aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/.gitignore8
-rw-r--r--lib/Makefile4
-rw-r--r--lib/asn1/c_src/asn1_erl_nif.c42
-rw-r--r--lib/asn1/doc/src/Makefile3
-rw-r--r--lib/asn1/doc/src/asn1_getting_started.xml85
-rw-r--r--lib/asn1/doc/src/asn1_introduction.xml2
-rw-r--r--lib/asn1/doc/src/asn1ct.xml64
-rw-r--r--lib/asn1/doc/src/asn1rt.xml135
-rw-r--r--lib/asn1/doc/src/notes.xml71
-rw-r--r--lib/asn1/doc/src/ref_man.xml3
-rw-r--r--lib/asn1/examples/recordnames.txt2
-rw-r--r--lib/asn1/src/Makefile1
-rw-r--r--lib/asn1/src/asn1.app.src1
-rw-r--r--lib/asn1/src/asn1_db.erl32
-rw-r--r--lib/asn1/src/asn1_records.hrl25
-rw-r--r--lib/asn1/src/asn1ct.erl380
-rw-r--r--lib/asn1/src/asn1ct_check.erl173
-rw-r--r--lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl411
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl973
-rw-r--r--lib/asn1/src/asn1ct_eval_ext.funcs1
-rw-r--r--lib/asn1/src/asn1ct_func.erl4
-rw-r--r--lib/asn1/src/asn1ct_gen.erl766
-rw-r--r--lib/asn1/src/asn1ct_gen_ber_bin_v2.erl306
-rw-r--r--lib/asn1/src/asn1ct_gen_check.erl193
-rw-r--r--lib/asn1/src/asn1ct_gen_per.erl78
-rw-r--r--lib/asn1/src/asn1ct_imm.erl97
-rw-r--r--lib/asn1/src/asn1ct_name.erl4
-rw-r--r--lib/asn1/src/asn1ct_parser2.erl4
-rw-r--r--lib/asn1/src/asn1ct_value.erl84
-rw-r--r--lib/asn1/src/asn1rt.erl184
-rw-r--r--lib/asn1/src/asn1rt_nif.erl3
-rw-r--r--lib/asn1/src/asn1rtt_ber.erl35
-rw-r--r--lib/asn1/src/asn1rtt_ext.erl64
-rw-r--r--lib/asn1/src/asn1rtt_per_common.erl4
-rw-r--r--lib/asn1/test/Makefile8
-rw-r--r--lib/asn1/test/asn1_SUITE.erl169
-rw-r--r--lib/asn1/test/asn1_SUITE_data/HighTagNumbers.asn117
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Maps.asn117
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Prim.asn12
-rw-r--r--lib/asn1/test/asn1_SUITE_data/SeqExtension.asn111
-rw-r--r--lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl4
-rw-r--r--lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Descriptions.asn (renamed from lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Discriptions.asn)2
-rw-r--r--lib/asn1/test/asn1_SUITE_data/test_records.erl4
-rw-r--r--lib/asn1/test/asn1_SUITE_data/testobj.erl14
-rw-r--r--lib/asn1/test/asn1_app_SUITE.erl (renamed from lib/asn1/test/asn1_app_test.erl)60
-rw-r--r--lib/asn1/test/asn1_appup_test.erl58
-rw-r--r--lib/asn1/test/asn1_test_lib.erl160
-rw-r--r--lib/asn1/test/ber_decode_error.erl41
-rw-r--r--lib/asn1/test/h323test.erl31
-rw-r--r--lib/asn1/test/testChoPrim.erl10
-rw-r--r--lib/asn1/test/testContextSwitchingTypes.erl3
-rw-r--r--lib/asn1/test/testInfObj.erl3
-rw-r--r--lib/asn1/test/testInfObjectClass.erl24
-rw-r--r--lib/asn1/test/testMaps.erl50
-rw-r--r--lib/asn1/test/testMultipleLevels.erl8
-rw-r--r--lib/asn1/test/testNBAPsystem.erl16
-rw-r--r--lib/asn1/test/testPrim.erl49
-rw-r--r--lib/asn1/test/testPrimStrings.erl22
-rw-r--r--lib/asn1/test/testRfcs.erl52
-rw-r--r--lib/asn1/test/testSeqExtension.erl40
-rw-r--r--lib/asn1/test/testTCAP.erl3
-rw-r--r--lib/asn1/test/testTimer.erl133
-rw-r--r--lib/asn1/test/testUniqueObjectSets.erl3
-rw-r--r--lib/asn1/test/test_compile_options.erl30
-rw-r--r--lib/asn1/vsn.mk2
-rw-r--r--lib/common_test/doc/specs/.gitignore1
-rw-r--r--lib/common_test/doc/src/Makefile14
-rw-r--r--lib/common_test/doc/src/basics_chapter.xml4
-rw-r--r--lib/common_test/doc/src/common_test_app.xml30
-rw-r--r--lib/common_test/doc/src/ct.xml201
-rw-r--r--lib/common_test/doc/src/ct_hooks.xml94
-rw-r--r--lib/common_test/doc/src/ct_hooks_chapter.xml84
-rw-r--r--lib/common_test/doc/src/ct_netconfc.xml916
-rw-r--r--lib/common_test/doc/src/ct_run.xml10
-rw-r--r--lib/common_test/doc/src/ct_ssh.xml135
-rw-r--r--lib/common_test/doc/src/ct_telnet.xml4
-rw-r--r--lib/common_test/doc/src/ct_testspec.xml84
-rw-r--r--lib/common_test/doc/src/event_handler_chapter.xml6
-rw-r--r--lib/common_test/doc/src/introduction.xml2
-rw-r--r--lib/common_test/doc/src/notes.xml288
-rw-r--r--lib/common_test/doc/src/ref_man.xml1
-rw-r--r--lib/common_test/doc/src/run_test_chapter.xml64
-rw-r--r--lib/common_test/doc/src/specs.xml5
-rw-r--r--lib/common_test/doc/src/write_test_chapter.xml60
-rw-r--r--lib/common_test/src/Makefile1
-rw-r--r--lib/common_test/src/common_test.app.src3
-rw-r--r--lib/common_test/src/ct.erl151
-rw-r--r--lib/common_test/src/ct_config.erl6
-rw-r--r--lib/common_test/src/ct_conn_log_h.erl18
-rw-r--r--lib/common_test/src/ct_default_gl.erl83
-rw-r--r--lib/common_test/src/ct_event.erl4
-rw-r--r--lib/common_test/src/ct_framework.erl219
-rw-r--r--lib/common_test/src/ct_ftp.erl26
-rw-r--r--lib/common_test/src/ct_gen_conn.erl54
-rw-r--r--lib/common_test/src/ct_groups.erl20
-rw-r--r--lib/common_test/src/ct_hooks.erl145
-rw-r--r--lib/common_test/src/ct_logs.erl195
-rw-r--r--lib/common_test/src/ct_make.erl8
-rw-r--r--lib/common_test/src/ct_master.erl26
-rw-r--r--lib/common_test/src/ct_master_event.erl6
-rw-r--r--lib/common_test/src/ct_master_logs.erl12
-rw-r--r--lib/common_test/src/ct_master_status.erl4
-rw-r--r--lib/common_test/src/ct_netconfc.erl926
-rw-r--r--lib/common_test/src/ct_property_test.erl6
-rw-r--r--lib/common_test/src/ct_release_test.erl23
-rw-r--r--lib/common_test/src/ct_repeat.erl10
-rw-r--r--lib/common_test/src/ct_run.erl156
-rw-r--r--lib/common_test/src/ct_slave.erl7
-rw-r--r--lib/common_test/src/ct_snmp.erl2
-rw-r--r--lib/common_test/src/ct_ssh.erl106
-rw-r--r--lib/common_test/src/ct_telnet.erl118
-rw-r--r--lib/common_test/src/ct_telnet_client.erl4
-rw-r--r--lib/common_test/src/ct_testspec.erl41
-rw-r--r--lib/common_test/src/ct_util.erl37
-rw-r--r--lib/common_test/src/ct_util.hrl1
-rw-r--r--lib/common_test/src/ct_webtool.erl34
-rw-r--r--lib/common_test/src/cth_conn_log.erl35
-rw-r--r--lib/common_test/src/cth_log_redirect.erl38
-rw-r--r--lib/common_test/src/cth_surefire.erl60
-rw-r--r--lib/common_test/src/erl2html2.erl2
-rw-r--r--lib/common_test/src/test_server.erl63
-rw-r--r--lib/common_test/src/test_server_ctrl.erl275
-rw-r--r--lib/common_test/src/test_server_gl.erl26
-rw-r--r--lib/common_test/src/test_server_io.erl14
-rw-r--r--lib/common_test/src/test_server_node.erl24
-rw-r--r--lib/common_test/src/test_server_sup.erl26
-rw-r--r--lib/common_test/src/unix_telnet.erl12
-rw-r--r--lib/common_test/src/vts.erl6
-rw-r--r--lib/common_test/test/Makefile7
-rw-r--r--lib/common_test/test/ct_SUITE.erl53
-rw-r--r--lib/common_test/test/ct_auto_compile_SUITE.erl1
-rw-r--r--lib/common_test/test/ct_config_SUITE.erl63
-rw-r--r--lib/common_test/test/ct_error_SUITE.erl10
-rw-r--r--lib/common_test/test/ct_hooks_SUITE.erl1203
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/all_hook_callbacks_SUITE.erl62
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/config_clash_SUITE.erl43
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_end_config_SUITE.erl51
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_init_config_SUITE.erl54
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_init_suite_config_SUITE.erl39
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl124
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl34
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fallback_cth.erl81
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl8
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/prio_cth.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/repeat_SUITE.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/seq_SUITE.erl45
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip.spec8
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_case_SUITE.erl106
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_cth.erl182
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_fail_SUITE.erl53
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_group_SUITE.erl64
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_init_SUITE.erl53
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_end_cth.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_init_tc_cth.erl79
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_req_SUITE.erl53
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl42
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_data_dir_cth.erl42
-rw-r--r--lib/common_test/test/ct_keep_logs_SUITE.erl199
-rw-r--r--lib/common_test/test/ct_keep_logs_SUITE_data/keep_logs_SUITE.erl (renamed from lib/typer/src/typer.appup.src)22
-rw-r--r--lib/common_test/test/ct_log_SUITE.erl134
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE.erl7
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl75
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl8
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/ns.erl14
-rw-r--r--lib/common_test/test/ct_repeat_testrun_SUITE.erl7
-rw-r--r--lib/common_test/test/ct_surefire_SUITE.erl139
-rw-r--r--lib/common_test/test/ct_surefire_SUITE_data/skip_one_case.spec2
-rw-r--r--lib/common_test/test/ct_surefire_SUITE_data/skip_one_suite.spec2
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE.erl3
-rw-r--r--lib/common_test/test/ct_test_support.erl148
-rw-r--r--lib/common_test/test/ct_testspec_1_SUITE.erl8
-rw-r--r--lib/common_test/test/ct_testspec_2_SUITE.erl82
-rw-r--r--lib/common_test/test/ct_unicode_SUITE.erl218
-rw-r--r--lib/common_test/test/ct_unicode_SUITE_data/unicode_atoms_SUITE.erl98
-rw-r--r--lib/common_test/test/ct_verbosity_SUITE.erl6
-rw-r--r--lib/common_test/test/erl2html2_SUITE.erl6
-rw-r--r--lib/common_test/test/test_server_test_lib.erl4
-rw-r--r--lib/common_test/test_server/ts_install.erl4
-rw-r--r--lib/common_test/test_server/ts_make.erl4
-rw-r--r--lib/common_test/test_server/ts_run.erl2
-rw-r--r--lib/common_test/vsn.mk2
-rw-r--r--lib/compiler/doc/src/compile.xml72
-rw-r--r--lib/compiler/doc/src/notes.xml285
-rw-r--r--lib/compiler/doc/src/ref_man.xml2
-rw-r--r--lib/compiler/src/Makefile9
-rw-r--r--lib/compiler/src/beam_a.erl3
-rw-r--r--lib/compiler/src/beam_asm.erl77
-rw-r--r--lib/compiler/src/beam_block.erl111
-rw-r--r--lib/compiler/src/beam_bool.erl765
-rw-r--r--lib/compiler/src/beam_bs.erl3
-rw-r--r--lib/compiler/src/beam_bsm.erl69
-rw-r--r--lib/compiler/src/beam_clean.erl20
-rw-r--r--lib/compiler/src/beam_dead.erl54
-rw-r--r--lib/compiler/src/beam_dict.erl32
-rw-r--r--lib/compiler/src/beam_disasm.erl3
-rw-r--r--lib/compiler/src/beam_except.erl9
-rw-r--r--lib/compiler/src/beam_flatten.erl4
-rw-r--r--lib/compiler/src/beam_jump.erl86
-rw-r--r--lib/compiler/src/beam_listing.erl18
-rw-r--r--lib/compiler/src/beam_peep.erl3
-rw-r--r--lib/compiler/src/beam_receive.erl3
-rw-r--r--lib/compiler/src/beam_record.erl106
-rw-r--r--lib/compiler/src/beam_reorder.erl3
-rw-r--r--lib/compiler/src/beam_split.erl6
-rw-r--r--lib/compiler/src/beam_trim.erl9
-rw-r--r--lib/compiler/src/beam_type.erl58
-rw-r--r--lib/compiler/src/beam_utils.erl358
-rw-r--r--lib/compiler/src/beam_validator.erl36
-rw-r--r--lib/compiler/src/beam_z.erl3
-rw-r--r--lib/compiler/src/cerl.erl22
-rw-r--r--lib/compiler/src/cerl_clauses.erl9
-rw-r--r--lib/compiler/src/cerl_inline.erl11
-rw-r--r--lib/compiler/src/cerl_trees.erl9
-rw-r--r--lib/compiler/src/compile.erl561
-rw-r--r--lib/compiler/src/compiler.app.src8
-rw-r--r--lib/compiler/src/core_parse.yrl15
-rw-r--r--lib/compiler/src/core_pp.erl2
-rw-r--r--lib/compiler/src/core_scan.erl34
-rw-r--r--lib/compiler/src/erl_bifs.erl9
-rwxr-xr-xlib/compiler/src/genop.tab10
-rw-r--r--lib/compiler/src/rec_env.erl9
-rw-r--r--lib/compiler/src/sys_core_bsm.erl355
-rw-r--r--lib/compiler/src/sys_core_fold.erl607
-rw-r--r--lib/compiler/src/sys_pre_attributes.erl48
-rw-r--r--lib/compiler/src/sys_pre_expand.erl616
-rw-r--r--lib/compiler/src/v3_codegen.erl54
-rw-r--r--lib/compiler/src/v3_core.erl277
-rw-r--r--lib/compiler/src/v3_kernel.erl618
-rw-r--r--lib/compiler/src/v3_kernel.hrl3
-rw-r--r--lib/compiler/src/v3_kernel_pp.erl24
-rw-r--r--lib/compiler/src/v3_life.erl66
-rw-r--r--lib/compiler/src/v3_life.hrl8
-rw-r--r--lib/compiler/test/Makefile25
-rw-r--r--lib/compiler/test/beam_block_SUITE.erl49
-rw-r--r--lib/compiler/test/beam_bool_SUITE.erl197
-rw-r--r--lib/compiler/test/beam_jump_SUITE.erl19
-rw-r--r--lib/compiler/test/beam_reorder_SUITE.erl2
-rw-r--r--lib/compiler/test/beam_type_SUITE.erl52
-rw-r--r--lib/compiler/test/beam_utils_SUITE.erl8
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl29
-rw-r--r--lib/compiler/test/bif_SUITE.erl61
-rw-r--r--lib/compiler/test/bs_bincomp_SUITE.erl1
-rw-r--r--lib/compiler/test/bs_construct_SUITE.erl23
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl98
-rw-r--r--lib/compiler/test/bs_utf_SUITE.erl1
-rw-r--r--lib/compiler/test/compilation_SUITE.erl4
-rw-r--r--lib/compiler/test/compile_SUITE.erl412
-rw-r--r--lib/compiler/test/compile_SUITE_data/simple.erl5
-rw-r--r--lib/compiler/test/compile_SUITE_data/small_float.erl5
-rw-r--r--lib/compiler/test/core_SUITE.erl20
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core147
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core98
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core98
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core82
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core98
-rw-r--r--lib/compiler/test/core_fold_SUITE.erl32
-rw-r--r--lib/compiler/test/float_SUITE.erl12
-rw-r--r--lib/compiler/test/guard_SUITE.erl307
-rw-r--r--lib/compiler/test/lc_SUITE.erl13
-rw-r--r--lib/compiler/test/lfe-core.patch97
-rw-r--r--lib/compiler/test/lfe-source.patch117
-rw-r--r--lib/compiler/test/lfe.readme31
-rw-r--r--lib/compiler/test/lfe_andor_SUITE.core2014
-rw-r--r--lib/compiler/test/lfe_guard_SUITE.core3438
-rw-r--r--lib/compiler/test/map_SUITE.erl1
-rw-r--r--lib/compiler/test/match_SUITE.erl21
-rw-r--r--lib/compiler/test/misc_SUITE.erl30
-rw-r--r--lib/compiler/test/num_bif_SUITE.erl285
-rw-r--r--lib/compiler/test/overridden_bif_SUITE.erl101
-rw-r--r--lib/compiler/test/record_SUITE_data/record_access_in_guards.erl63
-rw-r--r--lib/compiler/test/regressions_SUITE.erl19
-rw-r--r--lib/compiler/test/test_lib.erl9
-rw-r--r--lib/compiler/test/warnings_SUITE.erl140
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/cosProperty/doc/src/notes.xml16
-rw-r--r--lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl4
-rw-r--r--lib/cosProperty/vsn.mk2
-rw-r--r--lib/crypto/c_src/Makefile.in2
-rw-r--r--lib/crypto/c_src/crypto.c1352
-rw-r--r--lib/crypto/c_src/crypto_callback.c8
-rw-r--r--lib/crypto/c_src/crypto_callback.h15
-rw-r--r--lib/crypto/doc/src/Makefile2
-rw-r--r--lib/crypto/doc/src/crypto.xml131
-rw-r--r--lib/crypto/doc/src/crypto_app.xml29
-rw-r--r--lib/crypto/doc/src/fips.xml211
-rw-r--r--lib/crypto/doc/src/notes.xml232
-rw-r--r--lib/crypto/doc/src/usersguide.xml1
-rw-r--r--lib/crypto/src/Makefile2
-rw-r--r--lib/crypto/src/crypto.app.src6
-rw-r--r--lib/crypto/src/crypto.erl770
-rw-r--r--lib/crypto/src/crypto_ec_curves.erl25
-rw-r--r--lib/crypto/test/Makefile4
-rw-r--r--lib/crypto/test/blowfish_SUITE.erl85
-rw-r--r--lib/crypto/test/crypto_SUITE.erl1397
-rw-r--r--lib/crypto/test/crypto_SUITE_data/KAT_AES.zipbin0 -> 726299 bytes
-rw-r--r--lib/crypto/test/crypto_SUITE_data/aesmmt.zipbin0 -> 75959 bytes
-rw-r--r--lib/crypto/test/crypto_SUITE_data/cmactestvectors.zipbin0 -> 8823056 bytes
-rw-r--r--lib/crypto/test/crypto_SUITE_data/gcmtestvectors.zipbin0 -> 9154174 bytes
-rw-r--r--lib/crypto/test/old_crypto_SUITE.erl2309
-rw-r--r--lib/crypto/vsn.mk2
-rw-r--r--lib/debugger/doc/src/Makefile2
-rw-r--r--lib/debugger/doc/src/debugger_chapter.xml8
-rw-r--r--lib/debugger/doc/src/i.xml4
-rw-r--r--lib/debugger/doc/src/notes.xml61
-rw-r--r--lib/debugger/src/Makefile2
-rw-r--r--lib/debugger/src/dbg_icmd.erl44
-rw-r--r--lib/debugger/src/dbg_ieval.erl3
-rw-r--r--lib/debugger/src/dbg_iload.erl157
-rw-r--r--lib/debugger/src/dbg_iserver.erl40
-rw-r--r--lib/debugger/src/dbg_wx_code.erl4
-rw-r--r--lib/debugger/src/dbg_wx_src_view.erl4
-rw-r--r--lib/debugger/src/dbg_wx_trace.erl18
-rw-r--r--lib/debugger/src/dbg_wx_view.erl12
-rw-r--r--lib/debugger/src/dbg_wx_win.erl7
-rw-r--r--lib/debugger/src/int.erl6
-rw-r--r--lib/debugger/test/Makefile1
-rw-r--r--lib/debugger/test/andor_SUITE.erl2
-rw-r--r--lib/debugger/test/bs_bincomp_SUITE.erl1
-rw-r--r--lib/debugger/test/int_SUITE.erl5
-rw-r--r--lib/debugger/test/map_SUITE.erl22
-rw-r--r--lib/debugger/test/overridden_bif_SUITE.erl99
-rw-r--r--lib/debugger/test/test_lib.erl7
-rw-r--r--lib/debugger/vsn.mk2
-rw-r--r--lib/dialyzer/RELEASE_NOTES4
-rw-r--r--lib/dialyzer/doc/manual.txt2
-rw-r--r--lib/dialyzer/doc/src/Makefile2
-rw-r--r--lib/dialyzer/doc/src/book.xml2
-rw-r--r--lib/dialyzer/doc/src/dialyzer.xml827
-rw-r--r--lib/dialyzer/doc/src/dialyzer_chapter.xml303
-rw-r--r--lib/dialyzer/doc/src/notes.xml201
-rw-r--r--lib/dialyzer/doc/src/part.xml3
-rw-r--r--lib/dialyzer/doc/src/ref_man.xml6
-rw-r--r--lib/dialyzer/doc/src/typer.xml157
-rw-r--r--lib/dialyzer/src/Makefile8
-rw-r--r--lib/dialyzer/src/dialyzer.app.src7
-rw-r--r--lib/dialyzer/src/dialyzer.erl176
-rw-r--r--lib/dialyzer/src/dialyzer.hrl6
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl264
-rw-r--r--lib/dialyzer/src/dialyzer_behaviours.erl20
-rw-r--r--lib/dialyzer/src/dialyzer_callgraph.erl163
-rw-r--r--lib/dialyzer/src/dialyzer_cl.erl74
-rw-r--r--lib/dialyzer/src/dialyzer_cl_parse.erl14
-rw-r--r--lib/dialyzer/src/dialyzer_codeserver.erl308
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl242
-rw-r--r--lib/dialyzer/src/dialyzer_coordinator.erl72
-rw-r--r--lib/dialyzer/src/dialyzer_dataflow.erl248
-rw-r--r--lib/dialyzer/src/dialyzer_dep.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_explanation.erl10
-rw-r--r--lib/dialyzer/src/dialyzer_gui_wx.erl28
-rw-r--r--lib/dialyzer/src/dialyzer_gui_wx.hrl12
-rw-r--r--lib/dialyzer/src/dialyzer_options.erl22
-rw-r--r--lib/dialyzer/src/dialyzer_plt.erl437
-rw-r--r--lib/dialyzer/src/dialyzer_race_data_server.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_races.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_succ_typings.erl195
-rw-r--r--lib/dialyzer/src/dialyzer_timing.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_typesig.erl343
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl581
-rw-r--r--lib/dialyzer/src/dialyzer_worker.erl60
-rw-r--r--lib/dialyzer/src/typer.erl (renamed from lib/typer/src/typer.erl)133
-rw-r--r--lib/dialyzer/test/Makefile4
-rw-r--r--lib/dialyzer/test/abstract_SUITE.erl107
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/dialyzer_options1
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs6
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return2
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args9
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks3
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour12
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old4
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return2
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec8
-rw-r--r--lib/dialyzer/test/dialyzer_common.erl11
-rw-r--r--lib/dialyzer/test/map_SUITE_data/dialyzer_options1
-rw-r--r--lib/dialyzer/test/map_SUITE_data/results/map_galore8
-rw-r--r--lib/dialyzer/test/map_SUITE_data/results/map_in_guard24
-rw-r--r--lib/dialyzer/test/map_SUITE_data/results/opaque_key8
-rw-r--r--lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/a.erl9
-rw-r--r--lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/b.erl3
-rw-r--r--lib/dialyzer/test/map_SUITE_data/src/map_galore.erl24
-rw-r--r--lib/dialyzer/test/map_SUITE_data/src/opaque_bif.erl13
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/dialyzer_options1
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/array4
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/dict18
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/ets6
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/my_queue2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/opaque2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/para10
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/queue6
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/rec4
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/simple46
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/timer4
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/union8
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/weird6
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/wings8
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_ig_moves.erl75
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_vectors.erl129
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/cerl.erl4595
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/core_parse.hrl115
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer.hrl173
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_dataflow.erl3795
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_races.erl2487
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/erl_types.erl5735
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/simple/is_rec.erl6
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl8
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl26
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/timer/timer_use.erl4
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning1.erl18
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning2.erl14
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning3.erl19
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl4
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/results/compiler2
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_disasm.erl2
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_inline.erl6
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/rec_env.erl2
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl2
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_codegen.erl2
-rw-r--r--lib/dialyzer/test/options2_SUITE_data/dialyzer_options2
-rw-r--r--lib/dialyzer/test/options2_SUITE_data/results/unknown_type2
-rw-r--r--lib/dialyzer/test/options2_SUITE_data/results/unused_unknown_type2
-rw-r--r--lib/dialyzer/test/options2_SUITE_data/src/unknown_type.erl7
-rw-r--r--lib/dialyzer/test/options2_SUITE_data/src/unused_unknown_type.erl10
-rw-r--r--lib/dialyzer/test/plt_SUITE.erl146
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/results/mnesia1
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct.erl4
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_check.erl6
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber_bin_v2.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser2.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin_v2.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin_rt2ct.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/ftp.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/http.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/http_lib.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_manager.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_manager.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_parse.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_response.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/jnets_httpd.hrl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_mnesia.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_htaccess.erl10
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_range.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_responsecontrol.erl4
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_bup.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint.erl4
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_loader.erl4
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_locker.erl8
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_schema.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/chars4
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/fun_arity32
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/guards2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/anno.erl18
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/chars.erl32
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/ms.erl8
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/tuple1.erl2
-rw-r--r--lib/dialyzer/test/typer_SUITE.erl158
-rw-r--r--lib/dialyzer/vsn.mk2
-rw-r--r--lib/diameter/doc/src/diameter.xml168
-rw-r--r--lib/diameter/doc/src/diameter_app.xml39
-rw-r--r--lib/diameter/doc/src/diameter_codec.xml75
-rw-r--r--lib/diameter/doc/src/diameter_dict.xml82
-rw-r--r--lib/diameter/doc/src/diameter_examples.xml1
-rw-r--r--lib/diameter/doc/src/diameter_tcp.xml2
-rw-r--r--lib/diameter/doc/src/diameter_transport.xml9
-rw-r--r--lib/diameter/doc/src/diameterc.xml6
-rw-r--r--lib/diameter/doc/src/notes.xml146
-rw-r--r--lib/diameter/examples/code/relay.erl4
-rw-r--r--lib/diameter/include/diameter_gen.hrl722
-rw-r--r--lib/diameter/src/Makefile2
-rw-r--r--lib/diameter/src/base/diameter.erl4
-rw-r--r--lib/diameter/src/base/diameter_callback.erl4
-rw-r--r--lib/diameter/src/base/diameter_capx.erl89
-rw-r--r--lib/diameter/src/base/diameter_codec.erl524
-rw-r--r--lib/diameter/src/base/diameter_config.erl69
-rw-r--r--lib/diameter/src/base/diameter_dict.erl154
-rw-r--r--lib/diameter/src/base/diameter_gen.erl709
-rw-r--r--lib/diameter/src/base/diameter_lib.erl57
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm.erl242
-rw-r--r--lib/diameter/src/base/diameter_reg.erl4
-rw-r--r--lib/diameter/src/base/diameter_service.erl214
-rw-r--r--lib/diameter/src/base/diameter_sup.erl4
-rw-r--r--lib/diameter/src/base/diameter_traffic.erl1431
-rw-r--r--lib/diameter/src/base/diameter_types.erl300
-rw-r--r--lib/diameter/src/base/diameter_watchdog.erl187
-rw-r--r--lib/diameter/src/compiler/diameter_codegen.erl120
-rw-r--r--lib/diameter/src/diameter.app.src10
-rw-r--r--lib/diameter/src/diameter.appup.src12
-rw-r--r--lib/diameter/src/info/diameter_info.erl4
-rw-r--r--lib/diameter/src/modules.mk4
-rw-r--r--lib/diameter/src/transport/diameter_sctp.erl369
-rw-r--r--lib/diameter/src/transport/diameter_sctp_sup.erl3
-rw-r--r--lib/diameter/src/transport/diameter_tcp.erl533
-rw-r--r--lib/diameter/test/diameter_capx_SUITE.erl6
-rw-r--r--lib/diameter/test/diameter_codec_SUITE.erl19
-rw-r--r--lib/diameter/test/diameter_codec_SUITE_data/diameter_test_unknown.erl11
-rw-r--r--lib/diameter/test/diameter_codec_test.erl33
-rw-r--r--lib/diameter/test/diameter_compiler_SUITE.erl10
-rw-r--r--lib/diameter/test/diameter_dict_SUITE.erl145
-rw-r--r--lib/diameter/test/diameter_dpr_SUITE.erl113
-rw-r--r--lib/diameter/test/diameter_examples_SUITE.erl10
-rw-r--r--lib/diameter/test/diameter_gen_sctp_SUITE.erl455
-rw-r--r--lib/diameter/test/diameter_gen_tcp_SUITE.erl4
-rw-r--r--lib/diameter/test/diameter_pool_SUITE.erl4
-rw-r--r--lib/diameter/test/diameter_relay_SUITE.erl4
-rw-r--r--lib/diameter/test/diameter_traffic_SUITE.erl219
-rw-r--r--lib/diameter/test/diameter_transport_SUITE.erl30
-rw-r--r--lib/diameter/test/diameter_util.erl43
-rw-r--r--lib/diameter/test/diameter_watchdog_SUITE.erl104
-rw-r--r--lib/diameter/test/modules.mk3
-rw-r--r--lib/diameter/vsn.mk4
-rw-r--r--lib/edoc/COPYING504
-rw-r--r--lib/edoc/doc/overview.edoc14
-rw-r--r--lib/edoc/doc/src/notes.xml54
-rw-r--r--lib/edoc/include/edoc_doclet.hrl29
-rw-r--r--lib/edoc/src/edoc.erl35
-rw-r--r--lib/edoc/src/edoc.hrl29
-rw-r--r--lib/edoc/src/edoc_data.erl29
-rw-r--r--lib/edoc/src/edoc_doclet.erl31
-rw-r--r--lib/edoc/src/edoc_extract.erl55
-rw-r--r--lib/edoc/src/edoc_layout.erl340
-rw-r--r--lib/edoc/src/edoc_lib.erl31
-rw-r--r--lib/edoc/src/edoc_macros.erl29
-rw-r--r--lib/edoc/src/edoc_parser.yrl106
-rw-r--r--lib/edoc/src/edoc_refs.erl29
-rw-r--r--lib/edoc/src/edoc_report.erl31
-rw-r--r--lib/edoc/src/edoc_run.erl29
-rw-r--r--lib/edoc/src/edoc_scanner.erl30
-rw-r--r--lib/edoc/src/edoc_specs.erl13
-rw-r--r--lib/edoc/src/edoc_tags.erl42
-rw-r--r--lib/edoc/src/edoc_types.erl29
-rw-r--r--lib/edoc/src/edoc_types.hrl29
-rw-r--r--lib/edoc/src/edoc_wiki.erl29
-rw-r--r--lib/edoc/src/otpsgml_layout.erl29
-rw-r--r--lib/edoc/test/edoc_SUITE.erl22
-rw-r--r--lib/edoc/test/edoc_SUITE_data/un_atom1.erl41
-rw-r--r--lib/edoc/test/edoc_SUITE_data/un_atom2.erl40
-rw-r--r--lib/edoc/vsn.mk2
-rw-r--r--lib/eldap/doc/src/eldap.xml22
-rw-r--r--lib/eldap/test/Makefile2
-rw-r--r--lib/eldap/test/README2
-rw-r--r--lib/eldap/test/eldap.cover3
-rw-r--r--lib/eldap/test/eldap_basic_SUITE.erl5
-rw-r--r--lib/erl_docgen/doc/src/notes.xml71
-rwxr-xr-xlib/erl_docgen/priv/bin/xref_mod_app.escript2
-rw-r--r--lib/erl_docgen/priv/css/Makefile3
-rw-r--r--lib/erl_docgen/priv/css/highlight.css96
-rw-r--r--lib/erl_docgen/priv/css/otp_doc.css220
-rw-r--r--lib/erl_docgen/priv/dtd/erlref.dtd2
-rw-r--r--lib/erl_docgen/priv/images/erlang-logo.gifbin11588 -> 3342 bytes
-rw-r--r--lib/erl_docgen/priv/images/erlang-logo.pngbin14795 -> 5837 bytes
-rw-r--r--lib/erl_docgen/priv/js/flipmenu/Makefile1
-rw-r--r--lib/erl_docgen/priv/js/flipmenu/flip_closed.gifbin82 -> 79 bytes
-rw-r--r--lib/erl_docgen/priv/js/flipmenu/flip_open.gifbin86 -> 85 bytes
-rw-r--r--lib/erl_docgen/priv/js/flipmenu/flip_static.gifbin109 -> 132 bytes
-rw-r--r--lib/erl_docgen/priv/js/highlight.js39
-rw-r--r--lib/erl_docgen/priv/js/highlight.pack.js2
-rw-r--r--lib/erl_docgen/priv/xsl/db_html.xsl289
-rw-r--r--lib/erl_docgen/src/docgen_edoc_xml_cb.erl162
-rw-r--r--lib/erl_docgen/vsn.mk2
-rw-r--r--lib/erl_interface/doc/src/book.xml11
-rw-r--r--lib/erl_interface/doc/src/ei.xml1181
-rw-r--r--lib/erl_interface/doc/src/ei_connect.xml1057
-rw-r--r--lib/erl_interface/doc/src/ei_users_guide.xml715
-rw-r--r--lib/erl_interface/doc/src/erl_call.xml221
-rw-r--r--lib/erl_interface/doc/src/erl_connect.xml803
-rw-r--r--lib/erl_interface/doc/src/erl_error.xml94
-rw-r--r--lib/erl_interface/doc/src/erl_eterm.xml795
-rw-r--r--lib/erl_interface/doc/src/erl_format.xml102
-rw-r--r--lib/erl_interface/doc/src/erl_global.xml132
-rw-r--r--lib/erl_interface/doc/src/erl_interface.xml209
-rw-r--r--lib/erl_interface/doc/src/erl_malloc.xml181
-rw-r--r--lib/erl_interface/doc/src/erl_marshal.xml287
-rw-r--r--lib/erl_interface/doc/src/fascicules.xml24
-rw-r--r--lib/erl_interface/doc/src/notes.xml102
-rw-r--r--lib/erl_interface/doc/src/part.xml2
-rw-r--r--lib/erl_interface/doc/src/part_erl_interface.xml5
-rw-r--r--lib/erl_interface/doc/src/ref_man.xml18
-rw-r--r--lib/erl_interface/doc/src/ref_man_ei.xml13
-rw-r--r--lib/erl_interface/doc/src/ref_man_erl_interface.xml5
-rw-r--r--lib/erl_interface/doc/src/registry.xml869
-rw-r--r--lib/erl_interface/src/README2
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c55
-rw-r--r--lib/erl_interface/src/encode/encode_atom.c66
-rw-r--r--lib/erl_interface/src/encode/encode_boolean.c10
-rw-r--r--lib/erl_interface/src/legacy/erl_eterm.c18
-rw-r--r--lib/erl_interface/src/legacy/erl_marshal.c19
-rw-r--r--lib/erl_interface/src/misc/ei_locking.c6
-rw-r--r--lib/erl_interface/src/misc/ei_portio.h2
-rw-r--r--lib/erl_interface/src/prog/erl_call.c5
-rw-r--r--lib/erl_interface/src/prog/erl_start.c73
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE.erl29
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c4
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE.erl5
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE.erl36
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE.erl4
-rw-r--r--lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c12
-rw-r--r--lib/erl_interface/vsn.mk2
-rw-r--r--lib/eunit/COPYING504
-rw-r--r--lib/eunit/doc/overview.edoc4
-rw-r--r--lib/eunit/doc/src/notes.xml52
-rw-r--r--lib/eunit/include/eunit.hrl37
-rw-r--r--lib/eunit/src/Makefile2
-rw-r--r--lib/eunit/src/eunit.erl31
-rw-r--r--lib/eunit/src/eunit_autoexport.erl29
-rw-r--r--lib/eunit/src/eunit_data.erl29
-rw-r--r--lib/eunit/src/eunit_internal.hrl21
-rw-r--r--lib/eunit/src/eunit_lib.erl29
-rw-r--r--lib/eunit/src/eunit_listener.erl29
-rw-r--r--lib/eunit/src/eunit_proc.erl29
-rw-r--r--lib/eunit/src/eunit_serial.erl29
-rw-r--r--lib/eunit/src/eunit_server.erl29
-rw-r--r--lib/eunit/src/eunit_striptests.erl29
-rw-r--r--lib/eunit/src/eunit_surefire.erl30
-rw-r--r--lib/eunit/src/eunit_test.erl29
-rw-r--r--lib/eunit/src/eunit_tests.erl29
-rw-r--r--lib/eunit/src/eunit_tty.erl29
-rw-r--r--lib/eunit/vsn.mk2
-rw-r--r--lib/gs/AUTHORS16
-rw-r--r--lib/gs/Makefile40
-rw-r--r--lib/gs/configure.in46
-rw-r--r--lib/gs/doc/html/.gitignore0
-rw-r--r--lib/gs/doc/man3/.gitignore0
-rw-r--r--lib/gs/doc/pdf/.gitignore0
-rw-r--r--lib/gs/doc/src/Makefile158
-rw-r--r--lib/gs/doc/src/book.xml50
-rw-r--r--lib/gs/doc/src/examples/die_icon9
-rw-r--r--lib/gs/doc/src/examples/ex1.erl20
-rw-r--r--lib/gs/doc/src/examples/ex10.erl59
-rw-r--r--lib/gs/doc/src/examples/ex11.erl42
-rw-r--r--lib/gs/doc/src/examples/ex12.erl33
-rw-r--r--lib/gs/doc/src/examples/ex13.erl74
-rw-r--r--lib/gs/doc/src/examples/ex14.erl46
-rw-r--r--lib/gs/doc/src/examples/ex15.erl30
-rw-r--r--lib/gs/doc/src/examples/ex16.erl40
-rw-r--r--lib/gs/doc/src/examples/ex17.erl32
-rw-r--r--lib/gs/doc/src/examples/ex2.erl19
-rw-r--r--lib/gs/doc/src/examples/ex3.erl23
-rw-r--r--lib/gs/doc/src/examples/ex4.erl23
-rw-r--r--lib/gs/doc/src/examples/ex5.erl27
-rw-r--r--lib/gs/doc/src/examples/ex6.erl23
-rw-r--r--lib/gs/doc/src/examples/ex7.erl42
-rw-r--r--lib/gs/doc/src/examples/ex8.erl22
-rw-r--r--lib/gs/doc/src/examples/ex9.erl43
-rw-r--r--lib/gs/doc/src/fascicules.xml18
-rw-r--r--lib/gs/doc/src/gs.xml158
-rw-r--r--lib/gs/doc/src/gs_chapter1.xml91
-rw-r--r--lib/gs/doc/src/gs_chapter2.xmlsrc165
-rw-r--r--lib/gs/doc/src/gs_chapter3.xml177
-rw-r--r--lib/gs/doc/src/gs_chapter4.xmlsrc197
-rw-r--r--lib/gs/doc/src/gs_chapter5.xmlsrc70
-rw-r--r--lib/gs/doc/src/gs_chapter6.xmlsrc62
-rw-r--r--lib/gs/doc/src/gs_chapter7.xmlsrc65
-rw-r--r--lib/gs/doc/src/gs_chapter8.xmlsrc1691
-rw-r--r--lib/gs/doc/src/images/arc.gifbin1828 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/arc.ps1385
-rw-r--r--lib/gs/doc/src/images/buttons.gifbin3708 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/buttons.ps6003
-rw-r--r--lib/gs/doc/src/images/ex1.gifbin2035 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/ex1.ps2387
-rw-r--r--lib/gs/doc/src/images/ex10.gifbin5117 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/ex10.ps6635
-rw-r--r--lib/gs/doc/src/images/ex11.gifbin3669 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/ex11.ps5873
-rw-r--r--lib/gs/doc/src/images/ex12.gifbin4377 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/ex12.ps4187
-rw-r--r--lib/gs/doc/src/images/ex13.gifbin2881 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/ex13.ps2369
-rw-r--r--lib/gs/doc/src/images/ex14.gifbin5440 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/ex14.ps11546
-rw-r--r--lib/gs/doc/src/images/ex15.gifbin4079 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/ex15.ps9796
-rw-r--r--lib/gs/doc/src/images/ex16.gifbin3366 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/ex16.ps4187
-rw-r--r--lib/gs/doc/src/images/ex8.gifbin2560 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/ex8.ps6003
-rw-r--r--lib/gs/doc/src/images/ex9.gifbin2659 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/ex9.ps1879
-rw-r--r--lib/gs/doc/src/images/gs1-1-image-1.gifbin2841 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/gs1-1-image-1.ps171
-rw-r--r--lib/gs/doc/src/images/gs1-1-image-2.gifbin4367 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/gs1-1-image-2.ps2832
-rw-r--r--lib/gs/doc/src/images/gs1-1-image-3.gifbin3723 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/gs1-1-image-3.ps2830
-rw-r--r--lib/gs/doc/src/images/gs1-1-image-4.gifbin1991 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/gs1-1-image-4.ps2761
-rw-r--r--lib/gs/doc/src/images/image.gifbin14990 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/image.ps2103
-rw-r--r--lib/gs/doc/src/images/line.gifbin1855 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/line.ps1613
-rw-r--r--lib/gs/doc/src/images/oval.gifbin2193 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/oval.ps2321
-rw-r--r--lib/gs/doc/src/images/packer1.gifbin3021 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/packer1.ps5987
-rw-r--r--lib/gs/doc/src/images/packer2.gifbin2618 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/packer2.ps5176
-rw-r--r--lib/gs/doc/src/images/polygon.gifbin1934 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/polygon.ps1963
-rw-r--r--lib/gs/doc/src/images/rectangle.gifbin2078 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/rectangle.ps2173
-rw-r--r--lib/gs/doc/src/images/text.gifbin1979 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/text.ps1767
-rw-r--r--lib/gs/doc/src/images/window.gifbin1972 -> 0 bytes
-rw-r--r--lib/gs/doc/src/images/window.ps3221
-rw-r--r--lib/gs/doc/src/inofficial_options65
-rw-r--r--lib/gs/doc/src/note.gifbin1539 -> 0 bytes
-rw-r--r--lib/gs/doc/src/notes.xml363
-rw-r--r--lib/gs/doc/src/part.xml47
-rw-r--r--lib/gs/doc/src/part_notes.xml40
-rw-r--r--lib/gs/doc/src/ref_man.xml40
-rw-r--r--lib/gs/doc/src/removed_options31
-rw-r--r--lib/gs/doc/src/warning.gifbin1498 -> 0 bytes
-rw-r--r--lib/gs/ebin/.gitignore0
-rw-r--r--lib/gs/examples/Makefile96
-rw-r--r--lib/gs/examples/README24
-rw-r--r--lib/gs/examples/ball.erl78
-rw-r--r--lib/gs/examples/browser.erl98
-rw-r--r--lib/gs/examples/calc.erl114
-rw-r--r--lib/gs/examples/calc2.erl103
-rw-r--r--lib/gs/examples/color_demo.erl68
-rw-r--r--lib/gs/examples/color_demo2.erl113
-rw-r--r--lib/gs/examples/distrib_draw.erl122
-rw-r--r--lib/gs/examples/entry_demo.erl70
-rw-r--r--lib/gs/examples/event_test.erl52
-rw-r--r--lib/gs/examples/file_dialog.erl261
-rw-r--r--lib/gs/examples/focus_demo.erl103
-rw-r--r--lib/gs/examples/frac.erl158
-rw-r--r--lib/gs/examples/line_demo.erl82
-rw-r--r--lib/gs/examples/man.erl202
-rw-r--r--lib/gs/examples/menu_demo.erl81
-rw-r--r--lib/gs/examples/rubber.erl113
-rw-r--r--lib/gs/info2
-rw-r--r--lib/gs/prebuild.skip1
-rw-r--r--lib/gs/priv/bitmap/fup.bm7
-rw-r--r--lib/gs/priv/gs-xdefaults88
-rw-r--r--lib/gs/priv/gstk.tcl366
-rw-r--r--lib/gs/src/Makefile121
-rw-r--r--lib/gs/src/gs.app.src14
-rw-r--r--lib/gs/src/gs.erl410
-rw-r--r--lib/gs/src/gs_frontend.erl371
-rw-r--r--lib/gs/src/gs_make.erl266
-rw-r--r--lib/gs/src/gs_packer.erl276
-rw-r--r--lib/gs/src/gs_widgets.erl99
-rw-r--r--lib/gs/src/gse.erl788
-rw-r--r--lib/gs/src/gstk.erl389
-rw-r--r--lib/gs/src/gstk_arc.erl192
-rw-r--r--lib/gs/src/gstk_button.erl221
-rw-r--r--lib/gs/src/gstk_canvas.erl516
-rw-r--r--lib/gs/src/gstk_checkbutton.erl320
-rw-r--r--lib/gs/src/gstk_db.erl413
-rw-r--r--lib/gs/src/gstk_editor.erl400
-rw-r--r--lib/gs/src/gstk_entry.erl234
-rw-r--r--lib/gs/src/gstk_font.erl255
-rw-r--r--lib/gs/src/gstk_frame.erl282
-rw-r--r--lib/gs/src/gstk_generic.erl1089
-rw-r--r--lib/gs/src/gstk_grid.erl284
-rw-r--r--lib/gs/src/gstk_gridline.erl301
-rw-r--r--lib/gs/src/gstk_gs.erl54
-rw-r--r--lib/gs/src/gstk_image.erl321
-rw-r--r--lib/gs/src/gstk_label.erl183
-rw-r--r--lib/gs/src/gstk_line.erl203
-rw-r--r--lib/gs/src/gstk_listbox.erl324
-rw-r--r--lib/gs/src/gstk_menu.erl268
-rw-r--r--lib/gs/src/gstk_menubar.erl176
-rw-r--r--lib/gs/src/gstk_menubutton.erl238
-rw-r--r--lib/gs/src/gstk_menuitem.erl584
-rw-r--r--lib/gs/src/gstk_oval.erl189
-rw-r--r--lib/gs/src/gstk_polygon.erl196
-rw-r--r--lib/gs/src/gstk_port_handler.erl467
-rw-r--r--lib/gs/src/gstk_radiobutton.erl343
-rw-r--r--lib/gs/src/gstk_rectangle.erl186
-rw-r--r--lib/gs/src/gstk_scale.erl215
-rw-r--r--lib/gs/src/gstk_text.erl190
-rw-r--r--lib/gs/src/gstk_widgets.erl94
-rw-r--r--lib/gs/src/gstk_window.erl371
-rw-r--r--lib/gs/src/tcl2erl.erl459
-rw-r--r--lib/gs/src/tool_file_dialog.erl456
-rw-r--r--lib/gs/src/tool_utils.erl438
-rw-r--r--lib/gs/tcl/Makefile24
-rw-r--r--lib/gs/tcl/Makefile.in84
-rw-r--r--lib/gs/tcl/README156
-rw-r--r--lib/gs/test/Makefile65
-rw-r--r--lib/gs/test/gs.spec1
-rw-r--r--lib/gs/test/gs_SUITE.erl51
-rw-r--r--lib/gs/vsn.mk2
-rw-r--r--lib/hipe/amd64/Makefile8
-rw-r--r--lib/hipe/amd64/hipe_amd64_assemble.erl9
-rw-r--r--lib/hipe/amd64/hipe_amd64_defuse.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_encode.erl53
-rw-r--r--lib/hipe/amd64/hipe_amd64_frame.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_liveness.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_main.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_pp.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_finalise.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_ls.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_naive.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_postconditions.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl180
-rw-r--r--lib/hipe/amd64/hipe_amd64_registers.erl42
-rw-r--r--lib/hipe/amd64/hipe_amd64_spill_restore.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_sse2.erl76
-rw-r--r--lib/hipe/amd64/hipe_amd64_subst.erl (renamed from lib/gs/src/gs.appup.src)13
-rw-r--r--lib/hipe/amd64/hipe_amd64_x87.erl8
-rw-r--r--lib/hipe/amd64/hipe_rtl_to_amd64.erl8
-rw-r--r--lib/hipe/arm/Makefile1
-rw-r--r--lib/hipe/arm/hipe_arm.erl14
-rw-r--r--lib/hipe/arm/hipe_arm.hrl8
-rw-r--r--lib/hipe/arm/hipe_arm_assemble.erl9
-rw-r--r--lib/hipe/arm/hipe_arm_cfg.erl30
-rw-r--r--lib/hipe/arm/hipe_arm_defuse.erl16
-rw-r--r--lib/hipe/arm/hipe_arm_encode.erl6
-rw-r--r--lib/hipe/arm/hipe_arm_finalise.erl92
-rw-r--r--lib/hipe/arm/hipe_arm_frame.erl126
-rw-r--r--lib/hipe/arm/hipe_arm_liveness_gpr.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_main.erl17
-rw-r--r--lib/hipe/arm/hipe_arm_pp.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_ra.erl45
-rw-r--r--lib/hipe/arm/hipe_arm_ra_finalise.erl43
-rw-r--r--lib/hipe/arm/hipe_arm_ra_ls.erl42
-rw-r--r--lib/hipe/arm/hipe_arm_ra_naive.erl17
-rw-r--r--lib/hipe/arm/hipe_arm_ra_postconditions.erl52
-rw-r--r--lib/hipe/arm/hipe_arm_registers.erl17
-rw-r--r--lib/hipe/arm/hipe_arm_subst.erl127
-rw-r--r--lib/hipe/arm/hipe_rtl_to_arm.erl157
-rw-r--r--lib/hipe/cerl/cerl_cconv.erl9
-rw-r--r--lib/hipe/cerl/cerl_closurean.erl17
-rw-r--r--lib/hipe/cerl/cerl_hipe_primops.hrl17
-rw-r--r--lib/hipe/cerl/cerl_hipeify.erl9
-rw-r--r--lib/hipe/cerl/cerl_lib.erl10
-rw-r--r--lib/hipe/cerl/cerl_messagean.erl16
-rw-r--r--lib/hipe/cerl/cerl_pmatch.erl9
-rw-r--r--lib/hipe/cerl/cerl_prettypr.erl16
-rw-r--r--lib/hipe/cerl/cerl_to_icode.erl10
-rw-r--r--lib/hipe/cerl/cerl_typean.erl14
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl115
-rw-r--r--lib/hipe/cerl/erl_types.erl574
-rw-r--r--lib/hipe/doc/src/notes.xml212
-rw-r--r--lib/hipe/flow/cfg.hrl8
-rw-r--r--lib/hipe/flow/cfg.inc137
-rw-r--r--lib/hipe/flow/ebb.inc20
-rw-r--r--lib/hipe/flow/hipe_bb.erl8
-rw-r--r--lib/hipe/flow/hipe_bb.hrl6
-rw-r--r--lib/hipe/flow/hipe_dominators.erl8
-rw-r--r--lib/hipe/flow/hipe_gen_cfg.erl9
-rw-r--r--lib/hipe/flow/liveness.inc28
-rw-r--r--lib/hipe/icode/hipe_beam_to_icode.erl78
-rw-r--r--lib/hipe/icode/hipe_icode.erl26
-rw-r--r--lib/hipe/icode/hipe_icode.hrl7
-rw-r--r--lib/hipe/icode/hipe_icode_bincomp.erl34
-rw-r--r--lib/hipe/icode/hipe_icode_call_elim.erl10
-rw-r--r--lib/hipe/icode/hipe_icode_callgraph.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_cfg.erl8
-rw-r--r--lib/hipe/icode/hipe_icode_coordinator.erl35
-rw-r--r--lib/hipe/icode/hipe_icode_ebb.erl9
-rw-r--r--lib/hipe/icode/hipe_icode_exceptions.erl9
-rw-r--r--lib/hipe/icode/hipe_icode_fp.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_heap_test.erl9
-rw-r--r--lib/hipe/icode/hipe_icode_inline_bifs.erl8
-rw-r--r--lib/hipe/icode/hipe_icode_instruction_counter.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_liveness.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_mulret.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_pp.erl10
-rw-r--r--lib/hipe/icode/hipe_icode_primops.erl14
-rw-r--r--lib/hipe/icode/hipe_icode_primops.hrl8
-rw-r--r--lib/hipe/icode/hipe_icode_range.erl159
-rw-r--r--lib/hipe/icode/hipe_icode_split_arith.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_ssa.erl15
-rw-r--r--lib/hipe/icode/hipe_icode_ssa_const_prop.erl49
-rw-r--r--lib/hipe/icode/hipe_icode_ssa_copy_prop.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_type.erl29
-rw-r--r--lib/hipe/icode/hipe_icode_type.hrl7
-rw-r--r--lib/hipe/llvm/Makefile5
-rw-r--r--lib/hipe/llvm/hipe_llvm.erl40
-rw-r--r--lib/hipe/llvm/hipe_llvm_main.erl47
-rw-r--r--lib/hipe/llvm/hipe_llvm_merge.erl2
-rw-r--r--lib/hipe/llvm/hipe_rtl_to_llvm.erl224
-rw-r--r--lib/hipe/main/hipe.app.src18
-rw-r--r--lib/hipe/main/hipe.erl173
-rw-r--r--lib/hipe/main/hipe.hrl.src16
-rw-r--r--lib/hipe/main/hipe_main.erl6
-rw-r--r--lib/hipe/misc/Makefile2
-rw-r--r--lib/hipe/misc/hipe_consttab.erl21
-rw-r--r--lib/hipe/misc/hipe_consttab.hrl6
-rw-r--r--lib/hipe/misc/hipe_data_pp.erl7
-rw-r--r--lib/hipe/misc/hipe_gensym.erl8
-rw-r--r--lib/hipe/misc/hipe_pack_constants.erl20
-rw-r--r--lib/hipe/misc/hipe_sdi.erl109
-rw-r--r--lib/hipe/misc/hipe_sdi.hrl8
-rw-r--r--lib/hipe/misc/hipe_segment_trees.erl174
-rw-r--r--lib/hipe/opt/Makefile3
-rw-r--r--lib/hipe/opt/hipe_bb_weights.erl449
-rw-r--r--lib/hipe/opt/hipe_schedule.erl11
-rw-r--r--lib/hipe/opt/hipe_schedule_prio.erl6
-rw-r--r--lib/hipe/opt/hipe_spillmin.erl40
-rw-r--r--lib/hipe/opt/hipe_spillmin_color.erl136
-rw-r--r--lib/hipe/opt/hipe_spillmin_scan.erl56
-rw-r--r--lib/hipe/opt/hipe_target_machine.erl7
-rw-r--r--lib/hipe/opt/hipe_ultra_mod2.erl7
-rw-r--r--lib/hipe/opt/hipe_ultra_prio.erl7
-rw-r--r--lib/hipe/ppc/Makefile1
-rw-r--r--lib/hipe/ppc/hipe_ppc.erl34
-rw-r--r--lib/hipe/ppc/hipe_ppc.hrl10
-rw-r--r--lib/hipe/ppc/hipe_ppc_assemble.erl17
-rw-r--r--lib/hipe/ppc/hipe_ppc_cfg.erl46
-rw-r--r--lib/hipe/ppc/hipe_ppc_defuse.erl18
-rw-r--r--lib/hipe/ppc/hipe_ppc_encode.erl6
-rw-r--r--lib/hipe/ppc/hipe_ppc_finalise.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_frame.erl136
-rw-r--r--lib/hipe/ppc/hipe_ppc_liveness_all.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_liveness_fpr.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_liveness_gpr.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_main.erl13
-rw-r--r--lib/hipe/ppc/hipe_ppc_pp.erl13
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra.erl45
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_finalise.erl33
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_ls.erl42
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_naive.erl17
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_postconditions.erl52
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl42
-rw-r--r--lib/hipe/ppc/hipe_ppc_registers.erl9
-rw-r--r--lib/hipe/ppc/hipe_ppc_subst.erl79
-rw-r--r--lib/hipe/ppc/hipe_rtl_to_ppc.erl120
-rw-r--r--lib/hipe/regalloc/Makefile6
-rw-r--r--lib/hipe/regalloc/hipe_adj_list.erl6
-rw-r--r--lib/hipe/regalloc/hipe_amd64_specific.erl9
-rw-r--r--lib/hipe/regalloc/hipe_amd64_specific_sse2.erl209
-rw-r--r--lib/hipe/regalloc/hipe_amd64_specific_x87.erl9
-rw-r--r--lib/hipe/regalloc/hipe_arm_specific.erl180
-rw-r--r--lib/hipe/regalloc/hipe_coalescing_regalloc.erl64
-rw-r--r--lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl98
-rw-r--r--lib/hipe/regalloc/hipe_ig.erl115
-rw-r--r--lib/hipe/regalloc/hipe_ig_moves.erl17
-rw-r--r--lib/hipe/regalloc/hipe_ls_regalloc.erl99
-rw-r--r--lib/hipe/regalloc/hipe_moves.erl7
-rw-r--r--lib/hipe/regalloc/hipe_node_sets.erl7
-rw-r--r--lib/hipe/regalloc/hipe_optimistic_regalloc.erl157
-rw-r--r--lib/hipe/regalloc/hipe_ppc_specific.erl173
-rw-r--r--lib/hipe/regalloc/hipe_ppc_specific_fp.erl167
-rw-r--r--lib/hipe/regalloc/hipe_range_split.erl1187
-rw-r--r--lib/hipe/regalloc/hipe_reg_worklists.erl37
-rw-r--r--lib/hipe/regalloc/hipe_regalloc_loop.erl104
-rw-r--r--lib/hipe/regalloc/hipe_regalloc_prepass.erl953
-rw-r--r--lib/hipe/regalloc/hipe_restore_reuse.erl516
-rw-r--r--lib/hipe/regalloc/hipe_sparc_specific.erl173
-rw-r--r--lib/hipe/regalloc/hipe_sparc_specific_fp.erl167
-rw-r--r--lib/hipe/regalloc/hipe_spillcost.erl7
-rw-r--r--lib/hipe/regalloc/hipe_spillcost.hrl8
-rw-r--r--lib/hipe/regalloc/hipe_temp_map.erl46
-rw-r--r--lib/hipe/regalloc/hipe_x86_specific.erl189
-rw-r--r--lib/hipe/regalloc/hipe_x86_specific_x87.erl115
-rw-r--r--lib/hipe/rtl/Makefile10
-rw-r--r--lib/hipe/rtl/hipe_icode2rtl.erl21
-rw-r--r--lib/hipe/rtl/hipe_rtl.erl102
-rw-r--r--lib/hipe/rtl/hipe_rtl.hrl7
-rw-r--r--lib/hipe/rtl/hipe_rtl_arch.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith.inc6
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith_32.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith_64.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary.erl28
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary_construct.erl189
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary_match.erl48
-rw-r--r--lib/hipe/rtl/hipe_rtl_cfg.erl14
-rw-r--r--lib/hipe/rtl/hipe_rtl_cleanup_const.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_exceptions.erl8
-rw-r--r--lib/hipe/rtl/hipe_rtl_lcm.erl7
-rw-r--r--lib/hipe/rtl/hipe_rtl_liveness.erl8
-rw-r--r--lib/hipe/rtl/hipe_rtl_mk_switch.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_primops.erl29
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssa.erl8
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl7
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl88
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssapre.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_symbolic.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_varmap.erl7
-rw-r--r--lib/hipe/rtl/hipe_tagscheme.erl252
-rw-r--r--lib/hipe/sparc/Makefile3
-rw-r--r--lib/hipe/sparc/hipe_rtl_to_sparc.erl208
-rw-r--r--lib/hipe/sparc/hipe_sparc.erl21
-rw-r--r--lib/hipe/sparc/hipe_sparc.hrl9
-rw-r--r--lib/hipe/sparc/hipe_sparc_assemble.erl9
-rw-r--r--lib/hipe/sparc/hipe_sparc_cfg.erl52
-rw-r--r--lib/hipe/sparc/hipe_sparc_defuse.erl24
-rw-r--r--lib/hipe/sparc/hipe_sparc_encode.erl6
-rw-r--r--lib/hipe/sparc/hipe_sparc_finalise.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_frame.erl113
-rw-r--r--lib/hipe/sparc/hipe_sparc_liveness_all.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_liveness_fpr.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_liveness_gpr.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_main.erl15
-rw-r--r--lib/hipe/sparc/hipe_sparc_pp.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra.erl44
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_finalise.erl33
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_ls.erl42
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_naive.erl17
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_postconditions.erl52
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl43
-rw-r--r--lib/hipe/sparc/hipe_sparc_registers.erl17
-rw-r--r--lib/hipe/sparc/hipe_sparc_subst.erl82
-rw-r--r--lib/hipe/ssa/hipe_ssa.inc28
-rw-r--r--lib/hipe/ssa/hipe_ssa_const_prop.inc6
-rw-r--r--lib/hipe/ssa/hipe_ssa_copy_prop.inc6
-rw-r--r--lib/hipe/ssa/hipe_ssa_liveness.inc33
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl42
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_edge_cases.erl142
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_num_bif.erl217
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_tuples.erl14
-rw-r--r--lib/hipe/test/bs_SUITE_data/bs_pmatch_bugs.erl48
-rw-r--r--lib/hipe/test/hipe_SUITE.erl6
-rw-r--r--lib/hipe/test/hipe_testsuite_driver.erl6
-rw-r--r--lib/hipe/test/maps_SUITE_data/maps_redundant_branch_is_key.erl14
-rw-r--r--lib/hipe/test/maps_SUITE_data/maps_warn_pair_key_overloaded.erl1
-rw-r--r--lib/hipe/test/opt_verify_SUITE.erl39
-rw-r--r--lib/hipe/tools/hipe_jit.erl6
-rw-r--r--lib/hipe/tools/hipe_profile.erl7
-rw-r--r--lib/hipe/tools/hipe_timer.erl13
-rw-r--r--lib/hipe/util/Makefile5
-rw-r--r--lib/hipe/util/hipe_digraph.erl6
-rw-r--r--lib/hipe/util/hipe_dot.erl6
-rw-r--r--lib/hipe/util/hipe_dsets.erl84
-rw-r--r--lib/hipe/util/hipe_timing.erl6
-rw-r--r--lib/hipe/util/hipe_vectors.erl45
-rw-r--r--lib/hipe/vsn.mk2
-rw-r--r--lib/hipe/x86/Makefile3
-rw-r--r--lib/hipe/x86/NOTES.OPTIM2
-rw-r--r--lib/hipe/x86/NOTES.RA2
-rw-r--r--lib/hipe/x86/hipe_rtl_to_x86.erl127
-rw-r--r--lib/hipe/x86/hipe_x86.erl33
-rw-r--r--lib/hipe/x86/hipe_x86.hrl9
-rw-r--r--lib/hipe/x86/hipe_x86_assemble.erl91
-rw-r--r--lib/hipe/x86/hipe_x86_cfg.erl34
-rw-r--r--lib/hipe/x86/hipe_x86_defuse.erl25
-rw-r--r--lib/hipe/x86/hipe_x86_encode.erl30
-rw-r--r--lib/hipe/x86/hipe_x86_encode.txt2
-rw-r--r--lib/hipe/x86/hipe_x86_frame.erl139
-rw-r--r--lib/hipe/x86/hipe_x86_liveness.erl6
-rw-r--r--lib/hipe/x86/hipe_x86_main.erl29
-rw-r--r--lib/hipe/x86/hipe_x86_postpass.erl56
-rw-r--r--lib/hipe/x86/hipe_x86_pp.erl14
-rw-r--r--lib/hipe/x86/hipe_x86_ra.erl100
-rw-r--r--lib/hipe/x86/hipe_x86_ra_finalise.erl97
-rw-r--r--lib/hipe/x86/hipe_x86_ra_ls.erl74
-rw-r--r--lib/hipe/x86/hipe_x86_ra_naive.erl28
-rw-r--r--lib/hipe/x86/hipe_x86_ra_postconditions.erl121
-rw-r--r--lib/hipe/x86/hipe_x86_ra_x87_ls.erl64
-rw-r--r--lib/hipe/x86/hipe_x86_registers.erl10
-rw-r--r--lib/hipe/x86/hipe_x86_spill_restore.erl18
-rw-r--r--lib/hipe/x86/hipe_x86_subst.erl112
-rw-r--r--lib/hipe/x86/hipe_x86_x87.erl11
-rw-r--r--lib/ic/doc/src/Makefile2
-rw-r--r--lib/ic/doc/src/notes.xml24
-rw-r--r--lib/ic/src/ic_codegen.erl8
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE_data/c_client.c4
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c4
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c4
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE_data/c_server.c4
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c4
-rw-r--r--lib/ic/vsn.mk2
-rw-r--r--lib/inets/doc/src/http_server.xml36
-rw-r--r--lib/inets/doc/src/http_uri.xml23
-rw-r--r--lib/inets/doc/src/httpc.xml10
-rw-r--r--lib/inets/doc/src/httpd.xml18
-rw-r--r--lib/inets/doc/src/mod_auth.xml2
-rw-r--r--lib/inets/doc/src/mod_esi.xml4
-rw-r--r--lib/inets/doc/src/notes.xml272
-rw-r--r--lib/inets/src/ftp/ftp.erl181
-rw-r--r--lib/inets/src/ftp/ftp_progress.erl26
-rw-r--r--lib/inets/src/ftp/ftp_response.erl18
-rw-r--r--lib/inets/src/http_client/httpc.erl104
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl825
-rw-r--r--lib/inets/src/http_client/httpc_internal.hrl51
-rw-r--r--lib/inets/src/http_client/httpc_manager.erl4
-rw-r--r--lib/inets/src/http_client/httpc_request.erl6
-rw-r--r--lib/inets/src/http_client/httpc_response.erl42
-rw-r--r--lib/inets/src/http_lib/http_internal.hrl5
-rw-r--r--lib/inets/src/http_lib/http_request.erl20
-rw-r--r--lib/inets/src/http_lib/http_uri.erl79
-rw-r--r--lib/inets/src/http_lib/http_util.erl6
-rw-r--r--lib/inets/src/http_server/httpd_conf.erl12
-rw-r--r--lib/inets/src/http_server/httpd_example.erl11
-rw-r--r--lib/inets/src/http_server/httpd_request_handler.erl17
-rw-r--r--lib/inets/src/http_server/httpd_response.erl2
-rw-r--r--lib/inets/src/http_server/httpd_util.erl6
-rw-r--r--lib/inets/src/http_server/mod_auth_server.erl2
-rw-r--r--lib/inets/src/http_server/mod_esi.erl66
-rw-r--r--lib/inets/src/inets_app/inets.appup.src6
-rw-r--r--lib/inets/src/inets_app/inets_lib.erl2
-rw-r--r--lib/inets/test/ftp_SUITE.erl126
-rw-r--r--lib/inets/test/ftp_format_SUITE.erl13
-rw-r--r--lib/inets/test/http_format_SUITE.erl2
-rw-r--r--lib/inets/test/httpc_SUITE.erl149
-rw-r--r--lib/inets/test/httpd_1_1.erl6
-rw-r--r--lib/inets/test/httpd_SUITE.erl85
-rw-r--r--lib/inets/test/httpd_basic_SUITE.erl15
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/httpd.conf4
-rw-r--r--lib/inets/test/inets_SUITE.erl14
-rw-r--r--lib/inets/test/inets_socketwrap_SUITE.erl2
-rw-r--r--lib/inets/test/inets_sup_SUITE.erl38
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf4
-rw-r--r--lib/inets/test/uri_SUITE.erl106
-rw-r--r--lib/inets/vsn.mk4
-rw-r--r--lib/jinterface/doc/src/Makefile2
-rw-r--r--lib/jinterface/doc/src/notes.xml44
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java4
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java4
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java31
-rw-r--r--lib/jinterface/test/jinterface_SUITE_data/Maps.java12
-rw-r--r--lib/jinterface/vsn.mk2
-rw-r--r--lib/kernel/doc/src/app.xml6
-rw-r--r--lib/kernel/doc/src/application.xml6
-rw-r--r--lib/kernel/doc/src/auth.xml4
-rw-r--r--lib/kernel/doc/src/code.xml79
-rw-r--r--lib/kernel/doc/src/config.xml6
-rw-r--r--lib/kernel/doc/src/disk_log.xml27
-rw-r--r--lib/kernel/doc/src/erl_boot_server.xml4
-rw-r--r--lib/kernel/doc/src/erl_ddll.xml6
-rw-r--r--lib/kernel/doc/src/error_logger.xml65
-rw-r--r--lib/kernel/doc/src/file.xml36
-rw-r--r--lib/kernel/doc/src/gen_tcp.xml31
-rw-r--r--lib/kernel/doc/src/gen_udp.xml6
-rw-r--r--lib/kernel/doc/src/heart.xml19
-rw-r--r--lib/kernel/doc/src/inet.xml89
-rw-r--r--lib/kernel/doc/src/init_stub.xml2
-rw-r--r--lib/kernel/doc/src/kernel_app.xml131
-rw-r--r--lib/kernel/doc/src/net_kernel.xml63
-rw-r--r--lib/kernel/doc/src/notes.xml344
-rw-r--r--lib/kernel/doc/src/os.xml34
-rw-r--r--lib/kernel/doc/src/rpc.xml20
-rw-r--r--lib/kernel/doc/src/seq_trace.xml12
-rw-r--r--lib/kernel/doc/src/zlib_stub.xml2
-rw-r--r--lib/kernel/include/dist_util.hrl10
-rw-r--r--lib/kernel/include/inet.hrl4
-rw-r--r--lib/kernel/src/Makefile4
-rw-r--r--lib/kernel/src/application_controller.erl4
-rw-r--r--lib/kernel/src/code.erl178
-rw-r--r--lib/kernel/src/code_server.erl69
-rw-r--r--lib/kernel/src/disk_log.erl401
-rw-r--r--lib/kernel/src/disk_log.hrl10
-rw-r--r--lib/kernel/src/disk_log_1.erl62
-rw-r--r--lib/kernel/src/dist_ac.erl12
-rw-r--r--lib/kernel/src/dist_util.erl141
-rw-r--r--lib/kernel/src/erl_epmd.erl6
-rw-r--r--lib/kernel/src/erl_signal_handler.erl57
-rw-r--r--lib/kernel/src/error_logger.erl30
-rw-r--r--lib/kernel/src/erts_debug.erl25
-rw-r--r--lib/kernel/src/file.erl53
-rw-r--r--lib/kernel/src/gen_sctp.erl2
-rw-r--r--lib/kernel/src/gen_tcp.erl2
-rw-r--r--lib/kernel/src/gen_udp.erl2
-rw-r--r--lib/kernel/src/global.erl21
-rw-r--r--lib/kernel/src/global_group.erl2
-rw-r--r--lib/kernel/src/group.erl5
-rw-r--r--lib/kernel/src/group_history.erl341
-rw-r--r--lib/kernel/src/heart.erl15
-rw-r--r--lib/kernel/src/hipe_ext_format.hrl12
-rw-r--r--lib/kernel/src/hipe_unified_loader.erl379
-rw-r--r--lib/kernel/src/inet.erl21
-rw-r--r--lib/kernel/src/inet6_tcp_dist.erl7
-rw-r--r--lib/kernel/src/inet_db.erl3
-rw-r--r--lib/kernel/src/inet_int.hrl4
-rw-r--r--lib/kernel/src/inet_parse.erl104
-rw-r--r--lib/kernel/src/inet_tcp_dist.erl35
-rw-r--r--lib/kernel/src/inet_udp.erl8
-rw-r--r--lib/kernel/src/kernel.app.src6
-rw-r--r--lib/kernel/src/kernel.appup.src8
-rw-r--r--lib/kernel/src/kernel.erl255
-rw-r--r--lib/kernel/src/net_kernel.erl172
-rw-r--r--lib/kernel/src/os.erl95
-rw-r--r--lib/kernel/src/rpc.erl16
-rw-r--r--lib/kernel/test/application_SUITE.erl4
-rw-r--r--lib/kernel/test/code_SUITE.erl394
-rw-r--r--lib/kernel/test/code_SUITE_data/upgrade_client.erl93
-rw-r--r--lib/kernel/test/code_SUITE_data/upgradee.erl12
-rw-r--r--lib/kernel/test/disk_log_SUITE.erl33
-rw-r--r--lib/kernel/test/erl_distribution_SUITE.erl278
-rw-r--r--lib/kernel/test/erl_distribution_wb_SUITE.erl10
-rw-r--r--lib/kernel/test/error_logger_SUITE.erl15
-rw-r--r--lib/kernel/test/file_SUITE.erl60
-rw-r--r--lib/kernel/test/file_SUITE_data/realmen.html4
-rw-r--r--lib/kernel/test/file_name_SUITE.erl4
-rw-r--r--lib/kernel/test/gen_sctp_SUITE.erl148
-rw-r--r--lib/kernel/test/gen_tcp_api_SUITE.erl27
-rw-r--r--lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c2
-rw-r--r--lib/kernel/test/gen_tcp_misc_SUITE.erl2
-rw-r--r--lib/kernel/test/gen_udp_SUITE.erl6
-rw-r--r--lib/kernel/test/inet_SUITE.erl230
-rw-r--r--lib/kernel/test/inet_sockopt_SUITE.erl4
-rw-r--r--lib/kernel/test/init_SUITE.erl61
-rw-r--r--lib/kernel/test/interactive_shell_SUITE.erl2
-rw-r--r--lib/kernel/test/multi_load_SUITE.erl10
-rw-r--r--lib/kernel/test/os_SUITE.erl100
-rw-r--r--lib/kernel/test/os_SUITE_data/Makefile.src8
-rw-r--r--lib/kernel/test/os_SUITE_data/my_fds.c9
-rw-r--r--lib/kernel/test/pdict_SUITE.erl60
-rw-r--r--lib/kernel/test/pg2_SUITE.erl29
-rw-r--r--lib/kernel/test/prim_file_SUITE.erl49
-rw-r--r--lib/kernel/test/rpc_SUITE.erl14
-rw-r--r--lib/kernel/test/sendfile_SUITE.erl6
-rw-r--r--lib/kernel/test/zlib_SUITE.erl38
-rw-r--r--lib/kernel/vsn.mk2
-rw-r--r--lib/megaco/doc/src/notes.xml19
-rw-r--r--lib/megaco/src/app/megaco.appup.src2
-rw-r--r--lib/megaco/src/text/megaco_text_gen_prev3a.hrl4
-rw-r--r--lib/megaco/src/text/megaco_text_gen_prev3b.hrl4
-rw-r--r--lib/megaco/src/text/megaco_text_gen_prev3c.hrl4
-rw-r--r--lib/megaco/test/megaco_app_test.erl308
-rw-r--r--lib/megaco/test/megaco_appup_test.erl498
-rw-r--r--lib/megaco/vsn.mk4
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap1.xml28
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap3.xmlsrc2
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap5.xmlsrc5
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap8.xml8
-rw-r--r--lib/mnesia/doc/src/Mnesia_overview.xml42
-rw-r--r--lib/mnesia/doc/src/mnesia.xml336
-rw-r--r--lib/mnesia/doc/src/mnesia_frag_hash.xml12
-rw-r--r--lib/mnesia/doc/src/mnesia_registry.xml12
-rw-r--r--lib/mnesia/doc/src/notes.xml85
-rw-r--r--lib/mnesia/doc/src/part.xml2
-rw-r--r--lib/mnesia/doc/src/ref_man.xml2
-rw-r--r--lib/mnesia/src/Makefile5
-rw-r--r--lib/mnesia/src/mnesia.app.src7
-rw-r--r--lib/mnesia/src/mnesia.erl327
-rw-r--r--lib/mnesia/src/mnesia.hrl7
-rw-r--r--lib/mnesia/src/mnesia_app.erl (renamed from lib/percept/src/percept.appup.src)31
-rw-r--r--lib/mnesia/src/mnesia_checkpoint.erl9
-rw-r--r--lib/mnesia/src/mnesia_controller.erl11
-rw-r--r--lib/mnesia/src/mnesia_event.erl5
-rw-r--r--lib/mnesia/src/mnesia_frag.erl76
-rw-r--r--lib/mnesia/src/mnesia_frag_old_hash.erl133
-rw-r--r--lib/mnesia/src/mnesia_kernel_sup.erl3
-rw-r--r--lib/mnesia/src/mnesia_lib.erl16
-rw-r--r--lib/mnesia/src/mnesia_loader.erl17
-rw-r--r--lib/mnesia/src/mnesia_monitor.erl4
-rw-r--r--lib/mnesia/src/mnesia_schema.erl22
-rw-r--r--lib/mnesia/src/mnesia_snmp_sup.erl43
-rw-r--r--lib/mnesia/src/mnesia_sup.erl33
-rw-r--r--lib/mnesia/src/mnesia_tm.erl3
-rw-r--r--lib/mnesia/test/ext_test.erl6
-rw-r--r--lib/mnesia/test/mnesia_evil_backup.erl45
-rw-r--r--lib/mnesia/test/mnesia_test_lib.erl1
-rw-r--r--lib/mnesia/test/mnesia_trans_access_test.erl10
-rw-r--r--lib/mnesia/vsn.mk2
-rw-r--r--lib/observer/doc/src/etop.xml10
-rw-r--r--lib/observer/doc/src/notes.xml187
-rw-r--r--lib/observer/doc/src/observer.xml4
-rw-r--r--lib/observer/doc/src/observer_ug.xml7
-rw-r--r--lib/observer/doc/src/ttb.xml18
-rwxr-xr-xlib/observer/priv/bin/cdv2
-rw-r--r--lib/observer/priv/bin/cdv.bat2
-rw-r--r--lib/observer/priv/crashdump_viewer.tool2
-rw-r--r--lib/observer/priv/crashdump_viewer/collapsd.gifbin141 -> 0 bytes
-rw-r--r--lib/observer/priv/crashdump_viewer/exploded.gifbin143 -> 0 bytes
-rw-r--r--lib/observer/src/Makefile10
-rw-r--r--lib/observer/src/cdv_bin_cb.erl4
-rw-r--r--lib/observer/src/cdv_detail_wx.erl4
-rw-r--r--lib/observer/src/cdv_ets_cb.erl28
-rw-r--r--lib/observer/src/cdv_mem_cb.erl4
-rw-r--r--lib/observer/src/cdv_wx.erl2
-rw-r--r--lib/observer/src/crashdump_viewer.erl102
-rw-r--r--lib/observer/src/crashdump_viewer.hrl3
-rw-r--r--lib/observer/src/etop.erl40
-rw-r--r--lib/observer/src/etop_txt.erl65
-rw-r--r--lib/observer/src/observer_alloc_wx.erl72
-rw-r--r--lib/observer/src/observer_app_wx.erl20
-rw-r--r--lib/observer/src/observer_lib.erl67
-rw-r--r--lib/observer/src/observer_perf_wx.erl164
-rw-r--r--lib/observer/src/observer_port_wx.erl230
-rw-r--r--lib/observer/src/observer_pro_wx.erl210
-rw-r--r--lib/observer/src/observer_procinfo.erl21
-rw-r--r--lib/observer/src/observer_sys_wx.erl15
-rw-r--r--lib/observer/src/observer_trace_wx.erl73
-rw-r--r--lib/observer/src/observer_tv_table.erl32
-rw-r--r--lib/observer/src/observer_tv_wx.erl118
-rw-r--r--lib/observer/src/observer_wx.erl160
-rw-r--r--lib/observer/src/ttb.erl21
-rw-r--r--lib/observer/test/crashdump_helper.erl6
-rw-r--r--lib/observer/test/crashdump_viewer_SUITE.erl39
-rw-r--r--lib/observer/test/observer_SUITE.erl19
-rw-r--r--lib/observer/vsn.mk2
-rw-r--r--lib/odbc/configure.in24
-rw-r--r--lib/odbc/doc/src/notes.xml41
-rw-r--r--lib/odbc/test/odbc_connect_SUITE.erl188
-rw-r--r--lib/odbc/test/odbc_data_type_SUITE.erl421
-rw-r--r--lib/odbc/test/odbc_query_SUITE.erl464
-rw-r--r--lib/odbc/test/odbc_start_SUITE.erl37
-rw-r--r--lib/odbc/test/odbc_test_lib.erl6
-rw-r--r--lib/odbc/vsn.mk2
-rw-r--r--lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl24
-rw-r--r--lib/orber/doc/src/notes.xml14
-rw-r--r--lib/orber/src/cdr_encode.erl4
-rw-r--r--lib/orber/src/corba.erl4
-rw-r--r--lib/orber/src/orber_ifr_contained.erl2
-rw-r--r--lib/orber/src/orber_iiop.hrl6
-rw-r--r--lib/orber/src/orber_initial_references.erl4
-rw-r--r--lib/orber/src/orber_objectkeys.erl4
-rw-r--r--lib/orber/test/multi_ORB_SUITE.erl7
-rw-r--r--lib/orber/test/orber_test_lib.erl36
-rw-r--r--lib/orber/vsn.mk2
-rw-r--r--lib/os_mon/doc/src/notes.xml15
-rw-r--r--lib/os_mon/src/Makefile2
-rw-r--r--lib/os_mon/src/memsup.erl1
-rw-r--r--lib/os_mon/vsn.mk2
-rw-r--r--lib/otp_mibs/src/Makefile2
-rw-r--r--lib/parsetools/doc/src/leex.xml5
-rw-r--r--lib/parsetools/doc/src/notes.xml65
-rw-r--r--lib/parsetools/doc/src/yecc.xml6
-rw-r--r--lib/parsetools/include/leexinc.hrl35
-rw-r--r--lib/parsetools/include/yeccpre.hrl13
-rw-r--r--lib/parsetools/src/Makefile2
-rw-r--r--lib/parsetools/src/leex.erl100
-rw-r--r--lib/parsetools/src/yecc.erl255
-rw-r--r--lib/parsetools/src/yeccgramm.yrl45
-rw-r--r--lib/parsetools/src/yeccparser.erl192
-rw-r--r--lib/parsetools/test/leex_SUITE.erl93
-rw-r--r--lib/parsetools/test/yecc_SUITE.erl102
-rw-r--r--lib/parsetools/vsn.mk2
-rw-r--r--lib/percept/AUTHORS4
-rw-r--r--lib/percept/Makefile35
-rw-r--r--lib/percept/c_src/.gitignore0
-rw-r--r--lib/percept/doc/html/.gitignore0
-rw-r--r--lib/percept/doc/man3/.gitignore0
-rw-r--r--lib/percept/doc/pdf/.gitignore0
-rw-r--r--lib/percept/doc/src/Makefile190
-rw-r--r--lib/percept/doc/src/book.xml52
-rw-r--r--lib/percept/doc/src/egd_ug.xmlsrc90
-rw-r--r--lib/percept/doc/src/fascicules.xml18
-rw-r--r--lib/percept/doc/src/img.erl50
-rw-r--r--lib/percept/doc/src/img_esi.erl25
-rw-r--r--lib/percept/doc/src/img_esi_result.gifbin374 -> 0 bytes
-rw-r--r--lib/percept/doc/src/ipc_tree.erl30
-rw-r--r--lib/percept/doc/src/notes.xml495
-rw-r--r--lib/percept/doc/src/part.xml47
-rw-r--r--lib/percept/doc/src/part_notes.xml41
-rw-r--r--lib/percept/doc/src/percept_compare.gifbin241343 -> 0 bytes
-rw-r--r--lib/percept/doc/src/percept_examples.html11
-rw-r--r--lib/percept/doc/src/percept_overview.gifbin158719 -> 0 bytes
-rw-r--r--lib/percept/doc/src/percept_processes.gifbin182273 -> 0 bytes
-rw-r--r--lib/percept/doc/src/percept_processinfo.gifbin135512 -> 0 bytes
-rw-r--r--lib/percept/doc/src/percept_ug.xmlsrc223
-rw-r--r--lib/percept/doc/src/ref_man.xml48
-rw-r--r--lib/percept/doc/src/sorter.erl41
-rw-r--r--lib/percept/doc/src/test1.gifbin951 -> 0 bytes
-rw-r--r--lib/percept/doc/src/test2.gifbin1035 -> 0 bytes
-rw-r--r--lib/percept/doc/src/test3.gifbin2382 -> 0 bytes
-rw-r--r--lib/percept/doc/src/test4.gifbin2294 -> 0 bytes
-rw-r--r--lib/percept/doc/stylesheet.css39
-rw-r--r--lib/percept/ebin/.gitignore0
-rw-r--r--lib/percept/include/.gitignore0
-rw-r--r--lib/percept/info2
-rw-r--r--lib/percept/priv/Makefile97
-rw-r--r--lib/percept/priv/fonts/6x11_latin1.wingsfontbin2016 -> 0 bytes
-rw-r--r--lib/percept/priv/logs/.gitignore0
-rw-r--r--lib/percept/priv/obj/.gitignore0
-rw-r--r--lib/percept/priv/server_root/cgi-bin/.gitignore0
-rw-r--r--lib/percept/priv/server_root/conf/mime.types462
-rw-r--r--lib/percept/priv/server_root/css/percept.css162
-rw-r--r--lib/percept/priv/server_root/htdocs/index.html41
-rw-r--r--lib/percept/priv/server_root/images/nav.pngbin560 -> 0 bytes
-rw-r--r--lib/percept/priv/server_root/images/white.pngbin69 -> 0 bytes
-rw-r--r--lib/percept/priv/server_root/scripts/percept_area_select.js182
-rw-r--r--lib/percept/priv/server_root/scripts/percept_error_handler.js26
-rw-r--r--lib/percept/priv/server_root/scripts/percept_select_all.js28
-rw-r--r--lib/percept/src/Makefile108
-rw-r--r--lib/percept/src/egd.erl275
-rw-r--r--lib/percept/src/egd.hrl45
-rw-r--r--lib/percept/src/egd_font.erl173
-rw-r--r--lib/percept/src/egd_png.erl105
-rw-r--r--lib/percept/src/egd_primitives.erl412
-rw-r--r--lib/percept/src/egd_render.erl664
-rw-r--r--lib/percept/src/percept.app.src45
-rw-r--r--lib/percept/src/percept.erl337
-rw-r--r--lib/percept/src/percept.hrl53
-rw-r--r--lib/percept/src/percept_analyzer.erl368
-rw-r--r--lib/percept/src/percept_db.erl780
-rw-r--r--lib/percept/src/percept_graph.erl134
-rw-r--r--lib/percept/src/percept_html.erl707
-rw-r--r--lib/percept/src/percept_image.erl316
-rw-r--r--lib/percept/test/Makefile91
-rw-r--r--lib/percept/test/egd_SUITE.erl389
-rw-r--r--lib/percept/test/ipc_tree.erl49
-rw-r--r--lib/percept/test/percept.cover2
-rw-r--r--lib/percept/test/percept.spec1
-rw-r--r--lib/percept/test/percept_SUITE.erl126
-rw-r--r--lib/percept/test/percept_SUITE_data/ipc-dist.datbin2098105 -> 0 bytes
-rw-r--r--lib/percept/test/percept_db_SUITE.erl55
-rw-r--r--lib/percept/vsn.mk1
-rw-r--r--lib/public_key/asn1/PKCS-8.asn12
-rw-r--r--lib/public_key/doc/src/notes.xml82
-rw-r--r--lib/public_key/doc/src/public_key.xml80
-rw-r--r--lib/public_key/doc/src/public_key_app.xml4
-rw-r--r--lib/public_key/doc/src/using_public_key.xml253
-rw-r--r--lib/public_key/src/pubkey_ssh.erl35
-rw-r--r--lib/public_key/src/public_key.app.src2
-rw-r--r--lib/public_key/src/public_key.erl298
-rw-r--r--lib/public_key/test/erl_make_certs.erl16
-rw-r--r--lib/public_key/test/pbe_SUITE.erl7
-rw-r--r--lib/public_key/test/public_key.cover2
-rw-r--r--lib/public_key/test/public_key_SUITE.erl205
-rw-r--r--lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_cn.pem17
-rw-r--r--lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_subjAltName.pem14
-rw-r--r--lib/public_key/test/public_key_SUITE_data/verify_hostname.conf16
-rw-r--r--lib/public_key/vsn.mk2
-rw-r--r--lib/reltool/doc/src/notes.xml70
-rw-r--r--lib/reltool/doc/src/part.xml2
-rw-r--r--lib/reltool/doc/src/ref_man.xml2
-rw-r--r--lib/reltool/doc/src/reltool.xml8
-rw-r--r--lib/reltool/doc/src/reltool_examples.xml631
-rw-r--r--lib/reltool/doc/src/reltool_intro.xml4
-rw-r--r--lib/reltool/src/reltool.hrl28
-rw-r--r--lib/reltool/src/reltool_server.erl151
-rw-r--r--lib/reltool/test/reltool_server_SUITE.erl37
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/x-1.0/ebin/x.app7
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/x-1.0/src/x1.erl5
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/y-1.0/ebin/y.app8
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/y-1.0/src/y1.erl5
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/z-1.0/ebin/z.app7
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/z-1.0/src/z1.erl5
-rw-r--r--lib/reltool/vsn.mk2
-rw-r--r--lib/runtime_tools/c_src/dyntrace.c2
-rw-r--r--lib/runtime_tools/doc/src/LTTng.xml4
-rw-r--r--lib/runtime_tools/doc/src/dbg.xml4
-rw-r--r--lib/runtime_tools/doc/src/notes.xml104
-rw-r--r--lib/runtime_tools/src/Makefile3
-rw-r--r--lib/runtime_tools/src/dbg.erl222
-rw-r--r--lib/runtime_tools/src/dyntrace.erl2
-rw-r--r--lib/runtime_tools/src/msacc.erl2
-rw-r--r--lib/runtime_tools/src/observer_backend.erl81
-rw-r--r--lib/runtime_tools/src/percept_profile.erl195
-rw-r--r--lib/runtime_tools/src/runtime_tools.app.src8
-rw-r--r--lib/runtime_tools/test/dbg_SUITE_data/dbg_SUITE.c4
-rw-r--r--lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat5
-rw-r--r--lib/runtime_tools/vsn.mk2
-rw-r--r--lib/sasl/doc/src/alarm_handler.xml4
-rw-r--r--lib/sasl/doc/src/appup.xml10
-rw-r--r--lib/sasl/doc/src/error_logging.xml18
-rw-r--r--lib/sasl/doc/src/notes.xml126
-rw-r--r--lib/sasl/doc/src/part.xml2
-rw-r--r--lib/sasl/doc/src/rb.xml6
-rw-r--r--lib/sasl/doc/src/ref_man.xml2
-rw-r--r--lib/sasl/doc/src/rel.xml6
-rw-r--r--lib/sasl/doc/src/release_handler.xml20
-rw-r--r--lib/sasl/doc/src/sasl_app.xml24
-rw-r--r--lib/sasl/doc/src/sasl_intro.xml2
-rw-r--r--lib/sasl/doc/src/script.xml2
-rw-r--r--lib/sasl/doc/src/systools.xml14
-rw-r--r--lib/sasl/src/format_lib_supp.erl123
-rw-r--r--lib/sasl/src/misc_supp.erl20
-rw-r--r--lib/sasl/src/rb.erl113
-rw-r--r--lib/sasl/src/rb_format_supp.erl10
-rw-r--r--lib/sasl/src/release_handler.erl18
-rw-r--r--lib/sasl/src/sasl.app.src2
-rw-r--r--lib/sasl/src/sasl.appup.src6
-rw-r--r--lib/sasl/src/sasl_report.erl14
-rw-r--r--lib/sasl/src/systools_make.erl221
-rw-r--r--lib/sasl/src/systools_rc.erl32
-rw-r--r--lib/sasl/src/systools_relup.erl158
-rw-r--r--lib/sasl/test/release_handler_SUITE.erl18
-rwxr-xr-xlib/sasl/test/release_handler_SUITE_data/start3
-rwxr-xr-xlib/sasl/test/release_handler_SUITE_data/start_client3
-rw-r--r--lib/sasl/test/rh_test_lib.erl2
-rw-r--r--lib/sasl/test/sasl_report_SUITE.erl4
-rw-r--r--lib/sasl/test/systools_SUITE.erl167
-rw-r--r--lib/sasl/test/test_lib.hrl4
-rw-r--r--lib/sasl/vsn.mk2
-rw-r--r--lib/snmp/doc/src/notes.xml69
-rw-r--r--lib/snmp/src/agent/snmp_generic.erl30
-rw-r--r--lib/snmp/src/agent/snmpa_conf.erl16
-rw-r--r--lib/snmp/src/app/snmp.app.src14
-rw-r--r--lib/snmp/src/app/snmp.appup.src8
-rw-r--r--lib/snmp/src/app/snmp.erl80
-rw-r--r--lib/snmp/src/compile/snmpc.erl13
-rw-r--r--lib/snmp/src/compile/snmpc_lib.erl4
-rw-r--r--lib/snmp/src/compile/snmpc_mib_gram.yrl6
-rw-r--r--lib/snmp/src/compile/snmpc_misc.erl20
-rw-r--r--lib/snmp/test/modules.mk1
-rw-r--r--lib/snmp/test/snmp_SUITE.erl4
-rw-r--r--lib/snmp/test/snmp_agent_conf_test.erl210
-rw-r--r--lib/snmp/test/snmp_agent_test.erl26
-rw-r--r--lib/snmp/test/snmp_app_test.erl381
-rw-r--r--lib/snmp/test/snmp_compiler_test.erl32
-rw-r--r--lib/snmp/test/snmp_manager_test.erl40
-rw-r--r--lib/snmp/test/snmp_test_data/OTP14145-MIB.mib44
-rw-r--r--lib/snmp/test/snmp_to_snmpnet_SUITE.erl10
-rw-r--r--lib/snmp/vsn.mk4
-rw-r--r--lib/ssh/doc/src/introduction.xml2
-rw-r--r--lib/ssh/doc/src/notes.xml480
-rw-r--r--lib/ssh/doc/src/ssh.xml167
-rw-r--r--lib/ssh/doc/src/ssh_app.xml55
-rw-r--r--lib/ssh/doc/src/ssh_channel.xml2
-rw-r--r--lib/ssh/doc/src/ssh_protocol.xml4
-rw-r--r--lib/ssh/doc/src/ssh_sftp.xml12
-rw-r--r--lib/ssh/doc/src/using_ssh.xml4
-rw-r--r--lib/ssh/src/Makefile5
-rw-r--r--lib/ssh/src/ssh.app.src8
-rw-r--r--lib/ssh/src/ssh.appup.src6
-rw-r--r--lib/ssh/src/ssh.erl1048
-rw-r--r--lib/ssh/src/ssh.hrl80
-rw-r--r--lib/ssh/src/ssh_acceptor.erl145
-rw-r--r--lib/ssh/src/ssh_acceptor_sup.erl63
-rw-r--r--lib/ssh/src/ssh_auth.erl495
-rw-r--r--lib/ssh/src/ssh_bits.erl46
-rw-r--r--lib/ssh/src/ssh_channel.erl9
-rw-r--r--lib/ssh/src/ssh_cli.erl43
-rw-r--r--lib/ssh/src/ssh_connect.hrl6
-rw-r--r--lib/ssh/src/ssh_connection.erl73
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl814
-rw-r--r--lib/ssh/src/ssh_connection_sup.erl30
-rw-r--r--lib/ssh/src/ssh_dbg.erl222
-rw-r--r--lib/ssh/src/ssh_dbg.hrl (renamed from lib/hipe/amd64/hipe_amd64_ra_x87_ls.erl)14
-rw-r--r--lib/ssh/src/ssh_file.erl43
-rw-r--r--lib/ssh/src/ssh_info.erl2
-rw-r--r--lib/ssh/src/ssh_io.erl64
-rw-r--r--lib/ssh/src/ssh_message.erl48
-rw-r--r--lib/ssh/src/ssh_options.erl904
-rw-r--r--lib/ssh/src/ssh_sftp.erl225
-rw-r--r--lib/ssh/src/ssh_sftpd.erl83
-rw-r--r--lib/ssh/src/ssh_sftpd_file_api.erl4
-rw-r--r--lib/ssh/src/ssh_subsystem_sup.erl77
-rw-r--r--lib/ssh/src/ssh_sup.erl77
-rw-r--r--lib/ssh/src/ssh_system_sup.erl196
-rw-r--r--lib/ssh/src/ssh_transport.erl870
-rw-r--r--lib/ssh/src/ssh_transport.hrl30
-rw-r--r--lib/ssh/src/sshc_sup.erl45
-rw-r--r--lib/ssh/src/sshd_sup.erl111
-rw-r--r--lib/ssh/test/Makefile8
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_info_timing.erl92
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_encode_decode.erl374
-rw-r--r--lib/ssh/test/ssh.cover1
-rw-r--r--lib/ssh/test/ssh.spec4
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE.erl270
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa3846
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa5217
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl280
-rw-r--r--lib/ssh/test/ssh_bench.spec3
-rw-r--r--lib/ssh/test/ssh_bench_SUITE.erl252
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/id_dsa (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/id_dsa)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa256 (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa256.pub (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256.pub)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa384 (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa384.pub (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384.pub)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa521 (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa521.pub (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521.pub)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/id_rsa (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/id_rsa)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/ssh_host_dsa_key (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/ssh_host_dsa_key.pub (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key.pub)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key256 (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key256.pub (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256.pub)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key384 (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key384.pub (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384.pub)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key521 (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key521.pub (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521.pub)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/ssh_host_rsa_key (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key)0
-rw-r--r--lib/ssh/test/ssh_bench_SUITE_data/ssh_host_rsa_key.pub (renamed from lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key.pub)0
-rw-r--r--lib/ssh/test/ssh_bench_dev_null.erl58
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE.erl563
-rw-r--r--lib/ssh/test/ssh_connection_SUITE.erl206
-rw-r--r--lib/ssh/test/ssh_eqc_event_handler.erl43
-rw-r--r--lib/ssh/test/ssh_key_cb.erl6
-rw-r--r--lib/ssh/test/ssh_key_cb_options.erl4
-rw-r--r--lib/ssh/test/ssh_options_SUITE.erl160
-rw-r--r--lib/ssh/test/ssh_property_test_SUITE.erl15
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE.erl244
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test4
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli5
-rw-r--r--lib/ssh/test/ssh_relay.erl7
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE.erl40
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE.erl28
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_sftpd_SUITE.erl172
-rw-r--r--lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl7
-rw-r--r--lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_sup_SUITE.erl144
-rw-r--r--lib/ssh/test/ssh_test_lib.erl294
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE.erl234
-rw-r--r--lib/ssh/test/ssh_trpt_test_lib.erl47
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE.erl4
-rw-r--r--lib/ssh/vsn.mk2
-rw-r--r--lib/ssl/doc/src/notes.xml342
-rw-r--r--lib/ssl/doc/src/ssl.xml81
-rw-r--r--lib/ssl/doc/src/ssl_app.xml10
-rw-r--r--lib/ssl/doc/src/ssl_crl_cache_api.xml2
-rw-r--r--lib/ssl/doc/src/ssl_distribution.xml6
-rw-r--r--lib/ssl/doc/src/ssl_session_cache_api.xml31
-rw-r--r--lib/ssl/src/Makefile20
-rw-r--r--lib/ssl/src/dtls_connection.erl915
-rw-r--r--lib/ssl/src/dtls_connection.hrl20
-rw-r--r--lib/ssl/src/dtls_connection_sup.erl2
-rw-r--r--lib/ssl/src/dtls_handshake.erl596
-rw-r--r--lib/ssl/src/dtls_handshake.hrl18
-rw-r--r--lib/ssl/src/dtls_record.erl477
-rw-r--r--lib/ssl/src/dtls_record.hrl9
-rw-r--r--lib/ssl/src/dtls_socket.erl156
-rw-r--r--lib/ssl/src/dtls_udp_listener.erl304
-rw-r--r--lib/ssl/src/dtls_udp_sup.erl62
-rw-r--r--lib/ssl/src/dtls_v1.erl40
-rw-r--r--lib/ssl/src/ssl.app.src20
-rw-r--r--lib/ssl/src/ssl.appup.src3
-rw-r--r--lib/ssl/src/ssl.erl458
-rw-r--r--lib/ssl/src/ssl_admin_sup.erl95
-rw-r--r--lib/ssl/src/ssl_alert.erl13
-rw-r--r--lib/ssl/src/ssl_alert.hrl2
-rw-r--r--lib/ssl/src/ssl_certificate.erl59
-rw-r--r--lib/ssl/src/ssl_cipher.erl142
-rw-r--r--lib/ssl/src/ssl_config.erl54
-rw-r--r--lib/ssl/src/ssl_connection.erl897
-rw-r--r--lib/ssl/src/ssl_connection.hrl24
-rw-r--r--lib/ssl/src/ssl_connection_sup.erl101
-rw-r--r--lib/ssl/src/ssl_crl.erl64
-rw-r--r--lib/ssl/src/ssl_crl_cache.erl2
-rw-r--r--lib/ssl/src/ssl_crl_cache_api.erl2
-rw-r--r--lib/ssl/src/ssl_dist_admin_sup.erl74
-rw-r--r--lib/ssl/src/ssl_dist_connection_sup.erl79
-rw-r--r--lib/ssl/src/ssl_dist_sup.erl42
-rw-r--r--lib/ssl/src/ssl_handshake.erl439
-rw-r--r--lib/ssl/src/ssl_handshake.hrl3
-rw-r--r--lib/ssl/src/ssl_internal.hrl14
-rw-r--r--lib/ssl/src/ssl_listen_tracker_sup.erl4
-rw-r--r--lib/ssl/src/ssl_manager.erl180
-rw-r--r--lib/ssl/src/ssl_pem_cache.erl266
-rw-r--r--lib/ssl/src/ssl_pkix_db.erl135
-rw-r--r--lib/ssl/src/ssl_record.erl530
-rw-r--r--lib/ssl/src/ssl_record.hrl42
-rw-r--r--lib/ssl/src/ssl_sup.erl76
-rw-r--r--lib/ssl/src/ssl_tls_dist_proxy.erl2
-rw-r--r--lib/ssl/src/tls_connection.erl673
-rw-r--r--lib/ssl/src/tls_handshake.erl131
-rw-r--r--lib/ssl/src/tls_record.erl451
-rw-r--r--lib/ssl/src/tls_socket.erl (renamed from lib/ssl/src/ssl_socket.erl)93
-rw-r--r--lib/ssl/src/tls_v1.erl66
-rw-r--r--lib/ssl/test/Makefile5
-rw-r--r--lib/ssl/test/erl_make_certs.erl4
-rw-r--r--lib/ssl/test/make_certs.erl18
-rw-r--r--lib/ssl/test/ssl.spec3
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE.erl479
-rw-r--r--lib/ssl/test/ssl_alpn_handshake_SUITE.erl4
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl457
-rw-r--r--lib/ssl/test/ssl_bench_SUITE.erl128
-rw-r--r--lib/ssl/test/ssl_certificate_verify_SUITE.erl621
-rw-r--r--lib/ssl/test/ssl_crl_SUITE.erl98
-rw-r--r--lib/ssl/test/ssl_dist_SUITE.erl350
-rw-r--r--lib/ssl/test/ssl_handshake_SUITE.erl13
-rw-r--r--lib/ssl/test/ssl_npn_handshake_SUITE.erl2
-rw-r--r--lib/ssl/test/ssl_npn_hello_SUITE.erl28
-rw-r--r--lib/ssl/test/ssl_packet_SUITE.erl78
-rw-r--r--lib/ssl/test/ssl_payload_SUITE.erl11
-rw-r--r--lib/ssl/test/ssl_pem_cache_SUITE.erl11
-rw-r--r--lib/ssl/test/ssl_session_cache_SUITE.erl4
-rw-r--r--lib/ssl/test/ssl_sni_SUITE.erl2
-rw-r--r--lib/ssl/test/ssl_test_lib.erl628
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl144
-rw-r--r--lib/ssl/test/ssl_upgrade_SUITE.erl22
-rw-r--r--lib/ssl/test/x509_test.erl352
-rw-r--r--lib/ssl/vsn.mk2
-rw-r--r--lib/stdlib/doc/src/assert_hrl.xml46
-rw-r--r--lib/stdlib/doc/src/beam_lib.xml48
-rw-r--r--lib/stdlib/doc/src/c.xml44
-rw-r--r--lib/stdlib/doc/src/dets.xml63
-rw-r--r--lib/stdlib/doc/src/dict.xml10
-rw-r--r--lib/stdlib/doc/src/erl_expand_records.xml6
-rw-r--r--lib/stdlib/doc/src/erl_internal.xml10
-rw-r--r--lib/stdlib/doc/src/erl_tar.xml78
-rw-r--r--lib/stdlib/doc/src/ets.xml76
-rw-r--r--lib/stdlib/doc/src/filelib.xml56
-rw-r--r--lib/stdlib/doc/src/filename.xml39
-rw-r--r--lib/stdlib/doc/src/gb_sets.xml2
-rw-r--r--lib/stdlib/doc/src/gb_trees.xml24
-rw-r--r--lib/stdlib/doc/src/gen_event.xml48
-rw-r--r--lib/stdlib/doc/src/gen_fsm.xml1095
-rw-r--r--lib/stdlib/doc/src/gen_server.xml38
-rw-r--r--lib/stdlib/doc/src/gen_statem.xml1056
-rw-r--r--lib/stdlib/doc/src/introduction.xml2
-rw-r--r--lib/stdlib/doc/src/io.xml6
-rw-r--r--lib/stdlib/doc/src/io_lib.xml17
-rw-r--r--lib/stdlib/doc/src/maps.xml2
-rw-r--r--lib/stdlib/doc/src/math.xml3
-rw-r--r--lib/stdlib/doc/src/notes.xml667
-rw-r--r--lib/stdlib/doc/src/orddict.xml13
-rw-r--r--lib/stdlib/doc/src/ordsets.xml3
-rw-r--r--lib/stdlib/doc/src/proc_lib.xml14
-rw-r--r--lib/stdlib/doc/src/proplists.xml4
-rw-r--r--lib/stdlib/doc/src/queue.xml2
-rw-r--r--lib/stdlib/doc/src/rand.xml227
-rw-r--r--lib/stdlib/doc/src/re.xml320
-rw-r--r--lib/stdlib/doc/src/sets.xml4
-rw-r--r--lib/stdlib/doc/src/shell.xml35
-rw-r--r--lib/stdlib/doc/src/shell_default.xml2
-rw-r--r--lib/stdlib/doc/src/stdlib_app.xml8
-rw-r--r--lib/stdlib/doc/src/string.xml747
-rw-r--r--lib/stdlib/doc/src/supervisor.xml14
-rw-r--r--lib/stdlib/doc/src/sys.xml36
-rw-r--r--lib/stdlib/doc/src/timer.xml2
-rw-r--r--lib/stdlib/doc/src/unicode.xml181
-rw-r--r--lib/stdlib/doc/src/unicode_usage.xml114
-rw-r--r--lib/stdlib/doc/src/zip.xml6
-rw-r--r--lib/stdlib/include/assert.hrl184
-rw-r--r--lib/stdlib/src/Makefile13
-rw-r--r--lib/stdlib/src/array.erl14
-rw-r--r--lib/stdlib/src/base64.erl69
-rw-r--r--lib/stdlib/src/beam_lib.erl149
-rw-r--r--lib/stdlib/src/binary.erl4
-rw-r--r--lib/stdlib/src/c.erl302
-rw-r--r--lib/stdlib/src/dets.erl489
-rw-r--r--lib/stdlib/src/dets.hrl162
-rw-r--r--lib/stdlib/src/dets_utils.erl26
-rw-r--r--lib/stdlib/src/dets_v8.erl1594
-rw-r--r--lib/stdlib/src/dets_v9.erl112
-rw-r--r--lib/stdlib/src/dict.erl23
-rw-r--r--lib/stdlib/src/edlin_expand.erl95
-rw-r--r--lib/stdlib/src/epp.erl28
-rw-r--r--lib/stdlib/src/erl_abstract_code.erl28
-rw-r--r--lib/stdlib/src/erl_anno.erl8
-rw-r--r--lib/stdlib/src/erl_compile.erl8
-rw-r--r--lib/stdlib/src/erl_eval.erl1
-rw-r--r--lib/stdlib/src/erl_expand_records.erl113
-rw-r--r--lib/stdlib/src/erl_internal.erl124
-rw-r--r--lib/stdlib/src/erl_lint.erl460
-rw-r--r--lib/stdlib/src/erl_parse.yrl151
-rw-r--r--lib/stdlib/src/erl_pp.erl133
-rw-r--r--lib/stdlib/src/erl_tar.erl2582
-rw-r--r--lib/stdlib/src/erl_tar.hrl396
-rw-r--r--lib/stdlib/src/error_logger_file_h.erl71
-rw-r--r--lib/stdlib/src/error_logger_tty_h.erl72
-rw-r--r--lib/stdlib/src/escript.erl98
-rw-r--r--lib/stdlib/src/ets.erl58
-rw-r--r--lib/stdlib/src/eval_bits.erl14
-rw-r--r--lib/stdlib/src/filelib.erl124
-rw-r--r--lib/stdlib/src/filename.erl142
-rw-r--r--lib/stdlib/src/gb_sets.erl7
-rw-r--r--lib/stdlib/src/gb_trees.erl52
-rw-r--r--lib/stdlib/src/gen.erl12
-rw-r--r--lib/stdlib/src/gen_event.erl174
-rw-r--r--lib/stdlib/src/gen_fsm.erl150
-rw-r--r--lib/stdlib/src/gen_server.erl338
-rw-r--r--lib/stdlib/src/gen_statem.erl1682
-rw-r--r--lib/stdlib/src/io_lib.erl228
-rw-r--r--lib/stdlib/src/io_lib_format.erl39
-rw-r--r--lib/stdlib/src/io_lib_fread.erl11
-rw-r--r--lib/stdlib/src/io_lib_pretty.erl157
-rw-r--r--lib/stdlib/src/lib.erl292
-rw-r--r--lib/stdlib/src/math.erl19
-rw-r--r--lib/stdlib/src/ms_transform.erl64
-rw-r--r--lib/stdlib/src/orddict.erl21
-rw-r--r--lib/stdlib/src/otp_internal.erl268
-rw-r--r--lib/stdlib/src/proc_lib.erl158
-rw-r--r--lib/stdlib/src/proplists.erl17
-rw-r--r--lib/stdlib/src/qlc.erl57
-rw-r--r--lib/stdlib/src/qlc_pt.erl59
-rw-r--r--lib/stdlib/src/rand.erl645
-rw-r--r--lib/stdlib/src/re.erl9
-rw-r--r--lib/stdlib/src/sets.erl66
-rw-r--r--lib/stdlib/src/shell.erl50
-rw-r--r--lib/stdlib/src/shell_default.erl5
-rw-r--r--lib/stdlib/src/sofs.erl357
-rw-r--r--lib/stdlib/src/stdlib.app.src7
-rw-r--r--lib/stdlib/src/stdlib.appup.src8
-rw-r--r--lib/stdlib/src/string.erl1339
-rw-r--r--lib/stdlib/src/supervisor.erl4
-rw-r--r--lib/stdlib/src/sys.erl6
-rw-r--r--lib/stdlib/src/timer.erl6
-rw-r--r--lib/stdlib/src/unicode.erl341
-rw-r--r--lib/stdlib/src/zip.erl146
-rw-r--r--lib/stdlib/test/Makefile2
-rw-r--r--lib/stdlib/test/base64_SUITE.erl45
-rw-r--r--lib/stdlib/test/beam_lib_SUITE.erl91
-rw-r--r--lib/stdlib/test/dets_SUITE.erl813
-rw-r--r--lib/stdlib/test/dets_SUITE_data/version_8.dets (renamed from lib/stdlib/test/dets_SUITE_data/version_r2d.dets)bin33885 -> 35143 bytes
-rw-r--r--lib/stdlib/test/dict_SUITE.erl27
-rw-r--r--lib/stdlib/test/dict_test_lib.erl22
-rw-r--r--lib/stdlib/test/dummy_h.erl14
-rw-r--r--lib/stdlib/test/edlin_expand_SUITE.erl86
-rw-r--r--lib/stdlib/test/epp_SUITE.erl45
-rw-r--r--lib/stdlib/test/erl_internal_SUITE.erl17
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl385
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl81
-rw-r--r--lib/stdlib/test/erl_scan_SUITE.erl21
-rw-r--r--lib/stdlib/test/error_logger_h_SUITE.erl4
-rw-r--r--lib/stdlib/test/escript_SUITE.erl15
-rwxr-xr-xlib/stdlib/test/escript_SUITE_data/two_lines2
-rw-r--r--lib/stdlib/test/ets_SUITE.erl1034
-rw-r--r--lib/stdlib/test/ets_tough_SUITE.erl60
-rw-r--r--lib/stdlib/test/filelib_SUITE.erl62
-rw-r--r--lib/stdlib/test/filename_SUITE.erl77
-rw-r--r--lib/stdlib/test/gen_event_SUITE.erl302
-rw-r--r--lib/stdlib/test/gen_event_SUITE_data/oc_event.erl40
-rw-r--r--lib/stdlib/test/gen_fsm_SUITE.erl197
-rw-r--r--lib/stdlib/test/gen_fsm_SUITE_data/oc_fsm.erl48
-rw-r--r--lib/stdlib/test/gen_server_SUITE.erl266
-rw-r--r--lib/stdlib/test/gen_server_SUITE_data/oc_server.erl (renamed from lib/gs/src/gstk.hrl)26
-rw-r--r--lib/stdlib/test/gen_statem_SUITE.erl628
-rw-r--r--lib/stdlib/test/gen_statem_SUITE_data/oc_statem.erl (renamed from lib/hipe/util/hipe_vectors.hrl)32
-rw-r--r--lib/stdlib/test/io_SUITE.erl366
-rw-r--r--lib/stdlib/test/io_proto_SUITE.erl276
-rw-r--r--lib/stdlib/test/lists_SUITE.erl4
-rw-r--r--lib/stdlib/test/math_SUITE.erl92
-rw-r--r--lib/stdlib/test/ms_transform_SUITE.erl17
-rw-r--r--lib/stdlib/test/proc_lib_SUITE.erl49
-rw-r--r--lib/stdlib/test/qlc_SUITE.erl127
-rw-r--r--lib/stdlib/test/rand_SUITE.erl820
-rw-r--r--lib/stdlib/test/random_iolist.erl40
-rw-r--r--lib/stdlib/test/random_unicode_list.erl40
-rw-r--r--lib/stdlib/test/re_SUITE.erl26
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput1310
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput10102
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput22396
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput315
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput420
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput5138
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput6465
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput7810
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput8453
-rw-r--r--lib/stdlib/test/re_SUITE_data/testoutput9110
-rw-r--r--lib/stdlib/test/re_testoutput1_replacement_test.erl10530
-rw-r--r--lib/stdlib/test/re_testoutput1_split_test.erl373
-rw-r--r--lib/stdlib/test/run_pcre_tests.erl78
-rw-r--r--lib/stdlib/test/shell_SUITE.erl171
-rw-r--r--lib/stdlib/test/sofs_SUITE.erl13
-rw-r--r--lib/stdlib/test/string_SUITE.erl979
-rw-r--r--lib/stdlib/test/tar_SUITE.erl327
-rw-r--r--lib/stdlib/test/tar_SUITE_data/bsd.tarbin0 -> 9216 bytes
-rw-r--r--lib/stdlib/test/tar_SUITE_data/gnu.tarbin0 -> 30720 bytes
-rw-r--r--lib/stdlib/test/tar_SUITE_data/pax_mtime.tarbin0 -> 10240 bytes
-rw-r--r--lib/stdlib/test/tar_SUITE_data/sparse00.tar (renamed from lib/stdlib/test/dets_SUITE_data/version_r3b02.dets)bin34484 -> 61440 bytes
-rw-r--r--lib/stdlib/test/tar_SUITE_data/sparse01.tar (renamed from lib/stdlib/test/dets_SUITE_data/dets_test_v8b_little_endian.dets)bin37396 -> 61440 bytes
-rw-r--r--lib/stdlib/test/tar_SUITE_data/sparse01_empty.tarbin0 -> 10240 bytes
-rw-r--r--lib/stdlib/test/tar_SUITE_data/sparse10.tar (renamed from lib/stdlib/test/dets_SUITE_data/dets_test_v8b.dets)bin37396 -> 61440 bytes
-rw-r--r--lib/stdlib/test/tar_SUITE_data/sparse10_empty.tarbin0 -> 10240 bytes
-rw-r--r--lib/stdlib/test/tar_SUITE_data/star.tarbin0 -> 10240 bytes
-rw-r--r--lib/stdlib/test/tar_SUITE_data/v7.tarbin0 -> 10240 bytes
-rw-r--r--lib/stdlib/test/timer_SUITE.erl2
-rw-r--r--lib/stdlib/test/timer_simple_SUITE.erl2
-rw-r--r--lib/stdlib/test/unicode_SUITE.erl109
-rw-r--r--lib/stdlib/test/unicode_util_SUITE.erl433
-rw-r--r--lib/stdlib/test/unicode_util_SUITE_data/GraphemeBreakTest.txt849
-rw-r--r--lib/stdlib/test/unicode_util_SUITE_data/LineBreakTest.txt7341
-rw-r--r--lib/stdlib/test/unicode_util_SUITE_data/NormalizationTest.txt18777
-rw-r--r--lib/stdlib/test/zip_SUITE.erl86
-rw-r--r--lib/stdlib/test/zip_SUITE_data/exploit.zipbin0 -> 797 bytes
-rw-r--r--lib/stdlib/uc_spec/CaseFolding.txt1495
-rw-r--r--lib/stdlib/uc_spec/CompositionExclusions.txt208
-rw-r--r--lib/stdlib/uc_spec/GraphemeBreakProperty.txt1431
-rw-r--r--lib/stdlib/uc_spec/PropList.txt1579
-rw-r--r--lib/stdlib/uc_spec/README-UPDATE.txt7
-rw-r--r--lib/stdlib/uc_spec/SpecialCasing.txt281
-rw-r--r--lib/stdlib/uc_spec/UnicodeData.txt30592
-rwxr-xr-xlib/stdlib/uc_spec/gen_unicode_mod.escript911
-rw-r--r--lib/stdlib/vsn.mk2
-rw-r--r--lib/syntax_tools/AUTHORS2
-rw-r--r--lib/syntax_tools/COPYING504
-rw-r--r--lib/syntax_tools/doc/specs/.gitignore1
-rw-r--r--lib/syntax_tools/doc/src/Makefile8
-rw-r--r--lib/syntax_tools/doc/src/notes.xml67
-rw-r--r--lib/syntax_tools/doc/src/specs.xml14
-rw-r--r--lib/syntax_tools/src/epp_dodger.erl29
-rw-r--r--lib/syntax_tools/src/erl_comment_scan.erl39
-rw-r--r--lib/syntax_tools/src/erl_prettypr.erl52
-rw-r--r--lib/syntax_tools/src/erl_recomment.erl33
-rw-r--r--lib/syntax_tools/src/erl_syntax.erl58
-rw-r--r--lib/syntax_tools/src/erl_syntax_lib.erl37
-rw-r--r--lib/syntax_tools/src/erl_tidy.erl46
-rw-r--r--lib/syntax_tools/src/igor.erl51
-rw-r--r--lib/syntax_tools/src/merl.erl10
-rw-r--r--lib/syntax_tools/src/merl_tests.erl25
-rw-r--r--lib/syntax_tools/src/merl_transform.erl23
-rw-r--r--lib/syntax_tools/src/prettypr.erl29
-rw-r--r--lib/syntax_tools/syntax_tools.pub13
-rw-r--r--lib/syntax_tools/test/merl_SUITE.erl21
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE.erl16
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE_data/erl_tidy_tilde.erl13
-rw-r--r--lib/syntax_tools/vsn.mk2
-rw-r--r--lib/tools/doc/src/erlang_mode.xml9
-rw-r--r--lib/tools/doc/src/lcnt.xml12
-rw-r--r--lib/tools/doc/src/lcnt_chapter.xml32
-rw-r--r--lib/tools/doc/src/make.xml26
-rw-r--r--lib/tools/doc/src/notes.xml135
-rw-r--r--lib/tools/doc/src/xref_chapter.xml6
-rw-r--r--lib/tools/emacs/Makefile2
-rw-r--r--lib/tools/emacs/erlang-edoc.el178
-rw-r--r--lib/tools/emacs/erlang-eunit.el48
-rw-r--r--lib/tools/emacs/erlang-flymake.el3
-rw-r--r--lib/tools/emacs/erlang-pkg.el4
-rw-r--r--lib/tools/emacs/erlang-skels.el169
-rw-r--r--lib/tools/emacs/erlang-start.el39
-rw-r--r--lib/tools/emacs/erlang-test.el179
-rw-r--r--lib/tools/emacs/erlang.el4359
-rw-r--r--lib/tools/emacs/erldoc.el514
-rw-r--r--lib/tools/emacs/test.erl.indented810
-rw-r--r--lib/tools/emacs/test.erl.orig210
-rw-r--r--lib/tools/examples/xref_examples.erl2
-rw-r--r--lib/tools/src/cover.erl44
-rw-r--r--lib/tools/src/fprof.erl17
-rw-r--r--lib/tools/src/lcnt.erl58
-rw-r--r--lib/tools/src/make.erl85
-rw-r--r--lib/tools/src/tags.erl2
-rw-r--r--lib/tools/src/tools.app.src7
-rw-r--r--lib/tools/src/xref_base.erl7
-rw-r--r--lib/tools/src/xref_reader.erl57
-rw-r--r--lib/tools/test/Makefile6
-rw-r--r--lib/tools/test/cover_SUITE.erl33
-rw-r--r--lib/tools/test/cover_SUITE_data/otp_6115/f1.erl15
-rw-r--r--lib/tools/test/cover_SUITE_data/otp_6115/f2.erl14
-rw-r--r--lib/tools/test/lcnt_SUITE.erl87
-rw-r--r--lib/tools/test/make_SUITE.erl60
-rw-r--r--lib/tools/test/make_SUITE_data/incl_src/test_incl2.erl9
-rw-r--r--lib/tools/test/make_SUITE_data/test1.erl2
-rw-r--r--lib/tools/test/make_SUITE_data/test_incl.hrl1
-rw-r--r--lib/tools/test/make_SUITE_data/test_incl1.erl9
-rw-r--r--lib/tools/test/xref_SUITE.erl30
-rw-r--r--lib/tools/vsn.mk2
-rw-r--r--lib/typer/Makefile44
-rw-r--r--lib/typer/RELEASE_NOTES22
-rw-r--r--lib/typer/doc/Makefile40
-rw-r--r--lib/typer/doc/html/.gitignore0
-rw-r--r--lib/typer/doc/pdf/.gitignore0
-rw-r--r--lib/typer/doc/src/Makefile118
-rw-r--r--lib/typer/doc/src/book.xml42
-rw-r--r--lib/typer/doc/src/fascicules.xml12
-rw-r--r--lib/typer/doc/src/notes.xml111
-rw-r--r--lib/typer/doc/src/part_notes.xml36
-rw-r--r--lib/typer/doc/src/ref_man.xml36
-rw-r--r--lib/typer/doc/src/typer_app.xml44
-rw-r--r--lib/typer/ebin/.gitignore0
-rw-r--r--lib/typer/info2
-rw-r--r--lib/typer/src/Makefile111
-rw-r--r--lib/typer/src/typer.app.src11
-rw-r--r--lib/typer/test/Makefile65
-rw-r--r--lib/typer/test/typer.spec1
-rw-r--r--lib/typer/test/typer_SUITE.erl57
-rw-r--r--lib/typer/vsn.mk1
-rw-r--r--lib/wx/api_gen/gen_util.erl4
-rw-r--r--lib/wx/api_gen/gl_gen.erl33
-rw-r--r--lib/wx/api_gen/gl_gen_c.erl31
-rw-r--r--lib/wx/api_gen/gl_gen_erl.erl55
-rw-r--r--lib/wx/api_gen/glapi.conf6
-rw-r--r--lib/wx/api_gen/wx_doxygen.conf2
-rw-r--r--lib/wx/api_gen/wx_extra/added_func.h11
-rw-r--r--lib/wx/api_gen/wx_extra/wxListCtrl.erl62
-rw-r--r--lib/wx/api_gen/wx_extra/wxXmlResource.erl6
-rw-r--r--lib/wx/api_gen/wx_gen.erl34
-rw-r--r--lib/wx/api_gen/wx_gen_cpp.erl14
-rw-r--r--lib/wx/api_gen/wx_gen_erl.erl13
-rw-r--r--lib/wx/api_gen/wxapi.conf15
-rw-r--r--lib/wx/c_src/egl_impl.h4
-rw-r--r--lib/wx/c_src/gen/gl_funcs.cpp1052
-rw-r--r--lib/wx/c_src/gen/wxe_events.cpp17
-rw-r--r--lib/wx/c_src/gen/wxe_funcs.cpp40
-rw-r--r--lib/wx/c_src/gen/wxe_macros.h6659
-rw-r--r--lib/wx/c_src/wxe_impl.cpp43
-rw-r--r--lib/wx/c_src/wxe_impl.h4
-rw-r--r--lib/wx/c_src/wxe_main.cpp6
-rw-r--r--lib/wx/doc/specs/.gitignore1
-rw-r--r--lib/wx/doc/src/Makefile6
-rw-r--r--lib/wx/doc/src/notes.xml63
-rw-r--r--lib/wx/doc/src/specs.xml232
-rw-r--r--lib/wx/examples/demo/demo.erl24
-rw-r--r--lib/wx/include/wx.hrl465
-rw-r--r--lib/wx/src/gen/gl.erl1223
-rw-r--r--lib/wx/src/gen/glu.erl4
-rw-r--r--lib/wx/src/gen/wxArtProvider.erl8
-rw-r--r--lib/wx/src/gen/wxAuiManager.erl8
-rw-r--r--lib/wx/src/gen/wxAuiNotebook.erl78
-rw-r--r--lib/wx/src/gen/wxAuiPaneInfo.erl4
-rw-r--r--lib/wx/src/gen/wxBitmap.erl12
-rw-r--r--lib/wx/src/gen/wxBitmapButton.erl69
-rw-r--r--lib/wx/src/gen/wxButton.erl54
-rw-r--r--lib/wx/src/gen/wxCalendarCtrl.erl50
-rw-r--r--lib/wx/src/gen/wxCheckBox.erl58
-rw-r--r--lib/wx/src/gen/wxCheckListBox.erl19
-rw-r--r--lib/wx/src/gen/wxChoice.erl73
-rw-r--r--lib/wx/src/gen/wxChoicebook.erl60
-rw-r--r--lib/wx/src/gen/wxColourDialog.erl72
-rw-r--r--lib/wx/src/gen/wxColourPickerCtrl.erl29
-rw-r--r--lib/wx/src/gen/wxComboBox.erl84
-rw-r--r--lib/wx/src/gen/wxCommandEvent.erl2
-rw-r--r--lib/wx/src/gen/wxControl.erl54
-rw-r--r--lib/wx/src/gen/wxControlWithItems.erl66
-rw-r--r--lib/wx/src/gen/wxDC.erl20
-rw-r--r--lib/wx/src/gen/wxDatePickerCtrl.erl27
-rw-r--r--lib/wx/src/gen/wxDialog.erl64
-rw-r--r--lib/wx/src/gen/wxDirDialog.erl76
-rw-r--r--lib/wx/src/gen/wxDirPickerCtrl.erl29
-rw-r--r--lib/wx/src/gen/wxDropFilesEvent.erl89
-rw-r--r--lib/wx/src/gen/wxFileDataObject.erl2
-rw-r--r--lib/wx/src/gen/wxFileDialog.erl82
-rw-r--r--lib/wx/src/gen/wxFilePickerCtrl.erl29
-rw-r--r--lib/wx/src/gen/wxFindReplaceData.erl4
-rw-r--r--lib/wx/src/gen/wxFindReplaceDialog.erl80
-rw-r--r--lib/wx/src/gen/wxFont.erl4
-rw-r--r--lib/wx/src/gen/wxFontDialog.erl72
-rw-r--r--lib/wx/src/gen/wxFontPickerCtrl.erl27
-rw-r--r--lib/wx/src/gen/wxFrame.erl68
-rw-r--r--lib/wx/src/gen/wxGLCanvas.erl50
-rw-r--r--lib/wx/src/gen/wxGauge.erl50
-rw-r--r--lib/wx/src/gen/wxGenericDirCtrl.erl58
-rw-r--r--lib/wx/src/gen/wxGraphicsContext.erl12
-rw-r--r--lib/wx/src/gen/wxGrid.erl84
-rw-r--r--lib/wx/src/gen/wxGridCellBoolEditor.erl2
-rw-r--r--lib/wx/src/gen/wxGridCellChoiceEditor.erl2
-rw-r--r--lib/wx/src/gen/wxGridCellFloatEditor.erl2
-rw-r--r--lib/wx/src/gen/wxGridCellFloatRenderer.erl2
-rw-r--r--lib/wx/src/gen/wxGridCellNumberEditor.erl2
-rw-r--r--lib/wx/src/gen/wxGridCellTextEditor.erl2
-rw-r--r--lib/wx/src/gen/wxHtmlEasyPrinting.erl24
-rw-r--r--lib/wx/src/gen/wxHtmlWindow.erl78
-rw-r--r--lib/wx/src/gen/wxIcon.erl4
-rw-r--r--lib/wx/src/gen/wxIconBundle.erl4
-rw-r--r--lib/wx/src/gen/wxImage.erl34
-rw-r--r--lib/wx/src/gen/wxListBox.erl75
-rw-r--r--lib/wx/src/gen/wxListCtrl.erl148
-rw-r--r--lib/wx/src/gen/wxListItem.erl2
-rw-r--r--lib/wx/src/gen/wxListView.erl50
-rw-r--r--lib/wx/src/gen/wxListbook.erl60
-rw-r--r--lib/wx/src/gen/wxLocale.erl20
-rw-r--r--lib/wx/src/gen/wxMDIChildFrame.erl90
-rw-r--r--lib/wx/src/gen/wxMDIClientWindow.erl50
-rw-r--r--lib/wx/src/gen/wxMDIParentFrame.erl55
-rw-r--r--lib/wx/src/gen/wxMenu.erl56
-rw-r--r--lib/wx/src/gen/wxMenuBar.erl63
-rw-r--r--lib/wx/src/gen/wxMenuItem.erl6
-rw-r--r--lib/wx/src/gen/wxMessageDialog.erl76
-rw-r--r--lib/wx/src/gen/wxMiniFrame.erl55
-rw-r--r--lib/wx/src/gen/wxMultiChoiceDialog.erl76
-rw-r--r--lib/wx/src/gen/wxNotebook.erl60
-rw-r--r--lib/wx/src/gen/wxPanel.erl50
-rw-r--r--lib/wx/src/gen/wxPasswordEntryDialog.erl64
-rw-r--r--lib/wx/src/gen/wxPickerBase.erl50
-rw-r--r--lib/wx/src/gen/wxPopupTransientWindow.erl69
-rw-r--r--lib/wx/src/gen/wxPopupWindow.erl50
-rw-r--r--lib/wx/src/gen/wxPreviewCanvas.erl64
-rw-r--r--lib/wx/src/gen/wxPreviewControlBar.erl69
-rw-r--r--lib/wx/src/gen/wxPreviewFrame.erl47
-rw-r--r--lib/wx/src/gen/wxPrintData.erl2
-rw-r--r--lib/wx/src/gen/wxPrintDialog.erl72
-rw-r--r--lib/wx/src/gen/wxPrinter.erl2
-rw-r--r--lib/wx/src/gen/wxProgressDialog.erl76
-rw-r--r--lib/wx/src/gen/wxRadioBox.erl29
-rw-r--r--lib/wx/src/gen/wxRadioButton.erl58
-rw-r--r--lib/wx/src/gen/wxSashLayoutWindow.erl53
-rw-r--r--lib/wx/src/gen/wxSashWindow.erl50
-rw-r--r--lib/wx/src/gen/wxScrollBar.erl50
-rw-r--r--lib/wx/src/gen/wxScrolledWindow.erl69
-rw-r--r--lib/wx/src/gen/wxSingleChoiceDialog.erl76
-rw-r--r--lib/wx/src/gen/wxSlider.erl50
-rw-r--r--lib/wx/src/gen/wxSpinButton.erl50
-rw-r--r--lib/wx/src/gen/wxSpinCtrl.erl52
-rw-r--r--lib/wx/src/gen/wxSplashScreen.erl47
-rw-r--r--lib/wx/src/gen/wxSplitterWindow.erl50
-rw-r--r--lib/wx/src/gen/wxStaticBitmap.erl50
-rw-r--r--lib/wx/src/gen/wxStaticBox.erl58
-rw-r--r--lib/wx/src/gen/wxStaticLine.erl50
-rw-r--r--lib/wx/src/gen/wxStaticText.erl62
-rw-r--r--lib/wx/src/gen/wxStatusBar.erl58
-rw-r--r--lib/wx/src/gen/wxStyledTextCtrl.erl113
-rw-r--r--lib/wx/src/gen/wxSystemOptions.erl12
-rw-r--r--lib/wx/src/gen/wxTextCtrl.erl64
-rw-r--r--lib/wx/src/gen/wxTextDataObject.erl2
-rw-r--r--lib/wx/src/gen/wxTextEntryDialog.erl78
-rw-r--r--lib/wx/src/gen/wxToggleButton.erl58
-rw-r--r--lib/wx/src/gen/wxToolBar.erl74
-rw-r--r--lib/wx/src/gen/wxToolTip.erl4
-rw-r--r--lib/wx/src/gen/wxToolbook.erl60
-rw-r--r--lib/wx/src/gen/wxTopLevelWindow.erl52
-rw-r--r--lib/wx/src/gen/wxTreeCtrl.erl68
-rw-r--r--lib/wx/src/gen/wxTreeEvent.erl2
-rw-r--r--lib/wx/src/gen/wxTreebook.erl64
-rw-r--r--lib/wx/src/gen/wxUpdateUIEvent.erl2
-rw-r--r--lib/wx/src/gen/wxWindow.erl90
-rw-r--r--lib/wx/src/gen/wxXmlResource.erl40
-rw-r--r--lib/wx/src/gen/wx_misc.erl6
-rw-r--r--lib/wx/src/gen/wxe_debug.hrl6659
-rw-r--r--lib/wx/src/gen/wxe_funcs.hrl6659
-rw-r--r--lib/wx/src/wx_object.erl135
-rw-r--r--lib/wx/src/wxe.hrl2
-rw-r--r--lib/wx/src/wxe_master.erl12
-rw-r--r--lib/wx/test/Makefile3
-rw-r--r--lib/wx/test/wx_basic_SUITE.erl157
-rw-r--r--lib/wx/test/wx_obj_test.erl7
-rw-r--r--lib/wx/test/wx_oc_object.erl44
-rw-r--r--lib/wx/test/wx_opengl_SUITE.erl2
-rw-r--r--lib/wx/vsn.mk2
-rw-r--r--lib/xmerl/doc/src/notes.xml112
-rw-r--r--lib/xmerl/notes.html28
-rw-r--r--lib/xmerl/src/xmerl_eventp.erl84
-rw-r--r--lib/xmerl/src/xmerl_regexp.erl4
-rw-r--r--lib/xmerl/src/xmerl_sax_old_dom.erl9
-rw-r--r--lib/xmerl/src/xmerl_sax_parser.erl198
-rw-r--r--lib/xmerl/src/xmerl_sax_parser.hrl11
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_base.erlsrc411
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_latin1.erlsrc38
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_list.erlsrc21
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_utf16be.erlsrc50
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_utf16le.erlsrc50
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_utf8.erlsrc50
-rw-r--r--lib/xmerl/src/xmerl_sax_simple_dom.erl7
-rw-r--r--lib/xmerl/src/xmerl_scan.erl42
-rw-r--r--lib/xmerl/src/xmerl_xpath.erl30
-rw-r--r--lib/xmerl/src/xmerl_xs.erl7
-rw-r--r--lib/xmerl/src/xmerl_xsd.erl13
-rw-r--r--lib/xmerl/test/Makefile7
-rw-r--r--lib/xmerl/test/xmerl_SUITE.erl56
-rw-r--r--lib/xmerl/test/xmerl_sax_SUITE.erl84
-rw-r--r--lib/xmerl/test/xmerl_sax_SUITE_data/test_data_1.xml4
-rw-r--r--lib/xmerl/test/xmerl_sax_std_SUITE.erl100
-rw-r--r--lib/xmerl/test/xmerl_sax_stream_SUITE.erl260
-rw-r--r--lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_one.xml17
-rw-r--r--lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_one_junk.xml18
-rw-r--r--lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_two.xml34
-rw-r--r--lib/xmerl/vsn.mk2
-rw-r--r--lib/xmerl/xmerl.pub19
2134 files changed, 201961 insertions, 202260 deletions
diff --git a/lib/.gitignore b/lib/.gitignore
index b1da61706d..283393faa9 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -526,14 +526,6 @@
/orber/src/oe_erlang.erl
/orber/src/oe_erlang.hrl
-# percept
-
-/percept/doc/src/egd.xml
-/percept/doc/src/egd_ug.xml
-/percept/doc/src/percept.xml
-/percept/doc/src/percept_profile.xml
-/percept/doc/src/percept_ug.xml
-
# snmp
snmp/doc/intex.html
diff --git a/lib/Makefile b/lib/Makefile
index bc5d4cdcc1..ae466ed518 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -30,12 +30,12 @@ ERLANG_APPLICATIONS = tools common_test runtime_tools inets parsetools
# These are only build if -a is given to otp_build or make is used directly
ALL_ERLANG_APPLICATIONS = xmerl edoc erl_docgen snmp otp_mibs erl_interface \
asn1 jinterface \
- wx debugger reltool gs \
+ wx debugger reltool \
ic mnesia crypto orber os_mon syntax_tools \
public_key ssl observer odbc diameter \
cosTransactions cosEvent cosTime cosNotification \
cosProperty cosFileTransfer cosEventDomain et megaco \
- eunit ssh typer percept eldap dialyzer hipe
+ eunit ssh eldap dialyzer hipe
ifdef BUILD_ALL
ERLANG_APPLICATIONS += $(ALL_ERLANG_APPLICATIONS)
diff --git a/lib/asn1/c_src/asn1_erl_nif.c b/lib/asn1/c_src/asn1_erl_nif.c
index 4577689fc3..d5aaadb89b 100644
--- a/lib/asn1/c_src/asn1_erl_nif.c
+++ b/lib/asn1/c_src/asn1_erl_nif.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2002-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include "erl_nif.h"
+#include <erl_nif.h>
/* #define ASN1_DEBUG 1 */
@@ -901,31 +901,35 @@ static int ber_decode_tag(ErlNifEnv* env, ERL_NIF_TERM *tag, unsigned char *in_b
/* then get the tag number */
if ((tmp_tag = (int) INVMASK(in_buf[*ib_index],ASN1_CLASSFORM)) < 31) {
- *tag = enif_make_uint(env, tag_no + tmp_tag);
+ *tag = enif_make_uint(env, tag_no | tmp_tag);
(*ib_index)++;
} else {
- int n = 0; /* n is used to check that the 64K limit is not
- exceeded*/
-
/* should check that at least three bytes are left in
in-buffer,at least two tag byte and at least one length byte */
if ((*ib_index + 3) > in_buf_len)
return ASN1_VALUE_ERROR;
(*ib_index)++;
- /* The tag is in the following bytes in in_buf as
- 1ttttttt 1ttttttt ... 0ttttttt, where the t-bits
- is the tag number*/
- /* In practice is the tag size limited to 64K, i.e. 16 bits. If
- the tag is greater then 64K return an error */
- while (((tmp_tag = (int) in_buf[*ib_index]) >= 128) && n < 2) {
- /* m.s.b. = 1 */
- tag_no = tag_no + (MASK(tmp_tag,ASN1_LONG_TAG) << 7);
+ /*
+ * The tag is in the following bytes in in_buf as:
+ *
+ * 1ttttttt 0ttttttt
+ *
+ * or
+ *
+ * 0ttttttt
+ *
+ * where the t-bits is the tag number. If the tag does not
+ * fit in two tag bytes (16K), return an error.
+ */
+ if ((tmp_tag = (int) in_buf[*ib_index]) >= 128) {
+ tag_no = tag_no | (MASK(tmp_tag,ASN1_LONG_TAG) << 7);
(*ib_index)++;
- n++;
- };
- if ((n == 2) && in_buf[*ib_index] > 3)
- return ASN1_TAG_ERROR; /* tag number > 64K */
- tag_no = tag_no + in_buf[*ib_index];
+ }
+ tmp_tag = (int) in_buf[*ib_index];
+ if (tmp_tag >= 128) {
+ return ASN1_TAG_ERROR; /* tag number > 16K */
+ }
+ tag_no = tag_no | tmp_tag;
(*ib_index)++;
*tag = enif_make_uint(env, tag_no);
}
diff --git a/lib/asn1/doc/src/Makefile b/lib/asn1/doc/src/Makefile
index 559836116f..9a388e4e8a 100644
--- a/lib/asn1/doc/src/Makefile
+++ b/lib/asn1/doc/src/Makefile
@@ -37,8 +37,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# Target Specs
# ----------------------------------------------------
XML_APPLICATION_FILES = ref_man.xml
-XML_REF3_FILES = asn1ct.xml \
- asn1rt.xml
+XML_REF3_FILES = asn1ct.xml
GEN_XML = \
asn1_spec.xml
diff --git a/lib/asn1/doc/src/asn1_getting_started.xml b/lib/asn1/doc/src/asn1_getting_started.xml
index 3c8ec24723..907bf051d5 100644
--- a/lib/asn1/doc/src/asn1_getting_started.xml
+++ b/lib/asn1/doc/src/asn1_getting_started.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -187,6 +187,14 @@ erlc -o ../asnfiles -I ../asnfiles -I /usr/local/standards/asn1 Person.asn</pre>
<item>
<p>DER encoding rule. Only when using option <c>-ber</c>.</p>
</item>
+ <tag><c>+maps</c></tag>
+ <item>
+ <p>Use maps instead of records to represent the <c>SEQUENCE</c> and
+ <c>SET</c> types. No <c>.hrl</c> files will be generated.
+ See the Section <seealso marker="asn1_getting_started#MAP_SEQ_SET">
+ Map representation for SEQUENCE and SET</seealso>
+ for more information.</p>
+ </item>
<tag><c>+asn1config</c></tag>
<item>
<p>This functionality works together with option
@@ -258,6 +266,10 @@ asn1ct:compile("H323-MESSAGES.asn1",[per]). </pre>
<c>{error, {asn1, Description}}</c> where
<c>Description</c> is
an Erlang term describing the error.</p>
+ <p>Currently, <c>Description</c> looks like this:
+ <c>{ErrorDescription, StackTrace}</c>. Applications should
+ not depend on the exact contents of <c>Description</c> as it
+ could change in the future.</p>
</section>
</section>
@@ -678,7 +690,7 @@ ok
1081,32,1043,1085,1086,1084]</pre>
<p>For details, see the <seealso marker="stdlib:unicode">unicode</seealso>
- module in <c>stdlib</c>.</p>
+ module in STDLIB.</p>
<p>In the following example, this ASN.1 specification is used:</p>
<pre>
@@ -766,8 +778,11 @@ Pdu ::= SEQUENCE {
b REAL,
c OBJECT IDENTIFIER,
d NULL } </pre>
- <p>This is a 4-component structure called <c>Pdu</c>. The record format
- is the major format for representation of <c>SEQUENCE</c> in Erlang.
+ <p>This is a 4-component structure called <c>Pdu</c>. By default,
+ a <c>SEQUENCE</c> is represented by a record in Erlang.
+ It can also be represented as a map; see
+ <seealso marker="asn1_getting_started#MAP_SEQ_SET">
+ Map representation for SEQUENCE and SET</seealso>.
For each <c>SEQUENCE</c> and <c>SET</c> in an ASN.1 module an Erlang
record declaration is generated. For <c>Pdu</c>, a record
like the following is defined:</p>
@@ -878,6 +893,48 @@ SExt ::= SEQUENCE {
</section>
<section>
+ <marker id="MAP_SEQ_SET"></marker>
+ <title>Map representation for SEQUENCE and SET</title>
+ <p>If the ASN.1 module has been compiled with option <c>maps</c>,
+ the types <c>SEQUENCE</c> and <c>SET</c> are represented as maps.</p>
+ <p>In the following example, this ASN.1 specification is used:</p>
+ <pre>
+File DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+Seq1 ::= SEQUENCE {
+ a INTEGER DEFAULT 42,
+ b BOOLEAN OPTIONAL,
+ c IA5String
+}
+END </pre>
+
+ <p>Optional fields are to be omitted from the map if they have
+ no value:</p>
+
+ <pre>
+1> <input>asn1ct:compile('File', [per,maps]).</input>
+ok
+2> <input>{ok,E} = 'File':encode('Seq1', #{a=>0,c=>"string"}).</input>
+{ok,&lt;&lt;128,1,0,6,115,116,114,105,110,103&gt;&gt;} </pre>
+
+ <p>When decoding, optional fields will be omitted from the map:</p>
+
+ <pre>
+3> <input>'File':decode('Seq1', E).</input>
+{ok,#{a => 0,c => "string"}} </pre>
+
+ <p>Default values can be omitted from the map:</p>
+ <pre>
+4> <input>{ok,E2} = 'File':encode('Seq1', #{c=>"string"}).</input>
+{ok,&lt;&lt;0,6,115,116,114,105,110,103&gt;&gt;}
+5> <input>'File':decode('Seq1', E2).</input>
+{ok,#{a => 42,c => "string"}} </pre>
+
+ <note><p>It is not allowed to use the atoms <c>asn1_VALUE</c> and
+ <c>asn1_DEFAULT</c> with maps.</p></note>
+ </section>
+
+ <section>
<marker id="CHOICE"></marker>
<title>CHOICE</title>
<p>The type <c>CHOICE</c> is a space saver and is similar to the
@@ -1004,11 +1061,16 @@ T ::= CHOICE {
<section>
<title>Naming of Records in .hrl Files</title>
+ <p>When the option <c>maps</c> is given, no <c>.hrl</c> files
+ will be generated. The rest of this section describes the behavior
+ of the compiler when <c>maps</c> is not used.</p>
+
<p>When an ASN.1 specification is compiled, all defined types of type
- <c>SET</c> or <c>SEQUENCE</c> result in a corresponding record in the
- generated <c>.hrl</c> file. This is because the values for
- <c>SET</c> and <c>SEQUENCE</c> are represented as records as
- mentioned earlier.</p>
+ <c>SET</c> or <c>SEQUENCE</c> result in a corresponding record in the
+ generated <c>.hrl</c> file. This is because the values for
+ <c>SET</c> and <c>SEQUENCE</c> are represented as records
+ by default.</p>
+
<p>Some special cases of this functionality are presented in the
next section.</p>
@@ -1144,9 +1206,10 @@ SS ::= SET {
<p>This example shows that a function is generated by the compiler
that returns a valid Erlang representation of the value, although
the value is of a complex type.</p>
- <p>Furthermore, a macro is generated for each value in the <c>.hrl</c>
- file. So, the defined value <c>tt</c> can also be extracted by
- <c>?tt</c> in application code.</p>
+ <p>Furthermore, if the option <c>maps</c> is not used,
+ a macro is generated for each value in the <c>.hrl</c>
+ file. So, the defined value <c>tt</c> can also be extracted by
+ <c>?tt</c> in application code.</p>
</section>
<section>
diff --git a/lib/asn1/doc/src/asn1_introduction.xml b/lib/asn1/doc/src/asn1_introduction.xml
index d8b81aa467..e4f406364d 100644
--- a/lib/asn1/doc/src/asn1_introduction.xml
+++ b/lib/asn1/doc/src/asn1_introduction.xml
@@ -30,7 +30,7 @@
<file>asn1_introduction.xml</file>
</header>
- <p>The <c>ASN.1</c> application provides the following:</p>
+ <p>The ASN.1 application provides the following:</p>
<list type="bulleted">
<item>An ASN.1 compiler for Erlang, which generates encode and
diff --git a/lib/asn1/doc/src/asn1ct.xml b/lib/asn1/doc/src/asn1ct.xml
index e5a7b1bcc4..ccf07a9cc1 100644
--- a/lib/asn1/doc/src/asn1ct.xml
+++ b/lib/asn1/doc/src/asn1ct.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -170,11 +170,24 @@ File3.asn</pre>
as for <c>ber</c>.
</p>
</item>
+ <tag><c>maps</c></tag>
+ <item>
+ <p>This option changes the representation of the types
+ <c>SEQUENCE</c> and <c>SET</c> to use maps (instead of
+ records). This option also suppresses the generation of
+ <c>.hrl</c> files.</p>
+ <p>For details, see Section
+ <seealso marker="asn1_getting_started#MAP_SEQ_SET">
+ Map representation for SEQUENCE and SET</seealso>
+ in the User's Guide.
+ </p>
+ </item>
<tag><c>compact_bit_string</c></tag>
<item>
<p>
The <c>BIT STRING</c> type is decoded to "compact notation".
<em>This option is not recommended for new code.</em>
+ This option cannot be combined with the option <c>maps</c>.
</p>
<p>For details, see Section
<seealso marker="asn1_getting_started#BIT STRING">
@@ -188,6 +201,7 @@ File3.asn</pre>
The <c>BIT STRING</c> type is decoded to the legacy
format, that is, a list of zeroes and ones.
<em>This option is not recommended for new code.</em>
+ This option cannot be combined with the option <c>maps</c>.
</p>
<p>For details, see Section
<seealso marker="asn1_getting_started#BIT STRING">BIT STRING</seealso>
@@ -202,7 +216,8 @@ File3.asn</pre>
marker="asn1_getting_started#BIT STRING">BIT STRING</seealso> and Section
<seealso marker="asn1_getting_started#OCTET STRING">OCTET
STRING</seealso> in the User's Guide.</p>
- <p><em>This option is not recommended for new code.</em></p>
+ <p><em>This option is not recommended for new code.</em>
+ This option cannot be combined with the option <c>maps</c>.</p>
</item>
<tag><c>{n2n, EnumTypeName}</c></tag>
<item>
@@ -321,45 +336,6 @@ File3.asn</pre>
</func>
<func>
- <name>encode(Module, Type, Value)-> {ok, Bytes} | {error, Reason}</name>
- <fsummary>Encodes an ASN.1 value.</fsummary>
- <type>
- <v>Module = Type = atom()</v>
- <v>Value = term()</v>
- <v>Bytes = binary()</v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <p>Encodes <c>Value</c> of <c>Type</c> defined in the <c>ASN.1</c> module
- <c>Module</c>. To get as fast execution as possible, the
- encode function performs only the rudimentary tests that input
- <c>Value</c> is a correct instance of <c>Type</c>. So, for example,
- the length of strings is
- not always checked. Returns <c>{ok, Bytes}</c> if successful or
- <c>{error, Reason}</c> if an error occurred.
- </p>
- <p>This function is deprecated.
- Use <c>Module:encode(Type, Value)</c> instead.</p>
- </desc>
- </func>
-
- <func>
- <name>decode(Module, Type, Bytes) -> {ok, Value} | {error, Reason}</name>
- <fsummary>Decode from Bytes into an ASN.1 value.</fsummary>
- <type>
- <v>Module = Type = atom()</v>
- <v>Value = Reason = term()</v>
- <v>Bytes = binary()</v>
- </type>
- <desc>
- <p>Decodes <c>Type</c> from <c>Module</c> from the binary
- <c>Bytes</c>. Returns <c>{ok, Value}</c> if successful.</p>
- <p>This function is deprecated.
- Use <c>Module:decode(Type, Bytes)</c> instead.</p>
- </desc>
- </func>
-
- <func>
<name>value(Module, Type) -> {ok, Value} | {error, Reason}</name>
<fsummary>Creates an ASN.1 value for test purposes.</fsummary>
<type>
@@ -424,11 +400,11 @@ File3.asn</pre>
<p>Schematically, the following occurs for each type in the module:</p>
<code type="none">
{ok, Value} = asn1ct:value(Module, Type),
-{ok, Bytes} = asn1ct:encode(Module, Type, Value),
-{ok, Value} = asn1ct:decode(Module, Type, Bytes).</code>
+{ok, Bytes} = Module:encode(Type, Value),
+{ok, Value} = Module:decode(Type, Bytes).</code>
<p>The <c>test</c> functions use the <c>*.asn1db</c> files
for all included modules. If they are located in a different
- directory than the current working directory, use the include
+ directory than the current working directory, use the <c>include</c>
option to add paths. This is only needed when automatically
generating values. For static values using <c>Value</c> no
options are needed.</p>
diff --git a/lib/asn1/doc/src/asn1rt.xml b/lib/asn1/doc/src/asn1rt.xml
deleted file mode 100644
index 3f53ca0f56..0000000000
--- a/lib/asn1/doc/src/asn1rt.xml
+++ /dev/null
@@ -1,135 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE erlref SYSTEM "erlref.dtd">
-
-<erlref>
- <header>
- <copyright>
- <year>1997</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>asn1rt</title>
- <prepared>Kenneth Lundin</prepared>
- <responsible>Kenneth Lundin</responsible>
- <docno>1</docno>
- <approved>Kenneth Lundin</approved>
- <checked></checked>
- <date>97-10-04</date>
- <rev>A</rev>
- <file>asn1.sgml</file>
- </header>
- <module>asn1rt</module>
- <modulesummary>ASN.1 runtime support functions</modulesummary>
- <description>
- <warning>
- <p>
- All functions in this module are deprecated and will be
- removed in a future release.
- </p>
- </warning>
- </description>
-
- <funcs>
-
- <func>
- <name>decode(Module,Type,Bytes) -> {ok,Value}|{error,Reason}</name>
- <fsummary>Decodes from Bytes into an ASN.1 value.</fsummary>
- <type>
- <v>Module = Type = atom()</v>
- <v>Value = Reason = term()</v>
- <v>Bytes = binary</v>
- </type>
- <desc>
- <p>Decodes <c>Type</c> from <c>Module</c> from the binary <c>Bytes</c>.
- Returns <c>{ok,Value}</c> if successful.</p>
- <p>Use <c>Module:decode(Type, Bytes)</c> instead of this function.</p>
- </desc>
- </func>
-
- <func>
- <name>encode(Module,Type,Value)-> {ok,Bytes} | {error,Reason}</name>
- <fsummary>Encodes an ASN.1 value.</fsummary>
- <type>
- <v>Module = Type = atom()</v>
- <v>Value = term()</v>
- <v>Bytes = binary</v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <p>Encodes <c>Value</c> of <c>Type</c> defined in the <c>ASN.1</c>
- module <c>Module</c>. Returns a binary if successful. To get
- as fast execution as possible, the encode function performs
- only the rudimentary test that input <c>Value</c> is a correct
- instance of <c>Type</c>. For example, the length of strings is
- not always checked.</p>
- <p>Use <c>Module:encode(Type, Value)</c> instead of this function.</p>
- </desc>
- </func>
-
- <func>
- <name>info(Module) -> {ok,Info} | {error,Reason}</name>
- <fsummary>Returns compiler information about the Module.</fsummary>
- <type>
- <v>Module = atom()</v>
- <v>Info = list()</v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <p>Returns the version of the <c>ASN.1</c> compiler that was
- used to compile the module. It also returns the compiler options
- that were used.</p>
- <p>Use <c>Module:info()</c> instead of this function.</p>
- </desc>
- </func>
-
- <func>
- <name>utf8_binary_to_list(UTF8Binary) -> {ok,UnicodeList} | {error,Reason}</name>
- <fsummary>Transforms an UTF8 encoded binary to a unicode list.</fsummary>
- <type>
- <v>UTF8Binary = binary()</v>
- <v>UnicodeList = [integer()]</v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <p>Transforms a UTF8 encoded binary
- to a list of integers, where each integer represents one
- character as its unicode value. The function fails if the binary
- is not a properly encoded UTF8 string.</p>
- <p>Use <seealso marker="stdlib:unicode#characters_to_list-1">unicode:characters_to_list/1</seealso> instead of this function.</p>
- </desc>
- </func>
-
- <func>
- <name>utf8_list_to_binary(UnicodeList) -> {ok,UTF8Binary} | {error,Reason}</name>
- <fsummary>Transforms an unicode list to a UTF8 binary.</fsummary>
- <type>
- <v>UnicodeList = [integer()]</v>
- <v>UTF8Binary = binary()</v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <p>Transforms a list of integers,
- where each integer represents one character as its unicode
- value, to a UTF8 encoded binary.</p>
- <p>Use <seealso marker="stdlib:unicode#characters_to_binary-1">unicode:characters_to_binary/1</seealso> instead of this function.</p>
- </desc>
- </func>
-
- </funcs>
-
-</erlref>
-
diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml
index 68d335f451..26640acabc 100644
--- a/lib/asn1/doc/src/notes.xml
+++ b/lib/asn1/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,6 +32,71 @@
<p>This document describes the changes made to the asn1 application.</p>
+<section><title>Asn1 5.0</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add compile option <c>-compile(no_native)</c> in modules
+ with <c>on_load</c> directive which is not yet supported
+ by HiPE.</p>
+ <p>
+ Own Id: OTP-14316 Aux Id: PR-1390 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The <c>error</c> tuple returned from the <c>encode</c>
+ and <c>decode</c> functions will now include the stack
+ backtrace to make it easier to understand what went
+ wrong.</p>
+ <p>
+ Own Id: OTP-13961</p>
+ </item>
+ <item>
+ <p>The deprecated module <c>asn1rt</c> has been removed.
+ The deprecated functions <c>asn1ct:encode/3</c> and
+ <c>asn1ct:decode/3</c> have been removed. The
+ undocumented function <c>asn1ct:encode/2</c> has been
+ removed.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14146</p>
+ </item>
+ <item>
+ <p>The new '<c>maps</c>' option changes the
+ representation of the types <c>SEQUENCE</c> and
+ <c>SET</c> to be maps (instead of records).</p>
+ <p>
+ Own Id: OTP-14219</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Asn1 4.0.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Compiling multiple ASN.1 modules in the same directory
+ with parallel make (make -j) should now be safe.</p>
+ <p>
+ Own Id: OTP-13624</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Asn1 4.0.3</title>
<section><title>Improvements and New Features</title>
@@ -329,7 +394,7 @@
</item>
<item>
<p>
- The <c>asn1</c> application would fail to build if the
+ The ASN.1 application would fail to build if the
<c>.erlang</c> file printed something to standard output.</p>
<p>
Own Id: OTP-11360</p>
@@ -997,7 +1062,7 @@
also been extended. </item><item> The <c>configure</c>
scripts of <c>erl_interface</c> and <c>odbc</c> now
search for thread libraries and thread library quirks the
- same way as <c>erts</c> do. </item><item> The
+ same way as ERTS do. </item><item> The
<c>configure</c> script of the <c>odbc</c> application
now also looks for odbc libraries in <c>lib64</c> and
<c>lib/64</c> directories when building on a 64-bit
diff --git a/lib/asn1/doc/src/ref_man.xml b/lib/asn1/doc/src/ref_man.xml
index d70e2bc05f..14f6818cae 100644
--- a/lib/asn1/doc/src/ref_man.xml
+++ b/lib/asn1/doc/src/ref_man.xml
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -34,6 +34,5 @@
contains modules with compile-time and runtime support for ASN.1.</p>
</description>
<xi:include href="asn1ct.xml"/>
- <xi:include href="asn1rt.xml"/>
</application>
diff --git a/lib/asn1/examples/recordnames.txt b/lib/asn1/examples/recordnames.txt
index 78e30ab510..9b890b4aa7 100644
--- a/lib/asn1/examples/recordnames.txt
+++ b/lib/asn1/examples/recordnames.txt
@@ -1,6 +1,6 @@
For each ASN1 types SET and SEQUENCE a record is generated in the .hrl
file with the same name as the corresponding type.
-A decoded value is also returned as a record with the apropriate name.
+A decoded value is also returned as a record with the appropriate name.
An internally defined type as the type in component 'a' in the
following example will result in a record with name 'Seq_a':
diff --git a/lib/asn1/src/Makefile b/lib/asn1/src/Makefile
index 38cf2d496a..ba459f6cd3 100644
--- a/lib/asn1/src/Makefile
+++ b/lib/asn1/src/Makefile
@@ -68,7 +68,6 @@ CT_MODULES= \
$(EVAL_CT_MODULES)
RT_MODULES= \
- asn1rt \
asn1rt_nif
MODULES= $(CT_MODULES) $(RT_MODULES)
diff --git a/lib/asn1/src/asn1.app.src b/lib/asn1/src/asn1.app.src
index 1f8805ff5e..d2da727193 100644
--- a/lib/asn1/src/asn1.app.src
+++ b/lib/asn1/src/asn1.app.src
@@ -2,7 +2,6 @@
[{description, "The Erlang ASN1 compiler version %VSN%"},
{vsn, "%VSN%"},
{modules, [
- asn1rt,
asn1rt_nif
]},
{registered, [
diff --git a/lib/asn1/src/asn1_db.erl b/lib/asn1/src/asn1_db.erl
index 557eca0ffd..7486fa2db9 100644
--- a/lib/asn1/src/asn1_db.erl
+++ b/lib/asn1/src/asn1_db.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
%%
-module(asn1_db).
--export([dbstart/1,dbnew/2,dbload/1,dbload/3,dbsave/2,dbput/2,
+-export([dbstart/1,dbnew/3,dbload/1,dbload/4,dbsave/2,dbput/2,
dbput/3,dbget/2]).
-export([dbstop/0]).
@@ -37,13 +37,13 @@ dbstart(Includes0) ->
put(?MODULE, spawn_link(fun() -> init(Parent, Includes) end)),
ok.
-dbload(Module, Erule, Mtime) ->
- req({load, Module, Erule, Mtime}).
+dbload(Module, Erule, Maps, Mtime) ->
+ req({load, Module, {Erule,Maps}, Mtime}).
dbload(Module) ->
req({load, Module, any, {{0,0,0},{0,0,0}}}).
-dbnew(Module, Erule) -> req({new, Module, Erule}).
+dbnew(Module, Erule, Maps) -> req({new, Module, {Erule,Maps}}).
dbsave(OutFile, Module) -> cast({save, OutFile, Module}).
dbput(Module, K, V) -> cast({set, Module, K, V}).
dbput(Module, Kvs) -> cast({set, Module, Kvs}).
@@ -106,21 +106,23 @@ loop(#state{parent = Parent, monitor = MRef, table = Table,
loop(State);
{save, OutFile, Mod} ->
[{_,Mtab}] = ets:lookup(Table, Mod),
- ok = ets:tab2file(Mtab, OutFile),
+ TempFile = OutFile ++ ".#temp",
+ ok = ets:tab2file(Mtab, TempFile),
+ ok = file:rename(TempFile, OutFile),
loop(State);
- {From, {new, Mod, Erule}} ->
+ {From, {new, Mod, EruleMaps}} ->
[] = ets:lookup(Table, Mod), %Assertion.
ModTableId = ets:new(list_to_atom(lists:concat(["asn1_",Mod])), []),
ets:insert(Table, {Mod, ModTableId}),
- ets:insert(ModTableId, {?MAGIC_KEY, info(Erule)}),
+ ets:insert(ModTableId, {?MAGIC_KEY, info(EruleMaps)}),
reply(From, ok),
loop(State);
- {From, {load, Mod, Erule, Mtime}} ->
+ {From, {load, Mod, EruleMaps, Mtime}} ->
case ets:member(Table, Mod) of
true ->
reply(From, ok);
false ->
- case load_table(Mod, Erule, Mtime, Includes) of
+ case load_table(Mod, EruleMaps, Mtime, Includes) of
{ok, ModTableId} ->
ets:insert(Table, {Mod, ModTableId}),
reply(From, ok);
@@ -149,20 +151,20 @@ lookup(Tab, K) ->
[{K,V}] -> V
end.
-info(Erule) ->
- {asn1ct:vsn(),Erule}.
+info(EruleMaps) ->
+ {asn1ct:vsn(),EruleMaps}.
-load_table(Mod, Erule, Mtime, Includes) ->
+load_table(Mod, EruleMaps, Mtime, Includes) ->
Base = lists:concat([Mod, ".asn1db"]),
case path_find(Includes, Mtime, Base) of
error ->
error;
- {ok,ModTab} when Erule =:= any ->
+ {ok,ModTab} when EruleMaps =:= any ->
{ok,ModTab};
{ok,ModTab} ->
Vsn = asn1ct:vsn(),
case ets:lookup(ModTab, ?MAGIC_KEY) of
- [{_,{Vsn,Erule}}] ->
+ [{_,{Vsn,EruleMaps}}] ->
%% Correct version and encoding rule.
{ok,ModTab};
_ ->
diff --git a/lib/asn1/src/asn1_records.hrl b/lib/asn1/src/asn1_records.hrl
index af10c1771c..43fa61bc5b 100644
--- a/lib/asn1/src/asn1_records.hrl
+++ b/lib/asn1/src/asn1_records.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@
-define('COMPLETE_ENCODE',1).
-define('TLV_DECODE',2).
+-define(MISSING_IN_MAP, asn1__MISSING_IN_MAP).
-record(module,{pos,name,defid,tagdefault='EXPLICIT',exports={exports,[]},imports={imports,[]}, extensiondefault=empty,typeorval}).
@@ -96,6 +97,28 @@
error_context %Top-level thingie (contains line numbers)
}).
+%% Code generation parameters and options.
+-record(gen,
+ {erule=ber :: 'ber' | 'per',
+ der=false :: boolean(),
+ aligned=false :: boolean(),
+ rec_prefix="" :: string(),
+ macro_prefix="" :: string(),
+ pack=record :: 'record' | 'map',
+ options=[] :: [any()]
+ }).
+
+%% Abstract intermediate representation.
+-record(abst,
+ {name :: module(), %Name of module.
+ types, %Types.
+ values, %Values.
+ ptypes, %Parameterized types.
+ classes, %Classes.
+ objects, %Objects.
+ objsets %Object sets.
+ }).
+
%% state record used by back-end at partial decode
%% active is set to 'yes' when a partial decode function is generated.
%% prefix is set to 'dec-inc-' or 'dec-partial-' is for
diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl
index dd269f095d..f36d71a601 100644
--- a/lib/asn1/src/asn1ct.erl
+++ b/lib/asn1/src/asn1ct.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,18 +20,13 @@
%%
%%
-module(asn1ct).
--deprecated([decode/3,encode/3]).
--compile([{nowarn_deprecated_function,{asn1rt,decode,3}},
- {nowarn_deprecated_function,{asn1rt,encode,2}},
- {nowarn_deprecated_function,{asn1rt,encode,3}}]).
%% Compile Time functions for ASN.1 (e.g ASN.1 compiler).
-%%-compile(export_all).
%% Public exports
-export([compile/1, compile/2]).
--export([encode/2, encode/3, decode/3]).
-export([test/1, test/2, test/3, value/2, value/3]).
+
%% Application internal exports
-export([compile_asn/3,compile_asn1/3,compile_py/3,compile/3,
vsn/0,
@@ -80,12 +75,9 @@
-define(ALTERNATIVE,alt).
-define(ALTERNATIVE_UNDECODED,alt_undec).
-define(ALTERNATIVE_PARTS,alt_parts).
-%-define(BINARY,bin).
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This is the interface to the compiler
-%%
-%%
compile(File) ->
compile(File,[]).
@@ -198,7 +190,7 @@ check_pass(#st{code=M,file=File,includes=Includes,
erule=Erule,dbfile=DbFile,opts=Opts,
inputmodules=InputModules}=St) ->
start(Includes),
- case asn1ct_check:storeindb(#state{erule=Erule}, M) of
+ case asn1ct_check:storeindb(#state{erule=Erule,options=Opts}, M) of
ok ->
Module = asn1_db:dbget(M#module.name, 'MODULE'),
State = #state{mname=Module#module.name,
@@ -221,9 +213,8 @@ check_pass(#st{code=M,file=File,includes=Includes,
{error,St#st{error=Reason}}
end.
-save_pass(#st{code=M,erule=Erule,dbfile=DbFile}=St) ->
- ok = asn1ct_check:storeindb(#state{erule=Erule}, M),
- asn1_db:dbsave(DbFile,M#module.name),
+save_pass(#st{code=M,erule=Erule,opts=Opts}=St) ->
+ ok = asn1ct_check:storeindb(#state{erule=Erule,options=Opts}, M),
{ok,St}.
parse_listing(#st{code=Code,outfile=OutFile0}=St) ->
@@ -242,12 +233,8 @@ abs_listing(#st{code={M,_},outfile=OutFile}) ->
generate_pass(#st{code=Code,outfile=OutFile,erule=Erule,opts=Opts}=St0) ->
St = St0#st{code=undefined}, %Reclaim heap space
- case generate(Code, OutFile, Erule, Opts) of
- {error,Reason} ->
- {error,St#st{error=Reason}};
- ok ->
- {ok,St}
- end.
+ generate(Code, OutFile, Erule, Opts),
+ {ok,St}.
compile_pass(#st{outfile=OutFile,opts=Opts0}=St) ->
asn1_db:dbstop(), %Reclaim memory.
@@ -761,7 +748,6 @@ remove_import_doubles([]) ->
remove_import_doubles(ImportList) ->
MergedImportList =
merge_symbols_from_module(ImportList,[]),
-%% io:format("MergedImportList: ~p~n",[MergedImportList]),
delete_double_of_symbol(MergedImportList,[]).
merge_symbols_from_module([Imp|Imps],Acc) ->
@@ -779,7 +765,6 @@ merge_symbols_from_module([Imp|Imps],Acc) ->
end,
Imps),
NewImps = lists:subtract(Imps,IfromModName),
-%% io:format("Imp: ~p~nIfromModName: ~p~n",[Imp,IfromModName]),
NewImp =
Imp#'SymbolsFromModule'{
symbols = lists:append(
@@ -840,37 +825,53 @@ delete_double_of_symbol1([],Acc) ->
%%***********************************
-generate({M,GenTOrV}, OutFile, EncodingRule, Options) ->
- debug_on(Options),
+generate({M,CodeTuple}, OutFile, EncodingRule, Options) ->
+ {Types,Values,Ptypes,Classes,Objects,ObjectSets} = CodeTuple,
+ Code = #abst{name=M#module.name,
+ types=Types,values=Values,ptypes=Ptypes,
+ classes=Classes,objects=Objects,objsets=ObjectSets},
setup_bit_string_format(Options),
setup_legacy_erlang_types(Options),
- put(encoding_options,Options),
asn1ct_table:new(check_functions),
+ Gen = init_gen_record(EncodingRule, Options),
+
+ check_maps_option(Gen),
+
%% create decoding function names and taglists for partial decode
- case (catch specialized_decode_prepare(EncodingRule,M,GenTOrV,Options)) of
- {error, Reason} -> warning("Error in configuration file: ~n~p~n",
- [Reason], Options,
- "Error in configuration file");
- _ -> ok
+ try
+ specialized_decode_prepare(Gen, M)
+ catch
+ throw:{error, Reason} ->
+ warning("Error in configuration file: ~n~p~n",
+ [Reason], Options,
+ "Error in configuration file")
end,
- Result =
- case (catch asn1ct_gen:pgen(OutFile,EncodingRule,
- M#module.name,GenTOrV,Options)) of
- {'EXIT',Reason2} ->
- error("~p~n",[Reason2],Options),
- {error,Reason2};
- _ ->
- ok
- end,
- debug_off(Options),
- erase(encoding_options),
+ asn1ct_gen:pgen(OutFile, Gen, Code),
cleanup_bit_string_format(),
erase(tlv_format), % used in ber
erase(class_default_type),% used in ber
asn1ct_table:delete(check_functions),
- Result.
+ ok.
+
+init_gen_record(EncodingRule, Options) ->
+ Erule = case EncodingRule of
+ uper -> per;
+ _ -> EncodingRule
+ end,
+ Der = proplists:get_bool(der, Options),
+ Aligned = EncodingRule =:= per,
+ RecPrefix = proplists:get_value(record_name_prefix, Options, ""),
+ MacroPrefix = proplists:get_value(macro_name_prefix, Options, ""),
+ Pack = case proplists:get_value(maps, Options, false) of
+ true -> map;
+ false -> record
+ end,
+ #gen{erule=Erule,der=Der,aligned=Aligned,
+ rec_prefix=RecPrefix,macro_prefix=MacroPrefix,
+ pack=Pack,options=Options}.
+
setup_legacy_erlang_types(Opts) ->
F = case lists:member(legacy_erlang_types, Opts) of
@@ -916,6 +917,26 @@ cleanup_bit_string_format() ->
get_bit_string_format() ->
get(bit_string_format).
+check_maps_option(#gen{pack=map}) ->
+ case get_bit_string_format() of
+ bitstring ->
+ ok;
+ _ ->
+ Message1 = "The 'maps' option must not be combined with "
+ "'compact_bit_string' or 'legacy_bit_string'",
+ exit({error,{asn1,Message1}})
+ end,
+ case use_legacy_types() of
+ false ->
+ ok;
+ true ->
+ Message2 = "The 'maps' option must not be combined with "
+ "'legacy_erlang_types'",
+ exit({error,{asn1,Message2}})
+ end;
+check_maps_option(#gen{}) ->
+ ok.
+
%% parse_and_save parses an asn1 spec and saves the unchecked parse
%% tree in a data base file.
@@ -925,22 +946,27 @@ parse_and_save(Module,S) ->
SourceDir = S#state.sourcedir,
Includes = [I || {i,I} <- Options],
Erule = S#state.erule,
+ Maps = lists:member(maps, Options),
case get_input_file(Module, [SourceDir|Includes]) of
%% search for asn1 source
{file,SuffixedASN1source} ->
Mtime = filelib:last_modified(SuffixedASN1source),
- case asn1_db:dbload(Module, Erule, Mtime) of
+ case asn1_db:dbload(Module, Erule, Maps, Mtime) of
ok -> ok;
error -> parse_and_save1(S, SuffixedASN1source, Options)
end;
- Err ->
+ Err when not Maps ->
case asn1_db:dbload(Module) of
ok ->
+ %% FIXME: This should be an error.
warning("could not do a consistency check of the ~p file: no asn1 source file was found.~n",
[lists:concat([Module,".asn1db"])],Options);
error ->
ok
end,
+ {error,{asn1,input_file_error,Err}};
+ Err ->
+ %% Always fail directly when the 'maps' option is used.
{error,{asn1,input_file_error,Err}}
end.
@@ -957,12 +983,8 @@ get_input_file(Module,[]) ->
get_input_file(Module,[I|Includes]) ->
case (catch input_file_type(filename:join([I,Module]))) of
{single_file,FileName} ->
-%% case file:read_file_info(FileName) of
-%% {ok,_} ->
{file,FileName};
-%% _ -> get_input_file(Module,Includes)
-%% end;
- _ ->
+ _ ->
get_input_file(Module,Includes)
end.
@@ -1003,9 +1025,8 @@ input_file_type(File) ->
end
end;
".asn1config" ->
- case read_config_file(File,asn1_module) of
+ case read_config_file_info(File, asn1_module) of
{ok,Asn1Module} ->
-% put(asn1_config_file,File),
input_file_type(Asn1Module);
Error ->
Error
@@ -1098,30 +1119,29 @@ translate_options([H|T]) ->
translate_options([]) -> [].
remove_asn_flags(Options) ->
- [X || X <- Options,
- X /= get_rule(Options),
- X /= optimize,
- X /= compact_bit_string,
- X /= legacy_bit_string,
- X /= legacy_erlang_types,
- X /= debug,
- X /= asn1config,
- X /= record_name_prefix].
-
-debug_on(Options) ->
- case lists:member(debug,Options) of
- true ->
- put(asndebug,true);
- _ ->
- true
- end.
-
-debug_off(_Options) ->
- erase(asndebug).
+ [X || X <- Options, not is_asn1_flag(X)].
+
+is_asn1_flag(asn1config) -> true;
+is_asn1_flag(ber) -> true;
+is_asn1_flag(compact_bit_string) -> true;
+is_asn1_flag(debug) -> true;
+is_asn1_flag(der) -> true;
+is_asn1_flag(legacy_bit_string) -> true;
+is_asn1_flag({macro_name_prefix,_}) -> true;
+is_asn1_flag({n2n,_}) -> true;
+is_asn1_flag(noobj) -> true;
+is_asn1_flag(no_ok_wrapper) -> true;
+is_asn1_flag(optimize) -> true;
+is_asn1_flag(per) -> true;
+is_asn1_flag({record_name_prefix,_}) -> true;
+is_asn1_flag(undec_rec) -> true;
+is_asn1_flag(uper) -> true;
+is_asn1_flag(verbose) -> true;
+%% 'warnings_as_errors' is intentionally passed through to the compiler.
+is_asn1_flag(_) -> false.
outfile(Base, Ext, Opts) ->
-% io:format("Opts. ~p~n",[Opts]),
Obase = case lists:keysearch(outdir, 1, Opts) of
{value, {outdir, Odir}} -> filename:join(Odir, Base);
_NotFound -> Base % Not found or bad format
@@ -1172,9 +1192,6 @@ compile_py(File,OutFile,Options) ->
compile(File, _OutFile, Options) ->
case compile(File, make_erl_options(Options)) of
{error,_Reason} ->
- %% case occurs due to error in asn1ct_parser2,asn1ct_check
-%% io:format("~p~n",[_Reason]),
-%% io:format("~p~n~s~n",[_Reason,"error"]),
error;
ok ->
ok;
@@ -1272,21 +1289,6 @@ pretty2(Module,AbsFile) ->
start(Includes) when is_list(Includes) ->
asn1_db:dbstart(Includes).
-
-encode(Module,Term) ->
- asn1rt:encode(Module,Term).
-
-encode(Module,Type,Term) when is_list(Module) ->
- asn1rt:encode(list_to_atom(Module),Type,Term);
-encode(Module,Type,Term) ->
- asn1rt:encode(Module,Type,Term).
-
-decode(Module,Type,Bytes) when is_list(Module) ->
- asn1rt:decode(list_to_atom(Module),Type,Bytes);
-decode(Module,Type,Bytes) ->
- asn1rt:decode(Module,Type,Bytes).
-
-
test(Module) -> test_module(Module, []).
test(Module, [] = Options) -> test_module(Module, Options);
@@ -1331,10 +1333,10 @@ test_type(Module, Type) ->
test_value(Module, Type, Value) ->
in_process(fun() ->
- case catch encode(Module, Type, Value) of
+ case catch Module:encode(Type, Value) of
{ok, Bytes} ->
NewBytes = prepare_bytes(Bytes),
- case decode(Module, Type, NewBytes) of
+ case Module:decode(Type, NewBytes) of
{ok, Value} ->
{ok, {Module, Type, Value}};
{ok, Res} ->
@@ -1391,25 +1393,26 @@ prepare_bytes(Bytes) -> list_to_binary(Bytes).
vsn() ->
?vsn.
-specialized_decode_prepare(Erule,M,TsAndVs,Options) ->
- case lists:member(asn1config,Options) of
+specialized_decode_prepare(#gen{erule=ber,options=Options}=Gen, M) ->
+ case lists:member(asn1config, Options) of
true ->
- partial_decode_prepare(Erule,M,TsAndVs,Options);
- _ ->
+ special_decode_prepare_1(Gen, M);
+ false ->
ok
- end.
+ end;
+specialized_decode_prepare(_, _) ->
+ ok.
+
%% Reads the configuration file if it exists and stores information
%% about partial decode and incomplete decode
-partial_decode_prepare(ber,M,TsAndVs,Options) when is_tuple(TsAndVs) ->
+special_decode_prepare_1(#gen{options=Options}=Gen, M) ->
%% read configure file
-
- ModName =
- case lists:keysearch(asn1config,1,Options) of
- {value,{_,MName}} -> MName;
- _ -> M#module.name
- end,
+ ModName = case lists:keyfind(asn1config, 1, Options) of
+ {_,MName} -> MName;
+ false -> M#module.name
+ end,
%% io:format("ModName: ~p~nM#module.name: ~p~n~n",[ModName,M#module.name]),
- case read_config_file(ModName) of
+ case read_config_file(Gen, ModName) of
no_config_file ->
ok;
CfgList ->
@@ -1428,11 +1431,7 @@ partial_decode_prepare(ber,M,TsAndVs,Options) when is_tuple(TsAndVs) ->
Part_inc_tlv_tags = tlv_tags(CommandList2),
save_config(partial_incomplete_decode,Part_inc_tlv_tags),
save_gen_state(exclusive_decode,ExclusiveDecode,Part_inc_tlv_tags)
- end;
-partial_decode_prepare(_,_,_,_) ->
- ok.
-
-
+ end.
%% create_partial_inc_decode_gen_info/2
%%
@@ -1487,7 +1486,8 @@ create_pdec_inc_command(_ModName,_,[],Acc) ->
create_pdec_inc_command(ModName,{Comps1,Comps2},TNL,Acc)
when is_list(Comps1),is_list(Comps2) ->
create_pdec_inc_command(ModName,Comps1 ++ Comps2,TNL,Acc);
-%% The following two functionclauses matches on the type after the top type. This one if the top type had no tag, i.e. a CHOICE
+%% The following two clauses match on the type after the top
+%% type. This one if the top type had no tag, i.e. a CHOICE.
create_pdec_inc_command(ModN,Clist,[CL|_Rest],[[]]) when is_list(CL) ->
create_pdec_inc_command(ModN,Clist,CL,[]);
create_pdec_inc_command(ModN,Clist,[CL|_Rest],Acc) when is_list(CL) ->
@@ -1498,17 +1498,14 @@ create_pdec_inc_command(ModName,
prop=Prop}|Comps],
TNL=[C1|Cs],Acc) ->
case C1 of
-% Name ->
-% %% In this case C1 is an atom
-% TagCommand = get_tag_command(TS,?MANDATORY,Prop),
-% create_pdec_inc_command(ModName,get_components(TS#type.def),Cs,[TagCommand|Acc]);
{Name,undecoded} ->
TagCommand = get_tag_command(TS,?UNDECODED,Prop),
create_pdec_inc_command(ModName,Comps,Cs,concat_sequential(TagCommand,Acc));
{Name,parts} ->
TagCommand = get_tag_command(TS,?PARTS,Prop),
create_pdec_inc_command(ModName,Comps,Cs,concat_sequential(TagCommand,Acc));
- L when is_list(L) -> % I guess this never happens due to previous function clause
+ L when is_list(L) ->
+ %% I guess this never happens due to previous clause.
%% This case is only possible as the first element after
%% the top type element, when top type is SEGUENCE or SET.
%% Follow each element in L. Must note every tag on the
@@ -1530,8 +1527,6 @@ create_pdec_inc_command(ModName,
RestPartsList,[]),
create_pdec_inc_command(ModName,Comps,Cs,
[[?MANDATORY,InnerDirectives]|Acc]);
-% create_pdec_inc_command(ModName,Comps,Cs,
-% [InnerDirectives,?MANDATORY|Acc]);
[Opt,EncTag] ->
InnerDirectives =
create_pdec_inc_command(ModName,TS#type.def,
@@ -1539,9 +1534,8 @@ create_pdec_inc_command(ModName,
create_pdec_inc_command(ModName,Comps,Cs,
[[Opt,EncTag,InnerDirectives]|Acc])
end;
-% create_pdec_inc_command(ModName,CList,RestPartsList,Acc);
-%% create_pdec_inc_command(ModName,TS#type.def,RestPartsList,Acc);
- _ -> %% this component may not be in the config list
+ _ ->
+ %% this component may not be in the config list
TagCommand = get_tag_command(TS,?MANDATORY,Prop),
create_pdec_inc_command(ModName,Comps,TNL,concat_sequential(TagCommand,Acc))
end;
@@ -1552,7 +1546,6 @@ create_pdec_inc_command(ModName,
[{C1,Directive}|Rest],Acc) ->
case Directive of
List when is_list(List) ->
-% [Command,Tag] = get_tag_command(TS,?ALTERNATIVE,Prop),
TagCommand = get_tag_command(TS,?ALTERNATIVE,Prop),
CompAcc =
create_pdec_inc_command(ModName,
@@ -1561,9 +1554,6 @@ create_pdec_inc_command(ModName,
[Command,Tag] when is_atom(Command) ->
[[Command,Tag,CompAcc]|Acc];
[L1,_L2|Rest] when is_list(L1) ->
-% [LastComm|Comms] = lists:reverse(TagCommand),
-% [concat_sequential(lists:reverse(Comms),
-% [LastComm,CompAcc])|Acc]
case lists:reverse(TagCommand) of
[Atom|Comms] when is_atom(Atom) ->
[concat_sequential(lists:reverse(Comms),
@@ -1572,12 +1562,8 @@ create_pdec_inc_command(ModName,
[concat_sequential(lists:reverse(Comms),
[[Command2,Tag2,CompAcc]])|Acc]
end
-% [concat_sequential(lists:reverse(Comms),
-% InnerCommand)|Acc]
-
end,
create_pdec_inc_command(ModName,{'CHOICE',Comps},Rest,
-% [[Command,Tag,CompAcc]|Acc]);
NewAcc);
undecoded ->
TagCommand = get_tag_command(TS,?ALTERNATIVE_UNDECODED,Prop),
@@ -1633,7 +1619,6 @@ create_partial_decode_gen_info(_M1,{M2,_}) ->
throw({error,{"wrong module name in asn1 config file",
M2}}).
-%create_partial_decode_gen_info1(ModName,{ModName,TypeList}) ->
create_partial_decode_gen_info1(ModName,{FuncName,TypeList}) ->
case TypeList of
[TopType|Rest] ->
@@ -1653,11 +1638,6 @@ create_partial_decode_gen_info1(ModName,{FuncName,TypeList}) ->
end;
create_partial_decode_gen_info1(_,_) ->
ok.
-% create_partial_decode_gen_info1(_,[]) ->
-% [];
-% create_partial_decode_gen_info1(_M1,{M2,_}) ->
-% throw({error,{"wrong module name in asn1 config file",
-% M2}}).
%% create_pdec_command/4 for each name (type or component) in the
%% third argument, TypeNameList, a command is created. The command has
@@ -1673,7 +1653,6 @@ create_pdec_command(_ModName,_,[],Acc) ->
Fun(L,[H|Res],Fun)
end,
Remove_empty_lists(Acc,[],Remove_empty_lists);
-% lists:reverse(Acc);
create_pdec_command(ModName,[#'ComponentType'{name=C1,typespec=TS}|_Comps],
[C1|Cs],Acc) ->
%% this component is a constructed type or the last in the
@@ -1722,9 +1701,7 @@ create_pdec_command(ModName,TS=#type{def=Def},[C1|Cs],Acc) ->
create_pdec_command(_,_,TNL,_) ->
throw({error,{"unexpected error when creating partial "
"decode command",TNL}}).
-
-% get_components({'CHOICE',Components}) ->
-% Components;
+
get_components(#'SEQUENCE'{components={C1,C2}}) when is_list(C1),is_list(C2) ->
C1++C2;
get_components(#'SEQUENCE'{components=Components}) ->
@@ -1795,8 +1772,6 @@ get_tag_command(#type{tag=[Tag]},Command) ->
[Command,encode_tag_val(decode_class(Tag#tag.class),Tag#tag.form,
Tag#tag.number)];
get_tag_command(T=#type{tag=[Tag|Tags]},Command) ->
-% [get_tag_command(T#type{tag=[Tag]},Command)|
-% [get_tag_command(T#type{tag=Tags},Command)]].
TC = get_tag_command(T#type{tag=[Tag]},Command),
TCs = get_tag_command(T#type{tag=Tags},Command),
case many_tags(TCs) of
@@ -1824,7 +1799,6 @@ get_tag_command(#type{tag=Tag},Command,Prop) when is_record(Tag,tag) ->
get_tag_command(#type{tag=[Tag]},Command,Prop);
get_tag_command(T=#type{tag=[Tag|Tags]},Command,Prop) ->
[get_tag_command(T#type{tag=[Tag]},Command,Prop)|[
-% get_tag_command(T#type{tag=Tags},?MANDATORY,Prop)]].
get_tag_command(T#type{tag=Tags},Command,Prop)]].
anonymous_dec_command(?UNDECODED,'OPTIONAL') ->
@@ -1884,46 +1858,38 @@ tlv_tag1(<<0:1,PartialTag:7>>,Acc) ->
tlv_tag1(<<1:1,PartialTag:7,Buffer/binary>>,Acc) ->
tlv_tag1(Buffer,(Acc bsl 7) bor PartialTag).
-%% reads the content from the configuration file and returns the
-%% selected part choosen by InfoType. Assumes that the config file
+%% Reads the content from the configuration file and returns the
+%% selected part chosen by InfoType. Assumes that the config file
%% content is an Erlang term.
-read_config_file(ModuleName,InfoType) when is_atom(InfoType) ->
- CfgList = read_config_file(ModuleName),
- get_config_info(CfgList,InfoType).
+read_config_file_info(ModuleName, InfoType) when is_atom(InfoType) ->
+ Name = ensure_ext(ModuleName, ".asn1config"),
+ CfgList = read_config_file0(Name, []),
+ get_config_info(CfgList, InfoType).
+read_config_file(#gen{options=Options}, ModuleName) ->
+ Name = ensure_ext(ModuleName, ".asn1config"),
+ Includes = [I || {i,I} <- Options],
+ read_config_file0(Name, ["."|Includes]).
-read_config_file(ModuleName) ->
- case file:consult(lists:concat([ModuleName,'.asn1config'])) of
+read_config_file0(Name, [D|Dirs]) ->
+ case file:consult(filename:join(D, Name)) of
{ok,CfgList} ->
CfgList;
{error,enoent} ->
- Options = get(encoding_options),
- Includes = [I || {i,I} <- Options],
- read_config_file1(ModuleName,Includes);
+ read_config_file0(Name, Dirs);
{error,Reason} ->
Error = "error reading asn1 config file: " ++
file:format_error(Reason),
throw({error,Error})
- end.
-read_config_file1(ModuleName,[]) ->
- case filename:extension(ModuleName) of
- ".asn1config" ->
- no_config_file;
- _ ->
- read_config_file(lists:concat([ModuleName,".asn1config"]))
end;
-read_config_file1(ModuleName,[H|T]) ->
-% File = filename:join([H,lists:concat([ModuleName,'.asn1config'])]),
- File = filename:join([H,ModuleName]),
- case file:consult(File) of
- {ok,CfgList} ->
- CfgList;
- {error,enoent} ->
- read_config_file1(ModuleName,T);
- {error,Reason} ->
- Error = "error reading asn1 config file: " ++
- file:format_error(Reason),
- throw({error,Error})
+read_config_file0(_, []) ->
+ no_config_file.
+
+ensure_ext(ModuleName, Ext) ->
+ Name = filename:join([ModuleName]),
+ case filename:extension(Name) of
+ Ext -> Name;
+ _ -> Name ++ Ext
end.
get_config_info(CfgList,InfoType) ->
@@ -1947,8 +1913,8 @@ read_config_data(Key) ->
true ->
case asn1ct_table:lookup(asn1_general,{asn1_config,Key}) of
[{_,Data}] -> Data;
- Err -> % Err is [] when nothing was saved in the ets table
-%% io:format("strange data from config file ~w~n",[Err]),
+ Err ->
+ %% Err is [] when nothing was saved in the ets table
Err
end
end.
@@ -1961,7 +1927,6 @@ read_config_data(Key) ->
%% saves input data in a new gen_state record
save_gen_state(exclusive_decode,{_,ConfList},PartIncTlvTagList) ->
- %ConfList=[{FunctionName,PatternList}|Rest]
State =
case get_gen_state() of
S when is_record(S,gen_state) -> S;
@@ -1971,14 +1936,12 @@ save_gen_state(exclusive_decode,{_,ConfList},PartIncTlvTagList) ->
inc_type_pattern=ConfList},
save_config(gen_state,StateRec);
save_gen_state(_,_,_) ->
-%% ok.
case get_gen_state() of
S when is_record(S,gen_state) -> ok;
_ -> save_config(gen_state,#gen_state{})
end.
save_gen_state(selective_decode,{_,Type_component_name_list}) ->
-%% io:format("Selective_decode: ~p~n",[Type_component_name_list]),
State =
case get_gen_state() of
S when is_record(S,gen_state) -> S;
@@ -2060,11 +2023,6 @@ update_gen_state(type_pattern,State,Data) ->
update_gen_state(func_name,State,Data) ->
save_gen_state(State#gen_state{func_name=Data});
update_gen_state(namelist,State,Data) ->
-% SData =
-% case Data of
-% [D] when is_list(D) -> D;
-% _ -> Data
-% end,
save_gen_state(State#gen_state{namelist=Data});
update_gen_state(tobe_refed_funcs,State,Data) ->
save_gen_state(State#gen_state{tobe_refed_funcs=Data});
@@ -2119,7 +2077,6 @@ get_tobe_refed_func(Name) ->
%% tuple. Do not save if it exists in generated_functions, because
%% then it will be or already is generated.
add_tobe_refed_func(Data) ->
- %%
{Name,SI,Pattern} =
fun({N,Si,P,_}) -> {N,Si,P};
(D) -> D end (Data),
@@ -2127,8 +2084,6 @@ add_tobe_refed_func(Data) ->
case SI of
I when is_integer(I) ->
fun(D) -> D end(Data);
-% fun({N,Ix,P}) -> {N,Ix+1,P};
-% ({N,Ix,P,T}) -> {N,Ix+1,P,T} end (Data);
_ ->
fun({N,_,P}) -> {N,0,P};
({N,_,P,T}) -> {N,0,P,T} end (Data)
@@ -2136,12 +2091,13 @@ add_tobe_refed_func(Data) ->
L = get_gen_state_field(generated_functions),
case generated_functions_member(get(currmod),Name,L,Pattern) of
- true -> % it exists in generated_functions, it has already
- % been generated or saved in tobe_refed_func
+ true ->
+ %% it exists in generated_functions, it has already
+ %% been generated or saved in tobe_refed_func
ok;
_ ->
add_once_tobe_refed_func(NewData),
- %%only to get it saved in generated_functions
+ %% only to get it saved in generated_functions
maybe_rename_function(tobe_refed,Name,Pattern)
end.
@@ -2156,16 +2112,13 @@ add_once_tobe_refed_func(Data) ->
({N,I,_,_}) when N==Name,I==Index -> true;
(_) -> false end,TRFL) of
[] ->
-%% case lists:keysearch(element(1,Data),1,TRFL) of
-%% false ->
update_gen_state(tobe_refed_funcs,[Data|TRFL]);
_ ->
ok
end.
-
-%% moves Name from the to be list to the generated list.
+%% Moves Name from the to be list to the generated list.
generated_refed_func(Name) ->
L = get_gen_state_field(tobe_refed_funcs),
NewL = lists:keydelete(Name,1,L),
@@ -2173,7 +2126,7 @@ generated_refed_func(Name) ->
L2 = get_gen_state_field(gen_refed_funcs),
update_gen_state(gen_refed_funcs,[Name|L2]).
-%% adds Data to gen_refed_funcs field in gen_state.
+%% Adds Data to gen_refed_funcs field in gen_state.
add_generated_refed_func(Data) ->
case is_function_generated(Data) of
true ->
@@ -2195,7 +2148,7 @@ next_refed_func() ->
reset_gen_state() ->
save_gen_state(#gen_state{}).
-%% adds Data to generated_functions field in gen_state.
+%% Adds Data to generated_functions field in gen_state.
add_generated_function(Data) ->
L = get_gen_state_field(generated_functions),
update_gen_state(generated_functions,[Data|L]).
@@ -2214,16 +2167,18 @@ maybe_rename_function(Mode,Name,Pattern) ->
{_,true} ->
L2 = generated_functions_filter(get(currmod),Name,L),
case lists:keysearch(Pattern,3,L2) of
- false -> %name existed, but not pattern
+ false ->
+ %% name existed, but not pattern
NextIndex = length(L2),
- %%rename function
+ %% rename function
Suffix = lists:concat(["_",NextIndex]),
NewName =
maybe_rename_function2(type_check(Name),Name,
Suffix),
add_generated_function({Name,NextIndex,Pattern}),
NewName;
- Value -> % name and pattern existed
+ Value ->
+ %% name and pattern existed
%% do not save any new index
Suffix = make_suffix(Value),
Name2 =
@@ -2233,9 +2188,9 @@ maybe_rename_function(Mode,Name,Pattern) ->
end,
lists:concat([Name2,Suffix])
end;
- {inc_disp,_} -> %% this is when
- %% decode_partial_inc_disp/2 is
- %% generated
+ {inc_disp,_} ->
+ %% this is when decode_partial_inc_disp/2 is
+ %% generated
add_generated_function({Name,0,Pattern}),
Name;
_ -> % this if call from add_tobe_refed_func
@@ -2281,23 +2236,12 @@ generated_functions_member(M,Name,[_|T]) ->
generated_functions_member(_,_,[]) ->
false.
-% generated_functions_member(M,Name,L) ->
-% case lists:keymember(Name,1,L) of
-% true ->
-% true;
-% _ ->
-% generated_functions_member1(M,Name,L)
-% end.
-% generated_functions_member1(M,#'Externaltypereference'{module=M,type=Name},L) ->
-% lists:keymember(Name,1,L);
-% generated_functions_member1(_,_,_) -> false.
-
generated_functions_filter(_,Name,L) when is_atom(Name);is_list(Name) ->
lists:filter(fun({N,_,_}) when N==Name -> true;
(_) -> false
end, L);
generated_functions_filter(M,#'Externaltypereference'{module=M,type=Name},L)->
- % remove toptypename from patterns
+ %% remove top typename from patterns
RemoveTType =
fun({N,I,[N,P]}) when N == Name ->
{N,I,P};
@@ -2334,8 +2278,6 @@ set_current_sindex(Index) ->
type_check(A) when is_atom(A) ->
atom;
-%% type_check(I) when is_integer(I) ->
-%% integer;
type_check(L) when is_list(L) ->
Pred = fun(X) when X=<255 ->
false;
@@ -2403,8 +2345,10 @@ format_error({write_error,File,Reason}) ->
io_lib:format("writing output file ~s failed: ~s",
[File,file:format_error(Reason)]).
-is_error(S) when is_record(S, state) ->
- is_error(S#state.options);
+is_error(#state{options=Opts}) ->
+ is_error(Opts);
+is_error(#gen{options=Opts}) ->
+ is_error(Opts);
is_error(O) ->
lists:member(errors, O) orelse is_verbose(O).
@@ -2413,8 +2357,10 @@ is_warning(S) when is_record(S, state) ->
is_warning(O) ->
lists:member(warnings, O) orelse is_verbose(O).
-is_verbose(S) when is_record(S, state) ->
- is_verbose(S#state.options);
+is_verbose(#state{options=Opts}) ->
+ is_verbose(Opts);
+is_verbose(#gen{options=Opts}) ->
+ is_verbose(Opts);
is_verbose(O) ->
lists:member(verbose, O).
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl
index f2c895bfaa..83d12600b7 100644
--- a/lib/asn1/src/asn1ct_check.erl
+++ b/lib/asn1/src/asn1ct_check.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -23,10 +23,9 @@
%% Main Module for ASN.1 compile time functions
-%-compile(export_all).
-export([check/2,storeindb/2,format_error/1]).
-%-define(debug,1).
-include("asn1_records.hrl").
+
%%% The tag-number for universal types
-define(N_BOOLEAN, 1).
-define(N_INTEGER, 2).
@@ -63,7 +62,8 @@
-define(TAG_CONSTRUCTED(Num),
#tag{class='UNIVERSAL',number=Num,type='IMPLICIT',form=32}).
--record(newt,{type=unchanged,tag=unchanged,constraint=unchanged,inlined=no}). % used in check_type to update type and tag
+%% used in check_type to update type and tag
+-record(newt,{type=unchanged,tag=unchanged,constraint=unchanged,inlined=no}).
check(S,{Types,Values,ParameterizedTypes,Classes,Objects,ObjectSets}) ->
%%Predicates used to filter errors
@@ -561,7 +561,6 @@ check_class_fields(S,[F|Fields],Acc) ->
D;
{undefined,user} ->
%% neither of {primitive,bif} or {constructed,bif}
-
{_,D} = get_referenced_type(S,#'Externaltypereference'{module=S#state.mname,type=Type#type.def}),
D;
_ ->
@@ -623,7 +622,6 @@ if_current_checked_type(S,#type{def=Def}) ->
CurrentModule = S#state.mname,
CurrentCheckedName = S#state.tname,
MergedModules = S#state.inputmodules,
- % CurrentCheckedModule = S#state.mname,
case Def of
#'Externaltypereference'{module=CurrentModule,
type=CurrentCheckedName} ->
@@ -656,7 +654,6 @@ check_pobjectset(S,PObjSet) ->
ClassName = #'Externaltypereference'{module=Mod,
type=get_datastr_name(Def)},
{valueset,Set} = ValueSet,
-% ObjectSet = #'ObjectSet'{class={objectclassname,ClassName},
ObjectSet = #'ObjectSet'{class=ClassName,
set=Set},
#pobjectsetdef{pos=Pos,name=Name,args=Args,class=Type#type.def,
@@ -1696,7 +1693,7 @@ check_value(OldS,V) when is_record(V,typedef) ->
%% reference to class
check_value(OldS,V#typedef{typespec=TS#'ObjectSet'{class=Eref}});
#typedef{typespec=HostType} ->
- % an ordinary value set with a type in #typedef.typespec
+ %% an ordinary value set with a type in #typedef.typespec
ValueSet0 = TS#'ObjectSet'.set,
Constr = check_constraints(OldS, HostType, [ValueSet0]),
Type = check_type(OldS,TSDef,TSDef#typedef.typespec),
@@ -2239,12 +2236,18 @@ normalized_record(SorS,S,Value,Components,NameList) ->
case is_record_normalized(S,NewName,Value,length(Components)) of
true ->
Value;
- _ ->
+ false ->
NoComps = length(Components),
ListOfVals = normalize_seq_or_set(SorS,S,Value,Components,NameList,[]),
- NoComps = length(ListOfVals), %% Assert
- list_to_tuple([NewName|ListOfVals])
+ NoComps = length(ListOfVals), %Assertion.
+ case use_maps(S) of
+ false ->
+ list_to_tuple([NewName|ListOfVals]);
+ true ->
+ create_map_value(Components, ListOfVals)
+ end
end.
+
is_record_normalized(S,Name,V = #'Externalvaluereference'{},NumComps) ->
case get_referenced_type(S,V) of
{_M,#valuedef{type=_T1,value=V2}} ->
@@ -2253,9 +2256,20 @@ is_record_normalized(S,Name,V = #'Externalvaluereference'{},NumComps) ->
end;
is_record_normalized(_S,Name,Value,NumComps) when is_tuple(Value) ->
(tuple_size(Value) =:= (NumComps + 1)) andalso (element(1, Value) =:= Name);
+is_record_normalized(_S, _Name, Value, _NumComps) when is_map(Value) ->
+ true;
is_record_normalized(_,_,_,_) ->
false.
+use_maps(#state{options=Opts}) ->
+ lists:member(maps, Opts).
+
+create_map_value(Components, ListOfVals) ->
+ Zipped = lists:zip(Components, ListOfVals),
+ L = [{Name,V} || {#'ComponentType'{name=Name},V} <- Zipped,
+ V =/= asn1_NOVALUE],
+ maps:from_list(L).
+
normalize_seq_or_set(SorS, S,
[{#seqtag{val=Cname},V}|Vs],
[#'ComponentType'{name=Cname,typespec=TS}|Cs],
@@ -2364,15 +2378,6 @@ normalize_s_of(SorS,S,Value,Type,NameList)
%% normalize_restrictedstring handles all format of restricted strings.
-%% tuple case
-% normalize_restrictedstring(_S,[Int1,Int2],_) when is_integer(Int1),is_integer(Int2) ->
-% {Int1,Int2};
-% %% quadruple case
-% normalize_restrictedstring(_S,[Int1,Int2,Int3,Int4],_) when is_integer(Int1),
-% is_integer(Int2),
-% is_integer(Int3),
-% is_integer(Int4) ->
-% {Int1,Int2,Int3,Int4};
%% character string list case
normalize_restrictedstring(S,[H|T],CType) when is_list(H);is_tuple(H) ->
[normalize_restrictedstring(S,H,CType)|normalize_restrictedstring(S,T,CType)];
@@ -2474,7 +2479,7 @@ check_ptype(S,Type,Ts) when is_record(Ts,type) ->
Ts#type{def=TDef}
end,
Ts2;
-%parameterized class
+%% parameterized class
check_ptype(_S,_PTDef,Ts) when is_record(Ts,objectclass) ->
throw({asn1_param_class,Ts}).
@@ -2489,8 +2494,6 @@ check_formal_parameter(_, #'Externaltypereference'{}) ->
check_formal_parameter(S, #'Externalvaluereference'{value=Name}) ->
asn1_error(S, {illegal_typereference,Name}).
-% check_type(S,Type,ObjSpec={{objectclassname,_},_}) ->
- % check_class(S,ObjSpec);
check_type(_S,Type,Ts) when is_record(Type,typedef),
(Type#typedef.checked==true) ->
Ts;
@@ -2589,7 +2592,6 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
constraint = NewC};
_ ->
%% Here we only expand the tags and keep the ext ref.
-
NewExt = ExtRef#'Externaltypereference'{module=merged_mod(S,RefMod,Ext)},
TempNewDef#newt{
type = check_externaltypereference(S,NewExt),
@@ -2732,7 +2734,6 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
case TopName of
[] ->
[get_datastr_name(Type)];
-% [Type#typedef.name];
_ ->
TopName
end,
@@ -2756,7 +2757,6 @@ check_type(S=#state{recordtopname=TopName},Type,Ts) when is_record(Ts,type) ->
case TopName of
[] ->
[get_datastr_name(Type)];
-% [Type#typedef.name];
_ ->
TopName
end,
@@ -2881,8 +2881,6 @@ tablecinf_choose(#'SEQUENCE'{tablecinf=TCI}) ->
get_innertag(_S,#'ObjectClassFieldType'{type=Type}) ->
case Type of
-% #type{tag=Tag} -> Tag;
-% {fixedtypevaluefield,_,#type{tag=[]}=T} -> get_taglist(S,T);
{fixedtypevaluefield,_,#type{tag=Tag}} -> Tag;
{TypeFieldName,_} when is_atom(TypeFieldName) -> [];
_ -> []
@@ -3737,14 +3735,8 @@ check_reference(S,#'Externaltypereference'{pos=Pos,module=Emod,type=Name}) ->
{ok,Imodule} ->
check_imported(S,Imodule,Name),
#'Externaltypereference'{module=Imodule,type=Name};
-%% case check_imported(S,Imodule,Name) of
-%% ok ->
-%% #'Externaltypereference'{module=Imodule,type=Name};
-%% Err ->
-%% Err
-%% end;
_ ->
- %may be a renamed type in multi file compiling!
+ %% may be a renamed type in multi file compiling!
{M,T}=get_renamed_reference(S,Name,Emod),
NewName = asn1ct:get_name_of_def(T),
NewPos = asn1ct:get_pos_of_def(T),
@@ -4153,7 +4145,6 @@ iof_associated_type(S,[]) ->
def=AssociateSeq}},
asn1_db:dbput(S#state.mname,'INSTANCE OF',TypeDef),
instance_of_decl(S#state.mname);
-%% put(instance_of,{generate,S#state.mname});
_ ->
instance_of_decl(S#state.mname),
ok
@@ -4182,17 +4173,15 @@ iof_associated_type1(S,C) ->
ObjectIdentifier =
#'ObjectClassFieldType'{classname=TypeIdentifierRef,
class=[],
-%% fieldname=[{valuefieldreference,id}],
fieldname={id,[]},
type={fixedtypevaluefield,id,
#type{def='OBJECT IDENTIFIER'}}},
Typefield =
#'ObjectClassFieldType'{classname=TypeIdentifierRef,
class=[],
-%% fieldname=[{typefieldreference,'Type'}],
fieldname={'Type',[]},
type=Typefield_type},
- IOFComponents =
+ IOFComponents0 =
[#'ComponentType'{name='type-id',
typespec=#type{tag=C1TypeTag,
def=ObjectIdentifier,
@@ -4209,6 +4198,7 @@ iof_associated_type1(S,C) ->
tablecinf=Comp2tablecinf},
prop=mandatory,
tags=[{'CONTEXT',0}]}],
+ IOFComponents = textual_order(IOFComponents0),
#'SEQUENCE'{tablecinf=TableCInf,
components=simplify_comps(IOFComponents)}.
@@ -4342,11 +4332,11 @@ check_boolean(_S,_Constr) ->
check_octetstring(_S,_Constr) ->
ok.
-% check all aspects of a SEQUENCE
-% - that all component names are unique
-% - that all TAGS are ok (when TAG default is applied)
-% - that each component is of a valid type
-% - that the extension marks are valid
+%% check all aspects of a SEQUENCE
+%% - that all component names are unique
+%% - that all TAGS are ok (when TAG default is applied)
+%% - that each component is of a valid type
+%% - that the extension marks are valid
check_sequence(S,Type,Comps) ->
Components = expand_components(S,Comps),
@@ -4687,11 +4677,11 @@ check_objectidentifier(_S,_Constr) ->
check_relative_oid(_S,_Constr) ->
ok.
-% check all aspects of a CHOICE
-% - that all alternative names are unique
-% - that all TAGS are ok (when TAG default is applied)
-% - that each alternative is of a valid type
-% - that the extension marks are valid
+%% check all aspects of a CHOICE
+%% - that all alternative names are unique
+%% - that all TAGS are ok (when TAG default is applied)
+%% - that each alternative is of a valid type
+%% - that the extension marks are valid
check_choice(S,Type,Components) when is_list(Components) ->
Components1 = [C||C = #'ComponentType'{} <- Components],
case check_unique(Components1,#'ComponentType'.name) of
@@ -4930,7 +4920,7 @@ componentrelation_leadingattr(S,CompList) ->
%%FIXME expand_ExtAddGroups([C#'ExtensionAdditionGroup'{components=ExtAdds}|T],
%% CurrPos,PosAcc,CompAcc) ->
-%% expand_ExtAddGroups(T,CurrPos+ L = lenght(ExtAdds),[{CurrPos,L}|PosAcc],ExtAdds++CompAcc);
+%% expand_ExtAddGroups(T,CurrPos+ L = length(ExtAdds),[{CurrPos,L}|PosAcc],ExtAdds++CompAcc);
%% expand_ExtAddGroups([C|T],CurrPos,PosAcc,CompAcc) ->
%% expand_ExtAddGroups(T,CurrPos+ 1,PosAcc,[C|CompAcc]);
%% expand_ExtAddGroups([],_CurrPos,PosAcc,CompAcc) ->
@@ -5045,12 +5035,12 @@ remove_doubles1(El,L) ->
%% referred to in the ObjectClassFieldType, and the name of the unique
%% field of the class of the ObjectClassFieldType.
%%
-% %% The level information outermost/innermost must be kept. There are
-% %% at least two possibilities to cover here for an outermost case: 1)
-% %% Both the simple table and the component relation have a common path
-% %% at least one step below the outermost level, i.e. the leading
-% %% information shall be on a sub level. 2) They don't have any common
-% %% path.
+%% The level information outermost/innermost must be kept. There are
+%% at least two possibilities to cover here for an outermost case: 1)
+%% Both the simple table and the component relation have a common path
+%% at least one step below the outermost level, i.e. the leading
+%% information shall be on a sub level. 2) They don't have any common
+%% path.
get_simple_table_info(S, Cs, AtLists) ->
[get_simple_table_info1(S, Cs, AtList, []) || AtList <- AtLists].
@@ -5091,10 +5081,10 @@ simple_table_info(S,#'ObjectClassFieldType'{classname=ClRef,
{_FirstFieldName,FieldNames} ->
lists:last(FieldNames)
end,
- %%ObjectClassFieldName is the last element in the dotted
- %%list of the ObjectClassFieldType. The last element may
- %%be of another class, that is referenced from the class
- %%of the ObjectClassFieldType
+ %% ObjectClassFieldName is the last element in the dotted list of
+ %% the ObjectClassFieldType. The last element may be of another
+ %% class, that is referenced from the class of the
+ %% ObjectClassFieldType
ClassDef =
case ObjectClass of
[] ->
@@ -5110,7 +5100,7 @@ simple_table_info(S,#'ObjectClassFieldType'{classname=ClRef,
%% the "name path" in the at-list to the component relation constraint
%% that must refer to a simple table constraint. The list is empty if
%% no component relation constraints were found.
-%%
+%%
%% NamePath has the names of all components that are followed from the
%% beginning of the search. CNames holds the names of all components
%% of the start level, this info is used if an outermost at-notation
@@ -5123,6 +5113,7 @@ any_component_relation(S,[#'ComponentType'{name=CName,typespec=Type}|Cs],CNames,
%% whether this constraint is relevant for the level
%% where the search started
AtNot = extract_at_notation(AtNotation),
+
%% evaluate_atpath returns the relative path to the
%% simple table constraint from where the component
%% relation is found.
@@ -5228,12 +5219,10 @@ get_components(_,#'SET'{components=Cs}) ->
tuple2complist(Cs);
get_components(_,{'CHOICE',Cs}) ->
tuple2complist(Cs);
-%do not step in inlined structures
+%%do not step in inlined structures
get_components(any,{'SEQUENCE OF',T = #type{def=_Def,inlined=no}}) ->
-% get_components(any,Def);
T;
get_components(any,{'SET OF',T = #type{def=_Def,inlined=no}}) ->
-% get_components(any,Def);
T;
get_components(_,_) ->
[].
@@ -5263,15 +5252,12 @@ extract_at_notation([{Level,ValueRefs}]) ->
componentrelation1(S,C = #type{def=Def,constraint=Constraint,tablecinf=TCI},
Path) ->
Ret =
-% case Constraint of
-% [{componentrelation,{_,_,ObjectSet},AtList}|_Rest] ->
case lists:keyfind(componentrelation, 1, Constraint) of
{_,{_,_,ObjectSet},AtList} ->
[{_,AL=[#'Externalvaluereference'{}|_R1]}|_R2] = AtList,
%% Note: if Path is longer than one,i.e. it is within
%% an inner type of the actual level, then the only
%% relevant at-list is of "outermost" type.
-%% #'ObjectClassFieldType'{class=ClassDef} = Def,
ClassDef = get_ObjectClassFieldType_classdef(S,Def),
AtPath =
lists:map(fun(#'Externalvaluereference'{value=V})->V end,
@@ -5357,7 +5343,6 @@ innertype_comprel1(S,T = #type{def=Def,constraint=Cons,tablecinf=TCI},Path) ->
%% relevent here.
[{_,AL=[#'Externalvaluereference'{value=_Attr}|_R1]}|_R2]
= AtList,
-%% #'ObjectClassFieldType'{class=ClassDef} = Def,
ClassDef = get_ObjectClassFieldType_classdef(S,Def),
AtPath =
lists:map(fun(#'Externalvaluereference'{value=V})->V end,
@@ -5426,7 +5411,7 @@ leading_attr_index1(S,[C|Cs],Arg={ObjectSet,_,CDef,P},
value_match(S,C,Name,SubAttr) ->
value_match(S,C,Name,SubAttr,[]). % C has name Name
value_match(_S,#'ComponentType'{},_Name,[],Acc) ->
- Acc;% do not reverse, indexes in reverse order
+ Acc; % do not reverse, indexes in reverse order
value_match(S,#'ComponentType'{typespec=Type},Name,[At|Ats],Acc) ->
InnerType = asn1ct_gen:get_inner(Type#type.def),
Components =
@@ -5496,8 +5481,6 @@ get_tableconstraint_info(S,Type,[C=#'ComponentType'{typespec=CheckedTs}|Cs],Acc)
CheckedTs#type{
def=NewOCFT
}};
-% constraint=[{tableconstraint_info,
-% FieldRef}]}};
{'SEQUENCE OF',SOType} when is_record(SOType,type),
(element(1,SOType#type.def)=='CHOICE') ->
CTypeList = element(2,SOType#type.def),
@@ -5600,51 +5583,6 @@ get_taglist1(S,[_H|Rest]) -> % skip EXTENSIONMARK
get_taglist1(_S,[]) ->
[].
-%% def_to_tag(S,Def) ->
-%% case asn1ct_gen:def_to_tag(Def) of
-%% {'UNIVERSAL',T} ->
-%% case asn1ct_gen:prim_bif(T) of
-%% true ->
-%% ?TAG_PRIMITIVE(tag_number(T));
-%% _ ->
-%% ?TAG_CONSTRUCTED(tag_number(T))
-%% end;
-%% _ -> []
-%% end.
-%% tag_number('BOOLEAN') -> 1;
-%% tag_number('INTEGER') -> 2;
-%% tag_number('BIT STRING') -> 3;
-%% tag_number('OCTET STRING') -> 4;
-%% tag_number('NULL') -> 5;
-%% tag_number('OBJECT IDENTIFIER') -> 6;
-%% tag_number('ObjectDescriptor') -> 7;
-%% tag_number('EXTERNAL') -> 8;
-%% tag_number('INSTANCE OF') -> 8;
-%% tag_number('REAL') -> 9;
-%% tag_number('ENUMERATED') -> 10;
-%% tag_number('EMBEDDED PDV') -> 11;
-%% tag_number('UTF8String') -> 12;
-%% %%tag_number('RELATIVE-OID') -> 13;
-%% tag_number('SEQUENCE') -> 16;
-%% tag_number('SEQUENCE OF') -> 16;
-%% tag_number('SET') -> 17;
-%% tag_number('SET OF') -> 17;
-%% tag_number('NumericString') -> 18;
-%% tag_number('PrintableString') -> 19;
-%% tag_number('TeletexString') -> 20;
-%% %%tag_number('T61String') -> 20;
-%% tag_number('VideotexString') -> 21;
-%% tag_number('IA5String') -> 22;
-%% tag_number('UTCTime') -> 23;
-%% tag_number('GeneralizedTime') -> 24;
-%% tag_number('GraphicString') -> 25;
-%% tag_number('VisibleString') -> 26;
-%% %%tag_number('ISO646String') -> 26;
-%% tag_number('GeneralString') -> 27;
-%% tag_number('UniversalString') -> 28;
-%% tag_number('CHARACTER STRING') -> 29;
-%% tag_number('BMPString') -> 30.
-
merge_tags(T1, T2) when is_list(T2) ->
merge_tags2(T1 ++ T2, []);
merge_tags(T1, T2) ->
@@ -5673,7 +5611,8 @@ storeindb(S0, #module{name=ModName,typeorval=TVlist0}=M) ->
storeindb_1(S, #module{name=ModName}=M, TVlist0, TVlist) ->
NewM = M#module{typeorval=findtypes_and_values(TVlist0)},
- asn1_db:dbnew(ModName, S#state.erule),
+ Maps = lists:member(maps, S#state.options),
+ asn1_db:dbnew(ModName, S#state.erule, Maps),
asn1_db:dbput(ModName, 'MODULE', NewM),
asn1_db:dbput(ModName, TVlist),
include_default_class(S, NewM#module.name),
diff --git a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
index 325bea5879..35cf9691c7 100644
--- a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,17 +32,17 @@
-include("asn1_records.hrl").
--import(asn1ct_gen, [emit/1,demit/1,get_record_name_prefix/0]).
+-import(asn1ct_gen, [emit/1,get_record_name_prefix/1]).
-define(ASN1CT_GEN_BER,asn1ct_gen_ber_bin_v2).
-% the encoding of class of tag bits 8 and 7
+%% the encoding of class of tag bits 8 and 7
-define(UNIVERSAL, 0).
-define(APPLICATION, 16#40).
-define(CONTEXT, 16#80).
-define(PRIVATE, 16#C0).
-% primitive or constructed encoding % bit 6
+%% primitive or constructed encoding % bit 6
-define(PRIMITIVE, 0).
-define(CONSTRUCTED, 2#00100000).
@@ -57,7 +57,7 @@
%%===============================================================================
%%===============================================================================
-gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
+gen_encode_sequence(Gen, Typename, #type{}=D) ->
asn1ct_name:start(),
asn1ct_name:new(term),
asn1ct_name:new(bytes),
@@ -67,8 +67,12 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
ValName =
case Typename of
['EXTERNAL'] ->
+ Tr = case Gen of
+ #gen{pack=record} -> transform_to_EXTERNAL1990;
+ #gen{pack=map} -> transform_to_EXTERNAL1990_maps
+ end,
emit([indent(4),"NewVal = ",
- {call,ext,transform_to_EXTERNAL1990,["Val"]},
+ {call,ext,Tr,["Val"]},
com,nl]),
"NewVal";
_ ->
@@ -90,25 +94,15 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
{Rl,El} -> Rl ++ El;
_ -> CompList
end,
-
-%% don't match recordname for now, because of compatibility reasons
-%% emit(["{'",asn1ct_gen:list2rname(Typename),"'"]),
- emit(["{_"]),
- case length(CompList1) of
- 0 ->
- true;
- CompListLen ->
- emit([","]),
- mkcindexlist([Tc || Tc <- lists:seq(1,CompListLen)])
- end,
- emit(["} = ",ValName,",",nl]),
+
+ enc_match_input(Gen, ValName, CompList1),
+
EncObj =
case TableConsInfo of
#simpletableattributes{usedclassfield=Used,
uniqueclassfield=Unique} when Used /= Unique ->
false;
%% ObjectSet, name of the object set in constraints
- %%
#simpletableattributes{objectsetname=ObjectSetRef,
c_name=AttrN,
c_index=N,
@@ -125,7 +119,7 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
emit([ObjectEncode," = ",nl,
" ",{asis,ObjSetMod},":'getenc_",ObjSetName,
"'("]),
- ValueMatch = value_match(ValueIndex,
+ ValueMatch = value_match(Gen, ValueIndex,
lists:concat(["Cindex",N])),
emit([indent(35),ValueMatch,"),",nl]),
{AttrN,ObjectEncode};
@@ -144,7 +138,7 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
end
end,
- gen_enc_sequence_call(Erules,Typename,CompList1,1,Ext,EncObj),
+ gen_enc_sequence_call(Gen, Typename, CompList1, 1, Ext, EncObj),
emit([nl," BytesSoFar = "]),
case SeqOrSet of
@@ -168,7 +162,36 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
call(encode_tags, ["TagIn","BytesSoFar","LenSoFar"]),
emit([".",nl]).
-gen_decode_sequence(Erules,Typename,D) when is_record(D,type) ->
+enc_match_input(#gen{pack=record}, ValName, CompList) ->
+ Len = length(CompList),
+ Vars = [lists:concat(["Cindex",N]) || N <- lists:seq(1, Len)],
+ RecordName = "_",
+ emit(["{",lists:join(",", [RecordName|Vars]),"} = ",ValName,com,nl]);
+enc_match_input(#gen{pack=map}, ValName, CompList) ->
+ Len = length(CompList),
+ Vars = [lists:concat(["Cindex",N]) || N <- lists:seq(1, Len)],
+ Zipped = lists:zip(CompList, Vars),
+ M = [[{asis,Name},":=",Var] ||
+ {#'ComponentType'{prop=mandatory,name=Name},Var} <- Zipped],
+ case M of
+ [] ->
+ ok;
+ [_|_] ->
+ emit(["#{",lists:join(",", M),"} = ",ValName,com,nl])
+ end,
+ Os0 = [{Name,Var} ||
+ {#'ComponentType'{prop=Prop,name=Name},Var} <- Zipped,
+ Prop =/= mandatory],
+ F = fun({Name,Var}) ->
+ [Var," = case ",ValName," of\n"
+ " #{",{asis,Name},":=",Var,"_0} -> ",
+ Var,"_0;\n"
+ " _ -> ",atom_to_list(?MISSING_IN_MAP),"\n"
+ "end"]
+ end,
+ emit(lists:join(",\n", [F(E) || E <- Os0]++[[]])).
+
+gen_decode_sequence(Gen, Typename, #type{}=D) ->
asn1ct_name:start(),
asn1ct_name:new(tag),
#'SEQUENCE'{tablecinf=TableConsInfo,components=CList0} = D#type.def,
@@ -206,7 +229,6 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) ->
usedclassfield=UniqueFieldName,
uniqueclassfield=UniqueFieldName,
valueindex=ValIndex} ->
-% {ObjectSetRef,AttrN,_N,UniqueFieldName} ->%% N is index of attribute that determines constraint
F = fun(#'ComponentType'{typespec=CT})->
case {asn1ct_gen:get_constraint(CT#type.constraint,componentrelation),CT#type.tablecinf} of
{no,[{objfun,_}|_]} -> true;
@@ -225,15 +247,20 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) ->
_ ->
{false,false}
end,
- RecordName = lists:concat([get_record_name_prefix(),
- asn1ct_gen:list2rname(Typename)]),
- case gen_dec_sequence_call(Erules,Typename,CompList2,Ext,DecObjInf) of
- no_terms -> % an empty sequence
- emit([nl,nl]),
- demit(["Result = "]), %dbg
- %% return value as record
+ RecordName0 = lists:concat([get_record_name_prefix(Gen),
+ asn1ct_gen:list2rname(Typename)]),
+ RecordName = list_to_atom(RecordName0),
+ case gen_dec_sequence_call(Gen, Typename, CompList2, Ext, DecObjInf) of
+ no_terms -> % an empty sequence
asn1ct_name:new(rb),
- emit([" {'",RecordName,"'}.",nl,nl]);
+ case Gen of
+ #gen{pack=record} ->
+ emit([nl,nl,
+ " {'",RecordName,"'}.",nl,nl]);
+ #gen{pack=map} ->
+ emit([nl,nl,
+ " #{}.",nl,nl])
+ end;
{LeadingAttrTerm,PostponedDecArgs} ->
emit([nl]),
case {LeadingAttrTerm,PostponedDecArgs} of
@@ -243,19 +270,19 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) ->
ok;
{[{ObjSetRef,LeadingAttr,Term}],PostponedDecArgs} ->
DecObj = asn1ct_gen:un_hyphen_var(lists:concat(['DecObj',LeadingAttr,Term])),
- ValueMatch = value_match(ValueIndex,Term),
+ ValueMatch = value_match(Gen, ValueIndex,Term),
{ObjSetMod,ObjSetName} = ObjSetRef,
emit([DecObj," =",nl,
" ",{asis,ObjSetMod},":'getdec_",ObjSetName,"'(",
ValueMatch,"),",nl]),
gen_dec_postponed_decs(DecObj,PostponedDecArgs)
end,
- demit(["Result = "]), %dbg
%% return value as record
case Ext of
{ext,_,_} ->
emit(["case ",{prev,tlv}," of [] -> true; _ -> true end, % ... extra fields skipped",nl]);
- _ -> % noext | extensible
+ _ ->
+ %% noext | extensible
emit(["case ",{prev,tlv}," of",nl,
"[] -> true;",
"_ -> exit({error,{asn1, {unexpected,",{prev,tlv},
@@ -263,22 +290,64 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) ->
"end,",nl])
end,
asn1ct_name:new(rb),
- case Typename of
- ['EXTERNAL'] ->
- emit([" OldFormat={'",RecordName,
- "', "]),
- mkvlist(asn1ct_name:all(term)),
- emit(["},",nl]),
- emit([" ",
- {call,ext,transform_to_EXTERNAL1994,
- ["OldFormat"]},".",nl]);
- _ ->
- emit([" {'",RecordName,"', "]),
- mkvlist(asn1ct_name:all(term)),
- emit(["}.",nl,nl])
- end
+ gen_dec_pack(Gen, RecordName, Typename, CompList),
+ emit([".",nl])
end.
+gen_dec_pack(Gen, RecordName, Typename, CompList) ->
+ case Typename of
+ ['EXTERNAL'] ->
+ dec_external(Gen, RecordName);
+ _ ->
+ asn1ct_name:new(res),
+ gen_dec_do_pack(Gen, RecordName, CompList),
+ emit([com,nl,
+ {curr,res}])
+ end.
+
+dec_external(#gen{pack=record}, RecordName) ->
+ All = [{var,Term} || Term <- asn1ct_name:all(term)],
+ Record = [{asis,RecordName}|All],
+ emit(["OldFormat={",lists:join(",", Record),"},",nl,
+ {call,ext,transform_to_EXTERNAL1994,
+ ["OldFormat"]}]);
+dec_external(#gen{pack=map}, _RecordName) ->
+ Vars = asn1ct_name:all(term),
+ Names = ['direct-reference','indirect-reference',
+ 'data-value-descriptor',encoding],
+ Zipped = lists:zip(Names, Vars),
+ MapInit = lists:join(",", [["'",N,"'=>",{var,V}] || {N,V} <- Zipped]),
+ emit(["OldFormat = #{",MapInit,"}",com,nl,
+ "ASN11994Format =",nl,
+ {call,ext,transform_to_EXTERNAL1994_maps,
+ ["OldFormat"]}]).
+
+gen_dec_do_pack(#gen{pack=record}, RecordName, _CompList) ->
+ All = asn1ct_name:all(term),
+ L = [{asis,RecordName}|[{var,Var} || Var <- All]],
+ emit([{curr,res}," = {",lists:join(",", L),"}"]);
+gen_dec_do_pack(#gen{pack=map}, _, CompList) ->
+ Zipped = lists:zip(CompList, asn1ct_name:all(term)),
+ PF = fun({#'ComponentType'{prop='OPTIONAL'},_}) -> false;
+ ({_,_}) -> true
+ end,
+ {Mandatory,Optional} = lists:partition(PF, Zipped),
+ L = [[{asis,Name},"=>",{var,Var}] ||
+ {#'ComponentType'{name=Name},Var} <- Mandatory],
+ emit([{curr,res}," = #{",lists:join(",", L),"}"]),
+ gen_dec_map_optional(Optional).
+
+gen_dec_map_optional([{#'ComponentType'{name=Name},Var}|T]) ->
+ asn1ct_name:new(res),
+ emit([com,nl,
+ {curr,res}," = case ",{var,Var}," of",nl,
+ " asn1_NOVALUE -> ",{prev,res},";",nl,
+ " _ -> ",{prev,res},"#{",{asis,Name},"=>",{var,Var},"}",nl,
+ "end"]),
+ gen_dec_map_optional(T);
+gen_dec_map_optional([]) ->
+ ok.
+
gen_dec_postponed_decs(_,[]) ->
emit(nl);
gen_dec_postponed_decs(DecObj,[{_Cname,{FirstPFN,PFNList},Term,
@@ -327,7 +396,7 @@ emit_opt_or_mand_check(Value,TmpTerm) ->
gen_encode_set(Erules,Typename,D) when is_record(D,type) ->
gen_encode_sequence(Erules,Typename,D).
-gen_decode_set(Erules,Typename,D) when is_record(D,type) ->
+gen_decode_set(Gen, Typename, #type{}=D) ->
asn1ct_name:start(),
%% asn1ct_name:new(term),
asn1ct_name:new(tag),
@@ -360,7 +429,6 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) ->
{DecObjInf,ValueIndex} =
case TableConsInfo of
-%% {ObjectSetRef,AttrN,_N,UniqueFieldName} ->%% N is index of attribute that determines constraint
#simpletableattributes{objectsetname=ObjectSetRef,
c_name=AttrN,
usedclassfield=UniqueFieldName,
@@ -375,7 +443,8 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) ->
end
end,
case lists:any(F,CompList) of
- true -> % when component relation constraint establish
+ true ->
+ %% when component relation constraint establish
%% relation from a component to another components
%% subtype component
{{AttrN,{deep,ObjectSetRef,UniqueFieldName,ValIndex}},
@@ -393,7 +462,7 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) ->
_ ->
emit(["SetFun = fun(FunTlv) ->", nl]),
emit(["case FunTlv of ",nl]),
- NextNum = gen_dec_set_cases(Erules,Typename,CompList,1),
+ NextNum = gen_dec_set_cases(Gen, Typename, CompList, 1),
emit([indent(6), {curr,else}," -> ",nl,
indent(9),"{",NextNum,", ",{curr,else},"}",nl]),
emit([indent(3),"end",nl]),
@@ -405,14 +474,17 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) ->
asn1ct_name:new(tlv)
end,
- RecordName = lists:concat([get_record_name_prefix(),
- asn1ct_gen:list2rname(Typename)]),
- case gen_dec_sequence_call(Erules,Typename,CompList,Ext,DecObjInf) of
- no_terms -> % an empty sequence
- emit([nl,nl]),
- demit(["Result = "]), %dbg
- %% return value as record
- emit([" {'",RecordName,"'}.",nl]);
+ RecordName0 = lists:concat([get_record_name_prefix(Gen),
+ asn1ct_gen:list2rname(Typename)]),
+ RecordName = list_to_atom(RecordName0),
+ case gen_dec_sequence_call(Gen, Typename, CompList, Ext, DecObjInf) of
+ no_terms -> % an empty SET
+ case Gen of
+ #gen{pack=record} ->
+ emit([nl,nl," {'",RecordName,"'}.",nl,nl]);
+ #gen{pack=map} ->
+ emit([nl,nl," #{}.",nl,nl])
+ end;
{LeadingAttrTerm,PostponedDecArgs} ->
emit([nl]),
case {LeadingAttrTerm,PostponedDecArgs} of
@@ -422,14 +494,13 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) ->
ok;
{[{ObjSetRef,LeadingAttr,Term}],PostponedDecArgs} ->
DecObj = asn1ct_gen:un_hyphen_var(lists:concat(['DecObj',LeadingAttr,Term])),
- ValueMatch = value_match(ValueIndex,Term),
+ ValueMatch = value_match(Gen, ValueIndex, Term),
{ObjSetMod,ObjSetName} = ObjSetRef,
emit([DecObj," =",nl,
" ",{asis,ObjSetMod},":'getdec_",ObjSetName,"'(",
ValueMatch,"),",nl]),
gen_dec_postponed_decs(DecObj,PostponedDecArgs)
end,
- demit(["Result = "]), %dbg
%% return value as record
case Ext of
Extnsn when Extnsn =/= noext ->
@@ -441,9 +512,8 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) ->
"}}}) % extra fields not allowed",nl,
"end,",nl])
end,
- emit([" {'",RecordName,"', "]),
- mkvlist(asn1ct_name:all(term)),
- emit(["}.",nl])
+ gen_dec_pack(Gen, RecordName, Typename, CompList),
+ emit([".",nl])
end.
@@ -504,10 +574,8 @@ gen_decode_sof(Erules,TypeName,_InnerTypeName,D) when is_record(D,type) ->
emit([" || ",{curr,v}," <- ",{curr,tlv},"].",nl,nl,nl]).
-gen_encode_sof_components(Erules,Typename,SeqOrSetOf,Cont)
- when is_record(Cont,type)->
-
- {Objfun,Objfun_novar,EncObj} =
+gen_encode_sof_components(Gen, Typename, SeqOrSetOf, #type{}=Cont) ->
+ {Objfun,Objfun_novar,EncObj} =
case Cont#type.tablecinf of
[{objfun,_}|_R] ->
{", ObjFun",", _",{no_attr,"ObjFun"}};
@@ -517,20 +585,19 @@ gen_encode_sof_components(Erules,Typename,SeqOrSetOf,Cont)
emit(["'enc_",asn1ct_gen:list2name(Typename),
"_components'([]",Objfun_novar,", AccBytes, AccLen) -> ",nl]),
- case catch lists:member(der,get(encoding_options)) of
- true when SeqOrSetOf=='SET OF'->
+ case {Gen,SeqOrSetOf} of
+ {#gen{der=true},'SET OF'} ->
asn1ct_func:need({ber,dynamicsort_SETOF,1}),
emit([indent(3),
"{dynamicsort_SETOF(AccBytes),AccLen};",nl,nl]);
- _ ->
+ {_,_} ->
emit([indent(3),"{lists:reverse(AccBytes),AccLen};",nl,nl])
end,
emit(["'enc_",asn1ct_gen:list2name(Typename),
"_components'([H|T]",Objfun,",AccBytes, AccLen) ->",nl]),
TypeNameSuffix = asn1ct_gen:constructed_suffix(SeqOrSetOf,Cont#type.def),
- gen_enc_line(Erules,Typename,TypeNameSuffix,Cont,"H",3,
-% mandatory,"{EncBytes,EncLen} = ",EncObj),
- mandatory,EncObj),
+ gen_enc_line(Gen, Typename, TypeNameSuffix, Cont, "H", 3,
+ mandatory, EncObj),
emit([",",nl]),
emit([indent(3),"'enc_",asn1ct_gen:list2name(Typename),
"_components'(T",Objfun,","]),
@@ -652,7 +719,7 @@ gen_dec_sequence_call2(Erules,TopType,{Root1,EList,Root2},_Ext,DecObjInf) ->
length(Root1)+length(EList),noext,
DecObjInf,LA,ArgsAcc).
-%% returns a list of tags of the elements in the component (second
+%% Returns a list of tags of the elements in the component (second
%% root) list up to and including the first mandatory tag. See 24.6 in
%% X.680 (7/2002)
get_root2_taglist([],Acc) ->
@@ -741,8 +808,6 @@ gen_dec_set_cases(Erules,TopType,[Comp|RestComps],Pos) ->
[FirstTag|_] ->
[(?ASN1CT_GEN_BER:decode_class(FirstTag#tag.class) bsl 10) + FirstTag#tag.number]
end,
-% emit([indent(6),"%Tags: ",Tags,nl]),
-% emit([indent(6),"%Type#type.tag: ",Type#type.tag,nl]),
CaseFun = fun(TagList=[H|T],Fun,N) ->
Semicolon = case TagList of
[_Tag1,_|_] -> [";",nl];
@@ -757,7 +822,6 @@ gen_dec_set_cases(Erules,TopType,[Comp|RestComps],Pos) ->
emit([";",nl])
end,
CaseFun(Tags,CaseFun,0),
-%% emit([";",nl]),
gen_dec_set_cases(Erules,TopType,RestComps,Pos+1).
@@ -937,14 +1001,6 @@ gen_enc_line(Erules,TopType,Cname,
["{",{curr,encBytes},",",{curr,encLen},"} = "],
EncObj)
end;
-% gen_enc_line(Erules,TopType,Cname,
-% Type=#type{constraint=[{componentrelation,_,_}],
-% def=#'ObjectClassFieldType'{type={typefield,_}}},
-% Element,Indent,OptOrMand=mandatory,EncObj)
-% when is_list(Element) ->
-% asn1ct_name:new(tmpBytes),
-% gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,
-% ["{",{curr,tmpBytes},",_} = "],EncObj);
gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,EncObj)
when is_list(Element) ->
gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,
@@ -965,37 +1021,30 @@ gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,Assign,EncObj)
gen_optormand_case(OptOrMand, Erules, TopType, Cname, Type, Element),
case {Type,asn1ct_gen:get_constraint(Type#type.constraint,
componentrelation)} of
-% #type{constraint=[{tableconstraint_info,RefedFieldName}],
-% def={typefield,_}} ->
{#type{def=#'ObjectClassFieldType'{type={typefield,_},
fieldname=RefedFieldName}},
{componentrelation,_,_}} ->
{_LeadingAttrName,Fun} = EncObj,
- case RefedFieldName of
- {Name,RestFieldNames} when is_atom(Name) ->
- case OptOrMand of
- mandatory -> ok;
- _ ->
-% emit(["{",{curr,tmpBytes},",",{curr,tmpLen},
- emit(["{",{curr,tmpBytes},",_ } = "])
-% "} = "])
- end,
- emit([Fun,"(",{asis,Name},", ",Element,", ",
- {asis,RestFieldNames},"),",nl]),
- emit(IndDeep),
- case OptOrMand of
- mandatory ->
- emit(["{",{curr,encBytes},",",{curr,encLen},
- "} = ",
- {call,ber,encode_open_type,
- [{curr,tmpBytes},{asis,Tag}]},nl]);
- _ ->
- emit([{call,ber,encode_open_type,
- [{curr,tmpBytes},{asis,Tag}]}])
- end;
- Err ->
- throw({asn1,{'internal error',Err}})
- end;
+ {Name,RestFieldNames} = RefedFieldName,
+ true = is_atom(Name), %Assertion.
+ case OptOrMand of
+ mandatory -> ok;
+ _ ->
+ emit(["{",{curr,tmpBytes},",_ } = "])
+ end,
+ emit([Fun,"(",{asis,Name},", ",Element,", ",
+ {asis,RestFieldNames},"),",nl]),
+ emit(IndDeep),
+ case OptOrMand of
+ mandatory ->
+ emit(["{",{curr,encBytes},",",{curr,encLen},
+ "} = ",
+ {call,ber,encode_open_type,
+ [{curr,tmpBytes},{asis,Tag}]},nl]);
+ _ ->
+ emit([{call,ber,encode_open_type,
+ [{curr,tmpBytes},{asis,Tag}]}])
+ end;
_ ->
case WhatKind of
{primitive,bif} ->
@@ -1028,35 +1077,44 @@ gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,Assign,EncObj)
emit([nl,indent(7),"end"])
end.
-gen_optormand_case(mandatory, _Erules, _TopType, _Cname, _Type, _Element) ->
+gen_optormand_case(mandatory, _Gen, _TopType, _Cname, _Type, _Element) ->
ok;
-gen_optormand_case('OPTIONAL', Erules, _TopType, _Cname, _Type, Element) ->
+gen_optormand_case('OPTIONAL', Gen, _TopType, _Cname, _Type, Element) ->
emit([" case ",Element," of",nl]),
- emit([indent(9),"asn1_NOVALUE -> {",
- empty_lb(Erules),",0};",nl]),
+ Missing = case Gen of
+ #gen{pack=record} -> asn1_NOVALUE;
+ #gen{pack=map} -> ?MISSING_IN_MAP
+ end,
+ emit([indent(9),Missing," -> {",
+ empty_lb(Gen),",0};",nl]),
emit([indent(9),"_ ->",nl,indent(12)]);
-gen_optormand_case({'DEFAULT',DefaultValue}, Erules, _TopType,
+gen_optormand_case({'DEFAULT',DefaultValue}, Gen, _TopType,
_Cname, Type, Element) ->
CurrMod = get(currmod),
- case catch lists:member(der,get(encoding_options)) of
- true ->
- asn1ct_gen_check:emit(Type, DefaultValue, Element);
- _ ->
- emit([" case ",Element," of",nl]),
- emit([indent(9),"asn1_DEFAULT -> {",
- empty_lb(Erules),
- ",0};",nl]),
- case DefaultValue of
- #'Externalvaluereference'{module=CurrMod,
- value=V} ->
- emit([indent(9),"?",{asis,V}," -> {",
- empty_lb(Erules),",0};",nl]);
- _ ->
- emit([indent(9),{asis,
- DefaultValue}," -> {",
- empty_lb(Erules),",0};",nl])
- end,
- emit([indent(9),"_ ->",nl,indent(12)])
+ case Gen of
+ #gen{erule=ber,der=true} ->
+ asn1ct_gen_check:emit(Gen, Type, DefaultValue, Element);
+ #gen{erule=ber,der=false,pack=Pack} ->
+ Ind9 = indent(9),
+ DefMarker = case Pack of
+ record -> asn1_DEFAULT;
+ map -> ?MISSING_IN_MAP
+ end,
+ emit([" case ",Element," of",nl,
+ Ind9,{asis,DefMarker}," ->",nl,
+ Ind9,indent(3),"{",empty_lb(Gen),",0};",nl,
+ Ind9,"_ when ",Element," =:= "]),
+ Dv = case DefaultValue of
+ #'Externalvaluereference'{module=CurrMod,
+ value=V} ->
+ ["?",{asis,V}];
+ _ ->
+ [{asis,DefaultValue}]
+ end,
+ emit(Dv++[" ->",nl,
+ Ind9,indent(3),"{",empty_lb(Gen),",0};",nl,
+ Ind9,"_ ->",nl,
+ indent(12)])
end.
%% Use for SEQUENCE OF and CHOICE.
@@ -1087,7 +1145,9 @@ gen_dec_line(Erules,TopType,Cname,CTags,Type,OptOrMand,DecObjInf) ->
gen_dec_call(InnerType,Erules,TopType,Cname,Type,
BytesVar,Tag,
mandatory,", mandatory, ",DecObjInf,OptOrMand);
- _ -> %optional or default or a mandatory component after an extensionmark
+ _ ->
+ %% optional or default, or a mandatory component after
+ %% an extension marker
{FirstTag,RestTag} =
case Tag of
[] ->
@@ -1162,9 +1222,9 @@ gen_dec_line(Erules,TopType,Cname,CTags,Type,OptOrMand,DecObjInf) ->
PostponedDec
end,
case DecObjInf of
- {Cname,ObjSet} -> % this must be the component were an object is
- %% choosen from the object set according to the table
- %% constraint.
+ {Cname,ObjSet} ->
+ %% This must be the component were an object is chosen
+ %% from the object set according to the table constraint.
ObjSetName = case ObjSet of
{deep,OSName,_,_} ->
OSName;
@@ -1201,13 +1261,10 @@ gen_dec_call({typefield,_},_,_,_Cname,Type,BytesVar,Tag,_,_,false,_) ->
[];
gen_dec_call({typefield,_},_,_,Cname,Type,BytesVar,Tag,_,_,_DecObjInf,OptOrMandComp) ->
call(decode_open_type, [BytesVar,{asis,Tag}]),
- RefedFieldName =
-% asn1ct_gen:get_constraint(Type#type.constraint,
-% tableconstraint_info),
- (Type#type.def)#'ObjectClassFieldType'.fieldname,
+ RefedFieldName = (Type#type.def)#'ObjectClassFieldType'.fieldname,
[{Cname,RefedFieldName,asn1ct_gen:mk_var(asn1ct_name:curr(term)),
asn1ct_gen:mk_var(asn1ct_name:curr(tmpterm)),Tag,OptOrMandComp}];
-gen_dec_call(InnerType, _Erules, TopType, Cname, Type, BytesVar,
+gen_dec_call(InnerType, Gen, TopType, Cname, Type, BytesVar,
Tag, _PrimOptOrMand, _OptOrMand, DecObjInf,_) ->
WhatKind = asn1ct_gen:type(InnerType),
gen_dec_call1(WhatKind, InnerType, TopType, Cname,
@@ -1215,7 +1272,7 @@ gen_dec_call(InnerType, _Erules, TopType, Cname, Type, BytesVar,
case DecObjInf of
{Cname,{_,OSet,_UniqueFName,ValIndex}} ->
Term = asn1ct_gen:mk_var(asn1ct_name:curr(term)),
- ValueMatch = value_match(ValIndex,Term),
+ ValueMatch = value_match(Gen, ValIndex, Term),
{ObjSetMod,ObjSetName} = OSet,
emit([",",nl,"ObjFun = ",{asis,ObjSetMod},":'getdec_",ObjSetName,
"'(",ValueMatch,")"]);
@@ -1260,8 +1317,6 @@ gen_dec_call1(WhatKind, _, TopType, Cname, Type, BytesVar, Tag) ->
emit(["{'",asn1ct_gen:list2name([Cname|TopType]),"',",
BytesVar,"}"]);
_ ->
-% {DecFunName, _DecMod, _DecFun} =
-% case {asn1ct:get_gen_state_field(namelist),WhatKind} of
EmitDecFunCall =
fun(FuncName) ->
case {WhatKind,Type#type.tablecinf} of
@@ -1277,14 +1332,11 @@ gen_dec_call1(WhatKind, _, TopType, Cname, Type, BytesVar, Tag) ->
Sindex =
case WhatKind of
#'Externaltypereference'{} ->
-% asn1ct:maybe_rename_function(WhatKind,List),
SI = asn1ct:maybe_saved_sindex(WhatKind,List),
Saves = {WhatKind,SI,List},
asn1ct:add_tobe_refed_func(Saves),
SI;
_ ->
-% asn1ct:maybe_rename_function([Cname|TopType],
-% List),
SI = asn1ct:maybe_saved_sindex([Cname|TopType],List),
Saves = {[Cname|TopType],SI,List,Type},
asn1ct:add_tobe_refed_func(Saves),
@@ -1292,8 +1344,6 @@ gen_dec_call1(WhatKind, _, TopType, Cname, Type, BytesVar, Tag) ->
end,
asn1ct:update_gen_state(namelist,Rest),
Prefix=asn1ct:get_gen_state_field(prefix),
-% Suffix =
-% lists:concat(["_",asn1ct:latest_sindex()]),
Suffix =
case Sindex of
I when is_integer(I),I>0 -> lists:concat(["_",I]);
@@ -1301,8 +1351,6 @@ gen_dec_call1(WhatKind, _, TopType, Cname, Type, BytesVar, Tag) ->
end,
{DecFunName,_,_}=
mkfuncname(TopType,Cname,WhatKind,Prefix,Suffix),
-% SuffixedName =
-% lists:concat([DecFunName,asn1ct:latest_sindex()]),
EmitDecFunCall(DecFunName);
[{Cname,parts}|Rest] ->
asn1ct:update_gen_state(namelist,Rest),
@@ -1322,13 +1370,6 @@ gen_dec_call1(WhatKind, _, TopType, Cname, Type, BytesVar, Tag) ->
mkfuncname(TopType,Cname,WhatKind,"dec_",""),
EmitDecFunCall(DecFunName)
end
-% case {WhatKind,Type#type.tablecinf} of
-% {{constructed,bif},[{objfun,_}|_Rest]} ->
-% emit([DecFunName,"(",BytesVar,", ",{asis,Tag},
-% ", ObjFun)"]);
-% _ ->
-% emit([DecFunName,"(",BytesVar,", ",{asis,Tag},")"])
-% end
end.
@@ -1340,19 +1381,6 @@ gen_dec_call1(WhatKind, _, TopType, Cname, Type, BytesVar, Tag) ->
indent(N) ->
lists:duplicate(N,32). % 32 = space
-mkcindexlist([H,T1|T], Sep) -> % Sep is a string e.g ", " or "+ "
- emit(["Cindex",H,Sep]),
- mkcindexlist([T1|T], Sep);
-mkcindexlist([H|T], Sep) ->
- emit(["Cindex",H]),
- mkcindexlist(T, Sep);
-mkcindexlist([], _) ->
- true.
-
-mkcindexlist(L) ->
- mkcindexlist(L,", ").
-
-
mkvlist([H,T1|T], Sep) -> % Sep is a string e.g ", " or "+ "
emit([{var,H},Sep]),
mkvlist([T1|T], Sep);
@@ -1398,6 +1426,9 @@ print_attribute_comment(InnerType,Pos,Cname,Prop) ->
case InnerType of
#'Externaltypereference'{module=XModule,type=Name} ->
emit([nl,"%% attribute ",Cname,"(",Pos,") External ",XModule,":",Name]);
+ _ when is_tuple(InnerType) ->
+ emit([nl,"%% attribute ",Cname,"(",Pos,") with type "|
+ tuple_to_list(InnerType)]);
_ ->
emit([nl,"%% attribute ",Cname,"(",Pos,") with type ",InnerType])
end,
@@ -1429,19 +1460,25 @@ mkfuncname(TopType,Cname,WhatKind,Prefix,Suffix) ->
{F, "?MODULE", F}
end.
-empty_lb(ber) ->
+empty_lb(#gen{erule=ber}) ->
"<<>>".
-value_match(Index,Value) when is_atom(Value) ->
- value_match(Index,atom_to_list(Value));
-value_match([],Value) ->
+value_match(#gen{pack=record}, VIs, Value) ->
+ value_match_rec(VIs, Value);
+value_match(#gen{pack=map}, VIs, Value) ->
+ value_match_map(VIs, Value).
+
+value_match_rec([], Value) ->
+ Value;
+value_match_rec([{VI,_}|VIs], Value0) ->
+ Value = value_match_rec(VIs, Value0),
+ lists:concat(["element(",VI,", ",Value,")"]).
+
+value_match_map([], Value) ->
Value;
-value_match([{VI,_}|VIs],Value) ->
- value_match1(Value,VIs,lists:concat(["element(",VI,","]),1).
-value_match1(Value,[],Acc,Depth) ->
- Acc ++ Value ++ lists:concat(lists:duplicate(Depth,")"));
-value_match1(Value,[{VI,_}|VIs],Acc,Depth) ->
- value_match1(Value,VIs,Acc++lists:concat(["element(",VI,","]),Depth+1).
+value_match_map([{_,Name}|VIs], Value0) ->
+ Value = value_match_map(VIs, Value0),
+ lists:concat(["maps:get(",Name,", ",Value,")"]).
call(F, Args) ->
asn1ct_func:call(ber, F, Args).
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index a34b25182c..3f1be4febb 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -30,19 +30,28 @@
-export([gen_decode_choice/3]).
-include("asn1_records.hrl").
-%-compile(export_all).
--import(asn1ct_gen, [emit/1,demit/1,get_record_name_prefix/0]).
--import(asn1ct_func, [call/3]).
+-import(asn1ct_gen, [emit/1,get_record_name_prefix/1]).
+
+-type type_name() :: any().
+
%% ENCODE GENERATOR FOR SEQUENCE TYPE ** **********
-gen_encode_set(Erules,TypeName,D) ->
- gen_encode_constructed(Erules,TypeName,D).
+-spec gen_encode_set(Gen, TypeName, #type{}) -> 'ok' when
+ Gen :: #gen{},
+ TypeName :: type_name().
+
+gen_encode_set(Gen, TypeName, D) ->
+ gen_encode_constructed(Gen, TypeName, D).
-gen_encode_sequence(Erules,TypeName,D) ->
- gen_encode_constructed(Erules,TypeName,D).
+-spec gen_encode_sequence(Gen, TypeName, #type{}) -> 'ok' when
+ Gen :: #gen{},
+ TypeName :: type_name().
+
+gen_encode_sequence(Gen, TypeName, D) ->
+ gen_encode_constructed(Gen, TypeName, D).
gen_encode_constructed(Erule, Typename, #type{}=D) ->
asn1ct_name:start(),
@@ -50,88 +59,23 @@ gen_encode_constructed(Erule, Typename, #type{}=D) ->
asn1ct_imm:enc_cg(Imm, is_aligned(Erule)),
emit([".",nl]).
-gen_encode_constructed_imm(Erule, Typename, #type{}=D) ->
- {ExtAddGroup,TmpCompList,TableConsInfo} =
- case D#type.def of
- #'SEQUENCE'{tablecinf=TCI,components=CL,extaddgroup=ExtAddGroup0} ->
- {ExtAddGroup0,CL,TCI};
- #'SET'{tablecinf=TCI,components=CL} ->
- {undefined,CL,TCI}
- end,
-
- CompList = case ExtAddGroup of
- undefined ->
- TmpCompList;
- _ when is_integer(ExtAddGroup) ->
- %% This is a fake SEQUENCE representing an ExtensionAdditionGroup
- %% Reset the textual order so we get the right
- %% index of the components
- [Comp#'ComponentType'{textual_order=undefined}||
- Comp<-TmpCompList]
- end,
- ExternalImm =
- case Typename of
- ['EXTERNAL'] ->
- Next = asn1ct_gen:mk_var(asn1ct_name:next(val)),
- Curr = asn1ct_gen:mk_var(asn1ct_name:curr(val)),
- asn1ct_name:new(val),
- [{call,ext,transform_to_EXTERNAL1990,[{var,Curr}],{var,Next}}];
- _ ->
- []
- end,
- Aligned = is_aligned(Erule),
- Value0 = make_var(val),
+gen_encode_constructed_imm(Gen, Typename, #type{}=D) ->
+ {CompList,TableConsInfo} = enc_complist(D),
+ ExternalImm = external_imm(Gen, Typename),
Optionals = optionals(to_textual_order(CompList)),
- ImmOptionals = [asn1ct_imm:per_enc_optional(Value0, Opt, Aligned) ||
- Opt <- Optionals],
+ ImmOptionals = enc_optionals(Gen, Optionals),
Ext = extensible_enc(CompList),
+ Aligned = is_aligned(Gen),
ExtImm = case Ext of
{ext,ExtPos,NumExt} when NumExt > 0 ->
- gen_encode_extaddgroup(CompList),
+ gen_encode_extaddgroup(Gen, CompList),
Value = make_var(val),
- asn1ct_imm:per_enc_extensions(Value, ExtPos,
- NumExt, Aligned);
+ enc_extensions(Gen, Value, ExtPos, NumExt, Aligned);
_ ->
[]
end,
- {EncObj,ObjSetImm} =
- case TableConsInfo of
- #simpletableattributes{usedclassfield=Used,
- uniqueclassfield=Unique} when Used /= Unique ->
- {false,[]};
- %% ObjectSet, name of the object set in constraints
- %%
- %%{ObjectSet,AttrN,N,UniqueFieldName} -> %% N is index of attribute that determines constraint
- #simpletableattributes{objectsetname=ObjectSet,
- c_name=AttrN,
- c_index=N,
- usedclassfield=UniqueFieldName,
- uniqueclassfield=UniqueFieldName,
- valueindex=ValueIndex0
- } -> %% N is index of attribute that determines constraint
- {Module,ObjSetName} = ObjectSet,
- #typedef{typespec=#'ObjectSet'{gen=Gen}} =
- asn1_db:dbget(Module, ObjSetName),
- case Gen of
- true ->
- ValueIndex = ValueIndex0 ++ [{N+1,top}],
- Val = make_var(val),
- {ObjSetImm0,Dst} = enc_dig_out_value(ValueIndex, Val),
- {{AttrN,Dst},ObjSetImm0};
- false ->
- {false,[]}
- end;
- _ ->
- case D#type.tablecinf of
- [{objfun,_}|_] ->
- %% when the simpletableattributes was at an outer
- %% level and the objfun has been passed through the
- %% function call
- {{"got objfun through args",{var,"ObjFun"}},[]};
- _ ->
- {false,[]}
- end
- end,
+ MatchImm = enc_map_match(Gen, CompList),
+ {EncObj,ObjSetImm} = enc_table(Gen, TableConsInfo, D),
ImmSetExt =
case Ext of
{ext,_Pos,NumExt2} when NumExt2 > 0 ->
@@ -141,38 +85,195 @@ gen_encode_constructed_imm(Erule, Typename, #type{}=D) ->
_ ->
[]
end,
- ImmBody = gen_enc_components_call(Erule, Typename, CompList, EncObj, Ext),
- ExternalImm ++ ExtImm ++ ObjSetImm ++
+ ImmBody = gen_enc_components_call(Gen, Typename, CompList, EncObj, Ext),
+ ExternalImm ++ MatchImm ++ ExtImm ++ ObjSetImm ++
asn1ct_imm:enc_append([ImmSetExt] ++ ImmOptionals ++ ImmBody).
-gen_encode_extaddgroup(CompList) ->
+external_imm(Gen, ['EXTERNAL']) ->
+ Next = asn1ct_gen:mk_var(asn1ct_name:next(val)),
+ Curr = asn1ct_gen:mk_var(asn1ct_name:curr(val)),
+ asn1ct_name:new(val),
+ F = case Gen of
+ #gen{pack=record} -> transform_to_EXTERNAL1990;
+ #gen{pack=map} -> transform_to_EXTERNAL1990_maps
+ end,
+ [{call,ext,F,[{var,Curr}],{var,Next}}];
+external_imm(_, _) ->
+ [].
+
+enc_extensions(#gen{pack=record}, Value, ExtPos, NumExt, Aligned) ->
+ asn1ct_imm:per_enc_extensions(Value, ExtPos, NumExt, Aligned);
+enc_extensions(#gen{pack=map}, Value, ExtPos, NumExt, Aligned) ->
+ Vars = [{var,lists:concat(["Input@",Pos])} ||
+ Pos <- lists:seq(ExtPos, ExtPos+NumExt-1)],
+ Undefined = atom_to_list(?MISSING_IN_MAP),
+ asn1ct_imm:per_enc_extensions_map(Value, Vars, Undefined, Aligned).
+
+enc_complist(#type{def=Def}) ->
+ case Def of
+ #'SEQUENCE'{tablecinf=TCI,components=CL0,extaddgroup=ExtAddGroup} ->
+ case ExtAddGroup of
+ undefined ->
+ {CL0,TCI};
+ _ when is_integer(ExtAddGroup) ->
+ %% This is a fake SEQUENCE representing an
+ %% ExtensionAdditionGroup. Renumber the textual
+ %% order so we get the right index of the
+ %% components.
+ CL = add_textual_order(CL0),
+ {CL,TCI}
+ end;
+ #'SET'{tablecinf=TCI,components=CL} ->
+ {CL,TCI}
+ end.
+
+enc_table(Gen, #simpletableattributes{objectsetname=ObjectSet,
+ c_name=AttrN,
+ c_index=N,
+ usedclassfield=UniqueFieldName,
+ uniqueclassfield=UniqueFieldName,
+ valueindex=ValueIndex0}, _) ->
+ {Module,ObjSetName} = ObjectSet,
+ #typedef{typespec=#'ObjectSet'{gen=MustGen}} =
+ asn1_db:dbget(Module, ObjSetName),
+ case MustGen of
+ true ->
+ ValueIndex = ValueIndex0 ++ [{N+1,'ASN1_top'}],
+ Val = make_var(val),
+ {ObjSetImm,Dst} = enc_dig_out_value(Gen, ValueIndex, Val),
+ {{AttrN,Dst},ObjSetImm};
+ false ->
+ {false,[]}
+ end;
+enc_table(_Gen, #simpletableattributes{}, _) ->
+ {false,[]};
+enc_table(_Gen, _, #type{tablecinf=TCInf}) ->
+ case TCInf of
+ [{objfun,_}|_] ->
+ %% The simpletableattributes was at an outer
+ %% level and the objfun has been passed through the
+ %% function call.
+ {{"got objfun through args",{var,"ObjFun"}},[]};
+ _ ->
+ {false,[]}
+ end.
+
+enc_optionals(Gen, Optionals) ->
+ Var = make_var(val),
+ enc_optionals_1(Gen, Optionals, Var).
+
+enc_optionals_1(#gen{pack=record}=Gen, [{Pos,DefVals}|T], Var) ->
+ {Imm0,Element} = asn1ct_imm:enc_element(Pos+1, Var),
+ Imm = asn1ct_imm:per_enc_optional(Element, DefVals),
+ [Imm0++Imm|enc_optionals_1(Gen, T, Var)];
+enc_optionals_1(#gen{pack=map}=Gen, [{Pos,DefVals0}|T], V) ->
+ Var = {var,lists:concat(["Input@",Pos])},
+ DefVals = translate_missing_value(Gen, DefVals0),
+ Imm = asn1ct_imm:per_enc_optional(Var, DefVals),
+ [Imm|enc_optionals_1(Gen, T, V)];
+enc_optionals_1(_, [], _) ->
+ [].
+
+enc_map_match(#gen{pack=record}, _Cs) ->
+ [];
+enc_map_match(#gen{pack=map}, Cs0) ->
+ Var0 = "Input",
+ Cs = enc_flatten_components(Cs0),
+ M = [[quote_atom(Name),":=",lists:concat([Var0,"@",Order])] ||
+ #'ComponentType'{prop=mandatory,name=Name,
+ textual_order=Order} <- Cs],
+ Mand = case M of
+ [] ->
+ [];
+ [_|_] ->
+ Patt = {expr,lists:flatten(["#{",lists:join(",", M),"}"])},
+ [{assign,Patt,{var,asn1ct_name:curr(val)}}]
+ end,
+
+ Os0 = [{Name,Order} ||
+ #'ComponentType'{prop=Prop,name=Name,
+ textual_order=Order} <- Cs,
+ Prop =/= mandatory],
+ {var,Val} = make_var(val),
+ F = fun({Name,Order}) ->
+ Var = lists:concat([Var0,"@",Order]),
+ P0 = ["case ",Val," of\n"
+ " #{",quote_atom(Name),":=",Var,"_0} -> ",
+ Var,"_0;\n"
+ " _ -> ",atom_to_list(?MISSING_IN_MAP),"\n"
+ "end"],
+ P = lists:flatten(P0),
+ {assign,{var,Var},P}
+ end,
+ Os = [F(O) || O <- Os0],
+ Mand ++ Os.
+
+enc_flatten_components({Root1,Ext0,Root2}=CL) ->
+ {_,Gs} = extgroup_pos_and_length(CL),
+ Ext = wrap_extensionAdditionGroups(Ext0, Gs),
+ Root1 ++ Root2 ++ [mark_optional(C) || C <- Ext];
+enc_flatten_components({Root,Ext}) ->
+ enc_flatten_components({Root,Ext,[]});
+enc_flatten_components(Cs) ->
+ Cs.
+
+gen_encode_extaddgroup(#gen{pack=record}, CompList) ->
case extgroup_pos_and_length(CompList) of
{extgrouppos,[]} ->
ok;
{extgrouppos,ExtGroupPosLenList} ->
- _ = [do_gen_encode_extaddgroup(G) || G <- ExtGroupPosLenList],
+ _ = [gen_encode_eag_record(G) ||
+ G <- ExtGroupPosLenList],
ok
- end.
+ end;
+gen_encode_extaddgroup(#gen{pack=map}, Cs0) ->
+ Cs = enc_flatten_components(Cs0),
+ gen_encode_eag_map(Cs).
+
+gen_encode_eag_map([#'ComponentType'{name=Group,typespec=Type}|Cs]) ->
+ case Type of
+ #type{def=#'SEQUENCE'{extaddgroup=G,components=GCs0}}
+ when is_integer(G) ->
+ Ns = [N || #'ComponentType'{name=N,prop=mandatory} <- GCs0],
+ test_for_mandatory(Ns, Group),
+ gen_encode_eag_map(Cs);
+ _ ->
+ gen_encode_eag_map(Cs)
+ end;
+gen_encode_eag_map([]) ->
+ ok.
+
+test_for_mandatory([Mand|_], Group) ->
+ emit([{next,val}," = case ",{curr,val}," of",nl,
+ "#{",quote_atom(Mand),":=_} -> ",
+ {curr,val},"#{",{asis,Group},"=>",{curr,val},"};",nl,
+ "#{} -> ",{curr,val},nl,
+ "end,",nl]),
+ asn1ct_name:new(val);
+test_for_mandatory([], _) ->
+ ok.
-do_gen_encode_extaddgroup({ActualGroupPos,GroupVirtualPos,GroupLen}) ->
+gen_encode_eag_record({ActualPos,VirtualPos,Len}) ->
Val = asn1ct_gen:mk_var(asn1ct_name:curr(val)),
- Elements = make_elements(GroupVirtualPos+1,
- Val,
- lists:seq(1, GroupLen)),
- Expr = any_non_value(GroupVirtualPos+1, Val, GroupLen, ""),
+ Elements = get_input_vars(Val, VirtualPos, Len),
+ Expr = any_non_value(Val, VirtualPos, Len),
emit([{next,val}," = case ",Expr," of",nl,
- "false -> setelement(",{asis,ActualGroupPos+1},", ",
+ "false -> setelement(",{asis,ActualPos+1},", ",
{curr,val},", asn1_NOVALUE);",nl,
- "true -> setelement(",{asis,ActualGroupPos+1},", ",
+ "true -> setelement(",{asis,ActualPos+1},", ",
{curr,val},", {extaddgroup,", Elements,"})",nl,
"end,",nl]),
asn1ct_name:new(val).
-any_non_value(_, _, 0, _) ->
+any_non_value(Val, Pos, N) ->
+ L = any_non_value_1(Val, Pos, N),
+ lists:join(" orelse ", L).
+
+any_non_value_1(_, _, 0) ->
[];
-any_non_value(Pos, Val, N, Sep) ->
- Sep ++ [make_element(Pos, Val)," =/= asn1_NOVALUE"] ++
- any_non_value(Pos+1, Val, N-1, [" orelse",nl]).
+any_non_value_1(Val, Pos, N) ->
+ Var = get_input_var(Val, Pos),
+ [Var ++ " =/= asn1_NOVALUE"|any_non_value_1(Val, Pos+1, N-1)].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% generate decode function for SEQUENCE and SET
@@ -255,7 +356,6 @@ gen_dec_constructed_imm(Erule, Typename, #type{}=D) ->
#'SEQUENCE'{tablecinf=TCI,components=CL} ->
{add_textual_order(CL),TCI};
#'SET'{tablecinf=TCI,components=CL} ->
-%% {add_textual_order(CL),TCI}
{CL,TCI} % the textual order is already taken care of
end,
Ext = extensible_dec(CompList),
@@ -273,13 +373,11 @@ gen_dec_constructed_imm(Erule, Typename, #type{}=D) ->
end,
ObjSetInfo =
case TableConsInfo of
-%% {ObjectSet,AttrN,N,UniqueFieldName} ->%% N is index of attribute that determines constraint
#simpletableattributes{objectsetname=ObjectSet,
c_name=AttrN,
usedclassfield=UniqueFieldName,
uniqueclassfield=UniqueFieldName,
valueindex=ValIndex} ->
-%% {AttrN,ObjectSet};
F = fun(#'ComponentType'{typespec=CT})->
case {asn1ct_gen:get_constraint(CT#type.constraint,componentrelation),CT#type.tablecinf} of
{no,[{objfun,_}|_R]} -> true;
@@ -306,55 +404,105 @@ gen_dec_constructed_imm(Erule, Typename, #type{}=D) ->
{DecObjInf,_,_} = ObjSetInfo,
EmitComp = gen_dec_components_call(Erule, Typename, CompList,
DecObjInf, Ext, length(Optionals)),
- EmitRest = fun({AccTerm,AccBytes}) ->
- gen_dec_constructed_imm_2(Erule, Typename,
- CompList,
- ObjSetInfo,
- AccTerm, AccBytes)
- end,
- [EmitExt,EmitOpt|EmitComp++[{safe,EmitRest}]].
+ EmitObjSets = gen_dec_objsets_fun(Erule, ObjSetInfo),
+ EmitPack = fun(_) ->
+ gen_dec_pack(Erule, Typename, CompList)
+ end,
+ RestGroup = {group,[{safe,EmitObjSets},{safe,EmitPack}]},
+ [EmitExt,EmitOpt|EmitComp++[RestGroup]].
+
+gen_dec_objsets_fun(Gen, ObjSetInfo) ->
+ fun({AccTerm,AccBytes}) ->
+ {_,_UniqueFName,ValueIndex} = ObjSetInfo,
+ case {AccTerm,AccBytes} of
+ {[],[]} ->
+ ok;
+ {_,[]} ->
+ ok;
+ {[{ObjSet,LeadingAttr,Term}],ListOfOpenTypes} ->
+ ValueMatch = value_match(Gen, ValueIndex, Term),
+ _ = [begin
+ gen_dec_open_type(Gen, ValueMatch, ObjSet,
+ LeadingAttr, T),
+ emit([com,nl])
+ end || T <- ListOfOpenTypes],
+ ok
+ end
+ end.
-gen_dec_constructed_imm_2(Erule, Typename, CompList,
- ObjSetInfo, AccTerm, AccBytes) ->
- {_,_UniqueFName,ValueIndex} = ObjSetInfo,
- case {AccTerm,AccBytes} of
- {[],[]} ->
- ok;
- {_,[]} ->
- ok;
- {[{ObjSet,LeadingAttr,Term}],ListOfOpenTypes} ->
- ValueMatch = value_match(ValueIndex, Term),
- _ = [begin
- gen_dec_open_type(Erule, ValueMatch, ObjSet,
- LeadingAttr, T),
- emit([com,nl])
- end || T <- ListOfOpenTypes],
- ok
- end,
- %% we don't return named lists any more Cnames = mkcnamelist(CompList),
- demit({"Result = "}), %dbg
- %% return value as record
- RecordName = record_name(Typename),
+gen_dec_pack(Gen, Typename, CompList) ->
case Typename of
['EXTERNAL'] ->
- emit({" OldFormat={'",RecordName,
- "'"}),
- mkvlist(asn1ct_name:all(term)),
- emit({"},",nl}),
- emit([" ASN11994Format =",nl,
- " ",
- {call,ext,transform_to_EXTERNAL1994,
- ["OldFormat"]},com,nl]),
- emit(" {ASN11994Format,");
+ dec_external(Gen, Typename);
_ ->
- emit(["{{'",RecordName,"'"]),
- %% CompList is used here because we don't want
- %% ExtensionAdditionGroups to be wrapped in SEQUENCES when
- %% we are ordering the fields according to textual order
- mkvlist(textual_order(to_encoding_order(CompList),asn1ct_name:all(term))),
- emit("},")
- end,
- emit({{curr,bytes},"}"}).
+ asn1ct_name:new(res),
+ gen_dec_do_pack(Gen, Typename, CompList),
+ emit([com,nl,
+ "{",{curr,res},",",{curr,bytes},"}"])
+ end.
+
+dec_external(#gen{pack=record}=Gen, Typename) ->
+ RecordName = list_to_atom(record_name(Gen, Typename)),
+ All = [{var,Term} || Term <- asn1ct_name:all(term)],
+ Record = [{asis,RecordName}|All],
+ emit(["OldFormat={",lists:join(",", Record),"},",nl,
+ "ASN11994Format =",nl,
+ {call,ext,transform_to_EXTERNAL1994,
+ ["OldFormat"]},com,nl,
+ "{ASN11994Format,",{curr,bytes},"}"]);
+dec_external(#gen{pack=map}, _Typename) ->
+ Vars = asn1ct_name:all(term),
+ Names = ['direct-reference','indirect-reference',
+ 'data-value-descriptor',encoding],
+ Zipped = lists:zip(Names, Vars),
+ MapInit = lists:join(",", [["'",N,"'=>",{var,V}] || {N,V} <- Zipped]),
+ emit(["OldFormat = #{",MapInit,"}",com,nl,
+ "ASN11994Format =",nl,
+ {call,ext,transform_to_EXTERNAL1994_maps,
+ ["OldFormat"]},com,nl,
+ "{ASN11994Format,",{curr,bytes},"}"]).
+
+gen_dec_do_pack(#gen{pack=record}=Gen, TypeName, CompList) ->
+ Zipped0 = zip_components(CompList, asn1ct_name:all(term)),
+ Zipped = textual_order(Zipped0),
+ RecordName = ["'",record_name(Gen, TypeName),"'"],
+ L = [RecordName|[{var,Var} || {_,Var} <- Zipped]],
+ emit([{curr,res}," = {",lists:join(",", L),"}"]);
+gen_dec_do_pack(#gen{pack=map}, _, CompList0) ->
+ CompList = enc_flatten_components(CompList0),
+ Zipped0 = zip_components(CompList, asn1ct_name:all(term)),
+ Zipped = textual_order(Zipped0),
+ PF = fun({#'ComponentType'{prop='OPTIONAL'},_}) -> false;
+ ({_,_}) -> true
+ end,
+ {Mandatory,Optional} = lists:partition(PF, Zipped),
+ L = [[{asis,Name},"=>",{var,Var}] ||
+ {#'ComponentType'{name=Name},Var} <- Mandatory],
+ emit([{curr,res}," = #{",lists:join(",", L),"}"]),
+ gen_dec_map_optional(Optional),
+ gen_dec_merge_maps(asn1ct_name:all(map)).
+
+gen_dec_map_optional([{#'ComponentType'{name=Name},Var}|T]) ->
+ asn1ct_name:new(res),
+ emit([com,nl,
+ {curr,res}," = case ",{var,Var}," of",nl,
+ " asn1_NOVALUE -> ",{prev,res},";",nl,
+ " _ -> ",{prev,res},"#{",{asis,Name},"=>",{var,Var},"}",nl,
+ "end"]),
+ gen_dec_map_optional(T);
+gen_dec_map_optional([]) ->
+ ok.
+
+gen_dec_merge_maps([M|Ms]) ->
+ asn1ct_name:new(res),
+ emit([com,nl,
+ {curr,res}," = maps:merge(",{prev,res},", ",{var,M},")"]),
+ gen_dec_merge_maps(Ms);
+gen_dec_merge_maps([]) ->
+ ok.
+
+quote_atom(A) when is_atom(A) ->
+ io_lib:format("~p", [A]).
%% record_name([TypeName]) -> RecordNameString
%% Construct a record name for the constructed type, ignoring any
@@ -362,10 +510,10 @@ gen_dec_constructed_imm_2(Erule, Typename, CompList,
%% group. Such fake sequences never appear as a top type, and their
%% name always start with "ExtAddGroup".
-record_name(Typename0) ->
+record_name(Gen, Typename0) ->
[TopType|Typename1] = lists:reverse(Typename0),
Typename = filter_ext_add_groups(Typename1, [TopType]),
- lists:concat([get_record_name_prefix(),
+ lists:concat([get_record_name_prefix(Gen),
asn1ct_gen:list2rname(Typename)]).
filter_ext_add_groups([H|T], Acc) when is_atom(H) ->
@@ -379,17 +527,26 @@ filter_ext_add_groups([H|T], Acc) ->
filter_ext_add_groups(T, [H|Acc]);
filter_ext_add_groups([], Acc) -> Acc.
-textual_order([#'ComponentType'{textual_order=undefined}|_],TermList) ->
- TermList;
-textual_order(CompList,TermList) when is_list(CompList) ->
- OrderList = [Ix||#'ComponentType'{textual_order=Ix} <- CompList],
- [Term||{_,Term}<-
- lists:sort(lists:zip(OrderList,
- lists:sublist(TermList,length(OrderList))))];
- %% sublist is just because Termlist can sometimes be longer than
- %% OrderList, which it really shouldn't
-textual_order({Root,Ext},TermList) ->
- textual_order(Root ++ Ext,TermList).
+zip_components({Root,Ext}, Vars) ->
+ zip_components({Root,Ext,[]}, Vars);
+zip_components({R1,Ext0,R2}, Vars) ->
+ Ext = [mark_optional(C) || C <- Ext0],
+ zip_components(R1++R2++Ext, Vars);
+zip_components(Cs, Vars) when is_list(Cs) ->
+ zip_components_1(Cs, Vars).
+
+zip_components_1([#'ComponentType'{}=C|Cs], [V|Vs]) ->
+ [{C,V}|zip_components_1(Cs, Vs)];
+zip_components_1([_|Cs], Vs) ->
+ zip_components_1(Cs, Vs);
+zip_components_1([], []) ->
+ [].
+
+textual_order([{#'ComponentType'{textual_order=undefined},_}|_]=L) ->
+ L;
+textual_order(L0) ->
+ L = [{Ix,P} || {#'ComponentType'{textual_order=Ix},_}=P <- L0],
+ [C || {_,C} <- lists:sort(L)].
to_textual_order({Root,Ext}) ->
{to_textual_order(Root),Ext};
@@ -458,7 +615,7 @@ dec_objset_default(N, _, _, true) ->
end]).
dec_objset_1(Erule, N, {Id,Obj}, RestFields, Typename) ->
- emit([{asis,N},"(Bytes, ",{asis,Id},") ->",nl]),
+ emit([{asis,N},"(Bytes, Id) when Id =:= ",{asis,Id}," ->",nl]),
dec_objset_2(Erule, Obj, RestFields, Typename).
dec_objset_2(Erule, Obj, RestFields0, Typename) ->
@@ -525,10 +682,10 @@ gen_decode_choice(Erules,Typename,D) when is_record(D,type) ->
{'CHOICE',CompList} = D#type.def,
Ext = extensible_enc(CompList),
gen_dec_choice(Erules,Typename,CompList,Ext),
- emit({".",nl}).
+ emit([".",nl]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Encode generator for SEQUENCE OF type
+%% Encode generator for SEQUENCE OF type
gen_encode_sof(Erule, Typename, SeqOrSetOf, D) ->
asn1ct_name:start(),
@@ -595,8 +752,7 @@ do_gen_decode_sof(Erules, Typename, SeqOrSetOf, D) ->
emit([",",nl,
{asis,F},"(",Num,", ",Buf,ObjFun,", [])"]).
-is_aligned(per) -> true;
-is_aligned(uper) -> false.
+is_aligned(#gen{erule=per,aligned=Aligned}) -> Aligned.
gen_decode_length(Constraint, Erule) ->
emit(["%% Length with constraint ",{asis,Constraint},nl]),
@@ -621,41 +777,26 @@ gen_decode_sof_components(Erule, Name, Typename, SeqOrSetOf, Cont) ->
case asn1ct_gen:type(Conttype) of
{primitive,bif} ->
asn1ct_gen_per:gen_dec_prim(Erule, Cont, "Bytes"),
- emit({com,nl});
+ emit([com,nl]);
{constructed,bif} ->
NewTypename = [Constructed_Suffix|Typename],
- emit({"'dec_",asn1ct_gen:list2name(NewTypename),
- "'(Bytes",ObjFun,"),",nl});
+ emit([{asis,dec_func(asn1ct_gen:list2name(NewTypename))},
+ "(Bytes",ObjFun,"),",nl]);
#'Externaltypereference'{}=Etype ->
asn1ct_gen_per:gen_dec_external(Etype, "Bytes"),
emit([com,nl]);
'ASN1_OPEN_TYPE' ->
asn1ct_gen_per:gen_dec_prim(Erule, #type{def='ASN1_OPEN_TYPE'},
"Bytes"),
- emit({com,nl});
+ emit([com,nl]);
_ ->
- emit({"'dec_",Conttype,"'(Bytes),",nl})
+ emit([{asis,dec_func(Conttype)},"(Bytes),",nl])
end,
emit([{asis,Name},"(Num-1, Remain",ObjFun,", [Term|Acc]).",nl]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% General and special help functions (not exported)
-
-mkvlist([H|T]) ->
- emit(","),
- mkvlist2([H|T]);
-mkvlist([]) ->
- true.
-mkvlist2([H,T1|T]) ->
- emit({{var,H},","}),
- mkvlist2([T1|T]);
-mkvlist2([H|T]) ->
- emit({{var,H}}),
- mkvlist2(T);
-mkvlist2([]) ->
- true.
-
+%% General and special help functions (not exported)
extensible_dec(CompList) when is_list(CompList) ->
noext;
@@ -728,28 +869,26 @@ gen_dec_optionals(Optionals) ->
{imm,Imm0,E}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Produce a list with positions (in the Value record) where
-%% there are optional components, start with 2 because first element
-%% is the record name
-
-optionals({L1,Ext,L2}) ->
- Opt1 = optionals(L1,[],2),
- ExtComps = length([C||C = #'ComponentType'{}<-Ext]),
- Opt2 = optionals(L2,[],2+length(L1)+ExtComps),
- Opt1 ++ Opt2;
-optionals({L,_Ext}) -> optionals(L,[],2);
-optionals(L) -> optionals(L,[],2).
-optionals([#'ComponentType'{prop='OPTIONAL'}|Rest], Acc, Pos) ->
- optionals(Rest, [Pos|Acc], Pos+1);
-optionals([#'ComponentType'{typespec=T,prop={'DEFAULT',Val}}|Rest],
- Acc, Pos) ->
+optionals({Root1,Ext,Root2}) ->
+ Opt1 = optionals(Root1, 1),
+ ExtComps = length([C || C = #'ComponentType'{} <- Ext]),
+ Opt2 = optionals(Root2, 1 + length(Root1) + ExtComps),
+ Opt1 ++ Opt2;
+optionals({L,_Ext}) ->
+ optionals(L, 1);
+optionals(L) ->
+ optionals(L, 1).
+
+optionals([#'ComponentType'{prop='OPTIONAL'}|Rest], Pos) ->
+ [{Pos,[asn1_NOVALUE]}|optionals(Rest, Pos+1)];
+optionals([#'ComponentType'{typespec=T,prop={'DEFAULT',Val}}|Cs], Pos) ->
Vals = def_values(T, Val),
- optionals(Rest, [{Pos,Vals}|Acc], Pos+1);
-optionals([#'ComponentType'{}|Rest], Acc, Pos) ->
- optionals(Rest, Acc, Pos+1);
-optionals([], Acc, _) ->
- lists:reverse(Acc).
+ [{Pos,Vals}|optionals(Cs, Pos+1)];
+optionals([#'ComponentType'{}|Rest], Pos) ->
+ optionals(Rest, Pos+1);
+optionals([], _) ->
+ [].
%%%%%%%%%%%%%%%%%%%%%%
%% create_optionality_table(Cs=[#'ComponentType'{textual_order=undefined}|_]) ->
@@ -779,13 +918,6 @@ get_optionality_pos(TextPos,OptTable) ->
no_num
end.
-to_encoding_order(Cs) when is_list(Cs) ->
- Cs;
-to_encoding_order(Cs = {_Root,_Ext}) ->
- Cs;
-to_encoding_order({R1,Ext,R2}) ->
- {R1++R2,Ext}.
-
add_textual_order(Cs) when is_list(Cs) ->
{NewCs,_} = add_textual_order1(Cs,1),
NewCs;
@@ -798,9 +930,7 @@ add_textual_order({R1,Ext,R2}) ->
{NewExt,Num2} = add_textual_order1(Ext,Num1),
{NewR2,_} = add_textual_order1(R2,Num2),
{NewR1,NewExt,NewR2}.
-%%add_textual_order1(Cs=[#'ComponentType'{textual_order=Int}|_],I)
-%% when is_integer(Int) ->
-%% {Cs,I};
+
add_textual_order1(Cs,NumIn) ->
lists:mapfoldl(fun(C=#'ComponentType'{},Num) ->
{C#'ComponentType'{textual_order=Num},
@@ -810,69 +940,81 @@ add_textual_order1(Cs,NumIn) ->
end,
NumIn,Cs).
-gen_enc_components_call(Erule,TopType,{Root,ExtList}, DynamicEnc,Ext) ->
- gen_enc_components_call(Erule,TopType,{Root,ExtList,[]}, DynamicEnc,Ext);
-gen_enc_components_call(Erule,TopType,CL={Root,ExtList,Root2}, DynamicEnc,Ext) ->
- %% The type has extensionmarker
- {Imm0,Rpos} = gen_enc_components_call1(Erule,TopType,Root++Root2,1, DynamicEnc,noext,[]),
+gen_enc_components_call(Erule, TopType, {Root,ExtList}, DynamicEnc, Ext) ->
+ gen_enc_components_call(Erule, TopType, {Root,ExtList,[]}, DynamicEnc, Ext);
+gen_enc_components_call(Erule, TopType, {R1,ExtList0,R2}=CL, DynamicEnc, Ext) ->
+ Root = R1 ++ R2,
+ Imm0 = gen_enc_components_call1(Erule, TopType, Root, DynamicEnc, noext),
ExtImm = case Ext of
{ext,_,ExtNum} when ExtNum > 0 ->
[{var,"Extensions"}];
_ ->
[]
end,
- %handle extensions
{extgrouppos,ExtGroupPosLen} = extgroup_pos_and_length(CL),
- NewExtList = wrap_extensionAdditionGroups(ExtList,ExtGroupPosLen),
- {Imm1,_} = gen_enc_components_call1(Erule,TopType,NewExtList,Rpos,DynamicEnc,Ext,[]),
+ ExtList1 = wrap_extensionAdditionGroups(ExtList0, ExtGroupPosLen),
+ ExtList = [mark_optional(C) || C <- ExtList1],
+ Imm1 = gen_enc_components_call1(Erule, TopType, ExtList, DynamicEnc, Ext),
Imm0 ++ [ExtImm|Imm1];
-gen_enc_components_call(Erule,TopType, CompList, DynamicEnc, Ext) ->
- %% The type has no extensionmarker
- {Imm,_} = gen_enc_components_call1(Erule,TopType,CompList,1,DynamicEnc,Ext,[]),
- Imm.
+gen_enc_components_call(Erule, TopType, CompList, DynamicEnc, Ext) ->
+ %% No extension marker.
+ gen_enc_components_call1(Erule, TopType, CompList, DynamicEnc, Ext).
+
+mark_optional(#'ComponentType'{prop=Prop0}=C) ->
+ Prop = case Prop0 of
+ mandatory -> 'OPTIONAL';
+ 'OPTIONAL'=Keep -> Keep;
+ {'DEFAULT',_}=Keep -> Keep
+ end,
+ C#'ComponentType'{prop=Prop};
+mark_optional(Other) ->
+ Other.
+
+gen_enc_components_call1(Gen, TopType, [C|Rest], DynamicEnc, Ext) ->
+ #'ComponentType'{name=Cname,typespec=Type,
+ prop=Prop,textual_order=Num} = C,
+ InnerType = asn1ct_gen:get_inner(Type#type.def),
+ CommentString = attribute_comment(InnerType, Num, Cname),
+ ImmComment = asn1ct_imm:enc_comment(CommentString),
-gen_enc_components_call1(Erule,TopType,
- [C=#'ComponentType'{name=Cname,typespec=Type,prop=Prop}|Rest],
- Tpos,
- DynamicEnc, Ext, Acc) ->
-
- TermNo =
- case C#'ComponentType'.textual_order of
- undefined ->
- Tpos;
- CanonicalNum ->
- CanonicalNum
- end,
- Val = make_var(val),
- {Imm0,Element} = asn1ct_imm:enc_element(TermNo+1, Val),
- Imm1 = gen_enc_line_imm(Erule, TopType, Cname, Type, Element, DynamicEnc, Ext),
- Category = case {Prop,Ext} of
- {'OPTIONAL',_} ->
- optional;
- {{'DEFAULT',DefVal},_} ->
- {default,DefVal};
- {_,{ext,ExtPos,_}} when Tpos >= ExtPos ->
- optional;
- {_,_} ->
- mandatory
- end,
- Imm2 = case Category of
+ {Imm0,Element} = enc_fetch_field(Gen, Num, Prop),
+ Imm1 = gen_enc_line_imm(Gen, TopType, Cname, Type,
+ Element, DynamicEnc, Ext),
+ Imm2 = case Prop of
mandatory ->
Imm1;
- optional ->
- asn1ct_imm:enc_absent(Element, [asn1_NOVALUE], Imm1);
- {default,Def} ->
+ 'OPTIONAL' ->
+ enc_absent(Gen, Element, [asn1_NOVALUE], Imm1);
+ {'DEFAULT',Def} ->
DefValues = def_values(Type, Def),
- asn1ct_imm:enc_absent(Element, DefValues, Imm1)
+ enc_absent(Gen, Element, DefValues, Imm1)
end,
Imm = case Imm2 of
[] -> [];
- _ -> Imm0 ++ Imm2
+ _ -> [ImmComment|Imm0 ++ Imm2]
end,
- gen_enc_components_call1(Erule, TopType, Rest, Tpos+1, DynamicEnc, Ext, [Imm|Acc]);
-gen_enc_components_call1(_Erule,_TopType,[],Pos,_,_, Acc) ->
- ImmList = lists:reverse(Acc),
- {ImmList,Pos}.
+ [Imm|gen_enc_components_call1(Gen, TopType, Rest, DynamicEnc, Ext)];
+gen_enc_components_call1(_Gen, _TopType, [], _, _) ->
+ [].
+
+enc_absent(Gen, Var, Absent0, Imm) ->
+ Absent = translate_missing_value(Gen, Absent0),
+ asn1ct_imm:enc_absent(Var, Absent, Imm).
+
+translate_missing_value(#gen{pack=record}, Optionals) ->
+ Optionals;
+translate_missing_value(#gen{pack=map}, Optionals) ->
+ case Optionals of
+ [asn1_NOVALUE|T] -> [?MISSING_IN_MAP|T];
+ [asn1_DEFAULT|T] -> [?MISSING_IN_MAP|T];
+ {call,_,_,_} -> Optionals
+ end.
+
+enc_fetch_field(#gen{pack=record}, Num, _Prop) ->
+ Val = make_var(val),
+ asn1ct_imm:enc_element(Num+1, Val);
+enc_fetch_field(#gen{pack=map}, Num, _) ->
+ {[],{var,lists:concat(["Input@",Num])}}.
def_values(#type{def=#'Externaltypereference'{module=Mod,type=Type}}, Def) ->
#typedef{typespec=T} = asn1_db:dbget(Mod, Type),
@@ -1115,27 +1257,31 @@ gen_dec_components_call(Erule, TopType, {Root,ExtList},
DecInfObj, Ext, NumberOfOptionals) ->
gen_dec_components_call(Erule,TopType,{Root,ExtList,[]},
DecInfObj,Ext,NumberOfOptionals);
-gen_dec_components_call(Erule,TopType,CL={Root1,ExtList,Root2},
- DecInfObj,Ext,NumberOfOptionals) ->
+gen_dec_components_call(Gen, TopType, {Root1,ExtList,Root2}=CL,
+ DecInfObj, Ext, NumberOfOptionals) ->
%% The type has extensionmarker
OptTable = create_optionality_table(Root1++Root2),
Init = {ignore,fun(_) -> {[],[]} end},
{EmitRoot,Tpos} =
- gen_dec_comp_calls(Root1++Root2, Erule, TopType, OptTable,
+ gen_dec_comp_calls(Root1++Root2, Gen, TopType, OptTable,
DecInfObj, noext, NumberOfOptionals,
1, []),
- EmitGetExt = gen_dec_get_extension(Erule),
+ EmitGetExt = gen_dec_get_extension(Gen),
{extgrouppos,ExtGroupPosLen} = extgroup_pos_and_length(CL),
NewExtList = wrap_extensionAdditionGroups(ExtList, ExtGroupPosLen),
- {EmitExts,_} = gen_dec_comp_calls(NewExtList, Erule, TopType, OptTable,
+ {EmitExts,_} = gen_dec_comp_calls(NewExtList, Gen, TopType, OptTable,
DecInfObj, Ext, NumberOfOptionals,
Tpos, []),
NumExtsToSkip = ext_length(ExtList),
Finish =
fun(St) ->
emit([{next,bytes},"= "]),
- call(Erule, skipextensions,
- [{curr,bytes},NumExtsToSkip+1,"Extensions"]),
+ Mod = case Gen of
+ #gen{erule=per,aligned=false} -> uper;
+ #gen{erule=per,aligned=true} -> per
+ end,
+ asn1ct_func:call(Mod, skipextensions,
+ [{curr,bytes},NumExtsToSkip+1,"Extensions"]),
asn1ct_name:new(bytes),
St
end,
@@ -1178,29 +1324,19 @@ gen_dec_comp_calls([C|Cs], Erule, TopType, OptTable, DecInfObj,
gen_dec_comp_calls([], _, _, _, _, _, _, Tpos, Acc) ->
{lists:append(lists:reverse(Acc)),Tpos}.
-gen_dec_comp_call(Comp, Erule, TopType, Tpos, OptTable, DecInfObj,
+gen_dec_comp_call(Comp, Gen, TopType, Tpos, OptTable, DecInfObj,
Ext, NumberOfOptionals) ->
- #'ComponentType'{typespec=Type,prop=Prop,textual_order=TextPos} = Comp,
+ #'ComponentType'{name=Cname,typespec=Type,
+ prop=Prop,textual_order=TextPos} = Comp,
Pos = case Ext of
noext -> Tpos;
{ext,Epos,_Enum} -> Tpos - Epos + 1
end,
- InnerType =
- case Type#type.def of
- #'ObjectClassFieldType'{type=InType} ->
- InType;
- Def ->
- asn1ct_gen:get_inner(Def)
- end,
+ InnerType = asn1ct_gen:get_inner(Type#type.def),
- DispType = case InnerType of
- #'Externaltypereference'{type=T} -> T;
- IT when is_tuple(IT) -> element(2,IT);
- _ -> InnerType
- end,
+ CommentString = attribute_comment(InnerType, TextPos, Cname),
Comment = fun(St) ->
- emit([nl,"%% attribute number ",TextPos,
- " with type ",DispType,nl]),
+ emit([nl,"%% ",CommentString,nl]),
St
end,
@@ -1219,15 +1355,9 @@ gen_dec_comp_call(Comp, Erule, TopType, Tpos, OptTable, DecInfObj,
_ ->
case Type of
#type{def=#'SEQUENCE'{
- extaddgroup=Number1,
- components=ExtGroupCompList1}} when is_integer(Number1)->
- fun(St) ->
- emit(["{{_,"]),
- emit_extaddgroupTerms(term,ExtGroupCompList1),
- emit(["}"]),
- emit([",",{next,bytes},"} = "]),
- St
- end;
+ extaddgroup=GroupNum,
+ components=CompList}} when is_integer(GroupNum)->
+ dec_match_extadd_fun(Gen, CompList);
_ ->
fun(St) ->
asn1ct_name:new(term),
@@ -1237,9 +1367,9 @@ gen_dec_comp_call(Comp, Erule, TopType, Tpos, OptTable, DecInfObj,
end
end
end,
- {Pre,Post} = comp_call_pre_post(Ext, Prop, Pos, Type, TextPos,
+ {Pre,Post} = comp_call_pre_post(Gen, Ext, Prop, Pos, Type, TextPos,
OptTable, NumberOfOptionals, Ext),
- Lines = gen_dec_seq_line_imm(Erule, TopType, Comp, Tpos, DecInfObj, Ext),
+ Lines = gen_dec_seq_line_imm(Gen, TopType, Comp, Tpos, DecInfObj, Ext),
AdvBuffer = {ignore,fun(St) ->
asn1ct_name:new(bytes),
St
@@ -1247,9 +1377,24 @@ gen_dec_comp_call(Comp, Erule, TopType, Tpos, OptTable, DecInfObj,
[{group,[{safe,Comment},{safe,Preamble}] ++ Pre ++
Lines ++ Post ++ [{safe,AdvBuffer}]}].
-comp_call_pre_post(noext, mandatory, _, _, _, _, _, _) ->
+dec_match_extadd_fun(#gen{pack=record}, CompList) ->
+ fun(St) ->
+ emit(["{{_,"]),
+ emit_extaddgroupTerms(term, CompList),
+ emit(["}"]),
+ emit([",",{next,bytes},"} = "]),
+ St
+ end;
+dec_match_extadd_fun(#gen{pack=map}, _CompList) ->
+ fun(St) ->
+ asn1ct_name:new(map),
+ emit(["{",{curr,map},",",{next,bytes},"} = "]),
+ St
+ end.
+
+comp_call_pre_post(_Gen, noext, mandatory, _, _, _, _, _, _) ->
{[],[]};
-comp_call_pre_post(noext, Prop, _, Type, TextPos,
+comp_call_pre_post(_Gen, noext, Prop, _, Type, TextPos,
OptTable, NumOptionals, Ext) ->
%% OPTIONAL or DEFAULT
OptPos = get_optionality_pos(TextPos, OptTable),
@@ -1273,32 +1418,53 @@ comp_call_pre_post(noext, Prop, _, Type, TextPos,
"end"]),
St
end]};
-comp_call_pre_post({ext,_,_}, Prop, Pos, Type, _, _, _, Ext) ->
+comp_call_pre_post(Gen, {ext,_,_}, Prop, Pos, Type, _, _, _, Ext) ->
%% Extension
{[fun(St) ->
emit(["case Extensions of",nl,
" <<_:",Pos-1,",1:1,_/bitstring>> ->",nl]),
St
end],
- [fun(St) ->
- emit([";",nl,
- "_ ->",nl,
- "{"]),
- case Type of
- #type{def=#'SEQUENCE'{
- extaddgroup=Number2,
- components=ExtGroupCompList2}}
- when is_integer(Number2)->
- emit("{extAddGroup,"),
- gen_dec_extaddGroup_no_val(Ext, Type, ExtGroupCompList2),
- emit("}");
- _ ->
- gen_dec_component_no_val(Ext, Type, Prop)
- end,
- emit([",",{curr,bytes},"}",nl,
- "end"]),
- St
- end]}.
+ [extadd_group_fun(Gen, Prop, Type, Ext)]}.
+
+extadd_group_fun(#gen{pack=record}, Prop, Type, Ext) ->
+ fun(St) ->
+ emit([";",nl,
+ "_ ->",nl,
+ "{"]),
+ case Type of
+ #type{def=#'SEQUENCE'{
+ extaddgroup=Number2,
+ components=ExtGroupCompList2}}
+ when is_integer(Number2)->
+ emit("{extAddGroup,"),
+ gen_dec_extaddGroup_no_val(Ext, Type, ExtGroupCompList2),
+ emit("}");
+ _ ->
+ gen_dec_component_no_val(Ext, Type, Prop)
+ end,
+ emit([",",{curr,bytes},"}",nl,
+ "end"]),
+ St
+ end;
+extadd_group_fun(#gen{pack=map}, Prop, Type, Ext) ->
+ fun(St) ->
+ emit([";",nl,
+ "_ ->",nl,
+ "{"]),
+ case Type of
+ #type{def=#'SEQUENCE'{
+ extaddgroup=Number2,
+ components=Comp}}
+ when is_integer(Number2)->
+ dec_map_extaddgroup_no_val(Ext, Type, Comp);
+ _ ->
+ gen_dec_component_no_val(Ext, Type, Prop)
+ end,
+ emit([",",{curr,bytes},"}",nl,
+ "end"]),
+ St
+ end.
is_mandatory_predef_tab_c(noext, mandatory,
{"got objfun through args","ObjFun"}) ->
@@ -1322,10 +1488,23 @@ gen_dec_component_no_val(_, Type, {'DEFAULT',DefVal0}) ->
DefVal = asn1ct_gen:conform_value(Type, DefVal0),
emit([{asis,DefVal}]);
gen_dec_component_no_val(_, _, 'OPTIONAL') ->
- emit({"asn1_NOVALUE"});
+ emit(["asn1_NOVALUE"]);
gen_dec_component_no_val({ext,_,_}, _, mandatory) ->
- emit({"asn1_NOVALUE"}).
-
+ emit(["asn1_NOVALUE"]).
+
+dec_map_extaddgroup_no_val(Ext, Type, Comp) ->
+ L0 = [dec_map_extaddgroup_no_val_1(N, P, Ext, Type) ||
+ #'ComponentType'{name=N,prop=P} <- Comp],
+ L = [E || E <- L0, E =/= []],
+ emit(["#{",lists:join(",", L),"}"]).
+
+dec_map_extaddgroup_no_val_1(Name, {'DEFAULT',DefVal0}, _Ext, Type) ->
+ DefVal = asn1ct_gen:conform_value(Type, DefVal0),
+ [Name,"=>",{asis,DefVal}];
+dec_map_extaddgroup_no_val_1(_Name, 'OPTIONAL', _, _) ->
+ [];
+dec_map_extaddgroup_no_val_1(_Name, mandatory, {ext,_,_}, _) ->
+ [].
gen_dec_choice_line(Erule, TopType, Comp, Pre) ->
Imm0 = gen_dec_line_imm(Erule, TopType, Comp, false, Pre),
@@ -1461,29 +1640,29 @@ gen_dec_line_special(Erule, {typefield,_}, _TopType, Comp,
Prop}],PrevSt}
end
end;
-gen_dec_line_special(Erule, Atype, TopType, Comp, DecInfObj) ->
- case gen_dec_line_other(Erule, Atype, TopType, Comp) of
+gen_dec_line_special(Gen, Atype, TopType, Comp, DecInfObj) ->
+ case gen_dec_line_other(Gen, Atype, TopType, Comp) of
Fun when is_function(Fun, 1) ->
fun({BytesVar,PrevSt}) ->
Fun(BytesVar),
- gen_dec_line_dec_inf(Comp, DecInfObj),
+ gen_dec_line_dec_inf(Gen,Comp, DecInfObj),
{[],PrevSt}
end;
Imm0 ->
{imm,Imm0,
fun(Imm, {BytesVar,PrevSt}) ->
asn1ct_imm:dec_code_gen(Imm, BytesVar),
- gen_dec_line_dec_inf(Comp, DecInfObj),
+ gen_dec_line_dec_inf(Gen, Comp, DecInfObj),
{[],PrevSt}
end}
end.
-gen_dec_line_dec_inf(Comp, DecInfObj) ->
+gen_dec_line_dec_inf(Gen, Comp, DecInfObj) ->
#'ComponentType'{name=Cname} = Comp,
case DecInfObj of
{Cname,{_,_OSet,_UniqueFName,ValIndex}} ->
Term = asn1ct_gen:mk_var(asn1ct_name:curr(term)),
- ValueMatch = value_match(ValIndex,Term),
+ ValueMatch = value_match(Gen, ValIndex,Term),
emit([",",nl,
"ObjFun = ",ValueMatch]);
_ ->
@@ -1508,16 +1687,15 @@ gen_dec_line_other(Erule, Atype, TopType, Comp) ->
end;
{constructed,bif} ->
NewTypename = [Cname|TopType],
+ DecFunc = dec_func(asn1ct_gen:list2name(NewTypename)),
case Type#type.tablecinf of
[{objfun,_}|_R] ->
fun(BytesVar) ->
- emit({"'dec_",asn1ct_gen:list2name(NewTypename),
- "'(",BytesVar,", ObjFun)"})
+ emit([{asis,DecFunc},"(",BytesVar,", ObjFun)"])
end;
_ ->
fun(BytesVar) ->
- emit({"'dec_",asn1ct_gen:list2name(NewTypename),
- "'(",BytesVar,")"})
+ emit([{asis,DecFunc},"(",BytesVar,")"])
end
end
end.
@@ -1705,20 +1883,17 @@ gen_dec_choice2(Erule, TopType, [H0|T], Pos, Sep0, Pre) ->
gen_dec_choice2(Erule, TopType, T, Pos+1, Sep, Pre);
gen_dec_choice2(_, _, [], _, _, _) -> ok.
-make_elements(I,Val,ExtCnames) ->
- make_elements(I,Val,ExtCnames,[]).
+get_input_vars(Val, I, N) ->
+ L = get_input_vars_1(Val, I, N),
+ lists:join(",", L).
-make_elements(I,Val,[_ExtCname],Acc)-> % the last one, no comma needed
- Element = make_element(I, Val),
- make_elements(I+1,Val,[],[Element|Acc]);
-make_elements(I,Val,[_ExtCname|Rest],Acc)->
- Element = make_element(I, Val),
- make_elements(I+1,Val,Rest,[", ",Element|Acc]);
-make_elements(_I,_,[],Acc) ->
- lists:reverse(Acc).
+get_input_vars_1(_Val, _I, 0) ->
+ [];
+get_input_vars_1(Val, I, N) ->
+ [get_input_var(Val, I)|get_input_vars_1(Val, I+1, N-1)].
-make_element(I, Val) ->
- lists:flatten(io_lib:format("element(~w, ~s)", [I,Val])).
+get_input_var(Val, I) ->
+ lists:flatten(io_lib:format("element(~w, ~s)", [I+1,Val])).
emit_extaddgroupTerms(VarSeries,[_]) ->
asn1ct_name:new(VarSeries),
@@ -1726,7 +1901,7 @@ emit_extaddgroupTerms(VarSeries,[_]) ->
ok;
emit_extaddgroupTerms(VarSeries,[_|Rest]) ->
asn1ct_name:new(VarSeries),
- emit({{curr,VarSeries},","}),
+ emit([{curr,VarSeries},","]),
emit_extaddgroupTerms(VarSeries,Rest);
emit_extaddgroupTerms(_,[]) ->
ok.
@@ -1735,63 +1910,79 @@ flat_complist({Rl1,El,Rl2}) -> Rl1 ++ El ++ Rl2;
flat_complist({Rl,El}) -> Rl ++ El;
flat_complist(CompList) -> CompList.
-%%wrap_compList({Root1,Ext,Root2}) ->
-%% {Root1,wrap_extensionAdditionGroups(Ext),Root2};
-%%wrap_compList({Root1,Ext}) ->
-%% {Root1,wrap_extensionAdditionGroups(Ext)};
-%%wrap_compList(CompList) ->
-%% CompList.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Will convert all componentTypes following 'ExtensionAdditionGroup'
+%% Convert all componentTypes following 'ExtensionAdditionGroup'
%% up to the matching 'ExtensionAdditionGroupEnd' into one componentType
-%% of type SEQUENCE with the componentTypes as components
+%% of type SEQUENCE with the componentTypes as components.
%%
-wrap_extensionAdditionGroups(ExtCompList,ExtGroupPosLen) ->
- wrap_extensionAdditionGroups(ExtCompList,ExtGroupPosLen,[],0,0).
+wrap_extensionAdditionGroups(ExtCompList, ExtGroupPosLen) ->
+ wrap_eags(ExtCompList, ExtGroupPosLen, 0, 0).
-wrap_extensionAdditionGroups([{'ExtensionAdditionGroup',_Number}|Rest],
- [{ActualPos,_,_}|ExtGroupPosLenRest],Acc,_ExtAddGroupDiff,ExtGroupNum) ->
- {ExtGroupCompList,['ExtensionAdditionGroupEnd'|Rest2]} =
+wrap_eags([{'ExtensionAdditionGroup',_Number}|T0],
+ [{ActualPos,_,_}|Gs], _ExtAddGroupDiff, ExtGroupNum) ->
+ {ExtGroupCompList,['ExtensionAdditionGroupEnd'|T]} =
lists:splitwith(fun(#'ComponentType'{}) -> true;
(_) -> false
- end,
- Rest),
- wrap_extensionAdditionGroups(Rest2,ExtGroupPosLenRest,
- [#'ComponentType'{
- name=list_to_atom("ExtAddGroup"++
- integer_to_list(ExtGroupNum+1)),
- typespec=#type{def=#'SEQUENCE'{
- extaddgroup=ExtGroupNum+1,
- components=ExtGroupCompList}},
- textual_order = ActualPos,
- prop='OPTIONAL'}|Acc],length(ExtGroupCompList)-1,
- ExtGroupNum+1);
-wrap_extensionAdditionGroups([H=#'ComponentType'{textual_order=Tord}|T],
- ExtAddGrpLenPos,Acc,ExtAddGroupDiff,ExtGroupNum) when is_integer(Tord) ->
- wrap_extensionAdditionGroups(T,ExtAddGrpLenPos,[H#'ComponentType'{
- textual_order=Tord - ExtAddGroupDiff}|Acc],ExtAddGroupDiff,ExtGroupNum);
-wrap_extensionAdditionGroups([H|T],ExtAddGrpLenPos,Acc,ExtAddGroupDiff,ExtGroupNum) ->
- wrap_extensionAdditionGroups(T,ExtAddGrpLenPos,[H|Acc],ExtAddGroupDiff,ExtGroupNum);
-wrap_extensionAdditionGroups([],_,Acc,_,_) ->
- lists:reverse(Acc).
-
-value_match(Index,Value) when is_atom(Value) ->
- value_match(Index,atom_to_list(Value));
-value_match([],Value) ->
+ end, T0),
+ Name = list_to_atom(lists:concat(["ExtAddGroup",ExtGroupNum+1])),
+ Seq = #type{def=#'SEQUENCE'{extaddgroup=ExtGroupNum+1,
+ components=ExtGroupCompList}},
+ Comp = #'ComponentType'{name=Name,
+ typespec=Seq,
+ textual_order=ActualPos,
+ prop='OPTIONAL'},
+ [Comp|wrap_eags(T, Gs, length(ExtGroupCompList)-1, ExtGroupNum+1)];
+wrap_eags([#'ComponentType'{textual_order=Tord}=H|T],
+ ExtAddGrpLenPos, ExtAddGroupDiff, ExtGroupNum)
+ when is_integer(Tord) ->
+ Comp = H#'ComponentType'{textual_order=Tord - ExtAddGroupDiff},
+ [Comp|wrap_eags(T, ExtAddGrpLenPos, ExtAddGroupDiff, ExtGroupNum)];
+wrap_eags([H|T], ExtAddGrpLenPos, ExtAddGroupDiff, ExtGroupNum) ->
+ [H|wrap_eags(T, ExtAddGrpLenPos, ExtAddGroupDiff, ExtGroupNum)];
+wrap_eags([], _, _, _) ->
+ [].
+
+value_match(#gen{pack=record}, VIs, Value) ->
+ value_match_rec(VIs, Value);
+value_match(#gen{pack=map}, VIs, Value) ->
+ value_match_map(VIs, Value).
+
+value_match_rec([], Value) ->
+ Value;
+value_match_rec([{VI,_}|VIs], Value0) ->
+ Value = value_match_rec(VIs, Value0),
+ lists:concat(["element(",VI,", ",Value,")"]).
+
+value_match_map([], Value) ->
Value;
-value_match([{VI,_}|VIs],Value) ->
- value_match1(Value,VIs,lists:concat(["element(",VI,","]),1).
-value_match1(Value,[],Acc,Depth) ->
- Acc ++ Value ++ lists:concat(lists:duplicate(Depth,")"));
-value_match1(Value,[{VI,_}|VIs],Acc,Depth) ->
- value_match1(Value,VIs,Acc++lists:concat(["element(",VI,","]),Depth+1).
-
-enc_dig_out_value([], Value) ->
+value_match_map([{_,Name}|VIs], Value0) ->
+ Value = value_match_map(VIs, Value0),
+ lists:concat(["maps:get(",Name,", ",Value,")"]).
+
+enc_dig_out_value(_Gen, [], Value) ->
{[],Value};
-enc_dig_out_value([{N,_}|T], Value) ->
- {Imm0,Dst0} = enc_dig_out_value(T, Value),
+enc_dig_out_value(#gen{pack=record}=Gen, [{N,_}|T], Value) ->
+ {Imm0,Dst0} = enc_dig_out_value(Gen, T, Value),
{Imm,Dst} = asn1ct_imm:enc_element(N, Dst0),
+ {Imm0++Imm,Dst};
+enc_dig_out_value(#gen{pack=map}, [{N,'ASN1_top'}], _Value) ->
+ {[],{var,lists:concat(["Input@",N-1])}};
+enc_dig_out_value(#gen{pack=map}=Gen, [{_,Name}|T], Value) ->
+ {Imm0,Dst0} = enc_dig_out_value(Gen, T, Value),
+ {Imm,Dst} = asn1ct_imm:enc_maps_get(Name, Dst0),
{Imm0++Imm,Dst}.
make_var(Base) ->
{var,atom_to_list(asn1ct_gen:mk_var(asn1ct_name:curr(Base)))}.
+
+attribute_comment(InnerType, TextPos, Cname) ->
+ DispType = case InnerType of
+ #'Externaltypereference'{type=T} -> T;
+ IT when is_tuple(IT) -> element(2,IT);
+ _ -> InnerType
+ end,
+ Comment = ["attribute ",Cname,"(",TextPos,") with type ",DispType],
+ lists:concat(Comment).
+
+dec_func(Tname) ->
+ list_to_atom(lists:concat(["dec_",Tname])).
diff --git a/lib/asn1/src/asn1ct_eval_ext.funcs b/lib/asn1/src/asn1ct_eval_ext.funcs
index 5761901f89..01c67e7b5a 100644
--- a/lib/asn1/src/asn1ct_eval_ext.funcs
+++ b/lib/asn1/src/asn1ct_eval_ext.funcs
@@ -1 +1,2 @@
{ext,transform_to_EXTERNAL1994,1}.
+{ext,transform_to_EXTERNAL1994_maps,1}.
diff --git a/lib/asn1/src/asn1ct_func.erl b/lib/asn1/src/asn1ct_func.erl
index 0cd72acf9d..b2ce93c17f 100644
--- a/lib/asn1/src/asn1ct_func.erl
+++ b/lib/asn1/src/asn1ct_func.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -65,7 +65,7 @@ generate(Fd) ->
Funcs = sofs:to_external(Funcs0),
ok = file:write(Fd, Funcs).
-is_used({_,_,_}=MFA) ->
+is_used({M,F,A}=MFA) when is_atom(M), is_atom(F), is_integer(A) ->
req({is_used,MFA}).
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index bfaffa13bf..838d59a512 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,8 +22,7 @@
-include("asn1_records.hrl").
--export([demit/1,
- emit/1,
+-export([emit/1,
open_output_file/1,close_output_file/0,
get_inner/1,type/1,def_to_tag/1,prim_bif/1,
list2name/1,
@@ -34,10 +33,10 @@
insert_once/2,
ct_gen_module/1,
index2suffix/1,
- get_record_name_prefix/0,
+ get_record_name_prefix/1,
conform_value/2,
named_bitstring_value/2]).
--export([pgen/5,
+-export([pgen/3,
mk_var/1,
un_hyphen_var/1]).
-export([gen_encode_constructed/4,
@@ -45,23 +44,19 @@
-define(SUPPRESSION_FUNC, 'dialyzer-suppressions').
+
%% pgen(Outfile, Erules, Module, TypeOrVal, Options)
-%% Generate Erlang module (.erl) and (.hrl) file corresponding to an ASN.1 module
-%% .hrl file is only generated if necessary
-%% Erules = per | ber
-%% Module = atom()
-%% TypeOrVal = {TypeList,ValueList}
-%% TypeList = ValueList = [atom()]
-%% Options = [Options] from asn1ct:compile()
-
-pgen(OutFile,Erules,Module,TypeOrVal,Options) ->
- pgen_module(OutFile,Erules,Module,TypeOrVal,Options,true).
-
-
-pgen_module(OutFile,Erules,Module,
- TypeOrVal = {Types,_Values,_Ptypes,_Classes,_Objects,_ObjectSets},
- Options,Indent) ->
- N2nConvEnums = [CName|| {n2n,CName} <- get(encoding_options)],
+%% Generate Erlang module (.erl) and (.hrl) file corresponding to
+%% an ASN.1 module. The .hrl file is only generated if necessary.
+
+-spec pgen(Outfile, Gen, Code) -> 'ok' when
+ Outfile :: any(),
+ Gen :: #gen{},
+ Code :: #abst{}.
+
+pgen(OutFile, #gen{options=Options}=Gen, Code) ->
+ #abst{name=Module,types=Types} = Code,
+ N2nConvEnums = [CName|| {n2n,CName} <- Options],
case N2nConvEnums -- Types of
[] ->
ok;
@@ -69,30 +64,30 @@ pgen_module(OutFile,Erules,Module,
exit({"Non existing ENUMERATION types used in n2n option",
UnmatchedTypes})
end,
- put(outfile,OutFile),
- HrlGenerated = pgen_hrl(Erules,Module,TypeOrVal,Options,Indent),
+ put(outfile, OutFile),
+ put(currmod, Module),
+ HrlGenerated = pgen_hrl(Gen, Code),
asn1ct_name:start(),
ErlFile = lists:concat([OutFile,".erl"]),
_ = open_output_file(ErlFile),
asn1ct_func:start_link(),
- gen_head(Erules,Module,HrlGenerated),
- pgen_exports(Erules,Module,TypeOrVal),
- pgen_dispatcher(Erules,Module,TypeOrVal),
+ gen_head(Gen, Module, HrlGenerated),
+ pgen_exports(Gen, Code),
+ pgen_dispatcher(Gen, Types),
pgen_info(),
- pgen_typeorval(Erules,Module,N2nConvEnums,TypeOrVal),
- pgen_partial_incomplete_decode(Erules),
-% gen_vars(asn1_db:mod_to_vars(Module)),
-% gen_tag_table(AllTypes),
+ pgen_typeorval(Gen, N2nConvEnums, Code),
+ pgen_partial_incomplete_decode(Gen),
emit([nl,
"%%%",nl,
"%%% Run-time functions.",nl,
"%%%",nl]),
- dialyzer_suppressions(Erules),
+ dialyzer_suppressions(Gen),
Fd = get(gen_file_out),
asn1ct_func:generate(Fd),
close_output_file(),
_ = erase(outfile),
- asn1ct:verbose("--~p--~n",[{generated,ErlFile}],Options).
+ asn1ct:verbose("--~p--~n", [{generated,ErlFile}], Gen),
+ ok.
dialyzer_suppressions(Erules) ->
emit([nl,
@@ -100,20 +95,27 @@ dialyzer_suppressions(Erules) ->
Rtmod = ct_gen_module(Erules),
Rtmod:dialyzer_suppressions(Erules).
-pgen_typeorval(Erules,Module,N2nConvEnums,{Types,Values,_Ptypes,_Classes,Objects,ObjectSets}) ->
+pgen_typeorval(Erules, N2nConvEnums, Code) ->
+ #abst{name=Module,types=Types,values=Values,
+ objects=Objects,objsets=ObjectSets} = Code,
Rtmod = ct_gen_module(Erules),
pgen_types(Rtmod,Erules,N2nConvEnums,Module,Types),
- pgen_values(Erules,Module,Values),
+ pgen_values(Values, Module),
pgen_objects(Rtmod,Erules,Module,Objects),
pgen_objectsets(Rtmod,Erules,Module,ObjectSets),
pgen_partial_decode(Rtmod,Erules,Module).
-pgen_values(_,_,[]) ->
- true;
-pgen_values(Erules,Module,[H|T]) ->
- Valuedef = asn1_db:dbget(Module,H),
- gen_value(Valuedef),
- pgen_values(Erules,Module,T).
+%% Generate a function 'V'/0 for each Value V defined in the ASN.1 module.
+%% The function returns the value in an Erlang representation which can be
+%% used as input to the runtime encode functions.
+
+pgen_values([H|T], Module) ->
+ #valuedef{name=Name,value=Value} = asn1_db:dbget(Module, H),
+ emit([{asis,Name},"() ->",nl,
+ {asis,Value},".",nl,nl]),
+ pgen_values(T, Module);
+pgen_values([], _) ->
+ ok.
pgen_types(_, _, _, _, []) ->
true;
@@ -181,20 +183,16 @@ pgen_objectsets(Rtmod,Erules,Module,[H|T]) ->
Rtmod:gen_objectset_code(Erules,TypeDef),
pgen_objectsets(Rtmod,Erules,Module,T).
-pgen_partial_decode(Rtmod,Erule,Module) when Erule == ber ->
- pgen_partial_inc_dec(Rtmod,Erule,Module),
- pgen_partial_dec(Rtmod,Erule,Module);
-pgen_partial_decode(_,_,_) ->
+pgen_partial_decode(Rtmod, #gen{erule=ber}=Gen, Module) ->
+ pgen_partial_inc_dec(Rtmod, Gen, Module),
+ pgen_partial_dec(Rtmod, Gen, Module);
+pgen_partial_decode(_, _, _) ->
ok.
pgen_partial_inc_dec(Rtmod,Erules,Module) ->
-% io:format("Start partial incomplete decode gen?~n"),
case asn1ct:get_gen_state_field(inc_type_pattern) of
undefined ->
-% io:format("Partial incomplete decode gen not started: ~w~n",[asn1ct:get_gen_state_field(active)]),
ok;
-% [] ->
-% ok;
ConfList ->
PatternLists=lists:map(fun({_,P}) -> P end,ConfList),
pgen_partial_inc_dec1(Rtmod,Erules,Module,PatternLists),
@@ -212,11 +210,9 @@ pgen_partial_inc_dec1(Rtmod,Erules,Module,[P|Ps]) ->
asn1ct:update_gen_state(prefix,"dec-inc-"),
case asn1ct:maybe_saved_sindex(TopTypeName,P) of
I when is_integer(I),I > 0 ->
-% io:format("Index:~p~n",[I]),
asn1ct:set_current_sindex(I);
_I ->
asn1ct:set_current_sindex(0),
-% io:format("Index=~p~n",[_I]),
ok
end,
Rtmod:gen_decode(Erules,TypeDef),
@@ -225,7 +221,7 @@ pgen_partial_inc_dec1(Rtmod,Erules,Module,[P|Ps]) ->
pgen_partial_inc_dec1(_,_,_,[]) ->
ok.
-gen_partial_inc_dec_refed_funcs(Rtmod,Erule) when Erule == ber ->
+gen_partial_inc_dec_refed_funcs(Rtmod, #gen{erule=ber}=Gen) ->
case asn1ct:next_refed_func() of
[] ->
ok;
@@ -233,39 +229,36 @@ gen_partial_inc_dec_refed_funcs(Rtmod,Erule) when Erule == ber ->
TypeDef = asn1_db:dbget(M,Name),
asn1ct:update_gen_state(namelist,Pattern),
asn1ct:set_current_sindex(Sindex),
- Rtmod:gen_inc_decode(Erule,TypeDef),
- gen_dec_part_inner_constr(Rtmod,Erule,TypeDef,[Name]),
- gen_partial_inc_dec_refed_funcs(Rtmod,Erule);
+ Rtmod:gen_inc_decode(Gen, TypeDef),
+ gen_dec_part_inner_constr(Rtmod, Gen, TypeDef, [Name]),
+ gen_partial_inc_dec_refed_funcs(Rtmod, Gen);
{Name,Sindex,Pattern,Type} ->
TypeDef=#typedef{name=asn1ct_gen:list2name(Name),typespec=Type},
asn1ct:update_gen_state(namelist,Pattern),
asn1ct:set_current_sindex(Sindex),
- Rtmod:gen_inc_decode(Erule,TypeDef),
- gen_dec_part_inner_constr(Rtmod,Erule,TypeDef,Name),
- gen_partial_inc_dec_refed_funcs(Rtmod,Erule)
- end;
-gen_partial_inc_dec_refed_funcs(_,_) ->
- ok.
+ Rtmod:gen_inc_decode(Gen, TypeDef),
+ gen_dec_part_inner_constr(Rtmod, Gen, TypeDef, Name),
+ gen_partial_inc_dec_refed_funcs(Rtmod, Gen)
+ end.
pgen_partial_dec(_Rtmod,Erules,_Module) ->
Type_pattern = asn1ct:get_gen_state_field(type_pattern),
-% io:format("Type_pattern: ~w~n",[Type_pattern]),
- %% Get the typedef of the top type and follow into the choosen components until the last type/component.
+ %% Get the typedef of the top type and follow into the choosen
+ %% components until the last type/component.
pgen_partial_types(Erules,Type_pattern),
ok.
-pgen_partial_types(Erules,Type_pattern) ->
- % until this functionality works on all back-ends
- Options = get(encoding_options),
- case lists:member(asn1config,Options) of
+pgen_partial_types(#gen{options=Options}=Gen, TypePattern) ->
+ %% until this functionality works on all back-ends
+ case lists:member(asn1config, Options) of
true ->
- pgen_partial_types1(Erules,Type_pattern);
- _ -> ok
+ pgen_partial_types1(Gen, TypePattern);
+ false ->
+ ok
end.
-
+
pgen_partial_types1(Erules,[{FuncName,[TopType|RestTypes]}|Rest]) ->
-% emit([FuncName,"(Bytes) ->",nl]),
CurrMod = get(currmod),
TypeDef = asn1_db:dbget(CurrMod,TopType),
traverse_type_structure(Erules,TypeDef,RestTypes,FuncName,
@@ -290,8 +283,9 @@ traverse_type_structure(Erules,Type,[],FuncName,TopTypeName) ->
end,
Ctmod:gen_decode_selected(Erules,TypeDef,FuncName); % what if Type is #type{}
traverse_type_structure(Erules,#type{def=Def},[[N]],FuncName,TopTypeName)
- when is_integer(N) -> % this case a decode of one of the elements in
- % the SEQUENCE OF is required.
+ when is_integer(N) ->
+ %% In this case a decode of one of the elements in the SEQUENCE OF is
+ %% required.
InnerType = asn1ct_gen:get_inner(Def),
case InnerType of
'SEQUENCE OF' ->
@@ -367,8 +361,9 @@ traverse_type_structure(Erules,#typedef{typespec=Def},[T|Ts],FuncName,
TypeDef = asn1_db:dbget(M,TName),
traverse_type_structure(Erules,TypeDef,[T|Ts],FuncName,
[TypeDef#typedef.name]);
- _ -> %this may be a referenced type that shall be traversed or
- %the selected type
+ _ ->
+ %% This may be a referenced type that shall be traversed
+ %% or the selected type
traverse_type_structure(Erules,Def,Ts,FuncName,[T|TopTypeName])
end.
@@ -383,9 +378,7 @@ get_component(Name,{C1,C2}) when is_list(C1),is_list(C2) ->
get_component(Name,[C=#'ComponentType'{name=Name}|_Cs]) ->
C;
get_component(Name,[_C|Cs]) ->
- get_component(Name,Cs);
-get_component(Name,_) ->
- throw({error,{asn1,{internal_error,Name}}}).
+ get_component(Name,Cs).
%% generate code for all inner types that are called from the top type
%% of the partial incomplete decode and are defined within the top
@@ -441,7 +434,8 @@ pgen_partial_incomplete_decode(Erule) ->
_ ->
ok
end.
-pgen_partial_incomplete_decode1(ber) ->
+
+pgen_partial_incomplete_decode1(#gen{erule=ber}) ->
case asn1ct:read_config_data(partial_incomplete_decode) of
undefined ->
ok;
@@ -449,9 +443,8 @@ pgen_partial_incomplete_decode1(ber) ->
lists:foreach(fun emit_partial_incomplete_decode/1,Data)
end,
GeneratedFs= asn1ct:get_gen_state_field(gen_refed_funcs),
-% io:format("GeneratedFs :~n~p~n",[GeneratedFs]),
gen_part_decode_funcs(GeneratedFs,0);
-pgen_partial_incomplete_decode1(_) -> ok.
+pgen_partial_incomplete_decode1(#gen{}) -> ok.
emit_partial_incomplete_decode({FuncName,TopType,Pattern}) ->
TypePattern = asn1ct:get_gen_state_field(inc_type_pattern),
@@ -578,18 +571,6 @@ un_hyphen_var([H|T]) ->
un_hyphen_var([]) ->
[].
-%% Generate value functions ***************
-%% ****************************************
-%% Generates a function 'V'/0 for each Value V defined in the ASN.1 module
-%% the function returns the value in an Erlang representation which can be
-%% used as input to the runtime encode functions
-
-gen_value(Value) when is_record(Value,valuedef) ->
-%% io:format(" ~w ",[Value#valuedef.name]),
- emit({"'",Value#valuedef.name,"'() ->",nl}),
- V = Value#valuedef.value,
- emit([{asis,V},".",nl,nl]).
-
gen_encode_constructed(Erules,Typename,InnerType,D) when is_record(D,type) ->
Rtmod = ct_constructed_module(Erules),
case InnerType of
@@ -614,9 +595,7 @@ gen_encode_constructed(Erules,Typename,InnerType,D) when is_record(D,type) ->
Rtmod:gen_encode_sof(Erules,Typename,InnerType,D),
{_,Type} = D#type.def,
NameSuffix = asn1ct_gen:constructed_suffix(InnerType,Type#type.def),
- gen_types(Erules, [NameSuffix|Typename], Type, gen_encode);
- _ ->
- exit({nyi,InnerType})
+ gen_types(Erules, [NameSuffix|Typename], Type, gen_encode)
end;
gen_encode_constructed(Erules,Typename,InnerType,D)
when is_record(D,typedef) ->
@@ -654,78 +633,32 @@ gen_decode_constructed(Erules,Typename,InnerType,D) when is_record(D,typedef) ->
gen_decode_constructed(Erules,Typename,InnerType,D#typedef.typespec).
-pgen_exports(Erules,_Module,{Types,Values,_,_,Objects,ObjectSets}) ->
- emit(["-export([encoding_rule/0,bit_string_format/0,",nl,
+pgen_exports(#gen{options=Options}=Gen, Code) ->
+ #abst{types=Types,values=Values,objects=Objects,objsets=ObjectSets} = Code,
+ emit(["-export([encoding_rule/0,maps/0,bit_string_format/0,",nl,
" legacy_erlang_types/0]).",nl]),
emit(["-export([",{asis,?SUPPRESSION_FUNC},"/1]).",nl]),
- case Types of
- [] -> ok;
- _ ->
- emit({"-export([",nl}),
- case Erules of
- ber ->
- gen_exports1(Types,"enc_",2);
- _ ->
- gen_exports1(Types,"enc_",1)
- end,
- emit({"-export([",nl}),
- case Erules of
- ber ->
- gen_exports1(Types, "dec_", 2);
- _ ->
- gen_exports1(Types, "dec_", 1)
- end
- end,
- case [X || {n2n,X} <- get(encoding_options)] of
- [] -> ok;
- A2nNames ->
- emit({"-export([",nl}),
- gen_exports1(A2nNames,"name2num_",1),
- emit({"-export([",nl}),
- gen_exports1(A2nNames,"num2name_",1)
- end,
- case Values of
- [] -> ok;
- _ ->
- emit({"-export([",nl}),
- gen_exports1(Values,"",0)
+ case Gen of
+ #gen{erule=ber} ->
+ gen_exports(Types, "enc_", 2),
+ gen_exports(Types, "dec_", 2),
+ gen_exports(Objects, "enc_", 3),
+ gen_exports(Objects, "dec_", 3),
+ gen_exports(ObjectSets, "getenc_", 1),
+ gen_exports(ObjectSets, "getdec_", 1);
+ #gen{erule=per} ->
+ gen_exports(Types, "enc_", 1),
+ gen_exports(Types, "dec_", 1)
end,
- case Objects of
- [] -> ok;
- _ ->
- case erule(Erules) of
- per ->
- ok;
- ber ->
- emit({"-export([",nl}),
- gen_exports1(Objects,"enc_",3),
- emit({"-export([",nl}),
- gen_exports1(Objects,"dec_",3)
- end
- end,
- case ObjectSets of
- [] -> ok;
- _ ->
- case erule(Erules) of
- per ->
- ok;
- ber ->
- emit({"-export([",nl}),
- gen_exports1(ObjectSets, "getenc_",1),
- emit({"-export([",nl}),
- gen_exports1(ObjectSets, "getdec_",1)
- end
- end,
- emit({"-export([info/0]).",nl}),
- gen_partial_inc_decode_exports(),
- gen_selected_decode_exports(),
- emit({nl,nl}).
-gen_exports1([F1,F2|T],Prefix,Arity) ->
- emit({"'",Prefix,F1,"'/",Arity,com,nl}),
- gen_exports1([F2|T],Prefix,Arity);
-gen_exports1([Flast|_T],Prefix,Arity) ->
- emit({"'",Prefix,Flast,"'/",Arity,nl,"]).",nl,nl}).
+ A2nNames = [X || {n2n,X} <- Options],
+ gen_exports(A2nNames, "name2num_", 1),
+ gen_exports(A2nNames, "num2name_", 1),
+
+ gen_exports(Values, "", 0),
+ emit(["-export([info/0]).",nl,nl]),
+ gen_partial_inc_decode_exports(),
+ gen_selected_decode_exports().
gen_partial_inc_decode_exports() ->
case {asn1ct:read_config_data(partial_incomplete_decode),
@@ -734,66 +667,54 @@ gen_partial_inc_decode_exports() ->
ok;
{_,undefined} ->
ok;
- {Data,_} ->
- gen_partial_inc_decode_exports(Data),
- emit(["-export([decode_part/2]).",nl])
+ {Data0,_} ->
+ Data = [Name || {Name,_,_} <- Data0],
+ gen_exports(Data, "", 1),
+ emit(["-export([decode_part/2]).",nl,nl])
end.
-gen_partial_inc_decode_exports([]) ->
- ok;
-gen_partial_inc_decode_exports([{Name,_,_}|Rest]) ->
- emit(["-export([",Name,"/1"]),
- gen_partial_inc_decode_exports1(Rest);
-gen_partial_inc_decode_exports([_|Rest]) ->
- gen_partial_inc_decode_exports(Rest).
-
-gen_partial_inc_decode_exports1([]) ->
- emit(["]).",nl]);
-gen_partial_inc_decode_exports1([{Name,_,_}|Rest]) ->
- emit([", ",Name,"/1"]),
- gen_partial_inc_decode_exports1(Rest);
-gen_partial_inc_decode_exports1([_|Rest]) ->
- gen_partial_inc_decode_exports1(Rest).
gen_selected_decode_exports() ->
case asn1ct:get_gen_state_field(type_pattern) of
undefined ->
ok;
- L ->
- gen_selected_decode_exports(L)
+ Data0 ->
+ Data = [Name || {Name,_} <- Data0],
+ gen_exports(Data, "", 1)
end.
-gen_selected_decode_exports([]) ->
+gen_exports([], _Prefix, _Arity) ->
ok;
-gen_selected_decode_exports([{FuncName,_}|Rest]) ->
- emit(["-export([",FuncName,"/1"]),
- gen_selected_decode_exports1(Rest).
-gen_selected_decode_exports1([]) ->
- emit(["]).",nl,nl]);
-gen_selected_decode_exports1([{FuncName,_}|Rest]) ->
- emit([",",nl," ",FuncName,"/1"]),
- gen_selected_decode_exports1(Rest).
-
-pgen_dispatcher(Erules,_Module,{[],_Values,_,_,_Objects,_ObjectSets}) ->
+gen_exports([_|_]=L0, Prefix, Arity) ->
+ FF = fun(F0) ->
+ F = list_to_atom(lists:concat([Prefix,F0])),
+ [{asis,F},"/",Arity]
+ end,
+ L = lists:join(",\n", [FF(F) || F <- L0]),
+ emit(["-export([",nl,
+ L,nl,
+ "]).",nl,nl]).
+
+pgen_dispatcher(Erules, []) ->
gen_info_functions(Erules);
-pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) ->
+pgen_dispatcher(Gen, Types) ->
emit(["-export([encode/2,decode/2]).",nl,nl]),
- gen_info_functions(Erules),
+ gen_info_functions(Gen),
- Options = get(encoding_options),
+ Options = Gen#gen.options,
NoFinalPadding = lists:member(no_final_padding, Options),
NoOkWrapper = proplists:get_bool(no_ok_wrapper, Options),
- Call = case Erules of
- per ->
- asn1ct_func:need({Erules,complete,1}),
+ Call = case Gen of
+ #gen{erule=per,aligned=true} ->
+ asn1ct_func:need({per,complete,1}),
"complete(encode_disp(Type, Data))";
- ber ->
+ #gen{erule=ber} ->
"iolist_to_binary(element(1, encode_disp(Type, Data)))";
- uper when NoFinalPadding == true ->
- asn1ct_func:need({Erules,complete_NFP,1}),
+ #gen{erule=per,aligned=false} when NoFinalPadding ->
+ asn1ct_func:need({uper,complete_NFP,1}),
"complete_NFP(encode_disp(Type, Data))";
- uper ->
- asn1ct_func:need({Erules,complete,1}),
+ #gen{erule=per,aligned=false} ->
+ asn1ct_func:need({uper,complete,1}),
"complete(encode_disp(Type, Data))"
end,
@@ -809,36 +730,36 @@ pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) ->
end,
emit([nl,nl]),
- Return_rest = proplists:get_bool(undec_rest, Options),
- Data = case {Erules,Return_rest} of
- {ber,true} -> "Data0";
- _ -> "Data"
+ ReturnRest = proplists:get_bool(undec_rest, Gen#gen.options),
+ Data = case Gen#gen.erule =:= ber andalso ReturnRest of
+ true -> "Data0";
+ false -> "Data"
end,
- emit(["decode(Type,",Data,") ->",nl]),
+ emit(["decode(Type, ",Data,") ->",nl]),
DecWrap =
- case {Erules,Return_rest} of
- {ber,false} ->
+ case {Gen,ReturnRest} of
+ {#gen{erule=ber},false} ->
asn1ct_func:need({ber,ber_decode_nif,1}),
"element(1, ber_decode_nif(Data))";
- {ber,true} ->
+ {#gen{erule=ber},true} ->
asn1ct_func:need({ber,ber_decode_nif,1}),
emit(["{Data,Rest} = ber_decode_nif(Data0),",nl]),
"Data";
- _ ->
+ {_,_} ->
"Data"
end,
emit([case NoOkWrapper of
false -> "try";
true -> "case"
end, " decode_disp(Type, ",DecWrap,") of",nl]),
- case erule(Erules) of
- ber ->
+ case Gen of
+ #gen{erule=ber} ->
emit([" Result ->",nl]);
- per ->
+ #gen{erule=per} ->
emit([" {Result,Rest} ->",nl])
end,
- case Return_rest of
+ case ReturnRest of
false -> result_line(NoOkWrapper, ["Result"]);
true -> result_line(NoOkWrapper, ["Result","Rest"])
end,
@@ -849,18 +770,11 @@ pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) ->
emit([nl,"end.",nl,nl])
end,
- gen_decode_partial_incomplete(Erules),
+ gen_decode_partial_incomplete(Gen),
+ gen_partial_inc_dispatcher(Gen),
- case Erules of
- ber ->
- gen_dispatcher(Types,"encode_disp","enc_",""),
- gen_dispatcher(Types,"decode_disp","dec_",""),
- gen_partial_inc_dispatcher();
- _PerOrPer_bin ->
- gen_dispatcher(Types,"encode_disp","enc_",""),
- gen_dispatcher(Types,"decode_disp","dec_","")
- end,
- emit([nl,nl]).
+ gen_dispatcher(Types, "encode_disp", "enc_"),
+ gen_dispatcher(Types, "decode_disp", "dec_").
result_line(NoOkWrapper, Items) ->
S = [" "|case NoOkWrapper of
@@ -877,23 +791,35 @@ result_line_1(Items) ->
try_catch() ->
[" catch",nl,
" Class:Exception when Class =:= error; Class =:= exit ->",nl,
+ " Stk = erlang:get_stacktrace(),",nl,
" case Exception of",nl,
- " {error,Reason}=Error ->",nl,
- " Error;",nl,
+ " {error,{asn1,Reason}} ->",nl,
+ " {error,{asn1,{Reason,Stk}}};",nl,
" Reason ->",nl,
- " {error,{asn1,Reason}}",nl,
+ " {error,{asn1,{Reason,Stk}}}",nl,
" end",nl,
"end."].
-gen_info_functions(Erules) ->
+gen_info_functions(Gen) ->
+ Erule = case Gen of
+ #gen{erule=ber} -> ber;
+ #gen{erule=per,aligned=false} -> uper;
+ #gen{erule=per,aligned=true} -> per
+ end,
+ Maps = case Gen of
+ #gen{pack=record} -> false;
+ #gen{pack=map} -> true
+ end,
emit(["encoding_rule() -> ",
- {asis,Erules},".",nl,nl,
+ {asis,Erule},".",nl,nl,
+ "maps() -> ",
+ {asis,Maps},".",nl,nl,
"bit_string_format() -> ",
{asis,asn1ct:get_bit_string_format()},".",nl,nl,
"legacy_erlang_types() -> ",
{asis,asn1ct:use_legacy_types()},".",nl,nl]).
-gen_decode_partial_incomplete(ber) ->
+gen_decode_partial_incomplete(#gen{erule=ber}) ->
case {asn1ct:read_config_data(partial_incomplete_decode),
asn1ct:get_gen_state_field(inc_type_pattern)} of
{undefined,_} ->
@@ -931,10 +857,10 @@ gen_decode_partial_incomplete(ber) ->
EmitCaseClauses(),
emit([".",nl,nl])
end;
-gen_decode_partial_incomplete(_Erule) ->
+gen_decode_partial_incomplete(#gen{}) ->
ok.
-gen_partial_inc_dispatcher() ->
+gen_partial_inc_dispatcher(#gen{erule=ber}) ->
case {asn1ct:read_config_data(partial_incomplete_decode),
asn1ct:get_gen_state_field(inc_type_pattern)} of
{undefined,_} ->
@@ -942,9 +868,10 @@ gen_partial_inc_dispatcher() ->
{_,undefined} ->
ok;
{Data1,Data2} ->
-% io:format("partial_incomplete_decode: ~p~ninc_type_pattern: ~p~n",[Data,Data2]),
gen_partial_inc_dispatcher(Data1, Data2, "")
- end.
+ end;
+gen_partial_inc_dispatcher(#gen{}) ->
+ ok.
gen_partial_inc_dispatcher([{FuncName,TopType,_Pattern}|Rest], TypePattern, Sep) ->
TPattern =
@@ -968,12 +895,18 @@ gen_partial_inc_dispatcher([{FuncName,TopType,_Pattern}|Rest], TypePattern, Sep)
gen_partial_inc_dispatcher([], _, _) ->
emit([".",nl]).
-gen_dispatcher([F1,F2|T],FuncName,Prefix,ExtraArg) ->
- emit([FuncName,"('",F1,"',Data) -> '",Prefix,F1,"'(Data",ExtraArg,")",";",nl]),
- gen_dispatcher([F2|T],FuncName,Prefix,ExtraArg);
-gen_dispatcher([Flast|_T],FuncName,Prefix,ExtraArg) ->
- emit([FuncName,"('",Flast,"',Data) -> '",Prefix,Flast,"'(Data",ExtraArg,")",";",nl]),
- emit([FuncName,"(","Type",",_Data) -> exit({error,{asn1,{undefined_type,Type}}}).",nl,nl,nl]).
+gen_dispatcher(L, DispFunc, Prefix) ->
+ gen_dispatcher_1(L, DispFunc, Prefix),
+ emit([DispFunc,"(","Type",", _Data) ->"
+ " exit({error,{asn1,{undefined_type,Type}}}).",nl,nl]).
+
+gen_dispatcher_1([F|T], FuncName, Prefix) ->
+ Func = list_to_atom(lists:concat([Prefix,F])),
+ emit([FuncName,"(",{asis,F},", Data) -> ",
+ {asis,Func},"(Data)",";",nl]),
+ gen_dispatcher_1(T, FuncName, Prefix);
+gen_dispatcher_1([], _, _) ->
+ ok.
pgen_info() ->
emit(["info() ->",nl,
@@ -1009,71 +942,39 @@ hrl_protector(OutFile) ->
end || C <- P].
-%% EMIT functions ************************
-%% ***************************************
-
- % debug generation
-demit(Term) ->
- case get(asndebug) of
- true -> emit(Term);
- _ ->true
- end.
-
- % always generation
emit(Term) ->
ok = file:write(get(gen_file_out), do_emit(Term)).
-do_emit({external,_M,T}) ->
- do_emit(T);
-
do_emit({prev,Variable}) when is_atom(Variable) ->
do_emit({var,asn1ct_name:prev(Variable)});
-
do_emit({next,Variable}) when is_atom(Variable) ->
do_emit({var,asn1ct_name:next(Variable)});
-
do_emit({curr,Variable}) when is_atom(Variable) ->
do_emit({var,asn1ct_name:curr(Variable)});
-
do_emit({var,Variable}) when is_atom(Variable) ->
[Head|V] = atom_to_list(Variable),
[Head-32|V];
-
-do_emit({var,Variable}) ->
- [Head|V] = Variable,
- [Head-32|V];
-
do_emit({asis,What}) ->
io_lib:format("~w", [What]);
-
do_emit({call,M,F,A}) ->
MFA = {M,F,length(A)},
asn1ct_func:need(MFA),
[atom_to_list(F),"(",call_args(A, "")|")"];
-
do_emit(nl) ->
"\n";
-
do_emit(com) ->
",";
-
-do_emit(tab) ->
- " ";
-
+do_emit([C|_]=Str) when is_integer(C) ->
+ Str;
+do_emit([_|_]=L) ->
+ [do_emit(E) || E <- L];
+do_emit([]) ->
+ [];
do_emit(What) when is_integer(What) ->
integer_to_list(What);
-
-do_emit(What) when is_list(What), is_integer(hd(What)) ->
- What;
-
do_emit(What) when is_atom(What) ->
- atom_to_list(What);
-
-do_emit(What) when is_tuple(What) ->
- [do_emit(E) || E <- tuple_to_list(What)];
+ atom_to_list(What).
-do_emit(What) when is_list(What) ->
- [do_emit(E) || E <- What].
call_args([A|As], Sep) ->
[Sep,do_emit(A)|call_args(As, ", ")];
@@ -1092,22 +993,21 @@ open_output_file(F) ->
close_output_file() ->
ok = file:close(erase(gen_file_out)).
-pgen_hrl(Erules,Module,TypeOrVal,Options,_Indent) ->
- put(currmod,Module),
- {Types,Values,Ptypes,_,_,_} = TypeOrVal,
+pgen_hrl(#gen{pack=record}=Gen, Code) ->
+ #abst{name=Module,types=Types,values=Values,ptypes=Ptypes} = Code,
Ret =
- case pgen_hrltypes(Erules,Module,Ptypes++Types,0) of
+ case pgen_hrltypes(Gen, Module, Ptypes++Types, 0) of
0 ->
case Values of
[] ->
0;
_ ->
- open_hrl(get(outfile),get(currmod)),
- pgen_macros(Erules,Module,Values),
+ open_hrl(get(outfile), Module),
+ pgen_macros(Gen, Module, Values),
1
end;
X ->
- pgen_macros(Erules,Module,Values),
+ pgen_macros(Gen, Module, Values),
X
end,
case Ret of
@@ -1119,70 +1019,67 @@ pgen_hrl(Erules,Module,TypeOrVal,Options,_Indent) ->
close_output_file(),
asn1ct:verbose("--~p--~n",
[{generated,lists:concat([get(outfile),".hrl"])}],
- Options),
+ Gen),
Y
- end.
+ end;
+pgen_hrl(#gen{pack=map}, _) ->
+ 0.
pgen_macros(_,_,[]) ->
true;
-pgen_macros(Erules,Module,[H|T]) ->
- Valuedef = asn1_db:dbget(Module,H),
- gen_macro(Valuedef),
- pgen_macros(Erules,Module,T).
+pgen_macros(Gen, Module, [H|T]) ->
+ Valuedef = asn1_db:dbget(Module, H),
+ gen_macro(Gen, Valuedef),
+ pgen_macros(Gen, Module, T).
pgen_hrltypes(_,_,[],NumRecords) ->
NumRecords;
-pgen_hrltypes(Erules,Module,[H|T],NumRecords) ->
-% io:format("records = ~p~n",NumRecords),
- Typedef = asn1_db:dbget(Module,H),
- AddNumRecords = gen_record(Typedef,NumRecords),
- pgen_hrltypes(Erules,Module,T,NumRecords+AddNumRecords).
+pgen_hrltypes(Gen, Module, [H|T], NumRecords) ->
+ Typedef = asn1_db:dbget(Module, H),
+ AddNumRecords = gen_record(Gen, Typedef, NumRecords),
+ pgen_hrltypes(Gen, Module, T, NumRecords+AddNumRecords).
%% Generates a macro for value Value defined in the ASN.1 module
-gen_macro(Value) when is_record(Value,valuedef) ->
- Prefix = get_macro_name_prefix(),
- emit({"-define('",Prefix,Value#valuedef.name,"', ",
- {asis,Value#valuedef.value},").",nl}).
+gen_macro(Gen, #valuedef{name=Name,value=Value}) ->
+ Prefix = get_macro_name_prefix(Gen),
+ emit(["-define('",Prefix,Name,"', ",{asis,Value},").",nl]).
%% Generate record functions **************
%% Generates an Erlang record for each named and unnamed SEQUENCE and SET in the ASN.1
%% module. If no SEQUENCE or SET is found there is no .hrl file generated
-gen_record(Tdef,NumRecords) when is_record(Tdef,typedef) ->
+gen_record(Gen, #typedef{}=Tdef, NumRecords) ->
Name = [Tdef#typedef.name],
Type = Tdef#typedef.typespec,
- gen_record(type,Name,Type,NumRecords);
-
-gen_record(Tdef,NumRecords) when is_record(Tdef,ptypedef) ->
+ gen_record(Gen, type, Name, Type, NumRecords);
+gen_record(Gen, #ptypedef{}=Tdef, NumRecords) ->
Name = [Tdef#ptypedef.name],
Type = Tdef#ptypedef.typespec,
- gen_record(ptype,Name,Type,NumRecords).
-
-gen_record(TorPtype,Name,[#'ComponentType'{name=Cname,typespec=Type}|T],Num) ->
- Num2 = gen_record(TorPtype,[Cname|Name],Type,Num),
- gen_record(TorPtype,Name,T,Num2);
-gen_record(TorPtype,Name,{Clist1,Clist2},Num)
+ gen_record(Gen, ptype, Name, Type, NumRecords).
+
+gen_record(Gen, TorPtype, Name,
+ [#'ComponentType'{name=Cname,typespec=Type}|T], Num) ->
+ Num2 = gen_record(Gen, TorPtype, [Cname|Name], Type, Num),
+ gen_record(Gen, TorPtype, Name, T, Num2);
+gen_record(Gen, TorPtype, Name, {Clist1,Clist2}, Num)
when is_list(Clist1), is_list(Clist2) ->
- gen_record(TorPtype,Name,Clist1++Clist2,Num);
-gen_record(TorPtype,Name,{Clist1,EClist,Clist2},Num)
+ gen_record(Gen, TorPtype, Name, Clist1++Clist2, Num);
+gen_record(Gen, TorPtype, Name, {Clist1,EClist,Clist2}, Num)
when is_list(Clist1), is_list(EClist), is_list(Clist2) ->
- gen_record(TorPtype,Name,Clist1++EClist++Clist2,Num);
-gen_record(TorPtype,Name,[_|T],Num) -> % skip EXTENSIONMARK
- gen_record(TorPtype,Name,T,Num);
-gen_record(_TorPtype,_Name,[],Num) ->
+ gen_record(Gen, TorPtype, Name, Clist1++EClist++Clist2, Num);
+gen_record(Gen, TorPtype, Name, [_|T], Num) -> % skip EXTENSIONMARK
+ gen_record(Gen, TorPtype, Name, T, Num);
+gen_record(_Gen, _TorPtype, _Name, [], Num) ->
Num;
-
-gen_record(TorPtype,Name,Type,Num) when is_record(Type,type) ->
+gen_record(Gen, TorPtype, Name, #type{}=Type, Num) ->
Def = Type#type.def,
Rec = case Def of
Seq when is_record(Seq,'SEQUENCE') ->
case Seq#'SEQUENCE'.pname of
false ->
{record,Seq#'SEQUENCE'.components};
-%% _Pname when TorPtype == type ->
-%% false;
_ ->
{record,Seq#'SEQUENCE'.components}
end;
@@ -1195,8 +1092,6 @@ gen_record(TorPtype,Name,Type,Num) when is_record(Type,type) ->
_ ->
{record,to_textual_order(Set#'SET'.components)}
end;
-% {'SET',{_,_CompList}} ->
-% {record,_CompList};
{'CHOICE',_CompList} -> {inner,Def};
{'SEQUENCE OF',_CompList} -> {['SEQOF'|Name],Def};
{'SET OF',_CompList} -> {['SETOF'|Name],Def};
@@ -1209,127 +1104,103 @@ gen_record(TorPtype,Name,Type,Num) when is_record(Type,type) ->
0 -> open_hrl(get(outfile),get(currmod));
_ -> true
end,
- Prefix = get_record_name_prefix(),
- emit({"-record('",Prefix,list2name(Name),"',{",nl}),
- RootList = case CompList of
- _ when is_list(CompList) ->
- CompList;
- {Rl,_} -> Rl;
- {Rl1,_Ext,_Rl2} -> Rl1
- end,
- gen_record2(Name,'SEQUENCE',RootList),
- NewCompList =
+ do_gen_record(Gen, Name, CompList),
+ NewCompList =
case CompList of
{CompList1,[]} ->
- emit({"}). % with extension mark",nl,nl}),
CompList1;
{Tr,ExtensionList2} ->
- case Tr of
- [] -> true;
- _ -> emit({",",nl})
- end,
- emit({"%% with extensions",nl}),
- gen_record2(Name, 'SEQUENCE', ExtensionList2,
- "", ext),
- emit({"}).",nl,nl}),
Tr ++ ExtensionList2;
{Rootl1,Extl,Rootl2} ->
- case Rootl1 =/= [] andalso Extl++Rootl2 =/= [] of
- true -> emit([com]);
- false -> ok
- end,
- case Rootl1 of
- [_|_] -> emit([nl]);
- [] -> ok
- end,
- emit(["%% with extensions",nl]),
- gen_record2(Name,'SEQUENCE',Extl,"",ext),
- case Extl =/= [] andalso Rootl2 =/= [] of
- true -> emit([com]);
- false -> ok
- end,
- case Extl of
- [_|_] -> emit([nl]);
- [] -> ok
- end,
- emit(["%% end of extensions",nl]),
- gen_record2(Name,'SEQUENCE',Rootl2,"",noext),
- emit(["}).",nl,nl]),
Rootl1++Extl++Rootl2;
- _ ->
- emit({"}).",nl,nl}),
+ _ ->
CompList
end,
- gen_record(TorPtype,Name,NewCompList,Num+1);
+ gen_record(Gen, TorPtype, Name, NewCompList, Num+1);
{inner,{'CHOICE', CompList}} ->
- gen_record(TorPtype,Name,CompList,Num);
+ gen_record(Gen, TorPtype, Name, CompList, Num);
{NewName,{_, CompList}} ->
- gen_record(TorPtype,NewName,CompList,Num)
+ gen_record(Gen, TorPtype, NewName, CompList, Num)
end;
-gen_record(_,_,_,NumRecords) -> % skip CLASS etc for now.
+gen_record(_, _, _, _, NumRecords) -> % skip CLASS etc for now.
NumRecords.
-
-gen_head(Erules,Mod,Hrl) ->
- Options = get(encoding_options),
- case Erules of
- per ->
- emit(["%% Generated by the Erlang ASN.1 PER-"
- "compiler version, utilizing bit-syntax:",
- asn1ct:vsn(),nl]);
- ber ->
- emit(["%% Generated by the Erlang ASN.1 BER_V2-"
- "compiler version, utilizing bit-syntax:",
- asn1ct:vsn(),nl]);
- uper ->
- emit(["%% Generated by the Erlang ASN.1 UNALIGNED"
- " PER-compiler version, utilizing bit-syntax:",
- asn1ct:vsn(),nl])
+
+do_gen_record(Gen, Name, CL0) ->
+ CL = case CL0 of
+ {Root,[]} ->
+ Root ++ [{comment,"with extension mark"}];
+ {Root,Ext} ->
+ Root ++ [{comment,"with exensions"}] ++
+ only_components(Ext);
+ {Root1,Ext,Root2} ->
+ Root1 ++ [{comment,"with exensions"}] ++
+ only_components(Ext) ++
+ [{comment,"end of extensions"}] ++ Root2;
+ _ when is_list(CL0) ->
+ CL0
+ end,
+ Prefix = get_record_name_prefix(Gen),
+ emit(["-record('",Prefix,list2name(Name),"', {"] ++
+ do_gen_record_1(CL) ++
+ [nl,"}).",nl,nl]).
+
+only_components(CL) ->
+ [C || #'ComponentType'{}=C <- CL].
+
+do_gen_record_1([#'ComponentType'{name=Name,prop=Prop}|T]) ->
+ Val = case Prop of
+ 'OPTIONAL' ->
+ " = asn1_NOVALUE";
+ {'DEFAULT',_} ->
+ " = asn1_DEFAULT";
+ _ ->
+ []
+ end,
+ Com = case needs_trailing_comma(T) of
+ true -> [com];
+ false -> []
end,
- emit({"%% Purpose: encoder and decoder to the types in mod ",Mod,nl,nl}),
- emit({"-module('",Mod,"').",nl}),
- put(currmod,Mod),
- emit({"-compile(nowarn_unused_vars).",nl}),
- emit({"-dialyzer(no_improper_lists).",nl}),
+ [nl," ",{asis,Name},Val,Com|do_gen_record_1(T)];
+do_gen_record_1([{comment,Text}|T]) ->
+ [nl," %% ",Text|do_gen_record_1(T)];
+do_gen_record_1([]) ->
+ [].
+
+needs_trailing_comma([#'ComponentType'{}|_]) -> true;
+needs_trailing_comma([_|T]) -> needs_trailing_comma(T);
+needs_trailing_comma([]) -> false.
+
+gen_head(#gen{options=Options}=Gen, Mod, Hrl) ->
+ Name = case Gen of
+ #gen{erule=per,aligned=false} ->
+ "PER (unaligned)";
+ #gen{erule=per,aligned=true} ->
+ "PER (aligned)";
+ #gen{erule=ber} ->
+ "BER"
+ end,
+ emit(["%% Generated by the Erlang ASN.1 ",Name,
+ " compiler. Version: ",asn1ct:vsn(),nl,
+ "%% Purpose: Encoding and decoding of the types in ",
+ Mod,".",nl,nl,
+ "-module('",Mod,"').",nl,
+ "-compile(nowarn_unused_vars).",nl,
+ "-dialyzer(no_improper_lists).",nl]),
case Hrl of
0 -> ok;
- _ -> emit({"-include(\"",Mod,".hrl\").",nl})
+ _ -> emit(["-include(\"",Mod,".hrl\").",nl])
end,
emit(["-asn1_info([{vsn,'",asn1ct:vsn(),"'},",nl,
" {module,'",Mod,"'},",nl,
" {options,",io_lib:format("~p",[Options]),"}]).",nl,nl]).
-
-gen_hrlhead(Mod) ->
- emit({"%% Generated by the Erlang ASN.1 compiler version:",asn1ct:vsn(),nl}),
- emit({"%% Purpose: Erlang record definitions for each named and unnamed",nl}),
- emit({"%% SEQUENCE and SET, and macro definitions for each value",nl}),
- emit({"%% definition,in module ",Mod,nl,nl}),
- emit({nl,nl}).
-gen_record2(Name,SeqOrSet,Comps) ->
- gen_record2(Name,SeqOrSet,Comps,"",noext).
-
-gen_record2(_Name,_SeqOrSet,[],_Com,_Extension) ->
- true;
-gen_record2(_Name,_SeqOrSet,[H = #'ComponentType'{name=Cname}],Com,Extension) ->
- emit(Com),
- emit({asis,Cname}),
- gen_record_default(H, Extension);
-gen_record2(Name,SeqOrSet,[H = #'ComponentType'{name=Cname}|T],Com, Extension) ->
- emit(Com),
- emit({asis,Cname}),
- gen_record_default(H, Extension),
- gen_record2(Name,SeqOrSet,T,", ", Extension);
-gen_record2(Name,SeqOrSet,[_|T],Com,Extension) ->
- %% skip EXTENSIONMARK, ExtensionAdditionGroup and other markers
- gen_record2(Name,SeqOrSet,T,Com,Extension).
-
-gen_record_default(#'ComponentType'{prop='OPTIONAL'}, _)->
- emit(" = asn1_NOVALUE");
-gen_record_default(#'ComponentType'{prop={'DEFAULT',_}}, _)->
- emit(" = asn1_DEFAULT");
-gen_record_default(_, _) ->
- true.
+gen_hrlhead(Mod) ->
+ emit(["%% Generated by the Erlang ASN.1 compiler. Version: ",
+ asn1ct:vsn(),nl,
+ "%% Purpose: Erlang record definitions for each named and unnamed",nl,
+ "%% SEQUENCE and SET, and macro definitions for each value",nl,
+ "%% definition in module ",Mod,".",nl,nl]).
%% May only be a list or a two-tuple.
to_textual_order({Root,Ext}) ->
@@ -1426,7 +1297,6 @@ get_inner({fixedtypevaluefield,_,Type}) ->
get_inner({typefield,TypeName}) ->
TypeName;
get_inner(#'ObjectClassFieldType'{type=Type}) ->
-% get_inner(Type);
Type;
get_inner(T) when is_tuple(T) ->
case element(1,T) of
@@ -1435,9 +1305,7 @@ get_inner(T) when is_tuple(T) ->
{valuefieldreference,FieldName} ->
get_fieldtype(element(2,Tuple),FieldName);
{typefieldreference,FieldName} ->
- get_fieldtype(element(2,Tuple),FieldName);
- {'EXIT',Reason} ->
- throw({asn1,{'internal error in get_inner/1',Reason}})
+ get_fieldtype(element(2,Tuple),FieldName)
end;
_ -> element(1,T)
end.
@@ -1585,27 +1453,19 @@ constructed_suffix('SEQUENCE OF',_) ->
constructed_suffix('SET OF',_) ->
'SETOF'.
-erule(ber) -> ber;
-erule(per) -> per;
-erule(uper) -> per.
-
index2suffix(0) ->
"";
index2suffix(N) ->
lists:concat(["_",N]).
-ct_gen_module(ber) ->
+ct_gen_module(#gen{erule=ber}) ->
asn1ct_gen_ber_bin_v2;
-ct_gen_module(per) ->
- asn1ct_gen_per;
-ct_gen_module(uper) ->
+ct_gen_module(#gen{erule=per}) ->
asn1ct_gen_per.
-ct_constructed_module(ber) ->
+ct_constructed_module(#gen{erule=ber}) ->
asn1ct_constructed_ber_bin_v2;
-ct_constructed_module(per) ->
- asn1ct_constructed_per;
-ct_constructed_module(uper) ->
+ct_constructed_module(#gen{erule=per}) ->
asn1ct_constructed_per.
get_constraint(C,Key) ->
@@ -1617,19 +1477,9 @@ get_constraint(C,Key) ->
{value,Cnstr} ->
Cnstr
end.
-
-get_record_name_prefix() ->
- case lists:keysearch(record_name_prefix,1,get(encoding_options)) of
- false ->
- "";
- {value,{_,Prefix}} ->
- Prefix
- end.
-get_macro_name_prefix() ->
- case lists:keysearch(macro_name_prefix,1,get(encoding_options)) of
- false ->
- "";
- {value,{_,Prefix}} ->
- Prefix
- end.
+get_record_name_prefix(#gen{rec_prefix=Prefix}) ->
+ Prefix.
+
+get_macro_name_prefix(#gen{macro_prefix=Prefix}) ->
+ Prefix.
diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
index b884d14b0d..446f508998 100644
--- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -35,21 +35,21 @@
-export([extaddgroup2sequence/1]).
-export([dialyzer_suppressions/1]).
--import(asn1ct_gen, [emit/1,demit/1]).
+-import(asn1ct_gen, [emit/1]).
- % the encoding of class of tag bits 8 and 7
+%% The encoding of class of tag bits 8 and 7
-define(UNIVERSAL, 0).
-define(APPLICATION, 16#40).
-define(CONTEXT, 16#80).
-define(PRIVATE, 16#C0).
- % primitive or constructed encoding % bit 6
+%% Primitive or constructed encoding % bit 6
-define(PRIMITIVE, 0).
-define(CONSTRUCTED, 2#00100000).
-define(T_ObjectDescriptor, ?UNIVERSAL bor ?PRIMITIVE bor 7).
- % restricted character string types
+%% Restricted character string types
-define(T_NumericString, ?UNIVERSAL bor ?PRIMITIVE bor 18). %can be constructed
-define(T_PrintableString, ?UNIVERSAL bor ?PRIMITIVE bor 19). %can be constructed
-define(T_TeletexString, ?UNIVERSAL bor ?PRIMITIVE bor 20). %can be constructed
@@ -107,20 +107,12 @@ gen_encode(Erules,Typename,Type) when is_record(Type,type) ->
case asn1ct_gen:type(InnerType) of
{constructed,bif} ->
- emit([nl,nl,nl,"%%================================"]),
- emit([nl,"%% ",asn1ct_gen:list2name(Typename)]),
- emit([nl,"%%================================",nl]),
- case length(Typename) of
- 1 -> % top level type
- emit(["'enc_",asn1ct_gen:list2name(Typename),
- "'(Val",ObjFun,") ->",nl]),
- emit([" 'enc_",asn1ct_gen:list2name(Typename),
- "'(Val, ", {asis,lists:reverse(Type#type.tag)},ObjFun,").",nl,nl]);
- _ -> % embedded type with constructed name
- true
- end,
- emit(["'enc_",asn1ct_gen:list2name(Typename),
- "'(Val, TagIn",ObjFun,") ->",nl," "]),
+ Func = {asis,enc_func(asn1ct_gen:list2name(Typename))},
+ emit([nl,nl,nl,"%%================================",nl,
+ "%% ",asn1ct_gen:list2name(Typename),nl,
+ "%%================================",nl,
+ Func,"(Val, TagIn",ObjFun,") ->",nl,
+ " "]),
asn1ct_gen:gen_encode_constructed(Erules,Typename,InnerType,Type);
_ ->
true
@@ -146,7 +138,7 @@ gen_encode_user(Erules, #typedef{}=D, Wrapper) ->
emit([nl,nl,"%%================================"]),
emit([nl,"%% ",Typename]),
emit([nl,"%%================================",nl]),
- FuncName = "'enc_" ++ asn1ct_gen:list2name(Typename) ++ "'",
+ FuncName = {asis,enc_func(asn1ct_gen:list2name(Typename))},
case Wrapper of
true ->
%% This is a top-level type. Generate an 'enc_Type'/1
@@ -169,9 +161,10 @@ gen_encode_user(Erules, #typedef{}=D, Wrapper) ->
gen_encode_prim(ber,Type,"TagIn","Val"),
emit([".",nl]);
#'Externaltypereference'{module=CurrentMod,type=Etype} ->
- emit([" 'enc_",Etype,"'(Val, TagIn).",nl]);
+ emit([" ",{asis,enc_func(Etype)},"(Val, TagIn).",nl]);
#'Externaltypereference'{module=Emod,type=Etype} ->
- emit([" '",Emod,"':'enc_",Etype,"'(Val, TagIn).",nl]);
+ emit([" ",{asis,Emod},":",{asis,enc_func(Etype)},
+ "(Val, TagIn).",nl]);
'ASN1_OPEN_TYPE' ->
emit(["%% OPEN TYPE",nl]),
gen_encode_prim(ber,
@@ -326,40 +319,39 @@ gen_decode(Erules,Type) when is_record(Type,typedef) ->
Tag = [(decode_class(X#tag.class) bsl 10) + X#tag.number || X <- InnerTag],
- FunctionName =
+ FuncName0 =
case {asn1ct:get_gen_state_field(active),
asn1ct:get_gen_state_field(prefix)} of
{true,Pref} ->
%% prevent duplicated function definitions
-% Pattern = asn1ct:get_gen_state_field(namelist),
-% FuncName=asn1ct:maybe_rename_function(Type#typedef.name,
-% Pattern),
case asn1ct:current_sindex() of
- I when is_integer(I),I>0 ->
- lists:concat([Pref,Type#typedef.name,"_",I]);
+ I when is_integer(I), I > 0 ->
+ [Pref,Type#typedef.name,"_",I];
_->
- lists:concat([Pref,Type#typedef.name])
- end; % maybe the current_sindex must be reset
- _ -> lists:concat(["dec_",Type#typedef.name])
+ [Pref,Type#typedef.name]
+ end;
+ {_,_} ->
+ ["dec_",Type#typedef.name]
end,
- emit({nl,nl}),
- emit(["'",FunctionName,"'(Tlv) ->",nl]),
- emit([" '",FunctionName,"'(Tlv, ",{asis,Tag},").",nl,nl]),
- emit(["'",FunctionName,"'(Tlv, TagIn) ->",nl]),
- dbdec(Type#typedef.name,"Tlv"),
+ FuncName = {asis,list_to_atom(lists:concat(FuncName0))},
+ emit([nl,nl,
+ FuncName,"(Tlv) ->",nl,
+ " ",FuncName,"(Tlv, ",{asis,Tag},").",nl,nl,
+ FuncName,"(Tlv, TagIn) ->",nl]),
gen_decode_user(Erules,Type).
gen_inc_decode(Erules,Type) when is_record(Type,typedef) ->
Prefix = asn1ct:get_gen_state_field(prefix),
Suffix = asn1ct_gen:index2suffix(asn1ct:current_sindex()),
- emit({nl,nl}),
- emit(["'",Prefix,Type#typedef.name,Suffix,"'(Tlv, TagIn) ->",nl]),
+ FuncName0 = [Prefix,Type#typedef.name,Suffix],
+ FuncName = {asis,list_to_atom(lists:concat(FuncName0))},
+ emit([nl,nl,
+ FuncName,"(Tlv, TagIn) ->",nl]),
gen_decode_user(Erules,Type).
%% gen_decode_selected exported function for selected decode
gen_decode_selected(Erules,Type,FuncName) ->
emit([FuncName,"(Bin) ->",nl]),
-% Pattern = asn1ct:get_gen_state_field(tag_pattern),
Patterns = asn1ct:read_config_data(partial_decode),
Pattern =
case lists:keysearch(FuncName,1,Patterns) of
@@ -398,12 +390,10 @@ gen_decode_selected_type(_Erules,TypeDef) ->
asn1ct_gen:list2name(TopType),"'"]),
emit([DecFunName,"(",BytesVar,
", ",{asis,Tag},")"]);
-% emit([";",nl]);
TheType ->
DecFunName = mkfuncname(TheType,dec),
emit([DecFunName,"(",BytesVar,
", ",{asis,Tag},")"])
-% emit([";",nl])
end.
%%===============================================================================
@@ -418,7 +408,6 @@ gen_decode(Erules,Typename,Type) when is_record(Type,type) ->
FunctionName =
case asn1ct:get_gen_state_field(active) of
true ->
-% Suffix = asn1ct_gen:index2suffix(SIndex),
Pattern = asn1ct:get_gen_state_field(namelist),
Suffix =
case asn1ct:maybe_saved_sindex(Typename,Pattern) of
@@ -431,8 +420,6 @@ gen_decode(Erules,Typename,Type) when is_record(Type,type) ->
_ ->
lists:concat(["'dec_",asn1ct_gen:list2name(Typename)])
end,
-% io:format("Typename: ~p,~n",[Typename]),
-% io:format("FunctionName: ~p~n",[FunctionName]),
case asn1ct_gen:type(InnerType) of
{constructed,bif} ->
ObjFun =
@@ -442,9 +429,7 @@ gen_decode(Erules,Typename,Type) when is_record(Type,type) ->
_ ->
""
end,
-% emit([Prefix,asn1ct_gen:list2name(Typename),"'(Tlv, TagIn",ObjFun,") ->",nl]),
emit([FunctionName,"'(Tlv, TagIn",ObjFun,") ->",nl]),
- dbdec(Typename,"Tlv"),
asn1ct_gen:gen_decode_constructed(Erules,Typename,InnerType,Type);
Rec when is_record(Rec,'Externaltypereference') ->
case {Typename,asn1ct:get_gen_state_field(namelist)} of
@@ -476,10 +461,10 @@ gen_decode(Erules,Typename,Type) when is_record(Type,type) ->
gen_decode(Erules,Tname,#'ComponentType'{name=Cname,typespec=Type}) ->
NewTname = [Cname|Tname],
- %% The tag is set to [] to avoid that it is
- %% taken into account twice, both as a component/alternative (passed as
- %% argument to the encode decode function and within the encode decode
- %% function it self.
+ %% The tag is set to [] to avoid that it is taken into account
+ %% twice, both as a component/alternative (passed as argument to
+ %% the encode/decode function), and within the encode decode
+ %% function itself.
NewType = Type#type{tag=[]},
case {asn1ct:get_gen_state_field(active),
asn1ct:get_tobe_refed_func(NewTname)} of
@@ -504,7 +489,7 @@ gen_decode_user(Erules,D) when is_record(D,typedef) ->
asn1ct_name:new(len),
gen_dec_prim(Def#type{def='ASN1_OPEN_TYPE'},
BytesVar, {string,"TagIn"}),
- emit({".",nl,nl});
+ emit([".",nl,nl]);
{primitive,bif} ->
asn1ct_name:new(len),
gen_dec_prim(Def, BytesVar, {string,"TagIn"}),
@@ -515,8 +500,7 @@ gen_decode_user(Erules,D) when is_record(D,typedef) ->
TheType ->
DecFunName = mkfuncname(TheType,dec),
emit([DecFunName,"(",BytesVar,
- ", TagIn)"]),
- emit([".",nl,nl])
+ ", TagIn).",nl,nl])
end.
@@ -746,9 +730,10 @@ gen_obj_code(Erules,_Module,Obj) when is_record(Obj,typedef) ->
#'Externaltypereference'{module=M,type=ClName} = Def#'Object'.classname,
Class = asn1_db:dbget(M,ClName),
{object,_,Fields} = Def#'Object'.def,
- emit({nl,nl,nl,"%%================================"}),
- emit({nl,"%% ",ObjName}),
- emit({nl,"%%================================",nl}),
+ emit([nl,nl,nl,
+ "%%================================",nl,
+ "%% ",ObjName,nl,
+ "%%================================",nl]),
EncConstructed =
gen_encode_objectfields(ClName,get_class_fields(Class),
ObjName,Fields,[]),
@@ -766,11 +751,9 @@ gen_encode_objectfields(ClassName,[{typefield,Name,OptOrMand}|Rest],
ObjName,ObjectFields,ConstrAcc) ->
EmitFuncClause =
fun(Arg) ->
- emit(["'enc_",ObjName,"'(",{asis,Name},
- ", ",Arg,", _RestPrimFieldName) ->",nl])
+ emit([{asis,enc_func(ObjName)},"(",{asis,Name},
+ ", ",Arg,", _RestPrimFieldName) ->",nl])
end,
-% emit(["'enc_",ObjName,"'(",{asis,Name},
-% ", Val, RestPrimFieldName) ->",nl]),
MaybeConstr=
case {get_object_field(Name,ObjectFields),OptOrMand} of
{false,'OPTIONAL'} ->
@@ -799,11 +782,9 @@ gen_encode_objectfields(ClassName,[{objectfield,Name,_,_,OptOrMand}|Rest],
CurrentMod = get(currmod),
EmitFuncClause =
fun(Args) ->
- emit(["'enc_",ObjName,"'(",{asis,Name},
+ emit([{asis,enc_func(ObjName)},"(",{asis,Name},
", ",Args,") ->",nl])
end,
-% emit(["'enc_",ObjName,"'(",{asis,Name},
-% ", Val,[H|T]) ->",nl]),
case {get_object_field(Name,ObjectFields),OptOrMand} of
{false,'OPTIONAL'} ->
EmitFuncClause("_,_"),
@@ -814,19 +795,14 @@ gen_encode_objectfields(ClassName,[{objectfield,Name,_,_,OptOrMand}|Rest],
{{Name,#'Externalvaluereference'{module=CurrentMod,
value=TypeName}},_} ->
EmitFuncClause(" Val, [H|T]"),
- emit({indent(3),"'enc_",TypeName,"'(H, Val, T)"});
+ emit([indent(3),{asis,enc_func(TypeName)},"(H, Val, T)"]);
{{Name,#'Externalvaluereference'{module=M,value=TypeName}},_} ->
EmitFuncClause(" Val, [H|T]"),
- emit({indent(3),"'",M,"':'enc_",TypeName,"'(H, Val, T)"});
- {{Name,TypeSpec},_} ->
+ emit([indent(3),{asis,M},":",{asis,enc_func(TypeName)},
+ "(H, Val, T)"]);
+ {{Name,#typedef{name=TypeName}},_} when is_atom(TypeName) ->
EmitFuncClause(" Val, [H|T]"),
- case TypeSpec#typedef.name of
- {ExtMod,TypeName} ->
- emit({indent(3),"'",ExtMod,"':'enc_",TypeName,
- "'(H, Val, T)"});
- TypeName ->
- emit({indent(3),"'enc_",TypeName,"'(H, Val, T)"})
- end
+ emit([indent(3),{asis,enc_func(TypeName)},"(H, Val, T)"])
end,
case more_genfields(Rest) of
true ->
@@ -862,10 +838,11 @@ gen_encode_field_call(_ObjName,_FieldName,
X <- OTag],
if
M == CurrentMod ->
- emit({" 'enc_",T,"'(Val, ",{asis,Tag},")"}),
+ emit([" ",{asis,enc_func(T)},"(Val, ",{asis,Tag},")"]),
[];
true ->
- emit({" '",M,"':'enc_",T,"'(Val, ",{asis,Tag},")"}),
+ emit([" ",{asis,M},":",{asis,enc_func(T)},
+ "(Val, ",{asis,Tag},")"]),
[]
end;
gen_encode_field_call(ObjName,FieldName,Type) ->
@@ -875,24 +852,21 @@ gen_encode_field_call(ObjName,FieldName,Type) ->
X#tag.form,X#tag.number)||
X <- OTag],
case Type#typedef.name of
- {primitive,bif} -> %%tag should be the primitive tag
-% OTag = Def#type.tag,
-% Tag = [encode_tag_val(decode_class(X#tag.class),
-% X#tag.form,X#tag.number)||
-% X <- OTag],
+ {primitive,bif} -> %tag should be the primitive tag
gen_encode_prim(ber,Def,{asis,lists:reverse(Tag)},
"Val"),
[];
{constructed,bif} ->
- emit({" 'enc_",ObjName,'_',FieldName,
- "'(Val,",{asis,Tag},")"}),
- [Type#typedef{name=list_to_atom(lists:concat([ObjName,'_',FieldName]))}];
+ Name = lists:concat([ObjName,'_',FieldName]),
+ emit([" ",{asis,enc_func(Name)},"(Val,",{asis,Tag},")"]),
+ [Type#typedef{name=list_to_atom(Name)}];
{ExtMod,TypeName} ->
- emit({" '",ExtMod,"':'enc_",TypeName,
- "'(Val,",{asis,Tag},")"}),
+ emit([" ",{asis,ExtMod},":",{asis,enc_func(TypeName)},
+ "(Val,",{asis,Tag},")"]),
[];
TypeName ->
- emit({" 'enc_",TypeName,"'(Val,",{asis,Tag},")"}),
+ emit([" ",{asis,enc_func(TypeName)},
+ "(Val,",{asis,Tag},")"]),
[]
end.
@@ -903,10 +877,10 @@ gen_encode_default_call(ClassName,FieldName,Type) ->
Tag = [encode_tag_val(decode_class(X#tag.class),X#tag.form,X#tag.number)|| X <- OTag],
case asn1ct_gen:type(InnerType) of
{constructed,bif} ->
- emit([" 'enc_",ClassName,'_',FieldName,"'",
+ Name = lists:concat([ClassName,'_',FieldName]),
+ emit([" ",{asis,enc_func(Name)},
"(Val, ",{asis,Tag},")"]),
- [#typedef{name=list_to_atom(lists:concat([ClassName,'_',FieldName])),
- typespec=Type}];
+ [#typedef{name=list_to_atom(Name),typespec=Type}];
{primitive,bif} ->
gen_encode_prim(ber,Type,{asis,lists:reverse(Tag)},"Val"),
[];
@@ -916,12 +890,6 @@ gen_encode_default_call(ClassName,FieldName,Type) ->
#'Externaltypereference'{module=Emod,type=Etype} ->
emit([" '",Emod,"':'enc_",Etype,"'(Val, ",{asis,Tag},")",nl]),
[]
-% 'ASN1_OPEN_TYPE' ->
-% emit(["%% OPEN TYPE",nl]),
-% gen_encode_prim(ber,
-% Type#type{def='ASN1_OPEN_TYPE'},
-% "TagIn","Val"),
-% emit([".",nl])
end.
%%%%%%%%%%%%%%%%
@@ -930,11 +898,9 @@ gen_decode_objectfields(ClassName,[{typefield,Name,OptOrMand}|Rest],
ObjName,ObjectFields,ConstrAcc) ->
EmitFuncClause =
fun(Arg) ->
- emit(["'dec_",ObjName,"'(",{asis,Name},
+ emit([{asis,dec_func(ObjName)},"(",{asis,Name},
", ",Arg,",_) ->",nl])
end,
-% emit(["'dec_",ObjName,"'(",{asis,Name},
-% ", Bytes, RestPrimFieldName) ->",nl]),
MaybeConstr=
case {get_object_field(Name,ObjectFields),OptOrMand} of
{false,'OPTIONAL'} ->
@@ -964,12 +930,9 @@ gen_decode_objectfields(ClassName,[{objectfield,Name,_,_,OptOrMand}|Rest],
CurrentMod = get(currmod),
EmitFuncClause =
fun(Args) ->
- emit(["'dec_",ObjName,"'(",{asis,Name},
+ emit([{asis,dec_func(ObjName)},"(",{asis,Name},
", ",Args,") ->",nl])
end,
-% emit(["'dec_",ObjName,"'(",{asis,Name},
-% ", Bytes,[H|T]) ->",nl]),
-% emit_tlv_format("Bytes"),
case {get_object_field(Name,ObjectFields),OptOrMand} of
{false,'OPTIONAL'} ->
EmitFuncClause("_,_"),
@@ -980,21 +943,14 @@ gen_decode_objectfields(ClassName,[{objectfield,Name,_,_,OptOrMand}|Rest],
{{Name,#'Externalvaluereference'{module=CurrentMod,
value=TypeName}},_} ->
EmitFuncClause("Bytes,[H|T]"),
- emit({indent(3),"'dec_",TypeName,"'(H, Bytes, T)"});
+ emit([indent(3),{asis,dec_func(TypeName)},"(H, Bytes, T)"]);
{{Name,#'Externalvaluereference'{module=M,value=TypeName}},_} ->
EmitFuncClause("Bytes,[H|T]"),
- emit({indent(3),"'",M,"':'dec_",TypeName,
- "'(H, Bytes, T)"});
- {{Name,TypeSpec},_} ->
- EmitFuncClause("Bytes,[H|T]"),
-% emit_tlv_format("Bytes"),
- case TypeSpec#typedef.name of
- {ExtMod,TypeName} ->
- emit({indent(3),"'",ExtMod,"':'dec_",TypeName,
- "'(H, Bytes, T)"});
- TypeName ->
- emit({indent(3),"'dec_",TypeName,"'(H, Bytes, T)"})
- end
+ emit([indent(3),{asis,M},":",{asis,dec_func(TypeName)},
+ "(H, Bytes, T)"]);
+ {{Name,#typedef{name=TypeName}},_} when is_atom(TypeName) ->
+ EmitFuncClause("Bytes,[H|T]"),
+ emit([indent(3),{asis,dec_func(TypeName)},"(H, Bytes, T)"])
end,
case more_genfields(Rest) of
true ->
@@ -1014,24 +970,20 @@ emit_tlv_format(Bytes) ->
notice_tlv_format_gen() ->
Module = get(currmod),
-% io:format("Noticed: ~p~n",[Module]),
case get(tlv_format) of
{done,Module} ->
ok;
- _ -> % true or undefined
+ _ -> % true or undefined
put(tlv_format,true)
end.
emit_tlv_format_function() ->
Module = get(currmod),
-% io:format("Tlv formated: ~p",[Module]),
case get(tlv_format) of
true ->
-% io:format(" YES!~n"),
emit_tlv_format_function1(),
put(tlv_format,{done,Module});
_ ->
-% io:format(" NO!~n"),
ok
end.
emit_tlv_format_function1() ->
@@ -1066,12 +1018,12 @@ gen_decode_field_call(_ObjName,_FieldName,Bytes,
X <- OTag],
if
M == CurrentMod ->
- emit({" 'dec_",T,"'(",Bytes,
- ", ",{asis,Tag},")"}),
+ emit([" ",{asis,dec_func(T)},"(",Bytes,
+ ", ",{asis,Tag},")"]),
[];
true ->
- emit({" '",M,"':'dec_",T,
- "'(",Bytes,", ",{asis,Tag},")"}),
+ emit([" ",{asis,M},":",{asis,dec_func(T)},
+ "(",Bytes,", ",{asis,Tag},")"]),
[]
end;
gen_decode_field_call(ObjName,FieldName,Bytes,Type) ->
@@ -1084,15 +1036,17 @@ gen_decode_field_call(ObjName,FieldName,Bytes,Type) ->
gen_dec_prim(Def, Bytes, Tag),
[];
{constructed,bif} ->
- emit({" 'dec_",ObjName,'_',FieldName,
- "'(",Bytes,",",{asis,Tag},")"}),
- [Type#typedef{name=list_to_atom(lists:concat([ObjName,'_',FieldName]))}];
+ Name = lists:concat([ObjName,"_",FieldName]),
+ emit([" ",{asis,dec_func(Name)},
+ "(",Bytes,",",{asis,Tag},")"]),
+ [Type#typedef{name=list_to_atom(Name)}];
{ExtMod,TypeName} ->
- emit({" '",ExtMod,"':'dec_",TypeName,
- "'(",Bytes,",",{asis,Tag},")"}),
+ emit([" ",{asis,ExtMod},":",{asis,dec_func(TypeName)},
+ "(",Bytes,",",{asis,Tag},")"]),
[];
TypeName ->
- emit({" 'dec_",TypeName,"'(",Bytes,",",{asis,Tag},")"}),
+ emit([" ",{asis,dec_func(TypeName)},
+ "(",Bytes,",",{asis,Tag},")"]),
[]
end.
@@ -1118,12 +1072,6 @@ gen_decode_default_call(ClassName,FieldName,Bytes,Type) ->
emit([" '",Emod,"':'dec_",Etype,"'(",Bytes,", ",
{asis,Tag},")",nl]),
[]
-% 'ASN1_OPEN_TYPE' ->
-% emit(["%% OPEN TYPE",nl]),
-% gen_encode_prim(ber,
-% Type#type{def='ASN1_OPEN_TYPE'},
-% "TagIn","Val"),
-% emit([".",nl])
end.
%%%%%%%%%%%
@@ -1162,15 +1110,15 @@ more_genfields([Field|Fields]) ->
gen_objectset_code(Erules,ObjSet) ->
ObjSetName = ObjSet#typedef.name,
Def = ObjSet#typedef.typespec,
-% {ClassName,ClassDef} = Def#'ObjectSet'.class,
#'Externaltypereference'{module=ClassModule,
type=ClassName} = Def#'ObjectSet'.class,
ClassDef = asn1_db:dbget(ClassModule,ClassName),
UniqueFName = Def#'ObjectSet'.uniquefname,
Set = Def#'ObjectSet'.set,
- emit({nl,nl,nl,"%%================================"}),
- emit({nl,"%% ",ObjSetName}),
- emit({nl,"%%================================",nl}),
+ emit([nl,nl,nl,
+ "%%================================",nl,
+ "%% ",ObjSetName,nl,
+ "%%================================",nl]),
case ClassName of
{_Module,ExtClassName} ->
gen_objset_code(Erules,ObjSetName,UniqueFName,Set,ExtClassName,ClassDef);
@@ -1200,17 +1148,20 @@ gen_objset_enc(Erules, ObjSetName, UniqueName,
{no_mod,no_name} ->
gen_inlined_enc_funs(Fields, ClFields, ObjSetName, Val, NthObj);
{CurrMod,Name} ->
- emit(["'getenc_",ObjSetName,"'(",{asis,Val},") ->",nl,
- " fun 'enc_",Name,"'/3;",nl]),
+ emit([asis_atom(["getenc_",ObjSetName]),
+ "(Id) when Id =:= ",{asis,Val}," ->",nl,
+ " fun ",asis_atom(["enc_",Name]),"/3;",nl]),
{[],NthObj};
{ModuleName,Name} ->
- emit(["'getenc_",ObjSetName,"'(",{asis,Val},") ->",nl]),
+ emit([asis_atom(["getenc_",ObjSetName]),
+ "(Id) when Id =:= ",{asis,Val}," ->",nl]),
emit_ext_fun(enc,ModuleName,Name),
emit([";",nl]),
{[],NthObj};
_ ->
- emit(["'getenc_",ObjSetName,"'(",{asis,Val},") ->",nl,
- " fun 'enc_",ObjName,"'/3;",nl]),
+ emit([asis_atom(["getenc_",ObjSetName]),
+ "(",{asis,Val},") ->",nl,
+ " fun ",asis_atom(["enc_",ObjName]),"/3;",nl]),
{[],NthObj}
end,
gen_objset_enc(Erules, ObjSetName, UniqueName, T, ClName, ClFields,
@@ -1218,7 +1169,7 @@ gen_objset_enc(Erules, ObjSetName, UniqueName,
%% See X.681 Annex E for the following case
gen_objset_enc(_,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName,
_ClFields,_NthObj,Acc) ->
- emit(["'getenc_",ObjSetName,"'(_) ->",nl,
+ emit([asis_atom(["getenc_",ObjSetName]),"(_) ->",nl,
indent(2),"fun(_, Val, _RestPrimFieldName) ->",nl]),
emit_enc_open_type(4),
emit([nl,
@@ -1226,7 +1177,7 @@ gen_objset_enc(_,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName,
Acc;
gen_objset_enc(_, ObjSetName, UniqueName, [], _, _, _, Acc) ->
emit_default_getenc(ObjSetName, UniqueName),
- emit({".",nl,nl}),
+ emit([".",nl,nl]),
Acc.
emit_ext_fun(EncDec,ModuleName,Name) ->
@@ -1234,14 +1185,15 @@ emit_ext_fun(EncDec,ModuleName,Name) ->
Name,"'(T,V,O) end"]).
emit_default_getenc(ObjSetName,UniqueName) ->
- emit(["'getenc_",ObjSetName,"'(ErrV) ->",nl]),
- emit([indent(3),"fun(C,V,_) -> exit({'Type not compatible with table constraint',{component,C},{value,V}, {unique_name_and_value,",{asis,UniqueName},", ErrV}}) end"]).
+ emit([asis_atom(["getenc_",ObjSetName]),"(ErrV) ->",nl,
+ indent(3),"fun(C,V,_) ->",nl,
+ "exit({'Type not compatible with table constraint',{component,C},{value,V}, {unique_name_and_value,",{asis,UniqueName},", ErrV}}) end"]).
%% gen_inlined_enc_funs for each object iterates over all fields of a
%% class, and for each typefield it checks if the object has that
%% field and emits the proper code.
gen_inlined_enc_funs(Fields, [{typefield,_,_}|_]=T, ObjSetName, Val, NthObj) ->
- emit(["'getenc_",ObjSetName,"'(",{asis,Val},") ->",nl,
+ emit([asis_atom(["getenc_",ObjSetName]),"(",{asis,Val},") ->",nl,
indent(3),"fun(Type, Val, _RestPrimFieldName) ->",nl,
indent(6),"case Type of",nl]),
gen_inlined_enc_funs1(Fields, T, ObjSetName, [], NthObj, []);
@@ -1281,8 +1233,8 @@ gen_inlined_enc_funs1(Fields, [{typefield,Name,_}|Rest], ObjSetName,
end,
{Acc0,0};
false ->
- %% This field was not present in the object thus there
- %% were no type in the table and we therefore generate
+ %% This field was not present in the object; thus, there
+ %% was no type in the table and we therefore generate
%% code that returns the input for application
%% treatment.
emit([indent(9),{asis,Name}," ->",nl]),
@@ -1320,7 +1272,6 @@ emit_inner_of_fun(TDef=#typedef{name={ExtMod,Name},typespec=Type},
InternalDefFunName) ->
OTag = Type#type.tag,
Tag = [encode_tag_val(decode_class(X#tag.class),X#tag.form,X#tag.number)|| X <- OTag],
-% remove Tag = [X#tag{class=decode_class(X#tag.class)}|| X <- OTag],
case {ExtMod,Name} of
{primitive,bif} ->
emit(indent(12)),
@@ -1331,20 +1282,14 @@ emit_inner_of_fun(TDef=#typedef{name={ExtMod,Name},typespec=Type},
InternalDefFunName,"'(Val, ",{asis,Tag},")"]),
{[TDef#typedef{name=InternalDefFunName}],1};
_ ->
- emit({indent(12),"'",ExtMod,"':'enc_",Name,"'(Val",{asis,Tag},")"}),
+ emit([indent(12),"'",ExtMod,"':'enc_",Name,"'(Val",{asis,Tag},")"]),
{[],0}
end;
emit_inner_of_fun(#typedef{name=Name},_) ->
-% OTag = Type#type.tag,
-% remove Tag = [X#tag{class=decode_class(X#tag.class)}|| X <- OTag],
-% Tag = [encode_tag_val(decode_class(X#tag.class),X#tag.form,X#tag.number)|| X <- OTag],
- emit({indent(12),"'enc_",Name,"'(Val)"}),
+ emit([indent(12),"'enc_",Name,"'(Val)"]),
{[],0};
emit_inner_of_fun(Type,_) when is_record(Type,type) ->
CurrMod = get(currmod),
-% OTag = Type#type.tag,
-% remove Tag = [X#tag{class=decode_class(X#tag.class)}|| X <- OTag],
-% Tag = [encode_tag_val(decode_class(X#tag.class),X#tag.form,X#tag.number)|| X <- OTag],
case Type#type.def of
Def when is_atom(Def) ->
OTag = Type#type.tag,
@@ -1382,16 +1327,19 @@ gen_objset_dec(Erules, ObjSName, UniqueName, [{ObjName,Val,Fields}|T],
{no_mod,no_name} ->
gen_inlined_dec_funs(Fields,ClFields,ObjSName,Val,NthObj);
{CurrMod,Name} ->
- emit(["'getdec_",ObjSName,"'(",{asis,Val},") ->",nl,
+ emit([asis_atom(["getdec_",ObjSName]),
+ "(Id) when Id =:= ",{asis,Val}," ->",nl,
" fun 'dec_",Name,"'/3;", nl]),
NthObj;
{ModuleName,Name} ->
- emit(["'getdec_",ObjSName,"'(",{asis,Val},") ->",nl]),
+ emit([asis_atom(["getdec_",ObjSName]),
+ "(Id) when Id =:= ",{asis,Val}," ->",nl]),
emit_ext_fun(dec,ModuleName,Name),
emit([";",nl]),
NthObj;
_ ->
- emit(["'getdec_",ObjSName,"'(",{asis,Val},") ->",nl,
+ emit([asis_atom(["getdec_",ObjSName]),
+ "(",{asis,Val},") ->",nl,
" fun 'dec_",ObjName,"'/3;", nl]),
NthObj
end,
@@ -1399,8 +1347,8 @@ gen_objset_dec(Erules, ObjSName, UniqueName, [{ObjName,Val,Fields}|T],
ClFields, NewNthObj);
gen_objset_dec(_,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName,
_ClFields,_NthObj) ->
- emit(["'getdec_",ObjSetName,"'(_) ->",nl]),
- emit([indent(2),"fun(_,Bytes, _RestPrimFieldName) ->",nl]),
+ emit([asis_atom(["getdec_",ObjSetName]),"(_) ->",nl,
+ indent(2),"fun(_,Bytes, _RestPrimFieldName) ->",nl]),
emit_dec_open_type(4),
emit([nl,
indent(2),"end.",nl,nl]),
@@ -1491,7 +1439,6 @@ emit_dec_open_type(I) ->
emit_inner_of_decfun(#typedef{name={ExtName,Name},typespec=Type}, _Prop,
InternalDefFunName) ->
OTag = Type#type.tag,
-%% Tag = [X#tag{class=decode_class(X#tag.class)}|| X <- OTag],
Tag = [(decode_class(X#tag.class) bsl 10) + X#tag.number || X <- OTag],
case {ExtName,Name} of
{primitive,bif} ->
@@ -1500,8 +1447,6 @@ emit_inner_of_decfun(#typedef{name={ExtName,Name},typespec=Type}, _Prop,
0;
{constructed,bif} ->
emit([indent(12),"'dec_",
-% asn1ct_gen:list2name(InternalDefFunName),"'(Bytes, ",Prop,
-% ", ",{asis,Tag},")"]),
asn1ct_gen:list2name(InternalDefFunName),"'(Bytes, ",
{asis,Tag},")"]),
1;
@@ -1515,7 +1460,6 @@ emit_inner_of_decfun(#typedef{name=Name},_Prop,_) ->
0;
emit_inner_of_decfun(#type{}=Type, _Prop, _) ->
OTag = Type#type.tag,
-%% Tag = [X#tag{class=decode_class(X#tag.class)}|| X <- OTag],
Tag = [(decode_class(X#tag.class) bsl 10) + X#tag.number || X <- OTag],
CurrMod = get(currmod),
Def = Type#type.def,
@@ -1527,11 +1471,9 @@ emit_inner_of_decfun(#type{}=Type, _Prop, _) ->
gen_dec_prim(Type, "Bytes", Tag);
#'Externaltypereference'{module=CurrMod,type=T} ->
emit([indent(9),T," ->",nl,indent(12),"'dec_",T,
-% "'(Bytes, ",Prop,")"]);
"'(Bytes)"]);
#'Externaltypereference'{module=ExtMod,type=T} ->
emit([indent(9),T," ->",nl,indent(12),ExtMod,":'dec_",
-% T,"'(Bytes, ",Prop,")"])
T,"'(Bytes, ",{asis,Tag},")"])
end,
0.
@@ -1546,10 +1488,6 @@ gen_internal_funcs(Erules,[TypeDef|Rest]) ->
gen_internal_funcs(Erules,Rest).
-dbdec(Type,Arg) ->
- demit({"io:format(\"decoding: ",{asis,Type},"~w~n\",[",Arg,"]),",nl}).
-
-
decode_class('UNIVERSAL') ->
?UNIVERSAL;
decode_class('APPLICATION') ->
@@ -1601,7 +1539,7 @@ encode_tag_val(Class, Form, TagNo) ->
%%%%%%%%%%%
%% mk_object_val(Value) -> {OctetList, Len}
-%% returns a Val as a list of octets, the 8 bit is allways set to one except
+%% returns a Val as a list of octets, the 8 bit is always set to one except
%% for the last octet, where its 0
%%
@@ -1615,8 +1553,9 @@ mk_object_val(0, Ack, Len) ->
mk_object_val(Val, Ack, Len) ->
mk_object_val(Val bsr 7, [((Val band 127) bor 128) | Ack], Len + 1).
-%% For BER the ExtensionAdditionGroup notation has no impact on the encoding/decoding
-%% and therefore we only filter away the ExtensionAdditionGroup start and end markers
+%% For BER the ExtensionAdditionGroup notation has no impact on the
+%% encoding/decoding. Therefore we can filter away the
+%% ExtensionAdditionGroup start and end markers.
extaddgroup2sequence(ExtList) when is_list(ExtList) ->
lists:filter(fun(#'ExtensionAdditionGroup'{}) ->
false;
@@ -1628,3 +1567,12 @@ extaddgroup2sequence(ExtList) when is_list(ExtList) ->
call(F, Args) ->
asn1ct_func:call(ber, F, Args).
+
+enc_func(Tname) ->
+ list_to_atom(lists:concat(["enc_",Tname])).
+
+dec_func(Tname) ->
+ list_to_atom(lists:concat(["dec_",Tname])).
+
+asis_atom(List) ->
+ {asis,list_to_atom(lists:concat(List))}.
diff --git a/lib/asn1/src/asn1ct_gen_check.erl b/lib/asn1/src/asn1ct_gen_check.erl
index abe77dd0cb..4996491fa7 100644
--- a/lib/asn1/src/asn1ct_gen_check.erl
+++ b/lib/asn1/src/asn1ct_gen_check.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2014-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,45 +21,51 @@
%%
-module(asn1ct_gen_check).
--export([emit/3]).
+-export([emit/4]).
-import(asn1ct_gen, [emit/1]).
-include("asn1_records.hrl").
-emit(Type, Default, Value) ->
+emit(Gen, Type, Default, Value) ->
Key = {Type,Default},
- Gen = fun(Fd, Name) ->
- file:write(Fd, gen(Name, Type, Default))
- end,
+ DoGen = fun(Fd, Name) ->
+ file:write(Fd, gen(Gen, Name, Type, Default))
+ end,
emit(" case "),
- asn1ct_func:call_gen("is_default_", Key, Gen, [Value]),
+ asn1ct_func:call_gen("is_default_", Key, DoGen, [Value]),
emit([" of",nl,
"true -> {[],0};",nl,
"false ->",nl]).
-gen(Name, #type{def=T}, Default) ->
+gen(#gen{pack=Pack}=Gen, Name, #type{def=T}, Default) ->
+ DefMarker = case Pack of
+ record -> "asn1_DEFAULT";
+ map -> atom_to_list(?MISSING_IN_MAP)
+ end,
NameStr = atom_to_list(Name),
- [NameStr,"(asn1_DEFAULT) ->\n",
- "true;\n"|case do_gen(T, Default) of
- {literal,Literal} ->
- [NameStr,"(",term2str(Literal),") ->\n","true;\n",
- NameStr,"(_) ->\n","false.\n\n"];
- {exception,Func,Args} ->
- [NameStr,"(Value) ->\n",
- "try ",Func,"(Value",arg2str(Args),") of\n",
- "_ -> true\n"
- "catch throw:false -> false\n"
- "end.\n\n"]
- end].
+ [NameStr,"(",DefMarker,") ->\n",
+ "true;\n"|
+ case do_gen(Gen, T, Default) of
+ {literal,Literal} ->
+ [NameStr,"(Def) when Def =:= ",term2str(Literal)," ->\n",
+ "true;\n",
+ NameStr,"(_) ->\n","false.\n\n"];
+ {exception,Func,Args} ->
+ [NameStr,"(Value) ->\n",
+ "try ",Func,"(Value",arg2str(Args),") of\n",
+ "_ -> true\n"
+ "catch throw:false -> false\n"
+ "end.\n\n"]
+ end].
-do_gen(_, asn1_NOVALUE) ->
+do_gen(_Gen, _, asn1_NOVALUE) ->
{literal,asn1_NOVALUE};
-do_gen(#'Externaltypereference'{module=M,type=T}, Default) ->
+do_gen(Gen, #'Externaltypereference'{module=M,type=T}, Default) ->
#typedef{typespec=#type{def=Td}} = asn1_db:dbget(M, T),
- do_gen(Td, Default);
-do_gen('BOOLEAN', Default) ->
+ do_gen(Gen, Td, Default);
+do_gen(_Gen, 'BOOLEAN', Default) ->
{literal,Default};
-do_gen({'BIT STRING',[]}, Default) ->
+do_gen(_Gen, {'BIT STRING',[]}, Default) ->
true = is_bitstring(Default), %Assertion.
case asn1ct:use_legacy_types() of
false ->
@@ -67,17 +73,17 @@ do_gen({'BIT STRING',[]}, Default) ->
true ->
{exception,need(check_legacy_bitstring, 2),[Default]}
end;
-do_gen({'BIT STRING',[_|_]=NBL}, Default) ->
+do_gen(_Gen, {'BIT STRING',[_|_]=NBL}, Default) ->
do_named_bitstring(NBL, Default);
-do_gen({'ENUMERATED',_}, Default) ->
+do_gen(_Gen, {'ENUMERATED',_}, Default) ->
{literal,Default};
-do_gen('INTEGER', Default) ->
+do_gen(_Gen, 'INTEGER', Default) ->
{literal,Default};
-do_gen({'INTEGER',NNL}, Default) ->
+do_gen(_Gen, {'INTEGER',NNL}, Default) ->
{exception,need(check_int, 3),[Default,NNL]};
-do_gen('NULL', Default) ->
+do_gen(_Gen, 'NULL', Default) ->
{literal,Default};
-do_gen('OCTET STRING', Default) ->
+do_gen(_Gen, 'OCTET STRING', Default) ->
true = is_binary(Default), %Assertion.
case asn1ct:use_legacy_types() of
false ->
@@ -85,34 +91,34 @@ do_gen('OCTET STRING', Default) ->
true ->
{exception,need(check_octetstring, 2),[Default]}
end;
-do_gen('OBJECT IDENTIFIER', Default0) ->
+do_gen(_Gen, 'OBJECT IDENTIFIER', Default0) ->
Default = pre_process_oid(Default0),
{exception,need(check_objectidentifier, 2),[Default]};
-do_gen({'CHOICE',Cs}, Default) ->
+do_gen(Gen, {'CHOICE',Cs}, Default) ->
{Tag,Value} = Default,
[Type] = [Type || #'ComponentType'{name=T,typespec=Type} <- Cs,
T =:= Tag],
- case do_gen(Type#type.def, Value) of
+ case do_gen(Gen, Type#type.def, Value) of
{literal,Lit} ->
{literal,{Tag,Lit}};
{exception,Func0,Args} ->
Key = {Tag,Func0,Args},
- Gen = fun(Fd, Name) ->
- S = gen_choice(Name, Tag, Func0, Args),
- ok = file:write(Fd, S)
+ DoGen = fun(Fd, Name) ->
+ S = gen_choice(Name, Tag, Func0, Args),
+ ok = file:write(Fd, S)
end,
- Func = asn1ct_func:call_gen("is_default_choice", Key, Gen),
+ Func = asn1ct_func:call_gen("is_default_choice", Key, DoGen),
{exception,atom_to_list(Func),[]}
end;
-do_gen(#'SEQUENCE'{components=Cs}, Default) ->
- do_seq_set(Cs, Default);
-do_gen({'SEQUENCE OF',Type}, Default) ->
- do_sof(Type, Default);
-do_gen(#'SET'{components=Cs}, Default) ->
- do_seq_set(Cs, Default);
-do_gen({'SET OF',Type}, Default) ->
- do_sof(Type, Default);
-do_gen(Type, Default) ->
+do_gen(Gen, #'SEQUENCE'{components=Cs}, Default) ->
+ do_seq_set(Gen, Cs, Default);
+do_gen(Gen, {'SEQUENCE OF',Type}, Default) ->
+ do_sof(Gen, Type, Default);
+do_gen(Gen, #'SET'{components=Cs}, Default) ->
+ do_seq_set(Gen, Cs, Default);
+do_gen(Gen, {'SET OF',Type}, Default) ->
+ do_sof(Gen, Type, Default);
+do_gen(_Gen, Type, Default) ->
case asn1ct_gen:unify_if_string(Type) of
restrictedstring ->
{exception,need(check_restrictedstring, 2),[Default]};
@@ -136,39 +142,58 @@ do_named_bitstring(_, Default) when is_bitstring(Default) ->
end,
{exception,need(Func, 3),[Default,bit_size(Default)]}.
-do_seq_set(Cs0, Default) ->
+do_seq_set(#gen{pack=record}=Gen, Cs0, Default) ->
Tag = element(1, Default),
Cs1 = [T || #'ComponentType'{typespec=T} <- Cs0],
- Cs = components(Cs1, tl(tuple_to_list(Default))),
+ Cs = components(Gen, Cs1, tl(tuple_to_list(Default))),
case are_all_literals(Cs) of
true ->
Literal = list_to_tuple([Tag|[L || {literal,L} <- Cs]]),
{literal,Literal};
false ->
Key = {Cs,Default},
- Gen = fun(Fd, Name) ->
- S = gen_components(Name, Tag, Cs),
- ok = file:write(Fd, S)
- end,
- Func = asn1ct_func:call_gen("is_default_cs_", Key, Gen),
+ DoGen = fun(Fd, Name) ->
+ S = gen_components(Name, Tag, Cs),
+ ok = file:write(Fd, S)
+ end,
+ Func = asn1ct_func:call_gen("is_default_cs_", Key, DoGen),
+ {exception,atom_to_list(Func),[]}
+ end;
+do_seq_set(#gen{pack=map}=Gen, Cs0, Default) ->
+ Cs1 = [{N,T} || #'ComponentType'{name=N,typespec=T} <- Cs0],
+ Cs = map_components(Gen, Cs1, Default),
+ AllLiterals = lists:all(fun({_,{literal,_}}) -> true;
+ ({_,_}) -> false
+ end, Cs),
+ case AllLiterals of
+ true ->
+ L = [{Name,Lit} || {Name,{literal,Lit}} <- Cs],
+ {literal,maps:from_list(L)};
+ false ->
+ Key = {Cs,Default},
+ DoGen = fun(Fd, Name) ->
+ S = gen_map_components(Name, Cs),
+ ok = file:write(Fd, S)
+ end,
+ Func = asn1ct_func:call_gen("is_default_cs_", Key, DoGen),
{exception,atom_to_list(Func),[]}
end.
-do_sof(Type, Default0) ->
+do_sof(Gen, Type, Default0) ->
Default = lists:sort(Default0),
Cs0 = lists:duplicate(length(Default), Type),
- Cs = components(Cs0, Default),
+ Cs = components(Gen, Cs0, Default),
case are_all_literals(Cs) of
true ->
Literal = [Lit || {literal,Lit} <- Cs],
{exception,need(check_literal_sof, 2),[Literal]};
false ->
Key = Cs,
- Gen = fun(Fd, Name) ->
- S = gen_sof(Name, Cs),
- ok = file:write(Fd, S)
+ DoGen = fun(Fd, Name) ->
+ S = gen_sof(Name, Cs),
+ ok = file:write(Fd, S)
end,
- Func = asn1ct_func:call_gen("is_default_sof", Key, Gen),
+ Func = asn1ct_func:call_gen("is_default_sof", Key, DoGen),
{exception,atom_to_list(Func),[]}
end.
@@ -199,6 +224,39 @@ gen_cs_2([], _) ->
"throw(false)\n"
"end.\n"].
+gen_map_components(Name, Cs) ->
+ [atom_to_list(Name),"(Value) ->\n",
+ "case Value of\n",
+ "#{"|gen_map_cs_1(Cs, 1, "", [])].
+
+gen_map_cs_1([{Name,{literal,Lit}}|T], I, Sep, Acc) ->
+ Var = "E"++integer_to_list(I),
+ G = Var ++ " =:= " ++ term2str(Lit),
+ [Sep,term2str(Name),":=",Var|
+ gen_map_cs_1(T, I+1, ",\n", [{guard,G}|Acc])];
+gen_map_cs_1([{Name,Exc}|T], I, Sep, Acc) ->
+ Var = "E"++integer_to_list(I),
+ [Sep,term2str(Name),":=",Var|
+ gen_map_cs_1(T, I+1, ",\n", [{exc,{Var,Exc}}|Acc])];
+gen_map_cs_1([], _, _, Acc) ->
+ G = lists:join(", ", [S || {guard,S} <- Acc]),
+ Exc = [E || {exc,E} <- Acc],
+ Body = gen_map_cs_2(Exc, ""),
+ case G of
+ [] ->
+ ["} ->\n"|Body];
+ [_|_] ->
+ ["} when ",G," ->\n"|Body]
+ end.
+
+gen_map_cs_2([{Var,{exception,Func,Args}}|T], Sep) ->
+ [Sep,Func,"(",Var,arg2str(Args),")"|gen_map_cs_2(T, ",\n")];
+gen_map_cs_2([], _) ->
+ [";\n",
+ "_ ->\n"
+ "throw(false)\n"
+ "end.\n"].
+
gen_sof(Name, Cs) ->
[atom_to_list(Name),"(Value) ->\n",
"case length(Value) of\n",
@@ -221,9 +279,18 @@ gen_sof_1([{exception,Func,Args}|Cs], I) ->
gen_sof_1([], _) ->
".\n".
-components([#type{def=Def}|Ts], [V|Vs]) ->
- [do_gen(Def, V)|components(Ts, Vs)];
-components([], []) -> [].
+components(Gen, [#type{def=Def}|Ts], [V|Vs]) ->
+ [do_gen(Gen, Def, V)|components(Gen, Ts, Vs)];
+components(_Gen, [], []) -> [].
+
+map_components(Gen, [{Name,#type{def=Def}}|Ts], Value) ->
+ case maps:find(Name, Value) of
+ {ok,V} ->
+ [{Name,do_gen(Gen, Def, V)}|map_components(Gen, Ts, Value)];
+ error ->
+ map_components(Gen, Ts, Value)
+ end;
+map_components(_Gen, [], _Value) -> [].
gen_choice(Name, Tag, Func, Args) ->
NameStr = atom_to_list(Name),
diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl
index aa7223904e..28b4e46b0c 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@
%% all types in an ASN.1 module
-include("asn1_records.hrl").
-%-compile(export_all).
-export([gen_dec_imm/2]).
-export([gen_dec_prim/3,gen_encode_prim_imm/3]).
@@ -35,15 +34,20 @@
-export([extaddgroup2sequence/1]).
-export([dialyzer_suppressions/1]).
--import(asn1ct_gen, [emit/1,demit/1]).
+-import(asn1ct_gen, [emit/1]).
-import(asn1ct_func, [call/3]).
-%% Generate ENCODING ******************************
-%%****************************************x
+%%****************************************
+%% Generate ENCODING
+%%****************************************
-dialyzer_suppressions(Erules) ->
- case asn1ct_func:is_used({Erules,complete,1}) of
+dialyzer_suppressions(#gen{erule=per,aligned=Aligned}) ->
+ Mod = case Aligned of
+ false -> uper;
+ true -> per
+ end,
+ case asn1ct_func:is_used({Mod,complete,1}) of
false ->
ok;
true ->
@@ -54,14 +58,6 @@ dialyzer_suppressions(Erules) ->
gen_encode(Erules,Type) when is_record(Type,typedef) ->
gen_encode_user(Erules,Type).
-%% case Type#typedef.typespec of
-%% Def when is_record(Def,type) ->
-%% gen_encode_user(Erules,Type);
-%% Def when is_tuple(Def),(element(1,Def) == 'Object') ->
-%% gen_encode_object(Erules,Type);
-%% Other ->
-%% exit({error,{asn1,{unknown,Other}}})
-%% end.
gen_encode(Erules,Typename,#'ComponentType'{name=Cname,typespec=Type}) ->
NewTypename = [Cname|Typename],
@@ -72,15 +68,14 @@ gen_encode(Erules,Typename,Type) when is_record(Type,type) ->
ObjFun =
case lists:keysearch(objfun,1,Type#type.tablecinf) of
{value,{_,_Name}} ->
-%% lists:concat([", ObjFun",Name]);
", ObjFun";
false ->
""
end,
case asn1ct_gen:type(InnerType) of
{constructed,bif} ->
- emit({"'enc_",asn1ct_gen:list2name(Typename),"'(Val",ObjFun,
- ") ->",nl}),
+ Func = enc_func(asn1ct_gen:list2name(Typename)),
+ emit([{asis,Func},"(Val",ObjFun,") ->",nl]),
asn1ct_gen:gen_encode_constructed(Erules,Typename,InnerType,Type);
_ ->
true
@@ -92,20 +87,21 @@ gen_encode_user(Erules,D) when is_record(D,typedef) ->
Typename = [D#typedef.name],
Def = D#typedef.typespec,
InnerType = asn1ct_gen:get_inner(Def#type.def),
- emit({"'enc_",asn1ct_gen:list2name(Typename),"'(Val) ->",nl}),
+ Func = enc_func(asn1ct_gen:list2name(Typename)),
+ emit([{asis,Func},"(Val) ->",nl]),
case asn1ct_gen:type(InnerType) of
{primitive,bif} ->
gen_encode_prim(Erules, Def),
- emit({".",nl});
+ emit([".",nl]);
'ASN1_OPEN_TYPE' ->
gen_encode_prim(Erules, Def#type{def='ASN1_OPEN_TYPE'}),
- emit({".",nl});
+ emit([".",nl]);
{constructed,bif} ->
asn1ct_gen:gen_encode_constructed(Erules,Typename,InnerType,D);
#'Externaltypereference'{module=CurrMod,type=Etype} ->
- emit({"'enc_",Etype,"'(Val).",nl,nl});
+ emit([{asis,enc_func(Etype)},"(Val).",nl]);
#'Externaltypereference'{module=Emod,type=Etype} ->
- emit({"'",Emod,"':'enc_",Etype,"'(Val).",nl,nl})
+ emit([{asis,Emod},":",enc_func(Etype),"(Val).",nl])
end.
@@ -113,11 +109,7 @@ gen_encode_prim(Erules, D) ->
Value = {var,atom_to_list(asn1ct_gen:mk_var(asn1ct_name:curr(val)))},
gen_encode_prim(Erules, D, Value).
-gen_encode_prim(Erules, #type{}=D, Value) ->
- Aligned = case Erules of
- uper -> false;
- per -> true
- end,
+gen_encode_prim(#gen{erule=per,aligned=Aligned}, #type{}=D, Value) ->
Imm = gen_encode_prim_imm(Value, D, Aligned),
asn1ct_imm:enc_cg(Imm, Aligned).
@@ -224,7 +216,6 @@ gen_objectset_code(_Erules, _ObjSet) ->
gen_decode(Erules, #typedef{}=Type) ->
DecFunc = dec_func(Type#typedef.name),
emit([nl,nl,{asis,DecFunc},"(Bytes) ->",nl]),
- dbdec(Type#typedef.name),
gen_decode_user(Erules, Type).
gen_decode(Erules,Tname,#'ComponentType'{name=Cname,typespec=Type}) ->
@@ -245,17 +236,11 @@ gen_decode(Erules,Typename,Type) when is_record(Type,type) ->
emit([nl,
{asis,dec_func(asn1ct_gen:list2name(Typename))},
"(Bytes",ObjFun,") ->",nl]),
- dbdec(Typename),
asn1ct_gen:gen_decode_constructed(Erules,Typename,InnerType,Type);
_ ->
true
end.
-dbdec(Type) when is_list(Type)->
- demit({"io:format(\"decoding: ",asn1ct_gen:list2name(Type),"~w~n\",[Bytes]),",nl});
-dbdec(Type) ->
- demit({"io:format(\"decoding: ",{asis,Type},"~w~n\",[Bytes]),",nl}).
-
gen_decode_user(Erules,D) when is_record(D,typedef) ->
Typename = [D#typedef.name],
Def = D#typedef.typespec,
@@ -263,17 +248,15 @@ gen_decode_user(Erules,D) when is_record(D,typedef) ->
case asn1ct_gen:type(InnerType) of
{primitive,bif} ->
gen_dec_prim(Erules,Def,"Bytes"),
- emit({".",nl,nl});
+ emit([".",nl,nl]);
'ASN1_OPEN_TYPE' ->
gen_dec_prim(Erules,Def#type{def='ASN1_OPEN_TYPE'},"Bytes"),
- emit({".",nl,nl});
+ emit([".",nl,nl]);
{constructed,bif} ->
asn1ct_gen:gen_decode_constructed(Erules,Typename,InnerType,D);
#'Externaltypereference'{}=Etype ->
gen_dec_external(Etype, "Bytes"),
- emit([".",nl,nl]);
- Other ->
- exit({error,{asn1,{unknown,Other}}})
+ emit([".",nl,nl])
end.
gen_dec_external(Ext, BytesVar) ->
@@ -284,11 +267,7 @@ gen_dec_external(Ext, BytesVar) ->
_ -> [{asis,Mod},":"]
end,{asis,dec_func(Type)},"(",BytesVar,")"]).
-gen_dec_imm(Erule, #type{def=Name,constraint=C}) ->
- Aligned = case Erule of
- uper -> false;
- per -> true
- end,
+gen_dec_imm(#gen{erule=per,aligned=Aligned}, #type{def=Name,constraint=C}) ->
gen_dec_imm_1(Name, C, Aligned).
gen_dec_imm_1('ASN1_OPEN_TYPE', Constraint, Aligned) ->
@@ -406,10 +385,11 @@ gen_dec_prim(Erule, Type, BytesVar) ->
asn1ct_imm:dec_code_gen(Imm, BytesVar).
-%% For PER the ExtensionAdditionGroup notation has significance for the encoding and decoding
-%% the components within the ExtensionAdditionGroup is treated in a similar way as if they
-%% have been specified within a SEQUENCE, therefore we construct a fake sequence type here
-%% so that we can generate code for it
+%% For PER the ExtensionAdditionGroup notation has significance for
+%% the encoding and decoding. The components within the
+%% ExtensionAdditionGroup is treated in a similar way as if they have
+%% been specified within a SEQUENCE. Therefore we construct a fake
+%% sequence type here so that we can generate code for it.
extaddgroup2sequence(ExtList) ->
extaddgroup2sequence(ExtList,0,[]).
diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl
index 8b96242c56..231048694a 100644
--- a/lib/asn1/src/asn1ct_imm.erl
+++ b/lib/asn1/src/asn1ct_imm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -37,9 +37,12 @@
per_enc_open_type/2,
per_enc_restricted_string/3,
per_enc_small_number/2]).
--export([per_enc_extension_bit/2,per_enc_extensions/4,per_enc_optional/3]).
+-export([per_enc_extension_bit/2,per_enc_extensions/4,
+ per_enc_extensions_map/4,
+ per_enc_optional/2]).
-export([per_enc_sof/5]).
--export([enc_absent/3,enc_append/1,enc_element/2]).
+-export([enc_absent/3,enc_append/1,enc_element/2,enc_maps_get/2,
+ enc_comment/1]).
-export([enc_cg/2]).
-export([optimize_alignment/1,optimize_alignment/2,
dec_slim_cg/2,dec_code_gen/2]).
@@ -214,7 +217,8 @@ per_enc_legacy_bit_string(Val0, NNL0, Constraint0, Aligned) ->
per_enc_boolean(Val0, _Aligned) ->
{B,[Val]} = mk_vars(Val0, []),
B++build_cond([[{eq,Val,false},{put_bits,0,1,[1]}],
- [{eq,Val,true},{put_bits,1,1,[1]}]]).
+ [{eq,Val,true},{put_bits,1,1,[1]}],
+ ['_',{error,{illegal_boolean,Val}}]]).
per_enc_choice(Val0, Cs0, _Aligned) ->
{B,[Val]} = mk_vars(Val0, []),
@@ -235,7 +239,7 @@ per_enc_enumerated(Val0, Root, Aligned) ->
B++[{'cond',Cs++enumerated_error(Val)}].
enumerated_error(Val) ->
- [['_',{error,Val}]].
+ [['_',{error,{illegal_enumerated,Val}}]].
per_enc_integer(Val0, Constraint0, Aligned) ->
{B,[Val]} = mk_vars(Val0, []),
@@ -349,27 +353,32 @@ per_enc_extensions(Val0, Pos0, NumBits, Aligned) when NumBits > 0 ->
['_'|Length ++ PutBits]]}],
{var,"Extensions"}}].
-per_enc_optional(Val0, {Pos,DefVals}, _Aligned) when is_integer(Pos),
- is_list(DefVals) ->
- {B,Val} = enc_element(Pos, Val0),
+per_enc_extensions_map(Val0, Vars, Undefined, Aligned) ->
+ NumBits = length(Vars),
+ {B,[_Val,Bitmap]} = mk_vars(Val0, [bitmap]),
+ Length = per_enc_small_length(NumBits, Aligned),
+ PutBits = case NumBits of
+ 1 -> [{put_bits,1,1,[1]}];
+ _ -> [{put_bits,Bitmap,NumBits,[1]}]
+ end,
+ BitmapExpr = extensions_bitmap(Vars, Undefined),
+ B++[{assign,Bitmap,BitmapExpr},
+ {list,[{'cond',[[{eq,Bitmap,0}],
+ ['_'|Length ++ PutBits]]}],
+ {var,"Extensions"}}].
+
+per_enc_optional(Val, DefVals) when is_list(DefVals) ->
Zero = {put_bits,0,1,[1]},
One = {put_bits,1,1,[1]},
- B++[{'cond',
- [[{eq,Val,DefVal},Zero] || DefVal <- DefVals] ++ [['_',One]]}];
-per_enc_optional(Val0, {Pos,{call,M,F,A}}, _Aligned) when is_integer(Pos) ->
- {B,Val} = enc_element(Pos, Val0),
+ [{'cond',
+ [[{eq,Val,DefVal},Zero] || DefVal <- DefVals] ++ [['_',One]]}];
+per_enc_optional(Val, {call,M,F,A}) ->
{[],[[],Tmp]} = mk_vars([], [tmp]),
Zero = {put_bits,0,1,[1]},
One = {put_bits,1,1,[1]},
- B++[{call,M,F,[Val|A],Tmp},
- {'cond',
- [[{eq,Tmp,true},Zero],['_',One]]}];
-per_enc_optional(Val0, Pos, _Aligned) when is_integer(Pos) ->
- {B,Val} = enc_element(Pos, Val0),
- Zero = {put_bits,0,1,[1]},
- One = {put_bits,1,1,[1]},
- B++[{'cond',[[{eq,Val,asn1_NOVALUE},Zero],
- ['_',One]]}].
+ [{call,M,F,[Val|A],Tmp},
+ {'cond',
+ [[{eq,Tmp,true},Zero],['_',One]]}].
per_enc_sof(Val0, Constraint, ElementVar, ElementImm, Aligned) ->
{B,[Val,Len]} = mk_vars(Val0, [len]),
@@ -423,6 +432,16 @@ enc_element(N, Val0) ->
{[],[Val,Dst]} = mk_vars(Val0, [element]),
{[{call,erlang,element,[N,Val],Dst}],Dst}.
+enc_maps_get(N, Val0) ->
+ {[],[Val,Dst0]} = mk_vars(Val0, [element]),
+ {var,Dst} = Dst0,
+ DstExpr = {expr,lists:concat(["#{",N,":=",Dst,"}"])},
+ {var,SrcVar} = Val,
+ {[{assign,DstExpr,SrcVar}],Dst0}.
+
+enc_comment(Comment) ->
+ {comment,Comment}.
+
enc_cg(Imm0, false) ->
Imm1 = enc_cse(Imm0),
Imm2 = enc_pre_cg(Imm1),
@@ -860,10 +879,8 @@ flatten_map_cs_1([integer_default], {Int,_}) ->
[{'_',Int}];
flatten_map_cs_1([enum_default], {Int,_}) ->
[{'_',["{asn1_enum,",Int,"}"]}];
-flatten_map_cs_1([enum_error], {Var,Cs}) ->
- Vs = [V || {_,V} <- Cs],
- [{'_',["exit({error,{asn1,{decode_enumerated,{",Var,",",
- {asis,Vs},"}}}})"]}];
+flatten_map_cs_1([enum_error], {Var,_}) ->
+ [{'_',["exit({error,{asn1,{decode_enumerated,",Var,"}}})"]}];
flatten_map_cs_1([], _) -> [].
flatten_hoist_align([[{align_bits,_,_}=Ab|T]|Cs]) ->
@@ -1037,6 +1054,7 @@ split_off_nonbuilding(Imm) ->
is_nonbuilding({assign,_,_}) -> true;
is_nonbuilding({call,_,_,_,_}) -> true;
+is_nonbuilding({comment,_}) -> true;
is_nonbuilding({lc,_,_,_,_}) -> true;
is_nonbuilding({set,_,_}) -> true;
is_nonbuilding({list,_,_}) -> true;
@@ -1093,7 +1111,7 @@ per_enc_integer_1(Val0, [{{_,_}=Constr,[]}], Aligned) ->
per_enc_integer_1(Val0, [Constr], Aligned) ->
{Prefix,Check,Action} = per_enc_integer_2(Val0, Constr, Aligned),
Prefix++build_cond([[Check|Action],
- ['_',{error,Val0}]]).
+ ['_',{error,{illegal_integer,Val0}}]]).
per_enc_integer_2(Val, {'SingleValue',Sv}, Aligned) when is_integer(Sv) ->
per_enc_constrained(Val, Sv, Sv, Aligned);
@@ -1240,6 +1258,20 @@ enc_length(Len, {Lb,Ub}, Aligned) when is_integer(Lb) ->
enc_length(Len, Sv, _Aligned) when is_integer(Sv) ->
[{'cond',[[{eq,Len,Sv}]]}].
+extensions_bitmap(Vs, Undefined) ->
+ Highest = 1 bsl (length(Vs)-1),
+ Cs = extensions_bitmap_1(Vs, Undefined, Highest),
+ lists:flatten(lists:join(" bor ", Cs)).
+
+extensions_bitmap_1([{var,V}|Vs], Undefined, Power) ->
+ S = ["case ",V," of\n",
+ " ",Undefined," -> 0;\n"
+ " _ -> ",integer_to_list(Power),"\n"
+ "end"],
+ [S|extensions_bitmap_1(Vs, Undefined, Power bsr 1)];
+extensions_bitmap_1([], _, _) ->
+ [].
+
put_bits_binary(Bin, _Unit, Aligned) when is_binary(Bin) ->
Sz = byte_size(Bin),
<<Int:Sz/unit:8>> = Bin,
@@ -1903,6 +1935,8 @@ enc_opt({'cond',Cs0}, St0) ->
{Cs,Type} = enc_opt_cond_1(Cs1, Type0, [{Cond,Imm}]),
{{'cond',Cs},St0#ost{t=Type}}
end;
+enc_opt({comment,_}=Imm, St) ->
+ {Imm,St#ost{t=undefined}};
enc_opt({cons,H0,T0}, St0) ->
{H,#ost{t=TypeH}=St1} = enc_opt(H0, St0),
{T,#ost{t=TypeT}=St} = enc_opt(T0, St1),
@@ -2292,6 +2326,9 @@ enc_cg({block,Imm}) ->
enc_cg(Imm),
emit([nl,
"end"]);
+enc_cg({seq,{comment,Comment},Then}) ->
+ emit(["%% ",Comment,nl]),
+ enc_cg(Then);
enc_cg({seq,First,Then}) ->
enc_cg(First),
emit([com,nl]),
@@ -2325,9 +2362,9 @@ enc_cg({'cond',Cs}) ->
enc_cg_cond(Cs);
enc_cg({error,Error}) when is_function(Error, 0) ->
Error();
-enc_cg({error,Var0}) ->
+enc_cg({error,{Tag,Var0}}) ->
Var = mk_val(Var0),
- emit(["exit({error,{asn1,{illegal_value,",Var,"}}})"]);
+ emit(["exit({error,{asn1,{",Tag,",",Var,"}}})"]);
enc_cg({integer,Int}) ->
emit(mk_val(Int));
enc_cg({lc,Body,Var,List}) ->
@@ -2590,6 +2627,8 @@ enc_opt_al({call,per_common,encode_unconstrained_number,[_]}=Call, _) ->
{[Call],0};
enc_opt_al({call,_,_,_,_}=Call, Al) ->
{[Call],Al};
+enc_opt_al({comment,_}=Imm, Al) ->
+ {[Imm],Al};
enc_opt_al({'cond',Cs0}, Al0) ->
{Cs,Al} = enc_opt_al_cond(Cs0, Al0),
{[{'cond',Cs}],Al};
@@ -2686,6 +2725,8 @@ per_fixup([{block,Block}|T]) ->
[{block,per_fixup(Block)}|per_fixup(T)];
per_fixup([{'assign',_,_}=H|T]) ->
[H|per_fixup(T)];
+per_fixup([{comment,_}=H|T]) ->
+ [H|per_fixup(T)];
per_fixup([{'cond',Cs0}|T]) ->
Cs = [[C|per_fixup(Act)] || [C|Act] <- Cs0],
[{'cond',Cs}|per_fixup(T)];
diff --git a/lib/asn1/src/asn1ct_name.erl b/lib/asn1/src/asn1ct_name.erl
index 72d541cbbc..281608f3ae 100644
--- a/lib/asn1/src/asn1ct_name.erl
+++ b/lib/asn1/src/asn1ct_name.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
%%
-module(asn1ct_name).
-%%-compile(export_all).
-export([start/0,
curr/1,
clear/0,
@@ -44,7 +43,6 @@ start() ->
end.
name_server_loop({Ref, Parent} = Monitor,Vars) ->
-%% io:format("name -- ~w~n",[Vars]),
receive
{_From,clear} ->
name_server_loop(Monitor, []);
diff --git a/lib/asn1/src/asn1ct_parser2.erl b/lib/asn1/src/asn1ct_parser2.erl
index 2de9b0e2f0..35c921e98d 100644
--- a/lib/asn1/src/asn1ct_parser2.erl
+++ b/lib/asn1/src/asn1ct_parser2.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1496,7 +1496,7 @@ parse_ContentsConstraint([{'ENCODED',_},{'BY',_}|Rest]) ->
parse_ContentsConstraint(Tokens) ->
parse_error(Tokens).
-% X.683 Parameterization of ASN.1 specifications
+%% X.683 Parameterization of ASN.1 specifications
parse_Governor(Tokens) ->
Flist = [fun parse_Type/1,
diff --git a/lib/asn1/src/asn1ct_value.erl b/lib/asn1/src/asn1ct_value.erl
index 57cd3f8af6..05fe2f4ef4 100644
--- a/lib/asn1/src/asn1ct_value.erl
+++ b/lib/asn1/src/asn1ct_value.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,18 +19,17 @@
%%
%%
-module(asn1ct_value).
--compile([{nowarn_deprecated_function,{asn1rt,utf8_list_to_binary,1}}]).
%% Generate Erlang values for ASN.1 types.
%% The value is randomized within it's constraints
-include("asn1_records.hrl").
-%-compile(export_all).
-export([from_type/2]).
-%% Generate examples of values ******************************
-%%****************************************x
+%%****************************************
+%% Generate examples of values
+%%****************************************
from_type(M,Typename) ->
@@ -65,7 +64,11 @@ from_type(M,Typename,Type) when is_record(Type,type) ->
end;
{constructed,bif} when Typename == ['EXTERNAL'] ->
Val=from_type_constructed(M,Typename,InnerType,Type),
- asn1ct_eval_ext:transform_to_EXTERNAL1994(Val);
+ T = case M:maps() of
+ false -> transform_to_EXTERNAL1994;
+ true -> transform_to_EXTERNAL1994_maps
+ end,
+ asn1ct_eval_ext:T(Val);
{constructed,bif} ->
from_type_constructed(M,Typename,InnerType,Type)
end;
@@ -89,9 +92,6 @@ get_inner(T) when is_tuple(T) ->
Other ->
Other
end.
-%%get_inner(T) when is_tuple(T) -> element(1,T).
-
-
from_type_constructed(M,Typename,InnerType,D) when is_record(D,type) ->
case InnerType of
@@ -108,9 +108,7 @@ from_type_constructed(M,Typename,InnerType,D) when is_record(D,type) ->
'SET OF' ->
{_,Type} = D#type.def,
NameSuffix = asn1ct_gen:constructed_suffix(InnerType,Type#type.def),
- get_sequence_of(M,Typename,D,NameSuffix);
- _ ->
- exit({nyi,InnerType})
+ get_sequence_of(M,Typename,D,NameSuffix)
end.
get_sequence(M,Typename,Type) ->
@@ -119,11 +117,13 @@ get_sequence(M,Typename,Type) ->
#'SEQUENCE'{components=Cl} -> {'SEQUENCE',Cl};
#'SET'{components=Cl} -> {'SET',to_textual_order(Cl)}
end,
- case get_components(M,Typename,CompList) of
- [] ->
- {list_to_atom(asn1ct_gen:list2rname(Typename))};
- C ->
- list_to_tuple([list_to_atom(asn1ct_gen:list2rname(Typename))|C])
+ Cs = get_components(M, Typename, CompList),
+ case M:maps() of
+ false ->
+ RecordTag = list_to_atom(asn1ct_gen:list2rname(Typename)),
+ list_to_tuple([RecordTag|[Val || {_,Val} <- Cs]]);
+ true ->
+ maps:from_list(Cs)
end.
get_components(M,Typename,{Root,Ext}) ->
@@ -131,9 +131,9 @@ get_components(M,Typename,{Root,Ext}) ->
%% Should enhance this *** HERE *** with proper handling of extensions
-get_components(M,Typename,[H|T]) ->
- [from_type(M,Typename,H)|
- get_components(M,Typename,T)];
+get_components(M, Typename, [H|T]) ->
+ #'ComponentType'{name=Name} = H,
+ [{Name,from_type(M, Typename, H)}|get_components(M, Typename, T)];
get_components(_,_,[]) ->
[].
@@ -142,7 +142,8 @@ get_choice(M,Typename,Type) ->
case TCompList of
[] ->
{asn1_EMPTY,asn1_EMPTY};
- {CompList,ExtList} -> % Should be enhanced to handle extensions too
+ {CompList,ExtList} ->
+ %% should be enhanced to handle extensions too.
CList = CompList ++ ExtList,
C = lists:nth(random(length(CList)),CList),
{C#'ComponentType'.name,from_type(M,Typename,C)};
@@ -242,14 +243,6 @@ from_type_prim(M, D) ->
_ ->
{2#11111111,2,2}
end;
-%% Sign1 = random_sign(integer),
-%% Sign2 = random_sign(integer),
-%% {Sign1*random(10000),2,Sign2*random(1028)};
-%% 2 ->
-%% %% base 10 tuple format
-%% Sign1 = random_sign(integer),
-%% Sign2 = random_sign(integer),
-%% {Sign1*random(10000),10,Sign2*random(1028)};
_ ->
%% base 10 string format, NR3 format
case random(2) of
@@ -292,12 +285,12 @@ from_type_prim(M, D) ->
'BMPString' ->
adjust_list(size_random(C),c_string(C,"BMPString"));
'UTF8String' ->
- {ok,Res}=asn1rt:utf8_list_to_binary(adjust_list(random(50),[$U,$T,$F,$8,$S,$t,$r,$i,$n,$g,16#ffff,16#fffffff,16#ffffff,16#fffff,16#fff])),
- Res;
+ L = adjust_list(random(50),
+ [$U,$T,$F,$8,$S,$t,$r,$i,$n,$g,
+ 16#ffff,16#ffee,16#10ffff,16#ffff,16#fff]),
+ unicode:characters_to_binary(L);
'UniversalString' ->
- adjust_list(size_random(C),c_string(C,"UniversalString"));
- XX ->
- exit({asn1_error,nyi,XX})
+ adjust_list(size_random(C),c_string(C,"UniversalString"))
end.
c_string(C,Default) ->
@@ -336,22 +329,6 @@ random_unnamed_bit_string(M, C) ->
{PadLen,<<BitString/bitstring,0:PadLen>>}
end.
-%% FIXME:
-%% random_sign(integer) ->
-%% case random(2) of
-%% 2 ->
-%% -1;
-%% _ ->
-%% 1
-%% end;
-%% random_sign(string) ->
-%% case random(2) of
-%% 2 ->
-%% "-";
-%% _ ->
-%% ""
-%% end.
-
random(Upper) ->
rand:uniform(Upper).
@@ -402,13 +379,6 @@ c_random(VRange,Single) ->
S;
{_,S} when is_list(S) ->
lists:nth(random(length(S)),S)
-%% {S1,S2} ->
-%% io:format("asn1ct_value: hejsan hoppsan~n");
-%% _ ->
-%% io:format("asn1ct_value: hejsan hoppsan 2~n")
-%% io:format("asn1ct_value: c_random/2: S1 = ~w~n"
-%% "S2 = ~w,~n",[S1,S2])
-%% exit(self(),goodbye)
end.
adjust_list(Len,Orig) ->
diff --git a/lib/asn1/src/asn1rt.erl b/lib/asn1/src/asn1rt.erl
deleted file mode 100644
index 3e09ce2252..0000000000
--- a/lib/asn1/src/asn1rt.erl
+++ /dev/null
@@ -1,184 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%%
--module(asn1rt).
--deprecated(module).
-
-%% Runtime functions for ASN.1 (i.e encode, decode)
-
--export([encode/2,encode/3,decode/3,load_driver/0,unload_driver/0,info/1]).
-
--export([utf8_binary_to_list/1,utf8_list_to_binary/1]).
-
-encode(Module,{Type,Term}) ->
- encode(Module,Type,Term).
-
-encode(Module,Type,Term) ->
- case catch apply(Module,encode,[Type,Term]) of
- {'EXIT',undef} ->
- {error,{asn1,{undef,Module,Type}}};
- Result ->
- Result
- end.
-
-decode(Module,Type,Bytes) ->
- case catch apply(Module,decode,[Type,Bytes]) of
- {'EXIT',undef} ->
- {error,{asn1,{undef,Module,Type}}};
- Result ->
- Result
- end.
-
-%% Remove in R16A
-load_driver() ->
- ok.
-
-unload_driver() ->
- ok.
-
-info(Module) ->
- case catch apply(Module,info,[]) of
- {'EXIT',{undef,_Reason}} ->
- {error,{asn1,{undef,Module,info}}};
- Result ->
- {ok,Result}
- end.
-
-%% utf8_binary_to_list/1 transforms a utf8 encoded binary to a list of
-%% unicode elements, where each element is the unicode integer value
-%% of a utf8 character.
-%% Bin is a utf8 encoded value. The return value is either {ok,Val} or
-%% {error,Reason}. Val is a list of integers, where each integer is a
-%% unicode character value.
-utf8_binary_to_list(Bin) when is_binary(Bin) ->
- utf8_binary_to_list(Bin,[]).
-
-utf8_binary_to_list(<<>>,Acc) ->
- {ok,lists:reverse(Acc)};
-utf8_binary_to_list(Bin,Acc) ->
- Len = utf8_binary_len(Bin),
- case catch split_binary(Bin,Len) of
- {CharBin,RestBin} ->
- case utf8_binary_char(CharBin) of
- C when is_integer(C) ->
- utf8_binary_to_list(RestBin,[C|Acc]);
- Err -> Err
- end;
- Err -> {error,{asn1,{bad_encoded_utf8string,Err}}}
- end.
-
-utf8_binary_len(<<0:1,_:7,_/binary>>) ->
- 1;
-utf8_binary_len(<<1:1,1:1,0:1,_:5,_/binary>>) ->
- 2;
-utf8_binary_len(<<1:1,1:1,1:1,0:1,_:4,_/binary>>) ->
- 3;
-utf8_binary_len(<<1:1,1:1,1:1,1:1,0:1,_:3,_/binary>>) ->
- 4;
-utf8_binary_len(<<1:1,1:1,1:1,1:1,1:1,0:1,_:2,_/binary>>) ->
- 5;
-utf8_binary_len(<<1:1,1:1,1:1,1:1,1:1,1:1,0:1,_:1,_/binary>>) ->
- 6;
-utf8_binary_len(Bin) ->
- {error,{asn1,{bad_utf8_length,Bin}}}.
-
-utf8_binary_char(<<0:1,Int:7>>) ->
- Int;
-utf8_binary_char(<<_:2,0:1,Int1:5,1:1,0:1,Int2:6>>) ->
- (Int1 bsl 6) bor Int2;
-utf8_binary_char(<<_:3,0:1,Int1:4,1:1,0:1,Int2:6,1:1,0:1,Int3:6>>) ->
- <<Res:16>> = <<Int1:4,Int2:6,Int3:6>>,
- Res;
-utf8_binary_char(<<_:4,0:1,Int1:3,Rest/binary>>) ->
- <<1:1,0:1,Int2:6,1:1,0:1,Int3:6,1:1,0:1,Int4:6>> = Rest,
- <<Res:24>> = <<0:3,Int1:3,Int2:6,Int3:6,Int4:6>>,
- Res;
-utf8_binary_char(<<_:5,0:1,Int1:2,Rest/binary>>) ->
- <<1:1,0:1,Int2:6,1:1,0:1,Int3:6,1:1,0:1,Int4:6,1:1,0:1,Int5:6>> = Rest,
- <<Res:32>> = <<0:6,Int1:2,Int2:6,Int3:6,Int4:6,Int5:6>>,
- Res;
-utf8_binary_char(<<_:6,0:1,I:1,Rest/binary>>) ->
- <<1:1,0:1,Int2:6,1:1,0:1,Int3:6,1:1,0:1,Int4:6,1:1,0:1,
- Int5:6,1:1,0:1,Int6:6>> = Rest,
- <<Res:32>> = <<0:1,I:1,Int2:6,Int3:6,Int4:6,Int5:6,Int6:6>>,
- Res;
-utf8_binary_char(Err) ->
- {error,{asn1,{bad_utf8_character_encoding,Err}}}.
-
-
-%% macros used for utf8 encoding
--define(bit1to6_into_utf8byte(I),16#80 bor (I band 16#3f)).
--define(bit7to12_into_utf8byte(I),16#80 bor ((I band 16#fc0) bsr 6)).
--define(bit13to18_into_utf8byte(I),16#80 bor ((I band 16#3f000) bsr 12)).
--define(bit19to24_into_utf8byte(I),16#80 bor ((Int band 16#fc0000) bsr 18)).
--define(bit25to30_into_utf8byte(I),16#80 bor ((Int band 16#3f000000) bsr 24)).
-
-%% utf8_list_to_binary/1 transforms a list of integers to a
-%% binary. Each element in the input list has the unicode (integer)
-%% value of an utf8 character.
-%% The return value is either {ok,Bin} or {error,Reason}. The
-%% resulting binary is utf8 encoded.
-utf8_list_to_binary(List) ->
- utf8_list_to_binary(List,[]).
-
-utf8_list_to_binary([],Acc) when is_list(Acc) ->
- {ok,list_to_binary(lists:reverse(Acc))};
-utf8_list_to_binary([],Acc) ->
- {error,{asn1,Acc}};
-utf8_list_to_binary([H|T],Acc) ->
- case catch utf8_encode(H,Acc) of
- NewAcc when is_list(NewAcc) ->
- utf8_list_to_binary(T,NewAcc);
- Err -> Err
- end.
-
-
-utf8_encode(Int,Acc) when Int < 128 ->
- %% range 16#00000000 - 16#0000007f
- %% utf8 encoding: 0xxxxxxx
- [Int|Acc];
-utf8_encode(Int,Acc) when Int < 16#800 ->
- %% range 16#00000080 - 16#000007ff
- %% utf8 encoding: 110xxxxx 10xxxxxx
- [?bit1to6_into_utf8byte(Int),16#c0 bor (Int bsr 6)|Acc];
-utf8_encode(Int,Acc) when Int < 16#10000 ->
- %% range 16#00000800 - 16#0000ffff
- %% utf8 encoding: 1110xxxx 10xxxxxx 10xxxxxx
- [?bit1to6_into_utf8byte(Int),?bit7to12_into_utf8byte(Int),
- 16#e0 bor ((Int band 16#f000) bsr 12)|Acc];
-utf8_encode(Int,Acc) when Int < 16#200000 ->
- %% range 16#00010000 - 16#001fffff
- %% utf8 encoding: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- [?bit1to6_into_utf8byte(Int),?bit7to12_into_utf8byte(Int),
- ?bit13to18_into_utf8byte(Int),
- 16#f0 bor ((Int band 16#1c0000) bsr 18)|Acc];
-utf8_encode(Int,Acc) when Int < 16#4000000 ->
- %% range 16#00200000 - 16#03ffffff
- %% utf8 encoding: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
- [?bit1to6_into_utf8byte(Int),?bit7to12_into_utf8byte(Int),
- ?bit13to18_into_utf8byte(Int),?bit19to24_into_utf8byte(Int),
- 16#f8 bor ((Int band 16#3000000) bsr 24)|Acc];
-utf8_encode(Int,Acc) ->
- %% range 16#04000000 - 16#7fffffff
- %% utf8 encoding: 1111110x 10xxxxxx ...(total 6 bytes) 10xxxxxx
- [?bit1to6_into_utf8byte(Int),?bit7to12_into_utf8byte(Int),
- ?bit13to18_into_utf8byte(Int),?bit19to24_into_utf8byte(Int),
- ?bit25to30_into_utf8byte(Int),
- 16#fc bor ((Int band 16#40000000) bsr 30)|Acc].
diff --git a/lib/asn1/src/asn1rt_nif.erl b/lib/asn1/src/asn1rt_nif.erl
index ff464885f6..a62b476644 100644
--- a/lib/asn1/src/asn1rt_nif.erl
+++ b/lib/asn1/src/asn1rt_nif.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
decode_ber_tlv/1,
encode_ber_tlv/1]).
+-compile(no_native).
-on_load(load_nif/0).
-define(ASN1_NIF_VSN,1).
diff --git a/lib/asn1/src/asn1rtt_ber.erl b/lib/asn1/src/asn1rtt_ber.erl
index fdb9b9061f..d1cd22579b 100644
--- a/lib/asn1/src/asn1rtt_ber.erl
+++ b/lib/asn1/src/asn1rtt_ber.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -92,7 +92,7 @@
-define(N_BMPString, 30).
-% the complete tag-word of built-in types
+%% The complete tag-word of built-in types
-define(T_BOOLEAN, ?UNIVERSAL bor ?PRIMITIVE bor 1).
-define(T_INTEGER, ?UNIVERSAL bor ?PRIMITIVE bor 2).
-define(T_BIT_STRING, ?UNIVERSAL bor ?PRIMITIVE bor 3). % can be CONSTRUCTED
@@ -137,11 +137,11 @@ ber_decode_erlang(Tlv) ->
decode_primitive(Bin) ->
{Form,TagNo,V,Rest} = decode_tag_and_length(Bin),
case Form of
- 1 -> % constructed
+ 1 -> % constructed
{{TagNo,decode_constructed(V)},Rest};
- 0 -> % primitive
+ 0 -> % primitive
{{TagNo,V},Rest};
- 2 -> % constructed indefinite
+ 2 -> % constructed indefinite
{Vlist,Rest2} = decode_constructed_indefinite(V,[]),
{{TagNo,Vlist},Rest2}
end.
@@ -165,31 +165,30 @@ decode_primitive_incomplete([[default,TagNo]],Bin) -> %default
{Form,TagNo,V,Rest} ->
decode_incomplete2(Form,TagNo,V,[],Rest);
_ ->
- %{asn1_DEFAULT,Bin}
asn1_NOVALUE
end;
-decode_primitive_incomplete([[default,TagNo,Directives]],Bin) -> %default, constructed type, Directives points into this type
+decode_primitive_incomplete([[default,TagNo,Directives]],Bin) ->
+ %% default, constructed type, Directives points into this type
case decode_tag_and_length(Bin) of
{Form,TagNo,V,Rest} ->
decode_incomplete2(Form,TagNo,V,Directives,Rest);
_ ->
- %{asn1_DEFAULT,Bin}
asn1_NOVALUE
end;
-decode_primitive_incomplete([[opt,TagNo]],Bin) -> %optional
+decode_primitive_incomplete([[opt,TagNo]],Bin) ->
+ %% optional
case decode_tag_and_length(Bin) of
{Form,TagNo,V,Rest} ->
decode_incomplete2(Form,TagNo,V,[],Rest);
_ ->
- %{{TagNo,asn1_NOVALUE},Bin}
asn1_NOVALUE
end;
-decode_primitive_incomplete([[opt,TagNo,Directives]],Bin) -> %optional
+decode_primitive_incomplete([[opt,TagNo,Directives]],Bin) ->
+ %% optional
case decode_tag_and_length(Bin) of
{Form,TagNo,V,Rest} ->
decode_incomplete2(Form,TagNo,V,Directives,Rest);
_ ->
- %{{TagNo,asn1_NOVALUE},Bin}
asn1_NOVALUE
end;
%% An optional that shall be undecoded
@@ -236,7 +235,8 @@ decode_primitive_incomplete([[alt_parts,TagNo]|RestAlts],Bin) ->
_ ->
decode_primitive_incomplete(RestAlts,Bin)
end;
-decode_primitive_incomplete([[undec,_TagNo]|_RestTag],Bin) -> %incomlete decode
+decode_primitive_incomplete([[undec,_TagNo]|_RestTag],Bin) ->
+ %% incomlete decode
decode_incomplete_bin(Bin);
decode_primitive_incomplete([[parts,TagNo]|_RestTag],Bin) ->
case decode_tag_and_length(Bin) of
@@ -301,7 +301,8 @@ decode_constructed_incomplete(Directives=[[Alt,_]|_],Bin)
{TagNo,Tlv};
{alt_parts,_} ->
[{TagNo,decode_parts_incomplete(V)}];
- no_match -> %% if a choice alternative was encoded that
+ no_match ->
+ %% if a choice alternative was encoded that
%% was not specified in the config file,
%% thus decode component anonomous.
{Tlv,_}=decode_primitive(Bin),
@@ -546,7 +547,7 @@ decode_tag_and_length(<<Class:2, Form:1, 31:5, Buffer/binary>>) ->
decode_tag(<<0:1,PartialTag:7, Buffer/binary>>, TagAck) ->
TagNo = (TagAck bsl 7) bor PartialTag,
{TagNo, Buffer};
-% more tags
+%% more tags
decode_tag(<<_:1,PartialTag:7, Buffer/binary>>, TagAck) ->
TagAck1 = (TagAck bsl 7) bor PartialTag,
decode_tag(Buffer, TagAck1).
@@ -941,12 +942,12 @@ encode_bit_string_bits(C, BitListVal, _NamedBitList, TagIn) when is_list(BitList
case length(BitListVal) of
BitSize when BitSize == Size ->
{Len, Unused, OctetList} = encode_bitstring(BitListVal),
- %%add unused byte to the Len
+ %% add unused byte to the Len
encode_tags(TagIn, [Unused | OctetList], Len+1);
BitSize when BitSize < Size ->
PaddedList = pad_bit_list(Size-BitSize,BitListVal),
{Len, Unused, OctetList} = encode_bitstring(PaddedList),
- %%add unused byte to the Len
+ %% add unused byte to the Len
encode_tags(TagIn, [Unused | OctetList], Len+1);
BitSize ->
exit({error,{asn1,
diff --git a/lib/asn1/src/asn1rtt_ext.erl b/lib/asn1/src/asn1rtt_ext.erl
index 3bf01823db..f028e33888 100644
--- a/lib/asn1/src/asn1rtt_ext.erl
+++ b/lib/asn1/src/asn1rtt_ext.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,7 +19,8 @@
%%
-module(asn1rtt_ext).
--export([transform_to_EXTERNAL1990/1,transform_to_EXTERNAL1994/1]).
+-export([transform_to_EXTERNAL1990/1,transform_to_EXTERNAL1990_maps/1,
+ transform_to_EXTERNAL1994/1,transform_to_EXTERNAL1994_maps/1]).
transform_to_EXTERNAL1990({_,_,_,_}=Val) ->
transform_to_EXTERNAL1990(tuple_to_list(Val), []);
@@ -51,6 +52,30 @@ transform_to_EXTERNAL1990([Data_value], Acc)
list_to_tuple(lists:reverse([{'octet-aligned',Data_value}|Acc])).
+transform_to_EXTERNAL1990_maps(#{identification:=Id,'data-value':=Value}=V) ->
+ M0 = case Id of
+ {syntax,DRef} ->
+ #{'direct-reference'=>DRef};
+ {'presentation-context-id',IndRef} ->
+ #{'indirect-reference'=>IndRef};
+ {'context-negotiation',
+ #{'presentation-context-id':=IndRef,
+ 'transfer-syntax':=DRef}} ->
+ #{'direct-reference'=>DRef,
+ 'indirect-reference'=>IndRef}
+ end,
+ M = case V of
+ #{'data-value-descriptor':=Dvd} ->
+ M0#{'data-value-descriptor'=>Dvd};
+ #{} ->
+ M0
+ end,
+ M#{encoding=>{'octet-aligned',Value}};
+transform_to_EXTERNAL1990_maps(#{encoding:=_}=V) ->
+ %% Already in the EXTERNAL 1990 format.
+ V.
+
+
transform_to_EXTERNAL1994({'EXTERNAL',DRef,IndRef,Data_v_desc,Encoding}=V) ->
Identification =
case {DRef,IndRef} of
@@ -71,3 +96,38 @@ transform_to_EXTERNAL1994({'EXTERNAL',DRef,IndRef,Data_v_desc,Encoding}=V) ->
%% information.
V
end.
+
+transform_to_EXTERNAL1994_maps(V0) ->
+ Identification =
+ case V0 of
+ #{'direct-reference':=DRef,
+ 'indirect-reference':=asn1_NOVALUE} ->
+ {syntax,DRef};
+ #{'direct-reference':=asn1_NOVALUE,
+ 'indirect-reference':=IndRef} ->
+ {'presentation-context-id',IndRef};
+ #{'direct-reference':=DRef,
+ 'indirect-reference':=IndRef} ->
+ {'context-negotiation',
+ #{'transfer-syntax'=>DRef,
+ 'presentation-context-id'=>IndRef}}
+ end,
+ case V0 of
+ #{encoding:={'octet-aligned',Val}}
+ when is_list(Val); is_binary(Val) ->
+ %% Transform to the EXTERNAL 1994 definition.
+ V = #{identification=>Identification,
+ 'data-value'=>Val},
+ case V0 of
+ #{'data-value-descriptor':=asn1_NOVALUE} ->
+ V;
+ #{'data-value-descriptor':=Dvd} ->
+ V#{'data-value-descriptor'=>Dvd}
+ end;
+ _ ->
+ %% Keep the EXTERNAL 1990 definition to avoid losing
+ %% information.
+ V = [{K,V} || {K,V} <- maps:to_list(V0),
+ V =/= asn1_NOVALUE],
+ maps:from_list(V)
+ end.
diff --git a/lib/asn1/src/asn1rtt_per_common.erl b/lib/asn1/src/asn1rtt_per_common.erl
index 3896cb7fa5..2ecc9e4bc7 100644
--- a/lib/asn1/src/asn1rtt_per_common.erl
+++ b/lib/asn1/src/asn1rtt_per_common.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -140,6 +140,8 @@ encode_relative_oid(Val) when is_tuple(Val) ->
encode_relative_oid(Val) when is_list(Val) ->
list_to_binary([e_object_element(X)||X <- Val]).
+encode_unconstrained_number(Val) when not is_integer(Val) ->
+ exit({error,{asn1,{illegal_integer,Val}}});
encode_unconstrained_number(Val) when Val >= 0 ->
if
Val < 16#80 ->
diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile
index 0716d79291..f4041fa89b 100644
--- a/lib/asn1/test/Makefile
+++ b/lib/asn1/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
+# Copyright Ericsson AB 1997-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -82,6 +82,7 @@ MODULES= \
testInfObjExtract \
testParameterizedInfObj \
testFragmented \
+ testMaps \
testMergeCompile \
testMultipleLevels \
testDeepTConstr \
@@ -114,8 +115,7 @@ MODULES= \
testImporting \
testExtensibilityImplied \
asn1_test_lib \
- asn1_app_test \
- asn1_appup_test \
+ asn1_app_SUITE \
asn1_SUITE \
error_SUITE \
syntax_SUITE
@@ -134,7 +134,7 @@ RELSYSDIR = $(RELEASE_PATH)/asn1_test
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warnings_as_errors
+ERL_COMPILE_FLAGS += +warnings_as_errors +nowarn_export_all
EBIN = .
# ----------------------------------------------------
diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl
index b6430134ab..5fe6945ff2 100644
--- a/lib/asn1/test/asn1_SUITE.erl
+++ b/lib/asn1/test/asn1_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,6 +21,9 @@
-module(asn1_SUITE).
+%% Suppress compilation of an addititional module compiled for maps.
+-define(NO_MAPS_MODULE, asn1_test_lib_no_maps).
+
-define(only_ber(Func),
if Rule =:= ber -> Func;
true -> ok
@@ -39,10 +42,11 @@ suite() ->
{timetrap,{minutes,60}}].
all() ->
- [{group, compile},
+ [xref,
+ xref_export_all,
+
+ {group, compile},
{group, parallel},
- {group, app_test},
- {group, appup_test},
% TODO: Investigate parallel running of these:
testComment,
@@ -64,13 +68,8 @@ groups() ->
ber_optional,
tagdefault_automatic]},
- {app_test, [], [{asn1_app_test, all}]},
-
- {appup_test, [], [{asn1_appup_test, all}]},
-
{parallel, Parallel,
[cover,
- xref,
{group, ber},
% Uses 'P-Record', 'Constraints', 'MEDIA-GATEWAY-CONTROL'...
{group, [], [parse,
@@ -102,6 +101,7 @@ groups() ->
testMultipleLevels,
testOpt,
testSeqDefault,
+ testMaps,
% Uses 'External'
{group, [], [testExternal,
testSeqExtension]},
@@ -176,8 +176,11 @@ groups() ->
{performance, [],
[testTimer_ber,
+ testTimer_ber_maps,
testTimer_per,
- testTimer_uper]}].
+ testTimer_per_maps,
+ testTimer_uper,
+ testTimer_uper_maps]}].
%%------------------------------------------------------------------------------
%% Init/end
@@ -441,6 +444,16 @@ testDEFAULT(Config, Rule, Opts) ->
testDef:main(Rule),
testSeqSetDefaultVal:main(Rule, Opts).
+testMaps(Config) ->
+ test(Config, fun testMaps/3,
+ [{ber,[maps,no_ok_wrapper]},
+ {ber,[maps,der,no_ok_wrapper]},
+ {per,[maps,no_ok_wrapper]},
+ {uper,[maps,no_ok_wrapper]}]).
+testMaps(Config, Rule, Opts) ->
+ asn1_test_lib:compile_all(['Maps'], Config, [Rule|Opts]),
+ testMaps:main(Rule).
+
testOpt(Config) -> test(Config, fun testOpt/3).
testOpt(Config, Rule, Opts) ->
asn1_test_lib:compile("Opt", Config, [Rule|Opts]),
@@ -614,12 +627,12 @@ parse(Config) ->
[asn1_test_lib:compile(M, Config, [abs]) || M <- test_modules()].
per(Config) ->
- test(Config, fun per/3, [per,uper]).
+ test(Config, fun per/3, [per,uper,{per,[maps]},{uper,[maps]}]).
per(Config, Rule, Opts) ->
[module_test(M, Config, Rule, Opts) || M <- per_modules()].
ber_other(Config) ->
- test(Config, fun ber_other/3, [ber]).
+ test(Config, fun ber_other/3, [ber,{ber,[maps]}]).
ber_other(Config, Rule, Opts) ->
[module_test(M, Config, Rule, Opts) || M <- ber_modules()].
@@ -628,7 +641,7 @@ der(Config) ->
asn1_test_lib:compile_all(ber_modules(), Config, [der]).
module_test(M0, Config, Rule, Opts) ->
- asn1_test_lib:compile(M0, Config, [Rule|Opts]),
+ asn1_test_lib:compile(M0, Config, [Rule,?NO_MAPS_MODULE|Opts]),
case list_to_atom(M0) of
'LDAP' ->
%% Because of the recursive definition of 'Filter' in
@@ -995,7 +1008,9 @@ testS1AP(Config, Rule, Opts) ->
testRfcs() ->
[{timetrap,{minutes,90}}].
-testRfcs(Config) -> test(Config, fun testRfcs/3, [{ber,[der]}]).
+testRfcs(Config) -> test(Config, fun testRfcs/3,
+ [{ber,[der,?NO_MAPS_MODULE]},
+ {ber,[der,maps]}]).
testRfcs(Config, Rule, Opts) ->
case erlang:system_info(system_architecture) of
"sparc-sun-solaris2.10" ->
@@ -1010,7 +1025,8 @@ test_compile_options(Config) ->
ok = test_compile_options:path(Config),
ok = test_compile_options:noobj(Config),
ok = test_compile_options:record_name_prefix(Config),
- ok = test_compile_options:verbose(Config).
+ ok = test_compile_options:verbose(Config),
+ ok = test_compile_options:maps(Config).
testDoubleEllipses(Config) -> test(Config, fun testDoubleEllipses/3).
testDoubleEllipses(Config, Rule, Opts) ->
@@ -1027,18 +1043,6 @@ test_modified_x420(Config, Rule, Opts) ->
test_modified_x420:test(Config).
-testX420() ->
- [{timetrap,{minutes,90}}].
-testX420(Config) ->
- case erlang:system_info(system_architecture) of
- "sparc-sun-solaris2.10" ->
- {skip,"Too slow for an old Sparc"};
- _ ->
- Rule = ber,
- testX420:compile(Rule, [der], Config),
- ok = testX420:ticket7759(Rule, Config)
- end.
-
test_x691(Config) ->
test(Config, fun test_x691/3, [per, uper]).
test_x691(Config, Rule, Opts) ->
@@ -1069,7 +1073,7 @@ test_x691(Config, Rule, Opts) ->
ok.
ticket_6143(Config) ->
- ok = test_compile_options:ticket_6143(Config).
+ asn1_test_lib:compile("AA1", Config, [?NO_MAPS_MODULE]).
testExtensionAdditionGroup(Config) ->
test(Config, fun testExtensionAdditionGroup/3).
@@ -1104,6 +1108,7 @@ test_modules() ->
"From",
"H235-SECURITY-MESSAGES",
"H323-MESSAGES",
+ "HighTagNumbers",
"Import",
"Int",
"MAP-commonDataTypes",
@@ -1157,20 +1162,33 @@ END
ok = asn1ct:compile(File, [{outdir, PrivDir}]).
-timer_compile(Config, Rule) ->
- asn1_test_lib:compile_all(["H235-SECURITY-MESSAGES", "H323-MESSAGES"],
- Config, [no_ok_wrapper,Rule]).
+timer_compile(Config, Opts0) ->
+ Files = ["H235-SECURITY-MESSAGES", "H323-MESSAGES"],
+ Opts = [no_ok_wrapper,?NO_MAPS_MODULE|Opts0],
+ asn1_test_lib:compile_all(Files, Config, Opts).
testTimer_ber(Config) ->
- timer_compile(Config, ber),
+ timer_compile(Config, [ber]),
testTimer:go().
testTimer_per(Config) ->
- timer_compile(Config, per),
+ timer_compile(Config, [per]),
testTimer:go().
testTimer_uper(Config) ->
- timer_compile(Config, uper),
+ timer_compile(Config, [uper]),
+ testTimer:go().
+
+testTimer_ber_maps(Config) ->
+ timer_compile(Config, [ber,maps]),
+ testTimer:go().
+
+testTimer_per_maps(Config) ->
+ timer_compile(Config, [per,maps]),
+ testTimer:go().
+
+testTimer_uper_maps(Config) ->
+ timer_compile(Config, [uper,maps]),
testTimer:go().
%% Test of multiple-line comment, OTP-8043
@@ -1179,9 +1197,11 @@ testComment(Config) ->
asn1_test_lib:roundtrip('Comment', 'Seq', {'Seq',12,true}).
testName2Number(Config) ->
- N2NOptions = [{n2n,Type} || Type <- ['CauseMisc', 'CauseProtocol',
- 'CauseRadioNetwork',
- 'CauseTransport','CauseNas']],
+ N2NOptions0 = [{n2n,Type} ||
+ Type <- ['CauseMisc', 'CauseProtocol',
+ 'CauseRadioNetwork',
+ 'CauseTransport','CauseNas']],
+ N2NOptions = [?NO_MAPS_MODULE|N2NOptions0],
asn1_test_lib:compile("S1AP-IEs", Config, N2NOptions),
0 = 'S1AP-IEs':name2num_CauseMisc('control-processing-overload'),
@@ -1191,8 +1211,9 @@ testName2Number(Config) ->
%% Test that n2n option generates name2num and num2name functions supporting
%% values not within the extension root if the enumeration type has an
%% extension marker.
- N2NOptionsExt = [{n2n, 'NoExt'}, {n2n, 'Ext'}, {n2n, 'Ext2'}],
+ N2NOptionsExt = [?NO_MAPS_MODULE,{n2n,'NoExt'},{n2n,'Ext'},{n2n,'Ext2'}],
asn1_test_lib:compile("EnumN2N", Config, N2NOptionsExt),
+
%% Previously, name2num and num2name was not generated if the type didn't
%% have an extension marker:
0 = 'EnumN2N':name2num_NoExt('blue'),
@@ -1210,9 +1231,11 @@ testName2Number(Config) ->
ok.
ticket_7407(Config) ->
- asn1_test_lib:compile("EUTRA-extract-7407", Config, [uper]),
+ Opts = [uper,?NO_MAPS_MODULE],
+ asn1_test_lib:compile("EUTRA-extract-7407", Config, Opts),
ticket_7407_code(true),
- asn1_test_lib:compile("EUTRA-extract-7407", Config, [uper,no_final_padding]),
+ asn1_test_lib:compile("EUTRA-extract-7407", Config,
+ [no_final_padding|Opts]),
ticket_7407_code(false).
ticket_7407_code(FinalPadding) ->
@@ -1287,16 +1310,72 @@ ticket7904(Config) ->
{ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1),
{ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1).
+
+%% Make sure that functions exported from other modules are
+%% actually used.
+
xref(_Config) ->
- xref:start(s),
- xref:set_default(s, [{verbose,false},{warnings,false},{builtins,true}]),
+ S = ?FUNCTION_NAME,
+ xref:start(S),
+ xref:set_default(S, [{verbose,false},{warnings,false},{builtins,true}]),
Test = filename:dirname(code:which(?MODULE)),
- {ok,_PMs} = xref:add_directory(s, Test),
- UnusedExports = "X - XU - asn1_appup_test - asn1_app_test - \".*_SUITE\" : Mod",
- case xref:q(s, UnusedExports) of
+ {ok,_PMs} = xref:add_directory(S, Test),
+ Q = "X - XU - \".*_SUITE\" : Mod",
+ UnusedExports = xref:q(S, Q),
+ xref:stop(S),
+ case UnusedExports of
{ok,[]} ->
ok;
{ok,[_|_]=Res} ->
io:format("Exported, but unused: ~p\n", [Res]),
?t:fail()
end.
+
+%% Ensure that all functions that are implicitly exported by
+%% 'export_all' in this module are actually used.
+
+xref_export_all(_Config) ->
+ S = ?FUNCTION_NAME,
+ xref:start(S),
+ xref:set_default(S, [{verbose,false},{warnings,false},{builtins,true}]),
+ {ok,_PMs} = xref:add_module(S, code:which(?MODULE)),
+ AllCalled = all_called(),
+ Def = "Called := " ++ lists:flatten(io_lib:format("~p", [AllCalled])),
+ {ok,_} = xref:q(S, Def),
+ {ok,Unused} = xref:q(S, "X - Called - range (closure E | Called)"),
+ xref:stop(S),
+ case Unused of
+ [] ->
+ ok;
+ [_|_] ->
+ S = [io_lib:format("~p:~p/~p\n", [M,F,A]) || {M,F,A} <- Unused],
+ io:format("There are unused functions:\n\n~s\n", [S]),
+ ?t:fail(unused_functions)
+ end.
+
+%% Collect all functions that common_test will call in this module.
+
+all_called() ->
+ [{?MODULE,end_per_group,2},
+ {?MODULE,end_per_suite,1},
+ {?MODULE,end_per_testcase,2},
+ {?MODULE,init_per_group,2},
+ {?MODULE,init_per_suite,1},
+ {?MODULE,init_per_testcase,2},
+ {?MODULE,suite,0}] ++
+ all_called_1(all() ++ groups()).
+
+all_called_1([{_,_}|T]) ->
+ all_called_1(T);
+all_called_1([{_Name,_Flags,Fs}|T]) ->
+ all_called_1(Fs ++ T);
+all_called_1([F|T]) when is_atom(F) ->
+ L = case erlang:function_exported(?MODULE, F, 0) of
+ false ->
+ [{?MODULE,F,1}];
+ true ->
+ [{?MODULE,F,0},{?MODULE,F,1}]
+ end,
+ L ++ all_called_1(T);
+all_called_1([]) ->
+ [].
diff --git a/lib/asn1/test/asn1_SUITE_data/HighTagNumbers.asn1 b/lib/asn1/test/asn1_SUITE_data/HighTagNumbers.asn1
new file mode 100644
index 0000000000..b681063965
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/HighTagNumbers.asn1
@@ -0,0 +1,17 @@
+HighTagNumbers DEFINITIONS ::=
+BEGIN
+
+S ::= SEQUENCE {
+ a [127] INTEGER,
+ b [128] INTEGER,
+ c [150] INTEGER,
+ d [207] INTEGER,
+ e [255] INTEGER,
+ f [256] INTEGER,
+ g [7777] INTEGER,
+ h [9999] INTEGER,
+ i [16382] INTEGER,
+ j [16383] INTEGER
+}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Maps.asn1 b/lib/asn1/test/asn1_SUITE_data/Maps.asn1
new file mode 100644
index 0000000000..fd5f373e45
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE_data/Maps.asn1
@@ -0,0 +1,17 @@
+Maps DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+XY ::= SEQUENCE { x INTEGER DEFAULT 0, y INTEGER DEFAULT 0 }
+
+xy1 XY ::= { x 42, y 17 }
+xy2 XY ::= { }
+xy3 XY ::= { y 999 }
+
+S ::= SEQUENCE {
+ xy XY DEFAULT { x 100, y 100 },
+ os OCTET STRING OPTIONAL
+}
+
+s1 S ::= {}
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/Prim.asn1 b/lib/asn1/test/asn1_SUITE_data/Prim.asn1
index 4fe0901683..91c8696e61 100644
--- a/lib/asn1/test/asn1_SUITE_data/Prim.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/Prim.asn1
@@ -18,6 +18,8 @@ BEGIN
IntExpPri ::= [PRIVATE 51] EXPLICIT INTEGER
IntExpApp ::= [APPLICATION 52] EXPLICIT INTEGER
+ IntConstrained ::= INTEGER (0..255)
+
IntEnum ::= INTEGER {first(1),last(31)}
Enum ::= ENUMERATED {monday(1),tuesday(2),wednesday(3),thursday(4),
diff --git a/lib/asn1/test/asn1_SUITE_data/SeqExtension.asn1 b/lib/asn1/test/asn1_SUITE_data/SeqExtension.asn1
index 5fda19303a..e866ef2f4f 100644
--- a/lib/asn1/test/asn1_SUITE_data/SeqExtension.asn1
+++ b/lib/asn1/test/asn1_SUITE_data/SeqExtension.asn1
@@ -48,6 +48,17 @@ SeqExt6 ::= SEQUENCE
[[ i6 [106] INTEGER, i7 [107] INTEGER ]]
}
+SeqExt7 ::= SEQUENCE
+{
+ -- The spaces between the ellipsis and the comma will prevent them
+ -- from being removed.
+ ... ,
+ [[ a INTEGER (0..65535) OPTIONAL,
+ b OCTET STRING OPTIONAL,
+ c BOOLEAN
+ ]]
+}
+
SeqExt1X ::= XSeqExt1
SeqExt2X ::= XSeqExt2
diff --git a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
index 6cf8ecf451..cd6c74b995 100644
--- a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
+++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
@@ -120,10 +120,10 @@ run3(Erule) ->
asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
asn1_NOVALUE,asn1_NOVALUE}}}}}}},
io:format("~p:~p~n",[Erule,Val]),
- {ok,List}= asn1rt:encode('EUTRA-RRC-Definitions','DL-DCCH-Message',Val),
+ {ok,List}= 'EUTRA-RRC-Definitions':encode('DL-DCCH-Message',Val),
Enc = iolist_to_binary(List),
io:format("Result from encode:~n~p~n",[Enc]),
- {ok,Val2} = asn1rt:decode('EUTRA-RRC-Definitions','DL-DCCH-Message',Enc),
+ {ok,Val2} = 'EUTRA-RRC-Definitions':decode('DL-DCCH-Message', Enc),
io:format("Result from decode:~n~p~n",[Val2]),
case Val2 of
Val -> ok;
diff --git a/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Discriptions.asn b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Descriptions.asn
index b9be9934e4..12a4475422 100644
--- a/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Discriptions.asn
+++ b/lib/asn1/test/asn1_SUITE_data/nbapsystem/NBAP-PDU-Descriptions.asn
@@ -4,7 +4,7 @@
--
-- **************************************************************
-NBAP-PDU-Discriptions {
+NBAP-PDU-Descriptions {
itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)
umts-Access (20) modules (3) nbap (2) version1 (1) nbap-PDU-Descriptions (0) }
diff --git a/lib/asn1/test/asn1_SUITE_data/test_records.erl b/lib/asn1/test/asn1_SUITE_data/test_records.erl
index 9fd07c1449..16167e2f85 100644
--- a/lib/asn1/test/asn1_SUITE_data/test_records.erl
+++ b/lib/asn1/test/asn1_SUITE_data/test_records.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@
-define(line,put(test_server_loc,{?MODULE,?LINE}),).
--include("NBAP-PDU-Discriptions.hrl").
+-include("NBAP-PDU-Descriptions.hrl").
-include("NBAP-PDU-Contents.hrl").
-include("NBAP-Containers.hrl").
-include("NBAP-CommonDataTypes.hrl").
diff --git a/lib/asn1/test/asn1_SUITE_data/testobj.erl b/lib/asn1/test/asn1_SUITE_data/testobj.erl
index a0e00f8314..b582935f73 100644
--- a/lib/asn1/test/asn1_SUITE_data/testobj.erl
+++ b/lib/asn1/test/asn1_SUITE_data/testobj.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -967,7 +967,7 @@ pdu_pdp() ->
116,101,115,116, % lable1 = test
4, % length lable2
116,101,115,116, % lable2 = test
- 4, % lenght lable3
+ 4, % length lable3
116,101,115,116, % lable3 = test
4, % length lable3
116,101,115,116, % lable4 = test
@@ -1410,16 +1410,14 @@ int2bin(Int) ->
%%%%%%%%%%%%%%%%% wrappers %%%%%%%%%%%%%%%%%%%%%%%%
wrapper_encode(Module,Type,Value) ->
- case asn1rt:encode(Module,Type,Value) of
- {ok,X} when binary(X) ->
+ case Module:encode(Type, Value) of
+ {ok,X} when is_binary(X) ->
{ok, binary_to_list(X)};
- {ok,X} ->
- {ok, binary_to_list(list_to_binary(X))};
Error ->
Error
end.
wrapper_decode(Module, Type, Bytes) when is_binary(Bytes) ->
- asn1rt:decode(Module, Type, Bytes);
+ Module:decode(Type, Bytes);
wrapper_decode(Module, Type, Bytes) when is_list(Bytes) ->
- asn1rt:decode(Module, Type, list_to_binary(Bytes)).
+ Module:decode(Type, list_to_binary(Bytes)).
diff --git a/lib/asn1/test/asn1_app_test.erl b/lib/asn1/test/asn1_app_SUITE.erl
index 028322f555..b06eb59ed9 100644
--- a/lib/asn1/test/asn1_app_test.erl
+++ b/lib/asn1/test/asn1_app_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,23 +21,24 @@
%%----------------------------------------------------------------------
%% Purpose: Verify the application specifics of the asn1 application
%%----------------------------------------------------------------------
--module(asn1_app_test).
-
--compile(export_all).
+-module(asn1_app_SUITE).
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1,end_per_suite/1,
+ appup/1,fields/1,modules/1,export_all/1,app_depend/1]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all() ->
- [fields, modules, exportall, app_depend].
+all() ->
+ [appup, fields, modules, export_all, app_depend].
-groups() ->
+groups() ->
[].
init_per_group(_GroupName, Config) ->
- Config.
+ Config.
end_per_group(_GroupName, Config) ->
- Config.
+ Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -65,12 +66,15 @@ is_app(App) ->
end_per_suite(Config) when is_list(Config) ->
Config.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+appup(Config) when is_list(Config) ->
+ ok = test_server:appup_test(asn1).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% .
fields(Config) when is_list(Config) ->
- AppFile = key1search(app_file, Config),
+ AppFile = key1find(app_file, Config),
Fields = [vsn, description, modules, registered, applications],
case check_fields(Fields, AppFile, []) of
[] ->
@@ -96,10 +100,9 @@ check_field(Name, AppFile, Missing) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% .
modules(Config) when is_list(Config) ->
- AppFile = key1search(app_file, Config),
- Mods = key1search(modules, AppFile),
+ AppFile = key1find(app_file, Config),
+ Mods = key1find(modules, AppFile),
EbinList = get_ebin_mods(asn1),
case missing_modules(Mods, EbinList, []) of
[] ->
@@ -112,10 +115,9 @@ modules(Config) when is_list(Config) ->
ok;
Extra ->
check_asn1ct_modules(Extra)
-% throw({error, {extra_modules, Extra}})
end,
{ok, Mods}.
-
+
get_ebin_mods(App) ->
LibDir = code:lib_dir(App),
EbinDir = filename:join([LibDir,"ebin"]),
@@ -166,10 +168,9 @@ extra_modules(Mods, [Mod|Ebins], Extra) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% .
-exportall(Config) when is_list(Config) ->
- AppFile = key1search(app_file, Config),
- Mods = key1search(modules, AppFile),
+export_all(Config) when is_list(Config) ->
+ AppFile = key1find(app_file, Config),
+ Mods = key1find(modules, AppFile),
check_export_all(Mods).
@@ -180,10 +181,10 @@ check_export_all([Mod|Mods]) ->
{'EXIT', {undef, _}} ->
check_export_all(Mods);
O ->
- case lists:keysearch(options, 1, O) of
+ case lists:keyfind(options, 1, O) of
false ->
check_export_all(Mods);
- {value, {options, List}} ->
+ {options, List} ->
case lists:member(export_all, List) of
true ->
throw({error, {export_all, Mod}});
@@ -193,13 +194,12 @@ check_export_all([Mod|Mods]) ->
end
end.
-
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% .
app_depend(Config) when is_list(Config) ->
- AppFile = key1search(app_file, Config),
- Apps = key1search(applications, AppFile),
+ AppFile = key1find(app_file, Config),
+ Apps = key1find(applications, AppFile),
check_apps(Apps).
@@ -220,10 +220,10 @@ check_apps([App|Apps]) ->
fail(Reason) ->
exit({suite_failed, Reason}).
-key1search(Key, L) ->
- case lists:keysearch(Key, 1, L) of
- undefined ->
+key1find(Key, L) ->
+ case lists:keyfind(Key, 1, L) of
+ false ->
fail({not_found, Key, L});
- {value, {Key, Value}} ->
+ {Key, Value} ->
Value
end.
diff --git a/lib/asn1/test/asn1_appup_test.erl b/lib/asn1/test/asn1_appup_test.erl
deleted file mode 100644
index 54540e53cc..0000000000
--- a/lib/asn1/test/asn1_appup_test.erl
+++ /dev/null
@@ -1,58 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%%
-%%----------------------------------------------------------------------
-%% Purpose: Verify the application specifics of the asn1 application
-%%----------------------------------------------------------------------
--module(asn1_appup_test).
--compile(export_all).
--include_lib("common_test/include/ct.hrl").
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-all() ->
- [appup].
-
-groups() ->
- [].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-init_per_suite(Config) when is_list(Config) ->
- Config.
-
-
-end_per_suite(Config) when is_list(Config) ->
- Config.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-appup() ->
- [{doc, "perform a simple check of the asn1 appup file"}].
-appup(Config) when is_list(Config) ->
- ok = ?t:appup_test(asn1).
diff --git a/lib/asn1/test/asn1_test_lib.erl b/lib/asn1/test/asn1_test_lib.erl
index 1b4c3b3c77..1cc332406b 100644
--- a/lib/asn1/test/asn1_test_lib.erl
+++ b/lib/asn1/test/asn1_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,7 +25,8 @@
hex_to_bin/1,
match_value/2,
parallel/0,
- roundtrip/3,roundtrip/4,roundtrip_enc/3,roundtrip_enc/4]).
+ roundtrip/3,roundtrip/4,roundtrip_enc/3,roundtrip_enc/4,
+ map_roundtrip/3]).
-include_lib("common_test/include/ct.hrl").
@@ -34,12 +35,16 @@ run_dialyzer() ->
compile(File, Config, Options) -> compile_all([File], Config, Options).
-compile_all(Files, Config, Options) ->
+compile_all(Files, Config, Options0) ->
DataDir = proplists:get_value(data_dir, Config),
CaseDir = proplists:get_value(case_dir, Config),
- [compile_file(filename:join(DataDir, F), [{outdir, CaseDir},
- debug_info|Options])
- || F <- Files],
+ Options = [{outdir,CaseDir},debug_info|Options0],
+
+ Comp = fun(F) ->
+ compile_file(filename:join(DataDir, F), Options)
+ end,
+ p_run(Comp, Files),
+
dialyze(Files, Options),
ok.
@@ -90,15 +95,58 @@ module(F0) ->
list_to_atom(F).
%% filename:join(CaseDir, F ++ ".beam").
-compile_file(File, Options) ->
+compile_file(File, Options0) ->
+ Options = [warnings_as_errors|Options0],
try
- ok = asn1ct:compile(File, [warnings_as_errors|Options])
+ ok = asn1ct:compile(File, Options),
+ ok = compile_maps(File, Options)
catch
- Class:Reason ->
- ct:print("Failed to compile ~s\n", [File]),
- erlang:error({compile_failed, {File, Options}, {Class, Reason}})
+ _:Reason ->
+ ct:print("Failed to compile ~s\n~p", [File,Reason]),
+ error
+ end.
+
+compile_maps(File, Options) ->
+ unload_map_mod(File),
+ Incompat = [abs,compact_bit_string,legacy_bit_string,
+ legacy_erlang_types,maps,asn1_test_lib_no_maps],
+ case lists:any(fun(E) -> lists:member(E, Incompat) end, Options) of
+ true ->
+ ok;
+ false ->
+ compile_maps_1(File, Options)
end.
+compile_maps_1(File, Options) ->
+ ok = asn1ct:compile(File, [maps,no_ok_wrapper,noobj|Options]),
+ OutDir = proplists:get_value(outdir, Options),
+ Base0 = filename:rootname(filename:basename(File)),
+ Base = case filename:extension(Base0) of
+ ".set" ->
+ filename:rootname(Base0);
+ _ ->
+ Base0
+ end,
+ ErlBase = Base ++ ".erl",
+ ErlFile = filename:join(OutDir, ErlBase),
+ {ok,Erl0} = file:read_file(ErlFile),
+ Erl = re:replace(Erl0, <<"-module\\('">>, "&maps_"),
+ MapsErlFile = filename:join(OutDir, "maps_" ++ ErlBase),
+ ok = file:write_file(MapsErlFile, Erl),
+ {ok,_} = compile:file(MapsErlFile, [report,{outdir,OutDir},{i,OutDir}]),
+ ok.
+
+unload_map_mod(File0) ->
+ File1 = filename:basename(File0),
+ File2 = filename:rootname(File1, ".asn"),
+ File3 = filename:rootname(File2, ".asn1"),
+ File4 = filename:rootname(File3, ".py"),
+ File = filename:rootname(File4, ".set"),
+ MapMod = list_to_atom("maps_"++File),
+ code:delete(MapMod),
+ code:purge(MapMod),
+ ok.
+
compile_erlang(Mod, Config, Options) ->
DataDir = proplists:get_value(data_dir, Config),
CaseDir = proplists:get_value(case_dir, Config),
@@ -143,24 +191,60 @@ roundtrip(Mod, Type, Value) ->
roundtrip(Mod, Type, Value, Value).
roundtrip(Mod, Type, Value, ExpectedValue) ->
- {ok,Encoded} = Mod:encode(Type, Value),
- {ok,ExpectedValue} = Mod:decode(Type, Encoded),
- test_ber_indefinite(Mod, Type, Encoded, ExpectedValue),
- ok.
+ roundtrip_enc(Mod, Type, Value, ExpectedValue).
roundtrip_enc(Mod, Type, Value) ->
roundtrip_enc(Mod, Type, Value, Value).
roundtrip_enc(Mod, Type, Value, ExpectedValue) ->
- {ok,Encoded} = Mod:encode(Type, Value),
- {ok,ExpectedValue} = Mod:decode(Type, Encoded),
+ case Mod:encode(Type, Value) of
+ {ok,Encoded} ->
+ {ok,ExpectedValue} = Mod:decode(Type, Encoded);
+ Encoded when is_binary(Encoded) ->
+ ExpectedValue = Mod:decode(Type, Encoded)
+ end,
+ map_roundtrip(Mod, Type, Encoded),
test_ber_indefinite(Mod, Type, Encoded, ExpectedValue),
Encoded.
+map_roundtrip(Mod, Type, Encoded) ->
+ MapMod = list_to_atom("maps_"++atom_to_list(Mod)),
+ try MapMod:maps() of
+ true ->
+ map_roundtrip_1(MapMod, Type, Encoded)
+ catch
+ error:undef ->
+ ok
+ end.
+
%%%
%%% Internal functions.
%%%
+map_roundtrip_1(Mod, Type, Encoded) ->
+ Decoded = Mod:decode(Type, Encoded),
+ case Mod:encode(Type, Decoded) of
+ Encoded ->
+ ok;
+ OtherEncoding ->
+ case is_named_bitstring(Decoded) of
+ true ->
+ %% In BER, named BIT STRINGs with different number of
+ %% trailing zeroes decode to the same value.
+ ok;
+ false ->
+ error({encode_mismatch,Decoded,Encoded,OtherEncoding})
+ end
+ end,
+ ok.
+
+is_named_bitstring([H|T]) ->
+ is_atom(H) andalso is_named_bitstring(T);
+is_named_bitstring([]) ->
+ true;
+is_named_bitstring(_) ->
+ false.
+
hex2num(C) when $0 =< C, C =< $9 -> C - $0;
hex2num(C) when $A =< C, C =< $F -> C - $A + 10;
hex2num(C) when $a =< C, C =< $f -> C - $a + 10.
@@ -175,7 +259,12 @@ test_ber_indefinite(Mod, Type, Encoded, ExpectedValue) ->
case Mod:encoding_rule() of
ber ->
Indefinite = iolist_to_binary(ber_indefinite(Encoded)),
- {ok,ExpectedValue} = Mod:decode(Type, Indefinite);
+ case Mod:decode(Type, Indefinite) of
+ {ok,ExpectedValue} ->
+ ok;
+ ExpectedValue ->
+ ok
+ end;
_ ->
ok
end.
@@ -219,3 +308,38 @@ ber_get_len(<<0:1,L:7,T/binary>>) ->
ber_get_len(<<1:1,Octets:7,T0/binary>>) ->
<<L:Octets/unit:8,T/binary>> = T0,
{L,T}.
+
+%% p_run(fun(Data) -> ok|error, List) -> ok
+%% Will fail the test case if there were any errors.
+
+p_run(Test, List) ->
+ S = erlang:system_info(schedulers),
+ N = case test_server:is_cover() of
+ false ->
+ S + 1;
+ true ->
+ %% Cover is running. Using too many processes
+ %% could slow us down.
+ min(S, 4)
+ end,
+ %%io:format("p_run: ~p parallel processes\n", [N]),
+ p_run_loop(Test, List, N, [], 0).
+
+p_run_loop(_, [], _, [], Errors) ->
+ case Errors of
+ 0 -> ok;
+ N -> ct:fail({N,errors})
+ end;
+p_run_loop(Test, [H|T], N, Refs, Errors) when length(Refs) < N ->
+ {_,Ref} = erlang:spawn_monitor(fun() -> exit(Test(H)) end),
+ p_run_loop(Test, T, N, [Ref|Refs], Errors);
+p_run_loop(Test, List, N, Refs0, Errors0) ->
+ receive
+ {'DOWN',Ref,process,_,Res} ->
+ Errors = case Res of
+ ok -> Errors0;
+ error -> Errors0+1
+ end,
+ Refs = Refs0 -- [Ref],
+ p_run_loop(Test, List, N, Refs, Errors)
+ end.
diff --git a/lib/asn1/test/ber_decode_error.erl b/lib/asn1/test/ber_decode_error.erl
index c0840e02d7..e5b231a7c7 100644
--- a/lib/asn1/test/ber_decode_error.erl
+++ b/lib/asn1/test/ber_decode_error.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -26,48 +26,41 @@ run([]) ->
{ok,B} = 'Constructed':encode('S3', {'S3',17}),
[T,L|V] = binary_to_list(B),
Bytes = list_to_binary([T,L+3|V] ++ [2,1,3]),
- case 'Constructed':decode('S3', Bytes) of
- {error,{asn1,{unexpected,_}}} -> ok
- end,
+ {unexpected,_} = dec_error('S3', Bytes),
%% Unexpected bytes must be accepted if there is an extensionmark
{ok,{'S3ext',17}} = 'Constructed':decode('S3ext', Bytes),
%% Truncated tag.
- {error,{asn1,{invalid_tag,_}}} =
- (catch 'Constructed':decode('I', <<31,255,255>>)),
+ {invalid_tag,_} = dec_error('I', <<31,255,255>>),
%% Overlong tag.
- {error,{asn1,{invalid_tag,_}}} =
- (catch 'Constructed':decode('I', <<31,255,255,255,127>>)),
+ {invalid_tag,_} = dec_error('I', <<31,255,255,255,127>>),
%% Invalid length.
- {error,{asn1,{invalid_length,_}}} =
- (catch 'Constructed':decode('I', <<8,255>>)),
+ {invalid_length,_} = dec_error('I', <<8,255>>),
%% Other errors.
- {error,{asn1,{invalid_value,_}}} =
- (catch 'Constructed':decode('I', <<>>)),
+ {invalid_value,_} = dec_error('I', <<>>),
- {error,{asn1,{invalid_value,_}}} =
- (catch 'Constructed':decode('I', <<8,7>>)),
+ {invalid_value,_} = dec_error('I', <<8,7>>),
%% Short indefinite length. Make sure that the decoder doesn't look
%% beyond the end of binary when looking for a 0,0 terminator.
- {error,{asn1,{invalid_length,_}}} =
- (catch 'Constructed':decode('S', sub(<<8,16#80,0,0>>, 3))),
- {error,{asn1,{invalid_length,_}}} =
- (catch 'Constructed':decode('S', sub(<<8,16#80,0,0>>, 2))),
- {error,{asn1,{invalid_length,_}}} =
- (catch 'Constructed':decode('S', sub(<<40,16#80,1,1,255,0,0>>, 6))),
- {error,{asn1,{invalid_length,_}}} =
- (catch 'Constructed':decode('S', sub(<<40,16#80,1,1,255,0,0>>, 5))),
+ {invalid_length,_} = dec_error('S', sub(<<8,16#80,0,0>>, 3)),
+ {invalid_length,_} = dec_error('S', sub(<<8,16#80,0,0>>, 2)),
+ {invalid_length,_} = dec_error('S', sub(<<40,16#80,1,1,255,0,0>>, 6)),
+ {invalid_length,_} = dec_error('S', sub(<<40,16#80,1,1,255,0,0>>, 5)),
%% A primitive must not be encoded with an indefinite length.
- {error,{asn1,{invalid_length,_}}} =
- (catch 'Constructed':decode('OS', <<4,128,4,3,97,98,99,0,0>>)),
+ {invalid_length,_} = dec_error('OS', <<4,128,4,3,97,98,99,0,0>>),
ok.
+dec_error(T, Bin) ->
+ {error,{asn1,{Reason,Stk}}} = 'Constructed':decode(T, Bin),
+ [{_,_,_,_}|_] = Stk,
+ Reason.
+
sub(Bin, Bytes) ->
<<B:Bytes/binary,_/binary>> = Bin,
B.
diff --git a/lib/asn1/test/h323test.erl b/lib/asn1/test/h323test.erl
index 935af0ba09..c4eaa75c9a 100644
--- a/lib/asn1/test/h323test.erl
+++ b/lib/asn1/test/h323test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,6 +27,8 @@ run(per) -> run();
run(_Rules) -> ok.
run() ->
+ roundtrip('EndpointType', endpoint()),
+ roundtrip('Alerting-UUIE', alerting_uuie()),
roundtrip('H323-UserInformation', alerting_val(), alerting_enc()),
roundtrip('H323-UserInformation', connect_val(), connect_enc()),
general_string(),
@@ -36,18 +38,24 @@ alerting_val() ->
{'H323-UserInformation',
{'H323-UU-PDU',
{alerting,
- {'Alerting-UUIE',
- {0,0,8,2250,0,2},
- {'EndpointType',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
- asn1_NOVALUE,asn1_NOVALUE,
- {'TerminalInfo',asn1_NOVALUE},
- false,false},
- asn1_NOVALUE,
- {'CallIdentifier',<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>},
- asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}},
+ alerting_uuie()},
asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
asn1_NOVALUE}.
+endpoint() ->
+ {'EndpointType',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE,asn1_NOVALUE,
+ {'TerminalInfo',asn1_NOVALUE},
+ false,false}.
+
+alerting_uuie() ->
+ {'Alerting-UUIE',
+ {0,0,8,2250,0,2},
+ endpoint(),
+ asn1_NOVALUE,
+ {'CallIdentifier',<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>},
+ asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}.
+
alerting_enc() ->
"0380060008914a0002020120110000000000000000000000000000000000".
@@ -82,6 +90,9 @@ general_string() ->
UI = <<109,64,1,57>>,
{ok, _V} = 'MULTIMEDIA-SYSTEM-CONTROL':decode(Type, UI).
+roundtrip(T, V) ->
+ asn1_test_lib:roundtrip('H323-MESSAGES', T, V).
+
roundtrip(T, V, HexString) ->
Enc = asn1_test_lib:hex_to_bin(HexString),
Enc = asn1_test_lib:roundtrip_enc('H323-MESSAGES', T, V),
diff --git a/lib/asn1/test/testChoPrim.erl b/lib/asn1/test/testChoPrim.erl
index 573c482f2b..91fbc1488a 100644
--- a/lib/asn1/test/testChoPrim.erl
+++ b/lib/asn1/test/testChoPrim.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -31,10 +31,10 @@ bool(Rules) ->
roundtrip('ChoCon', {int2,233}),
case Rules of
ber ->
- {error,{asn1,{invalid_choice_type,wrong}}} =
- (catch 'ChoPrim':encode('ChoCon', {wrong,233})),
- {error,{asn1,{invalid_choice_tag,_WrongTag}}} =
- (catch 'ChoPrim':decode('ChoCon', <<131,2,0,233>>));
+ {error,{asn1,{{invalid_choice_type,wrong},[_|_]}}} =
+ (catch 'ChoPrim':encode('ChoCon', {wrong,233})),
+ {error,{asn1,{{invalid_choice_tag,_WrongTag},[_|_]}}} =
+ (catch 'ChoPrim':decode('ChoCon', <<131,2,0,233>>));
per ->
ok;
uper ->
diff --git a/lib/asn1/test/testContextSwitchingTypes.erl b/lib/asn1/test/testContextSwitchingTypes.erl
index 10012908a9..bc7d9733b9 100644
--- a/lib/asn1/test/testContextSwitchingTypes.erl
+++ b/lib/asn1/test/testContextSwitchingTypes.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -90,5 +90,6 @@ check_object_identifier(Tuple) when is_tuple(Tuple) ->
enc_dec(T, V0) ->
M = 'ContextSwitchingTypes',
{ok,Enc} = M:encode(T, V0),
+ asn1_test_lib:map_roundtrip(M, T, Enc),
{ok,V} = M:decode(T, Enc),
V.
diff --git a/lib/asn1/test/testInfObj.erl b/lib/asn1/test/testInfObj.erl
index 5a9f47d865..d3ec35b652 100644
--- a/lib/asn1/test/testInfObj.erl
+++ b/lib/asn1/test/testInfObj.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -197,5 +197,6 @@ roundtrip(M, T, V) ->
enc_dec(M, T, V0) ->
{ok,Enc} = M:encode(T, V0),
+ asn1_test_lib:map_roundtrip(M, T, Enc),
{ok,V} = M:decode(T, Enc),
V.
diff --git a/lib/asn1/test/testInfObjectClass.erl b/lib/asn1/test/testInfObjectClass.erl
index 560986fac9..02ff38e78a 100644
--- a/lib/asn1/test/testInfObjectClass.erl
+++ b/lib/asn1/test/testInfObjectClass.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,19 +33,29 @@ main(Rule) ->
roundtrip('Seq', Val),
%% OTP-5783
- {error,{asn1,{'Type not compatible with table constraint',
- {component,'ArgumentType'},
- {value,_},_}}} = 'InfClass':encode('Seq', {'Seq',12,13,1}),
+ {'Type not compatible with table constraint',
+ {component,'ArgumentType'},
+ {value,_},_} = enc_error('Seq', {'Seq',12,13,1}),
Bytes2 = case Rule of
ber ->
<<48,9,2,1,12,2,1,11,2,1,1>>;
_ ->
<<1,12,1,11,1,1>>
end,
- {error,{asn1,{'Type not compatible with table constraint',
- {{component,_},
- {value,_B},_}}}} = 'InfClass':decode('Seq', Bytes2),
+ {'Type not compatible with table constraint',
+ {{component,_},
+ {value,_B},_}} = dec_error('Seq', Bytes2),
ok.
roundtrip(T, V) ->
asn1_test_lib:roundtrip('InfClass', T, V).
+
+enc_error(T, V) ->
+ {error,{asn1,{Reason,Stk}}} = 'InfClass':encode(T, V),
+ [{_,_,_,_}|_] = Stk,
+ Reason.
+
+dec_error(T, Bin) ->
+ {error,{asn1,{Reason,Stk}}} = 'InfClass':decode(T, Bin),
+ [{_,_,_,_}|_] = Stk,
+ Reason.
diff --git a/lib/asn1/test/testMaps.erl b/lib/asn1/test/testMaps.erl
new file mode 100644
index 0000000000..45dd2255ba
--- /dev/null
+++ b/lib/asn1/test/testMaps.erl
@@ -0,0 +1,50 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(testMaps).
+
+-export([main/1]).
+
+main(_) ->
+ M = 'Maps',
+ true = M:maps(),
+
+ true = M:xy1() =:= #{x=>42,y=>17},
+ true = M:xy2() =:= #{x=>0,y=>0},
+ true = M:xy3() =:= #{x=>0,y=>999},
+ true = M:s1() =:= #{xy=>#{x=>100,y=>100}},
+
+ roundtrip('XY', M:xy1()),
+ roundtrip('XY', M:xy2()),
+ roundtrip('XY', M:xy3()),
+ roundtrip('XY', #{}, #{x=>0,y=>0}),
+
+ roundtrip('S', M:s1()),
+ roundtrip('S', #{}, #{xy=>#{x=>100,y=>100}}),
+ roundtrip('S', #{os=><<1,2,3>>}, #{xy=>#{x=>100,y=>100},
+ os=><<1,2,3>>}),
+
+ ok.
+
+roundtrip(Type, Value) ->
+ roundtrip(Type, Value, Value).
+
+roundtrip(Type, Value, Expected) ->
+ asn1_test_lib:roundtrip('Maps', Type, Value, Expected).
diff --git a/lib/asn1/test/testMultipleLevels.erl b/lib/asn1/test/testMultipleLevels.erl
index c610e59f3d..5de2c5a2fa 100644
--- a/lib/asn1/test/testMultipleLevels.erl
+++ b/lib/asn1/test/testMultipleLevels.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,5 +24,7 @@
main(_) ->
Data = {'Top',{short,"abc"},{long,"a long string follows here"}},
- {ok,B} = 'MultipleLevels':encode('Top', Data),
- {ok,Data} = 'MultipleLevels':decode('Top', iolist_to_binary(B)).
+ roundtrip('Top', Data).
+
+roundtrip(T, V) ->
+ asn1_test_lib:roundtrip('MultipleLevels', T, V).
diff --git a/lib/asn1/test/testNBAPsystem.erl b/lib/asn1/test/testNBAPsystem.erl
index 1af283af42..264cf5abd4 100644
--- a/lib/asn1/test/testNBAPsystem.erl
+++ b/lib/asn1/test/testNBAPsystem.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -84,7 +84,7 @@ compile(Config, Options) ->
M <- ["NBAP-CommonDataTypes.asn",
"NBAP-IEs.asn",
"NBAP-PDU-Contents.asn",
- "NBAP-PDU-Discriptions.asn",
+ "NBAP-PDU-Descriptions.asn",
"NBAP-Constants.asn",
"NBAP-Containers.asn"]],
asn1_test_lib:compile_all(Fs, Config, Options),
@@ -98,16 +98,16 @@ test(_Erule,Config) ->
ticket_5812(Config) ->
Msg = v_5812(),
- {ok,B2} = 'NBAP-PDU-Discriptions':encode('NBAP-PDU', Msg),
+ {ok,B2} = 'NBAP-PDU-Descriptions':encode('NBAP-PDU', Msg),
V = <<0,28,74,0,3,48,0,0,1,0,123,64,41,0,0,0,126,64,35,95,208,2,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,145,0,1,205,0,0,0,0,2,98,64,1,128>>,
ok = compare(V,B2),
- {ok,Msg2} = 'NBAP-PDU-Discriptions':decode('NBAP-PDU', B2),
+ {ok,Msg2} = 'NBAP-PDU-Descriptions':decode('NBAP-PDU', B2),
ok = check_record_names(Msg2,Config).
enc_audit_req_msg() ->
Msg = {initiatingMessage, audit_req_msg()},
- {ok,B} = 'NBAP-PDU-Discriptions':encode('NBAP-PDU', Msg),
- {ok,_Msg} = 'NBAP-PDU-Discriptions':decode('NBAP-PDU', B),
+ {ok,B} = 'NBAP-PDU-Descriptions':encode('NBAP-PDU', Msg),
+ {ok,_Msg} = 'NBAP-PDU-Descriptions':decode('NBAP-PDU', B),
{initiatingMessage,
#'InitiatingMessage'{value=#'AuditRequest'{protocolIEs=[{_,114,ignore,_}],
protocolExtensions = asn1_NOVALUE}}} = _Msg,
@@ -116,8 +116,8 @@ enc_audit_req_msg() ->
cell_setup_req_msg_test() ->
Msg = {initiatingMessage, cell_setup_req_msg()},
- {ok,B} = 'NBAP-PDU-Discriptions':encode('NBAP-PDU', Msg),
- {ok,_Msg} = 'NBAP-PDU-Discriptions':decode('NBAP-PDU', B),
+ {ok,B} = 'NBAP-PDU-Descriptions':encode('NBAP-PDU', Msg),
+ {ok,_Msg} = 'NBAP-PDU-Descriptions':decode('NBAP-PDU', B),
io:format("Msg: ~P~n~n_Msg: ~P~n",[Msg,15,_Msg,15]),
ok.
diff --git a/lib/asn1/test/testPrim.erl b/lib/asn1/test/testPrim.erl
index 96a2dd6c79..a5d34f5f08 100644
--- a/lib/asn1/test/testPrim.erl
+++ b/lib/asn1/test/testPrim.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -34,15 +34,12 @@ bool(Rules) ->
Types = ['Bool','BoolCon','BoolPri','BoolApp',
'BoolExpCon','BoolExpPri','BoolExpApp'],
[roundtrip(T, V) || T <- Types, V <- [true,false]],
- case Rules of
- ber ->
- [begin
- {error,{asn1,{encode_boolean,517}}} = enc_error(T, 517)
- end || T <- Types],
- ok;
- _ ->
- ok
- end.
+ Tag = case Rules of
+ ber -> encode_boolean;
+ _ -> illegal_boolean
+ end,
+ [{Tag,517} = enc_error(T, 517) || T <- Types],
+ ok.
int(Rules) ->
@@ -60,10 +57,22 @@ int(Rules) ->
123456789,12345678901234567890,
-1,-2,-3,-4,-100,-127,-255,-256,-257,
-1234567890,-2147483648],
- [roundtrip(T, V) ||
- T <- ['Int','IntCon','IntPri','IntApp',
- 'IntExpCon','IntExpPri','IntExpApp'],
- V <- [1|Values]],
+ Types = ['Int','IntCon','IntPri','IntApp',
+ 'IntExpCon','IntExpPri','IntExpApp'],
+ _ = [roundtrip(T, V) || T <- Types, V <- [1|Values]],
+ Tag = case Rules of
+ ber -> encode_integer;
+ _ -> illegal_integer
+ end,
+ _ = [{Tag,V} = enc_error(T, V) ||
+ T <- Types, V <- [atom,42.0,{a,b,c}]],
+ case Rules of
+ ber ->
+ ok;
+ _ ->
+ _ = [{Tag,V} = enc_error('IntConstrained', V) ||
+ V <- [atom,-1,256,42.0]]
+ end,
%%==========================================================
%% IntEnum ::= INTEGER {first(1),last(31)}
@@ -119,7 +128,11 @@ enum(Rules) ->
roundtrip('Enum', monday),
roundtrip('Enum', thursday),
- {error,{asn1,{_,4}}} = enc_error('Enum', 4),
+ Tag = case Rules of
+ ber -> enumerated_not_in_range;
+ _ -> illegal_enumerated
+ end,
+ {Tag,4} = enc_error('Enum', 4),
case Rules of
Per when Per =:= per; Per =:= uper ->
@@ -182,13 +195,15 @@ roundtrip(Type, Value, ExpectedValue) ->
enc_error(T, V) ->
case get(no_ok_wrapper) of
false ->
- 'Prim':encode(T, V);
+ {error,{asn1,{Reason,Stk}}} = 'Prim':encode(T, V),
+ [{_,_,_,_}|_] = Stk,
+ Reason;
true ->
try 'Prim':encode(T, V) of
_ ->
?t:fail()
catch
- _:Reason ->
+ _:{error,{asn1,Reason}} ->
Reason
end
end.
diff --git a/lib/asn1/test/testPrimStrings.erl b/lib/asn1/test/testPrimStrings.erl
index cb97655c15..b7f0323301 100644
--- a/lib/asn1/test/testPrimStrings.erl
+++ b/lib/asn1/test/testPrimStrings.erl
@@ -19,8 +19,6 @@
%%
%%
-module(testPrimStrings).
--compile([{nowarn_deprecated_function,{asn1rt,utf8_list_to_binary,1}},
- {nowarn_deprecated_function,{asn1rt,utf8_binary_to_list,1}}]).
-export([bit_string/2]).
-export([octet_string/1]).
@@ -756,19 +754,21 @@ utf8_string(_Rules) ->
16#800,
16#ffff,
16#10000,
- 16#1fffff,
- 16#200000,
- 16#3ffffff,
- 16#4000000,
- 16#7fffffff],
+ 16#1ffff,
+ 16#20000,
+ 16#2ffff,
+ 16#e0000,
+ 16#effff,
+ 16#F0000,
+ 16#10ffff],
[begin
- {ok,UTF8} = asn1rt:utf8_list_to_binary([Char]),
- {ok,[Char]} = asn1rt:utf8_binary_to_list(UTF8),
+ UTF8 = unicode:characters_to_binary([Char]),
+ [Char] = unicode:characters_to_list([UTF8]),
roundtrip('UTF', UTF8)
end || Char <- AllRanges],
- {ok,UTF8} = asn1rt:utf8_list_to_binary(AllRanges),
- {ok,AllRanges} = asn1rt:utf8_binary_to_list(UTF8),
+ UTF8 = unicode:characters_to_binary(AllRanges),
+ AllRanges = unicode:characters_to_list(UTF8),
roundtrip('UTF', UTF8),
ok.
diff --git a/lib/asn1/test/testRfcs.erl b/lib/asn1/test/testRfcs.erl
index da7333ef98..502a53220e 100644
--- a/lib/asn1/test/testRfcs.erl
+++ b/lib/asn1/test/testRfcs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2014-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -35,22 +35,27 @@ compile(Config, Erules, Options0) ->
asn1_test_lib:compile_all(Specs, Config, [Erules,{i,CaseDir}|Options]).
test() ->
- {1,3,6,1,5,5,7,48,1,2} =
- IdPkixOcspNonce =
- 'OCSP-2009':'id-pkix-ocsp-nonce'(),
- roundtrip('OCSP-2009', 'OCSPRequest',
- {'OCSPRequest',
- {'TBSRequest',
- 0,
- {rfc822Name,"name string"},
- [{'Request',
- {'CertID',{'_',{2,9,3,4,5},asn1_NOVALUE},
- <<"POTATOHASH">>,<<"HASHBROWN">>,42},
- [{'_',IdPkixOcspNonce,true,<<34,159,16,57,199>>}]}],
- asn1_NOVALUE},
- asn1_NOVALUE}),
- otp_7759(),
- ok.
+ M = 'OCSP-2009',
+ case M:maps() of
+ false ->
+ {1,3,6,1,5,5,7,48,1,2} =
+ IdPkixOcspNonce =
+ 'OCSP-2009':'id-pkix-ocsp-nonce'(),
+ roundtrip('OCSP-2009', 'OCSPRequest',
+ {'OCSPRequest',
+ {'TBSRequest',
+ 0,
+ {rfc822Name,"name string"},
+ [{'Request',
+ {'CertID',{'_',{2,9,3,4,5},asn1_NOVALUE},
+ <<"POTATOHASH">>,<<"HASHBROWN">>,42},
+ [{'_',IdPkixOcspNonce,true,<<34,159,16,57,199>>}]}],
+ asn1_NOVALUE},
+ asn1_NOVALUE}),
+ otp_7759(records);
+ true ->
+ otp_7759(maps)
+ end.
roundtrip(Module, Type, Value0) ->
Enc = Module:encode(Type, Value0),
@@ -58,7 +63,7 @@ roundtrip(Module, Type, Value0) ->
asn1_test_lib:match_value(Value0, Value1),
ok.
-otp_7759() ->
+otp_7759(Pack) ->
%% The release note for asn-1.6.6 says:
%% Decode of an open_type when the value was empty tagged
%% type encoded with indefinite length failed.
@@ -66,10 +71,15 @@ otp_7759() ->
Encoded = encoded_msg(),
ContentInfo = Mod:decode('ContentInfo', Encoded),
io:format("~p\n", [ContentInfo]),
- {'ContentInfo',_Id,PKCS7_content} = ContentInfo,
- X = Mod:decode('SignedData', PKCS7_content),
+ Content = case ContentInfo of
+ {'ContentInfo',_Id,Content0} when Pack =:= records ->
+ Content0;
+ #{'content-type':=_,'pkcs7-content':=Content0}
+ when Pack =:= maps ->
+ Content0
+ end,
+ X = Mod:decode('SignedData', Content),
io:format("~p\n", [X]),
- io:nl(),
ok.
encoded_msg() ->
diff --git a/lib/asn1/test/testSeqExtension.erl b/lib/asn1/test/testSeqExtension.erl
index f7885cb002..f7187314ce 100644
--- a/lib/asn1/test/testSeqExtension.erl
+++ b/lib/asn1/test/testSeqExtension.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@
-record('SeqExt4',{bool, int}).
-record('SeqExt5',{name, shoesize}).
-record('SeqExt6',{i1,i2,i3,i4,i5,i6,i7}).
+-record('SeqExt7',{a=asn1_NOVALUE,b=asn1_NOVALUE,c}).
-record('SuperSeq',{s1,s2,s3,s4,s5,s6,i}).
main(Erule, DataDir, Opts) ->
@@ -45,8 +46,35 @@ main(Erule, DataDir, Opts) ->
roundtrip('SeqExt4', #'SeqExt4'{bool=true,int=12345}),
roundtrip('SeqExt4', #'SeqExt4'{bool=false,int=123456}),
+ case Erule of
+ ber ->
+ %% BER currently does not handle Extension Addition Groups
+ %% correctly.
+ ok;
+ _ ->
+ v_roundtrip3('SeqExt5', #'SeqExt5'{name=asn1_NOVALUE,
+ shoesize=asn1_NOVALUE},
+ Erule, #{per=>"00",
+ uper=>"00"}),
+ v_roundtrip3('SeqExt7', #'SeqExt7'{c=asn1_NOVALUE},
+ Erule, #{per=>"00",
+ uper=>"00"})
+ end,
roundtrip('SeqExt5', #'SeqExt5'{name = <<"Arne">>,shoesize=47}),
+ v_roundtrip3('SeqExt7', #'SeqExt7'{c=false},
+ Erule, #{per=>"80800100",
+ uper=>"80808000"}),
+ v_roundtrip3('SeqExt7', #'SeqExt7'{c=true},
+ Erule, #{per=>"80800120",
+ uper=>"80809000"}),
+ v_roundtrip3('SeqExt7', #'SeqExt7'{a=777,b = <<16#AA>>,c=false},
+ Erule, #{per=>"808006C0 030901AA 00",
+ uper=>"8082E061 20354000"}),
+ v_roundtrip3('SeqExt7', #'SeqExt7'{a=8888,c=false},
+ Erule, #{per=>"80800480 22B800",
+ uper=>"8081C457 0000"}),
+
%% Encode a value with this version of the specification.
BigInt = 128638468966,
SuperSeq = #'SuperSeq'{s1=#'SeqExt1'{},
@@ -106,6 +134,7 @@ main(Erule, DataDir, Opts) ->
v_roundtrip2(Erule, 'SeqExt130',
list_to_tuple(['SeqExt130'|
lists:duplicate(129, asn1_NOVALUE)++[199]])),
+
ok.
roundtrip(Type, Value) ->
@@ -118,6 +147,15 @@ v_roundtrip2(Erule, Type, Value) ->
roundtrip2(Type, Value) ->
asn1_test_lib:roundtrip_enc('SeqExtension2', Type, Value).
+v_roundtrip3(Type, Value, Erule, Map) ->
+ case maps:find(Erule, Map) of
+ {ok,Hex} ->
+ Encoded = asn1_test_lib:hex_to_bin(Hex),
+ Encoded = asn1_test_lib:roundtrip_enc('SeqExtension', Type, Value);
+ error ->
+ asn1_test_lib:roundtrip('SeqExtension', Type, Value)
+ end.
+
v(ber, 'SeqExt66') -> "30049F41 017D";
v(per, 'SeqExt66') -> "C0420000 00000000 00004001 FA";
v(uper, 'SeqExt66') -> "D0800000 00000000 00101FA0";
diff --git a/lib/asn1/test/testTCAP.erl b/lib/asn1/test/testTCAP.erl
index 422ae1f0fc..d892863f5e 100644
--- a/lib/asn1/test/testTCAP.erl
+++ b/lib/asn1/test/testTCAP.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -92,5 +92,6 @@ test_asn1config() ->
enc_dec(T, V0) ->
M = 'TCAPPackage',
{ok,Enc} = M:encode(T, V0),
+ asn1_test_lib:map_roundtrip(M, T, Enc),
{ok,V} = M:decode(T, Enc),
V.
diff --git a/lib/asn1/test/testTimer.erl b/lib/asn1/test/testTimer.erl
index bd8da85735..e8313802e4 100644
--- a/lib/asn1/test/testTimer.erl
+++ b/lib/asn1/test/testTimer.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,7 +25,42 @@
-define(times, 5000).
-val() ->
+go() ->
+ Module = 'H323-MESSAGES',
+ Type = 'H323-UserInformation',
+ Value = case Module:maps() of
+ false -> val_records();
+ true -> val_maps()
+ end,
+ Bytes = Module:encode(Type, Value),
+ Value = Module:decode(Type, Bytes),
+
+ {ValWr,done} = timer:tc(fun() -> encode(?times, Module, Type, Value) end),
+ io:format("ASN.1 encoding: ~p micro~n", [ValWr / ?times]),
+
+ done = decode(2, Module, Type, Bytes),
+
+ {ValRead,done} = timer:tc(fun() -> decode(?times, Module, Type, Bytes) end),
+ io:format("ASN.1 decoding: ~p micro~n", [ValRead /?times]),
+
+ Comment = "encode: "++integer_to_list(round(ValWr/?times)) ++
+ " micro, decode: "++integer_to_list(round(ValRead /?times)) ++
+ " micro. [" ++ atom_to_list(Module:encoding_rule()) ++ "]",
+ {comment,Comment}.
+
+encode(0, _Module,_Type,_Value) ->
+ done;
+encode(N, Module,Type,Value) ->
+ Module:encode(Type, Value),
+ encode(N-1, Module, Type, Value).
+
+decode(0, _Module, _Type, _Value) ->
+ done;
+decode(N, Module, Type, Value) ->
+ Module:decode(Type, Value),
+ decode(N-1, Module, Type, Value).
+
+val_records() ->
{'H323-UserInformation',{'H323-UU-PDU',
{callProceeding,
{'CallProceeding-UUIE',
@@ -126,34 +161,66 @@ val() ->
{'H323-UserInformation_user-data',24,<<"O">>}}.
-go() ->
- Module = 'H323-MESSAGES',
- Type = 'H323-UserInformation',
- Value = val(),
- Bytes = Module:encode(Type, Value),
- Value = Module:decode(Type, Bytes),
-
- {ValWr,done} = timer:tc(fun() -> encode(?times, Module, Type, Value) end),
- io:format("ASN.1 encoding: ~p micro~n", [ValWr / ?times]),
-
- done = decode(2, Module, Type, Bytes),
-
- {ValRead,done} = timer:tc(fun() -> decode(?times, Module, Type, Bytes) end),
- io:format("ASN.1 decoding: ~p micro~n", [ValRead /?times]),
-
- Comment = "encode: "++integer_to_list(round(ValWr/?times)) ++
- " micro, decode: "++integer_to_list(round(ValRead /?times)) ++
- " micro. [" ++ atom_to_list(Module:encoding_rule()) ++ "]",
- {comment,Comment}.
-
-encode(0, _Module,_Type,_Value) ->
- done;
-encode(N, Module,Type,Value) ->
- Module:encode(Type, Value),
- encode(N-1, Module, Type, Value).
-
-decode(0, _Module, _Type, _Value) ->
- done;
-decode(N, Module, Type, Value) ->
- Module:decode(Type, Value),
- decode(N-1, Module, Type, Value).
+val_maps() ->
+#{'h323-uu-pdu' => #{h245Control => [],
+ h245Tunneling => true,
+ 'h323-message-body' => {callProceeding,#{callIdentifier => #{guid => <<"OCTET STRINGOCTE">>},
+ cryptoTokens => [{cryptoGKPwdEncr,#{algorithmOID => {1,18,467,467},
+ encryptedData => <<"OC">>,
+ paramS => #{iv8 => <<"OCTET ST">>,
+ ranInt => -7477016}}},
+ {cryptoGKPwdEncr,#{algorithmOID => {1,19,486,486},
+ encryptedData => <<>>,
+ paramS => #{iv8 => <<"OCTET ST">>,
+ ranInt => -2404513}}}],
+ destinationInfo => #{gatekeeper => #{nonStandardData => #{data => <<"O">>,
+ nonStandardIdentifier => {object,{0,10,260}}}},
+ gateway => #{nonStandardData => #{data => <<"O">>,
+ nonStandardIdentifier => {object,{0,13,326}}},
+ protocol => [{h320,#{dataRatesSupported => [#{channelMultiplier => 78,
+ channelRate => 1290470518,
+ nonStandardData => #{data => <<"O">>,
+ nonStandardIdentifier => {object,{0,11,295}}}}],
+ nonStandardData => #{data => <<"O">>,
+ nonStandardIdentifier => {object,{0,11,282}}},
+ supportedPrefixes => [#{nonStandardData => #{data => <<"O">>,
+ nonStandardIdentifier => {object,{0,12,312}}},
+ prefix => {'h323-ID',"BM"}}]}}]},
+ mc => true,
+ mcu => #{nonStandardData => #{data => <<"OC">>,
+ nonStandardIdentifier => {object,{1,13,340,340}}}},
+ nonStandardData => #{data => <<"O">>,nonStandardIdentifier => {object,{0,9,237}}},
+ terminal => #{nonStandardData => #{data => <<"OC">>,
+ nonStandardIdentifier => {object,{1,14,353,354}}}},
+ undefinedNode => true,
+ vendor => #{productId => <<"OC">>,
+ vendor => #{manufacturerCode => 16282,
+ t35CountryCode => 62,
+ t35Extension => 63},
+ versionId => <<"OC">>}},
+ fastStart => [],
+ h245Address => {ipxAddress,#{netnum => <<"OCTE">>,
+ node => <<"OCTET ">>,
+ port => <<"OC">>}},
+ h245SecurityMode => {noSecurity,'NULL'},
+ protocolIdentifier => {0,8,222},
+ tokens => [#{certificate => #{certificate => <<"OC">>,type => {1,16,405,406}},
+ challenge => <<"OCTET STR">>,
+ dhkey => #{generator => <<1:1>>,halfkey => <<1:1>>,modSize => <<1:1>>},
+ generalID => "BMP",
+ nonStandard => #{data => <<"OC">>,nonStandardIdentifier => {1,16,414,415}},
+ password => "BM",
+ random => -26430296,
+ timeStamp => 1667517741},
+ #{certificate => #{certificate => <<"OC">>,type => {1,17,442,443}},
+ challenge => <<"OCTET STRI">>,
+ dhkey => #{generator => <<1:1>>,halfkey => <<1:1>>,modSize => <<1:1>>},
+ generalID => "BMP",
+ nonStandard => #{data => <<"OC">>,nonStandardIdentifier => {1,18,452,452}},
+ password => "BMP",
+ random => -16356110,
+ timeStamp => 1817656756}]}},
+ h4501SupplementaryService => [],
+ nonStandardControl => [],
+ nonStandardData => #{data => <<>>,nonStandardIdentifier => {object,{0,3,84}}}},
+ 'user-data' => #{'protocol-discriminator' => 24,'user-information' => <<"O">>}}.
diff --git a/lib/asn1/test/testUniqueObjectSets.erl b/lib/asn1/test/testUniqueObjectSets.erl
index 4d3ec94391..476d190651 100644
--- a/lib/asn1/test/testUniqueObjectSets.erl
+++ b/lib/asn1/test/testUniqueObjectSets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2014-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ seq_roundtrip(I, D0) ->
M = 'UniqueObjectSets',
try
{ok,Enc} = M:encode('Seq', {'Seq',I,D0}),
+ asn1_test_lib:map_roundtrip(M, 'Seq', Enc),
{ok,{'Seq',I,D}} = M:decode('Seq', Enc),
D
catch C:E ->
diff --git a/lib/asn1/test/test_compile_options.erl b/lib/asn1/test/test_compile_options.erl
index ac74470537..f9997d37d0 100644
--- a/lib/asn1/test/test_compile_options.erl
+++ b/lib/asn1/test/test_compile_options.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,8 +24,8 @@
-include_lib("common_test/include/ct.hrl").
--export([wrong_path/1,comp/2,path/1,ticket_6143/1,noobj/1,
- record_name_prefix/1,verbose/1]).
+-export([wrong_path/1,comp/2,path/1,noobj/1,
+ record_name_prefix/1,verbose/1,maps/1]).
%% OTP-5689
wrong_path(Config) ->
@@ -64,8 +64,6 @@ path(Config) ->
file:set_cwd(CWD),
ok.
-ticket_6143(Config) -> asn1_test_lib:compile("AA1", Config, []).
-
noobj(Config) ->
DataDir = proplists:get_value(data_dir,Config),
OutDir = proplists:get_value(priv_dir,Config),
@@ -130,6 +128,28 @@ verbose(Config) when is_list(Config) ->
[] = test_server:capture_get(),
ok.
+maps(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ OutDir = proplists:get_value(case_dir, Config),
+ InFile = filename:join(DataDir, "P-Record"),
+
+ do_maps(ber, InFile, OutDir),
+ do_maps(per, InFile, OutDir),
+ do_maps(uper, InFile, OutDir).
+
+do_maps(Erule, InFile, OutDir) ->
+ Opts = [Erule,maps,{outdir,OutDir}],
+ ok = asn1ct:compile(InFile, Opts),
+
+ %% Make sure that no .hrl files are generated.
+ [] = filelib:wildcard(filename:join(OutDir, "*.hrl")),
+
+ %% Remove all generated files.
+ All = filelib:wildcard(filename:join(OutDir, "*")),
+ _ = [file:delete(N) || N <- All],
+
+ ok.
+
outfiles_check(OutDir) ->
outfiles_check(OutDir,outfiles1()).
diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk
index 527af05da1..7329a9f879 100644
--- a/lib/asn1/vsn.mk
+++ b/lib/asn1/vsn.mk
@@ -1 +1 @@
-ASN1_VSN = 4.0.3
+ASN1_VSN = 5.0
diff --git a/lib/common_test/doc/specs/.gitignore b/lib/common_test/doc/specs/.gitignore
new file mode 100644
index 0000000000..322eebcb06
--- /dev/null
+++ b/lib/common_test/doc/specs/.gitignore
@@ -0,0 +1 @@
+specs_*.xml
diff --git a/lib/common_test/doc/src/Makefile b/lib/common_test/doc/src/Makefile
index e495f587a3..faa2d58a06 100644
--- a/lib/common_test/doc/src/Makefile
+++ b/lib/common_test/doc/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2003-2016. All Rights Reserved.
+# Copyright Ericsson AB 2003-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -53,7 +53,8 @@ XML_REF3_FILES = ct.xml \
ct_slave.xml \
ct_property_test.xml \
ct_netconfc.xml \
- ct_hooks.xml
+ ct_hooks.xml \
+ ct_testspec.xml
XML_REF6_FILES = common_test_app.xml
XML_PART_FILES = part.xml
@@ -105,11 +106,17 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
+SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml)
+
+TOP_SPECS_FILE = specs.xml
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
XML_FLAGS +=
DVIPS_FLAGS +=
+SPECS_FLAGS = -I../../include -I../../../snmp/include \
+ -I../../../kernel/include
# ----------------------------------------------------
# Targets
@@ -118,7 +125,7 @@ DVIPS_FLAGS +=
$(HTMLDIR)/%.gif: %.gif
$(INSTALL_DATA) $< $@
-docs: pdf html man
+docs: man pdf html
$(TOP_PDF_FILE): $(XML_FILES)
@@ -139,6 +146,7 @@ clean clean_docs:
rm -f $(MAN3DIR)/*
rm -f $(MAN6DIR)/*
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f $(SPECDIR)/*
rm -f errs core *~
# ----------------------------------------------------
diff --git a/lib/common_test/doc/src/basics_chapter.xml b/lib/common_test/doc/src/basics_chapter.xml
index b349d93813..95599ca1f1 100644
--- a/lib/common_test/doc/src/basics_chapter.xml
+++ b/lib/common_test/doc/src/basics_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2016</year>
+ <year>2003</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -75,7 +75,7 @@
<p><c>Common Test</c> is also a very useful tool for white-box testing Erlang
code (for example, module testing), as the test programs can call exported Erlang
- functions directly. there is very little overhead required for
+ functions directly. There is very little overhead required for
implementing basic test suites and executing simple tests. For black-box
testing Erlang software, Erlang RPC and standard O&amp;M interfaces
can be used for example.
diff --git a/lib/common_test/doc/src/common_test_app.xml b/lib/common_test/doc/src/common_test_app.xml
index 3f83747485..a3b3f927eb 100644
--- a/lib/common_test/doc/src/common_test_app.xml
+++ b/lib/common_test/doc/src/common_test_app.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2003</year><year>2016</year>
+ <year>2003</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -224,7 +224,9 @@
</type>
<desc>
- <p>OPTIONAL</p>
+ <p>OPTIONAL; if this function is defined, then <seealso
+ marker="#Module:end_per_suite-1"><c>end_per_suite/1</c></seealso>
+ must also be defined.</p>
<p>This configuration function is called as the first function in the
suite. It typically contains initializations that are common for
@@ -256,7 +258,9 @@
</type>
<desc>
- <p>OPTIONAL</p>
+ <p>OPTIONAL; if this function is defined, then <seealso
+ marker="#Module:init_per_suite-1"><c>init_per_suite/1</c></seealso>
+ must also be defined.</p>
<p>This function is called as the last test case in the
suite. It is meant to be used for cleaning up after
@@ -360,7 +364,9 @@
</type>
<desc>
- <p>OPTIONAL</p>
+ <p>OPTIONAL; if this function is defined, then <seealso
+ marker="#Module:end_per_group-2"><c>end_per_group/2</c></seealso>
+ must also be defined.</p>
<p>This configuration function is called before execution of a
test case group. It typically contains initializations that are
@@ -396,7 +402,9 @@
</type>
<desc>
- <p>OPTIONAL</p>
+ <p>OPTIONAL; if this function is defined, then <seealso
+ marker="#Module:init_per_group-2"><c>init_per_group/2</c></seealso>
+ must also be defined.</p>
<p>This function is called after the execution of a test case group
is finished. It is meant to be used for cleaning up after
@@ -427,7 +435,10 @@
</type>
<desc>
- <p>OPTIONAL</p>
+ <p>OPTIONAL; if this function is defined,
+ then <seealso marker="#Module:end_per_testcase-2">
+ <c>end_per_testcase/2</c></seealso> must also be
+ defined.</p>
<p>This function is called before each test case. Argument
<c>TestCase</c> is the test case name, and
@@ -454,7 +465,10 @@
</type>
<desc>
- <p>OPTIONAL</p>
+ <p>OPTIONAL; if this function is defined,
+ then <seealso marker="#Module:init_per_testcase-2">
+ <c>init_per_testcase/2</c></seealso> must also be
+ defined.</p>
<p>This function is called after each test case, and can be used
to clean up after
@@ -566,7 +580,7 @@
(which also causes the test case process to terminate).</p>
<p>Elements from the <c>Config</c> list can, for example, be read
- with <c>proplists:get_value/2</c> in <c>STDLIB</c>
+ with <c>proplists:get_value/2</c> in STDLIB
(or the macro <c>?config</c> defined in <c>ct.hrl</c>).</p>
<p>If you decide not to run the test case after all, return
diff --git a/lib/common_test/doc/src/ct.xml b/lib/common_test/doc/src/ct.xml
index 264bcff251..1a3cfdb0c5 100644
--- a/lib/common_test/doc/src/ct.xml
+++ b/lib/common_test/doc/src/ct.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2010</year><year>2016</year>
+ <year>2010</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -70,17 +70,69 @@
<marker id="types"/>
<taglist>
- <tag><c>handle() = pid()</c></tag>
- <item><marker id="type-handle"/>
- <p>The identity (handle) of a connection.</p></item>
-
- <tag><c>target_name() = atom()</c></tag>
- <item><marker id="type-target_name"/>
- <p>A name and association to configuration data introduced
- through a require statement, or a call to
- <seealso marker="#require-2"><c>ct:require/2</c></seealso>,
- for example,
- <c>ct:require(mynodename,{node,[telnet]})</c>.</p></item>
+ <tag>
+ <marker id="type-handle"/>
+ <c>handle() = pid()</c>
+ </tag>
+ <item>
+ <p>The identity (handle) of a connection.</p>
+ </item>
+
+ <tag>
+ <marker id="type-config_key"/>
+ <c>config_key() = atom()</c>
+ </tag>
+ <item>
+ <p>A configuration key which exists in a configuration file</p>
+ </item>
+
+ <tag>
+ <marker id="type-target_name"/><c>target_name() = atom()</c>
+ </tag>
+ <item>
+ <p>A name and association to configuration data introduced
+ through a require statement, or a call to
+ <seealso marker="#require-2"><c>ct:require/2</c></seealso>,
+ for example,
+ <c>ct:require(mynodename,{node,[telnet]})</c>.</p>
+ </item>
+
+ <tag>
+ <marker id="type-key_or_name"/>
+ <c>key_or_name() = config_key() | target_name()</c>
+ </tag>
+ <item/>
+
+ <tag>
+ <marker id="type-conn_log_options"/>
+ <c>conn_log_options() = [conn_log_option()]</c>
+ </tag>
+ <item>
+ <p>Options that can be given to the <c>cth_conn_log</c> hook,
+ which is used for logging of NETCONF and Telnet
+ connections. See
+ <seealso marker="ct_netconfc#Logging">ct_netconfc</seealso>
+ or <seealso marker="ct_telnet#Logging">ct_telnet</seealso>
+ for description and examples of how to use this hook.</p>
+ </item>
+
+ <tag>
+ <marker id="type-conn_log_option"/>
+ <c>conn_log_option() = {log_type,conn_log_type()} | {hosts,[key_or_name()]}</c>
+ </tag>
+ <item/>
+
+ <tag>
+ <marker id="type-conn_log_type"/>
+ <c>conn_log_type() = raw | pretty | html | silent</c>
+ </tag>
+ <item/>
+
+ <tag>
+ <marker id="type-conn_log_mod"/>
+ <c>conn_log_mod() = ct_netconfc | ct_telnet</c>
+ </tag>
+ <item/>
</taglist>
</section>
@@ -620,6 +672,21 @@
</func>
<func>
+ <name>get_verbosity(Category) -&gt; Level | undefined</name>
+ <fsummary>Read the verbosity level for a logging category.</fsummary>
+ <type>
+ <v>Category = default | atom()</v>
+ <v>Level = integer()</v>
+ </type>
+ <desc><marker id="get_verbosity-1"/>
+ <p>This function returns the verbosity level for the specified logging
+ category. See the <seealso marker="write_test_chapter#logging">
+ User's Guide</seealso> for details. Use the value <c>default</c> to read
+ the general verbosity level.</p>
+ </desc>
+ </func>
+
+ <func>
<name>install(Opts) -&gt; ok | {error, Reason}</name>
<fsummary>Installs configuration files and event handlers.</fsummary>
<type>
@@ -725,7 +792,7 @@
<v>Format = string()</v>
<v>FormatArgs = list()</v>
<v>Opts = [Opt]</v>
- <v>Opt = no_css | esc_chars</v>
+ <v>Opt = {heading,string()} | no_css | esc_chars</v>
</type>
<desc><marker id="log-5"/>
<p>Prints from a test case to the log file.</p>
@@ -777,59 +844,77 @@
caught by any installed event manager.</p>
<p>See also
- <seealso marker="stdlib:gen_event"><c>stdlib:gen_event(3)</c></seealso>.</p>
+ <seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso>.</p>
</desc>
</func>
<func>
<name>pal(Format) -&gt; ok</name>
- <fsummary>Equivalent to pal(default, 50, Format, []).</fsummary>
+ <fsummary>Equivalent to pal(default, 50, Format, [], []).</fsummary>
<desc><marker id="pal-1"/>
<p>Equivalent to
- <seealso marker="#pal-4"><c>ct:pal(default, 50, Format,
- [])</c></seealso>.</p>
+ <seealso marker="#pal-5"><c>ct:pal(default, 50, Format,
+ [], [])</c></seealso>.</p>
</desc>
</func>
<func>
<name>pal(X1, X2) -&gt; ok</name>
<fsummary>Equivalent to pal(Category, Importance, Format,
- FormatArgs).</fsummary>
+ FormatArgs, []).</fsummary>
<type>
<v>X1 = Category | Importance | Format</v>
<v>X2 = Format | FormatArgs</v>
</type>
<desc><marker id="pal-2"/>
- <p>Equivalent to <seealso marker="#pal-4"><c>ct:pal(Category,
- Importance, Format, FormatArgs)</c></seealso>.</p>
+ <p>Equivalent to <seealso marker="#pal-5"><c>ct:pal(Category,
+ Importance, Format, FormatArgs, [])</c></seealso>.</p>
</desc>
</func>
<func>
<name>pal(X1, X2, X3) -&gt; ok</name>
<fsummary>Equivalent to pal(Category, Importance, Format,
- FormatArgs).</fsummary>
+ FormatArgs, Opts).</fsummary>
<type>
<v>X1 = Category | Importance</v>
<v>X2 = Importance | Format</v>
- <v>X3 = Format | FormatArgs</v>
+ <v>X3 = Format | FormatArgs | Opts</v>
</type>
<desc><marker id="pal-3"/>
- <p>Equivalent to <seealso marker="#pal-4"><c>ct:pal(Category,
- Importance, Format, FormatArgs)</c></seealso>.</p>
+ <p>Equivalent to <seealso marker="#pal-5"><c>ct:pal(Category,
+ Importance, Format, FormatArgs, Opts)</c></seealso>.</p>
</desc>
</func>
<func>
- <name>pal(Category, Importance, Format, FormatArgs) -&gt; ok</name>
+ <name>pal(X1, X2, X3, X4) -&gt; ok</name>
+ <fsummary>Equivalent to pal(Category, Importance, Format,
+ FormatArgs, Opts).</fsummary>
+ <type>
+ <v>X1 = Category | Importance</v>
+ <v>X2 = Importance | Format</v>
+ <v>X3 = Format | FormatArgs</v>
+ <v>X4 = FormatArgs | Opts</v>
+ </type>
+ <desc><marker id="pal-4"/>
+ <p>Equivalent to <seealso marker="#pal-5"><c>ct:pal(Category,
+ Importance, Format, FormatArgs, Opts)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>pal(Category, Importance, Format, FormatArgs, Opts) -&gt; ok</name>
<fsummary>Prints and logs from a test case.</fsummary>
<type>
<v>Category = atom()</v>
<v>Importance = integer()</v>
<v>Format = string()</v>
<v>FormatArgs = list()</v>
+ <v>Opts = [Opt]</v>
+ <v>Opt = {heading,string()} | no_css</v>
</type>
- <desc><marker id="pal-4"/>
+ <desc><marker id="pal-5"/>
<p>Prints and logs from a test case.</p>
<p>This function is meant for printing a string from a test case,
@@ -873,52 +958,70 @@
<func>
<name>print(Format) -&gt; ok</name>
- <fsummary>Equivalent to print(default, 50, Format, []).</fsummary>
+ <fsummary>Equivalent to print(default, 50, Format, [], []).</fsummary>
<desc><marker id="print-1"/>
- <p>Equivalent to <seealso marker="#print-4"><c>ct:print(default,
- 50, Format, [])</c></seealso>.</p>
+ <p>Equivalent to <seealso marker="#print-5"><c>ct:print(default,
+ 50, Format, [], [])</c></seealso>.</p>
</desc>
</func>
<func>
<name>print(X1, X2) -&gt; ok</name>
<fsummary>Equivalent to print(Category, Importance, Format,
- FormatArgs).</fsummary>
+ FormatArgs, []).</fsummary>
<type>
<v>X1 = Category | Importance | Format</v>
<v>X2 = Format | FormatArgs</v>
</type>
<desc><marker id="print-2"/>
- <p>Equivalent to <seealso marker="#print-4"><c>ct:print(Category,
- Importance, Format, FormatArgs)</c></seealso>.</p>
+ <p>Equivalent to <seealso marker="#print-5"><c>ct:print(Category,
+ Importance, Format, FormatArgs, [])</c></seealso>.</p>
</desc>
</func>
<func>
<name>print(X1, X2, X3) -&gt; ok</name>
<fsummary>Equivalent to print(Category, Importance, Format,
- FormatArgs).</fsummary>
+ FormatArgs, Opts).</fsummary>
<type>
<v>X1 = Category | Importance</v>
<v>X2 = Importance | Format</v>
- <v>X3 = Format | FormatArgs</v>
+ <v>X3 = Format | FormatArgs | Opts</v>
</type>
<desc><marker id="print-3"/>
- <p>Equivalent to <seealso marker="#print-4"><c>ct:print(Category,
- Importance, Format, FormatArgs)</c></seealso>.</p>
+ <p>Equivalent to <seealso marker="#print-5"><c>ct:print(Category,
+ Importance, Format, FormatArgs, Opts)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>print(X1, X2, X3, X4) -&gt; ok</name>
+ <fsummary>Equivalent to print(Category, Importance, Format,
+ FormatArgs, Opts).</fsummary>
+ <type>
+ <v>X1 = Category | Importance</v>
+ <v>X2 = Importance | Format</v>
+ <v>X3 = Format | FormatArgs</v>
+ <v>X4 = FormatArgs | Opts</v>
+ </type>
+ <desc><marker id="print-4"/>
+ <p>Equivalent to <seealso marker="#print-5"><c>ct:print(Category,
+ Importance, Format, FormatArgs, Opts)</c></seealso>.</p>
</desc>
</func>
<func>
- <name>print(Category, Importance, Format, FormatArgs) -&gt; ok</name>
+ <name>print(Category, Importance, Format, FormatArgs, Opts) -&gt; ok</name>
<fsummary>Prints from a test case to the console.</fsummary>
<type>
<v>Category = atom()</v>
<v>Importance = integer()</v>
<v>Format = string()</v>
<v>FormatArgs = list()</v>
+ <v>Opts = [Opt]</v>
+ <v>Opt = {heading,string()}</v>
</type>
- <desc><marker id="print-4"/>
+ <desc><marker id="print-5"/>
<p>Prints from a test case to the console.</p>
<p>This function is meant for printing a string from a test case to
@@ -1139,7 +1242,7 @@
Opts.</fsummary>
<type>
<v>Opts = [OptTuples]</v>
- <v>OptTuples = {dir, TestDirs} | {suite, Suites} | {group, Groups} | {testcase, Cases} | {spec, TestSpecs} | {join_specs, Bool} | {label, Label} | {config, CfgFiles} | {userconfig, UserConfig} | {allow_user_terms, Bool} | {logdir, LogDir} | {silent_connections, Conns} | {stylesheet, CSSFile} | {cover, CoverSpecFile} | {cover_stop, Bool} | {step, StepOpts} | {event_handler, EventHandlers} | {include, InclDirs} | {auto_compile, Bool} | {abort_if_missing_suites, Bool} | {create_priv_dir, CreatePrivDir} | {multiply_timetraps, M} | {scale_timetraps, Bool} | {repeat, N} | {duration, DurTime} | {until, StopTime} | {force_stop, ForceStop} | {decrypt, DecryptKeyOrFile} | {refresh_logs, LogDir} | {logopts, LogOpts} | {verbosity, VLevels} | {basic_html, Bool} | {esc_chars, Bool} | {ct_hooks, CTHs} | {enable_builtin_hooks, Bool} | {release_shell, Bool}</v>
+ <v>OptTuples = {dir, TestDirs} | {suite, Suites} | {group, Groups} | {testcase, Cases} | {spec, TestSpecs} | {join_specs, Bool} | {label, Label} | {config, CfgFiles} | {userconfig, UserConfig} | {allow_user_terms, Bool} | {logdir, LogDir} | {silent_connections, Conns} | {stylesheet, CSSFile} | {cover, CoverSpecFile} | {cover_stop, Bool} | {step, StepOpts} | {event_handler, EventHandlers} | {include, InclDirs} | {auto_compile, Bool} | {abort_if_missing_suites, Bool} | {create_priv_dir, CreatePrivDir} | {multiply_timetraps, M} | {scale_timetraps, Bool} | {repeat, N} | {duration, DurTime} | {until, StopTime} | {force_stop, ForceStop} | {decrypt, DecryptKeyOrFile} | {refresh_logs, LogDir} | {logopts, LogOpts} | {verbosity, VLevels} | {basic_html, Bool} | {esc_chars, Bool} | {keep_logs,KeepSpec} | {ct_hooks, CTHs} | {enable_builtin_hooks, Bool} | {release_shell, Bool}</v>
<v>TestDirs = [string()] | string()</v>
<v>Suites = [string()] | [atom()] | string() | atom()</v>
<v>Cases = [atom()] | atom()</v>
@@ -1175,6 +1278,7 @@
<v>VLevels = VLevel | [{Category, VLevel}]</v>
<v>VLevel = integer()</v>
<v>Category = atom()</v>
+ <v>KeepSpec = all | pos_integer()</v>
<v>CTHs = [CTHModule | {CTHModule, CTHInitArgs}]</v>
<v>CTHModule = atom()</v>
<v>CTHInitArgs = term()</v>
@@ -1225,6 +1329,21 @@
</func>
<func>
+ <name>set_verbosity(Category, Level) -&gt; ok</name>
+ <fsummary>Set the verbosity level for a logging category.</fsummary>
+ <type>
+ <v>Category = default | atom()</v>
+ <v>Level = integer()</v>
+ </type>
+ <desc><marker id="set_verbosity-2"/>
+ <p>Use this function to set, or modify, the verbosity level for a logging
+ category. See the <seealso marker="write_test_chapter#logging">
+ User's Guide</seealso> for details. Use the value <c>default</c> to set the
+ general verbosity level.</p>
+ </desc>
+ </func>
+
+ <func>
<name>sleep(Time) -&gt; ok</name>
<fsummary>This function, similar to timer:sleep/1, suspends the
test case for a specified time.</fsummary>
@@ -1236,7 +1355,7 @@
<v>Millisecs = integer() | float()</v>
</type>
<desc><marker id="sleep-1"/>
- <p>This function, similar to <c>timer:sleep/1</c> in <c>STDLIB</c>,
+ <p>This function, similar to <c>timer:sleep/1</c> in STDLIB,
suspends the test case for a specified time.
However, this function also multiplies <c>Time</c> with the
<c>multiply_timetraps</c> value (if set) and under certain
@@ -1330,7 +1449,7 @@
caught by any installed event manager.</p>
<p>See also
- <seealso marker="stdlib:gen_event"><c>stdlib:gen_event(3)</c></seealso>.
+ <seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso>.
</p>
</desc>
</func>
diff --git a/lib/common_test/doc/src/ct_hooks.xml b/lib/common_test/doc/src/ct_hooks.xml
index 3b1e564b66..954be0ffba 100644
--- a/lib/common_test/doc/src/ct_hooks.xml
+++ b/lib/common_test/doc/src/ct_hooks.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2010</year><year>2016</year>
+ <year>2010</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -94,7 +94,7 @@
<seealso marker="#Module:id-1"><c>ct_hooks:id/1</c></seealso>,
or a <c>reference</c> (created using
<seealso marker="erts:erlang#make_ref-0">erlang:make_ref/0</seealso>
- in <c>ERTS</c>) if
+ in ERTS) if
<seealso marker="#Module:id-1"><c>ct_hooks:id/1</c></seealso>
is not implemented.</p>
@@ -208,9 +208,10 @@
</func>
<func>
- <name>Module:pre_init_per_group(GroupName, InitData, CTHState) -&gt; Result</name>
+ <name>Module:pre_init_per_group(SuiteName, GroupName, InitData, CTHState) -&gt; Result</name>
<fsummary>Called before init_per_group.</fsummary>
<type>
+ <v>SuiteName = atom()</v>
<v>GroupName = atom()</v>
<v>InitData = Config | SkipOrFail</v>
<v>Config = NewConfig = [{Key,Value}]</v>
@@ -231,13 +232,19 @@
but for function
<seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso>
instead.</p>
+
+ <p>If <c>Module:pre_init_per_group/4</c> is not exported, common_test
+ will attempt to call <c>Module:pre_init_per_group(GroupName,
+ InitData, CTHState)</c> instead. This is for backwards
+ compatibility.</p>
</desc>
</func>
<func>
- <name>Module:post_init_per_group(GroupName, Config, Return, CTHState) -&gt; Result</name>
+ <name>Module:post_init_per_group(SuiteName, GroupName, Config, Return, CTHState) -&gt; Result</name>
<fsummary>Called after init_per_group.</fsummary>
<type>
+ <v>SuiteName = atom()</v>
<v>GroupName = atom()</v>
<v>Config = [{Key,Value}]</v>
<v>Return = NewReturn = Config | SkipOrFail | term()</v>
@@ -258,13 +265,19 @@
but for function
<seealso marker="common_test#Module:init_per_group-2"><c>init_per_group</c></seealso>
instead.</p>
+
+ <p>If <c>Module:post_init_per_group/5</c> is not exported, common_test
+ will attempt to call <c>Module:post_init_per_group(GroupName,
+ Config, Return, CTHState)</c> instead. This is for backwards
+ compatibility.</p>
</desc>
</func>
<func>
- <name>Module:pre_init_per_testcase(TestcaseName, InitData, CTHState) -&gt; Result</name>
+ <name>Module:pre_init_per_testcase(SuiteName, TestcaseName, InitData, CTHState) -&gt; Result</name>
<fsummary>Called before init_per_testcase.</fsummary>
<type>
+ <v>SuiteName = atom()</v>
<v>TestcaseName = atom()</v>
<v>InitData = Config | SkipOrFail</v>
<v>Config = NewConfig = [{Key,Value}]</v>
@@ -286,6 +299,11 @@
<seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase</c></seealso>
instead.</p>
+ <p>If <c>Module:pre_init_per_testcase/4</c> is not exported, common_test
+ will attempt to call <c>Module:pre_init_per_testcase(TestcaseName,
+ InitData, CTHState)</c> instead. This is for backwards
+ compatibility.</p>
+
<p>CTHs cannot be added here right now. That feature may be added in
a later release, but it would right now break backwards
compatibility.</p>
@@ -293,9 +311,10 @@
</func>
<func>
- <name>Module:post_init_per_testcase(TestcaseName, Config, Return, CTHState) -&gt; Result</name>
+ <name>Module:post_init_per_testcase(SuiteName, TestcaseName, Config, Return, CTHState) -&gt; Result</name>
<fsummary>Called after init_per_testcase.</fsummary>
<type>
+ <v>SuiteName = atom()</v>
<v>TestcaseName = atom()</v>
<v>Config = [{Key,Value}]</v>
<v>Return = NewReturn = Config | SkipOrFail | term()</v>
@@ -316,15 +335,21 @@
but for function
<seealso marker="common_test#Module:init_per_testcase-2"><c>init_per_testcase</c></seealso>
instead.</p>
+
+ <p>If <c>Module:post_init_per_testcase/5</c> is not exported, common_test
+ will attempt to call <c>Module:post_init_per_testcase(TestcaseName,
+ Config, Return, CTHState)</c> instead. This is for backwards
+ compatibility.</p>
</desc>
</func>
<func>
- <name>Module:pre_end_per_testcase(TestcaseName, InitData, CTHState) -&gt; Result</name>
+ <name>Module:pre_end_per_testcase(SuiteName, TestcaseName, EndData, CTHState) -&gt; Result</name>
<fsummary>Called before end_per_testcase.</fsummary>
<type>
+ <v>SuiteName = atom()</v>
<v>TestcaseName = atom()</v>
- <v>InitData = Config</v>
+ <v>EndData = Config</v>
<v>Config = NewConfig = [{Key,Value}]</v>
<v>CTHState = NewCTHState = term()</v>
<v>Result = {NewConfig, NewCTHState}</v>
@@ -345,14 +370,20 @@
<p>This function can not change the result of the test case by returning skip or fail
tuples, but it may insert items in <c>Config</c> that can be read in
- <c>end_per_testcase/2</c> or in <c>post_end_per_testcase/4</c>.</p>
+ <c>end_per_testcase/2</c> or in <c>post_end_per_testcase/5</c>.</p>
+
+ <p>If <c>Module:pre_end_per_testcase/4</c> is not exported, common_test
+ will attempt to call <c>Module:pre_end_per_testcase(TestcaseName,
+ EndData, CTHState)</c> instead. This is for backwards
+ compatibility.</p>
</desc>
</func>
<func>
- <name>Module:post_end_per_testcase(TestcaseName, Config, Return, CTHState) -&gt; Result</name>
+ <name>Module:post_end_per_testcase(SuiteName, TestcaseName, Config, Return, CTHState) -&gt; Result</name>
<fsummary>Called after end_per_testcase.</fsummary>
<type>
+ <v>SuiteName = atom()</v>
<v>TestcaseName = atom()</v>
<v>Config = [{Key,Value}]</v>
<v>Return = NewReturn = Config | SkipOrFail | term()</v>
@@ -373,13 +404,19 @@
but for function
<seealso marker="common_test#Module:end_per_testcase-2"><c>end_per_testcase</c></seealso>
instead.</p>
+
+ <p>If <c>Module:post_end_per_testcase/5</c> is not exported, common_test
+ will attempt to call <c>Module:post_end_per_testcase(TestcaseName,
+ Config, Return, CTHState)</c> instead. This is for backwards
+ compatibility.</p>
</desc>
</func>
<func>
- <name>Module:pre_end_per_group(GroupName, EndData, CTHState) -&gt; Result</name>
+ <name>Module:pre_end_per_group(SuiteName, GroupName, EndData, CTHState) -&gt; Result</name>
<fsummary>Called before end_per_group.</fsummary>
<type>
+ <v>SuiteName = atom()</v>
<v>GroupName = atom()</v>
<v>EndData = Config | SkipOrFail</v>
<v>Config = NewConfig = [{Key,Value}]</v>
@@ -400,13 +437,19 @@
but for function
<seealso marker="common_test#Module:end_per_group-2"><c>end_per_group</c></seealso>
instead.</p>
+
+ <p>If <c>Module:pre_end_per_group/4</c> is not exported, common_test
+ will attempt to call <c>Module:pre_end_per_group(GroupName,
+ EndData, CTHState)</c> instead. This is for backwards
+ compatibility.</p>
</desc>
</func>
<func>
- <name>Module:post_end_per_group(GroupName, Config, Return, CTHState) -&gt; Result</name>
+ <name>Module:post_end_per_group(SuiteName, GroupName, Config, Return, CTHState) -&gt; Result</name>
<fsummary>Called after end_per_group.</fsummary>
<type>
+ <v>SuiteName = atom()</v>
<v>GroupName = atom()</v>
<v>Config = [{Key,Value}]</v>
<v>Return = NewReturn = Config | SkipOrFail | term()</v>
@@ -427,6 +470,11 @@
but for function
<seealso marker="common_test#Module:end_per_group-2">end_per_group</seealso>
instead.</p>
+
+ <p>If <c>Module:post_end_per_group/5</c> is not exported, common_test
+ will attempt to call <c>Module:post_end_per_group(GroupName,
+ Config, Return, CTHState)</c> instead. This is for backwards
+ compatibility.</p>
</desc>
</func>
@@ -485,9 +533,10 @@
</func>
<func>
- <name>Module:on_tc_fail(TestName, Reason, CTHState) -&gt; NewCTHState</name>
+ <name>Module:on_tc_fail(SuiteName, TestName, Reason, CTHState) -&gt; NewCTHState</name>
<fsummary>Called after the CTH scope ends.</fsummary>
<type>
+ <v>SuiteName = atom()</v>
<v>TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName</v>
<v>FuncName = atom()</v>
<v>GroupName = atom()</v>
@@ -505,7 +554,7 @@
<item><p>If <c>init_per_suite</c> fails, this function is called after
<seealso marker="#Module:post_init_per_suite-4"><c>post_init_per_suite</c></seealso>.</p></item>
<item><p>If a test case fails, this funcion is called after
- <seealso marker="#Module:post_end_per_testcase-4"><c>post_end_per_testcase</c></seealso>.</p></item>
+ <seealso marker="#Module:post_end_per_testcase-5"><c>post_end_per_testcase</c></seealso>.</p></item>
</list>
<p>If the failed test case belongs to a test case group, the first
@@ -519,13 +568,19 @@
For details, see section
<seealso marker="event_handler_chapter#events">Event Handling</seealso>
in the User's Guide.</p>
+
+ <p>If <c>Module:on_tc_fail/4</c> is not exported, common_test
+ will attempt to call <c>Module:on_tc_fail(TestName, Reason,
+ CTHState)</c> instead. This is for backwards
+ compatibility.</p>
</desc>
</func>
<func>
- <name>Module:on_tc_skip(TestName, Reason, CTHState) -&gt; NewCTHState</name>
+ <name>Module:on_tc_skip(SuiteName, TestName, Reason, CTHState) -&gt; NewCTHState</name>
<fsummary>Called after the CTH scope ends.</fsummary>
<type>
+ <v>SuiteName = atom()</v>
<v>TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName</v>
<v>FuncName = atom()</v>
<v>GroupName = atom()</v>
@@ -542,9 +597,9 @@
<list type="bulleted">
<item><p>If <c>init_per_group</c> is skipped, this function is
called after
- <seealso marker="#Module:post_init_per_group-4"><c>post_init_per_group</c></seealso>.</p></item>
+ <seealso marker="#Module:post_init_per_group-5"><c>post_init_per_group</c></seealso>.</p></item>
<item><p>If a test case is skipped, this function is called after
- <seealso marker="#Module:post_end_per_testcase-4"><c>post_end_per_testcase</c></seealso>.</p></item>
+ <seealso marker="#Module:post_end_per_testcase-5"><c>post_end_per_testcase</c></seealso>.</p></item>
</list>
<p>If the skipped test case belongs to a test case group, the first
@@ -559,6 +614,11 @@
For details, see section
<seealso marker="event_handler_chapter#events">Event Handling</seealso>
in the User's Guide.</p>
+
+ <p>If <c>Module:on_tc_skip/4</c> is not exported, common_test
+ will attempt to call <c>Module:on_tc_skip(TestName, Reason,
+ CTHState)</c> instead. This is for backwards
+ compatibility.</p>
</desc>
</func>
diff --git a/lib/common_test/doc/src/ct_hooks_chapter.xml b/lib/common_test/doc/src/ct_hooks_chapter.xml
index 1998f15697..7ecc2e4298 100644
--- a/lib/common_test/doc/src/ct_hooks_chapter.xml
+++ b/lib/common_test/doc/src/ct_hooks_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2011</year><year>2016</year>
+ <year>2011</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -38,7 +38,7 @@
extensions of the default behavior of <c>Common Test</c> using hooks
before and after all test suite calls. CTHs allow advanced <c>Common Test</c>
users to abstract out behavior that is common to multiple test suites
- without littering all test suites with library calls. this can be used
+ without littering all test suites with library calls. This can be used
for logging, starting, and monitoring external systems,
building C files needed by the tests, and so on.</p>
@@ -175,10 +175,10 @@
<row>
<cell><seealso marker="common_test#Module:init_per_group-2">
init_per_group/2</seealso></cell>
- <cell><seealso marker="ct_hooks#Module:post_init_per_group-4">
- post_init_per_group/4</seealso> is called</cell>
- <cell><seealso marker="ct_hooks#Module:post_end_per_suite-4">
- post_end_per_group/4</seealso> has been called for that group</cell>
+ <cell><seealso marker="ct_hooks#Module:post_init_per_group-5">
+ post_init_per_group/5</seealso> is called</cell>
+ <cell><seealso marker="ct_hooks#Module:post_end_per_group-5">
+ post_end_per_group/5</seealso> has been called for that group</cell>
</row>
<tcaption>Scope of a CTH</tcaption>
</table>
@@ -245,16 +245,18 @@
</list>
<p>
- This is done in the CTH functions called pre_&lt;name of function&gt;.
- These functions take the same three arguments, <c>Name</c>,
+ This is done in the CTH functions called <c>pre_&lt;name of function&gt;</c>.
+ These functions take the arguments <c>SuiteName</c>, <c>Name</c> (group or test case name, if applicable),
<c>Config</c>, and <c>CTHState</c>. The return value of the CTH function
is always a combination of a result for the suite/group/test and an
updated <c>CTHState</c>.</p>
<p>To let the test suite continue on executing, return the configuration
- list that you want the test to use as the result. To skip or
- fail the test, return a tuple with <c>skip</c> or <c>fail</c>, and a reason
- as the result.</p>
+ list that you want the test to use as the result.</p>
+
+ <p>All pre hooks, except <c>pre_end_per_testcase/4</c>, can
+ skip or fail the test by returning a tuple with <c>skip</c> or
+ <c>fail</c>, and a reason as the result.</p>
<p><em>Example:</em></p>
<code>
@@ -290,7 +292,7 @@
<p>
This is done in the CTH functions called <c>post_&lt;name of function&gt;</c>.
- These functions take the same four arguments, <c>Name</c>,
+ These functions take the arguments <c>SuiteName</c>, <c>Name</c> (group or test case name, if applicable),
<c>Config</c>, <c>Return</c>, and <c>CTHState</c>. <c>Config</c> in this
case is the same <c>Config</c> as the testcase is called with.
<c>Return</c> is the value returned by the testcase. If the testcase
@@ -308,7 +310,7 @@
<p><em>Example:</em></p>
<code>
- post_end_per_testcase(_TC, Config, {'EXIT',{_,_}}, CTHState) -&gt;
+ post_end_per_testcase(_Suite, _TC, Config, {'EXIT',{_,_}}, CTHState) -&gt;
case db:check_consistency() of
true ->
%% DB is good, pass the test.
@@ -317,7 +319,7 @@
%% DB is not good, mark as skipped instead of failing
{{skip, "DB is inconsisten!"}, CTHState}
end;
- post_end_per_testcase(_TC, Config, Return, CTHState) -&gt;
+ post_end_per_testcase(_Suite, _TC, Config, Return, CTHState) -&gt;
%% Do nothing if tc does not crash.
{Return, CTHState}.</code>
@@ -331,8 +333,8 @@
<title>Skip and Fail Hooks</title>
<p>
After any post hook has been executed for all installed CTHs,
- <seealso marker="ct_hooks#Module:on_tc_fail-3">on_tc_fail</seealso>
- or <seealso marker="ct_hooks#Module:on_tc_skip-3">on_tc_skip</seealso>
+ <seealso marker="ct_hooks#Module:on_tc_fail-4">on_tc_fail</seealso>
+ or <seealso marker="ct_hooks#Module:on_tc_skip-4">on_tc_skip</seealso>
is called if the testcase failed or was skipped, respectively.
You cannot affect the outcome of the tests any further at this point.
</p>
@@ -374,7 +376,7 @@
<title>Example CTH</title>
<p>The following CTH logs information about a test run into a format
parseable by <seealso marker="kernel:file#consult-1">file:consult/1</seealso>
- (in <c>Kernel</c>):
+ (in Kernel):
</p>
<code>
%%% @doc Common Test Example Common Test Hook module.
@@ -389,18 +391,18 @@
-export([pre_end_per_suite/3]).
-export([post_end_per_suite/4]).
- -export([pre_init_per_group/3]).
- -export([post_init_per_group/4]).
- -export([pre_end_per_group/3]).
- -export([post_end_per_group/4]).
+ -export([pre_init_per_group/4]).
+ -export([post_init_per_group/5]).
+ -export([pre_end_per_group/4]).
+ -export([post_end_per_group/5]).
- -export([pre_init_per_testcase/3]).
- -export([post_init_per_testcase/4]).
- -export([pre_end_per_testcase/3]).
- -export([post_end_per_testcase/4]).
+ -export([pre_init_per_testcase/4]).
+ -export([post_init_per_testcase/5]).
+ -export([pre_end_per_testcase/4]).
+ -export([post_end_per_testcase/5]).
- -export([on_tc_fail/3]).
- -export([on_tc_skip/3]).
+ -export([on_tc_fail/4]).
+ -export([on_tc_skip/4]).
-export([terminate/1]).
@@ -435,46 +437,46 @@
total = State#state.total + State#state.suite_total } }.
%% @doc Called before each init_per_group.
- pre_init_per_group(Group,Config,State) ->
+ pre_init_per_group(Suite,Group,Config,State) ->
{Config, State}.
%% @doc Called after each init_per_group.
- post_init_per_group(Group,Config,Return,State) ->
+ post_init_per_group(Suite,Group,Config,Return,State) ->
{Return, State}.
%% @doc Called before each end_per_group.
- pre_end_per_group(Group,Config,State) ->
+ pre_end_per_group(Suite,Group,Config,State) ->
{Config, State}.
%% @doc Called after each end_per_group.
- post_end_per_group(Group,Config,Return,State) ->
+ post_end_per_group(Suite,Group,Config,Return,State) ->
{Return, State}.
%% @doc Called before each init_per_testcase.
- pre_init_per_testcase(TC,Config,State) ->
+ pre_init_per_testcase(Suite,TC,Config,State) ->
{Config, State#state{ ts = now(), total = State#state.suite_total + 1 } }.
%% Called after each init_per_testcase (immediately before the test case).
- post_init_per_testcase(TC,Config,Return,State) ->
+ post_init_per_testcase(Suite,TC,Config,Return,State) ->
{Return, State}
%% @doc Called before each end_per_testcase (immediately after the test case).
- pre_end_per_testcase(TC,Config,State) ->
+ pre_end_per_testcase(Suite,TC,Config,State) ->
{Config, State}.
%% @doc Called after each end_per_testcase.
- post_end_per_testcase(TC,Config,Return,State) ->
- TCInfo = {testcase, TC, Return, timer:now_diff(now(), State#state.ts)},
+ post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ TCInfo = {testcase, Suite, TC, Return, timer:now_diff(now(), State#state.ts)},
{Return, State#state{ ts = undefined, tcs = [TCInfo | State#state.tcs] } }.
%% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group,
%% post_end_per_group and post_end_per_testcase if the suite, group or test case failed.
- on_tc_fail(TC, Reason, State) ->
+ on_tc_fail(Suite, TC, Reason, State) ->
State.
%% @doc Called when a test case is skipped by either user action
%% or due to an init function failing.
- on_tc_skip(TC, Reason, State) ->
+ on_tc_skip(Suite, TC, Reason, State) ->
State.
%% @doc Called when the scope of the CTH is done
@@ -499,13 +501,13 @@
<tag><c>cth_log_redirect</c></tag>
<item>
<p>Built-in</p>
- <p>Captures all <c>error_logger</c> and <c>SASL</c> logging
+ <p>Captures all <c>error_logger</c> and SASL logging
events and prints them to the current test case log. If an event cannot be
associated with a test case, it is printed in the <c>Common Test</c> framework log.
This happens for test cases running in parallel and events occuring
in-between test cases. You can configure the level of
- <seealso marker="sasl:sasl_app"><c>SASL</c></seealso> events report
- using the normal <c>SASL</c> mechanisms.</p>
+ <seealso marker="sasl:sasl_app">SASL</seealso> events report
+ using the normal SASL mechanisms.</p>
</item>
<tag><c>cth_surefire</c></tag>
<item>
diff --git a/lib/common_test/doc/src/ct_netconfc.xml b/lib/common_test/doc/src/ct_netconfc.xml
index e6930b30d5..7ec8f23073 100644
--- a/lib/common_test/doc/src/ct_netconfc.xml
+++ b/lib/common_test/doc/src/ct_netconfc.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2010</year><year>2016</year>
+ <year>2010</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -35,13 +35,35 @@
<module>ct_netconfc</module>
<modulesummary>NETCONF client module.</modulesummary>
-<description>
+ <description>
<p>NETCONF client module.</p>
<p>The NETCONF client is compliant with RFC 4741 NETCONF Configuration
Protocol and RFC 4742 Using the NETCONF Configuration Protocol over
- Secure SHell (SSH)..</p>
+ Secure SHell (SSH).</p>
+
+ <marker id="Connecting"/>
+ <p><em>Connecting to a NETCONF server</em></p>
+
+ <p>NETCONF sessions can either be opened by a single call
+ to <seealso marker="#open-1"><c>open/1,2</c></seealso> or by a call
+ to <seealso marker="#connect-1"><c>connect/1,2</c></seealso> followed
+ by one or more calls to
+ <seealso marker="#session-1"><c>session/1,2,3</c></seealso>.</p>
+
+ <p>The properties of the sessions will be exactly the same, except
+ that when
+ using <seealso marker="#connect-1"><c>connect/1,2</c></seealso>, you
+ may start multiple sessions over the same SSH connection. Each
+ session is implemented as an SSH channel.</p>
+
+ <p><seealso marker="#open-1"><c>open/1,2</c></seealso> will establish one
+ SSH connection with one SSH channel implementing one NETCONF
+ session. You may start mutiple sessions by
+ calling <seealso marker="#open-1"><c>open/1,2</c></seealso> multiple
+ times, but then a new SSH connection will be established for each
+ session.</p>
<p>For each server to test against, the following entry can be added to a
configuration file:</p>
@@ -49,23 +71,21 @@
<pre>
{server_id(),options()}.</pre>
- <p>The <c>server_id()</c> or an associated <c>target_name()</c> (see
- module <seealso marker="ct"><c>ct</c></seealso>) must then be used
- in calls to
- <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso>.</p>
+ <p>The <seealso marker="#type-server_id"><c>server_id()</c></seealso>
+ or an associated
+ <seealso marker="ct#type-target_name"><c>ct:target_name()</c></seealso>
+ must then be used in calls to
+ <seealso marker="#connect-2"><c>connect/2</c></seealso>
+ or <seealso marker="#open-2"><c>open/2</c></seealso>.</p>
- <p>If no configuration exists for a server, a session can still be
- opened by calling
- <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso> with
- all necessary options specified in the call. The first argument to
- <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso> can
- then be any atom.</p>
+ <p>If no configuration exists for a server,
+ use <seealso marker="#connect-1"><c>connect/1</c></seealso>
+ or <seealso marker="#open-1"><c>open/1</c></seealso> instead,
+ and specify all necessary options in the <c>Options</c> parameter.</p>
- </description>
+ <marker id="Logging"/>
+ <p><em>Logging</em></p>
- <section>
- <marker id="Logging"/>
- <title>Logging</title>
<p>The NETCONF server uses <c>error_logger</c> for logging of NETCONF
traffic. A special purpose error handler is implemented in
<c>ct_conn_log_h</c>. To use this error handler, add the
@@ -73,9 +93,9 @@
<pre>
suite() -&gt;
- [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}].</pre>
+ [{ct_hooks, [{cth_conn_log, [{<seealso marker="ct#type-conn_log_mod"><c>ct:conn_log_mod()</c></seealso>,<seealso marker="ct#type-conn_log_options"><c>ct:conn_log_options()</c></seealso>}]}]}].</pre>
- <p><c>conn_mod()</c> is the name of the <c>Common Test</c> module
+ <p><c>conn_log_mod()</c> is the name of the <c>Common Test</c> module
implementing the connection protocol, for example, <c>ct_netconfc</c>.</p>
<p>Hook option <c>log_type</c> specifies the type of logging:</p>
@@ -84,7 +104,7 @@
<tag><c>raw</c></tag>
<item><p>The sent and received NETCONF data is logged to a separate
text file "as is" without any formatting. A link to the file is
- added to the test case HTML log.</p>.</item>
+ added to the test case HTML log.</p></item>
<tag><c>pretty</c></tag>
<item><p>The sent and received NETCONF data is logged to a separate
@@ -104,7 +124,7 @@
To do this, use hook option <c>hosts</c> and list the names of the
servers/connections to be used in the suite. The connections
must be named for this to work, that is, they must be opened with
- <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso>.</p>
+ <seealso marker="#open-2"><c>open/2</c></seealso>.</p>
<p>Option <c>hosts</c> has no effect if <c>log_type</c> is set to
<c>html</c> or <c>silent</c>.</p>
@@ -113,13 +133,13 @@
configuration variable <c>ct_conn_log</c>:</p>
<pre>
- {ct_conn_log,[{conn_mod(),hook_options()}]}.</pre>
+ {ct_conn_log,[{<seealso marker="ct#type-conn_log_mod"><c>ct:conn_log_mod()</c></seealso>,<seealso marker="ct#type-conn_log_options"><c>ct:conn_log_options()</c></seealso>}]}.</pre>
<p>For example:</p>
<pre>
{ct_conn_log,[{ct_netconfc,[{log_type,pretty},
- {hosts,[key_or_name()]}]}]}</pre>
+ {hosts,[<seealso marker="ct#type-key_or_name"><c>ct:key_or_name()</c></seealso>]}]}]}</pre>
<note>
<p>Hook options specified in a configuration file overwrite the
@@ -164,173 +184,149 @@
<p>The same <c>ct_hooks</c> statement without the configuration file
would cause HTML logging of all NETCONF connections in to the test
case HTML log.</p>
- </section>
- <section>
- <marker id="Notifications"/>
- <title>Notifications</title>
+ <marker id="Notifications"/>
+ <p><em>Notifications</em></p>
<p>The NETCONF client is also compliant with RFC 5277 NETCONF Event
Notifications, which defines a mechanism for an asynchronous message
notification delivery service for the NETCONF protocol.</p>
<p>Specific functions to support this are
- <seealso marker="#create_subscription-6"><c>ct_netconfc:create_subscription/6</c></seealso>
+ <seealso marker="#create_subscription-1"><c>create_subscription/1-6</c></seealso>
and
- <seealso marker="#get_event_streams-3"><c>ct_netconfc:get_event_streams/3</c></seealso>.
- (The functions also exist with other arities.)</p>
- </section>
-
- <section>
- <title>Data Types</title>
- <marker id="types"/>
- <taglist>
- <tag><c>client() = handle() | key_or_name()</c></tag>
- <item><marker id="type-client"/>
- <p>For <c>handle()</c>, see module
- <seealso marker="ct"><c>ct</c></seealso>.</p></item>
-
- <tag><c>error_reason() = term()</c></tag>
- <item><marker id="type-error_reason"/> </item>
- <tag><c>event_time() = {eventTime, xml_attributes(), [xs_datetime()]}</c></tag>
- <item><marker id="type-event_time"/> </item>
-
- <tag><c>handle() = term()</c></tag>
- <item><marker id="type-handle"/>
- <p>Opaque reference for a connection (NETCONF session). For more
- information, see module <seealso marker="ct"><c>ct</c></seealso>.</p>
- </item>
-
- <tag><c>host() = </c><seealso marker="kernel:inet#type-hostname"><c>inet:hostname()</c></seealso>
- <c> | </c><seealso marker="kernel:inet#type-ip_address"><c>inet:ip_address()</c></seealso></tag>
- <item><marker id="type-host"/></item>
-
- <tag><c>key_or_name() = server_id() | target_name()</c></tag>
- <item><marker id="type-key_or_name"/>
- <p>For <c>target_name</c>, see module
- <seealso marker="ct"><c>ct</c></seealso>.</p></item>
-
- <tag><c>netconf_db() = running | startup | candidate</c></tag>
- <item><marker id="type-netconf_db"/> </item>
+ <seealso marker="#get_event_streams-1"><c>get_event_streams/1-3</c></seealso>.</p>
- <tag><c>notification() = {notification, xml_attributes(), notification_content()}</c></tag>
- <item><marker id="type-notification"/> </item>
+ <marker id="Default_timeout"/>
+ <p><em>Default Timeout</em></p>
- <tag><c>notification_content() = [event_time() | simple_xml()]</c></tag>
- <item><marker id="type-notification_content"/> </item>
+ <p>Most of the functions in this module have one variant with
+ a <c>Timeout</c> parameter, and one without. If nothing else is
+ specified, the default value <c>infinity</c> is used when
+ the <c>Timeout</c> parameter is not given.</p>
- <tag><c>option() = {ssh, host()} | {port, </c>
- <seealso marker="kernel:inet#type-port_number"><c>inet:port_number()</c></seealso>
- <c>} | {timeout, timeout()} | SshConnectOption</c></tag>
- <item><marker id="type-option"/>
+ </description>
+ <datatypes>
+ <datatype>
+ <name name="client"/>
+ </datatype>
+ <datatype>
+ <name name="error_reason"/>
+ </datatype>
+ <datatype>
+ <name name="event_time"/>
+ </datatype>
+ <datatype>
+ <name name="handle"/>
+ <desc>
+ <p>Opaque reference for a connection to a NETCONF server or a
+ NETCONF session.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="host"/>
+ </datatype>
+ <datatype>
+ <name name="netconf_db"/>
+ </datatype>
+ <datatype>
+ <name name="notification"/>
+ </datatype>
+ <datatype>
+ <name name="notification_content"/>
+ </datatype>
+ <datatype>
+ <name name="option"/>
+ <desc>
<p><c>SshConnectOption</c> is any valid option to
<seealso marker="ssh:ssh#connect-3"><c>ssh:connect/3,4</c></seealso>.
Common options used are <c>user</c>, <c>password</c>
and <c>user_dir</c>. The <c>SshConnectOptions</c> are
- verfied by the SSH application.</p></item>
-
- <tag><c>options() = [option()]</c></tag>
- <item><marker id="type-options"/>
- <p>Options used for setting up an SSH connection to a NETCONF
- server.</p></item>
-
- <tag><c>server_id() = atom()</c></tag>
- <item><marker id="type-server_id"/>
+ verfied by the SSH application.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="options"/>
+ <desc>
+ <p>Options used for setting up an SSH connection to a NETCONF
+ server.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="server_id"/>
+ <desc>
<p>The identity of a server, specified in a configuration
- file.</p></item>
-
- <tag><c>simple_xml() = {xml_tag(), xml_attributes(), xml_content()} | {xml_tag(), xml_content()} | xml_tag()</c></tag>
- <item><marker id="type-simple_xml"/>
- <p>This type is further described in application
- <seealso marker="xmerl:index"><c>xmerl</c></seealso>.</p></item>
-
- <tag><c>stream_data() = {description, string()} | {replaySupport, string()} | {replayLogCreationTime, string()} | {replayLogAgedTime, string()}</c></tag>
- <item><marker id="type-stream_data"/>
- <p>For details about the data format for the string values, see
- "XML Schema for Event Notifications" in RFC 5277.</p></item>
-
- <tag><c>stream_name() = string()</c></tag>
- <item><marker id="type-stream_name"/> </item>
-
- <tag><c>streams() = [{stream_name(), [stream_data()]}]</c></tag>
- <item><marker id="type-streams"/> </item>
-
- <tag><c>xml_attribute_tag() = atom()</c></tag>
- <item><marker id="type-xml_attribute_tag"/> </item>
-
- <tag><c>xml_attribute_value() = string()</c></tag>
- <item><marker id="type-xml_attribute_value"/> </item>
-
- <tag><c>xml_attributes() = [{xml_attribute_tag(), xml_attribute_value()}]</c></tag>
- <item><marker id="type-xml_attributes"/> </item>
-
- <tag><c>xml_content() = [simple_xml() | iolist()]</c></tag>
- <item><marker id="type-xml_content"/> </item>
-
- <tag><c>xml_tag() = atom()</c></tag>
- <item><marker id="type-xml_tag"/> </item>
-
- <tag><c>xpath() = {xpath, string()}</c></tag>
- <item><marker id="type-xpath"/> </item>
-
- <tag><c>xs_datetime() = string()</c></tag>
- <item><marker id="type-xs_datetime"/>
- <p>This date and time identifier has the same format as the XML type
+ file.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="simple_xml"/>
+ <desc>
+ <p>This type is further described in application
+ <seealso marker="xmerl:index"><c>xmerl</c></seealso>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="stream_data"/>
+ <desc>
+ <p>For details about the data format for the string values, see
+ "XML Schema for Event Notifications" in RFC 5277.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="stream_name"/>
+ </datatype>
+ <datatype>
+ <name name="streams"/>
+ </datatype>
+ <datatype>
+ <name name="xml_attribute_tag"/>
+ </datatype>
+ <datatype>
+ <name name="xml_attribute_value"/>
+ </datatype>
+ <datatype>
+ <name name="xml_attributes"/>
+ </datatype>
+ <datatype>
+ <name name="xml_content"/>
+ </datatype>
+ <datatype>
+ <name name="xml_tag"/>
+ </datatype>
+ <datatype>
+ <name name="xpath"/>
+ </datatype>
+ <datatype>
+ <name name="xs_datetime"/>
+ <desc>
+ <p>This date and time identifier has the same format as the XML type
<c>dateTime</c> and is compliant with RFC 3339 Date and Time on
the Internet Timestamps. The format is as follows:</p>
- <pre>
+ <pre>
[-]CCYY-MM-DDThh:mm:ss[.s][Z|(+|-)hh:mm]</pre>
- </item>
- </taglist>
- </section>
-
- <funcs>
- <func>
- <name>action(Client, Action) -&gt; Result</name>
- <fsummary>Equivalent to action(Client, Action, infinity).</fsummary>
- <desc><marker id="action-2"/>
- <p>Equivalent to
- <seealso marker="#action-3"><c>ct_netconfc:action(Client, Action,
- infinity)</c></seealso>.</p>
</desc>
- </func>
+ </datatype>
+ </datatypes>
+ <funcs>
<func>
- <name>action(Client, Action, Timeout) -&gt; Result</name>
+ <name name="action" arity="2"/>
+ <name name="action" arity="3"/>
<fsummary>Executes an action.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Action = simple_xml()</v>
- <v>Timeout = timeout()</v>
- <v>Result = ok | {ok, [simple_xml()]} | {error, error_reason()}</v>
- </type>
- <desc><marker id="action-3"/>
+ <desc>
<p>Executes an action. If the return type is void, <c>ok</c> is
returned instead of <c>{ok,[simple_xml()]}</c>.</p>
</desc>
</func>
<func>
- <name>close_session(Client) -&gt; Result</name>
- <fsummary>Equivalent to close_session(Client, infinity).</fsummary>
- <desc><marker id="close_session-1"/>
- <p>Equivalent to
- <seealso marker="#close_session-2"><c>ct_netconfc:close_session(Client,
- infinity)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>close_session(Client, Timeout) -&gt; Result</name>
+ <name name="close_session" arity="1"/>
+ <name name="close_session" arity="2"/>
<fsummary>Requests graceful termination of the session associated with
the client.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Timeout = timeout()</v>
- <v>Result = ok | {error, error_reason()}</v>
- </type>
- <desc><marker id="close_session-2"/>
+ <desc>
<p>Requests graceful termination of the session associated with the
client.</p>
@@ -343,115 +339,148 @@
</func>
<func>
- <name>copy_config(Client, Source, Target) -&gt; Result</name>
- <fsummary>Equivalent to copy_config(Client, Source, Target,
- infinity).</fsummary>
- <desc><marker id="copy_config-3"/>
- <p>Equivalent to
- <seealso marker="#copy_config-4"><c>ct_netconfc:copy_config(Client,
- Source, Target, infinity)</c></seealso>.</p>
- </desc>
- </func>
+ <name name="connect" arity="1"/>
+ <fsummary>Opens an SSH connection to a NETCONF server.</fsummary>
+ <desc>
+ <p>Opens an SSH connection to a NETCONF server.</p>
- <func>
- <name>copy_config(Client, Target, Source, Timeout) -&gt; Result</name>
- <fsummary>Copies configuration data.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Target = netconf_db()</v>
- <v>Source = netconf_db()</v>
- <v>Timeout = timeout()</v>
- <v>Result = ok | {error, error_reason()}</v>
- </type>
- <desc><marker id="copy_config-4"/>
- <p>Copies configuration data.</p>
+ <p>If the server options are specified in a configuration file, use
+ <seealso marker="#connect-2"><c>connect/2</c></seealso>
+ instead.</p>
- <p>Which source and target options that can be issued depends on the
- capabilities supported by the server. That is, <c>:candidate</c>
- and/or <c>:startup</c> are required.</p>
+ <p>The opaque <seealso marker="#type-handle"><c>handle()</c></seealso>
+ reference returned from this
+ function is required as connection identifier when opening
+ sessions over this connection, see
+ <seealso marker="#session-1"><c>session/1,2,3</c></seealso>.</p>
+
+ <p>Option <c>timeout</c> (milliseconds) is used when setting up the
+ SSH connection. It is not used for any other purposes during the
+ lifetime of the connection.</p>
</desc>
</func>
<func>
- <name>create_subscription(Client) -&gt; term()</name>
- <fsummary>Creates a subscription for event notifications.</fsummary>
- <desc><marker id="create_subscription-1"/></desc>
- </func>
+ <name name="connect" arity="2"/>
+ <fsummary>Opens an SSH connection to a named NETCONF server.</fsummary>
+ <desc>
+ <p>Open an SSH connection to a named NETCONF server.</p>
- <func>
- <name>create_subscription(Client, Timeout) -&gt; term()</name>
- <fsummary>Creates a subscription for event notifications.</fsummary>
- <desc><marker id="create_subscription-2"/></desc>
- </func>
+ <p>If <c><anno>KeyOrName</anno></c> is a
+ configured <c>server_id()</c> or a
+ <c>target_name()</c> associated with such an Id, then the options
+ for this server are fetched from the configuration file.</p>
- <func>
- <name>create_subscription(Client, Stream, Timeout) -&gt; term()</name>
- <fsummary>Creates a subscription for event notifications.</fsummary>
- <desc><marker id="create_subscription-3"/></desc>
- </func>
+ <p>Argument <c><anno>ExtraOptions</anno></c> is added to the
+ options found in the configuration file. If the same options
+ are specified, the values from the configuration file
+ overwrite <c><anno>ExtraOptions</anno></c>.</p>
- <func>
- <name>create_subscription(Client, StartTime, StopTime, Timeout) -&gt; term()</name>
- <fsummary>Creates a subscription for event notifications.</fsummary>
- <desc><marker id="create_subscription-4"/></desc>
+ <p>If the server is not specified in a configuration file, use
+ <seealso marker="#connect-1"><c>connect/1</c></seealso>
+ instead.</p>
+
+ <p>The opaque <seealso marker="#type-handle"><c>handle()</c></seealso>
+ reference returned from this
+ function can be used as connection identifier when opening
+ sessions over this connection, see
+ <seealso marker="#session-1"><c>session/1,2,3</c></seealso>.
+ However, if <c><anno>KeyOrName</anno></c> is a
+ <c>target_name()</c>, that is, if the server is named through a
+ call to <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>
+ or a <c>require</c> statement in the test suite, then this name can
+ be used instead of
+ <seealso marker="#type-handle"><c>handle()</c></seealso>.</p>
+
+ <p>Option <c>timeout</c> (milliseconds) is used when setting up the
+ SSH connection. It is not used for any other purposes during the
+ lifetime of the connection.</p>
+ </desc>
</func>
<func>
- <name>create_subscription(Client, Stream, StartTime, StopTime, Timeout) -&gt; term()</name>
- <fsummary>Creates a subscription for event notifications.</fsummary>
- <desc><marker id="create_subscription-5"/></desc>
+ <name name="copy_config" arity="3"/>
+ <name name="copy_config" arity="4"/>
+ <fsummary>Copies configuration data.</fsummary>
+ <desc>
+ <p>Copies configuration data.</p>
+
+ <p>Which source and target options that can be issued depends on the
+ capabilities supported by the server. That is, <c>:candidate</c>
+ and/or <c>:startup</c> are required.</p>
+ </desc>
</func>
<func>
- <name>create_subscription(Client, Stream, Filter, StartTime, StopTime, Timeout) -&gt; Result</name>
+ <name>create_subscription(Client) -> Result</name>
+ <name>create_subscription(Client, Stream) -> Result</name>
+ <name>create_subscription(Client, Stream, Filter) -> Result</name>
+ <name>create_subscription(Client, Stream, Filter, Timeout) -> Result</name>
+ <name name="create_subscription" arity="5" clause_i="2"/>
+ <name name="create_subscription" arity="6"/>
<fsummary>Creates a subscription for event notifications.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Stream = stream_name()</v>
- <v>Filter = simple_xml() | [simple_xml()]</v>
- <v>StartTime = xs_datetime()</v>
- <v>StopTime = xs_datetime()</v>
- <v>Timeout = timeout()</v>
- <v>Result = ok | {error, error_reason()}</v>
- </type>
- <desc><marker id="create_subscription-6"/>
+ <desc>
<p>Creates a subscription for event notifications.</p>
<p>This function sets up a subscription for NETCONF event
notifications of the specified stream type, matching the specified
filter. The calling process receives notifications as messages of
- type <c>notification()</c>.</p>
+ type <seealso marker="#type-notification"><c>notification()</c></seealso>.</p>
+
+ <p>Only a subset of the function clauses are show above. The
+ full set of valid combinations of input parameters is as
+ follows:</p>
+
+<pre>create_subscription(Client)
+
+create_subscription(Client, Timeout)
+create_subscription(Client, Stream)
+create_subscription(Client, Filter)
+
+create_subscription(Client, Stream, Timeout)
+create_subscription(Client, Filter, Timeout)
+create_subscription(Client, Stream, Filter)
+create_subscription(Client, StartTime, StopTime)
+
+create_subscription(Client, Stream, Filter, Timeout)
+create_subscription(Client, StartTime, StopTime, Timeout)
+create_subscription(Client, Stream, StartTime, StopTime)
+create_subscription(Client, Filter, StartTime, StopTime)
+
+create_subscription(Client, Stream, StartTime, StopTime, Timeout)
+create_subscription(Client, Stream, Filter, StartTime, StopTime)
+create_subscription(Client, Stream, Filter, StartTime, StopTime, Timeout)</pre>
<taglist>
- <tag><c>Stream</c></tag>
+ <tag><c><anno>Stream</anno></c></tag>
<item><p>Optional parameter that indicates which stream of event
is of interest. If not present, events in the default NETCONF
stream are sent.</p></item>
- <tag><c>Filter</c></tag>
+ <tag><c><anno>Filter</anno></c></tag>
<item><p>Optional parameter that indicates which subset of all
possible events is of interest. The parameter format is the
same as that of the filter parameter in the NETCONF protocol
operations. If not present, all events not precluded by other
parameters are sent.</p></item>
- <tag><c>StartTime</c></tag>
+ <tag><c><anno>StartTime</anno></c></tag>
<item><p>Optional parameter used to trigger the replay feature and
indicate that the replay is to start at the time specified.
- If <c>StartTime</c> is not present, this is not a replay
- subscription.</p>
+ If <c><anno>StartTime</anno></c> is not present, this is not a
+ replay subscription.</p>
<p>It is not valid to specify start times that are later than
- the current time. If <c>StartTime</c> is specified earlier
- than the log can support, the replay begins with the earliest
- available notification.</p>
+ the current time. If <c><anno>StartTime</anno></c> is specified
+ earlier than the log can support, the replay begins with the
+ earliest available notification.</p>
<p>This parameter is of type <c>dateTime</c> and compliant to
RFC 3339. Implementations must support time zones.</p></item>
- <tag><c>StopTime</c></tag>
+ <tag><c><anno>StopTime</anno></c></tag>
<item><p>Optional parameter used with the optional replay feature
to indicate the newest notifications of interest. If
- <c>StopTime</c> is not present, the notifications continues
- until the subscription is terminated.</p>
+ <c><anno>StopTime</anno></c> is not present, the notifications
+ continues until the subscription is terminated.</p>
<p>Must be used with and be later than <c>StartTime</c>. Values
- of <c>StopTime</c> in the future are valid. This parameter is
- of type <c>dateTime</c> and compliant to RFC 3339.
+ of <c><anno>StopTime</anno></c> in the future are valid. This
+ parameter is of type <c>dateTime</c> and compliant to RFC 3339.
Implementations must support time zones.</p></item>
</taglist>
@@ -461,25 +490,10 @@
</func>
<func>
- <name>delete_config(Client, Target) -&gt; Result</name>
- <fsummary>Equivalent to delete_config(Client, Target,
- infinity).</fsummary>
- <desc><marker id="delete_config-2"/>
- <p>Equivalent to
- <seealso marker="#delete_config-3"><c>ct_netconfc:delete_config(Client, Target, infinity)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>delete_config(Client, Target, Timeout) -&gt; Result</name>
+ <name name="delete_config" arity="2"/>
+ <name name="delete_config" arity="3"/>
<fsummary>Deletes configuration data.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Target = startup | candidate</v>
- <v>Timeout = timeout()</v>
- <v>Result = ok | {error, error_reason()}</v>
- </type>
- <desc><marker id="delete_config-3"/>
+ <desc>
<p>Deletes configuration data.</p>
<p>The running configuration cannot be deleted and <c>:candidate</c>
@@ -487,54 +501,25 @@
</desc>
</func>
- <func>
- <name>edit_config(Client, Target, Config) -&gt; Result</name>
- <fsummary>Equivalent to edit_config(Client, Target, Config, [],
- infinity).</fsummary>
- <desc><marker id="edit_config-3"/>
- <p>Equivalent to
- <seealso marker="#edit_config-5"><c>ct_netconfc:edit_config(Client,
- Target, Config, [], infinity)</c></seealso>.</p>
- </desc>
- </func>
+ <func>
+ <name name="disconnect" arity="1"/>
+ <fsummary>Closes the given SSH connection.</fsummary>
+ <desc>
+ <p>Closes the given SSH connection.</p>
- <func>
- <name>edit_config(Client, Target, Config, OptParamsOrTimeout) -&gt; Result</name>
- <fsummary>If OptParamsOrTimeout is a time-out value, this function is
- equivalent to ct_netconfc:edit_config(Client, Target, Config, [],
- Timeout).</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Target = netconf_db()</v>
- <v>Config = simple_xml()</v>
- <v>OptParamsOrTimeout = [simple_xml()] | timeout()</v>
- <v>Result = ok | {error, error_reason()}</v>
- </type>
- <desc><marker id="edit_config-4"/>
- <p>If <c>OptParamsOrTimeout</c> is a time-out value, this function is
- equivalent to
- <seealso marker="#edit_config-5"><c>ct_netconfc:edit_config(Client,
- Target, Config, [], Timeout)</c></seealso>.</p>
-
- <p>If <c>OptParamsOrTimeout</c> is a list of simple XML, this
- function is equivalent to
- <seealso marker="#edit_config-5"><c>ct_netconfc:edit_config(Client,
- Target, Config, OptParams, infinity)</c></seealso>.</p>
+ <p>If there are open NETCONF sessions on the connection, these
+ will be brutally aborted. To avoid this, close each session
+ with <seealso marker="#close_session-1"><c>close_session/1,2</c></seealso></p>
</desc>
</func>
<func>
- <name>edit_config(Client, Target, Config, OptParams, Timeout) -&gt; Result</name>
+ <name name="edit_config" arity="3"/>
+ <name name="edit_config" arity="4" clause_i="1"/>
+ <name name="edit_config" arity="4" clause_i="2"/>
+ <name name="edit_config" arity="5"/>
<fsummary>Edits configuration data.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Target = netconf_db()</v>
- <v>Config = simple_xml()</v>
- <v>OptParams = [simple_xml()]</v>
- <v>Timeout = timeout()</v>
- <v>Result = ok | {error, error_reason()}</v>
- </type>
- <desc><marker id="edit_config-5"/>
+ <desc>
<p>Edits configuration data.</p>
<p>By default only the running target is available, unless the server
@@ -550,29 +535,17 @@
<pre>
[{'default-operation', ["none"]},
{'error-option', ["rollback-on-error"]}]</pre>
- </desc>
- </func>
- <func>
- <name>get(Client, Filter) -&gt; Result</name>
- <fsummary>Equivalent to get(Client, Filter, infinity).</fsummary>
- <desc><marker id="get-2"/>
- <p>Equivalent to
- <seealso marker="#get-3"><c>ct_netconfc:get(Client, Filter,
- infinity)</c></seealso>.</p>
+ <p>If <c><anno>OptParams</anno></c> is not given, the default
+ value <c>[]</c> is used.</p>
</desc>
</func>
<func>
- <name>get(Client, Filter, Timeout) -&gt; Result</name>
+ <name name="get" arity="2"/>
+ <name name="get" arity="3"/>
<fsummary>Gets data.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Filter = simple_xml() | xpath()</v>
- <v>Timeout = timeout()</v>
- <v>Result = {ok, [simple_xml()]} | {error, error_reason()}</v>
- </type>
- <desc><marker id="get-3"/>
+ <desc>
<p>Gets data.</p>
<p>This operation returns both configuration and state data from the
@@ -584,24 +557,10 @@
</func>
<func>
- <name>get_capabilities(Client) -&gt; Result</name>
- <fsummary>Equivalent to get_capabilities(Client, infinity).</fsummary>
- <desc><marker id="get_capabilities-1"/>
- <p>Equivalent to
- <seealso marker="#get_capabilities-2"><c>ct_netconfc:get_capabilities(Client,
- infinity)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>get_capabilities(Client, Timeout) -&gt; Result</name>
+ <name name="get_capabilities" arity="1"/>
+ <name name="get_capabilities" arity="2"/>
<fsummary>Returns the server side capabilities.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Timeout = timeout()</v>
- <v>Result = [string()] | {error, error_reason()}</v>
- </type>
- <desc><marker id="get_capabilities-2"/>
+ <desc>
<p>Returns the server side capabilities.</p>
<p>The following capability identifiers, defined in RFC 4741 NETCONF
@@ -623,26 +582,10 @@
</func>
<func>
- <name>get_config(Client, Source, Filter) -&gt; Result</name>
- <fsummary>Equivalent to get_config(Client, Source, Filter,
- infinity).</fsummary>
- <desc><marker id="get_config-3"/>
- <p>Equivalent to
- <seealso marker="#get_config-4"><c>ct_netconfc:get_config(Client, Source, Filter, infinity)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>get_config(Client, Source, Filter, Timeout) -&gt; Result</name>
+ <name name="get_config" arity="3"/>
+ <name name="get_config" arity="4"/>
<fsummary>Gets configuration data.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Source = netconf_db()</v>
- <v>Filter = simple_xml() | xpath()</v>
- <v>Timeout = timeout()</v>
- <v>Result = {ok, [simple_xml()]} | {error, error_reason()}</v>
- </type>
- <desc><marker id="get_config-4"/>
+ <desc>
<p>Gets configuration data.</p>
<p>To be able to access another source than <c>running</c>, the
@@ -654,25 +597,12 @@
</func>
<func>
- <name>get_event_streams(Client, Timeout) -&gt; Result</name>
- <fsummary>Equivalent to get_event_streams(Client, [], Timeout).</fsummary>
- <desc><marker id="get_event_streams-2"/>
- <p>Equivalent to
- <seealso marker="#get_event_streams-3"><c>ct_netconfc:get_event_streams(Client,
- [], Timeout)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>get_event_streams(Client, Streams, Timeout) -&gt; Result</name>
+ <name name="get_event_streams" arity="1"/>
+ <name name="get_event_streams" arity="2" clause_i="1"/>
+ <name name="get_event_streams" arity="2" clause_i="2"/>
+ <name name="get_event_streams" arity="3"/>
<fsummary>Sends a request to get the specified event streams.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Streams = [stream_name()]</v>
- <v>Timeout = timeout()</v>
- <v>Result = {ok, streams()} | {error, error_reason()}</v>
- </type>
- <desc><marker id="get_event_streams-3"/>
+ <desc>
<p>Sends a request to get the specified event streams.</p>
<p><c>Streams</c> is a list of stream names. The following filter is
@@ -700,67 +630,28 @@
&lt;/netconf&gt;</pre>
<p>If more complex filtering is needed, use
- <seealso marker="#get-2"><c>ct_netconfc:get/2</c></seealso> or
- <seealso marker="#get-3"><c>ct_netconfc:get/3</c></seealso> and
+ <seealso marker="#get-2"><c>ct_netconfc:get/2,3</c></seealso> and
specify the exact filter according to "XML Schema for Event
Notifications" in RFC 5277.</p>
</desc>
</func>
<func>
- <name>get_session_id(Client) -&gt; Result</name>
- <fsummary>Equivalent to get_session_id(Client, infinity).</fsummary>
- <desc><marker id="get_session_id-1"/>
- <p>Equivalent to
- <seealso marker="#get_session_id-2"><c>ct_netconfc:get_session_id(Client,
- infinity)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>get_session_id(Client, Timeout) -&gt; Result</name>
+ <name name="get_session_id" arity="1"/>
+ <name name="get_session_id" arity="2"/>
<fsummary>Returns the session Id associated with the specified
client.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Timeout = timeout()</v>
- <v>Result = pos_integer() | {error, error_reason()}</v>
- </type>
- <desc><marker id="get_session_id-2"/>
+ <desc>
<p>Returns the session Id associated with the specified client.</p>
</desc>
</func>
<func>
- <name>hello(Client) -&gt; Result</name>
- <fsummary>Equivalent to hello(Client, [], infinity).</fsummary>
- <desc><marker id="hello-1"/>
- <p>Equivalent to
- <seealso marker="#hello-3"><c>ct_netconfc:hello(Client, [],
- infinity)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>hello(Client, Timeout) -&gt; Result</name>
- <fsummary>Equivalent to hello(Client, [], Timeout).</fsummary>
- <desc><marker id="hello-2"/>
- <p>Equivalent to
- <seealso marker="#hello-3"><c>ct_netconfc:hello(Client, [],
- Timeout)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>hello(Client, Options, Timeout) -&gt; Result</name>
+ <name name="hello" arity="1"/>
+ <name name="hello" arity="2"/>
+ <name name="hello" arity="3"/>
<fsummary>Exchanges hello messages with the server.</fsummary>
- <type>
- <v>Client = handle()</v>
- <v>Options = [{capability, [string()]}]</v>
- <v>Timeout = timeout()</v>
- <v>Result = ok | {error, error_reason()}</v>
- </type>
- <desc><marker id="hello-3"/>
+ <desc>
<p>Exchanges <c>hello</c> messages with the server.</p>
<p>Adds optional capabilities and sends a <c>hello</c> message to the
@@ -769,27 +660,11 @@
</func>
<func>
- <name>kill_session(Client, SessionId) -&gt; Result</name>
- <fsummary>Equivalent to kill_session(Client, SessionId,
- infinity).</fsummary>
- <desc><marker id="kill_session-2"/>
- <p>Equivalent to
- <seealso marker="#kill_session-3"><c>ct_netconfc:kill_session(Client,
-SessionId, infinity)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>kill_session(Client, SessionId, Timeout) -&gt; Result</name>
+ <name name="kill_session" arity="2"/>
+ <name name="kill_session" arity="3"/>
<fsummary>Forces termination of the session associated with the supplied
session Id.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>SessionId = pos_integer()</v>
- <v>Timeout = timeout()</v>
- <v>Result = ok | {error, error_reason()}</v>
- </type>
- <desc><marker id="kill_session-3"/>
+ <desc>
<p>Forces termination of the session associated with the supplied
session Id.</p>
@@ -807,26 +682,11 @@ SessionId, infinity)</c></seealso>.</p>
</func>
<func>
- <name>lock(Client, Target) -&gt; Result</name>
- <fsummary>Equivalent to lock(Client, Target, infinity).</fsummary>
- <desc><marker id="lock-2"/>
- <p>Equivalent to
- <seealso marker="#lock-3"><c>ct_netconfc:lock(Client, Target,
- infinity)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>lock(Client, Target, Timeout) -&gt; Result</name>
- <fsummary>Unlocks the configuration target.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Target = netconf_db()</v>
- <v>Timeout = timeout()</v>
- <v>Result = ok | {error, error_reason()}</v>
- </type>
- <desc><marker id="lock-3"/>
- <p>Unlocks the configuration target.</p>
+ <name name="lock" arity="2"/>
+ <name name="lock" arity="3"/>
+ <fsummary>Locks the configuration target.</fsummary>
+ <desc>
+ <p>Locks the configuration target.</p>
<p>Which target parameters that can be used depends on if
<c>:candidate</c> and/or <c>:startup</c> are supported by the
@@ -835,9 +695,7 @@ SessionId, infinity)</c></seealso>.</p>
Locks are intended to be short-lived.</p>
<p>Operation
- <seealso marker="#kill_session-2"><c>ct_netconfc:kill_session/2</c></seealso>
- or
- <seealso marker="#kill_session-3"><c>ct_netconfc:kill_session/3</c></seealso>
+ <seealso marker="#kill_session-2"><c>kill_session/2,3</c></seealso>
can be used to force the release of a lock owned by another NETCONF
session. How this is achieved by the server side is
implementation-specific.</p>
@@ -845,54 +703,41 @@ SessionId, infinity)</c></seealso>.</p>
</func>
<func>
- <name>only_open(Options) -&gt; Result</name>
+ <name name="only_open" arity="1"/>
<fsummary>Opens a NETCONF session, but does not send hello.</fsummary>
- <type>
- <v>Options = options()</v>
- <v>Result = {ok, handle()} | {error, error_reason()}</v>
- </type>
- <desc><marker id="only_open-1"/>
+ <desc>
<p>Opens a NETCONF session, but does not send <c>hello</c>.</p>
- <p>As <seealso marker="#open-1"><c>ct_netconfc:open/1</c></seealso>,
- but does not send a <c>hello</c> message.</p>
+ <p>As <seealso marker="#open-1"><c>open/1</c></seealso>, but
+ does not send a <c>hello</c> message.</p>
</desc>
</func>
<func>
- <name>only_open(KeyOrName, ExtraOptions) -&gt; Result</name>
- <fsummary>Opens a name NETCONF session, but does not send
- hello.</fsummary>
- <type>
- <v>KeyOrName = key_or_name()</v>
- <v>ExtraOptions = options()</v>
- <v>Result = {ok, handle()} | {error, error_reason()}</v>
- </type>
- <desc><marker id="only_open-2"/>
- <p>Opens a name NETCONF session, but does not send <c>hello</c>.</p>
-
- <p>As <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso>,
- but does not send a <c>hello</c> message.</p>
+ <name name="only_open" arity="2"/>
+ <fsummary>Opens a named NETCONF session, but does not send hello.</fsummary>
+ <desc>
+ <p>Opens a named NETCONF session, but does not send <c>hello</c>.</p>
+
+ <p>As <seealso marker="#open-2"><c>open/2</c></seealso>, but
+ does not send a <c>hello</c> message.</p>
</desc>
</func>
<func>
- <name>open(Options) -&gt; Result</name>
- <fsummary>Opens a NETCONF session and exchanges hello messages.</fsummary>
- <type>
- <v>Options = options()</v>
- <v>Result = {ok, handle()} | {error, error_reason()}</v>
- </type>
- <desc><marker id="open-1"/>
+ <name name="open" arity="1"/>
+ <fsummary>Opens a NETCONF session and exchanges hello messages.</fsummary>
+ <desc>
<p>Opens a NETCONF session and exchanges <c>hello</c> messages.</p>
<p>If the server options are specified in a configuration file,
or if a named client is needed for logging purposes (see section
<seealso marker="#Logging">Logging</seealso> in this module), use
- <seealso marker="#open-2"><c>ct_netconfc:open/2</c></seealso>
+ <seealso marker="#open-2"><c>open/2</c></seealso>
instead.</p>
- <p>The opaque <c>handle()</c> reference returned from this
+ <p>The opaque <seealso marker="#type-handle"><c>handle()</c></seealso>
+ reference returned from this
function is required as client identifier when calling any other
function in this module.</p>
@@ -904,37 +749,36 @@ SessionId, infinity)</c></seealso>.</p>
</func>
<func>
- <name>open(KeyOrName, ExtraOptions) -&gt; Result</name>
+ <name name="open" arity="2"/>
<fsummary>Opens a named NETCONF session and exchanges hello
messages.</fsummary>
- <type>
- <v>KeyOrName = key_or_name()</v>
- <v>ExtraOptions = options()</v>
- <v>Result = {ok, handle()} | {error, error_reason()}</v>
- </type>
- <desc><marker id="open-2"/>
+ <desc>
<p>Opens a named NETCONF session and exchanges <c>hello</c>
messages.</p>
- <p>If <c>KeyOrName</c> is a configured <c>server_id()</c> or a
+ <p>If <c><anno>KeyOrName</anno></c> is a
+ configured <c>server_id()</c> or a
<c>target_name()</c> associated with such an Id, then the options
for this server are fetched from the configuration file.</p>
- <p>Argument <c>ExtraOptions</c> is added to the options found in the
- configuration file. If the same options are specified, the values
- from the configuration file overwrite <c>ExtraOptions</c>.</p>
+ <p>Argument <c><anno>ExtraOptions</anno></c> is added to the
+ options found in the configuration file. If the same
+ options are specified, the values from the configuration
+ file overwrite <c><anno>ExtraOptions</anno></c>.</p>
<p>If the server is not specified in a configuration file, use
- <seealso marker="#open-1"><c>ct_netconfc:open/1</c></seealso>
+ <seealso marker="#open-1"><c>open/1</c></seealso>
instead.</p>
- <p>The opaque <c>handle()</c> reference returned from this
+ <p>The opaque <seealso marker="#type-handle"><c>handle()</c></seealso>
+ reference returned from this
function can be used as client identifier when calling any other
- function in this module. However, if <c>KeyOrName</c> is a
+ function in this module. However, if <c><anno>KeyOrName</anno></c> is a
<c>target_name()</c>, that is, if the server is named through a
call to <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>
or a <c>require</c> statement in the test suite, then this name can
- be used instead of <c>handle()</c>.</p>
+ be used instead of
+ <seealso marker="#type-handle"><c>handle()</c></seealso>.</p>
<p>Option <c>timeout</c> (milliseconds) is used when setting up the
SSH connection and when waiting for the <c>hello</c> message from
@@ -947,25 +791,10 @@ SessionId, infinity)</c></seealso>.</p>
</func>
<func>
- <name>send(Client, SimpleXml) -&gt; Result</name>
- <fsummary>Equivalent to send(Client, SimpleXml, infinity).</fsummary>
- <desc><marker id="send-2"/>
- <p>Equivalent to
- <seealso marker="#send-3"><c>ct_netconfc:send(Client, SimpleXml,
- infinity)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>send(Client, SimpleXml, Timeout) -&gt; Result</name>
+ <name name="send" arity="2"/>
+ <name name="send" arity="3"/>
<fsummary>Sends an XML document to the server.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>SimpleXml = simple_xml()</v>
- <v>Timeout = timeout()</v>
- <v>Result = simple_xml() | {error, error_reason()}</v>
- </type>
- <desc><marker id="send-3"/>
+ <desc>
<p>Sends an XML document to the server.</p>
<p>The specified XML document is sent "as is" to the server. This
@@ -975,25 +804,10 @@ SessionId, infinity)</c></seealso>.</p>
</func>
<func>
- <name>send_rpc(Client, SimpleXml) -&gt; Result</name>
- <fsummary>Equivalent to send_rpc(Client, SimpleXml, infinity).</fsummary>
- <desc><marker id="send_rpc-2"/>
- <p>Equivalent to
- <seealso marker="#send_rpc-3"><c>ct_netconfc:send_rpc(Client,
- SimpleXml, infinity)</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>send_rpc(Client, SimpleXml, Timeout) -&gt; Result</name>
+ <name name="send_rpc" arity="2"/>
+ <name name="send_rpc" arity="3"/>
<fsummary>Sends a NETCONF rpc request to the server.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>SimpleXml = simple_xml()</v>
- <v>Timeout = timeout()</v>
- <v>Result = [simple_xml()] | {error, error_reason()}</v>
- </type>
- <desc><marker id="send_rpc-3"/>
+ <desc>
<p>Sends a NETCONF <c>rpc</c> request to the server.</p>
<p>The specified XML document is wrapped in a valid NETCONF <c>rpc</c>
@@ -1006,30 +820,42 @@ SessionId, infinity)</c></seealso>.</p>
</func>
<func>
- <name>unlock(Client, Target) -&gt; Result</name>
- <fsummary>Equivalent to unlock(Client, Target, infinity).</fsummary>
- <desc><marker id="unlock-2"/>
- <p>Equivalent to
- <seealso marker="#unlock-3"><c>ct_netconfc:unlock(Client, Target,
- infinity)</c></seealso>.</p>
+ <name name="session" arity="1"/>
+ <name name="session" arity="2" clause_i="1"/>
+ <name name="session" arity="2" clause_i="2"/>
+ <name name="session" arity="3"/>
+ <fsummary>Opens a NETCONF session as a channel on the given SSH
+ connection, and exchanges hello messages with the
+ server.</fsummary>
+ <type name="session_options"/>
+ <type name="session_option"/>
+ <desc>
+ <p>Opens a NETCONF session as a channel on the given SSH
+ connection, and exchanges hello messages with the server.</p>
+
+ <p>The opaque <seealso marker="#type-handle"><c>handle()</c></seealso>
+ reference returned from this
+ function can be used as client identifier when calling any
+ other function in this module. However, if <c><anno>KeyOrName</anno></c>
+ is used and it is a <c>target_name()</c>, that is, if the
+ server is named through a call
+ to <seealso marker="ct#require-2"><c>ct:require/2</c></seealso>
+ or a <c>require</c> statement in the test suite, then this
+ name can be used instead of
+ <seealso marker="#type-handle"><c>handle()</c></seealso>.</p>
+
</desc>
</func>
<func>
- <name>unlock(Client, Target, Timeout) -&gt; Result</name>
+ <name name="unlock" arity="2"/>
+ <name name="unlock" arity="3"/>
<fsummary>Unlocks the configuration target.</fsummary>
- <type>
- <v>Client = client()</v>
- <v>Target = netconf_db()</v>
- <v>Timeout = timeout()</v>
- <v>Result = ok | {error, error_reason()}</v>
- </type>
- <desc><marker id="unlock-3"/>
+ <desc>
<p>Unlocks the configuration target.</p>
<p>If the client earlier has acquired a lock through
- <seealso marker="#lock-2"><c>ct_netconfc:lock/2</c></seealso> or
- <seealso marker="#lock-3"><c>ct_netconfc:lock/3</c></seealso>, this
+ <seealso marker="#lock-2"><c>lock/2,3</c></seealso>, this
operation releases the associated lock. To access another target
than <c>running</c>, the server must support <c>:candidate</c>
and/or <c>:startup</c>.</p>
diff --git a/lib/common_test/doc/src/ct_run.xml b/lib/common_test/doc/src/ct_run.xml
index 9e6229f1dd..5b962ed5c7 100644
--- a/lib/common_test/doc/src/ct_run.xml
+++ b/lib/common_test/doc/src/ct_run.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>2007</year><year>2016</year>
+ <year>2007</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -125,6 +125,7 @@
[-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]
[-basic_html]
[-no_esc_chars]
+ [-keep_logs all | NLogs]
[-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and ..
CTHModuleN CTHOptsN]
[-exit_status ignore_config]
@@ -164,6 +165,7 @@
[-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]
[-basic_html]
[-no_esc_chars]
+ [-keep_logs all | NLogs]
[-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and ..
CTHModuleN CTHOptsN]
[-exit_status ignore_config]</pre>
@@ -189,13 +191,15 @@
[-scale_timetraps]
[-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]
[-basic_html]
- [-no_esc_chars]</pre>
+ [-no_esc_chars]
+ [-keep_logs all | NLogs]</pre>
</section>
<section>
<title>Refresh HTML Index Files</title>
<pre>
- ct_run -refresh_logs [-logdir LogDir] [-basic_html]</pre>
+ ct_run -refresh_logs [-logdir LogDir] [-basic_html]
+ [-keep_logs all | NLogs]</pre>
</section>
<section>
diff --git a/lib/common_test/doc/src/ct_ssh.xml b/lib/common_test/doc/src/ct_ssh.xml
index d00737aa5a..0c7efed154 100644
--- a/lib/common_test/doc/src/ct_ssh.xml
+++ b/lib/common_test/doc/src/ct_ssh.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2010</year><year>2016</year>
+ <year>2010</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -64,7 +64,7 @@
<p><c>ConnType = ssh | sftp</c>.</p>
<p>For other types, see
- <seealso marker="ssh:ssh"><c>ssh:ssh(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh"><c>ssh(3)</c></seealso>.</p>
<p>All time-out parameters in <c>ct_ssh</c> functions are values in
milliseconds.</p>
@@ -88,7 +88,7 @@
<tag><c>ssh_sftp_return() = term()</c></tag>
<item><marker id="type-ssh_sftp_return"/>
<p>Return value from an
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp</c></seealso>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp</c></seealso>
function.</p></item>
</taglist>
</section>
@@ -104,7 +104,7 @@
</type>
<desc><marker id="apread-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -118,7 +118,7 @@
</type>
<desc><marker id="apread-5"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -132,7 +132,7 @@
</type>
<desc><marker id="apwrite-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -146,7 +146,7 @@
</type>
<desc><marker id="apwrite-5"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -160,7 +160,7 @@
</type>
<desc><marker id="aread-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -174,7 +174,7 @@
</type>
<desc><marker id="aread-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -188,7 +188,7 @@
</type>
<desc><marker id="awrite-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -202,7 +202,7 @@
</type>
<desc><marker id="awrite-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -216,7 +216,7 @@
</type>
<desc><marker id="close-2"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -230,7 +230,7 @@
</type>
<desc><marker id="close-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -310,7 +310,7 @@
</type>
<desc><marker id="del_dir-2"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -324,7 +324,7 @@
</type>
<desc><marker id="del_dir-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -338,7 +338,7 @@
</type>
<desc><marker id="delete-2"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -352,7 +352,7 @@
</type>
<desc><marker id="delete-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -423,7 +423,7 @@
</type>
<desc><marker id="get_file_info-2"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -437,7 +437,7 @@
</type>
<desc><marker id="get_file_info-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -451,7 +451,7 @@
</type>
<desc><marker id="list_dir-2"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -465,7 +465,7 @@
</type>
<desc><marker id="list_dir-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -479,7 +479,7 @@
</type>
<desc><marker id="make_dir-2"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -493,7 +493,7 @@
</type>
<desc><marker id="make_dir-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -507,7 +507,7 @@
</type>
<desc><marker id="make_symlink-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -521,7 +521,7 @@
</type>
<desc><marker id="make_symlink-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -535,7 +535,7 @@
</type>
<desc><marker id="open-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -549,7 +549,7 @@
</type>
<desc><marker id="open-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -563,7 +563,7 @@
</type>
<desc><marker id="opendir-2"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -577,7 +577,7 @@
</type>
<desc><marker id="opendir-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -591,7 +591,7 @@
</type>
<desc><marker id="position-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -605,7 +605,7 @@
</type>
<desc><marker id="position-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -619,7 +619,7 @@
</type>
<desc><marker id="pread-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -633,7 +633,7 @@
</type>
<desc><marker id="pread-5"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -647,7 +647,7 @@
</type>
<desc><marker id="pwrite-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -661,7 +661,7 @@
</type>
<desc><marker id="pwrite-5"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -675,7 +675,7 @@
</type>
<desc><marker id="read-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -689,7 +689,7 @@
</type>
<desc><marker id="read-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -703,7 +703,7 @@
</type>
<desc><marker id="read_file-2"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -717,7 +717,7 @@
</type>
<desc><marker id="read_file-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -731,7 +731,7 @@
</type>
<desc><marker id="read_file_info-2"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -745,7 +745,7 @@
</type>
<desc><marker id="read_file_info-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -759,7 +759,7 @@
</type>
<desc><marker id="read_link-2"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -773,7 +773,7 @@
</type>
<desc><marker id="read_link-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -787,7 +787,7 @@
</type>
<desc><marker id="read_link_info-2"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -801,7 +801,7 @@
</type>
<desc><marker id="read_link_info-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -853,7 +853,7 @@ ChannelId, End, DefaultTimeout)</c></seealso>.</p>
<p>If <c>End</c> is a fun, this fun is called with one argument, the
data value in a received <c>ssh_cm</c> message (see
- <seealso marker="ssh:ssh_connection"><c>ssh:ssh_connection(3)</c></seealso>.
+ <seealso marker="ssh:ssh_connection"><c>ssh_connection(3)</c></seealso>.
The fun is to return either <c>true</c> to end the receiving
operation (and have the so far collected data returned) or
<c>false</c> to wait for more data from the server. Even if a fun
@@ -872,7 +872,7 @@ ChannelId, End, DefaultTimeout)</c></seealso>.</p>
</type>
<desc><marker id="rename-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -886,7 +886,7 @@ ChannelId, End, DefaultTimeout)</c></seealso>.</p>
</type>
<desc><marker id="rename-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -1034,6 +1034,33 @@ ChannelId, 0, Data, End, Timeout)</c></seealso>.</p>
</func>
<func>
+ <name>shell(SSH, ChannelId) -&gt; ok | {error, Reason}</name>
+ <fsummary>Equivalent to shell(SSH, ChannelId, DefaultTimeout).</fsummary>
+ <desc><marker id="shell-2"/>
+ <p>Equivalent to
+ <seealso marker="#shell-3"><c>ct_ssh:shell(SSH, ChannelId,
+ DefaultTimeout)</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>shell(SSH, ChannelId, Timeout) -&gt; ok | {error, Reason}</name>
+ <fsummary>Requests that the user default shell is executed at the
+ server end.</fsummary>
+ <type>
+ <v>SSH = connection()</v>
+ <v>ChannelId = integer()</v>
+ <v>Timeout = integer()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="shell-3"/>
+ <p>Requests that the user default shell (typically defined in
+ <c>/etc/passwd</c> in Unix systems) is executed at the
+ server end.</p>
+ </desc>
+ </func>
+
+ <func>
<name>subsystem(SSH, ChannelId, Subsystem) -&gt; Status | {error, Reason}</name>
<fsummary>Equivalent to subsystem(SSH, ChannelId, Subsystem,
DefaultTimeout).</fsummary>
@@ -1070,7 +1097,7 @@ ChannelId, 0, Data, End, Timeout)</c></seealso>.</p>
</type>
<desc><marker id="write-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -1084,7 +1111,7 @@ ChannelId, 0, Data, End, Timeout)</c></seealso>.</p>
</type>
<desc><marker id="write-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -1098,7 +1125,7 @@ ChannelId, 0, Data, End, Timeout)</c></seealso>.</p>
</type>
<desc><marker id="write_file-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -1112,7 +1139,7 @@ ChannelId, 0, Data, End, Timeout)</c></seealso>.</p>
</type>
<desc><marker id="write_file-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -1126,7 +1153,7 @@ ChannelId, 0, Data, End, Timeout)</c></seealso>.</p>
</type>
<desc><marker id="write_file_info-3"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
@@ -1140,7 +1167,7 @@ ChannelId, 0, Data, End, Timeout)</c></seealso>.</p>
</type>
<desc><marker id="write_file_info-4"/>
<p>For information and other types, see
- <seealso marker="ssh:ssh_sftp"><c>ssh:ssh_sftp(3)</c></seealso>.</p>
+ <seealso marker="ssh:ssh_sftp"><c>ssh_sftp(3)</c></seealso>.</p>
</desc>
</func>
</funcs>
diff --git a/lib/common_test/doc/src/ct_telnet.xml b/lib/common_test/doc/src/ct_telnet.xml
index e2a45e894b..8e85cccc99 100644
--- a/lib/common_test/doc/src/ct_telnet.xml
+++ b/lib/common_test/doc/src/ct_telnet.xml
@@ -198,7 +198,7 @@
<item><marker id="type-prompt_regexp"/>
<p>Regular expression matching all possible prompts for a specific
target type. <c>regexp</c> must not have any groups, that is, when
- matching, <c>re:run/3</c> (in <c>STDLIB</c>) must return a list with
+ matching, <c>re:run/3</c> (in STDLIB) must return a list with
one single element.</p></item>
</taglist>
</section>
@@ -337,7 +337,7 @@
<c>FullMatch</c> is the string matched by the whole regular
expression, and <c>SubMatchN</c> is the string that matched
subexpression number <c>N</c>. Subexpressions are denoted with
- <c>(' ')</c> in the regular expression.</p>
+ <c>'(' ')'</c> in the regular expression.</p>
<p>If a <c>Tag</c> is speciifed, the returned <c>Match</c> also
includes the matched <c>Tag</c>. Otherwise, only <c>RxMatch</c>
diff --git a/lib/common_test/doc/src/ct_testspec.xml b/lib/common_test/doc/src/ct_testspec.xml
new file mode 100644
index 0000000000..36893f66cf
--- /dev/null
+++ b/lib/common_test/doc/src/ct_testspec.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2016</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ </legalnotice>
+
+ <title>ct_testspec</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>ct_testspec.xml</file>
+ </header>
+ <module>ct_testspec</module>
+ <modulesummary>Parsing of test specifications for Common Test.
+ </modulesummary>
+
+<description>
+
+ <p>Parsing of test specifications for <c>Common Test</c>.</p>
+
+ <p>This module exports help functions for parsing of test specifications.</p>
+
+</description>
+
+ <funcs>
+ <func>
+ <name>get_tests(SpecsIn) -&gt; {ok, [{Specs,Tests}]} | {error, Reason}</name>
+ <fsummary>Parse the given test specification files and return the tests to run and skip.</fsummary>
+ <type>
+ <v>SpecsIn = [string()] | [[string()]]</v>
+ <v>Specs = [string()]</v>
+ <v>Test = [{Node,Run,Skip}]</v>
+ <v>Node = atom()</v>
+ <v>Run = {Dir,Suites,Cases}</v>
+ <v>Skip = {Dir,Suites,Comment} | {Dir,Suites,Cases,Comment}</v>
+ <v>Dir = string()</v>
+ <v>Suites = atom | [atom()] | all</v>
+ <v>Cases = atom | [atom()] | all</v>
+ <v>Comment = string()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc><marker id="add_nodes-1"/>
+ <p>Parse the given test specification files and return the
+ tests to run and skip.</p>
+
+ <p>If <c>SpecsIn=[Spec1,Spec2,...]</c>, separate tests will be
+ created per specification. If
+ <c>SpecsIn=[[Spec1,Spec2,...]]</c>, all specifications will be
+ merge into one test.</p>
+
+ <p>For each test, a <c>{Specs,Tests}</c> element is returned,
+ where <c>Specs</c> is a list of all included test
+ specifications, and <c>Tests</c> specifies actual tests to
+ run/skip per node.</p>
+ </desc>
+ </func>
+
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/event_handler_chapter.xml b/lib/common_test/doc/src/event_handler_chapter.xml
index 2978226a19..bd9ed21cb4 100644
--- a/lib/common_test/doc/src/event_handler_chapter.xml
+++ b/lib/common_test/doc/src/event_handler_chapter.xml
@@ -50,7 +50,7 @@
pass the information on. The event handlers are Erlang modules
implemented by the <c>Common Test</c> user according to the <c>gen_event</c>
behavior (for details, see module
- <seealso marker="stdlib:gen_event"><c>stdlib:gen_event</c></seealso> and
+ <seealso marker="stdlib:gen_event"><c>gen_event</c></seealso> and
section
<seealso marker="doc/design_principles:events"><c>gen_event Behaviour</c></seealso>
in OTP Design Principles in the System Documentation).
@@ -69,8 +69,8 @@
manager, either by telling <c>Common Test</c> to install them before the test
run (described later), or by adding the handlers dynamically during the test
run using
- <seealso marker="stdlib:gen_event#add_handler-3"><c>stdlib:gen_event:add_handler/3</c></seealso> or
- <seealso marker="stdlib:gen_event#add_sup_handler-3"><c>stdlib:gen_event:add_sup_handler/3</c></seealso>.
+ <seealso marker="stdlib:gen_event#add_handler-3"><c>gen_event:add_handler/3</c></seealso> or
+ <seealso marker="stdlib:gen_event#add_sup_handler-3"><c>gen_event:add_sup_handler/3</c></seealso>.
In the latter scenario, the reference of the <c>Common Test</c> event manager is
required. To get it, call
<seealso marker="ct#get_event_mgr_ref-0"><c>ct:get_event_mgr_ref/0</c></seealso>
diff --git a/lib/common_test/doc/src/introduction.xml b/lib/common_test/doc/src/introduction.xml
index 40724f24e9..df12bea6dd 100644
--- a/lib/common_test/doc/src/introduction.xml
+++ b/lib/common_test/doc/src/introduction.xml
@@ -45,7 +45,7 @@
</list>
<p><c>Common Test</c> also integrates use of the OTP
<seealso marker="tools:cover">cover</seealso> tool in application
- <c>Tools</c> for code coverage analysis of Erlang/OTP programs.</p>
+ Tools for code coverage analysis of Erlang/OTP programs.</p>
<p><c>Common Test</c> executes test suite programs automatically,
without operator interaction. Test progress and results are
diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml
index 32ae699c7a..28b2d44168 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -33,6 +33,292 @@
<file>notes.xml</file>
</header>
+<section><title>Common_Test 1.15</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Errors in the documentation for user HTML stylesheets
+ have been corrected.</p>
+ <p>
+ Own Id: OTP-14332 Aux Id: seq13299 </p>
+ </item>
+ <item>
+ <p>Internal code change: Calls to <c>catch</c> followed
+ by a call to <c>erlang:get_stacktrace/0</c> has been
+ rewritten to use <c>try</c> instead of <c>catch</c> to
+ make the code future-proof.</p>
+ <p>
+ Own Id: OTP-14400</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The <c>ct_slave</c> modules now handle nodenames in
+ the same way as nodenames passed to <c>-sname</c>. That
+ means <c>ct_slave:start('[email protected]').</c> will now
+ work.</p>
+ <p>
+ Own Id: OTP-13806</p>
+ </item>
+ <item>
+ <p>
+ Added the new option, <c>keep_logs</c>. If setting the
+ value for this option to an integer, N, common_test will
+ remove all ct_run.* directories in the current log
+ directory, except the N newest.</p>
+ <p>
+ Own Id: OTP-14179</p>
+ </item>
+ <item>
+ <p>
+ The existing <c>ct_netconfc:open/1,2</c> opens an SSH
+ connection with one SSH channel realizing one Netconf
+ session. To allow testing of multiple sessions over the
+ same SSH connection, the following functions are added to
+ <c>ct_netconfc</c>:</p>
+ <p>
+ * <c>connect/1,2</c> - establish an SSH connection *
+ <c>disconnect/1</c> - close the given SSH connection *
+ <c>session/1,2,3</c> - open an ssh channel on the given
+ connection and send 'hello' to start a Netconf session</p>
+ <p>
+ Own Id: OTP-14284</p>
+ </item>
+ <item>
+ <p> Miscellaneous updates due to atoms containing
+ arbitrary Unicode characters. </p>
+ <p>
+ Own Id: OTP-14285</p>
+ </item>
+ <item>
+ <p>
+ The function ct_ssh:shell/2,3 is added.</p>
+ <p>
+ Own Id: OTP-14415 Aux Id: seq13315 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Common_Test 1.14</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The following corrections and improvements are done in
+ the common_test hook handling:</p> <list> <item> <p>An
+ extra argument, <c>Suite</c>, is added as the first
+ argument to each of the following hook callback
+ functions:</p> <list>
+ <item><c>pre_init_per_group</c></item>
+ <item><c>post_init_per_group</c></item>
+ <item><c>pre_end_per_group</c></item>
+ <item><c>post_end_per_group</c></item>
+ <item><c>pre_init_per_testcase</c></item>
+ <item><c>post_init_per_testcase</c></item>
+ <item><c>pre_end_per_testcase</c></item>
+ <item><c>post_end_per_testcase</c></item>
+ <item><c>on_tc_fail</c></item>
+ <item><c>on_tc_skip</c></item> </list> <p>For backwards
+ compatibility, if the new function is not exported from a
+ hook callback module, <c>common_test</c> will fall back
+ to the old interface and call the function without the
+ <c>Suite</c> argument.</p> </item> <item> <p>If either
+ <c>init_per_suite</c> or <c>end_per_suite</c> exists, but
+ not the other, then the non-existing function will be
+ reported as failed with reason <c>undef</c> in the test
+ log. The same goes for <c>init/end_per_group</c>. This
+ has always been a requirement according to the user's
+ guide, but now <c>common_test</c> is more explicit in the
+ report.</p> </item> <item> <p>If <c>init_per_suite</c>
+ was exported from a test suite, but not
+ <c>end_per_suite</c>, then <c>pre/post_end_per_suite</c>
+ was called with <c>Suite=ct_framework</c> instead of the
+ correct suite name. This is now corrected.</p> </item>
+ <item> <p>If <c>end_per_group</c> was exported from a
+ suite, but not <c>init_per_group</c>, then
+ <c>end_per_group</c> was never called. This is now
+ corrected.</p> </item> <item> <p>Tests that were skipped
+ before calling <c>pre_init_per_*</c> got faulty calls to
+ the corresponding <c>post_init_per_*</c>. E.g. if a test
+ was skipped because <c>suite/0</c> failed, then
+ <c>post_init_per_suite</c> would be called even though
+ <c>pre_init_per_suite</c> and <c>init_per_suite</c> were
+ not called. This is now corrected so a <c>post_*</c>
+ callback will never be called unless the corresponding
+ <c>pre_*</c> callback has been called first.</p> </item>
+ <item> <p>Tests that were skipped before or in
+ <c>init_per_testcase</c> got faulty calls to
+ <c>pre_end_per_testcase</c> and
+ <c>post_end_per_testcase</c>. This is now corrected so
+ <c>pre/post_end_per_testcase</c> are not called when
+ <c>end_per_testcase</c> is not called.</p> </item> <item>
+ <p>If an exit signal causes the test case process to die
+ while running <c>init_per_testcase</c>, the case was
+ earlier reported as failed with reason <c>{skip,...}</c>.
+ This is now corrected so the case will be marked as
+ skipped.</p> </item> <item> <p>If an exist signal causes
+ the test case process to die while running
+ <c>end_per_testcase</c>, the case was earlier marked as
+ failed. This is now corrected so the status of the test
+ case is not changed - there is only a warning added to
+ the comment field.</p> </item> <item> <p>If a test case
+ was skipped because of option
+ <c>{force_stop,skip_rest}</c> or because of a failed
+ sequence, then no <c>tc_start</c> event would be sent,
+ only <c>tc_done</c>. This is now corrected so both events
+ are sent.</p> </item> <item> <p>When skipping or failing
+ in a configuration function, the configuration function
+ itself would get <c>{auto_skipped,Reason}</c>,
+ <c>{skipped,Reason}</c> or <c>{failed,Reason}</c> in the
+ hook callbacks <c>on_tc_skip</c> or <c>on_tc_fail</c>.
+ The other test cases that were skipped as a result of
+ this would only get <c>Reason</c> in <c>on_tc_skip</c>.
+ This is now corrected so even the configuration function
+ that caused the skip/fail will only get <c>Reason</c> in
+ the hook callback.</p> </item> </list>
+ <p>
+ Own Id: OTP-10599 Aux Id: kunagi-344 [255] </p>
+ </item>
+ <item>
+ <p>
+ When a test case was skipped by a <c>skip_cases</c>
+ statement in a test spec, then <c>cth_surefire</c> would
+ erroneously mark the previous test case as skipped in the
+ xml report. The actually skipped test case would not be
+ present in the xml report at all. This is now corrected.</p>
+ <p>
+ Own Id: OTP-14129 Aux Id: seq13244 </p>
+ </item>
+ <item>
+ <p>The <c>multiply_timetraps</c> and
+ <c>scale_timetraps</c> options did not work with test
+ specifications, which has been corrected.</p>
+ <p>
+ Own Id: OTP-14210</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ ct_testspec:get_tests/1 is added. This is used by rebar3
+ to get all directories that must be compiled when running
+ tests from testspec - instead of implementing testspec
+ parsing in rebar3.</p>
+ <p>
+ Own Id: OTP-14132</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Common_Test 1.13</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Some types of printouts to screen during test runs
+ (including <c>ct:print/1,2,3,4</c>) used the local
+ <c>user</c> process as IO device and these printouts
+ would not be visible when e.g. running tests via a shell
+ on a remote node. A default Common Test group leader
+ process has been introduced to solve the problem. This
+ process routes printouts to the group leader of the
+ starting process, if available, otherwise to <c>user</c>.</p>
+ <p>
+ Own Id: OTP-13973 Aux Id: ERL-279 </p>
+ </item>
+ <item>
+ <p>
+ Some Common Test processes, that act as I/O group leaders
+ for test cases, would not terminate as expected at the
+ end of test runs. This error has been corrected.</p>
+ <p>
+ Own Id: OTP-14026 Aux Id: ERL-287 </p>
+ </item>
+ <item>
+ <p>
+ The logging verbosity feature was incorrectly documented.
+ The default verbosity levels for test runs is e.g. not 50
+ (<c>?STD_VERBOSITY</c>), but 100 (<c>?MAX_VERBOSITY</c>).
+ Also, some of the examples had errors and flaws. The
+ corresponding chapter (5.18) in the User's Guide has been
+ updated.</p>
+ <p>
+ Own Id: OTP-14044 Aux Id: seq13223 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ A feature to let the user specify headings to log
+ printouts has been added. The heading is specified as
+ <c>{heading,string()}</c> in the <c>Opts</c> list
+ argument to <c>ct:pal/3,4,5</c>, <c>ct:print/3,4,5</c>,
+ or <c>ct:log/3,4,5</c>. If the heading option is omitted,
+ the category name, or <c>"User"</c>, is used as the
+ heading instead.</p>
+ <p>
+ Own Id: OTP-14043 Aux Id: seq13226 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Common_Test 1.12.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ If the telnet server would pause during transmission of a
+ line of text before terminating the line, the
+ <c>ct_telnet:expect/3</c> function would print the line
+ twice in the test case HTML log. This problem has been
+ fixed.</p>
+ <p>
+ Own Id: OTP-13730 Aux Id: seq13135 </p>
+ </item>
+ <item>
+ <p>
+ The functions <c>ct:set_verbosity/2</c> and
+ <c>ct:get_verbosity/1</c> have been added in order to
+ make it possible for test cases, CT Hooks, or test
+ framework functions, to modify and read verbosity levels
+ for logging.</p>
+ <p>
+ Own Id: OTP-13841</p>
+ </item>
+ <item>
+ <p><c>make</c> (tools) and <c>ct_make</c> (common_test)
+ would crash if an Erlang source file contained a
+ <c>-warning()</c> directive.</p>
+ <p>
+ Own Id: OTP-13855</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Common_Test 1.12.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/common_test/doc/src/ref_man.xml b/lib/common_test/doc/src/ref_man.xml
index d1567e2d3c..1ac20db5c2 100644
--- a/lib/common_test/doc/src/ref_man.xml
+++ b/lib/common_test/doc/src/ref_man.xml
@@ -47,6 +47,7 @@
<xi:include href="ct_slave.xml"/>
<xi:include href="ct_hooks.xml"/>
<xi:include href="ct_property_test.xml"/>
+ <xi:include href="ct_testspec.xml"/>
</application>
diff --git a/lib/common_test/doc/src/run_test_chapter.xml b/lib/common_test/doc/src/run_test_chapter.xml
index 43e36adfb6..56f6f7bcc4 100644
--- a/lib/common_test/doc/src/run_test_chapter.xml
+++ b/lib/common_test/doc/src/run_test_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2016</year>
+ <year>2003</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -274,7 +274,7 @@
<note><p>Directories passed to <c>Common Test</c> can have either relative or absolute paths.</p></note>
- <note><p>Any start flags to the Erlang runtime system (application <c>ERTS</c>) can also be passed as
+ <note><p>Any start flags to the Erlang runtime system (application ERTS) can also be passed as
parameters to <c>ct_run</c>. It is, for example, useful to be able to
pass directories to be added to the Erlang code server search path
with flag <c>-pa</c> or <c>-pz</c>. If you have common help- or library
@@ -286,7 +286,7 @@
<p>The absolute path of directory <c>chat_server/ebin</c>
is here passed to the code server. This is essential because relative
paths are stored by the code server as relative, and <c>Common Test</c> changes
- the current working directory of <c>ERTS</c> during the test run.</p>
+ the current working directory of ERTS during the test run.</p>
</note>
<p>The <c>ct_run</c> program sets the exit status before shutting down. The following values
@@ -1258,7 +1258,7 @@
<p>The minor log files contain full details of every single test
case, each in a separate file. This way, it is
straightforward to compare the latest results to that of previous
- test runs, even if the set of test cases changes. If application <c>SASL</c>
+ test runs, even if the set of test cases changes. If application SASL
is running, its logs are also printed to the current minor log file by the
<seealso marker="common_test:ct_hooks_chapter#builtin_cths">
cth_log_redirect built-in hook</seealso>.
@@ -1322,8 +1322,8 @@
<title>The Unexpected I/O Log</title>
<p>The test suites overview page includes a link to the Unexpected I/O Log.
In this log, <c>Common Test</c> saves printouts made with
- <seealso marker="ct#log-2"><c>ct:log/2</c></seealso> and
- <seealso marker="ct#pal-2"><c>ct:pal/2</c></seealso>, as well as captured system
+ <seealso marker="ct#log-2"><c>ct:log/1,2,3,4,5</c></seealso> and
+ <seealso marker="ct#pal-2"><c>ct:pal/1,2,3,4,5</c></seealso>, as well as captured system
error- and progress reports, which cannot be associated with particular test cases and
therefore cannot be written to individual test case log files. This occurs,
for example, if a log printout is made from an external process (not a test
@@ -1338,7 +1338,7 @@
<title>The Pre- and Post Test I/O Log</title>
<p>The <c>Common Test</c> Framework Log page includes links to the
Pre- and Post Test I/O Log. In this log, <c>Common Test</c> saves printouts made
- with <c>ct:log/2</c> and <c>ct:pal/2</c>, as well as captured system error-
+ with <c>ct:log/1,2,3,4,5</c> and <c>ct:pal/1,2,3,4,5</c>, as well as captured system error-
and progress reports, which take place before, and after, the test run.
Examples of this are printouts from a CT hook init- or terminate function, or
progress reports generated when an OTP application is started from a CT hook
@@ -1349,10 +1349,22 @@
applications, see section
<seealso marker="ct_hooks_chapter#synchronizing">Synchronizing</seealso>
in section Common Test Hooks.</p>
- <note><p>Logging to file with <c>ct:log/2</c> or <c>ct:pal/2</c>
- only works when <c>Common Test</c> is running. Printouts with <c>ct:pal/2</c>
+ <note><p>Logging to file with <c>ct:log/1,2,3,4,5</c> or <c>ct:pal/1,2,3,4,5</c>
+ only works when <c>Common Test</c> is running. Printouts with <c>ct:pal/1,2,3,4,5</c>
are however always displayed on screen.</p></note>
</section>
+
+ <section>
+ <marker id="delete_old_logs"></marker>
+ <title>Delete Old Logs</title>
+ <p><c>Common Test</c> can automatically delete old log. This
+ is specified with the <c>keep_logs</c> option. The default
+ value for this option is <c>all</c>, which means that no
+ logs are deleted. If the value is set to an
+ integer, <c>N</c>, <c>Common Test</c> deletes
+ all <c>ct_run.&lt;timestamp&gt;</c> directories, except
+ the <c>N</c> newest.</p>
+ </section>
</section>
<section>
@@ -1371,24 +1383,38 @@
<p><c>Common Test</c> includes an <em>optional</em> feature to allow
user HTML style sheets for customizing printouts. The
functions in <c>ct</c> that print to a test case HTML log
- file (<c>log/3</c> and <c>pal/3</c>) accept <c>Category</c>
+ file (<c>log/3,4,5</c> and <c>pal/3,4,5</c>) accept <c>Category</c>
as first argument. With this argument a category can be specified
- that can be mapped to a selector in a CSS
- definition. This is useful, especially for coloring text
+ that can be mapped to a named <c>div</c> selector in a CSS rule-set.
+ This is useful, especially for coloring text
differently depending on the type of (or reason for) the
- printout. Say you want one color for test system
+ printout. Say you want one particular background color for test system
configuration information, a different one for test system
state information, and finally one for errors detected by the
test case functions. The corresponding style sheet can
look as follows:</p>
<pre>
- div.sys_config { background:blue; color:white }
- div.sys_state { background:yellow; color:black }
- div.error { background:red; color:white }</pre>
+ div.sys_config { background:blue }
+ div.sys_state { background:yellow }
+ div.error { background:red }</pre>
+
+ <p>Common Test prints the text from <c>ct:log/3,4,5</c> or
+ <c>ct:pal/3,4,5</c> inside a <c>pre</c> element
+ nested under the named <c>div</c> element. Since the <c>pre</c> selector
+ has a predefined CSS rule (in file <c>ct_default.css</c>) for the attributes
+ <c>color</c>, <c>font-family</c> and <c>font-size</c>, if a user wants to
+ change any of the predefined attribute settings, a new rule for <c>pre</c>
+ must be added to the user stylesheet. Example:</p>
+
+ <pre>
+div.error pre { color:white }</pre>
+
+ <p>Here, white text is used instead of the default black for <c>div.error</c>
+ printouts (and no other attribute settings for <c>pre</c> are affected).</p>
<p>To install the CSS file (<c>Common Test</c> inlines the definition in the
- HTML code), the name can be provided when executing <c>ct_run</c>.</p>
+ HTML code), the file name can be provided when executing <c>ct_run</c>.</p>
<p><em>Example:</em></p>
<pre>
@@ -1436,8 +1462,8 @@
suite.</p>
<p>Argument <c>Category</c> in the previous example can have the
- value (atom) <c>sys_config</c> (white on blue), <c>sys_state</c>
- (black on yellow), or <c>error</c> (white on red).</p>
+ value (atom) <c>sys_config</c> (blue background), <c>sys_state</c>
+ (yellow background), or <c>error</c> (white text on red background).</p>
</section>
<section>
diff --git a/lib/common_test/doc/src/specs.xml b/lib/common_test/doc/src/specs.xml
new file mode 100644
index 0000000000..7e40e8351d
--- /dev/null
+++ b/lib/common_test/doc/src/specs.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<specs xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="../specs/specs_ct_netconfc.xml"/>
+ <xi:include href="../specs/specs_ct.xml"/>
+</specs>
diff --git a/lib/common_test/doc/src/write_test_chapter.xml b/lib/common_test/doc/src/write_test_chapter.xml
index 83daf771a6..82dc06834f 100644
--- a/lib/common_test/doc/src/write_test_chapter.xml
+++ b/lib/common_test/doc/src/write_test_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2016</year>
+ <year>2003</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -269,10 +269,10 @@
<p>As parameter <c>Config</c> is a list of key-value tuples, that is,
a data type called a property list, it can be handled by the
- <seealso marker="stdlib:proplists"><c>stdlib:proplists</c></seealso> module.
+ <seealso marker="stdlib:proplists"><c>proplists</c></seealso> module.
A value can, for example, be searched for and returned with function
<seealso marker="stdlib:proplists#get_value-2"><c>proplists:get_value/2</c></seealso>.
- Also, or alternatively, the general <seealso marker="stdlib:lists"><c>stdlib:lists</c></seealso>
+ Also, or alternatively, the general <seealso marker="stdlib:lists"><c>lists</c></seealso>
module contains useful functions. Normally, the only operations
performed on <c>Config</c> is insert (adding a tuple to the head of the list)
and lookup. <c>Common Test</c> provides a simple macro named <c>?config</c>,
@@ -566,7 +566,7 @@
for the test cases in the group. After execution of the group is finished, function
<seealso marker="common_test#Module:end_per_group-2"><c>end_per_group(GroupName, Config)</c></seealso>
is called. This function is meant to be used for cleaning up after
- <c>init_per_group/2</c>.</p>
+ <c>init_per_group/2</c>. If the init function is defined, so must the end function be.</p>
<p>Whenever a group is executed, if <c>init_per_group</c> and
<c>end_per_group</c> do not exist in the suite, <c>Common Test</c> calls
@@ -652,7 +652,7 @@
<title>Parallel Test Cases and I/O</title>
<p>A parallel test case has a private I/O server as its group leader.
(For a description of the group leader concept, see
- <seealso marker="erts:index"><c>ERTS</c></seealso>).
+ <seealso marker="erts:index">ERTS</seealso>).
The central I/O server process, which handles the output from
regular test cases and configuration functions, does not respond to I/O messages
during execution of parallel groups. This is important to understand
@@ -986,15 +986,17 @@
<c>io:put_chars/1</c>, and so on.</p>
<p><c>Importance</c> is compared to a verbosity level set by the
- <c>verbosity</c> start flag/option. The verbosity level can be set per
- category or generally, or both. The default verbosity level,
- <c>?STD_VERBOSITY</c>, is 50, that is, all standard I/O gets printed.
- If a lower verbosity level is set, standard I/O printouts are ignored.
- <c>Common Test</c> performs the following test:</p>
+ <c>verbosity</c> start flag/option. The level can be set per
+ category or generally, or both. If <c>verbosity</c> is not set by the user,
+ a level of 100 (<c>?MAX_VERBOSITY</c> = all printouts visible) is used as
+ default value. <c>Common Test</c> performs the following test:</p>
<pre>
- Importance >= (100-VerbosityLevel)</pre>
- <p>This also means that verbosity level 0 effectively turns all logging off
- (except from printouts made by <c>Common Test</c> itself).</p>
+Importance >= (100-VerbosityLevel)</pre>
+ <p>The constant <c>?STD_VERBOSITY</c> has value 50 (see <c>ct.hrl</c>).
+ At this level, all standard I/O gets printed. If a lower verbosity level
+ is set, standard I/O printouts are ignored. Verbosity level 0 effectively
+ turns all logging off (except from printouts made by <c>Common Test</c>
+ itself).</p>
<p>The general verbosity level is not associated with any particular
category. This level sets the threshold for the standard I/O printouts,
@@ -1003,17 +1005,17 @@
<p><em>Examples:</em></p>
<p>Some printouts during test case execution:</p>
- <pre>
+ <pre>
io:format("1. Standard IO, importance = ~w~n", [?STD_IMPORTANCE]),
ct:log("2. Uncategorized, importance = ~w", [?STD_IMPORTANCE]),
- ct:log(info, "3. Categorized info, importance = ~w", [?STD_IMPORTANCE]]),
+ ct:log(info, "3. Categorized info, importance = ~w", [?STD_IMPORTANCE]),
ct:log(info, ?LOW_IMPORTANCE, "4. Categorized info, importance = ~w", [?LOW_IMPORTANCE]),
- ct:log(error, "5. Categorized error, importance = ~w", [?HI_IMPORTANCE]),
- ct:log(error, ?HI_IMPORTANCE, "6. Categorized error, importance = ~w", [?MAX_IMPORTANCE]),</pre>
+ ct:log(error, ?HI_IMPORTANCE, "5. Categorized error, importance = ~w", [?HI_IMPORTANCE]),
+ ct:log(error, ?MAX_IMPORTANCE, "6. Categorized error, importance = ~w", [?MAX_IMPORTANCE]),</pre>
- <p>If starting the test without specifying any verbosity levels as follows:</p>
+ <p>If starting the test with a general verbosity level of 50 (<c>?STD_VERBOSITY</c>):</p>
<pre>
- $ ct_run ...</pre>
+ $ ct_run -verbosity 50</pre>
<p>the following is printed:</p>
<pre>
1. Standard IO, importance = 50
@@ -1031,9 +1033,25 @@
4. Categorized info, importance = 25
6. Categorized error, importance = 99</pre>
+ <p>Note that the category argument is not required in order to only specify the
+ importance of a printout. Example:</p>
+ <pre>
+ct:pal(?LOW_IMPORTANCE, "Info report: ~p", [Info])</pre>
+ <p>Or perhaps in combination with constants:</p>
+ <pre>
+-define(INFO, ?LOW_IMPORTANCE).
+-define(ERROR, ?HI_IMPORTANCE).
+
+ct:log(?INFO, "Info report: ~p", [Info])
+ct:pal(?ERROR, "Error report: ~p", [Error])</pre>
+
+ <p>The functions <seealso marker="ct#set_verbosity-2"><c>ct:set_verbosity/2</c></seealso>
+ and <seealso marker="ct#get_verbosity-1"><c>ct:get_verbosity/1</c></seealso> may be used
+ to modify and read verbosity levels during test execution.</p>
+
<p>The arguments <c>Format</c> and <c>FormatArgs</c> in <c>ct:log/print/pal</c> are
- always passed on to the <c>stdlib</c> function <c>io:format/3</c> (For details,
- see the <seealso marker="stdlib:io"><c>stdlib:io</c></seealso> manual page).</p>
+ always passed on to the STDLIB function <c>io:format/3</c> (For details,
+ see the <seealso marker="stdlib:io"><c>io</c></seealso> manual page).</p>
<p><c>ct:pal/4</c> and <c>ct:log/5</c> add headers to strings being printed to the
log file. The strings are also wrapped in div tags with a CSS class
diff --git a/lib/common_test/src/Makefile b/lib/common_test/src/Makefile
index 0f9e044f9e..9d751996ad 100644
--- a/lib/common_test/src/Makefile
+++ b/lib/common_test/src/Makefile
@@ -80,6 +80,7 @@ MODULES= \
ct_groups \
ct_property_test \
ct_release_test \
+ ct_default_gl \
erl2html2 \
test_server_ctrl \
test_server_gl \
diff --git a/lib/common_test/src/common_test.app.src b/lib/common_test/src/common_test.app.src
index 77588af59b..430a4fa2fb 100644
--- a/lib/common_test/src/common_test.app.src
+++ b/lib/common_test/src/common_test.app.src
@@ -1,7 +1,7 @@
% This is an -*- erlang -*- file.
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
{vsn, "%VSN%"},
{modules, [ct_cover,
ct,
+ ct_default_gl,
ct_event,
ct_framework,
ct_ftp,
diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl
index d7ae81a5ce..19b0ee20fe 100644
--- a/lib/common_test/src/ct.erl
+++ b/lib/common_test/src/ct.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -66,8 +66,9 @@
reload_config/1,
escape_chars/1, escape_chars/2,
log/1, log/2, log/3, log/4, log/5,
- print/1, print/2, print/3, print/4,
- pal/1, pal/2, pal/3, pal/4,
+ print/1, print/2, print/3, print/4, print/5,
+ pal/1, pal/2, pal/3, pal/4, pal/5,
+ set_verbosity/2, get_verbosity/1,
capture_start/0, capture_stop/0, capture_get/0, capture_get/1,
fail/1, fail/2, comment/1, comment/2, make_priv_dir/0,
testcases/2, userdata/2, userdata/3,
@@ -88,6 +89,36 @@
-export([get_target_name/1]).
-export([parse_table/1, listenv/1]).
+%%----------------------------------------------------------------------
+%% Exported types
+%%----------------------------------------------------------------------
+%% For ct_gen_conn
+-export_type([config_key/0,
+ target_name/0,
+ key_or_name/0]).
+
+%% For cth_conn_log
+-export_type([conn_log_options/0,
+ conn_log_type/0,
+ conn_log_mod/0]).
+
+%%------------------------------------------------------------------
+%% Type declarations
+%% ------------------------------------------------------------------
+-type config_key() :: atom(). % Config key which exists in a config file
+-type target_name() :: atom().% Name associated to a config_key() though 'require'
+-type key_or_name() :: config_key() | target_name().
+
+%% Types used when logging connections with the 'cth_conn_log' hook
+-type conn_log_options() :: [conn_log_option()].
+-type conn_log_option() :: {log_type,conn_log_type()} |
+ {hosts,[key_or_name()]}.
+-type conn_log_type() :: raw | pretty | html | silent.
+-type conn_log_mod() :: ct_netconfc | ct_telnet.
+%%----------------------------------------------------------------------
+
+
+
%%%-----------------------------------------------------------------
%%% @spec install(Opts) -> ok | {error,Reason}
%%% Opts = [Opt]
@@ -591,7 +622,7 @@ log(X1,X2,X3,X4) ->
%%% Format = string()
%%% Args = list()
%%% Opts = [Opt]
-%%% Opt = esc_chars | no_css
+%%% Opt = {heading,string()} | esc_chars | no_css
%%%
%%% @doc Printout from a test case to the log file.
%%%
@@ -609,43 +640,61 @@ log(Category,Importance,Format,Args,Opts) ->
%%%-----------------------------------------------------------------
%%% @spec print(Format) -> ok
-%%% @equiv print(default,50,Format,[])
+%%% @equiv print(default,50,Format,[],[])
print(Format) ->
- print(default,?STD_IMPORTANCE,Format,[]).
+ print(default,?STD_IMPORTANCE,Format,[],[]).
%%%-----------------------------------------------------------------
%%% @spec print(X1,X2) -> ok
%%% X1 = Category | Importance | Format
%%% X2 = Format | Args
-%%% @equiv print(Category,Importance,Format,Args)
+%%% @equiv print(Category,Importance,Format,Args,[])
print(X1,X2) ->
{Category,Importance,Format,Args} =
if is_atom(X1) -> {X1,?STD_IMPORTANCE,X2,[]};
is_integer(X1) -> {default,X1,X2,[]};
is_list(X1) -> {default,?STD_IMPORTANCE,X1,X2}
end,
- print(Category,Importance,Format,Args).
+ print(Category,Importance,Format,Args,[]).
%%%-----------------------------------------------------------------
%%% @spec print(X1,X2,X3) -> ok
+%%% X1 = Category | Importance | Format
+%%% X2 = Importance | Format | Args
+%%% X3 = Format | Args | Opts
+%%% @equiv print(Category,Importance,Format,Args,Opts)
+print(X1,X2,X3) ->
+ {Category,Importance,Format,Args,Opts} =
+ if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[],[]};
+ is_atom(X1), is_list(X2) -> {X1,?STD_IMPORTANCE,X2,X3,[]};
+ is_integer(X1) -> {default,X1,X2,X3,[]};
+ is_list(X1), is_list(X2) -> {default,?STD_IMPORTANCE,X1,X2,X3}
+ end,
+ print(Category,Importance,Format,Args,Opts).
+
+%%%-----------------------------------------------------------------
+%%% @spec print(X1,X2,X3,X4) -> ok
%%% X1 = Category | Importance
%%% X2 = Importance | Format
%%% X3 = Format | Args
-%%% @equiv print(Category,Importance,Format,Args)
-print(X1,X2,X3) ->
- {Category,Importance,Format,Args} =
- if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[]};
- is_atom(X1), is_list(X2) -> {X1,?STD_IMPORTANCE,X2,X3};
- is_integer(X1) -> {default,X1,X2,X3}
+%%% X4 = Args | Opts
+%%% @equiv print(Category,Importance,Format,Args,Opts)
+print(X1,X2,X3,X4) ->
+ {Category,Importance,Format,Args,Opts} =
+ if is_atom(X1), is_integer(X2) -> {X1,X2,X3,X4,[]};
+ is_atom(X1), is_list(X2) -> {X1,?STD_IMPORTANCE,X2,X3,X4};
+ is_integer(X1) -> {default,X1,X2,X3,X4}
end,
- print(Category,Importance,Format,Args).
+ print(Category,Importance,Format,Args,Opts).
%%%-----------------------------------------------------------------
-%%% @spec print(Category,Importance,Format,Args) -> ok
+%%% @spec print(Category,Importance,Format,Args,Opts) -> ok
%%% Category = atom()
%%% Importance = integer()
%%% Format = string()
%%% Args = list()
+%%% Opts = [Opt]
+%%% Opt = {heading,string()}
%%%
%%% @doc Printout from a test case to the console.
%%%
@@ -657,13 +706,13 @@ print(X1,X2,X3) ->
%%% and default value for <c>Args</c> is <c>[]</c>.</p>
%%% <p>Please see the User's Guide for details on <c>Category</c>
%%% and <c>Importance</c>.</p>
-print(Category,Importance,Format,Args) ->
- ct_logs:tc_print(Category,Importance,Format,Args).
+print(Category,Importance,Format,Args,Opts) ->
+ ct_logs:tc_print(Category,Importance,Format,Args,Opts).
%%%-----------------------------------------------------------------
%%% @spec pal(Format) -> ok
-%%% @equiv pal(default,50,Format,[])
+%%% @equiv pal(default,50,Format,[],[])
pal(Format) ->
pal(default,?STD_IMPORTANCE,Format,[]).
@@ -671,35 +720,53 @@ pal(Format) ->
%%% @spec pal(X1,X2) -> ok
%%% X1 = Category | Importance | Format
%%% X2 = Format | Args
-%%% @equiv pal(Category,Importance,Format,Args)
+%%% @equiv pal(Category,Importance,Format,Args,[])
pal(X1,X2) ->
{Category,Importance,Format,Args} =
if is_atom(X1) -> {X1,?STD_IMPORTANCE,X2,[]};
is_integer(X1) -> {default,X1,X2,[]};
is_list(X1) -> {default,?STD_IMPORTANCE,X1,X2}
end,
- pal(Category,Importance,Format,Args).
+ pal(Category,Importance,Format,Args,[]).
%%%-----------------------------------------------------------------
%%% @spec pal(X1,X2,X3) -> ok
+%%% X1 = Category | Importance | Format
+%%% X2 = Importance | Format | Args
+%%% X3 = Format | Args | Opts
+%%% @equiv pal(Category,Importance,Format,Args,Opts)
+pal(X1,X2,X3) ->
+ {Category,Importance,Format,Args,Opts} =
+ if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[],[]};
+ is_atom(X1), is_list(X2) -> {X1,?STD_IMPORTANCE,X2,X3,[]};
+ is_integer(X1) -> {default,X1,X2,X3,[]};
+ is_list(X1), is_list(X2) -> {default,?STD_IMPORTANCE,X1,X2,X3}
+ end,
+ pal(Category,Importance,Format,Args,Opts).
+
+%%%-----------------------------------------------------------------
+%%% @spec pal(X1,X2,X3,X4) -> ok
%%% X1 = Category | Importance
%%% X2 = Importance | Format
%%% X3 = Format | Args
-%%% @equiv pal(Category,Importance,Format,Args)
-pal(X1,X2,X3) ->
- {Category,Importance,Format,Args} =
- if is_atom(X1), is_integer(X2) -> {X1,X2,X3,[]};
- is_atom(X1), is_list(X2) -> {X1,?STD_IMPORTANCE,X2,X3};
- is_integer(X1) -> {default,X1,X2,X3}
+%%% X4 = Args | Opts
+%%% @equiv pal(Category,Importance,Format,Args,Opts)
+pal(X1,X2,X3,X4) ->
+ {Category,Importance,Format,Args,Opts} =
+ if is_atom(X1), is_integer(X2) -> {X1,X2,X3,X4,[]};
+ is_atom(X1), is_list(X2) -> {X1,?STD_IMPORTANCE,X2,X3,X4};
+ is_integer(X1) -> {default,X1,X2,X3,X4}
end,
- pal(Category,Importance,Format,Args).
+ pal(Category,Importance,Format,Args,Opts).
%%%-----------------------------------------------------------------
-%%% @spec pal(Category,Importance,Format,Args) -> ok
+%%% @spec pal(Category,Importance,Format,Args,Opts) -> ok
%%% Category = atom()
%%% Importance = integer()
%%% Format = string()
%%% Args = list()
+%%% Opts = [Opt]
+%%% Opt = {heading,string()} | no_css
%%%
%%% @doc Print and log from a test case.
%%%
@@ -711,8 +778,26 @@ pal(X1,X2,X3) ->
%%% and default value for <c>Args</c> is <c>[]</c>.</p>
%%% <p>Please see the User's Guide for details on <c>Category</c>
%%% and <c>Importance</c>.</p>
-pal(Category,Importance,Format,Args) ->
- ct_logs:tc_pal(Category,Importance,Format,Args).
+pal(Category,Importance,Format,Args,Opts) ->
+ ct_logs:tc_pal(Category,Importance,Format,Args,Opts).
+
+%%%-----------------------------------------------------------------
+%%% @spec set_verbosity(Category, Level) -> ok
+%%% Category = default | atom()
+%%% Level = integer()
+%%%
+%%% @doc Set the verbosity level for a category
+set_verbosity(Category, Level) ->
+ ct_util:set_verbosity({Category,Level}).
+
+%%%-----------------------------------------------------------------
+%%% @spec get_verbosity(Category) -> Level | undefined
+%%% Category = default | atom()
+%%% Level = integer()
+%%%
+%%% @doc Read the verbosity level for a category
+get_verbosity(Category) ->
+ ct_util:get_verbosity(Category).
%%%-----------------------------------------------------------------
%%% @spec capture_start() -> ok
@@ -832,13 +917,13 @@ comment(Comment) when is_list(Comment) ->
Formatted =
case (catch io_lib:format("~ts",[Comment])) of
{'EXIT',_} -> % it's a list not a string
- io_lib:format("~p",[Comment]);
+ io_lib:format("~tp",[Comment]);
String ->
String
end,
send_html_comment(lists:flatten(Formatted));
comment(Comment) ->
- Formatted = io_lib:format("~p",[Comment]),
+ Formatted = io_lib:format("~tp",[Comment]),
send_html_comment(lists:flatten(Formatted)).
%%%-----------------------------------------------------------------
diff --git a/lib/common_test/src/ct_config.erl b/lib/common_test/src/ct_config.erl
index 99de311570..d48ae830bb 100644
--- a/lib/common_test/src/ct_config.erl
+++ b/lib/common_test/src/ct_config.erl
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -171,8 +171,8 @@ reload_config(KeyOrName) ->
process_default_configs(Opts) ->
lists:flatmap(fun({config,[_|_] = FileOrFiles}) ->
- case {io_lib:printable_list(FileOrFiles),
- io_lib:printable_list(hd(FileOrFiles))} of
+ case {io_lib:printable_unicode_list(FileOrFiles),
+ io_lib:printable_unicode_list(hd(FileOrFiles))} of
{false,true} ->
FileOrFiles;
{true,false} ->
diff --git a/lib/common_test/src/ct_conn_log_h.erl b/lib/common_test/src/ct_conn_log_h.erl
index 93e64c65fe..cf0a228e1b 100644
--- a/lib/common_test/src/ct_conn_log_h.erl
+++ b/lib/common_test/src/ct_conn_log_h.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -186,7 +186,7 @@ format_head(ConnMod,_,Time,Text) ->
io_lib:format("~n~ts",[Head]).
format_title(raw,#conn_log{client=Client}=Info) ->
- io_lib:format("Client ~w ~s ~ts",[Client,actionstr(Info),serverstr(Info)]);
+ io_lib:format("Client ~tw ~s ~ts",[Client,actionstr(Info),serverstr(Info)]);
format_title(_,Info) ->
Title = pad_char_end(?WIDTH,pretty_title(Info),$=),
io_lib:format("~n~ts", [Title]).
@@ -197,9 +197,9 @@ format_data(ConnMod,LogType,Data) ->
ConnMod:format_data(LogType,Data).
format_error(raw,Report) ->
- io_lib:format("~n~p~n",[Report]);
+ io_lib:format("~n~tp~n",[Report]);
format_error(pretty,Report) ->
- [io_lib:format("~n ~p: ~p",[K,V]) || {K,V} <- Report].
+ [io_lib:format("~n ~tp: ~tp",[K,V]) || {K,V} <- Report].
%%%-----------------------------------------------------------------
@@ -230,7 +230,7 @@ pretty_head({{{Y,Mo,D},{H,Mi,S}},MicroS},ConnMod,Text0) ->
micro2milli(MicroS)]).
pretty_title(#conn_log{client=Client}=Info) ->
- io_lib:format("= Client ~w ~s ~ts ",
+ io_lib:format("= Client ~tw ~s ~ts ",
[Client,actionstr(Info),serverstr(Info)]).
actionstr(#conn_log{action=send}) -> "----->";
@@ -238,16 +238,18 @@ actionstr(#conn_log{action=cmd}) -> "----->";
actionstr(#conn_log{action=recv}) -> "<-----";
actionstr(#conn_log{action=open}) -> "opened session to";
actionstr(#conn_log{action=close}) -> "closed session to";
+actionstr(#conn_log{action=connect}) -> "connected to";
+actionstr(#conn_log{action=disconnect}) -> "disconnected from";
actionstr(_) -> "<---->".
serverstr(#conn_log{name=undefined,address={undefined,_}}) ->
io_lib:format("server",[]);
serverstr(#conn_log{name=undefined,address=Address}) ->
- io_lib:format("~p",[Address]);
+ io_lib:format("~tp",[Address]);
serverstr(#conn_log{name=Alias,address={undefined,_}}) ->
- io_lib:format("~w",[Alias]);
+ io_lib:format("~tw",[Alias]);
serverstr(#conn_log{name=Alias,address=Address}) ->
- io_lib:format("~w(~p)",[Alias,Address]).
+ io_lib:format("~tw(~tp)",[Alias,Address]).
month(1) -> "Jan";
month(2) -> "Feb";
diff --git a/lib/common_test/src/ct_default_gl.erl b/lib/common_test/src/ct_default_gl.erl
new file mode 100644
index 0000000000..d1b52e5f4f
--- /dev/null
+++ b/lib/common_test/src/ct_default_gl.erl
@@ -0,0 +1,83 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ct_default_gl).
+-export([start_link/1, stop/0]).
+
+-export([init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2]).
+
+%% start_link()
+%% Start a new group leader process.
+start_link(ParentGL) ->
+ do_start(ParentGL, 3).
+
+do_start(_ParentGL, 0) ->
+ exit({?MODULE,startup});
+do_start(ParentGL, Retries) ->
+ case whereis(?MODULE) of
+ undefined ->
+ case gen_server:start_link(?MODULE, [ParentGL], []) of
+ {ok,Pid} ->
+ {ok,Pid};
+ Other ->
+ Other
+ end;
+ Pid ->
+ exit(Pid, kill),
+ timer:sleep(1000),
+ do_start(ParentGL, Retries-1)
+ end.
+
+%% stop(Pid)
+%% Stop a group leader process.
+stop() ->
+ gen_server:cast(whereis(?MODULE), stop).
+
+
+%%% Internal functions.
+
+init([ParentGL]) ->
+ register(?MODULE, self()),
+ {ok,#{parent_gl_pid => ParentGL,
+ parent_gl_monitor => erlang:monitor(process,ParentGL)}}.
+
+handle_cast(stop, St) ->
+ {stop,normal,St}.
+
+%% If the parent group leader dies, fall back on using the local user process
+handle_info({'DOWN',Ref,process,_,_Reason}, #{parent_gl_monitor := Ref} = St) ->
+ User = whereis(user),
+ {noreply,St#{parent_gl_pid => User,
+ parent_gl_monitor => erlang:monitor(process,User)}};
+
+handle_info({io_request,_From,_ReplyAs,_Req} = IoReq,
+ #{parent_gl_pid := ParentGL} = St) ->
+ ParentGL ! IoReq,
+ {noreply,St};
+
+handle_info(Msg, St) ->
+ io:format(user, "Common Test Group Leader process got: ~tp~n", [Msg]),
+ {noreply,St}.
+
+handle_call(_Req, _From, St) ->
+ {reply,ok,St}.
+
+terminate(_, _) ->
+ ok.
diff --git a/lib/common_test/src/ct_event.erl b/lib/common_test/src/ct_event.erl
index 5fa9f410bf..1a0ee4f3cd 100644
--- a/lib/common_test/src/ct_event.erl
+++ b/lib/common_test/src/ct_event.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -151,7 +151,7 @@ init(RecvPids) ->
%%--------------------------------------------------------------------
handle_event(Event,State=#state{receivers=RecvPids}) ->
print("~n=== ~w ===~n", [?MODULE]),
- print("~w: ~w~n", [Event#event.name,Event#event.data]),
+ print("~tw: ~tw~n", [Event#event.name,Event#event.data]),
lists:foreach(fun(Recv) -> report_event(Recv,Event) end, RecvPids),
{ok,State}.
diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl
index 104515e57e..6066470233 100644
--- a/lib/common_test/src/ct_framework.erl
+++ b/lib/common_test/src/ct_framework.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -52,6 +52,10 @@
%%%
%%% @doc Test server framework callback, called by the test_server
%%% when a new test case is started.
+init_tc(_,{end_per_testcase_not_run,_},[Config]) ->
+ %% Testcase is completed (skipped or failed), but end_per_testcase
+ %% is not run - don't call pre-hook.
+ {ok,[Config]};
init_tc(Mod,EPTC={end_per_testcase,_},[Config]) ->
%% in case Mod == ct_framework, lookup the suite name
Suite = get_suite_name(Mod, Config),
@@ -62,7 +66,7 @@ init_tc(Mod,EPTC={end_per_testcase,_},[Config]) ->
Other
end;
-init_tc(Mod,Func0,Args) ->
+init_tc(Mod,Func0,Args) ->
%% in case Mod == ct_framework, lookup the suite name
Suite = get_suite_name(Mod, Args),
{Func,HookFunc} = case Func0 of
@@ -84,12 +88,15 @@ init_tc(Mod,Func0,Args) ->
andalso Func=/=end_per_group
andalso ct_util:get_testdata(skip_rest) of
true ->
+ initialize(false,Mod,Func,Args),
{auto_skip,"Repeated test stopped by force_stop option"};
_ ->
case ct_util:get_testdata(curr_tc) of
{Suite,{suite0_failed,{require,Reason}}} ->
+ initialize(false,Mod,Func,Args),
{auto_skip,{require_failed_in_suite0,Reason}};
{Suite,{suite0_failed,_}=Failure} ->
+ initialize(false,Mod,Func,Args),
{fail,Failure};
_ ->
ct_util:update_testdata(curr_tc,
@@ -118,16 +125,14 @@ init_tc(Mod,Func0,Args) ->
end,
init_tc1(Mod,Suite,Func,HookFunc,Args);
{failed,Seq,BadFunc} ->
- {auto_skip,{sequence_failed,Seq,BadFunc}}
+ initialize(false,Mod,Func,Args),
+ {auto_skip,{sequence_failed,Seq,BadFunc}}
end
end
end.
init_tc1(?MODULE,_,error_in_suite,_,[Config0]) when is_list(Config0) ->
- ct_logs:init_tc(false),
- ct_event:notify(#event{name=tc_start,
- node=node(),
- data={?MODULE,error_in_suite}}),
+ initialize(false,?MODULE,error_in_suite),
_ = ct_suite_init(?MODULE,error_in_suite,[],Config0),
case ?val(error,Config0) of
undefined ->
@@ -177,27 +182,21 @@ init_tc1(Mod,Suite,Func,HookFunc,[Config0]) when is_list(Config0) ->
ct_config:delete_default_config(testcase),
HookFunc
end,
- Initialize = fun() ->
- ct_logs:init_tc(false),
- ct_event:notify(#event{name=tc_start,
- node=node(),
- data={Mod,FuncSpec}})
- end,
case add_defaults(Mod,Func,AllGroups) of
Error = {suite0_failed,_} ->
- Initialize(),
+ initialize(false,Mod,FuncSpec),
ct_util:set_testdata({curr_tc,{Suite,Error}}),
{error,Error};
Error = {group0_failed,_} ->
- Initialize(),
+ initialize(false,Mod,FuncSpec),
{auto_skip,Error};
Error = {testcase0_failed,_} ->
- Initialize(),
+ initialize(false,Mod,FuncSpec),
{auto_skip,Error};
{SuiteInfo,MergeResult} ->
case MergeResult of
{error,Reason} ->
- Initialize(),
+ initialize(false,Mod,FuncSpec),
{fail,Reason};
_ ->
init_tc2(Mod,Suite,Func,HookFunc1,
@@ -236,11 +235,8 @@ init_tc2(Mod,Suite,Func,HookFunc,SuiteInfo,MergeResult,Config) ->
Conns ->
ct_util:silence_connections(Conns)
end,
- ct_logs:init_tc(Func == init_per_suite),
FuncSpec = group_or_func(Func,Config),
- ct_event:notify(#event{name=tc_start,
- node=node(),
- data={Mod,FuncSpec}}),
+ initialize((Func==init_per_suite),Mod,FuncSpec),
case catch configure(MergedInfo,MergedInfo,SuiteInfo,
FuncSpec,[],Config) of
@@ -268,6 +264,18 @@ init_tc2(Mod,Suite,Func,HookFunc,SuiteInfo,MergeResult,Config) ->
end
end.
+initialize(RefreshLogs,Mod,Func,[Config]) when is_list(Config) ->
+ initialize(RefreshLogs,Mod,group_or_func(Func,Config));
+initialize(RefreshLogs,Mod,Func,_) ->
+ initialize(RefreshLogs,Mod,Func).
+
+initialize(RefreshLogs,Mod,FuncSpec) ->
+ ct_logs:init_tc(RefreshLogs),
+ ct_event:notify(#event{name=tc_start,
+ node=node(),
+ data={Mod,FuncSpec}}).
+
+
ct_suite_init(Suite,HookFunc,PostInitHook,Config) when is_list(Config) ->
case ct_hooks:init_tc(Suite,HookFunc,Config) of
NewConfig when is_list(NewConfig) ->
@@ -304,10 +312,10 @@ add_defaults(Mod,Func, GroupPath) ->
end;
{'EXIT',Reason} ->
ErrStr = io_lib:format("~n*** ERROR *** "
- "~w:suite/0 failed: ~p~n",
+ "~w:suite/0 failed: ~tp~n",
[Suite,Reason]),
io:format(ErrStr, []),
- io:format(user, ErrStr, []),
+ io:format(?def_gl, ErrStr, []),
{suite0_failed,{exited,Reason}};
SuiteInfo when is_list(SuiteInfo) ->
case lists:all(fun(E) when is_tuple(E) -> true;
@@ -327,18 +335,18 @@ add_defaults(Mod,Func, GroupPath) ->
false ->
ErrStr = io_lib:format("~n*** ERROR *** "
"Invalid return value from "
- "~w:suite/0: ~p~n",
+ "~w:suite/0: ~tp~n",
[Suite,SuiteInfo]),
io:format(ErrStr, []),
- io:format(user, ErrStr, []),
+ io:format(?def_gl, ErrStr, []),
{suite0_failed,bad_return_value}
end;
SuiteInfo ->
ErrStr = io_lib:format("~n*** ERROR *** "
"Invalid return value from "
- "~w:suite/0: ~p~n", [Suite,SuiteInfo]),
+ "~w:suite/0: ~tp~n", [Suite,SuiteInfo]),
io:format(ErrStr, []),
- io:format(user, ErrStr, []),
+ io:format(?def_gl, ErrStr, []),
{suite0_failed,bad_return_value}
end.
@@ -363,10 +371,10 @@ add_defaults1(Mod,Func, GroupPath, SuiteInfo) ->
{value,{error,BadGr0Val,GrName}} ->
Gr0ErrStr = io_lib:format("~n*** ERROR *** "
"Invalid return value from "
- "~w:group(~w): ~p~n",
+ "~w:group(~tw): ~tp~n",
[Mod,GrName,BadGr0Val]),
io:format(Gr0ErrStr, []),
- io:format(user, Gr0ErrStr, []),
+ io:format(?def_gl, Gr0ErrStr, []),
{group0_failed,bad_return_value};
_ ->
Args = if Func == init_per_group ; Func == end_per_group ->
@@ -385,10 +393,10 @@ add_defaults1(Mod,Func, GroupPath, SuiteInfo) ->
{error,BadTC0Val} ->
TC0ErrStr = io_lib:format("~n*** ERROR *** "
"Invalid return value from "
- "~w:~w/0: ~p~n",
+ "~w:~tw/0: ~tp~n",
[Mod,Func,BadTC0Val]),
io:format(TC0ErrStr, []),
- io:format(user, TC0ErrStr, []),
+ io:format(?def_gl, TC0ErrStr, []),
{testcase0_failed,bad_return_value};
_ ->
%% let test case info (also for all config funcs) override
@@ -675,22 +683,35 @@ end_tc(Mod,Func,{Result,[Args]}, Return) ->
end_tc(Mod,Func,self(),Result,Args,Return).
end_tc(Mod,IPTC={init_per_testcase,_Func},_TCPid,Result,Args,Return) ->
- %% in case Mod == ct_framework, lookup the suite name
- Suite = get_suite_name(Mod, Args),
- case ct_hooks:end_tc(Suite,IPTC,Args,Result,Return) of
- '$ct_no_change' ->
- ok;
- HookResult ->
- HookResult
+ case end_hook_func(IPTC,Return,IPTC) of
+ undefined -> ok;
+ _ ->
+ %% in case Mod == ct_framework, lookup the suite name
+ Suite = get_suite_name(Mod, Args),
+ case ct_hooks:end_tc(Suite,IPTC,Args,Result,Return) of
+ '$ct_no_change' ->
+ ok;
+ HookResult ->
+ HookResult
+ end
end;
end_tc(Mod,Func0,TCPid,Result,Args,Return) ->
%% in case Mod == ct_framework, lookup the suite name
Suite = get_suite_name(Mod, Args),
- {EPTC,Func} = case Func0 of
- {end_per_testcase,F} -> {true,F};
- _ -> {false,Func0}
- end,
+ {Func,FuncSpec,HookFunc} =
+ case Func0 of
+ {end_per_testcase_not_run,F} ->
+ %% Testcase is completed (skipped or failed), but
+ %% end_per_testcase is not run - don't call post-hook.
+ {F,F,undefined};
+ {end_per_testcase,F} ->
+ {F,F,Func0};
+ _ ->
+ FS = group_or_func(Func0,Args),
+ HF = end_hook_func(Func0,Return,FS),
+ {Func0,FS,HF}
+ end,
test_server:timetrap_cancel(),
@@ -717,20 +738,18 @@ end_tc(Mod,Func0,TCPid,Result,Args,Return) ->
end,
ct_util:delete_suite_data(last_saved_config),
- {FuncSpec,HookFunc} =
- if not EPTC ->
- FS = group_or_func(Func,Args),
- {FS,FS};
- true ->
- {Func,Func0}
- end,
{Result1,FinalNotify} =
- case ct_hooks:end_tc(Suite,HookFunc,Args,Result,Return) of
- '$ct_no_change' ->
- {ok,Result};
- HookResult ->
- {HookResult,HookResult}
- end,
+ case HookFunc of
+ undefined ->
+ {ok,Result};
+ _ ->
+ case ct_hooks:end_tc(Suite,HookFunc,Args,Result,Return) of
+ '$ct_no_change' ->
+ {ok,Result};
+ HookResult ->
+ {HookResult,HookResult}
+ end
+ end,
FinalResult =
case get('$test_server_framework_test') of
undefined ->
@@ -821,6 +840,34 @@ end_tc(Mod,Func0,TCPid,Result,Args,Return) ->
end,
FinalResult.
+%% This is to make sure that no post_init_per_* is ever called if the
+%% corresponding pre_init_per_* was not called.
+%% The skip or fail reasons are those that can be returned from
+%% init_tc above in situations where we never came to call
+%% ct_hooks:init_tc/3, e.g. if suite/0 fails, then we never call
+%% ct_hooks:init_tc for init_per_suite, and thus we must not call
+%% ct_hooks:end_tc for init_per_suite either.
+end_hook_func({init_per_testcase,_},{auto_skip,{sequence_failed,_,_}},_) ->
+ undefined;
+end_hook_func({init_per_testcase,_},{auto_skip,"Repeated test stopped by force_stop option"},_) ->
+ undefined;
+end_hook_func({init_per_testcase,_},{fail,{config_name_already_in_use,_}},_) ->
+ undefined;
+end_hook_func({init_per_testcase,_},{auto_skip,{InfoFuncError,_}},_)
+ when InfoFuncError==testcase0_failed;
+ InfoFuncError==require_failed ->
+ undefined;
+end_hook_func(init_per_group,{auto_skip,{InfoFuncError,_}},_)
+ when InfoFuncError==group0_failed;
+ InfoFuncError==require_failed ->
+ undefined;
+end_hook_func(init_per_suite,{auto_skip,{require_failed_in_suite0,_}},_) ->
+ undefined;
+end_hook_func(init_per_suite,{auto_skip,{failed,{error,{suite0_failed,_}}}},_) ->
+ undefined;
+end_hook_func(_,_,Default) ->
+ Default.
+
%% {error,Reason} | {skip,Reason} | {timetrap_timeout,TVal} |
%% {testcase_aborted,Reason} | testcase_aborted_or_killed |
%% {'EXIT',Reason} | {fail,Reason} | {failed,Reason} |
@@ -874,7 +921,7 @@ error_notification(Mod,Func,_Args,{Error,Loc}) ->
end,
ErrorStr = case ErrorSpec of
{badmatch,Descr} ->
- Descr1 = lists:flatten(io_lib:format("~P",[Descr,10])),
+ Descr1 = lists:flatten(io_lib:format("~tP",[Descr,10])),
if length(Descr1) > 50 ->
Descr2 = string:substr(Descr1,1,50),
io_lib:format("{badmatch,~ts...}",[Descr2]);
@@ -884,15 +931,15 @@ error_notification(Mod,Func,_Args,{Error,Loc}) ->
{test_case_failed,Reason} ->
case (catch io_lib:format("{test_case_failed,~ts}", [Reason])) of
{'EXIT',_} ->
- io_lib:format("{test_case_failed,~p}", [Reason]);
+ io_lib:format("{test_case_failed,~tp}", [Reason]);
Result -> Result
end;
{'EXIT',_Reason} = EXIT ->
- io_lib:format("~P", [EXIT,5]);
+ io_lib:format("~tP", [EXIT,5]);
{Spec,_Reason} when is_atom(Spec) ->
- io_lib:format("~w", [Spec]);
+ io_lib:format("~tw", [Spec]);
Other ->
- io_lib:format("~P", [Other,5])
+ io_lib:format("~tP", [Other,5])
end,
ErrorHtml =
"<font color=\"brown\">" ++ ct_logs:escape_chars(ErrorStr) ++ "</font>",
@@ -927,7 +974,7 @@ error_notification(Mod,Func,_Args,{Error,Loc}) ->
Div = "~n- - - - - - - - - - - - - - - - - - - "
"- - - - - - - - - - - - - - - - - - - - -~n",
ErrorStr2 = io_lib:format(ErrorFormat, ErrorArgs),
- io:format(user, lists:concat([Div,ErrorStr2,Div,"~n"]),
+ io:format(?def_gl, lists:concat([Div,ErrorStr2,Div,"~n"]),
[]),
Link =
"\n\n<a href=\"#end\">"
@@ -949,16 +996,16 @@ error_notification(Mod,Func,_Args,{Error,Loc}) ->
%% if a function specified by all/0 does not exist, we
%% pick up undef here
[{LastMod,LastFunc}|_] when ErrorStr == "undef" ->
- PrintError("~w:~w could not be executed~nReason: ~ts",
+ PrintError("~w:~tw could not be executed~nReason: ~ts",
[LastMod,LastFunc,ErrorStr]);
[{LastMod,LastFunc}|_] ->
- PrintError("~w:~w failed~nReason: ~ts", [LastMod,LastFunc,ErrorStr]);
+ PrintError("~w:~tw failed~nReason: ~ts", [LastMod,LastFunc,ErrorStr]);
[{LastMod,LastFunc,LastLine}|_] ->
%% print error to console, we are only
%% interested in the last executed expression
- PrintError("~w:~w failed on line ~w~nReason: ~ts",
+ PrintError("~w:~tw failed on line ~w~nReason: ~ts",
[LastMod,LastFunc,LastLine,ErrorStr]),
case ct_util:read_suite_data({seq,Mod,Func}) of
@@ -1131,9 +1178,9 @@ get_all(Mod, ConfTests) ->
case ct_util:get_testdata({error_in_suite,Mod}) of
undefined ->
ErrStr = io_lib:format("~n*** ERROR *** "
- "~w:all/0 failed: ~p~n",
+ "~w:all/0 failed: ~tp~n",
[Mod,ExitReason]),
- io:format(user, ErrStr, []),
+ io:format(?def_gl, ErrStr, []),
%% save the error info so it doesn't get printed twice
ct_util:set_testdata_async({{error_in_suite,Mod},
ExitReason});
@@ -1247,8 +1294,8 @@ save_seq(Mod,Seq,SeqTCs,All) ->
check_private(Seq,TCs,All) ->
Bad = lists:filter(fun(TC) -> lists:member(TC,All) end, TCs),
if Bad /= [] ->
- Reason = io_lib:format("regular test cases not allowed in sequence ~p: "
- "~p",[Seq,Bad]),
+ Reason = io_lib:format("regular test cases not allowed in sequence ~tp: "
+ "~tp",[Seq,Bad]),
throw({error,list_to_atom(lists:flatten(Reason))});
true ->
ok
@@ -1265,7 +1312,7 @@ check_multiple(Mod,Seq,TCs) ->
end,TCs),
if Bad /= [] ->
Reason = io_lib:format("test cases found in multiple sequences: "
- "~p",[Bad]),
+ "~tp",[Bad]),
throw({error,list_to_atom(lists:flatten(Reason))});
true ->
ok
@@ -1293,15 +1340,15 @@ end_per_suite(_Config) ->
%% if the group config functions are missing in the suite,
%% use these instead
init_per_group(GroupName, Config) ->
- ct:comment(io_lib:format("start of ~p", [GroupName])),
- ct_logs:log("TEST INFO", "init_per_group/2 for ~w missing "
+ ct:comment(io_lib:format("start of ~tp", [GroupName])),
+ ct_logs:log("TEST INFO", "init_per_group/2 for ~tw missing "
"in suite, using default.",
[GroupName]),
Config.
end_per_group(GroupName, _) ->
- ct:comment(io_lib:format("end of ~p", [GroupName])),
- ct_logs:log("TEST INFO", "end_per_group/2 for ~w missing "
+ ct:comment(io_lib:format("end of ~tp", [GroupName])),
+ ct_logs:log("TEST INFO", "end_per_group/2 for ~tw missing "
"in suite, using default.",
[GroupName]),
ok.
@@ -1339,25 +1386,25 @@ report(What,Data) ->
ok;
tc_done ->
{Suite,{Func,GrName},Result} = Data,
- Data1 = if GrName == undefined -> {Suite,Func,Result};
- true -> Data
- end,
+ FuncSpec = if GrName == undefined -> Func;
+ true -> {Func,GrName}
+ end,
%% Register the group leader for the process calling the report
%% function, making it possible for a hook function to print
%% in the test case log file
ReportingPid = self(),
ct_logs:register_groupleader(ReportingPid, group_leader()),
case Result of
- {failed, _} ->
- ct_hooks:on_tc_fail(What, Data1);
- {skipped,{failed,{_,init_per_testcase,_}}} ->
- ct_hooks:on_tc_skip(tc_auto_skip, Data1);
- {skipped,{require_failed,_}} ->
- ct_hooks:on_tc_skip(tc_auto_skip, Data1);
- {skipped,_} ->
- ct_hooks:on_tc_skip(tc_user_skip, Data1);
- {auto_skipped,_} ->
- ct_hooks:on_tc_skip(tc_auto_skip, Data1);
+ {failed, Reason} ->
+ ct_hooks:on_tc_fail(What, {Suite,FuncSpec,Reason});
+ {skipped,{failed,{_,init_per_testcase,_}}=Reason} ->
+ ct_hooks:on_tc_skip(tc_auto_skip, {Suite,FuncSpec,Reason});
+ {skipped,{require_failed,_}=Reason} ->
+ ct_hooks:on_tc_skip(tc_auto_skip, {Suite,FuncSpec,Reason});
+ {skipped,Reason} ->
+ ct_hooks:on_tc_skip(tc_user_skip, {Suite,FuncSpec,Reason});
+ {auto_skipped,Reason} ->
+ ct_hooks:on_tc_skip(tc_auto_skip, {Suite,FuncSpec,Reason});
_Else ->
ok
end,
diff --git a/lib/common_test/src/ct_ftp.erl b/lib/common_test/src/ct_ftp.erl
index 84e664b387..8effb06e7e 100644
--- a/lib/common_test/src/ct_ftp.erl
+++ b/lib/common_test/src/ct_ftp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -119,19 +119,19 @@ open(KeyOrName) ->
_ ->
case ct:get_config(KeyOrName) of
undefined ->
- log(heading(open,KeyOrName),"Failed: ~p\n",
+ log(heading(open,KeyOrName),"Failed: ~tp\n",
[{not_available,KeyOrName}]),
{error,{not_available,KeyOrName}};
_ ->
case ct:get_config({KeyOrName,username}) of
undefined ->
- log(heading(open,KeyOrName),"Failed: ~p\n",
+ log(heading(open,KeyOrName),"Failed: ~tp\n",
[{not_available,{KeyOrName,username}}]),
{error,{not_available,{KeyOrName,username}}};
Username ->
case ct:get_config({KeyOrName,password}) of
undefined ->
- log(heading(open,KeyOrName),"Failed: ~p\n",
+ log(heading(open,KeyOrName),"Failed: ~tp\n",
[{not_available,{KeyOrName,password}}]),
{error,{not_available,{KeyOrName,password}}};
Password ->
@@ -145,7 +145,7 @@ open(KeyOrName,Username,Password) ->
log(heading(open,KeyOrName),"",[]),
case ct:get_config({KeyOrName,ftp}) of
undefined ->
- log(heading(open,KeyOrName),"Failed: ~p\n",
+ log(heading(open,KeyOrName),"Failed: ~tp\n",
[{not_available,{KeyOrName,ftp}}]),
{error,{not_available,{KeyOrName,ftp}}};
Addr ->
@@ -284,7 +284,7 @@ init(KeyOrName,{IP,Port},{Username,Password}) ->
case ftp_connect(IP,Port,Username,Password) of
{ok,FtpPid} ->
log(heading(init,KeyOrName),
- "Opened ftp connection:\nIP: ~p\nUsername: ~p\nPassword: ~p\n",
+ "Opened ftp connection:\nIP: ~tp\nUsername: ~tp\nPassword: ~p\n",
[IP,Username,lists:duplicate(length(Password),$*)]),
{ok,FtpPid,#state{ftp_pid=FtpPid,target_name=KeyOrName}};
Error ->
@@ -308,28 +308,28 @@ ftp_connect(IP,Port,Username,Password) ->
%% @hidden
handle_msg({send,LocalFile,RemoteFile},State) ->
log(heading(send,State#state.target_name),
- "LocalFile: ~p\nRemoteFile: ~p\n",[LocalFile,RemoteFile]),
+ "LocalFile: ~tp\nRemoteFile: ~tp\n",[LocalFile,RemoteFile]),
Result = ftp:send(State#state.ftp_pid,LocalFile,RemoteFile),
{Result,State};
handle_msg({recv,RemoteFile,LocalFile},State) ->
log(heading(recv,State#state.target_name),
- "RemoteFile: ~p\nLocalFile: ~p\n",[RemoteFile,LocalFile]),
+ "RemoteFile: ~tp\nLocalFile: ~tp\n",[RemoteFile,LocalFile]),
Result = ftp:recv(State#state.ftp_pid,RemoteFile,LocalFile),
{Result,State};
handle_msg({cd,Dir},State) ->
- log(heading(cd,State#state.target_name),"Dir: ~p\n",[Dir]),
+ log(heading(cd,State#state.target_name),"Dir: ~tp\n",[Dir]),
Result = ftp:cd(State#state.ftp_pid,Dir),
{Result,State};
handle_msg({ls,Dir},State) ->
- log(heading(ls,State#state.target_name),"Dir: ~p\n",[Dir]),
+ log(heading(ls,State#state.target_name),"Dir: ~tp\n",[Dir]),
Result = ftp:ls(State#state.ftp_pid,Dir),
{Result,State};
handle_msg({type,Type},State) ->
- log(heading(type,State#state.target_name),"Type: ~p\n",[Type]),
+ log(heading(type,State#state.target_name),"Type: ~tp\n",[Type]),
Result = ftp:type(State#state.ftp_pid,Type),
{Result,State};
handle_msg({delete,File},State) ->
- log(heading(delete,State#state.target_name),"Delete file: ~p\n",[File]),
+ log(heading(delete,State#state.target_name),"Delete file: ~tp\n",[File]),
Result = ftp:delete(State#state.ftp_pid,File),
{Result,State}.
@@ -368,7 +368,7 @@ call(Pid,Msg) ->
heading(Function,Name) ->
- io_lib:format("ct_ftp:~w ~p",[Function,Name]).
+ io_lib:format("ct_ftp:~tw ~tp",[Function,Name]).
log(Heading,Str,Args) ->
ct_gen_conn:log(Heading,Str,Args).
diff --git a/lib/common_test/src/ct_gen_conn.erl b/lib/common_test/src/ct_gen_conn.erl
index 23ba1ab981..badb7c52ae 100644
--- a/lib/common_test/src/ct_gen_conn.erl
+++ b/lib/common_test/src/ct_gen_conn.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,14 +27,7 @@
-export([start/4, stop/1, get_conn_pid/1, check_opts/1]).
-export([call/2, call/3, return/2, do_within_time/2]).
--export([log/3, start_log/1, cont_log/2, end_log/0]).
-
-%%----------------------------------------------------------------------
-%% Exported types
-%%----------------------------------------------------------------------
--export_type([server_id/0,
- target_name/0,
- key_or_name/0]).
+-export([log/3, start_log/1, cont_log/2, cont_log_no_timestamp/2, end_log/0]).
-ifdef(debug).
-define(dbg,true).
@@ -54,18 +47,6 @@
cb_state,
ct_util_server}).
-%%------------------------------------------------------------------
-%% Type declarations
-%%------------------------------------------------------------------
--type server_id() :: atom().
-%% A `ServerId' which exists in a configuration file.
--type target_name() :: atom().
-%% A name which is associated to a `server_id()' via a
-%% `require' statement or a call to {@link ct:require/2} in the
-%% test suite.
--type key_or_name() :: server_id() | target_name().
-
-
%%%-----------------------------------------------------------------
%%% @spec start(Address,InitData,CallbackMod,Opts) ->
%%% {ok,Handle} | {error,Reason}
@@ -175,6 +156,14 @@ cont_log(Format,Args) ->
log(cont_log,[Format,Args]).
%%%-----------------------------------------------------------------
+%%% @spec cont_log_no_timestamp(Format,Args) -> ok
+%%%
+%%% @doc Log activities on the current connection (tool-internal use only).
+%%% @see ct_logs:cont_log/2
+cont_log_no_timestamp(Format,Args) ->
+ log(cont_log_no_timestamp,[Format,Args]).
+
+%%%-----------------------------------------------------------------
%%% @spec end_log() -> ok
%%%
%%% @doc Log activities on the current connection (tool-internal use only).
@@ -258,7 +247,7 @@ do_start(Opts) ->
Error;
{'DOWN',MRef,process,_,Reason} ->
log("ct_gen_conn:start",
- "Connection process died: ~p\n",
+ "Connection process died: ~tp\n",
[Reason]),
{error,{connection_process_died,Reason}}
end.
@@ -338,7 +327,7 @@ loop(Opts) ->
case Opts#gen_opts.reconnect of
true ->
log("Connection down!\nOpening new!",
- "Reason: ~p\nAddress: ~p\n",
+ "Reason: ~tp\nAddress: ~tp\n",
[Reason,Opts#gen_opts.address]),
case reconnect(Opts) of
{ok, NewPid, NewState} ->
@@ -349,12 +338,12 @@ loop(Opts) ->
Error ->
ct_util:unregister_connection(self()),
log("Reconnect failed. Giving up!",
- "Reason: ~p\n",
+ "Reason: ~tp\n",
[Error])
end;
false ->
ct_util:unregister_connection(self()),
- log("Connection closed!","Reason: ~p\n",[Reason])
+ log("Connection closed!","Reason: ~tp\n",[Reason])
end;
{'EXIT',Pid,Reason} ->
case Opts#gen_opts.ct_util_server of
@@ -365,8 +354,9 @@ loop(Opts) ->
end;
{stop, From} ->
ct_util:unregister_connection(self()),
- (Opts#gen_opts.callback):terminate(Opts#gen_opts.conn_pid,
- Opts#gen_opts.cb_state),
+ ConnPid = Opts#gen_opts.conn_pid,
+ unlink(ConnPid),
+ (Opts#gen_opts.callback):terminate(ConnPid,Opts#gen_opts.cb_state),
return(From,ok),
ok;
{{retry,{Error,_Name,CPid,_Msg}}, From} when
@@ -403,8 +393,9 @@ loop(Opts) ->
loop(Opts#gen_opts{cb_state=NewState});
{stop,Reply,NewState} ->
ct_util:unregister_connection(self()),
- (Opts#gen_opts.callback):terminate(Opts#gen_opts.conn_pid,
- NewState),
+ ConnPid = Opts#gen_opts.conn_pid,
+ unlink(ConnPid),
+ (Opts#gen_opts.callback):terminate(ConnPid,NewState),
return(From,Reply)
end;
Msg when Opts#gen_opts.forward==true ->
@@ -414,8 +405,9 @@ loop(Opts) ->
loop(Opts#gen_opts{cb_state=NewState});
{stop,NewState} ->
ct_util:unregister_connection(self()),
- (Opts#gen_opts.callback):terminate(Opts#gen_opts.conn_pid,
- NewState)
+ ConnPid = Opts#gen_opts.conn_pid,
+ unlink(ConnPid),
+ (Opts#gen_opts.callback):terminate(ConnPid,NewState)
end
end.
diff --git a/lib/common_test/src/ct_groups.erl b/lib/common_test/src/ct_groups.erl
index 1375e7dcc7..2235365a0e 100644
--- a/lib/common_test/src/ct_groups.erl
+++ b/lib/common_test/src/ct_groups.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -210,7 +210,7 @@ find(Mod, _GrNames, _TCs, [BadTerm | _Gs], Known, _Defs, _FindAll) ->
"group "++atom_to_list(lists:last(Known))++
" in "++atom_to_list(Mod)++":groups/0"
end,
- Term = io_lib:format("~p", [BadTerm]),
+ Term = io_lib:format("~tp", [BadTerm]),
E = "Bad term "++lists:flatten(Term)++" in "++Where,
throw({error,list_to_atom(E)});
@@ -442,17 +442,21 @@ make_conf(Mod, Name, Props, TestSpec) ->
ok
end,
{InitConf,EndConf,ExtraProps} =
- case erlang:function_exported(Mod,init_per_group,2) of
- true ->
- {{Mod,init_per_group},{Mod,end_per_group},[]};
- false ->
+ case {erlang:function_exported(Mod,init_per_group,2),
+ erlang:function_exported(Mod,end_per_group,2)} of
+ {false,false} ->
ct_logs:log("TEST INFO", "init_per_group/2 and "
"end_per_group/2 missing for group "
- "~w in ~w, using default.",
+ "~tw in ~w, using default.",
[Name,Mod]),
{{ct_framework,init_per_group},
{ct_framework,end_per_group},
- [{suite,Mod}]}
+ [{suite,Mod}]};
+ _ ->
+ %% If any of these exist, the other should too
+ %% (required and documented). If it isn't, it will fail
+ %% with reason 'undef'.
+ {{Mod,init_per_group},{Mod,end_per_group},[]}
end,
{conf,[{name,Name}|Props++ExtraProps],InitConf,TestSpec,EndConf}.
diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl
index c9a4abb5ee..f0592a40be 100644
--- a/lib/common_test/src/ct_hooks.erl
+++ b/lib/common_test/src/ct_hooks.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -92,15 +92,17 @@ init_tc(Mod, end_per_suite, Config) ->
call(fun call_generic/3, Config, [pre_end_per_suite, Mod]);
init_tc(Mod, {init_per_group, GroupName, Properties}, Config) ->
maybe_start_locker(Mod, GroupName, Properties),
- call(fun call_generic/3, Config, [pre_init_per_group, GroupName]);
-init_tc(_Mod, {end_per_group, GroupName, _}, Config) ->
- call(fun call_generic/3, Config, [pre_end_per_group, GroupName]);
-init_tc(_Mod, {init_per_testcase,TC}, Config) ->
- call(fun call_generic/3, Config, [pre_init_per_testcase, TC]);
-init_tc(_Mod, {end_per_testcase,TC}, Config) ->
- call(fun call_generic/3, Config, [pre_end_per_testcase, TC]);
-init_tc(_Mod, TC = error_in_suite, Config) ->
- call(fun call_generic/3, Config, [pre_init_per_testcase, TC]).
+ call(fun call_generic_fallback/3, Config,
+ [pre_init_per_group, Mod, GroupName]);
+init_tc(Mod, {end_per_group, GroupName, _}, Config) ->
+ call(fun call_generic_fallback/3, Config,
+ [pre_end_per_group, Mod, GroupName]);
+init_tc(Mod, {init_per_testcase,TC}, Config) ->
+ call(fun call_generic_fallback/3, Config, [pre_init_per_testcase, Mod, TC]);
+init_tc(Mod, {end_per_testcase,TC}, Config) ->
+ call(fun call_generic_fallback/3, Config, [pre_end_per_testcase, Mod, TC]);
+init_tc(Mod, TC = error_in_suite, Config) ->
+ call(fun call_generic_fallback/3, Config, [pre_init_per_testcase, Mod, TC]).
%% @doc Called as each test case is completed. This includes all configuration
%% tests.
@@ -126,23 +128,23 @@ end_tc(Mod, init_per_suite, Config, _Result, Return) ->
end_tc(Mod, end_per_suite, Config, Result, _Return) ->
call(fun call_generic/3, Result, [post_end_per_suite, Mod, Config],
'$ct_no_change');
-end_tc(_Mod, {init_per_group, GroupName, _}, Config, _Result, Return) ->
- call(fun call_generic/3, Return, [post_init_per_group, GroupName, Config],
- '$ct_no_change');
+end_tc(Mod, {init_per_group, GroupName, _}, Config, _Result, Return) ->
+ call(fun call_generic_fallback/3, Return,
+ [post_init_per_group, Mod, GroupName, Config], '$ct_no_change');
end_tc(Mod, {end_per_group, GroupName, Properties}, Config, Result, _Return) ->
- Res = call(fun call_generic/3, Result,
- [post_end_per_group, GroupName, Config], '$ct_no_change'),
+ Res = call(fun call_generic_fallback/3, Result,
+ [post_end_per_group, Mod, GroupName, Config], '$ct_no_change'),
maybe_stop_locker(Mod, GroupName, Properties),
Res;
-end_tc(_Mod, {init_per_testcase,TC}, Config, Result, _Return) ->
- call(fun call_generic/3, Result, [post_init_per_testcase, TC, Config],
- '$ct_no_change');
-end_tc(_Mod, {end_per_testcase,TC}, Config, Result, _Return) ->
- call(fun call_generic/3, Result, [post_end_per_testcase, TC, Config],
- '$ct_no_change');
-end_tc(_Mod, TC = error_in_suite, Config, Result, _Return) ->
- call(fun call_generic/3, Result, [post_end_per_testcase, TC, Config],
- '$ct_no_change').
+end_tc(Mod, {init_per_testcase,TC}, Config, Result, _Return) ->
+ call(fun call_generic_fallback/3, Result,
+ [post_init_per_testcase, Mod, TC, Config], '$ct_no_change');
+end_tc(Mod, {end_per_testcase,TC}, Config, Result, _Return) ->
+ call(fun call_generic_fallback/3, Result,
+ [post_end_per_testcase, Mod, TC, Config], '$ct_no_change');
+end_tc(Mod, TC = error_in_suite, Config, Result, _Return) ->
+ call(fun call_generic_fallback/3, Result,
+ [post_end_per_testcase, Mod, TC, Config], '$ct_no_change').
%% Case = TestCase | {TestCase,GroupName}
@@ -181,15 +183,21 @@ call_terminate(#ct_hook_config{ module = Mod, state = State} = Hook, _, _) ->
{[],Hook}.
call_cleanup(#ct_hook_config{ module = Mod, state = State} = Hook,
- Reason, [Function, _Suite | Args]) ->
+ Reason, [Function | Args]) ->
NewState = catch_apply(Mod,Function, Args ++ [Reason, State],
- State),
+ State, true),
{Reason, Hook#ct_hook_config{ state = NewState } }.
-call_generic(#ct_hook_config{ module = Mod, state = State} = Hook,
- Value, [Function | Args]) ->
+call_generic(Hook, Value, Meta) ->
+ do_call_generic(Hook, Value, Meta, false).
+
+call_generic_fallback(Hook, Value, Meta) ->
+ do_call_generic(Hook, Value, Meta, true).
+
+do_call_generic(#ct_hook_config{ module = Mod, state = State} = Hook,
+ Value, [Function | Args], Fallback) ->
{NewValue, NewState} = catch_apply(Mod, Function, Args ++ [Value, State],
- {Value,State}),
+ {Value,State}, Fallback),
{NewValue, Hook#ct_hook_config{ state = NewState } }.
%% Generic call function
@@ -227,7 +235,7 @@ call([{Hook, call_id, NextFun} | Rest], Config, Meta, Hooks) ->
call(resort(NewRest,NewHooks,Meta), Config, Meta, NewHooks)
catch Error:Reason ->
Trace = erlang:get_stacktrace(),
- ct_logs:log("Suite Hook","Failed to start a CTH: ~p:~p",
+ ct_logs:log("Suite Hook","Failed to start a CTH: ~tp:~tp",
[Error,{Reason,Trace}]),
call([], {fail,"Failed to start CTH"
", see the CT Log for details"}, Meta, Hooks)
@@ -257,15 +265,15 @@ remove(Key,List) when is_list(List) ->
remove(_, Else) ->
Else.
-%% Translate scopes, i.e. init_per_group,group1 -> end_per_group,group1 etc
-scope([pre_init_per_testcase, TC|_]) ->
- [post_init_per_testcase, TC];
-scope([pre_end_per_testcase, TC|_]) ->
- [post_end_per_testcase, TC];
-scope([pre_init_per_group, GroupName|_]) ->
- [post_end_per_group, GroupName];
-scope([post_init_per_group, GroupName|_]) ->
- [post_end_per_group, GroupName];
+%% Translate scopes, i.e. is_tuplenit_per_group,group1 -> end_per_group,group1 etc
+scope([pre_init_per_testcase, SuiteName, TC|_]) ->
+ [post_init_per_testcase, SuiteName, TC];
+scope([pre_end_per_testcase, SuiteName, TC|_]) ->
+ [post_end_per_testcase, SuiteName, TC];
+scope([pre_init_per_group, SuiteName, GroupName|_]) ->
+ [post_end_per_group, SuiteName, GroupName];
+scope([post_init_per_group, SuiteName, GroupName|_]) ->
+ [post_end_per_group, SuiteName, GroupName];
scope([pre_init_per_suite, SuiteName|_]) ->
[post_end_per_suite, SuiteName];
scope([post_init_per_suite, SuiteName|_]) ->
@@ -273,14 +281,29 @@ scope([post_init_per_suite, SuiteName|_]) ->
scope(init) ->
none.
-terminate_if_scope_ends(HookId, [on_tc_skip,_Suite,{end_per_group,Name}],
+strip_config([post_init_per_testcase, SuiteName, TC|_]) ->
+ [post_init_per_testcase, SuiteName, TC];
+strip_config([post_end_per_testcase, SuiteName, TC|_]) ->
+ [post_end_per_testcase, SuiteName, TC];
+strip_config([post_init_per_group, SuiteName, GroupName|_]) ->
+ [post_init_per_group, SuiteName, GroupName];
+strip_config([post_end_per_group, SuiteName, GroupName|_]) ->
+ [post_end_per_group, SuiteName, GroupName];
+strip_config([post_init_per_suite, SuiteName|_]) ->
+ [post_init_per_suite, SuiteName];
+strip_config([post_end_per_suite, SuiteName|_]) ->
+ [post_end_per_suite, SuiteName];
+strip_config(Other) ->
+ Other.
+
+
+terminate_if_scope_ends(HookId, [on_tc_skip,Suite,{end_per_group,Name}],
Hooks) ->
- terminate_if_scope_ends(HookId, [post_end_per_group, Name], Hooks);
+ terminate_if_scope_ends(HookId, [post_end_per_group, Suite, Name], Hooks);
terminate_if_scope_ends(HookId, [on_tc_skip,Suite,end_per_suite], Hooks) ->
terminate_if_scope_ends(HookId, [post_end_per_suite, Suite], Hooks);
-terminate_if_scope_ends(HookId, [Function,Tag|T], Hooks) when T =/= [] ->
- terminate_if_scope_ends(HookId,[Function,Tag],Hooks);
-terminate_if_scope_ends(HookId, Function, Hooks) ->
+terminate_if_scope_ends(HookId, Function0, Hooks) ->
+ Function = strip_config(Function0),
case lists:keyfind(HookId, #ct_hook_config.id, Hooks) of
#ct_hook_config{ id = HookId, scope = Function} = Hook ->
terminate([Hook]),
@@ -384,21 +407,29 @@ pos(Id,[_|Rest],Num) ->
catch_apply(M,F,A, Default) ->
+ catch_apply(M,F,A,Default,false).
+catch_apply(M,F,A, Default, Fallback) ->
+ not erlang:module_loaded(M) andalso (catch M:module_info()),
+ case erlang:function_exported(M,F,length(A)) of
+ false when Fallback ->
+ catch_apply(M,F,tl(A),Default,false);
+ false ->
+ Default;
+ true ->
+ catch_apply(M,F,A)
+ end.
+
+catch_apply(M,F,A) ->
try
- erlang:apply(M,F,A)
+ erlang:apply(M,F,A)
catch _:Reason ->
- case erlang:get_stacktrace() of
- %% Return the default if it was the CTH module which did not have the function.
- [{M,F,A,_}|_] when Reason == undef ->
- Default;
- Trace ->
- ct_logs:log("Suite Hook","Call to CTH failed: ~w:~p",
- [error,{Reason,Trace}]),
- throw({error_in_cth_call,
- lists:flatten(
- io_lib:format("~w:~w/~w CTH call failed",
- [M,F,length(A)]))})
- end
+ Trace = erlang:get_stacktrace(),
+ ct_logs:log("Suite Hook","Call to CTH failed: ~w:~tp",
+ [error,{Reason,Trace}]),
+ throw({error_in_cth_call,
+ lists:flatten(
+ io_lib:format("~w:~tw/~w CTH call failed",
+ [M,F,length(A)]))})
end.
diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl
index 53245c596a..ba7660fe6a 100644
--- a/lib/common_test/src/ct_logs.erl
+++ b/lib/common_test/src/ct_logs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@
-export([init/2, close/2, init_tc/1, end_tc/1]).
-export([register_groupleader/2, unregister_groupleader/1]).
-export([get_log_dir/0, get_log_dir/1]).
--export([log/3, start_log/1, cont_log/2, end_log/0]).
+-export([log/3, start_log/1, cont_log/2, cont_log_no_timestamp/2, end_log/0]).
-export([set_stylesheet/2, clear_stylesheet/1]).
-export([add_external_logs/1, add_link/3]).
-export([make_last_run_index/0]).
@@ -41,12 +41,13 @@
-export([xhtml/2, locate_priv_file/1, make_relative/1]).
-export([insert_javascript/1]).
-export([uri/1]).
+-export([parse_keep_logs/1]).
%% Logging stuff directly from testcase
-export([tc_log/3, tc_log/4, tc_log/5, tc_log/6,
tc_log_async/3, tc_log_async/5,
- tc_print/3, tc_print/4,
- tc_pal/3, tc_pal/4, ct_log/3,
+ tc_print/3, tc_print/4, tc_print/5,
+ tc_pal/3, tc_pal/4, tc_pal/5, ct_log/3,
basic_html/0]).
%% Simulate logger process for use without ct environment running
@@ -138,7 +139,7 @@ close(Info, StartDir) ->
LogCacheBin =
case make_last_run_index() of
{error, Reason} -> % log server not responding
- io:format("Warning! ct_logs not responding: ~p~n", [Reason]),
+ io:format("Warning! ct_logs not responding: ~tp~n", [Reason]),
undefined;
LCB ->
LCB
@@ -174,7 +175,7 @@ close(Info, StartDir) ->
ok ->
ok;
Error ->
- io:format("Warning! Cleanup failed: ~p~n", [Error])
+ io:format("Warning! Cleanup failed: ~tp~n", [Error])
end,
_ = make_all_suites_index(stop),
make_all_runs_index(stop),
@@ -373,6 +374,20 @@ cont_log(Format,Args) ->
ok.
%%%-----------------------------------------------------------------
+%%% @spec cont_log_no_timestamp(Format,Args) -> ok
+%%%
+%%% @doc Adds information about an activity (tool-internal use only).
+%%%
+%%% @see start_log/1
+%%% @see end_log/0
+cont_log_no_timestamp([],[]) ->
+ ok;
+cont_log_no_timestamp(Format,Args) ->
+ cast({log,sync,self(),group_leader(),ct_internal,?MAX_IMPORTANCE,
+ [{Format,Args}],true}),
+ ok.
+
+%%%-----------------------------------------------------------------
%%% @spec end_log() -> ok
%%%
%%% @doc Ends the logging of an activity (tool-internal use only).
@@ -410,7 +425,7 @@ add_external_logs(Logs) ->
%%% @doc Print a link to a given file stored in the priv_dir of the
%%% calling test suite.
add_link(Heading,File,Type) ->
- log(Heading,"<a href=\"~ts\" type=~p>~ts</a>\n",
+ log(Heading,"<a href=\"~ts\" type=~tp>~ts</a>\n",
[uri(filename:join("log_private",File)),Type,File]).
@@ -433,10 +448,10 @@ tc_log(Category,Importance,Format,Args,Opts) ->
tc_log(Category,Importance,"User",Format,Args,Opts).
%%%-----------------------------------------------------------------
-%%% @spec tc_log(Category,Importance,Printer,Format,Args,Opts) -> ok
+%%% @spec tc_log(Category,Importance,Heading,Format,Args,Opts) -> ok
%%% Category = atom()
%%% Importance = integer()
-%%% Printer = string()
+%%% Heading = string()
%%% Format = string()
%%% Args = list()
%%% Opts = list()
@@ -446,13 +461,18 @@ tc_log(Category,Importance,Format,Args,Opts) ->
%%% <p>This function is called by <code>ct</code> when logging
%%% stuff directly from a testcase (i.e. not from within the CT
%%% framework).</p>
-tc_log(Category,Importance,Printer,Format,Args,Opts) ->
+tc_log(Category,Importance,Heading,Format,Args,Opts) ->
Data =
case lists:member(no_css, Opts) of
true ->
[{Format,Args}];
false ->
- [{hd,div_header(Category,Printer),[]},
+ Heading1 =
+ case proplists:get_value(heading, Opts) of
+ undefined -> Heading;
+ Str -> Str
+ end,
+ [{hd,div_header(Category,Heading1),[]},
{Format,Args},
{ft,div_footer(),[]}]
end,
@@ -470,7 +490,7 @@ tc_log_async(Category,Format,Args) ->
%%% @spec tc_log_async(Category,Importance,Format,Args) -> ok
%%% Category = atom()
%%% Importance = integer()
-%%% Printer = string()
+%%% Heading = string()
%%% Format = string()
%%% Args = list()
%%%
@@ -481,31 +501,38 @@ tc_log_async(Category,Format,Args) ->
%%% to avoid deadlocks when e.g. the hook that handles SASL printouts
%%% prints to the test case log file at the same time test server
%%% asks ct_logs for an html wrapper.</p>
-tc_log_async(Category,Importance,Printer,Format,Args) ->
+tc_log_async(Category,Importance,Heading,Format,Args) ->
cast({log,async,self(),group_leader(),Category,Importance,
- [{hd,div_header(Category,Printer),[]},
+ [{hd,div_header(Category,Heading),[]},
{Format,Args},
{ft,div_footer(),[]}],
true}),
ok.
%%%-----------------------------------------------------------------
%%% @spec tc_print(Category,Format,Args)
-%%% @equiv tc_print(Category,?STD_IMPORTANCE,Format,Args)
+%%% @equiv tc_print(Category,?STD_IMPORTANCE,Format,Args,[])
tc_print(Category,Format,Args) ->
- tc_print(Category,?STD_IMPORTANCE,Format,Args).
+ tc_print(Category,?STD_IMPORTANCE,Format,Args,[]).
%%%-----------------------------------------------------------------
-%%% @spec tc_print(Category,Importance,Format,Args) -> ok
+%%% @spec tc_print(Category,Importance,Format,Args)
+%%% @equiv tc_print(Category,Importance,Format,Args,[])
+tc_print(Category,Importance,Format,Args) ->
+ tc_print(Category,Importance,Format,Args,[]).
+
+%%%-----------------------------------------------------------------
+%%% @spec tc_print(Category,Importance,Format,Args,Opts) -> ok
%%% Category = atom()
%%% Importance = integer()
%%% Format = string()
%%% Args = list()
+%%% Opts = list()
%%%
%%% @doc Console printout from a testcase.
%%%
%%% <p>This function is called by <code>ct</code> when printing
%%% stuff from a testcase on the user console.</p>
-tc_print(Category,Importance,Format,Args) ->
+tc_print(Category,Importance,Format,Args,Opts) ->
VLvl = case ct_util:get_verbosity(Category) of
undefined ->
ct_util:get_verbosity('$unspecified');
@@ -517,50 +544,61 @@ tc_print(Category,Importance,Format,Args) ->
Val
end,
if Importance >= (100-VLvl) ->
- Head = get_heading(Category),
- io:format(user, lists:concat([Head,Format,"\n\n"]), Args),
+ Heading =
+ case proplists:get_value(heading, Opts) of
+ undefined -> atom_to_list(Category);
+ Hd -> Hd
+ end,
+ Str = lists:concat([get_header(Heading),Format,"\n\n"]),
+ try
+ io:format(?def_gl, Str, Args)
+ catch
+ %% default group leader probably not started, or has stopped
+ _:_ -> io:format(user, Str, Args)
+ end,
ok;
true ->
ok
end.
-get_heading(default) ->
+get_header("default") ->
io_lib:format("\n-----------------------------"
"-----------------------\n~s\n",
[log_timestamp(?now)]);
-get_heading(Category) ->
+get_header(Heading) ->
io_lib:format("\n-----------------------------"
- "-----------------------\n~s ~w\n",
- [log_timestamp(?now),Category]).
+ "-----------------------\n~ts ~s\n",
+ [Heading,log_timestamp(?now)]).
%%%-----------------------------------------------------------------
%%% @spec tc_pal(Category,Format,Args) -> ok
-%%% @equiv tc_pal(Category,?STD_IMPORTANCE,Format,Args) -> ok
+%%% @equiv tc_pal(Category,?STD_IMPORTANCE,Format,Args,[]) -> ok
tc_pal(Category,Format,Args) ->
- tc_pal(Category,?STD_IMPORTANCE,Format,Args).
+ tc_pal(Category,?STD_IMPORTANCE,Format,Args,[]).
%%%-----------------------------------------------------------------
%%% @spec tc_pal(Category,Importance,Format,Args) -> ok
+%%% @equiv tc_pal(Category,Importance,Format,Args,[]) -> ok
+tc_pal(Category,Importance,Format,Args) ->
+ tc_pal(Category,Importance,Format,Args,[]).
+
+%%%-----------------------------------------------------------------
+%%% @spec tc_pal(Category,Importance,Format,Args,Opts) -> ok
%%% Category = atom()
%%% Importance = integer()
%%% Format = string()
%%% Args = list()
+%%% Opts = list()
%%%
%%% @doc Print and log from a testcase.
%%%
%%% <p>This function is called by <code>ct</code> when logging
%%% stuff directly from a testcase. The info is written both in the
%%% log and on the console.</p>
-tc_pal(Category,Importance,Format,Args) ->
- tc_print(Category,Importance,Format,Args),
- cast({log,sync,self(),group_leader(),Category,Importance,
- [{hd,div_header(Category),[]},
- {Format,Args},
- {ft,div_footer(),[]}],
- true}),
- ok.
-
+tc_pal(Category,Importance,Format,Args,Opts) ->
+ tc_print(Category,Importance,Format,Args,Opts),
+ tc_log(Category,Importance,"User",Format,Args,[esc_chars|Opts]).
%%%-----------------------------------------------------------------
%%% @spec ct_log(Category,Format,Args) -> ok
@@ -589,13 +627,12 @@ int_footer() ->
div_header(Class) ->
div_header(Class,"User").
-div_header(Class,Printer) ->
+div_header(Class,Heading) ->
"\n</pre>\n<div class=\"" ++ atom_to_list(Class) ++ "\"><pre><b>*** "
- ++ Printer ++ " " ++ log_timestamp(?now) ++ " ***</b>".
+ ++ Heading ++ " " ++ log_timestamp(?now) ++ " ***</b>".
div_footer() ->
"</pre></div>\n<pre>".
-
maybe_log_timestamp() ->
{MS,S,US} = ?now,
case get(log_timestamp) of
@@ -666,18 +703,18 @@ logger(Parent, Mode, Verbosity) ->
PrivFilesDestRun = [filename:join(AbsDir, F) || F <- PrivFiles],
case copy_priv_files(PrivFilesSrc, PrivFilesDestTop) of
{error,Src1,Dest1,Reason1} ->
- io:format(user, "ERROR! "++
- "Priv file ~p could not be copied to ~p. "++
- "Reason: ~p~n",
+ io:format(?def_gl, "ERROR! "++
+ "Priv file ~tp could not be copied to ~tp. "++
+ "Reason: ~tp~n",
[Src1,Dest1,Reason1]),
exit({priv_file_error,Dest1});
ok ->
case copy_priv_files(PrivFilesSrc, PrivFilesDestRun) of
{error,Src2,Dest2,Reason2} ->
- io:format(user,
+ io:format(?def_gl,
"ERROR! "++
- "Priv file ~p could not be copied to ~p. "
- ++"Reason: ~p~n",
+ "Priv file ~tp could not be copied to ~tp. "
+ ++"Reason: ~tp~n",
[Src2,Dest2,Reason2]),
exit({priv_file_error,Dest2});
ok ->
@@ -854,7 +891,7 @@ logger_loop(State) ->
logger_loop(State);
{set_stylesheet,TC,SSFile} ->
Fd = State#logger_state.ct_log_fd,
- io:format(Fd, "~p loading external style sheet: ~ts~n",
+ io:format(Fd, "~tp loading external style sheet: ~ts~n",
[TC,SSFile]),
logger_loop(State#logger_state{stylesheet = SSFile});
{clear_stylesheet,_} when State#logger_state.stylesheet == undefined ->
@@ -915,7 +952,7 @@ create_io_fun(FromPid, CtLogFd, EscChars) ->
[IoList,"\n",IoStr]
catch
_:_Reason ->
- io:format(CtLogFd, "Logging fails! Str: ~p, Args: ~p~n",
+ io:format(CtLogFd, "Logging fails! Str: ~tp, Args: ~tp~n",
[Str,Args]),
%% stop the testcase, we need to see the fault
exit(FromPid, {log_printout_error,Str,Args}),
@@ -1114,7 +1151,7 @@ open_ctlog(MiscIoName) ->
Dir = filename:dirname(Cwd),
Variables = ct_run:variables_file_name(Dir),
io:format(Fd,
- "Can not read the file \'~ts\' Reason: ~w\n"
+ "Can not read the file \'~ts\' Reason: ~tw\n"
"No configuration found for test!!\n",
[Variables,Reason])
end,
@@ -1176,7 +1213,7 @@ print_style(Fd, IoFormat, StyleSheet) ->
end.
print_style_error(Fd, IoFormat, StyleSheet, Reason) ->
- IO = io_lib:format("\n<!-- Failed to load stylesheet ~ts: ~p -->\n",
+ IO = io_lib:format("\n<!-- Failed to load stylesheet ~ts: ~tp -->\n",
[StyleSheet,Reason]),
IoFormat(Fd, IO, []),
print_style(Fd, IoFormat, undefined).
@@ -1219,11 +1256,11 @@ make_last_run_index(StartTime) ->
case catch make_last_run_index1(StartTime,IndexName) of
{'EXIT', Reason} ->
io:put_chars("CRASHED while updating " ++ AbsIndexName ++ "!\n"),
- io:format("~p~n", [Reason]),
+ io:format("~tp~n", [Reason]),
{error, Reason};
{error, Reason} ->
io:put_chars("FAILED while updating " ++ AbsIndexName ++ "\n"),
- io:format("~p~n", [Reason]),
+ io:format("~tp~n", [Reason]),
{error, Reason};
ok ->
ok;
@@ -1524,7 +1561,7 @@ get_missing_suites(_,_) ->
[].
term_to_text(Term) ->
- lists:flatten(io_lib:format("~p.\n", [Term])).
+ lists:flatten(io_lib:format("~tp.\n", [Term])).
%%% Headers and footers.
@@ -1792,7 +1829,7 @@ count_cases(Dir) ->
Summary
end;
{error, Reason} ->
- io:format("\nFailed to read ~p: ~p (skipped)\n",
+ io:format("\nFailed to read ~tp: ~tp (skipped)\n",
[LogFile,Reason]),
error
end
@@ -1874,10 +1911,10 @@ config_table_header() ->
config_table1([{Key,Value}|Vars]) ->
[xhtml(["<tr><td>", atom_to_list(Key), "</td>\n",
- "<td><pre>",io_lib:format("~p",[Value]),"</pre></td></tr>\n"],
+ "<td><pre>",io_lib:format("~tp",[Value]),"</pre></td></tr>\n"],
["<tr class=\"", odd_or_even(), "\">\n",
"<td>", atom_to_list(Key), "</td>\n",
- "<td>", io_lib:format("~p",[Value]), "</td>\n</tr>\n"]) |
+ "<td>", io_lib:format("~tp",[Value]), "</td>\n</tr>\n"]) |
config_table1(Vars)];
config_table1([]) ->
[xhtml("","</tbody>\n"),"</table>\n"].
@@ -1910,7 +1947,11 @@ make_all_runs_index(When) ->
end,
Dirs = filelib:wildcard(logdir_prefix()++"*.*"),
- DirsSorted = (catch sort_all_runs(Dirs)),
+ DirsSorted0 = (catch sort_all_runs(Dirs)),
+ DirsSorted =
+ if When == start -> DirsSorted0;
+ true -> maybe_delete_old_dirs(DirsSorted0)
+ end,
LogCacheInfo = get_cache_data(UseCache),
@@ -2028,6 +2069,36 @@ sort_ct_runs(Dirs) ->
{DateHH1,MM1,SS1} =< {DateHH2,MM2,SS2}
end, Dirs).
+parse_keep_logs([Str="all"]) ->
+ parse_keep_logs(list_to_atom(Str));
+parse_keep_logs([NStr]) ->
+ parse_keep_logs(list_to_integer(NStr));
+parse_keep_logs(all) ->
+ all;
+parse_keep_logs(N) when is_integer(N), N>0 ->
+ N.
+
+maybe_delete_old_dirs(Sorted) ->
+ {Keep,Delete} =
+ case application:get_env(common_test, keep_logs) of
+ {ok,MaxN} when is_integer(MaxN), length(Sorted)>MaxN ->
+ lists:split(MaxN,Sorted);
+ _ ->
+ {Sorted,[]}
+ end,
+ delete_old_dirs(Delete),
+ Keep.
+
+delete_old_dirs([]) ->
+ ok;
+delete_old_dirs(Dirs) ->
+ io:put_chars("\n Removing old test directories:\n"),
+ [begin
+ io:put_chars(" " ++ Dir ++ "\n"),
+ rm_dir(Dir)
+ end|| Dir <- Dirs],
+ ok.
+
dir_diff_all_runs(Dirs, LogCache) ->
case LogCache#log_cache.all_runs of
[] ->
@@ -2403,17 +2474,17 @@ make_all_suites_index(NewTestData = {_TestName,DirName}) ->
LogDirData) of
{'EXIT',Reason} ->
io:put_chars("CRASHED while updating " ++ AbsIndexName ++ "!\n"),
- io:format("~p~n", [Reason]),
+ io:format("~tp~n", [Reason]),
{error,Reason};
{error,Reason} ->
io:put_chars("FAILED while updating " ++ AbsIndexName ++ "\n"),
- io:format("~p~n", [Reason]),
+ io:format("~tp~n", [Reason]),
{error,Reason};
ok ->
ok;
Err ->
io:format("Unknown internal error while updating ~ts. "
- "Please report.\n(Err: ~p, ID: 1)",
+ "Please report.\n(Err: ~tp, ID: 1)",
[AbsIndexName,Err]),
{error, Err}
end,
@@ -2632,11 +2703,11 @@ make_all_suites_index1(When, AbsIndexName, AllTestLogDirs) ->
case catch make_all_suites_index2(IndexName, AllTestLogDirs) of
{'EXIT', Reason} ->
io:put_chars("CRASHED while updating " ++ AbsIndexName ++ "!\n"),
- io:format("~p~n", [Reason]),
+ io:format("~tp~n", [Reason]),
{error, Reason};
{error, Reason} ->
io:put_chars("FAILED while updating " ++ AbsIndexName ++ "\n"),
- io:format("~p~n", [Reason]),
+ io:format("~tp~n", [Reason]),
{error, Reason};
{ok,TempData} ->
case When of
@@ -2650,7 +2721,7 @@ make_all_suites_index1(When, AbsIndexName, AllTestLogDirs) ->
end;
Err ->
io:format("Unknown internal error while updating ~ts. "
- "Please report.\n(Err: ~p, ID: 1)",
+ "Please report.\n(Err: ~tp, ID: 1)",
[AbsIndexName,Err]),
{error, Err}
end.
@@ -3129,7 +3200,7 @@ get_ts_html_wrapper(TestName, Logdir, PrintLabel, Cwd, TableCols, Encoding) ->
TestName1 = if is_list(TestName) ->
lists:flatten(TestName);
true ->
- lists:flatten(io_lib:format("~p", [TestName]))
+ lists:flatten(io_lib:format("~tp", [TestName]))
end,
Basic = basic_html(),
LabelStr =
diff --git a/lib/common_test/src/ct_make.erl b/lib/common_test/src/ct_make.erl
index e7a9cfa843..4d66796b83 100644
--- a/lib/common_test/src/ct_make.erl
+++ b/lib/common_test/src/ct_make.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -96,7 +96,7 @@ read_emakefile(Emakefile,Opts) ->
Mods = [filename:rootname(F) || F <- filelib:wildcard("*.erl")],
[{Mods, Opts}];
{error,Other} ->
- io:format("make: Trouble reading 'Emakefile':~n~p~n",[Other]),
+ io:format("make: Trouble reading 'Emakefile':~n~tp~n",[Other]),
error
end.
@@ -151,7 +151,7 @@ get_opts_from_emakefile(Mods,Emakefile,Opts) ->
{error,enoent} ->
[{Mods, Opts}];
{error,Other} ->
- io:format("make: Trouble reading 'Emakefile':~n~p~n",[Other]),
+ io:format("make: Trouble reading 'Emakefile':~n~tp~n",[Other]),
error
end.
@@ -342,5 +342,7 @@ check_includes2(Epp, File, ObjMTime) ->
epp:close(Epp),
false;
{error, _Error} ->
+ check_includes2(Epp, File, ObjMTime);
+ {warning, _Warning} ->
check_includes2(Epp, File, ObjMTime)
end.
diff --git a/lib/common_test/src/ct_master.erl b/lib/common_test/src/ct_master.erl
index 4eef27d2a5..6e6d1879c2 100644
--- a/lib/common_test/src/ct_master.erl
+++ b/lib/common_test/src/ct_master.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -434,7 +434,7 @@ init_master1(Parent,NodeOptsList,InitOptions,LogDirs) ->
init_master2(Parent,NodeOptsList,LogDirs) ->
process_flag(trap_exit,true),
Cookie = erlang:get_cookie(),
- log(all,"Cookie","~w",[Cookie]),
+ log(all,"Cookie","~tw",[Cookie]),
log(all,"Starting Tests",
"Tests starting on: ~p",[[N || {N,_} <- NodeOptsList]]),
SpawnAndMon =
@@ -454,7 +454,7 @@ master_loop(#state{node_ctrl_pids=[],
results=Finished}) ->
Str =
lists:map(fun({Node,Result}) ->
- io_lib:format("~-40.40.*ts~p\n",
+ io_lib:format("~-40.40.*ts~tp\n",
[$_,atom_to_list(Node),Result])
end,lists:reverse(Finished)),
log(all,"TEST RESULTS",Str,[]),
@@ -488,7 +488,7 @@ master_loop(State=#state{node_ctrl_pids=NodeCtrlPids,
Bad
end,
log(all,"Test Info",
- "Test on node ~w failed! Reason: ~p",
+ "Test on node ~w failed! Reason: ~tp",
[Node,Error]),
{Locks1,Blocked1} =
update_queue(exit,Node,Locks,Blocked),
@@ -501,7 +501,7 @@ master_loop(State=#state{node_ctrl_pids=NodeCtrlPids,
undefined ->
%% ignore (but report) exit from master_logger etc
log(all,"Test Info",
- "Warning! Process ~w has terminated. Reason: ~p",
+ "Warning! Process ~w has terminated. Reason: ~tp",
[Pid,Reason]),
master_loop(State)
end;
@@ -584,7 +584,7 @@ update_queue(take,Node,From,Lock={Op,Resource},Locks,Blocked) ->
%% Blocked: [{{Operation,Resource},Node,WaitingPid},...]
case lists:keysearch(Lock,1,Locks) of
{value,{_Lock,Owner}} -> % other node has lock
- log(html,"Lock Info","Node ~w blocked on ~w by ~w. Resource: ~p",
+ log(html,"Lock Info","Node ~w blocked on ~w by ~w. Resource: ~tp",
[Node,Op,Owner,Resource]),
Blocked1 = Blocked ++ [{Lock,Node,From}],
{Locks,Blocked1};
@@ -599,7 +599,7 @@ update_queue(release,Node,_From,Lock={Op,Resource},Locks,Blocked) ->
case lists:keysearch(Lock,1,Blocked) of
{value,E={Lock,SomeNode,WaitingPid}} ->
Blocked1 = lists:delete(E,Blocked),
- log(html,"Lock Info","Node ~w proceeds with ~w. Resource: ~p",
+ log(html,"Lock Info","Node ~w proceeds with ~w. Resource: ~tp",
[SomeNode,Op,Resource]),
reply(ok,WaitingPid), % waiting process may start
{Locks1,Blocked1};
@@ -678,7 +678,7 @@ refresh_logs([D|Dirs],Refreshed) ->
refresh_logs([],Refreshed) ->
Str =
lists:map(fun({D,Result}) ->
- io_lib:format("Refreshing logs in ~p... ~p",
+ io_lib:format("Refreshing logs in ~tp... ~tp",
[D,Result])
end,Refreshed),
log(all,"Info",Str,[]).
@@ -712,7 +712,7 @@ init_node_ctrl(MasterPid,Cookie,Opts) ->
{ok, _} = start_ct_event(),
ct_event:add_handler([{master,MasterPid}]),
- %% log("Running test with options: ~p~n", [Opts]),
+ %% log("Running test with options: ~tp~n", [Opts]),
Result = case (catch ct:run_test(Opts)) of
ok -> finished_ok;
Other -> Other
@@ -828,7 +828,7 @@ start_nodes(InitOptions)->
"with callback ~w~n", [NodeName,Callback]);
{error, Reason, _NodeName} ->
io:format("Failed to start node ~w with callback ~w! "
- "Reason: ~p~n", [NodeName, Callback, Reason])
+ "Reason: ~tp~n", [NodeName, Callback, Reason])
end;
{true, true}->
io:format("WARNING: Node ~w is alive but has node_start "
@@ -857,10 +857,10 @@ eval_on_nodes(InitOptions)->
evaluate(Node, [{M,F,A}|MFAs])->
case rpc:call(Node, M, F, A) of
{badrpc,Reason}->
- io:format("WARNING: Failed to call ~w:~w/~w on node ~w "
- "due to ~p~n", [M,F,length(A),Node,Reason]);
+ io:format("WARNING: Failed to call ~w:~tw/~w on node ~w "
+ "due to ~tp~n", [M,F,length(A),Node,Reason]);
Result->
- io:format("Called ~w:~w/~w on node ~w, result: ~p~n",
+ io:format("Called ~w:~tw/~w on node ~w, result: ~tp~n",
[M,F,length(A),Node,Result])
end,
evaluate(Node, MFAs);
diff --git a/lib/common_test/src/ct_master_event.erl b/lib/common_test/src/ct_master_event.erl
index d28ef42c20..d535d1274e 100644
--- a/lib/common_test/src/ct_master_event.erl
+++ b/lib/common_test/src/ct_master_event.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -71,7 +71,7 @@ stop() ->
{error,Reason} ->
ct_master_logs:log("Error",
"No response from CT Master Event.\n"
- "Reason = ~p\n"
+ "Reason = ~tp\n"
"Terminating now!\n",[Reason]),
%% communication with event manager fails, kill it
catch exit(whereis(?CT_MEVMGR_REF), kill);
@@ -135,7 +135,7 @@ handle_event(#event{name=start_logging,node=Node,data=RunDir},State) ->
handle_event(#event{name=Name,node=Node,data=Data},State) ->
print("~n=== ~w ===~n", [?MODULE]),
- print("~w on ~w: ~p~n", [Name,Node,Data]),
+ print("~tw on ~w: ~tp~n", [Name,Node,Data]),
{ok,State}.
%%--------------------------------------------------------------------
diff --git a/lib/common_test/src/ct_master_logs.erl b/lib/common_test/src/ct_master_logs.erl
index 52003f752d..d8ecd641ed 100644
--- a/lib/common_test/src/ct_master_logs.erl
+++ b/lib/common_test/src/ct_master_logs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -110,16 +110,16 @@ init(Parent,LogDir,Nodes) ->
case copy_priv_files(PrivFilesSrc, PrivFilesDestTop) of
{error,Src1,Dest1,Reason1} ->
io:format(user, "ERROR! "++
- "Priv file ~p could not be copied to ~p. "++
- "Reason: ~p~n",
+ "Priv file ~tp could not be copied to ~tp. "++
+ "Reason: ~tp~n",
[Src1,Dest1,Reason1]),
exit({priv_file_error,Dest1});
ok ->
case copy_priv_files(PrivFilesSrc, PrivFilesDestRun) of
{error,Src2,Dest2,Reason2} ->
io:format(user, "ERROR! "++
- "Priv file ~p could not be copied to ~p. "++
- "Reason: ~p~n",
+ "Priv file ~tp could not be copied to ~tp. "++
+ "Reason: ~tp~n",
[Src2,Dest2,Reason2]),
exit({priv_file_error,Dest2});
ok ->
@@ -170,7 +170,7 @@ loop(State) ->
case catch io:format(Fd,Str++"\n",Args) of
{'EXIT',Reason} ->
io:format(Fd,
- "Logging fails! Str: ~p, Args: ~p~n",
+ "Logging fails! Str: ~tp, Args: ~tp~n",
[Str,Args]),
exit({logging_failed,Reason}),
ok;
diff --git a/lib/common_test/src/ct_master_status.erl b/lib/common_test/src/ct_master_status.erl
index 7d3e54e645..b27fdd341e 100644
--- a/lib/common_test/src/ct_master_status.erl
+++ b/lib/common_test/src/ct_master_status.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -71,7 +71,7 @@ init(_) ->
%%
handle_event(#event{name=Name,node=Node,data=Data},State) ->
print("~n=== ~w ===~n", [?MODULE]),
- print("~w on ~w: ~p~n", [Name,Node,Data]),
+ print("~tw on ~w: ~tp~n", [Name,Node,Data]),
{ok,State}.
%%--------------------------------------------------------------------
diff --git a/lib/common_test/src/ct_netconfc.erl b/lib/common_test/src/ct_netconfc.erl
index ff45407fe0..2c4b97df20 100644
--- a/lib/common_test/src/ct_netconfc.erl
+++ b/lib/common_test/src/ct_netconfc.erl
@@ -1,7 +1,7 @@
%%----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -23,24 +23,15 @@
%% Description:
%% This file contains the Netconf client interface
%%
-%% @author Support
+%% Netconf servers can be configured by adding the following statement
+%% to a configuration file:
%%
-%% @doc Netconf client module.
+%% {server_id(),options()}.
%%
-%% <p>The Netconf client is compliant with RFC4741 and RFC4742.</p>
+%% The server_id() or an associated ct:target_name() shall then be
+%% used in calls to open/2 connect/2.
%%
-%% <p> For each server to test against, the following entry can be
-%% added to a configuration file:</p>
-%%
-%% <p>`{server_id(),options()}.'</p>
-%%
-%% <p> The `server_id()' or an associated `target_name()' (see
-%% {@link ct}) shall then be used in calls to {@link open/2}.</p>
-%%
-%% <p>If no configuration exists for a server, a session can still be
-%% opened by calling {@link open/2} with all necessary options given
-%% in the call. The first argument to {@link open/2} can then be any
-%% atom.</p>
+%% If no configuration exists for a server, use open/1 and connect/1.
%%
%% == Logging ==
%%
@@ -49,102 +40,15 @@
%% `ct_conn_log_h'. To use this error handler, add the `cth_conn_log'
%% hook in your test suite, e.g.
%%
-%% ```
%% suite() ->
-%% [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}].
-%%'''
-%%
-%% The `conn_mod()' is the name of the common_test module implementing
-%% the connection protocol, e.g. `ct_netconfc'.
-%%
-%% The hook option `log_type' specifies the type of logging:
-%%
-%% <dl>
-%% <dt>`raw'</dt>
-%% <dd>The sent and received netconf data is logged to a separate
-%% text file as is without any formatting. A link to the file is
-%% added to the test case HTML log.</dd>
-%%
-%% <dt>`pretty'</dt>
-%% <dd>The sent and received netconf data is logged to a separate
-%% text file with XML data nicely indented. A link to the file is
-%% added to the test case HTML log.</dd>
-%%
-%% <dt>`html (default)'</dt>
-%% <dd>The sent and received netconf traffic is pretty printed
-%% directly in the test case HTML log.</dd>
-%%
-%% <dt>`silent'</dt>
-%% <dd>Netconf traffic is not logged.</dd>
-%% </dl>
-%%
-%% By default, all netconf traffic is logged in one single log
-%% file. However, it is possible to have different connections logged
-%% in separate files. To do this, use the hook option `hosts' and
-%% list the names of the servers/connections that will be used in the
-%% suite. Note that the connections must be named for this to work,
-%% i.e. they must be opened with {@link open/2}.
-%%
-%% The `hosts' option has no effect if `log_type' is set to `html' or
-%% `silent'.
-%%
-%% The hook options can also be specified in a configuration file with
-%% the configuration variable `ct_conn_log':
-%%
-%% ```
-%% {ct_conn_log,[{conn_mod(),hook_options()}]}.
-%% '''
+%% [{ct_hooks, [{cth_conn_log, [{ct:conn_log_mod(),ct:conn_log_options()}]}]}].
%%
%% For example:
%%
-%% ```
-%% {ct_conn_log,[{ct_netconfc,[{log_type,pretty},
-%% {hosts,[key_or_name()]}]}]}
-%% '''
-%%
-%% <b>Note</b> that hook options specified in a configuration file
-%% will overwrite the hardcoded hook options in the test suite.
-%%
-%% === Logging example 1 ===
-%%
-%% The following `ct_hooks' statement will cause pretty printing of
-%% netconf traffic to separate logs for the connections named
-%% `nc_server1' and `nc_server2'. Any other connections will be logged
-%% to default netconf log.
-%%
-%% ```
%% suite() ->
-%% [{ct_hooks, [{cth_conn_log, [{ct_netconfc,[{log_type,pretty}},
-%% {hosts,[nc_server1,nc_server2]}]}
-%% ]}]}].
-%%'''
-%%
-%% Connections must be opened like this:
-%%
-%% ```
-%% open(nc_server1,[...]),
-%% open(nc_server2,[...]).
-%% '''
-%%
-%% === Logging example 2 ===
-%%
-%% The following configuration file will cause raw logging of all
-%% netconf traffic into one single text file.
-%%
-%% ```
-%% {ct_conn_log,[{ct_netconfc,[{log_type,raw}]}]}.
-%% '''
-%%
-%% The `ct_hooks' statement must look like this:
-%%
-%% ```
-%% suite() ->
-%% [{ct_hooks, [{cth_conn_log, []}]}].
-%% '''
-%%
-%% The same `ct_hooks' statement without the configuration file would
-%% cause HTML logging of all netconf connections into the test case
-%% HTML log.
+%% [{ct_hooks,
+%% [{cth_conn_log,[{ct_netconfc,[{log_type,pretty},
+%% {hosts,[my_configured_server]}]}]}
%%
%% == Notifications ==
%%
@@ -152,11 +56,9 @@
%% Notifications, which defines a mechanism for an asynchronous
%% message notification delivery service for the netconf protocol.
%%
-%% Specific functions to support this are {@link
-%% create_subscription/6} and {@link get_event_streams/3}. (The
-%% functions also exist with other arities.)
+%% Specific functions to support this are create_subscription/6
+%% get_event_streams/3. (The functions also exist with other arities.)
%%
-%% @end
%%----------------------------------------------------------------------
-module(ct_netconfc).
@@ -167,7 +69,13 @@
%%----------------------------------------------------------------------
%% External exports
%%----------------------------------------------------------------------
--export([open/1,
+-export([connect/1,
+ connect/2,
+ disconnect/1,
+ session/1,
+ session/2,
+ session/3,
+ open/1,
open/2,
only_open/1,
only_open/2,
@@ -205,6 +113,7 @@
create_subscription/4,
create_subscription/5,
create_subscription/6,
+ get_event_streams/1,
get_event_streams/2,
get_event_streams/3,
get_capabilities/1,
@@ -215,7 +124,9 @@
%%----------------------------------------------------------------------
%% Exported types
%%----------------------------------------------------------------------
--export_type([notification/0]).
+-export_type([client/0,
+ handle/0,
+ notification/0]).
%%----------------------------------------------------------------------
%% Internal exports
@@ -273,13 +184,15 @@
host,
port = ?DEFAULT_PORT,
timeout = ?DEFAULT_TIMEOUT,
- name}).
+ name,
+ type}).
%% Connection reference
-record(connection, {reference, % {CM,Ch}
host,
port,
- name}).
+ name,
+ type}).
%% Pending replies from server
-record(pending, {tref, % timer ref (returned from timer:xxx)
@@ -291,17 +204,17 @@
%%----------------------------------------------------------------------
%% Type declarations
%%----------------------------------------------------------------------
--type client() :: handle() | ct_gen_conn:server_id() | ct_gen_conn:target_name().
--type handle() :: term().
-%% An opaque reference for a connection (netconf session). See {@link
-%% ct} for more information.
+-type client() :: handle() | server_id() | ct:target_name().
+-opaque handle() :: pid().
-type options() :: [option()].
-%% Options used for setting up ssh connection to a netconf server.
-
-type option() :: {ssh,host()} | {port,inet:port_number()} | {user,string()} |
{password,string()} | {user_dir,string()} |
{timeout,timeout()}.
+
+-type session_options() :: [session_option()].
+-type session_option() :: {timeout,timeout()}.
+
-type host() :: inet:hostname() | inet:ip_address().
-type notification() :: {notification, xml_attributes(), notification_content()}.
@@ -317,14 +230,13 @@
%% See XML Schema for Event Notifications found in RFC5277 for further
%% detail about the data format for the string values.
-%-type error_handler() :: module().
-type error_reason() :: term().
+-type server_id() :: atom().
+
-type simple_xml() :: {xml_tag(), xml_attributes(), xml_content()} |
{xml_tag(), xml_content()} |
xml_tag().
-%% <p>This type is further described in the documentation for the
-%% <tt>Xmerl</tt> application.</p>
-type xml_tag() :: atom().
-type xml_attributes() :: [{xml_attribute_tag(),xml_attribute_value()}].
-type xml_attribute_tag() :: atom().
@@ -336,69 +248,130 @@
-type xs_datetime() :: string().
%% This date and time identifyer has the same format as the XML type
%% dateTime and compliant to RFC3339. The format is
-%% ```[-]CCYY-MM-DDThh:mm:ss[.s][Z|(+|-)hh:mm]'''
+%% "[-]CCYY-MM-DDThh:mm:ss[.s][Z|(+|-)hh:mm]"
%%----------------------------------------------------------------------
%% External interface functions
%%----------------------------------------------------------------------
%%----------------------------------------------------------------------
--spec open(Options) -> Result when
+%% Open an SSH connection to a Netconf server
+%% If the server options are specified in a configuration file, use
+%% open/2.
+-spec connect(Options) -> Result when
Options :: options(),
Result :: {ok,handle()} | {error,error_reason()}.
-%% @doc Open a netconf session and exchange `hello' messages.
-%%
-%% If the server options are specified in a configuration file, or if
-%% a named client is needed for logging purposes (see {@section
-%% Logging}) use {@link open/2} instead.
-%%
-%% The opaque `handler()' reference which is returned from this
-%% function is required as client identifier when calling any other
-%% function in this module.
-%%
-%% The `timeout' option (milli seconds) is used when setting up
-%% the ssh connection and when waiting for the hello message from the
-%% server. It is not used for any other purposes during the lifetime
-%% of the connection.
-%%
-%% @end
+connect(Options) ->
+ do_connect(Options, #options{type=connection},[]).
+
+-spec connect(KeyOrName,ExtraOptions) -> Result when
+ KeyOrName :: ct:key_or_name(),
+ ExtraOptions :: options(),
+ Result :: {ok,handle()} | {error,error_reason()}.
+connect(KeyOrName, ExtraOptions) ->
+ SortedExtra = lists:keysort(1,ExtraOptions),
+ SortedConfig = lists:keysort(1,ct:get_config(KeyOrName,[])),
+ AllOpts = lists:ukeymerge(1,SortedConfig,SortedExtra),
+ do_connect(AllOpts,#options{name=KeyOrName,type=connection},[{name,KeyOrName}]).
+
+do_connect(OptList,InitOptRec,NameOpt) ->
+ case check_options(OptList,InitOptRec) of
+ {Host,Port,Options} ->
+ ct_gen_conn:start({Host,Port},Options,?MODULE,
+ NameOpt ++ [{reconnect,false},
+ {use_existing_connection,false},
+ {forward_messages,false}]);
+ Error ->
+ Error
+ end.
+
%%----------------------------------------------------------------------
-open(Options) ->
- open(Options,#options{},[],true).
+%% Close the given SSH connection.
+-spec disconnect(Conn) -> ok | {error,error_reason()} when
+ Conn :: handle().
+disconnect(Conn) ->
+ case call(Conn,get_ssh_connection) of
+ {ok,_} ->
+ ct_gen_conn:stop(Conn);
+ Error ->
+ Error
+ end.
%%----------------------------------------------------------------------
+%% Open a netconf session as a channel on the given SSH connection,
+%% and exchange `hello' messages.
+-spec session(Conn) -> Result when
+ Conn :: handle(),
+ Result :: {ok,handle()} | {error,error_reason()}.
+session(Conn) ->
+ do_session(Conn,[],#options{type=channel},[]).
+
+-spec session(Conn,Options) -> Result when
+ Conn :: handle(),
+ Options :: session_options(),
+ Result :: {ok,handle()} | {error,error_reason()};
+ (KeyOrName,Conn) -> Result when
+ KeyOrName :: ct:key_or_name(),
+ Conn :: handle(),
+ Result :: {ok,handle()} | {error,error_reason()}.
+session(Conn,Options) when is_list(Options) ->
+ do_session(Conn,Options,#options{type=channel},[]);
+session(KeyOrName,Conn) ->
+ do_session(Conn,[],#options{name=KeyOrName,type=channel},[{name,KeyOrName}]).
+
+-spec session(KeyOrName,Conn,Options) -> Result when
+ Conn :: handle(),
+ Options :: session_options(),
+ KeyOrName :: ct:key_or_name(),
+ Result :: {ok,handle()} | {error,error_reason()}.
+session(KeyOrName,Conn,ExtraOptions) ->
+ SortedExtra = lists:keysort(1,ExtraOptions),
+ SortedConfig = lists:keysort(1,ct:get_config(KeyOrName,[])),
+ AllOpts = lists:ukeymerge(1,SortedConfig,SortedExtra),
+ do_session(Conn,AllOpts,#options{name=KeyOrName,type=channel},
+ [{name,KeyOrName}]).
+
+do_session(Conn,OptList,InitOptRec,NameOpt) ->
+ case call(Conn,get_ssh_connection) of
+ {ok,SshConn} ->
+ case check_session_options(OptList,InitOptRec) of
+ {ok,Options} ->
+ case ct_gen_conn:start(SshConn,Options,?MODULE,
+ NameOpt ++
+ [{reconnect,false},
+ {use_existing_connection,false},
+ {forward_messages,true}]) of
+ {ok,Client} ->
+ case hello(Client,Options#options.timeout) of
+ ok ->
+ {ok,Client};
+ Error ->
+ Error
+ end;
+ Error ->
+ Error
+ end;
+ Error ->
+ Error
+ end;
+ Error ->
+ Error
+ end.
+
+%%----------------------------------------------------------------------
+%% Open a netconf session and exchange 'hello' messages.
+%% If the server options are specified in a configuration file, use
+%% open/2.
+-spec open(Options) -> Result when
+ Options :: options(),
+ Result :: {ok,handle()} | {error,error_reason()}.
+open(Options) ->
+ open(Options,#options{type=connection_and_channel},[],true).
+
-spec open(KeyOrName, ExtraOptions) -> Result when
- KeyOrName :: ct_gen_conn:key_or_name(),
+ KeyOrName :: ct:key_or_name(),
ExtraOptions :: options(),
Result :: {ok,handle()} | {error,error_reason()}.
-%% @doc Open a named netconf session and exchange `hello' messages.
-%%
-%% If `KeyOrName' is a configured `server_id()' or a
-%% `target_name()' associated with such an ID, then the options
-%% for this server will be fetched from the configuration file.
-%
-%% The `ExtraOptions' argument will be added to the options found in
-%% the configuration file. If the same options are given, the values
-%% from the configuration file will overwrite `ExtraOptions'.
-%%
-%% If the server is not specified in a configuration file, use {@link
-%% open/1} instead.
-%%
-%% The opaque `handle()' reference which is returned from this
-%% function can be used as client identifier when calling any other
-%% function in this module. However, if `KeyOrName' is a
-%% `target_name()', i.e. if the server is named via a call to
-%% `ct:require/2' or a `require' statement in the test
-%% suite, then this name may be used instead of the `handle()'.
-%%
-%% The `timeout' option (milli seconds) is used when setting up
-%% the ssh connection and when waiting for the hello message from the
-%% server. It is not used for any other purposes during the lifetime
-%% of the connection.
-%%
-%% @see ct:require/2
-%% @end
-%%----------------------------------------------------------------------
open(KeyOrName, ExtraOpts) ->
open(KeyOrName, ExtraOpts, true).
@@ -406,10 +379,11 @@ open(KeyOrName, ExtraOpts, Hello) ->
SortedExtra = lists:keysort(1,ExtraOpts),
SortedConfig = lists:keysort(1,ct:get_config(KeyOrName,[])),
AllOpts = lists:ukeymerge(1,SortedConfig,SortedExtra),
- open(AllOpts,#options{name=KeyOrName},[{name,KeyOrName}],Hello).
+ open(AllOpts,#options{name=KeyOrName,type=connection_and_channel},
+ [{name,KeyOrName}],Hello).
open(OptList,InitOptRec,NameOpt,Hello) ->
- case check_options(OptList,undefined,undefined,InitOptRec) of
+ case check_options(OptList,InitOptRec) of
{Host,Port,Options} ->
case ct_gen_conn:start({Host,Port},Options,?MODULE,
NameOpt ++ [{reconnect,false},
@@ -431,296 +405,206 @@ open(OptList,InitOptRec,NameOpt,Hello) ->
%%----------------------------------------------------------------------
+%% As open/1,2, except no 'hello' message is sent.
-spec only_open(Options) -> Result when
Options :: options(),
Result :: {ok,handle()} | {error,error_reason()}.
-%% @doc Open a netconf session, but don't send `hello'.
-%%
-%% As {@link open/1} but does not send a `hello' message.
-%%
-%% @end
-%%----------------------------------------------------------------------
only_open(Options) ->
- open(Options,#options{},[],false).
+ open(Options,#options{type=connection_and_channel},[],false).
-%%----------------------------------------------------------------------
-spec only_open(KeyOrName,ExtraOptions) -> Result when
- KeyOrName :: ct_gen_conn:key_or_name(),
+ KeyOrName :: ct:key_or_name(),
ExtraOptions :: options(),
Result :: {ok,handle()} | {error,error_reason()}.
-%% @doc Open a name netconf session, but don't send `hello'.
-%%
-%% As {@link open/2} but does not send a `hello' message.
-%%
-%% @end
-%%----------------------------------------------------------------------
only_open(KeyOrName, ExtraOpts) ->
open(KeyOrName, ExtraOpts, false).
%%----------------------------------------------------------------------
-%% @spec hello(Client) -> Result
-%% @equiv hello(Client, [], infinity)
+%% Send a 'hello' message.
+-spec hello(Client) -> Result when
+ Client :: handle(),
+ Result :: ok | {error,error_reason()}.
hello(Client) ->
hello(Client,[],?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec hello(Client,Timeout) -> Result when
Client :: handle(),
Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
-%% @spec hello(Client, Timeout) -> Result
-%% @equiv hello(Client, [], Timeout)
hello(Client,Timeout) ->
hello(Client,[],Timeout).
-%%----------------------------------------------------------------------
-spec hello(Client,Options,Timeout) -> Result when
Client :: handle(),
Options :: [{capability, [string()]}],
Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
-%% @doc Exchange `hello' messages with the server.
-%%
-%% Adds optional capabilities and sends a `hello' message to the
-%% server and waits for the return.
-%% @end
-%%----------------------------------------------------------------------
hello(Client,Options,Timeout) ->
call(Client, {hello, Options, Timeout}).
%%----------------------------------------------------------------------
-%% @spec get_session_id(Client) -> Result
-%% @equiv get_session_id(Client, infinity)
+%% Get the session id for the session specified by Client.
+-spec get_session_id(Client) -> Result when
+ Client :: client(),
+ Result :: pos_integer() | {error,error_reason()}.
get_session_id(Client) ->
get_session_id(Client, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec get_session_id(Client, Timeout) -> Result when
Client :: client(),
Timeout :: timeout(),
Result :: pos_integer() | {error,error_reason()}.
-%% @doc Returns the session id associated with the given client.
-%%
-%% @end
-%%----------------------------------------------------------------------
get_session_id(Client, Timeout) ->
call(Client, get_session_id, Timeout).
%%----------------------------------------------------------------------
-%% @spec get_capabilities(Client) -> Result
-%% @equiv get_capabilities(Client, infinity)
+%% Get the server side capabilities.
+-spec get_capabilities(Client) -> Result when
+ Client :: client(),
+ Result :: [string()] | {error,error_reason()}.
get_capabilities(Client) ->
get_capabilities(Client, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec get_capabilities(Client, Timeout) -> Result when
Client :: client(),
Timeout :: timeout(),
Result :: [string()] | {error,error_reason()}.
-%% @doc Returns the server side capabilities
-%%
-%% The following capability identifiers, defined in RFC 4741, can be returned:
-%%
-%% <ul>
-%% <li>`"urn:ietf:params:netconf:base:1.0"'</li>
-%% <li>`"urn:ietf:params:netconf:capability:writable-running:1.0"'</li>
-%% <li>`"urn:ietf:params:netconf:capability:candidate:1.0"'</li>
-%% <li>`"urn:ietf:params:netconf:capability:confirmed-commit:1.0"'</li>
-%% <li>`"urn:ietf:params:netconf:capability:rollback-on-error:1.0"'</li>
-%% <li>`"urn:ietf:params:netconf:capability:startup:1.0"'</li>
-%% <li>`"urn:ietf:params:netconf:capability:url:1.0"'</li>
-%% <li>`"urn:ietf:params:netconf:capability:xpath:1.0"'</li>
-%% </ul>
-%%
-%% Note, additional identifiers may exist, e.g. server side namespace.
-%%
-%% @end
-%%----------------------------------------------------------------------
get_capabilities(Client, Timeout) ->
call(Client, get_capabilities, Timeout).
%%----------------------------------------------------------------------
-%% @spec send(Client, SimpleXml) -> Result
-%% @equiv send(Client, SimpleXml, infinity)
+%% Send an XML document to the server.
+-spec send(Client, SimpleXml) -> Result when
+ Client :: client(),
+ SimpleXml :: simple_xml(),
+ Result :: simple_xml() | {error,error_reason()}.
send(Client, SimpleXml) ->
send(Client, SimpleXml, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec send(Client, SimpleXml, Timeout) -> Result when
Client :: client(),
SimpleXml :: simple_xml(),
Timeout :: timeout(),
Result :: simple_xml() | {error,error_reason()}.
-%% @doc Send an XML document to the server.
-%%
-%% The given XML document is sent as is to the server. This function
-%% can be used for sending XML documents that can not be expressed by
-%% other interface functions in this module.
send(Client, SimpleXml, Timeout) ->
call(Client,{send, Timeout, SimpleXml}).
%%----------------------------------------------------------------------
-%% @spec send_rpc(Client, SimpleXml) -> Result
-%% @equiv send_rpc(Client, SimpleXml, infinity)
+%% Wrap the given XML document in a valid netconf 'rpc' request and
+%% send to the server.
+-spec send_rpc(Client, SimpleXml) -> Result when
+ Client :: client(),
+ SimpleXml :: simple_xml(),
+ Result :: [simple_xml()] | {error,error_reason()}.
send_rpc(Client, SimpleXml) ->
send_rpc(Client, SimpleXml, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec send_rpc(Client, SimpleXml, Timeout) -> Result when
Client :: client(),
SimpleXml :: simple_xml(),
Timeout :: timeout(),
Result :: [simple_xml()] | {error,error_reason()}.
-%% @doc Send a Netconf <code>rpc</code> request to the server.
-%%
-%% The given XML document is wrapped in a valid Netconf
-%% <code>rpc</code> request and sent to the server. The
-%% <code>message-id</code> and namespace attributes are added to the
-%% <code>rpc</code> element.
-%%
-%% This function can be used for sending <code>rpc</code> requests
-%% that can not be expressed by other interface functions in this
-%% module.
send_rpc(Client, SimpleXml, Timeout) ->
call(Client,{send_rpc, SimpleXml, Timeout}).
%%----------------------------------------------------------------------
-%% @spec lock(Client, Target) -> Result
-%% @equiv lock(Client, Target, infinity)
+%% Send a 'lock' request.
+-spec lock(Client, Target) -> Result when
+ Client :: client(),
+ Target :: netconf_db(),
+ Result :: ok | {error,error_reason()}.
lock(Client, Target) ->
lock(Client, Target,?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec lock(Client, Target, Timeout) -> Result when
Client :: client(),
Target :: netconf_db(),
Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
-%% @doc Unlock configuration target.
-%%
-%% Which target parameters that can be used depends on if
-%% `:candidate' and/or `:startup' are supported by the
-%% server. If successfull, the configuration system of the device is
-%% not available to other clients (Netconf, CORBA, SNMP etc). Locks
-%% are intended to be short-lived.
-%%
-%% The operations {@link kill_session/2} or {@link kill_session/3} can
-%% be used to force the release of a lock owned by another Netconf
-%% session. How this is achieved by the server side is implementation
-%% specific.
-%%
-%% @end
-%%----------------------------------------------------------------------
lock(Client, Target, Timeout) ->
call(Client,{send_rpc_op,lock,[Target],Timeout}).
%%----------------------------------------------------------------------
-%% @spec unlock(Client, Target) -> Result
-%% @equiv unlock(Client, Target, infinity)
+%% Send a 'unlock' request.
+-spec unlock(Client, Target) -> Result when
+ Client :: client(),
+ Target :: netconf_db(),
+ Result :: ok | {error,error_reason()}.
unlock(Client, Target) ->
unlock(Client, Target,?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec unlock(Client, Target, Timeout) -> Result when
Client :: client(),
Target :: netconf_db(),
Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
-%% @doc Unlock configuration target.
-%%
-%% If the client earlier has aquired a lock, via {@link lock/2} or
-%% {@link lock/3}, this operation release the associated lock. To be
-%% able to access another target than `running', the server must
-%% support `:candidate' and/or `:startup'.
-%%
-%% @end
-%%----------------------------------------------------------------------
unlock(Client, Target, Timeout) ->
call(Client, {send_rpc_op, unlock, [Target], Timeout}).
%%----------------------------------------------------------------------
-%% @spec get(Client, Filter) -> Result
-%% @equiv get(Client, Filter, infinity)
+%% Send a 'get' request.
+-spec get(Client, Filter) -> Result when
+ Client :: client(),
+ Filter :: simple_xml() | xpath(),
+ Result :: {ok,[simple_xml()]} | {error,error_reason()}.
get(Client, Filter) ->
get(Client, Filter, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec get(Client, Filter, Timeout) -> Result when
Client :: client(),
Filter :: simple_xml() | xpath(),
Timeout :: timeout(),
Result :: {ok,[simple_xml()]} | {error,error_reason()}.
-%% @doc Get data.
-%%
-%% This operation returns both configuration and state data from the
-%% server.
-%%
-%% Filter type `xpath' can only be used if the server supports
-%% `:xpath'.
-%%
-%% @end
-%%----------------------------------------------------------------------
get(Client, Filter, Timeout) ->
call(Client,{send_rpc_op, get, [Filter], Timeout}).
%%----------------------------------------------------------------------
-%% @spec get_config(Client, Source, Filter) -> Result
-%% @equiv get_config(Client, Source, Filter, infinity)
+%% Send a 'get-config' request.
+-spec get_config(Client, Source, Filter) -> Result when
+ Client :: client(),
+ Source :: netconf_db(),
+ Filter :: simple_xml() | xpath(),
+ Result :: {ok,[simple_xml()]} | {error,error_reason()}.
get_config(Client, Source, Filter) ->
get_config(Client, Source, Filter, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec get_config(Client, Source, Filter, Timeout) -> Result when
Client :: client(),
Source :: netconf_db(),
Filter :: simple_xml() | xpath(),
Timeout :: timeout(),
Result :: {ok,[simple_xml()]} | {error,error_reason()}.
-%% @doc Get configuration data.
-%%
-%% To be able to access another source than `running', the server
-%% must advertise `:candidate' and/or `:startup'.
-%%
-%% Filter type `xpath' can only be used if the server supports
-%% `:xpath'.
-%%
-%%
-%% @end
-%%----------------------------------------------------------------------
get_config(Client, Source, Filter, Timeout) ->
call(Client, {send_rpc_op, get_config, [Source, Filter], Timeout}).
%%----------------------------------------------------------------------
-%% @spec edit_config(Client, Target, Config) -> Result
-%% @equiv edit_config(Client, Target, Config, [], infinity)
+%% Send a 'edit-config' request.
+-spec edit_config(Client, Target, Config) -> Result when
+ Client :: client(),
+ Target :: netconf_db(),
+ Config :: simple_xml(),
+ Result :: ok | {error,error_reason()}.
edit_config(Client, Target, Config) ->
edit_config(Client, Target, Config, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
--spec edit_config(Client, Target, Config, OptParamsOrTimeout) -> Result when
+-spec edit_config(Client, Target, Config, OptParams) -> Result when
+ Client :: client(),
+ Target :: netconf_db(),
+ Config :: simple_xml(),
+ OptParams :: [simple_xml()],
+ Result :: ok | {error,error_reason()};
+ (Client, Target, Config, Timeout) -> Result when
Client :: client(),
Target :: netconf_db(),
Config :: simple_xml(),
- OptParamsOrTimeout :: [simple_xml()] | timeout(),
+ Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
-%% @doc
-%%
-%% If `OptParamsOrTimeout' is a timeout value, then this is
-%% equivalent to {@link edit_config/5. edit_config(Client, Target,
-%% Config, [], Timeout)}.
-%%
-%% If `OptParamsOrTimeout' is a list of simple XML, then this is
-%% equivalent to {@link edit_config/5. edit_config(Client, Target,
-%% Config, OptParams, infinity)}.
-%%
-%% @end
edit_config(Client, Target, Config, Timeout) when ?is_timeout(Timeout) ->
edit_config(Client, Target, Config, [], Timeout);
edit_config(Client, Target, Config, OptParams) when is_list(OptParams) ->
edit_config(Client, Target, Config, OptParams, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec edit_config(Client, Target, Config, OptParams, Timeout) -> Result when
Client :: client(),
Target :: netconf_db(),
@@ -728,99 +612,79 @@ edit_config(Client, Target, Config, OptParams) when is_list(OptParams) ->
OptParams :: [simple_xml()],
Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
-%% @doc Edit configuration data.
-%%
-%% Per default only the running target is available, unless the server
-%% include `:candidate' or `:startup' in its list of
-%% capabilities.
-%%
-%% `OptParams' can be used for specifying optional parameters
-%% (`default-operation', `test-option' or `error-option') that will be
-%% added to the `edit-config' request. The value must be a list
-%% containing valid simple XML, for example
-%%
-%% ```
-%% [{'default-operation', ["none"]},
-%% {'error-option', ["rollback-on-error"]}]
-%%'''
-%%
-%% @end
-%%----------------------------------------------------------------------
edit_config(Client, Target, Config, OptParams, Timeout) ->
call(Client, {send_rpc_op, edit_config, [Target,Config,OptParams], Timeout}).
%%----------------------------------------------------------------------
-%% @spec delete_config(Client, Target) -> Result
-%% @equiv delete_config(Client, Target, infinity)
+%% Send a 'delete-config' request.
+-spec delete_config(Client, Target) -> Result when
+ Client :: client(),
+ Target :: startup | candidate,
+ Result :: ok | {error,error_reason()}.
delete_config(Client, Target) ->
delete_config(Client, Target, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec delete_config(Client, Target, Timeout) -> Result when
Client :: client(),
Target :: startup | candidate,
Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
-%% @doc Delete configuration data.
-%%
-%% The running configuration cannot be deleted and `:candidate'
-%% or `:startup' must be advertised by the server.
-%%
-%% @end
-%%----------------------------------------------------------------------
delete_config(Client, Target, Timeout) when Target == startup;
Target == candidate ->
call(Client,{send_rpc_op, delete_config, [Target], Timeout}).
%%----------------------------------------------------------------------
-%% @spec copy_config(Client, Source, Target) -> Result
-%% @equiv copy_config(Client, Source, Target, infinity)
+%% Send a 'copy-config' request.
+-spec copy_config(Client, Target, Source) -> Result when
+ Client :: client(),
+ Target :: netconf_db(),
+ Source :: netconf_db(),
+ Result :: ok | {error,error_reason()}.
copy_config(Client, Source, Target) ->
copy_config(Client, Source, Target, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec copy_config(Client, Target, Source, Timeout) -> Result when
Client :: client(),
Target :: netconf_db(),
Source :: netconf_db(),
Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
-%% @doc Copy configuration data.
-%%
-%% Which source and target options that can be issued depends on the
-%% capabilities supported by the server. I.e. `:candidate' and/or
-%% `:startup' are required.
-%%
-%% @end
-%%----------------------------------------------------------------------
copy_config(Client, Target, Source, Timeout) ->
call(Client,{send_rpc_op, copy_config, [Target, Source], Timeout}).
%%----------------------------------------------------------------------
-%% @spec action(Client, Action) -> Result
-%% @equiv action(Client, Action, infinity)
+%% Execute an action.
+-spec action(Client, Action) -> Result when
+ Client :: client(),
+ Action :: simple_xml(),
+ Result :: ok | {ok,[simple_xml()]} | {error,error_reason()}.
action(Client,Action) ->
action(Client,Action,?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec action(Client, Action, Timeout) -> Result when
Client :: client(),
Action :: simple_xml(),
Timeout :: timeout(),
Result :: ok | {ok,[simple_xml()]} | {error,error_reason()}.
-%% @doc Execute an action. If the return type is void, <c>ok</c> will
-%% be returned instead of <c>{ok,[simple_xml()]}</c>.
-%%
-%% @end
-%%----------------------------------------------------------------------
action(Client,Action,Timeout) ->
call(Client,{send_rpc_op, action, [Action], Timeout}).
%%----------------------------------------------------------------------
+%% Send a 'create-subscription' request
+%% See RFC5277, NETCONF Event Notifications
+-spec create_subscription(Client) -> Result when
+ Client :: client(),
+ Result :: ok | {error,error_reason()}.
create_subscription(Client) ->
create_subscription(Client,?DEFAULT_STREAM,?DEFAULT_TIMEOUT).
+-spec create_subscription(Client, Stream | Filter | Timeout) -> Result when
+ Client :: client(),
+ Stream :: stream_name(),
+ Filter :: simple_xml() | [simple_xml()],
+ Timeout :: timeout(),
+ Result :: ok | {error,error_reason()}.
create_subscription(Client,Timeout)
when ?is_timeout(Timeout) ->
create_subscription(Client,?DEFAULT_STREAM,Timeout);
@@ -876,6 +740,22 @@ create_subscription(Client,Stream,Filter,Timeout)
[Stream,Filter,undefined,undefined],
Timeout}).
+-spec create_subscription(Client, Stream, StartTime, StopTime, Timeout) ->
+ Result when
+ Client :: client(),
+ Stream :: stream_name(),
+ StartTime :: xs_datetime(),
+ StopTime :: xs_datetime(),
+ Timeout :: timeout(),
+ Result :: ok | {error,error_reason()};
+ (Client, Stream, Filter,StartTime, StopTime) ->
+ Result when
+ Client :: client(),
+ Stream :: stream_name(),
+ Filter :: simple_xml() | [simple_xml()],
+ StartTime :: xs_datetime(),
+ StopTime :: xs_datetime(),
+ Result :: ok | {error,error_reason()}.
create_subscription(Client,Stream,StartTime,StopTime,Timeout)
when ?is_string(Stream) andalso
?is_string(StartTime) andalso
@@ -891,7 +771,6 @@ create_subscription(Client,Stream,Filter,StartTime,StopTime)
?is_string(StopTime) ->
create_subscription(Client,Stream,Filter,StartTime,StopTime,?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec create_subscription(Client, Stream, Filter,StartTime, StopTime, Timeout) ->
Result when
Client :: client(),
@@ -901,168 +780,75 @@ create_subscription(Client,Stream,Filter,StartTime,StopTime)
StopTime :: xs_datetime(),
Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
-%% @doc Create a subscription for event notifications.
-%%
-%% This function sets up a subscription for netconf event
-%% notifications of the given stream type, matching the given
-%% filter. The calling process will receive notifications as messages
-%% of type `notification()'.
-%%
-%% <dl>
-%% <dt>Stream:</dt>
-%% <dd> An optional parameter that indicates which stream of events
-%% is of interest. If not present, events in the default NETCONF
-%% stream will be sent.</dd>
-%%
-%% <dt>Filter:</dt>
-%% <dd>An optional parameter that indicates which subset of all
-%% possible events is of interest. The format of this parameter is
-%% the same as that of the filter parameter in the NETCONF protocol
-%% operations. If not present, all events not precluded by other
-%% parameters will be sent.</dd>
-%%
-%% <dt>StartTime:</dt>
-%% <dd>An optional parameter used to trigger the replay feature and
-%% indicate that the replay should start at the time specified. If
-%% `StartTime' is not present, this is not a replay subscription.
-%% It is not valid to specify start times that are later than the
-%% current time. If the `StartTime' specified is earlier than the
-%% log can support, the replay will begin with the earliest
-%% available notification. This parameter is of type dateTime and
-%% compliant to [RFC3339]. Implementations must support time
-%% zones.</dd>
-%%
-%% <dt>StopTime:</dt>
-%% <dd>An optional parameter used with the optional replay feature
-%% to indicate the newest notifications of interest. If `StopTime'
-%% is not present, the notifications will continue until the
-%% subscription is terminated. Must be used with and be later than
-%% `StartTime'. Values of `StopTime' in the future are valid. This
-%% parameter is of type dateTime and compliant to [RFC3339].
-%% Implementations must support time zones.</dd>
-%% </dl>
-%%
-%% See RFC5277 for further details about the event notification
-%% mechanism.
-%%
-%% @end
-%%----------------------------------------------------------------------
create_subscription(Client,Stream,Filter,StartTime,StopTime,Timeout) ->
call(Client,{send_rpc_op,{create_subscription, self()},
[Stream,Filter,StartTime,StopTime],
Timeout}).
%%----------------------------------------------------------------------
-%% @spec get_event_streams(Client, Timeout) -> Result
-%% @equiv get_event_streams(Client, [], Timeout)
+%% Send a request to get the given event streams
+%% See RFC5277, NETCONF Event Notifications
+-spec get_event_streams(Client)
+ -> Result when
+ Client :: client(),
+ Result :: {ok,streams()} | {error,error_reason()}.
+get_event_streams(Client) ->
+ get_event_streams(Client,[],?DEFAULT_TIMEOUT).
+
+-spec get_event_streams(Client, Timeout)
+ -> Result when
+ Client :: client(),
+ Timeout :: timeout(),
+ Result :: {ok,streams()} | {error,error_reason()};
+ (Client, Streams) -> Result when
+ Client :: client(),
+ Streams :: [stream_name()],
+ Result :: {ok,streams()} | {error,error_reason()}.
get_event_streams(Client,Timeout) when is_integer(Timeout); Timeout==infinity ->
get_event_streams(Client,[],Timeout);
-
-%%----------------------------------------------------------------------
-%% @spec get_event_streams(Client, Streams) -> Result
-%% @equiv get_event_streams(Client, Streams, infinity)
get_event_streams(Client,Streams) when is_list(Streams) ->
get_event_streams(Client,Streams,?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec get_event_streams(Client, Streams, Timeout)
-> Result when
Client :: client(),
Streams :: [stream_name()],
Timeout :: timeout(),
Result :: {ok,streams()} | {error,error_reason()}.
-%% @doc Send a request to get the given event streams.
-%%
-%% `Streams' is a list of stream names. The following filter will
-%% be sent to the netconf server in a `get' request:
-%%
-%% ```
-%% <netconf xmlns="urn:ietf:params:xml:ns:netmod:notification">
-%% <streams>
-%% <stream>
-%% <name>StreamName1</name>
-%% </stream>
-%% <stream>
-%% <name>StreamName2</name>
-%% </stream>
-%% ...
-%% </streams>
-%% </netconf>
-%% '''
-%%
-%% If `Streams' is an empty list, ALL streams will be requested
-%% by sending the following filter:
-%%
-%% ```
-%% <netconf xmlns="urn:ietf:params:xml:ns:netmod:notification">
-%% <streams/>
-%% </netconf>
-%% '''
-%%
-%% If more complex filtering is needed, a use {@link get/2} or {@link
-%% get/3} and specify the exact filter according to XML Schema for
-%% Event Notifications found in RFC5277.
-%%
-%% @end
-%%----------------------------------------------------------------------
get_event_streams(Client,Streams,Timeout) ->
call(Client,{get_event_streams,Streams,Timeout}).
%%----------------------------------------------------------------------
-%% @spec close_session(Client) -> Result
-%% @equiv close_session(Client, infinity)
+%% Send a 'close-session' request
+-spec close_session(Client) -> Result when
+ Client :: client(),
+ Result :: ok | {error,error_reason()}.
close_session(Client) ->
close_session(Client, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec close_session(Client, Timeout) -> Result when
Client :: client(),
Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
-%% @doc Request graceful termination of the session associated with the client.
-%%
-%% When a netconf server receives a `close-session' request, it
-%% will gracefully close the session. The server will release any
-%% locks and resources associated with the session and gracefully
-%% close any associated connections. Any NETCONF requests received
-%% after a `close-session' request will be ignored.
-%%
-%% @end
-%%----------------------------------------------------------------------
close_session(Client, Timeout) ->
call(Client,{send_rpc_op, close_session, [], Timeout}, true).
%%----------------------------------------------------------------------
-%% @spec kill_session(Client, SessionId) -> Result
-%% @equiv kill_session(Client, SessionId, infinity)
+%% Send a 'kill-session' request
+-spec kill_session(Client, SessionId) -> Result when
+ Client :: client(),
+ SessionId :: pos_integer(),
+ Result :: ok | {error,error_reason()}.
kill_session(Client, SessionId) ->
kill_session(Client, SessionId, ?DEFAULT_TIMEOUT).
-%%----------------------------------------------------------------------
-spec kill_session(Client, SessionId, Timeout) -> Result when
Client :: client(),
SessionId :: pos_integer(),
Timeout :: timeout(),
Result :: ok | {error,error_reason()}.
-%% @doc Force termination of the session associated with the supplied
-%% session id.
-%%
-%% The server side shall abort any operations currently in process,
-%% release any locks and resources associated with the session, and
-%% close any associated connections.
-%%
-%% Only if the server is in the confirmed commit phase, the
-%% configuration will be restored to its state before entering the
-%% confirmed commit phase. Otherwise, no configuration roll back will
-%% be performed.
-%%
-%% If the given `SessionId' is equal to the current session id,
-%% an error will be returned.
-%%
-%% @end
-%% ----------------------------------------------------------------------
kill_session(Client, SessionId, Timeout) ->
call(Client,{send_rpc_op, kill_session, [SessionId], Timeout}).
@@ -1071,24 +857,35 @@ kill_session(Client, SessionId, Timeout) ->
%% Callback functions
%%----------------------------------------------------------------------
-%% @private
+init(_KeyOrName,{CM,{Host,Port}},Options) ->
+ case ssh_channel(#connection{reference=CM,host=Host,port=Port},Options) of
+ {ok,Connection} ->
+ {ok, CM, #state{connection = Connection}};
+ {error,Reason}->
+ {error,Reason}
+ end;
+init(_KeyOrName,{_Host,_Port},Options) when Options#options.type==connection ->
+ case ssh_connect(Options) of
+ {ok, Connection} ->
+ ConnPid = Connection#connection.reference,
+ {ok, ConnPid, #state{connection = Connection}};
+ Error ->
+ Error
+ end;
init(_KeyOrName,{_Host,_Port},Options) ->
case ssh_open(Options) of
{ok, Connection} ->
- log(Connection,open),
{ConnPid,_} = Connection#connection.reference,
{ok, ConnPid, #state{connection = Connection}};
{error,Reason}->
{error,Reason}
end.
-%% @private
+
terminate(_, #state{connection=Connection}) ->
ssh_close(Connection),
- log(Connection,close),
ok.
-%% @private
handle_msg({hello, Options, Timeout}, From,
#state{connection=Connection,hello_status=HelloStatus} = State) ->
case do_send(Connection, client_hello(Options)) of
@@ -1107,6 +904,14 @@ handle_msg({hello, Options, Timeout}, From,
Error ->
{stop, Error, State}
end;
+handle_msg(get_ssh_connection, _From, #state{connection=Connection}=State) ->
+ Reply =
+ case Connection#connection.reference of
+ {_,_} -> {error,not_an_ssh_connection};
+ CM -> {ok,{CM,{Connection#connection.host,
+ Connection#connection.port}}}
+ end,
+ {reply, Reply, State};
handle_msg(_, _From, #state{session_id=undefined} = State) ->
%% Hello is not yet excanged - this shall never happen
{reply,{error,waiting_for_hello},State};
@@ -1136,7 +941,6 @@ handle_msg({get_event_streams=Op,Streams,Timeout}, From, State) ->
SimpleXml = encode_rpc_operation(get,[Filter]),
do_send_rpc(Op, SimpleXml, Timeout, From, State).
-%% @private
handle_msg({ssh_cm, CM, {data, Ch, _Type, Data}}, State) ->
ssh_connection:adjust_window(CM,Ch,size(Data)),
handle_data(Data, State);
@@ -1172,7 +976,6 @@ handle_msg({Ref,timeout},#state{pending=Pending} = State) ->
%% the implementation before this patch
{R,State#state{pending=Pending1, no_end_tag_buff= <<>>, buff= <<>>}}.
-%% @private
%% Called by ct_util_server to close registered connections before terminate.
close(Client) ->
case get_handle(Client) of
@@ -1243,15 +1046,18 @@ get_handle(Client) ->
Error
end.
+check_options(OptList,Options) ->
+ check_options(OptList,undefined,undefined,Options).
+
check_options([], undefined, _Port, _Options) ->
{error, no_host_address};
check_options([], _Host, undefined, _Options) ->
{error, no_port};
check_options([], Host, Port, Options) ->
{Host,Port,Options};
-check_options([{ssh, Host}|T], _, Port, #options{} = Options) ->
+check_options([{ssh, Host}|T], _, Port, Options) ->
check_options(T, Host, Port, Options#options{host=Host});
-check_options([{port,Port}|T], Host, _, #options{} = Options) ->
+check_options([{port,Port}|T], Host, _, Options) ->
check_options(T, Host, Port, Options#options{port=Port});
check_options([{timeout, Timeout}|T], Host, Port, Options)
when is_integer(Timeout); Timeout==infinity ->
@@ -1262,6 +1068,15 @@ check_options([Opt|T], Host, Port, #options{ssh=SshOpts}=Options) ->
%% Option verified by ssh
check_options(T, Host, Port, Options#options{ssh=[Opt|SshOpts]}).
+check_session_options([],Options) ->
+ {ok,Options};
+check_session_options([{timeout, Timeout}|T], Options)
+ when is_integer(Timeout); Timeout==infinity ->
+ check_session_options(T, Options#options{timeout = Timeout});
+check_session_options([Opt|_T], _Options) ->
+ {error, {invalid_option, Opt}}.
+
+
%%%-----------------------------------------------------------------
set_request_timer(infinity) ->
{undefined,undefined};
@@ -1356,7 +1171,6 @@ do_send_rpc(Connection, MsgId, SimpleXml) ->
do_send(Connection, SimpleXml) ->
Xml=to_xml_doc(SimpleXml),
- log(Connection,send,Xml),
ssh_send(Connection, Xml).
to_xml_doc(Simple) ->
@@ -1766,9 +1580,14 @@ decode_streams([]) ->
log(Connection,Action) ->
log(Connection,Action,<<>>).
-log(#connection{host=Host,port=Port,name=Name},Action,Data) ->
+log(#connection{reference=Ref,host=Host,port=Port,name=Name},Action,Data) ->
+ Address =
+ case Ref of
+ {_,Ch} -> {Host,Port,Ch};
+ _ -> {Host,Port}
+ end,
error_logger:info_report(#conn_log{client=self(),
- address={Host,Port},
+ address=Address,
name=Name,
action=Action,
module=?MODULE},
@@ -1776,7 +1595,6 @@ log(#connection{host=Host,port=Port,name=Name},Action,Data) ->
%% Log callback - called from the error handler process
-%% @private
format_data(How,Data) ->
%% Assuming that the data is encoded as UTF-8. If it is not, then
%% the printout might be wrong, but the format function will not
@@ -1915,42 +1733,84 @@ get_tag([]) ->
%%%-----------------------------------------------------------------
%%% SSH stuff
-
-ssh_open(#options{host=Host,timeout=Timeout,port=Port,ssh=SshOpts,name=Name}) ->
+ssh_connect(#options{host=Host,timeout=Timeout,port=Port,
+ ssh=SshOpts,name=Name,type=Type}) ->
case ssh:connect(Host, Port,
[{user_interaction,false},
- {silently_accept_hosts, true}|SshOpts]) of
+ {silently_accept_hosts, true}|SshOpts],
+ Timeout) of
{ok,CM} ->
- case ssh_connection:session_channel(CM, Timeout) of
- {ok,Ch} ->
- case ssh_connection:subsystem(CM, Ch, "netconf", Timeout) of
- success ->
- {ok, #connection{reference = {CM,Ch},
- host = Host,
- port = Port,
- name = Name}};
- failure ->
- ssh:close(CM),
- {error,{ssh,could_not_execute_netconf_subsystem}};
- {error,timeout} ->
- {error,{ssh,could_not_execute_netconf_subsystem,timeout}}
- end;
- {error, Reason} ->
- ssh:close(CM),
- {error,{ssh,could_not_open_channel,Reason}}
- end;
+ Connection = #connection{reference = CM,
+ host = Host,
+ port = Port,
+ name = Name,
+ type = Type},
+ log(Connection,connect),
+ {ok,Connection};
{error,Reason} ->
{error,{ssh,could_not_connect_to_server,Reason}}
end.
-ssh_send(#connection{reference = {CM,Ch}}, Data) ->
+ssh_channel(#connection{reference=CM}=Connection0,
+ #options{timeout=Timeout,name=Name,type=Type}) ->
+ case ssh_connection:session_channel(CM, Timeout) of
+ {ok,Ch} ->
+ case ssh_connection:subsystem(CM, Ch, "netconf", Timeout) of
+ success ->
+ Connection = Connection0#connection{reference = {CM,Ch},
+ name = Name,
+ type = Type},
+ log(Connection,open),
+ {ok, Connection};
+ failure ->
+ ssh_connection:close(CM,Ch),
+ {error,{ssh,could_not_execute_netconf_subsystem}};
+ {error,timeout} ->
+ ssh_connection:close(CM,Ch),
+ {error,{ssh,could_not_execute_netconf_subsystem,timeout}}
+ end;
+ {error, Reason} ->
+ {error,{ssh,could_not_open_channel,Reason}}
+ end.
+
+
+ssh_open(Options) ->
+ case ssh_connect(Options) of
+ {ok,Connection} ->
+ case ssh_channel(Connection,Options) of
+ {ok,_} = Ok ->
+ Ok;
+ Error ->
+ ssh_close(Connection),
+ Error
+ end;
+ Error ->
+ Error
+ end.
+
+ssh_send(#connection{reference = {CM,Ch}}=Connection, Data) ->
case ssh_connection:send(CM, Ch, Data) of
- ok -> ok;
- {error,Reason} -> {error,{ssh,failed_to_send_data,Reason}}
+ ok ->
+ log(Connection,send,Data),
+ ok;
+ {error,Reason} ->
+ {error,{ssh,failed_to_send_data,Reason}}
end.
-ssh_close(#connection{reference = {CM,_Ch}}) ->
- ssh:close(CM).
+ssh_close(Connection=#connection{reference = {CM,Ch}, type = Type}) ->
+ _ = ssh_connection:close(CM,Ch),
+ log(Connection,close),
+ case Type of
+ connection_and_channel ->
+ ssh_close(Connection#connection{reference = CM});
+ _ ->
+ ok
+ end,
+ ok;
+ssh_close(Connection=#connection{reference = CM}) ->
+ _ = ssh:close(CM),
+ log(Connection,disconnect),
+ ok.
%%----------------------------------------------------------------------
diff --git a/lib/common_test/src/ct_property_test.erl b/lib/common_test/src/ct_property_test.erl
index 12c3d726d3..94ccb59af9 100644
--- a/lib/common_test/src/ct_property_test.erl
+++ b/lib/common_test/src/ct_property_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -134,7 +134,7 @@ mk_ct_return(Other, Tool) ->
try lists:last(hd(Tool:counterexample()))
of
{set,{var,_},{call,M,F,Args}} ->
- {fail, io_lib:format("~p:~p/~p returned bad result",[M,F,length(Args)])}
+ {fail, io_lib:format("~p:~tp/~p returned bad result",[M,F,length(Args)])}
catch
_:_ ->
{fail, Other}
@@ -174,7 +174,7 @@ compile_tests(Path, ToolModule) ->
BeamFiles = [F || F<-FileNames,
filename:extension(F) == ".beam"],
_ = [file:delete(F) || F<-BeamFiles],
- ct:pal("Compiling in ~p:~n Deleted ~p~n MacroDefs=~p",[Path,BeamFiles,MacroDefs]),
+ ct:pal("Compiling in ~tp:~n Deleted ~p~n MacroDefs=~p",[Path,BeamFiles,MacroDefs]),
Result = make:all([load|MacroDefs]),
ok = file:set_cwd(Cwd),
Result.
diff --git a/lib/common_test/src/ct_release_test.erl b/lib/common_test/src/ct_release_test.erl
index d783f8d04e..551a7e06d7 100644
--- a/lib/common_test/src/ct_release_test.erl
+++ b/lib/common_test/src/ct_release_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2014-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -132,7 +132,7 @@
%%-----------------------------------------------------------------
-define(testnode, 'ct_release_test-upgrade').
--define(exclude_apps, [hipe, typer, dialyzer]). % never include these apps
+-define(exclude_apps, [hipe, dialyzer]). % never include these apps
%%-----------------------------------------------------------------
-record(ct_data, {from,to}).
@@ -445,7 +445,7 @@ init_upgrade_test(Level) ->
end,
case OldRel of
false ->
- ct:log("Release ~p is not available."
+ ct:log("Release ~tp is not available."
" Upgrade on '~p' level can not be tested.",
[FromVsn,Level]),
undefined;
@@ -522,8 +522,8 @@ upgrade(Apps,Level,Callback,CreateDir,InstallDir,Config) ->
{ToVsn,ToRel,ToAppsVsns} =
upgrade_system(Apps, FromRel, CreateDir,
InstallDir, Data),
- ct:log("Upgrade from: OTP-~ts, ~p",[FromVsn, FromAppsVsns]),
- ct:log("Upgrade to: OTP-~ts, ~p",[ToVsn, ToAppsVsns]),
+ ct:log("Upgrade from: OTP-~ts, ~tp",[FromVsn, FromAppsVsns]),
+ ct:log("Upgrade to: OTP-~ts, ~tp",[ToVsn, ToAppsVsns]),
do_upgrade(Callback, FromVsn, FromAppsVsns, ToRel,
ToAppsVsns, InstallDir)
end
@@ -727,9 +727,9 @@ do_upgrade({Cb,InitState},FromVsn,FromAppsVsns,ToRel,ToAppsVsns,InstallDir) ->
do_callback(Node,Mod,Func,Args) ->
Dir = filename:dirname(code:which(Mod)),
_ = rpc:call(Node,code,add_path,[Dir]),
- ct:log("Calling ~p:~p/1",[Mod,Func]),
+ ct:log("Calling ~p:~tp/1",[Mod,Func]),
R = rpc:call(Node,Mod,Func,Args),
- ct:log("~p:~p/~w returned: ~p",[Mod,Func,length(Args),R]),
+ ct:log("~p:~tp/~w returned: ~tp",[Mod,Func,length(Args),R]),
case R of
{badrpc,Error} ->
throw({fail,{test_upgrade_callback,Mod,Func,Args,Error}});
@@ -860,10 +860,7 @@ copy_file(Src, Dest, Opts) ->
end.
write_file(FName, Conts) ->
- Enc = file:native_name_encoding(),
- {ok, Fd} = file:open(FName, [write]),
- ok = file:write(Fd, unicode:characters_to_binary(Conts,Enc,Enc)),
- ok = file:close(Fd).
+ file:write_file(FName, unicode:characters_to_binary(Conts)).
%% Substitute all occurrences of %Var% for Val in the given scripts
subst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) ->
@@ -879,7 +876,7 @@ subst_src_script(Script, SrcDir, DestDir, Vars, Opts) ->
subst_file(Src, Dest, Vars, Opts) ->
{ok, Bin} = file:read_file(Src),
- Conts = binary_to_list(Bin),
+ Conts = unicode:characters_to_list(Bin),
NConts = subst(Conts, Vars),
write_file(Dest, NConts),
case lists:member(preserve, Opts) of
@@ -891,7 +888,7 @@ subst_file(Src, Dest, Vars, Opts) ->
end.
subst(Str, [{Var,Val}|Vars]) ->
- subst(re:replace(Str,"%"++Var++"%",Val,[{return,list}]),Vars);
+ subst(re:replace(Str,"%"++Var++"%",Val,[{return,list},unicode]),Vars);
subst(Str, []) ->
Str.
diff --git a/lib/common_test/src/ct_repeat.erl b/lib/common_test/src/ct_repeat.erl
index dac596a135..c043c9846c 100644
--- a/lib/common_test/src/ct_repeat.erl
+++ b/lib/common_test/src/ct_repeat.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@ loop_test(If,Args) when is_list(Args) ->
no_loop ->
false;
E = {error,_} ->
- io:format("Common Test error: ~p\n\n",[E]),
+ io:format("Common Test error: ~tp\n\n",[E]),
ok = file:set_cwd(Cwd),
E;
{repeat,N} ->
@@ -89,18 +89,18 @@ loop(If,Type,N,Data0,Data1,Args,TPid,AccResult) ->
{'EXIT',Pid,Reason} ->
case Reason of
{user_error,What} ->
- io:format("\nTest run failed!\nReason: ~p\n\n\n", [What]),
+ io:format("\nTest run failed!\nReason: ~tp\n\n\n", [What]),
cancel(TPid),
{error,What};
_ ->
io:format("Test run crashed! This could be an internal error "
"- please report!\n\n"
- "~p\n\n\n",[Reason]),
+ "~tp\n\n\n",[Reason]),
cancel(TPid),
{error,Reason}
end;
{Pid,{error,Reason}} ->
- io:format("\nTest run failed!\nReason: ~p\n\n\n",[Reason]),
+ io:format("\nTest run failed!\nReason: ~tp\n\n\n",[Reason]),
cancel(TPid),
{error,Reason};
{Pid,Result} ->
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index fbb9c7ab60..14f28f9ca3 100644
--- a/lib/common_test/src/ct_run.erl
+++ b/lib/common_test/src/ct_run.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -76,8 +76,8 @@
abort_if_missing_suites,
silent_connections = [],
stylesheet,
- multiply_timetraps = 1,
- scale_timetraps = false,
+ multiply_timetraps,
+ scale_timetraps,
create_priv_dir,
testspec_files = [],
current_testspec,
@@ -121,13 +121,13 @@ script_start() ->
%% used for purpose of testing the run_test interface
io:format(user, "~n-------------------- START ARGS "
"--------------------~n", []),
- io:format(user, "--- Init args:~n~p~n", [FlagFilter(Init)]),
- io:format(user, "--- CT args:~n~p~n", [FlagFilter(CtArgs)]),
+ io:format(user, "--- Init args:~n~tp~n", [FlagFilter(Init)]),
+ io:format(user, "--- CT args:~n~tp~n", [FlagFilter(CtArgs)]),
EnvArgs = opts2args(EnvStartOpts),
- io:format(user, "--- Env opts -> args:~n~p~n =>~n~p~n",
+ io:format(user, "--- Env opts -> args:~n~tp~n =>~n~tp~n",
[EnvStartOpts,EnvArgs]),
Merged = merge_arguments(CtArgs ++ EnvArgs),
- io:format(user, "--- Merged args:~n~p~n", [FlagFilter(Merged)]),
+ io:format(user, "--- Merged args:~n~tp~n", [FlagFilter(Merged)]),
io:format(user, "-----------------------------------"
"-----------------~n~n", []),
Merged;
@@ -160,18 +160,18 @@ script_start(Args) ->
{'EXIT',Pid,Reason} ->
case Reason of
{user_error,What} ->
- io:format("\nTest run failed!\nReason: ~p\n\n\n",
+ io:format("\nTest run failed!\nReason: ~tp\n\n\n",
[What]),
finish(Tracing, ?EXIT_STATUS_TEST_RUN_FAILED, Args);
_ ->
io:format("Test run crashed! "
"This could be an internal error "
"- please report!\n\n"
- "~p\n\n\n", [Reason]),
+ "~tp\n\n\n", [Reason]),
finish(Tracing, ?EXIT_STATUS_TEST_RUN_FAILED, Args)
end;
{Pid,{error,Reason}} ->
- io:format("\nTest run failed! Reason:\n~p\n\n\n",[Reason]),
+ io:format("\nTest run failed! Reason:\n~tp\n\n\n",[Reason]),
finish(Tracing, ?EXIT_STATUS_TEST_RUN_FAILED, Args);
{Pid,Result} ->
io:nl(),
@@ -219,7 +219,7 @@ analyze_test_result([], _) ->
analyze_test_result(interactive_mode, _) ->
interactive_mode;
analyze_test_result(Unknown, _) ->
- io:format("\nTest run failed! Reason:\n~p\n\n\n",[Unknown]),
+ io:format("\nTest run failed! Reason:\n~tp\n\n\n",[Unknown]),
?EXIT_STATUS_TEST_RUN_FAILED.
finish(Tracing, ExitStatus, Args) ->
@@ -264,11 +264,11 @@ script_start1(Parent, Args) ->
[], Args),
Verbosity = verbosity_args2opts(Args),
MultTT = get_start_opt(multiply_timetraps,
- fun([MT]) -> list_to_integer(MT) end, 1, Args),
+ fun([MT]) -> list_to_integer(MT) end, Args),
ScaleTT = get_start_opt(scale_timetraps,
fun([CT]) -> list_to_atom(CT);
([]) -> true
- end, false, Args),
+ end, Args),
CreatePrivDir = get_start_opt(create_priv_dir,
fun([PD]) -> list_to_atom(PD);
([]) -> auto_per_tc
@@ -363,6 +363,12 @@ script_start1(Parent, Args) ->
_ ->
application:set_env(common_test, disable_log_cache, true)
end,
+ %% log_cleanup - used by ct_logs
+ KeepLogs = get_start_opt(keep_logs,
+ fun ct_logs:parse_keep_logs/1,
+ all,
+ Args),
+ application:set_env(common_test, keep_logs, KeepLogs),
Opts = #opts{label = Label, profile = Profile,
vts = Vts, shell = Shell,
@@ -430,13 +436,17 @@ script_start2(Opts = #opts{vts = undefined,
Specs1 = get_start_opt(join_specs, [Specs], Specs, Args),
%% using testspec as input for test
Relaxed = get_start_opt(allow_user_terms, true, false, Args),
- case catch ct_testspec:collect_tests_from_file(Specs1, Relaxed) of
- {E,Reason} when E == error ; E == 'EXIT' ->
+ try ct_testspec:collect_tests_from_file(Specs1, Relaxed) of
+ TestSpecData ->
+ execute_all_specs(TestSpecData, Opts, Args, [])
+ catch
+ throw:{error,Reason} ->
StackTrace = erlang:get_stacktrace(),
{error,{invalid_testspec,{Reason,StackTrace}}};
- TestSpecData ->
- execute_all_specs(TestSpecData, Opts, Args, [])
- end;
+ _:Reason ->
+ StackTrace = erlang:get_stacktrace(),
+ {error,{invalid_testspec,{Reason,StackTrace}}}
+ end;
[] ->
{error,no_testspec_specified};
_ -> % no testspec used
@@ -750,7 +760,7 @@ script_start4(#opts{label = Label, profile = Profile,
if Config == [] ->
ok;
true ->
- io:format("\nInstalling: ~p\n\n", [Config])
+ io:format("\nInstalling: ~tp\n\n", [Config])
end,
case install([{config,Config},{event_handler,EvHandlers},
{ct_hooks, CTHooks},
@@ -899,9 +909,9 @@ install(Opts, LogDir) ->
case whereis(ct_util_server) of
undefined ->
VarFile = variables_file_name(LogDir),
- case file:open(VarFile, [write]) of
+ case file:open(VarFile, [write, {encoding,utf8}]) of
{ok,Fd} ->
- _ = [io:format(Fd, "~p.\n", [Opt]) || Opt <- ConfOpts],
+ _ = [io:format(Fd, "~tp.\n", [Opt]) || Opt <- ConfOpts],
ok = file:close(Fd);
{error,Reason} ->
io:format("CT failed to install configuration data. Please "
@@ -970,6 +980,12 @@ run_test1(StartOpts) when is_list(StartOpts) ->
stop_trace(Tracing),
exit(Res);
RefreshDir ->
+ %% log_cleanup - used by ct_logs
+ KeepLogs = get_start_opt(keep_logs,
+ fun ct_logs:parse_keep_logs/1,
+ all,
+ StartOpts),
+ application:set_env(common_test, keep_logs, KeepLogs),
ok = refresh_logs(?abs(RefreshDir)),
exit(done)
end.
@@ -1055,8 +1071,8 @@ run_test2(StartOpts) ->
CoverStop = get_start_opt(cover_stop, value, StartOpts),
%% timetrap manipulation
- MultiplyTT = get_start_opt(multiply_timetraps, value, 1, StartOpts),
- ScaleTT = get_start_opt(scale_timetraps, value, false, StartOpts),
+ MultiplyTT = get_start_opt(multiply_timetraps, value, StartOpts),
+ ScaleTT = get_start_opt(scale_timetraps, value, StartOpts),
%% create unique priv dir names
CreatePrivDir = get_start_opt(create_priv_dir, value, StartOpts),
@@ -1131,6 +1147,12 @@ run_test2(StartOpts) ->
DisableCacheBool ->
application:set_env(common_test, disable_log_cache, DisableCacheBool)
end,
+ %% log_cleanup - used by ct_logs
+ KeepLogs = get_start_opt(keep_logs,
+ fun ct_logs:parse_keep_logs/1,
+ all,
+ StartOpts),
+ application:set_env(common_test, keep_logs, KeepLogs),
%% stepped execution
Step = get_start_opt(step, value, StartOpts),
@@ -1180,12 +1202,16 @@ run_spec_file(Relaxed,
end,
AbsSpecs = lists:map(fun(SF) -> ?abs(SF) end, Specs1),
AbsSpecs1 = get_start_opt(join_specs, [AbsSpecs], AbsSpecs, StartOpts),
- case catch ct_testspec:collect_tests_from_file(AbsSpecs1, Relaxed) of
- {Error,CTReason} when Error == error ; Error == 'EXIT' ->
- StackTrace = erlang:get_stacktrace(),
- exit({error,{invalid_testspec,{CTReason,StackTrace}}});
+ try ct_testspec:collect_tests_from_file(AbsSpecs1, Relaxed) of
TestSpecData ->
run_all_specs(TestSpecData, Opts, StartOpts, [])
+ catch
+ throw:{error,CTReason} ->
+ StackTrace = erlang:get_stacktrace(),
+ exit({error,{invalid_testspec,{CTReason,StackTrace}}});
+ _:CTReason ->
+ StackTrace = erlang:get_stacktrace(),
+ exit({error,{invalid_testspec,{CTReason,StackTrace}}})
end.
run_all_specs([], _, _, TotResult) ->
@@ -1802,10 +1828,10 @@ compile_and_run(Tests, Skip, Opts, Args) ->
case lists:member(all, Conns) of
true ->
Conns1 = ct_util:override_silence_all_connections(),
- ct_logs:log("Silent connections", "~p", [Conns1]);
+ ct_logs:log("Silent connections", "~tp", [Conns1]);
false ->
ct_util:override_silence_connections(Conns),
- ct_logs:log("Silent connections", "~p", [Conns])
+ ct_logs:log("Silent connections", "~tp", [Conns])
end
end,
log_ts_names(Opts#opts.testspec_files),
@@ -1898,7 +1924,7 @@ possibly_spawn(true, Tests, Skip, Opts) ->
TestRunPid = spawn_link(TestRun),
receive
{'EXIT',TestRunPid,{ok,TestResult}} ->
- io:format(user, "~nCommon Test returned ~p~n~n",
+ io:format(user, "~nCommon Test returned ~tp~n~n",
[TestResult]);
{'EXIT',TestRunPid,Error} ->
exit(Error)
@@ -1917,7 +1943,7 @@ auto_compile(TestSuites) ->
case application:get_env(common_test, include) of
{ok,UserInclDirs} when length(UserInclDirs) > 0 ->
io:format("Including the following directories:~n"),
- [begin io:format("~p~n",[UserInclDir]), {i,UserInclDir} end ||
+ [begin io:format("~tp~n",[UserInclDir]), {i,UserInclDir} end ||
UserInclDir <- UserInclDirs];
_ ->
[]
@@ -2155,8 +2181,8 @@ continue(_MakeErrors, true) ->
false;
continue(_MakeErrors, _AbortIfMissingSuites) ->
io:nl(),
- OldGl = group_leader(),
- case set_group_leader_same_as_shell() of
+ OldGL = group_leader(),
+ case set_group_leader_same_as_shell(OldGL) of
true ->
S = self(),
io:format("Failed to compile or locate one "
@@ -2172,7 +2198,7 @@ continue(_MakeErrors, _AbortIfMissingSuites) ->
S ! false
end
end),
- group_leader(OldGl, self()),
+ group_leader(OldGL, self()),
receive R when R==true; R==false ->
R
after 15000 ->
@@ -2184,7 +2210,9 @@ continue(_MakeErrors, _AbortIfMissingSuites) ->
true
end.
-set_group_leader_same_as_shell() ->
+set_group_leader_same_as_shell(OldGL) ->
+ %% find the group leader process on the node in a dirty fashion
+ %% (check initial function call and look in the process dictionary)
GS2or3 = fun(P) ->
case process_info(P,initial_call) of
{initial_call,{group,server,X}} when X == 2 ; X == 3 ->
@@ -2197,7 +2225,10 @@ set_group_leader_same_as_shell() ->
true == lists:keymember(shell,1,
element(2,process_info(P,dictionary)))] of
[GL|_] ->
- group_leader(GL, self());
+ %% check if started from remote node (skip interaction)
+ if node(OldGL) /= node(GL) -> false;
+ true -> group_leader(GL, self())
+ end;
[] ->
false
end.
@@ -2253,7 +2284,7 @@ do_run_test(Tests, Skip, Opts0) ->
NoOfSuites = length(Suites1),
ct_util:warn_duplicates(Suites1),
{ok,Cwd} = file:get_cwd(),
- io:format("~nCWD set to: ~p~n", [Cwd]),
+ io:format("~nCWD set to: ~tp~n", [Cwd]),
if NoOfCases == unknown ->
io:format("~nTEST INFO: ~w test(s), ~w suite(s)~n~n",
[NoOfTests,NoOfSuites]),
@@ -2275,8 +2306,19 @@ do_run_test(Tests, Skip, Opts0) ->
_Lower ->
ok
end,
- test_server_ctrl:multiply_timetraps(Opts0#opts.multiply_timetraps),
- test_server_ctrl:scale_timetraps(Opts0#opts.scale_timetraps),
+
+ case Opts0#opts.multiply_timetraps of
+ undefined -> MultTT = 1;
+ MultTT -> MultTT
+ end,
+ case Opts0#opts.scale_timetraps of
+ undefined -> ScaleTT = false;
+ ScaleTT -> ScaleTT
+ end,
+ ct_logs:log("TEST INFO","Timetrap time multiplier = ~w~n"
+ "Timetrap scaling enabled = ~w", [MultTT,ScaleTT]),
+ test_server_ctrl:multiply_timetraps(MultTT),
+ test_server_ctrl:scale_timetraps(ScaleTT),
test_server_ctrl:create_priv_dir(choose_val(
Opts0#opts.create_priv_dir,
@@ -2312,7 +2354,7 @@ do_run_test(Tests, Skip, Opts0) ->
case ct_util:get_testdata(severe_error) of
undefined -> ok;
SevereError ->
- ct_logs:log("SEVERE ERROR", "~p\n", [SevereError]),
+ ct_logs:log("SEVERE ERROR", "~tp\n", [SevereError]),
exit(SevereError)
end,
@@ -2383,7 +2425,7 @@ start_cover(Opts=#opts{coverspec=CovData,cover_stop=CovStop},LogDir) ->
if (CovNodes /= []) and (CovNodes /= undefined) ->
ct_logs:log("COVER INFO",
"Nodes included in cover "
- "session: ~w",
+ "session: ~tw",
[CovNodes]),
cover:start(CovNodes);
true ->
@@ -2397,7 +2439,7 @@ start_cover(Opts=#opts{coverspec=CovData,cover_stop=CovStop},LogDir) ->
{error,Reason} ->
ct_logs:log("COVER INFO",
"Importing cover data from: ~ts fails! "
- "Reason: ~p", [Imp,Reason])
+ "Reason: ~tp", [Imp,Reason])
end
end, CovImport),
{TsCoverInfo,Opts}.
@@ -2731,7 +2773,7 @@ run_make(Targets, TestDir0, Mod, UserInclude) ->
{up_to_date,_} ->
ok;
{'EXIT',Reason} ->
- io:format("{error,{make_crashed,~p}\n", [Reason]),
+ io:format("{error,{make_crashed,~tp}\n", [Reason]),
{error,{make_crashed,TestDir,Reason}};
{error,ModInfo} ->
io:format("{error,make_failed}\n", []),
@@ -2740,7 +2782,7 @@ run_make(Targets, TestDir0, Mod, UserInclude) ->
{error,{make_failed,Bad}}
end;
{error,_} ->
- io:format("{error,{invalid_directory,~p}}\n", [TestDir0]),
+ io:format("{error,{invalid_directory,~tp}}\n", [TestDir0]),
{error,{invalid_directory,TestDir0}}
end.
@@ -2790,7 +2832,7 @@ maybe_interpret2(Suite, Cases, StepOpts) ->
_ -> ok
catch
_:_Error ->
- io:format(user, "Invalid breakpoint: ~w:~w/1~n",
+ io:format(user, "Invalid breakpoint: ~w:~tw/1~n",
[Suite,Case])
end
end || Case <- Cases, is_atom(Case)],
@@ -2921,7 +2963,7 @@ ct_hooks_args2opts([],Acc) ->
parse_cth_args(String) ->
try
- true = io_lib:printable_list(String),
+ true = io_lib:printable_unicode_list(String),
{ok,Toks,_} = erl_scan:string(String++"."),
{ok, Args} = erl_parse:parse_term(Toks),
Args
@@ -3000,7 +3042,7 @@ rel_to_abs(CtArgs) ->
_ = if Dir /= Abs ->
_ = code:del_path(Dir),
_ = code:del_path(Abs),
- io:format(user, "Converting ~p to ~p and re-inserting "
+ io:format(user, "Converting ~tp to ~tp and re-inserting "
"with add_pathz/1~n",
[Dir, Abs]);
true ->
@@ -3014,7 +3056,7 @@ rel_to_abs(CtArgs) ->
_ = if Dir /= Abs ->
_ = code:del_path(Dir),
_ = code:del_path(Abs),
- io:format(user, "Converting ~p to ~p and re-inserting "
+ io:format(user, "Converting ~tp to ~tp and re-inserting "
"with add_patha/1~n",
[Dir, Abs]);
true ->
@@ -3084,7 +3126,7 @@ opts2args(EnvStartOpts) ->
({group,G}) when is_atom(G) ->
[{group,[atom_to_list(G)]}];
({group,Gs}) when is_list(Gs) ->
- LOfGStrs = [lists:flatten(io_lib:format("~w",[G])) ||
+ LOfGStrs = [lists:flatten(io_lib:format("~tw",[G])) ||
G <- Gs],
[{group,LOfGStrs}];
({testcase,Case}) when is_atom(Case) ->
@@ -3136,10 +3178,10 @@ opts2args(EnvStartOpts) ->
({event_handler,EHs}) when is_list(EHs) ->
[{event_handler,[atom_to_list(EH) || EH <- EHs]}];
({event_handler,{EH,Arg}}) when is_atom(EH) ->
- ArgStr = lists:flatten(io_lib:format("~p", [Arg])),
+ ArgStr = lists:flatten(io_lib:format("~tp", [Arg])),
[{event_handler_init,[atom_to_list(EH),ArgStr]}];
({event_handler,{EHs,Arg}}) when is_list(EHs) ->
- ArgStr = lists:flatten(io_lib:format("~p", [Arg])),
+ ArgStr = lists:flatten(io_lib:format("~tp", [Arg])),
Strs = lists:flatmap(fun(EH) ->
[atom_to_list(EH),
ArgStr,"and"]
@@ -3170,25 +3212,25 @@ opts2args(EnvStartOpts) ->
({ct_hooks,[]}) ->
[];
({ct_hooks,CTHs}) when is_list(CTHs) ->
- io:format(user,"ct_hooks: ~p",[CTHs]),
+ io:format(user,"ct_hooks: ~tp",[CTHs]),
Strs = lists:flatmap(
fun({CTH,Arg,Prio}) ->
[atom_to_list(CTH),
lists:flatten(
- io_lib:format("~p",[Arg])),
+ io_lib:format("~tp",[Arg])),
lists:flatten(
- io_lib:format("~p",[Prio])),
+ io_lib:format("~tp",[Prio])),
"and"];
({CTH,Arg}) ->
[atom_to_list(CTH),
lists:flatten(
- io_lib:format("~p",[Arg])),
+ io_lib:format("~tp",[Arg])),
"and"];
(CTH) when is_atom(CTH) ->
[atom_to_list(CTH),"and"]
end,CTHs),
[_LastAnd|StrsR] = lists:reverse(Strs),
- io:format(user,"return: ~p",[lists:reverse(StrsR)]),
+ io:format(user,"return: ~tp",[lists:reverse(StrsR)]),
[{ct_hooks,lists:reverse(StrsR)}];
({Opt,As=[A|_]}) when is_atom(A) ->
[{Opt,[atom_to_list(Atom) || Atom <- As]}];
@@ -3270,7 +3312,7 @@ start_trace(Args) ->
ok ->
true;
{_,Error} ->
- io:format("Warning! Tracing not started. Reason: ~p~n~n",
+ io:format("Warning! Tracing not started. Reason: ~tp~n~n",
[Error]),
false
end;
diff --git a/lib/common_test/src/ct_slave.erl b/lib/common_test/src/ct_slave.erl
index 571958ca03..4188bd7c3b 100644
--- a/lib/common_test/src/ct_slave.erl
+++ b/lib/common_test/src/ct_slave.erl
@@ -309,7 +309,12 @@ is_started(ENode) ->
% make a Erlang node name from name and hostname
enodename(Host, Node) ->
- list_to_atom(atom_to_list(Node)++"@"++atom_to_list(Host)).
+ case lists:member($@, atom_to_list(Node)) of
+ true ->
+ Node;
+ false ->
+ list_to_atom(atom_to_list(Node)++"@"++atom_to_list(Host))
+ end.
% performs actual start of the "slave" node
do_start(Host, Node, Options) ->
diff --git a/lib/common_test/src/ct_snmp.erl b/lib/common_test/src/ct_snmp.erl
index 2c59b19196..5844909d17 100644
--- a/lib/common_test/src/ct_snmp.erl
+++ b/lib/common_test/src/ct_snmp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/common_test/src/ct_ssh.erl b/lib/common_test/src/ct_ssh.erl
index 6ab3bf036c..ca62357e1c 100644
--- a/lib/common_test/src/ct_ssh.erl
+++ b/lib/common_test/src/ct_ssh.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -68,7 +68,8 @@
send_and_receive/3, send_and_receive/4, send_and_receive/5,
send_and_receive/6,
exec/2, exec/3, exec/4,
- subsystem/3, subsystem/4]).
+ subsystem/3, subsystem/4,
+ shell/2, shell/3]).
%% STFP Functions
-export([sftp_connect/1,
@@ -94,6 +95,7 @@
-record(state, {ssh_ref, conn_type, target}).
+-type handle() :: pid().
%%%-----------------------------------------------------------------
%%%------------------------ SSH COMMANDS ---------------------------
@@ -159,7 +161,7 @@ connect(KeyOrName, ExtraOpts) when is_list(ExtraOpts) ->
connect(KeyOrName, ConnType, ExtraOpts) ->
case ct:get_config(KeyOrName) of
undefined ->
- log(heading(connect,KeyOrName), "Failed: ~p\n",
+ log(heading(connect,KeyOrName), "Failed: ~tp\n",
[{not_available,KeyOrName}]),
{error,{not_available,KeyOrName}};
SSHData ->
@@ -212,18 +214,18 @@ connect(KeyOrName, ConnType, ExtraOpts) ->
end,
case {Addr,proplists:get_value(port, AllOpts1)} of
{undefined,_} ->
- log(heading(connect,KeyOrName), "Failed: ~p\n",
+ log(heading(connect,KeyOrName), "Failed: ~tp\n",
[{not_available,{KeyOrName,ConnType1}}]),
{error,{not_available,{KeyOrName,ConnType1}}};
{_,undefined} ->
try_log(heading(connect,KeyOrName),
- "Opening ~w connection to ~p:22\n",
+ "Opening ~w connection to ~tp:22\n",
[ConnType1,Addr]),
ct_gen_conn:start(KeyOrName, {ConnType1,Addr,22},
AllOpts1, ?MODULE);
{_,Port} ->
try_log(heading(connect,KeyOrName),
- "Opening ~w connection to ~p:~w\n",
+ "Opening ~w connection to ~tp:~w\n",
[ConnType1,Addr,Port]),
ct_gen_conn:start(KeyOrName, {ConnType1,Addr,Port},
AllOpts1, ?MODULE)
@@ -490,6 +492,22 @@ subsystem(SSH, ChannelId, Subsystem, Timeout) ->
call(SSH, {subsystem,ChannelId,Subsystem,Timeout}).
+-spec shell(SSH, ChannelId) -> Result when
+ SSH :: handle() | ct:target_name(),
+ ChannelId :: ssh:ssh_channel_id(),
+ Result :: ok | {error,term()}.
+shell(SSH, ChannelId) ->
+ shell(SSH, ChannelId, ?DEFAULT_TIMEOUT).
+
+-spec shell(SSH, ChannelId, Timeout) -> Result when
+ SSH :: handle() | ct:target_name(),
+ ChannelId :: ssh:ssh_channel_id(),
+ Timeout :: timeout(),
+ Result :: ok | {error,term()}.
+shell(SSH, ChannelId, Timeout) ->
+ call(SSH, {shell,ChannelId,Timeout}).
+
+
%%%-----------------------------------------------------------------
%%%------------------------ SFTP COMMANDS --------------------------
@@ -977,7 +995,7 @@ init(KeyOrName, {ConnType,Addr,Port}, AllOpts) ->
SSHRef = element(2, Ok),
try_log(heading(init,KeyOrName),
"Opened ~w connection:\n"
- "Host: ~p (~p)\nUser: ~p\nPassword: ~p\n",
+ "Host: ~tp (~p)\nUser: ~tp\nPassword: ~p\n",
[ConnType,Addr,Port,User,lists:duplicate(length(Password),$*)]),
{ok,SSHRef,#state{ssh_ref=SSHRef, conn_type=ConnType,
target=KeyOrName}}
@@ -1015,11 +1033,11 @@ handle_msg({exec,Chn,Command,TO}, State) ->
end,
case Chn1 of
{error,_} = ChnError ->
- log(heading(exec,Target), "Opening channel failed: ~p", [ChnError]),
+ log(heading(exec,Target), "Opening channel failed: ~tp", [ChnError]),
{ChnError,State};
_ ->
try_log(heading(exec,Target),
- "SSH Ref: ~p, Chn: ~p, Command: ~p, Timeout: ~p",
+ "SSH Ref: ~p, Chn: ~p, Command: ~tp, Timeout: ~p",
[SSHRef,Chn1,Command,TO]),
case ssh_connection:exec(SSHRef, Chn1, Command, TO) of
success ->
@@ -1042,7 +1060,7 @@ handle_msg({send,Chn,Type,Data,TO}, State) ->
#state{ssh_ref=SSHRef, target=Target} = State,
try_log(heading(send,Target),
"SSH Ref: ~p, Chn: ~p, Type: ~p, Timeout: ~p~n"
- "Data: ~p", [SSHRef,Chn,Type,TO,Data]),
+ "Data: ~tp", [SSHRef,Chn,Type,TO,Data]),
Result = ssh_connection:send(SSHRef, Chn, Type, Data, TO),
{Result,State};
@@ -1050,7 +1068,7 @@ handle_msg({send_and_receive,Chn,Type,Data,End,TO}, State) ->
#state{ssh_ref=SSHRef, target=Target} = State,
try_log(heading(send_and_receive,Target),
"SSH Ref: ~p, Chn: ~p, Type: ~p, Timeout: ~p~n"
- "Data: ~p", [SSHRef,Chn,Type,TO,Data]),
+ "Data: ~tp", [SSHRef,Chn,Type,TO,Data]),
case ssh_connection:send(SSHRef, Chn, Type, Data, TO) of
ok ->
Result = do_recv_response(SSHRef, Chn, [], End, TO),
@@ -1062,160 +1080,168 @@ handle_msg({send_and_receive,Chn,Type,Data,End,TO}, State) ->
handle_msg({subsystem,Chn,Subsystem,TO}, State) ->
#state{ssh_ref=SSHRef, target=Target} = State,
try_log(heading(subsystem,Target),
- "SSH Ref: ~p, Chn: ~p, Subsys: ~p, Timeout: ~p",
+ "SSH Ref: ~p, Chn: ~p, Subsys: ~tp, Timeout: ~p",
[SSHRef,Chn,Subsystem,TO]),
Result = ssh_connection:subsystem(SSHRef, Chn, Subsystem, TO),
{Result,State};
+handle_msg({shell,Chn,TO}, State) ->
+ #state{ssh_ref=SSHRef, target=Target} = State,
+ try_log(heading(shell,Target),
+ "SSH Ref: ~p, Chn: ~p, Timeout: ~p",
+ [SSHRef,Chn,TO]),
+ Result = ssh_connection:shell(SSHRef, Chn),
+ {Result,State};
+
%% --- SFTP Commands ---
handle_msg({read_file,Srv,File}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:read_file(ref(Srv,SSHRef), File),S};
handle_msg({write_file,Srv,File,Iolist}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:write_file(ref(Srv,SSHRef), File, Iolist),S};
handle_msg({list_dir,Srv,Path}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:list_dir(ref(Srv,SSHRef), Path),S};
handle_msg({open,Srv,File,Mode}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:open(ref(Srv,SSHRef), File, Mode),S};
handle_msg({opendir,Srv,Path}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:opendir(ref(Srv,SSHRef), Path),S};
handle_msg({close,Srv,Handle}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:close(ref(Srv,SSHRef), Handle),S};
handle_msg({read,Srv,Handle,Len}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:read(ref(Srv,SSHRef), Handle, Len),S};
handle_msg({pread,Srv,Handle,Position,Length}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:pread(ref(Srv,SSHRef),Handle,Position,Length),S};
handle_msg({aread,Srv,Handle,Len}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:aread(ref(Srv,SSHRef), Handle, Len),S};
handle_msg({apread,Srv,Handle,Position,Length}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:apread(ref(Srv,SSHRef), Handle, Position, Length),S};
handle_msg({write,Srv,Handle,Data}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:write(ref(Srv,SSHRef), Handle, Data),S};
handle_msg({pwrite,Srv,Handle,Position,Data}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:pwrite(ref(Srv,SSHRef), Handle, Position, Data),S};
handle_msg({awrite,Srv,Handle,Data}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:awrite(ref(Srv,SSHRef), Handle, Data),S};
handle_msg({apwrite,Srv,Handle,Position,Data}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:apwrite(ref(Srv,SSHRef), Handle, Position, Data),S};
handle_msg({position,Srv,Handle,Location}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:position(ref(Srv,SSHRef), Handle, Location),S};
handle_msg({read_file_info,Srv,Name}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:read_file_info(ref(Srv,SSHRef), Name),S};
handle_msg({get_file_info,Srv,Handle}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:get_file_info(ref(Srv,SSHRef), Handle),S};
handle_msg({read_link_info,Srv,Name}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:read_link_info(ref(Srv,SSHRef), Name),S};
handle_msg({write_file_info,Srv,Name,Info}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:write_file_info(ref(Srv,SSHRef), Name, Info),S};
handle_msg({read_link,Srv,Name}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:read_link(ref(Srv,SSHRef), Name),S};
handle_msg({make_symlink,Srv,Name,Target}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:make_symlink(ref(Srv,SSHRef), Name, Target),S};
handle_msg({rename,Srv,OldName,NewName}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:rename(ref(Srv,SSHRef), OldName, NewName),S};
handle_msg({delete,Srv,Name}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:delete(ref(Srv,SSHRef), Name),S};
handle_msg({make_dir,Srv,Name}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:make_dir(ref(Srv,SSHRef), Name),S};
handle_msg({del_dir,Srv,Name}=Cmd, S=#state{ssh_ref=SSHRef}) ->
try_log(heading(sftp,S#state.target),
- "SSH Ref: ~p, Server: ~p~nCmd: ~p",
+ "SSH Ref: ~p, Server: ~p~nCmd: ~tp",
[SSHRef,ref(Srv,SSHRef),mod(Cmd)]),
{ssh_sftp:del_dir(ref(Srv,SSHRef), Name),S}.
@@ -1259,7 +1285,7 @@ do_recv_response(SSH, Chn, Data, End, Timeout) ->
{ssh_cm, SSH, {data,Chn,_,NewData}} ->
ssh_connection:adjust_window(SSH, Chn, size(NewData)),
- debug("RECVD~n~p", [binary_to_list(NewData)]),
+ debug("RECVD~n~tp", [binary_to_list(NewData)]),
DataAcc = Data ++ binary_to_list(NewData),
if is_function(End) ->
case End(DataAcc) of
@@ -1312,7 +1338,7 @@ do_recv_response(SSH, Chn, Data, End, Timeout) ->
%% {ok,WCh};
Other ->
- debug("UNEXPECTED MESSAGE~n~p ~p~n~p", [SSH,Chn,Other]),
+ debug("UNEXPECTED MESSAGE~n~p ~p~n~tp", [SSH,Chn,Other]),
do_recv_response(SSH, Chn, Data, End, Timeout)
after Timeout ->
@@ -1365,7 +1391,7 @@ mod(Cmd) ->
%%%-----------------------------------------------------------------
%%%
heading(Function, Ref) ->
- io_lib:format("ct_ssh:~w ~p",[Function,Ref]).
+ io_lib:format("ct_ssh:~tw ~tp",[Function,Ref]).
%%%-----------------------------------------------------------------
%%%
diff --git a/lib/common_test/src/ct_telnet.erl b/lib/common_test/src/ct_telnet.erl
index 8fb411ec4f..14d9d381da 100644
--- a/lib/common_test/src/ct_telnet.erl
+++ b/lib/common_test/src/ct_telnet.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -251,7 +251,7 @@ open(KeyOrName,ConnType,TargetMod) ->
open(KeyOrName,ConnType,TargetMod,Extra) ->
case ct:get_config({KeyOrName,ConnType}) of
undefined ->
- log(undefined,open,"Failed: ~p",[{not_available,KeyOrName}]),
+ log(undefined,open,"Failed: ~tp",[{not_available,KeyOrName}]),
{error,{not_available,KeyOrName,ConnType}};
Addr ->
Addr1 =
@@ -273,7 +273,7 @@ open(KeyOrName,ConnType,TargetMod,Extra) ->
end;
Bool -> Bool
end,
- log(undefined,open,"Connecting to ~p(~p)",
+ log(undefined,open,"Connecting to ~tp(~tp)",
[KeyOrName,Addr1]),
Reconnect =
case ct:get_config({telnet_settings,reconnection_attempts}) of
@@ -672,7 +672,7 @@ set_telnet_defaults([{tcp_nodelay,NoDelay}|Ss],S) ->
set_telnet_defaults(Ss,S#state{tcp_nodelay=NoDelay});
set_telnet_defaults([Unknown|Ss],S) ->
force_log(S,error,
- "Bad element in telnet_settings: ~p",[Unknown]),
+ "Bad element in telnet_settings: ~tp",[Unknown]),
set_telnet_defaults(Ss,S);
set_telnet_defaults([],S) ->
S.
@@ -680,7 +680,7 @@ set_telnet_defaults([],S) ->
%% @hidden
handle_msg({cmd,Cmd,Opts},State) ->
start_gen_log(heading(cmd,State#state.name)),
- log(State,cmd,"Cmd: ~p",[Cmd]),
+ log(State,cmd,"Cmd: ~tp",[Cmd]),
%% whatever is in the buffer from previous operations
%% will be ignored as we go ahead with this telnet cmd
@@ -715,7 +715,7 @@ handle_msg({cmd,Cmd,Opts},State) ->
case teln_cmd(State#state.teln_pid, Cmd, State#state.prx,
Newline, TO) of
{ok,Data,_PromptType,Rest} ->
- log(State,recv,"Return: ~p",[{ok,Data}]),
+ log(State,recv,"Return: ~tp",[{ok,Data}]),
{{ok,Data},Rest,true};
Error ->
Retry = {retry,{Error,
@@ -723,14 +723,14 @@ handle_msg({cmd,Cmd,Opts},State) ->
State#state.type},
State#state.teln_pid,
{cmd,Cmd,Opts}}},
- log(State,recv,"Return: ~p",[Error]),
+ log(State,recv,"Return: ~tp",[Error]),
{Retry,[],false}
end,
end_gen_log(),
{Return,State#state{buffer=NewBuffer,prompt=Prompt}};
handle_msg({send,Cmd,Opts},State) ->
start_gen_log(heading(send,State#state.name)),
- log(State,send,"Sending: ~p",[Cmd]),
+ log(State,send,"Sending: ~tp",[Cmd]),
debug_cont_gen_log("Throwing Buffer:",[]),
debug_log_lines(State#state.buffer),
@@ -762,12 +762,12 @@ handle_msg(get_data,State) ->
log(State,cmd,"Reading data...",[]),
{ok,Data,Buffer} = teln_get_all_data(State,State#state.buffer,[],[],
State#state.poll_limit),
- log(State,recv,"Return: ~p",[{ok,Data}]),
+ log(State,recv,"Return: ~tp",[{ok,Data}]),
end_gen_log(),
{{ok,Data},State#state{buffer=Buffer}};
handle_msg({expect,Pattern,Opts},State) ->
start_gen_log(heading(expect,State#state.name)),
- log(State,expect,"Expect: ~p\nOpts = ~p\n",[Pattern,Opts]),
+ log(State,expect,"Expect: ~tp\nOpts = ~tp\n",[Pattern,Opts]),
{Return,NewBuffer,Prompt} =
case teln_expect(State#state.name,
State#state.teln_pid,
@@ -779,15 +779,15 @@ handle_msg({expect,Pattern,Opts},State) ->
P = check_if_prompt_was_reached(Data,[]),
{{ok,Data},Rest,P};
{ok,Data,HaltReason,Rest} ->
- force_log(State,expect,"HaltReason: ~p",[HaltReason]),
+ force_log(State,expect,"HaltReason: ~tp",[HaltReason]),
P = check_if_prompt_was_reached(Data,HaltReason),
{{ok,Data,HaltReason},Rest,P};
{error,Reason,Rest} ->
- force_log(State,expect,"Expect failed\n~p",[{error,Reason}]),
+ force_log(State,expect,"Expect failed\n~tp",[{error,Reason}]),
P = check_if_prompt_was_reached([],Reason),
{{error,Reason},Rest,P};
{error,Reason} ->
- force_log(State,expect,"Expect failed\n~p",[{error,Reason}]),
+ force_log(State,expect,"Expect failed\n~tp",[{error,Reason}]),
P = check_if_prompt_was_reached([],Reason),
{{error,Reason},[],P}
end,
@@ -896,7 +896,7 @@ check_if_prompt_was_reached(_,_) ->
heading(Action,undefined) ->
io_lib:format("~w ~w",[?MODULE,Action]);
heading(Action,Name) ->
- io_lib:format("~w ~w for ~p",[?MODULE,Action,Name]).
+ io_lib:format("~w ~w for ~tp",[?MODULE,Action,Name]).
force_log(State,Action,String,Args) ->
log(State,Action,String,Args,true).
@@ -954,7 +954,7 @@ log(#state{name=Name,teln_pid=TelnPid,host=Host,port=Port},
true ->
ok;
false ->
- ct_gen_conn:cont_log(String,Args)
+ ct_gen_conn:cont_log_no_timestamp(String,Args)
end;
ForcePrint == true ->
@@ -965,7 +965,7 @@ log(#state{name=Name,teln_pid=TelnPid,host=Host,port=Port},
%% called
ct_gen_conn:log(heading(Action,Name1),String,Args);
false ->
- ct_gen_conn:cont_log(String,Args)
+ ct_gen_conn:cont_log_no_timestamp(String,Args)
end
end
end.
@@ -1224,7 +1224,6 @@ teln_expect1(Name,Pid,Data,Pattern,Acc,EO=#eo{idle_timeout=IdleTO,
EOMod = if TotalTO /= infinity -> EO#eo{total_timeout=trunc(TotalTO)};
true -> EO
end,
-
ExpectFun = case EOMod#eo.seq of
true -> fun() ->
seq_expect(Name,Pid,Data,Pattern,Acc,EOMod)
@@ -1247,38 +1246,34 @@ teln_expect1(Name,Pid,Data,Pattern,Acc,EO=#eo{idle_timeout=IdleTO,
true ->
IdleTO
end,
+ {PatOrPats1,Acc1,Rest1} = case NotFinished of
+ {nomatch,Rest0} ->
+ %% one expect
+ {Pattern,[],Rest0};
+ {continue,Pats0,Acc0,Rest0} ->
+ %% sequence
+ {Pats0,Acc0,Rest0}
+ end,
case timer:tc(ct_gen_conn, do_within_time, [Fun,BreakAfter]) of
- {_,{error,Reason}} ->
+ {_,{error,Reason}} ->
%% A timeout will occur when the telnet connection
%% is idle for EO#eo.idle_timeout milliseconds.
+ if Rest1 /= [] ->
+ log(name_or_pid(Name,Pid)," ~ts",[Rest1]);
+ true ->
+ ok
+ end,
{error,Reason};
{_,{ok,Data1}} when TotalTO == infinity ->
- case NotFinished of
- {nomatch,Rest} ->
- %% One expect
- teln_expect1(Name,Pid,Rest++Data1,
- Pattern,[],EOMod);
- {continue,Patterns1,Acc1,Rest} ->
- %% Sequence
- teln_expect1(Name,Pid,Rest++Data1,
- Patterns1,Acc1,EOMod)
- end;
+ teln_expect1(Name,Pid,Rest1++Data1,PatOrPats1,Acc1,EOMod);
{Elapsed,{ok,Data1}} ->
TVal = TotalTO - (Elapsed/1000),
if TVal =< 0 ->
{error,timeout};
true ->
EO1 = EO#eo{total_timeout = TVal},
- case NotFinished of
- {nomatch,Rest} ->
- %% One expect
- teln_expect1(Name,Pid,Rest++Data1,
- Pattern,[],EO1);
- {continue,Patterns1,Acc1,Rest} ->
- %% Sequence
- teln_expect1(Name,Pid,Rest++Data1,
- Patterns1,Acc1,EO1)
- end
+ teln_expect1(Name,Pid,Rest1++Data1,
+ PatOrPats1,Acc1,EO1)
end
end
end.
@@ -1299,7 +1294,7 @@ get_data1(Pid) ->
%% one_expect: split data chunk at prompts
one_expect(Name,Pid,Data,Pattern,EO) when EO#eo.prompt_check==false ->
-% io:format("Raw Data ~p Pattern ~p EO ~p ",[Data,Pattern,EO]),
+% io:format("Raw Data ~tp Pattern ~tp EO ~tp ",[Data,Pattern,EO]),
one_expect1(Name,Pid,Data,Pattern,[],EO#eo{found_prompt=false});
one_expect(Name,Pid,Data,Pattern,EO) ->
case match_prompt(Data,EO#eo.prx) of
@@ -1416,14 +1411,14 @@ match_lines(Name,Pid,Data,Patterns,EO) ->
case one_line(Data,[]) of
{noline,Rest} when FoundPrompt=/=false ->
%% This is the line including the prompt
- case match_line(Name,Pid,Rest,Patterns,FoundPrompt,EO) of
+ case match_line(Name,Pid,Rest,Patterns,FoundPrompt,false,EO) of
nomatch ->
{nomatch,prompt};
{Tag,Match} ->
{Tag,Match,[]}
end;
{noline,Rest} when EO#eo.prompt_check==false ->
- case match_line(Name,Pid,Rest,Patterns,false,EO) of
+ case match_line(Name,Pid,Rest,Patterns,false,false,EO) of
nomatch ->
{nomatch,Rest};
{Tag,Match} ->
@@ -1432,7 +1427,7 @@ match_lines(Name,Pid,Data,Patterns,EO) ->
{noline,Rest} ->
{nomatch,Rest};
{Line,Rest} ->
- case match_line(Name,Pid,Line,Patterns,false,EO) of
+ case match_line(Name,Pid,Line,Patterns,false,true,EO) of
nomatch ->
match_lines(Name,Pid,Rest,Patterns,EO);
{Tag,Match} ->
@@ -1440,45 +1435,50 @@ match_lines(Name,Pid,Data,Patterns,EO) ->
end
end.
-
%% For one line, match each pattern
-match_line(Name,Pid,Line,Patterns,FoundPrompt,EO) ->
- match_line(Name,Pid,Line,Patterns,FoundPrompt,EO,match).
+match_line(Name,Pid,Line,Patterns,FoundPrompt,Terminated,EO) ->
+ match_line(Name,Pid,Line,Patterns,FoundPrompt,Terminated,EO,match).
-match_line(Name,Pid,Line,[prompt|Patterns],false,EO,RetTag) ->
- match_line(Name,Pid,Line,Patterns,false,EO,RetTag);
-match_line(Name,Pid,Line,[prompt|_Patterns],FoundPrompt,_EO,RetTag) ->
+match_line(Name,Pid,Line,[prompt|Patterns],false,Term,EO,RetTag) ->
+ match_line(Name,Pid,Line,Patterns,false,Term,EO,RetTag);
+match_line(Name,Pid,Line,[prompt|_Patterns],FoundPrompt,_Term,_EO,RetTag) ->
log(name_or_pid(Name,Pid)," ~ts",[Line]),
log(name_or_pid(Name,Pid),"PROMPT: ~ts",[FoundPrompt]),
{RetTag,{prompt,FoundPrompt}};
-match_line(Name,Pid,Line,[{prompt,PromptType}|_Patterns],FoundPrompt,_EO,RetTag)
- when PromptType==FoundPrompt ->
+match_line(Name,Pid,Line,[{prompt,PromptType}|_Patterns],FoundPrompt,_Term,
+ _EO,RetTag) when PromptType==FoundPrompt ->
log(name_or_pid(Name,Pid)," ~ts",[Line]),
log(name_or_pid(Name,Pid),"PROMPT: ~ts",[FoundPrompt]),
{RetTag,{prompt,FoundPrompt}};
-match_line(Name,Pid,Line,[{prompt,PromptType}|Patterns],FoundPrompt,EO,RetTag)
+match_line(Name,Pid,Line,[{prompt,PromptType}|Patterns],FoundPrompt,Term,
+ EO,RetTag)
when PromptType=/=FoundPrompt ->
- match_line(Name,Pid,Line,Patterns,FoundPrompt,EO,RetTag);
-match_line(Name,Pid,Line,[{Tag,Pattern}|Patterns],FoundPrompt,EO,RetTag) ->
+ match_line(Name,Pid,Line,Patterns,FoundPrompt,Term,EO,RetTag);
+match_line(Name,Pid,Line,[{Tag,Pattern}|Patterns],FoundPrompt,Term,EO,RetTag) ->
case re:run(Line,Pattern,[{capture,all,list}]) of
nomatch ->
- match_line(Name,Pid,Line,Patterns,FoundPrompt,EO,RetTag);
+ match_line(Name,Pid,Line,Patterns,FoundPrompt,Term,EO,RetTag);
{match,Match} ->
log(name_or_pid(Name,Pid),"MATCH: ~ts",[Line]),
{RetTag,{Tag,Match}}
end;
-match_line(Name,Pid,Line,[Pattern|Patterns],FoundPrompt,EO,RetTag) ->
+match_line(Name,Pid,Line,[Pattern|Patterns],FoundPrompt,Term,EO,RetTag) ->
case re:run(Line,Pattern,[{capture,all,list}]) of
nomatch ->
- match_line(Name,Pid,Line,Patterns,FoundPrompt,EO,RetTag);
+ match_line(Name,Pid,Line,Patterns,FoundPrompt,Term,EO,RetTag);
{match,Match} ->
log(name_or_pid(Name,Pid),"MATCH: ~ts",[Line]),
{RetTag,Match}
end;
-match_line(Name,Pid,Line,[],FoundPrompt,EO,match) ->
- match_line(Name,Pid,Line,EO#eo.haltpatterns,FoundPrompt,EO,halt);
-match_line(Name,Pid,Line,[],_FoundPrompt,_EO,halt) ->
+match_line(Name,Pid,Line,[],FoundPrompt,Term,EO,match) ->
+ match_line(Name,Pid,Line,EO#eo.haltpatterns,FoundPrompt,Term,EO,halt);
+%% print any terminated line that can not be matched
+match_line(Name,Pid,Line,[],_FoundPrompt,true,_EO,halt) ->
log(name_or_pid(Name,Pid)," ~ts",[Line]),
+ nomatch;
+%% if there's no line termination, Line is saved as Rest (above) and will
+%% be printed later
+match_line(_Name,_Pid,_Line,[],_FoundPrompt,false,_EO,halt) ->
nomatch.
one_line([$\n|Rest],Line) ->
diff --git a/lib/common_test/src/ct_telnet_client.erl b/lib/common_test/src/ct_telnet_client.erl
index 5df7e279ac..c8d217cd2a 100644
--- a/lib/common_test/src/ct_telnet_client.erl
+++ b/lib/common_test/src/ct_telnet_client.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -120,7 +120,7 @@ get_data(Pid) ->
init(Parent, Server, Port, Timeout, KeepAlive, NoDelay, ConnName) ->
case gen_tcp:connect(Server, Port, [list,{packet,0},{nodelay,NoDelay}], Timeout) of
{ok,Sock} ->
- dbg("~p connected to: ~p (port: ~w, keep_alive: ~w)\n",
+ dbg("~tp connected to: ~tp (port: ~w, keep_alive: ~w)\n",
[ConnName,Server,Port,KeepAlive]),
send([?IAC,?DO,?SUPPRESS_GO_AHEAD], Sock, ConnName),
Parent ! {open,self()},
diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl
index 991abb0666..09839bd35d 100644
--- a/lib/common_test/src/ct_testspec.erl
+++ b/lib/common_test/src/ct_testspec.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -26,7 +26,8 @@
-export([prepare_tests/1, prepare_tests/2,
collect_tests_from_list/2, collect_tests_from_list/3,
- collect_tests_from_file/2, collect_tests_from_file/3]).
+ collect_tests_from_file/2, collect_tests_from_file/3,
+ get_tests/1]).
-export([testspec_rec2list/1, testspec_rec2list/2]).
@@ -343,7 +344,7 @@ create_spec_tree([Spec|Specs],TS,JoinWithNext,Known) ->
create_spec_tree(Specs,TS,JoinWithNext,Known)};
{error,Reason} ->
ReasonStr =
- lists:flatten(io_lib:format("~s",
+ lists:flatten(io_lib:format("~ts",
[file:format_error(Reason)])),
throw({error,{SpecAbsName,ReasonStr}})
end
@@ -803,6 +804,31 @@ list_nodes(#testspec{nodes=NodeRefs}) ->
lists:map(fun({_Ref,Node}) -> Node end, NodeRefs).
+%%%-----------------------------------------------------------------
+%%% Parse the given test specs and return the complete set of specs
+%%% and tests to run/skip.
+%%% [Spec1,Spec2,...] means create separate tests per spec
+%%% [[Spec1,Spec2,...]] means merge all specs into one
+-spec get_tests(Specs) -> {ok,[{Specs,Tests}]} | {error,Reason} when
+ Specs :: [string()] | [[string()]],
+ Tests :: {Node,Run,Skip},
+ Node :: atom(),
+ Run :: {Dir,Suites,Cases},
+ Skip :: {Dir,Suites,Comment} | {Dir,Suites,Cases,Comment},
+ Dir :: string(),
+ Suites :: atom | [atom()] | all,
+ Cases :: atom | [atom()] | all,
+ Comment :: string(),
+ Reason :: term().
+
+get_tests(Specs) ->
+ case collect_tests_from_file(Specs,true) of
+ Tests when is_list(Tests) ->
+ {ok,[{S,prepare_tests(R)} || {S,R} <- Tests]};
+ Error ->
+ Error
+ end.
+
%% -----------------------------------------------------
%% / \
%% | When adding test/config terms, remember to update |
@@ -1075,7 +1101,7 @@ check_term(Term) when is_tuple(Term) ->
true ->
io:format("~nSuspicious term, "
"please check:~n"
- "~p~n", [Term]),
+ "~tp~n", [Term]),
invalid;
false ->
invalid
@@ -1132,6 +1158,11 @@ handle_data(verbosity,Node,VLvls,_Spec) when is_list(VLvls) ->
VLvls1 = lists:map(fun(VLvl = {_Cat,_Lvl}) -> VLvl;
(Lvl) -> {'$unspecified',Lvl} end, VLvls),
[{Node,VLvls1}];
+handle_data(multiply_timetraps,Node,Mult,_Spec) when is_integer(Mult) ->
+ [{Node,Mult}];
+handle_data(scale_timetraps,Node,Scale,_Spec) when Scale == true;
+ Scale == false ->
+ [{Node,Scale}];
handle_data(silent_connections,Node,all,_Spec) ->
[{Node,[all]}];
handle_data(silent_connections,Node,Conn,_Spec) when is_atom(Conn) ->
@@ -1150,6 +1181,8 @@ should_be_added(Tag,Node,_Data,Spec) ->
Tag == label; Tag == auto_compile;
Tag == abort_if_missing_suites;
Tag == stylesheet; Tag == verbosity;
+ Tag == multiply_timetraps;
+ Tag == scale_timetraps;
Tag == silent_connections ->
lists:keymember(ref2node(Node,Spec#testspec.nodes),1,
read_field(Spec,Tag)) == false;
diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl
index 82a8743cf0..abf131f4df 100644
--- a/lib/common_test/src/ct_util.erl
+++ b/lib/common_test/src/ct_util.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -188,6 +188,8 @@ do_start(Parent, Mode, LogDir, Verbosity) ->
ok
end,
+ ct_default_gl:start_link(group_leader()),
+
{StartTime,TestLogDir} = ct_logs:init(Mode, Verbosity),
ct_event:notify(#event{name=test_start,
@@ -199,20 +201,13 @@ do_start(Parent, Mode, LogDir, Verbosity) ->
ok ->
Parent ! {self(),started};
{fail,CTHReason} ->
- ErrorInfo = if is_atom(CTHReason) ->
- io_lib:format("{~p,~p}",
- [CTHReason,
- erlang:get_stacktrace()]);
- true ->
- CTHReason
- end,
- ct_logs:tc_print('Suite Callback',ErrorInfo,[]),
+ ct_logs:tc_print('Suite Callback',CTHReason,[]),
self() ! {{stop,{self(),{user_error,CTHReason}}},
{Parent,make_ref()}}
catch
_:CTHReason ->
ErrorInfo = if is_atom(CTHReason) ->
- io_lib:format("{~p,~p}",
+ io_lib:format("{~tp,~tp}",
[CTHReason,
erlang:get_stacktrace()]);
true ->
@@ -474,6 +469,7 @@ loop(Mode,TestData,StartDir) ->
ct_logs:close(Info, StartDir),
ct_event:stop(),
ct_config:stop(),
+ ct_default_gl:stop(),
ok = file:set_cwd(StartDir),
return(From, Info);
{Ref, _Msg} when is_reference(Ref) ->
@@ -494,7 +490,7 @@ loop(Mode,TestData,StartDir) ->
?MAX_IMPORTANCE,
"CT Error Notification",
"Connection process died: "
- "Pid: ~w, Address: ~p, "
+ "Pid: ~w, Address: ~tp, "
"Callback: ~w\n"
"Reason: ~ts\n\n",
[Pid,A,CB,ErrorHtml]),
@@ -505,7 +501,7 @@ loop(Mode,TestData,StartDir) ->
_ ->
%% Let process crash in case of error, this shouldn't happen!
io:format("\n\nct_util_server got EXIT "
- "from ~w: ~p\n\n", [Pid,Reason]),
+ "from ~w: ~tp\n\n", [Pid,Reason]),
ok = file:set_cwd(StartDir),
exit(Reason)
end
@@ -926,7 +922,8 @@ warn_duplicates(Suites) ->
[] ->
ok;
_ ->
- io:format(user,"~nWARNING! Deprecated function: ~w:sequences/0.~n"
+ io:format(?def_gl,
+ "~nWARNING! Deprecated function: ~w:sequences/0.~n"
" Use group with sequence property instead.~n",[Mod])
end
end,
@@ -980,12 +977,12 @@ get_profile_data(Profile, Key, StartDir) ->
end,
case Result of
{error,enoent} when Profile /= default ->
- io:format(user, "~nERROR! Missing profile file ~p~n", [File]),
+ io:format(?def_gl, "~nERROR! Missing profile file ~tp~n", [File]),
undefined;
{error,enoent} when Profile == default ->
undefined;
{error,Reason} ->
- io:format(user,"~nERROR! Error in profile file ~p: ~p~n",
+ io:format(?def_gl,"~nERROR! Error in profile file ~tp: ~tp~n",
[WhichFile,Reason]),
undefined;
{ok,Data} ->
@@ -995,8 +992,8 @@ get_profile_data(Profile, Key, StartDir) ->
_ when is_list(Data) ->
Data;
_ ->
- io:format(user,
- "~nERROR! Invalid profile data in ~p~n",
+ io:format(?def_gl,
+ "~nERROR! Invalid profile data in ~tp~n",
[WhichFile]),
[]
end,
@@ -1082,10 +1079,10 @@ open_url(iexplore, Args, URL) ->
Path = proplists:get_value(default, Paths),
[Cmd | _] = string:tokens(Path, "%"),
Cmd1 = Cmd ++ " " ++ Args ++ " " ++ URL,
- io:format(user, "~nOpening ~ts with command:~n ~ts~n", [URL,Cmd1]),
+ io:format(?def_gl, "~nOpening ~ts with command:~n ~ts~n", [URL,Cmd1]),
open_port({spawn,Cmd1}, []);
_ ->
- io:format("~nNo path to iexplore.exe~n",[])
+ io:format(?def_gl, "~nNo path to iexplore.exe~n",[])
end,
win32reg:close(R),
ok;
@@ -1095,6 +1092,6 @@ open_url(Prog, Args, URL) ->
is_list(Prog) -> Prog
end,
Cmd = ProgStr ++ " " ++ Args ++ " " ++ URL,
- io:format(user, "~nOpening ~ts with command:~n ~ts~n", [URL,Cmd]),
+ io:format(?def_gl, "~nOpening ~ts with command:~n ~ts~n", [URL,Cmd]),
open_port({spawn,Cmd},[]),
ok.
diff --git a/lib/common_test/src/ct_util.hrl b/lib/common_test/src/ct_util.hrl
index d7efa26863..039c8168ec 100644
--- a/lib/common_test/src/ct_util.hrl
+++ b/lib/common_test/src/ct_util.hrl
@@ -23,6 +23,7 @@
-define(board_table,ct_boards).
-define(suite_table,ct_suite_data).
-define(verbosity_table,ct_verbosity_table).
+-define(def_gl, ct_default_gl).
-record(conn, {handle,
targetref,
diff --git a/lib/common_test/src/ct_webtool.erl b/lib/common_test/src/ct_webtool.erl
index 87af442fd3..9016aca899 100644
--- a/lib/common_test/src/ct_webtool.erl
+++ b/lib/common_test/src/ct_webtool.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -120,10 +120,10 @@ debug_app(Mod) ->
out(_,{trace_ts,Pid,call,MFA={M,F,A},{W,_,_},TS},_,S)
when W==webtool;W==mod_esi->
- io:format("~w: (~p)~ncall ~s~n", [TS,Pid,ffunc(MFA)]),
+ io:format("~w: (~p)~ncall ~ts~n", [TS,Pid,ffunc(MFA)]),
[{M,F,length(A)}|S];
out(_,{trace_ts,Pid,return_from,MFA,R,TS},_,[MFA|S]) ->
- io:format("~w: (~p)~nreturned from ~s -> ~p~n", [TS,Pid,ffunc(MFA),R]),
+ io:format("~w: (~p)~nreturned from ~ts -> ~tp~n", [TS,Pid,ffunc(MFA),R]),
S;
out(_,_,_,_) ->
ok.
@@ -171,7 +171,7 @@ script_start([App,Browser]) ->
IExplore=filename:join(win32reg:expand(Val),"iexplore.exe"),
os:cmd("\"" ++ IExplore ++ "\" " ++ Url);
_ when OSType == win32 ->
- io:format("Starting ~w...\n",[Browser]),
+ io:format("Starting ~tw...\n",[Browser]),
os:cmd("\"" ++ atom_to_list(Browser) ++ "\" " ++ Url);
B when B==firefox; B==mozilla ->
io:format("Sending URL to ~w...",[Browser]),
@@ -194,7 +194,7 @@ script_start([App,Browser]) ->
os:cmd(BStr ++ " " ++ Url)
end;
_ ->
- io:format("Starting ~w...\n",[Browser]),
+ io:format("Starting ~tw...\n",[Browser]),
os:cmd(atom_to_list(Browser) ++ " " ++ Url)
end,
ok;
@@ -379,7 +379,7 @@ print_url(ConfigData)->
Server=proplists:get_value(server_name,ConfigData,"undefined"),
Port=proplists:get_value(port,ConfigData,"undefined"),
{A,B,C,D}=proplists:get_value(bind_address,ConfigData,"undefined"),
- io:format("WebTool is available at http://~s:~w/~n",[Server,Port]),
+ io:format("WebTool is available at http://~ts:~w/~n",[Server,Port]),
io:format("Or http://~w.~w.~w.~w:~w/~n",[A,B,C,D,Port]).
@@ -859,8 +859,8 @@ handle_app({Name,{start,{func,Start,Stop}}},Data,_Pid,Cmd)->
%%! Here the tool disappears from the webtool interface!!
io:format("\n=======ERROR (webtool, line ~w) =======\n"
"Could not start application \'~p\'\n\n"
- "~w:~w(~s) ->\n"
- "~p\n\n",
+ "~w:~tw(~ts) ->\n"
+ "~tp\n\n",
[?LINE,Name,M,F,format_args(A),Exit]),
ets:delete(Data,Name);
_OK->
@@ -883,16 +883,16 @@ handle_app({Name,{start,{child,ChildSpec}}},Data,Pid,Cmd)->
%%! Here the tool disappears from the webtool interface!!
io:format("\n=======ERROR (webtool, line ~w) =======\n"
"Could not start application \'~p\'\n\n"
- "supervisor:start_child(~p,~p) ->\n"
- "~p\n\n",
+ "supervisor:start_child(~p,~tp) ->\n"
+ "~tp\n\n",
[?LINE,Name,Pid,ChildSpec,{error,Reason}]),
ets:delete(Data,Name);
Error ->
%%! Here the tool disappears from the webtool interface!!
io:format("\n=======ERROR (webtool, line ~w) =======\n"
"Could not start application \'~p\'\n\n"
- "supervisor:start_child(~p,~p) ->\n"
- "~p\n\n",
+ "supervisor:start_child(~p,~tp) ->\n"
+ "~tp\n\n",
[?LINE,Name,Pid,ChildSpec,Error]),
ets:delete(Data,Name)
end;
@@ -924,7 +924,7 @@ handle_app({Name,{start,{app,Real_name}}},Data,_Pid,Cmd)->
io:format("\n=======ERROR (webtool, line ~w) =======\n"
"Could not start application \'~p\'\n\n"
"application:start(~p,~p) ->\n"
- "~p\n\n",
+ "~tp\n\n",
[?LINE,Name,Real_name,temporary,Error]),
ets:delete(Data,Name)
end;
@@ -940,7 +940,7 @@ handle_app({Name,Incorrect},Data,_Pid,Cmd)->
%%! Here the tool disappears from the webtool interface!!
io:format("\n=======ERROR (webtool, line ~w) =======\n"
"Could not ~w application \'~p\'\n\n"
- "Incorrect data: ~p\n\n",
+ "Incorrect data: ~tp\n\n",
[?LINE,Cmd,Name,Incorrect]),
ets:delete(Data,Name).
@@ -1202,12 +1202,12 @@ filter_tool_files(Dir,[File|Rest]) ->
%%%-----------------------------------------------------------------
%%% format functions
ffunc({M,F,A}) when is_list(A) ->
- io_lib:format("~w:~w(~s)\n",[M,F,format_args(A)]);
+ io_lib:format("~w:~tw(~ts)\n",[M,F,format_args(A)]);
ffunc({M,F,A}) when is_integer(A) ->
- io_lib:format("~w:~w/~w\n",[M,F,A]).
+ io_lib:format("~w:~tw/~w\n",[M,F,A]).
format_args([]) ->
"";
format_args(Args) ->
- Str = lists:append(["~p"|lists:duplicate(length(Args)-1,",~p")]),
+ Str = lists:append(["~tp"|lists:duplicate(length(Args)-1,",~tp")]),
io_lib:format(Str,Args).
diff --git a/lib/common_test/src/cth_conn_log.erl b/lib/common_test/src/cth_conn_log.erl
index 883da0da0a..7b6f03311a 100644
--- a/lib/common_test/src/cth_conn_log.erl
+++ b/lib/common_test/src/cth_conn_log.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,11 +24,11 @@
%%
%% suite() ->
%% [{ct_hooks, [{cth_conn_log,
-%% [{ct_netconfc:conn_mod(),ct_netconfc:hook_options()}]}]}].
+%% [{conn_mod(),hook_options()}]}]}].
%%
%% or specified in a configuration file:
%%
-%% {ct_conn_log,[{ct_netconfc:conn_mod(),ct_netconfc:hook_options()}]}.
+%% {ct_conn_log,[{conn_mod(),hook_options()}]}.
%%
%% The conn_mod() is the common test module implementing the protocol,
%% e.g. ct_netconfc, ct_telnet, etc. This module must log by calling
@@ -54,32 +54,21 @@
-include_lib("common_test/include/ct.hrl").
-export([init/2,
- pre_init_per_testcase/3,
- post_end_per_testcase/4]).
-
-%%----------------------------------------------------------------------
-%% Exported types
-%%----------------------------------------------------------------------
--export_type([hook_options/0,
- log_type/0,
- conn_mod/0]).
+ pre_init_per_testcase/4,
+ post_end_per_testcase/5]).
%%----------------------------------------------------------------------
%% Type declarations
%%----------------------------------------------------------------------
--type hook_options() :: [hook_option()].
-%% Options that can be given to `cth_conn_log' in the `ct_hook' statement.
--type hook_option() :: {log_type,log_type()} |
- {hosts,[ct_gen_conn:key_or_name()]}.
--type log_type() :: raw | pretty | html | silent.
--type conn_mod() :: ct_netconfc | ct_telnet.
+-type hook_options() :: ct:conn_log_options().
+-type log_type() :: ct:conn_log_type().
+-type conn_mod() :: ct:conn_log_mod().
%%----------------------------------------------------------------------
-spec init(Id, HookOpts) -> Result when
Id :: term(),
HookOpts :: hook_options(),
- Result :: {ok,[{conn_mod(),
- {log_type(),[ct_gen_conn:key_or_name()]}}]}.
+ Result :: {ok,[{conn_mod(),{log_type(),[ct:key_or_name()]}}]}.
init(_Id, HookOpts) ->
ConfOpts = ct:get_config(ct_conn_log,[]),
{ok,merge_log_info(ConfOpts,HookOpts)}.
@@ -104,7 +93,7 @@ get_log_opts(Mod,Opts) ->
Hosts = proplists:get_value(hosts,Opts,[]),
{LogType,Hosts}.
-pre_init_per_testcase(TestCase,Config,CthState) ->
+pre_init_per_testcase(_Suite,TestCase,Config,CthState) ->
Logs =
lists:map(
fun({ConnMod,{LogType,Hosts}}) ->
@@ -127,7 +116,7 @@ pre_init_per_testcase(TestCase,Config,CthState) ->
"<table borders=1>"
"<b>" ++ ConnModStr ++ " logs:</b>\n" ++
[io_lib:format(
- "<tr><td>~p</td><td><a href=\"~ts\">~ts</a>"
+ "<tr><td>~tp</td><td><a href=\"~ts\">~ts</a>"
"</td></tr>",
[S,ct_logs:uri(L),filename:basename(L)])
|| {S,L} <- Ls] ++
@@ -158,7 +147,7 @@ pre_init_per_testcase(TestCase,Config,CthState) ->
ct_util:update_testdata(?MODULE, Update, [create]),
{Config,CthState}.
-post_end_per_testcase(TestCase,_Config,Return,CthState) ->
+post_end_per_testcase(_Suite,TestCase,_Config,Return,CthState) ->
Update =
fun(PrevUsers) ->
case lists:delete(TestCase, PrevUsers) of
diff --git a/lib/common_test/src/cth_log_redirect.erl b/lib/common_test/src/cth_log_redirect.erl
index 6d77d7ee9e..8b29d0f96d 100644
--- a/lib/common_test/src/cth_log_redirect.erl
+++ b/lib/common_test/src/cth_log_redirect.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -28,10 +28,10 @@
%% CTH Callbacks
-export([id/1, init/2,
pre_init_per_suite/3, pre_end_per_suite/3, post_end_per_suite/4,
- pre_init_per_group/3, post_init_per_group/4,
- pre_end_per_group/3, post_end_per_group/4,
- pre_init_per_testcase/3, post_init_per_testcase/4,
- pre_end_per_testcase/3, post_end_per_testcase/4]).
+ pre_init_per_group/4, post_init_per_group/5,
+ pre_end_per_group/4, post_end_per_group/5,
+ pre_init_per_testcase/4, post_init_per_testcase/5,
+ pre_end_per_testcase/4, post_end_per_testcase/5]).
%% Event handler Callbacks
-export([init/1,
@@ -71,11 +71,11 @@ post_end_per_suite(_Suite, Config, Return, State) ->
set_curr_func(undefined, Config),
{Return, State}.
-pre_init_per_group(Group, Config, State) ->
+pre_init_per_group(_Suite, Group, Config, State) ->
set_curr_func({group,Group,init_per_group}, Config),
{Config, State}.
-post_init_per_group(Group, Config, Result, tc_log_async) when is_list(Config) ->
+post_init_per_group(_Suite, Group, Config, Result, tc_log_async) when is_list(Config) ->
case lists:member(parallel,proplists:get_value(
tc_group_properties,Config,[])) of
true ->
@@ -83,33 +83,33 @@ post_init_per_group(Group, Config, Result, tc_log_async) when is_list(Config) ->
false ->
{Result, tc_log_async}
end;
-post_init_per_group(_Group, _Config, Result, State) ->
+post_init_per_group(_Suite, _Group, _Config, Result, State) ->
{Result, State}.
-pre_init_per_testcase(TC, Config, State) ->
+pre_init_per_testcase(_Suite, TC, Config, State) ->
set_curr_func(TC, Config),
{Config, State}.
-post_init_per_testcase(_TC, _Config, Return, State) ->
+post_init_per_testcase(_Suite, _TC, _Config, Return, State) ->
{Return, State}.
-pre_end_per_testcase(_TC, Config, State) ->
+pre_end_per_testcase(_Suite, _TC, Config, State) ->
{Config, State}.
-post_end_per_testcase(_TC, _Config, Result, State) ->
+post_end_per_testcase(_Suite, _TC, _Config, Result, State) ->
%% Make sure that the event queue is flushed
%% before ending this test case.
gen_event:call(error_logger, ?MODULE, flush, 300000),
{Result, State}.
-pre_end_per_group(Group, Config, {tc_log, Group}) ->
+pre_end_per_group(_Suite, Group, Config, {tc_log, Group}) ->
set_curr_func({group,Group,end_per_group}, Config),
{Config, set_log_func(tc_log_async)};
-pre_end_per_group(Group, Config, State) ->
+pre_end_per_group(_Suite, Group, Config, State) ->
set_curr_func({group,Group,end_per_group}, Config),
{Config, State}.
-post_end_per_group(_Group, Config, Return, State) ->
+post_end_per_group(_Suite, _Group, Config, Return, State) ->
set_curr_func({group,undefined}, Config),
{Return, State}.
@@ -250,26 +250,26 @@ format_header(#eh_state{curr_suite = Suite,
format_header(#eh_state{curr_suite = Suite,
curr_group = undefined,
curr_func = TcOrConf}) ->
- io_lib:format("System report during ~w:~w/1",
+ io_lib:format("System report during ~w:~tw/1",
[Suite,TcOrConf]);
format_header(#eh_state{curr_suite = Suite,
curr_group = Group,
curr_func = Conf}) when Conf == init_per_group;
Conf == end_per_group ->
- io_lib:format("System report during ~w:~w/2 for ~w",
+ io_lib:format("System report during ~w:~w/2 for ~tw",
[Suite,Conf,Group]);
format_header(#eh_state{curr_suite = Suite,
curr_group = Group,
parallel_tcs = true}) ->
- io_lib:format("System report during ~w in ~w",
+ io_lib:format("System report during ~tw in ~w",
[Group,Suite]);
format_header(#eh_state{curr_suite = Suite,
curr_group = Group,
curr_func = TC}) ->
- io_lib:format("System report during ~w:~w/1 in ~w",
+ io_lib:format("System report during ~w:~tw/1 in ~tw",
[Suite,TC,Group]).
code_change(_OldVsn, State, _Extra) ->
diff --git a/lib/common_test/src/cth_surefire.erl b/lib/common_test/src/cth_surefire.erl
index 59b916851e..da68bd105e 100644
--- a/lib/common_test/src/cth_surefire.erl
+++ b/lib/common_test/src/cth_surefire.erl
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,16 +33,16 @@
-export([pre_end_per_suite/3]).
-export([post_end_per_suite/4]).
--export([pre_init_per_group/3]).
--export([post_init_per_group/4]).
--export([pre_end_per_group/3]).
--export([post_end_per_group/4]).
+-export([pre_init_per_group/4]).
+-export([post_init_per_group/5]).
+-export([pre_end_per_group/4]).
+-export([post_end_per_group/5]).
--export([pre_init_per_testcase/3]).
--export([post_end_per_testcase/4]).
+-export([pre_init_per_testcase/4]).
+-export([post_end_per_testcase/5]).
--export([on_tc_fail/3]).
--export([on_tc_skip/3]).
+-export([on_tc_fail/4]).
+-export([on_tc_skip/4]).
-export([terminate/1]).
@@ -116,40 +116,39 @@ pre_end_per_suite(_Suite,Config,State) ->
post_end_per_suite(_Suite,Config,Result,State) ->
{Result, end_tc(end_per_suite,Config,Result,State)}.
-pre_init_per_group(Group,Config,State) ->
+pre_init_per_group(_Suite,Group,Config,State) ->
{Config, init_tc(State#state{ curr_group = [Group|State#state.curr_group]},
Config)}.
-post_init_per_group(_Group,Config,Result,State) ->
+post_init_per_group(_Suite,_Group,Config,Result,State) ->
{Result, end_tc(init_per_group,Config,Result,State)}.
-pre_end_per_group(_Group,Config,State) ->
+pre_end_per_group(_Suite,_Group,Config,State) ->
{Config, init_tc(State, Config)}.
-post_end_per_group(_Group,Config,Result,State) ->
+post_end_per_group(_Suite,_Group,Config,Result,State) ->
NewState = end_tc(end_per_group, Config, Result, State),
{Result, NewState#state{ curr_group = tl(NewState#state.curr_group)}}.
-pre_init_per_testcase(_TC,Config,State) ->
+pre_init_per_testcase(_Suite,_TC,Config,State) ->
{Config, init_tc(State, Config)}.
-post_end_per_testcase(TC,Config,Result,State) ->
+post_end_per_testcase(_Suite,TC,Config,Result,State) ->
{Result, end_tc(TC,Config, Result,State)}.
-on_tc_fail(_TC, _Res, State = #state{test_cases = []}) ->
+on_tc_fail(_Suite,_TC, _Res, State = #state{test_cases = []}) ->
State;
-on_tc_fail(_TC, Res, State) ->
+on_tc_fail(_Suite,_TC, Res, State) ->
TCs = State#state.test_cases,
TC = hd(TCs),
NewTC = TC#testcase{
result =
- {fail,lists:flatten(io_lib:format("~p",[Res]))} },
+ {fail,lists:flatten(io_lib:format("~tp",[Res]))} },
State#state{ test_cases = [NewTC | tl(TCs)]}.
-on_tc_skip({ConfigFunc,_GrName},{Type,_Reason} = Res, State0)
- when Type == tc_auto_skip; Type == tc_user_skip ->
- on_tc_skip(ConfigFunc, Res, State0);
-on_tc_skip(Tc,{Type,_Reason} = Res, State0) when Type == tc_auto_skip ->
+on_tc_skip(Suite,{ConfigFunc,_GrName}, Res, State) ->
+ on_tc_skip(Suite,ConfigFunc, Res, State);
+on_tc_skip(Suite,Tc, Res, State0) ->
TcStr = atom_to_list(Tc),
State =
case State0#state.test_cases of
@@ -158,18 +157,14 @@ on_tc_skip(Tc,{Type,_Reason} = Res, State0) when Type == tc_auto_skip ->
_ ->
State0
end,
- do_tc_skip(Res, end_tc(Tc,[],Res,init_tc(State,[])));
-on_tc_skip(_Tc, _Res, State = #state{test_cases = []}) ->
- State;
-on_tc_skip(_Tc, Res, State) ->
- do_tc_skip(Res, State).
+ do_tc_skip(Res, end_tc(Tc,[],Res,init_tc(set_suite(Suite,State),[]))).
do_tc_skip(Res, State) ->
TCs = State#state.test_cases,
TC = hd(TCs),
NewTC = TC#testcase{
result =
- {skipped,lists:flatten(io_lib:format("~p",[Res]))} },
+ {skipped,lists:flatten(io_lib:format("~tp",[Res]))} },
State#state{ test_cases = [NewTC | tl(TCs)]}.
init_tc(State, Config) when is_list(Config) == false ->
@@ -209,6 +204,12 @@ end_tc(Name, _Config, _Res, State = #state{ curr_suite = Suite,
result = passed }|
State#state.test_cases],
tc_log = ""}. % so old tc_log is not set if next is on_tc_skip
+
+set_suite(Suite,#state{curr_suite=undefined}=State) ->
+ State#state{curr_suite=Suite, curr_suite_ts=?now};
+set_suite(_,State) ->
+ State.
+
close_suite(#state{ test_cases = [] } = State) ->
State;
close_suite(#state{ test_cases = TCs, url_base = UrlBase } = State) ->
@@ -228,7 +229,8 @@ close_suite(#state{ test_cases = TCs, url_base = UrlBase } = State) ->
testcases = lists:reverse(TCs),
log = SuiteLog,
url = SuiteUrl},
- State#state{ test_cases = [],
+ State#state{ curr_suite = undefined,
+ test_cases = [],
test_suites = [Suite | State#state.test_suites]}.
terminate(State = #state{ test_cases = [] }) ->
diff --git a/lib/common_test/src/erl2html2.erl b/lib/common_test/src/erl2html2.erl
index e819f345de..7f3eb699de 100644
--- a/lib/common_test/src/erl2html2.erl
+++ b/lib/common_test/src/erl2html2.erl
@@ -130,6 +130,8 @@ parse_preprocessed_file(Epp, File, InCorrectFile) ->
throw({error,Reason,InCorrectFile});
{error,_Reason} ->
parse_preprocessed_file(Epp, File, InCorrectFile);
+ {warning,_} ->
+ parse_preprocessed_file(Epp, File, InCorrectFile);
{eof,_Location} ->
[]
end.
diff --git a/lib/common_test/src/test_server.erl b/lib/common_test/src/test_server.erl
index 924086f2bd..ee3a5e4bba 100644
--- a/lib/common_test/src/test_server.erl
+++ b/lib/common_test/src/test_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -175,7 +175,7 @@ do_cover_compile(Modules) ->
ok.
warn_compile({error,{Reason,Module}}) ->
- io:fwrite("\nWARNING: Could not cover compile ~ts: ~p\n",
+ io:fwrite("\nWARNING: Could not cover compile ~ts: ~tp\n",
[Module,{error,Reason}]).
%% Make sure all modules are loaded and unstick if sticky
@@ -189,7 +189,7 @@ prepare_cover_compile([M|Ms],Sticky) ->
{module,_} ->
prepare_cover_compile([M|Ms],Sticky);
Error ->
- io:fwrite("\nWARNING: Could not load ~w: ~p\n",[M,Error]),
+ io:fwrite("\nWARNING: Could not load ~w: ~tp\n",[M,Error]),
prepare_cover_compile(Ms,Sticky)
end;
{false,_} ->
@@ -359,10 +359,10 @@ stick_all_sticky(Node,Sticky) ->
%% cover.
run_test_case_apply({Mod,Func,Args,Name,RunInit,TimetrapData}) ->
- case os:getenv("TS_RUN_VALGRIND") of
+ case is_valgrind() of
false ->
ok;
- _ ->
+ true ->
os:putenv("VALGRIND_LOGFILE_INFIX",atom_to_list(Mod)++"."++
atom_to_list(Func)++"-")
end,
@@ -450,7 +450,7 @@ run_test_case_msgloop(#st{ref=Ref,pid=Pid,end_conf_pid=EndConfPid0}=St0) ->
exit(Pid, kill),
%% here's the only place we know Reason, so we save
%% it as a comment, potentially replacing user data
- Error = lists:flatten(io_lib:format("Aborted: ~p",
+ Error = lists:flatten(io_lib:format("Aborted: ~tp",
[Reason])),
Error1 = lists:flatten([string:strip(S,left) ||
S <- string:tokens(Error,
@@ -756,13 +756,13 @@ print_end_conf_result(Mod,Func,Conf,Cause,Error) ->
Str2Print =
fun(NoHTML) when NoHTML == stdout; NoHTML == major ->
io_lib:format("WARNING! "
- "~w:end_per_testcase(~w, ~tp)"
+ "~w:end_per_testcase(~tw, ~tp)"
" ~s!\n\tReason: ~tp\n",
[Mod,Func,Conf,Cause,Error]);
(minor) ->
ErrorStr = test_server_ctrl:escape_chars(Error),
io_lib:format("WARNING! "
- "~w:end_per_testcase(~w, ~tp)"
+ "~w:end_per_testcase(~tw, ~tp)"
" ~s!\n\tReason: ~ts\n",
[Mod,Func,Conf,Cause,ErrorStr])
end,
@@ -778,9 +778,9 @@ spawn_fw_call(Mod,IPTC={init_per_testcase,Func},CurrConf,Pid,
%% if init_per_testcase fails, the test case
%% should be skipped
try begin do_end_tc_call(Mod,IPTC, {Pid,Skip,[CurrConf]}, Why),
- do_init_tc_call(Mod,{end_per_testcase,Func},
+ do_init_tc_call(Mod,{end_per_testcase_not_run,Func},
[CurrConf],{ok,[CurrConf]}),
- do_end_tc_call(Mod,{end_per_testcase,Func},
+ do_end_tc_call(Mod,{end_per_testcase_not_run,Func},
{Pid,Skip,[CurrConf]}, Why) end of
_ -> ok
catch
@@ -792,7 +792,7 @@ spawn_fw_call(Mod,IPTC={init_per_testcase,Func},CurrConf,Pid,
_ -> died
end,
group_leader() ! {printout,12,
- "ERROR! ~w:init_per_testcase(~w, ~p)"
+ "ERROR! ~w:init_per_testcase(~tw, ~tp)"
" failed!\n\tReason: ~tp\n",
[Mod,Func,CurrConf,Why]},
%% finished, report back
@@ -820,7 +820,7 @@ spawn_fw_call(Mod,EPTC={end_per_testcase,Func},EndConf,Pid,
{timetrap_timeout,TVal} ->
group_leader() !
{printout,12,
- "WARNING! ~w:end_per_testcase(~w, ~p)"
+ "WARNING! ~w:end_per_testcase(~tw, ~tp)"
" failed!\n\tReason: timetrap timeout"
" after ~w ms!\n", [Mod,Func,EndConf,TVal]},
W = "<font color=\"red\">"
@@ -829,7 +829,7 @@ spawn_fw_call(Mod,EPTC={end_per_testcase,Func},EndConf,Pid,
_ ->
group_leader() !
{printout,12,
- "WARNING! ~w:end_per_testcase(~w, ~p)"
+ "WARNING! ~w:end_per_testcase(~tw, ~tp)"
" failed!\n\tReason: ~tp\n",
[Mod,Func,EndConf,Why]},
W = "<font color=\"red\">"
@@ -859,7 +859,7 @@ spawn_fw_call(FwMod,FwFunc,_,_Pid,{framework_error,FwError},_,SendTo) ->
Comment =
lists:flatten(
io_lib:format("<font color=\"red\">"
- "WARNING! ~w:~w failed!</font>",
+ "WARNING! ~w:~tw failed!</font>",
[FwMod,FwFunc])),
%% finished, report back
SendTo ! {self(),fw_notify_done,
@@ -1151,14 +1151,14 @@ do_end_tc_call(Mod, IPTC={init_per_testcase,Func}, Res, Return) ->
Args
end,
EPTCInitRes =
- case do_init_tc_call(Mod,{end_per_testcase,Func},
+ case do_init_tc_call(Mod,{end_per_testcase_not_run,Func},
IPTCEndRes,Return) of
{ok,EPTCInitConfig} when is_list(EPTCInitConfig) ->
{Return,EPTCInitConfig};
_ ->
- Return
+ {Return,IPTCEndRes}
end,
- do_end_tc_call1(Mod, {end_per_testcase,Func},
+ do_end_tc_call1(Mod, {end_per_testcase_not_run,Func},
EPTCInitRes, Return);
_Ok ->
do_end_tc_call1(Mod, IPTC, Res, Return)
@@ -1341,7 +1341,7 @@ print_init_conf_result(Line,Cause,Reason) ->
Str2Print =
fun(NoHTML) when NoHTML == stdout; NoHTML == major ->
io_lib:format("ERROR! init_per_testcase ~s!\n"
- "\tLocation: ~p\n\tReason: ~tp\n",
+ "\tLocation: ~tp\n\tReason: ~tp\n",
[Cause,Line,Reason]);
(minor) ->
ReasonStr = test_server_ctrl:escape_chars(Reason),
@@ -1413,7 +1413,7 @@ print_end_tc_warning(EndFunc,Reason,Cause,Loc) ->
Str2Print =
fun(NoHTML) when NoHTML == stdout; NoHTML == major ->
io_lib:format("WARNING: ~w ~s!\n"
- "Reason: ~tp\nLine: ~p\n",
+ "Reason: ~tp\nLine: ~tp\n",
[EndFunc,Cause,Reason,Loc]);
(minor) ->
ReasonStr = test_server_ctrl:escape_chars(Reason),
@@ -1515,7 +1515,7 @@ lookup_config(Key,Config) ->
{value,{Key,Val}} ->
Val;
_ ->
- io:format("Could not find element ~p in Config.~n",[Key]),
+ io:format("Could not find element ~tp in Config.~n",[Key]),
undefined
end.
@@ -1600,7 +1600,7 @@ format(Detail, Format, Args) ->
Str =
case catch io_lib:format(Format,Args) of
{'EXIT',_} ->
- io_lib:format("illegal format; ~p with args ~p.\n",
+ io_lib:format("illegal format; ~tp with args ~tp.\n",
[Format,Args]);
Valid -> Valid
end,
@@ -1732,7 +1732,7 @@ fail(Reason) ->
cast_to_list(X) when is_list(X) -> X;
cast_to_list(X) when is_atom(X) -> atom_to_list(X);
-cast_to_list(X) -> lists:flatten(io_lib:format("~p", [X])).
+cast_to_list(X) -> lists:flatten(io_lib:format("~tp", [X])).
@@ -1827,7 +1827,8 @@ timetrap_scale_factor() ->
{ 2, fun() -> has_lock_checking() end},
{ 3, fun() -> has_superfluous_schedulers() end},
{ 6, fun() -> is_debug() end},
- {10, fun() -> is_cover() end}
+ {10, fun() -> is_cover() end},
+ {10, fun() -> is_valgrind() end}
]).
timetrap_scale_factor(Scales) ->
@@ -1903,7 +1904,7 @@ ensure_timetrap(Config) ->
Garbage ->
erase(test_server_default_timetrap),
format("=== WARNING: garbage in "
- "test_server_default_timetrap: ~p~n",
+ "test_server_default_timetrap: ~tp~n",
[Garbage])
end,
DTmo = case lists:keysearch(default_timeout,1,Config) of
@@ -1932,7 +1933,7 @@ cancel_default_timetrap(true) ->
Garbage ->
erase(test_server_default_timetrap),
format("=== WARNING: garbage in "
- "test_server_default_timetrap: ~p~n",
+ "test_server_default_timetrap: ~tp~n",
[Garbage]),
error
end.
@@ -1941,7 +1942,7 @@ time_ms({hours,N}, _, _) -> hours(N);
time_ms({minutes,N}, _, _) -> minutes(N);
time_ms({seconds,N}, _, _) -> seconds(N);
time_ms({Other,_N}, _, _) ->
- format("=== ERROR: Invalid time specification: ~p. "
+ format("=== ERROR: Invalid time specification: ~tp. "
"Should be seconds, minutes, or hours.~n", [Other]),
exit({invalid_time_format,Other});
time_ms(Ms, _, _) when is_integer(Ms) -> Ms;
@@ -2729,6 +2730,16 @@ is_commercial() ->
_ -> true
end.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% is_valgrind() -> boolean()
+%%
+%% Returns true if valgrind is running, else false
+is_valgrind() ->
+ case os:getenv("TS_RUN_VALGRIND") of
+ false -> false;
+ _ -> true
+ end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Apply given function and reply to caller or proxy.
diff --git a/lib/common_test/src/test_server_ctrl.erl b/lib/common_test/src/test_server_ctrl.erl
index b52e4bef9b..9412c43187 100644
--- a/lib/common_test/src/test_server_ctrl.erl
+++ b/lib/common_test/src/test_server_ctrl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -232,7 +232,7 @@ parse_cmd_line(['SPEC',Spec|Cmds], SpecList, Names, Param, Trc, Cov, TCCB) ->
parse_cmd_line(Cmds, TermList++SpecList, [Name|Names], Param,
Trc, Cov, TCCB);
{error,Reason} ->
- io:format("Can't open ~w: ~p\n",[Spec, file:format_error(Reason)]),
+ io:format("Can't open ~tw: ~tp\n",[Spec, file:format_error(Reason)]),
parse_cmd_line(Cmds, SpecList, Names, Param, Trc, Cov, TCCB)
end;
parse_cmd_line(['NAME',Name|Cmds], SpecList, Names, Param, Trc, Cov, TCCB) ->
@@ -261,7 +261,7 @@ parse_cmd_line(['COVER',App,CF,Analyse|Cmds], SpecList, Names, Param, Trc, _Cov,
parse_cmd_line(['TESTCASE_CALLBACK',Mod,Func|Cmds], SpecList, Names, Param, Trc, Cov, _) ->
parse_cmd_line(Cmds, SpecList, Names, Param, Trc, Cov, {Mod,Func});
parse_cmd_line([Obj|_Cmds], _SpecList, _Names, _Param, _Trc, _Cov, _TCCB) ->
- io:format("~w: Bad argument: ~w\n", [?MODULE,Obj]),
+ io:format("~w: Bad argument: ~tw\n", [?MODULE,Obj]),
io:format(" Use the `ts' module to start tests.\n", []),
io:format(" (If you ARE using `ts', there is a bug in `ts'.)\n", []),
halt(1);
@@ -280,7 +280,7 @@ parse_cmd_line([], SpecList, Names, Param, Trc, Cov, TCCB) ->
cast_to_list(X) when is_list(X) -> X;
cast_to_list(X) when is_atom(X) -> atom_to_list(X);
-cast_to_list(X) -> lists:flatten(io_lib:format("~w", [X])).
+cast_to_list(X) -> lists:flatten(io_lib:format("~tw", [X])).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% START INTERFACE
@@ -878,7 +878,7 @@ handle_call({testcase_callback,ModFunc}, _From, State) ->
ok;
false ->
io:format(user,
- "WARNING! Callback function ~w:~w/4 undefined.~n~n",
+ "WARNING! Callback function ~w:~tw/4 undefined.~n~n",
[Mod,Func])
end;
_ ->
@@ -1016,7 +1016,7 @@ handle_info({'EXIT',Pid,Reason}, State) ->
killed ->
io:format("Suite ~ts was killed\n", [Name]);
_Other ->
- io:format("Suite ~ts was killed with reason ~p\n",
+ io:format("Suite ~ts was killed with reason ~tp\n",
[Name,Reason])
end,
State2 = State#state{jobs=NewJobs},
@@ -1168,10 +1168,10 @@ init_tester(Mod, Func, Args, Dir, Name, {_,_,MinLev}=Levels,
{'EXIT',test_suites_done} ->
ok;
{'EXIT',_Pid,Reason} ->
- print(1, "EXIT, reason ~p", [Reason]);
+ print(1, "EXIT, reason ~tp", [Reason]);
{'EXIT',Reason} ->
report_severe_error(Reason),
- print(1, "EXIT, reason ~p", [Reason])
+ print(1, "EXIT, reason ~tp", [Reason])
end,
Time = TimeMy/1000000,
SuccessStr =
@@ -1263,7 +1263,7 @@ do_spec(SpecName, TimetrapSpec) when is_list(SpecName) ->
{ok,TermList} ->
do_spec_list(TermList,TimetrapSpec);
{error,Reason} ->
- io:format("Can't open ~ts: ~p\n", [SpecName,Reason]),
+ io:format("Can't open ~ts: ~tp\n", [SpecName,Reason]),
{error,{cant_open_spec,Reason}}
end.
@@ -1346,7 +1346,7 @@ do_spec_terms([{require_nodenames,NumNames}|Terms], TopCases, SkipList, Config)
do_spec_terms(Terms, TopCases, SkipList,
update_config(Config, {nodenames,NodeNames}));
do_spec_terms([Other|Terms], TopCases, SkipList, Config) ->
- io:format("** WARNING: Spec file contains unknown directive ~p\n",
+ io:format("** WARNING: Spec file contains unknown directive ~tp\n",
[Other]),
do_spec_terms(Terms, TopCases, SkipList, Config).
@@ -1503,7 +1503,7 @@ do_test_cases(TopCases, SkipCases,
FwMod = get_fw_mod(?MODULE),
case collect_all_cases(TopCases, SkipCases) of
{error,Why} ->
- print(1, "Error starting: ~p", [Why]),
+ print(1, "Error starting: ~tp", [Why]),
exit(test_suites_done);
TestSpec0 ->
N = case remove_conf(TestSpec0) of
@@ -1762,18 +1762,14 @@ make_html_link(LinkName, Target, Explanation) ->
start_minor_log_file(Mod, Func, ParallelTC) ->
MFA = {Mod,Func,1},
LogDir = get(test_server_log_dir_base),
- Name0 = lists:flatten(io_lib:format("~w.~w~ts", [Mod,Func,?html_ext])),
- Name = downcase(Name0),
+ Name = minor_log_file_name(Mod,Func),
AbsName = filename:join(LogDir, Name),
case (ParallelTC orelse (element(1,file:read_file_info(AbsName))==ok)) of
false -> %% normal case, unique name
start_minor_log_file1(Mod, Func, LogDir, AbsName, MFA);
true -> %% special case, duplicate names
Tag = test_server_sup:unique_name(),
- Name1_0 =
- lists:flatten(io_lib:format("~w.~w.~ts~ts", [Mod,Func,Tag,
- ?html_ext])),
- Name1 = downcase(Name1_0),
+ Name1 = minor_log_file_name(Mod,Func,[$.|Tag]),
AbsName1 = filename:join(LogDir, Name1),
start_minor_log_file1(Mod, Func, LogDir, AbsName1, MFA)
end.
@@ -1784,7 +1780,7 @@ start_minor_log_file1(Mod, Func, LogDir, AbsName, MFA) ->
put(test_server_minor_fd, Fd),
test_server_gl:set_minor_fd(group_leader(), Fd, MFA),
- TestDescr = io_lib:format("Test ~w:~w result", [Mod,Func]),
+ TestDescr = io_lib:format("Test ~w:~tw result", [Mod,Func]),
{Header,Footer} =
case test_server_sup:framework_call(get_html_wrapper,
[TestDescr,false,
@@ -1825,13 +1821,13 @@ start_minor_log_file1(Mod, Func, LogDir, AbsName, MFA) ->
lists:member(no_src, get(test_server_logopts))} of
{true,false} ->
print(Lev, ["$tc_html",
- Info ++ "<a href=\"~ts#~ts\">~w:~w/~w</a> "
+ Info ++ "<a href=\"~ts#~ts\">~w:~tw/~w</a> "
"(click for source code)\n"],
[uri_encode(SrcListing),
uri_encode(atom_to_list(Func)++"-1",utf8),
Mod,Func,Arity]);
_ ->
- print(Lev, ["$tc_html",Info ++ "~w:~w/~w\n"], [Mod,Func,Arity])
+ print(Lev, ["$tc_html",Info ++ "~w:~tw/~w\n"], [Mod,Func,Arity])
end
end,
@@ -1845,6 +1841,19 @@ stop_minor_log_file() ->
ok = file:close(Fd),
put(test_server_minor_fd, undefined).
+minor_log_file_name(Mod,Func) ->
+ minor_log_file_name(Mod,Func,"").
+minor_log_file_name(Mod,Func,Tag) ->
+ Name =
+ downcase(
+ lists:flatten(
+ io_lib:format("~w.~tw~s~s", [Mod,Func,Tag,?html_ext]))),
+ Ok = file:native_name_encoding()==utf8
+ orelse io_lib:printable_latin1_list(Name),
+ if Ok -> Name;
+ true -> exit({error,unicode_name_on_latin1_file_system})
+ end.
+
downcase(S) -> downcase(S, []).
downcase([Uc|Rest], Result) when $A =< Uc, Uc =< $Z ->
downcase(Rest, [Uc-$A+$a|Result]);
@@ -2051,17 +2060,21 @@ add_init_and_end_per_suite([], _LastMod, skipped_suite, _FwMod) ->
add_init_and_end_per_suite([], LastMod, LastRef, FwMod) ->
%% we'll add end_per_suite here even if it's not exported
%% (and simply let the call fail if it's missing)
- case erlang:function_exported(LastMod, end_per_suite, 1) of
- true ->
- [{conf,LastRef,[],{LastMod,end_per_suite}}];
- false ->
+ case {erlang:function_exported(LastMod, end_per_suite, 1),
+ erlang:function_exported(LastMod, init_per_suite, 1)} of
+ {false,false} ->
%% let's call a "fake" end_per_suite if it exists
case erlang:function_exported(FwMod, end_per_suite, 1) of
true ->
[{conf,LastRef,[{suite,LastMod}],{FwMod,end_per_suite}}];
false ->
[{conf,LastRef,[],{LastMod,end_per_suite}}]
- end
+ end;
+ _ ->
+ %% If any of these exist, the other should too
+ %% (required and documented). If it isn't, it will fail
+ %% with reason 'undef'.
+ [{conf,LastRef,[],{LastMod,end_per_suite}}]
end.
do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod) ->
@@ -2070,11 +2083,9 @@ do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod) ->
_ -> ok
end,
{Init,NextMod,NextRef} =
- case erlang:function_exported(Mod, init_per_suite, 1) of
- true ->
- Ref = make_ref(),
- {[{conf,Ref,[],{Mod,init_per_suite}}],Mod,Ref};
- false ->
+ case {erlang:function_exported(Mod, init_per_suite, 1),
+ erlang:function_exported(Mod, end_per_suite, 1)} of
+ {false,false} ->
%% let's call a "fake" init_per_suite if it exists
case erlang:function_exported(FwMod, init_per_suite, 1) of
true ->
@@ -2083,8 +2094,13 @@ do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod) ->
{FwMod,init_per_suite}}],Mod,Ref};
false ->
{[],Mod,undefined}
- end
-
+ end;
+ _ ->
+ %% If any of these exist, the other should too
+ %% (required and documented). If it isn't, it will fail
+ %% with reason 'undef'.
+ Ref = make_ref(),
+ {[{conf,Ref,[],{Mod,init_per_suite}}],Mod,Ref}
end,
Cases =
if LastRef==undefined ->
@@ -2094,10 +2110,9 @@ do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod) ->
true ->
%% we'll add end_per_suite here even if it's not exported
%% (and simply let the call fail if it's missing)
- case erlang:function_exported(LastMod, end_per_suite, 1) of
- true ->
- [{conf,LastRef,[],{LastMod,end_per_suite}}|Init];
- false ->
+ case {erlang:function_exported(LastMod, end_per_suite, 1),
+ erlang:function_exported(LastMod, init_per_suite, 1)} of
+ {false,false} ->
%% let's call a "fake" end_per_suite if it exists
case erlang:function_exported(FwMod, end_per_suite, 1) of
true ->
@@ -2105,8 +2120,13 @@ do_add_init_and_end_per_suite(LastMod, LastRef, Mod, FwMod) ->
{FwMod,end_per_suite}}|Init];
false ->
[{conf,LastRef,[],{LastMod,end_per_suite}}|Init]
- end
- end
+ end;
+ _ ->
+ %% If any of these exist, the other should too
+ %% (required and documented). If it isn't, it will fail
+ %% with reason 'undef'.
+ [{conf,LastRef,[],{LastMod,end_per_suite}}|Init]
+ end
end,
{Cases,NextMod,NextRef}.
@@ -2115,11 +2135,9 @@ do_add_end_per_suite_and_skip(LastMod, LastRef, Mod, FwMod) ->
No when No==undefined ; No==skipped_suite ->
{[],Mod,skipped_suite};
_Ref ->
- case erlang:function_exported(LastMod, end_per_suite, 1) of
- true ->
- {[{conf,LastRef,[],{LastMod,end_per_suite}}],
- Mod,skipped_suite};
- false ->
+ case {erlang:function_exported(LastMod, end_per_suite, 1),
+ erlang:function_exported(LastMod, init_per_suite, 1)} of
+ {false,false} ->
case erlang:function_exported(FwMod, end_per_suite, 1) of
true ->
%% let's call "fake" end_per_suite if it exists
@@ -2128,7 +2146,13 @@ do_add_end_per_suite_and_skip(LastMod, LastRef, Mod, FwMod) ->
false ->
{[{conf,LastRef,[],{LastMod,end_per_suite}}],
Mod,skipped_suite}
- end
+ end;
+ _ ->
+ %% If any of these exist, the other should too
+ %% (required and documented). If it isn't, it will fail
+ %% with reason 'undef'.
+ {[{conf,LastRef,[],{LastMod,end_per_suite}}],
+ Mod,skipped_suite}
end
end.
@@ -2721,7 +2745,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
TimetrapData, Mode, Status2);
Bad ->
print(minor,
- "~n*** ~w returned bad elements in Config: ~p.~n",
+ "~n*** ~tw returned bad elements in Config: ~tp.~n",
[Func,Bad]),
Reason = {failed,{Mod,init_per_suite,bad_return}},
Cases2 = skip_cases_upto(Ref, Cases, Reason, conf, CurrMode,
@@ -2737,9 +2761,9 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
stop_minor_log_file(),
run_test_cases_loop(Cases, [NewCfg|Config], TimetrapData, Mode, Status2);
{_,{framework_error,{FwMod,FwFunc},Reason},_} ->
- print(minor, "~n*** ~w failed in ~w. Reason: ~p~n",
+ print(minor, "~n*** ~w failed in ~tw. Reason: ~tp~n",
[FwMod,FwFunc,Reason]),
- print(1, "~w failed in ~w. Reason: ~p~n", [FwMod,FwFunc,Reason]),
+ print(1, "~w failed in ~tw. Reason: ~tp~n", [FwMod,FwFunc,Reason]),
exit(framework_error);
{_,Fail,_} when element(1,Fail) == 'EXIT';
element(1,Fail) == timetrap_timeout;
@@ -2748,7 +2772,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
{Cases2,Config1,Status3} =
if StartConf ->
ReportAbortRepeat(failed),
- print(minor, "~n*** ~w failed.~n"
+ print(minor, "~n*** ~tw failed.~n"
" Skipping all cases.", [Func]),
Reason = {failed,{Mod,Func,Fail}},
{skip_cases_upto(Ref, Cases, Reason, conf, CurrMode,
@@ -2771,7 +2795,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
{Cases2,Config1,Status3} =
if StartConf ->
ReportAbortRepeat(auto_skipped),
- print(minor, "~n*** ~w auto skipped.~n"
+ print(minor, "~n*** ~tw auto skipped.~n"
" Skipping all cases.", [Func]),
{skip_cases_upto(Ref, Cases, SkipReason, conf, CurrMode,
auto_skip_case),
@@ -2788,7 +2812,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
{_,{Skip,Reason},_} when StartConf and ((Skip==skip) or (Skip==skipped)) ->
ReportAbortRepeat(skipped),
- print(minor, "~n*** ~w skipped.~n"
+ print(minor, "~n*** ~tw skipped.~n"
" Skipping all cases.", [Func]),
set_io_buffering(IOHandler),
stop_minor_log_file(),
@@ -2798,7 +2822,7 @@ run_test_cases_loop([{conf,Ref,Props,{Mod,Func}}|_Cases]=Cs0,
delete_status(Ref, Status2));
{_,{skip_and_save,Reason,_SavedConfig},_} when StartConf ->
ReportAbortRepeat(skipped),
- print(minor, "~n*** ~w skipped.~n"
+ print(minor, "~n*** ~tw skipped.~n"
" Skipping all cases.", [Func]),
set_io_buffering(IOHandler),
stop_minor_log_file(),
@@ -2863,7 +2887,7 @@ run_test_cases_loop([{make,Ref,{Mod,Func,Args}}|Cases0], Config, TimetrapData,
Mode, Status) ->
case run_test_case(Ref, 0, Mod, Func, Args, skip_init, TimetrapData) of
{_,Why={'EXIT',_},_} ->
- print(minor, "~n*** ~w failed.~n"
+ print(minor, "~n*** ~tw failed.~n"
" Skipping all cases.", [Func]),
Reason = {failed,{Mod,Func,Why}},
Cases = skip_cases_upto(Ref, Cases0, Reason, conf, Mode,
@@ -2917,29 +2941,28 @@ run_test_cases_loop([{Mod,Func,Args}|Cases], Config, TimetrapData, Mode, Status)
RunInit, TimetrapData, Mode) of
%% callback to framework module failed, exit immediately
{_,{framework_error,{FwMod,FwFunc},Reason},_} ->
- print(minor, "~n*** ~w failed in ~w. Reason: ~p~n",
+ print(minor, "~n*** ~w failed in ~tw. Reason: ~tp~n",
[FwMod,FwFunc,Reason]),
- print(1, "~w failed in ~w. Reason: ~p~n", [FwMod,FwFunc,Reason]),
+ print(1, "~w failed in ~tw. Reason: ~tp~n", [FwMod,FwFunc,Reason]),
stop_minor_log_file(),
exit(framework_error);
%% sequential execution of test case finished
{Time,RetVal,_} ->
+ RetTag =
+ if is_tuple(RetVal) -> element(1,RetVal);
+ true -> undefined
+ end,
{Failed,Status1} =
- case Time of
- died ->
- {true,update_status(failed, Mod, Func, Status)};
- _ when is_tuple(RetVal) ->
- case element(1, RetVal) of
- R when R=='EXIT'; R==failed ->
- {true,update_status(failed, Mod, Func, Status)};
- R when R==skip; R==skipped ->
- {false,update_status(skipped, Mod, Func, Status)};
- _ ->
- {false,update_status(ok, Mod, Func, Status)}
- end;
- _ ->
- {false,update_status(ok, Mod, Func, Status)}
- end,
+ case RetTag of
+ Skip when Skip==skip; Skip==skipped ->
+ {false,update_status(skipped, Mod, Func, Status)};
+ Fail when Fail=='EXIT'; Fail==failed ->
+ {true,update_status(failed, Mod, Func, Status)};
+ _ when Time==died, RetVal=/=ok ->
+ {true,update_status(failed, Mod, Func, Status)};
+ _ ->
+ {false,update_status(ok, Mod, Func, Status)}
+ end,
case check_prop(sequence, Mode) of
false ->
stop_minor_log_file(),
@@ -2951,7 +2974,7 @@ run_test_cases_loop([{Mod,Func,Args}|Cases], Config, TimetrapData, Mode, Status)
stop_minor_log_file(),
run_test_cases_loop(Cases, Config, TimetrapData, Mode, Status1);
true -> % skip rest of cases in sequence
- print(minor, "~n*** ~w failed.~n"
+ print(minor, "~n*** ~tw failed.~n"
" Skipping all other cases in sequence.",
[Func]),
Reason = {failed,{Mod,Func}},
@@ -3091,8 +3114,8 @@ print_conf_time(ConfTime) ->
print_props([]) ->
ok;
print_props(Props) ->
- print(major, "=group_props ~p", [Props]),
- print(minor, "Group properties: ~p~n", [Props]).
+ print(major, "=group_props ~tp", [Props]),
+ print(minor, "Group properties: ~tp~n", [Props]).
%% repeat N times: {repeat,N}
%% repeat N times or until all successful: {repeat_until_all_ok,N}
@@ -3239,13 +3262,13 @@ skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) ->
ResultCol = if Type == auto -> ?auto_skip_color;
Type == user -> ?user_skip_color
end,
- print(major, "~n=case ~w:~w", [Mod,Func]),
+ print(major, "~n=case ~w:~tw", [Mod,Func]),
GroupName = case get_name(Mode) of
undefined ->
"";
GrName ->
GrName1 = cast_to_list(GrName),
- print(major, "=group_props ~p", [[{name,GrName1}]]),
+ print(major, "=group_props ~tp", [[{name,GrName1}]]),
GrName1
end,
print(major, "=started ~s", [lists:flatten(timestamp_get(""))]),
@@ -3256,9 +3279,9 @@ skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) ->
print(major, "=result skipped: ~ts", [Comment1])
end,
if CaseNum == 0 ->
- print(2,"*** Skipping ~w ***", [{Mod,Func}]);
+ print(2,"*** Skipping ~tw ***", [{Mod,Func}]);
true ->
- print(2,"*** Skipping test case #~w ~w ***", [CaseNum,{Mod,Func}])
+ print(2,"*** Skipping test case #~w ~tw ***", [CaseNum,{Mod,Func}])
end,
TR = xhtml("<tr valign=\"top\">", ["<tr class=\"",odd_or_even(),"\">"]),
GroupName = case get_name(Mode) of
@@ -3269,7 +3292,7 @@ skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) ->
TR ++ "<td>" ++ Col0 ++ "~ts" ++ Col1 ++ "</td>"
"<td>" ++ Col0 ++ "~w" ++ Col1 ++ "</td>"
"<td>" ++ Col0 ++ "~ts" ++ Col1 ++ "</td>"
- "<td>" ++ Col0 ++ "~w" ++ Col1 ++ "</td>"
+ "<td>" ++ Col0 ++ "~tw" ++ Col1 ++ "</td>"
"<td>" ++ Col0 ++ "< >" ++ Col1 ++ "</td>"
"<td>" ++ Col0 ++ "0.000s" ++ Col1 ++ "</td>"
"<td><font color=\"~ts\">SKIPPED</font></td>"
@@ -3490,7 +3513,7 @@ wait_and_resend(Ref, [{_,CurrPid,CaseNum,Mod,Func}|Ps] = Cases, Ok,Skip,Fail) ->
{'EXIT',CurrPid,Reason} when Reason /= normal ->
%% unexpected termination of test case process
{value,{_,_,CaseNum,Mod,Func}} = lists:keysearch(CurrPid, 2, Cases),
- print(1, "Error! Process for test case #~w (~w:~w) died! Reason: ~p",
+ print(1, "Error! Process for test case #~w (~w:~tw) died! Reason: ~tp",
[CaseNum, Mod, Func, Reason]),
exit({unexpected_termination,{CaseNum,Mod,Func},{CurrPid,Reason}})
end;
@@ -3629,7 +3652,7 @@ handle_io_and_exits(Main, CurrPid, CaseNum, Mod, Func, Cases) ->
{'EXIT',TCPid,Reason} when Reason /= normal ->
test_server_io:print_buffered(CurrPid),
{value,{_,_,Num,M,F}} = lists:keysearch(TCPid, 2, Cases),
- print(1, "Error! Process for test case #~w (~w:~w) died! Reason: ~p",
+ print(1, "Error! Process for test case #~w (~w:~tw) died! Reason: ~tp",
[Num, M, F, Reason]),
exit({unexpected_termination,{Num,M,F},{TCPid,Reason}})
end.
@@ -3702,7 +3725,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
end,
TSDir = get(test_server_dir),
- print(major, "=case ~w:~w", [Mod, Func]),
+ print(major, "=case ~w:~tw", [Mod, Func]),
MinorName = start_minor_log_file(Mod, Func, self() /= Main),
MinorBase = filename:basename(MinorName),
print(major, "=logfile ~ts", [filename:basename(MinorName)]),
@@ -3764,7 +3787,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
print(html, TR ++ "<td>" ++ Col0 ++ "~ts" ++ Col1 ++ "</td>"
"<td>" ++ Col0 ++ "~w" ++ Col1 ++ "</td>"
"<td>" ++ Col0 ++ "~ts" ++ Col1 ++ "</td>"
- "<td><a href=\"~ts\">~w</a></td>"
+ "<td><a href=\"~ts\">~tw</a></td>"
"<td><a href=\"~ts#top\">&lt;</a> <a href=\"~ts#end\">&gt;</a></td>",
[num2str(Num),fw_name(Mod),GrNameStr,EncMinorBase,Func,
EncMinorBase,EncMinorBase]),
@@ -3794,7 +3817,15 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
{died,{timetrap_timeout,TimetrapTimeout}} ->
progress(failed, Num, Mod, Func, GrName, Loc,
timetrap_timeout, TimetrapTimeout, Comment, Style);
- {died,Reason} ->
+ {died,{Skip,Reason}} when Skip==skip; Skip==skipped ->
+ %% died in init_per_testcase
+ progress(skip, Num, Mod, Func, GrName, Loc, Reason,
+ Time, Comment, Style);
+ {died,Reason} when Reason=/=ok ->
+ %% (If Reason==ok it means that process died in
+ %% end_per_testcase after successfully completing the
+ %% test case itself - then we shall not fail, but a
+ %% warning will be issued in the comment field.)
progress(failed, Num, Mod, Func, GrName, Loc, Reason,
Time, Comment, Style);
{_,{'EXIT',{Skip,Reason}}} when Skip==skip; Skip==skipped;
@@ -3872,13 +3903,13 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit,
{'EXIT',_} = Exit ->
print(minor,
"WARNING: There might be slavenodes left in the"
- " system. I tried to kill them, but I failed: ~p\n",
+ " system. I tried to kill them, but I failed: ~tp\n",
[Exit]);
[] -> ok;
List ->
print(minor, "WARNING: ~w slave nodes in system after test"++
"case. Tried to killed them.~n"++
- " Names:~p",
+ " Names:~tp",
[length(List),List])
end;
false ->
@@ -3938,11 +3969,14 @@ progress(skip, CaseNum, Mod, Func, GrName, Loc, Reason, Time,
if_auto_skip(Reason,
fun() -> {?auto_skip_color,auto_skip,auto_skipped} end,
fun() -> {?user_skip_color,skip,skipped} end),
- print(major, "=result ~w: ~p", [ReportTag,Reason1]),
+ print(major, "=result ~w: ~tp", [ReportTag,Reason1]),
print(1, "*** SKIPPED ~ts ***",
[get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,{Func,GrName},
{ReportTag,Reason1}}]),
+ TimeStr = io_lib:format(if is_float(Time) -> "~.3fs";
+ true -> "~w"
+ end, [Time]),
ReasonStr = escape_chars(reason_to_string(Reason1)),
ReasonStr1 = lists:flatten([string:strip(S,left) ||
S <- string:tokens(ReasonStr,[$\n])]),
@@ -3957,10 +3991,10 @@ progress(skip, CaseNum, Mod, Func, GrName, Loc, Reason, Time,
_ -> xhtml("<br>(","<br />(") ++ to_string(Comment) ++ ")"
end,
print(html,
- "<td>" ++ St0 ++ "~.3fs" ++ St1 ++ "</td>"
+ "<td>" ++ St0 ++ "~ts" ++ St1 ++ "</td>"
"<td><font color=\"~ts\">SKIPPED</font></td>"
"<td>~ts~ts</td></tr>\n",
- [Time,Color,ReasonStr2,Comment1]),
+ [TimeStr,Color,ReasonStr2,Comment1]),
FormatLoc = test_server_sup:format_loc(Loc),
print(minor, "=== Location: ~ts", [FormatLoc]),
print(minor, "=== Reason: ~ts", [ReasonStr1]),
@@ -3968,7 +4002,7 @@ progress(skip, CaseNum, Mod, Func, GrName, Loc, Reason, Time,
progress(failed, CaseNum, Mod, Func, GrName, Loc, timetrap_timeout, T,
Comment0, {St0,St1}) ->
- print(major, "=result failed: timeout, ~p", [Loc]),
+ print(major, "=result failed: timeout, ~tp", [Loc]),
print(1, "*** FAILED ~ts ***",
[get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report,
@@ -3994,7 +4028,7 @@ progress(failed, CaseNum, Mod, Func, GrName, Loc, timetrap_timeout, T,
progress(failed, CaseNum, Mod, Func, GrName, Loc, {testcase_aborted,Reason}, _T,
Comment0, {St0,St1}) ->
- print(major, "=result failed: testcase_aborted, ~p", [Loc]),
+ print(major, "=result failed: testcase_aborted, ~tp", [Loc]),
print(1, "*** FAILED ~ts ***",
[get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report,
@@ -4016,14 +4050,14 @@ progress(failed, CaseNum, Mod, Func, GrName, Loc, {testcase_aborted,Reason}, _T,
FormatLoc = test_server_sup:format_loc(Loc),
print(minor, "=== Location: ~ts", [FormatLoc]),
print(minor,
- escape_chars(io_lib:format("=== Reason: {testcase_aborted,~p}",
+ escape_chars(io_lib:format("=== Reason: {testcase_aborted,~tp}",
[Reason])),
[]),
failed;
progress(failed, CaseNum, Mod, Func, GrName, unknown, Reason, Time,
Comment0, {St0,St1}) ->
- print(major, "=result failed: ~p, ~w", [Reason,unknown_location]),
+ print(major, "=result failed: ~tp, ~w", [Reason,unknown_location]),
print(1, "*** FAILED ~ts ***",
[get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,{Func,GrName},
@@ -4031,7 +4065,7 @@ progress(failed, CaseNum, Mod, Func, GrName, unknown, Reason, Time,
TimeStr = io_lib:format(if is_float(Time) -> "~.3fs";
true -> "~w"
end, [Time]),
- ErrorReason = escape_chars(lists:flatten(io_lib:format("~p", [Reason]))),
+ ErrorReason = escape_chars(lists:flatten(io_lib:format("~tp", [Reason]))),
ErrorReason1 = lists:flatten([string:strip(S,left) ||
S <- string:tokens(ErrorReason,[$\n])]),
ErrorReason2 =
@@ -4068,7 +4102,7 @@ progress(failed, CaseNum, Mod, Func, GrName, Loc, Reason, Time,
end;
true -> {Loc,Loc}
end,
- print(major, "=result failed: ~p, ~p", [Reason,LocMaj]),
+ print(major, "=result failed: ~tp, ~tp", [Reason,LocMaj]),
print(1, "*** FAILED ~ts ***",
[get_info_str(Mod,Func, CaseNum, get(test_server_cases))]),
test_server_sup:framework_call(report, [tc_done,{Mod,{Func,GrName},
@@ -4098,6 +4132,9 @@ progress(ok, _CaseNum, Mod, Func, GrName, _Loc, RetVal, Time,
Comment0, {St0,St1}) ->
print(minor, "successfully completed test case", []),
test_server_sup:framework_call(report, [tc_done,{Mod,{Func,GrName},ok}]),
+ TimeStr = io_lib:format(if is_float(Time) -> "~.3fs";
+ true -> "~w"
+ end, [Time]),
Comment =
case RetVal of
{comment,RetComment} ->
@@ -4116,10 +4153,10 @@ progress(ok, _CaseNum, Mod, Func, GrName, _Loc, RetVal, Time,
end,
print(major, "=elapsed ~p", [Time]),
print(html,
- "<td>" ++ St0 ++ "~.3fs" ++ St1 ++ "</td>"
+ "<td>" ++ St0 ++ "~ts" ++ St1 ++ "</td>"
"<td><font color=\"green\">Ok</font></td>"
"~ts</tr>\n",
- [Time,Comment]),
+ [TimeStr,Comment]),
print(minor,
escape_chars(io_lib:format("=== Returned value: ~tp", [RetVal])),
[]),
@@ -4208,7 +4245,7 @@ update_skip_counters(Pat, {US,AS}) ->
Result.
get_info_str(Mod,Func, 0, _Cases) ->
- io_lib:format("~w", [{Mod,Func}]);
+ io_lib:format("~tw", [{Mod,Func}]);
get_info_str(_Mod,_Func, CaseNum, unknown) ->
"test case " ++ integer_to_list(CaseNum);
get_info_str(_Mod,_Func, CaseNum, Cases) ->
@@ -4223,11 +4260,11 @@ print_if_known(Known, {SK,AK}, {SU,AU}) ->
to_string(Term) when is_list(Term) ->
case (catch io_lib:format("~ts", [Term])) of
- {'EXIT',_} -> lists:flatten(io_lib:format("~p", [Term]));
+ {'EXIT',_} -> lists:flatten(io_lib:format("~tp", [Term]));
String -> lists:flatten(String)
end;
to_string(Term) ->
- lists:flatten(io_lib:format("~p", [Term])).
+ lists:flatten(io_lib:format("~tp", [Term])).
get_last_loc(Loc) when is_tuple(Loc) ->
Loc;
@@ -4299,14 +4336,14 @@ format_exception(Reason={_Error,Stack}) when is_list(Stack) ->
undefined ->
case application:get_env(test_server, format_exception) of
{ok,false} ->
- {"~p",Reason};
+ {"~tp",Reason};
_ ->
do_format_exception(Reason)
end;
FW ->
case application:get_env(FW, format_exception) of
{ok,false} ->
- {"~p",Reason};
+ {"~tp",Reason};
_ ->
do_format_exception(Reason)
end
@@ -4317,13 +4354,13 @@ format_exception(Error) ->
do_format_exception(Reason={Error,Stack}) ->
StackFun = fun(_, _, _) -> false end,
PF = fun(Term, I) ->
- io_lib:format("~." ++ integer_to_list(I) ++ "p", [Term])
+ io_lib:format("~." ++ integer_to_list(I) ++ "tp", [Term])
end,
- case catch lib:format_exception(1, error, Error, Stack, StackFun, PF) of
- {'EXIT',_} ->
- {"~p",Reason};
+ case catch lib:format_exception(1, error, Error, Stack, StackFun, PF, utf8) of
+ {'EXIT',_R} ->
+ {"~tp",Reason};
Formatted ->
- Formatted1 = re:replace(Formatted, "exception error: ", "", [{return,list}]),
+ Formatted1 = re:replace(Formatted, "exception error: ", "", [{return,list},unicode]),
{"~ts",lists:flatten(Formatted1)}
end.
@@ -4429,7 +4466,7 @@ format(Detail, Format, Args) ->
Str =
case catch io_lib:format(Format, Args) of
{'EXIT',_} ->
- io_lib:format("illegal format; ~p with args ~p.\n",
+ io_lib:format("illegal format; ~tp with args ~tp.\n",
[Format,Args]);
Valid -> Valid
end,
@@ -4825,7 +4862,7 @@ collect_files(Dir, Pattern, St, Mode) ->
Wc = filename:join([Dir1,Pattern++"{.erl,"++code:objfile_extension()++"}"]),
case catch filelib:wildcard(Wc) of
{'EXIT', Reason} ->
- io:format("Could not collect files: ~p~n", [Reason]),
+ io:format("Could not collect files: ~tp~n", [Reason]),
{error,{collect_fail,Dir,Pattern}};
Files ->
%% convert to module names and remove duplicates
@@ -4869,13 +4906,13 @@ check_deny_req({Req,Val}, DenyList) ->
%%io:format("ValCheck ~p=~p in ~p\n", [Req,Val,DenyList]),
case lists:keysearch(Req, 1, DenyList) of
{value,{_Req,DenyVal}} when Val >= DenyVal ->
- {denied,io_lib:format("Requirement ~p=~p", [Req,Val])};
+ {denied,io_lib:format("Requirement ~tp=~tp", [Req,Val])};
_ ->
check_deny_req(Req, DenyList)
end;
check_deny_req(Req, DenyList) ->
case lists:member(Req, DenyList) of
- true -> {denied,io_lib:format("Requirement ~p", [Req])};
+ true -> {denied,io_lib:format("Requirement ~tp", [Req])};
false -> granted
end.
@@ -4976,7 +5013,7 @@ get_target_info() ->
start_node(Name, Type, Options) ->
T = 10 * ?ACCEPT_TIMEOUT * test_server:timetrap_scale_factor(),
- format(minor, "Attempt to start ~w node ~p with options ~p",
+ format(minor, "Attempt to start ~w node ~tp with options ~tp",
[Type, Name, Options]),
case controller_call({start_node,Name,Type,Options}, T) of
{{ok,Nodename}, Host, Cmd, Info, Warning} ->
@@ -4998,16 +5035,16 @@ start_node(Name, Type, Options) ->
{fail,{Ret, Host, Cmd}} ->
format(minor,
"Failed to start node ~tp on ~tp with command: ~ts~n"
- "Reason: ~p",
+ "Reason: ~tp",
[Name, Host, Cmd, Ret]),
{fail,Ret};
{Ret, undefined, undefined} ->
- format(minor, "Failed to start node ~tp: ~p", [Name,Ret]),
+ format(minor, "Failed to start node ~tp: ~tp", [Name,Ret]),
Ret;
{Ret, Host, Cmd} ->
format(minor,
"Failed to start node ~tp on ~tp with command: ~ts~n"
- "Reason: ~p",
+ "Reason: ~tp",
[Name, Host, Cmd, Ret]),
Ret
end.
@@ -5106,8 +5143,8 @@ display_info([Pid|T], R, M) ->
Reds = fetch(reductions, Info),
LM = length(fetch(messages, Info)),
pformat(io_lib:format("~w", [Pid]),
- io_lib:format("~w", [Call]),
- io_lib:format("~w", [Curr]), Reds, LM),
+ io_lib:format("~tw", [Call]),
+ io_lib:format("~tw", [Curr]), Reds, LM),
display_info(T, R+Reds, M + LM)
end;
display_info([], R, M) ->
@@ -5221,11 +5258,11 @@ read_cover_file(CoverFile) ->
case check_cover_file(List, [], [], []) of
{ok,Exclude,Include,Cross} -> {Exclude,Include,Cross};
error ->
- io:fwrite("Faulty format of CoverFile ~p\n", [CoverFile]),
+ io:fwrite("Faulty format of CoverFile ~tp\n", [CoverFile]),
{[],[],[]}
end;
{error,Reason} ->
- io:fwrite("Can't read CoverFile ~ts\nReason: ~p\n",
+ io:fwrite("Can't read CoverFile ~ts\nReason: ~tp\n",
[CoverFile,Reason]),
{[],[],[]}
end.
@@ -5493,8 +5530,8 @@ write_coverlog_header(CoverLog) ->
case catch io:put_chars(CoverLog,html_header("Coverage results")) of
{'EXIT',Reason} ->
io:format("\n\nERROR: Could not write normal heading in coverlog.\n"
- "CoverLog: ~w\n"
- "Reason: ~p\n",
+ "CoverLog: ~tw\n"
+ "Reason: ~tp\n",
[CoverLog,Reason]),
io:format(CoverLog,"<html><body>\n", []);
_ ->
diff --git a/lib/common_test/src/test_server_gl.erl b/lib/common_test/src/test_server_gl.erl
index 7d6fe64b92..ce7682d101 100644
--- a/lib/common_test/src/test_server_gl.erl
+++ b/lib/common_test/src/test_server_gl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
%% through the test_server_io module/process.
-module(test_server_gl).
--export([start_link/0,stop/1,set_minor_fd/3,unset_minor_fd/1,
+-export([start_link/1,stop/1,set_minor_fd/3,unset_minor_fd/1,
get_tc_supervisor/1,print/4,set_props/2]).
-export([init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2]).
@@ -33,6 +33,7 @@
tc :: mfa() | 'undefined', %Current test case MFA
minor :: 'none'|pid(), %Minor fd
minor_monitor, %Monitor ref for minor fd
+ tsio_monitor, %Monitor red for controlling proc
capture :: 'none'|pid(), %Capture output
reject_io :: boolean(), %Reject I/O requests...
permit_io, %... and exceptions
@@ -45,8 +46,8 @@
%% Start a new group leader process. Only to be called by
%% the test_server_io process.
-start_link() ->
- case gen_server:start_link(?MODULE, [], []) of
+start_link(TSIO) ->
+ case gen_server:start_link(?MODULE, [TSIO], []) of
{ok,Pid} ->
{ok,Pid};
Other ->
@@ -130,14 +131,16 @@ set_props(GL, PropList) ->
%%% Internal functions.
-init([]) ->
+init([TSIO]) ->
EscChars = case application:get_env(test_server, esc_chars) of
{ok,ECBool} -> ECBool;
_ -> true
end,
+ Ref = erlang:monitor(process, TSIO),
{ok,#st{tc_supervisor=none,
minor=none,
minor_monitor=none,
+ tsio_monitor=Ref,
capture=none,
reject_io=false,
permit_io=gb_sets:empty(),
@@ -170,12 +173,15 @@ handle_info({'DOWN',Ref,process,_,Reason}=D, #st{minor_monitor=Ref}=St) ->
case Reason of
normal -> ok;
_ ->
- Data = io_lib:format("=== WARNING === TC: ~w\n"
- "Got down from minor Fd ~w: ~w\n\n",
+ Data = io_lib:format("=== WARNING === TC: ~tw\n"
+ "Got down from minor Fd ~w: ~tw\n\n",
[St#st.tc,St#st.minor,D]),
test_server_io:print_unexpected(Data)
end,
{noreply,St#st{minor=none,minor_monitor=none}};
+handle_info({'DOWN',Ref,process,_,_}, #st{tsio_monitor=Ref}=St) ->
+ %% controlling process (test_server_io) terminated, we're done
+ {stop,normal,St};
handle_info({permit_io,Pid}, #st{permit_io=P}=St) ->
{noreply,St#st{permit_io=gb_sets:add(Pid, P)}};
handle_info({capture,Cap0}, St) ->
@@ -313,7 +319,7 @@ output(Level, Str, Sender, From, St) when is_atom(Level) ->
output_to_file(Level, dress_output(Str, Sender, St), From, St).
output_to_file(minor, Data0, From, #st{tc={M,F,A},minor=none}) ->
- Data = [io_lib:format("=== ~w:~w/~w\n", [M,F,A]),Data0],
+ Data = [io_lib:format("=== ~w:~tw/~w\n", [M,F,A]),Data0],
test_server_io:print(From, unexpected_io, Data),
ok;
output_to_file(minor, Data, From, #st{tc=TC,minor=Fd}) ->
@@ -322,10 +328,10 @@ output_to_file(minor, Data, From, #st{tc=TC,minor=Fd}) ->
catch
Type:Reason ->
Data1 =
- [io_lib:format("=== ERROR === TC: ~w\n"
+ [io_lib:format("=== ERROR === TC: ~tw\n"
"Failed to write to minor Fd: ~w\n"
"Type: ~w\n"
- "Reason: ~w\n",
+ "Reason: ~tw\n",
[TC,Fd,Type,Reason]),
Data,"\n"],
test_server_io:print(From, unexpected_io, Data1)
diff --git a/lib/common_test/src/test_server_io.erl b/lib/common_test/src/test_server_io.erl
index 3d5238052b..062e3bd8ff 100644
--- a/lib/common_test/src/test_server_io.erl
+++ b/lib/common_test/src/test_server_io.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -185,7 +185,7 @@ reset_state() ->
init([]) ->
process_flag(trap_exit, true),
Empty = gb_trees:empty(),
- {ok,Shared} = test_server_gl:start_link(),
+ {ok,Shared} = test_server_gl:start_link(self()),
{ok,#st{fds=Empty,shared_gl=Shared,gls=gb_sets:empty(),
io_buffering=gb_sets:empty(),
buffered=Empty,
@@ -200,7 +200,7 @@ req(Req) ->
gen_server:call(?MODULE, Req, infinity).
handle_call({get_gl,false}, _From, #st{gls=Gls,gl_props=Props}=St) ->
- {ok,Pid} = test_server_gl:start_link(),
+ {ok,Pid} = test_server_gl:start_link(self()),
test_server_gl:set_props(Pid, Props),
{reply,Pid,St#st{gls=gb_sets:insert(Pid, Gls)}};
handle_call({get_gl,true}, _From, #st{shared_gl=Shared}=St) ->
@@ -285,7 +285,7 @@ handle_call(reset_state, _From, #st{fds=Fds,tags=Tags,gls=Gls,
ok
end,
Empty = gb_trees:empty(),
- {ok,Shared} = test_server_gl:start_link(),
+ {ok,Shared} = test_server_gl:start_link(self()),
{reply,ok,#st{fds=Empty,shared_gl=Shared,gls=gb_sets:empty(),
io_buffering=gb_sets:empty(),
buffered=Empty,
@@ -359,7 +359,7 @@ handle_info(kill_group_leaders, #st{gls=Gls,stopping=From,
end, St#st{phase=idle,pending_ops=[]}, Ops),
{noreply,St1};
handle_info(Other, St) ->
- io:format("Ignoring: ~p\n", [Other]),
+ io:format("Ignoring: ~tp\n", [Other]),
{noreply,St}.
terminate(_, _) ->
@@ -395,7 +395,7 @@ do_output(Tag, Str, Phase, #st{fds=Fds}=St) ->
none when Phase /= started ->
buffer;
none ->
- S = io_lib:format("\n*** ERROR: ~w, line ~w: No known '~p' log file\n",
+ S = io_lib:format("\n*** ERROR: ~w, line ~w: No known '~tp' log file\n",
[?MODULE,?LINE,Tag]),
do_output(stdout, [S,Str], Phase, St);
{value,Fd} ->
@@ -407,7 +407,7 @@ do_output(Tag, Str, Phase, #st{fds=Fds}=St) ->
end
catch _:Error ->
S = io_lib:format("\n*** ERROR: ~w, line ~w: Error writing to "
- "log file '~p': ~p\n",
+ "log file '~tp': ~tp\n",
[?MODULE,?LINE,Tag,Error]),
do_output(stdout, [S,Str], Phase, St)
end
diff --git a/lib/common_test/src/test_server_node.erl b/lib/common_test/src/test_server_node.erl
index 0b406c54cc..a18ff1fd62 100644
--- a/lib/common_test/src/test_server_node.erl
+++ b/lib/common_test/src/test_server_node.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,11 +18,11 @@
%% %CopyrightEnd%
%%
-module(test_server_node).
--compile(r12).
+-compile(r16).
%%%
%%% The same compiled code for this module must be possible to load
-%%% in R12B and later.
+%%% in R16B and later.
%%%
%% Test Controller interface
@@ -237,23 +237,23 @@ print_trc(Out,{trace_ts,P,call,{M,F,A},C,Ts},N) ->
io:format(Out,
"~w: ~s~n"
"Process : ~w~n"
- "Call : ~w:~w/~w~n"
- "Arguments : ~p~n"
- "Caller : ~w~n~n",
+ "Call : ~w:~tw/~w~n"
+ "Arguments : ~tp~n"
+ "Caller : ~tw~n~n",
[N,ts(Ts),P,M,F,length(A),A,C]);
print_trc(Out,{trace_ts,P,call,{M,F,A},Ts},N) ->
io:format(Out,
"~w: ~s~n"
"Process : ~w~n"
- "Call : ~w:~w/~w~n"
- "Arguments : ~p~n~n",
+ "Call : ~w:~tw/~w~n"
+ "Arguments : ~tp~n~n",
[N,ts(Ts),P,M,F,length(A),A]);
print_trc(Out,{trace_ts,P,return_from,{M,F,A},R,Ts},N) ->
io:format(Out,
"~w: ~s~n"
"Process : ~w~n"
- "Return from : ~w:~w/~w~n"
- "Return value : ~p~n~n",
+ "Return from : ~w:~tw/~w~n"
+ "Return value : ~tp~n~n",
[N,ts(Ts),P,M,F,A,R]);
print_trc(Out,{drop,X},N) ->
io:format(Out,
@@ -263,7 +263,7 @@ print_trc(Out,Trace,N) ->
Ts = element(size(Trace),Trace),
io:format(Out,
"~w: ~s~n"
- "Trace : ~p~n~n",
+ "Trace : ~tp~n~n",
[N,ts(Ts),Trace]).
ts({_, _, Micro} = Now) ->
{{Y,M,D},{H,Min,S}} = calendar:now_to_local_time(Now),
@@ -580,7 +580,7 @@ kill_node(SI) ->
cast_to_list(X) when is_list(X) -> X;
cast_to_list(X) when is_atom(X) -> atom_to_list(X);
-cast_to_list(X) -> lists:flatten(io_lib:format("~w", [X])).
+cast_to_list(X) -> lists:flatten(io_lib:format("~tw", [X])).
%%% L contains elements of the forms
diff --git a/lib/common_test/src/test_server_sup.erl b/lib/common_test/src/test_server_sup.erl
index 6922e01fcc..9a26de4774 100644
--- a/lib/common_test/src/test_server_sup.erl
+++ b/lib/common_test/src/test_server_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -83,7 +83,7 @@ kill_the_process(Pid, Timeout0, TruncTO, ReportTVal) ->
"Testcase process ~w not "
"responding to timetrap "
"timeout:~n"
- " ~p.~n"
+ " ~tp.~n"
"Killing testcase...~n",
[Pid, Trap]),
exit(Pid, kill)
@@ -144,11 +144,11 @@ call_crash(Time,Crash,M,F,A) ->
{'EXIT',Pid,_Reason} when Crash==any ->
ok;
{'EXIT',Reason} ->
- test_server:format(12, "Wrong crash reason. Wanted ~p, got ~p.",
+ test_server:format(12, "Wrong crash reason. Wanted ~tp, got ~tp.",
[Crash, Reason]),
exit({wrong_crash_reason,Reason});
{'EXIT',Pid,Reason} ->
- test_server:format(12, "Wrong crash reason. Wanted ~p, got ~p.",
+ test_server:format(12, "Wrong crash reason. Wanted ~tp, got ~tp.",
[Crash, Reason]),
exit({wrong_crash_reason,Reason});
{'EXIT',OtherPid,Reason} when OldTrapExit == false ->
@@ -334,11 +334,11 @@ do_appup_tests(_, _Application, Up, Down, Modules) ->
ok ->
test_server:format(minor, "OK~n");
Error ->
- test_server:format(minor, "ERROR ~p~n", [Error]),
+ test_server:format(minor, "ERROR ~tp~n", [Error]),
test_server:fail(Error)
end;
Error ->
- test_server:format(minor, "ERROR ~p~n", [Error]),
+ test_server:format(minor, "ERROR ~tp~n", [Error]),
test_server:fail(Error)
end.
@@ -557,7 +557,7 @@ check_dict(Dict, Reason) ->
[] ->
1; % All ok.
List ->
- io:format("** ~ts (~ts) ->~n~p~n",[Reason, Dict, List]),
+ io:format("** ~ts (~ts) ->~n~tp~n",[Reason, Dict, List]),
0
end.
@@ -566,7 +566,7 @@ check_dict_tolerant(Dict, Reason, Mode) ->
[] ->
1; % All ok.
List ->
- io:format("** ~ts (~ts) ->~n~p~n",[Reason, Dict, List]),
+ io:format("** ~ts (~ts) ->~n~tp~n",[Reason, Dict, List]),
case Mode of
pedantic ->
0;
@@ -646,7 +646,7 @@ append_files_to_logfile([File|Files]) ->
%% fail, but in that case it will throw an exception so that
%% we will be aware of the problem.
io:format(Fd, "Unable to write the crash dump "
- "to this file: ~p~n", [file:format_error(Error)])
+ "to this file: ~tp~n", [file:format_error(Error)])
end;
_Error ->
io:format(Fd, "Failed to read: ~ts\n", [File])
@@ -802,9 +802,9 @@ format_loc([{Mod,Func,Line}|Rest]) ->
format_loc([{Mod,LineOrFunc}]) ->
format_loc({Mod,LineOrFunc});
format_loc({Mod,Func}) when is_atom(Func) ->
- io_lib:format("{~w,~w}",[Mod,Func]);
+ io_lib:format("{~w,~tw}",[Mod,Func]);
format_loc(Loc) ->
- io_lib:format("~p",[Loc]).
+ io_lib:format("~tp",[Loc]).
format_loc1([{Mod,Func,Line}]) ->
[" ",format_loc1({Mod,Func,Line}),"]"];
@@ -824,12 +824,12 @@ format_loc1({Mod,Func,Line}) ->
true ->
Line
end,
- io_lib:format("{~w,~w,<a href=\"~ts~ts#~s\">~w</a>}",
+ io_lib:format("{~w,~tw,<a href=\"~ts~ts#~ts\">~tw</a>}",
[Mod,Func,
test_server_ctrl:uri_encode(downcase(ModStr)),
?src_listing_ext,Link,Line]);
_ ->
- io_lib:format("{~w,~w,~w}",[Mod,Func,Line])
+ io_lib:format("{~w,~tw,~tw}",[Mod,Func,Line])
end.
downcase(S) -> downcase(S, []).
diff --git a/lib/common_test/src/unix_telnet.erl b/lib/common_test/src/unix_telnet.erl
index 4897ddb2f8..8ac467014c 100644
--- a/lib/common_test/src/unix_telnet.erl
+++ b/lib/common_test/src/unix_telnet.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -53,8 +53,6 @@
%%% @see ct_telnet
-module(unix_telnet).
--compile(export_all).
-
%% Callbacks for ct_telnet.erl
-export([connect/7,get_prompt_regexp/0]).
-import(ct_telnet,[start_gen_log/1,log/4,end_gen_log/0]).
@@ -134,25 +132,25 @@ connect1(Name,Ip,Port,Timeout,KeepAlive,TCPNoDelay,Username,Password) ->
Prompt=/=?password ->
{ok,Pid};
Error ->
- log(Name,recv,"Password failed\n~p\n",
+ log(Name,recv,"Password failed\n~tp\n",
[Error]),
{error,Error}
end;
Error ->
- log(Name,recv,"Login to ~p:~p failed\n~p\n",[Ip,Port,Error]),
+ log(Name,recv,"Login to ~p:~p failed\n~tp\n",[Ip,Port,Error]),
{error,Error}
end;
{ok,[{prompt,_OtherPrompt1},{prompt,_OtherPrompt2}],_} ->
{ok,Pid};
Error ->
log(Name,conn_error,
- "Did not get expected prompt from ~p:~p\n~p\n",
+ "Did not get expected prompt from ~p:~p\n~tp\n",
[Ip,Port,Error]),
{error,Error}
end;
Error ->
log(Name,conn_error,
- "Could not open telnet connection to ~p:~p\n~p\n",
+ "Could not open telnet connection to ~p:~p\n~tp\n",
[Ip,Port,Error]),
Error
end,
diff --git a/lib/common_test/src/vts.erl b/lib/common_test/src/vts.erl
index f1c5051164..99a109cfe8 100644
--- a/lib/common_test/src/vts.erl
+++ b/lib/common_test/src/vts.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -250,7 +250,7 @@ loop(State) ->
{'EXIT',Pid,Reason} ->
case State#state.test_runner of
Pid ->
- io:format("Test run error: ~p\n",[Reason]),
+ io:format("Test run error: ~tp\n",[Reason]),
loop(State);
_ ->
loop(State)
@@ -551,7 +551,7 @@ case_select(Dir,Suite,Case,N) ->
true = code:add_pathz(Dir),
case catch apply(Suite,all,[]) of
{'EXIT',Reason} ->
- io:format("\n~p\n",[Reason]),
+ io:format("\n~tp\n",[Reason]),
red(["COULD NOT READ TESTCASES!!",br(),
"See erlang shell for info"]);
{skip,_Reason} ->
diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile
index b1eddfedd7..0d9149f489 100644
--- a/lib/common_test/test/Makefile
+++ b/lib/common_test/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2008-2016. All Rights Reserved.
+# Copyright Ericsson AB 2008-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -70,7 +70,10 @@ MODULES= \
test_server_SUITE \
test_server_test_lib \
ct_release_test_SUITE \
- ct_log_SUITE
+ ct_log_SUITE \
+ ct_SUITE \
+ ct_keep_logs_SUITE \
+ ct_unicode_SUITE
ERL_FILES= $(MODULES:%=%.erl)
HRL_FILES= test_server_test_lib.hrl
diff --git a/lib/common_test/test/ct_SUITE.erl b/lib/common_test/test/ct_SUITE.erl
new file mode 100644
index 0000000000..eb98c2544f
--- /dev/null
+++ b/lib/common_test/test/ct_SUITE.erl
@@ -0,0 +1,53 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(ct_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [app_file, appup_file].
+
+%%%-----------------------------------------------------------------
+%%% Test cases
+
+app_file(_Config) ->
+ ok = test_server:app_test(common_test),
+ ok.
+
+appup_file(_Config) ->
+ ok = test_server:appup_test(common_test).
+
diff --git a/lib/common_test/test/ct_auto_compile_SUITE.erl b/lib/common_test/test/ct_auto_compile_SUITE.erl
index e6939d23c0..dface99b8f 100644
--- a/lib/common_test/test/ct_auto_compile_SUITE.erl
+++ b/lib/common_test/test/ct_auto_compile_SUITE.erl
@@ -27,6 +27,7 @@
%%% The suites used for the test are located in the data directory.
%%%-------------------------------------------------------------------
-module(ct_auto_compile_SUITE).
+-warning("Ignore me -- testing that the debugger can handle warnings").
-compile(export_all).
diff --git a/lib/common_test/test/ct_config_SUITE.erl b/lib/common_test/test/ct_config_SUITE.erl
index 9879e0f20d..250700741c 100644
--- a/lib/common_test/test/ct_config_SUITE.erl
+++ b/lib/common_test/test/ct_config_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -113,10 +113,14 @@ userconfig_static(Config) when is_list(Config) ->
["config_static_SUITE"]).
userconfig_dynamic(Config) when is_list(Config) ->
- run_test(config_dynamic_SUITE,
- Config,
- {userconfig, {config_driver, "config_server"}},
- ["config_dynamic_SUITE"]).
+ case skip_dynamic() of
+ true -> {skip,"TimeWarpingOS"};
+ false ->
+ run_test(config_dynamic_SUITE,
+ Config,
+ {userconfig, {config_driver, "config_server"}},
+ ["config_dynamic_SUITE"])
+ end.
testspec_legacy(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
@@ -147,16 +151,20 @@ testspec_static(Config) when is_list(Config) ->
file:delete(filename:join(ConfigDir, "spec_static.spec")).
testspec_dynamic(Config) when is_list(Config) ->
- DataDir = ?config(data_dir, Config),
- ConfigDir = ?config(config_dir, Config),
- make_spec(DataDir, ConfigDir, "spec_dynamic.spec",
- [config_dynamic_SUITE],
- [{userconfig, {config_driver, "config_server"}}]),
- run_test(config_dynamic_SUITE,
- Config,
- {spec, filename:join(ConfigDir, "spec_dynamic.spec")},
- []),
- file:delete(filename:join(ConfigDir, "spec_dynamic.spec")).
+ case skip_dynamic() of
+ true -> {skip,"TimeWarpingOS"};
+ false ->
+ DataDir = ?config(data_dir, Config),
+ ConfigDir = ?config(config_dir, Config),
+ make_spec(DataDir, ConfigDir, "spec_dynamic.spec",
+ [config_dynamic_SUITE],
+ [{userconfig, {config_driver, "config_server"}}]),
+ run_test(config_dynamic_SUITE,
+ Config,
+ {spec, filename:join(ConfigDir, "spec_dynamic.spec")},
+ []),
+ file:delete(filename:join(ConfigDir, "spec_dynamic.spec"))
+ end.
@@ -164,10 +172,10 @@ testspec_dynamic(Config) when is_list(Config) ->
%%% HELP FUNCTIONS
%%%-----------------------------------------------------------------
make_spec(DataDir, ConfigDir, Filename, Suites, Config)->
- {ok, Fd} = file:open(filename:join(ConfigDir, Filename), [write]),
- ok = file:write(Fd,
- io_lib:format("{suites, \"~sconfig/test/\", ~p}.~n", [DataDir, Suites])),
- lists:foreach(fun(C)-> ok=file:write(Fd, io_lib:format("~p.~n", [C])) end, Config),
+ {ok, Fd} = file:open(filename:join(ConfigDir, Filename),
+ [write, {encoding,utf8}]),
+ ok = io:format(Fd,"{suites, \"~tsconfig/test/\", ~p}.~n", [DataDir, Suites]),
+ lists:foreach(fun(C)-> ok=io:format(Fd, "~tp.~n", [C]) end, Config),
ok = file:close(Fd).
run_test(Name, Config, CTConfig, SuiteNames)->
@@ -198,6 +206,23 @@ setup_env(Test, Config, CTConfig) ->
reformat_events(Events, EH) ->
ct_test_support:reformat(Events, EH).
+
+%%%-----------------------------------------------------------------
+%%% Test related to 'localtime' will often fail if the test host is
+%%% time warping, so let's just skip the 'dynamic' tests then.
+skip_dynamic() ->
+ case os:getenv("TS_EXTRA_PLATFORM_LABEL") of
+ TSExtraPlatformLabel when is_list(TSExtraPlatformLabel) ->
+ case string:str(TSExtraPlatformLabel,"TimeWarpingOS") of
+ 0 -> false;
+ _ -> true
+ end;
+ _ ->
+ false
+ end.
+
+
+
%%%-----------------------------------------------------------------
%%% TEST EVENTS
%%%-----------------------------------------------------------------
diff --git a/lib/common_test/test/ct_error_SUITE.erl b/lib/common_test/test/ct_error_SUITE.erl
index fae23484e6..7468ebe9d9 100644
--- a/lib/common_test/test/ct_error_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1531,17 +1531,17 @@ test_events(config_func_errors) ->
{?eh,tc_start,{config_func_error_1_SUITE,exit_in_iptc}},
{?eh,tc_done,{config_func_error_1_SUITE,exit_in_iptc,'_'}},
- {?eh,test_stats,{0,1,{0,0}}},
+ {?eh,test_stats,{0,0,{0,1}}},
{?eh,tc_start,{config_func_error_1_SUITE,exit_in_eptc}},
{?eh,tc_done,{config_func_error_1_SUITE,exit_in_eptc,'_'}},
- {?eh,test_stats,{0,2,{0,0}}},
+ {?eh,test_stats,{1,0,{0,1}}},
[{?eh,tc_start,{config_func_error_1_SUITE,{init_per_group,g1,[]}}},
{?eh,tc_done,{config_func_error_1_SUITE,{init_per_group,g1,[]},ok}},
{?eh,tc_start,{config_func_error_1_SUITE,exit_in_iptc}},
{?eh,tc_done,{config_func_error_1_SUITE,exit_in_iptc,'_'}},
- {?eh,test_stats,{0,3,{0,0}}},
+ {?eh,test_stats,{1,0,{0,2}}},
{?eh,tc_start,{config_func_error_1_SUITE,{end_per_group,g1,[]}}},
{?eh,tc_done,{config_func_error_1_SUITE,{end_per_group,g1,[]},ok}}],
@@ -1549,7 +1549,7 @@ test_events(config_func_errors) ->
{?eh,tc_done,{config_func_error_1_SUITE,{init_per_group,g2,[]},ok}},
{?eh,tc_start,{config_func_error_1_SUITE,exit_in_eptc}},
{?eh,tc_done,{config_func_error_1_SUITE,exit_in_eptc,'_'}},
- {?eh,test_stats,{0,4,{0,0}}},
+ {?eh,test_stats,{2,0,{0,2}}},
{?eh,tc_start,{config_func_error_1_SUITE,{end_per_group,g2,[]}}},
{?eh,tc_done,{config_func_error_1_SUITE,{end_per_group,g2,[]},ok}}],
diff --git a/lib/common_test/test/ct_hooks_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE.erl
index 690d0af1bb..8ba14e63bc 100644
--- a/lib/common_test/test/ct_hooks_SUITE.erl
+++ b/lib/common_test/test/ct_hooks_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -70,22 +70,25 @@ suite() ->
all() ->
all(suite).
-all(suite) ->
+all(suite) ->
lists:reverse(
[
one_cth, two_cth, faulty_cth_no_init, faulty_cth_id_no_init,
faulty_cth_exit_in_init, faulty_cth_exit_in_id,
- faulty_cth_exit_in_init_scope_suite, minimal_cth,
- minimal_and_maximal_cth, faulty_cth_undef,
+ faulty_cth_exit_in_init_scope_suite, minimal_cth,
+ minimal_and_maximal_cth, faulty_cth_undef,
scope_per_suite_cth, scope_per_group_cth, scope_suite_cth,
- scope_per_suite_state_cth, scope_per_group_state_cth,
+ scope_per_suite_state_cth, scope_per_group_state_cth,
scope_suite_state_cth,
fail_pre_suite_cth, double_fail_pre_suite_cth,
fail_post_suite_cth, skip_pre_suite_cth, skip_pre_end_cth,
+ skip_pre_init_tc_cth,
skip_post_suite_cth, recover_post_suite_cth, update_config_cth,
- state_update_cth, options_cth, same_id_cth,
+ state_update_cth, options_cth, same_id_cth,
fail_n_skip_with_minimal_cth, prio_cth, no_config,
- data_dir, cth_log
+ no_init_suite_config, no_init_config, no_end_config,
+ failed_sequence, repeat_force_stop, config_clash,
+ callbacks_on_skip, fallback, data_dir, cth_log
]
).
@@ -96,10 +99,10 @@ all(suite) ->
%%%-----------------------------------------------------------------
%%%
-one_cth(Config) when is_list(Config) ->
+one_cth(Config) when is_list(Config) ->
do_test(one_empty_cth, "ct_cth_empty_SUITE.erl",[empty_cth], Config).
-two_cth(Config) when is_list(Config) ->
+two_cth(Config) when is_list(Config) ->
do_test(two_empty_cth, "ct_cth_empty_SUITE.erl",[empty_cth,empty_cth],
Config).
@@ -119,13 +122,13 @@ minimal_cth(Config) when is_list(Config) ->
minimal_and_maximal_cth(Config) when is_list(Config) ->
do_test(minimal_and_maximal_cth, "ct_cth_empty_SUITE.erl",
[minimal_cth, empty_cth],Config).
-
+
faulty_cth_undef(Config) when is_list(Config) ->
do_test(faulty_cth_undef, "ct_cth_empty_SUITE.erl",
[undef_cth],Config).
faulty_cth_exit_in_init_scope_suite(Config) when is_list(Config) ->
- do_test(faulty_cth_exit_in_init_scope_suite,
+ do_test(faulty_cth_exit_in_init_scope_suite,
"ct_exit_in_init_scope_suite_cth_SUITE.erl",
[],Config).
@@ -190,6 +193,10 @@ skip_post_suite_cth(Config) when is_list(Config) ->
do_test(skip_post_suite_cth, "ct_cth_empty_SUITE.erl",
[skip_post_suite_cth],Config).
+skip_pre_init_tc_cth(Config) ->
+ do_test(skip_pre_init_tc_cth, "ct_cth_empty_SUITE.erl",
+ [skip_pre_init_tc_cth],Config).
+
recover_post_suite_cth(Config) when is_list(Config) ->
do_test(recover_post_suite_cth, "ct_cth_fail_per_suite_SUITE.erl",
[recover_post_suite_cth],Config).
@@ -205,7 +212,7 @@ state_update_cth(Config) when is_list(Config) ->
options_cth(Config) when is_list(Config) ->
do_test(options_cth, "ct_cth_empty_SUITE.erl",
[{empty_cth,[test]}],Config).
-
+
same_id_cth(Config) when is_list(Config) ->
do_test(same_id_cth, "ct_cth_empty_SUITE.erl",
[same_id_cth,same_id_cth],Config).
@@ -223,13 +230,24 @@ no_config(Config) when is_list(Config) ->
do_test(no_config, "ct_no_config_SUITE.erl",
[verify_config_cth],Config).
+no_init_suite_config(Config) when is_list(Config) ->
+ do_test(no_init_suite_config, "ct_no_init_suite_config_SUITE.erl",
+ [empty_cth],Config).
+
+no_init_config(Config) when is_list(Config) ->
+ do_test(no_init_config, "ct_no_init_config_SUITE.erl",[empty_cth],Config).
+
+no_end_config(Config) when is_list(Config) ->
+ do_test(no_end_config, "ct_no_end_config_SUITE.erl",[empty_cth],Config).
+
data_dir(Config) when is_list(Config) ->
do_test(data_dir, "ct_data_dir_SUITE.erl",
[verify_data_dir_cth],Config).
-cth_log(Config) when is_list(Config) ->
+cth_log(Config) when is_list(Config) ->
%% test that cth_log_redirect writes properly to
%% unexpected I/O log
+ ct:timetrap({minutes,10}),
StartOpts = do_test(cth_log, "cth_log_SUITE.erl", [], Config),
Logdir = proplists:get_value(logdir, StartOpts),
UnexpIoLogs =
@@ -253,29 +271,57 @@ cth_log(Config) when is_list(Config) ->
end, UnexpIoLogs),
ok.
+%% OTP-10599 adds the Suite argument as first argument to all hook
+%% callbacks that did not have a Suite argument from before. This test
+%% checks that ct_hooks will fall back to old versions of callbacks if
+%% new versions are not exported.
+fallback(Config) ->
+ do_test(fallback, "all_hook_callbacks_SUITE.erl",[fallback_cth], Config).
+
+%% Test that expected callbacks, and only those, are called when tests
+%% are skipped in different ways
+callbacks_on_skip(Config) ->
+ do_test(callbacks_on_skip, {spec,"skip.spec"},[skip_cth], Config).
+
+%% Test that expected callbacks, and only those, are called when tests
+%% are skipped due to failed sequence
+failed_sequence(Config) ->
+ do_test(failed_sequence, "seq_SUITE.erl", [skip_cth], Config).
+
+%% Test that expected callbacks, and only those, are called when tests
+%% are skipped due to {force_stop,skip_rest} option
+repeat_force_stop(Config) ->
+ do_test(repeat_force_stop, "repeat_SUITE.erl", [skip_cth], Config, ok, 2,
+ [{force_stop,skip_rest},{duration,"000009"}]).
+
+%% Test that expected callbacks, and only those, are called when a test
+%% are fails due to clash in config alias names
+config_clash(Config) ->
+ do_test(config_clash, "config_clash_SUITE.erl", [skip_cth], Config).
%%%-----------------------------------------------------------------
%%% HELP FUNCTIONS
%%%-----------------------------------------------------------------
-do_test(Tag, SWC, CTHs, Config) ->
- do_test(Tag, SWC, CTHs, Config, ok).
-do_test(Tag, SWC, CTHs, Config, {error,_} = Res) ->
- do_test(Tag, SWC, CTHs, Config, Res, 1);
-do_test(Tag, SWC, CTHs, Config, Res) ->
- do_test(Tag, SWC, CTHs, Config, Res, 2).
+do_test(Tag, WTT, CTHs, Config) ->
+ do_test(Tag, WTT, CTHs, Config, ok).
+do_test(Tag, WTT, CTHs, Config, {error,_} = Res) ->
+ do_test(Tag, WTT, CTHs, Config, Res, 1,[]);
+do_test(Tag, WTT, CTHs, Config, Res) ->
+ do_test(Tag, WTT, CTHs, Config, Res, 2,[]).
-do_test(Tag, SuiteWildCard, CTHs, Config, Res, EC) ->
-
+do_test(Tag, WhatToTest, CTHs, Config, Res, EC, ExtraOpts) when is_list(WhatToTest) ->
+ do_test(Tag, {suite,WhatToTest}, CTHs, Config, Res, EC, ExtraOpts);
+do_test(Tag, {WhatTag,Wildcard}, CTHs, Config, Res, EC, ExtraOpts) ->
DataDir = ?config(data_dir, Config),
- Suites = filelib:wildcard(
- filename:join([DataDir,"cth/tests",SuiteWildCard])),
- {Opts,ERPid} = setup([{suite,Suites},
- {ct_hooks,CTHs},{label,Tag}], Config),
+ Files = filelib:wildcard(
+ filename:join([DataDir,"cth/tests",Wildcard])),
+ {Opts,ERPid} =
+ setup([{WhatTag,Files},{ct_hooks,CTHs},{label,Tag}|ExtraOpts], Config),
Res = ct_test_support:run(Opts, Config),
Events = ct_test_support:get_events(ERPid, Config),
- ct_test_support:log_events(Tag,
+ ct_test_support:log_events(Tag,
reformat(Events, ?eh),
?config(priv_dir, Config),
Opts),
@@ -323,12 +369,12 @@ test_events(one_empty_cth) ->
{?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
{?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
- {?eh,cth,{empty_cth,pre_init_per_testcase,[test_case,'$proplist',[]]}},
- {?eh,cth,{empty_cth,post_init_per_testcase,[test_case,'$proplist','_',[]]}},
- {?eh,cth,{empty_cth,pre_end_per_testcase,[test_case,'$proplist',[]]}},
- {?eh,cth,{empty_cth,post_end_per_testcase,[test_case,'$proplist','_',[]]}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist','_',[]]}},
+ {?eh,cth,{empty_cth,pre_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist','_',[]]}},
{?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
{?eh,cth,{empty_cth,pre_end_per_suite,
[ct_cth_empty_SUITE,'$proplist',[]]}},
@@ -355,12 +401,12 @@ test_events(two_empty_cth) ->
{?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
{?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',ok,[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',ok,[]]}},
{?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
{?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
{?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
@@ -402,7 +448,7 @@ test_events(minimal_cth) ->
{?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
{?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
{?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
{?eh,test_done,{'DEF','STOP_TIME'}},
@@ -423,10 +469,10 @@ test_events(minimal_and_maximal_cth) ->
{?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
{?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',ok,[]]}},
{?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
{?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
{?eh,cth,{'_',post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[]]}},
@@ -452,11 +498,11 @@ test_events(faulty_cth_undef) ->
{?eh,tc_auto_skip,{ct_cth_empty_SUITE,test_case,
{failed, FailReason}}},
{?eh,cth,{'_',on_tc_skip,'_'}},
-
+
{?eh,tc_auto_skip,{ct_cth_empty_SUITE,end_per_suite,
{failed, FailReason}}},
{?eh,cth,{'_',on_tc_skip,'_'}},
-
+
{?eh,test_done,{'DEF','STOP_TIME'}},
{?eh,stop_logging,[]}
];
@@ -512,10 +558,10 @@ test_events(scope_per_suite_cth) ->
{?eh,tc_done,{ct_scope_per_suite_cth_SUITE,init_per_suite,ok}},
{?eh,tc_start,{ct_scope_per_suite_cth_SUITE,test_case}},
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_per_suite_cth_SUITE,test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_scope_per_suite_cth_SUITE,test_case,'$proplist',ok,[]]}},
{?eh,tc_done,{ct_scope_per_suite_cth_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_scope_per_suite_cth_SUITE,end_per_suite}},
{?eh,cth,{'_',pre_end_per_suite,
[ct_scope_per_suite_cth_SUITE,'$proplist',[]]}},
@@ -538,10 +584,10 @@ test_events(scope_suite_cth) ->
{?eh,tc_done,{ct_scope_suite_cth_SUITE,init_per_suite,ok}},
{?eh,tc_start,{ct_scope_suite_cth_SUITE,test_case}},
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_suite_cth_SUITE,test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_scope_suite_cth_SUITE,test_case,'$proplist',ok,[]]}},
{?eh,tc_done,{ct_scope_suite_cth_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_scope_suite_cth_SUITE,end_per_suite}},
{?eh,cth,{'_',pre_end_per_suite,[ct_scope_suite_cth_SUITE,'$proplist',[]]}},
{?eh,cth,{'_',post_end_per_suite,[ct_scope_suite_cth_SUITE,'$proplist','_',[]]}},
@@ -561,20 +607,20 @@ test_events(scope_per_group_cth) ->
[{?eh,tc_start,{ct_scope_per_group_cth_SUITE,{init_per_group,group1,[]}}},
{?eh,cth,{'_',id,[[]]}},
{?eh,cth,{'_',init,['_',[]]}},
- {?eh,cth,{'_',post_init_per_group,[group1,'$proplist','$proplist',[]]}},
+ {?eh,cth,{'_',post_init_per_group,[ct_scope_per_group_cth_SUITE,group1, '$proplist','$proplist',[]]}},
{?eh,tc_done,{ct_scope_per_group_cth_SUITE,{init_per_group,group1,[]},ok}},
-
+
{?eh,tc_start,{ct_scope_per_group_cth_SUITE,test_case}},
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_per_group_cth_SUITE,test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_scope_per_group_cth_SUITE,test_case,'$proplist',ok,[]]}},
{?eh,tc_done,{ct_scope_per_group_cth_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_scope_per_group_cth_SUITE,{end_per_group,group1,[]}}},
- {?eh,cth,{'_',pre_end_per_group,[group1,'$proplist',[]]}},
- {?eh,cth,{'_',post_end_per_group,[group1,'$proplist','_',[]]}},
+ {?eh,cth,{'_',pre_end_per_group,[ct_scope_per_group_cth_SUITE,group1,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_group,[ct_scope_per_group_cth_SUITE,group1,'$proplist','_',[]]}},
{?eh,cth,{'_',terminate,[[]]}},
{?eh,tc_done,{ct_scope_per_group_cth_SUITE,{end_per_group,group1,[]},ok}}],
-
+
{?eh,tc_start,{ct_scope_per_group_cth_SUITE,end_per_suite}},
{?eh,tc_done,{ct_scope_per_group_cth_SUITE,end_per_suite,ok}},
{?eh,test_done,{'DEF','STOP_TIME'}},
@@ -592,10 +638,10 @@ test_events(scope_per_suite_state_cth) ->
{?eh,tc_done,{ct_scope_per_suite_state_cth_SUITE,init_per_suite,ok}},
{?eh,tc_start,{ct_scope_per_suite_state_cth_SUITE,test_case}},
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[test]]}},
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[test]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_per_suite_state_cth_SUITE,test_case,'$proplist',[test]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_scope_per_suite_state_cth_SUITE,test_case,'$proplist',ok,[test]]}},
{?eh,tc_done,{ct_scope_per_suite_state_cth_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_scope_per_suite_state_cth_SUITE,end_per_suite}},
{?eh,cth,{'_',pre_end_per_suite,
[ct_scope_per_suite_state_cth_SUITE,'$proplist',[test]]}},
@@ -618,10 +664,10 @@ test_events(scope_suite_state_cth) ->
{?eh,tc_done,{ct_scope_suite_state_cth_SUITE,init_per_suite,ok}},
{?eh,tc_start,{ct_scope_suite_state_cth_SUITE,test_case}},
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[test]]}},
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[test]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_suite_state_cth_SUITE,test_case,'$proplist',[test]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_scope_suite_state_cth_SUITE,test_case,'$proplist',ok,[test]]}},
{?eh,tc_done,{ct_scope_suite_state_cth_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_scope_suite_state_cth_SUITE,end_per_suite}},
{?eh,cth,{'_',pre_end_per_suite,[ct_scope_suite_state_cth_SUITE,'$proplist',[test]]}},
{?eh,cth,{'_',post_end_per_suite,[ct_scope_suite_state_cth_SUITE,'$proplist','_',[test]]}},
@@ -641,20 +687,20 @@ test_events(scope_per_group_state_cth) ->
[{?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,{init_per_group,group1,[]}}},
{?eh,cth,{'_',id,[[test]]}},
{?eh,cth,{'_',init,['_',[test]]}},
- {?eh,cth,{'_',post_init_per_group,[group1,'$proplist','$proplist',[test]]}},
+ {?eh,cth,{'_',post_init_per_group,[ct_scope_per_group_state_cth_SUITE,group1,'$proplist','$proplist',[test]]}},
{?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,{init_per_group,group1,[]},ok}},
-
+
{?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,test_case}},
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[test]]}},
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[test]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_per_group_state_cth_SUITE,test_case,'$proplist',[test]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_scope_per_group_state_cth_SUITE,test_case,'$proplist',ok,[test]]}},
{?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,{end_per_group,group1,[]}}},
- {?eh,cth,{'_',pre_end_per_group,[group1,'$proplist',[test]]}},
- {?eh,cth,{'_',post_end_per_group,[group1,'$proplist','_',[test]]}},
+ {?eh,cth,{'_',pre_end_per_group,[ct_scope_per_group_state_cth_SUITE,group1,'$proplist',[test]]}},
+ {?eh,cth,{'_',post_end_per_group,[ct_scope_per_group_state_cth_SUITE,group1,'$proplist','_',[test]]}},
{?eh,cth,{'_',terminate,[[test]]}},
{?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,{end_per_group,group1,[]},ok}}],
-
+
{?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,end_per_suite}},
{?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,end_per_suite,ok}},
{?eh,test_done,{'DEF','STOP_TIME'}},
@@ -666,7 +712,7 @@ test_events(fail_pre_suite_cth) ->
{?eh,start_logging,{'DEF','RUNDIR'}},
{?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
{?eh,cth,{'_',init,['_',[]]}},
-
+
{?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
{?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
{?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist',
@@ -674,27 +720,27 @@ test_events(fail_pre_suite_cth) ->
{?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,
{failed, {error,"Test failure"}}}},
{?eh,cth,{'_',on_tc_fail,
- [init_per_suite,{failed,"Test failure"},[]]}},
+ [ct_cth_empty_SUITE,init_per_suite,"Test failure",[]]}},
+
-
{?eh,tc_auto_skip,{ct_cth_empty_SUITE,test_case,
{failed,{ct_cth_empty_SUITE,init_per_suite,
{failed,"Test failure"}}}}},
{?eh,cth,{'_',on_tc_skip,
- [test_case, {tc_auto_skip,
+ [ct_cth_empty_SUITE,test_case, {tc_auto_skip,
{failed, {ct_cth_empty_SUITE, init_per_suite,
{failed, "Test failure"}}}},[]]}},
-
+
{?eh,tc_auto_skip, {ct_cth_empty_SUITE, end_per_suite,
{failed, {ct_cth_empty_SUITE, init_per_suite,
{failed, "Test failure"}}}}},
{?eh,cth,{'_',on_tc_skip,
- [end_per_suite, {tc_auto_skip,
+ [ct_cth_empty_SUITE,end_per_suite, {tc_auto_skip,
{failed, {ct_cth_empty_SUITE, init_per_suite,
{failed, "Test failure"}}}},[]]}},
-
+
{?eh,test_done,{'DEF','STOP_TIME'}},
{?eh,cth, {'_',terminate,[[]]}},
{?eh,stop_logging,[]}
@@ -727,17 +773,17 @@ test_events(fail_post_suite_cth) ->
{?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
{?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,
{failed,{error,"Test failure"}}}},
- {?eh,cth,{'_',on_tc_fail,[init_per_suite, {failed,"Test failure"}, []]}},
+ {?eh,cth,{'_',on_tc_fail,[ct_cth_empty_SUITE,init_per_suite, "Test failure", []]}},
{?eh,tc_auto_skip,{ct_cth_empty_SUITE,test_case,
{failed,{ct_cth_empty_SUITE,init_per_suite,
{failed,"Test failure"}}}}},
- {?eh,cth,{'_',on_tc_skip,[test_case,{tc_auto_skip,'_'},[]]}},
-
+ {?eh,cth,{'_',on_tc_skip,[ct_cth_empty_SUITE,test_case,{tc_auto_skip,'_'},[]]}},
+
{?eh,tc_auto_skip, {ct_cth_empty_SUITE, end_per_suite,
{failed, {ct_cth_empty_SUITE, init_per_suite,
{failed, "Test failure"}}}}},
- {?eh,cth,{'_',on_tc_skip,[end_per_suite,{tc_auto_skip,'_'},[]]}},
+ {?eh,cth,{'_',on_tc_skip,[ct_cth_empty_SUITE,end_per_suite,{tc_auto_skip,'_'},[]]}},
{?eh,test_done,{'DEF','STOP_TIME'}},
{?eh,cth, {'_',terminate,[[]]}},
@@ -754,11 +800,11 @@ test_events(skip_pre_suite_cth) ->
{?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist',{skip,"Test skip"},[]]}},
{?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,{skipped,"Test skip"}}},
{?eh,cth,{'_',on_tc_skip,
- [init_per_suite,{tc_user_skip,{skipped,"Test skip"}},[]]}},
+ [ct_cth_empty_SUITE,init_per_suite,{tc_user_skip,"Test skip"},[]]}},
{?eh,tc_user_skip,{ct_cth_empty_SUITE,test_case,"Test skip"}},
- {?eh,cth,{'_',on_tc_skip,[test_case,{tc_user_skip,"Test skip"},[]]}},
-
+ {?eh,cth,{'_',on_tc_skip,[ct_cth_empty_SUITE,test_case,{tc_user_skip,"Test skip"},[]]}},
+
{?eh,tc_user_skip, {ct_cth_empty_SUITE, end_per_suite,"Test skip"}},
{?eh,test_done,{'DEF','STOP_TIME'}},
@@ -772,31 +818,33 @@ test_events(skip_pre_end_cth) ->
{?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
{?eh,tc_start,{ct_scope_per_group_cth_SUITE,init_per_suite}},
{?eh,tc_done,{ct_scope_per_group_cth_SUITE,init_per_suite,ok}},
-
+
[{?eh,tc_start,{ct_scope_per_group_cth_SUITE,{init_per_group,group1,[]}}},
{?eh,cth,{'_',id,[[]]}},
{?eh,cth,{'_',init,['_',[]]}},
- {?eh,cth,{'_',post_init_per_group,[group1,'$proplist','$proplist',[]]}},
+ {?eh,cth,{'_',post_init_per_group,[ct_scope_per_group_cth_SUITE,group1,'$proplist','$proplist',[]]}},
{?eh,tc_done,{ct_scope_per_group_cth_SUITE,{init_per_group,group1,[]},ok}},
-
+
{?eh,tc_start,{ct_scope_per_group_cth_SUITE,test_case}},
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_scope_per_group_cth_SUITE,test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_scope_per_group_cth_SUITE,test_case,'$proplist',ok,[]]}},
{?eh,tc_done,{ct_scope_per_group_cth_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_scope_per_group_cth_SUITE,{end_per_group,group1,[]}}},
- {?eh,cth,{'_',pre_end_per_group,[group1,'$proplist',[]]}},
- {?eh,cth,{'_',post_end_per_group,[group1,'$proplist','_',[]]}},
+ {?eh,cth,{'_',pre_end_per_group,[ct_scope_per_group_cth_SUITE,group1,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_group,[ct_scope_per_group_cth_SUITE,group1,'$proplist','_',[]]}},
{?eh,tc_done,{ct_scope_per_group_cth_SUITE,{end_per_group,group1,[]},
{skipped,"Test skip"}}}],
- {?eh,cth,{'_',on_tc_skip,[{end_per_group,group1},
- {tc_user_skip,{skipped,"Test skip"}},
+ {?eh,cth,{'_',on_tc_skip,[ct_scope_per_group_cth_SUITE,
+ {end_per_group,group1},
+ {tc_user_skip,"Test skip"},
[]]}},
{?eh,tc_start,{ct_scope_per_group_cth_SUITE,end_per_suite}},
{?eh,tc_done,{ct_scope_per_group_cth_SUITE,end_per_suite,
{skipped,"Test skip"}}},
- {?eh,cth,{'_',on_tc_skip,[end_per_suite,
- {tc_user_skip,{skipped,"Test skip"}},
+ {?eh,cth,{'_',on_tc_skip,[ct_scope_per_group_cth_SUITE,
+ end_per_suite,
+ {tc_user_skip,"Test skip"},
[]]}},
{?eh,test_done,{'DEF','STOP_TIME'}},
{?eh,cth,{'_',terminate,[[]]}},
@@ -808,24 +856,59 @@ test_events(skip_post_suite_cth) ->
{?eh,start_logging,{'DEF','RUNDIR'}},
{?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
{?eh,cth,{'_',init,['_',[]]}},
-
+
{?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
{?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
{?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
{?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,{skipped,"Test skip"}}},
{?eh,cth,{'_',on_tc_skip,
- [init_per_suite,{tc_user_skip,{skipped,"Test skip"}},[]]}},
+ [ct_cth_empty_SUITE,init_per_suite,{tc_user_skip,"Test skip"},[]]}},
{?eh,tc_user_skip,{ct_cth_empty_SUITE,test_case,"Test skip"}},
- {?eh,cth,{'_',on_tc_skip,[test_case,{tc_user_skip,"Test skip"},[]]}},
-
+ {?eh,cth,{'_',on_tc_skip,[ct_cth_empty_SUITE,test_case,{tc_user_skip,"Test skip"},[]]}},
+
{?eh,tc_user_skip, {ct_cth_empty_SUITE, end_per_suite,"Test skip"}},
-
+
{?eh,test_done,{'DEF','STOP_TIME'}},
{?eh,cth,{'_',terminate,[[]]}},
{?eh,stop_logging,[]}
];
+test_events(skip_pre_init_tc_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,cth,{empty_cth,init,['_',[]]}},
+ {?eh,start_info,{1,1,1}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,
+ [ct_cth_empty_SUITE,test_case,'$proplist',
+ {skip,"Skipped in pre_init_per_testcase"},
+ []]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,test_case,
+ {skipped,"Skipped in pre_init_per_testcase"}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [ct_cth_empty_SUITE,test_case,
+ {tc_user_skip,"Skipped in pre_init_per_testcase"},
+ []]}},
+ {?eh,test_stats,{0,0,{1,0}}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
+ {?eh,cth,{empty_cth,pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_suite,
+ [ct_cth_empty_SUITE,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{empty_cth,terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
test_events(recover_post_suite_cth) ->
Suite = ct_cth_fail_per_suite_SUITE,
[
@@ -840,11 +923,11 @@ test_events(recover_post_suite_cth) ->
{?eh,tc_start,{Suite,test_case}},
{?eh,cth,{'_',pre_init_per_testcase,
- [test_case, not_contains([tc_status]),[]]}},
+ [Suite,test_case, not_contains([tc_status]),[]]}},
{?eh,cth,{'_',post_end_per_testcase,
- [test_case, contains([tc_status]),'_',[]]}},
+ [Suite,test_case, contains([tc_status]),'_',[]]}},
{?eh,tc_done,{Suite,test_case,ok}},
-
+
{?eh,tc_start,{Suite,end_per_suite}},
{?eh,cth,{'_',pre_end_per_suite,
[Suite,not_contains([tc_status]),[]]}},
@@ -861,7 +944,7 @@ test_events(update_config_cth) ->
{?eh,start_logging,{'DEF','RUNDIR'}},
{?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
{?eh,cth,{'_',init,['_',[]]}},
-
+
{?eh,tc_start,{ct_update_config_SUITE,init_per_suite}},
{?eh,cth,{'_',pre_init_per_suite,
[ct_update_config_SUITE,contains([]),[]]}},
@@ -876,13 +959,15 @@ test_events(update_config_cth) ->
{?eh,tc_start,{ct_update_config_SUITE, {init_per_group,group1,[]}}},
{?eh,cth,{'_',pre_init_per_group,
- [group1,contains(
+ [ct_update_config_SUITE,
+ group1,contains(
[post_init_per_suite,
init_per_suite,
pre_init_per_suite]),
[]]}},
{?eh,cth,{'_',post_init_per_group,
- [group1,
+ [ct_update_config_SUITE,
+ group1,
contains(
[post_init_per_suite,
init_per_suite,
@@ -898,7 +983,8 @@ test_events(update_config_cth) ->
{?eh,tc_start,{ct_update_config_SUITE,test_case}},
{?eh,cth,{'_',pre_init_per_testcase,
- [test_case,contains(
+ [ct_update_config_SUITE,
+ test_case,contains(
[post_init_per_group,
init_per_group,
pre_init_per_group,
@@ -907,7 +993,8 @@ test_events(update_config_cth) ->
pre_init_per_suite]),
[]]}},
{?eh,cth,{'_',post_end_per_testcase,
- [test_case,contains(
+ [ct_update_config_SUITE,
+ test_case,contains(
[init_per_testcase,
pre_init_per_testcase,
post_init_per_group,
@@ -921,7 +1008,8 @@ test_events(update_config_cth) ->
{?eh,tc_start,{ct_update_config_SUITE, {end_per_group,group1,[]}}},
{?eh,cth,{'_',pre_end_per_group,
- [group1,contains(
+ [ct_update_config_SUITE,
+ group1,contains(
[post_init_per_group,
init_per_group,
pre_init_per_group,
@@ -930,7 +1018,8 @@ test_events(update_config_cth) ->
pre_init_per_suite]),
[]]}},
{?eh,cth,{'_',post_end_per_group,
- [group1,
+ [ct_update_config_SUITE,
+ group1,
contains(
[pre_end_per_group,
post_init_per_group,
@@ -941,7 +1030,7 @@ test_events(update_config_cth) ->
pre_init_per_suite]),
ok,[]]}},
{?eh,tc_done,{ct_update_config_SUITE,{end_per_group,group1,[]},ok}},
-
+
{?eh,tc_start,{ct_update_config_SUITE,end_per_suite}},
{?eh,cth,{'_',pre_end_per_suite,
[ct_update_config_SUITE,contains(
@@ -974,7 +1063,7 @@ test_events(state_update_cth) ->
{?eh,cth,{'_',init,['_',[]]}},
{?eh,cth,{'_',init,['_',[]]}},
{?eh,tc_start,{'_',init_per_suite}},
-
+
{?eh,tc_done,{'_',end_per_suite,ok}},
{?eh,test_done,{'DEF','STOP_TIME'}},
{?eh,cth,{'_',terminate,[contains(
@@ -1018,10 +1107,10 @@ test_events(options_cth) ->
{?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
{?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
- {?eh,cth,{empty_cth,pre_init_per_testcase,[test_case,'$proplist',[test]]}},
- {?eh,cth,{empty_cth,post_end_per_testcase,[test_case,'$proplist','_',[test]]}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[test]]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist','_',[test]]}},
{?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},
-
+
{?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
{?eh,cth,{empty_cth,pre_end_per_suite,
[ct_cth_empty_SUITE,'$proplist',[test]]}},
@@ -1051,14 +1140,14 @@ test_events(same_id_cth) ->
{?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}}},
{?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
{negative,
- {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}}},
+ {?eh,cth,{'_',pre_init_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',ok,[]]}}},
{negative,
- {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[ct_cth_empty_SUITE,test_case,'$proplist',ok,[]]}},
{?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}}},
-
+
{?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
{?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
{negative,
@@ -1094,11 +1183,13 @@ test_events(fail_n_skip_with_minimal_cth) ->
{?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,test_case2,{skipped,"skip it"}}},
{?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,test_case3}},
{?eh,tc_done,{ct_cth_fail_one_skip_one_SUITE,test_case3,{skipped,"skip it"}}},
- {?eh,cth,{empty_cth,on_tc_skip,[{test_case2,group2},
- {tc_user_skip,{skipped,"skip it"}},
+ {?eh,cth,{empty_cth,on_tc_skip,[ct_cth_fail_one_skip_one_SUITE,
+ {test_case2,group2},
+ {tc_user_skip,"skip it"},
[]]}},
- {?eh,cth,{empty_cth,on_tc_skip,[{test_case3,group2},
- {tc_user_skip,{skipped,"skip it"}},
+ {?eh,cth,{empty_cth,on_tc_skip,[ct_cth_fail_one_skip_one_SUITE,
+ {test_case3,group2},
+ {tc_user_skip,"skip it"},
[]]}},
{?eh,tc_start,{ct_cth_fail_one_skip_one_SUITE,{end_per_group,
group2,[parallel]}}},
@@ -1115,17 +1206,25 @@ test_events(fail_n_skip_with_minimal_cth) ->
];
test_events(prio_cth) ->
-
- GenPre = fun(Func,States) ->
- [{?eh,cth,{'_',Func,['_','_',State]}} ||
+ GenPre = fun(Func,States) when Func==pre_init_per_suite;
+ Func==pre_end_per_suite ->
+ [{?eh,cth,{'_',Func,['_','_',State]}} ||
+ State <- States];
+ (Func,States) ->
+ [{?eh,cth,{'_',Func,['_','_','_',State]}} ||
State <- States]
end,
- GenPost = fun(Func,States) ->
- [{?eh,cth,{'_',Func,['_','_','_',State]}} ||
+ GenPost = fun(Func,States) when Func==post_init_per_suite;
+ Func==post_end_per_suite ->
+ [{?eh,cth,{'_',Func,['_','_','_',State]}} ||
+ State <- States];
+ (Func,States) ->
+ [{?eh,cth,{'_',Func,['_','_','_','_',State]}} ||
State <- States]
- end,
-
+
+ end,
+
[{?eh,start_logging,{'DEF','RUNDIR'}},
{?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}}] ++
@@ -1136,7 +1235,7 @@ test_events(prio_cth) ->
[[1100,100],[600,200],[600,600],[700],[800],[900],[1000],
[1200,1050],[1100],[1200]]) ++
[{?eh,tc_done,{ct_cth_prio_SUITE,init_per_suite,ok}},
-
+
[{?eh,tc_start,{ct_cth_prio_SUITE,{init_per_group,'_',[]}}}] ++
GenPre(pre_init_per_group,
@@ -1147,7 +1246,7 @@ test_events(prio_cth) ->
[900],[900,900],[500,900],[1000],[1200,1050],
[1100],[1200]]) ++
[{?eh,tc_done,{ct_cth_prio_SUITE,{init_per_group,'_',[]},ok}}] ++
-
+
[{?eh,tc_start,{ct_cth_prio_SUITE,test_case}}] ++
GenPre(pre_init_per_testcase,
[[1100,100],[600,200],[600,600],[600],[700],[800],
@@ -1161,7 +1260,7 @@ test_events(prio_cth) ->
[{?eh,tc_done,{ct_cth_prio_SUITE,test_case,ok}},
{?eh,tc_start,{ct_cth_prio_SUITE,{end_per_group,'_',[]}}}] ++
- GenPre(pre_end_per_group,
+ GenPre(pre_end_per_group,
lists:reverse(
[[1100,100],[600,200],[600,600],[600],[700],[800],
[900],[900,900],[500,900],[1000],[1200,1050],
@@ -1200,30 +1299,30 @@ test_events(no_config) ->
{?eh,tc_done,{ct_framework,init_per_suite,ok}},
{?eh,tc_start,{ct_no_config_SUITE,test_case_1}},
{?eh,cth,{empty_cth,pre_init_per_testcase,
- [test_case_1,'$proplist',[]]}},
+ [ct_no_config_SUITE,test_case_1,'$proplist',[]]}},
{?eh,cth,{empty_cth,post_end_per_testcase,
- [test_case_1,'$proplist',ok,[]]}},
+ [ct_no_config_SUITE,test_case_1,'$proplist',ok,[]]}},
{?eh,tc_done,{ct_no_config_SUITE,test_case_1,ok}},
{?eh,test_stats,{1,0,{0,0}}},
[{?eh,tc_start,{ct_framework,{init_per_group,test_group,'$proplist'}}},
{?eh,cth,{empty_cth,pre_init_per_group,
- [test_group,'$proplist',[]]}},
+ [ct_no_config_SUITE,test_group,'$proplist',[]]}},
{?eh,cth,{empty_cth,post_init_per_group,
- [test_group,'$proplist','$proplist',[]]}},
+ [ct_no_config_SUITE,test_group,'$proplist','$proplist',[]]}},
{?eh,tc_done,{ct_framework,
{init_per_group,test_group,'$proplist'},ok}},
{?eh,tc_start,{ct_no_config_SUITE,test_case_2}},
{?eh,cth,{empty_cth,pre_init_per_testcase,
- [test_case_2,'$proplist',[]]}},
+ [ct_no_config_SUITE,test_case_2,'$proplist',[]]}},
{?eh,cth,{empty_cth,post_end_per_testcase,
- [test_case_2,'$proplist',ok,[]]}},
+ [ct_no_config_SUITE,test_case_2,'$proplist',ok,[]]}},
{?eh,tc_done,{ct_no_config_SUITE,test_case_2,ok}},
{?eh,test_stats,{2,0,{0,0}}},
{?eh,tc_start,{ct_framework,{end_per_group,test_group,'$proplist'}}},
{?eh,cth,{empty_cth,pre_end_per_group,
- [test_group,'$proplist',[]]}},
+ [ct_no_config_SUITE,test_group,'$proplist',[]]}},
{?eh,cth,{empty_cth,post_end_per_group,
- [test_group,'$proplist',ok,[]]}},
+ [ct_no_config_SUITE,test_group,'$proplist',ok,[]]}},
{?eh,tc_done,{ct_framework,{end_per_group,test_group,'$proplist'},ok}}],
{?eh,tc_start,{ct_framework,end_per_suite}},
{?eh,cth,{empty_cth,pre_end_per_suite,
@@ -1236,6 +1335,166 @@ test_events(no_config) ->
{?eh,stop_logging,[]}
];
+test_events(no_init_suite_config) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
+ {?eh,start_info,{1,1,1}},
+ {?eh,tc_start,{ct_no_init_suite_config_SUITE,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,
+ [ct_no_init_suite_config_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [ct_no_init_suite_config_SUITE,'$proplist','_',[]]}},
+ {?eh,tc_done,{ct_no_init_suite_config_SUITE,init_per_suite,
+ {failed,{error,{undef,'_'}}}}},
+ {?eh,cth,{empty_cth,on_tc_fail,[ct_no_init_suite_config_SUITE,
+ init_per_suite,
+ {undef,'_'},[]]}},
+ {?eh,tc_auto_skip,{ct_no_init_suite_config_SUITE,test_case,
+ {failed,{ct_no_init_suite_config_SUITE,init_per_suite,
+ {'EXIT',{undef,'_'}}}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [ct_no_init_suite_config_SUITE,
+ test_case,
+ {tc_auto_skip,
+ {failed,{ct_no_init_suite_config_SUITE,init_per_suite,
+ {'EXIT',{undef,'_'}}}}},
+ []]}},
+ {?eh,test_stats,{0,0,{0,1}}},
+ {?eh,tc_auto_skip,{ct_no_init_suite_config_SUITE,end_per_suite,
+ {failed,{ct_no_init_suite_config_SUITE,init_per_suite,
+ {'EXIT',{undef,'_'}}}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [ct_no_init_suite_config_SUITE,
+ end_per_suite,
+ {tc_auto_skip,
+ {failed,{ct_no_init_suite_config_SUITE,init_per_suite,
+ {'EXIT',{undef,'_'}}}}},
+ []]}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{empty_cth,terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(no_init_config) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
+ {?eh,start_info,{1,1,2}},
+ {?eh,tc_start,{ct_no_init_config_SUITE,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,
+ [ct_no_init_config_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [ct_no_init_config_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_no_init_config_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{ct_no_init_config_SUITE,test_case_1}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [ct_no_init_config_SUITE,test_case_1,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,
+ [ct_no_init_config_SUITE,test_case_1,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_no_init_config_SUITE,test_case_1,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ [{?eh,tc_start,{ct_no_init_config_SUITE,{init_per_group,test_group,[]}}},
+ {?eh,cth,{empty_cth,pre_init_per_group,
+ [ct_no_init_config_SUITE,test_group,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_group,
+ [ct_no_init_config_SUITE,test_group,'$proplist','_',[]]}},
+ {?eh,tc_done,{ct_no_init_config_SUITE,{init_per_group,test_group,[]},
+ {failed,{error,{undef,'_'}}}}},
+ {?eh,cth,{empty_cth,on_tc_fail,[ct_no_init_config_SUITE,
+ {init_per_group,test_group},
+ {undef,'_'},[]]}},
+ {?eh,tc_auto_skip,{ct_no_init_config_SUITE,{test_case_2,test_group},
+ {failed,{ct_no_init_config_SUITE,init_per_group,
+ {'EXIT',{undef,'_'}}}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,[ct_no_init_config_SUITE,
+ {test_case_2,test_group},
+ {tc_auto_skip,
+ {failed,
+ {ct_no_init_config_SUITE,init_per_group,
+ {'EXIT',{undef,'_'}}}}},
+ []]}},
+ {?eh,test_stats,{1,0,{0,1}}},
+ {?eh,tc_auto_skip,{ct_no_init_config_SUITE,{end_per_group,test_group},
+ {failed,{ct_no_init_config_SUITE,init_per_group,
+ {'EXIT',{undef,'_'}}}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,[ct_no_init_config_SUITE,
+ {end_per_group,test_group},
+ {tc_auto_skip,
+ {failed,
+ {ct_no_init_config_SUITE,init_per_group,
+ {'EXIT',{undef,'_'}}}}},
+ []]}}],
+ {?eh,tc_start,{ct_no_init_config_SUITE,end_per_suite}},
+ {?eh,cth,{empty_cth,pre_end_per_suite,
+ [ct_no_init_config_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_suite,
+ [ct_no_init_config_SUITE,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_no_init_config_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{empty_cth,terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(no_end_config) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
+ {?eh,start_info,{1,1,2}},
+ {?eh,tc_start,{ct_no_end_config_SUITE,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,
+ [ct_no_end_config_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [ct_no_end_config_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_no_end_config_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{ct_no_end_config_SUITE,test_case_1}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [ct_no_end_config_SUITE,test_case_1,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,
+ [ct_no_end_config_SUITE,test_case_1,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_no_end_config_SUITE,test_case_1,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ [{?eh,tc_start,{ct_no_end_config_SUITE,
+ {init_per_group,test_group,'$proplist'}}},
+ {?eh,cth,{empty_cth,pre_init_per_group,
+ [ct_no_end_config_SUITE,test_group,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_group,
+ [ct_no_end_config_SUITE,test_group,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_no_end_config_SUITE,
+ {init_per_group,test_group,'$proplist'},ok}},
+ {?eh,tc_start,{ct_no_end_config_SUITE,test_case_2}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [ct_no_end_config_SUITE,test_case_2,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,
+ [ct_no_end_config_SUITE,test_case_2,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_no_end_config_SUITE,test_case_2,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{ct_no_end_config_SUITE,
+ {end_per_group,test_group,'$proplist'}}},
+ {?eh,cth,{empty_cth,pre_end_per_group,
+ [ct_no_end_config_SUITE,test_group,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_group,
+ [ct_no_end_config_SUITE,test_group,'$proplist','_',[]]}},
+ {?eh,tc_done,{ct_no_end_config_SUITE,{end_per_group,test_group,[]},
+ {failed,{error,{undef,'_'}}}}},
+ {?eh,cth,{empty_cth,on_tc_fail,[ct_no_end_config_SUITE,
+ {end_per_group,test_group},
+ {undef,'_'},[]]}}],
+ {?eh,tc_start,{ct_no_end_config_SUITE,end_per_suite}},
+ {?eh,cth,{empty_cth,pre_end_per_suite,
+ [ct_no_end_config_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_suite,
+ [ct_no_end_config_SUITE,'$proplist','_',[]]}},
+ {?eh,tc_done,{ct_no_end_config_SUITE,end_per_suite,
+ {failed,{error,{undef,'_'}}}}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{empty_cth,terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
test_events(data_dir) ->
[
{?eh,start_logging,{'DEF','RUNDIR'}},
@@ -1250,30 +1509,30 @@ test_events(data_dir) ->
{?eh,tc_done,{ct_framework,init_per_suite,ok}},
{?eh,tc_start,{ct_data_dir_SUITE,test_case_1}},
{?eh,cth,{empty_cth,pre_init_per_testcase,
- [test_case_1,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
+ [ct_data_dir_SUITE,test_case_1,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
{?eh,cth,{empty_cth,post_end_per_testcase,
- [test_case_1,'$proplist',ok,[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
+ [ct_data_dir_SUITE,test_case_1,'$proplist',ok,[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
{?eh,tc_done,{ct_data_dir_SUITE,test_case_1,ok}},
{?eh,test_stats,{1,0,{0,0}}},
[{?eh,tc_start,{ct_framework,{init_per_group,test_group,'$proplist'}}},
{?eh,cth,{empty_cth,pre_init_per_group,
- [test_group,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
+ [ct_data_dir_SUITE,test_group,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
{?eh,cth,{empty_cth,post_init_per_group,
- [test_group,'$proplist','$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
+ [ct_data_dir_SUITE,test_group,'$proplist','$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
{?eh,tc_done,{ct_framework,
{init_per_group,test_group,'$proplist'},ok}},
{?eh,tc_start,{ct_data_dir_SUITE,test_case_2}},
{?eh,cth,{empty_cth,pre_init_per_testcase,
- [test_case_2,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
+ [ct_data_dir_SUITE,test_case_2,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
{?eh,cth,{empty_cth,post_end_per_testcase,
- [test_case_2,'$proplist',ok,[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
+ [ct_data_dir_SUITE,test_case_2,'$proplist',ok,[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
{?eh,tc_done,{ct_data_dir_SUITE,test_case_2,ok}},
{?eh,test_stats,{2,0,{0,0}}},
{?eh,tc_start,{ct_framework,{end_per_group,test_group,'$proplist'}}},
{?eh,cth,{empty_cth,pre_end_per_group,
- [test_group,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
+ [ct_data_dir_SUITE,test_group,'$proplist',[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
{?eh,cth,{empty_cth,post_end_per_group,
- [test_group,'$proplist',ok,[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
+ [ct_data_dir_SUITE,test_group,'$proplist',ok,[{data_dir_name,"ct_data_dir_SUITE_data"}]]}},
{?eh,tc_done,{ct_framework,{end_per_group,test_group,'$proplist'},ok}}],
{?eh,tc_start,{ct_framework,end_per_suite}},
{?eh,cth,{empty_cth,pre_end_per_suite,
@@ -1300,16 +1559,654 @@ test_events(cth_log) ->
[{suite,cth_log_SUITE},parallel]}}},
{?eh,tc_done,{ct_framework,{end_per_group,g1,
[{suite,cth_log_SUITE},parallel]},ok}}]},
-
+
{?eh,tc_done,{cth_log_SUITE,end_per_suite,ok}},
{?eh,test_done,{'DEF','STOP_TIME'}},
{?eh,stop_logging,[]}
];
+test_events(fallback) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,cth,{empty_cth,id,[[]]}},
+ {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
+ {?eh,tc_start,{all_hook_callbacks_SUITE,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,
+ [all_hook_callbacks_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [all_hook_callbacks_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{all_hook_callbacks_SUITE,init_per_suite,ok}},
+
+ [{?eh,tc_start,{ct_framework,{init_per_group,test_group,'$proplist'}}},
+ {?eh,cth,{empty_cth,pre_init_per_group,
+ [fallback_nosuite,test_group,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_group,
+ [fallback_nosuite,test_group,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_framework,
+ {init_per_group,test_group,'$proplist'},ok}},
+ {?eh,tc_start,{all_hook_callbacks_SUITE,test_case}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [fallback_nosuite,test_case,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,
+ [fallback_nosuite,test_case,'$proplist',ok,[]]}},
+ {?eh,tc_done,{all_hook_callbacks_SUITE,test_case,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{ct_framework,{end_per_group,test_group,'$proplist'}}},
+ {?eh,cth,{empty_cth,pre_end_per_group,
+ [fallback_nosuite,test_group,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_group,
+ [fallback_nosuite,test_group,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_framework,{end_per_group,test_group,'$proplist'},ok}}],
+ {?eh,tc_start,{all_hook_callbacks_SUITE,test_case}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [fallback_nosuite,test_case,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,
+ [fallback_nosuite,test_case,'$proplist','_',[]]}},
+ {?eh,cth,{empty_cth,pre_end_per_testcase,
+ [fallback_nosuite,test_case,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,
+ [fallback_nosuite,test_case,'$proplist','_',[]]}},
+ {?eh,tc_done,{all_hook_callbacks_SUITE,test_case,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{all_hook_callbacks_SUITE,skip_case}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [fallback_nosuite,skip_case,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,
+ [fallback_nosuite,skip_case,'$proplist',
+ {skip,"Skipped in init_per_testcase/2"},[]]}},
+ {?eh,tc_done,{all_hook_callbacks_SUITE,skip_case,
+ {skipped,"Skipped in init_per_testcase/2"}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [fallback_nosuite,skip_case,
+ {tc_user_skip,"Skipped in init_per_testcase/2"},
+ []]}},
+ {?eh,test_stats,{2,0,{1,0}}},
+ {?eh,tc_start,{all_hook_callbacks_SUITE,end_per_suite}},
+ {?eh,cth,{empty_cth,pre_end_per_suite,
+ [all_hook_callbacks_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_suite,
+ [all_hook_callbacks_SUITE,'$proplist','_',[]]}},
+ {?eh,tc_done,{all_hook_callbacks_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{empty_cth,terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(callbacks_on_skip) ->
+ %% skip_cth.erl will send a 'cth_error' event if a hook is
+ %% erroneously called. Therefore, all Events are changed to
+ %% {negative,{?eh,cth_error,'_'},Event}
+ %% at the end of this function.
+ Events =
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,cth,{empty_cth,id,[[]]}},
+ {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
+ {?eh,start_info,{6,6,15}},
+
+ %% all_hook_callbacks_SUITE is skipped in spec
+ %% Only the on_tc_skip callback shall be called
+ {?eh,tc_user_skip,{all_hook_callbacks_SUITE,all,"Skipped in spec"}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [all_hook_callbacks_SUITE,all,
+ {tc_user_skip,"Skipped in spec"},
+ []]}},
+ {?eh,test_stats,{0,0,{1,0}}},
+
+ %% skip_init_SUITE is skipped in its init_per_suite function
+ %% No group- or testcase-functions shall be called.
+ {?eh,tc_start,{skip_init_SUITE,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,
+ [skip_init_SUITE,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [skip_init_SUITE,
+ '$proplist',
+ {skip,"Skipped in init_per_suite/1"},
+ []]}},
+ {?eh,tc_done,{skip_init_SUITE,init_per_suite,
+ {skipped,"Skipped in init_per_suite/1"}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_init_SUITE,init_per_suite,
+ {tc_user_skip,"Skipped in init_per_suite/1"},
+ []]}},
+ {?eh,tc_user_skip,{skip_init_SUITE,test_case,"Skipped in init_per_suite/1"}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_init_SUITE,test_case,
+ {tc_user_skip,"Skipped in init_per_suite/1"},
+ []]}},
+ {?eh,test_stats,{0,0,{2,0}}},
+ {?eh,tc_user_skip,{skip_init_SUITE,end_per_suite,
+ "Skipped in init_per_suite/1"}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_init_SUITE,end_per_suite,
+ {tc_user_skip,"Skipped in init_per_suite/1"},
+ []]}},
+
+ %% skip_req_SUITE is auto-skipped since a 'require' statement
+ %% returned by suite/0 is not fulfilled.
+ %% No group- or testcase-functions shall be called.
+ {?eh,tc_start,{skip_req_SUITE,init_per_suite}},
+ {?eh,tc_done,{skip_req_SUITE,init_per_suite,
+ {auto_skipped,{require_failed_in_suite0,
+ {not_available,whatever}}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_req_SUITE,init_per_suite,
+ {tc_auto_skip,{require_failed_in_suite0,
+ {not_available,whatever}}},
+ []]}},
+ {?eh,tc_auto_skip,{skip_req_SUITE,test_case,{require_failed_in_suite0,
+ {not_available,whatever}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_req_SUITE,test_case,
+ {tc_auto_skip,{require_failed_in_suite0,
+ {not_available,whatever}}},
+ []]}},
+ {?eh,test_stats,{0,0,{2,1}}},
+ {?eh,tc_auto_skip,{skip_req_SUITE,end_per_suite,
+ {require_failed_in_suite0,
+ {not_available,whatever}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_req_SUITE,end_per_suite,
+ {tc_auto_skip,{require_failed_in_suite0,
+ {not_available,whatever}}},
+ []]}},
+
+ %% skip_fail_SUITE is auto-skipped since the suite/0 function
+ %% retuns a faluty format.
+ %% No group- or testcase-functions shall be called.
+ {?eh,tc_start,{skip_fail_SUITE,init_per_suite}},
+ {?eh,tc_done,{skip_fail_SUITE,init_per_suite,
+ {failed,{error,{suite0_failed,bad_return_value}}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_fail_SUITE,init_per_suite,
+ {tc_auto_skip,
+ {failed,{error,{suite0_failed,bad_return_value}}}},
+ []]}},
+ {?eh,tc_auto_skip,{skip_fail_SUITE,test_case,
+ {failed,{error,{suite0_failed,bad_return_value}}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_fail_SUITE,test_case,
+ {tc_auto_skip,
+ {failed,{error,{suite0_failed,bad_return_value}}}},
+ []]}},
+ {?eh,test_stats,{0,0,{2,2}}},
+ {?eh,tc_auto_skip,{skip_fail_SUITE,end_per_suite,
+ {failed,{error,{suite0_failed,bad_return_value}}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_fail_SUITE,end_per_suite,
+ {tc_auto_skip,
+ {failed,{error,{suite0_failed,bad_return_value}}}},
+ []]}},
+
+ %% skip_group_SUITE
+ {?eh,tc_start,{skip_group_SUITE,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,
+ [skip_group_SUITE,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [skip_group_SUITE,
+ '$proplist',
+ '_',
+ []]}},
+ {?eh,tc_done,{skip_group_SUITE,init_per_suite,ok}},
+
+ %% test_group_1 - auto_skip due to require failed
+ [{?eh,tc_start,{skip_group_SUITE,{init_per_group,test_group_1,[]}}},
+ {?eh,tc_done,
+ {skip_group_SUITE,{init_per_group,test_group_1,[]},
+ {auto_skipped,{require_failed,{not_available,whatever}}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_group_SUITE,
+ {init_per_group,test_group_1},
+ {tc_auto_skip,{require_failed,{not_available,whatever}}},
+ []]}},
+ {?eh,tc_auto_skip,{skip_group_SUITE,{test_case,test_group_1},
+ {require_failed,{not_available,whatever}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_group_SUITE,
+ {test_case,test_group_1},
+ {tc_auto_skip,{require_failed,{not_available,whatever}}},
+ []]}},
+ {?eh,test_stats,{0,0,{2,3}}},
+ {?eh,tc_auto_skip,{skip_group_SUITE,{end_per_group,test_group_1},
+ {require_failed,{not_available,whatever}}}}],
+ %% The following appears to be outside of the group, but
+ %% that's only an implementation detail in
+ %% ct_test_support.erl - it does not know about events from
+ %% test suite specific hooks and regards the group ended with
+ %% the above tc_auto_skip-event for end_per_group.
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_group_SUITE,
+ {end_per_group,test_group_1},
+ {tc_auto_skip,{require_failed,{not_available,whatever}}},
+ []]}},
+
+ %% test_group_2 - auto_skip due to failed return from group/1
+ [{?eh,tc_start,{skip_group_SUITE,{init_per_group,test_group_2,[]}}},
+ {?eh,tc_done,
+ {skip_group_SUITE,{init_per_group,test_group_2,[]},
+ {auto_skipped,{group0_failed,bad_return_value}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_group_SUITE,
+ {init_per_group,test_group_2},
+ {tc_auto_skip,{group0_failed,bad_return_value}},
+ []]}},
+ {?eh,tc_auto_skip,{skip_group_SUITE,{test_case,test_group_2},
+ {group0_failed,bad_return_value}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_group_SUITE,
+ {test_case,test_group_2},
+ {tc_auto_skip,{group0_failed,bad_return_value}},
+ []]}},
+ {?eh,test_stats,{0,0,{2,4}}},
+ {?eh,tc_auto_skip,{skip_group_SUITE,{end_per_group,test_group_2},
+ {group0_failed,bad_return_value}}}],
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_group_SUITE,
+ {end_per_group,test_group_2},
+ {tc_auto_skip,{group0_failed,bad_return_value}},
+ []]}},
+ %% test_group_3 - user_skip in init_per_group/2
+ [{?eh,tc_start,
+ {skip_group_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,cth,{empty_cth,pre_init_per_group,
+ [skip_group_SUITE,test_group_3,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_group,
+ [skip_group_SUITE,test_group_3,'$proplist',
+ {skip,"Skipped in init_per_group/2"},
+ []]}},
+ {?eh,tc_done,{skip_group_SUITE,
+ {init_per_group,test_group_3,[]},
+ {skipped,"Skipped in init_per_group/2"}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_group_SUITE,
+ {init_per_group,test_group_3},
+ {tc_user_skip,"Skipped in init_per_group/2"},
+ []]}},
+ {?eh,tc_user_skip,{skip_group_SUITE,
+ {test_case,test_group_3},
+ "Skipped in init_per_group/2"}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_group_SUITE,
+ {test_case,test_group_3},
+ {tc_user_skip,"Skipped in init_per_group/2"},
+ []]}},
+ {?eh,test_stats,{0,0,{3,4}}},
+ {?eh,tc_user_skip,{skip_group_SUITE,
+ {end_per_group,test_group_3},
+ "Skipped in init_per_group/2"}}],
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_group_SUITE,
+ {end_per_group,test_group_3},
+ {tc_user_skip,"Skipped in init_per_group/2"},
+ []]}},
+
+ {?eh,tc_start,{skip_group_SUITE,end_per_suite}},
+ {?eh,cth,{empty_cth,pre_end_per_suite,
+ [skip_group_SUITE,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_end_per_suite,
+ [skip_group_SUITE,
+ '$proplist',
+ ok,[]]}},
+ {?eh,tc_done,{skip_group_SUITE,end_per_suite,ok}},
+
+
+ %% skip_case_SUITE has 4 test cases which are all skipped in
+ %% different ways
+ {?eh,tc_start,{skip_case_SUITE,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,
+ [skip_case_SUITE,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [skip_case_SUITE,
+ '$proplist',
+ '_',
+ []]}},
+ {?eh,tc_done,{skip_case_SUITE,init_per_suite,ok}},
+
+ %% Skip in spec -> only on_tc_skip shall be called
+ {?eh,tc_user_skip,{skip_case_SUITE,skip_in_spec,"Skipped in spec"}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_case_SUITE,skip_in_spec,
+ {tc_user_skip,"Skipped in spec"},
+ []]}},
+ {?eh,test_stats,{0,0,{4,4}}},
+
+ %% Skip in init_per_testcase -> pre/post_end_per_testcase
+ %% shall not be called
+ {?eh,tc_start,{skip_case_SUITE,skip_in_init}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [skip_case_SUITE,skip_in_init,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,
+ [skip_case_SUITE,skip_in_init,
+ '$proplist',
+ {skip,"Skipped in init_per_testcase/2"},
+ []]}},
+ {?eh,tc_done,{skip_case_SUITE,skip_in_init,
+ {skipped,"Skipped in init_per_testcase/2"}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_case_SUITE,skip_in_init,
+ {tc_user_skip,"Skipped in init_per_testcase/2"},
+ []]}},
+ {?eh,test_stats,{0,0,{5,4}}},
+
+ %% Fail in init_per_testcase -> pre/post_end_per_testcase
+ %% shall not be called
+ {?eh,tc_start,{skip_case_SUITE,fail_in_init}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [skip_case_SUITE,fail_in_init,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,
+ [skip_case_SUITE,fail_in_init,
+ '$proplist',
+ {skip,{failed,'_'}},
+ []]}},
+ {?eh,tc_done,{skip_case_SUITE,fail_in_init,
+ {auto_skipped,{failed,'_'}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_case_SUITE,fail_in_init,
+ {tc_auto_skip,{failed,'_'}},
+ []]}},
+ {?eh,test_stats,{0,0,{5,5}}},
+
+ %% Exit in init_per_testcase -> pre/post_end_per_testcase
+ %% shall not be called
+ {?eh,tc_start,{skip_case_SUITE,exit_in_init}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [skip_case_SUITE,exit_in_init,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,
+ [skip_case_SUITE,exit_in_init,
+ '$proplist',
+ {skip,{failed,'_'}},
+ []]}},
+ {?eh,tc_done,{skip_case_SUITE,exit_in_init,
+ {auto_skipped,{failed,'_'}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_case_SUITE,exit_in_init,
+ {tc_auto_skip,{failed,'_'}},
+ []]}},
+ {?eh,test_stats,{0,0,{5,6}}},
+
+ %% Fail in end_per_testcase -> all hooks shall be called and
+ %% test shall succeed.
+ {?eh,tc_start,{skip_case_SUITE,fail_in_end}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [skip_case_SUITE,fail_in_end,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,
+ [skip_case_SUITE,fail_in_end,
+ '$proplist',
+ ok,
+ []]}},
+ {?eh,cth,{empty_cth,pre_end_per_testcase,
+ [skip_case_SUITE,fail_in_end,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,
+ [skip_case_SUITE,fail_in_end,
+ '$proplist',
+ {failed,
+ {skip_case_SUITE,end_per_testcase,
+ {'EXIT',
+ {test_case_failed,"Failed in end_per_testcase/2"}}}},
+ []]}},
+ {?eh,tc_done,{skip_case_SUITE,fail_in_end,
+ {failed,
+ {skip_case_SUITE,end_per_testcase,
+ {'EXIT',
+ {test_case_failed,"Failed in end_per_testcase/2"}}}}}},
+ {?eh,test_stats,{1,0,{5,6}}},
+
+ %% Exit in end_per_testcase -> all hooks shall be called and
+ %% test shall succeed.
+ {?eh,tc_start,{skip_case_SUITE,exit_in_end}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [skip_case_SUITE,exit_in_end,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,
+ [skip_case_SUITE,exit_in_end,
+ '$proplist',
+ ok,
+ []]}},
+ {?eh,cth,{empty_cth,pre_end_per_testcase,
+ [skip_case_SUITE,exit_in_end,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,
+ [skip_case_SUITE,exit_in_end,
+ '$proplist',
+ {failed,
+ {skip_case_SUITE,end_per_testcase,
+ {'EXIT',"Exit in end_per_testcase/2"}}},
+ []]}},
+ {?eh,tc_done,{skip_case_SUITE,exit_in_end,
+ {failed,
+ {skip_case_SUITE,end_per_testcase,
+ {'EXIT',"Exit in end_per_testcase/2"}}}}},
+ {?eh,test_stats,{2,0,{5,6}}},
+
+ %% Skip in testcase function -> all callbacks shall be called
+ {?eh,tc_start,{skip_case_SUITE,skip_in_case}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [skip_case_SUITE,skip_in_case,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,
+ [skip_case_SUITE,skip_in_case,
+ '$proplist',
+ ok,[]]}},
+ {?eh,cth,{empty_cth,pre_end_per_testcase,
+ [skip_case_SUITE,skip_in_case,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,
+ [skip_case_SUITE,skip_in_case,
+ '$proplist',
+ {skip,"Skipped in test case function"},
+ []]}},
+ {?eh,tc_done,{skip_case_SUITE,skip_in_case,
+ {skipped,"Skipped in test case function"}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_case_SUITE,skip_in_case,
+ {tc_user_skip,"Skipped in test case function"},
+ []]}},
+ {?eh,test_stats,{2,0,{6,6}}},
+
+ %% Auto skip due to failed 'require' -> only the on_tc_skip
+ %% callback shall be called
+ {?eh,tc_start,{skip_case_SUITE,req_auto_skip}},
+ {?eh,tc_done,{skip_case_SUITE,req_auto_skip,
+ {auto_skipped,{require_failed,{not_available,whatever}}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_case_SUITE,req_auto_skip,
+ {tc_auto_skip,{require_failed,{not_available,whatever}}},
+ []]}},
+ {?eh,test_stats,{2,0,{6,7}}},
+
+ %% Auto skip due to failed testcase/0 function -> only the
+ %% on_tc_skip callback shall be called
+ {?eh,tc_start,{skip_case_SUITE,fail_auto_skip}},
+ {?eh,tc_done,{skip_case_SUITE,fail_auto_skip,
+ {auto_skipped,{testcase0_failed,bad_return_value}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [skip_case_SUITE,fail_auto_skip,
+ {tc_auto_skip,{testcase0_failed,bad_return_value}},
+ []]}},
+ {?eh,test_stats,{2,0,{6,8}}},
+
+ {?eh,tc_start,{skip_case_SUITE,end_per_suite}},
+ {?eh,cth,{empty_cth,pre_end_per_suite,
+ [skip_case_SUITE,
+ '$proplist',
+ []]}},
+ {?eh,cth,{empty_cth,post_end_per_suite,
+ [skip_case_SUITE,
+ '$proplist',
+ ok,[]]}},
+ {?eh,tc_done,{skip_case_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{empty_cth,terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ],
+ %% Make sure no 'cth_error' events are received!
+ [{negative,{?eh,cth_error,'_'},E} || E <- Events];
+
+test_events(failed_sequence) ->
+ %% skip_cth.erl will send a 'cth_error' event if a hook is
+ %% erroneously called. Therefore, all Events are changed to
+ %% {negative,{?eh,cth_error,'_'},Event}
+ %% at the end of this function.
+ Events =
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,cth,{empty_cth,id,[[]]}},
+ {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
+ {?eh,start_info,{1,1,2}},
+ {?eh,tc_start,{ct_framework,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,[seq_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [seq_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_framework,init_per_suite,ok}},
+ {?eh,tc_start,{seq_SUITE,test_case_1}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [seq_SUITE,test_case_1,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,
+ [seq_SUITE,test_case_1,'$proplist',ok,[]]}},
+ {?eh,cth,{empty_cth,pre_end_per_testcase,
+ [seq_SUITE,test_case_1,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,
+ [seq_SUITE,test_case_1,'$proplist',
+ {error,failed_on_purpose},[]]}},
+ {?eh,tc_done,{seq_SUITE,test_case_1,{failed,{error,failed_on_purpose}}}},
+ {?eh,cth,{empty_cth,on_tc_fail,
+ [seq_SUITE,test_case_1,failed_on_purpose,[]]}},
+ {?eh,test_stats,{0,1,{0,0}}},
+ {?eh,tc_start,{seq_SUITE,test_case_2}},
+ {?eh,tc_done,{seq_SUITE,test_case_2,
+ {auto_skipped,{sequence_failed,seq1,test_case_1}}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [seq_SUITE,test_case_2,
+ {tc_auto_skip,{sequence_failed,seq1,test_case_1}},
+ []]}},
+ {?eh,test_stats,{0,1,{0,1}}},
+ {?eh,tc_start,{ct_framework,end_per_suite}},
+ {?eh,cth,{empty_cth,pre_end_per_suite,[seq_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_suite,[seq_SUITE,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_framework,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{empty_cth,terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ],
+ %% Make sure no 'cth_error' events are received!
+ [{negative,{?eh,cth_error,'_'},E} || E <- Events];
+
+test_events(repeat_force_stop) ->
+ %% skip_cth.erl will send a 'cth_error' event if a hook is
+ %% erroneously called. Therefore, all Events are changed to
+ %% {negative,{?eh,cth_error,'_'},Event}
+ %% at the end of this function.
+ Events=
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,cth,{empty_cth,id,[[]]}},
+ {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
+ {?eh,start_info,{1,1,2}},
+ {?eh,tc_start,{ct_framework,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,[repeat_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [repeat_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_framework,init_per_suite,ok}},
+ {?eh,tc_start,{repeat_SUITE,test_case_1}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,
+ [repeat_SUITE,test_case_1,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_testcase,
+ [repeat_SUITE,test_case_1,'$proplist',ok,[]]}},
+ {?eh,cth,{empty_cth,pre_end_per_testcase,
+ [repeat_SUITE,test_case_1,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,
+ [repeat_SUITE,test_case_1,'$proplist',ok,[]]}},
+ {?eh,tc_done,{repeat_SUITE,test_case_1,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{repeat_SUITE,test_case_2}},
+ {?eh,tc_done,{repeat_SUITE,test_case_2,
+ {auto_skipped,
+ "Repeated test stopped by force_stop option"}}},
+ {?eh,cth,{empty_cth,on_tc_skip,
+ [repeat_SUITE,test_case_2,
+ {tc_auto_skip,"Repeated test stopped by force_stop option"},
+ []]}},
+ {?eh,test_stats,{1,0,{0,1}}},
+ {?eh,tc_start,{ct_framework,end_per_suite}},
+ {?eh,cth,{empty_cth,pre_end_per_suite,[repeat_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_suite,
+ [repeat_SUITE,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_framework,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{empty_cth,terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ],
+ %% Make sure no 'cth_error' events are received!
+ [{negative,{?eh,cth_error,'_'},E} || E <- Events];
+
+test_events(config_clash) ->
+ %% skip_cth.erl will send a 'cth_error' event if a hook is
+ %% erroneously called. Therefore, all Events are changed to
+ %% {negative,{?eh,cth_error,'_'},Event}
+ %% at the end of this function.
+ Events =
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,cth,{empty_cth,id,[[]]}},
+ {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
+ {?eh,start_info,{1,1,1}},
+ {?eh,tc_start,{ct_framework,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,
+ [config_clash_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [config_clash_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_framework,init_per_suite,ok}},
+ {?eh,tc_start,{config_clash_SUITE,test_case_1}},
+ {?eh,tc_done,{config_clash_SUITE,test_case_1,
+ {failed,{error,{config_name_already_in_use,[aa]}}}}},
+ {?eh,cth,{empty_cth,on_tc_fail,
+ [config_clash_SUITE,test_case_1,
+ {config_name_already_in_use,[aa]},
+ []]}},
+ {?eh,test_stats,{0,1,{0,0}}},
+ {?eh,tc_start,{ct_framework,end_per_suite}},
+ {?eh,cth,{empty_cth,pre_end_per_suite,
+ [config_clash_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_suite,
+ [config_clash_SUITE,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_framework,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{empty_cth,terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ],
+ %% Make sure no 'cth_error' events are received!
+ [{negative,{?eh,cth_error,'_'},E} || E <- Events];
+
test_events(ok) ->
ok.
-
%% test events help functions
contains(List) ->
fun(Proplist) when is_list(Proplist) ->
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/all_hook_callbacks_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/all_hook_callbacks_SUITE.erl
new file mode 100644
index 0000000000..af8a85cd75
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/all_hook_callbacks_SUITE.erl
@@ -0,0 +1,62 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(all_hook_callbacks_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(Config) ->
+ Config.
+
+end_per_group(_Config) ->
+ ok.
+
+init_per_testcase(skip_case, Config) ->
+ {skip,"Skipped in init_per_testcase/2"};
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [{group,test_group},test_case,skip_case].
+
+groups() ->
+ [{test_group,[test_case]}].
+
+%% Test cases starts here.
+test_case(Config) ->
+ ok.
+
+skip_case(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/config_clash_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/config_clash_SUITE.erl
new file mode 100644
index 0000000000..3853dc29da
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/config_clash_SUITE.erl
@@ -0,0 +1,43 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(config_clash_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl").
+
+suite() ->
+ [{require,aa,yy},{default_config,yy,"this is a default value"}].
+
+init_per_testcase(_,Config) ->
+ Config.
+
+end_per_testcase(_,_) ->
+ ok.
+
+all() ->
+ [test_case_1].
+
+%% Test cases starts here.
+test_case_1() ->
+ [{require,aa,xx}].
+test_case_1(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_end_config_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_end_config_SUITE.erl
new file mode 100644
index 0000000000..0b6cabead3
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_end_config_SUITE.erl
@@ -0,0 +1,51 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ct_no_end_config_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl").
+
+%%% This suite is used to verify that all pre/post_end_per_* callbacks
+%%% are called with correct SuiteName even if no end_per_* config
+%%% function exist in the suite, and that the non-exported config
+%%% functions fail with 'undef'.
+
+init_per_suite(Config) ->
+ Config.
+
+init_per_group(_Group,Config) ->
+ Config.
+
+init_per_testcase(_TC,Config) ->
+ Config.
+
+all() ->
+ [test_case_1, {group,test_group}].
+
+groups() ->
+ [{test_group,[],[test_case_2]}].
+
+test_case_1(Config) ->
+ ok.
+
+test_case_2(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_init_config_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_init_config_SUITE.erl
new file mode 100644
index 0000000000..29cdc21ee4
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_init_config_SUITE.erl
@@ -0,0 +1,54 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ct_no_init_config_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl").
+
+%%% This suite is used to verify that all
+%%% pre/post_init_per_group/testcase callbacks are called with correct
+%%% SuiteName even if no init_per_group/testcase function exist in the
+%%% suite, and that the non-exported config functions fail with 'undef'.
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ Config.
+
+end_per_group(_Group,Config) ->
+ Config.
+
+end_per_testcase(_TC,Config) ->
+ Config.
+
+all() ->
+ [test_case_1, {group,test_group}].
+
+groups() ->
+ [{test_group,[],[test_case_2]}].
+
+test_case_1(Config) ->
+ ok.
+
+test_case_2(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_init_suite_config_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_init_suite_config_SUITE.erl
new file mode 100644
index 0000000000..d6daff9792
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_no_init_suite_config_SUITE.erl
@@ -0,0 +1,39 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ct_no_init_suite_config_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl").
+
+%%% This suite is used to verify that pre/post_init_per_suite
+%%% callbacks are called with correct SuiteName even if no
+%%% init_per_suite function exist in the suite, and that the
+%%% non-exported config function fails with 'undef'.
+
+end_per_suite(Config) ->
+ Config.
+
+all() ->
+ [test_case].
+
+test_case(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl
index c00eb5cf93..961ea68d2d 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -44,18 +44,18 @@
-export([pre_end_per_suite/3]).
-export([post_end_per_suite/4]).
--export([pre_init_per_group/3]).
--export([post_init_per_group/4]).
--export([pre_end_per_group/3]).
--export([post_end_per_group/4]).
+-export([pre_init_per_group/4]).
+-export([post_init_per_group/5]).
+-export([pre_end_per_group/4]).
+-export([post_end_per_group/5]).
--export([pre_init_per_testcase/3]).
--export([post_init_per_testcase/4]).
--export([pre_end_per_testcase/3]).
--export([post_end_per_testcase/4]).
+-export([pre_init_per_testcase/4]).
+-export([post_init_per_testcase/5]).
+-export([pre_end_per_testcase/4]).
+-export([post_end_per_testcase/5]).
--export([on_tc_fail/3]).
--export([on_tc_skip/3]).
+-export([on_tc_fail/4]).
+-export([on_tc_skip/4]).
-export([terminate/1]).
@@ -154,150 +154,160 @@ post_end_per_suite(Suite,Config,Return,State) ->
%% @doc Called before each init_per_group.
%% You can change the config in this function.
--spec pre_init_per_group(Group :: atom(),
- Config :: config(),
- State :: #state{}) ->
+-spec pre_init_per_group(Suite :: atom(),
+ Group :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
{config() | skip_or_fail(), NewState :: #state{}}.
-pre_init_per_group(Group,Config,State) ->
+pre_init_per_group(Suite,Group,Config,State) ->
gen_event:notify(
?CT_EVMGR_REF, #event{ name = cth, node = node(),
data = {?MODULE, pre_init_per_group,
- [Group,Config,State]}}),
- ct:log("~w:pre_init_per_group(~w) called", [?MODULE,Group]),
+ [Suite,Group,Config,State]}}),
+ ct:log("~w:pre_init_per_group(~w,~w) called", [?MODULE,Suite,Group]),
{Config, State}.
%% @doc Called after each init_per_group.
%% You can change the return value in this function.
--spec post_init_per_group(Group :: atom(),
+-spec post_init_per_group(Suite :: atom(),
+ Group :: atom(),
Config :: config(),
Return :: config() | skip_or_fail(),
State :: #state{}) ->
{config() | skip_or_fail(), NewState :: #state{}}.
-post_init_per_group(Group,Config,Return,State) ->
+post_init_per_group(Suite,Group,Config,Return,State) ->
gen_event:notify(
?CT_EVMGR_REF, #event{ name = cth, node = node(),
data = {?MODULE, post_init_per_group,
- [Group,Config,Return,State]}}),
- ct:log("~w:post_init_per_group(~w) called", [?MODULE,Group]),
+ [Suite,Group,Config,Return,State]}}),
+ ct:log("~w:post_init_per_group(~w,~w) called", [?MODULE,Suite,Group]),
{Return, State}.
%% @doc Called after each end_per_group. The config/state can be changed here,
%% though it will only affect the *end_per_group functions.
--spec pre_end_per_group(Group :: atom(),
+-spec pre_end_per_group(Suite :: atom(),
+ Group :: atom(),
Config :: config() | skip_or_fail(),
State :: #state{}) ->
{ok | skip_or_fail(), NewState :: #state{}}.
-pre_end_per_group(Group,Config,State) ->
+pre_end_per_group(Suite,Group,Config,State) ->
gen_event:notify(
?CT_EVMGR_REF, #event{ name = cth, node = node(),
data = {?MODULE, pre_end_per_group,
- [Group,Config,State]}}),
- ct:log("~w:pre_end_per_group(~w) called", [?MODULE,Group]),
+ [Suite,Group,Config,State]}}),
+ ct:log("~w:pre_end_per_group(~w~w) called", [?MODULE,Suite,Group]),
{Config, State}.
%% @doc Called after each end_per_group. Note that the config cannot be
%% changed here, only the status of the group.
--spec post_end_per_group(Group :: atom(),
+-spec post_end_per_group(Suite :: atom(),
+ Group :: atom(),
Config :: config(),
Return :: term(),
State :: #state{}) ->
{ok | skip_or_fail(), NewState :: #state{}}.
-post_end_per_group(Group,Config,Return,State) ->
+post_end_per_group(Suite,Group,Config,Return,State) ->
gen_event:notify(
?CT_EVMGR_REF, #event{ name = cth, node = node(),
data = {?MODULE, post_end_per_group,
- [Group,Config,Return,State]}}),
- ct:log("~w:post_end_per_group(~w) called", [?MODULE,Group]),
+ [Suite,Group,Config,Return,State]}}),
+ ct:log("~w:post_end_per_group(~w,~w) called", [?MODULE,Suite,Group]),
{Return, State}.
%% @doc Called before init_per_testcase/2 for each test case.
%% You can change the config in this function.
--spec pre_init_per_testcase(TC :: atom(),
- Config :: config(),
- State :: #state{}) ->
+-spec pre_init_per_testcase(Suite :: atom(),
+ TC :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
{config() | skip_or_fail(), NewState :: #state{}}.
-pre_init_per_testcase(TC,Config,State) ->
+pre_init_per_testcase(Suite,TC,Config,State) ->
gen_event:notify(
?CT_EVMGR_REF, #event{ name = cth, node = node(),
data = {?MODULE, pre_init_per_testcase,
- [TC,Config,State]}}),
- ct:log("~w:pre_init_per_testcase(~w) called", [?MODULE,TC]),
+ [Suite,TC,Config,State]}}),
+ ct:log("~w:pre_init_per_testcase(~w,~w) called", [?MODULE,Suite,TC]),
{Config, State}.
%% @doc Called after init_per_testcase/2, and before the test case.
--spec post_init_per_testcase(TC :: atom(),
+-spec post_init_per_testcase(Suite :: atom(),
+ TC :: atom(),
Config :: config(),
Return :: config() | skip_or_fail(),
State :: #state{}) ->
{config() | skip_or_fail(), NewState :: #state{}}.
-post_init_per_testcase(TC,Config,Return,State) ->
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
gen_event:notify(
?CT_EVMGR_REF, #event{ name = cth, node = node(),
data = {?MODULE, post_init_per_testcase,
- [TC,Config,Return,State]}}),
- ct:log("~w:post_init_per_testcase(~w) called", [?MODULE,TC]),
+ [Suite,TC,Config,Return,State]}}),
+ ct:log("~w:post_init_per_testcase(~w,~w) called", [?MODULE,Suite,TC]),
{Return, State}.
%% @doc Called before end_per_testacse/2. No skip or fail allowed here,
%% only config additions.
--spec pre_end_per_testcase(TC :: atom(),
- Config :: config(),
- State :: #state{}) ->
+-spec pre_end_per_testcase(Suite :: atom(),
+ TC :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
{config(), NewState :: #state{}}.
-pre_end_per_testcase(TC,Config,State) ->
+pre_end_per_testcase(Suite,TC,Config,State) ->
gen_event:notify(
?CT_EVMGR_REF, #event{ name = cth, node = node(),
data = {?MODULE, pre_end_per_testcase,
- [TC,Config,State]}}),
- ct:log("~w:pre_end_per_testcase(~w) called", [?MODULE,TC]),
+ [Suite,TC,Config,State]}}),
+ ct:log("~w:pre_end_per_testcase(~w,~w) called", [?MODULE,Suite,TC]),
{Config, State}.
%% @doc Called after end_per_testcase/2 for each test case. Note that
%% the config cannot be changed here, only the status of the test case.
--spec post_end_per_testcase(TC :: atom(),
+-spec post_end_per_testcase(Suite :: atom(),
+ TC :: atom(),
Config :: config(),
Return :: term(),
State :: #state{}) ->
{ok | skip_or_fail(), NewState :: #state{}}.
-post_end_per_testcase(TC,Config,Return,State) ->
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
gen_event:notify(
?CT_EVMGR_REF, #event{ name = cth, node = node(),
data = {?MODULE, post_end_per_testcase,
- [TC,Config,Return,State]}}),
- ct:log("~w:post_end_per_testcase(~w) called", [?MODULE,TC]),
+ [Suite,TC,Config,Return,State]}}),
+ ct:log("~w:post_end_per_testcase(~w,~w) called", [?MODULE,Suite,TC]),
{Return, State}.
%% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group,
%% post_end_per_group and post_end_per_tc if the suite, group or test case failed.
%% This function should be used for extra cleanup which might be needed.
%% It is not possible to modify the config or the status of the test run.
--spec on_tc_fail(TC :: init_per_suite | end_per_suite |
+-spec on_tc_fail(Suite :: atom(),
+ TC :: init_per_suite | end_per_suite |
init_per_group | end_per_group | atom() |
{Function :: atom(), GroupName :: atom()},
Reason :: term(), State :: #state{}) -> NewState :: #state{}.
-on_tc_fail(TC, Reason, State) ->
+on_tc_fail(Suite, TC, Reason, State) ->
gen_event:notify(
?CT_EVMGR_REF, #event{ name = cth, node = node(),
data = {?MODULE, on_tc_fail,
- [TC,Reason,State]}}),
- ct:log("~w:on_tc_fail(~w) called", [?MODULE,TC]),
+ [Suite,TC,Reason,State]}}),
+ ct:log("~w:on_tc_fail(~w,~w) called", [?MODULE,Suite,TC]),
State.
%% @doc Called when a test case is skipped by either user action
%% or due to an init function failing. Test case can be
%% end_per_suite, init_per_group, end_per_group and the actual test cases.
--spec on_tc_skip(TC :: end_per_suite |
+-spec on_tc_skip(Suite :: atom(),
+ TC :: end_per_suite |
init_per_group | end_per_group | atom() |
{Function :: atom(), GroupName :: atom()},
{tc_auto_skip, {failed, {Mod :: atom(), Function :: atom(), Reason :: term()}}} |
{tc_user_skip, {skipped, Reason :: term()}},
State :: #state{}) -> NewState :: #state{}.
-on_tc_skip(TC, Reason, State) ->
+on_tc_skip(Suite, TC, Reason, State) ->
gen_event:notify(
?CT_EVMGR_REF, #event{ name = cth, node = node(),
data = {?MODULE, on_tc_skip,
- [TC,Reason,State]}}),
- ct:log("~w:on_tc_skip(~w) called", [?MODULE,TC]),
+ [Suite,TC,Reason,State]}}),
+ ct:log("~w:on_tc_skip(~w,~w) called", [?MODULE,Suite,TC]),
State.
%% @doc Called when the scope of the CTH is done, this depends on
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl
index 559b22bc9f..7cb2d19414 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -45,29 +45,29 @@ pre_end_per_suite(Suite,Config,State) ->
post_end_per_suite(Suite,Config,Return,State) ->
empty_cth:post_end_per_suite(Suite,Config,Return,State).
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
+pre_init_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State).
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State).
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl
index 51202443bf..ebe6014127 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -45,35 +45,35 @@ pre_end_per_suite(Suite,Config,State) ->
post_end_per_suite(Suite,Config,Return,State) ->
empty_cth:post_end_per_suite(Suite,Config,Return,State).
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
+pre_init_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State).
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State).
-post_init_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_init_per_testcase(TC,Config,Return,State).
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
-pre_end_per_testcase(TC,Config,State) ->
- empty_cth:pre_end_per_testcase(TC,Config,State).
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fallback_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fallback_cth.erl
new file mode 100644
index 0000000000..665efd659a
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fallback_cth.erl
@@ -0,0 +1,81 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+
+-module(fallback_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+id(Opts) ->
+ empty_cth:id(Opts).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(fallback_nosuite,Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(fallback_nosuite,Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(fallback_nosuite,Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(fallback_nosuite,Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(fallback_nosuite,TC,Config,State).
+
+post_init_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(fallback_nosuite,TC,Config,Return,State).
+
+pre_end_per_testcase(TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(fallback_nosuite,TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(fallback_nosuite,TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(fallback_nosuite,TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(fallback_nosuite,TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl
index b49cbe7fb4..f5d215c69d 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,13 +29,13 @@
%% CT Hooks
-export([init/2]).
-export([terminate/1]).
--export([on_tc_skip/3]).
+-export([on_tc_skip/4]).
init(Id, Opts) ->
empty_cth:init(Id, Opts).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite, TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/prio_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/prio_cth.erl
index a687743641..d462e5e071 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/prio_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/prio_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -47,35 +47,35 @@ pre_end_per_suite(Suite,Config,State) ->
post_end_per_suite(Suite,Config,Return,State) ->
empty_cth:post_end_per_suite(Suite,Config,Return,State).
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
+pre_init_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State).
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State).
-post_init_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_init_per_testcase(TC,Config,Return,State).
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
-pre_end_per_testcase(TC,Config,State) ->
- empty_cth:pre_end_per_testcase(TC,Config,State).
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl
index 4d9c60f1ca..f67d152cf1 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -47,35 +47,35 @@ pre_end_per_suite(Suite,Config,State) ->
post_end_per_suite(Suite,Config,Return,State) ->
empty_cth:post_end_per_suite(Suite,Config,Return,State).
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
+pre_init_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State).
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State).
-post_init_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_init_per_testcase(TC,Config,Return,State).
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
-pre_end_per_testcase(TC,Config,State) ->
- empty_cth:pre_end_per_testcase(TC,Config,State).
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/repeat_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/repeat_SUITE.erl
new file mode 100644
index 0000000000..a1849839c9
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/repeat_SUITE.erl
@@ -0,0 +1,42 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(repeat_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl").
+
+init_per_testcase(_,Config) ->
+ Config.
+
+end_per_testcase(_,_) ->
+ ok.
+
+all() ->
+ [test_case_1, test_case_2].
+
+%% Test cases starts here.
+test_case_1(_Config) ->
+ timer:sleep(10000),
+ ok.
+
+test_case_2(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl
index 494f398fc1..a4105f5829 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -48,35 +48,35 @@ pre_end_per_suite(Suite,Config,State) ->
post_end_per_suite(Suite,Config,Return,State) ->
empty_cth:post_end_per_suite(Suite,Config,Return,State).
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
+pre_init_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State).
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State).
-post_init_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_init_per_testcase(TC,Config,Return,State).
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
-pre_end_per_testcase(TC,Config,State) ->
- empty_cth:pre_end_per_testcase(TC,Config,State).
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/seq_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/seq_SUITE.erl
new file mode 100644
index 0000000000..30eebb272a
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/seq_SUITE.erl
@@ -0,0 +1,45 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(seq_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl").
+
+init_per_testcase(_,Config) ->
+ Config.
+
+end_per_testcase(_,_) ->
+ ok.
+
+all() ->
+ [{sequence,seq1}].
+
+sequences() ->
+ [{seq1,[test_case_1,test_case_2]}].
+
+%% Test cases starts here.
+test_case_1(_Config) ->
+ exit(failed_on_purpose).
+
+test_case_2(_Config) ->
+ ct:fail("This test shall never be run since test_case_1 fails "
+ "and they are run in sequence").
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip.spec b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip.spec
new file mode 100644
index 0000000000..a271c5e8b2
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip.spec
@@ -0,0 +1,8 @@
+{suites,".",[all_hook_callbacks_SUITE,
+ skip_init_SUITE,
+ skip_req_SUITE,
+ skip_fail_SUITE,
+ skip_group_SUITE,
+ skip_case_SUITE]}.
+{skip_suites,".",all_hook_callbacks_SUITE,"Skipped in spec"}.
+{skip_cases,".",skip_case_SUITE,skip_in_spec,"Skipped in spec"}.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_case_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_case_SUITE.erl
new file mode 100644
index 0000000000..3c2275d55f
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_case_SUITE.erl
@@ -0,0 +1,106 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(skip_case_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl").
+
+suite() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ ok.
+
+init_per_group(_,Config) ->
+ Config.
+
+end_per_group(_,_) ->
+ ok.
+
+init_per_testcase(skip_in_init,Config) ->
+ {skip,"Skipped in init_per_testcase/2"};
+init_per_testcase(fail_in_init,Config) ->
+ ct:fail("Failed in init_per_testcase/2");
+init_per_testcase(exit_in_init,Config) ->
+ exit(self(),"Exit in init_per_testcase/2");
+init_per_testcase(_,Config) ->
+ Config.
+
+end_per_testcase(fail_in_end,_) ->
+ ct:fail("Failed in end_per_testcase/2");
+end_per_testcase(exit_in_end,_) ->
+ exit(self(),"Exit in end_per_testcase/2");
+end_per_testcase(_,_) ->
+ ok.
+
+all() ->
+ [skip_in_spec,
+ skip_in_init,
+ fail_in_init,
+ exit_in_init,
+ fail_in_end,
+ exit_in_end,
+ skip_in_case,
+ req_auto_skip,
+ fail_auto_skip
+ ].
+
+%% Test cases starts here.
+skip_in_spec(Config) ->
+ ct:fail("This test shall never be run. "
+ "It shall be skipped in the test spec.").
+
+skip_in_init(Config) ->
+ ct:fail("This test shall never be run. "
+ "It shall be skipped in init_per_testcase/2.").
+
+fail_in_init(Config) ->
+ ct:fail("This test shall never be run. "
+ "It shall fail in init_per_testcase/2.").
+
+exit_in_init(Config) ->
+ ct:fail("This test shall never be run. "
+ "It shall exit in init_per_testcase/2.").
+
+fail_in_end(Config) ->
+ ok.
+
+exit_in_end(Config) ->
+ ok.
+
+skip_in_case(Config) ->
+ {skip,"Skipped in test case function"}.
+
+req_auto_skip() ->
+ [{require,whatever}].
+req_auto_skip(Config) ->
+ ct:fail("This test shall never be run due to "
+ "failed require").
+
+fail_auto_skip() ->
+ faulty_return_value.
+fail_auto_skip(Config) ->
+ ct:fail("This test shall never be run due to "
+ "faulty return from info function").
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_cth.erl
new file mode 100644
index 0000000000..7b5e93f836
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_cth.erl
@@ -0,0 +1,182 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+
+-module(skip_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+%% Send a cth_error event if a callback is called with unexpected arguments
+-define(fail(Info),
+ gen_event:notify(
+ ?CT_EVMGR_REF,
+ #event{ name = cth_error,
+ node = node(),
+ data = {illegal_hook_callback,{?MODULE,?FUNCTION_NAME,Info}}})).
+
+%% CT Hooks
+-compile(export_all).
+
+id(Opts) ->
+ empty_cth:id(Opts).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ Suite==skip_init_SUITE
+ orelse Suite==skip_group_SUITE
+ orelse Suite==skip_case_SUITE
+ orelse Suite==seq_SUITE
+ orelse Suite==repeat_SUITE
+ orelse Suite==config_clash_SUITE
+ orelse ?fail(Suite),
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ Suite==skip_init_SUITE
+ orelse Suite==skip_group_SUITE
+ orelse Suite==skip_case_SUITE
+ orelse Suite==seq_SUITE
+ orelse Suite==repeat_SUITE
+ orelse Suite==config_clash_SUITE
+ orelse ?fail(Suite),
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ Suite==skip_case_SUITE
+ orelse Suite==skip_group_SUITE
+ orelse Suite==seq_SUITE
+ orelse Suite==repeat_SUITE
+ orelse Suite==config_clash_SUITE
+ orelse ?fail(Suite),
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ Suite==skip_case_SUITE
+ orelse Suite==skip_group_SUITE
+ orelse Suite==seq_SUITE
+ orelse Suite==repeat_SUITE
+ orelse Suite==config_clash_SUITE
+ orelse ?fail(Suite),
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Suite,Group,Config,State) ->
+ (Suite==skip_group_SUITE andalso Group==test_group_3)
+ orelse ?fail({Suite,Group}),
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
+
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ (Suite==skip_group_SUITE andalso Group==test_group_3)
+ orelse ?fail({Suite,Group}),
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
+
+pre_end_per_group(Suite,Group,Config,State) ->
+ ?fail({Suite,Group}),
+ empty_cth:pre_end_per_group(Suite,Group,Config,State).
+
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ ?fail({Suite,Group}),
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
+
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ (Suite==skip_case_SUITE andalso (TC==skip_in_init
+ orelse TC==fail_in_init
+ orelse TC==exit_in_init
+ orelse TC==fail_in_end
+ orelse TC==exit_in_end
+ orelse TC==skip_in_case))
+ orelse (Suite==seq_SUITE andalso TC==test_case_1)
+ orelse (Suite==repeat_SUITE andalso TC==test_case_1)
+ orelse ?fail({Suite,TC}),
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State).
+
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ (Suite==skip_case_SUITE andalso (TC==skip_in_init
+ orelse TC==fail_in_init
+ orelse TC==exit_in_init
+ orelse TC==fail_in_end
+ orelse TC==exit_in_end
+ orelse TC==skip_in_case))
+ orelse (Suite==seq_SUITE andalso TC==test_case_1)
+ orelse (Suite==repeat_SUITE andalso TC==test_case_1)
+ orelse ?fail({Suite,TC}),
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
+
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ (Suite==skip_case_SUITE andalso (TC==skip_in_case
+ orelse TC==fail_in_end
+ orelse TC==exit_in_end))
+ orelse (Suite==seq_SUITE andalso TC==test_case_1)
+ orelse (Suite==repeat_SUITE andalso TC==test_case_1)
+ orelse ?fail({Suite,TC}),
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
+
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ (Suite==skip_case_SUITE andalso (TC==skip_in_case
+ orelse TC==fail_in_end
+ orelse TC==exit_in_end))
+ orelse (Suite==seq_SUITE andalso TC==test_case_1)
+ orelse (Suite==repeat_SUITE andalso TC==test_case_1)
+ orelse ?fail({Suite,TC}),
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
+
+on_tc_fail(Suite,TC,Reason,State) ->
+ (Suite==seq_SUITE andalso TC==test_case_1)
+ orelse (Suite==config_clash_SUITE andalso TC==test_case_1)
+ orelse ?fail({Suite,TC}),
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
+
+on_tc_skip(all_hook_callbacks_SUITE=Suite,all=TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State);
+on_tc_skip(Suite,TC,Reason,State)
+ when (Suite==skip_init_SUITE
+ orelse Suite==skip_req_SUITE
+ orelse Suite==skip_fail_SUITE)
+ andalso
+ (TC==init_per_suite
+ orelse TC==test_case
+ orelse TC==end_per_suite) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State);
+on_tc_skip(skip_group_SUITE=Suite,TC={C,G},Reason,State)
+ when (C==init_per_group orelse C==test_case orelse C==end_per_group) andalso
+ (G==test_group_1 orelse G==test_group_2 orelse G==test_group_3) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State);
+on_tc_skip(skip_case_SUITE=Suite,TC,Reason,State)
+ when TC==skip_in_spec;
+ TC==skip_in_init;
+ TC==fail_in_init;
+ TC==exit_in_init;
+ TC==skip_in_case;
+ TC==req_auto_skip;
+ TC==fail_auto_skip ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State);
+on_tc_skip(Suite,TC,Reason,State)
+ when (Suite==seq_SUITE andalso TC==test_case_2)
+ orelse (Suite==repeat_SUITE andalso TC==test_case_2) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State);
+on_tc_skip(Suite,TC,Reason,State) ->
+ ?fail({Suite,TC}),
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_fail_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_fail_SUITE.erl
new file mode 100644
index 0000000000..df8835598e
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_fail_SUITE.erl
@@ -0,0 +1,53 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(skip_fail_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl").
+
+suite() ->
+ faulty_return_value.
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ ok.
+
+init_per_group(_,Config) ->
+ Config.
+
+end_per_group(_,_) ->
+ ok.
+
+init_per_testcase(_,Config) ->
+ Config.
+
+end_per_testcase(_,_) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_group_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_group_SUITE.erl
new file mode 100644
index 0000000000..8d25701a22
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_group_SUITE.erl
@@ -0,0 +1,64 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(skip_group_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl").
+
+suite() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ ok.
+
+group(test_group_1) ->
+ [{require,whatever}];
+group(test_group_2) ->
+ faulty_return_value;
+group(_) ->
+ [].
+
+init_per_group(test_group_3,Config) ->
+ {skip,"Skipped in init_per_group/2"};
+init_per_group(_,Config) ->
+ ct:fail("This shall never be run due to auto_skip from group/1").
+
+end_per_group(_,_) ->
+ ct:fail("This shall never be run").
+
+all() ->
+ [{group,test_group_1},
+ {group,test_group_2},
+ {group,test_group_3}].
+
+groups() ->
+ [{test_group_1,[test_case]},
+ {test_group_2,[test_case]},
+ {test_group_3,[test_case]}].
+
+%% Test cases starts here.
+test_case(_Config) ->
+ ct:fail("This test case shall never be run due to skip on group level").
+
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_init_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_init_SUITE.erl
new file mode 100644
index 0000000000..7d01ff58a9
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_init_SUITE.erl
@@ -0,0 +1,53 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(skip_init_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl").
+
+suite() ->
+ [].
+
+init_per_suite(Config) ->
+ {skip,"Skipped in init_per_suite/1"}.
+
+end_per_suite(Config) ->
+ ok.
+
+init_per_group(_,Config) ->
+ Config.
+
+end_per_group(_,_) ->
+ ok.
+
+init_per_testcase(_,Config) ->
+ Config.
+
+end_per_testcase(_,_) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl
index d5b347e723..b3b5db23fb 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -45,35 +45,35 @@ pre_end_per_suite(Suite,Config,State) ->
post_end_per_suite(Suite,Config,Return,State) ->
empty_cth:post_end_per_suite(Suite,Config,Return,State).
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
+pre_init_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State).
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State).
-post_init_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_init_per_testcase(TC,Config,Return,State).
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
-pre_end_per_testcase(TC,Config,State) ->
- empty_cth:pre_end_per_testcase(TC,Config,State).
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_end_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_end_cth.erl
index 36abac0bf8..525c376830 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_end_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_end_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -46,36 +46,36 @@ pre_end_per_suite(Suite,Config,State) ->
post_end_per_suite(Suite,Config,Return,State) ->
empty_cth:post_end_per_suite(Suite,Config,Return,State).
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
+pre_init_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State),
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State),
{{skip, "Test skip"}, State}.
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State).
-post_init_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_init_per_testcase(TC,Config,Return,State).
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
-pre_end_per_testcase(TC,Config,State) ->
- empty_cth:pre_end_per_testcase(TC,Config,State).
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_init_tc_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_init_tc_cth.erl
new file mode 100644
index 0000000000..459608ac07
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_init_tc_cth.erl
@@ -0,0 +1,79 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+
+-module(skip_pre_init_tc_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
+
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
+
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State).
+
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
+
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State),
+ {{skip, "Skipped in pre_init_per_testcase"}, State}.
+
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
+
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
+
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
+
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
+
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl
index fa510b2d54..1e6cab04ed 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -46,35 +46,35 @@ pre_end_per_suite(Suite,Config,State) ->
post_end_per_suite(Suite,Config,Return,State) ->
empty_cth:post_end_per_suite(Suite,Config,Return,State).
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
+pre_init_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State).
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State).
-post_init_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_init_per_testcase(TC,Config,Return,State).
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
-pre_end_per_testcase(TC,Config,State) ->
- empty_cth:pre_end_per_testcase(TC,Config,State).
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_req_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_req_SUITE.erl
new file mode 100644
index 0000000000..c6e67d978e
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_req_SUITE.erl
@@ -0,0 +1,53 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(skip_req_SUITE).
+
+-compile(export_all).
+
+-include("ct.hrl").
+
+suite() ->
+ [{require,whatever}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ ok.
+
+init_per_group(_,Config) ->
+ Config.
+
+end_per_group(_,_) ->
+ ok.
+
+init_per_testcase(_,Config) ->
+ Config.
+
+end_per_testcase(_,_) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl
index 7ec0d458b6..2b37116cb2 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -48,44 +48,44 @@ post_end_per_suite(Suite,Config,Return,State) ->
empty_cth:post_end_per_suite(Suite,Config,Return,State),
{Return, [post_end_per_suite|State]}.
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State),
+pre_init_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State),
{Config, [pre_init_per_group|State]}.
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State),
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State),
{Return, [post_init_per_group|State]}.
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State),
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State),
{Config, [pre_end_per_group|State]}.
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State),
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State),
{Return, [post_end_per_group|State]}.
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State),
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State),
{Config, [pre_init_per_testcase|State]}.
-post_init_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_init_per_testcase(TC,Config,Return,State),
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State),
{Return, [post_init_per_testcase|State]}.
-pre_end_per_testcase(TC,Config,State) ->
- empty_cth:pre_end_per_testcase(TC,Config,State),
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State),
{Config, [pre_end_per_testcase|State]}.
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State),
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State),
{Return, [post_end_per_testcase|State]}.
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State),
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State),
[on_tc_fail|State].
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State),
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State),
[on_tc_skip|State].
terminate(State) ->
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl
index 2b9e726819..ac7b74539a 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -44,35 +44,35 @@ pre_end_per_suite(Suite,Config,State) ->
post_end_per_suite(Suite,Config,Return,State) ->
empty_cth:post_end_per_suite(Suite,Config,Return,State).
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State).
+pre_init_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State).
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State).
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State).
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State).
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State).
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State).
-post_init_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_init_per_testcase(TC,Config,Return,State).
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
-pre_end_per_testcase(TC,Config,State) ->
- empty_cth:pre_end_per_testcase(TC,Config,State).
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl
index d48981f667..7b0c1f599f 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -50,43 +50,43 @@ post_end_per_suite(Suite,Config,Return,State) ->
NewConfig = [{post_end_per_suite,?now}|Config],
{NewConfig,NewConfig}.
-pre_init_per_group(Group,Config,State) ->
- empty_cth:pre_init_per_group(Group,Config,State),
+pre_init_per_group(Suite, Group,Config,State) ->
+ empty_cth:pre_init_per_group(Suite,Group,Config,State),
{[{pre_init_per_group,?now}|Config],State}.
-post_init_per_group(Group,Config,Return,State) ->
- empty_cth:post_init_per_group(Group,Config,Return,State),
+post_init_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State),
{[{post_init_per_group,?now}|Return],State}.
-pre_end_per_group(Group,Config,State) ->
- empty_cth:pre_end_per_group(Group,Config,State),
+pre_end_per_group(Suite,Group,Config,State) ->
+ empty_cth:pre_end_per_group(Suite,Group,Config,State),
{[{pre_end_per_group,?now}|Config],State}.
-post_end_per_group(Group,Config,Return,State) ->
- empty_cth:post_end_per_group(Group,Config,Return,State),
+post_end_per_group(Suite,Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State),
{[{post_end_per_group,?now}|Config],State}.
-pre_init_per_testcase(TC,Config,State) ->
- empty_cth:pre_init_per_testcase(TC,Config,State),
+pre_init_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State),
{[{pre_init_per_testcase,?now}|Config],State}.
-post_init_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_init_per_testcase(TC,Config,Return,State),
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State),
{[{post_init_per_testcase,?now}|Config],State}.
-pre_end_per_testcase(TC,Config,State) ->
- empty_cth:pre_end_per_testcase(TC,Config,State),
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State),
{[{pre_end_per_testcase,?now}|Config],State}.
-post_end_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_end_per_testcase(TC,Config,Return,State),
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State),
{[{post_end_per_testcase,?now}|Config],State}.
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl
index 71d84781e0..44e7c7c29d 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_config_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -60,37 +60,37 @@ post_end_per_suite(Suite,Config,Return,State) ->
ct_no_config_SUITE = ct:get_config(suite_cfg),
empty_cth:post_end_per_suite(Suite,Config,Return,State).
-pre_init_per_group(Group,Config,State) ->
+pre_init_per_group(Suite,Group,Config,State) ->
true = ?val(post_init_per_suite, Config),
ct_no_config_SUITE = ct:get_config(suite_cfg),
test_group = ct:get_config(group_cfg),
- empty_cth:pre_init_per_group(Group,
+ empty_cth:pre_init_per_group(Suite,Group,
[{pre_init_per_group,true} | Config],
State).
-post_init_per_group(Group,Config,Return,State) ->
+post_init_per_group(Suite,Group,Config,Return,State) ->
true = ?val(pre_init_per_group, Return),
test_group = ct:get_config(group_cfg),
- empty_cth:post_init_per_group(Group,
+ empty_cth:post_init_per_group(Suite,Group,
Config,
[{post_init_per_group,true} | Return],
State).
-pre_end_per_group(Group,Config,State) ->
+pre_end_per_group(Suite,Group,Config,State) ->
true = ?val(post_init_per_group, Config),
ct_no_config_SUITE = ct:get_config(suite_cfg),
test_group = ct:get_config(group_cfg),
- empty_cth:pre_end_per_group(Group,
+ empty_cth:pre_end_per_group(Suite,Group,
[{pre_end_per_group,true} | Config],
State).
-post_end_per_group(Group,Config,Return,State) ->
+post_end_per_group(Suite,Group,Config,Return,State) ->
true = ?val(pre_end_per_group, Config),
ct_no_config_SUITE = ct:get_config(suite_cfg),
test_group = ct:get_config(group_cfg),
- empty_cth:post_end_per_group(Group,Config,Return,State).
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
-pre_init_per_testcase(TC,Config,State) ->
+pre_init_per_testcase(Suite,TC,Config,State) ->
true = ?val(post_init_per_suite, Config),
case ?val(name, ?val(tc_group_properties, Config)) of
undefined ->
@@ -102,19 +102,19 @@ pre_init_per_testcase(TC,Config,State) ->
ct_no_config_SUITE = ct:get_config(suite_cfg),
CfgKey = list_to_atom(atom_to_list(TC) ++ "_cfg"),
TC = ct:get_config(CfgKey),
- empty_cth:pre_init_per_testcase(TC,
+ empty_cth:pre_init_per_testcase(Suite,TC,
[{pre_init_per_testcase,true} | Config],
State).
%%! TODO: Verify Config also in post_init and pre_end!
-post_init_per_testcase(TC,Config,Return,State) ->
- empty_cth:post_init_per_testcase(TC,Config,Return,State).
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
-pre_end_per_testcase(TC,Config,State) ->
- empty_cth:pre_end_per_testcase(TC,Config,State).
+pre_end_per_testcase(Suite,TC,Config,State) ->
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
-post_end_per_testcase(TC,Config,Return,State) ->
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
true = ?val(post_init_per_suite, Config),
true = ?val(pre_init_per_testcase, Config),
case ?val(name, ?val(tc_group_properties, Config)) of
@@ -127,13 +127,13 @@ post_end_per_testcase(TC,Config,Return,State) ->
ct_no_config_SUITE = ct:get_config(suite_cfg),
CfgKey = list_to_atom(atom_to_list(TC) ++ "_cfg"),
TC = ct:get_config(CfgKey),
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_data_dir_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_data_dir_cth.erl
index 9abd2e5e83..bde6744433 100644
--- a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_data_dir_cth.erl
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/verify_data_dir_cth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -62,43 +62,43 @@ post_end_per_suite(Suite,Config,Return,State) ->
check_dirs(State,Config),
empty_cth:post_end_per_suite(Suite,Config,Return,State).
-pre_init_per_group(Group,Config,State) ->
+pre_init_per_group(Suite,Group,Config,State) ->
check_dirs(State,Config),
- empty_cth:pre_init_per_group(Group,Config,State).
+ empty_cth:pre_init_per_group(Suite,Group,Config,State).
-post_init_per_group(Group,Config,Return,State) ->
+post_init_per_group(Suite,Group,Config,Return,State) ->
check_dirs(State,Return),
- empty_cth:post_init_per_group(Group,Config,Return,State).
+ empty_cth:post_init_per_group(Suite,Group,Config,Return,State).
-pre_end_per_group(Group,Config,State) ->
+pre_end_per_group(Suite,Group,Config,State) ->
check_dirs(State,Config),
- empty_cth:pre_end_per_group(Group,Config,State).
+ empty_cth:pre_end_per_group(Suite,Group,Config,State).
-post_end_per_group(Group,Config,Return,State) ->
+post_end_per_group(Suite,Group,Config,Return,State) ->
check_dirs(State,Config),
- empty_cth:post_end_per_group(Group,Config,Return,State).
+ empty_cth:post_end_per_group(Suite,Group,Config,Return,State).
-pre_init_per_testcase(TC,Config,State) ->
+pre_init_per_testcase(Suite,TC,Config,State) ->
check_dirs(State,Config),
- empty_cth:pre_init_per_testcase(TC,Config,State).
+ empty_cth:pre_init_per_testcase(Suite,TC,Config,State).
-post_init_per_testcase(TC,Config,Return,State) ->
+post_init_per_testcase(Suite,TC,Config,Return,State) ->
check_dirs(State,Config),
- empty_cth:post_init_per_testcase(TC,Config,Return,State).
+ empty_cth:post_init_per_testcase(Suite,TC,Config,Return,State).
-pre_end_per_testcase(TC,Config,State) ->
+pre_end_per_testcase(Suite,TC,Config,State) ->
check_dirs(State,Config),
- empty_cth:pre_end_per_testcase(TC,Config,State).
+ empty_cth:pre_end_per_testcase(Suite,TC,Config,State).
-post_end_per_testcase(TC,Config,Return,State) ->
+post_end_per_testcase(Suite,TC,Config,Return,State) ->
check_dirs(State,Config),
- empty_cth:post_end_per_testcase(TC,Config,Return,State).
+ empty_cth:post_end_per_testcase(Suite,TC,Config,Return,State).
-on_tc_fail(TC, Reason, State) ->
- empty_cth:on_tc_fail(TC,Reason,State).
+on_tc_fail(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_fail(Suite,TC,Reason,State).
-on_tc_skip(TC, Reason, State) ->
- empty_cth:on_tc_skip(TC,Reason,State).
+on_tc_skip(Suite,TC, Reason, State) ->
+ empty_cth:on_tc_skip(Suite,TC,Reason,State).
terminate(State) ->
empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_keep_logs_SUITE.erl b/lib/common_test/test/ct_keep_logs_SUITE.erl
new file mode 100644
index 0000000000..83b7963d7d
--- /dev/null
+++ b/lib/common_test/test/ct_keep_logs_SUITE.erl
@@ -0,0 +1,199 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_keep_logs_SUITE
+%%%
+%%% Description:
+%%% Test the 'keep_logs' option
+%%%
+%%%-------------------------------------------------------------------
+-module(ct_keep_logs_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+init_per_suite(Config0) ->
+ ct_test_support:init_per_suite(Config0).
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [
+ keep_logs,
+ refresh_logs
+ ].
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%% Test the keep_logs option with normal common_test runs
+keep_logs(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Suite = filename:join(DataDir, "keep_logs_SUITE"),
+ Opts0 = ct_test_support:get_opts(Config),
+ Opts = [{suite,Suite},{label,keep_logs} | Opts0],
+
+ LogDir=?config(logdir,Opts),
+ KeepLogsDir = create_dir(filename:join(LogDir,"keep_logs-")),
+ Opts1 = lists:keyreplace(logdir,1,Opts,{logdir,KeepLogsDir}),
+ ct:log("New LogDir = ~ts", [KeepLogsDir]),
+
+ %% Create 6 ct_run.* log directories
+ [ok = ct_test_support:run(Opts1, Config) || _ <- lists:seq(1,3)],
+
+ %% Verify the number of directories
+ WC = filename:join(KeepLogsDir,"ct_run.ct@*"),
+ L1 = filelib:wildcard(WC),
+ 6 = length(L1),
+
+ %% Keep all logs
+ {1,0,{0,0}}=ct_test_support:run_ct_run_test([{keep_logs,all}|Opts1], Config),
+ L2 = filelib:wildcard(WC),
+ 7 = length(L2),
+ 0 = ct_test_support:run_ct_script_start([{keep_logs,all}|Opts1], Config),
+ L3 = filelib:wildcard(WC),
+ 8 = length(L3),
+
+ %% N<length of list
+ {1,0,{0,0}}=ct_test_support:run_ct_run_test([{keep_logs,7}|Opts1], Config),
+ L4 = filelib:wildcard(WC),
+ 7 = length(L4),
+ 0 = ct_test_support:run_ct_script_start([{keep_logs,6}|Opts1], Config),
+ L5 = filelib:wildcard(WC),
+ 6 = length(L5),
+
+ %% N>length of list
+ {1,0,{0,0}}=ct_test_support:run_ct_run_test([{keep_logs,10}|Opts1], Config),
+ L6 = filelib:wildcard(WC),
+ 7 = length(L6),
+ 0 = ct_test_support:run_ct_script_start([{keep_logs,10}|Opts1], Config),
+ L7 = filelib:wildcard(WC),
+ 8 = length(L7),
+
+ %% N==length of list
+ {1,0,{0,0}}=ct_test_support:run_ct_run_test([{keep_logs,8}|Opts1], Config),
+ L8 = filelib:wildcard(WC),
+ 8 = length(L8),
+ 0 = ct_test_support:run_ct_script_start([{keep_logs,8}|Opts1], Config),
+ L9 = filelib:wildcard(WC),
+ 8 = length(L9),
+
+ %% N==length of list + current run
+ {1,0,{0,0}}=ct_test_support:run_ct_run_test([{keep_logs,9}|Opts1], Config),
+ L10 = filelib:wildcard(WC),
+ 9 = length(L10),
+ 0 = ct_test_support:run_ct_script_start([{keep_logs,10}|Opts1], Config),
+ L11 = filelib:wildcard(WC),
+ 10 = length(L11),
+
+ {ok,Content} = file:list_dir(KeepLogsDir),
+ ct:log("Deleting dir: ~p~nContent: ~p~n",[KeepLogsDir,Content]),
+ ct_test_support:rm_dir(KeepLogsDir).
+
+%% Test the keep_logs option togwther with the refresh_logs option
+refresh_logs(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Suite = filename:join(DataDir, "keep_logs_SUITE"),
+ Opts0 = ct_test_support:get_opts(Config),
+ LogDir=?config(logdir,Opts0),
+ KeepLogsDir = create_dir(filename:join(LogDir,"refresh_logs-")),
+ Opts1 = lists:keyreplace(logdir,1,Opts0,{logdir,KeepLogsDir}),
+ ct:log("New LogDir = ~ts", [KeepLogsDir]),
+
+ %% Create 6 ct_run.* log directories
+ SuiteOpts = [{suite,Suite},{label,refresh_logs} | Opts1],
+ [ok = ct_test_support:run(SuiteOpts, Config) || _ <- lists:seq(1,3)],
+
+ %% Verify the number of directories
+ WC = filename:join(KeepLogsDir,"ct_run.ct@*"),
+ L1 = filelib:wildcard(WC),
+ 6 = length(L1),
+
+ RefreshOpts = [{refresh_logs,KeepLogsDir},{label,refresh_logs} | Opts1],
+
+ %% Keep all logs (note that refresh_logs option prevents the
+ %% creation of a new log directory for the current run)
+ done = ct_test_support:run_ct_run_test([{keep_logs,all}|RefreshOpts], Config),
+ L2 = filelib:wildcard(WC),
+ 6 = length(L2),
+ 0 = ct_test_support:run_ct_script_start([{keep_logs,all}|RefreshOpts],Config),
+ L3 = filelib:wildcard(WC),
+ 6 = length(L3),
+
+ %% N<length of list
+ done = ct_test_support:run_ct_run_test([{keep_logs,5}|RefreshOpts], Config),
+ L5 = filelib:wildcard(WC),
+ 5 = length(L5),
+ 0 = ct_test_support:run_ct_script_start([{keep_logs,4}|RefreshOpts], Config),
+ L6 = filelib:wildcard(WC),
+ 4 = length(L6),
+
+ %% N>length of list
+ done = ct_test_support:run_ct_run_test([{keep_logs,5}|RefreshOpts], Config),
+ L7 = filelib:wildcard(WC),
+ 4 = length(L7),
+ 0 = ct_test_support:run_ct_script_start([{keep_logs,5}|RefreshOpts], Config),
+ L8 = filelib:wildcard(WC),
+ 4 = length(L8),
+
+ %% N==length of list
+ done = ct_test_support:run_ct_run_test([{keep_logs,4}|RefreshOpts], Config),
+ L9 = filelib:wildcard(WC),
+ 4 = length(L9),
+ 0 = ct_test_support:run_ct_script_start([{keep_logs,4}|RefreshOpts], Config),
+ L10 = filelib:wildcard(WC),
+ 4 = length(L10),
+
+ {ok,Content} = file:list_dir(KeepLogsDir),
+ ct:log("Deleting dir: ~p~nContent: ~p~n",[KeepLogsDir,Content]),
+ ct_test_support:rm_dir(KeepLogsDir).
+
+%%%-----------------------------------------------------------------
+%%% Internal
+create_dir(Prefix) ->
+ I = erlang:unique_integer([positive]),
+ Dir = Prefix ++ integer_to_list(I),
+ case filelib:is_dir(Dir) of
+ true ->
+ %% Try again
+ create_dir(Prefix);
+ false ->
+ ok = file:make_dir(Dir),
+ Dir
+ end.
diff --git a/lib/typer/src/typer.appup.src b/lib/common_test/test/ct_keep_logs_SUITE_data/keep_logs_SUITE.erl
index 3b7464a97c..c78080748b 100644
--- a/lib/typer/src/typer.appup.src
+++ b/lib/common_test/test/ct_keep_logs_SUITE_data/keep_logs_SUITE.erl
@@ -1,7 +1,7 @@
-%% -*- erlang -*-
+%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -16,7 +16,17 @@
%% limitations under the License.
%%
%% %CopyrightEnd%
-{"%VSN%",
- [{<<".*">>,[{restart_application, typer}]}],
- [{<<".*">>,[{restart_application, typer}]}]
-}.
+%%
+-module(keep_logs_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+suite() ->
+ [].
+all() ->
+ [test_case].
+
+test_case(_Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_log_SUITE.erl b/lib/common_test/test/ct_log_SUITE.erl
index 9bdd44cbdf..93affda398 100644
--- a/lib/common_test/test/ct_log_SUITE.erl
+++ b/lib/common_test/test/ct_log_SUITE.erl
@@ -86,18 +86,7 @@ print(Config) ->
io:format("5. Printing a pid: ~w~n", [Pid]),
io:format("6. Printing HTML: <pre>~s</pre>~n", [String]),
- %% --- API ---
- %% pal(Format) ->
- %% = ct:pal(default, 50, Format, []).
- %% pal(X1, X2) -> ok
- %% X1 = Category | Importance | Format
- %% X2 = Format | FormatArgs
- %% pal(X1, X2, X3) -> ok
- %% X1 = Category | Importance
- %% X2 = Importance | Format
- %% X3 = Format | FormatArgs
- %% pal(Category, Importance, Format, FormatArgs) -> ok
- %% ------
+ %% ct:pal
ct:pal("1. Printing nothing"),
ct:pal("2. Printing nothing", []),
ct:pal("3. Printing a string: ~s", [String]),
@@ -111,23 +100,16 @@ print(Config) ->
ct:pal(50, "11. Printing with ~s", ["importance"]),
ct:pal(ct_internal, 50, "12. Printing with ~s", ["category and importance"]),
- %% --- API ---
- %% log(Format) -> ok
- %% = ct:log(default, 50, Format, [], []).
- %% log(X1, X2) -> ok
- %% X1 = Category | Importance | Format
- %% X2 = Format | FormatArgs
- %% log(X1, X2, X3) -> ok
- %% X1 = Category | Importance
- %% X2 = Importance | Format
- %% X3 = Format | FormatArgs | Opts
- %% log(X1, X2, X3, X4) -> ok
- %% X1 = Category | Importance
- %% X2 = Importance | Format
- %% X3 = Format | FormatArgs
- %% X4 = FormatArgs | Opts
- %% log(Category, Importance, Format, FormatArgs, Opts) -> ok
- %% ------
+ ct:pal("13. Printing with heading", [],
+ [{heading,"This is a heading"}]),
+ ct:pal(ct_internal, "14. Printing with category and heading", [],
+ [{heading,"This is a heading"}]),
+ ct:pal(50, "15. Printing with importance and heading", [],
+ [{heading,"This is a heading"}]),
+ ct:pal(ct_internal, 50, "16. Printing with category, importance and heading", [],
+ [{heading,"This is a heading"}]),
+
+ %% ct:log
ct:log("1. Printing nothing"),
ct:log("2. Printing nothing", []),
ct:log("3. Printing a string: ~s", [String]),
@@ -153,8 +135,37 @@ print(Config) ->
ct:log(ct_internal, 50, "21. Printing a pid escaped with ~s, no_css: ~w",
["category and importance",Pid], [esc_chars,no_css]),
+ ct:log("22. Printing with heading", [],
+ [{heading,"This is a heading"}]),
+ ct:log(ct_internal, "23. Printing with category and heading", [],
+ [{heading,"This is a heading"}]),
+ ct:log(50, "24. Printing with importance and heading", [],
+ [{heading,"This is a heading"}]),
+ ct:log(ct_internal, 50, "25. Printing with category, importance and heading", [],
+ [{heading,"This is a heading"}]),
+
%% END mark
ct:log("LOGGING END", [], [no_css]),
+
+
+ %% ct:print
+ ct:print("1. Does this show??"),
+ ct:print("2. Does this ~s", ["show??"]),
+ ct:print("3. Is this a non-html pid?? ~w", [self()]),
+ ct:print(ct_internal, "4. Printing with category"),
+ ct:print(ct_internal, "5. Printing with ~s", ["category"]),
+ ct:print(50, "6. Printing with importance"),
+ ct:print(50, "7. Printing with ~s", ["importance"]),
+ ct:print(ct_internal, 50, "8. Printing with ~s", ["category and importance"]),
+ ct:print("9. Printing with heading", [],
+ [{heading,"This is a heading"}]),
+ ct:print(ct_internal, "10. Printing with category and heading", [],
+ [{heading,"This is a heading"}]),
+ ct:print(50, "11. Printing with importance and heading", [],
+ [{heading,"This is a heading"}]),
+ ct:print(ct_internal, 50, "12. Printing with category, importance and heading", [],
+ [{heading,"This is a heading"}]),
+
{save_config,[{the_logfile,TcLogFile},{the_pid,Pid},{the_string,String}]}.
@@ -169,6 +180,8 @@ verify(Config) ->
{ok,Dev} = file:open(TcLogFile, [read]),
ok = read_until(Dev, "LOGGING START\n"),
+ ct:pal("VERIFYING LOG ENTRIES...", []),
+
%% io:format
match_line(Dev, "1. Printing nothing", []),
read_nl(Dev),
@@ -182,6 +195,7 @@ verify(Config) ->
read_nl(Dev),
match_line(Dev, "6. Printing HTML: &lt;pre&gt;~s&lt;/pre&gt;", [String]),
read_nl(Dev),
+
%% ct:pal
read_header(Dev),
match_line(Dev, "1. Printing nothing", []),
@@ -219,6 +233,19 @@ verify(Config) ->
read_header(Dev, "\"ct_internal\""),
match_line(Dev, "12. Printing with ~s", ["category and importance"]),
read_footer(Dev),
+ read_header(Dev, "\"default\"", "This is a heading"),
+ match_line(Dev, "13. Printing with heading", []),
+ read_footer(Dev),
+ read_header(Dev, "\"ct_internal\"", "This is a heading"),
+ match_line(Dev, "14. Printing with category and heading", []),
+ read_footer(Dev),
+ read_header(Dev, "\"default\"", "This is a heading"),
+ match_line(Dev, "15. Printing with importance and heading", []),
+ read_footer(Dev),
+ read_header(Dev, "\"ct_internal\"", "This is a heading"),
+ match_line(Dev, "16. Printing with category, importance and heading", []),
+ read_footer(Dev),
+
%% ct:log
read_header(Dev),
match_line(Dev, "1. Printing nothing", []),
@@ -275,7 +302,18 @@ verify(Config) ->
read_footer(Dev),
match_line(Dev, "21. Printing a pid escaped with ~s, no_css: ~s",
["category and importance",EscPid]),
-
+ read_header(Dev, "\"default\"", "This is a heading"),
+ match_line(Dev, "22. Printing with heading", []),
+ read_footer(Dev),
+ read_header(Dev, "\"ct_internal\"", "This is a heading"),
+ match_line(Dev, "23. Printing with category and heading", []),
+ read_footer(Dev),
+ read_header(Dev, "\"default\"", "This is a heading"),
+ match_line(Dev, "24. Printing with importance and heading", []),
+ read_footer(Dev),
+ read_header(Dev, "\"ct_internal\"", "This is a heading"),
+ match_line(Dev, "25. Printing with category, importance and heading", []),
+ read_footer(Dev),
file:close(Dev),
ok.
@@ -298,29 +336,51 @@ read_until(Dev, Pat) ->
match_line(Dev, Format, Args) ->
Pat = lists:flatten(io_lib:format(Format, Args)),
Line = element(2, file:read_line(Dev)),
+
+ %% for debugging purposes:
+ ct:pal("L: ~tp", [Line], [no_css]),
+
case re:run(Line, Pat) of
{match,_} ->
ok;
nomatch ->
- ct:pal("ERROR! No match for ~p.\nLine = ~p", [Pat,Line]),
+ ct:pal("ERROR! No match for ~p", [Pat]),
file:close(Dev),
ct:fail({mismatch,Pat,Line})
end.
read_header(Dev) ->
- read_header(Dev, "\"default\"").
+ read_header(Dev, "\"default\"", "User").
read_header(Dev, Cat) ->
+ read_header(Dev, Cat, "User").
+
+read_header(Dev, Cat, Heading) ->
file:read_line(Dev), % \n
"</pre>\n" = element(2, file:read_line(Dev)),
- {match,_} =
- re:run(element(2, file:read_line(Dev)), "<div class="++Cat++"><pre><b>"
- "\\*\\*\\* User \\d{4}-\\d{2}-\\d{2} "
- "\\d{2}:\\d{2}:\\d{2}.\\d{1,} \\*\\*\\*</b>").
+ {ok,Hd} = file:read_line(Dev),
+
+ %% for debugging purposes:
+ ct:pal("H: ~tp", [Hd], [no_css]),
+
+ Pat = "<div class="++Cat++"><pre><b>"++
+ "\\*\\*\\* "++Heading++" \\d{4}-\\d{2}-\\d{2} "++
+ "\\d{2}:\\d{2}:\\d{2}.\\d{1,} \\*\\*\\*</b>",
+
+ case re:run(Hd, Pat) of
+ {match,_} ->
+ ok;
+ _ ->
+ ct:pal("ERROR! No match for ~p", [Pat]),
+ file:close(Dev),
+ ct:fail({mismatch,Pat,Hd})
+ end.
read_footer(Dev) ->
"</pre></div>\n" = element(2, file:read_line(Dev)),
- "<pre>\n" = element(2, file:read_line(Dev)).
+ "<pre>\n" = element(2, file:read_line(Dev)),
+ %% for debugging purposes:
+ ct:pal("F: </pre></div><pre>", [], [no_css]).
read_nl(Dev) ->
file:read_line(Dev).
diff --git a/lib/common_test/test/ct_netconfc_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE.erl
index 8932f930d1..e8c7b65140 100644
--- a/lib/common_test/test/ct_netconfc_SUITE.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -52,9 +52,8 @@ init_per_suite(Config) ->
end.
check_crypto_and_ssh() ->
- (catch code:load_file(crypto)),
- case code:is_loaded(crypto) of
- {file,_} ->
+ case code:ensure_loaded(crypto) of
+ {module,_} ->
case catch ssh:start() of
Ok when Ok==ok; Ok=={error,{already_started,ssh}} ->
ct:log("ssh started",[]),
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
index 2aa6c4d354..586589ad40 100644
--- a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -102,7 +102,9 @@ all() ->
receive_one_event,
receive_multiple_events,
receive_event_and_rpc,
- receive_event_and_rpc_in_chunks
+ receive_event_and_rpc_in_chunks,
+ multiple_channels,
+ kill_session_same_connection
]
end.
@@ -124,7 +126,7 @@ end_per_testcase(_Case, _Config) ->
ok.
init_per_suite(Config) ->
- (catch code:load_file(crypto)),
+ code:ensure_loaded(crypto),
case {ssh:start(),code:is_loaded(crypto)} of
{Ok,{file,_}} when Ok==ok; Ok=={error,{already_started,ssh}} ->
ct:log("ssh started",[]),
@@ -498,10 +500,11 @@ kill_session(Config) ->
?NS:hello(2),
?NS:expect(2,hello),
- {ok,_OtherClient} = open(SshDir),
+ {ok,OtherClient} = open(SshDir),
?NS:expect_do_reply('kill-session',{kill,2},ok),
?ok = ct_netconfc:kill_session(Client,2),
+ {error,_}=ct_netconfc:get(OtherClient,{server,[{xmlns,"myns"}],[]}),
?NS:expect_do_reply('close-session',close,ok),
?ok = ct_netconfc:close_session(Client),
@@ -1179,13 +1182,73 @@ receive_event_and_rpc_in_chunks(Config) ->
?ok = ct_netconfc:close_session(Client),
ok.
+multiple_channels(Config) ->
+ SshDir = ?config(ssh_dir,Config),
+ SshOpts = ?DEFAULT_SSH_OPTS(SshDir),
+ {ok,Conn} = ct_netconfc:connect(SshOpts),
+ ?NS:hello(1),
+ ?NS:expect(hello),
+ {ok,Client1} = ct_netconfc:session(Conn),
+ ?NS:hello(2),
+ ?NS:expect(2,hello),
+ {ok,Client2} = ct_netconfc:session(Conn),
+ ?NS:hello(3),
+ ?NS:expect(3,hello),
+ {ok,Client3} = ct_netconfc:session(Conn),
+
+ Data = [{server,[{xmlns,"myns"}],[{name,[],["myserver"]}]}],
+ ?NS:expect_reply(1,'get',{data,Data}),
+ {ok,Data} = ct_netconfc:get(Client1,{server,[{xmlns,"myns"}],[]}),
+ ?NS:expect_reply(2,'get',{data,Data}),
+ {ok,Data} = ct_netconfc:get(Client2,{server,[{xmlns,"myns"}],[]}),
+ ?NS:expect_reply(3,'get',{data,Data}),
+ {ok,Data} = ct_netconfc:get(Client3,{server,[{xmlns,"myns"}],[]}),
+
+ ?NS:expect_do_reply(2,'close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client2),
+
+ ?NS:expect_reply(1,'get',{data,Data}),
+ {ok,Data} = ct_netconfc:get(Client1,{server,[{xmlns,"myns"}],[]}),
+ {error,no_such_client}=ct_netconfc:get(Client2,{server,[{xmlns,"myns"}],[]}),
+ ?NS:expect_reply(3,'get',{data,Data}),
+ {ok,Data} = ct_netconfc:get(Client3,{server,[{xmlns,"myns"}],[]}),
+
+ ?NS:expect_do_reply(1,'close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client1),
+ ?NS:expect_do_reply(3,'close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client3),
+
+ ?ok = ct_netconfc:disconnect(Conn),
+ ok.
+
+kill_session_same_connection(Config) ->
+ SshDir = ?config(ssh_dir,Config),
+ SshOpts = ?DEFAULT_SSH_OPTS(SshDir),
+ {ok,Conn} = ct_netconfc:connect(SshOpts),
+ ?NS:hello(1),
+ ?NS:expect(hello),
+ {ok,Client1} = ct_netconfc:session(Conn),
+ ?NS:hello(2),
+ ?NS:expect(2,hello),
+ {ok,Client2} = ct_netconfc:session(Conn),
+
+ ?NS:expect_do_reply('kill-session',{kill,2},ok),
+ ?ok = ct_netconfc:kill_session(Client1,2),
+ timer:sleep(1000),
+ {error,no_such_client}=ct_netconfc:get(Client2,{server,[{xmlns,"myns"}],[]}),
+
+ ?NS:expect_do_reply('close-session',close,ok),
+ ?ok = ct_netconfc:close_session(Client1),
+
+ ok.
+
%%%-----------------------------------------------------------------
break(_Config) ->
- test_server:break("break test case").
+ ct:break("break test case").
br() ->
- test_server:break("").
+ ct:break("").
%%%-----------------------------------------------------------------
%% Open a netconf session which is not specified in a config file
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl
index a65275da43..cbdb4cf11a 100644
--- a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2014-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -62,7 +62,7 @@ stop_node(Case) ->
init_per_suite(Config) ->
- (catch code:load_file(crypto)),
+ code:ensure_loaded(crypto),
case {ssh:start(),code:is_loaded(crypto)} of
{Ok,{file,_}} when Ok==ok; Ok=={error,{already_started,ssh}} ->
ct:log("SSH started locally",[]),
@@ -83,7 +83,9 @@ end_per_suite(Config) ->
%% Running the netconf server in a remote node, test that the client
%% process terminates if the remote node goes down.
remote_crash(Config) ->
- {ok,Node} = ct_slave:start(nc_remote_crash),
+ {ok,Node} = ct_slave:start(nc_remote_crash,[{boot_timeout,15},
+ {init_timeout,15},
+ {startup_timeout,15}]),
Pa = filename:dirname(code:which(?NS)),
true = rpc:call(Node,code,add_patha,[Pa]),
rpc:call(Node,code,load_file,[crypto]),
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl b/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl
index e62bc617fa..63bf9be134 100644
--- a/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -254,7 +254,7 @@ data(Data, State = #session{connection = ConnRef,
end.
stop_channel(CM, Ch, State) ->
- ssh:close(CM),
+ ssh_connection:close(CM,Ch),
{stop, Ch, State}.
@@ -290,8 +290,8 @@ send_frag({CM,Ch},Data) ->
%%% Kill ssh connection
-kill({CM,_Ch}) ->
- ssh:close(CM).
+kill({CM,Ch}) ->
+ ssh_connection:close(CM,Ch).
add_expect(SessionId,Add) ->
table_trans(fun do_add_expect/2,[SessionId,Add]).
@@ -302,10 +302,14 @@ table_trans(Fun,Args) ->
S ->
apply(Fun,Args);
Pid ->
+ Ref = erlang:monitor(process,Pid),
Pid ! {table_trans,Fun,Args,self()},
receive
{table_trans_done,Result} ->
- Result
+ erlang:demonitor(Ref,[flush]),
+ Result;
+ {'DOWN',Ref,process,Pid,Reason} ->
+ exit({main_ns_proc_died,Reason})
after 20000 ->
exit(table_trans_timeout)
end
diff --git a/lib/common_test/test/ct_repeat_testrun_SUITE.erl b/lib/common_test/test/ct_repeat_testrun_SUITE.erl
index f8b6a379f6..9382e4c011 100644
--- a/lib/common_test/test/ct_repeat_testrun_SUITE.erl
+++ b/lib/common_test/test/ct_repeat_testrun_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -363,14 +363,17 @@ skip_first_tc1(Suite) ->
{?eh,tc_start,{Suite,tc1}},
{?eh,tc_done,{Suite,tc1,ok}},
{?eh,test_stats,{'_',0,{0,0}}},
+ {?eh,tc_start,{Suite,tc2}},
{?eh,tc_done,{Suite,tc2,?skipped}},
{?eh,test_stats,{'_',0,{0,1}}},
+ {?eh,tc_start,{Suite,{init_per_group,g,[]}}},
{?eh,tc_done,{Suite,{init_per_group,g,[]},?skipped}},
{?eh,tc_auto_skip,{Suite,{tc1,g},?skip_reason}},
{?eh,test_stats,{'_',0,{0,2}}},
{?eh,tc_auto_skip,{Suite,{tc2,g},?skip_reason}},
{?eh,test_stats,{'_',0,{0,3}}},
{?eh,tc_auto_skip,{Suite,{end_per_group,g},?skip_reason}},
+ {?eh,tc_start,{Suite,tc2}},
{?eh,tc_done,{Suite,tc2,?skipped}},
{?eh,test_stats,{'_',0,{0,4}}},
{?eh,tc_start,{Suite,end_per_suite}},
@@ -390,10 +393,12 @@ skip_tc1_in_group(Suite) ->
{?eh,tc_start,{Suite,tc1}},
{?eh,tc_done,{Suite,tc1,ok}},
{?eh,test_stats,{'_',0,{0,0}}},
+ {?eh,tc_start,{Suite,tc2}},
{?eh,tc_done,{Suite,tc2,?skipped}},
{?eh,test_stats,{'_',0,{0,1}}},
{?eh,tc_start,{Suite,{end_per_group,g,[]}}},
{?eh,tc_done,{Suite,{end_per_group,g,[]},ok}}],
+ {?eh,tc_start,{Suite,tc2}},
{?eh,tc_done,{Suite,tc2,?skipped}},
{?eh,test_stats,{'_',0,{0,2}}},
{?eh,tc_start,{Suite,end_per_suite}},
diff --git a/lib/common_test/test/ct_surefire_SUITE.erl b/lib/common_test/test/ct_surefire_SUITE.erl
index 42ec685c16..a71288fb12 100644
--- a/lib/common_test/test/ct_surefire_SUITE.erl
+++ b/lib/common_test/test/ct_surefire_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -73,7 +73,9 @@ all() ->
relative_path,
url,
logdir,
- fail_pre_init_per_suite
+ fail_pre_init_per_suite,
+ skip_case_in_spec,
+ skip_suite_in_spec
].
%%--------------------------------------------------------------------
@@ -119,6 +121,18 @@ fail_pre_init_per_suite(Config) when is_list(Config) ->
run(fail_pre_init_per_suite,[fail_pre_init_per_suite,
{cth_surefire,[{path,Path}]}],Path,Config,[],Suites).
+skip_case_in_spec(Config) ->
+ DataDir = ?config(data_dir,Config),
+ Spec = filename:join(DataDir,"skip_one_case.spec"),
+ Path = "skip_case_in_spec.xml",
+ run_spec(skip_case_in_spec,[{cth_surefire,[{path,Path}]}],Path,Config,Spec).
+
+skip_suite_in_spec(Config) ->
+ DataDir = ?config(data_dir,Config),
+ Spec = filename:join(DataDir,"skip_one_suite.spec"),
+ Path = "skip_suite_in_spec.xml",
+ run_spec(skip_suite_in_spec,[{cth_surefire,[{path,Path}]}],Path,Config,Spec).
+
%%%-----------------------------------------------------------------
%%% HELP FUNCTIONS
%%%-----------------------------------------------------------------
@@ -129,8 +143,15 @@ run(Case,CTHs,Report,Config,ExtraOpts) ->
Suite = filename:join(DataDir, "surefire_SUITE"),
run(Case,CTHs,Report,Config,ExtraOpts,Suite).
run(Case,CTHs,Report,Config,ExtraOpts,Suite) ->
- {Opts,ERPid} = setup([{suite,Suite},{ct_hooks,CTHs},{label,Case}|ExtraOpts],
- Config),
+ Test = [{suite,Suite},{ct_hooks,CTHs},{label,Case}|ExtraOpts],
+ do_run(Case, Report, Test, Config).
+
+run_spec(Case,CTHs,Report,Config,Spec) ->
+ Test = [{spec,Spec},{ct_hooks,CTHs},{label,Case}],
+ do_run(Case, Report, Test, Config).
+
+do_run(Case, Report, Test, Config) ->
+ {Opts,ERPid} = setup(Test, Config),
ok = execute(Case, Opts, ERPid, Config),
LogDir =
case lists:keyfind(logdir,1,Opts) of
@@ -201,7 +222,10 @@ test_suite_events(pass_SUITE) ->
{?eh,test_stats,{1,0,{0,0}}},
{?eh,tc_start,{ct_framework,end_per_suite}},
{?eh,tc_done,{ct_framework,end_per_suite,ok}}];
-test_suite_events(_) ->
+test_suite_events(skip_all_surefire_SUITE) ->
+ [{?eh,tc_user_skip,{skip_all_surefire_SUITE,all,"skipped in spec"}},
+ {?eh,test_stats,{0,0,{1,0}}}];
+test_suite_events(Test) ->
[{?eh,tc_start,{surefire_SUITE,init_per_suite}},
{?eh,tc_done,{surefire_SUITE,init_per_suite,ok}},
{?eh,tc_start,{surefire_SUITE,tc_ok}},
@@ -210,46 +234,55 @@ test_suite_events(_) ->
{?eh,tc_start,{surefire_SUITE,tc_fail}},
{?eh,tc_done,{surefire_SUITE,tc_fail,
{failed,{error,{test_case_failed,"this test should fail"}}}}},
- {?eh,test_stats,{1,1,{0,0}}},
- {?eh,tc_start,{surefire_SUITE,tc_skip}},
- {?eh,tc_done,{surefire_SUITE,tc_skip,{skipped,"this test is skipped"}}},
- {?eh,test_stats,{1,1,{1,0}}},
- {?eh,tc_start,{surefire_SUITE,tc_autoskip_require}},
- {?eh,tc_done,{surefire_SUITE,tc_autoskip_require,
- {auto_skipped,{require_failed,'_'}}}},
- {?eh,test_stats,{1,1,{1,1}}},
- [{?eh,tc_start,{surefire_SUITE,{init_per_group,g,[]}}},
- {?eh,tc_done,{surefire_SUITE,{init_per_group,g,[]},ok}},
- {?eh,tc_start,{surefire_SUITE,tc_ok}},
- {?eh,tc_done,{surefire_SUITE,tc_ok,ok}},
- {?eh,test_stats,{2,1,{1,1}}},
- {?eh,tc_start,{surefire_SUITE,tc_fail}},
- {?eh,tc_done,{surefire_SUITE,tc_fail,
- {failed,{error,{test_case_failed,"this test should fail"}}}}},
- {?eh,test_stats,{2,2,{1,1}}},
- {?eh,tc_start,{surefire_SUITE,tc_skip}},
- {?eh,tc_done,{surefire_SUITE,tc_skip,{skipped,"this test is skipped"}}},
- {?eh,test_stats,{2,2,{2,1}}},
- {?eh,tc_start,{surefire_SUITE,tc_autoskip_require}},
- {?eh,tc_done,{surefire_SUITE,tc_autoskip_require,
- {auto_skipped,{require_failed,'_'}}}},
- {?eh,test_stats,{2,2,{2,2}}},
- {?eh,tc_start,{surefire_SUITE,{end_per_group,g,[]}}},
- {?eh,tc_done,{surefire_SUITE,{end_per_group,g,[]},ok}}],
- [{?eh,tc_start,{surefire_SUITE,{init_per_group,g_fail,[]}}},
- {?eh,tc_done,{surefire_SUITE,{init_per_group,g_fail,[]},
- {failed,{error,all_cases_should_be_skipped}}}},
- {?eh,tc_auto_skip,{surefire_SUITE,{tc_ok,g_fail},
- {failed,
- {surefire_SUITE,init_per_group,
- {'EXIT',all_cases_should_be_skipped}}}}},
- {?eh,test_stats,{2,2,{2,3}}},
- {?eh,tc_auto_skip,{surefire_SUITE,{end_per_group,g_fail},
- {failed,
- {surefire_SUITE,init_per_group,
- {'EXIT',all_cases_should_be_skipped}}}}}],
- {?eh,tc_start,{surefire_SUITE,end_per_suite}},
- {?eh,tc_done,{surefire_SUITE,end_per_suite,ok}}].
+ {?eh,test_stats,{1,1,{0,0}}}] ++
+ tc_skip_events(Test,undefined) ++
+ [{?eh,test_stats,{1,1,{1,0}}},
+ {?eh,tc_start,{surefire_SUITE,tc_autoskip_require}},
+ {?eh,tc_done,{surefire_SUITE,tc_autoskip_require,
+ {auto_skipped,{require_failed,'_'}}}},
+ {?eh,test_stats,{1,1,{1,1}}},
+ [{?eh,tc_start,{surefire_SUITE,{init_per_group,g,[]}}},
+ {?eh,tc_done,{surefire_SUITE,{init_per_group,g,[]},ok}},
+ {?eh,tc_start,{surefire_SUITE,tc_ok}},
+ {?eh,tc_done,{surefire_SUITE,tc_ok,ok}},
+ {?eh,test_stats,{2,1,{1,1}}},
+ {?eh,tc_start,{surefire_SUITE,tc_fail}},
+ {?eh,tc_done,{surefire_SUITE,tc_fail,
+ {failed,{error,{test_case_failed,"this test should fail"}}}}},
+ {?eh,test_stats,{2,2,{1,1}}}] ++
+ tc_skip_events(Test,g) ++
+ [{?eh,test_stats,{2,2,{2,1}}},
+ {?eh,tc_start,{surefire_SUITE,tc_autoskip_require}},
+ {?eh,tc_done,{surefire_SUITE,tc_autoskip_require,
+ {auto_skipped,{require_failed,'_'}}}},
+ {?eh,test_stats,{2,2,{2,2}}},
+ {?eh,tc_start,{surefire_SUITE,{end_per_group,g,[]}}},
+ {?eh,tc_done,{surefire_SUITE,{end_per_group,g,[]},ok}}],
+ [{?eh,tc_start,{surefire_SUITE,{init_per_group,g_fail,[]}}},
+ {?eh,tc_done,{surefire_SUITE,{init_per_group,g_fail,[]},
+ {failed,{error,all_cases_should_be_skipped}}}},
+ {?eh,tc_auto_skip,{surefire_SUITE,{tc_ok,g_fail},
+ {failed,
+ {surefire_SUITE,init_per_group,
+ {'EXIT',all_cases_should_be_skipped}}}}},
+ {?eh,test_stats,{2,2,{2,3}}},
+ {?eh,tc_auto_skip,{surefire_SUITE,{end_per_group,g_fail},
+ {failed,
+ {surefire_SUITE,init_per_group,
+ {'EXIT',all_cases_should_be_skipped}}}}}],
+ {?eh,tc_start,{surefire_SUITE,end_per_suite}},
+ {?eh,tc_done,{surefire_SUITE,end_per_suite,ok}}].
+
+tc_skip_events(skip_case_in_spec,Group) ->
+ [{?eh,tc_user_skip,{surefire_SUITE,tc_skip_name(Group),"skipped in spec"}}];
+tc_skip_events(_Test,_Group) ->
+ [{?eh,tc_start,{surefire_SUITE,tc_skip}},
+ {?eh,tc_done,{surefire_SUITE,tc_skip,{skipped,"this test is skipped"}}}].
+
+tc_skip_name(undefined) ->
+ tc_skip;
+tc_skip_name(Group) ->
+ {tc_skip,Group}.
test_events(fail_pre_init_per_suite) ->
[{?eh,start_logging,{'DEF','RUNDIR'}},
@@ -257,6 +290,10 @@ test_events(fail_pre_init_per_suite) ->
test_suite_events(pass_SUITE) ++
test_suite_events(fail_SUITE, {1,0,{0,1}}) ++
[{?eh,stop_logging,[]}];
+test_events(skip_suite_in_spec) ->
+ [{?eh,start_logging,'_'},{?eh,start_info,{1,1,0}}] ++
+ test_suite_events(skip_all_surefire_SUITE) ++
+ [{?eh,stop_logging,[]}];
test_events(Test) ->
[{?eh,start_logging,'_'}, {?eh,start_info,{1,1,9}}] ++
test_suite_events(Test) ++
@@ -267,7 +304,7 @@ test_events(Test) ->
check_xml(Case,XmlRe) ->
case filelib:wildcard(XmlRe) of
[] ->
- ct:fail("No xml files found with regexp ~p~n", [XmlRe]);
+ ct:fail("No xml files found with regexp ~tp~n", [XmlRe]);
[_] = Xmls when Case==absolute_path ->
do_check_xml(Case,Xmls);
[_,_] = Xmls ->
@@ -289,12 +326,12 @@ check_xml(Case,XmlRe) ->
%% ...
%% </testsuites>
do_check_xml(Case,[Xml|Xmls]) ->
- ct:log("Checking <a href=~p>~s</a>~n",[Xml,Xml]),
+ ct:log("Checking <a href=~tp>~ts</a>~n",[Xml,Xml]),
{E,_} = xmerl_scan:file(Xml),
Expected = events_to_result(lists:flatten(test_events(Case))),
ParseResult = testsuites(Case,E),
- ct:log("Expecting: ~p~n",[Expected]),
- ct:log("Actual : ~p~n",[ParseResult]),
+ ct:log("Expecting: ~tp~n",[Expected]),
+ ct:log("Actual : ~tp~n",[ParseResult]),
Expected = ParseResult,
do_check_xml(Case,Xmls);
do_check_xml(_,[]) ->
@@ -364,6 +401,8 @@ failed_or_skipped([]) ->
events_to_result(E) ->
events_to_result(E, []).
+events_to_result([{?eh,tc_user_skip,{_Suite,all,_}}|E], Result) ->
+ events_to_result(E, [[[s]]|Result]);
events_to_result([{?eh,tc_auto_skip,{_Suite,init_per_suite,_}}|E], Result) ->
{Suite,Rest} = events_to_result1(E),
events_to_result(Rest, [[[s]|Suite]|Result]);
@@ -382,7 +421,7 @@ events_to_result1([{?eh,tc_done,{_Suite, end_per_suite,R}}|E]) ->
events_to_result1([{?eh,tc_done,{_Suite,_Case,R}}|E]) ->
{Suite,Rest} = events_to_result1(E),
{[result(R)|Suite],Rest};
-events_to_result1([{?eh,tc_auto_skip,_}|E]) ->
+events_to_result1([{?eh,Skip,_}|E]) when Skip==tc_auto_skip; Skip==tc_user_skip ->
{Suite,Rest} = events_to_result1(E),
{[[s]|Suite],Rest};
events_to_result1([_|E]) ->
diff --git a/lib/common_test/test/ct_surefire_SUITE_data/skip_one_case.spec b/lib/common_test/test/ct_surefire_SUITE_data/skip_one_case.spec
new file mode 100644
index 0000000000..42df8a7d1a
--- /dev/null
+++ b/lib/common_test/test/ct_surefire_SUITE_data/skip_one_case.spec
@@ -0,0 +1,2 @@
+{suites,".",surefire_SUITE}.
+{skip_cases,".",surefire_SUITE,tc_skip,"skipped in spec"}.
diff --git a/lib/common_test/test/ct_surefire_SUITE_data/skip_one_suite.spec b/lib/common_test/test/ct_surefire_SUITE_data/skip_one_suite.spec
new file mode 100644
index 0000000000..57966328ab
--- /dev/null
+++ b/lib/common_test/test/ct_surefire_SUITE_data/skip_one_suite.spec
@@ -0,0 +1,2 @@
+{suites,".",[skip_all_surefire_SUITE]}.
+{skip_suites,".",skip_all_surefire_SUITE,"skipped in spec"}.
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE.erl
index 228d900545..0455313669 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -161,6 +161,7 @@ test_events(ts_if_1) ->
{?eh,tc_start,{ts_if_1_SUITE,tc4}},
{?eh,tc_done,{ts_if_1_SUITE,tc4,{failed,{error,failed_on_purpose}}}},
{?eh,test_stats,{1,2,{0,1}}},
+ {?eh,tc_start,{ts_if_1_SUITE,tc5}},
{?eh,tc_done,{ts_if_1_SUITE,tc5,{auto_skipped,{sequence_failed,seq1,tc4}}}},
{?eh,test_stats,{1,2,{0,2}}},
diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl
index e926abd885..44c27e54c2 100644
--- a/lib/common_test/test/ct_test_support.erl
+++ b/lib/common_test/test/ct_test_support.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -45,6 +45,8 @@
-export([unique_timestamp/0]).
+-export([rm_dir/1]).
+
-include_lib("kernel/include/file.hrl").
%%%-----------------------------------------------------------------
@@ -65,7 +67,7 @@ init_per_suite(Config, Level) ->
end,
case delete_old_logs(os:type(), Config) of
{'EXIT',DelLogsReason} ->
- test_server:format(0, "Failed to delete old log directories: ~p~n",
+ test_server:format(0, "Failed to delete old log directories: ~tp~n",
[DelLogsReason]);
_ ->
ok
@@ -89,7 +91,8 @@ start_slave(NodeName, Config, Level) ->
[_,Host] = string:tokens(atom_to_list(node()), "@"),
test_server:format(0, "Trying to start ~s~n",
[atom_to_list(NodeName)++"@"++Host]),
- case slave:start(Host, NodeName, []) of
+ PR = proplists:get_value(printable_range,Config,io:printable_range()),
+ case slave:start(Host, NodeName, "+pc " ++ atom_to_list(PR)) of
{error,Reason} ->
test_server:fail(Reason);
{ok,CTNode} ->
@@ -117,7 +120,7 @@ start_slave(NodeName, Config, Level) ->
[true = rpc:call(CTNode, code, add_patha, [D]) || D <- PathDirs],
test_server:format(Level, "Dirs added to code path (on ~w):~n",
[CTNode]),
- [io:format("~s~n", [D]) || D <- PathDirs],
+ [io:format("~ts~n", [D]) || D <- PathDirs],
case proplists:get_value(start_sasl, Config) of
true ->
@@ -159,12 +162,12 @@ init_per_testcase(_TestCase, Config) ->
case lists:keysearch(master, 1, Config) of
false->
test_server:format("See Common Test logs here:\n\n"
- "<a href=\"file://~s/all_runs.html\">~s/all_runs.html</a>\n"
- "<a href=\"file://~s/index.html\">~s/index.html</a>",
+ "<a href=\"file://~ts/all_runs.html\">~ts/all_runs.html</a>\n"
+ "<a href=\"file://~ts/index.html\">~ts/index.html</a>",
[LogDir,LogDir,LogDir,LogDir]);
{value, _}->
test_server:format("See CT Master Test logs here:\n\n"
- "<a href=\"file://~s/master_runs.html\">~s/master_runs.html</a>",
+ "<a href=\"file://~ts/master_runs.html\">~ts/master_runs.html</a>",
[LogDir,LogDir])
end,
Config.
@@ -190,11 +193,11 @@ write_testspec(TestSpec, Dir, Name) ->
write_testspec(TestSpec, filename:join(Dir, Name)).
write_testspec(TestSpec, TSFile) ->
- {ok,Dev} = file:open(TSFile, [write]),
- [io:format(Dev, "~p.~n", [Entry]) || Entry <- TestSpec],
+ {ok,Dev} = file:open(TSFile, [write,{encoding,utf8}]),
+ [io:format(Dev, "~tp.~n", [Entry]) || Entry <- TestSpec],
file:close(Dev),
- io:format("Test specification written to: ~p~n", [TSFile]),
- io:format(user, "Test specification written to: ~p~n", [TSFile]),
+ io:format("Test specification written to: ~tp~n", [TSFile]),
+ io:format(user, "Test specification written to: ~tp~n", [TSFile]),
TSFile.
@@ -267,7 +270,7 @@ run(Opts0, Config) when is_list(Opts0) ->
Override =
fun(O={Key,_}, Os) ->
io:format(user, "ADDING START "
- "OPTION: ~p~n", [O]),
+ "OPTION: ~tp~n", [O]),
[O | lists:keydelete(Key, 1, Os)]
end,
lists:foldl(Override, Opts0, OROpts);
@@ -289,14 +292,14 @@ run(Opts0, Config) when is_list(Opts0) ->
run_ct_run_test(Opts,Config) ->
CTNode = proplists:get_value(ct_node, Config),
Level = proplists:get_value(trace_level, Config),
- test_server:format(Level, "~n[RUN #1] Calling ct:run_test(~p) on ~p~n",
+ test_server:format(Level, "~n[RUN #1] Calling ct:run_test(~tp) on ~p~n",
[Opts, CTNode]),
T0 = erlang:monotonic_time(),
CtRunTestResult = rpc:call(CTNode, ct, run_test, [Opts]),
T1 = erlang:monotonic_time(),
Elapsed = erlang:convert_time_unit(T1-T0, native, milli_seconds),
- test_server:format(Level, "~n[RUN #1] Got return value ~p after ~p ms~n",
+ test_server:format(Level, "~n[RUN #1] Got return value ~tp after ~p ms~n",
[CtRunTestResult,Elapsed]),
case rpc:call(CTNode, erlang, whereis, [ct_util_server]) of
undefined ->
@@ -314,7 +317,7 @@ run_ct_script_start(Opts, Config) ->
CTNode = proplists:get_value(ct_node, Config),
Level = proplists:get_value(trace_level, Config),
Opts1 = [{halt_with,{?MODULE,ct_test_halt}} | Opts],
- test_server:format(Level, "Saving start opts on ~p: ~p~n",
+ test_server:format(Level, "Saving start opts on ~p: ~tp~n",
[CTNode, Opts1]),
rpc:call(CTNode, application, set_env,
[common_test, run_test_start_opts, Opts1]),
@@ -324,7 +327,7 @@ run_ct_script_start(Opts, Config) ->
ExitStatus = rpc:call(CTNode, ct_run, script_start, []),
T1 = erlang:monotonic_time(),
Elapsed = erlang:convert_time_unit(T1-T0, native, milli_seconds),
- test_server:format(Level, "[RUN #2] Got exit status value ~p after ~p ms~n",
+ test_server:format(Level, "[RUN #2] Got exit status value ~tp after ~p ms~n",
[ExitStatus,Elapsed]),
ExitStatus.
@@ -351,6 +354,9 @@ check_result(CtRunTestResult,ExitStatus,Opts)
catch _:_ ->
{error,{unexpected_return_value,{CtRunTestResult,ExitStatus}}}
end;
+check_result(done,0,_Opts) ->
+ %% refresh_logs return
+ ok;
check_result(CtRunTestResult,ExitStatus,_Opts) ->
{error,{unexpected_return_value,{CtRunTestResult,ExitStatus}}}.
@@ -367,12 +373,12 @@ run({M,F,A}, InitCalls, Config) ->
Level = proplists:get_value(trace_level, Config),
lists:foreach(
fun({IM,IF,IA}) ->
- test_server:format(Level, "~nInit call ~w:~w(~p) on ~p...~n",
+ test_server:format(Level, "~nInit call ~w:~tw(~tp) on ~p...~n",
[IM, IF, IA, CTNode]),
Result = rpc:call(CTNode, IM, IF, IA),
- test_server:format(Level, "~n...with result: ~p~n", [Result])
+ test_server:format(Level, "~n...with result: ~tp~n", [Result])
end, InitCalls),
- test_server:format(Level, "~nStarting test with ~w:~w(~p) on ~p~n",
+ test_server:format(Level, "~nStarting test with ~w:~tw(~tp) on ~p~n",
[M, F, A, CTNode]),
rpc:call(CTNode, M, F, A).
@@ -399,7 +405,7 @@ wait_for_ct_stop(Retries, CTNode) ->
Info = (catch process_info(Pid)),
test_server:format(0, "Waiting for CT (~p) to finish (~p)...",
[Pid,Retries]),
- test_server:format(0, "Process info for ~p:~n~p", [Info]),
+ test_server:format(0, "Process info for ~p:~n~tp", [Pid,Info]),
timer:sleep(5000),
wait_for_ct_stop(Retries-1, CTNode)
end.
@@ -409,7 +415,7 @@ wait_for_ct_stop(Retries, CTNode) ->
ct_rpc({M,F,A}, Config) ->
CTNode = proplists:get_value(ct_node, Config),
Level = proplists:get_value(trace_level, Config),
- test_server:format(Level, "~nCalling ~w:~w(~p) on ~p...",
+ test_server:format(Level, "~nCalling ~w:~tw(~tp) on ~p...",
[M,F,A, CTNode]),
rpc:call(CTNode, M, F, A).
@@ -525,7 +531,7 @@ verify_events(TEvs, Evs, Node, Config) ->
verify_events1([TestEv|_], [{TEH,#event{name=stop_logging,node=Node,data=_}}|_], Node, _)
when element(1,TestEv) == TEH, element(2,TestEv) =/= stop_logging ->
- test_server:format("Failed to find ~p in the list of events!~n", [TestEv]),
+ test_server:format("Failed to find ~tp in the list of events!~n", [TestEv]),
exit({event_not_found,TestEv});
verify_events1(TEvs = [TestEv | TestEvs], Evs = [_|Events], Node, Config) ->
@@ -533,8 +539,8 @@ verify_events1(TEvs = [TestEv | TestEvs], Evs = [_|Events], Node, Config) ->
nomatch ->
verify_events1(TEvs, Events, Node, Config);
{'EXIT',Reason} ->
- test_server:format("Failed to find ~p in ~p~n"
- "Reason: ~p~n", [TestEv,Evs,Reason]),
+ test_server:format("Failed to find ~tp in ~tp~n"
+ "Reason: ~tp~n", [TestEv,Evs,Reason]),
exit(Reason);
{Config1,Events1} ->
if is_list(TestEv) ->
@@ -542,13 +548,13 @@ verify_events1(TEvs = [TestEv | TestEvs], Evs = [_|Events], Node, Config) ->
element(1,TestEv) == parallel ; element(1,TestEv) == shuffle ->
ok;
true ->
- test_server:format("Found ~p!", [TestEv])
+ test_server:format("Found ~tp!", [TestEv])
end,
verify_events1(TestEvs, Events1, Node, Config1)
end;
verify_events1([TestEv|_], [], _, _) ->
- test_server:format("Failed to find ~p in the list of events!~n", [TestEv]),
+ test_server:format("Failed to find ~tp in the list of events!~n", [TestEv]),
exit({event_not_found,TestEv});
verify_events1([], Evs, _, Config) ->
@@ -581,8 +587,8 @@ locate(TEvs, Node, Evs, Config) when is_list(TEvs) ->
false ->
nomatch;
true ->
- test_server:format("Found ~p!", [InitStart]),
- test_server:format("Found ~p!", [InitDone]),
+ test_server:format("Found ~tp!", [InitStart]),
+ test_server:format("Found ~tp!", [InitDone]),
verify_events1(TEvs1, Evs1, Node, Config)
end;
_ ->
@@ -630,8 +636,8 @@ locate({parallel,TEvs}, Node, Evs, Config) ->
true
end, Es),
- test_server:format("Found ~p!", [InitStart]),
- test_server:format("Found ~p!", [InitDone]),
+ test_server:format("Found ~tp!", [InitStart]),
+ test_server:format("Found ~tp!", [InitDone]),
{TEs,EvsG};
_ ->
nomatch
@@ -683,10 +689,10 @@ locate({parallel,TEvs}, Node, Evs, Config) ->
[] when Evs2 == [] ->
exit({unmatched,TEv});
[] ->
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
exit({tc_done_not_found,TEv});
[TcDone|Evs3] ->
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
RemSize1 = length(Evs3),
if RemSize1 < RemSize ->
{[TcDone|Done],Evs3,RemSize1};
@@ -702,7 +708,7 @@ locate({parallel,TEvs}, Node, Evs, Config) ->
EH == TEH, EvNode == Node, Mod == M,
Func == F, result_match(R, Result)] of
[TcDone|_] ->
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
{lists:delete(TcDone, Done),RemEvs,RemSize};
[] ->
exit({unmatched,TEv})
@@ -730,7 +736,7 @@ locate({parallel,TEvs}, Node, Evs, Config) ->
[] ->
exit({end_per_group_not_found,TEv});
[_ | RemEvs2] ->
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
{Done,RemEvs2,length(RemEvs2)}
end;
%% tc_done event for end_per_group
@@ -761,27 +767,27 @@ locate({parallel,TEvs}, Node, Evs, Config) ->
[] ->
exit({end_per_group_not_found,TEv});
[_ | RemEvs2] ->
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
{Done,RemEvs2,length(RemEvs2)}
end;
%% end_per_group auto- or user skipped
- (TEv={TEH,AutoOrUserSkip,{M,end_per_group,R}}, {Done,RemEvs,_RemSize})
+ (TEv={TEH,AutoOrUserSkip,{M,{end_per_group,G},R}}, {Done,RemEvs,_RemSize})
when AutoOrUserSkip == tc_auto_skip;
AutoOrUserSkip == tc_user_skip ->
RemEvs1 =
lists:dropwhile(
fun({EH,#event{name=tc_auto_skip,
node=EvNode,
- data={Mod,end_per_group,Reason}}}) when
- EH == TEH, EvNode == Node, Mod == M ->
+ data={Mod,{end_per_group,EvGroupName},Reason}}}) when
+ EH == TEH, EvNode == Node, Mod == M, EvGroupName == G ->
case match_data(R, Reason) of
match -> false;
_ -> true
end;
({EH,#event{name=tc_user_skip,
node=EvNode,
- data={Mod,end_per_group,Reason}}}) when
- EH == TEH, EvNode == Node, Mod == M ->
+ data={Mod,{end_per_group,EvGroupName},Reason}}}) when
+ EH == TEH, EvNode == Node, Mod == M, EvGroupName == G ->
case match_data(R, Reason) of
match -> false;
_ -> true
@@ -808,7 +814,7 @@ locate({parallel,TEvs}, Node, Evs, Config) ->
[] ->
exit({unmatched,TEv});
_ ->
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
Acc
end;
%% start of a sub-group
@@ -861,8 +867,8 @@ locate({shuffle,TEvs}, Node, Evs, Config) ->
_ ->
Props = EvProps
end,
- test_server:format("Found ~p!", [InitStart]),
- test_server:format("Found ~p!", [InitDone]),
+ test_server:format("Found ~tp!", [InitStart]),
+ test_server:format("Found ~tp!", [InitDone]),
{TEs,Es};
false ->
nomatch
@@ -903,7 +909,7 @@ locate({shuffle,TEvs}, Node, Evs, Config) ->
[_TcStart, TcDone={TEH,#event{name=tc_done,
node=Node,
data={M,F,_}}} | Evs3] ->
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
RemSize1 = length(Evs3),
if RemSize1 < RemSize ->
{[TcDone|Done],Evs3,RemSize1};
@@ -919,7 +925,7 @@ locate({shuffle,TEvs}, Node, Evs, Config) ->
EH == TEH, EvNode == Node, Mod == M,
Func == F, result_match(R, Result)] of
[TcDone|_] ->
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
{lists:delete(TcDone, Done),RemEvs,RemSize};
[] ->
exit({unmatched,TEv})
@@ -960,7 +966,7 @@ locate({shuffle,TEvs}, Node, Evs, Config) ->
_ ->
Props = EvProps1
end,
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
{Done,RemEvs2,length(RemEvs2)}
end;
%% tc_done event for end_per_group
@@ -1004,24 +1010,24 @@ locate({shuffle,TEvs}, Node, Evs, Config) ->
_ ->
Props = EvProps1
end,
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
{Done,RemEvs2,length(RemEvs2)}
end;
%% end_per_group auto-or user skipped
- (TEv={TEH,AutoOrUserSkip,{M,end_per_group,R}}, {Done,RemEvs,_RemSize})
+ (TEv={TEH,AutoOrUserSkip,{M,{end_per_group,G},R}}, {Done,RemEvs,_RemSize})
when AutoOrUserSkip == tc_auto_skip;
AutoOrUserSkip == tc_user_skip ->
RemEvs1 =
lists:dropwhile(
fun({EH,#event{name=tc_auto_skip,
node=EvNode,
- data={Mod,end_per_group,Reason}}}) when
- EH == TEH, EvNode == Node, Mod == M, Reason == R ->
+ data={Mod,{end_per_group,EvGroupName},Reason}}}) when
+ EH == TEH, EvNode == Node, Mod == M, EvGroupName == G, Reason == R ->
false;
({EH,#event{name=tc_user_skip,
node=EvNode,
- data={Mod,end_per_group,Reason}}}) when
- EH == TEH, EvNode == Node, Mod == M, Reason == R ->
+ data={Mod,{end_per_group,EvGroupName},Reason}}}) when
+ EH == TEH, EvNode == Node, Mod == M, EvGroupName == G, Reason == R ->
false;
({EH,#event{name=stop_logging,
node=EvNode,data=_}}) when
@@ -1045,7 +1051,7 @@ locate({shuffle,TEvs}, Node, Evs, Config) ->
[] ->
exit({unmatched,TEv});
_ ->
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
Acc
end;
(TEv={TEH,N,D}, Acc) ->
@@ -1056,7 +1062,7 @@ locate({shuffle,TEvs}, Node, Evs, Config) ->
[] ->
exit({unmatched,TEv});
_ ->
- test_server:format("Found ~p!", [TEv]),
+ test_server:format("Found ~tp!", [TEv]),
Acc
end;
%% start of a sub-group
@@ -1227,54 +1233,54 @@ result_match(_, _) ->
log_events(TC, Events, EvLogDir, Opts) ->
LogFile = filename:join(EvLogDir, atom_to_list(TC)++".events"),
- {ok,Dev} = file:open(LogFile, [write]),
+ {ok,Dev} = file:open(LogFile, [write,{encoding,utf8}]),
io:format(Dev, "[~n", []),
log_events1(Events, Dev, " "),
file:close(Dev),
FullLogFile = join_abs_dirs(proplists:get_value(net_dir, Opts),
LogFile),
- ct:log("Events written to logfile: <a href=\"file://~s\">~s</a>~n",
+ ct:log("Events written to logfile: <a href=\"file://~ts\">~ts</a>~n",
[FullLogFile,FullLogFile],[no_css]),
- io:format(user, "Events written to logfile: ~p~n", [LogFile]).
+ io:format(user, "Events written to logfile: ~tp~n", [LogFile]).
log_events1(Evs, Dev, "") ->
log_events1(Evs, Dev, " ");
log_events1([E={_EH,tc_start,{_M,{init_per_group,_GrName,Props}}} | Evs], Dev, Ind) ->
case get_prop(Props) of
undefined ->
- io:format(Dev, "~s[~p,~n", [Ind,E]),
+ io:format(Dev, "~s[~tp,~n", [Ind,E]),
log_events1(Evs, Dev, Ind++" ");
Prop ->
- io:format(Dev, "~s{~w,~n~s[~p,~n", [Ind,Prop,Ind++" ",E]),
+ io:format(Dev, "~s{~w,~n~s[~tp,~n", [Ind,Prop,Ind++" ",E]),
log_events1(Evs, Dev, Ind++" ")
end;
log_events1([E={_EH,tc_done,{_M,{init_per_group,_GrName,_Props},_R}} | Evs], Dev, Ind) ->
- io:format(Dev, "~s~p,~n", [Ind,E]),
+ io:format(Dev, "~s~tp,~n", [Ind,E]),
log_events1(Evs, Dev, Ind++" ");
log_events1([E={_EH,tc_start,{_M,{end_per_group,_GrName,_Props}}} | Evs], Dev, Ind) ->
Ind1 = Ind -- " ",
- io:format(Dev, "~s~p,~n", [Ind1,E]),
+ io:format(Dev, "~s~tp,~n", [Ind1,E]),
log_events1(Evs, Dev, Ind1);
log_events1([E={_EH,tc_done,{_M,{end_per_group,_GrName,Props},_R}} | Evs], Dev, Ind) ->
case get_prop(Props) of
undefined ->
- io:format(Dev, "~s~p],~n", [Ind,E]),
+ io:format(Dev, "~s~tp],~n", [Ind,E]),
log_events1(Evs, Dev, Ind--" ");
_Prop ->
- io:format(Dev, "~s~p]},~n", [Ind,E]),
+ io:format(Dev, "~s~tp]},~n", [Ind,E]),
log_events1(Evs, Dev, Ind--" ")
end;
-log_events1([E={_EH,tc_auto_skip,{_M,end_per_group,_Reason}} | Evs], Dev, Ind) ->
- io:format(Dev, "~s~p],~n", [Ind,E]),
+log_events1([E={_EH,tc_auto_skip,{_M,{end_per_group,_GrName},_Reason}} | Evs], Dev, Ind) ->
+ io:format(Dev, "~s~tp],~n", [Ind,E]),
log_events1(Evs, Dev, Ind--" ");
-log_events1([E={_EH,tc_user_skip,{_M,end_per_group,_Reason}} | Evs], Dev, Ind) ->
- io:format(Dev, "~s~p],~n", [Ind,E]),
+log_events1([E={_EH,tc_user_skip,{_M,{end_per_group,_GrName},_Reason}} | Evs], Dev, Ind) ->
+ io:format(Dev, "~s~tp],~n", [Ind,E]),
log_events1(Evs, Dev, Ind--" ");
log_events1([E], Dev, Ind) ->
- io:format(Dev, "~s~p~n].~n", [Ind,E]),
+ io:format(Dev, "~s~tp~n].~n", [Ind,E]),
ok;
log_events1([E | Evs], Dev, Ind) ->
- io:format(Dev, "~s~p,~n", [Ind,E]),
+ io:format(Dev, "~s~tp,~n", [Ind,E]),
log_events1(Evs, Dev, Ind);
log_events1([], _Dev, _Ind) ->
ok.
@@ -1388,10 +1394,10 @@ delete_dirs(LogDir) ->
delete_dirs(_, []) ->
ok;
delete_dirs(LogDir, [Dir | Dirs]) ->
- test_server:format(0, "Removing old log directory: ~s", [Dir]),
+ test_server:format(0, "Removing old log directory: ~ts", [Dir]),
case catch rm_rec(Dir) of
{_,Reason} ->
- test_server:format(0, "Delete failed! (~p)", [Reason]);
+ test_server:format(0, "Delete failed! (~tp)", [Reason]);
ok ->
ok
end,
diff --git a/lib/common_test/test/ct_testspec_1_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE.erl
index fca5ef3eb3..2d2c42999f 100644
--- a/lib/common_test/test/ct_testspec_1_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_1_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -616,7 +616,7 @@ setup_and_execute(TCName, TestSpec, Config) ->
FullSpecFile = ct_test_support:join_abs_dirs(?config(net_dir, Opts),
SpecFile),
- io:format("~nTest spec created here~n~n<a href=\"file://~s\">~s</a>~n",
+ io:format("~nTest spec created here~n~n<a href=\"file://~ts\">~ts</a>~n",
[FullSpecFile,FullSpecFile]),
ok = ct_test_support:run(Opts, Config),
@@ -638,8 +638,8 @@ setup_and_execute(TCName, TestSpec, Config) ->
create_spec_file(SpecDir, TCName, TestSpec) ->
FileName = filename:join(SpecDir,
atom_to_list(TCName)++".spec"),
- {ok,Dev} = file:open(FileName, [write]),
- [io:format(Dev, "~p.~n", [Term]) || Term <- TestSpec],
+ {ok,Dev} = file:open(FileName, [write,{encoding,utf8}]),
+ [io:format(Dev, "~tp.~n", [Term]) || Term <- TestSpec],
file:close(Dev),
FileName.
diff --git a/lib/common_test/test/ct_testspec_2_SUITE.erl b/lib/common_test/test/ct_testspec_2_SUITE.erl
index 1a941df185..1bab80942a 100644
--- a/lib/common_test/test/ct_testspec_2_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_2_SUITE.erl
@@ -220,7 +220,24 @@ basic_compatible_no_nodes(_Config) ->
{tc2,{skip,"skipped"}}]}]}],
merge_tests = true},
- verify_result(Verify,ListResult,FileResult).
+ verify_result(Verify,ListResult,FileResult),
+
+ {ok,Tests} = ct_testspec:get_tests([SpecFile]),
+ ct:pal("ct_testspec:get_tests/1:~n~p~n", [Tests]),
+ [{[SpecFile],[{Node,Run,Skip}]}] = Tests,
+ [{Alias1V,x_SUITE,all},
+ {Alias1V,y_SUITE,[{g1,all},{g2,all},tc1,tc2]},
+ {Alias1V,z_SUITE,all},
+ {Alias2V,x_SUITE,all},
+ {Alias2V,y_SUITE,all}] = lists:sort(Run),
+ [{Alias1V,z_SUITE,"skipped"},
+ {Alias2V,x_SUITE,{g1,all},"skipped"},
+ {Alias2V,x_SUITE,{g2,all},"skipped"},
+ {Alias2V,y_SUITE,tc1,"skipped"},
+ {Alias2V,y_SUITE,tc2,"skipped"}] = lists:sort(Skip),
+
+ ok.
+
%%%-----------------------------------------------------------------
%%%
@@ -346,7 +363,25 @@ basic_compatible_nodes(_Config) ->
{tc2,{skip,"skipped"}}]}]}],
merge_tests = true},
- verify_result(Verify,ListResult,FileResult).
+ verify_result(Verify,ListResult,FileResult),
+
+ {ok,Tests} = ct_testspec:get_tests([SpecFile]),
+ ct:pal("ct_testspec:get_tests/1:~n~p~n", [Tests]),
+ [{[SpecFile],[{Node,[],[]},
+ {Node1,Run1,Skip1},
+ {Node2,Run2,Skip2}]}] = Tests,
+ [{TO1V,x_SUITE,all},
+ {TO1V,y_SUITE,[{g1,all},{g2,all},tc1,tc2]},
+ {TO1V,z_SUITE,all}] = lists:sort(Run1),
+ [{TO2V,x_SUITE,all},
+ {TO2V,y_SUITE,all}] = lists:sort(Run2),
+ [{TO1V,z_SUITE,"skipped"}] = lists:sort(Skip1),
+ [{TO2V,x_SUITE,{g1,all},"skipped"},
+ {TO2V,x_SUITE,{g2,all},"skipped"},
+ {TO2V,y_SUITE,tc1,"skipped"},
+ {TO2V,y_SUITE,tc2,"skipped"}] = lists:sort(Skip2),
+
+ ok.
%%%-----------------------------------------------------------------
%%%
@@ -439,7 +474,28 @@ no_merging(_Config) ->
[{y_SUITE,[{tc1,{skip,"skipped"}},
{tc2,{skip,"skipped"}}]}]}]},
- verify_result(Verify,ListResult,FileResult).
+ verify_result(Verify,ListResult,FileResult),
+
+ {ok,Tests} = ct_testspec:get_tests([SpecFile]),
+ ct:pal("ct_testspec:get_tests/1:~n~p~n", [Tests]),
+ [{[SpecFile],[{Node,[],[]},
+ {Node1,Run1,Skip1},
+ {Node2,Run2,Skip2}]}] = Tests,
+ [{TO1V,x_SUITE,all},
+ {TO1V,y_SUITE,[tc1,tc2]},
+ {TO1V,y_SUITE,[{g1,all},{g2,all}]},
+ {TO1V,z_SUITE,all}] = lists:sort(Run1),
+ [{TO2V,x_SUITE,all},
+ {TO2V,x_SUITE,[{skipped,g1,all},{skipped,g2,all}]},
+ {TO2V,y_SUITE,all},
+ {TO2V,y_SUITE,[{skipped,tc1},{skipped,tc2}]}] = lists:sort(Run2),
+ [{TO1V,z_SUITE,"skipped"}] = lists:sort(Skip1),
+ [{TO2V,x_SUITE,{g1,all},"skipped"},
+ {TO2V,x_SUITE,{g2,all},"skipped"},
+ {TO2V,y_SUITE,tc1,"skipped"},
+ {TO2V,y_SUITE,tc2,"skipped"}] = lists:sort(Skip2),
+
+ ok.
%%%-----------------------------------------------------------------
%%%
@@ -510,7 +566,25 @@ multiple_specs(_Config) ->
{y_SUITE,[all,{tc1,{skip,"skipped"}},
{tc2,{skip,"skipped"}}]}]}]},
- verify_result(Verify,FileResult,FileResult).
+ verify_result(Verify,FileResult,FileResult),
+
+ {ok,Tests} = ct_testspec:get_tests([[SpecFile1,SpecFile2]]),
+ ct:pal("ct_testspec:get_tests/1:~n~p~n", [Tests]),
+ [{[SpecFile1,SpecFile2],[{Node,[],[]},
+ {Node1,Run1,Skip1},
+ {Node2,Run2,Skip2}]}] = Tests,
+ [{TO1V,x_SUITE,all},
+ {TO1V,y_SUITE,[{g1,all},{g2,all},tc1,tc2]},
+ {TO1V,z_SUITE,all}] = lists:sort(Run1),
+ [{TO2V,x_SUITE,all},
+ {TO2V,y_SUITE,all}] = lists:sort(Run2),
+ [{TO1V,z_SUITE,"skipped"}] = lists:sort(Skip1),
+ [{TO2V,x_SUITE,{g1,all},"skipped"},
+ {TO2V,x_SUITE,{g2,all},"skipped"},
+ {TO2V,y_SUITE,tc1,"skipped"},
+ {TO2V,y_SUITE,tc2,"skipped"}] = lists:sort(Skip2),
+
+ ok.
%%%-----------------------------------------------------------------
%%%
diff --git a/lib/common_test/test/ct_unicode_SUITE.erl b/lib/common_test/test/ct_unicode_SUITE.erl
new file mode 100644
index 0000000000..355503a5dc
--- /dev/null
+++ b/lib/common_test/test/ct_unicode_SUITE.erl
@@ -0,0 +1,218 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_unicode_SUITE
+%%%
+%%% Description:
+%%% Test that common_test handles and logs unicode strings and atoms
+%%% correctly.
+%%%
+%%% The suite used for the test is located in the data directory.
+%%%-------------------------------------------------------------------
+-module(ct_unicode_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ case file:native_name_encoding() of
+ latin1 -> {skip,"Test is not applicable on latin1 file system"};
+ _ ->
+ ct_test_support:init_per_suite([{printable_range,unicode}|Config])
+ end.
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+suite() -> [].
+
+all() ->
+ [unicode_atoms_SUITE,
+ unicode_spec].
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+unicode_atoms_SUITE(Config) ->
+ DataDir = ?config(data_dir,Config),
+ PrivDir = ?config(priv_dir,Config),
+ run_test(unicode_atoms_SUITE,
+ [{dir,DataDir},{suite,unicode_atoms_SUITE}], Config).
+
+unicode_spec(Config) ->
+ DataDir = ?config(data_dir,Config),
+ PrivDir = ?config(priv_dir,Config),
+ CfgName = "unicode_αβ.cfg",
+ Cfg = io_lib:format("{~tw,[{~tw,\"~ts\"}]}.~n",
+ ['key_αβ','subkey_αβ',"value_αβ"]),
+ ok = file:write_file(filename:join(PrivDir,CfgName),
+ unicode:characters_to_binary(Cfg)),
+ TestSpec = [{cases, DataDir, unicode_atoms_SUITE, ['config_αβ']},
+ {config, PrivDir, CfgName}],
+ TestSpecName = ct_test_support:write_testspec(TestSpec, PrivDir,
+ "unicode_αβ.spec"),
+ run_test(unicode_spec,[{spec,TestSpecName}],Config).
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+run_test(Label, Test, Config) ->
+ {Opts,ERPid} = setup_env([{label,Label}|Test], Config),
+ ok = ct_test_support:run(Opts, Config),
+ TestEvents = ct_test_support:get_events(ERPid, Config),
+ ct_test_support:log_events(Label,
+ reformat_events(TestEvents, ?eh),
+ ?config(priv_dir, Config),
+ Opts),
+ ExpEvents = events_to_check(Label),
+ ok = ct_test_support:verify_events(ExpEvents, TestEvents, Config),
+ check_logs([_,_]=get_log_dirs(TestEvents)).
+
+setup_env(Test, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+ Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}} | Test],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+reformat_events(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+
+get_log_dirs([{?eh,#event{name=start_logging,data=LogDir}}|Events]) ->
+ [LogDir|get_log_dirs(Events)];
+get_log_dirs([_|Events]) ->
+ get_log_dirs(Events);
+get_log_dirs([]) ->
+ [].
+
+%%%-----------------------------------------------------------------
+%%% TEST EVENTS
+%%%-----------------------------------------------------------------
+events_to_check(Test) ->
+ %% 2 tests (ct:run_test + script_start) is default
+ events_to_check(Test, 2).
+
+events_to_check(_, 0) ->
+ [];
+events_to_check(Test, N) ->
+ test_events(Test) ++ events_to_check(Test, N-1).
+
+test_events(unicode_atoms_SUITE) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,6}},
+ {?eh,tc_start,{unicode_atoms_SUITE,init_per_suite}},
+ {?eh,tc_done,{unicode_atoms_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{unicode_atoms_SUITE,'test_αβ'}},
+ {?eh,tc_done,{unicode_atoms_SUITE,'test_αβ',ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{unicode_atoms_SUITE,'fail_αβ_1'}},
+ {?eh,tc_done,{unicode_atoms_SUITE,'fail_αβ_1','_'}},
+ {?eh,test_stats,{1,1,{0,0}}},
+ {?eh,tc_start,{unicode_atoms_SUITE,'fail_αβ_2'}},
+ {?eh,tc_done,{unicode_atoms_SUITE,'fail_αβ_2','_'}},
+ {?eh,test_stats,{1,2,{0,0}}},
+ {?eh,tc_start,{unicode_atoms_SUITE,'fail_αβ_3'}},
+ {?eh,tc_done,{unicode_atoms_SUITE,'fail_αβ_3','_'}},
+ {?eh,test_stats,{1,3,{0,0}}},
+ {?eh,tc_start,{unicode_atoms_SUITE,'fail_αβ_4'}},
+ {?eh,tc_done,{unicode_atoms_SUITE,'fail_αβ_4','_'}},
+ {?eh,test_stats,{1,4,{0,0}}},
+ {?eh,tc_start,{unicode_atoms_SUITE,'skip_αβ'}},
+ {?eh,tc_done,{unicode_atoms_SUITE,'skip_αβ','_'}},
+ {?eh,test_stats,{1,4,{1,0}}},
+ {?eh,tc_start,{unicode_atoms_SUITE,end_per_suite}},
+ {?eh,tc_done,{unicode_atoms_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+test_events(unicode_spec) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,1}},
+ {?eh,tc_start,{unicode_atoms_SUITE,init_per_suite}},
+ {?eh,tc_done,{unicode_atoms_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{unicode_atoms_SUITE,'config_αβ'}},
+ {?eh,tc_done,{unicode_atoms_SUITE,'config_αβ',ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{unicode_atoms_SUITE,end_per_suite}},
+ {?eh,tc_done,{unicode_atoms_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ].
+
+%%%-----------------------------------------------------------------
+%%% Check logs for escaped unicode characters
+check_logs(Dirs) ->
+ ct:log("Checking logs for escaped unicode characters (αβ).~nDirs:~n~tp",
+ [Dirs]),
+ {ok,RE} = re:compile(<<"x{3B[12]}"/utf8>>),
+ case check_logs1(RE,Dirs,[]) of
+ [] ->
+ ok;
+ Match ->
+ MatchStr = string:join(Match,"\n"),
+ ct:log("ERROR: Escaped unicode characters found in:~n~ts",[MatchStr]),
+ ct:fail(escaped_unicode_characters_found)
+ end.
+
+check_logs1(RE,[F|Fs],Match) ->
+ New = case filelib:is_dir(F) of
+ true ->
+ {ok,Files} = file:list_dir(F),
+ check_logs1(RE,[filename:join(F,File)||File<-Files],[]);
+ false ->
+ check_log(RE,F)
+ end,
+ check_logs1(RE,Fs,New++Match);
+check_logs1(_RE,[],Match) ->
+ Match.
+
+check_log(RE,F) ->
+ {ok,Bin} = file:read_file(F),
+ case re:run(Bin,RE,[{capture,none}]) of
+ match ->
+ [F];
+ nomatch ->
+ []
+ end.
diff --git a/lib/common_test/test/ct_unicode_SUITE_data/unicode_atoms_SUITE.erl b/lib/common_test/test/ct_unicode_SUITE_data/unicode_atoms_SUITE.erl
new file mode 100644
index 0000000000..993452500e
--- /dev/null
+++ b/lib/common_test/test/ct_unicode_SUITE_data/unicode_atoms_SUITE.erl
@@ -0,0 +1,98 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(unicode_atoms_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+suite() ->
+ [{timetrap,{seconds,30}}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+groups() ->
+ [].
+
+all() ->
+ ['test_αβ',
+ 'fail_αβ_1',
+ 'fail_αβ_2',
+ 'fail_αβ_3',
+ 'fail_αβ_4',
+ 'skip_αβ'].
+
+'test_αβ'(_Config) ->
+ ct:log("This is test case ~tw",[?FUNCTION_NAME]),
+ ok.
+
+'fail_αβ_1'(_Config) ->
+ ct:log("This is test case ~tw",[?FUNCTION_NAME]),
+ 'α' = 'β',
+ ok.
+
+'fail_αβ_2'(_Config) ->
+ ct:log("This is test case ~tw",[?FUNCTION_NAME]),
+ ct:fail({failing,testcase,?FUNCTION_NAME}),
+ ok.
+
+'fail_αβ_3'(_Config) ->
+ ct:log("This is test case ~tw",[?FUNCTION_NAME]),
+ exit({exiting,testcase,?FUNCTION_NAME}),
+ ok.
+
+'fail_αβ_4'(_Config) ->
+ ct:log("This is test case ~tw",[?FUNCTION_NAME]),
+ S = try throw(ok) catch throw:ok -> erlang:get_stacktrace() end,
+ erlang:raise(error,{error,testcase,?FUNCTION_NAME},S),
+ ok.
+
+'skip_αβ'(_Config) ->
+ ct:log("This is test case ~tw",[?FUNCTION_NAME]),
+ {skip,"Skipping " ++ atom_to_list(?FUNCTION_NAME)}.
+
+
+%% This should not be listed in all/0. It is only to be run explicitly
+%% using a test spec where the config file is declared as well.
+'config_αβ'() ->
+ [{require,'alias_αβ','key_αβ'}].
+'config_αβ'(_Config) ->
+ ct:log("This is test case ~tw",[?FUNCTION_NAME]),
+ Conf = ct:get_config('alias_αβ'),
+ Conf = ct:get_config('key_αβ'),
+ ct:log("Required config: ~tp",[Conf]),
+ ok.
diff --git a/lib/common_test/test/ct_verbosity_SUITE.erl b/lib/common_test/test/ct_verbosity_SUITE.erl
index b9298e54ca..095cd1b70b 100644
--- a/lib/common_test/test/ct_verbosity_SUITE.erl
+++ b/lib/common_test/test/ct_verbosity_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -47,8 +47,8 @@
init_per_suite(Config) ->
DataDir = ?config(data_dir, Config),
EvH = filename:join(DataDir,"simple_evh.erl"),
- ct:pal("Compiling ~s: ~p", [EvH,compile:file(EvH,[{outdir,DataDir},
- debug_info])]),
+ ct:pal("Compiling ~ts: ~p", [EvH,compile:file(EvH,[{outdir,DataDir},
+ debug_info])]),
ct_test_support:init_per_suite([{path_dirs,[DataDir]} | Config]).
end_per_suite(Config) ->
diff --git a/lib/common_test/test/erl2html2_SUITE.erl b/lib/common_test/test/erl2html2_SUITE.erl
index bdce43c9c9..53a63578b2 100644
--- a/lib/common_test/test/erl2html2_SUITE.erl
+++ b/lib/common_test/test/erl2html2_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -163,9 +163,9 @@ convert_module(Mod,InclDirs,Config) ->
PrivDir = ?config(priv_dir,Config),
Src = filename:join(DataDir,Mod++".erl"),
Dst = filename:join(PrivDir,Mod++".erl.html"),
- io:format("<a href=\"~s\">~s</a>\n",[Src,filename:basename(Src)]),
+ io:format("<a href=\"~ts\">~s</a>\n",[Src,filename:basename(Src)]),
ok = erl2html2:convert(Src, Dst, InclDirs, "<html><body>"),
- io:format("<a href=\"~s\">~s</a>\n",[Dst,filename:basename(Dst)]),
+ io:format("<a href=\"~ts\">~s</a>\n",[Dst,filename:basename(Dst)]),
{Src,Dst}.
%% Check that there are the same number of lines in each file, and
diff --git a/lib/common_test/test/test_server_test_lib.erl b/lib/common_test/test/test_server_test_lib.erl
index cf5951ae03..c18b89b178 100644
--- a/lib/common_test/test/test_server_test_lib.erl
+++ b/lib/common_test/test/test_server_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -81,7 +81,7 @@ prepare_tester_node(Node,Config) ->
[true = rpc:call(Node, code, add_patha, [D]) || D <- PathDirs],
io:format("Dirs added to code path (on ~w):~n",
[Node]),
- [io:format("~s~n", [D]) || D <- PathDirs],
+ [io:format("~ts~n", [D]) || D <- PathDirs],
true = rpc:call(Node, os, putenv,
["TEST_SERVER_FRAMEWORK", "undefined"]),
diff --git a/lib/common_test/test_server/ts_install.erl b/lib/common_test/test_server/ts_install.erl
index 5734bd0787..c4e0223ac7 100644
--- a/lib/common_test/test_server/ts_install.erl
+++ b/lib/common_test/test_server/ts_install.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -136,7 +136,7 @@ unix_autoconf(XConf) ->
true ->
OSXEnv = macosx_cflags(),
UnQuotedEnv = assign_vars(unquote(Env++OSXEnv)),
- io:format("Running ~s~nEnv: ~p~n",
+ io:format("Running ~ts~nEnv: ~p~n",
[lists:flatten(Configure ++ Args),UnQuotedEnv]),
Port = open_port({spawn, lists:flatten(["\"",Configure,"\"",Args])},
[stream, eof, {env,UnQuotedEnv}]),
diff --git a/lib/common_test/test_server/ts_make.erl b/lib/common_test/test_server/ts_make.erl
index 456e913c39..ad5b75b529 100644
--- a/lib/common_test/test_server/ts_make.erl
+++ b/lib/common_test/test_server/ts_make.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@ unmake(Config) when is_list(Config) ->
make(Make, Dir, Makefile) ->
{RunFile, RunCmd, Script} = run_make_script(os:type(), Make, Dir, Makefile),
- case file:write_file(RunFile, Script) of
+ case file:write_file(RunFile, unicode:characters_to_binary(Script)) of
ok ->
Log = filename:join(Dir, "make.log"),
file:delete(Log),
diff --git a/lib/common_test/test_server/ts_run.erl b/lib/common_test/test_server/ts_run.erl
index 66db1ff9a7..82ae44ec06 100644
--- a/lib/common_test/test_server/ts_run.erl
+++ b/lib/common_test/test_server/ts_run.erl
@@ -258,7 +258,7 @@ make_command(Vars, Spec, State) ->
run_batch(Vars, _Spec, State) ->
process_flag(trap_exit, true),
- Command = State#state.command ++ " -noinput -s erlang halt",
+ Command = State#state.command ++ " -noinput -eval \"erlang:halt(0,[{flush,false}]).\"",
ts_lib:progress(Vars, 1, "Command: ~ts~n", [Command]),
io:format(user, "Command: ~ts~n",[Command]),
Port = open_port({spawn, Command}, [stream, in, eof, exit_status]),
diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk
index c68750886a..a219aa4736 100644
--- a/lib/common_test/vsn.mk
+++ b/lib/common_test/vsn.mk
@@ -1 +1 @@
-COMMON_TEST_VSN = 1.12.2
+COMMON_TEST_VSN = 1.15
diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml
index 61e214294e..10164890f2 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>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -132,12 +132,10 @@
<tag><c>debug_info</c></tag>
<item>
<marker id="debug_info"></marker>
- <p>Includes debug information in the form of abstract code
- (see
- <seealso marker="erts:absform">The Abstract Format</seealso>
- in ERTS User's Guide) in the compiled beam module. Tools
- such as <c>Debugger</c>, <c>Xref</c>, and <c>Cover</c> require
- the debug information to be included.</p>
+ <p>Includes debug information in the form of <seealso marker="erts:absform">
+ Erlang Abstract Format</seealso> in the <c>debug_info</c>
+ chunk of the compiled beam module. Tools such as Debugger,
+ Xref, and Cover require the debug information to be included.</p>
<p><em>Warning</em>: Source code can be reconstructed from
the debug information. Use encrypted debug information
@@ -147,6 +145,21 @@
<seealso marker="stdlib:beam_lib#debug_info">beam_lib(3)</seealso>.</p>
</item>
+ <tag><c>{debug_info, {Backend, Data}}</c></tag>
+ <item>
+ <marker id="debug_info"></marker>
+ <p>Includes custom debug information in the form of a
+ <c>Backend</c> module with custom <c>Data</c> in the compiled beam module.
+ The given module must implement a <c>debug_info/4</c> function
+ and is responsible for generating different code representations,
+ as described in the <c>debug_info</c> under
+ <seealso marker="stdlib:beam_lib#debug_info">beam_lib(3)</seealso>.</p>
+
+ <p><em>Warning</em>: Source code can be reconstructed from
+ the debug information. Use encrypted debug information
+ (<c>encrypt_debug_info</c>) to prevent this.</p>
+ </item>
+
<tag><c>{debug_info_key,KeyString}</c></tag>
<item></item>
<tag><c>{debug_info_key,{Mode,KeyString}}</c></tag>
@@ -176,6 +189,14 @@
<seealso marker="stdlib:beam_lib#debug_info">beam_lib(3)</seealso>.</p>
</item>
+ <tag><c>deterministic</c></tag>
+ <item>
+ <p>Omit the <c>options</c> and <c>source</c> tuples in
+ the list returned by <c>Module:module_info(compile)</c>.
+ This option will make it easier to achieve reproducible builds.
+ </p>
+ </item>
+
<tag><c>makedep</c></tag>
<item>
<p>Produces a Makefile rule to track headers dependencies.
@@ -410,7 +431,7 @@ module.beam: module.erl \
without module prefix to local or imported functions before
trying with auto-imported BIFs. If the BIF is to be
called, use the <c>erlang</c> module prefix in the call, not
- <c>{ no_auto_import,[{F,A}, ...]}</c>.</p>
+ <c>{no_auto_import,[{F,A}, ...]}</c>.</p>
</note>
<p>If this option is written in the source code, as a
<c>-compile</c> directive, the syntax <c>F/A</c> can be used instead
@@ -431,6 +452,15 @@ module.beam: module.erl \
</p>
</item>
+ <tag><c>{extra_chunks, [{binary(), binary()}]}</c></tag>
+ <item>
+ <p>Pass extra chunks to be stored in the <c>.beam</c> file.
+ The extra chunks must be a list of tuples with a four byte
+ binary as chunk name followed by a binary with the chunk contents.
+ See <seealso marker="stdlib:beam_lib">beam_lib</seealso> for
+ more information.
+ </p>
+ </item>
</taglist>
<p>If warnings are turned on (option <c>report_warnings</c>
@@ -498,9 +528,11 @@ module.beam: module.erl \
</warning>
</item>
- <tag><c>warn_export_all</c></tag>
+ <tag><c>nowarn_export_all</c></tag>
<item>
- <p>Emits a warning if option <c>export_all</c> is also given.</p>
+ <p>Turns off warnings for uses of the <c>export_all</c>
+ option. Default is to emit a warning if option
+ <c>export_all</c> is also given.</p>
</item>
<tag><c>warn_export_vars</c></tag>
@@ -544,7 +576,7 @@ module.beam: module.erl \
compiler to be deprecated. Notice that the compiler does not know
about attribute <c>-deprecated()</c>, but uses an
assembled list of deprecated functions in Erlang/OTP. To
- do a more general check, the <c>Xref</c> tool can be used.
+ do a more general check, the Xref tool can be used.
See also
<seealso marker="tools:xref#deprecated_function">xref(3)</seealso>
and the function
@@ -568,13 +600,13 @@ module.beam: module.erl \
to be deprecated.</p>
</item>
- <tag><c>warn_obsolete_guard</c></tag>
+ <tag><c>nowarn_obsolete_guard</c></tag>
<item>
- <p>Emits warnings for calls to old type testing BIFs,
+ <p>Turns off warnings for calls to old type testing BIFs,
such as <c>pid/1</c> and <c>list/1</c>. See the
<seealso marker="doc/reference_manual:expressions#guards">Erlang Reference Manual</seealso>
for a complete list of type testing BIFs and their old
- equivalents. Default is to emit no warnings for calls to
+ equivalents. Default is to emit warnings for calls to
old type testing BIFs.</p>
</item>
@@ -597,6 +629,14 @@ module.beam: module.erl \
<p>Turns off warnings for unused record types. Default is to
emit warnings for unused locally defined record types.</p>
</item>
+
+ <tag><c>nowarn_get_stacktrace</c></tag>
+ <item>
+ <p>Turns off warnings for using <c>get_stacktrace/0</c> in a context
+ where it will probably not work in a future release. For example,
+ by default there will be a warning if <c>get_stacktrace/0</c> is
+ used following a <c>catch</c> expression.</p>
+ </item>
</taglist>
<p>Another class of warnings is generated by the compiler
@@ -669,7 +709,7 @@ module.beam: module.erl \
<fsummary>Compiles a list of forms.</fsummary>
<desc>
<p>Is the same as
- <c>forms(File, [verbose,report_errors,report_warnings])</c>.
+ <c>forms(Forms, [verbose,report_errors,report_warnings])</c>.
</p>
</desc>
</func>
@@ -846,7 +886,7 @@ pi() -> 3.1416.
<section>
<title>Inlining of List Functions</title>
<p>The compiler can also inline various list manipulation functions
- from the module <c>list</c> in <c>STDLIB</c>.</p>
+ from the module <c>list</c> in STDLIB.</p>
<p>This feature must be explicitly enabled with a compiler option or a
<c>-compile()</c> attribute in the source module.</p>
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index e25cdc580c..f3d42a909b 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,6 +32,285 @@
<p>This document describes the changes made to the Compiler
application.</p>
+<section><title>Compiler 7.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>For many releases, it has been legal to override a BIF
+ with a local function having the same name. However,
+ calling a local function with the same name as guard BIF
+ as filter in a list comprehension was not allowed.</p>
+ <p>
+ Own Id: OTP-13690</p>
+ </item>
+ <item>
+ <p>compile:forms/2 would not return the module name as
+ documented when one of the options '<c>from_core</c>',
+ '<c>from_asm</c>', or '<c>from_beam</c>' was given. Also,
+ the compiler would crash if one of those options was
+ combined with '<c>native</c>'.</p>
+ <p>
+ Own Id: OTP-14408 Aux Id: ERL-417 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Optimized test for tuples with an atom as first element.</p>
+ <p>
+ Own Id: OTP-12148</p>
+ </item>
+ <item>
+ <p>
+ Compilation of modules with huge literal binary strings
+ is now much faster.</p>
+ <p>
+ Own Id: OTP-13794</p>
+ </item>
+ <item>
+ <p>Replaced usage of deprecated symbolic <seealso
+ marker="erts:erlang#type-time_unit"><c>time
+ unit</c></seealso> representations.</p>
+ <p>
+ Own Id: OTP-13831 Aux Id: OTP-13735 </p>
+ </item>
+ <item>
+ <p>The undocumented and unsupported module
+ <c>sys_pre_expand</c> has been removed. As a partial
+ replacement for the functionality, there is a new
+ function <c>erl_internal:add_predefined_functions/1</c>
+ and <c>erl_expand_records</c> will now add a module
+ prefix to calls to BIFs and imported functions.</p>
+ <p>
+ Own Id: OTP-13856</p>
+ </item>
+ <item>
+ <p>The internal compiler passes now start all generated
+ variables with "@" to avoid any conflicts with variables
+ in languages such as Elixir or LFE.</p>
+ <p>
+ Own Id: OTP-13924</p>
+ </item>
+ <item>
+ <p>The function <c>fmod/2</c> has been added to the
+ <c>math</c> module.</p>
+ <p>
+ Own Id: OTP-14000</p>
+ </item>
+ <item>
+ <p>Code generation for complicated guards have been
+ improved.</p>
+ <p>
+ Own Id: OTP-14042</p>
+ </item>
+ <item>
+ <p>
+ The compiler has new warnings for repeated identical map
+ keys.</p>
+ <p>
+ A map expression such as,</p>
+ <p>
+ <c> #{'a' => 1, 'b' => 2, 'a' => 3}.</c></p>
+ <p>
+ will produce a warning for the repeated key 'a'.</p>
+ <p>
+ Own Id: OTP-14058</p>
+ </item>
+ <item>
+ <p>By default, there will now be a warning when
+ <c>export_all</c> is used. The warning can be disabled
+ using <c>nowarn_export_all</c>.</p>
+ <p>
+ Own Id: OTP-14071</p>
+ </item>
+ <item>
+ <p>
+ Optimize maps pattern matching by only examining the
+ common keys in each clause first instead of all keys.
+ This will reduce the number of lookups of each key in
+ maps pattern matching.</p>
+ <p>
+ Own Id: OTP-14072</p>
+ </item>
+ <item>
+ <p>There is a new '<c>deterministic</c>' option to omit
+ '<c>source</c>' and '<c>options</c>' tuples in the BEAM
+ file.</p>
+ <p>
+ Own Id: OTP-14087</p>
+ </item>
+ <item>
+ <p>
+ Analyzing modules with binary construction with huge
+ strings is now much faster. The compiler also compiles
+ such modules slightly faster.</p>
+ <p>
+ Own Id: OTP-14125 Aux Id: ERL-308 </p>
+ </item>
+ <item>
+ <p>Atoms may now contain arbitrary Unicode
+ characters.</p>
+ <p>
+ Own Id: OTP-14178</p>
+ </item>
+ <item>
+ <p><c>compile:file/2</c> now accepts the option
+ <c>extra_chunks</c> to include extra chunks in the BEAM
+ file.</p>
+ <p>
+ Own Id: OTP-14221</p>
+ </item>
+ <item>
+ <p>The format of debug information that is stored in BEAM
+ files (when <c>debug_info</c> is used) has been changed.
+ The purpose of the change is to better support other
+ BEAM-based languages such as Elixir or LFE.</p>
+ <p>All tools included in OTP (dialyzer, debugger, cover,
+ and so on) will handle both the new format and the
+ previous format. Tools that retrieve the debug
+ information using <c>beam_lib:chunk(Beam,
+ [abstract_code])</c> will continue to work with both the
+ new and old format. Tools that call
+ <c>beam_lib:chunk(Beam, ["Abst"])</c> will not work with
+ the new format.</p>
+ <p>For more information, see the description of
+ <c>debug_info</c> in the documentation for
+ <c>beam_lib</c> and the description of the
+ <c>{debug_info,{Backend,Data}}</c> option in the
+ documentation for <c>compile</c>.</p>
+ <p>
+ Own Id: OTP-14369 Aux Id: PR-1367 </p>
+ </item>
+ <item>
+ <p>In a future release, <c>erlang:get_stacktrace/0</c>
+ will probably only work when called from within a
+ '<c>try</c>' expression (otherwise it will return
+ <c>[]</c>.</p>
+ <p>To help prepare for that change, the compiler will now
+ by default warn if '<c>get_stacktrace/0</c>' is used in a
+ way that will not work in the future. Note that the
+ warning will not be issued if '<c>get_stacktrace/0</c>'
+ is used in a function that uses neither '<c>catch</c>'
+ nor '<c>try</c>' (because that could be a legal use if
+ the function is called from within a '<c>try</c>'.</p>
+ <p>
+ Own Id: OTP-14401</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Compiler 7.0.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Minor internal changes. A typo in the documentation was
+ also fixed.</p>
+ <p>
+ Own Id: OTP-14240</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Compiler 7.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a compiler crash when maps were matched.</p>
+ <p>
+ Own Id: OTP-13931 Aux Id: ERL-266 </p>
+ </item>
+ <item>
+ <p>
+ Fixed a compiler crash having to with the delayed
+ sub-creation optimization. (Thanks to Jose Valim for
+ reporting this bug.)</p>
+ <p>
+ Own Id: OTP-13947 Aux Id: ERL-268 </p>
+ </item>
+ <item>
+ <p>The compiler option <c>inline_list_funcs</c>
+ accidentally turned off some other optimizations.</p>
+ <p>
+ Own Id: OTP-13985</p>
+ </item>
+ <item>
+ <p>The compiler could sometimes generate spurious
+ warnings when inlining was enabled.</p>
+ <p>
+ Own Id: OTP-14040 Aux Id: ERL-301 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Compiler 7.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ If the compiler fails to write the BEAM file, it will now
+ report the reason of the error for the write operation.</p>
+ <p>
+ Own Id: OTP-13701</p>
+ </item>
+ <item>
+ <p>
+ Fixed an internal compiler error. (Thanks to Svilen
+ Ivanov for reporting this bug.)</p>
+ <p>
+ Own Id: OTP-13780 Aux Id: ERL-202 </p>
+ </item>
+ <item>
+ <p>
+ The compiler could crash when trying to compile a
+ complicated expression with multiple catches all on one
+ line . (Thanks to Thomas Arts for reporting this bug.)</p>
+ <p>
+ Own Id: OTP-13804 Aux Id: ERL-209 </p>
+ </item>
+ <item>
+ <p>
+ Eliminated a few internal compiler failures.</p>
+ <p>
+ Own Id: OTP-13863</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Compiler 7.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A literal binary matching regression was introduced in
+ 19.0 where a match could fail to resolve to the right
+ clause. This has now been fixed.</p>
+ <p>
+ Own Id: OTP-13738</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Compiler 7.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -263,7 +542,7 @@
<item>
<p>
The <c>cerl</c> and <c>cerl_trees</c> modules in the
- <c>compiler</c> application are now documented.</p>
+ Compiler application are now documented.</p>
<p>
Own Id: OTP-11978</p>
</item>
@@ -1965,7 +2244,7 @@
<c>RightExpr</c> or vice versa. The evaluation order is
only important if the expressions contains and/or depends
on operations with side-effects, such as message passing
- or <c>ets</c> operations.</p>
+ or ETS operations.</p>
<p>
Own Id: OTP-7206</p>
</item>
diff --git a/lib/compiler/doc/src/ref_man.xml b/lib/compiler/doc/src/ref_man.xml
index f5466553c0..c32c499008 100644
--- a/lib/compiler/doc/src/ref_man.xml
+++ b/lib/compiler/doc/src/ref_man.xml
@@ -30,7 +30,7 @@
<file>application.sgml</file>
</header>
<description>
- <p>The <c>Compiler</c> application compiles Erlang
+ <p>The Compiler application compiles Erlang
code to byte-code. The highly compact byte-code is executed by
the Erlang emulator.</p>
</description>
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index 518c89d044..ef6db66ff6 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2016. All Rights Reserved.
+# Copyright Ericsson AB 1996-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -49,7 +49,6 @@ MODULES = \
beam_a \
beam_asm \
beam_block \
- beam_bool \
beam_bs \
beam_bsm \
beam_clean \
@@ -64,6 +63,7 @@ MODULES = \
beam_peep \
beam_receive \
beam_reorder \
+ beam_record \
beam_split \
beam_trim \
beam_type \
@@ -83,12 +83,12 @@ MODULES = \
core_scan \
erl_bifs \
rec_env \
+ sys_core_bsm \
sys_core_dsetel \
sys_core_fold \
sys_core_fold_lists \
sys_core_inline \
sys_pre_attributes \
- sys_pre_expand \
v3_codegen \
v3_core \
v3_kernel \
@@ -128,7 +128,7 @@ ERL_COMPILE_FLAGS += +native
endif
ERL_COMPILE_FLAGS += +inline +warn_unused_import \
-Werror \
- -I../../stdlib/include -I$(EGEN) -W
+ -I../../stdlib/include -I$(EGEN) -W +warn_missing_spec
# ----------------------------------------------------
# Targets
@@ -198,7 +198,6 @@ $(EBIN)/sys_core_dsetel.beam: core_parse.hrl
$(EBIN)/sys_core_fold.beam: core_parse.hrl
$(EBIN)/sys_core_fold_lists.beam: core_parse.hrl
$(EBIN)/sys_core_inline.beam: core_parse.hrl
-$(EBIN)/sys_pre_expand.beam: ../../stdlib/include/erl_bits.hrl
$(EBIN)/v3_codegen.beam: v3_life.hrl
$(EBIN)/v3_core.beam: core_parse.hrl
$(EBIN)/v3_kernel.beam: core_parse.hrl v3_kernel.hrl
diff --git a/lib/compiler/src/beam_a.erl b/lib/compiler/src/beam_a.erl
index 91e6d80da3..cdb32d5d55 100644
--- a/lib/compiler/src/beam_a.erl
+++ b/lib/compiler/src/beam_a.erl
@@ -25,6 +25,9 @@
-export([module/2]).
+-spec module(beam_asm:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc}, _Opt) ->
Fs = [function(F) || F <- Fs0],
{ok,{Mod,Exp,Attr,Fs,Lc}}.
diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl
index f6ca7a0afb..c35efdfc9d 100644
--- a/lib/compiler/src/beam_asm.erl
+++ b/lib/compiler/src/beam_asm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,23 +21,54 @@
-module(beam_asm).
--export([module/4]).
+-export([module/5]).
-export([encode/2]).
+-export_type([fail/0,label/0,reg/0,src/0,module_code/0,function_name/0]).
+
-import(lists, [map/2,member/2,keymember/3,duplicate/2,splitwith/2]).
-include("beam_opcodes.hrl").
-module(Code, Abst, SourceFile, Opts) ->
- {ok,assemble(Code, Abst, SourceFile, Opts)}.
+%% Common types for describing operands for BEAM instructions.
+-type reg_num() :: 0..1023.
+-type reg() :: {'x',reg_num()} | {'y',reg_num()}.
+-type src() :: reg() |
+ {'literal',term()} |
+ {'atom',atom()} |
+ {'integer',integer()} |
+ 'nil' |
+ {'float',float()}.
+-type label() :: pos_integer().
+-type fail() :: {'f',label() | 0}.
+
+%% asm_instruction() describes only the instructions that
+%% are used in BEAM files (as opposed to internal instructions
+%% used only during optimization).
+
+-type asm_instruction() :: atom() | tuple().
+
+-type function_name() :: atom().
+
+-type asm_function() ::
+ {'function',function_name(),arity(),label(),[asm_instruction()]}.
+
+-type module_code() ::
+ {module(),[_],[_],[asm_function()],pos_integer()}.
+
+-spec module(module_code(), [{binary(), binary()}], [_], [compile:option()], [compile:option()]) ->
+ {'ok',binary()}.
-assemble({Mod,Exp0,Attr0,Asm0,NumLabels}, Abst, SourceFile, Opts) ->
+module(Code, ExtraChunks, SourceFile, Opts, CompilerOpts) ->
+ {ok,assemble(Code, ExtraChunks, SourceFile, Opts, CompilerOpts)}.
+
+assemble({Mod,Exp0,Attr0,Asm0,NumLabels}, ExtraChunks, SourceFile, Opts, CompilerOpts) ->
{1,Dict0} = beam_dict:atom(Mod, beam_dict:new()),
{0,Dict1} = beam_dict:fname(atom_to_list(Mod) ++ ".erl", Dict0),
NumFuncs = length(Asm0),
{Asm,Attr} = on_load(Asm0, Attr0),
Exp = cerl_sets:from_list(Exp0),
{Code,Dict2} = assemble_1(Asm, Exp, Dict1, []),
- build_file(Code, Attr, Dict2, NumLabels, NumFuncs, Abst, SourceFile, Opts).
+ build_file(Code, Attr, Dict2, NumLabels, NumFuncs, ExtraChunks, SourceFile, Opts, CompilerOpts).
on_load(Fs0, Attr0) ->
case proplists:get_value(on_load, Attr0) of
@@ -80,7 +111,7 @@ assemble_function([H|T], Acc, Dict0) ->
assemble_function([], Code, Dict) ->
{Code, Dict}.
-build_file(Code, Attr, Dict, NumLabels, NumFuncs, Abst, SourceFile, Opts) ->
+build_file(Code, Attr, Dict, NumLabels, NumFuncs, ExtraChunks, SourceFile, Opts, CompilerOpts) ->
%% Create the code chunk.
CodeChunk = chunk(<<"Code">>,
@@ -92,9 +123,9 @@ build_file(Code, Attr, Dict, NumLabels, NumFuncs, Abst, SourceFile, Opts) ->
Code),
%% Create the atom table chunk.
-
- {NumAtoms, AtomTab} = beam_dict:atom_table(Dict),
- AtomChunk = chunk(<<"Atom">>, <<NumAtoms:32>>, AtomTab),
+ AtomEncoding = atom_encoding(CompilerOpts),
+ {NumAtoms, AtomTab} = beam_dict:atom_table(Dict, AtomEncoding),
+ AtomChunk = chunk(atom_chunk_name(AtomEncoding), <<NumAtoms:32>>, AtomTab),
%% Create the import table chunk.
@@ -155,21 +186,30 @@ build_file(Code, Attr, Dict, NumLabels, NumFuncs, Abst, SourceFile, Opts) ->
AttrChunk = chunk(<<"Attr">>, Attributes),
CompileChunk = chunk(<<"CInf">>, Compile),
- %% Create the abstract code chunk.
+ %% Compile all extra chunks.
- AbstChunk = chunk(<<"Abst">>, Abst),
+ CheckedChunks = [chunk(Key, Value) || {Key, Value} <- ExtraChunks],
%% Create IFF chunk.
Chunks = case member(slim, Opts) of
true ->
- [Essentials,AttrChunk,AbstChunk];
+ [Essentials,AttrChunk];
false ->
[Essentials,LocChunk,AttrChunk,
- CompileChunk,AbstChunk,LineChunk]
+ CompileChunk,CheckedChunks,LineChunk]
end,
build_form(<<"BEAM">>, Chunks).
+atom_encoding(Opts) ->
+ case proplists:get_bool(no_utf8_atoms, Opts) of
+ false -> utf8;
+ true -> latin1
+ end.
+
+atom_chunk_name(utf8) -> <<"AtU8">>;
+atom_chunk_name(latin1) -> <<"Atom">>.
+
%% finalize_fun_table(Essentials, MD5) -> FinalizedEssentials
%% Update the 'old_uniq' field in the entry for each fun in the
%% 'FunT' chunk. We'll use part of the MD5 for the module as a
@@ -233,7 +273,12 @@ build_attributes(Opts, SourceFile, Attr, MD5) ->
false -> Misc0;
true -> []
end,
- Compile = [{options,Opts},{version,?COMPILER_VSN}|Misc],
+ Compile = case member(deterministic, Opts) of
+ false ->
+ [{options,Opts},{version,?COMPILER_VSN}|Misc];
+ true ->
+ [{version,?COMPILER_VSN}]
+ end,
{term_to_binary(set_vsn_attribute(Attr, MD5)),term_to_binary(Compile)}.
build_line_table(Dict) ->
@@ -434,6 +479,8 @@ encode_alloc_list_1([{floats,Floats}|T], Dict, Acc0) ->
encode_alloc_list_1([], Dict, Acc) ->
{iolist_to_binary(Acc),Dict}.
+-spec encode(non_neg_integer(), pos_integer()) -> iodata().
+
encode(Tag, N) when N < 0 ->
encode1(Tag, negative_to_bytes(N));
encode(Tag, N) when N < 16 ->
diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl
index 85d332c56e..6543e05e20 100644
--- a/lib/compiler/src/beam_block.erl
+++ b/lib/compiler/src/beam_block.erl
@@ -25,6 +25,9 @@
-export([module/2]).
-import(lists, [reverse/1,reverse/2,foldl/3,member/2]).
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc}, _Opt) ->
Fs = [function(F) || F <- Fs0],
{ok,{Mod,Exp,Attr,Fs,Lc}}.
@@ -58,13 +61,6 @@ blockify(Is) ->
blockify([{loop_rec,{f,Fail},{x,0}},{loop_rec_end,_Lbl},{label,Fail}|Is], Acc) ->
%% Useless instruction sequence.
blockify(Is, Acc);
-blockify([{get_map_elements,F,S,{list,Gets}}|Is0], Acc) ->
- %% A get_map_elements instruction is only safe at the beginning of
- %% a block because of the failure label.
- {Ss,Ds} = beam_utils:split_even(Gets),
- I = {set,Ds,[S|Ss],{get_map_elements,F}},
- {Block,Is} = collect_block(Is0, [I]),
- blockify(Is, [{block,Block}|Acc]);
blockify([I|Is0]=IsAll, Acc) ->
case collect(I) of
error -> blockify(Is0, [I|Acc]);
@@ -159,14 +155,43 @@ find_fixpoint(OptFun, Is0) ->
end.
%% move_allocates(Is0) -> Is
-%% Move allocate instructions upwards in the instruction stream, in the
-%% hope of getting more possibilities for optimizing away moves later.
+%% Move allocate instructions upwards in the instruction stream
+%% (within the same block), in the hope of getting more possibilities
+%% for optimizing away moves later.
+%%
+%% For example, we can transform the following instructions:
+%%
+%% get_tuple_element x(1) Element => x(2)
+%% allocate_zero StackSize 3 %% x(0), x(1), x(2) are live
+%%
+%% to the following instructions:
+%%
+%% allocate_zero StackSize 2 %% x(0) and x(1) are live
+%% get_tuple_element x(1) Element => x(2)
+%%
+%% NOTE: Since the beam_reorder pass has been run, it is no longer
+%% safe to assume that if x(N) is initialized, then all lower-numbered
+%% x registers are also initialized.
%%
-%% NOTE: Moving allocation instructions is only safe because it is done
-%% immediately after code generation so that we KNOW that if {x,X} is
-%% initialized, all x registers with lower numbers are also initialized.
-%% That assumption may not be true after other optimizations, such as
-%% the beam_utils:live_opt/1 optimization.
+%% For example, in general it is not safe to transform the following
+%% instructions:
+%%
+%% get_tuple_element x(0) Element => x(1)
+%% allocate_zero StackSize 3 %x(0), x(1), x(2) are live
+%%
+%% to the following instructions:
+%%
+%% allocate_zero StackSize 3
+%% get_tuple_element x(0) Element => x(1)
+%%
+%% The transformation is safe if and only if x(1) has been
+%% initialized previously. Unfortunately, beam_reorder may have moved
+%% a get_tuple_element instruction so that x(1) is not always
+%% initialized when this code is reached. To find whether or not x(1)
+%% is initialized, we would need to analyze all code preceding these
+%% two instructions (across branches). Since we currently don't have
+%% any practical mechanism for doing that, we will have to
+%% conservatively assume that the transformation is unsafe.
move_allocates([{block,Bl0}|Is]) ->
Bl = move_allocates_1(reverse(Bl0), []),
@@ -175,38 +200,26 @@ move_allocates([I|Is]) ->
[I|move_allocates(Is)];
move_allocates([]) -> [].
-move_allocates_1([{set,[],[],{alloc,_,_}=Alloc}|Is0], Acc0) ->
- {Is,Acc} = move_allocates_2(Alloc, Is0, Acc0),
- move_allocates_1(Is, Acc);
+move_allocates_1([I|Is], [{set,[],[],{alloc,Live0,Info}}|Acc]=Acc0) ->
+ case {alloc_may_pass(I),alloc_live_regs(I, Live0)} of
+ {false,_} ->
+ move_allocates_1(Is, [I|Acc0]);
+ {true,not_possible} ->
+ move_allocates_1(Is, [I|Acc0]);
+ {true,Live} when is_integer(Live) ->
+ A = {set,[],[],{alloc,Live,Info}},
+ move_allocates_1(Is, [A,I|Acc])
+ end;
move_allocates_1([I|Is], Acc) ->
move_allocates_1(Is, [I|Acc]);
-move_allocates_1([], Is) -> Is.
-
-move_allocates_2({alloc,Live,Info}, [{set,[],[],{alloc,Live0,Info0}}|Is], Acc) ->
- Live = Live0, % Assertion.
- Alloc = {alloc,Live,combine_alloc(Info0, Info)},
- move_allocates_2(Alloc, Is, Acc);
-move_allocates_2({alloc,Live,Info}=Alloc0, [I|Is]=Is0, Acc) ->
- case alloc_may_pass(I) of
- false ->
- {Is0,[{set,[],[],Alloc0}|Acc]};
- true ->
- Alloc = {alloc,alloc_live_regs(I, Live),Info},
- move_allocates_2(Alloc, Is, [I|Acc])
- end;
-move_allocates_2(Alloc, [], Acc) ->
- {[],[{set,[],[],Alloc}|Acc]}.
+move_allocates_1([], Acc) -> Acc.
alloc_may_pass({set,_,_,{alloc,_,_}}) -> false;
alloc_may_pass({set,_,_,{set_tuple_element,_}}) -> false;
-alloc_may_pass({set,_,_,{get_map_elements,_}}) -> false;
alloc_may_pass({set,_,_,put_list}) -> false;
alloc_may_pass({set,_,_,put}) -> false;
alloc_may_pass({set,_,_,_}) -> true.
-combine_alloc({_,Ns,Nh1,Init}, {_,nostack,Nh2,[]}) ->
- {zero,Ns,beam_utils:combine_heap_needs(Nh1, Nh2),Init}.
-
%% opt([Instruction]) -> [Instruction]
%% Optimize the instruction stream inside a basic block.
@@ -217,8 +230,6 @@ opt([{set,_,_,{line,_}}=Line1,
{set,[D2],[{integer,Idx2},Reg],{bif,element,{f,0}}}=I2|Is])
when Idx1 < Idx2, D1 =/= D2, D1 =/= Reg, D2 =/= Reg ->
opt([Line2,I2,Line1,I1|Is]);
-opt([{set,[_|_],_Ss,{get_map_elements,_F}}=I|Is]) ->
- [I|opt(Is)];
opt([{set,Ds0,Ss,Op}|Is0]) ->
{Ds,Is} = opt_moves(Ds0, Is0),
[{set,Ds,Ss,Op}|opt(Is)];
@@ -393,10 +404,19 @@ eliminate_use_of_from_reg([I]=Is, From, _To, Acc) ->
%% opt_alloc(Instructions) -> Instructions'
%% Optimises all allocate instructions.
+opt_alloc([{set,[],[],{alloc,Live0,Info0}},
+ {set,[],[],{alloc,Live,Info}}|Is]) ->
+ Live = Live0, %Assertion.
+ Alloc = combine_alloc(Info0, Info),
+ I = {set,[],[],{alloc,Live,Alloc}},
+ opt_alloc([I|Is]);
opt_alloc([{set,[],[],{alloc,R,{_,Ns,Nh,[]}}}|Is]) ->
[{set,[],[],opt_alloc(Is, Ns, Nh, R)}|Is];
opt_alloc([I|Is]) -> [I|opt_alloc(Is)];
opt_alloc([]) -> [].
+
+combine_alloc({_,Ns,Nh1,Init}, {_,nostack,Nh2,[]}) ->
+ {zero,Ns,beam_utils:combine_heap_needs(Nh1, Nh2),Init}.
%% opt_alloc(Instructions, FrameSize, HeapNeed, LivingRegs) -> [Instr]
%% Generates the optimal sequence of instructions for
@@ -445,13 +465,14 @@ count_ones(Bits, Acc) ->
alloc_live_regs({set,Ds,Ss,_}, Regs0) ->
Rset = x_live(Ss, x_dead(Ds, (1 bsl Regs0)-1)),
- live_regs(Rset).
+ live_regs(0, Rset).
-live_regs(Regs) ->
- live_regs_1(0, Regs).
-
-live_regs_1(N, 0) -> N;
-live_regs_1(N, Regs) -> live_regs_1(N+1, Regs bsr 1).
+live_regs(N, 0) ->
+ N;
+live_regs(N, Regs) when Regs band 1 =:= 1 ->
+ live_regs(N+1, Regs bsr 1);
+live_regs(_, _) ->
+ not_possible.
x_dead([{x,N}|Rs], Regs) -> x_dead(Rs, Regs band (bnot (1 bsl N)));
x_dead([_|Rs], Regs) -> x_dead(Rs, Regs);
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
deleted file mode 100644
index 99e4ccb1e9..0000000000
--- a/lib/compiler/src/beam_bool.erl
+++ /dev/null
@@ -1,765 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%% Purpose: Optimizes booleans in guards.
-
--module(beam_bool).
-
--export([module/2]).
-
--import(lists, [reverse/1,reverse/2,foldl/3,mapfoldl/3,map/2]).
-
--record(st,
- {next, %Next label number.
- ll %Live regs at labels.
- }).
-
-module({Mod,Exp,Attr,Fs0,Lc}, _Opts) ->
- %%io:format("~p:\n", [Mod]),
- {Fs,_} = mapfoldl(fun(Fn, Lbl) -> function(Fn, Lbl) end, 100000000, Fs0),
- {ok,{Mod,Exp,Attr,Fs,Lc}}.
-
-function({function,Name,Arity,CLabel,Is0}, Lbl0) ->
- try
- {Is,#st{next=Lbl}} = bool_opt(Is0, Lbl0),
- {{function,Name,Arity,CLabel,Is},Lbl}
- catch
- Class:Error ->
- Stack = erlang:get_stacktrace(),
- io:fwrite("Function: ~w/~w\n", [Name,Arity]),
- erlang:raise(Class, Error, Stack)
- end.
-
-%%
-%% Optimize boolean expressions that use guard bifs. Rewrite to
-%% use test instructions if possible.
-%%
-
-bool_opt(Asm, Lbl) ->
- LiveInfo = beam_utils:index_labels(Asm),
- bopt(Asm, [], #st{next=Lbl,ll=LiveInfo}).
-
-bopt([{block,Bl0}=Block|
- [{jump,{f,Succ}},
- {label,Fail},
- {block,[{set,[Dst],[{atom,false}],move}]},
- {label,Succ}|Is]=Is0], Acc0, St) ->
- case split_block(Bl0, Dst, Fail, Acc0, true) of
- failed ->
- bopt(Is0, [Block|Acc0], St);
- {Bl,PreBlock} ->
- Acc1 = case PreBlock of
- [] -> Acc0;
- _ -> [{block,PreBlock}|Acc0]
- end,
- Acc = [{protected,[Dst],Bl,{Fail,Succ}}|Acc1],
- bopt(Is, Acc, St)
- end;
-bopt([{test,is_eq_exact,{f,Fail},[Reg,{atom,true}]}=I|Is], [{block,_}|_]=Acc0, St0) ->
- case bopt_block(Reg, Fail, Is, Acc0, St0) of
- failed -> bopt(Is, [I|Acc0], St0);
- {Acc,St} -> bopt(Is, Acc, St)
- end;
-bopt([I|Is], Acc, St) ->
- bopt(Is, [I|Acc], St);
-bopt([], Acc, St) ->
- {bopt_reverse(Acc, []),St}.
-
-bopt_reverse([{protected,[Dst],Block,{Fail,Succ}}|Is], Acc0) ->
- Acc = [{block,Block},{jump,{f,Succ}},
- {label,Fail},
- {block,[{set,[Dst],[{atom,false}],move}]},
- {label,Succ}|Acc0],
- bopt_reverse(Is, Acc);
-bopt_reverse([I|Is], Acc) ->
- bopt_reverse(Is, [I|Acc]);
-bopt_reverse([], Acc) -> Acc.
-
-%% bopt_block(Reg, Fail, OldIs, Accumulator, St) -> failed | {NewAcc,St}
-%% Attempt to optimized a block of guard BIFs followed by a test
-%% instruction.
-bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) ->
- case split_block(Bl0, Reg, Fail, Acc0, false) of
- failed ->
- %% Reason for failure: The block either contained no
- %% guard BIFs with the failure label Fail, or the final
- %% instruction in the block did not assign the Reg register.
-
- %%io:format("split ~p: ~P\n", [Reg,Bl0,20]),
- failed;
- {Bl1,BlPre} ->
- %% The block has been splitted. Bl1 is a non-empty list
- %% of guard BIF instructions having the failure label Fail.
- %% BlPre is a (possibly empty list) of instructions preceeding
- %% Bl1.
- Acc1 = make_block(BlPre, Acc0),
- {Bl,Acc} = extend_block(Bl1, Fail, Acc1),
- try
- {NewCode,St} = bopt_tree_cg(Bl, Fail, St0),
- ensure_opt_safe(Bl, NewCode, OldIs, Fail, Acc, St),
- {NewCode++Acc,St}
- catch
- %% Not possible to rewrite because a boolean value is
- %% passed to another guard bif, e.g. 'abs(A > B)'
- %% (in this case, obviously nonsense code). Rare in
- %% practice.
- throw:mixed ->
- failed;
-
- %% There was a reference to a boolean expression
- %% from inside a protected block (try/catch), to
- %% a boolean expression outside.
- throw:protected_barrier ->
- failed;
-
- %% The 'xor' operator was used. We currently don't
- %% find it worthwile to translate 'xor' operators
- %% (the code would be clumsy).
- throw:'xor' ->
- failed;
-
- %% The block does not contain a boolean expression,
- %% but only a call to a guard BIF.
- %% For instance: ... when element(1, T) ->
- throw:not_boolean_expr ->
- failed;
-
- %% The optimization is not safe. (A register
- %% used by the instructions following the
- %% optimized code is either not assigned a
- %% value at all or assigned a different value.)
- throw:all_registers_not_killed ->
- failed;
- throw:registers_used ->
- failed;
-
- %% A protected block refered to the value
- %% returned by another protected block,
- %% probably because the Core Erlang code
- %% used nested try/catches in the guard.
- %% (v3_core never produces nested try/catches
- %% in guards, so it must have been another
- %% Core Erlang translator.)
- throw:protected_violation ->
- failed;
-
- %% Failed to work out the live registers for a GC
- %% BIF. For example, if the number of live registers
- %% needed to be 4 because {x,3} was a source register,
- %% but {x,2} was not known to be initialized, this
- %% exception would be thrown.
- throw:gc_bif_alloc_failure ->
- failed
-
- end
- end.
-
-%% ensure_opt_safe(OriginalCode, OptCode, FollowingCode, Fail,
-%% ReversedPrecedingCode, State) -> ok
-%% Comparing the original code to the optimized code, determine
-%% whether the optimized code is guaranteed to work in the same
-%% way as the original code.
-%%
-%% Throw an exception if the optimization is not safe.
-%%
-ensure_opt_safe(Bl, NewCode, OldIs, Fail, PrecedingCode, St) ->
- %% Here are the conditions that must be true for the
- %% optimization to be safe.
- %%
- %% 1. If a register is INITIALIZED by PrecedingCode,
- %% then if that register assigned a value in the original
- %% code, but not in the optimized code, it must be UNUSED or KILLED
- %% in the code that follows.
- %%
- %% 2. If a register is not known to be INITIALIZED by PreccedingCode,
- %% then if that register assigned a value in the original
- %% code, but not in the optimized code, it must be KILLED
- %% by the code that follows.
- %%
- %% 3. Any register that is assigned a value in the optimized
- %% code must be UNUSED or KILLED in the following code,
- %% unless we can be sure that it is always assigned the same
- %% value.
-
- InitInPreceding = initialized_regs(PrecedingCode),
-
- PrevDst = dst_regs(Bl),
- NewDst = dst_regs(NewCode),
- NotSet = ordsets:subtract(PrevDst, NewDst),
- MustBeKilled = ordsets:subtract(NotSet, InitInPreceding),
-
- case all_killed(MustBeKilled, OldIs, Fail, St) of
- false -> throw(all_registers_not_killed);
- true -> ok
- end,
- MustBeUnused = ordsets:subtract(ordsets:union(NotSet, NewDst),
- MustBeKilled),
- case none_used(MustBeUnused, OldIs, Fail, St) of
- false -> throw(registers_used);
- true -> ok
- end,
- ok.
-
-update_fail_label([{set,Ds,As,{bif,N,{f,_}}}|Is], Fail, Acc) ->
- update_fail_label(Is, Fail, [{set,Ds,As,{bif,N,{f,Fail}}}|Acc]);
-update_fail_label([{set,Ds,As,{alloc,Regs,{gc_bif,N,{f,_}}}}|Is], Fail, Acc) ->
- update_fail_label(Is, Fail,
- [{set,Ds,As,{alloc,Regs,{gc_bif,N,{f,Fail}}}}|Acc]);
-update_fail_label([], _, Acc) -> reverse(Acc).
-
-make_block(Bl) ->
- make_block(Bl, []).
-
-make_block([], Acc) -> Acc;
-make_block(Bl, Acc) -> [{block,Bl}|Acc].
-
-extend_block(BlAcc, Fail, [{protected,_,_,_}=Prot|OldAcc]) ->
- extend_block([Prot|BlAcc], Fail, OldAcc);
-extend_block(BlAcc0, Fail, [{block,Is0}|OldAcc]) ->
- case extend_block_1(reverse(Is0), Fail, BlAcc0) of
- {BlAcc,[]} -> extend_block(BlAcc, Fail, OldAcc);
- {BlAcc,Is} -> {BlAcc,[{block,Is}|OldAcc]}
- end;
-extend_block(BlAcc, _, OldAcc) -> {BlAcc,OldAcc}.
-
-extend_block_1([{set,[{x,_}],_,{bif,_,{f,Fail}}}=I|Is], Fail, Acc) ->
- extend_block_1(Is, Fail, [I|Acc]);
-extend_block_1([{set,[{x,_}],As,{bif,Bif,_}}=I|Is]=Is0, Fail, Acc) ->
- case safe_bool_op(Bif, length(As)) of
- false -> {Acc,reverse(Is0)};
- true -> extend_block_1(Is, Fail, [I|Acc])
- end;
-extend_block_1([_|_]=Is, _, Acc) -> {Acc,reverse(Is)};
-extend_block_1([], _, Acc) -> {Acc,[]}.
-
-%% split_block([Instruction], Destination, FailLabel, [PreInstruction],
-%% ProhibitFailLabelInPreBlock) -> failed | {Block,PreBlock}
-%% Split a sequence of instructions into two blocks - one containing
-%% all guard bif instructions and a pre-block all instructions before
-%% the guard BIFs.
-
-split_block(Is0, Dst, Fail, PreIs, ProhibitFailLabel) ->
- case ProhibitFailLabel andalso beam_jump:is_label_used_in(Fail, PreIs) of
- true ->
- %% The failure label was used in one of the instructions (most
- %% probably bit syntax construction) preceeding the block,
- %% the caller might eliminate the label.
- failed;
- false ->
- case reverse(Is0) of
- [{set,[Dst],_,_}|_]=Is ->
- split_block_1(Is, Fail, ProhibitFailLabel);
- _ -> failed
- end
- end.
-
-split_block_1(Is, Fail, ProhibitFailLabel) ->
- case split_block_2(Is, Fail, []) of
- {[],_} -> failed;
- {_,PreBlock}=Res ->
- case ProhibitFailLabel andalso
- split_block_label_used(PreBlock, Fail) of
- true ->
- %% The failure label was used in the pre-block;
- %% not allowed, because the label may be removed.
- failed;
- false ->
- Res
- end
- end.
-
-split_block_2([{set,[_],_,{bif,_,{f,Fail}}}=I|Is], Fail, Acc) ->
- split_block_2(Is, Fail, [I|Acc]);
-split_block_2([{set,[_],_,{alloc,_,{gc_bif,_,{f,Fail}}}}=I|Is], Fail, Acc) ->
- split_block_2(Is, Fail, [I|Acc]);
-split_block_2(Is0, _, Acc) ->
- Is = reverse(Is0),
- {Acc,Is}.
-
-split_block_label_used([{set,[_],_,{bif,_,{f,Fail}}}|_], Fail) ->
- true;
-split_block_label_used([{set,[_],_,{alloc,_,{gc_bif,_,{f,Fail}}}}|_], Fail) ->
- true;
-split_block_label_used([{set,[_],_,{alloc,_,{put_map,_,{f,Fail}}}}|_], Fail) ->
- true;
-split_block_label_used([_|Is], Fail) ->
- split_block_label_used(Is, Fail);
-split_block_label_used([], _) -> false.
-
-dst_regs(Is) ->
- dst_regs(Is, []).
-
-dst_regs([{block,Bl}|Is], Acc) ->
- dst_regs(Bl, dst_regs(Is, Acc));
-dst_regs([{set,[D],_,{bif,_,{f,_}}}|Is], Acc) ->
- dst_regs(Is, [D|Acc]);
-dst_regs([{set,[D],_,{alloc,_,{gc_bif,_,{f,_}}}}|Is], Acc) ->
- dst_regs(Is, [D|Acc]);
-dst_regs([{protected,_,Bl,_}|Is], Acc) ->
- dst_regs(Bl, dst_regs(Is, Acc));
-dst_regs([_|Is], Acc) ->
- dst_regs(Is, Acc);
-dst_regs([], Acc) -> ordsets:from_list(Acc).
-
-all_killed([R|Rs], OldIs, Fail, St) ->
- case is_killed(R, OldIs, Fail, St) of
- false -> false;
- true -> all_killed(Rs, OldIs, Fail, St)
- end;
-all_killed([], _, _, _) -> true.
-
-none_used([R|Rs], OldIs, Fail, St) ->
- case is_not_used(R, OldIs, Fail, St) of
- false -> false;
- true -> none_used(Rs, OldIs, Fail, St)
- end;
-none_used([], _, _, _) -> true.
-
-bopt_tree_cg(Block0, Fail, St) ->
- Free = free_variables(Block0),
- Block = ssa_block(Block0),
-%% io:format("~p\n", [Block0]),
-%% io:format("~p\n", [Block]),
-%% io:format("~p\n", [gb_trees:to_list(Free)]),
- case bopt_tree(Block, Free, []) of
- {Pre0,[{_,Tree}]} ->
- Pre1 = update_fail_label(Pre0, Fail, []),
- Regs0 = init_regs(gb_trees:keys(Free)),
-%% io:format("~p\n", [dst_regs(Block0)]),
-%% io:format("~p\n", [Pre1]),
-%% io:format("~p\n", [Tree]),
-%% io:nl(),
- {Pre,Regs} = rename_regs(Pre1, Regs0),
-%% io:format("~p\n", [Regs0]),
-%% io:format("~p\n", [Pre]),
- bopt_cg(Tree, Fail, Regs, make_block(Pre), St);
- _Res ->
- throw(not_boolean_expr)
- end.
-
-bopt_tree([{set,[Dst],As0,{bif,'not',_}}|Is], Forest0, Pre) ->
- {[Arg],Forest1} = bopt_bool_args(As0, Forest0),
- Forest = gb_trees:enter(Dst, {'not',Arg}, Forest1),
- bopt_tree(Is, Forest, Pre);
-bopt_tree([{set,[Dst],As0,{bif,'and',_}}|Is], Forest0, Pre) ->
- {As,Forest1} = bopt_bool_args(As0, Forest0),
- Node = make_and_node(As),
- Forest = gb_trees:enter(Dst, Node, Forest1),
- bopt_tree(Is, Forest, Pre);
-bopt_tree([{set,[Dst],As0,{bif,'or',_}}|Is], Forest0, Pre) ->
- {As,Forest1} = bopt_bool_args(As0, Forest0),
- Node = make_or_node(As),
- Forest = gb_trees:enter(Dst, Node, Forest1),
- bopt_tree(Is, Forest, Pre);
-bopt_tree([{set,_,_,{bif,'xor',_}}|_], _, _) ->
- throw('xor');
-bopt_tree([{protected,[Dst],Code,_}|Is], Forest0, Pre) ->
- ProtForest0 = gb_trees:from_orddict([P || {_,any}=P <- gb_trees:to_list(Forest0)]),
- case bopt_tree(Code, ProtForest0, []) of
- {ProtPre,[{_,ProtTree}]} ->
- Prot = {prot,ProtPre,ProtTree},
- Forest = gb_trees:enter(Dst, Prot, Forest0),
- bopt_tree(Is, Forest, Pre);
- _Res ->
- throw(not_boolean_expr)
- end;
-bopt_tree([{set,[Dst],As,{bif,N,_}}=Bif|Is], Forest0, Pre) ->
- Ar = length(As),
- case safe_bool_op(N, Ar) of
- false ->
- bopt_good_args(As, Forest0),
- Forest = gb_trees:enter(Dst, any, Forest0),
- bopt_tree(Is, Forest, [Bif|Pre]);
- true ->
- bopt_good_args(As, Forest0),
- Test = bif_to_test(Dst, N, As),
- Forest = gb_trees:enter(Dst, Test, Forest0),
- bopt_tree(Is, Forest, Pre)
- end;
-bopt_tree([{set,[Dst],As,{alloc,_,{gc_bif,_,_}}}=Bif|Is], Forest0, Pre) ->
- bopt_good_args(As, Forest0),
- Forest = gb_trees:enter(Dst, any, Forest0),
- bopt_tree(Is, Forest, [Bif|Pre]);
-bopt_tree([], Forest, Pre) ->
- {reverse(Pre),[R || {_,V}=R <- gb_trees:to_list(Forest), V =/= any]}.
-
-safe_bool_op(N, Ar) ->
- erl_internal:new_type_test(N, Ar) orelse erl_internal:comp_op(N, Ar).
-
-bopt_bool_args([V0,V0], Forest0) ->
- {V,Forest} = bopt_bool_arg(V0, Forest0),
- {[V,V],Forest};
-bopt_bool_args(As, Forest) ->
- mapfoldl(fun bopt_bool_arg/2, Forest, As).
-
-bopt_bool_arg({T,_}=R, Forest) when T =:= x; T =:= y; T =:= tmp ->
- Val = case gb_trees:lookup(R, Forest) of
- {value,any} -> {test,is_eq_exact,fail,[R,{atom,true}]};
- {value,Val0} -> Val0;
- none -> throw(mixed)
- end,
- {Val,gb_trees:delete(R, Forest)};
-bopt_bool_arg(Term, Forest) ->
- {Term,Forest}.
-
-bopt_good_args([A|As], Regs) ->
- bopt_good_arg(A, Regs),
- bopt_good_args(As, Regs);
-bopt_good_args([], _) -> ok.
-
-bopt_good_arg({Tag,_}=X, Regs) when Tag =:= x; Tag =:= tmp ->
- case gb_trees:lookup(X, Regs) of
- {value,any} -> ok;
- {value,_} -> throw(mixed);
- none -> throw(protected_barrier)
- end;
-bopt_good_arg(_, _) -> ok.
-
-bif_to_test(_, N, As) ->
- beam_utils:bif_to_test(N, As, fail).
-
-make_and_node(Is) ->
- AndList0 = make_and_list(Is),
- case simplify_and_list(AndList0) of
- [] -> {atom,true};
- [Op] -> Op;
- AndList -> {'and',AndList}
- end.
-
-make_and_list([{'and',As}|Is]) ->
- make_and_list(As++Is);
-make_and_list([I|Is]) ->
- [I|make_and_list(Is)];
-make_and_list([]) -> [].
-
-simplify_and_list([{atom,true}|T]) ->
- simplify_and_list(T);
-simplify_and_list([{atom,false}=False|_]) ->
- [False];
-simplify_and_list([H|T]) ->
- [H|simplify_and_list(T)];
-simplify_and_list([]) -> [].
-
-make_or_node(Is) ->
- OrList0 = make_or_list(Is),
- case simplify_or_list(OrList0) of
- [] -> {atom,false};
- [Op] -> Op;
- OrList -> {'or',OrList}
- end.
-
-make_or_list([{'or',As}|Is]) ->
- make_or_list(As++Is);
-make_or_list([I|Is]) ->
- [I|make_or_list(Is)];
-make_or_list([]) -> [].
-
-simplify_or_list([{atom,false}|T]) ->
- simplify_or_list(T);
-simplify_or_list([{atom,true}=True|_]) ->
- [True];
-simplify_or_list([H|T]) ->
- [H|simplify_or_list(T)];
-simplify_or_list([]) -> [].
-
-%% Code generation for a boolean tree.
-
-bopt_cg({'not',Arg}, Fail, Rs, Acc, St) ->
- I = bopt_cg_not(Arg),
- bopt_cg(I, Fail, Rs, Acc, St);
-bopt_cg({'and',As}, Fail, Rs, Acc, St) ->
- bopt_cg_and(As, Fail, Rs, Acc, St);
-bopt_cg({'or',As}, Fail, Rs, Acc, St0) ->
- {Succ,St} = new_label(St0),
- bopt_cg_or(As, Succ, Fail, Rs, Acc, St);
-bopt_cg({test,N,fail,As0}, Fail, Rs, Acc, St) ->
- As = rename_sources(As0, Rs),
- Test = {test,N,{f,Fail},As},
- {[Test|Acc],St};
-bopt_cg({inverted_test,N,fail,As0}, Fail, Rs, Acc, St0) ->
- As = rename_sources(As0, Rs),
- {Lbl,St} = new_label(St0),
- {[{label,Lbl},{jump,{f,Fail}},{test,N,{f,Lbl},As}|Acc],St};
-bopt_cg({prot,Pre0,Tree}, Fail, Rs0, Acc, St0) ->
- Pre1 = update_fail_label(Pre0, Fail, []),
- {Pre,Rs} = rename_regs(Pre1, Rs0),
- bopt_cg(Tree, Fail, Rs, make_block(Pre, Acc), St0);
-bopt_cg({atom,true}, _Fail, _Rs, Acc, St) ->
- {Acc,St};
-bopt_cg({atom,false}, Fail, _Rs, Acc, St) ->
- {[{jump,{f,Fail}}|Acc],St};
-bopt_cg(_, _, _, _, _) ->
- throw(not_boolean_expr).
-
-bopt_cg_not({'and',As0}) ->
- As = [bopt_cg_not(A) || A <- As0],
- {'or',As};
-bopt_cg_not({'or',As0}) ->
- As = [bopt_cg_not(A) || A <- As0],
- {'and',As};
-bopt_cg_not({'not',Arg}) ->
- bopt_cg_not_not(Arg);
-bopt_cg_not({test,Test,Fail,As}) ->
- {inverted_test,Test,Fail,As};
-bopt_cg_not({atom,Bool}) when is_boolean(Bool) ->
- {atom,not Bool};
-bopt_cg_not(_) ->
- throw(not_boolean_expr).
-
-bopt_cg_not_not({'and',As}) ->
- {'and',[bopt_cg_not_not(A) || A <- As]};
-bopt_cg_not_not({'or',As}) ->
- {'or',[bopt_cg_not_not(A) || A <- As]};
-bopt_cg_not_not({'not',Arg}) ->
- bopt_cg_not(Arg);
-bopt_cg_not_not(Leaf) -> Leaf.
-
-bopt_cg_and([I|Is], Fail, Rs, Acc0, St0) ->
- {Acc,St} = bopt_cg(I, Fail, Rs, Acc0, St0),
- bopt_cg_and(Is, Fail, Rs, Acc, St);
-bopt_cg_and([], _, _, Acc, St) -> {Acc,St}.
-
-bopt_cg_or([I], Succ, Fail, Rs, Acc0, St0) ->
- {Acc,St} = bopt_cg(I, Fail, Rs, Acc0, St0),
- {[{label,Succ}|Acc],St};
-bopt_cg_or([I|Is], Succ, Fail, Rs, Acc0, St0) ->
- {Lbl,St1} = new_label(St0),
- {Acc,St} = bopt_cg(I, Lbl, Rs, Acc0, St1),
- bopt_cg_or(Is, Succ, Fail, Rs, [{label,Lbl},{jump,{f,Succ}}|Acc], St).
-
-new_label(#st{next=LabelNum}=St) when is_integer(LabelNum) ->
- {LabelNum,St#st{next=LabelNum+1}}.
-
-free_variables(Is) ->
- E = gb_sets:empty(),
- free_vars_1(Is, E, E, E).
-
-free_vars_1([{set,Ds,As,{bif,_,_}}|Is], F0, N0, A) ->
- F = gb_sets:union(F0, gb_sets:difference(var_list(As), N0)),
- N = gb_sets:union(N0, var_list(Ds)),
- free_vars_1(Is, F, N, A);
-free_vars_1([{set,Ds,As,{alloc,Regs,{gc_bif,_,_}}}|Is], F0, N0, A0) ->
- A = gb_sets:union(A0, gb_sets:from_list(free_vars_regs(Regs))),
- F = gb_sets:union(F0, gb_sets:difference(var_list(As), N0)),
- N = gb_sets:union(N0, var_list(Ds)),
- free_vars_1(Is, F, N, A);
-free_vars_1([{protected,_,Pa,_}|Is], F, N, A) ->
- free_vars_1(Pa++Is, F, N, A);
-free_vars_1([], F0, N, A) ->
- F = case gb_sets:is_empty(A) of
- true ->
- %% No GC BIFs.
- {x,X} = gb_sets:smallest(N),
- P = ordsets:from_list(free_vars_regs(X)),
- ordsets:union(gb_sets:to_list(F0), P);
- false ->
- %% At least one GC BIF.
- gb_sets:to_list(gb_sets:union(F0, gb_sets:difference(A, N)))
- end,
- gb_trees:from_orddict([{K,any} || K <- F]).
-
-var_list(Is) ->
- var_list_1(Is, gb_sets:empty()).
-
-var_list_1([{Tag,_}=X|Is], D) when Tag =:= x; Tag =:= y ->
- var_list_1(Is, gb_sets:add(X, D));
-var_list_1([_|Is], D) ->
- var_list_1(Is, D);
-var_list_1([], D) -> D.
-
-free_vars_regs(0) -> [];
-free_vars_regs(X) -> [{x,X-1}|free_vars_regs(X-1)].
-
-rename_regs(Is, Regs) ->
- rename_regs(Is, Regs, []).
-
-rename_regs([{set,[Dst0],Ss0,{alloc,_,Info}}|Is], Regs0, Acc) ->
- Live = live_regs(Regs0),
- Ss = rename_sources(Ss0, Regs0),
- Regs = put_reg(Dst0, Regs0),
- Dst = fetch_reg(Dst0, Regs),
- rename_regs(Is, Regs, [{set,[Dst],Ss,{alloc,Live,Info}}|Acc]);
-rename_regs([{set,[Dst0],Ss0,Info}|Is], Regs0, Acc) ->
- Ss = rename_sources(Ss0, Regs0),
- Regs = put_reg(Dst0, Regs0),
- Dst = fetch_reg(Dst0, Regs),
- rename_regs(Is, Regs, [{set,[Dst],Ss,Info}|Acc]);
-rename_regs([], Regs, Acc) -> {reverse(Acc),Regs}.
-
-rename_sources(Ss, Regs) ->
- map(fun({x,_}=R) -> fetch_reg(R, Regs);
- ({tmp,_}=R) -> fetch_reg(R, Regs);
- (E) -> E
- end, Ss).
-
-%%%
-%%% Keeping track of register assignments.
-%%%
-
-init_regs(Free) ->
- init_regs_1(Free, 0).
-
-init_regs_1([{x,I}=V|T], I) ->
- [{I,V}|init_regs_1(T, I+1)];
-init_regs_1([{x,X}|_]=T, I) when I < X ->
- [{I,reserved}|init_regs_1(T, I+1)];
-init_regs_1([{y,_}|_], _) -> [];
-init_regs_1([], _) -> [].
-
-put_reg(V, Rs) -> put_reg_1(V, Rs, 0).
-
-put_reg_1(V, [R|Rs], I) -> [R|put_reg_1(V, Rs, I+1)];
-put_reg_1(V, [], I) -> [{I,V}].
-
-fetch_reg(V, [{I,V}|_]) -> {x,I};
-fetch_reg(V, [_|SRs]) -> fetch_reg(V, SRs).
-
-live_regs([{_,reserved}|_]) ->
- %% We are not sure that this register is initialized, so we must
- %% abort the optimization.
- throw(gc_bif_alloc_failure);
-live_regs([{I,_}]) ->
- I+1;
-live_regs([{_,_}|Regs]) ->
- live_regs(Regs);
-live_regs([]) ->
- 0.
-
-
-%%%
-%%% Convert a block to Static Single Assignment (SSA) form.
-%%%
-
--record(ssa,
- {live=0, %Variable counter.
- sub=gb_trees:empty(), %Substitution table.
- prot=gb_sets:empty(), %Targets assigned by protecteds.
- in_prot=false %Inside a protected.
- }).
-
-ssa_block(Is0) ->
- {Is,_} = ssa_block_1(Is0, #ssa{}, []),
- Is.
-
-ssa_block_1([{protected,[_],Pa0,Pb}|Is], Sub0, Acc) ->
- {Pa,Sub1} = ssa_block_1(Pa0, Sub0#ssa{in_prot=true}, []),
- Dst = ssa_last_target(Pa),
- Sub = Sub1#ssa{prot=gb_sets:insert(Dst, Sub1#ssa.prot),
- in_prot=Sub0#ssa.in_prot},
- ssa_block_1(Is, Sub, [{protected,[Dst],Pa,Pb}|Acc]);
-ssa_block_1([{set,[Dst],As,Bif}|Is], Sub0, Acc0) ->
- Sub1 = ssa_in_use_list(As, Sub0),
- Sub = ssa_assign(Dst, Sub1),
- Acc = [{set,[ssa_sub(Dst, Sub)],ssa_sub_list(As, Sub0),Bif}|Acc0],
- ssa_block_1(Is, Sub, Acc);
-ssa_block_1([], Sub, Acc) -> {reverse(Acc),Sub}.
-
-ssa_in_use_list(As, Sub) ->
- foldl(fun ssa_in_use/2, Sub, As).
-
-ssa_in_use({x,_}=R, #ssa{sub=Sub0}=Ssa) ->
- case gb_trees:is_defined(R, Sub0) of
- true -> Ssa;
- false ->
- Sub = gb_trees:insert(R, R, Sub0),
- Ssa#ssa{sub=Sub}
- end;
-ssa_in_use(_, Ssa) -> Ssa.
-
-ssa_assign({x,_}=R, #ssa{sub=Sub0}=Ssa0) ->
- {NewReg,Ssa} = ssa_new_reg(Ssa0),
- case gb_trees:is_defined(R, Sub0) of
- false ->
- Sub = gb_trees:insert(R, NewReg, Sub0),
- Ssa#ssa{sub=Sub};
- true ->
- Sub1 = gb_trees:update(R, NewReg, Sub0),
- Sub = gb_trees:insert(NewReg, NewReg, Sub1),
- Ssa#ssa{sub=Sub}
- end.
-
-ssa_sub_list(List, Sub) ->
- [ssa_sub(E, Sub) || E <- List].
-
-ssa_sub(R0, #ssa{sub=Sub,prot=Prot,in_prot=InProt}) ->
- case gb_trees:lookup(R0, Sub) of
- none -> R0;
- {value,R} ->
- case InProt andalso gb_sets:is_element(R, Prot) of
- true ->
- throw(protected_violation);
- false ->
- R
- end
- end.
-
-ssa_new_reg(#ssa{live=Reg}=Ssa) ->
- {{tmp,Reg},Ssa#ssa{live=Reg+1}}.
-
-ssa_last_target([{set,[Dst],_,_}]) -> Dst;
-ssa_last_target([_|Is]) -> ssa_last_target(Is).
-
-%% is_killed(Register, [Instruction], FailLabel, State) -> true|false
-%% Determine whether a register is killed in the instruction sequence.
-%% The state is used to allow us to determine the kill state
-%% across branches.
-
-is_killed(R, Is, Label, #st{ll=Ll}) ->
- beam_utils:is_killed(R, Is, Ll) andalso
- beam_utils:is_killed_at(R, Label, Ll).
-
-%% is_not_used(Register, [Instruction], FailLabel, State) -> true|false
-%% Determine whether a register is never used in the instruction sequence
-%% (it could still referenced by an allocate instruction, meaning that
-%% it MUST be initialized).
-%% The state is used to allow us to determine the usage state
-%% across branches.
-
-is_not_used(R, Is, Label, #st{ll=Ll}) ->
- beam_utils:is_not_used(R, Is, Ll) andalso
- beam_utils:is_not_used_at(R, Label, Ll).
-
-%% initialized_regs([Instruction]) -> [Register])
-%% Given a REVERSED instruction sequence, return a list of the registers
-%% that are guaranteed to be initialized (not contain garbage).
-
-initialized_regs(Is) ->
- initialized_regs(Is, ordsets:new()).
-
-initialized_regs([{set,Dst,_Src,{alloc,Live,_}}|_], Regs0) ->
- Regs = add_init_regs(free_vars_regs(Live), Regs0),
- add_init_regs(Dst, Regs);
-initialized_regs([{set,Dst,Src,_}|Is], Regs) ->
- initialized_regs(Is, add_init_regs(Dst, add_init_regs(Src, Regs)));
-initialized_regs([{test,_,_,Src}|Is], Regs) ->
- initialized_regs(Is, add_init_regs(Src, Regs));
-initialized_regs([{block,Bl}|Is], Regs) ->
- initialized_regs(reverse(Bl, Is), Regs);
-initialized_regs([{bs_context_to_binary,Src}|Is], Regs) ->
- initialized_regs(Is, add_init_regs([Src], Regs));
-initialized_regs([{label,_},{func_info,_,_,Arity}|_], Regs) ->
- InitRegs = free_vars_regs(Arity),
- add_init_regs(InitRegs, Regs);
-initialized_regs([_|_], Regs) -> Regs.
-
-add_init_regs([{x,_}=X|T], Regs) ->
- add_init_regs(T, ordsets:add_element(X, Regs));
-add_init_regs([_|T], Regs) ->
- add_init_regs(T, Regs);
-add_init_regs([], Regs) -> Regs.
diff --git a/lib/compiler/src/beam_bs.erl b/lib/compiler/src/beam_bs.erl
index 2aed98d4e7..beb055b23d 100644
--- a/lib/compiler/src/beam_bs.erl
+++ b/lib/compiler/src/beam_bs.erl
@@ -25,6 +25,9 @@
-export([module/2]).
-import(lists, [mapfoldl/3,reverse/1]).
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc0}, _Opt) ->
{Fs,Lc} = mapfoldl(fun function/2, Lc0, Fs0),
{ok,{Mod,Exp,Attr,Fs,Lc}}.
diff --git a/lib/compiler/src/beam_bsm.erl b/lib/compiler/src/beam_bsm.erl
index 286307a4be..9a4e7fb133 100644
--- a/lib/compiler/src/beam_bsm.erl
+++ b/lib/compiler/src/beam_bsm.erl
@@ -60,19 +60,26 @@
%%% data structures or passed to BIFs.
%%%
+-type label() :: beam_asm:label().
+-type func_info() :: {beam_asm:reg(),boolean()}.
+
-record(btb,
- {f, %Gbtrees for all functions.
- index, %{Label,Code} index (for liveness).
- ok_br, %Labels that are OK.
- must_not_save, %Must not save position when
- % optimizing (reaches
- % bs_context_to_binary).
- must_save %Must save position when optimizing.
+ {f :: gb_trees:tree(label(), func_info()),
+ index :: beam_utils:code_index(), %{Label,Code} index (for liveness).
+ ok_br=gb_sets:empty() :: gb_sets:set(label()), %Labels that are OK.
+ must_not_save=false :: boolean(), %Must not save position when
+ % optimizing (reaches
+ % bs_context_to_binary).
+ must_save=false :: boolean() %Must save position when optimizing.
}).
+
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc}, Opts) ->
- D = #btb{f=btb_index(Fs0)},
- Fs = [function(F, D) || F <- Fs0],
+ FIndex = btb_index(Fs0),
+ Fs = [function(F, FIndex) || F <- Fs0],
Code = {Mod,Exp,Attr,Fs,Lc},
case proplists:get_bool(bin_opt_info, Opts) of
true ->
@@ -92,10 +99,10 @@ format_error({no_bin_opt,Reason}) ->
%%% Local functions.
%%%
-function({function,Name,Arity,Entry,Is}, D0) ->
+function({function,Name,Arity,Entry,Is}, FIndex) ->
try
Index = beam_utils:index_labels(Is),
- D = D0#btb{index=Index},
+ D = #btb{f=FIndex,index=Index},
{function,Name,Arity,Entry,btb_opt_1(Is, D, [])}
catch
Class:Error ->
@@ -179,15 +186,14 @@ btb_gen_save(false, _, Acc) -> Acc.
%% a bs_context_to_binary instruction.
%%
-btb_reaches_match(Is, RegList, D0) ->
+btb_reaches_match(Is, RegList, D) ->
try
Regs = btb_regs_from_list(RegList),
- D = D0#btb{ok_br=gb_sets:empty(),must_not_save=false,must_save=false},
#btb{must_not_save=MustNotSave,must_save=MustSave} =
- btb_reaches_match_1(Is, Regs, D),
- case MustNotSave and MustSave of
+ btb_reaches_match_1(Is, Regs, D),
+ case MustNotSave andalso MustSave of
true -> btb_error(must_and_must_not_save);
- _ -> {ok,MustSave}
+ false -> {ok,MustSave}
end
catch
throw:{error,_}=Error -> Error
@@ -205,8 +211,15 @@ btb_reaches_match_1(Is, Regs, D) ->
btb_reaches_match_2([{block,Bl}|Is], Regs0, D) ->
Regs = btb_reaches_match_block(Bl, Regs0),
btb_reaches_match_1(Is, Regs, D);
-btb_reaches_match_2([{call,Arity,{f,Lbl}}|Is], Regs, D) ->
- btb_call(Arity, Lbl, Regs, Is, D);
+btb_reaches_match_2([{call,Arity,{f,Lbl}}|Is], Regs0, D) ->
+ case is_tail_call(Is) of
+ true ->
+ Regs1 = btb_kill_not_live(Arity, Regs0),
+ Regs = btb_kill_yregs(Regs1),
+ btb_tail_call(Lbl, Regs, D);
+ false ->
+ btb_call(Arity, Lbl, Regs0, Is, D)
+ end;
btb_reaches_match_2([{apply,Arity}|Is], Regs, D) ->
btb_call(Arity+2, apply, Regs, Is, D);
btb_reaches_match_2([{call_fun,Live}=I|Is], Regs, D) ->
@@ -360,6 +373,10 @@ btb_reaches_match_2([{line,_}|Is], Regs, D) ->
btb_reaches_match_2([I|_], Regs, _) ->
btb_error({btb_context_regs(Regs),I,not_handled}).
+is_tail_call([{deallocate,_}|_]) -> true;
+is_tail_call([return|_]) -> true;
+is_tail_call(_) -> false.
+
btb_call(Arity, Lbl, Regs0, Is, D0) ->
Regs = btb_kill_not_live(Arity, Regs0),
case btb_are_x_registers_empty(Regs) of
@@ -369,15 +386,15 @@ btb_call(Arity, Lbl, Regs0, Is, D0) ->
D = btb_tail_call(Lbl, Regs, D0),
%% No problem so far (the called function can handle a
- %% match context). Now we must make sure that the rest
- %% of this function following the call does not attempt
- %% to use the match context in case there is a copy
- %% tucked away in a y register.
+ %% match context). Now we must make sure that we don't
+ %% have any copies of the match context tucked away in an
+ %% y register.
RegList = btb_context_regs(Regs),
- YRegs = [R || {y,_}=R <- RegList],
- case btb_are_all_unused(YRegs, Is, D) of
- true -> D;
- false -> btb_error({multiple_uses,RegList})
+ case [R || {y,_}=R <- RegList] of
+ [] ->
+ D;
+ [_|_] ->
+ btb_error({multiple_uses,RegList})
end;
true ->
%% No match context in any x register. It could have been
diff --git a/lib/compiler/src/beam_clean.erl b/lib/compiler/src/beam_clean.erl
index 10805a3c36..b736d39f9c 100644
--- a/lib/compiler/src/beam_clean.erl
+++ b/lib/compiler/src/beam_clean.erl
@@ -26,6 +26,9 @@
-export([clean_labels/1]).
-import(lists, [map/2,foldl/3,reverse/1,filter/2]).
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,_}, Opts) ->
Order = [Lbl || {function,_,_,Lbl,_} <- Fs0],
All = foldl(fun({function,_,_,Lbl,_}=Func,D) -> dict:store(Lbl, Func, D) end,
@@ -39,6 +42,10 @@ module({Mod,Exp,Attr,Fs0,_}, Opts) ->
{ok,{Mod,Exp,Attr,Fs,Lc}}.
%% Remove all bs_save2/2 instructions not referenced by a bs_restore2/2.
+
+-spec bs_clean_saves([beam_utils:instruction()]) ->
+ [beam_utils:instruction()].
+
bs_clean_saves(Is) ->
Needed = bs_restores(Is, []),
bs_clean_saves_1(Is, gb_sets:from_list(Needed), []).
@@ -98,13 +105,18 @@ add_to_work_list(F, {Fs,Used}=Sets) ->
%%% want to see the expanded code in a .S file.
%%%
--record(st, {lmap, %Translation tables for labels.
- entry, %Number of entry label.
- lc %Label counter
+-type label() :: beam_asm:label().
+
+-record(st, {lmap :: [{label(),label()}], %Translation tables for labels.
+ entry :: beam_asm:label(), %Number of entry label.
+ lc :: non_neg_integer() %Label counter
}).
+-spec clean_labels([beam_utils:instruction()]) ->
+ {[beam_utils:instruction()],pos_integer()}.
+
clean_labels(Fs0) ->
- St0 = #st{lmap=[],lc=1},
+ St0 = #st{lmap=[],entry=1,lc=1},
{Fs1,#st{lmap=Lmap0,lc=Lc}} = function_renumber(Fs0, St0, []),
Lmap = gb_trees:from_orddict(ordsets:from_list(Lmap0)),
Fs = function_replace(Fs1, Lmap, []),
diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl
index b01f58f683..d379fdc4eb 100644
--- a/lib/compiler/src/beam_dead.erl
+++ b/lib/compiler/src/beam_dead.erl
@@ -29,6 +29,10 @@
-import(lists, [mapfoldl/3,reverse/1]).
+
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,_}, _Opts) ->
{Fs1,Lc1} = beam_clean:clean_labels(Fs0),
{Fs,Lc} = mapfoldl(fun function/2, Lc1, Fs1),
@@ -266,22 +270,41 @@ backward([{jump,{f,To0}},{move,Src,Reg}=Move|Is], D, Acc) ->
false -> backward([Move|Is], D, [Jump|Acc]);
true -> backward([Jump|Is], D, Acc)
end;
-backward([{jump,{f,To}}=J|[{bif,Op,_,Ops,Reg}|Is]=Is0], D, Acc) ->
+backward([{jump,{f,To}}=J|[{bif,Op,{f,BifFail},Ops,Reg}|Is]=Is0], D, Acc) ->
try replace_comp_op(To, Reg, Op, Ops, D) of
I -> backward(Is, D, I++Acc)
catch
- throw:not_possible -> backward(Is0, D, [J|Acc])
+ throw:not_possible ->
+ case To =:= BifFail of
+ true ->
+ %% The bif instruction is redundant. See the comment
+ %% in the next clause for why there is no need to
+ %% test for liveness of Reg at label To.
+ backward([J|Is], D, Acc);
+ false ->
+ backward(Is0, D, [J|Acc])
+ end
end;
+backward([{jump,{f,To}}=J|[{gc_bif,_,{f,To},_,_,_Dst}|Is]], D, Acc) ->
+ %% The gc_bif instruction is redundant, since either the gc_bif
+ %% instruction itself or the jump instruction will transfer control
+ %% to label To. Note that a gc_bif instruction does not assign its
+ %% destination register if the failure branch is taken; therefore,
+ %% the code at label To is not allowed to assume that the destination
+ %% register is initialized, and it is therefore no need to test
+ %% for liveness of the destination register at label To.
+ backward([J|Is], D, Acc);
backward([{test,bs_start_match2,F,Live,[R,_]=Args,Ctxt}|Is], D,
[{test,bs_match_string,F,[Ctxt,Bs]},
{test,bs_test_tail2,F,[Ctxt,0]}|Acc0]=Acc) ->
{f,To0} = F,
- To = shortcut_bs_start_match(To0, R, D),
case beam_utils:is_killed(Ctxt, Acc0, D) of
true ->
+ To = shortcut_bs_context_to_binary(To0, R, D),
Eq = {test,is_eq_exact,{f,To},[R,{literal,Bs}]},
backward(Is, D, [Eq|Acc0]);
false ->
+ To = shortcut_bs_start_match(To0, R, D),
I = {test,bs_start_match2,{f,To},Live,Args,Ctxt},
backward(Is, D, [I|Acc])
end;
@@ -360,6 +383,14 @@ backward([{kill,_}=I|Is], D, [{line,_},Exit|_]=Acc) ->
false -> backward(Is, D, [I|Acc]);
true -> backward(Is, D, Acc)
end;
+backward([{bif,'or',{f,To0},[Dst,{atom,false}],Dst}=I|Is], D,
+ [{test,is_eq_exact,{f,To},[Dst,{atom,true}]}|_]=Acc) ->
+ case shortcut_label(To0, D) of
+ To ->
+ backward(Is, D, Acc);
+ _ ->
+ backward(Is, D, [I|Acc])
+ end;
backward([I|Is], D, Acc) ->
backward(Is, D, [I|Acc]);
backward([], _D, Acc) -> Acc.
@@ -378,6 +409,8 @@ shortcut_select_list([Lit,{f,To0}|T], Reg, D, Acc) ->
shortcut_select_list(T, Reg, D, [{f,To},Lit|Acc]);
shortcut_select_list([], _, _, Acc) -> reverse(Acc).
+shortcut_label(0, _) ->
+ 0;
shortcut_label(To0, D) ->
case beam_utils:code_at(To0, D) of
[{jump,{f,To}}|_] -> shortcut_label(To, D);
@@ -554,6 +587,21 @@ shortcut_bs_start_match_1([{test,bs_start_match2,{f,To},_,[Reg|_],_}|_],
shortcut_bs_start_match_1(_, _, To, _) ->
To.
+%% shortcut_bs_context_to_binary(TargetLabel, Reg) -> TargetLabel
+%% If a bs_start_match2 instruction has been eliminated, the
+%% bs_context_to_binary instruction can be eliminated too.
+
+shortcut_bs_context_to_binary(To, Reg, D) ->
+ shortcut_bs_ctb_1(beam_utils:code_at(To, D), Reg, To, D).
+
+shortcut_bs_ctb_1([{bs_context_to_binary,Reg}|Is], Reg, To, D) ->
+ shortcut_bs_ctb_1(Is, Reg, To, D);
+shortcut_bs_ctb_1([{jump,{f,To}}|_], Reg, _, D) ->
+ Code = beam_utils:code_at(To, D),
+ shortcut_bs_ctb_1(Code, Reg, To, D);
+shortcut_bs_ctb_1(_, _, To, _) ->
+ To.
+
%% shortcut_rel_op(FailLabel, Operator, [Operand], D) -> FailLabel'
%% Try to shortcut the given test instruction. Example:
%%
diff --git a/lib/compiler/src/beam_dict.erl b/lib/compiler/src/beam_dict.erl
index 9565ab74c4..990e86062a 100644
--- a/lib/compiler/src/beam_dict.erl
+++ b/lib/compiler/src/beam_dict.erl
@@ -24,11 +24,11 @@
-export([new/0,opcode/2,highest_opcode/1,
atom/2,local/4,export/4,import/4,
string/2,lambda/3,literal/2,line/2,fname/2,
- atom_table/1,local_table/1,export_table/1,import_table/1,
+ atom_table/2,local_table/1,export_table/1,import_table/1,
string_table/1,lambda_table/1,literal_table/1,
line_table/1]).
--type label() :: non_neg_integer().
+-type label() :: beam_asm:label().
-type index() :: non_neg_integer().
@@ -38,13 +38,16 @@
-type line_tab() :: #{{Fname :: index(), Line :: term()} => index()}.
-type literal_tab() :: dict:dict(Literal :: term(), index()).
+-type lambda_info() :: {label(),{index(),label(),non_neg_integer()}}.
+-type lambda_tab() :: {non_neg_integer(),[lambda_info()]}.
+
-record(asm,
{atoms = #{} :: atom_tab(),
exports = [] :: [{label(), arity(), label()}],
locals = [] :: [{label(), arity(), label()}],
imports = gb_trees:empty() :: import_tab(),
strings = <<>> :: binary(), %String pool
- lambdas = {0,[]}, %[{...}]
+ lambdas = {0,[]} :: lambda_tab(),
literals = dict:new() :: literal_tab(),
fnames = #{} :: fname_tab(),
lines = #{} :: line_tab(),
@@ -148,10 +151,7 @@ string(Str, Dict) when is_list(Str) ->
lambda(Lbl, NumFree, #asm{lambdas={OldIndex,Lambdas0}}=Dict) ->
%% Set Index the same as OldIndex.
Index = OldIndex,
- %% Initialize OldUniq to 0. It will be set to an unique value
- %% based on the MD5 checksum of the BEAM code for the module.
- OldUniq = 0,
- Lambdas = [{Lbl,{OldIndex,Lbl,Index,NumFree,OldUniq}}|Lambdas0],
+ Lambdas = [{Lbl,{Index,Lbl,NumFree}}|Lambdas0],
{OldIndex,Dict#asm{lambdas={OldIndex+1,Lambdas}}}.
%% Returns the index for a literal (adding it to the literal table if necessary).
@@ -185,6 +185,9 @@ line([{location,Name,Line}], #asm{lines=Lines,num_lines=N}=Dict0) ->
{Index, Dict1#asm{lines=Lines#{Key=>Index},num_lines=N+1}}
end.
+-spec fname(nonempty_string(), bdict()) ->
+ {non_neg_integer(), bdict()}.
+
fname(Name, #asm{fnames=Fnames}=Dict) ->
case Fnames of
#{Name := Index} -> {Index,Dict};
@@ -194,15 +197,15 @@ fname(Name, #asm{fnames=Fnames}=Dict) ->
end.
%% Returns the atom table.
-%% atom_table(Dict) -> {LastIndex,[Length,AtomString...]}
--spec atom_table(bdict()) -> {non_neg_integer(), [[non_neg_integer(),...]]}.
+%% atom_table(Dict, Encoding) -> {LastIndex,[Length,AtomString...]}
+-spec atom_table(bdict(), latin1 | utf8) -> {non_neg_integer(), [[non_neg_integer(),...]]}.
-atom_table(#asm{atoms=Atoms}) ->
+atom_table(#asm{atoms=Atoms}, Encoding) ->
NumAtoms = maps:size(Atoms),
Sorted = lists:keysort(2, maps:to_list(Atoms)),
{NumAtoms,[begin
- L = atom_to_list(A),
- [length(L)|L]
+ L = atom_to_binary(A, Encoding),
+ [byte_size(L),L]
end || {A,_} <- Sorted]}.
%% Returns the table of local functions.
@@ -239,8 +242,11 @@ lambda_table(#asm{locals=Loc0,lambdas={NumLambdas,Lambdas0}}) ->
Lambdas1 = sofs:relation(Lambdas0),
Loc = sofs:relation([{Lbl,{F,A}} || {F,A,Lbl} <- Loc0]),
Lambdas2 = sofs:relative_product1(Lambdas1, Loc),
+ %% Initialize OldUniq to 0. It will be set to an unique value
+ %% based on the MD5 checksum of the BEAM code for the module.
+ OldUniq = 0,
Lambdas = [<<F:32,A:32,Lbl:32,Index:32,NumFree:32,OldUniq:32>> ||
- {{_,Lbl,Index,NumFree,OldUniq},{F,A}} <- sofs:to_external(Lambdas2)],
+ {{Index,Lbl,NumFree},{F,A}} <- sofs:to_external(Lambdas2)],
{NumLambdas,Lambdas}.
%% Returns the literal table.
diff --git a/lib/compiler/src/beam_disasm.erl b/lib/compiler/src/beam_disasm.erl
index c699672db1..8fd0b36d05 100644
--- a/lib/compiler/src/beam_disasm.erl
+++ b/lib/compiler/src/beam_disasm.erl
@@ -815,6 +815,9 @@ resolve_inst({is_tuple=I,Args0},_,_,_) ->
resolve_inst({test_arity=I,Args0},_,_,_) ->
[L|Args] = resolve_args(Args0),
{test,I,L,Args};
+resolve_inst({is_tagged_tuple=I,Args0},_,_,_) ->
+ [F|Args] = resolve_args(Args0),
+ {test,I,F,Args};
resolve_inst({select_val,Args},_,_,_) ->
[Reg,FLbl,{{z,1},{u,_Len},List0}] = Args,
List = resolve_args(List0),
diff --git a/lib/compiler/src/beam_except.erl b/lib/compiler/src/beam_except.erl
index 4a181c1923..9801c68ee2 100644
--- a/lib/compiler/src/beam_except.erl
+++ b/lib/compiler/src/beam_except.erl
@@ -33,6 +33,9 @@
-import(lists, [reverse/1]).
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc}, _Opt) ->
Fs = [function(F) || F <- Fs0],
{ok,{Mod,Exp,Attr,Fs,Lc}}.
@@ -49,9 +52,9 @@ function({function,Name,Arity,CLabel,Is0}) ->
end.
-record(st,
- {lbl, %func_info label
- loc, %location for func_info
- arity %arity for function
+ {lbl :: beam_asm:label(), %func_info label
+ loc :: [_], %location for func_info
+ arity :: arity() %arity for function
}).
function_1(Is0) ->
diff --git a/lib/compiler/src/beam_flatten.erl b/lib/compiler/src/beam_flatten.erl
index 36369bd0b4..a4d45a4ca6 100644
--- a/lib/compiler/src/beam_flatten.erl
+++ b/lib/compiler/src/beam_flatten.erl
@@ -25,6 +25,9 @@
-import(lists, [reverse/1,reverse/2]).
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs,Lc}, _Opt) ->
{ok,{Mod,Exp,Attr,[function(F) || F <- Fs],Lc}}.
@@ -64,7 +67,6 @@ norm({set,[],[S,D],{set_tuple_element,I}}) -> {set_tuple_element,S,D,I};
norm({set,[D1,D2],[S],get_list}) -> {get_list,S,D1,D2};
norm({set,[D],[S|Puts],{alloc,R,{put_map,Op,F}}}) ->
{put_map,F,Op,S,D,R,{list,Puts}};
-%% get_map_elements is always handled in beam_split (moved out of block)
norm({set,[],[],remove_message}) -> remove_message;
norm({set,[],[],fclearerror}) -> fclearerror;
norm({set,[],[],fcheckerror}) -> {fcheckerror,{f,0}}.
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index 09cd3aa2d4..4365451356 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -23,7 +23,7 @@
-export([module/2,
is_unreachable_after/1,is_exit_instruction/1,
- remove_unused_labels/1,is_label_used_in/2]).
+ remove_unused_labels/1]).
%%% The following optimisations are done:
%%%
@@ -130,6 +130,11 @@
-import(lists, [reverse/1,reverse/2,foldl/3]).
+-type instruction() :: beam_utils:instruction().
+
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc}, _Opt) ->
Fs = [function(F) || F <- Fs0],
{ok,{Mod,Exp,Attr,Fs,Lc}}.
@@ -155,9 +160,7 @@ share(Is0) ->
Is = eliminate_fallthroughs(Is0, []),
share_1(Is, #{}, [], []).
-share_1([{label,_}=Lbl|Is], Dict, [], Acc) ->
- share_1(Is, Dict, [], [Lbl|Acc]);
-share_1([{label,L}=Lbl|Is], Dict0, Seq, Acc) ->
+share_1([{label,L}=Lbl|Is], Dict0, [_|_]=Seq, Acc) ->
case maps:find(Seq, Dict0) of
error ->
Dict = maps:put(Seq, L, Dict0),
@@ -167,12 +170,18 @@ share_1([{label,L}=Lbl|Is], Dict0, Seq, Acc) ->
end;
share_1([{func_info,_,_,_}=I|Is], _, [], Acc) ->
reverse(Is, [I|Acc]);
+share_1([{'catch',_,_}=I|Is], Dict0, Seq, Acc) ->
+ Dict = clean_non_sharable(Dict0),
+ share_1(Is, Dict, [I|Seq], Acc);
share_1([{'try',_,_}=I|Is], Dict0, Seq, Acc) ->
Dict = clean_non_sharable(Dict0),
share_1(Is, Dict, [I|Seq], Acc);
share_1([{try_case,_}=I|Is], Dict0, Seq, Acc) ->
Dict = clean_non_sharable(Dict0),
share_1(Is, Dict, [I|Seq], Acc);
+share_1([{catch_end,_}=I|Is], Dict0, Seq, Acc) ->
+ Dict = clean_non_sharable(Dict0),
+ share_1(Is, Dict, [I|Seq], Acc);
share_1([I|Is], Dict, Seq, Acc) ->
case is_unreachable_after(I) of
false ->
@@ -182,18 +191,18 @@ share_1([I|Is], Dict, Seq, Acc) ->
end.
clean_non_sharable(Dict) ->
- %% We are passing in or out of a 'try' block. Remove
- %% sequences that should not shared over the boundaries
- %% of a 'try' block. Since the end of the sequence must match,
- %% the only possible match between a sequence outside and
- %% a sequence inside the 'try' block is a sequence that ends
- %% with an instruction that causes an exception. Any sequence
- %% that causes an exception must contain a line/1 instruction.
+ %% We are passing in or out of a 'catch' or 'try' block. Remove
+ %% sequences that should not be shared over the boundaries of the
+ %% block. Since the end of the sequence must match, the only
+ %% possible match between a sequence outside and a sequence inside
+ %% the 'catch'/'try' block is a sequence that ends with an
+ %% instruction that causes an exception. Any sequence that causes
+ %% an exception must contain a line/1 instruction.
maps:filter(fun(K, _V) -> sharable_with_try(K) end, Dict).
sharable_with_try([{line,_}|_]) ->
%% This sequence may cause an exception and may potentially
- %% match a sequence on the other side of the 'try' block
+ %% match a sequence on the other side of the 'catch'/'try' block
%% boundary.
false;
sharable_with_try([_|Is]) ->
@@ -202,21 +211,18 @@ sharable_with_try([]) -> true.
%% Eliminate all fallthroughs. Return the result reversed.
-eliminate_fallthroughs([I,{label,L}=Lbl|Is], Acc) ->
- case is_unreachable_after(I) orelse is_label(I) of
+eliminate_fallthroughs([{label,L}=Lbl|Is], [I|_]=Acc) ->
+ case is_unreachable_after(I) of
false ->
%% Eliminate fallthrough.
- eliminate_fallthroughs(Is, [Lbl,{jump,{f,L}},I|Acc]);
+ eliminate_fallthroughs(Is, [Lbl,{jump,{f,L}}|Acc]);
true ->
- eliminate_fallthroughs(Is, [Lbl,I|Acc])
+ eliminate_fallthroughs(Is, [Lbl|Acc])
end;
eliminate_fallthroughs([I|Is], Acc) ->
eliminate_fallthroughs(Is, [I|Acc]);
eliminate_fallthroughs([], Acc) -> Acc.
-is_label({label,_}) -> true;
-is_label(_) -> false.
-
%%%
%%% (2) Move short code sequences ending in an instruction that causes an exit
%%% to the end of the function.
@@ -268,9 +274,9 @@ extract_seq_1(_, _) -> no.
-record(st,
{
- entry, %Entry label (must not be moved).
- mlbl, %Moved labels.
- labels :: cerl_sets:set() %Set of referenced labels.
+ entry :: beam_asm:label(), %Entry label (must not be moved).
+ mlbl :: #{beam_asm:label() := [beam_asm:label()]}, %Moved labels.
+ labels :: cerl_sets:set() %Set of referenced labels.
}).
opt(Is0, CLabel) ->
@@ -452,6 +458,8 @@ is_label_used(L, St) ->
%% is_unreachable_after(Instruction) -> boolean()
%% Test whether the code after Instruction is unreachable.
+-spec is_unreachable_after(instruction()) -> boolean().
+
is_unreachable_after({func_info,_M,_F,_A}) -> true;
is_unreachable_after(return) -> true;
is_unreachable_after({jump,_Lbl}) -> true;
@@ -464,6 +472,8 @@ is_unreachable_after(I) -> is_exit_instruction(I).
%% Test whether the instruction Instruction always
%% causes an exit/failure.
+-spec is_exit_instruction(instruction()) -> boolean().
+
is_exit_instruction({call_ext,_,{extfunc,M,F,A}}) ->
erl_bifs:is_exit_bif(M, F, A);
is_exit_instruction(if_end) -> true;
@@ -472,40 +482,12 @@ is_exit_instruction({try_case_end,_}) -> true;
is_exit_instruction({badmatch,_}) -> true;
is_exit_instruction(_) -> false.
-%% is_label_used_in(LabelNumber, [Instruction]) -> boolean()
-%% Check whether the label is used in the instruction sequence
-%% (including inside blocks).
-
-is_label_used_in(Lbl, Is) ->
- is_label_used_in_1(Is, Lbl, cerl_sets:new()).
-
-is_label_used_in_1([{block,Block}|Is], Lbl, Empty) ->
- lists:any(fun(I) -> is_label_used_in_block(I, Lbl) end, Block)
- orelse is_label_used_in_1(Is, Lbl, Empty);
-is_label_used_in_1([I|Is], Lbl, Empty) ->
- Used = ulbl(I, Empty),
- cerl_sets:is_element(Lbl, Used) orelse is_label_used_in_1(Is, Lbl, Empty);
-is_label_used_in_1([], _, _) -> false.
-
-is_label_used_in_block({set,_,_,Info}, Lbl) ->
- case Info of
- {bif,_,{f,F}} -> F =:= Lbl;
- {alloc,_,{gc_bif,_,{f,F}}} -> F =:= Lbl;
- {alloc,_,{put_map,_,{f,F}}} -> F =:= Lbl;
- {get_map_elements,{f,F}} -> F =:= Lbl;
- {try_catch,_,{f,F}} -> F =:= Lbl;
- {alloc,_,_} -> false;
- {put_tuple,_} -> false;
- {get_tuple_element,_} -> false;
- {set_tuple_element,_} -> false;
- {line,_} -> false;
- _ when is_atom(Info) -> false
- end.
-
%% remove_unused_labels(Instructions0) -> Instructions
%% Remove all unused labels. Also remove unreachable
%% instructions following labels that are removed.
+-spec remove_unused_labels([instruction()]) -> [instruction()].
+
remove_unused_labels(Is) ->
Used0 = initial_labels(Is),
Used = foldl(fun ulbl/2, Used0, Is),
diff --git a/lib/compiler/src/beam_listing.erl b/lib/compiler/src/beam_listing.erl
index ce566373bb..94b47cf568 100644
--- a/lib/compiler/src/beam_listing.erl
+++ b/lib/compiler/src/beam_listing.erl
@@ -21,14 +21,24 @@
-export([module/2]).
+-include("core_parse.hrl").
+-include("v3_kernel.hrl").
-include("v3_life.hrl").
-import(lists, [foreach/2]).
-module(File, Core) when element(1, Core) == c_module ->
+-type code() :: cerl:c_module()
+ | beam_utils:module_code()
+ | #k_mdef{}
+ | {module(),_,_,_} %v3_life
+ | [_]. %form-based format
+
+-spec module(file:io_device(), code()) -> 'ok'.
+
+module(File, #c_module{}=Core) ->
%% This is a core module.
io:put_chars(File, core_pp:format(Core));
-module(File, Kern) when element(1, Kern) == k_mdef ->
+module(File, #k_mdef{}=Kern) ->
%% This is a kernel module.
io:put_chars(File, v3_kernel_pp:format(Kern));
%%io:put_chars(File, io_lib:format("~p~n", [Kern]));
@@ -49,10 +59,6 @@ module(Stream, {Mod,Exp,Attr,Code,NumLabels}) ->
[Name, Arity, Entry]),
io:put_chars(Stream, format_asm(Asm))
end, Code);
-module(Stream, {Mod,Exp,Inter}) ->
- %% Other kinds of intermediate formats.
- io:fwrite(Stream, "~w.~n~p.~n", [Mod,Exp]),
- foreach(fun (F) -> io:format(Stream, "~p.\n", [F]) end, Inter);
module(Stream, [_|_]=Fs) ->
%% Form-based abstract format.
foreach(fun (F) -> io:format(Stream, "~p.\n", [F]) end, Fs).
diff --git a/lib/compiler/src/beam_peep.erl b/lib/compiler/src/beam_peep.erl
index c8bef31824..6df5c02334 100644
--- a/lib/compiler/src/beam_peep.erl
+++ b/lib/compiler/src/beam_peep.erl
@@ -24,6 +24,9 @@
-import(lists, [reverse/1,member/2]).
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,_}, _Opts) ->
%% First coalesce adjacent labels.
{Fs1,Lc} = beam_clean:clean_labels(Fs0),
diff --git a/lib/compiler/src/beam_receive.erl b/lib/compiler/src/beam_receive.erl
index 89cafe27ce..1403e1e05e 100644
--- a/lib/compiler/src/beam_receive.erl
+++ b/lib/compiler/src/beam_receive.erl
@@ -65,6 +65,9 @@
%%% as the SomeUniqInteger.
%%%
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc}, _Opts) ->
Fs = [function(F) || F <- Fs0],
Code = {Mod,Exp,Attr,Fs,Lc},
diff --git a/lib/compiler/src/beam_record.erl b/lib/compiler/src/beam_record.erl
new file mode 100644
index 0000000000..419089b1bc
--- /dev/null
+++ b/lib/compiler/src/beam_record.erl
@@ -0,0 +1,106 @@
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014-2017. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, 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: beam_record.erl
+%% Author: Björn-Egil Dahlberg
+%% Created: 2014-09-03
+%%
+
+-module(beam_record).
+-export([module/2]).
+
+%% Rewrite the instruction stream on tagged tuple tests.
+%% Tagged tuples means a tuple of any arity with an atom as its first element.
+%% Typically records, ok-tuples and error-tuples.
+%%
+%% from:
+%% ...
+%% {test,is_tuple,Fail,[Src]}.
+%% {test,test_arity,Fail,[Src,Sz]}.
+%% ...
+%% {get_tuple_element,Src,0,Dst}.
+%% ...
+%% {test,is_eq_exact,Fail,[Dst,Atom]}.
+%% ...
+%% to:
+%% ...
+%% {test,is_tagged_tuple,Fail,[Src,Sz,Atom]}.
+%% ...
+
+
+-import(lists, [reverse/1]).
+
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
+module({Mod,Exp,Attr,Fs0,Lc}, _Opt) ->
+ Fs = [function(F) || F <- Fs0],
+ {ok,{Mod,Exp,Attr,Fs,Lc}}.
+
+function({function,Name,Arity,CLabel,Is}) ->
+ try
+ Idx = beam_utils:index_labels(Is),
+ {function,Name,Arity,CLabel,rewrite(Is,Idx)}
+ catch
+ Class:Error ->
+ Stack = erlang:get_stacktrace(),
+ io:fwrite("Function: ~w/~w\n", [Name,Arity]),
+ erlang:raise(Class, Error, Stack)
+ end.
+
+rewrite(Is,Idx) ->
+ rewrite(Is,Idx,[]).
+
+rewrite([{test,is_tuple,Fail,[Src]}=I1,
+ {test,test_arity,Fail,[Src,N]}=I2|Is],Idx,Acc) ->
+ case is_tagged_tuple(Is,Fail,Src,Idx) of
+ no ->
+ rewrite(Is,Idx,[I2,I1|Acc]);
+ {Atom,[{block,[]}|Is1]} ->
+ rewrite(Is1,Idx,[{test,is_tagged_tuple,Fail,[Src,N,Atom]}|Acc]);
+ {Atom,Is1} ->
+ rewrite(Is1,Idx,[{test,is_tagged_tuple,Fail,[Src,N,Atom]}|Acc])
+ end;
+rewrite([I|Is],Idx,Acc) ->
+ rewrite(Is,Idx,[I|Acc]);
+rewrite([],_,Acc) -> reverse(Acc).
+
+is_tagged_tuple([{block,[{set,[Dst],[Src],{get_tuple_element,0}}=B|Bs]},
+ {test,is_eq_exact,Fail,[Dst,{atom,_}=Atom]}|Is],Fail,Src,Idx) ->
+
+ %% if Dst is killed in the instruction stream and at fail label,
+ %% we can safely remove get_tuple_element.
+ %%
+ %% if Dst is not killed in the stream, we cannot remove get_tuple_element
+ %% since it is referenced.
+
+ case is_killed(Dst,Is,Fail,Idx) of
+ true -> {Atom,[{block,Bs}|Is]};
+ false -> {Atom,[{block,[B|Bs]}|Is]}
+ end;
+is_tagged_tuple([{block,[{set,_,_,_}=B|Bs]},
+ {test,is_eq_exact,_,_}=I|Is],Fail,Src,Idx) ->
+ case is_tagged_tuple([{block,Bs},I|Is],Fail,Src,Idx) of
+ {Atom,[{block,Bsr}|Isr]} -> {Atom,[{block,[B|Bsr]}|Isr]};
+ no -> no
+ end;
+is_tagged_tuple(_Is,_Fail,_Src,_Idx) ->
+ no.
+
+is_killed(Dst,Is,{_,Lbl},Idx) ->
+ beam_utils:is_killed(Dst,Is,Idx) andalso
+ beam_utils:is_killed_at(Dst,Lbl,Idx).
diff --git a/lib/compiler/src/beam_reorder.erl b/lib/compiler/src/beam_reorder.erl
index 6a7c033ec6..910b7f6b0a 100644
--- a/lib/compiler/src/beam_reorder.erl
+++ b/lib/compiler/src/beam_reorder.erl
@@ -23,6 +23,9 @@
-export([module/2]).
-import(lists, [member/2,reverse/1]).
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc}, _Opt) ->
Fs = [function(F) || F <- Fs0],
{ok,{Mod,Exp,Attr,Fs,Lc}}.
diff --git a/lib/compiler/src/beam_split.erl b/lib/compiler/src/beam_split.erl
index c83c686953..d041f18806 100644
--- a/lib/compiler/src/beam_split.erl
+++ b/lib/compiler/src/beam_split.erl
@@ -23,6 +23,9 @@
-import(lists, [reverse/1]).
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc}, _Opts) ->
Fs = [split_blocks(F) || F <- Fs0],
{ok,{Mod,Exp,Attr,Fs,Lc}}.
@@ -56,9 +59,6 @@ split_block([{set,[D],[S|Puts],{alloc,R,{put_map,Op,{f,Lbl}=Fail}}}|Is],
Bl, Acc) when Lbl =/= 0 ->
split_block(Is, [], [{put_map,Fail,Op,S,D,R,{list,Puts}}|
make_block(Bl, Acc)]);
-split_block([{set,Ds,[S|Ss],{get_map_elements,Fail}}|Is], Bl, Acc) ->
- Gets = beam_utils:join_even(Ss,Ds),
- split_block(Is, [], [{get_map_elements,Fail,S,{list,Gets}}|make_block(Bl, Acc)]);
split_block([{set,[R],[],{try_catch,Op,L}}|Is], Bl, Acc) ->
split_block(Is, [], [{Op,R,L}|make_block(Bl, Acc)]);
split_block([{set,[],[],{line,_}=Line}|Is], Bl, Acc) ->
diff --git a/lib/compiler/src/beam_trim.erl b/lib/compiler/src/beam_trim.erl
index a8dc6805bc..4da0985085 100644
--- a/lib/compiler/src/beam_trim.erl
+++ b/lib/compiler/src/beam_trim.erl
@@ -24,10 +24,13 @@
-import(lists, [reverse/1,reverse/2,splitwith/2,sort/1]).
-record(st,
- {safe, %Safe labels.
- lbl %Code at each label.
+ {safe :: gb_sets:set(beam_asm:label()), %Safe labels.
+ lbl :: beam_utils:code_index() %Code at each label.
}).
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc}, _Opts) ->
Fs = [function(F) || F <- Fs0],
{ok,{Mod,Exp,Attr,Fs,Lc}}.
@@ -230,7 +233,7 @@ safe_labels([], Acc) -> gb_sets:from_list(Acc).
frame_layout(Is, Kills, #st{safe=Safe,lbl=D}) ->
N = frame_size(Is, Safe),
- IsKilled = fun(R) -> beam_utils:is_killed(R, Is, D) end,
+ IsKilled = fun(R) -> beam_utils:is_not_used(R, Is, D) end,
{N,frame_layout_1(Kills, 0, N, IsKilled, [])}.
frame_layout_1([{kill,{y,Y}}=I|Ks], Y, N, IsKilled, Acc) ->
diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl
index acaf3ede66..3d842a6fd3 100644
--- a/lib/compiler/src/beam_type.erl
+++ b/lib/compiler/src/beam_type.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -26,6 +26,11 @@
-import(lists, [filter/2,foldl/3,keyfind/3,member/2,
reverse/1,reverse/2,sort/1]).
+-define(UNICODE_INT, {integer,{0,16#10FFFF}}).
+
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc}, _Opts) ->
Fs = [function(F) || F <- Fs0],
{ok,{Mod,Exp,Attr,Fs,Lc}}.
@@ -34,7 +39,8 @@ function({function,Name,Arity,CLabel,Asm0}) ->
try
Asm1 = beam_utils:live_opt(Asm0),
Asm2 = opt(Asm1, [], tdb_new()),
- Asm = beam_utils:delete_live_annos(Asm2),
+ Asm3 = beam_utils:live_opt(Asm2),
+ Asm = beam_utils:delete_live_annos(Asm3),
{function,Name,Arity,CLabel,Asm}
catch
Class:Error ->
@@ -490,6 +496,10 @@ update({test,test_arity,_Fail,[Src,Arity]}, Ts0) ->
tdb_update([{Src,{tuple,Arity,[]}}], Ts0);
update({test,is_map,_Fail,[Src]}, Ts0) ->
tdb_update([{Src,map}], Ts0);
+update({get_map_elements,_,Src,{list,Elems0}}, Ts0) ->
+ {_Ss,Ds} = beam_utils:split_even(Elems0),
+ Elems = [{Dst,kill} || Dst <- Ds],
+ tdb_update([{Src,map}|Elems], Ts0);
update({test,is_nonempty_list,_Fail,[Src]}, Ts0) ->
tdb_update([{Src,nonempty_list}], Ts0);
update({test,is_eq_exact,_,[Reg,{atom,_}=Atom]}, Ts) ->
@@ -503,10 +513,39 @@ update({test,is_eq_exact,_,[Reg,{atom,_}=Atom]}, Ts) ->
end;
update({test,is_record,_Fail,[Src,Tag,{integer,Arity}]}, Ts) ->
tdb_update([{Src,{tuple,Arity,[Tag]}}], Ts);
-update({test,_Test,_Fail,_Other}, Ts) ->
- Ts;
+
+%% Binary matching
+
update({test,bs_get_integer2,_,_,Args,Dst}, Ts) ->
tdb_update([{Dst,get_bs_integer_type(Args)}], Ts);
+update({test,bs_get_utf8,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,?UNICODE_INT}], Ts);
+update({test,bs_get_utf16,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,?UNICODE_INT}], Ts);
+update({test,bs_get_utf32,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,?UNICODE_INT}], Ts);
+update({bs_init,_,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,kill}], Ts);
+update({bs_put,_,_,_}, Ts) ->
+ Ts;
+update({bs_save2,_,_}, Ts) ->
+ Ts;
+update({bs_restore2,_,_}, Ts) ->
+ Ts;
+update({bs_context_to_binary,Dst}, Ts) ->
+ tdb_update([{Dst,kill}], Ts);
+update({test,bs_start_match2,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,kill}], Ts);
+update({test,bs_get_binary2,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,kill}], Ts);
+update({test,bs_get_float2,_,_,_,Dst}, Ts) ->
+ tdb_update([{Dst,float}], Ts);
+
+update({test,_Test,_Fail,_Other}, Ts) ->
+ Ts;
+
+%% Calls
+
update({call_ext,Ar,{extfunc,math,Math,Ar}}, Ts) ->
case is_math_bif(Math, Ar) of
true -> tdb_update([{{x,0},float}], Ts);
@@ -533,9 +572,10 @@ update({call_ext,3,{extfunc,erlang,setelement,3}}, Ts0) ->
update({call,_Arity,_Func}, Ts) -> tdb_kill_xregs(Ts);
update({call_ext,_Arity,_Func}, Ts) -> tdb_kill_xregs(Ts);
update({make_fun2,_,_,_,_}, Ts) -> tdb_kill_xregs(Ts);
+update({call_fun, _}, Ts) -> tdb_kill_xregs(Ts);
+update({apply, _}, Ts) -> tdb_kill_xregs(Ts);
+
update({line,_}, Ts) -> Ts;
-update({bs_save2,_,_}, Ts) -> Ts;
-update({bs_restore2,_,_}, Ts) -> Ts;
%% The instruction is unknown. Kill all information.
update(_I, _Ts) -> tdb_new().
@@ -592,6 +632,9 @@ is_math_bif(log10, 1) -> true;
is_math_bif(sqrt, 1) -> true;
is_math_bif(atan2, 2) -> true;
is_math_bif(pow, 2) -> true;
+is_math_bif(ceil, 1) -> true;
+is_math_bif(floor, 1) -> true;
+is_math_bif(fmod, 2) -> true;
is_math_bif(pi, 0) -> true;
is_math_bif(_, _) -> false.
@@ -676,6 +719,9 @@ op_type('bsr') -> integer;
op_type('div') -> integer;
op_type(_) -> unknown.
+flush(Rs, [{set,[_],[_,_,_],{bif,is_record,_}}|_]=Is0, Acc0) ->
+ Acc = flush_all(Rs, Is0, Acc0),
+ {[],Acc};
flush(Rs, [{set,[_],[],{put_tuple,_}}|_]=Is0, Acc0) ->
Acc = flush_all(Rs, Is0, Acc0),
{[],Acc};
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index a15ecf633e..cc6e54ca16 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -22,18 +22,37 @@
-module(beam_utils).
-export([is_killed_block/2,is_killed/3,is_killed_at/3,
- is_not_used/3,is_not_used_at/3,
+ is_not_used/3,
empty_label_index/0,index_label/3,index_labels/1,
code_at/2,bif_to_test/3,is_pure_test/1,
live_opt/1,delete_live_annos/1,combine_heap_needs/2,
- join_even/2,split_even/1]).
+ split_even/1]).
+
+-export_type([code_index/0,module_code/0,instruction/0]).
-import(lists, [member/2,sort/1,reverse/1,splitwith/2]).
+%% instruction() describes all instructions that are used during optimzation
+%% (from beam_a to beam_z).
+-type instruction() :: atom() | tuple().
+
+-type code_index() :: gb_trees:tree(beam_asm:label(), [instruction()]).
+
+-type int_function() :: {'function',beam_asm:function_name(),arity(),
+ beam_asm:label(),[instruction()]}.
+
+-type module_code() ::
+ {module(),[_],[_],[int_function()],pos_integer()}.
+
+%% Internal types.
+-type fail() :: beam_asm:fail() | 'fail'.
+-type test() :: {'test',atom(),fail(),[beam_asm:src()]} |
+ {'test',atom(),fail(),integer(),list(),beam_asm:reg()}.
+-type result_cache() :: gb_trees:tree(beam_asm:label(), 'killed' | 'used').
+
-record(live,
- {bl, %Block check fun.
- lbl, %Label to code index.
- res}). %Result cache for each label.
+ {lbl :: code_index(), %Label to code index.
+ res :: result_cache()}). %Result cache for each label.
%% is_killed_block(Register, [Instruction]) -> true|false
@@ -45,12 +64,18 @@
%% i.e. it is OK to enter the instruction sequence with Register
%% containing garbage.
-is_killed_block(R, Is) ->
- case check_killed_block(R, Is) of
- killed -> true;
- used -> false;
- transparent -> false
- end.
+-spec is_killed_block(beam_asm:reg(), [instruction()]) -> boolean().
+
+is_killed_block({x,X}, [{set,_,_,{alloc,Live,_}}|_]) ->
+ X >= Live;
+is_killed_block(R, [{set,Ds,Ss,_Op}|Is]) ->
+ not member(R, Ss) andalso (member(R, Ds) orelse is_killed_block(R, Is));
+is_killed_block(R, [{'%live',_,Regs}|Is]) ->
+ case R of
+ {x,X} when (Regs bsr X) band 1 =:= 0 -> true;
+ _ -> is_killed_block(R, Is)
+ end;
+is_killed_block(_, []) -> false.
%% is_killed(Register, [Instruction], State) -> true|false
%% Determine whether a register is killed by the instruction sequence.
@@ -62,21 +87,25 @@ is_killed_block(R, Is) ->
%% The state (constructed by index_instructions/1) is used to allow us
%% to determine the kill state across branches.
+-spec is_killed(beam_asm:reg(), [instruction()], code_index()) -> boolean().
+
is_killed(R, Is, D) ->
- St = #live{bl=check_killed_block_fun(),lbl=D,res=gb_trees:empty()},
+ St = #live{lbl=D,res=gb_trees:empty()},
case check_liveness(R, Is, St) of
{killed,_} -> true;
- {used,_} -> false
+ {_,_} -> false
end.
%% is_killed_at(Reg, Lbl, State) -> true|false
%% Determine whether Reg is killed at label Lbl.
+-spec is_killed_at(beam_asm:reg(), beam_asm:label(), code_index()) -> boolean().
+
is_killed_at(R, Lbl, D) when is_integer(Lbl) ->
- St0 = #live{bl=check_killed_block_fun(),lbl=D,res=gb_trees:empty()},
+ St0 = #live{lbl=D,res=gb_trees:empty()},
case check_liveness_at(R, Lbl, St0) of
{killed,_} -> true;
- {used,_} -> false
+ {_,_} -> false
end.
%% is_not_used(Register, [Instruction], State) -> true|false
@@ -86,43 +115,38 @@ is_killed_at(R, Lbl, D) when is_integer(Lbl) ->
%% The state is used to allow us to determine the usage state
%% across branches.
+-spec is_not_used(beam_asm:reg(), [instruction()], code_index()) -> boolean().
+
is_not_used(R, Is, D) ->
- St = #live{bl=fun check_used_block/3,lbl=D,res=gb_trees:empty()},
+ St = #live{lbl=D,res=gb_trees:empty()},
case check_liveness(R, Is, St) of
- {killed,_} -> true;
- {used,_} -> false
- end.
-
-%% is_not_used(Register, [Instruction], State) -> true|false
-%% Determine whether a register is never used in the instruction sequence
-%% (it could still be referenced by an allocate instruction, meaning that
-%% it MUST be initialized, but that its value does not matter).
-%% The state is used to allow us to determine the usage state
-%% across branches.
-
-is_not_used_at(R, Lbl, D) ->
- St = #live{bl=fun check_used_block/3,lbl=D,res=gb_trees:empty()},
- case check_liveness_at(R, Lbl, St) of
- {killed,_} -> true;
- {used,_} -> false
+ {used,_} -> false;
+ {_,_} -> true
end.
%% index_labels(FunctionIs) -> State
%% Index the instruction sequence so that we can quickly
%% look up the instruction following a specific label.
+-spec index_labels([instruction()]) -> code_index().
+
index_labels(Is) ->
index_labels_1(Is, []).
%% empty_label_index() -> State
%% Create an empty label index.
+-spec empty_label_index() -> code_index().
+
empty_label_index() ->
gb_trees:empty().
%% index_label(Label, [Instruction], State) -> State
%% Add an index for a label.
+-spec index_label(beam_asm:label(), [instruction()], code_index()) ->
+ code_index().
+
index_label(Lbl, Is0, Acc) ->
Is = drop_labels(Is0),
gb_trees:enter(Lbl, Is, Acc).
@@ -131,12 +155,16 @@ index_label(Lbl, Is0, Acc) ->
%% code_at(Label, State) -> [I].
%% Retrieve the code at the given label.
+-spec code_at(beam_asm:label(), code_index()) -> [instruction()].
+
code_at(L, Ll) ->
gb_trees:get(L, Ll).
%% bif_to_test(Bif, [Op], Fail) -> {test,Test,Fail,[Op]}
%% Convert a BIF to a test. Fail if not possible.
+-spec bif_to_test(atom(), list(), fail()) -> test().
+
bif_to_test(is_atom, [_]=Ops, Fail) -> {test,is_atom,Fail,Ops};
bif_to_test(is_boolean, [_]=Ops, Fail) -> {test,is_boolean,Fail,Ops};
bif_to_test(is_binary, [_]=Ops, Fail) -> {test,is_binary,Fail,Ops};
@@ -169,6 +197,9 @@ bif_to_test(is_record, [_,_,_]=Ops, Fail) -> {test,is_record,Fail,Ops}.
%% Return 'true' if the test instruction does not modify any
%% registers and/or bit syntax matching state.
%%
+
+-spec is_pure_test(test()) -> boolean().
+
is_pure_test({test,is_eq,_,[_,_]}) -> true;
is_pure_test({test,is_ne,_,[_,_]}) -> true;
is_pure_test({test,is_eq_exact,_,[_,_]}) -> true;
@@ -191,7 +222,9 @@ is_pure_test({test,Op,_,Ops}) ->
%% whose destination is a register that will not be used.
%% Also insert {'%live',Live,Regs} annotations at the beginning
%% and end of each block.
-%%
+
+-spec live_opt([instruction()]) -> [instruction()].
+
live_opt(Is0) ->
{[{label,Fail}|_]=Bef,[Fi|Is]} =
splitwith(fun({func_info,_,_,_}) -> false;
@@ -204,7 +237,9 @@ live_opt(Is0) ->
%% delete_live_annos([Instruction]) -> [Instruction].
%% Delete all live annotations.
-%%
+
+-spec delete_live_annos([instruction()]) -> [instruction()].
+
delete_live_annos([{block,Bl0}|Is]) ->
case delete_live_annos(Bl0) of
[] -> delete_live_annos(Is);
@@ -219,6 +254,8 @@ delete_live_annos([]) -> [].
%% combine_heap_needs(HeapNeed1, HeapNeed2) -> HeapNeed
%% Combine the heap need for two allocation instructions.
+-spec combine_heap_needs(term(), term()) -> term().
+
combine_heap_needs({alloc,Alloc1}, {alloc,Alloc2}) ->
{alloc,combine_alloc_lists(Alloc1, Alloc2)};
combine_heap_needs({alloc,Alloc}, Words) when is_integer(Words) ->
@@ -231,13 +268,10 @@ combine_heap_needs(H1, H2) when is_integer(H1), is_integer(H2) ->
%% split_even/1
%% [1,2,3,4,5,6] -> {[1,3,5],[2,4,6]}
-split_even(Rs) -> split_even(Rs, [], []).
+-spec split_even(list()) -> {list(),list()}.
-%% join_even/1
-%% {[1,3,5],[2,4,6]} -> [1,2,3,4,5,6]
+split_even(Rs) -> split_even(Rs, [], []).
-join_even([], []) -> [];
-join_even([S|Ss], [D|Ds]) -> [S,D|join_even(Ss, Ds)].
%%%
%%% Local functions.
@@ -245,15 +279,19 @@ join_even([S|Ss], [D|Ds]) -> [S,D|join_even(Ss, Ds)].
%% check_liveness(Reg, [Instruction], #live{}) ->
-%% {killed | used, #live{}}
+%% {killed | not_used | used, #live{}}
%% Find out whether Reg is used or killed in instruction sequence.
-%% 'killed' means that Reg is assigned a new value or killed by an
-%% allocation instruction. 'used' means that Reg is used in some way.
+%%
+%% killed - Reg is assigned or killed by an allocation instruction.
+%% not_used - the value of Reg is not used, but Reg must not be garbage
+%% used - Reg is used
-check_liveness(R, [{block,Blk}|Is], #live{bl=BlockCheck}=St0) ->
- case BlockCheck(R, Blk, St0) of
- {transparent,St} -> check_liveness(R, Is, St);
- {Other,_}=Res when is_atom(Other) -> Res
+check_liveness(R, [{block,Blk}|Is], St0) ->
+ case check_liveness_block(R, Blk, St0) of
+ {transparent,St1} ->
+ check_liveness(R, Is, St1);
+ {Other,_}=Res when is_atom(Other) ->
+ Res
end;
check_liveness(R, [{label,_}|Is], St) ->
check_liveness(R, Is, St);
@@ -263,8 +301,12 @@ check_liveness(R, [{test,_,{f,Fail},As}|Is], St0) ->
{used,St0};
false ->
case check_liveness_at(R, Fail, St0) of
- {killed,St} -> check_liveness(R, Is, St);
- {_,_}=Other -> Other
+ {killed,St1} ->
+ check_liveness(R, Is, St1);
+ {not_used,St1} ->
+ not_used(check_liveness(R, Is, St1));
+ {used,_}=Used ->
+ Used
end
end;
check_liveness(R, [{test,Op,Fail,Live,Ss,Dst}|Is], St) ->
@@ -334,7 +376,7 @@ check_liveness(R, [{call,Live,_}|Is], St) ->
case R of
{x,X} when X < Live -> {used,St};
{x,_} -> {killed,St};
- {y,_} -> check_liveness(R, Is, St)
+ {y,_} -> not_used(check_liveness(R, Is, St))
end;
check_liveness(R, [{call_ext,Live,_}=I|Is], St) ->
case R of
@@ -345,7 +387,7 @@ check_liveness(R, [{call_ext,Live,_}=I|Is], St) ->
{y,_} ->
case beam_jump:is_exit_instruction(I) of
false ->
- check_liveness(R, Is, St);
+ not_used(check_liveness(R, Is, St));
true ->
%% We must make sure we don't check beyond this
%% instruction or we will fall through into random
@@ -357,43 +399,20 @@ check_liveness(R, [{call_fun,Live}|Is], St) ->
case R of
{x,X} when X =< Live -> {used,St};
{x,_} -> {killed,St};
- {y,_} -> check_liveness(R, Is, St)
+ {y,_} -> not_used(check_liveness(R, Is, St))
end;
check_liveness(R, [{apply,Args}|Is], St) ->
case R of
{x,X} when X < Args+2 -> {used,St};
{x,_} -> {killed,St};
- {y,_} -> check_liveness(R, Is, St)
- end;
-check_liveness(R, [{bif,Op,{f,Fail},Ss,D}|Is], St0) ->
- case check_liveness_fail(R, Op, Ss, Fail, St0) of
- {killed,St} = Killed ->
- case member(R, Ss) of
- true -> {used,St};
- false when R =:= D -> Killed;
- false -> check_liveness(R, Is, St)
- end;
- Other ->
- Other
- end;
-check_liveness(R, [{gc_bif,Op,{f,Fail},Live,Ss,D}|Is], St0) ->
- case R of
- {x,X} when X >= Live ->
- {killed,St0};
- {x,_} ->
- {used,St0};
- _ ->
- case check_liveness_fail(R, Op, Ss, Fail, St0) of
- {killed,St}=Killed ->
- case member(R, Ss) of
- true -> {used,St};
- false when R =:= D -> Killed;
- false -> check_liveness(R, Is, St)
- end;
- Other ->
- Other
- end
- end;
+ {y,_} -> not_used(check_liveness(R, Is, St))
+ end;
+check_liveness(R, [{bif,Op,Fail,Ss,D}|Is], St) ->
+ Set = {set,[D],Ss,{bif,Op,Fail}},
+ check_liveness(R, [{block,[Set]}|Is], St);
+check_liveness(R, [{gc_bif,Op,{f,Fail},Live,Ss,D}|Is], St) ->
+ Set = {set,[D],Ss,{alloc,Live,{gc_bif,Op,Fail}}},
+ check_liveness(R, [{block,[Set]}|Is], St);
check_liveness(R, [{bs_put,{f,0},_,Ss}|Is], St) ->
case member(R, Ss) of
true -> {used,St};
@@ -419,7 +438,7 @@ check_liveness(R, [{make_fun2,_,_,_,NumFree}|Is], St) ->
case R of
{x,X} when X < NumFree -> {used,St};
{x,_} -> {killed,St};
- _ -> check_liveness(R, Is, St)
+ {y,_} -> not_used(check_liveness(R, Is, St))
end;
check_liveness({x,_}=R, [{'catch',_,_}|Is], St) ->
%% All x registers will be killed if an exception occurs.
@@ -488,18 +507,9 @@ check_liveness(R, [{get_map_elements,{f,Fail},S,{list,L}}|Is], St0) ->
Other
end
end;
-check_liveness(R, [{put_map,{f,_},_,Src,_D,Live,{list,_}}|_], St0) ->
- case R of
- Src ->
- {used,St0};
- {x,X} when X < Live ->
- {used,St0};
- {x,_} ->
- {killed,St0};
- {y,_} ->
- %% Conservatively mark it as used.
- {used,St0}
- end;
+check_liveness(R, [{put_map,F,Op,S,D,Live,{list,Puts}}|Is], St) ->
+ Set = {set,[D],[S|Puts],{alloc,Live,{put_map,Op,F}}},
+ check_liveness(R, [{block,[Set]}||Is], St);
check_liveness(R, [{test_heap,N,Live}|Is], St) ->
I = {block,[{set,[],[],{alloc,Live,{nozero,nostack,N,[]}}}]},
check_liveness(R, [I|Is], St);
@@ -512,16 +522,24 @@ check_liveness(R, [{get_list,S,D1,D2}|Is], St) ->
check_liveness(_R, Is, St) when is_list(Is) ->
%% Not implemented. Conservatively assume that the register is used.
{used,St}.
-
-check_liveness_everywhere(R, [{f,Lbl}|T], St0) ->
- case check_liveness_at(R, Lbl, St0) of
- {killed,St} -> check_liveness_everywhere(R, T, St);
- {_,_}=Other -> Other
+
+check_liveness_everywhere(R, Lbls, St0) ->
+ check_liveness_everywhere_1(R, Lbls, killed, St0).
+
+check_liveness_everywhere_1(R, [{f,Lbl}|T], Res0, St0) ->
+ {Res1,St} = check_liveness_at(R, Lbl, St0),
+ Res = case Res1 of
+ killed -> Res0;
+ _ -> Res1
+ end,
+ case Res of
+ used -> {used,St};
+ _ -> check_liveness_everywhere_1(R, T, Res, St)
end;
-check_liveness_everywhere(R, [_|T], St) ->
- check_liveness_everywhere(R, T, St);
-check_liveness_everywhere(_, [], St) ->
- {killed,St}.
+check_liveness_everywhere_1(R, [_|T], Res, St) ->
+ check_liveness_everywhere_1(R, T, Res, St);
+check_liveness_everywhere_1(_, [], Res, St) ->
+ {Res,St}.
check_liveness_at(R, Lbl, #live{lbl=Ll,res=ResMemorized}=St0) ->
case gb_trees:lookup(Lbl, ResMemorized) of
@@ -535,56 +553,20 @@ check_liveness_at(R, Lbl, #live{lbl=Ll,res=ResMemorized}=St0) ->
{Res,St#live{res=gb_trees:insert(Lbl, Res, St#live.res)}}
end.
+not_used({killed,St}) -> {not_used,St};
+not_used({_,_}=Res) -> Res.
+
check_liveness_ret(R, R, St) -> {used,St};
check_liveness_ret(_, _, St) -> {killed,St}.
-check_liveness_fail(_, _, _, 0, St) ->
- {killed,St};
-check_liveness_fail(R, Op, Args, Fail, St) ->
- Arity = length(Args),
- case erl_internal:comp_op(Op, Arity) orelse
- erl_internal:new_type_test(Op, Arity) of
- true -> {killed,St};
- false -> check_liveness_at(R, Fail, St)
- end.
-
-%% check_killed_block(Reg, [Instruction], State) -> killed | transparent | used
-%% Finds out how Reg is used in the instruction sequence inside a block.
-%% Returns one of:
-%% killed - Reg is assigned a new value or killed by an allocation instruction
-%% transparent - Reg is neither used nor killed
-%% used - Reg is used or referenced by an allocation instruction.
-%%
-%% (Unknown instructions will cause an exception.)
-
-check_killed_block_fun() ->
- fun(R, Is, St) -> {check_killed_block(R, Is),St} end.
-
-check_killed_block({x,X}, [{set,_,_,{alloc,Live,_}}|_]) ->
- if
- X >= Live -> killed;
- true -> used
- end;
-check_killed_block(R, [{set,Ds,Ss,_Op}|Is]) ->
- case member(R, Ss) of
- true -> used;
- false ->
- case member(R, Ds) of
- true -> killed;
- false -> check_killed_block(R, Is)
- end
- end;
-check_killed_block(R, [{'%live',_,Regs}|Is]) ->
- case R of
- {x,X} when (Regs bsr X) band 1 =:= 0 -> killed;
- _ -> check_killed_block(R, Is)
- end;
-check_killed_block(_, []) -> transparent.
-
-%% check_used_block(Reg, [Instruction], State) -> killed | transparent | used
+%% check_liveness_block(Reg, [Instruction], State) ->
+%% {killed | not_used | used | transparent,State'}
%% Finds out how Reg is used in the instruction sequence inside a block.
%% Returns one of:
-%% killed - Reg is assigned a new value or killed by an allocation instruction
+%% killed - Reg is assigned a new value or killed by an
+%% allocation instruction
+%% not_used - The value is not used, but the register is referenced
+%% e.g. by an allocation instruction
%% transparent - Reg is neither used nor killed
%% used - Reg is explicitly used by an instruction
%%
@@ -592,45 +574,64 @@ check_killed_block(_, []) -> transparent.
%%
%% (Unknown instructions will cause an exception.)
-check_used_block({x,X}=R, [{set,Ds,Ss,{alloc,Live,Op}}|Is], St) ->
+check_liveness_block({x,X}=R, [{set,Ds,Ss,{alloc,Live,Op}}|Is], St0) ->
if
- X >= Live -> {killed,St};
- true -> check_used_block_1(R, Ss, Ds, Op, Is, St)
+ X >= Live ->
+ {killed,St0};
+ true ->
+ case check_liveness_block_1(R, Ss, Ds, Op, Is, St0) of
+ {killed,St} -> {not_used,St};
+ {transparent,St} -> {not_used,St};
+ {_,_}=Res -> Res
+ end
end;
-check_used_block(R, [{set,Ds,Ss,Op}|Is], St) ->
- check_used_block_1(R, Ss, Ds, Op, Is, St);
-check_used_block(_, [], St) -> {transparent,St}.
+check_liveness_block({y,_}=R, [{set,Ds,Ss,{alloc,_Live,Op}}|Is], St) ->
+ check_liveness_block_1(R, Ss, Ds, Op, Is, St);
+check_liveness_block(R, [{set,Ds,Ss,Op}|Is], St) ->
+ check_liveness_block_1(R, Ss, Ds, Op, Is, St);
+check_liveness_block(_, [], St) -> {transparent,St}.
-check_used_block_1(R, Ss, Ds, Op, Is, St0) ->
+check_liveness_block_1(R, Ss, Ds, Op, Is, St0) ->
case member(R, Ss) of
true ->
{used,St0};
false ->
- case is_reg_used_at(R, Op, St0) of
- {true,St} ->
- {used,St};
- {false,St} ->
+ case check_liveness_block_2(R, Op, Ss, St0) of
+ {killed,St} ->
case member(R, Ds) of
true -> {killed,St};
- false -> check_used_block(R, Is, St)
- end
+ false -> check_liveness_block(R, Is, St)
+ end;
+ {not_used,St} ->
+ not_used(case member(R, Ds) of
+ true -> {killed,St};
+ false -> check_liveness_block(R, Is, St)
+ end);
+ {used,St} ->
+ {used,St}
end
end.
-is_reg_used_at(R, {gc_bif,_,{f,Lbl}}, St) ->
- is_reg_used_at_1(R, Lbl, St);
-is_reg_used_at(R, {bif,_,{f,Lbl}}, St) ->
- is_reg_used_at_1(R, Lbl, St);
-is_reg_used_at(_, _, St) ->
- {false,St}.
+check_liveness_block_2(R, {gc_bif,_Op,{f,Lbl}}, _Ss, St) ->
+ check_liveness_block_3(R, Lbl, St);
+check_liveness_block_2(R, {bif,Op,{f,Lbl}}, Ss, St) ->
+ Arity = length(Ss),
+ case erl_internal:comp_op(Op, Arity) orelse
+ erl_internal:new_type_test(Op, Arity) of
+ true ->
+ {killed,St};
+ false ->
+ check_liveness_block_3(R, Lbl, St)
+ end;
+check_liveness_block_2(R, {put_map,_Op,{f,Lbl}}, _Ss, St) ->
+ check_liveness_block_3(R, Lbl, St);
+check_liveness_block_2(_, _, _, St) ->
+ {killed,St}.
-is_reg_used_at_1(_, 0, St) ->
- {false,St};
-is_reg_used_at_1(R, Lbl, St0) ->
- case check_liveness_at(R, Lbl, St0) of
- {killed,St} -> {false,St};
- {used,St} -> {true,St}
- end.
+check_liveness_block_3(_, 0, St) ->
+ {killed,St};
+check_liveness_block_3(R, Lbl, St0) ->
+ check_liveness_at(R, Lbl, St0).
index_labels_1([{label,Lbl}|Is0], Acc) ->
Is = drop_labels(Is0),
@@ -753,6 +754,11 @@ live_opt([timeout=I|Is], _, D, Acc) ->
live_opt(Is, 0, D, [I|Acc]);
live_opt([{wait,_}=I|Is], _, D, Acc) ->
live_opt(Is, 0, D, [I|Acc]);
+live_opt([{get_map_elements,Fail,Src,{list,List}}=I|Is], Regs0, D, Acc) ->
+ {Ss,Ds} = split_even(List),
+ Regs1 = x_live([Src|Ss], x_dead(Ds, Regs0)),
+ Regs = live_join_label(Fail, D, Regs1),
+ live_opt(Is, Regs, D, [I|Acc]);
%% Transparent instructions - they neither use nor modify x registers.
live_opt([{deallocate,_}=I|Is], Regs, D, Acc) ->
@@ -812,6 +818,8 @@ live_opt_block([{set,Ds,Ss,Op}=I0|Is], Regs0, D, Acc) ->
_ ->
live_opt_block(Is, Regs, D, [I|Acc])
end;
+live_opt_block([{'%live',_,_}|Is], Regs, D, Acc) ->
+ live_opt_block(Is, Regs, D, Acc);
live_opt_block([], Regs, _, Acc) -> {Acc,Regs}.
live_join_labels([{f,L}|T], D, Regs0) when L =/= 0 ->
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 4c0cb6780a..f726625510 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,6 +32,10 @@
-import(lists, [reverse/1,foldl/3,foreach/2,dropwhile/2]).
%% To be called by the compiler.
+
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_utils:module_code()}.
+
module({Mod,Exp,Attr,Fs,Lc}=Code, _Opts)
when is_atom(Mod), is_list(Exp), is_list(Attr), is_integer(Lc) ->
case validate(Mod, Fs) of
@@ -619,17 +623,17 @@ valfun_4({test,bs_skip_utf16,{f,Fail},[Ctx,Live,_]}, Vst) ->
valfun_4({test,bs_skip_utf32,{f,Fail},[Ctx,Live,_]}, Vst) ->
validate_bs_skip_utf(Fail, Ctx, Live, Vst);
valfun_4({test,bs_get_integer2,{f,Fail},Live,[Ctx,_,_,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, {integer, []}, Dst, Vst);
valfun_4({test,bs_get_float2,{f,Fail},Live,[Ctx,_,_,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, {float, []}, Dst, Vst);
valfun_4({test,bs_get_binary2,{f,Fail},Live,[Ctx,_,_,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, term, Dst, Vst);
valfun_4({test,bs_get_utf8,{f,Fail},Live,[Ctx,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, {integer, []}, Dst, Vst);
valfun_4({test,bs_get_utf16,{f,Fail},Live,[Ctx,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, {integer, []}, Dst, Vst);
valfun_4({test,bs_get_utf32,{f,Fail},Live,[Ctx,_],Dst}, Vst) ->
- validate_bs_get(Fail, Ctx, Live, Dst, Vst);
+ validate_bs_get(Fail, Ctx, Live, {integer, []}, Dst, Vst);
valfun_4({bs_save2,Ctx,SavePoint}, Vst) ->
bsm_save(Ctx, SavePoint, Vst);
valfun_4({bs_restore2,Ctx,SavePoint}, Vst) ->
@@ -649,6 +653,9 @@ valfun_4({test,is_nonempty_list,{f,Lbl},[Cons]}, Vst) ->
valfun_4({test,test_arity,{f,Lbl},[Tuple,Sz]}, Vst) when is_integer(Sz) ->
assert_type(tuple, Tuple, Vst),
set_type_reg({tuple,Sz}, Tuple, branch_state(Lbl, Vst));
+valfun_4({test,is_tagged_tuple,{f,Lbl},[Src,Sz,_Atom]}, Vst) ->
+ validate_src([Src], Vst),
+ set_type_reg({tuple, Sz}, Src, branch_state(Lbl, Vst));
valfun_4({test,has_map_fields,{f,Lbl},Src,{list,List}}, Vst) ->
assert_type(map, Src, Vst),
assert_unique_map_keys(List),
@@ -787,12 +794,12 @@ verify_put_map(Fail, Src, Dst, Live, List, Vst0) ->
%%
%% Common code for validating bs_get* instructions.
%%
-validate_bs_get(Fail, Ctx, Live, Dst, Vst0) ->
+validate_bs_get(Fail, Ctx, Live, Type, Dst, Vst0) ->
bsm_validate_context(Ctx, Vst0),
verify_live(Live, Vst0),
Vst1 = prune_x_regs(Live, Vst0),
Vst = branch_state(Fail, Vst1),
- set_type_reg(term, Dst, Vst).
+ set_type_reg(Type, Dst, Vst).
%%
%% Common code for validating bs_skip_utf* instructions.
@@ -808,9 +815,11 @@ validate_bs_skip_utf(Fail, Ctx, Live, Vst0) ->
%% A possibility for garbage collection must not occur between setelement/3 and
%% set_tuple_element/3.
%%
+%% Note that #vst.current will be 'none' if the instruction is unreachable.
+%%
val_dsetel({move,_,_}, Vst) ->
Vst;
-val_dsetel({call_ext,3,{extfunc,erlang,setelement,3}}, #vst{current=St}=Vst) ->
+val_dsetel({call_ext,3,{extfunc,erlang,setelement,3}}, #vst{current=#st{}=St}=Vst) ->
Vst#vst{current=St#st{setelem=true}};
val_dsetel({set_tuple_element,_,_,_}, #vst{current=#st{setelem=false}}) ->
error(illegal_context_for_set_tuple_element);
@@ -907,7 +916,7 @@ all_ms_in_x_regs(Live0, Vst) ->
ms_in_y_regs(Id, #vst{current=#st{y=Ys0}}) ->
Ys = gb_trees:to_list(Ys0),
- [Y || {Y,#ms{id=OtherId}} <- Ys, OtherId =:= Id].
+ [{y,Y} || {Y,#ms{id=OtherId}} <- Ys, OtherId =:= Id].
verify_call_match_context(Lbl, Ctx, #vst{ft=Ft}) ->
case gb_trees:lookup(Lbl, Ft) of
@@ -1506,7 +1515,9 @@ bif_type(abs, [Num], Vst) ->
bif_type(float, _, _) -> {float,[]};
bif_type('/', _, _) -> {float,[]};
%% Integer operations.
+bif_type(ceil, [_], _) -> {integer,[]};
bif_type('div', [_,_], _) -> {integer,[]};
+bif_type(floor, [_], _) -> {integer,[]};
bif_type('rem', [_,_], _) -> {integer,[]};
bif_type(length, [_], _) -> {integer,[]};
bif_type(size, [_], _) -> {integer,[]};
@@ -1640,6 +1651,9 @@ return_type_math(log10, 1) -> {float,[]};
return_type_math(sqrt, 1) -> {float,[]};
return_type_math(atan2, 2) -> {float,[]};
return_type_math(pow, 2) -> {float,[]};
+return_type_math(ceil, 1) -> {float,[]};
+return_type_math(floor, 1) -> {float,[]};
+return_type_math(fmod, 2) -> {float,[]};
return_type_math(pi, 0) -> {float,[]};
return_type_math(F, A) when is_atom(F), is_integer(A), A >= 0 -> term.
diff --git a/lib/compiler/src/beam_z.erl b/lib/compiler/src/beam_z.erl
index 6c7f8543c2..787e33c142 100644
--- a/lib/compiler/src/beam_z.erl
+++ b/lib/compiler/src/beam_z.erl
@@ -26,6 +26,9 @@
-import(lists, [dropwhile/2]).
+-spec module(beam_utils:module_code(), [compile:option()]) ->
+ {'ok',beam_asm:module_code()}.
+
module({Mod,Exp,Attr,Fs0,Lc}, _Opt) ->
Fs = [function(F) || F <- Fs0],
{ok,{Mod,Exp,Attr,Fs,Lc}}.
diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl
index 61abae344c..6b936a7687 100644
--- a/lib/compiler/src/cerl.erl
+++ b/lib/compiler/src/cerl.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +10,8 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-
-%% =====================================================================
+%% @copyright 1999-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Core Erlang abstract syntax trees.
%%
%% <p> This module defines an abstract data type for representing Core
@@ -1590,6 +1584,8 @@ ann_make_list(_, [], Node) ->
%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
%% map constructor, otherwise <code>false</code>.
+-type map_op() :: #c_literal{val::'assoc'} | #c_literal{val::'exact'}.
+
-spec is_c_map(cerl()) -> boolean().
is_c_map(#c_map{}) ->
@@ -1685,8 +1681,16 @@ update_c_map(#c_map{is_pat=true}=Old, M, Es) ->
update_c_map(#c_map{is_pat=false}=Old, M, Es) ->
ann_c_map(get_ann(Old), M, Es).
+-spec map_pair_key(c_map_pair()) -> cerl().
+
map_pair_key(#c_map_pair{key=K}) -> K.
+
+-spec map_pair_val(c_map_pair()) -> cerl().
+
map_pair_val(#c_map_pair{val=V}) -> V.
+
+-spec map_pair_op(c_map_pair()) -> map_op().
+
map_pair_op(#c_map_pair{op=Op}) -> Op.
-spec c_map_pair(cerl(), cerl()) -> c_map_pair().
@@ -1705,6 +1709,8 @@ c_map_pair_exact(Key,Val) ->
ann_c_map_pair(As,Op,K,V) ->
#c_map_pair{op=Op, key = K, val=V, anno = As}.
+-spec update_c_map_pair(c_map_pair(), map_op(), cerl(), cerl()) -> c_map_pair().
+
update_c_map_pair(Old,Op,K,V) ->
#c_map_pair{op=Op, key=K, val=V, anno = get_ann(Old)}.
diff --git a/lib/compiler/src/cerl_clauses.erl b/lib/compiler/src/cerl_clauses.erl
index 805095e30c..7d6518c3c6 100644
--- a/lib/compiler/src/cerl_clauses.erl
+++ b/lib/compiler/src/cerl_clauses.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +10,8 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-
+%% @copyright 1999-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Utility functions for Core Erlang case/receive clauses.
%%
%% <p>Syntax trees are defined in the module <a
diff --git a/lib/compiler/src/cerl_inline.erl b/lib/compiler/src/cerl_inline.erl
index 2a8cf2e758..f5afa75b16 100644
--- a/lib/compiler/src/cerl_inline.erl
+++ b/lib/compiler/src/cerl_inline.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +10,9 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% Core Erlang inliner.
+%% @copyright 1999-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
+%% @doc Core Erlang inliner.
%% =====================================================================
%%
diff --git a/lib/compiler/src/cerl_trees.erl b/lib/compiler/src/cerl_trees.erl
index b3decbec1f..f30a0b33ac 100644
--- a/lib/compiler/src/cerl_trees.erl
+++ b/lib/compiler/src/cerl_trees.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +10,8 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-
+%% @copyright 1999-2002 Richard Carlsson.
+%% @author Richard Carlsson <[email protected]>
%% @doc Basic functions on Core Erlang abstract syntax trees.
%%
%% <p>Syntax trees are defined in the module <a
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 82ff8a95f3..aa2d224bb4 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -43,6 +43,10 @@
-type abstract_code() :: [erl_parse:abstract_form()].
+%% Internal representations used for 'from_asm' and 'from_beam' compilation can
+%% also be valid, but have no relevant types defined.
+-type forms() :: abstract_code() | cerl:c_module().
+
-type option() :: atom() | {atom(), term()} | {'d', atom(), term()}.
-type err_info() :: {erl_anno:line() | 'none',
@@ -88,7 +92,7 @@ file(File, Opt) ->
forms(Forms) -> forms(Forms, ?DEFAULT_OPTIONS).
--spec forms(abstract_code(), [option()] | option()) -> comp_ret().
+-spec forms(forms(), [option()] | option()) -> comp_ret().
forms(Forms, Opts) when is_list(Opts) ->
do_compile({forms,Forms}, [binary|Opts++env_default_opts()]);
@@ -116,7 +120,7 @@ noenv_file(File, Opts) when is_list(Opts) ->
noenv_file(File, Opt) ->
noenv_file(File, [Opt|?DEFAULT_OPTIONS]).
--spec noenv_forms(abstract_code(), [option()] | option()) -> comp_ret().
+-spec noenv_forms(forms(), [option()] | option()) -> comp_ret().
noenv_forms(Forms, Opts) when is_list(Opts) ->
do_compile({forms,Forms}, [binary|Opts]);
@@ -143,8 +147,8 @@ env_compiler_options() -> env_default_opts().
%% Local functions
%%
--define(pass(P), {P,fun P/1}).
--define(pass(P,T), {P,fun T/1,fun P/1}).
+-define(pass(P), {P,fun P/2}).
+-define(pass(P,T), {P,fun T/1,fun P/2}).
env_default_opts() ->
Key = "ERL_COMPILER_OPTIONS",
@@ -169,26 +173,34 @@ env_default_opts() ->
do_compile(Input, Opts0) ->
Opts = expand_opts(Opts0),
- {Pid,Ref} =
- spawn_monitor(fun() ->
- exit(try
- internal(Input, Opts)
- catch
- error:Reason ->
- {error,Reason}
- end)
- end),
- receive
- {'DOWN',Ref,process,Pid,Rep} -> Rep
+ IntFun = fun() -> try
+ internal(Input, Opts)
+ catch
+ error:Reason ->
+ {error,Reason}
+ end
+ end,
+ %% Dialyzer has already spawned workers.
+ case lists:member(dialyzer, Opts) of
+ true ->
+ IntFun();
+ false ->
+ {Pid,Ref} =
+ spawn_monitor(fun() ->
+ exit(IntFun())
+ end),
+ receive
+ {'DOWN',Ref,process,Pid,Rep} -> Rep
+ end
end.
expand_opts(Opts0) ->
%% {debug_info_key,Key} implies debug_info.
Opts = case {proplists:get_value(debug_info_key, Opts0),
proplists:get_value(encrypt_debug_info, Opts0),
- proplists:get_bool(debug_info, Opts0)} of
+ proplists:get_value(debug_info, Opts0)} of
{undefined,undefined,_} -> Opts0;
- {_,_,false} -> [debug_info|Opts0];
+ {_,_,undefined} -> [debug_info|Opts0];
{_,_,_} -> Opts0
end,
foldr(fun expand_opt/2, [], Opts).
@@ -201,12 +213,14 @@ expand_opt(report, Os) ->
[report_errors,report_warnings|Os];
expand_opt(return, Os) ->
[return_errors,return_warnings|Os];
-expand_opt(r12, Os) ->
- [no_recv_opt,no_line_info|Os];
-expand_opt(r13, Os) ->
- [no_recv_opt,no_line_info|Os];
-expand_opt(r14, Os) ->
- [no_line_info|Os];
+expand_opt(r16, Os) ->
+ [no_record_opt,no_utf8_atoms|Os];
+expand_opt(r17, Os) ->
+ [no_record_opt,no_utf8_atoms|Os];
+expand_opt(r18, Os) ->
+ [no_record_opt,no_utf8_atoms|Os];
+expand_opt(r19, Os) ->
+ [no_record_opt,no_utf8_atoms|Os];
expand_opt({debug_info_key,_}=O, Os) ->
[encrypt_debug_info,O|Os];
expand_opt(no_float_opt, Os) ->
@@ -216,6 +230,8 @@ expand_opt(O, Os) -> [O|Os].
%% format_error(ErrorDescriptor) -> string()
+-spec format_error(term()) -> iolist().
+
format_error(no_native_support) ->
"this system is not configured for native-code compilation.";
format_error(no_crypto) ->
@@ -236,6 +252,8 @@ format_error({epp,E}) ->
epp:format_error(E);
format_error(write_error) ->
"error writing file";
+format_error({write_error, Error}) ->
+ io_lib:format("error writing file: ~ts", [file:format_error(Error)]);
format_error({rename,From,To,Error}) ->
io_lib:format("failed to rename ~ts to ~ts: ~ts",
[From,To,file:format_error(Error)]);
@@ -246,9 +264,9 @@ format_error({delete_temp,File,Error}) ->
io_lib:format("failed to delete temporary file ~ts: ~ts",
[File,file:format_error(Error)]);
format_error({parse_transform,M,R}) ->
- io_lib:format("error in parse transform '~s': ~tp", [M, R]);
+ io_lib:format("error in parse transform '~ts': ~tp", [M, R]);
format_error({undef_parse_transform,M}) ->
- io_lib:format("undefined parse transform '~s'", [M]);
+ io_lib:format("undefined parse transform '~ts'", [M]);
format_error({core_transform,M,R}) ->
io_lib:format("error in core transform '~s': ~tp", [M, R]);
format_error({crash,Pass,Reason}) ->
@@ -274,34 +292,41 @@ format_error_reason({Reason, Stack}) when is_list(Stack) ->
format_error_reason(Reason) ->
io_lib:format("~tp", [Reason]).
+-type err_warn_info() :: tuple().
+
%% The compile state record.
-record(compile, {filename="" :: file:filename(),
dir="" :: file:filename(),
base="" :: file:filename(),
ifile="" :: file:filename(),
ofile="" :: file:filename(),
- module=[],
- code=[],
- core_code=[],
- abstract_code=[], %Abstract code for debugger.
- options=[] :: [option()], %Options for compilation
+ module=[] :: module() | [],
+ core_code=[] :: cerl:c_module() | [],
+ abstract_code=[] :: abstract_code(), %Abstract code for debugger.
+ options=[] :: [option()], %Options for compilation
mod_options=[] :: [option()], %Options for module_info
encoding=none :: none | epp:source_encoding(),
- errors=[],
- warnings=[]}).
+ errors=[] :: [err_warn_info()],
+ warnings=[] :: [err_warn_info()],
+ extra_chunks=[] :: [{binary(), binary()}]}).
internal({forms,Forms}, Opts0) ->
{_,Ps} = passes(forms, Opts0),
Source = proplists:get_value(source, Opts0, ""),
Opts1 = proplists:delete(source, Opts0),
- Compile = #compile{code=Forms,options=Opts1,mod_options=Opts1},
- internal_comp(Ps, Source, "", Compile);
+ Compile = build_compile(Opts1),
+ internal_comp(Ps, Forms, Source, "", Compile);
internal({file,File}, Opts) ->
{Ext,Ps} = passes(file, Opts),
- Compile = #compile{options=Opts,mod_options=Opts},
- internal_comp(Ps, File, Ext, Compile).
+ Compile = build_compile(Opts),
+ internal_comp(Ps, none, File, Ext, Compile).
-internal_comp(Passes, File, Suffix, St0) ->
+build_compile(Opts0) ->
+ ExtraChunks = proplists:get_value(extra_chunks, Opts0, []),
+ Opts1 = proplists:delete(extra_chunks, Opts0),
+ #compile{options=Opts1,mod_options=Opts1,extra_chunks=ExtraChunks}.
+
+internal_comp(Passes, Code0, File, Suffix, St0) ->
Dir = filename:dirname(File),
Base = filename:basename(File, Suffix),
St1 = St0#compile{filename=File, dir=Dir, base=Base,
@@ -311,36 +336,41 @@ internal_comp(Passes, File, Suffix, St0) ->
Run0 = case member(time, Opts) of
true ->
io:format("Compiling ~tp\n", [File]),
- fun run_tc/2;
- false -> fun({_Name,Fun}, St) -> catch Fun(St) end
+ fun run_tc/3;
+ false ->
+ fun({_Name,Fun}, Code, St) ->
+ catch Fun(Code, St)
+ end
end,
Run = case keyfind(eprof, 1, Opts) of
{eprof,EprofPass} ->
- fun(P, St) ->
- run_eprof(P, EprofPass, St)
+ fun(P, Code, St) ->
+ run_eprof(P, Code, EprofPass, St)
end;
false ->
Run0
end,
- case fold_comp(Passes, Run, St1) of
- {ok,St2} -> comp_ret_ok(St2);
+ case fold_comp(Passes, Run, Code0, St1) of
+ {ok,Code,St2} -> comp_ret_ok(Code, St2);
{error,St2} -> comp_ret_err(St2)
end.
-fold_comp([{delay,Ps0}|Passes], Run, #compile{options=Opts}=St) ->
+fold_comp([{delay,Ps0}|Passes], Run, Code, #compile{options=Opts}=St) ->
Ps = select_passes(Ps0, Opts) ++ Passes,
- fold_comp(Ps, Run, St);
-fold_comp([{Name,Test,Pass}|Ps], Run, St) ->
+ fold_comp(Ps, Run, Code, St);
+fold_comp([{Name,Test,Pass}|Ps], Run, Code, St) ->
case Test(St) of
false -> %Pass is not needed.
- fold_comp(Ps, Run, St);
+ fold_comp(Ps, Run, Code, St);
true -> %Run pass in the usual way.
- fold_comp([{Name,Pass}|Ps], Run, St)
+ fold_comp([{Name,Pass}|Ps], Run, Code, St)
end;
-fold_comp([{Name,Pass}|Ps], Run, St0) ->
- case Run({Name,Pass}, St0) of
- {ok,St1} -> fold_comp(Ps, Run, St1);
- {error,_St1} = Error -> Error;
+fold_comp([{Name,Pass}|Ps], Run, Code0, St0) ->
+ case Run({Name,Pass}, Code0, St0) of
+ {ok,Code,St1} ->
+ fold_comp(Ps, Run, Code, St1);
+ {error,_St1}=Error ->
+ Error;
{'EXIT',Reason} ->
Es = [{St0#compile.ifile,[{none,?MODULE,{crash,Name,Reason}}]}],
{error,St0#compile{errors=St0#compile.errors ++ Es}};
@@ -348,30 +378,30 @@ fold_comp([{Name,Pass}|Ps], Run, St0) ->
Es = [{St0#compile.ifile,[{none,?MODULE,{bad_return,Name,Other}}]}],
{error,St0#compile{errors=St0#compile.errors ++ Es}}
end;
-fold_comp([], _Run, St) -> {ok,St}.
+fold_comp([], _Run, Code, St) -> {ok,Code,St}.
-run_tc({Name,Fun}, St) ->
+run_tc({Name,Fun}, Code, St) ->
T1 = erlang:monotonic_time(),
- Val = (catch Fun(St)),
+ Val = (catch Fun(Code, St)),
T2 = erlang:monotonic_time(),
- Elapsed = erlang:convert_time_unit(T2 - T1, native, milli_seconds),
+ Elapsed = erlang:convert_time_unit(T2 - T1, native, millisecond),
Mem0 = erts_debug:flat_size(Val)*erlang:system_info(wordsize),
Mem = lists:flatten(io_lib:format("~.1f kB", [Mem0/1024])),
io:format(" ~-30s: ~10.3f s ~12s\n",
[Name,Elapsed/1000,Mem]),
Val.
-run_eprof({Name,Fun}, Name, St) ->
+run_eprof({Name,Fun}, Code, Name, St) ->
io:format("~p: Running eprof\n", [Name]),
c:appcall(tools, eprof, start_profiling, [[self()]]),
- Val = (catch Fun(St)),
+ Val = (catch Fun(Code, St)),
c:appcall(tools, eprof, stop_profiling, []),
c:appcall(tools, eprof, analyze, []),
Val;
-run_eprof({_,Fun}, _, St) ->
- catch Fun(St).
+run_eprof({_,Fun}, Code, _, St) ->
+ catch Fun(Code, St).
-comp_ret_ok(#compile{code=Code,warnings=Warn0,module=Mod,options=Opts}=St) ->
+comp_ret_ok(Code, #compile{warnings=Warn0,module=Mod,options=Opts}=St) ->
case werror(St) of
true ->
case member(report_warnings, Opts) of
@@ -437,8 +467,10 @@ mpf(Ms) ->
passes(Type, Opts) ->
{Ext,Passes0} = passes_1(Opts),
Passes1 = case Type of
- file -> Passes0;
- forms -> tl(Passes0)
+ file ->
+ Passes0;
+ forms ->
+ fix_first_pass(Passes0)
end,
Passes = select_passes(Passes1, Opts),
@@ -475,6 +507,22 @@ pass(from_beam) ->
{".beam",[?pass(read_beam_file)|binary_passes()]};
pass(_) -> none.
+%% For compilation from forms, replace the first pass with a pass
+%% that retrieves the module name. The module name is needed for
+%% proper diagnostics and for compilation to native code.
+
+fix_first_pass([{parse_core,_}|Passes]) ->
+ [?pass(get_module_name_from_core)|Passes];
+fix_first_pass([{beam_consult_asm,_}|Passes]) ->
+ [?pass(get_module_name_from_asm)|Passes];
+fix_first_pass([{read_beam_file,_}|Passes]) ->
+ [?pass(get_module_name_from_beam)|Passes];
+fix_first_pass([_|Passes]) ->
+ %% When compiling from abstract code, the module name
+ %% will be set after running the v3_core pass.
+ Passes.
+
+
%% select_passes([Command], Opts) -> [{Name,Function}]
%% Interpret the lists of commands to return a pure list of passes.
%%
@@ -526,21 +574,21 @@ pass(_) -> none.
%%
select_passes([{pass,Mod}|Ps], Opts) ->
- F = fun(St) ->
- case catch Mod:module(St#compile.code, St#compile.options) of
+ F = fun(Code0, St) ->
+ case catch Mod:module(Code0, St#compile.options) of
{ok,Code} ->
- {ok,St#compile{code=Code}};
+ {ok,Code,St};
{ok,Code,Ws} ->
- {ok,St#compile{code=Code,warnings=St#compile.warnings++Ws}};
+ {ok,Code,St#compile{warnings=St#compile.warnings++Ws}};
{error,Es} ->
{error,St#compile{errors=St#compile.errors ++ Es}}
end
end,
[{Mod,F}|select_passes(Ps, Opts)];
select_passes([{src_listing,Ext}|_], _Opts) ->
- [{listing,fun (St) -> src_listing(Ext, St) end}];
+ [{listing,fun (Code, St) -> src_listing(Ext, Code, St) end}];
select_passes([{listing,Ext}|_], _Opts) ->
- [{listing,fun (St) -> listing(Ext, St) end}];
+ [{listing,fun (Code, St) -> listing(Ext, Code, St) end}];
select_passes([done|_], _Opts) ->
[];
select_passes([{done,Ext}|_], Opts) ->
@@ -640,13 +688,13 @@ standard_passes() ->
{iff,'dabstr',{listing,"abstr"}},
{iff,debug_info,?pass(save_abstract_code)},
- ?pass(expand_module),
+ ?pass(expand_records),
{iff,'dexp',{listing,"expand"}},
{iff,'E',{src_listing,"E"}},
{iff,'to_exp',{done,"E"}},
%% Conversion to Core Erlang.
- {pass,v3_core},
+ ?pass(core),
{iff,'dcore',{listing,"core"}},
{iff,'to_core0',{done,"core"}}
| core_passes()].
@@ -656,29 +704,31 @@ core_passes() ->
[{iff,clint0,?pass(core_lint_module)},
{delay,
[{unless,no_copt,
- [{core_old_inliner,fun test_old_inliner/1,fun core_old_inliner/1},
+ [{core_old_inliner,fun test_old_inliner/1,fun core_old_inliner/2},
{iff,doldinline,{listing,"oldinline"}},
{pass,sys_core_fold},
{iff,dcorefold,{listing,"corefold"}},
- {core_inline_module,fun test_core_inliner/1,fun core_inline_module/1},
+ {core_inline_module,fun test_core_inliner/1,fun core_inline_module/2},
{iff,dinline,{listing,"inline"}},
{core_fold_after_inlining,fun test_any_inliner/1,
- fun core_fold_module_after_inlining/1},
+ fun core_fold_module_after_inlining/2},
?pass(core_transforms)]},
{iff,dcopt,{listing,"copt"}},
{iff,'to_core',{done,"core"}}]}
| kernel_passes()].
kernel_passes() ->
- %% Destructive setelement/3 optimization and core lint.
- [{pass,sys_core_dsetel},
+ %% Optimizations that must be done after all other optimizations.
+ [{pass,sys_core_bsm},
+ {iff,dcbsm,{listing,"core_bsm"}},
+ {pass,sys_core_dsetel},
{iff,dsetel,{listing,"dsetel"}},
{iff,clint,?pass(core_lint_module)},
{iff,core,?pass(save_core_code)},
%% Kernel Erlang and code generation.
- {pass,v3_kernel},
+ ?pass(v3_kernel),
{iff,dkern,{listing,"kernel"}},
{iff,'to_kernel',{done,"kernel"}},
{pass,v3_life},
@@ -701,8 +751,6 @@ asm_passes() ->
{iff,dexcept,{listing,"except"}},
{unless,no_bs_opt,{pass,beam_bs}},
{iff,dbs,{listing,"bs"}},
- {unless,no_bopt,{pass,beam_bool}},
- {iff,dbool,{listing,"bool"}},
{unless,no_topt,{pass,beam_type}},
{iff,dtype,{listing,"type"}},
{pass,beam_split},
@@ -719,6 +767,8 @@ asm_passes() ->
{iff,dbsm,{listing,"bsm"}},
{unless,no_recv_opt,{pass,beam_receive}},
{iff,drecv,{listing,"recv"}},
+ {unless,no_record_opt,{pass,beam_record}},
+ {iff,drecord,{listing,"record"}},
{unless,no_stack_trimming,{pass,beam_trim}},
{iff,dtrim,{listing,"trim"}},
{pass,beam_flatten}]},
@@ -737,7 +787,7 @@ asm_passes() ->
| binary_passes()].
binary_passes() ->
- [{native_compile,fun test_native/1,fun native_compile/1},
+ [{native_compile,fun test_native/1,fun native_compile/2},
{unless,binary,?pass(save_binary,not_werror)}].
%%%
@@ -745,9 +795,9 @@ binary_passes() ->
%%%
%% Remove the target file so we don't have an old one if the compilation fail.
-remove_file(St) ->
+remove_file(Code, St) ->
_ = file:delete(St#compile.ofile),
- {ok,St}.
+ {ok,Code,St}.
-record(asm_module, {module,
exports,
@@ -795,34 +845,50 @@ collect_asm([{attributes, Attr} | Rest], R) ->
collect_asm([X | Rest], R) ->
collect_asm(Rest, R#asm_module{code=R#asm_module.code++[X]}).
-beam_consult_asm(St) ->
+beam_consult_asm(_Code, St) ->
case file:consult(St#compile.ifile) of
- {ok, Forms0} ->
+ {ok,Forms0} ->
Encoding = epp:read_encoding(St#compile.ifile),
- {Module, Forms} = preprocess_asm_forms(Forms0),
- {ok,St#compile{module=Module, code=Forms, encoding=Encoding}};
+ {Module,Forms} = preprocess_asm_forms(Forms0),
+ {ok,Forms,St#compile{module=Module,encoding=Encoding}};
{error,E} ->
Es = [{St#compile.ifile,[{none,?MODULE,{open,E}}]}],
{error,St#compile{errors=St#compile.errors ++ Es}}
end.
-read_beam_file(St) ->
+get_module_name_from_asm({Mod,_,_,_,_}=Asm, St) ->
+ {ok,Asm,St#compile{module=Mod}};
+get_module_name_from_asm(Asm, St) ->
+ %% Invalid Beam assembly code. Let it crash in a later pass.
+ {ok,Asm,St}.
+
+read_beam_file(_Code, St) ->
case file:read_file(St#compile.ifile) of
{ok,Beam} ->
Infile = St#compile.ifile,
case no_native_compilation(Infile, St) of
true ->
- {ok,St#compile{module=none,code=none}};
+ {ok,none,St#compile{module=none}};
false ->
Mod0 = filename:rootname(filename:basename(Infile)),
Mod = list_to_atom(Mod0),
- {ok,St#compile{module=Mod,code=Beam,ofile=Infile}}
+ {ok,Beam,St#compile{module=Mod,ofile=Infile}}
end;
{error,E} ->
Es = [{St#compile.ifile,[{none,?MODULE,{open,E}}]}],
{error,St#compile{errors=St#compile.errors ++ Es}}
end.
+get_module_name_from_beam(Beam, St) ->
+ case beam_lib:info(Beam) of
+ {error,beam_lib,Error} ->
+ Es = [{"((forms))",[{none,beam_lib,Error}]}],
+ {error,St#compile{errors=St#compile.errors ++ Es}};
+ Info ->
+ {module,Mod} = keyfind(module, 1, Info),
+ {ok,Beam,St#compile{module=Mod}}
+ end.
+
no_native_compilation(BeamFile, #compile{options=Opts0}) ->
case beam_lib:chunks(BeamFile, ["CInf"]) of
{ok,{_,[{"CInf",Term0}]}} ->
@@ -835,17 +901,17 @@ no_native_compilation(BeamFile, #compile{options=Opts0}) ->
_ -> false
end.
-parse_module(St0) ->
+parse_module(_Code, St0) ->
case do_parse_module(utf8, St0) of
- {ok,_}=Ret ->
+ {ok,_,_}=Ret ->
Ret;
{error,_}=Ret ->
Ret;
{invalid_unicode,File,Line} ->
case do_parse_module(latin1, St0) of
- {ok,St} ->
+ {ok,Code,St} ->
Es = [{File,[{Line,?MODULE,reparsing_invalid_unicode}]}],
- {ok,St#compile{warnings=Es++St#compile.warnings}};
+ {ok,Code,St#compile{warnings=Es++St#compile.warnings}};
{error,St} ->
Es = [{File,[{Line,?MODULE,reparsing_invalid_unicode}]}],
{error,St#compile{errors=Es++St#compile.errors}}
@@ -863,13 +929,13 @@ do_parse_module(DefEncoding, #compile{ifile=File,options=Opts,dir=Dir}=St) ->
Encoding = proplists:get_value(encoding, Extra),
case find_invalid_unicode(Forms, File) of
none ->
- {ok,St#compile{code=Forms,encoding=Encoding}};
+ {ok,Forms,St#compile{encoding=Encoding}};
{invalid_unicode,_,_}=Ret ->
case Encoding of
none ->
Ret;
_ ->
- {ok,St#compile{code=Forms,encoding=Encoding}}
+ {ok,Forms,St#compile{encoding=Encoding}}
end
end;
{error,E} ->
@@ -888,7 +954,7 @@ find_invalid_unicode([H|T], File0) ->
end;
find_invalid_unicode([], _) -> none.
-parse_core(St) ->
+parse_core(_Code, St) ->
case file:read_file(St#compile.ifile) of
{ok,Bin} ->
case core_scan:string(binary_to_list(Bin)) of
@@ -896,7 +962,7 @@ parse_core(St) ->
case core_parse:parse(Toks) of
{ok,Mod} ->
Name = (Mod#c_module.name)#c_literal.val,
- {ok,St#compile{module=Name,code=Mod}};
+ {ok,Mod,St#compile{module=Name}};
{error,E} ->
Es = [{St#compile.ifile,[E]}],
{error,St#compile{errors=St#compile.errors ++ Es}}
@@ -910,6 +976,16 @@ parse_core(St) ->
{error,St#compile{errors=St#compile.errors ++ Es}}
end.
+get_module_name_from_core(Core, St) ->
+ try
+ Mod = cerl:concrete(cerl:module_name(Core)),
+ {ok,Core,St#compile{module=Mod}}
+ catch
+ _:_ ->
+ %% Invalid Core Erlang code. Let it crash in a later pass.
+ {ok,Core,St}
+ end.
+
compile_options([{attribute,_L,compile,C}|Fs]) when is_list(C) ->
C ++ compile_options(Fs);
compile_options([{attribute,_L,compile,C}|Fs]) ->
@@ -933,31 +1009,36 @@ clean_parse_transforms_1([], Acc) -> reverse(Acc).
transforms(Os) -> [ M || {parse_transform,M} <- Os ].
-transform_module(#compile{options=Opt,code=Code0}=St0) ->
+transform_module(Code0, #compile{options=Opt}=St) ->
%% Extract compile options from code into options field.
case transforms(Opt ++ compile_options(Code0)) of
- [] -> {ok,St0}; %No parse transforms.
+ [] ->
+ %% No parse transforms.
+ {ok,Code0,St};
Ts ->
%% Remove parse_transform attributes from the abstract code to
%% prevent parse transforms to be run more than once.
Code = clean_parse_transforms(Code0),
- St = St0#compile{code=Code},
- foldl_transform(St, Ts)
+ foldl_transform(Ts, Code, St)
end.
-foldl_transform(St, [T|Ts]) ->
+foldl_transform([T|Ts], Code0, St) ->
Name = "transform " ++ atom_to_list(T),
case code:ensure_loaded(T) =:= {module,T} andalso
- erlang:function_exported(T, parse_transform, 2) of
+ erlang:function_exported(T, parse_transform, 2) of
true ->
- Fun = fun(S) ->
- T:parse_transform(S#compile.code, S#compile.options)
+ Fun = fun(Code, S) ->
+ T:parse_transform(Code, S#compile.options)
end,
Run = case member(time, St#compile.options) of
- true -> fun run_tc/2;
- false -> fun({_Name,F}, S) -> catch F(S) end
+ true ->
+ fun run_tc/3;
+ false ->
+ fun({_Name,F}, Code, S) ->
+ catch F(Code, S)
+ end
end,
- case Run({Name, Fun}, St) of
+ case Run({Name, Fun}, Code0, St) of
{error,Es,Ws} ->
{error,St#compile{warnings=St#compile.warnings ++ Ws,
errors=St#compile.errors ++ Es}};
@@ -966,41 +1047,44 @@ foldl_transform(St, [T|Ts]) ->
{parse_transform,T,R}}]}],
{error,St#compile{errors=St#compile.errors ++ Es}};
{warning, Forms, Ws} ->
- foldl_transform(
- St#compile{code=Forms,
- warnings=St#compile.warnings ++ Ws}, Ts);
+ foldl_transform(Ts, Forms,
+ St#compile{warnings=St#compile.warnings ++ Ws});
Forms ->
- foldl_transform(St#compile{code=Forms}, Ts)
+ foldl_transform(Ts, Forms, St)
end;
false ->
Es = [{St#compile.ifile,[{none,compile,
{undef_parse_transform,T}}]}],
{error,St#compile{errors=St#compile.errors ++ Es}}
end;
-foldl_transform(St, []) -> {ok,St}.
+foldl_transform([], Code, St) -> {ok,Code,St}.
get_core_transforms(Opts) -> [M || {core_transform,M} <- Opts].
-core_transforms(St) ->
+core_transforms(Code, St) ->
%% The options field holds the complete list of options at this
Ts = get_core_transforms(St#compile.options),
- foldl_core_transforms(St, Ts).
+ foldl_core_transforms(Ts, Code, St).
-foldl_core_transforms(St, [T|Ts]) ->
+foldl_core_transforms([T|Ts], Code0, St) ->
Name = "core transform " ++ atom_to_list(T),
- Fun = fun(S) -> T:core_transform(S#compile.code, S#compile.options) end,
+ Fun = fun(Code, S) -> T:core_transform(Code, S#compile.options) end,
Run = case member(time, St#compile.options) of
- true -> fun run_tc/2;
- false -> fun({_Name,F}, S) -> catch F(S) end
+ true ->
+ fun run_tc/3;
+ false ->
+ fun({_Name,F}, Code, S) ->
+ catch F(Code, S)
+ end
end,
- case Run({Name, Fun}, St) of
+ case Run({Name, Fun}, Code0, St) of
{'EXIT',R} ->
Es = [{St#compile.ifile,[{none,compile,{core_transform,T,R}}]}],
{error,St#compile{errors=St#compile.errors ++ Es}};
Forms ->
- foldl_core_transforms(St#compile{code=Forms}, Ts)
+ foldl_core_transforms(Ts, Forms, St)
end;
-foldl_core_transforms(St, []) -> {ok,St}.
+foldl_core_transforms([], Code, St) -> {ok,Code,St}.
%%% Fetches the module name from a list of forms. The module attribute must
%%% be present.
@@ -1021,31 +1105,28 @@ add_default_base(St, Forms) ->
St
end.
-lint_module(St) ->
- case erl_lint:module(St#compile.code,
- St#compile.ifile, St#compile.options) of
+lint_module(Code, St) ->
+ case erl_lint:module(Code, St#compile.ifile, St#compile.options) of
{ok,Ws} ->
%% Insert name of module as base name, if needed. This is
%% for compile:forms to work with listing files.
- St1 = add_default_base(St, St#compile.code),
- {ok,St1#compile{warnings=St1#compile.warnings ++ Ws}};
+ St1 = add_default_base(St, Code),
+ {ok,Code,St1#compile{warnings=St1#compile.warnings ++ Ws}};
{error,Es,Ws} ->
{error,St#compile{warnings=St#compile.warnings ++ Ws,
errors=St#compile.errors ++ Es}}
end.
-core_lint_module(St) ->
- case core_lint:module(St#compile.code, St#compile.options) of
+core_lint_module(Code, St) ->
+ case core_lint:module(Code, St#compile.options) of
{ok,Ws} ->
- {ok,St#compile{warnings=St#compile.warnings ++ Ws}};
+ {ok,Code,St#compile{warnings=St#compile.warnings ++ Ws}};
{error,Es,Ws} ->
{error,St#compile{warnings=St#compile.warnings ++ Ws,
errors=St#compile.errors ++ Es}}
end.
-makedep(#compile{code=Code,options=Opts}=St) ->
- Ifile = St#compile.ifile,
- Ofile = St#compile.ofile,
+makedep(Code0, #compile{ifile=Ifile,ofile=Ofile,options=Opts}=St) ->
%% Get the target of the Makefile rule.
Target0 =
@@ -1077,7 +1158,7 @@ makedep(#compile{code=Code,options=Opts}=St) ->
%% List the dependencies (includes) for this target.
{MainRule,PhonyRules} = makedep_add_headers(
Ifile, % The input file name.
- Code, % The parsed source.
+ Code0, % The parsed source.
[], % The list of dependencies already added.
length(Target), % The current line length.
Target, % The target.
@@ -1097,7 +1178,8 @@ makedep(#compile{code=Code,options=Opts}=St) ->
true -> MainRule ++ PhonyRules;
_ -> MainRule
end,
- {ok,St#compile{code=iolist_to_binary([Makefile,"\n"])}}.
+ Code = iolist_to_binary([Makefile,"\n"]),
+ {ok,Code,St}.
makedep_add_headers(Ifile, [{attribute,_,file,{File,_}}|Rest],
Included, LineLen, MainTarget, Phony, Opts) ->
@@ -1162,7 +1244,7 @@ makedep_add_header(Ifile, Included, LineLen, MainTarget, Phony, File) ->
end
end.
-makedep_output(#compile{code=Code,options=Opts,ofile=Ofile}=St) ->
+makedep_output(Code, #compile{options=Opts,ofile=Ofile}=St) ->
%% Write this Makefile (Code) to the selected output.
%% If no output is specified, the default is to write to a file named after
%% the output file.
@@ -1204,9 +1286,9 @@ makedep_output(#compile{code=Code,options=Opts,ofile=Ofile}=St) ->
CloseOutput -> ok = file:close(Output1);
true -> ok
end,
- {ok,St}
+ {ok,Code,St}
catch
- exit:_ ->
+ error:_ ->
%% Couldn't write to output Makefile.
Err = {St#compile.ifile,[{none,?MODULE,write_error}]},
{error,St#compile{errors=St#compile.errors++[Err]}}
@@ -1221,19 +1303,34 @@ makedep_output(#compile{code=Code,options=Opts,ofile=Ofile}=St) ->
{error,St#compile{errors=St#compile.errors++[Err]}}
end.
-%% expand_module(State) -> State'
-%% Do the common preprocessing of the input forms.
+expand_records(Code0, #compile{options=Opts}=St) ->
+ Code = erl_expand_records:module(Code0, Opts),
+ {ok,Code,St}.
-expand_module(#compile{code=Code,options=Opts0}=St0) ->
- {Mod,Exp,Forms,Opts1} = sys_pre_expand:module(Code, Opts0),
+core(Forms, #compile{options=Opts0}=St) ->
+ Opts1 = lists:flatten([C || {attribute,_,compile,C} <- Forms] ++ Opts0),
Opts = expand_opts(Opts1),
- {ok,St0#compile{module=Mod,options=Opts,code={Mod,Exp,Forms}}}.
+ {ok,Core,Ws} = v3_core:module(Forms, Opts),
+ Mod = cerl:concrete(cerl:module_name(Core)),
+ {ok,Core,St#compile{module=Mod,options=Opts,
+ warnings=St#compile.warnings++Ws}}.
-core_fold_module_after_inlining(#compile{code=Code0,options=Opts}=St) ->
+core_fold_module_after_inlining(Code0, #compile{options=Opts}=St) ->
%% Inlining may produce code that generates spurious warnings.
%% Ignore all warnings.
{ok,Code,_Ws} = sys_core_fold:module(Code0, Opts),
- {ok,St#compile{code=Code}}.
+ {ok,Code,St}.
+
+v3_kernel(Code0, #compile{options=Opts,warnings=Ws0}=St) ->
+ {ok,Code,Ws} = v3_kernel:module(Code0, Opts),
+ case Ws =:= [] orelse test_core_inliner(St) of
+ false ->
+ {ok,Code,St#compile{warnings=Ws0++Ws}};
+ true ->
+ %% cerl_inline may produce code that generates spurious
+ %% warnings. Ignore any such warnings.
+ {ok,Code,St}
+ end.
test_old_inliner(#compile{options=Opts}) ->
%% The point of this test is to avoid loading the old inliner
@@ -1256,52 +1353,51 @@ test_core_inliner(#compile{options=Opts}) ->
test_any_inliner(St) ->
test_old_inliner(St) orelse test_core_inliner(St).
-core_old_inliner(#compile{code=Code0,options=Opts}=St) ->
+core_old_inliner(Code0, #compile{options=Opts}=St) ->
{ok,Code} = sys_core_inline:module(Code0, Opts),
- {ok,St#compile{code=Code}}.
+ {ok,Code,St}.
-core_inline_module(#compile{code=Code0,options=Opts}=St) ->
+core_inline_module(Code0, #compile{options=Opts}=St) ->
Code = cerl_inline:core_transform(Code0, Opts),
- {ok,St#compile{code=Code}}.
-
-save_abstract_code(#compile{ifile=File}=St) ->
- case abstract_code(St) of
- {ok,Code} ->
- {ok,St#compile{abstract_code=Code}};
- {error,Es} ->
- {error,St#compile{errors=St#compile.errors ++ [{File,Es}]}}
- end.
+ {ok,Code,St}.
+
+save_abstract_code(Code, St) ->
+ {ok,Code,St#compile{abstract_code=erl_parse:anno_to_term(Code)}}.
+
+debug_info(#compile{module=Module,mod_options=Opts0,ofile=OFile,abstract_code=Abst}) ->
+ AbstOpts = cleanup_compile_options(Opts0),
+ Opts1 = proplists:delete(debug_info, Opts0),
+ {Backend,Metadata,Opts2} =
+ case proplists:get_value(debug_info, Opts0, false) of
+ {OptBackend,OptMetadata} when is_atom(OptBackend) -> {OptBackend,OptMetadata,Opts1};
+ false -> {erl_abstract_code,{none,AbstOpts},Opts1};
+ true -> {erl_abstract_code,{Abst,AbstOpts},[debug_info | Opts1]}
+ end,
+ DebugInfo = erlang:term_to_binary({debug_info_v1,Backend,Metadata}, [compressed]),
-abstract_code(#compile{code=Code0,options=Opts,ofile=OFile}) ->
- Code = erl_parse:anno_to_term(Code0),
- Abstr = erlang:term_to_binary({raw_abstract_v1,Code}, [compressed]),
- case member(encrypt_debug_info, Opts) of
+ case member(encrypt_debug_info, Opts2) of
true ->
- case keyfind(debug_info_key, 1, Opts) of
- {_,Key} ->
- encrypt_abs_code(Abstr, Key);
+ case lists:keytake(debug_info_key, 1, Opts2) of
+ {value,{_, Key},Opts3} ->
+ encrypt_debug_info(DebugInfo, Key, [{debug_info_key,'********'} | Opts3]);
false ->
- %% Note: #compile.module has not been set yet.
- %% Here is an approximation that should work for
- %% all valid cases.
- Module = list_to_atom(filename:rootname(filename:basename(OFile))),
- Mode = proplists:get_value(crypto_mode, Opts, des3_cbc),
+ Mode = proplists:get_value(crypto_mode, Opts2, des3_cbc),
case beam_lib:get_crypto_key({debug_info, Mode, Module, OFile}) of
error ->
{error, [{none,?MODULE,no_crypto_key}]};
Key ->
- encrypt_abs_code(Abstr, {Mode, Key})
+ encrypt_debug_info(DebugInfo, {Mode, Key}, Opts2)
end
end;
false ->
- {ok, Abstr}
+ {ok,DebugInfo,Opts2}
end.
-encrypt_abs_code(Abstr, Key0) ->
+encrypt_debug_info(DebugInfo, Key, Opts) ->
try
- RealKey = generate_key(Key0),
+ RealKey = generate_key(Key),
case start_crypto() of
- ok -> {ok,encrypt(RealKey, Abstr)};
+ ok -> {ok,encrypt(RealKey, DebugInfo),Opts};
{error,_}=E -> E
end
catch
@@ -1309,6 +1405,18 @@ encrypt_abs_code(Abstr, Key0) ->
{error,[{none,?MODULE,bad_crypto_key}]}
end.
+cleanup_compile_options(Opts) ->
+ lists:filter(fun keep_compile_option/1, Opts).
+
+%% We are storing abstract, not asm or core.
+keep_compile_option(from_asm) -> false;
+keep_compile_option(from_core) -> false;
+%% Parse transform and macros have already been applied.
+keep_compile_option({parse_transform, _}) -> false;
+keep_compile_option({d, _, _}) -> false;
+%% Do not affect compilation result on future calls.
+keep_compile_option(Option) -> effects_code_generation(Option).
+
start_crypto() ->
try crypto:start() of
{error,{already_started,crypto}} -> ok;
@@ -1332,18 +1440,19 @@ encrypt({des3_cbc=Type,Key,IVec,BlockSize}, Bin0) ->
TypeString = atom_to_list(Type),
list_to_binary([0,length(TypeString),TypeString,Bin]).
-save_core_code(St) ->
- {ok,St#compile{core_code=cerl:from_records(St#compile.code)}}.
-
-beam_asm(#compile{ifile=File,code=Code0,
- abstract_code=Abst,mod_options=Opts0}=St) ->
- Source = paranoid_absname(File),
- Opts1 = lists:map(fun({debug_info_key,_}) -> {debug_info_key,'********'};
- (Other) -> Other
- end, Opts0),
- Opts2 = [O || O <- Opts1, effects_code_generation(O)],
- case beam_asm:module(Code0, Abst, Source, Opts2) of
- {ok,Code} -> {ok,St#compile{code=Code,abstract_code=[]}}
+save_core_code(Code, St) ->
+ {ok,Code,St#compile{core_code=cerl:from_records(Code)}}.
+
+beam_asm(Code0, #compile{ifile=File,extra_chunks=ExtraChunks,options=CompilerOpts}=St) ->
+ case debug_info(St) of
+ {ok,DebugInfo,Opts0} ->
+ Source = paranoid_absname(File),
+ Opts1 = [O || O <- Opts0, effects_code_generation(O)],
+ Chunks = [{<<"Dbgi">>, DebugInfo} | ExtraChunks],
+ {ok,Code} = beam_asm:module(Code0, Chunks, Source, Opts1, CompilerOpts),
+ {ok,Code,St#compile{abstract_code=[]}};
+ {error,Es} ->
+ {error,St#compile{errors=St#compile.errors ++ [{File,Es}]}}
end.
paranoid_absname(""=File) ->
@@ -1367,17 +1476,17 @@ is_native_enabled([no_native|_]) -> false;
is_native_enabled([_|Opts]) -> is_native_enabled(Opts);
is_native_enabled([]) -> false.
-native_compile(#compile{code=none}=St) -> {ok,St};
-native_compile(St) ->
+native_compile(none, St) -> {ok,none,St};
+native_compile(Code, St) ->
case erlang:system_info(hipe_architecture) of
undefined ->
Ws = [{St#compile.ifile,[{none,compile,no_native_support}]}],
- {ok,St#compile{warnings=St#compile.warnings ++ Ws}};
+ {ok,Code,St#compile{warnings=St#compile.warnings ++ Ws}};
_ ->
- native_compile_1(St)
+ native_compile_1(Code, St)
end.
-native_compile_1(St) ->
+native_compile_1(Code, St) ->
Opts0 = St#compile.options,
IgnoreErrors = member(ignore_native_errors, Opts0),
Opts = case keyfind(hipe, 1, Opts0) of
@@ -1387,10 +1496,10 @@ native_compile_1(St) ->
end,
try hipe:compile(St#compile.module,
St#compile.core_code,
- St#compile.code,
+ Code,
Opts) of
{ok,{_Type,Bin}=T} when is_binary(Bin) ->
- {ok,embed_native_code(St, T)};
+ {ok,embed_native_code(Code, T),St};
{error,R} ->
case IgnoreErrors of
true ->
@@ -1413,13 +1522,13 @@ native_compile_1(St) ->
end
end.
-embed_native_code(St, {Architecture,NativeCode}) ->
- {ok, _, Chunks0} = beam_lib:all_chunks(St#compile.code),
+embed_native_code(Code, {Architecture,NativeCode}) ->
+ {ok, _, Chunks0} = beam_lib:all_chunks(Code),
ChunkName = hipe_unified_loader:chunk_name(Architecture),
Chunks1 = lists:keydelete(ChunkName, 1, Chunks0),
Chunks = Chunks1 ++ [{ChunkName,NativeCode}],
- {ok, BeamPlusNative} = beam_lib:build_module(Chunks),
- St#compile{code=BeamPlusNative}.
+ {ok,BeamPlusNative} = beam_lib:build_module(Chunks),
+ BeamPlusNative.
%% effects_code_generation(Option) -> true|false.
%% Determine whether the option could have any effect on the
@@ -1427,30 +1536,31 @@ embed_native_code(St, {Architecture,NativeCode}) ->
%% errors will be reported).
effects_code_generation(Option) ->
- case Option of
+ case Option of
beam -> false;
report_warnings -> false;
report_errors -> false;
return_errors-> false;
return_warnings-> false;
+ warnings_as_errors -> false;
binary -> false;
verbose -> false;
{cwd,_} -> false;
+ {outdir, _} -> false;
_ -> true
end.
-save_binary(#compile{code=none}=St) -> {ok,St};
-save_binary(#compile{module=Mod,ofile=Outfile,
- options=Opts}=St) ->
+save_binary(none, St) -> {ok,none,St};
+save_binary(Code, #compile{module=Mod,ofile=Outfile,options=Opts}=St) ->
%% Test that the module name and output file name match.
case member(no_error_module_mismatch, Opts) of
true ->
- save_binary_1(St);
+ save_binary_1(Code, St);
false ->
Base = filename:rootname(filename:basename(Outfile)),
case atom_to_list(Mod) of
Base ->
- save_binary_1(St);
+ save_binary_1(Code, St);
_ ->
Es = [{St#compile.ofile,
[{none,?MODULE,{module_name,Mod,Base}}]}],
@@ -1458,14 +1568,14 @@ save_binary(#compile{module=Mod,ofile=Outfile,
end
end.
-save_binary_1(St) ->
+save_binary_1(Code, St) ->
Ofile = St#compile.ofile,
Tfile = tmpfile(Ofile), %Temp working file
- case write_binary(Tfile, St#compile.code, St) of
+ case write_binary(Tfile, Code, St) of
ok ->
case file:rename(Tfile, Ofile) of
ok ->
- {ok,St};
+ {ok,none,St};
{error,RenameError} ->
Es0 = [{Ofile,[{none,?MODULE,{rename,Tfile,Ofile,
RenameError}}]}],
@@ -1479,8 +1589,8 @@ save_binary_1(St) ->
end,
{error,St#compile{errors=St#compile.errors ++ Es}}
end;
- {error,_Error} ->
- Es = [{Tfile,[{none,compile,write_error}]}],
+ {error,Error} ->
+ Es = [{Tfile,[{none,compile,{write_error,Error}}]}],
{error,St#compile{errors=St#compile.errors ++ Es}}
end.
@@ -1565,6 +1675,9 @@ list_errors(_F, []) -> ok.
%% tmpfile(ObjFile) -> TmpFile
%% Work out the correct input and output file names.
+-spec iofile(atom() | file:filename_all()) ->
+ {file:name_all(),file:name_all()}.
+
iofile(File) when is_atom(File) ->
iofile(atom_to_list(File));
iofile(File) ->
@@ -1605,31 +1718,31 @@ pre_defs([]) -> [].
inc_paths(Opts) ->
[ P || {i,P} <- Opts, is_list(P) ].
-src_listing(Ext, St) ->
+src_listing(Ext, Code, St) ->
listing(fun (Lf, {_Mod,_Exp,Fs}) -> do_src_listing(Lf, Fs);
(Lf, Fs) -> do_src_listing(Lf, Fs) end,
- Ext, St).
+ Ext, Code, St).
do_src_listing(Lf, Fs) ->
Opts = [lists:keyfind(encoding, 1, io:getopts(Lf))],
foreach(fun (F) -> io:put_chars(Lf, [erl_pp:form(F, Opts),"\n"]) end,
Fs).
-listing(Ext, St0) ->
+listing(Ext, Code, St0) ->
St = St0#compile{encoding = none},
- listing(fun(Lf, Fs) -> beam_listing:module(Lf, Fs) end, Ext, St).
+ listing(fun(Lf, Fs) -> beam_listing:module(Lf, Fs) end, Ext, Code, St).
-listing(LFun, Ext, St) ->
+listing(LFun, Ext, Code, St) ->
Lfile = outfile(St#compile.base, Ext, St#compile.options),
case file:open(Lfile, [write,delayed_write]) of
{ok,Lf} ->
- Code = restore_expanded_types(Ext, St#compile.code),
+ Code = restore_expanded_types(Ext, Code),
output_encoding(Lf, St),
LFun(Lf, Code),
ok = file:close(Lf),
- {ok,St};
- {error,_Error} ->
- Es = [{Lfile,[{none,compile,write_error}]}],
+ {ok,Code,St};
+ {error,Error} ->
+ Es = [{Lfile,[{none,compile,{write_error,Error}}]}],
{error,St#compile{errors=St#compile.errors ++ Es}}
end.
@@ -1699,6 +1812,8 @@ help(_) ->
%% compile(AbsFileName, Outfilename, Options)
%% Compile entry point for erl_compile.
+-spec compile(file:filename(), _, #options{}) -> 'ok' | 'error'.
+
compile(File0, _OutFile, Options) ->
pre_load(),
File = shorten_filename(File0),
@@ -1707,6 +1822,8 @@ compile(File0, _OutFile, Options) ->
Other -> Other
end.
+-spec compile_beam(file:filename(), _, #options{}) -> 'ok' | 'error'.
+
compile_beam(File0, _OutFile, Opts) ->
File = shorten_filename(File0),
case file(File, [from_beam|make_erl_options(Opts)]) of
@@ -1714,6 +1831,8 @@ compile_beam(File0, _OutFile, Opts) ->
Other -> Other
end.
+-spec compile_asm(file:filename(), _, #options{}) -> 'ok' | 'error'.
+
compile_asm(File0, _OutFile, Opts) ->
File = shorten_filename(File0),
case file(File, [from_asm|make_erl_options(Opts)]) of
@@ -1721,6 +1840,8 @@ compile_asm(File0, _OutFile, Opts) ->
Other -> Other
end.
+-spec compile_core(file:filename(), _, #options{}) -> 'ok' | 'error'.
+
compile_core(File0, _OutFile, Opts) ->
File = shorten_filename(File0),
case file(File, [from_core|make_erl_options(Opts)]) of
@@ -1770,7 +1891,6 @@ pre_load() ->
L = [beam_a,
beam_asm,
beam_block,
- beam_bool,
beam_bs,
beam_bsm,
beam_clean,
@@ -1782,6 +1902,7 @@ pre_load() ->
beam_opcodes,
beam_peep,
beam_receive,
+ beam_record,
beam_reorder,
beam_split,
beam_trim,
@@ -1800,9 +1921,9 @@ pre_load() ->
erl_lint,
erl_parse,
erl_scan,
+ sys_core_bsm,
sys_core_dsetel,
sys_core_fold,
- sys_pre_expand,
v3_codegen,
v3_core,
v3_kernel,
diff --git a/lib/compiler/src/compiler.app.src b/lib/compiler/src/compiler.app.src
index 1fd7800e85..3139d68902 100644
--- a/lib/compiler/src/compiler.app.src
+++ b/lib/compiler/src/compiler.app.src
@@ -1,7 +1,7 @@
% This is an -*- erlang -*- file.
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@
beam_a,
beam_asm,
beam_block,
- beam_bool,
beam_bs,
beam_bsm,
beam_clean,
@@ -39,6 +38,7 @@
beam_peep,
beam_receive,
beam_reorder,
+ beam_record,
beam_split,
beam_trim,
beam_type,
@@ -58,12 +58,12 @@
core_lib,
erl_bifs,
rec_env,
+ sys_core_bsm,
sys_core_dsetel,
sys_core_fold,
sys_core_fold_lists,
sys_core_inline,
sys_pre_attributes,
- sys_pre_expand,
v3_codegen,
v3_core,
v3_kernel,
@@ -73,5 +73,5 @@
{registered, []},
{applications, [kernel, stdlib]},
{env, []},
- {runtime_dependencies, ["stdlib-2.5","kernel-4.0","hipe-3.12","erts-7.0",
+ {runtime_dependencies, ["stdlib-2.5","kernel-4.0","hipe-3.12","erts-9.0",
"crypto-3.6"]}]}.
diff --git a/lib/compiler/src/core_parse.yrl b/lib/compiler/src/core_parse.yrl
index 8028aa99bb..79a7cccd98 100644
--- a/lib/compiler/src/core_parse.yrl
+++ b/lib/compiler/src/core_parse.yrl
@@ -432,6 +432,21 @@ timeout ->
%% ====================================================================== %%
+Header
+"%% This file was automatically generated from the file \"core_parse.yrl\"."
+"%%"
+"%% Copyright Ericsson AB 1999-2009. All Rights Reserved."
+"%%"
+"%% Licensed under the Apache License, Version 2.0 (the \"License\"); you may"
+"%% not use this file except in compliance with the License. You may obtain"
+"%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>"
+"%%"
+"%% Unless required by applicable law or agreed to in writing, software"
+"%% distributed under the License is distributed on an \"AS IS\" BASIS,"
+"%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."
+"%% See the License for the specific language governing permissions and"
+"%% limitations under the License."
+"".
Erlang code.
diff --git a/lib/compiler/src/core_pp.erl b/lib/compiler/src/core_pp.erl
index 67209d06be..cff6c7098b 100644
--- a/lib/compiler/src/core_pp.erl
+++ b/lib/compiler/src/core_pp.erl
@@ -179,7 +179,7 @@ format_1(#c_tuple{es=Es}, Ctxt) ->
format_hseq(Es, ",", add_indent(Ctxt, 1), fun format/2),
$}
];
-format_1(#c_map{arg=#c_literal{anno=[],val=M},es=Es}, Ctxt)
+format_1(#c_map{arg=#c_literal{val=M},es=Es}, Ctxt)
when is_map(M), map_size(M) =:= 0 ->
["~{",
format_hseq(Es, ",", add_indent(Ctxt, 1), fun format/2),
diff --git a/lib/compiler/src/core_scan.erl b/lib/compiler/src/core_scan.erl
index 11b52f6c5f..9f0676538f 100644
--- a/lib/compiler/src/core_scan.erl
+++ b/lib/compiler/src/core_scan.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -49,13 +49,37 @@
-import(lists, [reverse/1]).
+-type location() :: integer().
+-type category() :: atom().
+-type symbol() :: atom() | float() | integer() | string().
+-type token() :: {category(), Anno :: location(), symbol()}
+ | {category(), Anno :: location()}.
+-type tokens() :: [token()].
+-type error_description() :: term().
+-type error_info() :: {erl_anno:location(), module(), error_description()}.
+
%% string([Char]) ->
%% string([Char], StartPos) ->
%% {ok, [Tok], EndPos} |
%% {error, {Pos,core_scan,What}, EndPos}
+-spec string(String) -> Return when
+ String :: string(),
+ Return :: {'ok', Tokens :: tokens(), EndLocation}
+ | {'error', ErrorInfo :: error_info(), ErrorLocation},
+ EndLocation :: location(),
+ ErrorLocation :: location().
+
string(Cs) -> string(Cs, 1).
+-spec string(String, StartLocation) -> Return when
+ String :: string(),
+ Return :: {'ok', Tokens :: tokens(), EndLocation}
+ | {'error', ErrorInfo :: error_info(), ErrorLocation},
+ StartLocation :: location(),
+ EndLocation :: location(),
+ ErrorLocation :: location().
+
string(Cs, Sp) ->
%% Add an 'eof' to always get correct handling.
case string_pre_scan(Cs, [], Sp) of
@@ -259,10 +283,12 @@ scan1([$$|Cs0], Toks, Pos) -> %Character constant
scan1(Cs, [{char,Pos,C}|Toks], Pos1);
scan1([$'|Cs0], Toks, Pos) -> %Atom (always quoted)
{S,Cs1,Pos1} = scan_string(Cs0, $', Pos),
- case catch list_to_atom(S) of
+ try binary_to_atom(list_to_binary(S), utf8) of
A when is_atom(A) ->
- scan1(Cs1, [{atom,Pos,A}|Toks], Pos1);
- _Error -> scan_error({illegal,atom}, Pos)
+ scan1(Cs1, [{atom,Pos,A}|Toks], Pos1)
+ catch
+ error:_ ->
+ scan_error({illegal,atom}, Pos)
end;
scan1([$"|Cs0], Toks, Pos) -> %String
{S,Cs1,Pos1} = scan_string(Cs0, $", Pos),
diff --git a/lib/compiler/src/erl_bifs.erl b/lib/compiler/src/erl_bifs.erl
index 6b2d781a76..bafa9d75b7 100644
--- a/lib/compiler/src/erl_bifs.erl
+++ b/lib/compiler/src/erl_bifs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -75,11 +75,12 @@ is_pure(erlang, binary_to_list, 1) -> true;
is_pure(erlang, binary_to_list, 3) -> true;
is_pure(erlang, bit_size, 1) -> true;
is_pure(erlang, byte_size, 1) -> true;
+is_pure(erlang, ceil, 1) -> true;
is_pure(erlang, element, 2) -> true;
is_pure(erlang, float, 1) -> true;
is_pure(erlang, float_to_list, 1) -> true;
is_pure(erlang, float_to_binary, 1) -> true;
-is_pure(erlang, hash, 2) -> false;
+is_pure(erlang, floor, 1) -> true;
is_pure(erlang, hd, 1) -> true;
is_pure(erlang, integer_to_binary, 1) -> true;
is_pure(erlang, integer_to_list, 1) -> true;
@@ -129,11 +130,14 @@ is_pure(math, asinh, 1) -> true;
is_pure(math, atan, 1) -> true;
is_pure(math, atan2, 2) -> true;
is_pure(math, atanh, 1) -> true;
+is_pure(math, ceil, 1) -> true;
is_pure(math, cos, 1) -> true;
is_pure(math, cosh, 1) -> true;
is_pure(math, erf, 1) -> true;
is_pure(math, erfc, 1) -> true;
is_pure(math, exp, 1) -> true;
+is_pure(math, floor, 1) -> true;
+is_pure(math, fmod, 2) -> true;
is_pure(math, log, 1) -> true;
is_pure(math, log2, 1) -> true;
is_pure(math, log10, 1) -> true;
@@ -203,7 +207,6 @@ is_safe(erlang, registered, 0) -> true;
is_safe(erlang, self, 0) -> true;
is_safe(erlang, term_to_binary, 1) -> true;
is_safe(erlang, time, 0) -> true;
-is_safe(error_logger, warning_map, 0) -> true;
is_safe(_, _, _) -> false.
diff --git a/lib/compiler/src/genop.tab b/lib/compiler/src/genop.tab
index dcbdeb32e6..b5688de339 100755
--- a/lib/compiler/src/genop.tab
+++ b/lib/compiler/src/genop.tab
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1998-2016. All Rights Reserved.
+# Copyright Ericsson AB 1998-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -537,3 +537,11 @@ BEAM_FORMAT_NUMBER=0
156: is_map/2
157: has_map_fields/3
158: get_map_elements/3
+
+# OTP 20
+
+## @spec is_tagged_tuple Lbl Reg N Atom
+## @doc Test the type of Reg and jumps to Lbl if it is not a tuple.
+## Test the arity of Reg and jumps to Lbl if it is not N.
+## Test the first element of the tuple and jumps to Lbl if it is not Atom.
+159: is_tagged_tuple/4
diff --git a/lib/compiler/src/rec_env.erl b/lib/compiler/src/rec_env.erl
index cdc513e57c..48d39776dc 100644
--- a/lib/compiler/src/rec_env.erl
+++ b/lib/compiler/src/rec_env.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,10 +10,8 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% @author Richard Carlsson <[email protected]>
%% @copyright 1999-2004 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Abstract environments, supporting self-referential bindings and
%% automatic new-key generation.
diff --git a/lib/compiler/src/sys_core_bsm.erl b/lib/compiler/src/sys_core_bsm.erl
new file mode 100644
index 0000000000..3e04cc33df
--- /dev/null
+++ b/lib/compiler/src/sys_core_bsm.erl
@@ -0,0 +1,355 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%% Purpose : Optimize bit syntax matching.
+
+
+-module(sys_core_bsm).
+-export([module/2,format_error/1]).
+
+-include("core_parse.hrl").
+-import(lists, [member/2,nth/2,reverse/1,usort/1]).
+
+-spec module(cerl:c_module(), [compile:option()]) -> {'ok', cerl:c_module()}.
+
+module(#c_module{defs=Ds0}=Mod, Opts) ->
+ {Ds,Ws0} = function(Ds0, [], []),
+ case member(bin_opt_info, Opts) of
+ false ->
+ {ok,Mod#c_module{defs=Ds}};
+ true ->
+ Ws1 = [make_warning(Where, What) || {Where,What} <- Ws0],
+ Ws = usort(Ws1),
+ {ok,Mod#c_module{defs=Ds},Ws}
+ end.
+
+function([{#c_var{name={F,Arity}}=Name,B0}|Fs], FsAcc, Ws0) ->
+ try cerl_trees:mapfold(fun bsm_an/2, Ws0, B0) of
+ {B,Ws} ->
+ function(Fs, [{Name,B}|FsAcc], Ws)
+ catch
+ Class:Error ->
+ Stack = erlang:get_stacktrace(),
+ io:fwrite("Function: ~w/~w\n", [F,Arity]),
+ erlang:raise(Class, Error, Stack)
+ end;
+function([], Fs, Ws) ->
+ {reverse(Fs),Ws}.
+
+-type error() :: atom().
+-spec format_error(error()) -> nonempty_string().
+
+format_error(bin_opt_alias) ->
+ "INFO: the '=' operator will prevent delayed sub binary optimization";
+format_error(bin_partition) ->
+ "INFO: matching non-variables after a previous clause matching a variable "
+ "will prevent delayed sub binary optimization";
+format_error(bin_left_var_used_in_guard) ->
+ "INFO: a variable to the left of the binary pattern is used in a guard; "
+ "will prevent delayed sub binary optimization";
+format_error(bin_argument_order) ->
+ "INFO: matching anything else but a plain variable to the left of "
+ "binary pattern will prevent delayed sub binary optimization; "
+ "SUGGEST changing argument order";
+format_error(bin_var_used) ->
+ "INFO: using a matched out sub binary will prevent "
+ "delayed sub binary optimization";
+format_error(orig_bin_var_used_in_guard) ->
+ "INFO: using the original binary variable in a guard will prevent "
+ "delayed sub binary optimization";
+format_error(bin_var_used_in_guard) ->
+ "INFO: using a matched out sub binary in a guard will prevent "
+ "delayed sub binary optimization".
+
+
+%%%
+%%% Annotate bit syntax matching to faciliate optimization in further passes.
+%%%
+
+bsm_an(Core0, Ws0) ->
+ case bsm_an(Core0) of
+ {ok,Core} ->
+ {Core,Ws0};
+ {ok,Core,W} ->
+ {Core,[W|Ws0]}
+ end.
+
+bsm_an(#c_case{arg=#c_var{}=V}=Case) ->
+ bsm_an_1([V], Case);
+bsm_an(#c_case{arg=#c_values{es=Es}}=Case) ->
+ bsm_an_1(Es, Case);
+bsm_an(Other) ->
+ {ok,Other}.
+
+bsm_an_1(Vs, #c_case{clauses=Cs}=Case) ->
+ case bsm_leftmost(Cs) of
+ none -> {ok,Case};
+ Pos -> bsm_an_2(Vs, Cs, Case, Pos)
+ end.
+
+bsm_an_2(Vs, Cs, Case, Pos) ->
+ case bsm_nonempty(Cs, Pos) of
+ true -> bsm_an_3(Vs, Cs, Case, Pos);
+ false -> {ok,Case}
+ end.
+
+bsm_an_3(Vs, Cs, Case, Pos) ->
+ try
+ bsm_ensure_no_partition(Cs, Pos),
+ {ok,bsm_do_an(Vs, Pos, Cs, Case)}
+ catch
+ throw:{problem,Where,What} ->
+ {ok,Case,{Where,What}}
+ end.
+
+bsm_do_an(Vs0, Pos, Cs0, Case) ->
+ case nth(Pos, Vs0) of
+ #c_var{name=Vname}=V0 ->
+ Cs = bsm_do_an_var(Vname, Pos, Cs0, []),
+ V = bsm_annotate_for_reuse(V0),
+ Bef = lists:sublist(Vs0, Pos-1),
+ Aft = lists:nthtail(Pos, Vs0),
+ case Bef ++ [V|Aft] of
+ [_] ->
+ Case#c_case{arg=V,clauses=Cs};
+ Vs ->
+ Case#c_case{arg=#c_values{es=Vs},clauses=Cs}
+ end;
+ _ ->
+ Case
+ end.
+
+bsm_do_an_var(V, S, [#c_clause{pats=Ps,guard=G,body=B0}=C0|Cs], Acc) ->
+ case nth(S, Ps) of
+ #c_var{name=VarName} ->
+ case core_lib:is_var_used(V, G) of
+ true -> bsm_problem(C0, orig_bin_var_used_in_guard);
+ false -> ok
+ end,
+ case core_lib:is_var_used(VarName, G) of
+ true -> bsm_problem(C0, bin_var_used_in_guard);
+ false -> ok
+ end,
+ B1 = bsm_maybe_ctx_to_binary(VarName, B0),
+ B = bsm_maybe_ctx_to_binary(V, B1),
+ C = C0#c_clause{body=B},
+ bsm_do_an_var(V, S, Cs, [C|Acc]);
+ #c_alias{}=P ->
+ case bsm_could_match_binary(P) of
+ false ->
+ bsm_do_an_var(V, S, Cs, [C0|Acc]);
+ true ->
+ bsm_problem(C0, bin_opt_alias)
+ end;
+ P ->
+ case bsm_could_match_binary(P) andalso bsm_is_var_used(V, G, B0) of
+ false ->
+ bsm_do_an_var(V, S, Cs, [C0|Acc]);
+ true ->
+ bsm_problem(C0, bin_var_used)
+ end
+ end;
+bsm_do_an_var(_, _, [], Acc) -> reverse(Acc).
+
+bsm_annotate_for_reuse(#c_var{anno=Anno}=Var) ->
+ Var#c_var{anno=[reuse_for_context|Anno]}.
+
+bsm_is_var_used(V, G, B) ->
+ core_lib:is_var_used(V, G) orelse core_lib:is_var_used(V, B).
+
+bsm_maybe_ctx_to_binary(V, B) ->
+ case core_lib:is_var_used(V, B) andalso not previous_ctx_to_binary(V, B) of
+ false ->
+ B;
+ true ->
+ #c_seq{arg=#c_primop{name=#c_literal{val=bs_context_to_binary},
+ args=[#c_var{name=V}]},
+ body=B}
+ end.
+
+previous_ctx_to_binary(V, Core) ->
+ case Core of
+ #c_seq{arg=#c_primop{name=#c_literal{val=bs_context_to_binary},
+ args=[#c_var{name=V}]}} ->
+ true;
+ _ ->
+ false
+ end.
+
+%% bsm_leftmost(Cs) -> none | ArgumentNumber
+%% Find the leftmost argument that does binary matching. Return
+%% the number of the argument (1-N).
+
+bsm_leftmost(Cs) ->
+ bsm_leftmost_1(Cs, none).
+
+bsm_leftmost_1([#c_clause{pats=Ps}|Cs], Pos) ->
+ bsm_leftmost_2(Ps, Cs, 1, Pos);
+bsm_leftmost_1([], Pos) -> Pos.
+
+bsm_leftmost_2(_, Cs, Pos, Pos) ->
+ bsm_leftmost_1(Cs, Pos);
+bsm_leftmost_2([#c_binary{}|_], Cs, N, _) ->
+ bsm_leftmost_1(Cs, N);
+bsm_leftmost_2([_|Ps], Cs, N, Pos) ->
+ bsm_leftmost_2(Ps, Cs, N+1, Pos);
+bsm_leftmost_2([], Cs, _, Pos) ->
+ bsm_leftmost_1(Cs, Pos).
+
+%% bsm_nonempty(Cs, Pos) -> true|false
+%% Check if at least one of the clauses matches a non-empty
+%% binary in the given argument position.
+%%
+bsm_nonempty([#c_clause{pats=Ps}|Cs], Pos) ->
+ case nth(Pos, Ps) of
+ #c_binary{segments=[_|_]} ->
+ true;
+ _ ->
+ bsm_nonempty(Cs, Pos)
+ end;
+bsm_nonempty([], _ ) -> false.
+
+%% bsm_ensure_no_partition(Cs, Pos) -> ok (exception if problem)
+%% We must make sure that matching is not partitioned between
+%% variables like this:
+%% foo(<<...>>) -> ...
+%% foo(<Variable>) when ... -> ...
+%% foo(<Any non-variable pattern>) ->
+%% If there is such partition, we are not allowed to reuse the binary variable
+%% for the match context.
+%%
+%% Also, arguments to the left of the argument that is matched
+%% against a binary, are only allowed to be simple variables, not
+%% used in guards. The reason is that we must know that the binary is
+%% only matched in one place (i.e. there must be only one bs_start_match2
+%% instruction emitted).
+
+bsm_ensure_no_partition(Cs, Pos) ->
+ bsm_ensure_no_partition_1(Cs, Pos, before).
+
+%% Loop through each clause.
+bsm_ensure_no_partition_1([#c_clause{pats=Ps,guard=G}|Cs], Pos, State0) ->
+ State = bsm_ensure_no_partition_2(Ps, Pos, G, simple_vars, State0),
+ case State of
+ 'after' ->
+ bsm_ensure_no_partition_after(Cs, Pos);
+ _ ->
+ ok
+ end,
+ bsm_ensure_no_partition_1(Cs, Pos, State);
+bsm_ensure_no_partition_1([], _, _) -> ok.
+
+%% Loop through each pattern for this clause.
+bsm_ensure_no_partition_2([#c_binary{}=Where|_], 1, _, Vstate, State) ->
+ case State of
+ before when Vstate =:= simple_vars -> within;
+ before -> bsm_problem(Where, Vstate);
+ within when Vstate =:= simple_vars -> within;
+ within -> bsm_problem(Where, Vstate)
+ end;
+bsm_ensure_no_partition_2([#c_alias{}=Alias|_], 1, N, Vstate, State) ->
+ %% Retrieve the real pattern that the alias refers to and check that.
+ P = bsm_real_pattern(Alias),
+ bsm_ensure_no_partition_2([P], 1, N, Vstate, State);
+bsm_ensure_no_partition_2([_|_], 1, _, _Vstate, before=State) ->
+ %% No binary matching yet - therefore no partition.
+ State;
+bsm_ensure_no_partition_2([P|_], 1, _, Vstate, State) ->
+ case bsm_could_match_binary(P) of
+ false ->
+ %% If clauses can be freely arranged (Vstate =:= simple_vars),
+ %% a clause that cannot match a binary will not partition the clause.
+ %% Example:
+ %%
+ %% a(Var, <<>>) -> ...
+ %% a(Var, []) -> ...
+ %% a(Var, <<B>>) -> ...
+ %%
+ %% But if the clauses can't be freely rearranged, as in
+ %%
+ %% b(Var, <<X>>) -> ...
+ %% b(1, 2) -> ...
+ %%
+ %% we do have a problem.
+ %%
+ case Vstate of
+ simple_vars -> State;
+ _ -> bsm_problem(P, Vstate)
+ end;
+ true ->
+ %% The pattern P *may* match a binary, so we must update the state.
+ %% (P must be a variable.)
+ case State of
+ within -> 'after';
+ 'after' -> 'after'
+ end
+ end;
+bsm_ensure_no_partition_2([#c_var{name=V}|Ps], N, G, Vstate, S) ->
+ case core_lib:is_var_used(V, G) of
+ false ->
+ bsm_ensure_no_partition_2(Ps, N-1, G, Vstate, S);
+ true ->
+ bsm_ensure_no_partition_2(Ps, N-1, G, bin_left_var_used_in_guard, S)
+ end;
+bsm_ensure_no_partition_2([_|Ps], N, G, _, S) ->
+ bsm_ensure_no_partition_2(Ps, N-1, G, bin_argument_order, S).
+
+bsm_ensure_no_partition_after([#c_clause{pats=Ps}=C|Cs], Pos) ->
+ case nth(Pos, Ps) of
+ #c_var{} ->
+ bsm_ensure_no_partition_after(Cs, Pos);
+ _ ->
+ bsm_problem(C, bin_partition)
+ end;
+bsm_ensure_no_partition_after([], _) -> ok.
+
+bsm_could_match_binary(#c_alias{pat=P}) -> bsm_could_match_binary(P);
+bsm_could_match_binary(#c_cons{}) -> false;
+bsm_could_match_binary(#c_tuple{}) -> false;
+bsm_could_match_binary(#c_literal{val=Lit}) -> is_bitstring(Lit);
+bsm_could_match_binary(_) -> true.
+
+bsm_real_pattern(#c_alias{pat=P}) -> bsm_real_pattern(P);
+bsm_real_pattern(P) -> P.
+
+bsm_problem(Where, What) ->
+ throw({problem,Where,What}).
+
+make_warning(Core, Term) ->
+ case should_suppress_warning(Core) of
+ true ->
+ ok;
+ false ->
+ Anno = cerl:get_ann(Core),
+ Line = get_line(Anno),
+ File = get_file(Anno),
+ {File,[{Line,?MODULE,Term}]}
+ end.
+
+should_suppress_warning(Core) ->
+ Ann = cerl:get_ann(Core),
+ member(compiler_generated, Ann).
+
+get_line([Line|_]) when is_integer(Line) -> Line;
+get_line([_|T]) -> get_line(T);
+get_line([]) -> none.
+
+get_file([{file,File}|_]) -> File;
+get_file([_|T]) -> get_file(T);
+get_file([]) -> "no_file". % should not happen
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index e0de50f3ae..e0cd6da06f 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -71,7 +71,7 @@
-export([module/2,format_error/1]).
-import(lists, [map/2,foldl/3,foldr/3,mapfoldl/3,all/2,any/2,
- reverse/1,reverse/2,member/2,nth/2,flatten/1,
+ reverse/1,reverse/2,member/2,flatten/1,
unzip/1,keyfind/3]).
-import(cerl, [ann_c_cons/3,ann_c_map/3,ann_c_tuple/2]).
@@ -83,10 +83,11 @@
-ifdef(DEBUG).
-define(ASSERT(E),
case E of
- true -> ok;
+ true ->
+ ok;
false ->
io:format("~p, line ~p: assertion failed\n", [?MODULE,?LINE]),
- exit(assertion_failed)
+ error(assertion_failed)
end).
-else.
-define(ASSERT(E), ignore).
@@ -106,7 +107,6 @@
{'ok', cerl:c_module(), [_]}.
module(#c_module{defs=Ds0}=Mod, Opts) ->
- put(bin_opt_info, member(bin_opt_info, Opts)),
put(no_inline_list_funcs, not member(inline_list_funcs, Opts)),
case get(new_var_num) of
undefined -> put(new_var_num, 0);
@@ -115,12 +115,14 @@ module(#c_module{defs=Ds0}=Mod, Opts) ->
init_warnings(),
Ds1 = [function_1(D) || D <- Ds0],
erase(no_inline_list_funcs),
- erase(bin_opt_info),
{ok,Mod#c_module{defs=Ds1},get_warnings()}.
function_1({#c_var{name={F,Arity}}=Name,B0}) ->
try
- B = expr(B0, value, sub_new()), %This must be a fun!
+ B = find_fixpoint(fun(Core) ->
+ %% This must be a fun!
+ expr(Core, value, sub_new())
+ end, B0, 20),
{Name,B}
catch
Class:Error ->
@@ -129,6 +131,14 @@ function_1({#c_var{name={F,Arity}}=Name,B0}) ->
erlang:raise(Class, Error, Stack)
end.
+find_fixpoint(_OptFun, Core, 0) ->
+ Core;
+find_fixpoint(OptFun, Core0, Max) ->
+ case OptFun(Core0) of
+ Core0 -> Core0;
+ Core -> find_fixpoint(OptFun, Core, Max-1)
+ end.
+
%% body(Expr, Sub) -> Expr.
%% body(Expr, Context, Sub) -> Expr.
%% No special handling of anything except values.
@@ -160,13 +170,23 @@ guard(Expr, Sub) ->
%%
opt_guard_try(#c_seq{arg=Arg,body=Body0}=Seq) ->
Body = opt_guard_try(Body0),
- case {Arg,Body} of
- {#c_call{module=#c_literal{val=Mod},
- name=#c_literal{val=Name},
- args=Args},#c_literal{val=false}} ->
+ WillFail = case Body of
+ #c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=error},
+ args=[_]} ->
+ true;
+ #c_literal{val=false} ->
+ true;
+ _ ->
+ false
+ end,
+ case Arg of
+ #c_call{module=#c_literal{val=Mod},
+ name=#c_literal{val=Name},
+ args=Args} when WillFail ->
%% We have sequence consisting of a call (evaluated
%% for a possible exception and/or side effect only),
- %% followed by 'false'.
+ %% followed by 'false' or a call to error/1.
%% Since the sequence is inside a try block that will
%% default to 'false' if any exception occurs, not
%% evalutating the call will not change the behaviour
@@ -181,7 +201,7 @@ opt_guard_try(#c_seq{arg=Arg,body=Body0}=Seq) ->
%% be safely removed.
Body
end;
- {_,_} ->
+ _ ->
Seq#c_seq{body=Body}
end;
opt_guard_try(#c_case{clauses=Cs}=Term) ->
@@ -239,7 +259,7 @@ expr(#c_cons{anno=Anno,hd=H0,tl=T0}=Cons, Ctxt, Sub) ->
case Ctxt of
effect ->
add_warning(Cons, useless_building),
- expr(make_effect_seq([H1,T1], Sub), Ctxt, Sub);
+ make_effect_seq([H1,T1], Sub);
value ->
ann_c_cons(Anno, H1, T1)
end;
@@ -248,7 +268,7 @@ expr(#c_tuple{anno=Anno,es=Es0}=Tuple, Ctxt, Sub) ->
case Ctxt of
effect ->
add_warning(Tuple, useless_building),
- expr(make_effect_seq(Es, Sub), Ctxt, Sub);
+ make_effect_seq(Es, Sub);
value ->
ann_c_tuple(Anno, Es)
end;
@@ -257,7 +277,7 @@ expr(#c_map{anno=Anno,arg=V0,es=Es0}=Map, Ctxt, Sub) ->
case Ctxt of
effect ->
add_warning(Map, useless_building),
- expr(make_effect_seq(Es, Sub), Ctxt, Sub);
+ make_effect_seq(Es, Sub);
value ->
V = expr(V0, Ctxt, Sub),
ann_c_map(Anno,V,Es)
@@ -310,7 +330,7 @@ expr(#c_let{}=Let0, Ctxt, Sub) ->
Expr ->
%% The let body was successfully moved into the let argument.
%% Now recursively re-process the new expression.
- expr(Expr, Ctxt, sub_new_preserve_types(Sub))
+ Expr
end;
expr(#c_letrec{body=#c_var{}}=Letrec, effect, _Sub) ->
%% This is named fun in an 'effect' context. Warn and ignore.
@@ -351,7 +371,7 @@ expr(#c_case{}=Case0, Ctxt, Sub) ->
%% (in addition to any warnings that may have been emitted
%% according to the rules above).
%%
- case opt_bool_case(Case0) of
+ case opt_bool_case(Case0, Sub) of
#c_case{arg=Arg0,clauses=Cs0}=Case1 ->
Arg1 = body(Arg0, value, Sub),
LitExpr = cerl:is_literal(Arg1),
@@ -361,10 +381,8 @@ expr(#c_case{}=Case0, Ctxt, Sub) ->
warn_no_clause_match(Case1, Case),
Expr = eval_case(Case, Sub),
case move_case_into_arg(Case, Sub) of
- impossible ->
- bsm_an(Expr);
- Other ->
- expr(Other, Ctxt, sub_new_preserve_types(Sub))
+ impossible -> Expr;
+ Other -> Other
end;
Other ->
expr(Other, Ctxt, Sub)
@@ -468,7 +486,8 @@ bitstr(#c_bitstr{val=Val,size=Size}=BinSeg, Sub) ->
%% Currently, we don't attempt to check binaries because they
%% are difficult to check.
-is_safe_simple(#c_var{}, _) -> true;
+is_safe_simple(#c_var{}=Var, _) ->
+ not cerl:is_c_fname(Var);
is_safe_simple(#c_cons{hd=H,tl=T}, Sub) ->
is_safe_simple(H, Sub) andalso is_safe_simple(T, Sub);
is_safe_simple(#c_tuple{es=Es}, Sub) -> is_safe_simple_list(Es, Sub);
@@ -733,7 +752,7 @@ call(#c_call{args=As}=Call, #c_literal{val=M}=M0, #c_literal{val=N}=N0, Sub) ->
false ->
case sys_core_fold_lists:call(Call, M, N, As) of
none ->
- call_1(Call, M, N, As, Sub);
+ call_1(Call, M0, N0, As, Sub);
Core ->
expr(Core, Sub)
end
@@ -1129,7 +1148,13 @@ clause_1(#c_clause{guard=G0,body=B0}=Cl, Ps1, Cexpr, Ctxt, Sub1) ->
%%
%% case A of NewVar when true -> ...
%%
- sub_set_var(Var, Cexpr, Sub2);
+ case cerl:is_c_fname(Cexpr) of
+ false ->
+ sub_set_var(Var, Cexpr, Sub2);
+ true ->
+ %% We must not copy funs, and especially not into guards.
+ Sub2
+ end;
_ ->
Sub2
end,
@@ -1396,9 +1421,6 @@ sub_new() -> #sub{v=orddict:new(),s=cerl_sets:new(),t=#{}}.
sub_new(#sub{}=Sub) ->
Sub#sub{v=orddict:new(),t=#{}}.
-sub_new_preserve_types(#sub{}=Sub) ->
- Sub#sub{v=orddict:new()}.
-
sub_get_var(#c_var{name=V}=Var, #sub{v=S}) ->
case orddict:find(V, S) of
{ok,Val} -> Val;
@@ -1436,8 +1458,19 @@ sub_add_scope(Vs, #sub{s=Scope0}=Sub) ->
Sub#sub{s=Scope}.
sub_subst_scope(#sub{v=S0,s=Scope}=Sub) ->
- S = [{-1,#c_var{name=Sv}} || Sv <- cerl_sets:to_list(Scope)]++S0,
- Sub#sub{v=S}.
+ Initial = case S0 of
+ [{NegInt,_}|_] when is_integer(NegInt), NegInt < 0 ->
+ NegInt - 1;
+ _ ->
+ -1
+ end,
+ S = sub_subst_scope_1(cerl_sets:to_list(Scope), Initial, S0),
+ Sub#sub{v=orddict:from_list(S)}.
+
+%% The keys in an orddict must be unique. Make them so!
+sub_subst_scope_1([H|T], Key, Acc) ->
+ sub_subst_scope_1(T, Key-1, [{Key,#c_var{name=H}}|Acc]);
+sub_subst_scope_1([], _, Acc) -> Acc.
sub_is_val(#c_var{name=V}, #sub{v=S,s=Scope}) ->
%% When the bottleneck in sub_del_var/2 was eliminated, this
@@ -1528,9 +1561,11 @@ will_match(E, [P]) ->
will_match_1({false,_}) -> maybe;
will_match_1({true,_}) -> yes.
-%% opt_bool_case(CoreExpr) - CoreExpr'.
-%% Do various optimizations to case statement that has a
-%% boolean case expression.
+%% opt_bool_case(CoreExpr, Sub) - CoreExpr'.
+%%
+%% In bodies, do various optimizations to case statements that have
+%% boolean case expressions. We don't do the optimizations in guards,
+%% because they would thwart the optimization in v3_kernel.
%%
%% We start with some simple optimizations and normalization
%% to facilitate later optimizations.
@@ -1539,7 +1574,7 @@ will_match_1({true,_}) -> yes.
%% (or fail), we can remove any clause that cannot
%% possibly match 'true' or 'false'. Also, any clause
%% following both 'true' and 'false' clause can
-%% be removed. If successful, we will end up this:
+%% be removed. If successful, we will end up like this:
%%
%% case BoolExpr of case BoolExpr of
%% true -> false ->
@@ -1550,8 +1585,11 @@ will_match_1({true,_}) -> yes.
%%
%% We give up if there are clauses with guards, or if there
%% is a variable clause that matches anything.
-%%
-opt_bool_case(#c_case{arg=Arg}=Case0) ->
+
+opt_bool_case(#c_case{}=Case, #sub{in_guard=true}) ->
+ %% v3_kernel does a better job without "help".
+ Case;
+opt_bool_case(#c_case{arg=Arg}=Case0, #sub{in_guard=false}) ->
case is_bool_expr(Arg) of
false ->
Case0;
@@ -1563,8 +1601,7 @@ opt_bool_case(#c_case{arg=Arg}=Case0) ->
impossible ->
Case0
end
- end;
-opt_bool_case(Core) -> Core.
+ end.
opt_bool_clauses(#c_case{clauses=Cs}=Case) ->
Case#c_case{clauses=opt_bool_clauses(Cs, false, false)}.
@@ -1580,16 +1617,14 @@ opt_bool_clauses(Cs, true, true) ->
[]
end;
opt_bool_clauses([#c_clause{pats=[#c_literal{val=Lit}],
- guard=#c_literal{val=true},
- body=B}=C0|Cs], SeenT, SeenF) ->
+ guard=#c_literal{val=true}}=C|Cs], SeenT, SeenF) ->
case is_boolean(Lit) of
false ->
%% Not a boolean - this clause can't match.
- add_warning(C0, nomatch_clause_type),
+ add_warning(C, nomatch_clause_type),
opt_bool_clauses(Cs, SeenT, SeenF);
true ->
%% This clause will match.
- C = C0#c_clause{body=opt_bool_case(B)},
case {Lit,SeenT,SeenF} of
{false,_,false} ->
[C|opt_bool_clauses(Cs, SeenT, true)];
@@ -1865,10 +1900,10 @@ case_opt_arg_1(E0, Cs0, LitExpr) ->
true ->
E = case_opt_compiler_generated(E0),
Cs = case_opt_nomatch(E, Cs0, LitExpr),
- case cerl:data_type(E) of
- {atomic,_} ->
+ case cerl:is_literal(E) of
+ true ->
case_opt_lit(E, Cs);
- _ ->
+ false ->
case_opt_data(E, Cs)
end
end.
@@ -2016,10 +2051,10 @@ case_opt_lit_1(_, []) -> [].
%% the clauses where it is actually needed.
case_opt_data(E, Cs0) ->
- Es = cerl:data_es(E),
TypeSig = {cerl:data_type(E),cerl:data_arity(E)},
- try case_opt_data_1(Cs0, Es, TypeSig) of
+ try case_opt_data_1(Cs0, TypeSig) of
Cs ->
+ Es = cerl:data_es(E),
{ok,Es,Cs}
catch
throw:impossible ->
@@ -2027,44 +2062,47 @@ case_opt_data(E, Cs0) ->
{error,Cs0}
end.
-case_opt_data_1([{[P0|Ps0],C,PsAcc,Bs0}|Cs], Es, TypeSig) ->
+case_opt_data_1([{[P0|Ps0],C,PsAcc,Bs0}|Cs], TypeSig) ->
P = case_opt_compiler_generated(P0),
- BindTo = #c_var{name=dummy},
- {Ps1,[{BindTo,_}|Bs1]} = case_data_pat_alias(P, BindTo, TypeSig, []),
- [{Ps1++Ps0,C,PsAcc,Bs1++Bs0}|case_opt_data_1(Cs, Es, TypeSig)];
-case_opt_data_1([], _, _) -> [].
+ {Ps1,Bs} = case_opt_data_2(P, TypeSig, Bs0),
+ [{Ps1++Ps0,C,PsAcc,Bs}|case_opt_data_1(Cs, TypeSig)];
+case_opt_data_1([], _) -> [].
-case_data_pat_alias(P, BindTo0, TypeSig, Bs0) ->
- case cerl:type(P) of
- alias ->
- %% Recursively handle the pattern and bind to
- %% the alias variable.
- BindTo = cerl:alias_var(P),
- Apat0 = cerl:alias_pat(P),
- Ann = [compiler_generated],
- Apat = cerl:set_ann(Apat0, Ann),
- {Ps,Bs} = case_data_pat_alias(Apat, BindTo, TypeSig, Bs0),
- {Ps,[{BindTo0,BindTo}|Bs]};
- var ->
- %% Here we will need to actually build the data and bind
- %% it to the variable.
+case_opt_data_2(P, TypeSig, Bs0) ->
+ case case_analyze_pat(P) of
+ {[],Pat} when Pat =/= none ->
+ DataEs = cerl:data_es(P),
+ {DataEs,Bs0};
+ {[V|Vs],none} ->
{Type,Arity} = TypeSig,
Ann = [compiler_generated],
Vars = make_vars(Ann, Arity),
Data = cerl:ann_make_data(Ann, Type, Vars),
- Bs = [{BindTo0,P},{P,Data}|Bs0],
+ Bs = [{V,Data} | [{Var,V} || Var <- Vs] ++ Bs0],
{Vars,Bs};
- _ ->
- %% Since case_opt_nomatch/3 has removed all clauses that
- %% cannot match, we KNOW that this clause must match and
- %% that the pattern must be a data constructor.
- %% Here we must build the data and bind it to the variable.
+ {[V|Vs],Pat} when Pat =/= none ->
{Type,_} = TypeSig,
- DataEs = cerl:data_es(P),
+ DataEs = cerl:data_es(Pat),
Vars = pat_to_expr_list(DataEs),
Ann = [compiler_generated],
Data = cerl:ann_make_data(Ann, Type, Vars),
- {DataEs,[{BindTo0,Data}]}
+ Bs = [{V,Data} | [{Var,V} || Var <- Vs] ++ Bs0],
+ {DataEs,Bs}
+ end.
+
+case_analyze_pat(P) ->
+ case_analyze_pat_1(P, [], none).
+
+case_analyze_pat_1(P, Vs, Pat) ->
+ case cerl:type(P) of
+ alias ->
+ V = cerl:alias_var(P),
+ Apat = cerl:alias_pat(P),
+ case_analyze_pat_1(Apat, [V|Vs], Pat);
+ var ->
+ {[P|Vs],Pat};
+ _ ->
+ {Vs,P}
end.
%% pat_to_expr(Pattern) -> Expression.
@@ -2108,7 +2146,7 @@ make_var(A) ->
make_var_name() ->
N = get(new_var_num),
put(new_var_num, N+1),
- list_to_atom("fol"++integer_to_list(N)).
+ list_to_atom("@f"++integer_to_list(N)).
letify(Bs, Body) ->
Ann = cerl:get_ann(Body),
@@ -2122,7 +2160,7 @@ letify(Bs, Body) ->
-spec opt_not_in_let(cerl:c_let()) -> cerl:cerl().
opt_not_in_let(#c_let{vars=[_]=Vs0,arg=Arg0,body=Body0}=Let) ->
- case opt_not_in_let(Vs0, Arg0, Body0) of
+ case opt_not_in_let_0(Vs0, Arg0, Body0) of
{[],#c_values{es=[]},Body} ->
Body;
{Vs,Arg,Body} ->
@@ -2130,13 +2168,7 @@ opt_not_in_let(#c_let{vars=[_]=Vs0,arg=Arg0,body=Body0}=Let) ->
end;
opt_not_in_let(Let) -> Let.
-%% opt_not_in_let(Vs, Arg, Body) -> {Vs',Arg',Body'}
-%% Try to optimize away a 'not' operator in a 'let'.
-
--spec opt_not_in_let([cerl:c_var()], cerl:cerl(), cerl:cerl()) ->
- {[cerl:c_var()],cerl:cerl(),cerl:cerl()}.
-
-opt_not_in_let([#c_var{name=V}]=Vs0, Arg0, Body0) ->
+opt_not_in_let_0([#c_var{name=V}]=Vs0, Arg0, Body0) ->
case cerl:type(Body0) of
call ->
%% let <V> = Expr in not V ==>
@@ -2167,9 +2199,7 @@ opt_not_in_let([#c_var{name=V}]=Vs0, Arg0, Body0) ->
end;
_ ->
{Vs0,Arg0,Body0}
- end;
-opt_not_in_let(Vs, Arg, Body) ->
- {Vs,Arg,Body}.
+ end.
opt_not_in_let_1(V, Call, Body) ->
case Call of
@@ -2215,24 +2245,24 @@ inverse_rel_op('=<') -> '>';
inverse_rel_op(_) -> no.
-%% opt_bool_case_in_let(LetExpr, Sub) -> Core
+%% opt_bool_case_in_let(LetExpr) -> Core
opt_bool_case_in_let(#c_let{vars=Vs,arg=Arg,body=B}=Let, Sub) ->
- opt_case_in_let_1(Vs, Arg, B, Let, Sub).
+ opt_bool_case_in_let_1(Vs, Arg, B, Let, Sub).
-opt_case_in_let_1([#c_var{name=V}], Arg,
+opt_bool_case_in_let_1([#c_var{name=V}], Arg,
#c_case{arg=#c_var{name=V}}=Case0, Let, Sub) ->
case is_simple_case_arg(Arg) of
true ->
- Case = opt_bool_case(Case0#c_case{arg=Arg}),
+ Case = opt_bool_case(Case0#c_case{arg=Arg}, Sub),
case core_lib:is_var_used(V, Case) of
- false -> expr(Case, sub_new(Sub));
+ false -> Case;
true -> Let
end;
false ->
Let
end;
-opt_case_in_let_1(_, _, _, Let, _) -> Let.
+opt_bool_case_in_let_1(_, _, _, Let, _) -> Let.
%% is_simple_case_arg(Expr) -> true|false
%% Determine whether the Expr is simple enough to be worth
@@ -2365,9 +2395,7 @@ is_safe_bool_expr_list([], _, _) -> true.
%% as a let or a sequence, move the original let body into the complex
%% expression.
-simplify_let(#c_let{arg=Arg0}=Let0, Sub) ->
- Arg = opt_bool_case(Arg0),
- Let = Let0#c_let{arg=Arg},
+simplify_let(#c_let{arg=Arg}=Let, Sub) ->
move_let_into_expr(Let, Arg, Sub).
move_let_into_expr(#c_let{vars=InnerVs0,body=InnerBody0}=Inner,
@@ -2623,11 +2651,10 @@ opt_simple_let_0(#c_let{arg=Arg0}=Let, Ctxt, Sub) ->
opt_simple_let_1(#c_let{vars=Vs0,body=B0}=Let, Arg0, Ctxt, Sub0) ->
%% Optimise let and add new substitutions.
- {Vs1,Args,Sub1} = let_substs(Vs0, Arg0, Sub0),
- BodySub = update_let_types(Vs1, Args, Sub1),
- B1 = body(B0, Ctxt, BodySub),
- Arg1 = core_lib:make_values(Args),
- {Vs,Arg,B} = opt_not_in_let(Vs1, Arg1, B1),
+ {Vs,Args,Sub1} = let_substs(Vs0, Arg0, Sub0),
+ BodySub = update_let_types(Vs, Args, Sub1),
+ B = body(B0, Ctxt, BodySub),
+ Arg = core_lib:make_values(Args),
opt_simple_let_2(Let, Vs, Arg, B, B0, Ctxt, Sub1).
opt_simple_let_2(Let0, Vs0, Arg0, Body, PrevBody, Ctxt, Sub) ->
@@ -2640,25 +2667,23 @@ opt_simple_let_2(Let0, Vs0, Arg0, Body, PrevBody, Ctxt, Sub) ->
false ->
%% let <Var> = Arg in <OtherVar> ==> seq Arg OtherVar
Arg = maybe_suppress_warnings(Arg1, Vs0, PrevBody),
- expr(#c_seq{arg=Arg,body=Body}, Ctxt,
- sub_new_preserve_types(Sub))
+ #c_seq{arg=Arg,body=Body}
end;
{[],#c_values{es=[]},_} ->
%% No variables left.
Body;
{Vs,Arg1,#c_literal{}} ->
Arg = maybe_suppress_warnings(Arg1, Vs, PrevBody),
- E = case Ctxt of
- effect ->
- %% Throw away the literal body.
- Arg;
- value ->
- %% Since the variable is not used in the body, we
- %% can rewrite the let to a sequence.
- %% let <Var> = Arg in Literal ==> seq Arg Literal
- #c_seq{arg=Arg,body=Body}
- end,
- expr(E, Ctxt, sub_new_preserve_types(Sub));
+ case Ctxt of
+ effect ->
+ %% Throw away the literal body.
+ Arg;
+ value ->
+ %% Since the variable is not used in the body, we
+ %% can rewrite the let to a sequence.
+ %% let <Var> = Arg in Literal ==> seq Arg Literal
+ #c_seq{arg=Arg,body=Body}
+ end;
{Vs,Arg1,Body} ->
%% If none of the variables are used in the body, we can
%% rewrite the let to a sequence:
@@ -2667,12 +2692,10 @@ opt_simple_let_2(Let0, Vs0, Arg0, Body, PrevBody, Ctxt, Sub) ->
case is_any_var_used(Vs, Body) of
false ->
Arg = maybe_suppress_warnings(Arg1, Vs, PrevBody),
- expr(#c_seq{arg=Arg,body=Body}, Ctxt,
- sub_new_preserve_types(Sub));
+ #c_seq{arg=Arg,body=Body};
true ->
Let1 = Let0#c_let{vars=Vs,arg=Arg1,body=Body},
- Let2 = opt_bool_case_in_let(Let1, Sub),
- opt_case_in_let_arg(Let2, Ctxt, Sub)
+ opt_bool_case_in_let(Let1, Sub)
end
end.
@@ -2800,48 +2823,6 @@ move_case_into_arg(#c_case{arg=#c_seq{arg=OuterArg,body=InnerArg}=Outer,
move_case_into_arg(_, _) ->
impossible.
-%% In guards only, rewrite a case in a let argument like
-%%
-%% let <Var> = case <> of
-%% <> when AnyGuard -> Literal1;
-%% <> when AnyGuard -> Literal2
-%% end
-%% in LetBody
-%%
-%% to
-%%
-%% case <> of
-%% <> when AnyGuard ->
-%% let <Var> = Literal1 in LetBody
-%% <> when 'true' ->
-%% let <Var> = Literal2 in LetBody
-%% end
-%%
-%% In the worst case, the size of the code could increase.
-%% In practice, though, substituting the literals into
-%% LetBody and doing constant folding will decrease the code
-%% size. (Doing this transformation outside of guards could
-%% lead to a substantational increase in code size.)
-%%
-opt_case_in_let_arg(#c_let{arg=#c_case{}=Case}=Let, Ctxt,
- #sub{in_guard=true}=Sub) ->
- opt_case_in_let_arg_1(Let, Case, Ctxt, Sub);
-opt_case_in_let_arg(Let, _, _) -> Let.
-
-opt_case_in_let_arg_1(Let0, #c_case{arg=#c_values{es=[]},
- clauses=Cs}=Case0, Ctxt, Sub) ->
- Let = mark_compiler_generated(Let0),
- case Cs of
- [#c_clause{body=#c_literal{}=BodyA}=Ca0,
- #c_clause{body=#c_literal{}=BodyB}=Cb0] ->
- Ca = Ca0#c_clause{body=Let#c_let{arg=BodyA}},
- Cb = Cb0#c_clause{body=Let#c_let{arg=BodyB}},
- Case = Case0#c_case{clauses=[Ca,Cb]},
- expr(Case, Ctxt, sub_new_preserve_types(Sub));
- _ -> Let
- end;
-opt_case_in_let_arg_1(Let, _, _, _) -> Let.
-
is_any_var_used([#c_var{name=V}|Vs], Expr) ->
case core_lib:is_var_used(V, Expr) of
false -> is_any_var_used(Vs, Expr);
@@ -2949,7 +2930,9 @@ returns_integer(bit_size, [_]) -> true;
returns_integer('bsl', [_,_]) -> true;
returns_integer('bsr', [_,_]) -> true;
returns_integer(byte_size, [_]) -> true;
+returns_integer(ceil, [_]) -> true;
returns_integer('div', [_,_]) -> true;
+returns_integer(floor, [_]) -> true;
returns_integer(length, [_]) -> true;
returns_integer('rem', [_,_]) -> true;
returns_integer('round', [_]) -> true;
@@ -2967,15 +2950,8 @@ update_types(Expr, Pat, #sub{t=Tdb0}=Sub) ->
Tdb = update_types_1(Expr, Pat, Tdb0),
Sub#sub{t=Tdb}.
-update_types_1(#c_var{name=V,anno=Anno}, Pat, Types) ->
- case member(reuse_for_context, Anno) of
- true ->
- %% If a variable has been marked for reuse of binary context,
- %% optimizations based on type information are unsafe.
- kill_types(V, Types);
- false ->
- update_types_2(V, Pat, Types)
- end;
+update_types_1(#c_var{name=V}, Pat, Types) ->
+ update_types_2(V, Pat, Types);
update_types_1(_, _, Types) -> Types.
update_types_2(V, [#c_tuple{}=P], Types) ->
@@ -3018,274 +2994,14 @@ copy_type(_, _, Tdb) -> Tdb.
void() -> #c_literal{val=ok}.
-%%%
-%%% Annotate bit syntax matching to faciliate optimization in further passes.
-%%%
-
-bsm_an(#c_case{arg=#c_var{}=V}=Case) ->
- bsm_an_1([V], Case);
-bsm_an(#c_case{arg=#c_values{es=Es}}=Case) ->
- bsm_an_1(Es, Case);
-bsm_an(Other) -> Other.
-
-bsm_an_1(Vs, #c_case{clauses=Cs}=Case) ->
- case bsm_leftmost(Cs) of
- none -> Case;
- Pos -> bsm_an_2(Vs, Cs, Case, Pos)
- end.
-
-bsm_an_2(Vs, Cs, Case, Pos) ->
- case bsm_nonempty(Cs, Pos) of
- true -> bsm_an_3(Vs, Cs, Case, Pos);
- false -> Case
- end.
-
-bsm_an_3(Vs, Cs, Case, Pos) ->
- try
- bsm_ensure_no_partition(Cs, Pos),
- bsm_do_an(Vs, Pos, Cs, Case)
- catch
- throw:{problem,Where,What} ->
- add_bin_opt_info(Where, What),
- Case
- end.
-
-bsm_do_an(Vs0, Pos, Cs0, Case) ->
- case nth(Pos, Vs0) of
- #c_var{name=Vname}=V0 ->
- Cs = bsm_do_an_var(Vname, Pos, Cs0, []),
- V = bsm_annotate_for_reuse(V0),
- Bef = lists:sublist(Vs0, Pos-1),
- Aft = lists:nthtail(Pos, Vs0),
- case Bef ++ [V|Aft] of
- [_] ->
- Case#c_case{arg=V,clauses=Cs};
- Vs ->
- Case#c_case{arg=#c_values{es=Vs},clauses=Cs}
- end;
- _ ->
- Case
- end.
-
-bsm_do_an_var(V, S, [#c_clause{pats=Ps,guard=G,body=B0}=C0|Cs], Acc) ->
- case nth(S, Ps) of
- #c_var{name=VarName} ->
- case core_lib:is_var_used(V, G) of
- true -> bsm_problem(C0, orig_bin_var_used_in_guard);
- false -> ok
- end,
- case core_lib:is_var_used(VarName, G) of
- true -> bsm_problem(C0, bin_var_used_in_guard);
- false -> ok
- end,
- B1 = bsm_maybe_ctx_to_binary(VarName, B0),
- B = bsm_maybe_ctx_to_binary(V, B1),
- C = C0#c_clause{body=B},
- bsm_do_an_var(V, S, Cs, [C|Acc]);
- #c_alias{}=P ->
- case bsm_could_match_binary(P) of
- false ->
- bsm_do_an_var(V, S, Cs, [C0|Acc]);
- true ->
- bsm_problem(C0, bin_opt_alias)
- end;
- P ->
- case bsm_could_match_binary(P) andalso bsm_is_var_used(V, G, B0) of
- false ->
- bsm_do_an_var(V, S, Cs, [C0|Acc]);
- true ->
- bsm_problem(C0, bin_var_used)
- end
- end;
-bsm_do_an_var(_, _, [], Acc) -> reverse(Acc).
-
-bsm_annotate_for_reuse(#c_var{anno=Anno}=Var) ->
- case member(reuse_for_context, Anno) of
- false -> Var#c_var{anno=[reuse_for_context|Anno]};
- true -> Var
- end.
-
-bsm_is_var_used(V, G, B) ->
- core_lib:is_var_used(V, G) orelse core_lib:is_var_used(V, B).
-
-bsm_maybe_ctx_to_binary(V, B) ->
- case core_lib:is_var_used(V, B) andalso not previous_ctx_to_binary(V, B) of
- false ->
- B;
- true ->
- #c_seq{arg=#c_primop{name=#c_literal{val=bs_context_to_binary},
- args=[#c_var{name=V}]},
- body=B}
- end.
-
-previous_ctx_to_binary(V, Core) ->
- case Core of
- #c_seq{arg=#c_primop{name=#c_literal{val=bs_context_to_binary},
- args=[#c_var{name=V}]}} ->
- true;
- _ ->
- false
- end.
-
-%% bsm_leftmost(Cs) -> none | ArgumentNumber
-%% Find the leftmost argument that does binary matching. Return
-%% the number of the argument (1-N).
-
-bsm_leftmost(Cs) ->
- bsm_leftmost_1(Cs, none).
-
-bsm_leftmost_1([#c_clause{pats=Ps}|Cs], Pos) ->
- bsm_leftmost_2(Ps, Cs, 1, Pos);
-bsm_leftmost_1([], Pos) -> Pos.
-
-bsm_leftmost_2(_, Cs, Pos, Pos) ->
- bsm_leftmost_1(Cs, Pos);
-bsm_leftmost_2([#c_binary{}|_], Cs, N, _) ->
- bsm_leftmost_1(Cs, N);
-bsm_leftmost_2([_|Ps], Cs, N, Pos) ->
- bsm_leftmost_2(Ps, Cs, N+1, Pos);
-bsm_leftmost_2([], Cs, _, Pos) ->
- bsm_leftmost_1(Cs, Pos).
-
-%% bsm_nonempty(Cs, Pos) -> true|false
-%% Check if at least one of the clauses matches a non-empty
-%% binary in the given argument position.
-%%
-bsm_nonempty([#c_clause{pats=Ps}|Cs], Pos) ->
- case nth(Pos, Ps) of
- #c_binary{segments=[_|_]} ->
- true;
- _ ->
- bsm_nonempty(Cs, Pos)
- end;
-bsm_nonempty([], _ ) -> false.
-
-%% bsm_ensure_no_partition(Cs, Pos) -> ok (exception if problem)
-%% We must make sure that matching is not partitioned between
-%% variables like this:
-%% foo(<<...>>) -> ...
-%% foo(<Variable>) when ... -> ...
-%% foo(<Any non-variable pattern>) ->
-%% If there is such partition, we are not allowed to reuse the binary variable
-%% for the match context.
-%%
-%% Also, arguments to the left of the argument that is matched
-%% against a binary, are only allowed to be simple variables, not
-%% used in guards. The reason is that we must know that the binary is
-%% only matched in one place (i.e. there must be only one bs_start_match2
-%% instruction emitted).
-
-bsm_ensure_no_partition(Cs, Pos) ->
- bsm_ensure_no_partition_1(Cs, Pos, before).
-
-%% Loop through each clause.
-bsm_ensure_no_partition_1([#c_clause{pats=Ps,guard=G}|Cs], Pos, State0) ->
- State = bsm_ensure_no_partition_2(Ps, Pos, G, simple_vars, State0),
- case State of
- 'after' ->
- bsm_ensure_no_partition_after(Cs, Pos);
- _ ->
- ok
- end,
- bsm_ensure_no_partition_1(Cs, Pos, State);
-bsm_ensure_no_partition_1([], _, _) -> ok.
-
-%% Loop through each pattern for this clause.
-bsm_ensure_no_partition_2([#c_binary{}=Where|_], 1, _, Vstate, State) ->
- case State of
- before when Vstate =:= simple_vars -> within;
- before -> bsm_problem(Where, Vstate);
- within when Vstate =:= simple_vars -> within;
- within -> bsm_problem(Where, Vstate)
- end;
-bsm_ensure_no_partition_2([#c_alias{}=Alias|_], 1, N, Vstate, State) ->
- %% Retrieve the real pattern that the alias refers to and check that.
- P = bsm_real_pattern(Alias),
- bsm_ensure_no_partition_2([P], 1, N, Vstate, State);
-bsm_ensure_no_partition_2([_|_], 1, _, _Vstate, before=State) ->
- %% No binary matching yet - therefore no partition.
- State;
-bsm_ensure_no_partition_2([P|_], 1, _, Vstate, State) ->
- case bsm_could_match_binary(P) of
- false ->
- %% If clauses can be freely arranged (Vstate =:= simple_vars),
- %% a clause that cannot match a binary will not partition the clause.
- %% Example:
- %%
- %% a(Var, <<>>) -> ...
- %% a(Var, []) -> ...
- %% a(Var, <<B>>) -> ...
- %%
- %% But if the clauses can't be freely rearranged, as in
- %%
- %% b(Var, <<X>>) -> ...
- %% b(1, 2) -> ...
- %%
- %% we do have a problem.
- %%
- case Vstate of
- simple_vars -> State;
- _ -> bsm_problem(P, Vstate)
- end;
- true ->
- %% The pattern P *may* match a binary, so we must update the state.
- %% (P must be a variable.)
- case State of
- within -> 'after';
- 'after' -> 'after'
- end
- end;
-bsm_ensure_no_partition_2([#c_var{name=V}|Ps], N, G, Vstate, S) ->
- case core_lib:is_var_used(V, G) of
- false ->
- bsm_ensure_no_partition_2(Ps, N-1, G, Vstate, S);
- true ->
- bsm_ensure_no_partition_2(Ps, N-1, G, bin_left_var_used_in_guard, S)
- end;
-bsm_ensure_no_partition_2([_|Ps], N, G, _, S) ->
- bsm_ensure_no_partition_2(Ps, N-1, G, bin_argument_order, S).
-
-bsm_ensure_no_partition_after([#c_clause{pats=Ps}=C|Cs], Pos) ->
- case nth(Pos, Ps) of
- #c_var{} ->
- bsm_ensure_no_partition_after(Cs, Pos);
- _ ->
- bsm_problem(C, bin_partition)
- end;
-bsm_ensure_no_partition_after([], _) -> ok.
-
-bsm_could_match_binary(#c_alias{pat=P}) -> bsm_could_match_binary(P);
-bsm_could_match_binary(#c_cons{}) -> false;
-bsm_could_match_binary(#c_tuple{}) -> false;
-bsm_could_match_binary(#c_literal{val=Lit}) -> is_bitstring(Lit);
-bsm_could_match_binary(_) -> true.
-
-bsm_real_pattern(#c_alias{pat=P}) -> bsm_real_pattern(P);
-bsm_real_pattern(P) -> P.
-
-bsm_problem(Where, What) ->
- throw({problem,Where,What}).
%%%
%%% Handling of warnings.
%%%
-mark_compiler_generated(Term) ->
- cerl_trees:map(fun mark_compiler_generated_1/1, Term).
-
-mark_compiler_generated_1(#c_call{anno=Anno}=Term) ->
- Term#c_call{anno=[compiler_generated|Anno--[compiler_generated]]};
-mark_compiler_generated_1(Term) -> Term.
-
init_warnings() ->
put({?MODULE,warnings}, []).
-add_bin_opt_info(Core, Term) ->
- case get(bin_opt_info) of
- true -> add_warning(Core, Term);
- false -> ok
- end.
-
add_warning(Core, Term) ->
case should_suppress_warning(Core) of
true ->
@@ -3407,28 +3123,7 @@ format_error(result_ignored) ->
format_error(invalid_call) ->
"invalid function call";
format_error(useless_building) ->
- "a term is constructed, but never used";
-format_error(bin_opt_alias) ->
- "INFO: the '=' operator will prevent delayed sub binary optimization";
-format_error(bin_partition) ->
- "INFO: matching non-variables after a previous clause matching a variable "
- "will prevent delayed sub binary optimization";
-format_error(bin_left_var_used_in_guard) ->
- "INFO: a variable to the left of the binary pattern is used in a guard; "
- "will prevent delayed sub binary optimization";
-format_error(bin_argument_order) ->
- "INFO: matching anything else but a plain variable to the left of "
- "binary pattern will prevent delayed sub binary optimization; "
- "SUGGEST changing argument order";
-format_error(bin_var_used) ->
- "INFO: using a matched out sub binary will prevent "
- "delayed sub binary optimization";
-format_error(orig_bin_var_used_in_guard) ->
- "INFO: using the original binary variable in a guard will prevent "
- "delayed sub binary optimization";
-format_error(bin_var_used_in_guard) ->
- "INFO: using a matched out sub binary in a guard will prevent "
- "delayed sub binary optimization".
+ "a term is constructed, but never used".
-ifdef(DEBUG).
%% In order for simplify_let/2 to work correctly, the list of
@@ -3439,12 +3134,18 @@ format_error(bin_var_used_in_guard) ->
verify_scope(E, #sub{s=Scope}) ->
Free0 = cerl_trees:free_variables(E),
Free = [V || V <- Free0, not is_tuple(V)], %Ignore function names.
- case ordsets:is_subset(Free, cerl_sets:to_list(Scope)) of
- true -> true;
+ case is_subset_of_scope(Free, Scope) of
+ true ->
+ true;
false ->
io:format("~p\n", [E]),
io:format("~p\n", [Free]),
- io:format("~p\n", [cerl_sets:to_list(Scope)]),
+ io:format("~p\n", [ordsets:from_list(cerl_sets:to_list(Scope))]),
false
end.
+
+is_subset_of_scope([V|Vs], Scope) ->
+ cerl_sets:is_element(V, Scope) andalso is_subset_of_scope(Vs, Scope);
+is_subset_of_scope([], _) -> true.
+
-endif.
diff --git a/lib/compiler/src/sys_pre_attributes.erl b/lib/compiler/src/sys_pre_attributes.erl
index bc93c85989..67adae5acf 100644
--- a/lib/compiler/src/sys_pre_attributes.erl
+++ b/lib/compiler/src/sys_pre_attributes.erl
@@ -25,10 +25,10 @@
-define(OPTION_TAG, attributes).
--record(state, {forms,
- pre_ops = [],
- post_ops = [],
- options}).
+-record(state, {forms :: [form()],
+ pre_ops = [] :: [op()],
+ post_ops = [] :: [op()],
+ options :: [option()]}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Inserts, deletes and replaces Erlang compiler attributes.
@@ -59,9 +59,23 @@
%% due to that the pre_transform pass did not find the attribute plus
%% all insert operations.
+-type attribute() :: atom().
+-type value() :: term().
+-type form() :: {function, integer(), atom(), arity(), _}
+ | {attribute, integer(), attribute(), _}.
+-type option() :: compile:option()
+ | {'attribute', 'insert', attribute(), value()}
+ | {'attribute', 'replace', attribute(), value()}
+ | {'attribute', 'delete', attribute()}.
+-type op() :: {'insert', attribute(), value()}
+ | {'replace', attribute(), value()}
+ | {'delete', attribute()}.
+
+-spec parse_transform([form()], [option()]) -> [form()].
+
parse_transform(Forms, Options) ->
S = #state{forms = Forms, options = Options},
- S2 = init_transform(S),
+ S2 = init_transform(Options, S),
report_verbose("Pre options: ~p~n", [S2#state.pre_ops], S2),
report_verbose("Post options: ~p~n", [S2#state.post_ops], S2),
S3 = pre_transform(S2),
@@ -71,13 +85,6 @@ parse_transform(Forms, Options) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Computes the lists of pre_ops and post_ops that are
%% used in the real transformation.
-init_transform(S) ->
- case S#state.options of
- Options when is_list(Options) ->
- init_transform(Options, S);
- Option ->
- init_transform([Option], S)
- end.
init_transform([{attribute, insert, Name, Val} | Tail], S) ->
Op = {insert, Name, Val},
@@ -92,12 +99,9 @@ init_transform([{attribute, delete, Name} | Tail], S) ->
Op = {delete, Name},
PreOps = [Op | S#state.pre_ops],
init_transform(Tail, S#state{pre_ops = PreOps});
-init_transform([], S) ->
- S;
init_transform([_ | T], S) ->
init_transform(T, S);
-init_transform(BadOpt, S) ->
- report_error("Illegal option (ignored): ~p~n", [BadOpt], S),
+init_transform([], S) ->
S.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -176,18 +180,9 @@ attrs([], _, _) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Report functions.
%%
-%% Errors messages are controlled with the 'report_errors' compiler option
%% Warning messages are controlled with the 'report_warnings' compiler option
%% Verbose messages are controlled with the 'verbose' compiler option
-report_error(Format, Args, S) ->
- case is_error(S) of
- true ->
- io:format("~p: * ERROR * " ++ Format, [?MODULE | Args]);
- false ->
- ok
- end.
-
report_warning(Format, Args, S) ->
case is_warning(S) of
true ->
@@ -204,9 +199,6 @@ report_verbose(Format, Args, S) ->
ok
end.
-is_error(S) ->
- lists:member(report_errors, S#state.options) or is_verbose(S).
-
is_warning(S) ->
lists:member(report_warnings, S#state.options) or is_verbose(S).
diff --git a/lib/compiler/src/sys_pre_expand.erl b/lib/compiler/src/sys_pre_expand.erl
deleted file mode 100644
index 7ab4e1845c..0000000000
--- a/lib/compiler/src/sys_pre_expand.erl
+++ /dev/null
@@ -1,616 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%% Purpose : Expand some source Erlang constructions. This is part of the
-%% pre-processing phase.
-
-%% N.B. Although structs (tagged tuples) are not yet allowed in the
-%% language there is code included in pattern/2 and expr/3 (commented out)
-%% that handles them by transforming them to tuples.
-
--module(sys_pre_expand).
-
-%% Main entry point.
--export([module/2]).
-
--import(lists, [member/2,foldl/3,foldr/3]).
-
--type fa() :: {atom(), arity()}.
-
--record(expand, {module=[], %Module name
- exports=[], %Exports
- attributes=[], %Attributes
- callbacks=[], %Callbacks
- optional_callbacks=[] :: [fa()], %Optional callbacks
- vcount=0, %Variable counter
- func=[], %Current function
- arity=[], %Arity for current function
- fcount=0, %Local fun count
- ctype %Call type map
- }).
-
-%% module(Forms, CompileOptions)
-%% {ModuleName,Exports,TransformedForms,CompileOptions'}
-%% Expand the forms in one module.
-%%
-%% CompileOptions is augmented with options from -compile attributes.
-
-module(Fs0, Opts0) ->
-
- %% Expand records. Normalise guard tests.
- Fs = erl_expand_records:module(Fs0, Opts0),
-
- Opts = compiler_options(Fs) ++ Opts0,
-
- %% Set pre-defined exported functions.
- PreExp = [{module_info,0},{module_info,1}],
-
- %% Build the set of defined functions and the initial call
- %% type map.
- Defined = defined_functions(Fs, PreExp),
- Ctype = maps:from_list([{K,local} || K <- Defined]),
-
- %% Build initial expand record.
- St0 = #expand{exports=PreExp,
- ctype=Ctype
- },
-
- %% Expand the functions.
- {Tfs,St1} = forms(Fs, St0),
-
- %% Get the correct list of exported functions.
- Exports = case member(export_all, Opts) of
- true -> Defined;
- false -> St1#expand.exports
- end,
- St2 = St1#expand{exports=Exports,ctype=undefined},
-
- %% Generate all functions from stored info.
- {Ats,St3} = module_attrs(St2),
- {Mfs,St4} = module_predef_funcs(St3),
- {St4#expand.module, St4#expand.exports, Ats ++ Tfs ++ Mfs,
- Opts}.
-
-compiler_options(Forms) ->
- lists:flatten([C || {attribute,_,compile,C} <- Forms]).
-
-%% defined_function(Forms, Predef) -> Functions.
-%% Add function to defined if form is a function.
-
-defined_functions(Forms, Predef) ->
- Fs = foldl(fun({function,_,N,A,_Cs}, Acc) -> [{N,A}|Acc];
- (_, Acc) -> Acc
- end, Predef, Forms),
- ordsets:from_list(Fs).
-
-module_attrs(#expand{attributes=Attributes}=St) ->
- Attrs = [{attribute,Line,Name,Val} || {Name,Line,Val} <- Attributes],
- Callbacks = [Callback || {_,_,callback,_}=Callback <- Attrs],
- OptionalCallbacks = get_optional_callbacks(Attrs),
- {Attrs,St#expand{callbacks=Callbacks,
- optional_callbacks=OptionalCallbacks}}.
-
-get_optional_callbacks(Attrs) ->
- L = [O ||
- {attribute, _, optional_callbacks, O} <- Attrs,
- is_fa_list(O)],
- lists:append(L).
-
-is_fa_list([{FuncName, Arity}|L])
- when is_atom(FuncName), is_integer(Arity), Arity >= 0 ->
- is_fa_list(L);
-is_fa_list([]) -> true;
-is_fa_list(_) -> false.
-
-module_predef_funcs(St0) ->
- {Mpf1,St1} = module_predef_func_beh_info(St0),
- Mpf2 = module_predef_funcs_mod_info(St1),
- Mpf = [erl_parse:new_anno(F) || F <- Mpf1++Mpf2],
- {Mpf,St1}.
-
-module_predef_func_beh_info(#expand{callbacks=[]}=St) ->
- {[], St};
-module_predef_func_beh_info(#expand{callbacks=Callbacks,
- optional_callbacks=OptionalCallbacks,
- exports=Exports}=St) ->
- PreDef0 = [{behaviour_info,1}],
- PreDef = ordsets:from_list(PreDef0),
- {[gen_beh_info(Callbacks, OptionalCallbacks)],
- St#expand{exports=ordsets:union(PreDef, Exports)}}.
-
-gen_beh_info(Callbacks, OptionalCallbacks) ->
- List = make_list(Callbacks),
- OptionalList = make_optional_list(OptionalCallbacks),
- {function,0,behaviour_info,1,
- [{clause,0,[{atom,0,callbacks}],[],
- [List]},
- {clause,0,[{atom,0,optional_callbacks}],[],
- [OptionalList]}]}.
-
-make_list([]) -> {nil,0};
-make_list([{_,_,_,[{{Name,Arity},_}]}|Rest]) ->
- {cons,0,
- {tuple,0,
- [{atom,0,Name},
- {integer,0,Arity}]},
- make_list(Rest)}.
-
-make_optional_list([]) -> {nil,0};
-make_optional_list([{Name,Arity}|Rest]) ->
- {cons,0,
- {tuple,0,
- [{atom,0,Name},
- {integer,0,Arity}]},
- make_optional_list(Rest)}.
-
-module_predef_funcs_mod_info(#expand{module=Mod}) ->
- ModAtom = {atom,0,Mod},
- [{function,0,module_info,0,
- [{clause,0,[],[],
- [{call,0,{remote,0,{atom,0,erlang},{atom,0,get_module_info}},
- [ModAtom]}]}]},
- {function,0,module_info,1,
- [{clause,0,[{var,0,'X'}],[],
- [{call,0,{remote,0,{atom,0,erlang},{atom,0,get_module_info}},
- [ModAtom,{var,0,'X'}]}]}]}].
-
-%% forms(Forms, State) ->
-%% {TransformedForms,State'}
-%% Process the forms. Attributes are lost and just affect the state.
-%% Ignore uninteresting forms like eof and type.
-
-forms([{attribute,_,file,_File}=F|Fs0], St0) ->
- {Fs,St1} = forms(Fs0, St0),
- {[F|Fs],St1};
-forms([{attribute,Line,Name,Val}|Fs0], St0) ->
- St1 = attribute(Name, Val, Line, St0),
- forms(Fs0, St1);
-forms([{function,L,N,A,Cs}|Fs0], St0) ->
- {Ff,St1} = function(L, N, A, Cs, St0),
- {Fs,St2} = forms(Fs0, St1),
- {[Ff|Fs],St2};
-forms([_|Fs], St) -> forms(Fs, St);
-forms([], St) -> {[],St}.
-
-%% attribute(Attribute, Value, Line, State) -> State'.
-%% Process an attribute, this just affects the state.
-
-attribute(module, Module, _L, St) ->
- true = is_atom(Module),
- St#expand{module=Module};
-attribute(export, Es, _L, St) ->
- St#expand{exports=ordsets:union(ordsets:from_list(Es),
- St#expand.exports)};
-attribute(import, Is, _L, St) ->
- import(Is, St);
-attribute(compile, _C, _L, St) ->
- St;
-attribute(Name, Val, Line, St) when is_list(Val) ->
- St#expand{attributes=St#expand.attributes ++ [{Name,Line,Val}]};
-attribute(Name, Val, Line, St) ->
- St#expand{attributes=St#expand.attributes ++ [{Name,Line,[Val]}]}.
-
-function(L, N, A, Cs0, St0) ->
- {Cs,St} = clauses(Cs0, St0#expand{func=N,arity=A,fcount=0}),
- {{function,L,N,A,Cs},St}.
-
-%% clauses([Clause], State) ->
-%% {[TransformedClause],State}.
-%% Expand function clauses.
-
-clauses([{clause,Line,H0,G0,B0}|Cs0], St0) ->
- {H,St1} = head(H0, St0),
- {G,St2} = guard(G0, St1),
- {B,St3} = exprs(B0, St2),
- {Cs,St4} = clauses(Cs0, St3),
- {[{clause,Line,H,G,B}|Cs],St4};
-clauses([], St) -> {[],St}.
-
-%% head(HeadPatterns, State) ->
-%% {TransformedPatterns,Variables,UsedVariables,State'}
-
-head(As, St) -> pattern_list(As, St).
-
-%% pattern(Pattern, State) ->
-%% {TransformedPattern,State'}
-%%
-
-pattern({var,_,_}=Var, St) ->
- {Var,St};
-pattern({char,_,_}=Char, St) ->
- {Char,St};
-pattern({integer,_,_}=Int, St) ->
- {Int,St};
-pattern({float,_,_}=Float, St) ->
- {Float,St};
-pattern({atom,_,_}=Atom, St) ->
- {Atom,St};
-pattern({string,_,_}=String, St) ->
- {String,St};
-pattern({nil,_}=Nil, St) ->
- {Nil,St};
-pattern({cons,Line,H,T}, St0) ->
- {TH,St1} = pattern(H, St0),
- {TT,St2} = pattern(T, St1),
- {{cons,Line,TH,TT},St2};
-pattern({tuple,Line,Ps}, St0) ->
- {TPs,St1} = pattern_list(Ps, St0),
- {{tuple,Line,TPs},St1};
-pattern({map,Line,Ps}, St0) ->
- {TPs,St1} = pattern_list(Ps, St0),
- {{map,Line,TPs},St1};
-pattern({map_field_exact,Line,K0,V0}, St0) ->
- %% Key should be treated as an expression
- %% but since expressions are not allowed yet,
- %% process it through pattern .. and handle assoc
- %% (normalise unary op integer -> integer)
- {K,St1} = pattern(K0, St0),
- {V,St2} = pattern(V0, St1),
- {{map_field_exact,Line,K,V},St2};
-pattern({map_field_assoc,Line,K0,V0}, St0) ->
- %% when keys are Maps
- {K,St1} = pattern(K0, St0),
- {V,St2} = pattern(V0, St1),
- {{map_field_assoc,Line,K,V},St2};
-%%pattern({struct,Line,Tag,Ps}, St0) ->
-%% {TPs,TPsvs,St1} = pattern_list(Ps, St0),
-%% {{tuple,Line,[{atom,Line,Tag}|TPs]},TPsvs,St1};
-pattern({bin,Line,Es0}, St0) ->
- {Es1,St1} = pattern_bin(Es0, St0),
- {{bin,Line,Es1},St1};
-pattern({op,_,'++',{nil,_},R}, St) ->
- pattern(R, St);
-pattern({op,_,'++',{cons,Li,H,T},R}, St) ->
- pattern({cons,Li,H,{op,Li,'++',T,R}}, St);
-pattern({op,_,'++',{string,Li,L},R}, St) ->
- pattern(string_to_conses(Li, L, R), St);
-pattern({match,Line,Pat1, Pat2}, St0) ->
- {TH,St1} = pattern(Pat2, St0),
- {TT,St2} = pattern(Pat1, St1),
- {{match,Line,TT,TH},St2};
-%% Compile-time pattern expressions, including unary operators.
-pattern({op,_Line,_Op,_A}=Op, St) ->
- {erl_eval:partial_eval(Op),St};
-pattern({op,_Line,_Op,_L,_R}=Op, St) ->
- {erl_eval:partial_eval(Op),St}.
-
-pattern_list([P0|Ps0], St0) ->
- {P,St1} = pattern(P0, St0),
- {Ps,St2} = pattern_list(Ps0, St1),
- {[P|Ps],St2};
-pattern_list([], St) -> {[],St}.
-
-%% guard(Guard, State) ->
-%% {TransformedGuard,State'}
-%% Transform a list of guard tests. We KNOW that this has been checked
-%% and what the guards test are. Use expr for transforming the guard
-%% expressions.
-
-guard([G0|Gs0], St0) ->
- {G,St1} = guard_tests(G0, St0),
- {Gs,St2} = guard(Gs0, St1),
- {[G|Gs],St2};
-guard([], St) -> {[],St}.
-
-guard_tests([Gt0|Gts0], St0) ->
- {Gt1,St1} = guard_test(Gt0, St0),
- {Gts1,St2} = guard_tests(Gts0, St1),
- {[Gt1|Gts1],St2};
-guard_tests([], St) -> {[],St}.
-
-guard_test(Test, St) ->
- expr(Test, St).
-
-%% exprs(Expressions, State) ->
-%% {TransformedExprs,State'}
-
-exprs([E0|Es0], St0) ->
- {E,St1} = expr(E0, St0),
- {Es,St2} = exprs(Es0, St1),
- {[E|Es],St2};
-exprs([], St) -> {[],St}.
-
-%% expr(Expression, State) ->
-%% {TransformedExpression,State'}
-
-expr({var,_,_}=Var, St) ->
- {Var,St};
-expr({char,_,_}=Char, St) ->
- {Char,St};
-expr({integer,_,_}=Int, St) ->
- {Int,St};
-expr({float,_,_}=Float, St) ->
- {Float,St};
-expr({atom,_,_}=Atom, St) ->
- {Atom,St};
-expr({string,_,_}=String, St) ->
- {String,St};
-expr({nil,_}=Nil, St) ->
- {Nil,St};
-expr({cons,Line,H0,T0}, St0) ->
- {H,St1} = expr(H0, St0),
- {T,St2} = expr(T0, St1),
- {{cons,Line,H,T},St2};
-expr({lc,Line,E0,Qs0}, St0) ->
- {Qs1,St1} = lc_tq(Line, Qs0, St0),
- {E1,St2} = expr(E0, St1),
- {{lc,Line,E1,Qs1},St2};
-expr({bc,Line,E0,Qs0}, St0) ->
- {Qs1,St1} = lc_tq(Line, Qs0, St0),
- {E1,St2} = expr(E0, St1),
- {{bc,Line,E1,Qs1},St2};
-expr({tuple,Line,Es0}, St0) ->
- {Es1,St1} = expr_list(Es0, St0),
- {{tuple,Line,Es1},St1};
-%%expr({struct,Line,Tag,Es0}, Vs, St0) ->
-%% {Es1,Esvs,Esus,St1} = expr_list(Es0, Vs, St0),
-%% {{tuple,Line,[{atom,Line,Tag}|Es1]},Esvs,Esus,St1};
-expr({map,Line,Es0}, St0) ->
- {Es1,St1} = expr_list(Es0, St0),
- {{map,Line,Es1},St1};
-expr({map,Line,E0,Es0}, St0) ->
- {E1,St1} = expr(E0, St0),
- {Es1,St2} = expr_list(Es0, St1),
- {{map,Line,E1,Es1},St2};
-expr({map_field_assoc,Line,K0,V0}, St0) ->
- {K,St1} = expr(K0, St0),
- {V,St2} = expr(V0, St1),
- {{map_field_assoc,Line,K,V},St2};
-expr({map_field_exact,Line,K0,V0}, St0) ->
- {K,St1} = expr(K0, St0),
- {V,St2} = expr(V0, St1),
- {{map_field_exact,Line,K,V},St2};
-expr({bin,Line,Es0}, St0) ->
- {Es1,St1} = expr_bin(Es0, St0),
- {{bin,Line,Es1},St1};
-expr({block,Line,Es0}, St0) ->
- {Es,St1} = exprs(Es0, St0),
- {{block,Line,Es},St1};
-expr({'if',Line,Cs0}, St0) ->
- {Cs,St1} = clauses(Cs0, St0),
- {{'if',Line,Cs},St1};
-expr({'case',Line,E0,Cs0}, St0) ->
- {E,St1} = expr(E0, St0),
- {Cs,St2} = clauses(Cs0, St1),
- {{'case',Line,E,Cs},St2};
-expr({'receive',Line,Cs0}, St0) ->
- {Cs,St1} = clauses(Cs0, St0),
- {{'receive',Line,Cs},St1};
-expr({'receive',Line,Cs0,To0,ToEs0}, St0) ->
- {To,St1} = expr(To0, St0),
- {ToEs,St2} = exprs(ToEs0, St1),
- {Cs,St3} = clauses(Cs0, St2),
- {{'receive',Line,Cs,To,ToEs},St3};
-expr({'fun',Line,Body}, St) ->
- fun_tq(Line, Body, St);
-expr({named_fun,Line,Name,Cs}, St) ->
- fun_tq(Line, Cs, St, Name);
-expr({call,Line,{atom,La,N}=Atom,As0}, St0) ->
- {As,St1} = expr_list(As0, St0),
- Ar = length(As),
- Key = {N,Ar},
- case St1#expand.ctype of
- #{Key:=local} ->
- {{call,Line,Atom,As},St1};
- #{Key:={imported,Mod}} ->
- {{call,Line,{remote,La,{atom,La,Mod},Atom},As},St1};
- _ ->
- true = erl_internal:bif(N, Ar),
- {{call,Line,{remote,La,{atom,La,erlang},Atom},As},St1}
- end;
-expr({call,Line,{remote,Lr,M0,F},As0}, St0) ->
- {[M1,F1|As1],St1} = expr_list([M0,F|As0], St0),
- {{call,Line,{remote,Lr,M1,F1},As1},St1};
-expr({call,Line,F,As0}, St0) ->
- {[Fun1|As1],St1} = expr_list([F|As0], St0),
- {{call,Line,Fun1,As1},St1};
-expr({'try',Line,Es0,Scs0,Ccs0,As0}, St0) ->
- {Es1,St1} = exprs(Es0, St0),
- {Scs1,St2} = clauses(Scs0, St1),
- {Ccs1,St3} = clauses(Ccs0, St2),
- {As1,St4} = exprs(As0, St3),
- {{'try',Line,Es1,Scs1,Ccs1,As1},St4};
-expr({'catch',Line,E0}, St0) ->
- {E,St1} = expr(E0, St0),
- {{'catch',Line,E},St1};
-expr({match,Line,P0,E0}, St0) ->
- {E,St1} = expr(E0, St0),
- {P,St2} = pattern(P0, St1),
- {{match,Line,P,E},St2};
-expr({op,Line,Op,A0}, St0) ->
- {A,St1} = expr(A0, St0),
- {{op,Line,Op,A},St1};
-expr({op,Line,Op,L0,R0}, St0) ->
- {L,St1} = expr(L0, St0),
- {R,St2} = expr(R0, St1),
- {{op,Line,Op,L,R},St2}.
-
-expr_list([E0|Es0], St0) ->
- {E,St1} = expr(E0, St0),
- {Es,St2} = expr_list(Es0, St1),
- {[E|Es],St2};
-expr_list([], St) -> {[],St}.
-
-%% lc_tq(Line, Qualifiers, State) ->
-%% {[TransQual],State'}
-
-lc_tq(Line, [{generate,Lg,P0,G0} | Qs0], St0) ->
- {G1,St1} = expr(G0, St0),
- {P1,St2} = pattern(P0, St1),
- {Qs1,St3} = lc_tq(Line, Qs0, St2),
- {[{generate,Lg,P1,G1} | Qs1],St3};
-
-lc_tq(Line, [{b_generate,Lg,P0,G0}|Qs0], St0) ->
- {G1,St1} = expr(G0, St0),
- {P1,St2} = pattern(P0, St1),
- {Qs1,St3} = lc_tq(Line, Qs0, St2),
- {[{b_generate,Lg,P1,G1}|Qs1],St3};
-lc_tq(Line, [F0 | Qs0], St0) ->
- {F1,St1} = expr(F0, St0),
- {Qs1,St2} = lc_tq(Line, Qs0, St1),
- {[F1|Qs1],St2};
-lc_tq(_Line, [], St0) ->
- {[],St0}.
-
-
-%% fun_tq(Line, Body, State) ->
-%% {Fun,State'}
-%% Transform an "explicit" fun {'fun', Line, {clauses, Cs}} into an
-%% extended form {'fun', Line, {clauses, Cs}, Info}, unless it is the
-%% name of a BIF (erl_lint has checked that it is not an import).
-%% "Implicit" funs {'fun', Line, {function, F, A}} are not changed.
-
-fun_tq(Lf, {function,F,A}=Function, St0) ->
- case erl_internal:bif(F, A) of
- true ->
- {As,St1} = new_vars(A, Lf, St0),
- Cs = [{clause,Lf,As,[],[{call,Lf,{atom,Lf,F},As}]}],
- fun_tq(Lf, {clauses,Cs}, St1);
- false ->
- {Fname,St1} = new_fun_name(St0),
- Index = Uniq = 0,
- {{'fun',Lf,Function,{Index,Uniq,Fname}},St1}
- end;
-fun_tq(L, {function,M,F,A}, St) when is_atom(M), is_atom(F), is_integer(A) ->
- %% This is the old format for external funs, generated by a pre-R15
- %% compiler. That means that a tool, such as the debugger or xref,
- %% directly invoked this module with the abstract code from a
- %% pre-R15 BEAM file. Be helpful, and translate it to the new format.
- fun_tq(L, {function,{atom,L,M},{atom,L,F},{integer,L,A}}, St);
-fun_tq(Lf, {function,_,_,_}=ExtFun, St) ->
- {{'fun',Lf,ExtFun},St};
-fun_tq(Lf, {clauses,Cs0}, St0) ->
- {Cs1,St1} = clauses(Cs0, St0),
- {Fname,St2} = new_fun_name(St1),
- %% Set dummy values for Index and Uniq -- the real values will
- %% be assigned by beam_asm.
- Index = Uniq = 0,
- {{'fun',Lf,{clauses,Cs1},{Index,Uniq,Fname}},St2}.
-
-fun_tq(Line, Cs0, St0, Name) ->
- {Cs1,St1} = clauses(Cs0, St0),
- {Fname,St2} = new_fun_name(St1, Name),
- {{named_fun,Line,Name,Cs1,{0,0,Fname}},St2}.
-
-%% new_fun_name(State) -> {FunName,State}.
-
-new_fun_name(St) ->
- new_fun_name(St, 'fun').
-
-new_fun_name(#expand{func=F,arity=A,fcount=I}=St, FName) ->
- Name = "-" ++ atom_to_list(F) ++ "/" ++ integer_to_list(A)
- ++ "-" ++ atom_to_list(FName) ++ "-" ++ integer_to_list(I) ++ "-",
- {list_to_atom(Name),St#expand{fcount=I+1}}.
-
-%% pattern_bin([Element], State) -> {[Element],[Variable],[UsedVar],State}.
-
-pattern_bin(Es0, St) ->
- Es1 = bin_expand_strings(Es0),
- foldr(fun (E, Acc) -> pattern_element(E, Acc) end, {[],St}, Es1).
-
-pattern_element({bin_element,Line,Expr0,Size0,Type0}, {Es,St0}) ->
- {Expr1,St1} = pattern(Expr0, St0),
- {Size1,St2} = pat_bit_size(Size0, St1),
- {Size,Type} = make_bit_type(Line, Size1, Type0),
- Expr = coerce_to_float(Expr1, Type0),
- {[{bin_element,Line,Expr,Size,Type}|Es],St2}.
-
-pat_bit_size(default, St) -> {default,St};
-pat_bit_size({var,_Lv,_V}=Var, St) -> {Var,St};
-pat_bit_size(Size, St) ->
- Line = element(2, Size),
- {value,Sz,_} = erl_eval:expr(Size, erl_eval:new_bindings()),
- {{integer,Line,Sz},St}.
-
-make_bit_type(Line, default, Type0) ->
- case erl_bits:set_bit_type(default, Type0) of
- {ok,all,Bt} -> {{atom,Line,all},erl_bits:as_list(Bt)};
- {ok,undefined,Bt} -> {{atom,Line,undefined},erl_bits:as_list(Bt)};
- {ok,Size,Bt} -> {{integer,Line,Size},erl_bits:as_list(Bt)}
- end;
-make_bit_type(_Line, Size, Type0) -> %Integer or 'all'
- {ok,Size,Bt} = erl_bits:set_bit_type(Size, Type0),
- {Size,erl_bits:as_list(Bt)}.
-
-coerce_to_float({integer,L,I}=E, [float|_]) ->
- try
- {float,L,float(I)}
- catch
- error:badarg -> E
- end;
-coerce_to_float(E, _) -> E.
-
-%% expr_bin([Element], State) -> {[Element],State}.
-
-expr_bin(Es0, St) ->
- Es1 = bin_expand_strings(Es0),
- foldr(fun (E, Acc) -> bin_element(E, Acc) end, {[],St}, Es1).
-
-bin_element({bin_element,Line,Expr,Size,Type}, {Es,St0}) ->
- {Expr1,St1} = expr(Expr, St0),
- {Size1,St2} = if Size == default -> {default,St1};
- true -> expr(Size, St1)
- end,
- {Size2,Type1} = make_bit_type(Line, Size1, Type),
- {[{bin_element,Line,Expr1,Size2,Type1}|Es],St2}.
-
-bin_expand_strings(Es) ->
- foldr(fun ({bin_element,Line,{string,_,S},Sz,Ts}, Es1) ->
- foldr(fun (C, Es2) ->
- [{bin_element,Line,{char,Line,C},Sz,Ts}|Es2]
- end, Es1, S);
- (E, Es1) -> [E|Es1]
- end, [], Es).
-
-%% new_var_name(State) -> {VarName,State}.
-
-new_var_name(St) ->
- C = St#expand.vcount,
- {list_to_atom("pre" ++ integer_to_list(C)),St#expand{vcount=C+1}}.
-
-%% new_var(Line, State) -> {Var,State}.
-
-new_var(L, St0) ->
- {New,St1} = new_var_name(St0),
- {{var,L,New},St1}.
-
-%% new_vars(Count, Line, State) -> {[Var],State}.
-%% Make Count new variables.
-
-new_vars(N, L, St) -> new_vars(N, L, St, []).
-
-new_vars(N, L, St0, Vs) when N > 0 ->
- {V,St1} = new_var(L, St0),
- new_vars(N-1, L, St1, [V|Vs]);
-new_vars(0, _L, St, Vs) -> {Vs,St}.
-
-string_to_conses(Line, Cs, Tail) ->
- foldr(fun (C, T) -> {cons,Line,{char,Line,C},T} end, Tail, Cs).
-
-
-%% import(Line, Imports, State) ->
-%% State'
-%% Handle import declarations.
-
-import({Mod,Fs}, #expand{ctype=Ctype0}=St) ->
- true = is_atom(Mod),
- Ctype = foldl(fun(F, A) ->
- A#{F=>{imported,Mod}}
- end, Ctype0, Fs),
- St#expand{ctype=Ctype}.
diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl
index 4df1aadd0a..47c1567f10 100644
--- a/lib/compiler/src/v3_codegen.erl
+++ b/lib/compiler/src/v3_codegen.erl
@@ -69,6 +69,10 @@
stk=[], %Stack table
res=[]}). %Reserved regs: [{reserved,I,V}]
+-type life_module() :: {module(),_,_,[_]}.
+
+-spec module(life_module(), [compile:option()]) -> {'ok',beam_asm:module_code()}.
+
module({Mod,Exp,Attr,Forms}, _Options) ->
{Fs,St} = functions(Forms, {atom,Mod}),
{ok,{Mod,Exp,Attr,Fs,St#cg.lcount}}.
@@ -151,6 +155,8 @@ cg({bif,Bif,As,Rs}, Le, Vdb, Bef, St) ->
bif_cg(Bif, As, Rs, Le, Vdb, Bef, St);
cg({gc_bif,Bif,As,Rs}, Le, Vdb, Bef, St) ->
gc_bif_cg(Bif, As, Rs, Le, Vdb, Bef, St);
+cg({internal,Bif,As,Rs}, Le, Vdb, Bef, St) ->
+ internal_cg(Bif, As, Rs, Le, Vdb, Bef, St);
cg({receive_loop,Te,Rvar,Rm,Tes,Rs}, Le, Vdb, Bef, St) ->
recv_loop_cg(Te, Rvar, Rm, Tes, Rs, Le, Vdb, Bef, St);
cg(receive_next, Le, Vdb, Bef, St) ->
@@ -208,15 +214,10 @@ need_heap_1(#l{ke={set,_,Val}}, H) ->
{tuple,Es} -> 1 + length(Es);
_Other -> 0
end};
-need_heap_1(#l{ke={bif,dsetelement,_As,_Rs},i=I}, H) ->
- {need_heap_need(I, H),0};
-need_heap_1(#l{ke={bif,{make_fun,_,_,_,_},_As,_Rs},i=I}, H) ->
- {need_heap_need(I, H),0};
-need_heap_1(#l{ke={bif,bs_init_writable,_As,_Rs},i=I}, H) ->
- {need_heap_need(I, H),0};
need_heap_1(#l{ke={bif,_Bif,_As,_Rs}}, H) ->
{[],H};
need_heap_1(#l{i=I}, H) ->
+ %% Call or call-like instruction such as set_tuple_element/3.
{need_heap_need(I, H),0}.
need_heap_need(_I, 0) -> [];
@@ -366,7 +367,7 @@ bsm_rename_ctx(#l{ke={match,Ms0,Rs}}=L, Old, New, InProt) ->
bsm_rename_ctx(#l{ke={guard_match,Ms0,Rs}}=L, Old, New, InProt) ->
Ms = bsm_rename_ctx(Ms0, Old, New, InProt),
L#l{ke={guard_match,Ms,Rs}};
-bsm_rename_ctx(#l{ke={test,_,_}}=L, _, _, _) -> L;
+bsm_rename_ctx(#l{ke={test,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={bif,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={gc_bif,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={set,_,_}}=L, _, _, _) -> L;
@@ -1054,8 +1055,15 @@ guard_cg(#l{ke={protected,Ts,Rs},i=I,vdb=Pdb}, Fail, _Vdb, Bef, St) ->
protected_cg(Ts, Rs, Fail, I, Pdb, Bef, St);
guard_cg(#l{ke={block,Ts},i=I,vdb=Bdb}, Fail, _Vdb, Bef, St) ->
guard_cg_list(Ts, Fail, I, Bdb, Bef, St);
-guard_cg(#l{ke={test,Test,As},i=I,vdb=_Tdb}, Fail, Vdb, Bef, St) ->
- test_cg(Test, As, Fail, I, Vdb, Bef, St);
+guard_cg(#l{ke={test,Test,As,Inverted},i=I,vdb=_Tdb}, Fail, Vdb, Bef, St0) ->
+ case Inverted of
+ false ->
+ test_cg(Test, As, Fail, I, Vdb, Bef, St0);
+ true ->
+ {Psucc,St1} = new_label(St0),
+ {Is,Aft,St2} = test_cg(Test, As, Psucc, I, Vdb, Bef, St1),
+ {Is++[{jump,{f,Fail}},{label,Psucc}],Aft,St2}
+ end;
guard_cg(G, _Fail, Vdb, Bef, St) ->
%%ok = io:fwrite("cg ~w: ~p~n", [?LINE,{G,Fail,Vdb,Bef}]),
{Gis,Aft,St1} = cg(G, Vdb, Bef, St),
@@ -1106,6 +1114,13 @@ test_cg(is_map, [A], Fail, I, Vdb, Bef, St) ->
Arg = cg_reg_arg_prefer_y(A, Bef),
Aft = clear_dead(Bef, I, Vdb),
{[{test,is_map,{f,Fail},[Arg]}],Aft,St};
+test_cg(is_boolean, [{atom,Val}], Fail, I, Vdb, Bef, St) ->
+ Aft = clear_dead(Bef, I, Vdb),
+ Is = case is_boolean(Val) of
+ true -> [];
+ false -> [{jump,{f,Fail}}]
+ end,
+ {Is,Aft,St};
test_cg(Test, As, Fail, I, Vdb, Bef, St) ->
Args = cg_reg_args(As, Bef),
Aft = clear_dead(Bef, I, Vdb),
@@ -1301,10 +1316,10 @@ trap_bif(erlang, group_leader, 2) -> true;
trap_bif(erlang, exit, 2) -> true;
trap_bif(_, _, _) -> false.
-%% bif_cg(Bif, [Arg], [Ret], Le, Vdb, StackReg, State) ->
+%% internal_cg(Bif, [Arg], [Ret], Le, Vdb, StackReg, State) ->
%% {[Ainstr],StackReg,State}.
-bif_cg(bs_context_to_binary=Instr, [Src0], [], Le, Vdb, Bef, St0) ->
+internal_cg(bs_context_to_binary=Instr, [Src0], [], Le, Vdb, Bef, St0) ->
[Src] = cg_reg_args([Src0], Bef),
case is_register(Src) of
false ->
@@ -1312,25 +1327,34 @@ bif_cg(bs_context_to_binary=Instr, [Src0], [], Le, Vdb, Bef, St0) ->
true ->
{[{Instr,Src}],clear_dead(Bef, Le#l.i, Vdb), St0}
end;
-bif_cg(dsetelement, [Index0,Tuple0,New0], _Rs, Le, Vdb, Bef, St0) ->
+internal_cg(dsetelement, [Index0,Tuple0,New0], _Rs, Le, Vdb, Bef, St0) ->
[New,Tuple,{integer,Index1}] = cg_reg_args([New0,Tuple0,Index0], Bef),
Index = Index1-1,
{[{set_tuple_element,New,Tuple,Index}],
clear_dead(Bef, Le#l.i, Vdb), St0};
-bif_cg({make_fun,Func,Arity,Index,Uniq}, As, Rs, Le, Vdb, Bef, St0) ->
+internal_cg(make_fun, [Func0,Arity0|As], Rs, Le, Vdb, Bef, St0) ->
%% This behaves more like a function call.
+ {atom,Func} = Func0,
+ {integer,Arity} = Arity0,
{Sis,Int} = cg_setup_call(As, Bef, Le#l.i, Vdb),
Reg = load_vars(Rs, clear_regs(Int#sr.reg)),
{FuncLbl,St1} = local_func_label(Func, Arity, St0),
- MakeFun = {make_fun2,{f,FuncLbl},Index,Uniq,length(As)},
+ MakeFun = {make_fun2,{f,FuncLbl},0,0,length(As)},
{Sis ++ [MakeFun],
clear_dead(Int#sr{reg=Reg}, Le#l.i, Vdb),
St1};
-bif_cg(bs_init_writable=I, As, Rs, Le, Vdb, Bef, St) ->
+internal_cg(bs_init_writable=I, As, Rs, Le, Vdb, Bef, St) ->
%% This behaves like a function call.
{Sis,Int} = cg_setup_call(As, Bef, Le#l.i, Vdb),
Reg = load_vars(Rs, clear_regs(Int#sr.reg)),
{Sis++[I],clear_dead(Int#sr{reg=Reg}, Le#l.i, Vdb),St};
+internal_cg(raise, As, Rs, Le, Vdb, Bef, St) ->
+ %% raise can be treated like a guard BIF.
+ bif_cg(raise, As, Rs, Le, Vdb, Bef, St).
+
+%% bif_cg(Bif, [Arg], [Ret], Le, Vdb, StackReg, State) ->
+%% {[Ainstr],StackReg,State}.
+
bif_cg(Bif, As, [{var,V}], Le, Vdb, Bef, St0) ->
Ars = cg_reg_args(As, Bef),
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index d71411de80..ae650546e5 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -137,11 +137,13 @@
-record(core, {vcount=0 :: non_neg_integer(), %Variable counter
fcount=0 :: non_neg_integer(), %Function counter
+ function={none,0} :: fa(), %Current function.
in_guard=false :: boolean(), %In guard or not.
wanted=true :: boolean(), %Result wanted or not.
opts :: [compile:option()], %Options.
ws=[] :: [warning()], %Warnings.
- file=[{file,""}]}). %File
+ file=[{file,""}] %File.
+ }).
%% XXX: The following type declarations do not belong in this module
-type fa() :: {atom(), arity()}.
@@ -149,38 +151,73 @@
-type form() :: {function, integer(), atom(), arity(), _}
| {attribute, integer(), attribute(), _}.
--spec module({module(), [fa()], [form()]}, [compile:option()]) ->
+-record(imodule, {name = [],
+ exports = ordsets:new(),
+ attrs = [],
+ defs = [],
+ file = [],
+ opts = [],
+ ws = []}).
+
+-spec module([form()], [compile:option()]) ->
{'ok',cerl:c_module(),[warning()]}.
-module({Mod,Exp,Forms}, Opts) ->
- Cexp = map(fun ({_N,_A} = NA) -> #c_var{name=NA} end, Exp),
- {Kfs0,As0,Ws,_File} = foldl(fun (F, Acc) ->
- form(F, Acc, Opts)
- end, {[],[],[],[]}, Forms),
- Kfs = reverse(Kfs0),
+module(Forms0, Opts) ->
+ Forms = erl_internal:add_predefined_functions(Forms0),
+ Module = foldl(fun (F, Acc) ->
+ form(F, Acc, Opts)
+ end, #imodule{}, Forms),
+ #imodule{name=Mod,exports=Exp0,attrs=As0,defs=Kfs0,ws=Ws} = Module,
+ Exp = case member(export_all, Opts) of
+ true -> defined_functions(Forms);
+ false -> Exp0
+ end,
+ Cexp = [#c_var{name=FA} || {_,_}=FA <- Exp],
As = reverse(As0),
+ Kfs = reverse(Kfs0),
{ok,#c_module{name=#c_literal{val=Mod},exports=Cexp,attrs=As,defs=Kfs},Ws}.
-form({function,_,_,_,_}=F0, {Fs,As,Ws0,File}, Opts) ->
+form({function,_,_,_,_}=F0, Module, Opts) ->
+ #imodule{file=File,defs=Defs,ws=Ws0} = Module,
{F,Ws} = function(F0, Ws0, File, Opts),
- {[F|Fs],As,Ws,File};
-form({attribute,_,file,{File,_Line}}, {Fs,As,Ws,_}, _Opts) ->
- {Fs,As,Ws,File};
-form({attribute,_,_,_}=F, {Fs,As,Ws,File}, _Opts) ->
- {Fs,[attribute(F)|As],Ws,File}.
-
-attribute(Attribute) ->
- Fun = fun(A) -> [erl_anno:location(A)] end,
- {attribute,Line,Name,Val} = erl_parse:map_anno(Fun, Attribute),
+ Module#imodule{defs=[F|Defs],ws=Ws};
+form({attribute,_,module,Mod}, Module, _Opts) ->
+ true = is_atom(Mod),
+ Module#imodule{name=Mod};
+form({attribute,_,file,{File,_Line}}=F, #imodule{attrs=As}=Module, _Opts) ->
+ Module#imodule{file=File, attrs=[attribute(F)|As]};
+form({attribute,_,import,_}, Module, _Opts) ->
+ %% Ignore. We have no futher use for imports.
+ Module;
+form({attribute,_,export,Es}, #imodule{exports=Exp0}=Module, _Opts) ->
+ Exp = ordsets:union(ordsets:from_list(Es), Exp0),
+ Module#imodule{exports=Exp};
+form({attribute,_,_,_}=F, #imodule{attrs=As}=Module, _Opts) ->
+ Module#imodule{attrs=[attribute(F)|As]};
+form(_, Module, _Opts) ->
+ %% Ignore uninteresting forms such as 'eof'.
+ Module.
+
+attribute({attribute,A,Name,Val0}) ->
+ Line = [erl_anno:location(A)],
+ Val = if
+ is_list(Val0) -> Val0;
+ true -> [Val0]
+ end,
{#c_literal{val=Name, anno=Line}, #c_literal{val=Val, anno=Line}}.
+defined_functions(Forms) ->
+ Fs = [{Name,Arity} || {function,_,Name,Arity,_} <- Forms],
+ ordsets:from_list(Fs).
+
%% function_dump(module_info,_,_,_) -> ok;
%% function_dump(Name,Arity,Format,Terms) ->
%% io:format("~w/~w " ++ Format,[Name,Arity]++Terms),
%% ok.
function({function,_,Name,Arity,Cs0}, Ws0, File, Opts) ->
- St0 = #core{vcount=0,opts=Opts,ws=Ws0,file=[{file,File}]},
+ St0 = #core{vcount=0,function={Name,Arity},opts=Opts,
+ ws=Ws0,file=[{file,File}]},
{B0,St1} = body(Cs0, Name, Arity, St0),
%% ok = function_dump(Name,Arity,"body:~n~p~n",[B0]),
{B1,St2} = ubody(B0, St1),
@@ -632,9 +669,11 @@ expr({'catch',L,E0}, St0) ->
{E1,Eps,St1} = expr(E0, St0),
Lanno = lineno_anno(L, St1),
{#icatch{anno=#a{anno=Lanno},body=Eps ++ [E1]},[],St1};
-expr({'fun',L,{function,F,A},{_,_,_}=Id}, St) ->
- Lanno = full_anno(L, St),
- {#c_var{anno=Lanno++[{id,Id}],name={F,A}},[],St};
+expr({'fun',L,{function,F,A}}, St0) ->
+ {Fname,St1} = new_fun_name(St0),
+ Lanno = full_anno(L, St1),
+ Id = {0,0,Fname},
+ {#c_var{anno=Lanno++[{id,Id}],name={F,A}},[],St1};
expr({'fun',L,{function,M,F,A}}, St0) ->
{As,Aps,St1} = safe_list([M,F,A], St0),
Lanno = full_anno(L, St1),
@@ -642,12 +681,12 @@ expr({'fun',L,{function,M,F,A}}, St0) ->
module=#c_literal{val=erlang},
name=#c_literal{val=make_fun},
args=As},Aps,St1};
-expr({'fun',L,{clauses,Cs},Id}, St) ->
- fun_tq(Id, Cs, L, St, unnamed);
-expr({named_fun,L,'_',Cs,Id}, St) ->
- fun_tq(Id, Cs, L, St, unnamed);
-expr({named_fun,L,Name,Cs,Id}, St) ->
- fun_tq(Id, Cs, L, St, {named,Name});
+expr({'fun',L,{clauses,Cs}}, St) ->
+ fun_tq(Cs, L, St, unnamed);
+expr({named_fun,L,'_',Cs}, St) ->
+ fun_tq(Cs, L, St, unnamed);
+expr({named_fun,L,Name,Cs}, St) ->
+ fun_tq(Cs, L, St, {named,Name});
expr({call,L,{remote,_,M,F},As0}, St0) ->
{[M1,F1|As1],Aps,St1} = safe_list([M,F|As0], St0),
Anno = full_anno(L, St1),
@@ -840,19 +879,33 @@ badmap_term(Map, #core{in_guard=false}) ->
c_tuple([#c_literal{val=badmap},Map]).
map_build_pairs(Map, Es0, Ann, St0) ->
- {Es,Pre,St1} = map_build_pairs_1(Es0, St0),
+ {Es,Pre,_,St1} = map_build_pairs_1(Es0, cerl_sets:new(), St0),
{ann_c_map(Ann, Map, Es),Pre,St1}.
-map_build_pairs_1([{Op0,L,K0,V0}|Es], St0) ->
+map_build_pairs_1([{Op0,L,K0,V0}|Es], Used0, St0) ->
{K,Pre0,St1} = safe(K0, St0),
{V,Pre1,St2} = safe(V0, St1),
- {Pairs,Pre2,St3} = map_build_pairs_1(Es, St2),
+ {Pairs,Pre2,Used1,St3} = map_build_pairs_1(Es, Used0, St2),
As = lineno_anno(L, St3),
Op = map_op(Op0),
+ {Used2,St4} = maybe_warn_repeated_keys(K, L, Used1, St3),
Pair = cerl:ann_c_map_pair(As, Op, K, V),
- {[Pair|Pairs],Pre0++Pre1++Pre2,St3};
-map_build_pairs_1([], St) ->
- {[],[],St}.
+ {[Pair|Pairs],Pre0++Pre1++Pre2,Used2,St4};
+map_build_pairs_1([], Used, St) ->
+ {[],[],Used,St}.
+
+maybe_warn_repeated_keys(Ck,Line,Used,St) ->
+ case cerl:is_literal(Ck) of
+ false -> {Used,St};
+ true ->
+ K = cerl:concrete(Ck),
+ case cerl_sets:is_element(K,Used) of
+ true ->
+ {Used, add_warning(Line, {map_key_repeated,K}, St)};
+ false ->
+ {cerl_sets:add_element(K,Used), St}
+ end
+ end.
map_op(map_field_assoc) -> #c_literal{val=assoc};
map_op(map_field_exact) -> #c_literal{val=exact}.
@@ -899,14 +952,29 @@ try_after(As, St0) ->
%% record whereas c_literal should not have a wrapped annotation
expr_bin(Es0, Anno, St0) ->
- case constant_bin(Es0) of
+ Es1 = [bin_element(E) || E <- Es0],
+ case constant_bin(Es1) of
error ->
- {Es,Eps,St} = expr_bin_1(Es0, St0),
+ {Es,Eps,St} = expr_bin_1(bin_expand_strings(Es1), St0),
{#ibinary{anno=#a{anno=Anno},segments=Es},Eps,St};
Bin ->
{#c_literal{anno=Anno,val=Bin},[],St0}
end.
+bin_element({bin_element,Line,Expr,Size0,Type0}) ->
+ {Size,Type} = make_bit_type(Line, Size0, Type0),
+ {bin_element,Line,Expr,Size,Type}.
+
+make_bit_type(Line, default, Type0) ->
+ case erl_bits:set_bit_type(default, Type0) of
+ {ok,all,Bt} -> {{atom,Line,all},erl_bits:as_list(Bt)};
+ {ok,undefined,Bt} -> {{atom,Line,undefined},erl_bits:as_list(Bt)};
+ {ok,Size,Bt} -> {{integer,Line,Size},erl_bits:as_list(Bt)}
+ end;
+make_bit_type(_Line, Size, Type0) -> %Integer or 'all'
+ {ok,Size,Bt} = erl_bits:set_bit_type(Size, Type0),
+ {Size,erl_bits:as_list(Bt)}.
+
%% constant_bin([{bin_element,_,_,_,_}]) -> binary() | error
%% If the binary construction is truly constant (no variables,
%% no native fields), and does not contain fields whose expansion
@@ -923,7 +991,8 @@ constant_bin(Es) ->
constant_bin_1(Es) ->
verify_suitable_fields(Es),
EmptyBindings = erl_eval:new_bindings(),
- EvalFun = fun({integer,_,I}, B) -> {value,I,B};
+ EvalFun = fun({string,_,S}, B) -> {value,S,B};
+ ({integer,_,I}, B) -> {value,I,B};
({char,_,C}, B) -> {value,C,B};
({float,_,F}, B) -> {value,F,B};
({atom,_,undefined}, B) -> {value,undefined,B}
@@ -944,6 +1013,9 @@ verify_suitable_fields([{bin_element,_,Val,SzTerm,Opts}|Es]) ->
end,
{unit,Unit} = keyfind(unit, 1, Opts),
case {SzTerm,Val} of
+ {{atom,_,undefined},{string,_,_}} ->
+ %% UTF-8/16/32.
+ ok;
{{atom,_,undefined},{char,_,_}} ->
%% UTF-8/16/32.
ok;
@@ -983,6 +1055,31 @@ count_bits(Int) ->
count_bits_1(0, Bits) -> Bits;
count_bits_1(Int, Bits) -> count_bits_1(Int bsr 64, Bits+64).
+bin_expand_strings(Es0) ->
+ foldr(fun ({bin_element,Line,{string,_,S},{integer,_,8},_}, Es) ->
+ bin_expand_string(S, Line, 0, 0) ++ Es;
+ ({bin_element,Line,{string,_,S},Sz,Ts}, Es1) ->
+ foldr(
+ fun (C, Es) ->
+ [{bin_element,Line,{char,Line,C},Sz,Ts}|Es]
+ end, Es1, S);
+ (E, Es) ->
+ [E|Es]
+ end, [], Es0).
+
+bin_expand_string(S, Line, Val, Size) when Size >= 2048 ->
+ Combined = make_combined(Line, Val, Size),
+ [Combined|bin_expand_string(S, Line, 0, 0)];
+bin_expand_string([H|T], Line, Val, Size) ->
+ bin_expand_string(T, Line, (Val bsl 8) bor H, Size+8);
+bin_expand_string([], Line, Val, Size) ->
+ [make_combined(Line, Val, Size)].
+
+make_combined(Line, Val, Size) ->
+ {bin_element,Line,{integer,Line,Val},
+ {integer,Line,Size},
+ [integer,{unit,1},unsigned,big]}.
+
expr_bin_1(Es, St) ->
foldr(fun (E, {Ces,Esp,St0}) ->
{Ce,Ep,St1} = bitstr(E, St0),
@@ -1018,17 +1115,19 @@ bitstr({bin_element,_,E0,Size0,[Type,{unit,Unit}|Flags]}, St0) ->
%% fun_tq(Id, [Clauses], Line, State, NameInfo) -> {Fun,[PreExp],State}.
-fun_tq({_,_,Name}=Id, Cs0, L, St0, NameInfo) ->
+fun_tq(Cs0, L, St0, NameInfo) ->
Arity = clause_arity(hd(Cs0)),
{Cs1,Ceps,St1} = clauses(Cs0, St0),
{Args,St2} = new_vars(Arity, St1),
{Ps,St3} = new_vars(Arity, St2), %Need new variables here
Anno = full_anno(L, St3),
+ {Name,St4} = new_fun_name(St3),
Fc = function_clause(Ps, Anno, {Name,Arity}),
+ Id = {0,0,Name},
Fun = #ifun{anno=#a{anno=Anno},
id=[{id,Id}], %We KNOW!
vars=Args,clauses=Cs1,fc=Fc,name=NameInfo},
- {Fun,Ceps,St3}.
+ {Fun,Ceps,St4}.
%% lc_tq(Line, Exp, [Qualifier], Mc, State) -> {LetRec,[PreExp],State}.
%% This TQ from Simon PJ pp 127-138.
@@ -1354,8 +1453,9 @@ list_gen_pattern(P0, Line, St) ->
%%% the result binary in a binary comprehension.
%%%
-bc_initial_size(E, Q, St0) ->
+bc_initial_size(E0, Q, St0) ->
try
+ E = bin_bin_element(E0),
{ElemSzExpr,ElemSzPre,EVs,St1} = bc_elem_size(E, St0),
{V,St2} = new_var(St1),
{GenSzExpr,GenSzPre,St3} = bc_gen_size(Q, EVs, St2),
@@ -1394,11 +1494,15 @@ bc_elem_size({bin,_,El}, St0) ->
bc_elem_size(_, _) ->
throw(impossible).
-bc_elem_size_1([{bin_element,_,_,{integer,_,N},Flags}|Es], Bits, Vars) ->
- {unit,U} = keyfind(unit, 1, Flags),
+bc_elem_size_1([{bin_element,_,{string,_,String},{integer,_,N},_}=El|Es],
+ Bits, Vars) ->
+ U = get_unit(El),
+ bc_elem_size_1(Es, Bits+U*N*length(String), Vars);
+bc_elem_size_1([{bin_element,_,_,{integer,_,N},_}=El|Es], Bits, Vars) ->
+ U = get_unit(El),
bc_elem_size_1(Es, Bits+U*N, Vars);
-bc_elem_size_1([{bin_element,_,_,{var,_,Var},Flags}|Es], Bits, Vars) ->
- {unit,U} = keyfind(unit, 1, Flags),
+bc_elem_size_1([{bin_element,_,_,{var,_,Var},_}=El|Es], Bits, Vars) ->
+ U = get_unit(El),
bc_elem_size_1(Es, Bits, [{U,#c_var{name=Var}}|Vars]);
bc_elem_size_1([_|_], _, _) ->
throw(impossible);
@@ -1455,7 +1559,9 @@ bc_gen_size_1([{generate,L,El,Gen}|Qs], EVs, E0, Pre0, St0) ->
{E,Pre,St} = bc_gen_size_mul(E0, #c_literal{val=Len}, Pre0, St0),
bc_gen_size_1(Qs, EVs, E, Pre, St)
end;
-bc_gen_size_1([{b_generate,_,El,Gen}|Qs], EVs, E0, Pre0, St0) ->
+bc_gen_size_1([{b_generate,_,El0,Gen0}|Qs], EVs, E0, Pre0, St0) ->
+ El = bin_bin_element(El0),
+ Gen = bin_bin_element(Gen0),
bc_verify_non_filtering(El, EVs),
{MatchSzExpr,Pre1,_,St1} = bc_elem_size(El, St0),
Pre2 = reverse(Pre1, Pre0),
@@ -1471,6 +1577,10 @@ bc_gen_size_1([], _, E, Pre, St) ->
bc_gen_size_1(_, _, _, _, _) ->
throw(impossible).
+bin_bin_element({bin,L,El}) ->
+ {bin,L,[bin_element(E) || E <- El]};
+bin_bin_element(Other) -> Other.
+
bc_gen_bit_size({var,L,V}, Pre0, St0) ->
Lanno = lineno_anno(L, St0),
{SzVar,St} = new_var(St0),
@@ -1513,8 +1623,11 @@ bc_list_length(_, _) ->
bc_bin_size({bin,_,Els}) ->
bc_bin_size_1(Els, 0).
-bc_bin_size_1([{bin_element,_,_,{integer,_,Sz},Flags}|Els], N) ->
- {unit,U} = keyfind(unit, 1, Flags),
+bc_bin_size_1([{bin_element,_,{string,_,String},{integer,_,Sz},_}=El|Els], N) ->
+ U = get_unit(El),
+ bc_bin_size_1(Els, N+U*Sz*length(String));
+bc_bin_size_1([{bin_element,_,_,{integer,_,Sz},_}=El|Els], N) ->
+ U = get_unit(El),
bc_bin_size_1(Els, N+U*Sz);
bc_bin_size_1([], N) -> N;
bc_bin_size_1(_, _) -> throw(impossible).
@@ -1549,11 +1662,24 @@ bc_bsr(E1, E2) ->
name=#c_literal{val='bsr'},
args=[E1,E2]}.
-%% is_guard_test(Expression) -> true | false.
-%% Test if a general expression is a guard test. Use erl_lint here
-%% as it now allows sys_pre_expand transformed source.
+get_unit({bin_element,_,_,_,Flags}) ->
+ {unit,U} = keyfind(unit, 1, Flags),
+ U.
-is_guard_test(E) -> erl_lint:is_guard_test(E).
+%% is_guard_test(Expression) -> true | false.
+%% Test if a general expression is a guard test.
+%%
+%% Note that a local function overrides a BIF with the same name.
+%% For example, if there is a local function named is_list/1,
+%% any unqualified call to is_list/1 will be to the local function.
+%% The guard function must be explicitly called as erlang:is_list/1.
+
+is_guard_test(E) ->
+ %% erl_expand_records has added a module prefix to any call
+ %% to a BIF or imported function. Any call without a module
+ %% prefix that remains must therefore be to a local function.
+ IsOverridden = fun({_,_}) -> true end,
+ erl_lint:is_guard_test(E, [], IsOverridden).
%% novars(Expr, State) -> {Novars,[PreExpr],State}.
%% Generate a novars expression, basically a call or a safe. At this
@@ -1696,7 +1822,18 @@ pattern({bin,L,Ps}, St) ->
pattern({match,_,P1,P2}, St) ->
{Cp1,Eps1,St1} = pattern(P1,St),
{Cp2,Eps2,St2} = pattern(P2,St1),
- {pat_alias(Cp1,Cp2),Eps1++Eps2,St2}.
+ {pat_alias(Cp1,Cp2),Eps1++Eps2,St2};
+%% Evaluate compile-time expressions.
+pattern({op,_,'++',{nil,_},R}, St) ->
+ pattern(R, St);
+pattern({op,_,'++',{cons,Li,H,T},R}, St) ->
+ pattern({cons,Li,H,{op,Li,'++',T,R}}, St);
+pattern({op,_,'++',{string,Li,L},R}, St) ->
+ pattern(string_to_conses(Li, L, R), St);
+pattern({op,_Line,_Op,_A}=Op, St) ->
+ pattern(erl_eval:partial_eval(Op), St);
+pattern({op,_Line,_Op,_L,_R}=Op, St) ->
+ pattern(erl_eval:partial_eval(Op), St).
%% pattern_map_pairs([MapFieldExact],State) -> [#c_map_pairs{}]
pattern_map_pairs(Ps, St) ->
@@ -1736,18 +1873,29 @@ pat_alias_map_pairs_1([]) -> [].
%% pat_bin([BinElement], State) -> [BinSeg].
-pat_bin(Ps, St) -> [pat_segment(P, St) || P <- Ps].
+pat_bin(Ps, St) -> [pat_segment(P, St) || P <- bin_expand_strings(Ps)].
-pat_segment({bin_element,L,Val,Size,[Type,{unit,Unit}|Flags]}, St) ->
+pat_segment({bin_element,L,Val,Size0,Type0}, St) ->
+ {Size,Type1} = make_bit_type(L, Size0, Type0),
+ [Type,{unit,Unit}|Flags] = Type1,
Anno = lineno_anno(L, St),
- {Pval,[],St1} = pattern(Val,St),
- {Psize,[],_St2} = pattern(Size,St1),
+ {Pval0,[],St1} = pattern(Val, St),
+ Pval = coerce_to_float(Pval0, Type0),
+ {Psize,[],_St2} = pattern(Size, St1),
#c_bitstr{anno=Anno,
val=Pval,size=Psize,
unit=#c_literal{val=Unit},
type=#c_literal{val=Type},
flags=#c_literal{val=Flags}}.
+coerce_to_float(#c_literal{val=Int}=E, [float|_]) when is_integer(Int) ->
+ try
+ E#c_literal{val=float(Int)}
+ catch
+ error:badarg -> E
+ end;
+coerce_to_float(E, _) -> E.
+
%% pat_alias(CorePat, CorePat) -> AliasPat.
%% Normalise aliases. Trap bad aliases by throwing 'nomatch'.
@@ -1817,11 +1965,18 @@ pattern_list([P0|Ps0], St0) ->
pattern_list([], St) ->
{[],[],St}.
+string_to_conses(Line, Cs, Tail) ->
+ foldr(fun (C, T) -> {cons,Line,{char,Line,C},T} end, Tail, Cs).
%% make_vars([Name]) -> [{Var,Name}].
make_vars(Vs) -> [ #c_var{name=V} || V <- Vs ].
+new_fun_name(#core{function={F,A},fcount=I}=St) ->
+ Name = "-" ++ atom_to_list(F) ++ "/" ++ integer_to_list(A)
+ ++ "-fun-" ++ integer_to_list(I) ++ "-",
+ {list_to_atom(Name),St#core{fcount=I+1}}.
+
%% new_fun_name(Type, State) -> {FunName,State}.
new_fun_name(Type, #core{fcount=C}=St) ->
@@ -1830,7 +1985,7 @@ new_fun_name(Type, #core{fcount=C}=St) ->
%% new_var_name(State) -> {VarName,State}.
new_var_name(#core{vcount=C}=St) ->
- {list_to_atom("cor" ++ integer_to_list(C)),St#core{vcount=C + 1}}.
+ {list_to_atom("@c" ++ integer_to_list(C)),St#core{vcount=C + 1}}.
%% new_var(State) -> {{var,Name},State}.
%% new_var(LineAnno, State) -> {{var,Name},State}.
@@ -2475,7 +2630,11 @@ format_error(nomatch) ->
format_error(bad_binary) ->
"binary construction will fail because of a type mismatch";
format_error(badmap) ->
- "map construction will fail because of a type mismatch".
+ "map construction will fail because of a type mismatch";
+format_error({map_key_repeated,Key}) when is_atom(Key) ->
+ io_lib:format("key '~w' will be overridden in expression", [Key]);
+format_error({map_key_repeated,Key}) ->
+ io_lib:format("key ~p will be overridden in expression", [Key]).
add_warning(Anno, Term, #core{ws=Ws,file=[{file,File}]}=St) ->
case erl_anno:generated(Anno) of
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index b4bbc5e739..1fc05109c5 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -82,7 +82,7 @@
-export([module/2,format_error/1]).
-import(lists, [map/2,foldl/3,foldr/3,mapfoldl/3,splitwith/2,member/2,
- keymember/3,keyfind/3,partition/2,droplast/1,last/1]).
+ keymember/3,keyfind/3,partition/2,droplast/1,last/1,sort/1]).
-import(ordsets, [add_element/2,del_element/2,union/2,union/1,subtract/2]).
-import(cerl, [c_tuple/1]).
@@ -148,9 +148,12 @@ include_attribute(opaque) -> false;
include_attribute(export_type) -> false;
include_attribute(record) -> false;
include_attribute(optional_callbacks) -> false;
+include_attribute(file) -> false;
+include_attribute(compile) -> false;
include_attribute(_) -> true.
function({#c_var{name={F,Arity}=FA},Body}, St0) ->
+ %%io:format("~w/~w~n", [F,Arity]),
try
St1 = St0#kern{func=FA,ff=undefined,vcount=0,fcount=0,ds=cerl_sets:new()},
{#ifun{anno=Ab,vars=Kvs,body=B0},[],St2} = expr(Body, new_sub(), St1),
@@ -190,9 +193,479 @@ body(Ce, Sub, St0) ->
guard(G0, Sub, St0) ->
{G1,St1} = wrap_guard(G0, St0),
{Ge0,Pre,St2} = expr(G1, Sub, St1),
- {Ge,St} = gexpr_test(Ge0, St2),
+ {Ge1,St3} = gexpr_test(Ge0, St2),
+ {Ge,St} = guard_opt(Ge1, St3),
{pre_seq(Pre, Ge),St}.
+%% guard_opt(Kexpr, State) -> {Kexpr,State}.
+%% Optimize the Kexpr for the guard. Instead of evaluating a boolean
+%% expression comparing it to 'true' in a final #k_test{},
+%% replace BIF calls with #k_test{} in the expression.
+%%
+%% As an example, take the guard:
+%%
+%% when is_integer(V0), is_atom(V1) ->
+%%
+%% The unoptimized Kexpr translated to pseudo BEAM assembly
+%% code would look like:
+%%
+%% bif is_integer V0 => Bool0
+%% bif is_atom V1 => Bool1
+%% bif and Bool0 Bool1 => Bool
+%% test Bool =:= true else goto Fail
+%% ...
+%% Fail:
+%% ...
+%%
+%% The optimized code would look like:
+%%
+%% test is_integer V0 else goto Fail
+%% test is_atom V1 else goto Fail
+%% ...
+%% Fail:
+%% ...
+%%
+%% An 'or' operation is only slightly more complicated:
+%%
+%% test is_integer V0 else goto NotFailedYet
+%% goto Success
+%%
+%% NotFailedYet:
+%% test is_atom V1 else goto Fail
+%%
+%% Success:
+%% ...
+%% Fail:
+%% ...
+
+guard_opt(G, St0) ->
+ {Root,Forest0,St1} = make_forest(G, St0),
+ {Exprs,Forest,St} = rewrite_bool(Root, Forest0, false, St1),
+ E = forest_pre_seq(Exprs, Forest),
+ {G#k_try{arg=E},St}.
+
+%% rewrite_bool(Kexpr, Forest, Inv, St) -> {[Kexpr],Forest,St}.
+%% Rewrite Kexpr to use #k_test{} operations instead of comparison
+%% and type test BIFs.
+%%
+%% If Kexpr is a #k_test{} operation, the call will always
+%% succeed. Otherwise, a 'not_possible' exception will be
+%% thrown if Kexpr cannot be rewritten.
+
+rewrite_bool(#k_test{op=#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val='=:='}},
+ args=[#k_var{}=V,#k_atom{val=true}]}=Test, Forest0, Inv, St0) ->
+ try rewrite_bool_var(V, Forest0, Inv, St0) of
+ {_,_,_}=Res ->
+ Res
+ catch
+ throw:not_possible ->
+ {[Test],Forest0,St0}
+ end;
+rewrite_bool(#k_test{op=#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val='=:='}},
+ args=[#k_var{}=V,#k_atom{val=false}]}=Test, Forest0, Inv, St0) ->
+ try rewrite_bool_var(V, Forest0, not Inv, St0) of
+ {_,_,_}=Res ->
+ Res
+ catch
+ throw:not_possible ->
+ {[Test],Forest0,St0}
+ end;
+rewrite_bool(#k_test{op=#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val='=:='}},
+ args=[#k_atom{val=V1},#k_atom{val=V2}]}, Forest0, false, St0) ->
+ case V1 =:= V2 of
+ true ->
+ {[make_test(is_boolean, [#k_atom{val=true}])],Forest0,St0};
+ false ->
+ {[make_failing_test()],Forest0,St0}
+ end;
+rewrite_bool(#k_test{}=Test, Forest, false, St) ->
+ {[Test],Forest,St};
+rewrite_bool(#k_try{vars=[#k_var{name=X}],body=#k_var{name=X},
+ handler=#k_atom{val=false},ret=[]}=Prot,
+ Forest0, Inv, St0) ->
+ {Root,Forest1,St1} = make_forest(Prot, Forest0, St0),
+ {Exprs,Forest2,St} = rewrite_bool(Root, Forest1, Inv, St1),
+ InnerForest = maps:without(maps:keys(Forest0), Forest2),
+ Forest = maps:without(maps:keys(InnerForest), Forest2),
+ E = forest_pre_seq(Exprs, InnerForest),
+ {[Prot#k_try{arg=E}],Forest,St};
+rewrite_bool(#k_match{body=Body,ret=[]}, Forest, Inv, St) ->
+ rewrite_match(Body, Forest, Inv, St);
+rewrite_bool(Other, Forest, Inv, St) ->
+ case extract_bif(Other) of
+ {Name,Args} ->
+ rewrite_bif(Name, Args, Forest, Inv, St);
+ error ->
+ throw(not_possible)
+ end.
+
+%% rewrite_bool_var(Var, Forest, Inv, St) -> {[Kexpr],Forest,St}.
+%% Rewrite the boolean expression whose key in Forest is
+%% given by Var. Throw a 'not_possible' expression if something
+%% prevents the rewriting.
+
+rewrite_bool_var(Arg, Forest0, Inv, St) ->
+ {Expr,Forest} = forest_take_expr(Arg, Forest0),
+ rewrite_bool(Expr, Forest, Inv, St).
+
+%% rewrite_bool_args([Kexpr], Forest, Inv, St) -> {[[Kexpr]],Forest,St}.
+%% Rewrite each Kexpr in the list. The input Kexpr should be variables
+%% or boolean values. Throw a 'not_possible' expression if something
+%% prevents the rewriting.
+%%
+%% This function is suitable for handling the arguments for both
+%% 'and' and 'or'.
+
+rewrite_bool_args([#k_atom{val=B}=A|Vs], Forest0, false=Inv, St0) when is_boolean(B) ->
+ {Tail,Forest1,St1} = rewrite_bool_args(Vs, Forest0, Inv, St0),
+ Bif = make_bif('=:=', [A,#k_atom{val=true}]),
+ {Exprs,Forest,St} = rewrite_bool(Bif, Forest1, Inv, St1),
+ {[Exprs|Tail],Forest,St};
+rewrite_bool_args([#k_var{}=Var|Vs], Forest0, false=Inv, St0) ->
+ {Tail,Forest1,St1} = rewrite_bool_args(Vs, Forest0, Inv, St0),
+ {Exprs,Forest,St} =
+ case is_bool_expr(Var, Forest0) of
+ true ->
+ rewrite_bool_var(Var, Forest1, Inv, St1);
+ false ->
+ Bif = make_bif('=:=', [Var,#k_atom{val=true}]),
+ rewrite_bool(Bif, Forest1, Inv, St1)
+ end,
+ {[Exprs|Tail],Forest,St};
+rewrite_bool_args([_|_], _Forest, _Inv, _St) ->
+ throw(not_possible);
+rewrite_bool_args([], Forest, _Inv, St) ->
+ {[],Forest,St}.
+
+%% rewrite_bif(Name, [Kexpr], Forest, Inv, St) -> {[Kexpr],Forest,St}.
+%% Rewrite a BIF. Throw a 'not_possible' expression if something
+%% prevents the rewriting.
+
+rewrite_bif('or', Args, Forest, true, St) ->
+ rewrite_not_args('and', Args, Forest, St);
+rewrite_bif('and', Args, Forest, true, St) ->
+ rewrite_not_args('or', Args, Forest, St);
+rewrite_bif('and', [#k_atom{val=Val},Arg], Forest0, Inv, St0) ->
+ false = Inv, %Assertion.
+ case Val of
+ true ->
+ %% The result only depends on Arg.
+ rewrite_bool_var(Arg, Forest0, Inv, St0);
+ _ ->
+ %% Will fail. There is no need to evalute the expression
+ %% represented by Arg. Take it out from the forest and
+ %% discard the expression.
+ Failing = make_failing_test(),
+ try rewrite_bool_var(Arg, Forest0, Inv, St0) of
+ {_,Forest,St} ->
+ {[Failing],Forest,St}
+ catch
+ throw:not_possible ->
+ try forest_take_expr(Arg, Forest0) of
+ {_,Forest} ->
+ {[Failing],Forest,St0}
+ catch
+ throw:not_possible ->
+ %% Arg is probably a variable bound in an
+ %% outer scope.
+ {[Failing],Forest0,St0}
+ end
+ end
+ end;
+rewrite_bif('and', [Arg,#k_atom{}=Atom], Forest, Inv, St) ->
+ false = Inv, %Assertion.
+ rewrite_bif('and', [Atom,Arg], Forest, Inv, St);
+rewrite_bif('and', Args, Forest0, Inv, St0) ->
+ false = Inv, %Assertion.
+ {[Es1,Es2],Forest,St} = rewrite_bool_args(Args, Forest0, Inv, St0),
+ {Es1 ++ Es2,Forest,St};
+rewrite_bif('or', Args, Forest0, Inv, St0) ->
+ false = Inv, %Assertion.
+ {[First,Then],Forest,St} = rewrite_bool_args(Args, Forest0, Inv, St0),
+ Alt = make_alt(First, Then),
+ {[Alt],Forest,St};
+rewrite_bif('xor', [_,_], _Forest, _Inv, _St) ->
+ %% Rewriting 'xor' is not practical. Fortunately, 'xor' is
+ %% almost never used in practice.
+ throw(not_possible);
+rewrite_bif('not', [Arg], Forest0, Inv, St) ->
+ {Expr,Forest} = forest_take_expr(Arg, Forest0),
+ rewrite_bool(Expr, Forest, not Inv, St);
+rewrite_bif(Op, Args, Forest, Inv, St) ->
+ case is_test(Op, Args) of
+ true ->
+ rewrite_bool(make_test(Op, Args, Inv), Forest, false, St);
+ false ->
+ throw(not_possible)
+ end.
+
+rewrite_not_args(Op, [A0,B0], Forest0, St0) ->
+ {A,Forest1,St1} = rewrite_not_args_1(A0, Forest0, St0),
+ {B,Forest2,St2} = rewrite_not_args_1(B0, Forest1, St1),
+ rewrite_bif(Op, [A,B], Forest2, false, St2).
+
+rewrite_not_args_1(Arg, Forest, St) ->
+ Not = make_bif('not', [Arg]),
+ forest_add_expr(Not, Forest, St).
+
+%% rewrite_match(Kvar, TypeClause, Forest, Inv, St) ->
+%% {[Kexpr],Forest,St}.
+%% Try to rewrite a #k_match{} originating from an 'andalso' or an 'orelse'.
+
+rewrite_match(#k_alt{first=First,then=Then}, Forest, Inv, St) ->
+ case {First,Then} of
+ {#k_select{var=#k_var{name=V}=Var,types=[TypeClause]},#k_var{name=V}} ->
+ rewrite_match_1(Var, TypeClause, Forest, Inv, St);
+ {_,_} ->
+ throw(not_possible)
+ end.
+
+rewrite_match_1(Var, #k_type_clause{values=Cs0}, Forest0, Inv, St0) ->
+ Cs = sort([{Val,B} || #k_val_clause{val=#k_atom{val=Val},body=B} <- Cs0]),
+ case Cs of
+ [{false,False},{true,True}] ->
+ rewrite_match_2(Var, False, True, Forest0, Inv, St0);
+ _ ->
+ throw(not_possible)
+ end.
+
+rewrite_match_2(Var, False, #k_atom{val=true}, Forest0, Inv, St0) ->
+ %% Originates from an 'orelse'.
+ case False of
+ #k_atom{val=NotBool} when not is_boolean(NotBool) ->
+ rewrite_bool(Var, Forest0, Inv, St0);
+ _ ->
+ {CodeVar,Forest1,St1} = add_protected_expr(False, Forest0, St0),
+ rewrite_bif('or', [Var,CodeVar], Forest1, Inv, St1)
+ end;
+rewrite_match_2(Var, #k_atom{val=false}, True, Forest0, Inv, St0) ->
+ %% Originates from an 'andalso'.
+ {CodeVar,Forest1,St1} = add_protected_expr(True, Forest0, St0),
+ rewrite_bif('and', [Var,CodeVar], Forest1, Inv, St1);
+rewrite_match_2(_V, _, _, _Forest, _Inv, _St) ->
+ throw(not_possible).
+
+%% is_bool_expr(#k_var{}, Forest) -> true|false.
+%% Return true if the variable refers to a boolean expression
+%% that does not need an explicit '=:= true' test.
+
+is_bool_expr(V, Forest) ->
+ case forest_peek_expr(V, Forest) of
+ error ->
+ %% Defined outside of the guard. We can't know.
+ false;
+ Expr ->
+ case extract_bif(Expr) of
+ {Name,Args} ->
+ is_test(Name, Args) orelse
+ erl_internal:bool_op(Name, length(Args));
+ error ->
+ %% Not a BIF. Should be possible to rewrite
+ %% to a boolean. Definitely does not need
+ %% a '=:= true' test.
+ true
+ end
+ end.
+
+make_bif(Op, Args) ->
+ #k_bif{op=#k_remote{mod=#k_atom{val=erlang},
+ name=#k_atom{val=Op},
+ arity=length(Args)},
+ args=Args}.
+
+extract_bif(#k_bif{op=#k_remote{mod=#k_atom{val=erlang},
+ name=#k_atom{val=Name}},
+ args=Args}) ->
+ {Name,Args};
+extract_bif(_) ->
+ error.
+
+%% make_alt(First, Then) -> KMatch.
+%% Make a #k_alt{} within a #k_match{} to implement
+%% 'or' or 'orelse'.
+
+make_alt(First0, Then0) ->
+ First1 = pre_seq(droplast(First0), last(First0)),
+ Then1 = pre_seq(droplast(Then0), last(Then0)),
+ First2 = make_protected(First1),
+ Then2 = make_protected(Then1),
+ Body = #k_atom{val=ignored},
+ First3 = #k_guard_clause{guard=First2,body=Body},
+ Then3 = #k_guard_clause{guard=Then2,body=Body},
+ First = #k_guard{clauses=[First3]},
+ Then = #k_guard{clauses=[Then3]},
+ Alt = #k_alt{first=First,then=Then},
+ #k_match{vars=[],body=Alt}.
+
+add_protected_expr(#k_atom{}=Atom, Forest, St) ->
+ {Atom,Forest,St};
+add_protected_expr(#k_var{}=Var, Forest, St) ->
+ {Var,Forest,St};
+add_protected_expr(E0, Forest, St) ->
+ E = make_protected(E0),
+ forest_add_expr(E, Forest, St).
+
+make_protected(#k_try{}=Try) ->
+ Try;
+make_protected(B) ->
+ #k_try{arg=B,vars=[#k_var{name=''}],body=#k_var{name=''},
+ handler=#k_atom{val=false}}.
+
+make_failing_test() ->
+ make_test(is_boolean, [#k_atom{val=fail}]).
+
+make_test(Op, Args) ->
+ make_test(Op, Args, false).
+
+make_test(Op, Args, Inv) ->
+ Remote = #k_remote{mod=#k_atom{val=erlang},
+ name=#k_atom{val=Op},
+ arity=length(Args)},
+ #k_test{op=Remote,args=Args,inverted=Inv}.
+
+is_test(Op, Args) ->
+ A = length(Args),
+ erl_internal:new_type_test(Op, A) orelse erl_internal:comp_op(Op, A).
+
+%% make_forest(Kexpr, St) -> {RootKexpr,Forest,St}.
+%% Build a forest out of Kexpr. RootKexpr is the final expression
+%% nested inside Kexpr.
+
+make_forest(G, St) ->
+ make_forest_1(G, #{}, 0, St).
+
+%% make_forest(Kexpr, St) -> {RootKexpr,Forest,St}.
+%% Add to Forest from Kexpr. RootKexpr is the final expression
+%% nested inside Kexpr.
+
+make_forest(G, Forest0, St) ->
+ N = forest_next_index(Forest0),
+ make_forest_1(G, Forest0, N, St).
+
+make_forest_1(#k_try{arg=B}, Forest, I, St) ->
+ make_forest_1(B, Forest, I, St);
+make_forest_1(#iset{vars=[]}=Iset0, Forest, I, St0) ->
+ {UnrefVar,St} = new_var(St0),
+ Iset = Iset0#iset{vars=[UnrefVar]},
+ make_forest_1(Iset, Forest, I, St);
+make_forest_1(#iset{vars=[#k_var{name=V}],arg=Arg,body=B}, Forest0, I, St) ->
+ Forest = Forest0#{V => {I,Arg}, {untaken,V} => true},
+ make_forest_1(B, Forest, I+1, St);
+make_forest_1(Innermost, Forest, _I, St) ->
+ {Innermost,Forest,St}.
+
+%% forest_take_expr(Kexpr, Forest) -> {Expr,Forest}.
+%% If Kexpr is a variable, take out the expression corresponding
+%% to variable in Forest. Expressions that have been taken out
+%% of the forest will not be included the Kexpr returned
+%% by forest_pre_seq/2.
+%%
+%% Throw a 'not_possible' exception if Kexpr is not a variable or
+%% if the name of the variable is not a key in Forest.
+
+forest_take_expr(#k_var{name=V}, Forest0) ->
+ %% v3_core currently always generates guard expressions that can
+ %% be represented as a tree. Other code generators (such as LFE)
+ %% could generate guard expressions that can only be represented
+ %% as a DAG (i.e. some nodes are referenced more than once). To
+ %% handle DAGs, we must never remove a node from the forest, but
+ %% just remove the {untaken,V} marker. That will effectively convert
+ %% the DAG to a tree by duplicating the shared nodes and their
+ %% descendants.
+
+ case maps:find(V, Forest0) of
+ {ok,{_,Expr}} ->
+ Forest = maps:remove({untaken,V}, Forest0),
+ {Expr,Forest};
+ error ->
+ throw(not_possible)
+ end;
+forest_take_expr(_, _) ->
+ throw(not_possible).
+
+%% forest_peek_expr(Kvar, Forest) -> Kexpr | error.
+%% Return the expression corresponding to Kvar in Forest or
+%% return 'error' if there is a corresponding expression.
+
+forest_peek_expr(#k_var{name=V}, Forest0) ->
+ case maps:find(V, Forest0) of
+ {ok,{_,Expr}} -> Expr;
+ error -> error
+ end.
+
+%% forest_add_expr(Kexpr, Forest, St) -> {Kvar,Forest,St}.
+%% Add a new expression to Forest.
+
+forest_add_expr(Expr, Forest0, St0) ->
+ {#k_var{name=V}=Var,St} = new_var(St0),
+ N = forest_next_index(Forest0),
+ Forest = Forest0#{V => {N,Expr}},
+ {Var,Forest,St}.
+
+forest_next_index(Forest) ->
+ 1 + lists:max([N || {N,_} <- maps:values(Forest),
+ is_integer(N)] ++ [0]).
+
+%% forest_pre_seq([Kexpr], Forest) -> Kexpr.
+%% Package the list of Kexprs into a nested Kexpr, prepending all
+%% expressions in Forest that have not been taken out using
+%% forest_take_expr/2.
+
+forest_pre_seq(Exprs, Forest) ->
+ Es0 = [#k_var{name=V} || {untaken,V} <- maps:keys(Forest)],
+ Es = Es0 ++ Exprs,
+ Vs = extract_all_vars(Es, Forest, []),
+ Pre0 = sort([{maps:get(V, Forest),V} || V <- Vs]),
+ Pre = [#iset{vars=[#k_var{name=V}],arg=A} ||
+ {{_,A},V} <- Pre0],
+ pre_seq(Pre++droplast(Exprs), last(Exprs)).
+
+extract_all_vars(Es, Forest, Acc0) ->
+ case extract_var_list(Es) of
+ [] ->
+ Acc0;
+ [_|_]=Vs0 ->
+ Vs = [V || V <- Vs0, maps:is_key(V, Forest)],
+ NewVs = ordsets:subtract(Vs, Acc0),
+ NewEs = [begin
+ {_,E} = maps:get(V, Forest),
+ E
+ end || V <- NewVs],
+ Acc = union(NewVs, Acc0),
+ extract_all_vars(NewEs, Forest, Acc)
+ end.
+
+extract_vars(#iset{arg=A,body=B}) ->
+ union(extract_vars(A), extract_vars(B));
+extract_vars(#k_bif{args=Args}) ->
+ ordsets:from_list(lit_list_vars(Args));
+extract_vars(#k_call{}) ->
+ [];
+extract_vars(#k_test{args=Args}) ->
+ ordsets:from_list(lit_list_vars(Args));
+extract_vars(#k_match{body=Body}) ->
+ extract_vars(Body);
+extract_vars(#k_alt{first=First,then=Then}) ->
+ union(extract_vars(First), extract_vars(Then));
+extract_vars(#k_guard{clauses=Cs}) ->
+ extract_var_list(Cs);
+extract_vars(#k_guard_clause{guard=G}) ->
+ extract_vars(G);
+extract_vars(#k_select{var=Var,types=Types}) ->
+ union(ordsets:from_list(lit_vars(Var)),
+ extract_var_list(Types));
+extract_vars(#k_type_clause{values=Values}) ->
+ extract_var_list(Values);
+extract_vars(#k_val_clause{body=Body}) ->
+ extract_vars(Body);
+extract_vars(#k_try{arg=Arg}) ->
+ extract_vars(Arg);
+extract_vars(Lit) ->
+ ordsets:from_list(lit_vars(Lit)).
+
+extract_var_list(L) ->
+ union([extract_vars(E) || E <- L]).
+
%% Wrap the entire guard in a try/catch if needed.
wrap_guard(#c_try{}=Try, St) -> {Try,St};
@@ -840,23 +1313,26 @@ get_vsub(V, Vsub) ->
set_vsub(V, S, Vsub) ->
orddict:store(V, S, Vsub).
-subst_vsub(Key, New, [{K,Key}|Dict]) ->
+subst_vsub(Key, New, Vsub) ->
+ orddict:from_list(subst_vsub_1(Key, New, Vsub)).
+
+subst_vsub_1(Key, New, [{K,Key}|Dict]) ->
%% Fold chained substitution.
- [{K,New}|subst_vsub(Key, New, Dict)];
-subst_vsub(Key, New, [{K,_}|_]=Dict) when Key < K ->
+ [{K,New}|subst_vsub_1(Key, New, Dict)];
+subst_vsub_1(Key, New, [{K,_}|_]=Dict) when Key < K ->
%% Insert the new substitution here, and continue
%% look for chained substitutions.
- [{Key,New}|subst_vsub_1(Key, New, Dict)];
-subst_vsub(Key, New, [{K,_}=E|Dict]) when Key > K ->
- [E|subst_vsub(Key, New, Dict)];
-subst_vsub(Key, New, []) -> [{Key,New}].
+ [{Key,New}|subst_vsub_2(Key, New, Dict)];
+subst_vsub_1(Key, New, [{K,_}=E|Dict]) when Key > K ->
+ [E|subst_vsub_1(Key, New, Dict)];
+subst_vsub_1(Key, New, []) -> [{Key,New}].
-subst_vsub_1(V, S, [{K,V}|Dict]) ->
+subst_vsub_2(V, S, [{K,V}|Dict]) ->
%% Fold chained substitution.
- [{K,S}|subst_vsub_1(V, S, Dict)];
-subst_vsub_1(V, S, [E|Dict]) ->
- [E|subst_vsub_1(V, S, Dict)];
-subst_vsub_1(_, _, []) -> [].
+ [{K,S}|subst_vsub_2(V, S, Dict)];
+subst_vsub_2(V, S, [E|Dict]) ->
+ [E|subst_vsub_2(V, S, Dict)];
+subst_vsub_2(_, _, []) -> [].
get_fsub(F, A, Fsub) ->
case orddict:find({F,A}, Fsub) of
@@ -880,7 +1356,7 @@ new_fun_name(Type, #kern{func={F,Arity},fcount=C}=St) ->
%% new_var_name(State) -> {VarName,State}.
new_var_name(#kern{vcount=C}=St) ->
- {list_to_atom("ker" ++ integer_to_list(C)),St#kern{vcount=C+1}}.
+ {list_to_atom("@k" ++ integer_to_list(C)),St#kern{vcount=C+1}}.
%% new_var(State) -> {#k_var{},State}.
@@ -1350,10 +1826,70 @@ select(T, Cs) -> [ C || C <- Cs, clause_con(C) =:= T ].
%% At this point all the clauses have the same constructor, we must
%% now separate them according to value.
-match_value(Us, T, Cs0, Def, St0) ->
- Css = group_value(T, Cs0),
+match_value(Us0, T, Cs0, Def, St0) ->
+ {Us1,Cs1,St1} = partition_intersection(T, Us0, Cs0, St0),
+ UCss = group_value(T, Us1, Cs1),
%%ok = io:format("match_value ~p ~p~n", [T, Css]),
- mapfoldl(fun (Cs, St) -> match_clause(Us, Cs, Def, St) end, St0, Css).
+ mapfoldl(fun ({Us,Cs}, St) -> match_clause(Us, Cs, Def, St) end, St1, UCss).
+
+%% partition_intersection
+%% Partitions a map into two maps with the most common keys to the first map.
+%% case <M> of
+%% <#{a}>
+%% <#{a,b}>
+%% <#{a,c}>
+%% <#{c}>
+%% end
+%% becomes
+%% case <M,M> of
+%% <#{a}, #{ }>
+%% <#{a}, #{b}>
+%% <#{ }, #{c}>
+%% <#{a}, #{c}>
+%% end
+%% The intention is to group as many keys together as possible and thus
+%% reduce the number of lookups to that key.
+partition_intersection(k_map, [U|_]=Us0, [_,_|_]=Cs0,St0) ->
+ Ps = [clause_val(C) || C <- Cs0],
+ case find_key_partition(Ps) of
+ no_partition ->
+ {Us0,Cs0,St0};
+ Ks ->
+ {Cs1,St1} = mapfoldl(fun(#iclause{pats=[Arg|Args]}=C, Sti) ->
+ {{Arg1,Arg2},St} = partition_key_intersection(Arg, Ks, Sti),
+ {C#iclause{pats=[Arg1,Arg2|Args]}, St}
+ end, St0, Cs0),
+ {[U|Us0],Cs1,St1}
+ end;
+partition_intersection(_, Us, Cs, St) ->
+ {Us,Cs,St}.
+
+partition_key_intersection(#k_map{es=Pairs}=Map,Ks,St0) ->
+ F = fun(#k_map_pair{key=Key}) -> member(map_key_clean(Key), Ks) end,
+ {Ps1,Ps2} = partition(F, Pairs),
+ {{Map#k_map{es=Ps1},Map#k_map{es=Ps2}},St0};
+partition_key_intersection(#ialias{pat=Map}=Alias,Ks,St0) ->
+ %% only alias one of them
+ {{Map1,Map2},St1} = partition_key_intersection(Map, Ks, St0),
+ {{Map1,Alias#ialias{pat=Map2}},St1}.
+
+% Only check for the complete intersection of keys and not commonality
+find_key_partition(Ps) ->
+ Sets = [sets:from_list(Ks)||Ks <- Ps],
+ Is = sets:intersection(Sets),
+ case sets:to_list(Is) of
+ [] -> no_partition;
+ KeyIntersection ->
+ %% Check if the intersection are all keys in all clauses.
+ %% Don't split if they are since this will only
+ %% infer extra is_map instructions with no gain.
+ All = foldl(fun (Kset, Bool) ->
+ Bool andalso sets:is_subset(Kset, Is)
+ end, true, Sets),
+ if All -> no_partition;
+ true -> KeyIntersection
+ end
+ end.
%% group_value([Clause]) -> [[Clause]].
%% Group clauses according to value. Here we know that
@@ -1361,30 +1897,30 @@ match_value(Us, T, Cs0, Def, St0) ->
%% 2. The clauses in bin_segs cannot be reordered only grouped
%% 3. Other types are disjoint and can be reordered
-group_value(k_cons, Cs) -> [Cs]; %These are single valued
-group_value(k_nil, Cs) -> [Cs];
-group_value(k_binary, Cs) -> [Cs];
-group_value(k_bin_end, Cs) -> [Cs];
-group_value(k_bin_seg, Cs) -> group_bin_seg(Cs);
-group_value(k_bin_int, Cs) -> [Cs];
-group_value(k_map, Cs) -> group_map(Cs);
-group_value(_, Cs) ->
+group_value(k_cons, Us, Cs) -> [{Us,Cs}]; %These are single valued
+group_value(k_nil, Us, Cs) -> [{Us,Cs}];
+group_value(k_binary, Us, Cs) -> [{Us,Cs}];
+group_value(k_bin_end, Us, Cs) -> [{Us,Cs}];
+group_value(k_bin_seg, Us, Cs) -> group_bin_seg(Us,Cs);
+group_value(k_bin_int, Us, Cs) -> [{Us,Cs}];
+group_value(k_map, Us, Cs) -> group_map(Us,Cs);
+group_value(_, Us, Cs) ->
%% group_value(Cs).
Cd = foldl(fun (C, Gcs0) -> dict:append(clause_val(C), C, Gcs0) end,
dict:new(), Cs),
- dict:fold(fun (_, Vcs, Css) -> [Vcs|Css] end, [], Cd).
+ dict:fold(fun (_, Vcs, Css) -> [{Us,Vcs}|Css] end, [], Cd).
-group_bin_seg([C1|Cs]) ->
+group_bin_seg(Us, [C1|Cs]) ->
V1 = clause_val(C1),
{More,Rest} = splitwith(fun (C) -> clause_val(C) == V1 end, Cs),
- [[C1|More]|group_bin_seg(Rest)];
-group_bin_seg([]) -> [].
+ [{Us,[C1|More]}|group_bin_seg(Us,Rest)];
+group_bin_seg(_, []) -> [].
-group_map([C1|Cs]) ->
+group_map(Us, [C1|Cs]) ->
V1 = clause_val(C1),
{More,Rest} = splitwith(fun (C) -> clause_val(C) =:= V1 end, Cs),
- [[C1|More]|group_map(Rest)];
-group_map([]) -> [].
+ [{Us,[C1|More]}|group_map(Us,Rest)];
+group_map(_, []) -> [].
%% Profiling shows that this quadratic implementation account for a big amount
%% of the execution time if there are many values.
@@ -1734,15 +2270,15 @@ uexpr(#k_receive_accept{anno=A}, _, St) ->
{#k_receive_accept{anno=#k{us=[],ns=[],a=A}},[],St};
uexpr(#k_receive_next{anno=A}, _, St) ->
{#k_receive_next{anno=#k{us=[],ns=[],a=A}},[],St};
-uexpr(#k_try{anno=A,arg=A0,vars=Vs,body=B0,evars=Evs,handler=H0}=Try,
+uexpr(#k_try{anno=A,arg=A0,vars=Vs,body=B0,evars=Evs,handler=H0},
{break,Rs0}=Br, St0) ->
case is_in_guard(St0) of
true ->
{[#k_var{name=X}],#k_var{name=X}} = {Vs,B0}, %Assertion.
#k_atom{val=false} = H0, %Assertion.
{A1,Bu,St1} = uexpr(A0, Br, St0),
- {Try#k_try{anno=#k{us=Bu,ns=lit_list_vars(Rs0),a=A},
- arg=A1,ret=Rs0},Bu,St1};
+ {#k_protected{anno=#k{us=Bu,ns=lit_list_vars(Rs0),a=A},
+ arg=A1,ret=Rs0},Bu,St1};
false ->
{Avs,St1} = new_vars(length(Vs), St0),
{A1,Au,St2} = ubody(A0, {break,Avs}, St1),
@@ -1791,13 +2327,9 @@ uexpr(#ifun{anno=A,vars=Vs,body=B0}, {break,Rs}, St0) ->
end,
Fun = #k_fdef{anno=#k{us=[],ns=[],a=A},func=Fname,arity=Arity,
vars=Vs ++ Fvs,body=B1},
- %% Set dummy values for Index and Uniq -- the real values will
- %% be assigned by beam_asm.
- Index = Uniq = 0,
{#k_bif{anno=#k{us=Free,ns=lit_list_vars(Rs),a=A},
- op=#k_internal{name=make_fun,arity=length(Free)+3},
- args=[#k_atom{val=Fname},#k_int{val=Arity},
- #k_int{val=Index},#k_int{val=Uniq}|Fvs],
+ op=#k_internal{name=make_fun,arity=length(Free)+2},
+ args=[#k_atom{val=Fname},#k_int{val=Arity}|Fvs],
ret=Rs},
Free,add_local_function(Fun, St)};
uexpr(Lit, {break,Rs0}, St0) ->
diff --git a/lib/compiler/src/v3_kernel.hrl b/lib/compiler/src/v3_kernel.hrl
index 5216a1a620..7cd30b25a8 100644
--- a/lib/compiler/src/v3_kernel.hrl
+++ b/lib/compiler/src/v3_kernel.hrl
@@ -58,7 +58,7 @@
-record(k_seq, {anno=[],arg,body}).
-record(k_put, {anno=[],arg,ret=[]}).
-record(k_bif, {anno=[],op,args,ret=[]}).
--record(k_test, {anno=[],op,args}).
+-record(k_test, {anno=[],op,args,inverted=false}).
-record(k_call, {anno=[],op,args,ret=[]}).
-record(k_enter, {anno=[],op,args}).
-record(k_receive, {anno=[],var,body,timeout,action,ret=[]}).
@@ -66,6 +66,7 @@
-record(k_receive_next, {anno=[]}).
-record(k_try, {anno=[],arg,vars,body,evars,handler,ret=[]}).
-record(k_try_enter, {anno=[],arg,vars,body,evars,handler}).
+-record(k_protected, {anno=[],arg,ret=[]}).
-record(k_catch, {anno=[],body,ret=[]}).
-record(k_guard_match, {anno=[],vars,body,ret=[]}).
diff --git a/lib/compiler/src/v3_kernel_pp.erl b/lib/compiler/src/v3_kernel_pp.erl
index 0b90f0a1e0..53097d0d7d 100644
--- a/lib/compiler/src/v3_kernel_pp.erl
+++ b/lib/compiler/src/v3_kernel_pp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@
canno(Cthing) -> element(2, Cthing).
--spec format(cerl:cerl()) -> iolist().
+-spec format(#k_mdef{}) -> iolist().
format(Node) -> format(Node, #ctxt{}).
@@ -145,7 +145,7 @@ format_1(#k_local{name=N,arity=A}, Ctxt) ->
"local " ++ format_fa_pair({N,A}, Ctxt);
format_1(#k_remote{mod=M,name=N,arity=A}, _Ctxt) ->
%% This is for our internal translator.
- io_lib:format("remote ~s:~s/~w", [format(M),format(N),A]);
+ io_lib:format("remote ~ts:~ts/~w", [format(M),format(N),A]);
format_1(#k_internal{name=N,arity=A}, Ctxt) ->
"internal " ++ format_fa_pair({N,A}, Ctxt);
format_1(#k_seq{arg=A,body=B}, Ctxt) ->
@@ -235,8 +235,13 @@ format_1(#k_bif{op=Op,args=As,ret=Rs}, Ctxt) ->
[Txt,format_args(As, Ctxt1),
format_ret(Rs, Ctxt1)
];
-format_1(#k_test{op=Op,args=As}, Ctxt) ->
- Txt = ["test (",format(Op, ctxt_bump_indent(Ctxt, 6)),$)],
+format_1(#k_test{op=Op,args=As,inverted=Inverted}, Ctxt) ->
+ Txt = case Inverted of
+ false ->
+ ["test (",format(Op, ctxt_bump_indent(Ctxt, 6)),$)];
+ true ->
+ ["inverted_test (",format(Op, ctxt_bump_indent(Ctxt, 6)),$)]
+ end,
Ctxt1 = ctxt_bump_indent(Ctxt, 2),
[Txt,format_args(As, Ctxt1)];
format_1(#k_put{arg=A,ret=Rs}, Ctxt) ->
@@ -279,6 +284,15 @@ format_1(#k_try_enter{arg=A,vars=Vs,body=B,evars=Evs,handler=H}, Ctxt) ->
nl_indent(Ctxt),
"end"
];
+format_1(#k_protected{arg=A,ret=Rs}, Ctxt) ->
+ Ctxt1 = ctxt_bump_indent(Ctxt, Ctxt#ctxt.body_indent),
+ ["protected",
+ nl_indent(Ctxt1),
+ format(A, Ctxt1),
+ nl_indent(Ctxt),
+ "end",
+ format_ret(Rs, ctxt_bump_indent(Ctxt, 1))
+ ];
format_1(#k_catch{body=B,ret=Rs}, Ctxt) ->
Ctxt1 = ctxt_bump_indent(Ctxt, Ctxt#ctxt.body_indent),
["catch",
diff --git a/lib/compiler/src/v3_life.erl b/lib/compiler/src/v3_life.erl
index 1452b78d1d..be3ade47ff 100644
--- a/lib/compiler/src/v3_life.erl
+++ b/lib/compiler/src/v3_life.erl
@@ -52,10 +52,15 @@
-include("v3_kernel.hrl").
-include("v3_life.hrl").
+-type fa() :: {atom(),arity()}.
+
%% These are not defined in v3_kernel.hrl.
get_kanno(Kthing) -> element(2, Kthing).
%%set_kanno(Kthing, Anno) -> setelement(2, Kthing, Anno).
+-spec module(#k_mdef{}, [compile:option()]) ->
+ {'ok',{module(),[fa()],[_],[_]}}.
+
module(#k_mdef{name=M,exports=Es,attributes=As,body=Fs0}, _Opts) ->
Fs1 = functions(Fs0, []),
{ok,{M,Es,As,Fs1}}.
@@ -78,9 +83,7 @@ function(#k_fdef{anno=#k{a=Anno},func=F,arity=Ar,vars=Vs,body=Kb}) ->
#k_match{anno=#k{us=Ka#k.us,ns=[],a=Ka#k.a},
vars=Vs,body=Kb,ret=[]}
end,
- put(guard_refc, 0),
{B1,_,Vdb1} = body(B0, 1, Vdb0),
- erase(guard_refc),
{function,F,Ar,As,B1,Vdb1,Anno}
catch
Class:Error ->
@@ -106,12 +109,13 @@ body(Ke, I, Vdb0) ->
E = expr(Ke, I, Vdb1),
{[E],I,Vdb1}.
-%% guard(Kguard, I, Vdb) -> Guard.
+%% protected(Kprotected, I, Vdb) -> Protected.
+%% Only used in guards.
-guard(#k_try{anno=A,arg=Ts,vars=[#k_var{name=X}],body=#k_var{name=X},
- handler=#k_atom{val=false},ret=Rs}, I, Vdb) ->
+protected(#k_protected{anno=A,arg=Ts,ret=Rs}, I, Vdb) ->
%% Lock variables that are alive before try and used afterwards.
- %% Don't lock variables that are only used inside the try expression.
+ %% Don't lock variables that are only used inside the protected
+ %% expression.
Pdb0 = vdb_sub(I, I+1, Vdb),
{T,MaxI,Pdb1} = body(Ts, I+1, Pdb0),
Pdb2 = use_vars(A#k.ns, MaxI+1, Pdb1), %Save "return" values
@@ -119,8 +123,8 @@ guard(#k_try{anno=A,arg=Ts,vars=[#k_var{name=X}],body=#k_var{name=X},
%% expr(Kexpr, I, Vdb) -> Expr.
-expr(#k_test{anno=A,op=Op,args=As}, I, _Vdb) ->
- #l{ke={test,test_op(Op),atomic_list(As)},i=I,a=A#k.a};
+expr(#k_test{anno=A,op=Op,args=As,inverted=Inverted}, I, _Vdb) ->
+ #l{ke={test,test_op(Op),atomic_list(As),Inverted},i=I,a=A#k.a};
expr(#k_call{anno=A,op=Op,args=As,ret=Rs}, I, _Vdb) ->
#l{ke={call,call_op(Op),atomic_list(As),var_list(Rs)},i=I,a=A#k.a};
expr(#k_enter{anno=A,op=Op,args=As}, I, _Vdb) ->
@@ -139,10 +143,9 @@ expr(#k_guard_match{anno=A,body=Kb,ret=Rs}, I, Vdb) ->
M = match(Kb, A#k.us, I+1, [], Mdb),
#l{ke={guard_match,M,var_list(Rs)},i=I,vdb=use_vars(A#k.us, I+1, Mdb),a=A#k.a};
expr(#k_try{}=Try, I, Vdb) ->
- case is_in_guard() of
- false -> body_try(Try, I, Vdb);
- true -> guard(Try, I, Vdb)
- end;
+ body_try(Try, I, Vdb);
+expr(#k_protected{}=Protected, I, Vdb) ->
+ protected(Protected, I, Vdb);
expr(#k_try_enter{anno=A,arg=Ka,vars=Vs,body=Kb,evars=Evs,handler=Kh}, I, Vdb) ->
%% Lock variables that are alive before the catch and used afterwards.
%% Don't lock variables that are only used inside the try.
@@ -213,7 +216,6 @@ body_try(#k_try{anno=A,arg=Ka,vars=Vs,body=Kb,evars=Evs,handler=Kh,ret=Rs},
i=I,vdb=Tdb1,a=A#k.a}.
%% call_op(Op) -> Op.
-%% bif_op(Op) -> Op.
%% test_op(Op) -> Op.
%% Do any necessary name translations here to munge into beam format.
@@ -221,28 +223,14 @@ call_op(#k_local{name=N}) -> N;
call_op(#k_remote{mod=M,name=N}) -> {remote,atomic(M),atomic(N)};
call_op(Other) -> variable(Other).
-bif_op(#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val=N}}) -> N;
-bif_op(#k_internal{name=N}) -> N.
-
test_op(#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val=N}}) -> N.
%% k_bif(Anno, Op, [Arg], [Ret], Vdb) -> Expr.
-%% Build bifs, do special handling of internal some calls.
-
-k_bif(_A, #k_internal{name=dsetelement,arity=3}, As, []) ->
- {bif,dsetelement,atomic_list(As),[]};
-k_bif(_A, #k_internal{name=bs_context_to_binary=Op,arity=1}, As, []) ->
- {bif,Op,atomic_list(As),[]};
-k_bif(_A, #k_internal{name=bs_init_writable=Op,arity=1}, As, Rs) ->
- {bif,Op,atomic_list(As),var_list(Rs)};
-k_bif(_A, #k_internal{name=make_fun},
- [#k_atom{val=Fun},#k_int{val=Arity},
- #k_int{val=Index},#k_int{val=Uniq}|Free],
- Rs) ->
- {bif,{make_fun,Fun,Arity,Index,Uniq},var_list(Free),var_list(Rs)};
-k_bif(_A, Op, As, Rs) ->
- %% The general case.
- Name = bif_op(Op),
+%% Build bifs.
+
+k_bif(_A, #k_internal{name=Name}, As, Rs) ->
+ {internal,Name,atomic_list(As),var_list(Rs)};
+k_bif(_A, #k_remote{mod=#k_atom{val=erlang},name=#k_atom{val=Name}}, As, Rs) ->
Ar = length(As),
case is_gc_bif(Name, Ar) of
false ->
@@ -303,9 +291,7 @@ val_clause(#k_val_clause{anno=A,val=V,body=Kb}, Ls0, I, Ctxt0, Vdb0) ->
guard_clause(#k_guard_clause{anno=A,guard=Kg,body=Kb}, Ls, I, Ctxt, Vdb0) ->
Vdb1 = use_vars(union(A#k.us, Ls), I+2, Vdb0),
Gdb = vdb_sub(I+1, I+2, Vdb1),
- OldRefc = put(guard_refc, get(guard_refc)+1),
- G = guard(Kg, I+1, Gdb),
- put(guard_refc, OldRefc),
+ G = protected(Kg, I+1, Gdb),
B = match(Kb, Ls, I+2, Ctxt, Vdb1),
#l{ke={guard_clause,G,B},
i=I,vdb=use_vars((get_kanno(Kg))#k.us, I+2, Vdb1),
@@ -394,7 +380,6 @@ is_gc_bif(node, 0) -> false;
is_gc_bif(node, 1) -> false;
is_gc_bif(element, 2) -> false;
is_gc_bif(get, 1) -> false;
-is_gc_bif(raise, 2) -> false;
is_gc_bif(tuple_size, 1) -> false;
is_gc_bif(Bif, Arity) ->
not (erl_internal:bool_op(Bif, Arity) orelse
@@ -431,16 +416,15 @@ use_vars(Vs, I, Vdb) -> vdb_update_vars(Vs, Vdb, I).
add_var(V, F, L, Vdb) ->
vdb_store_new(V, {V,F,L}, Vdb).
-%% is_in_guard() -> true|false.
-
-is_in_guard() ->
- get(guard_refc) > 0.
-
%% vdb
vdb_new(Vs) ->
sort([{V,0,0} || {var,V} <- Vs]).
+-type var() :: atom().
+
+-spec vdb_find(var(), [vdb_entry()]) -> 'error' | vdb_entry().
+
vdb_find(V, Vdb) ->
case lists:keyfind(V, 1, Vdb) of
false -> error;
diff --git a/lib/compiler/src/v3_life.hrl b/lib/compiler/src/v3_life.hrl
index 9d03a86ccd..5c76312067 100644
--- a/lib/compiler/src/v3_life.hrl
+++ b/lib/compiler/src/v3_life.hrl
@@ -20,8 +20,10 @@
%% This record contains variable life-time annotation for a
%% kernel expression. Added by v3_life, used by v3_codegen.
+-type vdb_entry() :: {atom(),non_neg_integer(),non_neg_integer()}.
+
-record(l, {ke, %Kernel expression
- i=0, %Op number
- vdb=[], %Variable database
- a}). %Core annotation
+ i=0 :: non_neg_integer(), %Op number
+ vdb=[] :: [vdb_entry()], %Variable database
+ a=[] :: [term()]}). %Core annotation
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index f0185acbc7..63763f31b2 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -9,7 +9,6 @@ MODULES= \
andor_SUITE \
apply_SUITE \
beam_block_SUITE \
- beam_bool_SUITE \
beam_validator_SUITE \
beam_disasm_SUITE \
beam_except_SUITE \
@@ -36,7 +35,7 @@ MODULES= \
map_SUITE \
match_SUITE \
misc_SUITE \
- num_bif_SUITE \
+ overridden_bif_SUITE \
receive_SUITE \
record_SUITE \
regressions_SUITE \
@@ -49,7 +48,6 @@ NO_OPT= \
andor \
apply \
beam_block \
- beam_bool \
beam_except \
beam_jump \
beam_reorder \
@@ -67,7 +65,7 @@ NO_OPT= \
map \
match \
misc \
- num_bif \
+ overridden_bif \
receive \
record \
trycatch
@@ -76,8 +74,8 @@ INLINE= \
andor \
apply \
beam_block \
- beam_bool \
beam_utils \
+ bif \
bs_bincomp \
bs_bit_binaries \
bs_construct \
@@ -91,10 +89,14 @@ INLINE= \
map \
match \
misc \
- num_bif \
+ overridden_bif \
receive \
record
+CORE_MODULES = \
+ lfe_andor_SUITE \
+ lfe_guard_SUITE
+
NO_OPT_MODULES= $(NO_OPT:%=%_no_opt_SUITE)
NO_OPT_ERL_FILES= $(NO_OPT_MODULES:%=%.erl)
POST_OPT_MODULES= $(NO_OPT:%=%_post_opt_SUITE)
@@ -103,6 +105,8 @@ INLINE_MODULES= $(INLINE:%=%_inline_SUITE)
INLINE_ERL_FILES= $(INLINE_MODULES:%=%.erl)
ERL_FILES= $(MODULES:%=%.erl)
+CORE_FILES= $(CORE_MODULES:%=%.core)
+ERL_DUMMY_FILES= $(CORE_MODULES:%=%.erl)
##TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
##INSTALL_PROGS= $(TARGET_FILES)
@@ -136,6 +140,8 @@ make_emakefile: $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) $(INLINE_ERL_FILES)
-o$(EBIN) $(POST_OPT_MODULES) >> $(EMAKEFILE)
$(ERL_TOP)/make/make_emakefile +inline $(ERL_COMPILE_FLAGS) \
-o$(EBIN) $(INLINE_MODULES) >> $(EMAKEFILE)
+ $(ERL_TOP)/make/make_emakefile +from_core $(ERL_COMPILE_FLAGS) \
+ -o$(EBIN) $(CORE_MODULES) >> $(EMAKEFILE)
tests debug opt: make_emakefile
erl $(ERL_MAKE_FLAGS) -make
@@ -173,6 +179,13 @@ release_tests_spec: make_emakefile
$(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)"
$(INSTALL_DATA) $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) \
$(INLINE_ERL_FILES) "$(RELSYSDIR)"
+ $(INSTALL_DATA) $(CORE_FILES) "$(RELSYSDIR)"
+ for file in $(ERL_DUMMY_FILES); do \
+ module=`basename $$file .erl`; \
+ echo "-module($$module). %% dummy .erl file" >$$file; \
+ done
+ $(INSTALL_DATA) $(ERL_DUMMY_FILES) "$(RELSYSDIR)"
+ rm $(ERL_DUMMY_FILES)
chmod -R u+w "$(RELSYSDIR)"
@tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
diff --git a/lib/compiler/test/beam_block_SUITE.erl b/lib/compiler/test/beam_block_SUITE.erl
index 4bcb252833..55d5f2dbe8 100644
--- a/lib/compiler/test/beam_block_SUITE.erl
+++ b/lib/compiler/test/beam_block_SUITE.erl
@@ -21,7 +21,8 @@
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
init_per_group/2,end_per_group/2,
- get_map_elements/1,otp_7345/1,move_opt_across_gc_bif/1]).
+ get_map_elements/1,otp_7345/1,move_opt_across_gc_bif/1,
+ erl_202/1,repro/1]).
%% The only test for the following functions is that
%% the code compiles and is accepted by beam_validator.
@@ -37,7 +38,9 @@ groups() ->
[{p,[parallel],
[get_map_elements,
otp_7345,
- move_opt_across_gc_bif
+ move_opt_across_gc_bif,
+ erl_202,
+ repro
]}].
init_per_suite(Config) ->
@@ -135,6 +138,48 @@ positive(speaking) ->
paris([], P) -> P + 1.
+
+%% See https://bugs.erlang.org/browse/ERL-202.
+%% Test that move_allocates/1 in beam_block doesn't move allocate
+%% when it would not be safe.
+
+-record(erl_202_r1, {y}).
+-record(erl_202_r2, {x}).
+
+erl_202(_Config) ->
+ Ref = make_ref(),
+ Ref = erl_202({{1,2},Ref}, 42),
+
+ {Ref} = erl_202({7,8}, #erl_202_r1{y=#erl_202_r2{x=Ref}}),
+
+ ok.
+
+erl_202({{_, _},X}, _) ->
+ X;
+erl_202({_, _}, #erl_202_r1{y=R2}) ->
+ {R2#erl_202_r2.x}.
+
+%% See https://bugs.erlang.org/browse/ERL-266.
+%% Instructions with failure labels are not safe to include
+%% in a block. Including get_map_elements in a block would
+%% lead to unsafe code.
+
+repro(_Config) ->
+ [] = maps:to_list(repro([], #{}, #{})),
+ [{tmp1,n}] = maps:to_list(repro([{tmp1,0}], #{}, #{})),
+ [{tmp1,name}] = maps:to_list(repro([{tmp1,0}], #{}, #{0=>name})),
+ ok.
+
+repro([], TempNames, _Slots) ->
+ TempNames;
+repro([{Temp, Slot}|Xs], TempNames, Slots0) ->
+ {Name, Slots} =
+ case Slots0 of
+ #{Slot := Name0} -> {Name0, Slots0};
+ #{} -> {n, Slots0#{Slot => n}}
+ end,
+ repro(Xs, TempNames#{Temp => Name}, Slots).
+
%%%
%%% The only test of the following code is that it compiles.
%%%
diff --git a/lib/compiler/test/beam_bool_SUITE.erl b/lib/compiler/test/beam_bool_SUITE.erl
deleted file mode 100644
index e585eaedb5..0000000000
--- a/lib/compiler/test/beam_bool_SUITE.erl
+++ /dev/null
@@ -1,197 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(beam_bool_SUITE).
-
--export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
- init_per_group/2,end_per_group/2,
- before_and_inside_if/1,
- scotland/1,y_registers/1,protected/1,
- maps/1]).
-
-suite() ->
- [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- test_lib:recompile(?MODULE),
- [{group,p}].
-
-groups() ->
- [{p,[parallel],
- [before_and_inside_if,
- scotland,
- y_registers,
- protected,
- maps
- ]}].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-before_and_inside_if(_Config) ->
- no = before_and_inside_if([a], [b], delete),
- no = before_and_inside_if([a], [b], x),
- no = before_and_inside_if([a], [], delete),
- no = before_and_inside_if([a], [], x),
- no = before_and_inside_if([], [], delete),
- yes = before_and_inside_if([], [], x),
- yes = before_and_inside_if([], [b], delete),
- yes = before_and_inside_if([], [b], x),
-
- {ch1,ch2} = before_and_inside_if_2([a], [b], blah),
- {ch1,ch2} = before_and_inside_if_2([a], [b], xx),
- {ch1,ch2} = before_and_inside_if_2([a], [], blah),
- {ch1,ch2} = before_and_inside_if_2([a], [], xx),
- {no,no} = before_and_inside_if_2([], [b], blah),
- {no,no} = before_and_inside_if_2([], [b], xx),
- {ch1,no} = before_and_inside_if_2([], [], blah),
- {no,ch2} = before_and_inside_if_2([], [], xx),
- ok.
-
-%% Thanks to Simon Cornish and Kostis Sagonas.
-%% Used to crash beam_bool.
-before_and_inside_if(XDo1, XDo2, Do3) ->
- Do1 = (XDo1 =/= []),
- Do2 = (XDo2 =/= []),
- if
- %% This expression occurs in a try/catch (protected)
- %% block, which cannot refer to variables outside of
- %% the block that are boolean expressions.
- Do1 =:= true;
- Do1 =:= false, Do2 =:= false, Do3 =:= delete ->
- no;
- true ->
- yes
- end.
-
-%% Thanks to Simon Cornish.
-%% Used to generate code that would not set {y,0} on
-%% all paths before its use (and therefore fail
-%% validation by the beam_validator).
-before_and_inside_if_2(XDo1, XDo2, Do3) ->
- Do1 = (XDo1 =/= []),
- Do2 = (XDo2 =/= []),
- CH1 = if Do1 == true;
- Do1 == false,Do2==false,Do3 == blah ->
- ch1;
- true ->
- no
- end,
- CH2 = if Do1 == true;
- Do1 == false,Do2==false,Do3 == xx ->
- ch2;
- true ->
- no
- end,
- {CH1,CH2}.
-
-
-%% beam_bool would remove the initialization of {y,0}.
-%% (Thanks to Thomas Arts and QuickCheck.)
-
-scotland(_Config) ->
- million = do_scotland(placed),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(false)),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(true)),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(echo)),
- ok.
-
-do_scotland(Echo) ->
- found(case Echo of
- Echo when true; Echo, Echo, Echo ->
- Echo;
- echo ->
- []
- end,
- Echo = placed).
-
-found(_, _) -> million.
-
-
-%% ERL-143: beam_bool could not handle Y registers as a destination.
-y_registers(_Config) ->
- {'EXIT',{badarith,[_|_]}} = (catch baker(valentine)),
- {'EXIT',{badarith,[_|_]}} = (catch baker(clementine)),
-
- {not_ok,true} = potter([]),
- {ok,false} = potter([{encoding,any}]),
-
- ok.
-
-%% Thanks to Quickcheck.
-baker(Baker) ->
- (valentine == Baker) +
- case Baker of
- Baker when Baker; Baker ->
- Baker;
- Baker ->
- []
- end.
-
-%% Thanks to Jose Valim.
-potter(Modes) ->
- Raw = lists:keyfind(encoding, 1, Modes) == false,
- Final = case Raw of
- X when X == false; X == nil -> ok;
- _ -> not_ok
- end,
- {Final,Raw}.
-
-protected(_Config) ->
- {'EXIT',{if_clause,_}} = (catch photographs({1, surprise, true}, opinions)),
-
- {{true}} = welcome({perfect, true}),
- {'EXIT',{if_clause,_}} = (catch welcome({perfect, false})),
- ok.
-
-photographs({_Violation, surprise, Deep}, opinions) ->
- {if
- 0; "here", Deep ->
- Deep = Deep
- end}.
-
-welcome({perfect, Profit}) ->
- if
- Profit, Profit, Profit; 0 ->
- {id({Profit})}
- end.
-
-maps(_Config) ->
- ok = evidence(#{0 => 42}).
-
-%% Cover handling of put_map in in split_block_label_used/2.
-evidence(#{0 := Charge}) when 0; #{[] => Charge} == #{[] => 42} ->
- ok.
-
-
-%%%
-%%% Common utilities.
-%%%
-
-id(I) ->
- I.
diff --git a/lib/compiler/test/beam_jump_SUITE.erl b/lib/compiler/test/beam_jump_SUITE.erl
index 0b13adaff2..088f63606c 100644
--- a/lib/compiler/test/beam_jump_SUITE.erl
+++ b/lib/compiler/test/beam_jump_SUITE.erl
@@ -21,7 +21,7 @@
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
init_per_group/2,end_per_group/2,
- undefined_label/1]).
+ undefined_label/1,ambiguous_catch_try_state/1]).
suite() ->
[{ct_hooks,[ts_install_cth]}].
@@ -32,7 +32,8 @@ all() ->
groups() ->
[{p,[parallel],
- [undefined_label
+ [undefined_label,
+ ambiguous_catch_try_state
]}].
init_per_suite(Config) ->
@@ -57,3 +58,17 @@ flights(0, [], []) when [], 0; 0.0, [], false ->
clark;
flights(_, Reproduction, introduction) when false, Reproduction ->
responsible.
+
+%% [ERL-209] beam_jump would share 'catch' blocks, causing an
+%% ambiguous_catch_try_state error in beam_validator.
+
+ambiguous_catch_try_state(_Config) ->
+ {{'EXIT',{{case_clause,song},_}},{'EXIT',{{case_clause,song},_}}} =
+ checks(42),
+ ok.
+
+river() -> song.
+
+checks(Wanted) ->
+ %% Must be one line to cause the unsafe optimization.
+ {catch case river() of sheet -> begin +Wanted, if "da" -> Wanted end end end, catch case river() of sheet -> begin + Wanted, if "da" -> Wanted end end end}.
diff --git a/lib/compiler/test/beam_reorder_SUITE.erl b/lib/compiler/test/beam_reorder_SUITE.erl
index ff31f2d3bd..27ce51eec3 100644
--- a/lib/compiler/test/beam_reorder_SUITE.erl
+++ b/lib/compiler/test/beam_reorder_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl
index 69e2f1838d..86146c614f 100644
--- a/lib/compiler/test/beam_type_SUITE.erl
+++ b/lib/compiler/test/beam_type_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
init_per_group/2,end_per_group/2,
integers/1,coverage/1,booleans/1,setelement/1,cons/1,
- tuple/1]).
+ tuple/1,record_float/1,binary_float/1,float_compare/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -37,7 +37,10 @@ groups() ->
booleans,
setelement,
cons,
- tuple
+ tuple,
+ record_float,
+ binary_float,
+ float_compare
]}].
init_per_suite(Config) ->
@@ -126,5 +129,48 @@ tuple(_Config) ->
do_tuple() ->
{0, _} = {necessary}.
+-record(x, {a}).
+
+record_float(_Config) ->
+ 17.0 = record_float(#x{a={0}}, 1700),
+ 23.0 = record_float(#x{a={0}}, 2300.0),
+ {'EXIT',{if_clause,_}} = (catch record_float(#x{a={1}}, 88)),
+ {'EXIT',{if_clause,_}} = (catch record_float(#x{a={}}, 88)),
+ {'EXIT',{if_clause,_}} = (catch record_float(#x{}, 88)),
+ ok.
+
+record_float(R, N0) ->
+ N = N0 / 100,
+ if element(1, R#x.a) =:= 0 ->
+ N
+ end.
+
+binary_float(_Config) ->
+ <<-1/float>> = binary_negate_float(<<1/float>>),
+ ok.
+
+binary_negate_float(<<Float/float>>) ->
+ <<-Float/float>>.
+
+float_compare(_Config) ->
+ false = do_float_compare(-42.0),
+ false = do_float_compare(-42),
+ false = do_float_compare(0),
+ false = do_float_compare(0.0),
+ true = do_float_compare(42),
+ true = do_float_compare(42.0),
+ ok.
+
+do_float_compare(X) ->
+ %% ERL-433: Used to fail before OTP 20. Was accidentally fixed
+ %% in OTP 20. Add a test case to ensure it stays fixed.
+
+ Y = X + 1.0,
+ case X > 0 of
+ T when (T =:= nil) or (T =:= false) -> T;
+ _T -> Y > 0
+ end.
+
+
id(I) ->
I.
diff --git a/lib/compiler/test/beam_utils_SUITE.erl b/lib/compiler/test/beam_utils_SUITE.erl
index f6d4a311bb..a3f1bb93fe 100644
--- a/lib/compiler/test/beam_utils_SUITE.erl
+++ b/lib/compiler/test/beam_utils_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -283,6 +283,9 @@ coverage(_Config) ->
{'EXIT',{function_clause,_}} = (catch town(overall, {{abc},alcohol})),
+ self() ! junk_message,
+ {"url",#{true:="url"}} = appointment(#{"resolution" => "url"}),
+
ok.
%% Cover check_liveness/3.
@@ -352,6 +355,9 @@ yellow(Hill) ->
Hill,
id(42).
+do(A, B) -> {A,B}.
+appointment(#{"resolution" := Url}) ->
+ do(receive _ -> Url end, #{true => Url}).
%% The identity function.
id(I) -> I.
diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index 263fd2ca7e..c23514b36b 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,7 +32,8 @@
bad_bin_match/1,bad_dsetel/1,
state_after_fault_in_catch/1,no_exception_in_catch/1,
undef_label/1,illegal_instruction/1,failing_gc_guard_bif/1,
- map_field_lists/1,cover_bin_opt/1]).
+ map_field_lists/1,cover_bin_opt/1,
+ val_dsetel/1]).
-include_lib("common_test/include/ct.hrl").
@@ -60,7 +61,7 @@ groups() ->
freg_state,bad_bin_match,bad_dsetel,
state_after_fault_in_catch,no_exception_in_catch,
undef_label,illegal_instruction,failing_gc_guard_bif,
- map_field_lists,cover_bin_opt]}].
+ map_field_lists,cover_bin_opt,val_dsetel]}].
init_per_suite(Config) ->
Config.
@@ -445,7 +446,7 @@ do_bin_opt(Mod, Asm) ->
do_bin_opt(Transform, Mod, Asm0) ->
Asm = Transform(Asm0),
case compile:forms(Asm, [from_asm,no_postopt,return]) of
- {ok,[],Code,_Warnings} when is_binary(Code) ->
+ {ok,Mod,Code,_Warnings} when is_binary(Code) ->
ok;
{error,Errors0,_} ->
%% beam_validator must return errors, not simply crash,
@@ -546,3 +547,23 @@ beam_val(M) ->
_ = [io:put_chars(beam_validator:format_error(E)) ||
E <- Errors],
Errors.
+
+%%%-------------------------------------------------------------------------
+
+val_dsetel(_Config) ->
+ self() ! 13,
+ {'EXIT',{{try_clause,participating},_}} = (catch night(0)),
+ ok.
+
+night(Turned) ->
+ receive
+ 13 ->
+ try participating of engine -> 16 after false end
+ end,
+ %% The setelement/3 call is unreachable.
+ Turned(setelement(#{true => Turned},
+ participating(Turned, "suit", 40, []),
+ Turned < Turned)),
+ ok.
+
+participating(_, _, _, _) -> ok.
diff --git a/lib/compiler/test/bif_SUITE.erl b/lib/compiler/test/bif_SUITE.erl
index 51bc71da81..bba2058f2f 100644
--- a/lib/compiler/test/bif_SUITE.erl
+++ b/lib/compiler/test/bif_SUITE.erl
@@ -19,9 +19,11 @@
%%
-module(bif_SUITE).
+-include_lib("syntax_tools/include/merl.hrl").
+
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
init_per_group/2,end_per_group/2,
- beam_validator/1]).
+ beam_validator/1,trunc_and_friends/1,cover_safe_bifs/1]).
suite() ->
[{ct_hooks,[ts_install_cth]}].
@@ -32,7 +34,9 @@ all() ->
groups() ->
[{p,[parallel],
- [beam_validator
+ [beam_validator,
+ trunc_and_friends,
+ cover_safe_bifs
]}].
init_per_suite(Config) ->
@@ -63,3 +67,56 @@ food(Curriculum) ->
catch _ ->
0
end, Curriculum].
+
+%% Test trunc/1, round/1, floor/1, ceil/1.
+trunc_and_friends(_Config) ->
+ Bifs = [trunc,round,floor,ceil],
+ Fs = trunc_and_friends_1(Bifs),
+ Mod = ?FUNCTION_NAME,
+ Calls = [begin
+ Atom = erl_syntax:function_name(N),
+ ?Q("'@Atom'()")
+ end || N <- Fs],
+ Tree = ?Q(["-module('@Mod@').",
+ "-export([test/0]).",
+ "test() -> _@Calls, ok.",
+ "id(I) -> I."]) ++ Fs,
+ merl:print(Tree),
+ Opts = test_lib:opt_opts(?MODULE),
+ {ok,_Bin} = merl:compile_and_load(Tree, Opts),
+ Mod:test(),
+ ok.
+
+trunc_and_friends_1([F|Fs]) ->
+ Func = list_to_atom("f"++integer_to_list(length(Fs))),
+ [trunc_template(Func, F)|trunc_and_friends_1(Fs)];
+trunc_and_friends_1([]) -> [].
+
+trunc_template(Func, Bif) ->
+ Val = 42.77,
+ Res = erlang:Bif(Val),
+ FloatRes = float(Res),
+ ?Q("'@Func@'() ->
+ Var = id(_@Val@),
+ if _@Bif@(Var) =:= _@Res@ -> ok end,
+ if _@Bif@(Var) == _@FloatRes@ -> ok end,
+ if _@Bif@(Var) == _@Res@ -> ok end,
+ _@Res@ = _@Bif@(Var),
+ try begin _@Bif@(a), ok end
+ catch error:badarg -> ok end,
+ ok.").
+
+cover_safe_bifs(Config) ->
+ _ = get(),
+ _ = get_keys(a),
+ _ = group_leader(),
+ _ = is_alive(),
+ _ = min(Config, []),
+ _ = nodes(),
+ _ = erlang:ports(),
+ _ = pre_loaded(),
+ _ = processes(),
+ _ = registered(),
+ _ = term_to_binary(Config),
+
+ ok.
diff --git a/lib/compiler/test/bs_bincomp_SUITE.erl b/lib/compiler/test/bs_bincomp_SUITE.erl
index 4743821337..dd1d245f88 100644
--- a/lib/compiler/test/bs_bincomp_SUITE.erl
+++ b/lib/compiler/test/bs_bincomp_SUITE.erl
@@ -56,6 +56,7 @@ end_per_group(_GroupName, Config) ->
byte_aligned(Config) when is_list(Config) ->
cs_init(),
<<"abcdefg">> = cs(<< <<(X+32)>> || <<X>> <= <<"ABCDEFG">> >>),
+ <<"AxyzBxyzCxyz">> = cs(<< <<X, "xyz">> || <<X>> <= <<"ABC">> >>),
<<1:32/little,2:32/little,3:32/little,4:32/little>> =
cs(<< <<X:32/little>> || <<X:32>> <= <<1:32,2:32,3:32,4:32>> >>),
cs(<<1:32/little,2:32/little,3:32/little,4:32/little>> =
diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl
index ff18f8b41c..da99aba346 100644
--- a/lib/compiler/test/bs_construct_SUITE.erl
+++ b/lib/compiler/test/bs_construct_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,7 +29,8 @@
init_per_testcase/2,end_per_testcase/2,
two/1,test1/1,fail/1,float_bin/1,in_guard/1,in_catch/1,
nasty_literals/1,coerce_to_float/1,side_effect/1,
- opt/1,otp_7556/1,float_arith/1,otp_8054/1]).
+ opt/1,otp_7556/1,float_arith/1,otp_8054/1,
+ cover/1]).
-include_lib("common_test/include/ct.hrl").
@@ -45,7 +46,7 @@ groups() ->
[{p,[parallel],
[two,test1,fail,float_bin,in_guard,in_catch,
nasty_literals,side_effect,opt,otp_7556,float_arith,
- otp_8054]}].
+ otp_8054,cover]}].
init_per_suite(Config) ->
@@ -552,3 +553,19 @@ otp_8054_1([H|T], Bin) ->
end,
otp_8054_1(T, Bin);
otp_8054_1([], Bin) -> Bin.
+
+-define(LONG_STRING,
+ "3lz7Q4au2i3DJWNlNhWuzmvA7gYWGXG+LAPtgtlEO2VGSxRqL2WOoHW"
+ "QxORTQfJw17mNEU8i87UKvEPbo9YY8ppiM7vfaG88TTyfEzgUMTgY3I"
+ "vsikMBELPz2AayVz5aaMh9PBFTZ4DkBIFxURBUKHho4Vgt7IzYnWNgn"
+ "3ON5D9VS89TPANK5/PwSUoMQYZ2fk5VLbq7D1ExlnCScvTDnF/WHMQ3"
+ "m2GUcQWb+ajfOf3bnP7EX4f1Q3d/1Soe6lEpf1KN/5S7A/ugjMhy4+H"
+ "Zuo1J1J6CCwEVZ/wDc79OpDPPj/qOGhDK73F8DaMcynZ91El+01vfTn"
+ "uUxNFUHLpuoQ==").
+
+cover(Config) ->
+ %% Cover handling of a huge partially literal string.
+ L = length(Config),
+ Bin = id(<<L:32,?LONG_STRING>>),
+ <<L:32,?LONG_STRING>> = Bin,
+ ok.
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 224abf6c29..0ec05456ec 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -38,7 +38,8 @@
no_partition/1,calling_a_binary/1,binary_in_map/1,
match_string_opt/1,select_on_integer/1,
map_and_binary/1,unsafe_branch_caching/1,
- bad_literals/1,good_literals/1,constant_propagation/1]).
+ bad_literals/1,good_literals/1,constant_propagation/1,
+ parse_xml/1,get_payload/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -69,7 +70,8 @@ groups() ->
no_partition,calling_a_binary,binary_in_map,
match_string_opt,select_on_integer,
map_and_binary,unsafe_branch_caching,
- bad_literals,good_literals,constant_propagation]}].
+ bad_literals,good_literals,constant_propagation,parse_xml,
+ get_payload]}].
init_per_suite(Config) ->
@@ -768,6 +770,11 @@ multiple_uses(Config) when is_list(Config) ->
{344,62879,345,<<245,159,1,89>>} = multiple_uses_1(<<1,88,245,159,1,89>>),
true = multiple_uses_2(<<0,0,197,18>>),
<<42,43>> = multiple_uses_3(<<0,0,42,43>>, fun id/1),
+
+ ok = first_after(<<>>, 42),
+ <<1>> = first_after(<<1,2,3>>, 0),
+ <<2>> = first_after(<<1,2,3>>, 1),
+
ok.
multiple_uses_1(<<X:16,Tail/binary>>) ->
@@ -789,6 +796,24 @@ multiple_uses_match(<<Y:16,Z:16>>) ->
multiple_uses_cmp(<<Y:16>>, <<Y:16>>) -> true;
multiple_uses_cmp(<<_:16>>, <<_:16>>) -> false.
+first_after(Data, Offset) ->
+ case byte_size(Data) > Offset of
+ false ->
+ {First, Rest} = {ok, ok},
+ ok;
+ true ->
+ <<_:Offset/binary, Rest/binary>> = Data,
+ %% 'Rest' saved in y(0) before the call.
+ {First, _} = match_first(Data, Rest),
+ %% When beam_bsm sees the code, the following line
+ %% which uses y(0) has been optimized away.
+ {First, Rest} = {First, Rest},
+ First
+ end.
+
+match_first(_, <<First:1/binary, Rest/binary>>) ->
+ {First, Rest}.
+
zero_label(Config) when is_list(Config) ->
<<"nosemouth">> = read_pols(<<"FACE","nose","mouth">>),
<<"CE">> = read_pols(<<"noFACE">>),
@@ -863,28 +888,41 @@ matching_and_andalso(Config) when is_list(Config) ->
{'EXIT',{function_clause,_}} = (catch matching_and_andalso_1(<<1,2,3>>, blurf)),
{'EXIT',{function_clause,_}} = (catch matching_and_andalso_1(<<1,2,3>>, 19)),
- {"abc",<<"xyz">>} = matching_and_andalso_2("abc", <<"-xyz">>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($a-1)>>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($z+1)>>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($A-1)>>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($Z+1)>>),
- error = matching_and_andalso_2([], <<>>),
- error = matching_and_andalso_2([], <<$A>>),
- error = matching_and_andalso_2([], <<$Z>>),
- error = matching_and_andalso_2([], <<$a>>),
- error = matching_and_andalso_2([], <<$z>>),
+ {"abc",<<"xyz">>} = matching_and_andalso_23("abc", <<"-xyz">>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($a-1)>>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($z+1)>>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($A-1)>>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($Z+1)>>),
+ error = matching_and_andalso_23([], <<>>),
+ error = matching_and_andalso_23([], <<$A>>),
+ error = matching_and_andalso_23([], <<$Z>>),
+ error = matching_and_andalso_23([], <<$a>>),
+ error = matching_and_andalso_23([], <<$z>>),
ok.
matching_and_andalso_1(<<Bitmap/binary>>, K)
when is_integer(K) andalso size(Bitmap) >= K andalso 0 < K ->
ok.
+matching_and_andalso_23(Datetime, Bin) ->
+ Res = matching_and_andalso_2(Datetime, Bin),
+ Res = matching_and_andalso_3(Datetime, Bin),
+ Res.
+
matching_and_andalso_2(Datetime, <<H,T/binary>>)
when not ((H >= $a) andalso (H =< $z)) andalso
not ((H >= $A) andalso (H =< $Z)) ->
{Datetime,T};
matching_and_andalso_2(_, _) -> error.
+%% Contrived example to ensure we cover the handling of 'call' instructions
+%% in v3_codegen:bsm_rename_ctx/4.
+matching_and_andalso_3(Datetime, <<H,T/binary>>)
+ when not ((abs(H) >= $a) andalso (abs(H) =< $z)) andalso
+ not ((abs(H) >= $A) andalso (abs(H) =< $Z)) ->
+ {Datetime,T};
+matching_and_andalso_3(_, _) -> error.
+
%% Thanks to Tomas Stejskal.
otp_7188(Config) when is_list(Config) ->
MP3 = <<84,65,71,68,117,154,105,232,107,121,0,0,0,0,0,0,0,0,0,0,
@@ -1451,6 +1489,40 @@ constant_propagation_c() ->
X
end.
+parse_xml(_Config) ->
+ <<"<?xmlX">> = do_parse_xml(<<"<?xmlX">>),
+ <<" ">> = do_parse_xml(<<"<?xml ">>),
+ ok.
+
+do_parse_xml(<<"<?xml"/utf8,Rest/binary>> = Bytes) ->
+ %% Delayed sub-binary creation is not safe. A buggy (development)
+ %% version of check_liveness_everywhere() in beam_utils would turn
+ %% on the optimization.
+ Rest1 = case is_next_char_whitespace(Rest) of
+ false ->
+ Bytes;
+ true ->
+ id(Rest)
+ end,
+ id(Rest1).
+
+is_next_char_whitespace(<<C/utf8,_/binary>>) ->
+ C =:= $\s.
+
+-record(ext_header,
+ {this_hdr = 17,
+ ext_hdr_opts}).
+
+get_payload(Config) ->
+ <<3445:48>> = do_get_payload(#ext_header{ext_hdr_opts = <<3445:48>>}),
+ {'EXIT',_} = (catch do_get_payload(#ext_header{})),
+ ok.
+
+do_get_payload(ExtHdr) ->
+ _ = ExtHdr#ext_header.this_hdr,
+ ExtHdrOptions = ExtHdr#ext_header.ext_hdr_opts,
+ <<_:13,_:35>> = ExtHdr#ext_header.ext_hdr_opts,
+ ExtHdrOptions.
check(F, R) ->
R = F().
diff --git a/lib/compiler/test/bs_utf_SUITE.erl b/lib/compiler/test/bs_utf_SUITE.erl
index c894041f72..ef3fc54b37 100644
--- a/lib/compiler/test/bs_utf_SUITE.erl
+++ b/lib/compiler/test/bs_utf_SUITE.erl
@@ -235,6 +235,7 @@ utf32_to_unicode(<<>>) -> [].
literals(Config) when is_list(Config) ->
abc_utf8 = match_literal(<<"abc"/utf8>>),
abc_utf8 = match_literal(<<$a,$b,$c>>),
+ abc_utf8 = match_literal(<<$a/utf8,$b/utf8,$c/utf8>>),
abc_utf16be = match_literal(<<"abc"/utf16>>),
abc_utf16be = match_literal(<<$a:16,$b:16,$c:16>>),
diff --git a/lib/compiler/test/compilation_SUITE.erl b/lib/compiler/test/compilation_SUITE.erl
index cd1bc099e9..a4de125d32 100644
--- a/lib/compiler/test/compilation_SUITE.erl
+++ b/lib/compiler/test/compilation_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -319,7 +319,7 @@ self_compile_1(Config, Prefix, Opts) ->
%% Compile the compiler. (In this node to get better coverage.)
CompA = make_compiler_dir(Priv, Prefix++"compiler_a"),
VsnA = Version ++ ".0",
- compile_compiler(compiler_src(), CompA, VsnA, [clint0,clint|Opts]),
+ compile_compiler(compiler_src(), CompA, VsnA, Opts),
%% Compile the compiler again using the newly compiled compiler.
%% (In another node because reloading the compiler would disturb cover.)
diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl
index b0148f7103..f647a4030d 100644
--- a/lib/compiler/test/compile_SUITE.erl
+++ b/lib/compiler/test/compile_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,14 +27,16 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
app_test/1,appup_test/1,
+ debug_info/4, custom_debug_info/1,
file_1/1, forms_2/1, module_mismatch/1, big_file/1, outdir/1,
binary/1, makedep/1, cond_and_ifdef/1, listings/1, listings_big/1,
- other_output/1, encrypted_abstr/1,
- strict_record/1,
- cover/1, env/1, core/1,
- core_roundtrip/1, asm/1,
+ other_output/1, kernel_listing/1, encrypted_abstr/1,
+ strict_record/1, utf8_atoms/1, utf8_functions/1, extra_chunks/1,
+ cover/1, env/1, core_pp/1,
+ core_roundtrip/1, asm/1, optimized_guards/1,
sys_pre_attributes/1, dialyzer/1,
- warnings/1, pre_load_check/1, env_compiler_options/1
+ warnings/1, pre_load_check/1, env_compiler_options/1,
+ bc_options/1
]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -47,11 +49,11 @@ all() ->
test_lib:recompile(?MODULE),
[app_test, appup_test, file_1, forms_2, module_mismatch, big_file, outdir,
binary, makedep, cond_and_ifdef, listings, listings_big,
- other_output, encrypted_abstr,
- strict_record,
- cover, env, core, core_roundtrip, asm,
+ other_output, kernel_listing, encrypted_abstr,
+ strict_record, utf8_atoms, utf8_functions, extra_chunks,
+ cover, env, core_pp, core_roundtrip, asm, optimized_guards,
sys_pre_attributes, dialyzer, warnings, pre_load_check,
- env_compiler_options].
+ env_compiler_options, custom_debug_info, bc_options].
groups() ->
[].
@@ -105,6 +107,14 @@ file_1(Config) when is_list(Config) ->
{ok,simple} = compile:file(Simple, [{eprof,beam_z}]), %Coverage
+
+ %% Test option 'deterministic'.
+ {ok,simple} = compile:file(Simple, [deterministic]),
+ {module,simple} = c:l(simple),
+ [{version,_}] = simple:module_info(compile),
+ true = code:delete(simple),
+ false = code:purge(simple),
+
ok = file:set_cwd(Cwd),
true = exists(Target),
passed = run(Target, test, []),
@@ -153,6 +163,24 @@ forms_2(Config) when is_list(Config) ->
ok
end,
+ {ok,simple,Core} = compile:forms(SimpleCode, [to_core0,binary]),
+ forms_compile_and_load(Core, [from_core]),
+ forms_compile_and_load(Core, [from_core,native]),
+
+ {ok,simple,Asm} = compile:forms(SimpleCode, [to_asm,binary]),
+ forms_compile_and_load(Asm, [from_asm]),
+ forms_compile_and_load(Asm, [from_asm,native]),
+
+ {ok,simple,Beam} = compile:forms(SimpleCode, []),
+ forms_compile_and_load(Beam, [from_beam]),
+ forms_compile_and_load(Beam, [from_beam,native]),
+
+ %% Cover the error handling code.
+ error = compile:forms(bad_core, [from_core,report]),
+ error = compile:forms(bad_asm, [from_asm,report]),
+ error = compile:forms(<<"bad_beam">>, [from_beam,report]),
+ error = compile:forms(<<"bad_beam">>, [from_beam,native,report]),
+
ok.
@@ -170,6 +198,14 @@ forms_load_code(Mod, Src, Bin) ->
SourceOption.
+forms_compile_and_load(Code, Opts) ->
+ Mod = simple,
+ {ok,Mod,Bin} = compile:forms(Code, Opts),
+ {module,Mod} = code:load_binary(Mod, "ignore", Bin),
+ _ = Mod:module_info(),
+ true = code:delete(simple),
+ false = code:purge(simple),
+ ok.
module_mismatch(Config) when is_list(Config) ->
DataDir = proplists:get_value(data_dir, Config),
@@ -335,6 +371,7 @@ do_file_listings(DataDir, PrivDir, [File|Files]) ->
do_listing(Simple, TargetDir, dinline, ".inline"),
do_listing(Simple, TargetDir, dcore, ".core"),
do_listing(Simple, TargetDir, dcopt, ".copt"),
+ do_listing(Simple, TargetDir, dcbsm, ".core_bsm"),
do_listing(Simple, TargetDir, dsetel, ".dsetel"),
do_listing(Simple, TargetDir, dkern, ".kernel"),
do_listing(Simple, TargetDir, dlife, ".life"),
@@ -342,7 +379,6 @@ do_file_listings(DataDir, PrivDir, [File|Files]) ->
do_listing(Simple, TargetDir, dblk, ".block"),
do_listing(Simple, TargetDir, dexcept, ".except"),
do_listing(Simple, TargetDir, dbs, ".bs"),
- do_listing(Simple, TargetDir, dbool, ".bool"),
do_listing(Simple, TargetDir, dtype, ".type"),
do_listing(Simple, TargetDir, ddead, ".dead"),
do_listing(Simple, TargetDir, djmp, ".jump"),
@@ -403,12 +439,11 @@ other_output(Config) when is_list(Config) ->
end],
io:put_chars("to_exp (file)"),
- {ok,simple,Expand} = compile:file(Simple, [to_exp,binary,time]),
- case Expand of
- {simple,Exports,Forms} when is_list(Exports), is_list(Forms) -> ok
- end,
+ {ok,[],Expand} = compile:file(Simple, [to_exp,binary,time]),
+ true = is_list(Expand),
+ {attribute,_,module,simple} = lists:keyfind(module, 3, Expand),
io:put_chars("to_exp (forms)"),
- {ok,simple,Expand} = compile:forms(PP, [to_exp,binary,time]),
+ {ok,[],Expand} = compile:forms(PP, [to_exp,binary,time]),
io:put_chars("to_core (file)"),
{ok,simple,Core} = compile:file(Simple, [to_core,binary,time]),
@@ -431,6 +466,34 @@ other_output(Config) when is_list(Config) ->
ok.
+%% Smoke test and cover of pretty-printing of Kernel code.
+kernel_listing(_Config) ->
+ TestBeams = get_unique_beam_files(),
+ Abstr = [begin {ok,{Mod,[{abstract_code,
+ {raw_abstract_v1,Abstr}}]}} =
+ beam_lib:chunks(Beam, [abstract_code]),
+ {Mod,Abstr} end || Beam <- TestBeams],
+ test_lib:p_run(fun(F) -> do_kernel_listing(F) end, Abstr).
+
+do_kernel_listing({M,A}) ->
+ try
+ {ok,M,Kern} = compile:forms(A, [to_kernel]),
+ IoList = v3_kernel_pp:format(Kern),
+ case unicode:characters_to_binary(IoList) of
+ Bin when is_binary(Bin) ->
+ ok
+ end
+ catch
+ throw:{error,Error} ->
+ io:format("*** compilation failure '~p' for module ~s\n",
+ [Error,M]),
+ error;
+ Class:Error ->
+ io:format("~p: ~p ~p\n~p\n",
+ [M,Class,Error,erlang:get_stacktrace()]),
+ error
+ end.
+
encrypted_abstr(Config) when is_list(Config) ->
{Simple,Target} = get_files(Config, simple, "encrypted_abstr"),
@@ -470,17 +533,23 @@ encrypted_abstr_1(Simple, Target) ->
{ok,simple} = compile:file(Simple,
[debug_info,{debug_info_key,Key},
{outdir,TargetDir}]),
- verify_abstract(Target),
+ verify_abstract(Target, erl_abstract_code),
{ok,simple} = compile:file(Simple,
[{debug_info_key,Key},
{outdir,TargetDir}]),
- verify_abstract(Target),
+ verify_abstract(Target, erl_abstract_code),
{ok,simple} = compile:file(Simple,
[debug_info,{debug_info_key,{des3_cbc,Key}},
{outdir,TargetDir}]),
- verify_abstract(Target),
+ verify_abstract(Target, erl_abstract_code),
+
+ {ok,simple} = compile:file(Simple,
+ [{debug_info,{?MODULE,ok}},
+ {debug_info_key,Key},
+ {outdir,TargetDir}]),
+ verify_abstract(Target, ?MODULE),
{ok,{simple,[{compile_info,CInfo}]}} =
beam_lib:chunks(Target, [compile_info]),
@@ -505,7 +574,7 @@ encrypted_abstr_1(Simple, Target) ->
NewKey = "better use another key here",
write_crypt_file(["[{debug_info,des3_cbc,simple,\"",NewKey,"\"}].\n"]),
{ok,simple} = compile:file(Simple, [encrypt_debug_info,report]),
- verify_abstract("simple.beam"),
+ verify_abstract("simple.beam", erl_abstract_code),
ok = file:delete(".erlang.crypt"),
beam_lib:clear_crypto_key_fun(),
{error,beam_lib,{key_missing_or_invalid,"simple.beam",abstract_code}} =
@@ -538,9 +607,10 @@ encrypted_abstr_no_crypto(Simple, Target) ->
{outdir,TargetDir},report]),
ok.
-verify_abstract(Target) ->
- {ok,{simple,[Chunk]}} = beam_lib:chunks(Target, [abstract_code]),
- {abstract_code,{raw_abstract_v1,_}} = Chunk.
+verify_abstract(Beam, Backend) ->
+ {ok,{simple,[Abst, Dbgi]}} = beam_lib:chunks(Beam, [abstract_code, debug_info]),
+ {abstract_code,{raw_abstract_v1,_}} = Abst,
+ {debug_info,{debug_info_v1,Backend,_}} = Dbgi.
has_crypto() ->
try
@@ -559,6 +629,26 @@ install_crypto_key(Key) ->
ok = beam_lib:crypto_key_fun(F).
%% Miscellanous tests, mainly to get better coverage.
+debug_info(erlang_v1, Module, ok, _Opts) ->
+ {ok, [Module]};
+debug_info(erlang_v1, _Module, error, _Opts) ->
+ {error, unknown_format}.
+
+custom_debug_info(Config) when is_list(Config) ->
+ {Simple,_} = get_files(Config, simple, "file_1"),
+
+ {ok,simple,OkBin} = compile:file(Simple, [binary, {debug_info,{?MODULE,ok}}]), %Coverage
+ {ok,{simple,[{abstract_code,{raw_abstract_v1,[simple]}}]}} =
+ beam_lib:chunks(OkBin, [abstract_code]),
+ {ok,{simple,[{debug_info,{debug_info_v1,?MODULE,ok}}]}} =
+ beam_lib:chunks(OkBin, [debug_info]),
+
+ {ok,simple,ErrorBin} = compile:file(Simple, [binary, {debug_info,{?MODULE,error}}]), %Coverage
+ {ok,{simple,[{abstract_code,no_abstract_code}]}} =
+ beam_lib:chunks(ErrorBin, [abstract_code]),
+ {ok,{simple,[{debug_info,{debug_info_v1,?MODULE,error}}]}} =
+ beam_lib:chunks(ErrorBin, [debug_info]).
+
cover(Config) when is_list(Config) ->
io:format("~p\n", [compile:options()]),
ok.
@@ -648,6 +738,49 @@ test_sloppy() ->
{1,2} = record_access:test(Turtle),
Turtle.
+utf8_atoms(Config) when is_list(Config) ->
+ Anno = erl_anno:new(1),
+ Atom = binary_to_atom(<<"こんにちは"/utf8>>, utf8),
+ Forms = [{attribute,Anno,compile,[export_all]},
+ {function,Anno,atom,0,[{clause,Anno,[],[],[{atom,Anno,Atom}]}]}],
+
+ Utf8AtomForms = [{attribute,Anno,module,utf8_atom}|Forms],
+ {ok,utf8_atom,Utf8AtomBin} =
+ compile:forms(Utf8AtomForms, [binary]),
+ {ok,{utf8_atom,[{atoms,_}]}} =
+ beam_lib:chunks(Utf8AtomBin, [atoms]),
+ code:load_binary(utf8_atom, "compile_SUITE", Utf8AtomBin),
+ Atom = utf8_atom:atom(),
+
+ NoUtf8AtomForms = [{attribute,Anno,module,no_utf8_atom}|Forms],
+ error = compile:forms(NoUtf8AtomForms, [binary, r19]).
+
+utf8_functions(Config) when is_list(Config) ->
+ Anno = erl_anno:new(1),
+ Atom = binary_to_atom(<<"こんにちは"/utf8>>, utf8),
+ Forms = [{attribute,Anno,compile,[export_all]},
+ {function,Anno,Atom,0,[{clause,Anno,[],[],[{atom,Anno,world}]}]}],
+
+ Utf8FunctionForms = [{attribute,Anno,module,utf8_function}|Forms],
+ {ok,utf8_function,Utf8FunctionBin} =
+ compile:forms(Utf8FunctionForms, [binary]),
+ {ok,{utf8_function,[{atoms,_}]}} =
+ beam_lib:chunks(Utf8FunctionBin, [atoms]),
+ code:load_binary(utf8_function, "compile_SUITE", Utf8FunctionBin),
+ world = utf8_function:Atom(),
+
+ NoUtf8FunctionForms = [{attribute,Anno,module,no_utf8_function}|Forms],
+ error = compile:forms(NoUtf8FunctionForms, [binary, r19]).
+
+extra_chunks(Config) when is_list(Config) ->
+ Anno = erl_anno:new(1),
+ Forms = [{attribute,Anno,module,extra_chunks}],
+
+ {ok,extra_chunks,ExtraChunksBinary} =
+ compile:forms(Forms, [binary, {extra_chunks, [{<<"ExCh">>, <<"Contents">>}]}]),
+ {ok,{extra_chunks,[{"ExCh",<<"Contents">>}]}} =
+ beam_lib:chunks(ExtraChunksBinary, ["ExCh"]).
+
env(Config) when is_list(Config) ->
{Simple,Target} = get_files(Config, simple, env),
{ok,Cwd} = file:get_cwd(),
@@ -689,9 +822,9 @@ env_1(Simple, Target) ->
%% Test pretty-printing in Core Erlang format and then try to
%% compile the generated Core Erlang files.
-core(Config) when is_list(Config) ->
+core_pp(Config) when is_list(Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
- Outdir = filename:join(PrivDir, "core"),
+ Outdir = filename:join(PrivDir, atom_to_list(?FUNCTION_NAME)),
ok = file:make_dir(Outdir),
TestBeams = get_unique_beam_files(),
@@ -699,11 +832,11 @@ core(Config) when is_list(Config) ->
{raw_abstract_v1,Abstr}}]}} =
beam_lib:chunks(Beam, [abstract_code]),
{Mod,Abstr} end || Beam <- TestBeams],
- test_lib:p_run(fun(F) -> do_core(F, Outdir) end, Abstr).
+ test_lib:p_run(fun(F) -> do_core_pp(F, Outdir) end, Abstr).
-do_core({M,A}, Outdir) ->
+do_core_pp({M,A}, Outdir) ->
try
- do_core_1(M, A, Outdir)
+ do_core_pp_1(M, A, Outdir)
catch
throw:{error,Error} ->
io:format("*** compilation failure '~p' for module ~s\n",
@@ -715,11 +848,11 @@ do_core({M,A}, Outdir) ->
error
end.
-do_core_1(M, A, Outdir) ->
+do_core_pp_1(M, A, Outdir) ->
{ok,M,Core0} = compile:forms(A, [to_core]),
CoreFile = filename:join(Outdir, atom_to_list(M)++".core"),
CorePP = core_pp:format(Core0),
- ok = file:write_file(CoreFile, CorePP),
+ ok = file:write_file(CoreFile, unicode:characters_to_binary(CorePP)),
%% Parse the .core file and return the result as Core Erlang Terms.
Core = case compile:file(CoreFile, [report_errors,from_core,no_copt,to_core,binary]) of
@@ -729,7 +862,7 @@ do_core_1(M, A, Outdir) ->
ok = file:delete(CoreFile),
%% Compile as usual (including optimizations).
- compile_forms(Core, [clint,from_core,binary]),
+ compile_forms(M, Core, [clint,from_core,binary]),
%% Don't optimize to test that we are not dependent
%% on the Core Erlang optmimization passes.
@@ -738,13 +871,13 @@ do_core_1(M, A, Outdir) ->
%% records; if sys_core_fold was run it would fix
%% that; if sys_core_fold was not run v3_kernel would
%% crash.)
- compile_forms(Core, [clint,from_core,no_copt,binary]),
+ compile_forms(M, Core, [clint,from_core,no_copt,binary]),
ok.
-compile_forms(Forms, Opts) ->
+compile_forms(Mod, Forms, Opts) ->
case compile:forms(Forms, [report_errors|Opts]) of
- {ok,[],_} -> ok;
+ {ok,Mod,_} -> ok;
Other -> throw({error,Other})
end.
@@ -791,7 +924,7 @@ do_core_roundtrip_1(Mod, Abstr, Outdir) ->
do_core_roundtrip_2(M, Core0, Outdir) ->
CoreFile = filename:join(Outdir, atom_to_list(M)++".core"),
CorePP = core_pp:format_all(Core0),
- ok = file:write_file(CoreFile, CorePP),
+ ok = file:write_file(CoreFile, unicode:characters_to_binary(CorePP)),
%% Parse the .core file and return the result as Core Erlang Terms.
Core2 = case compile:file(CoreFile, [report_errors,from_core,
@@ -805,9 +938,7 @@ do_core_roundtrip_2(M, Core0, Outdir) ->
case cmp_core(Core0, Core, M) of
true -> ok;
false -> error
- end,
-
- ok.
+ end.
undo_var_translation(Tree) ->
F = fun(Node) ->
@@ -860,11 +991,72 @@ diff(E, E) ->
diff([H1|T1], [H2|T2]) ->
[diff(H1, H2)|diff(T1, T2)];
diff(T1, T2) when tuple_size(T1) =:= tuple_size(T2) ->
- L = diff(tuple_to_list(T1), tuple_to_list(T2)),
- list_to_tuple(L);
+ case cerl:is_c_var(T1) andalso cerl:is_c_var(T2) of
+ true ->
+ diff_var(T1, T2);
+ false ->
+ case cerl:is_c_map(T1) andalso cerl:is_c_map(T2) of
+ true ->
+ diff_map(T1, T2);
+ false ->
+ diff_tuple(T1, T2)
+ end
+ end;
diff(E1, E2) ->
{'DIFF',E1,E2}.
+diff_var(V1, V2) ->
+ case {cerl:var_name(V1),cerl:var_name(V2)} of
+ {Same,Same} ->
+ V1;
+ {Name1,Name2} ->
+ %% The inliner uses integers as variable names. Such integers
+ %% are read back as atoms.
+ case is_integer(Name1) andalso
+ list_to_atom(integer_to_list(Name1)) =:= Name2 of
+ true ->
+ V1;
+ _ ->
+ cerl:update_c_var(V1, {'DIFF',Name1,Name2})
+ end
+ end.
+
+%% Annotations for maps are not preserved exactly, but that is not
+%% a real problem. Workaround by not comparing all annotations when
+%% comparing maps.
+
+diff_map(M, M) ->
+ M;
+diff_map(M1, M2) ->
+ case cerl:get_ann(M1) =:= cerl:get_ann(M2) of
+ false ->
+ diff_tuple(M1, M2);
+ true ->
+ case remove_compiler_gen(M1) =:= remove_compiler_gen(M2) of
+ true ->
+ M1;
+ false ->
+ diff_tuple(M1, M2)
+ end
+ end.
+
+diff_tuple(T1, T2) ->
+ L = diff(tuple_to_list(T1), tuple_to_list(T2)),
+ list_to_tuple(L).
+
+remove_compiler_gen(M) ->
+ Arg0 = cerl:map_arg(M),
+ Arg = cerl:set_ann(Arg0, []),
+ Es0 = cerl:map_es(M),
+ Es = [remove_compiler_gen_1(Pair) || Pair <- Es0],
+ cerl:update_c_map(M, Arg, Es).
+
+remove_compiler_gen_1(Pair) ->
+ Op0 = cerl:map_pair_op(Pair),
+ Op = cerl:set_ann(Op0, []),
+ K = cerl:map_pair_key(Pair),
+ V = cerl:map_pair_val(Pair),
+ cerl:update_c_map_pair(Pair, Op, K, V).
%% Compile to Beam assembly language (.S) and then try to
%% run .S through the compiler again.
@@ -902,6 +1094,96 @@ do_asm(Beam, Outdir) ->
error
end.
+%% Make sure that guards are fully optimized. Guards should
+%% should use 'test' instructions, not 'bif' instructions.
+
+optimized_guards(_Config) ->
+ TestBeams = get_unique_beam_files(),
+ test_lib:p_run(fun(F) -> do_opt_guards(F) end, TestBeams).
+
+do_opt_guards(Beam) ->
+ {ok,{M,[{abstract_code,{raw_abstract_v1,A}}]}} =
+ beam_lib:chunks(Beam, [abstract_code]),
+ try
+ {ok,M,Asm} = compile:forms(A, ['S']),
+ do_opt_guards_mod(Asm)
+ catch Class:Error ->
+ io:format("~p: ~p ~p\n~p\n",
+ [M,Class,Error,erlang:get_stacktrace()]),
+ error
+ end.
+
+do_opt_guards_mod({Mod,_Exp,_Attr,Asm,_NumLabels}) ->
+ case do_opt_guards_fs(Mod, Asm) of
+ [] ->
+ ok;
+ [_|_]=Bifs ->
+ io:format("ERRORS FOR ~p:\n~p\n", [Mod,Bifs]),
+ error
+ end.
+
+do_opt_guards_fs(Mod, [{function,Name,Arity,_,Is}|Fs]) ->
+ Bifs0 = do_opt_guards_fun(Is),
+
+ %% The compiler does not attempt to optimize 'xor'.
+ %% Therefore, ignore all functions that use 'xor' in
+ %% a guard.
+ Bifs = case lists:any(fun({bif,'xor',_,_,_}) -> true;
+ (_) -> false
+ end, Bifs0) of
+ true -> [];
+ false -> Bifs0
+ end,
+
+ %% Filter out the allowed exceptions.
+ FA = {Name,Arity},
+ case {Bifs,is_exception(Mod, FA)} of
+ {[_|_],true} ->
+ io:format("~p:~p/~p IGNORED:\n~p\n",
+ [Mod,Name,Arity,Bifs]),
+ do_opt_guards_fs(Mod, Fs);
+ {[_|_],false} ->
+ [{FA,Bifs}|do_opt_guards_fs(Mod, Fs)];
+ {[],false} ->
+ do_opt_guards_fs(Mod, Fs);
+ {[],true} ->
+ io:format("Redundant exception for ~p:~p/~p\n",
+ [Mod,Name,Arity]),
+ error(redundant)
+ end;
+do_opt_guards_fs(_, []) -> [].
+
+do_opt_guards_fun([{bif,Name,{f,F},As,_}=I|Is]) when F =/= 0 ->
+ Arity = length(As),
+ case erl_internal:comp_op(Name, Arity) orelse
+ erl_internal:bool_op(Name, Arity) orelse
+ erl_internal:new_type_test(Name, Arity) of
+ true ->
+ [I|do_opt_guards_fun(Is)];
+ false ->
+ do_opt_guards_fun(Is)
+ end;
+do_opt_guards_fun([_|Is]) ->
+ do_opt_guards_fun(Is);
+do_opt_guards_fun([]) -> [].
+
+is_exception(bs_match_SUITE, {matching_and_andalso_2,2}) -> true;
+is_exception(bs_match_SUITE, {matching_and_andalso_3,2}) -> true;
+is_exception(guard_SUITE, {'-complex_not/1-fun-4-',1}) -> true;
+is_exception(guard_SUITE, {'-complex_not/1-fun-5-',1}) -> true;
+is_exception(guard_SUITE, {basic_andalso_orelse,1}) -> true;
+is_exception(guard_SUITE, {bad_guards,1}) -> true;
+is_exception(guard_SUITE, {bad_guards_2,2}) -> true;
+is_exception(guard_SUITE, {bad_guards_3,2}) -> true;
+is_exception(guard_SUITE, {cqlc,4}) -> true;
+is_exception(guard_SUITE, {csemi7,3}) -> true;
+is_exception(guard_SUITE, {misc,1}) -> true;
+is_exception(guard_SUITE, {nested_not_2b,4}) -> true;
+is_exception(guard_SUITE, {tricky_1,2}) -> true;
+is_exception(map_SUITE, {map_guard_update,2}) -> true;
+is_exception(map_SUITE, {map_guard_update_variables,3}) -> true;
+is_exception(_, _) -> false.
+
sys_pre_attributes(Config) ->
DataDir = proplists:get_value(data_dir, Config),
File = filename:join(DataDir, "attributes.erl"),
@@ -1110,6 +1392,47 @@ env_compiler_options(_Config) ->
end,
lists:foreach(F, Cases).
+%% Test options for compatibility with previous major versions of OTP.
+
+bc_options(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+
+ 101 = highest_opcode(DataDir, small_float, [no_line_info]),
+
+ 103 = highest_opcode(DataDir, big,
+ [no_record_opt,no_line_info,no_stack_trimming]),
+
+ 125 = highest_opcode(DataDir, small_float, [no_line_info,no_float_opt]),
+
+ 132 = highest_opcode(DataDir, small,
+ [no_record_opt,no_float_opt,no_line_info]),
+
+ 136 = highest_opcode(DataDir, big, [no_record_opt,no_line_info]),
+
+ 153 = highest_opcode(DataDir, big, [no_record_opt]),
+ 153 = highest_opcode(DataDir, big, [r16]),
+ 153 = highest_opcode(DataDir, big, [r17]),
+ 153 = highest_opcode(DataDir, big, [r18]),
+ 153 = highest_opcode(DataDir, big, [r19]),
+ 153 = highest_opcode(DataDir, small_float, [r16]),
+ 153 = highest_opcode(DataDir, small_float, []),
+
+ 158 = highest_opcode(DataDir, small_maps, [r17]),
+ 158 = highest_opcode(DataDir, small_maps, [r18]),
+ 158 = highest_opcode(DataDir, small_maps, [r19]),
+ 158 = highest_opcode(DataDir, small_maps, []),
+
+ 159 = highest_opcode(DataDir, big, []),
+
+ ok.
+
+highest_opcode(DataDir, Mod, Opt) ->
+ Src = filename:join(DataDir, atom_to_list(Mod)++".erl"),
+ {ok,Mod,Beam} = compile:file(Src, [binary|Opt]),
+ {ok,{Mod,[{"Code",Code}]}} = beam_lib:chunks(Beam, ["Code"]),
+ <<16:32,0:32,HighestOpcode:32,_/binary>> = Code,
+ HighestOpcode.
+
%%%
%%% Utilities.
%%%
@@ -1127,8 +1450,15 @@ get_unique_beam_files() ->
get_unique_files(Ext) ->
Wc = filename:join(filename:dirname(code:which(?MODULE)), "*"++Ext),
- [F || F <- filelib:wildcard(Wc), not is_cloned(F, Ext)].
+ [F || F <- filelib:wildcard(Wc),
+ not is_cloned(F, Ext), not is_lfe_module(F, Ext)].
is_cloned(File, Ext) ->
Mod = list_to_atom(filename:basename(File, Ext)),
test_lib:is_cloned_mod(Mod).
+
+is_lfe_module(File, Ext) ->
+ case filename:basename(File, Ext) of
+ "lfe_" ++ _ -> true;
+ _ -> false
+ end.
diff --git a/lib/compiler/test/compile_SUITE_data/simple.erl b/lib/compiler/test/compile_SUITE_data/simple.erl
index d8324dafaf..9385d101e0 100644
--- a/lib/compiler/test/compile_SUITE_data/simple.erl
+++ b/lib/compiler/test/compile_SUITE_data/simple.erl
@@ -19,7 +19,7 @@
%%
-module(simple).
--export([test/0]).
+-export([test/0,unicode/0]).
-ifdef(need_foo).
-export([foo/0]).
@@ -28,6 +28,9 @@
test() ->
passed.
+unicode() ->
+ {"это",'спутник'}.
+
%% Conditional inclusion.
%% Compile with [{d, need_foo}, {d, foo_value, 42}].
diff --git a/lib/compiler/test/compile_SUITE_data/small_float.erl b/lib/compiler/test/compile_SUITE_data/small_float.erl
new file mode 100644
index 0000000000..5cbb5aef83
--- /dev/null
+++ b/lib/compiler/test/compile_SUITE_data/small_float.erl
@@ -0,0 +1,5 @@
+-module(small_float).
+-export([f/1]).
+
+f(F) when is_float(F) ->
+ F / 2.
diff --git a/lib/compiler/test/core_SUITE.erl b/lib/compiler/test/core_SUITE.erl
index b768f49e2c..f8839da42f 100644
--- a/lib/compiler/test/core_SUITE.erl
+++ b/lib/compiler/test/core_SUITE.erl
@@ -26,8 +26,9 @@
seq_in_guard/1,make_effect_seq/1,eval_is_boolean/1,
unsafe_case/1,nomatch_shadow/1,reversed_annos/1,
map_core_test/1,eval_case/1,bad_boolean_guard/1,
- bs_shadowed_size_var/1
- ]).
+ bs_shadowed_size_var/1,
+ cover_v3_kernel_1/1,cover_v3_kernel_2/1,cover_v3_kernel_3/1,
+ cover_v3_kernel_4/1,cover_v3_kernel_5/1]).
-include_lib("common_test/include/ct.hrl").
@@ -53,8 +54,10 @@ groups() ->
[dehydrated_itracer,nested_tries,seq_in_guard,make_effect_seq,
eval_is_boolean,unsafe_case,nomatch_shadow,reversed_annos,
map_core_test,eval_case,bad_boolean_guard,
- bs_shadowed_size_var
- ]}].
+ bs_shadowed_size_var,
+ cover_v3_kernel_1,cover_v3_kernel_2,cover_v3_kernel_3,
+ cover_v3_kernel_4,cover_v3_kernel_5
+ ]}].
init_per_suite(Config) ->
@@ -64,10 +67,10 @@ end_per_suite(_Config) ->
ok.
init_per_group(_GroupName, Config) ->
- Config.
+ Config.
end_per_group(_GroupName, Config) ->
- Config.
+ Config.
?comp(dehydrated_itracer).
@@ -82,6 +85,11 @@ end_per_group(_GroupName, Config) ->
?comp(eval_case).
?comp(bad_boolean_guard).
?comp(bs_shadowed_size_var).
+?comp(cover_v3_kernel_1).
+?comp(cover_v3_kernel_2).
+?comp(cover_v3_kernel_3).
+?comp(cover_v3_kernel_4).
+?comp(cover_v3_kernel_5).
try_it(Mod, Conf) ->
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core
new file mode 100644
index 0000000000..9e5788796f
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core
@@ -0,0 +1,147 @@
+module 'cover_v3_kernel_1' ['cover_v3_kernel_1'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_1'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'bad_and_args'/1
+ ('x') of
+ <'error'> when 'true' ->
+ %% Line 7
+ case apply 'bad_and_args'/2
+ (1, 2) of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'bad_and_args'/2
+ (1, 'true') of
+ <'error'> when 'true' ->
+ %% Line 9
+ case apply 'bad_and_args'/2
+ ('true', 42) of
+ <'error'> when 'true' ->
+ %% Line 10
+ case apply 'bad_and_args'/2
+ ('true', 'false') of
+ <'error'> when 'true' ->
+ %% Line 11
+ case apply 'bad_and_args'/2
+ ('false', 'true') of
+ <'error'> when 'true' ->
+ %% Line 12
+ case apply 'bad_and_args'/2
+ ('true', 'true') of
+ <'ok'> when 'true' ->
+ %% Line 14
+ 'ok'
+ ( <_@c6> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c6})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c5> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c5})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c4})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c3})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c2})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c1})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_1',0}}] )
+ -| ['compiler_generated'] )
+ end
+'bad_and_args'/1 =
+ %% Line 16
+ fun (_@c0) ->
+ case _@c0 of
+ <A>
+ when try
+ call 'erlang':'and'(A, 42)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ %% Line 17
+ <_@c4> when 'true' ->
+ 'error'
+ ( <_@c3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_@c3})
+ -| [{'function_name',{'bad_and_args',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bad_and_args'/2 =
+ %% Line 19
+ fun (_@c1,_@c0) ->
+ case <_@c1,_@c0> of
+ <X,Y>
+ when try
+ call 'erlang':'and'(X, Y)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ %% Line 20
+ <_@c6,_@c7> when 'true' ->
+ 'error'
+ ( <_@c5,_@c4> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_@c5,_@c4})
+ -| [{'function_name',{'bad_and_args',2}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_1')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_@c0) ->
+ case _@c0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_1', X)
+ ( <_@c1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_@c1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core
new file mode 100644
index 0000000000..165aacd691
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core
@@ -0,0 +1,98 @@
+module 'cover_v3_kernel_2' ['cover_v3_kernel_2'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_2'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'strange_case'/1
+ ('a') of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'strange_case'/1
+ ('b') of
+ <'ok'> when 'true' ->
+ %% Line 7
+ case apply 'strange_case'/1
+ ('c') of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'strange_case'/1
+ (42) of
+ <'error'> when 'true' ->
+ %% Line 9
+ 'ok'
+ ( <_cor3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor3})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor2})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor1})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_2',0}}] )
+ -| ['compiler_generated'] )
+ end
+'strange_case'/1 =
+ %% Line 12
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when
+ case X of
+ <'a'> when 'true' -> 'true'
+ <'b'> when 'true' -> 'true'
+ <Other> when 'true' -> 'false'
+ end ->
+ 'ok'
+ %% Line 13
+ <_cor4> when 'true' ->
+ 'error'
+ ( <_cor3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor3})
+ -| [{'function_name',{'strange_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_2')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_2', X)
+ ( <_cor1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core
new file mode 100644
index 0000000000..88a9edc354
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core
@@ -0,0 +1,98 @@
+module 'cover_v3_kernel_3' ['cover_v3_kernel_3'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_3'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'strange_case'/1
+ (1) of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'strange_case'/1
+ (2) of
+ <'ok'> when 'true' ->
+ %% Line 7
+ case apply 'strange_case'/1
+ (42) of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'strange_case'/1
+ ('atom') of
+ <'error'> when 'true' ->
+ %% Line 9
+ 'ok'
+ ( <_cor3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor3})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor2})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor1})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_3',0}}] )
+ -| ['compiler_generated'] )
+ end
+'strange_case'/1 =
+ %% Line 12
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when
+ case X of
+ <1> when 'true' -> 'true'
+ <2> when 'true' -> 'true'
+ <Other> when 'true' -> 'false'
+ end ->
+ 'ok'
+ %% Line 13
+ <_cor4> when 'true' ->
+ 'error'
+ ( <_cor3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor3})
+ -| [{'function_name',{'strange_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_3')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_3', X)
+ ( <_cor1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core
new file mode 100644
index 0000000000..905e236f26
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core
@@ -0,0 +1,82 @@
+module 'cover_v3_kernel_4' ['cover_v3_kernel_4'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_4'/0 =
+ %% Line 4
+ fun () ->
+ %% Line 5
+ case apply 'turned_case'/1
+ (20) of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'turned_case'/1
+ (0) of
+ <'error'> when 'true' ->
+ %% Line 7
+ 'ok'
+ ( <_@c1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c1})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c0})
+ -| ['compiler_generated'] )
+ end
+'turned_case'/1 =
+ %% Line 9
+ fun (_@c0) ->
+ let <True> =
+ apply %% Line 10
+ 'id'/1
+ (%% Line 10
+ 'true')
+ in %% Line 11
+ case <> of
+ %% Line 12
+ <>
+ when try
+ ( let <_@c4> =
+ case call 'erlang':'<'
+ (_@c0, 10) of
+ ( <( 'false'
+ -| ['compiler_generated'] )> when 'true' ->
+ True
+ -| ['compiler_generated'] )
+ ( <( 'true'
+ -| ['compiler_generated'] )> when 'true' ->
+ 'false'
+ -| ['compiler_generated'] )
+ ( <_@c2> when 'true' ->
+ _@c2
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (( _@c4
+ -| ['compiler_generated'] ), 'true')
+ -| ['compiler_generated'] )
+ -| ['compiler_generated'] )
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ %% Line 13
+ <> when 'true' ->
+ 'error'
+ end
+'id'/1 =
+ %% Line 16
+ fun (_@c0) ->
+ _@c0
+'module_info'/0 =
+ fun () ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_4')
+'module_info'/1 =
+ fun (_@c0) ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_4', _@c0)
+end \ No newline at end of file
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core
new file mode 100644
index 0000000000..48c1bb84e6
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core
@@ -0,0 +1,98 @@
+module 'cover_v3_kernel_5' ['cover_v3_kernel_5'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_5'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'strange_case'/1
+ (1) of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'strange_case'/1
+ (2) of
+ <'ok'> when 'true' ->
+ %% Line 7
+ case apply 'strange_case'/1
+ (42) of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'strange_case'/1
+ ('atom') of
+ <'error'> when 'true' ->
+ %% Line 9
+ 'ok'
+ ( <_cor3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor3})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor2})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor1})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_5',0}}] )
+ -| ['compiler_generated'] )
+ end
+'strange_case'/1 =
+ %% Line 12
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when
+ case X of
+ <1> when 'true' -> 'true'
+ <2> when 'true' -> 'true'
+ <Other> when 'true' -> X
+ end ->
+ 'ok'
+ %% Line 13
+ <_cor4> when 'true' ->
+ 'error'
+ ( <_cor3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor3})
+ -| [{'function_name',{'strange_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_5')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_5', X)
+ ( <_cor1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl
index 376d2c8e9a..0097e28d4d 100644
--- a/lib/compiler/test/core_fold_SUITE.erl
+++ b/lib/compiler/test/core_fold_SUITE.erl
@@ -26,7 +26,7 @@
unused_multiple_values_error/1,unused_multiple_values/1,
multiple_aliases/1,redundant_boolean_clauses/1,
mixed_matching_clauses/1,unnecessary_building/1,
- no_no_file/1]).
+ no_no_file/1,configuration/1,supplies/1]).
-export([foo/0,foo/1,foo/2,foo/3]).
@@ -45,7 +45,7 @@ groups() ->
unused_multiple_values_error,unused_multiple_values,
multiple_aliases,redundant_boolean_clauses,
mixed_matching_clauses,unnecessary_building,
- no_no_file]}].
+ no_no_file,configuration,supplies]}].
init_per_suite(Config) ->
@@ -499,4 +499,32 @@ experiment() ->
end,
ok.
+
+%% Make sure we don't try to move a fun into a guard.
+configuration(_Config) ->
+ {'EXIT',_} = (catch configuration()),
+ ok.
+
+configuration() ->
+ [forgotten || Components <- enemy, is_tuple(fun art/0)].
+
+art() ->
+ creating.
+
+%% core_lint would complain after optimization. A call to error/1
+%% must not occur unconditionally in a guard.
+supplies(_Config) ->
+ case ?MODULE of
+ core_fold_inline_SUITE ->
+ %% Other error behaviour when inlined.
+ ok;
+ _ ->
+ {'EXIT',{function_clause,_}} = (catch do_supplies(#{1 => <<1,2,3>>})),
+ {'EXIT',{function_clause,_}} = (catch do_supplies(#{1 => a})),
+ {'EXIT',{function_clause,_}} = (catch do_supplies(42)),
+ ok
+ end.
+
+do_supplies(#{1 := Value}) when byte_size(Value), byte_size(kg) -> working.
+
id(I) -> I.
diff --git a/lib/compiler/test/float_SUITE.erl b/lib/compiler/test/float_SUITE.erl
index f6095947ca..08c3dd8593 100644
--- a/lib/compiler/test/float_SUITE.erl
+++ b/lib/compiler/test/float_SUITE.erl
@@ -150,6 +150,18 @@ math_functions(Config) when is_list(Config) ->
?OPTIONAL(0.0, math:erf(id(0))),
?OPTIONAL(1.0, math:erfc(id(0))),
+ 5.0 = math:floor(5.6),
+ 6.0 = math:ceil(5.6),
+ 5.0 = math:floor(id(5.4)),
+ 6.0 = math:ceil(id(5.4)),
+
+ 0.0 = math:fmod(42, 42),
+ 0.25 = math:fmod(1, 0.75),
+ -1.0 = math:fmod(-4.0, 1.5),
+ -0.375 = math:fmod(-3.0, -0.875),
+ 0.125 = math:fmod(8.125, -4),
+ {'EXIT',{badarith,_}} = (catch math:fmod(5.0, 0.0)),
+
%% Only for coverage (of beam_type.erl).
{'EXIT',{undef,_}} = (catch math:fnurfla(0)),
{'EXIT',{undef,_}} = (catch math:fnurfla(0, 0)),
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 6302f82f29..ccb9b58225 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@
basic_andalso_orelse/1,traverse_dcd/1,
check_qlc_hrl/1,andalso_semi/1,t_tuple_size/1,binary_part/1,
bad_constants/1,bad_guards/1,
- guard_in_catch/1]).
+ guard_in_catch/1,beam_bool_SUITE/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -54,7 +54,7 @@ groups() ->
rel_ops,rel_op_combinations,
literal_type_tests,basic_andalso_orelse,traverse_dcd,
check_qlc_hrl,andalso_semi,t_tuple_size,binary_part,
- bad_constants,bad_guards,guard_in_catch]}].
+ bad_constants,bad_guards,guard_in_catch,beam_bool_SUITE]}].
init_per_suite(Config) ->
Config.
@@ -87,8 +87,32 @@ misc(Config) when is_list(Config) ->
{ok,buf,<<>>} = get_data({o,true,0}, 42, buf),
{ok,buf,<<>>} = get_data({o,false,0}, 0, buf),
error = get_data({o,false,0}, 42, buf),
+
+ relief = misc_2(0),
+ error = misc_2(1),
+ error = misc_2(true),
+
+ if
+ is_integer(Config) =/= true ->
+ ok
+ end,
+
+ true = misc_3(1, 0),
+ true = misc_3(0, 0),
+ false = misc_3(0, 2),
+
+ %% Abuse of boolean values.
+
+ Zero = id(0),
+ One = id(1),
+ ok = if (Zero == 0) > false -> ok end,
+ ok = if (Zero == 0) =:= (One == 1) -> ok end,
+ ok = if (Zero == 0) =:= (One == 1) -> ok end,
+ ok = if is_atom(Zero > One) -> ok end,
+ error = if abs(Zero > One) -> ok; true -> error end,
+ ok = if is_integer(Zero) >= is_integer(One) -> ok end,
+
ok.
-
misc_1([{W},{X},{Y},{Z}]) ->
if
@@ -98,6 +122,17 @@ misc_1([{W},{X},{Y},{Z}]) ->
none
end.
+misc_2(0) -> relief;
+misc_2(Adapter = 1) when Adapter -> franklin;
+misc_2(_) -> error.
+
+misc_3(LenUp, LenDw) ->
+ if
+ %% Cover handling of #k_alt{}.
+ LenUp >= 1 orelse ((LenDw >= 2) xor true) -> true;
+ true -> false
+ end.
+
get_data({o,Active,Raw}, BytesToRead, Buffer)
when Raw =:= raw; Raw =:= 0 ->
if
@@ -163,6 +198,12 @@ basic_not(Config) when is_list(Config) ->
check(fun() -> if not glurf -> ok; true -> error end end, error),
check(fun() -> if not Glurf -> ok; true -> error end end, error),
+ check(fun() -> if not (not true) -> broken end end, broken),
+
+ check(fun() -> if not (True xor True) -> ok end end, ok),
+ check(fun() -> if not (True xor False) -> ok;
+ true -> error end end, error),
+
ok.
complex_not(Config) when is_list(Config) ->
@@ -187,8 +228,60 @@ complex_not(Config) when is_list(Config) ->
check(fun() -> if not(element(1, ATuple) orelse element(3, ATuple)) -> ok;
true -> error end end, error),
+ %% complex_not_1/4
+ ok = complex_not_1(1, 1, 1, a),
+ error = complex_not_1(1, 1, 1, []),
+ error = complex_not_1(1, 1, 3, a),
+ error = complex_not_1(1, 1, 3, []),
+ error = complex_not_1(1, 2, 1, a),
+ error = complex_not_1(1, 2, 1, []),
+ error = complex_not_1(1, 2, 3, a),
+ error = complex_not_1(1, 2, 3, []),
+
+ %% complex_not_2/4
+ ok = complex_not_2(1, 2, 0, x),
+ error = complex_not_2(1, 2, 0, []),
+ error = complex_not_2(1, 2, 3, x),
+ error = complex_not_2(1, 2, 3, []),
+ error = complex_not_2(1, 1, 0, x),
+ error = complex_not_2(1, 1, 0, []),
+ error = complex_not_2(1, 1, 3, x),
+ error = complex_not_2(1, 1, 3, []),
+
ok.
+complex_not_1(A, B, C, D) ->
+ Res = complex_not_1a(A, B, C, D),
+ Res = complex_not_1b(A, B, C, D).
+
+complex_not_1a(A, B, C, D)
+ when (not (A < B)) andalso (not (B < C)) andalso (not is_list(D)) ->
+ ok;
+complex_not_1a(_, _, _, _) ->
+ error.
+
+complex_not_1b(A, B, C, D)
+ when (not (A < B)) and (not (B < C)) and (not is_list(D)) ->
+ ok;
+complex_not_1b(_, _, _, _) ->
+ error.
+
+complex_not_2(A, B, C, D) ->
+ Res = complex_not_2a(A, B, C, D),
+ Res = complex_not_2b(A, B, C, D).
+
+complex_not_2a(A, B, C, D)
+ when A < B andalso not (B < C) andalso not is_list(D) ->
+ ok;
+complex_not_2a(_, _, _, _) ->
+ error.
+
+complex_not_2b(A, B, C, D)
+ when A < B, not (B < C), not is_list(D) ->
+ ok;
+complex_not_2b(_, _, _, _) ->
+ error.
+
nested_nots(Config) when is_list(Config) ->
true = nested_not_1(0, 0),
true = nested_not_1(0, 1),
@@ -209,19 +302,36 @@ nested_nots(Config) when is_list(Config) ->
false = nested_not_2(true, true, atom),
ok.
-nested_not_1(X, Y) when not (((X>Y) or not(is_atom(X))) and
+nested_not_1(X, Y) ->
+ Res = nested_not_1a(X, Y),
+ Res = nested_not_1b(X, Y).
+
+nested_not_1a(X, Y) when not (((X>Y) or not(is_atom(X))) and
(is_atom(Y) or (X==3.4))) ->
true;
-nested_not_1(_, _) ->
+nested_not_1a(_, _) ->
+ false.
+
+nested_not_1b(X, Y) when not (((X>Y) orelse not(is_atom(X))) andalso
+ (is_atom(Y) orelse (X==3.4))) ->
+ true;
+nested_not_1b(_, _) ->
false.
nested_not_2(X, Y, Z) ->
- nested_not_2(X, Y, Z, true).
+ Res = nested_not_2a(X, Y, Z, true),
+ Res = nested_not_2b(X, Y, Z, true).
-nested_not_2(X, Y, Z, True)
+nested_not_2a(X, Y, Z, True)
when not(True and not((not(X) and not(Y)) or not(is_atom(Z)))) ->
true;
-nested_not_2(_, _, _, _) ->
+nested_not_2a(_, _, _, _) ->
+ false.
+
+nested_not_2b(X, Y, Z, True)
+ when not(True andalso not((not(X) andalso not(Y)) orelse not(is_atom(Z)))) ->
+ true;
+nested_not_2b(_, _, _, _) ->
false.
semicolon(Config) when is_list(Config) ->
@@ -343,6 +453,11 @@ complex_semicolon(Config) when is_list(Config) ->
ok = csemi7(#{a=>1}, 3, 3),
ok = csemi7(#{a=>1, b=>3}, 0, 0),
+ %% 8: Make sure that funs cannot be copied into guards.
+ ok = csemi8(true),
+ error = csemi8(false),
+ error = csemi8(42),
+
ok.
csemi1(Type, Val) when is_list(Val), Type == float;
@@ -457,6 +572,13 @@ csemi6(_, _) -> error.
csemi7(A, B, C) when A#{a:=B} > #{a=>1}; abs(C) > 2 -> ok;
csemi7(_, _, _) -> error.
+csemi8(Together) ->
+ case fun csemi8/1 of
+ Typically when Together; Typically, Together -> ok;
+ _ -> error
+ end.
+
+
comma(Config) when is_list(Config) ->
%% ',' combinations of literal true/false.
@@ -1081,6 +1203,13 @@ tricky(Config) when is_list(Config) ->
false = rb(100000, [1], 42),
true = rb(100000, [], 42),
true = rb(555, [a,b,c], 19),
+
+ error = tricky_3(42),
+ error = tricky_3(42.0),
+ error = tricky_3(<<>>),
+ error = tricky_3(#{}),
+ error = tricky_3({a,b}),
+
ok.
tricky_1(X, Y) when abs((X == 1) or (Y == 2)) -> ok;
@@ -1089,6 +1218,15 @@ tricky_1(_, _) -> not_ok.
tricky_2(X) when float(X) or float(X) -> ok;
tricky_2(_) -> error.
+tricky_3(X)
+ when abs(X) or bit_size(X) or byte_size(X) or ceil(X) or
+ float(X) or floor(X) or length(X) or
+ map_size(X) or node() or node(X) or round(X) or
+ self() or size(X) or tl(X) or trunc(X) or tuple_size(X) ->
+ ok;
+tricky_3(_) ->
+ error.
+
%% From dets_v9:read_buckets/11, simplified.
rb(Size, ToRead, SoFar) when SoFar + Size < 81920; ToRead == [] -> true;
@@ -1400,7 +1538,7 @@ literal_type_tests_1(Config) ->
Func = {function, Anno, test, 0, [{clause,Anno,[],[],Tests}]},
Form = [{attribute,Anno,module,Mod},
{attribute,Anno,compile,export_all},
- Func, {eof,Anno}],
+ Func, {eof,999}],
%% Print generated code for inspection.
lists:foreach(fun (F) -> io:put_chars([erl_pp:form(F),"\n"]) end, Form),
@@ -1912,6 +2050,155 @@ do_guard_in_catch_bin(From) ->
saint
end.
+%%%
+%%% The beam_bool pass has been eliminated. Here are the tests from
+%%% beam_bool_SUITE.
+%%%
+
+beam_bool_SUITE(_Config) ->
+ before_and_inside_if(),
+ scotland(),
+ y_registers(),
+ protected(),
+ maps(),
+ ok.
+
+before_and_inside_if() ->
+ no = before_and_inside_if([a], [b], delete),
+ no = before_and_inside_if([a], [b], x),
+ no = before_and_inside_if([a], [], delete),
+ no = before_and_inside_if([a], [], x),
+ no = before_and_inside_if([], [], delete),
+ yes = before_and_inside_if([], [], x),
+ yes = before_and_inside_if([], [b], delete),
+ yes = before_and_inside_if([], [b], x),
+
+ {ch1,ch2} = before_and_inside_if_2([a], [b], blah),
+ {ch1,ch2} = before_and_inside_if_2([a], [b], xx),
+ {ch1,ch2} = before_and_inside_if_2([a], [], blah),
+ {ch1,ch2} = before_and_inside_if_2([a], [], xx),
+ {no,no} = before_and_inside_if_2([], [b], blah),
+ {no,no} = before_and_inside_if_2([], [b], xx),
+ {ch1,no} = before_and_inside_if_2([], [], blah),
+ {no,ch2} = before_and_inside_if_2([], [], xx),
+ ok.
+
+%% Thanks to Simon Cornish and Kostis Sagonas.
+%% Used to crash beam_bool.
+before_and_inside_if(XDo1, XDo2, Do3) ->
+ Do1 = (XDo1 =/= []),
+ Do2 = (XDo2 =/= []),
+ if
+ %% This expression occurs in a try/catch (protected)
+ %% block, which cannot refer to variables outside of
+ %% the block that are boolean expressions.
+ Do1 =:= true;
+ Do1 =:= false, Do2 =:= false, Do3 =:= delete ->
+ no;
+ true ->
+ yes
+ end.
+
+%% Thanks to Simon Cornish.
+%% Used to generate code that would not set {y,0} on
+%% all paths before its use (and therefore fail
+%% validation by the beam_validator).
+before_and_inside_if_2(XDo1, XDo2, Do3) ->
+ Do1 = (XDo1 =/= []),
+ Do2 = (XDo2 =/= []),
+ CH1 = if Do1 == true;
+ Do1 == false,Do2==false,Do3 == blah ->
+ ch1;
+ true ->
+ no
+ end,
+ CH2 = if Do1 == true;
+ Do1 == false,Do2==false,Do3 == xx ->
+ ch2;
+ true ->
+ no
+ end,
+ {CH1,CH2}.
+
+
+%% beam_bool would remove the initialization of {y,0}.
+%% (Thanks to Thomas Arts and QuickCheck.)
+
+scotland() ->
+ million = do_scotland(placed),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(false)),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(true)),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(echo)),
+ ok.
+
+do_scotland(Echo) ->
+ found(case Echo of
+ Echo when true; Echo, Echo, Echo ->
+ Echo;
+ echo ->
+ []
+ end,
+ Echo = placed).
+
+found(_, _) -> million.
+
+
+%% ERL-143: beam_bool could not handle Y registers as a destination.
+y_registers() ->
+ {'EXIT',{badarith,[_|_]}} = (catch baker(valentine)),
+ {'EXIT',{badarith,[_|_]}} = (catch baker(clementine)),
+
+ {not_ok,true} = potter([]),
+ {ok,false} = potter([{encoding,any}]),
+
+ ok.
+
+%% Thanks to Quickcheck.
+baker(Baker) ->
+ (valentine == Baker) +
+ case Baker of
+ Baker when Baker; Baker ->
+ Baker;
+ Baker ->
+ []
+ end.
+
+%% Thanks to Jose Valim.
+potter(Modes) ->
+ Raw = lists:keyfind(encoding, 1, Modes) == false,
+ Final = case Raw of
+ X when X == false; X == nil -> ok;
+ _ -> not_ok
+ end,
+ {Final,Raw}.
+
+protected() ->
+ {'EXIT',{if_clause,_}} = (catch photographs({1, surprise, true}, opinions)),
+
+ {{true}} = welcome({perfect, true}),
+ {'EXIT',{if_clause,_}} = (catch welcome({perfect, false})),
+ ok.
+
+photographs({_Violation, surprise, Deep}, opinions) ->
+ {if
+ 0; "here", Deep ->
+ Deep = Deep
+ end}.
+
+welcome({perfect, Profit}) ->
+ if
+ Profit, Profit, Profit; 0 ->
+ {id({Profit})}
+ end.
+
+maps() ->
+ ok = evidence(#{0 => 42}).
+
+%% Cover handling of put_map in in split_block_label_used/2.
+evidence(#{0 := Charge}) when 0; #{[] => Charge} == #{[] => 42} ->
+ ok.
+
+
%% Call this function to turn off constant propagation.
id(I) -> I.
diff --git a/lib/compiler/test/lc_SUITE.erl b/lib/compiler/test/lc_SUITE.erl
index 3cb49433ce..9ad417b09b 100644
--- a/lib/compiler/test/lc_SUITE.erl
+++ b/lib/compiler/test/lc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
%%
-module(lc_SUITE).
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+-export([all/0, suite/0, groups/0, init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
basic/1,deeply_nested/1,no_generator/1,
@@ -32,11 +32,11 @@ suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap,{minutes,1}}].
-all() ->
+all() ->
test_lib:recompile(?MODULE),
[{group,p}].
-groups() ->
+groups() ->
[{p,test_lib:parallel(),
[basic,
deeply_nested,
@@ -214,6 +214,7 @@ shadow(Config) when is_list(Config) ->
ok.
effect(Config) when is_list(Config) ->
+ ct:timetrap({minutes,10}),
[{42,{a,b,c}}] =
do_effect(fun(F, L) ->
[F({V1,V2}) ||
@@ -226,7 +227,7 @@ effect(Config) when is_list(Config) ->
lc_SUITE ->
_ = [{'EXIT',{badarg,_}} =
(catch binary_to_atom(<<C/utf8>>, utf8)) ||
- C <- lists:seq(16#10000, 16#FFFFF)];
+ C <- lists:seq(16#FF10000, 16#FFFFFFF)];
_ ->
ok
end,
@@ -240,7 +241,7 @@ do_effect(Lc, L) ->
lists:reverse(erase(?MODULE)).
id(I) -> I.
-
+
fc(Args, {'EXIT',{function_clause,[{?MODULE,_,Args,_}|_]}}) -> ok;
fc(Args, {'EXIT',{function_clause,[{?MODULE,_,Arity,_}|_]}})
when length(Args) =:= Arity ->
diff --git a/lib/compiler/test/lfe-core.patch b/lib/compiler/test/lfe-core.patch
new file mode 100644
index 0000000000..756d131e2c
--- /dev/null
+++ b/lib/compiler/test/lfe-core.patch
@@ -0,0 +1,97 @@
+Date: Sun, 13 Nov 2016 10:11:11 +0100
+Subject: [PATCH] Fix invalid variable names
+
+---
+ test/lfe_andor_SUITE.core | 16 ++++++++--------
+ test/lfe_guard_SUITE.core | 14 +++++++-------
+ 2 files changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/test/lfe_andor_SUITE.core b/test/lfe_andor_SUITE.core
+index 96ff765..df58b39 100644
+--- a/test/lfe_andor_SUITE.core
++++ b/test/lfe_andor_SUITE.core
+@@ -288,19 +288,19 @@ module 'lfe_andor_SUITE' ['$handle_undefined_function'/2,
+ 'lc$^0'/1 =
+ fun (_2) ->
+ case <_2> of
+- <[_x|_|-0-|]> when 'true' ->
++ <[_x|_lfe0]> when 'true' ->
+ letrec
+ 'lc$^1'/1 =
+ fun (_3) ->
+ case <_3> of
+- <[_y|_|-1-|]> when 'true' ->
++ <[_y|_lfe1]> when 'true' ->
+ let <_4> =
+ apply 'lc$^1'/1
+- (_|-1-|)
++ (_lfe1)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^0'/1
+- (_|-0-|)
++ (_lfe0)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+@@ -455,19 +455,19 @@ module 'lfe_andor_SUITE' ['$handle_undefined_function'/2,
+ 'lc$^2'/1 =
+ fun (_2) ->
+ case <_2> of
+- <[_x|_|-2-|]> when 'true' ->
++ <[_x|_lfe2]> when 'true' ->
+ letrec
+ 'lc$^3'/1 =
+ fun (_3) ->
+ case <_3> of
+- <[_y|_|-3-|]> when 'true' ->
++ <[_y|_lfe3]> when 'true' ->
+ let <_4> =
+ apply 'lc$^3'/1
+- (_|-3-|)
++ (_lfe3)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^2'/1
+- (_|-2-|)
++ (_lfe2)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+diff --git a/test/lfe_guard_SUITE.core b/test/lfe_guard_SUITE.core
+index 38f1d99..920be82 100644
+--- a/test/lfe_guard_SUITE.core
++++ b/test/lfe_guard_SUITE.core
+@@ -2857,22 +2857,22 @@ module 'lfe_guard_SUITE' ['$handle_undefined_function'/2,
+ 'false' ->
+ case <_t> of
+ <{_a,_b,_c,_d}> when 'true' ->
+- let <_|-0-|> =
++ let <_lfe0> =
+ <_a>
+- in let <_|-1-|> =
++ in let <_lfe1> =
+ <_b>
+- in let <_|-2-|> =
++ in let <_lfe2> =
+ <_c>
+- in let <_|-3-|> =
++ in let <_lfe3> =
+ <_d>
+ in let <_4> =
+ let <_3> =
+ call 'erlang':'+'
+- (_|-0-|, _|-1-|)
++ (_lfe0, _lfe1)
+ in call 'erlang':'+'
+- (_3, _|-2-|)
++ (_3, _lfe2)
+ in call 'erlang':'+'
+- (_4, _|-3-|)
++ (_4, _lfe3)
+ ( <_5> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_5}})
+--
+2.7.4 (Apple Git-66)
+
diff --git a/lib/compiler/test/lfe-source.patch b/lib/compiler/test/lfe-source.patch
new file mode 100644
index 0000000000..cbd6748bc9
--- /dev/null
+++ b/lib/compiler/test/lfe-source.patch
@@ -0,0 +1,117 @@
+Date: Sun, 13 Nov 2016 09:40:36 +0100
+Subject: [PATCH] Rename and fix up LFE test suites
+
+---
+ test/{andor_SUITE.lfe => lfe_andor_SUITE.lfe} | 16 ++++++++--------
+ test/{guard_SUITE.lfe => lfe_guard_SUITE.lfe} | 8 ++++----
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+ rename test/{andor_SUITE.lfe => lfe_andor_SUITE.lfe} (97%)
+ rename test/{guard_SUITE.lfe => lfe_guard_SUITE.lfe} (99%)
+
+diff --git a/test/andor_SUITE.lfe b/test/lfe_andor_SUITE.lfe
+similarity index 97%
+rename from test/andor_SUITE.lfe
+rename to test/lfe_andor_SUITE.lfe
+index 64feddd..1802b3f 100644
+--- a/test/andor_SUITE.lfe
++++ b/test/lfe_andor_SUITE.lfe
+@@ -26,14 +26,14 @@
+
+ (include-file "test_server.lfe")
+
+-(defmodule andor_SUITE
++(defmodule lfe_andor_SUITE
+ (export (all 0) (suite 0) (groups 0) (init_per_suite 1) (end_per_suite 1)
+ (init_per_group 2) (end_per_group 2)
+ (t_case 1) (t_and_or 1) (t_andalso 1) (t_orelse 1) (inside 1)
+ (overlap 1) (combined 1) (in_case 1) (before_and_inside_if 1)
+ ))
+
+-(defmacro MODULE () `'andor_SUITE)
++(defmacro MODULE () `'lfe_andor_SUITE)
+
+ (defun all ()
+ ;; (: test_lib recompile (MODULE))
+@@ -206,7 +206,7 @@
+
+ (defun t-andalso-1
+ ([(tuple x y)]
+- (: lfe_io format '"(andalso ~w ~w): " (list x y))
++ (: io format '"(andalso ~w ~w): " (list x y))
+ (let* ((v0 (andalso (echo x) (echo y)))
+ (v1 (when (=:= v0 v1))
+ (eif (andalso x y) 'true 'true 'false)))
+@@ -248,7 +248,7 @@
+
+ (defun t-orelse-1
+ ([(tuple x y)]
+- (: lfe_io format '"(orelse ~w ~w): " (list x y))
++ (: io format '"(orelse ~w ~w): " (list x y))
+ (let* ((v0 (orelse (echo x) (echo y)))
+ (v1 (when (=:= v0 v1))
+ (eif (orelse x y) 'true 'true 'false)))
+@@ -289,7 +289,7 @@
+ (when (=:= r1 r2) (=:= xm xm2) (=:= ym ym2) (=:= x x2)
+ (=:= y y2) (=:= w w2) (=:= h h2))
+ (inside-guard xm ym x y w h)))
+- (: lfe_io fwrite
++ (: io fwrite
+ '"(andalso (=< ~p ~p) (< ~p ~p) (=< ~p ~p) (< ~p ~p)) ==> ~p\n"
+ (list x xm xm (+ x w) y ym ym (+ y h) r1)))
+ r1))
+@@ -499,12 +499,12 @@
+ ;; Utilities
+
+ (defun check (v1 v0)
+- (eif (/= v1 v0) (progn (: lfe_io fwrite '"error: ~w.\n" (list v1))
++ (eif (/= v1 v0) (progn (: io fwrite '"error: ~w.\n" (list v1))
+ (exit 'suite_failed))
+- 'true (: lfe_io fwrite '"ok: ~w.\n" (list v1))))
++ 'true (: io fwrite '"ok: ~w.\n" (list v1))))
+
+ (defun echo (x)
+- (: lfe_io fwrite '"(eval ~w); " (list x))
++ (: io fwrite '"(eval ~w); " (list x))
+ x)
+
+ ;; Call this function to turn off constant propagation.
+diff --git a/test/guard_SUITE.lfe b/test/lfe_guard_SUITE.lfe
+similarity index 99%
+rename from test/guard_SUITE.lfe
+rename to test/lfe_guard_SUITE.lfe
+index 33b1344..2eeb1a6 100644
+--- a/test/guard_SUITE.lfe
++++ b/test/lfe_guard_SUITE.lfe
+@@ -26,7 +26,7 @@
+
+ (include-file "test_server.lfe")
+
+-(defmodule guard_SUITE
++(defmodule lfe_guard_SUITE
+ (export (all 0) (suite 0) (groups 0) (init_per_suite 1) (end_per_suite 1)
+ (init_per_group 2) (end_per_group 2)
+ (misc 1) (const_cond 1) (basic_not 1) (complex_not 1) (nested_nots 1)
+@@ -42,7 +42,7 @@
+ (check_qlc_hrl 1) (andalso_semi 1) (t_tuple_size 1) (binary_part 1)
+ ))
+
+-(defmacro MODULE () `'guard_SUITE)
++(defmacro MODULE () `'lfe_guard_SUITE)
+
+ (defun all ()
+ ;; (: test_lib recompile (MODULE))
+@@ -764,9 +764,9 @@
+
+ (defun is_function_2
+ ([config] (when (is_list config))
+- (line (test-pat 'true (is_function (id (function guard_SUITE all 1)) 1)))
++ (line (test-pat 'true (is_function (id (function lfe_guard_SUITE all 1)) 1)))
+ (line (test-pat 'true (is_function (id (lambda () 'ok)) 0)))
+- (line (test-pat 'false (is_function (id (function guard_SUITE all 1)) 0)))
++ (line (test-pat 'false (is_function (id (function lfe_guard_SUITE all 1)) 0)))
+ (line (test-pat 'false (is_function (id (lambda () 'ok)) 1)))
+
+ (let ((F (lambda (_) 'ok)))
+--
+2.7.4 (Apple Git-66)
+
diff --git a/lib/compiler/test/lfe.readme b/lib/compiler/test/lfe.readme
new file mode 100644
index 0000000000..2fc88e0252
--- /dev/null
+++ b/lib/compiler/test/lfe.readme
@@ -0,0 +1,31 @@
+Creating the LFE-derived test suites
+====================================
+
+Here is how to create `lfe_andor_SUITE.core` and `lfe_guard_SUITE.core`
+files.
+
+First clone and build LFE.
+
+ git clone https://github.com/rvirding/lfe.git
+ cd lfe
+ git checkout v1.2.0
+ MAKEFLAGS='' make compile
+ export PATH=$(pwd)/bin:$PATH
+
+Apply the source patch to rename and fix up the LFE source code:
+
+ cd test
+ git apply $ERL_TOP/lib/compiler/test/lfe-source.patch
+ git reset --hard HEAD
+
+Compile the modules to Core Erlang:
+
+ lfec +to-core0 lfe*.lfe
+
+Apply the core patch to correct some invalid variable names:
+
+ git apply $ERL_TOP/lib/compiler/test/lfe-core.patch
+
+Copy the patched .core file to the test suite:
+
+ cp lfe*.core $ERL_TOP/lib/compiler/test
diff --git a/lib/compiler/test/lfe_andor_SUITE.core b/lib/compiler/test/lfe_andor_SUITE.core
new file mode 100644
index 0000000000..df58b39ae6
--- /dev/null
+++ b/lib/compiler/test/lfe_andor_SUITE.core
@@ -0,0 +1,2014 @@
+module 'lfe_andor_SUITE' ['$handle_undefined_function'/2,
+ 'LFE-EXPAND-EXPORTED-MACRO'/3,
+ 'all'/0,
+ 'before_and_inside_if'/1,
+ 'combined'/1,
+ 'end_per_group'/2,
+ 'end_per_suite'/1,
+ 'groups'/0,
+ 'in_case'/1,
+ 'init_per_group'/2,
+ 'init_per_suite'/1,
+ 'inside'/1,
+ 'module_info'/0,
+ 'module_info'/1,
+ 'overlap'/1,
+ 'suite'/0,
+ 't_and_or'/1,
+ 't_andalso'/1,
+ 't_case'/1,
+ 't_orelse'/1]
+ attributes []
+'all'/0 =
+ %% Line 38
+ fun () ->
+ ['t_case'|['t_and_or'|['t_andalso'|['t_orelse'|['inside'|['overlap'|['combined'|['in_case'|['before_and_inside_if']]]]]]]]]
+'suite'/0 =
+ %% Line 44
+ fun () ->
+ []
+'groups'/0 =
+ %% Line 46
+ fun () ->
+ []
+'init_per_suite'/1 =
+ %% Line 48
+ fun (_config) ->
+ _config
+'end_per_suite'/1 =
+ %% Line 50
+ fun (_config) ->
+ 'ok'
+'init_per_group'/2 =
+ %% Line 52
+ fun (_name,_config) ->
+ _config
+'end_per_group'/2 =
+ %% Line 54
+ fun (_name,_config) ->
+ _config
+'t_case'/1 =
+ %% Line 56
+ fun (_0) ->
+ case <_0> of
+ <'suite'> when 'true' ->
+ []
+ <'doc'> when 'true' ->
+ [84|[101|[115|[116|[32|[105|[110|[32|[99|[97|[115|[101|[46]]]]]]]]]]]]]
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['less']]|[['t-case-a'|[1|[2]]]]]]})
+ let <_val> =
+ <apply 't-case-a'/2
+ (1, 2)>
+ in case <_val> of
+ <'less'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_25> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_25})
+ -| [{'function_name',{'t_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t-case-a'/2 =
+ %% Line 94
+ fun (_a,_b) ->
+ case call 'erlang':'<'
+ (_a, _b) of
+ <[_0|_1]> when 'true' ->
+ 'ok'
+ <'true'> when 'true' ->
+ 'less'
+ <'false'> when 'true' ->
+ 'not_less'
+ <{'a','b','c'}> when 'true' ->
+ 'ok'
+ <_2> when 'true' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-b'/2 =
+ %% Line 102
+ fun (_a,_b) ->
+ case call 'erlang':'=:='
+ (_a, _b) of
+ <'blurf'> when 'true' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-c'/2 =
+ %% Line 106
+ fun (_a,_b) ->
+ case let <_0> =
+ call 'erlang':'=:='
+ (_a, _b)
+ in call 'erlang':'not'
+ (_0) of
+ <'true'> when 'true' ->
+ 'ne'
+ <'false'> when 'true' ->
+ 'eq'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-d'/3 =
+ %% Line 111
+ fun (_a,_b,_x) ->
+ case let <_0> =
+ call 'erlang':'=:='
+ (_a, _b)
+ in call 'erlang':'and'
+ (_0, _x) of
+ <'true'> when 'true' ->
+ 't'
+ <'false'> when 'true' ->
+ 'f'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-e'/2 =
+ %% Line 116
+ fun (_a,_b) ->
+ case call 'erlang':'=:='
+ (_a, _b) of
+ <_bool>
+ when try
+ let <_0> =
+ call 'erlang':'is_tuple'
+ (_a)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_bool)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-xy'/3 =
+ %% Line 120
+ fun (_x,_y,_z) ->
+ let <_r0> =
+ <apply 't-case-x'/3
+ (_x, _y, _z)>
+ in case <apply 't-case-y'/3
+ (_x, _y, _z)> of
+ <_res>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_res, _r0)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _res
+ ( <_1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_1}})
+ -| ['compiler_generated'] )
+ end
+'t-case-x'/3 =
+ %% Line 125
+ fun (_x,_y,_z) ->
+ case let <_0> =
+ call 'erlang':'abs'
+ (_x)
+ in call 'erlang':'=:='
+ (_0, 42) of
+ <'true'> when 'true' ->
+ call 'erlang':'=:='
+ (_y, 100)
+ <'false'> when 'true' ->
+ call 'erlang':'=:='
+ (_z, 700)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-y'/3 =
+ %% Line 130
+ fun (_x,_y,_z) ->
+ case let <_0> =
+ call 'erlang':'abs'
+ (_x)
+ in call 'erlang':'=:='
+ (_0, 42) of
+ <'false'> when 'true' ->
+ call 'erlang':'=:='
+ (_z, 700)
+ <'true'> when 'true' ->
+ call 'erlang':'=:='
+ (_y, 100)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t_and_or'/1 =
+ %% Line 135
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['and'|[['quote'|['true']]|[['quote'|['true']]]]]]]]})
+ let <_val> =
+ <call 'erlang':'and'
+ ('true', 'true')>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_42> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_42})
+ -| [{'function_name',{'t_and_or',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t_andalso'/1 =
+ %% Line 172
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_bs> =
+ <['true'|['false']]>
+ in let <_ps> =
+ <letrec
+ 'lc$^0'/1 =
+ fun (_2) ->
+ case <_2> of
+ <[_x|_lfe0]> when 'true' ->
+ letrec
+ 'lc$^1'/1 =
+ fun (_3) ->
+ case <_3> of
+ <[_y|_lfe1]> when 'true' ->
+ let <_4> =
+ apply 'lc$^1'/1
+ (_lfe1)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^0'/1
+ (_lfe0)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'t_andalso',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^1'/1
+ (_bs)
+ <[]> when 'true' ->
+ []
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'t_andalso',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^0'/1
+ (_bs)>
+ in let <_7> =
+ fun (_p) ->
+ apply 't-andalso-1'/1
+ (_p)
+ in call 'lists':'foreach'
+ (_7, _ps)
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['andalso'|[['quote'|['true']]|[['quote'|['true']]]]]]]]})
+ let <_val> =
+ <case 'true' of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_8> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_8}})
+ -| ['compiler_generated'] )
+ end
+ ( <_57> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_57})
+ -| [{'function_name',{'t_andalso',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t-andalso-1'/1 =
+ %% Line 207
+ fun (_0) ->
+ case <_0> of
+ <{_x,_y}> when 'true' ->
+ do call 'io':'format'
+ ([40|[97|[110|[100|[97|[108|[115|[111|[32|[126|[119|[32|[126|[119|[41|[58|[32]]]]]]]]]]]]]]]]], [_x,_y])
+ let <_v0> =
+ <case apply 'echo'/1
+ (_x) of
+ <'true'> when 'true' ->
+ apply 'echo'/1
+ (_y)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <case 1 of
+ <_1>
+ when try
+ let <_3> =
+ let <_2> =
+ case _x of
+ <'true'> when 'true' ->
+ _y
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_v1>
+ when try
+ let <_5> =
+ call 'erlang':'=:='
+ (_v0, _v1)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_6> =
+ call 'erlang':'and'
+ (_x, _y)
+ in apply 'check'/2
+ (_v1, _6)
+ ( <_7> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_7}})
+ -| ['compiler_generated'] )
+ end
+ ( <_8> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_8})
+ -| [{'function_name',{'t-andalso-1',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t_orelse'/1 =
+ %% Line 215
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_bs> =
+ <['true'|['false']]>
+ in let <_ps> =
+ <letrec
+ 'lc$^2'/1 =
+ fun (_2) ->
+ case <_2> of
+ <[_x|_lfe2]> when 'true' ->
+ letrec
+ 'lc$^3'/1 =
+ fun (_3) ->
+ case <_3> of
+ <[_y|_lfe3]> when 'true' ->
+ let <_4> =
+ apply 'lc$^3'/1
+ (_lfe3)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^2'/1
+ (_lfe2)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'t_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^3'/1
+ (_bs)
+ <[]> when 'true' ->
+ []
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'t_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^2'/1
+ (_bs)>
+ in let <_7> =
+ fun (_p) ->
+ apply 't-orelse-1'/1
+ (_p)
+ in call 'lists':'foreach'
+ (_7, _ps)
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['orelse'|[['quote'|['true']]|[['quote'|['true']]]]]]]]})
+ let <_val> =
+ <case 'true' of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'true'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_8> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_8}})
+ -| ['compiler_generated'] )
+ end
+ ( <_57> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_57})
+ -| [{'function_name',{'t_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t-orelse-1'/1 =
+ %% Line 249
+ fun (_0) ->
+ case <_0> of
+ <{_x,_y}> when 'true' ->
+ do call 'io':'format'
+ ([40|[111|[114|[101|[108|[115|[101|[32|[126|[119|[32|[126|[119|[41|[58|[32]]]]]]]]]]]]]]]], [_x,_y])
+ let <_v0> =
+ <case apply 'echo'/1
+ (_x) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ apply 'echo'/1
+ (_y)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <case 1 of
+ <_1>
+ when try
+ let <_3> =
+ let <_2> =
+ case _x of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _y
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_v1>
+ when try
+ let <_5> =
+ call 'erlang':'=:='
+ (_v0, _v1)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_6> =
+ call 'erlang':'or'
+ (_x, _y)
+ in apply 'check'/2
+ (_v1, _6)
+ ( <_7> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_7}})
+ -| ['compiler_generated'] )
+ end
+ ( <_8> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_8})
+ -| [{'function_name',{'t-orelse-1',1}}] )
+ -| ['compiler_generated'] )
+ end
+'inside'/1 =
+ %% Line 257
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['inside'|[-8|[1]]]]]]})
+ let <_val> =
+ <apply 'inside'/2
+ (-8, 1)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12})
+ -| [{'function_name',{'inside',1}}] )
+ -| ['compiler_generated'] )
+ end
+'inside'/2 =
+ %% Line 272
+ fun (_xm,_ym) ->
+ let <_x> =
+ <-1.00000000000000000000e+01>
+ in let <_y> =
+ <-2.00000000000000000000e+00>
+ in let <_w> =
+ <2.00000000000000000000e+01>
+ in let <_h> =
+ <4.00000000000000000000e+00>
+ in let <_r0> =
+ <apply 'inside'/6
+ (_xm, _ym, _x, _y, _w, _h)>
+ in case <case 1 of
+ <_0>
+ when try
+ let <_4> =
+ let <_3> =
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_1> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _1) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_2> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _2)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r1>
+ when try
+ let <_6> =
+ call 'erlang':'=:='
+ (_r0, _r1)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do case let <_7> =
+ apply 'id'/1
+ (_r1)
+ in call 'erlang':'not'
+ (_7) of
+ <_o0> when 'true' ->
+ case <case 1 of
+ <_8>
+ when try
+ let <_12> =
+ let <_11> =
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_9> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _9) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_10> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _10)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in call 'erlang':'not'
+ (_11)
+ in _12
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_13>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_o1>
+ when try
+ let <_14> =
+ call 'erlang':'=:='
+ (_o0, _o1)
+ in _14
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _o1
+ ( <_15> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_15}})
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ do case <apply 'inside-guard'/6
+ (_xm, _ym, _x, _y, _w, _h)> of
+ <{_r2,_xm2,_ym2,_x2,_y2,_w2,_h2}>
+ when try
+ let <_16> =
+ call 'erlang':'=:='
+ (_r1, _r2)
+ in let <_17> =
+ call 'erlang':'=:='
+ (_xm, _xm2)
+ in let <_18> =
+ call 'erlang':'=:='
+ (_ym, _ym2)
+ in let <_19> =
+ call 'erlang':'=:='
+ (_x, _x2)
+ in let <_20> =
+ call 'erlang':'=:='
+ (_y, _y2)
+ in let <_21> =
+ call 'erlang':'=:='
+ (_w, _w2)
+ in let <_22> =
+ call 'erlang':'=:='
+ (_h, _h2)
+ in let <_23> =
+ call 'erlang':'and'
+ (_16, _17)
+ in let <_24> =
+ call 'erlang':'and'
+ (_23, _18)
+ in let <_25> =
+ call 'erlang':'and'
+ (_24, _19)
+ in let <_26> =
+ call 'erlang':'and'
+ (_25, _20)
+ in let <_27> =
+ call 'erlang':'and'
+ (_26, _21)
+ in call 'erlang':'and'
+ (_27, _22)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_30> =
+ let <_28> =
+ call 'erlang':'+'
+ (_x, _w)
+ in let <_29> =
+ call 'erlang':'+'
+ (_y, _h)
+ in [_x,_xm,_xm,_28,_y,_ym,_ym,_29,_r1]
+ in call 'io':'fwrite'
+ ([40|[97|[110|[100|[97|[108|[115|[111|[32|[40|[61|[60|[32|[126|[112|[32|[126|[112|[41|[32|[40|[60|[32|[126|[112|[32|[126|[112|[41|[32|[40|[61|[60|[32|[126|[112|[32|[126|[112|[41|[32|[40|[60|[32|[126|[112|[32|[126|[112|[41|[41|[32|[61|[61|[62|[32|[126|[112|[10]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]], _30)
+ ( <_31> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_31}})
+ -| ['compiler_generated'] )
+ end
+ _r1
+ ( <_32> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_32}})
+ -| ['compiler_generated'] )
+ end
+'inside'/6 =
+ %% Line 297
+ fun (_xm,_ym,_x,_y,_w,_h) ->
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_0> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _0) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_1> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _1)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+'inside-guard'/6 =
+ %% Line 300
+ fun (_5,_4,_3,_2,_1,_0) ->
+ case <_5,_4,_3,_2,_1,_0> of
+ <_xm,_ym,_x,_y,_w,_h>
+ when try
+ let <_9> =
+ let <_8> =
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_6> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _6) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_7> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _7)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_8, 'true')
+ -| ['compiler_generated'] )
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ {'true',_xm,_ym,_x,_y,_w,_h}
+ <_xm,_ym,_x,_y,_w,_h> when 'true' ->
+ {'false',_xm,_ym,_x,_y,_w,_h}
+ ( <_15,_14,_13,_12,_11,_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_15,_14,_13,_12,_11,_10})
+ -| [{'function_name',{'inside-guard',6}}] )
+ -| ['compiler_generated'] )
+ end
+'overlap'/1 =
+ %% Line 307
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['overlap'|[7.00000000000000000000e+00|[2.00000000000000000000e+00|[8.00000000000000000000e+00|[5.00000000000000000000e-01]]]]]]]]})
+ let <_val> =
+ <apply 'overlap'/4
+ (7.00000000000000000000e+00, 2.00000000000000000000e+00, 8.00000000000000000000e+00, 5.00000000000000000000e-01)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_10})
+ -| [{'function_name',{'overlap',1}}] )
+ -| ['compiler_generated'] )
+ end
+'overlap'/4 =
+ %% Line 321
+ fun (_pos1,_len1,_pos2,_len2) ->
+ let <_r0> =
+ <case _pos1 of
+ <_pos1>
+ when try
+ let <_3> =
+ let <_2> =
+ case case call 'erlang':'=<'
+ (_pos2, _pos1) of
+ <'true'> when 'true' ->
+ let <_0> =
+ call 'erlang':'+'
+ (_pos2, _len2)
+ in call 'erlang':'<'
+ (_pos1, _0)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_pos1, _pos2) of
+ <'true'> when 'true' ->
+ let <_1> =
+ call 'erlang':'+'
+ (_pos1, _len1)
+ in call 'erlang':'<'
+ (_pos2, _1)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_pos1> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <case case call 'erlang':'=<'
+ (_pos2, _pos1) of
+ <'true'> when 'true' ->
+ let <_4> =
+ call 'erlang':'+'
+ (_pos2, _len2)
+ in call 'erlang':'<'
+ (_pos1, _4)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_pos1, _pos2) of
+ <'true'> when 'true' ->
+ let <_5> =
+ call 'erlang':'+'
+ (_pos1, _len1)
+ in call 'erlang':'<'
+ (_pos2, _5)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end> of
+ <_r1>
+ when try
+ let <_6> =
+ call 'erlang':'=:='
+ (_r0, _r1)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case _pos1 of
+ <_pos1>
+ when try
+ let <_10> =
+ let <_9> =
+ case case call 'erlang':'=<'
+ (_pos2, _pos1) of
+ <'true'> when 'true' ->
+ let <_7> =
+ call 'erlang':'+'
+ (_pos2, _len2)
+ in call 'erlang':'<'
+ (_pos1, _7)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_pos1, _pos2) of
+ <'true'> when 'true' ->
+ let <_8> =
+ call 'erlang':'+'
+ (_pos1, _len1)
+ in call 'erlang':'<'
+ (_pos2, _8)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_9, 'true')
+ -| ['compiler_generated'] )
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_pos1> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r2>
+ when try
+ let <_11> =
+ call 'erlang':'=:='
+ (_r2, _r1)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_r2)
+ ( <_12> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_12}})
+ -| ['compiler_generated'] )
+ end
+ ( <_13> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_13}})
+ -| ['compiler_generated'] )
+ end
+'combined'/1 =
+ %% Line 348
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['false']]|[['comb'|[['quote'|['false']]|[['quote'|['false']]|[['quote'|['false']]]]]]]]]})
+ let <_val> =
+ <apply 'comb'/3
+ ('false', 'false', 'false')>
+ in case <_val> of
+ <'false'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_26> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_26})
+ -| [{'function_name',{'combined',1}}] )
+ -| ['compiler_generated'] )
+ end
+'comb'/3 =
+ %% Line 383
+ fun (_a,_b,_c) ->
+ let <_r0> =
+ <case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <case 1 of
+ <_0>
+ when try
+ let <_2> =
+ let <_1> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_1, 'true')
+ -| ['compiler_generated'] )
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_3>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r1>
+ when try
+ let <_4> =
+ call 'erlang':'=:='
+ (_r0, _r1)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_n0> =
+ <case 1 of
+ <_5>
+ when try
+ let <_7> =
+ let <_6> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in call 'erlang':'not'
+ (_6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <let <_9> =
+ call 'erlang':'not'
+ (_r1)
+ in apply 'id'/1
+ (_9)> of
+ <_n1>
+ when try
+ let <_10> =
+ call 'erlang':'=:='
+ (_n0, _n1)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end> of
+ <_r2>
+ when try
+ let <_11> =
+ call 'erlang':'=:='
+ (_r1, _r2)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case 1 of
+ <_12>
+ when try
+ let <_14> =
+ let <_13> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_13, 'true')
+ -| ['compiler_generated'] )
+ in _14
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_15>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r3>
+ when try
+ let <_16> =
+ call 'erlang':'=:='
+ (_r2, _r3)
+ in _16
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <let <_17> =
+ call 'erlang':'not'
+ (_r3)
+ in apply 'id'/1
+ (_17)> of
+ <_n2>
+ when try
+ let <_18> =
+ call 'erlang':'=:='
+ (_n1, _n2)
+ in _18
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case 1 of
+ <_19>
+ when try
+ let <_21> =
+ let <_20> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_20, 'true')
+ -| ['compiler_generated'] )
+ in _21
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_22>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r4>
+ when try
+ let <_23> =
+ call 'erlang':'=:='
+ (_r3, _r4)
+ in _23
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_r4)
+ ( <_24> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_24}})
+ -| ['compiler_generated'] )
+ end
+ ( <_25> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_25}})
+ -| ['compiler_generated'] )
+ end
+ ( <_26> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_26}})
+ -| ['compiler_generated'] )
+ end
+ ( <_27> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_27}})
+ -| ['compiler_generated'] )
+ end
+ ( <_28> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_28}})
+ -| ['compiler_generated'] )
+ end
+ ( <_29> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_29}})
+ -| ['compiler_generated'] )
+ end
+'in_case'/1 =
+ %% Line 402
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['edge_rings']]|[['in-case-1'|[1|[1|[1|[1|[1]]]]]]]]]})
+ let <_val> =
+ <apply 'in-case-1'/5
+ (1, 1, 1, 1, 1)>
+ in case <_val> of
+ <'edge_rings'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_13> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13})
+ -| [{'function_name',{'in_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'in-case-1'/5 =
+ %% Line 419
+ fun (_lenup,_lendw,_lenn,_rot,_count) ->
+ let <_r0> =
+ <apply 'in-case-1-body'/5
+ (_lenup, _lendw, _lenn, _rot, _count)>
+ in case <apply 'in-case-1-guard'/5
+ (_lenup, _lendw, _lenn, _rot, _count)> of
+ <_res>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_r0, _res)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _res
+ ( <_1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_1}})
+ -| ['compiler_generated'] )
+ end
+'in-case-1-body'/5 =
+ %% Line 425
+ fun (_lenup,_lendw,_lenn,_rot,_count) ->
+ case let <_5> =
+ let <_2> =
+ let <_0> =
+ call 'erlang':'/'
+ (_lenup, _count)
+ in call 'erlang':'>'
+ (_0, 7.06999999999999961808e-01)
+ in let <_3> =
+ let <_1> =
+ call 'erlang':'/'
+ (_lenn, _count)
+ in call 'erlang':'>'
+ (_1, 7.06999999999999961808e-01)
+ in call 'erlang':'and'
+ (_2, _3)
+ in let <_6> =
+ let <_4> =
+ call 'erlang':'abs'
+ (_rot)
+ in call 'erlang':'>'
+ (_4, 7.06999999999999961808e-01)
+ in call 'erlang':'and'
+ (_5, _6) of
+ <'true'> when 'true' ->
+ 'edge_rings'
+ <'false'> when 'true' ->
+ case let <_11> =
+ let <_9> =
+ let <_7> =
+ call 'erlang':'>='
+ (_lenup, 1)
+ in let <_8> =
+ call 'erlang':'>='
+ (_lendw, 1)
+ in call 'erlang':'or'
+ (_7, _8)
+ in let <_10> =
+ call 'erlang':'=<'
+ (_lenn, 1)
+ in call 'erlang':'or'
+ (_9, _10)
+ in let <_12> =
+ call 'erlang':'>'
+ (_count, 4)
+ in call 'erlang':'or'
+ (_11, _12) of
+ <'true'> when 'true' ->
+ 'not_loop'
+ <'false'> when 'true' ->
+ 'loop'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'in-case-1-guard'/5 =
+ %% Line 435
+ fun (_lenup,_lendw,_lenn,_rot,_count) ->
+ case case let <_0> =
+ call 'erlang':'/'
+ (_lenup, _count)
+ in call 'erlang':'>'
+ (_0, 7.06999999999999961808e-01) of
+ <'true'> when 'true' ->
+ case let <_1> =
+ call 'erlang':'/'
+ (_lenn, _count)
+ in call 'erlang':'>'
+ (_1, 7.06999999999999961808e-01) of
+ <'true'> when 'true' ->
+ let <_2> =
+ call 'erlang':'abs'
+ (_rot)
+ in call 'erlang':'>'
+ (_2, 7.06999999999999961808e-01)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'edge_rings'
+ <'false'>
+ when try
+ let <_4> =
+ let <_3> =
+ case call 'erlang':'>='
+ (_lenup, 1) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'>='
+ (_lendw, 1) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_lenn, 1) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ call 'erlang':'<'
+ (_count, 4)
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'not_loop'
+ <'false'> when 'true' ->
+ 'loop'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'before_and_inside_if'/1 =
+ %% Line 443
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['no']]|[['before-and-inside-if'|[['quote'|[['a']]]|[['quote'|[['b']]]|[['quote'|['delete']]]]]]]]]})
+ let <_val> =
+ <apply 'before-and-inside-if'/3
+ (['a'], ['b'], 'delete')>
+ in case <_val> of
+ <'no'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_18> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_18})
+ -| [{'function_name',{'before_and_inside_if',1}}] )
+ -| ['compiler_generated'] )
+ end
+'before-and-inside-if'/3 =
+ %% Line 468
+ fun (XDo1,XDo2,Do3) ->
+ let <Do1> =
+ <call 'erlang':'=/='
+ (XDo1, [])>
+ in let <Do2> =
+ <call 'erlang':'=/='
+ (XDo2, [])>
+ in case 1 of
+ <_0>
+ when try
+ let <_7> =
+ let <_5> =
+ call 'erlang':'=:='
+ (Do1, 'true')
+ in let <_6> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'=:='
+ (Do1, 'false')
+ in let <_2> =
+ call 'erlang':'=:='
+ (Do2, 'false')
+ in call 'erlang':'and'
+ (_1, _2)
+ in let <_4> =
+ call 'erlang':'=:='
+ (Do3, 'delete')
+ in call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'or'
+ (_5, _6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'no'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'yes'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'before-and-inside-if-2'/3 =
+ %% Line 484
+ fun (XDo1,XDo2,Do3) ->
+ let <Do1> =
+ <call 'erlang':'=/='
+ (XDo1, [])>
+ in let <Do2> =
+ <call 'erlang':'=/='
+ (XDo2, [])>
+ in let <CH1> =
+ <case 1 of
+ <_0>
+ when try
+ let <_7> =
+ let <_5> =
+ call 'erlang':'=='
+ (Do1, 'true')
+ in let <_6> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'=='
+ (Do1, 'false')
+ in let <_2> =
+ call 'erlang':'=='
+ (Do2, 'false')
+ in call 'erlang':'and'
+ (_1, _2)
+ in let <_4> =
+ call 'erlang':'=='
+ (Do3, 'blah')
+ in call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'or'
+ (_5, _6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ch1'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'no'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in let <CH2> =
+ <case 1 of
+ <_9>
+ when try
+ let <_16> =
+ let <_14> =
+ call 'erlang':'=='
+ (Do1, 'true')
+ in let <_15> =
+ let <_12> =
+ let <_10> =
+ call 'erlang':'=='
+ (Do1, 'false')
+ in let <_11> =
+ call 'erlang':'=='
+ (Do2, 'false')
+ in call 'erlang':'and'
+ (_10, _11)
+ in let <_13> =
+ call 'erlang':'=='
+ (Do3, 'xx')
+ in call 'erlang':'and'
+ (_12, _13)
+ in call 'erlang':'or'
+ (_14, _15)
+ in _16
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ch2'
+ <_17>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'no'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in {CH1,CH2}
+'check'/2 =
+ %% Line 501
+ fun (_v1,_v0) ->
+ case 1 of
+ <_0>
+ when try
+ let <_1> =
+ call 'erlang':'/='
+ (_v1, _v0)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'io':'fwrite'
+ ([101|[114|[114|[111|[114|[58|[32|[126|[119|[46|[10]]]]]]]]]]], [_v1])
+ call 'erlang':'exit'
+ ('suite_failed')
+ <_2>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ call 'io':'fwrite'
+ ([111|[107|[58|[32|[126|[119|[46|[10]]]]]]]], [_v1])
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'echo'/1 =
+ %% Line 506
+ fun (_x) ->
+ do call 'io':'fwrite'
+ ([40|[101|[118|[97|[108|[32|[126|[119|[41|[59|[32]]]]]]]]]]], [_x])
+ _x
+'id'/1 =
+ %% Line 511
+ fun (_i) ->
+ _i
+'$handle_undefined_function'/2 =
+ %% Line 29
+ fun (_f,_as) ->
+ case let <_0> =
+ call 'lfe_env':'new'
+ ()
+ in apply 'LFE-EXPAND-EXPORTED-MACRO'/3
+ (_f, _as, _0) of
+ <{'yes',_exp}> when 'true' ->
+ call 'lfe_eval':'expr'
+ (_exp)
+ <'no'> when 'true' ->
+ let <_a,_b> =
+ <_f,_as>
+ in call 'error_handler':'raise_undef_exception'
+ ('lfe_andor_SUITE', _a, _b)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'LFE-EXPAND-EXPORTED-MACRO'/3 =
+ %% Line 29
+ fun (_2,_1,_0) ->
+ 'no'
+'module_info'/0 =
+ fun () ->
+ call 'erlang':'get_module_info'
+ ('lfe_andor_SUITE')
+'module_info'/1 =
+ fun (_x) ->
+ call 'erlang':'get_module_info'
+ ('lfe_andor_SUITE', _x)
+end
diff --git a/lib/compiler/test/lfe_guard_SUITE.core b/lib/compiler/test/lfe_guard_SUITE.core
new file mode 100644
index 0000000000..920be82f61
--- /dev/null
+++ b/lib/compiler/test/lfe_guard_SUITE.core
@@ -0,0 +1,3438 @@
+module 'lfe_guard_SUITE' ['$handle_undefined_function'/2,
+ 'LFE-EXPAND-EXPORTED-MACRO'/3,
+ 'all'/0,
+ 'and_guard'/1,
+ 'andalso_semi'/1,
+ 'basic_andalso_orelse'/1,
+ 'basic_not'/1,
+ 'binary_part'/1,
+ 'build_in_guard'/1,
+ 'check_qlc_hrl'/1,
+ 'comma'/1,
+ 'complex_not'/1,
+ 'complex_or_guards'/1,
+ 'complex_semicolon'/1,
+ 'const_cond'/1,
+ 'end_per_group'/2,
+ 'end_per_suite'/1,
+ 'gbif'/1,
+ 'groups'/0,
+ 'init_per_group'/2,
+ 'init_per_suite'/1,
+ 'is_function_2'/1,
+ 'literal_type_tests'/1,
+ 'misc'/1,
+ 'module_info'/0,
+ 'module_info'/1,
+ 'more_or_guards'/1,
+ 'more_xor_guards'/1,
+ 'nested_nots'/1,
+ 'old_guard_tests'/1,
+ 'or_guard'/1,
+ 'rel_ops'/1,
+ 'semicolon'/1,
+ 'suite'/0,
+ 't_is_boolean'/1,
+ 't_tuple_size'/1,
+ 'traverse_dcd'/1,
+ 'tricky'/1,
+ 'xor_guard'/1]
+ attributes []
+'all'/0 =
+ %% Line 47
+ fun () ->
+ ['misc'|['const_cond'|['basic_not'|['complex_not'|['nested_nots'|['semicolon'|['complex_semicolon'|['comma'|['or_guard'|['more_or_guards'|['complex_or_guards'|['and_guard'|['xor_guard'|['more_xor_guards'|['build_in_guard'|['old_guard_tests'|['gbif'|['t_is_boolean'|['is_function_2'|['tricky'|['rel_ops'|['literal_type_tests'|['basic_andalso_orelse'|['traverse_dcd'|['check_qlc_hrl'|['andalso_semi'|['t_tuple_size'|['binary_part']]]]]]]]]]]]]]]]]]]]]]]]]]]]
+'suite'/0 =
+ %% Line 58
+ fun () ->
+ []
+'groups'/0 =
+ %% Line 60
+ fun () ->
+ []
+'init_per_suite'/1 =
+ %% Line 62
+ fun (_config) ->
+ _config
+'end_per_suite'/1 =
+ %% Line 64
+ fun (_config) ->
+ 'ok'
+'init_per_group'/2 =
+ %% Line 66
+ fun (_name,_config) ->
+ _config
+'end_per_group'/2 =
+ %% Line 68
+ fun (_name,_config) ->
+ _config
+'misc'/1 =
+ %% Line 70
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[42|[['case'|[['id'|[42]]|[['x'|[['when'|[['-'|['x']]]]|[['quote'|['ok']]]]]|[['x'|['x']]]]]]]]]})
+ let <_val> =
+ <case apply 'id'/1
+ (42) of
+ <_x>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'-'
+ (_x)
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_x> when 'true' ->
+ _x
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <42> when 'true' ->
+ _val
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_17> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_17})
+ -| [{'function_name',{'misc',1}}] )
+ -| ['compiler_generated'] )
+ end
+'misc-1'/1 =
+ %% Line 93
+ fun (_0) ->
+ case <_0> of
+ <[{_w},{_x},{_y},{_z}]> when 'true' ->
+ case 1 of
+ <_1>
+ when try
+ let <_4> =
+ let <_3> =
+ case call 'erlang':'>'
+ (_x, _y) of
+ <'true'> when 'true' ->
+ let <_2> =
+ call 'erlang':'abs'
+ (_z)
+ in call 'erlang':'=:='
+ (_2, 2)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_w)
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'none'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'misc-1',1}}] )
+ -| ['compiler_generated'] )
+ end
+'get-data'/3 =
+ %% Line 99
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <{'o',_active,_raw},_bytes,_buffer>
+ when try
+ let <_5> =
+ let <_3> =
+ call 'erlang':'=:='
+ (_raw, 'raw')
+ in let <_4> =
+ call 'erlang':'=:='
+ (_raw, 0)
+ in call 'erlang':'or'
+ (_3, _4)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case 1 of
+ <_6>
+ when try
+ let <_8> =
+ let <_7> =
+ case call 'erlang':'=/='
+ (_active, 'false') of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ call 'erlang':'=:='
+ (_bytes, 0)
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_7, 'true')
+ -| ['compiler_generated'] )
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ {'ok',_buffer,#{}#}
+ <_9>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_12,_11,_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12,_11,_10})
+ -| [{'function_name',{'get-data',3}}] )
+ -| ['compiler_generated'] )
+ end
+'const_cond'/1 =
+ %% Line 104
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['const-cond'|[{}|[0]]]]]]})
+ let <_val> =
+ <apply 'const-cond'/2
+ ({}, 0)>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_7> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_7})
+ -| [{'function_name',{'const_cond',1}}] )
+ -| ['compiler_generated'] )
+ end
+'const-cond'/2 =
+ %% Line 113
+ fun (_t,_sz) ->
+ case _t of
+ <_0>
+ when try
+ 'false'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'never'
+ <_1>
+ when try
+ let <_3> =
+ call 'erlang':'is_tuple'
+ (_t)
+ in let <_4> =
+ call 'erlang':'=='
+ ('eq', 'eq')
+ in let <_5> =
+ let <_2> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=='
+ (_2, _sz)
+ in let <_6> =
+ call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'and'
+ (_6, _5)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_7>
+ when try
+ let <_9> =
+ call 'erlang':'is_tuple'
+ (_t)
+ in let <_10> =
+ call 'erlang':'=='
+ ('eq', 'leq')
+ in let <_11> =
+ let <_8> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=='
+ (_8, _sz)
+ in let <_12> =
+ call 'erlang':'and'
+ (_9, _10)
+ in call 'erlang':'and'
+ (_12, _11)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_13> when 'true' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'basic_not'/1 =
+ %% Line 120
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_true> =
+ <apply 'id'/1
+ ('true')>
+ in let <_false> =
+ <apply 'id'/1
+ ('false')>
+ in let <_glurf> =
+ <apply 'id'/1
+ ('glurf')>
+ in let <_a> =
+ <apply 'id'/1
+ (5)>
+ in let <_b> =
+ <apply 'id'/1
+ (3.75000000000000000000e+01)>
+ in let <_c> =
+ <apply 'id'/1
+ (-1)>
+ in let <_d> =
+ <apply 'id'/1
+ (5)>
+ in let <_atuple> =
+ <{_false,_true,_glurf}>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['not'|[['quote'|['false']]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['ok']]]]]})
+ let <_5> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'not'
+ ('false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_5, 'ok')
+ ( <_128> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_128})
+ -| [{'function_name',{'basic_not',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex_not'/1 =
+ %% Line 164
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_atuple> =
+ <apply 'id'/1
+ ({'false','true','gurka'})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['not'|[['element'|[1|['atuple']]]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['ok']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'element'
+ (1, _atuple)
+ in call 'erlang':'not'
+ (_3)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'ok')
+ ( <_50> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_50})
+ -| [{'function_name',{'complex_not',1}}] )
+ -| ['compiler_generated'] )
+ end
+'nested_nots'/1 =
+ %% Line 191
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['true']]|[['nested-not-1'|[0|[0]]]]]]})
+ let <_val> =
+ <apply 'nested-not-1'/2
+ (0, 0)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_18> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_18})
+ -| [{'function_name',{'nested_nots',1}}] )
+ -| ['compiler_generated'] )
+ end
+'nested-not-1'/2 =
+ %% Line 213
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_x,_y>
+ when try
+ let <_10> =
+ let <_9> =
+ let <_7> =
+ let <_3> =
+ call 'erlang':'>'
+ (_x, _y)
+ in let <_4> =
+ let <_2> =
+ call 'erlang':'is_atom'
+ (_x)
+ in call 'erlang':'not'
+ (_2)
+ in call 'erlang':'or'
+ (_3, _4)
+ in let <_8> =
+ let <_5> =
+ call 'erlang':'is_atom'
+ (_y)
+ in let <_6> =
+ call 'erlang':'=='
+ (_x, 3.39999999999999991118e+00)
+ in call 'erlang':'or'
+ (_5, _6)
+ in call 'erlang':'and'
+ (_7, _8)
+ in call 'erlang':'not'
+ (_9)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_11,_12> when 'true' ->
+ 'false'
+ ( <_14,_13> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_14,_13})
+ -| [{'function_name',{'nested-not-1',2}}] )
+ -| ['compiler_generated'] )
+ end
+'nested-not-2'/3 =
+ %% Line 219
+ fun (_x,_y,_z) ->
+ apply 'nested-not-2'/4
+ (_x, _y, _z, 'true')
+'nested-not-2'/4 =
+ %% Line 222
+ fun (_3,_2,_1,_0) ->
+ case <_3,_2,_1,_0> of
+ <_x,_y,_z,_true>
+ when try
+ let <_12> =
+ let <_11> =
+ let <_10> =
+ let <_9> =
+ let <_7> =
+ let <_4> =
+ call 'erlang':'not'
+ (_x)
+ in let <_5> =
+ call 'erlang':'not'
+ (_y)
+ in call 'erlang':'and'
+ (_4, _5)
+ in let <_8> =
+ let <_6> =
+ call 'erlang':'is_atom'
+ (_z)
+ in call 'erlang':'not'
+ (_6)
+ in call 'erlang':'or'
+ (_7, _8)
+ in call 'erlang':'not'
+ (_9)
+ in call 'erlang':'and'
+ (_true, _10)
+ in call 'erlang':'not'
+ (_11)
+ in _12
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_13,_14,_15,_16> when 'true' ->
+ 'false'
+ ( <_20,_19,_18,_17> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_20,_19,_18,_17})
+ -| [{'function_name',{'nested-not-2',4}}] )
+ -| ['compiler_generated'] )
+ end
+'semicolon'/1 =
+ %% Line 228
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'semicolon',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex_semicolon'/1 =
+ %% Line 233
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'complex_semicolon',1}}] )
+ -| ['compiler_generated'] )
+ end
+'comma'/1 =
+ %% Line 239
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['progn'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'and'
+ ('true', 'false')
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'error')
+ ( <_181> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_181})
+ -| [{'function_name',{'comma',1}}] )
+ -| ['compiler_generated'] )
+ end
+'or_guard'/1 =
+ %% Line 305
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_true,_false,_glurf> =
+ <apply 'id'/1
+ ('true'),apply 'id'/1
+ ('false'),apply 'id'/1
+ ('glurf')>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['or'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]]]]]]]|[['quote'|['ok']]]]]})
+ let <_4> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'or'
+ ('true', 'false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_4, 'ok')
+ 'ok'
+ ( <_64> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_64})
+ -| [{'function_name',{'or_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'more_or_guards'/1 =
+ %% Line 346
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_true> =
+ <apply 'id'/1
+ ('true')>
+ in let <_false> =
+ <apply 'id'/1
+ ('false')>
+ in let <_atuple> =
+ <apply 'id'/1
+ ({'false','true','gurks'})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['or'|[['element'|[42|['atuple']]]|['false']]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'element'
+ (42, _atuple)
+ in call 'erlang':'or'
+ (_3, _false)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'error')
+ 'ok'
+ ( <_68> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_68})
+ -| [{'function_name',{'more_or_guards',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex_or_guards'/1 =
+ %% Line 409
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['complex-or-1'|[{'a','b','c','d'}|[{1,2,3}]]]]]]})
+ let <_val> =
+ <apply 'complex-or-1'/2
+ ({'a','b','c','d'}, {1,2,3})>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_55> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_55})
+ -| [{'function_name',{'complex_or_guards',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex-or-1'/2 =
+ %% Line 487
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_11> =
+ let <_9> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'tuple_size'
+ (_a)
+ in call 'erlang':'<'
+ (3, _1)
+ in let <_4> =
+ let <_2> =
+ call 'erlang':'tuple_size'
+ (_a)
+ in call 'erlang':'<'
+ (_2, 9)
+ in call 'erlang':'and'
+ (_3, _4)
+ in let <_10> =
+ let <_7> =
+ let <_5> =
+ call 'erlang':'tuple_size'
+ (_b)
+ in call 'erlang':'<'
+ (2, _5)
+ in let <_8> =
+ let <_6> =
+ call 'erlang':'tuple_size'
+ (_b)
+ in call 'erlang':'<'
+ (_6, 7)
+ in call 'erlang':'and'
+ (_7, _8)
+ in call 'erlang':'or'
+ (_9, _10)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_12>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-2'/1 =
+ %% Line 492
+ fun (_tuple) ->
+ case 1 of
+ <_0>
+ when try
+ let <_6> =
+ let <_4> =
+ call 'erlang':'element'
+ (1, _tuple)
+ in let <_5> =
+ let <_3> =
+ let <_2> =
+ let <_1> =
+ call 'erlang':'element'
+ (2, _tuple)
+ in call 'erlang':'tuple_size'
+ (_1)
+ in call 'erlang':'>'
+ (_2, 3)
+ in call 'erlang':'not'
+ (_3)
+ in call 'erlang':'or'
+ (_4, _5)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_7>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-3'/2 =
+ %% Line 496
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_5> =
+ let <_3> =
+ let <_2> =
+ let <_1> =
+ call 'erlang':'size'
+ (_b)
+ in call 'erlang':'>'
+ (_1, 3)
+ in call 'erlang':'not'
+ (_2)
+ in let <_4> =
+ call 'erlang':'element'
+ (1, _a)
+ in call 'erlang':'or'
+ (_3, _4)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_6>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-4'/2 =
+ %% Line 499
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_7> =
+ let <_5> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'is_tuple'
+ (_a)
+ in let <_3> =
+ let <_1> =
+ call 'erlang':'size'
+ (_a)
+ in call 'erlang':'>'
+ (_1, 3)
+ in call 'erlang':'and'
+ (_2, _3)
+ in call 'erlang':'not'
+ (_4)
+ in let <_6> =
+ call 'erlang':'element'
+ (1, _b)
+ in call 'erlang':'or'
+ (_5, _6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-5'/2 =
+ %% Line 503
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_8> =
+ let <_6> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'is_tuple'
+ (_a)
+ in let <_3> =
+ let <_1> =
+ call 'erlang':'size'
+ (_a)
+ in call 'erlang':'>'
+ (_1, 3)
+ in call 'erlang':'and'
+ (_2, _3)
+ in call 'erlang':'not'
+ (_4)
+ in let <_7> =
+ let <_5> =
+ call 'erlang':'element'
+ (1, _b)
+ in call 'erlang':'not'
+ (_5)
+ in call 'erlang':'or'
+ (_6, _7)
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_9>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-6'/2 =
+ %% Line 507
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_11> =
+ let <_9> =
+ let <_5> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'element'
+ (1, _a)
+ in call 'erlang':'not'
+ (_1)
+ in let <_4> =
+ let <_2> =
+ call 'erlang':'element'
+ (2, _a)
+ in call 'erlang':'not'
+ (_2)
+ in call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'not'
+ (_5)
+ in let <_10> =
+ let <_8> =
+ let <_7> =
+ let <_6> =
+ call 'erlang':'size'
+ (_b)
+ in call 'erlang':'>'
+ (_6, 3)
+ in call 'erlang':'not'
+ (_7)
+ in call 'erlang':'not'
+ (_8)
+ in call 'erlang':'or'
+ (_9, _10)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_12>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'and_guard'/1 =
+ %% Line 512
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['and'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_5> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'and'
+ ('true', 'false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_5, 'error')
+ ( <_120> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_120})
+ -| [{'function_name',{'and_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'relprod'/2 =
+ %% Line 588
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_r1,_r2>
+ when try
+ let <_10> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'size'
+ (_r1)
+ in call 'erlang':'=:='
+ (_2, 3)
+ in let <_5> =
+ let <_3> =
+ call 'erlang':'element'
+ (1, _r1)
+ in call 'erlang':'=:='
+ (_3, 'Set')
+ in call 'erlang':'and'
+ (_4, _5)
+ in let <_11> =
+ let <_8> =
+ let <_6> =
+ call 'erlang':'size'
+ (_r2)
+ in call 'erlang':'=:='
+ (_6, 3)
+ in let <_9> =
+ let <_7> =
+ call 'erlang':'element'
+ (1, _r2)
+ in call 'erlang':'=:='
+ (_7, 'Set')
+ in call 'erlang':'and'
+ (_8, _9)
+ in call 'erlang':'and'
+ (_10, _11)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'relprod',2}}] )
+ -| ['compiler_generated'] )
+ end
+'xor_guard'/1 =
+ %% Line 595
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['xor'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]]]]]]]|[['quote'|['ok']]]]]})
+ let <_4> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'xor'
+ ('true', 'false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_4, 'ok')
+ ( <_54> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_54})
+ -| [{'function_name',{'xor_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'more_xor_guards'/1 =
+ %% Line 636
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_true,_false,_atuple> =
+ <apply 'id'/1
+ ('true'),apply 'id'/1
+ ('false'),apply 'id'/1
+ ({'false','true','gurka'})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['xor'|[['element'|[42|['atuple']]]|['false']]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'element'
+ (42, _atuple)
+ in call 'erlang':'xor'
+ (_3, _false)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'error')
+ ( <_29> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_29})
+ -| [{'function_name',{'more_xor_guards',1}}] )
+ -| ['compiler_generated'] )
+ end
+'build_in_guard'/1 =
+ %% Line 666
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_subbin> =
+ <#{#<64>(8,1,'integer',['unsigned'|['big']]),
+ #<20>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']])}#>
+ in let <_b> =
+ <#{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<_subbin>('all',8,'binary',['unsigned'|['big']]),
+ #<3.50000000000000000000e+00>(64,1,'float',['unsigned'|['big']])}#>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['eif'|[['=:='|['b'|[['binary'|[1|[['subbin'|['binary']]|[[3.50000000000000000000e+00|['float']]]]]]]]]|[['quote'|['ok']]]]]]]]})
+ let <_val> =
+ <case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'=:='
+ (_b, #{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<_subbin>('all',8,'binary',['unsigned'|['big']]),
+ #<3.50000000000000000000e+00>(64,1,'float',['unsigned'|['big']])}#)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'build_in_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'old_guard_tests'/1 =
+ %% Line 674
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'old_guard_tests',1}}] )
+ -| ['compiler_generated'] )
+ end
+'gbif'/1 =
+ %% Line 679
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['error']]|[['gbif-1'|[1|[{'false','true'}]]]]]]})
+ let <_val> =
+ <apply 'gbif-1'/2
+ (1, {'false','true'})>
+ in case <_val> of
+ <'error'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_4> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_4})
+ -| [{'function_name',{'gbif',1}}] )
+ -| ['compiler_generated'] )
+ end
+'gbif-1'/2 =
+ %% Line 685
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_p,_t>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'element'
+ (_p, _t)
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4,_5> when 'true' ->
+ 'error'
+ ( <_7,_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_7,_6})
+ -| [{'function_name',{'gbif-1',2}}] )
+ -| ['compiler_generated'] )
+ end
+'t_is_boolean'/1 =
+ %% Line 690
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['true']]|[['is_boolean'|[['quote'|['true']]]]]]]})
+ let <_val> =
+ <call 'erlang':'is_boolean'
+ ('true')>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_70> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_70})
+ -| [{'function_name',{'t_is_boolean',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bool'/1 =
+ %% Line 744
+ fun (_0) ->
+ case <_0> of
+ <_x>
+ when try
+ let <_1> =
+ call 'erlang':'is_boolean'
+ (_x)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_2> when 'true' ->
+ 'error'
+ ( <_3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_3})
+ -| [{'function_name',{'bool',1}}] )
+ -| ['compiler_generated'] )
+ end
+'my-is-bool'/1 =
+ %% Line 748
+ fun (_v) ->
+ let <_r0> =
+ <apply 'my-is-bool-a'/1
+ (_v)>
+ in case <apply 'my-is-bool-b'/1
+ (_v)> of
+ <_res>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_res, _r0)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _res
+ ( <_1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_1}})
+ -| ['compiler_generated'] )
+ end
+'my-is-bool-a'/1 =
+ %% Line 753
+ fun (_v) ->
+ case _v of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'true'
+ <_0> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'my-is-bool-b'/1 =
+ %% Line 759
+ fun (_v) ->
+ case _v of
+ <'false'> when 'true' ->
+ 'true'
+ <'true'> when 'true' ->
+ 'true'
+ <_0> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'is_function_2'/1 =
+ %% Line 765
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['true']]|[['is_function'|[['id'|[['function'|['lfe_guard_SUITE'|['all'|[1]]]]]]|[1]]]]]]})
+ let <_val> =
+ <let <_3> =
+ let <_2> =
+ call 'erlang':'make_fun'
+ ('lfe_guard_SUITE', 'all', 1)
+ in apply 'id'/1
+ (_2)
+ in call 'erlang':'is_function'
+ (_3, 1)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_17> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_17})
+ -| [{'function_name',{'is_function_2',1}}] )
+ -| ['compiler_generated'] )
+ end
+'tricky'/1 =
+ %% Line 775
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['not_ok']]|[['tricky-1'|[1|[2]]]]]]})
+ let <_val> =
+ <apply 'tricky-1'/2
+ (1, 2)>
+ in case <_val> of
+ <'not_ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12})
+ -| [{'function_name',{'tricky',1}}] )
+ -| ['compiler_generated'] )
+ end
+'tricky-1'/2 =
+ %% Line 791
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_x,_y>
+ when try
+ let <_6> =
+ let <_5> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'=='
+ (_x, 1)
+ in let <_3> =
+ call 'erlang':'=='
+ (_y, 2)
+ in call 'erlang':'or'
+ (_2, _3)
+ in call 'erlang':'abs'
+ (_4)
+ in ( call 'erlang':'=:='
+ (_5, 'true')
+ -| ['compiler_generated'] )
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_7,_8> when 'true' ->
+ 'not_ok'
+ ( <_10,_9> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_10,_9})
+ -| [{'function_name',{'tricky-1',2}}] )
+ -| ['compiler_generated'] )
+ end
+'tricky-2'/1 =
+ %% Line 795
+ fun (_0) ->
+ case <_0> of
+ <_x>
+ when try
+ let <_3> =
+ let <_1> =
+ call 'erlang':'float'
+ (_x)
+ in let <_2> =
+ call 'erlang':'float'
+ (_x)
+ in call 'erlang':'or'
+ (_1, _2)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4> when 'true' ->
+ 'error'
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'tricky-2',1}}] )
+ -| ['compiler_generated'] )
+ end
+'rb'/3 =
+ %% Line 801
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <_size,_toread,_sofar>
+ when try
+ let <_6> =
+ let <_4> =
+ let <_3> =
+ call 'erlang':'+'
+ (_sofar, _size)
+ in call 'erlang':'<'
+ (_3, 81920)
+ in let <_5> =
+ call 'erlang':'=='
+ (_toread, [])
+ in call 'erlang':'or'
+ (_4, _5)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_7,_8,_9> when 'true' ->
+ 'false'
+ ( <_12,_11,_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12,_11,_10})
+ -| [{'function_name',{'rb',3}}] )
+ -| ['compiler_generated'] )
+ end
+'rel_ops'/1 =
+ %% Line 830
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['T'|['=/='|[1|[1.00000000000000000000e+00]]]]})
+ case <case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'=/='
+ (1, 1.00000000000000000000e+00)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_5>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'=/='
+ (1, 1.00000000000000000000e+00)
+ in call 'erlang':'not'
+ (_6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ let <_x,_y,_true,_false> =
+ <apply 'id'/1
+ (1),apply 'id'/1
+ (1.00000000000000000000e+00),apply 'id'/1
+ ('true'),apply 'id'/1
+ ('false')>
+ in case <case 1 of
+ <_9>
+ when try
+ let <_10> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_11>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_12>
+ when try
+ let <_15> =
+ let <_14> =
+ let <_13> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'or'
+ (_false, _13)
+ in call 'erlang':'or'
+ (_14, _false)
+ in _15
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_16>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_17>
+ when try
+ let <_19> =
+ let <_18> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'and'
+ (_18, _true)
+ in _19
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_20>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_21>
+ when try
+ let <_23> =
+ let <_22> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'not'
+ (_22)
+ in _23
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ <_24>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_25>
+ when try
+ let <_29> =
+ let <_28> =
+ let <_27> =
+ let <_26> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'not'
+ (_26)
+ in call 'erlang':'or'
+ (_false, _27)
+ in call 'erlang':'or'
+ (_28, _false)
+ in _29
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ <_30>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ 'ok'
+ ( <_31> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_31}})
+ -| ['compiler_generated'] )
+ end
+ ( <_32> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_32}})
+ -| ['compiler_generated'] )
+ end
+ ( <_33> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_33}})
+ -| ['compiler_generated'] )
+ end
+ ( <_34> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_34}})
+ -| ['compiler_generated'] )
+ end
+ ( <_35> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_35}})
+ -| ['compiler_generated'] )
+ end
+ ( <_36> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_36}})
+ -| ['compiler_generated'] )
+ end
+ ( <_37> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_37}})
+ -| ['compiler_generated'] )
+ end
+ ( <_769> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_769})
+ -| [{'function_name',{'rel_ops',1}}] )
+ -| ['compiler_generated'] )
+ end
+'literal_type_tests'/1 =
+ %% Line 873
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case 'guard_suite' of
+ <'guard_suite'> when 'true' ->
+ apply 'literal-type-tests-1'/1
+ (_config)
+ <_2> when 'true' ->
+ {'skip',[69|[110|[111|[117|[103|[104|[32|[116|[111|[32|[114|[117|[110|[32|[116|[104|[105|[115|[32|[99|[97|[115|[101|[32|[111|[110|[99|[101|[46]]]]]]]]]]]]]]]]]]]]]]]]]]]]]}
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_3})
+ -| [{'function_name',{'literal_type_tests',1}}] )
+ -| ['compiler_generated'] )
+ end
+'literal-type-tests-1'/1 =
+ %% Line 879
+ fun (_config) ->
+ 'ok'
+'basic_andalso_orelse'/1 =
+ %% Line 967
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_t> =
+ <apply 'id'/1
+ ({'type','integers',23,42})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[65|[['eif'|[['andalso'|[['=:='|[['element'|[1|['t']]]|[['quote'|['type']]]]]|[['=:='|[['tuple_size'|['t']]|[4]]]|[['=:='|[['element'|[2|['t']]]|[['quote'|['integers']]]]]]]]]|[['+'|[['element'|[3|['t']]]|[['element'|[4|['t']]]]]]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]})
+ let <_val> =
+ <case 1 of
+ <_2>
+ when try
+ let <_7> =
+ let <_6> =
+ case let <_3> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_3, 'type') of
+ <'true'> when 'true' ->
+ case let <_4> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_4, 4) of
+ <'true'> when 'true' ->
+ let <_5> =
+ call 'erlang':'element'
+ (2, _t)
+ in call 'erlang':'=:='
+ (_5, 'integers')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_6, 'true')
+ -| ['compiler_generated'] )
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_8> =
+ call 'erlang':'element'
+ (3, _t)
+ in let <_9> =
+ call 'erlang':'element'
+ (4, _t)
+ in call 'erlang':'+'
+ (_8, _9)
+ <_10>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <65> when 'true' ->
+ _val
+ ( <_11> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_11}})
+ -| ['compiler_generated'] )
+ end
+ ( <_47> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_47})
+ -| [{'function_name',{'basic_andalso_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+'basic-rt'/1 =
+ %% Line 1020
+ fun (_0) ->
+ case <_0> of
+ <_t>
+ when try
+ let <_5> =
+ let <_4> =
+ case call 'erlang':'is_tuple'
+ (_t) of
+ <'true'> when 'true' ->
+ case let <_1> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_1, 4) of
+ <'true'> when 'true' ->
+ case let <_2> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_2, 'type') of
+ <'true'> when 'true' ->
+ let <_3> =
+ call 'erlang':'element'
+ (2, _t)
+ in call 'erlang':'=='
+ (_3, 'integers')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_4, 'true')
+ -| ['compiler_generated'] )
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_6> =
+ call 'erlang':'element'
+ (3, _t)
+ in let <_7> =
+ call 'erlang':'element'
+ (4, _t)
+ in call 'erlang':'+'
+ (_6, _7)
+ <_t>
+ when try
+ let <_11> =
+ let <_10> =
+ case call 'erlang':'is_tuple'
+ (_t) of
+ <'true'> when 'true' ->
+ case let <_8> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_8, 2) of
+ <'true'> when 'true' ->
+ let <_9> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_9, 'vector')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_10, 'true')
+ -| ['compiler_generated'] )
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <call 'erlang':'element'
+ (2, _t)> of
+ <{_x,_y}> when 'true' ->
+ case 1 of
+ <_12>
+ when try
+ let <_16> =
+ let <_15> =
+ let <_13> =
+ call 'erlang':'is_float'
+ (_x)
+ in let <_14> =
+ call 'erlang':'is_float'
+ (_y)
+ in call 'erlang':'and'
+ (_13, _14)
+ in ( call 'erlang':'=:='
+ (_15, 'true')
+ -| ['compiler_generated'] )
+ in _16
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_19> =
+ let <_17> =
+ call 'erlang':'*'
+ (_x, _x)
+ in let <_18> =
+ call 'erlang':'*'
+ (_y, _y)
+ in call 'erlang':'+'
+ (_17, _18)
+ in call 'math':'sqrt'
+ (_19)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_20> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_20}})
+ -| ['compiler_generated'] )
+ end
+ <['+',_a,_b]> when 'true' ->
+ let <_22> =
+ let <_21> =
+ call 'erlang':'+'
+ (_a, _b)
+ in apply 'id'/1
+ (_21)
+ in call 'erlang':'*'
+ (_22, 2)
+ <{_r1,_r2}>
+ when try
+ let <_28> =
+ let <_27> =
+ case let <_23> =
+ call 'erlang':'size'
+ (_r1)
+ in call 'erlang':'=:='
+ (_23, 3) of
+ <'true'> when 'true' ->
+ case let <_24> =
+ call 'erlang':'element'
+ (1, _r1)
+ in call 'erlang':'=:='
+ (_24, 'Set') of
+ <'true'> when 'true' ->
+ case let <_25> =
+ call 'erlang':'size'
+ (_r2)
+ in call 'erlang':'=:='
+ (_25, 3) of
+ <'true'> when 'true' ->
+ let <_26> =
+ call 'erlang':'element'
+ (1, _r2)
+ in call 'erlang':'=:='
+ (_26, 'Set')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_27, 'true')
+ -| ['compiler_generated'] )
+ in _28
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_r1> =
+ <apply 'id'/1
+ (_r1)>
+ in let <_r2> =
+ <apply 'id'/1
+ (_r2)>
+ in _r1
+ <_t>
+ when try
+ let <_32> =
+ let <_31> =
+ case call 'erlang':'is_tuple'
+ (_t) of
+ <'true'> when 'true' ->
+ case let <_29> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_29, 2) of
+ <'true'> when 'true' ->
+ let <_30> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_30, 'klurf')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_31, 'true')
+ -| ['compiler_generated'] )
+ in _32
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_34> =
+ let <_33> =
+ call 'erlang':'element'
+ (2, _t)
+ in apply 'id'/1
+ (_33)
+ in call 'erlang':'*'
+ (3, _34)
+ <_35> when 'true' ->
+ 'error'
+ ( <_36> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_36})
+ -| [{'function_name',{'basic-rt',1}}] )
+ -| ['compiler_generated'] )
+ end
+'traverse_dcd'/1 =
+ %% Line 1043
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_l0> =
+ <[{'log_header','dcd_log',[49|[46|[48]]],'a','b','c'}|[{'log_header','dcd_log',[50|[46|[48]]],'a','b','c'}|[{'log_header','dcd_log',[48|[46|[48]]],'a','b','c'}|['blurf']]]]>
+ in case <apply 'traverse-dcd'/3
+ ({'cont',_l0}, 'log', 'funny')> of
+ <{'cont',[{'log_header','dcd_log',[48|[46|[48]]],'a','b','c'}|['blurf']],'log','funny'}> when 'true' ->
+ let <_l1> =
+ <[{'log_header','dcd_log',[49|[46|[48]]]}]>
+ in case <apply 'traverse-dcd'/3
+ ({'cont',_l1}, 'log', 'funny')> of
+ <{'cont',_l1,'log','funny'}> when 'true' ->
+ let <_l2> =
+ <[{'a','tuple'}]>
+ in case <apply 'traverse-dcd'/3
+ ({'cont',_l2}, 'log', 'funny')> of
+ <{'cont',_l2,'log','funny'}> when 'true' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_3}})
+ -| ['compiler_generated'] )
+ end
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'traverse_dcd',1}}] )
+ -| ['compiler_generated'] )
+ end
+'traverse-dcd'/3 =
+ %% Line 1066
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <{_cont,[_logh|_rest]},_log,_fun>
+ when try
+ let <_11> =
+ let <_6> =
+ case call 'erlang':'is_tuple'
+ (_logh) of
+ <'true'> when 'true' ->
+ case let <_3> =
+ call 'erlang':'tuple_size'
+ (_logh)
+ in call 'erlang':'=:='
+ (_3, 6) of
+ <'true'> when 'true' ->
+ case let <_4> =
+ call 'erlang':'element'
+ (1, _logh)
+ in call 'erlang':'=:='
+ (_4, 'log_header') of
+ <'true'> when 'true' ->
+ let <_5> =
+ call 'erlang':'element'
+ (2, _logh)
+ in call 'erlang':'=='
+ (_5, 'dcd_log')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_6, 'true')
+ -| ['compiler_generated'] )
+ in let <_12> =
+ let <_10> =
+ case call 'erlang':'is_tuple'
+ (_logh) of
+ <'true'> when 'true' ->
+ case let <_7> =
+ call 'erlang':'tuple_size'
+ (_logh)
+ in call 'erlang':'=:='
+ (_7, 6) of
+ <'true'> when 'true' ->
+ case let <_8> =
+ call 'erlang':'element'
+ (1, _logh)
+ in call 'erlang':'=:='
+ (_8, 'log_header') of
+ <'true'> when 'true' ->
+ let <_9> =
+ call 'erlang':'element'
+ (3, _logh)
+ in call 'erlang':'>='
+ (_9, [49|[46|[48]]])
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_10, 'true')
+ -| ['compiler_generated'] )
+ in call 'erlang':'and'
+ (_11, _12)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'traverse-dcd'/3
+ ({_cont,_rest}, _log, _fun)
+ <{_cont,_recs},_log,_fun> when 'true' ->
+ {_cont,_recs,_log,_fun}
+ ( <_15,_14,_13> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_15,_14,_13})
+ -| [{'function_name',{'traverse-dcd',3}}] )
+ -| ['compiler_generated'] )
+ end
+'check_qlc_hrl'/1 =
+ %% Line 1078
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_st> =
+ <{'r1','false','dum'}>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['foo']]|[['cqlc'|[['quote'|['qlc']]|[['quote'|['q']]|[['quote'|[[{'lc',1,2,3}]]]|['st']]]]]]]]})
+ let <_val> =
+ <apply 'cqlc'/4
+ ('qlc', 'q', [{'lc',1,2,3}], _st)>
+ in case <_val> of
+ <'foo'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'check_qlc_hrl',1}}] )
+ -| ['compiler_generated'] )
+ end
+'cqlc'/4 =
+ %% Line 1094
+ fun (_m,_f,_as,_st) ->
+ let <_arity> =
+ <call 'erlang':'length'
+ (_as)>
+ in case _as of
+ <[{'lc',_0,_1,_2}|_3]>
+ when try
+ let <_11> =
+ call 'erlang':'=:='
+ (_m, 'qlc')
+ in let <_12> =
+ call 'erlang':'=:='
+ (_f, 'q')
+ in let <_13> =
+ call 'erlang':'<'
+ (_arity, 3)
+ in let <_14> =
+ let <_10> =
+ let <_8> =
+ case let <_4> =
+ call 'erlang':'element'
+ (1, _st)
+ in call 'erlang':'=:='
+ (_4, 'r1') of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'fail'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in let <_9> =
+ let <_6> =
+ let <_5> =
+ call 'erlang':'tuple_size'
+ (_st)
+ in call 'erlang':'=:='
+ (_5, 3)
+ in let <_7> =
+ call 'erlang':'element'
+ (2, _st)
+ in call 'erlang':'and'
+ (_6, _7)
+ in call 'erlang':'and'
+ (_8, _9)
+ in call 'erlang':'not'
+ (_10)
+ in let <_15> =
+ call 'erlang':'and'
+ (_11, _12)
+ in let <_16> =
+ call 'erlang':'and'
+ (_15, _13)
+ in call 'erlang':'and'
+ (_16, _14)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'foo'
+ <_17> when 'true' ->
+ _st
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'andalso_semi'/1 =
+ %% Line 1106
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['andalso-semi-foo'|[0]]]]]})
+ let <_val> =
+ <apply 'andalso-semi-foo'/1
+ (0)>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_8> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_8})
+ -| [{'function_name',{'andalso_semi',1}}] )
+ -| ['compiler_generated'] )
+ end
+'andalso-semi-foo'/1 =
+ %% Line 1117
+ fun (_0) ->
+ case <_0> of
+ <_bar>
+ when try
+ let <_3> =
+ let <_1> =
+ case call 'erlang':'is_integer'
+ (_bar) of
+ <'true'> when 'true' ->
+ call 'erlang':'=:='
+ (_bar, 0)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in let <_2> =
+ call 'erlang':'=:='
+ (_bar, 1)
+ in call 'erlang':'or'
+ (_1, _2)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_4> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_4})
+ -| [{'function_name',{'andalso-semi-foo',1}}] )
+ -| ['compiler_generated'] )
+ end
+'andalso-semi-bar'/1 =
+ %% Line 1121
+ fun (_0) ->
+ case <_0> of
+ <_bar>
+ when try
+ let <_4> =
+ let <_2> =
+ case call 'erlang':'is_list'
+ (_bar) of
+ <'true'> when 'true' ->
+ let <_1> =
+ call 'erlang':'length'
+ (_bar)
+ in call 'erlang':'=:='
+ (_1, 3)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in let <_3> =
+ call 'erlang':'=:='
+ (_bar, 1)
+ in call 'erlang':'or'
+ (_2, _3)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'andalso-semi-bar',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t_tuple_size'/1 =
+ %% Line 1125
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[10|[['do-tuple-size'|[{1,2,3,4}]]]]]})
+ let <_val> =
+ <apply 'do-tuple-size'/1
+ ({1,2,3,4})>
+ in case <_val> of
+ <10> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_7> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_7})
+ -| [{'function_name',{'t_tuple_size',1}}] )
+ -| ['compiler_generated'] )
+ end
+'do-tuple-size'/1 =
+ %% Line 1139
+ fun (_0) ->
+ case <_0> of
+ <_t>
+ when try
+ let <_2> =
+ let <_1> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_1, 4)
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <_t> of
+ <{_a,_b,_c,_d}> when 'true' ->
+ let <_lfe0> =
+ <_a>
+ in let <_lfe1> =
+ <_b>
+ in let <_lfe2> =
+ <_c>
+ in let <_lfe3> =
+ <_d>
+ in let <_4> =
+ let <_3> =
+ call 'erlang':'+'
+ (_lfe0, _lfe1)
+ in call 'erlang':'+'
+ (_3, _lfe2)
+ in call 'erlang':'+'
+ (_4, _lfe3)
+ ( <_5> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_5}})
+ -| ['compiler_generated'] )
+ end
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'do-tuple-size',1}}] )
+ -| ['compiler_generated'] )
+ end
+'ludicrous-tuple-size'/1 =
+ %% Line 1144
+ fun (_0) ->
+ case <_0> of
+ <_t>
+ when try
+ let <_2> =
+ let <_1> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_1, 40652400101488115101757819767848575661943)
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_t>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_3, 18446744073709551616)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_t>
+ when try
+ let <_8> =
+ let <_6> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in let <_7> =
+ let <_5> =
+ call 'erlang':'bsl'
+ (1, 64)
+ in call 'erlang':'-'
+ (_5, 1)
+ in call 'erlang':'=:='
+ (_6, _7)
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_t>
+ when try
+ let <_10> =
+ let <_9> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_9, 18446744073709551615)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_11> when 'true' ->
+ 'error'
+ ( <_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12})
+ -| [{'function_name',{'ludicrous-tuple-size',1}}] )
+ -| ['compiler_generated'] )
+ end
+'mask-error'/1 =
+ %% Line 1152
+ fun (_0) ->
+ case <_0> of
+ <{'EXIT',{_err,_1}}> when 'true' ->
+ _err
+ <_else> when 'true' ->
+ _else
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'mask-error',1}}] )
+ -| ['compiler_generated'] )
+ end
+'binary_part'/1 =
+ %% Line 1156
+ fun (_0) ->
+ case <_0> of
+ <'doc'> when 'true' ->
+ [84|[101|[115|[116|[115|[32|[116|[104|[101|[32|[98|[105|[110|[97|[114|[121|[95|[112|[97|[114|[116|[47|[50|[44|[51|[32|[103|[117|[97|[114|[100|[32|[40|[71|[67|[41|[32|[98|[105|[102|[39|[115]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat',1,['bp-test',#{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<2>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#]]})
+ let <_val> =
+ <apply 'bp-test'/1
+ (#{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<2>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)>
+ in case <_val> of
+ <1> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_53> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_53})
+ -| [{'function_name',{'binary_part',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test'/1 =
+ %% Line 1225
+ fun (_0) ->
+ case <_0> of
+ <_b>
+ when try
+ let <_2> =
+ let <_1> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_1, 137)
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'binary_part'
+ (_b, {1,1})
+ in call 'erlang':'=:='
+ (_3, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b>
+ when try
+ let <_6> =
+ let <_5> =
+ call 'erlang':'binary_part'
+ (_b, 1, 1)
+ in call 'erlang':'=:='
+ (_5, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b>
+ when try
+ let <_8> =
+ let <_7> =
+ call 'erlang':'binary_part'
+ (_b, {1,2})
+ in call 'erlang':'=:='
+ (_7, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_9> when 'true' ->
+ 'error'
+ ( <_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_10})
+ -| [{'function_name',{'bp-test',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test'/2 =
+ %% Line 1232
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_b,_a>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_2, _a)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'binary_part'
+ (_b, {_a,1})
+ in call 'erlang':'=:='
+ (_4, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, _a, 1)
+ in call 'erlang':'=:='
+ (_6, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, {_a,2})
+ in call 'erlang':'=:='
+ (_8, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_10,_11> when 'true' ->
+ 'error'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'bp-test',2}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test-x'/2 =
+ %% Line 1239
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_b,_a>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_2, _a)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'binary_part'
+ (_b, _a)
+ in call 'erlang':'=:='
+ (_4, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, _a)
+ in call 'erlang':'=:='
+ (_6, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, _a)
+ in call 'erlang':'=:='
+ (_8, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_10,_11> when 'true' ->
+ 'error'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'bp-test-x',2}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test-y'/2 =
+ %% Line 1246
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_b,_a>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_2, _a)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'binary_part'
+ (_b, {1,_a})
+ in call 'erlang':'=:='
+ (_4, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, 1, _a)
+ in call 'erlang':'=:='
+ (_6, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, {1,_a})
+ in call 'erlang':'=:='
+ (_8, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_10,_11> when 'true' ->
+ 'error'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'bp-test-y',2}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test'/3 =
+ %% Line 1253
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <_b,_a,_3>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_4, _a)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a,_c>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, {_a,_c})
+ in call 'erlang':'=:='
+ (_6, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a,_c>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, _a, _c)
+ in call 'erlang':'=:='
+ (_8, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a,_c>
+ when try
+ let <_11> =
+ let <_10> =
+ call 'erlang':'binary_part'
+ (_b, {_a,_c})
+ in call 'erlang':'=:='
+ (_10, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_12,_13,_14> when 'true' ->
+ 'error'
+ ( <_17,_16,_15> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_17,_16,_15})
+ -| [{'function_name',{'bp-test',3}}] )
+ -| ['compiler_generated'] )
+ end
+'id'/1 =
+ %% Line 1262
+ fun (_i) ->
+ _i
+'check'/2 =
+ %% Line 1264
+ fun (_f,_result) ->
+ case apply _f
+ () of
+ <_r>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_r, _result)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_other> when 'true' ->
+ do call 'lfe_io':'format'
+ ([69|[120|[112|[101|[99|[116|[101|[100|[58|[32|[126|[112|[10]]]]]]]]]]]]], [_result])
+ do call 'lfe_io':'format'
+ ([32|[32|[32|[32|[32|[71|[111|[116|[58|[32|[126|[112|[10]]]]]]]]]]]]], [_other])
+ call 'test_server':'fail'
+ ()
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'fc'/1 =
+ %% Line 1272
+ fun (_0) ->
+ case <_0> of
+ <{'EXIT',{'function_clause'}}> when 'true' ->
+ 'ok'
+ <{'EXIT',{{'case_clause',_1},_2}}> when 'true' ->
+ 'ok'
+ ( <_3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_3})
+ -| [{'function_name',{'fc',1}}] )
+ -| ['compiler_generated'] )
+ end
+'$handle_undefined_function'/2 =
+ %% Line 29
+ fun (_f,_as) ->
+ case let <_0> =
+ call 'lfe_env':'new'
+ ()
+ in apply 'LFE-EXPAND-EXPORTED-MACRO'/3
+ (_f, _as, _0) of
+ <{'yes',_exp}> when 'true' ->
+ call 'lfe_eval':'expr'
+ (_exp)
+ <'no'> when 'true' ->
+ let <_a,_b> =
+ <_f,_as>
+ in call 'error_handler':'raise_undef_exception'
+ ('lfe_guard_SUITE', _a, _b)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'LFE-EXPAND-EXPORTED-MACRO'/3 =
+ %% Line 29
+ fun (_2,_1,_0) ->
+ 'no'
+'module_info'/0 =
+ fun () ->
+ call 'erlang':'get_module_info'
+ ('lfe_guard_SUITE')
+'module_info'/1 =
+ fun (_x) ->
+ call 'erlang':'get_module_info'
+ ('lfe_guard_SUITE', _x)
+end
diff --git a/lib/compiler/test/map_SUITE.erl b/lib/compiler/test/map_SUITE.erl
index 36e82c1459..5e90b79aa2 100644
--- a/lib/compiler/test/map_SUITE.erl
+++ b/lib/compiler/test/map_SUITE.erl
@@ -1559,7 +1559,6 @@ t_warn_pair_key_overloaded(Config) when is_list(Config) ->
"hi2" => lists:subtract([1,2],[1]),
"hi3" => +3,
"hi1" => erlang:min(1,2),
- "hi1" => erlang:hash({1,2},35),
"hi1" => erlang:phash({1,2},33),
"hi1" => erlang:phash2({1,2},34),
"hi1" => erlang:integer_to_binary(1337),
diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl
index 31402ac717..52b2da05f7 100644
--- a/lib/compiler/test/match_SUITE.erl
+++ b/lib/compiler/test/match_SUITE.erl
@@ -24,7 +24,7 @@
pmatch/1,mixed/1,aliases/1,non_matching_aliases/1,
match_in_call/1,untuplify/1,shortcut_boolean/1,letify_guard/1,
selectify/1,underscore/1,match_map/1,map_vars_used/1,
- coverage/1,grab_bag/1]).
+ coverage/1,grab_bag/1,literal_binary/1]).
-include_lib("common_test/include/ct.hrl").
@@ -40,7 +40,7 @@ groups() ->
match_in_call,untuplify,
shortcut_boolean,letify_guard,selectify,
underscore,match_map,map_vars_used,coverage,
- grab_bag]}].
+ grab_bag,literal_binary]}].
init_per_suite(Config) ->
@@ -574,6 +574,23 @@ grab_bag_remove_failure([{stretch,_,Mi}=Stretch | Specs], Unit, _MaxFailure) ->
ok
end.
+%% Regression in 19.0, reported by Alexei Sholik
+literal_binary(_Config) ->
+ 3 = literal_binary_match(bar, <<"y">>),
+
+ %% While we are at it, also test the remaining code paths
+ %% in literal_binary_match/2.
+ 1 = literal_binary_match(bar, <<"x">>),
+ 2 = literal_binary_match(foo, <<"x">>),
+ 3 = literal_binary_match(foo, <<"y">>),
+ fail = literal_binary_match(bar, <<"z">>),
+ fail = literal_binary_match(foo, <<"z">>),
+ ok.
+
+literal_binary_match(bar, <<"x">>) -> 1;
+literal_binary_match(_, <<"x">>) -> 2;
+literal_binary_match(_, <<"y">>) -> 3;
+literal_binary_match(_, _) -> fail.
id(I) -> I.
diff --git a/lib/compiler/test/misc_SUITE.erl b/lib/compiler/test/misc_SUITE.erl
index f543f0d4de..4bd884d86b 100644
--- a/lib/compiler/test/misc_SUITE.erl
+++ b/lib/compiler/test/misc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -161,11 +161,12 @@ md5_1(Beam) ->
%% Cover some code that handles internal errors.
silly_coverage(Config) when is_list(Config) ->
- %% sys_core_fold, sys_core_setel, v3_kernel
+ %% sys_core_fold, sys_core_bsm, sys_core_setel, v3_kernel
BadCoreErlang = {c_module,[],
name,[],[],
[{{c_var,[],{foo,2}},seriously_bad_body}]},
expect_error(fun() -> sys_core_fold:module(BadCoreErlang, []) end),
+ expect_error(fun() -> sys_core_bsm:module(BadCoreErlang, []) end),
expect_error(fun() -> sys_core_dsetel:module(BadCoreErlang, []) end),
expect_error(fun() -> v3_kernel:module(BadCoreErlang, []) end),
@@ -229,14 +230,6 @@ silly_coverage(Config) when is_list(Config) ->
{label,2}|non_proper_list]}],99},
expect_error(fun() -> beam_except:module(ExceptInput, []) end),
- %% beam_bool
- BoolInput = {?MODULE,[{foo,0}],[],
- [{function,foo,0,2,
- [{label,1},
- {func_info,{atom,?MODULE},{atom,foo},0},
- {label,2}|non_proper_list]}],99},
- expect_error(fun() -> beam_bool:module(BoolInput, []) end),
-
%% beam_dead. This is tricky. Our function must look OK to
%% beam_utils:clean_labels/1, but must crash beam_dead.
DeadInput = {?MODULE,[{foo,0}],[],
@@ -288,6 +281,23 @@ silly_coverage(Config) when is_list(Config) ->
{block,[a|b]}]}],0},
expect_error(fun() -> beam_receive:module(ReceiveInput, []) end),
+ %% beam_record.
+ RecordInput = {?MODULE,[{foo,0}],[],
+ [{function,foo,1,2,
+ [{label,1},
+ {func_info,{atom,?MODULE},{atom,foo},1},
+ {label,2},
+ {test,is_tuple,{f,1},[{x,0}]},
+ {test,test_arity,{f,1},[{x,0},3]},
+ {block,[{set,[{x,1}],[{x,0}],{get_tuple_element,0}}]},
+ {test,is_eq_exact,{f,1},[{x,1},{atom,bar}]},
+ {block,[{set,[{x,2}],[{x,0}],{get_tuple_element,1}}|a]},
+ {test,is_eq_exact,{f,1},[{x,2},{integer,1}]},
+ {block,[{set,[{x,0}],[{atom,ok}],move}]},
+ return]}],0},
+
+ expect_error(fun() -> beam_record:module(RecordInput, []) end),
+
BeamZInput = {?MODULE,[{foo,0}],[],
[{function,foo,0,2,
[{label,1},
diff --git a/lib/compiler/test/num_bif_SUITE.erl b/lib/compiler/test/num_bif_SUITE.erl
deleted file mode 100644
index 7eac90bac3..0000000000
--- a/lib/compiler/test/num_bif_SUITE.erl
+++ /dev/null
@@ -1,285 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(num_bif_SUITE).
-
--include_lib("common_test/include/ct.hrl").
-
-%% Tests optimization of the BIFs:
-%% abs/1
-%% float/1
-%% float_to_list/1
-%% integer_to_list/1
-%% list_to_float/1
-%% list_to_integer/1
-%% round/1
-%% trunc/1
-
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2, t_abs/1, t_float/1,
- t_float_to_list/1, t_integer_to_list/1,
- t_list_to_integer/1,
- t_list_to_float_safe/1, t_list_to_float_risky/1,
- t_round/1, t_trunc/1]).
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- test_lib:recompile(?MODULE),
- [t_abs, t_float, t_float_to_list, t_integer_to_list,
- {group, t_list_to_float}, t_list_to_integer, t_round,
- t_trunc].
-
-groups() ->
- [{t_list_to_float, [],
- [t_list_to_float_safe, t_list_to_float_risky]}].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-t_abs(Config) when is_list(Config) ->
- %% Floats.
- 5.5 = abs(5.5),
- 0.0 = abs(0.0),
- 100.0 = abs(-100.0),
-
- %% Integers.
- 5 = abs(5),
- 0 = abs(0),
- 100 = abs(-100),
-
- %% The largest smallnum. OTP-3190.
- X = (1 bsl 27) - 1,
- X = abs(X),
- X = abs(X-1)+1,
- X = abs(X+1)-1,
- X = abs(-X),
- X = abs(-X-1)-1,
- X = abs(-X+1)+1,
-
- %% Bignums.
- BigNum = 13984792374983749,
- BigNum = abs(BigNum),
- BigNum = abs(-BigNum),
- ok.
-
-t_float(Config) when is_list(Config) ->
- 0.0 = float(0),
- 2.5 = float(2.5),
- 0.0 = float(0.0),
- -100.55 = float(-100.55),
- 42.0 = float(42),
- -100.0 = float(-100),
-
- %% Bignums.
- 4294967305.0 = float(4294967305),
- -4294967305.0 = float(-4294967305),
-
- %% Extremly big bignums.
- Big = list_to_integer(lists:duplicate(2000, $1)),
- {'EXIT', {badarg, _}} = (catch float(Big)),
-
- %% Invalid types and lists.
- {'EXIT', {badarg, _}} = (catch list_to_integer(atom)),
- {'EXIT', {badarg, _}} = (catch list_to_integer(123)),
- {'EXIT', {badarg, _}} = (catch list_to_integer([$1, [$2]])),
- {'EXIT', {badarg, _}} = (catch list_to_integer("1.2")),
- {'EXIT', {badarg, _}} = (catch list_to_integer("a")),
- {'EXIT', {badarg, _}} = (catch list_to_integer("")),
- ok.
-
-
-%% Tests float_to_list/1.
-
-t_float_to_list(Config) when is_list(Config) ->
- test_ftl("0.0e+0", 0.0),
- test_ftl("2.5e+1", 25.0),
- test_ftl("2.5e+0", 2.5),
- test_ftl("2.5e-1", 0.25),
- test_ftl("-3.5e+17", -350.0e15),
- ok.
-
-test_ftl(Expect, Float) ->
- %% No on the next line -- we want the line number from t_float_to_list.
- Expect = remove_zeros(lists:reverse(float_to_list(Float)), []).
-
-%% Removes any non-significant zeros in a floating point number.
-%% Example: 2.500000e+01 -> 2.5e+1
-
-remove_zeros([$+, $e|Rest], [$0, X|Result]) ->
- remove_zeros([$+, $e|Rest], [X|Result]);
-remove_zeros([$-, $e|Rest], [$0, X|Result]) ->
- remove_zeros([$-, $e|Rest], [X|Result]);
-remove_zeros([$0, $.|Rest], [$e|Result]) ->
- remove_zeros(Rest, [$., $0, $e|Result]);
-remove_zeros([$0|Rest], [$e|Result]) ->
- remove_zeros(Rest, [$e|Result]);
-remove_zeros([Char|Rest], Result) ->
- remove_zeros(Rest, [Char|Result]);
-remove_zeros([], Result) ->
- Result.
-
-%% Tests integer_to_list/1.
-
-t_integer_to_list(Config) when is_list(Config) ->
- "0" = integer_to_list(0),
- "42" = integer_to_list(42),
- "-42" = integer_to_list(-42),
- "-42" = integer_to_list(-42),
- "32768" = integer_to_list(32768),
- "268435455" = integer_to_list(268435455),
- "-268435455" = integer_to_list(-268435455),
- "123456932798748738738" = integer_to_list(123456932798748738738),
- Big_List = lists:duplicate(2000, $1),
- Big = list_to_integer(Big_List),
- Big_List = integer_to_list(Big),
- ok.
-
-%% Tests list_to_float/1.
-
-
-t_list_to_float_safe(Config) when is_list(Config) ->
- 0.0 = list_to_float("0.0"),
- 0.0 = list_to_float("-0.0"),
- 0.5 = list_to_float("0.5"),
- -0.5 = list_to_float("-0.5"),
- 100.0 = list_to_float("1.0e2"),
- 127.5 = list_to_float("127.5"),
- -199.5 = list_to_float("-199.5"),
-
- {'EXIT', {badarg, _}} = (catch list_to_float("0")),
- {'EXIT', {badarg, _}} = (catch list_to_float("0..0")),
- {'EXIT', {badarg, _}} = (catch list_to_float("0e12")),
- {'EXIT', {badarg, _}} = (catch list_to_float("--0.0")),
-%% {'EXIT', {badarg, _}} = (catch list_to_float("0.0e+99999999")),
-
- ok.
-
-%% This might crash the emulator...
-%% (Known to crash the Unix version of Erlang 4.4.1)
-
-t_list_to_float_risky(Config) when is_list(Config) ->
- Many_Ones = lists:duplicate(25000, $1),
- _ = list_to_float("2."++Many_Ones),
- {'EXIT', {badarg, _}} = (catch list_to_float("2"++Many_Ones)),
- ok.
-
-%% Tests list_to_integer/1.
-
-t_list_to_integer(Config) when is_list(Config) ->
- 0 = list_to_integer("0"),
- 0 = list_to_integer("00"),
- 0 = list_to_integer("-0"),
- 1 = list_to_integer("1"),
- -1 = list_to_integer("-1"),
- 42 = list_to_integer("42"),
- -12 = list_to_integer("-12"),
- 32768 = list_to_integer("32768"),
- 268435455 = list_to_integer("268435455"),
- -268435455 = list_to_integer("-268435455"),
-
- %% Bignums.
- 123456932798748738738 = list_to_integer("123456932798748738738"),
- _ = list_to_integer(lists:duplicate(2000, $1)),
- ok.
-
-%% Tests round/1.
-
-t_round(Config) when is_list(Config) ->
- 0 = round(0.0),
- 0 = round(0.4),
- 1 = round(0.5),
- 0 = round(-0.4),
- -1 = round(-0.5),
- 255 = round(255.3),
- 256 = round(255.6),
- -1033 = round(-1033.3),
- -1034 = round(-1033.6),
-
- % OTP-3722:
- X = (1 bsl 27) - 1,
- MX = -X,
- MXm1 = -X-1,
- MXp1 = -X+1,
- F = X + 0.0,
- X = round(F),
- X = round(F+1)-1,
- X = round(F-1)+1,
- MX = round(-F),
- MXm1 = round(-F-1),
- MXp1 = round(-F+1),
-
- X = round(F+0.1),
- X = round(F+1+0.1)-1,
- X = round(F-1+0.1)+1,
- MX = round(-F+0.1),
- MXm1 = round(-F-1+0.1),
- MXp1 = round(-F+1+0.1),
-
- X = round(F-0.1),
- X = round(F+1-0.1)-1,
- X = round(F-1-0.1)+1,
- MX = round(-F-0.1),
- MXm1 = round(-F-1-0.1),
- MXp1 = round(-F+1-0.1),
-
- 0.5 = abs(round(F+0.5)-(F+0.5)),
- 0.5 = abs(round(F-0.5)-(F-0.5)),
- 0.5 = abs(round(-F-0.5)-(-F-0.5)),
- 0.5 = abs(round(-F+0.5)-(-F+0.5)),
-
- %% Bignums.
- 4294967296 = round(4294967296.1),
- 4294967297 = round(4294967296.9),
- -4294967296 = -round(4294967296.1),
- -4294967297 = -round(4294967296.9),
- ok.
-
-t_trunc(Config) when is_list(Config) ->
- 0 = trunc(0.0),
- 5 = trunc(5.3333),
- -10 = trunc(-10.978987),
- % The largest smallnum, converted to float (OTP-3722):
- X = (1 bsl 27) - 1,
- F = X + 0.0,
- io:format("X = ~p/~w/~w, F = ~p/~w/~w, trunc(F) = ~p/~w/~w~n",
- [X, X, binary_to_list(term_to_binary(X)),
- F, F, binary_to_list(term_to_binary(F)),
- trunc(F), trunc(F), binary_to_list(term_to_binary(trunc(F)))]),
- X = trunc(F),
- X = trunc(F+1)-1,
- X = trunc(F-1)+1,
- X = -trunc(-F),
- X = -trunc(-F-1)-1,
- X = -trunc(-F+1)+1,
-
- %% Bignums.
- 4294967305 = trunc(4294967305.7),
- -4294967305 = trunc(-4294967305.7),
- ok.
diff --git a/lib/compiler/test/overridden_bif_SUITE.erl b/lib/compiler/test/overridden_bif_SUITE.erl
new file mode 100644
index 0000000000..ce18916515
--- /dev/null
+++ b/lib/compiler/test/overridden_bif_SUITE.erl
@@ -0,0 +1,101 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(overridden_bif_SUITE).
+-compile({no_auto_import,[is_reference/1,size/1]}).
+
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ overridden_bif/1]).
+
+-include_lib("common_test/include/ct.hrl").
+
+%% Used by overridden_bif/1.
+-import(gb_sets, [size/1]).
+-import(test_lib, [binary/1]).
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,1}}].
+
+all() ->
+ test_lib:recompile(?MODULE),
+ [{group,p}].
+
+groups() ->
+ [{p,test_lib:parallel(),
+ [overridden_bif
+ ]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
+ Config.
+
+end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
+ ok.
+
+overridden_bif(_Config) ->
+ L = [-3,-2,-1,0,1,2,3,4],
+ [-3,0,3] = do_overridden_bif_1(L),
+ [-2,0,2,4] = do_overridden_bif_2(L),
+ [3] = do_overridden_bif_3(L),
+ [2,4] = do_overridden_bif_4(L),
+
+ Set = gb_sets:from_list(L),
+ [Set] = do_overridden_bif_5([gb_sets:singleton(42),Set]),
+
+ [100,0] = do_overridden_bif_6([100|L]),
+ ok.
+
+do_overridden_bif_1(L) ->
+ [E || E <- L, is_reference(E)].
+
+do_overridden_bif_2(L) ->
+ [E || E <- L, port(E)].
+
+do_overridden_bif_3(L) ->
+ [E || E <- L, (is_reference(E) andalso E > 0)].
+
+do_overridden_bif_4(L) ->
+ [E || E <- L, (port(E) andalso E > 0)].
+
+do_overridden_bif_5(L) ->
+ [E || E <- L, size(E) > 1].
+
+do_overridden_bif_6(L) ->
+ [E || E <- L, binary(E)].
+
+is_reference(N) ->
+ N rem 3 =:= 0.
+
+port(N) ->
+ N rem 2 =:= 0.
diff --git a/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl b/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl
index 9b72432246..dbd2419ad2 100644
--- a/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl
+++ b/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl
@@ -27,12 +27,12 @@
-record(r3, {a = fun(_) -> #r1{} end(1), b}).
t() ->
- foo = fun(A) when A#r1.a > A#r1.b -> foo end(#r1{b = 2}),
- 0 = fun(A) when A#r2.a -> 0 end(#r2{a = true}),
+ foo = rec_call(fun(A) when A#r1.a > A#r1.b -> foo end, #r1{b = 2}),
+ 0 = rec_call(fun(A) when A#r2.a -> 0 end, #r2{a = true}),
1 = fun(A) when (#r1{a = A})#r1.a > 2 -> 1 end(3),
2 = fun(N) when ((#r2{a = #r{a = 4}, b = length([a,b,c])})#r2.a)#r.a > N ->
- 2 end(2),
- 3 = fun(A) when (A#r2.a)#r1.a =:= 3 -> 3 end(#r2{a = #r1{a = 3}}),
+ 2 end(2),
+ 3 = rec_call(fun(A) when (A#r2.a)#r1.a =:= 3 -> 3 end, #r2{a = #r1{a = 3}}),
ok = fun() ->
F = fun(A) when record(A#r.a, r1) -> 4;
(A) when record(A#r1.a, r1) -> 5
@@ -41,9 +41,9 @@ t() ->
4 = F(#r{a = #r1{}}),
ok
end(),
- 3 = fun(A) when record(A#r1.a, r),
- (A#r1.a)#r.a > 3 -> 3
- end(#r1{a = #r{a = 4}}),
+ 3 = rec_call(fun(A) when record(A#r1.a, r),
+ (A#r1.a)#r.a > 3 -> 3
+ end, #r1{a = #r{a = 4}}),
7 = fun(A) when record(A#r3.a, r1) -> 7 end(#r3{}),
[#r1{a = 2,b = 1}] =
fun() ->
@@ -71,9 +71,10 @@ t() ->
(_) -> p
end(#r1{a = 2}),
- 3 = fun(A) when A#r1.a > 3,
- record(A, r1) -> 3
- end(#r1{a = 5}),
+ o = rec_call(fun(A) when (A#r1.a =:= 2) orelse (A#r2.a =:= 1) -> o end, #r1{a = 2}),
+ o = rec_call(fun(A) when A#r1.a =:= 2; A#r2.a =:= 1 -> o end, #r2{a = 1}),
+
+ 3 = rec_call(fun(A) when A#r1.a > 3, record(A, r1) -> 3 end, #r1{a = 5}),
ok = fun() ->
F = fun(A) when (A#r2.a =:= 1) orelse (A#r2.a) -> 2;
@@ -93,6 +94,8 @@ t() ->
(_) -> b
end(#r1{a = 1}),
+ a = rec_call(fun(A) when not (A#r.a =:= 1) or false -> a end, #r{a = 42}),
+
ok = fun() ->
F = fun(A) when not (A#r.a =:= 1) -> yes;
(_) -> no
@@ -103,14 +106,14 @@ t() ->
ok
end(),
- a = fun(A) when record(A, r),
- A#r.a =:= 1,
- A#r.b =:= 2 ->a
- end(#r{a = 1, b = 2}),
- a = fun(A) when erlang:is_record(A, r),
- A#r.a =:= 1,
- A#r.b =:= 2 -> a
- end(#r{a = 1, b = 2}),
+ a = rec_call(fun(A) when record(A, r),
+ A#r.a =:= 1,
+ A#r.b =:= 2 -> a
+ end, #r{a = 1, b = 2}),
+ a = rec_call(fun(A) when erlang:is_record(A, r),
+ A#r.a =:= 1,
+ A#r.b =:= 2 -> a
+ end, #r{a = 1, b = 2}),
a = fun(A) when is_record(A, r),
A#r.a =:= 1,
A#r.b =:= 2 -> a
@@ -144,8 +147,7 @@ t() ->
ok
end(),
- both = fun(A) when A#r.a, A#r.b -> both
- end(#r{a = true, b = true}),
+ both = rec_call(fun(A) when A#r.a, A#r.b -> both end, #r{a = true, b = true}),
ok = fun() ->
F = fun(A, B) when ((A#r1.a) orelse (B#r2.a))
@@ -176,3 +178,24 @@ t() ->
ok.
+rec_call(F, Rec) ->
+ Corrupted1 = setelement(1, Rec, wrong),
+ Corrupted2 = erlang:append_element(Rec, extra),
+ Corrupted3 = erlang:append_element(Corrupted1, extra),
+ fc(F, Corrupted1),
+ fc(F, Corrupted2),
+ fc(F, Corrupted3),
+ F(Rec).
+
+fc(F, Term) ->
+ try
+ F(Term),
+ error(expected_to_fail)
+ catch
+ error:function_clause ->
+ ok;
+ error:{case_clause,_} ->
+ Comp = ?MODULE:module_info(compile),
+ {_,Opts} = lists:keyfind(options, 1, Comp),
+ true = lists:member(inline, Opts)
+ end.
diff --git a/lib/compiler/test/regressions_SUITE.erl b/lib/compiler/test/regressions_SUITE.erl
index 7d2c2ac974..7a6fe08c73 100644
--- a/lib/compiler/test/regressions_SUITE.erl
+++ b/lib/compiler/test/regressions_SUITE.erl
@@ -24,7 +24,7 @@
-export([all/0,groups/0,init_per_testcase/2,end_per_testcase/2,suite/0]).
-export([maps/1]).
-groups() ->
+groups() ->
[{p,test_lib:parallel(),
[maps]}].
@@ -38,7 +38,7 @@ suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap,{minutes,2}}].
-all() ->
+all() ->
test_lib:recompile(?MODULE),
[{group,p}].
@@ -48,7 +48,18 @@ maps(Config) when is_list(Config) ->
Ts = [{beam_bool_get_elements,
<<"century(#{ron := operator}, _century) ->
if 0.0; _century, _century, _century -> _century end.
- ">>}],
+ ">>},
+ {empty_map_clauses,
+ <<"politics(#{}, researchers) -> concerned;
+ politics(#{[] := _}, workers) -> dot;
+ politics(#{[] := ct}, counsel) -> calls.
+ ">>},
+ {empty_map_clauses_variable,
+ <<"georgia(#{a := effectively}, ratio, is, eventually) -> teens;
+ georgia(#{a := government}, knowledge, poker, partly) -> signed;
+ georgia(#{}, recording, bring, vital) -> divided;
+ georgia(#{0 := 0}, articles, brought, #{true := true, a := There}) -> There.
+ ">>}],
ok = run(Config, Ts),
ok.
@@ -58,7 +69,7 @@ run(Config, Tests) ->
F = fun({N,P}) ->
io:format("Compiling test for: ~w~n", [N]),
case catch run_test(Config, P) of
- {'EXIT', Reason} ->
+ {'EXIT', Reason} ->
io:format("~nTest ~p failed.~nReason: ~p~n",
[N, Reason]),
fail();
diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl
index d5b79e2357..8954a9f5fb 100644
--- a/lib/compiler/test/test_lib.erl
+++ b/lib/compiler/test/test_lib.erl
@@ -22,7 +22,10 @@
-include_lib("common_test/include/ct.hrl").
-compile({no_auto_import,[binary_part/2]}).
-export([id/1,recompile/1,parallel/0,uniq/0,opt_opts/1,get_data_dir/1,
- is_cloned_mod/1,smoke_disasm/1,p_run/2,binary_part/2]).
+ is_cloned_mod/1,smoke_disasm/1,p_run/2]).
+
+%% Used by test case that override BIFs.
+-export([binary_part/2,binary/1]).
id(I) -> I.
@@ -151,3 +154,7 @@ p_run_loop(Test, List, N, Refs0, Errors0, Ws0) ->
%% This is for the misc_SUITE:override_bif testcase
binary_part(_A,_B) ->
dummy.
+
+%% This is for overridden_bif_SUITE.
+binary(N) ->
+ N rem 10 =:= 0.
diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl
index f884e6e7d6..857995b6a6 100644
--- a/lib/compiler/test/warnings_SUITE.erl
+++ b/lib/compiler/test/warnings_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@
comprehensions/1,maps/1,maps_bin_opt_info/1,
redundant_boolean_clauses/1,
latin1_fallback/1,underscore/1,no_warnings/1,
- bit_syntax/1]).
+ bit_syntax/1,inlining/1]).
init_per_testcase(_Case, Config) ->
Config.
@@ -65,7 +65,7 @@ groups() ->
bin_opt_info,bin_construction,comprehensions,maps,
maps_bin_opt_info,
redundant_boolean_clauses,latin1_fallback,
- underscore,no_warnings,bit_syntax]}].
+ underscore,no_warnings,bit_syntax,inlining]}].
init_per_suite(Config) ->
Config.
@@ -281,7 +281,6 @@ bad_arith(Config) when is_list(Config) ->
{3,sys_core_fold,{eval_failure,badarith}},
{9,sys_core_fold,nomatch_guard},
{9,sys_core_fold,{eval_failure,badarith}},
- {9,sys_core_fold,{no_effect,{erlang,is_integer,1}}},
{10,sys_core_fold,nomatch_guard},
{10,sys_core_fold,{eval_failure,badarith}},
{15,sys_core_fold,{eval_failure,badarith}}
@@ -530,7 +529,7 @@ bin_opt_info(Config) when is_list(Config) ->
Code,
[bin_opt_info],
{warnings,
- [{4,sys_core_fold,orig_bin_var_used_in_guard},
+ [{4,sys_core_bsm,orig_bin_var_used_in_guard},
{5,beam_bsm,{no_bin_opt,{{t1,1},no_suitable_bs_start_match}}},
{9,beam_bsm,{no_bin_opt,
{binary_used_in,{extfunc,erlang,split_binary,2}}}} ]}}],
@@ -629,7 +628,112 @@ maps(Config) when is_list(Config) ->
id(I) -> I.
">>,
[],
- []}],
+ []},
+ {repeated_keys1,
+ <<"
+ foo1() ->
+ #{a=>1,
+ b=> 2,
+ a=>3}.
+
+ bar1(M) ->
+ M#{a=>1, b=> 2, a:=3}.
+
+ baz1(M) ->
+ M#{a=>1, b=> 2, a:=3}.
+
+ foo2() ->
+ #{\"a\"=>1, \"b\"=> 2, \"a\"=>3}.
+
+ bar2(M) ->
+ M#{\"a\"=>1, \"b\"=> 2, \"a\":=3}.
+
+ baz2(M) ->
+ M#{\"a\"=>1, \"b\"=> 2, \"a\":=3}.
+
+ foo3() ->
+ #{\"a\"=>1,
+ \"b\"=> 2,
+ \"a\"=>3}.
+
+ bar3(M) ->
+ M#{\"a\"=>1, \"b\"=> 2, \"a\":=3}.
+
+ baz3(M) ->
+ M#{<<\"a\">>=>1, <<\"b\">>=> 2, <<\"a\">>:=3}.
+ ">>,
+ [],
+ {warnings,[{3,v3_core,{map_key_repeated,a}},
+ {8,v3_core,{map_key_repeated,a}},
+ {11,v3_core,{map_key_repeated,a}},
+ {14,v3_core,{map_key_repeated,"a"}},
+ {17,v3_core,{map_key_repeated,"a"}},
+ {20,v3_core,{map_key_repeated,"a"}},
+ {23,v3_core,{map_key_repeated,"a"}},
+ {28,v3_core,{map_key_repeated,"a"}},
+ {31,v3_core,{map_key_repeated,<<"a">>}}]}},
+ {repeated_keys2,
+ <<"
+ foo4(K) ->
+ #{\"a\"=>1, K => 1, \"b\"=> 2, \"a\"=>3, K=>2}.
+
+ bar4(M,K) ->
+ M#{a=>1, K =>1, b=> 2, a:=3, K=>2}.
+
+ baz4(M,K) ->
+ M#{<<\"a\">>=>1,
+ K => 1, <<\"b\">>=> 2,
+ <<\"a\">>:=3, K=>2}.
+
+ foo5(K) ->
+ #{{\"a\",1}=>1, K => 1, \"b\"=> 2, {\"a\",1}=>3, K=>2}.
+
+ bar5(M,K) ->
+ M#{{\"a\",<<\"b\">>}=>1, K =>1,
+ \"b\"=> 2, {\"a\",<<\"b\">>}:=3, K=>2}.
+
+ baz5(M,K) ->
+ M#{{<<\"a\">>,1}=>1, K => 1,
+ <<\"b\">>=> 2, {<<\"a\">>,1}:=3,K=>2}.
+
+ foo6(K) ->
+ #{#{\"a\"=>1}=>1, K => 1, \"b\"=> 2, #{\"a\"=>1}=>3, K=>2}.
+
+ bar6(M,K) ->
+ M#{#{\"a\"=><<\"b\">>}=>1, K =>1,
+ \"b\"=> 2, #{\"a\"=><<\"b\">>}:=3, K=>2}.
+
+ baz6(M,K) ->
+ M#{#{<<\"a\">>=>1}=>1,
+ K => 1,
+ <<\"b\">>=> 2,
+ #{<<\"a\">>=>1}:=3,K=>2}.
+
+ foo7(K) ->
+ M1 = #{#{\"a\"=>1}=>1, K => 1, \"b\"=> 2},
+ M1#{#{\"a\"=>1}=>3, K=>2}.
+
+ bar7(M,K) ->
+ M1 = M#{#{\"a\"=><<\"b\">>}=>1, K =>1, \"b\"=> 2},
+ M1#{#{\"a\"=><<\"b\">>}:=3, K=>2}.
+
+ baz7(M,K) ->
+ M1 = M#{#{<<\"a\">>=>1}=>1,
+ K => 1,
+ <<\"b\">>=> 2},
+ M1#{#{<<\"a\">>=>1}:=3,K=>2}.
+ ">>,
+ [],
+ {warnings,[{3,v3_core,{map_key_repeated,"a"}},
+ {6,v3_core,{map_key_repeated,a}},
+ {9,v3_core,{map_key_repeated,<<"a">>}},
+ {14,v3_core,{map_key_repeated,{"a",1}}},
+ {17,v3_core,{map_key_repeated,{"a",<<"b">>}}},
+ {21,v3_core,{map_key_repeated,{<<"a">>,1}}},
+ {25,v3_core,{map_key_repeated,#{"a" => 1}}},
+ {28,v3_core,{map_key_repeated,#{"a" => <<"b">>}}},
+ {32,v3_core,{map_key_repeated,#{<<"a">> => 1}}}]}}
+ ],
run(Config, Ts),
ok.
@@ -823,6 +927,30 @@ bit_syntax(Config) ->
run(Config, Ts),
ok.
+inlining(Config) ->
+ %% Make sure that no spurious warnings are generated
+ %% when inlining.
+ Ts = [{inlining_1,
+ <<"-compile(inline).
+ compute1(X) -> add(X, 0).
+ add(1, 0) -> 1;
+ add(1, Y) -> 1 + Y;
+ add(X, Y) -> X + Y.
+ ">>,
+ [],
+ []},
+ {inlining_2,
+ <<"-compile({inline,[add/2]}).
+ compute1(X) -> add(X, 0).
+ add(1, 0) -> 1;
+ add(1, Y) -> 1 + Y;
+ add(X, Y) -> X + Y.
+ ">>,
+ [],
+ []}
+ ],
+ run(Config, Ts),
+ ok.
%%%
%%% End of test cases.
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index 23dd4bd4b1..463c264a5f 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 7.0
+COMPILER_VSN = 7.1
diff --git a/lib/cosProperty/doc/src/notes.xml b/lib/cosProperty/doc/src/notes.xml
index d5219fc110..e5d22982c5 100644
--- a/lib/cosProperty/doc/src/notes.xml
+++ b/lib/cosProperty/doc/src/notes.xml
@@ -32,6 +32,22 @@
<file>notes.xml</file>
</header>
+
+ <section><title>cosProperty 1.2.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Fix dialyzer warnings.</p>
+ <p>
+ Own Id: OTP-14006</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
+
<section><title>cosProperty 1.2.1</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
index bf046530d8..cc67daa9e0 100644
--- a/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
+++ b/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -913,8 +913,6 @@ mnesia_read(State) ->
case mnesia:wread({oe_CosPropertyService, ?get_DBKey(State)}) of
[#oe_CosPropertyService{properties = X}] ->
X;
- {atomic, []} ->
- {'EXCEPTION', #'OBJECT_NOT_EXIST'{completion_status=?COMPLETED_NO}};
_Other ->
{'EXCEPTION', #'INTERNAL'{completion_status=?COMPLETED_NO}}
end.
diff --git a/lib/cosProperty/vsn.mk b/lib/cosProperty/vsn.mk
index 1a8e42ffdb..78ba88445d 100644
--- a/lib/cosProperty/vsn.mk
+++ b/lib/cosProperty/vsn.mk
@@ -1,2 +1,2 @@
-COSPROPERTY_VSN = 1.2.1
+COSPROPERTY_VSN = 1.2.2
diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in
index c62f25b3ee..af7c209c75 100644
--- a/lib/crypto/c_src/Makefile.in
+++ b/lib/crypto/c_src/Makefile.in
@@ -43,9 +43,11 @@ SSL_LIBDIR = @SSL_LIBDIR@
SSL_INCLUDE = @SSL_INCLUDE@
SSL_CRYPTO_LIBNAME = @SSL_CRYPTO_LIBNAME@
SSL_SSL_LIBNAME = @SSL_SSL_LIBNAME@
+SSL_FLAGS = @SSL_FLAGS@
INCLUDES = $(SSL_INCLUDE) $(DED_INCLUDES)
+CFLAGS += $(SSL_FLAGS)
ifeq ($(TYPE),debug)
TYPEMARKER = .debug
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 7183c395ae..688ec339aa 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2010-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,13 +31,15 @@
#include <stdio.h>
#include <string.h>
-#include "erl_nif.h"
+#include <erl_nif.h>
#define OPENSSL_THREAD_DEFINES
#include <openssl/opensslconf.h>
#include <openssl/crypto.h>
+#ifndef OPENSSL_NO_DES
#include <openssl/des.h>
+#endif /* #ifndef OPENSSL_NO_DES */
/* #include <openssl/idea.h> This is not supported on the openssl OTP requires */
#include <openssl/dsa.h>
#include <openssl/rsa.h>
@@ -48,98 +50,135 @@
#include <openssl/ripemd.h>
#include <openssl/bn.h>
#include <openssl/objects.h>
-#include <openssl/rc4.h>
-#include <openssl/rc2.h>
+#ifndef OPENSSL_NO_RC4
+ #include <openssl/rc4.h>
+#endif /* OPENSSL_NO_RC4 */
+#ifndef OPENSSL_NO_RC2
+ #include <openssl/rc2.h>
+#endif
#include <openssl/blowfish.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
-
/* Helper macro to construct a OPENSSL_VERSION_NUMBER.
* See openssl/opensslv.h
*/
-#define OpenSSL_version(MAJ, MIN, FIX, P) \
+#define PACKED_OPENSSL_VERSION(MAJ, MIN, FIX, P) \
((((((((MAJ << 8) | MIN) << 8 ) | FIX) << 8) | (P-'a'+1)) << 4) | 0xf)
-#define OpenSSL_version_plain(MAJ, MIN, FIX) \
- OpenSSL_version(MAJ,MIN,FIX,('a'-1))
+#define PACKED_OPENSSL_VERSION_PLAIN(MAJ, MIN, FIX) \
+ PACKED_OPENSSL_VERSION(MAJ,MIN,FIX,('a'-1))
+
+
+/* LibreSSL was cloned from OpenSSL 1.0.1g and claims to be API and BPI compatible
+ * with 1.0.1.
+ *
+ * LibreSSL has the same names on include files and symbols as OpenSSL, but defines
+ * the OPENSSL_VERSION_NUMBER to be >= 2.0.0
+ *
+ * Therefor works tests like this as intendend:
+ * OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
+ * (The test is for example "2.4.2" >= "1.0.0" although the test
+ * with the cloned OpenSSL test would be "1.0.1" >= "1.0.0")
+ *
+ * But tests like this gives wrong result:
+ * OPENSSL_VERSION_NUMBER < PACKED_OPENSSL_VERSION_PLAIN(1,1,0)
+ * (The test is false since "2.4.2" < "1.1.0". It should have been
+ * true because the LibreSSL API version is "1.0.1")
+ *
+ */
+
+#ifdef LIBRESSL_VERSION_NUMBER
+/* A macro to test on in this file */
+#define HAS_LIBRESSL
+#endif
+
+#ifdef HAS_LIBRESSL
+/* LibreSSL dislikes FIPS */
+# ifdef FIPS_SUPPORT
+# undef FIPS_SUPPORT
+# endif
+
+/* LibreSSL wants the 1.0.1 API */
+# define NEED_EVP_COMPATIBILITY_FUNCTIONS
+#endif
+
+
+#if OPENSSL_VERSION_NUMBER < PACKED_OPENSSL_VERSION_PLAIN(1,1,0)
+# define NEED_EVP_COMPATIBILITY_FUNCTIONS
+#endif
+
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(1,0,0)
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
#include <openssl/modes.h>
#endif
#include "crypto_callback.h"
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(0,9,8) \
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(0,9,8) \
&& !defined(OPENSSL_NO_SHA224) && defined(NID_sha224) \
&& !defined(OPENSSL_NO_SHA256) /* disabled like this in my sha.h (?) */
# define HAVE_SHA224
#endif
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(0,9,8) \
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(0,9,8) \
&& !defined(OPENSSL_NO_SHA256) && defined(NID_sha256)
# define HAVE_SHA256
#endif
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(0,9,8) \
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(0,9,8) \
&& !defined(OPENSSL_NO_SHA384) && defined(NID_sha384)\
&& !defined(OPENSSL_NO_SHA512) /* disabled like this in my sha.h (?) */
# define HAVE_SHA384
#endif
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(0,9,8) \
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(0,9,8) \
&& !defined(OPENSSL_NO_SHA512) && defined(NID_sha512)
# define HAVE_SHA512
#endif
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version(0,9,7,'e')
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION(0,9,7,'e')
# define HAVE_DES_ede3_cfb_encrypt
#endif
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version(0,9,8,'o') \
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION(0,9,8,'o') \
&& !defined(OPENSSL_NO_EC) \
&& !defined(OPENSSL_NO_ECDH) \
&& !defined(OPENSSL_NO_ECDSA)
# define HAVE_EC
#endif
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version(0,9,8,'c')
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION(0,9,8,'c')
# define HAVE_AES_IGE
#endif
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(1,0,1)
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,1)
# define HAVE_EVP_AES_CTR
# define HAVE_GCM
-# if OPENSSL_VERSION_NUMBER < OpenSSL_version(1,0,1,'d')
+# define HAVE_CMAC
+# if OPENSSL_VERSION_NUMBER < PACKED_OPENSSL_VERSION(1,0,1,'d')
# define HAVE_GCM_EVP_DECRYPT_BUG
# endif
#endif
-#if defined(NID_chacha20) && !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
-# define HAVE_CHACHA20_POLY1305
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,1,0)
+# ifndef HAS_LIBRESSL
+# define HAVE_CHACHA20_POLY1305
+# endif
#endif
-#if OPENSSL_VERSION_NUMBER <= OpenSSL_version(0,9,8,'l')
+#if OPENSSL_VERSION_NUMBER <= PACKED_OPENSSL_VERSION(0,9,8,'l')
# define HAVE_ECB_IVEC_BUG
#endif
+#if defined(HAVE_CMAC)
+#include <openssl/cmac.h>
+#endif
+
#if defined(HAVE_EC)
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/ecdsa.h>
#endif
-#if defined(HAVE_CHACHA20_POLY1305)
-#include <openssl/chacha.h>
-#include <openssl/poly1305.h>
-
-#if !defined(CHACHA20_NONCE_LEN)
-# define CHACHA20_NONCE_LEN 8
-#endif
-#if !defined(POLY1305_TAG_LEN)
-# define POLY1305_TAG_LEN 16
-#endif
-
-#endif
-
#ifdef VALGRIND
# include <valgrind/memcheck.h>
@@ -208,6 +247,163 @@ do { \
} \
} while (0)
+
+#ifdef NEED_EVP_COMPATIBILITY_FUNCTIONS
+/*
+ * In OpenSSL 1.1.0, most structs are opaque. That means that
+ * the structs cannot be allocated as automatic variables on the
+ * C stack (because the size is unknown) and that it is necessary
+ * to use access functions.
+ *
+ * For backward compatibility to previous versions of OpenSSL, define
+ * on our versions of the new functions defined in 1.1.0 here, so that
+ * we don't have to sprinkle ifdefs throughout the code.
+ */
+
+static HMAC_CTX *HMAC_CTX_new(void);
+static void HMAC_CTX_free(HMAC_CTX *ctx);
+
+static HMAC_CTX *HMAC_CTX_new()
+{
+ HMAC_CTX *ctx = CRYPTO_malloc(sizeof(HMAC_CTX), __FILE__, __LINE__);
+ HMAC_CTX_init(ctx);
+ return ctx;
+}
+
+static void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+ HMAC_CTX_cleanup(ctx);
+ return CRYPTO_free(ctx);
+}
+
+#define EVP_MD_CTX_new() EVP_MD_CTX_create()
+#define EVP_MD_CTX_free(ctx) EVP_MD_CTX_destroy(ctx)
+
+static INLINE void *BN_GENCB_get_arg(BN_GENCB *cb);
+
+static INLINE void *BN_GENCB_get_arg(BN_GENCB *cb)
+{
+ return cb->arg;
+}
+
+static INLINE int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
+static INLINE void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d);
+static INLINE int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q);
+static INLINE void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
+static INLINE int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp);
+static INLINE void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp);
+
+static INLINE int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+{
+ r->n = n;
+ r->e = e;
+ r->d = d;
+ return 1;
+}
+
+static INLINE void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
+{
+ *n = r->n;
+ *e = r->e;
+ *d = r->d;
+}
+
+static INLINE int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
+{
+ r->p = p;
+ r->q = q;
+ return 1;
+}
+
+static INLINE void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
+{
+ *p = r->p;
+ *q = r->q;
+}
+
+static INLINE int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
+{
+ r->dmp1 = dmp1;
+ r->dmq1 = dmq1;
+ r->iqmp = iqmp;
+ return 1;
+}
+
+static INLINE void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp)
+{
+ *dmp1 = r->dmp1;
+ *dmq1 = r->dmq1;
+ *iqmp = r->iqmp;
+}
+
+static INLINE int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key);
+static INLINE int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+
+static INLINE int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ d->pub_key = pub_key;
+ d->priv_key = priv_key;
+ return 1;
+}
+
+static INLINE int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ d->p = p;
+ d->q = q;
+ d->g = g;
+ return 1;
+}
+
+static INLINE int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key);
+static INLINE int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+static INLINE int DH_set_length(DH *dh, long length);
+static INLINE void DH_get0_pqg(const DH *dh,
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
+static INLINE void DH_get0_key(const DH *dh,
+ const BIGNUM **pub_key, const BIGNUM **priv_key);
+
+static INLINE int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ dh->pub_key = pub_key;
+ dh->priv_key = priv_key;
+ return 1;
+}
+
+static INLINE int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ dh->p = p;
+ dh->q = q;
+ dh->g = g;
+ return 1;
+}
+
+static INLINE int DH_set_length(DH *dh, long length)
+{
+ dh->length = length;
+ return 1;
+}
+
+static INLINE void
+DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+ *p = dh->p;
+ *q = dh->q;
+ *g = dh->g;
+}
+
+static INLINE void
+DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+ *pub_key = dh->pub_key;
+ *priv_key = dh->priv_key;
+}
+
+#else /* End of compatibility definitions. */
+
+#define HAVE_OPAQUE_BN_GENCB
+
+#endif
+
/* NIF interface declarations */
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info);
static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info);
@@ -215,6 +411,8 @@ static void unload(ErlNifEnv* env, void* priv_data);
/* The NIFs: */
static ERL_NIF_TERM info_lib(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM info_fips(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM enable_fips_mode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM hash_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM hash_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
@@ -224,27 +422,27 @@ static ERL_NIF_TERM hmac_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
static ERL_NIF_TERM hmac_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM hmac_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM hmac_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM cmac_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM block_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_cfb_8_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM aes_cfb_128_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_ctr_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM strong_rand_mpint_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM strong_rand_range_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM mod_exp_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM dss_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rsa_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM do_exor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM rc4_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rc4_set_key(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rc4_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM dss_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM rsa_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM dh_generate_parameters_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM dh_check(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
@@ -278,11 +476,14 @@ static EC_KEY* ec_key_new(ErlNifEnv* env, ERL_NIF_TERM curve_arg);
static int term2point(ErlNifEnv* env, ERL_NIF_TERM term,
EC_GROUP *group, EC_POINT **pptr);
#endif
+static ERL_NIF_TERM bin_from_bn(ErlNifEnv* env, const BIGNUM *bn);
static int library_refc = 0; /* number of users of this dynamic library */
static ErlNifFunc nif_funcs[] = {
{"info_lib", 0, info_lib},
+ {"info_fips", 0, info_fips},
+ {"enable_fips_mode", 1, enable_fips_mode},
{"algorithms", 0, algorithms},
{"hash_nif", 2, hash_nif},
{"hash_init_nif", 1, hash_init_nif},
@@ -294,33 +495,30 @@ static ErlNifFunc nif_funcs[] = {
{"hmac_update_nif", 2, hmac_update_nif},
{"hmac_final_nif", 1, hmac_final_nif},
{"hmac_final_nif", 2, hmac_final_nif},
+ {"cmac_nif", 3, cmac_nif},
{"block_crypt_nif", 5, block_crypt_nif},
{"block_crypt_nif", 4, block_crypt_nif},
{"aes_ige_crypt_nif", 4, aes_ige_crypt_nif},
-
- {"aes_ctr_encrypt", 3, aes_ctr_encrypt},
- {"aes_ctr_decrypt", 3, aes_ctr_encrypt},
{"aes_ctr_stream_init", 2, aes_ctr_stream_init},
{"aes_ctr_stream_encrypt", 2, aes_ctr_stream_encrypt},
{"aes_ctr_stream_decrypt", 2, aes_ctr_stream_encrypt},
- {"rand_bytes", 1, rand_bytes_1},
{"strong_rand_bytes_nif", 1, strong_rand_bytes_nif},
- {"strong_rand_mpint_nif", 3, strong_rand_mpint_nif},
+ {"strong_rand_range_nif", 1, strong_rand_range_nif},
{"rand_uniform_nif", 2, rand_uniform_nif},
{"mod_exp_nif", 4, mod_exp_nif},
{"dss_verify_nif", 4, dss_verify_nif},
{"rsa_verify_nif", 4, rsa_verify_nif},
{"do_exor", 2, do_exor},
- {"rc4_encrypt", 2, rc4_encrypt},
{"rc4_set_key", 1, rc4_set_key},
{"rc4_encrypt_with_state", 2, rc4_encrypt_with_state},
{"rsa_sign_nif", 3, rsa_sign_nif},
{"dss_sign_nif", 3, dss_sign_nif},
{"rsa_public_crypt", 4, rsa_public_crypt},
{"rsa_private_crypt", 4, rsa_private_crypt},
+ {"rsa_generate_key_nif", 2, rsa_generate_key_nif},
{"dh_generate_parameters_nif", 2, dh_generate_parameters_nif},
{"dh_check", 1, dh_check},
- {"dh_generate_key_nif", 3, dh_generate_key_nif},
+ {"dh_generate_key_nif", 4, dh_generate_key_nif},
{"dh_compute_key_nif", 3, dh_compute_key_nif},
{"srp_value_B_nif", 5, srp_value_B_nif},
{"srp_user_secret_nif", 7, srp_user_secret_nif},
@@ -338,8 +536,6 @@ static ErlNifFunc nif_funcs[] = {
{"chacha20_poly1305_encrypt", 4, chacha20_poly1305_encrypt},
{"chacha20_poly1305_decrypt", 5, chacha20_poly1305_decrypt}
-
-
};
ERL_NIF_INIT(crypto,nif_funcs,load,NULL,upgrade,unload)
@@ -369,6 +565,12 @@ static ERL_NIF_TERM atom_unknown;
static ERL_NIF_TERM atom_none;
static ERL_NIF_TERM atom_notsup;
static ERL_NIF_TERM atom_digest;
+#ifdef FIPS_SUPPORT
+static ERL_NIF_TERM atom_enabled;
+static ERL_NIF_TERM atom_not_enabled;
+#else
+static ERL_NIF_TERM atom_not_supported;
+#endif
#if defined(HAVE_EC)
static ERL_NIF_TERM atom_ec;
@@ -392,7 +594,7 @@ struct hmac_context
{
ErlNifMutex* mtx;
int alive;
- HMAC_CTX ctx;
+ HMAC_CTX* ctx;
};
static void hmac_context_dtor(ErlNifEnv* env, struct hmac_context*);
@@ -407,7 +609,7 @@ struct digest_type_t {
}md;
};
-struct digest_type_t digest_types[] =
+static struct digest_type_t digest_types[] =
{
{{"md4"}, {&EVP_md4}},
{{"md5"}, {&EVP_md5}},
@@ -458,16 +660,35 @@ struct cipher_type_t {
const size_t key_len; /* != 0 to also match on key_len */
};
-struct cipher_type_t cipher_types[] =
+#ifdef OPENSSL_NO_DES
+#define COND_NO_DES_PTR(Ptr) (NULL)
+#else
+#define COND_NO_DES_PTR(Ptr) (Ptr)
+#endif
+
+static struct cipher_type_t cipher_types[] =
{
- {{"rc2_cbc"}, {&EVP_rc2_cbc}},
- {{"des_cbc"}, {&EVP_des_cbc}},
- {{"des_cfb"}, {&EVP_des_cfb8}},
- {{"des_ecb"}, {&EVP_des_ecb}},
- {{"des_ede3_cbc"}, {&EVP_des_ede3_cbc}},
- {{"des_ede3_cbf"},
+ {{"rc2_cbc"},
+#ifndef OPENSSL_NO_RC2
+ {&EVP_rc2_cbc}
+#else
+ {NULL}
+#endif
+ },
+ {{"des_cbc"}, {COND_NO_DES_PTR(&EVP_des_cbc)}},
+ {{"des_cfb"}, {COND_NO_DES_PTR(&EVP_des_cfb8)}},
+ {{"des_ecb"}, {COND_NO_DES_PTR(&EVP_des_ecb)}},
+ {{"des_ede3_cbc"}, {COND_NO_DES_PTR(&EVP_des_ede3_cbc)}},
+ {{"des_ede3_cbf"}, /* Misspelled, retained */
#ifdef HAVE_DES_ede3_cfb_encrypt
- {&EVP_des_ede3_cfb8}
+ {COND_NO_DES_PTR(&EVP_des_ede3_cfb8)}
+#else
+ {NULL}
+#endif
+ },
+ {{"des_ede3_cfb"},
+#ifdef HAVE_DES_ede3_cfb_encrypt
+ {COND_NO_DES_PTR(&EVP_des_ede3_cfb8)}
#else
{NULL}
#endif
@@ -500,18 +721,24 @@ static struct cipher_type_t* get_cipher_type(ERL_NIF_TERM type, size_t key_len);
#define PRINTF_ERR1(FMT,A1)
#define PRINTF_ERR2(FMT,A1,A2)
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(1,0,0)
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
/* Define resource types for OpenSSL context structures. */
static ErlNifResourceType* evp_md_ctx_rtype;
-static void evp_md_ctx_dtor(ErlNifEnv* env, EVP_MD_CTX* ctx) {
- EVP_MD_CTX_cleanup(ctx);
+struct evp_md_ctx {
+ EVP_MD_CTX* ctx;
+};
+static void evp_md_ctx_dtor(ErlNifEnv* env, struct evp_md_ctx *ctx) {
+ EVP_MD_CTX_free(ctx->ctx);
}
#endif
#ifdef HAVE_EVP_AES_CTR
static ErlNifResourceType* evp_cipher_ctx_rtype;
-static void evp_cipher_ctx_dtor(ErlNifEnv* env, EVP_CIPHER_CTX* ctx) {
- EVP_CIPHER_CTX_cleanup(ctx);
+struct evp_cipher_ctx {
+ EVP_CIPHER_CTX* ctx;
+};
+static void evp_cipher_ctx_dtor(ErlNifEnv* env, struct evp_cipher_ctx* ctx) {
+ EVP_CIPHER_CTX_free(ctx->ctx);
}
#endif
@@ -530,6 +757,13 @@ static int verify_lib_version(void)
return 1;
}
+#ifdef FIPS_SUPPORT
+/* In FIPS mode non-FIPS algorithms are disabled and return badarg. */
+#define CHECK_NO_FIPS_MODE() { if (FIPS_mode()) return atom_notsup; }
+#else
+#define CHECK_NO_FIPS_MODE()
+#endif
+
#ifdef HAVE_DYNAMIC_CRYPTO_LIB
# if defined(DEBUG)
@@ -563,7 +797,7 @@ static void error_handler(void* null, const char* errstr)
}
#endif /* HAVE_DYNAMIC_CRYPTO_LIB */
-static int init(ErlNifEnv* env, ERL_NIF_TERM load_info)
+static int initialize(ErlNifEnv* env, ERL_NIF_TERM load_info)
{
#ifdef OPENSSL_THREADS
ErlNifSysInfo sys_info;
@@ -578,17 +812,17 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info)
char lib_buf[1000];
if (!verify_lib_version())
- return 0;
+ return __LINE__;
- /* load_info: {301, <<"/full/path/of/this/library">>} */
+ /* load_info: {302, <<"/full/path/of/this/library">>,true|false} */
if (!enif_get_tuple(env, load_info, &tpl_arity, &tpl_array)
- || tpl_arity != 2
+ || tpl_arity != 3
|| !enif_get_int(env, tpl_array[0], &vernum)
- || vernum != 301
+ || vernum != 302
|| !enif_inspect_binary(env, tpl_array[1], &lib_bin)) {
PRINTF_ERR1("CRYPTO: Invalid load_info '%T'", load_info);
- return 0;
+ return __LINE__;
}
hmac_context_rtype = enif_open_resource_type(env, NULL, "hmac_context",
@@ -597,16 +831,16 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info)
NULL);
if (!hmac_context_rtype) {
PRINTF_ERR0("CRYPTO: Could not open resource type 'hmac_context'");
- return 0;
+ return __LINE__;
}
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(1,0,0)
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
evp_md_ctx_rtype = enif_open_resource_type(env, NULL, "EVP_MD_CTX",
(ErlNifResourceDtor*) evp_md_ctx_dtor,
ERL_NIF_RT_CREATE|ERL_NIF_RT_TAKEOVER,
NULL);
if (!evp_md_ctx_rtype) {
PRINTF_ERR0("CRYPTO: Could not open resource type 'EVP_MD_CTX'");
- return 0;
+ return __LINE__;
}
#endif
#ifdef HAVE_EVP_AES_CTR
@@ -616,18 +850,33 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info)
NULL);
if (!evp_cipher_ctx_rtype) {
PRINTF_ERR0("CRYPTO: Could not open resource type 'EVP_CIPHER_CTX'");
- return 0;
+ return __LINE__;
}
#endif
if (library_refc > 0) {
/* Repeated loading of this library (module upgrade).
* Atoms and callbacks are already set, we are done.
*/
- return 1;
+ return 0;
}
atom_true = enif_make_atom(env,"true");
atom_false = enif_make_atom(env,"false");
+ /* Enter FIPS mode */
+ if (tpl_array[2] == atom_true) {
+#ifdef FIPS_SUPPORT
+ if (!FIPS_mode_set(1)) {
+#else
+ {
+#endif
+ PRINTF_ERR0("CRYPTO: Could not setup FIPS mode");
+ return 0;
+ }
+ } else if (tpl_array[2] != atom_false) {
+ PRINTF_ERR1("CRYPTO: Invalid load_info '%T'", load_info);
+ return 0;
+ }
+
atom_sha = enif_make_atom(env,"sha");
atom_error = enif_make_atom(env,"error");
atom_rsa_pkcs1_padding = enif_make_atom(env,"rsa_pkcs1_padding");
@@ -661,6 +910,13 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info)
atom_blowfish_ecb = enif_make_atom(env, "blowfish_ecb");
#endif
+#ifdef FIPS_SUPPORT
+ atom_enabled = enif_make_atom(env,"enabled");
+ atom_not_enabled = enif_make_atom(env,"not_enabled");
+#else
+ atom_not_supported = enif_make_atom(env,"not_supported");
+#endif
+
init_digest_types(env);
init_cipher_types(env);
init_algorithms_types(env);
@@ -669,14 +925,14 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info)
{
void* handle;
if (!change_basename(&lib_bin, lib_buf, sizeof(lib_buf), crypto_callback_name)) {
- return 0;
+ return __LINE__;
}
if (!(handle = enif_dlopen(lib_buf, &error_handler, NULL))) {
- return 0;
+ return __LINE__;
}
if (!(funcp = (get_crypto_callbacks_t*) enif_dlsym(handle, "get_crypto_callbacks",
&error_handler, NULL))) {
- return 0;
+ return __LINE__;
}
}
#else /* !HAVE_DYNAMIC_CRYPTO_LIB */
@@ -695,7 +951,7 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info)
if (!ccb || ccb->sizeof_me != sizeof(*ccb)) {
PRINTF_ERR0("Invalid 'crypto_callbacks'");
- return 0;
+ return __LINE__;
}
CRYPTO_set_mem_functions(ccb->crypto_alloc, ccb->crypto_realloc, ccb->crypto_free);
@@ -709,13 +965,15 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info)
CRYPTO_set_dynlock_destroy_callback(ccb->dyn_destroy_function);
}
#endif /* OPENSSL_THREADS */
- return 1;
+
+ return 0;
}
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
- if (!init(env, load_info)) {
- return -1;
+ int errline = initialize(env, load_info);
+ if (errline) {
+ return errline;
}
*priv_data = NULL;
@@ -726,14 +984,16 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data,
ERL_NIF_TERM load_info)
{
+ int errline;
if (*old_priv_data != NULL) {
- return -1; /* Don't know how to do that */
+ return __LINE__; /* Don't know how to do that */
}
if (*priv_data != NULL) {
- return -1; /* Don't know how to do that */
+ return __LINE__; /* Don't know how to do that */
}
- if (!init(env, load_info)) {
- return -1;
+ errline = initialize(env, load_info);
+ if (errline) {
+ return errline;
}
library_refc++;
return 0;
@@ -744,15 +1004,16 @@ static void unload(ErlNifEnv* env, void* priv_data)
--library_refc;
}
-static int algo_hash_cnt;
+static int algo_hash_cnt, algo_hash_fips_cnt;
static ERL_NIF_TERM algo_hash[8]; /* increase when extending the list */
-static int algo_pubkey_cnt;
+static int algo_pubkey_cnt, algo_pubkey_fips_cnt;
static ERL_NIF_TERM algo_pubkey[7]; /* increase when extending the list */
-static int algo_cipher_cnt;
-static ERL_NIF_TERM algo_cipher[20]; /* increase when extending the list */
+static int algo_cipher_cnt, algo_cipher_fips_cnt;
+static ERL_NIF_TERM algo_cipher[24]; /* increase when extending the list */
static void init_algorithms_types(ErlNifEnv* env)
{
+ // Validated algorithms first
algo_hash_cnt = 0;
algo_hash[algo_hash_cnt++] = atom_sha;
#ifdef HAVE_SHA224
@@ -767,6 +1028,8 @@ static void init_algorithms_types(ErlNifEnv* env)
#ifdef HAVE_SHA512
algo_hash[algo_hash_cnt++] = enif_make_atom(env, "sha512");
#endif
+ // Non-validated algorithms follow
+ algo_hash_fips_cnt = algo_hash_cnt;
algo_hash[algo_hash_cnt++] = enif_make_atom(env, "md4");
algo_hash[algo_hash_cnt++] = enif_make_atom(env, "md5");
algo_hash[algo_hash_cnt++] = enif_make_atom(env, "ripemd160");
@@ -782,13 +1045,19 @@ static void init_algorithms_types(ErlNifEnv* env)
algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env, "ecdsa");
algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env, "ecdh");
#endif
+ // Non-validated algorithms follow
+ algo_pubkey_fips_cnt = algo_pubkey_cnt;
algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env, "srp");
+ // Validated algorithms first
algo_cipher_cnt = 0;
+#ifndef OPENSSL_NO_DES
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env, "des3_cbc");
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env, "des_ede3");
#ifdef HAVE_DES_ede3_cfb_encrypt
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env, "des3_cbf");
+ algo_cipher[algo_cipher_cnt++] = enif_make_atom(env, "des3_cfb");
+#endif
#endif
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env, "aes_cbc");
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env, "aes_cbc128");
@@ -797,19 +1066,28 @@ static void init_algorithms_types(ErlNifEnv* env)
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env, "aes_cbc256");
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env, "aes_ctr");
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env, "aes_ecb");
+#if defined(HAVE_GCM)
+ algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"aes_gcm");
+#endif
+ // Non-validated algorithms follow
+ algo_cipher_fips_cnt = algo_cipher_cnt;
#ifdef HAVE_AES_IGE
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"aes_ige256");
#endif
+#ifndef OPENSSL_NO_DES
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"des_cbc");
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"des_cfb");
+ algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"des_ecb");
+#endif
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"blowfish_cbc");
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"blowfish_cfb64");
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"blowfish_ofb64");
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"blowfish_ecb");
+#ifndef OPENSSL_NO_RC2
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"rc2_cbc");
+#endif
+#ifndef OPENSSL_NO_RC4
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"rc4");
-#if defined(HAVE_GCM)
- algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"aes_gcm");
#endif
#if defined(HAVE_CHACHA20_POLY1305)
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"chacha20_poly1305");
@@ -822,9 +1100,16 @@ static void init_algorithms_types(ErlNifEnv* env)
static ERL_NIF_TERM algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
+#ifdef FIPS_SUPPORT
+ int fips_mode = FIPS_mode();
+ int hash_cnt = fips_mode ? algo_hash_fips_cnt : algo_hash_cnt;
+ int pubkey_cnt = fips_mode ? algo_pubkey_fips_cnt : algo_pubkey_cnt;
+ int cipher_cnt = fips_mode ? algo_cipher_fips_cnt : algo_cipher_cnt;
+#else
int hash_cnt = algo_hash_cnt;
int pubkey_cnt = algo_pubkey_cnt;
int cipher_cnt = algo_cipher_cnt;
+#endif
return enif_make_tuple3(env,
enif_make_list_from_array(env, algo_hash, hash_cnt),
enif_make_list_from_array(env, algo_pubkey, pubkey_cnt),
@@ -858,6 +1143,37 @@ static ERL_NIF_TERM info_lib(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
ver_term));
}
+static ERL_NIF_TERM info_fips(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+#ifdef FIPS_SUPPORT
+ return FIPS_mode() ? atom_enabled : atom_not_enabled;
+#else
+ return atom_not_supported;
+#endif
+}
+
+static ERL_NIF_TERM enable_fips_mode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Boolean) */
+ if (argv[0] == atom_true) {
+#ifdef FIPS_SUPPORT
+ if (FIPS_mode_set(1)) {
+ return atom_true;
+ }
+#endif
+ PRINTF_ERR0("CRYPTO: Could not setup FIPS mode");
+ return atom_false;
+ } else if (argv[0] == atom_false) {
+#ifdef FIPS_SUPPORT
+ if (!FIPS_mode_set(0)) {
+ return atom_false;
+ }
+#endif
+ return atom_true;
+ } else {
+ return enif_make_badarg(env);
+ }
+}
+
static ERL_NIF_TERM make_badarg_maybe(ErlNifEnv* env)
{
ERL_NIF_TERM reason;
@@ -898,12 +1214,12 @@ static ERL_NIF_TERM hash_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
return ret;
}
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(1,0,0)
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
static ERL_NIF_TERM hash_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Type) */
struct digest_type_t *digp = NULL;
- EVP_MD_CTX *ctx;
+ struct evp_md_ctx *ctx;
ERL_NIF_TERM ret;
digp = get_digest_type(argv[0]);
@@ -914,8 +1230,9 @@ static ERL_NIF_TERM hash_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
return atom_notsup;
}
- ctx = enif_alloc_resource(evp_md_ctx_rtype, sizeof(EVP_MD_CTX));
- if (!EVP_DigestInit(ctx, digp->md.p)) {
+ ctx = enif_alloc_resource(evp_md_ctx_rtype, sizeof(struct evp_md_ctx));
+ ctx->ctx = EVP_MD_CTX_new();
+ if (!EVP_DigestInit(ctx->ctx, digp->md.p)) {
enif_release_resource(ctx);
return atom_notsup;
}
@@ -925,7 +1242,7 @@ static ERL_NIF_TERM hash_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
}
static ERL_NIF_TERM hash_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Context, Data) */
- EVP_MD_CTX *ctx, *new_ctx;
+ struct evp_md_ctx *ctx, *new_ctx;
ErlNifBinary data;
ERL_NIF_TERM ret;
@@ -934,9 +1251,10 @@ static ERL_NIF_TERM hash_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
return enif_make_badarg(env);
}
- new_ctx = enif_alloc_resource(evp_md_ctx_rtype, sizeof(EVP_MD_CTX));
- if (!EVP_MD_CTX_copy(new_ctx, ctx) ||
- !EVP_DigestUpdate(new_ctx, data.data, data.size)) {
+ new_ctx = enif_alloc_resource(evp_md_ctx_rtype, sizeof(struct evp_md_ctx));
+ new_ctx->ctx = EVP_MD_CTX_new();
+ if (!EVP_MD_CTX_copy(new_ctx->ctx, ctx->ctx) ||
+ !EVP_DigestUpdate(new_ctx->ctx, data.data, data.size)) {
enif_release_resource(new_ctx);
return atom_notsup;
}
@@ -948,7 +1266,8 @@ static ERL_NIF_TERM hash_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
}
static ERL_NIF_TERM hash_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Context) */
- EVP_MD_CTX *ctx, new_ctx;
+ struct evp_md_ctx *ctx;
+ EVP_MD_CTX *new_ctx;
ERL_NIF_TERM ret;
unsigned ret_size;
@@ -956,16 +1275,19 @@ static ERL_NIF_TERM hash_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
return enif_make_badarg(env);
}
- ret_size = (unsigned)EVP_MD_CTX_size(ctx);
+ ret_size = (unsigned)EVP_MD_CTX_size(ctx->ctx);
ASSERT(0 < ret_size && ret_size <= EVP_MAX_MD_SIZE);
- if (!EVP_MD_CTX_copy(&new_ctx, ctx) ||
- !EVP_DigestFinal(&new_ctx,
+ new_ctx = EVP_MD_CTX_new();
+ if (!EVP_MD_CTX_copy(new_ctx, ctx->ctx) ||
+ !EVP_DigestFinal(new_ctx,
enif_make_new_binary(env, ret_size, &ret),
&ret_size)) {
+ EVP_MD_CTX_free(new_ctx);
return atom_notsup;
}
- ASSERT(ret_size == (unsigned)EVP_MD_CTX_size(ctx));
+ EVP_MD_CTX_free(new_ctx);
+ ASSERT(ret_size == (unsigned)EVP_MD_CTX_size(ctx->ctx));
return ret;
}
@@ -1249,7 +1571,7 @@ static ERL_NIF_TERM hmac_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
static void hmac_context_dtor(ErlNifEnv* env, struct hmac_context *obj)
{
if (obj->alive) {
- HMAC_CTX_cleanup(&obj->ctx);
+ HMAC_CTX_free(obj->ctx);
obj->alive = 0;
}
enif_mutex_destroy(obj->mtx);
@@ -1274,15 +1596,16 @@ static ERL_NIF_TERM hmac_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
obj = enif_alloc_resource(hmac_context_rtype, sizeof(struct hmac_context));
obj->mtx = enif_mutex_create("crypto.hmac");
obj->alive = 1;
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(1,0,0)
+ obj->ctx = HMAC_CTX_new();
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
// Check the return value of HMAC_Init: it may fail in FIPS mode
// for disabled algorithms
- if (!HMAC_Init(&obj->ctx, key.data, key.size, digp->md.p)) {
+ if (!HMAC_Init_ex(obj->ctx, key.data, key.size, digp->md.p, NULL)) {
enif_release_resource(obj);
return atom_notsup;
}
#else
- HMAC_Init(&obj->ctx, key.data, key.size, digp->md.p);
+ HMAC_Init_ex(obj->ctx, key.data, key.size, digp->md.p, NULL);
#endif
ret = enif_make_resource(env, obj);
@@ -1304,7 +1627,7 @@ static ERL_NIF_TERM hmac_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
enif_mutex_unlock(obj->mtx);
return enif_make_badarg(env);
}
- HMAC_Update(&obj->ctx, data.data, data.size);
+ HMAC_Update(obj->ctx, data.data, data.size);
enif_mutex_unlock(obj->mtx);
CONSUME_REDS(env,data);
@@ -1331,8 +1654,8 @@ static ERL_NIF_TERM hmac_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
return enif_make_badarg(env);
}
- HMAC_Final(&obj->ctx, mac_buf, &mac_len);
- HMAC_CTX_cleanup(&obj->ctx);
+ HMAC_Final(obj->ctx, mac_buf, &mac_len);
+ HMAC_CTX_free(obj->ctx);
obj->alive = 0;
enif_mutex_unlock(obj->mtx);
@@ -1346,12 +1669,59 @@ static ERL_NIF_TERM hmac_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
return ret;
}
+static ERL_NIF_TERM cmac_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Type, Key, Data) */
+#if defined(HAVE_CMAC)
+ struct cipher_type_t *cipherp = NULL;
+ const EVP_CIPHER *cipher;
+ CMAC_CTX *ctx;
+ ErlNifBinary key;
+ ErlNifBinary data;
+ ERL_NIF_TERM ret;
+ size_t ret_size;
+
+ if (!enif_inspect_iolist_as_binary(env, argv[1], &key)
+ || !(cipherp = get_cipher_type(argv[0], key.size))
+ || !enif_inspect_iolist_as_binary(env, argv[2], &data)) {
+ return enif_make_badarg(env);
+ }
+ cipher = cipherp->cipher.p;
+ if (!cipher) {
+ return enif_raise_exception(env, atom_notsup);
+ }
+
+ ctx = CMAC_CTX_new();
+ if (!CMAC_Init(ctx, key.data, key.size, cipher, NULL)) {
+ CMAC_CTX_free(ctx);
+ return atom_notsup;
+ }
+
+ if (!CMAC_Update(ctx, data.data, data.size) ||
+ !CMAC_Final(ctx,
+ enif_make_new_binary(env, EVP_CIPHER_block_size(cipher), &ret),
+ &ret_size)) {
+ CMAC_CTX_free(ctx);
+ return atom_notsup;
+ }
+ ASSERT(ret_size == (unsigned)EVP_CIPHER_block_size(cipher));
+
+ CMAC_CTX_free(ctx);
+ CONSUME_REDS(env, data);
+ return ret;
+#else
+ /* The CMAC functionality was introduced in OpenSSL 1.0.1
+ * Although OTP requires at least version 0.9.8, the versions 0.9.8 and 1.0.0 are
+ * no longer maintained. */
+ return atom_notsup;
+#endif
+}
+
static ERL_NIF_TERM block_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Type, Key, Ivec, Text, IsEncrypt) or (Type, Key, Text, IsEncrypt) */
struct cipher_type_t *cipherp = NULL;
const EVP_CIPHER *cipher;
ErlNifBinary key, ivec, text;
- EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX* ctx;
ERL_NIF_TERM ret;
unsigned char *out;
int ivec_size, out_size = 0;
@@ -1366,13 +1736,20 @@ static ERL_NIF_TERM block_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
return enif_raise_exception(env, atom_notsup);
}
- if ((argv[0] == atom_aes_cfb8 || argv[0] == atom_aes_cfb128)
+ if (argv[0] == atom_aes_cfb8
&& (key.size == 24 || key.size == 32)) {
/* Why do EVP_CIPHER_CTX_set_key_length() fail on these key sizes?
* Fall back on low level API
*/
return aes_cfb_8_crypt(env, argc-1, argv+1);
}
+ else if (argv[0] == atom_aes_cfb128
+ && (key.size == 24 || key.size == 32)) {
+ /* Why do EVP_CIPHER_CTX_set_key_length() fail on these key sizes?
+ * Fall back on low level API
+ */
+ return aes_cfb_128_crypt_nif(env, argc-1, argv+1);
+ }
ivec_size = EVP_CIPHER_iv_length(cipher);
@@ -1392,30 +1769,30 @@ static ERL_NIF_TERM block_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
out = enif_make_new_binary(env, text.size, &ret);
- EVP_CIPHER_CTX_init(&ctx);
- if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, NULL,
+ ctx = EVP_CIPHER_CTX_new();
+ if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL,
(argv[argc - 1] == atom_true)) ||
- !EVP_CIPHER_CTX_set_key_length(&ctx, key.size) ||
+ !EVP_CIPHER_CTX_set_key_length(ctx, key.size) ||
!(EVP_CIPHER_type(cipher) != NID_rc2_cbc ||
- EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_SET_RC2_KEY_BITS, key.size * 8, NULL)) ||
- !EVP_CipherInit_ex(&ctx, NULL, NULL,
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, key.size * 8, NULL)) ||
+ !EVP_CipherInit_ex(ctx, NULL, NULL,
key.data, ivec_size ? ivec.data : NULL, -1) ||
- !EVP_CIPHER_CTX_set_padding(&ctx, 0)) {
+ !EVP_CIPHER_CTX_set_padding(ctx, 0)) {
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
return enif_raise_exception(env, atom_notsup);
}
if (text.size > 0 && /* OpenSSL 0.9.8h asserts text.size > 0 */
- (!EVP_CipherUpdate(&ctx, out, &out_size, text.data, text.size)
+ (!EVP_CipherUpdate(ctx, out, &out_size, text.data, text.size)
|| (ASSERT(out_size == text.size), 0)
- || !EVP_CipherFinal_ex(&ctx, out + out_size, &out_size))) {
+ || !EVP_CipherFinal_ex(ctx, out + out_size, &out_size))) {
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
return enif_raise_exception(env, atom_notsup);
}
ASSERT(out_size == 0);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
CONSUME_REDS(env, text);
return ret;
@@ -1429,6 +1806,8 @@ static ERL_NIF_TERM aes_cfb_8_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM
int new_ivlen = 0;
ERL_NIF_TERM ret;
+ CHECK_NO_FIPS_MODE();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
|| !(key.size == 16 || key.size == 24 || key.size == 32)
|| !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16
@@ -1446,6 +1825,31 @@ static ERL_NIF_TERM aes_cfb_8_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM
return ret;
}
+static ERL_NIF_TERM aes_cfb_128_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Key, IVec, Data, IsEncrypt) */
+ ErlNifBinary key, ivec, text;
+ AES_KEY aes_key;
+ unsigned char ivec_clone[16]; /* writable copy */
+ int new_ivlen = 0;
+ ERL_NIF_TERM ret;
+
+ if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
+ || !(key.size == 16 || key.size == 24 || key.size == 32)
+ || !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16
+ || !enif_inspect_iolist_as_binary(env, argv[2], &text)) {
+ return enif_make_badarg(env);
+ }
+
+ memcpy(ivec_clone, ivec.data, 16);
+ AES_set_encrypt_key(key.data, key.size * 8, &aes_key);
+ AES_cfb128_encrypt((unsigned char *) text.data,
+ enif_make_new_binary(env, text.size, &ret),
+ text.size, &aes_key, ivec_clone, &new_ivlen,
+ (argv[3] == atom_true));
+ CONSUME_REDS(env,text);
+ return ret;
+}
+
static ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Key, IVec, Data, IsEncrypt) */
#ifdef HAVE_AES_IGE
@@ -1456,6 +1860,8 @@ static ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TE
unsigned char* ret_ptr;
ERL_NIF_TERM ret;
+ CHECK_NO_FIPS_MODE();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin)
|| (key_bin.size != 16 && key_bin.size != 32)
|| !enif_inspect_binary(env, argv[1], &ivec_bin)
@@ -1485,64 +1891,6 @@ static ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TE
#endif
}
-/* Common for both encrypt and decrypt
-*/
-static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Key, IVec, Data) */
- ErlNifBinary key, ivec, text;
-#ifdef HAVE_EVP_AES_CTR
- const EVP_CIPHER *cipher;
- EVP_CIPHER_CTX ctx;
- unsigned char *out;
- int outl = 0;
-#else
- AES_KEY aes_key;
- unsigned char ivec_clone[16]; /* writable copy */
- unsigned char ecount_buf[AES_BLOCK_SIZE];
- unsigned int num = 0;
-#endif
- ERL_NIF_TERM ret;
-
- if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
-#ifndef HAVE_EVP_AES_CTR
- || AES_set_encrypt_key(key.data, key.size*8, &aes_key) != 0
-#endif
- || !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16
- || !enif_inspect_iolist_as_binary(env, argv[2], &text)) {
- return enif_make_badarg(env);
- }
-#ifdef HAVE_EVP_AES_CTR
- switch (key.size)
- {
- case 16: cipher = EVP_aes_128_ctr(); break;
- case 24: cipher = EVP_aes_192_ctr(); break;
- case 32: cipher = EVP_aes_256_ctr(); break;
- default: return enif_make_badarg(env);
- }
-
- out = enif_make_new_binary(env,text.size,&ret);
- EVP_CIPHER_CTX_init(&ctx);
- EVP_CipherInit_ex(&ctx, cipher, NULL,
- key.data, ivec.data, (argv[3] == atom_true));
- EVP_CIPHER_CTX_set_padding(&ctx, 0);
- EVP_CipherUpdate(&ctx, out, &outl, text.data, text.size);
- ASSERT(outl == text.size);
- EVP_CipherFinal_ex(&ctx, out + outl, &outl);
- ASSERT(outl == 0);
- EVP_CIPHER_CTX_cleanup(&ctx);
-#else
- memcpy(ivec_clone, ivec.data, 16);
- memset(ecount_buf, 0, sizeof(ecount_buf));
- AES_ctr128_encrypt((unsigned char *) text.data,
- enif_make_new_binary(env, text.size, &ret),
- text.size, &aes_key, ivec_clone, ecount_buf, &num);
-#endif
- CONSUME_REDS(env,text);
-
- /* To do an incremental {en|de}cryption, the state to to keep between calls
- must include ivec_clone, ecount_buf and num. */
- return ret;
-}
/* Initializes state for ctr streaming (de)encryption
*/
@@ -1550,7 +1898,7 @@ static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM
static ERL_NIF_TERM aes_ctr_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Key, IVec) */
ErlNifBinary key_bin, ivec_bin;
- EVP_CIPHER_CTX *ctx;
+ struct evp_cipher_ctx *ctx;
const EVP_CIPHER *cipher;
ERL_NIF_TERM ret;
@@ -1568,18 +1916,18 @@ static ERL_NIF_TERM aes_ctr_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_
default: return enif_make_badarg(env);
}
- ctx = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(EVP_CIPHER_CTX));
- EVP_CIPHER_CTX_init(ctx);
- EVP_CipherInit_ex(ctx, cipher, NULL,
+ ctx = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx));
+ ctx->ctx = EVP_CIPHER_CTX_new();
+ EVP_CipherInit_ex(ctx->ctx, cipher, NULL,
key_bin.data, ivec_bin.data, 1);
- EVP_CIPHER_CTX_set_padding(ctx, 0);
+ EVP_CIPHER_CTX_set_padding(ctx->ctx, 0);
ret = enif_make_resource(env, ctx);
enif_release_resource(ctx);
return ret;
}
static ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Context, Data) */
- EVP_CIPHER_CTX *ctx, *new_ctx;
+ struct evp_cipher_ctx *ctx, *new_ctx;
ErlNifBinary data_bin;
ERL_NIF_TERM ret, cipher_term;
unsigned char *out;
@@ -1589,11 +1937,11 @@ static ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_N
|| !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) {
return enif_make_badarg(env);
}
- new_ctx = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(EVP_CIPHER_CTX));
- EVP_CIPHER_CTX_init(new_ctx);
- EVP_CIPHER_CTX_copy(new_ctx, ctx);
+ new_ctx = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx));
+ new_ctx->ctx = EVP_CIPHER_CTX_new();
+ EVP_CIPHER_CTX_copy(new_ctx->ctx, ctx->ctx);
out = enif_make_new_binary(env, data_bin.size, &cipher_term);
- EVP_CipherUpdate(new_ctx, out, &outl, data_bin.data, data_bin.size);
+ EVP_CipherUpdate(new_ctx->ctx, out, &outl, data_bin.data, data_bin.size);
ASSERT(outl == data_bin.size);
ret = enif_make_tuple2(env, enif_make_resource(env, new_ctx), cipher_term);
@@ -1664,7 +2012,7 @@ static ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_N
static ERL_NIF_TERM aes_gcm_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Key,Iv,AAD,In) */
#if defined(HAVE_GCM)
- EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX *ctx;
const EVP_CIPHER *cipher = NULL;
ErlNifBinary key, iv, aad, in;
unsigned int tag_len;
@@ -1688,40 +2036,40 @@ static ERL_NIF_TERM aes_gcm_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM
else if (key.size == 32)
cipher = EVP_aes_256_gcm();
- EVP_CIPHER_CTX_init(&ctx);
+ ctx = EVP_CIPHER_CTX_new();
- if (EVP_EncryptInit_ex(&ctx, cipher, NULL, NULL, NULL) != 1)
+ if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
goto out_err;
- EVP_CIPHER_CTX_set_padding(&ctx, 0);
+ EVP_CIPHER_CTX_set_padding(ctx, 0);
- if (EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, iv.size, NULL) != 1)
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv.size, NULL) != 1)
goto out_err;
- if (EVP_EncryptInit_ex(&ctx, NULL, NULL, key.data, iv.data) != 1)
+ if (EVP_EncryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
goto out_err;
- if (EVP_EncryptUpdate(&ctx, NULL, &len, aad.data, aad.size) != 1)
+ if (EVP_EncryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1)
goto out_err;
outp = enif_make_new_binary(env, in.size, &out);
- if (EVP_EncryptUpdate(&ctx, outp, &len, in.data, in.size) != 1)
+ if (EVP_EncryptUpdate(ctx, outp, &len, in.data, in.size) != 1)
goto out_err;
- if (EVP_EncryptFinal_ex(&ctx, outp+len, &len) != 1)
+ if (EVP_EncryptFinal_ex(ctx, outp+len, &len) != 1)
goto out_err;
tagp = enif_make_new_binary(env, tag_len, &out_tag);
- if (EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, tag_len, tagp) != 1)
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, tag_len, tagp) != 1)
goto out_err;
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
CONSUME_REDS(env, in);
return enif_make_tuple2(env, out, out_tag);
out_err:
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
return atom_error;
#else
@@ -1734,7 +2082,7 @@ static ERL_NIF_TERM aes_gcm_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM
#if defined(HAVE_GCM_EVP_DECRYPT_BUG)
return aes_gcm_decrypt_NO_EVP(env, argc, argv);
#elif defined(HAVE_GCM)
- EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX *ctx;
const EVP_CIPHER *cipher = NULL;
ErlNifBinary key, iv, aad, in, tag;
unsigned char *outp;
@@ -1757,34 +2105,34 @@ static ERL_NIF_TERM aes_gcm_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM
else if (key.size == 32)
cipher = EVP_aes_256_gcm();
- EVP_CIPHER_CTX_init(&ctx);
+ ctx = EVP_CIPHER_CTX_new();
- if (EVP_DecryptInit_ex(&ctx, cipher, NULL, NULL, NULL) != 1)
+ if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
goto out_err;
- if (EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, iv.size, NULL) != 1)
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv.size, NULL) != 1)
goto out_err;
- if (EVP_DecryptInit_ex(&ctx, NULL, NULL, key.data, iv.data) != 1)
+ if (EVP_DecryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
goto out_err;
- if (EVP_DecryptUpdate(&ctx, NULL, &len, aad.data, aad.size) != 1)
+ if (EVP_DecryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1)
goto out_err;
outp = enif_make_new_binary(env, in.size, &out);
- if (EVP_DecryptUpdate(&ctx, outp, &len, in.data, in.size) != 1)
+ if (EVP_DecryptUpdate(ctx, outp, &len, in.data, in.size) != 1)
goto out_err;
- if (EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, tag.size, tag.data) != 1)
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, tag.size, tag.data) != 1)
goto out_err;
- if (EVP_DecryptFinal_ex(&ctx, outp+len, &len) != 1)
+ if (EVP_DecryptFinal_ex(ctx, outp+len, &len) != 1)
goto out_err;
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
CONSUME_REDS(env, in);
return out;
out_err:
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
return atom_error;
#else
return enif_raise_exception(env, atom_notsup);
@@ -1838,71 +2186,61 @@ out_err:
}
#endif /* HAVE_GCM_EVP_DECRYPT_BUG */
-#if defined(HAVE_CHACHA20_POLY1305)
-static void
-poly1305_update_with_length(poly1305_state *poly1305,
- const unsigned char *data, size_t data_len)
-{
- size_t j = data_len;
- unsigned char length_bytes[8];
- unsigned i;
-
- for (i = 0; i < sizeof(length_bytes); i++) {
- length_bytes[i] = j;
- j >>= 8;
- }
-
- CRYPTO_poly1305_update(poly1305, data, data_len);
- CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
-}
-#endif
static ERL_NIF_TERM chacha20_poly1305_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Key,Iv,AAD,In) */
#if defined(HAVE_CHACHA20_POLY1305)
+ EVP_CIPHER_CTX *ctx;
+ const EVP_CIPHER *cipher = NULL;
ErlNifBinary key, iv, aad, in;
- unsigned char *outp;
+ unsigned char *outp, *tagp;
ERL_NIF_TERM out, out_tag;
- ErlNifUInt64 in_len_64;
- unsigned char poly1305_key[32];
- poly1305_state poly1305;
+ int len;
if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 32
- || !enif_inspect_binary(env, argv[1], &iv) || iv.size != CHACHA20_NONCE_LEN
+ || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0 || iv.size > 16
|| !enif_inspect_iolist_as_binary(env, argv[2], &aad)
|| !enif_inspect_iolist_as_binary(env, argv[3], &in)) {
return enif_make_badarg(env);
}
- /* Take from OpenSSL patch set/LibreSSL:
- *
- * The underlying ChaCha implementation may not overflow the block
- * counter into the second counter word. Therefore we disallow
- * individual operations that work on more than 2TB at a time.
- * in_len_64 is needed because, on 32-bit platforms, size_t is only
- * 32-bits and this produces a warning because it's always false.
- * Casting to uint64_t inside the conditional is not sufficient to stop
- * the warning. */
- in_len_64 = in.size;
- if (in_len_64 >= (1ULL << 32) * 64 - 64)
- return enif_make_badarg(env);
+ cipher = EVP_chacha20_poly1305();
+
+ ctx = EVP_CIPHER_CTX_new();
+
+ if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
+ goto out_err;
+
+ EVP_CIPHER_CTX_set_padding(ctx, 0);
- memset(poly1305_key, 0, sizeof(poly1305_key));
- CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), key.data, iv.data, 0);
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv.size, NULL) != 1)
+ goto out_err;
+ if (EVP_EncryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
+ goto out_err;
+ if (EVP_EncryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1)
+ goto out_err;
outp = enif_make_new_binary(env, in.size, &out);
- CRYPTO_poly1305_init(&poly1305, poly1305_key);
- poly1305_update_with_length(&poly1305, aad.data, aad.size);
- CRYPTO_chacha_20(outp, in.data, in.size, key.data, iv.data, 1);
- poly1305_update_with_length(&poly1305, outp, in.size);
+ if (EVP_EncryptUpdate(ctx, outp, &len, in.data, in.size) != 1)
+ goto out_err;
+ if (EVP_EncryptFinal_ex(ctx, outp+len, &len) != 1)
+ goto out_err;
+
+ tagp = enif_make_new_binary(env, 16, &out_tag);
+
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, tagp) != 1)
+ goto out_err;
- CRYPTO_poly1305_finish(&poly1305, enif_make_new_binary(env, POLY1305_TAG_LEN, &out_tag));
+ EVP_CIPHER_CTX_free(ctx);
CONSUME_REDS(env, in);
return enif_make_tuple2(env, out, out_tag);
+out_err:
+ EVP_CIPHER_CTX_free(ctx);
+ return atom_error;
#else
return enif_raise_exception(env, atom_notsup);
#endif
@@ -1911,72 +2249,57 @@ static ERL_NIF_TERM chacha20_poly1305_encrypt(ErlNifEnv* env, int argc, const ER
static ERL_NIF_TERM chacha20_poly1305_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Key,Iv,AAD,In,Tag) */
#if defined(HAVE_CHACHA20_POLY1305)
+ EVP_CIPHER_CTX *ctx;
+ const EVP_CIPHER *cipher = NULL;
ErlNifBinary key, iv, aad, in, tag;
unsigned char *outp;
ERL_NIF_TERM out;
- ErlNifUInt64 in_len_64;
- unsigned char poly1305_key[32];
- unsigned char mac[POLY1305_TAG_LEN];
- poly1305_state poly1305;
+ int len;
if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 32
- || !enif_inspect_binary(env, argv[1], &iv) || iv.size != CHACHA20_NONCE_LEN
+ || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0 || iv.size > 16
|| !enif_inspect_iolist_as_binary(env, argv[2], &aad)
|| !enif_inspect_iolist_as_binary(env, argv[3], &in)
- || !enif_inspect_iolist_as_binary(env, argv[4], &tag) || tag.size != POLY1305_TAG_LEN) {
+ || !enif_inspect_iolist_as_binary(env, argv[4], &tag) || tag.size != 16) {
return enif_make_badarg(env);
}
- /* Take from OpenSSL patch set/LibreSSL:
- *
- * The underlying ChaCha implementation may not overflow the block
- * counter into the second counter word. Therefore we disallow
- * individual operations that work on more than 2TB at a time.
- * in_len_64 is needed because, on 32-bit platforms, size_t is only
- * 32-bits and this produces a warning because it's always false.
- * Casting to uint64_t inside the conditional is not sufficient to stop
- * the warning. */
- in_len_64 = in.size;
- if (in_len_64 >= (1ULL << 32) * 64 - 64)
- return enif_make_badarg(env);
-
- memset(poly1305_key, 0, sizeof(poly1305_key));
- CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), key.data, iv.data, 0);
+ cipher = EVP_chacha20_poly1305();
- CRYPTO_poly1305_init(&poly1305, poly1305_key);
- poly1305_update_with_length(&poly1305, aad.data, aad.size);
- poly1305_update_with_length(&poly1305, in.data, in.size);
- CRYPTO_poly1305_finish(&poly1305, mac);
+ ctx = EVP_CIPHER_CTX_new();
- if (memcmp(mac, tag.data, POLY1305_TAG_LEN) != 0)
- return atom_error;
+ if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
+ goto out_err;
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv.size, NULL) != 1)
+ goto out_err;
+ if (EVP_DecryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
+ goto out_err;
+ if (EVP_DecryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1)
+ goto out_err;
outp = enif_make_new_binary(env, in.size, &out);
- CRYPTO_chacha_20(outp, in.data, in.size, key.data, iv.data, 1);
+ if (EVP_DecryptUpdate(ctx, outp, &len, in.data, in.size) != 1)
+ goto out_err;
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag.size, tag.data) != 1)
+ goto out_err;
+ if (EVP_DecryptFinal_ex(ctx, outp+len, &len) != 1)
+ goto out_err;
+
+ EVP_CIPHER_CTX_free(ctx);
CONSUME_REDS(env, in);
return out;
+
+out_err:
+ EVP_CIPHER_CTX_free(ctx);
+ return atom_error;
#else
return enif_raise_exception(env, atom_notsup);
#endif
}
-static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Bytes) */
- unsigned bytes;
- unsigned char* data;
- ERL_NIF_TERM ret;
-
- if (!enif_get_uint(env, argv[0], &bytes)) {
- return enif_make_badarg(env);
- }
- data = enif_make_new_binary(env, bytes, &ret);
- RAND_pseudo_bytes(data, bytes);
- ERL_VALGRIND_MAKE_MEM_DEFINED(data, bytes);
- return ret;
-}
static ERL_NIF_TERM strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Bytes) */
unsigned bytes;
@@ -1995,49 +2318,6 @@ static ERL_NIF_TERM strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NI
}
-static ERL_NIF_TERM strong_rand_mpint_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Bytes, TopMask, BottomMask) */
- unsigned bits;
- BIGNUM *bn_rand;
- int top, bottom;
- unsigned char* data;
- unsigned dlen;
- ERL_NIF_TERM ret;
-
- if (!enif_get_uint(env, argv[0], &bits)
- || !enif_get_int(env, argv[1], &top)
- || !enif_get_int(env, argv[2], &bottom)) {
- return enif_make_badarg(env);
- }
- if (! (top == -1 || top == 0 || top == 1) ) {
- return enif_make_badarg(env);
- }
- if (! (bottom == 0 || bottom == 1) ) {
- return enif_make_badarg(env);
- }
-
- bn_rand = BN_new();
- if (! bn_rand ) {
- return enif_make_badarg(env);
- }
-
- /* Get a (bits) bit random number */
- if (!BN_rand(bn_rand, bits, top, bottom)) {
- ret = atom_false;
- }
- else {
- /* Copy the bignum into an erlang mpint binary. */
- dlen = BN_num_bytes(bn_rand);
- data = enif_make_new_binary(env, dlen+4, &ret);
- put_int32(data, dlen);
- BN_bn2bin(bn_rand, data+4);
- ERL_VALGRIND_MAKE_MEM_DEFINED(data+4, dlen);
- }
- BN_free(bn_rand);
-
- return ret;
-}
-
static int get_bn_from_mpint(ErlNifEnv* env, ERL_NIF_TERM term, BIGNUM** bnp)
{
ErlNifBinary bin;
@@ -2065,6 +2345,41 @@ static int get_bn_from_bin(ErlNifEnv* env, ERL_NIF_TERM term, BIGNUM** bnp)
return 1;
}
+static ERL_NIF_TERM bin_from_bn(ErlNifEnv* env, const BIGNUM *bn)
+{
+ int bn_len;
+ unsigned char *bin_ptr;
+ ERL_NIF_TERM term;
+
+ /* Copy the bignum into an erlang binary. */
+ bn_len = BN_num_bytes(bn);
+ bin_ptr = enif_make_new_binary(env, bn_len, &term);
+ BN_bn2bin(bn, bin_ptr);
+
+ return term;
+}
+
+static ERL_NIF_TERM strong_rand_range_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Range) */
+ BIGNUM *bn_range, *bn_rand;
+ ERL_NIF_TERM ret;
+
+ if(!get_bn_from_bin(env, argv[0], &bn_range)) {
+ return enif_make_badarg(env);
+ }
+
+ bn_rand = BN_new();
+ if (BN_rand_range(bn_rand, bn_range) != 1) {
+ ret = atom_false;
+ }
+ else {
+ ret = bin_from_bn(env, bn_rand);
+ }
+ BN_free(bn_rand);
+ BN_free(bn_range);
+ return ret;
+}
+
static ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Lo,Hi) */
BIGNUM *bn_from = NULL, *bn_to, *bn_rand;
@@ -2141,7 +2456,7 @@ static ERL_NIF_TERM dss_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
DSA *dsa;
int i;
- if (!argv[0] == atom_sha
+ if (argv[0] != atom_sha
|| !enif_inspect_binary(env, argv[1], &digest_bin)
|| digest_bin.size != SHA_DIGEST_LENGTH
|| !enif_inspect_binary(env, argv[2], &sign_bin)
@@ -2163,13 +2478,10 @@ static ERL_NIF_TERM dss_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
}
dsa = DSA_new();
- dsa->p = dsa_p;
- dsa->q = dsa_q;
- dsa->g = dsa_g;
- dsa->priv_key = NULL;
- dsa->pub_key = dsa_y;
- i = DSA_verify(0, digest_bin.data, SHA_DIGEST_LENGTH,
- sign_bin.data, sign_bin.size, dsa);
+ DSA_set0_pqg(dsa, dsa_p, dsa_q, dsa_g);
+ DSA_set0_key(dsa, dsa_y, NULL);
+ i = DSA_verify(0, digest_bin.data, SHA_DIGEST_LENGTH,
+ sign_bin.data, sign_bin.size, dsa);
DSA_free(dsa);
return(i > 0) ? atom_true : atom_false;
}
@@ -2226,13 +2538,15 @@ static ERL_NIF_TERM rsa_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
ERL_NIF_TERM head, tail, ret;
int i;
RSA *rsa;
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(1,0,0)
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
EVP_PKEY *pkey;
EVP_PKEY_CTX *ctx;
#endif
const EVP_MD *md;
const ERL_NIF_TERM type = argv[0];
struct digest_type_t *digp = NULL;
+ BIGNUM *rsa_e;
+ BIGNUM *rsa_n;
digp = get_digest_type(type);
if (!digp) {
@@ -2249,16 +2563,18 @@ static ERL_NIF_TERM rsa_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
|| digest_bin.size != EVP_MD_size(md)
|| !enif_inspect_binary(env, argv[2], &sign_bin)
|| !enif_get_list_cell(env, argv[3], &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->e)
+ || !get_bn_from_bin(env, head, &rsa_e)
|| !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->n)
+ || !get_bn_from_bin(env, head, &rsa_n)
|| !enif_is_empty_list(env, tail)) {
ret = enif_make_badarg(env);
goto done;
}
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(1,0,0)
+ (void) RSA_set0_key(rsa, rsa_n, rsa_e, NULL);
+
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
pkey = EVP_PKEY_new();
EVP_PKEY_set1_RSA(pkey, rsa);
@@ -2304,43 +2620,34 @@ static ERL_NIF_TERM do_exor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
return ret;
}
-static ERL_NIF_TERM rc4_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Key, Data) */
- ErlNifBinary key, data;
- RC4_KEY rc4_key;
- ERL_NIF_TERM ret;
-
- if (!enif_inspect_iolist_as_binary(env,argv[0], &key)
- || !enif_inspect_iolist_as_binary(env,argv[1], &data)) {
- return enif_make_badarg(env);
- }
- RC4_set_key(&rc4_key, key.size, key.data);
- RC4(&rc4_key, data.size, data.data,
- enif_make_new_binary(env, data.size, &ret));
- CONSUME_REDS(env,data);
- return ret;
-}
-
static ERL_NIF_TERM rc4_set_key(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Key) */
+#ifndef OPENSSL_NO_RC4
ErlNifBinary key;
ERL_NIF_TERM ret;
+ CHECK_NO_FIPS_MODE();
+
if (!enif_inspect_iolist_as_binary(env,argv[0], &key)) {
return enif_make_badarg(env);
}
RC4_set_key((RC4_KEY*)enif_make_new_binary(env, sizeof(RC4_KEY), &ret),
key.size, key.data);
return ret;
+#else
+ return enif_raise_exception(env, atom_notsup);
+#endif
}
static ERL_NIF_TERM rc4_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (State, Data) */
-
+#ifndef OPENSSL_NO_RC4
ErlNifBinary state, data;
RC4_KEY* rc4_key;
ERL_NIF_TERM new_state, new_data;
+ CHECK_NO_FIPS_MODE();
+
if (!enif_inspect_iolist_as_binary(env,argv[0], &state)
|| state.size != sizeof(RC4_KEY)
|| !enif_inspect_iolist_as_binary(env,argv[1], &data)) {
@@ -2352,40 +2659,53 @@ static ERL_NIF_TERM rc4_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_N
enif_make_new_binary(env, data.size, &new_data));
CONSUME_REDS(env,data);
return enif_make_tuple2(env,new_state,new_data);
-}
+#else
+ return enif_raise_exception(env, atom_notsup);
+#endif
+}
static int get_rsa_private_key(ErlNifEnv* env, ERL_NIF_TERM key, RSA *rsa)
{
/* key=[E,N,D]|[E,N,D,P1,P2,E1,E2,C] */
ERL_NIF_TERM head, tail;
+ BIGNUM *e, *n, *d;
+ BIGNUM *p, *q;
+ BIGNUM *dmp1, *dmq1, *iqmp;
if (!enif_get_list_cell(env, key, &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->e)
+ || !get_bn_from_bin(env, head, &e)
+ || !enif_get_list_cell(env, tail, &head, &tail)
+ || !get_bn_from_bin(env, head, &n)
|| !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->n)
+ || !get_bn_from_bin(env, head, &d)) {
+ return 0;
+ }
+ (void) RSA_set0_key(rsa, n, e, d);
+ if (enif_is_empty_list(env, tail)) {
+ return 1;
+ }
+ if (!enif_get_list_cell(env, tail, &head, &tail)
+ || !get_bn_from_bin(env, head, &p)
+ || !enif_get_list_cell(env, tail, &head, &tail)
+ || !get_bn_from_bin(env, head, &q)
+ || !enif_get_list_cell(env, tail, &head, &tail)
+ || !get_bn_from_bin(env, head, &dmp1)
+ || !enif_get_list_cell(env, tail, &head, &tail)
+ || !get_bn_from_bin(env, head, &dmq1)
|| !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->d)
- || (!enif_is_empty_list(env, tail) &&
- (!enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->p)
- || !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->q)
- || !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->dmp1)
- || !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->dmq1)
- || !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->iqmp)
- || !enif_is_empty_list(env, tail)))) {
+ || !get_bn_from_bin(env, head, &iqmp)
+ || !enif_is_empty_list(env, tail)) {
return 0;
}
+ (void) RSA_set0_factors(rsa, p, q);
+ (void) RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp);
return 1;
}
static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Type, Digest, Key=[E,N,D]|[E,N,D,P1,P2,E1,E2,C]) */
ErlNifBinary digest_bin, ret_bin;
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(1,0,0)
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
EVP_PKEY *pkey;
EVP_PKEY_CTX *ctx;
size_t rsa_s_len;
@@ -2418,7 +2738,7 @@ static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
}
-#if OPENSSL_VERSION_NUMBER >= OpenSSL_version_plain(1,0,0)
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
pkey = EVP_PKEY_new();
EVP_PKEY_set1_RSA(pkey, rsa);
rsa_s_len=(size_t)EVP_PKEY_size(pkey);
@@ -2465,34 +2785,47 @@ static ERL_NIF_TERM dss_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
ERL_NIF_TERM head, tail;
unsigned int dsa_s_len;
DSA* dsa;
+ BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
+ BIGNUM *dummy_pub_key, *priv_key = NULL;
int i;
- if (!argv[0] == atom_sha
+ if (argv[0] != atom_sha
|| !enif_inspect_binary(env, argv[1], &digest_bin)
|| digest_bin.size != SHA_DIGEST_LENGTH) {
return enif_make_badarg(env);
}
- dsa = DSA_new();
-
- dsa->pub_key = NULL;
if (!enif_get_list_cell(env, argv[2], &head, &tail)
- || !get_bn_from_bin(env, head, &dsa->p)
+ || !get_bn_from_bin(env, head, &dsa_p)
|| !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &dsa->q)
+ || !get_bn_from_bin(env, head, &dsa_q)
|| !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &dsa->g)
+ || !get_bn_from_bin(env, head, &dsa_g)
|| !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &dsa->priv_key)
+ || !get_bn_from_bin(env, head, &priv_key)
|| !enif_is_empty_list(env,tail)) {
- DSA_free(dsa);
+ if (dsa_p) BN_free(dsa_p);
+ if (dsa_q) BN_free(dsa_q);
+ if (dsa_g) BN_free(dsa_g);
+ if (priv_key) BN_free(priv_key);
return enif_make_badarg(env);
}
+ /* Note: DSA_set0_key() does not allow setting only the
+ * private key, although DSA_sign() does not use the
+ * public key. Work around this limitation by setting
+ * the public key to a copy of the private key.
+ */
+ dummy_pub_key = BN_dup(priv_key);
+
+ dsa = DSA_new();
+ DSA_set0_pqg(dsa, dsa_p, dsa_q, dsa_g);
+ DSA_set0_key(dsa, dummy_pub_key, priv_key);
enif_alloc_binary(DSA_size(dsa), &ret_bin);
i = DSA_sign(NID_sha1, digest_bin.data, SHA_DIGEST_LENGTH,
ret_bin.data, &dsa_s_len, dsa);
DSA_free(dsa);
+
if (i) {
if (dsa_s_len != ret_bin.size) {
enif_realloc_binary(&ret_bin, dsa_s_len);
@@ -2529,20 +2862,22 @@ static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TER
ERL_NIF_TERM head, tail;
int padding, i;
RSA* rsa;
+ BIGNUM *e, *n;
rsa = RSA_new();
if (!enif_inspect_binary(env, argv[0], &data_bin)
|| !enif_get_list_cell(env, argv[1], &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->e)
+ || !get_bn_from_bin(env, head, &e)
|| !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &rsa->n)
+ || !get_bn_from_bin(env, head, &n)
|| !enif_is_empty_list(env,tail)
|| !rsa_pad(argv[2], &padding)) {
RSA_free(rsa);
return enif_make_badarg(env);
}
+ (void) RSA_set0_key(rsa, n, e, NULL);
enif_alloc_binary(RSA_size(rsa), &ret_bin);
@@ -2616,6 +2951,119 @@ static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE
}
}
+/* Creates a term which can be parsed by get_rsa_private_key(). This is a list of plain integer binaries (not mpints). */
+static ERL_NIF_TERM put_rsa_private_key(ErlNifEnv* env, const RSA *rsa)
+{
+ ERL_NIF_TERM result[8];
+ const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
+
+ /* Return at least [E,N,D] */
+ n = NULL; e = NULL; d = NULL;
+ RSA_get0_key(rsa, &n, &e, &d);
+
+ result[0] = bin_from_bn(env, e); // Exponent E
+ result[1] = bin_from_bn(env, n); // Modulus N = p*q
+ result[2] = bin_from_bn(env, d); // Exponent D
+
+ /* Check whether the optional additional parameters are available */
+ p = NULL; q = NULL;
+ RSA_get0_factors(rsa, &p, &q);
+ dmp1 = NULL; dmq1 = NULL; iqmp = NULL;
+ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
+
+ if (p && q && dmp1 && dmq1 && iqmp) {
+ result[3] = bin_from_bn(env, p); // Factor p
+ result[4] = bin_from_bn(env, q); // Factor q
+ result[5] = bin_from_bn(env, dmp1); // D mod (p-1)
+ result[6] = bin_from_bn(env, dmq1); // D mod (q-1)
+ result[7] = bin_from_bn(env, iqmp); // (1/q) mod p
+
+ return enif_make_list_from_array(env, result, 8);
+ } else {
+ return enif_make_list_from_array(env, result, 3);
+ }
+}
+
+static int check_erlang_interrupt(int maj, int min, BN_GENCB *ctxt)
+{
+ ErlNifEnv *env = BN_GENCB_get_arg(ctxt);
+
+ if (!enif_is_current_process_alive(env)) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+static ERL_NIF_TERM rsa_generate_key(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (ModulusSize, PublicExponent) */
+ int modulus_bits;
+ BIGNUM *pub_exp, *three;
+ RSA *rsa;
+ int success;
+ ERL_NIF_TERM result;
+ BN_GENCB *intr_cb;
+#ifndef HAVE_OPAQUE_BN_GENCB
+ BN_GENCB intr_cb_buf;
+#endif
+
+ if (!enif_get_int(env, argv[0], &modulus_bits) || modulus_bits < 256) {
+ return enif_make_badarg(env);
+ }
+
+ if (!get_bn_from_bin(env, argv[1], &pub_exp)) {
+ return enif_make_badarg(env);
+ }
+
+ /* Make sure the public exponent is large enough (at least 3).
+ * Without this, RSA_generate_key_ex() can run forever. */
+ three = BN_new();
+ BN_set_word(three, 3);
+ success = BN_cmp(pub_exp, three);
+ BN_free(three);
+ if (success < 0) {
+ BN_free(pub_exp);
+ return enif_make_badarg(env);
+ }
+
+ /* For large keys, prime generation can take many seconds. Set up
+ * the callback which we use to test whether the process has been
+ * interrupted. */
+#ifdef HAVE_OPAQUE_BN_GENCB
+ intr_cb = BN_GENCB_new();
+#else
+ intr_cb = &intr_cb_buf;
+#endif
+ BN_GENCB_set(intr_cb, check_erlang_interrupt, env);
+
+ rsa = RSA_new();
+ success = RSA_generate_key_ex(rsa, modulus_bits, pub_exp, intr_cb);
+ BN_free(pub_exp);
+
+#ifdef HAVE_OPAQUE_BN_GENCB
+ BN_GENCB_free(intr_cb);
+#endif
+
+ if (!success) {
+ RSA_free(rsa);
+ return atom_error;
+ }
+
+ result = put_rsa_private_key(env, rsa);
+ RSA_free(rsa);
+
+ return result;
+}
+
+static ERL_NIF_TERM rsa_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ /* RSA key generation can take a long time (>1 sec for a large
+ * modulus), so schedule it as a CPU-bound operation. */
+ return enif_schedule_nif(env, "rsa_generate_key",
+ ERL_NIF_DIRTY_JOB_CPU_BOUND,
+ rsa_generate_key, argc, argv);
+}
+
static ERL_NIF_TERM dh_generate_parameters_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (PrimeLen, Generator) */
int prime_len, generator;
@@ -2623,6 +3071,7 @@ static ERL_NIF_TERM dh_generate_parameters_nif(ErlNifEnv* env, int argc, const E
int p_len, g_len;
unsigned char *p_ptr, *g_ptr;
ERL_NIF_TERM ret_p, ret_g;
+ const BIGNUM *dh_p, *dh_q, *dh_g;
if (!enif_get_int(env, argv[0], &prime_len)
|| !enif_get_int(env, argv[1], &generator)) {
@@ -2633,15 +3082,16 @@ static ERL_NIF_TERM dh_generate_parameters_nif(ErlNifEnv* env, int argc, const E
if (dh_params == NULL) {
return atom_error;
}
- p_len = BN_num_bytes(dh_params->p);
- g_len = BN_num_bytes(dh_params->g);
+ DH_get0_pqg(dh_params, &dh_p, &dh_q, &dh_g);
+ DH_free(dh_params);
+ p_len = BN_num_bytes(dh_p);
+ g_len = BN_num_bytes(dh_g);
p_ptr = enif_make_new_binary(env, p_len, &ret_p);
g_ptr = enif_make_new_binary(env, g_len, &ret_g);
- BN_bn2bin(dh_params->p, p_ptr);
- BN_bn2bin(dh_params->g, g_ptr);
+ BN_bn2bin(dh_p, p_ptr);
+ BN_bn2bin(dh_g, g_ptr);
ERL_VALGRIND_MAKE_MEM_DEFINED(p_ptr, p_len);
ERL_VALGRIND_MAKE_MEM_DEFINED(g_ptr, g_len);
- DH_free(dh_params);
return enif_make_list2(env, ret_p, ret_g);
}
@@ -2650,18 +3100,19 @@ static ERL_NIF_TERM dh_check(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
DH* dh_params;
int i;
ERL_NIF_TERM ret, head, tail;
-
- dh_params = DH_new();
+ BIGNUM *dh_p, *dh_g;
if (!enif_get_list_cell(env, argv[0], &head, &tail)
- || !get_bn_from_bin(env, head, &dh_params->p)
+ || !get_bn_from_bin(env, head, &dh_p)
|| !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &dh_params->g)
+ || !get_bn_from_bin(env, head, &dh_g)
|| !enif_is_empty_list(env,tail)) {
- DH_free(dh_params);
return enif_make_badarg(env);
}
+
+ dh_params = DH_new();
+ DH_set0_pqg(dh_params, dh_p, NULL, dh_g);
if (DH_check(dh_params, &i)) {
if (i == 0) ret = atom_ok;
else if (i & DH_CHECK_P_NOT_PRIME) ret = atom_not_prime;
@@ -2678,38 +3129,58 @@ static ERL_NIF_TERM dh_check(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
}
static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (PrivKey, DHParams=[P,G], Mpint) */
+{/* (PrivKey|undefined, DHParams=[P,G], Mpint, Len|0) */
DH* dh_params;
int pub_len, prv_len;
unsigned char *pub_ptr, *prv_ptr;
ERL_NIF_TERM ret, ret_pub, ret_prv, head, tail;
int mpint; /* 0 or 4 */
+ BIGNUM *priv_key = NULL;
+ BIGNUM *dh_p = NULL, *dh_g = NULL;
+ unsigned long len = 0;
- dh_params = DH_new();
-
- if (!(get_bn_from_bin(env, argv[0], &dh_params->priv_key)
+ if (!(get_bn_from_bin(env, argv[0], &priv_key)
|| argv[0] == atom_undefined)
|| !enif_get_list_cell(env, argv[1], &head, &tail)
- || !get_bn_from_bin(env, head, &dh_params->p)
+ || !get_bn_from_bin(env, head, &dh_p)
|| !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &dh_params->g)
+ || !get_bn_from_bin(env, head, &dh_g)
|| !enif_is_empty_list(env, tail)
- || !enif_get_int(env, argv[2], &mpint) || (mpint & ~4)) {
- DH_free(dh_params);
+ || !enif_get_int(env, argv[2], &mpint) || (mpint & ~4)
+ || !enif_get_ulong(env, argv[3], &len) ) {
+
+ if (priv_key) BN_free(priv_key);
+ if (dh_p) BN_free(dh_p);
+ if (dh_g) BN_free(dh_g);
return enif_make_badarg(env);
}
+ dh_params = DH_new();
+ DH_set0_key(dh_params, NULL, priv_key);
+ DH_set0_pqg(dh_params, dh_p, NULL, dh_g);
+
+ if (len) {
+ if (len < BN_num_bits(dh_p))
+ DH_set_length(dh_params, len);
+ else {
+ DH_free(dh_params);
+ return enif_make_badarg(env);
+ }
+ }
+
if (DH_generate_key(dh_params)) {
- pub_len = BN_num_bytes(dh_params->pub_key);
- prv_len = BN_num_bytes(dh_params->priv_key);
+ const BIGNUM *pub_key, *priv_key;
+ DH_get0_key(dh_params, &pub_key, &priv_key);
+ pub_len = BN_num_bytes(pub_key);
+ prv_len = BN_num_bytes(priv_key);
pub_ptr = enif_make_new_binary(env, pub_len+mpint, &ret_pub);
prv_ptr = enif_make_new_binary(env, prv_len+mpint, &ret_prv);
if (mpint) {
put_int32(pub_ptr, pub_len); pub_ptr += 4;
put_int32(prv_ptr, prv_len); prv_ptr += 4;
}
- BN_bn2bin(dh_params->pub_key, pub_ptr);
- BN_bn2bin(dh_params->priv_key, prv_ptr);
+ BN_bn2bin(pub_key, pub_ptr);
+ BN_bn2bin(priv_key, prv_ptr);
ERL_VALGRIND_MAKE_MEM_DEFINED(pub_ptr, pub_len);
ERL_VALGRIND_MAKE_MEM_DEFINED(prv_ptr, prv_len);
ret = enif_make_tuple2(env, ret_pub, ret_prv);
@@ -2724,26 +3195,37 @@ static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_
static ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (OthersPublicKey, MyPrivateKey, DHParams=[P,G]) */
DH* dh_params;
- BIGNUM* pubkey = NULL;
+ BIGNUM *dummy_pub_key = NULL, *priv_key = NULL;
+ BIGNUM *other_pub_key;
+ BIGNUM *dh_p = NULL, *dh_g = NULL;
int i;
ErlNifBinary ret_bin;
ERL_NIF_TERM ret, head, tail;
dh_params = DH_new();
- if (!get_bn_from_bin(env, argv[0], &pubkey)
- || !get_bn_from_bin(env, argv[1], &dh_params->priv_key)
+ if (!get_bn_from_bin(env, argv[0], &other_pub_key)
+ || !get_bn_from_bin(env, argv[1], &priv_key)
|| !enif_get_list_cell(env, argv[2], &head, &tail)
- || !get_bn_from_bin(env, head, &dh_params->p)
+ || !get_bn_from_bin(env, head, &dh_p)
|| !enif_get_list_cell(env, tail, &head, &tail)
- || !get_bn_from_bin(env, head, &dh_params->g)
+ || !get_bn_from_bin(env, head, &dh_g)
|| !enif_is_empty_list(env, tail)) {
-
+ if (dh_p) BN_free(dh_p);
+ if (dh_g) BN_free(dh_g);
ret = enif_make_badarg(env);
}
else {
+ /* Note: DH_set0_key() does not allow setting only the
+ * private key, although DH_compute_key() does not use the
+ * public key. Work around this limitation by setting
+ * the public key to a copy of the private key.
+ */
+ dummy_pub_key = BN_dup(priv_key);
+ DH_set0_key(dh_params, dummy_pub_key, priv_key);
+ DH_set0_pqg(dh_params, dh_p, NULL, dh_g);
enif_alloc_binary(DH_size(dh_params), &ret_bin);
- i = DH_compute_key(ret_bin.data, pubkey, dh_params);
+ i = DH_compute_key(ret_bin.data, other_pub_key, dh_params);
if (i > 0) {
if (i != ret_bin.size) {
enif_realloc_binary(&ret_bin, i);
@@ -2755,7 +3237,7 @@ static ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_T
ret = atom_error;
}
}
- if (pubkey) BN_free(pubkey);
+ if (other_pub_key) BN_free(other_pub_key);
DH_free(dh_params);
return ret;
}
@@ -2769,6 +3251,8 @@ static ERL_NIF_TERM srp_value_B_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
unsigned dlen;
ERL_NIF_TERM ret;
+ CHECK_NO_FIPS_MODE();
+
if (!get_bn_from_bin(env, argv[0], &bn_multiplier)
|| !get_bn_from_bin(env, argv[1], &bn_verifier)
|| !get_bn_from_bin(env, argv[2], &bn_generator)
@@ -2829,6 +3313,8 @@ static ERL_NIF_TERM srp_user_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_
unsigned dlen;
ERL_NIF_TERM ret;
+ CHECK_NO_FIPS_MODE();
+
if (!get_bn_from_bin(env, argv[0], &bn_a)
|| !get_bn_from_bin(env, argv[1], &bn_u)
|| !get_bn_from_bin(env, argv[2], &bn_B)
@@ -2908,6 +3394,8 @@ static ERL_NIF_TERM srp_host_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_
unsigned dlen;
ERL_NIF_TERM ret;
+ CHECK_NO_FIPS_MODE();
+
if (!get_bn_from_bin(env, argv[0], &bn_verifier)
|| !get_bn_from_bin(env, argv[1], &bn_b)
|| !get_bn_from_bin(env, argv[2], &bn_u)
@@ -3327,7 +3815,7 @@ static ERL_NIF_TERM ecdsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
enif_alloc_binary(ECDSA_size(key), &ret_bin);
- i = ECDSA_sign(md->type, digest_bin.data, len,
+ i = ECDSA_sign(EVP_MD_type(md), digest_bin.data, len,
ret_bin.data, &dsa_s_len, key);
EC_KEY_free(key);
@@ -3377,7 +3865,7 @@ static ERL_NIF_TERM ecdsa_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TER
|| !get_ec_key(env, argv[3], atom_undefined, argv[4], &key))
goto badarg;
- i = ECDSA_verify(md->type, digest_bin.data, len,
+ i = ECDSA_verify(EVP_MD_type(md), digest_bin.data, len,
sign_bin.data, sign_bin.size, key);
EC_KEY_free(key);
diff --git a/lib/crypto/c_src/crypto_callback.c b/lib/crypto/c_src/crypto_callback.c
index 3acbbf406b..23d2bed057 100644
--- a/lib/crypto/c_src/crypto_callback.c
+++ b/lib/crypto/c_src/crypto_callback.c
@@ -22,7 +22,7 @@
#include <string.h>
#include <openssl/opensslconf.h>
-#include "erl_nif.h"
+#include <erl_nif.h>
#include "crypto_callback.h"
#ifdef DEBUG
@@ -62,7 +62,7 @@ static void nomem(size_t size, const char* op)
abort();
}
-static void* crypto_alloc(size_t size)
+static void* crypto_alloc(size_t size CCB_FILE_LINE_ARGS)
{
void *ret = enif_alloc(size);
@@ -70,7 +70,7 @@ static void* crypto_alloc(size_t size)
nomem(size, "allocate");
return ret;
}
-static void* crypto_realloc(void* ptr, size_t size)
+static void* crypto_realloc(void* ptr, size_t size CCB_FILE_LINE_ARGS)
{
void* ret = enif_realloc(ptr, size);
@@ -78,7 +78,7 @@ static void* crypto_realloc(void* ptr, size_t size)
nomem(size, "reallocate");
return ret;
}
-static void crypto_free(void* ptr)
+static void crypto_free(void* ptr CCB_FILE_LINE_ARGS)
{
enif_free(ptr);
}
diff --git a/lib/crypto/c_src/crypto_callback.h b/lib/crypto/c_src/crypto_callback.h
index 894d86cfd9..d46266fd8b 100644
--- a/lib/crypto/c_src/crypto_callback.h
+++ b/lib/crypto/c_src/crypto_callback.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2012-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2012-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,13 +18,20 @@
* %CopyrightEnd%
*/
+#include <openssl/crypto.h>
+#ifdef NEED_EVP_COMPATIBILITY_FUNCTIONS
+# define CCB_FILE_LINE_ARGS
+#else
+# define CCB_FILE_LINE_ARGS , const char *file, int line
+#endif
+
struct crypto_callbacks
{
size_t sizeof_me;
- void* (*crypto_alloc)(size_t size);
- void* (*crypto_realloc)(void* ptr, size_t size);
- void (*crypto_free)(void* ptr);
+ void* (*crypto_alloc)(size_t size CCB_FILE_LINE_ARGS);
+ void* (*crypto_realloc)(void* ptr, size_t size CCB_FILE_LINE_ARGS);
+ void (*crypto_free)(void* ptr CCB_FILE_LINE_ARGS);
/* openssl callbacks */
#ifdef OPENSSL_THREADS
diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile
index e55242d255..9c503b8fe0 100644
--- a/lib/crypto/doc/src/Makefile
+++ b/lib/crypto/doc/src/Makefile
@@ -39,7 +39,7 @@ XML_REF3_FILES = crypto.xml
XML_REF6_FILES = crypto_app.xml
XML_PART_FILES = release_notes.xml usersguide.xml
-XML_CHAPTER_FILES = notes.xml licenses.xml
+XML_CHAPTER_FILES = notes.xml licenses.xml fips.xml
BOOK_FILES = book.xml
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 5a5627747c..89ef529c5d 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1999</year><year>2016</year>
+ <year>1999</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -41,6 +41,9 @@
<p>Hmac functions - <url href="http://www.ietf.org/rfc/rfc2104.txt"> Keyed-Hashing for Message Authentication (RFC 2104) </url></p>
</item>
<item>
+ <p>Cmac functions - <url href="http://www.ietf.org/rfc/rfc4493.txt">The AES-CMAC Algorithm (RFC 4493)</url></p>
+ </item>
+ <item>
<p>Block ciphers - <url href="http://csrc.nist.gov/groups/ST/toolkit/block_ciphers.html"> </url> DES and AES in
Block Cipher Modes - <url href="http://csrc.nist.gov/groups/ST/toolkit/BCM/index.html"> ECB, CBC, CFB, OFB, CTR and GCM </url></p>
</item>
@@ -74,7 +77,7 @@
<code>rsa_private() = [key_value()] = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] </code>
<p>Where E is the public exponent, N is public modulus and D is
- the private exponent.The longer key format contains redundant
+ the private exponent. The longer key format contains redundant
information that will make the calculation faster. P1,P2 are first
and second prime factors. E1,E2 are first and second exponents. C
is the CRT coefficient. Terminology is taken from <url href="http://www.ietf.org/rfc/rfc3477.txt"> RFC 3447</url>.</p>
@@ -100,7 +103,7 @@
<code>dh_private() = key_value() </code>
- <code>dh_params() = [key_value()] = [P, G] </code>
+ <code>dh_params() = [key_value()] = [P, G] | [P, G, PrivateKeyBitLength]</code>
<code>ecdh_public() = key_value() </code>
@@ -136,7 +139,7 @@
<code>stream_cipher() = rc4 | aes_ctr </code>
<code>block_cipher() = aes_cbc | aes_cfb8 | aes_cfb128 | aes_ige256 | blowfish_cbc |
- blowfish_cfb64 | des_cbc | des_cfb | des3_cbc | des3_cbf | des_ede3 | rc2_cbc </code>
+ blowfish_cfb64 | des_cbc | des_cfb | des3_cbc | des3_cfb | des_ede3 | rc2_cbc </code>
<code>aead_cipher() = aes_gcm | chacha20_poly1305 </code>
@@ -161,7 +164,7 @@
</p>
<code> cipher_algorithms() = aes_cbc | aes_cfb8 | aes_cfb128 | aes_ctr | aes_gcm |
aes_ige256 | blowfish_cbc | blowfish_cfb64 | chacha20_poly1305 | des_cbc | des_cfb |
- des3_cbc | des3_cbf | des_ede3 | rc2_cbc | rc4 </code>
+ des3_cbc | des3_cfb | des_ede3 | rc2_cbc | rc4 </code>
<code> public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m</code>
<p>Note that ec_gf2m is not strictly a public key algorithm, but a restriction on what curves are supported
with ecdsa and ecdh.
@@ -295,22 +298,32 @@
<func>
<name>generate_key(Type, Params) -> {PublicKey, PrivKeyOut} </name>
<name>generate_key(Type, Params, PrivKeyIn) -> {PublicKey, PrivKeyOut} </name>
- <fsummary>Generates a public keys of type <c>Type</c></fsummary>
+ <fsummary>Generates a public key of type <c>Type</c></fsummary>
<type>
- <v> Type = dh | ecdh | srp </v>
- <v>Params = dh_params() | ecdh_params() | SrpUserParams | SrpHostParams </v>
+ <v> Type = dh | ecdh | rsa | srp </v>
+ <v>Params = dh_params() | ecdh_params() | RsaParams | SrpUserParams | SrpHostParams </v>
+ <v>RsaParams = {ModulusSizeInBits::integer(), PublicExponent::key_value()}</v>
<v>SrpUserParams = {user, [Generator::binary(), Prime::binary(), Version::atom()]}</v>
<v>SrpHostParams = {host, [Verifier::binary(), Generator::binary(), Prime::binary(), Version::atom()]}</v>
- <v>PublicKey = dh_public() | ecdh_public() | srp_public() </v>
+ <v>PublicKey = dh_public() | ecdh_public() | rsa_public() | srp_public() </v>
<v>PrivKeyIn = undefined | dh_private() | ecdh_private() | srp_private() </v>
- <v>PrivKeyOut = dh_private() | ecdh_private() | srp_private() </v>
+ <v>PrivKeyOut = dh_private() | ecdh_private() | rsa_private() | srp_private() </v>
</type>
<desc>
- <p>Generates public keys of type <c>Type</c>.
- See also <seealso marker="public_key:public_key#generate_key-1">public_key:generate_key/1</seealso>
- May throw exception <c>low_entropy</c> in case the random generator
- failed due to lack of secure "randomness".
- </p>
+ <p>Generates a public key of type <c>Type</c>.
+ See also <seealso marker="public_key:public_key#generate_key-1">public_key:generate_key/1</seealso>.
+ May throw exception an exception of class <c>error</c>:
+ </p>
+ <list type="bulleted">
+ <item><c>badarg</c>: an argument is of wrong type or has an illegal value,</item>
+ <item><c>low_entropy</c>: the random generator failed due to lack of secure "randomness",</item>
+ <item><c>computation_failed</c>: the computation fails of another reason than <c>low_entropy</c>.</item>
+ </list>
+ <note>
+ <p>RSA key generation is only available if the runtime was
+ built with dirty scheduler support. Otherwise, attempting to
+ generate an RSA key will throw exception <c>error:notsup</c>.</p>
+ </note>
</desc>
</func>
@@ -454,6 +467,46 @@
</func>
<func>
+ <name>cmac(Type, Key, Data) -> Mac</name>
+ <name>cmac(Type, Key, Data, MacLength) -> Mac</name>
+ <fsummary>Calculates the Cipher-based Message Authentication Code.</fsummary>
+ <type>
+ <v>Type = block_cipher()</v>
+ <v>Key = iodata()</v>
+ <v>Data = iodata()</v>
+ <v>MacLength = integer()</v>
+ <v>Mac = binary()</v>
+ </type>
+ <desc>
+ <p>Computes a CMAC of type <c>Type</c> from <c>Data</c> using
+ <c>Key</c> as the authentication key.</p> <p><c>MacLength</c>
+ will limit the size of the resultant <c>Mac</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>info_fips() -> Status</name>
+ <fsummary>Provides information about the FIPS operating status.</fsummary>
+ <type>
+ <v>Status = enabled | not_enabled | not_supported</v>
+ </type>
+ <desc>
+ <p>Provides information about the FIPS operating status of
+ crypto and the underlying OpenSSL library. If crypto was built
+ with FIPS support this can be either <c>enabled</c> (when
+ running in FIPS mode) or <c>not_enabled</c>. For other builds
+ this value is always <c>not_supported</c>.</p>
+ <warning>
+ <p>In FIPS mode all non-FIPS compliant algorithms are
+ disabled and throw exception <c>not_supported</c>. Check
+ <seealso marker="#supports-0">supports</seealso> that in
+ FIPS mode returns the restricted list of available
+ algorithms.</p>
+ </warning>
+ </desc>
+ </func>
+
+ <func>
<name>info_lib() -> [{Name,VerNum,VerStr}]</name>
<fsummary>Provides information about the libraries used by crypto.</fsummary>
<type>
@@ -468,7 +521,7 @@
scheme. <c>VerStr</c> contains a text variant of the version.</p>
<pre>
> <input>info_lib().</input>
-[{&lt;&lt;"OpenSSL"&gt;&gt;,9469983,&lt;&lt;"OpenSSL 0.9.8a 11 Oct 2005"&gt;&gt;}]
+[{&lt;&lt;"OpenSSL"&gt;&gt;,269484095,&lt;&lt;"OpenSSL 1.1.0c 10 Nov 2016""&gt;&gt;}]
</pre>
<note><p>
From OTP R16 the <em>numeric version</em> represents the version of the OpenSSL
@@ -605,10 +658,11 @@
</type>
<desc>
<p>Set the seed for PRNG to the given binary. This calls the
- RAND_seed function from openssl. Only use this if the system
- you are running on does not have enough "randomness" built in.
- Normally this is when <seealso marker="#strong_rand_bytes/1">
- strong_rand_bytes/1</seealso> returns <c>low_entropy</c></p>
+ RAND_seed function from openssl. Only use this if the system
+ you are running on does not have enough "randomness" built in.
+ Normally this is when
+ <seealso marker="#strong_rand_bytes/1">strong_rand_bytes/1</seealso>
+ throws <c>low_entropy</c></p>
</desc>
</func>
@@ -675,6 +729,43 @@
failed due to lack of secure "randomness".</p>
</desc>
</func>
+
+ <func>
+ <name>rand_seed() -> rand:state()</name>
+ <fsummary>Strong random number generation plugin state</fsummary>
+ <desc>
+ <p>
+ Creates state object for
+ <seealso marker="stdlib:rand">random number generation</seealso>,
+ in order to generate cryptographically strong random numbers
+ (based on OpenSSL's <c>BN_rand_range</c>),
+ and saves it on process dictionary before returning it as well.
+ See also
+ <seealso marker="stdlib:rand#seed-1">rand:seed/1</seealso>.
+ </p>
+ <p><em>Example</em></p>
+ <pre>
+_ = crypto:rand_seed(),
+_IntegerValue = rand:uniform(42), % [1; 42]
+_FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name>rand_seed_s() -> rand:state()</name>
+ <fsummary>Strong random number generation plugin state</fsummary>
+ <desc>
+ <p>
+ Creates state object for
+ <seealso marker="stdlib:rand">random number generation</seealso>,
+ in order to generate cryptographically strongly random numbers
+ (based on OpenSSL's <c>BN_rand_range</c>).
+ See also
+ <seealso marker="stdlib:rand#seed_s-1">rand:seed_s/1</seealso>.
+ </p>
+ </desc>
+ </func>
+
<func>
<name>stream_init(Type, Key) -> State</name>
<fsummary></fsummary>
diff --git a/lib/crypto/doc/src/crypto_app.xml b/lib/crypto/doc/src/crypto_app.xml
index 2b9e505988..ba22557480 100644
--- a/lib/crypto/doc/src/crypto_app.xml
+++ b/lib/crypto/doc/src/crypto_app.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1999</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -41,14 +41,37 @@
<section>
<title>DEPENDENCIES</title>
- <p>The current crypto implementation uses nifs to interface OpenSSLs crypto library
- and requires <em>OpenSSL</em> package version 0.9.8 or higher.</p>
+ <p>The current crypto implementation uses nifs to interface
+ OpenSSLs crypto library and may work with limited functionality
+ with as old versions as <em>OpenSSL</em> 0.9.8c.
+ FIPS mode support requires at least
+ version 1.0.1 and a FIPS capable OpenSSL installation. We recommend using a
+ version that is officially supported by the OpenSSL project. API compatible backends like
+ LibreSSL should also work.</p>
+
<p>Source releases of OpenSSL can be downloaded from the <url href="http://www.openssl.org">OpenSSL</url> project home page,
or mirror sites listed there.
</p>
</section>
<section>
+ <title>CONFIGURATION</title>
+ <p>The following configuration parameters are defined for the
+ crypto application. See <c>app(3)</c> for more information about
+ configuration parameters.</p>
+ <taglist>
+ <tag><c>fips_mode = boolean()</c></tag>
+ <item>
+ <p>Specifies whether to run crypto in FIPS mode. This setting
+ will take effect when the nif module is loaded. If FIPS mode
+ is requested but not available at run time the nif module and
+ thus the crypto module will fail to load. This mechanism
+ prevents the accidental use of non-validated algorithms.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
<title>SEE ALSO</title>
<p>application(3)</p>
</section>
diff --git a/lib/crypto/doc/src/fips.xml b/lib/crypto/doc/src/fips.xml
new file mode 100644
index 0000000000..3e5c2db1e0
--- /dev/null
+++ b/lib/crypto/doc/src/fips.xml
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2014</year><year>2017</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>FIPS mode</title>
+ <prepared>D&aacute;niel Szoboszlay</prepared>
+ <docno></docno>
+ <date>2014-05-12</date>
+ <rev>A</rev>
+ <file>fips.xml</file>
+ </header>
+ <p>
+ <marker id="fips"></marker>
+ This chapter describes FIPS mode support in the crypto application.
+ </p>
+
+ <section>
+ <title>Background</title>
+ <p>OpenSSL can be built to provide FIPS 140-2 validated
+ cryptographic services. It is not the OpenSSL application that is
+ validated, but a special software component called the OpenSSL
+ FIPS Object Module. However applications do not use this Object
+ Module directly, but through the regular API of the OpenSSL
+ library.</p>
+ <p>The crypto application supports using OpenSSL in FIPS mode. In
+ this scenario only the validated algorithms provided by the Object
+ Module are accessible, other algorithms usually available in
+ OpenSSL (like md5) or implemented in the Erlang code (like SRP)
+ are disabled.</p>
+ </section>
+
+ <section>
+ <title>Enabling FIPS mode</title>
+ <list type="ordered">
+ <item>
+ <p>Build or install the FIPS Object Module and a FIPS enabled
+ OpenSSL library.</p>
+ <p>You should read and precisely follow the instructions of
+ the <url
+ href="http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf">Security
+ Policy</url> and <url
+ href="https://www.openssl.org/docs/fips/UserGuide-2.0.pdf">User
+ Guide</url>.</p>
+ <warning><p>It is very easy to build a working OpenSSL FIPS
+ Object Module and library from the source. However it <em>does
+ not</em> qualify as FIPS 140-2 validated if the numerous
+ restrictions in the Security Policy are not properly
+ followed.</p></warning>
+ </item>
+ <item>
+ <p>Configure and build Erlang/OTP with FIPS support:</p>
+ <pre>
+$ <input>cd $ERL_TOP</input>
+$ <input>./otp_build configure --enable-fips</input>
+...
+checking for FIPS_mode_set... yes
+...
+$ <input>make</input>
+ </pre>
+ <p>If <c>FIPS_mode_set</c> returns <c>no</c> the OpenSSL
+ library is not FIPS enabled and crypto won't support FIPS mode
+ either.</p>
+ </item>
+ <item>
+ <p>Set the <c>fips_mode</c> configuration setting of the
+ crypto application to <c>true</c> <em>before loading the
+ crypto module</em>.</p>
+ <p>The best place is in the <c>sys.config</c> system
+ configuration file of the release.</p>
+ </item>
+ <item>
+ Start and use the crypto application as usual. However take
+ care to avoid the non-FIPS validated algorithms, they will all
+ throw exception <c>not_supported</c>.
+ </item>
+ </list>
+ <p>Entering and leaving FIPS mode on a node already running crypto
+ is not supported. The reason is that OpenSSL is designed to
+ prevent an application requesting FIPS mode to end up accidentally
+ running in non-FIPS mode. If entering FIPS mode fails (e.g. the
+ Object Module is not found or is compromised) any subsequent use
+ of the OpenSSL API would terminate the emulator.</p>
+ <p>An on-the-fly FIPS mode change would thus have to be performed
+ in a critical section protected from any concurrently running
+ crypto operations. Furthermore in case of failure all crypto calls
+ would have to be disabled from the Erlang or nif code. This would
+ be too much effort put into this not too important feature.</p>
+ </section>
+
+ <section>
+ <title>Incompatibilities with regular builds</title>
+ <p>The Erlang API of the crypto application is identical
+ regardless of building with or without FIPS support. However the
+ nif code internally uses a different OpenSSL API.</p>
+ <p>This means that the context (an opaque type) returned from
+ streaming crypto functions (<c>hash_(init|update|final)</c>,
+ <c>hmac_(init|update|final)</c> and
+ <c>stream_(init|encrypt|decrypt)</c>) is different and
+ incompatible with regular builds when compiling crypto with FIPS
+ support.</p>
+ </section>
+
+ <section>
+ <title>Common caveats</title>
+ <p>In FIPS mode non-validated algorithms are disabled. This may
+ cause some unexpected problems in application relying on
+ crypto.</p>
+ <warning><p>Do not try to work around these problems by using
+ alternative implementations of the missing algorithms! An
+ application can only claim to be using a FIPS 140-2 validated
+ cryptographic module if it uses it exclusively for every
+ cryptographic operation.</p></warning>
+
+ <section>
+ <title>Restrictions on key sizes</title>
+ <p>Although public key algorithms are supported in FIPS mode
+ they can only be used with secure key sizes. The Security Policy
+ requires the following minimum values:
+ </p>
+ <taglist>
+ <tag>RSA</tag><item>1024 bit</item>
+ <tag>DSS</tag><item>1024 bit</item>
+ <tag>EC algorithms</tag><item>160 bit</item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>Restrictions on elliptic curves</title>
+ <p>The Erlang API allows using arbitrary curve parameters, but
+ in FIPS mode only those allowed by the Security Policy shall be
+ used.</p>
+ </section>
+
+ <section>
+ <title>Avoid md5 for hashing</title>
+ <p>Md5 is a popular choice as a hash function, but it is not
+ secure enough to be validated. Try to use sha instead wherever
+ possible.</p>
+ <p>For exceptional, non-cryptographic use cases one may consider
+ switching to <c>erlang:md5/1</c> as well.</p>
+ </section>
+
+ <section>
+ <title>Certificates and encrypted keys</title>
+ <p>As md5 is not available in FIPS mode it is only possible to
+ use certificates that were signed using sha hashing. When
+ validating an entire certificate chain all certificates
+ (including the root CA's) must comply with this rule.</p>
+ <p>For similar dependency on the md5 and des algorithms most
+ encrypted private keys in PEM format do not work
+ either. However, the PBES2 encryption scheme allows the use of
+ stronger FIPS verified algorithms which is a viable
+ alternative.</p>
+ </section>
+
+ <section>
+ <title>SNMP v3 limitations</title>
+ <p>It is only possible to use <c>usmHMACSHAAuthProtocol</c> and
+ <c>usmAesCfb128Protocol</c> for authentication and privacy
+ respectively in FIPS mode. The snmp application however won't
+ restrict selecting disabled protocols in any way, and using them
+ would result in run time crashes.</p>
+ </section>
+
+ <section>
+ <title>TLS 1.2 is required</title>
+ <p>All SSL and TLS versions prior to TLS 1.2 use a combination
+ of md5 and sha1 hashes in the handshake for various purposes:</p>
+ <list>
+ <item>Authenticating the integrity of the handshake
+ messages.</item>
+ <item>In the exchange of DH parameters in cipher suites
+ providing non-anonymous PFS (perfect forward secrecy).</item>
+ <item>In the PRF (pseud-random function) to generate keying
+ materials in cipher suites not using PFS.</item>
+ </list>
+ <p>OpenSSL handles these corner cases in FIPS mode, however the
+ Erlang crypto and ssl applications are not prepared for them and
+ therefore you are limited to TLS 1.2 in FIPS mode.</p>
+ <p>On the other hand it worth mentioning that at least all
+ cipher suites that would rely on non-validated algorithms are
+ automatically disabled in FIPS mode.</p>
+ <note><p>Certificates using weak (md5) digests may also cause
+ problems in TLS. Although TLS 1.2 has an extension for
+ specifying which type of signatures are accepted, and in FIPS
+ mode the ssl application will use it properly, most TLS
+ implementations ignore this extension and simply send whatever
+ certificates they were configured with.</p></note>
+ </section>
+
+ </section>
+</chapter>
diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml
index 7d3a85326f..574353ce7a 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2016</year>
+ <year>1999</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,234 @@
</header>
<p>This document describes the changes made to the Crypto application.</p>
+<section><title>Crypto 4.0</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ LibreSSL can now be used by the modernized crypto app.</p>
+ <p>
+ Own Id: OTP-14247</p>
+ </item>
+ <item>
+ <p>
+ Add compile option <c>-compile(no_native)</c> in modules
+ with <c>on_load</c> directive which is not yet supported
+ by HiPE.</p>
+ <p>
+ Own Id: OTP-14316 Aux Id: PR-1390 </p>
+ </item>
+ <item>
+ <p>
+ Fix a bug in aes cfb128 function introduced by the bug
+ fix in GitHub pull request <url
+ href="https://github.com/erlang/otp/pull/1393">#1393</url>.</p>
+ <p>
+ Own Id: OTP-14435 Aux Id: PR-1462, PR-1393, OTP-14313 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add basic support for CMAC</p>
+ <p>
+ Own Id: OTP-13779 Aux Id: ERL-82 PR-1138 </p>
+ </item>
+ <item>
+ <p>
+ Removed functions deprecated in crypto-3.0 first released
+ in OTP-R16B01</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-13873</p>
+ </item>
+ <item>
+ <p>
+ The <c>crypto</c> application now supports OpenSSL 1.1.</p>
+ <p>
+ Own Id: OTP-13900</p>
+ </item>
+ <item>
+ <p>
+ Allow Erlang/OTP to use OpenSSL in FIPS-140 mode, in
+ order to satisfy specific security requirements (mostly
+ by different parts of the US federal government). </p>
+ <p>
+ See the new crypto users guide "FIPS mode" chapter about
+ building and using the FIPS support which is disabled by
+ default.</p>
+ <p>
+ (Thanks to dszoboszlay and legoscia)</p>
+ <p>
+ Own Id: OTP-13921 Aux Id: PR-1180 </p>
+ </item>
+ <item>
+ <p>
+ Crypto chacha20-poly1305 as in RFC 7539 enabled for
+ OpenSSL >= 1.1.</p>
+ <p>
+ Thanks to mururu.</p>
+ <p>
+ Own Id: OTP-14092 Aux Id: PR-1291 </p>
+ </item>
+ <item>
+ <p>
+ RSA key generation added to <c>crypto:generate_key/2</c>.
+ Thanks to wiml.</p>
+ <p>
+ An interface is also added to
+ <c>public_key:generate_key/1</c>.</p>
+ <p>
+ Own Id: OTP-14140 Aux Id: ERL-165, PR-1299 </p>
+ </item>
+ <item>
+ <p>
+ Raised minimum requirement for OpenSSL version to
+ OpenSSL-0.9.8.c although we recommend a much higher
+ version, that is a version that is still maintained
+ officially by the OpenSSL project. Note that using such
+ an old version may restrict the crypto algorithms
+ supported.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14171</p>
+ </item>
+ <item>
+ <p>
+ Deprecate crypto:rand_uniform/2 as it is not
+ cryptographically strong</p>
+ <p>
+ Own Id: OTP-14274</p>
+ </item>
+ <item>
+ <p>
+ The Crypto application now supports generation of
+ cryptographically strong random numbers (floats &lt; 1.0
+ and integer arbitrary ranges) as a plugin to the 'rand'
+ module.</p>
+ <p>
+ Own Id: OTP-14317 Aux Id: PR-1372 </p>
+ </item>
+ <item>
+ <p>
+ This replaces the hard coded test values for AES, CMAC
+ and GCM ciphers with the full validation set from NIST's
+ CAVP program.</p>
+ <p>
+ Own Id: OTP-14436 Aux Id: PR-1396 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Crypto 3.7.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix a bug with AES CFB 128 for 192 and 256 bit keys.
+ Thanks to kellymclaughlin !</p>
+ <p>
+ Own Id: OTP-14313 Aux Id: PR-1393 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Crypto 3.7.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The implementation of the key exchange algorithms
+ diffie-hellman-group-exchange-sha* are optimized, up to a
+ factor of 11 for the slowest ( = biggest and safest)
+ group size.</p>
+ <p>
+ Own Id: OTP-14169 Aux Id: seq-13261 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Crypto 3.7.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The crypto application has been fixed to not use RC2
+ against OpenSSL built with RC2 disabled.</p>
+ <p>
+ Own Id: OTP-13895 Aux Id: PR-1163 </p>
+ </item>
+ <item>
+ <p>
+ The crypto application has been fixed to not use RC4
+ against OpenSSL built with RC4 disabled.</p>
+ <p>
+ Own Id: OTP-13896 Aux Id: PR-1169 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ To ease troubleshooting, <c>erlang:load_nif/2</c> now
+ includes the return value from a failed call to
+ load/reload/upgrade in the text part of the error tuple.
+ The <c>crypto</c> NIF makes use of this feature by
+ returning the source line where/if the initialization
+ fails.</p>
+ <p>
+ Own Id: OTP-13951</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Crypto 3.7.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Crypto has been fixed to work against OpenSSL versions
+ with disabled DES ciphers. Correct spelling of cipher
+ algorithm 'des3_cfb' has been introduced; the previous
+ misspeling still works.</p>
+ <p>
+ Own Id: OTP-13783 Aux Id: ERL-203 </p>
+ </item>
+ <item>
+ <p>
+ The size of an internal array in crypto has been fixed to
+ not segfault when having all possible ciphers. Bug fix by
+ Duncan Overbruck.</p>
+ <p>
+ Own Id: OTP-13789 Aux Id: PR-1140 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Crypto 3.7</title>
<section><title>Improvements and New Features</title>
@@ -815,7 +1043,7 @@
also been extended. </item><item> The <c>configure</c>
scripts of <c>erl_interface</c> and <c>odbc</c> now
search for thread libraries and thread library quirks the
- same way as <c>erts</c> do. </item><item> The
+ same way as ERTS do. </item><item> The
<c>configure</c> script of the <c>odbc</c> application
now also looks for odbc libraries in <c>lib64</c> and
<c>lib/64</c> directories when building on a 64-bit
diff --git a/lib/crypto/doc/src/usersguide.xml b/lib/crypto/doc/src/usersguide.xml
index fb088a8285..7971aefff4 100644
--- a/lib/crypto/doc/src/usersguide.xml
+++ b/lib/crypto/doc/src/usersguide.xml
@@ -47,5 +47,6 @@
</p>
</description>
<xi:include href="licenses.xml"/>
+ <xi:include href="fips.xml"/>
</part>
diff --git a/lib/crypto/src/Makefile b/lib/crypto/src/Makefile
index 456b8be64d..aea8a5a71c 100644
--- a/lib/crypto/src/Makefile
+++ b/lib/crypto/src/Makefile
@@ -56,7 +56,7 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_obsolete_guard -DCRYPTO_VSN=\"$(VSN)\" -Werror
+ERL_COMPILE_FLAGS += -DCRYPTO_VSN=\"$(VSN)\" -Werror
# ----------------------------------------------------
# Targets
diff --git a/lib/crypto/src/crypto.app.src b/lib/crypto/src/crypto.app.src
index 8a47b8a78b..1d3f35e465 100644
--- a/lib/crypto/src/crypto.app.src
+++ b/lib/crypto/src/crypto.app.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
crypto_ec_curves]},
{registered, []},
{applications, [kernel, stdlib]},
- {env, []},
- {runtime_dependencies, ["erts-6.0","stdlib-2.0","kernel-3.0"]}]}.
+ {env, [{fips_mode, false}]},
+ {runtime_dependencies, ["erts-9.0","stdlib-3.4","kernel-5.3"]}]}.
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 025d57e9c5..d111525214 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,12 +22,19 @@
-module(crypto).
--export([start/0, stop/0, info_lib/0, supports/0, version/0, bytes_to_integer/1]).
+-export([start/0, stop/0, info_lib/0, info_fips/0, supports/0, enable_fips_mode/1,
+ version/0, bytes_to_integer/1]).
-export([hash/2, hash_init/1, hash_update/2, hash_final/1]).
-export([sign/4, verify/5]).
-export([generate_key/2, generate_key/3, compute_key/4]).
-export([hmac/3, hmac/4, hmac_init/2, hmac_update/2, hmac_final/1, hmac_final_n/2]).
+-export([cmac/3, cmac/4]).
-export([exor/2, strong_rand_bytes/1, mod_pow/3]).
+-export([rand_seed/0]).
+-export([rand_seed_s/0]).
+-export([rand_plugin_next/1]).
+-export([rand_plugin_uniform/1]).
+-export([rand_plugin_uniform/2]).
-export([rand_uniform/2]).
-export([block_encrypt/3, block_decrypt/3, block_encrypt/4, block_decrypt/4]).
-export([next_iv/2, next_iv/3]).
@@ -38,146 +45,15 @@
-export([ec_curve/1, ec_curves/0]).
-export([rand_seed/1]).
-%% DEPRECATED
--export([rand_bytes/1]).
--deprecated({rand_bytes, 1, next_major_release}).
-
-%% Replaced by hash_*
--export([md4/1, md4_init/0, md4_update/2, md4_final/1]).
--export([md5/1, md5_init/0, md5_update/2, md5_final/1]).
--export([sha/1, sha_init/0, sha_update/2, sha_final/1]).
--deprecated({md4, 1, next_major_release}).
--deprecated({md5, 1, next_major_release}).
--deprecated({sha, 1, next_major_release}).
--deprecated({md4_init, 0, next_major_release}).
--deprecated({md5_init, 0, next_major_release}).
--deprecated({sha_init, 0, next_major_release}).
--deprecated({md4_update, 2, next_major_release}).
--deprecated({md5_update, 2, next_major_release}).
--deprecated({sha_update, 2, next_major_release}).
--deprecated({md4_final, 1, next_major_release}).
--deprecated({md5_final, 1, next_major_release}).
--deprecated({sha_final, 1, next_major_release}).
-
-%% Replaced by hmac_*
--export([md5_mac/2, md5_mac_96/2, sha_mac/2, sha_mac/3, sha_mac_96/2]).
--deprecated({md5_mac, 2, next_major_release}).
--deprecated({md5_mac_96, 2, next_major_release}).
--deprecated({sha_mac, 2, next_major_release}).
--deprecated({sha_mac, 3, next_major_release}).
--deprecated({sha_mac_96, 2, next_major_release}).
-
-%% Replaced by sign/verify
--export([dss_verify/3, dss_verify/4, rsa_verify/3, rsa_verify/4]).
--export([dss_sign/2, dss_sign/3, rsa_sign/2, rsa_sign/3]).
--deprecated({dss_verify, 3, next_major_release}).
--deprecated({dss_verify, 4, next_major_release}).
--deprecated({rsa_verify, 3, next_major_release}).
--deprecated({rsa_verify, 4, next_major_release}).
--deprecated({dss_sign, 2, next_major_release}).
--deprecated({dss_sign, 3, next_major_release}).
--deprecated({rsa_sign, 2, next_major_release}).
--deprecated({rsa_sign, 3, next_major_release}).
-
-%% Replaced by generate_key
--export([dh_generate_key/1, dh_generate_key/2, dh_compute_key/3]).
--deprecated({dh_generate_key, 1, next_major_release}).
--deprecated({dh_generate_key, 2, next_major_release}).
--deprecated({dh_compute_key, 3, next_major_release}).
-
-%% Replaced by mod_exp_prim and no longer needed
--export([mod_exp/3, mpint/1, erlint/1, strong_rand_mpint/3]).
--deprecated({mod_exp, 3, next_major_release}).
--deprecated({mpint, 1, next_major_release}).
--deprecated({erlint, 1, next_major_release}).
--deprecated({strong_rand_mpint, 3, next_major_release}).
-
-%% Replaced by block_*
--export([des_cbc_encrypt/3, des_cbc_decrypt/3, des_cbc_ivec/1]).
--export([des3_cbc_encrypt/5, des3_cbc_decrypt/5]).
--export([des_ecb_encrypt/2, des_ecb_decrypt/2]).
--export([des_ede3_cbc_encrypt/5, des_ede3_cbc_decrypt/5]).
--export([des_cfb_encrypt/3, des_cfb_decrypt/3, des_cfb_ivec/2]).
--export([des3_cfb_encrypt/5, des3_cfb_decrypt/5]).
--deprecated({des_cbc_encrypt, 3, next_major_release}).
--deprecated({des_cbc_decrypt, 3, next_major_release}).
--deprecated({des_cbc_ivec, 1, next_major_release}).
--deprecated({des3_cbc_encrypt, 5, next_major_release}).
--deprecated({des3_cbc_decrypt, 5, next_major_release}).
--deprecated({des_ecb_encrypt, 2, next_major_release}).
--deprecated({des_ecb_decrypt, 2, next_major_release}).
--deprecated({des_ede3_cbc_encrypt, 5, next_major_release}).
--deprecated({des_ede3_cbc_decrypt, 5, next_major_release}).
--deprecated({des_cfb_encrypt, 3, next_major_release}).
--deprecated({des_cfb_decrypt, 3, next_major_release}).
--deprecated({des_cfb_ivec, 2, next_major_release}).
--deprecated({des3_cfb_encrypt, 5, next_major_release}).
--deprecated({des3_cfb_decrypt, 5, next_major_release}).
--export([blowfish_ecb_encrypt/2, blowfish_ecb_decrypt/2]).
--export([blowfish_cbc_encrypt/3, blowfish_cbc_decrypt/3]).
--export([blowfish_cfb64_encrypt/3, blowfish_cfb64_decrypt/3]).
--export([blowfish_ofb64_encrypt/3]).
--deprecated({blowfish_ecb_encrypt, 2, next_major_release}).
--deprecated({blowfish_ecb_decrypt, 2, next_major_release}).
--deprecated({blowfish_cbc_encrypt, 3, next_major_release}).
--deprecated({blowfish_cbc_decrypt, 3, next_major_release}).
--deprecated({blowfish_cfb64_encrypt, 3, next_major_release}).
--deprecated({blowfish_cfb64_decrypt, 3, next_major_release}).
--deprecated({blowfish_ofb64_encrypt, 3, next_major_release}).
--export([aes_cfb_128_encrypt/3, aes_cfb_128_decrypt/3]).
--export([aes_cbc_128_encrypt/3, aes_cbc_128_decrypt/3]).
--export([aes_cbc_256_encrypt/3, aes_cbc_256_decrypt/3]).
--export([aes_cbc_ivec/1]).
--deprecated({aes_cfb_128_encrypt, 3, next_major_release}).
--deprecated({aes_cfb_128_decrypt, 3, next_major_release}).
--deprecated({aes_cbc_128_encrypt, 3, next_major_release}).
--deprecated({aes_cbc_128_decrypt, 3, next_major_release}).
--deprecated({aes_cbc_256_encrypt, 3, next_major_release}).
--deprecated({aes_cbc_256_decrypt, 3, next_major_release}).
--deprecated({aes_cbc_ivec, 1, next_major_release}).
--export([rc2_cbc_encrypt/3, rc2_cbc_decrypt/3]).
--export([rc2_40_cbc_encrypt/3, rc2_40_cbc_decrypt/3]).
--deprecated({rc2_cbc_encrypt, 3, next_major_release}).
--deprecated({rc2_cbc_decrypt, 3, next_major_release}).
-%% allready replaced by above!
--deprecated({rc2_40_cbc_encrypt, 3, next_major_release}).
--deprecated({rc2_40_cbc_decrypt, 3, next_major_release}).
-
-%% Replaced by stream_*
--export([aes_ctr_stream_init/2, aes_ctr_stream_encrypt/2, aes_ctr_stream_decrypt/2]).
--export([rc4_set_key/1, rc4_encrypt_with_state/2]).
--deprecated({aes_ctr_stream_init, 2, next_major_release}).
--deprecated({aes_ctr_stream_encrypt, 2, next_major_release}).
--deprecated({aes_ctr_stream_decrypt, 2, next_major_release}).
--deprecated({rc4_set_key, 1, next_major_release}).
--deprecated({rc4_encrypt_with_state, 2, next_major_release}).
-
-%% Not needed special case of stream_*
--export([aes_ctr_encrypt/3, aes_ctr_decrypt/3, rc4_encrypt/2]).
--deprecated({aes_ctr_encrypt, 3, next_major_release}).
--deprecated({aes_ctr_decrypt, 3, next_major_release}).
--deprecated({rc4_encrypt, 2, next_major_release}).
-
-%% Replace by public/private_encrypt/decrypt
--export([rsa_public_encrypt/3, rsa_private_decrypt/3]).
--export([rsa_private_encrypt/3, rsa_public_decrypt/3]).
--deprecated({rsa_public_encrypt, 3, next_major_release}).
--deprecated({rsa_private_decrypt, 3, next_major_release}).
--deprecated({rsa_public_decrypt, 3, next_major_release}).
--deprecated({rsa_private_encrypt, 3, next_major_release}).
-
-%% Replaced by crypto:module_info()
--export([info/0]).
--deprecated({info, 0, next_major_release}).
+-deprecated({rand_uniform, 2, next_major_release}).
%% This should correspond to the similar macro in crypto.c
-define(MAX_BYTES_TO_NIF, 20000). %% Current value is: erlang:system_info(context_reductions) * 10
--type mpint() :: binary().
--type rsa_digest_type() :: 'md5' | 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'.
--type dss_digest_type() :: 'none' | 'sha'.
+%% Used by strong_rand_float/0
+-define(HALF_DBL_EPSILON, 1.1102230246251565e-16). % math:pow(2, -53)
+
%%-type ecdsa_digest_type() :: 'md5' | 'sha' | 'sha256' | 'sha384' | 'sha512'.
--type data_or_digest() :: binary() | {digest, binary()}.
-type crypto_integer() :: binary() | integer().
%%-type ec_named_curve() :: atom().
%%-type ec_point() :: crypto_integer().
@@ -188,8 +64,9 @@
%%-type ec_curve() :: ec_named_curve() | ec_curve_spec().
%%-type ec_key() :: {Curve :: ec_curve(), PrivKey :: binary() | undefined, PubKey :: ec_point() | undefined}.
+-compile(no_native).
-on_load(on_load/0).
--define(CRYPTO_NIF_VSN,301).
+-define(CRYPTO_NIF_VSN,302).
-define(nif_stub,nif_stub_error(?LINE)).
nif_stub_error(Line) ->
@@ -219,6 +96,14 @@ supports()->
info_lib() -> ?nif_stub.
+-spec info_fips() -> not_supported | not_enabled | enabled.
+
+info_fips() -> ?nif_stub.
+
+-spec enable_fips_mode(boolean()) -> boolean().
+
+enable_fips_mode(_) -> ?nif_stub.
+
-spec hash(_, iodata()) -> binary().
hash(Hash, Data0) ->
@@ -271,16 +156,25 @@ hmac_final(Context) ->
hmac_final_n(Context, HashLen) ->
notsup_to_error(hmac_final_nif(Context, HashLen)).
+-spec cmac(_, iodata(), iodata()) -> binary().
+-spec cmac(_, iodata(), iodata(), integer()) -> binary().
+
+cmac(Type, Key, Data) ->
+ notsup_to_error(cmac_nif(Type, Key, Data)).
+cmac(Type, Key, Data, MacSize) ->
+ erlang:binary_part(cmac(Type, Key, Data), 0, MacSize).
+
%% Ecrypt/decrypt %%%
-spec block_encrypt(des_cbc | des_cfb |
- des3_cbc | des3_cbf | des_ede3 |
+ des3_cbc | des3_cbf | des3_cfb | des_ede3 |
blowfish_cbc | blowfish_cfb64 | blowfish_ofb64 |
aes_cbc128 | aes_cfb8 | aes_cfb128 | aes_cbc256 | aes_ige256 |
- aes_cbc |
+ aes_cbc |
rc2_cbc,
- Key::iodata(), Ivec::binary(), Data::iodata()) -> binary();
- (aes_gcm | chacha20_poly1305, Key::iodata(), Ivec::binary(), {AAD::binary(), Data::iodata()}) -> {binary(), binary()}.
+ Key::iodata(), Ivec::binary(), Data::iodata()) -> binary();
+ (aes_gcm | chacha20_poly1305, Key::iodata(), Ivec::binary(), {AAD::binary(), Data::iodata()}) -> {binary(), binary()};
+ (aes_gcm, Key::iodata(), Ivec::binary(), {AAD::binary(), Data::iodata(), TagLength::1..16}) -> {binary(), binary()}.
block_encrypt(Type, Key, Ivec, Data) when Type =:= des_cbc;
Type =:= des_cfb;
@@ -301,8 +195,11 @@ block_encrypt(Type, Key0, Ivec, Data) when Type =:= des3_cbc;
block_encrypt(des3_cbf, Key0, Ivec, Data) ->
Key = check_des3_key(Key0),
block_crypt_nif(des_ede3_cbf, Key, Ivec, Data, true);
+block_encrypt(des3_cfb, Key0, Ivec, Data) ->
+ Key = check_des3_key(Key0),
+ block_crypt_nif(des_ede3_cfb, Key, Ivec, Data, true);
block_encrypt(aes_ige256, Key, Ivec, Data) ->
- aes_ige_crypt_nif(Key, Ivec, Data, true);
+ notsup_to_error(aes_ige_crypt_nif(Key, Ivec, Data, true));
block_encrypt(aes_gcm, Key, Ivec, {AAD, Data}) ->
aes_gcm_encrypt(Key, Ivec, AAD, Data);
block_encrypt(aes_gcm, Key, Ivec, {AAD, Data, TagLength}) ->
@@ -311,7 +208,7 @@ block_encrypt(chacha20_poly1305, Key, Ivec, {AAD, Data}) ->
chacha20_poly1305_encrypt(Key, Ivec, AAD, Data).
-spec block_decrypt(des_cbc | des_cfb |
- des3_cbc | des3_cbf | des_ede3 |
+ des3_cbc | des3_cbf | des3_cfb | des_ede3 |
blowfish_cbc | blowfish_cfb64 | blowfish_ofb64 |
aes_cbc128 | aes_cfb8 | aes_cfb128 | aes_cbc256 | aes_ige256 |
aes_cbc |
@@ -338,6 +235,9 @@ block_decrypt(Type, Key0, Ivec, Data) when Type =:= des3_cbc;
block_decrypt(des3_cbf, Key0, Ivec, Data) ->
Key = check_des3_key(Key0),
block_crypt_nif(des_ede3_cbf, Key, Ivec, Data, false);
+block_decrypt(des3_cfb, Key0, Ivec, Data) ->
+ Key = check_des3_key(Key0),
+ block_crypt_nif(des_ede3_cfb, Key, Ivec, Data, false);
block_decrypt(aes_ige256, Key, Ivec, Data) ->
notsup_to_error(aes_ige_crypt_nif(Key, Ivec, Data, false));
block_decrypt(aes_gcm, Key, Ivec, {AAD, Data, Tag}) ->
@@ -394,15 +294,14 @@ stream_decrypt(State, Data0) ->
stream_crypt(fun do_stream_decrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []).
%%
-%% RAND - pseudo random numbers using RN_ functions in crypto lib
+%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib
%%
--spec rand_bytes(non_neg_integer()) -> binary().
-spec strong_rand_bytes(non_neg_integer()) -> binary().
+-spec rand_seed() -> rand:state().
+-spec rand_seed_s() -> rand:state().
-spec rand_uniform(crypto_integer(), crypto_integer()) ->
crypto_integer().
-rand_bytes(_Bytes) -> ?nif_stub.
-
strong_rand_bytes(Bytes) ->
case strong_rand_bytes_nif(Bytes) of
false -> erlang:error(low_entropy);
@@ -411,6 +310,43 @@ strong_rand_bytes(Bytes) ->
strong_rand_bytes_nif(_Bytes) -> ?nif_stub.
+rand_seed() ->
+ rand:seed(rand_seed_s()).
+
+rand_seed_s() ->
+ {#{ type => ?MODULE,
+ bits => 64,
+ next => fun ?MODULE:rand_plugin_next/1,
+ uniform => fun ?MODULE:rand_plugin_uniform/1,
+ uniform_n => fun ?MODULE:rand_plugin_uniform/2},
+ no_seed}.
+
+rand_plugin_next(Seed) ->
+ {bytes_to_integer(strong_rand_range(1 bsl 64)), Seed}.
+
+rand_plugin_uniform(State) ->
+ {strong_rand_float(), State}.
+
+rand_plugin_uniform(Max, State) ->
+ {bytes_to_integer(strong_rand_range(Max)) + 1, State}.
+
+
+strong_rand_range(Range) when is_integer(Range), Range > 0 ->
+ BinRange = int_to_bin(Range),
+ strong_rand_range(BinRange);
+strong_rand_range(BinRange) when is_binary(BinRange) ->
+ case strong_rand_range_nif(BinRange) of
+ false ->
+ erlang:error(low_entropy);
+ <<BinResult/binary>> ->
+ BinResult
+ end.
+strong_rand_range_nif(_BinRange) -> ?nif_stub.
+
+strong_rand_float() ->
+ WholeRange = strong_rand_range(1 bsl 53),
+ ?HALF_DBL_EPSILON * bytes_to_integer(WholeRange).
+
rand_uniform(From,To) when is_binary(From), is_binary(To) ->
case rand_uniform_nif(From,To) of
<<Len:32/integer, MSB, Rest/binary>> when MSB > 127 ->
@@ -439,6 +375,7 @@ rand_uniform_pos(_,_) ->
rand_uniform_nif(_From,_To) -> ?nif_stub.
+
-spec rand_seed(binary()) -> ok.
rand_seed(Seed) ->
rand_seed_nif(Seed).
@@ -469,17 +406,17 @@ sign(Alg, Type, Data, Key) when is_binary(Data) ->
sign(Alg, Type, {digest, hash(Type, Data)}, Key);
sign(rsa, Type, {digest, Digest}, Key) ->
case rsa_sign_nif(Type, Digest, map_ensure_int_as_bin(Key)) of
- error -> erlang:error(badkey, [Type,Digest,Key]);
+ error -> erlang:error(badkey, [rsa, Type, {digest, Digest}, Key]);
Sign -> Sign
end;
sign(dss, Type, {digest, Digest}, Key) ->
case dss_sign_nif(Type, Digest, map_ensure_int_as_bin(Key)) of
- error -> erlang:error(badkey, [Digest, Key]);
+ error -> erlang:error(badkey, [dss, Type, {digest, Digest}, Key]);
Sign -> Sign
end;
sign(ecdsa, Type, {digest, Digest}, [Key, Curve]) ->
case ecdsa_sign_nif(Type, Digest, nif_curve_params(Curve), ensure_int_as_bin(Key)) of
- error -> erlang:error(badkey, [Type,Digest,Key]);
+ error -> erlang:error(badkey, [ecdsa, Type, {digest, Digest}, [Key, Curve]]);
Sign -> Sign
end.
@@ -495,7 +432,7 @@ sign(ecdsa, Type, {digest, Digest}, [Key, Curve]) ->
public_encrypt(rsa, BinMesg, Key, Padding) ->
case rsa_public_crypt(BinMesg, map_ensure_int_as_bin(Key), Padding, true) of
error ->
- erlang:error(encrypt_failed, [BinMesg,Key, Padding]);
+ erlang:error(encrypt_failed, [rsa, BinMesg,Key, Padding]);
Sign -> Sign
end.
@@ -503,7 +440,7 @@ public_encrypt(rsa, BinMesg, Key, Padding) ->
private_decrypt(rsa, BinMesg, Key, Padding) ->
case rsa_private_crypt(BinMesg, map_ensure_int_as_bin(Key), Padding, false) of
error ->
- erlang:error(decrypt_failed, [BinMesg,Key, Padding]);
+ erlang:error(decrypt_failed, [rsa, BinMesg,Key, Padding]);
Sign -> Sign
end.
@@ -512,7 +449,7 @@ private_decrypt(rsa, BinMesg, Key, Padding) ->
private_encrypt(rsa, BinMesg, Key, Padding) ->
case rsa_private_crypt(BinMesg, map_ensure_int_as_bin(Key), Padding, true) of
error ->
- erlang:error(encrypt_failed, [BinMesg,Key, Padding]);
+ erlang:error(encrypt_failed, [rsa, BinMesg,Key, Padding]);
Sign -> Sign
end.
@@ -520,7 +457,7 @@ private_encrypt(rsa, BinMesg, Key, Padding) ->
public_decrypt(rsa, BinMesg, Key, Padding) ->
case rsa_public_crypt(BinMesg, map_ensure_int_as_bin(Key), Padding, false) of
error ->
- erlang:error(decrypt_failed, [BinMesg,Key, Padding]);
+ erlang:error(decrypt_failed, [rsa, BinMesg,Key, Padding]);
Sign -> Sign
end.
@@ -540,9 +477,15 @@ exor(Bin1, Bin2) ->
generate_key(Type, Params) ->
generate_key(Type, Params, undefined).
-generate_key(dh, DHParameters, PrivateKey) ->
+generate_key(dh, DHParameters0, PrivateKey) ->
+ {DHParameters, Len} =
+ case DHParameters0 of
+ [P,G,L] -> {[P,G], L};
+ [P,G] -> {[P,G], 0}
+ end,
dh_generate_key_nif(ensure_int_as_bin(PrivateKey),
- map_ensure_int_as_bin(DHParameters), 0);
+ map_ensure_int_as_bin(DHParameters),
+ 0, Len);
generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, PrivArg)
when is_binary(Verifier), is_binary(Generator), is_binary(Prime), is_atom(Version) ->
@@ -560,6 +503,15 @@ generate_key(srp, {user, [Generator, Prime, Version]}, PrivateArg)
end,
user_srp_gen_key(Private, Generator, Prime);
+generate_key(rsa, {ModulusSize, PublicExponent}, undefined) ->
+ case rsa_generate_key_nif(ModulusSize, ensure_int_as_bin(PublicExponent)) of
+ error ->
+ erlang:error(computation_failed,
+ [rsa,{ModulusSize,PublicExponent}]);
+ Private ->
+ {lists:sublist(Private, 2), Private}
+ end;
+
generate_key(ecdh, Curve, PrivKey) ->
ec_key_generate(nif_curve_params(Curve), ensure_int_as_bin(PrivKey)).
@@ -568,7 +520,7 @@ compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) ->
ensure_int_as_bin(MyPrivateKey),
map_ensure_int_as_bin(DHParameters)) of
error -> erlang:error(computation_failed,
- [OthersPublicKey,MyPrivateKey,DHParameters]);
+ [dh,OthersPublicKey,MyPrivateKey,DHParameters]);
Ret -> Ret
end;
@@ -636,7 +588,8 @@ on_load() ->
end,
Lib = filename:join([PrivDir, "lib", LibName]),
LibBin = path2bin(Lib),
- Status = case erlang:load_nif(Lib, {?CRYPTO_NIF_VSN,LibBin}) of
+ FipsMode = application:get_env(crypto, fips_mode, false) == true,
+ Status = case erlang:load_nif(Lib, {?CRYPTO_NIF_VSN,LibBin,FipsMode}) of
ok -> ok;
{error, {load_failed, _}}=Error1 ->
ArchLibDir =
@@ -649,7 +602,7 @@ on_load() ->
_ ->
ArchLib = filename:join([ArchLibDir, LibName]),
ArchBin = path2bin(ArchLib),
- erlang:load_nif(ArchLib, {?CRYPTO_NIF_VSN,ArchBin})
+ erlang:load_nif(ArchLib, {?CRYPTO_NIF_VSN,ArchBin,FipsMode})
end;
Error1 -> Error1
end,
@@ -669,7 +622,7 @@ path2bin(Path) when is_list(Path) ->
end.
%%--------------------------------------------------------------------
-%%% Internal functions (some internal API functions are part of the deprecated API)
+%%% Internal functions
%%--------------------------------------------------------------------
max_bytes() ->
?MAX_BYTES_TO_NIF.
@@ -699,59 +652,6 @@ hash_init_nif(_Hash) -> ?nif_stub.
hash_update_nif(_State, _Data) -> ?nif_stub.
hash_final_nif(_State) -> ?nif_stub.
-
-%%
-%% MD5
-%%
-
--spec md5(iodata()) -> binary().
--spec md5_init() -> binary().
--spec md5_update(binary(), iodata()) -> binary().
--spec md5_final(binary()) -> binary().
-
-md5(Data) ->
- hash(md5, Data).
-md5_init() ->
- hash_init(md5).
-md5_update(Context, Data) ->
- hash_update(Context, Data).
-md5_final(Context) ->
- hash_final(Context).
-
-%%
-%% MD4
-%%
--spec md4(iodata()) -> binary().
--spec md4_init() -> binary().
--spec md4_update(binary(), iodata()) -> binary().
--spec md4_final(binary()) -> binary().
-
-md4(Data) ->
- hash(md4, Data).
-md4_init() ->
- hash_init(md4).
-md4_update(Context, Data) ->
- hash_update(Context, Data).
-md4_final(Context) ->
- hash_final(Context).
-
-%%
-%% SHA
-%%
--spec sha(iodata()) -> binary().
--spec sha_init() -> binary().
--spec sha_update(binary(), iodata()) -> binary().
--spec sha_final(binary()) -> binary().
-
-sha(Data) ->
- hash(sha, Data).
-sha_init() ->
- hash_init(sha).
-sha_update(Context, Data) ->
- hash_update(Context, Data).
-sha_final(Context) ->
- hash_final(Context).
-
%% HMAC --------------------------------------------------------------------
hmac(Type, Key, Data, MacSize, Size, MaxBytes) when Size =< MaxBytes ->
@@ -782,27 +682,9 @@ hmac_update_nif(_Context, _Data) -> ?nif_stub.
hmac_final_nif(_Context) -> ?nif_stub.
hmac_final_nif(_Context, _MacSize) -> ?nif_stub.
-%%
-%% MD5_MAC
-%%
--spec md5_mac(iodata(), iodata()) -> binary().
--spec md5_mac_96(iodata(), iodata()) -> binary().
-
-md5_mac(Key, Data) -> hmac(md5, Key, Data).
-
-md5_mac_96(Key, Data) -> hmac(md5, Key, Data, 12).
-
-%%
-%% SHA_MAC
-%%
--spec sha_mac(iodata(), iodata()) -> binary().
--spec sha_mac_96(iodata(), iodata()) -> binary().
-
-sha_mac(Key, Data) -> hmac(sha, Key, Data).
-
-sha_mac(Key, Data, Size) -> hmac(sha, Key, Data, Size).
+%% CMAC
-sha_mac_96(Key, Data) -> hmac(sha, Key, Data, 12).
+cmac_nif(_Type, _Key, _Data) -> ?nif_stub.
%% CIPHERS --------------------------------------------------------------------
@@ -820,94 +702,6 @@ check_des3_key(Key) ->
end.
%%
-%% DES - in electronic codebook mode (ECB)
-%%
--spec des_ecb_encrypt(iodata(), iodata()) -> binary().
--spec des_ecb_decrypt(iodata(), iodata()) -> binary().
-
-des_ecb_encrypt(Key, Data) ->
- block_encrypt(des_ecb, Key, Data).
-des_ecb_decrypt(Key, Data) ->
- block_decrypt(des_ecb, Key, Data).
-
-%%
-%% DES3 - in cipher block chaining mode (CBC)
-%%
--spec des3_cbc_encrypt(iodata(), iodata(), iodata(), binary(), iodata()) ->
- binary().
--spec des3_cbc_decrypt(iodata(), iodata(), iodata(), binary(), iodata()) ->
- binary().
-
-des3_cbc_encrypt(Key1, Key2, Key3, IVec, Data) ->
- block_encrypt(des3_cbc, [Key1, Key2, Key3], IVec, Data).
-des_ede3_cbc_encrypt(Key1, Key2, Key3, IVec, Data) ->
- block_encrypt(des_ede3, [Key1, Key2, Key3], IVec, Data).
-
-des3_cbc_decrypt(Key1, Key2, Key3, IVec, Data) ->
- block_decrypt(des3_cbc, [Key1, Key2, Key3], IVec, Data).
-des_ede3_cbc_decrypt(Key1, Key2, Key3, IVec, Data) ->
- block_decrypt(des_ede3, [Key1, Key2, Key3], IVec, Data).
-
-%%
-%% DES3 - in 8-bits cipher feedback mode (CFB)
-%%
--spec des3_cfb_encrypt(iodata(), iodata(), iodata(), binary(), iodata()) ->
- binary().
--spec des3_cfb_decrypt(iodata(), iodata(), iodata(), binary(), iodata()) ->
- binary().
-
-des3_cfb_encrypt(Key1, Key2, Key3, IVec, Data) ->
- block_encrypt(des3_cbf, [Key1, Key2, Key3], IVec, Data).
-
-des3_cfb_decrypt(Key1, Key2, Key3, IVec, Data) ->
- block_decrypt(des3_cbf, [Key1, Key2, Key3], IVec, Data).
-
-%%
-%% Blowfish
-%%
--spec blowfish_ecb_encrypt(iodata(), iodata()) -> binary().
--spec blowfish_ecb_decrypt(iodata(), iodata()) -> binary().
--spec blowfish_cbc_encrypt(iodata(), binary(), iodata()) -> binary().
--spec blowfish_cbc_decrypt(iodata(), binary(), iodata()) -> binary().
--spec blowfish_cfb64_encrypt(iodata(), binary(), iodata()) -> binary().
--spec blowfish_cfb64_decrypt(iodata(), binary(), iodata()) -> binary().
--spec blowfish_ofb64_encrypt(iodata(), binary(), iodata()) -> binary().
-
-blowfish_ecb_encrypt(Key, Data) ->
- block_encrypt(blowfish_ecb, Key, Data).
-
-blowfish_ecb_decrypt(Key, Data) ->
- block_decrypt(blowfish_ecb, Key, Data).
-
-blowfish_cbc_encrypt(Key, IVec, Data) ->
- block_encrypt(blowfish_cbc, Key, IVec, Data).
-
-blowfish_cbc_decrypt(Key, IVec, Data) ->
- block_decrypt(blowfish_cbc, Key, IVec, Data).
-
-blowfish_cfb64_encrypt(Key, IVec, Data) ->
- block_encrypt(blowfish_cfb64, Key, IVec, Data).
-
-blowfish_cfb64_decrypt(Key, IVec, Data) ->
- block_decrypt(blowfish_cfb64, Key, IVec, Data).
-
-blowfish_ofb64_encrypt(Key, IVec, Data) ->
- block_encrypt(blowfish_ofb64, Key, IVec, Data).
-
-
-%%
-%% AES in cipher feedback mode (CFB) - 128 bit shift
-%%
--spec aes_cfb_128_encrypt(iodata(), binary(), iodata()) -> binary().
--spec aes_cfb_128_decrypt(iodata(), binary(), iodata()) -> binary().
-
-aes_cfb_128_encrypt(Key, IVec, Data) ->
- block_encrypt(aes_cfb128, Key, IVec, Data).
-
-aes_cfb_128_decrypt(Key, IVec, Data) ->
- block_decrypt(aes_cfb128, Key, IVec, Data).
-
-%%
%% AES - in Galois/Counter Mode (GCM)
%%
%% The default tag length is EVP_GCM_TLS_TAG_LEN(16),
@@ -923,88 +717,6 @@ chacha20_poly1305_encrypt(_Key, _Ivec, _AAD, _In) -> ?nif_stub.
chacha20_poly1305_decrypt(_Key, _Ivec, _AAD, _In, _Tag) -> ?nif_stub.
%%
-%% DES - in cipher block chaining mode (CBC)
-%%
--spec des_cbc_encrypt(iodata(), binary(), iodata()) -> binary().
--spec des_cbc_decrypt(iodata(), binary(), iodata()) -> binary().
-
-des_cbc_encrypt(Key, IVec, Data) ->
- block_encrypt(des_cbc, Key, IVec, Data).
-
-des_cbc_decrypt(Key, IVec, Data) ->
- block_decrypt(des_cbc, Key, IVec, Data).
-
-%%
-%% dec_cbc_ivec(Data) -> binary()
-%%
-%% Returns the IVec to be used in the next iteration of
-%% des_cbc_[encrypt|decrypt].
-%%
--spec des_cbc_ivec(iodata()) -> binary().
-
-des_cbc_ivec(Data) ->
- next_iv(des_cbc, Data).
-
-%%
-%% DES - in 8-bits cipher feedback mode (CFB)
-%%
--spec des_cfb_encrypt(iodata(), binary(), iodata()) -> binary().
--spec des_cfb_decrypt(iodata(), binary(), iodata()) -> binary().
-
-des_cfb_encrypt(Key, IVec, Data) ->
- block_encrypt(des_cfb, Key, IVec, Data).
-
-des_cfb_decrypt(Key, IVec, Data) ->
- block_decrypt(des_cfb, Key, IVec, Data).
-
-%%
-%% dec_cfb_ivec(IVec, Data) -> binary()
-%%
-%% Returns the IVec to be used in the next iteration of
-%% des_cfb_[encrypt|decrypt].
-%%
-
--spec des_cfb_ivec(iodata(), iodata()) -> binary().
-
-des_cfb_ivec(IVec, Data) ->
- next_iv(des_cfb, Data, IVec).
-
-
-%%
-%% AES - with 128 or 256 bit key in cipher block chaining mode (CBC)
-%%
--spec aes_cbc_128_encrypt(iodata(), binary(), iodata()) ->
- binary().
--spec aes_cbc_128_decrypt(iodata(), binary(), iodata()) ->
- binary().
--spec aes_cbc_256_encrypt(iodata(), binary(), iodata()) ->
- binary().
--spec aes_cbc_256_decrypt(iodata(), binary(), iodata()) ->
- binary().
-
-aes_cbc_128_encrypt(Key, IVec, Data) ->
- block_encrypt(aes_cbc128, Key, IVec, Data).
-
-aes_cbc_128_decrypt(Key, IVec, Data) ->
- block_decrypt(aes_cbc128, Key, IVec, Data).
-
-aes_cbc_256_encrypt(Key, IVec, Data) ->
- block_encrypt(aes_cbc256, Key, IVec, Data).
-
-aes_cbc_256_decrypt(Key, IVec, Data) ->
- block_decrypt(aes_cbc256, Key, IVec, Data).
-
-%%
-%% aes_cbc_ivec(Data) -> binary()
-%%
-%% Returns the IVec to be used in the next iteration of
-%% aes_cbc_*_[encrypt|decrypt].
-%% IVec size: 16 bytes
-%%
-aes_cbc_ivec(Data) ->
- next_iv(aes_cbc, Data).
-
-%%
%% AES - with 256 bit key in infinite garble extension mode (IGE)
%%
@@ -1037,17 +749,6 @@ do_stream_decrypt({rc4, State0}, Data) ->
{State, Text} = rc4_encrypt_with_state(State0, Data),
{{rc4, State}, Text}.
-%%
-%% AES - in counter mode (CTR)
-%%
--spec aes_ctr_encrypt(iodata(), binary(), iodata()) ->
- binary().
--spec aes_ctr_decrypt(iodata(), binary(), iodata()) ->
- binary().
-
-aes_ctr_encrypt(_Key, _IVec, _Data) -> ?nif_stub.
-aes_ctr_decrypt(_Key, _IVec, _Cipher) -> ?nif_stub.
-
%%
%% AES - in counter mode (CTR) with state maintained for multi-call streaming
@@ -1067,34 +768,17 @@ aes_ctr_stream_decrypt(_State, _Cipher) -> ?nif_stub.
%%
%% RC4 - symmetric stream cipher
%%
--spec rc4_encrypt(iodata(), iodata()) -> binary().
-
-rc4_encrypt(_Key, _Data) -> ?nif_stub.
rc4_set_key(_Key) -> ?nif_stub.
rc4_encrypt_with_state(_State, _Data) -> ?nif_stub.
-
-%% RC2 block cipher
-
-rc2_cbc_encrypt(Key, IVec, Data) ->
- block_encrypt(rc2_cbc, Key, IVec, Data).
-
-rc2_cbc_decrypt(Key, IVec, Data) ->
- block_decrypt(rc2_cbc, Key, IVec, Data).
-
-%%
-%% RC2 - 40 bits block cipher - Backwards compatibility not documented.
-%%
-rc2_40_cbc_encrypt(Key, IVec, Data) when erlang:byte_size(Key) == 5 ->
- block_encrypt(rc2_cbc, Key, IVec, Data).
-
-rc2_40_cbc_decrypt(Key, IVec, Data) when erlang:byte_size(Key) == 5 ->
- block_decrypt(rc2_cbc, Key, IVec, Data).
-
-
%% Secure remote password -------------------------------------------------------------------
user_srp_gen_key(Private, Generator, Prime) ->
+ %% Ensure the SRP algorithm is disabled in FIPS mode
+ case info_fips() of
+ enabled -> erlang:error(notsup);
+ _ -> ok
+ end,
case mod_pow(Generator, Private, Prime) of
error ->
error;
@@ -1134,7 +818,7 @@ srp_scrambler(Version, UserPublic, HostPublic, Prime) when Version == '6'; Versi
srp_scrambler('3', _, HostPublic, _Prime) ->
%% The parameter u is a 32-bit unsigned integer which takes its value
%% from the first 32 bits of the SHA1 hash of B, MSB first.
- <<U:32/bits, _/binary>> = sha(HostPublic),
+ <<U:32/bits, _/binary>> = hash(sha, HostPublic),
U.
srp_pad_length(Width, Length) ->
@@ -1163,6 +847,11 @@ rsa_verify_nif(_Type, _Digest, _Signature, _Key) -> ?nif_stub.
ecdsa_verify_nif(_Type, _Digest, _Signature, _Curve, _Key) -> ?nif_stub.
%% Public Keys --------------------------------------------------------------------
+%% RSA Rivest-Shamir-Adleman functions
+%%
+
+rsa_generate_key_nif(_Bits, _Exp) -> ?nif_stub.
+
%% DH Diffie-Hellman functions
%%
@@ -1189,26 +878,10 @@ dh_check([_Prime,_Gen]) -> ?nif_stub.
%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()]
%% PrivKey = mpint()
--spec dh_generate_key([binary()]) -> {binary(),binary()}.
--spec dh_generate_key(binary()|undefined, [binary()]) ->
- {binary(),binary()}.
-
-dh_generate_key(DHParameters) ->
- dh_generate_key_nif(undefined, map_mpint_to_bin(DHParameters), 4).
-dh_generate_key(PrivateKey, DHParameters) ->
- dh_generate_key_nif(mpint_to_bin(PrivateKey), map_mpint_to_bin(DHParameters), 4).
-
-dh_generate_key_nif(_PrivateKey, _DHParameters, _Mpint) -> ?nif_stub.
+dh_generate_key_nif(_PrivateKey, _DHParameters, _Mpint, _Length) -> ?nif_stub.
%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()]
%% MyPrivKey, OthersPublicKey = mpint()
--spec dh_compute_key(binary(), binary(), [binary()]) -> binary().
-
-dh_compute_key(OthersPublicKey, MyPrivateKey, DHParameters) ->
- compute_key(dh, mpint_to_bin(OthersPublicKey), mpint_to_bin(MyPrivateKey),
- map_mpint_to_bin(DHParameters)).
-
-
dh_compute_key_nif(_OthersPublicKey, _MyPrivateKey, _DHParameters) -> ?nif_stub.
ec_key_generate(_Curve, _Key) -> ?nif_stub.
@@ -1288,137 +961,19 @@ ensure_int_as_bin(Int) when is_integer(Int) ->
ensure_int_as_bin(Bin) ->
Bin.
-map_to_norm_bin([H|_]=List) when is_integer(H) ->
- lists:map(fun(E) -> int_to_bin(E) end, List);
-map_to_norm_bin(List) ->
- lists:map(fun(E) -> mpint_to_bin(E) end, List).
-
-%%--------------------------------------------------------------------
-%%% Deprecated
%%--------------------------------------------------------------------
%%
-%% rsa_public_encrypt
-%% rsa_private_decrypt
-type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' | 'rsa_no_padding'.
--spec rsa_public_encrypt(binary(), [binary()], rsa_padding()) ->
- binary().
--spec rsa_public_decrypt(binary(), [integer() | mpint()], rsa_padding()) ->
- binary().
--spec rsa_private_encrypt(binary(), [integer() | mpint()], rsa_padding()) ->
- binary().
--spec rsa_private_decrypt(binary(), [integer() | mpint()], rsa_padding()) ->
- binary().
-
-%% Binary, Key = [E,N]
-rsa_public_encrypt(BinMesg, Key, Padding) ->
- case rsa_public_crypt(BinMesg, map_to_norm_bin(Key), Padding, true) of
- error ->
- erlang:error(encrypt_failed, [BinMesg,Key, Padding]);
- Sign -> Sign
- end.
-
rsa_public_crypt(_BinMsg, _Key, _Padding, _IsEncrypt) -> ?nif_stub.
-%% Binary, Key = [E,N,D]
-rsa_private_decrypt(BinMesg, Key, Padding) ->
- case rsa_private_crypt(BinMesg, map_to_norm_bin(Key), Padding, false) of
- error ->
- erlang:error(decrypt_failed, [BinMesg,Key, Padding]);
- Sign -> Sign
- end.
-
rsa_private_crypt(_BinMsg, _Key, _Padding, _IsEncrypt) -> ?nif_stub.
-
-%% Binary, Key = [E,N,D]
-rsa_private_encrypt(BinMesg, Key, Padding) ->
- case rsa_private_crypt(BinMesg, map_to_norm_bin(Key), Padding, true) of
- error ->
- erlang:error(encrypt_failed, [BinMesg,Key, Padding]);
- Sign -> Sign
- end.
-
-%% Binary, Key = [E,N]
-rsa_public_decrypt(BinMesg, Key, Padding) ->
- case rsa_public_crypt(BinMesg, map_to_norm_bin(Key), Padding, false) of
- error ->
- erlang:error(decrypt_failed, [BinMesg,Key, Padding]);
- Sign -> Sign
- end.
-
-map_mpint_to_bin(List) ->
- lists:map(fun(E) -> mpint_to_bin(E) end, List ).
-
-%%
-%% DSS, RSA - sign
-%%
-%% Key = [P,Q,G,X] P,Q,G=DSSParams X=PrivateKey
--spec dss_sign(data_or_digest(), [binary()]) -> binary().
--spec dss_sign(dss_digest_type(), data_or_digest(), [binary()]) -> binary().
--spec rsa_sign(data_or_digest(), [binary()]) -> binary().
--spec rsa_sign(rsa_digest_type(), data_or_digest(), [binary()]) -> binary().
-
-dss_sign(DataOrDigest,Key) ->
- dss_sign(sha,DataOrDigest,Key).
-dss_sign(Type, Data, Key) when is_binary(Data), Type=/=none ->
- sign(dss, Type, mpint_to_bin(Data), map_mpint_to_bin(Key));
-dss_sign(Type, Digest, Key) ->
- sign(dss, Type, Digest, map_mpint_to_bin(Key)).
-
-
-%% Key = [E,N,D] E=PublicExponent N=PublicModulus D=PrivateExponent
-rsa_sign(DataOrDigest,Key) ->
- rsa_sign(sha, DataOrDigest, Key).
-
-rsa_sign(Type, Data, Key) when is_binary(Data) ->
- sign(rsa, Type, mpint_to_bin(Data), map_mpint_to_bin(Key));
-rsa_sign(Type, Digest, Key) ->
- sign(rsa, Type, Digest, map_mpint_to_bin(Key)).
-
-%%
-%% DSS, RSA - verify
-%%
--spec dss_verify(data_or_digest(), binary(), [binary()]) -> boolean().
--spec dss_verify(dss_digest_type(), data_or_digest(), binary(), [binary()]) -> boolean().
--spec rsa_verify(data_or_digest(), binary(), [binary()]) -> boolean().
--spec rsa_verify(rsa_digest_type(), data_or_digest(), binary(), [binary()]) ->
- boolean().
-
-%% Key = [P,Q,G,Y] P,Q,G=DSSParams Y=PublicKey
-dss_verify(Data,Signature,Key) ->
- dss_verify(sha, Data, Signature, Key).
-
-dss_verify(Type,Data,Signature,Key) when is_binary(Data), Type=/=none ->
- verify(dss,Type,mpint_to_bin(Data),mpint_to_bin(Signature),map_mpint_to_bin(Key));
-dss_verify(Type,Digest,Signature,Key) ->
- verify(dss,Type,Digest,mpint_to_bin(Signature),map_mpint_to_bin(Key)).
-
-% Key = [E,N] E=PublicExponent N=PublicModulus
-rsa_verify(Data,Signature,Key) ->
- rsa_verify(sha, Data,Signature,Key).
-rsa_verify(Type, Data, Signature, Key) when is_binary(Data) ->
- verify(rsa, Type, mpint_to_bin(Data), mpint_to_bin(Signature), map_mpint_to_bin(Key));
-rsa_verify(Type, Digest, Signature, Key) ->
- verify(rsa, Type, Digest, mpint_to_bin(Signature), map_mpint_to_bin(Key)).
-
--spec strong_rand_mpint(Bits::non_neg_integer(),
- Top::-1..1,
- Bottom::0..1) -> binary().
-
-strong_rand_mpint(Bits, Top, Bottom) ->
- case strong_rand_mpint_nif(Bits,Top,Bottom) of
- false -> erlang:error(low_entropy);
- Bin -> Bin
- end.
-strong_rand_mpint_nif(_Bits, _Top, _Bottom) -> ?nif_stub.
-
-
%% large integer in a binary with 32bit length
%% MP representaion (SSH2)
mpint(X) when X < 0 -> mpint_neg(X);
mpint(X) -> mpint_pos(X).
-
+
-define(UINT32(X), X:32/unsigned-big-integer).
@@ -1443,75 +998,8 @@ erlint(<<MPIntSize:32/integer,MPIntValue/binary>>) ->
<<Integer:Bits/integer>> = MPIntValue,
Integer.
-mpint_to_bin(<<Len:32, Bin:Len/binary>>) ->
- Bin.
-
%%
%% mod_exp - utility for rsa generation and SRP
%%
-mod_exp(Base, Exponent, Modulo)
- when is_integer(Base), is_integer(Exponent), is_integer(Modulo) ->
- bin_to_int(mod_exp_nif(int_to_bin(Base), int_to_bin(Exponent), int_to_bin(Modulo), 0));
-
-mod_exp(Base, Exponent, Modulo) ->
- mod_exp_nif(mpint_to_bin(Base),mpint_to_bin(Exponent),mpint_to_bin(Modulo), 4).
-
mod_exp_nif(_Base,_Exp,_Mod,_bin_hdr) -> ?nif_stub.
--define(FUNC_LIST, [hash, hash_init, hash_update, hash_final,
- hmac, hmac_init, hmac_update, hmac_final, hmac_final_n,
- %% deprecated
- md4, md4_init, md4_update, md4_final,
- md5, md5_init, md5_update, md5_final,
- sha, sha_init, sha_update, sha_final,
- md5_mac, md5_mac_96,
- sha_mac, sha_mac_96,
- %%
- block_encrypt, block_decrypt,
- %% deprecated
- des_cbc_encrypt, des_cbc_decrypt,
- des_cfb_encrypt, des_cfb_decrypt,
- des_ecb_encrypt, des_ecb_decrypt,
- des3_cbc_encrypt, des3_cbc_decrypt,
- des3_cfb_encrypt, des3_cfb_decrypt,
- aes_cfb_128_encrypt, aes_cfb_128_decrypt,
- rc2_cbc_encrypt, rc2_cbc_decrypt,
- rc2_40_cbc_encrypt, rc2_40_cbc_decrypt,
- aes_cbc_128_encrypt, aes_cbc_128_decrypt,
- aes_cbc_256_encrypt, aes_cbc_256_decrypt,
- blowfish_cbc_encrypt, blowfish_cbc_decrypt,
- blowfish_cfb64_encrypt, blowfish_cfb64_decrypt,
- blowfish_ecb_encrypt, blowfish_ecb_decrypt, blowfish_ofb64_encrypt,
- %%
- rand_bytes,
- strong_rand_bytes,
- rand_uniform,
- rand_seed,
- mod_pow,
- exor,
- %% deprecated
- mod_exp,strong_rand_mpint,erlint, mpint,
- %%
- sign, verify, generate_key, compute_key,
- %% deprecated
- dss_verify,dss_sign,
- rsa_verify,rsa_sign,
- rsa_public_encrypt,rsa_private_decrypt,
- rsa_private_encrypt,rsa_public_decrypt,
- dh_generate_key, dh_compute_key,
- %%
- stream_init, stream_encrypt, stream_decrypt,
- %% deprecated
- rc4_encrypt, rc4_set_key, rc4_encrypt_with_state,
- aes_ctr_encrypt, aes_ctr_decrypt,
- aes_ctr_stream_init, aes_ctr_stream_encrypt, aes_ctr_stream_decrypt,
- %%
- next_iv,
- %% deprecated
- aes_cbc_ivec,
- des_cbc_ivec, des_cfb_ivec,
- info,
- %%
- info_lib, supports]).
-info() ->
- ?FUNC_LIST.
diff --git a/lib/crypto/src/crypto_ec_curves.erl b/lib/crypto/src/crypto_ec_curves.erl
index 002b03b80c..9602a7e24b 100644
--- a/lib/crypto/src/crypto_ec_curves.erl
+++ b/lib/crypto/src/crypto_ec_curves.erl
@@ -7,29 +7,36 @@ curves() ->
PubKeys = proplists:get_value(public_keys, CryptoSupport),
HasEC = proplists:get_bool(ecdh, PubKeys),
HasGF2m = proplists:get_bool(ec_gf2m, PubKeys),
- prime_curves(HasEC) ++ characteristic_two_curves(HasGF2m).
+ FIPSMode = crypto:info_fips() == enabled,
+ prime_curves(HasEC, FIPSMode) ++ characteristic_two_curves(HasGF2m, FIPSMode).
-prime_curves(true) ->
- [secp112r1,secp112r2,secp128r1,secp128r2,secp160k1,secp160r1,secp160r2,
+prime_curves(true, true) ->
+ [secp160k1,secp160r1,secp160r2,
secp192r1,secp192k1,secp224k1,secp224r1,secp256k1,secp256r1,secp384r1,
secp521r1,prime192v1,prime192v2,prime192v3,prime239v1,prime239v2,prime239v3,
- prime256v1,wtls6,wtls7,wtls8,wtls9,wtls12,
+ prime256v1,wtls7,wtls9,wtls12,
brainpoolP160r1,brainpoolP160t1,brainpoolP192r1,brainpoolP192t1,
brainpoolP224r1,brainpoolP224t1,brainpoolP256r1,brainpoolP256t1,
brainpoolP320r1,brainpoolP320t1,brainpoolP384r1,brainpoolP384t1,
brainpoolP512r1,brainpoolP512t1];
-prime_curves(_) ->
+prime_curves(true, false) ->
+ [secp112r1,secp112r2,secp128r1,secp128r2,wtls6,wtls8]
+ ++ prime_curves(true, true);
+prime_curves(_, _) ->
[].
-characteristic_two_curves(true) ->
- [sect113r1,sect113r2,sect131r1,sect131r2,sect163k1,sect163r1,
+characteristic_two_curves(true, true) ->
+ [sect163k1,sect163r1,
sect163r2,sect193r1,sect193r2,sect233k1,sect233r1,sect239k1,sect283k1,
sect283r1,sect409k1,sect409r1,sect571k1,sect571r1,c2pnb163v1,c2pnb163v2,
c2pnb163v3,c2pnb176v1,c2tnb191v1,c2tnb191v2,c2tnb191v3,c2pnb208w1,c2tnb239v1,
c2tnb239v2,c2tnb239v3,c2pnb272w1,c2pnb304w1,c2tnb359v1,c2pnb368w1,c2tnb431r1,
- wtls1,wtls3,wtls4,wtls5,wtls10,wtls11,ipsec3,ipsec4];
-characteristic_two_curves(_) ->
+ wtls3,wtls5,wtls10,wtls11];
+characteristic_two_curves(true, _) ->
+ [sect113r1,sect113r2,sect131r1,sect131r2,wtls1,wtls4,ipsec3,ipsec4]
+ ++ characteristic_two_curves(true, true);
+characteristic_two_curves(_, _) ->
[].
curve(secp112r1) ->
diff --git a/lib/crypto/test/Makefile b/lib/crypto/test/Makefile
index 928a1b1d73..138081d386 100644
--- a/lib/crypto/test/Makefile
+++ b/lib/crypto/test/Makefile
@@ -7,8 +7,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
MODULES = \
blowfish_SUITE \
- crypto_SUITE \
- old_crypto_SUITE
+ crypto_SUITE
ERL_FILES= $(MODULES:%=%.erl)
@@ -78,6 +77,7 @@ release_spec:
release_tests_spec: $(TEST_TARGET)
$(INSTALL_DIR) "$(RELSYSDIR)"
$(INSTALL_DATA) crypto.spec crypto.cover $(RELTEST_FILES) "$(RELSYSDIR)"
+ @tar cfh - crypto_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
chmod -R u+w "$(RELSYSDIR)"
release_docs_spec:
diff --git a/lib/crypto/test/blowfish_SUITE.erl b/lib/crypto/test/blowfish_SUITE.erl
index d7c50dc6de..c2d0d2621b 100644
--- a/lib/crypto/test/blowfish_SUITE.erl
+++ b/lib/crypto/test/blowfish_SUITE.erl
@@ -107,11 +107,37 @@ end_per_testcase(_TestCase, Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
-[ecb, cbc, cfb64, ofb64].
+[{group, fips},
+ {group, non_fips}].
groups() ->
- [].
+ [{fips, [], [no_ecb, no_cbc, no_cfb64, no_ofb64]},
+ {non_fips, [], [ecb, cbc, cfb64, ofb64]}].
+init_per_group(fips, Config) ->
+ case crypto:info_fips() of
+ enabled ->
+ Config;
+ not_enabled ->
+ case crypto:enable_fips_mode(true) of
+ true ->
+ enabled = crypto:info_fips(),
+ Config;
+ false ->
+ {skip, "Failed to enable FIPS mode"}
+ end;
+ not_supported ->
+ {skip, "FIPS mode not supported"}
+ end;
+init_per_group(non_fips, Config) ->
+ case crypto:info_fips() of
+ enabled ->
+ true = crypto:enable_fips_mode(false),
+ not_enabled = crypto:info_fips(),
+ Config;
+ _NotEnabled ->
+ Config
+ end;
init_per_group(_GroupName, Config) ->
Config.
@@ -125,7 +151,7 @@ end_per_group(_GroupName, Config) ->
ecb_test(KeyBytes, ClearBytes, CipherBytes) ->
{Key, Clear, Cipher} =
{to_bin(KeyBytes), to_bin(ClearBytes), to_bin(CipherBytes)},
- ?line m(crypto:blowfish_ecb_encrypt(Key, Clear), Cipher),
+ ?line m(crypto:block_encrypt(blowfish_ecb, Key, Clear), Cipher),
true.
ecb(doc) ->
@@ -174,7 +200,7 @@ cbc(doc) ->
cbc(suite) ->
[];
cbc(Config) when is_list(Config) ->
- true = crypto:blowfish_cbc_encrypt(?KEY, ?IVEC, ?DATA_PADDED) =:=
+ true = crypto:block_encrypt(blowfish_cbc, ?KEY, ?IVEC, ?DATA_PADDED) =:=
to_bin("6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC"),
ok.
@@ -183,7 +209,7 @@ cfb64(doc) ->
cfb64(suite) ->
[];
cfb64(Config) when is_list(Config) ->
- true = crypto:blowfish_cfb64_encrypt(?KEY, ?IVEC, ?DATA) =:=
+ true = crypto:block_encrypt(blowfish_cfb64, ?KEY, ?IVEC, ?DATA) =:=
to_bin("E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3"),
ok.
@@ -192,12 +218,59 @@ ofb64(doc) ->
ofb64(suite) ->
[];
ofb64(Config) when is_list(Config) ->
- true = crypto:blowfish_ofb64_encrypt(?KEY, ?IVEC, ?DATA) =:=
+ true = crypto:block_encrypt(blowfish_ofb64, ?KEY, ?IVEC, ?DATA) =:=
to_bin("E73214A2822139CA62B343CC5B65587310DD908D0C241B2263C2CF80DA"),
ok.
+no_ecb(doc) ->
+ "Test that ECB mode is disabled";
+no_ecb(suite) ->
+ [];
+no_ecb(Config) when is_list(Config) ->
+ notsup(fun crypto:block_encrypt/3,
+ [blowfish_ecb,
+ to_bin("0000000000000000"),
+ to_bin("FFFFFFFFFFFFFFFF")]).
+
+no_cbc(doc) ->
+ "Test that CBC mode is disabled";
+no_cbc(suite) ->
+ [];
+no_cbc(Config) when is_list(Config) ->
+ notsup(fun crypto:block_encrypt/4,
+ [blowfish_cbc, ?KEY, ?IVEC, ?DATA_PADDED]).
+
+no_cfb64(doc) ->
+ "Test that CFB64 mode is disabled";
+no_cfb64(suite) ->
+ [];
+no_cfb64(Config) when is_list(Config) ->
+ notsup(fun crypto:block_encrypt/4,
+ [blowfish_cfb64, ?KEY, ?IVEC, ?DATA]),
+ ok.
+
+no_ofb64(doc) ->
+ "Test that OFB64 mode is disabled";
+no_ofb64(suite) ->
+ [];
+no_ofb64(Config) when is_list(Config) ->
+ notsup(fun crypto:block_encrypt/4,
+ [blowfish_ofb64, ?KEY, ?IVEC, ?DATA]).
+
%% Helper functions
+%% Assert function fails with notsup error
+notsup(Fun, Args) ->
+ ok = try
+ {error, {return, apply(Fun, Args)}}
+ catch
+ error:notsup ->
+ ok;
+ Class:Error ->
+ {error, {Class, Error}}
+ end.
+
+
%% Convert a hexadecimal string to a binary.
-spec(to_bin(L::string()) -> binary()).
to_bin(L) ->
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 6732f27824..164f43dcb0 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,51 +29,90 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
-all() ->
+all() ->
[app,
appup,
- {group, md4},
- {group, md5},
- {group, ripemd160},
- {group, sha},
- {group, sha224},
- {group, sha256},
- {group, sha384},
- {group, sha512},
- {group, rsa},
- {group, dss},
- {group, ecdsa},
- {group, dh},
- {group, ecdh},
- {group, srp},
- {group, des_cbc},
- {group, des_cfb},
- {group, des3_cbc},
- {group, des3_cbf},
- {group, des_ede3},
- {group, blowfish_cbc},
- {group, blowfish_ecb},
- {group, blowfish_cfb64},
- {group, blowfish_ofb64},
- {group, aes_cbc128},
- {group, aes_cfb8},
- {group, aes_cfb128},
- {group, aes_cbc256},
- {group, aes_ecb},
- {group, aes_ige256},
- {group, rc2_cbc},
- {group, rc4},
- {group, aes_ctr},
- {group, aes_gcm},
- {group, chacha20_poly1305},
- {group, aes_cbc},
+ {group, fips},
+ {group, non_fips},
mod_pow,
exor,
- rand_uniform
+ rand_uniform,
+ rand_plugin,
+ rand_plugin_s
].
-groups() ->
- [{md4, [], [hash]},
+groups() ->
+ [{non_fips, [], [{group, md4},
+ {group, md5},
+ {group, ripemd160},
+ {group, sha},
+ {group, sha224},
+ {group, sha256},
+ {group, sha384},
+ {group, sha512},
+ {group, rsa},
+ {group, dss},
+ {group, ecdsa},
+ {group, dh},
+ {group, ecdh},
+ {group, srp},
+ {group, des_cbc},
+ {group, des_cfb},
+ {group, des3_cbc},
+ {group, des3_cbf},
+ {group, des3_cfb},
+ {group, des_ede3},
+ {group, blowfish_cbc},
+ {group, blowfish_ecb},
+ {group, blowfish_cfb64},
+ {group, blowfish_ofb64},
+ {group, aes_cbc128},
+ {group, aes_cfb8},
+ {group, aes_cfb128},
+ {group, aes_cbc256},
+ {group, aes_ige256},
+ {group, rc2_cbc},
+ {group, rc4},
+ {group, aes_ctr},
+ {group, aes_gcm},
+ {group, chacha20_poly1305},
+ {group, aes_cbc}]},
+ {fips, [], [{group, no_md4},
+ {group, no_md5},
+ {group, no_ripemd160},
+ {group, sha},
+ {group, sha224},
+ {group, sha256},
+ {group, sha384},
+ {group, sha512},
+ {group, rsa},
+ {group, dss},
+ {group, ecdsa},
+ {group, dh},
+ {group, ecdh},
+ {group, no_srp},
+ {group, no_des_cbc},
+ {group, no_des_cfb},
+ {group, des3_cbc},
+ {group, des3_cbf},
+ {group, des3_cfb},
+ {group, des_ede3},
+ {group, no_blowfish_cbc},
+ {group, no_blowfish_ecb},
+ {group, no_blowfish_cfb64},
+ {group, no_blowfish_ofb64},
+ {group, aes_cbc128},
+ {group, aes_cfb8},
+ {group, aes_cfb128},
+ {group, aes_cbc256},
+ {group, no_aes_ige256},
+ {group, no_rc2_cbc},
+ {group, no_rc4},
+ {group, aes_ctr},
+ {group, aes_gcm},
+ {group, no_chacha20_poly1305},
+ {group, aes_cbc}]},
+ {md4, [], [hash]},
{md5, [], [hash, hmac]},
{ripemd160, [], [hash]},
{sha, [], [hash, hmac]},
@@ -81,9 +120,10 @@ groups() ->
{sha256, [], [hash, hmac]},
{sha384, [], [hash, hmac]},
{sha512, [], [hash, hmac]},
- {rsa, [], [sign_verify,
- public_encrypt
- ]},
+ {rsa, [], [sign_verify,
+ public_encrypt,
+ generate
+ ]},
{dss, [], [sign_verify]},
{ecdsa, [], [sign_verify]},
{dh, [], [generate_compute]},
@@ -94,26 +134,47 @@ groups() ->
{des3_cbc,[], [block]},
{des_ede3,[], [block]},
{des3_cbf,[], [block]},
+ {des3_cfb,[], [block]},
{rc2_cbc,[], [block]},
- {aes_cbc128,[], [block]},
+ {aes_cbc128,[], [block, cmac]},
{aes_cfb8,[], [block]},
{aes_cfb128,[], [block]},
- {aes_cbc256,[], [block]},
+ {aes_cbc256,[], [block, cmac]},
{aes_ecb,[], [block]},
{aes_ige256,[], [block]},
{blowfish_cbc, [], [block]},
{blowfish_ecb, [], [block]},
{blowfish_cfb64, [], [block]},
{blowfish_ofb64,[], [block]},
- {rc4, [], [stream]},
+ {rc4, [], [stream]},
{aes_ctr, [], [stream]},
{aes_gcm, [], [aead]},
{chacha20_poly1305, [], [aead]},
- {aes_cbc, [], [block]}
+ {aes_cbc, [], [block]},
+ {no_md4, [], [no_support, no_hash]},
+ {no_md5, [], [no_support, no_hash, no_hmac]},
+ {no_ripemd160, [], [no_support, no_hash]},
+ {no_srp, [], [no_support, no_generate_compute]},
+ {no_des_cbc, [], [no_support, no_block]},
+ {no_des_cfb, [], [no_support, no_block]},
+ {no_blowfish_cbc, [], [no_support, no_block]},
+ {no_blowfish_ecb, [], [no_support, no_block]},
+ {no_blowfish_cfb64, [], [no_support, no_block]},
+ {no_blowfish_ofb64, [], [no_support, no_block]},
+ {no_aes_ige256, [], [no_support, no_block]},
+ {no_chacha20_poly1305, [], [no_support, no_aead]},
+ {no_rc2_cbc, [], [no_support, no_block]},
+ {no_rc4, [], [no_support, no_stream]}
].
%%-------------------------------------------------------------------
init_per_suite(Config) ->
+ file:set_cwd(datadir(Config)),
+ {ok, _} = zip:unzip("KAT_AES.zip"),
+ {ok, _} = zip:unzip("aesmmt.zip"),
+ {ok, _} = zip:unzip("cmactestvectors.zip"),
+ {ok, _} = zip:unzip("gcmtestvectors.zip"),
+
try crypto:start() of
ok ->
try crypto:strong_rand_bytes(1) of
@@ -139,12 +200,47 @@ end_per_suite(_Config) ->
application:stop(crypto).
%%-------------------------------------------------------------------
+init_per_group(fips, Config) ->
+ FIPSConfig = [{fips, true} | Config],
+ case crypto:info_fips() of
+ enabled ->
+ FIPSConfig;
+ not_enabled ->
+ case crypto:enable_fips_mode(true) of
+ true ->
+ enabled = crypto:info_fips(),
+ FIPSConfig;
+ false ->
+ {skip, "Failed to enable FIPS mode"}
+ end;
+ not_supported ->
+ {skip, "FIPS mode not supported"}
+ end;
+init_per_group(non_fips, Config) ->
+ NonFIPSConfig = [{fips, false} | Config],
+ case crypto:info_fips() of
+ enabled ->
+ true = crypto:enable_fips_mode(false),
+ not_enabled = crypto:info_fips(),
+ NonFIPSConfig;
+ _NotEnabled ->
+ NonFIPSConfig
+ end;
init_per_group(GroupName, Config) ->
- case is_supported(GroupName) of
- true ->
- group_config(GroupName, Config);
- false ->
- {skip, "Group not supported"}
+ case atom_to_list(GroupName) of
+ "no_" ++ TypeStr ->
+ %% Negated test case: check the algorithm is not supported
+ %% (e.g. due to FIPS mode limitations)
+ TypeAtom = list_to_atom(TypeStr),
+ [{type, TypeAtom} | group_config(TypeAtom, Config)];
+ _Other ->
+ %% Regular test case: skip if the algorithm is not supported
+ case is_supported(GroupName) of
+ true ->
+ [{type, GroupName} | group_config(GroupName, Config)];
+ false ->
+ {skip, "Group not supported"}
+ end
end.
end_per_group(_GroupName, Config) ->
@@ -152,6 +248,29 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(info, Config) ->
Config;
+init_per_testcase(cmac, Config) ->
+ case crypto:info_lib() of
+ [{<<"OpenSSL">>,LibVer,_}] when is_integer(LibVer), LibVer > 16#10001000 ->
+ Config;
+ _Else ->
+ % The CMAC functionality was introduced in OpenSSL 1.0.1
+ {skip, "OpenSSL is too old"}
+ end;
+init_per_testcase(generate, Config) ->
+ case proplists:get_value(type, Config) of
+ rsa ->
+ % RSA key generation is a lengthy process, and is only available
+ % if dirty CPU scheduler support was enabled for this runtime.
+ case try erlang:system_info(dirty_cpu_schedulers) of
+ N -> N > 0
+ catch
+ error:badarg -> false
+ end of
+ true -> Config;
+ false -> {skip, "RSA key generation requires dirty scheduler support."}
+ end;
+ _ -> Config
+ end;
init_per_testcase(_Name,Config) ->
Config.
@@ -173,6 +292,12 @@ appup() ->
appup(Config) when is_list(Config) ->
ok = ?t:appup_test(crypto).
%%--------------------------------------------------------------------
+no_support() ->
+ [{doc, "Test an algorithm is not reported in the supported list"}].
+no_support(Config) when is_list(Config) ->
+ Type = ?config(type, Config),
+ false = is_supported(Type).
+%%--------------------------------------------------------------------
hash() ->
[{doc, "Test all different hash functions"}].
hash(Config) when is_list(Config) ->
@@ -184,7 +309,14 @@ hash(Config) when is_list(Config) ->
hash(Type, Msgs, Digests),
hash(Type, lists:map(fun iolistify/1, Msgs), Digests),
hash_increment(Type, Inc, IncrDigest).
-%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
+no_hash() ->
+ [{doc, "Test all disabled hash functions"}].
+no_hash(Config) when is_list(Config) ->
+ Type = ?config(type, Config),
+ notsup(fun crypto:hash/2, [Type, <<"Hi There">>]),
+ notsup(fun crypto:hash_init/1, [Type]).
+%%--------------------------------------------------------------------
hmac() ->
[{doc, "Test all different hmac functions"}].
hmac(Config) when is_list(Config) ->
@@ -194,15 +326,68 @@ hmac(Config) when is_list(Config) ->
hmac(Type, lists:map(fun iolistify/1, Keys), lists:map(fun iolistify/1, Data), Expected),
hmac_increment(Type).
%%--------------------------------------------------------------------
+no_hmac() ->
+ [{doc, "Test all disabled hmac functions"}].
+no_hmac(Config) when is_list(Config) ->
+ Type = ?config(type, Config),
+ notsup(fun crypto:hmac/3, [Type, <<"Key">>, <<"Hi There">>]),
+ notsup(fun crypto:hmac_init/2, [Type, <<"Key">>]).
+%%--------------------------------------------------------------------
+cmac() ->
+ [{doc, "Test all different cmac functions"}].
+cmac(Config) when is_list(Config) ->
+ Pairs = lazy_eval(proplists:get_value(cmac, Config)),
+ lists:foreach(fun cmac_check/1, Pairs),
+ lists:foreach(fun cmac_check/1, cmac_iolistify(Pairs)).
+%%--------------------------------------------------------------------
block() ->
[{doc, "Test block ciphers"}].
block(Config) when is_list(Config) ->
- Blocks = proplists:get_value(block, Config),
+ Fips = proplists:get_bool(fips, Config),
+ Type = ?config(type, Config),
+ %% See comment about EVP_CIPHER_CTX_set_key_length in
+ %% block_crypt_nif in crypto.c.
+ case {Fips, Type} of
+ {true, aes_cfb8} ->
+ throw({skip, "Cannot test aes_cfb8 in FIPS mode because of key length issue"});
+ {true, aes_cfb128} ->
+ throw({skip, "Cannot test aes_cfb128 in FIPS mode because of key length issue"});
+ _ ->
+ ok
+ end,
+
+ Blocks = lazy_eval(proplists:get_value(block, Config)),
lists:foreach(fun block_cipher/1, Blocks),
lists:foreach(fun block_cipher/1, block_iolistify(Blocks)),
lists:foreach(fun block_cipher_increment/1, block_iolistify(Blocks)).
%%--------------------------------------------------------------------
+no_block() ->
+ [{doc, "Test disabled block ciphers"}].
+no_block(Config) when is_list(Config) ->
+ Blocks = lazy_eval(proplists:get_value(block, Config)),
+ Args = case Blocks of
+ [{_Type, _Key, _PlainText} = A | _] ->
+ tuple_to_list(A);
+ [{_Type, _Key, _IV, _PlainText} = A | _] ->
+ tuple_to_list(A);
+ [{Type, Key, IV, PlainText, _CipherText} | _] ->
+ [Type, Key, IV, PlainText]
+ end,
+ N = length(Args),
+ notsup(fun crypto:block_encrypt/N, Args),
+ notsup(fun crypto:block_decrypt/N, Args).
+%%--------------------------------------------------------------------
+no_aead() ->
+ [{doc, "Test disabled aead ciphers"}].
+no_aead(Config) when is_list(Config) ->
+ [{Type, Key, PlainText, Nonce, AAD, CipherText, CipherTag} | _] =
+ lazy_eval(proplists:get_value(aead, Config)),
+ EncryptArgs = [Type, Key, Nonce, {AAD, PlainText}],
+ DecryptArgs = [Type, Key, Nonce, {AAD, CipherText, CipherTag}],
+ notsup(fun crypto:block_encrypt/4, EncryptArgs),
+ notsup(fun crypto:block_decrypt/4, DecryptArgs).
+%%--------------------------------------------------------------------
stream() ->
[{doc, "Test stream ciphers"}].
stream(Config) when is_list(Config) ->
@@ -211,6 +396,12 @@ stream(Config) when is_list(Config) ->
lists:foreach(fun stream_cipher/1, Streams),
lists:foreach(fun stream_cipher/1, stream_iolistify(Streams)),
lists:foreach(fun stream_cipher_incment/1, stream_iolistify(Streams)).
+%%--------------------------------------------------------------------
+no_stream() ->
+ [{doc, "Test disabled stream ciphers"}].
+no_stream(Config) when is_list(Config) ->
+ Type = ?config(type, Config),
+ notsup(fun crypto:stream_init/2, [Type, <<"Key">>]).
%%--------------------------------------------------------------------
aead() ->
@@ -218,7 +409,20 @@ aead() ->
aead(Config) when is_list(Config) ->
AEADs = lazy_eval(proplists:get_value(aead, Config)),
- lists:foreach(fun aead_cipher/1, AEADs).
+ FilteredAEADs =
+ case proplists:get_bool(fips, Config) of
+ false ->
+ AEADs;
+ true ->
+ %% In FIPS mode, the IV length must be at least 12 bytes.
+ lists:filter(
+ fun(Tuple) ->
+ IVLen = byte_size(element(4, Tuple)),
+ IVLen >= 12
+ end, AEADs)
+ end,
+
+ lists:foreach(fun aead_cipher/1, FilteredAEADs).
%%--------------------------------------------------------------------
sign_verify() ->
@@ -242,6 +446,24 @@ generate_compute(Config) when is_list(Config) ->
GenCom = proplists:get_value(generate_compute, Config),
lists:foreach(fun do_generate_compute/1, GenCom).
%%--------------------------------------------------------------------
+no_generate_compute() ->
+ [{doc, "Test crypto:genarate_key and crypto:compute_key "
+ "for disabled algorithms"}].
+no_generate_compute(Config) when is_list(Config) ->
+ %% This test is specific to the SRP protocol
+ srp = ?config(type, Config),
+ {srp,
+ UserPrivate, UserGenParams, UserComParams,
+ HostPublic, HostPrivate, HostGenParams, HostComParams,
+ _SessionKey} = srp3(),
+ UserPublic = HostPublic, % use a fake public key
+ notsup(fun crypto:generate_key/3, [srp, UserGenParams, UserPrivate]),
+ notsup(fun crypto:generate_key/3, [srp, HostGenParams, HostPrivate]),
+ notsup(fun crypto:compute_key/4,
+ [srp, HostPublic, {UserPublic, UserPrivate}, UserComParams]),
+ notsup(fun crypto:compute_key/4,
+ [srp, UserPublic, {HostPublic, HostPrivate}, HostComParams]).
+%%--------------------------------------------------------------------
compute() ->
[{doc, " Test crypto:compute_key"}].
compute(Config) when is_list(Config) ->
@@ -272,6 +494,17 @@ rand_uniform(Config) when is_list(Config) ->
10 = byte_size(crypto:strong_rand_bytes(10)).
%%--------------------------------------------------------------------
+rand_plugin() ->
+ [{doc, "crypto rand plugin testing (implicit state / process dictionary)"}].
+rand_plugin(Config) when is_list(Config) ->
+ rand_plugin_aux(implicit_state).
+
+rand_plugin_s() ->
+ [{doc, "crypto rand plugin testing (explicit state)"}].
+rand_plugin_s(Config) when is_list(Config) ->
+ rand_plugin_aux(explicit_state).
+
+%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
hash(_, [], []) ->
@@ -346,6 +579,23 @@ hmac_increment(State0, [Increment | Rest]) ->
State = crypto:hmac_update(State0, Increment),
hmac_increment(State, Rest).
+cmac_check({Type, Key, Text, CMac}) ->
+ ExpCMac = iolist_to_binary(CMac),
+ case crypto:cmac(Type, Key, Text) of
+ ExpCMac ->
+ ok;
+ Other ->
+ ct:fail({{crypto, cmac, [Type, Key, Text]}, {expected, ExpCMac}, {got, Other}})
+ end;
+cmac_check({Type, Key, Text, Size, CMac}) ->
+ ExpCMac = iolist_to_binary(CMac),
+ case crypto:cmac(Type, Key, Text, Size) of
+ ExpCMac ->
+ ok;
+ Other ->
+ ct:fail({{crypto, cmac, [Type, Key, Text, Size]}, {expected, ExpCMac}, {got, Other}})
+ end.
+
block_cipher({Type, Key, PlainText}) ->
Plain = iolist_to_binary(PlainText),
CipherText = crypto:block_encrypt(Type, Key, PlainText),
@@ -381,16 +631,18 @@ block_cipher({Type, Key, IV, PlainText, CipherText}) ->
ct:fail({{crypto, block_decrypt, [Type, Key, IV, CipherText]}, {expected, Plain}, {got, Other1}})
end.
-block_cipher_increment({Type, Key, IV, PlainTexts}) when Type == des_cbc;
- Type == des3_cbc;
- Type == aes_cbc;
- Type == des_cbf
- ->
+block_cipher_increment({Type, Key, IV, PlainTexts})
+ when Type == des_cbc; Type == aes_cbc; Type == des3_cbc ->
block_cipher_increment(Type, Key, IV, IV, PlainTexts, iolist_to_binary(PlainTexts), []);
+block_cipher_increment({Type, Key, IV, PlainTexts, CipherText})
+ when Type == des_cbc; Type == des3_cbc ->
+ block_cipher_increment(Type, Key, IV, IV, PlainTexts, iolist_to_binary(PlainTexts), CipherText, []);
block_cipher_increment({Type, Key, IV, PlainTexts, _CipherText}) when Type == aes_cbc ->
Plain = iolist_to_binary(PlainTexts),
Blocks = [iolistify(Block) || << Block:128/bitstring >> <= Plain],
block_cipher_increment(Type, Key, IV, IV, Blocks, Plain, []);
+block_cipher_increment({_Type, _, _, _, _}) ->
+ ok;
block_cipher_increment({_Type, _, _, _}) ->
ok;
block_cipher_increment({_,_,_}) ->
@@ -407,6 +659,17 @@ block_cipher_increment(Type, Key, IV0, IV, [PlainText | PlainTexts], Plain, Acc)
CipherText = crypto:block_encrypt(Type, Key, IV, PlainText),
NextIV = crypto:next_iv(Type, CipherText),
block_cipher_increment(Type, Key, IV0, NextIV, PlainTexts, Plain, [CipherText | Acc]).
+block_cipher_increment(Type, Key, IV0, _IV, [], _Plain, CipherText, Acc) ->
+ case iolist_to_binary(lists:reverse(Acc)) of
+ CipherText ->
+ ok;
+ Other ->
+ ct:fail({{crypto, block_decrypt, [Type, Key, IV0, CipherText]}, {expected, CipherText}, {got, Other}})
+ end;
+block_cipher_increment(Type, Key, IV0, IV, [PlainText | PlainTexts], Plain, CipherText, Acc) ->
+ CT = crypto:block_encrypt(Type, Key, IV, PlainText),
+ NextIV = crypto:next_iv(Type, CT),
+ block_cipher_increment(Type, Key, IV0, NextIV, PlainTexts, Plain, CipherText, [CT | Acc]).
stream_cipher({Type, Key, PlainText}) ->
Plain = iolist_to_binary(PlainText),
@@ -544,11 +807,42 @@ do_generate({ecdh = Type, Curve, Priv, Pub}) ->
ok;
{Other, _} ->
ct:fail({{crypto, generate_key, [Type, Priv, Curve]}, {expected, Pub}, {got, Other}})
+ end;
+do_generate({rsa = Type, Mod, Exp}) ->
+ case crypto:info_fips() of
+ enabled when Mod < 3072 ->
+ ct:log("SKIP do_generate ~p FIPS=~p, Mod=~p Exp=~p", [Type, enabled, Mod, Exp]),
+ {skip, "FIPS violation"};
+ FIPS ->
+ ct:log("do_generate ~p FIPS=~p, Mod=~p Exp=~p", [Type, FIPS, Mod, Exp]),
+ {Pub,Priv} = crypto:generate_key(Type, {Mod,Exp}),
+ do_sign_verify({rsa, sha256, Pub, Priv, rsa_plain()})
+ end.
+
+notsup(Fun, Args) ->
+ Result =
+ try
+ {error, {return, apply(Fun, Args)}}
+ catch
+ error:notsup ->
+ ok;
+ Class:Error ->
+ {error, {Class, Error}}
+ end,
+ case Result of
+ ok ->
+ ok;
+ {error, Value} ->
+ {module, Module} = erlang:fun_info(Fun, module),
+ {name, Name} = erlang:fun_info(Fun, name),
+ ct:fail({{Module, Name, Args}, {expected, {error, notsup}}, {got, Value}})
end.
hexstr2point(X, Y) ->
<<4:8, (hexstr2bin(X))/binary, (hexstr2bin(Y))/binary>>.
+hexstr2bin(S) when is_binary(S) ->
+ list_to_binary(hexstr2list(binary_to_list(S)));
hexstr2bin(S) ->
list_to_binary(hexstr2list(S)).
@@ -566,11 +860,18 @@ mkint(C) when $a =< C, C =< $f ->
is_supported(Group) ->
lists:member(Group, lists:append([Algo || {_, Algo} <- crypto:supports()])).
+cmac_iolistify(Blocks) ->
+ lists:map(fun do_cmac_iolistify/1, Blocks).
block_iolistify(Blocks) ->
lists:map(fun do_block_iolistify/1, Blocks).
stream_iolistify(Streams) ->
lists:map(fun do_stream_iolistify/1, Streams).
+do_cmac_iolistify({Type, Key, Text, CMac}) ->
+ {Type, iolistify(Key), iolistify(Text), CMac};
+do_cmac_iolistify({Type, Key, Text, Size, CMac}) ->
+ {Type, iolistify(Key), iolistify(Text), Size, CMac}.
+
do_stream_iolistify({Type, Key, PlainText}) ->
{Type, iolistify(Key), iolistify(PlainText)};
do_stream_iolistify({Type, Key, IV, PlainText}) ->
@@ -582,6 +883,8 @@ do_block_iolistify({des3_cbc = Type, Key, IV, PlainText}) ->
{Type, Key, IV, des_iolistify(PlainText)};
do_block_iolistify({des3_cbf = Type, Key, IV, PlainText}) ->
{Type, Key, IV, des_iolistify(PlainText)};
+do_block_iolistify({des3_cfb = Type, Key, IV, PlainText}) ->
+ {Type, Key, IV, des_iolistify(PlainText)};
do_block_iolistify({des_ede3 = Type, Key, IV, PlainText}) ->
{Type, Key, IV, des_iolistify(PlainText)};
do_block_iolistify({Type, Key, PlainText}) ->
@@ -692,6 +995,101 @@ crypto_rand_uniform(L,H) ->
ct:fail({"Not in interval", R1, L, H})
end.
+foldallmap(_Fun, AccN, []) ->
+ {true, AccN};
+foldallmap(Fun, AccN, [H|T]) ->
+ case Fun(H, AccN) of
+ {true, AccM} -> foldallmap(Fun, AccM, T);
+ {{false, Result}, AccM} -> {Result, AccM}
+ end.
+
+allmap(_Fun, []) ->
+ true;
+allmap(Fun, [H|T]) ->
+ case Fun(H) of
+ true -> allmap(Fun, T);
+ {false, Result} -> Result
+ end.
+
+rand_plugin_aux(StateType) ->
+ {Seeder, SeedExporter, FloatGenerator, IntegerGenerator} = rand_plugin_functions(StateType),
+ State0 = Seeder(),
+ {crypto, no_seed} = SeedExporter(State0),
+ {FloatTestResult, State1} = rand_plugin_aux_floats(State0, FloatGenerator),
+ case FloatTestResult of
+ true ->
+ {IntegerTestResult, _State2} = rand_plugin_aux_integers(State1, IntegerGenerator),
+ IntegerTestResult;
+ {false, _} ->
+ FloatTestResult
+ end.
+
+% returns {Seeder, SeedExporter, FloatGenerator, IntegerGenerator} with consistent signatures
+rand_plugin_functions(implicit_state) ->
+ {fun () -> crypto:rand_seed(), implicit_state end,
+ fun (implicit_state) -> rand:export_seed() end,
+ fun (implicit_state) -> {rand:uniform(), implicit_state} end,
+ fun (N, implicit_state) -> {rand:uniform(N), implicit_state} end};
+rand_plugin_functions(explicit_state) ->
+ {fun crypto:rand_seed_s/0,
+ fun rand:export_seed_s/1,
+ fun rand:uniform_s/1,
+ fun rand:uniform_s/2}.
+
+rand_plugin_aux_floats(State0, FloatGenerator) ->
+ {FloatSamples, State1} =
+ lists:mapfoldl(
+ fun (_, StateAcc) ->
+ FloatGenerator(StateAcc)
+ end,
+ State0,
+ lists:seq(1, 10000)),
+
+ {allmap(
+ fun (V) ->
+ (V >= 0.0 andalso V < 1.0)
+ orelse {false, ct:fail({"Float sample not in interval", V, 0.0, 1.0})}
+ end,
+ FloatSamples),
+ State1}.
+
+rand_plugin_aux_integers(State0, IntegerGenerator) ->
+ MaxIntegerCeiling = 1 bsl 32,
+ {IntegerCeilings, State1} =
+ lists:mapfoldl(
+ fun (_, StateAcc) ->
+ IntegerGenerator(MaxIntegerCeiling, StateAcc)
+ end,
+ State0,
+ lists:seq(1, 100)),
+
+ foldallmap(
+ fun (Ceiling, StateAcc) ->
+ case Ceiling >= 1 andalso Ceiling =< MaxIntegerCeiling of
+ false ->
+ {{false, ct:fail({"Integer ceiling not in interval",
+ Ceiling, 1, MaxIntegerCeiling})},
+ StateAcc};
+ true ->
+ foldallmap(
+ fun (_, SubStateAcc) ->
+ {Sample, NewSubStateAcc} = IntegerGenerator(Ceiling, SubStateAcc),
+ case Sample >= 1 andalso Sample =< Ceiling of
+ false ->
+ {{false, ct:fail({"Integer sample not in interval",
+ Sample, 1, Ceiling})},
+ NewSubStateAcc};
+ true ->
+ {true, NewSubStateAcc}
+ end
+ end,
+ StateAcc,
+ lists:seq(1, 100))
+ end
+ end,
+ State1,
+ IntegerCeilings).
+
%%--------------------------------------------------------------------
%% Test data ------------------------------------------------
%%--------------------------------------------------------------------
@@ -751,13 +1149,25 @@ group_config(rsa = Type, Config) ->
Private = rsa_private(),
PublicS = rsa_public_stronger(),
PrivateS = rsa_private_stronger(),
- SignVerify = sign_verify_tests(Type, Msg, Public, Private, PublicS, PrivateS),
+ SignVerify =
+ case ?config(fips, Config) of
+ true ->
+ %% Use only the strong keys in FIPS mode
+ sign_verify_tests(Type, Msg,
+ PublicS, PrivateS,
+ PublicS, PrivateS);
+ false ->
+ sign_verify_tests(Type, Msg,
+ Public, Private,
+ PublicS, PrivateS)
+ end,
MsgPubEnc = <<"7896345786348 Asldi">>,
- PubPrivEnc = [{rsa, Public, Private, MsgPubEnc, rsa_pkcs1_padding},
- rsa_oaep(),
- no_padding()
- ],
- [{sign_verify, SignVerify}, {pub_priv_encrypt, PubPrivEnc} | Config];
+ PubPrivEnc = [{rsa, PublicS, PrivateS, MsgPubEnc, rsa_pkcs1_padding},
+ rsa_oaep(),
+ no_padding()
+ ],
+ Generate = [{rsa, 1024, 3}, {rsa, 2048, 17}, {rsa, 3072, 65537}],
+ [{sign_verify, SignVerify}, {pub_priv_encrypt, PubPrivEnc}, {generate, Generate} | Config];
group_config(dss = Type, Config) ->
Msg = dss_plain(),
Public = dss_params() ++ [dss_public()],
@@ -792,29 +1202,34 @@ group_config(des3_cbc, Config) ->
group_config(des3_cbf, Config) ->
Block = des3_cbf(),
[{block, Block} | Config];
+group_config(des3_cfb, Config) ->
+ Block = des3_cfb(),
+ [{block, Block} | Config];
group_config(des_ede3, Config) ->
Block = des_ede3(),
[{block, Block} | Config];
group_config(rc2_cbc, Config) ->
Block = rc2_cbc(),
[{block, Block} | Config];
-group_config(aes_cbc128, Config) ->
- Block = aes_cbc128(),
- [{block, Block} | Config];
-group_config(aes_cbc256, Config) ->
- Block = aes_cbc256(),
- [{block, Block} | Config];
+group_config(aes_cbc128 = Type, Config) ->
+ Block = fun() -> aes_cbc128(Config) end,
+ Pairs = fun() -> cmac_nist(Config, Type) end,
+ [{block, Block}, {cmac, Pairs} | Config];
+group_config(aes_cbc256 = Type, Config) ->
+ Block = fun() -> aes_cbc256(Config) end,
+ Pairs = fun() -> cmac_nist(Config, Type) end,
+ [{block, Block}, {cmac, Pairs} | Config];
group_config(aes_ecb, Config) ->
- Block = aes_ecb(),
- [{block, Block} | Config];
+ Block = fun() -> aes_ecb(Config) end,
+ [{block, Block} | Config];
group_config(aes_ige256, Config) ->
Block = aes_ige256(),
[{block, Block} | Config];
group_config(aes_cfb8, Config) ->
- Block = aes_cfb8(),
+ Block = fun() -> aes_cfb8(Config) end,
[{block, Block} | Config];
group_config(aes_cfb128, Config) ->
- Block = aes_cfb128(),
+ Block = fun() -> aes_cfb128(Config) end,
[{block, Block} | Config];
group_config(blowfish_cbc, Config) ->
Block = blowfish_cbc(),
@@ -835,13 +1250,13 @@ group_config(aes_ctr, Config) ->
Stream = aes_ctr(),
[{stream, Stream} | Config];
group_config(aes_gcm, Config) ->
- AEAD = aes_gcm(),
+ AEAD = fun() -> aes_gcm(Config) end,
[{aead, AEAD} | Config];
group_config(chacha20_poly1305, Config) ->
AEAD = chacha20_poly1305(),
[{aead, AEAD} | Config];
group_config(aes_cbc, Config) ->
- Block = aes_cbc(),
+ Block = aes_cbc(Config),
[{block, Block} | Config];
group_config(_, Config) ->
Config.
@@ -927,9 +1342,10 @@ rfc_4634_sha512_digests() ->
long_msg() ->
fun() -> lists:duplicate(1000000, $a) end.
-%% Building huge terms (like long_msg/0) in init_per_group seems to cause
-%% test_server crash with 'no_answer_from_tc_supervisor' sometimes on some
-%% machines. Therefore lazy evaluation when test case has started.
+%% Passing huge terms (like long_msg/0) through config causes excessive memory
+%% consumption and long runtimes in the test server. This results in test_server
+%% crash with 'no_answer_from_tc_supervisor' sometimes on some machines.
+%% Therefore lazy evaluation when test case has started.
lazy_eval(F) when is_function(F) -> F();
lazy_eval(Lst) when is_list(Lst) -> lists:map(fun lazy_eval/1, Lst);
lazy_eval(Tpl) when is_tuple(Tpl) -> list_to_tuple(lists:map(fun lazy_eval/1, tuple_to_list(Tpl)));
@@ -1193,7 +1609,16 @@ des_ede3() ->
des3_cbf() ->
[{des3_cbf,
- [hexstr2bin("0123456789abcdef"),
+ [hexstr2bin("0123456789abcdef"),
+ hexstr2bin("fedcba9876543210"),
+ hexstr2bin("0f2d4b6987a5c3e1")],
+ hexstr2bin("1234567890abcdef"),
+ <<"Now is the time for all ">>
+ }].
+
+des3_cfb() ->
+ [{des3_cfb,
+ [hexstr2bin("0123456789abcdef"),
hexstr2bin("fedcba9876543210"),
hexstr2bin("0f2d4b6987a5c3e1")],
hexstr2bin("1234567890abcdef"),
@@ -1208,209 +1633,30 @@ rc2_cbc() ->
}].
%% AES CBC test vectors from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
-aes_cbc() ->
- [
- %% F.2.1 CBC-AES128.Encrypt, F.2.2 CBC-AES128.Decrypt
- {aes_cbc,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), %% Key
- hexstr2bin("000102030405060708090a0b0c0d0e0f"), %% IV
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a" %% PlainText
- "ae2d8a571e03ac9c9eb76fac45af8e51"
- "30c81c46a35ce411e5fbc1191a0a52ef"
- "f69f2445df4f9b17ad2b417be66c3710"),
- hexstr2bin("7649abac8119b246cee98e9b12e9197d" %% CipherText
- "5086cb9b507219ee95db113a917678b2"
- "73bed6b8e3c1743b7116e69e22229516"
- "3ff1caa1681fac09120eca307586e1a7")},
- %% F.2.3 CBC-AES192.Encrypt, F.2.4 CBC-AES192.Decrypt
- {aes_cbc,
- hexstr2bin("8e73b0f7da0e6452c810f32b809079e5" %% Key
- "62f8ead2522c6b7b"),
- hexstr2bin("000102030405060708090a0b0c0d0e0f"), %% IV
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a" %% PlainText
- "ae2d8a571e03ac9c9eb76fac45af8e51"
- "30c81c46a35ce411e5fbc1191a0a52ef"
- "f69f2445df4f9b17ad2b417be66c3710"),
- hexstr2bin("4f021db243bc633d7178183a9fa071e8" %% CipherText
- "b4d9ada9ad7dedf4e5e738763f69145a"
- "571b242012fb7ae07fa9baac3df102e0"
- "08b0e27988598881d920a9e64f5615cd")},
- %% F.2.5 CBC-AES256.Encrypt, F.2.6 CBC-AES256.Decrypt
- {aes_cbc,
- hexstr2bin("603deb1015ca71be2b73aef0857d7781" %% Key
- "1f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("000102030405060708090a0b0c0d0e0f"), %% IV
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a" %% PlainText
- "ae2d8a571e03ac9c9eb76fac45af8e51"
- "30c81c46a35ce411e5fbc1191a0a52ef"
- "f69f2445df4f9b17ad2b417be66c3710"),
- hexstr2bin("f58c4c04d6e5f1ba779eabfb5f7bfbd6" %% CipherText
- "9cfc4e967edb808d679f777bc6702c7d"
- "39f23369a9d9bacfa530e26304231461"
- "b2eb05e2c39be9fcda6c19078c6a9d1b")}
- ].
-
-aes_cbc128() ->
- [{aes_cbc128,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("000102030405060708090a0b0c0d0e0f"),
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
- {aes_cbc128,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("7649ABAC8119B246CEE98E9B12E9197D"),
- hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
- {aes_cbc128,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("5086CB9B507219EE95DB113A917678B2"),
- hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
- {aes_cbc128,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("73BED6B8E3C1743B7116E69E22229516"),
- hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
- ].
-
-aes_cbc256() ->
- [{aes_cbc256,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("000102030405060708090A0B0C0D0E0F"),
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
- {aes_cbc256,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("F58C4C04D6E5F1BA779EABFB5F7BFBD6"),
- hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
- {aes_cbc256,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("9CFC4E967EDB808D679F777BC6702C7D"),
- hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
- {aes_cbc256,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("39F23369A9D9BACFA530E26304231461"),
- hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
- ].
-
-aes_ecb() ->
- [
- {aes_ecb,
- <<"YELLOW SUBMARINE">>,
- <<"YELLOW SUBMARINE">>},
- {aes_ecb,
- <<"0000000000000000">>,
- <<"0000000000000000">>},
- {aes_ecb,
- <<"FFFFFFFFFFFFFFFF">>,
- <<"FFFFFFFFFFFFFFFF">>},
- {aes_ecb,
- <<"3000000000000000">>,
- <<"1000000000000001">>},
- {aes_ecb,
- <<"1111111111111111">>,
- <<"1111111111111111">>},
- {aes_ecb,
- <<"0123456789ABCDEF">>,
- <<"1111111111111111">>},
- {aes_ecb,
- <<"0000000000000000">>,
- <<"0000000000000000">>},
- {aes_ecb,
- <<"FEDCBA9876543210">>,
- <<"0123456789ABCDEF">>},
- {aes_ecb,
- <<"7CA110454A1A6E57">>,
- <<"01A1D6D039776742">>},
- {aes_ecb,
- <<"0131D9619DC1376E">>,
- <<"5CD54CA83DEF57DA">>},
- {aes_ecb,
- <<"07A1133E4A0B2686">>,
- <<"0248D43806F67172">>},
- {aes_ecb,
- <<"3849674C2602319E">>,
- <<"51454B582DDF440A">>},
- {aes_ecb,
- <<"04B915BA43FEB5B6">>,
- <<"42FD443059577FA2">>},
- {aes_ecb,
- <<"0113B970FD34F2CE">>,
- <<"059B5E0851CF143A">>},
- {aes_ecb,
- <<"0170F175468FB5E6">>,
- <<"0756D8E0774761D2">>},
- {aes_ecb,
- <<"43297FAD38E373FE">>,
- <<"762514B829BF486A">>},
- {aes_ecb,
- <<"07A7137045DA2A16">>,
- <<"3BDD119049372802">>},
- {aes_ecb,
- <<"04689104C2FD3B2F">>,
- <<"26955F6835AF609A">>},
- {aes_ecb,
- <<"37D06BB516CB7546">>,
- <<"164D5E404F275232">>},
- {aes_ecb,
- <<"1F08260D1AC2465E">>,
- <<"6B056E18759F5CCA">>},
- {aes_ecb,
- <<"584023641ABA6176">>,
- <<"004BD6EF09176062">>},
- {aes_ecb,
- <<"025816164629B007">>,
- <<"480D39006EE762F2">>},
- {aes_ecb,
- <<"49793EBC79B3258F">>,
- <<"437540C8698F3CFA">>},
- {aes_ecb,
- <<"018310DC409B26D6">>,
- <<"1D9D5C5018F728C2">>},
- {aes_ecb,
- <<"1C587F1C13924FEF">>,
- <<"305532286D6F295A">>},
- {aes_ecb,
- <<"0101010101010101">>,
- <<"0123456789ABCDEF">>},
- {aes_ecb,
- <<"1F1F1F1F0E0E0E0E">>,
- <<"0123456789ABCDEF">>},
- {aes_ecb,
- <<"E0FEE0FEF1FEF1FE">>,
- <<"0123456789ABCDEF">>},
- {aes_ecb,
- <<"0000000000000000">>,
- <<"FFFFFFFFFFFFFFFF">>},
- {aes_ecb,
- <<"FFFFFFFFFFFFFFFF">>,
- <<"0000000000000000">>},
- {aes_ecb,
- <<"0123456789ABCDEF">>,
- <<"0000000000000000">>},
- {aes_ecb,
- <<"FEDCBA9876543210">>,
- <<"FFFFFFFFFFFFFFFF">>},
- %% AES ECB test vectors from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
- %% F.1.1 ECB-AES128.Encrypt, F.1.2 ECB-AES128.Decrypt
- {aes_ecb,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a"
- "ae2d8a571e03ac9c9eb76fac45af8e51"
- "30c81c46a35ce411e5fbc1191a0a52ef"
- "f69f2445df4f9b17ad2b417be66c3710")},
- %% F.1.3 ECB-AES192.Encrypt, F.1.4 ECB-AES192.Decrypt
- {aes_ecb,
- hexstr2bin("8e73b0f7da0e6452c810f32b809079e5"
- "62f8ead2522c6b7b"),
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a"
- "ae2d8a571e03ac9c9eb76fac45af8e51"
- "30c81c46a35ce411e5fbc1191a0a52ef"
- "f69f2445df4f9b17ad2b417be66c3710")},
- %% F.1.5 ECB-AES256.Encrypt, F.1.6 ECB-AES256.Decrypt
- {aes_ecb,
- hexstr2bin("603deb1015ca71be2b73aef0857d7781"
- "1f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a"
- "ae2d8a571e03ac9c9eb76fac45af8e51"
- "30c81c46a35ce411e5fbc1191a0a52ef"
- "f69f2445df4f9b17ad2b417be66c3710")}
- ].
+aes_cbc(Config) ->
+ read_rsp(Config, aes_cbc,
+ ["CBCVarTxt128.rsp", "CBCVarKey128.rsp", "CBCGFSbox128.rsp", "CBCKeySbox128.rsp",
+ "CBCVarTxt192.rsp", "CBCVarKey192.rsp", "CBCGFSbox192.rsp", "CBCKeySbox192.rsp",
+ "CBCVarTxt256.rsp", "CBCVarKey256.rsp", "CBCGFSbox256.rsp", "CBCKeySbox256.rsp",
+ "CBCMMT128.rsp", "CBCMMT192.rsp", "CBCMMT256.rsp"
+ ]).
+
+aes_cbc128(Config) ->
+ read_rsp(Config, aes_cbc128,
+ ["CBCVarTxt128.rsp", "CBCVarKey128.rsp", "CBCGFSbox128.rsp", "CBCKeySbox128.rsp",
+ "CBCMMT128.rsp"]).
+
+aes_cbc256(Config) ->
+ read_rsp(Config, aes_cbc256,
+ ["CBCVarTxt256.rsp", "CBCVarKey256.rsp", "CBCGFSbox256.rsp", "CBCKeySbox256.rsp",
+ "CBCMMT256.rsp"]).
+
+aes_ecb(Config) ->
+ read_rsp(Config, aes_ecb,
+ ["ECBVarTxt128.rsp", "ECBVarKey128.rsp", "ECBGFSbox128.rsp", "ECBKeySbox128.rsp",
+ "ECBVarTxt192.rsp", "ECBVarKey192.rsp", "ECBGFSbox192.rsp", "ECBKeySbox192.rsp",
+ "ECBVarTxt256.rsp", "ECBVarKey256.rsp", "ECBGFSbox256.rsp", "ECBKeySbox256.rsp",
+ "ECBMMT128.rsp", "ECBMMT192.rsp", "ECBMMT256.rsp"]).
aes_ige256() ->
[{aes_ige256,
@@ -1431,107 +1677,19 @@ aes_ige256() ->
hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
].
-aes_cfb8() ->
- [{aes_cfb8,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("000102030405060708090a0b0c0d0e0f"),
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
- {aes_cfb8,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("3B3FD92EB72DAD20333449F8E83CFB4A"),
- hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
- {aes_cfb8,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("C8A64537A0B3A93FCDE3CDAD9F1CE58B"),
- hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
- {aes_cfb8,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("26751F67A3CBB140B1808CF187A4F4DF"),
- hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")},
- {aes_cfb8,
- hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
- hexstr2bin("000102030405060708090a0b0c0d0e0f"),
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
- {aes_cfb8,
- hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
- hexstr2bin("cdc80d6fddf18cab34c25909c99a4174"),
- hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
- {aes_cfb8,
- hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
- hexstr2bin("67ce7f7f81173621961a2b70171d3d7a"),
- hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
- {aes_cfb8,
- hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
- hexstr2bin("2e1e8a1dd59b88b1c8e60fed1efac4c9"),
- hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")},
- {aes_cfb8,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("000102030405060708090a0b0c0d0e0f"),
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
- {aes_cfb8,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("dc7e84bfda79164b7ecd8486985d3860"),
- hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
- {aes_cfb8,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("39ffed143b28b1c832113c6331e5407b"),
- hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
- {aes_cfb8,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("df10132415e54b92a13ed0a8267ae2f9"),
- hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
- ].
+aes_cfb8(Config) ->
+ read_rsp(Config, aes_cfb8,
+ ["CFB8VarTxt128.rsp", "CFB8VarKey128.rsp", "CFB8GFSbox128.rsp", "CFB8KeySbox128.rsp",
+ "CFB8VarTxt192.rsp", "CFB8VarKey192.rsp", "CFB8GFSbox192.rsp", "CFB8KeySbox192.rsp",
+ "CFB8VarTxt256.rsp", "CFB8VarKey256.rsp", "CFB8GFSbox256.rsp", "CFB8KeySbox256.rsp",
+ "CFB8MMT128.rsp", "CFB8MMT192.rsp", "CFB8MMT256.rsp"]).
-aes_cfb128() ->
- [{aes_cfb128,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("000102030405060708090a0b0c0d0e0f"),
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
- {aes_cfb128,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("3B3FD92EB72DAD20333449F8E83CFB4A"),
- hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
- {aes_cfb128,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("C8A64537A0B3A93FCDE3CDAD9F1CE58B"),
- hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
- {aes_cfb128,
- hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- hexstr2bin("26751F67A3CBB140B1808CF187A4F4DF"),
- hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")},
- {aes_cfb128,
- hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
- hexstr2bin("000102030405060708090a0b0c0d0e0f"),
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
- {aes_cfb128,
- hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
- hexstr2bin("cdc80d6fddf18cab34c25909c99a4174"),
- hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
- {aes_cfb128,
- hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
- hexstr2bin("67ce7f7f81173621961a2b70171d3d7a"),
- hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
- {aes_cfb128,
- hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
- hexstr2bin("2e1e8a1dd59b88b1c8e60fed1efac4c9"),
- hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")},
- {aes_cfb128,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("000102030405060708090a0b0c0d0e0f"),
- hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
- {aes_cfb128,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("dc7e84bfda79164b7ecd8486985d3860"),
- hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
- {aes_cfb128,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("39ffed143b28b1c832113c6331e5407b"),
- hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
- {aes_cfb128,
- hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- hexstr2bin("df10132415e54b92a13ed0a8267ae2f9"),
- hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
- ].
+aes_cfb128(Config) ->
+ read_rsp(Config, aes_cfb128,
+ ["CFB128VarTxt128.rsp", "CFB128VarKey128.rsp", "CFB128GFSbox128.rsp", "CFB128KeySbox128.rsp",
+ "CFB128VarTxt192.rsp", "CFB128VarKey192.rsp", "CFB128GFSbox192.rsp", "CFB128KeySbox192.rsp",
+ "CFB128VarTxt256.rsp", "CFB128VarKey256.rsp", "CFB128GFSbox256.rsp", "CFB128KeySbox256.rsp",
+ "CFB128MMT128.rsp", "CFB128MMT192.rsp", "CFB128MMT256.rsp"]).
blowfish_cbc() ->
[{blowfish_cbc,
@@ -1705,295 +1863,58 @@ aes_ctr() ->
].
-%% AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
-aes_gcm() ->
- [
- %% Test Case 1
- {aes_gcm, hexstr2bin("00000000000000000000000000000000"), %% Key
- hexstr2bin(""), %% PlainText
- hexstr2bin("000000000000000000000000"), %% IV
- hexstr2bin(""), %% AAD
- hexstr2bin(""), %% CipherText
- hexstr2bin("58e2fccefa7e3061367f1d57a4e7455a")}, %% CipherTag
-
- %% Test Case 2
- {aes_gcm, hexstr2bin("00000000000000000000000000000000"), %% Key
- hexstr2bin("00000000000000000000000000000000"), %% PlainText
- hexstr2bin("000000000000000000000000"), %% IV
- hexstr2bin(""), %% AAD
- hexstr2bin("0388dace60b6a392f328c2b971b2fe78"), %% CipherText
- hexstr2bin("ab6e47d42cec13bdf53a67b21257bddf")}, %% CipherTag
-
- %% Test Case 3
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308"), %% Key
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b391aafd255"),
- hexstr2bin("cafebabefacedbaddecaf888"), %% IV
- hexstr2bin(""), %% AAD
- hexstr2bin("42831ec2217774244b7221b784d0d49c" %% CipherText
- "e3aa212f2c02a4e035c17e2329aca12e"
- "21d514b25466931c7d8f6a5aac84aa05"
- "1ba30b396a0aac973d58e091473f5985"),
- hexstr2bin("4d5c2af327cd64a62cf35abd2ba6fab4")}, %% CipherTag
-
- %% Test Case 4
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308"), %% Key
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b39"),
- hexstr2bin("cafebabefacedbaddecaf888"), %% IV
- hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
- "abaddad2"),
- hexstr2bin("42831ec2217774244b7221b784d0d49c" %% CipherText
- "e3aa212f2c02a4e035c17e2329aca12e"
- "21d514b25466931c7d8f6a5aac84aa05"
- "1ba30b396a0aac973d58e091"),
- hexstr2bin("5bc94fbc3221a5db94fae95ae7121a47")}, %% CipherTag
-
- %% Test Case 5
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308"), %% Key
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b39"),
- hexstr2bin("cafebabefacedbad"), %% IV
- hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
- "abaddad2"),
- hexstr2bin("61353b4c2806934a777ff51fa22a4755" %% CipherText
- "699b2a714fcdc6f83766e5f97b6c7423"
- "73806900e49f24b22b097544d4896b42"
- "4989b5e1ebac0f07c23f4598"),
- hexstr2bin("3612d2e79e3b0785561be14aaca2fccb")}, %% CipherTag
-
- %% Test Case 6"
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308"), %% Key
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b39"),
- hexstr2bin("9313225df88406e555909c5aff5269aa" %% IV
- "6a7a9538534f7da1e4c303d2a318a728"
- "c3c0c95156809539fcf0e2429a6b5254"
- "16aedbf5a0de6a57a637b39b"),
- hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
- "abaddad2"),
- hexstr2bin("8ce24998625615b603a033aca13fb894" %% CipherText
- "be9112a5c3a211a8ba262a3cca7e2ca7"
- "01e4a9a4fba43c90ccdcb281d48c7c6f"
- "d62875d2aca417034c34aee5"),
- hexstr2bin("619cc5aefffe0bfa462af43c1699d050")}, %% CipherTag
-
- %% Test Case 7
- {aes_gcm, hexstr2bin("00000000000000000000000000000000" %% Key
- "0000000000000000"),
- hexstr2bin(""), %% PlainText
- hexstr2bin("000000000000000000000000"), %% IV
- hexstr2bin(""), %% AAD
- hexstr2bin(""), %% CipherText
- hexstr2bin("cd33b28ac773f74ba00ed1f312572435")}, %% CipherTag
-
- %% Test Case 8
- {aes_gcm, hexstr2bin("00000000000000000000000000000000" %% Key
- "0000000000000000"),
- hexstr2bin("00000000000000000000000000000000"), %% PlainText
- hexstr2bin("000000000000000000000000"), %% IV
- hexstr2bin(""), %% AAD
- hexstr2bin("98e7247c07f0fe411c267e4384b0f600"), %% CipherText
- hexstr2bin("2ff58d80033927ab8ef4d4587514f0fb")}, %% CipherTag
-
- %% Test Case 9
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
- "feffe9928665731c"),
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b391aafd255"),
- hexstr2bin("cafebabefacedbaddecaf888"), %% IV
- hexstr2bin(""), %% ADD
- hexstr2bin("3980ca0b3c00e841eb06fac4872a2757" %% CipherText
- "859e1ceaa6efd984628593b40ca1e19c"
- "7d773d00c144c525ac619d18c84a3f47"
- "18e2448b2fe324d9ccda2710acade256"),
- hexstr2bin("9924a7c8587336bfb118024db8674a14")}, %% CipherTag
-
- %% Test Case 10
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
- "feffe9928665731c"),
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b39"),
- hexstr2bin("cafebabefacedbaddecaf888"), %% IV
- hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
- "abaddad2"),
- hexstr2bin("3980ca0b3c00e841eb06fac4872a2757" %% CipherText
- "859e1ceaa6efd984628593b40ca1e19c"
- "7d773d00c144c525ac619d18c84a3f47"
- "18e2448b2fe324d9ccda2710"),
- hexstr2bin("2519498e80f1478f37ba55bd6d27618c")}, %% CipherTag
-
- %% Test Case 11
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
- "feffe9928665731c"),
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b39"),
- hexstr2bin("cafebabefacedbad"), %% IV
- hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
- "abaddad2"),
- hexstr2bin("0f10f599ae14a154ed24b36e25324db8" %% CipherText
- "c566632ef2bbb34f8347280fc4507057"
- "fddc29df9a471f75c66541d4d4dad1c9"
- "e93a19a58e8b473fa0f062f7"),
- hexstr2bin("65dcc57fcf623a24094fcca40d3533f8")}, %% CipherTag
-
- %% Test Case 12
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
- "feffe9928665731c"),
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b39"),
- hexstr2bin("9313225df88406e555909c5aff5269aa" %% IV
- "6a7a9538534f7da1e4c303d2a318a728"
- "c3c0c95156809539fcf0e2429a6b5254"
- "16aedbf5a0de6a57a637b39b"),
- hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
- "abaddad2"),
- hexstr2bin("d27e88681ce3243c4830165a8fdcf9ff" %% CipherText
- "1de9a1d8e6b447ef6ef7b79828666e45"
- "81e79012af34ddd9e2f037589b292db3"
- "e67c036745fa22e7e9b7373b"),
- hexstr2bin("dcf566ff291c25bbb8568fc3d376a6d9")}, %% CipherTag
-
- %% Test Case 13
- {aes_gcm, hexstr2bin("00000000000000000000000000000000" %% Key
- "00000000000000000000000000000000"),
- hexstr2bin(""), %% PlainText
- hexstr2bin("000000000000000000000000"), %% IV
- hexstr2bin(""), %% AAD
- hexstr2bin(""), %% CipherText
- hexstr2bin("530f8afbc74536b9a963b4f1c4cb738b")}, %% CipherTag
-
- %% Test Case 14
- {aes_gcm, hexstr2bin("00000000000000000000000000000000" %% Key
- "00000000000000000000000000000000"),
- hexstr2bin("00000000000000000000000000000000"), %% PlainText
- hexstr2bin("000000000000000000000000"), %% IV
- hexstr2bin(""), %% AAD
- hexstr2bin("cea7403d4d606b6e074ec5d3baf39d18"), %% CipherText
- hexstr2bin("d0d1c8a799996bf0265b98b5d48ab919")}, %% CipherTag
-
- %% Test Case 15
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
- "feffe9928665731c6d6a8f9467308308"),
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b391aafd255"),
- hexstr2bin("cafebabefacedbaddecaf888"), %% IV
- hexstr2bin(""), %% AAD
- hexstr2bin("522dc1f099567d07f47f37a32a84427d" %% CipherText
- "643a8cdcbfe5c0c97598a2bd2555d1aa"
- "8cb08e48590dbb3da7b08b1056828838"
- "c5f61e6393ba7a0abcc9f662898015ad"),
- hexstr2bin("b094dac5d93471bdec1a502270e3cc6c")}, %% CipherTag
-
- %% Test Case 16
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
- "feffe9928665731c6d6a8f9467308308"),
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b39"),
- hexstr2bin("cafebabefacedbaddecaf888"), %% IV
- hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
- "abaddad2"),
- hexstr2bin("522dc1f099567d07f47f37a32a84427d" %% CipherText
- "643a8cdcbfe5c0c97598a2bd2555d1aa"
- "8cb08e48590dbb3da7b08b1056828838"
- "c5f61e6393ba7a0abcc9f662"),
- hexstr2bin("76fc6ece0f4e1768cddf8853bb2d551b")}, %% CipherTag
-
- %% Test Case 17
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
- "feffe9928665731c6d6a8f9467308308"),
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b39"),
- hexstr2bin("cafebabefacedbad"), %% IV
- hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
- "abaddad2"),
- hexstr2bin("c3762df1ca787d32ae47c13bf19844cb" %% CipherText
- "af1ae14d0b976afac52ff7d79bba9de0"
- "feb582d33934a4f0954cc2363bc73f78"
- "62ac430e64abe499f47c9b1f"),
- hexstr2bin("3a337dbf46a792c45e454913fe2ea8f2")}, %% CipherTag
-
- %% Test Case 18
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
- "feffe9928665731c6d6a8f9467308308"),
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b39"),
- hexstr2bin("9313225df88406e555909c5aff5269aa" %% IV
- "6a7a9538534f7da1e4c303d2a318a728"
- "c3c0c95156809539fcf0e2429a6b5254"
- "16aedbf5a0de6a57a637b39b"),
- hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
- "abaddad2"),
- hexstr2bin("5a8def2f0c9e53f1f75d7853659e2a20" %% CipherText
- "eeb2b22aafde6419a058ab4f6f746bf4"
- "0fc0c3b780f244452da3ebf1c5d82cde"
- "a2418997200ef82e44ae7e3f"),
- hexstr2bin("a44a8266ee1c8eb0c8b5d4cf5ae9f19a")}, %% CipherTag
-
- %% Test Case 0 for TagLength = 1
- {aes_gcm, hexstr2bin("00000000000000000000000000000000"), %% Key
- hexstr2bin(""), %% PlainText
- hexstr2bin("000000000000000000000000"), %% IV
- hexstr2bin(""), %% AAD
- hexstr2bin(""), %% CipherText
- hexstr2bin("58"), %% CipherTag
- 1}, %% TagLength
-
- %% Test Case 18 for TagLength = 1
- {aes_gcm, hexstr2bin("feffe9928665731c6d6a8f9467308308" %% Key
- "feffe9928665731c6d6a8f9467308308"),
- hexstr2bin("d9313225f88406e5a55909c5aff5269a" %% PlainText
- "86a7a9531534f7da2e4c303d8a318a72"
- "1c3c0c95956809532fcf0e2449a6b525"
- "b16aedf5aa0de657ba637b39"),
- hexstr2bin("9313225df88406e555909c5aff5269aa" %% IV
- "6a7a9538534f7da1e4c303d2a318a728"
- "c3c0c95156809539fcf0e2429a6b5254"
- "16aedbf5a0de6a57a637b39b"),
- hexstr2bin("feedfacedeadbeeffeedfacedeadbeef" %% AAD
- "abaddad2"),
- hexstr2bin("5a8def2f0c9e53f1f75d7853659e2a20" %% CipherText
- "eeb2b22aafde6419a058ab4f6f746bf4"
- "0fc0c3b780f244452da3ebf1c5d82cde"
- "a2418997200ef82e44ae7e3f"),
- hexstr2bin("a4"), %% CipherTag
- 1} %% TagLength
- ].
+aes_gcm(Config) ->
+ read_rsp(Config, aes_gcm,
+ ["gcmDecrypt128.rsp",
+ "gcmDecrypt192.rsp",
+ "gcmDecrypt256.rsp",
+ "gcmEncryptExtIV128.rsp",
+ "gcmEncryptExtIV192.rsp",
+ "gcmEncryptExtIV256.rsp"]).
-%% http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
+%% https://tools.ietf.org/html/rfc7539#appendix-A.5
chacha20_poly1305() ->
[
- {chacha20_poly1305, hexstr2bin("4290bcb154173531f314af57f3be3b500" %% Key
- "6da371ece272afa1b5dbdd1100a1007"),
- hexstr2bin("86d09974840bded2a5ca"), %% PlainText
- hexstr2bin("cd7cf67be39c794a"), %% Nonce
- hexstr2bin("87e229d4500845a079c0"), %% AAD
- hexstr2bin("e3e446f7ede9a19b62a4"), %% CipherText
- hexstr2bin("677dabf4e3d24b876bb284753896e1d6")} %% CipherTag
+ {chacha20_poly1305,
+ hexstr2bin("1c9240a5eb55d38af333888604f6b5f0" %% Key
+ "473917c1402b80099dca5cbc207075c0"),
+ hexstr2bin("496e7465726e65742d44726166747320" %% PlainText
+ "61726520647261667420646f63756d65"
+ "6e74732076616c696420666f72206120"
+ "6d6178696d756d206f6620736978206d"
+ "6f6e74687320616e64206d6179206265"
+ "20757064617465642c207265706c6163"
+ "65642c206f72206f62736f6c65746564"
+ "206279206f7468657220646f63756d65"
+ "6e747320617420616e792074696d652e"
+ "20497420697320696e617070726f7072"
+ "6961746520746f2075736520496e7465"
+ "726e65742d4472616674732061732072"
+ "65666572656e6365206d617465726961"
+ "6c206f7220746f206369746520746865"
+ "6d206f74686572207468616e20617320"
+ "2fe2809c776f726b20696e2070726f67"
+ "726573732e2fe2809d"),
+ hexstr2bin("000000000102030405060708"), %% Nonce
+ hexstr2bin("f33388860000000000004e91"), %% AAD
+ hexstr2bin("64a0861575861af460f062c79be643bd" %% CipherText
+ "5e805cfd345cf389f108670ac76c8cb2"
+ "4c6cfc18755d43eea09ee94e382d26b0"
+ "bdb7b73c321b0100d4f03b7f355894cf"
+ "332f830e710b97ce98c8a84abd0b9481"
+ "14ad176e008d33bd60f982b1ff37c855"
+ "9797a06ef4f0ef61c186324e2b350638"
+ "3606907b6a7c02b0f9f6157b53c867e4"
+ "b9166c767b804d46a59b5216cde7a4e9"
+ "9040c5a40433225ee282a1b0a06c523e"
+ "af4534d7f83fa1155b0047718cbc546a"
+ "0d072b04b3564eea1b422273f548271a"
+ "0bb2316053fa76991955ebd63159434e"
+ "cebb4e466dae5a1073a6727627097a10"
+ "49e617d91d361094fa68f0ff77987130"
+ "305beaba2eda04df997b714d6c6f2c29"
+ "a6ad5cb4022b02709b"),
+ hexstr2bin("eead9d67890cbb22392336fea1851f38")} %% CipherTag
].
rsa_plain() ->
@@ -2281,7 +2202,7 @@ ecdh() ->
TestCases).
dh() ->
- {dh, 0087761979513264537414556992123116644042638206717762626089877284926656954974893442000747478454809111207351620687968672207938731607963470779396984752680274820156266685080223616226905101126463253150237669547023934604953898814222890239130021414026118792251620881355456432549881723310342870016961804255746630219, 2}.
+ {dh, 90970053988169282502023478715631717259407236400413906591937635666709823903223997309250405131675572047545403771567755831138144089197560332757755059848492919215391041119286178688014693040542889497092308638580104031455627238700168892909539193174537248629499995652186913900511641708112112482297874449292467498403, 2}.
rsa_oaep() ->
%% ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt
@@ -2324,9 +2245,17 @@ ecc() ->
end,
TestCases).
+cmac_nist(Config, aes_cbc128 = Type) ->
+ read_rsp(Config, Type,
+ ["CMACGenAES128.rsp", "CMACVerAES128.rsp"]);
+
+cmac_nist(Config, aes_cbc256 = Type) ->
+ read_rsp(Config, Type,
+ ["CMACGenAES256.rsp", "CMACVerAES256.rsp"]).
+
no_padding() ->
- Public = [_, Mod] = rsa_public(),
- Private = rsa_private(),
+ Public = [_, Mod] = rsa_public_stronger(),
+ Private = rsa_private_stronger(),
MsgLen = erlang:byte_size(int_to_bin(Mod)),
Msg = list_to_binary(lists:duplicate(MsgLen, $X)),
{rsa, Public, Private, Msg, rsa_no_padding}.
@@ -2343,3 +2272,123 @@ int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 ->
list_to_binary(Ds);
int_to_bin_neg(X,Ds) ->
int_to_bin_neg(X bsr 8, [(X band 255)|Ds]).
+
+datadir(Config) ->
+ proplists:get_value(data_dir, Config).
+
+-define(KiB, 1024).
+-define(MiB, (1024 * 1024)).
+-define(GiB, (1024 * 1024 * 1024)).
+
+fmt_words(Words) ->
+ BSize = Words * erlang:system_info(wordsize),
+ if BSize < ?KiB ->
+ integer_to_list(BSize);
+ BSize < ?MiB ->
+ io_lib:format("~8.2fKiB (~8w)", [BSize / ?KiB, BSize]);
+ BSize < ?GiB ->
+ io_lib:format("~8.2fMiB (~8w)", [BSize / ?MiB, BSize]);
+ true ->
+ io_lib:format("~8.2fGiB (~8w)", [BSize / ?GiB, BSize])
+ end.
+
+log_rsp_size(Label, Term) ->
+ S = erts_debug:size(Term),
+ ct:pal("~s: ~w test(s), Memory used: ~s",
+ [Label, length(Term), fmt_words(S)]).
+
+read_rsp(Config, Type, Files) ->
+ Tests =
+ lists:foldl(
+ fun(FileName, Acc) ->
+ read_rsp_file(filename:join(datadir(Config), FileName),
+ Type, Acc)
+ end, [], Files),
+ log_rsp_size(Type, Tests),
+ Tests.
+
+read_rsp_file(FileName, Type, Acc) ->
+ {ok, Raw} = file:read_file(FileName),
+ Split = binary:split(Raw, [<<"\r">>, <<"\n">>], [global, trim_all]),
+ parse_rsp(Type, Split, Acc).
+
+parse_rsp(_Type, [], Acc) ->
+ Acc;
+parse_rsp(_Type, [<<"DECRYPT">>|_], Acc) ->
+ Acc;
+%% AES format
+parse_rsp(Type, [<<"COUNT = ", _/binary>>,
+ <<"KEY = ", Key/binary>>,
+ <<"IV = ", IV/binary>>,
+ <<"PLAINTEXT = ", PlainText/binary>>,
+ <<"CIPHERTEXT = ", CipherText/binary>>|Next], Acc) ->
+ parse_rsp(Type, Next, [{Type, hexstr2bin(Key), hexstr2bin(IV),
+ hexstr2bin(PlainText), hexstr2bin(CipherText)}|Acc]);
+%% CMAC format
+parse_rsp(Type, [<<"Count = ", _/binary>>,
+ <<"Klen = ", _/binary>>,
+ <<"Mlen = ", Mlen/binary>>,
+ <<"Tlen = ", Tlen/binary>>,
+ <<"Key = ", Key/binary>>,
+ <<"Msg = ", Msg/binary>>,
+ <<"Mac = ", MAC/binary>>|Rest], Acc) ->
+ case Rest of
+ [<<"Result = P">>|Next] ->
+ parse_rsp_cmac(Type, Key, Msg, Mlen, Tlen, MAC, Next, Acc);
+ [<<"Result = ", _/binary>>|Next] ->
+ parse_rsp(Type, Next, Acc);
+ _ ->
+ parse_rsp_cmac(Type, Key, Msg, Mlen, Tlen, MAC, Rest, Acc)
+ end;
+%% GCM format decode format
+parse_rsp(Type, [<<"Count = ", _/binary>>,
+ <<"Key = ", Key/binary>>,
+ <<"IV = ", IV/binary>>,
+ <<"CT = ", CipherText/binary>>,
+ <<"AAD = ", AAD/binary>>,
+ <<"Tag = ", CipherTag0/binary>>,
+ <<"PT = ", PlainText/binary>>|Next], Acc) ->
+ CipherTag = hexstr2bin(CipherTag0),
+ TestCase = {Type,
+ hexstr2bin(Key),
+ hexstr2bin(PlainText),
+ hexstr2bin(IV),
+ hexstr2bin(AAD),
+ hexstr2bin(CipherText),
+ CipherTag,
+ size(CipherTag)},
+ parse_rsp(Type, Next, [TestCase|Acc]);
+%% GCM format encode format
+parse_rsp(Type, [<<"Count = ", _/binary>>,
+ <<"Key = ", Key/binary>>,
+ <<"IV = ", IV/binary>>,
+ <<"PT = ", PlainText/binary>>,
+ <<"AAD = ", AAD/binary>>,
+ <<"CT = ", CipherText/binary>>,
+ <<"Tag = ", CipherTag0/binary>>|Next], Acc) ->
+ CipherTag = hexstr2bin(CipherTag0),
+ TestCase = {Type,
+ hexstr2bin(Key),
+ hexstr2bin(PlainText),
+ hexstr2bin(IV),
+ hexstr2bin(AAD),
+ hexstr2bin(CipherText),
+ CipherTag,
+ size(CipherTag)},
+ parse_rsp(Type, Next, [TestCase|Acc]);
+
+parse_rsp(Type, [_|Next], Acc) ->
+ parse_rsp(Type, Next, Acc).
+
+parse_rsp_cmac(Type, Key0, Msg0, Mlen0, Tlen, MAC0, Next, Acc) ->
+ Key = hexstr2bin(Key0),
+ Mlen = binary_to_integer(Mlen0),
+ <<Msg:Mlen/bytes, _/binary>> = hexstr2bin(Msg0),
+ MAC = hexstr2bin(MAC0),
+
+ case binary_to_integer(Tlen) of
+ 0 ->
+ parse_rsp(Type, Next, [{Type, Key, Msg, MAC}|Acc]);
+ I ->
+ parse_rsp(Type, Next, [{Type, Key, Msg, I, MAC}|Acc])
+ end.
diff --git a/lib/crypto/test/crypto_SUITE_data/KAT_AES.zip b/lib/crypto/test/crypto_SUITE_data/KAT_AES.zip
new file mode 100644
index 0000000000..128a74c52e
--- /dev/null
+++ b/lib/crypto/test/crypto_SUITE_data/KAT_AES.zip
Binary files differ
diff --git a/lib/crypto/test/crypto_SUITE_data/aesmmt.zip b/lib/crypto/test/crypto_SUITE_data/aesmmt.zip
new file mode 100644
index 0000000000..5024de1d06
--- /dev/null
+++ b/lib/crypto/test/crypto_SUITE_data/aesmmt.zip
Binary files differ
diff --git a/lib/crypto/test/crypto_SUITE_data/cmactestvectors.zip b/lib/crypto/test/crypto_SUITE_data/cmactestvectors.zip
new file mode 100644
index 0000000000..0d52444e57
--- /dev/null
+++ b/lib/crypto/test/crypto_SUITE_data/cmactestvectors.zip
Binary files differ
diff --git a/lib/crypto/test/crypto_SUITE_data/gcmtestvectors.zip b/lib/crypto/test/crypto_SUITE_data/gcmtestvectors.zip
new file mode 100644
index 0000000000..81eaa6c2f0
--- /dev/null
+++ b/lib/crypto/test/crypto_SUITE_data/gcmtestvectors.zip
Binary files differ
diff --git a/lib/crypto/test/old_crypto_SUITE.erl b/lib/crypto/test/old_crypto_SUITE.erl
deleted file mode 100644
index 0d97290d10..0000000000
--- a/lib/crypto/test/old_crypto_SUITE.erl
+++ /dev/null
@@ -1,2309 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(old_crypto_SUITE).
-
--include_lib("common_test/include/ct.hrl").
-
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2,
- init_per_testcase/2,
- end_per_testcase/2,
- info/1,
- link_test/1,
- md5/1,
- md5_update/1,
- md4/1,
- md4_update/1,
- sha/1,
- sha_update/1,
- hmac_update_sha/1,
- hmac_update_sha_n/1,
- hmac_update_sha256/1,
- hmac_update_sha512/1,
- hmac_update_md5/1,
- hmac_update_md5_io/1,
- hmac_update_md5_n/1,
- hmac_rfc2202/1,
- hmac_rfc4231_sha224/1,
- hmac_rfc4231_sha256/1,
- hmac_rfc4231_sha384/1,
- hmac_rfc4231_sha512/1,
- ripemd160/1,
- ripemd160_update/1,
- sha256/1,
- sha256_update/1,
- sha512/1,
- sha512_update/1,
- md5_mac/1,
- md5_mac_io/1,
- des_cbc/1,
- des_cbc_iter/1,
- des_cfb/1,
- des_cfb_iter/1,
- des_ecb/1,
- des3_cbc/1,
- des3_cfb/1,
- rc2_cbc/1,
- aes_cfb/1,
- aes_cbc/1,
- aes_cbc_iter/1,
- aes_ctr/1,
- aes_ctr_stream/1,
- mod_exp_test/1,
- rand_uniform_test/1,
- strong_rand_test/1,
- rsa_verify_test/1,
- dsa_verify_test/1,
- rsa_sign_test/1,
- rsa_sign_hash_test/1,
- dsa_sign_test/1,
- dsa_sign_hash_test/1,
- rsa_encrypt_decrypt/1,
- dh/1,
- srp3/1, srp6/1, srp6a/1,
- ec/1,
- exor_test/1,
- rc4_test/1,
- rc4_stream_test/1,
- blowfish_cfb64/1,
- smp/1]).
-
--export([hexstr2bin/1]).
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- [link_test, {group, info}].
-
-groups() ->
- [{info, [sequence],[info, {group, rest}]},
- {rest, [],
- [md5, md5_update, md4, md4_update, md5_mac,
- md5_mac_io, ripemd160, ripemd160_update, sha, sha_update,
- sha256, sha256_update, sha512, sha512_update,
- hmac_update_sha, hmac_update_sha_n, hmac_update_sha256, hmac_update_sha512,
- hmac_update_md5_n, hmac_update_md5_io, hmac_update_md5,
- hmac_rfc2202, hmac_rfc4231_sha224, hmac_rfc4231_sha256,
- hmac_rfc4231_sha384, hmac_rfc4231_sha512,
- des_cbc, aes_cfb, aes_cbc,
- des_cfb, des_cfb_iter, des3_cbc, des3_cfb, rc2_cbc,
- aes_cbc_iter, aes_ctr, aes_ctr_stream, des_cbc_iter, des_ecb,
- rand_uniform_test, strong_rand_test,
- rsa_verify_test, dsa_verify_test, rsa_sign_test,
- rsa_sign_hash_test, dsa_sign_test, dsa_sign_hash_test,
- rsa_encrypt_decrypt, dh, srp3, srp6, srp6a, ec, exor_test,
- rc4_test, rc4_stream_test, mod_exp_test, blowfish_cfb64,
- smp]}].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-init_per_testcase(info, Config) ->
- Config;
-init_per_testcase(_Name,Config) ->
- io:format("init_per_testcase\n"),
- ?line crypto:start(),
- Config.
-
-end_per_testcase(info, Config) ->
- Config;
-end_per_testcase(_Name,Config) ->
- io:format("end_per_testcase\n"),
- ?line crypto:stop(),
- Config.
-
-%%
-%%
-link_test(doc) ->
- ["Test that the library is statically linked to libcrypto.a."];
-link_test(suite) ->
- [];
-link_test(Config) when is_list(Config) ->
- ?line case os:type() of
- {unix,darwin} -> {skipped,"Darwin cannot link statically"};
- {unix,_} -> link_test_1();
- _ -> {skip,"Only runs on Unix"}
- end.
-
-link_test_1() ->
- ?line CryptoPriv = code:priv_dir(crypto),
- ?line Wc = filename:join([CryptoPriv,"lib","crypto.*"]),
- ?line case filelib:wildcard(Wc) of
- [] -> {skip,"Didn't find the crypto driver"};
- [Drv] -> link_test_2(Drv)
- end.
-
-link_test_2(Drv) ->
- case ldd_program() of
- none ->
- {skip,"No ldd-like program found"};
- Ldd ->
- Cmd = Ldd ++ " " ++ Drv,
- Libs = os:cmd(Cmd),
- io:format("~p\n", [Libs]),
- case string:str(Libs, "libcrypto") of
- 0 ->
- case ?t:is_commercial() of
- true ->
- ?t:fail({libcrypto,statically_linked});
- false ->
- {comment,"Statically linked (OK for open-source platform)"}
- end;
- _ ->
- ok
- end
- end.
-
-ldd_program() ->
- case os:find_executable("ldd") of
- false ->
- case os:type() of
- {unix,darwin} ->
- case os:find_executable("otool") of
- false -> none;
- Otool -> Otool ++ " -L"
- end;
- _ ->
- none
- end;
- Ldd when is_list(Ldd) -> Ldd
- end.
-
-
-
-info(doc) ->
- ["Call the info function."];
-info(suite) ->
- [];
-info(Config) when is_list(Config) ->
- case {code:lib_dir(crypto),?t:is_commercial()} of
- {{error,bad_name},false} ->
- {skip,"Missing crypto application"};
- {_,_} ->
- ?line crypto:start(),
- ?line Info = crypto:info(),
- ?line Exports = lists:usort([F || {F,_} <- crypto:module_info(exports)]),
- ?line [] = Info -- Exports,
- ?line NotInInfo = Exports -- Info,
- io:format("NotInInfo = ~p\n", [NotInInfo]),
- %% BlackList = lists:sort([des_ede3_cbc_decrypt, des_ede3_cbc_encrypt,
- %% dh_check, dh_generate_parameters,
- %% module_info, start, stop, version]),
- %% ?line BlackList = NotInInfo,
-
- ?line InfoLib = crypto:info_lib(),
- ?line [_|_] = InfoLib,
- F = fun([{Name,VerN,VerS}|T],Me) ->
- ?line true = is_binary(Name),
- ?line true = is_integer(VerN),
- ?line true = is_binary(VerS),
- Me(T,Me);
- ([],_) ->
- ok
- end,
- ?line F(InfoLib,F),
- ?line crypto:stop()
- end.
-
-%%
-%%
-md5(doc) ->
- ["Generate MD5 message digests and check the result. Examples are "
- "from RFC-1321."];
-md5(suite) ->
- [];
-md5(Config) when is_list(Config) ->
- ?line m(crypto:md5(""),
- hexstr2bin("d41d8cd98f00b204e9800998ecf8427e")),
- ?line m(crypto:md5("a"),
- hexstr2bin("0cc175b9c0f1b6a831c399e269772661")),
- ?line m(crypto:md5("abc"),
- hexstr2bin("900150983cd24fb0d6963f7d28e17f72")),
- ?line m(crypto:md5("message digest"),
- hexstr2bin("f96b697d7cb7938d525a2f31aaf161d0")),
- ?line m(crypto:md5("abcdefghijklmnopqrstuvwxyz"),
- hexstr2bin("c3fcd3d76192e4007dfb496cca67e13b")),
- ?line m(crypto:md5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
- "0123456789"),
- hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f")),
- ?line m(crypto:md5("12345678901234567890123456789012345678901234567890"
- "123456789012345678901234567890"),
- hexstr2bin("57edf4a22be3c955ac49da2e2107b67a")).
-
-%%
-%%
-md5_update(doc) ->
- ["Generate MD5 message using md5_init, md5_update, and md5_final, and"
- "check the result. Examples are from RFC-1321."];
-md5_update(suite) ->
- [];
-md5_update(Config) when is_list(Config) ->
- ?line Ctx = crypto:md5_init(),
- ?line Ctx1 = crypto:md5_update(Ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
- ?line Ctx2 = crypto:md5_update(Ctx1, "abcdefghijklmnopqrstuvwxyz"
- "0123456789"),
- ?line m(crypto:md5_final(Ctx2),
- hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f")).
-
-%%
-%%
-md4(doc) ->
- ["Generate MD4 message digests and check the result. Examples are "
- "from RFC-1321."];
-md4(suite) ->
- [];
-md4(Config) when is_list(Config) ->
- ?line m(crypto:md4(""),
- hexstr2bin("31d6cfe0d16ae931b73c59d7e0c089c0")),
- ?line m(crypto:md4("a"),
- hexstr2bin("bde52cb31de33e46245e05fbdbd6fb24")),
- ?line m(crypto:md4("abc"),
- hexstr2bin("a448017aaf21d8525fc10ae87aa6729d")),
- ?line m(crypto:md4("message digest"),
- hexstr2bin("d9130a8164549fe818874806e1c7014b")),
- ?line m(crypto:md4("abcdefghijklmnopqrstuvwxyz"),
- hexstr2bin("d79e1c308aa5bbcdeea8ed63df412da9")),
- ?line m(crypto:md4("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
- "0123456789"),
- hexstr2bin("043f8582f241db351ce627e153e7f0e4")),
- ?line m(crypto:md4("12345678901234567890123456789012345678901234567890"
- "123456789012345678901234567890"),
- hexstr2bin("e33b4ddc9c38f2199c3e7b164fcc0536")).
-
-%%
-%%
-md4_update(doc) ->
- ["Generate MD5 message using md5_init, md5_update, and md5_final, and"
- "check the result. Examples are from RFC-1321."];
-md4_update(suite) ->
- [];
-md4_update(Config) when is_list(Config) ->
- ?line Ctx = crypto:md4_init(),
- ?line Ctx1 = crypto:md4_update(Ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
- ?line Ctx2 = crypto:md4_update(Ctx1, "abcdefghijklmnopqrstuvwxyz"
- "0123456789"),
- ?line m(crypto:md4_final(Ctx2),
- hexstr2bin("043f8582f241db351ce627e153e7f0e4")).
-
-%%
-%%
-sha(doc) ->
- ["Generate SHA message digests and check the result. Examples are "
- "from FIPS-180-1."];
-sha(suite) ->
- [];
-sha(Config) when is_list(Config) ->
- ?line m(crypto:sha("abc"),
- hexstr2bin("A9993E364706816ABA3E25717850C26C9CD0D89D")),
- ?line m(crypto:sha("abcdbcdecdefdefgefghfghighijhijkijkljklmklm"
- "nlmnomnopnopq"),
- hexstr2bin("84983E441C3BD26EBAAE4AA1F95129E5E54670F1")).
-
-
-%%
-hmac_update_sha_n(doc) ->
- ["Request a larger-than-allowed SHA1 HMAC using hmac_init, hmac_update, and hmac_final_n. "
- "Expected values for examples are generated using crypto:sha_mac." ];
-hmac_update_sha_n(suite) ->
- [];
-hmac_update_sha_n(Config) when is_list(Config) ->
- ?line Key = hexstr2bin("00010203101112132021222330313233"
- "04050607141516172425262734353637"
- "08090a0b18191a1b28292a2b38393a3b"
- "0c0d0e0f1c1d1e1f2c2d2e2f3c3d3e3f"),
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(sha, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final_n(Ctx3, 1024),
- ?line Exp = crypto:sha_mac(Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac),
- ?line m(size(Exp), size(Mac)).
-
-
-hmac_update_sha(doc) ->
- ["Generate an SHA1 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:sha_mac." ];
-hmac_update_sha(suite) ->
- [];
-hmac_update_sha(Config) when is_list(Config) ->
- ?line Key = hexstr2bin("00010203101112132021222330313233"
- "04050607141516172425262734353637"
- "08090a0b18191a1b28292a2b38393a3b"
- "0c0d0e0f1c1d1e1f2c2d2e2f3c3d3e3f"),
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(sha, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final(Ctx3),
- ?line Exp = crypto:hmac(sha, Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac).
-
-hmac_update_sha256(doc) ->
- ["Generate an SHA256 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:sha256_mac." ];
-hmac_update_sha256(suite) ->
- [];
-hmac_update_sha256(Config) when is_list(Config) ->
- if_supported(sha256, fun() -> hmac_update_sha256_do() end).
-
-hmac_update_sha256_do() ->
- ?line Key = hexstr2bin("00010203101112132021222330313233"
- "04050607141516172425262734353637"
- "08090a0b18191a1b28292a2b38393a3b"
- "0c0d0e0f1c1d1e1f2c2d2e2f3c3d3e3f"),
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(sha256, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final(Ctx3),
- ?line Exp = crypto:hmac(sha256, Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac).
-
-hmac_update_sha512(doc) ->
- ["Generate an SHA512 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:sha512_mac." ];
-hmac_update_sha512(suite) ->
- [];
-hmac_update_sha512(Config) when is_list(Config) ->
- if_supported(sha512, fun() -> hmac_update_sha512_do() end).
-
-hmac_update_sha512_do() ->
- ?line Key = hexstr2bin("00010203101112132021222330313233"
- "04050607141516172425262734353637"
- "08090a0b18191a1b28292a2b38393a3b"
- "0c0d0e0f1c1d1e1f2c2d2e2f3c3d3e3f"),
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(sha512, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final(Ctx3),
- ?line Exp = crypto:hmac(sha512, Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac).
-
-hmac_update_md5(doc) ->
- ["Generate an MD5 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:md5_mac." ];
-hmac_update_md5(suite) ->
- [];
-hmac_update_md5(Config) when is_list(Config) ->
- % ?line Key2 = ["A fine speach", "by a fine man!"],
- Key2 = "A fine speach by a fine man!",
- ?line Long1 = "Four score and seven years ago our fathers brought forth on this continent a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal.",
- ?line Long2 = "Now we are engaged in a great civil war, testing whether that nation, or any nation, so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.",
- ?line Long3 = "But, in a larger sense, we can not dedicate, we can not consecrate, we can not hallow this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us-that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion that we here highly resolve that these dead shall not have died in vain-that this nation, under God, shall have a new birth of freedom-and that government of the people, by the people, for the people, shall not perish from the earth.",
- ?line CtxA = crypto:hmac_init(md5, Key2),
- ?line CtxB = crypto:hmac_update(CtxA, Long1),
- ?line CtxC = crypto:hmac_update(CtxB, Long2),
- ?line CtxD = crypto:hmac_update(CtxC, Long3),
- ?line Mac2 = crypto:hmac_final(CtxD),
- ?line Exp2 = crypto:md5_mac(Key2, lists:flatten([Long1, Long2, Long3])),
- ?line m(Exp2, Mac2).
-
-hmac_rfc2202(doc) ->
- ["Generate an HMAC using hmac, md5_mac, and sha_mac."
- "Test vectors are taken from RFC-2202."];
-hmac_rfc2202(suite) ->
- [];
-hmac_rfc2202(Config) when is_list(Config) ->
- hmac_rfc2202_md5(),
- hmac_rfc2202_sha().
-
-hmac_rfc2202_md5() ->
- %% Test case 1
- Case1Key = binary:copy(<<16#0b>>, 16),
- Case1Data = <<"Hi There">>,
- Case1Exp = hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d"),
-
- ?line Case1Mac_1 = crypto:md5_mac(Case1Key, Case1Data),
- ?line Case1Mac_2 = crypto:hmac(md5, Case1Key, Case1Data),
- ?line m(Case1Exp, Case1Mac_1),
- ?line m(Case1Exp, Case1Mac_2),
-
- %% Test case 2
- Case2Key = <<"Jefe">>,
- Case2Data = <<"what do ya want for nothing?">>,
- Case2Exp = hexstr2bin("750c783e6ab0b503eaa86e310a5db738"),
-
- ?line Case2Mac_1 = crypto:md5_mac(Case2Key, Case2Data),
- ?line Case2Mac_2 = crypto:hmac(md5, Case2Key, Case2Data),
- ?line m(Case2Exp, Case2Mac_1),
- ?line m(Case2Exp, Case2Mac_2),
-
- %% Test case 3
- Case3Key = binary:copy(<<16#aa>>, 16),
- Case3Data = binary:copy(<<16#dd>>, 50),
- Case3Exp = hexstr2bin("56be34521d144c88dbb8c733f0e8b3f6"),
-
- ?line Case3Mac_1 = crypto:md5_mac(Case3Key, Case3Data),
- ?line Case3Mac_2 = crypto:hmac(md5, Case3Key, Case3Data),
- ?line m(Case3Exp, Case3Mac_1),
- ?line m(Case3Exp, Case3Mac_2),
-
- %% Test case 4
- Case4Key = list_to_binary(lists:seq(1, 16#19)),
- Case4Data = binary:copy(<<16#cd>>, 50),
- Case4Exp = hexstr2bin("697eaf0aca3a3aea3a75164746ffaa79"),
-
- ?line Case4Mac_1 = crypto:md5_mac(Case4Key, Case4Data),
- ?line Case4Mac_2 = crypto:hmac(md5, Case4Key, Case4Data),
- ?line m(Case4Exp, Case4Mac_1),
- ?line m(Case4Exp, Case4Mac_2),
-
- %% Test case 5
- Case5Key = binary:copy(<<16#0c>>, 16),
- Case5Data = "Test With Truncation",
- Case5Exp = hexstr2bin("56461ef2342edc00f9bab995690efd4c"),
- Case5Exp96 = hexstr2bin("56461ef2342edc00f9bab995"),
-
- ?line Case5Mac_1 = crypto:md5_mac(Case5Key, Case5Data),
- ?line Case5Mac_2 = crypto:hmac(md5, Case5Key, Case5Data),
- ?line Case5Mac96_1 = crypto:md5_mac_96(Case5Key, Case5Data),
- ?line Case5Mac96_2 = crypto:hmac(md5, Case5Key, Case5Data, 12),
- ?line m(Case5Exp, Case5Mac_1),
- ?line m(Case5Exp, Case5Mac_2),
- ?line m(Case5Exp96, Case5Mac96_1),
- ?line m(Case5Exp96, Case5Mac96_2),
-
- %% Test case 6
- Case6Key = binary:copy(<<16#aa>>, 80),
- Case6Data = <<"Test Using Larger Than Block-Size Key - Hash Key First">>,
- Case6Exp = hexstr2bin("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd"),
-
- ?line Case6Mac_1 = crypto:md5_mac(Case6Key, Case6Data),
- ?line Case6Mac_2 = crypto:hmac(md5, Case6Key, Case6Data),
- ?line m(Case6Exp, Case6Mac_1),
- ?line m(Case6Exp, Case6Mac_2),
-
- %% Test case 7
- Case7Key = binary:copy(<<16#aa>>, 80),
- Case7Data = <<"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data">>,
- Case7Exp = hexstr2bin("6f630fad67cda0ee1fb1f562db3aa53e"),
-
- ?line Case7Mac_1 = crypto:md5_mac(Case7Key, Case7Data),
- ?line Case7Mac_2 = crypto:hmac(md5, Case7Key, Case7Data),
- ?line m(Case7Exp, Case7Mac_1),
- ?line m(Case7Exp, Case7Mac_2).
-
-hmac_rfc2202_sha() ->
- %% Test case 1
- Case1Key = binary:copy(<<16#0b>>, 20),
- Case1Data = <<"Hi There">>,
- Case1Exp = hexstr2bin("b617318655057264e28bc0b6fb378c8ef146be00"),
-
- ?line Case1Mac_1 = crypto:sha_mac(Case1Key, Case1Data),
- ?line Case1Mac_2 = crypto:hmac(sha, Case1Key, Case1Data),
- ?line m(Case1Exp, Case1Mac_1),
- ?line m(Case1Exp, Case1Mac_2),
-
- %% Test case 2
- Case2Key = <<"Jefe">>,
- Case2Data = <<"what do ya want for nothing?">>,
- Case2Exp = hexstr2bin("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"),
-
- ?line Case2Mac_1 = crypto:sha_mac(Case2Key, Case2Data),
- ?line Case2Mac_2 = crypto:hmac(sha, Case2Key, Case2Data),
- ?line m(Case2Exp, Case2Mac_1),
- ?line m(Case2Exp, Case2Mac_2),
-
- %% Test case 3
- Case3Key = binary:copy(<<16#aa>>, 20),
- Case3Data = binary:copy(<<16#dd>>, 50),
- Case3Exp = hexstr2bin("125d7342b9ac11cd91a39af48aa17b4f63f175d3"),
-
- ?line Case3Mac_1 = crypto:sha_mac(Case3Key, Case3Data),
- ?line Case3Mac_2 = crypto:hmac(sha, Case3Key, Case3Data),
- ?line m(Case3Exp, Case3Mac_1),
- ?line m(Case3Exp, Case3Mac_2),
-
- %% Test case 4
- Case4Key = list_to_binary(lists:seq(1, 16#19)),
- Case4Data = binary:copy(<<16#cd>>, 50),
- Case4Exp = hexstr2bin("4c9007f4026250c6bc8414f9bf50c86c2d7235da"),
-
- ?line Case4Mac_1 = crypto:sha_mac(Case4Key, Case4Data),
- ?line Case4Mac_2 = crypto:hmac(sha, Case4Key, Case4Data),
- ?line m(Case4Exp, Case4Mac_1),
- ?line m(Case4Exp, Case4Mac_2),
-
- %% Test case 5
- Case5Key = binary:copy(<<16#0c>>, 20),
- Case5Data = "Test With Truncation",
- Case5Exp = hexstr2bin("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04"),
- Case5Exp96 = hexstr2bin("4c1a03424b55e07fe7f27be1"),
-
- ?line Case5Mac_1 = crypto:sha_mac(Case5Key, Case5Data),
- ?line Case5Mac_2 = crypto:hmac(sha, Case5Key, Case5Data),
- ?line Case5Mac96_1 = crypto:sha_mac_96(Case5Key, Case5Data),
- ?line Case5Mac96_2 = crypto:hmac(sha, Case5Key, Case5Data, 12),
- ?line m(Case5Exp, Case5Mac_1),
- ?line m(Case5Exp, Case5Mac_2),
- ?line m(Case5Exp96, Case5Mac96_1),
- ?line m(Case5Exp96, Case5Mac96_2),
-
- %% Test case 6
- Case6Key = binary:copy(<<16#aa>>, 80),
- Case6Data = <<"Test Using Larger Than Block-Size Key - Hash Key First">>,
- Case6Exp = hexstr2bin("aa4ae5e15272d00e95705637ce8a3b55ed402112"),
-
- ?line Case6Mac_1 = crypto:sha_mac(Case6Key, Case6Data),
- ?line Case6Mac_2 = crypto:hmac(sha, Case6Key, Case6Data),
- ?line m(Case6Exp, Case6Mac_1),
- ?line m(Case6Exp, Case6Mac_2),
-
- %% Test case 7
- Case7Key = binary:copy(<<16#aa>>, 80),
- Case7Data = <<"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data">>,
- Case7Exp = hexstr2bin("e8e99d0f45237d786d6bbaa7965c7808bbff1a91"),
-
- ?line Case7Mac_1 = crypto:sha_mac(Case7Key, Case7Data),
- ?line Case7Mac_2 = crypto:hmac(sha, Case7Key, Case7Data),
- ?line m(Case7Exp, Case7Mac_1),
- ?line m(Case7Exp, Case7Mac_2).
-
-hmac_rfc4231_sha224(doc) ->
- ["Generate an HMAC using crypto:sha224_mac, hmac, and hmac_init, hmac_update, and hmac_final. "
- "Testvectors are take from RFC4231." ];
-hmac_rfc4231_sha224(suite) ->
- [];
-hmac_rfc4231_sha224(Config) when is_list(Config) ->
- if_supported(sha224, fun() -> hmac_rfc4231_sha224_do() end).
-
-hmac_rfc4231_sha256(doc) ->
- ["Generate an HMAC using crypto:sha256_mac, hmac, and hmac_init, hmac_update, and hmac_final. "
- "Testvectors are take from RFC4231." ];
-hmac_rfc4231_sha256(suite) ->
- [];
-hmac_rfc4231_sha256(Config) when is_list(Config) ->
- if_supported(sha256, fun() -> hmac_rfc4231_sha256_do() end).
-
-hmac_rfc4231_sha384(doc) ->
- ["Generate an HMAC using crypto:sha384_mac, hmac, and hmac_init, hmac_update, and hmac_final. "
- "Testvectors are take from RFC4231." ];
-hmac_rfc4231_sha384(suite) ->
- [];
-hmac_rfc4231_sha384(Config) when is_list(Config) ->
- if_supported(sha384, fun() -> hmac_rfc4231_sha384_do() end).
-
-hmac_rfc4231_sha512(doc) ->
- ["Generate an HMAC using crypto:sha512_mac, hmac, and hmac_init, hmac_update, and hmac_final. "
- "Testvectors are take from RFC4231." ];
-hmac_rfc4231_sha512(suite) ->
- [];
-hmac_rfc4231_sha512(Config) when is_list(Config) ->
- if_supported(sha512, fun() -> hmac_rfc4231_sha512_do() end).
-
-hmac_rfc4231_case(Hash, case1, Exp) ->
- %% Test 1
- Key = binary:copy(<<16#0b>>, 20),
- Data = <<"Hi There">>,
- hmac_rfc4231_case(Hash, Key, Data, Exp);
-
-hmac_rfc4231_case(Hash, case2, Exp) ->
- %% Test 2
- Key = <<"Jefe">>,
- Data = <<"what do ya want for nothing?">>,
- hmac_rfc4231_case(Hash, Key, Data, Exp);
-
-hmac_rfc4231_case(Hash, case3, Exp) ->
- %% Test 3
- Key = binary:copy(<<16#aa>>, 20),
- Data = binary:copy(<<16#dd>>, 50),
- hmac_rfc4231_case(Hash, Key, Data, Exp);
-
-hmac_rfc4231_case(Hash, case4, Exp) ->
- %% Test 4
- Key = list_to_binary(lists:seq(1, 16#19)),
- Data = binary:copy(<<16#cd>>, 50),
- hmac_rfc4231_case(Hash, Key, Data, Exp);
-
-hmac_rfc4231_case(Hash, case5, Exp) ->
- %% Test 5
- Key = binary:copy(<<16#0c>>, 20),
- Data = <<"Test With Truncation">>,
- hmac_rfc4231_case(Hash, Key, Data, 16, Exp);
-
-hmac_rfc4231_case(Hash, case6, Exp) ->
- %% Test 6
- Key = binary:copy(<<16#aa>>, 131),
- Data = <<"Test Using Larger Than Block-Size Key - Hash Key First">>,
- hmac_rfc4231_case(Hash, Key, Data, Exp);
-
-hmac_rfc4231_case(Hash, case7, Exp) ->
- %% Test Case 7
- Key = binary:copy(<<16#aa>>, 131),
- Data = <<"This is a test using a larger than block-size key and a larger t",
- "han block-size data. The key needs to be hashed before being use",
- "d by the HMAC algorithm.">>,
- hmac_rfc4231_case(Hash, Key, Data, Exp).
-
-hmac_rfc4231_case(Hash, Key, Data, Exp) ->
- ?line Ctx = crypto:hmac_init(Hash, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Mac1 = crypto:hmac_final(Ctx2),
- ?line Mac3 = crypto:hmac(Hash, Key, Data),
- ?line m(Exp, Mac1),
- ?line m(Exp, Mac3).
-
-hmac_rfc4231_case(Hash, Key, Data, Trunc, Exp) ->
- ?line Ctx = crypto:hmac_init(Hash, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Mac1 = crypto:hmac_final_n(Ctx2, Trunc),
- ?line Mac3 = crypto:hmac(Hash, Key, Data, Trunc),
- ?line m(Exp, Mac1),
- ?line m(Exp, Mac3).
-
-hmac_rfc4231_sha224_do() ->
- Case1 = hexstr2bin("896fb1128abbdf196832107cd49df33f"
- "47b4b1169912ba4f53684b22"),
- Case2 = hexstr2bin("a30e01098bc6dbbf45690f3a7e9e6d0f"
- "8bbea2a39e6148008fd05e44"),
- Case3 = hexstr2bin("7fb3cb3588c6c1f6ffa9694d7d6ad264"
- "9365b0c1f65d69d1ec8333ea"),
- Case4 = hexstr2bin("6c11506874013cac6a2abc1bb382627c"
- "ec6a90d86efc012de7afec5a"),
- Case5 = hexstr2bin("0e2aea68a90c8d37c988bcdb9fca6fa8"),
- Case6 = hexstr2bin("95e9a0db962095adaebe9b2d6f0dbce2"
- "d499f112f2d2b7273fa6870e"),
- Case7 = hexstr2bin("3a854166ac5d9f023f54d517d0b39dbd"
- "946770db9c2b95c9f6f565d1"),
- hmac_rfc4231_cases_do(sha224, [Case1, Case2, Case3, Case4, Case5, Case6, Case7]).
-
-hmac_rfc4231_sha256_do() ->
- Case1 = hexstr2bin("b0344c61d8db38535ca8afceaf0bf12b"
- "881dc200c9833da726e9376c2e32cff7"),
- Case2 = hexstr2bin("5bdcc146bf60754e6a042426089575c7"
- "5a003f089d2739839dec58b964ec3843"),
- Case3 = hexstr2bin("773ea91e36800e46854db8ebd09181a7"
- "2959098b3ef8c122d9635514ced565fe"),
- Case4 = hexstr2bin("82558a389a443c0ea4cc819899f2083a"
- "85f0faa3e578f8077a2e3ff46729665b"),
- Case5 = hexstr2bin("a3b6167473100ee06e0c796c2955552b"),
- Case6 = hexstr2bin("60e431591ee0b67f0d8a26aacbf5b77f"
- "8e0bc6213728c5140546040f0ee37f54"),
- Case7 = hexstr2bin("9b09ffa71b942fcb27635fbcd5b0e944"
- "bfdc63644f0713938a7f51535c3a35e2"),
- hmac_rfc4231_cases_do(sha256, [Case1, Case2, Case3, Case4, Case5, Case6, Case7]).
-
-hmac_rfc4231_sha384_do() ->
- Case1 = hexstr2bin("afd03944d84895626b0825f4ab46907f"
- "15f9dadbe4101ec682aa034c7cebc59c"
- "faea9ea9076ede7f4af152e8b2fa9cb6"),
- Case2 = hexstr2bin("af45d2e376484031617f78d2b58a6b1b"
- "9c7ef464f5a01b47e42ec3736322445e"
- "8e2240ca5e69e2c78b3239ecfab21649"),
- Case3 = hexstr2bin("88062608d3e6ad8a0aa2ace014c8a86f"
- "0aa635d947ac9febe83ef4e55966144b"
- "2a5ab39dc13814b94e3ab6e101a34f27"),
- Case4 = hexstr2bin("3e8a69b7783c25851933ab6290af6ca7"
- "7a9981480850009cc5577c6e1f573b4e"
- "6801dd23c4a7d679ccf8a386c674cffb"),
- Case5 = hexstr2bin("3abf34c3503b2a23a46efc619baef897"),
- Case6 = hexstr2bin("4ece084485813e9088d2c63a041bc5b4"
- "4f9ef1012a2b588f3cd11f05033ac4c6"
- "0c2ef6ab4030fe8296248df163f44952"),
- Case7 = hexstr2bin("6617178e941f020d351e2f254e8fd32c"
- "602420feb0b8fb9adccebb82461e99c5"
- "a678cc31e799176d3860e6110c46523e"),
- hmac_rfc4231_cases_do(sha384, [Case1, Case2, Case3, Case4, Case5, Case6, Case7]).
-
-hmac_rfc4231_sha512_do() ->
- Case1 = hexstr2bin("87aa7cdea5ef619d4ff0b4241a1d6cb0"
- "2379f4e2ce4ec2787ad0b30545e17cde"
- "daa833b7d6b8a702038b274eaea3f4e4"
- "be9d914eeb61f1702e696c203a126854"),
- Case2 = hexstr2bin("164b7a7bfcf819e2e395fbe73b56e0a3"
- "87bd64222e831fd610270cd7ea250554"
- "9758bf75c05a994a6d034f65f8f0e6fd"
- "caeab1a34d4a6b4b636e070a38bce737"),
- Case3 = hexstr2bin("fa73b0089d56a284efb0f0756c890be9"
- "b1b5dbdd8ee81a3655f83e33b2279d39"
- "bf3e848279a722c806b485a47e67c807"
- "b946a337bee8942674278859e13292fb"),
- Case4 = hexstr2bin("b0ba465637458c6990e5a8c5f61d4af7"
- "e576d97ff94b872de76f8050361ee3db"
- "a91ca5c11aa25eb4d679275cc5788063"
- "a5f19741120c4f2de2adebeb10a298dd"),
- Case5 = hexstr2bin("415fad6271580a531d4179bc891d87a6"),
- Case6 = hexstr2bin("80b24263c7c1a3ebb71493c1dd7be8b4"
- "9b46d1f41b4aeec1121b013783f8f352"
- "6b56d037e05f2598bd0fd2215d6a1e52"
- "95e64f73f63f0aec8b915a985d786598"),
- Case7 = hexstr2bin("e37b6a775dc87dbaa4dfa9f96e5e3ffd"
- "debd71f8867289865df5a32d20cdc944"
- "b6022cac3c4982b10d5eeb55c3e4de15"
- "134676fb6de0446065c97440fa8c6a58"),
- hmac_rfc4231_cases_do(sha512, [Case1, Case2, Case3, Case4, Case5, Case6, Case7]).
-
-hmac_rfc4231_cases_do(Hash, CasesData) ->
- hmac_rfc4231_cases_do(Hash, [case1, case2, case3, case4, case5, case6, case7], CasesData).
-
-hmac_rfc4231_cases_do(_Hash, _, []) ->
- ok;
-hmac_rfc4231_cases_do(Hash, [C|Cases], [D|CasesData]) ->
- hmac_rfc4231_case(Hash, C, D),
- hmac_rfc4231_cases_do(Hash, Cases, CasesData).
-
-hmac_update_md5_io(doc) ->
- ["Generate an MD5 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:md5_mac." ];
-hmac_update_md5_io(suite) ->
- [];
-hmac_update_md5_io(Config) when is_list(Config) ->
- ?line Key = ["A fine speach", "by a fine man!"],
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(md5, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final(Ctx3),
- ?line Exp = crypto:md5_mac(Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac).
-
-
-hmac_update_md5_n(doc) ->
- ["Generate a shortened MD5 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:md5_mac." ];
-hmac_update_md5_n(suite) ->
- [];
-hmac_update_md5_n(Config) when is_list(Config) ->
- ?line Key = ["A fine speach", "by a fine man!"],
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(md5, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final_n(Ctx3, 12),
- ?line Exp = crypto:md5_mac_96(Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac).
-%%
-%%
-ripemd160(doc) ->
- ["Generate RIPEMD160 message digests and check the result."];
-ripemd160(suite) ->
- [];
-ripemd160(Config) when is_list(Config) ->
- ?line m(crypto:hash(ripemd160,"abc"),
- hexstr2bin("8EB208F7E05D987A9B044A8E98C6B087F15A0BFC")),
- ?line m(crypto:hash(ripemd160,"abcdbcdecdefdefgefghfghighijhijkijkljklmklm"
- "nlmnomnopnopq"),
- hexstr2bin("12A053384A9C0C88E405A06C27DCF49ADA62EB2B")).
-
-
-%%
-%%
-ripemd160_update(doc) ->
- ["Generate RIPEMD160 message digests by using ripemd160_init,"
- "ripemd160_update, and ripemd160_final and check the result."];
-ripemd160_update(suite) ->
- [];
-ripemd160_update(Config) when is_list(Config) ->
- ?line Ctx = crypto:hash_init(ripemd160),
- ?line Ctx1 = crypto:hash_update(Ctx, "abcdbcdecdefdefgefghfghighi"),
- ?line Ctx2 = crypto:hash_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"),
- ?line m(crypto:hash_final(Ctx2),
- hexstr2bin("12A053384A9C0C88E405A06C27DCF49ADA62EB2B")).
-
-%%
-%%
-sha_update(doc) ->
- ["Generate SHA message digests by using sha_init, sha_update, and"
- "sha_final, and check the result. Examples are from FIPS-180-1."];
-sha_update(suite) ->
- [];
-sha_update(Config) when is_list(Config) ->
- ?line Ctx = crypto:sha_init(),
- ?line Ctx1 = crypto:sha_update(Ctx, "abcdbcdecdefdefgefghfghighi"),
- ?line Ctx2 = crypto:sha_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"),
- ?line m(crypto:sha_final(Ctx2),
- hexstr2bin("84983E441C3BD26EBAAE4AA1F95129E5E54670F1")).
-
-%%
-%%
-sha256(doc) ->
- ["Generate SHA-256 message digests and check the result. Examples are "
- "from rfc-4634."];
-sha256(suite) ->
- [];
-sha256(Config) when is_list(Config) ->
- if_supported(sha256, fun() -> sha256_do() end).
-
-sha256_do() ->
- ?line m(crypto:hash(sha256, "abc"),
- hexstr2bin("BA7816BF8F01CFEA4141"
- "40DE5DAE2223B00361A396177A9CB410FF61F20015AD")),
- ?line m(crypto:hash(sha256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklm"
- "nlmnomnopnopq"),
- hexstr2bin("248D6A61D20638B8"
- "E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")).
-
-%%
-%%
-sha256_update(doc) ->
- ["Generate SHA256 message digests by using sha256_init, sha256_update, and"
- "sha256_final, and check the result. Examples are from rfc-4634."];
-sha256_update(suite) ->
- [];
-sha256_update(Config) when is_list(Config) ->
- if_supported(sha256, fun() -> sha256_update_do() end).
-
-sha256_update_do() ->
- ?line Ctx = crypto:hash_init(sha256),
- ?line Ctx1 = crypto:hash_update(Ctx, "abcdbcdecdefdefgefghfghighi"),
- ?line Ctx2 = crypto:hash_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"),
- ?line m(crypto:hash_final(Ctx2),
- hexstr2bin("248D6A61D20638B8"
- "E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")).
-
-
-%%
-%%
-sha512(doc) ->
- ["Generate SHA-512 message digests and check the result. Examples are "
- "from rfc-4634."];
-sha512(suite) ->
- [];
-sha512(Config) when is_list(Config) ->
- if_supported(sha512, fun() -> sha512_do() end).
-
-sha512_do() ->
- ?line m(crypto:hash(sha512, "abc"),
- hexstr2bin("DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2"
- "0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD"
- "454D4423643CE80E2A9AC94FA54CA49F")),
- ?line m(crypto:hash(sha512, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"),
- hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1"
- "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A"
- "C7D329EEB6DD26545E96E55B874BE909")).
-
-%%
-%%
-sha512_update(doc) ->
- ["Generate SHA512 message digests by using sha512_init, sha512_update, and"
- "sha512_final, and check the result. Examples are from rfc=4634."];
-sha512_update(suite) ->
- [];
-sha512_update(Config) when is_list(Config) ->
- if_supported(sha512, fun() -> sha512_update_do() end).
-
-sha512_update_do() ->
- ?line Ctx = crypto:hash_init(sha512),
- ?line Ctx1 = crypto:hash_update(Ctx, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"),
- ?line Ctx2 = crypto:hash_update(Ctx1, "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"),
- ?line m(crypto:hash_final(Ctx2),
- hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1"
- "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A"
- "C7D329EEB6DD26545E96E55B874BE909")).
-
-%%
-%%
-md5_mac(doc) ->
- ["Generate some HMACs, using MD5, and check the result. Examples are "
- "from RFC-2104."];
-md5_mac(suite) ->
- [];
-md5_mac(Config) when is_list(Config) ->
- ?line m(crypto:md5_mac(hexstr2bin("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"),
- "Hi There"),
- hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d")),
- ?line m(crypto:md5_mac(list_to_binary("Jefe"),
- "what do ya want for nothing?"),
- hexstr2bin("750c783e6ab0b503eaa86e310a5db738")),
- ?line m(crypto:md5_mac(hexstr2bin("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),
- hexstr2bin("DDDDDDDDDDDDDDDDDDDD"
- "DDDDDDDDDDDDDDDDDDDD"
- "DDDDDDDDDDDDDDDDDDDD"
- "DDDDDDDDDDDDDDDDDDDD"
- "DDDDDDDDDDDDDDDDDDDD")),
- hexstr2bin("56be34521d144c88dbb8c733f0e8b3f6")).
-
-%%
-%%
-md5_mac_io(doc) ->
- ["Generate some HMACs, using MD5, with Key an IO-list, and check the "
- "result. Examples are from RFC-2104."];
-md5_mac_io(suite) ->
- [];
-md5_mac_io(Config) when is_list(Config) ->
- ?line Key1 = hexstr2bin("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"),
- ?line {B11, B12} = split_binary(Key1, 4),
- ?line Key11 = [B11,binary_to_list(B12)],
- ?line m(crypto:md5_mac(Key11, "Hi There"),
- hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d")).
-
-%%
-%%
-des_cbc(doc) ->
- "Encrypt and decrypt according to CBC DES. and check the result. "
- "Example are from FIPS-81.";
-des_cbc(suite) ->
- [];
-des_cbc(Config) when is_list(Config) ->
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain = "Now is the time for all ",
- ?line Cipher = crypto:des_cbc_encrypt(Key, IVec, Plain),
- ?line m(Cipher, hexstr2bin("e5c7cdde872bf27c43e934008c389c"
- "0f683788499a7c05f6")),
- ?line m(list_to_binary(Plain),
- crypto:des_cbc_decrypt(Key, IVec, Cipher)),
- ?line Plain2 = "7654321 Now is the time for " ++ [0, 0, 0, 0],
- ?line Cipher2 = crypto:des_cbc_encrypt(Key, IVec, Plain2),
- ?line m(Cipher2, hexstr2bin("b9916b8ee4c3da64b4f44e3cbefb9"
- "9484521388fa59ae67d58d2e77e86062733")),
- ?line m(list_to_binary(Plain2),
- crypto:des_cbc_decrypt(Key, IVec, Cipher2)).
-
-%%
-%%
-des_cbc_iter(doc) ->
- "Encrypt and decrypt according to CBC DES in two steps, and "
- "check the result. Example are from FIPS-81.";
-des_cbc_iter(suite) ->
- [];
-des_cbc_iter(Config) when is_list(Config) ->
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain1 = "Now is the time ",
- ?line Plain2 = "for all ",
- ?line Cipher1 = crypto:des_cbc_encrypt(Key, IVec, Plain1),
- ?line IVec2 = crypto:des_cbc_ivec(Cipher1),
- ?line Cipher2 = crypto:des_cbc_encrypt(Key, IVec2, Plain2),
- ?line Cipher = list_to_binary([Cipher1, Cipher2]),
- ?line m(Cipher, hexstr2bin("e5c7cdde872bf27c43e934008c389c"
- "0f683788499a7c05f6")).
-
-%%
-%%
-des_cfb(doc) ->
- "Encrypt and decrypt according to CFB DES. and check the result. "
- "Example is from FIPS-81.";
-des_cfb(suite) ->
- [];
-des_cfb(Config) when is_list(Config) ->
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain = "Now is the",
- ?line Cipher = crypto:des_cfb_encrypt(Key, IVec, Plain),
- ?line m(Cipher, hexstr2bin("f31fda07011462ee187f")),
- ?line m(list_to_binary(Plain),
- crypto:des_cfb_decrypt(Key, IVec, Cipher)).
-
-%%
-%%
-des_cfb_iter(doc) ->
- "Encrypt and decrypt according to CFB DES in two steps, and "
- "check the result. Example is from FIPS-81.";
-des_cfb_iter(suite) ->
- [];
-des_cfb_iter(Config) when is_list(Config) ->
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain1 = "Now i",
- ?line Plain2 = "s the",
- ?line Cipher1 = crypto:des_cfb_encrypt(Key, IVec, Plain1),
- ?line IVec2 = crypto:des_cfb_ivec(IVec, Cipher1),
- ?line Cipher2 = crypto:des_cfb_encrypt(Key, IVec2, Plain2),
- ?line Cipher = list_to_binary([Cipher1, Cipher2]),
- ?line m(Cipher, hexstr2bin("f31fda07011462ee187f")).
-
-%%
-%%
-des_ecb(doc) ->
- "Encrypt and decrypt according to ECB DES and check the result. "
- "Example are from FIPS-81.";
-des_ecb(suite) ->
- [];
-des_ecb(Config) when is_list(Config) ->
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line Cipher1 = crypto:des_ecb_encrypt(Key, "Now is t"),
- ?line m(Cipher1, hexstr2bin("3fa40e8a984d4815")),
- ?line Cipher2 = crypto:des_ecb_encrypt(Key, "he time "),
- ?line m(Cipher2, hexstr2bin("6a271787ab8883f9")),
- ?line Cipher3 = crypto:des_ecb_encrypt(Key, "for all "),
- ?line m(Cipher3, hexstr2bin("893d51ec4b563b53")),
- ?line Cipher4 = crypto:des_ecb_decrypt(Key, hexstr2bin("3fa40e8a984d4815")),
- ?line m(Cipher4, <<"Now is t">>),
- ?line Cipher5 = crypto:des_ecb_decrypt(Key, hexstr2bin("6a271787ab8883f9")),
- ?line m(Cipher5, <<"he time ">>),
- ?line Cipher6 = crypto:des_ecb_decrypt(Key, hexstr2bin("893d51ec4b563b53")),
- ?line m(Cipher6, <<"for all ">>).
-%%
-%%
-rc2_cbc(doc) ->
- "Encrypt and decrypt according to RC2 CBC and check the result. "
- "Example stripped out from public_key application test";
-rc2_cbc(Config) when is_list(Config) ->
-
- Key = <<146,210,160,124,215,227,153,239,227,17,222,140,3,93,27,191>>,
- IV = <<72,91,135,182,25,42,35,210>>,
-
- Cipher = <<36,245,206,158,168,230,58,69,148,137,32,192,250,41,237,181,181,251, 192,2,175,135,177,171,57,30,111,117,159,149,15,28,88,158,28,81,28,115, 85,219,241,82,117,222,91,85,73,117,164,25,182,52,191,64,123,57,26,19, 211,27,253,31,194,219,231,104,247,240,172,130,119,21,225,154,101,247, 32,216,42,216,133,169,78,22,97,27,227,26,196,224,172,168,17,9,148,55, 203,91,252,40,61,226,236,221,215,160,78,63,13,181,68,57,196,241,185, 207, 116,129,152,237,60,139,247,153,27,146,161,246,222,98,185,222,152, 187,135, 236,86,34,7,110,91,230,173,34,160,242,202,222,121,127,181,140, 101,203,195, 190,88,250,86,147,127,87,72,126,171,16,71,47,110,248,88, 14,29,143,161,152, 129,236,148,22,152,186,208,119,70,8,174,193,203,100, 193,203,200,117,102,242, 134,142,96,125,135,200,217,190,76,117,50,70, 209,186,101,241,200,91,40,193,54, 90,195,38,47,59,197,38,234,86,223,16, 51,253,204,129,20,171,66,21,241,26,135,216, 196,114,110,91,15,53,40, 164,201,136,113,95,247,51,181,208,241,68,168,98,151,36, 155,72,24,57, 42,191,14,125,204,10,167,214,233,138,115,125,234,121,134,227,26,247, 77,200,117,110,117,111,168,156,206,67,159,149,189,173,150,193,91,199, 216,153,22, 189,137,185,89,160,13,131,132,58,109,28,110,246,252,251,14, 232,91,38,52,29,101,188,69,123,50,0,130,178,93,73,239,118,7,77,35,59, 253,10,159,45,86,142,37,78,232,48>>,
- Text = <<48,130,1,85,2,1,0,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,4,130,1,63,48,130, 1,59,2,1,0,2,65,0,222,187,252,44,9,214,27,173,162,169,70,47,36,34,78,84,204, 107,60,192,117,95,21,206,49,142,245,126,121,223,23,2,107,106,133,204,161,36, 40,2,114,69,4,93,242,5,42,50,154,47,154,211,209,123,120,161,5,114,173,155,34, 191,52,59,2,3,1,0,1,2,64,45,144,169,106,220,236,71,39,67,82,123,192,35,21,61, 143,13,110,150,180,12,142,210,40,39,109,70,125,132,51,6,66,159,134,112,85, 155,243,118,221,65,133,127,99,151,194,252,141,149,224,229,62,214,45,228,32, 184,85,67,14,228,161,184,161,2,33,0,255,202,240,131,130,57,49,224,115,255,83, 79,6,165,212,21,179,212,20,188,97,74,69,68,163,223,247,237,39,24,23,235,2,33, 0,222,234,48,36,33,23,219,45,59,136,55,245,143,29,165,48,255,131,207,146,131, 104,13,163,54,131,236,78,88,54,16,241,2,33,0,230,2,99,129,173,176,166,131, 241,106,143,76,9,107,70,41,121,185,228,39,124,200,159,62,216,169,5,180,111, 169,255,159,2,33,0,151,193,70,212,209,210,179,219,175,83,165,4,255,81,103,76, 92,39,24,0,222,132,208,3,244,241,10,198,171,54,227,129,2,32,43,250,20,31,16, 189,168,116,225,1,125,132,94,130,118,124,28,56,232,39,69,218,244,33,240,200, 205,9,215,101,35,135,7,7,7,7,7,7,7>>,
-
- Text = crypto:rc2_cbc_decrypt(Key, IV, Cipher),
- Cipher = crypto:rc2_cbc_encrypt(Key, IV, Text).
-
-%%
-%%
-des3_cbc(doc) ->
- "Encrypt and decrypt according to CBC 3DES, and check the result.";
-des3_cbc(suite) ->
- [];
-des3_cbc(Config) when is_list(Config) ->
- ?line Key1 = hexstr2bin("0123456789abcdef"),
- ?line Key2 = hexstr2bin("fedcba9876543210"),
- ?line Key3 = hexstr2bin("0f2d4b6987a5c3e1"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain = "Now is the time for all ",
- ?line Cipher = crypto:des3_cbc_encrypt(Key1, Key2, Key3, IVec, Plain),
- ?line m(Cipher, hexstr2bin("8a2667ee5577267cd9b1af2c5a0480"
- "0bac1ae66970fb2b89")),
- ?line m(list_to_binary(Plain),
- crypto:des3_cbc_decrypt(Key1, Key2, Key3, IVec, Cipher)),
- ?line Plain2 = "7654321 Now is the time for " ++ [0, 0, 0, 0],
- ?line Cipher2 = crypto:des3_cbc_encrypt(Key1, Key2, Key3, IVec, Plain2),
- ?line m(Cipher2, hexstr2bin("eb33ec6ede2c8e90f6877e77b95d5"
- "4c83cee22907f7f0041ca1b7abe202bfafe")),
- ?line m(list_to_binary(Plain2),
- crypto:des3_cbc_decrypt(Key1, Key2, Key3, IVec, Cipher2)),
-
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line DESCipher = crypto:des3_cbc_encrypt(Key, Key, Key, IVec, Plain),
- ?line m(DESCipher, hexstr2bin("e5c7cdde872bf27c43e934008c389c"
- "0f683788499a7c05f6")),
- ?line m(list_to_binary(Plain),
- crypto:des3_cbc_decrypt(Key, Key, Key, IVec, DESCipher)),
- ?line DESCipher2 = crypto:des3_cbc_encrypt(Key, Key, Key, IVec, Plain2),
- ?line m(DESCipher2, hexstr2bin("b9916b8ee4c3da64b4f44e3cbefb9"
- "9484521388fa59ae67d58d2e77e86062733")),
- ?line m(list_to_binary(Plain2),
- crypto:des3_cbc_decrypt(Key, Key, Key, IVec, DESCipher2)).
-
-%%
-%%
-des3_cfb(doc) ->
- "Encrypt and decrypt according to CFB 3DES, and check the result.";
-des3_cfb(suite) ->
- [];
-des3_cfb(Config) when is_list(Config) ->
- case openssl_version() of
- V when V < 16#90705F -> {skipped,"OpenSSL version too old"};
- _ -> des3_cfb_do()
- end.
-
-des3_cfb_do() ->
- ?line Key1 = hexstr2bin("0123456789abcdef"),
- ?line Key2 = hexstr2bin("fedcba9876543210"),
- ?line Key3 = hexstr2bin("0f2d4b6987a5c3e1"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain = "Now is the time for all ",
- ?line Cipher = crypto:des3_cfb_encrypt(Key1, Key2, Key3, IVec, Plain),
- ?line m(Cipher, hexstr2bin("fc0ba7a20646ba53cc8bff263f0937"
- "1deab42a00666db02c")),
- ?line m(list_to_binary(Plain),
- crypto:des3_cfb_decrypt(Key1, Key2, Key3, IVec, Cipher)),
- ?line Plain2 = "7654321 Now is the time for " ++ [0, 0, 0, 0],
- ?line Cipher2 = crypto:des3_cfb_encrypt(Key1, Key2, Key3, IVec, Plain2),
- ?line m(Cipher2, hexstr2bin("8582c59ac01897422632c0accb66c"
- "e413f5efab838fce7e41e2ba67705bad5bc")),
- ?line m(list_to_binary(Plain2),
- crypto:des3_cfb_decrypt(Key1, Key2, Key3, IVec, Cipher2)).
-
-%%
-%%
-aes_cfb(doc) ->
- "Encrypt and decrypt according to AES CFB 128 bit and check "
- "the result. Example are from NIST SP 800-38A.";
-
-aes_cfb(suite) ->
- [];
-aes_cfb(Config) when is_list(Config) ->
-
-%% Sample data from NIST Spec.Publ. 800-38A
-%% F.3.13 CFB128-AES128.Encrypt
-%% Key 2b7e151628aed2a6abf7158809cf4f3c
-%% IV 000102030405060708090a0b0c0d0e0f
-%% Segment #1
-%% Input Block 000102030405060708090a0b0c0d0e0f
-%% Output Block 50fe67cc996d32b6da0937e99bafec60
-%% Plaintext 6bc1bee22e409f96e93d7e117393172a
-%% Ciphertext 3b3fd92eb72dad20333449f8e83cfb4a
-%% Segment #2
-%% Input Block 3b3fd92eb72dad20333449f8e83cfb4a
-%% Output Block 668bcf60beb005a35354a201dab36bda
-%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
-%% Ciphertext c8a64537a0b3a93fcde3cdad9f1ce58b
-%% Segment #3
-%% Input Block c8a64537a0b3a93fcde3cdad9f1ce58b
-%% Output Block 16bd032100975551547b4de89daea630
-%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
-%% Ciphertext 26751f67a3cbb140b1808cf187a4f4df
-%% Segment #4
-%% Input Block 26751f67a3cbb140b1808cf187a4f4df
-%% Output Block 36d42170a312871947ef8714799bc5f6
-%% Plaintext f69f2445df4f9b17ad2b417be66c3710
-%% Ciphertext c04b05357c5d1c0eeac4c66f9ff7f2e6
-
- ?line Key = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- ?line IVec = hexstr2bin("000102030405060708090a0b0c0d0e0f"),
- ?line Plain = hexstr2bin("6bc1bee22e409f96e93d7e117393172a"),
- ?line Cipher = hexstr2bin("3b3fd92eb72dad20333449f8e83cfb4a"),
-
- %% Try all prefixes of plain and cipher.
- aes_cfb_do(byte_size(Plain), Plain, Cipher, Key, IVec).
-
-aes_cfb_do(N, Plain, Cipher, Key, IVec) when N >= 0 ->
- <<P:N/binary, _/binary>> = Plain,
- <<C:N/binary, _/binary>> = Cipher,
- ?line C = crypto:aes_cfb_128_encrypt(Key, IVec, P),
- ?line P = crypto:aes_cfb_128_decrypt(Key, IVec, C),
- aes_cfb_do(N-1, Plain, Cipher, Key, IVec);
-aes_cfb_do(_, _, _, _, _) -> ok.
-
-
-%%
-%%
-aes_cbc(doc) ->
- "Encrypt and decrypt according to AES CBC 128 bit. and check the result. "
- "Example are from NIST SP 800-38A.";
-
-aes_cbc(suite) ->
- [];
-aes_cbc(Config) when is_list(Config) ->
-
-%% Sample data from NIST Spec.Publ. 800-38A
-%% F.2.1 CBC-AES128.Encrypt
-%% Key 2b7e151628aed2a6abf7158809cf4f3c
-%% IV 000102030405060708090a0b0c0d0e0f
-%% Block #1
-%% Plaintext 6bc1bee22e409f96e93d7e117393172a
-%% Input Block 6bc0bce12a459991e134741a7f9e1925
-%% Output Block 7649abac8119b246cee98e9b12e9197d
-%% Ciphertext 7649abac8119b246cee98e9b12e9197d
-%% Block #2
-%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
-%% Input Block d86421fb9f1a1eda505ee1375746972c
-%% Output Block 5086cb9b507219ee95db113a917678b2
-%% Ciphertext 5086cb9b507219ee95db113a917678b2
-%% Block #3
-%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
-%% Input Block 604ed7ddf32efdff7020d0238b7c2a5d
-%% Output Block 73bed6b8e3c1743b7116e69e22229516
-%% Ciphertext 73bed6b8e3c1743b7116e69e22229516
-%% Block #4
-%% Plaintext f69f2445df4f9b17ad2b417be66c3710
-%% Input Block 8521f2fd3c8eef2cdc3da7e5c44ea206
-%% Output Block 3ff1caa1681fac09120eca307586e1a7
-%% Ciphertext 3ff1caa1681fac09120eca307586e1a7
-%%
-%% F.2.2 CBC-AES128.Decrypt
-%% Key 2b7e151628aed2a6abf7158809cf4f3c
-%% IV 000102030405060708090a0b0c0d0e0f
- %% Block #1
-%% Ciphertext 7649abac8119b246cee98e9b12e9197d
-%% Input Block 7649abac8119b246cee98e9b12e9197d
-%% Output Block 6bc0bce12a459991e134741a7f9e1925
-%% Plaintext 6bc1bee22e409f96e93d7e117393172a
-%% Block #2
-%% Ciphertext 5086cb9b507219ee95db113a917678b2
-%% Input Block 5086cb9b507219ee95db113a917678b2
-%% Output Block d86421fb9f1a1eda505ee1375746972c
-%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
-%% Block #3
-%% Ciphertext 73bed6b8e3c1743b7116e69e22229516
-%% Input Block 73bed6b8e3c1743b7116e69e22229516
-%% Output Block 604ed7ddf32efdff7020d0238b7c2a5d
-%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
-%% Block #4
-%% Ciphertext 3ff1caa1681fac09120eca307586e1a7
-%% Input Block 3ff1caa1681fac09120eca307586e1a7
-%% Output Block 8521f2fd3c8eef2cdc3da7e5c44ea206
-%% Plaintext f69f2445df4f9b17ad2b417be66c3710
-
- ?line Key = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- ?line IVec = hexstr2bin("000102030405060708090a0b0c0d0e0f"),
- ?line Plain = hexstr2bin("6bc1bee22e409f96e93d7e117393172a"),
- ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Plain),
- ?line m(Cipher, hexstr2bin("7649abac8119b246cee98e9b12e9197d")),
- ?line m(Plain,
- crypto:aes_cbc_128_decrypt(Key, IVec, Cipher)).
-
-aes_cbc_iter(doc) ->
- "Encrypt and decrypt according to CBC AES in steps";
-aes_cbc_iter(suite) -> [];
-aes_cbc_iter(Config) when is_list(Config) ->
- Key = list_to_binary(lists:seq(255,256-16*17,-17)),
- IVec = list_to_binary(lists:seq(1,16*7,7)),
- Plain = <<"One, two, three o'clock, four o'clock, rock"
- "Five, six, seven o'clock, eight o'clock, rock"
- "Nine, ten, eleven o'clock, twelve o'clock, rock"
- "We're gonna rock around the clock tonight">>,
- ?line 0 = size(Plain) rem 16,
-
- ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Plain),
- ?line Plain = crypto:aes_cbc_128_decrypt(Key, IVec, Cipher),
-
- ?line Cipher = aes_cbc_encrypt_iter(Key,IVec,Plain,<<>>),
- ?line Plain = aes_cbc_decrypt_iter(Key,IVec,Cipher,<<>>),
- ok.
-
-aes_cbc_encrypt_iter(_,_,<<>>, Acc) ->
- Acc;
-aes_cbc_encrypt_iter(Key,IVec,Data, Acc) ->
- Bytes = 16 * (1 + size(Data) div (16*3)),
- <<Chunk:Bytes/binary, Rest/binary>> = Data,
- %%io:format("encrypt iter Chunk=~p Rest=~p\n",[Chunk,Rest]),
- ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Chunk),
- ?line IVec2 = crypto:aes_cbc_ivec(Cipher),
- aes_cbc_encrypt_iter(Key,IVec2,Rest, <<Acc/binary, Cipher/binary>>).
-
-aes_cbc_decrypt_iter(_,_,<<>>, Acc) ->
- Acc;
-aes_cbc_decrypt_iter(Key,IVec,Data, Acc) ->
- Bytes = 16 * (1 + size(Data) div (16*5)),
- <<Chunk:Bytes/binary, Rest/binary>> = Data,
- %%io:format("decrypt iter Chunk=~p Rest=~p\n",[Chunk,Rest]),
- ?line Plain = crypto:aes_cbc_128_decrypt(Key, IVec, Chunk),
- ?line IVec2 = crypto:aes_cbc_ivec(Chunk),
- aes_cbc_decrypt_iter(Key,IVec2,Rest, <<Acc/binary, Plain/binary>>).
-
-
-aes_ctr(doc) -> "CTR";
-aes_ctr(Config) when is_list(Config) ->
- %% Sample data from NIST Spec.Publ. 800-38A
- %% F.5.1 CTR-AES128.Encrypt
- Key128 = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- Samples128 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
- "6bc1bee22e409f96e93d7e117393172a", % Plaintext
- "874d6191b620e3261bef6864990db6ce"},% Ciphertext
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
- "ae2d8a571e03ac9c9eb76fac45af8e51",
- "9806f66b7970fdff8617187bb9fffdff"},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
- "30c81c46a35ce411e5fbc1191a0a52ef",
- "5ae4df3edbd5d35e5b4f09020db03eab"},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
- "f69f2445df4f9b17ad2b417be66c3710",
- "1e031dda2fbe03d1792170a0f3009cee"}],
- lists:foreach(fun(S) -> aes_ctr_do(Key128,S) end, Samples128),
-
- %% F.5.3 CTR-AES192.Encrypt
- Key192 = hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
- Samples192 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
- "6bc1bee22e409f96e93d7e117393172a", % Plaintext
- "1abc932417521ca24f2b0459fe7e6e0b"},% Ciphertext
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
- "ae2d8a571e03ac9c9eb76fac45af8e51",
- "090339ec0aa6faefd5ccc2c6f4ce8e94"},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
- "30c81c46a35ce411e5fbc1191a0a52ef",
- "1e36b26bd1ebc670d1bd1d665620abf7"},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
- "f69f2445df4f9b17ad2b417be66c3710",
- "4f78a7f6d29809585a97daec58c6b050"}],
- lists:foreach(fun(S) -> aes_ctr_do(Key192,S) end, Samples192),
-
- %% F.5.5 CTR-AES256.Encrypt
- Key256 = hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- Samples256 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
- "6bc1bee22e409f96e93d7e117393172a", % Plaintext
- "601ec313775789a5b7a7f504bbf3d228"},% Ciphertext
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
- "ae2d8a571e03ac9c9eb76fac45af8e51",
- "f443e3ca4d62b59aca84e990cacaf5c5"},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
- "30c81c46a35ce411e5fbc1191a0a52ef",
- "2b0930daa23de94ce87017ba2d84988d"},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
- "f69f2445df4f9b17ad2b417be66c3710",
- "dfc9c58db67aada613c2dd08457941a6"}],
- lists:foreach(fun(S) -> aes_ctr_do(Key256,S) end, Samples256).
-
-
-aes_ctr_do(Key,{IVec, Plain, Cipher}) ->
- ?line I = hexstr2bin(IVec),
- ?line P = hexstr2bin(Plain),
- ?line C = crypto:aes_ctr_encrypt(Key, I, P),
- ?line m(C, hexstr2bin(Cipher)),
- ?line m(P, crypto:aes_ctr_decrypt(Key, I, C)).
-
-aes_ctr_stream(doc) -> "CTR Streaming";
-aes_ctr_stream(Config) when is_list(Config) ->
- %% Sample data from NIST Spec.Publ. 800-38A
- %% F.5.1 CTR-AES128.Encrypt
- Key128 = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- Samples128 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
- ["6bc1bee22e409f", "96e93d7e117393172a"], % Plaintext
- ["874d6191b620e3261bef6864990db6ce"]}, % Ciphertext
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
- ["ae2d8a57", "1e03ac9c", "9eb76fac", "45af8e51"],
- ["9806f66b7970fdff","8617187bb9fffdff"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
- ["30c81c46a35c", "e411e5fbc119", "1a0a52ef"],
- ["5ae4df3e","dbd5d3","5e5b4f0902","0db03eab"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
- ["f69f2445df4f9b17ad2b417be66c3710"],
- ["1e031dda2fbe","03d1792170a0","f3009cee"]}],
- lists:foreach(fun(S) -> aes_ctr_stream_do(Key128,S) end, Samples128),
-
- %% F.5.3 CTR-AES192.Encrypt
- Key192 = hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
- Samples192 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
- ["6bc1bee22e409f96e93d7e117393172a"], % Plaintext
- ["1abc9324","17521c","a24f2b04","59fe7e6e0b"]}, % Ciphertext
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
- ["ae2d8a57", "1e03ac9c9eb76fac", "45af8e51"],
- ["090339ec0aa6faefd5ccc2c6f4ce8e94"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
- ["30c81c46a35ce411", "e5fbc1191a0a52ef"],
- ["1e36b26bd1","ebc670d1bd1d","665620abf7"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
- ["f69f2445", "df4f9b17ad", "2b417be6", "6c3710"],
- ["4f78a7f6d2980958","5a97daec58c6b050"]}],
- lists:foreach(fun(S) -> aes_ctr_stream_do(Key192,S) end, Samples192),
-
- %% F.5.5 CTR-AES256.Encrypt
- Key256 = hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- Samples256 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
- ["6bc1bee22e409f96", "e93d7e117393172a"], % Plaintext
- ["601ec313775789", "a5b7a7f504bbf3d228"]}, % Ciphertext
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
- ["ae2d8a571e03ac9c9eb76fac45af8e51"],
- ["f443e3ca","4d62b59aca84","e990cacaf5c5"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
- ["30c81c46","a35ce411","e5fbc119","1a0a52ef"],
- ["2b0930daa23de94ce87017ba2d84988d"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
- ["f69f2445df4f","9b17ad2b41","7be66c3710"],
- ["dfc9c5","8db67aada6","13c2dd08","457941a6"]}],
- lists:foreach(fun(S) -> aes_ctr_stream_do(Key256,S) end, Samples256).
-
-
-aes_ctr_stream_do(Key,{IVec, PlainList, CipherList}) ->
- ?line I = hexstr2bin(IVec),
- ?line S = crypto:aes_ctr_stream_init(Key, I),
- ?line C = aes_ctr_stream_do_iter(
- S, PlainList, [],
- fun(S2,P) -> crypto:aes_ctr_stream_encrypt(S2, P) end),
- ?line m(C, hexstr2bin(lists:flatten(CipherList))),
- ?line P = aes_ctr_stream_do_iter(
- S, CipherList, [],
- fun(S2,C2) -> crypto:aes_ctr_stream_decrypt(S2, C2) end),
- ?line m(P, hexstr2bin(lists:flatten(PlainList))).
-
-aes_ctr_stream_do_iter(_State, [], Acc, _CipherFun) ->
- iolist_to_binary(lists:reverse(Acc));
-aes_ctr_stream_do_iter(State, [Plain|Rest], Acc, CipherFun) ->
- ?line P = hexstr2bin(Plain),
- ?line {S2, C} = CipherFun(State, P),
- aes_ctr_stream_do_iter(S2, Rest, [C | Acc], CipherFun).
-
-%%
-%%
-mod_exp_test(doc) ->
- "mod_exp testing (A ^ M % P with bignums)";
-mod_exp_test(suite) ->
- [];
-mod_exp_test(Config) when is_list(Config) ->
- mod_exp_aux_test(2, 5, 10, 8).
-
-mod_exp_aux_test(_, _, _, 0) ->
- ok;
-mod_exp_aux_test(B, E, M, N) ->
- ?line R1 = crypto:mod_exp(B, E, M),
- ?line R2 = ipow(B, E, M),
- ?line m(R1, R2),
- ?line mod_exp_aux_test(B, E*E+1, M*M+1, N-1).
-
-%%
-%%
-rand_uniform_test(doc) ->
- "rand_uniform and random_bytes testing";
-rand_uniform_test(suite) ->
- [];
-rand_uniform_test(Config) when is_list(Config) ->
- rand_uniform_aux_test(10),
- ?line 10 = size(crypto:rand_bytes(10)).
-
-rand_uniform_aux_test(0) ->
- ok;
-rand_uniform_aux_test(N) ->
- ?line L = N*1000,
- ?line H = N*100000+1,
- ?line crypto_rand_uniform(L, H),
- ?line crypto_rand_uniform(-L, L),
- ?line crypto_rand_uniform(-H, -L),
- ?line crypto_rand_uniform(-H, L),
- ?line rand_uniform_aux_test(N-1).
-
-crypto_rand_uniform(L,H) ->
- ?line R1 = crypto:rand_uniform(L, H),
- ?line t(R1 >= L),
- ?line t(R1 < H).
-
-
-%%
-%%
-strong_rand_test(doc) ->
- "strong_rand_mpint and strong_random_bytes testing";
-strong_rand_test(suite) ->
- [];
-strong_rand_test(Config) when is_list(Config) ->
- strong_rand_aux_test(180),
- ?line 10 = byte_size(crypto:strong_rand_bytes(10)).
-
-strong_rand_aux_test(0) ->
- ?line t(crypto:strong_rand_mpint(0,0,0) =:= <<0,0,0,0>>),
- ok;
-strong_rand_aux_test(1) ->
- ?line t(crypto:erlint(crypto:strong_rand_mpint(1,0,1)) =:= 1),
- ?line strong_rand_aux_test(0);
-strong_rand_aux_test(N) ->
- ?line t(sru_length(crypto:strong_rand_mpint(N,-1,0)) =< N),
- ?line t(sru_length(crypto:strong_rand_mpint(N,0,0)) =:= N),
- ?line t(crypto:erlint(crypto:strong_rand_mpint(N,0,1)) band 1 =:= 1),
- ?line t(crypto:erlint(crypto:strong_rand_mpint(N,1,0)) bsr (N - 2) =:= 2#11),
- ?line strong_rand_aux_test(N-1).
-
-sru_length(Mpint) ->
- I = crypto:erlint(Mpint),
- length(erlang:integer_to_list(I, 2)).
-
-%%
-%%
-%%
-%%
-rsa_verify_test(doc) ->
- "rsa_verify testing (A ^ M % P with bignums)";
-rsa_verify_test(suite) ->
- [];
-rsa_verify_test(Config) when is_list(Config) ->
- ?line H = <<178,28,54,104,36,80,144,66,140,201,135,17,36,97,114,124,
- 194,164,172,147>>,
- ?line SigBlob = <<153,44,121,71,132,1,192,159,78,33,29,62,153,64,191,70,
- 208,239,166,208,220,167,49,111,128,67,91,253,24,63,194,241,
- 97,157,135,226,121,162,150,156,60,49,236,90,151,67,239,23,
- 92,103,89,254,17,165,78,181,64,128,13,210,86,111,209,76,
- 115,34,107,227,151,47,80,185,143,85,202,55,245,163,226,26,
- 139,104,196,6,96,82,108,197,13,0,12,70,153,109,107,180,
- 130,246,156,182,56,96,31,220,227,218,136,211,252,43,8,14,
- 145,155,191,206,72,194,80,52,54,206,53,27,6,188,195,29>>,
- ?line BadSigBlob = <<153,44,121,71,132,1,192,159,78,33,29,62,153,64,191,70,
- 208,239,166,208,220,167,49,111,128,67,91,253,24,63,194,241,
- 97,157,135,226,121,162,150,156,60,49,236,90,151,67,239,23,
- 92,103,89,254,17,165,78,181,64,128,13,210,86,111,209,76,
- 115,107,34,227,151,47,80,185,143,85,202,55,245,163,226,26,
- 139,104,196,6,96,82,108,197,13,0,12,70,153,109,107,180,
- 130,246,156,182,56,96,31,220,227,218,136,211,252,43,8,14,
- 145,155,191,206,72,194,80,52,54,206,53,27,6,188,195,29>>,
- ?line E = <<35>>,
- ?line N = <<0,199,209,142,191,86,92,148,103,37,250,217,175,169,109,10,
- 130,139,34,237,174,90,97,118,7,185,57,137,252,236,177,193,
- 228,16,62,29,153,144,64,207,152,240,152,206,136,89,64,6,
- 3,187,89,57,241,219,88,215,75,70,120,20,145,229,37,1,
- 67,138,204,17,39,231,249,239,116,142,169,99,149,41,65,123,
- 26,225,133,0,41,85,77,181,35,100,162,223,92,220,207,50,
- 63,168,193,171,174,199,23,214,201,63,157,76,125,6,54,73,
- 76,89,40,33,147,208,189,76,98,24,61,8,10,110,165,119,165>>,
- ?line Nbad = <<0,199,209,142,191,86,92,148,103,37,250,217,175,169,109,10,
- 130,139,34,237,174,90,97,118,7,185,57,137,252,236,177,193,
- 228,16,62,29,153,144,64,207,152,240,152,206,136,89,64,6,
- 3,187,89,57,241,219,88,215,75,70,120,20,145,229,37,1,
- 67,138,204,17,39,231,249,239,116,142,169,99,149,41,65,123,
- 26,225,133,0,41,85,77,181,35,100,162,223,92,220,207,50,
- 63,168,193,171,174,199,23,214,201,63,157,76,125,6,54,73,
- 76,89,40,33,147,189,208,76,98,24,61,8,10,110,165,119,165>>,
- ?line Ebad = <<77>>,
- ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob),
- [sized_binary(E), sized_binary(N)]), true),
- ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob),
- [sized_binary(Ebad), sized_binary(N)]), false),
- ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob),
- [sized_binary(E), sized_binary(Nbad)]), false),
- ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(BadSigBlob),
- [sized_binary(E), sized_binary(N)]), false).
-
-%%
-%%
-dsa_verify_test(doc) ->
- "dsa_verify testing (A ^ M % P with bignums)";
-dsa_verify_test(suite) ->
- [];
-dsa_verify_test(Config) when is_list(Config) ->
- ?line Msg = <<48,130,2,245,160,3,2,1,2,2,1,1,48,9,6,7,42,134,72,206,56,4,3,48,
- 58,49,11,48,9,6,3,85,4,6,19,2,85,83,49,26,48,24,6,3,85,4,10,19,17,
- 84,101,115,116,32,67,101,114,116,105,102,105,99,97,116,101,115,49,
- 15,48,13,6,3,85,4,3,19,6,68,83,65,32,67,65,48,30,23,13,48,49,48,
- 52,49,57,49,52,53,55,50,48,90,23,13,49,49,48,52,49,57,49,52,53,55,
- 50,48,90,48,93,49,11,48,9,6,3,85,4,6,19,2,85,83,49,26,48,24,6,3,
- 85,4,10,19,17,84,101,115,116,32,67,101,114,116,105,102,105,99,97,
- 116,101,115,49,50,48,48,6,3,85,4,3,19,41,86,97,108,105,100,32,68,
- 83,65,32,83,105,103,110,97,116,117,114,101,115,32,69,69,32,67,101,
- 114,116,105,102,105,99,97,116,101,32,84,101,115,116,52,48,130,1,
- 182,48,130,1,43,6,7,42,134,72,206,56,4,1,48,130,1,30,2,129,129,0,
- 228,139,175,64,140,21,215,61,124,238,3,150,18,104,193,32,5,232,23,
- 202,158,116,101,75,154,84,151,42,120,51,218,165,197,114,234,52,
- 179,148,104,66,213,27,253,119,240,168,66,158,100,147,144,182,194,
- 2,49,70,19,122,3,105,204,152,45,86,157,94,35,95,40,191,173,127,15,
- 208,105,149,98,92,26,7,42,94,140,115,73,126,253,18,34,142,85,229,
- 86,233,174,114,41,150,135,8,39,215,119,67,240,134,184,9,10,27,20,
- 165,230,3,230,69,121,77,233,250,83,95,193,9,189,126,197,195,2,21,
- 0,128,63,228,252,243,76,229,62,203,15,23,10,42,84,108,208,103,108,
- 13,59,2,129,128,102,212,22,138,32,173,254,209,50,159,165,127,167,
- 179,208,234,119,63,235,108,162,228,41,216,216,188,33,221,154,247,
- 204,229,180,119,77,223,236,218,162,140,156,117,18,90,31,254,102,
- 211,17,194,239,132,67,236,169,136,110,76,186,76,63,53,150,199,103,
- 252,153,189,15,153,41,19,145,78,216,2,174,254,107,175,80,86,170,
- 47,30,181,42,200,238,34,71,37,120,107,33,221,20,63,206,240,16,129,
- 247,150,29,156,65,187,94,68,146,93,46,198,30,184,205,105,200,143,
- 63,59,62,208,79,162,206,217,3,129,132,0,2,129,128,15,83,40,172,56,
- 47,61,243,17,97,65,195,61,167,214,122,247,246,1,50,211,33,113,16,
- 20,213,195,62,77,235,25,162,140,175,158,8,61,65,10,255,204,162,71,
- 130,122,86,161,163,253,236,178,139,183,57,181,202,160,25,133,130,
- 155,150,104,168,187,107,186,144,164,225,173,101,182,68,49,210,30,
- 34,47,83,65,79,250,156,248,47,232,44,67,36,22,126,43,216,100,247,
- 100,250,240,121,72,29,185,2,109,144,54,204,235,54,15,242,57,171,
- 125,39,236,247,71,111,221,51,196,126,77,238,36,87,163,107,48,105,
- 48,29,6,3,85,29,14,4,22,4,20,179,51,215,81,162,4,13,68,251,157,64,
- 241,18,98,113,176,83,246,105,13,48,31,6,3,85,29,35,4,24,48,22,128,
- 20,116,21,213,36,28,189,94,101,136,31,225,139,9,126,127,234,25,72,
- 78,97,48,23,6,3,85,29,32,4,16,48,14,48,12,6,10,96,134,72,1,101,3,
- 2,1,48,1,48,14,6,3,85,29,15,1,1,255,4,4,3,2,6,192>>,
-
- ?line SigBlob = <<48,45,2,21,0,140,167,200,210,153,212,64,155,249,33,146,104,243,
- 39,38,9,115,162,89,24,2,20,76,254,31,128,187,48,128,215,216,
- 112,198,78,118,160,217,157,180,246,64,234>>,
- ?line P_p = 157224271412839155721795253728878055347359513988016145491388196653004661857517720927482198111104095793441029858267073789634147217022008635826863307553453131345099940951090826856271796188522037524757740796268675508118348391218066949174594918958269259937813776150149068811425194955973128428675945283593831134219,
- ?line Q_p = 1181895316321540581845959276009400765315408342791,
- ?line G_p = 143872196713149000950547166575757355261637863805587906227228163275557375159769599033632918292482002186641475268486598023281100659643528846513898847919251032731261718358900479488287933293278745715922865499005559197328388506945134386346185262919258658109015074718441639029135304654725637911172671711310801418648,
-
- ?line Key = 12603618348903387232593303690286336220738319446775939686476278478034365380027994899970214309288018488811754534229198764622077544117034174589418477472887827980332636062691833965078594576024299807057520016043084384987871640003684704483975314128362610573625803532737054022545217931847268776098203204571431581966,
-
- ValidKey = [crypto:mpint(P_p),
- crypto:mpint(Q_p),
- crypto:mpint(G_p),
- crypto:mpint(Key)
- ],
-
- ?line m(my_dss_verify(sized_binary(Msg), sized_binary(SigBlob),
- ValidKey), true),
-
- BadMsg = one_bit_wrong(Msg),
- ?line m(my_dss_verify(sized_binary(BadMsg), sized_binary(SigBlob),
- ValidKey), false),
- BadSig = one_bit_wrong(SigBlob),
- ?line m(my_dss_verify(sized_binary(Msg), sized_binary(BadSig),
- ValidKey), false),
- SizeErr = size(SigBlob) - 13,
-
- BadArg = (catch my_dss_verify(sized_binary(Msg), <<SizeErr:32, SigBlob/binary>>,
- ValidKey)),
- badarg = case element(1,element(2,BadArg)) of
- badarg -> badarg;
- function_clause -> badarg;
- X -> X
- end,
- InValidKey = [crypto:mpint(P_p),
- crypto:mpint(Q_p),
- crypto:mpint(G_p),
- crypto:mpint(Key+17)
- ],
-
- ?line m(my_dss_verify(sized_binary(Msg), sized_binary(SigBlob),
- InValidKey), false).
-
-
-one_bit_wrong(List) when is_list(List) ->
- lists:map(fun(Bin) -> one_bit_wrong(Bin) end, List);
-one_bit_wrong(Bin) ->
- Half = size(Bin) div 2,
- <<First:Half/binary, Byte:8, Last/binary>> = Bin,
- <<First/binary, (Byte+1):8, Last/binary>>.
-
-
-%%
-%% Sign tests
-
-rsa_sign_test(doc) ->
- "rsa_sign testing";
-rsa_sign_test(suite) ->
- [];
-rsa_sign_test(Config) when is_list(Config) ->
- PubEx = 65537,
- PrivEx = 7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945,
- Mod = 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123,
- Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
- "09812312908312378623487263487623412039812 huagasd">>,
-
- PrivKey = [PubEx, Mod, PrivEx],
- PubKey = [PubEx, Mod],
- PubKeyMpint = map_int_to_mpint(PubKey),
- Sig1 = crypto:rsa_sign(sized_binary(Msg), map_int_to_mpint(PrivKey)),
- Sig1 = crypto:sign(rsa, sha, Msg, PrivKey),
- true = crypto:rsa_verify(sized_binary(Msg), sized_binary(Sig1), PubKeyMpint),
- true = crypto:verify(rsa, sha, Msg, Sig1, PubKey),
-
- Sig2 = crypto:rsa_sign(md5, sized_binary(Msg), map_int_to_mpint(PrivKey)),
- Sig2 = crypto:sign(rsa, md5, Msg, PrivKey),
- true = crypto:rsa_verify(md5, sized_binary(Msg), sized_binary(Sig2), PubKeyMpint),
- true = crypto:verify(rsa, md5, Msg, Sig2, PubKey),
-
- false = (Sig1 =:= Sig2),
- false = crypto:rsa_verify(md5, sized_binary(Msg), sized_binary(Sig1), PubKeyMpint),
- false = crypto:verify(rsa, md5, Msg, Sig1, PubKey),
- true = crypto:rsa_verify(sha, sized_binary(Msg), sized_binary(Sig1), PubKeyMpint),
- true = crypto:verify(rsa, sha, Msg, Sig1, PubKey),
-
- ok.
-map_int_to_mpint(List) ->
- lists:map(fun(E) -> crypto:mpint(E) end, List).
-
-rsa_sign_hash_test(doc) ->
- "rsa_sign_hash testing";
-rsa_sign_hash_test(suite) ->
- [];
-rsa_sign_hash_test(Config) when is_list(Config) ->
- PubEx = 65537,
- PrivEx = 7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945,
- Mod = 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123,
- Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
- "09812312908312378623487263487623412039812 huagasd">>,
-
- PrivKey = [crypto:mpint(PubEx), crypto:mpint(Mod), crypto:mpint(PrivEx)],
- PubKey = [crypto:mpint(PubEx), crypto:mpint(Mod)],
- MD5 = crypto:md5(sized_binary(Msg)),
- SHA = crypto:sha(sized_binary(Msg)),
- ?line Sig1 = crypto:rsa_sign(sha, {digest,SHA}, PrivKey),
- ?line m(crypto:rsa_verify(sha, {digest,SHA}, sized_binary(Sig1),PubKey), true),
-
- ?line Sig2 = crypto:rsa_sign(md5, {digest,MD5}, PrivKey),
- ?line m(crypto:rsa_verify(md5, {digest,MD5}, sized_binary(Sig2),PubKey), true),
-
- ?line m(Sig1 =:= Sig2, false),
- ?line m(crypto:rsa_verify(md5, {digest,MD5}, sized_binary(Sig1),PubKey), false),
- ?line m(crypto:rsa_verify(sha, {digest,SHA}, sized_binary(Sig2),PubKey), false),
-
- ok.
-
-dsa_sign_test(doc) ->
- "dsa_sign testing";
-dsa_sign_test(suite) ->
- [];
-dsa_sign_test(Config) when is_list(Config) ->
- Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
- "09812312908312378623487263487623412039812 huagasd">>,
-
- PubKey = _Y = 25854665488880835237281628794585130313500176551981812527054397586638455298000483144002221850980183404910190346416063318160497344811383498859129095184158800144312512447497510551471331451396405348497845813002058423110442376886564659959543650802132345311573634832461635601376738282831340827591903548964194832978,
- PrivKey = _X = 441502407453038284293378221372000880210588566361,
- ParamP = 109799869232806890760655301608454668257695818999841877165019612946154359052535682480084145133201304812979481136659521529774182959764860329095546511521488413513097576425638476458000255392402120367876345280670101492199681798674053929238558140260669578407351853803102625390950534052428162468100618240968893110797,
- ParamQ = 1349199015905534965792122312016505075413456283393,
- ParamG = 18320614775012672475365915366944922415598782131828709277168615511695849821411624805195787607930033958243224786899641459701930253094446221381818858674389863050420226114787005820357372837321561754462061849169568607689530279303056075793886577588606958623645901271866346406773590024901668622321064384483571751669,
-
- Params = [crypto:mpint(ParamP), crypto:mpint(ParamQ), crypto:mpint(ParamG)],
- ?line Sig1 = my_dss_sign(sized_binary(Msg), Params ++ [crypto:mpint(PrivKey)]),
-
- ?line m(my_dss_verify(sized_binary(Msg), Sig1,
- Params ++ [crypto:mpint(PubKey)]), true),
-
- ?line m(my_dss_verify(sized_binary(one_bit_wrong(Msg)), Sig1,
- Params ++ [crypto:mpint(PubKey)]), false),
-
- ?line m(my_dss_verify(sized_binary(Msg), one_bit_wrong(Sig1),
- Params ++ [crypto:mpint(PubKey)]), false),
-
- %%?line Bad = crypto:dss_sign(sized_binary(Msg), [Params, crypto:mpint(PubKey)]),
-
- ok.
-
-dsa_sign_hash_test(doc) ->
- "dsa_sign_hash testing";
-dsa_sign_hash_test(suite) ->
- [];
-dsa_sign_hash_test(Config) when is_list(Config) ->
- Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
- "09812312908312378623487263487623412039812 huagasd">>,
- SHA = crypto:sha(sized_binary(Msg)),
-
- PubKey = _Y = 25854665488880835237281628794585130313500176551981812527054397586638455298000483144002221850980183404910190346416063318160497344811383498859129095184158800144312512447497510551471331451396405348497845813002058423110442376886564659959543650802132345311573634832461635601376738282831340827591903548964194832978,
- PrivKey = _X = 441502407453038284293378221372000880210588566361,
- ParamP = 109799869232806890760655301608454668257695818999841877165019612946154359052535682480084145133201304812979481136659521529774182959764860329095546511521488413513097576425638476458000255392402120367876345280670101492199681798674053929238558140260669578407351853803102625390950534052428162468100618240968893110797,
- ParamQ = 1349199015905534965792122312016505075413456283393,
- ParamG = 18320614775012672475365915366944922415598782131828709277168615511695849821411624805195787607930033958243224786899641459701930253094446221381818858674389863050420226114787005820357372837321561754462061849169568607689530279303056075793886577588606958623645901271866346406773590024901668622321064384483571751669,
-
- Params = [crypto:mpint(ParamP), crypto:mpint(ParamQ), crypto:mpint(ParamG)],
- ?line Sig1 = crypto:dss_sign(sha, {digest,SHA}, Params ++ [crypto:mpint(PrivKey)]),
-
- ?line m(crypto:dss_verify(none, SHA, sized_binary(Sig1),
- Params ++ [crypto:mpint(PubKey)]), true),
-
- ?line m(crypto:dss_verify(sized_binary(one_bit_wrong(Msg)), sized_binary(Sig1),
- Params ++ [crypto:mpint(PubKey)]), false),
-
- ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(one_bit_wrong(Sig1)),
- Params ++ [crypto:mpint(PubKey)]), false),
-
- %%?line Bad = crypto:dss_sign(sized_binary(Msg), [Params, crypto:mpint(PubKey)]),
-
- ok.
-
-
-rsa_encrypt_decrypt(doc) ->
- ["Test rsa_public_encrypt and rsa_private_decrypt functions."];
-rsa_encrypt_decrypt(suite) -> [];
-rsa_encrypt_decrypt(Config) when is_list(Config) ->
- PubEx = 65537,
- PrivEx = 7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945,
- Mod = 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123,
-
- PrivKey = [PubEx, Mod, PrivEx],
- PubKey = [PubEx, Mod],
-
- Msg = <<"7896345786348 Asldi">>,
-
- ?line PKCS1 = rsa_public_encrypt(Msg, PubKey, rsa_pkcs1_padding),
- ?line PKCS1Dec = rsa_private_decrypt(PKCS1, PrivKey, rsa_pkcs1_padding),
- io:format("PKCS1Dec ~p~n",[PKCS1Dec]),
- ?line Msg = PKCS1Dec,
-
- ?line OAEP = rsa_public_encrypt(Msg, PubKey, rsa_pkcs1_oaep_padding),
- ?line Msg = rsa_private_decrypt(OAEP, PrivKey, rsa_pkcs1_oaep_padding),
-
- <<Msg2Len:32,_/binary>> = crypto:mpint(Mod),
- Msg2 = list_to_binary(lists:duplicate(Msg2Len-1, $X)),
- ?line NoPad = rsa_public_encrypt(Msg2, PubKey, rsa_no_padding),
- ?line NoPadDec = rsa_private_decrypt(NoPad, PrivKey, rsa_no_padding),
- ?line NoPadDec = Msg2,
-
- ShouldBeError = (catch rsa_public_encrypt(Msg, PubKey, rsa_no_padding)),
- ?line {'EXIT', {encrypt_failed,_}} = ShouldBeError,
-
-%% ?line SSL = rsa_public_encrypt(Msg, PubKey, rsa_sslv23_padding),
-%% ?line Msg = rsa_private_decrypt(SSL, PrivKey, rsa_sslv23_padding),
-
- ?line PKCS1_2 = rsa_private_encrypt(Msg, PrivKey, rsa_pkcs1_padding),
- ?line PKCS1_2Dec = rsa_public_decrypt(PKCS1_2, PubKey, rsa_pkcs1_padding),
- io:format("PKCS2Dec ~p~n",[PKCS1_2Dec]),
- ?line Msg = PKCS1_2Dec,
-
- ?line PKCS1_3 = rsa_private_encrypt(Msg2, PrivKey, rsa_no_padding),
- ?line PKCS1_3Dec = rsa_public_decrypt(PKCS1_3, PubKey, rsa_no_padding),
- io:format("PKCS2Dec ~p~n",[PKCS1_3Dec]),
- ?line Msg2 = PKCS1_3Dec,
-
- ?line {'EXIT', {encrypt_failed,_}} =
- (catch rsa_private_encrypt(Msg, PrivKey, rsa_no_padding)),
-
- ok.
-
-rsa_public_encrypt(Msg, Key, Pad) ->
- C1 = crypto:rsa_public_encrypt(Msg, Key, Pad),
- C2 = crypto:rsa_public_encrypt(Msg, lists:map(fun(E) -> crypto:mpint(E) end, Key), Pad),
- {C1,C2}.
-
-rsa_public_decrypt(Msg, Key, Pad) ->
- R = crypto:rsa_public_decrypt(Msg, Key, Pad),
- R = crypto:rsa_public_decrypt(Msg, lists:map(fun(E) -> crypto:mpint(E) end, Key), Pad).
-
-rsa_private_encrypt(Msg, Key, Pad) ->
- R = crypto:rsa_private_encrypt(Msg, Key, Pad),
- R = crypto:rsa_private_encrypt(Msg, lists:map(fun(E) -> crypto:mpint(E) end, Key), Pad).
-
-rsa_private_decrypt({C1,C2}, Key, Pad) ->
- R = crypto:rsa_private_decrypt(C1, Key, Pad),
- R = crypto:rsa_private_decrypt(C2, Key, Pad),
- R = crypto:rsa_private_decrypt(C1, lists:map(fun(E) -> crypto:mpint(E) end, Key), Pad),
- R = crypto:rsa_private_decrypt(C2, lists:map(fun(E) -> crypto:mpint(E) end, Key), Pad).
-
-
-dh(doc) ->
- ["Test dh (Diffie-Hellman) functions."];
-dh(suite) -> [];
-dh(Config) when is_list(Config) ->
- Self = self(),
- GenP = fun() ->
- %% Gen Param may take arbitrary long time to finish
- %% That's not a bug in erlang crypto application.
- ?line DHPs = crypto:dh_generate_parameters(512,2),
- ?line ok = crypto:dh_check(DHPs),
- Self ! {param, DHPs}
- end,
- Pid = spawn(GenP),
- receive
- {param, DHPs} ->
- timer:sleep(100),
- io:format("DHP ~p~n", [DHPs]),
- DHPs_mpint = lists:map(fun(E) -> sized_binary(E) end, DHPs),
- ?line {Pub1,Priv1} = crypto:generate_key(dh, DHPs),
- io:format("Key1:~n~p~n~p~n~n", [Pub1,Priv1]),
- ?line {Pub2,Priv2} = crypto:dh_generate_key(DHPs_mpint),
- io:format("Key2:~n~p~n~p~n~n", [Pub2,Priv2]),
- ?line A = crypto:compute_key(dh, Pub1, unsized_binary(Priv2), DHPs),
- ?line A = crypto:dh_compute_key(sized_binary(Pub1), Priv2, DHPs_mpint),
- timer:sleep(100), %% Get another thread see if that triggers problem
- ?line B = crypto:compute_key(dh, unsized_binary(Pub2), Priv1, DHPs),
- ?line B = crypto:dh_compute_key(Pub2, sized_binary(Priv1), DHPs_mpint),
- io:format("A ~p~n",[A]),
- io:format("B ~p~n",[B]),
- ?line A = B
- after 50000 ->
- io:format("Killing Param generation which took to long ~p~n",[Pid]),
- exit(Pid, kill)
- end.
-
-
-ec(doc) ->
- ["Test ec (Ecliptic Curve) functions."];
-ec(suite) -> [];
-ec(Config) when is_list(Config) ->
- if_supported(ecdh, fun() -> ec_do() end).
-
-ec_do() ->
- %% test for a name curve
- NamedCurve = hd(crypto:ec_curves()),
- {D2_pub, D2_priv} = crypto:generate_key(ecdh, NamedCurve),
- PrivECDH = [D2_priv, NamedCurve],
- PubECDH = [D2_pub, NamedCurve],
- %%TODO: find a published test case for a EC key
-
- Msg = <<99,234,6,64,190,237,201,99,80,248,58,40,70,45,149,218,5,246,242,63>>,
- Sign = crypto:sign(ecdsa, sha, Msg, PrivECDH),
- ?line true = crypto:verify(ecdsa, sha, Msg, Sign, PubECDH),
- ?line false = crypto:verify(ecdsa, sha, Msg, <<10,20>>, PubECDH),
-
- ok.
-
-srp3(doc) ->
- ["SRP-3 test vectors generated by http://srp.stanford.edu/demo/demo.html"];
-srp3(suite) -> [];
-srp3(Config) when is_list(Config) ->
- Username = <<"alice">>,
- Password = <<"password123">>,
- Salt = hexstr2bin("2857827A19266A1F2BC6"),
- Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
- "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
- "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
- "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
- "FD5138FE8376435B9FC61D2FC0EB06E3"),
- Generator = <<2>>,
- Version = '3',
- Scrambler = hexstr2bin("02E2476A"),
-
- %% X = hexstr2bin("96E54AB0CD4C5123EDCFA4A1502918AAD3C9E2A8"),
- Verifier = hexstr2bin("96EB5F13621D911AA1CA405DE9C64217D4108EEEECAFFE500034FE0E"
- "C031E42C8714667C161BCE0E7996F7DDE1B63824C130D2D7286C08C0"
- "49758420735961347112AE102A3F23B3F687F8FEE0DF2BFAF933C608"
- "D6FE5B5EEE3116FE54016E065BF8E8C9FDBBC08719231AC215149140"
- "519E8FDD9AA4F410C28A58AF42974D2D"),
- ClientPrivate = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
- "49C75C7B"),
- ServerPrivate = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
- "9AADCF8B"),
- ClientPublic = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
- "55C79E7A118865DC59B9D0353362C2A8261E7C1B0D221A0E233C2AD1"
- "640DACBB8664CBC9733EAC392DA7800142860380C3FC573C3C064329"
- "CF54063FD114C7210E9CB3A611EA8002B1844B698F930D95D143899B"
- "948A090E0C25938E5F84067D1883DC63"),
- ServerPublic = hexstr2bin("93A8C4D8B7F7395ADCFD4ABA37B015124513D3F37B3E85EB23064BE5"
- "F53C0AE32FFB9D8C0AA0DCFFA74D632DD67DEBB5C35AAE9812286CC8"
- "C43CC176ECBC6D3F447594D9554E995B2509127BF88FADDDA4982D03"
- "8EC3001320712D3B1269308CE70F319B2295FA57674F03A2D993CFB1"
- "F84C35B7D0C012FA73CD4C8F7D5A71C7"),
-
- SessionKey = hexstr2bin("C29A986C4D521BBC66428ED11D994CD7431574A6184B83CDCC345092"
- "791E75748A1D38CAC4BD14760F0D2694B711236419240FF2F172454C"
- "46ABF4FF39498DAFDD2C82924F7D7BD76CDFCE688C77D93F18A65409"
- "9176A9192615DC0277AE7C12F1F6A7F6563FCA11675D809AF578BDE5"
- "2B51E05D440B63099A017A0B45044801"),
- UserPassHash = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]),
- Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
- ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
-
- {ClientPublic, ClientPrivate} = crypto:generate_key(srp, {user, [Generator, Prime, Version]}, ClientPrivate),
- {ServerPublic, ServerPrivate} = crypto:generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, ServerPrivate),
- SessionKey = crypto:compute_key(srp, ServerPublic, {ClientPublic, ClientPrivate},
- {user, [UserPassHash, Prime, Generator, Version, Scrambler]}),
- SessionKey = crypto:compute_key(srp, ClientPublic, {ServerPublic, ServerPrivate},
- {host, [Verifier, Prime, Version, Scrambler]}).
-
-srp6(doc) ->
- ["SRP-6 test vectors generated by http://srp.stanford.edu/demo/demo.html"];
-srp6(suite) -> [];
-srp6(Config) when is_list(Config) ->
- Username = <<"alice">>,
- Password = <<"password123">>,
- Salt = hexstr2bin("2857827A19266A1F2BC6"),
- Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
- "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
- "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
- "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
- "FD5138FE8376435B9FC61D2FC0EB06E3"),
- Generator = <<2>>,
- Version = '6',
- Scrambler = hexstr2bin("0A2534C0BF52A0DA9001EEC62CF2A546AB0908A7"),
- Verifier = hexstr2bin("96EB5F13621D911AA1CA405DE9C64217D4108EEEECAFFE500034FE0E"
- "C031E42C8714667C161BCE0E7996F7DDE1B63824C130D2D7286C08C0"
- "49758420735961347112AE102A3F23B3F687F8FEE0DF2BFAF933C608"
- "D6FE5B5EEE3116FE54016E065BF8E8C9FDBBC08719231AC215149140"
- "519E8FDD9AA4F410C28A58AF42974D2D"),
- ClientPrivate = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
- "49C75C7B"),
- ServerPrivate = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
- "9AADCF8B"),
- ClientPublic = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
- "55C79E7A118865DC59B9D0353362C2A8261E7C1B0D221A0E233C2AD1"
- "640DACBB8664CBC9733EAC392DA7800142860380C3FC573C3C064329"
- "CF54063FD114C7210E9CB3A611EA8002B1844B698F930D95D143899B"
- "948A090E0C25938E5F84067D1883DC63"),
- ServerPublic = hexstr2bin("D2D07845CE7ECDB9845DD36B10ACD3598CC29049DE9F467F84CE16B6"
- "D97A6DC567AF8B0F9FEDF74962400AD5C357951E64E67B641246F264"
- "C8DE6D9A72E554D6C8D3194548780A0C438A0FCC509CA88A14AA1DEB"
- "C0F09E4B37A965D1545DB4AD361346F3189B0EA569C06D326C4E4797"
- "9E381C748293B7C0591BE0BE419E053E"),
-
- SessionKey = hexstr2bin("19D22C19612874EBF1F2581F8EFCFDC44C6FDA3B87B0A73823D7E962"
- "554295D4E48D3A336523ADBDDD0EC8FB0F02687109E97E01C17C93CC"
- "7216F9CD8A4AC39F0429857D8D1023066614BDFCBCB89F59A0FEB81C"
- "72E992AAD89095A84B6A5FADA152369AB1E350A03693BEF044DF3EDF"
- "0C34741F4696C30E9F675D09F58ACBEB"),
- UserPassHash = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]),
- Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
- ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
-
- {ClientPublic, ClientPrivate} = crypto:generate_key(srp, {user, [Generator, Prime, Version]}, ClientPrivate),
- {ServerPublic, ServerPrivate} = crypto:generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, ServerPrivate),
- SessionKey = crypto:compute_key(srp, ServerPublic, {ClientPublic, ClientPrivate},
- {user, [UserPassHash, Prime, Generator, Version, Scrambler]}),
- SessionKey = crypto:compute_key(srp, ClientPublic, {ServerPublic, ServerPrivate},
- {host, [Verifier, Prime, Version, Scrambler]}).
-
-srp6a(doc) ->
- ["SRP-6a test vectors from RFC5054."];
-srp6a(suite) -> [];
-srp6a(Config) when is_list(Config) ->
- Username = <<"alice">>,
- Password = <<"password123">>,
- Salt = hexstr2bin("BEB25379D1A8581EB5A727673A2441EE"),
- Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
- "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
- "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
- "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
- "FD5138FE8376435B9FC61D2FC0EB06E3"),
- Generator = <<2>>,
- Version = '6a',
- Scrambler = hexstr2bin("CE38B9593487DA98554ED47D70A7AE5F462EF019"),
- Verifier = hexstr2bin("7E273DE8696FFC4F4E337D05B4B375BEB0DDE1569E8FA00A9886D812"
- "9BADA1F1822223CA1A605B530E379BA4729FDC59F105B4787E5186F5"
- "C671085A1447B52A48CF1970B4FB6F8400BBF4CEBFBB168152E08AB5"
- "EA53D15C1AFF87B2B9DA6E04E058AD51CC72BFC9033B564E26480D78"
- "E955A5E29E7AB245DB2BE315E2099AFB"),
- ClientPrivate = hexstr2bin("60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DD"
- "DA2D4393"),
- ServerPrivate = hexstr2bin("E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D1"
- "05284D20"),
- ClientPublic = hexstr2bin("61D5E490F6F1B79547B0704C436F523DD0E560F0C64115BB72557EC4"
- "4352E8903211C04692272D8B2D1A5358A2CF1B6E0BFCF99F921530EC"
- "8E39356179EAE45E42BA92AEACED825171E1E8B9AF6D9C03E1327F44"
- "BE087EF06530E69F66615261EEF54073CA11CF5858F0EDFDFE15EFEA"
- "B349EF5D76988A3672FAC47B0769447B"),
- ServerPublic = hexstr2bin("BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011"
- "BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC99"
- "6C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA"
- "37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAE"
- "EB4012B7D7665238A8E3FB004B117B58"),
-
- SessionKey = hexstr2bin("B0DC82BABCF30674AE450C0287745E7990A3381F63B387AAF271A10D"
- "233861E359B48220F7C4693C9AE12B0A6F67809F0876E2D013800D6C"
- "41BB59B6D5979B5C00A172B4A2A5903A0BDCAF8A709585EB2AFAFA8F"
- "3499B200210DCC1F10EB33943CD67FC88A2F39A4BE5BEC4EC0A3212D"
- "C346D7E474B29EDE8A469FFECA686E5A"),
- UserPassHash = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]),
- Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
-
- {ClientPublic, ClientPrivate} = crypto:generate_key(srp, {user, [Generator, Prime, Version]}, ClientPrivate),
- {ServerPublic, ServerPrivate} = crypto:generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, ServerPrivate),
-
- SessionKey = crypto:compute_key(srp, ServerPublic, {ClientPublic, ClientPrivate},
- {user, [UserPassHash, Prime, Generator, Version, Scrambler]}),
- SessionKey = crypto:compute_key(srp, ClientPublic, {ServerPublic, ServerPrivate},
- {host, [Verifier, Prime, Version, Scrambler]}).
-
-%%
-%%
-exor_test(doc) ->
- ["Test the exor function."];
-exor_test(suite) ->
- [];
-exor_test(Config) when is_list(Config) ->
- B = <<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>>,
- Z1 = zero_bin(B),
- Z1 = crypto:exor(B, B),
- B1 = crypto:strong_rand_bytes(100),
- B2 = crypto:strong_rand_bytes(100),
- Z2 = zero_bin(B1),
- Z2 = crypto:exor(B1, B1),
- Z2 = crypto:exor(B2, B2),
- R = xor_bytes(B1, B2),
- R = crypto:exor(B1, B2),
- ok.
-
-%%
-%%
-rc4_test(doc) ->
- ["Test rc4 encryption ."];
-rc4_test(suite) ->
- [];
-rc4_test(Config) when is_list(Config) ->
- CT1 = <<"Yo baby yo">>,
- R1 = <<118,122,68,110,157,166,141,212,139,39>>,
- K = "apaapa",
- R1 = crypto:rc4_encrypt(K, CT1),
- CT1 = crypto:rc4_encrypt(K, R1),
- CT2 = lists:seq(0, 255),
- R2 = crypto:rc4_encrypt(K, CT2),
- CT2 = binary_to_list(crypto:rc4_encrypt(K, R2)),
- ok.
-
-rc4_stream_test(doc) ->
- ["Test rc4 stream encryption ."];
-rc4_stream_test(suite) ->
- [];
-rc4_stream_test(Config) when is_list(Config) ->
- CT1 = <<"Yo ">>,
- CT2 = <<"baby yo">>,
- K = "apaapa",
- State0 = crypto:rc4_set_key(K),
- {State1, R1} = crypto:rc4_encrypt_with_state(State0, CT1),
- {_State2, R2} = crypto:rc4_encrypt_with_state(State1, CT2),
- R = list_to_binary([R1, R2]),
- <<118,122,68,110,157,166,141,212,139,39>> = R,
- ok.
-
-blowfish_cfb64(doc) -> ["Test Blowfish encrypt/decrypt."];
-blowfish_cfb64(suite) -> [];
-blowfish_cfb64(Config) when is_list(Config) ->
- Key = <<1,35,69,103,137,171,205,239,240,225,210,195,180,165,150,135>>,
-
- IVec = <<254,220,186,152,118,84,50,16>>,
- Plain = <<"7654321 Now is the time for ">>,
- Enc = <<231,50,20,162,130,33,57,202,242,110,207,109,46,185,231,110,61,163,222,4,209,81,114,0,81,157,87,166>>,
-
- Enc = crypto:blowfish_cfb64_encrypt(Key, IVec, Plain),
- Plain = crypto:blowfish_cfb64_decrypt(Key, IVec, Enc),
-
- Key2 = <<"A2B4C">>,
- IVec2 = <<"12345678">>,
- Plain2 = <<"badger at my table....!">>,
- Enc2 = <<173,76,128,155,70,81,79,228,4,162,188,92,119,53,144,89,93,236,28,164,176,16,138>>,
-
- Enc2 = crypto:blowfish_cfb64_encrypt(Key2, IVec2, Plain2),
- Plain2 = crypto:blowfish_cfb64_decrypt(Key2, IVec2, Enc2).
-
-
-smp(doc) -> "Check concurrent access to crypto driver";
-smp(suite) -> [];
-smp(Config) ->
- case erlang:system_info(smp_support) of
- true ->
- NumOfProcs = erlang:system_info(schedulers),
- io:format("smp starting ~p workers\n",[NumOfProcs]),
- Seeds = [random:uniform(9999) || _ <- lists:seq(1,NumOfProcs)],
- Parent = self(),
- Pids = [spawn_link(fun()-> worker(Seed,Config,Parent) end)
- || Seed <- Seeds],
- wait_pids(Pids);
-
- false ->
- {skipped,"No smp support"}
- end.
-
-worker(Seed, Config, Parent) ->
- io:format("smp worker ~p, seed=~p~n",[self(),Seed]),
- random:seed(Seed,Seed,Seed),
- worker_loop(100, Config),
- %%io:format("worker ~p done\n",[self()]),
- Parent ! self().
-
-worker_loop(0, _) ->
- ok;
-worker_loop(N, Config) ->
- Funcs = { md5, md5_update, md5_mac, md5_mac_io, sha, sha_update, des_cbc,
- aes_cfb, aes_cbc, des_cbc_iter, rand_uniform_test, strong_rand_test,
- rsa_verify_test, exor_test, rc4_test, rc4_stream_test, mod_exp_test,
- hmac_update_md5, hmac_update_sha, hmac_update_sha256, hmac_update_sha512,
- hmac_rfc2202, hmac_rfc4231_sha224, hmac_rfc4231_sha256, hmac_rfc4231_sha384,
- hmac_rfc4231_sha512, aes_ctr_stream },
-
- F = element(random:uniform(size(Funcs)),Funcs),
- %%io:format("worker ~p calling ~p\n",[self(),F]),
- ?MODULE:F(Config),
- worker_loop(N-1,Config).
-
-wait_pids([]) ->
- ok;
-wait_pids(Pids) ->
- receive
- Pid ->
- ?line true = lists:member(Pid,Pids),
- Others = lists:delete(Pid,Pids),
- io:format("wait_pid got ~p, still waiting for ~p\n",[Pid,Others]),
- wait_pids(Others)
- end.
-
-%%
-%% Help functions
-%%
-
-% match
-m(X, X) ->
- ?line true.
-t(true) ->
- true.
-
-% hexstr2bin
-hexstr2bin(S) ->
- list_to_binary(hexstr2list(S)).
-
-hexstr2list([X,Y|T]) ->
- [mkint(X)*16 + mkint(Y) | hexstr2list(T)];
-hexstr2list([]) ->
- [].
-
-mkint(C) when $0 =< C, C =< $9 ->
- C - $0;
-mkint(C) when $A =< C, C =< $F ->
- C - $A + 10;
-mkint(C) when $a =< C, C =< $f ->
- C - $a + 10.
-
-%% mod_exp in erlang (copied from jungerl's ssh_math.erl)
-ipow(A, B, M) when M > 0, B >= 0 ->
- if A == 1 ->
- 1;
- true ->
- ipow(A, B, M, 1)
- end.
-
-ipow(A, 1, M, Prod) ->
- (A*Prod) rem M;
-ipow(_A, 0, _M, Prod) ->
- Prod;
-ipow(A, B, M, Prod) ->
- B1 = B bsr 1,
- A1 = (A*A) rem M,
- if B - B1 == B1 ->
- ipow(A1, B1, M, Prod);
- true ->
- ipow(A1, B1, M, (A*Prod) rem M)
- end.
-
-%%
-%% Invert an element X mod P
-%% Calculated as {1, {A,B}} = egcd(X,P),
-%% 1 == P*A + X*B == X*B (mod P) i.e B is the inverse element
-%%
-%% X > 0, P > 0, X < P (P should be prime)
-%%
-%% invert(X,P) when X > 0, P > 0, X < P ->
-%% I = inv(X,P,1,0),
-%% if
-%% I < 0 -> P + I;
-%% true -> I
-%% end.
-
-%% inv(0,_,_,Q) -> Q;
-%% inv(X,P,R1,Q1) ->
-%% D = P div X,
-%% inv(P rem X, X, Q1 - D*R1, R1).
-
-sized_binary(Binary) when is_binary(Binary) ->
- <<(size(Binary)):32/integer, Binary/binary>>;
-sized_binary(List) ->
- sized_binary(list_to_binary(List)).
-
-unsized_binary(<<Sz:32/integer, Binary:Sz/binary>>) ->
- Binary.
-
-xor_bytes(Bin1, Bin2) when is_binary(Bin1), is_binary(Bin2) ->
- L1 = binary_to_list(Bin1),
- L2 = binary_to_list(Bin2),
- list_to_binary(xor_bytes(L1, L2));
-xor_bytes(L1, L2) ->
- xor_bytes(L1, L2, []).
-
-xor_bytes([], [], Acc) ->
- lists:reverse(Acc);
-xor_bytes([N1 | Tl1], [N2 | Tl2], Acc) ->
- xor_bytes(Tl1, Tl2, [N1 bxor N2 | Acc]).
-
-zero_bin(N) when is_integer(N) ->
- N8 = N * 8,
- <<0:N8/integer>>;
-zero_bin(B) when is_binary(B) ->
- zero_bin(size(B)).
-
-my_dss_verify(Data,[Sign|Tail],Key) ->
- Res = my_dss_verify(Data,sized_binary(Sign),Key),
- case Tail of
- [] -> Res;
- _ -> ?line Res = my_dss_verify(Data,Tail,Key)
- end;
-my_dss_verify(Data,Sign,Key) ->
- ?line Res = crypto:dss_verify(Data, Sign, Key),
- ?line Res = crypto:dss_verify(sha, Data, Sign, Key),
- ?line <<_:32,Raw/binary>> = Data,
- ?line Res = crypto:dss_verify(none, crypto:sha(Raw), Sign, Key),
- Res.
-
-my_dss_sign(Data,Key) ->
- ?line S1 = crypto:dss_sign(Data, Key),
- ?line S2 = crypto:dss_sign(sha, Data, Key),
- ?line <<_:32,Raw/binary>> = Data,
- ?line S3 = crypto:dss_sign(none, crypto:sha(Raw), Key),
- [S1,S2,S3].
-
-openssl_version() ->
- case crypto:info_lib() of
- [{<<"OpenSSL">>,LibVer,_}] when is_integer(LibVer) ->
- LibVer;
- _ ->
- undefined
- end.
-
-if_supported(Algorithm, Fun) ->
- case lists:member(Algorithm, lists:append([Algo || {_, Algo} <- crypto:supports()])) of
- true ->
- Fun();
- _ ->
- {skipped, io:format("~s not spupported", [Algorithm])}
- end.
diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk
index 96466869d1..796e3b6d84 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 3.7
+CRYPTO_VSN = 4.0
diff --git a/lib/debugger/doc/src/Makefile b/lib/debugger/doc/src/Makefile
index 6c9617ca69..0f724b6f17 100644
--- a/lib/debugger/doc/src/Makefile
+++ b/lib/debugger/doc/src/Makefile
@@ -114,7 +114,7 @@ release_docs_spec: docs
$(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf"
$(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf"
$(INSTALL_DIR) "$(RELSYSDIR)/doc/html"
- (/bin/cp -rf $(HTMLDIR) "$(RELSYSDIR)/doc")
+ ($(CP) -rf $(HTMLDIR) "$(RELSYSDIR)/doc")
$(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)"
$(INSTALL_DIR) "$(RELEASE_PATH)/man/man3"
$(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3"
diff --git a/lib/debugger/doc/src/debugger_chapter.xml b/lib/debugger/doc/src/debugger_chapter.xml
index 45dfdb3776..3c37d4b924 100644
--- a/lib/debugger/doc/src/debugger_chapter.xml
+++ b/lib/debugger/doc/src/debugger_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -652,8 +652,10 @@ c_break(Bindings) ->
<item><p>The Bindings area, displaying all variables bindings. If you
click a variable name, the value is displayed in the Evaluator area.
Double-click a variable name to open a window where
- the variable value can be edited. Notice however that pid,
- reference, binary, or port values cannot be edited.</p>
+ the variable value can be edited. Notice however that pid, port,
+ reference, or fun
+ values cannot be edited unless they can be represented in the
+ running system.</p>
</item>
<item><p>The Trace area, which displays a trace output for the
diff --git a/lib/debugger/doc/src/i.xml b/lib/debugger/doc/src/i.xml
index db89f23494..628b91e9e4 100644
--- a/lib/debugger/doc/src/i.xml
+++ b/lib/debugger/doc/src/i.xml
@@ -45,7 +45,7 @@
attached manually or automatically.</p>
<p>By preference, these functions can be included in module
- <seealso marker="stdlib:shell_default"><c>stdlib:shell_default</c></seealso>.
+ <seealso marker="stdlib:shell_default"><c>shell_default</c></seealso>.
By default, they are included in that module.</p>
</description>
@@ -372,7 +372,7 @@
</fsummary>
<desc>
<p>Returns the current version number of the interpreter.
- Same as the version number of the <c>Debugger</c> application.</p>
+ Same as the version number of the Debugger application.</p>
</desc>
</func>
diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml
index 2e0d834269..fa85567a84 100644
--- a/lib/debugger/doc/src/notes.xml
+++ b/lib/debugger/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -33,6 +33,65 @@
<p>This document describes the changes made to the Debugger
application.</p>
+<section><title>Debugger 4.2.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> The Erlang shell, <c>qlc:string_to_handle()</c>, and
+ the Debugger (the Evaluator area and Edit variable window
+ of the Bindings area) can parse pids, ports, references,
+ and external funs, as long as they can be created in the
+ running system. </p>
+ <p>
+ Own Id: OTP-14296</p>
+ </item>
+ <item>
+ <p> Fix editing of simple binary values in the Bindings
+ area of the Debugger's Attach Process Window. </p>
+ <p>
+ Own Id: OTP-14318</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Miscellaneous updates due to atoms containing
+ arbitrary Unicode characters. </p>
+ <p>
+ Own Id: OTP-14285</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Debugger 4.2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Update build scripts to not make assumtions about where
+ env, cp and perl are located.</p>
+ <p>
+ Own Id: OTP-13800</p>
+ </item>
+ <item>
+ <p>
+ A bug causing non-interpreted code to crash the debugger
+ has been fixed.</p>
+ <p>
+ Own Id: OTP-13756</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Debugger 4.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/debugger/src/Makefile b/lib/debugger/src/Makefile
index 9594a0bfe3..118cb6b758 100644
--- a/lib/debugger/src/Makefile
+++ b/lib/debugger/src/Makefile
@@ -85,7 +85,7 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_obsolete_guard -Werror
+ERL_COMPILE_FLAGS += -Werror
# ----------------------------------------------------
diff --git a/lib/debugger/src/dbg_icmd.erl b/lib/debugger/src/dbg_icmd.erl
index 57a3719a50..4cd3dce670 100644
--- a/lib/debugger/src/dbg_icmd.erl
+++ b/lib/debugger/src/dbg_icmd.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -382,14 +382,19 @@ eval_restricted({From,_Mod,Cmd,SP}, Bs) ->
case catch parse_cmd(Cmd, 1) of
{'EXIT', _Reason} ->
From ! {self(), {eval_rsp, 'Parse error'}};
- [{var,_,Var}] ->
+ {[{var,_,Var}], XBs} ->
Bs2 = bindings(Bs, SP),
Res = case get_binding(Var, Bs2) of
{value, Value} -> Value;
- unbound -> unbound
+ unbound ->
+ case get_binding(Var, XBs) of
+ {value, _} ->
+ 'Only possible to inspect variables';
+ unbound -> unbound
+ end
end,
From ! {self(), {eval_rsp, Res}};
- _Forms ->
+ {_Forms, _XBs} ->
Rsp = 'Only possible to inspect variables',
From ! {self(), {eval_rsp, Rsp}}
end.
@@ -404,22 +409,22 @@ eval_nonrestricted({From, _Mod, Cmd, _SP}, Bs,
{'EXIT', _Reason} ->
From ! {self(), {eval_rsp, 'Parse error'}},
Bs;
- Forms ->
+ {Forms, XBs} ->
mark_running(Line, Le),
+ Bs1 = merge_bindings(Bs, XBs),
{Res, Bs2} =
lists:foldl(fun(Expr, {_Res, Bs0}) ->
eval_nonrestricted_1(Expr,Bs0,Ieval)
end,
- {null, Bs},
+ {null, Bs1},
Forms),
mark_break(M, Line, Le),
From ! {self(), {eval_rsp, Res}},
- Bs2
+ remove_binding_structs(Bs2, XBs)
end.
eval_nonrestricted_1({match,_,{var,_,Var},Expr}, Bs, Ieval) ->
- {value,Res,Bs2} =
- dbg_ieval:eval_expr(Expr, Bs, Ieval#ieval{top=false}),
+ {Res,Bs2} = eval_expr(Expr, Bs, Ieval),
Bs3 = case lists:keyfind(Var, 1, Bs) of
{Var,_Value} ->
lists:keyreplace(Var, 1, Bs2, {Var,Res});
@@ -433,10 +438,21 @@ eval_nonrestricted_1({var,_,Var}, Bs, _Ieval) ->
end,
{Res,Bs};
eval_nonrestricted_1(Expr, Bs, Ieval) ->
- {value,Res,Bs2} =
- dbg_ieval:eval_expr(Expr, Bs, Ieval#ieval{top=false}),
+ eval_expr(Expr, Bs, Ieval).
+
+eval_expr(Expr, Bs, Ieval) ->
+ {value,Res,Bs2} =
+ dbg_ieval:eval_expr(Expr, Bs, Ieval#ieval{top=false}),
{Res,Bs2}.
+%% XBs have unique keys.
+merge_bindings(Bs1, XBs) ->
+ Bs1 ++ erl_eval:bindings(XBs).
+
+remove_binding_structs(Bs1, XBs) ->
+ lists:foldl(fun({N, _V}, Bs) -> lists:keydelete(N, 1, Bs)
+ end, Bs1, erl_eval:bindings(XBs)).
+
mark_running(LineNo, Le) ->
put(next_break, running),
put(user_eval, [{LineNo, Le} | get(user_eval)]),
@@ -450,9 +466,9 @@ mark_break(Cm, LineNo, Le) ->
dbg_iserver:cast(get(int), {set_status,self(),break,{Cm,LineNo}}).
parse_cmd(Cmd, LineNo) ->
- {ok,Tokens,_} = erl_scan:string(Cmd, LineNo),
- {ok,Forms} = erl_parse:parse_exprs(Tokens),
- Forms.
+ {ok,Tokens,_} = erl_scan:string(Cmd, LineNo, [text]),
+ {ok,Forms,Bs} = lib:extended_parse_exprs(Tokens),
+ {Forms, Bs}.
%%====================================================================
%% Library functions for attached process handling
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index f5e079ef7e..88c7caacb0 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1486,7 +1486,6 @@ guard_expr({map,_,E0,Fs0}, Bs) ->
Value = lists:foldl(fun ({map_assoc,K,V}, Mi) -> maps:put(K,V,Mi);
({map_exact,K,V}, Mi) -> maps:update(K,V,Mi) end,
E, Fs),
- io:format("~p~n", [{E,Value}]),
{value,Value};
guard_expr({bin,_,Flds}, Bs) ->
{value,V,_Bs} =
diff --git a/lib/debugger/src/dbg_iload.erl b/lib/debugger/src/dbg_iload.erl
index 369b456524..468f6a809f 100644
--- a/lib/debugger/src/dbg_iload.erl
+++ b/lib/debugger/src/dbg_iload.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -72,8 +72,7 @@ store_module(Mod, File, Binary, Db) ->
exit({Mod,too_old_beam_file});
{raw_abstract_v1,Code0} ->
Code = interpret_file_attribute(Code0),
- {_,_,Forms0,_} = sys_pre_expand:module(Code, []),
- Forms0
+ standard_transforms(Code)
end,
dbg_idb:insert(Db, mod_file, File),
dbg_idb:insert(Db, defs, []),
@@ -94,6 +93,11 @@ store_module(Mod, File, Binary, Db) ->
dbg_idb:insert(Db, mod_bin, NewBinary),
dbg_idb:insert(Db, mod_raw, <<Src/binary,0:8>>). %% Add eos
+standard_transforms(Forms0) ->
+ Forms = erl_expand_records:module(Forms0, []),
+ erl_internal:add_predefined_functions(Forms).
+
+
%% Adjust line numbers using the file/2 attribute.
%% Also take the absolute value of line numbers.
%% This simple fix will make the marker point at the correct line
@@ -102,7 +106,6 @@ store_module(Mod, File, Binary, Db) ->
interpret_file_attribute(Code) ->
epp:interpret_file_attribute(Code).
-
abstr(Bin) when is_binary(Bin) -> binary_to_term(Bin);
abstr(Term) -> Term.
@@ -124,8 +127,9 @@ store_forms([{function,_,Name,Arity,Cs0}|Fs], Mod, Db, Exp) ->
store_forms(Fs, Mod, Db, Exp);
store_forms([{attribute,_,_Name,_Val}|Fs], Mod, Db, Exp) ->
store_forms(Fs, Mod, Db, Exp);
-store_forms([F|_], _Mod, _Db, _Exp) ->
- exit({unknown_form,F});
+store_forms([_|Fs], Mod, Db, Exp) ->
+ %% Ignore other forms such as {eof,_} or {warning,_}.
+ store_forms(Fs, Mod, Db, Exp);
store_forms([], _, _, _) ->
ok.
@@ -216,12 +220,36 @@ pattern({op,_,'-',{float,Anno,I}}) ->
pattern({op,_,'+',{float,Anno,I}}) ->
{value,ln(Anno),I};
pattern({bin,Anno,Grp}) ->
- Grp1 = pattern_list(Grp),
+ Grp1 = pattern_list(bin_expand_strings(Grp)),
{bin,ln(Anno),Grp1};
-pattern({bin_element,Anno,Expr,Size,Type}) ->
- Expr1 = pattern(Expr),
- Size1 = expr(Size, false),
- {bin_element,ln(Anno),Expr1,Size1,Type}.
+pattern({bin_element,Anno,Expr0,Size0,Type0}) ->
+ {Size1,Type} = make_bit_type(Anno, Size0, Type0),
+ Expr1 = pattern(Expr0),
+ Expr = coerce_to_float(Expr1, Type0),
+ Size = pattern(Size1),
+ {bin_element,ln(Anno),Expr,Size,Type};
+%% Evaluate compile-time expressions.
+pattern({op,_,'++',{nil,_},R}) ->
+ pattern(R);
+pattern({op,_,'++',{cons,Li,H,T},R}) ->
+ pattern({cons,Li,H,{op,Li,'++',T,R}});
+pattern({op,_,'++',{string,Li,L},R}) ->
+ pattern(string_to_conses(Li, L, R));
+pattern({op,_Line,_Op,_A}=Op) ->
+ pattern(erl_eval:partial_eval(Op));
+pattern({op,_Line,_Op,_L,_R}=Op) ->
+ pattern(erl_eval:partial_eval(Op)).
+
+string_to_conses(Anno, Cs, Tail) ->
+ lists:foldr(fun (C, T) -> {cons,Anno,{char,Anno,C},T} end, Tail, Cs).
+
+coerce_to_float({value,Anno,Int}=E, [float|_]) when is_integer(Int) ->
+ try
+ {value,Anno,float(Int)}
+ catch
+ error:badarg -> E
+ end;
+coerce_to_float(E, _) -> E.
%% These patterns are processed "in parallel" for purposes of variable
%% definition etc.
@@ -297,13 +325,14 @@ gexpr({map,Anno,E0,Fs0}) ->
Fs1 = map_fields(Fs0, fun gexpr/1),
{map,ln(Anno),E1,Fs1};
gexpr({bin,Anno,Flds0}) ->
- Flds = gexpr_list(Flds0),
+ Flds = gexpr_list(bin_expand_strings(Flds0)),
{bin,ln(Anno),Flds};
-gexpr({bin_element,Anno,Expr0,Size0,Type}) ->
+gexpr({bin_element,Anno,Expr0,Size0,Type0}) ->
+ {Size1,Type} = make_bit_type(Anno, Size0, Type0),
Expr = gexpr(Expr0),
- Size = gexpr(Size0),
+ Size = gexpr(Size1),
{bin_element,ln(Anno),Expr,Size,Type};
-%%% The previous passes have added the module name 'erlang' to
+%%% The erl_expand_records pass has added the module name 'erlang' to
%%% all BIF calls, even in guards.
gexpr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,self}},[]}) ->
{dbg,ln(Anno),self,[]};
@@ -383,18 +412,21 @@ expr({'receive',Anno,Cs0,To0,ToEs0}, Lc) ->
ToEs1 = exprs(ToEs0, Lc),
Cs1 = icr_clauses(Cs0, Lc),
{'receive',ln(Anno),Cs1,To1,ToEs1};
-expr({'fun',Anno,{clauses,Cs0},{_,_,Name}}, _Lc) when is_atom(Name) ->
+expr({'fun',Anno,{clauses,Cs0}}, _Lc) ->
%% New R10B-2 format (abstract_v2).
Cs = fun_clauses(Cs0),
+ Name = new_fun_name(),
{make_fun,ln(Anno),Name,Cs};
-expr({'fun',Anno,{function,F,A},{_Index,_OldUniq,Name}}, _Lc) ->
+expr({'fun',Anno,{function,F,A}}, _Lc) ->
%% New R8 format (abstract_v2).
Line = ln(Anno),
As = new_vars(A, Line),
+ Name = new_fun_name(),
Cs = [{clause,Line,As,[],[{local_call,Line,F,As,true}]}],
{make_fun,Line,Name,Cs};
-expr({named_fun,Anno,FName,Cs0,{_,_,Name}}, _Lc) when is_atom(Name) ->
+expr({named_fun,Anno,FName,Cs0}, _Lc) ->
Cs = fun_clauses(Cs0),
+ Name = new_fun_name(),
{make_named_fun,ln(Anno),Name,FName,Cs};
expr({'fun',Anno,{function,{atom,_,M},{atom,_,F},{integer,_,A}}}, _Lc)
when 0 =< A, A =< 255 ->
@@ -454,30 +486,10 @@ expr({'try',Anno,Es0,CaseCs0,CatchCs0,As0}, Lc) ->
CatchCs = icr_clauses(CatchCs0, Lc),
As = expr_list(As0),
{'try',ln(Anno),Es,CaseCs,CatchCs,As};
-expr({lc,Anno,E0,Gs0}, _Lc) -> %R8.
- Gs = lists:map(fun ({generate,L,P0,Qs}) ->
- {generate,L,pattern(P0),expr(Qs, false)};
- ({b_generate,L,P0,Qs}) -> %R12.
- {b_generate,L,pattern(P0),expr(Qs, false)};
- (Expr) ->
- case erl_lint:is_guard_test(Expr) of
- true -> {guard,guard([[Expr]])};
- false -> expr(Expr, false)
- end
- end, Gs0),
- {lc,ln(Anno),expr(E0, false),Gs};
-expr({bc,Anno,E0,Gs0}, _Lc) -> %R12.
- Gs = lists:map(fun ({generate,L,P0,Qs}) ->
- {generate,L,pattern(P0),expr(Qs, false)};
- ({b_generate,L,P0,Qs}) -> %R12.
- {b_generate,L,pattern(P0),expr(Qs, false)};
- (Expr) ->
- case erl_lint:is_guard_test(Expr) of
- true -> {guard,guard([[Expr]])};
- false -> expr(Expr, false)
- end
- end, Gs0),
- {bc,ln(Anno),expr(E0, false),Gs};
+expr({lc,_,_,_}=Compr, _Lc) ->
+ expr_lc_bc(Compr);
+expr({bc,_,_,_}=Compr, _Lc) ->
+ expr_lc_bc(Compr);
expr({match,Anno,P0,E0}, _Lc) ->
E1 = expr(E0, false),
P1 = pattern(P0),
@@ -506,19 +518,58 @@ expr({op,Anno,Op,L0,R0}, _Lc) ->
R1 = expr(R0, false), %They see the same variables
{op,ln(Anno),Op,[L1,R1]};
expr({bin,Anno,Grp}, _Lc) ->
- Grp1 = expr_list(Grp),
+ Grp1 = expr_list(bin_expand_strings(Grp)),
{bin,ln(Anno),Grp1};
-expr({bin_element,Anno,Expr,Size,Type}, _Lc) ->
- Expr1 = expr(Expr, false),
- Size1 = expr(Size, false),
- {bin_element,ln(Anno),Expr1,Size1,Type};
-expr(Other, _Lc) ->
- exit({?MODULE,{unknown_expr,Other}}).
+expr({bin_element,Anno,Expr0,Size0,Type0}, _Lc) ->
+ {Size1,Type} = make_bit_type(Anno, Size0, Type0),
+ Expr = expr(Expr0, false),
+ Size = expr(Size1, false),
+ {bin_element,ln(Anno),Expr,Size,Type}.
consify([A|As]) ->
{cons,0,A,consify(As)};
consify([]) -> {value,0,[]}.
+make_bit_type(Line, default, Type0) ->
+ case erl_bits:set_bit_type(default, Type0) of
+ {ok,all,Bt} -> {{atom,Line,all},erl_bits:as_list(Bt)};
+ {ok,undefined,Bt} -> {{atom,Line,undefined},erl_bits:as_list(Bt)};
+ {ok,Size,Bt} -> {{integer,Line,Size},erl_bits:as_list(Bt)}
+ end;
+make_bit_type(_Line, Size, Type0) -> %Integer or 'all'
+ {ok,Size,Bt} = erl_bits:set_bit_type(Size, Type0),
+ {Size,erl_bits:as_list(Bt)}.
+
+expr_lc_bc({Tag,Anno,E0,Gs0}) ->
+ Gs = lists:map(fun ({generate,L,P0,Qs}) ->
+ {generate,L,pattern(P0),expr(Qs, false)};
+ ({b_generate,L,P0,Qs}) -> %R12.
+ {b_generate,L,pattern(P0),expr(Qs, false)};
+ (Expr) ->
+ case is_guard_test(Expr) of
+ true -> {guard,guard([[Expr]])};
+ false -> expr(Expr, false)
+ end
+ end, Gs0),
+ {Tag,ln(Anno),expr(E0, false),Gs}.
+
+is_guard_test(Expr) ->
+ IsOverridden = fun({_,_}) -> true end,
+ erl_lint:is_guard_test(Expr, [], IsOverridden).
+
+%% The debugger converts both strings "abc" and lists [67, 68, 69]
+%% into {value, Line, [67, 68, 69]}, making it impossible to later
+%% distingish one or the other inside binaries when evaluating. To
+%% avoid <<[67, 68, 69]>> from evaluating, we convert strings into
+%% chars to avoid the ambiguity.
+bin_expand_strings(Es) ->
+ lists:foldr(fun ({bin_element,Line,{string,_,S},Sz,Ts}, Es1) ->
+ lists:foldr(fun (C, Es2) ->
+ [{bin_element,Line,{char,Line,C},Sz,Ts}|Es2]
+ end, Es1, S);
+ (E, Es1) -> [E|Es1]
+ end, [], Es).
+
%% -type expr_list([Expression]) -> [Expression].
%% These expressions are processed "in parallel" for purposes of variable
%% definition etc.
@@ -581,6 +632,14 @@ new_vars(N, L, Vs) when N > 0 ->
new_vars(N-1, L, [V|Vs]);
new_vars(0, _, Vs) -> Vs.
+new_fun_name() ->
+ {F,A} = get(current_function),
+ I = get(fun_count),
+ put(fun_count, I+1),
+ Name = "-" ++ atom_to_list(F) ++ "/" ++ integer_to_list(A) ++
+ "-fun-" ++ integer_to_list(I) ++ "-",
+ list_to_atom(Name).
+
ln(Anno) ->
erl_anno:line(Anno).
diff --git a/lib/debugger/src/dbg_iserver.erl b/lib/debugger/src/dbg_iserver.erl
index 3561454685..3e959e8e30 100644
--- a/lib/debugger/src/dbg_iserver.erl
+++ b/lib/debugger/src/dbg_iserver.erl
@@ -214,7 +214,6 @@ handle_call({new_process, Pid, Meta, Function}, _From, State) ->
%% Code loading
handle_call({load, Mod, Src, Bin}, _From, State) ->
-
%% Create an ETS table for storing information about the module
Db = State#state.db,
ModDb = ets:new(Mod, [ordered_set, public]),
@@ -285,23 +284,28 @@ handle_call({contents, Mod, Pid}, _From, State) ->
{reply, {ok, Bin}, State};
handle_call({raw_contents, Mod, Pid}, _From, State) ->
Db = State#state.db,
- [{{Mod, refs}, ModDbs}] = ets:lookup(Db, {Mod, refs}),
- ModDb = if
- Pid =:= any -> hd(ModDbs);
- true ->
- lists:foldl(fun(T, not_found) ->
- [{T, Pids}] = ets:lookup(Db, T),
- case lists:member(Pid, Pids) of
- true -> T;
- false -> not_found
- end;
- (_T, T) -> T
- end,
- not_found,
- ModDbs)
- end,
- [{mod_raw, Bin}] = ets:lookup(ModDb, mod_raw),
- {reply, {ok, Bin}, State};
+ case ets:lookup(Db, {Mod, refs}) of
+ [{{Mod, refs}, ModDbs}] ->
+ ModDb =
+ if
+ Pid =:= any -> hd(ModDbs);
+ true ->
+ lists:foldl(fun(T, not_found) ->
+ [{T, Pids}] = ets:lookup(Db, T),
+ case lists:member(Pid, Pids) of
+ true -> T;
+ false -> not_found
+ end;
+ (_T, T) -> T
+ end,
+ not_found,
+ ModDbs)
+ end,
+ [{mod_raw, Bin}] = ets:lookup(ModDb, mod_raw),
+ {reply, {ok, Bin}, State};
+ [] -> % code not interpreted
+ {reply, not_found, State}
+ end;
handle_call({is_interpreted, Mod, Name, Arity}, _From, State) ->
Db = State#state.db,
Reply = case ets:lookup(Db, {Mod, refs}) of
diff --git a/lib/debugger/src/dbg_wx_code.erl b/lib/debugger/src/dbg_wx_code.erl
index 473963500a..bca8a0d241 100644
--- a/lib/debugger/src/dbg_wx_code.erl
+++ b/lib/debugger/src/dbg_wx_code.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -190,6 +190,6 @@ find(Ed, Str, Case, Next) ->
keyWords() ->
L = ["after","begin","case","try","cond","catch","andalso","orelse",
- "end","fun","if","let","of","query","receive","when","bnot","not",
+ "end","fun","if","let","of","receive","when","bnot","not",
"div","rem","band","and","bor","bxor","bsl","bsr","or","xor"],
lists:flatten([K ++ " " || K <- L] ++ [0]).
diff --git a/lib/debugger/src/dbg_wx_src_view.erl b/lib/debugger/src/dbg_wx_src_view.erl
index 207c407fbc..ee8eb72407 100644
--- a/lib/debugger/src/dbg_wx_src_view.erl
+++ b/lib/debugger/src/dbg_wx_src_view.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -62,6 +62,6 @@ code_area(Parent, Sizer) ->
keyWords() ->
L = ["after","begin","case","try","cond","catch","andalso","orelse",
- "end","fun","if","let","of","query","receive","when","bnot","not",
+ "end","fun","if","let","of","receive","when","bnot","not",
"div","rem","band","and","bor","bxor","bsl","bsr","or","xor"],
lists:flatten([K ++ " " || K <- L] ++ [0]).
diff --git a/lib/debugger/src/dbg_wx_trace.erl b/lib/debugger/src/dbg_wx_trace.erl
index 6af19af33b..f4ee30618c 100644
--- a/lib/debugger/src/dbg_wx_trace.erl
+++ b/lib/debugger/src/dbg_wx_trace.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -524,7 +524,8 @@ gui_cmd({edit, {Var, Value}}, State) ->
cancel ->
State;
{Var, Term} ->
- Cmd = atom_to_list(Var)++"="++io_lib:format("~w", [Term]),
+ %% The space after "=" is needed for handling "B= <<1>>".
+ Cmd = atom_to_list(Var)++"= "++io_lib:format("~w", [Term]),
gui_cmd({user_command, lists:flatten(Cmd)}, State)
end.
@@ -818,11 +819,14 @@ gui_show_module(Win, Mod, Line, _Cm, Pid, How) ->
gui_load_module(Win, Mod, _Pid) ->
dbg_wx_trace_win:display(Win,{text, "Loading module..."}),
- %% Contents = int:contents(Mod, Pid),
- {ok, Contents} = dbg_iserver:call({raw_contents, Mod, any}),
- Win2 = dbg_wx_trace_win:show_code(Win, Mod, Contents),
- dbg_wx_trace_win:display(Win,{text, ""}),
- Win2.
+ case dbg_iserver:call({raw_contents, Mod, any}) of
+ {ok, Contents} ->
+ Win2 = dbg_wx_trace_win:show_code(Win, Mod, Contents),
+ dbg_wx_trace_win:display(Win,{text, ""}),
+ Win2;
+ not_found ->
+ dbg_wx_trace_win:show_no_code(Win)
+ end.
gui_update_bindings(Win,Meta) ->
Bs = int:meta(Meta, bindings, nostack),
diff --git a/lib/debugger/src/dbg_wx_view.erl b/lib/debugger/src/dbg_wx_view.erl
index 91fc0d08cb..86d009238f 100644
--- a/lib/debugger/src/dbg_wx_view.erl
+++ b/lib/debugger/src/dbg_wx_view.erl
@@ -263,7 +263,11 @@ shortcut(_) -> false.
gui_load_module(Win, Mod) ->
dbg_wx_trace_win:display(Win,{text, "Loading module..."}),
- {ok, Contents} = dbg_iserver:call({raw_contents, Mod, any}),
- Win2 = dbg_wx_trace_win:show_code(Win, Mod, Contents),
- dbg_wx_trace_win:display(Win,{text, ""}),
- Win2.
+ case dbg_iserver:call({raw_contents, Mod, any}) of
+ {ok, Contents} ->
+ Win2 = dbg_wx_trace_win:show_code(Win, Mod, Contents),
+ dbg_wx_trace_win:display(Win,{text, ""}),
+ Win2;
+ not_found ->
+ dbg_wx_trace_win:show_no_code(Win)
+ end.
diff --git a/lib/debugger/src/dbg_wx_win.erl b/lib/debugger/src/dbg_wx_win.erl
index 25ffc5054c..f1298154ab 100644
--- a/lib/debugger/src/dbg_wx_win.erl
+++ b/lib/debugger/src/dbg_wx_win.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -273,10 +273,9 @@ entry(Parent, Title, Prompt, {Type, Value}) ->
verify(Type, Str) ->
- case erl_scan:string(Str) of
+ case erl_scan:string(Str, 1, [text]) of
{ok, Tokens, _EndLine} when Type==term ->
-
- case erl_parse:parse_term(Tokens++[{dot, 1}]) of
+ case lib:extended_parse_term(Tokens++[{dot, erl_anno:new(1)}]) of
{ok, Value} -> {edit, Value};
_Error ->
ignore
diff --git a/lib/debugger/src/int.erl b/lib/debugger/src/int.erl
index e5bade9abe..fdf5957182 100644
--- a/lib/debugger/src/int.erl
+++ b/lib/debugger/src/int.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -533,7 +533,9 @@ load({Mod, Src, Beam, BeamBin, Exp, Abst}, Dist) ->
case erl_prim_loader:get_file(filename:absname(Src)) of
{ok, SrcBin, _} ->
MD5 = code:module_md5(BeamBin),
- Bin = term_to_binary({interpreter_module,Exp,Abst,SrcBin,MD5}),
+ SrcBin1 = unicode:characters_to_binary(SrcBin, enc(SrcBin)),
+ true = is_binary(SrcBin1),
+ Bin = term_to_binary({interpreter_module,Exp,Abst,SrcBin1,MD5}),
{module, Mod} = dbg_iserver:safe_call({load, Mod, Src, Bin}),
_ = everywhere(Dist,
fun() ->
diff --git a/lib/debugger/test/Makefile b/lib/debugger/test/Makefile
index 125abcacda..efb6d9ed8b 100644
--- a/lib/debugger/test/Makefile
+++ b/lib/debugger/test/Makefile
@@ -46,6 +46,7 @@ MODULES= \
lc_SUITE \
line_number_SUITE \
map_SUITE \
+ overridden_bif_SUITE \
record_SUITE \
trycatch_SUITE \
test_lib \
diff --git a/lib/debugger/test/andor_SUITE.erl b/lib/debugger/test/andor_SUITE.erl
index d7bbd4fccb..f6e39514af 100644
--- a/lib/debugger/test/andor_SUITE.erl
+++ b/lib/debugger/test/andor_SUITE.erl
@@ -29,6 +29,8 @@
-include_lib("common_test/include/ct.hrl").
+-warning("Ignore me -- testing that the debugger can handle warnings").
+
suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap,{minutes,1}}].
diff --git a/lib/debugger/test/bs_bincomp_SUITE.erl b/lib/debugger/test/bs_bincomp_SUITE.erl
index 39e2240f2d..064e9567b3 100644
--- a/lib/debugger/test/bs_bincomp_SUITE.erl
+++ b/lib/debugger/test/bs_bincomp_SUITE.erl
@@ -66,6 +66,7 @@ end_per_group(_GroupName, Config) ->
byte_aligned(Config) when is_list(Config) ->
<<"abcdefg">> = << <<(X+32)>> || <<X>> <= <<"ABCDEFG">> >>,
+ <<"AxyzBxyzCxyz">> = << <<X, "xyz">> || <<X>> <= <<"ABC">> >>,
<<1:32/little,2:32/little,3:32/little,4:32/little>> =
<< <<X:32/little>> || <<X:32>> <= <<1:32,2:32,3:32,4:32>> >>,
<<1:32/little,2:32/little,3:32/little,4:32/little>> =
diff --git a/lib/debugger/test/int_SUITE.erl b/lib/debugger/test/int_SUITE.erl
index f697ace4e5..cb1fcb83f3 100644
--- a/lib/debugger/test/int_SUITE.erl
+++ b/lib/debugger/test/int_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -241,7 +241,8 @@ interpretable(Config) when is_list(Config) ->
true = code:del_path(PrivDir),
%% {error, no_src}
- {ok, lists2, Binary} = compile:forms([{attribute,1,module,lists2}], []),
+ A1 = erl_anno:new(1),
+ {ok, lists2, Binary} = compile:forms([{attribute,A1,module,lists2}], []),
code:load_binary(lists2, "unknown", Binary),
{error, no_src} = int:interpretable(lists2),
diff --git a/lib/debugger/test/map_SUITE.erl b/lib/debugger/test/map_SUITE.erl
index 42484ff723..4d8a86f5a2 100644
--- a/lib/debugger/test/map_SUITE.erl
+++ b/lib/debugger/test/map_SUITE.erl
@@ -1714,10 +1714,8 @@ t_bif_map_values(Config) when is_list(Config) ->
t_erlang_hash(Config) when is_list(Config) ->
-
ok = t_bif_erlang_phash2(),
ok = t_bif_erlang_phash(),
- ok = t_bif_erlang_hash(),
ok.
t_bif_erlang_phash2() ->
@@ -1759,26 +1757,6 @@ t_bif_erlang_phash() ->
2620391445 = erlang:phash(M2,Sz), % 3590546636
ok.
-t_bif_erlang_hash() ->
- Sz = 1 bsl 27 - 1,
- 39684169 = erlang:hash(#{},Sz), % 5158
- 33673142 = erlang:hash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz), % 71555838
- 95337869 = erlang:hash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz), % 5497225
- 108959561 = erlang:hash(#{ 1 => a },Sz), % 126071654
- 59623150 = erlang:hash(#{ a => 1 },Sz), % 126426236
-
- 42775386 = erlang:hash(#{{} => <<>>},Sz), % 101655720
- 71692856 = erlang:hash(#{<<>> => {}},Sz), % 101655720
-
- M0 = #{ a => 1, "key" => <<"value">> },
- M1 = maps:remove("key",M0),
- M2 = M1#{ "key" => <<"value">> },
-
- 70254632 = erlang:hash(M0,Sz), % 38260486
- 59623150 = erlang:hash(M1,Sz), % 126426236
- 70254632 = erlang:hash(M2,Sz), % 38260486
- ok.
-
t_map_encode_decode(Config) when is_list(Config) ->
<<131,116,0,0,0,0>> = erlang:term_to_binary(#{}),
Pairs = [
diff --git a/lib/debugger/test/overridden_bif_SUITE.erl b/lib/debugger/test/overridden_bif_SUITE.erl
new file mode 100644
index 0000000000..04bef3c0a2
--- /dev/null
+++ b/lib/debugger/test/overridden_bif_SUITE.erl
@@ -0,0 +1,99 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(overridden_bif_SUITE).
+-compile({no_auto_import,[is_reference/1,size/1]}).
+
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ overridden_bif/1]).
+
+-include_lib("common_test/include/ct.hrl").
+
+%% Used by overridden_bif/1.
+-import(gb_sets, [size/1]).
+-import(test_lib, [binary/1]).
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,1}}].
+
+all() ->
+ [overridden_bif].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ test_lib:interpret(?MODULE),
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
+ Config.
+
+end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
+ ok.
+
+overridden_bif(_Config) ->
+ L = [-3,-2,-1,0,1,2,3,4],
+ [-3,0,3] = do_overridden_bif_1(L),
+ [-2,0,2,4] = do_overridden_bif_2(L),
+ [3] = do_overridden_bif_3(L),
+ [2,4] = do_overridden_bif_4(L),
+
+ Set = gb_sets:from_list(L),
+ [Set] = do_overridden_bif_5([gb_sets:singleton(42),Set]),
+
+ [100,0] = do_overridden_bif_6([100|L]),
+ ok.
+
+do_overridden_bif_1(L) ->
+ [E || E <- L, is_reference(E)].
+
+do_overridden_bif_2(L) ->
+ [E || E <- L, port(E)].
+
+do_overridden_bif_3(L) ->
+ [E || E <- L, (is_reference(E) andalso E > 0)].
+
+do_overridden_bif_4(L) ->
+ [E || E <- L, (port(E) andalso E > 0)].
+
+do_overridden_bif_5(L) ->
+ [E || E <- L, size(E) > 1].
+
+do_overridden_bif_6(L) ->
+ [E || E <- L, binary(E)].
+
+is_reference(N) ->
+ N rem 3 =:= 0.
+
+port(N) ->
+ N rem 2 =:= 0.
diff --git a/lib/debugger/test/test_lib.erl b/lib/debugger/test/test_lib.erl
index b9ac486694..7e98d210e8 100644
--- a/lib/debugger/test/test_lib.erl
+++ b/lib/debugger/test/test_lib.erl
@@ -23,8 +23,15 @@
-export([interpret/1]).
+%% Used by test case that override BIFs.
+-export([binary/1]).
+
interpret(Mod) when is_atom(Mod) ->
case lists:member(Mod, int:interpreted()) of
true -> ok;
false -> {module,Mod} = i:ii(Mod)
end.
+
+%% This is for overridden_bif_SUITE.
+binary(N) ->
+ N rem 10 =:= 0.
diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk
index dd496013cd..3534570ef5 100644
--- a/lib/debugger/vsn.mk
+++ b/lib/debugger/vsn.mk
@@ -1 +1 @@
-DEBUGGER_VSN = 4.2
+DEBUGGER_VSN = 4.2.2
diff --git a/lib/dialyzer/RELEASE_NOTES b/lib/dialyzer/RELEASE_NOTES
index 4e311bb543..299cc8642f 100644
--- a/lib/dialyzer/RELEASE_NOTES
+++ b/lib/dialyzer/RELEASE_NOTES
@@ -135,7 +135,7 @@ Version 1.9.1 (in Erlang/OTP R13B)
Version 1.9.0 (in Erlang/OTP R13A)
----------------------------------
- The analysis accepts opaque type declarations and detects violations of
- opaqueness of terms of such types. Starting with R13, many Erlang/OTP
+ opacity of terms of such types. Starting with R13, many Erlang/OTP
standard libraries (array, dict, digraph, ets, gb_sets, gb_trees, queue,
and sets) contain opaque type declarations of their main data types.
Dialyzer will spit out warnings in code that explicitly depends on the
@@ -181,7 +181,7 @@ Version 1.8.0 (in Erlang/OTP R12B-2)
- Dialyzer has a new warning option -Wunmatched_returns which warns for
function calls that ignore the return value.
This catches many common programming errors (e.g. calling file:close/1
- and not checking for the absense of errors), interface discrepancies
+ and not checking for the absence of errors), interface discrepancies
(e.g. a function returning multiple values when in reality the function
is void and only called for its side-effects), calling the wrong function
(e.g. io_lib:format/1 instead of io:format/1), and even possible
diff --git a/lib/dialyzer/doc/manual.txt b/lib/dialyzer/doc/manual.txt
index be1fd2f8bc..a571cd2e2b 100644
--- a/lib/dialyzer/doc/manual.txt
+++ b/lib/dialyzer/doc/manual.txt
@@ -255,7 +255,7 @@ Warning options:
-Wno_match
Suppress warnings for patterns that are unused or cannot match.
-Wno_opaque
- Suppress warnings for violations of opaqueness of data types.
+ Suppress warnings for violations of opacity of data types.
-Wunmatched_returns ***
Include warnings for function calls which ignore a structured return
value or do not match against one of many possible return value(s).
diff --git a/lib/dialyzer/doc/src/Makefile b/lib/dialyzer/doc/src/Makefile
index 77d0a6fc68..8fe6cd30eb 100644
--- a/lib/dialyzer/doc/src/Makefile
+++ b/lib/dialyzer/doc/src/Makefile
@@ -34,7 +34,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# Target Specs
# ----------------------------------------------------
XML_APPLICATION_FILES = ref_man.xml
-XML_REF3_FILES = dialyzer.xml
+XML_REF3_FILES = dialyzer.xml typer.xml
XML_PART_FILES = part.xml part_notes.xml
XML_CHAPTER_FILES = dialyzer_chapter.xml notes.xml
diff --git a/lib/dialyzer/doc/src/book.xml b/lib/dialyzer/doc/src/book.xml
index aecc0e5bfa..46df8b81b8 100644
--- a/lib/dialyzer/doc/src/book.xml
+++ b/lib/dialyzer/doc/src/book.xml
@@ -25,7 +25,7 @@
<title>Dialyzer</title>
<prepared></prepared>
<docno></docno>
- <date></date>
+ <date>2016-09-19</date>
<rev></rev>
<file>book.xml</file>
</header>
diff --git a/lib/dialyzer/doc/src/dialyzer.xml b/lib/dialyzer/doc/src/dialyzer.xml
index 619db125b1..e34ffd6def 100644
--- a/lib/dialyzer/doc/src/dialyzer.xml
+++ b/lib/dialyzer/doc/src/dialyzer.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2006</year><year>2015</year>
+ <year>2006</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -25,341 +25,472 @@
<title>dialyzer</title>
<prepared></prepared>
<docno></docno>
- <date></date>
+ <date>2016-09-20</date>
<rev></rev>
+ <file>dialyzer.xml</file>
</header>
<module>dialyzer</module>
- <modulesummary>The Dialyzer, a DIscrepancy AnalYZer for ERlang programs</modulesummary>
+ <modulesummary>Dialyzer, a DIscrepancy AnaLYZer for ERlang programs.
+ </modulesummary>
<description>
- <p>The Dialyzer is a static analysis tool that identifies software
- discrepancies such as definite type errors, code which has become
- dead or unreachable due to some programming error, unnecessary
- tests, etc. in single Erlang modules or entire (sets of)
- applications. Dialyzer starts its analysis from either
- debug-compiled BEAM bytecode or from Erlang source code. The file
- and line number of a discrepancy is reported along with an
- indication of what the discrepancy is about. Dialyzer bases its
- analysis on the concept of success typings which allows for sound
- warnings (no false positives).</p>
- <p>Read more about Dialyzer and about how to use it from the GUI
- in <seealso marker="dialyzer_chapter">Dialyzer User's
- Guide</seealso>.</p>
+ <p>Dialyzer is a static analysis tool that identifies software
+ discrepancies, such as definite type errors, code that has become dead
+ or unreachable because of programming error, and unnecessary tests,
+ in single Erlang modules or entire (sets of) applications.</p>
+
+ <p>Dialyzer starts its analysis from either
+ debug-compiled BEAM bytecode or from Erlang source code. The file
+ and line number of a discrepancy is reported along with an
+ indication of what the discrepancy is about. Dialyzer bases its
+ analysis on the concept of success typings, which allows for sound
+ warnings (no false positives).</p>
</description>
<section>
- <title>Using the Dialyzer from the command line</title>
- <p>Dialyzer also has a command line version for automated use. Below is a
- brief description of the list of its options. The same information can
- be obtained by writing</p>
- <code type="none">
- dialyzer --help</code>
- <p>in a shell. Please refer to the GUI description for more details on
- the operation of Dialyzer.</p>
- <p>The exit status of the command line version is:</p>
+ <marker id="command_line"></marker>
+ <title>Using Dialyzer from the Command Line</title>
+ <p>Dialyzer has a command-line version for automated use. This
+ section provides a brief description of the options. The same information
+ can be obtained by writing the following in a shell:</p>
+
<code type="none">
- 0 - No problems were encountered during the analysis and no
- warnings were emitted.
- 1 - Problems were encountered during the analysis.
- 2 - No problems were encountered, but warnings were emitted.</code>
- <p>Usage:</p>
+dialyzer --help</code>
+
+ <p>For more details about the operation of Dialyzer, see section
+ <seealso marker="dialyzer_chapter#dialyzer_gui">
+ Using Dialyzer from the GUI</seealso> in the User's Guide.</p>
+
+ <p><em>Exit status of the command-line version:</em></p>
+
+ <taglist>
+ <tag><c>0</c></tag>
+ <item>
+ <p>No problems were found during the analysis and no warnings were
+ emitted.</p>
+ </item>
+ <tag><c>1</c></tag>
+ <item>
+ <p>Problems were found during the analysis.</p>
+ </item>
+ <tag><c>2</c></tag>
+ <item>
+ <p>No problems were found during the analysis, but warnings were
+ emitted.</p>
+ </item>
+ </taglist>
+
+ <p><em>Usage:</em></p>
+
<code type="none">
- dialyzer [--help] [--version] [--shell] [--quiet] [--verbose]
- [-pa dir]* [--plt plt] [--plts plt*] [-Ddefine]*
- [-I include_dir]* [--output_plt file] [-Wwarn]* [--raw]
- [--src] [--gui] [files_or_dirs] [-r dirs]
- [--apps applications] [-o outfile]
- [--build_plt] [--add_to_plt] [--remove_from_plt]
- [--check_plt] [--no_check_plt] [--plt_info] [--get_warnings]
- [--dump_callgraph file] [--no_native] [--fullpath]
- [--statistics] [--no_native_cache]</code>
- <p>Options:</p>
+dialyzer [--add_to_plt] [--apps applications] [--build_plt]
+ [--check_plt] [-Ddefine]* [-Dname] [--dump_callgraph file]
+ [files_or_dirs] [--fullpath] [--get_warnings] [--gui] [--help]
+ [-I include_dir]* [--no_check_plt] [--no_native]
+ [--no_native_cache] [-o outfile] [--output_plt file] [-pa dir]*
+ [--plt plt] [--plt_info] [--plts plt*] [--quiet] [-r dirs]
+ [--raw] [--remove_from_plt] [--shell] [--src] [--statistics]
+ [--verbose] [--version] [-Wwarn]*</code>
+
+ <note>
+ <p>* denotes that multiple occurrences of the option are possible.</p>
+ </note>
+
+ <p><em>Options:</em></p>
+
<taglist>
- <tag><c><![CDATA[files_or_dirs]]></c> (for backwards compatibility also
- as: <c><![CDATA[-c files_or_dirs]]></c>)</tag>
- <item>Use Dialyzer from the command line to detect defects in the
- specified files or directories containing <c><![CDATA[.erl]]></c> or
- <c><![CDATA[.beam]]></c> files, depending on the type of the
- analysis.</item>
- <tag><c><![CDATA[-r dirs]]></c></tag>
- <item>Same as the previous but the specified directories are searched
- recursively for subdirectories containing <c><![CDATA[.erl]]></c> or
- <c><![CDATA[.beam]]></c> files in them, depending on the type of
- analysis.</item>
- <tag><c><![CDATA[--apps applications]]></c></tag>
- <item>Option typically used when building or modifying a plt as in:
+ <tag><c>--add_to_plt</c></tag>
+ <item>
+ <p>The PLT is extended to also include the files specified with
+ <c>-c</c> and <c>-r</c>. Use
+ <c>--plt</c> to specify which PLT to start from,
+ and <c>--output_plt</c> to specify where to put the PLT.
+ Notice that the analysis possibly can include files from the PLT if
+ they depend on the new files. This option only works for BEAM
+ files.</p>
+ </item>
+ <tag><c>--apps applications</c></tag>
+ <item>
+ <p>This option is typically used when building or modifying a PLT as
+ in:</p>
<code type="none">
- dialyzer --build_plt --apps erts kernel stdlib mnesia ...</code>
- to conveniently refer to library applications corresponding to the
- Erlang/OTP installation. However, the option is general and can also
- be used during analysis in order to refer to Erlang/OTP applications.
- In addition, file or directory names can also be included, as in:
+dialyzer --build_plt --apps erts kernel stdlib mnesia ...</code>
+ <p>to refer conveniently to library applications corresponding to the
+ Erlang/OTP installation. However, this option is general and can also
+ be used during analysis to refer to Erlang/OTP applications.
+ File or directory names can also be included, as in:</p>
<code type="none">
- dialyzer --apps inets ssl ./ebin ../other_lib/ebin/my_module.beam</code></item>
- <tag><c><![CDATA[-o outfile]]></c> (or
- <c><![CDATA[--output outfile]]></c>)</tag>
- <item>When using Dialyzer from the command line, send the analysis
- results to the specified outfile rather than to stdout.</item>
- <tag><c><![CDATA[--raw]]></c></tag>
- <item>When using Dialyzer from the command line, output the raw analysis
- results (Erlang terms) instead of the formatted result. The raw format
- is easier to post-process (for instance, to filter warnings or to
- output HTML pages).</item>
- <tag><c><![CDATA[--src]]></c></tag>
- <item>Override the default, which is to analyze BEAM files, and
- analyze starting from Erlang source code instead.</item>
- <tag><c><![CDATA[-Dname]]></c> (or <c><![CDATA[-Dname=value]]></c>)</tag>
- <item>When analyzing from source, pass the define to Dialyzer. (**)</item>
- <tag><c><![CDATA[-I include_dir]]></c></tag>
- <item>When analyzing from source, pass the <c><![CDATA[include_dir]]></c>
- to Dialyzer. (**)</item>
- <tag><c><![CDATA[-pa dir]]></c></tag>
- <item>Include <c><![CDATA[dir]]></c> in the path for Erlang (useful when
- analyzing files that have <c><![CDATA['-include_lib()']]></c>
- directives).</item>
- <tag><c><![CDATA[--output_plt file]]></c></tag>
- <item>Store the plt at the specified file after building it.</item>
- <tag><c><![CDATA[--plt plt]]></c></tag>
- <item>Use the specified plt as the initial plt (if the plt was built
- during setup the files will be checked for consistency).</item>
- <tag><c><![CDATA[--plts plt*]]></c></tag>
- <item>Merge the specified plts to create the initial plt -- requires
- that the plts are disjoint (i.e., do not have any module
- appearing in more than one plt).
- The plts are created in the usual way:
+dialyzer --apps inets ssl ./ebin ../other_lib/ebin/my_module.beam</code>
+ </item>
+ <tag><c>--build_plt</c></tag>
+ <item>
+ <p>The analysis starts from an empty PLT and creates a new one from
+ the files specified with <c>-c</c> and
+ <c>-r</c>. This option only works for BEAM files.
+ To override the default PLT location, use
+ <c>--plt</c> or <c>--output_plt</c>.</p>
+ </item>
+ <tag><c>--check_plt</c></tag>
+ <item>
+ <p>Check the PLT for consistency and rebuild it if it is not
+ up-to-date.</p>
+ </item>
+ <tag><c>-Dname</c> (or <c>-Dname=value</c>)</tag>
+ <item>
+ <p>When analyzing from source, pass the define to Dialyzer.
+ (**)</p>
+ </item>
+ <tag><c>--dump_callgraph file</c></tag>
+ <item>
+ <p>Dump the call graph into the specified file whose format is
+ determined by the filename extension. Supported extensions are:
+ <c>raw</c>, <c>dot</c>, and <c>ps</c>. If something else is used as
+ filename extension, default format <c>.raw</c> is used.</p>
+ </item>
+ <tag><c>files_or_dirs</c> (for backward compatibility also
+ as <c>-c files_or_dirs</c>)</tag>
+ <item>
+ <p>Use Dialyzer from the command line to detect defects in the
+ specified files or directories containing <c>.erl</c> or
+ <c>.beam</c> files, depending on the type of the
+ analysis.</p>
+ </item>
+ <tag><c>--fullpath</c></tag>
+ <item>
+ <p>Display the full path names of files for which warnings are
+ emitted.</p>
+ </item>
+ <tag><c>--get_warnings</c></tag>
+ <item>
+ <p>Make Dialyzer emit warnings even when manipulating the PLT.
+ Warnings are only emitted for files that are analyzed.</p>
+ </item>
+ <tag><c>--gui</c></tag>
+ <item>
+ <p>Use the GUI.</p></item>
+ <tag><c>--help</c> (or <c>-h</c>)</tag>
+ <item>
+ <p>Print this message and exit.</p>
+ </item>
+ <tag><c>-I include_dir</c></tag>
+ <item>
+ <p>When analyzing from source, pass the <c>include_dir</c>
+ to Dialyzer. (**)</p>
+ </item>
+ <tag><c>--no_check_plt</c></tag>
+ <item>
+ <p>Skip the PLT check when running Dialyzer. This is useful when
+ working with installed PLTs that never change.</p>
+ </item>
+ <tag><c>--no_native</c> (or <c>-nn</c>)</tag>
+ <item>
+ <p>Bypass the native code compilation of some key files that
+ Dialyzer heuristically performs when dialyzing many files.
+ This avoids the compilation time, but can result in (much) longer
+ analysis time.</p>
+ </item>
+ <tag><c>--no_native_cache</c></tag>
+ <item>
+ <p>By default, Dialyzer caches the results of native compilation
+ in directory <c>$XDG_CACHE_HOME/erlang/dialyzer_hipe_cache</c>.
+ <c>XDG_CACHE_HOME</c> defaults to <c>$HOME/.cache</c>.
+ Use this option to disable caching.</p>
+ </item>
+ <tag><c>-o outfile</c> (or
+ <c>--output outfile</c>)</tag>
+ <item>
+ <p>When using Dialyzer from the command line, send the analysis
+ results to the specified outfile rather than to <c>stdout</c>.</p>
+ </item>
+ <tag><c>--output_plt file</c></tag>
+ <item>
+ <p>Store the PLT at the specified file after building it.</p>
+ </item>
+ <tag><c>-pa dir</c></tag>
+ <item>
+ <p>Include <c>dir</c> in the path for Erlang. This is useful
+ when analyzing files that have <c>-include_lib()</c>
+ directives.</p>
+ </item>
+ <tag><c>--plt plt</c></tag>
+ <item>
+ <p>Use the specified PLT as the initial PLT. If the PLT was built
+ during setup, the files are checked for consistency.</p>
+ </item>
+ <tag><c>--plt_info</c></tag>
+ <item>
+ <p>Make Dialyzer print information about the PLT and then quit.
+ The PLT can be specified with <c>--plt(s)</c>.</p>
+ </item>
+ <tag><c>--plts plt*</c></tag>
+ <item>
+ <p>Merge the specified PLTs to create the initial PLT. This requires
+ that the PLTs are disjoint (that is, do not have any module
+ appearing in more than one PLT).
+ The PLTs are created in the usual way:</p>
<code type="none">
- dialyzer --build_plt --output_plt plt_1 files_to_include
- ...
- dialyzer --build_plt --output_plt plt_n files_to_include</code>
- and then can be used in either of the following ways:
+dialyzer --build_plt --output_plt plt_1 files_to_include
+...
+dialyzer --build_plt --output_plt plt_n files_to_include</code>
+ <p>They can then be used in either of the following ways:</p>
<code type="none">
- dialyzer files_to_analyze --plts plt_1 ... plt_n</code>
- or:
+dialyzer files_to_analyze --plts plt_1 ... plt_n</code>
+ <p>or</p>
<code type="none">
- dialyzer --plts plt_1 ... plt_n -- files_to_analyze</code>
- (Note the -- delimiter in the second case)</item>
- <tag><c><![CDATA[-Wwarn]]></c></tag>
- <item>A family of options which selectively turn on/off warnings
- (for help on the names of warnings use
- <c><![CDATA[dialyzer -Whelp]]></c>).
- Note that the options can also be given in the file with a
- <c>-dialyzer()</c> attribute. See <seealso
- marker="#suppression">Requesting or Suppressing Warnings in
- Source Files</seealso> below for details.</item>
- <tag><c><![CDATA[--shell]]></c></tag>
- <item>Do not disable the Erlang shell while running the GUI.</item>
- <tag><c><![CDATA[--version]]></c> (or <c><![CDATA[-v]]></c>)</tag>
- <item>Print the Dialyzer version and some more information and
- exit.</item>
- <tag><c><![CDATA[--help]]></c> (or <c><![CDATA[-h]]></c>)</tag>
- <item>Print this message and exit.</item>
- <tag><c><![CDATA[--quiet]]></c> (or <c><![CDATA[-q]]></c>)</tag>
- <item>Make Dialyzer a bit more quiet.</item>
- <tag><c><![CDATA[--verbose]]></c></tag>
- <item>Make Dialyzer a bit more verbose.</item>
- <tag><c><![CDATA[--statistics]]></c></tag>
- <item>Prints information about the progress of execution (analysis phases,
- time spent in each and size of the relative input).</item>
- <tag><c><![CDATA[--build_plt]]></c></tag>
- <item>The analysis starts from an empty plt and creates a new one from
- the files specified with <c><![CDATA[-c]]></c> and
- <c><![CDATA[-r]]></c>. Only works for beam files. Use
- <c><![CDATA[--plt]]></c> or <c><![CDATA[--output_plt]]></c> to
- override the default plt location.</item>
- <tag><c><![CDATA[--add_to_plt]]></c></tag>
- <item>The plt is extended to also include the files specified with
- <c><![CDATA[-c]]></c> and <c><![CDATA[-r]]></c>. Use
- <c><![CDATA[--plt]]></c> to specify which plt to start from,
- and <c><![CDATA[--output_plt]]></c> to specify where to put the plt.
- Note that the analysis might include files from the plt if they depend
- on the new files. This option only works with beam files.</item>
- <tag><c><![CDATA[--remove_from_plt]]></c></tag>
- <item>The information from the files specified with
- <c><![CDATA[-c]]></c> and <c><![CDATA[-r]]></c> is removed
- from the plt. Note that this may cause a re-analysis of the remaining
- dependent files.</item>
- <tag><c><![CDATA[--check_plt]]></c></tag>
- <item>Check the plt for consistency and rebuild it if it is not
- up-to-date.</item>
- <tag><c><![CDATA[--no_check_plt]]></c></tag>
- <item>Skip the plt check when running Dialyzer. Useful when working with
- installed plts that never change.</item>
- <tag><c><![CDATA[--plt_info]]></c></tag>
- <item>Make Dialyzer print information about the plt and then quit. The
- plt can be specified with <c><![CDATA[--plt(s)]]></c>.</item>
- <tag><c><![CDATA[--get_warnings]]></c></tag>
- <item>Make Dialyzer emit warnings even when manipulating the plt.
- Warnings are only emitted for files that are actually analyzed.</item>
- <tag><c><![CDATA[--dump_callgraph file]]></c></tag>
- <item>Dump the call graph into the specified file whose format is
- determined by the file name extension. Supported extensions are: raw,
- dot, and ps. If something else is used as file name extension, default
- format '.raw' will be used.</item>
- <tag><c><![CDATA[--no_native]]></c> (or <c><![CDATA[-nn]]></c>)</tag>
- <item>Bypass the native code compilation of some key files that Dialyzer
- heuristically performs when dialyzing many files; this avoids the
- compilation time but it may result in (much) longer analysis
- time.</item>
- <tag><c><![CDATA[--no_native_cache]]></c></tag>
- <item>By default, Dialyzer caches the results of native compilation in the
- <c>$XDG_CACHE_HOME/erlang/dialyzer_hipe_cache</c> directory.
- <c>XDG_CACHE_HOME</c> defaults to <c>$HOME/.cache</c>.
- Use this option to disable caching.</item>
- <tag><c><![CDATA[--fullpath]]></c></tag>
- <item>Display the full path names of files for which warnings are emitted.</item>
- <tag><c><![CDATA[--gui]]></c></tag>
- <item>Use the GUI.</item>
+dialyzer --plts plt_1 ... plt_n -- files_to_analyze</code>
+ <p>Notice the <c>--</c> delimiter in the second case.</p>
+ </item>
+ <tag><c>--quiet</c> (or <c>-q</c>)</tag>
+ <item>
+ <p>Make Dialyzer a bit more quiet.</p>
+ </item>
+ <tag><c>-r dirs</c></tag>
+ <item>
+ <p>Same as <c>files_or_dirs</c>, but the specified
+ directories are searched
+ recursively for subdirectories containing <c>.erl</c> or
+ <c>.beam</c> files in them, depending on the type of
+ analysis.</p>
+ </item>
+ <tag><c>--raw</c></tag>
+ <item>
+ <p>When using Dialyzer from the command line, output the raw
+ analysis results (Erlang terms) instead of the formatted result.
+ The raw format
+ is easier to post-process (for example, to filter warnings or to
+ output HTML pages).</p>
+ </item>
+ <tag><c>--remove_from_plt</c></tag>
+ <item>
+ <p>The information from the files specified with
+ <c>-c</c> and <c>-r</c> is removed from
+ the PLT. Notice that this can cause a reanalysis of the remaining
+ dependent files.</p>
+ </item>
+ <tag><c>--shell</c></tag>
+ <item>
+ <p>Do not disable the Erlang shell while running the GUI.</p>
+ </item>
+ <tag><c>--src</c></tag>
+ <item>
+ <p>Override the default, which is to analyze BEAM files, and
+ analyze starting from Erlang source code instead.</p>
+ </item>
+ <tag><c>--statistics</c></tag>
+ <item>
+ <p>Print information about the progress of execution (analysis phases,
+ time spent in each, and size of the relative input).</p>
+ </item>
+ <tag><c>--verbose</c></tag>
+ <item>
+ <p>Make Dialyzer a bit more verbose.</p>
+ </item>
+ <tag><c>--version</c> (or <c>-v</c>)</tag>
+ <item>
+ <p>Print the Dialyzer version and some more information and
+ exit.</p>
+ </item>
+ <tag><c>-Wwarn</c></tag>
+ <item>
+ <p>A family of options that selectively turn on/off warnings.
+ (For help on the names of warnings, use
+ <c>dialyzer -Whelp</c>.)
+ Notice that the options can also be specified in the file with a
+ <c>-dialyzer()</c> attribute. For details, see section <seealso
+ marker="#suppression">Requesting or Suppressing Warnings in
+ Source Files</seealso>.</p>
+ </item>
</taglist>
+
<note>
- <p>* denotes that multiple occurrences of these options are possible.</p>
- <p>** options <c><![CDATA[-D]]></c> and <c><![CDATA[-I]]></c> work both from command-line and in the Dialyzer GUI;
- the syntax of defines and includes is the same as that used by <c><![CDATA[erlc]]></c>.</p>
+ <p>** options <c>-D</c> and <c>-I</c> work both
+ from the command line and in the Dialyzer GUI; the syntax of
+ defines and includes is the same as that used by
+ <seealso marker="erts:erlc">erlc(1)</seealso>.</p>
</note>
- <p>Warning options:</p>
+
+ <p><em>Warning options:</em></p>
+
<taglist>
- <tag><c><![CDATA[-Wno_return]]></c></tag>
- <item>Suppress warnings for functions that will never return a
- value.</item>
- <tag><c><![CDATA[-Wno_unused]]></c></tag>
- <item>Suppress warnings for unused functions.</item>
- <tag><c><![CDATA[-Wno_improper_lists]]></c></tag>
- <item>Suppress warnings for construction of improper lists.</item>
- <tag><c><![CDATA[-Wno_fun_app]]></c></tag>
- <item>Suppress warnings for fun applications that will fail.</item>
- <tag><c><![CDATA[-Wno_match]]></c></tag>
- <item>Suppress warnings for patterns that are unused or cannot
- match.</item>
- <tag><c><![CDATA[-Wno_opaque]]></c></tag>
- <item>Suppress warnings for violations of opaqueness of data types.</item>
- <tag><c><![CDATA[-Wno_fail_call]]></c></tag>
- <item>Suppress warnings for failing calls.</item>
- <tag><c><![CDATA[-Wno_contracts]]></c></tag>
- <item>Suppress warnings about invalid contracts.</item>
- <tag><c><![CDATA[-Wno_behaviours]]></c></tag>
- <item>Suppress warnings about behaviour callbacks which drift from the
- published recommended interfaces.</item>
- <tag><c><![CDATA[-Wno_missing_calls]]></c></tag>
- <item>Suppress warnings about calls to missing functions.</item>
- <tag><c><![CDATA[-Wno_undefined_callbacks]]></c></tag>
- <item>Suppress warnings about behaviours that have no
- <c>-callback</c> attributes for their callbacks.</item>
- <tag><c><![CDATA[-Wunmatched_returns]]></c>***</tag>
- <item>Include warnings for function calls which ignore a structured return
- value or do not match against one of many possible return
- value(s).</item>
- <tag><c><![CDATA[-Werror_handling]]></c>***</tag>
- <item>Include warnings for functions that only return by means of an
- exception.</item>
- <tag><c><![CDATA[-Wrace_conditions]]></c>***</tag>
- <item>Include warnings for possible race conditions. Note that the
- analysis that finds data races performs intra-procedural data flow analysis
- and can sometimes explode in time. Enable it at your own risk.
- </item>
- <tag><c><![CDATA[-Wunderspecs]]></c>***</tag>
- <item>Warn about underspecified functions
- (the -spec is strictly more allowing than the success typing).</item>
- <tag><c><![CDATA[-Wunknown]]></c>***</tag>
- <item>Let warnings about unknown functions and types affect the
- exit status of the command line version. The default is to ignore
- warnings about unknown functions and types when setting the exit
- status. When using the Dialyzer from Erlang, warnings about unknown
- functions and types are returned; the default is not to return
- these warnings.</item>
+ <tag><c>-Werror_handling</c> (***)</tag>
+ <item>
+ <p>Include warnings for functions that only return by an exception.</p>
+ </item>
+ <tag><c>-Wno_behaviours</c></tag>
+ <item>
+ <p>Suppress warnings about behavior callbacks that drift from the
+ published recommended interfaces.</p>
+ </item>
+ <tag><c>-Wno_contracts</c></tag>
+ <item>
+ <p>Suppress warnings about invalid contracts.</p>
+ </item>
+ <tag><c>-Wno_fail_call</c></tag>
+ <item>
+ <p>Suppress warnings for failing calls.</p>
+ </item>
+ <tag><c>-Wno_fun_app</c></tag>
+ <item>
+ <p>Suppress warnings for fun applications that will fail.</p>
+ </item>
+ <tag><c>-Wno_improper_lists</c></tag>
+ <item>
+ <p>Suppress warnings for construction of improper lists.</p>
+ </item>
+ <tag><c>-Wno_match</c></tag>
+ <item>
+ <p>Suppress warnings for patterns that are unused or cannot match.</p>
+ </item>
+ <tag><c>-Wno_missing_calls</c></tag>
+ <item>
+ <p>Suppress warnings about calls to missing functions.</p>
+ </item>
+ <tag><c>-Wno_opaque</c></tag>
+ <item>
+ <p>Suppress warnings for violations of opacity of data types.</p>
+ </item>
+ <tag><c>-Wno_return</c></tag>
+ <item>
+ <p>Suppress warnings for functions that will never return a value.</p>
+ </item>
+ <tag><c>-Wno_undefined_callbacks</c></tag>
+ <item>
+ <p>Suppress warnings about behaviors that have no
+ <c>-callback</c> attributes for their callbacks.</p>
+ </item>
+ <tag><c>-Wno_unused</c></tag>
+ <item>
+ <p>Suppress warnings for unused functions.</p>
+ </item>
+ <tag><c>-Wrace_conditions</c> (***)</tag>
+ <item>
+ <p>Include warnings for possible race conditions. Notice that the
+ analysis that finds data races performs intra-procedural data flow
+ analysis and can sometimes explode in time. Enable it at your own
+ risk.</p>
+ </item>
+ <tag><c>-Wunderspecs</c> (***)</tag>
+ <item>
+ <p>Warn about underspecified functions (the specification is strictly
+ more allowing than the success typing).</p>
+ </item>
+ <tag><c>-Wunknown</c> (***)</tag>
+ <item>
+ <p>Let warnings about unknown functions and types affect the
+ exit status of the command-line version. The default is to ignore
+ warnings about unknown functions and types when setting the exit
+ status. When using Dialyzer from Erlang, warnings about unknown
+ functions and types are returned; the default is not to return
+ these warnings.</p>
+ </item>
+ <tag><c>-Wunmatched_returns</c> (***)</tag>
+ <item>
+ <p>Include warnings for function calls that ignore a structured return
+ value or do not match against one of many possible return
+ value(s).</p>
+ </item>
</taglist>
- <p>The following options are also available but their use is not
- recommended: (they are mostly for Dialyzer developers and internal
- debugging)</p>
+
+ <p>The following options are also available, but their use is not
+ recommended (they are mostly for Dialyzer developers and internal
+ debugging):</p>
+
<taglist>
- <tag><c><![CDATA[-Woverspecs]]></c>***</tag>
- <item>Warn about overspecified functions
- (the -spec is strictly less allowing than the success typing).</item>
- <tag><c><![CDATA[-Wspecdiffs]]></c>***</tag>
- <item>Warn when the -spec is different than the success typing.</item>
+ <tag><c>-Woverspecs</c> (***)</tag>
+ <item>
+ <p>Warn about overspecified functions (the specification is strictly
+ less allowing than the success typing).</p>
+ </item>
+ <tag><c>-Wspecdiffs</c> (***)</tag>
+ <item>
+ <p>Warn when the specification is different than the success typing.</p>
+ </item>
</taglist>
+
<note>
- <p>*** Identifies options that turn on warnings rather than
- turning them off.</p>
+ <p>*** denotes options that turn on warnings rather than
+ turning them off.</p>
</note>
</section>
<section>
- <title>Using the Dialyzer from Erlang</title>
- <p>You can also use Dialyzer directly from Erlang. Both the GUI and the
- command line versions are available. The options are similar to the ones
- given from the command line, so please refer to the sections above for
- a description of these.</p>
+ <title>Using Dialyzer from Erlang</title>
+ <p>Dialyzer can be used directly from Erlang. Both the GUI and the
+ command-line versions are also available. The options are similar to the
+ ones given from the command line, see section
+ <seealso marker="#command_line">
+ Using Dialyzer from the Command Line</seealso>.</p>
</section>
<section>
<marker id="suppression"></marker>
<title>Requesting or Suppressing Warnings in Source Files</title>
- <p>
- The <c>-dialyzer()</c> attribute can be used for turning off
+ <p>Attribute <c>-dialyzer()</c> can be used for turning off
warnings in a module by specifying functions or warning options.
For example, to turn off all warnings for the function
- <c>f/0</c>, include the following line:
- </p>
-<code type="none">
--dialyzer({nowarn_function, f/0}).
-</code>
+ <c>f/0</c>, include the following line:</p>
+
+ <code type="none">
+-dialyzer({nowarn_function, f/0}).</code>
+
<p>To turn off warnings for improper lists, add the following line
- to the source file:
- </p>
-<code type="none">
--dialyzer(no_improper_lists).
-</code>
- <p>The <c>-dialyzer()</c> attribute is allowed after function
- declarations. Lists of warning options or functions are allowed:
- </p>
-<code type="none">
--dialyzer([{nowarn_function, [f/0]}, no_improper_lists]).
-</code>
- <p>
- Warning options can be restricted to functions:
- </p>
-<code type="none">
--dialyzer({no_improper_lists, g/0}).
-</code>
-<code type="none">
--dialyzer({[no_return, no_match], [g/0, h/0]}).
-</code>
- <p>
- For help on the warning options use <c>dialyzer -Whelp</c>. The
- options are also enumerated <seealso
- marker="#gui/1">below</seealso> (<c>WarnOpts</c>).
- </p>
- <note>
- <p>
- The <c>-dialyzer()</c> attribute is not checked by the Erlang
- Compiler, but by the Dialyzer itself.
- </p>
- </note>
+ to the source file:</p>
+
+ <code type="none">
+-dialyzer(no_improper_lists).</code>
+
+ <p>Attribute <c>-dialyzer()</c> is allowed after function
+ declarations. Lists of warning options or functions are allowed:</p>
+
+ <code type="none">
+-dialyzer([{nowarn_function, [f/0]}, no_improper_lists]).</code>
+
+ <p>Warning options can be restricted to functions:</p>
+
+ <code type="none">
+-dialyzer({no_improper_lists, g/0}).</code>
+
+ <code type="none">
+-dialyzer({[no_return, no_match], [g/0, h/0]}).</code>
+
+ <p>For help on the warning options, use <c>dialyzer -Whelp</c>. The
+ options are also enumerated, see function <seealso marker="#gui/1">
+ <c>gui/1</c></seealso> below (<c>WarnOpts</c>).</p>
+
<note>
- <p>
- The warning option <c>-Wrace_conditions</c> has no effect when
- set in source files.
- </p>
+ <p>Warning option <c>-Wrace_conditions</c> has no effect when
+ set in source files.</p>
</note>
- <p>
- The <c>-dialyzer()</c> attribute can also be used for turning on
- warnings. For instance, if a module has been fixed regarding
- unmatched returns, adding the line
- </p>
-<code type="none">
--dialyzer(unmatched_returns).
-</code>
- <p>
- can help in assuring that no new unmatched return warnings are
- introduced.
- </p>
+
+ <p>Attribute <c>-dialyzer()</c> can also be used for turning on
+ warnings. For example, if a module has been fixed regarding
+ unmatched returns, adding the following line can help in assuring
+ that no new unmatched return warnings are introduced:</p>
+
+ <code type="none">
+-dialyzer(unmatched_returns).</code>
</section>
<funcs>
<func>
+ <name>format_warning(Msg) -> string()</name>
+ <fsummary>Get the string version of a warning message.</fsummary>
+ <type>
+ <v>Msg = {Tag, Id, msg()}</v>
+ <d>See <c>run/1</c>.</d>
+ </type>
+ <desc>
+ <p>Get a string from warnings as returned by
+ <seealso marker="#run/1"><c>run/1</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
<name>gui() -> ok | {error, Msg}</name>
<name>gui(OptList) -> ok | {error, Msg}</name>
- <fsummary>Dialyzer GUI version</fsummary>
+ <fsummary>Dialyzer GUI version.</fsummary>
<type>
- <v>OptList -- see below</v>
+ <v>OptList</v>
+ <d>See below.</d>
</type>
<desc>
<p>Dialyzer GUI version.</p>
@@ -368,9 +499,12 @@ OptList :: [Option]
Option :: {files, [Filename :: string()]}
| {files_rec, [DirName :: string()]}
| {defines, [{Macro :: atom(), Value :: term()}]}
- | {from, src_code | byte_code} %% Defaults to byte_code
- | {init_plt, FileName :: string()} %% If changed from default
- | {plts, [FileName :: string()]} %% If changed from default
+ | {from, src_code | byte_code}
+ %% Defaults to byte_code
+ | {init_plt, FileName :: string()}
+ %% If changed from default
+ | {plts, [FileName :: string()]}
+ %% If changed from default
| {include_dirs, [DirName :: string()]}
| {output_file, FileName :: string()}
| {output_plt, FileName :: string()}
@@ -383,76 +517,71 @@ Option :: {files, [Filename :: string()]}
| {warnings, [WarnOpts]}
| {get_warnings, bool()}
-WarnOpts :: no_return
- | no_unused
- | no_improper_lists
+WarnOpts :: error_handling
+ | no_behaviours
+ | no_contracts
+ | no_fail_call
| no_fun_app
+ | no_improper_lists
| no_match
+ | no_missing_calls
| no_opaque
- | no_fail_call
- | no_contracts
- | no_behaviours
+ | no_return
| no_undefined_callbacks
- | unmatched_returns
- | error_handling
+ | no_unused
| race_conditions
- | overspecs
| underspecs
- | specdiffs
- | unknown</code>
+ | unknown
+ | unmatched_returns
+ | overspecs
+ | specdiffs</code>
</desc>
</func>
+
<func>
- <name>run(OptList) -> Warnings</name>
- <fsummary>Dialyzer command line version</fsummary>
- <type>
- <v>OptList -- see gui/0,1</v>
- <v>Warnings -- see below </v>
- </type>
+ <name>plt_info(string()) -> {'ok', [{atom(), any()}]} | {'error', atom()}</name>
+ <fsummary>Return information about the specified PLT.</fsummary>
<desc>
- <p>Dialyzer command line version.</p>
- <code type="none">
-Warnings :: [{Tag, Id, Msg}]
-Tag :: 'warn_behaviour'
- | 'warn_bin_construction'
- | 'warn_callgraph'
- | 'warn_contract_not_equal'
- | 'warn_contract_range'
- | 'warn_contract_subtype'
- | 'warn_contract_supertype'
- | 'warn_contract_syntax'
- | 'warn_contract_types'
- | 'warn_failing_call'
- | 'warn_fun_app'
- | 'warn_matching'
- | 'warn_non_proper_list'
- | 'warn_not_called'
- | 'warn_opaque'
- | 'warn_race_condition'
- | 'warn_return_no_exit'
- | 'warn_return_only_exit'
- | 'warn_umatched_return'
- | 'warn_undefined_callbacks'
- | 'warn_unknown'
-Id = {File :: string(), Line :: integer()}
-Msg = msg() -- Undefined</code>
+ <p>Returns information about the specified PLT.</p>
</desc>
</func>
+
<func>
- <name>format_warning(Msg) -> string()</name>
- <fsummary>Get the string version of a warning message.</fsummary>
+ <name>run(OptList) -> Warnings</name>
+ <fsummary>Dialyzer command-line version.</fsummary>
<type>
- <v>Msg = {Tag, Id, msg()} -- See run/1</v>
+ <v>OptList</v>
+ <d>See <c>gui/0,1</c>.</d>
+ <v>Warnings</v>
+ <d>See below.</d>
</type>
<desc>
- <p>Get a string from warnings as returned by dialyzer:run/1.</p>
- </desc>
- </func>
- <func>
- <name>plt_info(string()) -> {'ok', [{atom(), any()}]} | {'error', atom()}</name>
- <fsummary>Returns information about the specified plt.</fsummary>
- <desc>
- <p>Returns information about the specified plt.</p>
+ <p>Dialyzer command-line version.</p>
+ <code type="none">
+Warnings :: [{Tag, Id, Msg}]
+Tag :: 'warn_behaviour'
+ | 'warn_bin_construction'
+ | 'warn_callgraph'
+ | 'warn_contract_not_equal'
+ | 'warn_contract_range'
+ | 'warn_contract_subtype'
+ | 'warn_contract_supertype'
+ | 'warn_contract_syntax'
+ | 'warn_contract_types'
+ | 'warn_failing_call'
+ | 'warn_fun_app'
+ | 'warn_matching'
+ | 'warn_non_proper_list'
+ | 'warn_not_called'
+ | 'warn_opaque'
+ | 'warn_race_condition'
+ | 'warn_return_no_exit'
+ | 'warn_return_only_exit'
+ | 'warn_umatched_return'
+ | 'warn_undefined_callbacks'
+ | 'warn_unknown'
+Id = {File :: string(), Line :: integer()}
+Msg = msg() -- Undefined</code>
</desc>
</func>
</funcs>
diff --git a/lib/dialyzer/doc/src/dialyzer_chapter.xml b/lib/dialyzer/doc/src/dialyzer_chapter.xml
index c445f2633f..b5acf3732e 100644
--- a/lib/dialyzer/doc/src/dialyzer_chapter.xml
+++ b/lib/dialyzer/doc/src/dialyzer_chapter.xml
@@ -25,196 +25,211 @@
<title>Dialyzer</title>
<prepared></prepared>
<docno></docno>
- <date></date>
+ <date>2016-09-19</date>
<rev></rev>
<file>dialyzer_chapter.xml</file>
</header>
<section>
<title>Introduction</title>
- <p><em>Dialyzer</em> is a static analysis tool that identifies software discrepancies
- such as type errors, unreachable code, unnecessary tests, etc in single Erlang modules
- or entire (sets of) applications.</p>
- </section>
-
- <section>
- <title>Using the Dialyzer from the GUI</title>
-
<section>
- <title>Choosing the applications or modules</title>
- <p>In the "File" window you will find a listing of the current directory.
- Click your way to the directories/modules you want to add or type the
- correct path in the entry.</p>
- <p>Mark the directories/modules you want to analyze for discrepancies and
- click "Add". You can either add the <c><![CDATA[.beam]]></c> and <c><![CDATA[.erl]]></c>-files directly, or
- you can add directories that contain these kinds of files. Note that
- you are only allowed to add the type of files that can be analyzed in
- the current mode of operation (see below), and that you cannot mix
- <c><![CDATA[.beam]]></c> and <c><![CDATA[.erl]]></c>-files.</p>
+ <title>Scope</title>
+ <p>Dialyzer is a static analysis tool that identifies software
+ discrepancies, such as definite type errors, code that has become dead
+ or unreachable because of programming error, and unnecessary tests,
+ in single Erlang modules or entire (sets of) applications.</p>
+
+ <p>Dialyzer can be called from the command line, from Erlang,
+ and from a GUI.</p>
</section>
<section>
- <title>The analysis modes</title>
- <p>Dialyzer has two modes of analysis, "Byte Code" or "Source Code".
- These are controlled by the buttons in the top-middle part of the
- main window, under "Analysis Options".</p>
- </section>
-
- <section>
- <title>Controlling the discrepancies reported by the Dialyzer</title>
- <p>Under the "Warnings" pull-down menu, there are buttons that control
- which discrepancies are reported to the user in the "Warnings" window.
- By clicking on these buttons, one can enable/disable a whole class of
- warnings. Information about the classes of warnings can be found on
- the "Warnings" item under the "Help" menu (at the rightmost top corner).</p>
- <p>If modules are compiled with inlining, spurious warnings may be emitted.
- In the "Options" menu you can choose to ignore inline-compiled modules
- when analyzing byte code. When starting from source code this is not a
- problem since the inlining is explicitly turned off by Dialyzer. The
- option causes Dialyzer to suppress all warnings from inline-compiled
- modules, since there is currently no way for Dialyzer to find what
- parts of the code have been produced by inlining. </p>
+ <title>Prerequisites</title>
+ <p>It is assumed that the reader is familiar with the Erlang programming
+ language.</p>
</section>
+ </section>
- <section>
- <title>Running the analysis</title>
- <p>Once you have chosen the modules or directories you want to analyze,
- click the "Run" button to start the analysis. If for some reason you
- want to stop the analysis while it is running, push the "Stop" button.</p>
- <p>The information from the analysis will be displayed in the Log and the
- Warnings windows.</p>
- </section>
+ <section>
+ <marker id="plt"/>
+ <title>The Persistent Lookup Table</title>
+ <p>Dialyzer stores the result of an analysis in a Persistent
+ Lookup Table (PLT). The PLT can then be used as a starting
+ point for later analyses. It is recommended to build a PLT with the
+ Erlang/OTP applications that you are using, but also to include your
+ own applications that you are using frequently.</p>
+
+ <p>The PLT is built using option <c>--build_plt</c> to Dialyzer.
+ The following command builds the recommended minimal PLT for
+ Erlang/OTP:</p>
- <section>
- <title>Include directories and macro definitions</title>
- <p>When analyzing from source you might have to supply Dialyzer with a
- list of include directories and macro definitions (as you can do with
- the <c><![CDATA[erlc]]></c> flags <c><![CDATA[-I]]></c> and <c><![CDATA[-D]]></c>). This can be done either by starting Dialyzer
- with these flags from the command line as in:</p>
- <code type="none">
+ <code type="none">
+dialyzer --build_plt --apps erts kernel stdlib mnesia</code>
- dialyzer -I my_includes -DDEBUG -Dvsn=42 -I one_more_dir
- </code>
- <p>or by adding these explicitly using the "Manage Macro Definitions" or
- "Manage Include Directories" sub-menus in the "Options" menu.</p>
- </section>
+ <p>Dialyzer looks if there is an environment variable called
+ <c>DIALYZER_PLT</c> and places the PLT at this location. If no such
+ variable is set, Dialyzer places the PLT at
+ <c>$HOME/.dialyzer_plt</c>. The placement can also be specified using
+ the options <c>--plt</c> or <c>--output_plt</c>.</p>
- <section>
- <title>Saving the information on the Log and Warnings windows</title>
- <p>In the "File" menu there are options to save the contents of the Log
- and the Warnings window. Just choose the options and enter the file to
- save the contents in.</p>
- <p>There are also buttons to clear the contents of each window.</p>
- </section>
+ <p>Information can be added to an existing PLT using option
+ <c>--add_to_plt</c>. If you also want to include the Erlang compiler in
+ the PLT and place it in a new PLT, then use the following command:</p>
- <section>
- <title>Inspecting the inferred types of the analyzed functions</title>
- <p>Dialyzer stores the information of the analyzed functions in a
- Persistent Lookup Table (PLT). After an analysis you can inspect this
- information. In the PLT menu you can choose to either search the PLT
- or inspect the contents of the whole PLT. The information is presented
- in edoc format.</p>
- </section>
- </section>
+ <code type="none">
+dialyzer --add_to_plt --apps compiler --output_plt my.plt</code>
- <section>
- <title>Using the Dialyzer from the command line</title>
- <p>See <seealso marker="dialyzer">dialyzer(3)</seealso>.</p>
- </section>
+ <p>Then you can add your favorite application my_app to the new
+ PLT:</p>
- <section>
- <title>Using the Dialyzer from Erlang</title>
- <p>See <seealso marker="dialyzer">dialyzer(3)</seealso>.</p>
- </section>
+ <code type="none">
+dialyzer --add_to_plt --plt my.plt -r my_app/ebin</code>
- <section>
- <title>More on the Persistent Lookup Table (PLT)</title>
+ <p>But you realize that it is unnecessary to have the Erlang compiler in this
+ one:</p>
- <p> The persistent lookup table, or PLT, is used to store the
- result of an analysis. The PLT can then be used as a starting
- point for later analyses. It is recommended to build a PLT with
- the otp applications that you are using, but also to include your
- own applications that you are using frequently.</p>
+ <code type="none">
+dialyzer --remove_from_plt --plt my.plt --apps compiler</code>
- <p>The PLT is built using the --build_plt option to dialyzer. The
- following command builds the recommended minimal PLT for OTP.</p>
+ <p>Later, when you have fixed a bug in your application my_app,
+ you want to update the PLT so that it becomes fresh the next time
+ you run Dialyzer. In this case, run the following command:</p>
<code type="none">
+dialyzer --check_plt --plt my.plt</code>
- dialyzer --build_plt -r $ERL_TOP/lib/stdlib/ebin\
- $ERL_TOP/lib/kernel/ebin \
- $ERL_TOP/lib/mnesia/ebin
- </code>
+ <p>Dialyzer then reanalyzes the changed files
+ and the files that depend on these files. Notice that this
+ consistency check is performed automatically the next time you
+ run Dialyzer with this PLT. Option <c>--check_plt</c> is only
+ for doing so without doing any other analysis.</p>
- <p>Dialyzer will look if there is an environment variable called
- $DIALYZER_PLT and place the PLT at this location. If no such
- variable is set, Dialyzer will place the PLT at
- $HOME/.dialyzer_plt. The placement can also be specified using the
- --plt, or --output_plt options.</p>
-
- <p>You can also add information to an existing plt using the
- --add_to_plt option. Suppose you want to also include the compiler
- in the PLT and place it in a new PLT, then give the command</p>
+ <p>To get information about a PLT, use the following option:</p>
<code type="none">
+dialyzer --plt_info</code>
- dialyzer --add_to_plt -r $ERL_TOP/lib/compiler/ebin --output_plt my.plt
- </code>
+ <p>To specify which PLT, use option <c>--plt</c>.</p>
- <p>Then you would like to add your favorite application my_app to
- the new plt.</p>
+ <p>To get the output printed to a file, use option <c>--output_file</c>.</p>
- <code type="none">
+ <p>Notice that when manipulating the PLT, no warnings are
+ emitted. To turn on warnings during (re)analysis of the PLT, use
+ option <c>--get_warnings</c>.</p>
+ </section>
- dialyzer --add_to_plt --plt my.plt -r my_app/ebin
- </code>
+ <section>
+ <title>Using Dialyzer from the Command Line</title>
+ <p>Dialyzer has a command-line version for automated use.
+ See <seealso marker="dialyzer"><c>dialyzer(3)</c></seealso>.</p>
+ </section>
- <p>But you realize that it is unnecessary to have compiler in this one.</p>
+ <section>
+ <title>Using Dialyzer from Erlang</title>
+ <p>Dialyzer can also be used directly from Erlang.
+ See <seealso marker="dialyzer"><c>dialyzer(3)</c></seealso>.</p>
+ </section>
- <code type="none">
+ <section>
+ <marker id="dialyzer_gui"/>
+ <title>Using Dialyzer from the GUI</title>
+ <section>
+ <title>Choosing the Applications or Modules</title>
+ <p>The <em>File</em> window displays a listing of the current directory.
+ Click your way to the directories/modules you want to add or type the
+ correct path in the entry.</p>
- dialyzer --remove_from_plt --plt my.plt -r $ERL_TOP/lib/compiler/ebin
- </code>
+ <p>Mark the directories/modules you want to analyze for discrepancies and
+ click <em>Add</em>. You can either add the <c>.beam</c> and
+ <c>.erl</c> files directly, or add directories that contain
+ these kind of files. Notice that
+ you are only allowed to add the type of files that can be analyzed in
+ the current mode of operation (see below), and that you cannot mix
+ <c>.beam</c> and <c>.erl</c> files.</p>
+ </section>
- <p> Later, when you have fixed a bug in your application my_app,
- you want to update the plt so that it will be fresh the next time
- you run Dialyzer, run the command</p>
+ <section>
+ <title>Analysis Modes</title>
+ <p>Dialyzer has two analysis modes: "Byte Code" and "Source Code".
+ They are controlled by the buttons in the top-middle part of the
+ main window, under <em>Analysis Options</em>.</p>
+ </section>
- <code type="none">
+ <section>
+ <title>Controlling the Discrepancies Reported by Dialyzer</title>
+ <p>Under the <em>Warnings</em> pull-down menu, there are buttons that
+ control which discrepancies are reported to the user in the
+ <em>Warnings</em> window. By clicking these buttons, you can
+ enable/disable a whole class of warnings. Information about the classes
+ of warnings is found on the "Warnings" item under the <em>Help</em>
+ menu (in the rightmost top corner).</p>
+
+ <p>If modules are compiled with inlining, spurious warnings can be
+ emitted. In the <em>Options</em> menu you can choose to ignore
+ inline-compiled modules when analyzing byte code.
+ When starting from source code, this is not a problem because
+ inlining is explicitly turned off by Dialyzer. The option causes
+ Dialyzer to suppress all warnings from inline-compiled
+ modules, as there is currently no way for Dialyzer to find what
+ parts of the code have been produced by inlining.</p>
+ </section>
- dialyzer --check_plt --plt my.plt
- </code>
+ <section>
+ <title>Running the Analysis</title>
+ <p>Once you have chosen the modules or directories you want to analyze,
+ click the <em>Run</em> button to start the analysis. If you for some
+ reason want to stop the analysis while it is running, click the
+ <em>Stop</em> button.</p>
- <p> Dialyzer will then reanalyze the files that have been changed,
- and the files that depend on these files. Note that this
- consistency check will be performed automatically the next time
- you run Dialyzer with this plt. The --check_plt option is merely
- for doing so without doing any other analysis.</p>
+ <p>The information from the analysis is displayed in the <em>Log</em>
+ window and the <em>Warnings</em> window.</p>
+ </section>
- <p> To get some information about a plt use the option</p>
- <code type="none">
+ <section>
+ <title>Include Directories and Macro Definitions</title>
+ <p>When analyzing from source, you might have to supply Dialyzer
+ with a list of include directories and macro definitions (as you can do
+ with the <seealso marker="erts:erlc"><c>erlc</c></seealso> flags
+ <c>-I</c> and <c>-D</c>). This can be done
+ either by starting Dialyzer with these flags from the command
+ line as in:</p>
+
+ <code type="none">
+dialyzer -I my_includes -DDEBUG -Dvsn=42 -I one_more_dir</code>
- dialyzer --plt_info
- </code>
+ <p>or by adding these explicitly using submenu
+ <em>Manage Macro Definitions</em> or
+ <em>Manage Include Directories</em> in the <em>Options</em> menu.</p>
+ </section>
- <p>You can also specify which plt with the --plt option, and get the
- output printed to a file with --output_file</p>
+ <section>
+ <title>Saving the Information on the Log and Warnings Windows</title>
+ <p>The <em>File</em> menu includes options to save the contents of the
+ <em>Log</em> window and the <em>Warnings</em> window. Simply choose the
+ options and enter the file to save the contents in.</p>
- <p>Note that when manipulating the plt, no warnings are
- emitted. To turn on warnings during (re)analysis of the plt, use
- the option --get_warnings.</p>
+ <p>There are also buttons to clear the contents of each window.</p>
+ </section>
+ <section>
+ <title>Inspecting the Inferred Types of the Analyzed Functions</title>
+ <p>Dialyzer stores the information of the analyzed functions in a
+ Persistent Lookup Table (PLT), see section
+ <seealso marker="#plt">The Persistent Lookup Table</seealso>.</p>
+
+ <p>After an analysis, you can inspect this information.
+ In the <em>PLT</em> menu you can choose to either search the PLT
+ or inspect the contents of the whole PLT. The information is presented
+ in <seealso marker="edoc:edoc"><c>EDoc</c></seealso> format.</p>
+ </section>
</section>
<section>
- <title>Feedback and bug reports</title>
- <p>At this point, we very much welcome user feedback (even wish-lists!).
- If you notice something weird, especially if the Dialyzer reports any
- discrepancy that is a false positive, please send an error report
- describing the symptoms and how to reproduce them to:</p>
- <code type="none"><![CDATA[
- ]]></code>
+ <title>Feedback and Bug Reports</title>
+ <p>We very much welcome user feedback - even wishlists!
+ If you notice anything weird, especially if Dialyzer reports
+ any discrepancy that is a false positive, please send an error report
+ describing the symptoms and how to reproduce them.</p>
</section>
</chapter>
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index a5a52fee61..0d2cb6c4df 100644
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2006</year><year>2016</year>
+ <year>2006</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,6 +32,201 @@
<p>This document describes the changes made to the Dialyzer
application.</p>
+<section><title>Dialyzer 3.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> The check of bad type variables in type declarations
+ was mistakingly removed in Erlang/OTP 18, and is now
+ re-introduced. </p>
+ <p>
+ Own Id: OTP-14423 Aux Id: OTP-14323 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Analyzing modules with binary construction with huge
+ strings is now much faster. The compiler also compiles
+ such modules slightly faster.</p>
+ <p>
+ Own Id: OTP-14125 Aux Id: ERL-308 </p>
+ </item>
+ <item>
+ <p> The peak memory consumption is reduced. </p>
+ <p>
+ Own Id: OTP-14127</p>
+ </item>
+ <item>
+ <p> Warnings about unknown types are now also generated
+ for types not used by any function specification. </p>
+ <p>
+ Own Id: OTP-14218 Aux Id: OTP-14127 </p>
+ </item>
+ <item>
+ <p>TypEr has been removed as separate application and is
+ now a part of the Dialyzer application. Documentation for
+ TypEr has been added in the Dialyzer application.</p>
+ <p>
+ Own Id: OTP-14336</p>
+ </item>
+ <item>
+ <p>The format of debug information that is stored in BEAM
+ files (when <c>debug_info</c> is used) has been changed.
+ The purpose of the change is to better support other
+ BEAM-based languages such as Elixir or LFE.</p>
+ <p>All tools included in OTP (dialyzer, debugger, cover,
+ and so on) will handle both the new format and the
+ previous format. Tools that retrieve the debug
+ information using <c>beam_lib:chunk(Beam,
+ [abstract_code])</c> will continue to work with both the
+ new and old format. Tools that call
+ <c>beam_lib:chunk(Beam, ["Abst"])</c> will not work with
+ the new format.</p>
+ <p>For more information, see the description of
+ <c>debug_info</c> in the documentation for
+ <c>beam_lib</c> and the description of the
+ <c>{debug_info,{Backend,Data}}</c> option in the
+ documentation for <c>compile</c>.</p>
+ <p>
+ Own Id: OTP-14369 Aux Id: PR-1367 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Dialyzer 3.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Report unknown types properly. A bug was introduced
+ in Erlang/OTP 19.3, where warnings about unknown types
+ were simply discarded. </p>
+ <p>
+ Own Id: OTP-14368</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Dialyzer 3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix a bug concerning parameterized opaque types. </p>
+ <p>
+ Own Id: OTP-14130</p>
+ </item>
+ <item>
+ <p> Improve a few warnings. One of them could cause a
+ crash. </p>
+ <p>
+ Own Id: OTP-14177</p>
+ </item>
+ <item>
+ <p>The dialyzer and observer applications will now use a
+ portable way to find the home directory. That means that
+ there is no longer any need to manually set the HOME
+ environment variable on Windows.</p>
+ <p>
+ Own Id: OTP-14249 Aux Id: ERL-161 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> The peak memory consumption is reduced. </p><p> The
+ evaluation of huge SCCs in <c>dialyzer_typesig</c> is
+ optimized. </p><p> Analyzing modules with binary
+ construction with huge strings is now much faster. </p>
+ <p>
+ Own Id: OTP-14126 Aux Id: ERL-308 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Dialyzer 3.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix bugs regarding opaque types. </p>
+ <p>
+ Own Id: OTP-13693</p>
+ </item>
+ <item>
+ <p> Fix error handling of bad <c>-dialyzer()</c>
+ attributes. </p>
+ <p>
+ Own Id: OTP-13979 Aux Id: ERL-283 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> A few warning messages have been improved. </p>
+ <p>
+ Own Id: OTP-11403</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Dialyzer 3.0.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> The translation of forms to types is improved for
+ opaque types in a few cases. </p>
+ <p>
+ Own Id: OTP-13682</p>
+ </item>
+ <item>
+ <p> Add warning suppression to compiler-generated case
+ statements. Warnings about clauses that cannot match and
+ are also compiler generated are suppressed unless none of
+ the clauses return. </p>
+ <p>
+ Own Id: OTP-13723 Aux Id: ERL-159, PR-1121 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Dialyzer 3.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Fix a map related bug.</p>
+ <p>
+ Own Id: OTP-13709 Aux Id: ERL-177, PR-1115 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Dialyzer 3.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -485,7 +680,7 @@
or modifying opaque types within the scope of a module.
</p> <p> Hitherto the shape of terms (tuple, list, etc.)
has been used to determine the opaque terms, but now the
- contracts are used for decorating types with opaqueness.
+ contracts are used for decorating types with opacity.
</p>
<p>
Own Id: OTP-10397</p>
@@ -1468,7 +1663,7 @@
<list>
<item>
<p>The analysis accepts opaque type declarations and
- detects violations of opaqueness of terms of such types.
+ detects violations of opacity of terms of such types.
Starting with R13, many Erlang/OTP standard libraries
(array, dict, digraph, ets, gb_sets, gb_trees, queue, and
sets) contain opaque type declarations of their main data
diff --git a/lib/dialyzer/doc/src/part.xml b/lib/dialyzer/doc/src/part.xml
index 575f77549a..9bfcf21a66 100644
--- a/lib/dialyzer/doc/src/part.xml
+++ b/lib/dialyzer/doc/src/part.xml
@@ -25,12 +25,11 @@
<title>Dialyzer User's Guide</title>
<prepared></prepared>
<docno></docno>
- <date></date>
+ <date>2016-09-19</date>
<rev></rev>
<file>part.xml</file>
</header>
<description>
- <p><em>Dialyzer</em> is a static analysis tool that identifies software discrepancies such as type errors, unreachable code, unnecessary tests, etc in single Erlang modules or entire (sets of) applications.</p>
</description>
<xi:include href="dialyzer_chapter.xml"/>
</part>
diff --git a/lib/dialyzer/doc/src/ref_man.xml b/lib/dialyzer/doc/src/ref_man.xml
index 01478cfb40..d8cf324232 100644
--- a/lib/dialyzer/doc/src/ref_man.xml
+++ b/lib/dialyzer/doc/src/ref_man.xml
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2006</year><year>2016</year>
+ <year>2006</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -25,12 +25,12 @@
<title>Dialyzer Reference Manual</title>
<prepared></prepared>
<docno></docno>
- <date></date>
+ <date>2016-09-19</date>
<rev></rev>
</header>
<description>
- <p><em>Dialyzer</em> is a static analysis tool that identifies software discrepancies such as type errors, unreachable code, unnecessary tests, etc in single Erlang modules or entire (sets of) applications.</p>
</description>
<xi:include href="dialyzer.xml"/>
+ <xi:include href="typer.xml"/>
</application>
diff --git a/lib/dialyzer/doc/src/typer.xml b/lib/dialyzer/doc/src/typer.xml
new file mode 100644
index 0000000000..1cfbe94807
--- /dev/null
+++ b/lib/dialyzer/doc/src/typer.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2006</year><year>2017</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ </legalnotice>
+
+ <title>typer</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date>2017-04-13</date>
+ <rev></rev>
+ <file>type.xml</file>
+ </header>
+ <module>typer</module>
+ <modulesummary>Typer, a Type annotator for ERlang programs.
+ </modulesummary>
+ <description>
+ <p>TypEr shows type information for Erlang modules to the user.
+ Additionally, it can annotate the code of files with such type
+ information.</p>
+ </description>
+
+ <section>
+ <marker id="command_line"></marker>
+ <title>Using TypEr from the Command Line</title>
+ <p>TypEr is used from the command-line. This section provides a
+ brief description of the options. The same information can be
+ obtained by writing the following in a shell:</p>
+
+ <code type="none">
+typer --help</code>
+
+ <p><em>Usage:</em></p>
+
+ <code type="none">
+typer [--help] [--version] [--plt PLT] [--edoc]
+ [--show | --show-exported | --annotate | --annotate-inc-files]
+ [-Ddefine]* [-I include_dir]* [-pa dir]* [-pz dir]*
+ [-T application]* [-r] file*</code>
+
+ <note>
+ <p>* denotes that multiple occurrences of the option are possible.</p>
+ </note>
+
+ <p><em>Options:</em></p>
+
+ <taglist>
+
+ <tag><c>--r</c></tag>
+ <item>
+ <p>Search directories recursively for .erl files below them.</p>
+ </item>
+ <tag><c>--show</c></tag>
+ <item>
+ <p>Print type specifications for all functions on stdout.
+ (This is the default behaviour; this option is not really
+ needed.)</p>
+ </item>
+
+ <tag><c>--show-exported</c> (or <c>show_exported</c>)</tag>
+ <item>
+ <p>Same as <c>--show</c>, but print specifications for
+ exported functions only. Specs are displayed sorted
+ alphabetically on the function's name.</p>
+ </item>
+
+ <tag><c>--annotate</c></tag>
+ <item>
+ <p>Annotate the specified files with type specifications.</p>
+ </item>
+
+ <tag><c>--annotate-inc-files</c></tag>
+ <item>
+ <p>Same as <c>--annotate</c> but annotates all
+ <c>-include()</c> files as well as all .erl files. (Use this
+ option with caution - it has not been tested much).</p>
+ </item>
+
+ <tag><c>--edoc</c></tag>
+ <item>
+ <p>Print type information as Edoc <c>@spec</c> comments, not
+ as type specs.</p>
+ </item>
+
+ <tag><c>--plt</c></tag>
+ <item>
+ <p>Use the specified dialyzer PLT file rather than the default one.</p>
+ </item>
+
+ <tag><c>-T file*</c></tag>
+ <item>
+ <p>The specified file(s) already contain type specifications
+ and these are to be trusted in order to print specs for the
+ rest of the files. (Multiple files or dirs, separated by
+ spaces, can be specified.)</p>
+ </item>
+
+ <tag><c>-Dname</c> (or <c>-Dname=value</c>)</tag>
+ <item>
+ <p>Pass the defined name(s) to TypEr. (**)</p>
+ </item>
+
+ <tag><c>-I</c></tag>
+ <item>
+ <p>Pass the include_dir to TypEr. (**)</p>
+ </item>
+
+ <tag><c>-pa dir</c></tag>
+ <item>
+ <p>Include <c>dir</c> in the path for Erlang. This is useful
+ when analyzing files that have <c>-include_lib()</c>
+ directives or use parse transforms.</p>
+ </item>
+
+ <tag><c>-pz dir</c></tag>
+ <item>
+ <p>Include <c>dir</c> in the path for Erlang. This is useful
+ when analyzing files that have <c>-include_lib()</c>
+ directives or use parse transforms.</p>
+ </item>
+
+ <tag><c>--version</c> (or <c>-v</c>)</tag>
+ <item>
+ <p>Print the TypEr version and some more information and
+ exit.</p>
+ </item>
+
+ </taglist>
+
+ <note>
+ <p>** options <c>-D</c> and <c>-I</c> work both
+ from the command line and in the TypEr GUI; the syntax of
+ defines and includes is the same as that used by
+ <seealso marker="erts:erlc">erlc(1)</seealso>.</p>
+ </note>
+
+ </section>
+
+</erlref>
diff --git a/lib/dialyzer/src/Makefile b/lib/dialyzer/src/Makefile
index 256f20f549..fc08e7ca2f 100644
--- a/lib/dialyzer/src/Makefile
+++ b/lib/dialyzer/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2006-2016. All Rights Reserved.
+# Copyright Ericsson AB 2006-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -68,7 +68,8 @@ MODULES = \
dialyzer_typesig \
dialyzer_coordinator \
dialyzer_worker \
- dialyzer_utils
+ dialyzer_utils \
+ typer
HRL_FILES= dialyzer.hrl dialyzer_gui_wx.hrl
ERL_FILES= $(MODULES:%=%.erl)
@@ -117,6 +118,9 @@ $(EBIN)/dialyzer_plt.$(EMULATOR): dialyzer_plt.erl ../vsn.mk
$(EBIN)/dialyzer_gui_wx.$(EMULATOR): dialyzer_gui_wx.erl ../vsn.mk
$(erlc_verbose)erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) dialyzer_gui_wx.erl
+$(EBIN)/typer.$(EMULATOR): typer.erl ../vsn.mk
+ $(erlc_verbose)erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) typer.erl
+
$(APP_TARGET): $(APP_SRC) ../vsn.mk
$(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
diff --git a/lib/dialyzer/src/dialyzer.app.src b/lib/dialyzer/src/dialyzer.app.src
index 5b28f7ae86..5f803875b0 100644
--- a/lib/dialyzer/src/dialyzer.app.src
+++ b/lib/dialyzer/src/dialyzer.app.src
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -43,10 +43,11 @@
dialyzer_typesig,
dialyzer_utils,
dialyzer_timing,
- dialyzer_worker]},
+ dialyzer_worker,
+ typer]},
{registered, []},
{applications, [compiler, hipe, kernel, stdlib, wx]},
{env, []},
{runtime_dependencies, ["wx-1.2","syntax_tools-2.0","stdlib-3.0",
- "kernel-5.0","hipe-3.15.1","erts-8.0",
+ "kernel-5.0","hipe-3.15.4","erts-8.0",
"compiler-7.0"]}]}.
diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl
index bcac8afe64..c319acb2fb 100644
--- a/lib/dialyzer/src/dialyzer.erl
+++ b/lib/dialyzer/src/dialyzer.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer.erl
@@ -118,13 +111,13 @@ get_plt_info([PLT|PLTs]) ->
String =
case dialyzer_plt:included_files(PLT) of
{ok, Files} ->
- io_lib:format("The PLT ~s includes the following files:\n~p\n\n",
+ io_lib:format("The PLT ~ts includes the following files:\n~tp\n\n",
[PLT, Files]);
{error, read_error} ->
- Msg = io_lib:format("Could not read the PLT file ~p\n\n", [PLT]),
+ Msg = io_lib:format("Could not read the PLT file ~tp\n\n", [PLT]),
throw({dialyzer_error, Msg});
{error, no_such_file} ->
- Msg = io_lib:format("The PLT file ~p does not exist\n\n", [PLT]),
+ Msg = io_lib:format("The PLT file ~tp does not exist\n\n", [PLT]),
throw({dialyzer_error, Msg})
end,
String ++ get_plt_info(PLTs);
@@ -133,16 +126,16 @@ get_plt_info([]) -> "".
do_print_plt_info(PLTInfo, OutputFile) ->
case OutputFile =:= none of
true ->
- io:format("~s", [PLTInfo]),
+ io:format("~ts", [PLTInfo]),
?RET_NOTHING_SUSPICIOUS;
false ->
case file:open(OutputFile, [write]) of
{ok, FileDesc} ->
- io:format(FileDesc, "~s", [PLTInfo]),
+ io:format(FileDesc, "~ts", [PLTInfo]),
ok = file:close(FileDesc),
?RET_NOTHING_SUSPICIOUS;
{error, Reason} ->
- Msg1 = io_lib:format("Could not open output file ~p, Reason: ~p\n",
+ Msg1 = io_lib:format("Could not open output file ~tp, Reason: ~p\n",
[OutputFile, Reason]),
throw({dialyzer_error, Msg1})
end
@@ -271,7 +264,7 @@ cl_halt({ok, R = ?RET_DISCREPANCIES}, #options{output_file = Output}) ->
halt(R);
cl_halt({error, Msg1}, #options{output_file = Output}) ->
%% Msg2 = "dialyzer: Internal problems were encountered in the analysis",
- io:format("\ndialyzer: ~s\n", [Msg1]),
+ io:format("\ndialyzer: ~ts\n", [Msg1]),
cl_check_log(Output),
halt(?RET_INTERNAL_ERROR).
@@ -280,9 +273,9 @@ cl_halt({error, Msg1}, #options{output_file = Output}) ->
cl_check_log(none) ->
ok;
cl_check_log(Output) ->
- io:format(" Check output file `~s' for details\n", [Output]).
+ io:format(" Check output file `~ts' for details\n", [Output]).
--spec format_warning(raw_warning()) -> string().
+-spec format_warning(raw_warning() | dial_warning()) -> string().
format_warning(W) ->
format_warning(W, basename).
@@ -298,7 +291,7 @@ format_warning({_Tag, {File, Line}, Msg}, FOpt) when is_list(File),
basename -> filename:basename(File)
end,
String = lists:flatten(message_to_string(Msg)),
- lists:flatten(io_lib:format("~s:~w: ~s", [F, Line, String])).
+ lists:flatten(io_lib:format("~ts:~w: ~ts", [F, Line, String])).
%%-----------------------------------------------------------------------------
@@ -309,54 +302,55 @@ format_warning({_Tag, {File, Line}, Msg}, FOpt) when is_list(File),
%%----- Warnings for general discrepancies ----------------
message_to_string({apply, [Args, ArgNs, FailReason,
SigArgs, SigRet, Contract]}) ->
- io_lib:format("Fun application with arguments ~s ", [Args]) ++
+ io_lib:format("Fun application with arguments ~ts ", [Args]) ++
call_or_apply_to_string(ArgNs, FailReason, SigArgs, SigRet, Contract);
message_to_string({app_call, [M, F, Args, Culprit, ExpectedType, FoundType]}) ->
- io_lib:format("The call ~s:~s~s requires that ~s is of type ~s not ~s\n",
+ io_lib:format("The call ~s:~ts~ts requires that ~ts is of type ~ts not ~ts\n",
[M, F, Args, Culprit, ExpectedType, FoundType]);
message_to_string({bin_construction, [Culprit, Size, Seg, Type]}) ->
io_lib:format("Binary construction will fail since the ~s field ~s in"
" segment ~s has type ~s\n", [Culprit, Size, Seg, Type]);
message_to_string({call, [M, F, Args, ArgNs, FailReason,
SigArgs, SigRet, Contract]}) ->
- io_lib:format("The call ~w:~w~s ", [M, F, Args]) ++
+ io_lib:format("The call ~w:~tw~ts ", [M, F, Args]) ++
call_or_apply_to_string(ArgNs, FailReason, SigArgs, SigRet, Contract);
message_to_string({call_to_missing, [M, F, A]}) ->
- io_lib:format("Call to missing or unexported function ~w:~w/~w\n", [M, F, A]);
+ io_lib:format("Call to missing or unexported function ~w:~tw/~w\n",
+ [M, F, A]);
message_to_string({exact_eq, [Type1, Op, Type2]}) ->
- io_lib:format("The test ~s ~s ~s can never evaluate to 'true'\n",
+ io_lib:format("The test ~ts ~s ~ts can never evaluate to 'true'\n",
[Type1, Op, Type2]);
message_to_string({fun_app_args, [Args, Type]}) ->
- io_lib:format("Fun application with arguments ~s will fail"
- " since the function has type ~s\n", [Args, Type]);
+ io_lib:format("Fun application with arguments ~ts will fail"
+ " since the function has type ~ts\n", [Args, Type]);
message_to_string({fun_app_no_fun, [Op, Type, Arity]}) ->
- io_lib:format("Fun application will fail since ~s :: ~s"
+ io_lib:format("Fun application will fail since ~ts :: ~ts"
" is not a function of arity ~w\n", [Op, Type, Arity]);
message_to_string({guard_fail, []}) ->
"Clause guard cannot succeed.\n";
message_to_string({guard_fail, [Arg1, Infix, Arg2]}) ->
- io_lib:format("Guard test ~s ~s ~s can never succeed\n", [Arg1, Infix, Arg2]);
+ io_lib:format("Guard test ~ts ~s ~ts can never succeed\n", [Arg1, Infix, Arg2]);
message_to_string({map_update, [Type, Key]}) ->
- io_lib:format("A key of type ~s cannot exist "
- "in a map of type ~s\n", [Key, Type]);
+ io_lib:format("A key of type ~ts cannot exist "
+ "in a map of type ~ts\n", [Key, Type]);
message_to_string({neg_guard_fail, [Arg1, Infix, Arg2]}) ->
- io_lib:format("Guard test not(~s ~s ~s) can never succeed\n",
+ io_lib:format("Guard test not(~ts ~s ~ts) can never succeed\n",
[Arg1, Infix, Arg2]);
message_to_string({guard_fail, [Guard, Args]}) ->
- io_lib:format("Guard test ~w~s can never succeed\n", [Guard, Args]);
+ io_lib:format("Guard test ~w~ts can never succeed\n", [Guard, Args]);
message_to_string({neg_guard_fail, [Guard, Args]}) ->
- io_lib:format("Guard test not(~w~s) can never succeed\n", [Guard, Args]);
+ io_lib:format("Guard test not(~w~ts) can never succeed\n", [Guard, Args]);
message_to_string({guard_fail_pat, [Pat, Type]}) ->
- io_lib:format("Clause guard cannot succeed. The ~s was matched"
- " against the type ~s\n", [Pat, Type]);
+ io_lib:format("Clause guard cannot succeed. The ~ts was matched"
+ " against the type ~ts\n", [Pat, Type]);
message_to_string({improper_list_constr, [TlType]}) ->
io_lib:format("Cons will produce an improper list"
- " since its 2nd argument is ~s\n", [TlType]);
+ " since its 2nd argument is ~ts\n", [TlType]);
message_to_string({no_return, [Type|Name]}) ->
NameString =
case Name of
[] -> "The created fun ";
- [F, A] -> io_lib:format("Function ~w/~w ", [F, A])
+ [F, A] -> io_lib:format("Function ~tw/~w ", [F, A])
end,
case Type of
no_match -> NameString ++ "has no clauses that will ever match\n";
@@ -365,125 +359,129 @@ message_to_string({no_return, [Type|Name]}) ->
both -> NameString ++ "has no local return\n"
end;
message_to_string({record_constr, [RecConstr, FieldDiffs]}) ->
- io_lib:format("Record construction ~s violates the"
- " declared type of field ~s\n", [RecConstr, FieldDiffs]);
+ io_lib:format("Record construction ~ts violates the"
+ " declared type of field ~ts\n", [RecConstr, FieldDiffs]);
message_to_string({record_constr, [Name, Field, Type]}) ->
- io_lib:format("Record construction violates the declared type for #~w{}"
- " since ~s cannot be of type ~s\n", [Name, Field, Type]);
+ io_lib:format("Record construction violates the declared type for #~tw{}"
+ " since ~ts cannot be of type ~ts\n", [Name, Field, Type]);
message_to_string({record_matching, [String, Name]}) ->
- io_lib:format("The ~s violates the"
- " declared type for #~w{}\n", [String, Name]);
+ io_lib:format("The ~ts violates the"
+ " declared type for #~tw{}\n", [String, Name]);
message_to_string({record_match, [Pat, Type]}) ->
- io_lib:format("Matching of ~s tagged with a record name violates the declared"
- " type of ~s\n", [Pat, Type]);
+ io_lib:format("Matching of ~ts tagged with a record name violates"
+ " the declared type of ~ts\n", [Pat, Type]);
message_to_string({pattern_match, [Pat, Type]}) ->
- io_lib:format("The ~s can never match the type ~s\n", [Pat, Type]);
+ io_lib:format("The ~ts can never match the type ~ts\n", [Pat, Type]);
message_to_string({pattern_match_cov, [Pat, Type]}) ->
- io_lib:format("The ~s can never match since previous"
- " clauses completely covered the type ~s\n",
+ io_lib:format("The ~ts can never match since previous"
+ " clauses completely covered the type ~ts\n",
[Pat, Type]);
message_to_string({unmatched_return, [Type]}) ->
- io_lib:format("Expression produces a value of type ~s,"
+ io_lib:format("Expression produces a value of type ~ts,"
" but this value is unmatched\n", [Type]);
message_to_string({unused_fun, [F, A]}) ->
- io_lib:format("Function ~w/~w will never be called\n", [F, A]);
+ io_lib:format("Function ~tw/~w will never be called\n", [F, A]);
%%----- Warnings for specs and contracts -------------------
message_to_string({contract_diff, [M, F, _A, Contract, Sig]}) ->
- io_lib:format("Type specification ~w:~w~s"
- " is not equal to the success typing: ~w:~w~s\n",
+ io_lib:format("Type specification ~w:~tw~ts"
+ " is not equal to the success typing: ~w:~tw~ts\n",
[M, F, Contract, M, F, Sig]);
message_to_string({contract_subtype, [M, F, _A, Contract, Sig]}) ->
- io_lib:format("Type specification ~w:~w~s"
- " is a subtype of the success typing: ~w:~w~s\n",
+ io_lib:format("Type specification ~w:~tw~ts"
+ " is a subtype of the success typing: ~w:~tw~ts\n",
[M, F, Contract, M, F, Sig]);
message_to_string({contract_supertype, [M, F, _A, Contract, Sig]}) ->
- io_lib:format("Type specification ~w:~w~s"
- " is a supertype of the success typing: ~w:~w~s\n",
+ io_lib:format("Type specification ~w:~tw~ts"
+ " is a supertype of the success typing: ~w:~tw~ts\n",
[M, F, Contract, M, F, Sig]);
message_to_string({contract_range, [Contract, M, F, ArgStrings, Line, CRet]}) ->
- io_lib:format("The contract ~w:~w~s cannot be right because the inferred"
- " return for ~w~s on line ~w is ~s\n",
+ io_lib:format("The contract ~w:~tw~ts cannot be right because the inferred"
+ " return for ~tw~ts on line ~w is ~ts\n",
[M, F, Contract, F, ArgStrings, Line, CRet]);
message_to_string({invalid_contract, [M, F, A, Sig]}) ->
- io_lib:format("Invalid type specification for function ~w:~w/~w."
- " The success typing is ~s\n", [M, F, A, Sig]);
+ io_lib:format("Invalid type specification for function ~w:~tw/~w."
+ " The success typing is ~ts\n", [M, F, A, Sig]);
+message_to_string({contract_with_opaque, [M, F, A, OpaqueType, SigType]}) ->
+ io_lib:format("The specification for ~w:~tw/~w"
+ " has an opaque subtype ~ts which is violated by the"
+ " success typing ~ts\n", [M, F, A, OpaqueType, SigType]);
message_to_string({extra_range, [M, F, A, ExtraRanges, SigRange]}) ->
- io_lib:format("The specification for ~w:~w/~w states that the function"
- " might also return ~s but the inferred return is ~s\n",
+ io_lib:format("The specification for ~w:~tw/~w states that the function"
+ " might also return ~ts but the inferred return is ~ts\n",
[M, F, A, ExtraRanges, SigRange]);
message_to_string({overlapping_contract, [M, F, A]}) ->
- io_lib:format("Overloaded contract for ~w:~w/~w has overlapping domains;"
+ io_lib:format("Overloaded contract for ~w:~tw/~w has overlapping domains;"
" such contracts are currently unsupported and are simply ignored\n",
[M, F, A]);
message_to_string({spec_missing_fun, [M, F, A]}) ->
- io_lib:format("Contract for function that does not exist: ~w:~w/~w\n",
+ io_lib:format("Contract for function that does not exist: ~w:~tw/~w\n",
[M, F, A]);
%%----- Warnings for opaque type violations -------------------
message_to_string({call_with_opaque, [M, F, Args, ArgNs, ExpArgs]}) ->
- io_lib:format("The call ~w:~w~s contains ~s when ~s\n",
+ io_lib:format("The call ~w:~tw~ts contains ~ts when ~ts\n",
[M, F, Args, form_positions(ArgNs), form_expected(ExpArgs)]);
message_to_string({call_without_opaque, [M, F, Args, ExpectedTriples]}) ->
- io_lib:format("The call ~w:~w~s does not have ~s\n",
+ io_lib:format("The call ~w:~tw~ts does not have ~ts\n",
[M, F, Args, form_expected_without_opaque(ExpectedTriples)]);
message_to_string({opaque_eq, [Type, _Op, OpaqueType]}) ->
- io_lib:format("Attempt to test for equality between a term of type ~s"
- " and a term of opaque type ~s\n", [Type, OpaqueType]);
+ io_lib:format("Attempt to test for equality between a term of type ~ts"
+ " and a term of opaque type ~ts\n", [Type, OpaqueType]);
message_to_string({opaque_guard, [Arg1, Infix, Arg2, ArgNs]}) ->
- io_lib:format("Guard test ~s ~s ~s contains ~s\n",
+ io_lib:format("Guard test ~ts ~s ~ts contains ~s\n",
[Arg1, Infix, Arg2, form_positions(ArgNs)]);
message_to_string({opaque_guard, [Guard, Args]}) ->
- io_lib:format("Guard test ~w~s breaks the opaqueness of its argument\n",
+ io_lib:format("Guard test ~w~ts breaks the opacity of its argument\n",
[Guard, Args]);
message_to_string({opaque_match, [Pat, OpaqueType, OpaqueTerm]}) ->
Term = if OpaqueType =:= OpaqueTerm -> "the term";
true -> OpaqueTerm
end,
- io_lib:format("The attempt to match a term of type ~s against the ~s"
- " breaks the opaqueness of ~s\n", [OpaqueType, Pat, Term]);
+ io_lib:format("The attempt to match a term of type ~s against the ~ts"
+ " breaks the opacity of ~ts\n", [OpaqueType, Pat, Term]);
message_to_string({opaque_neq, [Type, _Op, OpaqueType]}) ->
- io_lib:format("Attempt to test for inequality between a term of type ~s"
- " and a term of opaque type ~s\n", [Type, OpaqueType]);
+ io_lib:format("Attempt to test for inequality between a term of type ~ts"
+ " and a term of opaque type ~ts\n", [Type, OpaqueType]);
message_to_string({opaque_type_test, [Fun, Args, Arg, ArgType]}) ->
- io_lib:format("The type test ~s~s breaks the opaqueness of the term ~s~s\n",
+ io_lib:format("The type test ~ts~ts breaks the opacity of the term ~ts~ts\n",
[Fun, Args, Arg, ArgType]);
message_to_string({opaque_size, [SizeType, Size]}) ->
- io_lib:format("The size ~s breaks the opaqueness of ~s\n",
+ io_lib:format("The size ~ts breaks the opacity of ~ts\n",
[SizeType, Size]);
message_to_string({opaque_call, [M, F, Args, Culprit, OpaqueType]}) ->
- io_lib:format("The call ~s:~s~s breaks the opaqueness of the term ~s :: ~s\n",
+ io_lib:format("The call ~s:~ts~ts breaks the opacity of the term ~ts :: ~ts\n",
[M, F, Args, Culprit, OpaqueType]);
%%----- Warnings for concurrency errors --------------------
message_to_string({race_condition, [M, F, Args, Reason]}) ->
- io_lib:format("The call ~w:~w~s ~s\n", [M, F, Args, Reason]);
+ io_lib:format("The call ~w:~tw~ts ~ts\n", [M, F, Args, Reason]);
%%----- Warnings for behaviour errors --------------------
message_to_string({callback_type_mismatch, [B, F, A, ST, CT]}) ->
- io_lib:format("The inferred return type of ~w/~w (~s) has nothing in common"
- " with ~s, which is the expected return type for the callback of"
- " ~w behaviour\n", [F, A, ST, CT, B]);
+ io_lib:format("The inferred return type of ~tw/~w (~ts) has nothing in"
+ " common with ~ts, which is the expected return type for"
+ " the callback of the ~w behaviour\n", [F, A, ST, CT, B]);
message_to_string({callback_arg_type_mismatch, [B, F, A, N, ST, CT]}) ->
- io_lib:format("The inferred type for the ~s argument of ~w/~w (~s) is"
- " not a supertype of ~s, which is expected type for this"
+ io_lib:format("The inferred type for the ~s argument of ~tw/~w (~ts) is"
+ " not a supertype of ~ts, which is expected type for this"
" argument in the callback of the ~w behaviour\n",
[ordinal(N), F, A, ST, CT, B]);
message_to_string({callback_spec_type_mismatch, [B, F, A, ST, CT]}) ->
- io_lib:format("The return type ~s in the specification of ~w/~w is not a"
- " subtype of ~s, which is the expected return type for the"
- " callback of ~w behaviour\n", [ST, F, A, CT, B]);
+ io_lib:format("The return type ~ts in the specification of ~tw/~w is not a"
+ " subtype of ~ts, which is the expected return type for the"
+ " callback of the ~w behaviour\n", [ST, F, A, CT, B]);
message_to_string({callback_spec_arg_type_mismatch, [B, F, A, N, ST, CT]}) ->
- io_lib:format("The specified type for the ~s argument of ~w/~w (~s) is"
- " not a supertype of ~s, which is expected type for this"
+ io_lib:format("The specified type for the ~ts argument of ~tw/~w (~ts) is"
+ " not a supertype of ~ts, which is expected type for this"
" argument in the callback of the ~w behaviour\n",
[ordinal(N), F, A, ST, CT, B]);
message_to_string({callback_missing, [B, F, A]}) ->
- io_lib:format("Undefined callback function ~w/~w (behaviour '~w')\n",
+ io_lib:format("Undefined callback function ~tw/~w (behaviour ~w)\n",
[F, A, B]);
message_to_string({callback_info_missing, [B]}) ->
io_lib:format("Callback info about the ~w behaviour is not available\n", [B]);
%%----- Warnings for unknown functions, types, and behaviours -------------
message_to_string({unknown_type, {M, F, A}}) ->
- io_lib:format("Unknown type ~w:~w/~w", [M, F, A]);
+ io_lib:format("Unknown type ~w:~tw/~w", [M, F, A]);
message_to_string({unknown_function, {M, F, A}}) ->
- io_lib:format("Unknown function ~w:~w/~w", [M, F, A]);
+ io_lib:format("Unknown function ~w:~tw/~w", [M, F, A]);
message_to_string({unknown_behaviour, B}) ->
io_lib:format("Unknown behaviour ~w", [B]).
diff --git a/lib/dialyzer/src/dialyzer.hrl b/lib/dialyzer/src/dialyzer.hrl
index ea6a71217c..e7cf2860b7 100644
--- a/lib/dialyzer/src/dialyzer.hrl
+++ b/lib/dialyzer/src/dialyzer.hrl
@@ -1,9 +1,5 @@
%%% This is an -*- Erlang -*- file.
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
%%%
-%%% %CopyrightEnd%
-%%%
%%%-------------------------------------------------------------------
%%% File : dialyzer.hrl
%%% Author : Tobias Lindahl <[email protected]>
diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index 50fc1d8471..a4b42c9367 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%--------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_analysis_callgraph.erl
@@ -99,6 +92,7 @@ loop(#server_state{parent = Parent} = State,
send_warnings(Parent, Warnings),
loop(State, Analysis, ExtCalls);
{AnalPid, cserver, CServer, Plt} ->
+ skip_ets_transfer(AnalPid),
send_codeserver_plt(Parent, CServer, Plt),
loop(State, Analysis, ExtCalls);
{AnalPid, done, Plt, DocPlt} ->
@@ -140,79 +134,120 @@ analysis_start(Parent, Analysis, LegalWarnings) ->
Files = ordsets:from_list(Analysis#analysis.files),
{Callgraph, TmpCServer0} = compile_and_store(Files, State),
%% Remote type postprocessing
- NewCServer =
- try
- NewRecords = dialyzer_codeserver:get_temp_records(TmpCServer0),
- NewExpTypes = dialyzer_codeserver:get_temp_exported_types(TmpCServer0),
- OldRecords = dialyzer_plt:get_types(Plt),
- OldExpTypes0 = dialyzer_plt:get_exported_types(Plt),
- MergedRecords = dialyzer_utils:merge_records(NewRecords, OldRecords),
- RemMods =
- [case Analysis#analysis.start_from of
- byte_code -> list_to_atom(filename:basename(F, ".beam"));
- src_code -> list_to_atom(filename:basename(F, ".erl"))
- end || F <- Files],
- OldExpTypes1 = dialyzer_utils:sets_filter(RemMods, OldExpTypes0),
- MergedExpTypes = sets:union(NewExpTypes, OldExpTypes1),
- TmpCServer1 = dialyzer_codeserver:set_temp_records(MergedRecords, TmpCServer0),
- TmpCServer2 =
- dialyzer_codeserver:finalize_exported_types(MergedExpTypes, TmpCServer1),
- ?timing(State#analysis_state.timing_server, "remote",
- begin
- TmpCServer3 =
- dialyzer_utils:process_record_remote_types(TmpCServer2),
- dialyzer_contracts:process_contract_remote_types(TmpCServer3)
- end)
- catch
- throw:{error, _ErrorMsg} = Error -> exit(Error)
- end,
- NewPlt0 = dialyzer_plt:insert_types(Plt, dialyzer_codeserver:get_records(NewCServer)),
- ExpTypes = dialyzer_codeserver:get_exported_types(NewCServer),
- NewPlt1 = dialyzer_plt:insert_exported_types(NewPlt0, ExpTypes),
- State0 = State#analysis_state{plt = NewPlt1},
- dump_callgraph(Callgraph, State0, Analysis),
- State1 = State0#analysis_state{codeserver = NewCServer},
+ Args = {Plt, Analysis, Parent},
+ NewCServer = remote_type_postprocessing(TmpCServer0, Args),
+ dump_callgraph(Callgraph, State, Analysis),
%% Remove all old versions of the files being analyzed
AllNodes = dialyzer_callgraph:all_nodes(Callgraph),
- Plt1 = dialyzer_plt:delete_list(NewPlt1, AllNodes),
+ Plt1_a = dialyzer_plt:delete_list(Plt, AllNodes),
+ Plt1 = dialyzer_plt:insert_callbacks(Plt1_a, NewCServer),
+ State1 = State#analysis_state{codeserver = NewCServer, plt = Plt1},
Exports = dialyzer_codeserver:get_exports(NewCServer),
+ NonExports = sets:subtract(sets:from_list(AllNodes), Exports),
+ NonExportsList = sets:to_list(NonExports),
NewCallgraph =
case Analysis#analysis.race_detection of
true -> dialyzer_callgraph:put_race_detection(true, Callgraph);
false -> Callgraph
end,
- State2 = analyze_callgraph(NewCallgraph, State1#analysis_state{plt = Plt1}),
+ State2 = analyze_callgraph(NewCallgraph, State1),
+ #analysis_state{plt = Plt2,
+ doc_plt = DocPlt,
+ codeserver = Codeserver0} = State2,
+ {Codeserver, Plt3} = move_data(Codeserver0, Plt2),
dialyzer_callgraph:dispose_race_server(NewCallgraph),
- rcv_and_send_ext_types(Parent),
- NonExports = sets:subtract(sets:from_list(AllNodes), Exports),
- NonExportsList = sets:to_list(NonExports),
- Plt2 = dialyzer_plt:delete_list(State2#analysis_state.plt, NonExportsList),
- send_codeserver_plt(Parent, CServer, State2#analysis_state.plt),
- send_analysis_done(Parent, Plt2, State2#analysis_state.doc_plt).
+ %% Since the PLT is never used, a dummy is sent:
+ DummyPlt = dialyzer_plt:new(),
+ send_codeserver_plt(Parent, Codeserver, DummyPlt),
+ dialyzer_plt:delete(DummyPlt),
+ Plt4 = dialyzer_plt:delete_list(Plt3, NonExportsList),
+ send_analysis_done(Parent, Plt4, DocPlt).
+
+remote_type_postprocessing(TmpCServer, Args) ->
+ Fun = fun() ->
+ exit(remote_type_postproc(TmpCServer, Args))
+ end,
+ {Pid, Ref} = erlang:spawn_monitor(Fun),
+ dialyzer_codeserver:give_away(TmpCServer, Pid),
+ Pid ! {self(), go},
+ receive {'DOWN', Ref, process, Pid, Return} ->
+ skip_ets_transfer(Pid),
+ case Return of
+ {error, _ErrorMsg} = Error -> exit(Error);
+ _ -> Return
+ end
+ end.
+
+remote_type_postproc(TmpCServer0, Args) ->
+ {Plt, Analysis, Parent} = Args,
+ fun() ->
+ Caller = receive {Pid, go} -> Pid end,
+ TmpCServer1 = dialyzer_utils:merge_types(TmpCServer0, Plt),
+ NewExpTypes = dialyzer_codeserver:get_temp_exported_types(TmpCServer0),
+ OldExpTypes0 = dialyzer_plt:get_exported_types(Plt),
+ #analysis{start_from = StartFrom,
+ timing_server = TimingServer} = Analysis,
+ Files = ordsets:from_list(Analysis#analysis.files),
+ RemMods =
+ [case StartFrom of
+ byte_code -> list_to_atom(filename:basename(F, ".beam"));
+ src_code -> list_to_atom(filename:basename(F, ".erl"))
+ end || F <- Files],
+ OldExpTypes1 = dialyzer_utils:sets_filter(RemMods, OldExpTypes0),
+ MergedExpTypes = sets:union(NewExpTypes, OldExpTypes1),
+ TmpCServer2 =
+ dialyzer_codeserver:finalize_exported_types(MergedExpTypes,
+ TmpCServer1),
+ TmpServer4 =
+ ?timing
+ (TimingServer, "remote",
+ begin
+ TmpCServer3 =
+ dialyzer_utils:process_record_remote_types(TmpCServer2),
+ dialyzer_contracts:process_contract_remote_types(TmpCServer3)
+ end),
+ rcv_and_send_ext_types(Caller, Parent),
+ dialyzer_codeserver:give_away(TmpServer4, Caller),
+ TmpServer4
+ end().
+
+skip_ets_transfer(Pid) ->
+ receive
+ {'ETS-TRANSFER', _Tid, Pid, _HeriData} ->
+ skip_ets_transfer(Pid)
+ after 0 ->
+ ok
+ end.
+
+move_data(CServer, Plt) ->
+ {CServer1, Records} = dialyzer_codeserver:extract_records(CServer),
+ Plt1 = dialyzer_plt:insert_types(Plt, Records),
+ {NewCServer, ExpTypes} = dialyzer_codeserver:extract_exported_types(CServer1),
+ NewPlt = dialyzer_plt:insert_exported_types(Plt1, ExpTypes),
+ {NewCServer, NewPlt}.
analyze_callgraph(Callgraph, #analysis_state{codeserver = Codeserver,
doc_plt = DocPlt,
+ plt = Plt,
timing_server = TimingServer,
parent = Parent,
solvers = Solvers} = State) ->
- Plt = dialyzer_plt:insert_callbacks(State#analysis_state.plt, Codeserver),
- {NewPlt, NewDocPlt} =
- case State#analysis_state.analysis_type of
- plt_build ->
- NewPlt0 =
- dialyzer_succ_typings:analyze_callgraph(Callgraph, Plt, Codeserver,
- TimingServer, Solvers, Parent),
- {NewPlt0, DocPlt};
- succ_typings ->
- {Warnings, NewPlt0, NewDocPlt0} =
- dialyzer_succ_typings:get_warnings(Callgraph, Plt, DocPlt, Codeserver,
- TimingServer, Solvers, Parent),
- Warnings1 = filter_warnings(Warnings, Codeserver),
- send_warnings(State#analysis_state.parent, Warnings1),
- {NewPlt0, NewDocPlt0}
- end,
- dialyzer_callgraph:delete(Callgraph),
- State#analysis_state{plt = NewPlt, doc_plt = NewDocPlt}.
+ case State#analysis_state.analysis_type of
+ plt_build ->
+ NewPlt =
+ dialyzer_succ_typings:analyze_callgraph(Callgraph, Plt, Codeserver,
+ TimingServer, Solvers, Parent),
+ dialyzer_callgraph:delete(Callgraph),
+ State#analysis_state{plt = NewPlt, doc_plt = DocPlt};
+ succ_typings ->
+ {Warnings, NewPlt, NewDocPlt} =
+ dialyzer_succ_typings:get_warnings(Callgraph, Plt, DocPlt, Codeserver,
+ TimingServer, Solvers, Parent),
+ dialyzer_callgraph:delete(Callgraph),
+ Warnings1 = filter_warnings(Warnings, Codeserver),
+ send_warnings(State#analysis_state.parent, Warnings1),
+ State#analysis_state{plt = NewPlt, doc_plt = NewDocPlt}
+ end.
%%--------------------------------------------------------------------
%% Build the callgraph and fill the codeserver.
@@ -269,7 +304,7 @@ compile_and_store(Files, #analysis_state{codeserver = CServer,
dict:new(), Files),
check_for_duplicate_modules(ModDict);
false ->
- Msg = io_lib:format("Could not scan the following file(s):~n~s",
+ Msg = io_lib:format("Could not scan the following file(s):~n~ts",
[[Reason || {_Filename, Reason} <- Failed]]),
exit({error, Msg})
end,
@@ -367,64 +402,46 @@ compile_src(File, Includes, Defines, Callgraph, CServer, UseContracts,
DefaultIncludes = default_includes(filename:dirname(File)),
SrcCompOpts = dialyzer_utils:src_compiler_opts(),
CompOpts = SrcCompOpts ++ Includes ++ Defines ++ DefaultIncludes,
- case dialyzer_utils:get_abstract_code_from_src(File, CompOpts) of
+ case dialyzer_utils:get_core_from_src(File, CompOpts) of
{error, _Msg} = Error -> Error;
- {ok, AbstrCode} ->
- compile_common(File, AbstrCode, CompOpts, Callgraph, CServer,
- UseContracts, LegalWarnings)
+ {ok, Core} ->
+ compile_common(Core, Callgraph, CServer, UseContracts, LegalWarnings)
end.
compile_byte(File, Callgraph, CServer, UseContracts, LegalWarnings) ->
- case dialyzer_utils:get_abstract_code_from_beam(File) of
- error ->
- {error, " Could not get abstract code for: " ++ File ++ "\n" ++
- " Recompile with +debug_info or analyze starting from source code"};
- {ok, AbstrCode} ->
- compile_byte(File, AbstrCode, Callgraph, CServer, UseContracts,
- LegalWarnings)
- end.
-
-compile_byte(File, AbstrCode, Callgraph, CServer, UseContracts,
- LegalWarnings) ->
- case dialyzer_utils:get_compile_options_from_beam(File) of
- error ->
- {error, " Could not get compile options for: " ++ File ++ "\n" ++
- " Recompile or analyze starting from source code"};
- {ok, CompOpts} ->
- compile_common(File, AbstrCode, CompOpts, Callgraph, CServer,
- UseContracts, LegalWarnings)
+ case dialyzer_utils:get_core_from_beam(File) of
+ {error, _} = Error -> Error;
+ {ok, Core} ->
+ compile_common(Core, Callgraph, CServer, UseContracts, LegalWarnings)
end.
-compile_common(File, AbstrCode, CompOpts, Callgraph, CServer,
- UseContracts, LegalWarnings) ->
- case dialyzer_utils:get_core_from_abstract_code(AbstrCode, CompOpts) of
- error -> {error, " Could not get core Erlang code for: " ++ File};
- {ok, Core} ->
- Mod = cerl:concrete(cerl:module_name(Core)),
- case dialyzer_utils:get_record_and_type_info(AbstrCode) of
+compile_common(Core, Callgraph, CServer, UseContracts, LegalWarnings) ->
+ Mod = cerl:concrete(cerl:module_name(Core)),
+ case dialyzer_utils:get_record_and_type_info(Core) of
+ {error, _} = Error -> Error;
+ {ok, RecInfo} ->
+ CServer1 =
+ dialyzer_codeserver:store_temp_records(Mod, RecInfo, CServer),
+ case dialyzer_utils:get_fun_meta_info(Mod, Core, LegalWarnings) of
{error, _} = Error -> Error;
- {ok, RecInfo} ->
- CServer1 =
- dialyzer_codeserver:store_temp_records(Mod, RecInfo, CServer),
- MetaFunInfo =
- dialyzer_utils:get_fun_meta_info(Mod, AbstrCode, LegalWarnings),
- CServer2 =
- dialyzer_codeserver:insert_fun_meta_info(MetaFunInfo, CServer1),
+ MetaFunInfo ->
+ CServer2 =
+ dialyzer_codeserver:insert_fun_meta_info(MetaFunInfo, CServer1),
case UseContracts of
true ->
- case dialyzer_utils:get_spec_info(Mod, AbstrCode, RecInfo) of
- {error, _} = Error -> Error;
- {ok, SpecInfo, CallbackInfo} ->
- CServer3 =
- dialyzer_codeserver:store_temp_contracts(Mod, SpecInfo,
- CallbackInfo,
- CServer2),
- store_core(Mod, Core, Callgraph, CServer3)
+ case dialyzer_utils:get_spec_info(Mod, Core, RecInfo) of
+ {error, _} = Error -> Error;
+ {ok, SpecInfo, CallbackInfo} ->
+ CServer3 =
+ dialyzer_codeserver:store_temp_contracts(Mod, SpecInfo,
+ CallbackInfo,
+ CServer2),
+ store_core(Mod, Core, Callgraph, CServer3)
end;
false ->
store_core(Mod, Core, Callgraph, CServer2)
- end
end
+ end
end.
store_core(Mod, Core, Callgraph, CServer) ->
@@ -525,13 +542,13 @@ default_includes(Dir) ->
%% Handle Messages
%%-------------------------------------------------------------------
-rcv_and_send_ext_types(Parent) ->
+rcv_and_send_ext_types(SendTo, Parent) ->
Self = self(),
Self ! {Self, done},
case rcv_ext_types(Self, []) of
[] -> ok;
ExtTypes ->
- Parent ! {Self, ext_types, ExtTypes},
+ Parent ! {SendTo, ext_types, ExtTypes},
ok
end.
@@ -579,7 +596,8 @@ send_ext_types(Parent, ExtTypes) ->
Parent ! {self(), ext_types, ExtTypes},
ok.
-send_codeserver_plt(Parent, CServer, Plt ) ->
+send_codeserver_plt(Parent, CServer, Plt) ->
+ ok = dialyzer_codeserver:give_away(CServer, Parent),
Parent ! {self(), cserver, CServer, Plt},
ok.
@@ -598,14 +616,14 @@ format_bad_calls([{{_, _, _}, {_, module_info, A}}|Left], CodeServer, Acc)
format_bad_calls([{FromMFA, {M, F, A} = To}|Left], CodeServer, Acc) ->
{_Var, FunCode} = dialyzer_codeserver:lookup_mfa_code(FromMFA, CodeServer),
Msg = {call_to_missing, [M, F, A]},
- {File, Line} = find_call_file_and_line(FunCode, To),
+ {File, Line} = find_call_file_and_line(FromMFA, FunCode, To, CodeServer),
WarningInfo = {File, Line, FromMFA},
NewAcc = [{?WARN_CALLGRAPH, WarningInfo, Msg}|Acc],
format_bad_calls(Left, CodeServer, NewAcc);
format_bad_calls([], _CodeServer, Acc) ->
Acc.
-find_call_file_and_line(Tree, MFA) ->
+find_call_file_and_line({Module, _, _}, Tree, MFA, CodeServer) ->
Fun =
fun(SubTree, Acc) ->
case cerl:is_c_call(SubTree) of
@@ -618,7 +636,7 @@ find_call_file_and_line(Tree, MFA) ->
case {cerl:concrete(M), cerl:concrete(F), A} of
MFA ->
Ann = cerl:get_ann(SubTree),
- [{get_file(Ann), get_line(Ann)}|Acc];
+ [{get_file(CodeServer, Module, Ann), get_line(Ann)}|Acc];
{erlang, make_fun, 3} ->
[CA1, CA2, CA3] = cerl:call_args(SubTree),
case
@@ -634,7 +652,8 @@ find_call_file_and_line(Tree, MFA) ->
of
MFA ->
Ann = cerl:get_ann(SubTree),
- [{get_file(Ann), get_line(Ann)}|Acc];
+ [{get_file(CodeServer, Module, Ann),
+ get_line(Ann)}|Acc];
_ ->
Acc
end;
@@ -654,8 +673,10 @@ get_line([Line|_]) when is_integer(Line) -> Line;
get_line([_|Tail]) -> get_line(Tail);
get_line([]) -> -1.
-get_file([{file, File}|_]) -> File;
-get_file([_|Tail]) -> get_file(Tail).
+get_file(Codeserver, Module, [{file, FakeFile}|_]) ->
+ dialyzer_codeserver:translate_fake_file(Codeserver, Module, FakeFile);
+get_file(Codeserver, Module, [_|Tail]) ->
+ get_file(Codeserver, Module, Tail).
-spec dump_callgraph(dialyzer_callgraph:callgraph(), #analysis_state{}, #analysis{}) ->
'ok'.
@@ -678,12 +699,13 @@ dump_callgraph(CallGraph, _State, #analysis{callgraph_file = File}, ".ps") ->
Args = "-Gratio=compress -Gsize=\"100,100\"",
dialyzer_callgraph:to_ps(CallGraph, File, Args);
dump_callgraph(CallGraph, State, #analysis{callgraph_file = File}, _Ext) ->
+ %% TODO: write the graph, not the ETS table identifiers.
case file:open(File, [write]) of
{ok, Fd} ->
io:format(Fd, "~p", [CallGraph]),
ok = file:close(Fd);
{error, Reason} ->
- Msg = io_lib:format("Could not open output file ~p, Reason: ~p\n",
+ Msg = io_lib:format("Could not open output file ~tp, Reason: ~p\n",
[File, Reason]),
send_log(State#analysis_state.parent, Msg)
end.
diff --git a/lib/dialyzer/src/dialyzer_behaviours.erl b/lib/dialyzer/src/dialyzer_behaviours.erl
index 5623929a43..d380ab2a50 100644
--- a/lib/dialyzer/src/dialyzer_behaviours.erl
+++ b/lib/dialyzer/src/dialyzer_behaviours.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_behaviours.erl
@@ -62,9 +55,9 @@ check_callbacks(Module, Attrs, Records, Plt, Codeserver) ->
_ ->
MFA = {Module,module_info,0},
{_Var,Code} = dialyzer_codeserver:lookup_mfa_code(MFA, Codeserver),
- File = get_file(cerl:get_ann(Code)),
+ File = get_file(Codeserver, Module, cerl:get_ann(Code)),
State = #state{plt = Plt, filename = File, behlines = BehLines,
- codeserver = Codeserver, records = Records},
+ codeserver = Codeserver, records = Records},
Warnings = get_warnings(Module, Behaviours, State),
[add_tag_warning_info(Module, W, State) || W <- Warnings]
end.
@@ -213,12 +206,15 @@ add_tag_warning_info(Module, {_Tag, [_B, Fun, Arity|_R]} = Warn, State) ->
dialyzer_codeserver:lookup_mfa_code({Module, Fun, Arity},
State#state.codeserver),
Anns = cerl:get_ann(FunCode),
- WarningInfo = {get_file(Anns), get_line(Anns), {Module, Fun, Arity}},
+ File = get_file(State#state.codeserver, Module, Anns),
+ WarningInfo = {File, get_line(Anns), {Module, Fun, Arity}},
{?WARN_BEHAVIOUR, WarningInfo, Warn}.
get_line([Line|_]) when is_integer(Line) -> Line;
get_line([_|Tail]) -> get_line(Tail);
get_line([]) -> -1.
-get_file([{file, File}|_]) -> File;
-get_file([_|Tail]) -> get_file(Tail).
+get_file(Codeserver, Module, [{file, FakeFile}|_]) ->
+ dialyzer_codeserver:translate_fake_file(Codeserver, Module, FakeFile);
+get_file(Codeserver, Module, [_|Tail]) ->
+ get_file(Codeserver, Module, Tail).
diff --git a/lib/dialyzer/src/dialyzer_callgraph.erl b/lib/dialyzer/src/dialyzer_callgraph.erl
index 50abb22009..7411b1d28b 100644
--- a/lib/dialyzer/src/dialyzer_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_callgraph.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_callgraph.erl
@@ -47,7 +40,7 @@
module_postorder_from_funs/2,
new/0,
get_depends_on/2,
- get_required_by/2,
+ %% get_required_by/2,
in_neighbours/2,
renew_race_info/4,
renew_race_code/2,
@@ -119,7 +112,11 @@
-opaque callgraph() :: #callgraph{}.
--type active_digraph() :: {'d', digraph:graph()} | {'e', ets:tid(), ets:tid()}.
+-type active_digraph() :: {'d', digraph:graph()}
+ | {'e',
+ Out :: ets:tid(),
+ In :: ets:tid(),
+ Map :: ets:tid()}.
%%----------------------------------------------------------------------
@@ -248,23 +245,29 @@ find_non_local_calls([], Set) ->
-spec get_depends_on(scc() | module(), callgraph()) -> [scc()].
-get_depends_on(SCC, #callgraph{active_digraph = {'e', Out, _In}}) ->
- case ets_lookup_dict(SCC, Out) of
- {ok, Value} -> Value;
- error -> []
- end;
+get_depends_on(SCC, #callgraph{active_digraph = {'e', Out, _In, Maps}}) ->
+ lookup_scc(SCC, Out, Maps);
get_depends_on(SCC, #callgraph{active_digraph = {'d', DG}}) ->
digraph:out_neighbours(DG, SCC).
--spec get_required_by(scc() | module(), callgraph()) -> [scc()].
-
-get_required_by(SCC, #callgraph{active_digraph = {'e', _Out, In}}) ->
- case ets_lookup_dict(SCC, In) of
- {ok, Value} -> Value;
+%% -spec get_required_by(scc() | module(), callgraph()) -> [scc()].
+
+%% get_required_by(SCC, #callgraph{active_digraph = {'e', _Out, In, Maps}}) ->
+%% lookup_scc(SCC, In, Maps);
+%% get_required_by(SCC, #callgraph{active_digraph = {'d', DG}}) ->
+%% digraph:in_neighbours(DG, SCC).
+
+lookup_scc(SCC, Table, Maps) ->
+ case ets_lookup_dict({'scc', SCC}, Maps) of
+ {ok, SCCInt} ->
+ case ets_lookup_dict(SCCInt, Table) of
+ {ok, Ints} ->
+ [ets:lookup_element(Maps, Int, 2) || Int <- Ints];
+ error ->
+ []
+ end;
error -> []
- end;
-get_required_by(SCC, #callgraph{active_digraph = {'d', DG}}) ->
- digraph:in_neighbours(DG, SCC).
+ end.
%%----------------------------------------------------------------------
%% Handling of modules & SCCs
@@ -282,9 +285,11 @@ module_postorder(#callgraph{digraph = DG}) ->
Nodes = sets:from_list([M || {M,_F,_A} <- digraph_vertices(DG)]),
MDG = digraph:new([acyclic]),
digraph_confirm_vertices(sets:to_list(Nodes), MDG),
- Foreach = fun({M1,M2}) -> digraph:add_edge(MDG, M1, M2) end,
+ Foreach = fun({M1,M2}) -> _ = digraph:add_edge(MDG, M1, M2) end,
lists:foreach(Foreach, sets:to_list(Edges)),
- {digraph_utils:topsort(MDG), {'d', MDG}}.
+ %% The out-neighbors of a vertex are the vertices called directly.
+ %% The used vertices are to occur *before* the calling vertex:
+ {lists:reverse(digraph_utils:topsort(MDG)), {'d', MDG}}.
edge_fold({{M1,_,_},{M2,_,_}}, Set) ->
case M1 =/= M2 of
@@ -302,7 +307,7 @@ module_deps(#callgraph{digraph = DG}) ->
Nodes = sets:from_list([M || {M,_F,_A} <- digraph_vertices(DG)]),
MDG = digraph:new(),
digraph_confirm_vertices(sets:to_list(Nodes), MDG),
- Foreach = fun({M1,M2}) -> digraph:add_edge(MDG, M1, M2) end,
+ Foreach = fun({M1,M2}) -> check_add_edge(MDG, M1, M2) end,
lists:foreach(Foreach, sets:to_list(Edges)),
Deps = [{N, ordsets:from_list(digraph:in_neighbours(MDG, N))}
|| N <- sets:to_list(Nodes)],
@@ -360,7 +365,7 @@ ets_lookup_set(Key, Table) ->
%% The core tree must be labeled as by cerl_trees:label/1 (or /2).
%% The set of labels in the tree must be disjoint from the set of
-%% labels already occuring in the callgraph.
+%% labels already occurring in the callgraph.
-spec scan_core_tree(cerl:c_module(), callgraph()) ->
{[mfa_or_funlbl()], [callgraph_edge()]}.
@@ -549,9 +554,21 @@ digraph_add_edge(From, To, DG) ->
false -> digraph:add_vertex(DG, To);
{To, _} -> ok
end,
- digraph:add_edge(DG, {From, To}, From, To, []),
+ check_add_edge(DG, {From, To}, From, To, []),
ok.
+check_add_edge(G, V1, V2) ->
+ case digraph:add_edge(G, V1, V2) of
+ {error, Error} -> exit({add_edge, V1, V2, Error});
+ _Edge -> ok
+ end.
+
+check_add_edge(G, E, V1, V2, L) ->
+ case digraph:add_edge(G, E, V1, V2, L) of
+ {error, Error} -> exit({add_edge, E, V1, V2, L, Error});
+ _Edge -> ok
+ end.
+
digraph_confirm_vertices([MFA|Left], DG) ->
digraph:add_vertex(DG, MFA, confirmed),
digraph_confirm_vertices(Left, DG);
@@ -582,9 +599,10 @@ digraph_delete(DG) ->
active_digraph_delete({'d', DG}) ->
digraph:delete(DG);
-active_digraph_delete({'e', Out, In}) ->
+active_digraph_delete({'e', Out, In, Maps}) ->
ets:delete(Out),
- ets:delete(In).
+ ets:delete(In),
+ ets:delete(Maps).
digraph_edges(DG) ->
digraph:edges(DG).
@@ -737,6 +755,7 @@ put_behaviour_api_calls(Calls,
-spec to_dot(callgraph(), file:filename()) -> 'ok'.
to_dot(#callgraph{digraph = DG, esc = Esc} = CG, File) ->
+ %% TODO: handle Unicode names.
Fun = fun(L) ->
case lookup_name(L, CG) of
error -> L;
@@ -751,44 +770,60 @@ to_dot(#callgraph{digraph = DG, esc = Esc} = CG, File) ->
-spec to_ps(callgraph(), file:filename(), string()) -> 'ok'.
to_ps(#callgraph{} = CG, File, Args) ->
+ %% TODO: handle Unicode names.
Dot_File = filename:rootname(File) ++ ".dot",
to_dot(CG, Dot_File),
- Command = io_lib:format("dot -Tps ~s -o ~s ~s", [Args, File, Dot_File]),
+ Command = io_lib:format("dot -Tps ~ts -o ~ts ~ts", [Args, File, Dot_File]),
_ = os:cmd(Command),
ok.
condensation(G) ->
- SCs = digraph_utils:strong_components(G),
- V2I = ets:new(condensation_v2i, []),
- I2C = ets:new(condensation_i2c, []),
- I2I = ets:new(condensation_i2i, [bag]),
- CFun =
- fun(SC, N) ->
- lists:foreach(fun(V) -> true = ets:insert(V2I, {V,N}) end, SC),
- true = ets:insert(I2C, {N, SC}),
- N + 1
- end,
- lists:foldl(CFun, 1, SCs),
- Fun1 =
- fun({V1, V2}) ->
- I1 = ets:lookup_element(V2I, V1, 2),
- I2 = ets:lookup_element(V2I, V2, 2),
- I1 =:= I2 orelse ets:insert(I2I, {I1, I2})
- end,
- lists:foreach(Fun1, digraph:edges(G)),
- Fun3 =
- fun({I1, I2}, {Out, In}) ->
- SC1 = ets:lookup_element(I2C, I1, 2),
- SC2 = ets:lookup_element(I2C, I2, 2),
- {dict:append(SC1, SC2, Out), dict:append(SC2, SC1, In)}
- end,
- {OutDict, InDict} = ets:foldl(Fun3, {dict:new(), dict:new()}, I2I),
- [OutETS, InETS] =
- [ets:new(Name,[{read_concurrency, true}]) ||
- Name <- [callgraph_deps_out, callgraph_deps_in]],
- ets:insert(OutETS, dict:to_list(OutDict)),
- ets:insert(InETS, dict:to_list(InDict)),
- ets:delete(V2I),
- ets:delete(I2C),
- ets:delete(I2I),
- {{'e', OutETS, InETS}, SCs}.
+ {Pid, Ref} = erlang:spawn_monitor(do_condensation(G, self())),
+ receive {'DOWN', Ref, process, Pid, Result} ->
+ {SCCInts, OutETS, InETS, MapsETS} = Result,
+ NewSCCs = [ets:lookup_element(MapsETS, SCCInt, 2) || SCCInt <- SCCInts],
+ {{'e', OutETS, InETS, MapsETS}, NewSCCs}
+ end.
+
+-spec do_condensation(digraph:graph(), pid()) -> fun(() -> no_return()).
+
+do_condensation(G, Parent) ->
+ fun() ->
+ [OutETS, InETS, MapsETS] =
+ [ets:new(Name,[{read_concurrency, true}]) ||
+ Name <- [callgraph_deps_out, callgraph_deps_in, callgraph_scc_map]],
+ SCCs = digraph_utils:strong_components(G),
+ %% Assign unique numbers to SCCs:
+ Ints = lists:seq(1, length(SCCs)),
+ IntToSCC = lists:zip(Ints, SCCs),
+ IntScc = sofs:relation(IntToSCC, [{int, scc}]),
+ %% Create mapping from unique integers to SCCs:
+ ets:insert(MapsETS, IntToSCC),
+ %% Subsitute strong components for vertices in edges using the
+ %% unique numbers:
+ C2V = sofs:relation([{SC, V} || SC <- SCCs, V <- SC], [{scc, v}]),
+ I2V = sofs:relative_product(IntScc, C2V), % [{v, int}]
+ Es = sofs:relation(digraph:edges(G), [{v, v}]),
+ R1 = sofs:relative_product(I2V, Es),
+ R2 = sofs:relative_product(I2V, sofs:converse(R1)),
+ R2Strict = sofs:strict_relation(R2),
+ %% Create out-neighbours:
+ Out = sofs:relation_to_family(sofs:converse(R2Strict)),
+ ets:insert(OutETS, sofs:to_external(Out)),
+ %% Sort the SCCs topologically:
+ DG = sofs:family_to_digraph(Out),
+ lists:foreach(fun(I) -> digraph:add_vertex(DG, I) end, Ints),
+ SCCInts0 = digraph_utils:topsort(DG),
+ digraph:delete(DG),
+ %% The out-neighbors of a vertex are the vertices called directly.
+ %% The used vertices are to occur *before* the calling vertex:
+ SCCInts = lists:reverse(SCCInts0),
+ %% Create in-neighbours:
+ In = sofs:relation_to_family(R2Strict),
+ ets:insert(InETS, sofs:to_external(In)),
+ %% Create mapping from SCCs to unique integers:
+ ets:insert(MapsETS, lists:zip([{'scc', SCC} || SCC<- SCCs], Ints)),
+ lists:foreach(fun(E) -> true = ets:give_away(E, Parent, any)
+ end, [OutETS, InETS, MapsETS]),
+ exit({SCCInts, OutETS, InETS, MapsETS})
+ end.
diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl
index fc56693ea3..0617be6435 100644
--- a/lib/dialyzer/src/dialyzer_cl.erl
+++ b/lib/dialyzer/src/dialyzer_cl.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_cl.erl
@@ -37,6 +30,8 @@
-record(cl_state,
{backend_pid :: pid() | 'undefined',
+ code_server = none :: 'none'
+ | dialyzer_codeserver:codeserver(),
erlang_mode = false :: boolean(),
external_calls = [] :: [mfa()],
external_types = [] :: [mfa()],
@@ -82,7 +77,7 @@ init_opts_for_build(Opts) ->
[] -> Opts#options{output_plt = get_default_output_plt()};
[Plt] -> Opts#options{init_plts = [], output_plt = Plt};
Plts ->
- Msg = io_lib:format("Could not build multiple PLT files: ~s\n",
+ Msg = io_lib:format("Could not build multiple PLT files: ~ts\n",
[format_plts(Plts)]),
cl_error(Msg)
end;
@@ -104,7 +99,7 @@ init_opts_for_add(Opts) ->
init_plts = get_default_init_plt()};
[Plt] -> Opts#options{output_plt = Plt};
Plts ->
- Msg = io_lib:format("Could not add to multiple PLT files: ~s\n",
+ Msg = io_lib:format("Could not add to multiple PLT files: ~ts\n",
[format_plts(Plts)]),
cl_error(Msg)
end;
@@ -170,7 +165,7 @@ init_opts_for_remove(Opts) ->
init_plts = get_default_init_plt()};
[Plt] -> Opts#options{output_plt = Plt};
Plts ->
- Msg = io_lib:format("Could not remove from multiple PLT files: ~s\n",
+ Msg = io_lib:format("Could not remove from multiple PLT files: ~ts\n",
[format_plts(Plts)]),
cl_error(Msg)
end;
@@ -217,19 +212,19 @@ plt_common(#options{init_plts = [InitPlt]} = Opts, RemoveFiles, AddFiles) ->
do_analysis(AnalFiles, Opts, Plt, {Md5, ModDeps1})
end;
{error, no_such_file} ->
- Msg = io_lib:format("Could not find the PLT: ~s\n~s",
+ Msg = io_lib:format("Could not find the PLT: ~ts\n~s",
[InitPlt, default_plt_error_msg()]),
cl_error(Msg);
{error, not_valid} ->
- Msg = io_lib:format("The file: ~s is not a valid PLT file\n~s",
+ Msg = io_lib:format("The file: ~ts is not a valid PLT file\n~s",
[InitPlt, default_plt_error_msg()]),
cl_error(Msg);
{error, read_error} ->
- Msg = io_lib:format("Could not read the PLT: ~s\n~s",
+ Msg = io_lib:format("Could not read the PLT: ~ts\n~s",
[InitPlt, default_plt_error_msg()]),
cl_error(Msg);
{error, {no_file_to_remove, F}} ->
- Msg = io_lib:format("Could not remove the file ~s from the PLT: ~s\n",
+ Msg = io_lib:format("Could not remove the file ~ts from the PLT: ~ts\n",
[F, InitPlt]),
cl_error(Msg)
end.
@@ -269,7 +264,7 @@ report_check(#options{report_mode = ReportMode, init_plts = [InitPlt]}) ->
case ReportMode of
quiet -> ok;
_ ->
- io:format(" Checking whether the PLT ~s is up-to-date...", [InitPlt])
+ io:format(" Checking whether the PLT ~ts is up-to-date...", [InitPlt])
end.
report_old_version(#options{report_mode = ReportMode, init_plts = [InitPlt]}) ->
@@ -277,7 +272,7 @@ report_old_version(#options{report_mode = ReportMode, init_plts = [InitPlt]}) ->
quiet -> ok;
_ ->
io:put_chars(" no\n"),
- io:format(" (the PLT ~s was built with an old version of Dialyzer)\n",
+ io:format(" (the PLT ~ts was built with an old version of Dialyzer)\n",
[InitPlt])
end.
@@ -305,19 +300,19 @@ report_analysis_start(#options{analysis_type = Type,
plt_add ->
[InitPlt] = InitPlts,
case InitPlt =:= OutputPlt of
- true -> io:format("Adding information to ~s...", [OutputPlt]);
- false -> io:format("Adding information from ~s to ~s...",
+ true -> io:format("Adding information to ~ts...", [OutputPlt]);
+ false -> io:format("Adding information from ~ts to ~ts...",
[InitPlt, OutputPlt])
end;
plt_build ->
- io:format("Creating PLT ~s ...", [OutputPlt]);
+ io:format("Creating PLT ~ts ...", [OutputPlt]);
plt_check ->
- io:format("Rebuilding the information in ~s...", [OutputPlt]);
+ io:format("Rebuilding the information in ~ts...", [OutputPlt]);
plt_remove ->
[InitPlt] = InitPlts,
case InitPlt =:= OutputPlt of
- true -> io:format("Removing information from ~s...", [OutputPlt]);
- false -> io:format("Removing information from ~s to ~s...",
+ true -> io:format("Removing information from ~ts...", [OutputPlt]);
+ false -> io:format("Removing information from ~ts to ~ts...",
[InitPlt, OutputPlt])
end;
succ_typings -> io:format("Proceeding with analysis...")
@@ -425,7 +420,7 @@ assert_writable(PltFile) ->
case check_if_writable(PltFile) of
true -> ok;
false ->
- Msg = io_lib:format(" The PLT file ~s is not writable", [PltFile]),
+ Msg = io_lib:format(" The PLT file ~ts is not writable", [PltFile]),
cl_error(Msg)
end.
@@ -601,9 +596,11 @@ init_output(State0, #options{output_file = OutFile,
false ->
case file:open(OutFile, [write]) of
{ok, File} ->
+ %% Warnings and errors can include Unicode characters.
+ ok = io:setopts(File, [{encoding, unicode}]),
State#cl_state{output = File};
{error, Reason} ->
- Msg = io_lib:format("Could not open output file ~p, Reason: ~p\n",
+ Msg = io_lib:format("Could not open output file ~tp, Reason: ~p\n",
[OutFile, Reason]),
cl_error(State, lists:flatten(Msg))
end
@@ -637,6 +634,9 @@ cl_loop(State, LogCache) ->
{BackendPid, warnings, Warnings} ->
NewState = store_warnings(State, Warnings),
cl_loop(NewState, LogCache);
+ {BackendPid, cserver, CodeServer, _Plt} -> % Plt is ignored
+ NewState = State#cl_state{code_server = CodeServer},
+ cl_loop(NewState, LogCache);
{BackendPid, done, NewPlt, _NewDocPlt} ->
return_value(State, NewPlt);
{BackendPid, ext_calls, ExtCalls} ->
@@ -689,20 +689,30 @@ cl_error(Msg) ->
cl_error(State, Msg) ->
case State#cl_state.output of
standard_io -> ok;
- Outfile -> io:format(Outfile, "\n~s\n", [Msg])
+ Outfile -> io:format(Outfile, "\n~ts\n", [Msg])
end,
maybe_close_output_file(State),
throw({dialyzer_error, lists:flatten(Msg)}).
-return_value(State = #cl_state{erlang_mode = ErlangMode,
+return_value(State = #cl_state{code_server = CodeServer,
+ erlang_mode = ErlangMode,
mod_deps = ModDeps,
output_plt = OutputPlt,
plt_info = PltInfo,
stored_warnings = StoredWarnings},
Plt) ->
+ %% Just for now:
+ case CodeServer =:= none of
+ true ->
+ ok;
+ false ->
+ dialyzer_codeserver:delete(CodeServer)
+ end,
case OutputPlt =:= none of
- true -> ok;
- false -> dialyzer_plt:to_file(OutputPlt, Plt, ModDeps, PltInfo)
+ true ->
+ dialyzer_plt:delete(Plt);
+ false ->
+ dialyzer_plt:to_file(OutputPlt, Plt, ModDeps, PltInfo)
end,
UnknownWarnings = unknown_warnings(State),
RetValue =
@@ -765,7 +775,7 @@ print_ext_calls(#cl_state{output = Output,
end.
do_print_ext_calls(Output, [{M,F,A}|T], Before) ->
- io:format(Output, "~s~p:~p/~p\n", [Before,M,F,A]),
+ io:format(Output, "~s~tp:~tp/~p\n", [Before,M,F,A]),
do_print_ext_calls(Output, T, Before);
do_print_ext_calls(_, [], _) ->
ok.
@@ -798,7 +808,7 @@ print_ext_types(#cl_state{output = Output,
end.
do_print_ext_types(Output, [{M,F,A}|T], Before) ->
- io:format(Output, "~s~p:~p/~p\n", [Before,M,F,A]),
+ io:format(Output, "~s~tp:~tp/~p\n", [Before,M,F,A]),
do_print_ext_types(Output, T, Before);
do_print_ext_types(_, [], _) ->
ok.
@@ -817,10 +827,10 @@ print_warnings(#cl_state{output = Output,
formatted ->
[dialyzer:format_warning(W, FOpt) || W <- PrWarnings];
raw ->
- [io_lib:format("~p. \n",
+ [io_lib:format("~tp. \n",
[W]) || W <- set_warning_id(PrWarnings)]
end,
- io:format(Output, "\n~s", [S])
+ io:format(Output, "\n~ts", [S])
end.
-spec process_warnings([raw_warning()]) -> [raw_warning()].
diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl
index 934351aeeb..a456d38e64 100644
--- a/lib/dialyzer/src/dialyzer_cl_parse.erl
+++ b/lib/dialyzer/src/dialyzer_cl_parse.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(dialyzer_cl_parse).
@@ -44,11 +37,12 @@ start() ->
init(),
Args = init:get_plain_arguments(),
try
- cl(Args)
+ Ret = cl(Args),
+ Ret
catch
throw:{dialyzer_cl_parse_error, Msg} -> {error, Msg};
_:R ->
- Msg = io_lib:format("~p\n~p\n", [R, erlang:get_stacktrace()]),
+ Msg = io_lib:format("~tp\n~tp\n", [R, erlang:get_stacktrace()]),
{error, lists:flatten(Msg)}
end.
@@ -510,7 +504,7 @@ warning_options_msg() ->
-Wno_match
Suppress warnings for patterns that are unused or cannot match.
-Wno_opaque
- Suppress warnings for violations of opaqueness of data types.
+ Suppress warnings for violations of opacity of data types.
-Wno_fail_call
Suppress warnings for failing calls.
-Wno_contracts
diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl
index 03cd9671af..5587cf2bdf 100644
--- a/lib/dialyzer/src/dialyzer_codeserver.erl
+++ b/lib/dialyzer/src/dialyzer_codeserver.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_codeserver.erl
@@ -29,18 +22,25 @@
-module(dialyzer_codeserver).
-export([delete/1,
- finalize_contracts/3,
+ store_temp_contracts/4,
+ give_away/2,
+ finalize_contracts/1,
finalize_exported_types/2,
- finalize_records/2,
+ finalize_records/1,
get_contracts/1,
get_callbacks/1,
get_exported_types/1,
+ extract_exported_types/1,
get_exports/1,
- get_records/1,
+ get_records_table/1,
+ extract_records/1,
get_next_core_label/1,
- get_temp_contracts/1,
+ get_temp_contracts/2,
+ all_temp_modules/1,
+ store_contracts/4,
get_temp_exported_types/1,
- get_temp_records/1,
+ get_temp_records_table/1,
+ lookup_temp_mod_records/2,
insert/3,
insert_exports/2,
insert_temp_exported_types/2,
@@ -48,30 +48,29 @@
is_exported/2,
lookup_mod_code/2,
lookup_mfa_code/2,
+ lookup_mfa_var_label/2,
lookup_mod_records/2,
lookup_mod_contracts/2,
lookup_mfa_contract/2,
lookup_meta_info/2,
new/0,
set_next_core_label/2,
- set_temp_records/2,
store_temp_records/3,
- store_temp_contracts/4]).
+ translate_fake_file/3]).
--export_type([codeserver/0, fun_meta_info/0]).
+-export_type([codeserver/0, fun_meta_info/0, contracts/0]).
-include("dialyzer.hrl").
%%--------------------------------------------------------------------
-type dict_ets() :: ets:tid().
+-type map_ets() :: ets:tid().
-type set_ets() :: ets:tid().
-type types() :: erl_types:type_table().
--type mod_records() :: dict:dict(module(), types()).
--type contracts() :: dict:dict(mfa(),dialyzer_contracts:file_contract()).
--type mod_contracts() :: dict:dict(module(), contracts()).
+-type contracts() :: #{mfa() => dialyzer_contracts:file_contract()}.
%% A property-list of data compiled from -compile and -dialyzer attributes.
-type meta_info() :: [{{'nowarn_function' | dial_warn_tag()},
@@ -81,16 +80,16 @@
-record(codeserver, {next_core_label = 0 :: label(),
code :: dict_ets(),
- exported_types :: set_ets() | 'undefined', % set(mfa())
- records :: dict_ets() | 'undefined',
- contracts :: dict_ets() | 'undefined',
- callbacks :: dict_ets() | 'undefined',
+ exported_types :: 'clean' | set_ets(), % set(mfa())
+ records :: 'clean' | map_ets(),
+ contracts :: map_ets(),
+ callbacks :: map_ets(),
fun_meta_info :: dict_ets(), % {mfa(), meta_info()}
exports :: 'clean' | set_ets(), % set(mfa())
temp_exported_types :: 'clean' | set_ets(), % set(mfa())
- temp_records :: 'clean' | dict_ets(),
- temp_contracts :: 'clean' | dict_ets(),
- temp_callbacks :: 'clean' | dict_ets()
+ temp_records :: 'clean' | map_ets(),
+ temp_contracts :: 'clean' | map_ets(),
+ temp_callbacks :: 'clean' | map_ets()
}).
-opaque codeserver() :: #codeserver{}.
@@ -104,13 +103,10 @@ ets_dict_find(Key, Table) ->
_:_ -> error
end.
-ets_dict_store(Key, Element, Table) ->
+ets_map_store(Key, Element, Table) ->
true = ets:insert(Table, {Key, Element}),
Table.
-ets_dict_store_dict(Dict, Table) ->
- true = ets:insert(Table, dict:to_list(Dict)).
-
ets_dict_to_dict(Table) ->
Fold = fun({Key,Value}, Dict) -> dict:store(Key, Value, Dict) end,
ets:foldl(Fold, dict:new(), Table).
@@ -128,9 +124,6 @@ ets_set_to_set(Table) ->
Fold = fun({E}, Set) -> sets:add_element(E, Set) end,
ets:foldl(Fold, sets:new(), Table).
-ets_read_concurrent_table(Name) ->
- ets:new(Name, [{read_concurrency, true}]).
-
%%--------------------------------------------------------------------
-spec new() -> codeserver().
@@ -138,6 +131,13 @@ ets_read_concurrent_table(Name) ->
new() ->
CodeOptions = [compressed, public, {read_concurrency, true}],
Code = ets:new(dialyzer_codeserver_code, CodeOptions),
+ ReadOptions = [compressed, {read_concurrency, true}],
+ [Contracts, Callbacks, Records, ExportedTypes] =
+ [ets:new(Name, ReadOptions) ||
+ Name <- [dialyzer_codeserver_contracts,
+ dialyzer_codeserver_callbacks,
+ dialyzer_codeserver_records,
+ dialyzer_codeserver_exported_types]],
TempOptions = [public, {write_concurrency, true}],
[Exports, FunMetaInfo, TempExportedTypes, TempRecords, TempContracts,
TempCallbacks] =
@@ -150,6 +150,10 @@ new() ->
#codeserver{code = Code,
exports = Exports,
fun_meta_info = FunMetaInfo,
+ exported_types = ExportedTypes,
+ records = Records,
+ contracts = Contracts,
+ callbacks = Callbacks,
temp_exported_types = TempExportedTypes,
temp_records = TempRecords,
temp_contracts = TempContracts,
@@ -157,11 +161,8 @@ new() ->
-spec delete(codeserver()) -> 'ok'.
-delete(#codeserver{code = Code, exported_types = ExportedTypes,
- records = Records, contracts = Contracts,
- callbacks = Callbacks}) ->
- lists:foreach(fun ets:delete/1,
- [Code, ExportedTypes, Records, Contracts, Callbacks]).
+delete(CServer) ->
+ lists:foreach(fun(Table) -> true = ets:delete(Table) end, tables(CServer)).
-spec insert(atom(), cerl:c_module(), codeserver()) -> codeserver().
@@ -170,13 +171,15 @@ insert(Mod, ModCode, CS) ->
Exports = cerl:module_exports(ModCode),
Attrs = cerl:module_attrs(ModCode),
Defs = cerl:module_defs(ModCode),
+ {Files, SmallDefs} = compress_file_anno(Defs),
As = cerl:get_ann(ModCode),
Funs =
[{{Mod, cerl:fname_id(Var), cerl:fname_arity(Var)},
- Val} || Val = {Var, _Fun} <- Defs],
- Keys = [Key || {Key, _Value} <- Funs],
+ Val, {Var, cerl_trees:get_label(Fun)}} || Val = {Var, Fun} <- SmallDefs],
+ Keys = [Key || {Key, _Value, _Label} <- Funs],
ModEntry = {Mod, {Name, Exports, Attrs, Keys, As}},
- true = ets:insert(CS#codeserver.code, [ModEntry|Funs]),
+ ModFileEntry = {{mod, Mod}, Files},
+ true = ets:insert(CS#codeserver.code, [ModEntry, ModFileEntry|Funs]),
CS.
-spec get_temp_exported_types(codeserver()) -> sets:set(mfa()).
@@ -213,6 +216,11 @@ is_exported(MFA, #codeserver{exports = Exports}) ->
get_exported_types(#codeserver{exported_types = ExpTypes}) ->
ets_set_to_set(ExpTypes).
+-spec extract_exported_types(codeserver()) -> {codeserver(), set_ets()}.
+
+extract_exported_types(#codeserver{exported_types = ExpTypes} = CS) ->
+ {CS#codeserver{exported_types = 'clean'}, ExpTypes}.
+
-spec get_exports(codeserver()) -> sets:set(mfa()).
get_exports(#codeserver{exports = Exports}) ->
@@ -220,12 +228,12 @@ get_exports(#codeserver{exports = Exports}) ->
-spec finalize_exported_types(sets:set(mfa()), codeserver()) -> codeserver().
-finalize_exported_types(Set, CS) ->
- ExportedTypes = ets_read_concurrent_table(dialyzer_codeserver_exported_types),
+finalize_exported_types(Set,
+ #codeserver{exported_types = ExportedTypes,
+ temp_exported_types = TempETypes} = CS) ->
true = ets_set_insert_set(Set, ExportedTypes),
- TempExpTypes = CS#codeserver.temp_exported_types,
- true = ets:delete(TempExpTypes),
- CS#codeserver{exported_types = ExportedTypes, temp_exported_types = clean}.
+ true = ets:delete(TempETypes),
+ CS#codeserver{temp_exported_types = clean}.
-spec lookup_mod_code(atom(), codeserver()) -> cerl:c_module().
@@ -237,6 +245,11 @@ lookup_mod_code(Mod, CS) when is_atom(Mod) ->
lookup_mfa_code({_M, _F, _A} = MFA, CS) ->
table__lookup(CS#codeserver.code, MFA).
+-spec lookup_mfa_var_label(mfa(), codeserver()) -> {cerl:c_var(), label()}.
+
+lookup_mfa_var_label({_M, _F, _A} = MFA, CS) ->
+ ets:lookup_element(CS#codeserver.code, MFA, 3).
+
-spec get_next_core_label(codeserver()) -> label().
get_next_core_label(#codeserver{next_core_label = NCL}) ->
@@ -251,53 +264,78 @@ set_next_core_label(NCL, CS) ->
lookup_mod_records(Mod, #codeserver{records = RecDict}) when is_atom(Mod) ->
case ets_dict_find(Mod, RecDict) of
- error -> dict:new();
- {ok, Dict} -> Dict
+ error -> maps:new();
+ {ok, Map} -> Map
end.
--spec get_records(codeserver()) -> mod_records().
+-spec get_records_table(codeserver()) -> map_ets().
+
+get_records_table(#codeserver{records = RecDict}) ->
+ RecDict.
+
+-spec extract_records(codeserver()) -> {codeserver(), map_ets()}.
-get_records(#codeserver{records = RecDict}) ->
- ets_dict_to_dict(RecDict).
+extract_records(#codeserver{records = RecDict} = CS) ->
+ {CS#codeserver{records = clean}, RecDict}.
-spec store_temp_records(module(), types(), codeserver()) -> codeserver().
-store_temp_records(Mod, Dict, #codeserver{temp_records = TempRecDict} = CS)
+store_temp_records(Mod, Map, #codeserver{temp_records = TempRecDict} = CS)
when is_atom(Mod) ->
- case dict:size(Dict) =:= 0 of
+ case maps:size(Map) =:= 0 of
true -> CS;
- false -> CS#codeserver{temp_records = ets_dict_store(Mod, Dict, TempRecDict)}
+ false -> CS#codeserver{temp_records = ets_map_store(Mod, Map, TempRecDict)}
end.
--spec get_temp_records(codeserver()) -> mod_records().
+-spec get_temp_records_table(codeserver()) -> map_ets().
-get_temp_records(#codeserver{temp_records = TempRecDict}) ->
- ets_dict_to_dict(TempRecDict).
+get_temp_records_table(#codeserver{temp_records = TempRecDict}) ->
+ TempRecDict.
--spec set_temp_records(mod_records(), codeserver()) -> codeserver().
+-spec lookup_temp_mod_records(module(), codeserver()) -> types().
-set_temp_records(Dict, CS) ->
- true = ets:delete(CS#codeserver.temp_records),
- TempRecords = ets:new(dialyzer_codeserver_temp_records,[]),
- true = ets_dict_store_dict(Dict, TempRecords),
- CS#codeserver{temp_records = TempRecords}.
-
--spec finalize_records(mod_records(), codeserver()) -> codeserver().
+lookup_temp_mod_records(Mod, #codeserver{temp_records = TempRecDict}) ->
+ case ets_dict_find(Mod, TempRecDict) of
+ error -> maps:new();
+ {ok, Map} -> Map
+ end.
-finalize_records(Dict, CS) ->
- true = ets:delete(CS#codeserver.temp_records),
- Records = ets_read_concurrent_table(dialyzer_codeserver_records),
- true = ets_dict_store_dict(Dict, Records),
- CS#codeserver{records = Records, temp_records = clean}.
+-spec finalize_records(codeserver()) -> codeserver().
+
+finalize_records(#codeserver{temp_records = TmpRecords,
+ records = Records} = CS) ->
+ %% The annotations of the abstract code are reset as they are no
+ %% longer needed, which makes the ETS table compression better.
+ A0 = erl_anno:new(0),
+ AFun = fun(_) -> A0 end,
+ FFun = fun({F, Abs, Type}) ->
+ NewAbs = erl_parse:map_anno(AFun, Abs),
+ {F, NewAbs, Type}
+ end,
+ ArFun = fun({Arity, Fields}) -> {Arity, lists:map(FFun, Fields)} end,
+ List = dialyzer_utils:ets_tab2list(TmpRecords),
+ true = ets:delete(TmpRecords),
+ Fun = fun({Mod, Map}) ->
+ MFun =
+ fun({record, _}, {FileLine, ArityFields}) ->
+ {FileLine, lists:map(ArFun, ArityFields)};
+ (_, {{M, FileLine, Abs, Args}, Type}) ->
+ {{M, FileLine, erl_parse:map_anno(AFun, Abs), Args}, Type}
+ end,
+ {Mod, maps:map(MFun, Map)}
+ end,
+ NewList = lists:map(Fun, List),
+ true = ets:insert(Records, NewList),
+ CS#codeserver{temp_records = clean}.
-spec lookup_mod_contracts(atom(), codeserver()) -> contracts().
lookup_mod_contracts(Mod, #codeserver{contracts = ContDict})
when is_atom(Mod) ->
case ets_dict_find(Mod, ContDict) of
- error -> dict:new();
+ error -> maps:new();
{ok, Keys} ->
- dict:from_list([get_file_contract(Key, ContDict)|| Key <- Keys])
+ maps:from_list([get_file_contract(Key, ContDict)|| Key <- Keys])
end.
get_file_contract(Key, ContDict) ->
@@ -317,10 +355,13 @@ lookup_meta_info(MorMFA, #codeserver{fun_meta_info = FunMetaInfo}) ->
{ok, PropList} -> PropList
end.
--spec get_contracts(codeserver()) -> mod_contracts().
+-spec get_contracts(codeserver()) ->
+ dict:dict(mfa(), dialyzer_contracts:file_contract()).
get_contracts(#codeserver{contracts = ContDict}) ->
- ets_dict_to_dict(ContDict).
+ dict:filter(fun({_M, _F, _A}, _) -> true;
+ (_, _) -> false
+ end, ets_dict_to_dict(ContDict)).
-spec get_callbacks(codeserver()) -> list().
@@ -330,48 +371,79 @@ get_callbacks(#codeserver{callbacks = CallbDict}) ->
-spec store_temp_contracts(module(), contracts(), contracts(), codeserver()) ->
codeserver().
-store_temp_contracts(Mod, SpecDict, CallbackDict,
+store_temp_contracts(Mod, SpecMap, CallbackMap,
#codeserver{temp_contracts = Cn,
temp_callbacks = Cb} = CS)
when is_atom(Mod) ->
- CS1 =
- case dict:size(SpecDict) =:= 0 of
- true -> CS;
- false ->
- CS#codeserver{temp_contracts = ets_dict_store(Mod, SpecDict, Cn)}
- end,
- case dict:size(CallbackDict) =:= 0 of
- true -> CS1;
- false ->
- CS1#codeserver{temp_callbacks = ets_dict_store(Mod, CallbackDict, Cb)}
- end.
-
--spec get_temp_contracts(codeserver()) -> {mod_contracts(), mod_contracts()}.
+ %% Make sure Mod is stored even if there are no callbacks or
+ %% contracts.
+ CS1 = CS#codeserver{temp_contracts = ets_map_store(Mod, SpecMap, Cn)},
+ CS1#codeserver{temp_callbacks = ets_map_store(Mod, CallbackMap, Cb)}.
-get_temp_contracts(#codeserver{temp_contracts = TempContDict,
- temp_callbacks = TempCallDict}) ->
- {ets_dict_to_dict(TempContDict), ets_dict_to_dict(TempCallDict)}.
+-spec all_temp_modules(codeserver()) -> [module()].
--spec finalize_contracts(mod_contracts(), mod_contracts(), codeserver()) ->
- codeserver().
+all_temp_modules(#codeserver{temp_contracts = TempContTable}) ->
+ ets:select(TempContTable, [{{'$1', '$2'}, [], ['$1']}]).
-finalize_contracts(SpecDict, CallbackDict, CS) ->
- Contracts = ets_read_concurrent_table(dialyzer_codeserver_contracts),
- Callbacks = ets_read_concurrent_table(dialyzer_codeserver_callbacks),
- Contracts = dict:fold(fun decompose_spec_dict/3, Contracts, SpecDict),
- Callbacks = dict:fold(fun decompose_cb_dict/3, Callbacks, CallbackDict),
- CS#codeserver{contracts = Contracts, callbacks = Callbacks,
- temp_contracts = clean, temp_callbacks = clean}.
+-spec store_contracts(module(), contracts(), contracts(), codeserver()) ->
+ codeserver().
-decompose_spec_dict(Mod, Dict, Table) ->
- Keys = dict:fetch_keys(Dict),
- true = ets:insert(Table, dict:to_list(Dict)),
- true = ets:insert(Table, {Mod, Keys}),
- Table.
+store_contracts(Mod, SpecMap, CallbackMap, CS) ->
+ #codeserver{contracts = SpecDict, callbacks = CallbackDict} = CS,
+ Keys = maps:keys(SpecMap),
+ true = ets:insert(SpecDict, maps:to_list(SpecMap)),
+ true = ets:insert(SpecDict, {Mod, Keys}),
+ true = ets:insert(CallbackDict, maps:to_list(CallbackMap)),
+ CS.
-decompose_cb_dict(_Mod, Dict, Table) ->
- true = ets:insert(Table, dict:to_list(Dict)),
- Table.
+-spec get_temp_contracts(module(), codeserver()) ->
+ {contracts(), contracts()}.
+
+get_temp_contracts(Mod, #codeserver{temp_contracts = TempContDict,
+ temp_callbacks = TempCallDict}) ->
+ [{Mod, Contracts}] = ets:lookup(TempContDict, Mod),
+ true = ets:delete(TempContDict, Mod),
+ [{Mod, Callbacks}] = ets:lookup(TempCallDict, Mod),
+ true = ets:delete(TempCallDict, Mod),
+ {Contracts, Callbacks}.
+
+-spec give_away(codeserver(), pid()) -> 'ok'.
+
+give_away(CServer, Pid) ->
+ lists:foreach(fun(Table) -> true = ets:give_away(Table, Pid, any)
+ end, tables(CServer)).
+
+tables(#codeserver{code = Code,
+ fun_meta_info = FunMetaInfo,
+ exports = Exports,
+ temp_exported_types = TempExpTypes,
+ temp_records = TempRecords,
+ temp_contracts = TempContracts,
+ temp_callbacks = TempCallbacks,
+ exported_types = ExportedTypes,
+ records = Records,
+ contracts = Contracts,
+ callbacks = Callbacks}) ->
+ [Table || Table <- [Code, FunMetaInfo, Exports, TempExpTypes,
+ TempRecords, TempContracts, TempCallbacks,
+ ExportedTypes, Records, Contracts, Callbacks],
+ Table =/= clean].
+
+-spec finalize_contracts(codeserver()) -> codeserver().
+
+finalize_contracts(#codeserver{temp_contracts = TempContDict,
+ temp_callbacks = TempCallDict} = CS) ->
+ true = ets:delete(TempContDict),
+ true = ets:delete(TempCallDict),
+ CS#codeserver{temp_contracts = clean, temp_callbacks = clean}.
+
+-spec translate_fake_file(codeserver(), module(), file:filename()) ->
+ file:filename().
+
+translate_fake_file(#codeserver{code = Code}, Module, FakeFile) ->
+ Files = ets:lookup_element(Code, {mod, Module}, 2),
+ {FakeFile, File} = lists:keyfind(FakeFile, 1, Files),
+ File.
table__lookup(TablePid, M) when is_atom(M) ->
{Name, Exports, Attrs, Keys, As} = ets:lookup_element(TablePid, M, 2),
@@ -379,3 +451,25 @@ table__lookup(TablePid, M) when is_atom(M) ->
cerl:ann_c_module(As, Name, Exports, Attrs, Defs);
table__lookup(TablePid, MFA) ->
ets:lookup_element(TablePid, MFA, 2).
+
+compress_file_anno(Term) ->
+ {Files, SmallTerm} = compress_file_anno(Term, []),
+ {[{FakeFile, File} || {File, {file, FakeFile}} <- Files], SmallTerm}.
+
+compress_file_anno({file, F}, Fs) when is_list(F) ->
+ case lists:keyfind(F, 1, Fs) of
+ false ->
+ I = integer_to_list(length(Fs)),
+ FileI = {file, I},
+ NFs = [{F, FileI}|Fs],
+ {NFs, FileI};
+ {F, FileI} -> {Fs, FileI}
+ end;
+compress_file_anno(T, Fs) when is_tuple(T) ->
+ {NFs, NL} = compress_file_anno(tuple_to_list(T), Fs),
+ {NFs, list_to_tuple(NL)};
+compress_file_anno([E|L], Fs) ->
+ {Fs1, NE} = compress_file_anno(E, Fs),
+ {NFs, NL} = compress_file_anno(L, Fs1),
+ {NFs, [NE|NL]};
+compress_file_anno(T, Fs) -> {Fs, T}.
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index 976a2b8955..b554ebc2cc 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(dialyzer_contracts).
@@ -25,7 +18,7 @@
check_contracts/4,
contracts_without_fun/3,
contract_to_string/1,
- get_invalid_contract_warnings/4,
+ get_invalid_contract_warnings/3,
get_contract_args/1,
get_contract_return/1,
get_contract_return/2,
@@ -147,55 +140,53 @@ sequence([H], _Delimiter) -> H;
sequence([H|T], Delimiter) -> H ++ Delimiter ++ sequence(T, Delimiter).
-spec process_contract_remote_types(dialyzer_codeserver:codeserver()) ->
- dialyzer_codeserver:codeserver().
+ dialyzer_codeserver:codeserver().
process_contract_remote_types(CodeServer) ->
- {TmpContractDict, TmpCallbackDict} =
- dialyzer_codeserver:get_temp_contracts(CodeServer),
+ Mods = dialyzer_codeserver:all_temp_modules(CodeServer),
+ RecordTable = dialyzer_codeserver:get_records_table(CodeServer),
ExpTypes = dialyzer_codeserver:get_exported_types(CodeServer),
- RecordDict = dialyzer_codeserver:get_records(CodeServer),
ContractFun =
fun({{_M, _F, _A}=MFA, {File, TmpContract, Xtra}}, C0) ->
#tmp_contract{contract_funs = CFuns, forms = Forms} = TmpContract,
{NewCs, C2} = lists:mapfoldl(fun(CFun, C1) ->
- CFun(ExpTypes, RecordDict, C1)
+ CFun(ExpTypes, RecordTable, C1)
end, C0, CFuns),
Args = general_domain(NewCs),
Contract = #contract{contracts = NewCs, args = Args, forms = Forms},
{{MFA, {File, Contract, Xtra}}, C2}
end,
ModuleFun =
- fun({ModuleName, ContractDict}, C3) ->
- {NewContractList, C4} =
- lists:mapfoldl(ContractFun, C3, dict:to_list(ContractDict)),
- {{ModuleName, dict:from_list(NewContractList)}, C4}
+ fun(ModuleName) ->
+ Cache = erl_types:cache__new(),
+ {ContractMap, CallbackMap} =
+ dialyzer_codeserver:get_temp_contracts(ModuleName, CodeServer),
+ {NewContractList, Cache1} =
+ lists:mapfoldl(ContractFun, Cache, maps:to_list(ContractMap)),
+ {NewCallbackList, _NewCache} =
+ lists:mapfoldl(ContractFun, Cache1, maps:to_list(CallbackMap)),
+ dialyzer_codeserver:store_contracts(ModuleName,
+ maps:from_list(NewContractList),
+ maps:from_list(NewCallbackList),
+ CodeServer)
end,
- Cache = erl_types:cache__new(),
- {NewContractList, C5} =
- lists:mapfoldl(ModuleFun, Cache, dict:to_list(TmpContractDict)),
- {NewCallbackList, _C6} =
- lists:mapfoldl(ModuleFun, C5, dict:to_list(TmpCallbackDict)),
- NewContractDict = dict:from_list(NewContractList),
- NewCallbackDict = dict:from_list(NewCallbackList),
- dialyzer_codeserver:finalize_contracts(NewContractDict, NewCallbackDict,
- CodeServer).
-
--type opaques_fun() :: fun((module()) -> [erl_types:erl_type()]).
+ lists:foreach(ModuleFun, Mods),
+ dialyzer_codeserver:finalize_contracts(CodeServer).
--type fun_types() :: dict:dict(label(), erl_types:type_table()).
+-type fun_types() :: orddict:orddict(label(), erl_types:type_table()).
--spec check_contracts([{mfa(), file_contract()}],
+-spec check_contracts(orddict:orddict(mfa(), #contract{}),
dialyzer_callgraph:callgraph(), fun_types(),
- opaques_fun()) -> plt_contracts().
+ erl_types:opaques()) -> plt_contracts().
-check_contracts(Contracts, Callgraph, FunTypes, FindOpaques) ->
+check_contracts(Contracts, Callgraph, FunTypes, ModOpaques) ->
FoldFun =
- fun(Label, Type, NewContracts) ->
+ fun({Label, Type}, NewContracts) ->
case dialyzer_callgraph:lookup_name(Label, Callgraph) of
{ok, {M,F,A} = MFA} ->
case orddict:find(MFA, Contracts) of
- {ok, {_FileLine, Contract, _Xtra}} ->
- Opaques = FindOpaques(M),
+ {ok, Contract} ->
+ {M, Opaques} = lists:keyfind(M, 1, ModOpaques),
case check_contract(Contract, Type, Opaques) of
ok ->
case erl_bif_types:is_known(M, F, A) of
@@ -213,7 +204,7 @@ check_contracts(Contracts, Callgraph, FunTypes, FindOpaques) ->
error -> NewContracts
end
end,
- dict:fold(FoldFun, [], FunTypes).
+ orddict:from_list(lists:foldl(FoldFun, [], orddict:to_list(FunTypes))).
%% Checks all components of a contract
-spec check_contract(#contract{}, erl_types:erl_type()) -> 'ok' | {'error', term()}.
@@ -221,6 +212,9 @@ check_contracts(Contracts, Callgraph, FunTypes, FindOpaques) ->
check_contract(Contract, SuccType) ->
check_contract(Contract, SuccType, 'universe').
+-spec check_contract(#contract{}, erl_types:erl_type(), erl_types:opaques()) ->
+ 'ok' | {'error', term()}.
+
check_contract(#contract{contracts = Contracts}, SuccType, Opaques) ->
try
Contracts1 = [{Contract, insert_constraints(Constraints)}
@@ -232,7 +226,7 @@ check_contract(#contract{contracts = Contracts}, SuccType, Opaques) ->
error ->
{error, {overlapping_contract, []}};
ok ->
- InfList = [erl_types:t_inf(Contract, SuccType, Opaques)
+ InfList = [{Contract, erl_types:t_inf(Contract, SuccType, Opaques)}
|| Contract <- Contracts2],
case check_contract_inf_list(InfList, SuccType, Opaques) of
{error, _} = Invalid -> Invalid;
@@ -256,10 +250,21 @@ check_domains([Dom|Doms]) ->
%% Allow a contract if one of the overloaded contracts is possible.
%% We used to be more strict, e.g., all overloaded contracts had to be
%% possible.
-check_contract_inf_list([FunType|Left], SuccType, Opaques) ->
+check_contract_inf_list(List, SuccType, Opaques) ->
+ case check_contract_inf_list(List, SuccType, Opaques, []) of
+ ok -> ok;
+ {error, []} -> {error, invalid_contract};
+ {error, [{SigRange, ContrRange}|_]} ->
+ case erl_types:t_find_opaque_mismatch(SigRange, ContrRange, Opaques) of
+ error -> {error, invalid_contract};
+ {ok, _T1, T2} -> {error, {opaque_mismatch, T2}}
+ end
+ end.
+
+check_contract_inf_list([{Contract, FunType}|Left], SuccType, Opaques, OM) ->
FunArgs = erl_types:t_fun_args(FunType),
case lists:any(fun erl_types:t_is_none_or_unit/1, FunArgs) of
- true -> check_contract_inf_list(Left, SuccType, Opaques);
+ true -> check_contract_inf_list(Left, SuccType, Opaques, OM);
false ->
STRange = erl_types:t_fun_range(SuccType),
case erl_types:t_is_none_or_unit(STRange) of
@@ -267,13 +272,16 @@ check_contract_inf_list([FunType|Left], SuccType, Opaques) ->
false ->
Range = erl_types:t_fun_range(FunType),
case erl_types:t_is_none(erl_types:t_inf(STRange, Range)) of
- true -> check_contract_inf_list(Left, SuccType, Opaques);
+ true ->
+ CR = erl_types:t_fun_range(Contract),
+ NewOM = [{STRange, CR}|OM],
+ check_contract_inf_list(Left, SuccType, Opaques, NewOM);
false -> ok
end
end
end;
-check_contract_inf_list([], _SuccType, _Opaques) ->
- {error, invalid_contract}.
+check_contract_inf_list([], _SuccType, _Opaques, OM) ->
+ {error, OM}.
check_extraneous([], _SuccType) -> ok;
check_extraneous([C|Cs], SuccType) ->
@@ -286,7 +294,7 @@ check_extraneous_1(Contract, SuccType) ->
CRng = erl_types:t_fun_range(Contract),
CRngs = erl_types:t_elements(CRng),
STRng = erl_types:t_fun_range(SuccType),
- ?debug("CR = ~p\nSR = ~p\n", [CRngs, STRng]),
+ ?debug("CR = ~tp\nSR = ~tp\n", [CRngs, STRng]),
case [CR || CR <- CRngs,
erl_types:t_is_none(erl_types:t_inf(CR, STRng))] of
[] ->
@@ -353,7 +361,7 @@ process_contract({Contract, Constraints}, CallTypes0) ->
CallTypesFun = erl_types:t_fun(CallTypes0, erl_types:t_any()),
ContArgsFun = erl_types:t_fun(erl_types:t_fun_args(Contract),
erl_types:t_any()),
- ?debug("Instance: Contract: ~s\n Arguments: ~s\n",
+ ?debug("Instance: Contract: ~ts\n Arguments: ~ts\n",
[erl_types:t_to_string(ContArgsFun),
erl_types:t_to_string(CallTypesFun)]),
case solve_constraints(ContArgsFun, CallTypesFun, Constraints) of
@@ -383,7 +391,7 @@ solve_constraints(Contract, Call, Constraints) ->
%% ?debug("Inf: ~s\n", [erl_types:t_to_string(Inf)]),
%% erl_types:t_assign_variables_to_subtype(Contract, Inf).
--type contracts() :: dict:dict(mfa(),dialyzer_contracts:file_contract()).
+-type contracts() :: dialyzer_codeserver:contracts().
%% Checks the contracts for functions that are not implemented
-spec contracts_without_fun(contracts(), [_], dialyzer_callgraph:callgraph()) ->
@@ -393,12 +401,12 @@ contracts_without_fun(Contracts, AllFuns0, Callgraph) ->
AllFuns1 = [{dialyzer_callgraph:lookup_name(Label, Callgraph), Arity}
|| {Label, Arity} <- AllFuns0],
AllFuns2 = [{M, F, A} || {{ok, {M, F, _}}, A} <- AllFuns1],
- AllContractMFAs = dict:fetch_keys(Contracts),
+ AllContractMFAs = maps:keys(Contracts),
ErrorContractMFAs = AllContractMFAs -- AllFuns2,
[warn_spec_missing_fun(MFA, Contracts) || MFA <- ErrorContractMFAs].
warn_spec_missing_fun({M, F, A} = MFA, Contracts) ->
- {{File, Line}, _Contract, _Xtra} = dict:fetch(MFA, Contracts),
+ {{File, Line}, _Contract, _Xtra} = maps:get(MFA, Contracts),
WarningInfo = {File, Line, MFA},
{?WARN_CONTRACT_SYNTAX, WarningInfo, {spec_missing_fun, [M, F, A]}}.
@@ -420,7 +428,7 @@ insert_constraints([{subtype, Type1, Type2}|Left], Map) ->
false ->
%% A lot of things should change to add supertypes
throw({error, io_lib:format("First argument of is_subtype constraint "
- "must be a type variable: ~p\n", [Type1])})
+ "must be a type variable: ~tp\n", [Type1])})
end;
insert_constraints([], Map) -> Map.
@@ -431,11 +439,11 @@ insert_constraints([], Map) -> Map.
-spec store_tmp_contract(mfa(), file_line(), spec_data(), contracts(), types()) ->
contracts().
-store_tmp_contract(MFA, FileLine, {TypeSpec, Xtra}, SpecDict, RecordsDict) ->
- %% io:format("contract from form: ~p\n", [TypeSpec]),
+store_tmp_contract(MFA, FileLine, {TypeSpec, Xtra}, SpecMap, RecordsDict) ->
+ %% io:format("contract from form: ~tp\n", [TypeSpec]),
TmpContract = contract_from_form(TypeSpec, MFA, RecordsDict, FileLine),
- %% io:format("contract: ~p\n", [TmpContract]),
- dict:store(MFA, {FileLine, TmpContract, Xtra}, SpecDict).
+ %% io:format("contract: ~tp\n", [TmpContract]),
+ maps:put(MFA, {FileLine, TmpContract, Xtra}, SpecMap).
contract_from_form(Forms, MFA, RecDict, FileLine) ->
{CFuns, Forms1} = contract_from_form(Forms, MFA, RecDict, FileLine, [], []),
@@ -444,15 +452,15 @@ contract_from_form(Forms, MFA, RecDict, FileLine) ->
contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], MFA, RecDict,
FileLine, TypeAcc, FormAcc) ->
TypeFun =
- fun(ExpTypes, AllRecords, Cache) ->
+ fun(ExpTypes, RecordTable, Cache) ->
{NewType, NewCache} =
try
- from_form_with_check(Form, ExpTypes, MFA, AllRecords, Cache)
+ from_form_with_check(Form, ExpTypes, MFA, RecordTable, Cache)
catch
throw:{error, Msg} ->
{File, Line} = FileLine,
- NewMsg = io_lib:format("~s:~p: ~s", [filename:basename(File),
- Line, Msg]),
+ NewMsg = io_lib:format("~ts:~p: ~ts", [filename:basename(File),
+ Line, Msg]),
throw({error, NewMsg})
end,
NewTypeNoVars = erl_types:subst_all_vars_to_any(NewType),
@@ -465,12 +473,12 @@ contract_from_form([{type, _L1, bounded_fun,
[{type, _L2, 'fun', [_, _]} = Form, Constr]}| Left],
MFA, RecDict, FileLine, TypeAcc, FormAcc) ->
TypeFun =
- fun(ExpTypes, AllRecords, Cache) ->
+ fun(ExpTypes, RecordTable, Cache) ->
{Constr1, VarTable, Cache1} =
- process_constraints(Constr, MFA, RecDict, ExpTypes, AllRecords,
+ process_constraints(Constr, MFA, RecDict, ExpTypes, RecordTable,
Cache),
{NewType, NewCache} =
- from_form_with_check(Form, ExpTypes, MFA, AllRecords,
+ from_form_with_check(Form, ExpTypes, MFA, RecordTable,
VarTable, Cache1),
NewTypeNoVars = erl_types:subst_all_vars_to_any(NewType),
{{NewTypeNoVars, Constr1}, NewCache}
@@ -481,47 +489,47 @@ contract_from_form([{type, _L1, bounded_fun,
contract_from_form([], _MFA, _RecDict, _FileLine, TypeAcc, FormAcc) ->
{lists:reverse(TypeAcc), lists:reverse(FormAcc)}.
-process_constraints(Constrs, MFA, RecDict, ExpTypes, AllRecords, Cache) ->
+process_constraints(Constrs, MFA, RecDict, ExpTypes, RecordTable, Cache) ->
{Init0, NewCache} = initialize_constraints(Constrs, MFA, RecDict, ExpTypes,
- AllRecords, Cache),
+ RecordTable, Cache),
Init = remove_cycles(Init0),
- constraints_fixpoint(Init, MFA, RecDict, ExpTypes, AllRecords, NewCache).
+ constraints_fixpoint(Init, MFA, RecDict, ExpTypes, RecordTable, NewCache).
-initialize_constraints(Constrs, MFA, RecDict, ExpTypes, AllRecords, Cache) ->
- initialize_constraints(Constrs, MFA, RecDict, ExpTypes, AllRecords,
+initialize_constraints(Constrs, MFA, RecDict, ExpTypes, RecordTable, Cache) ->
+ initialize_constraints(Constrs, MFA, RecDict, ExpTypes, RecordTable,
Cache, []).
-initialize_constraints([], _MFA, _RecDict, _ExpTypes, _AllRecords,
+initialize_constraints([], _MFA, _RecDict, _ExpTypes, _RecordTable,
Cache, Acc) ->
{Acc, Cache};
-initialize_constraints([Constr|Rest], MFA, RecDict, ExpTypes, AllRecords,
+initialize_constraints([Constr|Rest], MFA, RecDict, ExpTypes, RecordTable,
Cache, Acc) ->
case Constr of
{type, _, constraint, [{atom, _, is_subtype}, [Type1, Type2]]} ->
VarTable = erl_types:var_table__new(),
{T1, NewCache} =
- final_form(Type1, ExpTypes, MFA, AllRecords, VarTable, Cache),
+ final_form(Type1, ExpTypes, MFA, RecordTable, VarTable, Cache),
Entry = {T1, Type2},
- initialize_constraints(Rest, MFA, RecDict, ExpTypes, AllRecords,
+ initialize_constraints(Rest, MFA, RecDict, ExpTypes, RecordTable,
NewCache, [Entry|Acc]);
{type, _, constraint, [{atom,_,Name}, List]} ->
N = length(List),
throw({error,
- io_lib:format("Unsupported type guard ~w/~w\n", [Name, N])})
+ io_lib:format("Unsupported type guard ~tw/~w\n", [Name, N])})
end.
-constraints_fixpoint(Constrs, MFA, RecDict, ExpTypes, AllRecords, Cache) ->
+constraints_fixpoint(Constrs, MFA, RecDict, ExpTypes, RecordTable, Cache) ->
VarTable = erl_types:var_table__new(),
{VarTab, NewCache} =
- constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, AllRecords,
+ constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, RecordTable,
VarTable, Cache),
constraints_fixpoint(VarTab, MFA, Constrs, RecDict, ExpTypes,
- AllRecords, NewCache).
+ RecordTable, NewCache).
constraints_fixpoint(OldVarTab, MFA, Constrs, RecDict, ExpTypes,
- AllRecords, Cache) ->
+ RecordTable, Cache) ->
{NewVarTab, NewCache} =
- constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, AllRecords,
+ constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, RecordTable,
OldVarTab, Cache),
case NewVarTab of
OldVarTab ->
@@ -533,38 +541,38 @@ constraints_fixpoint(OldVarTab, MFA, Constrs, RecDict, ExpTypes,
{FinalConstrs, NewVarTab, NewCache};
_Other ->
constraints_fixpoint(NewVarTab, MFA, Constrs, RecDict, ExpTypes,
- AllRecords, NewCache)
+ RecordTable, NewCache)
end.
-final_form(Form, ExpTypes, MFA, AllRecords, VarTable, Cache) ->
- from_form_with_check(Form, ExpTypes, MFA, AllRecords, VarTable, Cache).
+final_form(Form, ExpTypes, MFA, RecordTable, VarTable, Cache) ->
+ from_form_with_check(Form, ExpTypes, MFA, RecordTable, VarTable, Cache).
-from_form_with_check(Form, ExpTypes, MFA, AllRecords, Cache) ->
+from_form_with_check(Form, ExpTypes, MFA, RecordTable, Cache) ->
VarTable = erl_types:var_table__new(),
- from_form_with_check(Form, ExpTypes, MFA, AllRecords, VarTable, Cache).
+ from_form_with_check(Form, ExpTypes, MFA, RecordTable, VarTable, Cache).
-from_form_with_check(Form, ExpTypes, MFA, AllRecords, VarTable, Cache) ->
+from_form_with_check(Form, ExpTypes, MFA, RecordTable, VarTable, Cache) ->
Site = {spec, MFA},
- C1 = erl_types:t_check_record_fields(Form, ExpTypes, Site, AllRecords,
+ C1 = erl_types:t_check_record_fields(Form, ExpTypes, Site, RecordTable,
VarTable, Cache),
- erl_types:t_from_form(Form, ExpTypes, Site, AllRecords, VarTable, C1).
+ erl_types:t_from_form(Form, ExpTypes, Site, RecordTable, VarTable, C1).
-constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, AllRecords,
+constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, RecordTable,
VarTab, Cache) ->
{Subtypes, NewCache} =
- constraints_to_subs(Constrs, MFA, RecDict, ExpTypes, AllRecords,
+ constraints_to_subs(Constrs, MFA, RecDict, ExpTypes, RecordTable,
VarTab, Cache, []),
{insert_constraints(Subtypes), NewCache}.
-constraints_to_subs([], _MFA, _RecDict, _ExpTypes, _AllRecords,
+constraints_to_subs([], _MFA, _RecDict, _ExpTypes, _RecordTable,
_VarTab, Cache, Acc) ->
{Acc, Cache};
-constraints_to_subs([{T1, Form2}|Rest], MFA, RecDict, ExpTypes, AllRecords,
+constraints_to_subs([{T1, Form2}|Rest], MFA, RecDict, ExpTypes, RecordTable,
VarTab, Cache, Acc) ->
{T2, NewCache} =
- final_form(Form2, ExpTypes, MFA, AllRecords, VarTab, Cache),
+ final_form(Form2, ExpTypes, MFA, RecordTable, VarTab, Cache),
NewAcc = [{subtype, T1, T2}|Acc],
- constraints_to_subs(Rest, MFA, RecDict, ExpTypes, AllRecords,
+ constraints_to_subs(Rest, MFA, RecDict, ExpTypes, RecordTable,
VarTab, NewCache, NewAcc).
%% Replaces variables with '_' when necessary to break up cycles among
@@ -655,38 +663,46 @@ general_domain([], AccSig) ->
-spec get_invalid_contract_warnings([module()],
dialyzer_codeserver:codeserver(),
- dialyzer_plt:plt(),
- opaques_fun()) -> [raw_warning()].
+ dialyzer_plt:plt()) -> [raw_warning()].
-get_invalid_contract_warnings(Modules, CodeServer, Plt, FindOpaques) ->
- get_invalid_contract_warnings_modules(Modules, CodeServer, Plt, FindOpaques, []).
+get_invalid_contract_warnings(Modules, CodeServer, Plt) ->
+ get_invalid_contract_warnings_modules(Modules, CodeServer, Plt, []).
-get_invalid_contract_warnings_modules([Mod|Mods], CodeServer, Plt, FindOpaques, Acc) ->
+get_invalid_contract_warnings_modules([Mod|Mods], CodeServer, Plt, Acc) ->
Contracts1 = dialyzer_codeserver:lookup_mod_contracts(Mod, CodeServer),
- Contracts2 = dict:to_list(Contracts1),
- Records = dialyzer_codeserver:lookup_mod_records(Mod, CodeServer),
- NewAcc = get_invalid_contract_warnings_funs(Contracts2, Plt, Records, FindOpaques, Acc),
- get_invalid_contract_warnings_modules(Mods, CodeServer, Plt, FindOpaques, NewAcc);
-get_invalid_contract_warnings_modules([], _CodeServer, _Plt, _FindOpaques, Acc) ->
+ NewAcc =
+ case maps:size(Contracts1) =:= 0 of
+ true -> Acc;
+ false ->
+ Contracts2 = maps:to_list(Contracts1),
+ Records = dialyzer_codeserver:lookup_mod_records(Mod, CodeServer),
+ Opaques = erl_types:t_opaque_from_records(Records),
+ get_invalid_contract_warnings_funs(Contracts2, Plt, Records,
+ Opaques, Acc)
+ end,
+ get_invalid_contract_warnings_modules(Mods, CodeServer, Plt, NewAcc);
+get_invalid_contract_warnings_modules([], _CodeServer, _Plt, Acc) ->
Acc.
get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract, _Xtra}}|Left],
- Plt, RecDict, FindOpaques, Acc) ->
+ Plt, RecDict, Opaques, Acc) ->
case dialyzer_plt:lookup(Plt, MFA) of
none ->
%% This must be a contract for a non-available function. Just accept it.
- get_invalid_contract_warnings_funs(Left, Plt, RecDict, FindOpaques, Acc);
+ get_invalid_contract_warnings_funs(Left, Plt, RecDict, Opaques, Acc);
{value, {Ret, Args}} ->
Sig = erl_types:t_fun(Args, Ret),
{M, _F, _A} = MFA,
- %% io:format("MFA ~p~n", [MFA]),
- Opaques = FindOpaques(M),
+ %% io:format("MFA ~tp~n", [MFA]),
{File, Line} = FileLine,
WarningInfo = {File, Line, MFA},
NewAcc =
case check_contract(Contract, Sig, Opaques) of
{error, invalid_contract} ->
[invalid_contract_warning(MFA, WarningInfo, Sig, RecDict)|Acc];
+ {error, {opaque_mismatch, T2}} ->
+ W = contract_opaque_warning(MFA, WarningInfo, T2, Sig, RecDict),
+ [W|Acc];
{error, {overlapping_contract, []}} ->
[overlapping_contract_warning(MFA, WarningInfo)|Acc];
{error, {extra_range, ExtraRanges, STRange}} ->
@@ -731,15 +747,21 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract, _Xtra}}|Left],
RecDict, Acc)
end
end,
- get_invalid_contract_warnings_funs(Left, Plt, RecDict, FindOpaques, NewAcc)
+ get_invalid_contract_warnings_funs(Left, Plt, RecDict, Opaques, NewAcc)
end;
-get_invalid_contract_warnings_funs([], _Plt, _RecDict, _FindOpaques, Acc) ->
+get_invalid_contract_warnings_funs([], _Plt, _RecDict, _Opaques, Acc) ->
Acc.
invalid_contract_warning({M, F, A}, WarningInfo, SuccType, RecDict) ->
SuccTypeStr = dialyzer_utils:format_sig(SuccType, RecDict),
{?WARN_CONTRACT_TYPES, WarningInfo, {invalid_contract, [M, F, A, SuccTypeStr]}}.
+contract_opaque_warning({M, F, A}, WarningInfo, OpType, SuccType, RecDict) ->
+ OpaqueStr = erl_types:t_to_string(OpType),
+ SuccTypeStr = dialyzer_utils:format_sig(SuccType, RecDict),
+ {?WARN_CONTRACT_TYPES, WarningInfo,
+ {contract_with_opaque, [M, F, A, OpaqueStr, SuccTypeStr]}}.
+
overlapping_contract_warning({M, F, A}, WarningInfo) ->
{?WARN_CONTRACT_TYPES, WarningInfo, {overlapping_contract, [M, F, A]}}.
@@ -768,19 +790,9 @@ picky_contract_check(CSig0, Sig0, MFA, WarningInfo, Contract, RecDict, Acc) ->
end.
extra_contract_warning(MFA, WarningInfo, Contract, CSig, Sig, RecDict) ->
- %% We do not want to depend upon erl_types:t_to_string() possibly
- %% hiding the contents of opaque types.
- SigUnopaque = erl_types:t_unopaque(Sig),
- CSigUnopaque = erl_types:t_unopaque(CSig),
- SigString0 =
- lists:flatten(dialyzer_utils:format_sig(SigUnopaque, RecDict)),
- ContractString0 =
- lists:flatten(dialyzer_utils:format_sig(CSigUnopaque, RecDict)),
- %% The only difference is in record fields containing 'undefined' or not.
- IsUndefRecordFieldsRelated = SigString0 =:= ContractString0,
{IsRemoteTypesRelated, SubtypeRelation} =
is_remote_types_related(Contract, CSig, Sig, MFA, RecDict),
- case IsUndefRecordFieldsRelated orelse IsRemoteTypesRelated of
+ case IsRemoteTypesRelated of
true ->
no_warning;
false ->
diff --git a/lib/dialyzer/src/dialyzer_coordinator.erl b/lib/dialyzer/src/dialyzer_coordinator.erl
index 87cbd25b30..7c1bc1de5a 100644
--- a/lib/dialyzer/src/dialyzer_coordinator.erl
+++ b/lib/dialyzer/src/dialyzer_coordinator.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_coordinator.erl
@@ -83,6 +76,8 @@
active = 0 :: integer(),
result :: result(),
next_label = 0 :: integer(),
+ jobs :: [job()],
+ job_fun :: fun(),
init_data :: init_data(),
regulator :: regulator(),
scc_to_pid :: scc_to_pid()
@@ -115,16 +110,18 @@ spawn_jobs(Mode, Jobs, InitData, Timing) ->
false -> unused
end,
Coordinator = {Collector, Regulator, SCCtoPID},
- Fold =
- fun(Job, Count) ->
- Pid = dialyzer_worker:launch(Mode, Job, InitData, Coordinator),
- case TypesigOrDataflow of
- true -> true = ets:insert(SCCtoPID, {Job, Pid}), ok;
- false -> ok
- end,
- Count + 1
+ JobFun =
+ fun(Job) ->
+ Pid = dialyzer_worker:launch(Mode, Job, InitData, Coordinator),
+ case TypesigOrDataflow of
+ true -> true = ets:insert(SCCtoPID, {Job, Pid});
+ false -> true
+ end
end,
- JobCount = lists:foldl(Fold, 0, Jobs),
+ JobCount = length(Jobs),
+ NumberOfInitJobs = min(JobCount, 20 * dialyzer_utils:parallelism()),
+ {InitJobs, RestJobs} = lists:split(NumberOfInitJobs, Jobs),
+ lists:foreach(JobFun, InitJobs),
Unit =
case Mode of
'typesig' -> "SCCs";
@@ -136,11 +133,13 @@ spawn_jobs(Mode, Jobs, InitData, Timing) ->
'compile' -> dialyzer_analysis_callgraph:compile_init_result();
_ -> []
end,
- #state{mode = Mode, active = JobCount, result = InitResult, next_label = 0,
- init_data = InitData, regulator = Regulator, scc_to_pid = SCCtoPID}.
+ #state{mode = Mode, active = JobCount, result = InitResult,
+ next_label = 0, job_fun = JobFun, jobs = RestJobs,
+ init_data = InitData, regulator = Regulator, scc_to_pid = SCCtoPID}.
collect_result(#state{mode = Mode, active = Active, result = Result,
next_label = NextLabel, init_data = InitData,
+ jobs = JobsLeft, job_fun = JobFun,
regulator = Regulator, scc_to_pid = SCCtoPID} = State) ->
receive
{next_label_request, Estimation, Pid} ->
@@ -148,20 +147,35 @@ collect_result(#state{mode = Mode, active = Active, result = Result,
collect_result(State#state{next_label = NextLabel + Estimation});
{done, Job, Data} ->
NewResult = update_result(Mode, InitData, Job, Data, Result),
+ TypesigOrDataflow = (Mode =:= 'typesig') orelse (Mode =:= 'dataflow'),
case Active of
1 ->
kill_regulator(Regulator),
case Mode of
'compile' ->
{NewResult, NextLabel};
- X when X =:= 'typesig'; X =:= 'dataflow' ->
+ _ when TypesigOrDataflow ->
ets:delete(SCCtoPID),
NewResult;
'warnings' ->
NewResult
end;
N ->
- collect_result(State#state{result = NewResult, active = N - 1})
+ case TypesigOrDataflow of
+ true -> true = ets:delete(SCCtoPID, Job);
+ false -> true
+ end,
+ NewJobsLeft =
+ case JobsLeft of
+ [] -> [];
+ [NewJob|JobsLeft1] ->
+ JobFun(NewJob),
+ JobsLeft1
+ end,
+ NewState = State#state{result = NewResult,
+ jobs = NewJobsLeft,
+ active = N - 1},
+ collect_result(NewState)
end
end.
@@ -177,18 +191,20 @@ update_result(Mode, InitData, Job, Data, Result) ->
end.
-spec sccs_to_pids([scc() | module()], coordinator()) ->
- {[dialyzer_worker:worker()], [scc() | module()]}.
+ [dialyzer_worker:worker()].
sccs_to_pids(SCCs, {_Collector, _Regulator, SCCtoPID}) ->
Fold =
- fun(SCC, {Pids, Unknown}) ->
- try ets:lookup_element(SCCtoPID, SCC, 2) of
- Result -> {[Result|Pids], Unknown}
- catch
- _:_ -> {Pids, [SCC|Unknown]}
- end
+ fun(SCC, Pids) ->
+ %% The SCCs that SCC depends on have always been started.
+ try ets:lookup_element(SCCtoPID, SCC, 2) of
+ Pid when is_pid(Pid) ->
+ [Pid|Pids]
+ catch
+ _:_ -> Pids
+ end
end,
- lists:foldl(Fold, {[], []}, SCCs).
+ lists:foldl(Fold, [], SCCs).
-spec job_done(job(), job_result(), coordinator()) -> ok.
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl
index 9399789464..8367432ac5 100644
--- a/lib/dialyzer/src/dialyzer_dataflow.erl
+++ b/lib/dialyzer/src/dialyzer_dataflow.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%--------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_dataflow.erl
@@ -145,7 +138,7 @@
%%--------------------------------------------------------------------
--type fun_types() :: dict:dict(label(), type()).
+-type fun_types() :: orddict:orddict(label(), type()).
-spec get_warnings(cerl:c_module(), dialyzer_plt:plt(),
dialyzer_callgraph:callgraph(),
@@ -198,19 +191,19 @@ analyze_loop(State) ->
{ArgTypes, IsCalled} = state__get_args_and_status(Fun, NewState1),
case not IsCalled of
true ->
- ?debug("Not handling (not called) ~w: ~s\n",
+ ?debug("Not handling (not called) ~w: ~ts\n",
[NewState1#state.curr_fun,
t_to_string(t_product(ArgTypes))]),
analyze_loop(NewState1);
false ->
case state__fun_env(Fun, NewState1) of
none ->
- ?debug("Not handling (no env) ~w: ~s\n",
+ ?debug("Not handling (no env) ~w: ~ts\n",
[NewState1#state.curr_fun,
t_to_string(t_product(ArgTypes))]),
analyze_loop(NewState1);
Map ->
- ?debug("Handling fun ~p: ~s\n",
+ ?debug("Handling fun ~p: ~ts\n",
[NewState1#state.curr_fun,
t_to_string(state__fun_type(Fun, NewState1))]),
Vars = cerl:fun_vars(Fun),
@@ -229,7 +222,7 @@ analyze_loop(State) ->
end,
{NewState4, _Map2, BodyType} =
traverse(Body, Map1, NewState3),
- ?debug("Done analyzing: ~w:~s\n",
+ ?debug("Done analyzing: ~w:~ts\n",
[NewState1#state.curr_fun,
t_to_string(t_fun(ArgTypes, BodyType))]),
NewState5 =
@@ -239,7 +232,7 @@ analyze_loop(State) ->
end,
NewState6 =
state__update_fun_entry(Fun, ArgTypes, BodyType, NewState5),
- ?debug("done adding stuff for ~w\n",
+ ?debug("done adding stuff for ~tw\n",
[state__lookup_name(get_label(Fun), State)]),
analyze_loop(NewState6)
end
@@ -494,23 +487,23 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left],
end,
?debug("--------------------------------------------------------\n", []),
- ?debug("Fun: ~p\n", [state__lookup_name(Fun, State)]),
+ ?debug("Fun: ~tp\n", [state__lookup_name(Fun, State)]),
?debug("Module ~p\n", [State#state.module]),
- ?debug("CArgs ~s\n", [erl_types:t_to_string(t_product(CArgs))]),
- ?debug("ArgTypes ~s\n", [erl_types:t_to_string(t_product(ArgTypes))]),
- ?debug("BifArgs ~p\n", [erl_types:t_to_string(t_product(BifArgs))]),
+ ?debug("CArgs ~ts\n", [erl_types:t_to_string(t_product(CArgs))]),
+ ?debug("ArgTypes ~ts\n", [erl_types:t_to_string(t_product(ArgTypes))]),
+ ?debug("BifArgs ~tp\n", [erl_types:t_to_string(t_product(BifArgs))]),
NewArgsSig = t_inf_lists(SigArgs, ArgTypes, Opaques),
- ?debug("SigArgs ~s\n", [erl_types:t_to_string(t_product(SigArgs))]),
- ?debug("NewArgsSig: ~s\n", [erl_types:t_to_string(t_product(NewArgsSig))]),
+ ?debug("SigArgs ~ts\n", [erl_types:t_to_string(t_product(SigArgs))]),
+ ?debug("NewArgsSig: ~ts\n", [erl_types:t_to_string(t_product(NewArgsSig))]),
NewArgsContract = t_inf_lists(CArgs, ArgTypes, Opaques),
- ?debug("NewArgsContract: ~s\n",
+ ?debug("NewArgsContract: ~ts\n",
[erl_types:t_to_string(t_product(NewArgsContract))]),
NewArgsBif = t_inf_lists(BifArgs, ArgTypes, Opaques),
- ?debug("NewArgsBif: ~s\n", [erl_types:t_to_string(t_product(NewArgsBif))]),
+ ?debug("NewArgsBif: ~ts\n", [erl_types:t_to_string(t_product(NewArgsBif))]),
NewArgTypes0 = t_inf_lists(NewArgsSig, NewArgsContract),
NewArgTypes = t_inf_lists(NewArgTypes0, NewArgsBif, Opaques),
- ?debug("NewArgTypes ~s\n", [erl_types:t_to_string(t_product(NewArgTypes))]),
+ ?debug("NewArgTypes ~ts\n", [erl_types:t_to_string(t_product(NewArgTypes))]),
?debug("\n", []),
BifRet = BifRange(NewArgTypes),
@@ -518,18 +511,18 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left],
RetWithoutContr = t_inf(SigRange, BifRet),
RetWithoutLocal = t_inf(ContrRet, RetWithoutContr),
- ?debug("RetWithoutContr: ~s\n",[erl_types:t_to_string(RetWithoutContr)]),
- ?debug("RetWithoutLocal: ~s\n", [erl_types:t_to_string(RetWithoutLocal)]),
- ?debug("BifRet: ~s\n", [erl_types:t_to_string(BifRange(NewArgTypes))]),
- ?debug("SigRange: ~s\n", [erl_types:t_to_string(SigRange)]),
- ?debug("ContrRet: ~s\n", [erl_types:t_to_string(ContrRet)]),
- ?debug("LocalRet: ~s\n", [erl_types:t_to_string(LocalRet)]),
+ ?debug("RetWithoutContr: ~ts\n",[erl_types:t_to_string(RetWithoutContr)]),
+ ?debug("RetWithoutLocal: ~ts\n", [erl_types:t_to_string(RetWithoutLocal)]),
+ ?debug("BifRet: ~ts\n", [erl_types:t_to_string(BifRange(NewArgTypes))]),
+ ?debug("SigRange: ~ts\n", [erl_types:t_to_string(SigRange)]),
+ ?debug("ContrRet: ~ts\n", [erl_types:t_to_string(ContrRet)]),
+ ?debug("LocalRet: ~ts\n", [erl_types:t_to_string(LocalRet)]),
State1 =
case is_race_analysis_enabled(State) of
true ->
Ann = cerl:get_ann(Tree),
- File = get_file(Ann),
+ File = get_file(Ann, State),
Line = abs(get_line(Ann)),
dialyzer_races:store_race_call(Fun, ArgTypes, Args,
{File, Line}, State);
@@ -603,7 +596,7 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left],
false -> t_inf(RetWithoutLocal, LocalRet)
end,
NewAccRet = t_sup(AccRet, TotalRet),
- ?debug("NewAccRet: ~s\n", [t_to_string(NewAccRet)]),
+ ?debug("NewAccRet: ~ts\n", [t_to_string(NewAccRet)]),
{NewWarnings, State4} = state__remove_added_warnings(State, State3),
{HowMany, OldWarnings} = Warns,
NewWarns =
@@ -978,12 +971,21 @@ handle_case(Tree, Map, State) ->
false -> State1
end,
Map2 = join_maps_begin(Map1),
- {MapList, State3, Type} =
+ {MapList, State3, Type, Warns} =
handle_clauses(Clauses, Arg, ArgType, ArgType, State2,
- [], Map2, [], []),
+ [], Map2, [], [], []),
+ %% Non-Erlang BEAM languages, such as Elixir, expand language constructs
+ %% into case statements. In that case, we do not want to warn on
+ %% individual clauses not matching unless none of them can.
+ SupressForced = is_compiler_generated(cerl:get_ann(Tree))
+ andalso not (t_is_none(Type)),
+ State4 = lists:foldl(fun({T,R,M,F}, S) ->
+ state__add_warning(
+ S,T,R,M,F andalso (not SupressForced))
+ end, State3, Warns),
Map3 = join_maps_end(MapList, Map2),
debug_pp_map(Map3),
- {State3, Map3, Type}
+ {State4, Map3, Type}
end.
%%----------------------------------------
@@ -1082,22 +1084,24 @@ handle_receive(Tree, Map, State) ->
RaceListSize + 1, State);
false -> State
end,
- {MapList, State2, ReceiveType} =
+ {MapList, State2, ReceiveType, Warns} =
handle_clauses(Clauses, ?no_arg, t_any(), t_any(), State1, [], Map,
- [], []),
+ [], [], []),
+ State3 = lists:foldl(fun({T,R,M,F}, S) -> state__add_warning(S,T,R,M,F) end,
+ State2, Warns),
Map1 = join_maps(MapList, Map),
- {State3, Map2, TimeoutType} = traverse(Timeout, Map1, State2),
- Opaques = State3#state.opaques,
+ {State4, Map2, TimeoutType} = traverse(Timeout, Map1, State3),
+ Opaques = State4#state.opaques,
case (t_is_atom(TimeoutType, Opaques) andalso
(t_atom_vals(TimeoutType, Opaques) =:= ['infinity'])) of
true ->
- {State3, Map2, ReceiveType};
+ {State4, Map2, ReceiveType};
false ->
Action = cerl:receive_action(Tree),
- {State4, Map3, ActionType} = traverse(Action, Map, State3),
+ {State5, Map3, ActionType} = traverse(Action, Map, State4),
Map4 = join_maps([Map3, Map1], Map),
Type = t_sup(ReceiveType, ActionType),
- {State4, Map4, Type}
+ {State5, Map4, Type}
end.
%%----------------------------------------
@@ -1200,7 +1204,7 @@ handle_tuple(Tree, Map, State) ->
TagVal = cerl:atom_val(Tag),
case state__lookup_record(TagVal, length(Left), State1) of
error -> {State1, Map1, TupleType};
- {ok, RecType} ->
+ {ok, RecType, FieldNames} ->
InfTupleType = t_inf(RecType, TupleType),
case t_is_none(InfTupleType) of
true ->
@@ -1221,10 +1225,13 @@ handle_tuple(Tree, Map, State) ->
Tree, Msg),
{State2, Map1, t_none()};
{error, opaque, ErrorPat, ErrorType, OpaqueType} ->
+ OpaqueStr = format_type(OpaqueType, State1),
+ Name = field_name(Elements, ErrorPat, FieldNames),
Msg = {opaque_match,
- [format_patterns(ErrorPat),
- format_type(ErrorType, State1),
- format_type(OpaqueType, State1)]},
+ ["record field" ++ Name ++
+ " declared to be of type " ++
+ format_type(ErrorType, State1),
+ OpaqueStr, OpaqueStr]},
State2 = state__add_warning(State1, ?WARN_OPAQUE,
Tree, Msg),
{State2, Map1, t_none()};
@@ -1241,11 +1248,20 @@ handle_tuple(Tree, Map, State) ->
end
end.
+field_name(Elements, ErrorPat, FieldNames) ->
+ try
+ [Pat] = ErrorPat,
+ Take = lists:takewhile(fun(X) -> X =/= Pat end, Elements),
+ " " ++ format_atom(lists:nth(length(Take), FieldNames))
+ catch
+ _:_ -> ""
+ end.
+
%%----------------------------------------
%% Clauses
%%
handle_clauses([C|Left], Arg, ArgType, OrigArgType, State, CaseTypes, MapIn,
- Acc, ClauseAcc) ->
+ Acc, ClauseAcc, WarnAcc0) ->
IsRaceAnalysisEnabled = is_race_analysis_enabled(State),
State1 =
case IsRaceAnalysisEnabled of
@@ -1258,8 +1274,8 @@ handle_clauses([C|Left], Arg, ArgType, OrigArgType, State, CaseTypes, MapIn,
State);
false -> State
end,
- {State2, ClauseMap, BodyType, NewArgType} =
- do_clause(C, Arg, ArgType, OrigArgType, MapIn, State1),
+ {State2, ClauseMap, BodyType, NewArgType, WarnAcc} =
+ do_clause(C, Arg, ArgType, OrigArgType, MapIn, State1, WarnAcc0),
{NewClauseAcc, State3} =
case IsRaceAnalysisEnabled of
true ->
@@ -1277,9 +1293,9 @@ handle_clauses([C|Left], Arg, ArgType, OrigArgType, State, CaseTypes, MapIn,
false -> {[BodyType|CaseTypes], [ClauseMap|Acc]}
end,
handle_clauses(Left, Arg, NewArgType, OrigArgType, State3,
- NewCaseTypes, MapIn, NewAcc, NewClauseAcc);
+ NewCaseTypes, MapIn, NewAcc, NewClauseAcc, WarnAcc);
handle_clauses([], _Arg, _ArgType, _OrigArgType, State, CaseTypes, _MapIn, Acc,
- ClauseAcc) ->
+ ClauseAcc, WarnAcc) ->
State1 =
case is_race_analysis_enabled(State) of
true ->
@@ -1289,9 +1305,9 @@ handle_clauses([], _Arg, _ArgType, _OrigArgType, State, CaseTypes, _MapIn, Acc,
RaceListSize + 1, State);
false -> State
end,
- {lists:reverse(Acc), State1, t_sup(CaseTypes)}.
+ {lists:reverse(Acc), State1, t_sup(CaseTypes), WarnAcc}.
-do_clause(C, Arg, ArgType0, OrigArgType, Map, State) ->
+do_clause(C, Arg, ArgType0, OrigArgType, Map, State, Warns) ->
Pats = cerl:clause_pats(C),
Guard = cerl:clause_guard(C),
Body = cerl:clause_body(C),
@@ -1319,17 +1335,15 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, State) ->
end,
case BindRes of
{error, ErrorType, NewPats, Type, OpaqueTerm} ->
- ?debug("Failed binding pattern: ~s\nto ~s\n",
+ ?debug("Failed binding pattern: ~ts\nto ~ts\n",
[cerl_prettypr:format(C), format_type(ArgType0, State1)]),
case state__warning_mode(State1) of
false ->
- {State1, Map, t_none(), ArgType0};
+ {State1, Map, t_none(), ArgType0, Warns};
true ->
{Msg, Force} =
case t_is_none(ArgType0) of
true ->
- PatString = format_patterns(Pats),
- PatTypes = [PatString, format_type(OrigArgType, State1)],
%% See if this is covered by an earlier clause or if it
%% simply cannot match
OrigArgTypes =
@@ -1337,17 +1351,27 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, State) ->
true -> Any = t_any(), [Any || _ <- Pats];
false -> t_to_tlist(OrigArgType)
end,
+ PatString = format_patterns(Pats),
+ ArgTypeString = format_type(OrigArgType, State1),
+ BindResOrig =
+ bind_pat_vars(Pats, OrigArgTypes, [], Map1, State1),
Tag =
- case bind_pat_vars(Pats, OrigArgTypes, [], Map1, State1) of
+ case BindResOrig of
{error, bind, _, _, _} -> pattern_match;
{error, record, _, _, _} -> record_match;
{error, opaque, _, _, _} -> opaque_match;
{_, _} -> pattern_match_cov
end,
- {{Tag, PatTypes}, false};
+ PatTypes = case BindResOrig of
+ {error, opaque, _, _, OpaqueType} ->
+ [PatString, ArgTypeString,
+ format_type(OpaqueType, State1)];
+ _ -> [PatString, ArgTypeString]
+ end,
+ {{Tag, PatTypes}, false};
false ->
%% Try to find out if this is a default clause in a list
- %% comprehension and supress this. A real Hack(tm)
+ %% comprehension and suppress this. A real Hack(tm)
Force0 =
case is_compiler_generated(cerl:get_ann(C)) of
true ->
@@ -1403,8 +1427,7 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, State) ->
{record_match, _} -> ?WARN_MATCHING;
{pattern_match_cov, _} -> ?WARN_MATCHING
end,
- {state__add_warning(State1, WarnType, C, Msg, Force),
- Map, t_none(), ArgType0}
+ {State1, Map, t_none(), ArgType0, [{WarnType, C, Msg, Force}|Warns]}
end;
{Map2, PatTypes} ->
Map3 =
@@ -1428,7 +1451,7 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, State) ->
end,
case bind_guard(Guard, Map3, State1) of
{error, Reason} ->
- ?debug("Failed guard: ~s\n",
+ ?debug("Failed guard: ~ts\n",
[cerl_prettypr:format(C, [{hook, cerl_typean:pp_hook()}])]),
PatString = format_patterns(Pats),
DefaultMsg =
@@ -1437,9 +1460,9 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, State) ->
false ->
{guard_fail_pat, [PatString, format_type(ArgType0, State1)]}
end,
- State2 =
+ Warn =
case Reason of
- none -> state__add_warning(State1, ?WARN_MATCHING, C, DefaultMsg);
+ none -> {?WARN_MATCHING, C, DefaultMsg, false};
{FailGuard, Msg} ->
case is_compiler_generated(cerl:get_ann(FailGuard)) of
false ->
@@ -1448,15 +1471,15 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map, State) ->
{neg_guard_fail, _} -> ?WARN_MATCHING;
{opaque_guard, _} -> ?WARN_OPAQUE
end,
- state__add_warning(State1, WarnType, FailGuard, Msg);
+ {WarnType, FailGuard, Msg, false};
true ->
- state__add_warning(State1, ?WARN_MATCHING, C, Msg)
+ {?WARN_MATCHING, C, Msg, false}
end
end,
- {State2, Map, t_none(), NewArgType};
+ {State1, Map, t_none(), NewArgType, [Warn|Warns]};
Map4 ->
{RetState, RetMap, BodyType} = traverse(Body, Map4, State1),
- {RetState, RetMap, BodyType, NewArgType}
+ {RetState, RetMap, BodyType, NewArgType, Warns}
end
end.
@@ -1509,7 +1532,7 @@ bind_pat_vars_reverse(Pats, Types, Acc, Map, State) ->
end.
bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
- ?debug("Binding pat: ~w to ~s\n", [cerl:type(Pat), format_type(Type, State)]
+ ?debug("Binding pat: ~tw to ~ts\n", [cerl:type(Pat), format_type(Type, State)]
),
Opaques = State#state.opaques,
{NewMap, TypeOut} =
@@ -1622,7 +1645,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
TagAtom = cerl:atom_val(Tag),
case state__lookup_record(TagAtom, length(Left), State) of
error -> {false, t_tuple(length(Es))};
- {ok, Record} ->
+ {ok, Record, _FieldNames} ->
[_Head|AnyTail] = [t_any() || _ <- Es],
UntypedRecord = t_tuple([t_atom(TagAtom)|AnyTail]),
{not t_is_equal(Record, UntypedRecord), Record}
@@ -1807,7 +1830,7 @@ bind_guard(Guard, Map, State) ->
end.
bind_guard(Guard, Map, Env, Eval, State) ->
- ?debug("Handling ~w guard: ~s\n",
+ ?debug("Handling ~tw guard: ~ts\n",
[Eval, cerl_prettypr:format(Guard, [{noann, true}])]),
case cerl:type(Guard) of
binary ->
@@ -1986,7 +2009,7 @@ handle_guard_type_test(Guard, F, Map, Env, Eval, State) ->
?debug("Type test: ~w failed\n", [F]),
signal_guard_fail(Eval, Guard, [ArgType], State);
{ok, NewArgType, Ret} ->
- ?debug("Type test: ~w succeeded, NewType: ~s, Ret: ~s\n",
+ ?debug("Type test: ~w succeeded, NewType: ~ts, Ret: ~ts\n",
[F, t_to_string(NewArgType), t_to_string(Ret)]),
{enter_type(Arg, NewArgType, Map1), Ret}
end.
@@ -2150,7 +2173,7 @@ handle_guard_is_record(Guard, Map, Env, Eval, State) ->
TupleType =
case state__lookup_record(Tag, ArityMin1, State) of
error -> Tuple;
- {ok, Prototype} -> Prototype
+ {ok, Prototype, _FieldNames} -> Prototype
end,
Type = t_inf(TupleType, RecType, State#state.opaques),
case t_is_none(Type) of
@@ -2272,8 +2295,8 @@ handle_guard_eqeq(Guard, Map, Env, Eval, State) ->
bind_eqeq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State) ->
{Map1, Type1} = bind_guard(Arg1, Map, Env, dont_know, State),
{Map2, Type2} = bind_guard(Arg2, Map1, Env, dont_know, State),
- ?debug("Types are:~s =:= ~s\n", [t_to_string(Type1),
- t_to_string(Type2)]),
+ ?debug("Types are:~ts =:= ~ts\n", [t_to_string(Type1),
+ t_to_string(Type2)]),
Opaques = State#state.opaques,
Inf = t_inf(Type1, Type2, Opaques),
case t_is_none(Inf) of
@@ -2600,7 +2623,7 @@ bind_guard_case_clauses(Arg, Clauses, Map0, Env, Eval, State) ->
Map = join_maps_begin(Map0),
{GenMap, GenArgType} = bind_guard(Arg, Map, Env, dont_know, State),
bind_guard_case_clauses(GenArgType, GenMap, Arg, Clauses1, Map, Env, Eval,
- t_none(), [], State).
+ t_none(), [], [], State).
filter_fail_clauses([Clause|Left]) ->
case (cerl:clause_pats(Clause) =:= []) of
@@ -2619,7 +2642,7 @@ filter_fail_clauses([]) ->
[].
bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left],
- Map, Env, Eval, AccType, AccMaps, State) ->
+ Map, Env, Eval, AccType, AccMaps, Throws, State) ->
Pats = cerl:clause_pats(Clause),
{NewMap0, ArgType} =
case Pats of
@@ -2663,9 +2686,9 @@ bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left],
case (NewMap1 =:= none) orelse t_is_none(GenArgType) of
true ->
bind_guard_case_clauses(NewGenArgType, GenMap, ArgExpr, Left, Map, Env,
- Eval, AccType, AccMaps, State);
+ Eval, AccType, AccMaps, Throws, State);
false ->
- {NewAccType, NewAccMaps} =
+ {NewAccType, NewAccMaps, NewThrows} =
try
{NewMap2, GuardType} = bind_guard(Guard, NewMap1, Env, pos, State),
case t_is_none(t_inf(t_atom(true), GuardType)) of
@@ -2689,17 +2712,26 @@ bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left],
dont_know ->
ok
end,
- {t_sup(AccType, CType), [NewMap3|AccMaps]}
+ {t_sup(AccType, CType), [NewMap3|AccMaps], Throws}
catch
- throw:{fail, _What} -> {AccType, AccMaps}
+ throw:{fail, Reason} ->
+ Throws1 = case Reason of
+ none -> Throws;
+ _ -> Throws ++ [Reason]
+ end,
+ {AccType, AccMaps, Throws1}
end,
bind_guard_case_clauses(NewGenArgType, GenMap, ArgExpr, Left, Map, Env,
- Eval, NewAccType, NewAccMaps, State)
+ Eval, NewAccType, NewAccMaps, NewThrows, State)
end;
bind_guard_case_clauses(_GenArgType, _GenMap, _ArgExpr, [], Map, _Env, _Eval,
- AccType, AccMaps, _State) ->
+ AccType, AccMaps, Throws, _State) ->
case t_is_none(AccType) of
- true -> throw({fail, none});
+ true ->
+ case Throws of
+ [Throw|_] -> throw({fail, Throw});
+ [] -> throw({fail, none})
+ end;
false -> {join_maps_end(AccMaps, Map), AccType}
end.
@@ -2808,7 +2840,7 @@ enter_type(Key, Val, MS) ->
?debug("Binding ~p to ~p\n", [KeyLabel, NewKey]),
enter_type(NewKey, Val, MS);
error ->
- ?debug("Entering ~p :: ~s\n", [KeyLabel, t_to_string(Val)]),
+ ?debug("Entering ~p :: ~ts\n", [KeyLabel, t_to_string(Val)]),
case maps:find(KeyLabel, Map) of
{ok, Value} ->
case erl_types:t_is_equal(Val, Value) of
@@ -2908,7 +2940,7 @@ debug_pp_map(#map{map = Map}=MapRec) ->
Keys = maps:keys(Map),
io:format("Map:\n", []),
lists:foreach(fun (Key) ->
- io:format("\t~w :: ~s\n",
+ io:format("\t~w :: ~ts\n",
[Key, t_to_string(lookup_type(Key, MapRec))])
end, Keys),
ok.
@@ -3059,21 +3091,23 @@ state__add_warning(#state{warnings = Warnings, warning_mode = true} = State,
Ann = cerl:get_ann(Tree),
case Force of
true ->
- WarningInfo = {get_file(Ann),
+ WarningInfo = {get_file(Ann, State),
abs(get_line(Ann)),
State#state.curr_fun},
Warn = {Tag, WarningInfo, Msg},
- ?debug("MSG ~s\n", [dialyzer:format_warning(Warn)]),
+ ?debug("MSG ~ts\n", [dialyzer:format_warning(Warn)]),
State#state{warnings = [Warn|Warnings]};
false ->
case is_compiler_generated(Ann) of
true -> State;
false ->
- WarningInfo = {get_file(Ann), get_line(Ann), State#state.curr_fun},
+ WarningInfo = {get_file(Ann, State),
+ get_line(Ann),
+ State#state.curr_fun},
Warn = {Tag, WarningInfo, Msg},
case Tag of
?WARN_CONTRACT_RANGE -> ok;
- _ -> ?debug("MSG ~s\n", [dialyzer:format_warning(Warn)])
+ _ -> ?debug("MSG ~ts\n", [dialyzer:format_warning(Warn)])
end,
State#state{warnings = [Warn|Warnings]}
end
@@ -3197,7 +3231,8 @@ state__lookup_record(Tag, Arity, #state{records = Records}) ->
RecType =
t_tuple([t_atom(Tag)|
[FieldType || {_FieldName, _Abstr, FieldType} <- Fields]]),
- {ok, RecType};
+ FieldNames = [FieldName || {FieldName, _Abstr, _FieldType} <- Fields],
+ {ok, RecType, FieldNames};
error ->
error
end.
@@ -3282,7 +3317,9 @@ state__clean_not_called(#state{fun_tab = FunTab} = State) ->
state__all_fun_types(State) ->
#state{fun_tab = FunTab} = state__clean_not_called(State),
Tab1 = dict:erase(top, FunTab),
- dict:map(fun(_Fun, {Args, Ret}) -> t_fun(Args, Ret)end, Tab1).
+ List = [{Fun, t_fun(Args, Ret)} ||
+ {Fun, {Args, Ret}} <- dict:to_list(Tab1)],
+ orddict:from_list(List).
state__fun_type(Fun, #state{fun_tab = FunTab}) ->
Label =
@@ -3316,14 +3353,14 @@ state__update_fun_entry(Tree, ArgTypes, Out0,
SameOut = t_is_equal(OldOut, Out),
if
SameArgs, SameOut ->
- ?debug("Fixpoint for ~w: ~s\n",
+ ?debug("Fixpoint for ~tw: ~ts\n",
[state__lookup_name(Fun, State),
t_to_string(t_fun(ArgTypes, Out))]),
State;
true ->
%% Can only happen in self-recursive functions.
NewEntry = {OldArgTypes, Out},
- ?debug("New Entry for ~w: ~s\n",
+ ?debug("New Entry for ~tw: ~ts\n",
[state__lookup_name(Fun, State),
t_to_string(t_fun(OldArgTypes, Out))]),
NewFunTab = dict:store(Fun, NewEntry, FunTab),
@@ -3345,7 +3382,7 @@ state__add_work_from_fun(Tree, #state{callgraph = Callgraph,
|| MFA <- MFAList],
%% Must filter the result for results in this module.
FilteredList = [L || {ok, L} <- LabelList, dict:is_key(L, TreeMap)],
- ?debug("~w: Will try to add:~w\n",
+ ?debug("~tw: Will try to add:~tw\n",
[state__lookup_name(Label, State), MFAList]),
lists:foldl(fun(L, AccState) ->
state__add_work(L, AccState)
@@ -3392,7 +3429,7 @@ state__fun_info(Fun, #state{callgraph = CG, fun_tab = FunTab, plt = PLT}) ->
{not_handled, {_Args, Ret}} -> Ret;
{_Args, Ret} -> Ret
end,
- ?debug("LocalRet: ~s\n", [t_to_string(LocalRet)]),
+ ?debug("LocalRet: ~ts\n", [t_to_string(LocalRet)]),
{Fun, Sig, Contract, LocalRet}.
forward_args(Fun, ArgTypes, #state{work = Work, fun_tab = FunTab} = State) ->
@@ -3410,7 +3447,7 @@ forward_args(Fun, ArgTypes, #state{work = Work, fun_tab = FunTab} = State) ->
NewArgTypes = [t_sup(X, Y) ||
{X, Y} <- lists:zip(ArgTypes, OldArgTypes)],
NewWork = add_work(Fun, Work),
- ?debug("~w: forwarding args ~s\n",
+ ?debug("~tw: forwarding args ~ts\n",
[state__lookup_name(Fun, State),
t_to_string(t_product(NewArgTypes))]),
NewFunTab = dict:store(Fun, {NewArgTypes, OldOut}, FunTab),
@@ -3467,6 +3504,12 @@ state__put_races(Races, State) ->
state__records_only(#state{records = Records}) ->
#state{records = Records}.
+-spec state__translate_file(file:filename(), state()) -> file:filename().
+
+state__translate_file(FakeFile, State) ->
+ #state{codeserver = CodeServer, module = Module} = State,
+ dialyzer_codeserver:translate_fake_file(CodeServer, Module, FakeFile).
+
%%% ===========================================================================
%%%
%%% Races
@@ -3538,9 +3581,11 @@ get_line([Line|_]) when is_integer(Line) -> Line;
get_line([_|Tail]) -> get_line(Tail);
get_line([]) -> -1.
-get_file([]) -> [];
-get_file([{file, File}|_]) -> File;
-get_file([_|Tail]) -> get_file(Tail).
+get_file([], _State) -> [];
+get_file([{file, FakeFile}|_], State) ->
+ state__translate_file(FakeFile, State);
+get_file([_|Tail], State) ->
+ get_file(Tail, State).
is_compiler_generated(Ann) ->
lists:member(compiler_generated, Ann) orelse (get_line(Ann) < 1).
@@ -3575,6 +3620,7 @@ format_arg(Arg) ->
case cerl:var_name(Arg) of
Atom when is_atom(Atom) ->
case atom_to_list(Atom) of
+ "@"++_ -> Default;
"cor"++_ -> Default;
"rec"++_ -> Default;
Name -> Name ++ "::"
@@ -3635,6 +3681,7 @@ map_pats(Pats) ->
case cerl:var_name(Tree) of
Atom when is_atom(Atom) ->
case atom_to_list(Atom) of
+ "@"++_ -> cerl:c_var('');
"cor"++_ -> cerl:c_var('');
"rec"++_ -> cerl:c_var('');
_ -> cerl:set_ann(Tree, [])
@@ -3650,6 +3697,9 @@ map_pats(Pats) ->
fold_literals(TreeList) ->
[cerl:fold_literal(Tree) || Tree <- TreeList].
+format_atom(A) ->
+ format_cerl(cerl:c_atom(A)).
+
type(Tree) ->
Folded = cerl:fold_literal(Tree),
case cerl:type(Folded) of
diff --git a/lib/dialyzer/src/dialyzer_dep.erl b/lib/dialyzer/src/dialyzer_dep.erl
index 273c05c54c..36cdc0876c 100644
--- a/lib/dialyzer/src/dialyzer_dep.erl
+++ b/lib/dialyzer/src/dialyzer_dep.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_dep.erl
diff --git a/lib/dialyzer/src/dialyzer_explanation.erl b/lib/dialyzer/src/dialyzer_explanation.erl
index 968f8df78e..10b3ef8ea5 100644
--- a/lib/dialyzer/src/dialyzer_explanation.erl
+++ b/lib/dialyzer/src/dialyzer_explanation.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
-%%
+%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_explanation.erl
@@ -50,4 +43,3 @@ expl_loop(Parent, CServer, Plt) ->
send_explanation(Parent, Expl) ->
Parent ! {self(), explanation, Expl},
ok.
-
diff --git a/lib/dialyzer/src/dialyzer_gui_wx.erl b/lib/dialyzer/src/dialyzer_gui_wx.erl
index 30d2bdeca4..538327d4d1 100644
--- a/lib/dialyzer/src/dialyzer_gui_wx.erl
+++ b/lib/dialyzer/src/dialyzer_gui_wx.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%------------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-----------------------------------------------------------------------
%%% File : dialyzer_gui_wx.erl
@@ -310,7 +303,7 @@ createWarningsMenu() ->
addCheckedItem(WarningsMenu, ?menuID_WARN_FAIL_FUN_CALLS,
"Failing function calls"),
addCheckedItem(WarningsMenu, ?menuID_WARN_BAD_FUN, "Bad fun applications"),
- addCheckedItem(WarningsMenu, ?menuID_WARN_OPAQUE, "Opaqueness violations"),
+ addCheckedItem(WarningsMenu, ?menuID_WARN_OPAQUE, "Opacity violations"),
addCheckedItem(WarningsMenu, ?menuID_WARN_LIST_CONSTR,
"Improper list constructions"),
addCheckedItem(WarningsMenu, ?menuID_WARN_UNUSED_FUN, "Unused functions"),
@@ -476,18 +469,18 @@ gui_loop(#gui_state{backend_pid = BackendPid, doc_plt = DocPlt,
Msg = io_lib:format("The following functions are called "
"but type information about them is not available.\n"
"The analysis might get more precise by including "
- "the modules containing these functions:\n\n\t~p\n",
+ "the modules containing these functions:\n\n\t~tp\n",
[ExtCalls]),
free_editor(State,"Analysis Done", Msg),
gui_loop(State);
{BackendPid, ext_types, ExtTypes} ->
- Map = fun({M,F,A}) -> io_lib:format("~p:~p/~p",[M,F,A]) end,
+ Map = fun({M,F,A}) -> io_lib:format("~tp:~tp/~p",[M,F,A]) end,
ExtTypeString = string:join(lists:map(Map, ExtTypes), "\n"),
Msg = io_lib:format("The following remote types are being used "
"but information about them is not available.\n"
"The analysis might get more precise by including "
"the modules containing these types and making sure "
- "that they are exported:\n~s\n", [ExtTypeString]),
+ "that they are exported:\n~ts\n", [ExtTypeString]),
free_editor(State, "Analysis done", Msg),
gui_loop(State);
{BackendPid, log, LogMsg} ->
@@ -505,8 +498,9 @@ gui_loop(#gui_state{backend_pid = BackendPid, doc_plt = DocPlt,
end,
ExplanationPid = spawn_link(Fun),
gui_loop(State#gui_state{expl_pid = ExplanationPid});
- {BackendPid, done, _NewPlt, NewDocPlt} ->
+ {BackendPid, done, NewPlt, NewDocPlt} ->
message(State, "Analysis done"),
+ dialyzer_plt:delete(NewPlt),
config_gui_stop(State),
gui_loop(State#gui_state{doc_plt = NewDocPlt});
{'EXIT', BackendPid, {error, Reason}} ->
@@ -514,7 +508,7 @@ gui_loop(#gui_state{backend_pid = BackendPid, doc_plt = DocPlt,
config_gui_stop(State),
gui_loop(State);
{'EXIT', BackendPid, Reason} when Reason =/= 'normal' ->
- free_editor(State, ?DIALYZER_ERROR_TITLE, io_lib:format("~p", [Reason])),
+ free_editor(State, ?DIALYZER_ERROR_TITLE, io_lib:format("~tp", [Reason])),
config_gui_stop(State),
gui_loop(State)
end.
@@ -932,7 +926,7 @@ include_dialog(#gui_state{gui = Wx, frame = Frame, options = Options}) ->
wxButton:connect(DeleteAllButton, command_button_clicked),
wxButton:connect(Ok, command_button_clicked),
wxButton:connect(Cancel, command_button_clicked),
- Dirs = [io_lib:format("~s", [X]) || X <- Options#options.include_dirs],
+ Dirs = [io_lib:format("~ts", [X]) || X <- Options#options.include_dirs],
wxListBox:set(Box, Dirs),
Layout = wxBoxSizer:new(?wxVERTICAL),
Buttons = wxBoxSizer:new(?wxHORIZONTAL),
@@ -1124,13 +1118,13 @@ handle_help(State, Title, Txt) ->
case file:open(FileName, [read]) of
{error, Reason} ->
error_sms(State,
- io_lib:format("Could not find doc/~s file!\n\n ~p",
+ io_lib:format("Could not find doc/~ts file!\n\n ~tp",
[Txt, Reason]));
{ok, _Handle} ->
case file:read_file(FileName) of
{error, Reason} ->
error_sms(State,
- io_lib:format("Could not read doc/~s file!\n\n ~p",
+ io_lib:format("Could not read doc/~ts file!\n\n ~tp",
[Txt, Reason]));
{ok, Binary} ->
Contents = binary_to_list(Binary),
@@ -1229,7 +1223,7 @@ update_explanation(#gui_state{explanation_box = Box}, Explanation) ->
wxTextCtrl:appendText(Box, ExplString).
format_explanation({function_return, {M, F, A}, NewList}) ->
- io_lib:format("The function ~p: ~p/~p returns ~p\n",
+ io_lib:format("The function ~w:~tw/~w returns ~ts\n",
[M, F, A, erl_types:t_to_string(NewList)]);
format_explanation(Explanation) ->
io_lib:format("~p\n", [Explanation]).
diff --git a/lib/dialyzer/src/dialyzer_gui_wx.hrl b/lib/dialyzer/src/dialyzer_gui_wx.hrl
index e81eeb1ab5..fe763a9abc 100644
--- a/lib/dialyzer/src/dialyzer_gui_wx.hrl
+++ b/lib/dialyzer/src/dialyzer_gui_wx.hrl
@@ -1,3 +1,15 @@
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
-include_lib("wx/include/wx.hrl").
diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl
index add660eae9..03040f8e38 100644
--- a/lib/dialyzer/src/dialyzer_options.erl
+++ b/lib/dialyzer/src/dialyzer_options.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -16,16 +12,9 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-
-%%%----------------------------------------------------------------------
-%%% File : dialyzer_options.erl
-%%% Authors : Richard Carlsson <[email protected]>
-%%% Description : Provides a better way to start Dialyzer from a script.
-%%%
-%%% Created : 17 Oct 2004 by Richard Carlsson <[email protected]>
-%%%----------------------------------------------------------------------
+%% @copyright 2004 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
+%% @doc Provides a better way to start Dialyzer from a script.
-module(dialyzer_options).
@@ -123,7 +112,7 @@ adapt_get_warnings(Opts = #options{analysis_type = Mode,
-spec bad_option(string(), term()) -> no_return().
bad_option(String, Term) ->
- Msg = io_lib:format("~s: ~P", [String, Term, 25]),
+ Msg = io_lib:format("~ts: ~tP", [String, Term, 25]),
throw({dialyzer_options_error, lists:flatten(Msg)}).
build_options([{OptName, undefined}|Rest], Options) when is_atom(OptName) ->
@@ -288,6 +277,9 @@ assert_solvers([Term|_]) ->
-spec build_warnings([atom()], dial_warn_tags()) -> dial_warn_tags().
+%% The warning options are checked by the code linter.
+%% The function erl_lint:is_module_dialyzer_option/1 must
+%% be updated if options are added or removed.
build_warnings([Opt|Opts], Warnings) ->
NewWarnings =
case Opt of
diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl
index cf2f0e919e..47994fc35b 100644
--- a/lib/dialyzer/src/dialyzer_plt.erl
+++ b/lib/dialyzer/src/dialyzer_plt.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_plt.erl
@@ -38,15 +31,15 @@
included_files/1,
from_file/1,
get_default_plt/0,
- get_types/1,
+ get_module_types/2,
get_exported_types/1,
- %% insert/3,
insert_list/2,
insert_contract_list/2,
insert_callbacks/2,
insert_types/2,
insert_exported_types/2,
lookup/2,
+ is_contract/2,
lookup_contract/2,
lookup_callbacks/2,
lookup_module/2,
@@ -57,8 +50,7 @@
get_specs/1,
get_specs/4,
to_file/4,
- get_mini_plt/1,
- restore_full_plt/2
+ delete/1
]).
%% Debug utilities
@@ -66,6 +58,8 @@
-export_type([plt/0, plt_info/0]).
+-include_lib("stdlib/include/ms_transform.hrl").
+
%%----------------------------------------------------------------------
-type mod_deps() :: dialyzer_callgraph:mod_deps().
@@ -81,18 +75,16 @@
%%----------------------------------------------------------------------
--record(plt, {info = table_new() :: dict:dict(),
- types = table_new() :: dict:dict(),
- contracts = table_new() :: dict:dict(),
- callbacks = table_new() :: dict:dict(),
- exported_types = sets:new() :: sets:set()}).
-
--record(mini_plt, {info :: ets:tid(),
- contracts :: ets:tid(),
- callbacks :: ets:tid()
- }).
+-record(plt, {info :: ets:tid(), %% {mfa() | integer(), ret_args_types()}
+ types :: ets:tid(), %% {module(), erl_types:type_table()}
+ contracts :: ets:tid(), %% {mfa(), #contract{}}
+ callbacks :: ets:tid(), %% {module(),
+ %% [{mfa(),
+ %% dialyzer_contracts:file_contract()}]
+ exported_types :: ets:tid() %% {module(), sets:set()}
+ }).
--opaque plt() :: #plt{} | #mini_plt{}.
+-opaque plt() :: #plt{}.
-include("dialyzer.hrl").
@@ -114,7 +106,17 @@
-spec new() -> plt().
new() ->
- #plt{}.
+ [ETSInfo, ETSContracts] =
+ [ets:new(Name, [public]) ||
+ Name <- [plt_info, plt_contracts]],
+ [ETSTypes, ETSCallbacks, ETSExpTypes] =
+ [ets:new(Name, [compressed, public]) ||
+ Name <- [plt_types, plt_callbacks, plt_exported_types]],
+ #plt{info = ETSInfo,
+ types = ETSTypes,
+ contracts = ETSContracts,
+ callbacks = ETSCallbacks,
+ exported_types = ETSExpTypes}.
-spec delete_module(plt(), atom()) -> plt().
@@ -125,50 +127,55 @@ delete_module(#plt{info = Info, types = Types,
#plt{info = table_delete_module(Info, Mod),
types = table_delete_module2(Types, Mod),
contracts = table_delete_module(Contracts, Mod),
- callbacks = table_delete_module(Callbacks, Mod),
+ callbacks = table_delete_module2(Callbacks, Mod),
exported_types = table_delete_module1(ExpTypes, Mod)}.
-spec delete_list(plt(), [mfa() | integer()]) -> plt().
-delete_list(#plt{info = Info, types = Types,
- contracts = Contracts,
- callbacks = Callbacks,
- exported_types = ExpTypes}, List) ->
- #plt{info = table_delete_list(Info, List),
- types = Types,
- contracts = table_delete_list(Contracts, List),
- callbacks = Callbacks,
- exported_types = ExpTypes}.
+delete_list(#plt{info = Info,
+ contracts = Contracts}=Plt, List) ->
+ Plt#plt{info = ets_table_delete_list(Info, List),
+ contracts = ets_table_delete_list(Contracts, List)}.
-spec insert_contract_list(plt(), dialyzer_contracts:plt_contracts()) -> plt().
-insert_contract_list(#mini_plt{contracts = Contracts} = PLT, List) ->
+insert_contract_list(#plt{contracts = Contracts} = PLT, List) ->
true = ets:insert(Contracts, List),
PLT.
-spec insert_callbacks(plt(), dialyzer_codeserver:codeserver()) -> plt().
insert_callbacks(#plt{callbacks = Callbacks} = Plt, Codeserver) ->
- List = dialyzer_codeserver:get_callbacks(Codeserver),
- Plt#plt{callbacks = table_insert_list(Callbacks, List)}.
+ CallbacksList = dialyzer_codeserver:get_callbacks(Codeserver),
+ CallbacksByModule =
+ [{M, [Cb || {{M1,_,_},_} = Cb <- CallbacksList, M1 =:= M]} ||
+ M <- lists:usort([M || {{M,_,_},_} <- CallbacksList])],
+ true = ets:insert(Callbacks, CallbacksByModule),
+ Plt.
+
+-spec is_contract(plt(), mfa()) -> boolean().
+
+is_contract(#plt{contracts = ETSContracts},
+ {M, F, _} = MFA) when is_atom(M), is_atom(F) ->
+ ets:member(ETSContracts, MFA).
-spec lookup_contract(plt(), mfa_patt()) -> 'none' | {'value', #contract{}}.
-lookup_contract(#mini_plt{contracts = ETSContracts},
+lookup_contract(#plt{contracts = ETSContracts},
{M, F, _} = MFA) when is_atom(M), is_atom(F) ->
ets_table_lookup(ETSContracts, MFA).
-spec lookup_callbacks(plt(), module()) ->
'none' | {'value', [{mfa(), dialyzer_contracts:file_contract()}]}.
-lookup_callbacks(#mini_plt{callbacks = ETSCallbacks}, Mod) when is_atom(Mod) ->
+lookup_callbacks(#plt{callbacks = ETSCallbacks}, Mod) when is_atom(Mod) ->
ets_table_lookup(ETSCallbacks, Mod).
-type ret_args_types() :: {erl_types:erl_type(), [erl_types:erl_type()]}.
-spec insert_list(plt(), [{mfa() | integer(), ret_args_types()}]) -> plt().
-insert_list(#mini_plt{info = Info} = PLT, List) ->
+insert_list(#plt{info = Info} = PLT, List) ->
true = ets:insert(Info, List),
PLT.
@@ -180,28 +187,31 @@ lookup(Plt, {M, F, _} = MFA) when is_atom(M), is_atom(F) ->
lookup(Plt, Label) when is_integer(Label) ->
lookup_1(Plt, Label).
-lookup_1(#mini_plt{info = Info}, MFAorLabel) ->
+lookup_1(#plt{info = Info}, MFAorLabel) ->
ets_table_lookup(Info, MFAorLabel).
--spec insert_types(plt(), dict:dict()) -> plt().
+-spec insert_types(plt(), ets:tid()) -> plt().
-insert_types(PLT, Rec) ->
- PLT#plt{types = Rec}.
+insert_types(PLT, Records) ->
+ ok = dialyzer_utils:ets_move(Records, PLT#plt.types),
+ PLT.
--spec insert_exported_types(plt(), sets:set()) -> plt().
+-spec insert_exported_types(plt(), ets:tid()) -> plt().
-insert_exported_types(PLT, Set) ->
- PLT#plt{exported_types = Set}.
+insert_exported_types(PLT, ExpTypes) ->
+ ok = dialyzer_utils:ets_move(ExpTypes, PLT#plt.exported_types),
+ PLT.
--spec get_types(plt()) -> dict:dict().
+-spec get_module_types(plt(), atom()) ->
+ 'none' | {'value', erl_types:type_table()}.
-get_types(#plt{types = Types}) ->
- Types.
+get_module_types(#plt{types = Types}, M) when is_atom(M) ->
+ ets_table_lookup(Types, M).
-spec get_exported_types(plt()) -> sets:set().
-get_exported_types(#plt{exported_types = ExpTypes}) ->
- ExpTypes.
+get_exported_types(#plt{exported_types = ETSExpTypes}) ->
+ sets:from_list([E || {E} <- table_to_list(ETSExpTypes)]).
-type mfa_types() :: {mfa(), erl_types:erl_type(), [erl_types:erl_type()]}.
@@ -218,20 +228,15 @@ all_modules(#plt{info = Info, contracts = Cs}) ->
-spec contains_mfa(plt(), mfa()) -> boolean().
contains_mfa(#plt{info = Info, contracts = Contracts}, MFA) ->
- (table_lookup(Info, MFA) =/= none)
- orelse (table_lookup(Contracts, MFA) =/= none).
+ ets:member(Info, MFA) orelse ets:member(Contracts, MFA).
-spec get_default_plt() -> file:filename().
get_default_plt() ->
case os:getenv("DIALYZER_PLT") of
false ->
- case os:getenv("HOME") of
- false ->
- plt_error("The HOME environment variable needs to be set " ++
- "so that Dialyzer knows where to find the default PLT");
- HomeDir -> filename:join(HomeDir, ".dialyzer_plt")
- end;
+ {ok,[[HomeDir]]} = init:get_argument(home),
+ filename:join(HomeDir, ".dialyzer_plt");
UserSpecPlt -> UserSpecPlt
end.
@@ -246,30 +251,60 @@ from_file(FileName) ->
from_file(FileName, false).
from_file(FileName, ReturnInfo) ->
+ Plt = new(),
+ Fun = fun() -> from_file1(Plt, FileName, ReturnInfo) end,
+ case subproc(Fun) of
+ {ok, Return} ->
+ Return;
+ {error, Msg} ->
+ delete(Plt),
+ plt_error(Msg)
+ end.
+
+from_file1(Plt, FileName, ReturnInfo) ->
case get_record_from_file(FileName) of
{ok, Rec} ->
case check_version(Rec) of
error ->
- Msg = io_lib:format("Old PLT file ~s\n", [FileName]),
- plt_error(Msg);
+ Msg = io_lib:format("Old PLT file ~ts\n", [FileName]),
+ {error, Msg};
ok ->
- Plt = #plt{info = Rec#file_plt.info,
- types = Rec#file_plt.types,
- contracts = Rec#file_plt.contracts,
- callbacks = Rec#file_plt.callbacks,
- exported_types = Rec#file_plt.exported_types},
+ #file_plt{info = FileInfo,
+ contracts = FileContracts,
+ callbacks = FileCallbacks,
+ types = FileTypes,
+ exported_types = FileExpTypes} = Rec,
+ Types = [{Mod, maps:from_list(dict:to_list(Types))} ||
+ {Mod, Types} <- dict:to_list(FileTypes)],
+ CallbacksList = dict:to_list(FileCallbacks),
+ CallbacksByModule =
+ [{M, [Cb || {{M1,_,_},_} = Cb <- CallbacksList, M1 =:= M]} ||
+ M <- lists:usort([M || {{M,_,_},_} <- CallbacksList])],
+ #plt{info = ETSInfo,
+ types = ETSTypes,
+ contracts = ETSContracts,
+ callbacks = ETSCallbacks,
+ exported_types = ETSExpTypes} = Plt,
+ [true, true, true] =
+ [ets:insert(ETS, Data) ||
+ {ETS, Data} <- [{ETSInfo, dict:to_list(FileInfo)},
+ {ETSTypes, Types},
+ {ETSContracts, dict:to_list(FileContracts)}]],
+ true = ets:insert(ETSCallbacks, CallbacksByModule),
+ true = ets:insert(ETSExpTypes, [{ET} ||
+ ET <- sets:to_list(FileExpTypes)]),
case ReturnInfo of
- false -> Plt;
+ false -> {ok, Plt};
true ->
PltInfo = {Rec#file_plt.file_md5_list,
Rec#file_plt.mod_deps},
- {Plt, PltInfo}
+ {ok, {Plt, PltInfo}}
end
end;
{error, Reason} ->
- Msg = io_lib:format("Could not read PLT file ~s: ~p\n",
+ Msg = io_lib:format("Could not read PLT file ~ts: ~p\n",
[FileName, Reason]),
- plt_error(Msg)
+ {error, Msg}
end.
-type err_rsn() :: 'not_valid' | 'no_such_file' | 'read_error'.
@@ -278,6 +313,10 @@ from_file(FileName, ReturnInfo) ->
| {'error', err_rsn()}.
included_files(FileName) ->
+ Fun = fun() -> included_files1(FileName) end,
+ subproc(Fun).
+
+included_files1(FileName) ->
case get_record_from_file(FileName) of
{ok, #file_plt{file_md5_list = Md5}} ->
{ok, [File || {File, _} <- Md5]};
@@ -310,6 +349,9 @@ get_record_from_file(FileName) ->
-spec merge_plts([plt()]) -> plt().
+%% One of the PLTs of the list is augmented with the contents of the
+%% other PLTs, and returned. The other PLTs are deleted.
+
merge_plts(List) ->
{InfoList, TypesList, ExpTypesList, ContractsList, CallbacksList} =
group_fields(List),
@@ -322,6 +364,12 @@ merge_plts(List) ->
-spec merge_disj_plts([plt()]) -> plt().
+%% One of the PLTs of the list is augmented with the contents of the
+%% other PLTs, and returned. The other PLTs are deleted.
+%%
+%% The keys are compared when checking for disjointness. Sometimes the
+%% key is a module(), sometimes an mfa(). It boils down to checking if
+%% any module occurs more than once.
merge_disj_plts(List) ->
{InfoList, TypesList, ExpTypesList, ContractsList, CallbacksList} =
group_fields(List),
@@ -351,7 +399,7 @@ merge_plts_or_report_conflicts(PltFiles, Plts) ->
ConfFiles = find_duplicates(IncFiles),
Msg = io_lib:format("Could not merge PLTs since they are not disjoint\n"
"The following files are included in more than one "
- "PLTs:\n~p\n", [ConfFiles]),
+ "PLTs:\n~tp\n", [ConfFiles]),
plt_error(Msg)
end.
@@ -362,21 +410,42 @@ find_duplicates(List) ->
-spec to_file(file:filename(), plt(), mod_deps(), {[file_md5()], mod_deps()}) -> 'ok'.
-to_file(FileName,
- #plt{info = Info, types = Types, contracts = Contracts,
- callbacks = Callbacks, exported_types = ExpTypes},
+%% Write the PLT to file, and deletes the PLT.
+to_file(FileName, Plt, ModDeps, MD5_OldModDeps) ->
+ Fun = fun() -> to_file1(FileName, Plt, ModDeps, MD5_OldModDeps) end,
+ Return = subproc(Fun),
+ delete(Plt),
+ case Return of
+ ok -> ok;
+ Thrown -> throw(Thrown)
+ end.
+
+to_file1(FileName,
+ #plt{info = ETSInfo, types = ETSTypes, contracts = ETSContracts,
+ callbacks = ETSCallbacks, exported_types = ETSExpTypes},
ModDeps, {MD5, OldModDeps}) ->
NewModDeps = dict:merge(fun(_Key, OldVal, NewVal) ->
ordsets:union(OldVal, NewVal)
end,
OldModDeps, ModDeps),
ImplMd5 = compute_implementation_md5(),
+ CallbacksList =
+ [Cb ||
+ {_M, Cbs} <- tab2list(ETSCallbacks),
+ Cb <- Cbs],
+ Callbacks = dict:from_list(CallbacksList),
+ Info = dict:from_list(tab2list(ETSInfo)),
+ Types = tab2list(ETSTypes),
+ Contracts = dict:from_list(tab2list(ETSContracts)),
+ ExpTypes = sets:from_list([E || {E} <- tab2list(ETSExpTypes)]),
+ FileTypes = dict:from_list([{Mod, dict:from_list(maps:to_list(MTypes))} ||
+ {Mod, MTypes} <- Types]),
Record = #file_plt{version = ?VSN,
file_md5_list = MD5,
info = Info,
contracts = Contracts,
callbacks = Callbacks,
- types = Types,
+ types = FileTypes,
exported_types = ExpTypes,
mod_deps = NewModDeps,
implementation_md5 = ImplMd5},
@@ -384,9 +453,9 @@ to_file(FileName,
case file:write_file(FileName, Bin) of
ok -> ok;
{error, Reason} ->
- Msg = io_lib:format("Could not write PLT file ~s: ~w\n",
+ Msg = io_lib:format("Could not write PLT file ~ts: ~w\n",
[FileName, Reason]),
- throw({dialyzer_error, Msg})
+ {dialyzer_error, Msg}
end.
-type md5_diff() :: [{'differ', atom()} | {'removed', atom()}].
@@ -399,6 +468,10 @@ to_file(FileName,
| {'old_version', [file_md5()]}.
check_plt(FileName, RemoveFiles, AddFiles) ->
+ Fun = fun() -> check_plt1(FileName, RemoveFiles, AddFiles) end,
+ subproc(Fun).
+
+check_plt1(FileName, RemoveFiles, AddFiles) ->
case get_record_from_file(FileName) of
{ok, #file_plt{file_md5_list = Md5, mod_deps = ModDeps} = Rec} ->
case check_version(Rec) of
@@ -460,15 +533,14 @@ compute_md5_from_files(Files) ->
compute_md5_from_file(File) ->
case filelib:is_regular(File) of
false ->
- Msg = io_lib:format("Not a regular file: ~s\n", [File]),
+ Msg = io_lib:format("Not a regular file: ~ts\n", [File]),
throw({dialyzer_error, Msg});
true ->
- case dialyzer_utils:get_abstract_code_from_beam(File) of
- error ->
- Msg = io_lib:format("Could not get abstract code for file: ~s (please recompile it with +debug_info)\n", [File]),
- throw({dialyzer_error, Msg});
- {ok, Abs} ->
- erlang:md5(term_to_binary(Abs))
+ case dialyzer_utils:get_core_from_beam(File) of
+ {error, Error} ->
+ throw({dialyzer_error, Error});
+ {ok, Core} ->
+ erlang:md5(term_to_binary(Core))
end
end.
@@ -508,33 +580,29 @@ init_md5_list_1([], DiffList, Acc) ->
init_md5_list_1(Md5List, [], Acc) ->
{ok, lists:reverse(Acc, Md5List)}.
--spec get_mini_plt(plt()) -> plt().
-
-get_mini_plt(#plt{info = Info, contracts = Contracts, callbacks = Callbacks}) ->
- [ETSInfo, ETSContracts, ETSCallbacks] =
- [ets:new(Name, [public]) || Name <- [plt_info, plt_contracts, plt_callbacks]],
- CallbackList = dict:to_list(Callbacks),
- CallbacksByModule =
- [{M, [Cb || {{M1,_,_},_} = Cb <- CallbackList, M1 =:= M]} ||
- M <- lists:usort([M || {{M,_,_},_} <- CallbackList])],
- [true, true] =
- [ets:insert(ETS, dict:to_list(Data)) ||
- {ETS, Data} <- [{ETSInfo, Info}, {ETSContracts, Contracts}]],
- true = ets:insert(ETSCallbacks, CallbacksByModule),
- #mini_plt{info = ETSInfo, contracts = ETSContracts, callbacks = ETSCallbacks};
-get_mini_plt(undefined) ->
- undefined.
-
--spec restore_full_plt(plt(), plt()) -> plt().
-
-restore_full_plt(#mini_plt{info = ETSInfo, contracts = ETSContracts}, Plt) ->
- Info = dict:from_list(ets:tab2list(ETSInfo)),
- Contracts = dict:from_list(ets:tab2list(ETSContracts)),
- ets:delete(ETSContracts),
- ets:delete(ETSInfo),
- Plt#plt{info = Info, contracts = Contracts};
-restore_full_plt(undefined, undefined) ->
- undefined.
+-spec delete(plt()) -> 'ok'.
+
+delete(#plt{info = ETSInfo,
+ types = ETSTypes,
+ contracts = ETSContracts,
+ callbacks = ETSCallbacks,
+ exported_types = ETSExpTypes}) ->
+ true = ets:delete(ETSContracts),
+ true = ets:delete(ETSTypes),
+ true = ets:delete(ETSInfo),
+ true = ets:delete(ETSCallbacks),
+ true = ets:delete(ETSExpTypes),
+ ok.
+
+tab2list(Tab) ->
+ dialyzer_utils:ets_tab2list(Tab).
+
+subproc(Fun) ->
+ F = fun() -> exit(Fun()) end,
+ {Pid, Ref} = erlang:spawn_monitor(F),
+ receive {'DOWN', Ref, process, Pid, Return} ->
+ Return
+ end.
%%---------------------------------------------------------------------------
%% Edoc
@@ -543,7 +611,8 @@ restore_full_plt(undefined, undefined) ->
get_specs(#plt{info = Info}) ->
%% TODO: Should print contracts as well.
- L = lists:sort([{MFA, Val} || {{_,_,_} = MFA, Val} <- table_to_list(Info)]),
+ L = lists:sort([{MFA, Val} ||
+ {{_,_,_} = MFA, Val} <- table_to_list(Info)]),
lists:flatten(create_specs(L, [])).
beam_file_to_module(Filename) ->
@@ -553,13 +622,13 @@ beam_file_to_module(Filename) ->
get_specs(#plt{info = Info}, M, F, A) when is_atom(M), is_atom(F) ->
MFA = {M, F, A},
- case table_lookup(Info, MFA) of
+ case ets_table_lookup(Info, MFA) of
none -> none;
{value, Val} -> lists:flatten(create_specs([{MFA, Val}], []))
end.
create_specs([{{M, F, _A}, {Ret, Args}}|Left], M) ->
- [io_lib:format("-spec ~w(~s) -> ~s\n",
+ [io_lib:format("-spec ~tw(~ts) -> ~ts\n",
[F, expand_args(Args), erl_types:t_to_string(Ret)])
| create_specs(Left, M)];
create_specs(List = [{{M, _F, _A}, {_Ret, _Args}}| _], _M) ->
@@ -590,41 +659,30 @@ plt_error(Msg) ->
%%---------------------------------------------------------------------------
%% Ets table
-table_new() ->
- dict:new().
-
table_to_list(Plt) ->
- dict:to_list(Plt).
-
-table_delete_module(Plt, Mod) ->
- dict:filter(fun({M, _F, _A}, _Val) -> M =/= Mod;
- (_, _) -> true
- end, Plt).
-
-table_delete_module1(Plt, Mod) ->
- sets:filter(fun({M, _F, _A}) -> M =/= Mod end, Plt).
-
-table_delete_module2(Plt, Mod) ->
- dict:filter(fun(M, _Val) -> M =/= Mod end, Plt).
-
-table_delete_list(Plt, [H|T]) ->
- table_delete_list(dict:erase(H, Plt), T);
-table_delete_list(Plt, []) ->
- Plt.
-
-table_insert_list(Plt, [{Key, Val}|Left]) ->
- table_insert_list(table_insert(Plt, Key, Val), Left);
-table_insert_list(Plt, []) ->
- Plt.
-
-table_insert(Plt, Key, {_File, #contract{}, _Xtra} = C) ->
- dict:store(Key, C, Plt).
-
-table_lookup(Plt, Obj) ->
- case dict:find(Obj, Plt) of
- error -> none;
- {ok, Val} -> {value, Val}
- end.
+ ets:tab2list(Plt).
+
+table_delete_module(Tab, Mod) ->
+ MS = ets:fun2ms(fun({{M, _F, _A}, _Val}) -> M =:= Mod;
+ ({_, _}) -> false
+ end),
+ _NumDeleted = ets:select_delete(Tab, MS),
+ Tab.
+
+table_delete_module1(Tab, Mod) ->
+ MS = ets:fun2ms(fun({{M, _F, _A}}) -> M =:= Mod end),
+ _NumDeleted = ets:select_delete(Tab, MS),
+ Tab.
+
+table_delete_module2(Tab, Mod) ->
+ true = ets:delete(Tab, Mod),
+ Tab.
+
+ets_table_delete_list(Tab, [H|T]) ->
+ ets:delete(Tab, H),
+ ets_table_delete_list(Tab, T);
+ets_table_delete_list(Tab, []) ->
+ Tab.
ets_table_lookup(Plt, Obj) ->
try ets:lookup_element(Plt, Obj, 2) of
@@ -633,25 +691,28 @@ ets_table_lookup(Plt, Obj) ->
_:_ -> none
end.
-table_lookup_module(Plt, Mod) ->
- List = dict:fold(fun(Key, Val, Acc) ->
- case Key of
- {Mod, _F, _A} -> [{Key, element(1, Val),
- element(2, Val)}|Acc];
- _ -> Acc
- end
- end, [], Plt),
+table_lookup_module(Tab, Mod) ->
+ MS = ets:fun2ms(fun({{M, F, A}, V}) when M =:= Mod ->
+ {{M, F, A}, V} end),
+ List = [begin
+ {V1, V2} = V,
+ {MFA, V1, V2}
+ end || {MFA, V} <- ets:select(Tab, MS)],
case List =:= [] of
true -> none;
false -> {value, List}
end.
-table_all_modules(Plt) ->
- Fold =
- fun({M, _F, _A}, _Val, Acc) -> sets:add_element(M, Acc);
- (_, _, Acc) -> Acc
- end,
- dict:fold(Fold, sets:new(), Plt).
+table_all_modules(Tab) ->
+ Ks = ets:match(Tab, {'$1', '_'}, 100),
+ all_mods(Ks, sets:new()).
+
+all_mods('$end_of_table', S) ->
+ S;
+all_mods({ListsOfKeys, Cont}, S) ->
+ S1 = lists:foldl(fun([{M, _F, _A}], S0) -> sets:add_element(M, S0)
+ end, S, ListsOfKeys),
+ all_mods(ets:match(Cont), S1).
table_merge([H|T]) ->
table_merge(T, H).
@@ -659,7 +720,7 @@ table_merge([H|T]) ->
table_merge([], Acc) ->
Acc;
table_merge([Plt|Plts], Acc) ->
- NewAcc = dict:merge(fun(_Key, Val, Val) -> Val end, Plt, Acc),
+ NewAcc = merge_tables(Plt, Acc),
table_merge(Plts, NewAcc).
table_disj_merge([H|T]) ->
@@ -670,24 +731,18 @@ table_disj_merge([], Acc) ->
table_disj_merge([Plt|Plts], Acc) ->
case table_is_disjoint(Plt, Acc) of
true ->
- NewAcc = dict:merge(fun(_Key, _Val1, _Val2) -> gazonk end,
- Plt, Acc),
+ NewAcc = merge_tables(Plt, Acc),
table_disj_merge(Plts, NewAcc);
false -> throw({dialyzer_error, not_disjoint_plts})
end.
-table_is_disjoint(T1, T2) ->
- K1 = dict:fetch_keys(T1),
- K2 = dict:fetch_keys(T2),
- lists:all(fun(E) -> not lists:member(E, K2) end, K1).
-
sets_merge([H|T]) ->
sets_merge(T, H).
sets_merge([], Acc) ->
Acc;
sets_merge([Plt|Plts], Acc) ->
- NewAcc = sets:union(Plt, Acc),
+ NewAcc = merge_tables(Plt, Acc),
sets_merge(Plts, NewAcc).
sets_disj_merge([H|T]) ->
@@ -696,13 +751,39 @@ sets_disj_merge([H|T]) ->
sets_disj_merge([], Acc) ->
Acc;
sets_disj_merge([Plt|Plts], Acc) ->
- case sets:is_disjoint(Plt, Acc) of
+ case table_is_disjoint(Plt, Acc) of
true ->
- NewAcc = sets:union(Plt, Acc),
+ NewAcc = merge_tables(Plt, Acc),
sets_disj_merge(Plts, NewAcc);
false -> throw({dialyzer_error, not_disjoint_plts})
end.
+table_is_disjoint(T1, T2) ->
+ tab_is_disj(ets:first(T1), T1, T2).
+
+tab_is_disj('$end_of_table', _T1, _T2) ->
+ true;
+tab_is_disj(K1, T1, T2) ->
+ case ets:member(T2, K1) of
+ false ->
+ tab_is_disj(ets:next(T1, K1), T1, T2);
+ true ->
+ false
+ end.
+
+merge_tables(T1, T2) ->
+ tab_merge(ets:first(T1), T1, T2).
+
+tab_merge('$end_of_table', T1, T2) ->
+ true = ets:delete(T1),
+ T2;
+tab_merge(K1, T1, T2) ->
+ Vs = ets:lookup(T1, K1),
+ NextK1 = ets:next(T1, K1),
+ true = ets:delete(T1, K1),
+ true = ets:insert(T2, Vs),
+ tab_merge(NextK1, T1, T2).
+
%%---------------------------------------------------------------------------
%% Debug utilities.
@@ -720,7 +801,7 @@ pp_non_returning() ->
io:format("= Loops =\n"),
io:format("=========================================\n\n"),
lists:foreach(fun({{M, F, _}, Type}) ->
- io:format("~w:~w~s.\n",
+ io:format("~w:~tw~ts.\n",
[M, F, dialyzer_utils:format_sig(Type)])
end, lists:sort(Unit)),
io:format("\n"),
@@ -730,7 +811,8 @@ pp_non_returning() ->
lists:foreach(fun({{M, F, _}, Type}) ->
io:format("~w:~w~s.\n",
[M, F, dialyzer_utils:format_sig(Type)])
- end, lists:sort(None)).
+ end, lists:sort(None)),
+ delete(Plt).
-spec pp_mod(atom()) -> 'ok'.
@@ -742,8 +824,9 @@ pp_mod(Mod) when is_atom(Mod) ->
lists:foreach(fun({{_, F, _}, Ret, Args}) ->
T = erl_types:t_fun(Args, Ret),
S = dialyzer_utils:format_sig(T),
- io:format("-spec ~w~s.\n", [F, S])
+ io:format("-spec ~tw~ts.\n", [F, S])
end, lists:sort(List));
none ->
io:format("dialyzer: Found no module named '~s' in the PLT\n", [Mod])
- end.
+ end,
+ delete(Plt).
diff --git a/lib/dialyzer/src/dialyzer_race_data_server.erl b/lib/dialyzer/src/dialyzer_race_data_server.erl
index 3600491809..953cebfdf1 100644
--- a/lib/dialyzer/src/dialyzer_race_data_server.erl
+++ b/lib/dialyzer/src/dialyzer_race_data_server.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_race_data_server.erl
diff --git a/lib/dialyzer/src/dialyzer_races.erl b/lib/dialyzer/src/dialyzer_races.erl
index bb43d1dcb8..7fe64c3e11 100644
--- a/lib/dialyzer/src/dialyzer_races.erl
+++ b/lib/dialyzer/src/dialyzer_races.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%----------------------------------------------------------------------
%%% File : dialyzer_races.erl
diff --git a/lib/dialyzer/src/dialyzer_succ_typings.erl b/lib/dialyzer/src/dialyzer_succ_typings.erl
index 987da3aecf..48115bb683 100644
--- a/lib/dialyzer/src/dialyzer_succ_typings.erl
+++ b/lib/dialyzer/src/dialyzer_succ_typings.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_succ_typings.erl
@@ -36,7 +29,7 @@
-export([
find_succ_types_for_scc/2,
refine_one_module/2,
- find_required_by/2,
+ %% find_required_by/2,
find_depends_on/2,
collect_warnings/2,
lookup_names/2
@@ -96,7 +89,7 @@ analyze_callgraph(Callgraph, Plt, Codeserver, TimingServer, Solvers, Parent) ->
NewState =
init_state_and_get_success_typings(Callgraph, Plt, Codeserver,
TimingServer, Solvers, Parent),
- dialyzer_plt:restore_full_plt(NewState#st.plt, Plt).
+ NewState#st.plt.
%%--------------------------------------------------------------------
@@ -104,7 +97,7 @@ init_state_and_get_success_typings(Callgraph, Plt, Codeserver,
TimingServer, Solvers, Parent) ->
{SCCs, Callgraph1} =
?timing(TimingServer, "order", dialyzer_callgraph:finalize(Callgraph)),
- State = #st{callgraph = Callgraph1, plt = dialyzer_plt:get_mini_plt(Plt),
+ State = #st{callgraph = Callgraph1, plt = Plt,
codeserver = Codeserver, parent = Parent,
timing_server = TimingServer, solvers = Solvers},
get_refined_success_typings(SCCs, State).
@@ -145,18 +138,15 @@ get_warnings(Callgraph, Plt, DocPlt, Codeserver,
init_state_and_get_success_typings(Callgraph, Plt, Codeserver,
TimingServer, Solvers, Parent),
Mods = dialyzer_callgraph:modules(InitState#st.callgraph),
- MiniPlt = InitState#st.plt,
- FindOpaques = lookup_and_find_opaques_fun(Codeserver),
+ Plt = InitState#st.plt,
CWarns =
- dialyzer_contracts:get_invalid_contract_warnings(Mods, Codeserver,
- MiniPlt, FindOpaques),
- MiniDocPlt = dialyzer_plt:get_mini_plt(DocPlt),
+ dialyzer_contracts:get_invalid_contract_warnings(Mods, Codeserver, Plt),
ModWarns =
?timing(TimingServer, "warning",
- get_warnings_from_modules(Mods, InitState, MiniDocPlt)),
+ get_warnings_from_modules(Mods, InitState, DocPlt)),
{postprocess_warnings(CWarns ++ ModWarns, Codeserver),
- dialyzer_plt:restore_full_plt(MiniPlt, Plt),
- dialyzer_plt:restore_full_plt(MiniDocPlt, DocPlt)}.
+ Plt,
+ DocPlt}.
get_warnings_from_modules(Mods, State, DocPlt) ->
#st{callgraph = Callgraph, codeserver = Codeserver,
@@ -168,16 +158,16 @@ get_warnings_from_modules(Mods, State, DocPlt) ->
collect_warnings(M, {Codeserver, Callgraph, Plt, DocPlt}) ->
ModCode = dialyzer_codeserver:lookup_mod_code(M, Codeserver),
- Records = dialyzer_codeserver:lookup_mod_records(M, Codeserver),
Contracts = dialyzer_codeserver:lookup_mod_contracts(M, Codeserver),
AllFuns = collect_fun_info([ModCode]),
%% Check if there are contracts for functions that do not exist
Warnings1 =
dialyzer_contracts:contracts_without_fun(Contracts, AllFuns, Callgraph),
+ Attrs = cerl:module_attrs(ModCode),
+ Records = dialyzer_codeserver:lookup_mod_records(M, Codeserver),
{Warnings2, FunTypes} =
dialyzer_dataflow:get_warnings(ModCode, Plt, Callgraph, Codeserver,
Records),
- Attrs = cerl:module_attrs(ModCode),
Warnings3 =
dialyzer_behaviours:check_callbacks(M, Attrs, Records, Plt, Codeserver),
DocPlt = insert_into_doc_plt(FunTypes, Callgraph, DocPlt),
@@ -242,10 +232,10 @@ refine_succ_typings(Modules, #st{codeserver = Codeserver,
find_depends_on(SCC, {_Codeserver, Callgraph, _Plt, _Solvers}) ->
dialyzer_callgraph:get_depends_on(SCC, Callgraph).
--spec find_required_by(scc() | module(), fixpoint_init_data()) -> [scc()].
+%% -spec find_required_by(scc() | module(), fixpoint_init_data()) -> [scc()].
-find_required_by(SCC, {_Codeserver, Callgraph, _Plt, _Solvers}) ->
- dialyzer_callgraph:get_required_by(SCC, Callgraph).
+%% find_required_by(SCC, {_Codeserver, Callgraph, _Plt, _Solvers}) ->
+%% dialyzer_callgraph:get_required_by(SCC, Callgraph).
-spec lookup_names([label()], fixpoint_init_data()) -> [mfa_or_funlbl()].
@@ -257,24 +247,22 @@ lookup_names(Labels, {_Codeserver, Callgraph, _Plt, _Solvers}) ->
refine_one_module(M, {CodeServer, Callgraph, Plt, _Solvers}) ->
ModCode = dialyzer_codeserver:lookup_mod_code(M, CodeServer),
AllFuns = collect_fun_info([ModCode]),
- Records = dialyzer_codeserver:lookup_mod_records(M, CodeServer),
FunTypes = get_fun_types_from_plt(AllFuns, Callgraph, Plt),
+ Records = dialyzer_codeserver:lookup_mod_records(M, CodeServer),
NewFunTypes =
dialyzer_dataflow:get_fun_types(ModCode, Plt, Callgraph, CodeServer, Records),
- Contracts1 = dialyzer_codeserver:lookup_mod_contracts(M, CodeServer),
- Contracts = orddict:from_list(dict:to_list(Contracts1)),
- FindOpaques = find_opaques_fun(Records),
- DecoratedFunTypes =
- decorate_succ_typings(Contracts, Callgraph, NewFunTypes, FindOpaques),
- %% ?debug("NewFunTypes ~p\n ~n", [dict:to_list(NewFunTypes)]),
- %% ?debug("refine DecoratedFunTypes ~p\n ~n", [dict:to_list(DecoratedFunTypes)]),
+ {FunMFAContracts, ModOpaques} =
+ prepare_decoration(NewFunTypes, Callgraph, CodeServer),
+ DecoratedFunTypes = decorate_succ_typings(FunMFAContracts, ModOpaques),
+ %% ?Debug("NewFunTypes ~tp\n ~n", [NewFunTypes]),
+ %% ?debug("refine DecoratedFunTypes ~tp\n ~n", [DecoratedFunTypes]),
debug_pp_functions("Refine", NewFunTypes, DecoratedFunTypes, Callgraph),
case reached_fixpoint(FunTypes, DecoratedFunTypes) of
true -> [];
{false, NotFixpoint} ->
?debug("Not fixpoint\n", []),
- Plt = insert_into_plt(dict:from_list(NotFixpoint), Callgraph, Plt),
+ Plt = insert_into_plt(orddict:from_list(NotFixpoint), Callgraph, Plt),
[FunLbl || {FunLbl,_Type} <- NotFixpoint]
end.
@@ -288,22 +276,20 @@ reached_fixpoint_strict(OldTypes, NewTypes) ->
end.
reached_fixpoint(OldTypes0, NewTypes0, Strict) ->
- MapFun = fun(_Key, Type) ->
+ MapFun = fun({Key, Type}) ->
case is_failed_or_not_called_fun(Type) of
- true -> failed_fun;
- false -> erl_types:t_limit(Type, ?TYPE_LIMIT)
+ true -> {Key, failed_fun};
+ false -> {Key, erl_types:t_limit(Type, ?TYPE_LIMIT)}
end
end,
- OldTypes = dict:map(MapFun, OldTypes0),
- NewTypes = dict:map(MapFun, NewTypes0),
+ OldTypes = lists:map(MapFun, orddict:to_list(OldTypes0)),
+ NewTypes = lists:map(MapFun, orddict:to_list(NewTypes0)),
compare_types(OldTypes, NewTypes, Strict).
is_failed_or_not_called_fun(Type) ->
erl_types:any_none([erl_types:t_fun_range(Type)|erl_types:t_fun_args(Type)]).
-compare_types(Dict1, Dict2, Strict) ->
- List1 = lists:keysort(1, dict:to_list(Dict1)),
- List2 = lists:keysort(1, dict:to_list(Dict2)),
+compare_types(List1, List2, Strict) ->
compare_types_1(List1, List2, Strict, []).
compare_types_1([{X, _Type1}|Left1], [{X, failed_fun}|Left2],
@@ -320,7 +306,7 @@ compare_types_1([{X, Type1}|Left1], [{X, Type2}|Left2], Strict, NotFixpoint) ->
case Res of
true -> compare_types_1(Left1, Left2, Strict, NotFixpoint);
false ->
- ?debug("Failed fixpoint for ~w: ~s =/= ~s\n",
+ ?debug("Failed fixpoint for ~w: ~ts =/= ~ts\n",
[X, erl_types:t_to_string(Type1), erl_types:t_to_string(Type2)]),
compare_types_1(Left1, Left2, Strict, [{X, Type2}|NotFixpoint])
end;
@@ -348,88 +334,95 @@ find_succ_typings(SCCs, #st{codeserver = Codeserver, callgraph = Callgraph,
-spec find_succ_types_for_scc(scc(), typesig_init_data()) -> [mfa_or_funlbl()].
-find_succ_types_for_scc(SCC, {Codeserver, Callgraph, Plt, Solvers}) ->
- SCC_Info = [{MFA,
- dialyzer_codeserver:lookup_mfa_code(MFA, Codeserver),
- dialyzer_codeserver:lookup_mod_records(M, Codeserver)}
- || {M, _, _} = MFA <- SCC],
- Contracts1 = [{MFA, dialyzer_codeserver:lookup_mfa_contract(MFA, Codeserver)}
- || {_, _, _} = MFA <- SCC],
- Contracts2 = [{MFA, Contract} || {MFA, {ok, Contract}} <- Contracts1],
- Contracts3 = orddict:from_list(Contracts2),
+find_succ_types_for_scc(SCC0, {Codeserver, Callgraph, Plt, Solvers}) ->
+ SCC = [MFA || {_, _, _} = MFA <- SCC0],
Label = dialyzer_codeserver:get_next_core_label(Codeserver),
- AllFuns = collect_fun_info([Fun || {_MFA, {_Var, Fun}, _Rec} <- SCC_Info]),
+ AllFuns = lists:append(
+ [begin
+ {_Var, Fun} =
+ dialyzer_codeserver:lookup_mfa_code(MFA, Codeserver),
+ collect_fun_info([Fun])
+ end || MFA <- SCC]),
PropTypes = get_fun_types_from_plt(AllFuns, Callgraph, Plt),
%% Assume that the PLT contains the current propagated types
- FunTypes = dialyzer_typesig:analyze_scc(SCC_Info, Label, Callgraph,
- Plt, PropTypes, Solvers),
+ FunTypes = dialyzer_typesig:analyze_scc(SCC, Label, Callgraph,
+ Codeserver, Plt, PropTypes,
+ Solvers),
AllFunSet = sets:from_list([X || {X, _} <- AllFuns]),
FilteredFunTypes =
- dict:filter(fun(X, _) -> sets:is_element(X, AllFunSet) end, FunTypes),
- FindOpaques = lookup_and_find_opaques_fun(Codeserver),
- DecoratedFunTypes =
- decorate_succ_typings(Contracts3, Callgraph, FilteredFunTypes, FindOpaques),
+ orddict:filter(fun(F, _T) -> sets:is_element(F, AllFunSet)
+ end, FunTypes),
+ {FunMFAContracts, ModOpaques} =
+ prepare_decoration(FilteredFunTypes, Callgraph, Codeserver),
+ DecoratedFunTypes = decorate_succ_typings(FunMFAContracts, ModOpaques),
%% Check contracts
+ Contracts = orddict:from_list([{MFA, Contract} ||
+ {_, {MFA, Contract}} <- FunMFAContracts]),
PltContracts =
- dialyzer_contracts:check_contracts(Contracts3, Callgraph,
- DecoratedFunTypes, FindOpaques),
- %% ?debug("FilteredFunTypes ~p\n ~n", [dict:to_list(FilteredFunTypes)]),
- %% ?debug("SCC DecoratedFunTypes ~p\n ~n", [dict:to_list(DecoratedFunTypes)]),
+ dialyzer_contracts:check_contracts(Contracts, Callgraph,
+ DecoratedFunTypes,
+ ModOpaques),
+ %% ?debug("FilteredFunTypes ~tp\n ~n", [FilteredFunTypes]),
+ %% ?debug("SCC DecoratedFunTypes ~tp\n ~n", [DecoratedFunTypes]),
debug_pp_functions("SCC", FilteredFunTypes, DecoratedFunTypes, Callgraph),
- ContractFixpoint =
- lists:all(fun({MFA, _C}) ->
- %% Check the non-deleted PLT
- case dialyzer_plt:lookup_contract(Plt, MFA) of
- none -> false;
- {value, _} -> true
- end
- end, PltContracts),
+ NewPltContracts = [MC ||
+ {MFA, _C}=MC <- PltContracts,
+ %% Check the non-deleted PLT
+ not dialyzer_plt:is_contract(Plt, MFA)],
+ ContractFixpoint = NewPltContracts =:= [],
Plt = insert_into_plt(DecoratedFunTypes, Callgraph, Plt),
- Plt = dialyzer_plt:insert_contract_list(Plt, PltContracts),
+ Plt = dialyzer_plt:insert_contract_list(Plt, NewPltContracts),
case (ContractFixpoint andalso
reached_fixpoint_strict(PropTypes, DecoratedFunTypes)) of
true -> [];
false ->
- ?debug("Not fixpoint for: ~w\n", [AllFuns]),
+ ?debug("Not fixpoint for: ~tw\n", [AllFuns]),
[Fun || {Fun, _Arity} <- AllFuns]
end.
-decorate_succ_typings(Contracts, Callgraph, FunTypes, FindOpaques) ->
- F = fun(Label, Type) ->
+prepare_decoration(FunTypes, Callgraph, Codeserver) ->
+ F = fun({Label, _Type}=LabelType, Acc) ->
case dialyzer_callgraph:lookup_name(Label, Callgraph) of
{ok, MFA} ->
- case orddict:find(MFA, Contracts) of
+ case dialyzer_codeserver:lookup_mfa_contract(MFA, Codeserver) of
{ok, {_FileLine, Contract, _Xtra}} ->
- Args = dialyzer_contracts:get_contract_args(Contract),
- Ret = dialyzer_contracts:get_contract_return(Contract),
- C = erl_types:t_fun(Args, Ret),
- {M, _, _} = MFA,
- Opaques = FindOpaques(M),
- erl_types:t_decorate_with_opaque(Type, C, Opaques);
- error -> Type
+ [{LabelType, {MFA, Contract}}|Acc];
+ error -> [{LabelType, no}|Acc]
end;
- error -> Type
+ error -> [{LabelType, no}|Acc]
end
end,
- dict:map(F, FunTypes).
-
-lookup_and_find_opaques_fun(Codeserver) ->
- fun(Module) ->
- Records = dialyzer_codeserver:lookup_mod_records(Module, Codeserver),
- (find_opaques_fun(Records))(Module)
- end.
+ Contracts = lists:foldl(F, [], orddict:to_list(FunTypes)),
+ ModOpaques =
+ [{M, lookup_opaques(M, Codeserver)} ||
+ M <- lists:usort([M || {_LabelType, {{M, _, _}, _Con}} <- Contracts])],
+ {Contracts, orddict:from_list(ModOpaques)}.
+
+decorate_succ_typings(FunTypesContracts, ModOpaques) ->
+ F = fun({{Label, Type}, {{M, _, _}, Contract}}) ->
+ Args = dialyzer_contracts:get_contract_args(Contract),
+ Ret = dialyzer_contracts:get_contract_return(Contract),
+ C = erl_types:t_fun(Args, Ret),
+ {M, Opaques} = lists:keyfind(M, 1, ModOpaques),
+ R = erl_types:t_decorate_with_opaque(Type, C, Opaques),
+ {Label, R};
+ ({LabelType, no}) ->
+ LabelType
+ end,
+ orddict:from_list(lists:map(F, FunTypesContracts)).
-find_opaques_fun(Records) ->
- fun(_Module) -> erl_types:t_opaque_from_records(Records) end.
+lookup_opaques(Module, Codeserver) ->
+ Records = dialyzer_codeserver:lookup_mod_records(Module, Codeserver),
+ erl_types:t_opaque_from_records(Records).
get_fun_types_from_plt(FunList, Callgraph, Plt) ->
- get_fun_types_from_plt(FunList, Callgraph, Plt, dict:new()).
+ get_fun_types_from_plt(FunList, Callgraph, Plt, []).
get_fun_types_from_plt([{FunLabel, Arity}|Left], Callgraph, Plt, Map) ->
Type = lookup_fun_type(FunLabel, Arity, Callgraph, Plt),
- get_fun_types_from_plt(Left, Callgraph, Plt, dict:store(FunLabel, Type, Map));
+ get_fun_types_from_plt(Left, Callgraph, Plt, [{FunLabel, Type}|Map]);
get_fun_types_from_plt([], _Callgraph, _Plt, Map) ->
- Map.
+ orddict:from_list(Map).
collect_fun_info(Trees) ->
collect_fun_info(Trees, []).
@@ -465,7 +458,7 @@ insert_into_plt(SuccTypes0, Callgraph, Plt) ->
dialyzer_plt:insert_list(Plt, SuccTypes).
format_succ_types(SuccTypes, Callgraph) ->
- format_succ_types(dict:to_list(SuccTypes), Callgraph, []).
+ format_succ_types(SuccTypes, Callgraph, []).
format_succ_types([{Label, Type0}|Left], Callgraph, Acc) ->
Type = erl_types:t_limit(Type0, ?TYPE_LIMIT+1),
@@ -478,28 +471,26 @@ format_succ_types([], _Callgraph, Acc) ->
-ifdef(DEBUG).
debug_pp_succ_typings(SuccTypes) ->
?debug("Succ typings:\n", []),
- [?debug(" ~w :: ~s\n",
+ [?debug(" ~tw :: ~ts\n",
[MFA, erl_types:t_to_string(erl_types:t_fun(ArgT, RetT))])
|| {MFA, {RetT, ArgT}} <- SuccTypes],
?debug("Contracts:\n", []),
- [?debug(" ~w :: ~s\n",
+ [?debug(" ~tw :: ~ts\n",
[MFA, erl_types:t_to_string(erl_types:t_fun(ArgT, RetFun(ArgT)))])
|| {MFA, {contract, RetFun, ArgT}} <- SuccTypes],
?debug("\n", []),
ok.
-debug_pp_functions(Header, FunTypes, DecoratedFunTypes, Callgraph) ->
+debug_pp_functions(Header, FTypes, DTypes, Callgraph) ->
?debug("FunTypes (~s)\n", [Header]),
- FTypes = lists:keysort(1, dict:to_list(FunTypes)),
- DTypes = lists:keysort(1, dict:to_list(DecoratedFunTypes)),
Fun = fun({{Label, Type},{Label, DecoratedType}}) ->
Name = lookup_name(Label, Callgraph),
- ?debug("~w (~w): ~s\n",
+ ?debug("~tw (~w): ~ts\n",
[Name, Label, erl_types:t_to_string(Type)]),
case erl_types:t_is_equal(Type, DecoratedType) of
true -> ok;
false ->
- ?debug(" With opaque types: ~s\n",
+ ?debug(" With opaque types: ~ts\n",
[erl_types:t_to_string(DecoratedType)])
end
end,
diff --git a/lib/dialyzer/src/dialyzer_timing.erl b/lib/dialyzer/src/dialyzer_timing.erl
index aa71318d8e..056ccd51d8 100644
--- a/lib/dialyzer/src/dialyzer_timing.erl
+++ b/lib/dialyzer/src/dialyzer_timing.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_timing.erl
diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl
index 1787b66192..c4d8f45447 100644
--- a/lib/dialyzer/src/dialyzer_typesig.erl
+++ b/lib/dialyzer/src/dialyzer_typesig.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_typesig.erl
@@ -29,7 +22,7 @@
-module(dialyzer_typesig).
--export([analyze_scc/6]).
+-export([analyze_scc/7]).
-export([get_safe_underapprox/2]).
%%-import(helper, %% 'helper' could be any module doing sanity checks...
@@ -88,7 +81,7 @@
-record(constraint_list, {type :: 'conj' | 'disj',
list :: [constr()],
deps :: deps(),
- masks = maps:new() :: #{dep() => mask()},
+ masks :: #{dep() => mask()} | 'undefined',
id :: {'list', dep()} | 'undefined'}).
-type constraint_list() :: #constraint_list{}.
@@ -101,13 +94,14 @@
-type types() :: erl_types:type_table().
--type typesig_scc() :: [{mfa(), {cerl:c_var(), cerl:c_fun()}, types()}].
-type typesig_funmap() :: #{type_var() => type_var()}.
--type prop_types() :: dict:dict(label(), types()).
+-type prop_types() :: orddict:orddict(label(), erl_types:erl_type()).
+-type dict_prop_types() :: dict:dict(label(), erl_types:erl_type()).
-record(state, {callgraph :: dialyzer_callgraph:callgraph()
| 'undefined',
+ cserver :: dialyzer_codeserver:codeserver(),
cs = [] :: [constr()],
cmap = maps:new() :: #{type_var() => constr()},
fun_map = maps:new() :: typesig_funmap(),
@@ -120,8 +114,8 @@
self_rec :: 'false' | erl_types:erl_type(),
plt :: dialyzer_plt:plt()
| 'undefined',
- prop_types = dict:new() :: prop_types(),
- records = dict:new() :: types(),
+ prop_types = dict:new() :: dict_prop_types(),
+ mod_records = [] :: [{module(), types()}],
scc = [] :: ordsets:ordset(type_var()),
mfas :: [mfa()],
solvers = [] :: [solver()]
@@ -146,9 +140,11 @@
-ifdef(DEBUG).
-define(debug(__String, __Args), io:format(__String, __Args)).
-define(mk_fun_var(Fun, Vars), mk_fun_var(?LINE, Fun, Vars)).
+-define(pp_map(S, M), pp_map(S, M)).
-else.
-define(debug(__String, __Args), ok).
-define(mk_fun_var(Fun, Vars), mk_fun_var(Fun, Vars)).
+-define(pp_map(S, M), ok).
-endif.
%% ============================================================================
@@ -160,11 +156,10 @@
%%-----------------------------------------------------------------------------
%% Analysis of strongly connected components.
%%
-%% analyze_scc(SCC, NextLabel, CallGraph, PLT, PropTypes, Solvers) -> FunTypes
+%% analyze_scc(SCC, NextLabel, CallGraph, CodeServer,
+%% PLT, PropTypes, Solvers) -> FunTypes
%%
-%% SCC - [{MFA, Def, Records}]
-%% where Def = {Var, Fun} as in the Core Erlang module definitions.
-%% Records = dict(RecName, {Arity, [{FieldName, FieldType}]})
+%% SCC - [{MFA}]
%% NextLabel - An integer that is higher than any label in the code.
%% CallGraph - A callgraph as produced by dialyzer_callgraph.erl
%% Note: The callgraph must have been built with all the
@@ -176,27 +171,23 @@
%% Solvers - User specified solvers.
%%-----------------------------------------------------------------------------
--spec analyze_scc(typesig_scc(), label(),
+-spec analyze_scc([mfa()], label(),
dialyzer_callgraph:callgraph(),
+ dialyzer_codeserver:codeserver(),
dialyzer_plt:plt(), prop_types(), [solver()]) -> prop_types().
-analyze_scc(SCC, NextLabel, CallGraph, Plt, PropTypes, Solvers0) ->
+analyze_scc(SCC, NextLabel, CallGraph, CServer, Plt, PropTypes, Solvers0) ->
Solvers = solvers(Solvers0),
- assert_format_of_scc(SCC),
- State1 = new_state(SCC, NextLabel, CallGraph, Plt, PropTypes, Solvers),
- DefSet = add_def_list([Var || {_MFA, {Var, _Fun}, _Rec} <- SCC], sets:new()),
- State2 = traverse_scc(SCC, DefSet, State1),
+ State1 = new_state(SCC, NextLabel, CallGraph, CServer, Plt, PropTypes,
+ Solvers),
+ DefSet = add_def_list(maps:values(State1#state.name_map), sets:new()),
+ State2 = traverse_scc(SCC, CServer, DefSet, State1),
State3 = state__finalize(State2),
Funs = state__scc(State3),
pp_constrs_scc(Funs, State3),
constraints_to_dot_scc(Funs, State3),
T = solve(Funs, State3),
- dict:from_list(maps:to_list(T)).
-
-assert_format_of_scc([{_MFA, {_Var, _Fun}, _Records}|Left]) ->
- assert_format_of_scc(Left);
-assert_format_of_scc([]) ->
- ok.
+ orddict:from_list(maps:to_list(T)).
solvers([]) -> [v2];
solvers(Solvers) -> Solvers.
@@ -207,12 +198,14 @@ solvers(Solvers) -> Solvers.
%%
%% ============================================================================
-traverse_scc([{_MFA, Def, Rec}|Left], DefSet, AccState) ->
- TmpState1 = state__set_rec_dict(AccState, Rec),
+traverse_scc([{M,_,_}=MFA|Left], Codeserver, DefSet, AccState) ->
+ TmpState1 = state__set_module(AccState, M),
+ Def = dialyzer_codeserver:lookup_mfa_code(MFA, Codeserver),
DummyLetrec = cerl:c_letrec([Def], cerl:c_atom(foo)),
- {NewAccState, _} = traverse(DummyLetrec, DefSet, TmpState1),
- traverse_scc(Left, DefSet, NewAccState);
-traverse_scc([], _DefSet, AccState) ->
+ TmpState2 = state__new_constraint_context(TmpState1),
+ {NewAccState, _} = traverse(DummyLetrec, DefSet, TmpState2),
+ traverse_scc(Left, Codeserver, DefSet, NewAccState);
+traverse_scc([], _Codeserver, _DefSet, AccState) ->
AccState.
traverse(Tree, DefinedVars, State) ->
@@ -478,12 +471,11 @@ traverse(Tree, DefinedVars, State) ->
true ->
%% Check if a record is constructed.
Arity = length(Fields),
- Records = State2#state.records,
- case lookup_record(Records, cerl:atom_val(Tag), Arity) of
- error -> {State2, TupleType};
- {ok, RecType} ->
- State3 = state__store_conj(TupleType, sub, RecType, State2),
- {State3, TupleType}
+ case lookup_record(State2, cerl:atom_val(Tag), Arity) of
+ {error, State3} -> {State3, TupleType};
+ {ok, RecType, State3} ->
+ State4 = state__store_conj(TupleType, sub, RecType, State3),
+ {State4, TupleType}
end;
false -> {State2, TupleType}
end;
@@ -779,7 +771,7 @@ handle_call(Call, DefinedVars, State) ->
{ok, Var} ->
%% This is part of the SCC currently analyzed.
%% Intercept and change this to an apply instead.
- ?debug("Found the call to ~w\n", [MFA]),
+ ?debug("Found the call to ~tw\n", [MFA]),
Label = cerl_trees:get_label(Call),
Apply = cerl:ann_c_apply([{label, Label}], Var, Args),
traverse(Apply, DefinedVars, State)
@@ -1448,7 +1440,6 @@ get_bif_constr({erlang, is_record, 2}, Dst, [Var, Tag] = Args, _State) ->
mk_constraint(Var, sub, ArgV)]);
get_bif_constr({erlang, is_record, 3}, Dst, [Var, Tag, Arity] = Args, State) ->
%% TODO: Revise this to make it precise for Tag and Arity.
- Records = State#state.records,
ArgFun =
fun(Map) ->
case t_is_any_atom(true, lookup_type(Dst, Map)) of
@@ -1465,10 +1456,10 @@ get_bif_constr({erlang, is_record, 3}, Dst, [Var, Tag, Arity] = Args, State) ->
GenRecord = t_tuple([TagType|AnyElems]),
case t_atom_vals(TagType) of
[TagVal] ->
- case lookup_record(Records, TagVal, ArityVal - 1) of
- {ok, Type} ->
+ case lookup_record(State, TagVal, ArityVal - 1) of
+ {ok, Type, _NewState} ->
Type;
- error -> GenRecord
+ {error, _NewState} -> GenRecord
end;
_ -> GenRecord
end;
@@ -1797,11 +1788,11 @@ get_bif_test_constr(Dst, Arg, Type, _State) ->
%%=============================================================================
solve([Fun], State) ->
- ?debug("============ Analyzing Fun: ~w ===========\n",
+ ?debug("============ Analyzing Fun: ~tw ===========\n",
[debug_lookup_name(Fun)]),
solve_fun(Fun, map_new(), State);
solve([_|_] = SCC, State) ->
- ?debug("============ Analyzing SCC: ~w ===========\n",
+ ?debug("============ Analyzing SCC: ~tw ===========\n",
[[debug_lookup_name(F) || F <- SCC]]),
Users = comp_users(SCC, State),
solve_scc(SCC, map_new(), State, Users, _ToSolve=SCC, false).
@@ -1837,13 +1828,13 @@ solve_scc(SCC, Map, State, Users, ToSolve, TryingUnit) ->
erase_type(t_var_name(Fun), AccFunMap)
end, Map, ToSolve),
Map1 = enter_type_lists(Vars, RecTypes, CleanMap),
- ?debug("Checking SCC: ~w\n", [[debug_lookup_name(F) || F <- SCC]]),
+ ?debug("Checking SCC: ~tw\n", [[debug_lookup_name(F) || F <- SCC]]),
SolveFun = fun(X, Y) -> scc_fold_fun(X, Y, State) end,
Map2 = lists:foldl(SolveFun, Map1, ToSolve),
Updated = updated_vars_only(Vars, Map, Map2),
case Updated =:= [] of
true ->
- ?debug("SCC ~w reached fixpoint\n", [SCC]),
+ ?debug("SCC ~tw reached fixpoint\n", [SCC]),
NewTypes = unsafe_lookup_type_list(Funs, Map2),
case erl_types:any_none([t_fun_range(T) || T <- NewTypes])
andalso TryingUnit =:= false of
@@ -1859,7 +1850,7 @@ solve_scc(SCC, Map, State, Users, ToSolve, TryingUnit) ->
Map2
end;
false ->
- ?debug("SCC ~w did not reach fixpoint\n", [SCC]),
+ ?debug("SCC ~tw did not reach fixpoint\n", [SCC]),
ToSolve1 = affected(Updated, Users),
solve_scc(SCC, Map2, State, Users, ToSolve1, TryingUnit)
end.
@@ -1883,8 +1874,8 @@ scc_fold_fun(F, FunMap, State) ->
error ->
enter_type(F, NewType, FunMap)
end,
- ?debug("Done solving for function ~w :: ~s\n", [debug_lookup_name(F),
- format_type(NewType)]),
+ ?debug("Done solving for function ~tw :: ~ts\n", [debug_lookup_name(F),
+ format_type(NewType)]),
NewFunMap.
solve(Fun, Cs, FunMap, State) ->
@@ -1903,7 +1894,7 @@ solver(Solver, SolveFun) ->
[Solver, _R, 60]),
throw(error)
catch E:R ->
- io:format("Solver ~w failed: ~w:~p\n ~p\n",
+ io:format("Solver ~w failed: ~w:~p\n ~tp\n",
[Solver, E, R, erlang:get_stacktrace()]),
throw(error)
end.
@@ -1925,8 +1916,8 @@ check_solutions([{S1,Map1,_Time1}|Maps], Fun, S, Map) ->
check_solutions(Maps, Fun, S1, Map1);
false ->
?debug("Constraint solvers do not agree on ~w\n", [Fun]),
- pp_map(atom_to_list(S), Map),
- pp_map(atom_to_list(S1), Map1),
+ ?pp_map(atom_to_list(S), Map),
+ ?pp_map(atom_to_list(S1), Map1),
io:format("A bug was found. Please report it, and use the option "
"`--solver v1' until the bug has been fixed.\n"),
throw(error)
@@ -1940,9 +1931,9 @@ sane_maps(Map1, Map2, Keys, _S1, _S2) ->
true -> true;
false ->
?debug("Constraint solvers do not agree on ~w\n", [Key]),
- ?debug("~w: ~s\n",
+ ?debug("~w: ~ts\n",
[_S1, format_type(unsafe_lookup_type(Key, Map1))]),
- ?debug("~w: ~s\n",
+ ?debug("~w: ~ts\n",
[_S2, format_type(unsafe_lookup_type(Key, Map2))]),
false
end
@@ -1974,8 +1965,8 @@ v2_solve(#constraint_ref{id = Id}, Map, V2State) ->
v2_solve_reference(Id, Map, V2State).
v2_solve_reference(Id, Map, V2State0) ->
- ?debug("Checking ref to fun: ~w\n", [debug_lookup_name(Id)]),
- pp_map("Map", Map),
+ ?debug("Checking ref to fun: ~tw\n", [debug_lookup_name(Id)]),
+ ?pp_map("Map", Map),
pp_constr_data("solve_ref", V2State0),
Map1 = restore_local_map(V2State0, Id, Map),
State = V2State0#v2_state.state,
@@ -1988,7 +1979,7 @@ v2_solve_reference(Id, Map, V2State0) ->
{FunType, V2State} =
case Res of
{error, V2State1} ->
- ?debug("Error solving for function ~p\n", [debug_lookup_name(Id)]),
+ ?debug("Error solving for function ~tp\n", [debug_lookup_name(Id)]),
Arity = state__fun_arity(Id, State),
FunType0 =
case state__prop_domain(t_var_name(Id), State) of
@@ -1997,12 +1988,12 @@ v2_solve_reference(Id, Map, V2State0) ->
end,
{FunType0, V2State1};
{ok, NewMap, V2State1, U} ->
- ?debug("Done solving fun: ~p\n", [debug_lookup_name(Id)]),
+ ?debug("Done solving fun: ~tp\n", [debug_lookup_name(Id)]),
FunType0 = lookup_type(Id, NewMap),
V2State2 = save_local_map(V2State1, Id, U, NewMap),
{FunType0, V2State2}
end,
- ?debug("ref Id=~w Assigned ~s\n", [Id, format_type(FunType)]),
+ ?debug("ref Id=~w Assigned ~ts\n", [Id, format_type(FunType)]),
{NewMap1, U1} = enter_var_type(Id, FunType, Map),
{NewMap2, U2} =
case state__get_rec_var(Id, State) of
@@ -2012,10 +2003,10 @@ v2_solve_reference(Id, Map, V2State0) ->
{ok, NewMap2, V2State, lists:umerge(U1, U2)}.
v2_solve_self_recursive(Cs, Map, Id, RecType0, V2State0) ->
- ?debug("Solving self recursive ~w\n", [debug_lookup_name(Id)]),
+ ?debug("Solving self recursive ~tw\n", [debug_lookup_name(Id)]),
State = V2State0#v2_state.state,
{ok, RecVar} = state__get_rec_var(Id, State),
- ?debug("OldRecType ~s\n", [format_type(RecType0)]),
+ ?debug("OldRecType ~ts\n", [format_type(RecType0)]),
RecType = t_limit(RecType0, ?TYPE_LIMIT),
{Map1, U0} = enter_var_type(RecVar, RecType, Map),
V2State1 = save_updated_vars1(V2State0, Cs, U0), % Probably not necessary
@@ -2031,7 +2022,7 @@ v2_solve_self_recursive(Cs, Map, Id, RecType0, V2State0) ->
Error
end;
{ok, NewMap, V2State, U} ->
- pp_map("recursive finished", NewMap),
+ ?pp_map("recursive finished", NewMap),
NewRecType = unsafe_lookup_type(Id, NewMap),
case is_equal(NewRecType, RecType0) of
true ->
@@ -2049,7 +2040,7 @@ enter_var_type(Var, Type, Map0) ->
v2_solve_disjunct(Disj, Map, V2State0) ->
#constraint_list{type = disj, id = _Id, list = Cs, masks = Masks} = Disj,
?debug("disjunct Id=~w~n", [_Id]),
- pp_map("Map", Map),
+ ?pp_map("Map", Map),
pp_constr_data("disjunct", V2State0),
case get_flags(V2State0, Disj) of
{V2State1, failed_list} -> {error, V2State1}; % cannot happen
@@ -2077,7 +2068,7 @@ v2_solve_disjunct(Disj, Map, V2State0) ->
U1 = [V || V <- U0,
var_occurs_everywhere(V, Masks, NotFailed)],
NewMap = join_maps(U1, MapL, Map),
- pp_map("NewMap", NewMap),
+ ?pp_map("NewMap", NewMap),
U = updated_vars_only(U1, Map, NewMap),
?debug("disjunct finished _Id=~w\n", [_Id]),
{ok, NewMap, V2State, U}
@@ -2100,12 +2091,18 @@ v2_solve_disj([I|Is], [C|Cs], I, Map0, V2State0, UL, MapL, Eval, Uneval,
{ok, Map, V2State1, U} ->
?debug("disj I=~w U=~w~n", [I, U]),
V2State = save_local_map(V2State1, Id, U, Map),
- pp_map("DMap", Map),
+ ?pp_map("DMap", Map),
v2_solve_disj(Is, Cs, I+1, Map0, V2State, [U|UL], [Map|MapL],
[I|Eval], Uneval, Failed0)
end;
v2_solve_disj([], [], _I, _Map, V2State, UL, MapL, Eval, Uneval, Failed) ->
{ok, V2State, lists:reverse(Eval), UL, MapL, lists:reverse(Uneval), Failed};
+v2_solve_disj([every_i], Cs, I, Map, V2State, UL, MapL, Eval, Uneval, Failed) ->
+ NewIs = case Cs of
+ [] -> [];
+ _ -> [I, every_i]
+ end,
+ v2_solve_disj(NewIs, Cs, I, Map, V2State, UL, MapL, Eval, Uneval, Failed);
v2_solve_disj(Is, [C|Cs], I, Map, V2State, UL, MapL, Eval, Uneval0, Failed) ->
Uneval = [{I,C#constraint_list.id} ||
not is_failed_list(C, V2State)] ++ Uneval0,
@@ -2120,9 +2117,9 @@ save_local_map(#v2_state{constr_data = ConData}=V2State, Id, U, Map) ->
end,
?debug("save local map Id=~w:\n", [Id]),
Part = lists:ukeymerge(1, lists:keysort(1, Part0), Part1),
- pp_map("New Part", maps:from_list(Part0)),
- pp_map("Old Part", maps:from_list(Part1)),
- pp_map(" => Part", maps:from_list(Part)),
+ ?pp_map("New Part", maps:from_list(Part0)),
+ ?pp_map("Old Part", maps:from_list(Part1)),
+ ?pp_map(" => Part", maps:from_list(Part)),
V2State#v2_state{constr_data = maps:put(Id, {Part,[]}, ConData)}.
restore_local_map(#v2_state{constr_data = ConData}, Id, Map0) ->
@@ -2133,10 +2130,10 @@ restore_local_map(#v2_state{constr_data = ConData}, Id, Map0) ->
{ok, {Part0,U}} ->
Part = [KV || {K,_V} = KV <- Part0, not lists:member(K, U)],
?debug("restore local map Id=~w U=~w\n", [Id, U]),
- pp_map("Part", maps:from_list(Part)),
- pp_map("Map0", Map0),
+ ?pp_map("Part", maps:from_list(Part)),
+ ?pp_map("Map0", Map0),
Map = lists:foldl(fun({K,V}, D) -> maps:put(K, V, D) end, Map0, Part),
- pp_map("Map", Map),
+ ?pp_map("Map", Map),
Map
end.
@@ -2177,7 +2174,7 @@ v2_solve_conj([I|Is], [Cs|Tail], I, Map0, Conj, IsFlat, V2State0,
M = lists:keydelete(I, 1, vars_per_child(U, Masks)),
{V2State2, NewF0} = save_updated_vars_list(AllCs, M, V2State1),
{NewF, F} = lists:splitwith(fun(J) -> J < I end, NewF0),
- Is1 = lists:umerge(Is, F),
+ Is1 = umerge_mask(Is, F),
NewFs = [NewF|NewFs0],
v2_solve_conj(Is1, Tail, I+1, Map, Conj, IsFlat, V2State2,
[U|UL], NewFs, VarsUp, LastMap, LastFlags)
@@ -2199,6 +2196,14 @@ v2_solve_conj([], _Cs, _I, Map, Conj, IsFlat, V2State, UL, NewFs, VarsUp,
v2_solve_conj(NewFlags, Cs, 1, Map, Conj, IsFlat, V2State,
[], [], [U|VarsUp], Map, NewFlags)
end;
+v2_solve_conj([every_i], Cs, I, Map, Conj, IsFlat, V2State, UL, NewFs, VarsUp,
+ LastMap, LastFlags) ->
+ NewIs = case Cs of
+ [] -> [];
+ _ -> [I, every_i]
+ end,
+ v2_solve_conj(NewIs, Cs, I, Map, Conj, IsFlat, V2State, UL, NewFs, VarsUp,
+ LastMap, LastFlags);
v2_solve_conj(Is, [_|Tail], I, Map, Conj, IsFlat, V2State, UL, NewFs, VarsUp,
LastMap, LastFlags) ->
v2_solve_conj(Is, Tail, I+1, Map, Conj, IsFlat, V2State, UL, NewFs, VarsUp,
@@ -2215,7 +2220,12 @@ report_detected_loop(_) ->
add_mask_to_flags(Flags, [Im|M], I, L) when I > Im ->
add_mask_to_flags(Flags, M, I, [Im|L]);
add_mask_to_flags(Flags, [_|M], _I, L) ->
- {lists:umerge(M, Flags), lists:reverse(L)}.
+ {umerge_mask(Flags, M), lists:reverse(L)}.
+
+umerge_mask([every_i]=Is, _F) ->
+ Is;
+umerge_mask(Is, F) ->
+ lists:umerge(Is, F).
get_mask(V, Masks) ->
case maps:find(V, Masks) of
@@ -2229,7 +2239,7 @@ get_flags(#v2_state{constr_data = ConData}=V2State0, C) ->
error ->
?debug("get_flags Id=~w Flags=all ~w\n", [Id, length(Cs)]),
V2State = V2State0#v2_state{constr_data = maps:put(Id, {[],[]}, ConData)},
- {V2State, lists:seq(1, length(Cs))};
+ {V2State, [every_i]};
{ok, failed} ->
{V2State0, failed_list};
{ok, {Part,U}} when U =/= [] ->
@@ -2279,7 +2289,7 @@ pp_constr_data(_Tag, #v2_state{constr_data = D}) ->
case _PartU of
{_Part, _U} ->
io:format("Id: ~w Vars: ~w\n", [_Id, _U]),
- [pp_map("Part", maps:from_list(_Part)) || _Part =/= []];
+ [?pp_map("Part", maps:from_list(_Part)) || _Part =/= []];
failed ->
io:format("Id: ~w failed list\n", [_Id])
end
@@ -2308,7 +2318,7 @@ solve_ref_or_list(#constraint_ref{id = Id, deps = Deps},
error -> {map_new(), false};
{ok, M} -> {M, true}
end,
- ?debug("Checking ref to fun: ~w\n", [debug_lookup_name(Id)]),
+ ?debug("Checking ref to fun: ~tw\n", [debug_lookup_name(Id)]),
%% Note: mk_constraint_ref() has already removed Id from Deps. The
%% reason for doing it there is that it makes it easy for
%% calculate_masks() to make the corresponding adjustment for
@@ -2330,7 +2340,7 @@ solve_ref_or_list(#constraint_ref{id = Id, deps = Deps},
{NewMapDict, FunType} =
case Res of
{error, NewMapDict0} ->
- ?debug("Error solving for function ~p\n", [debug_lookup_name(Id)]),
+ ?debug("Error solving for function ~tp\n", [debug_lookup_name(Id)]),
Arity = state__fun_arity(Id, State),
FunType0 =
case state__prop_domain(t_var_name(Id), State) of
@@ -2339,11 +2349,11 @@ solve_ref_or_list(#constraint_ref{id = Id, deps = Deps},
end,
{NewMapDict0, FunType0};
{ok, NewMapDict0, NewMap} ->
- ?debug("Done solving fun: ~p\n", [debug_lookup_name(Id)]),
+ ?debug("Done solving fun: ~tp\n", [debug_lookup_name(Id)]),
FunType0 = lookup_type(Id, NewMap),
{NewMapDict0, FunType0}
end,
- ?debug(" Id=~w Assigned ~s\n", [Id, format_type(FunType)]),
+ ?debug(" Id=~w Assigned ~ts\n", [Id, format_type(FunType)]),
NewMap1 = enter_type(Id, FunType, Map),
NewMap2 =
case state__get_rec_var(Id, State) of
@@ -2365,21 +2375,21 @@ solve_ref_or_list(#constraint_list{type=Type, list = Cs, deps = Deps, id = Id},
true ->
case Check andalso maps_are_equal(OldLocalMap, Map, Deps) of
true ->
- ?debug("~w equal ~w\n", [Type, Id]),
+ ?debug("~tw equal ~w\n", [Type, Id]),
{ok, MapDict, Map};
false ->
- ?debug("~w not equal: ~w. Solving\n", [Type, Id]),
+ ?debug("~tw not equal: ~w. Solving\n", [Type, Id]),
solve_clist(Cs, Type, Id, Deps, MapDict, Map, State)
end
end.
solve_self_recursive(Cs, Map, MapDict, Id, RecType0, State) ->
- ?debug("Solving self recursive ~w\n", [debug_lookup_name(Id)]),
+ ?debug("Solving self recursive ~tw\n", [debug_lookup_name(Id)]),
{ok, RecVar} = state__get_rec_var(Id, State),
- ?debug("OldRecType ~s\n", [format_type(RecType0)]),
+ ?debug("OldRecType ~ts\n", [format_type(RecType0)]),
RecType = t_limit(RecType0, ?TYPE_LIMIT),
Map1 = enter_type(RecVar, RecType, erase_type(t_var_name(Id), Map)),
- pp_map("Map1", Map1),
+ ?pp_map("Map1", Map1),
case solve_ref_or_list(Cs, Map1, MapDict, State) of
{error, _} = Error ->
case t_is_none(RecType0) of
@@ -2392,7 +2402,7 @@ solve_self_recursive(Cs, Map, MapDict, Id, RecType0, State) ->
Error
end;
{ok, NewMapDict, NewMap} ->
- pp_map("NewMap", NewMap),
+ ?pp_map("NewMap", NewMap),
NewRecType = unsafe_lookup_type(Id, NewMap),
case is_equal(NewRecType, RecType0) of
true ->
@@ -2458,7 +2468,7 @@ solve_one_c(#constraint{lhs = Lhs, rhs = Rhs, op = Op}, Map) ->
LhsType = lookup_type(Lhs, Map),
RhsType = lookup_type(Rhs, Map),
Inf = t_inf(LhsType, RhsType),
- ?debug("Solving: ~s :: ~s ~w ~s :: ~s\n\tInf: ~s\n",
+ ?debug("Solving: ~ts :: ~ts ~w ~ts :: ~ts\n\tInf: ~ts\n",
[format_type(Lhs), format_type(LhsType), Op,
format_type(Rhs), format_type(RhsType), format_type(Inf)]),
case t_is_none(Inf) of
@@ -2490,14 +2500,14 @@ solve_subtype(Type, Inf, Map) ->
{_, List} -> {ok, enter_type_list(List, Map)}
catch
throw:{mismatch, _T1, _T2} ->
- ?debug("Mismatch between ~s and ~s\n",
+ ?debug("Mismatch between ~ts and ~ts\n",
[format_type(_T1), format_type(_T2)]),
error
end.
%% end.
report_failed_constraint(_C, _Map) ->
- ?debug("+++++++++++\nFailed: ~s :: ~s ~w ~s :: ~s\n+++++++++++\n",
+ ?debug("+++++++++++\nFailed: ~ts :: ~ts ~w ~ts :: ~ts\n+++++++++++\n",
[format_type(_C#constraint.lhs),
format_type(lookup_type(_C#constraint.lhs, _Map)),
_C#constraint.op,
@@ -2555,7 +2565,7 @@ maps_are_equal_1(Map1, Map2, [H|Tail]) ->
case is_equal(T1, T2) of
true -> maps_are_equal_1(Map1, Map2, Tail);
false ->
- ?debug("~w: ~s =/= ~s\n", [H, format_type(T1), format_type(T2)]),
+ ?debug("~w: ~ts =/= ~ts\n", [H, format_type(T1), format_type(T2)]),
false
end;
maps_are_equal_1(_Map1, _Map2, []) ->
@@ -2583,7 +2593,7 @@ prune_keys(Map1, Map2, Deps) ->
end.
enter_type(Key, Val, Map) when is_integer(Key) ->
- ?debug("Entering ~s :: ~s\n", [format_type(t_var(Key)), format_type(Val)]),
+ ?debug("Entering ~ts :: ~ts\n", [format_type(t_var(Key)), format_type(Val)]),
%% Keep any() in the map if it is opaque:
case is_equal(Val, t_any()) of
true ->
@@ -2592,7 +2602,7 @@ enter_type(Key, Val, Map) when is_integer(Key) ->
LimitedVal = t_limit(Val, ?INTERNAL_TYPE_LIMIT),
case is_equal(LimitedVal, Val) of
true -> ok;
- false -> ?debug("LimitedVal ~s\n", [format_type(LimitedVal)])
+ false -> ?debug("LimitedVal ~ts\n", [format_type(LimitedVal)])
end,
case maps:find(Key, Map) of
{ok, Value} ->
@@ -2627,7 +2637,7 @@ enter_type2(Key, Val, Map) ->
{Map1, [Key || not is_same(Key, Map, Map1)]}.
map_store(Key, Val, Map) ->
- ?debug("Storing ~w :: ~s\n", [Key, format_type(Val)]),
+ ?debug("Storing ~tw :: ~ts\n", [Key, format_type(Val)]),
maps:put(Key, Val, Map).
erase_type(Key, Map) ->
@@ -2691,22 +2701,20 @@ is_same(Key, Map1, Map2) ->
is_equal(Type1, Type2) ->
t_is_equal(Type1, Type2).
-pp_map(_S, _Map) ->
- ?debug("\t~s: ~p\n",
- [_S, [{X, lists:flatten(format_type(Y))} ||
- {X, Y} <- lists:keysort(1, maps:to_list(_Map))]]).
-
%% ============================================================================
%%
%% The State.
%%
%% ============================================================================
-new_state(SCC0, NextLabel, CallGraph, Plt, PropTypes, Solvers) ->
- List = [{MFA, Var} || {MFA, {Var, _Fun}, _Rec} <- SCC0],
+new_state(MFAs, NextLabel, CallGraph, CServer, Plt, PropTypes0, Solvers) ->
+ List_SCC =
+ [begin
+ {Var, Label} = dialyzer_codeserver:lookup_mfa_var_label(MFA, CServer),
+ {{MFA, Var}, t_var(Label)}
+ end || MFA <- MFAs],
+ {List, SCC} = lists:unzip(List_SCC),
NameMap = maps:from_list(List),
- MFAs = [MFA || {MFA, _Var} <- List],
- SCC = [mk_var(Fun) || {_MFA, {_Var, Fun}, _Rec} <- SCC0],
SelfRec =
case SCC of
[OneF] ->
@@ -2717,12 +2725,14 @@ new_state(SCC0, NextLabel, CallGraph, Plt, PropTypes, Solvers) ->
end;
_Many -> false
end,
+ PropTypes = dict:from_list(PropTypes0),
#state{callgraph = CallGraph, name_map = NameMap, next_label = NextLabel,
prop_types = PropTypes, plt = Plt, scc = ordsets:from_list(SCC),
- mfas = MFAs, self_rec = SelfRec, solvers = Solvers}.
+ mfas = MFAs, self_rec = SelfRec, solvers = Solvers,
+ cserver = CServer}.
-state__set_rec_dict(State, RecDict) ->
- State#state{records = RecDict}.
+state__set_module(State, Module) ->
+ State#state{module = Module}.
state__set_in_match(State, Bool) ->
State#state{in_match = Bool}.
@@ -2832,7 +2842,7 @@ state__add_prop_constrs(Tree, #state{prop_types = PropTypes} = State) ->
case erl_types:any_none(ArgTypes) of
true -> not_called;
false ->
- ?debug("Adding propagated constr: ~s for function ~w\n",
+ ?debug("Adding propagated constr: ~ts for function ~tw\n",
[format_type(FunType), debug_lookup_name(mk_var(Tree))]),
FunVar = mk_var(Tree),
state__store_conj(FunVar, sub, FunType, State)
@@ -2906,8 +2916,9 @@ state__get_rec_var(Fun, #state{fun_map = Map}) ->
maps:find(Fun, Map).
state__finalize(State) ->
- State1 = enumerate_constraints(State),
- order_fun_constraints(State1).
+ State1 = state__new_constraint_context(State),
+ State2 = enumerate_constraints(State1),
+ order_fun_constraints(State2).
%% ============================================================================
%%
@@ -2960,6 +2971,11 @@ mk_fun_var(Line, Fun, Types) ->
Deps = [t_var_name(Var) || Var <- t_collect_vars(t_product(Types))],
#fun_var{'fun' = Fun, deps = ordsets:from_list(Deps), origin = Line}.
+pp_map(S, Map) ->
+ ?debug("\t~s: ~p\n",
+ [S, [{X, lists:flatten(format_type(Y))} ||
+ {X, Y} <- lists:keysort(1, maps:to_list(Map))]]).
+
-else.
-spec mk_fun_var(fun((_) -> erl_types:erl_type()), [erl_types:erl_type()]) -> #fun_var{}.
@@ -2987,7 +3003,7 @@ find_constraint_deps([Type|Tail], Acc) ->
NewAcc = [[t_var_name(D) || D <- t_collect_vars(Type)]|Acc],
find_constraint_deps(Tail, NewAcc);
find_constraint_deps([], Acc) ->
- lists:flatten(Acc).
+ lists:append(Acc).
mk_constraint_1(Lhs, eq, Rhs, Deps) when Lhs < Rhs ->
#constraint{lhs = Lhs, op = eq, rhs = Rhs, deps = Deps};
@@ -3095,8 +3111,8 @@ expand_to_conjunctions(#constraint_list{type = disj, list = List}) ->
List1 = [C || C <- List, is_simple_constraint(C)],
%% Just an assert.
[] = [C || #constraint{} = C <- List1],
- Expanded = lists:flatten([expand_to_conjunctions(C)
- || #constraint_list{} = C <- List]),
+ Expanded = lists:append([expand_to_conjunctions(C)
+ || #constraint_list{} = C <- List]),
ReturnList = Expanded ++ List1,
if length(ReturnList) > ?DISJ_NORM_FORM_LIMIT -> throw(too_many_disj);
true -> ReturnList
@@ -3121,8 +3137,10 @@ calculate_deps(List) ->
calculate_deps([H|Tail], Acc) ->
Deps = get_deps(H),
calculate_deps(Tail, [Deps|Acc]);
+calculate_deps([], []) -> [];
+calculate_deps([], [L]) -> L;
calculate_deps([], Acc) ->
- ordsets:from_list(lists:flatten(Acc)).
+ lists:umerge(Acc).
mk_conj_constraint_list(List) ->
mk_constraint_list(conj, List).
@@ -3190,7 +3208,8 @@ order_fun_constraints(State) ->
order_fun_constraints([#constraint_ref{id = Id}|Tail], State) ->
Cs = state__get_cs(Id, State),
- {[NewCs], State1} = order_fun_constraints([Cs], [], [], State),
+ {[Cs1], State1} = order_fun_constraints([Cs], [], [], State),
+ NewCs = Cs1#constraint_list{deps = Cs#constraint_list.deps},
NewState = state__store_constrs(Id, NewCs, State1),
order_fun_constraints(Tail, NewState);
order_fun_constraints([], State) ->
@@ -3198,23 +3217,31 @@ order_fun_constraints([], State) ->
order_fun_constraints([#constraint_ref{} = C|Tail], Funs, Acc, State) ->
order_fun_constraints(Tail, [C|Funs], Acc, State);
-order_fun_constraints([#constraint_list{list = List, type = Type} = C|Tail],
+order_fun_constraints([#constraint_list{list = List,
+ type = Type,
+ masks = OldMasks} = C|Tail],
Funs, Acc, State) ->
- {NewList, NewState} =
- case Type of
- conj -> order_fun_constraints(List, [], [], State);
- disj ->
- FoldFun = fun(X, AccState) ->
- {[NewX], NewAccState} =
- order_fun_constraints([X], [], [], AccState),
- {NewX, NewAccState}
- end,
- lists:mapfoldl(FoldFun, State, List)
- end,
- C1 = update_constraint_list(C, NewList),
- Masks = calculate_masks(NewList, 1, []),
- NewAcc = [update_masks(C1, Masks)|Acc],
- order_fun_constraints(Tail, Funs, NewAcc, NewState);
+ case OldMasks of
+ undefined ->
+ {NewList, NewState} =
+ case Type of
+ conj -> order_fun_constraints(List, [], [], State);
+ disj ->
+ FoldFun = fun(X, AccState) ->
+ {[NewX], NewAccState} =
+ order_fun_constraints([X], [], [], AccState),
+ {NewX, NewAccState}
+ end,
+ lists:mapfoldl(FoldFun, State, List)
+ end,
+ NewList2 = reset_deps(NewList, State),
+ C1 = update_constraint_list(C, NewList2),
+ Masks = calculate_masks(NewList, 1, []),
+ NewAcc = [update_masks(C1, Masks)|Acc],
+ order_fun_constraints(Tail, Funs, NewAcc, NewState);
+ M when is_map(M) ->
+ order_fun_constraints(Tail, Funs, [C|Acc], State)
+ end;
order_fun_constraints([#constraint{} = C|Tail], Funs, Acc, State) ->
order_fun_constraints(Tail, Funs, [C|Acc], State);
order_fun_constraints([], Funs, Acc, State) ->
@@ -3224,6 +3251,18 @@ order_fun_constraints([], Funs, Acc, State) ->
update_masks(C, Masks) ->
C#constraint_list{masks = Masks}.
+reset_deps(ConstrList, #state{solvers = Solvers}) ->
+ case lists:member(v1, Solvers) of
+ true ->
+ ConstrList;
+ false ->
+ [reset_deps(Constr) || Constr <- ConstrList]
+ end.
+
+reset_deps(#constraint{}=C) -> C#constraint{deps = []};
+reset_deps(#constraint_list{}=C) -> C#constraint_list{deps = []};
+reset_deps(#constraint_ref{}=C) -> C#constraint_ref{deps = []}.
+
calculate_masks([C|Cs], I, L0) ->
calculate_masks(Cs, I+1, [{V, I} || V <- get_deps(C)] ++ L0);
calculate_masks([], _I, L) ->
@@ -3310,15 +3349,25 @@ fold_literal_maybe_match(Tree0, State) ->
true -> dialyzer_utils:refold_pattern(Tree1)
end.
-lookup_record(Records, Tag, Arity) ->
- case erl_types:lookup_record(Tag, Arity, Records) of
+lookup_record(State, Tag, Arity) ->
+ #state{module = M, mod_records = ModRecs, cserver = CServer} = State,
+ {State1, Rec} =
+ case lists:keyfind(M, 1, ModRecs) of
+ {M, Rec0} ->
+ {State, Rec0};
+ false ->
+ Rec0 = dialyzer_codeserver:lookup_mod_records(M, CServer),
+ NewModRecs = [{M, Rec0}|ModRecs],
+ {State#state{mod_records = NewModRecs}, Rec0}
+ end,
+ case erl_types:lookup_record(Tag, Arity, Rec) of
{ok, Fields} ->
RecType =
t_tuple([t_from_term(Tag)|
[FieldType || {_FieldName, _Abstr, FieldType} <- Fields]]),
- {ok, RecType};
+ {ok, RecType, State1};
error ->
- error
+ {error, State1}
end.
is_literal_record(Tree) ->
@@ -3343,10 +3392,10 @@ family(L) ->
-ifdef(DEBUG).
format_type(#fun_var{deps = Deps, origin = Origin}) ->
L = [format_type(t_var(X)) || X <- Deps],
- io_lib:format("Fun@L~p(~s)", [Origin, join_chars(L, ",")]);
+ io_lib:format("Fun@L~p(~ts)", [Origin, join_chars(L, ",")]);
format_type(Type) ->
case cerl:is_literal(Type) of
- true -> io_lib:format("~w", [cerl:concrete(Type)]);
+ true -> io_lib:format("~tw", [cerl:concrete(Type)]);
false -> erl_types:t_to_string(Type)
end.
@@ -3388,7 +3437,7 @@ pp_constrs_scc(SCC, State) ->
[pp_constrs(Fun, state__get_cs(Fun, State), State) || Fun <- SCC].
pp_constrs(Fun, Cs, State) ->
- io:format("Constraints for fun: ~w", [debug_lookup_name(Fun)]),
+ io:format("Constraints for fun: ~tw", [debug_lookup_name(Fun)]),
MaxDepth = pp_constraints(Cs, State),
io:format("Depth: ~w\n", [MaxDepth]).
@@ -3426,7 +3475,7 @@ pp_constraints([#constraint_list{type = Type, list = List, id = Id}|Tail],
pp_op(#constraint{lhs = Lhs, op = Op, rhs = Rhs}, Level) ->
pp_indent(Level),
- io:format("~s ~w ~s", [format_type(Lhs), Op, format_type(Rhs)]).
+ io:format("~ts ~w ~ts", [format_type(Lhs), Op, format_type(Rhs)]).
pp_indent(Level) ->
io:format("\n~*s", [Level*2, ""]).
@@ -3438,19 +3487,25 @@ pp_constrs_scc(_SCC, _State) ->
-ifdef(TO_DOT).
constraints_to_dot_scc(SCC, State) ->
- io:format("SCC: ~p\n", [SCC]),
- Name = lists:flatten([io_lib:format("'~w'", [debug_lookup_name(Fun)])
- || Fun <- SCC]),
+ %% TODO: handle Unicode names.
+ io:format("SCC: ~tp\n", [SCC]),
+ Name = lists:flatten([format_lookup_name(debug_lookup_name(Fun))
+ || Fun <- SCC]),
Cs = [state__get_cs(Fun, State) || Fun <- SCC],
constraints_to_dot(Cs, Name, State).
+format_lookup_name({FunName, Arity}) ->
+ TupleS = io_lib:format("{~ts,~w}", [atom_to_list(FunName), Arity]),
+ io_lib:format("~tw", [list_to_atom(lists:flatten(TupleS))]).
+
constraints_to_dot(Cs0, Name, State) ->
NofCs = length(Cs0),
Cs = lists:zip(lists:seq(1, NofCs), Cs0),
{Graph, Opts, _N} = constraints_to_nodes(Cs, NofCs + 1, 1, [], [], State),
hipe_dot:translate_list(Graph, "/tmp/cs.dot", "foo", Opts),
+ %% "-T ps" works for Latin-1. hipe_dot cannot handle UTF-8 either.
Res = os:cmd("dot -o /tmp/"++ Name ++ ".ps -T ps /tmp/cs.dot"),
- io:format("Res: ~p~n", [Res]),
+ io:format("Res: ~ts~n", [Res]),
ok.
constraints_to_nodes([{Name, #constraint_list{type = Type, list = List, id=Id}}
@@ -3469,7 +3524,7 @@ constraints_to_nodes([{Name, #constraint_list{type = Type, list = List, id=Id}}
constraints_to_nodes(Left, N2, Level, NewGraph, NewOpts, State);
constraints_to_nodes([{Name, #constraint{lhs = Lhs, op = Op, rhs = Rhs}}|Left],
N, Level, Graph, Opts, State) ->
- Label = lists:flatten(io_lib:format("~s ~w ~s",
+ Label = lists:flatten(io_lib:format("~ts ~w ~ts",
[format_type(Lhs), Op,
format_type(Rhs)])),
ThisNode = [{Name, Opt} || Opt <- [{label, Label}, {level, Level}]],
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl
index 76a5cf3d0b..511a6d66bf 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_utils.erl
@@ -31,25 +24,23 @@
-export([
format_sig/1,
format_sig/2,
- get_abstract_code_from_beam/1,
- get_compile_options_from_beam/1,
- get_abstract_code_from_src/1,
- get_abstract_code_from_src/2,
- get_core_from_abstract_code/1,
- get_core_from_abstract_code/2,
get_core_from_src/1,
get_core_from_src/2,
+ get_core_from_beam/1,
+ get_core_from_beam/2,
get_record_and_type_info/1,
get_spec_info/3,
get_fun_meta_info/3,
is_suppressed_fun/2,
is_suppressed_tag/3,
- merge_records/2,
pp_hook/0,
process_record_remote_types/1,
+ merge_types/2,
sets_filter/2,
src_compiler_opts/0,
refold_pattern/1,
+ ets_tab2list/1,
+ ets_move/2,
parallelism/0,
family/1
]).
@@ -67,15 +58,15 @@ print_types1([], _) ->
ok;
print_types1([{type, _Name, _NArgs} = Key|T], RecDict) ->
{ok, {{_Mod, _FileLine, _Form, _Args}, Type}} = dict:find(Key, RecDict),
- io:format("\n~w: ~w\n", [Key, Type]),
+ io:format("\n~tw: ~tw\n", [Key, Type]),
print_types1(T, RecDict);
print_types1([{opaque, _Name, _NArgs} = Key|T], RecDict) ->
{ok, {{_Mod, _FileLine, _Form, _Args}, Type}} = dict:find(Key, RecDict),
- io:format("\n~w: ~w\n", [Key, Type]),
+ io:format("\n~tw: ~tw\n", [Key, Type]),
print_types1(T, RecDict);
print_types1([{record, _Name} = Key|T], RecDict) ->
{ok, {_FileLine, [{_Arity, _Fields} = AF]}} = dict:find(Key, RecDict),
- io:format("~w: ~w\n\n", [Key, AF]),
+ io:format("~tw: ~tw\n\n", [Key, AF]),
print_types1(T, RecDict).
-define(debug(D_), print_types(D_)).
-else.
@@ -84,9 +75,7 @@ print_types1([{record, _Name} = Key|T], RecDict) ->
%% ----------------------------------------------------------------------------
--type abstract_code() :: [erl_parse:abstract_form()].
-type comp_options() :: [compile:option()].
--type mod_or_fname() :: module() | file:filename().
-type fa() :: {atom(), arity()}.
-type codeserver() :: dialyzer_codeserver:codeserver().
@@ -96,63 +85,82 @@ print_types1([{record, _Name} = Key|T], RecDict) ->
%%
%% ============================================================================
--spec get_abstract_code_from_src(mod_or_fname()) ->
- {'ok', abstract_code()} | {'error', [string()]}.
+-type get_core_from_src_ret() :: {'ok', cerl:c_module()} | {'error', string()}.
+
+-spec get_core_from_src(file:filename()) -> get_core_from_src_ret().
-get_abstract_code_from_src(File) ->
- get_abstract_code_from_src(File, src_compiler_opts()).
+get_core_from_src(File) ->
+ get_core_from_src(File, []).
--spec get_abstract_code_from_src(mod_or_fname(), comp_options()) ->
- {'ok', abstract_code()} | {'error', [string()]}.
+-spec get_core_from_src(file:filename(), comp_options()) -> get_core_from_src_ret().
-get_abstract_code_from_src(File, Opts) ->
- case compile:noenv_file(File, [to_pp, binary|Opts]) of
+get_core_from_src(File, Opts) ->
+ case compile:noenv_file(File, Opts ++ src_compiler_opts()) of
error -> {error, []};
{error, Errors, _} -> {error, format_errors(Errors)};
- {ok, _, AbstrCode} -> {ok, AbstrCode}
+ {ok, _, Core} -> {ok, Core}
end.
--type get_core_from_src_ret() :: {'ok', cerl:c_module()} | {'error', string()}.
+-type get_core_from_beam_ret() :: {'ok', cerl:c_module()} | {'error', string()}.
--spec get_core_from_src(file:filename()) -> get_core_from_src_ret().
+-spec get_core_from_beam(file:filename()) -> get_core_from_beam_ret().
-get_core_from_src(File) ->
- get_core_from_src(File, []).
+get_core_from_beam(File) ->
+ get_core_from_beam(File, []).
--spec get_core_from_src(file:filename(), comp_options()) -> get_core_from_src_ret().
+-spec get_core_from_beam(file:filename(), comp_options()) -> get_core_from_beam_ret().
-get_core_from_src(File, Opts) ->
- case get_abstract_code_from_src(File, Opts) of
- {error, _} = Error -> Error;
+get_core_from_beam(File, Opts) ->
+ case beam_lib:chunks(File, [debug_info]) of
+ {ok, {Module, [{debug_info, {debug_info_v1, Backend, Metadata}}]}} ->
+ case Backend:debug_info(core_v1, Module, Metadata, Opts ++ src_compiler_opts()) of
+ {ok, Core} ->
+ {ok, Core};
+ {error, _} ->
+ {error, " Could not get Core Erlang code for: " ++ File ++ "\n"}
+ end;
+ _ ->
+ deprecated_get_core_from_beam(File, Opts)
+ end.
+
+deprecated_get_core_from_beam(File, Opts) ->
+ case get_abstract_code_from_beam(File) of
+ error ->
+ {error, " Could not get abstract code for: " ++ File ++ "\n" ++
+ " Recompile with +debug_info or analyze starting from source code"};
{ok, AbstrCode} ->
- case get_core_from_abstract_code(AbstrCode, Opts) of
- error -> {error, " Could not get Core Erlang code from abstract code"};
- {ok, _Core} = C -> C
+ case get_compile_options_from_beam(File) of
+ error ->
+ {error, " Could not get compile options for: " ++ File ++ "\n" ++
+ " Recompile or analyze starting from source code"};
+ {ok, CompOpts} ->
+ case get_core_from_abstract_code(AbstrCode, Opts ++ CompOpts) of
+ error ->
+ {error, " Could not get core Erlang code for: " ++ File};
+ {ok, _} = Core ->
+ Core
+ end
end
end.
--spec get_abstract_code_from_beam(file:filename()) -> 'error' | {'ok', abstract_code()}.
-
get_abstract_code_from_beam(File) ->
case beam_lib:chunks(File, [abstract_code]) of
{ok, {_, List}} ->
case lists:keyfind(abstract_code, 1, List) of
- {abstract_code, {raw_abstract_v1, Abstr}} -> {ok, Abstr};
- _ -> error
+ {abstract_code, {raw_abstract_v1, Abstr}} -> {ok, Abstr};
+ _ -> error
end;
_ ->
%% No or unsuitable abstract code.
error
end.
--spec get_compile_options_from_beam(file:filename()) -> 'error' | {'ok', [compile:option()]}.
-
get_compile_options_from_beam(File) ->
case beam_lib:chunks(File, [compile_info]) of
{ok, {_, List}} ->
case lists:keyfind(compile_info, 1, List) of
- {compile_info, CompInfo} -> compile_info_to_options(CompInfo);
- _ -> error
+ {compile_info, CompInfo} -> compile_info_to_options(CompInfo);
+ _ -> error
end;
_ ->
%% No or unsuitable compile info.
@@ -165,15 +173,6 @@ compile_info_to_options(CompInfo) ->
_ -> error
end.
--type get_core_from_abs_ret() :: {'ok', cerl:c_module()} | 'error'.
-
--spec get_core_from_abstract_code(abstract_code()) -> get_core_from_abs_ret().
-
-get_core_from_abstract_code(AbstrCode) ->
- get_core_from_abstract_code(AbstrCode, []).
-
--spec get_core_from_abstract_code(abstract_code(), comp_options()) -> get_core_from_abs_ret().
-
get_core_from_abstract_code(AbstrCode, Opts) ->
%% We do not want the parse_transforms around since we already
%% performed them. In some cases we end up in trouble when
@@ -182,12 +181,31 @@ get_core_from_abstract_code(AbstrCode, Opts) ->
%% Remove parse_transforms (and other options) from compile options.
Opts2 = cleanup_compile_options(Opts),
try compile:noenv_forms(AbstrCode1, Opts2 ++ src_compiler_opts()) of
- {ok, _, Core} -> {ok, Core};
- _What -> error
+ {ok, _, Core} -> {ok, Core};
+ _What -> error
catch
error:_ -> error
end.
+cleanup_parse_transforms([{attribute, _, compile, {parse_transform, _}}|Left]) ->
+ cleanup_parse_transforms(Left);
+cleanup_parse_transforms([Other|Left]) ->
+ [Other|cleanup_parse_transforms(Left)];
+cleanup_parse_transforms([]) ->
+ [].
+
+cleanup_compile_options(Opts) ->
+ lists:filter(fun keep_compile_option/1, Opts).
+
+%% Using abstract, not asm or core.
+keep_compile_option(from_asm) -> false;
+keep_compile_option(from_core) -> false;
+%% The parse transform will already have been applied, may cause
+%% problems if it is re-applied.
+keep_compile_option({parse_transform, _}) -> false;
+keep_compile_option(warnings_as_errors) -> false;
+keep_compile_option(_) -> true.
+
%% ============================================================================
%%
%% Typed Records
@@ -195,57 +213,51 @@ get_core_from_abstract_code(AbstrCode, Opts) ->
%% ============================================================================
-type type_table() :: erl_types:type_table().
--type mod_records() :: dict:dict(module(), type_table()).
--spec get_record_and_type_info(abstract_code()) ->
- {'ok', type_table()} | {'error', string()}.
+-spec get_record_and_type_info(cerl:c_module()) ->
+ {'ok', type_table()} | {'error', string()}.
-get_record_and_type_info(AbstractCode) ->
- Module = get_module(AbstractCode),
- get_record_and_type_info(AbstractCode, Module, dict:new()).
+get_record_and_type_info(Core) ->
+ Module = cerl:concrete(cerl:module_name(Core)),
+ Tuples = core_to_attr_tuples(Core),
+ get_record_and_type_info(Tuples, Module, maps:new(), "nofile").
--spec get_record_and_type_info(abstract_code(), module(), type_table()) ->
- {'ok', type_table()} | {'error', string()}.
-
-get_record_and_type_info(AbstractCode, Module, RecDict) ->
- get_record_and_type_info(AbstractCode, Module, RecDict, "nofile").
-
-get_record_and_type_info([{attribute, A, record, {Name, Fields0}}|Left],
+get_record_and_type_info([{record, Line, [{Name, Fields0}]}|Left],
Module, RecDict, File) ->
{ok, Fields} = get_record_fields(Fields0, RecDict),
Arity = length(Fields),
- FN = {File, erl_anno:line(A)},
- NewRecDict = dict:store({record, Name}, {FN, [{Arity,Fields}]}, RecDict),
+ FN = {File, Line},
+ NewRecDict = maps:put({record, Name}, {FN, [{Arity,Fields}]}, RecDict),
get_record_and_type_info(Left, Module, NewRecDict, File);
-get_record_and_type_info([{attribute, A, type, {{record, Name}, Fields0, []}}
+get_record_and_type_info([{type, Line, [{{record, Name}, Fields0, []}]}
|Left], Module, RecDict, File) ->
%% This overrides the original record declaration.
{ok, Fields} = get_record_fields(Fields0, RecDict),
Arity = length(Fields),
- FN = {File, erl_anno:line(A)},
- NewRecDict = dict:store({record, Name}, {FN, [{Arity, Fields}]}, RecDict),
+ FN = {File, Line},
+ NewRecDict = maps:put({record, Name}, {FN, [{Arity, Fields}]}, RecDict),
get_record_and_type_info(Left, Module, NewRecDict, File);
-get_record_and_type_info([{attribute, A, Attr, {Name, TypeForm}}|Left],
+get_record_and_type_info([{Attr, Line, [{Name, TypeForm}]}|Left],
Module, RecDict, File)
when Attr =:= 'type'; Attr =:= 'opaque' ->
- FN = {File, erl_anno:line(A)},
+ FN = {File, Line},
try add_new_type(Attr, Name, TypeForm, [], Module, FN, RecDict) of
NewRecDict ->
get_record_and_type_info(Left, Module, NewRecDict, File)
catch
throw:{error, _} = Error -> Error
end;
-get_record_and_type_info([{attribute, A, Attr, {Name, TypeForm, Args}}|Left],
+get_record_and_type_info([{Attr, Line, [{Name, TypeForm, Args}]}|Left],
Module, RecDict, File)
when Attr =:= 'type'; Attr =:= 'opaque' ->
- FN = {File, erl_anno:line(A)},
+ FN = {File, Line},
try add_new_type(Attr, Name, TypeForm, Args, Module, FN, RecDict) of
NewRecDict ->
get_record_and_type_info(Left, Module, NewRecDict, File)
catch
throw:{error, _} = Error -> Error
end;
-get_record_and_type_info([{attribute, _, file, {IncludeFile, _}}|Left],
+get_record_and_type_info([{file, _, [{IncludeFile, _}]}|Left],
Module, RecDict, _File) ->
get_record_and_type_info(Left, Module, RecDict, IncludeFile);
get_record_and_type_info([_Other|Left], Module, RecDict, File) ->
@@ -258,17 +270,17 @@ add_new_type(TypeOrOpaque, Name, TypeForm, ArgForms, Module, FN,
Arity = length(ArgForms),
case erl_types:type_is_defined(TypeOrOpaque, Name, Arity, RecDict) of
true ->
- Msg = flat_format("Type ~s/~w already defined\n", [Name, Arity]),
+ Msg = flat_format("Type ~ts/~w already defined\n", [Name, Arity]),
throw({error, Msg});
false ->
try erl_types:t_var_names(ArgForms) of
ArgNames ->
- dict:store({TypeOrOpaque, Name, Arity},
- {{Module, FN, TypeForm, ArgNames},
- erl_types:t_any()}, RecDict)
+ maps:put({TypeOrOpaque, Name, Arity},
+ {{Module, FN, TypeForm, ArgNames},
+ erl_types:t_any()}, RecDict)
catch
_:_ ->
- throw({error, flat_format("Type declaration for ~w does not "
+ throw({error, flat_format("Type declaration for ~tw does not "
"have variables as parameters", [Name])})
end
end.
@@ -300,15 +312,14 @@ get_record_fields([], _RecDict, Acc) ->
%% The field types are cached. Used during analysis when handling records.
process_record_remote_types(CServer) ->
- TempRecords = dialyzer_codeserver:get_temp_records(CServer),
ExpTypes = dialyzer_codeserver:get_exported_types(CServer),
- Cache = erl_types:cache__new(),
- {TempRecords1, Cache1} =
- process_opaque_types0(TempRecords, ExpTypes, Cache),
- %% A cache (not the field type cache) is used for speeding things up a bit.
+ Mods = dialyzer_codeserver:all_temp_modules(CServer),
+ process_opaque_types0(Mods, CServer, ExpTypes),
VarTable = erl_types:var_table__new(),
+ RecordTable = dialyzer_codeserver:get_temp_records_table(CServer),
ModuleFun =
- fun({Module, Record}, C0) ->
+ fun(Module) ->
+ RecordMap = dialyzer_codeserver:lookup_temp_mod_records(Module, CServer),
RecordFun =
fun({Key, Value}, C2) ->
case Key of
@@ -321,7 +332,7 @@ process_record_remote_types(CServer) ->
{FieldT, C6} =
erl_types:t_from_form
(Field, ExpTypes, Site,
- TempRecords1, VarTable,
+ RecordTable, VarTable,
C5),
{{FieldName, Field, FieldT}, C6}
end, C4, Fields),
@@ -331,32 +342,46 @@ process_record_remote_types(CServer) ->
{FieldsList, C3} =
lists:mapfoldl(FieldFun, C2, orddict:to_list(Fields)),
{{Key, {FileLine, orddict:from_list(FieldsList)}}, C3};
- _Other -> {{Key, Value}, C2}
+ {type, Name, NArgs} ->
+ %% Make sure warnings about unknown types are output
+ %% also for types unused by specs.
+ Site = {type, {Module, Name, NArgs}},
+ L = erl_anno:new(0),
+ Args = lists:duplicate(NArgs, {var, L, '_'}),
+ UserType = {user_type, L, Name, Args},
+ {_NewType, C3} =
+ erl_types:t_from_form(UserType, ExpTypes, Site,
+ RecordTable, VarTable, C2),
+ {{Key, Value}, C3};
+ {opaque, _Name, _NArgs} ->
+ {{Key, Value}, C2}
end
end,
- {RecordList, C1} =
- lists:mapfoldl(RecordFun, C0, dict:to_list(Record)),
- {{Module, dict:from_list(RecordList)}, C1}
+ Cache = erl_types:cache__new(),
+ {RecordList, _NewCache} =
+ lists:mapfoldl(RecordFun, Cache, maps:to_list(RecordMap)),
+ dialyzer_codeserver:store_temp_records(Module,
+ maps:from_list(RecordList),
+ CServer)
end,
- {NewRecordsList, C1} =
- lists:mapfoldl(ModuleFun, Cache1, dict:to_list(TempRecords1)),
- NewRecords = dict:from_list(NewRecordsList),
- _C8 = check_record_fields(NewRecords, ExpTypes, C1),
- dialyzer_codeserver:finalize_records(NewRecords, CServer).
+ lists:foreach(ModuleFun, Mods),
+ check_record_fields(Mods, CServer, ExpTypes),
+ dialyzer_codeserver:finalize_records(CServer).
%% erl_types:t_from_form() substitutes the declaration of opaque types
%% for the expanded type in some cases. To make sure the initial type,
%% any(), is not used, the expansion is done twice.
%% XXX: Recursive opaque types are not handled well.
-process_opaque_types0(TempRecords0, TempExpTypes, Cache) ->
- {TempRecords1, NewCache} =
- process_opaque_types(TempRecords0, TempExpTypes, Cache),
- process_opaque_types(TempRecords1, TempExpTypes, NewCache).
+process_opaque_types0(AllModules, CServer, TempExpTypes) ->
+ process_opaque_types(AllModules, CServer, TempExpTypes),
+ process_opaque_types(AllModules, CServer, TempExpTypes).
-process_opaque_types(TempRecords, TempExpTypes, Cache) ->
+process_opaque_types(AllModules, CServer, TempExpTypes) ->
VarTable = erl_types:var_table__new(),
+ RecordTable = dialyzer_codeserver:get_temp_records_table(CServer),
ModuleFun =
- fun({Module, Record}, C0) ->
+ fun(Module) ->
+ RecordMap = dialyzer_codeserver:lookup_temp_mod_records(Module, CServer),
RecordFun =
fun({Key, Value}, C2) ->
case Key of
@@ -365,31 +390,35 @@ process_opaque_types(TempRecords, TempExpTypes, Cache) ->
Site = {type, {Module, Name, NArgs}},
{Type, C3} =
erl_types:t_from_form(Form, TempExpTypes, Site,
- TempRecords, VarTable, C2),
+ RecordTable, VarTable, C2),
{{Key, {F, Type}}, C3};
- _Other -> {{Key, Value}, C2}
+ {type, _Name, _NArgs} ->
+ {{Key, Value}, C2};
+ {record, _RecName} ->
+ {{Key, Value}, C2}
end
end,
- {RecordList, C1} =
- lists:mapfoldl(RecordFun, C0, dict:to_list(Record)),
- {{Module, dict:from_list(RecordList)}, C1}
- %% dict:map(RecordFun, Record)
+ C0 = erl_types:cache__new(),
+ {RecordList, _NewCache} =
+ lists:mapfoldl(RecordFun, C0, maps:to_list(RecordMap)),
+ dialyzer_codeserver:store_temp_records(Module,
+ maps:from_list(RecordList),
+ CServer)
end,
- {TempRecordList, NewCache} =
- lists:mapfoldl(ModuleFun, Cache, dict:to_list(TempRecords)),
- {dict:from_list(TempRecordList), NewCache}.
- %% dict:map(ModuleFun, TempRecords).
+ lists:foreach(ModuleFun, AllModules).
-check_record_fields(Records, TempExpTypes, Cache) ->
+check_record_fields(AllModules, CServer, TempExpTypes) ->
VarTable = erl_types:var_table__new(),
+ RecordTable = dialyzer_codeserver:get_temp_records_table(CServer),
CheckFun =
- fun({Module, Element}, C0) ->
+ fun(Module) ->
CheckForm = fun(Form, Site, C1) ->
erl_types:t_check_record_fields(Form, TempExpTypes,
- Site, Records,
+ Site, RecordTable,
VarTable, C1)
end,
- ElemFun =
+ RecordMap = dialyzer_codeserver:lookup_temp_mod_records(Module, CServer),
+ RecordFun =
fun({Key, Value}, C2) ->
case Key of
{record, Name} ->
@@ -410,9 +439,10 @@ check_record_fields(Records, TempExpTypes, Cache) ->
msg_with_position(Fun, FileLine)
end
end,
- lists:foldl(ElemFun, C0, dict:to_list(Element))
+ C0 = erl_types:cache__new(),
+ _ = lists:foldl(RecordFun, C0, maps:to_list(RecordMap))
end,
- lists:foldl(CheckFun, Cache, dict:to_list(Records)).
+ lists:foreach(CheckFun, AllModules).
msg_with_position(Fun, FileLine) ->
try Fun()
@@ -420,14 +450,41 @@ msg_with_position(Fun, FileLine) ->
throw:{error, Msg} ->
{File, Line} = FileLine,
BaseName = filename:basename(File),
- NewMsg = io_lib:format("~s:~p: ~s", [BaseName, Line, Msg]),
+ NewMsg = io_lib:format("~ts:~p: ~ts", [BaseName, Line, Msg]),
throw({error, NewMsg})
end.
--spec merge_records(mod_records(), mod_records()) -> mod_records().
+-spec merge_types(codeserver(), dialyzer_plt:plt()) -> codeserver().
-merge_records(NewRecords, OldRecords) ->
- dict:merge(fun(_Key, NewVal, _OldVal) -> NewVal end, NewRecords, OldRecords).
+merge_types(CServer, Plt) ->
+ AllNewModules = dialyzer_codeserver:all_temp_modules(CServer),
+ AllNewModulesSet = sets:from_list(AllNewModules),
+ AllOldModulesSet = dialyzer_plt:all_modules(Plt),
+ AllModulesSet = sets:union(AllNewModulesSet, AllOldModulesSet),
+ ModuleFun =
+ fun(Module) ->
+ KeepOldFun =
+ fun() ->
+ case dialyzer_plt:get_module_types(Plt, Module) of
+ none -> no;
+ {value, OldRecords} ->
+ case sets:is_element(Module, AllNewModulesSet) of
+ true -> no;
+ false -> {yes, OldRecords}
+ end
+ end
+ end,
+ Records =
+ case KeepOldFun() of
+ no ->
+ dialyzer_codeserver:lookup_temp_mod_records(Module, CServer);
+ {yes, OldRecords} ->
+ OldRecords
+ end,
+ dialyzer_codeserver:store_temp_records(Module, Records, CServer)
+ end,
+ lists:foreach(ModuleFun, sets:to_list(AllModulesSet)),
+ CServer.
%% ============================================================================
%%
@@ -435,26 +492,21 @@ merge_records(NewRecords, OldRecords) ->
%%
%% ============================================================================
--type spec_dict() :: dict:dict().
--type callback_dict() :: dict:dict().
+-type spec_map() :: dialyzer_codeserver:contracts().
+-type callback_map() :: dialyzer_codeserver:contracts().
--spec get_spec_info(module(), abstract_code(), type_table()) ->
- {'ok', spec_dict(), callback_dict()} | {'error', string()}.
+-spec get_spec_info(module(), cerl:c_module(), type_table()) ->
+ {'ok', spec_map(), callback_map()} | {'error', string()}.
-get_spec_info(ModName, AbstractCode, RecordsDict) ->
- OptionalCallbacks0 = get_optional_callbacks(AbstractCode, ModName),
+get_spec_info(ModName, Core, RecordsMap) ->
+ Tuples = core_to_attr_tuples(Core),
+ OptionalCallbacks0 = get_optional_callbacks(Tuples, ModName),
OptionalCallbacks = gb_sets:from_list(OptionalCallbacks0),
- get_spec_info(AbstractCode, dict:new(), dict:new(),
- RecordsDict, ModName, OptionalCallbacks, "nofile").
+ get_spec_info(Tuples, maps:new(), maps:new(),
+ RecordsMap, ModName, OptionalCallbacks, "nofile").
-get_optional_callbacks(Abs, ModName) ->
- [{ModName, F, A} || {F, A} <- get_optional_callbacks(Abs)].
-
-get_optional_callbacks(Abs) ->
- L = [O ||
- {attribute, _, optional_callbacks, O} <- Abs,
- is_fa_list(O)],
- lists:append(L).
+get_optional_callbacks(Tuples, ModName) ->
+ [{ModName, F, A} || {optional_callbacks, _, O} <- Tuples, is_fa_list(O), {F, A} <- O].
%% TypeSpec is a list of conditional contracts for a function.
%% Each contract is of the form {[Argument], Range, [Constraint]} where
@@ -462,68 +514,82 @@ get_optional_callbacks(Abs) ->
%% - Constraint is of the form {subtype, T1, T2} where T1 and T2
%% are erl_types:erl_type()
-get_spec_info([{attribute, Anno, Contract, {Id, TypeSpec}}|Left],
- SpecDict, CallbackDict, RecordsDict, ModName, OptCb, File)
+get_spec_info([{Contract, Ln, [{Id, TypeSpec}]}|Left],
+ SpecMap, CallbackMap, RecordsMap, ModName, OptCb, File)
when ((Contract =:= 'spec') or (Contract =:= 'callback')),
is_list(TypeSpec) ->
- Ln = erl_anno:line(Anno),
MFA = case Id of
{_, _, _} = T -> T;
{F, A} -> {ModName, F, A}
end,
Xtra = [optional_callback || gb_sets:is_member(MFA, OptCb)],
- ActiveDict =
+ ActiveMap =
case Contract of
- spec -> SpecDict;
- callback -> CallbackDict
+ spec -> SpecMap;
+ callback -> CallbackMap
end,
- try dict:find(MFA, ActiveDict) of
+ try maps:find(MFA, ActiveMap) of
error ->
SpecData = {TypeSpec, Xtra},
- NewActiveDict =
+ NewActiveMap =
dialyzer_contracts:store_tmp_contract(MFA, {File, Ln}, SpecData,
- ActiveDict, RecordsDict),
- {NewSpecDict, NewCallbackDict} =
+ ActiveMap, RecordsMap),
+ {NewSpecMap, NewCallbackMap} =
case Contract of
- spec -> {NewActiveDict, CallbackDict};
- callback -> {SpecDict, NewActiveDict}
+ spec -> {NewActiveMap, CallbackMap};
+ callback -> {SpecMap, NewActiveMap}
end,
- get_spec_info(Left, NewSpecDict, NewCallbackDict,
- RecordsDict, ModName, OptCb, File);
+ get_spec_info(Left, NewSpecMap, NewCallbackMap,
+ RecordsMap, ModName, OptCb, File);
{ok, {{OtherFile, L}, _D}} ->
{Mod, Fun, Arity} = MFA,
- Msg = flat_format(" Contract/callback for function ~w:~w/~w "
- "already defined in ~s:~w\n",
+ Msg = flat_format(" Contract/callback for function ~w:~tw/~w "
+ "already defined in ~ts:~w\n",
[Mod, Fun, Arity, OtherFile, L]),
throw({error, Msg})
catch
throw:{error, Error} ->
- {error, flat_format(" Error while parsing contract in line ~w: ~s\n",
+ {error, flat_format(" Error while parsing contract in line ~w: ~ts\n",
[Ln, Error])}
end;
-get_spec_info([{attribute, _, file, {IncludeFile, _}}|Left],
- SpecDict, CallbackDict, RecordsDict, ModName, OptCb, _File) ->
- get_spec_info(Left, SpecDict, CallbackDict,
- RecordsDict, ModName, OptCb, IncludeFile);
-get_spec_info([_Other|Left], SpecDict, CallbackDict,
- RecordsDict, ModName, OptCb, File) ->
- get_spec_info(Left, SpecDict, CallbackDict,
- RecordsDict, ModName, OptCb, File);
-get_spec_info([], SpecDict, CallbackDict,
- _RecordsDict, _ModName, _OptCb, _File) ->
- {ok, SpecDict, CallbackDict}.
-
--spec get_fun_meta_info(module(), abstract_code(), [dial_warn_tag()]) ->
- dialyzer_codeserver:fun_meta_info().
-
-get_fun_meta_info(M, Abs, LegalWarnings) ->
- NoWarn = get_nowarn_unused_function(M, Abs),
- FuncSupp = get_func_suppressions(M, Abs),
- Warnings0 = get_options(Abs, LegalWarnings),
- Warnings = ordsets:to_list(Warnings0),
- ModuleWarnings = [{M, W} || W <- Warnings],
- RawProps = lists:append([NoWarn, FuncSupp, ModuleWarnings]),
- process_options(dialyzer_utils:family(RawProps), Warnings0).
+get_spec_info([{file, _, [{IncludeFile, _}]}|Left],
+ SpecMap, CallbackMap, RecordsMap, ModName, OptCb, _File) ->
+ get_spec_info(Left, SpecMap, CallbackMap,
+ RecordsMap, ModName, OptCb, IncludeFile);
+get_spec_info([_Other|Left], SpecMap, CallbackMap,
+ RecordsMap, ModName, OptCb, File) ->
+ get_spec_info(Left, SpecMap, CallbackMap,
+ RecordsMap, ModName, OptCb, File);
+get_spec_info([], SpecMap, CallbackMap,
+ _RecordsMap, _ModName, _OptCb, _File) ->
+ {ok, SpecMap, CallbackMap}.
+
+core_to_attr_tuples(Core) ->
+ [{cerl:concrete(Key), get_core_line(cerl:get_ann(Key)), cerl:concrete(Value)} ||
+ {Key, Value} <- cerl:module_attrs(Core)].
+
+get_core_line([L | _As]) when is_integer(L) -> L;
+get_core_line([_ | As]) -> get_core_line(As);
+get_core_line([]) -> undefined.
+
+-spec get_fun_meta_info(module(), cerl:c_module(), [dial_warn_tag()]) ->
+ dialyzer_codeserver:fun_meta_info() | {'error', string()}.
+
+get_fun_meta_info(M, Core, LegalWarnings) ->
+ Functions = lists:map(fun cerl:var_name/1, cerl:module_vars(Core)),
+ try
+ {get_nowarn_unused_function(M, Core, Functions),
+ get_func_suppressions(M, Core, Functions)}
+ of
+ {NoWarn, FuncSupp} ->
+ Warnings0 = get_options(Core, LegalWarnings),
+ Warnings = ordsets:to_list(Warnings0),
+ ModuleWarnings = [{M, W} || W <- Warnings],
+ RawProps = lists:append([NoWarn, FuncSupp, ModuleWarnings]),
+ process_options(dialyzer_utils:family(RawProps), Warnings0)
+ catch throw:{error, _} = Error ->
+ Error
+ end.
process_options([{M, _}=Mod|Left], Warnings) when is_atom(M) ->
[Mod|process_options(Left, Warnings)];
@@ -542,74 +608,75 @@ process_options([{{_M, _F, _A}=MFA, Opts}|Left], Warnings) ->
end;
process_options([], _Warnings) -> [].
--spec get_nowarn_unused_function(module(), abstract_code()) ->
+-spec get_nowarn_unused_function(module(), cerl:c_module(), [fa()]) ->
[{mfa(), 'no_unused'}].
-get_nowarn_unused_function(M, Abs) ->
- Opts = get_options_with_tag(compile, Abs),
+get_nowarn_unused_function(M, Core, Functions) ->
+ Opts = get_options_with_tag(compile, Core),
Warn = erl_lint:bool_option(warn_unused_function, nowarn_unused_function,
true, Opts),
- Functions = [{F, A} || {function, _, F, A, _} <- Abs],
- AttrFile = collect_attribute(Abs, compile),
+ AttrFile = collect_attribute(Core, compile),
TagsFaList = check_fa_list(AttrFile, nowarn_unused_function, Functions),
FAs = case Warn of
false -> Functions;
true ->
- [FA || {{nowarn_unused_function,_L,_File}, FA} <- TagsFaList]
+ [FA || {{[nowarn_unused_function],_L,_File}, FA} <- TagsFaList]
end,
[{{M, F, A}, no_unused} || {F, A} <- FAs].
--spec get_func_suppressions(module(), abstract_code()) ->
+-spec get_func_suppressions(module(), cerl:c_module(), [fa()]) ->
[{mfa(), 'nowarn_function' | dial_warn_tag()}].
-get_func_suppressions(M, Abs) ->
- Functions = [{F, A} || {function, _, F, A, _} <- Abs],
- AttrFile = collect_attribute(Abs, dialyzer),
+get_func_suppressions(M, Core, Functions) ->
+ AttrFile = collect_attribute(Core, dialyzer),
TagsFAs = check_fa_list(AttrFile, '*', Functions),
%% Check the options:
- Fun = fun({{nowarn_function, _L, _File}, _FA}) -> ok;
+ Fun = fun({{[nowarn_function], _L, _File}, _FA}) -> ok;
({OptLFile, _FA}) ->
_ = get_options1([OptLFile], ordsets:new())
end,
lists:foreach(Fun, TagsFAs),
- [{{M, F, A}, W} || {{W, _L, _File}, {F, A}} <- TagsFAs].
+ [{{M, F, A}, W} || {{Warnings, _L, _File}, {F, A}} <- TagsFAs, W <- Warnings].
--spec get_options(abstract_code(), [dial_warn_tag()]) ->
+-spec get_options(cerl:c_module(), [dial_warn_tag()]) ->
ordsets:ordset(dial_warn_tag()).
-get_options(Abs, LegalWarnings) ->
- AttrFile = collect_attribute(Abs, dialyzer),
+get_options(Core, LegalWarnings) ->
+ AttrFile = collect_attribute(Core, dialyzer),
get_options1(AttrFile, LegalWarnings).
get_options1([{Args, L, File}|Left], Warnings) ->
- Opts = [O ||
- O <- lists:flatten([Args]),
- is_atom(O)],
+ Opts = [O || O <- Args, is_atom(O)],
try dialyzer_options:build_warnings(Opts, Warnings) of
NewWarnings ->
get_options1(Left, NewWarnings)
catch
throw:{dialyzer_options_error, Msg} ->
- Msg1 = flat_format(" ~s:~w: ~s", [File, L, Msg]),
+ Msg1 = flat_format(" ~ts:~w: ~ts", [File, L, Msg]),
throw({error, Msg1})
end;
get_options1([], Warnings) ->
Warnings.
-type collected_attribute() ::
- {Args :: term(), erl_anno:line(), file:filename()}.
-
-collect_attribute(Abs, Tag) ->
- collect_attribute(Abs, Tag, "nofile").
-
-collect_attribute([{attribute, L, Tag, Args}|Left], Tag, File) ->
- CollAttr = {Args, L, File},
- [CollAttr | collect_attribute(Left, Tag, File)];
-collect_attribute([{attribute, _, file, {IncludeFile, _}}|Left], Tag, _) ->
- collect_attribute(Left, Tag, IncludeFile);
-collect_attribute([_Other|Left], Tag, File) ->
- collect_attribute(Left, Tag, File);
-collect_attribute([], _Tag, _File) -> [].
+ {Args :: [term()], erl_anno:line(), file:filename()}.
+
+collect_attribute(Core, Tag) ->
+ collect_attribute(cerl:module_attrs(Core), Tag, "nofile").
+
+collect_attribute([{Key, Value}|T], Tag, File) ->
+ case cerl:concrete(Key) of
+ Tag ->
+ [{cerl:concrete(Value), get_core_line(cerl:get_ann(Key)), File} |
+ collect_attribute(T, Tag, File)];
+ file ->
+ [{IncludeFile, _}] = cerl:concrete(Value),
+ collect_attribute(T, Tag, IncludeFile);
+ _ ->
+ collect_attribute(T, Tag, File)
+ end;
+collect_attribute([], _Tag, _File) ->
+ [].
-spec is_suppressed_fun(mfa(), codeserver()) -> boolean().
@@ -660,40 +727,11 @@ src_compiler_opts() ->
no_inline, strict_record_tests, strict_record_updates,
dialyzer].
--spec get_module(abstract_code()) -> module().
-
-get_module([{attribute, _, module, {M, _As}} | _]) -> M;
-get_module([{attribute, _, module, M} | _]) -> M;
-get_module([_ | Rest]) -> get_module(Rest).
-
--spec cleanup_parse_transforms(abstract_code()) -> abstract_code().
-
-cleanup_parse_transforms([{attribute, _, compile, {parse_transform, _}}|Left]) ->
- cleanup_parse_transforms(Left);
-cleanup_parse_transforms([Other|Left]) ->
- [Other|cleanup_parse_transforms(Left)];
-cleanup_parse_transforms([]) ->
- [].
-
--spec cleanup_compile_options([compile:option()]) -> [compile:option()].
-
-cleanup_compile_options(Opts) ->
- lists:filter(fun keep_compile_option/1, Opts).
-
-%% Using abstract, not asm or core.
-keep_compile_option(from_asm) -> false;
-keep_compile_option(from_core) -> false;
-%% The parse transform will already have been applied, may cause
-%% problems if it is re-applied.
-keep_compile_option({parse_transform, _}) -> false;
-keep_compile_option(warnings_as_errors) -> false;
-keep_compile_option(_) -> true.
-
-spec format_errors([{module(), string()}]) -> [string()].
format_errors([{Mod, Errors}|Left]) ->
FormatedError =
- [io_lib:format("~s:~w: ~s\n", [Mod, Line, M:format_error(Desc)])
+ [io_lib:format("~ts:~w: ~ts\n", [Mod, Line, M:format_error(Desc)])
|| {Line, M, Desc} <- Errors],
[lists:flatten(FormatedError) | format_errors(Left)];
format_errors([]) ->
@@ -702,7 +740,7 @@ format_errors([]) ->
-spec format_sig(erl_types:erl_type()) -> string().
format_sig(Type) ->
- format_sig(Type, dict:new()).
+ format_sig(Type, maps:new()).
-spec format_sig(erl_types:erl_type(), type_table()) -> string().
@@ -714,10 +752,12 @@ format_sig(Type, RecDict) ->
flat_format(Fmt, Lst) ->
lists:flatten(io_lib:format(Fmt, Lst)).
--spec get_options_with_tag(atom(), abstract_code()) -> [term()].
+-spec get_options_with_tag(atom(), cerl:c_module()) -> [term()].
-get_options_with_tag(Tag, Abs) ->
- lists:flatten([O || {attribute, _, Tag0, O} <- Abs, Tag =:= Tag0]).
+get_options_with_tag(Tag, Core) ->
+ [O || {Key, Value} <- cerl:module_attrs(Core),
+ cerl:concrete(Key) =:= Tag,
+ O <- cerl:concrete(Value)].
%% Check F/A, and collect (unchecked) warning tags with line and file.
-spec check_fa_list([collected_attribute()], atom(), [fa()]) ->
@@ -728,22 +768,22 @@ check_fa_list(AttrFile, Tag, Functions) ->
check_fa_list1(AttrFile, Tag, FuncTab).
check_fa_list1([{Args, L, File}|Left], Tag, Funcs) ->
- TermsL = [{{Tag0, L, File}, Term} ||
- {Tags, Terms0} <- lists:flatten([Args]),
+ TermsL = [{{[Tag0], L, File}, Term} ||
+ {Tags, Terms0} <- Args,
Tag0 <- lists:flatten([Tags]),
Tag =:= '*' orelse Tag =:= Tag0,
Term <- lists:flatten([Terms0])],
case lists:dropwhile(fun({_, T}) -> is_fa(T) end, TermsL) of
[] -> ok;
[{_, Bad}|_] ->
- Msg1 = flat_format(" Bad function ~w in line ~s:~w",
+ Msg1 = flat_format(" Bad function ~tw in line ~ts:~w",
[Bad, File, L]),
throw({error, Msg1})
end,
case lists:dropwhile(fun({_, FA}) -> is_known(FA, Funcs) end, TermsL) of
[] -> ok;
[{_, {F, A}}|_] ->
- Msg2 = flat_format(" Unknown function ~w/~w in line ~s:~w",
+ Msg2 = flat_format(" Unknown function ~tw/~w in line ~ts:~w",
[F, A, File, L]),
throw({error, Msg2})
end,
@@ -951,12 +991,39 @@ label(Tree) ->
%%------------------------------------------------------------------------------
+-spec ets_tab2list(ets:tid()) -> list().
+
+%% Deletes the contents of the table. Use:
+%% ets_tab2list(T), ets:delete(T)
+%% instead of:
+%% ets:tab2list(T), ets:delete(T)
+%% to save some memory at the expense of somewhat longer execution time.
+ets_tab2list(T) ->
+ F = fun(Vs, A) -> Vs ++ A end,
+ ets_take(ets:first(T), T, F, []).
+
+-spec ets_move(From :: ets:tid(), To :: ets:tid()) -> 'ok'.
+
+ets_move(T1, T2) ->
+ F = fun(Es, A) -> true = ets:insert(T2, Es), A end,
+ [] = ets_take(ets:first(T1), T1, F, []),
+ ok.
+
+ets_take('$end_of_table', T, F, A) ->
+ case ets:first(T) of % no safe_fixtable()...
+ '$end_of_table' -> A;
+ Key -> ets_take(Key, T, F, A)
+ end;
+ets_take(Key, T, F, A) ->
+ Vs = ets:lookup(T, Key),
+ Key1 = ets:next(T, Key),
+ true = ets:delete(T, Key),
+ ets_take(Key1, T, F, F(Vs, A)).
+
-spec parallelism() -> integer().
parallelism() ->
- CPUs = erlang:system_info(logical_processors_available),
- Schedulers = erlang:system_info(schedulers),
- min(CPUs, Schedulers).
+ erlang:system_info(schedulers_online).
-spec family([{K,V}]) -> [{K,[V]}].
diff --git a/lib/dialyzer/src/dialyzer_worker.erl b/lib/dialyzer/src/dialyzer_worker.erl
index b9ab27c11d..af0f2e9e08 100644
--- a/lib/dialyzer/src/dialyzer_worker.erl
+++ b/lib/dialyzer/src/dialyzer_worker.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(dialyzer_worker).
@@ -63,10 +56,14 @@ launch(Mode, Job, InitData, Coordinator) ->
%%--------------------------------------------------------------------
-init(#state{job = SCC, mode = Mode, init_data = InitData} = State) when
+init(#state{job = SCC, mode = Mode, init_data = InitData,
+ coordinator = Coordinator} = State) when
Mode =:= 'typesig'; Mode =:= 'dataflow' ->
- DependsOn = dialyzer_succ_typings:find_depends_on(SCC, InitData),
- ?debug("Deps ~p: ~p\n",[SCC, DependsOn]),
+ DependsOnSCCs = dialyzer_succ_typings:find_depends_on(SCC, InitData),
+ ?debug("~w: Deps ~p: ~p\n", [self(), SCC, DependsOnSCCs]),
+ Pids = dialyzer_coordinator:sccs_to_pids(DependsOnSCCs, Coordinator),
+ ?debug("~w: PidsDeps ~p\n", [self(), Pids]),
+ DependsOn = [{Pid, erlang:monitor(process, Pid)} || Pid <- Pids],
loop(updating, State#state{depends_on = DependsOn});
init(#state{mode = Mode} = State) when
Mode =:= 'compile'; Mode =:= 'warnings' ->
@@ -74,7 +71,7 @@ init(#state{mode = Mode} = State) when
loop(updating, #state{mode = Mode} = State) when
Mode =:= 'typesig'; Mode =:= 'dataflow' ->
- ?debug("Update: ~p\n",[State#state.job]),
+ ?debug("~w: Update: ~p\n", [self(), State#state.job]),
NextStatus =
case waits_more_success_typings(State) of
true -> waiting;
@@ -83,11 +80,11 @@ loop(updating, #state{mode = Mode} = State) when
loop(NextStatus, State);
loop(waiting, #state{mode = Mode} = State) when
Mode =:= 'typesig'; Mode =:= 'dataflow' ->
- ?debug("Wait: ~p\n",[State#state.job]),
+ ?debug("~w: Wait: ~p\n", [self(), State#state.job]),
NewState = wait_for_success_typings(State),
loop(updating, NewState);
loop(running, #state{mode = 'compile'} = State) ->
- dialyzer_coordinator:request_activation(State#state.coordinator),
+ request_activation(State),
?debug("Compile: ~s\n",[State#state.job]),
Result =
case start_compilation(State) of
@@ -99,51 +96,28 @@ loop(running, #state{mode = 'compile'} = State) ->
end,
report_to_coordinator(Result, State);
loop(running, #state{mode = 'warnings'} = State) ->
- dialyzer_coordinator:request_activation(State#state.coordinator),
+ request_activation(State),
?debug("Warning: ~s\n",[State#state.job]),
Result = collect_warnings(State),
report_to_coordinator(Result, State);
loop(running, #state{mode = Mode} = State) when
Mode =:= 'typesig'; Mode =:= 'dataflow' ->
request_activation(State),
- ?debug("Run: ~p\n",[State#state.job]),
+ ?debug("~w: Run: ~p\n", [self(), State#state.job]),
NotFixpoint = do_work(State),
- ok = broadcast_done(State),
report_to_coordinator(NotFixpoint, State).
waits_more_success_typings(#state{depends_on = Depends}) ->
Depends =/= [].
-broadcast_done(#state{job = SCC, init_data = InitData,
- coordinator = Coordinator}) ->
- RequiredBy = dialyzer_succ_typings:find_required_by(SCC, InitData),
- {Callers, Unknown} =
- dialyzer_coordinator:sccs_to_pids(RequiredBy, Coordinator),
- send_done(Callers, SCC),
- continue_broadcast_done(Unknown, SCC, Coordinator).
-
-send_done(Callers, SCC) ->
- ?debug("Sending ~p: ~p\n",[SCC, Callers]),
- SendSTFun = fun(PID) -> PID ! {done, SCC} end,
- lists:foreach(SendSTFun, Callers).
-
-continue_broadcast_done([], _SCC, _Coordinator) -> ok;
-continue_broadcast_done(Rest, SCC, Coordinator) ->
- %% This time limit should be greater than the time required
- %% by the coordinator to spawn all processes.
- timer:sleep(500),
- {Callers, Unknown} = dialyzer_coordinator:sccs_to_pids(Rest, Coordinator),
- send_done(Callers, SCC),
- continue_broadcast_done(Unknown, SCC, Coordinator).
-
wait_for_success_typings(#state{depends_on = DependsOn} = State) ->
receive
- {done, SCC} ->
- ?debug("GOT ~p: ~p\n",[State#state.job, SCC]),
- State#state{depends_on = DependsOn -- [SCC]}
+ {'DOWN', Ref, process, Pid, _Info} ->
+ ?debug("~w: ~p got DOWN: ~p\n", [self(), State#state.job, Pid]),
+ State#state{depends_on = DependsOn -- [{Pid, Ref}]}
after
5000 ->
- ?debug("Still Waiting ~p: ~p\n",[State#state.job, DependsOn]),
+ ?debug("~w: Still Waiting ~p:\n ~p\n", [self(), State#state.job, DependsOn]),
State
end.
@@ -157,7 +131,7 @@ do_work(#state{mode = Mode, job = Job, init_data = InitData}) ->
end.
report_to_coordinator(Result, #state{job = Job, coordinator = Coordinator}) ->
- ?debug("Done: ~p\n",[Job]),
+ ?debug("~w: Done: ~p\n",[self(), Job]),
dialyzer_coordinator:job_done(Job, Result, Coordinator).
start_compilation(#state{job = Job, init_data = InitData}) ->
diff --git a/lib/typer/src/typer.erl b/lib/dialyzer/src/typer.erl
index 5c82750a21..bf5484e5f6 100644
--- a/lib/typer/src/typer.erl
+++ b/lib/dialyzer/src/typer.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%-----------------------------------------------------------------------
%% File : typer.erl
@@ -81,6 +74,7 @@
-spec start() -> no_return().
start() ->
+_ = io:setopts(standard_error, [{encoding,unicode}]),
{Args, Analysis} = process_cl_args(),
%% io:format("Args: ~p\n", [Args]),
%% io:format("Analysis: ~p\n", [Analysis]),
@@ -88,7 +82,7 @@ start() ->
TrustedFiles = filter_fd(Args#args.trusted, [], fun is_erl_file/1),
Analysis2 = extract(Analysis, TrustedFiles),
All_Files = get_all_files(Args),
- %% io:format("All_Files: ~p\n", [All_Files]),
+ %% io:format("All_Files: ~tp\n", [All_Files]),
Analysis3 = Analysis2#analysis{files = All_Files},
Analysis4 = collect_info(Analysis3),
%% io:format("Final: ~p\n", [Analysis4#analysis.fms]),
@@ -116,12 +110,12 @@ extract(#analysis{macros = Macros,
AllIncludes = [filename:dirname(filename:dirname(File)) | Includes],
Is = [{i, Dir} || Dir <- AllIncludes],
CompOpts = dialyzer_utils:src_compiler_opts() ++ Is ++ Ds,
- case dialyzer_utils:get_abstract_code_from_src(File, CompOpts) of
- {ok, AbstractCode} ->
- case dialyzer_utils:get_record_and_type_info(AbstractCode) of
+ case dialyzer_utils:get_core_from_src(File, CompOpts) of
+ {ok, Core} ->
+ case dialyzer_utils:get_record_and_type_info(Core) of
{ok, RecDict} ->
Mod = list_to_atom(filename:basename(File, ".erl")),
- case dialyzer_utils:get_spec_info(Mod, AbstractCode, RecDict) of
+ case dialyzer_utils:get_spec_info(Mod, Core, RecDict) of
{ok, SpecDict, CbDict} ->
CS1 = dialyzer_codeserver:store_temp_records(Mod, RecDict, CS),
dialyzer_codeserver:store_temp_contracts(Mod, SpecDict, CbDict, CS1);
@@ -136,12 +130,11 @@ extract(#analysis{macros = Macros,
%% Process remote types
NewCodeServer =
try
- NewRecords = dialyzer_codeserver:get_temp_records(CodeServer1),
+ CodeServer2 =
+ dialyzer_utils:merge_types(CodeServer1,
+ TrustPLT), % XXX change to the PLT?
NewExpTypes = dialyzer_codeserver:get_temp_exported_types(CodeServer1),
case sets:size(NewExpTypes) of 0 -> ok end,
- OldRecords = dialyzer_plt:get_types(TrustPLT), % XXX change to the PLT?
- MergedRecords = dialyzer_utils:merge_records(NewRecords, OldRecords),
- CodeServer2 = dialyzer_codeserver:set_temp_records(MergedRecords, CodeServer1),
CodeServer3 = dialyzer_codeserver:finalize_exported_types(NewExpTypes, CodeServer2),
CodeServer4 = dialyzer_utils:process_record_remote_types(CodeServer3),
dialyzer_contracts:process_contract_remote_types(CodeServer4)
@@ -150,16 +143,9 @@ extract(#analysis{macros = Macros,
compile_error(ErrorMsg)
end,
%% Create TrustPLT
- Contracts = dialyzer_codeserver:get_contracts(NewCodeServer),
- Modules = dict:fetch_keys(Contracts),
- FoldFun =
- fun(Module, TmpPlt) ->
- {ok, ModuleContracts} = dict:find(Module, Contracts),
- SpecList = [{MFA, Contract}
- || {MFA, {_FileLine, Contract}} <- dict:to_list(ModuleContracts)],
- dialyzer_plt:insert_contract_list(TmpPlt, SpecList)
- end,
- NewTrustPLT = lists:foldl(FoldFun, TrustPLT, Modules),
+ ContractsDict = dialyzer_codeserver:get_contracts(NewCodeServer),
+ Contracts = orddict:from_list(dict:to_list(ContractsDict)),
+ NewTrustPLT = dialyzer_plt:insert_contract_list(TrustPLT, Contracts),
Analysis#analysis{trust_plt = NewTrustPLT}.
%%--------------------------------------------------------------------
@@ -172,15 +158,16 @@ get_type_info(#analysis{callgraph = CallGraph,
StrippedCallGraph = remove_external(CallGraph, TrustPLT),
%% io:format("--- Analyzing callgraph... "),
try
- NewPlt = dialyzer_succ_typings:analyze_callgraph(StrippedCallGraph,
- TrustPLT, CodeServer),
+ NewPlt = dialyzer_succ_typings:analyze_callgraph(StrippedCallGraph,
+ TrustPLT,
+ CodeServer),
Analysis#analysis{callgraph = StrippedCallGraph, trust_plt = NewPlt}
catch
error:What ->
- fatal_error(io_lib:format("Analysis failed with message: ~p",
+ fatal_error(io_lib:format("Analysis failed with message: ~tp",
[{What, erlang:get_stacktrace()}]));
throw:{dialyzer_succ_typing_error, Msg} ->
- fatal_error(io_lib:format("Analysis failed with message: ~s", [Msg]))
+ fatal_error(io_lib:format("Analysis failed with message: ~ts", [Msg]))
end.
-spec remove_external(callgraph(), plt()) -> callgraph().
@@ -190,11 +177,11 @@ remove_external(CallGraph, PLT) ->
case get_external(Ext, PLT) of
[] -> ok;
Externals ->
- msg(io_lib:format(" Unknown functions: ~p\n", [lists:usort(Externals)])),
+ msg(io_lib:format(" Unknown functions: ~tp\n", [lists:usort(Externals)])),
ExtTypes = rcv_ext_types(),
case ExtTypes of
[] -> ok;
- _ -> msg(io_lib:format(" Unknown types: ~p\n", [ExtTypes]))
+ _ -> msg(io_lib:format(" Unknown types: ~tp\n", [ExtTypes]))
end
end,
StrippedCG0.
@@ -224,7 +211,7 @@ get_external(Exts, Plt) ->
-type fa() :: {atom(), arity()}.
-type func_info() :: {line(), atom(), arity()}.
--record(info, {records = map__new() :: map_dict(),
+-record(info, {records = maps:new() :: erl_types:type_table(),
functions = [] :: [func_info()],
types = map__new() :: map_dict(),
edoc = false :: boolean()}).
@@ -267,12 +254,12 @@ write_inc_files(Inc) ->
Functions = [Key || {Key, _} <- Val],
Val1 = [{{F,A},Type} || {{_Line,F,A},Type} <- Val],
Info = #info{types = map__from_list(Val1),
- records = map__new(),
+ records = maps:new(),
%% Note we need to sort functions here!
functions = lists:keysort(1, Functions)},
- %% io:format("Types ~p\n", [Info#info.types]),
- %% io:format("Functions ~p\n", [Info#info.functions]),
- %% io:format("Records ~p\n", [Info#info.records]),
+ %% io:format("Types ~tp\n", [Info#info.types]),
+ %% io:format("Functions ~tp\n", [Info#info.functions]),
+ %% io:format("Records ~tp\n", [Info#info.records]),
write_typed_file(File, Info)
end,
lists:foreach(Fun, dict:fetch_keys(Inc#inc.map)).
@@ -362,8 +349,8 @@ check_imported_functions({File, {Line, F, A}}, Inc, Types) ->
end.
inc_warning({F, A}, File) ->
- io:format(" ***Warning: Skip function ~p/~p ", [F, A]),
- io:format("in file ~p because of inconsistent type\n", [File]).
+ io:format(" ***Warning: Skip function ~tp/~p ", [F, A]),
+ io:format("in file ~tp because of inconsistent type\n", [File]).
clean_inc(Inc) ->
Inc1 = remove_yecc_generated_file(Inc),
@@ -420,13 +407,13 @@ get_type({{M, F, A} = MFA, Range, Arg}, CodeServer, Records) ->
{error, invalid_contract} ->
CString = dialyzer_contracts:contract_to_string(Contract),
SigString = dialyzer_utils:format_sig(Sig, Records),
- Msg = io_lib:format("Error in contract of function ~w:~w/~w\n"
+ Msg = io_lib:format("Error in contract of function ~w:~tw/~w\n"
"\t The contract is: " ++ CString ++ "\n" ++
- "\t but the inferred signature is: ~s",
+ "\t but the inferred signature is: ~ts",
[M, F, A, SigString]),
fatal_error(Msg);
{error, ErrorStr} when is_list(ErrorStr) -> % ErrorStr is a string()
- Msg = io_lib:format("Error in contract of function ~w:~w/~w: ~s",
+ Msg = io_lib:format("Error in contract of function ~w:~tw/~w: ~ts",
[M, F, A, ErrorStr]),
fatal_error(Msg)
end
@@ -461,7 +448,7 @@ remove_module_info(FunInfoList) ->
lists:filter(F, FunInfoList).
write_typed_file(File, Info) ->
- io:format(" Processing file: ~p\n", [File]),
+ io:format(" Processing file: ~tp\n", [File]),
Dir = filename:dirname(File),
RootName = filename:basename(filename:rootname(File)),
Ext = filename:extension(File),
@@ -476,18 +463,18 @@ write_typed_file(File, Info) ->
ok -> ok;
{error, enoent} -> ok;
{error, _} ->
- Msg = io_lib:format("Error in deleting file ~s\n", [NewFileName]),
+ Msg = io_lib:format("Error in deleting file ~ts\n", [NewFileName]),
fatal_error(Msg)
end,
write_typed_file(File, Info, NewFileName);
enospc ->
- Msg = io_lib:format("Not enough space in ~p\n", [Dir]),
+ Msg = io_lib:format("Not enough space in ~tp\n", [Dir]),
fatal_error(Msg);
eacces ->
- Msg = io_lib:format("No write permission in ~p\n", [Dir]),
+ Msg = io_lib:format("No write permission in ~tp\n", [Dir]),
fatal_error(Msg);
_ ->
- Msg = io_lib:format("Unhandled error ~s when writing ~p\n",
+ Msg = io_lib:format("Unhandled error ~ts when writing ~tp\n",
[Reason, Dir]),
fatal_error(Msg)
end;
@@ -499,7 +486,7 @@ write_typed_file(File, Info, NewFileName) ->
{ok, Binary} = file:read_file(File),
Chars = binary_to_list(Binary),
write_typed_file(Chars, NewFileName, Info, 1, []),
- io:format(" Saved as: ~p\n", [NewFileName]).
+ io:format(" Saved as: ~tp\n", [NewFileName]).
write_typed_file(Chars, File, #info{functions = []}, _LNo, _Acc) ->
ok = file:write_file(File, list_to_binary(Chars), [append]);
@@ -559,12 +546,12 @@ get_type_string(F, A, Info, Mode) ->
end.
show_type_info(File, Info) ->
- io:format("\n%% File: ~p\n%% ", [File]),
+ io:format("\n%% File: ~tp\n%% ", [File]),
OutputString = lists:concat(["~.", length(File)+8, "c~n"]),
io:fwrite(OutputString, [$-]),
Fun = fun ({_LineNo, F, A}) ->
TypeInfo = get_type_string(F, A, Info, show),
- io:format("~s\n", [TypeInfo])
+ io:format("~ts\n", [TypeInfo])
end,
lists:foreach(Fun, Info#info.functions).
@@ -574,7 +561,7 @@ get_type_info(Func, Types) ->
%% Note: Typeinfo of any function should exist in
%% the result offered by dialyzer, otherwise there
%% *must* be something wrong with the analysis
- Msg = io_lib:format("No type info for function: ~p\n", [Func]),
+ Msg = io_lib:format("No type info for function: ~tp\n", [Func]),
fatal_error(Msg);
{contract, _Fun} = C -> C;
{_RetType, _ArgType} = RA -> RA
@@ -588,7 +575,7 @@ get_type_info(Func, Types) ->
process_cl_args() ->
ArgList = init:get_plain_arguments(),
- %% io:format("Args is ~p\n", [ArgList]),
+ %% io:format("Args is ~tp\n", [ArgList]),
{Args, Analysis} = analyze_args(ArgList, #args{}, #analysis{}),
%% if the mode has not been set, set it to the default mode (show)
{Args, case Analysis#analysis.mode of
@@ -839,14 +826,10 @@ collect_info(Analysis) ->
TmpCServer = NewAnalysis#analysis.codeserver,
NewCServer =
try
- NewRecords = dialyzer_codeserver:get_temp_records(TmpCServer),
+ TmpCServer1 = dialyzer_utils:merge_types(TmpCServer, NewPlt),
NewExpTypes = dialyzer_codeserver:get_temp_exported_types(TmpCServer),
- OldRecords = dialyzer_plt:get_types(NewPlt),
OldExpTypes = dialyzer_plt:get_exported_types(NewPlt),
- MergedRecords = dialyzer_utils:merge_records(NewRecords, OldRecords),
MergedExpTypes = sets:union(NewExpTypes, OldExpTypes),
- %% io:format("Merged Records ~p",[MergedRecords]),
- TmpCServer1 = dialyzer_codeserver:set_temp_records(MergedRecords, TmpCServer),
TmpCServer2 =
dialyzer_codeserver:finalize_exported_types(MergedExpTypes, TmpCServer1),
TmpCServer3 = dialyzer_utils:process_record_remote_types(TmpCServer2),
@@ -863,26 +846,22 @@ collect_one_file_info(File, Analysis) ->
Includes = [filename:dirname(File)|Analysis#analysis.includes],
Is = [{i,Dir} || Dir <- Includes],
Options = dialyzer_utils:src_compiler_opts() ++ Is ++ Ds,
- case dialyzer_utils:get_abstract_code_from_src(File, Options) of
+ case dialyzer_utils:get_core_from_src(File, Options) of
{error, Reason} ->
- %% io:format("File=~p\n,Options=~p\n,Error=~p\n", [File,Options,Reason]),
+ %% io:format("File=~tp\n,Options=~p\n,Error=~p\n", [File,Options,Reason]),
compile_error(Reason);
- {ok, AbstractCode} ->
- case dialyzer_utils:get_core_from_abstract_code(AbstractCode, Options) of
- error -> compile_error(["Could not get core erlang for "++File]);
- {ok, Core} ->
- case dialyzer_utils:get_record_and_type_info(AbstractCode) of
+ {ok, Core} ->
+ case dialyzer_utils:get_record_and_type_info(Core) of
+ {error, Reason} -> compile_error([Reason]);
+ {ok, Records} ->
+ Mod = cerl:concrete(cerl:module_name(Core)),
+ case dialyzer_utils:get_spec_info(Mod, Core, Records) of
{error, Reason} -> compile_error([Reason]);
- {ok, Records} ->
- Mod = cerl:concrete(cerl:module_name(Core)),
- case dialyzer_utils:get_spec_info(Mod, AbstractCode, Records) of
- {error, Reason} -> compile_error([Reason]);
- {ok, SpecInfo, CbInfo} ->
- ExpTypes = get_exported_types_from_core(Core),
- analyze_core_tree(Core, Records, SpecInfo, CbInfo,
- ExpTypes, Analysis, File)
- end
- end
+ {ok, SpecInfo, CbInfo} ->
+ ExpTypes = get_exported_types_from_core(Core),
+ analyze_core_tree(Core, Records, SpecInfo, CbInfo,
+ ExpTypes, Analysis, File)
+ end
end
end.
@@ -943,7 +922,7 @@ analyze_one_function({Var, FunBody} = Function, Acc) ->
{FuncAcc, IncFuncAcc} =
case (FileName =:= OriginalName) orelse (BaseName =:= OriginalName) of
true -> %% Coming from original file
- %% io:format("Added function ~p\n", [{LineNo, F, A}]),
+ %% io:format("Added function ~tp\n", [{LineNo, F, A}]),
{Acc#tmpAcc.funcAcc ++ [FuncInfo], Acc#tmpAcc.incFuncAcc};
false ->
%% Coming from other sourses, including:
@@ -993,7 +972,7 @@ get_exported_types_from_core(Core) ->
-spec fatal_error(string()) -> no_return().
fatal_error(Slogan) ->
- msg(io_lib:format("typer: ~s\n", [Slogan])),
+ msg(io_lib:format("typer: ~ts\n", [Slogan])),
erlang:halt(1).
-spec mode_error(mode(), mode()) -> no_return().
@@ -1014,7 +993,7 @@ compile_error(Reason) ->
-spec msg(string()) -> 'ok'.
msg(Msg) ->
- io:format(standard_error, "~s", [Msg]).
+ io:format(standard_error, "~ts", [Msg]).
%%--------------------------------------------------------------------
%% Version and help messages.
diff --git a/lib/dialyzer/test/Makefile b/lib/dialyzer/test/Makefile
index f43e04dd59..43c8a61ce1 100644
--- a/lib/dialyzer/test/Makefile
+++ b/lib/dialyzer/test/Makefile
@@ -12,7 +12,9 @@ AUXILIARY_FILES=\
dialyzer_common.erl\
file_utils.erl\
dialyzer_SUITE.erl\
- plt_SUITE.erl
+ abstract_SUITE.erl\
+ plt_SUITE.erl\
+ typer_SUITE.erl
# ----------------------------------------------------
# Release directory specification
diff --git a/lib/dialyzer/test/abstract_SUITE.erl b/lib/dialyzer/test/abstract_SUITE.erl
new file mode 100644
index 0000000000..37fb39cf27
--- /dev/null
+++ b/lib/dialyzer/test/abstract_SUITE.erl
@@ -0,0 +1,107 @@
+%% This suite contains cases that cannot be written
+%% in Erlang itself and must be done via the abstract
+%% format.
+
+-module(abstract_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+-include("dialyzer_test_constants.hrl").
+
+-export([suite/0, all/0, init_per_suite/0, init_per_suite/1, end_per_suite/1]).
+-export([generated_case/1]).
+
+suite() ->
+ [{timetrap, {minutes, 1}}].
+all() ->
+ [generated_case].
+
+init_per_suite() ->
+ [{timetrap, ?plt_timeout}].
+init_per_suite(Config) ->
+ OutDir = ?config(priv_dir, Config),
+ case dialyzer_common:check_plt(OutDir) of
+ fail -> {skip, "Plt creation/check failed."};
+ ok -> [{dialyzer_options, []}|Config]
+ end.
+
+end_per_suite(_Config) ->
+ %% This function is required since init_per_suite/1 exists.
+ ok.
+
+generated_case(Config) when is_list(Config) ->
+ %% Equivalent to:
+ %%
+ %% -module(foo).
+ %% -export(bar).
+ %% bar() ->
+ %% Arg = sample,
+ %% case Arg of
+ %% #{} -> map;
+ %% _ -> Arg:fn()
+ %% end.
+ %%
+ %% Except the case statement and its clauses are marked as autogenerated.
+ [] =
+ test([{attribute,1,module,foo},
+ {attribute,2,export,[{bar,0}]},
+ {function,3,bar,0,
+ [{clause,3,[],[],
+ [{match,4,{var,4,'Arg'},{atom,4,sample}},
+ {'case',[{location,5},{generated,true}],{var,5,'Arg'},
+ [{clause,[{location,6},{generated,true}],[{map,6,[]}],[],
+ [{atom,6,map}]},
+ {clause,[{location,7},{generated,true}],[{var,7,'_'}],[],
+ [{call,7,{remote,7,{var,7,'Arg'},{atom,7,fn}},[]}]}]}]}]}],
+ Config, [], []),
+ %% With the first clause not auto-generated
+ [{warn_matching,{_,6},_}] =
+ test([{attribute,1,module,foo},
+ {attribute,2,export,[{bar,0}]},
+ {function,3,bar,0,
+ [{clause,3,[],[],
+ [{match,4,{var,4,'Arg'},{atom,4,sample}},
+ {'case',[{location,5},{generated,true}],{var,5,'Arg'},
+ [{clause,6,[{map,6,[]}],[],
+ [{atom,6,map}]},
+ {clause,[{location,7},{generated,true}],[{var,7,'_'}],[],
+ [{call,7,{remote,7,{var,7,'Arg'},{atom,7,fn}},[]}]}]}]}]}],
+ Config, [], []),
+ %% With Arg set to [] so neither clause matches
+ [{warn_return_no_exit,{_,3},_},
+ {warn_matching,{_,6},_},
+ {warn_failing_call,{_,7},_}] =
+ test([{attribute,1,module,foo},
+ {attribute,2,export,[{bar,0}]},
+ {function,3,bar,0,
+ [{clause,3,[],[],
+ [{match,4,{var,4,'Arg'},{nil,4}},
+ {'case',[{location,5},{generated,true}],{var,5,'Arg'},
+ [{clause,[{location,6},{generated,true}],[{map,6,[]}],[],
+ [{atom,6,map}]},
+ {clause,[{location,7},{generated,true}],[{var,7,'_'}],[],
+ [{call,7,{remote,7,{var,7,'Arg'},{atom,7,fn}},[]}]}]}]}]}],
+ Config, [], []),
+ ok.
+
+test(Prog0, Config, COpts, DOpts) ->
+ Prog = erl_parse:anno_from_term(Prog0),
+ {ok, BeamFile} = compile(Config, Prog, COpts),
+ run_dialyzer(Config, succ_typings, [BeamFile], DOpts).
+
+compile(Config, Prog, CompileOpts) ->
+ OutDir = ?config(priv_dir, Config),
+ Opts = [{outdir, OutDir}, debug_info, return_errors | CompileOpts],
+ {ok, Module, Source} = compile:forms(Prog, Opts),
+ BeamFile = filename:join([OutDir, lists:concat([Module, ".beam"])]),
+ ok = file:write_file(BeamFile, Source),
+ {ok, BeamFile}.
+
+run_dialyzer(Config, Analysis, Files, Opts) ->
+ OutDir = ?config(priv_dir, Config),
+ PltFilename = dialyzer_common:plt_file(OutDir),
+ dialyzer:run([{analysis_type, Analysis},
+ {files, Files},
+ {init_plt, PltFilename},
+ {check_plt, false},
+ {from, byte_code} |
+ Opts]).
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/dialyzer_options b/lib/dialyzer/test/behaviour_SUITE_data/dialyzer_options
index 50991c9bc5..365b4798c5 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/dialyzer_options
+++ b/lib/dialyzer/test/behaviour_SUITE_data/dialyzer_options
@@ -1 +1,2 @@
{dialyzer_options, []}.
+{time_limit, 5}.
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs b/lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs
index 38999e8919..843d26ee59 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs
+++ b/lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs
@@ -1,5 +1,5 @@
-my_callbacks_wrong.erl:26: The return type #state{parent::pid(),status::'closed' | 'init' | 'open',subscribe::[{pid(),integer()}],counter::integer()} in the specification of callback_init/1 is not a subtype of {'ok',_}, which is the expected return type for the callback of my_behaviour behaviour
-my_callbacks_wrong.erl:28: The inferred return type of callback_init/1 (#state{parent::pid(),status::'init',subscribe::[],counter::1}) has nothing in common with {'ok',_}, which is the expected return type for the callback of my_behaviour behaviour
-my_callbacks_wrong.erl:30: The return type {'reply',#state{parent::pid(),status::'closed' | 'init' | 'open',subscribe::[{pid(),integer()}],counter::integer()}} in the specification of callback_cast/3 is not a subtype of {'noreply',_}, which is the expected return type for the callback of my_behaviour behaviour
+my_callbacks_wrong.erl:26: The return type #state{parent::pid(),status::'closed' | 'init' | 'open',subscribe::[{pid(),integer()}],counter::integer()} in the specification of callback_init/1 is not a subtype of {'ok',_}, which is the expected return type for the callback of the my_behaviour behaviour
+my_callbacks_wrong.erl:28: The inferred return type of callback_init/1 (#state{parent::pid(),status::'init',subscribe::[],counter::1}) has nothing in common with {'ok',_}, which is the expected return type for the callback of the my_behaviour behaviour
+my_callbacks_wrong.erl:30: The return type {'reply',#state{parent::pid(),status::'closed' | 'init' | 'open',subscribe::[{pid(),integer()}],counter::integer()}} in the specification of callback_cast/3 is not a subtype of {'noreply',_}, which is the expected return type for the callback of the my_behaviour behaviour
my_callbacks_wrong.erl:39: The specified type for the 2nd argument of callback_call/3 (atom()) is not a supertype of pid(), which is expected type for this argument in the callback of the my_behaviour behaviour
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return
index e646eea383..c3ebee05da 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return
+++ b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return
@@ -1,2 +1,2 @@
-gen_event_incorrect_return.erl:16: The inferred return type of init/1 ('error') has nothing in common with {'error',_} | {'ok',_} | {'ok',_,'hibernate'}, which is the expected return type for the callback of gen_event behaviour
+gen_event_incorrect_return.erl:16: The inferred return type of init/1 ('error') has nothing in common with {'error',_} | {'ok',_} | {'ok',_,'hibernate'}, which is the expected return type for the callback of the gen_event behaviour
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args
index 3e98da785f..1eb8cd455b 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args
+++ b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args
@@ -1,8 +1,5 @@
-gen_server_incorrect_args.erl:3: Undefined callback function code_change/3 (behaviour 'gen_server')
-gen_server_incorrect_args.erl:3: Undefined callback function handle_cast/2 (behaviour 'gen_server')
-gen_server_incorrect_args.erl:3: Undefined callback function handle_info/2 (behaviour 'gen_server')
-gen_server_incorrect_args.erl:3: Undefined callback function init/1 (behaviour 'gen_server')
-gen_server_incorrect_args.erl:3: Undefined callback function terminate/2 (behaviour 'gen_server')
-gen_server_incorrect_args.erl:7: The inferred return type of handle_call/3 ({'no'} | {'ok'}) has nothing in common with {'noreply',_} | {'noreply',_,'hibernate' | 'infinity' | non_neg_integer()} | {'reply',_,_} | {'stop',_,_} | {'reply',_,_,'hibernate' | 'infinity' | non_neg_integer()} | {'stop',_,_,_}, which is the expected return type for the callback of gen_server behaviour
+gen_server_incorrect_args.erl:3: Undefined callback function handle_cast/2 (behaviour gen_server)
+gen_server_incorrect_args.erl:3: Undefined callback function init/1 (behaviour gen_server)
+gen_server_incorrect_args.erl:7: The inferred return type of handle_call/3 ({'no'} | {'ok'}) has nothing in common with {'noreply',_} | {'noreply',_,'hibernate' | 'infinity' | non_neg_integer()} | {'reply',_,_} | {'stop',_,_} | {'reply',_,_,'hibernate' | 'infinity' | non_neg_integer()} | {'stop',_,_,_}, which is the expected return type for the callback of the gen_server behaviour
gen_server_incorrect_args.erl:7: The inferred type for the 2nd argument of handle_call/3 ('boo' | 'foo') is not a supertype of {pid(),_}, which is expected type for this argument in the callback of the gen_server behaviour
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks
index 5e0ed5fd27..188f7822fa 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks
+++ b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks
@@ -1,3 +1,2 @@
-gen_server_missing_callbacks.erl:3: Undefined callback function handle_cast/2 (behaviour 'gen_server')
-gen_server_missing_callbacks.erl:3: Undefined callback function handle_info/2 (behaviour 'gen_server')
+gen_server_missing_callbacks.erl:3: Undefined callback function handle_cast/2 (behaviour gen_server)
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour
index 8cecabccaa..68adf4cfa0 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour
+++ b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour
@@ -1,9 +1,9 @@
-sample_callback_wrong.erl:16: The inferred return type of sample_callback_2/0 (42) has nothing in common with atom(), which is the expected return type for the callback of sample_behaviour behaviour
-sample_callback_wrong.erl:17: The inferred return type of sample_callback_3/0 ('fair') has nothing in common with 'fail' | {'ok',1..255}, which is the expected return type for the callback of sample_behaviour behaviour
-sample_callback_wrong.erl:18: The inferred return type of sample_callback_4/1 ('fail') has nothing in common with 'ok', which is the expected return type for the callback of sample_behaviour behaviour
-sample_callback_wrong.erl:20: The inferred return type of sample_callback_5/1 (string()) has nothing in common with 'fail' | 'ok', which is the expected return type for the callback of sample_behaviour behaviour
+sample_callback_wrong.erl:16: The inferred return type of sample_callback_2/0 (42) has nothing in common with atom(), which is the expected return type for the callback of the sample_behaviour behaviour
+sample_callback_wrong.erl:17: The inferred return type of sample_callback_3/0 ('fair') has nothing in common with 'fail' | {'ok',1..255}, which is the expected return type for the callback of the sample_behaviour behaviour
+sample_callback_wrong.erl:18: The inferred return type of sample_callback_4/1 ('fail') has nothing in common with 'ok', which is the expected return type for the callback of the sample_behaviour behaviour
+sample_callback_wrong.erl:20: The inferred return type of sample_callback_5/1 (string()) has nothing in common with 'fail' | 'ok', which is the expected return type for the callback of the sample_behaviour behaviour
sample_callback_wrong.erl:20: The inferred type for the 1st argument of sample_callback_5/1 (atom()) is not a supertype of 1..255, which is expected type for this argument in the callback of the sample_behaviour behaviour
-sample_callback_wrong.erl:22: The inferred return type of sample_callback_6/3 ({'okk',number()}) has nothing in common with 'fail' | {'ok',1..255}, which is the expected return type for the callback of sample_behaviour behaviour
+sample_callback_wrong.erl:22: The inferred return type of sample_callback_6/3 ({'okk',number()}) has nothing in common with 'fail' | {'ok',1..255}, which is the expected return type for the callback of the sample_behaviour behaviour
sample_callback_wrong.erl:22: The inferred type for the 3rd argument of sample_callback_6/3 (atom()) is not a supertype of string(), which is expected type for this argument in the callback of the sample_behaviour behaviour
-sample_callback_wrong.erl:4: Undefined callback function sample_callback_1/0 (behaviour 'sample_behaviour')
+sample_callback_wrong.erl:4: Undefined callback function sample_callback_1/0 (behaviour sample_behaviour)
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old
index f0181bb59c..67aa872984 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old
+++ b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old
@@ -1,4 +1,4 @@
incorrect_args_callback.erl:12: The inferred type for the 2nd argument of bar/2 ('yes') is not a supertype of [any()], which is expected type for this argument in the callback of the correct_behaviour behaviour
-incorrect_return_callback.erl:9: The inferred return type of foo/0 ('error') has nothing in common with 'no' | 'yes', which is the expected return type for the callback of correct_behaviour behaviour
-missing_callback.erl:5: Undefined callback function foo/0 (behaviour 'correct_behaviour')
+incorrect_return_callback.erl:9: The inferred return type of foo/0 ('error') has nothing in common with 'no' | 'yes', which is the expected return type for the callback of the correct_behaviour behaviour
+missing_callback.erl:5: Undefined callback function foo/0 (behaviour correct_behaviour)
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return b/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return
index 638d031923..5a063a12b8 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return
+++ b/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return
@@ -1,2 +1,2 @@
-supervisor_incorrect_return.erl:14: The inferred return type of init/1 ({'ok',{{'one_against_one',0,1},[{_,_,_,_,_,_},...]}}) has nothing in common with 'ignore' | {'ok',{{'one_for_all',non_neg_integer(),pos_integer()} | {'one_for_one',non_neg_integer(),pos_integer()} | {'rest_for_one',non_neg_integer(),pos_integer()} | {'simple_one_for_one',non_neg_integer(),pos_integer()} | #{'intensity'=>non_neg_integer(), 'period'=>pos_integer(), 'strategy'=>'one_for_all' | 'one_for_one' | 'rest_for_one' | 'simple_one_for_one'},[{_,{atom(),atom(),'undefined' | [any()]},'permanent' | 'temporary' | 'transient','brutal_kill' | 'infinity' | non_neg_integer(),'supervisor' | 'worker','dynamic' | [atom()]} | #{'id':=_, 'start':={atom(),atom(),'undefined' | [any()]}, 'modules'=>'dynamic' | [atom()], 'restart'=>'permanent' | 'temporary' | 'transient', 'shutdown'=>'brutal_kill' | 'infinity' | non_neg_integer(), 'type'=>'supervisor' | 'worker'}]}}, which is the expected return type for the callback of supervisor behaviour
+supervisor_incorrect_return.erl:14: The inferred return type of init/1 ({'ok',{{'one_against_one',0,1},[{_,_,_,_,_,_},...]}}) has nothing in common with 'ignore' | {'ok',{{'one_for_all',non_neg_integer(),pos_integer()} | {'one_for_one',non_neg_integer(),pos_integer()} | {'rest_for_one',non_neg_integer(),pos_integer()} | {'simple_one_for_one',non_neg_integer(),pos_integer()} | #{'intensity'=>non_neg_integer(), 'period'=>pos_integer(), 'strategy'=>'one_for_all' | 'one_for_one' | 'rest_for_one' | 'simple_one_for_one'},[{_,{atom(),atom(),'undefined' | [any()]},'permanent' | 'temporary' | 'transient','brutal_kill' | 'infinity' | non_neg_integer(),'supervisor' | 'worker','dynamic' | [atom()]} | #{'id':=_, 'start':={atom(),atom(),'undefined' | [any()]}, 'modules'=>'dynamic' | [atom()], 'restart'=>'permanent' | 'temporary' | 'transient', 'shutdown'=>'brutal_kill' | 'infinity' | non_neg_integer(), 'type'=>'supervisor' | 'worker'}]}}, which is the expected return type for the callback of the supervisor behaviour
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec b/lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec
index 5284e412f0..f313c24420 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec
+++ b/lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec
@@ -1,6 +1,4 @@
-vars_in_beh_spec.erl:3: Undefined callback function handle_call/3 (behaviour 'gen_server')
-vars_in_beh_spec.erl:3: Undefined callback function handle_cast/2 (behaviour 'gen_server')
-vars_in_beh_spec.erl:3: Undefined callback function handle_info/2 (behaviour 'gen_server')
-vars_in_beh_spec.erl:3: Undefined callback function init/1 (behaviour 'gen_server')
-vars_in_beh_spec.erl:3: Undefined callback function terminate/2 (behaviour 'gen_server')
+vars_in_beh_spec.erl:3: Undefined callback function handle_call/3 (behaviour gen_server)
+vars_in_beh_spec.erl:3: Undefined callback function handle_cast/2 (behaviour gen_server)
+vars_in_beh_spec.erl:3: Undefined callback function init/1 (behaviour gen_server)
diff --git a/lib/dialyzer/test/dialyzer_common.erl b/lib/dialyzer/test/dialyzer_common.erl
index d2b1026c06..48083a2731 100644
--- a/lib/dialyzer/test/dialyzer_common.erl
+++ b/lib/dialyzer/test/dialyzer_common.erl
@@ -7,7 +7,7 @@
-module(dialyzer_common).
--export([check_plt/1, check/4, create_all_suites/0, new_tests/2]).
+-export([check_plt/1, check/4, create_all_suites/0, new_tests/2, plt_file/1]).
-include_lib("kernel/include/file.hrl").
@@ -39,7 +39,7 @@
check_plt(OutDir) ->
io:format("Checking plt:"),
- PltFilename = filename:join(OutDir, ?plt_filename),
+ PltFilename = plt_file(OutDir),
case file:read_file_info(PltFilename) of
{ok, _} -> dialyzer_check_plt(PltFilename);
{error, _ } ->
@@ -63,6 +63,11 @@ check_plt(OutDir) ->
end
end.
+-spec plt_file(string()) -> string().
+
+plt_file(OutDir) ->
+ filename:join(OutDir, ?plt_filename).
+
dialyzer_check_plt(PltFilename) ->
try dialyzer:run([{analysis_type, plt_check},
{init_plt, PltFilename}]) of
@@ -119,7 +124,7 @@ build_plt(PltFilename) ->
'same' | {differ, [term()]}.
check(TestCase, Opts, Dir, OutDir) ->
- PltFilename = filename:join(OutDir, ?plt_filename),
+ PltFilename = plt_file(OutDir),
SrcDir = filename:join(Dir, ?input_files_directory),
ResDir = filename:join(Dir, ?result_files_directory),
Filename = filename:join(SrcDir, atom_to_list(TestCase)),
diff --git a/lib/dialyzer/test/map_SUITE_data/dialyzer_options b/lib/dialyzer/test/map_SUITE_data/dialyzer_options
index 50991c9bc5..02425c33f2 100644
--- a/lib/dialyzer/test/map_SUITE_data/dialyzer_options
+++ b/lib/dialyzer/test/map_SUITE_data/dialyzer_options
@@ -1 +1,2 @@
{dialyzer_options, []}.
+{time_limit, 30}.
diff --git a/lib/dialyzer/test/map_SUITE_data/results/map_galore b/lib/dialyzer/test/map_SUITE_data/results/map_galore
index 6ea88f01f8..c34ba5cf30 100644
--- a/lib/dialyzer/test/map_SUITE_data/results/map_galore
+++ b/lib/dialyzer/test/map_SUITE_data/results/map_galore
@@ -20,9 +20,9 @@ map_galore.erl:186: The pattern #{'x':=2} can never match the type #{'x':=3}
map_galore.erl:187: The pattern #{'x':=3} can never match the type {'a','b','c'}
map_galore.erl:188: The pattern #{'x':=3} can never match the type #{'y':=3}
map_galore.erl:189: The pattern #{'x':=3} can never match the type #{'x':=[101 | 104 | 114 | 116,...]}
-map_galore.erl:2304: Cons will produce an improper list since its 2nd argument is {'b','a'}
-map_galore.erl:2304: The call maps:from_list(nonempty_improper_list({'a','b'},{'b','a'})) will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}])
-map_galore.erl:2305: The call maps:from_list('a') will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}])
-map_galore.erl:2306: The call maps:from_list(42) will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}])
+map_galore.erl:2280: Cons will produce an improper list since its 2nd argument is {'b','a'}
+map_galore.erl:2280: The call maps:from_list(nonempty_improper_list({'a','b'},{'b','a'})) will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}])
+map_galore.erl:2281: The call maps:from_list('a') will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}])
+map_galore.erl:2282: The call maps:from_list(42) will never return since it differs in the 1st argument from the success typing arguments: ([{_,_}])
map_galore.erl:997: A key of type 'nonexisting' cannot exist in a map of type #{}
map_galore.erl:998: A key of type 'nonexisting' cannot exist in a map of type #{1:='a', 2:='b', 4:='d', 5:='e', float()=>'c'}
diff --git a/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2 b/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2
index f6fb98a863..46e2e8d36c 100644
--- a/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2
+++ b/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2
@@ -2,11 +2,11 @@
map_in_guard2.erl:10: The call map_in_guard2:assoc_guard_clause('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (map())
map_in_guard2.erl:12: The pattern 'true' can never match the type 'false'
map_in_guard2.erl:14: The call map_in_guard2:exact_guard_clause(#{}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':=_, _=>_})
-map_in_guard2.erl:17: Clause guard cannot succeed. The variable M was matched against the type 'not_a_map'
+map_in_guard2.erl:17: Guard test is_map(M::'not_a_map') can never succeed
map_in_guard2.erl:20: Function assoc_update/1 has no local return
map_in_guard2.erl:20: Guard test is_map(M::'not_a_map') can never succeed
-map_in_guard2.erl:22: Clause guard cannot succeed. The variable M was matched against the type 'not_a_map'
map_in_guard2.erl:22: Function assoc_guard_clause/1 has no local return
+map_in_guard2.erl:22: Guard test is_map(M::'not_a_map') can never succeed
map_in_guard2.erl:24: Clause guard cannot succeed. The variable M was matched against the type #{}
map_in_guard2.erl:27: Clause guard cannot succeed. The variable M was matched against the type #{}
map_in_guard2.erl:27: Function exact_guard_clause/1 has no local return
diff --git a/lib/dialyzer/test/map_SUITE_data/results/opaque_key b/lib/dialyzer/test/map_SUITE_data/results/opaque_key
index fb7080cdc5..2ae0e0c5c6 100644
--- a/lib/dialyzer/test/map_SUITE_data/results/opaque_key
+++ b/lib/dialyzer/test/map_SUITE_data/results/opaque_key
@@ -6,10 +6,10 @@ opaque_key_adt.erl:59: Invalid type specification for function opaque_key_adt:sm
opaque_key_use.erl:13: The test opaque_key_use:t() =:= opaque_key_use:t(integer()) can never evaluate to 'true'
opaque_key_use.erl:24: Attempt to test for equality between a term of type opaque_key_adt:t(integer()) and a term of opaque type opaque_key_adt:t()
opaque_key_use.erl:37: Function adt_mm1/0 has no local return
-opaque_key_use.erl:40: The attempt to match a term of type opaque_key_adt:m() against the pattern #{A:=R} breaks the opaqueness of the term
+opaque_key_use.erl:40: The attempt to match a term of type opaque_key_adt:m() against the pattern #{A:=R} breaks the opacity of the term
opaque_key_use.erl:48: Function adt_mu1/0 has no local return
-opaque_key_use.erl:51: Guard test is_map(M::opaque_key_adt:m()) breaks the opaqueness of its argument
+opaque_key_use.erl:51: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument
opaque_key_use.erl:53: Function adt_mu2/0 has no local return
-opaque_key_use.erl:56: Guard test is_map(M::opaque_key_adt:m()) breaks the opaqueness of its argument
+opaque_key_use.erl:56: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument
opaque_key_use.erl:58: Function adt_mu3/0 has no local return
-opaque_key_use.erl:60: Guard test is_map(M::opaque_key_adt:m()) breaks the opaqueness of its argument
+opaque_key_use.erl:60: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument
diff --git a/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/a.erl b/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/a.erl
new file mode 100644
index 0000000000..827984b20b
--- /dev/null
+++ b/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/a.erl
@@ -0,0 +1,9 @@
+-module(a).
+-export([to_map/1, to_map/2]).
+-type t() :: #{type := b:t()}.
+
+-spec to_map(t()) -> map().
+to_map(Resource) -> to_map(Resource, #{}).
+
+-spec to_map(t(), map()) -> map().
+to_map(_, Map) when is_map(Map) -> #{}.
diff --git a/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/b.erl b/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/b.erl
new file mode 100644
index 0000000000..31f9bb6b3e
--- /dev/null
+++ b/lib/dialyzer/test/map_SUITE_data/src/mand_remote_val/b.erl
@@ -0,0 +1,3 @@
+-module(b).
+-export_type([t/0]).
+-type t() :: binary().
diff --git a/lib/dialyzer/test/map_SUITE_data/src/map_galore.erl b/lib/dialyzer/test/map_SUITE_data/src/map_galore.erl
index 2611241379..99eb73a5f6 100644
--- a/lib/dialyzer/test/map_SUITE_data/src/map_galore.erl
+++ b/lib/dialyzer/test/map_SUITE_data/src/map_galore.erl
@@ -2070,11 +2070,8 @@ t_bif_map_values(Config) when is_list(Config) ->
ok.
t_erlang_hash(Config) when is_list(Config) ->
-
ok = t_bif_erlang_phash2(),
ok = t_bif_erlang_phash(),
- ok = t_bif_erlang_hash(),
-
ok.
t_bif_erlang_phash2() ->
@@ -2117,27 +2114,6 @@ t_bif_erlang_phash() ->
2620391445 = erlang:phash(M2,Sz), % 3590546636
ok.
-t_bif_erlang_hash() ->
- Sz = 1 bsl 27 - 1,
- 39684169 = erlang:hash(#{},Sz), % 5158
- 33673142 = erlang:hash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz), % 71555838
- 95337869 = erlang:hash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz), % 5497225
- 108959561 = erlang:hash(#{ 1 => a },Sz), % 126071654
- 59623150 = erlang:hash(#{ a => 1 },Sz), % 126426236
-
- 42775386 = erlang:hash(#{{} => <<>>},Sz), % 101655720
- 71692856 = erlang:hash(#{<<>> => {}},Sz), % 101655720
-
- M0 = #{ a => 1, "key" => <<"value">> },
- M1 = maps:remove("key",M0),
- M2 = M1#{ "key" => <<"value">> },
-
- 70254632 = erlang:hash(M0,Sz), % 38260486
- 59623150 = erlang:hash(M1,Sz), % 126426236
- 70254632 = erlang:hash(M2,Sz), % 38260486
- ok.
-
-
t_map_encode_decode(Config) when is_list(Config) ->
<<131,116,0,0,0,0>> = erlang:term_to_binary(#{}),
Pairs = [
diff --git a/lib/dialyzer/test/map_SUITE_data/src/opaque_bif.erl b/lib/dialyzer/test/map_SUITE_data/src/opaque_bif.erl
new file mode 100644
index 0000000000..40214a1887
--- /dev/null
+++ b/lib/dialyzer/test/map_SUITE_data/src/opaque_bif.erl
@@ -0,0 +1,13 @@
+-module(opaque_bif).
+-export([o1/1]).
+-export_type([opaque_any_map/0]).
+-opaque opaque_any_map() :: map().
+
+%% ERL-249: A bug with opaque arguments to maps:merge/2
+%% Reported by Felipe Ripoll on 6/9/2016
+-spec o1(opaque_any_map()) -> opaque_any_map().
+o1(Map) ->
+ maps:merge(o1_c(), Map).
+
+-spec o1_c() -> opaque_any_map().
+o1_c() -> #{}.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/dialyzer_options b/lib/dialyzer/test/opaque_SUITE_data/dialyzer_options
index 3ff26b87db..cb301ff6a1 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/dialyzer_options
+++ b/lib/dialyzer/test/opaque_SUITE_data/dialyzer_options
@@ -1 +1,2 @@
{dialyzer_options, [{warnings, [no_unused, no_return]}]}.
+{time_limit, 40}.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/array b/lib/dialyzer/test/opaque_SUITE_data/results/array
index 9921b61669..6f1aa1ce3d 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/array
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/array
@@ -1,3 +1,3 @@
-array_use.erl:12: The type test is_tuple(array:array(_)) breaks the opaqueness of the term array:array(_)
-array_use.erl:9: The attempt to match a term of type array:array(_) against the pattern {'array', _, _, 'undefined', _} breaks the opaqueness of the term
+array_use.erl:12: The type test is_tuple(array:array(_)) breaks the opacity of the term array:array(_)
+array_use.erl:9: The attempt to match a term of type array:array(_) against the pattern {'array', _, _, 'undefined', _} breaks the opacity of the term
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/dict b/lib/dialyzer/test/opaque_SUITE_data/results/dict
index 42f6663191..3f8242c72d 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/dict
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/dict
@@ -1,15 +1,15 @@
-dict_use.erl:41: The attempt to match a term of type dict:dict(_,_) against the pattern 'gazonk' breaks the opaqueness of the term
-dict_use.erl:45: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opaqueness of the term
-dict_use.erl:46: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opaqueness of the term
-dict_use.erl:51: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opaqueness of the term
-dict_use.erl:52: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opaqueness of the term
+dict_use.erl:41: The attempt to match a term of type dict:dict(_,_) against the pattern 'gazonk' breaks the opacity of the term
+dict_use.erl:45: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opacity of the term
+dict_use.erl:46: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opacity of the term
+dict_use.erl:51: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opacity of the term
+dict_use.erl:52: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opacity of the term
dict_use.erl:58: Attempt to test for equality between a term of type maybe_improper_list() and a term of opaque type dict:dict(_,_)
dict_use.erl:60: Attempt to test for inequality between a term of type atom() and a term of opaque type dict:dict(_,_)
-dict_use.erl:64: Guard test length(D::dict:dict(_,_)) breaks the opaqueness of its argument
-dict_use.erl:65: Guard test is_atom(D::dict:dict(_,_)) breaks the opaqueness of its argument
-dict_use.erl:66: Guard test is_list(D::dict:dict(_,_)) breaks the opaqueness of its argument
-dict_use.erl:70: The type test is_list(dict:dict(_,_)) breaks the opaqueness of the term dict:dict(_,_)
+dict_use.erl:64: Guard test length(D::dict:dict(_,_)) breaks the opacity of its argument
+dict_use.erl:65: Guard test is_atom(D::dict:dict(_,_)) breaks the opacity of its argument
+dict_use.erl:66: Guard test is_list(D::dict:dict(_,_)) breaks the opacity of its argument
+dict_use.erl:70: The type test is_list(dict:dict(_,_)) breaks the opacity of the term dict:dict(_,_)
dict_use.erl:73: The call dict:fetch('foo',[1 | 2 | 3,...]) does not have an opaque term of type dict:dict(_,_) as 2nd argument
dict_use.erl:76: The call dict:merge(Fun::any(),42,[1 | 2,...]) does not have opaque terms as 2nd and 3rd arguments
dict_use.erl:79: The call dict:store(42,'elli',{'dict',0,16,16,8,80,48,{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},{{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}}) does not have an opaque term of type dict:dict(_,_) as 3rd argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/ets b/lib/dialyzer/test/opaque_SUITE_data/results/ets
index e11c7a8352..5dde23fb15 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/ets
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/ets
@@ -1,4 +1,4 @@
-ets_use.erl:12: Guard test is_integer(T::atom() | ets:tid()) breaks the opaqueness of its argument
-ets_use.erl:20: The type test is_integer(atom() | ets:tid()) breaks the opaqueness of the term atom() | ets:tid()
-ets_use.erl:7: Guard test is_integer(T::ets:tid()) breaks the opaqueness of its argument
+ets_use.erl:12: Guard test is_integer(T::atom() | ets:tid()) breaks the opacity of its argument
+ets_use.erl:20: The type test is_integer(atom() | ets:tid()) breaks the opacity of the term atom() | ets:tid()
+ets_use.erl:7: Guard test is_integer(T::ets:tid()) breaks the opacity of its argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/my_queue b/lib/dialyzer/test/opaque_SUITE_data/results/my_queue
index 1f25a6f9c3..67999b0e20 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/my_queue
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/my_queue
@@ -1,7 +1,7 @@
my_queue_use.erl:15: The call my_queue_adt:is_empty([]) does not have an opaque term of type my_queue_adt:my_queue() as 1st argument
my_queue_use.erl:19: The call my_queue_adt:add(42,Q0::[]) does not have an opaque term of type my_queue_adt:my_queue() as 2nd argument
-my_queue_use.erl:24: The attempt to match a term of type my_queue_adt:my_queue() against the pattern [42 | Q2] breaks the opaqueness of the term
+my_queue_use.erl:24: The attempt to match a term of type my_queue_adt:my_queue() against the pattern [42 | Q2] breaks the opacity of the term
my_queue_use.erl:30: Attempt to test for equality between a term of type [] and a term of opaque type my_queue_adt:my_queue()
my_queue_use.erl:34: Cons will produce an improper list since its 2nd argument is my_queue_adt:my_queue()
my_queue_use.erl:34: The call my_queue_adt:dequeue(nonempty_maybe_improper_list(42,my_queue_adt:my_queue())) does not have an opaque term of type my_queue_adt:my_queue() as 1st argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/opaque b/lib/dialyzer/test/opaque_SUITE_data/results/opaque
index 5747f9061f..864e0d853c 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/opaque
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/opaque
@@ -1,3 +1,3 @@
opaque_bug3.erl:19: The pattern 'a' can never match the type #c{}
-opaque_bug4.erl:20: The attempt to match a term of type opaque_adt:abc() against the pattern 'a' breaks the opaqueness of the term
+opaque_bug4.erl:20: The attempt to match a term of type opaque_adt:abc() against the pattern 'a' breaks the opacity of the term
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/para b/lib/dialyzer/test/opaque_SUITE_data/results/para
index 8fe67e39ad..37b5b7b44e 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/para
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/para
@@ -16,12 +16,12 @@ para2.erl:88: The test para2:circ(integer()) =:= para2:circ(integer(),integer())
para3.erl:28: Invalid type specification for function para3:ot2/0. The success typing is () -> 'foo'
para3.erl:36: The pattern {{{17}}} can never match the type {{{{{{_,_,_,_,_}}}}}}
para3.erl:55: Invalid type specification for function para3:t2/0. The success typing is () -> 'foo'
-para3.erl:65: The attempt to match a term of type {{{{{para3_adt:ot1(_,_,_,_,_)}}}}} against the pattern {{{{{17}}}}} breaks the opaqueness of para3_adt:ot1(_,_,_,_,_)
+para3.erl:65: The attempt to match a term of type {{{{{para3_adt:ot1(_,_,_,_,_)}}}}} against the pattern {{{{{17}}}}} breaks the opacity of para3_adt:ot1(_,_,_,_,_)
para3.erl:68: The pattern {{{{17}}}} can never match the type {{{{{para3_adt:ot1(_,_,_,_,_)}}}}}
-para3.erl:74: Invalid type specification for function para3:exp_adt/0. The success typing is () -> 3
-para4.erl:21: Invalid type specification for function para4:a/1. The success typing is (dict:dict(atom() | integer(),atom() | integer()) | para4:d_all()) -> [{atom() | integer(),atom() | integer()}]
-para4.erl:26: Invalid type specification for function para4:i/1. The success typing is (dict:dict(atom() | integer(),atom() | integer()) | para4:d_all()) -> [{atom() | integer(),atom() | integer()}]
-para4.erl:31: Invalid type specification for function para4:t/1. The success typing is (dict:dict(atom() | integer(),atom() | integer()) | para4:d_all()) -> [{atom() | integer(),atom() | integer()}]
+para3.erl:74: The specification for para3:exp_adt/0 has an opaque subtype para3_adt:exp1(para3_adt:exp2()) which is violated by the success typing () -> 3
+para4.erl:21: Invalid type specification for function para4:a/1. The success typing is (para4:d_all() | para4:d_atom()) -> [{atom() | integer(),atom() | integer()}]
+para4.erl:26: Invalid type specification for function para4:i/1. The success typing is (para4:d_all() | para4:d_integer()) -> [{atom() | integer(),atom() | integer()}]
+para4.erl:31: Invalid type specification for function para4:t/1. The success typing is (para4:d_all() | para4:d_tuple()) -> [{atom() | integer(),atom() | integer()}]
para4.erl:59: Attempt to test for equality between a term of type para4_adt:t(atom() | integer()) and a term of opaque type para4_adt:t(integer())
para4.erl:64: Attempt to test for equality between a term of type para4_adt:t(atom() | integer()) and a term of opaque type para4_adt:t(atom())
para4.erl:69: Attempt to test for equality between a term of type para4_adt:int(1 | 2 | 3 | 4) and a term of opaque type para4_adt:int(1 | 2)
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/queue b/lib/dialyzer/test/opaque_SUITE_data/results/queue
index 5b3813c418..9822b7168f 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/queue
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/queue
@@ -1,11 +1,11 @@
queue_use.erl:18: The call queue:is_empty({[],[]}) does not have an opaque term of type queue:queue(_) as 1st argument
queue_use.erl:22: The call queue:in(42,Q0::{[],[]}) does not have an opaque term of type queue:queue(_) as 2nd argument
-queue_use.erl:27: The attempt to match a term of type queue:queue(_) against the pattern {"*", Q2} breaks the opaqueness of the term
+queue_use.erl:27: The attempt to match a term of type queue:queue(_) against the pattern {"*", Q2} breaks the opacity of the term
queue_use.erl:33: Attempt to test for equality between a term of type {[42,...],[]} and a term of opaque type queue:queue(_)
-queue_use.erl:36: The attempt to match a term of type queue:queue(_) against the pattern {F, _R} breaks the opaqueness of the term
+queue_use.erl:36: The attempt to match a term of type queue:queue(_) against the pattern {F, _R} breaks the opacity of the term
queue_use.erl:40: The call queue:out({[42,...],[]}) does not have an opaque term of type queue:queue(_) as 1st argument
queue_use.erl:51: The call queue_use:is_in_queue(E::42,DB::#db{p::[],q::queue:queue(_)}) contains an opaque term as 2nd argument when terms of different types are expected in these positions
-queue_use.erl:56: The attempt to match a term of type #db{p::[],q::queue:queue(_)} against the pattern {'db', _, {L1, L2}} breaks the opaqueness of queue:queue(_)
+queue_use.erl:56: The attempt to match a term of type #db{p::[],q::queue:queue(_)} against the pattern {'db', _, {L1, L2}} breaks the opacity of queue:queue(_)
queue_use.erl:62: The call queue_use:tuple_queue({42,'gazonk'}) does not have a term of type {_,queue:queue(_)} (with opaque subterms) as 1st argument
queue_use.erl:65: The call queue:in(F::42,Q::'gazonk') does not have an opaque term of type queue:queue(_) as 2nd argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/rec b/lib/dialyzer/test/opaque_SUITE_data/results/rec
index 72736b3b3c..e9b217a93f 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/rec
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/rec
@@ -1,6 +1,6 @@
-rec_use.erl:17: The attempt to match a term of type rec_adt:rec() against the pattern {'rec', _, 42} breaks the opaqueness of the term
-rec_use.erl:18: Guard test tuple_size(R::rec_adt:rec()) breaks the opaqueness of its argument
+rec_use.erl:17: The attempt to match a term of type rec_adt:rec() against the pattern {'rec', _, 42} breaks the opacity of the term
+rec_use.erl:18: Guard test tuple_size(R::rec_adt:rec()) breaks the opacity of its argument
rec_use.erl:23: The call rec_adt:get_a(R::tuple()) does not have an opaque term of type rec_adt:rec() as 1st argument
rec_use.erl:27: Attempt to test for equality between a term of type {'rec','gazonk',42} and a term of opaque type rec_adt:rec()
rec_use.erl:30: The call erlang:tuple_size(rec_adt:rec()) contains an opaque term as 1st argument when a structured term of type tuple() is expected
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/simple b/lib/dialyzer/test/opaque_SUITE_data/results/simple
index 391c37664e..5cd8916aee 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/simple
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/simple
@@ -1,29 +1,29 @@
exact_api.erl:17: The call exact_api:set_type(A::#digraph{vtab::'notable',etab::'notable',ntab::'notable',cyclic::'true'}) does not have an opaque term of type digraph:graph() as 1st argument
exact_api.erl:23: The call digraph:delete(G::#digraph{vtab::'notable',etab::'notable',ntab::'notable',cyclic::'true'}) does not have an opaque term of type digraph:graph() as 1st argument
-exact_api.erl:55: The attempt to match a term of type exact_adt:exact_adt() against the pattern {'exact_adt'} breaks the opaqueness of the term
+exact_api.erl:55: The attempt to match a term of type exact_adt:exact_adt() against the pattern {'exact_adt'} breaks the opacity of the term
exact_api.erl:59: The call exact_adt:exact_adt_set_type2(A::#exact_adt{}) does not have an opaque term of type exact_adt:exact_adt() as 1st argument
is_rec.erl:10: The call erlang:is_record(simple1_adt:d1(),'r',2) contains an opaque term as 1st argument when terms of different types are expected in these positions
is_rec.erl:15: The call erlang:is_record(A::simple1_adt:d1(),'r',I::1 | 2 | 3) contains an opaque term as 1st argument when terms of different types are expected in these positions
-is_rec.erl:19: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opaqueness of its argument
-is_rec.erl:23: Guard test is_record({simple1_adt:d1(),1},'r',2) breaks the opaqueness of its argument
+is_rec.erl:19: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opacity of its argument
+is_rec.erl:23: Guard test is_record({simple1_adt:d1(),1},'r',2) breaks the opacity of its argument
is_rec.erl:41: The call erlang:is_record(A::simple1_adt:d1(),R::'a') contains an opaque term as 1st argument when terms of different types are expected in these positions
is_rec.erl:45: The call erlang:is_record(A::simple1_adt:d1(),A::simple1_adt:d1(),1) contains an opaque term as 2nd argument when terms of different types are expected in these positions
is_rec.erl:49: The call erlang:is_record(A::simple1_adt:d1(),any(),1) contains an opaque term as 1st argument when terms of different types are expected in these positions
is_rec.erl:53: The call erlang:is_record(A::simple1_adt:d1(),A::simple1_adt:d1(),any()) contains an opaque term as 2nd argument when terms of different types are expected in these positions
-is_rec.erl:57: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opaqueness of its argument
+is_rec.erl:57: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opacity of its argument
is_rec.erl:61: The record #r{f1::simple1_adt:d1()} violates the declared type for #r{}
is_rec.erl:65: The call erlang:is_record({simple1_adt:d1(),1},'r',2) contains an opaque term as 1st argument when terms of different types are expected in these positions
rec_api.erl:104: Matching of pattern {'r2', 10} tagged with a record name violates the declared type of #r2{f1::10}
-rec_api.erl:113: The attempt to match a term of type #r3{f1::queue:queue(_)} against the pattern {'r3', 'a'} breaks the opaqueness of queue:queue(_)
+rec_api.erl:113: The attempt to match a term of type #r3{f1::queue:queue(_)} against the pattern {'r3', 'a'} breaks the opacity of queue:queue(_)
rec_api.erl:118: Record construction #r3{f1::10} violates the declared type of field f1::queue:queue(_)
-rec_api.erl:123: The attempt to match a term of type #r3{f1::10} against the pattern {'r3', 10} breaks the opaqueness of queue:queue(_)
+rec_api.erl:123: The attempt to match a term of type #r3{f1::10} against the pattern {'r3', 10} breaks the opacity of queue:queue(_)
rec_api.erl:24: Record construction #r1{f1::10} violates the declared type of field f1::rec_api:a()
rec_api.erl:29: Matching of pattern {'r1', 10} tagged with a record name violates the declared type of #r1{f1::10}
-rec_api.erl:33: The attempt to match a term of type rec_adt:r1() against the pattern {'r1', 'a'} breaks the opaqueness of the term
+rec_api.erl:33: The attempt to match a term of type rec_adt:r1() against the pattern {'r1', 'a'} breaks the opacity of the term
rec_api.erl:35: Invalid type specification for function rec_api:adt_t1/1. The success typing is (#r1{f1::'a'}) -> #r1{f1::'a'}
-rec_api.erl:40: Invalid type specification for function rec_api:adt_r1/0. The success typing is () -> #r1{f1::'a'}
-rec_api.erl:85: The attempt to match a term of type rec_api:f() against the variable _ breaks the opaqueness of rec_adt:f()
+rec_api.erl:40: The specification for rec_api:adt_r1/0 has an opaque subtype rec_adt:r1() which is violated by the success typing () -> #r1{f1::'a'}
+rec_api.erl:85: The attempt to match a term of type rec_adt:f() against the record field 'f' declared to be of type rec_api:f() breaks the opacity of the term
rec_api.erl:99: Record construction #r2{f1::10} violates the declared type of field f1::rec_api:a()
simple1_api.erl:113: The test simple1_api:d1() =:= simple1_api:d2() can never evaluate to 'true'
simple1_api.erl:118: Guard test simple1_api:d2() =:= A::simple1_api:d1() can never succeed
@@ -35,20 +35,20 @@ simple1_api.erl:165: Attempt to test for equality between a term of type simple1
simple1_api.erl:181: Guard test A::simple1_adt:d1() =< B::simple1_adt:d2() contains opaque terms as 1st and 2nd arguments
simple1_api.erl:185: Guard test 'a' =< B::simple1_adt:d2() contains an opaque term as 2nd argument
simple1_api.erl:189: Guard test A::simple1_adt:d1() =< 'd' contains an opaque term as 1st argument
-simple1_api.erl:197: The type test is_integer(A::simple1_adt:d1()) breaks the opaqueness of the term A::simple1_adt:d1()
+simple1_api.erl:197: The type test is_integer(A::simple1_adt:d1()) breaks the opacity of the term A::simple1_adt:d1()
simple1_api.erl:221: Guard test A::simple1_api:i1() > 3 can never succeed
simple1_api.erl:225: Guard test A::simple1_adt:i1() > 3 contains an opaque term as 1st argument
simple1_api.erl:233: Guard test A::simple1_adt:i1() < 3 contains an opaque term as 1st argument
simple1_api.erl:239: Guard test A::1 > 3 can never succeed
simple1_api.erl:243: Guard test A::1 > 3 can never succeed
simple1_api.erl:257: Guard test is_function(T::simple1_api:o1()) can never succeed
-simple1_api.erl:265: Guard test is_function(T::simple1_adt:o1()) breaks the opaqueness of its argument
-simple1_api.erl:269: The type test is_function(T::simple1_adt:o1()) breaks the opaqueness of the term T::simple1_adt:o1()
+simple1_api.erl:265: Guard test is_function(T::simple1_adt:o1()) breaks the opacity of its argument
+simple1_api.erl:269: The type test is_function(T::simple1_adt:o1()) breaks the opacity of the term T::simple1_adt:o1()
simple1_api.erl:274: Guard test is_function(T::simple1_api:o1(),A::simple1_api:i1()) can never succeed
-simple1_api.erl:284: Guard test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opaqueness of its argument
-simple1_api.erl:289: The type test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opaqueness of the term T::simple1_adt:o1()
+simple1_api.erl:284: Guard test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opacity of its argument
+simple1_api.erl:289: The type test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opacity of the term T::simple1_adt:o1()
simple1_api.erl:294: The call erlang:is_function(T::simple1_api:o1(),A::simple1_adt:i1()) contains an opaque term as 2nd argument when terms of different types are expected in these positions
-simple1_api.erl:300: The type test is_function(T::simple1_adt:o1(),A::simple1_api:i1()) breaks the opaqueness of the term T::simple1_adt:o1()
+simple1_api.erl:300: The type test is_function(T::simple1_adt:o1(),A::simple1_api:i1()) breaks the opacity of the term T::simple1_adt:o1()
simple1_api.erl:306: Guard test B::simple1_api:b2() =:= 'true' can never succeed
simple1_api.erl:315: Guard test A::simple1_api:b1() =:= 'false' can never succeed
simple1_api.erl:319: Guard test not('and'('true','true')) can never succeed
@@ -60,14 +60,14 @@ simple1_api.erl:365: Clause guard cannot succeed.
simple1_api.erl:368: Invalid type specification for function simple1_api:bool_adt_t8/2. The success typing is (boolean(),boolean()) -> 1
simple1_api.erl:378: Clause guard cannot succeed.
simple1_api.erl:381: Invalid type specification for function simple1_api:bool_adt_t9/2. The success typing is ('false','false') -> 1
-simple1_api.erl:407: The size simple1_adt:i1() breaks the opaqueness of A
-simple1_api.erl:418: The attempt to match a term of type non_neg_integer() against the variable A breaks the opaqueness of simple1_adt:i1()
-simple1_api.erl:425: The attempt to match a term of type non_neg_integer() against the variable B breaks the opaqueness of simple1_adt:i1()
+simple1_api.erl:407: The size simple1_adt:i1() breaks the opacity of A
+simple1_api.erl:418: The attempt to match a term of type non_neg_integer() against the variable A breaks the opacity of simple1_adt:i1()
+simple1_api.erl:425: The attempt to match a term of type non_neg_integer() against the variable B breaks the opacity of simple1_adt:i1()
simple1_api.erl:432: The pattern <<_:B/integer-unit:1>> can never match the type any()
-simple1_api.erl:448: The attempt to match a term of type non_neg_integer() against the variable Sz breaks the opaqueness of simple1_adt:i1()
-simple1_api.erl:460: The attempt to match a term of type simple1_adt:bit1() against the pattern <<_/binary-unit:8>> breaks the opaqueness of the term
-simple1_api.erl:478: The call 'foo':A(A::simple1_adt:a()) breaks the opaqueness of the term A :: simple1_adt:a()
-simple1_api.erl:486: The call A:'foo'(A::simple1_adt:a()) breaks the opaqueness of the term A :: simple1_adt:a()
+simple1_api.erl:448: The attempt to match a term of type non_neg_integer() against the variable Sz breaks the opacity of simple1_adt:i1()
+simple1_api.erl:460: The attempt to match a term of type simple1_adt:bit1() against the pattern <<_/binary-unit:8>> breaks the opacity of the term
+simple1_api.erl:478: The call 'foo':A(A::simple1_adt:a()) breaks the opacity of the term A :: simple1_adt:a()
+simple1_api.erl:486: The call A:'foo'(A::simple1_adt:a()) breaks the opacity of the term A :: simple1_adt:a()
simple1_api.erl:499: The call 'foo':A(A::simple1_api:i()) requires that A is of type atom() not simple1_api:i()
simple1_api.erl:503: The call 'foo':A(A::simple1_adt:i()) requires that A is of type atom() not simple1_adt:i()
simple1_api.erl:507: The call A:'foo'(A::simple1_api:i()) requires that A is of type atom() not simple1_api:i()
@@ -79,7 +79,7 @@ simple1_api.erl:538: Guard test A::simple1_adt:d1() =:= 3 contains an opaque ter
simple1_api.erl:548: The call erlang:'<'(A::simple1_adt:d1(),3) contains an opaque term as 1st argument when terms of different types are expected in these positions
simple1_api.erl:558: The call erlang:'=<'(A::simple1_adt:d1(),B::simple1_adt:d2()) contains opaque terms as 1st and 2nd arguments when terms of different types are expected in these positions
simple1_api.erl:565: Guard test {digraph:graph(),3} > {digraph:graph(),atom() | ets:tid()} contains an opaque term as 2nd argument
-simple1_api.erl:91: Invalid type specification for function simple1_api:tup/0. The success typing is () -> {'a','b'}
+simple1_api.erl:91: The specification for simple1_api:tup/0 has an opaque subtype simple1_adt:tuple1() which is violated by the success typing () -> {'a','b'}
simple2_api.erl:100: The call lists:flatten(A::simple1_adt:tuple1()) contains an opaque term as 1st argument when a structured term of type [any()] is expected
simple2_api.erl:116: The call lists:flatten({simple1_adt:tuple1()}) will never return since it differs in the 1st argument from the success typing arguments: ([any()])
simple2_api.erl:121: Guard test {simple1_adt:d1(),3} > {simple1_adt:d1(),simple1_adt:tuple1()} contains an opaque term as 2nd argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/timer b/lib/dialyzer/test/opaque_SUITE_data/results/timer
index b1cfcd4e9f..46c5a86307 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/timer
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/timer
@@ -1,4 +1,4 @@
timer_use.erl:16: The pattern 'gazonk' can never match the type {'error',_} | {'ok',timer:tref()}
-timer_use.erl:17: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {'ok', 42} breaks the opaqueness of timer:tref()
-timer_use.erl:18: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {Tag, 'gazonk'} breaks the opaqueness of timer:tref()
+timer_use.erl:17: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {'ok', 42} breaks the opacity of timer:tref()
+timer_use.erl:18: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {Tag, 'gazonk'} breaks the opacity of timer:tref()
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/union b/lib/dialyzer/test/opaque_SUITE_data/results/union
index 98829b424a..8763088bf0 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/union
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/union
@@ -1,5 +1,5 @@
-union_use.erl:12: The attempt to match a term of type union_adt:u() against the pattern 'aaa' breaks the opaqueness of the term
-union_use.erl:16: The type test is_tuple(union_adt:u()) breaks the opaqueness of the term union_adt:u()
-union_use.erl:7: Guard test is_atom(A::union_adt:u()) breaks the opaqueness of its argument
-union_use.erl:8: Guard test is_tuple(T::union_adt:u()) breaks the opaqueness of its argument
+union_use.erl:12: The attempt to match a term of type union_adt:u() against the pattern 'aaa' breaks the opacity of the term
+union_use.erl:16: The type test is_tuple(union_adt:u()) breaks the opacity of the term union_adt:u()
+union_use.erl:7: Guard test is_atom(A::union_adt:u()) breaks the opacity of its argument
+union_use.erl:8: Guard test is_tuple(T::union_adt:u()) breaks the opacity of its argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/weird b/lib/dialyzer/test/opaque_SUITE_data/results/weird
new file mode 100644
index 0000000000..d7f57cd152
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/weird
@@ -0,0 +1,6 @@
+
+weird_warning1.erl:15: Matching of pattern {'a', Dict} tagged with a record name violates the declared type of #b{q::queue:queue(_)}
+weird_warning2.erl:13: Matching of pattern <{'b', Queue}, Key, Value> tagged with a record name violates the declared type of <#a{d::dict:dict(_,_)},'my_key','my_value'>
+weird_warning3.erl:14: The call weird_warning3:add_element(#a{d::queue:queue(_)},'my_key','my_value') does not have a term of type #a{d::dict:dict(_,_)} | #b{q::queue:queue(_)} (with opaque subterms) as 1st argument
+weird_warning3.erl:16: The attempt to match a term of type #a{d::queue:queue(_)} against the pattern {'a', Dict} breaks the opacity of queue:queue(_)
+weird_warning3.erl:18: Matching of pattern {'b', Queue} tagged with a record name violates the declared type of #a{d::queue:queue(_)}
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/wings b/lib/dialyzer/test/opaque_SUITE_data/results/wings
index 511263b70a..391501d86f 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/wings
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/wings
@@ -1,11 +1,11 @@
-wings_dissolve.erl:103: Guard test is_list(List::gb_sets:set(_)) breaks the opaqueness of its argument
-wings_dissolve.erl:19: Guard test is_list(Faces::gb_sets:set(_)) breaks the opaqueness of its argument
-wings_dissolve.erl:272: Guard test is_list(Faces::gb_sets:set(_)) breaks the opaqueness of its argument
+wings_dissolve.erl:103: Guard test is_list(List::gb_sets:set(_)) breaks the opacity of its argument
+wings_dissolve.erl:19: Guard test is_list(Faces::gb_sets:set(_)) breaks the opacity of its argument
+wings_dissolve.erl:272: Guard test is_list(Faces::gb_sets:set(_)) breaks the opacity of its argument
wings_dissolve.erl:31: The call gb_sets:is_empty(Faces::[any(),...]) does not have an opaque term of type gb_sets:set(_) as 1st argument
wings_edge.erl:205: The pattern <Edge, 'hard', Htab> can never match the type <_,'soft',_>
wings_edge_cmd.erl:30: The call gb_trees:size(P::gb_sets:set(_)) does not have an opaque term of type gb_trees:tree(_,_) as 1st argument
wings_edge_cmd.erl:32: The pattern [_ | Parts] can never match the type []
wings_edge_cmd.erl:32: The pattern [{_, P} | _] can never match the type []
-wings_io.erl:30: The attempt to match a term of type {'empty',queue:queue(_)} against the pattern {'empty', {In, Out}} breaks the opaqueness of queue:queue(_)
+wings_io.erl:30: The attempt to match a term of type {'empty',queue:queue(_)} against the pattern {'empty', {In, Out}} breaks the opacity of queue:queue(_)
wings_we.erl:155: The call wings_util:gb_trees_largest_key(Etab::gb_trees:tree(_,_)) contains an opaque term as 1st argument when a structured term of type {_,{_,_,_,'nil' | {_,_,_,'nil' | {_,_,_,_}}}} is expected
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl b/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl
index a4cec065ab..2527f166f2 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl
@@ -34,7 +34,7 @@ middle() ->
{w1(), w2()}.
%%---------------------------------------------------------------------
-%% Cases that are problematic w.r.t. opaqueness of types
+%% Cases that are problematic w.r.t. opacity of types
%%---------------------------------------------------------------------
w1() ->
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_ig_moves.erl b/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_ig_moves.erl
new file mode 100644
index 0000000000..94768e77e7
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_ig_moves.erl
@@ -0,0 +1,75 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+-module(hipe_ig_moves).
+-export([new/1,
+ new_move/3,
+ get_moves/1]).
+
+%%-----------------------------------------------------------------------------
+%% The main data structure; its fields are:
+%% - movelist : mapping from temp to set of associated move numbers
+%% - nrmoves : number of distinct move instructions seen so far
+%% - moveinsns : list of move instructions, in descending move number order
+%% - moveset : set of move instructions
+
+-record(ig_moves, {movelist :: movelist(),
+ nrmoves = 0 :: non_neg_integer(),
+ moveinsns = [] :: [{_,_}],
+ moveset = gb_sets:empty() :: gb_sets:set()}).
+
+-type movelist() :: hipe_vectors:vector(ordsets:ordset(non_neg_integer())).
+
+%%-----------------------------------------------------------------------------
+
+-spec new(non_neg_integer()) -> #ig_moves{}.
+
+new(NrTemps) ->
+ MoveList = hipe_vectors:new(NrTemps, ordsets:new()),
+ #ig_moves{movelist = MoveList}.
+
+-spec new_move(_, _, #ig_moves{}) -> #ig_moves{}.
+
+new_move(Dst, Src, IG_moves) ->
+ MoveSet = IG_moves#ig_moves.moveset,
+ MoveInsn = {Dst, Src},
+ case gb_sets:is_member(MoveInsn, MoveSet) of
+ true ->
+ IG_moves;
+ false ->
+ MoveNr = IG_moves#ig_moves.nrmoves,
+ Movelist0 = IG_moves#ig_moves.movelist,
+ Movelist1 = add_movelist(MoveNr, Dst,
+ add_movelist(MoveNr, Src, Movelist0)),
+ IG_moves#ig_moves{nrmoves = MoveNr+1,
+ movelist = Movelist1,
+ moveinsns = [MoveInsn|IG_moves#ig_moves.moveinsns],
+ moveset = gb_sets:insert(MoveInsn, MoveSet)}
+ end.
+
+-spec add_movelist(non_neg_integer(), non_neg_integer(), movelist())
+ -> movelist().
+
+add_movelist(MoveNr, Temp, MoveList) ->
+ AssocMoves = hipe_vectors:get(MoveList, Temp),
+ %% XXX: MoveNr does not occur in moveList[Temp], but the new list must be an
+ %% ordset due to the ordsets:union in hipe_coalescing_regalloc:combine().
+ hipe_vectors:set(MoveList, Temp, ordsets:add_element(MoveNr, AssocMoves)).
+
+-spec get_moves(#ig_moves{}) -> {movelist(), non_neg_integer(), tuple()}.
+
+get_moves(IG_moves) -> % -> {MoveList, NrMoves, MoveInsns}
+ {IG_moves#ig_moves.movelist,
+ IG_moves#ig_moves.nrmoves,
+ list_to_tuple(lists:reverse(IG_moves#ig_moves.moveinsns))}.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_vectors.erl b/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_vectors.erl
new file mode 100644
index 0000000000..1890b86c8d
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_vectors.erl
@@ -0,0 +1,129 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% VECTORS IN ERLANG
+%%
+%% Abstract interface to vectors, indexed from 0 to size-1.
+
+-module(hipe_vectors).
+-export([new/2,
+ set/3,
+ get/2,
+ size/1,
+ vector_to_list/1,
+ %% list_to_vector/1,
+ list/1]).
+
+%%-define(USE_TUPLES, true).
+%%-define(USE_GBTREES, true).
+-define(USE_ARRAYS, true).
+
+-type vector() :: vector(_).
+-export_type([vector/0, vector/1]).
+
+-spec new(non_neg_integer(), V) -> vector(E) when V :: E.
+-spec set(vector(E), non_neg_integer(), V :: E) -> vector(E).
+-spec get(vector(E), non_neg_integer()) -> E.
+-spec size(vector(_)) -> non_neg_integer().
+-spec vector_to_list(vector(E)) -> [E].
+%% -spec list_to_vector([E]) -> vector(E).
+-spec list(vector(E)) -> [{non_neg_integer(), E}].
+
+%% ---------------------------------------------------------------------
+
+-ifdef(USE_TUPLES).
+-opaque vector(_) :: tuple().
+
+new(N, V) ->
+ erlang:make_tuple(N, V).
+
+size(V) -> erlang:tuple_size(V).
+
+list(Vec) ->
+ index(tuple_to_list(Vec), 0).
+
+index([X|Xs],N) ->
+ [{N,X} | index(Xs,N+1)];
+index([],_) ->
+ [].
+
+%% list_to_vector(Xs) ->
+%% list_to_tuple(Xs).
+
+vector_to_list(V) ->
+ tuple_to_list(V).
+
+set(Vec, Ix, V) ->
+ setelement(Ix+1, Vec, V).
+
+get(Vec, Ix) -> element(Ix+1, Vec).
+
+-endif. %% ifdef USE_TUPLES
+
+%% ---------------------------------------------------------------------
+
+-ifdef(USE_GBTREES).
+-opaque vector(E) :: gb_trees:tree(non_neg_integer(), E).
+
+new(N, V) when is_integer(N), N >= 0 ->
+ gb_trees:from_orddict(mklist(N, V)).
+
+mklist(N, V) ->
+ mklist(0, N, V).
+
+mklist(M, N, V) when M < N ->
+ [{M, V} | mklist(M+1, N, V)];
+mklist(_, _, _) ->
+ [].
+
+size(V) -> gb_trees:size(V).
+
+list(Vec) ->
+ gb_trees:to_list(Vec).
+
+%% list_to_vector(Xs) ->
+%% gb_trees:from_orddict(index(Xs, 0)).
+%%
+%% index([X|Xs], N) ->
+%% [{N, X} | index(Xs, N+1)];
+%% index([],_) ->
+%% [].
+
+vector_to_list(V) ->
+ gb_trees:values(V).
+
+set(Vec, Ix, V) ->
+ gb_trees:update(Ix, V, Vec).
+
+get(Vec, Ix) ->
+ gb_trees:get(Ix, Vec).
+
+-endif. %% ifdef USE_GBTREES
+
+%% ---------------------------------------------------------------------
+
+-ifdef(USE_ARRAYS).
+-opaque vector(E) :: array:array(E).
+%%-type vector(E) :: array:array(E). % Work around dialyzer bug
+
+new(N, V) -> array:new(N, {default, V}).
+size(V) -> array:size(V).
+list(Vec) -> array:to_orddict(Vec).
+%% list_to_vector(Xs) -> array:from_list(Xs).
+vector_to_list(V) -> array:to_list(V).
+set(Vec, Ix, V) -> array:set(Ix, V, Vec).
+get(Vec, Ix) -> array:get(Ix, Vec).
+
+-endif. %% ifdef USE_ARRAYS
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl
index 102215b28d..d8c1f561f7 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl
@@ -62,7 +62,7 @@ t2() ->
%% Shows that the list TypeNames in t_from_form must include ArgsLen.
t1_adt() ->
- {{{{{17}}}}} = para3_adt:t1(3). % breaks the opaqueness
+ {{{{{17}}}}} = para3_adt:t1(3). % breaks the opacity
t2_adt() ->
{{{{17}}}} = para3_adt:t1(3). % can never match
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/cerl.erl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/cerl.erl
new file mode 100644
index 0000000000..299ebe60d6
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/cerl.erl
@@ -0,0 +1,4595 @@
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+%% =====================================================================
+%% @doc Core Erlang abstract syntax trees.
+%%
+%% <p> This module defines an abstract data type for representing Core
+%% Erlang source code as syntax trees.</p>
+%%
+%% <p>A recommended starting point for the first-time user is the
+%% documentation of the function <a
+%% href="#type-1"><code>type/1</code></a>.</p>
+%%
+%% <h3><b>NOTES:</b></h3>
+%%
+%% <p>This module deals with the composition and decomposition of
+%% <em>syntactic</em> entities (as opposed to semantic ones); its
+%% purpose is to hide all direct references to the data structures
+%% used to represent these entities. With few exceptions, the
+%% functions in this module perform no semantic interpretation of
+%% their inputs, and in general, the user is assumed to pass
+%% type-correct arguments - if this is not done, the effects are not
+%% defined.</p>
+%%
+%% <p>Currently, the internal data structure used is the same as
+%% the record-based data structures used traditionally in the Beam
+%% compiler.</p>
+%%
+%% <p>The internal representations of abstract syntax trees are
+%% subject to change without notice, and should not be documented
+%% outside this module. Furthermore, we do not give any guarantees on
+%% how an abstract syntax tree may or may not be represented, <em>with
+%% the following exceptions</em>: no syntax tree is represented by a
+%% single atom, such as <code>none</code>, by a list constructor
+%% <code>[X | Y]</code>, or by the empty list <code>[]</code>. This
+%% can be relied on when writing functions that operate on syntax
+%% trees.</p>
+%%
+%% @type cerl(). An abstract Core Erlang syntax tree.
+%%
+%% <p>Every abstract syntax tree has a <em>type</em>, given by the
+%% function <a href="#type-1"><code>type/1</code></a>. In addition,
+%% each syntax tree has a list of <em>user annotations</em> (cf. <a
+%% href="#get_ann-1"><code>get_ann/1</code></a>), which are included
+%% in the Core Erlang syntax.</p>
+
+-module(cerl).
+
+-export([abstract/1, add_ann/2, alias_pat/1, alias_var/1,
+ ann_abstract/2, ann_c_alias/3, ann_c_apply/3, ann_c_atom/2,
+ ann_c_call/4, ann_c_case/3, ann_c_catch/2, ann_c_char/2,
+ ann_c_clause/3, ann_c_clause/4, ann_c_cons/3, ann_c_float/2,
+ ann_c_fname/3, ann_c_fun/3, ann_c_int/2, ann_c_let/4,
+ ann_c_letrec/3, ann_c_module/4, ann_c_module/5, ann_c_nil/1,
+ ann_c_cons_skel/3, ann_c_tuple_skel/2, ann_c_primop/3,
+ ann_c_receive/2, ann_c_receive/4, ann_c_seq/3, ann_c_string/2,
+ ann_c_try/6, ann_c_tuple/2, ann_c_values/2, ann_c_var/2,
+ ann_make_data/3, ann_make_list/2, ann_make_list/3,
+ ann_make_data_skel/3, ann_make_tree/3, apply_args/1,
+ apply_arity/1, apply_op/1, atom_lit/1, atom_name/1, atom_val/1,
+ c_alias/2, c_apply/2, c_atom/1, c_call/3, c_case/2, c_catch/1,
+ c_char/1, c_clause/2, c_clause/3, c_cons/2, c_float/1,
+ c_fname/2, c_fun/2, c_int/1, c_let/3, c_letrec/2, c_module/3,
+ c_module/4, c_nil/0, c_cons_skel/2, c_tuple_skel/1, c_primop/2,
+ c_receive/1, c_receive/3, c_seq/2, c_string/1, c_try/5,
+ c_tuple/1, c_values/1, c_var/1, call_args/1, call_arity/1,
+ call_module/1, call_name/1, case_arg/1, case_arity/1,
+ case_clauses/1, catch_body/1, char_lit/1, char_val/1,
+ clause_arity/1, clause_body/1, clause_guard/1, clause_pats/1,
+ clause_vars/1, concrete/1, cons_hd/1, cons_tl/1, copy_ann/2,
+ data_arity/1, data_es/1, data_type/1, float_lit/1, float_val/1,
+ fname_arity/1, fname_id/1, fold_literal/1, from_records/1,
+ fun_arity/1, fun_body/1, fun_vars/1, get_ann/1, int_lit/1,
+ int_val/1, is_c_alias/1, is_c_apply/1, is_c_atom/1,
+ is_c_call/1, is_c_case/1, is_c_catch/1, is_c_char/1,
+ is_c_clause/1, is_c_cons/1, is_c_float/1, is_c_fname/1,
+ is_c_fun/1, is_c_int/1, is_c_let/1, is_c_letrec/1, is_c_list/1,
+ is_c_module/1, is_c_nil/1, is_c_primop/1, is_c_receive/1,
+ is_c_seq/1, is_c_string/1, is_c_try/1, is_c_tuple/1,
+ is_c_values/1, is_c_var/1, is_data/1, is_leaf/1, is_literal/1,
+ is_literal_term/1, is_print_char/1, is_print_string/1,
+ let_arg/1, let_arity/1, let_body/1, let_vars/1, letrec_body/1,
+ letrec_defs/1, letrec_vars/1, list_elements/1, list_length/1,
+ make_data/2, make_list/1, make_list/2, make_data_skel/2,
+ make_tree/2, meta/1, module_attrs/1, module_defs/1,
+ module_exports/1, module_name/1, module_vars/1,
+ pat_list_vars/1, pat_vars/1, primop_args/1, primop_arity/1,
+ primop_name/1, receive_action/1, receive_clauses/1,
+ receive_timeout/1, seq_arg/1, seq_body/1, set_ann/2,
+ string_lit/1, string_val/1, subtrees/1, to_records/1,
+ try_arg/1, try_body/1, try_vars/1, try_evars/1, try_handler/1,
+ tuple_arity/1, tuple_es/1, type/1, unfold_literal/1,
+ update_c_alias/3, update_c_apply/3, update_c_call/4,
+ update_c_case/3, update_c_catch/2, update_c_clause/4,
+ update_c_cons/3, update_c_cons_skel/3, update_c_fname/2,
+ update_c_fname/3, update_c_fun/3, update_c_let/4,
+ update_c_letrec/3, update_c_module/5, update_c_primop/3,
+ update_c_receive/4, update_c_seq/3, update_c_try/6,
+ update_c_tuple/2, update_c_tuple_skel/2, update_c_values/2,
+ update_c_var/2, update_data/3, update_list/2, update_list/3,
+ update_data_skel/3, update_tree/2, update_tree/3,
+ values_arity/1, values_es/1, var_name/1, c_binary/1,
+ update_c_binary/2, ann_c_binary/2, is_c_binary/1,
+ binary_segments/1, c_bitstr/3, c_bitstr/4, c_bitstr/5,
+ update_c_bitstr/5, update_c_bitstr/6, ann_c_bitstr/5,
+ ann_c_bitstr/6, is_c_bitstr/1, bitstr_val/1, bitstr_size/1,
+ bitstr_bitsize/1, bitstr_unit/1, bitstr_type/1, bitstr_flags/1,
+
+ %% keep map exports here for now
+ c_map_pattern/1,
+ is_c_map/1,
+ is_c_map_pattern/1,
+ map_es/1,
+ map_arg/1,
+ update_c_map/3,
+ c_map/1, is_c_map_empty/1,
+ ann_c_map/2, ann_c_map/3,
+ ann_c_map_pattern/2,
+ map_pair_op/1,map_pair_key/1,map_pair_val/1,
+ update_c_map_pair/4,
+ c_map_pair/2, c_map_pair_exact/2,
+ ann_c_map_pair/4
+ ]).
+
+-export_type([c_binary/0, c_bitstr/0, c_call/0, c_clause/0, c_cons/0, c_fun/0,
+ c_let/0, c_literal/0, c_map/0, c_map_pair/0,
+ c_module/0, c_tuple/0,
+ c_values/0, c_var/0, cerl/0,
+ anns/0, attrs/0, defs/0, litval/0, var_name/0]).
+
+-include("core_parse.hrl").
+
+-type c_alias() :: #c_alias{}.
+-type c_apply() :: #c_apply{}.
+-type c_binary() :: #c_binary{}.
+-type c_bitstr() :: #c_bitstr{}.
+-type c_call() :: #c_call{}.
+-type c_case() :: #c_case{}.
+-type c_catch() :: #c_catch{}.
+-type c_clause() :: #c_clause{}.
+-type c_cons() :: #c_cons{}.
+-type c_fun() :: #c_fun{}.
+-type c_let() :: #c_let{}.
+-type c_letrec() :: #c_letrec{}.
+-type c_literal() :: #c_literal{}.
+-type c_map() :: #c_map{}.
+-type c_map_pair() :: #c_map_pair{}.
+-type c_module() :: #c_module{}.
+-type c_primop() :: #c_primop{}.
+-type c_receive() :: #c_receive{}.
+-type c_seq() :: #c_seq{}.
+-type c_try() :: #c_try{}.
+-type c_tuple() :: #c_tuple{}.
+-type c_values() :: #c_values{}.
+-type c_var() :: #c_var{}.
+
+-type cerl() :: c_alias() | c_apply() | c_binary() | c_bitstr()
+ | c_call() | c_case() | c_catch() | c_clause() | c_cons()
+ | c_fun() | c_let() | c_letrec() | c_literal()
+ | c_map() | c_map_pair()
+ | c_module() | c_primop() | c_receive() | c_seq()
+ | c_try() | c_tuple() | c_values() | c_var().
+
+-type anns() :: [term()].
+-type attr() :: {c_literal(), c_literal()}.
+-type attrs() :: [attr()].
+-type def() :: {c_var(), c_fun()}.
+-type defs() :: [def()].
+
+-type litval() :: atom() | bitstring() | map() | number()
+ | string() | tuple() | [litval()].
+
+-type var_name() :: integer() | atom() | {atom(), arity()}.
+
+
+%% =====================================================================
+%% Representation (general)
+%%
+%% All nodes are represented by tuples of arity 2 or (generally)
+%% greater, whose first element is an atom which uniquely identifies the
+%% type of the node, and whose second element is a (proper) list of
+%% annotation terms associated with the node - this is by default empty.
+%%
+%% For most node constructor functions, there are analogous functions
+%% named 'ann_...', taking one extra argument 'As' (always the first
+%% argument), specifying an annotation list at node creation time.
+%% Similarly, there are also functions named 'update_...', taking one
+%% extra argument 'Old', specifying a node from which all fields not
+%% explicitly given as arguments should be copied (generally, this is
+%% the annotation field only).
+%% =====================================================================
+
+%% @spec type(Node::cerl()) -> atom()
+%%
+%% @doc Returns the type tag of <code>Node</code>. Current node types
+%% are:
+%%
+%% <p><center><table border="1">
+%% <tr>
+%% <td>alias</td>
+%% <td>apply</td>
+%% <td>binary</td>
+%% <td>bitstr</td>
+%% <td>call</td>
+%% <td>case</td>
+%% <td>catch</td>
+%% <td>clause</td>
+%% </tr><tr>
+%% <td>cons</td>
+%% <td>fun</td>
+%% <td>let</td>
+%% <td>letrec</td>
+%% <td>literal</td>
+%% <td>map</td>
+%% <td>map_pair</td>
+%% <td>module</td>
+%% </tr><tr>
+%% <td>primop</td>
+%% <td>receive</td>
+%% <td>seq</td>
+%% <td>try</td>
+%% <td>tuple</td>
+%% <td>values</td>
+%% <td>var</td>
+%% </tr>
+%% </table></center></p>
+%%
+%% <p>Note: The name of the primary constructor function for a node
+%% type is always the name of the type itself, prefixed by
+%% "<code>c_</code>"; recognizer predicates are correspondingly
+%% prefixed by "<code>is_c_</code>". Furthermore, to simplify
+%% preservation of annotations (cf. <code>get_ann/1</code>), there are
+%% analogous constructor functions prefixed by "<code>ann_c_</code>"
+%% and "<code>update_c_</code>", for setting the annotation list of
+%% the new node to either a specific value or to the annotations of an
+%% existing node, respectively.</p>
+%%
+%% @see abstract/1
+%% @see c_alias/2
+%% @see c_apply/2
+%% @see c_binary/1
+%% @see c_bitstr/5
+%% @see c_call/3
+%% @see c_case/2
+%% @see c_catch/1
+%% @see c_clause/3
+%% @see c_cons/2
+%% @see c_fun/2
+%% @see c_let/3
+%% @see c_letrec/2
+%% @see c_module/3
+%% @see c_primop/2
+%% @see c_receive/1
+%% @see c_seq/2
+%% @see c_try/5
+%% @see c_tuple/1
+%% @see c_values/1
+%% @see c_var/1
+%% @see get_ann/1
+%% @see to_records/1
+%% @see from_records/1
+%% @see data_type/1
+%% @see subtrees/1
+%% @see meta/1
+
+-type ctype() :: 'alias' | 'apply' | 'binary' | 'bitrst' | 'call' | 'case'
+ | 'catch' | 'clause' | 'cons' | 'fun' | 'let' | 'letrec'
+ | 'literal' | 'map' | 'map_pair' | 'module' | 'primop'
+ | 'receive' | 'seq' | 'try' | 'tuple' | 'values' | 'var'.
+
+-spec type(cerl()) -> ctype().
+
+type(#c_alias{}) -> alias;
+type(#c_apply{}) -> apply;
+type(#c_binary{}) -> binary;
+type(#c_bitstr{}) -> bitstr;
+type(#c_call{}) -> call;
+type(#c_case{}) -> 'case';
+type(#c_catch{}) -> 'catch';
+type(#c_clause{}) -> clause;
+type(#c_cons{}) -> cons;
+type(#c_fun{}) -> 'fun';
+type(#c_let{}) -> 'let';
+type(#c_letrec{}) -> letrec;
+type(#c_literal{}) -> literal;
+type(#c_map{}) -> map;
+type(#c_map_pair{}) -> map_pair;
+type(#c_module{}) -> module;
+type(#c_primop{}) -> primop;
+type(#c_receive{}) -> 'receive';
+type(#c_seq{}) -> seq;
+type(#c_try{}) -> 'try';
+type(#c_tuple{}) -> tuple;
+type(#c_values{}) -> values;
+type(#c_var{}) -> var.
+
+
+%% @spec is_leaf(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is a leaf node,
+%% otherwise <code>false</code>. The current leaf node types are
+%% <code>literal</code> and <code>var</code>.
+%%
+%% <p>Note: all literals (cf. <code>is_literal/1</code>) are leaf
+%% nodes, even if they represent structured (constant) values such as
+%% <code>{foo, [bar, baz]}</code>. Also note that variables are leaf
+%% nodes but not literals.</p>
+%%
+%% @see type/1
+%% @see is_literal/1
+
+-spec is_leaf(cerl()) -> boolean().
+
+is_leaf(Node) ->
+ case type(Node) of
+ literal -> true;
+ var -> true;
+ _ -> false
+ end.
+
+
+%% @spec get_ann(cerl()) -> anns()
+%%
+%% @doc Returns the list of user annotations associated with a syntax
+%% tree node. For a newly created node, this is the empty list. The
+%% annotations may be any terms.
+%%
+%% @see set_ann/2
+
+-spec get_ann(cerl()) -> anns().
+
+get_ann(Node) ->
+ element(2, Node).
+
+
+%% @spec set_ann(Node::cerl(), Annotations::anns()) -> cerl()
+%%
+%% @doc Sets the list of user annotations of <code>Node</code> to
+%% <code>Annotations</code>.
+%%
+%% @see get_ann/1
+%% @see add_ann/2
+%% @see copy_ann/2
+
+-spec set_ann(cerl(), anns()) -> cerl().
+
+set_ann(Node, List) ->
+ setelement(2, Node, List).
+
+
+%% @spec add_ann(Annotations::anns(), Node::cerl()) -> cerl()
+%%
+%% @doc Appends <code>Annotations</code> to the list of user
+%% annotations of <code>Node</code>.
+%%
+%% <p>Note: this is equivalent to <code>set_ann(Node, Annotations ++
+%% get_ann(Node))</code>, but potentially more efficient.</p>
+%%
+%% @see get_ann/1
+%% @see set_ann/2
+
+-spec add_ann(anns(), cerl()) -> cerl().
+
+add_ann(Terms, Node) ->
+ set_ann(Node, Terms ++ get_ann(Node)).
+
+
+%% @spec copy_ann(Source::cerl(), Target::cerl()) -> cerl()
+%%
+%% @doc Copies the list of user annotations from <code>Source</code>
+%% to <code>Target</code>.
+%%
+%% <p>Note: this is equivalent to <code>set_ann(Target,
+%% get_ann(Source))</code>, but potentially more efficient.</p>
+%%
+%% @see get_ann/1
+%% @see set_ann/2
+
+-spec copy_ann(cerl(), cerl()) -> cerl().
+
+copy_ann(Source, Target) ->
+ set_ann(Target, get_ann(Source)).
+
+
+%% @spec abstract(Term::litval()) -> cerl()
+%%
+%% @doc Creates a syntax tree corresponding to an Erlang term.
+%% <code>Term</code> must be a literal term, i.e., one that can be
+%% represented as a source code literal. Thus, it may not contain a
+%% process identifier, port, reference or function value as a subterm.
+%%
+%% <p>Note: This is a constant time operation.</p>
+%%
+%% @see ann_abstract/2
+%% @see concrete/1
+%% @see is_literal/1
+%% @see is_literal_term/1
+
+-spec abstract(litval()) -> c_literal().
+
+abstract(T) ->
+ #c_literal{val = T}.
+
+
+%% @spec ann_abstract(Annotations::anns(), Term::litval()) -> cerl()
+%% @see abstract/1
+
+-spec ann_abstract(anns(), litval()) -> c_literal().
+
+ann_abstract(As, T) ->
+ #c_literal{val = T, anno = As}.
+
+
+%% @spec is_literal_term(Term::term()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Term</code> can be
+%% represented as a literal, otherwise <code>false</code>. This
+%% function takes time proportional to the size of <code>Term</code>.
+%%
+%% @see abstract/1
+
+-spec is_literal_term(term()) -> boolean().
+
+is_literal_term(T) when is_integer(T) -> true;
+is_literal_term(T) when is_float(T) -> true;
+is_literal_term(T) when is_atom(T) -> true;
+is_literal_term([]) -> true;
+is_literal_term([H | T]) ->
+ is_literal_term(H) andalso is_literal_term(T);
+is_literal_term(T) when is_tuple(T) ->
+ is_literal_term_list(tuple_to_list(T));
+is_literal_term(B) when is_bitstring(B) -> true;
+is_literal_term(M) when is_map(M) ->
+ is_literal_term_list(maps:to_list(M));
+is_literal_term(_) ->
+ false.
+
+-spec is_literal_term_list([term()]) -> boolean().
+
+is_literal_term_list([T | Ts]) ->
+ case is_literal_term(T) of
+ true ->
+ is_literal_term_list(Ts);
+ false ->
+ false
+ end;
+is_literal_term_list([]) ->
+ true.
+
+
+%% @spec concrete(Node::c_literal()) -> litval()
+%%
+%% @doc Returns the Erlang term represented by a syntax tree. An
+%% exception is thrown if <code>Node</code> does not represent a
+%% literal term.
+%%
+%% <p>Note: This is a constant time operation.</p>
+%%
+%% @see abstract/1
+%% @see is_literal/1
+
+%% Because the normal tuple and list constructor operations always
+%% return a literal if the arguments are literals, 'concrete' and
+%% 'is_literal' never need to traverse the structure.
+
+-spec concrete(c_literal()) -> litval().
+
+concrete(#c_literal{val = V}) ->
+ V.
+
+
+%% @spec is_literal(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> represents a
+%% literal term, otherwise <code>false</code>. This function returns
+%% <code>true</code> if and only if the value of
+%% <code>concrete(Node)</code> is defined.
+%%
+%% <p>Note: This is a constant time operation.</p>
+%%
+%% @see abstract/1
+%% @see concrete/1
+%% @see fold_literal/1
+
+-spec is_literal(cerl()) -> boolean().
+
+is_literal(#c_literal{}) ->
+ true;
+is_literal(_) ->
+ false.
+
+
+%% @spec fold_literal(Node::cerl()) -> cerl()
+%%
+%% @doc Assures that literals have a compact representation. This is
+%% occasionally useful if <code>c_cons_skel/2</code>,
+%% <code>c_tuple_skel/1</code> or <code>unfold_literal/1</code> were
+%% used in the construction of <code>Node</code>, and you want to revert
+%% to the normal "folded" representation of literals. If
+%% <code>Node</code> represents a tuple or list constructor, its
+%% elements are rewritten recursively, and the node is reconstructed
+%% using <code>c_cons/2</code> or <code>c_tuple/1</code>, respectively;
+%% otherwise, <code>Node</code> is not changed.
+%%
+%% @see is_literal/1
+%% @see c_cons_skel/2
+%% @see c_tuple_skel/1
+%% @see c_cons/2
+%% @see c_tuple/1
+%% @see unfold_literal/1
+
+-spec fold_literal(cerl()) -> cerl().
+
+fold_literal(Node) ->
+ case type(Node) of
+ tuple ->
+ update_c_tuple(Node, fold_literal_list(tuple_es(Node)));
+ cons ->
+ update_c_cons(Node, fold_literal(cons_hd(Node)),
+ fold_literal(cons_tl(Node)));
+ _ ->
+ Node
+ end.
+
+fold_literal_list([E | Es]) ->
+ [fold_literal(E) | fold_literal_list(Es)];
+fold_literal_list([]) ->
+ [].
+
+
+%% @spec unfold_literal(Node::cerl()) -> cerl()
+%%
+%% @doc Assures that literals have a fully expanded representation. If
+%% <code>Node</code> represents a literal tuple or list constructor, its
+%% elements are rewritten recursively, and the node is reconstructed
+%% using <code>c_cons_skel/2</code> or <code>c_tuple_skel/1</code>,
+%% respectively; otherwise, <code>Node</code> is not changed. The {@link
+%% fold_literal/1} can be used to revert to the normal compact
+%% representation.
+%%
+%% @see is_literal/1
+%% @see c_cons_skel/2
+%% @see c_tuple_skel/1
+%% @see c_cons/2
+%% @see c_tuple/1
+%% @see fold_literal/1
+
+-spec unfold_literal(cerl()) -> cerl().
+
+unfold_literal(Node) ->
+ case type(Node) of
+ literal ->
+ copy_ann(Node, unfold_concrete(concrete(Node)));
+ _ ->
+ Node
+ end.
+
+unfold_concrete(Val) ->
+ case Val of
+ _ when is_tuple(Val) ->
+ c_tuple_skel(unfold_concrete_list(tuple_to_list(Val)));
+ [H|T] ->
+ c_cons_skel(unfold_concrete(H), unfold_concrete(T));
+ _ ->
+ abstract(Val)
+ end.
+
+unfold_concrete_list([E | Es]) ->
+ [unfold_concrete(E) | unfold_concrete_list(Es)];
+unfold_concrete_list([]) ->
+ [].
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_module(Name::c_literal(), Exports, Definitions) -> c_module()
+%%
+%% Exports = [c_var()]
+%% Definitions = defs()
+%%
+%% @equiv c_module(Name, Exports, [], Definitions)
+
+-spec c_module(c_literal(), [c_var()], defs()) -> c_module().
+
+c_module(Name, Exports, Defs) ->
+ #c_module{name = Name, exports = Exports, attrs = [], defs = Defs}.
+
+
+%% @spec c_module(Name::c_literal(), Exports, Attributes, Definitions) ->
+%% c_module()
+%%
+%% Exports = [c_var()]
+%% Attributes = attrs()
+%% Definitions = defs()
+%%
+%% @doc Creates an abstract module definition. The result represents
+%% <pre>
+%% module <em>Name</em> [<em>E1</em>, ..., <em>Ek</em>]
+%% attributes [<em>K1</em> = <em>T1</em>, ...,
+%% <em>Km</em> = <em>Tm</em>]
+%% <em>V1</em> = <em>F1</em>
+%% ...
+%% <em>Vn</em> = <em>Fn</em>
+%% end</pre>
+%%
+%% if <code>Exports</code> = <code>[E1, ..., Ek]</code>,
+%% <code>Attributes</code> = <code>[{K1, T1}, ..., {Km, Tm}]</code>,
+%% and <code>Definitions</code> = <code>[{V1, F1}, ..., {Vn,
+%% Fn}]</code>.
+%%
+%% <p><code>Name</code> and all the <code>Ki</code> must be atom
+%% literals, and all the <code>Ti</code> must be constant literals. All
+%% the <code>Vi</code> and <code>Ei</code> must have type
+%% <code>var</code> and represent function names. All the
+%% <code>Fi</code> must have type <code>'fun'</code>.</p>
+%%
+%% @see c_module/3
+%% @see module_name/1
+%% @see module_exports/1
+%% @see module_attrs/1
+%% @see module_defs/1
+%% @see module_vars/1
+%% @see ann_c_module/4
+%% @see ann_c_module/5
+%% @see update_c_module/5
+%% @see c_atom/1
+%% @see c_var/1
+%% @see c_fun/2
+%% @see is_literal/1
+
+-spec c_module(c_literal(), [c_var()], attrs(), defs()) -> c_module().
+
+c_module(Name, Exports, Attrs, Defs) ->
+ #c_module{name = Name, exports = Exports, attrs = Attrs, defs = Defs}.
+
+
+%% @spec ann_c_module(As::anns(), Name::c_literal(), Exports,
+%% Definitions) -> c_module()
+%%
+%% Exports = [c_var()]
+%% Definitions = defs()
+%%
+%% @see c_module/3
+%% @see ann_c_module/5
+
+-spec ann_c_module(anns(), c_literal(), [c_var()], defs()) -> c_module().
+
+ann_c_module(As, Name, Exports, Defs) ->
+ #c_module{name = Name, exports = Exports, attrs = [], defs = Defs,
+ anno = As}.
+
+
+%% @spec ann_c_module(As::anns(), Name::c_literal(), Exports,
+%% Attributes, Definitions) -> c_module()
+%%
+%% Exports = [c_var()]
+%% Attributes = attrs()
+%% Definitions = defs()
+%%
+%% @see c_module/4
+%% @see ann_c_module/4
+
+-spec ann_c_module(anns(), c_literal(), [c_var()], attrs(), defs()) ->
+ c_module().
+
+ann_c_module(As, Name, Exports, Attrs, Defs) ->
+ #c_module{name = Name, exports = Exports, attrs = Attrs, defs = Defs,
+ anno = As}.
+
+
+%% @spec update_c_module(Old::cerl(), Name::c_literal(), Exports,
+%% Attributes, Definitions) -> c_module()
+%%
+%% Exports = [c_var()]
+%% Attributes = attrs()
+%% Definitions = defs()
+%%
+%% @see c_module/4
+
+-spec update_c_module(c_module(), c_literal(), [c_var()], attrs(), defs()) ->
+ c_module().
+
+update_c_module(Node, Name, Exports, Attrs, Defs) ->
+ #c_module{name = Name, exports = Exports, attrs = Attrs, defs = Defs,
+ anno = get_ann(Node)}.
+
+
+%% @spec is_c_module(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% module definition, otherwise <code>false</code>.
+%%
+%% @see type/1
+
+-spec is_c_module(cerl()) -> boolean().
+
+is_c_module(#c_module{}) ->
+ true;
+is_c_module(_) ->
+ false.
+
+
+%% @spec module_name(Node::c_module()) -> c_literal()
+%%
+%% @doc Returns the name subtree of an abstract module definition.
+%%
+%% @see c_module/4
+
+-spec module_name(c_module()) -> c_literal().
+
+module_name(Node) ->
+ Node#c_module.name.
+
+
+%% @spec module_exports(Node::c_module()) -> [c_var()]
+%%
+%% @doc Returns the list of exports subtrees of an abstract module
+%% definition.
+%%
+%% @see c_module/4
+
+-spec module_exports(c_module()) -> [c_var()].
+
+module_exports(Node) ->
+ Node#c_module.exports.
+
+
+%% @spec module_attrs(Node::c_module()) -> [{cerl(), cerl()}]
+%%
+%% @doc Returns the list of pairs of attribute key/value subtrees of
+%% an abstract module definition.
+%%
+%% @see c_module/4
+
+-spec module_attrs(c_module()) -> attrs().
+
+module_attrs(Node) ->
+ Node#c_module.attrs.
+
+
+%% @spec module_defs(Node::c_module()) -> defs()
+%%
+%% @doc Returns the list of function definitions of an abstract module
+%% definition.
+%%
+%% @see c_module/4
+
+-spec module_defs(c_module()) -> defs().
+
+module_defs(Node) ->
+ Node#c_module.defs.
+
+
+%% @spec module_vars(Node::c_module()) -> [c_var()]
+%%
+%% @doc Returns the list of left-hand side function variable subtrees
+%% of an abstract module definition.
+%%
+%% @see c_module/4
+
+-spec module_vars(c_module()) -> [c_var()].
+
+module_vars(Node) ->
+ [F || {F, _} <- module_defs(Node)].
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_int(Value::integer()) -> c_literal()
+%%
+%% @doc Creates an abstract integer literal. The lexical
+%% representation is the canonical decimal numeral of
+%% <code>Value</code>.
+%%
+%% @see ann_c_int/2
+%% @see is_c_int/1
+%% @see int_val/1
+%% @see int_lit/1
+%% @see c_char/1
+
+-spec c_int(integer()) -> c_literal().
+
+c_int(Value) ->
+ #c_literal{val = Value}.
+
+
+%% @spec ann_c_int(As::anns(), Value::integer()) -> c_literal()
+%% @see c_int/1
+
+-spec ann_c_int(anns(), integer()) -> c_literal().
+
+ann_c_int(As, Value) ->
+ #c_literal{val = Value, anno = As}.
+
+
+%% @spec is_c_int(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> represents an
+%% integer literal, otherwise <code>false</code>.
+%% @see c_int/1
+
+-spec is_c_int(cerl()) -> boolean().
+
+is_c_int(#c_literal{val = V}) when is_integer(V) ->
+ true;
+is_c_int(_) ->
+ false.
+
+
+%% @spec int_val(c_literal()) -> integer()
+%%
+%% @doc Returns the value represented by an integer literal node.
+%% @see c_int/1
+
+-spec int_val(c_literal()) -> integer().
+
+int_val(Node) ->
+ Node#c_literal.val.
+
+
+%% @spec int_lit(c_literal()) -> string()
+%%
+%% @doc Returns the numeral string represented by an integer literal
+%% node.
+%% @see c_int/1
+
+-spec int_lit(c_literal()) -> string().
+
+int_lit(Node) ->
+ integer_to_list(int_val(Node)).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_float(Value::float()) -> c_literal()
+%%
+%% @doc Creates an abstract floating-point literal. The lexical
+%% representation is the decimal floating-point numeral of
+%% <code>Value</code>.
+%%
+%% @see ann_c_float/2
+%% @see is_c_float/1
+%% @see float_val/1
+%% @see float_lit/1
+
+%% Note that not all floating-point numerals can be represented with
+%% full precision.
+
+-spec c_float(float()) -> c_literal().
+
+c_float(Value) ->
+ #c_literal{val = Value}.
+
+
+%% @spec ann_c_float(As::anns(), Value::float()) -> c_literal()
+%% @see c_float/1
+
+-spec ann_c_float(anns(), float()) -> c_literal().
+
+ann_c_float(As, Value) ->
+ #c_literal{val = Value, anno = As}.
+
+
+%% @spec is_c_float(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> represents a
+%% floating-point literal, otherwise <code>false</code>.
+%% @see c_float/1
+
+-spec is_c_float(cerl()) -> boolean().
+
+is_c_float(#c_literal{val = V}) when is_float(V) ->
+ true;
+is_c_float(_) ->
+ false.
+
+
+%% @spec float_val(c_literal()) -> float()
+%%
+%% @doc Returns the value represented by a floating-point literal
+%% node.
+%% @see c_float/1
+
+-spec float_val(c_literal()) -> float().
+
+float_val(Node) ->
+ Node#c_literal.val.
+
+
+%% @spec float_lit(c_literal()) -> string()
+%%
+%% @doc Returns the numeral string represented by a floating-point
+%% literal node.
+%% @see c_float/1
+
+-spec float_lit(c_literal()) -> string().
+
+float_lit(Node) ->
+ float_to_list(float_val(Node)).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_atom(Name) -> c_literal()
+%% Name = atom() | string()
+%%
+%% @doc Creates an abstract atom literal. The print name of the atom
+%% is the character sequence represented by <code>Name</code>.
+%%
+%% <p>Note: passing a string as argument to this function causes a
+%% corresponding atom to be created for the internal representation.</p>
+%%
+%% @see ann_c_atom/2
+%% @see is_c_atom/1
+%% @see atom_val/1
+%% @see atom_name/1
+%% @see atom_lit/1
+
+-spec c_atom(atom() | string()) -> c_literal().
+
+c_atom(Name) when is_atom(Name) ->
+ #c_literal{val = Name};
+c_atom(Name) ->
+ #c_literal{val = list_to_atom(Name)}.
+
+
+%% @spec ann_c_atom(As::anns(), Name) -> cerl()
+%% Name = atom() | string()
+%% @see c_atom/1
+
+-spec ann_c_atom(anns(), atom() | string()) -> c_literal().
+
+ann_c_atom(As, Name) when is_atom(Name) ->
+ #c_literal{val = Name, anno = As};
+ann_c_atom(As, Name) ->
+ #c_literal{val = list_to_atom(Name), anno = As}.
+
+
+%% @spec is_c_atom(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> represents an
+%% atom literal, otherwise <code>false</code>.
+%%
+%% @see c_atom/1
+
+-spec is_c_atom(cerl()) -> boolean().
+
+is_c_atom(#c_literal{val = V}) when is_atom(V) ->
+ true;
+is_c_atom(_) ->
+ false.
+
+%% @spec atom_val(c_literal()) -> atom()
+%%
+%% @doc Returns the value represented by an abstract atom.
+%%
+%% @see c_atom/1
+
+-spec atom_val(c_literal()) -> atom().
+
+atom_val(Node) ->
+ Node#c_literal.val.
+
+
+%% @spec atom_name(c_literal()) -> string()
+%%
+%% @doc Returns the printname of an abstract atom.
+%%
+%% @see c_atom/1
+
+-spec atom_name(c_literal()) -> string().
+
+atom_name(Node) ->
+ atom_to_list(atom_val(Node)).
+
+
+%% @spec atom_lit(cerl()) -> string()
+%%
+%% @doc Returns the literal string represented by an abstract
+%% atom. This always includes surrounding single-quote characters.
+%%
+%% <p>Note that an abstract atom may have several literal
+%% representations, and that the representation yielded by this
+%% function is not fixed; e.g.,
+%% <code>atom_lit(c_atom("a\012b"))</code> could yield the string
+%% <code>"\'a\\nb\'"</code>.</p>
+%%
+%% @see c_atom/1
+
+%% TODO: replace the use of the unofficial 'write_string/2'.
+
+-spec atom_lit(cerl()) -> nonempty_string().
+
+atom_lit(Node) ->
+ io_lib:write_string(atom_name(Node), $'). %' stupid Emacs.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_char(Value) -> c_literal()
+%%
+%% Value = char() | integer()
+%%
+%% @doc Creates an abstract character literal. If the local
+%% implementation of Erlang defines <code>char()</code> as a subset of
+%% <code>integer()</code>, this function is equivalent to
+%% <code>c_int/1</code>. Otherwise, if the given value is an integer,
+%% it will be converted to the character with the corresponding
+%% code. The lexical representation of a character is
+%% "<code>$<em>Char</em></code>", where <code>Char</code> is a single
+%% printing character or an escape sequence.
+%%
+%% @see c_int/1
+%% @see c_string/1
+%% @see ann_c_char/2
+%% @see is_c_char/1
+%% @see char_val/1
+%% @see char_lit/1
+%% @see is_print_char/1
+
+-spec c_char(non_neg_integer()) -> c_literal().
+
+c_char(Value) when is_integer(Value), Value >= 0 ->
+ #c_literal{val = Value}.
+
+
+%% @spec ann_c_char(As::anns(), Value::char()) -> c_literal()
+%% @see c_char/1
+
+-spec ann_c_char(anns(), char()) -> c_literal().
+
+ann_c_char(As, Value) ->
+ #c_literal{val = Value, anno = As}.
+
+
+%% @spec is_c_char(Node::c_literal()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> may represent a
+%% character literal, otherwise <code>false</code>.
+%%
+%% <p>If the local implementation of Erlang defines
+%% <code>char()</code> as a subset of <code>integer()</code>, then
+%% <code>is_c_int(<em>Node</em>)</code> will also yield
+%% <code>true</code>.</p>
+%%
+%% @see c_char/1
+%% @see is_print_char/1
+
+-spec is_c_char(c_literal()) -> boolean().
+
+is_c_char(#c_literal{val = V}) when is_integer(V), V >= 0 ->
+ is_char_value(V);
+is_c_char(_) ->
+ false.
+
+
+%% @spec is_print_char(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> may represent a
+%% "printing" character, otherwise <code>false</code>. (Cf.
+%% <code>is_c_char/1</code>.) A "printing" character has either a
+%% given graphical representation, or a "named" escape sequence such
+%% as "<code>\n</code>". Currently, only ISO 8859-1 (Latin-1)
+%% character values are recognized.
+%%
+%% @see c_char/1
+%% @see is_c_char/1
+
+-spec is_print_char(cerl()) -> boolean().
+
+is_print_char(#c_literal{val = V}) when is_integer(V), V >= 0 ->
+ is_print_char_value(V);
+is_print_char(_) ->
+ false.
+
+
+%% @spec char_val(c_literal()) -> char()
+%%
+%% @doc Returns the value represented by an abstract character literal.
+%%
+%% @see c_char/1
+
+-spec char_val(c_literal()) -> char().
+
+char_val(Node) ->
+ Node#c_literal.val.
+
+
+%% @spec char_lit(c_literal()) -> string()
+%%
+%% @doc Returns the literal string represented by an abstract
+%% character. This includes a leading <code>$</code>
+%% character. Currently, all characters that are not in the set of ISO
+%% 8859-1 (Latin-1) "printing" characters will be escaped.
+%%
+%% @see c_char/1
+
+-spec char_lit(c_literal()) -> nonempty_string().
+
+char_lit(Node) ->
+ io_lib:write_char(char_val(Node)).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_string(Value::string()) -> c_literal()
+%%
+%% @doc Creates an abstract string literal. Equivalent to creating an
+%% abstract list of the corresponding character literals
+%% (cf. <code>is_c_string/1</code>), but is typically more
+%% efficient. The lexical representation of a string is
+%% "<code>"<em>Chars</em>"</code>", where <code>Chars</code> is a
+%% sequence of printing characters or spaces.
+%%
+%% @see c_char/1
+%% @see ann_c_string/2
+%% @see is_c_string/1
+%% @see string_val/1
+%% @see string_lit/1
+%% @see is_print_string/1
+
+-spec c_string(string()) -> c_literal().
+
+c_string(Value) ->
+ #c_literal{val = Value}.
+
+
+%% @spec ann_c_string(As::anns(), Value::string()) -> c_literal()
+%% @see c_string/1
+
+-spec ann_c_string(anns(), string()) -> c_literal().
+
+ann_c_string(As, Value) ->
+ #c_literal{val = Value, anno = As}.
+
+
+%% @spec is_c_string(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> may represent a
+%% string literal, otherwise <code>false</code>. Strings are defined
+%% as lists of characters; see <code>is_c_char/1</code> for details.
+%%
+%% @see c_string/1
+%% @see is_c_char/1
+%% @see is_print_string/1
+
+-spec is_c_string(cerl()) -> boolean().
+
+is_c_string(#c_literal{val = V}) ->
+ is_char_list(V);
+is_c_string(_) ->
+ false.
+
+
+%% @spec is_print_string(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> may represent a
+%% string literal containing only "printing" characters, otherwise
+%% <code>false</code>. See <code>is_c_string/1</code> and
+%% <code>is_print_char/1</code> for details. Currently, only ISO
+%% 8859-1 (Latin-1) character values are recognized.
+%%
+%% @see c_string/1
+%% @see is_c_string/1
+%% @see is_print_char/1
+
+-spec is_print_string(cerl()) -> boolean().
+
+is_print_string(#c_literal{val = V}) ->
+ is_print_char_list(V);
+is_print_string(_) ->
+ false.
+
+
+%% @spec string_val(cerl()) -> string()
+%%
+%% @doc Returns the value represented by an abstract string literal.
+%%
+%% @see c_string/1
+
+-spec string_val(c_literal()) -> string().
+
+string_val(Node) ->
+ Node#c_literal.val.
+
+
+%% @spec string_lit(cerl()) -> string()
+%%
+%% @doc Returns the literal string represented by an abstract string.
+%% This includes surrounding double-quote characters
+%% <code>"..."</code>. Currently, characters that are not in the set
+%% of ISO 8859-1 (Latin-1) "printing" characters will be escaped,
+%% except for spaces.
+%%
+%% @see c_string/1
+
+-spec string_lit(c_literal()) -> nonempty_string().
+
+string_lit(Node) ->
+ io_lib:write_string(string_val(Node)).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_nil() -> cerl()
+%%
+%% @doc Creates an abstract empty list. The result represents
+%% "<code>[]</code>". The empty list is traditionally called "nil".
+%%
+%% @see ann_c_nil/1
+%% @see is_c_list/1
+%% @see c_cons/2
+
+-spec c_nil() -> c_literal().
+
+c_nil() ->
+ #c_literal{val = []}.
+
+
+%% @spec ann_c_nil(As::anns()) -> cerl()
+%% @see c_nil/0
+
+-spec ann_c_nil(anns()) -> c_literal().
+
+ann_c_nil(As) ->
+ #c_literal{val = [], anno = As}.
+
+
+%% @spec is_c_nil(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% empty list, otherwise <code>false</code>.
+
+-spec is_c_nil(cerl()) -> boolean().
+
+is_c_nil(#c_literal{val = []}) ->
+ true;
+is_c_nil(_) ->
+ false.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_cons(Head::cerl(), Tail::cerl()) -> cerl()
+%%
+%% @doc Creates an abstract list constructor. The result represents
+%% "<code>[<em>Head</em> | <em>Tail</em>]</code>". Note that if both
+%% <code>Head</code> and <code>Tail</code> have type
+%% <code>literal</code>, then the result will also have type
+%% <code>literal</code>, and annotations on <code>Head</code> and
+%% <code>Tail</code> are lost.
+%%
+%% <p>Recall that in Erlang, the tail element of a list constructor is
+%% not necessarily a list.</p>
+%%
+%% @see ann_c_cons/3
+%% @see update_c_cons/3
+%% @see c_cons_skel/2
+%% @see is_c_cons/1
+%% @see cons_hd/1
+%% @see cons_tl/1
+%% @see is_c_list/1
+%% @see c_nil/0
+%% @see list_elements/1
+%% @see list_length/1
+%% @see make_list/2
+
+%% *Always* collapse literals.
+
+-spec c_cons(cerl(), cerl()) -> c_literal() | c_cons().
+
+c_cons(#c_literal{val = Head}, #c_literal{val = Tail}) ->
+ #c_literal{val = [Head | Tail]};
+c_cons(Head, Tail) ->
+ #c_cons{hd = Head, tl = Tail}.
+
+
+%% @spec ann_c_cons(As::anns(), Head::cerl(), Tail::cerl()) -> cerl()
+%% @see c_cons/2
+
+-spec ann_c_cons(anns(), cerl(), cerl()) -> c_literal() | c_cons().
+
+ann_c_cons(As, #c_literal{val = Head}, #c_literal{val = Tail}) ->
+ #c_literal{val = [Head | Tail], anno = As};
+ann_c_cons(As, Head, Tail) ->
+ #c_cons{hd = Head, tl = Tail, anno = As}.
+
+
+%% @spec update_c_cons(Old::cerl(), Head::cerl(), Tail::cerl()) ->
+%% cerl()
+%% @see c_cons/2
+
+-spec update_c_cons(c_literal() | c_cons(), cerl(), cerl()) ->
+ c_literal() | c_cons().
+
+update_c_cons(Node, #c_literal{val = Head}, #c_literal{val = Tail}) ->
+ #c_literal{val = [Head | Tail], anno = get_ann(Node)};
+update_c_cons(Node, Head, Tail) ->
+ #c_cons{hd = Head, tl = Tail, anno = get_ann(Node)}.
+
+
+%% @spec c_cons_skel(Head::cerl(), Tail::cerl()) -> c_cons()
+%%
+%% @doc Creates an abstract list constructor skeleton. Does not fold
+%% constant literals, i.e., the result always has type
+%% <code>cons</code>, representing "<code>[<em>Head</em> |
+%% <em>Tail</em>]</code>".
+%%
+%% <p>This function is occasionally useful when it is necessary to have
+%% annotations on the subnodes of a list constructor node, even when the
+%% subnodes are constant literals. Note however that
+%% <code>is_literal/1</code> will yield <code>false</code> and
+%% <code>concrete/1</code> will fail if passed the result from this
+%% function.</p>
+%%
+%% <p><code>fold_literal/1</code> can be used to revert a node to the
+%% normal-form representation.</p>
+%%
+%% @see ann_c_cons_skel/3
+%% @see update_c_cons_skel/3
+%% @see c_cons/2
+%% @see is_c_cons/1
+%% @see is_c_list/1
+%% @see c_nil/0
+%% @see is_literal/1
+%% @see fold_literal/1
+%% @see concrete/1
+
+%% *Never* collapse literals.
+
+-spec c_cons_skel(cerl(), cerl()) -> c_cons().
+
+c_cons_skel(Head, Tail) ->
+ #c_cons{hd = Head, tl = Tail}.
+
+
+%% @spec ann_c_cons_skel(As::anns(), Head::cerl(), Tail::cerl()) ->
+%% c_cons()
+%% @see c_cons_skel/2
+
+-spec ann_c_cons_skel(anns(), cerl(), cerl()) -> c_cons().
+
+ann_c_cons_skel(As, Head, Tail) ->
+ #c_cons{hd = Head, tl = Tail, anno = As}.
+
+
+%% @spec update_c_cons_skel(Old::cerl(), Head::cerl(), Tail::cerl()) ->
+%% c_cons()
+%% @see c_cons_skel/2
+
+-spec update_c_cons_skel(c_cons() | c_literal(), cerl(), cerl()) -> c_cons().
+
+update_c_cons_skel(Node, Head, Tail) ->
+ #c_cons{hd = Head, tl = Tail, anno = get_ann(Node)}.
+
+
+%% @spec is_c_cons(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% list constructor, otherwise <code>false</code>.
+
+-spec is_c_cons(cerl()) -> boolean().
+
+is_c_cons(#c_cons{}) ->
+ true;
+is_c_cons(#c_literal{val = [_ | _]}) ->
+ true;
+is_c_cons(_) ->
+ false.
+
+
+%% @spec cons_hd(cerl()) -> cerl()
+%%
+%% @doc Returns the head subtree of an abstract list constructor.
+%%
+%% @see c_cons/2
+
+-spec cons_hd(c_cons() | c_literal()) -> cerl().
+
+cons_hd(#c_cons{hd = Head}) ->
+ Head;
+cons_hd(#c_literal{val = [Head | _]}) ->
+ #c_literal{val = Head}.
+
+
+%% @spec cons_tl(c_cons() | c_literal()) -> cerl()
+%%
+%% @doc Returns the tail subtree of an abstract list constructor.
+%%
+%% <p>Recall that the tail does not necessarily represent a proper
+%% list.</p>
+%%
+%% @see c_cons/2
+
+-spec cons_tl(c_cons() | c_literal()) -> cerl().
+
+cons_tl(#c_cons{tl = Tail}) ->
+ Tail;
+cons_tl(#c_literal{val = [_ | Tail]}) ->
+ #c_literal{val = Tail}.
+
+
+%% @spec is_c_list(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> represents a
+%% proper list, otherwise <code>false</code>. A proper list is either
+%% the empty list <code>[]</code>, or a cons cell <code>[<em>Head</em> |
+%% <em>Tail</em>]</code>, where recursively <code>Tail</code> is a
+%% proper list.
+%%
+%% <p>Note: Because <code>Node</code> is a syntax tree, the actual
+%% run-time values corresponding to its subtrees may often be partially
+%% or completely unknown. Thus, if <code>Node</code> represents e.g.
+%% "<code>[... | Ns]</code>" (where <code>Ns</code> is a variable), then
+%% the function will return <code>false</code>, because it is not known
+%% whether <code>Ns</code> will be bound to a list at run-time. If
+%% <code>Node</code> instead represents e.g. "<code>[1, 2, 3]</code>" or
+%% "<code>[A | []]</code>", then the function will return
+%% <code>true</code>.</p>
+%%
+%% @see c_cons/2
+%% @see c_nil/0
+%% @see list_elements/1
+%% @see list_length/1
+
+-spec is_c_list(cerl()) -> boolean().
+
+is_c_list(#c_cons{tl = Tail}) ->
+ is_c_list(Tail);
+is_c_list(#c_literal{val = V}) ->
+ is_proper_list(V);
+is_c_list(_) ->
+ false.
+
+is_proper_list([_ | Tail]) ->
+ is_proper_list(Tail);
+is_proper_list([]) ->
+ true;
+is_proper_list(_) ->
+ false.
+
+%% @spec list_elements(c_cons() | c_literal()) -> [cerl()]
+%%
+%% @doc Returns the list of element subtrees of an abstract list.
+%% <code>Node</code> must represent a proper list. E.g., if
+%% <code>Node</code> represents "<code>[<em>X1</em>, <em>X2</em> |
+%% [<em>X3</em>, <em>X4</em> | []]</code>", then
+%% <code>list_elements(Node)</code> yields the list <code>[X1, X2, X3,
+%% X4]</code>.
+%%
+%% @see c_cons/2
+%% @see c_nil/0
+%% @see is_c_list/1
+%% @see list_length/1
+%% @see make_list/2
+
+-spec list_elements(c_cons() | c_literal()) -> [cerl()].
+
+list_elements(#c_cons{hd = Head, tl = Tail}) ->
+ [Head | list_elements(Tail)];
+list_elements(#c_literal{val = V}) ->
+ abstract_list(V).
+
+abstract_list([X | Xs]) ->
+ [abstract(X) | abstract_list(Xs)];
+abstract_list([]) ->
+ [].
+
+
+%% @spec list_length(Node::c_cons() | c_literal()) -> integer()
+%%
+%% @doc Returns the number of element subtrees of an abstract list.
+%% <code>Node</code> must represent a proper list. E.g., if
+%% <code>Node</code> represents "<code>[X1 | [X2, X3 | [X4, X5,
+%% X6]]]</code>", then <code>list_length(Node)</code> returns the
+%% integer 6.
+%%
+%% <p>Note: this is equivalent to
+%% <code>length(list_elements(Node))</code>, but potentially more
+%% efficient.</p>
+%%
+%% @see c_cons/2
+%% @see c_nil/0
+%% @see is_c_list/1
+%% @see list_elements/1
+
+-spec list_length(c_cons() | c_literal()) -> non_neg_integer().
+
+list_length(L) ->
+ list_length(L, 0).
+
+list_length(#c_cons{tl = Tail}, A) ->
+ list_length(Tail, A + 1);
+list_length(#c_literal{val = V}, A) ->
+ A + length(V).
+
+
+%% @spec make_list(List) -> Node
+%% @equiv make_list(List, none)
+
+-spec make_list([cerl()]) -> cerl().
+
+make_list(List) ->
+ ann_make_list([], List).
+
+
+%% @spec make_list(List::[cerl()], Tail) -> cerl()
+%%
+%% Tail = cerl() | none
+%%
+%% @doc Creates an abstract list from the elements in <code>List</code>
+%% and the optional <code>Tail</code>. If <code>Tail</code> is
+%% <code>none</code>, the result will represent a nil-terminated list,
+%% otherwise it represents "<code>[... | <em>Tail</em>]</code>".
+%%
+%% @see c_cons/2
+%% @see c_nil/0
+%% @see ann_make_list/3
+%% @see update_list/3
+%% @see list_elements/1
+
+-spec make_list([cerl()], cerl() | 'none') -> cerl().
+
+make_list(List, Tail) ->
+ ann_make_list([], List, Tail).
+
+
+%% @spec update_list(Old::cerl(), List::[cerl()]) -> cerl()
+%% @equiv update_list(Old, List, none)
+
+-spec update_list(cerl(), [cerl()]) -> cerl().
+
+update_list(Node, List) ->
+ ann_make_list(get_ann(Node), List).
+
+
+%% @spec update_list(Old::cerl(), List::[cerl()], Tail) -> cerl()
+%%
+%% Tail = cerl() | none
+%%
+%% @see make_list/2
+%% @see update_list/2
+
+-spec update_list(cerl(), [cerl()], cerl() | 'none') -> cerl().
+
+update_list(Node, List, Tail) ->
+ ann_make_list(get_ann(Node), List, Tail).
+
+
+%% @spec ann_make_list(As::anns(), List::[cerl()]) -> cerl()
+%% @equiv ann_make_list(As, List, none)
+
+-spec ann_make_list(anns(), [cerl()]) -> cerl().
+
+ann_make_list(As, List) ->
+ ann_make_list(As, List, none).
+
+
+%% @spec ann_make_list(As::anns(), List::[cerl()], Tail) -> cerl()
+%%
+%% Tail = cerl() | none
+%%
+%% @see make_list/2
+%% @see ann_make_list/2
+
+-spec ann_make_list(anns(), [cerl()], cerl() | 'none') -> cerl().
+
+ann_make_list(As, [H | T], Tail) ->
+ ann_c_cons(As, H, make_list(T, Tail)); % `c_cons' folds literals
+ann_make_list(As, [], none) ->
+ ann_c_nil(As);
+ann_make_list(_, [], Node) ->
+ Node.
+
+
+%% ---------------------------------------------------------------------
+%% maps
+
+%% @spec is_c_map(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% map constructor, otherwise <code>false</code>.
+
+-spec is_c_map(cerl()) -> boolean().
+
+is_c_map(#c_map{}) ->
+ true;
+is_c_map(#c_literal{val = V}) when is_map(V) ->
+ true;
+is_c_map(_) ->
+ false.
+
+-spec map_es(c_map() | c_literal()) -> [c_map_pair()].
+
+map_es(#c_literal{anno=As,val=M}) when is_map(M) ->
+ [ann_c_map_pair(As,
+ #c_literal{anno=As,val='assoc'},
+ #c_literal{anno=As,val=K},
+ #c_literal{anno=As,val=V}) || {K,V} <- maps:to_list(M)];
+map_es(#c_map{es = Es}) ->
+ Es.
+
+-spec map_arg(c_map() | c_literal()) -> c_map() | c_literal().
+
+map_arg(#c_literal{anno=As,val=M}) when is_map(M) ->
+ #c_literal{anno=As,val=#{}};
+map_arg(#c_map{arg=M}) ->
+ M.
+
+-spec c_map([c_map_pair()]) -> c_map().
+
+c_map(Pairs) ->
+ ann_c_map([], Pairs).
+
+-spec c_map_pattern([c_map_pair()]) -> c_map().
+
+c_map_pattern(Pairs) ->
+ #c_map{es=Pairs, is_pat=true}.
+
+-spec ann_c_map_pattern([term()], [c_map_pair()]) -> c_map().
+
+ann_c_map_pattern(As, Pairs) ->
+ #c_map{anno=As, es=Pairs, is_pat=true}.
+
+-spec is_c_map_empty(c_map() | c_literal()) -> boolean().
+
+is_c_map_empty(#c_map{ es=[] }) -> true;
+is_c_map_empty(#c_literal{val=M}) when is_map(M),map_size(M) =:= 0 -> true;
+is_c_map_empty(_) -> false.
+
+-spec is_c_map_pattern(c_map()) -> boolean().
+
+is_c_map_pattern(#c_map{is_pat=IsPat}) ->
+ IsPat.
+
+-spec ann_c_map([term()], [c_map_pair()]) -> c_map() | c_literal().
+
+ann_c_map(As, Es) ->
+ ann_c_map(As, #c_literal{val=#{}}, Es).
+
+-spec ann_c_map(anns(), c_map() | c_literal(), [c_map_pair()]) -> c_map() | c_literal().
+
+ann_c_map(As, #c_literal{val=M}, Es) when is_map(M) ->
+ fold_map_pairs(As,Es,M);
+ann_c_map(As, M, Es) ->
+ #c_map{arg=M, es=Es, anno=As}.
+
+fold_map_pairs(As,[],M) -> #c_literal{anno=As,val=M};
+%% M#{ K => V}
+fold_map_pairs(As,[#c_map_pair{op=#c_literal{val=assoc},key=Ck,val=Cv}=E|Es],M) ->
+ case is_lit_list([Ck,Cv]) of
+ true ->
+ [K,V] = lit_list_vals([Ck,Cv]),
+ fold_map_pairs(As,Es,maps:put(K,V,M));
+ false ->
+ #c_map{arg=#c_literal{val=M,anno=As}, es=[E|Es], anno=As}
+ end;
+%% M#{ K := V}
+fold_map_pairs(As,[#c_map_pair{op=#c_literal{val=exact},key=Ck,val=Cv}=E|Es],M) ->
+ case is_lit_list([Ck,Cv]) of
+ true ->
+ [K,V] = lit_list_vals([Ck,Cv]),
+ case maps:is_key(K,M) of
+ true -> fold_map_pairs(As,Es,maps:put(K,V,M));
+ false ->
+ #c_map{arg=#c_literal{val=M,anno=As}, es=[E|Es], anno=As }
+ end;
+ false ->
+ #c_map{arg=#c_literal{val=M,anno=As}, es=[E|Es], anno=As }
+ end.
+
+-spec update_c_map(c_map(), cerl(), [cerl()]) -> c_map() | c_literal().
+
+update_c_map(#c_map{is_pat=true}=Old, M, Es) ->
+ Old#c_map{arg=M, es=Es};
+update_c_map(#c_map{is_pat=false}=Old, M, Es) ->
+ ann_c_map(get_ann(Old), M, Es).
+
+map_pair_key(#c_map_pair{key=K}) -> K.
+map_pair_val(#c_map_pair{val=V}) -> V.
+map_pair_op(#c_map_pair{op=Op}) -> Op.
+
+-spec c_map_pair(cerl(), cerl()) -> c_map_pair().
+
+c_map_pair(Key,Val) ->
+ #c_map_pair{op=#c_literal{val=assoc},key=Key,val=Val}.
+
+-spec c_map_pair_exact(cerl(), cerl()) -> c_map_pair().
+
+c_map_pair_exact(Key,Val) ->
+ #c_map_pair{op=#c_literal{val=exact},key=Key,val=Val}.
+
+-spec ann_c_map_pair(anns(), cerl(), cerl(), cerl()) ->
+ c_map_pair().
+
+ann_c_map_pair(As,Op,K,V) ->
+ #c_map_pair{op = Op, key = K, val = V, anno = As}.
+
+update_c_map_pair(Old,Op,K,V) ->
+ #c_map_pair{op = Op, key = K, val = V, anno = get_ann(Old)}.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_tuple(Elements::[cerl()]) -> cerl()
+%%
+%% @doc Creates an abstract tuple. If <code>Elements</code> is
+%% <code>[E1, ..., En]</code>, the result represents
+%% "<code>{<em>E1</em>, ..., <em>En</em>}</code>". Note that if all
+%% nodes in <code>Elements</code> have type <code>literal</code>, or if
+%% <code>Elements</code> is empty, then the result will also have type
+%% <code>literal</code> and annotations on nodes in
+%% <code>Elements</code> are lost.
+%%
+%% <p>Recall that Erlang has distinct 1-tuples, i.e., <code>{X}</code>
+%% is always distinct from <code>X</code> itself.</p>
+%%
+%% @see ann_c_tuple/2
+%% @see update_c_tuple/2
+%% @see is_c_tuple/1
+%% @see tuple_es/1
+%% @see tuple_arity/1
+%% @see c_tuple_skel/1
+
+%% *Always* collapse literals.
+
+-spec c_tuple([cerl()]) -> c_tuple() | c_literal().
+
+c_tuple(Es) ->
+ case is_lit_list(Es) of
+ false ->
+ #c_tuple{es = Es};
+ true ->
+ #c_literal{val = list_to_tuple(lit_list_vals(Es))}
+ end.
+
+
+%% @spec ann_c_tuple(As::anns(), Elements::[cerl()]) -> cerl()
+%% @see c_tuple/1
+
+-spec ann_c_tuple(anns(), [cerl()]) -> c_tuple() | c_literal().
+
+ann_c_tuple(As, Es) ->
+ case is_lit_list(Es) of
+ false ->
+ #c_tuple{es = Es, anno = As};
+ true ->
+ #c_literal{val = list_to_tuple(lit_list_vals(Es)), anno = As}
+ end.
+
+
+%% @spec update_c_tuple(Old::cerl(), Elements::[cerl()]) -> cerl()
+%% @see c_tuple/1
+
+-spec update_c_tuple(c_tuple() | c_literal(), [cerl()]) -> c_tuple() | c_literal().
+
+update_c_tuple(Node, Es) ->
+ case is_lit_list(Es) of
+ false ->
+ #c_tuple{es = Es, anno = get_ann(Node)};
+ true ->
+ #c_literal{val = list_to_tuple(lit_list_vals(Es)),
+ anno = get_ann(Node)}
+ end.
+
+
+%% @spec c_tuple_skel(Elements::[cerl()]) -> cerl()
+%%
+%% @doc Creates an abstract tuple skeleton. Does not fold constant
+%% literals, i.e., the result always has type <code>tuple</code>,
+%% representing "<code>{<em>E1</em>, ..., <em>En</em>}</code>", if
+%% <code>Elements</code> is <code>[E1, ..., En]</code>.
+%%
+%% <p>This function is occasionally useful when it is necessary to have
+%% annotations on the subnodes of a tuple node, even when all the
+%% subnodes are constant literals. Note however that
+%% <code>is_literal/1</code> will yield <code>false</code> and
+%% <code>concrete/1</code> will fail if passed the result from this
+%% function.</p>
+%%
+%% <p><code>fold_literal/1</code> can be used to revert a node to the
+%% normal-form representation.</p>
+%%
+%% @see ann_c_tuple_skel/2
+%% @see update_c_tuple_skel/2
+%% @see c_tuple/1
+%% @see tuple_es/1
+%% @see is_c_tuple/1
+%% @see is_literal/1
+%% @see fold_literal/1
+%% @see concrete/1
+
+%% *Never* collapse literals.
+
+-spec c_tuple_skel([cerl()]) -> c_tuple().
+
+c_tuple_skel(Es) ->
+ #c_tuple{es = Es}.
+
+
+%% @spec ann_c_tuple_skel(As::anns(), Elements::[cerl()]) -> cerl()
+%% @see c_tuple_skel/1
+
+-spec ann_c_tuple_skel(anns(), [cerl()]) -> c_tuple().
+
+ann_c_tuple_skel(As, Es) ->
+ #c_tuple{es = Es, anno = As}.
+
+
+%% @spec update_c_tuple_skel(Old::cerl(), Elements::[cerl()]) -> cerl()
+%% @see c_tuple_skel/1
+
+-spec update_c_tuple_skel(c_tuple(), [cerl()]) -> c_tuple().
+
+update_c_tuple_skel(Old, Es) ->
+ #c_tuple{es = Es, anno = get_ann(Old)}.
+
+
+%% @spec is_c_tuple(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% tuple, otherwise <code>false</code>.
+%%
+%% @see c_tuple/1
+
+-spec is_c_tuple(cerl()) -> boolean().
+
+is_c_tuple(#c_tuple{}) ->
+ true;
+is_c_tuple(#c_literal{val = V}) when is_tuple(V) ->
+ true;
+is_c_tuple(_) ->
+ false.
+
+
+%% @spec tuple_es(cerl()) -> [cerl()]
+%%
+%% @doc Returns the list of element subtrees of an abstract tuple.
+%%
+%% @see c_tuple/1
+
+-spec tuple_es(c_tuple() | c_literal()) -> [cerl()].
+
+tuple_es(#c_tuple{es = Es}) ->
+ Es;
+tuple_es(#c_literal{val = V}) ->
+ make_lit_list(tuple_to_list(V)).
+
+
+%% @spec tuple_arity(Node::cerl()) -> integer()
+%%
+%% @doc Returns the number of element subtrees of an abstract tuple.
+%%
+%% <p>Note: this is equivalent to <code>length(tuple_es(Node))</code>,
+%% but potentially more efficient.</p>
+%%
+%% @see tuple_es/1
+%% @see c_tuple/1
+
+-spec tuple_arity(c_tuple() | c_literal()) -> non_neg_integer().
+
+tuple_arity(#c_tuple{es = Es}) ->
+ length(Es);
+tuple_arity(#c_literal{val = V}) when is_tuple(V) ->
+ tuple_size(V).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_var(Name::var_name()) -> cerl()
+%%
+%% var_name() = integer() | atom() | {atom(), arity()}
+%%
+%% @doc Creates an abstract variable. A variable is identified by its
+%% name, given by the <code>Name</code> parameter.
+%%
+%% <p>If a name is given by a single atom, it should either be a
+%% "simple" atom which does not need to be single-quoted in Erlang, or
+%% otherwise its print name should correspond to a proper Erlang
+%% variable, i.e., begin with an uppercase character or an
+%% underscore. Names on the form <code>{A, N}</code> represent
+%% function name variables "<code><em>A</em>/<em>N</em></code>"; these
+%% are special variables which may be bound only in the function
+%% definitions of a module or a <code>letrec</code>. They may not be
+%% bound in <code>let</code> expressions and cannot occur in clause
+%% patterns. The atom <code>A</code> in a function name may be any
+%% atom; the integer <code>N</code> must be nonnegative. The functions
+%% <code>c_fname/2</code> etc. are utilities for handling function
+%% name variables.</p>
+%%
+%% <p>When printing variable names, they must have the form of proper
+%% Core Erlang variables and function names. E.g., a name represented
+%% by an integer such as <code>42</code> could be formatted as
+%% "<code>_42</code>", an atom <code>'Xxx'</code> simply as
+%% "<code>Xxx</code>", and an atom <code>foo</code> as
+%% "<code>_foo</code>". However, one must assure that any two valid
+%% distinct names are never mapped to the same strings. Tuples such
+%% as <code>{foo, 2}</code> representing function names can simply by
+%% formatted as "<code>'foo'/2</code>", with no risk of conflicts.</p>
+%%
+%% @see ann_c_var/2
+%% @see update_c_var/2
+%% @see is_c_var/1
+%% @see var_name/1
+%% @see c_fname/2
+%% @see c_module/4
+%% @see c_letrec/2
+
+-spec c_var(var_name()) -> c_var().
+
+c_var(Name) ->
+ #c_var{name = Name}.
+
+
+%% @spec ann_c_var(As::anns(), Name::var_name()) -> c_var()
+%%
+%% @see c_var/1
+
+-spec ann_c_var(anns(), var_name()) -> c_var().
+
+ann_c_var(As, Name) ->
+ #c_var{name = Name, anno = As}.
+
+%% @spec update_c_var(Old::cerl(), Name::var_name()) -> c_var()
+%%
+%% @see c_var/1
+
+-spec update_c_var(c_var(), var_name()) -> c_var().
+
+update_c_var(Node, Name) ->
+ #c_var{name = Name, anno = get_ann(Node)}.
+
+
+%% @spec is_c_var(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% variable, otherwise <code>false</code>.
+%%
+%% @see c_var/1
+
+-spec is_c_var(cerl()) -> boolean().
+
+is_c_var(#c_var{}) ->
+ true;
+is_c_var(_) ->
+ false.
+
+
+%% @spec c_fname(Name::atom(), Arity::arity()) -> c_var()
+%% @equiv c_var({Name, Arity})
+%% @see fname_id/1
+%% @see fname_arity/1
+%% @see is_c_fname/1
+%% @see ann_c_fname/3
+%% @see update_c_fname/3
+
+-spec c_fname(atom(), arity()) -> c_var().
+
+c_fname(Atom, Arity) ->
+ c_var({Atom, Arity}).
+
+
+%% @spec ann_c_fname(As::anns(), Name::atom(), Arity::arity()) -> c_var()
+%%
+%% @equiv ann_c_var(As, {Atom, Arity})
+%% @see c_fname/2
+
+-spec ann_c_fname(anns(), atom(), arity()) -> c_var().
+
+ann_c_fname(As, Atom, Arity) ->
+ ann_c_var(As, {Atom, Arity}).
+
+
+%% @spec update_c_fname(Old::c_var(), Name::atom()) -> c_var()
+%% @doc Like <code>update_c_fname/3</code>, but takes the arity from
+%% <code>Node</code>.
+%% @see update_c_fname/3
+%% @see c_fname/2
+
+-spec update_c_fname(c_var(), atom()) -> c_var().
+
+update_c_fname(#c_var{name = {_, Arity}, anno = As}, Atom) ->
+ #c_var{name = {Atom, Arity}, anno = As}.
+
+
+%% @spec update_c_fname(Old::var(), Name::atom(), Arity::arity()) -> c_var()
+%%
+%% @equiv update_c_var(Old, {Atom, Arity})
+%% @see update_c_fname/2
+%% @see c_fname/2
+
+-spec update_c_fname(c_var(), atom(), arity()) -> c_var().
+
+update_c_fname(Node, Atom, Arity) ->
+ update_c_var(Node, {Atom, Arity}).
+
+
+%% @spec is_c_fname(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% function name variable, otherwise <code>false</code>.
+%%
+%% @see c_fname/2
+%% @see c_var/1
+%% @see var_name/1
+
+-spec is_c_fname(cerl()) -> boolean().
+
+is_c_fname(#c_var{name = {A, N}}) when is_atom(A), is_integer(N), N >= 0 ->
+ true;
+is_c_fname(_) ->
+ false.
+
+
+%% @spec var_name(c_var()) -> var_name()
+%%
+%% @doc Returns the name of an abstract variable.
+%%
+%% @see c_var/1
+
+-spec var_name(c_var()) -> var_name().
+
+var_name(Node) ->
+ Node#c_var.name.
+
+
+%% @spec fname_id(c_var()) -> atom()
+%%
+%% @doc Returns the identifier part of an abstract function name
+%% variable.
+%%
+%% @see fname_arity/1
+%% @see c_fname/2
+
+-spec fname_id(c_var()) -> atom().
+
+fname_id(#c_var{name={A,_}}) ->
+ A.
+
+
+%% @spec fname_arity(c_var()) -> arity()
+%%
+%% @doc Returns the arity part of an abstract function name variable.
+%%
+%% @see fname_id/1
+%% @see c_fname/2
+
+-spec fname_arity(c_var()) -> arity().
+
+fname_arity(#c_var{name={_,N}}) ->
+ N.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_values(Elements::[cerl()]) -> c_values()
+%%
+%% @doc Creates an abstract value list. If <code>Elements</code> is
+%% <code>[E1, ..., En]</code>, the result represents
+%% "<code>&lt;<em>E1</em>, ..., <em>En</em>&gt;</code>".
+%%
+%% @see ann_c_values/2
+%% @see update_c_values/2
+%% @see is_c_values/1
+%% @see values_es/1
+%% @see values_arity/1
+
+-spec c_values([cerl()]) -> c_values().
+
+c_values(Es) ->
+ #c_values{es = Es}.
+
+
+%% @spec ann_c_values(As::anns(), Elements::[cerl()]) -> c_values()
+%% @see c_values/1
+
+-spec ann_c_values(anns(), [cerl()]) -> c_values().
+
+ann_c_values(As, Es) ->
+ #c_values{es = Es, anno = As}.
+
+
+%% @spec update_c_values(Old::cerl(), Elements::[cerl()]) -> c_values()
+%% @see c_values/1
+
+-spec update_c_values(c_values(), [cerl()]) -> c_values().
+
+update_c_values(Node, Es) ->
+ #c_values{es = Es, anno = get_ann(Node)}.
+
+
+%% @spec is_c_values(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% value list; otherwise <code>false</code>.
+%%
+%% @see c_values/1
+
+-spec is_c_values(cerl()) -> boolean().
+
+is_c_values(#c_values{}) ->
+ true;
+is_c_values(_) ->
+ false.
+
+
+%% @spec values_es(c_values()) -> [cerl()]
+%%
+%% @doc Returns the list of element subtrees of an abstract value
+%% list.
+%%
+%% @see c_values/1
+%% @see values_arity/1
+
+-spec values_es(c_values()) -> [cerl()].
+
+values_es(Node) ->
+ Node#c_values.es.
+
+
+%% @spec values_arity(Node::c_values()) -> non_neg_integer()
+%%
+%% @doc Returns the number of element subtrees of an abstract value
+%% list.
+%%
+%% <p>Note: This is equivalent to
+%% <code>length(values_es(Node))</code>, but potentially more
+%% efficient.</p>
+%%
+%% @see c_values/1
+%% @see values_es/1
+
+-spec values_arity(c_values()) -> non_neg_integer().
+
+values_arity(Node) ->
+ length(values_es(Node)).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_binary(Segments::[c_bitstr()]) -> c_binary()
+%%
+%% @doc Creates an abstract binary-template. A binary object is a
+%% sequence of 8-bit bytes. It is specified by zero or more bit-string
+%% template <em>segments</em> of arbitrary lengths (in number of bits),
+%% such that the sum of the lengths is evenly divisible by 8. If
+%% <code>Segments</code> is <code>[S1, ..., Sn]</code>, the result
+%% represents "<code>#{<em>S1</em>, ..., <em>Sn</em>}#</code>". All the
+%% <code>Si</code> must have type <code>bitstr</code>.
+%%
+%% @see ann_c_binary/2
+%% @see update_c_binary/2
+%% @see is_c_binary/1
+%% @see binary_segments/1
+%% @see c_bitstr/5
+
+-spec c_binary([c_bitstr()]) -> c_binary().
+
+c_binary(Segments) ->
+ #c_binary{segments = Segments}.
+
+
+%% @spec ann_c_binary(As::anns(), Segments::[c_bitstr()]) -> c_binary()
+%% @see c_binary/1
+
+-spec ann_c_binary(anns(), [c_bitstr()]) -> c_binary().
+
+ann_c_binary(As, Segments) ->
+ #c_binary{segments = Segments, anno = As}.
+
+
+%% @spec update_c_binary(Old::cerl(), Segments::[c_bitstr()]) -> cerl()
+%% @see c_binary/1
+
+-spec update_c_binary(c_binary(), [c_bitstr()]) -> c_binary().
+
+update_c_binary(Node, Segments) ->
+ #c_binary{segments = Segments, anno = get_ann(Node)}.
+
+
+%% @spec is_c_binary(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% binary-template; otherwise <code>false</code>.
+%%
+%% @see c_binary/1
+
+-spec is_c_binary(cerl()) -> boolean().
+
+is_c_binary(#c_binary{}) ->
+ true;
+is_c_binary(_) ->
+ false.
+
+
+%% @spec binary_segments(cerl()) -> [c_bitstr()]
+%%
+%% @doc Returns the list of segment subtrees of an abstract
+%% binary-template.
+%%
+%% @see c_binary/1
+%% @see c_bitstr/5
+
+-spec binary_segments(c_binary()) -> [c_bitstr()].
+
+binary_segments(Node) ->
+ Node#c_binary.segments.
+
+
+%% @spec c_bitstr(Value::cerl(), Size::cerl(), Unit::cerl(),
+%% Type::cerl(), Flags::cerl()) -> c_bitstr()
+%%
+%% @doc Creates an abstract bit-string template. These can only occur as
+%% components of an abstract binary-template (see {@link c_binary/1}).
+%% The result represents "<code>#&lt;<em>Value</em>&gt;(<em>Size</em>,
+%% <em>Unit</em>, <em>Type</em>, <em>Flags</em>)</code>", where
+%% <code>Unit</code> must represent a positive integer constant,
+%% <code>Type</code> must represent a constant atom (one of
+%% <code>'integer'</code>, <code>'float'</code>, or
+%% <code>'binary'</code>), and <code>Flags</code> must represent a
+%% constant list <code>"[<em>F1</em>, ..., <em>Fn</em>]"</code> where
+%% all the <code>Fi</code> are atoms.
+%%
+%% @see c_binary/1
+%% @see ann_c_bitstr/6
+%% @see update_c_bitstr/6
+%% @see is_c_bitstr/1
+%% @see bitstr_val/1
+%% @see bitstr_size/1
+%% @see bitstr_unit/1
+%% @see bitstr_type/1
+%% @see bitstr_flags/1
+
+-spec c_bitstr(cerl(), cerl(), cerl(), cerl(), cerl()) -> c_bitstr().
+
+c_bitstr(Val, Size, Unit, Type, Flags) ->
+ #c_bitstr{val = Val, size = Size, unit = Unit, type = Type,
+ flags = Flags}.
+
+
+%% @spec c_bitstr(Value::cerl(), Size::cerl(), Type::cerl(),
+%% Flags::cerl()) -> c_bitstr()
+%% @equiv c_bitstr(Value, Size, abstract(1), Type, Flags)
+
+-spec c_bitstr(cerl(), cerl(), cerl(), cerl()) -> c_bitstr().
+
+c_bitstr(Val, Size, Type, Flags) ->
+ c_bitstr(Val, Size, abstract(1), Type, Flags).
+
+
+%% @spec c_bitstr(Value::cerl(), Type::cerl(),
+%% Flags::cerl()) -> c_bitstr()
+%% @equiv c_bitstr(Value, abstract(all), abstract(1), Type, Flags)
+
+-spec c_bitstr(cerl(), cerl(), cerl()) -> c_bitstr().
+
+c_bitstr(Val, Type, Flags) ->
+ c_bitstr(Val, abstract(all), abstract(1), Type, Flags).
+
+
+%% @spec ann_c_bitstr(As::anns(), Value::cerl(), Size::cerl(),
+%% Unit::cerl(), Type::cerl(), Flags::cerl()) -> cerl()
+%% @see c_bitstr/5
+%% @see ann_c_bitstr/5
+
+-spec ann_c_bitstr(anns(), cerl(), cerl(), cerl(), cerl(), cerl()) ->
+ c_bitstr().
+
+ann_c_bitstr(As, Val, Size, Unit, Type, Flags) ->
+ #c_bitstr{val = Val, size = Size, unit = Unit, type = Type,
+ flags = Flags, anno = As}.
+
+%% @spec ann_c_bitstr(As::anns(), Value::cerl(), Size::cerl(),
+%% Type::cerl(), Flags::cerl()) -> c_bitstr()
+%% @equiv ann_c_bitstr(As, Value, Size, abstract(1), Type, Flags)
+
+-spec ann_c_bitstr(anns(), cerl(), cerl(), cerl(), cerl()) -> c_bitstr().
+
+ann_c_bitstr(As, Value, Size, Type, Flags) ->
+ ann_c_bitstr(As, Value, Size, abstract(1), Type, Flags).
+
+
+%% @spec update_c_bitstr(Old::c_bitstr(), Value::cerl(), Size::cerl(),
+%% Unit::cerl(), Type::cerl(), Flags::cerl()) -> c_bitstr()
+%% @see c_bitstr/5
+%% @see update_c_bitstr/5
+
+-spec update_c_bitstr(c_bitstr(), cerl(), cerl(), cerl(), cerl(), cerl()) ->
+ c_bitstr().
+
+update_c_bitstr(Node, Val, Size, Unit, Type, Flags) ->
+ #c_bitstr{val = Val, size = Size, unit = Unit, type = Type,
+ flags = Flags, anno = get_ann(Node)}.
+
+
+%% @spec update_c_bitstr(Old::c_bitstr(), Value::cerl(), Size::cerl(),
+%% Type::cerl(), Flags::cerl()) -> c_bitstr()
+%% @equiv update_c_bitstr(Node, Value, Size, abstract(1), Type, Flags)
+
+-spec update_c_bitstr(c_bitstr(), cerl(), cerl(), cerl(), cerl()) -> c_bitstr().
+
+update_c_bitstr(Node, Value, Size, Type, Flags) ->
+ update_c_bitstr(Node, Value, Size, abstract(1), Type, Flags).
+
+%% @spec is_c_bitstr(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% bit-string template; otherwise <code>false</code>.
+%%
+%% @see c_bitstr/5
+
+-spec is_c_bitstr(cerl()) -> boolean().
+
+is_c_bitstr(#c_bitstr{}) ->
+ true;
+is_c_bitstr(_) ->
+ false.
+
+
+%% @spec bitstr_val(c_bitstr()) -> cerl()
+%%
+%% @doc Returns the value subtree of an abstract bit-string template.
+%%
+%% @see c_bitstr/5
+
+-spec bitstr_val(c_bitstr()) -> cerl().
+
+bitstr_val(Node) ->
+ Node#c_bitstr.val.
+
+
+%% @spec bitstr_size(c_bitstr()) -> cerl()
+%%
+%% @doc Returns the size subtree of an abstract bit-string template.
+%%
+%% @see c_bitstr/5
+
+-spec bitstr_size(c_bitstr()) -> cerl().
+
+bitstr_size(Node) ->
+ Node#c_bitstr.size.
+
+
+%% @spec bitstr_bitsize(c_bitstr()) -> any | all | utf | integer()
+%%
+%% @doc Returns the total size in bits of an abstract bit-string
+%% template. If the size field is an integer literal, the result is the
+%% product of the size and unit values; if the size field is the atom
+%% literal <code>all</code>, the atom <code>all</code> is returned.
+%% If the size is not a literal, the atom <code>any</code> is returned.
+%%
+%% @see c_bitstr/5
+
+-spec bitstr_bitsize(c_bitstr()) -> 'all' | 'any' | 'utf' | non_neg_integer().
+
+bitstr_bitsize(Node) ->
+ Size = Node#c_bitstr.size,
+ case is_literal(Size) of
+ true ->
+ case concrete(Size) of
+ all ->
+ all;
+ undefined ->
+ %% just an assertion below
+ "utf" ++ _ = atom_to_list(concrete(Node#c_bitstr.type)),
+ utf;
+ S when is_integer(S) ->
+ S * concrete(Node#c_bitstr.unit)
+ end;
+ false ->
+ any
+ end.
+
+
+%% @spec bitstr_unit(c_bitstr()) -> cerl()
+%%
+%% @doc Returns the unit subtree of an abstract bit-string template.
+%%
+%% @see c_bitstr/5
+
+-spec bitstr_unit(c_bitstr()) -> cerl().
+
+bitstr_unit(Node) ->
+ Node#c_bitstr.unit.
+
+
+%% @spec bitstr_type(c_bitstr()) -> cerl()
+%%
+%% @doc Returns the type subtree of an abstract bit-string template.
+%%
+%% @see c_bitstr/5
+
+-spec bitstr_type(c_bitstr()) -> cerl().
+
+bitstr_type(Node) ->
+ Node#c_bitstr.type.
+
+
+%% @spec bitstr_flags(c_bitstr()) -> cerl()
+%%
+%% @doc Returns the flags subtree of an abstract bit-string template.
+%%
+%% @see c_bitstr/5
+
+-spec bitstr_flags(c_bitstr()) -> cerl().
+
+bitstr_flags(Node) ->
+ Node#c_bitstr.flags.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_fun(Variables::[c_var()], Body::cerl()) -> c_fun()
+%%
+%% @doc Creates an abstract fun-expression. If <code>Variables</code>
+%% is <code>[V1, ..., Vn]</code>, the result represents "<code>fun
+%% (<em>V1</em>, ..., <em>Vn</em>) -> <em>Body</em></code>". All the
+%% <code>Vi</code> must have type <code>var</code>.
+%%
+%% @see ann_c_fun/3
+%% @see update_c_fun/3
+%% @see is_c_fun/1
+%% @see fun_vars/1
+%% @see fun_body/1
+%% @see fun_arity/1
+
+-spec c_fun([c_var()], cerl()) -> c_fun().
+
+c_fun(Variables, Body) ->
+ #c_fun{vars = Variables, body = Body}.
+
+
+%% @spec ann_c_fun(As::anns(), Variables::[c_var()], Body::cerl()) ->
+%% c_fun()
+%% @see c_fun/2
+
+-spec ann_c_fun(anns(), [c_var()], cerl()) -> c_fun().
+
+ann_c_fun(As, Variables, Body) ->
+ #c_fun{vars = Variables, body = Body, anno = As}.
+
+
+%% @spec update_c_fun(Old::c_fun(), Variables::[c_var()],
+%% Body::cerl()) -> c_fun()
+%% @see c_fun/2
+
+-spec update_c_fun(c_fun(), [c_var()], cerl()) -> c_fun().
+
+update_c_fun(Node, Variables, Body) ->
+ #c_fun{vars = Variables, body = Body, anno = get_ann(Node)}.
+
+
+%% @spec is_c_fun(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% fun-expression, otherwise <code>false</code>.
+%%
+%% @see c_fun/2
+
+-spec is_c_fun(cerl()) -> boolean().
+
+is_c_fun(#c_fun{}) ->
+ true; % Now this is fun!
+is_c_fun(_) ->
+ false.
+
+
+%% @spec fun_vars(c_fun()) -> [c_var()]
+%%
+%% @doc Returns the list of parameter subtrees of an abstract
+%% fun-expression.
+%%
+%% @see c_fun/2
+%% @see fun_arity/1
+
+-spec fun_vars(c_fun()) -> [c_var()].
+
+fun_vars(Node) ->
+ Node#c_fun.vars.
+
+
+%% @spec fun_body(c_fun()) -> cerl()
+%%
+%% @doc Returns the body subtree of an abstract fun-expression.
+%%
+%% @see c_fun/2
+
+-spec fun_body(c_fun()) -> cerl().
+
+fun_body(Node) ->
+ Node#c_fun.body.
+
+
+%% @spec fun_arity(Node::c_fun()) -> arity()
+%%
+%% @doc Returns the number of parameter subtrees of an abstract
+%% fun-expression.
+%%
+%% <p>Note: this is equivalent to <code>length(fun_vars(Node))</code>,
+%% but potentially more efficient.</p>
+%%
+%% @see c_fun/2
+%% @see fun_vars/1
+
+-spec fun_arity(c_fun()) -> arity().
+
+fun_arity(Node) ->
+ length(fun_vars(Node)).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_seq(Argument::cerl(), Body::cerl()) -> c_seq()
+%%
+%% @doc Creates an abstract sequencing expression. The result
+%% represents "<code>do <em>Argument</em> <em>Body</em></code>".
+%%
+%% @see ann_c_seq/3
+%% @see update_c_seq/3
+%% @see is_c_seq/1
+%% @see seq_arg/1
+%% @see seq_body/1
+
+-spec c_seq(cerl(), cerl()) -> c_seq().
+
+c_seq(Argument, Body) ->
+ #c_seq{arg = Argument, body = Body}.
+
+
+%% @spec ann_c_seq(As::anns(), Argument::cerl(), Body::cerl()) -> c_seq()
+%%
+%% @see c_seq/2
+
+-spec ann_c_seq(anns(), cerl(), cerl()) -> c_seq().
+
+ann_c_seq(As, Argument, Body) ->
+ #c_seq{arg = Argument, body = Body, anno = As}.
+
+
+%% @spec update_c_seq(Old::c_seq(), Argument::cerl(), Body::cerl()) ->
+%% c_seq()
+%% @see c_seq/2
+
+-spec update_c_seq(c_seq(), cerl(), cerl()) -> c_seq().
+
+update_c_seq(Node, Argument, Body) ->
+ #c_seq{arg = Argument, body = Body, anno = get_ann(Node)}.
+
+
+%% @spec is_c_seq(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% sequencing expression, otherwise <code>false</code>.
+%%
+%% @see c_seq/2
+
+-spec is_c_seq(cerl()) -> boolean().
+
+is_c_seq(#c_seq{}) ->
+ true;
+is_c_seq(_) ->
+ false.
+
+
+%% @spec seq_arg(c_seq()) -> cerl()
+%%
+%% @doc Returns the argument subtree of an abstract sequencing
+%% expression.
+%%
+%% @see c_seq/2
+
+-spec seq_arg(c_seq()) -> cerl().
+
+seq_arg(Node) ->
+ Node#c_seq.arg.
+
+
+%% @spec seq_body(c_seq()) -> cerl()
+%%
+%% @doc Returns the body subtree of an abstract sequencing expression.
+%%
+%% @see c_seq/2
+
+-spec seq_body(c_seq()) -> cerl().
+
+seq_body(Node) ->
+ Node#c_seq.body.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_let(Variables::[c_var()], Argument::cerl(), Body::cerl()) ->
+%% c_let()
+%%
+%% @doc Creates an abstract let-expression. If <code>Variables</code>
+%% is <code>[V1, ..., Vn]</code>, the result represents "<code>let
+%% &lt;<em>V1</em>, ..., <em>Vn</em>&gt; = <em>Argument</em> in
+%% <em>Body</em></code>". All the <code>Vi</code> must have type
+%% <code>var</code>.
+%%
+%% @see ann_c_let/4
+%% @see update_c_let/4
+%% @see is_c_let/1
+%% @see let_vars/1
+%% @see let_arg/1
+%% @see let_body/1
+%% @see let_arity/1
+
+-spec c_let([c_var()], cerl(), cerl()) -> c_let().
+
+c_let(Variables, Argument, Body) ->
+ #c_let{vars = Variables, arg = Argument, body = Body}.
+
+
+%% ann_c_let(As, Variables, Argument, Body) -> c_let()
+%% @see c_let/3
+
+-spec ann_c_let(anns(), [c_var()], cerl(), cerl()) -> c_let().
+
+ann_c_let(As, Variables, Argument, Body) ->
+ #c_let{vars = Variables, arg = Argument, body = Body, anno = As}.
+
+
+%% update_c_let(Old, Variables, Argument, Body) -> c_let()
+%% @see c_let/3
+
+-spec update_c_let(c_let(), [c_var()], cerl(), cerl()) -> c_let().
+
+update_c_let(Node, Variables, Argument, Body) ->
+ #c_let{vars = Variables, arg = Argument, body = Body,
+ anno = get_ann(Node)}.
+
+
+%% @spec is_c_let(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% let-expression, otherwise <code>false</code>.
+%%
+%% @see c_let/3
+
+-spec is_c_let(cerl()) -> boolean().
+
+is_c_let(#c_let{}) ->
+ true;
+is_c_let(_) ->
+ false.
+
+
+%% @spec let_vars(c_let()) -> [c_var()]
+%%
+%% @doc Returns the list of left-hand side variables of an abstract
+%% let-expression.
+%%
+%% @see c_let/3
+%% @see let_arity/1
+
+-spec let_vars(c_let()) -> [c_var()].
+
+let_vars(Node) ->
+ Node#c_let.vars.
+
+
+%% @spec let_arg(c_let()) -> cerl()
+%%
+%% @doc Returns the argument subtree of an abstract let-expression.
+%%
+%% @see c_let/3
+
+-spec let_arg(c_let()) -> cerl().
+
+let_arg(Node) ->
+ Node#c_let.arg.
+
+
+%% @spec let_body(c_let()) -> cerl()
+%%
+%% @doc Returns the body subtree of an abstract let-expression.
+%%
+%% @see c_let/3
+
+-spec let_body(c_let()) -> cerl().
+
+let_body(Node) ->
+ Node#c_let.body.
+
+
+%% @spec let_arity(Node::c_let()) -> non_neg_integer()
+%%
+%% @doc Returns the number of left-hand side variables of an abstract
+%% let-expression.
+%%
+%% <p>Note: this is equivalent to <code>length(let_vars(Node))</code>,
+%% but potentially more efficient.</p>
+%%
+%% @see c_let/3
+%% @see let_vars/1
+
+-spec let_arity(c_let()) -> non_neg_integer().
+
+let_arity(Node) ->
+ length(let_vars(Node)).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_letrec(Definitions::defs(), Body::cerl()) -> c_letrec()
+%%
+%% @doc Creates an abstract letrec-expression. If
+%% <code>Definitions</code> is <code>[{V1, F1}, ..., {Vn, Fn}]</code>,
+%% the result represents "<code>letrec <em>V1</em> = <em>F1</em>
+%% ... <em>Vn</em> = <em>Fn</em> in <em>Body</em></code>. All the
+%% <code>Vi</code> must have type <code>var</code> and represent
+%% function names. All the <code>Fi</code> must have type
+%% <code>'fun'</code>.
+%%
+%% @see ann_c_letrec/3
+%% @see update_c_letrec/3
+%% @see is_c_letrec/1
+%% @see letrec_defs/1
+%% @see letrec_body/1
+%% @see letrec_vars/1
+
+-spec c_letrec(defs(), cerl()) -> c_letrec().
+
+c_letrec(Defs, Body) ->
+ #c_letrec{defs = Defs, body = Body}.
+
+
+%% @spec ann_c_letrec(As::anns(), Definitions::defs(),
+%% Body::cerl()) -> c_letrec()
+%% @see c_letrec/2
+
+-spec ann_c_letrec(anns(), defs(), cerl()) -> c_letrec().
+
+ann_c_letrec(As, Defs, Body) ->
+ #c_letrec{defs = Defs, body = Body, anno = As}.
+
+
+%% @spec update_c_letrec(Old::c_letrec(), Definitions::defs(),
+%% Body::cerl()) -> c_letrec()
+%% @see c_letrec/2
+
+-spec update_c_letrec(c_letrec(), defs(), cerl()) -> c_letrec().
+
+update_c_letrec(Node, Defs, Body) ->
+ #c_letrec{defs = Defs, body = Body, anno = get_ann(Node)}.
+
+
+%% @spec is_c_letrec(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% letrec-expression, otherwise <code>false</code>.
+%%
+%% @see c_letrec/2
+
+-spec is_c_letrec(cerl()) -> boolean().
+
+is_c_letrec(#c_letrec{}) ->
+ true;
+is_c_letrec(_) ->
+ false.
+
+
+%% @spec letrec_defs(Node::c_letrec()) -> defs()
+%%
+%% @doc Returns the list of definitions of an abstract
+%% letrec-expression. If <code>Node</code> represents "<code>letrec
+%% <em>V1</em> = <em>F1</em> ... <em>Vn</em> = <em>Fn</em> in
+%% <em>Body</em></code>", the returned value is <code>[{V1, F1}, ...,
+%% {Vn, Fn}]</code>.
+%%
+%% @see c_letrec/2
+
+-spec letrec_defs(c_letrec()) -> defs().
+
+letrec_defs(Node) ->
+ Node#c_letrec.defs.
+
+
+%% @spec letrec_body(c_letrec()) -> cerl()
+%%
+%% @doc Returns the body subtree of an abstract letrec-expression.
+%%
+%% @see c_letrec/2
+
+-spec letrec_body(c_letrec()) -> cerl().
+
+letrec_body(Node) ->
+ Node#c_letrec.body.
+
+
+%% @spec letrec_vars(c_letrec()) -> [cerl()]
+%%
+%% @doc Returns the list of left-hand side function variable subtrees
+%% of a letrec-expression. If <code>Node</code> represents
+%% "<code>letrec <em>V1</em> = <em>F1</em> ... <em>Vn</em> =
+%% <em>Fn</em> in <em>Body</em></code>", the returned value is
+%% <code>[V1, ..., Vn]</code>.
+%%
+%% @see c_letrec/2
+
+-spec letrec_vars(c_letrec()) -> [cerl()].
+
+letrec_vars(Node) ->
+ [F || {F, _} <- letrec_defs(Node)].
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_case(Argument::cerl(), Clauses::[cerl()]) -> c_case()
+%%
+%% @doc Creates an abstract case-expression. If <code>Clauses</code>
+%% is <code>[C1, ..., Cn]</code>, the result represents "<code>case
+%% <em>Argument</em> of <em>C1</em> ... <em>Cn</em>
+%% end</code>". <code>Clauses</code> must not be empty.
+%%
+%% @see ann_c_case/3
+%% @see update_c_case/3
+%% @see is_c_case/1
+%% @see c_clause/3
+%% @see case_arg/1
+%% @see case_clauses/1
+%% @see case_arity/1
+
+-spec c_case(cerl(), [cerl()]) -> c_case().
+
+c_case(Expr, Clauses) ->
+ #c_case{arg = Expr, clauses = Clauses}.
+
+
+%% @spec ann_c_case(As::anns(), Argument::cerl(),
+%% Clauses::[cerl()]) -> c_case()
+%% @see c_case/2
+
+-spec ann_c_case(anns(), cerl(), [cerl()]) -> c_case().
+
+ann_c_case(As, Expr, Clauses) ->
+ #c_case{arg = Expr, clauses = Clauses, anno = As}.
+
+
+%% @spec update_c_case(Old::cerl(), Argument::cerl(),
+%% Clauses::[cerl()]) -> c_case()
+%% @see c_case/2
+
+-spec update_c_case(c_case(), cerl(), [cerl()]) -> c_case().
+
+update_c_case(Node, Expr, Clauses) ->
+ #c_case{arg = Expr, clauses = Clauses, anno = get_ann(Node)}.
+
+
+%% is_c_case(Node) -> boolean()
+%%
+%% Node = cerl()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% case-expression; otherwise <code>false</code>.
+%%
+%% @see c_case/2
+
+-spec is_c_case(cerl()) -> boolean().
+
+is_c_case(#c_case{}) ->
+ true;
+is_c_case(_) ->
+ false.
+
+
+%% @spec case_arg(c_case()) -> cerl()
+%%
+%% @doc Returns the argument subtree of an abstract case-expression.
+%%
+%% @see c_case/2
+
+-spec case_arg(c_case()) -> cerl().
+
+case_arg(Node) ->
+ Node#c_case.arg.
+
+
+%% @spec case_clauses(c_case()) -> [cerl()]
+%%
+%% @doc Returns the list of clause subtrees of an abstract
+%% case-expression.
+%%
+%% @see c_case/2
+%% @see case_arity/1
+
+-spec case_clauses(c_case()) -> [cerl()].
+
+case_clauses(Node) ->
+ Node#c_case.clauses.
+
+
+%% @spec case_arity(Node::c_case()) -> non_neg_integer()
+%%
+%% @doc Equivalent to
+%% <code>clause_arity(hd(case_clauses(Node)))</code>, but potentially
+%% more efficient.
+%%
+%% @see c_case/2
+%% @see case_clauses/1
+%% @see clause_arity/1
+
+-spec case_arity(c_case()) -> non_neg_integer().
+
+case_arity(Node) ->
+ clause_arity(hd(case_clauses(Node))).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_clause(Patterns::[cerl()], Body::cerl()) -> c_clause()
+%% @equiv c_clause(Patterns, c_atom(true), Body)
+%% @see c_atom/1
+
+-spec c_clause([cerl()], cerl()) -> c_clause().
+
+c_clause(Patterns, Body) ->
+ c_clause(Patterns, c_atom(true), Body).
+
+
+%% @spec c_clause(Patterns::[cerl()], Guard::cerl(), Body::cerl()) ->
+%% c_clause()
+%%
+%% @doc Creates an an abstract clause. If <code>Patterns</code> is
+%% <code>[P1, ..., Pn]</code>, the result represents
+%% "<code>&lt;<em>P1</em>, ..., <em>Pn</em>&gt; when <em>Guard</em> ->
+%% <em>Body</em></code>".
+%%
+%% @see c_clause/2
+%% @see ann_c_clause/4
+%% @see update_c_clause/4
+%% @see is_c_clause/1
+%% @see c_case/2
+%% @see c_receive/3
+%% @see clause_pats/1
+%% @see clause_guard/1
+%% @see clause_body/1
+%% @see clause_arity/1
+%% @see clause_vars/1
+
+-spec c_clause([cerl()], cerl(), cerl()) -> c_clause().
+
+c_clause(Patterns, Guard, Body) ->
+ #c_clause{pats = Patterns, guard = Guard, body = Body}.
+
+
+%% @spec ann_c_clause(As::anns(), Patterns::[cerl()],
+%% Body::cerl()) -> c_clause()
+%% @equiv ann_c_clause(As, Patterns, c_atom(true), Body)
+%% @see c_clause/3
+
+-spec ann_c_clause(anns(), [cerl()], cerl()) -> c_clause().
+
+ann_c_clause(As, Patterns, Body) ->
+ ann_c_clause(As, Patterns, c_atom(true), Body).
+
+
+%% @spec ann_c_clause(As::anns(), Patterns::[cerl()], Guard::cerl(),
+%% Body::cerl()) -> c_clause()
+%% @see ann_c_clause/3
+%% @see c_clause/3
+
+-spec ann_c_clause(anns(), [cerl()], cerl(), cerl()) -> c_clause().
+
+ann_c_clause(As, Patterns, Guard, Body) ->
+ #c_clause{pats = Patterns, guard = Guard, body = Body, anno = As}.
+
+
+%% @spec update_c_clause(Old::c_clause(), Patterns::[cerl()],
+%% Guard::cerl(), Body::cerl()) -> c_clause()
+%% @see c_clause/3
+
+-spec update_c_clause(c_clause(), [cerl()], cerl(), cerl()) -> c_clause().
+
+update_c_clause(Node, Patterns, Guard, Body) ->
+ #c_clause{pats = Patterns, guard = Guard, body = Body,
+ anno = get_ann(Node)}.
+
+
+%% @spec is_c_clause(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% clause, otherwise <code>false</code>.
+%%
+%% @see c_clause/3
+
+-spec is_c_clause(cerl()) -> boolean().
+
+is_c_clause(#c_clause{}) ->
+ true;
+is_c_clause(_) ->
+ false.
+
+
+%% @spec clause_pats(c_clause()) -> [cerl()]
+%%
+%% @doc Returns the list of pattern subtrees of an abstract clause.
+%%
+%% @see c_clause/3
+%% @see clause_arity/1
+
+-spec clause_pats(c_clause()) -> [cerl()].
+
+clause_pats(Node) ->
+ Node#c_clause.pats.
+
+
+%% @spec clause_guard(c_clause()) -> cerl()
+%%
+%% @doc Returns the guard subtree of an abstract clause.
+%%
+%% @see c_clause/3
+
+-spec clause_guard(c_clause()) -> cerl().
+
+clause_guard(Node) ->
+ Node#c_clause.guard.
+
+
+%% @spec clause_body(c_clause()) -> cerl()
+%%
+%% @doc Returns the body subtree of an abstract clause.
+%%
+%% @see c_clause/3
+
+-spec clause_body(c_clause()) -> cerl().
+
+clause_body(Node) ->
+ Node#c_clause.body.
+
+
+%% @spec clause_arity(Node::c_clause()) -> non_neg_integer()
+%%
+%% @doc Returns the number of pattern subtrees of an abstract clause.
+%%
+%% <p>Note: this is equivalent to
+%% <code>length(clause_pats(Node))</code>, but potentially more
+%% efficient.</p>
+%%
+%% @see c_clause/3
+%% @see clause_pats/1
+
+-spec clause_arity(c_clause()) -> non_neg_integer().
+
+clause_arity(Node) ->
+ length(clause_pats(Node)).
+
+
+%% @spec clause_vars(c_clause()) -> [cerl()]
+%%
+%% @doc Returns the list of all abstract variables in the patterns of
+%% an abstract clause. The order of listing is not defined.
+%%
+%% @see c_clause/3
+%% @see pat_list_vars/1
+
+-spec clause_vars(c_clause()) -> [cerl()].
+
+clause_vars(Clause) ->
+ pat_list_vars(clause_pats(Clause)).
+
+
+%% @spec pat_vars(Pattern::cerl()) -> [cerl()]
+%%
+%% @doc Returns the list of all abstract variables in a pattern. An
+%% exception is thrown if <code>Node</code> does not represent a
+%% well-formed Core Erlang clause pattern. The order of listing is not
+%% defined.
+%%
+%% @see pat_list_vars/1
+%% @see clause_vars/1
+
+-spec pat_vars(cerl()) -> [cerl()].
+
+pat_vars(Node) ->
+ pat_vars(Node, []).
+
+pat_vars(Node, Vs) ->
+ case type(Node) of
+ var ->
+ [Node | Vs];
+ literal ->
+ Vs;
+ cons ->
+ pat_vars(cons_hd(Node), pat_vars(cons_tl(Node), Vs));
+ tuple ->
+ pat_list_vars(tuple_es(Node), Vs);
+ map ->
+ pat_list_vars(map_es(Node), Vs);
+ map_pair ->
+ %% map_pair_key is not a pattern var, excluded
+ pat_list_vars([map_pair_op(Node),map_pair_val(Node)],Vs);
+ binary ->
+ pat_list_vars(binary_segments(Node), Vs);
+ bitstr ->
+ %% bitstr_size is not a pattern var, excluded
+ pat_vars(bitstr_val(Node), Vs);
+ alias ->
+ pat_vars(alias_pat(Node), [alias_var(Node) | Vs])
+ end.
+
+
+%% @spec pat_list_vars(Patterns::[cerl()]) -> [cerl()]
+%%
+%% @doc Returns the list of all abstract variables in the given
+%% patterns. An exception is thrown if some element in
+%% <code>Patterns</code> does not represent a well-formed Core Erlang
+%% clause pattern. The order of listing is not defined.
+%%
+%% @see pat_vars/1
+%% @see clause_vars/1
+
+-spec pat_list_vars([cerl()]) -> [cerl()].
+
+pat_list_vars(Ps) ->
+ pat_list_vars(Ps, []).
+
+pat_list_vars([P | Ps], Vs) ->
+ pat_list_vars(Ps, pat_vars(P, Vs));
+pat_list_vars([], Vs) ->
+ Vs.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_alias(Variable::c_var(), Pattern::cerl()) -> c_alias()
+%%
+%% @doc Creates an abstract pattern alias. The result represents
+%% "<code><em>Variable</em> = <em>Pattern</em></code>".
+%%
+%% @see ann_c_alias/3
+%% @see update_c_alias/3
+%% @see is_c_alias/1
+%% @see alias_var/1
+%% @see alias_pat/1
+%% @see c_clause/3
+
+-spec c_alias(c_var(), cerl()) -> c_alias().
+
+c_alias(Var, Pattern) ->
+ #c_alias{var = Var, pat = Pattern}.
+
+
+%% @spec ann_c_alias(As::anns(), Variable::c_var(),
+%% Pattern::cerl()) -> c_alias()
+%% @see c_alias/2
+
+-spec ann_c_alias(anns(), c_var(), cerl()) -> c_alias().
+
+ann_c_alias(As, Var, Pattern) ->
+ #c_alias{var = Var, pat = Pattern, anno = As}.
+
+
+%% @spec update_c_alias(Old::cerl(), Variable::c_var(),
+%% Pattern::cerl()) -> c_alias()
+%% @see c_alias/2
+
+-spec update_c_alias(c_alias(), c_var(), cerl()) -> c_alias().
+
+update_c_alias(Node, Var, Pattern) ->
+ #c_alias{var = Var, pat = Pattern, anno = get_ann(Node)}.
+
+
+%% @spec is_c_alias(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% pattern alias, otherwise <code>false</code>.
+%%
+%% @see c_alias/2
+
+-spec is_c_alias(cerl()) -> boolean().
+
+is_c_alias(#c_alias{}) ->
+ true;
+is_c_alias(_) ->
+ false.
+
+
+%% @spec alias_var(c_alias()) -> c_var()
+%%
+%% @doc Returns the variable subtree of an abstract pattern alias.
+%%
+%% @see c_alias/2
+
+-spec alias_var(c_alias()) -> c_var().
+
+alias_var(Node) ->
+ Node#c_alias.var.
+
+
+%% @spec alias_pat(c_alias()) -> cerl()
+%%
+%% @doc Returns the pattern subtree of an abstract pattern alias.
+%%
+%% @see c_alias/2
+
+-spec alias_pat(c_alias()) -> cerl().
+
+alias_pat(Node) ->
+ Node#c_alias.pat.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_receive(Clauses::[cerl()]) -> c_receive()
+%% @equiv c_receive(Clauses, c_atom(infinity), c_atom(true))
+%% @see c_atom/1
+
+-spec c_receive([cerl()]) -> c_receive().
+
+c_receive(Clauses) ->
+ c_receive(Clauses, c_atom(infinity), c_atom(true)).
+
+
+%% @spec c_receive(Clauses::[cerl()], Timeout::cerl(),
+%% Action::cerl()) -> c_receive()
+%%
+%% @doc Creates an abstract receive-expression. If
+%% <code>Clauses</code> is <code>[C1, ..., Cn]</code>, the result
+%% represents "<code>receive <em>C1</em> ... <em>Cn</em> after
+%% <em>Timeout</em> -> <em>Action</em> end</code>".
+%%
+%% @see c_receive/1
+%% @see ann_c_receive/4
+%% @see update_c_receive/4
+%% @see is_c_receive/1
+%% @see receive_clauses/1
+%% @see receive_timeout/1
+%% @see receive_action/1
+
+-spec c_receive([cerl()], cerl(), cerl()) -> c_receive().
+
+c_receive(Clauses, Timeout, Action) ->
+ #c_receive{clauses = Clauses, timeout = Timeout, action = Action}.
+
+
+%% @spec ann_c_receive(As::anns(), Clauses::[cerl()]) -> c_receive()
+%% @equiv ann_c_receive(As, Clauses, c_atom(infinity), c_atom(true))
+%% @see c_receive/3
+%% @see c_atom/1
+
+-spec ann_c_receive(anns(), [cerl()]) -> c_receive().
+
+ann_c_receive(As, Clauses) ->
+ ann_c_receive(As, Clauses, c_atom(infinity), c_atom(true)).
+
+
+%% @spec ann_c_receive(As::anns(), Clauses::[cerl()],
+%% Timeout::cerl(), Action::cerl()) -> c_receive()
+%% @see ann_c_receive/2
+%% @see c_receive/3
+
+-spec ann_c_receive(anns(), [cerl()], cerl(), cerl()) -> c_receive().
+
+ann_c_receive(As, Clauses, Timeout, Action) ->
+ #c_receive{clauses = Clauses, timeout = Timeout, action = Action,
+ anno = As}.
+
+
+%% @spec update_c_receive(Old::cerl(), Clauses::[cerl()],
+%% Timeout::cerl(), Action::cerl()) -> c_receive()
+%% @see c_receive/3
+
+-spec update_c_receive(c_receive(), [cerl()], cerl(), cerl()) -> c_receive().
+
+update_c_receive(Node, Clauses, Timeout, Action) ->
+ #c_receive{clauses = Clauses, timeout = Timeout, action = Action,
+ anno = get_ann(Node)}.
+
+
+%% @spec is_c_receive(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% receive-expression, otherwise <code>false</code>.
+%%
+%% @see c_receive/3
+
+-spec is_c_receive(cerl()) -> boolean().
+
+is_c_receive(#c_receive{}) ->
+ true;
+is_c_receive(_) ->
+ false.
+
+
+%% @spec receive_clauses(c_receive()) -> [cerl()]
+%%
+%% @doc Returns the list of clause subtrees of an abstract
+%% receive-expression.
+%%
+%% @see c_receive/3
+
+-spec receive_clauses(c_receive()) -> [cerl()].
+
+receive_clauses(Node) ->
+ Node#c_receive.clauses.
+
+
+%% @spec receive_timeout(c_receive()) -> cerl()
+%%
+%% @doc Returns the timeout subtree of an abstract receive-expression.
+%%
+%% @see c_receive/3
+
+-spec receive_timeout(c_receive()) -> cerl().
+
+receive_timeout(Node) ->
+ Node#c_receive.timeout.
+
+
+%% @spec receive_action(c_receive()) -> cerl()
+%%
+%% @doc Returns the action subtree of an abstract receive-expression.
+%%
+%% @see c_receive/3
+
+-spec receive_action(c_receive()) -> cerl().
+
+receive_action(Node) ->
+ Node#c_receive.action.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_apply(Operator::c_var(), Arguments::[cerl()]) -> c_apply()
+%%
+%% @doc Creates an abstract function application. If
+%% <code>Arguments</code> is <code>[A1, ..., An]</code>, the result
+%% represents "<code>apply <em>Operator</em>(<em>A1</em>, ...,
+%% <em>An</em>)</code>".
+%%
+%% @see ann_c_apply/3
+%% @see update_c_apply/3
+%% @see is_c_apply/1
+%% @see apply_op/1
+%% @see apply_args/1
+%% @see apply_arity/1
+%% @see c_call/3
+%% @see c_primop/2
+
+-spec c_apply(c_var(), [cerl()]) -> c_apply().
+
+c_apply(Operator, Arguments) ->
+ #c_apply{op = Operator, args = Arguments}.
+
+
+%% @spec ann_c_apply(As::anns(), Operator::c_var(),
+%% Arguments::[cerl()]) -> c_apply()
+%% @see c_apply/2
+
+-spec ann_c_apply(anns(), c_var(), [cerl()]) -> c_apply().
+
+ann_c_apply(As, Operator, Arguments) ->
+ #c_apply{op = Operator, args = Arguments, anno = As}.
+
+
+%% @spec update_c_apply(Old::c_apply(), Operator::cerl(),
+%% Arguments::[cerl()]) -> c_apply()
+%% @see c_apply/2
+
+-spec update_c_apply(c_apply(), c_var(), [cerl()]) -> c_apply().
+
+update_c_apply(Node, Operator, Arguments) ->
+ #c_apply{op = Operator, args = Arguments, anno = get_ann(Node)}.
+
+
+%% @spec is_c_apply(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% function application, otherwise <code>false</code>.
+%%
+%% @see c_apply/2
+
+-spec is_c_apply(cerl()) -> boolean().
+
+is_c_apply(#c_apply{}) ->
+ true;
+is_c_apply(_) ->
+ false.
+
+
+%% @spec apply_op(c_apply()) -> c_var()
+%%
+%% @doc Returns the operator subtree of an abstract function
+%% application.
+%%
+%% @see c_apply/2
+
+-spec apply_op(c_apply()) -> c_var().
+
+apply_op(Node) ->
+ Node#c_apply.op.
+
+
+%% @spec apply_args(c_apply()) -> [cerl()]
+%%
+%% @doc Returns the list of argument subtrees of an abstract function
+%% application.
+%%
+%% @see c_apply/2
+%% @see apply_arity/1
+
+-spec apply_args(c_apply()) -> [cerl()].
+
+apply_args(Node) ->
+ Node#c_apply.args.
+
+
+%% @spec apply_arity(Node::c_apply()) -> arity()
+%%
+%% @doc Returns the number of argument subtrees of an abstract
+%% function application.
+%%
+%% <p>Note: this is equivalent to
+%% <code>length(apply_args(Node))</code>, but potentially more
+%% efficient.</p>
+%%
+%% @see c_apply/2
+%% @see apply_args/1
+
+-spec apply_arity(c_apply()) -> arity().
+
+apply_arity(Node) ->
+ length(apply_args(Node)).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_call(Module::cerl(), Name::cerl(), Arguments::[cerl()]) ->
+%% c_call()
+%%
+%% @doc Creates an abstract inter-module call. If
+%% <code>Arguments</code> is <code>[A1, ..., An]</code>, the result
+%% represents "<code>call <em>Module</em>:<em>Name</em>(<em>A1</em>,
+%% ..., <em>An</em>)</code>".
+%%
+%% @see ann_c_call/4
+%% @see update_c_call/4
+%% @see is_c_call/1
+%% @see call_module/1
+%% @see call_name/1
+%% @see call_args/1
+%% @see call_arity/1
+%% @see c_apply/2
+%% @see c_primop/2
+
+-spec c_call(cerl(), cerl(), [cerl()]) -> c_call().
+
+c_call(Module, Name, Arguments) ->
+ #c_call{module = Module, name = Name, args = Arguments}.
+
+
+%% @spec ann_c_call(As::anns(), Module::cerl(), Name::cerl(),
+%% Arguments::[cerl()]) -> c_call()
+%% @see c_call/3
+
+-spec ann_c_call(anns(), cerl(), cerl(), [cerl()]) -> c_call().
+
+ann_c_call(As, Module, Name, Arguments) ->
+ #c_call{module = Module, name = Name, args = Arguments, anno = As}.
+
+
+%% @spec update_c_call(Old::cerl(), Module::cerl(), Name::cerl(),
+%% Arguments::[cerl()]) -> c_call()
+%% @see c_call/3
+
+-spec update_c_call(cerl(), cerl(), cerl(), [cerl()]) -> c_call().
+
+update_c_call(Node, Module, Name, Arguments) ->
+ #c_call{module = Module, name = Name, args = Arguments,
+ anno = get_ann(Node)}.
+
+
+%% @spec is_c_call(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% inter-module call expression; otherwise <code>false</code>.
+%%
+%% @see c_call/3
+
+-spec is_c_call(cerl()) -> boolean().
+
+is_c_call(#c_call{}) ->
+ true;
+is_c_call(_) ->
+ false.
+
+
+%% @spec call_module(c_call()) -> cerl()
+%%
+%% @doc Returns the module subtree of an abstract inter-module call.
+%%
+%% @see c_call/3
+
+-spec call_module(c_call()) -> cerl().
+
+call_module(Node) ->
+ Node#c_call.module.
+
+
+%% @spec call_name(c_call()) -> cerl()
+%%
+%% @doc Returns the name subtree of an abstract inter-module call.
+%%
+%% @see c_call/3
+
+-spec call_name(c_call()) -> cerl().
+
+call_name(Node) ->
+ Node#c_call.name.
+
+
+%% @spec call_args(c_call()) -> [cerl()]
+%%
+%% @doc Returns the list of argument subtrees of an abstract
+%% inter-module call.
+%%
+%% @see c_call/3
+%% @see call_arity/1
+
+-spec call_args(c_call()) -> [cerl()].
+
+call_args(Node) ->
+ Node#c_call.args.
+
+
+%% @spec call_arity(Node::c_call()) -> arity()
+%%
+%% @doc Returns the number of argument subtrees of an abstract
+%% inter-module call.
+%%
+%% <p>Note: this is equivalent to
+%% <code>length(call_args(Node))</code>, but potentially more
+%% efficient.</p>
+%%
+%% @see c_call/3
+%% @see call_args/1
+
+-spec call_arity(c_call()) -> arity().
+
+call_arity(Node) ->
+ length(call_args(Node)).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_primop(Name::c_literal(), Arguments::[cerl()]) -> c_primop()
+%%
+%% @doc Creates an abstract primitive operation call. If
+%% <code>Arguments</code> is <code>[A1, ..., An]</code>, the result
+%% represents "<code>primop <em>Name</em>(<em>A1</em>, ...,
+%% <em>An</em>)</code>". <code>Name</code> must be an atom literal.
+%%
+%% @see ann_c_primop/3
+%% @see update_c_primop/3
+%% @see is_c_primop/1
+%% @see primop_name/1
+%% @see primop_args/1
+%% @see primop_arity/1
+%% @see c_apply/2
+%% @see c_call/3
+
+-spec c_primop(c_literal(), [cerl()]) -> c_primop().
+
+c_primop(Name, Arguments) ->
+ #c_primop{name = Name, args = Arguments}.
+
+
+%% @spec ann_c_primop(As::anns(), Name::c_literal(),
+%% Arguments::[cerl()]) -> c_primop()
+%% @see c_primop/2
+
+-spec ann_c_primop(anns(), c_literal(), [cerl()]) -> c_primop().
+
+ann_c_primop(As, Name, Arguments) ->
+ #c_primop{name = Name, args = Arguments, anno = As}.
+
+
+%% @spec update_c_primop(Old::cerl(), Name::c_literal(),
+%% Arguments::[cerl()]) -> c_primop()
+%% @see c_primop/2
+
+-spec update_c_primop(cerl(), c_literal(), [cerl()]) -> c_primop().
+
+update_c_primop(Node, Name, Arguments) ->
+ #c_primop{name = Name, args = Arguments, anno = get_ann(Node)}.
+
+
+%% @spec is_c_primop(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% primitive operation call, otherwise <code>false</code>.
+%%
+%% @see c_primop/2
+
+-spec is_c_primop(cerl()) -> boolean().
+
+is_c_primop(#c_primop{}) ->
+ true;
+is_c_primop(_) ->
+ false.
+
+
+%% @spec primop_name(c_primop()) -> c_literal()
+%%
+%% @doc Returns the name subtree of an abstract primitive operation
+%% call.
+%%
+%% @see c_primop/2
+
+-spec primop_name(c_primop()) -> c_literal().
+
+primop_name(Node) ->
+ Node#c_primop.name.
+
+
+%% @spec primop_args(c_primop()) -> [cerl()]
+%%
+%% @doc Returns the list of argument subtrees of an abstract primitive
+%% operation call.
+%%
+%% @see c_primop/2
+%% @see primop_arity/1
+
+-spec primop_args(c_primop()) -> [cerl()].
+
+primop_args(Node) ->
+ Node#c_primop.args.
+
+
+%% @spec primop_arity(Node::c_primop()) -> arity()
+%%
+%% @doc Returns the number of argument subtrees of an abstract
+%% primitive operation call.
+%%
+%% <p>Note: this is equivalent to
+%% <code>length(primop_args(Node))</code>, but potentially more
+%% efficient.</p>
+%%
+%% @see c_primop/2
+%% @see primop_args/1
+
+-spec primop_arity(c_primop()) -> arity().
+
+primop_arity(Node) ->
+ length(primop_args(Node)).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_try(Argument::cerl(), Variables::[c_var()], Body::cerl(),
+%% ExceptionVars::[c_var()], Handler::cerl()) -> c_try()
+%%
+%% @doc Creates an abstract try-expression. If <code>Variables</code> is
+%% <code>[V1, ..., Vn]</code> and <code>ExceptionVars</code> is
+%% <code>[X1, ..., Xm]</code>, the result represents "<code>try
+%% <em>Argument</em> of &lt;<em>V1</em>, ..., <em>Vn</em>&gt; ->
+%% <em>Body</em> catch &lt;<em>X1</em>, ..., <em>Xm</em>&gt; ->
+%% <em>Handler</em></code>". All the <code>Vi</code> and <code>Xi</code>
+%% must have type <code>var</code>.
+%%
+%% @see ann_c_try/6
+%% @see update_c_try/6
+%% @see is_c_try/1
+%% @see try_arg/1
+%% @see try_vars/1
+%% @see try_body/1
+%% @see c_catch/1
+
+-spec c_try(cerl(), [c_var()], cerl(), [c_var()], cerl()) -> c_try().
+
+c_try(Expr, Vs, Body, Evs, Handler) ->
+ #c_try{arg = Expr, vars = Vs, body = Body,
+ evars = Evs, handler = Handler}.
+
+
+%% @spec ann_c_try(As::[term()], Expression::cerl(),
+%% Variables::[c_var()], Body::cerl(),
+%% EVars::[c_var()], Handler::cerl()) -> c_try()
+%% @see c_try/5
+
+-spec ann_c_try(anns(), cerl(), [c_var()], cerl(), [c_var()], cerl()) ->
+ c_try().
+
+ann_c_try(As, Expr, Vs, Body, Evs, Handler) ->
+ #c_try{arg = Expr, vars = Vs, body = Body,
+ evars = Evs, handler = Handler, anno = As}.
+
+
+%% @spec update_c_try(Old::c_try(), Expression::cerl(),
+%% Variables::[c_var()], Body::cerl(),
+%% EVars::[c_var()], Handler::cerl()) -> cerl()
+%% @see c_try/5
+
+-spec update_c_try(c_try(), cerl(), [c_var()], cerl(), [c_var()], cerl()) ->
+ c_try().
+
+update_c_try(Node, Expr, Vs, Body, Evs, Handler) ->
+ #c_try{arg = Expr, vars = Vs, body = Body,
+ evars = Evs, handler = Handler, anno = get_ann(Node)}.
+
+
+%% @spec is_c_try(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% try-expression, otherwise <code>false</code>.
+%%
+%% @see c_try/5
+
+-spec is_c_try(cerl()) -> boolean().
+
+is_c_try(#c_try{}) ->
+ true;
+is_c_try(_) ->
+ false.
+
+
+%% @spec try_arg(c_try()) -> cerl()
+%%
+%% @doc Returns the expression subtree of an abstract try-expression.
+%%
+%% @see c_try/5
+
+-spec try_arg(c_try()) -> cerl().
+
+try_arg(Node) ->
+ Node#c_try.arg.
+
+
+%% @spec try_vars(c_try()) -> [c_var()]
+%%
+%% @doc Returns the list of success variable subtrees of an abstract
+%% try-expression.
+%%
+%% @see c_try/5
+
+-spec try_vars(c_try()) -> [c_var()].
+
+try_vars(Node) ->
+ Node#c_try.vars.
+
+
+%% @spec try_body(c_try()) -> cerl()
+%%
+%% @doc Returns the success body subtree of an abstract try-expression.
+%%
+%% @see c_try/5
+
+-spec try_body(c_try()) -> cerl().
+
+try_body(Node) ->
+ Node#c_try.body.
+
+
+%% @spec try_evars(c_try()) -> [c_var()]
+%%
+%% @doc Returns the list of exception variable subtrees of an abstract
+%% try-expression.
+%%
+%% @see c_try/5
+
+-spec try_evars(c_try()) -> [c_var()].
+
+try_evars(Node) ->
+ Node#c_try.evars.
+
+
+%% @spec try_handler(c_try()) -> cerl()
+%%
+%% @doc Returns the exception body subtree of an abstract
+%% try-expression.
+%%
+%% @see c_try/5
+
+-spec try_handler(c_try()) -> cerl().
+
+try_handler(Node) ->
+ Node#c_try.handler.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec c_catch(Body::cerl()) -> c_catch()
+%%
+%% @doc Creates an abstract catch-expression. The result represents
+%% "<code>catch <em>Body</em></code>".
+%%
+%% <p>Note: catch-expressions can be rewritten as try-expressions, and
+%% will eventually be removed from Core Erlang.</p>
+%%
+%% @see ann_c_catch/2
+%% @see update_c_catch/2
+%% @see is_c_catch/1
+%% @see catch_body/1
+%% @see c_try/5
+
+-spec c_catch(cerl()) -> c_catch().
+
+c_catch(Body) ->
+ #c_catch{body = Body}.
+
+
+%% @spec ann_c_catch(As::anns(), Body::cerl()) -> c_catch()
+%% @see c_catch/1
+
+-spec ann_c_catch(anns(), cerl()) -> c_catch().
+
+ann_c_catch(As, Body) ->
+ #c_catch{body = Body, anno = As}.
+
+
+%% @spec update_c_catch(Old::c_catch(), Body::cerl()) -> c_catch()
+%% @see c_catch/1
+
+-spec update_c_catch(c_catch(), cerl()) -> c_catch().
+
+update_c_catch(Node, Body) ->
+ #c_catch{body = Body, anno = get_ann(Node)}.
+
+
+%% @spec is_c_catch(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> is an abstract
+%% catch-expression, otherwise <code>false</code>.
+%%
+%% @see c_catch/1
+
+-spec is_c_catch(cerl()) -> boolean().
+
+is_c_catch(#c_catch{}) ->
+ true;
+is_c_catch(_) ->
+ false.
+
+
+%% @spec catch_body(Node::c_catch()) -> cerl()
+%%
+%% @doc Returns the body subtree of an abstract catch-expression.
+%%
+%% @see c_catch/1
+
+-spec catch_body(c_catch()) -> cerl().
+
+catch_body(Node) ->
+ Node#c_catch.body.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec to_records(Tree::cerl()) -> record(record_types())
+%%
+%% @doc Translates an abstract syntax tree to a corresponding explicit
+%% record representation. The records are defined in the file
+%% "<code>cerl.hrl</code>".
+%%
+%% @see type/1
+%% @see from_records/1
+
+-spec to_records(cerl()) -> cerl().
+
+to_records(Node) ->
+ Node.
+
+%% @spec from_records(Tree::record(record_types())) -> cerl()
+%%
+%% record_types() = c_alias | c_apply | c_binary | c_bitstr | c_call |
+%% c_case | c_catch | c_clause | c_cons | c_fun |
+%% c_let | c_letrec | c_literal | c_map | c_map_pair |
+%% c_module | c_primop | c_receive | c_seq |
+%% c_try | c_tuple | c_values | c_var
+%%
+%% @doc Translates an explicit record representation to a
+%% corresponding abstract syntax tree. The records are defined in the
+%% file "<code>core_parse.hrl</code>".
+%%
+%% @see type/1
+%% @see to_records/1
+
+-spec from_records(cerl()) -> cerl().
+
+from_records(Node) ->
+ Node.
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec is_data(Node::cerl()) -> boolean()
+%%
+%% @doc Returns <code>true</code> if <code>Node</code> represents a
+%% data constructor, otherwise <code>false</code>. Data constructors
+%% are cons cells, tuples, and atomic literals.
+%%
+%% @see data_type/1
+%% @see data_es/1
+%% @see data_arity/1
+
+-spec is_data(cerl()) -> boolean().
+
+is_data(#c_literal{}) ->
+ true;
+is_data(#c_cons{}) ->
+ true;
+is_data(#c_tuple{}) ->
+ true;
+is_data(_) ->
+ false.
+
+
+%% @spec data_type(Node::cerl()) -> dtype()
+%%
+%% dtype() = cons | tuple | {atomic, Value}
+%% Value = integer() | float() | atom() | []
+%%
+%% @doc Returns a type descriptor for a data constructor
+%% node. (Cf. <code>is_data/1</code>.) This is mainly useful for
+%% comparing types and for constructing new nodes of the same type
+%% (cf. <code>make_data/2</code>). If <code>Node</code> represents an
+%% integer, floating-point number, atom or empty list, the result is
+%% <code>{atomic, Value}</code>, where <code>Value</code> is the value
+%% of <code>concrete(Node)</code>, otherwise the result is either
+%% <code>cons</code> or <code>tuple</code>.
+%%
+%% <p>Type descriptors can be compared for equality or order (in the
+%% Erlang term order), but remember that floating-point values should
+%% in general never be tested for equality.</p>
+%%
+%% @see is_data/1
+%% @see make_data/2
+%% @see type/1
+%% @see concrete/1
+
+-type value() :: integer() | float() | atom() | [].
+-type dtype() :: 'cons' | 'tuple' | {'atomic', value()}.
+-type c_lct() :: c_literal() | c_cons() | c_tuple().
+
+-spec data_type(c_lct()) -> dtype().
+
+data_type(#c_literal{val = V}) ->
+ case V of
+ [_ | _] ->
+ cons;
+ _ when is_tuple(V) ->
+ tuple;
+ _ ->
+ {atomic, V}
+ end;
+data_type(#c_cons{}) ->
+ cons;
+data_type(#c_tuple{}) ->
+ tuple.
+
+%% @spec data_es(Node::cerl()) -> [cerl()]
+%%
+%% @doc Returns the list of subtrees of a data constructor node. If
+%% the arity of the constructor is zero, the result is the empty list.
+%%
+%% <p>Note: if <code>data_type(Node)</code> is <code>cons</code>, the
+%% number of subtrees is exactly two. If <code>data_type(Node)</code>
+%% is <code>{atomic, Value}</code>, the number of subtrees is
+%% zero.</p>
+%%
+%% @see is_data/1
+%% @see data_type/1
+%% @see data_arity/1
+%% @see make_data/2
+
+-spec data_es(c_lct()) -> [cerl()].
+
+data_es(#c_literal{val = V}) ->
+ case V of
+ [Head | Tail] ->
+ [#c_literal{val = Head}, #c_literal{val = Tail}];
+ _ when is_tuple(V) ->
+ make_lit_list(tuple_to_list(V));
+ _ ->
+ []
+ end;
+data_es(#c_cons{hd = H, tl = T}) ->
+ [H, T];
+data_es(#c_tuple{es = Es}) ->
+ Es.
+
+%% @spec data_arity(Node::cerl()) -> non_neg_integer()
+%%
+%% @doc Returns the number of subtrees of a data constructor
+%% node. This is equivalent to <code>length(data_es(Node))</code>, but
+%% potentially more efficient.
+%%
+%% @see is_data/1
+%% @see data_es/1
+
+-spec data_arity(c_lct()) -> non_neg_integer().
+
+data_arity(#c_literal{val = V}) ->
+ case V of
+ [_ | _] ->
+ 2;
+ _ when is_tuple(V) ->
+ tuple_size(V);
+ _ ->
+ 0
+ end;
+data_arity(#c_cons{}) ->
+ 2;
+data_arity(#c_tuple{es = Es}) ->
+ length(Es).
+
+
+%% @spec make_data(Type::dtype(), Elements::[cerl()]) -> cerl()
+%%
+%% @doc Creates a data constructor node with the specified type and
+%% subtrees. (Cf. <code>data_type/1</code>.) An exception is thrown
+%% if the length of <code>Elements</code> is invalid for the given
+%% <code>Type</code>; see <code>data_es/1</code> for arity constraints
+%% on constructor types.
+%%
+%% @see data_type/1
+%% @see data_es/1
+%% @see ann_make_data/3
+%% @see update_data/3
+%% @see make_data_skel/2
+
+-spec make_data(dtype(), [cerl()]) -> c_lct().
+
+make_data(CType, Es) ->
+ ann_make_data([], CType, Es).
+
+
+%% @spec ann_make_data(As::anns(), Type::dtype(),
+%% Elements::[cerl()]) -> cerl()
+%% @see make_data/2
+
+-spec ann_make_data(anns(), dtype(), [cerl()]) -> c_lct().
+
+ann_make_data(As, {atomic, V}, []) -> #c_literal{val = V, anno = As};
+ann_make_data(As, cons, [H, T]) -> ann_c_cons(As, H, T);
+ann_make_data(As, tuple, Es) -> ann_c_tuple(As, Es).
+
+%% @spec update_data(Old::cerl(), Type::dtype(),
+%% Elements::[cerl()]) -> cerl()
+%% @see make_data/2
+
+-spec update_data(cerl(), dtype(), [cerl()]) -> c_lct().
+
+update_data(Node, CType, Es) ->
+ ann_make_data(get_ann(Node), CType, Es).
+
+
+%% @spec make_data_skel(Type::dtype(), Elements::[cerl()]) -> cerl()
+%%
+%% @doc Like <code>make_data/2</code>, but analogous to
+%% <code>c_tuple_skel/1</code> and <code>c_cons_skel/2</code>.
+%%
+%% @see ann_make_data_skel/3
+%% @see update_data_skel/3
+%% @see make_data/2
+%% @see c_tuple_skel/1
+%% @see c_cons_skel/2
+
+-spec make_data_skel(dtype(), [cerl()]) -> c_lct().
+
+make_data_skel(CType, Es) ->
+ ann_make_data_skel([], CType, Es).
+
+
+%% @spec ann_make_data_skel(As::anns(), Type::dtype(),
+%% Elements::[cerl()]) -> cerl()
+%% @see make_data_skel/2
+
+-spec ann_make_data_skel(anns(), dtype(), [cerl()]) -> c_lct().
+
+ann_make_data_skel(As, {atomic, V}, []) -> #c_literal{val = V, anno = As};
+ann_make_data_skel(As, cons, [H, T]) -> ann_c_cons_skel(As, H, T);
+ann_make_data_skel(As, tuple, Es) -> ann_c_tuple_skel(As, Es).
+
+
+%% @spec update_data_skel(Old::cerl(), Type::dtype(),
+%% Elements::[cerl()]) -> cerl()
+%% @see make_data_skel/2
+
+-spec update_data_skel(cerl(), dtype(), [cerl()]) -> c_lct().
+
+update_data_skel(Node, CType, Es) ->
+ ann_make_data_skel(get_ann(Node), CType, Es).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec subtrees(Node::cerl()) -> [[cerl()]]
+%%
+%% @doc Returns the grouped list of all subtrees of a node. If
+%% <code>Node</code> is a leaf node (cf. <code>is_leaf/1</code>), this
+%% is the empty list, otherwise the result is always a nonempty list,
+%% containing the lists of subtrees of <code>Node</code>, in
+%% left-to-right order as they occur in the printed program text, and
+%% grouped by category. Often, each group contains only a single
+%% subtree.
+%%
+%% <p>Depending on the type of <code>Node</code>, the size of some
+%% groups may be variable (e.g., the group consisting of all the
+%% elements of a tuple), while others always contain the same number
+%% of elements - usually exactly one (e.g., the group containing the
+%% argument expression of a case-expression). Note, however, that the
+%% exact structure of the returned list (for a given node type) should
+%% in general not be depended upon, since it might be subject to
+%% change without notice.</p>
+%%
+%% <p>The function <code>subtrees/1</code> and the constructor functions
+%% <code>make_tree/2</code> and <code>update_tree/2</code> can be a
+%% great help if one wants to traverse a syntax tree, visiting all its
+%% subtrees, but treat nodes of the tree in a uniform way in most or all
+%% cases. Using these functions makes this simple, and also assures that
+%% your code is not overly sensitive to extensions of the syntax tree
+%% data type, because any node types not explicitly handled by your code
+%% can be left to a default case.</p>
+%%
+%% <p>For example:
+%% <pre>
+%% postorder(F, Tree) ->
+%% F(case subtrees(Tree) of
+%% [] -> Tree;
+%% List -> update_tree(Tree,
+%% [[postorder(F, Subtree)
+%% || Subtree &lt;- Group]
+%% || Group &lt;- List])
+%% end).
+%% </pre>
+%% maps the function <code>F</code> on <code>Tree</code> and all its
+%% subtrees, doing a post-order traversal of the syntax tree. (Note
+%% the use of <code>update_tree/2</code> to preserve annotations.) For
+%% a simple function like:
+%% <pre>
+%% f(Node) ->
+%% case type(Node) of
+%% atom -> atom("a_" ++ atom_name(Node));
+%% _ -> Node
+%% end.
+%% </pre>
+%% the call <code>postorder(fun f/1, Tree)</code> will yield a new
+%% representation of <code>Tree</code> in which all atom names have
+%% been extended with the prefix "a_", but nothing else (including
+%% annotations) has been changed.</p>
+%%
+%% @see is_leaf/1
+%% @see make_tree/2
+%% @see update_tree/2
+
+-spec subtrees(cerl()) -> [[cerl()]].
+
+subtrees(T) ->
+ case is_leaf(T) of
+ true ->
+ [];
+ false ->
+ case type(T) of
+ values ->
+ [values_es(T)];
+ binary ->
+ [binary_segments(T)];
+ bitstr ->
+ [[bitstr_val(T)], [bitstr_size(T)],
+ [bitstr_unit(T)], [bitstr_type(T)],
+ [bitstr_flags(T)]];
+ cons ->
+ [[cons_hd(T)], [cons_tl(T)]];
+ tuple ->
+ [tuple_es(T)];
+ map ->
+ [map_es(T)];
+ map_pair ->
+ [[map_pair_op(T)],[map_pair_key(T)],[map_pair_val(T)]];
+ 'let' ->
+ [let_vars(T), [let_arg(T)], [let_body(T)]];
+ seq ->
+ [[seq_arg(T)], [seq_body(T)]];
+ apply ->
+ [[apply_op(T)], apply_args(T)];
+ call ->
+ [[call_module(T)], [call_name(T)],
+ call_args(T)];
+ primop ->
+ [[primop_name(T)], primop_args(T)];
+ 'case' ->
+ [[case_arg(T)], case_clauses(T)];
+ clause ->
+ [clause_pats(T), [clause_guard(T)],
+ [clause_body(T)]];
+ alias ->
+ [[alias_var(T)], [alias_pat(T)]];
+ 'fun' ->
+ [fun_vars(T), [fun_body(T)]];
+ 'receive' ->
+ [receive_clauses(T), [receive_timeout(T)],
+ [receive_action(T)]];
+ 'try' ->
+ [[try_arg(T)], try_vars(T), [try_body(T)],
+ try_evars(T), [try_handler(T)]];
+ 'catch' ->
+ [[catch_body(T)]];
+ letrec ->
+ Es = unfold_tuples(letrec_defs(T)),
+ [Es, [letrec_body(T)]];
+ module ->
+ As = unfold_tuples(module_attrs(T)),
+ Es = unfold_tuples(module_defs(T)),
+ [[module_name(T)], module_exports(T), As, Es]
+ end
+ end.
+
+
+%% @spec update_tree(Old::cerl(), Groups::[[cerl()]]) -> cerl()
+%%
+%% @doc Creates a syntax tree with the given subtrees, and the same
+%% type and annotations as the <code>Old</code> node. This is
+%% equivalent to <code>ann_make_tree(get_ann(Node), type(Node),
+%% Groups)</code>, but potentially more efficient.
+%%
+%% @see update_tree/3
+%% @see ann_make_tree/3
+%% @see get_ann/1
+%% @see type/1
+
+-spec update_tree(cerl(), [[cerl()],...]) -> cerl().
+
+update_tree(Node, Gs) ->
+ ann_make_tree(get_ann(Node), type(Node), Gs).
+
+
+%% @spec update_tree(Old::cerl(), Type::ctype(), Groups::[[cerl()]]) ->
+%% cerl()
+%%
+%% @doc Creates a syntax tree with the given type and subtrees, and
+%% the same annotations as the <code>Old</code> node. This is
+%% equivalent to <code>ann_make_tree(get_ann(Node), Type,
+%% Groups)</code>, but potentially more efficient.
+%%
+%% @see update_tree/2
+%% @see ann_make_tree/3
+%% @see get_ann/1
+
+-spec update_tree(cerl(), ctype(), [[cerl()],...]) -> cerl().
+
+update_tree(Node, Type, Gs) ->
+ ann_make_tree(get_ann(Node), Type, Gs).
+
+
+%% @spec make_tree(Type::ctype(), Groups::[[cerl()]]) -> cerl()
+%%
+%% @doc Creates a syntax tree with the given type and subtrees.
+%% <code>Type</code> must be a node type name
+%% (cf. <code>type/1</code>) that does not denote a leaf node type
+%% (cf. <code>is_leaf/1</code>). <code>Groups</code> must be a
+%% <em>nonempty</em> list of groups of syntax trees, representing the
+%% subtrees of a node of the given type, in left-to-right order as
+%% they would occur in the printed program text, grouped by category
+%% as done by <code>subtrees/1</code>.
+%%
+%% <p>The result of <code>ann_make_tree(get_ann(Node), type(Node),
+%% subtrees(Node))</code> (cf. <code>update_tree/2</code>) represents
+%% the same source code text as the original <code>Node</code>,
+%% assuming that <code>subtrees(Node)</code> yields a nonempty
+%% list. However, it does not necessarily have the exact same data
+%% representation as <code>Node</code>.</p>
+%%
+%% @see ann_make_tree/3
+%% @see type/1
+%% @see is_leaf/1
+%% @see subtrees/1
+%% @see update_tree/2
+
+-spec make_tree(ctype(), [[cerl()],...]) -> cerl().
+
+make_tree(Type, Gs) ->
+ ann_make_tree([], Type, Gs).
+
+
+%% @spec ann_make_tree(As::anns(), Type::ctype(),
+%% Groups::[[cerl()]]) -> cerl()
+%%
+%% @doc Creates a syntax tree with the given annotations, type and
+%% subtrees. See <code>make_tree/2</code> for details.
+%%
+%% @see make_tree/2
+
+-spec ann_make_tree(anns(), ctype(), [[cerl()],...]) -> cerl().
+
+ann_make_tree(As, values, [Es]) -> ann_c_values(As, Es);
+ann_make_tree(As, binary, [Ss]) -> ann_c_binary(As, Ss);
+ann_make_tree(As, bitstr, [[V],[S],[U],[T],[Fs]]) ->
+ ann_c_bitstr(As, V, S, U, T, Fs);
+ann_make_tree(As, cons, [[H], [T]]) -> ann_c_cons(As, H, T);
+ann_make_tree(As, tuple, [Es]) -> ann_c_tuple(As, Es);
+ann_make_tree(As, map, [Es]) -> ann_c_map(As, Es);
+ann_make_tree(As, map, [[A], Es]) -> ann_c_map(As, A, Es);
+ann_make_tree(As, map_pair, [[Op], [K], [V]]) -> ann_c_map_pair(As, Op, K, V);
+ann_make_tree(As, 'let', [Vs, [A], [B]]) -> ann_c_let(As, Vs, A, B);
+ann_make_tree(As, seq, [[A], [B]]) -> ann_c_seq(As, A, B);
+ann_make_tree(As, apply, [[Op], Es]) -> ann_c_apply(As, Op, Es);
+ann_make_tree(As, call, [[M], [N], Es]) -> ann_c_call(As, M, N, Es);
+ann_make_tree(As, primop, [[N], Es]) -> ann_c_primop(As, N, Es);
+ann_make_tree(As, 'case', [[A], Cs]) -> ann_c_case(As, A, Cs);
+ann_make_tree(As, clause, [Ps, [G], [B]]) -> ann_c_clause(As, Ps, G, B);
+ann_make_tree(As, alias, [[V], [P]]) -> ann_c_alias(As, V, P);
+ann_make_tree(As, 'fun', [Vs, [B]]) -> ann_c_fun(As, Vs, B);
+ann_make_tree(As, 'receive', [Cs, [T], [A]]) ->
+ ann_c_receive(As, Cs, T, A);
+ann_make_tree(As, 'try', [[E], Vs, [B], Evs, [H]]) ->
+ ann_c_try(As, E, Vs, B, Evs, H);
+ann_make_tree(As, 'catch', [[B]]) -> ann_c_catch(As, B);
+ann_make_tree(As, letrec, [Es, [B]]) ->
+ ann_c_letrec(As, fold_tuples(Es), B);
+ann_make_tree(As, module, [[N], Xs, Es, Ds]) ->
+ ann_c_module(As, N, Xs, fold_tuples(Es), fold_tuples(Ds)).
+
+
+%% ---------------------------------------------------------------------
+
+%% @spec meta(Tree::cerl()) -> cerl()
+%%
+%% @doc Creates a meta-representation of a syntax tree. The result
+%% represents an Erlang expression "<code><em>MetaTree</em></code>"
+%% which, if evaluated, will yield a new syntax tree representing the
+%% same source code text as <code>Tree</code> (although the actual
+%% data representation may be different). The expression represented
+%% by <code>MetaTree</code> is <em>implementation independent</em>
+%% with regard to the data structures used by the abstract syntax tree
+%% implementation.
+%%
+%% <p>Any node in <code>Tree</code> whose node type is
+%% <code>var</code> (cf. <code>type/1</code>), and whose list of
+%% annotations (cf. <code>get_ann/1</code>) contains the atom
+%% <code>meta_var</code>, will remain unchanged in the resulting tree,
+%% except that exactly one occurrence of <code>meta_var</code> is
+%% removed from its annotation list.</p>
+%%
+%% <p>The main use of the function <code>meta/1</code> is to transform
+%% a data structure <code>Tree</code>, which represents a piece of
+%% program code, into a form that is <em>representation independent
+%% when printed</em>. E.g., suppose <code>Tree</code> represents a
+%% variable named "V". Then (assuming a function <code>print/1</code>
+%% for printing syntax trees), evaluating
+%% <code>print(abstract(Tree))</code> - simply using
+%% <code>abstract/1</code> to map the actual data structure onto a
+%% syntax tree representation - would output a string that might look
+%% something like "<code>{var, ..., 'V'}</code>", which is obviously
+%% dependent on the implementation of the abstract syntax trees. This
+%% could e.g. be useful for caching a syntax tree in a file. However,
+%% in some situations like in a program generator generator (with two
+%% "generator"), it may be unacceptable. Using
+%% <code>print(meta(Tree))</code> instead would output a
+%% <em>representation independent</em> syntax tree generating
+%% expression; in the above case, something like
+%% "<code>cerl:c_var('V')</code>".</p>
+%%
+%% <p>The implementation tries to generate compact code with respect
+%% to literals and lists.</p>
+%%
+%% @see abstract/1
+%% @see type/1
+%% @see get_ann/1
+
+-spec meta(cerl()) -> cerl().
+
+meta(Node) ->
+ %% First of all we check for metavariables:
+ case type(Node) of
+ var ->
+ case lists:member(meta_var, get_ann(Node)) of
+ false ->
+ meta_0(var, Node);
+ true ->
+ %% A meta-variable: remove the first found
+ %% 'meta_var' annotation, but otherwise leave
+ %% the node unchanged.
+ set_ann(Node, lists:delete(meta_var, get_ann(Node)))
+ end;
+ Type ->
+ meta_0(Type, Node)
+ end.
+
+meta_0(Type, Node) ->
+ case get_ann(Node) of
+ [] ->
+ meta_1(Type, Node);
+ As ->
+ meta_call(set_ann, [meta_1(Type, Node), abstract(As)])
+ end.
+
+meta_1(literal, Node) ->
+ %% We handle atomic literals separately, to get a bit
+ %% more compact code. For the rest, we use 'abstract'.
+ case concrete(Node) of
+ V when is_atom(V) ->
+ meta_call(c_atom, [Node]);
+ V when is_integer(V) ->
+ meta_call(c_int, [Node]);
+ V when is_float(V) ->
+ meta_call(c_float, [Node]);
+ [] ->
+ meta_call(c_nil, []);
+ _ ->
+ meta_call(abstract, [Node])
+ end;
+meta_1(var, Node) ->
+ %% A normal variable or function name.
+ meta_call(c_var, [abstract(var_name(Node))]);
+meta_1(values, Node) ->
+ meta_call(c_values,
+ [make_list(meta_list(values_es(Node)))]);
+meta_1(binary, Node) ->
+ meta_call(c_binary,
+ [make_list(meta_list(binary_segments(Node)))]);
+meta_1(bitstr, Node) ->
+ meta_call(c_bitstr,
+ [meta(bitstr_val(Node)),
+ meta(bitstr_size(Node)),
+ meta(bitstr_unit(Node)),
+ meta(bitstr_type(Node)),
+ meta(bitstr_flags(Node))]);
+meta_1(cons, Node) ->
+ %% The list is split up if some sublist has annotatations. If
+ %% we get exactly one element, we generate a 'c_cons' call
+ %% instead of 'make_list' to reconstruct the node.
+ case split_list(Node) of
+ {[H], Node1} ->
+ meta_call(c_cons, [meta(H), meta(Node1)]);
+ {L, Node1} ->
+ meta_call(make_list,
+ [make_list(meta_list(L)), meta(Node1)])
+ end;
+meta_1(tuple, Node) ->
+ meta_call(c_tuple,
+ [make_list(meta_list(tuple_es(Node)))]);
+meta_1('let', Node) ->
+ meta_call(c_let,
+ [make_list(meta_list(let_vars(Node))),
+ meta(let_arg(Node)), meta(let_body(Node))]);
+meta_1(seq, Node) ->
+ meta_call(c_seq,
+ [meta(seq_arg(Node)), meta(seq_body(Node))]);
+meta_1(apply, Node) ->
+ meta_call(c_apply,
+ [meta(apply_op(Node)),
+ make_list(meta_list(apply_args(Node)))]);
+meta_1(call, Node) ->
+ meta_call(c_call,
+ [meta(call_module(Node)), meta(call_name(Node)),
+ make_list(meta_list(call_args(Node)))]);
+meta_1(primop, Node) ->
+ meta_call(c_primop,
+ [meta(primop_name(Node)),
+ make_list(meta_list(primop_args(Node)))]);
+meta_1('case', Node) ->
+ meta_call(c_case,
+ [meta(case_arg(Node)),
+ make_list(meta_list(case_clauses(Node)))]);
+meta_1(clause, Node) ->
+ meta_call(c_clause,
+ [make_list(meta_list(clause_pats(Node))),
+ meta(clause_guard(Node)),
+ meta(clause_body(Node))]);
+meta_1(alias, Node) ->
+ meta_call(c_alias,
+ [meta(alias_var(Node)), meta(alias_pat(Node))]);
+meta_1('fun', Node) ->
+ meta_call(c_fun,
+ [make_list(meta_list(fun_vars(Node))),
+ meta(fun_body(Node))]);
+meta_1('receive', Node) ->
+ meta_call(c_receive,
+ [make_list(meta_list(receive_clauses(Node))),
+ meta(receive_timeout(Node)),
+ meta(receive_action(Node))]);
+meta_1('try', Node) ->
+ meta_call(c_try,
+ [meta(try_arg(Node)),
+ make_list(meta_list(try_vars(Node))),
+ meta(try_body(Node)),
+ make_list(meta_list(try_evars(Node))),
+ meta(try_handler(Node))]);
+meta_1('catch', Node) ->
+ meta_call(c_catch, [meta(catch_body(Node))]);
+meta_1(letrec, Node) ->
+ meta_call(c_letrec,
+ [make_list([c_tuple([meta(N), meta(F)])
+ || {N, F} <- letrec_defs(Node)]),
+ meta(letrec_body(Node))]);
+meta_1(module, Node) ->
+ meta_call(c_module,
+ [meta(module_name(Node)),
+ make_list(meta_list(module_exports(Node))),
+ make_list([c_tuple([meta(A), meta(V)])
+ || {A, V} <- module_attrs(Node)]),
+ make_list([c_tuple([meta(N), meta(F)])
+ || {N, F} <- module_defs(Node)])]).
+
+meta_call(F, As) ->
+ c_call(c_atom(?MODULE), c_atom(F), As).
+
+meta_list([T | Ts]) ->
+ [meta(T) | meta_list(Ts)];
+meta_list([]) ->
+ [].
+
+split_list(Node) ->
+ split_list(set_ann(Node, []), []).
+
+split_list(Node, L) ->
+ A = get_ann(Node),
+ case type(Node) of
+ cons when A =:= [] ->
+ split_list(cons_tl(Node), [cons_hd(Node) | L]);
+ _ ->
+ {lists:reverse(L), Node}
+ end.
+
+
+%% ---------------------------------------------------------------------
+
+%% General utilities
+
+is_lit_list([#c_literal{} | Es]) ->
+ is_lit_list(Es);
+is_lit_list([_ | _]) ->
+ false;
+is_lit_list([]) ->
+ true.
+
+lit_list_vals([#c_literal{val = V} | Es]) ->
+ [V | lit_list_vals(Es)];
+lit_list_vals([]) ->
+ [].
+
+-spec make_lit_list([litval()]) -> [c_literal()].
+
+make_lit_list([V | Vs]) ->
+ [#c_literal{val = V} | make_lit_list(Vs)];
+make_lit_list([]) ->
+ [].
+
+%% The following tests are the same as done by 'io_lib:char_list' and
+%% 'io_lib:printable_list', respectively, but for a single character.
+
+is_char_value(V) when V >= $\000, V =< $\377 -> true;
+is_char_value(_) -> false.
+
+is_print_char_value(V) when V >= $\040, V =< $\176 -> true;
+is_print_char_value(V) when V >= $\240, V =< $\377 -> true;
+is_print_char_value(V) when V =:= $\b -> true;
+is_print_char_value(V) when V =:= $\d -> true;
+is_print_char_value(V) when V =:= $\e -> true;
+is_print_char_value(V) when V =:= $\f -> true;
+is_print_char_value(V) when V =:= $\n -> true;
+is_print_char_value(V) when V =:= $\r -> true;
+is_print_char_value(V) when V =:= $\s -> true;
+is_print_char_value(V) when V =:= $\t -> true;
+is_print_char_value(V) when V =:= $\v -> true;
+is_print_char_value(V) when V =:= $\" -> true;
+is_print_char_value(V) when V =:= $\' -> true; %' stupid Emacs.
+is_print_char_value(V) when V =:= $\\ -> true;
+is_print_char_value(_) -> false.
+
+is_char_list([V | Vs]) when is_integer(V) ->
+ is_char_value(V) andalso is_char_list(Vs);
+is_char_list([]) ->
+ true;
+is_char_list(_) ->
+ false.
+
+is_print_char_list([V | Vs]) when is_integer(V) ->
+ is_print_char_value(V) andalso is_print_char_list(Vs);
+is_print_char_list([]) ->
+ true;
+is_print_char_list(_) ->
+ false.
+
+unfold_tuples([{X, Y} | Ps]) ->
+ [X, Y | unfold_tuples(Ps)];
+unfold_tuples([]) ->
+ [].
+
+fold_tuples([X, Y | Es]) ->
+ [{X, Y} | fold_tuples(Es)];
+fold_tuples([]) ->
+ [].
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/core_parse.hrl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/core_parse.hrl
new file mode 100644
index 0000000000..14a53d0d2d
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/core_parse.hrl
@@ -0,0 +1,115 @@
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Purpose : Core Erlang syntax trees as records.
+
+%% It would be nice to incorporate some generic functions as well but
+%% this could make including this file difficult.
+
+%% Note: the annotation list is *always* the first record field.
+%% Thus it is possible to define the macros:
+%% -define(get_ann(X), element(2, X)).
+%% -define(set_ann(X, Y), setelement(2, X, Y)).
+
+%% The record definitions appear alphabetically
+
+-record(c_alias, {anno=[] :: cerl:anns(),
+ var :: cerl:c_var(),
+ pat :: cerl:cerl()}).
+
+-record(c_apply, {anno=[] :: cerl:anns(),
+ op :: cerl:c_var(),
+ args :: [cerl:cerl()]}).
+
+-record(c_binary, {anno=[] :: cerl:anns(),
+ segments :: [cerl:c_bitstr()]}).
+
+-record(c_bitstr, {anno=[], val, % val :: Tree,
+ size, % size :: Tree,
+ unit, % unit :: Tree,
+ type, % type :: Tree,
+ flags}). % flags :: Tree
+
+-record(c_call, {anno=[], module, % module :: cerl:cerl(),
+ name, % name :: cerl:cerl(),
+ args}). % args :: [cerl:cerl()]
+
+-record(c_case, {anno=[] :: cerl:anns(),
+ arg :: cerl:cerl(),
+ clauses :: [cerl:cerl()]}).
+
+-record(c_catch, {anno=[] :: cerl:anns(), body :: cerl:cerl()}).
+
+-record(c_clause, {anno=[] :: cerl:anns(),
+ pats, % :: [cerl:cerl()], % pats :: [Tree],
+ guard, % :: cerl:cerl(), % guard :: Tree,
+ body}). % :: cerl:cerl()}). % body :: Tree
+
+-record(c_cons, {anno=[] :: cerl:anns(),
+ hd :: cerl:cerl(),
+ tl :: cerl:cerl()}).
+
+-record(c_fun, {anno=[] :: cerl:anns(),
+ vars :: [cerl:c_var()],
+ body :: cerl:cerl()}).
+
+-record(c_let, {anno=[] :: cerl:anns(),
+ vars :: [cerl:c_var()],
+ arg :: cerl:cerl(),
+ body :: cerl:cerl()}).
+
+-record(c_letrec, {anno=[] :: cerl:anns(),
+ defs :: cerl:defs(),
+ body :: cerl:cerl()}).
+
+-record(c_literal, {anno=[] :: cerl:anns(), val :: cerl:litval()}).
+
+-record(c_map, {anno=[] :: cerl:anns(),
+ arg=#c_literal{val=#{}} :: cerl:c_var() | cerl:c_literal(),
+ es :: [cerl:c_map_pair()],
+ is_pat=false :: boolean()}).
+
+-record(c_map_pair, {anno=[] :: cerl:anns(),
+ op, %:: #c_literal{val::'assoc'} | #c_literal{val::'exact'},
+ key,
+ val}).
+
+-record(c_module, {anno=[] :: cerl:anns(),
+ name :: cerl:c_literal(),
+ exports :: [cerl:c_var()],
+ attrs :: cerl:attrs(),
+ defs :: cerl:defs()}).
+
+-record(c_primop, {anno=[] :: cerl:anns(),
+ name :: cerl:c_literal(),
+ args :: [cerl:cerl()]}).
+
+-record(c_receive, {anno=[]:: cerl:anns(),
+ clauses, % clauses :: [Tree],
+ timeout, % timeout :: Tree,
+ action}). % action :: Tree
+
+-record(c_seq, {anno=[] :: cerl:anns(),
+ arg, % arg :: cerl:cerl(),
+ body}). % body :: cerl:cerl()
+
+-record(c_try, {anno=[], arg, % arg :: cerl:cerl(),
+ vars, % vars :: [cerl:c_var()],
+ body, % body :: cerl:cerl(),
+ evars, % evars :: [cerl:c_var()],
+ handler}). % handler :: cerl:cerl()
+
+-record(c_tuple, {anno=[] :: cerl:anns(), es :: [cerl:cerl()]}).
+
+-record(c_values, {anno=[] :: cerl:anns(), es :: [cerl:cerl()]}).
+
+-record(c_var, {anno=[] :: cerl:anns(), name :: cerl:var_name()}).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer.hrl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer.hrl
new file mode 100644
index 0000000000..c0f287893e
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer.hrl
@@ -0,0 +1,173 @@
+%%% This is an -*- Erlang -*- file.
+%%%
+%%% Licensed under the Apache License, Version 2.0 (the "License");
+%%% you may not use this file except in compliance with the License.
+%%% You may obtain a copy of the License at
+%%%
+%%% http://www.apache.org/licenses/LICENSE-2.0
+%%%
+%%% Unless required by applicable law or agreed to in writing, software
+%%% distributed under the License is distributed on an "AS IS" BASIS,
+%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%%% See the License for the specific language governing permissions and
+%%% limitations under the License.
+%%%-------------------------------------------------------------------
+%%% File : dialyzer.hrl
+%%% Author : Tobias Lindahl <[email protected]>
+%%% Kostis Sagonas <[email protected]>
+%%% Description : Header file for Dialyzer.
+%%%
+%%% Created : 1 Oct 2004 by Kostis Sagonas <[email protected]>
+%%%-------------------------------------------------------------------
+
+-define(RET_NOTHING_SUSPICIOUS, 0).
+-define(RET_INTERNAL_ERROR, 1).
+-define(RET_DISCREPANCIES, 2).
+
+-type dial_ret() :: ?RET_NOTHING_SUSPICIOUS
+ | ?RET_INTERNAL_ERROR
+ | ?RET_DISCREPANCIES.
+
+%%--------------------------------------------------------------------
+%% Warning classification
+%%--------------------------------------------------------------------
+
+-define(WARN_RETURN_NO_RETURN, warn_return_no_exit).
+-define(WARN_RETURN_ONLY_EXIT, warn_return_only_exit).
+-define(WARN_NOT_CALLED, warn_not_called).
+-define(WARN_NON_PROPER_LIST, warn_non_proper_list).
+-define(WARN_FUN_APP, warn_fun_app).
+-define(WARN_MATCHING, warn_matching).
+-define(WARN_OPAQUE, warn_opaque).
+-define(WARN_FAILING_CALL, warn_failing_call).
+-define(WARN_BIN_CONSTRUCTION, warn_bin_construction).
+-define(WARN_CONTRACT_TYPES, warn_contract_types).
+-define(WARN_CONTRACT_SYNTAX, warn_contract_syntax).
+-define(WARN_CONTRACT_NOT_EQUAL, warn_contract_not_equal).
+-define(WARN_CONTRACT_SUBTYPE, warn_contract_subtype).
+-define(WARN_CONTRACT_SUPERTYPE, warn_contract_supertype).
+-define(WARN_CONTRACT_RANGE, warn_contract_range).
+-define(WARN_CALLGRAPH, warn_callgraph).
+-define(WARN_UNMATCHED_RETURN, warn_umatched_return).
+-define(WARN_RACE_CONDITION, warn_race_condition).
+-define(WARN_BEHAVIOUR, warn_behaviour).
+-define(WARN_UNDEFINED_CALLBACK, warn_undefined_callbacks).
+-define(WARN_UNKNOWN, warn_unknown).
+-define(WARN_MAP_CONSTRUCTION, warn_map_construction).
+
+%%
+%% The following type has double role:
+%% 1. It is the set of warnings that will be collected.
+%% 2. It is also the set of tags for warnings that will be returned.
+%%
+-type dial_warn_tag() :: ?WARN_RETURN_NO_RETURN | ?WARN_RETURN_ONLY_EXIT
+ | ?WARN_NOT_CALLED | ?WARN_NON_PROPER_LIST
+ | ?WARN_MATCHING | ?WARN_OPAQUE | ?WARN_FUN_APP
+ | ?WARN_FAILING_CALL | ?WARN_BIN_CONSTRUCTION
+ | ?WARN_CONTRACT_TYPES | ?WARN_CONTRACT_SYNTAX
+ | ?WARN_CONTRACT_NOT_EQUAL | ?WARN_CONTRACT_SUBTYPE
+ | ?WARN_CONTRACT_SUPERTYPE | ?WARN_CALLGRAPH
+ | ?WARN_UNMATCHED_RETURN | ?WARN_RACE_CONDITION
+ | ?WARN_BEHAVIOUR | ?WARN_CONTRACT_RANGE
+ | ?WARN_UNDEFINED_CALLBACK | ?WARN_UNKNOWN
+ | ?WARN_MAP_CONSTRUCTION.
+
+%%
+%% This is the representation of each warning as they will be returned
+%% to dialyzer's callers
+%%
+-type file_line() :: {file:filename(), non_neg_integer()}.
+-type dial_warning() :: {dial_warn_tag(), file_line(), {atom(), [term()]}}.
+
+%%
+%% This is the representation of each warning before suppressions have
+%% been applied
+%%
+-type m_or_mfa() :: module() % warnings not associated with any function
+ | mfa().
+-type warning_info() :: {file:filename(), non_neg_integer(), m_or_mfa()}.
+-type raw_warning() :: {dial_warn_tag(), warning_info(), {atom(), [term()]}}.
+
+%%
+%% This is the representation of dialyzer's internal errors
+%%
+-type dial_error() :: any(). %% XXX: underspecified
+
+%%--------------------------------------------------------------------
+%% Basic types used either in the record definitions below or in other
+%% parts of the application
+%%--------------------------------------------------------------------
+
+-type anal_type() :: 'succ_typings' | 'plt_build'.
+-type anal_type1() :: anal_type() | 'plt_add' | 'plt_check' | 'plt_remove'.
+-type contr_constr() :: {'subtype', erl_types:erl_type(), erl_types:erl_type()}.
+-type contract_pair() :: {erl_types:erl_type(), [contr_constr()]}.
+-type dial_define() :: {atom(), term()}.
+-type dial_option() :: {atom(), term()}.
+-type dial_options() :: [dial_option()].
+-type fopt() :: 'basename' | 'fullpath'.
+-type format() :: 'formatted' | 'raw'.
+-type label() :: non_neg_integer().
+-type dial_warn_tags():: ordsets:ordset(dial_warn_tag()).
+-type rep_mode() :: 'quiet' | 'normal' | 'verbose'.
+-type start_from() :: 'byte_code' | 'src_code'.
+-type mfa_or_funlbl() :: label() | mfa().
+-type solver() :: 'v1' | 'v2'.
+
+%%--------------------------------------------------------------------
+%% Record declarations used by various files
+%%--------------------------------------------------------------------
+
+-type doc_plt() :: 'undefined' | dialyzer_plt:plt().
+
+-record(analysis, {analysis_pid :: pid() | 'undefined',
+ type = succ_typings :: anal_type(),
+ defines = [] :: [dial_define()],
+ doc_plt :: doc_plt(),
+ files = [] :: [file:filename()],
+ include_dirs = [] :: [file:filename()],
+ start_from = byte_code :: start_from(),
+ plt :: dialyzer_plt:plt(),
+ use_contracts = true :: boolean(),
+ race_detection = false :: boolean(),
+ behaviours_chk = false :: boolean(),
+ timing = false :: boolean() | 'debug',
+ timing_server = none :: dialyzer_timing:timing_server(),
+ callgraph_file = "" :: file:filename(),
+ solvers :: [solver()]}).
+
+-record(options, {files = [] :: [file:filename()],
+ files_rec = [] :: [file:filename()],
+ analysis_type = succ_typings :: anal_type1(),
+ timing = false :: boolean() | 'debug',
+ defines = [] :: [dial_define()],
+ from = byte_code :: start_from(),
+ get_warnings = maybe :: boolean() | 'maybe',
+ init_plts = [] :: [file:filename()],
+ include_dirs = [] :: [file:filename()],
+ output_plt = none :: 'none' | file:filename(),
+ legal_warnings = ordsets:new() :: dial_warn_tags(),
+ report_mode = normal :: rep_mode(),
+ erlang_mode = false :: boolean(),
+ use_contracts = true :: boolean(),
+ output_file = none :: 'none' | file:filename(),
+ output_format = formatted :: format(),
+ filename_opt = basename :: fopt(),
+ callgraph_file = "" :: file:filename(),
+ check_plt = true :: boolean(),
+ solvers = [] :: [solver()]}).
+
+-record(contract, {contracts = [] :: [contract_pair()],
+ args = [] :: [erl_types:erl_type()],
+ forms = [] :: [{_, _}]}).
+
+%%--------------------------------------------------------------------
+
+-define(timing(Server, Msg, Var, Expr),
+ begin
+ dialyzer_timing:start_stamp(Server, Msg),
+ Var = Expr,
+ dialyzer_timing:end_stamp(Server),
+ Var
+ end).
+-define(timing(Server, Msg, Expr), ?timing(Server, Msg, _T, Expr)).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_dataflow.erl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_dataflow.erl
new file mode 100644
index 0000000000..53b08cc5c9
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_dataflow.erl
@@ -0,0 +1,3795 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+%%%-------------------------------------------------------------------
+%%% File : dialyzer_dataflow.erl
+%%% Author : Tobias Lindahl <[email protected]>
+%%% Description :
+%%%
+%%% Created : 19 Apr 2005 by Tobias Lindahl <[email protected]>
+%%%-------------------------------------------------------------------
+
+-module(dialyzer_dataflow).
+
+-export([get_fun_types/5, get_warnings/5, format_args/3]).
+
+%% Data structure interfaces.
+-export([state__add_warning/2, state__cleanup/1,
+ state__duplicate/1, dispose_state/1,
+ state__get_callgraph/1, state__get_races/1,
+ state__get_records/1, state__put_callgraph/2,
+ state__put_races/2, state__records_only/1,
+ state__find_function/2]).
+
+-export_type([state/0]).
+
+-include("dialyzer.hrl").
+
+-import(erl_types,
+ [t_inf/2, t_inf/3, t_inf_lists/2, t_inf_lists/3,
+ t_inf_lists/3, t_is_equal/2, t_is_subtype/2, t_subtract/2,
+ t_sup/1, t_sup/2]).
+
+-import(erl_types,
+ [any_none/1, t_any/0, t_atom/0, t_atom/1, t_atom_vals/1, t_atom_vals/2,
+ t_binary/0, t_boolean/0,
+ t_bitstr/0, t_bitstr/2, t_bitstr_concat/1, t_bitstr_match/2,
+ t_cons/0, t_cons/2, t_cons_hd/2, t_cons_tl/2,
+ t_contains_opaque/2,
+ t_find_opaque_mismatch/3, t_float/0, t_from_range/2, t_from_term/1,
+ t_fun/0, t_fun/2, t_fun_args/1, t_fun_args/2, t_fun_range/1,
+ t_fun_range/2, t_integer/0, t_integers/1,
+ t_is_any/1, t_is_atom/1, t_is_atom/2, t_is_any_atom/3,
+ t_is_boolean/2,
+ t_is_integer/2, t_is_list/1,
+ t_is_nil/2, t_is_none/1, t_is_none_or_unit/1,
+ t_is_number/2, t_is_reference/2, t_is_pid/2, t_is_port/2,
+ t_is_unit/1,
+ t_limit/2, t_list/0, t_list_elements/2,
+ t_maybe_improper_list/0, t_module/0,
+ t_none/0, t_non_neg_integer/0, t_number/0, t_number_vals/2,
+ t_pid/0, t_port/0, t_product/1, t_reference/0,
+ t_to_string/2, t_to_tlist/1,
+ t_tuple/0, t_tuple/1, t_tuple_args/1, t_tuple_args/2,
+ t_tuple_subtypes/2,
+ t_unit/0, t_unopaque/2,
+ t_map/0, t_map/1, t_is_singleton/2
+ ]).
+
+%%-define(DEBUG, true).
+%%-define(DEBUG_PP, true).
+%%-define(DEBUG_TIME, true).
+
+-ifdef(DEBUG).
+-import(erl_types, [t_to_string/1]).
+-define(debug(S_, L_), io:format(S_, L_)).
+-else.
+-define(debug(S_, L_), ok).
+-endif.
+
+%%--------------------------------------------------------------------
+
+-type type() :: erl_types:erl_type().
+-type types() :: erl_types:type_table().
+
+-type curr_fun() :: 'undefined' | 'top' | mfa_or_funlbl().
+
+-define(no_arg, no_arg).
+
+-define(TYPE_LIMIT, 3).
+
+-define(BITS, 128).
+
+%% Types with comment 'race' are due to dialyzer_races.erl.
+-record(state, {callgraph :: dialyzer_callgraph:callgraph()
+ | 'undefined', % race
+ codeserver :: dialyzer_codeserver:codeserver()
+ | 'undefined', % race
+ envs :: env_tab()
+ | 'undefined', % race
+ fun_tab :: fun_tab()
+ | 'undefined', % race
+ fun_homes :: dict:dict(label(), mfa())
+ | 'undefined', % race
+ plt :: dialyzer_plt:plt()
+ | 'undefined', % race
+ opaques :: [type()]
+ | 'undefined', % race
+ races = dialyzer_races:new() :: dialyzer_races:races(),
+ records = dict:new() :: types(),
+ tree_map :: dict:dict(label(), cerl:cerl())
+ | 'undefined', % race
+ warning_mode = false :: boolean(),
+ warnings = [] :: [raw_warning()],
+ work :: {[_], [_], sets:set()}
+ | 'undefined', % race
+ module :: module(),
+ curr_fun :: curr_fun()
+ }).
+
+-record(map, {map = maps:new() :: type_tab(),
+ subst = maps:new() :: subst_tab(),
+ modified = [] :: [Key :: term()],
+ modified_stack = [] :: [{[Key :: term()],reference()}],
+ ref = undefined :: reference() | undefined}).
+
+-type env_tab() :: dict:dict(label(), #map{}).
+-type fun_entry() :: {Args :: [type()], RetType :: type()}.
+-type fun_tab() :: dict:dict('top' | label(),
+ {'not_handled', fun_entry()} | fun_entry()).
+-type key() :: label() | cerl:cerl().
+-type type_tab() :: #{key() => type()}.
+-type subst_tab() :: #{key() => cerl:cerl()}.
+
+%% Exported Types
+
+-opaque state() :: #state{}.
+
+%%--------------------------------------------------------------------
+
+-type fun_types() :: dict:dict(label(), type()).
+
+-spec get_warnings(cerl:c_module(), dialyzer_plt:plt(),
+ dialyzer_callgraph:callgraph(),
+ dialyzer_codeserver:codeserver(),
+ types()) ->
+ {[raw_warning()], fun_types()}.
+
+get_warnings(Tree, Plt, Callgraph, Codeserver, Records) ->
+ State1 = analyze_module(Tree, Plt, Callgraph, Codeserver, Records, true),
+ State2 = state__renew_warnings(state__get_warnings(State1), State1),
+ State3 = state__get_race_warnings(State2),
+ {State3#state.warnings, state__all_fun_types(State3)}.
+
+-spec get_fun_types(cerl:c_module(), dialyzer_plt:plt(),
+ dialyzer_callgraph:callgraph(),
+ dialyzer_codeserver:codeserver(),
+ types()) -> fun_types().
+
+get_fun_types(Tree, Plt, Callgraph, Codeserver, Records) ->
+ State = analyze_module(Tree, Plt, Callgraph, Codeserver, Records, false),
+ state__all_fun_types(State).
+
+%%% ===========================================================================
+%%%
+%%% The analysis.
+%%%
+%%% ===========================================================================
+
+analyze_module(Tree, Plt, Callgraph, Codeserver, Records, GetWarnings) ->
+ debug_pp(Tree, false),
+ Module = cerl:atom_val(cerl:module_name(Tree)),
+ TopFun = cerl:ann_c_fun([{label, top}], [], Tree),
+ State = state__new(Callgraph, Codeserver, TopFun, Plt, Module, Records),
+ State1 = state__race_analysis(not GetWarnings, State),
+ State2 = analyze_loop(State1),
+ case GetWarnings of
+ true ->
+ State3 = state__set_warning_mode(State2),
+ State4 = analyze_loop(State3),
+ dialyzer_races:race(State4);
+ false ->
+ State2
+ end.
+
+analyze_loop(State) ->
+ case state__get_work(State) of
+ none -> state__set_curr_fun(undefined, State);
+ {Fun, NewState0} ->
+ NewState1 = state__set_curr_fun(get_label(Fun), NewState0),
+ {ArgTypes, IsCalled} = state__get_args_and_status(Fun, NewState1),
+ case not IsCalled of
+ true ->
+ ?debug("Not handling (not called) ~w: ~s\n",
+ [NewState1#state.curr_fun,
+ t_to_string(t_product(ArgTypes))]),
+ analyze_loop(NewState1);
+ false ->
+ case state__fun_env(Fun, NewState1) of
+ none ->
+ ?debug("Not handling (no env) ~w: ~s\n",
+ [NewState1#state.curr_fun,
+ t_to_string(t_product(ArgTypes))]),
+ analyze_loop(NewState1);
+ Map ->
+ ?debug("Handling fun ~p: ~s\n",
+ [NewState1#state.curr_fun,
+ t_to_string(state__fun_type(Fun, NewState1))]),
+ Vars = cerl:fun_vars(Fun),
+ Map1 = enter_type_lists(Vars, ArgTypes, Map),
+ Body = cerl:fun_body(Fun),
+ FunLabel = get_label(Fun),
+ IsRaceAnalysisEnabled = is_race_analysis_enabled(State),
+ NewState3 =
+ case IsRaceAnalysisEnabled of
+ true ->
+ NewState2 = state__renew_curr_fun(
+ state__lookup_name(FunLabel, NewState1), FunLabel,
+ NewState1),
+ state__renew_race_list([], 0, NewState2);
+ false -> NewState1
+ end,
+ {NewState4, _Map2, BodyType} =
+ traverse(Body, Map1, NewState3),
+ ?debug("Done analyzing: ~w:~s\n",
+ [NewState1#state.curr_fun,
+ t_to_string(t_fun(ArgTypes, BodyType))]),
+ NewState5 =
+ case IsRaceAnalysisEnabled of
+ true -> renew_race_code(NewState4);
+ false -> NewState4
+ end,
+ NewState6 =
+ state__update_fun_entry(Fun, ArgTypes, BodyType, NewState5),
+ ?debug("done adding stuff for ~w\n",
+ [state__lookup_name(get_label(Fun), State)]),
+ analyze_loop(NewState6)
+ end
+ end
+ end.
+
+traverse(Tree, Map, State) ->
+ ?debug("Handling ~p\n", [cerl:type(Tree)]),
+ %% debug_pp_map(Map),
+ case cerl:type(Tree) of
+ alias ->
+ %% This only happens when checking for illegal record patterns
+ %% so the handling is a bit rudimentary.
+ traverse(cerl:alias_pat(Tree), Map, State);
+ apply ->
+ handle_apply(Tree, Map, State);
+ binary ->
+ Segs = cerl:binary_segments(Tree),
+ {State1, Map1, SegTypes} = traverse_list(Segs, Map, State),
+ {State1, Map1, t_bitstr_concat(SegTypes)};
+ bitstr ->
+ handle_bitstr(Tree, Map, State);
+ call ->
+ handle_call(Tree, Map, State);
+ 'case' ->
+ handle_case(Tree, Map, State);
+ 'catch' ->
+ {State1, _Map1, _} = traverse(cerl:catch_body(Tree), Map, State),
+ {State1, Map, t_any()};
+ cons ->
+ handle_cons(Tree, Map, State);
+ 'fun' ->
+ Type = state__fun_type(Tree, State),
+ case state__warning_mode(State) of
+ true -> {State, Map, Type};
+ false ->
+ State2 = state__add_work(get_label(Tree), State),
+ State3 = state__update_fun_env(Tree, Map, State2),
+ {State3, Map, Type}
+ end;
+ 'let' ->
+ handle_let(Tree, Map, State);
+ letrec ->
+ Defs = cerl:letrec_defs(Tree),
+ Body = cerl:letrec_body(Tree),
+ %% By not including the variables in scope we can assure that we
+ %% will get the current function type when using the variables.
+ FoldFun = fun({Var, Fun}, {AccState, AccMap}) ->
+ {NewAccState, NewAccMap0, FunType} =
+ traverse(Fun, AccMap, AccState),
+ NewAccMap = enter_type(Var, FunType, NewAccMap0),
+ {NewAccState, NewAccMap}
+ end,
+ {State1, Map1} = lists:foldl(FoldFun, {State, Map}, Defs),
+ traverse(Body, Map1, State1);
+ literal ->
+ Type = literal_type(Tree),
+ {State, Map, Type};
+ module ->
+ handle_module(Tree, Map, State);
+ primop ->
+ Type =
+ case cerl:atom_val(cerl:primop_name(Tree)) of
+ match_fail -> t_none();
+ raise -> t_none();
+ bs_init_writable -> t_from_term(<<>>);
+ Other -> erlang:error({'Unsupported primop', Other})
+ end,
+ {State, Map, Type};
+ 'receive' ->
+ handle_receive(Tree, Map, State);
+ seq ->
+ Arg = cerl:seq_arg(Tree),
+ Body = cerl:seq_body(Tree),
+ {State1, Map1, ArgType} = SMA = traverse(Arg, Map, State),
+ case t_is_none_or_unit(ArgType) of
+ true ->
+ SMA;
+ false ->
+ State2 =
+ case
+ t_is_any(ArgType)
+ orelse t_is_simple(ArgType, State)
+ orelse is_call_to_send(Arg)
+ orelse is_lc_simple_list(Arg, ArgType, State)
+ of
+ true -> % do not warn in these cases
+ State1;
+ false ->
+ state__add_warning(State1, ?WARN_UNMATCHED_RETURN, Arg,
+ {unmatched_return,
+ [format_type(ArgType, State1)]})
+ end,
+ traverse(Body, Map1, State2)
+ end;
+ 'try' ->
+ handle_try(Tree, Map, State);
+ tuple ->
+ handle_tuple(Tree, Map, State);
+ map ->
+ handle_map(Tree, Map, State);
+ values ->
+ Elements = cerl:values_es(Tree),
+ {State1, Map1, EsType} = traverse_list(Elements, Map, State),
+ Type = t_product(EsType),
+ {State1, Map1, Type};
+ var ->
+ ?debug("Looking up unknown variable: ~p\n", [Tree]),
+ case state__lookup_type_for_letrec(Tree, State) of
+ error ->
+ LType = lookup_type(Tree, Map),
+ {State, Map, LType};
+ {ok, Type} -> {State, Map, Type}
+ end;
+ Other ->
+ erlang:error({'Unsupported type', Other})
+ end.
+
+traverse_list(Trees, Map, State) ->
+ traverse_list(Trees, Map, State, []).
+
+traverse_list([Tree|Tail], Map, State, Acc) ->
+ {State1, Map1, Type} = traverse(Tree, Map, State),
+ traverse_list(Tail, Map1, State1, [Type|Acc]);
+traverse_list([], Map, State, Acc) ->
+ {State, Map, lists:reverse(Acc)}.
+
+%%________________________________________
+%%
+%% Special instructions
+%%
+
+handle_apply(Tree, Map, State) ->
+ Args = cerl:apply_args(Tree),
+ Op = cerl:apply_op(Tree),
+ {State0, Map1, ArgTypes} = traverse_list(Args, Map, State),
+ {State1, Map2, OpType} = traverse(Op, Map1, State0),
+ case any_none(ArgTypes) of
+ true ->
+ {State1, Map2, t_none()};
+ false ->
+ FunList =
+ case state__lookup_call_site(Tree, State) of
+ error -> [external]; %% so that we go directly in the fallback
+ {ok, List} -> List
+ end,
+ FunInfoList = [{local, state__fun_info(Fun, State)} || Fun <- FunList],
+ case
+ handle_apply_or_call(FunInfoList, Args, ArgTypes, Map2, Tree, State1)
+ of
+ {had_external, State2} ->
+ %% Fallback: use whatever info we collected from traversing the op
+ %% instead of the result that has been generalized to t_any().
+ Arity = length(Args),
+ OpType1 = t_inf(OpType, t_fun(Arity, t_any())),
+ case t_is_none(OpType1) of
+ true ->
+ Msg = {fun_app_no_fun,
+ [format_cerl(Op), format_type(OpType, State2), Arity]},
+ State3 = state__add_warning(State2, ?WARN_FAILING_CALL,
+ Tree, Msg),
+ {State3, Map2, t_none()};
+ false ->
+ NewArgs = t_inf_lists(ArgTypes,
+ t_fun_args(OpType1, 'universe')),
+ case any_none(NewArgs) of
+ true ->
+ Msg = {fun_app_args,
+ [format_args(Args, ArgTypes, State),
+ format_type(OpType, State)]},
+ State3 = state__add_warning(State2, ?WARN_FAILING_CALL,
+ Tree, Msg),
+ {State3, enter_type(Op, OpType1, Map2), t_none()};
+ false ->
+ Map3 = enter_type_lists(Args, NewArgs, Map2),
+ Range0 = t_fun_range(OpType1, 'universe'),
+ Range =
+ case t_is_unit(Range0) of
+ true -> t_none();
+ false -> Range0
+ end,
+ {State2, enter_type(Op, OpType1, Map3), Range}
+ end
+ end;
+ Normal -> Normal
+ end
+ end.
+
+handle_apply_or_call(FunInfoList, Args, ArgTypes, Map, Tree, State) ->
+ None = t_none(),
+ %% Call-site analysis may be inaccurate and consider more funs than those that
+ %% are actually possible. If all of them are incorrect, then warnings can be
+ %% emitted. If at least one fun is ok, however, then no warning is emitted,
+ %% just in case the bad ones are not really possible. The last argument is
+ %% used for this, with the following encoding:
+ %% Initial value: {none, []}
+ %% First fun checked: {one, <List of warns>}
+ %% More funs checked: {many, <List of warns>}
+ %% A '{one, []}' can only become '{many, []}'.
+ %% If at any point an fun does not add warnings, then the list is also
+ %% replaced with an empty list.
+ handle_apply_or_call(FunInfoList, Args, ArgTypes, Map, Tree, State,
+ [None || _ <- ArgTypes], None, false, {none, []}).
+
+handle_apply_or_call([{local, external}|Left], Args, ArgTypes, Map, Tree, State,
+ _AccArgTypes, _AccRet, _HadExternal, Warns) ->
+ {HowMany, _} = Warns,
+ NewHowMany =
+ case HowMany of
+ none -> one;
+ _ -> many
+ end,
+ NewWarns = {NewHowMany, []},
+ handle_apply_or_call(Left, Args, ArgTypes, Map, Tree, State,
+ ArgTypes, t_any(), true, NewWarns);
+handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left],
+ Args, ArgTypes, Map, Tree,
+ #state{opaques = Opaques} = State,
+ AccArgTypes, AccRet, HadExternal, Warns) ->
+ Any = t_any(),
+ AnyArgs = [Any || _ <- Args],
+ GenSig = {AnyArgs, fun(_) -> t_any() end},
+ {CArgs, CRange} =
+ case Contr of
+ {value, #contract{args = As} = C} ->
+ {As, fun(FunArgs) ->
+ dialyzer_contracts:get_contract_return(C, FunArgs)
+ end};
+ none -> GenSig
+ end,
+ {BifArgs, BifRange} =
+ case TypeOfApply of
+ remote ->
+ {M, F, A} = Fun,
+ case erl_bif_types:is_known(M, F, A) of
+ true ->
+ BArgs = erl_bif_types:arg_types(M, F, A),
+ BRange =
+ fun(FunArgs) ->
+ erl_bif_types:type(M, F, A, FunArgs, Opaques)
+ end,
+ {BArgs, BRange};
+ false ->
+ GenSig
+ end;
+ local -> GenSig
+ end,
+ {SigArgs, SigRange} =
+ case Sig of
+ {value, {SR, SA}} -> {SA, SR};
+ none -> {AnyArgs, t_any()}
+ end,
+
+ ?debug("--------------------------------------------------------\n", []),
+ ?debug("Fun: ~p\n", [state__lookup_name(Fun, State)]),
+ ?debug("Module ~p\n", [State#state.module]),
+ ?debug("CArgs ~s\n", [erl_types:t_to_string(t_product(CArgs))]),
+ ?debug("ArgTypes ~s\n", [erl_types:t_to_string(t_product(ArgTypes))]),
+ ?debug("BifArgs ~p\n", [erl_types:t_to_string(t_product(BifArgs))]),
+
+ NewArgsSig = t_inf_lists(SigArgs, ArgTypes, Opaques),
+ ?debug("SigArgs ~s\n", [erl_types:t_to_string(t_product(SigArgs))]),
+ ?debug("NewArgsSig: ~s\n", [erl_types:t_to_string(t_product(NewArgsSig))]),
+ NewArgsContract = t_inf_lists(CArgs, ArgTypes, Opaques),
+ ?debug("NewArgsContract: ~s\n",
+ [erl_types:t_to_string(t_product(NewArgsContract))]),
+ NewArgsBif = t_inf_lists(BifArgs, ArgTypes, Opaques),
+ ?debug("NewArgsBif: ~s\n", [erl_types:t_to_string(t_product(NewArgsBif))]),
+ NewArgTypes0 = t_inf_lists(NewArgsSig, NewArgsContract),
+ NewArgTypes = t_inf_lists(NewArgTypes0, NewArgsBif, Opaques),
+ ?debug("NewArgTypes ~s\n", [erl_types:t_to_string(t_product(NewArgTypes))]),
+ ?debug("\n", []),
+
+ BifRet = BifRange(NewArgTypes),
+ ContrRet = CRange(NewArgTypes),
+ RetWithoutContr = t_inf(SigRange, BifRet),
+ RetWithoutLocal = t_inf(ContrRet, RetWithoutContr),
+
+ ?debug("RetWithoutContr: ~s\n",[erl_types:t_to_string(RetWithoutContr)]),
+ ?debug("RetWithoutLocal: ~s\n", [erl_types:t_to_string(RetWithoutLocal)]),
+ ?debug("BifRet: ~s\n", [erl_types:t_to_string(BifRange(NewArgTypes))]),
+ ?debug("SigRange: ~s\n", [erl_types:t_to_string(SigRange)]),
+ ?debug("ContrRet: ~s\n", [erl_types:t_to_string(ContrRet)]),
+ ?debug("LocalRet: ~s\n", [erl_types:t_to_string(LocalRet)]),
+
+ State1 =
+ case is_race_analysis_enabled(State) of
+ true ->
+ Ann = cerl:get_ann(Tree),
+ File = get_file(Ann),
+ Line = abs(get_line(Ann)),
+ dialyzer_races:store_race_call(Fun, ArgTypes, Args,
+ {File, Line}, State);
+ false -> State
+ end,
+ FailedConj = any_none([RetWithoutLocal|NewArgTypes]),
+ IsFailBif = t_is_none(BifRange(BifArgs)),
+ IsFailSig = t_is_none(SigRange),
+ ?debug("FailedConj: ~p~n", [FailedConj]),
+ ?debug("IsFailBif: ~p~n", [IsFailBif]),
+ ?debug("IsFailSig: ~p~n", [IsFailSig]),
+ State2 =
+ case FailedConj andalso not (IsFailBif orelse IsFailSig) of
+ true ->
+ case t_is_none(RetWithoutLocal) andalso
+ not t_is_none(RetWithoutContr) andalso
+ not any_none(NewArgTypes) of
+ true ->
+ {value, C1} = Contr,
+ Contract = dialyzer_contracts:contract_to_string(C1),
+ {M1, F1, A1} = state__lookup_name(Fun, State),
+ ArgStrings = format_args(Args, ArgTypes, State),
+ CRet = erl_types:t_to_string(RetWithoutContr),
+ %% This Msg will be post_processed by dialyzer_succ_typings
+ Msg =
+ {contract_range, [Contract, M1, F1, A1, ArgStrings, CRet]},
+ state__add_warning(State1, ?WARN_CONTRACT_RANGE, Tree, Msg);
+ false ->
+ FailedSig = any_none(NewArgsSig),
+ FailedContract =
+ any_none([CRange(NewArgsContract)|NewArgsContract]),
+ FailedBif = any_none([BifRange(NewArgsBif)|NewArgsBif]),
+ InfSig = t_inf(t_fun(SigArgs, SigRange),
+ t_fun(BifArgs, BifRange(BifArgs))),
+ FailReason =
+ apply_fail_reason(FailedSig, FailedBif, FailedContract),
+ Msg = get_apply_fail_msg(Fun, Args, ArgTypes, NewArgTypes, InfSig,
+ Contr, CArgs, State1, FailReason, Opaques),
+ WarnType = case Msg of
+ {call, _} -> ?WARN_FAILING_CALL;
+ {apply, _} -> ?WARN_FAILING_CALL;
+ {call_with_opaque, _} -> ?WARN_OPAQUE;
+ {call_without_opaque, _} -> ?WARN_OPAQUE;
+ {opaque_type_test, _} -> ?WARN_OPAQUE
+ end,
+ Frc = {erlang, is_record, 3} =:= state__lookup_name(Fun, State),
+ state__add_warning(State1, WarnType, Tree, Msg, Frc)
+ end;
+ false -> State1
+ end,
+ State3 =
+ case TypeOfApply of
+ local ->
+ case state__is_escaping(Fun, State2) of
+ true -> State2;
+ false ->
+ ForwardArgs = [t_limit(X, ?TYPE_LIMIT) || X <- ArgTypes],
+ forward_args(Fun, ForwardArgs, State2)
+ end;
+ remote ->
+ add_bif_warnings(Fun, NewArgTypes, Tree, State2)
+ end,
+ NewAccArgTypes =
+ case FailedConj of
+ true -> AccArgTypes;
+ false -> [t_sup(X, Y) || {X, Y} <- lists:zip(NewArgTypes, AccArgTypes)]
+ end,
+ TotalRet =
+ case t_is_none(LocalRet) andalso t_is_unit(RetWithoutLocal) of
+ true -> RetWithoutLocal;
+ false -> t_inf(RetWithoutLocal, LocalRet)
+ end,
+ NewAccRet = t_sup(AccRet, TotalRet),
+ ?debug("NewAccRet: ~s\n", [t_to_string(NewAccRet)]),
+ {NewWarnings, State4} = state__remove_added_warnings(State, State3),
+ {HowMany, OldWarnings} = Warns,
+ NewWarns =
+ case HowMany of
+ none -> {one, NewWarnings};
+ _ ->
+ case OldWarnings =:= [] of
+ true -> {many, []};
+ false ->
+ case NewWarnings =:= [] of
+ true -> {many, []};
+ false -> {many, NewWarnings ++ OldWarnings}
+ end
+ end
+ end,
+ handle_apply_or_call(Left, Args, ArgTypes, Map, Tree,
+ State4, NewAccArgTypes, NewAccRet, HadExternal, NewWarns);
+handle_apply_or_call([], Args, _ArgTypes, Map, _Tree, State,
+ AccArgTypes, AccRet, HadExternal, {_, Warnings}) ->
+ State1 = state__add_warnings(Warnings, State),
+ case HadExternal of
+ false ->
+ NewMap = enter_type_lists(Args, AccArgTypes, Map),
+ {State1, NewMap, AccRet};
+ true ->
+ {had_external, State1}
+ end.
+
+apply_fail_reason(FailedSig, FailedBif, FailedContract) ->
+ if
+ (FailedSig orelse FailedBif) andalso (not FailedContract) -> only_sig;
+ FailedContract andalso (not (FailedSig orelse FailedBif)) -> only_contract;
+ true -> both
+ end.
+
+get_apply_fail_msg(Fun, Args, ArgTypes, NewArgTypes,
+ Sig, Contract, ContrArgs, State, FailReason, Opaques) ->
+ ArgStrings = format_args(Args, ArgTypes, State),
+ ContractInfo =
+ case Contract of
+ {value, #contract{} = C} ->
+ {dialyzer_contracts:is_overloaded(C),
+ dialyzer_contracts:contract_to_string(C)};
+ none -> {false, none}
+ end,
+ EnumArgTypes = lists:zip(lists:seq(1, length(NewArgTypes)), NewArgTypes),
+ ArgNs = [Arg || {Arg, Type} <- EnumArgTypes, t_is_none(Type)],
+ case state__lookup_name(Fun, State) of
+ {M, F, A} ->
+ case is_opaque_type_test_problem(Fun, Args, NewArgTypes, State) of
+ {yes, Arg, ArgType} ->
+ {opaque_type_test, [atom_to_list(F), ArgStrings,
+ format_arg(Arg), format_type(ArgType, State)]};
+ no ->
+ SigArgs = t_fun_args(Sig),
+ BadOpaque =
+ opaque_problems([SigArgs, ContrArgs], ArgTypes, Opaques, ArgNs),
+ %% In fact *both* 'call_with_opaque' and
+ %% 'call_without_opaque' are possible.
+ case lists:keyfind(decl, 1, BadOpaque) of
+ {decl, BadArgs} ->
+ %% a structured term is used where an opaque is expected
+ ExpectedTriples =
+ case FailReason of
+ only_sig -> expected_arg_triples(BadArgs, SigArgs, State);
+ _ -> expected_arg_triples(BadArgs, ContrArgs, State)
+ end,
+ {call_without_opaque, [M, F, ArgStrings, ExpectedTriples]};
+ false ->
+ case lists:keyfind(use, 1, BadOpaque) of
+ {use, BadArgs} ->
+ %% an opaque term is used where a structured term is expected
+ ExpectedArgs =
+ case FailReason of
+ only_sig -> SigArgs;
+ _ -> ContrArgs
+ end,
+ {call_with_opaque, [M, F, ArgStrings, BadArgs, ExpectedArgs]};
+ false ->
+ case
+ erl_bif_types:opaque_args(M, F, A, ArgTypes, Opaques)
+ of
+ [] -> %% there is a structured term clash in some argument
+ {call, [M, F, ArgStrings,
+ ArgNs, FailReason,
+ format_sig_args(Sig, State),
+ format_type(t_fun_range(Sig), State),
+ ContractInfo]};
+ Ns ->
+ {call_with_opaque, [M, F, ArgStrings, Ns, ContrArgs]}
+ end
+ end
+ end
+ end;
+ Label when is_integer(Label) ->
+ {apply, [ArgStrings,
+ ArgNs, FailReason,
+ format_sig_args(Sig, State),
+ format_type(t_fun_range(Sig), State),
+ ContractInfo]}
+ end.
+
+%% -> [{ElementI, [ArgN]}] where [ArgN] is a non-empty list of
+%% arguments containing unknown opaque types and Element is 1 or 2.
+opaque_problems(ContractOrSigList, ArgTypes, Opaques, ArgNs) ->
+ ArgElementList = find_unknown(ContractOrSigList, ArgTypes, Opaques, ArgNs),
+ F = fun(1) -> decl; (2) -> use end,
+ [{F(ElementI), lists:usort([ArgN || {ArgN, EI} <- ArgElementList,
+ EI =:= ElementI])} ||
+ ElementI <- lists:usort([EI || {_, EI} <- ArgElementList])].
+
+%% -> [{ArgN, ElementI}] where ElementI = 1 means there is an unknown
+%% opaque type in argument ArgN of the the contract/signature,
+%% and ElementI = 2 means that there is an unknown opaque type in
+%% argument ArgN of the the (current) argument types.
+find_unknown(ContractOrSigList, ArgTypes, Opaques, NoneArgNs) ->
+ ArgNs = lists:seq(1, length(ArgTypes)),
+ [{ArgN, ElementI} ||
+ ContractOrSig <- ContractOrSigList,
+ {E1, E2, ArgN} <- lists:zip3(ContractOrSig, ArgTypes, ArgNs),
+ lists:member(ArgN, NoneArgNs),
+ ElementI <- erl_types:t_find_unknown_opaque(E1, E2, Opaques)].
+
+is_opaque_type_test_problem(Fun, Args, ArgTypes, State) ->
+ case Fun of
+ {erlang, FN, 1} when FN =:= is_atom; FN =:= is_boolean;
+ FN =:= is_binary; FN =:= is_bitstring;
+ FN =:= is_float; FN =:= is_function;
+ FN =:= is_integer; FN =:= is_list;
+ FN =:= is_number; FN =:= is_pid; FN =:= is_port;
+ FN =:= is_reference; FN =:= is_tuple;
+ FN =:= is_map ->
+ type_test_opaque_arg(Args, ArgTypes, State#state.opaques);
+ {erlang, FN, 2} when FN =:= is_function ->
+ type_test_opaque_arg(Args, ArgTypes, State#state.opaques);
+ _ -> no
+ end.
+
+type_test_opaque_arg([], [], _Opaques) ->
+ no;
+type_test_opaque_arg([Arg|Args], [ArgType|ArgTypes], Opaques) ->
+ case erl_types:t_has_opaque_subtype(ArgType, Opaques) of
+ true -> {yes, Arg, ArgType};
+ false -> type_test_opaque_arg(Args, ArgTypes, Opaques)
+ end.
+
+expected_arg_triples(ArgNs, ArgTypes, State) ->
+ [begin
+ Arg = lists:nth(N, ArgTypes),
+ {N, Arg, format_type(Arg, State)}
+ end || N <- ArgNs].
+
+add_bif_warnings({erlang, Op, 2}, [T1, T2] = Ts, Tree, State)
+ when Op =:= '=:='; Op =:= '==' ->
+ Opaques = State#state.opaques,
+ Inf = t_inf(T1, T2, Opaques),
+ case
+ t_is_none(Inf) andalso (not any_none(Ts))
+ andalso (not is_int_float_eq_comp(T1, Op, T2, Opaques))
+ of
+ true ->
+ %% Give priority to opaque warning (as usual).
+ case erl_types:t_find_unknown_opaque(T1, T2, Opaques) of
+ [] ->
+ Args = comp_format_args([], T1, Op, T2, State),
+ state__add_warning(State, ?WARN_MATCHING, Tree, {exact_eq, Args});
+ Ns ->
+ Args = comp_format_args(Ns, T1, Op, T2, State),
+ state__add_warning(State, ?WARN_OPAQUE, Tree, {opaque_eq, Args})
+ end;
+ false ->
+ State
+ end;
+add_bif_warnings({erlang, Op, 2}, [T1, T2] = Ts, Tree, State)
+ when Op =:= '=/='; Op =:= '/=' ->
+ Opaques = State#state.opaques,
+ case
+ (not any_none(Ts))
+ andalso (not is_int_float_eq_comp(T1, Op, T2, Opaques))
+ of
+ true ->
+ case erl_types:t_find_unknown_opaque(T1, T2, Opaques) of
+ [] -> State;
+ Ns ->
+ Args = comp_format_args(Ns, T1, Op, T2, State),
+ state__add_warning(State, ?WARN_OPAQUE, Tree, {opaque_neq, Args})
+ end;
+ false ->
+ State
+ end;
+add_bif_warnings(_, _, _, State) ->
+ State.
+
+is_int_float_eq_comp(T1, Op, T2, Opaques) ->
+ (Op =:= '==' orelse Op =:= '/=') andalso
+ ((erl_types:t_is_float(T1, Opaques)
+ andalso t_is_integer(T2, Opaques)) orelse
+ (t_is_integer(T1, Opaques)
+ andalso erl_types:t_is_float(T2, Opaques))).
+
+comp_format_args([1|_], T1, Op, T2, State) ->
+ [format_type(T2, State), Op, format_type(T1, State)];
+comp_format_args(_, T1, Op, T2, State) ->
+ [format_type(T1, State), Op, format_type(T2, State)].
+
+%%----------------------------------------
+
+handle_bitstr(Tree, Map, State) ->
+ %% Construction of binaries.
+ Size = cerl:bitstr_size(Tree),
+ Val = cerl:bitstr_val(Tree),
+ BitstrType = cerl:concrete(cerl:bitstr_type(Tree)),
+ {State1, Map1, SizeType0} = traverse(Size, Map, State),
+ {State2, Map2, ValType0} = traverse(Val, Map1, State1),
+ case cerl:bitstr_bitsize(Tree) of
+ BitSz when BitSz =:= all orelse BitSz =:= utf ->
+ ValType =
+ case BitSz of
+ all ->
+ true = (BitstrType =:= binary),
+ t_inf(ValType0, t_bitstr());
+ utf ->
+ true = lists:member(BitstrType, [utf8, utf16, utf32]),
+ t_inf(ValType0, t_integer())
+ end,
+ Map3 = enter_type(Val, ValType, Map2),
+ case t_is_none(ValType) of
+ true ->
+ Msg = {bin_construction, ["value",
+ format_cerl(Val), format_cerl(Tree),
+ format_type(ValType0, State2)]},
+ State3 = state__add_warning(State2, ?WARN_BIN_CONSTRUCTION, Val, Msg),
+ {State3, Map3, t_none()};
+ false ->
+ {State2, Map3, t_bitstr()}
+ end;
+ BitSz when is_integer(BitSz) orelse BitSz =:= any ->
+ SizeType = t_inf(SizeType0, t_non_neg_integer()),
+ ValType =
+ case BitstrType of
+ binary -> t_inf(ValType0, t_bitstr());
+ float -> t_inf(ValType0, t_number());
+ integer -> t_inf(ValType0, t_integer())
+ end,
+ case any_none([SizeType, ValType]) of
+ true ->
+ {Msg, Offending} =
+ case t_is_none(SizeType) of
+ true ->
+ {{bin_construction,
+ ["size", format_cerl(Size), format_cerl(Tree),
+ format_type(SizeType0, State2)]},
+ Size};
+ false ->
+ {{bin_construction,
+ ["value", format_cerl(Val), format_cerl(Tree),
+ format_type(ValType0, State2)]},
+ Val}
+ end,
+ State3 = state__add_warning(State2, ?WARN_BIN_CONSTRUCTION,
+ Offending, Msg),
+ {State3, Map2, t_none()};
+ false ->
+ UnitVal = cerl:concrete(cerl:bitstr_unit(Tree)),
+ Opaques = State2#state.opaques,
+ NumberVals = t_number_vals(SizeType, Opaques),
+ {State3, Type} =
+ case t_contains_opaque(SizeType, Opaques) of
+ true ->
+ Msg = {opaque_size, [format_type(SizeType, State2),
+ format_cerl(Size)]},
+ {state__add_warning(State2, ?WARN_OPAQUE, Size, Msg),
+ t_none()};
+ false ->
+ case NumberVals of
+ [OneSize] -> {State2, t_bitstr(0, OneSize * UnitVal)};
+ unknown -> {State2, t_bitstr()};
+ _ ->
+ MinSize = erl_types:number_min(SizeType, Opaques),
+ {State2, t_bitstr(UnitVal, UnitVal * MinSize)}
+ end
+ end,
+ Map3 = enter_type_lists([Val, Size, Tree],
+ [ValType, SizeType, Type], Map2),
+ {State3, Map3, Type}
+ end
+ end.
+
+%%----------------------------------------
+
+handle_call(Tree, Map, State) ->
+ M = cerl:call_module(Tree),
+ F = cerl:call_name(Tree),
+ Args = cerl:call_args(Tree),
+ MFAList = [M, F|Args],
+ {State1, Map1, [MType0, FType0|As]} = traverse_list(MFAList, Map, State),
+ Opaques = State#state.opaques,
+ MType = t_inf(t_module(), MType0, Opaques),
+ FType = t_inf(t_atom(), FType0, Opaques),
+ Map2 = enter_type_lists([M, F], [MType, FType], Map1),
+ MOpaque = t_is_none(MType) andalso (not t_is_none(MType0)),
+ FOpaque = t_is_none(FType) andalso (not t_is_none(FType0)),
+ case any_none([MType, FType|As]) of
+ true ->
+ State2 =
+ if
+ MOpaque -> % This is a problem we just detected; not a known one
+ MS = format_cerl(M),
+ case t_is_none(t_inf(t_module(), MType0)) of
+ true ->
+ Msg = {app_call, [MS, format_cerl(F),
+ format_args(Args, As, State1),
+ MS, format_type(t_module(), State1),
+ format_type(MType0, State1)]},
+ state__add_warning(State1, ?WARN_FAILING_CALL, Tree, Msg);
+ false ->
+ Msg = {opaque_call, [MS, format_cerl(F),
+ format_args(Args, As, State1),
+ MS, format_type(MType0, State1)]},
+ state__add_warning(State1, ?WARN_FAILING_CALL, Tree, Msg)
+ end;
+ FOpaque ->
+ FS = format_cerl(F),
+ case t_is_none(t_inf(t_atom(), FType0)) of
+ true ->
+ Msg = {app_call, [format_cerl(M), FS,
+ format_args(Args, As, State1),
+ FS, format_type(t_atom(), State1),
+ format_type(FType0, State1)]},
+ state__add_warning(State1, ?WARN_FAILING_CALL, Tree, Msg);
+ false ->
+ Msg = {opaque_call, [format_cerl(M), FS,
+ format_args(Args, As, State1),
+ FS, format_type(FType0, State1)]},
+ state__add_warning(State1, ?WARN_FAILING_CALL, Tree, Msg)
+ end;
+ true -> State1
+ end,
+ {State2, Map2, t_none()};
+ false ->
+ case t_is_atom(MType) of
+ true ->
+ %% XXX: Consider doing this for all combinations of MF
+ case {t_atom_vals(MType), t_atom_vals(FType)} of
+ {[MAtom], [FAtom]} ->
+ FunInfo = [{remote, state__fun_info({MAtom, FAtom, length(Args)},
+ State1)}],
+ handle_apply_or_call(FunInfo, Args, As, Map2, Tree, State1);
+ {_MAtoms, _FAtoms} ->
+ {State1, Map2, t_any()}
+ end;
+ false ->
+ {State1, Map2, t_any()}
+ end
+ end.
+
+%%----------------------------------------
+
+handle_case(Tree, Map, State) ->
+ Arg = cerl:case_arg(Tree),
+ Clauses = filter_match_fail(cerl:case_clauses(Tree)),
+ {State1, Map1, ArgType} = SMA = traverse(Arg, Map, State),
+ case t_is_none_or_unit(ArgType) of
+ true -> SMA;
+ false ->
+ State2 =
+ case is_race_analysis_enabled(State) of
+ true ->
+ {RaceList, RaceListSize} = get_race_list_and_size(State1),
+ state__renew_race_list([beg_case|RaceList],
+ RaceListSize + 1, State1);
+ false -> State1
+ end,
+ Map2 = join_maps_begin(Map1),
+ {MapList, State3, Type} =
+ handle_clauses(Clauses, Arg, ArgType, ArgType, State2,
+ [], Map2, [], []),
+ Map3 = join_maps_end(MapList, Map2),
+ debug_pp_map(Map3),
+ {State3, Map3, Type}
+ end.
+
+%%----------------------------------------
+
+handle_cons(Tree, Map, State) ->
+ Hd = cerl:cons_hd(Tree),
+ Tl = cerl:cons_tl(Tree),
+ {State1, Map1, HdType} = traverse(Hd, Map, State),
+ {State2, Map2, TlType} = traverse(Tl, Map1, State1),
+ State3 =
+ case t_is_none(t_inf(TlType, t_list(), State2#state.opaques)) of
+ true ->
+ Msg = {improper_list_constr, [format_type(TlType, State2)]},
+ state__add_warning(State2, ?WARN_NON_PROPER_LIST, Tree, Msg);
+ false ->
+ State2
+ end,
+ Type = t_cons(HdType, TlType),
+ {State3, Map2, Type}.
+
+%%----------------------------------------
+
+handle_let(Tree, Map, State) ->
+ IsRaceAnalysisEnabled = is_race_analysis_enabled(State),
+ Arg = cerl:let_arg(Tree),
+ Vars = cerl:let_vars(Tree),
+ {Map0, State0} =
+ case cerl:is_c_var(Arg) of
+ true ->
+ [Var] = Vars,
+ {enter_subst(Var, Arg, Map),
+ case IsRaceAnalysisEnabled of
+ true ->
+ {RaceList, RaceListSize} = get_race_list_and_size(State),
+ state__renew_race_list(
+ [dialyzer_races:let_tag_new(Var, Arg)|RaceList],
+ RaceListSize + 1, State);
+ false -> State
+ end};
+ false -> {Map, State}
+ end,
+ Body = cerl:let_body(Tree),
+ {State1, Map1, ArgTypes} = SMA = traverse(Arg, Map0, State0),
+ State2 =
+ case IsRaceAnalysisEnabled andalso cerl:is_c_call(Arg) of
+ true ->
+ Mod = cerl:call_module(Arg),
+ Name = cerl:call_name(Arg),
+ case cerl:is_literal(Mod) andalso
+ cerl:concrete(Mod) =:= ets andalso
+ cerl:is_literal(Name) andalso
+ cerl:concrete(Name) =:= new of
+ true -> renew_race_public_tables(Vars, State1);
+ false -> State1
+ end;
+ false -> State1
+ end,
+ case t_is_none_or_unit(ArgTypes) of
+ true -> SMA;
+ false ->
+ Map2 = enter_type_lists(Vars, t_to_tlist(ArgTypes), Map1),
+ traverse(Body, Map2, State2)
+ end.
+
+%%----------------------------------------
+
+handle_module(Tree, Map, State) ->
+ %% By not including the variables in scope we can assure that we
+ %% will get the current function type when using the variables.
+ Defs = cerl:module_defs(Tree),
+ PartFun = fun({_Var, Fun}) ->
+ state__is_escaping(get_label(Fun), State)
+ end,
+ {Defs1, Defs2} = lists:partition(PartFun, Defs),
+ Letrec = cerl:c_letrec(Defs1, cerl:c_int(42)),
+ {State1, Map1, _FunTypes} = traverse(Letrec, Map, State),
+ %% Also add environments for the other top-level functions.
+ VarTypes = [{Var, state__fun_type(Fun, State1)} || {Var, Fun} <- Defs],
+ EnvMap = enter_type_list(VarTypes, Map),
+ FoldFun = fun({_Var, Fun}, AccState) ->
+ state__update_fun_env(Fun, EnvMap, AccState)
+ end,
+ State2 = lists:foldl(FoldFun, State1, Defs2),
+ {State2, Map1, t_any()}.
+
+%%----------------------------------------
+
+handle_receive(Tree, Map, State) ->
+ Clauses = filter_match_fail(cerl:receive_clauses(Tree)),
+ Timeout = cerl:receive_timeout(Tree),
+ State1 =
+ case is_race_analysis_enabled(State) of
+ true ->
+ {RaceList, RaceListSize} = get_race_list_and_size(State),
+ state__renew_race_list([beg_case|RaceList],
+ RaceListSize + 1, State);
+ false -> State
+ end,
+ {MapList, State2, ReceiveType} =
+ handle_clauses(Clauses, ?no_arg, t_any(), t_any(), State1, [], Map,
+ [], []),
+ Map1 = join_maps(MapList, Map),
+ {State3, Map2, TimeoutType} = traverse(Timeout, Map1, State2),
+ Opaques = State3#state.opaques,
+ case (t_is_atom(TimeoutType, Opaques) andalso
+ (t_atom_vals(TimeoutType, Opaques) =:= ['infinity'])) of
+ true ->
+ {State3, Map2, ReceiveType};
+ false ->
+ Action = cerl:receive_action(Tree),
+ {State4, Map3, ActionType} = traverse(Action, Map, State3),
+ Map4 = join_maps([Map3, Map1], Map),
+ Type = t_sup(ReceiveType, ActionType),
+ {State4, Map4, Type}
+ end.
+
+%%----------------------------------------
+
+handle_try(Tree, Map, State) ->
+ Arg = cerl:try_arg(Tree),
+ EVars = cerl:try_evars(Tree),
+ Vars = cerl:try_vars(Tree),
+ Body = cerl:try_body(Tree),
+ Handler = cerl:try_handler(Tree),
+ {State1, Map1, ArgType} = traverse(Arg, Map, State),
+ Map2 = mark_as_fresh(Vars, Map1),
+ {SuccState, SuccMap, SuccType} =
+ case bind_pat_vars(Vars, t_to_tlist(ArgType), [], Map2, State1) of
+ {error, _, _, _, _} ->
+ {State1, map__new(), t_none()};
+ {SuccMap1, VarTypes} ->
+ %% Try to bind the argument. Will only succeed if
+ %% it is a simple structured term.
+ SuccMap2 =
+ case bind_pat_vars_reverse([Arg], [t_product(VarTypes)], [],
+ SuccMap1, State1) of
+ {error, _, _, _, _} -> SuccMap1;
+ {SM, _} -> SM
+ end,
+ traverse(Body, SuccMap2, State1)
+ end,
+ ExcMap1 = mark_as_fresh(EVars, Map),
+ {State2, ExcMap2, HandlerType} = traverse(Handler, ExcMap1, SuccState),
+ TryType = t_sup(SuccType, HandlerType),
+ {State2, join_maps([ExcMap2, SuccMap], Map1), TryType}.
+
+%%----------------------------------------
+
+handle_map(Tree,Map,State) ->
+ Pairs = cerl:map_es(Tree),
+ Arg = cerl:map_arg(Tree),
+ {State1, Map1, ArgType} = traverse(Arg, Map, State),
+ ArgType1 = t_inf(t_map(), ArgType),
+ case t_is_none_or_unit(ArgType1) of
+ true ->
+ {State1, Map1, ArgType1};
+ false ->
+ {State2, Map2, TypePairs, ExactKeys} =
+ traverse_map_pairs(Pairs, Map1, State1, t_none(), [], []),
+ InsertPair = fun({KV,assoc,_},Acc) -> erl_types:t_map_put(KV,Acc);
+ ({KV,exact,KVTree},Acc) ->
+ case t_is_none(T=erl_types:t_map_update(KV,Acc)) of
+ true -> throw({none, Acc, KV, KVTree});
+ false -> T
+ end
+ end,
+ try lists:foldl(InsertPair, ArgType1, TypePairs)
+ of ResT ->
+ BindT = t_map([{K, t_any()} || K <- ExactKeys]),
+ case bind_pat_vars_reverse([Arg], [BindT], [], Map2, State2) of
+ {error, _, _, _, _} -> {State2, Map2, ResT};
+ {Map3, _} -> {State2, Map3, ResT}
+ end
+ catch {none, MapType, {K,_}, KVTree} ->
+ Msg2 = {map_update, [format_type(MapType, State2),
+ format_type(K, State2)]},
+ {state__add_warning(State2, ?WARN_MAP_CONSTRUCTION, KVTree, Msg2),
+ Map2, t_none()}
+ end
+ end.
+
+traverse_map_pairs([], Map, State, _ShadowKeys, PairAcc, KeyAcc) ->
+ {State, Map, lists:reverse(PairAcc), KeyAcc};
+traverse_map_pairs([Pair|Pairs], Map, State, ShadowKeys, PairAcc, KeyAcc) ->
+ Key = cerl:map_pair_key(Pair),
+ Val = cerl:map_pair_val(Pair),
+ Op = cerl:map_pair_op(Pair),
+ {State1, Map1, [K,V]} = traverse_list([Key,Val],Map,State),
+ KeyAcc1 =
+ case cerl:is_literal(Op) andalso cerl:concrete(Op) =:= exact andalso
+ t_is_singleton(K, State#state.opaques) andalso
+ t_is_none(t_inf(ShadowKeys, K)) of
+ true -> [K|KeyAcc];
+ false -> KeyAcc
+ end,
+ traverse_map_pairs(Pairs, Map1, State1, t_sup(K, ShadowKeys),
+ [{{K,V},cerl:concrete(Op),Pair}|PairAcc], KeyAcc1).
+
+%%----------------------------------------
+
+handle_tuple(Tree, Map, State) ->
+ Elements = cerl:tuple_es(Tree),
+ {State1, Map1, EsType} = traverse_list(Elements, Map, State),
+ TupleType = t_tuple(EsType),
+ case t_is_none(TupleType) of
+ true ->
+ {State1, Map1, t_none()};
+ false ->
+ %% Let's find out if this is a record
+ case Elements of
+ [Tag|Left] ->
+ case cerl:is_c_atom(Tag) andalso is_literal_record(Tree) of
+ true ->
+ TagVal = cerl:atom_val(Tag),
+ case state__lookup_record(TagVal, length(Left), State1) of
+ error -> {State1, Map1, TupleType};
+ {ok, RecType} ->
+ InfTupleType = t_inf(RecType, TupleType),
+ case t_is_none(InfTupleType) of
+ true ->
+ RecC = format_type(TupleType, State1),
+ FieldDiffs = format_field_diffs(TupleType, State1),
+ Msg = {record_constr, [RecC, FieldDiffs]},
+ State2 = state__add_warning(State1, ?WARN_MATCHING,
+ Tree, Msg),
+ {State2, Map1, t_none()};
+ false ->
+ case bind_pat_vars(Elements, t_tuple_args(RecType),
+ [], Map1, State1) of
+ {error, bind, ErrorPat, ErrorType, _} ->
+ Msg = {record_constr,
+ [TagVal, format_patterns(ErrorPat),
+ format_type(ErrorType, State1)]},
+ State2 = state__add_warning(State1, ?WARN_MATCHING,
+ Tree, Msg),
+ {State2, Map1, t_none()};
+ {error, opaque, ErrorPat, ErrorType, OpaqueType} ->
+ Msg = {opaque_match,
+ [format_patterns(ErrorPat),
+ format_type(ErrorType, State1),
+ format_type(OpaqueType, State1)]},
+ State2 = state__add_warning(State1, ?WARN_OPAQUE,
+ Tree, Msg),
+ {State2, Map1, t_none()};
+ {Map2, ETypes} ->
+ {State1, Map2, t_tuple(ETypes)}
+ end
+ end
+ end;
+ false ->
+ {State1, Map1, t_tuple(EsType)}
+ end;
+ [] ->
+ {State1, Map1, t_tuple([])}
+ end
+ end.
+
+%%----------------------------------------
+%% Clauses
+%%
+handle_clauses([C|Left], Arg, ArgType, OrigArgType, State, CaseTypes, MapIn,
+ Acc, ClauseAcc) ->
+ IsRaceAnalysisEnabled = is_race_analysis_enabled(State),
+ State1 =
+ case IsRaceAnalysisEnabled of
+ true ->
+ {RaceList, RaceListSize} = get_race_list_and_size(State),
+ state__renew_race_list(
+ [dialyzer_races:beg_clause_new(Arg, cerl:clause_pats(C),
+ cerl:clause_guard(C))|
+ RaceList], RaceListSize + 1,
+ State);
+ false -> State
+ end,
+ {State2, ClauseMap, BodyType, NewArgType} =
+ do_clause(C, Arg, ArgType, OrigArgType, MapIn, State1),
+ {NewClauseAcc, State3} =
+ case IsRaceAnalysisEnabled of
+ true ->
+ {RaceList1, RaceListSize1} = get_race_list_and_size(State2),
+ EndClause = dialyzer_races:end_clause_new(Arg, cerl:clause_pats(C),
+ cerl:clause_guard(C)),
+ {[EndClause|ClauseAcc],
+ state__renew_race_list([EndClause|RaceList1],
+ RaceListSize1 + 1, State2)};
+ false -> {ClauseAcc, State2}
+ end,
+ {NewCaseTypes, NewAcc} =
+ case t_is_none(BodyType) of
+ true -> {CaseTypes, Acc};
+ false -> {[BodyType|CaseTypes], [ClauseMap|Acc]}
+ end,
+ handle_clauses(Left, Arg, NewArgType, OrigArgType, State3,
+ NewCaseTypes, MapIn, NewAcc, NewClauseAcc);
+handle_clauses([], _Arg, _ArgType, _OrigArgType, State, CaseTypes, _MapIn, Acc,
+ ClauseAcc) ->
+ State1 =
+ case is_race_analysis_enabled(State) of
+ true ->
+ {RaceList, RaceListSize} = get_race_list_and_size(State),
+ state__renew_race_list(
+ [dialyzer_races:end_case_new(ClauseAcc)|RaceList],
+ RaceListSize + 1, State);
+ false -> State
+ end,
+ {lists:reverse(Acc), State1, t_sup(CaseTypes)}.
+
+do_clause(C, Arg, ArgType0, OrigArgType, Map, State) ->
+ Pats = cerl:clause_pats(C),
+ Guard = cerl:clause_guard(C),
+ Body = cerl:clause_body(C),
+ State1 =
+ case is_race_analysis_enabled(State) of
+ true ->
+ state__renew_fun_args(Pats, State);
+ false -> State
+ end,
+ Map0 = mark_as_fresh(Pats, Map),
+ Map1 = if Arg =:= ?no_arg -> Map0;
+ true -> bind_subst(Arg, Pats, Map0)
+ end,
+ BindRes =
+ case t_is_none(ArgType0) of
+ true ->
+ {error, bind, Pats, ArgType0, ArgType0};
+ false ->
+ ArgTypes =
+ case t_is_any(ArgType0) of
+ true -> [ArgType0 || _ <- Pats];
+ false -> t_to_tlist(ArgType0)
+ end,
+ bind_pat_vars(Pats, ArgTypes, [], Map1, State1)
+ end,
+ case BindRes of
+ {error, ErrorType, NewPats, Type, OpaqueTerm} ->
+ ?debug("Failed binding pattern: ~s\nto ~s\n",
+ [cerl_prettypr:format(C), format_type(ArgType0, State1)]),
+ case state__warning_mode(State1) of
+ false ->
+ {State1, Map, t_none(), ArgType0};
+ true ->
+ {Msg, Force} =
+ case t_is_none(ArgType0) of
+ true ->
+ PatString = format_patterns(Pats),
+ PatTypes = [PatString, format_type(OrigArgType, State1)],
+ %% See if this is covered by an earlier clause or if it
+ %% simply cannot match
+ OrigArgTypes =
+ case t_is_any(OrigArgType) of
+ true -> Any = t_any(), [Any || _ <- Pats];
+ false -> t_to_tlist(OrigArgType)
+ end,
+ Tag =
+ case bind_pat_vars(Pats, OrigArgTypes, [], Map1, State1) of
+ {error, bind, _, _, _} -> pattern_match;
+ {error, record, _, _, _} -> record_match;
+ {error, opaque, _, _, _} -> opaque_match;
+ {_, _} -> pattern_match_cov
+ end,
+ {{Tag, PatTypes}, false};
+ false ->
+ %% Try to find out if this is a default clause in a list
+ %% comprehension and suppress this. A real Hack(tm)
+ Force0 =
+ case is_compiler_generated(cerl:get_ann(C)) of
+ true ->
+ case Pats of
+ [Pat] ->
+ case cerl:is_c_cons(Pat) of
+ true ->
+ not (cerl:is_c_var(cerl:cons_hd(Pat)) andalso
+ cerl:is_c_var(cerl:cons_tl(Pat)) andalso
+ cerl:is_literal(Guard) andalso
+ (cerl:concrete(Guard) =:= true));
+ false ->
+ true
+ end;
+ [Pat0, Pat1] -> % binary comprehension
+ case cerl:is_c_cons(Pat0) of
+ true ->
+ not (cerl:is_c_var(cerl:cons_hd(Pat0)) andalso
+ cerl:is_c_var(cerl:cons_tl(Pat0)) andalso
+ cerl:is_c_var(Pat1) andalso
+ cerl:is_literal(Guard) andalso
+ (cerl:concrete(Guard) =:= true));
+ false ->
+ true
+ end;
+ _ -> true
+ end;
+ false ->
+ true
+ end,
+ PatString =
+ case ErrorType of
+ bind -> format_patterns(Pats);
+ record -> format_patterns(NewPats);
+ opaque -> format_patterns(NewPats)
+ end,
+ PatTypes = case ErrorType of
+ bind -> [PatString, format_type(ArgType0, State1)];
+ record -> [PatString, format_type(Type, State1)];
+ opaque -> [PatString, format_type(Type, State1),
+ format_type(OpaqueTerm, State1)]
+ end,
+ FailedTag = case ErrorType of
+ bind -> pattern_match;
+ record -> record_match;
+ opaque -> opaque_match
+ end,
+ {{FailedTag, PatTypes}, Force0}
+ end,
+ WarnType = case Msg of
+ {opaque_match, _} -> ?WARN_OPAQUE;
+ {pattern_match, _} -> ?WARN_MATCHING;
+ {record_match, _} -> ?WARN_MATCHING;
+ {pattern_match_cov, _} -> ?WARN_MATCHING
+ end,
+ {state__add_warning(State1, WarnType, C, Msg, Force),
+ Map, t_none(), ArgType0}
+ end;
+ {Map2, PatTypes} ->
+ Map3 =
+ case Arg =:= ?no_arg of
+ true -> Map2;
+ false ->
+ %% Try to bind the argument. Will only succeed if
+ %% it is a simple structured term.
+ case bind_pat_vars_reverse([Arg], [t_product(PatTypes)],
+ [], Map2, State1) of
+ {error, _, _, _, _} -> Map2;
+ {NewMap, _} -> NewMap
+ end
+ end,
+ NewArgType =
+ case Arg =:= ?no_arg of
+ true -> ArgType0;
+ false ->
+ GenType = dialyzer_typesig:get_safe_underapprox(Pats, Guard),
+ t_subtract(t_product(t_to_tlist(ArgType0)), GenType)
+ end,
+ case bind_guard(Guard, Map3, State1) of
+ {error, Reason} ->
+ ?debug("Failed guard: ~s\n",
+ [cerl_prettypr:format(C, [{hook, cerl_typean:pp_hook()}])]),
+ PatString = format_patterns(Pats),
+ DefaultMsg =
+ case Pats =:= [] of
+ true -> {guard_fail, []};
+ false ->
+ {guard_fail_pat, [PatString, format_type(ArgType0, State1)]}
+ end,
+ State2 =
+ case Reason of
+ none -> state__add_warning(State1, ?WARN_MATCHING, C, DefaultMsg);
+ {FailGuard, Msg} ->
+ case is_compiler_generated(cerl:get_ann(FailGuard)) of
+ false ->
+ WarnType = case Msg of
+ {guard_fail, _} -> ?WARN_MATCHING;
+ {neg_guard_fail, _} -> ?WARN_MATCHING;
+ {opaque_guard, _} -> ?WARN_OPAQUE
+ end,
+ state__add_warning(State1, WarnType, FailGuard, Msg);
+ true ->
+ state__add_warning(State1, ?WARN_MATCHING, C, Msg)
+ end
+ end,
+ {State2, Map, t_none(), NewArgType};
+ Map4 ->
+ {RetState, RetMap, BodyType} = traverse(Body, Map4, State1),
+ {RetState, RetMap, BodyType, NewArgType}
+ end
+ end.
+
+bind_subst(Arg, Pats, Map) ->
+ case cerl:type(Arg) of
+ values ->
+ bind_subst_list(cerl:values_es(Arg), Pats, Map);
+ var ->
+ [Pat] = Pats,
+ enter_subst(Arg, Pat, Map);
+ _ ->
+ Map
+ end.
+
+bind_subst_list([Arg|ArgLeft], [Pat|PatLeft], Map) ->
+ NewMap =
+ case {cerl:type(Arg), cerl:type(Pat)} of
+ {var, var} -> enter_subst(Arg, Pat, Map);
+ {var, alias} -> enter_subst(Arg, cerl:alias_pat(Pat), Map);
+ {literal, literal} -> Map;
+ {T, T} -> bind_subst_list(lists:flatten(cerl:subtrees(Arg)),
+ lists:flatten(cerl:subtrees(Pat)),
+ Map);
+ _ -> Map
+ end,
+ bind_subst_list(ArgLeft, PatLeft, NewMap);
+bind_subst_list([], [], Map) ->
+ Map.
+
+%%----------------------------------------
+%% Patterns
+%%
+
+bind_pat_vars(Pats, Types, Acc, Map, State) ->
+ try
+ bind_pat_vars(Pats, Types, Acc, Map, State, false)
+ catch
+ throw:Error ->
+ %% Error = {error, bind | opaque | record, ErrorPats, ErrorType}
+ Error
+ end.
+
+bind_pat_vars_reverse(Pats, Types, Acc, Map, State) ->
+ try
+ bind_pat_vars(Pats, Types, Acc, Map, State, true)
+ catch
+ throw:Error ->
+ %% Error = {error, bind | opaque | record, ErrorPats, ErrorType}
+ Error
+ end.
+
+bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
+ ?debug("Binding pat: ~w to ~s\n", [cerl:type(Pat), format_type(Type, State)]
+),
+ Opaques = State#state.opaques,
+ {NewMap, TypeOut} =
+ case cerl:type(Pat) of
+ alias ->
+ %% Map patterns are more allowing than the type of their literal. We
+ %% must unfold AliasPat if it is a literal.
+ AliasPat = dialyzer_utils:refold_pattern(cerl:alias_pat(Pat)),
+ Var = cerl:alias_var(Pat),
+ Map1 = enter_subst(Var, AliasPat, Map),
+ {Map2, [PatType]} = bind_pat_vars([AliasPat], [Type], [],
+ Map1, State, Rev),
+ {enter_type(Var, PatType, Map2), PatType};
+ binary ->
+ %% Cannot bind the binary if we are in reverse match since
+ %% binary patterns and binary construction are not symmetric.
+ case Rev of
+ true -> {Map, t_bitstr()};
+ false ->
+ BinType = t_inf(t_bitstr(), Type, Opaques),
+ case t_is_none(BinType) of
+ true ->
+ case t_find_opaque_mismatch(t_bitstr(), Type, Opaques) of
+ {ok, T1, T2} ->
+ bind_error([Pat], T1, T2, opaque);
+ error ->
+ bind_error([Pat], Type, t_none(), bind)
+ end;
+ false ->
+ Segs = cerl:binary_segments(Pat),
+ {Map1, SegTypes} = bind_bin_segs(Segs, BinType, Map, State),
+ {Map1, t_bitstr_concat(SegTypes)}
+ end
+ end;
+ cons ->
+ Cons = t_inf(Type, t_cons(), Opaques),
+ case t_is_none(Cons) of
+ true ->
+ bind_opaque_pats(t_cons(), Type, Pat, State);
+ false ->
+ {Map1, [HdType, TlType]} =
+ bind_pat_vars([cerl:cons_hd(Pat), cerl:cons_tl(Pat)],
+ [t_cons_hd(Cons, Opaques),
+ t_cons_tl(Cons, Opaques)],
+ [], Map, State, Rev),
+ {Map1, t_cons(HdType, TlType)}
+ end;
+ literal ->
+ Pat0 = dialyzer_utils:refold_pattern(Pat),
+ case cerl:is_literal(Pat0) of
+ true ->
+ Literal = literal_type(Pat),
+ case t_is_none(t_inf(Literal, Type, Opaques)) of
+ true ->
+ bind_opaque_pats(Literal, Type, Pat, State);
+ false -> {Map, Literal}
+ end;
+ false ->
+ %% Retry with the unfolded pattern
+ {Map1, [PatType]}
+ = bind_pat_vars([Pat0], [Type], [], Map, State, Rev),
+ {Map1, PatType}
+ end;
+ map ->
+ MapT = t_inf(Type, t_map(), Opaques),
+ case t_is_none(MapT) of
+ true ->
+ bind_opaque_pats(t_map(), Type, Pat, State);
+ false ->
+ case Rev of
+ %% TODO: Reverse matching (propagating a matched subset back to a value)
+ true -> {Map, MapT};
+ false ->
+ FoldFun =
+ fun(Pair, {MapAcc, ListAcc}) ->
+ %% Only exact (:=) can appear in patterns
+ exact = cerl:concrete(cerl:map_pair_op(Pair)),
+ Key = cerl:map_pair_key(Pair),
+ KeyType =
+ case cerl:type(Key) of
+ var ->
+ case state__lookup_type_for_letrec(Key, State) of
+ error -> lookup_type(Key, MapAcc);
+ {ok, RecType} -> RecType
+ end;
+ literal ->
+ literal_type(Key)
+ end,
+ Bind = erl_types:t_map_get(KeyType, MapT),
+ {MapAcc1, [ValType]} =
+ bind_pat_vars([cerl:map_pair_val(Pair)],
+ [Bind], [], MapAcc, State, Rev),
+ case t_is_singleton(KeyType, Opaques) of
+ true -> {MapAcc1, [{KeyType, ValType}|ListAcc]};
+ false -> {MapAcc1, ListAcc}
+ end
+ end,
+ {Map1, Pairs} = lists:foldl(FoldFun, {Map, []}, cerl:map_es(Pat)),
+ {Map1, t_inf(MapT, t_map(Pairs))}
+ end
+ end;
+ tuple ->
+ Es = cerl:tuple_es(Pat),
+ {TypedRecord, Prototype} =
+ case Es of
+ [] -> {false, t_tuple([])};
+ [Tag|Left] ->
+ case cerl:is_c_atom(Tag) andalso is_literal_record(Pat) of
+ true ->
+ TagAtom = cerl:atom_val(Tag),
+ case state__lookup_record(TagAtom, length(Left), State) of
+ error -> {false, t_tuple(length(Es))};
+ {ok, Record} ->
+ [_Head|AnyTail] = [t_any() || _ <- Es],
+ UntypedRecord = t_tuple([t_atom(TagAtom)|AnyTail]),
+ {not t_is_equal(Record, UntypedRecord), Record}
+ end;
+ false -> {false, t_tuple(length(Es))}
+ end
+ end,
+ Tuple = t_inf(Prototype, Type, Opaques),
+ case t_is_none(Tuple) of
+ true ->
+ bind_opaque_pats(Prototype, Type, Pat, State);
+ false ->
+ SubTuples = t_tuple_subtypes(Tuple, Opaques),
+ %% Need to call the top function to get the try-catch wrapper
+ MapJ = join_maps_begin(Map),
+ Results =
+ case Rev of
+ true ->
+ [bind_pat_vars_reverse(Es, t_tuple_args(SubTuple, Opaques),
+ [], MapJ, State)
+ || SubTuple <- SubTuples];
+ false ->
+ [bind_pat_vars(Es, t_tuple_args(SubTuple, Opaques), [],
+ MapJ, State)
+ || SubTuple <- SubTuples]
+ end,
+ case lists:keyfind(opaque, 2, Results) of
+ {error, opaque, _PatList, _Type, Opaque} ->
+ bind_error([Pat], Tuple, Opaque, opaque);
+ false ->
+ case [M || {M, _} <- Results, M =/= error] of
+ [] ->
+ case TypedRecord of
+ true -> bind_error([Pat], Tuple, Prototype, record);
+ false -> bind_error([Pat], Tuple, t_none(), bind)
+ end;
+ Maps ->
+ Map1 = join_maps_end(Maps, MapJ),
+ TupleType = t_sup([t_tuple(EsTypes)
+ || {M, EsTypes} <- Results, M =/= error]),
+ {Map1, TupleType}
+ end
+ end
+ end;
+ values ->
+ Es = cerl:values_es(Pat),
+ {Map1, EsTypes} =
+ bind_pat_vars(Es, t_to_tlist(Type), [], Map, State, Rev),
+ {Map1, t_product(EsTypes)};
+ var ->
+ VarType1 =
+ case state__lookup_type_for_letrec(Pat, State) of
+ error -> lookup_type(Pat, Map);
+ {ok, RecType} -> RecType
+ end,
+ %% Must do inf when binding args to pats. Vars in pats are fresh.
+ VarType2 = t_inf(VarType1, Type, Opaques),
+ case t_is_none(VarType2) of
+ true ->
+ case t_find_opaque_mismatch(VarType1, Type, Opaques) of
+ {ok, T1, T2} ->
+ bind_error([Pat], T1, T2, opaque);
+ error ->
+ bind_error([Pat], Type, t_none(), bind)
+ end;
+ false ->
+ Map1 = enter_type(Pat, VarType2, Map),
+ {Map1, VarType2}
+ end;
+ _Other ->
+ %% Catch all is needed when binding args to pats
+ ?debug("Failed match for ~p\n", [_Other]),
+ bind_error([Pat], Type, t_none(), bind)
+ end,
+ bind_pat_vars(PatLeft, TypeLeft, [TypeOut|Acc], NewMap, State, Rev);
+bind_pat_vars([], [], Acc, Map, _State, _Rev) ->
+ {Map, lists:reverse(Acc)}.
+
+bind_bin_segs(BinSegs, BinType, Map, State) ->
+ bind_bin_segs(BinSegs, BinType, [], Map, State).
+
+bind_bin_segs([Seg|Segs], BinType, Acc, Map, State) ->
+ Val = cerl:bitstr_val(Seg),
+ SegType = cerl:concrete(cerl:bitstr_type(Seg)),
+ UnitVal = cerl:concrete(cerl:bitstr_unit(Seg)),
+ case cerl:bitstr_bitsize(Seg) of
+ all ->
+ binary = SegType, [] = Segs, %% just an assert
+ T = t_inf(t_bitstr(UnitVal, 0), BinType),
+ {Map1, [Type]} = bind_pat_vars([Val], [T], [], Map, State, false),
+ Type1 = remove_local_opaque_types(Type, State#state.opaques),
+ bind_bin_segs(Segs, t_bitstr(0, 0), [Type1|Acc], Map1, State);
+ utf -> % XXX: possibly can be strengthened
+ true = lists:member(SegType, [utf8, utf16, utf32]),
+ {Map1, [_]} = bind_pat_vars([Val], [t_integer()], [], Map, State, false),
+ Type = t_binary(),
+ bind_bin_segs(Segs, BinType, [Type|Acc], Map1, State);
+ BitSz when is_integer(BitSz) orelse BitSz =:= any ->
+ Size = cerl:bitstr_size(Seg),
+ {Map1, [SizeType]} =
+ bind_pat_vars([Size], [t_non_neg_integer()], [], Map, State, false),
+ Opaques = State#state.opaques,
+ NumberVals = t_number_vals(SizeType, Opaques),
+ case t_contains_opaque(SizeType, Opaques) of
+ true -> bind_error([Seg], SizeType, t_none(), opaque);
+ false -> ok
+ end,
+ Type =
+ case NumberVals of
+ [OneSize] -> t_bitstr(0, UnitVal * OneSize);
+ _ -> % 'unknown' too
+ MinSize = erl_types:number_min(SizeType, Opaques),
+ t_bitstr(UnitVal, UnitVal * MinSize)
+ end,
+ ValConstr =
+ case SegType of
+ binary -> Type; %% The same constraints as for the whole bitstr
+ float -> t_float();
+ integer ->
+ case NumberVals of
+ unknown -> t_integer();
+ List ->
+ SizeVal = lists:max(List),
+ Flags = cerl:concrete(cerl:bitstr_flags(Seg)),
+ N = SizeVal * UnitVal,
+ case N >= ?BITS of
+ true ->
+ case lists:member(signed, Flags) of
+ true -> t_from_range(neg_inf, pos_inf);
+ false -> t_from_range(0, pos_inf)
+ end;
+ false ->
+ case lists:member(signed, Flags) of
+ true -> t_from_range(-(1 bsl (N - 1)), 1 bsl (N - 1) - 1);
+ false -> t_from_range(0, 1 bsl N - 1)
+ end
+ end
+ end
+ end,
+ {Map2, [_]} = bind_pat_vars([Val], [ValConstr], [], Map1, State, false),
+ NewBinType = t_bitstr_match(Type, BinType),
+ case t_is_none(NewBinType) of
+ true -> bind_error([Seg], BinType, t_none(), bind);
+ false -> bind_bin_segs(Segs, NewBinType, [Type|Acc], Map2, State)
+ end
+ end;
+bind_bin_segs([], _BinType, Acc, Map, _State) ->
+ {Map, lists:reverse(Acc)}.
+
+bind_error(Pats, Type, OpaqueType, Error0) ->
+ Error = case {Error0, Pats} of
+ {bind, [Pat]} ->
+ case is_literal_record(Pat) of
+ true -> record;
+ false -> Error0
+ end;
+ _ -> Error0
+ end,
+ throw({error, Error, Pats, Type, OpaqueType}).
+
+-spec bind_opaque_pats(type(), type(), cerl:c_literal(), state()) ->
+ no_return().
+
+bind_opaque_pats(GenType, Type, Pat, State) ->
+ case t_find_opaque_mismatch(GenType, Type, State#state.opaques) of
+ {ok, T1, T2} ->
+ bind_error([Pat], T1, T2, opaque);
+ error ->
+ bind_error([Pat], Type, t_none(), bind)
+ end.
+
+%%----------------------------------------
+%% Guards
+%%
+
+bind_guard(Guard, Map, State) ->
+ try bind_guard(Guard, Map, maps:new(), pos, State) of
+ {Map1, _Type} -> Map1
+ catch
+ throw:{fail, Warning} -> {error, Warning};
+ throw:{fatal_fail, Warning} -> {error, Warning}
+ end.
+
+bind_guard(Guard, Map, Env, Eval, State) ->
+ ?debug("Handling ~w guard: ~s\n",
+ [Eval, cerl_prettypr:format(Guard, [{noann, true}])]),
+ case cerl:type(Guard) of
+ binary ->
+ {Map, t_binary()};
+ 'case' ->
+ Arg = cerl:case_arg(Guard),
+ Clauses = cerl:case_clauses(Guard),
+ bind_guard_case_clauses(Arg, Clauses, Map, Env, Eval, State);
+ cons ->
+ Hd = cerl:cons_hd(Guard),
+ Tl = cerl:cons_tl(Guard),
+ {Map1, HdType} = bind_guard(Hd, Map, Env, dont_know, State),
+ {Map2, TlType} = bind_guard(Tl, Map1, Env, dont_know, State),
+ {Map2, t_cons(HdType, TlType)};
+ literal ->
+ {Map, literal_type(Guard)};
+ 'try' ->
+ Arg = cerl:try_arg(Guard),
+ [Var] = cerl:try_vars(Guard),
+ EVars = cerl:try_evars(Guard),
+ %%?debug("Storing: ~w\n", [Var]),
+ Map1 = join_maps_begin(Map),
+ Map2 = mark_as_fresh(EVars, Map1),
+ %% Visit handler first so we know if it should be ignored
+ {{HandlerMap, HandlerType}, HandlerE} =
+ try {bind_guard(cerl:try_handler(Guard), Map2, Env, Eval, State), none}
+ catch throw:HE ->
+ {{Map2, t_none()}, HE}
+ end,
+ BodyEnv = maps:put(get_label(Var), Arg, Env),
+ Wanted = case Eval of pos -> t_atom(true); neg -> t_atom(false);
+ dont_know -> t_any() end,
+ case t_is_none(t_inf(HandlerType, Wanted)) of
+ %% Handler won't save us; pretend it does not exist
+ true -> bind_guard(cerl:try_body(Guard), Map, BodyEnv, Eval, State);
+ false ->
+ {{BodyMap, BodyType}, BodyE} =
+ try {bind_guard(cerl:try_body(Guard), Map1, BodyEnv,
+ Eval, State), none}
+ catch throw:BE ->
+ {{Map1, t_none()}, BE}
+ end,
+ Map3 = join_maps_end([BodyMap, HandlerMap], Map1),
+ case t_is_none(Sup = t_sup(BodyType, HandlerType)) of
+ true ->
+ %% Pick a reason. N.B. We assume that the handler is always
+ %% compiler-generated if the body is; that way, we won't need to
+ %% check.
+ Fatality = case {BodyE, HandlerE} of
+ {{fatal_fail, _}, _} -> fatal_fail;
+ {_, {fatal_fail, _}} -> fatal_fail;
+ _ -> fail
+ end,
+ throw({Fatality,
+ case {BodyE, HandlerE} of
+ {{_, Rsn}, _} when Rsn =/= none -> Rsn;
+ {_, {_,Rsn}} -> Rsn;
+ _ -> none
+ end});
+ false -> {Map3, Sup}
+ end
+ end;
+ tuple ->
+ Es0 = cerl:tuple_es(Guard),
+ {Map1, Es} = bind_guard_list(Es0, Map, Env, dont_know, State),
+ {Map1, t_tuple(Es)};
+ map ->
+ case Eval of
+ dont_know -> handle_guard_map(Guard, Map, Env, State);
+ _PosOrNeg -> {Map, t_none()} %% Map exprs do not produce bools
+ end;
+ 'let' ->
+ Arg = cerl:let_arg(Guard),
+ [Var] = cerl:let_vars(Guard),
+ %%?debug("Storing: ~w\n", [Var]),
+ NewEnv = maps:put(get_label(Var), Arg, Env),
+ bind_guard(cerl:let_body(Guard), Map, NewEnv, Eval, State);
+ values ->
+ Es = cerl:values_es(Guard),
+ List = [bind_guard(V, Map, Env, dont_know, State) || V <- Es],
+ Type = t_product([T || {_, T} <- List]),
+ {Map, Type};
+ var ->
+ ?debug("Looking for var(~w)...", [cerl_trees:get_label(Guard)]),
+ case maps:find(get_label(Guard), Env) of
+ error ->
+ ?debug("Did not find it\n", []),
+ Type = lookup_type(Guard, Map),
+ Constr =
+ case Eval of
+ pos -> t_atom(true);
+ neg -> t_atom(false);
+ dont_know -> Type
+ end,
+ Inf = t_inf(Constr, Type),
+ {enter_type(Guard, Inf, Map), Inf};
+ {ok, Tree} ->
+ ?debug("Found it\n", []),
+ {Map1, Type} = bind_guard(Tree, Map, Env, Eval, State),
+ {enter_type(Guard, Type, Map1), Type}
+ end;
+ call ->
+ handle_guard_call(Guard, Map, Env, Eval, State)
+ end.
+
+handle_guard_call(Guard, Map, Env, Eval, State) ->
+ MFA = {cerl:atom_val(cerl:call_module(Guard)),
+ cerl:atom_val(cerl:call_name(Guard)),
+ cerl:call_arity(Guard)},
+ case MFA of
+ {erlang, F, 1} when F =:= is_atom; F =:= is_boolean;
+ F =:= is_binary; F =:= is_bitstring;
+ F =:= is_float; F =:= is_function;
+ F =:= is_integer; F =:= is_list; F =:= is_map;
+ F =:= is_number; F =:= is_pid; F =:= is_port;
+ F =:= is_reference; F =:= is_tuple ->
+ handle_guard_type_test(Guard, F, Map, Env, Eval, State);
+ {erlang, is_function, 2} ->
+ handle_guard_is_function(Guard, Map, Env, Eval, State);
+ MFA when (MFA =:= {erlang, internal_is_record, 3}) or
+ (MFA =:= {erlang, is_record, 3}) ->
+ handle_guard_is_record(Guard, Map, Env, Eval, State);
+ {erlang, '=:=', 2} ->
+ handle_guard_eqeq(Guard, Map, Env, Eval, State);
+ {erlang, '==', 2} ->
+ handle_guard_eq(Guard, Map, Env, Eval, State);
+ {erlang, 'and', 2} ->
+ handle_guard_and(Guard, Map, Env, Eval, State);
+ {erlang, 'or', 2} ->
+ handle_guard_or(Guard, Map, Env, Eval, State);
+ {erlang, 'not', 1} ->
+ handle_guard_not(Guard, Map, Env, Eval, State);
+ {erlang, Comp, 2} when Comp =:= '<'; Comp =:= '=<';
+ Comp =:= '>'; Comp =:= '>=' ->
+ handle_guard_comp(Guard, Comp, Map, Env, Eval, State);
+ _ ->
+ handle_guard_gen_fun(MFA, Guard, Map, Env, Eval, State)
+ end.
+
+handle_guard_gen_fun({M, F, A}, Guard, Map, Env, Eval, State) ->
+ Args = cerl:call_args(Guard),
+ {Map1, As} = bind_guard_list(Args, Map, Env, dont_know, State),
+ Opaques = State#state.opaques,
+ BifRet = erl_bif_types:type(M, F, A, As, Opaques),
+ case t_is_none(BifRet) of
+ true ->
+ %% Is this an error-bif?
+ case t_is_none(erl_bif_types:type(M, F, A)) of
+ true -> signal_guard_fail(Eval, Guard, As, State);
+ false -> signal_guard_fatal_fail(Eval, Guard, As, State)
+ end;
+ false ->
+ BifArgs = bif_args(M, F, A),
+ Map2 = enter_type_lists(Args, t_inf_lists(BifArgs, As, Opaques), Map1),
+ Ret =
+ case Eval of
+ pos -> t_inf(t_atom(true), BifRet);
+ neg -> t_inf(t_atom(false), BifRet);
+ dont_know -> BifRet
+ end,
+ case t_is_none(Ret) of
+ true ->
+ case Eval =:= pos of
+ true -> signal_guard_fail(Eval, Guard, As, State);
+ false -> throw({fail, none})
+ end;
+ false -> {Map2, Ret}
+ end
+ end.
+
+handle_guard_type_test(Guard, F, Map, Env, Eval, State) ->
+ [Arg] = cerl:call_args(Guard),
+ {Map1, ArgType} = bind_guard(Arg, Map, Env, dont_know, State),
+ case bind_type_test(Eval, F, ArgType, State) of
+ error ->
+ ?debug("Type test: ~w failed\n", [F]),
+ signal_guard_fail(Eval, Guard, [ArgType], State);
+ {ok, NewArgType, Ret} ->
+ ?debug("Type test: ~w succeeded, NewType: ~s, Ret: ~s\n",
+ [F, t_to_string(NewArgType), t_to_string(Ret)]),
+ {enter_type(Arg, NewArgType, Map1), Ret}
+ end.
+
+bind_type_test(Eval, TypeTest, ArgType, State) ->
+ Type = case TypeTest of
+ is_atom -> t_atom();
+ is_boolean -> t_boolean();
+ is_binary -> t_binary();
+ is_bitstring -> t_bitstr();
+ is_float -> t_float();
+ is_function -> t_fun();
+ is_integer -> t_integer();
+ is_list -> t_maybe_improper_list();
+ is_map -> t_map();
+ is_number -> t_number();
+ is_pid -> t_pid();
+ is_port -> t_port();
+ is_reference -> t_reference();
+ is_tuple -> t_tuple()
+ end,
+ case Eval of
+ pos ->
+ Inf = t_inf(Type, ArgType, State#state.opaques),
+ case t_is_none(Inf) of
+ true -> error;
+ false -> {ok, Inf, t_atom(true)}
+ end;
+ neg ->
+ Sub = t_subtract(ArgType, Type),
+ case t_is_none(Sub) of
+ true -> error;
+ false -> {ok, Sub, t_atom(false)}
+ end;
+ dont_know ->
+ {ok, ArgType, t_boolean()}
+ end.
+
+handle_guard_comp(Guard, Comp, Map, Env, Eval, State) ->
+ Args = cerl:call_args(Guard),
+ [Arg1, Arg2] = Args,
+ {Map1, ArgTypes} = bind_guard_list(Args, Map, Env, dont_know, State),
+ Opaques = State#state.opaques,
+ [Type1, Type2] = ArgTypes,
+ IsInt1 = t_is_integer(Type1, Opaques),
+ IsInt2 = t_is_integer(Type2, Opaques),
+ case {type(Arg1), type(Arg2)} of
+ {{literal, Lit1}, {literal, Lit2}} ->
+ case erlang:Comp(cerl:concrete(Lit1), cerl:concrete(Lit2)) of
+ true when Eval =:= pos -> {Map, t_atom(true)};
+ true when Eval =:= dont_know -> {Map, t_atom(true)};
+ true when Eval =:= neg -> {Map, t_atom(true)};
+ false when Eval =:= pos ->
+ signal_guard_fail(Eval, Guard, ArgTypes, State);
+ false when Eval =:= dont_know -> {Map, t_atom(false)};
+ false when Eval =:= neg -> {Map, t_atom(false)}
+ end;
+ {{literal, Lit1}, var} when IsInt1 andalso IsInt2 andalso (Eval =:= pos) ->
+ case bind_comp_literal_var(Lit1, Arg2, Type2, Comp, Map1, Opaques) of
+ error -> signal_guard_fail(Eval, Guard, ArgTypes, State);
+ {ok, NewMap} -> {NewMap, t_atom(true)}
+ end;
+ {var, {literal, Lit2}} when IsInt1 andalso IsInt2 andalso (Eval =:= pos) ->
+ case bind_comp_literal_var(Lit2, Arg1, Type1, invert_comp(Comp),
+ Map1, Opaques) of
+ error -> signal_guard_fail(Eval, Guard, ArgTypes, State);
+ {ok, NewMap} -> {NewMap, t_atom(true)}
+ end;
+ {_, _} ->
+ handle_guard_gen_fun({erlang, Comp, 2}, Guard, Map, Env, Eval, State)
+ end.
+
+invert_comp('=<') -> '>=';
+invert_comp('<') -> '>';
+invert_comp('>=') -> '=<';
+invert_comp('>') -> '<'.
+
+bind_comp_literal_var(Lit, Var, VarType, CompOp, Map, Opaques) ->
+ LitVal = cerl:concrete(Lit),
+ NewVarType =
+ case t_number_vals(VarType, Opaques) of
+ unknown ->
+ Range =
+ case CompOp of
+ '=<' -> t_from_range(LitVal, pos_inf);
+ '<' -> t_from_range(LitVal + 1, pos_inf);
+ '>=' -> t_from_range(neg_inf, LitVal);
+ '>' -> t_from_range(neg_inf, LitVal - 1)
+ end,
+ t_inf(Range, VarType, Opaques);
+ NumberVals ->
+ NewNumberVals = [X || X <- NumberVals, erlang:CompOp(LitVal, X)],
+ t_integers(NewNumberVals)
+ end,
+ case t_is_none(NewVarType) of
+ true -> error;
+ false -> {ok, enter_type(Var, NewVarType, Map)}
+ end.
+
+handle_guard_is_function(Guard, Map, Env, Eval, State) ->
+ Args = cerl:call_args(Guard),
+ {Map1, ArgTypes0} = bind_guard_list(Args, Map, Env, dont_know, State),
+ [FunType0, ArityType0] = ArgTypes0,
+ Opaques = State#state.opaques,
+ ArityType = t_inf(ArityType0, t_integer(), Opaques),
+ case t_is_none(ArityType) of
+ true -> signal_guard_fail(Eval, Guard, ArgTypes0, State);
+ false ->
+ FunTypeConstr =
+ case t_number_vals(ArityType, State#state.opaques) of
+ unknown -> t_fun();
+ Vals ->
+ t_sup([t_fun(lists:duplicate(X, t_any()), t_any()) || X <- Vals])
+ end,
+ FunType = t_inf(FunType0, FunTypeConstr, Opaques),
+ case t_is_none(FunType) of
+ true ->
+ case Eval of
+ pos -> signal_guard_fail(Eval, Guard, ArgTypes0, State);
+ neg -> {Map1, t_atom(false)};
+ dont_know -> {Map1, t_atom(false)}
+ end;
+ false ->
+ case Eval of
+ pos -> {enter_type_lists(Args, [FunType, ArityType], Map1),
+ t_atom(true)};
+ neg -> {Map1, t_atom(false)};
+ dont_know -> {Map1, t_boolean()}
+ end
+ end
+ end.
+
+handle_guard_is_record(Guard, Map, Env, Eval, State) ->
+ Args = cerl:call_args(Guard),
+ [Rec, Tag0, Arity0] = Args,
+ Tag = cerl:atom_val(Tag0),
+ Arity = cerl:int_val(Arity0),
+ {Map1, RecType} = bind_guard(Rec, Map, Env, dont_know, State),
+ ArityMin1 = Arity - 1,
+ Opaques = State#state.opaques,
+ Tuple = t_tuple([t_atom(Tag)|lists:duplicate(ArityMin1, t_any())]),
+ case t_is_none(t_inf(Tuple, RecType, Opaques)) of
+ true ->
+ case erl_types:t_has_opaque_subtype(RecType, Opaques) of
+ true ->
+ signal_guard_fail(Eval, Guard,
+ [RecType, t_from_term(Tag),
+ t_from_term(Arity)],
+ State);
+ false ->
+ case Eval of
+ pos -> signal_guard_fail(Eval, Guard,
+ [RecType, t_from_term(Tag),
+ t_from_term(Arity)],
+ State);
+ neg -> {Map1, t_atom(false)};
+ dont_know -> {Map1, t_atom(false)}
+ end
+ end;
+ false ->
+ TupleType =
+ case state__lookup_record(Tag, ArityMin1, State) of
+ error -> Tuple;
+ {ok, Prototype} -> Prototype
+ end,
+ Type = t_inf(TupleType, RecType, State#state.opaques),
+ case t_is_none(Type) of
+ true ->
+ %% No special handling of opaque errors.
+ FArgs = "record " ++ format_type(RecType, State),
+ Msg = {record_matching, [FArgs, Tag]},
+ throw({fail, {Guard, Msg}});
+ false ->
+ case Eval of
+ pos -> {enter_type(Rec, Type, Map1), t_atom(true)};
+ neg -> {Map1, t_atom(false)};
+ dont_know -> {Map1, t_boolean()}
+ end
+ end
+ end.
+
+handle_guard_eq(Guard, Map, Env, Eval, State) ->
+ [Arg1, Arg2] = cerl:call_args(Guard),
+ case {type(Arg1), type(Arg2)} of
+ {{literal, Lit1}, {literal, Lit2}} ->
+ case cerl:concrete(Lit1) =:= cerl:concrete(Lit2) of
+ true ->
+ if
+ Eval =:= pos -> {Map, t_atom(true)};
+ Eval =:= neg ->
+ ArgTypes = [t_from_term(cerl:concrete(Lit1)),
+ t_from_term(cerl:concrete(Lit2))],
+ signal_guard_fail(Eval, Guard, ArgTypes, State);
+ Eval =:= dont_know -> {Map, t_atom(true)}
+ end;
+ false ->
+ if
+ Eval =:= neg -> {Map, t_atom(false)};
+ Eval =:= dont_know -> {Map, t_atom(false)};
+ Eval =:= pos ->
+ ArgTypes = [t_from_term(cerl:concrete(Lit1)),
+ t_from_term(cerl:concrete(Lit2))],
+ signal_guard_fail(Eval, Guard, ArgTypes, State)
+ end
+ end;
+ {{literal, Lit1}, _} when Eval =:= pos ->
+ case cerl:concrete(Lit1) of
+ Atom when is_atom(Atom) ->
+ bind_eqeq_guard_lit_other(Guard, Lit1, Arg2, Map, Env, State);
+ [] ->
+ bind_eqeq_guard_lit_other(Guard, Lit1, Arg2, Map, Env, State);
+ _ ->
+ bind_eq_guard(Guard, Lit1, Arg2, Map, Env, Eval, State)
+ end;
+ {_, {literal, Lit2}} when Eval =:= pos ->
+ case cerl:concrete(Lit2) of
+ Atom when is_atom(Atom) ->
+ bind_eqeq_guard_lit_other(Guard, Lit2, Arg1, Map, Env, State);
+ [] ->
+ bind_eqeq_guard_lit_other(Guard, Lit2, Arg1, Map, Env, State);
+ _ ->
+ bind_eq_guard(Guard, Arg1, Lit2, Map, Env, Eval, State)
+ end;
+ {_, _} ->
+ bind_eq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State)
+ end.
+
+bind_eq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State) ->
+ {Map1, Type1} = bind_guard(Arg1, Map, Env, dont_know, State),
+ {Map2, Type2} = bind_guard(Arg2, Map1, Env, dont_know, State),
+ Opaques = State#state.opaques,
+ case
+ t_is_nil(Type1, Opaques) orelse t_is_nil(Type2, Opaques)
+ orelse t_is_atom(Type1, Opaques) orelse t_is_atom(Type2, Opaques)
+ of
+ true -> bind_eqeq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State);
+ false ->
+ %% XXX. Is this test OK?
+ OpArgs = erl_types:t_find_unknown_opaque(Type1, Type2, Opaques),
+ case OpArgs =:= [] of
+ true ->
+ case Eval of
+ pos -> {Map2, t_atom(true)};
+ neg -> {Map2, t_atom(false)};
+ dont_know -> {Map2, t_boolean()}
+ end;
+ false ->
+ signal_guard_fail(Eval, Guard, [Type1, Type2], State)
+ end
+ end.
+
+handle_guard_eqeq(Guard, Map, Env, Eval, State) ->
+ [Arg1, Arg2] = cerl:call_args(Guard),
+ case {type(Arg1), type(Arg2)} of
+ {{literal, Lit1}, {literal, Lit2}} ->
+
+ case cerl:concrete(Lit1) =:= cerl:concrete(Lit2) of
+ true ->
+ if Eval =:= neg ->
+ ArgTypes = [t_from_term(cerl:concrete(Lit1)),
+ t_from_term(cerl:concrete(Lit2))],
+ signal_guard_fail(Eval, Guard, ArgTypes, State);
+ Eval =:= pos -> {Map, t_atom(true)};
+ Eval =:= dont_know -> {Map, t_atom(true)}
+ end;
+ false ->
+ if Eval =:= neg -> {Map, t_atom(false)};
+ Eval =:= dont_know -> {Map, t_atom(false)};
+ Eval =:= pos ->
+ ArgTypes = [t_from_term(cerl:concrete(Lit1)),
+ t_from_term(cerl:concrete(Lit2))],
+ signal_guard_fail(Eval, Guard, ArgTypes, State)
+ end
+ end;
+ {{literal, Lit1}, _} when Eval =:= pos ->
+ bind_eqeq_guard_lit_other(Guard, Lit1, Arg2, Map, Env, State);
+ {_, {literal, Lit2}} when Eval =:= pos ->
+ bind_eqeq_guard_lit_other(Guard, Lit2, Arg1, Map, Env, State);
+ {_, _} ->
+ bind_eqeq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State)
+ end.
+
+bind_eqeq_guard(Guard, Arg1, Arg2, Map, Env, Eval, State) ->
+ {Map1, Type1} = bind_guard(Arg1, Map, Env, dont_know, State),
+ {Map2, Type2} = bind_guard(Arg2, Map1, Env, dont_know, State),
+ ?debug("Types are:~s =:= ~s\n", [t_to_string(Type1),
+ t_to_string(Type2)]),
+ Opaques = State#state.opaques,
+ Inf = t_inf(Type1, Type2, Opaques),
+ case t_is_none(Inf) of
+ true ->
+ OpArgs = erl_types:t_find_unknown_opaque(Type1, Type2, Opaques),
+ case OpArgs =:= [] of
+ true ->
+ case Eval of
+ neg -> {Map2, t_atom(false)};
+ dont_know -> {Map2, t_atom(false)};
+ pos -> signal_guard_fail(Eval, Guard, [Type1, Type2], State)
+ end;
+ false ->
+ signal_guard_fail(Eval, Guard, [Type1, Type2], State)
+ end;
+ false ->
+ case Eval of
+ pos ->
+ case {cerl:type(Arg1), cerl:type(Arg2)} of
+ {var, var} ->
+ Map3 = enter_subst(Arg1, Arg2, Map2),
+ Map4 = enter_type(Arg2, Inf, Map3),
+ {Map4, t_atom(true)};
+ {var, _} ->
+ Map3 = enter_type(Arg1, Inf, Map2),
+ {Map3, t_atom(true)};
+ {_, var} ->
+ Map3 = enter_type(Arg2, Inf, Map2),
+ {Map3, t_atom(true)};
+ {_, _} ->
+ {Map2, t_atom(true)}
+ end;
+ neg ->
+ {Map2, t_atom(false)};
+ dont_know ->
+ {Map2, t_boolean()}
+ end
+ end.
+
+bind_eqeq_guard_lit_other(Guard, Arg1, Arg2, Map, Env, State) ->
+ Eval = dont_know,
+ Opaques = State#state.opaques,
+ case cerl:concrete(Arg1) of
+ true ->
+ {_, Type} = MT = bind_guard(Arg2, Map, Env, pos, State),
+ case t_is_any_atom(true, Type, Opaques) of
+ true -> MT;
+ false ->
+ {_, Type0} = bind_guard(Arg2, Map, Env, Eval, State),
+ signal_guard_fail(Eval, Guard, [Type0, t_atom(true)], State)
+ end;
+ false ->
+ {Map1, Type} = bind_guard(Arg2, Map, Env, neg, State),
+ case t_is_any_atom(false, Type, Opaques) of
+ true -> {Map1, t_atom(true)};
+ false ->
+ {_, Type0} = bind_guard(Arg2, Map, Env, Eval, State),
+ signal_guard_fail(Eval, Guard, [Type0, t_atom(false)], State)
+ end;
+ Term ->
+ LitType = t_from_term(Term),
+ {Map1, Type} = bind_guard(Arg2, Map, Env, Eval, State),
+ case t_is_subtype(LitType, Type) of
+ false -> signal_guard_fail(Eval, Guard, [Type, LitType], State);
+ true ->
+ case cerl:is_c_var(Arg2) of
+ true -> {enter_type(Arg2, LitType, Map1), t_atom(true)};
+ false -> {Map1, t_atom(true)}
+ end
+ end
+ end.
+
+handle_guard_and(Guard, Map, Env, Eval, State) ->
+ [Arg1, Arg2] = cerl:call_args(Guard),
+ Opaques = State#state.opaques,
+ case Eval of
+ pos ->
+ {Map1, Type1} = bind_guard(Arg1, Map, Env, Eval, State),
+ case t_is_any_atom(true, Type1, Opaques) of
+ false -> signal_guard_fail(Eval, Guard, [Type1, t_any()], State);
+ true ->
+ {Map2, Type2} = bind_guard(Arg2, Map1, Env, Eval, State),
+ case t_is_any_atom(true, Type2, Opaques) of
+ false -> signal_guard_fail(Eval, Guard, [Type1, Type2], State);
+ true -> {Map2, t_atom(true)}
+ end
+ end;
+ neg ->
+ MapJ = join_maps_begin(Map),
+ {Map1, Type1} =
+ try bind_guard(Arg1, MapJ, Env, neg, State)
+ catch throw:{fail, _} -> bind_guard(Arg2, MapJ, Env, pos, State)
+ end,
+ {Map2, Type2} =
+ try bind_guard(Arg2, MapJ, Env, neg, State)
+ catch throw:{fail, _} -> bind_guard(Arg1, MapJ, Env, pos, State)
+ end,
+ case
+ t_is_any_atom(false, Type1, Opaques)
+ orelse t_is_any_atom(false, Type2, Opaques)
+ of
+ true -> {join_maps_end([Map1, Map2], MapJ), t_atom(false)};
+ false -> signal_guard_fail(Eval, Guard, [Type1, Type2], State)
+ end;
+ dont_know ->
+ MapJ = join_maps_begin(Map),
+ {Map1, Type1} = bind_guard(Arg1, MapJ, Env, dont_know, State),
+ {Map2, Type2} = bind_guard(Arg2, MapJ, Env, dont_know, State),
+ Bool1 = t_inf(Type1, t_boolean()),
+ Bool2 = t_inf(Type2, t_boolean()),
+ case t_is_none(Bool1) orelse t_is_none(Bool2) of
+ true -> throw({fatal_fail, none});
+ false ->
+ NewMap = join_maps_end([Map1, Map2], MapJ),
+ NewType =
+ case {t_atom_vals(Bool1, Opaques), t_atom_vals(Bool2, Opaques)} of
+ {['true'] , ['true'] } -> t_atom(true);
+ {['false'], _ } -> t_atom(false);
+ {_ , ['false']} -> t_atom(false);
+ {unknown , _ } ->
+ signal_guard_fail(Eval, Guard, [Type1, Type2], State);
+ {_ , unknown } ->
+ signal_guard_fail(Eval, Guard, [Type1, Type2], State);
+ {_ , _ } -> t_boolean()
+
+ end,
+ {NewMap, NewType}
+ end
+ end.
+
+handle_guard_or(Guard, Map, Env, Eval, State) ->
+ [Arg1, Arg2] = cerl:call_args(Guard),
+ Opaques = State#state.opaques,
+ case Eval of
+ pos ->
+ MapJ = join_maps_begin(Map),
+ {Map1, Bool1} =
+ try bind_guard(Arg1, MapJ, Env, pos, State)
+ catch
+ throw:{fail,_} -> bind_guard(Arg1, MapJ, Env, dont_know, State)
+ end,
+ {Map2, Bool2} =
+ try bind_guard(Arg2, MapJ, Env, pos, State)
+ catch
+ throw:{fail,_} -> bind_guard(Arg2, MapJ, Env, dont_know, State)
+ end,
+ case
+ ((t_is_any_atom(true, Bool1, Opaques)
+ andalso t_is_boolean(Bool2, Opaques))
+ orelse
+ (t_is_any_atom(true, Bool2, Opaques)
+ andalso t_is_boolean(Bool1, Opaques)))
+ of
+ true -> {join_maps_end([Map1, Map2], MapJ), t_atom(true)};
+ false -> signal_guard_fail(Eval, Guard, [Bool1, Bool2], State)
+ end;
+ neg ->
+ {Map1, Type1} = bind_guard(Arg1, Map, Env, neg, State),
+ case t_is_any_atom(false, Type1, Opaques) of
+ false -> signal_guard_fail(Eval, Guard, [Type1, t_any()], State);
+ true ->
+ {Map2, Type2} = bind_guard(Arg2, Map1, Env, neg, State),
+ case t_is_any_atom(false, Type2, Opaques) of
+ false -> signal_guard_fail(Eval, Guard, [Type1, Type2], State);
+ true -> {Map2, t_atom(false)}
+ end
+ end;
+ dont_know ->
+ MapJ = join_maps_begin(Map),
+ {Map1, Type1} = bind_guard(Arg1, MapJ, Env, dont_know, State),
+ {Map2, Type2} = bind_guard(Arg2, MapJ, Env, dont_know, State),
+ Bool1 = t_inf(Type1, t_boolean()),
+ Bool2 = t_inf(Type2, t_boolean()),
+ case t_is_none(Bool1) orelse t_is_none(Bool2) of
+ true -> throw({fatal_fail, none});
+ false ->
+ NewMap = join_maps_end([Map1, Map2], MapJ),
+ NewType =
+ case {t_atom_vals(Bool1, Opaques), t_atom_vals(Bool2, Opaques)} of
+ {['false'], ['false']} -> t_atom(false);
+ {['true'] , _ } -> t_atom(true);
+ {_ , ['true'] } -> t_atom(true);
+ {unknown , _ } ->
+ signal_guard_fail(Eval, Guard, [Type1, Type2], State);
+ {_ , unknown } ->
+ signal_guard_fail(Eval, Guard, [Type1, Type2], State);
+ {_ , _ } -> t_boolean()
+ end,
+ {NewMap, NewType}
+ end
+ end.
+
+handle_guard_not(Guard, Map, Env, Eval, State) ->
+ [Arg] = cerl:call_args(Guard),
+ Opaques = State#state.opaques,
+ case Eval of
+ neg ->
+ {Map1, Type} = bind_guard(Arg, Map, Env, pos, State),
+ case t_is_any_atom(true, Type, Opaques) of
+ true -> {Map1, t_atom(false)};
+ false ->
+ {_, Type0} = bind_guard(Arg, Map, Env, Eval, State),
+ signal_guard_fail(Eval, Guard, [Type0], State)
+ end;
+ pos ->
+ {Map1, Type} = bind_guard(Arg, Map, Env, neg, State),
+ case t_is_any_atom(false, Type, Opaques) of
+ true -> {Map1, t_atom(true)};
+ false ->
+ {_, Type0} = bind_guard(Arg, Map, Env, Eval, State),
+ signal_guard_fail(Eval, Guard, [Type0], State)
+ end;
+ dont_know ->
+ {Map1, Type} = bind_guard(Arg, Map, Env, dont_know, State),
+ Bool = t_inf(Type, t_boolean()),
+ case t_is_none(Bool) of
+ true -> throw({fatal_fail, none});
+ false ->
+ case t_atom_vals(Bool, Opaques) of
+ ['true'] -> {Map1, t_atom(false)};
+ ['false'] -> {Map1, t_atom(true)};
+ [_, _] -> {Map1, Bool};
+ unknown -> signal_guard_fail(Eval, Guard, [Type], State)
+ end
+ end
+ end.
+
+bind_guard_list(Guards, Map, Env, Eval, State) ->
+ bind_guard_list(Guards, Map, Env, Eval, State, []).
+
+bind_guard_list([G|Gs], Map, Env, Eval, State, Acc) ->
+ {Map1, T} = bind_guard(G, Map, Env, Eval, State),
+ bind_guard_list(Gs, Map1, Env, Eval, State, [T|Acc]);
+bind_guard_list([], Map, _Env, _Eval, _State, Acc) ->
+ {Map, lists:reverse(Acc)}.
+
+handle_guard_map(Guard, Map, Env, State) ->
+ Pairs = cerl:map_es(Guard),
+ Arg = cerl:map_arg(Guard),
+ {Map1, ArgType0} = bind_guard(Arg, Map, Env, dont_know, State),
+ ArgType1 = t_inf(t_map(), ArgType0),
+ case t_is_none_or_unit(ArgType1) of
+ true -> {Map1, t_none()};
+ false ->
+ {Map2, TypePairs} = bind_guard_map_pairs(Pairs, Map1, Env, State, []),
+ {Map2, lists:foldl(fun({KV,assoc},Acc) -> erl_types:t_map_put(KV,Acc);
+ ({KV,exact},Acc) -> erl_types:t_map_update(KV,Acc)
+ end, ArgType1, TypePairs)}
+ end.
+
+bind_guard_map_pairs([], Map, _Env, _State, PairAcc) ->
+ {Map, lists:reverse(PairAcc)};
+bind_guard_map_pairs([Pair|Pairs], Map, Env, State, PairAcc) ->
+ Key = cerl:map_pair_key(Pair),
+ Val = cerl:map_pair_val(Pair),
+ Op = cerl:map_pair_op(Pair),
+ {Map1, [K,V]} = bind_guard_list([Key,Val],Map,Env,dont_know,State),
+ bind_guard_map_pairs(Pairs, Map1, Env, State,
+ [{{K,V},cerl:concrete(Op)}|PairAcc]).
+
+-type eval() :: 'pos' | 'neg' | 'dont_know'.
+
+-spec signal_guard_fail(eval(), cerl:c_call(), [type()],
+ state()) -> no_return().
+
+signal_guard_fail(Eval, Guard, ArgTypes, State) ->
+ signal_guard_failure(Eval, Guard, ArgTypes, fail, State).
+
+-spec signal_guard_fatal_fail(eval(), cerl:c_call(), [erl_types:erl_type()],
+ state()) -> no_return().
+
+signal_guard_fatal_fail(Eval, Guard, ArgTypes, State) ->
+ signal_guard_failure(Eval, Guard, ArgTypes, fatal_fail, State).
+
+signal_guard_failure(Eval, Guard, ArgTypes, Tag, State) ->
+ Args = cerl:call_args(Guard),
+ F = cerl:atom_val(cerl:call_name(Guard)),
+ {M, F, A} = MFA = {cerl:atom_val(cerl:call_module(Guard)), F, length(Args)},
+ Opaques = State#state.opaques,
+ {Kind, XInfo} =
+ case erl_bif_types:opaque_args(M, F, A, ArgTypes, Opaques) of
+ [] ->
+ {case Eval of
+ neg -> neg_guard_fail;
+ pos -> guard_fail;
+ dont_know -> guard_fail
+ end,
+ []};
+ Ns -> {opaque_guard, [Ns]}
+ end,
+ FArgs =
+ case is_infix_op(MFA) of
+ true ->
+ [ArgType1, ArgType2] = ArgTypes,
+ [Arg1, Arg2] = Args,
+ [format_args_1([Arg1], [ArgType1], State),
+ atom_to_list(F),
+ format_args_1([Arg2], [ArgType2], State)] ++ XInfo;
+ false ->
+ [F, format_args(Args, ArgTypes, State)]
+ end,
+ Msg = {Kind, FArgs},
+ throw({Tag, {Guard, Msg}}).
+
+is_infix_op({erlang, '=:=', 2}) -> true;
+is_infix_op({erlang, '==', 2}) -> true;
+is_infix_op({erlang, '=/=', 2}) -> true;
+is_infix_op({erlang, '=/', 2}) -> true;
+is_infix_op({erlang, '<', 2}) -> true;
+is_infix_op({erlang, '=<', 2}) -> true;
+is_infix_op({erlang, '>', 2}) -> true;
+is_infix_op({erlang, '>=', 2}) -> true;
+is_infix_op({M, F, A}) when is_atom(M), is_atom(F),
+ is_integer(A), 0 =< A, A =< 255 -> false.
+
+bif_args(M, F, A) ->
+ case erl_bif_types:arg_types(M, F, A) of
+ unknown -> lists:duplicate(A, t_any());
+ List -> List
+ end.
+
+bind_guard_case_clauses(Arg, Clauses, Map0, Env, Eval, State) ->
+ Clauses1 = filter_fail_clauses(Clauses),
+ Map = join_maps_begin(Map0),
+ {GenMap, GenArgType} = bind_guard(Arg, Map, Env, dont_know, State),
+ bind_guard_case_clauses(GenArgType, GenMap, Arg, Clauses1, Map, Env, Eval,
+ t_none(), [], State).
+
+filter_fail_clauses([Clause|Left]) ->
+ case (cerl:clause_pats(Clause) =:= []) of
+ true ->
+ Body = cerl:clause_body(Clause),
+ case cerl:is_literal(Body) andalso (cerl:concrete(Body) =:= fail) orelse
+ cerl:is_c_primop(Body) andalso
+ (cerl:atom_val(cerl:primop_name(Body)) =:= match_fail) of
+ true -> filter_fail_clauses(Left);
+ false -> [Clause|filter_fail_clauses(Left)]
+ end;
+ false ->
+ [Clause|filter_fail_clauses(Left)]
+ end;
+filter_fail_clauses([]) ->
+ [].
+
+bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left],
+ Map, Env, Eval, AccType, AccMaps, State) ->
+ Pats = cerl:clause_pats(Clause),
+ {NewMap0, ArgType} =
+ case Pats of
+ [Pat] ->
+ case cerl:is_literal(Pat) of
+ true ->
+ try
+ case cerl:concrete(Pat) of
+ true -> bind_guard(ArgExpr, Map, Env, pos, State);
+ false -> bind_guard(ArgExpr, Map, Env, neg, State);
+ _ -> {GenMap, GenArgType}
+ end
+ catch
+ throw:{fail, _} -> {none, GenArgType}
+ end;
+ false ->
+ {GenMap, GenArgType}
+ end;
+ _ -> {GenMap, GenArgType}
+ end,
+ NewMap1 =
+ case Pats =:= [] of
+ true -> NewMap0;
+ false ->
+ case t_is_none(ArgType) of
+ true -> none;
+ false ->
+ ArgTypes = case t_is_any(ArgType) of
+ true -> Any = t_any(), [Any || _ <- Pats];
+ false -> t_to_tlist(ArgType)
+ end,
+ case bind_pat_vars(Pats, ArgTypes, [], NewMap0, State) of
+ {error, _, _, _, _} -> none;
+ {PatMap, _PatTypes} -> PatMap
+ end
+ end
+ end,
+ Guard = cerl:clause_guard(Clause),
+ GenPatType = dialyzer_typesig:get_safe_underapprox(Pats, Guard),
+ NewGenArgType = t_subtract(GenArgType, GenPatType),
+ case (NewMap1 =:= none) orelse t_is_none(GenArgType) of
+ true ->
+ bind_guard_case_clauses(NewGenArgType, GenMap, ArgExpr, Left, Map, Env,
+ Eval, AccType, AccMaps, State);
+ false ->
+ {NewAccType, NewAccMaps} =
+ try
+ {NewMap2, GuardType} = bind_guard(Guard, NewMap1, Env, pos, State),
+ case t_is_none(t_inf(t_atom(true), GuardType)) of
+ true -> throw({fail, none});
+ false -> ok
+ end,
+ {NewMap3, CType} = bind_guard(cerl:clause_body(Clause), NewMap2,
+ Env, Eval, State),
+ Opaques = State#state.opaques,
+ case Eval of
+ pos ->
+ case t_is_any_atom(true, CType, Opaques) of
+ true -> ok;
+ false -> throw({fail, none})
+ end;
+ neg ->
+ case t_is_any_atom(false, CType, Opaques) of
+ true -> ok;
+ false -> throw({fail, none})
+ end;
+ dont_know ->
+ ok
+ end,
+ {t_sup(AccType, CType), [NewMap3|AccMaps]}
+ catch
+ throw:{fail, _What} -> {AccType, AccMaps}
+ end,
+ bind_guard_case_clauses(NewGenArgType, GenMap, ArgExpr, Left, Map, Env,
+ Eval, NewAccType, NewAccMaps, State)
+ end;
+bind_guard_case_clauses(_GenArgType, _GenMap, _ArgExpr, [], Map, _Env, _Eval,
+ AccType, AccMaps, _State) ->
+ case t_is_none(AccType) of
+ true -> throw({fail, none});
+ false -> {join_maps_end(AccMaps, Map), AccType}
+ end.
+
+%%% ===========================================================================
+%%%
+%%% Maps and types.
+%%%
+%%% ===========================================================================
+
+map__new() ->
+ #map{}.
+
+%% join_maps_begin pushes 'modified' to the stack; join_maps pops
+%% 'modified' from the stack.
+
+join_maps_begin(#map{modified = M, modified_stack = S, ref = Ref} = Map) ->
+ Map#map{ref = make_ref(), modified = [], modified_stack = [{M,Ref} | S]}.
+
+join_maps_end(Maps, MapOut) ->
+ #map{ref = Ref, modified_stack = [{M1,R1} | S]} = MapOut,
+ true = lists:all(fun(M) -> M#map.ref =:= Ref end, Maps), % sanity
+ Keys0 = lists:usort(lists:append([M#map.modified || M <- Maps])),
+ #map{map = Map, subst = Subst} = MapOut,
+ Keys = [Key ||
+ Key <- Keys0,
+ maps:is_key(Key, Map) orelse maps:is_key(Key, Subst)],
+ Out = case Maps of
+ [] -> join_maps(Maps, MapOut);
+ _ -> join_maps(Keys, Maps, MapOut)
+ end,
+ debug_join_check(Maps, MapOut, Out),
+ Out#map{ref = R1,
+ modified = Out#map.modified ++ M1, % duplicates possible
+ modified_stack = S}.
+
+join_maps(Maps, MapOut) ->
+ #map{map = Map, subst = Subst} = MapOut,
+ Keys = ordsets:from_list(maps:keys(Map) ++ maps:keys(Subst)),
+ join_maps(Keys, Maps, MapOut).
+
+join_maps(Keys, Maps, MapOut) ->
+ KTs = join_maps_collect(Keys, Maps, MapOut),
+ lists:foldl(fun({K, T}, M) -> enter_type(K, T, M) end, MapOut, KTs).
+
+join_maps_collect([Key|Left], Maps, MapOut) ->
+ Type = join_maps_one_key(Maps, Key, t_none()),
+ case t_is_equal(lookup_type(Key, MapOut), Type) of
+ true -> join_maps_collect(Left, Maps, MapOut);
+ false -> [{Key, Type} | join_maps_collect(Left, Maps, MapOut)]
+ end;
+join_maps_collect([], _Maps, _MapOut) ->
+ [].
+
+join_maps_one_key([Map|Left], Key, AccType) ->
+ case t_is_any(AccType) of
+ true ->
+ %% We can stop here
+ AccType;
+ false ->
+ join_maps_one_key(Left, Key, t_sup(lookup_type(Key, Map), AccType))
+ end;
+join_maps_one_key([], _Key, AccType) ->
+ AccType.
+
+-ifdef(DEBUG).
+debug_join_check(Maps, MapOut, Out) ->
+ #map{map = Map, subst = Subst} = Out,
+ #map{map = Map2, subst = Subst2} = join_maps(Maps, MapOut),
+ F = fun(D) -> lists:keysort(1, maps:to_list(D)) end,
+ [throw({bug, join_maps}) ||
+ F(Map) =/= F(Map2) orelse F(Subst) =/= F(Subst2)].
+-else.
+debug_join_check(_Maps, _MapOut, _Out) -> ok.
+-endif.
+
+enter_type_lists([Key|KeyTail], [Val|ValTail], Map) ->
+ Map1 = enter_type(Key, Val, Map),
+ enter_type_lists(KeyTail, ValTail, Map1);
+enter_type_lists([], [], Map) ->
+ Map.
+
+enter_type_list([{Key, Val}|Left], Map) ->
+ Map1 = enter_type(Key, Val, Map),
+ enter_type_list(Left, Map1);
+enter_type_list([], Map) ->
+ Map.
+
+enter_type(Key, Val, MS) ->
+ case cerl:is_literal(Key) of
+ true -> MS;
+ false ->
+ case cerl:is_c_values(Key) of
+ true ->
+ Keys = cerl:values_es(Key),
+ case t_is_any(Val) orelse t_is_none(Val) of
+ true ->
+ enter_type_lists(Keys, [Val || _ <- Keys], MS);
+ false ->
+ enter_type_lists(Keys, t_to_tlist(Val), MS)
+ end;
+ false ->
+ #map{map = Map, subst = Subst} = MS,
+ KeyLabel = get_label(Key),
+ case maps:find(KeyLabel, Subst) of
+ {ok, NewKey} ->
+ ?debug("Binding ~p to ~p\n", [KeyLabel, NewKey]),
+ enter_type(NewKey, Val, MS);
+ error ->
+ ?debug("Entering ~p :: ~s\n", [KeyLabel, t_to_string(Val)]),
+ case maps:find(KeyLabel, Map) of
+ {ok, Value} ->
+ case erl_types:t_is_equal(Val, Value) of
+ true -> MS;
+ false -> store_map(KeyLabel, Val, MS)
+ end;
+ error -> store_map(KeyLabel, Val, MS)
+ end
+ end
+ end
+ end.
+
+store_map(Key, Val, #map{map = Map, ref = undefined} = MapRec) ->
+ MapRec#map{map = maps:put(Key, Val, Map)};
+store_map(Key, Val, #map{map = Map, modified = Mod} = MapRec) ->
+ MapRec#map{map = maps:put(Key, Val, Map), modified = [Key | Mod]}.
+
+enter_subst(Key, Val0, #map{subst = Subst} = MS) ->
+ KeyLabel = get_label(Key),
+ Val = dialyzer_utils:refold_pattern(Val0),
+ case cerl:is_literal(Val) of
+ true ->
+ store_map(KeyLabel, literal_type(Val), MS);
+ false ->
+ case cerl:is_c_var(Val) of
+ false -> MS;
+ true ->
+ ValLabel = get_label(Val),
+ case maps:find(ValLabel, Subst) of
+ {ok, NewVal} ->
+ enter_subst(Key, NewVal, MS);
+ error ->
+ if KeyLabel =:= ValLabel -> MS;
+ true ->
+ ?debug("Subst: storing ~p = ~p\n", [KeyLabel, ValLabel]),
+ store_subst(KeyLabel, ValLabel, MS)
+ end
+ end
+ end
+ end.
+
+store_subst(Key, Val, #map{subst = S, ref = undefined} = Map) ->
+ Map#map{subst = maps:put(Key, Val, S)};
+store_subst(Key, Val, #map{subst = S, modified = Mod} = Map) ->
+ Map#map{subst = maps:put(Key, Val, S), modified = [Key | Mod]}.
+
+lookup_type(Key, #map{map = Map, subst = Subst}) ->
+ lookup(Key, Map, Subst, t_none()).
+
+lookup(Key, Map, Subst, AnyNone) ->
+ case cerl:is_literal(Key) of
+ true -> literal_type(Key);
+ false ->
+ Label = get_label(Key),
+ case maps:find(Label, Subst) of
+ {ok, NewKey} -> lookup(NewKey, Map, Subst, AnyNone);
+ error ->
+ case maps:find(Label, Map) of
+ {ok, Val} -> Val;
+ error -> AnyNone
+ end
+ end
+ end.
+
+lookup_fun_sig(Fun, Callgraph, Plt) ->
+ MFAorLabel =
+ case dialyzer_callgraph:lookup_name(Fun, Callgraph) of
+ error -> Fun;
+ {ok, MFA} -> MFA
+ end,
+ dialyzer_plt:lookup(Plt, MFAorLabel).
+
+literal_type(Lit) ->
+ t_from_term(cerl:concrete(Lit)).
+
+mark_as_fresh([Tree|Left], Map) ->
+ SubTrees1 = lists:append(cerl:subtrees(Tree)),
+ {SubTrees2, Map1} =
+ case cerl:type(Tree) of
+ bitstr ->
+ %% The Size field is not fresh.
+ {SubTrees1 -- [cerl:bitstr_size(Tree)], Map};
+ map_pair ->
+ %% The keys are not fresh
+ {SubTrees1 -- [cerl:map_pair_key(Tree)], Map};
+ var ->
+ {SubTrees1, enter_type(Tree, t_any(), Map)};
+ _ ->
+ {SubTrees1, Map}
+ end,
+ mark_as_fresh(SubTrees2 ++ Left, Map1);
+mark_as_fresh([], Map) ->
+ Map.
+
+-ifdef(DEBUG).
+debug_pp_map(#map{map = Map}=MapRec) ->
+ Keys = maps:keys(Map),
+ io:format("Map:\n", []),
+ lists:foreach(fun (Key) ->
+ io:format("\t~w :: ~s\n",
+ [Key, t_to_string(lookup_type(Key, MapRec))])
+ end, Keys),
+ ok.
+-else.
+debug_pp_map(_Map) -> ok.
+-endif.
+
+%%% ===========================================================================
+%%%
+%%% Utilities
+%%%
+%%% ===========================================================================
+
+get_label(L) when is_integer(L) ->
+ L;
+get_label(T) ->
+ cerl_trees:get_label(T).
+
+t_is_simple(ArgType, State) ->
+ Opaques = State#state.opaques,
+ t_is_atom(ArgType, Opaques) orelse t_is_number(ArgType, Opaques)
+ orelse t_is_port(ArgType, Opaques)
+ orelse t_is_pid(ArgType, Opaques) orelse t_is_reference(ArgType, Opaques)
+ orelse t_is_nil(ArgType, Opaques).
+
+remove_local_opaque_types(Type, Opaques) ->
+ t_unopaque(Type, Opaques).
+
+%% t_is_structured(ArgType) ->
+%% case t_is_nil(ArgType) of
+%% true -> false;
+%% false ->
+%% SType = t_inf(t_sup([t_list(), t_tuple(), t_binary()]), ArgType),
+%% t_is_equal(ArgType, SType)
+%% end.
+
+is_call_to_send(Tree) ->
+ case cerl:is_c_call(Tree) of
+ false -> false;
+ true ->
+ Mod = cerl:call_module(Tree),
+ Name = cerl:call_name(Tree),
+ Arity = cerl:call_arity(Tree),
+ cerl:is_c_atom(Mod)
+ andalso cerl:is_c_atom(Name)
+ andalso is_send(cerl:atom_val(Name))
+ andalso (cerl:atom_val(Mod) =:= erlang)
+ andalso (Arity =:= 2)
+ end.
+
+is_send('!') -> true;
+is_send(send) -> true;
+is_send(_) -> false.
+
+is_lc_simple_list(Tree, TreeType, State) ->
+ Opaques = State#state.opaques,
+ Ann = cerl:get_ann(Tree),
+ lists:member(list_comprehension, Ann)
+ andalso t_is_list(TreeType)
+ andalso t_is_simple(t_list_elements(TreeType, Opaques), State).
+
+filter_match_fail([Clause] = Cls) ->
+ Body = cerl:clause_body(Clause),
+ case cerl:type(Body) of
+ primop ->
+ case cerl:atom_val(cerl:primop_name(Body)) of
+ match_fail -> [];
+ raise -> [];
+ _ -> Cls
+ end;
+ _ -> Cls
+ end;
+filter_match_fail([H|T]) ->
+ [H|filter_match_fail(T)];
+filter_match_fail([]) ->
+ %% This can actually happen, for example in
+ %% receive after 1 -> ok end
+ [].
+
+%%% ===========================================================================
+%%%
+%%% The State.
+%%%
+%%% ===========================================================================
+
+state__new(Callgraph, Codeserver, Tree, Plt, Module, Records) ->
+ Opaques = erl_types:t_opaque_from_records(Records),
+ {TreeMap, FunHomes} = build_tree_map(Tree, Callgraph),
+ Funs = dict:fetch_keys(TreeMap),
+ FunTab = init_fun_tab(Funs, dict:new(), TreeMap, Callgraph, Plt),
+ ExportedFuns =
+ [Fun || Fun <- Funs--[top], dialyzer_callgraph:is_escaping(Fun, Callgraph)],
+ Work = init_work(ExportedFuns),
+ Env = lists:foldl(fun(Fun, Env) -> dict:store(Fun, map__new(), Env) end,
+ dict:new(), Funs),
+ #state{callgraph = Callgraph, codeserver = Codeserver,
+ envs = Env, fun_tab = FunTab, fun_homes = FunHomes, opaques = Opaques,
+ plt = Plt, races = dialyzer_races:new(), records = Records,
+ warning_mode = false, warnings = [], work = Work, tree_map = TreeMap,
+ module = Module}.
+
+state__warning_mode(#state{warning_mode = WM}) ->
+ WM.
+
+state__set_warning_mode(#state{tree_map = TreeMap, fun_tab = FunTab,
+ races = Races} = State) ->
+ ?debug("==========\nStarting warning pass\n==========\n", []),
+ Funs = dict:fetch_keys(TreeMap),
+ State#state{work = init_work([top|Funs--[top]]),
+ fun_tab = FunTab, warning_mode = true,
+ races = dialyzer_races:put_race_analysis(true, Races)}.
+
+state__race_analysis(Analysis, #state{races = Races} = State) ->
+ State#state{races = dialyzer_races:put_race_analysis(Analysis, Races)}.
+
+state__renew_curr_fun(CurrFun, CurrFunLabel,
+ #state{races = Races} = State) ->
+ State#state{races = dialyzer_races:put_curr_fun(CurrFun, CurrFunLabel,
+ Races)}.
+
+state__renew_fun_args(Args, #state{races = Races} = State) ->
+ case state__warning_mode(State) of
+ true -> State;
+ false ->
+ State#state{races = dialyzer_races:put_fun_args(Args, Races)}
+ end.
+
+state__renew_race_list(RaceList, RaceListSize,
+ #state{races = Races} = State) ->
+ State#state{races = dialyzer_races:put_race_list(RaceList, RaceListSize,
+ Races)}.
+
+state__renew_warnings(Warnings, State) ->
+ State#state{warnings = Warnings}.
+
+-spec state__add_warning(raw_warning(), state()) -> state().
+
+state__add_warning(Warn, #state{warnings = Warnings} = State) ->
+ State#state{warnings = [Warn|Warnings]}.
+
+state__add_warning(State, Tag, Tree, Msg) ->
+ state__add_warning(State, Tag, Tree, Msg, false).
+
+state__add_warning(#state{warning_mode = false} = State, _, _, _, _) ->
+ State;
+state__add_warning(#state{warnings = Warnings, warning_mode = true} = State,
+ Tag, Tree, Msg, Force) ->
+ Ann = cerl:get_ann(Tree),
+ case Force of
+ true ->
+ WarningInfo = {get_file(Ann),
+ abs(get_line(Ann)),
+ State#state.curr_fun},
+ Warn = {Tag, WarningInfo, Msg},
+ ?debug("MSG ~s\n", [dialyzer:format_warning(Warn)]),
+ State#state{warnings = [Warn|Warnings]};
+ false ->
+ case is_compiler_generated(Ann) of
+ true -> State;
+ false ->
+ WarningInfo = {get_file(Ann), get_line(Ann), State#state.curr_fun},
+ Warn = {Tag, WarningInfo, Msg},
+ case Tag of
+ ?WARN_CONTRACT_RANGE -> ok;
+ _ -> ?debug("MSG ~s\n", [dialyzer:format_warning(Warn)])
+ end,
+ State#state{warnings = [Warn|Warnings]}
+ end
+ end.
+
+state__remove_added_warnings(OldState, NewState) ->
+ #state{warnings = OldWarnings} = OldState,
+ #state{warnings = NewWarnings} = NewState,
+ {NewWarnings -- OldWarnings, NewState#state{warnings = OldWarnings}}.
+
+state__add_warnings(Warns, #state{warnings = Warnings} = State) ->
+ State#state{warnings = Warns ++ Warnings}.
+
+-spec state__set_curr_fun(curr_fun(), state()) -> state().
+
+state__set_curr_fun(undefined, State) ->
+ State#state{curr_fun = undefined};
+state__set_curr_fun(FunLbl, State) ->
+ State#state{curr_fun = find_function(FunLbl, State)}.
+
+-spec state__find_function(mfa_or_funlbl(), state()) -> mfa_or_funlbl().
+
+state__find_function(FunLbl, State) ->
+ find_function(FunLbl, State).
+
+state__get_race_warnings(#state{races = Races} = State) ->
+ {Races1, State1} = dialyzer_races:get_race_warnings(Races, State),
+ State1#state{races = Races1}.
+
+state__get_warnings(#state{tree_map = TreeMap, fun_tab = FunTab,
+ callgraph = Callgraph, plt = Plt} = State) ->
+ FoldFun =
+ fun({top, _}, AccState) -> AccState;
+ ({FunLbl, Fun}, AccState) ->
+ AccState1 = state__set_curr_fun(FunLbl, AccState),
+ {NotCalled, Ret} =
+ case dict:fetch(get_label(Fun), FunTab) of
+ {not_handled, {_Args0, Ret0}} -> {true, Ret0};
+ {_Args0, Ret0} -> {false, Ret0}
+ end,
+ case NotCalled of
+ true ->
+ case dialyzer_callgraph:lookup_name(FunLbl, Callgraph) of
+ error -> AccState1;
+ {ok, {_M, F, A}} ->
+ Msg = {unused_fun, [F, A]},
+ state__add_warning(AccState1, ?WARN_NOT_CALLED, Fun, Msg)
+ end;
+ false ->
+ {Name, Contract} =
+ case dialyzer_callgraph:lookup_name(FunLbl, Callgraph) of
+ error -> {[], none};
+ {ok, {_M, F, A} = MFA} ->
+ {[F, A], dialyzer_plt:lookup_contract(Plt, MFA)}
+ end,
+ case t_is_none(Ret) of
+ true ->
+ %% Check if the function has a contract that allows this.
+ Warn =
+ case Contract of
+ none -> not parent_allows_this(FunLbl, AccState1);
+ {value, C} ->
+ GenRet = dialyzer_contracts:get_contract_return(C),
+ not t_is_unit(GenRet)
+ end,
+ case Warn of
+ true ->
+ case classify_returns(Fun) of
+ no_match ->
+ Msg = {no_return, [no_match|Name]},
+ state__add_warning(AccState1, ?WARN_RETURN_NO_RETURN,
+ Fun, Msg);
+ only_explicit ->
+ Msg = {no_return, [only_explicit|Name]},
+ state__add_warning(AccState1, ?WARN_RETURN_ONLY_EXIT,
+ Fun, Msg);
+ only_normal ->
+ Msg = {no_return, [only_normal|Name]},
+ state__add_warning(AccState1, ?WARN_RETURN_NO_RETURN,
+ Fun, Msg);
+ both ->
+ Msg = {no_return, [both|Name]},
+ state__add_warning(AccState1, ?WARN_RETURN_NO_RETURN,
+ Fun, Msg)
+ end;
+ false ->
+ AccState
+ end;
+ false ->
+ AccState
+ end
+ end
+ end,
+ #state{warnings = Warn} = lists:foldl(FoldFun, State, dict:to_list(TreeMap)),
+ Warn.
+
+state__is_escaping(Fun, #state{callgraph = Callgraph}) ->
+ dialyzer_callgraph:is_escaping(Fun, Callgraph).
+
+state__lookup_type_for_letrec(Var, #state{callgraph = Callgraph} = State) ->
+ Label = get_label(Var),
+ case dialyzer_callgraph:lookup_letrec(Label, Callgraph) of
+ error -> error;
+ {ok, FunLabel} ->
+ {ok, state__fun_type(FunLabel, State)}
+ end.
+
+state__lookup_name({_, _, _} = MFA, #state{}) ->
+ MFA;
+state__lookup_name(top, #state{}) ->
+ top;
+state__lookup_name(Fun, #state{callgraph = Callgraph}) ->
+ case dialyzer_callgraph:lookup_name(Fun, Callgraph) of
+ {ok, MFA} -> MFA;
+ error -> Fun
+ end.
+
+state__lookup_record(Tag, Arity, #state{records = Records}) ->
+ case erl_types:lookup_record(Tag, Arity, Records) of
+ {ok, Fields} ->
+ RecType =
+ t_tuple([t_atom(Tag)|
+ [FieldType || {_FieldName, _Abstr, FieldType} <- Fields]]),
+ {ok, RecType};
+ error ->
+ error
+ end.
+
+state__get_args_and_status(Tree, #state{fun_tab = FunTab}) ->
+ Fun = get_label(Tree),
+ case dict:find(Fun, FunTab) of
+ {ok, {not_handled, {ArgTypes, _}}} -> {ArgTypes, false};
+ {ok, {ArgTypes, _}} -> {ArgTypes, true}
+ end.
+
+build_tree_map(Tree, Callgraph) ->
+ Fun =
+ fun(T, {Dict, Homes, FunLbls} = Acc) ->
+ case cerl:is_c_fun(T) of
+ true ->
+ FunLbl = get_label(T),
+ Dict1 = dict:store(FunLbl, T, Dict),
+ case catch dialyzer_callgraph:lookup_name(FunLbl, Callgraph) of
+ {ok, MFA} ->
+ F2 =
+ fun(Lbl, Dict0) ->
+ dict:store(Lbl, MFA, Dict0)
+ end,
+ Homes1 = lists:foldl(F2, Homes, [FunLbl|FunLbls]),
+ {Dict1, Homes1, []};
+ _ ->
+ {Dict1, Homes, [FunLbl|FunLbls]}
+ end;
+ false ->
+ Acc
+ end
+ end,
+ Dict0 = dict:new(),
+ {Dict, Homes, _} = cerl_trees:fold(Fun, {Dict0, Dict0, []}, Tree),
+ {Dict, Homes}.
+
+init_fun_tab([top|Left], Dict, TreeMap, Callgraph, Plt) ->
+ NewDict = dict:store(top, {[], t_none()}, Dict),
+ init_fun_tab(Left, NewDict, TreeMap, Callgraph, Plt);
+init_fun_tab([Fun|Left], Dict, TreeMap, Callgraph, Plt) ->
+ Arity = cerl:fun_arity(dict:fetch(Fun, TreeMap)),
+ FunEntry =
+ case dialyzer_callgraph:is_escaping(Fun, Callgraph) of
+ true ->
+ Args = lists:duplicate(Arity, t_any()),
+ case lookup_fun_sig(Fun, Callgraph, Plt) of
+ none -> {Args, t_unit()};
+ {value, {RetType, _}} ->
+ case t_is_none(RetType) of
+ true -> {Args, t_none()};
+ false -> {Args, t_unit()}
+ end
+ end;
+ false -> {not_handled, {lists:duplicate(Arity, t_none()), t_unit()}}
+ end,
+ NewDict = dict:store(Fun, FunEntry, Dict),
+ init_fun_tab(Left, NewDict, TreeMap, Callgraph, Plt);
+init_fun_tab([], Dict, _TreeMap, _Callgraph, _Plt) ->
+ ?debug("DICT:~p\n",[dict:to_list(Dict)]),
+ Dict.
+
+state__update_fun_env(Tree, Map, #state{envs = Envs} = State) ->
+ NewEnvs = dict:store(get_label(Tree), Map, Envs),
+ State#state{envs = NewEnvs}.
+
+state__fun_env(Tree, #state{envs = Envs}) ->
+ Fun = get_label(Tree),
+ case dict:find(Fun, Envs) of
+ error -> none;
+ {ok, Map} -> Map
+ end.
+
+state__clean_not_called(#state{fun_tab = FunTab} = State) ->
+ NewFunTab =
+ dict:map(fun(top, Entry) -> Entry;
+ (_Fun, {not_handled, {Args, _}}) -> {Args, t_none()};
+ (_Fun, Entry) -> Entry
+ end, FunTab),
+ State#state{fun_tab = NewFunTab}.
+
+state__all_fun_types(State) ->
+ #state{fun_tab = FunTab} = state__clean_not_called(State),
+ Tab1 = dict:erase(top, FunTab),
+ dict:map(fun(_Fun, {Args, Ret}) -> t_fun(Args, Ret)end, Tab1).
+
+state__fun_type(Fun, #state{fun_tab = FunTab}) ->
+ Label =
+ if is_integer(Fun) -> Fun;
+ true -> get_label(Fun)
+ end,
+ Entry = dict:find(Label, FunTab),
+ ?debug("FunType ~p:~p\n",[Label, Entry]),
+ case Entry of
+ {ok, {not_handled, {A, R}}} ->
+ t_fun(A, R);
+ {ok, {A, R}} ->
+ t_fun(A, R)
+ end.
+
+state__update_fun_entry(Tree, ArgTypes, Out0,
+ #state{fun_tab=FunTab, callgraph=CG, plt=Plt} = State)->
+ Fun = get_label(Tree),
+ Out1 =
+ if Fun =:= top -> Out0;
+ true ->
+ case lookup_fun_sig(Fun, CG, Plt) of
+ {value, {SigRet, _}} -> t_inf(SigRet, Out0);
+ none -> Out0
+ end
+ end,
+ Out = t_limit(Out1, ?TYPE_LIMIT),
+ {ok, {OldArgTypes, OldOut}} = dict:find(Fun, FunTab),
+ SameArgs = lists:all(fun({A, B}) -> erl_types:t_is_equal(A, B)
+ end, lists:zip(OldArgTypes, ArgTypes)),
+ SameOut = t_is_equal(OldOut, Out),
+ if
+ SameArgs, SameOut ->
+ ?debug("Fixpoint for ~w: ~s\n",
+ [state__lookup_name(Fun, State),
+ t_to_string(t_fun(ArgTypes, Out))]),
+ State;
+ true ->
+ %% Can only happen in self-recursive functions.
+ NewEntry = {OldArgTypes, Out},
+ ?debug("New Entry for ~w: ~s\n",
+ [state__lookup_name(Fun, State),
+ t_to_string(t_fun(OldArgTypes, Out))]),
+ NewFunTab = dict:store(Fun, NewEntry, FunTab),
+ State1 = State#state{fun_tab = NewFunTab},
+ state__add_work_from_fun(Tree, State1)
+ end.
+
+state__add_work_from_fun(_Tree, #state{warning_mode = true} = State) ->
+ State;
+state__add_work_from_fun(Tree, #state{callgraph = Callgraph,
+ tree_map = TreeMap} = State) ->
+ case get_label(Tree) of
+ top -> State;
+ Label when is_integer(Label) ->
+ case dialyzer_callgraph:in_neighbours(Label, Callgraph) of
+ none -> State;
+ MFAList ->
+ LabelList = [dialyzer_callgraph:lookup_label(MFA, Callgraph)
+ || MFA <- MFAList],
+ %% Must filter the result for results in this module.
+ FilteredList = [L || {ok, L} <- LabelList, dict:is_key(L, TreeMap)],
+ ?debug("~w: Will try to add:~w\n",
+ [state__lookup_name(Label, State), MFAList]),
+ lists:foldl(fun(L, AccState) ->
+ state__add_work(L, AccState)
+ end, State, FilteredList)
+ end
+ end.
+
+state__add_work(external, State) ->
+ State;
+state__add_work(top, State) ->
+ State;
+state__add_work(Fun, #state{work = Work} = State) ->
+ NewWork = add_work(Fun, Work),
+ State#state{work = NewWork}.
+
+state__get_work(#state{work = Work, tree_map = TreeMap} = State) ->
+ case get_work(Work) of
+ none -> none;
+ {Fun, NewWork} ->
+ {dict:fetch(Fun, TreeMap), State#state{work = NewWork}}
+ end.
+
+state__lookup_call_site(Tree, #state{callgraph = Callgraph}) ->
+ Label = get_label(Tree),
+ dialyzer_callgraph:lookup_call_site(Label, Callgraph).
+
+state__fun_info(external, #state{}) ->
+ external;
+state__fun_info({_, _, _} = MFA, #state{plt = PLT}) ->
+ {MFA,
+ dialyzer_plt:lookup(PLT, MFA),
+ dialyzer_plt:lookup_contract(PLT, MFA),
+ t_any()};
+state__fun_info(Fun, #state{callgraph = CG, fun_tab = FunTab, plt = PLT}) ->
+ {Sig, Contract} =
+ case dialyzer_callgraph:lookup_name(Fun, CG) of
+ error ->
+ {dialyzer_plt:lookup(PLT, Fun), none};
+ {ok, MFA} ->
+ {dialyzer_plt:lookup(PLT, MFA), dialyzer_plt:lookup_contract(PLT, MFA)}
+ end,
+ LocalRet =
+ case dict:fetch(Fun, FunTab) of
+ {not_handled, {_Args, Ret}} -> Ret;
+ {_Args, Ret} -> Ret
+ end,
+ ?debug("LocalRet: ~s\n", [t_to_string(LocalRet)]),
+ {Fun, Sig, Contract, LocalRet}.
+
+forward_args(Fun, ArgTypes, #state{work = Work, fun_tab = FunTab} = State) ->
+ {OldArgTypes, OldOut, Fixpoint} =
+ case dict:find(Fun, FunTab) of
+ {ok, {not_handled, {OldArgTypes0, OldOut0}}} ->
+ {OldArgTypes0, OldOut0, false};
+ {ok, {OldArgTypes0, OldOut0}} ->
+ {OldArgTypes0, OldOut0,
+ t_is_subtype(t_product(ArgTypes), t_product(OldArgTypes0))}
+ end,
+ case Fixpoint of
+ true -> State;
+ false ->
+ NewArgTypes = [t_sup(X, Y) ||
+ {X, Y} <- lists:zip(ArgTypes, OldArgTypes)],
+ NewWork = add_work(Fun, Work),
+ ?debug("~w: forwarding args ~s\n",
+ [state__lookup_name(Fun, State),
+ t_to_string(t_product(NewArgTypes))]),
+ NewFunTab = dict:store(Fun, {NewArgTypes, OldOut}, FunTab),
+ State#state{work = NewWork, fun_tab = NewFunTab}
+ end.
+
+-spec state__cleanup(state()) -> state().
+
+state__cleanup(#state{callgraph = Callgraph,
+ races = Races,
+ records = Records}) ->
+ #state{callgraph = dialyzer_callgraph:cleanup(Callgraph),
+ races = dialyzer_races:cleanup(Races),
+ records = Records}.
+
+-spec state__duplicate(state()) -> state().
+
+state__duplicate(#state{callgraph = Callgraph} = State) ->
+ State#state{callgraph = dialyzer_callgraph:duplicate(Callgraph)}.
+
+-spec dispose_state(state()) -> ok.
+
+dispose_state(#state{callgraph = Callgraph}) ->
+ dialyzer_callgraph:dispose_race_server(Callgraph).
+
+-spec state__get_callgraph(state()) -> dialyzer_callgraph:callgraph().
+
+state__get_callgraph(#state{callgraph = Callgraph}) ->
+ Callgraph.
+
+-spec state__get_races(state()) -> dialyzer_races:races().
+
+state__get_races(#state{races = Races}) ->
+ Races.
+
+-spec state__get_records(state()) -> types().
+
+state__get_records(#state{records = Records}) ->
+ Records.
+
+-spec state__put_callgraph(dialyzer_callgraph:callgraph(), state()) ->
+ state().
+
+state__put_callgraph(Callgraph, State) ->
+ State#state{callgraph = Callgraph}.
+
+-spec state__put_races(dialyzer_races:races(), state()) -> state().
+
+state__put_races(Races, State) ->
+ State#state{races = Races}.
+
+-spec state__records_only(state()) -> state().
+
+state__records_only(#state{records = Records}) ->
+ #state{records = Records}.
+
+%%% ===========================================================================
+%%%
+%%% Races
+%%%
+%%% ===========================================================================
+
+is_race_analysis_enabled(#state{races = Races, callgraph = Callgraph}) ->
+ RaceDetection = dialyzer_callgraph:get_race_detection(Callgraph),
+ RaceAnalysis = dialyzer_races:get_race_analysis(Races),
+ RaceDetection andalso RaceAnalysis.
+
+get_race_list_and_size(#state{races = Races}) ->
+ dialyzer_races:get_race_list_and_size(Races).
+
+renew_race_code(#state{races = Races, callgraph = Callgraph,
+ warning_mode = WarningMode} = State) ->
+ case WarningMode of
+ true -> State;
+ false ->
+ NewCallgraph = dialyzer_callgraph:renew_race_code(Races, Callgraph),
+ State#state{callgraph = NewCallgraph}
+ end.
+
+renew_race_public_tables([Var], #state{races = Races, callgraph = Callgraph,
+ warning_mode = WarningMode} = State) ->
+ case WarningMode of
+ true -> State;
+ false ->
+ Table = dialyzer_races:get_new_table(Races),
+ case Table of
+ no_t -> State;
+ _Other ->
+ VarLabel = get_label(Var),
+ NewCallgraph =
+ dialyzer_callgraph:renew_race_public_tables(VarLabel, Callgraph),
+ State#state{callgraph = NewCallgraph}
+ end
+ end.
+
+%%% ===========================================================================
+%%%
+%%% Worklist
+%%%
+%%% ===========================================================================
+
+init_work(List) ->
+ {List, [], sets:from_list(List)}.
+
+get_work({[], [], _Set}) ->
+ none;
+get_work({[H|T], Rev, Set}) ->
+ {H, {T, Rev, sets:del_element(H, Set)}};
+get_work({[], Rev, Set}) ->
+ get_work({lists:reverse(Rev), [], Set}).
+
+add_work(New, {List, Rev, Set} = Work) ->
+ case sets:is_element(New, Set) of
+ true -> Work;
+ false -> {List, [New|Rev], sets:add_element(New, Set)}
+ end.
+
+%%% ===========================================================================
+%%%
+%%% Utilities.
+%%%
+%%% ===========================================================================
+
+get_line([Line|_]) when is_integer(Line) -> Line;
+get_line([_|Tail]) -> get_line(Tail);
+get_line([]) -> -1.
+
+get_file([]) -> [];
+get_file([{file, File}|_]) -> File;
+get_file([_|Tail]) -> get_file(Tail).
+
+is_compiler_generated(Ann) ->
+ lists:member(compiler_generated, Ann) orelse (get_line(Ann) < 1).
+
+is_literal_record(Tree) ->
+ Ann = cerl:get_ann(Tree),
+ lists:member(record, Ann).
+
+-spec format_args([cerl:cerl()], [type()], state()) ->
+ nonempty_string().
+
+format_args([], [], _State) ->
+ "()";
+format_args(ArgList0, TypeList, State) ->
+ ArgList = fold_literals(ArgList0),
+ "(" ++ format_args_1(ArgList, TypeList, State) ++ ")".
+
+format_args_1([Arg], [Type], State) ->
+ format_arg(Arg) ++ format_type(Type, State);
+format_args_1([Arg|Args], [Type|Types], State) ->
+ String =
+ case cerl:is_literal(Arg) of
+ true -> format_cerl(Arg);
+ false -> format_arg(Arg) ++ format_type(Type, State)
+ end,
+ String ++ "," ++ format_args_1(Args, Types, State).
+
+format_arg(Arg) ->
+ Default = "",
+ case cerl:is_c_var(Arg) of
+ true ->
+ case cerl:var_name(Arg) of
+ Atom when is_atom(Atom) ->
+ case atom_to_list(Atom) of
+ "cor"++_ -> Default;
+ "rec"++_ -> Default;
+ Name -> Name ++ "::"
+ end;
+ _What -> Default
+ end;
+ false ->
+ Default
+ end.
+
+-spec format_type(type(), state()) -> string().
+
+format_type(Type, #state{records = R}) ->
+ t_to_string(Type, R).
+
+-spec format_field_diffs(type(), state()) -> string().
+
+format_field_diffs(RecConstruction, #state{records = R}) ->
+ erl_types:record_field_diffs_to_string(RecConstruction, R).
+
+-spec format_sig_args(type(), state()) -> string().
+
+format_sig_args(Type, #state{opaques = Opaques} = State) ->
+ SigArgs = t_fun_args(Type, Opaques),
+ case SigArgs of
+ [] -> "()";
+ [SArg|SArgs] ->
+ lists:flatten("(" ++ format_type(SArg, State)
+ ++ ["," ++ format_type(T, State) || T <- SArgs] ++ ")")
+ end.
+
+format_cerl(Tree) ->
+ cerl_prettypr:format(cerl:set_ann(Tree, []),
+ [{hook, dialyzer_utils:pp_hook()},
+ {noann, true},
+ {paper, 100000}, %% These guys strip
+ {ribbon, 100000} %% newlines.
+ ]).
+
+format_patterns(Pats0) ->
+ Pats = fold_literals(Pats0),
+ NewPats = map_pats(cerl:c_values(Pats)),
+ String = format_cerl(NewPats),
+ case Pats of
+ [PosVar] ->
+ case cerl:is_c_var(PosVar) andalso (cerl:var_name(PosVar) =/= '') of
+ true -> "variable "++String;
+ false -> "pattern "++String
+ end;
+ _ ->
+ "pattern "++String
+ end.
+
+map_pats(Pats) ->
+ Fun = fun(Tree) ->
+ case cerl:is_c_var(Tree) of
+ true ->
+ case cerl:var_name(Tree) of
+ Atom when is_atom(Atom) ->
+ case atom_to_list(Atom) of
+ "cor"++_ -> cerl:c_var('');
+ "rec"++_ -> cerl:c_var('');
+ _ -> cerl:set_ann(Tree, [])
+ end;
+ _What -> cerl:c_var('')
+ end;
+ false ->
+ cerl:set_ann(Tree, [])
+ end
+ end,
+ cerl_trees:map(Fun, Pats).
+
+fold_literals(TreeList) ->
+ [cerl:fold_literal(Tree) || Tree <- TreeList].
+
+type(Tree) ->
+ Folded = cerl:fold_literal(Tree),
+ case cerl:type(Folded) of
+ literal -> {literal, Folded};
+ Type -> Type
+ end.
+
+is_literal(Tree) ->
+ Folded = cerl:fold_literal(Tree),
+ case cerl:is_literal(Folded) of
+ true -> {yes, Folded};
+ false -> no
+ end.
+
+parent_allows_this(FunLbl, #state{callgraph = Callgraph, plt = Plt} =State) ->
+ case state__is_escaping(FunLbl, State) of
+ false -> false; % if it isn't escaping it can't be a return value
+ true ->
+ case state__lookup_name(FunLbl, State) of
+ {_M, _F, _A} -> false; % if it has a name it is not a fun
+ _ ->
+ case dialyzer_callgraph:in_neighbours(FunLbl, Callgraph) of
+ [Parent] ->
+ case state__lookup_name(Parent, State) of
+ {_M, _F, _A} = PMFA ->
+ case dialyzer_plt:lookup_contract(Plt, PMFA) of
+ none -> false;
+ {value, C} ->
+ GenRet = dialyzer_contracts:get_contract_return(C),
+ case erl_types:t_is_fun(GenRet) of
+ false -> false; % element of structure? far-fetched...
+ true -> t_is_unit(t_fun_range(GenRet))
+ end
+ end;
+ _ -> false % parent should have a name to have a contract
+ end;
+ _ -> false % called in other funs? far-fetched...
+ end
+ end
+ end.
+
+find_function({_, _, _} = MFA, _State) ->
+ MFA;
+find_function(top, _State) ->
+ top;
+find_function(FunLbl, #state{fun_homes = Homes}) ->
+ dict:fetch(FunLbl, Homes).
+
+classify_returns(Tree) ->
+ case find_terminals(cerl:fun_body(Tree)) of
+ {false, false} -> no_match;
+ {true, false} -> only_explicit;
+ {false, true} -> only_normal;
+ {true, true} -> both
+ end.
+
+find_terminals(Tree) ->
+ case cerl:type(Tree) of
+ apply -> {false, true};
+ binary -> {false, true};
+ bitstr -> {false, true};
+ call ->
+ M0 = cerl:call_module(Tree),
+ F0 = cerl:call_name(Tree),
+ A = length(cerl:call_args(Tree)),
+ case {is_literal(M0), is_literal(F0)} of
+ {{yes, LitM}, {yes, LitF}} ->
+ M = cerl:concrete(LitM),
+ F = cerl:concrete(LitF),
+ case (erl_bif_types:is_known(M, F, A)
+ andalso t_is_none(erl_bif_types:type(M, F, A))) of
+ true -> {true, false};
+ false -> {false, true}
+ end;
+ _ ->
+ %% We cannot make assumptions. Say that both are true.
+ {true, true}
+ end;
+ 'case' -> find_terminals_list(cerl:case_clauses(Tree));
+ 'catch' -> find_terminals(cerl:catch_body(Tree));
+ clause -> find_terminals(cerl:clause_body(Tree));
+ cons -> {false, true};
+ 'fun' -> {false, true};
+ 'let' -> find_terminals(cerl:let_body(Tree));
+ letrec -> find_terminals(cerl:letrec_body(Tree));
+ literal -> {false, true};
+ map -> {false, true};
+ primop -> {false, false}; %% match_fail, etc. are not explicit exits.
+ 'receive' ->
+ Timeout = cerl:receive_timeout(Tree),
+ Clauses = cerl:receive_clauses(Tree),
+ case (cerl:is_literal(Timeout) andalso
+ (cerl:concrete(Timeout) =:= infinity)) of
+ true ->
+ if Clauses =:= [] -> {false, true}; %% A never ending receive.
+ true -> find_terminals_list(Clauses)
+ end;
+ false -> find_terminals_list([cerl:receive_action(Tree)|Clauses])
+ end;
+ seq -> find_terminals(cerl:seq_body(Tree));
+ 'try' ->
+ find_terminals_list([cerl:try_handler(Tree), cerl:try_body(Tree)]);
+ tuple -> {false, true};
+ values -> {false, true};
+ var -> {false, true}
+ end.
+
+find_terminals_list(List) ->
+ find_terminals_list(List, false, false).
+
+find_terminals_list([Tree|Left], Explicit1, Normal1) ->
+ {Explicit2, Normal2} = find_terminals(Tree),
+ case {Explicit1 or Explicit2, Normal1 or Normal2} of
+ {true, true} = Ans -> Ans;
+ {NewExplicit, NewNormal} ->
+ find_terminals_list(Left, NewExplicit, NewNormal)
+ end;
+find_terminals_list([], Explicit, Normal) ->
+ {Explicit, Normal}.
+
+%%----------------------------------------------------------------------------
+
+-ifdef(DEBUG_PP).
+debug_pp(Tree, true) ->
+ io:put_chars(cerl_prettypr:format(Tree, [{hook, cerl_typean:pp_hook()}])),
+ io:nl(),
+ ok;
+debug_pp(Tree, false) ->
+ io:put_chars(cerl_prettypr:format(strip_annotations(Tree))),
+ io:nl(),
+ ok.
+
+strip_annotations(Tree) ->
+ Fun = fun(T) ->
+ case cerl:type(T) of
+ var ->
+ cerl:set_ann(T, [{label, cerl_trees:get_label(T)}]);
+ 'fun' ->
+ cerl:set_ann(T, [{label, cerl_trees:get_label(T)}]);
+ _ ->
+ cerl:set_ann(T, [])
+ end
+ end,
+ cerl_trees:map(Fun, Tree).
+
+-else.
+
+debug_pp(_Tree, _UseHook) ->
+ ok.
+-endif.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_races.erl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_races.erl
new file mode 100644
index 0000000000..7fe64c3e11
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_races.erl
@@ -0,0 +1,2487 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+%%%----------------------------------------------------------------------
+%%% File : dialyzer_races.erl
+%%% Author : Maria Christakis <[email protected]>
+%%% Description : Utility functions for race condition detection
+%%%
+%%% Created : 21 Nov 2008 by Maria Christakis <[email protected]>
+%%%----------------------------------------------------------------------
+-module(dialyzer_races).
+
+%% Race Analysis
+
+-export([store_race_call/5, race/1, get_race_warnings/2, format_args/4]).
+
+%% Record Interfaces
+
+-export([beg_clause_new/3, cleanup/1, end_case_new/1, end_clause_new/3,
+ get_curr_fun/1, get_curr_fun_args/1, get_new_table/1,
+ get_race_analysis/1, get_race_list/1, get_race_list_size/1,
+ get_race_list_and_size/1,
+ let_tag_new/2, new/0, put_curr_fun/3, put_fun_args/2,
+ put_race_analysis/2, put_race_list/3]).
+
+-export_type([races/0, core_vars/0]).
+
+-include("dialyzer.hrl").
+
+%%% ===========================================================================
+%%%
+%%% Definitions
+%%%
+%%% ===========================================================================
+
+-define(local, 5).
+-define(no_arg, no_arg).
+-define(no_label, no_label).
+-define(bypassed, bypassed).
+
+-define(WARN_WHEREIS_REGISTER, warn_whereis_register).
+-define(WARN_WHEREIS_UNREGISTER, warn_whereis_unregister).
+-define(WARN_ETS_LOOKUP_INSERT, warn_ets_lookup_insert).
+-define(WARN_MNESIA_DIRTY_READ_WRITE, warn_mnesia_dirty_read_write).
+-define(WARN_NO_WARN, warn_no_warn).
+
+%%% ===========================================================================
+%%%
+%%% Local Types
+%%%
+%%% ===========================================================================
+
+-type label_type() :: label() | [label()] | {label()} | ?no_label.
+-type args() :: [label_type() | [string()]].
+-type core_vars() :: cerl:cerl() | ?no_arg | ?bypassed.
+-type var_to_map1() :: core_vars() | [cerl:cerl()].
+-type var_to_map2() :: cerl:cerl() | [cerl:cerl()] | ?bypassed.
+-type core_args() :: [core_vars()] | 'empty'.
+-type op() :: 'bind' | 'unbind'.
+
+-type dep_calls() :: 'whereis' | 'ets_lookup' | 'mnesia_dirty_read'.
+-type warn_calls() :: 'register' | 'unregister' | 'ets_insert'
+ | 'mnesia_dirty_write'.
+-type call() :: 'whereis' | 'register' | 'unregister' | 'ets_new'
+ | 'ets_lookup' | 'ets_insert' | 'mnesia_dirty_read1'
+ | 'mnesia_dirty_read2' | 'mnesia_dirty_write1'
+ | 'mnesia_dirty_write2' | 'function_call'.
+-type race_tag() :: 'whereis_register' | 'whereis_unregister'
+ | 'ets_lookup_insert' | 'mnesia_dirty_read_write'.
+
+%% The following type is similar to the raw_warning() type but has a
+%% tag which is local to this module and is not propagated to outside
+-type dial_race_warning() :: {race_warn_tag(), warning_info(), {atom(), [term()]}}.
+-type race_warn_tag() :: ?WARN_WHEREIS_REGISTER | ?WARN_WHEREIS_UNREGISTER
+ | ?WARN_ETS_LOOKUP_INSERT | ?WARN_MNESIA_DIRTY_READ_WRITE.
+
+-record(beg_clause, {arg :: var_to_map1() | 'undefined',
+ pats :: var_to_map1() | 'undefined',
+ guard :: cerl:cerl() | 'undefined'}).
+-record(end_clause, {arg :: var_to_map1() | 'undefined',
+ pats :: var_to_map1() | 'undefined',
+ guard :: cerl:cerl() | 'undefined'}).
+-record(end_case, {clauses :: [#end_clause{}]}).
+-record(curr_fun, {status :: 'in' | 'out' | 'undefined',
+ mfa :: dialyzer_callgraph:mfa_or_funlbl()
+ | 'undefined',
+ label :: label() | 'undefined',
+ def_vars :: [core_vars()] | 'undefined',
+ arg_types :: [erl_types:erl_type()] | 'undefined',
+ call_vars :: [core_vars()] | 'undefined',
+ var_map :: dict:dict() | 'undefined'}).
+-record(dep_call, {call_name :: dep_calls(),
+ args :: args() | 'undefined',
+ arg_types :: [erl_types:erl_type()],
+ vars :: [core_vars()],
+ state :: dialyzer_dataflow:state(),
+ file_line :: file_line(),
+ var_map :: dict:dict() | 'undefined'}).
+-record(fun_call, {caller :: dialyzer_callgraph:mfa_or_funlbl(),
+ callee :: dialyzer_callgraph:mfa_or_funlbl(),
+ arg_types :: [erl_types:erl_type()],
+ vars :: [core_vars()]}).
+-record(let_tag, {var :: var_to_map1(),
+ arg :: var_to_map1()}).
+-record(warn_call, {call_name :: warn_calls(),
+ args :: args(),
+ var_map :: dict:dict() | 'undefined'}).
+
+-type case_tags() :: 'beg_case' | #beg_clause{} | #end_clause{} | #end_case{}.
+-type code() :: [#dep_call{} | #fun_call{} | #warn_call{} |
+ #curr_fun{} | #let_tag{} | case_tags() | race_tag()].
+
+-type table_var() :: label() | ?no_label.
+-type table() :: {'named', table_var(), [string()]} | 'other' | 'no_t'.
+
+-record(race_fun, {mfa :: mfa(),
+ args :: args(),
+ arg_types :: [erl_types:erl_type()],
+ vars :: [core_vars()],
+ file_line :: file_line(),
+ index :: non_neg_integer(),
+ fun_mfa :: dialyzer_callgraph:mfa_or_funlbl(),
+ fun_label :: label()}).
+
+-record(races, {curr_fun :: dialyzer_callgraph:mfa_or_funlbl()
+ | 'undefined',
+ curr_fun_label :: label() | 'undefined',
+ curr_fun_args = 'empty' :: core_args(),
+ new_table = 'no_t' :: table(),
+ race_list = [] :: code(),
+ race_list_size = 0 :: non_neg_integer(),
+ race_tags = [] :: [#race_fun{}],
+ %% true for fun types and warning mode
+ race_analysis = false :: boolean(),
+ race_warnings = [] :: [dial_race_warning()]}).
+
+%%% ===========================================================================
+%%%
+%%% Exported Types
+%%%
+%%% ===========================================================================
+
+-opaque races() :: #races{}.
+
+%%% ===========================================================================
+%%%
+%%% Race Analysis
+%%%
+%%% ===========================================================================
+
+-spec store_race_call(dialyzer_callgraph:mfa_or_funlbl(),
+ [erl_types:erl_type()], [core_vars()],
+ file_line(), dialyzer_dataflow:state()) ->
+ dialyzer_dataflow:state().
+
+store_race_call(Fun, ArgTypes, Args, FileLine, State) ->
+ Races = dialyzer_dataflow:state__get_races(State),
+ CurrFun = Races#races.curr_fun,
+ CurrFunLabel = Races#races.curr_fun_label,
+ RaceTags = Races#races.race_tags,
+ CleanState = dialyzer_dataflow:state__records_only(State),
+ {NewRaceList, NewRaceListSize, NewRaceTags, NewTable} =
+ case CurrFun of
+ {_Module, module_info, A} when A =:= 0 orelse A =:= 1 ->
+ {[], 0, RaceTags, no_t};
+ _Thing ->
+ RaceList = Races#races.race_list,
+ RaceListSize = Races#races.race_list_size,
+ case Fun of
+ {erlang, get_module_info, A} when A =:= 1 orelse A =:= 2 ->
+ {[], 0, RaceTags, no_t};
+ {erlang, register, 2} ->
+ VarArgs = format_args(Args, ArgTypes, CleanState, register),
+ RaceFun = #race_fun{mfa = Fun, args = VarArgs,
+ arg_types = ArgTypes, vars = Args,
+ file_line = FileLine, index = RaceListSize,
+ fun_mfa = CurrFun, fun_label = CurrFunLabel},
+ {[#warn_call{call_name = register, args = VarArgs}|
+ RaceList], RaceListSize + 1, [RaceFun|RaceTags], no_t};
+ {erlang, unregister, 1} ->
+ VarArgs = format_args(Args, ArgTypes, CleanState, unregister),
+ RaceFun = #race_fun{mfa = Fun, args = VarArgs,
+ arg_types = ArgTypes, vars = Args,
+ file_line = FileLine, index = RaceListSize,
+ fun_mfa = CurrFun, fun_label = CurrFunLabel},
+ {[#warn_call{call_name = unregister, args = VarArgs}|
+ RaceList], RaceListSize + 1, [RaceFun|RaceTags], no_t};
+ {erlang, whereis, 1} ->
+ VarArgs = format_args(Args, ArgTypes, CleanState, whereis),
+ {[#dep_call{call_name = whereis, args = VarArgs,
+ arg_types = ArgTypes, vars = Args,
+ state = CleanState, file_line = FileLine}|
+ RaceList], RaceListSize + 1, RaceTags, no_t};
+ {ets, insert, 2} ->
+ VarArgs = format_args(Args, ArgTypes, CleanState, ets_insert),
+ RaceFun = #race_fun{mfa = Fun, args = VarArgs,
+ arg_types = ArgTypes, vars = Args,
+ file_line = FileLine, index = RaceListSize,
+ fun_mfa = CurrFun, fun_label = CurrFunLabel},
+ {[#warn_call{call_name = ets_insert, args = VarArgs}|
+ RaceList], RaceListSize + 1, [RaceFun|RaceTags], no_t};
+ {ets, lookup, 2} ->
+ VarArgs = format_args(Args, ArgTypes, CleanState, ets_lookup),
+ {[#dep_call{call_name = ets_lookup, args = VarArgs,
+ arg_types = ArgTypes, vars = Args,
+ state = CleanState, file_line = FileLine}|
+ RaceList], RaceListSize + 1, RaceTags, no_t};
+ {ets, new, 2} ->
+ VarArgs = format_args(Args, ArgTypes, CleanState, ets_new),
+ [VarArgs1, VarArgs2, _, Options] = VarArgs,
+ NewTable1 =
+ case lists:member("'public'", Options) of
+ true ->
+ case lists:member("'named_table'", Options) of
+ true ->
+ {named, VarArgs1, VarArgs2};
+ false -> other
+ end;
+ false -> no_t
+ end,
+ {RaceList, RaceListSize, RaceTags, NewTable1};
+ {mnesia, dirty_read, A} when A =:= 1 orelse A =:= 2 ->
+ VarArgs =
+ case A of
+ 1 ->
+ format_args(Args, ArgTypes, CleanState, mnesia_dirty_read1);
+ 2 ->
+ format_args(Args, ArgTypes, CleanState, mnesia_dirty_read2)
+ end,
+ {[#dep_call{call_name = mnesia_dirty_read, args = VarArgs,
+ arg_types = ArgTypes, vars = Args,
+ state = CleanState, file_line = FileLine}|RaceList],
+ RaceListSize + 1, RaceTags, no_t};
+ {mnesia, dirty_write, A} when A =:= 1 orelse A =:= 2 ->
+ VarArgs =
+ case A of
+ 1 ->
+ format_args(Args, ArgTypes, CleanState, mnesia_dirty_write1);
+ 2 ->
+ format_args(Args, ArgTypes, CleanState, mnesia_dirty_write2)
+ end,
+ RaceFun = #race_fun{mfa = Fun, args = VarArgs,
+ arg_types = ArgTypes, vars = Args,
+ file_line = FileLine, index = RaceListSize,
+ fun_mfa = CurrFun, fun_label = CurrFunLabel},
+ {[#warn_call{call_name = mnesia_dirty_write,
+ args = VarArgs}|RaceList],
+ RaceListSize + 1, [RaceFun|RaceTags], no_t};
+ Int when is_integer(Int) ->
+ {[#fun_call{caller = CurrFun, callee = Int, arg_types = ArgTypes,
+ vars = Args}|RaceList],
+ RaceListSize + 1, RaceTags, no_t};
+ _Other ->
+ Callgraph = dialyzer_dataflow:state__get_callgraph(State),
+ case digraph:vertex(dialyzer_callgraph:get_digraph(Callgraph),
+ Fun) of
+ {Fun, confirmed} ->
+ {[#fun_call{caller = CurrFun, callee = Fun,
+ arg_types = ArgTypes, vars = Args}|RaceList],
+ RaceListSize + 1, RaceTags, no_t};
+ false ->
+ {RaceList, RaceListSize, RaceTags, no_t}
+ end
+ end
+ end,
+ state__renew_info(NewRaceList, NewRaceListSize, NewRaceTags, NewTable, State).
+
+-spec race(dialyzer_dataflow:state()) -> dialyzer_dataflow:state().
+
+race(State) ->
+ Races = dialyzer_dataflow:state__get_races(State),
+ RaceTags = Races#races.race_tags,
+ RetState =
+ case RaceTags of
+ [] -> State;
+ [#race_fun{mfa = Fun,
+ args = VarArgs, arg_types = ArgTypes,
+ vars = Args, file_line = FileLine,
+ index = Index, fun_mfa = CurrFun,
+ fun_label = CurrFunLabel}|T] ->
+ Callgraph = dialyzer_dataflow:state__get_callgraph(State),
+ {ok, [_Args, Code]} =
+ dict:find(CurrFun, dialyzer_callgraph:get_race_code(Callgraph)),
+ RaceList = lists:reverse(Code),
+ RaceWarnTag =
+ case Fun of
+ {erlang, register, 2} -> ?WARN_WHEREIS_REGISTER;
+ {erlang, unregister, 1} -> ?WARN_WHEREIS_UNREGISTER;
+ {ets, insert, 2} -> ?WARN_ETS_LOOKUP_INSERT;
+ {mnesia, dirty_write, _A} -> ?WARN_MNESIA_DIRTY_READ_WRITE
+ end,
+ State1 =
+ state__renew_curr_fun(CurrFun,
+ state__renew_curr_fun_label(CurrFunLabel,
+ state__renew_race_list(lists:nthtail(length(RaceList) - Index,
+ RaceList), State))),
+ DepList = fixup_race_list(RaceWarnTag, VarArgs, State1),
+ {State2, RaceWarn} =
+ get_race_warn(Fun, Args, ArgTypes, DepList, State),
+ {File, Line} = FileLine,
+ CurrMFA = dialyzer_dataflow:state__find_function(CurrFun, State),
+ WarningInfo = {File, Line, CurrMFA},
+ race(
+ state__add_race_warning(
+ state__renew_race_tags(T, State2), RaceWarn, RaceWarnTag,
+ WarningInfo))
+ end,
+ state__renew_race_tags([], RetState).
+
+fixup_race_list(RaceWarnTag, WarnVarArgs, State) ->
+ Races = dialyzer_dataflow:state__get_races(State),
+ CurrFun = Races#races.curr_fun,
+ CurrFunLabel = Races#races.curr_fun_label,
+ RaceList = Races#races.race_list,
+ Callgraph = dialyzer_dataflow:state__get_callgraph(State),
+ Digraph = dialyzer_callgraph:get_digraph(Callgraph),
+ Calls = digraph:edges(Digraph),
+ RaceTag =
+ case RaceWarnTag of
+ ?WARN_WHEREIS_REGISTER -> whereis_register;
+ ?WARN_WHEREIS_UNREGISTER -> whereis_unregister;
+ ?WARN_ETS_LOOKUP_INSERT -> ets_lookup_insert;
+ ?WARN_MNESIA_DIRTY_READ_WRITE -> mnesia_dirty_read_write
+ end,
+ NewRaceList = [RaceTag|RaceList],
+ CleanState = dialyzer_dataflow:state__cleanup(State),
+ NewState = state__renew_race_list(NewRaceList, CleanState),
+ DepList1 =
+ fixup_race_forward_pullout(CurrFun, CurrFunLabel, Calls,
+ lists:reverse(NewRaceList), [], CurrFun,
+ WarnVarArgs, RaceWarnTag, dict:new(),
+ [], [], [], 2 * ?local, NewState),
+ Parents = fixup_race_backward(CurrFun, Calls, Calls, [], ?local),
+ UParents = lists:usort(Parents),
+ Filtered = filter_parents(UParents, UParents, Digraph),
+ NewParents =
+ case lists:member(CurrFun, Filtered) of
+ true -> Filtered;
+ false -> [CurrFun|Filtered]
+ end,
+ DepList2 =
+ fixup_race_list_helper(NewParents, Calls, CurrFun, WarnVarArgs,
+ RaceWarnTag, NewState),
+ dialyzer_dataflow:dispose_state(CleanState),
+ lists:usort(cleanup_dep_calls(DepList1 ++ DepList2)).
+
+fixup_race_list_helper(Parents, Calls, CurrFun, WarnVarArgs, RaceWarnTag,
+ State) ->
+ case Parents of
+ [] -> [];
+ [Head|Tail] ->
+ Callgraph = dialyzer_dataflow:state__get_callgraph(State),
+ Code =
+ case dict:find(Head, dialyzer_callgraph:get_race_code(Callgraph)) of
+ error -> [];
+ {ok, [_A, C]} -> C
+ end,
+ {ok, FunLabel} = dialyzer_callgraph:lookup_label(Head, Callgraph),
+ DepList1 =
+ fixup_race_forward_pullout(Head, FunLabel, Calls, Code, [], CurrFun,
+ WarnVarArgs, RaceWarnTag, dict:new(),
+ [], [], [], 2 * ?local, State),
+ DepList2 =
+ fixup_race_list_helper(Tail, Calls, CurrFun, WarnVarArgs,
+ RaceWarnTag, State),
+ DepList1 ++ DepList2
+ end.
+
+%%% ===========================================================================
+%%%
+%%% Forward Analysis
+%%%
+%%% ===========================================================================
+
+fixup_race_forward_pullout(CurrFun, CurrFunLabel, Calls, Code, RaceList,
+ InitFun, WarnVarArgs, RaceWarnTag, RaceVarMap,
+ FunDefVars, FunCallVars, FunArgTypes, NestingLevel,
+ State) ->
+ TState = dialyzer_dataflow:state__duplicate(State),
+ {DepList, NewCurrFun, NewCurrFunLabel, NewCalls,
+ NewCode, NewRaceList, NewRaceVarMap, NewFunDefVars,
+ NewFunCallVars, NewFunArgTypes, NewNestingLevel} =
+ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList,
+ InitFun, WarnVarArgs, RaceWarnTag, RaceVarMap,
+ FunDefVars, FunCallVars, FunArgTypes, NestingLevel,
+ cleanup_race_code(TState)),
+ dialyzer_dataflow:dispose_state(TState),
+ case NewCode of
+ [] -> DepList;
+ [#fun_call{caller = NewCurrFun, callee = Call, arg_types = FunTypes,
+ vars = FunArgs}|Tail] ->
+ Callgraph = dialyzer_dataflow:state__get_callgraph(State),
+ OkCall = {ok, Call},
+ {Name, Label} =
+ case is_integer(Call) of
+ true ->
+ case dialyzer_callgraph:lookup_name(Call, Callgraph) of
+ error -> {OkCall, OkCall};
+ N -> {N, OkCall}
+ end;
+ false ->
+ {OkCall, dialyzer_callgraph:lookup_label(Call, Callgraph)}
+ end,
+ {NewCurrFun1, NewCurrFunLabel1, NewCalls1, NewCode1, NewRaceList1,
+ NewRaceVarMap1, NewFunDefVars1, NewFunCallVars1, NewFunArgTypes1,
+ NewNestingLevel1} =
+ case Label =:= error of
+ true ->
+ {NewCurrFun, NewCurrFunLabel, NewCalls, Tail, NewRaceList,
+ NewRaceVarMap, NewFunDefVars, NewFunCallVars, NewFunArgTypes,
+ NewNestingLevel};
+ false ->
+ {ok, Fun} = Name,
+ {ok, Int} = Label,
+ case dict:find(Fun, dialyzer_callgraph:get_race_code(Callgraph)) of
+ error ->
+ {NewCurrFun, NewCurrFunLabel, NewCalls, Tail, NewRaceList,
+ NewRaceVarMap, NewFunDefVars, NewFunCallVars, NewFunArgTypes,
+ NewNestingLevel};
+ {ok, [Args, CodeB]} ->
+ Races = dialyzer_dataflow:state__get_races(State),
+ {RetCurrFun, RetCurrFunLabel, RetCalls, RetCode,
+ RetRaceList, RetRaceVarMap, RetFunDefVars, RetFunCallVars,
+ RetFunArgTypes, RetNestingLevel} =
+ fixup_race_forward_helper(NewCurrFun,
+ NewCurrFunLabel, Fun, Int, NewCalls, NewCalls,
+ [#curr_fun{status = out, mfa = NewCurrFun,
+ label = NewCurrFunLabel,
+ var_map = NewRaceVarMap,
+ def_vars = NewFunDefVars,
+ call_vars = NewFunCallVars,
+ arg_types = NewFunArgTypes}|
+ Tail],
+ NewRaceList, InitFun, FunArgs, FunTypes, RaceWarnTag,
+ NewRaceVarMap, NewFunDefVars, NewFunCallVars,
+ NewFunArgTypes, NewNestingLevel, Args, CodeB,
+ Races#races.race_list),
+ case RetCode of
+ [#curr_fun{}|_CodeTail] ->
+ {NewCurrFun, NewCurrFunLabel, RetCalls, RetCode,
+ RetRaceList, NewRaceVarMap, NewFunDefVars,
+ NewFunCallVars, NewFunArgTypes, RetNestingLevel};
+ _Else ->
+ {RetCurrFun, RetCurrFunLabel, RetCalls, RetCode,
+ RetRaceList, RetRaceVarMap, RetFunDefVars,
+ RetFunCallVars, RetFunArgTypes, RetNestingLevel}
+ end
+ end
+ end,
+ DepList ++
+ fixup_race_forward_pullout(NewCurrFun1, NewCurrFunLabel1, NewCalls1,
+ NewCode1, NewRaceList1, InitFun, WarnVarArgs,
+ RaceWarnTag, NewRaceVarMap1, NewFunDefVars1,
+ NewFunCallVars1, NewFunArgTypes1,
+ NewNestingLevel1, State)
+ end.
+
+fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList,
+ InitFun, WarnVarArgs, RaceWarnTag, RaceVarMap,
+ FunDefVars, FunCallVars, FunArgTypes, NestingLevel,
+ State) ->
+ case Code of
+ [] ->
+ {[], CurrFun, CurrFunLabel, Calls, Code, RaceList, RaceVarMap,
+ FunDefVars, FunCallVars, FunArgTypes, NestingLevel};
+ [Head|Tail] ->
+ Callgraph = dialyzer_dataflow:state__get_callgraph(State),
+ {NewRL, DepList, NewNL, Return} =
+ case Head of
+ #dep_call{call_name = whereis} ->
+ case RaceWarnTag of
+ WarnWhereis when WarnWhereis =:= ?WARN_WHEREIS_REGISTER orelse
+ WarnWhereis =:= ?WARN_WHEREIS_UNREGISTER ->
+ {[Head#dep_call{var_map = RaceVarMap}|RaceList],
+ [], NestingLevel, false};
+ _Other ->
+ {RaceList, [], NestingLevel, false}
+ end;
+ #dep_call{call_name = ets_lookup} ->
+ case RaceWarnTag of
+ ?WARN_ETS_LOOKUP_INSERT ->
+ {[Head#dep_call{var_map = RaceVarMap}|RaceList],
+ [], NestingLevel, false};
+ _Other ->
+ {RaceList, [], NestingLevel, false}
+ end;
+ #dep_call{call_name = mnesia_dirty_read} ->
+ case RaceWarnTag of
+ ?WARN_MNESIA_DIRTY_READ_WRITE ->
+ {[Head#dep_call{var_map = RaceVarMap}|RaceList],
+ [], NestingLevel, false};
+ _Other ->
+ {RaceList, [], NestingLevel, false}
+ end;
+ #warn_call{call_name = RegCall} when RegCall =:= register orelse
+ RegCall =:= unregister ->
+ case RaceWarnTag of
+ WarnWhereis when WarnWhereis =:= ?WARN_WHEREIS_REGISTER orelse
+ WarnWhereis =:= ?WARN_WHEREIS_UNREGISTER ->
+ {[Head#warn_call{var_map = RaceVarMap}|RaceList],
+ [], NestingLevel, false};
+ _Other ->
+ {RaceList, [], NestingLevel, false}
+ end;
+ #warn_call{call_name = ets_insert} ->
+ case RaceWarnTag of
+ ?WARN_ETS_LOOKUP_INSERT ->
+ {[Head#warn_call{var_map = RaceVarMap}|RaceList],
+ [], NestingLevel, false};
+ _Other ->
+ {RaceList, [], NestingLevel, false}
+ end;
+ #warn_call{call_name = mnesia_dirty_write} ->
+ case RaceWarnTag of
+ ?WARN_MNESIA_DIRTY_READ_WRITE ->
+ {[Head#warn_call{var_map = RaceVarMap}|RaceList],
+ [], NestingLevel, false};
+ _Other ->
+ {RaceList, [], NestingLevel, false}
+ end;
+ #fun_call{caller = CurrFun, callee = InitFun} ->
+ {RaceList, [], NestingLevel, false};
+ #fun_call{caller = CurrFun} ->
+ {RaceList, [], NestingLevel - 1, false};
+ beg_case ->
+ {[Head|RaceList], [], NestingLevel, false};
+ #beg_clause{} ->
+ {[#beg_clause{}|RaceList], [], NestingLevel, false};
+ #end_clause{} ->
+ {[#end_clause{}|RaceList], [], NestingLevel, false};
+ #end_case{} ->
+ {[Head|RaceList], [], NestingLevel, false};
+ #let_tag{} ->
+ {RaceList, [], NestingLevel, false};
+ #curr_fun{status = in, mfa = InitFun,
+ label = _InitFunLabel, var_map = _NewRVM,
+ def_vars = NewFDV, call_vars = NewFCV,
+ arg_types = _NewFAT} ->
+ {[#curr_fun{status = out, var_map = RaceVarMap,
+ def_vars = NewFDV, call_vars = NewFCV}|
+ RaceList], [], NestingLevel - 1, false};
+ #curr_fun{status = in, def_vars = NewFDV,
+ call_vars = NewFCV} ->
+ {[#curr_fun{status = out, var_map = RaceVarMap,
+ def_vars = NewFDV, call_vars = NewFCV}|
+ RaceList],
+ [], NestingLevel - 1, false};
+ #curr_fun{status = out} ->
+ {[#curr_fun{status = in, var_map = RaceVarMap}|RaceList], [],
+ NestingLevel + 1, false};
+ RaceTag ->
+ PublicTables = dialyzer_callgraph:get_public_tables(Callgraph),
+ NamedTables = dialyzer_callgraph:get_named_tables(Callgraph),
+ WarnVarArgs1 =
+ var_type_analysis(FunDefVars, FunArgTypes, WarnVarArgs,
+ RaceWarnTag, RaceVarMap,
+ dialyzer_dataflow:state__records_only(State)),
+ {NewDepList, IsPublic, _Return} =
+ get_deplist_paths(RaceList, WarnVarArgs1, RaceWarnTag,
+ RaceVarMap, 0, PublicTables, NamedTables),
+ {NewHead, NewDepList1} =
+ case RaceTag of
+ whereis_register ->
+ {[#warn_call{call_name = register, args = WarnVarArgs,
+ var_map = RaceVarMap}],
+ NewDepList};
+ whereis_unregister ->
+ {[#warn_call{call_name = unregister, args = WarnVarArgs,
+ var_map = RaceVarMap}],
+ NewDepList};
+ ets_lookup_insert ->
+ NewWarnCall =
+ [#warn_call{call_name = ets_insert, args = WarnVarArgs,
+ var_map = RaceVarMap}],
+ [Tab, Names, _, _] = WarnVarArgs,
+ case IsPublic orelse
+ compare_var_list(Tab, PublicTables, RaceVarMap)
+ orelse
+ length(Names -- NamedTables) < length(Names) of
+ true ->
+ {NewWarnCall, NewDepList};
+ false -> {NewWarnCall, []}
+ end;
+ mnesia_dirty_read_write ->
+ {[#warn_call{call_name = mnesia_dirty_write,
+ args = WarnVarArgs, var_map = RaceVarMap}],
+ NewDepList}
+ end,
+ {NewHead ++ RaceList, NewDepList1, NestingLevel,
+ is_last_race(RaceTag, InitFun, Tail, Callgraph)}
+ end,
+ {NewCurrFun, NewCurrFunLabel, NewCode, NewRaceList, NewRaceVarMap,
+ NewFunDefVars, NewFunCallVars, NewFunArgTypes, NewNestingLevel,
+ PullOut} =
+ case Head of
+ #fun_call{caller = CurrFun} ->
+ case NewNL =:= 0 of
+ true ->
+ {CurrFun, CurrFunLabel, Tail, NewRL, RaceVarMap,
+ FunDefVars, FunCallVars, FunArgTypes, NewNL, false};
+ false ->
+ {CurrFun, CurrFunLabel, Code, NewRL, RaceVarMap,
+ FunDefVars, FunCallVars, FunArgTypes, NewNL, true}
+ end;
+ #beg_clause{arg = Arg, pats = Pats, guard = Guard} ->
+ {RaceVarMap1, RemoveClause} =
+ race_var_map_guard(Arg, Pats, Guard, RaceVarMap, bind),
+ case RemoveClause of
+ true ->
+ {RaceList2,
+ #curr_fun{mfa = CurrFun2, label = CurrFunLabel2,
+ var_map = RaceVarMap2, def_vars = FunDefVars2,
+ call_vars = FunCallVars2, arg_types = FunArgTypes2},
+ Code2, NestingLevel2} =
+ remove_clause(NewRL,
+ #curr_fun{mfa = CurrFun, label = CurrFunLabel,
+ var_map = RaceVarMap1,
+ def_vars = FunDefVars,
+ call_vars = FunCallVars,
+ arg_types = FunArgTypes},
+ Tail, NewNL),
+ {CurrFun2, CurrFunLabel2, Code2, RaceList2,
+ RaceVarMap2, FunDefVars2, FunCallVars2, FunArgTypes2,
+ NestingLevel2, false};
+ false ->
+ {CurrFun, CurrFunLabel, Tail, NewRL, RaceVarMap1,
+ FunDefVars, FunCallVars, FunArgTypes, NewNL, false}
+ end;
+ #end_clause{arg = Arg, pats = Pats, guard = Guard} ->
+ {RaceVarMap1, _RemoveClause} =
+ race_var_map_guard(Arg, Pats, Guard, RaceVarMap, unbind),
+ {CurrFun, CurrFunLabel, Tail, NewRL, RaceVarMap1,
+ FunDefVars, FunCallVars, FunArgTypes, NewNL,
+ false};
+ #end_case{clauses = Clauses} ->
+ RaceVarMap1 =
+ race_var_map_clauses(Clauses, RaceVarMap),
+ {CurrFun, CurrFunLabel, Tail, NewRL, RaceVarMap1,
+ FunDefVars, FunCallVars, FunArgTypes, NewNL,
+ false};
+ #let_tag{var = Var, arg = Arg} ->
+ {CurrFun, CurrFunLabel, Tail, NewRL,
+ race_var_map(Var, Arg, RaceVarMap, bind), FunDefVars,
+ FunCallVars, FunArgTypes, NewNL, false};
+ #curr_fun{mfa = CurrFun1, label = CurrFunLabel1,
+ var_map = RaceVarMap1, def_vars = FunDefVars1,
+ call_vars = FunCallVars1, arg_types = FunArgTypes1} ->
+ case NewNL =:= 0 of
+ true ->
+ {CurrFun, CurrFunLabel,
+ remove_nonlocal_functions(Tail, 1), NewRL, RaceVarMap,
+ FunDefVars, FunCallVars, FunArgTypes, NewNL, false};
+ false ->
+ {CurrFun1, CurrFunLabel1, Tail, NewRL, RaceVarMap1,
+ FunDefVars1, FunCallVars1, FunArgTypes1, NewNL, false}
+ end;
+ _Thing ->
+ {CurrFun, CurrFunLabel, Tail, NewRL, RaceVarMap,
+ FunDefVars, FunCallVars, FunArgTypes, NewNL, false}
+ end,
+ case Return of
+ true ->
+ {DepList, NewCurrFun, NewCurrFunLabel, Calls,
+ [], NewRaceList, NewRaceVarMap, NewFunDefVars,
+ NewFunCallVars, NewFunArgTypes, NewNestingLevel};
+ false ->
+ NewNestingLevel1 =
+ case NewNestingLevel =:= 0 of
+ true -> NewNestingLevel + 1;
+ false -> NewNestingLevel
+ end,
+ case PullOut of
+ true ->
+ {DepList, NewCurrFun, NewCurrFunLabel, Calls,
+ NewCode, NewRaceList, NewRaceVarMap, NewFunDefVars,
+ NewFunCallVars, NewFunArgTypes, NewNestingLevel1};
+ false ->
+ {RetDepList, NewCurrFun1, NewCurrFunLabel1, NewCalls1,
+ NewCode1, NewRaceList1, NewRaceVarMap1, NewFunDefVars1,
+ NewFunCallVars1, NewFunArgTypes1, NewNestingLevel2} =
+ fixup_race_forward(NewCurrFun, NewCurrFunLabel, Calls,
+ NewCode, NewRaceList, InitFun, WarnVarArgs,
+ RaceWarnTag, NewRaceVarMap, NewFunDefVars,
+ NewFunCallVars, NewFunArgTypes,
+ NewNestingLevel1, State),
+ {DepList ++ RetDepList, NewCurrFun1, NewCurrFunLabel1,
+ NewCalls1, NewCode1, NewRaceList1, NewRaceVarMap1,
+ NewFunDefVars1, NewFunCallVars1, NewFunArgTypes1,
+ NewNestingLevel2}
+ end
+ end
+ end.
+
+get_deplist_paths(RaceList, WarnVarArgs, RaceWarnTag, RaceVarMap, CurrLevel,
+ PublicTables, NamedTables) ->
+ case RaceList of
+ [] -> {[], false, true};
+ [Head|Tail] ->
+ case Head of
+ #end_case{} ->
+ {RaceList1, DepList1, IsPublic1, Continue1} =
+ handle_case(Tail, WarnVarArgs, RaceWarnTag, RaceVarMap, CurrLevel,
+ PublicTables, NamedTables),
+ case Continue1 of
+ true ->
+ {DepList2, IsPublic2, Continue2} =
+ get_deplist_paths(RaceList1, WarnVarArgs, RaceWarnTag,
+ RaceVarMap, CurrLevel, PublicTables,
+ NamedTables),
+ {DepList1 ++ DepList2, IsPublic1 orelse IsPublic2, Continue2};
+ false -> {DepList1, IsPublic1, false}
+ end;
+ #beg_clause{} ->
+ get_deplist_paths(fixup_before_case_path(Tail), WarnVarArgs,
+ RaceWarnTag, RaceVarMap, CurrLevel, PublicTables,
+ NamedTables);
+ #curr_fun{status = in, var_map = RaceVarMap1} ->
+ {DepList, IsPublic, Continue} =
+ get_deplist_paths(Tail, WarnVarArgs, RaceWarnTag, RaceVarMap,
+ CurrLevel + 1, PublicTables, NamedTables),
+ IsPublic1 =
+ case RaceWarnTag of
+ ?WARN_ETS_LOOKUP_INSERT ->
+ [Tabs, Names, _, _] = WarnVarArgs,
+ IsPublic orelse
+ lists:any(
+ fun (T) ->
+ compare_var_list(T, PublicTables, RaceVarMap1)
+ end, Tabs)
+ orelse
+ length(Names -- NamedTables) < length(Names);
+ _ -> true
+ end,
+ {DepList, IsPublic1, Continue};
+ #curr_fun{status = out, var_map = RaceVarMap1, def_vars = FunDefVars,
+ call_vars = FunCallVars} ->
+ WarnVarArgs1 =
+ var_analysis([format_arg(DefVar) || DefVar <- FunDefVars],
+ [format_arg(CallVar) || CallVar <- FunCallVars],
+ WarnVarArgs, RaceWarnTag),
+ {WarnVarArgs2, Stop} =
+ case RaceWarnTag of
+ ?WARN_WHEREIS_REGISTER ->
+ [WVA1, WVA2, WVA3, WVA4] = WarnVarArgs1,
+ Vars =
+ lists:flatten(
+ [find_all_bound_vars(V, RaceVarMap1) || V <- WVA1]),
+ case {Vars, CurrLevel} of
+ {[], 0} ->
+ {WarnVarArgs, true};
+ {[], _} ->
+ {WarnVarArgs, false};
+ _ ->
+ {[Vars, WVA2, WVA3, WVA4], false}
+ end;
+ ?WARN_WHEREIS_UNREGISTER ->
+ [WVA1, WVA2] = WarnVarArgs1,
+ Vars =
+ lists:flatten(
+ [find_all_bound_vars(V, RaceVarMap1) || V <- WVA1]),
+ case {Vars, CurrLevel} of
+ {[], 0} ->
+ {WarnVarArgs, true};
+ {[], _} ->
+ {WarnVarArgs, false};
+ _ ->
+ {[Vars, WVA2], false}
+ end;
+ ?WARN_ETS_LOOKUP_INSERT ->
+ [WVA1, WVA2, WVA3, WVA4] = WarnVarArgs1,
+ Vars1 =
+ lists:flatten(
+ [find_all_bound_vars(V1, RaceVarMap1) || V1 <- WVA1]),
+ Vars2 =
+ lists:flatten(
+ [find_all_bound_vars(V2, RaceVarMap1) || V2 <- WVA3]),
+ case {Vars1, Vars2, CurrLevel} of
+ {[], _, 0} ->
+ {WarnVarArgs, true};
+ {[], _, _} ->
+ {WarnVarArgs, false};
+ {_, [], 0} ->
+ {WarnVarArgs, true};
+ {_, [], _} ->
+ {WarnVarArgs, false};
+ _ ->
+ {[Vars1, WVA2, Vars2, WVA4], false}
+ end;
+ ?WARN_MNESIA_DIRTY_READ_WRITE ->
+ [WVA1, WVA2|T] = WarnVarArgs1,
+ Vars =
+ lists:flatten(
+ [find_all_bound_vars(V, RaceVarMap1) || V <- WVA1]),
+ case {Vars, CurrLevel} of
+ {[], 0} ->
+ {WarnVarArgs, true};
+ {[], _} ->
+ {WarnVarArgs, false};
+ _ ->
+ {[Vars, WVA2|T], false}
+ end
+ end,
+ case Stop of
+ true -> {[], false, false};
+ false ->
+ CurrLevel1 =
+ case CurrLevel of
+ 0 -> CurrLevel;
+ _ -> CurrLevel - 1
+ end,
+ get_deplist_paths(Tail, WarnVarArgs2, RaceWarnTag, RaceVarMap1,
+ CurrLevel1, PublicTables, NamedTables)
+ end;
+ #warn_call{call_name = RegCall, args = WarnVarArgs1,
+ var_map = RaceVarMap1} when RegCall =:= register orelse
+ RegCall =:= unregister ->
+ case compare_first_arg(WarnVarArgs, WarnVarArgs1, RaceVarMap1) of
+ true -> {[], false, false};
+ NewWarnVarArgs ->
+ get_deplist_paths(Tail, NewWarnVarArgs, RaceWarnTag, RaceVarMap,
+ CurrLevel, PublicTables, NamedTables)
+ end;
+ #warn_call{call_name = ets_insert, args = WarnVarArgs1,
+ var_map = RaceVarMap1} ->
+ case compare_ets_insert(WarnVarArgs, WarnVarArgs1, RaceVarMap1) of
+ true -> {[], false, false};
+ NewWarnVarArgs ->
+ get_deplist_paths(Tail, NewWarnVarArgs, RaceWarnTag, RaceVarMap,
+ CurrLevel, PublicTables, NamedTables)
+ end;
+ #warn_call{call_name = mnesia_dirty_write, args = WarnVarArgs1,
+ var_map = RaceVarMap1} ->
+ case compare_first_arg(WarnVarArgs, WarnVarArgs1, RaceVarMap1) of
+ true -> {[], false, false};
+ NewWarnVarArgs ->
+ get_deplist_paths(Tail, NewWarnVarArgs, RaceWarnTag, RaceVarMap,
+ CurrLevel, PublicTables, NamedTables)
+ end;
+ #dep_call{var_map = RaceVarMap1} ->
+ {DepList, IsPublic, Continue} =
+ get_deplist_paths(Tail, WarnVarArgs, RaceWarnTag, RaceVarMap,
+ CurrLevel, PublicTables, NamedTables),
+ {refine_race(Head, WarnVarArgs, RaceWarnTag, DepList, RaceVarMap1),
+ IsPublic, Continue}
+ end
+ end.
+
+handle_case(RaceList, WarnVarArgs, RaceWarnTag, RaceVarMap, CurrLevel,
+ PublicTables, NamedTables) ->
+ case RaceList of
+ [] -> {[], [], false, true};
+ [Head|Tail] ->
+ case Head of
+ #end_clause{} ->
+ {RestRaceList, DepList1, IsPublic1, Continue1} =
+ do_clause(Tail, WarnVarArgs, RaceWarnTag, RaceVarMap, CurrLevel,
+ PublicTables, NamedTables),
+ {RetRaceList, DepList2, IsPublic2, Continue2} =
+ handle_case(RestRaceList, WarnVarArgs, RaceWarnTag, RaceVarMap,
+ CurrLevel, PublicTables, NamedTables),
+ {RetRaceList, DepList1 ++ DepList2, IsPublic1 orelse IsPublic2,
+ Continue1 orelse Continue2};
+ beg_case -> {Tail, [], false, false}
+ end
+ end.
+
+do_clause(RaceList, WarnVarArgs, RaceWarnTag, RaceVarMap, CurrLevel,
+ PublicTables, NamedTables) ->
+ {DepList, IsPublic, Continue} =
+ get_deplist_paths(fixup_case_path(RaceList, 0), WarnVarArgs,
+ RaceWarnTag, RaceVarMap, CurrLevel,
+ PublicTables, NamedTables),
+ {fixup_case_rest_paths(RaceList, 0), DepList, IsPublic, Continue}.
+
+fixup_case_path(RaceList, NestingLevel) ->
+ case RaceList of
+ [] -> [];
+ [Head|Tail] ->
+ {NewNestingLevel, Return} =
+ case Head of
+ beg_case -> {NestingLevel - 1, false};
+ #end_case{} -> {NestingLevel + 1, false};
+ #beg_clause{} ->
+ case NestingLevel =:= 0 of
+ true -> {NestingLevel, true};
+ false -> {NestingLevel, false}
+ end;
+ _Other -> {NestingLevel, false}
+ end,
+ case Return of
+ true -> [];
+ false -> [Head|fixup_case_path(Tail, NewNestingLevel)]
+ end
+ end.
+
+%% Gets the race list before a case clause.
+fixup_before_case_path(RaceList) ->
+ case RaceList of
+ [] -> [];
+ [Head|Tail] ->
+ case Head of
+ #end_clause{} ->
+ fixup_before_case_path(fixup_case_rest_paths(Tail, 0));
+ beg_case -> Tail
+ end
+ end.
+
+fixup_case_rest_paths(RaceList, NestingLevel) ->
+ case RaceList of
+ [] -> [];
+ [Head|Tail] ->
+ {NewNestingLevel, Return} =
+ case Head of
+ beg_case -> {NestingLevel - 1, false};
+ #end_case{} -> {NestingLevel + 1, false};
+ #beg_clause{} ->
+ case NestingLevel =:= 0 of
+ true -> {NestingLevel, true};
+ false -> {NestingLevel, false}
+ end;
+ _Other -> {NestingLevel, false}
+ end,
+ case Return of
+ true -> Tail;
+ false -> fixup_case_rest_paths(Tail, NewNestingLevel)
+ end
+ end.
+
+fixup_race_forward_helper(CurrFun, CurrFunLabel, Fun, FunLabel,
+ Calls, CallsToAnalyze, Code, RaceList,
+ InitFun, NewFunArgs, NewFunTypes,
+ RaceWarnTag, RaceVarMap, FunDefVars,
+ FunCallVars, FunArgTypes, NestingLevel,
+ Args, CodeB, StateRaceList) ->
+ case Calls of
+ [] ->
+ {NewRaceList,
+ #curr_fun{mfa = NewCurrFun, label = NewCurrFunLabel,
+ var_map = NewRaceVarMap, def_vars = NewFunDefVars,
+ call_vars = NewFunCallVars, arg_types = NewFunArgTypes},
+ NewCode, NewNestingLevel} =
+ remove_clause(RaceList,
+ #curr_fun{mfa = CurrFun, label = CurrFunLabel, var_map = RaceVarMap,
+ def_vars = FunDefVars, call_vars = FunCallVars,
+ arg_types = FunArgTypes},
+ Code, NestingLevel),
+ {NewCurrFun, NewCurrFunLabel, CallsToAnalyze, NewCode, NewRaceList,
+ NewRaceVarMap, NewFunDefVars, NewFunCallVars, NewFunArgTypes,
+ NewNestingLevel};
+ [Head|Tail] ->
+ case Head of
+ {InitFun, InitFun} when CurrFun =:= InitFun, Fun =:= InitFun ->
+ NewCallsToAnalyze = lists:delete(Head, CallsToAnalyze),
+ NewRaceVarMap =
+ race_var_map(Args, NewFunArgs, RaceVarMap, bind),
+ RetC =
+ fixup_all_calls(InitFun, InitFun, FunLabel, Args,
+ CodeB ++
+ [#curr_fun{status = out, mfa = InitFun,
+ label = CurrFunLabel, var_map = RaceVarMap,
+ def_vars = FunDefVars, call_vars = FunCallVars,
+ arg_types = FunArgTypes}],
+ Code, RaceVarMap),
+ NewCode =
+ fixup_all_calls(InitFun, InitFun, FunLabel, Args,
+ CodeB ++
+ [#curr_fun{status = out, mfa = InitFun,
+ label = CurrFunLabel, var_map = NewRaceVarMap,
+ def_vars = Args, call_vars = NewFunArgs,
+ arg_types = NewFunTypes}],
+ [#curr_fun{status = in, mfa = Fun,
+ label = FunLabel, var_map = NewRaceVarMap,
+ def_vars = Args, call_vars = NewFunArgs,
+ arg_types = NewFunTypes}|
+ lists:reverse(StateRaceList)] ++
+ RetC, NewRaceVarMap),
+ {InitFun, FunLabel, NewCallsToAnalyze, NewCode, RaceList,
+ NewRaceVarMap, Args, NewFunArgs, NewFunTypes, NestingLevel};
+ {CurrFun, Fun} ->
+ NewCallsToAnalyze = lists:delete(Head, CallsToAnalyze),
+ NewRaceVarMap = race_var_map(Args, NewFunArgs, RaceVarMap, bind),
+ RetC =
+ case Fun of
+ InitFun ->
+ fixup_all_calls(CurrFun, Fun, FunLabel, Args,
+ lists:reverse(StateRaceList) ++
+ [#curr_fun{status = out, mfa = CurrFun,
+ label = CurrFunLabel, var_map = RaceVarMap,
+ def_vars = FunDefVars, call_vars = FunCallVars,
+ arg_types = FunArgTypes}],
+ Code, RaceVarMap);
+ _Other1 ->
+ fixup_all_calls(CurrFun, Fun, FunLabel, Args,
+ CodeB ++
+ [#curr_fun{status = out, mfa = CurrFun,
+ label = CurrFunLabel, var_map = RaceVarMap,
+ def_vars = FunDefVars, call_vars = FunCallVars,
+ arg_types = FunArgTypes}],
+ Code, RaceVarMap)
+ end,
+ NewCode =
+ case Fun of
+ InitFun ->
+ [#curr_fun{status = in, mfa = Fun,
+ label = FunLabel, var_map = NewRaceVarMap,
+ def_vars = Args, call_vars = NewFunArgs,
+ arg_types = NewFunTypes}|
+ lists:reverse(StateRaceList)] ++ RetC;
+ _ ->
+ [#curr_fun{status = in, mfa = Fun,
+ label = FunLabel, var_map = NewRaceVarMap,
+ def_vars = Args, call_vars = NewFunArgs,
+ arg_types = NewFunTypes}|CodeB] ++
+ RetC
+ end,
+ {Fun, FunLabel, NewCallsToAnalyze, NewCode, RaceList, NewRaceVarMap,
+ Args, NewFunArgs, NewFunTypes, NestingLevel};
+ {_TupleA, _TupleB} ->
+ fixup_race_forward_helper(CurrFun, CurrFunLabel, Fun, FunLabel,
+ Tail, CallsToAnalyze, Code, RaceList, InitFun, NewFunArgs,
+ NewFunTypes, RaceWarnTag, RaceVarMap, FunDefVars, FunCallVars,
+ FunArgTypes, NestingLevel, Args, CodeB, StateRaceList)
+ end
+ end.
+
+%%% ===========================================================================
+%%%
+%%% Backward Analysis
+%%%
+%%% ===========================================================================
+
+fixup_race_backward(CurrFun, Calls, CallsToAnalyze, Parents, Height) ->
+ case Height =:= 0 of
+ true -> Parents;
+ false ->
+ case Calls of
+ [] ->
+ case is_integer(CurrFun) orelse lists:member(CurrFun, Parents) of
+ true -> Parents;
+ false -> [CurrFun|Parents]
+ end;
+ [Head|Tail] ->
+ {Parent, TupleB} = Head,
+ case TupleB =:= CurrFun of
+ true -> % more paths are needed
+ NewCallsToAnalyze = lists:delete(Head, CallsToAnalyze),
+ NewParents =
+ fixup_race_backward(Parent, NewCallsToAnalyze,
+ NewCallsToAnalyze, Parents, Height - 1),
+ fixup_race_backward(CurrFun, Tail, NewCallsToAnalyze, NewParents,
+ Height);
+ false ->
+ fixup_race_backward(CurrFun, Tail, CallsToAnalyze, Parents,
+ Height)
+ end
+ end
+ end.
+
+%%% ===========================================================================
+%%%
+%%% Utilities
+%%%
+%%% ===========================================================================
+
+are_bound_labels(Label1, Label2, RaceVarMap) ->
+ case dict:find(Label1, RaceVarMap) of
+ error -> false;
+ {ok, Labels} ->
+ lists:member(Label2, Labels) orelse
+ are_bound_labels_helper(Labels, Label1, Label2, RaceVarMap)
+ end.
+
+are_bound_labels_helper(Labels, OldLabel, CompLabel, RaceVarMap) ->
+ case dict:size(RaceVarMap) of
+ 0 -> false;
+ _ ->
+ case Labels of
+ [] -> false;
+ [Head|Tail] ->
+ NewRaceVarMap = dict:erase(OldLabel, RaceVarMap),
+ are_bound_labels(Head, CompLabel, NewRaceVarMap) orelse
+ are_bound_labels_helper(Tail, Head, CompLabel, NewRaceVarMap)
+ end
+ end.
+
+are_bound_vars(Vars1, Vars2, RaceVarMap) ->
+ case is_list(Vars1) andalso is_list(Vars2) of
+ true ->
+ case Vars1 of
+ [] -> false;
+ [AHead|ATail] ->
+ case Vars2 of
+ [] -> false;
+ [PHead|PTail] ->
+ are_bound_vars(AHead, PHead, RaceVarMap) andalso
+ are_bound_vars(ATail, PTail, RaceVarMap)
+ end
+ end;
+ false ->
+ {NewVars1, NewVars2, IsList} =
+ case is_list(Vars1) of
+ true ->
+ case Vars1 of
+ [Var1] -> {Var1, Vars2, true};
+ _Thing -> {Vars1, Vars2, false}
+ end;
+ false ->
+ case is_list(Vars2) of
+ true ->
+ case Vars2 of
+ [Var2] -> {Vars1, Var2, true};
+ _Thing -> {Vars1, Vars2, false}
+ end;
+ false -> {Vars1, Vars2, true}
+ end
+ end,
+ case IsList of
+ true ->
+ case cerl:type(NewVars1) of
+ var ->
+ case cerl:type(NewVars2) of
+ var ->
+ ALabel = cerl_trees:get_label(NewVars1),
+ PLabel = cerl_trees:get_label(NewVars2),
+ are_bound_labels(ALabel, PLabel, RaceVarMap) orelse
+ are_bound_labels(PLabel, ALabel, RaceVarMap);
+ alias ->
+ are_bound_vars(NewVars1, cerl:alias_var(NewVars2),
+ RaceVarMap);
+ values ->
+ are_bound_vars(NewVars1, cerl:values_es(NewVars2),
+ RaceVarMap);
+ _Other -> false
+ end;
+ tuple ->
+ case cerl:type(NewVars2) of
+ tuple ->
+ are_bound_vars(cerl:tuple_es(NewVars1),
+ cerl:tuple_es(NewVars2), RaceVarMap);
+ alias ->
+ are_bound_vars(NewVars1, cerl:alias_var(NewVars2),
+ RaceVarMap);
+ values ->
+ are_bound_vars(NewVars1, cerl:values_es(NewVars2),
+ RaceVarMap);
+ _Other -> false
+ end;
+ cons ->
+ case cerl:type(NewVars2) of
+ cons ->
+ are_bound_vars(cerl:cons_hd(NewVars1),
+ cerl:cons_hd(NewVars2), RaceVarMap)
+ andalso
+ are_bound_vars(cerl:cons_tl(NewVars1),
+ cerl:cons_tl(NewVars2), RaceVarMap);
+ alias ->
+ are_bound_vars(NewVars1, cerl:alias_var(NewVars2),
+ RaceVarMap);
+ values ->
+ are_bound_vars(NewVars1, cerl:values_es(NewVars2),
+ RaceVarMap);
+ _Other -> false
+ end;
+ alias ->
+ case cerl:type(NewVars2) of
+ alias ->
+ are_bound_vars(cerl:alias_var(NewVars1),
+ cerl:alias_var(NewVars2), RaceVarMap);
+ _Other ->
+ are_bound_vars(cerl:alias_var(NewVars1),
+ NewVars2, RaceVarMap)
+ end;
+ values ->
+ case cerl:type(NewVars2) of
+ values ->
+ are_bound_vars(cerl:values_es(NewVars1),
+ cerl:values_es(NewVars2), RaceVarMap);
+ _Other ->
+ are_bound_vars(cerl:values_es(NewVars1),
+ NewVars2, RaceVarMap)
+ end;
+ _Other -> false
+ end;
+ false -> false
+ end
+ end.
+
+callgraph__renew_tables(Table, Callgraph) ->
+ case Table of
+ {named, NameLabel, Names} ->
+ PTablesToAdd =
+ case NameLabel of
+ ?no_label -> [];
+ _Other -> [NameLabel]
+ end,
+ NamesToAdd = filter_named_tables(Names),
+ PTables = dialyzer_callgraph:get_public_tables(Callgraph),
+ NTables = dialyzer_callgraph:get_named_tables(Callgraph),
+ dialyzer_callgraph:put_public_tables(
+ lists:usort(PTablesToAdd ++ PTables),
+ dialyzer_callgraph:put_named_tables(
+ NamesToAdd ++ NTables, Callgraph));
+ _Other ->
+ Callgraph
+ end.
+
+cleanup_clause_code(#curr_fun{mfa = CurrFun} = CurrTuple, Code,
+ NestingLevel, LocalNestingLevel) ->
+ case Code of
+ [] -> {CurrTuple, []};
+ [Head|Tail] ->
+ {NewLocalNestingLevel, NewNestingLevel, NewCurrTuple, Return} =
+ case Head of
+ beg_case ->
+ {LocalNestingLevel, NestingLevel + 1, CurrTuple, false};
+ #end_case{} ->
+ {LocalNestingLevel, NestingLevel - 1, CurrTuple, false};
+ #end_clause{} ->
+ case NestingLevel =:= 0 of
+ true ->
+ {LocalNestingLevel, NestingLevel, CurrTuple, true};
+ false ->
+ {LocalNestingLevel, NestingLevel, CurrTuple, false}
+ end;
+ #fun_call{caller = CurrFun} ->
+ {LocalNestingLevel - 1, NestingLevel, CurrTuple, false};
+ #curr_fun{status = in} ->
+ {LocalNestingLevel - 1, NestingLevel, Head, false};
+ #curr_fun{status = out} ->
+ {LocalNestingLevel + 1, NestingLevel, Head, false};
+ Other when Other =/= #fun_call{} ->
+ {LocalNestingLevel, NestingLevel, CurrTuple, false}
+ end,
+ case Return of
+ true -> {NewCurrTuple, Tail};
+ false ->
+ cleanup_clause_code(NewCurrTuple, Tail, NewNestingLevel,
+ NewLocalNestingLevel)
+ end
+ end.
+
+cleanup_dep_calls(DepList) ->
+ case DepList of
+ [] -> [];
+ [#dep_call{call_name = CallName, arg_types = ArgTypes,
+ vars = Vars, state = State, file_line = FileLine}|T] ->
+ [#dep_call{call_name = CallName, arg_types = ArgTypes,
+ vars = Vars, state = State, file_line = FileLine}|
+ cleanup_dep_calls(T)]
+ end.
+
+cleanup_race_code(State) ->
+ Callgraph = dialyzer_dataflow:state__get_callgraph(State),
+ dialyzer_dataflow:state__put_callgraph(
+ dialyzer_callgraph:race_code_new(Callgraph), State).
+
+filter_named_tables(NamesList) ->
+ case NamesList of
+ [] -> [];
+ [Head|Tail] ->
+ NewHead =
+ case string:rstr(Head, "()") of
+ 0 -> [Head];
+ _Other -> []
+ end,
+ NewHead ++ filter_named_tables(Tail)
+ end.
+
+filter_parents(Parents, NewParents, Digraph) ->
+ case Parents of
+ [] -> NewParents;
+ [Head|Tail] ->
+ NewParents1 = filter_parents_helper1(Head, Tail, NewParents, Digraph),
+ filter_parents(Tail, NewParents1, Digraph)
+ end.
+
+filter_parents_helper1(First, Rest, NewParents, Digraph) ->
+ case Rest of
+ [] -> NewParents;
+ [Head|Tail] ->
+ NewParents1 = filter_parents_helper2(First, Head, NewParents, Digraph),
+ filter_parents_helper1(First, Tail, NewParents1, Digraph)
+ end.
+
+filter_parents_helper2(Parent1, Parent2, NewParents, Digraph) ->
+ case digraph:get_path(Digraph, Parent1, Parent2) of
+ false ->
+ case digraph:get_path(Digraph, Parent2, Parent1) of
+ false -> NewParents;
+ _Vertices -> NewParents -- [Parent1]
+ end;
+ _Vertices -> NewParents -- [Parent2]
+ end.
+
+find_all_bound_vars(Label, RaceVarMap) ->
+ case dict:find(Label, RaceVarMap) of
+ error -> [Label];
+ {ok, Labels} ->
+ lists:usort(Labels ++
+ find_all_bound_vars_helper(Labels, Label, RaceVarMap))
+ end.
+
+find_all_bound_vars_helper(Labels, Label, RaceVarMap) ->
+ case dict:size(RaceVarMap) of
+ 0 -> [];
+ _ ->
+ case Labels of
+ [] -> [];
+ [Head|Tail] ->
+ NewRaceVarMap = dict:erase(Label, RaceVarMap),
+ find_all_bound_vars(Head, NewRaceVarMap) ++
+ find_all_bound_vars_helper(Tail, Head, NewRaceVarMap)
+ end
+ end.
+
+fixup_all_calls(CurrFun, NextFun, NextFunLabel, Args, CodeToReplace,
+ Code, RaceVarMap) ->
+ case Code of
+ [] -> [];
+ [Head|Tail] ->
+ NewCode =
+ case Head of
+ #fun_call{caller = CurrFun, callee = Callee,
+ arg_types = FunArgTypes, vars = FunArgs}
+ when Callee =:= NextFun orelse Callee =:= NextFunLabel ->
+ RaceVarMap1 = race_var_map(Args, FunArgs, RaceVarMap, bind),
+ [#curr_fun{status = in, mfa = NextFun, label = NextFunLabel,
+ var_map = RaceVarMap1, def_vars = Args,
+ call_vars = FunArgs, arg_types = FunArgTypes}|
+ CodeToReplace];
+ _Other -> [Head]
+ end,
+ RetCode =
+ fixup_all_calls(CurrFun, NextFun, NextFunLabel, Args, CodeToReplace,
+ Tail, RaceVarMap),
+ NewCode ++ RetCode
+ end.
+
+is_last_race(RaceTag, InitFun, Code, Callgraph) ->
+ case Code of
+ [] -> true;
+ [Head|Tail] ->
+ case Head of
+ RaceTag -> false;
+ #fun_call{callee = Fun} ->
+ FunName =
+ case is_integer(Fun) of
+ true ->
+ case dialyzer_callgraph:lookup_name(Fun, Callgraph) of
+ error -> Fun;
+ {ok, Name} -> Name
+ end;
+ false -> Fun
+ end,
+ Digraph = dialyzer_callgraph:get_digraph(Callgraph),
+ case FunName =:= InitFun orelse
+ digraph:get_path(Digraph, FunName, InitFun) of
+ false -> is_last_race(RaceTag, InitFun, Tail, Callgraph);
+ _Vertices -> false
+ end;
+ _Other -> is_last_race(RaceTag, InitFun, Tail, Callgraph)
+ end
+ end.
+
+lists_key_member(Member, List, N) when is_integer(Member) ->
+ case List of
+ [] -> 0;
+ [Head|Tail] ->
+ NewN = N + 1,
+ case Head of
+ Member -> NewN;
+ _Other -> lists_key_member(Member, Tail, NewN)
+ end
+ end;
+lists_key_member(_M, _L, _N) ->
+ 0.
+
+lists_key_member_lists(MemberList, List) ->
+ case MemberList of
+ [] -> 0;
+ [Head|Tail] ->
+ case lists_key_member(Head, List, 0) of
+ 0 -> lists_key_member_lists(Tail, List);
+ Other -> Other
+ end
+ end.
+
+lists_key_members_lists(MemberList, List) ->
+ case MemberList of
+ [] -> [];
+ [Head|Tail] ->
+ lists:usort(
+ lists_key_members_lists_helper(Head, List, 1) ++
+ lists_key_members_lists(Tail, List))
+ end.
+
+lists_key_members_lists_helper(Elem, List, N) when is_integer(Elem) ->
+ case List of
+ [] -> [];
+ [Head|Tail] ->
+ NewHead =
+ case Head =:= Elem of
+ true -> [N];
+ false -> []
+ end,
+ NewHead ++ lists_key_members_lists_helper(Elem, Tail, N + 1)
+ end;
+lists_key_members_lists_helper(_Elem, _List, _N) ->
+ [0].
+
+lists_key_replace(N, List, NewMember) ->
+ {Before, [_|After]} = lists:split(N - 1, List),
+ Before ++ [NewMember|After].
+
+lists_get(0, _List) -> ?no_label;
+lists_get(N, List) -> lists:nth(N, List).
+
+refine_race(RaceCall, WarnVarArgs, RaceWarnTag, DependencyList, RaceVarMap) ->
+ case RaceWarnTag of
+ WarnWhereis when WarnWhereis =:= ?WARN_WHEREIS_REGISTER orelse
+ WarnWhereis =:= ?WARN_WHEREIS_UNREGISTER ->
+ case RaceCall of
+ #dep_call{call_name = ets_lookup} ->
+ DependencyList;
+ #dep_call{call_name = mnesia_dirty_read} ->
+ DependencyList;
+ #dep_call{call_name = whereis, args = VarArgs} ->
+ refine_race_helper(RaceCall, VarArgs, WarnVarArgs, RaceWarnTag,
+ DependencyList, RaceVarMap)
+ end;
+ ?WARN_ETS_LOOKUP_INSERT ->
+ case RaceCall of
+ #dep_call{call_name = whereis} ->
+ DependencyList;
+ #dep_call{call_name = mnesia_dirty_read} ->
+ DependencyList;
+ #dep_call{call_name = ets_lookup, args = VarArgs} ->
+ refine_race_helper(RaceCall, VarArgs, WarnVarArgs, RaceWarnTag,
+ DependencyList, RaceVarMap)
+ end;
+ ?WARN_MNESIA_DIRTY_READ_WRITE ->
+ case RaceCall of
+ #dep_call{call_name = whereis} ->
+ DependencyList;
+ #dep_call{call_name = ets_lookup} ->
+ DependencyList;
+ #dep_call{call_name = mnesia_dirty_read, args = VarArgs} ->
+ refine_race_helper(RaceCall, VarArgs, WarnVarArgs, RaceWarnTag,
+ DependencyList, RaceVarMap)
+ end
+ end.
+
+refine_race_helper(RaceCall, VarArgs, WarnVarArgs, RaceWarnTag, DependencyList,
+ RaceVarMap) ->
+ case compare_types(VarArgs, WarnVarArgs, RaceWarnTag, RaceVarMap) of
+ true -> [RaceCall|DependencyList];
+ false -> DependencyList
+ end.
+
+remove_clause(RaceList, CurrTuple, Code, NestingLevel) ->
+ NewRaceList = fixup_case_rest_paths(RaceList, 0),
+ {NewCurrTuple, NewCode} =
+ cleanup_clause_code(CurrTuple, Code, 0, NestingLevel),
+ ReturnTuple = {NewRaceList, NewCurrTuple, NewCode, NestingLevel},
+ case NewRaceList of
+ [beg_case|RTail] ->
+ case NewCode of
+ [#end_case{}|CTail] ->
+ remove_clause(RTail, NewCurrTuple, CTail, NestingLevel);
+ _Other -> ReturnTuple
+ end;
+ _Else -> ReturnTuple
+ end.
+
+remove_nonlocal_functions(Code, NestingLevel) ->
+ case Code of
+ [] -> [];
+ [H|T] ->
+ NewNL =
+ case H of
+ #curr_fun{status = in} ->
+ NestingLevel + 1;
+ #curr_fun{status = out} ->
+ NestingLevel - 1;
+ _Other ->
+ NestingLevel
+ end,
+ case NewNL =:= 0 of
+ true -> T;
+ false -> remove_nonlocal_functions(T, NewNL)
+ end
+ end.
+
+renew_curr_fun(CurrFun, Races) ->
+ Races#races{curr_fun = CurrFun}.
+
+renew_curr_fun_label(CurrFunLabel, Races) ->
+ Races#races{curr_fun_label = CurrFunLabel}.
+
+renew_race_list(RaceList, Races) ->
+ Races#races{race_list = RaceList}.
+
+renew_race_list_size(RaceListSize, Races) ->
+ Races#races{race_list_size = RaceListSize}.
+
+renew_race_tags(RaceTags, Races) ->
+ Races#races{race_tags = RaceTags}.
+
+renew_table(Table, Races) ->
+ Races#races{new_table = Table}.
+
+state__renew_curr_fun(CurrFun, State) ->
+ Races = dialyzer_dataflow:state__get_races(State),
+ dialyzer_dataflow:state__put_races(renew_curr_fun(CurrFun, Races), State).
+
+state__renew_curr_fun_label(CurrFunLabel, State) ->
+ Races = dialyzer_dataflow:state__get_races(State),
+ dialyzer_dataflow:state__put_races(
+ renew_curr_fun_label(CurrFunLabel, Races), State).
+
+state__renew_race_list(RaceList, State) ->
+ Races = dialyzer_dataflow:state__get_races(State),
+ dialyzer_dataflow:state__put_races(renew_race_list(RaceList, Races), State).
+
+state__renew_race_tags(RaceTags, State) ->
+ Races = dialyzer_dataflow:state__get_races(State),
+ dialyzer_dataflow:state__put_races(renew_race_tags(RaceTags, Races), State).
+
+state__renew_info(RaceList, RaceListSize, RaceTags, Table, State) ->
+ Callgraph = dialyzer_dataflow:state__get_callgraph(State),
+ Races = dialyzer_dataflow:state__get_races(State),
+ dialyzer_dataflow:state__put_callgraph(
+ callgraph__renew_tables(Table, Callgraph),
+ dialyzer_dataflow:state__put_races(
+ renew_table(Table,
+ renew_race_list(RaceList,
+ renew_race_list_size(RaceListSize,
+ renew_race_tags(RaceTags, Races)))), State)).
+
+%%% ===========================================================================
+%%%
+%%% Variable and Type Utilities
+%%%
+%%% ===========================================================================
+
+any_args(StrList) ->
+ case StrList of
+ [] -> false;
+ [Head|Tail] ->
+ case string:rstr(Head, "()") of
+ 0 -> any_args(Tail);
+ _Other -> true
+ end
+ end.
+
+-spec bind_dict_vars(label(), label(), dict:dict()) -> dict:dict().
+
+bind_dict_vars(Key, Label, RaceVarMap) ->
+ case Key =:= Label of
+ true -> RaceVarMap;
+ false ->
+ case dict:find(Key, RaceVarMap) of
+ error -> dict:store(Key, [Label], RaceVarMap);
+ {ok, Labels} ->
+ case lists:member(Label, Labels) of
+ true -> RaceVarMap;
+ false -> dict:store(Key, [Label|Labels], RaceVarMap)
+ end
+ end
+ end.
+
+bind_dict_vars_list(Key, Labels, RaceVarMap) ->
+ case Labels of
+ [] -> RaceVarMap;
+ [Head|Tail] ->
+ bind_dict_vars_list(Key, Tail, bind_dict_vars(Key, Head, RaceVarMap))
+ end.
+
+compare_ets_insert(OldWarnVarArgs, NewWarnVarArgs, RaceVarMap) ->
+ [Old1, Old2, Old3, Old4] = OldWarnVarArgs,
+ [New1, New2, New3, New4] = NewWarnVarArgs,
+ Bool =
+ case any_args(Old2) of
+ true -> compare_var_list(New1, Old1, RaceVarMap);
+ false ->
+ case any_args(New2) of
+ true -> compare_var_list(New1, Old1, RaceVarMap);
+ false -> compare_var_list(New1, Old1, RaceVarMap)
+ orelse (Old2 =:= New2)
+ end
+ end,
+ case Bool of
+ true ->
+ case any_args(Old4) of
+ true ->
+ case compare_list_vars(Old3, ets_list_args(New3), [], RaceVarMap) of
+ true -> true;
+ Args3 -> lists_key_replace(3, OldWarnVarArgs, Args3)
+ end;
+ false ->
+ case any_args(New4) of
+ true ->
+ case compare_list_vars(Old3, ets_list_args(New3), [],
+ RaceVarMap) of
+ true -> true;
+ Args3 -> lists_key_replace(3, OldWarnVarArgs, Args3)
+ end;
+ false ->
+ case compare_list_vars(Old3, ets_list_args(New3), [],
+ RaceVarMap) of
+ true -> true;
+ Args3 ->
+ lists_key_replace(4,
+ lists_key_replace(3, OldWarnVarArgs, Args3), Old4 -- New4)
+ end
+ end
+ end;
+ false -> OldWarnVarArgs
+ end.
+
+compare_first_arg(OldWarnVarArgs, NewWarnVarArgs, RaceVarMap) ->
+ [Old1, Old2|_OldT] = OldWarnVarArgs,
+ [New1, New2|_NewT] = NewWarnVarArgs,
+ case any_args(Old2) of
+ true ->
+ case compare_var_list(New1, Old1, RaceVarMap) of
+ true -> true;
+ false -> OldWarnVarArgs
+ end;
+ false ->
+ case any_args(New2) of
+ true ->
+ case compare_var_list(New1, Old1, RaceVarMap) of
+ true -> true;
+ false -> OldWarnVarArgs
+ end;
+ false ->
+ case compare_var_list(New1, Old1, RaceVarMap) of
+ true -> true;
+ false -> lists_key_replace(2, OldWarnVarArgs, Old2 -- New2)
+ end
+ end
+ end.
+
+compare_argtypes(ArgTypes, WarnArgTypes) ->
+ lists:any(fun (X) -> lists:member(X, WarnArgTypes) end, ArgTypes).
+
+%% Compares the argument types of the two suspicious calls.
+compare_types(VarArgs, WarnVarArgs, RaceWarnTag, RaceVarMap) ->
+ case RaceWarnTag of
+ ?WARN_WHEREIS_REGISTER ->
+ [VA1, VA2] = VarArgs,
+ [WVA1, WVA2, _, _] = WarnVarArgs,
+ case any_args(VA2) of
+ true -> compare_var_list(VA1, WVA1, RaceVarMap);
+ false ->
+ case any_args(WVA2) of
+ true -> compare_var_list(VA1, WVA1, RaceVarMap);
+ false ->
+ compare_var_list(VA1, WVA1, RaceVarMap) orelse
+ compare_argtypes(VA2, WVA2)
+ end
+ end;
+ ?WARN_WHEREIS_UNREGISTER ->
+ [VA1, VA2] = VarArgs,
+ [WVA1, WVA2] = WarnVarArgs,
+ case any_args(VA2) of
+ true -> compare_var_list(VA1, WVA1, RaceVarMap);
+ false ->
+ case any_args(WVA2) of
+ true -> compare_var_list(VA1, WVA1, RaceVarMap);
+ false ->
+ compare_var_list(VA1, WVA1, RaceVarMap) orelse
+ compare_argtypes(VA2, WVA2)
+ end
+ end;
+ ?WARN_ETS_LOOKUP_INSERT ->
+ [VA1, VA2, VA3, VA4] = VarArgs,
+ [WVA1, WVA2, WVA3, WVA4] = WarnVarArgs,
+ Bool =
+ case any_args(VA2) of
+ true -> compare_var_list(VA1, WVA1, RaceVarMap);
+ false ->
+ case any_args(WVA2) of
+ true -> compare_var_list(VA1, WVA1, RaceVarMap);
+ false ->
+ compare_var_list(VA1, WVA1, RaceVarMap) orelse
+ compare_argtypes(VA2, WVA2)
+ end
+ end,
+ Bool andalso
+ (case any_args(VA4) of
+ true ->
+ compare_var_list(VA3, WVA3, RaceVarMap);
+ false ->
+ case any_args(WVA4) of
+ true ->
+ compare_var_list(VA3, WVA3, RaceVarMap);
+ false ->
+ compare_var_list(VA3, WVA3, RaceVarMap) orelse
+ compare_argtypes(VA4, WVA4)
+ end
+ end);
+ ?WARN_MNESIA_DIRTY_READ_WRITE ->
+ [VA1, VA2|_] = VarArgs, %% Two or four elements
+ [WVA1, WVA2|_] = WarnVarArgs,
+ case any_args(VA2) of
+ true -> compare_var_list(VA1, WVA1, RaceVarMap);
+ false ->
+ case any_args(WVA2) of
+ true -> compare_var_list(VA1, WVA1, RaceVarMap);
+ false ->
+ compare_var_list(VA1, WVA1, RaceVarMap) orelse
+ compare_argtypes(VA2, WVA2)
+ end
+ end
+ end.
+
+compare_list_vars(VarList1, VarList2, NewVarList1, RaceVarMap) ->
+ case VarList1 of
+ [] ->
+ case NewVarList1 of
+ [] -> true;
+ _Other -> NewVarList1
+ end;
+ [Head|Tail] ->
+ NewHead =
+ case compare_var_list(Head, VarList2, RaceVarMap) of
+ true -> [];
+ false -> [Head]
+ end,
+ compare_list_vars(Tail, VarList2, NewHead ++ NewVarList1, RaceVarMap)
+ end.
+
+compare_vars(Var1, Var2, RaceVarMap) when is_integer(Var1), is_integer(Var2) ->
+ Var1 =:= Var2 orelse
+ are_bound_labels(Var1, Var2, RaceVarMap) orelse
+ are_bound_labels(Var2, Var1, RaceVarMap);
+compare_vars(_Var1, _Var2, _RaceVarMap) ->
+ false.
+
+-spec compare_var_list(label_type(), [label_type()], dict:dict()) -> boolean().
+
+compare_var_list(Var, VarList, RaceVarMap) ->
+ lists:any(fun (V) -> compare_vars(Var, V, RaceVarMap) end, VarList).
+
+ets_list_args(MaybeList) ->
+ case is_list(MaybeList) of
+ true ->
+ try [ets_tuple_args(T) || T <- MaybeList]
+ catch _:_ -> [?no_label]
+ end;
+ false -> [ets_tuple_args(MaybeList)]
+ end.
+
+ets_list_argtypes(ListStr) ->
+ ListStr1 = string:strip(ListStr, left, $[),
+ ListStr2 = string:strip(ListStr1, right, $]),
+ ListStr3 = string:strip(ListStr2, right, $.),
+ string:strip(ListStr3, right, $,).
+
+ets_tuple_args(MaybeTuple) ->
+ case is_tuple(MaybeTuple) of
+ true -> element(1, MaybeTuple);
+ false -> ?no_label
+ end.
+
+ets_tuple_argtypes2(TupleList, ElemList) ->
+ case TupleList of
+ [] -> ElemList;
+ [H|T] ->
+ ets_tuple_argtypes2(T,
+ ets_tuple_argtypes2_helper(H, [], 0) ++ ElemList)
+ end.
+
+ets_tuple_argtypes2_helper(TupleStr, ElemStr, NestingLevel) ->
+ case TupleStr of
+ [] -> [];
+ [H|T] ->
+ {NewElemStr, NewNestingLevel, Return} =
+ case H of
+ ${ when NestingLevel =:= 0 ->
+ {ElemStr, NestingLevel + 1, false};
+ ${ ->
+ {[H|ElemStr], NestingLevel + 1, false};
+ $[ ->
+ {[H|ElemStr], NestingLevel + 1, false};
+ $( ->
+ {[H|ElemStr], NestingLevel + 1, false};
+ $} ->
+ {[H|ElemStr], NestingLevel - 1, false};
+ $] ->
+ {[H|ElemStr], NestingLevel - 1, false};
+ $) ->
+ {[H|ElemStr], NestingLevel - 1, false};
+ $, when NestingLevel =:= 1 ->
+ {lists:reverse(ElemStr), NestingLevel, true};
+ _Other ->
+ {[H|ElemStr], NestingLevel, false}
+ end,
+ case Return of
+ true -> string:tokens(NewElemStr, " |");
+ false ->
+ ets_tuple_argtypes2_helper(T, NewElemStr, NewNestingLevel)
+ end
+ end.
+
+ets_tuple_argtypes1(Str, Tuple, TupleList, NestingLevel) ->
+ case Str of
+ [] -> TupleList;
+ [H|T] ->
+ {NewTuple, NewNestingLevel, Add} =
+ case H of
+ ${ ->
+ {[H|Tuple], NestingLevel + 1, false};
+ $} ->
+ case NestingLevel of
+ 1 ->
+ {[H|Tuple], NestingLevel - 1, true};
+ _Else ->
+ {[H|Tuple], NestingLevel - 1, false}
+ end;
+ _Other1 when NestingLevel =:= 0 ->
+ {Tuple, NestingLevel, false};
+ _Other2 ->
+ {[H|Tuple], NestingLevel, false}
+ end,
+ case Add of
+ true ->
+ ets_tuple_argtypes1(T, [],
+ [lists:reverse(NewTuple)|TupleList],
+ NewNestingLevel);
+ false ->
+ ets_tuple_argtypes1(T, NewTuple, TupleList, NewNestingLevel)
+ end
+ end.
+
+format_arg(?bypassed) -> ?no_label;
+format_arg(Arg0) ->
+ Arg = cerl:fold_literal(Arg0),
+ case cerl:type(Arg) of
+ var -> cerl_trees:get_label(Arg);
+ tuple -> list_to_tuple([format_arg(A) || A <- cerl:tuple_es(Arg)]);
+ cons -> [format_arg(cerl:cons_hd(Arg))|format_arg(cerl:cons_tl(Arg))];
+ alias -> format_arg(cerl:alias_var(Arg));
+ literal ->
+ case cerl:is_c_nil(Arg) of
+ true -> [];
+ false -> ?no_label
+ end;
+ _Other -> ?no_label
+ end.
+
+-spec format_args([core_vars()], [erl_types:erl_type()],
+ dialyzer_dataflow:state(), call()) ->
+ args().
+
+format_args([], [], _State, _Call) ->
+ [];
+format_args(ArgList, TypeList, CleanState, Call) ->
+ format_args_2(format_args_1(ArgList, TypeList, CleanState), Call).
+
+format_args_1([Arg], [Type], CleanState) ->
+ [format_arg(Arg), format_type(Type, CleanState)];
+format_args_1([Arg|Args], [Type|Types], CleanState) ->
+ List =
+ case Arg =:= ?bypassed of
+ true -> [?no_label, format_type(Type, CleanState)];
+ false ->
+ case cerl:is_literal(cerl:fold_literal(Arg)) of
+ true -> [?no_label, format_cerl(Arg)];
+ false -> [format_arg(Arg), format_type(Type, CleanState)]
+ end
+ end,
+ List ++ format_args_1(Args, Types, CleanState).
+
+format_args_2(StrArgList, Call) ->
+ case Call of
+ whereis ->
+ lists_key_replace(2, StrArgList,
+ string:tokens(lists:nth(2, StrArgList), " |"));
+ register ->
+ lists_key_replace(2, StrArgList,
+ string:tokens(lists:nth(2, StrArgList), " |"));
+ unregister ->
+ lists_key_replace(2, StrArgList,
+ string:tokens(lists:nth(2, StrArgList), " |"));
+ ets_new ->
+ StrArgList1 = lists_key_replace(2, StrArgList,
+ string:tokens(lists:nth(2, StrArgList), " |")),
+ lists_key_replace(4, StrArgList1,
+ string:tokens(ets_list_argtypes(lists:nth(4, StrArgList1)), " |"));
+ ets_lookup ->
+ StrArgList1 = lists_key_replace(2, StrArgList,
+ string:tokens(lists:nth(2, StrArgList), " |")),
+ lists_key_replace(4, StrArgList1,
+ string:tokens(lists:nth(4, StrArgList1), " |"));
+ ets_insert ->
+ StrArgList1 = lists_key_replace(2, StrArgList,
+ string:tokens(lists:nth(2, StrArgList), " |")),
+ lists_key_replace(4, StrArgList1,
+ ets_tuple_argtypes2(
+ ets_tuple_argtypes1(lists:nth(4, StrArgList1), [], [], 0),
+ []));
+ mnesia_dirty_read1 ->
+ lists_key_replace(2, StrArgList,
+ [mnesia_tuple_argtypes(T) || T <- string:tokens(
+ lists:nth(2, StrArgList), " |")]);
+ mnesia_dirty_read2 ->
+ lists_key_replace(2, StrArgList,
+ string:tokens(lists:nth(2, StrArgList), " |"));
+ mnesia_dirty_write1 ->
+ lists_key_replace(2, StrArgList,
+ [mnesia_record_tab(R) || R <- string:tokens(
+ lists:nth(2, StrArgList), " |")]);
+ mnesia_dirty_write2 ->
+ lists_key_replace(2, StrArgList,
+ string:tokens(lists:nth(2, StrArgList), " |"));
+ function_call -> StrArgList
+ end.
+
+format_cerl(Tree) ->
+ cerl_prettypr:format(cerl:set_ann(Tree, []),
+ [{hook, dialyzer_utils:pp_hook()},
+ {noann, true},
+ {paper, 100000},
+ {ribbon, 100000}
+ ]).
+
+format_type(Type, State) ->
+ R = dialyzer_dataflow:state__get_records(State),
+ erl_types:t_to_string(Type, R).
+
+mnesia_record_tab(RecordStr) ->
+ case string:str(RecordStr, "#") =:= 1 of
+ true ->
+ "'" ++
+ string:sub_string(RecordStr, 2, string:str(RecordStr, "{") - 1) ++
+ "'";
+ false -> RecordStr
+ end.
+
+mnesia_tuple_argtypes(TupleStr) ->
+ TupleStr1 = string:strip(TupleStr, left, ${),
+ [TupleStr2|_T] = string:tokens(TupleStr1, " ,"),
+ lists:flatten(string:tokens(TupleStr2, " |")).
+
+-spec race_var_map(var_to_map1(), var_to_map2(), dict:dict(), op()) ->
+ dict:dict().
+
+race_var_map(Vars1, Vars2, RaceVarMap, Op) ->
+ case Vars1 =:= ?no_arg orelse Vars1 =:= ?bypassed
+ orelse Vars2 =:= ?bypassed of
+ true -> RaceVarMap;
+ false ->
+ case is_list(Vars1) andalso is_list(Vars2) of
+ true ->
+ case Vars1 of
+ [] -> RaceVarMap;
+ [AHead|ATail] ->
+ case Vars2 of
+ [] -> RaceVarMap;
+ [PHead|PTail] ->
+ NewRaceVarMap = race_var_map(AHead, PHead, RaceVarMap, Op),
+ race_var_map(ATail, PTail, NewRaceVarMap, Op)
+ end
+ end;
+ false ->
+ {NewVars1, NewVars2, Bool} =
+ case is_list(Vars1) of
+ true ->
+ case Vars1 of
+ [Var1] -> {Var1, Vars2, true};
+ _Thing -> {Vars1, Vars2, false}
+ end;
+ false ->
+ case is_list(Vars2) of
+ true ->
+ case Vars2 of
+ [Var2] -> {Vars1, Var2, true};
+ _Thing -> {Vars1, Vars2, false}
+ end;
+ false -> {Vars1, Vars2, true}
+ end
+ end,
+ case Bool of
+ true ->
+ case cerl:type(NewVars1) of
+ var ->
+ case cerl:type(NewVars2) of
+ var ->
+ ALabel = cerl_trees:get_label(NewVars1),
+ PLabel = cerl_trees:get_label(NewVars2),
+ case Op of
+ bind ->
+ TempRaceVarMap =
+ bind_dict_vars(ALabel, PLabel, RaceVarMap),
+ bind_dict_vars(PLabel, ALabel, TempRaceVarMap);
+ unbind ->
+ TempRaceVarMap =
+ unbind_dict_vars(ALabel, PLabel, RaceVarMap),
+ unbind_dict_vars(PLabel, ALabel, TempRaceVarMap)
+ end;
+ alias ->
+ race_var_map(NewVars1, cerl:alias_var(NewVars2),
+ RaceVarMap, Op);
+ values ->
+ race_var_map(NewVars1, cerl:values_es(NewVars2),
+ RaceVarMap, Op);
+ _Other -> RaceVarMap
+ end;
+ tuple ->
+ case cerl:type(NewVars2) of
+ tuple ->
+ race_var_map(cerl:tuple_es(NewVars1),
+ cerl:tuple_es(NewVars2), RaceVarMap, Op);
+ alias ->
+ race_var_map(NewVars1, cerl:alias_var(NewVars2),
+ RaceVarMap, Op);
+ values ->
+ race_var_map(NewVars1, cerl:values_es(NewVars2),
+ RaceVarMap, Op);
+ _Other -> RaceVarMap
+ end;
+ cons ->
+ case cerl:type(NewVars2) of
+ cons ->
+ NewRaceVarMap = race_var_map(cerl:cons_hd(NewVars1),
+ cerl:cons_hd(NewVars2), RaceVarMap, Op),
+ race_var_map(cerl:cons_tl(NewVars1),
+ cerl:cons_tl(NewVars2), NewRaceVarMap, Op);
+ alias ->
+ race_var_map(NewVars1, cerl:alias_var(NewVars2),
+ RaceVarMap, Op);
+ values ->
+ race_var_map(NewVars1, cerl:values_es(NewVars2),
+ RaceVarMap, Op);
+ _Other -> RaceVarMap
+ end;
+ alias ->
+ case cerl:type(NewVars2) of
+ alias ->
+ race_var_map(cerl:alias_var(NewVars1),
+ cerl:alias_var(NewVars2), RaceVarMap, Op);
+ _Other ->
+ race_var_map(cerl:alias_var(NewVars1),
+ NewVars2, RaceVarMap, Op)
+ end;
+ values ->
+ case cerl:type(NewVars2) of
+ values ->
+ race_var_map(cerl:values_es(NewVars1),
+ cerl:values_es(NewVars2), RaceVarMap, Op);
+ _Other ->
+ race_var_map(cerl:values_es(NewVars1),
+ NewVars2, RaceVarMap, Op)
+ end;
+ _Other -> RaceVarMap
+ end;
+ false -> RaceVarMap
+ end
+ end
+ end.
+
+race_var_map_clauses(Clauses, RaceVarMap) ->
+ case Clauses of
+ [] -> RaceVarMap;
+ [#end_clause{arg = Arg, pats = Pats, guard = Guard}|T] ->
+ {RaceVarMap1, _RemoveClause} =
+ race_var_map_guard(Arg, Pats, Guard, RaceVarMap, bind),
+ race_var_map_clauses(T, RaceVarMap1)
+ end.
+
+race_var_map_guard(Arg, Pats, Guard, RaceVarMap, Op) ->
+ {NewRaceVarMap, RemoveClause} =
+ case cerl:type(Guard) of
+ call ->
+ CallName = cerl:call_name(Guard),
+ case cerl:is_literal(CallName) of
+ true ->
+ case cerl:concrete(CallName) of
+ '=:=' ->
+ [Arg1, Arg2] = cerl:call_args(Guard),
+ {race_var_map(Arg1, Arg2, RaceVarMap, Op), false};
+ '==' ->
+ [Arg1, Arg2] = cerl:call_args(Guard),
+ {race_var_map(Arg1, Arg2, RaceVarMap, Op), false};
+ '=/=' ->
+ case Op of
+ bind ->
+ [Arg1, Arg2] = cerl:call_args(Guard),
+ {RaceVarMap, are_bound_vars(Arg1, Arg2, RaceVarMap)};
+ unbind -> {RaceVarMap, false}
+ end;
+ _Other -> {RaceVarMap, false}
+ end;
+ false -> {RaceVarMap, false}
+ end;
+ _Other -> {RaceVarMap, false}
+ end,
+ {RaceVarMap1, RemoveClause1} =
+ race_var_map_guard_helper1(Arg, Pats,
+ race_var_map(Arg, Pats, NewRaceVarMap, Op), Op),
+ {RaceVarMap1, RemoveClause orelse RemoveClause1}.
+
+race_var_map_guard_helper1(Arg, Pats, RaceVarMap, Op) ->
+ case Arg =:= ?no_arg orelse Arg =:= ?bypassed of
+ true -> {RaceVarMap, false};
+ false ->
+ case cerl:type(Arg) of
+ call ->
+ case Pats of
+ [NewPat] ->
+ ModName = cerl:call_module(Arg),
+ CallName = cerl:call_name(Arg),
+ case cerl:is_literal(ModName) andalso
+ cerl:is_literal(CallName) of
+ true ->
+ case {cerl:concrete(ModName),
+ cerl:concrete(CallName)} of
+ {erlang, '=:='} ->
+ race_var_map_guard_helper2(Arg, NewPat, true,
+ RaceVarMap, Op);
+ {erlang, '=='} ->
+ race_var_map_guard_helper2(Arg, NewPat, true,
+ RaceVarMap, Op);
+ {erlang, '=/='} ->
+ race_var_map_guard_helper2(Arg, NewPat, false,
+ RaceVarMap, Op);
+ _Else -> {RaceVarMap, false}
+ end;
+ false -> {RaceVarMap, false}
+ end;
+ _Other -> {RaceVarMap, false}
+ end;
+ _Other -> {RaceVarMap, false}
+ end
+ end.
+
+race_var_map_guard_helper2(Arg, Pat0, Bool, RaceVarMap, Op) ->
+ Pat = cerl:fold_literal(Pat0),
+ case cerl:type(Pat) of
+ literal ->
+ [Arg1, Arg2] = cerl:call_args(Arg),
+ case cerl:concrete(Pat) of
+ Bool ->
+ {race_var_map(Arg1, Arg2, RaceVarMap, Op), false};
+ _Else ->
+ case Op of
+ bind ->
+ {RaceVarMap, are_bound_vars(Arg1, Arg2, RaceVarMap)};
+ unbind -> {RaceVarMap, false}
+ end
+ end;
+ _Else -> {RaceVarMap, false}
+ end.
+
+unbind_dict_vars(Var, Var, RaceVarMap) ->
+ RaceVarMap;
+unbind_dict_vars(Var1, Var2, RaceVarMap) ->
+ case dict:find(Var1, RaceVarMap) of
+ error -> RaceVarMap;
+ {ok, Labels} ->
+ case Labels of
+ [] -> dict:erase(Var1, RaceVarMap);
+ _Else ->
+ case lists:member(Var2, Labels) of
+ true ->
+ unbind_dict_vars(Var1, Var2,
+ bind_dict_vars_list(Var1, Labels -- [Var2],
+ dict:erase(Var1, RaceVarMap)));
+ false ->
+ unbind_dict_vars_helper(Labels, Var1, Var2, RaceVarMap)
+ end
+ end
+ end.
+
+unbind_dict_vars_helper(Labels, Key, CompLabel, RaceVarMap) ->
+ case dict:size(RaceVarMap) of
+ 0 -> RaceVarMap;
+ _ ->
+ case Labels of
+ [] -> RaceVarMap;
+ [Head|Tail] ->
+ NewRaceVarMap =
+ case are_bound_labels(Head, CompLabel, RaceVarMap) orelse
+ are_bound_labels(CompLabel, Head, RaceVarMap) of
+ true ->
+ bind_dict_vars_list(Key, Labels -- [Head],
+ dict:erase(Key, RaceVarMap));
+ false -> RaceVarMap
+ end,
+ unbind_dict_vars_helper(Tail, Key, CompLabel, NewRaceVarMap)
+ end
+ end.
+
+var_analysis(FunDefArgs, FunCallArgs, WarnVarArgs, RaceWarnTag) ->
+ case RaceWarnTag of
+ ?WARN_WHEREIS_REGISTER ->
+ [WVA1, WVA2, WVA3, WVA4] = WarnVarArgs,
+ ArgNos = lists_key_members_lists(WVA1, FunDefArgs),
+ [[lists_get(N, FunCallArgs) || N <- ArgNos], WVA2, WVA3, WVA4];
+ ?WARN_WHEREIS_UNREGISTER ->
+ [WVA1, WVA2] = WarnVarArgs,
+ ArgNos = lists_key_members_lists(WVA1, FunDefArgs),
+ [[lists_get(N, FunCallArgs) || N <- ArgNos], WVA2];
+ ?WARN_ETS_LOOKUP_INSERT ->
+ [WVA1, WVA2, WVA3, WVA4] = WarnVarArgs,
+ ArgNos1 = lists_key_members_lists(WVA1, FunDefArgs),
+ ArgNos2 = lists_key_members_lists(WVA3, FunDefArgs),
+ [[lists_get(N1, FunCallArgs) || N1 <- ArgNos1], WVA2,
+ [lists_get(N2, FunCallArgs) || N2 <- ArgNos2], WVA4];
+ ?WARN_MNESIA_DIRTY_READ_WRITE ->
+ [WVA1, WVA2|T] = WarnVarArgs,
+ ArgNos = lists_key_members_lists(WVA1, FunDefArgs),
+ [[lists_get(N, FunCallArgs) || N <- ArgNos], WVA2|T]
+ end.
+
+var_type_analysis(FunDefArgs, FunCallTypes, WarnVarArgs, RaceWarnTag,
+ RaceVarMap, CleanState) ->
+ FunVarArgs = format_args(FunDefArgs, FunCallTypes, CleanState, function_call),
+ case RaceWarnTag of
+ ?WARN_WHEREIS_REGISTER ->
+ [WVA1, WVA2, WVA3, WVA4] = WarnVarArgs,
+ Vars = find_all_bound_vars(WVA1, RaceVarMap),
+ case lists_key_member_lists(Vars, FunVarArgs) of
+ 0 -> [Vars, WVA2, WVA3, WVA4];
+ N when is_integer(N) ->
+ NewWVA2 = string:tokens(lists:nth(N + 1, FunVarArgs), " |"),
+ [Vars, NewWVA2, WVA3, WVA4]
+ end;
+ ?WARN_WHEREIS_UNREGISTER ->
+ [WVA1, WVA2] = WarnVarArgs,
+ Vars = find_all_bound_vars(WVA1, RaceVarMap),
+ case lists_key_member_lists(Vars, FunVarArgs) of
+ 0 -> [Vars, WVA2];
+ N when is_integer(N) ->
+ NewWVA2 = string:tokens(lists:nth(N + 1, FunVarArgs), " |"),
+ [Vars, NewWVA2]
+ end;
+ ?WARN_ETS_LOOKUP_INSERT ->
+ [WVA1, WVA2, WVA3, WVA4] = WarnVarArgs,
+ Vars1 = find_all_bound_vars(WVA1, RaceVarMap),
+ FirstVarArg =
+ case lists_key_member_lists(Vars1, FunVarArgs) of
+ 0 -> [Vars1, WVA2];
+ N1 when is_integer(N1) ->
+ NewWVA2 = string:tokens(lists:nth(N1 + 1, FunVarArgs), " |"),
+ [Vars1, NewWVA2]
+ end,
+ Vars2 =
+ lists:flatten(
+ [find_all_bound_vars(A, RaceVarMap) || A <- ets_list_args(WVA3)]),
+ case lists_key_member_lists(Vars2, FunVarArgs) of
+ 0 -> FirstVarArg ++ [Vars2, WVA4];
+ N2 when is_integer(N2) ->
+ NewWVA4 =
+ ets_tuple_argtypes2(
+ ets_tuple_argtypes1(lists:nth(N2 + 1, FunVarArgs), [], [], 0),
+ []),
+ FirstVarArg ++ [Vars2, NewWVA4]
+
+ end;
+ ?WARN_MNESIA_DIRTY_READ_WRITE ->
+ [WVA1, WVA2|T] = WarnVarArgs,
+ Arity =
+ case T of
+ [] -> 1;
+ _Else -> 2
+ end,
+ Vars = find_all_bound_vars(WVA1, RaceVarMap),
+ case lists_key_member_lists(Vars, FunVarArgs) of
+ 0 -> [Vars, WVA2|T];
+ N when is_integer(N) ->
+ NewWVA2 =
+ case Arity of
+ 1 ->
+ [mnesia_record_tab(R) || R <- string:tokens(
+ lists:nth(2, FunVarArgs), " |")];
+ 2 ->
+ string:tokens(lists:nth(N + 1, FunVarArgs), " |")
+ end,
+ [Vars, NewWVA2|T]
+ end
+ end.
+
+%%% ===========================================================================
+%%%
+%%% Warning Format Utilities
+%%%
+%%% ===========================================================================
+
+add_race_warning(Warn, #races{race_warnings = Warns} = Races) ->
+ Races#races{race_warnings = [Warn|Warns]}.
+
+get_race_warn(Fun, Args, ArgTypes, DepList, State) ->
+ {M, F, _A} = Fun,
+ case DepList of
+ [] -> {State, no_race};
+ _Other ->
+ {State, {race_condition, [M, F, Args, ArgTypes, State, DepList]}}
+ end.
+
+-spec get_race_warnings(races(), dialyzer_dataflow:state()) ->
+ {races(), dialyzer_dataflow:state()}.
+
+get_race_warnings(#races{race_warnings = RaceWarnings}, State) ->
+ get_race_warnings_helper(RaceWarnings, State).
+
+get_race_warnings_helper(Warnings, State) ->
+ case Warnings of
+ [] ->
+ {dialyzer_dataflow:state__get_races(State), State};
+ [H|T] ->
+ {RaceWarnTag, WarningInfo, {race_condition, [M, F, A, AT, S, DepList]}} = H,
+ Reason =
+ case RaceWarnTag of
+ ?WARN_WHEREIS_REGISTER ->
+ get_reason(lists:keysort(7, DepList),
+ "might fail due to a possible race condition "
+ "caused by its combination with ");
+ ?WARN_WHEREIS_UNREGISTER ->
+ get_reason(lists:keysort(7, DepList),
+ "might fail due to a possible race condition "
+ "caused by its combination with ");
+ ?WARN_ETS_LOOKUP_INSERT ->
+ get_reason(lists:keysort(7, DepList),
+ "might have an unintended effect due to " ++
+ "a possible race condition " ++
+ "caused by its combination with ");
+ ?WARN_MNESIA_DIRTY_READ_WRITE ->
+ get_reason(lists:keysort(7, DepList),
+ "might have an unintended effect due to " ++
+ "a possible race condition " ++
+ "caused by its combination with ")
+ end,
+ W =
+ {?WARN_RACE_CONDITION, WarningInfo,
+ {race_condition,
+ [M, F, dialyzer_dataflow:format_args(A, AT, S), Reason]}},
+ get_race_warnings_helper(T,
+ dialyzer_dataflow:state__add_warning(W, State))
+ end.
+
+get_reason(DependencyList, Reason) ->
+ case DependencyList of
+ [] -> "";
+ [#dep_call{call_name = Call, arg_types = ArgTypes, vars = Args,
+ state = State, file_line = {File, Line}}|T] ->
+ R =
+ Reason ++
+ case Call of
+ whereis -> "the erlang:whereis";
+ ets_lookup -> "the ets:lookup";
+ mnesia_dirty_read -> "the mnesia:dirty_read"
+ end ++
+ dialyzer_dataflow:format_args(Args, ArgTypes, State) ++
+ " call in " ++
+ filename:basename(File) ++
+ " on line " ++
+ lists:flatten(io_lib:write(Line)),
+ case T of
+ [] -> R;
+ _ -> get_reason(T, R ++ ", ")
+ end
+ end.
+
+state__add_race_warning(State, RaceWarn, RaceWarnTag, WarningInfo) ->
+ case RaceWarn of
+ no_race -> State;
+ _Else ->
+ Races = dialyzer_dataflow:state__get_races(State),
+ Warn = {RaceWarnTag, WarningInfo, RaceWarn},
+ dialyzer_dataflow:state__put_races(add_race_warning(Warn, Races), State)
+ end.
+
+%%% ===========================================================================
+%%%
+%%% Record Interfaces
+%%%
+%%% ===========================================================================
+
+-spec beg_clause_new(var_to_map1(), var_to_map1(), cerl:cerl()) ->
+ #beg_clause{}.
+
+beg_clause_new(Arg, Pats, Guard) ->
+ #beg_clause{arg = Arg, pats = Pats, guard = Guard}.
+
+-spec cleanup(races()) -> races().
+
+cleanup(#races{race_list = RaceList}) ->
+ #races{race_list = RaceList}.
+
+-spec end_case_new([#end_clause{}]) -> #end_case{}.
+
+end_case_new(Clauses) ->
+ #end_case{clauses = Clauses}.
+
+-spec end_clause_new(var_to_map1(), var_to_map1(), cerl:cerl()) ->
+ #end_clause{}.
+
+end_clause_new(Arg, Pats, Guard) ->
+ #end_clause{arg = Arg, pats = Pats, guard = Guard}.
+
+-spec get_curr_fun(races()) -> dialyzer_callgraph:mfa_or_funlbl().
+
+get_curr_fun(#races{curr_fun = CurrFun}) ->
+ CurrFun.
+
+-spec get_curr_fun_args(races()) -> core_args().
+
+get_curr_fun_args(#races{curr_fun_args = CurrFunArgs}) ->
+ CurrFunArgs.
+
+-spec get_new_table(races()) -> table().
+
+get_new_table(#races{new_table = Table}) ->
+ Table.
+
+-spec get_race_analysis(races()) -> boolean().
+
+get_race_analysis(#races{race_analysis = RaceAnalysis}) ->
+ RaceAnalysis.
+
+-spec get_race_list(races()) -> code().
+
+get_race_list(#races{race_list = RaceList}) ->
+ RaceList.
+
+-spec get_race_list_size(races()) -> non_neg_integer().
+
+get_race_list_size(#races{race_list_size = RaceListSize}) ->
+ RaceListSize.
+
+-spec get_race_list_and_size(races()) -> {code(), non_neg_integer()}.
+
+get_race_list_and_size(#races{race_list = RaceList,
+ race_list_size = RaceListSize}) ->
+ {RaceList, RaceListSize}.
+
+-spec let_tag_new(var_to_map1(), var_to_map1()) -> #let_tag{}.
+
+let_tag_new(Var, Arg) ->
+ #let_tag{var = Var, arg = Arg}.
+
+-spec new() -> races().
+
+new() -> #races{}.
+
+-spec put_curr_fun(dialyzer_callgraph:mfa_or_funlbl(), label(), races()) ->
+ races().
+
+put_curr_fun(CurrFun, CurrFunLabel, Races) ->
+ Races#races{curr_fun = CurrFun,
+ curr_fun_label = CurrFunLabel,
+ curr_fun_args = empty}.
+
+-spec put_fun_args(core_args(), races()) -> races().
+
+put_fun_args(Args, #races{curr_fun_args = CurrFunArgs} = Races) ->
+ case CurrFunArgs of
+ empty -> Races#races{curr_fun_args = Args};
+ _Other -> Races
+ end.
+
+-spec put_race_analysis(boolean(), races()) ->
+ races().
+
+put_race_analysis(Analysis, Races) ->
+ Races#races{race_analysis = Analysis}.
+
+-spec put_race_list(code(), non_neg_integer(), races()) ->
+ races().
+
+put_race_list(RaceList, RaceListSize, Races) ->
+ Races#races{race_list = RaceList, race_list_size = RaceListSize}.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/erl_types.erl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/erl_types.erl
new file mode 100644
index 0000000000..41e3d4be27
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/erl_types.erl
@@ -0,0 +1,5735 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% ======================================================================
+%% Copyright (C) 2000-2003 Richard Carlsson
+%%
+%% ======================================================================
+%% Provides a representation of Erlang types.
+%%
+%% The initial author of this file is Richard Carlsson (2000-2004).
+%% In July 2006, the type representation was totally re-designed by
+%% Tobias Lindahl. This is the representation which is used currently.
+%% In late 2008, Manouk Manoukian and Kostis Sagonas added support for
+%% opaque types to the structure-based representation of types.
+%% During February and March 2009, Kostis Sagonas significantly
+%% cleaned up the type representation and added spec declarations.
+%%
+%% ======================================================================
+
+-module(erl_types).
+
+-export([any_none/1,
+ any_none_or_unit/1,
+ lookup_record/3,
+ max/2,
+ min/2,
+ number_max/1, number_max/2,
+ number_min/1, number_min/2,
+ t_abstract_records/2,
+ t_any/0,
+ t_arity/0,
+ t_atom/0,
+ t_atom/1,
+ t_atoms/1,
+ t_atom_vals/1, t_atom_vals/2,
+ t_binary/0,
+ t_bitstr/0,
+ t_bitstr/2,
+ t_bitstr_base/1,
+ t_bitstr_concat/1,
+ t_bitstr_concat/2,
+ t_bitstr_match/2,
+ t_bitstr_unit/1,
+ t_bitstrlist/0,
+ t_boolean/0,
+ t_byte/0,
+ t_char/0,
+ t_collect_vars/1,
+ t_cons/0,
+ t_cons/2,
+ t_cons_hd/1, t_cons_hd/2,
+ t_cons_tl/1, t_cons_tl/2,
+ t_contains_opaque/1, t_contains_opaque/2,
+ t_decorate_with_opaque/3,
+ t_elements/1,
+ t_find_opaque_mismatch/3,
+ t_find_unknown_opaque/3,
+ t_fixnum/0,
+ t_map/2,
+ t_non_neg_fixnum/0,
+ t_pos_fixnum/0,
+ t_float/0,
+ t_var_names/1,
+ t_form_to_string/1,
+ t_from_form/6,
+ t_from_form_without_remote/3,
+ t_check_record_fields/6,
+ t_from_range/2,
+ t_from_range_unsafe/2,
+ t_from_term/1,
+ t_fun/0,
+ t_fun/1,
+ t_fun/2,
+ t_fun_args/1, t_fun_args/2,
+ t_fun_arity/1, t_fun_arity/2,
+ t_fun_range/1, t_fun_range/2,
+ t_has_opaque_subtype/2,
+ t_has_var/1,
+ t_identifier/0,
+ %% t_improper_list/2,
+ t_inf/1,
+ t_inf/2,
+ t_inf/3,
+ t_inf_lists/2,
+ t_inf_lists/3,
+ t_integer/0,
+ t_integer/1,
+ t_non_neg_integer/0,
+ t_pos_integer/0,
+ t_integers/1,
+ t_iodata/0,
+ t_iolist/0,
+ t_is_any/1,
+ t_is_atom/1, t_is_atom/2,
+ t_is_any_atom/2, t_is_any_atom/3,
+ t_is_binary/1, t_is_binary/2,
+ t_is_bitstr/1, t_is_bitstr/2,
+ t_is_bitwidth/1,
+ t_is_boolean/1, t_is_boolean/2,
+ %% t_is_byte/1,
+ %% t_is_char/1,
+ t_is_cons/1, t_is_cons/2,
+ t_is_equal/2,
+ t_is_fixnum/1,
+ t_is_float/1, t_is_float/2,
+ t_is_fun/1, t_is_fun/2,
+ t_is_instance/2,
+ t_is_integer/1, t_is_integer/2,
+ t_is_list/1,
+ t_is_map/1,
+ t_is_map/2,
+ t_is_matchstate/1,
+ t_is_nil/1, t_is_nil/2,
+ t_is_non_neg_integer/1,
+ t_is_none/1,
+ t_is_none_or_unit/1,
+ t_is_number/1, t_is_number/2,
+ t_is_opaque/1, t_is_opaque/2,
+ t_is_pid/1, t_is_pid/2,
+ t_is_port/1, t_is_port/2,
+ t_is_maybe_improper_list/1, t_is_maybe_improper_list/2,
+ t_is_reference/1, t_is_reference/2,
+ t_is_singleton/1,
+ t_is_singleton/2,
+ t_is_string/1,
+ t_is_subtype/2,
+ t_is_tuple/1, t_is_tuple/2,
+ t_is_unit/1,
+ t_is_var/1,
+ t_limit/2,
+ t_list/0,
+ t_list/1,
+ t_list_elements/1, t_list_elements/2,
+ t_list_termination/1, t_list_termination/2,
+ t_map/0,
+ t_map/1,
+ t_map/3,
+ t_map_entries/2, t_map_entries/1,
+ t_map_def_key/2, t_map_def_key/1,
+ t_map_def_val/2, t_map_def_val/1,
+ t_map_get/2, t_map_get/3,
+ t_map_is_key/2, t_map_is_key/3,
+ t_map_update/2, t_map_update/3,
+ t_map_put/2, t_map_put/3,
+ t_matchstate/0,
+ t_matchstate/2,
+ t_matchstate_present/1,
+ t_matchstate_slot/2,
+ t_matchstate_slots/1,
+ t_matchstate_update_present/2,
+ t_matchstate_update_slot/3,
+ t_mfa/0,
+ t_module/0,
+ t_nil/0,
+ t_node/0,
+ t_none/0,
+ t_nonempty_list/0,
+ t_nonempty_list/1,
+ t_nonempty_string/0,
+ t_number/0,
+ t_number/1,
+ t_number_vals/1, t_number_vals/2,
+ t_opaque_from_records/1,
+ t_opaque_structure/1,
+ t_pid/0,
+ t_port/0,
+ t_maybe_improper_list/0,
+ %% t_maybe_improper_list/2,
+ t_product/1,
+ t_reference/0,
+ t_singleton_to_term/2,
+ t_string/0,
+ t_struct_from_opaque/2,
+ t_subst/2,
+ t_subtract/2,
+ t_subtract_list/2,
+ t_sup/1,
+ t_sup/2,
+ t_timeout/0,
+ t_to_string/1,
+ t_to_string/2,
+ t_to_tlist/1,
+ t_tuple/0,
+ t_tuple/1,
+ t_tuple_args/1, t_tuple_args/2,
+ t_tuple_size/1, t_tuple_size/2,
+ t_tuple_sizes/1,
+ t_tuple_subtypes/1,
+ t_tuple_subtypes/2,
+ t_unify/2,
+ t_unit/0,
+ t_unopaque/1, t_unopaque/2,
+ t_var/1,
+ t_var_name/1,
+ %% t_assign_variables_to_subtype/2,
+ type_is_defined/4,
+ record_field_diffs_to_string/2,
+ subst_all_vars_to_any/1,
+ lift_list_to_pos_empty/1, lift_list_to_pos_empty/2,
+ is_opaque_type/2,
+ is_erl_type/1,
+ atom_to_string/1,
+ var_table__new/0,
+ cache__new/0,
+ map_pairwise_merge/3
+ ]).
+
+%%-define(DO_ERL_TYPES_TEST, true).
+-compile({no_auto_import,[min/2,max/2]}).
+
+-ifdef(DO_ERL_TYPES_TEST).
+-export([test/0]).
+-else.
+-define(NO_UNUSED, true).
+-endif.
+
+-ifndef(NO_UNUSED).
+-export([t_is_identifier/1]).
+-endif.
+
+-export_type([erl_type/0, opaques/0, type_table/0, var_table/0, cache/0]).
+
+%%-define(DEBUG, true).
+
+-ifdef(DEBUG).
+-define(debug(__A), __A).
+-else.
+-define(debug(__A), ok).
+-endif.
+
+%%=============================================================================
+%%
+%% Definition of the type structure
+%%
+%%=============================================================================
+
+%%-----------------------------------------------------------------------------
+%% Limits
+%%
+
+-define(REC_TYPE_LIMIT, 2).
+-define(EXPAND_DEPTH, 16).
+-define(EXPAND_LIMIT, 10000).
+
+-define(TUPLE_TAG_LIMIT, 5).
+-define(TUPLE_ARITY_LIMIT, 8).
+-define(SET_LIMIT, 13).
+-define(MAX_BYTE, 255).
+-define(MAX_CHAR, 16#10ffff).
+
+-define(UNIT_MULTIPLIER, 8).
+
+-define(TAG_IMMED1_SIZE, 4).
+-define(BITS, (erlang:system_info(wordsize) * 8) - ?TAG_IMMED1_SIZE).
+
+-define(MAX_TUPLE_SIZE, (1 bsl 10)).
+
+%%-----------------------------------------------------------------------------
+%% Type tags and qualifiers
+%%
+
+-define(atom_tag, atom).
+-define(binary_tag, binary).
+-define(function_tag, function).
+-define(identifier_tag, identifier).
+-define(list_tag, list).
+-define(map_tag, map).
+-define(matchstate_tag, matchstate).
+-define(nil_tag, nil).
+-define(number_tag, number).
+-define(opaque_tag, opaque).
+-define(product_tag, product).
+-define(tuple_set_tag, tuple_set).
+-define(tuple_tag, tuple).
+-define(union_tag, union).
+-define(var_tag, var).
+
+-type tag() :: ?atom_tag | ?binary_tag | ?function_tag | ?identifier_tag
+ | ?list_tag | ?map_tag | ?matchstate_tag | ?nil_tag | ?number_tag
+ | ?opaque_tag | ?product_tag
+ | ?tuple_tag | ?tuple_set_tag | ?union_tag | ?var_tag.
+
+-define(float_qual, float).
+-define(integer_qual, integer).
+-define(nonempty_qual, nonempty).
+-define(pid_qual, pid).
+-define(port_qual, port).
+-define(reference_qual, reference).
+-define(unknown_qual, unknown).
+
+-type qual() :: ?float_qual | ?integer_qual | ?nonempty_qual | ?pid_qual
+ | ?port_qual | ?reference_qual | ?unknown_qual | {_, _}.
+
+%%-----------------------------------------------------------------------------
+%% The type representation
+%%
+
+-define(any, any).
+-define(none, none).
+-define(unit, unit).
+%% Generic constructor - elements can be many things depending on the tag.
+-record(c, {tag :: tag(),
+ elements = [] :: term(),
+ qualifier = ?unknown_qual :: qual()}).
+
+-opaque erl_type() :: ?any | ?none | ?unit | #c{}.
+
+%%-----------------------------------------------------------------------------
+%% Auxiliary types and convenient macros
+%%
+
+-type parse_form() :: erl_parse:abstract_type().
+-type rng_elem() :: 'pos_inf' | 'neg_inf' | integer().
+
+-record(int_set, {set :: [integer()]}).
+-record(int_rng, {from :: rng_elem(), to :: rng_elem()}).
+%% Note: the definition of #opaque{} was changed to 'mod' and 'name';
+%% it used to be an ordsets of {Mod, Name} pairs. The Dialyzer version
+%% was updated to 2.7 due to this change.
+-record(opaque, {mod :: module(), name :: atom(),
+ args = [] :: [erl_type()], struct :: erl_type()}).
+
+-define(atom(Set), #c{tag=?atom_tag, elements=Set}).
+-define(bitstr(Unit, Base), #c{tag=?binary_tag, elements=[Unit,Base]}).
+-define(float, ?number(?any, ?float_qual)).
+-define(function(Domain, Range), #c{tag=?function_tag,
+ elements=[Domain, Range]}).
+-define(identifier(Types), #c{tag=?identifier_tag, elements=Types}).
+-define(integer(Types), ?number(Types, ?integer_qual)).
+-define(int_range(From, To), ?integer(#int_rng{from=From, to=To})).
+-define(int_set(Set), ?integer(#int_set{set=Set})).
+-define(list(Types, Term, Size), #c{tag=?list_tag, elements=[Types,Term],
+ qualifier=Size}).
+-define(nil, #c{tag=?nil_tag}).
+-define(nonempty_list(Types, Term),?list(Types, Term, ?nonempty_qual)).
+-define(number(Set, Qualifier), #c{tag=?number_tag, elements=Set,
+ qualifier=Qualifier}).
+-define(map(Pairs,DefKey,DefVal),
+ #c{tag=?map_tag, elements={Pairs,DefKey,DefVal}}).
+-define(opaque(Optypes), #c{tag=?opaque_tag, elements=Optypes}).
+-define(product(Types), #c{tag=?product_tag, elements=Types}).
+-define(tuple(Types, Arity, Qual), #c{tag=?tuple_tag, elements=Types,
+ qualifier={Arity, Qual}}).
+-define(tuple_set(Tuples), #c{tag=?tuple_set_tag, elements=Tuples}).
+-define(var(Id), #c{tag=?var_tag, elements=Id}).
+
+-define(matchstate(P, Slots), #c{tag=?matchstate_tag, elements=[P,Slots]}).
+-define(any_matchstate, ?matchstate(t_bitstr(), ?any)).
+
+-define(byte, ?int_range(0, ?MAX_BYTE)).
+-define(char, ?int_range(0, ?MAX_CHAR)).
+-define(integer_pos, ?int_range(1, pos_inf)).
+-define(integer_non_neg, ?int_range(0, pos_inf)).
+-define(integer_neg, ?int_range(neg_inf, -1)).
+
+-type opaques() :: [erl_type()] | 'universe'.
+
+-type record_key() :: {'record', atom()}.
+-type type_key() :: {'type' | 'opaque', mfa()}.
+-type record_value() :: [{atom(), erl_parse:abstract_expr(), erl_type()}].
+-type type_value() :: {{module(), {file:name(), erl_anno:line()},
+ erl_parse:abstract_type(), ArgNames :: [atom()]},
+ erl_type()}.
+-type type_table() :: dict:dict(record_key() | type_key(),
+ record_value() | type_value()).
+
+-opaque var_table() :: #{atom() => erl_type()}.
+
+%%-----------------------------------------------------------------------------
+%% Unions
+%%
+
+-define(union(List), #c{tag=?union_tag, elements=[_,_,_,_,_,_,_,_,_,_]=List}).
+
+-define(atom_union(T), ?union([T,?none,?none,?none,?none,?none,?none,?none,?none,?none])).
+-define(bitstr_union(T), ?union([?none,T,?none,?none,?none,?none,?none,?none,?none,?none])).
+-define(function_union(T), ?union([?none,?none,T,?none,?none,?none,?none,?none,?none,?none])).
+-define(identifier_union(T), ?union([?none,?none,?none,T,?none,?none,?none,?none,?none,?none])).
+-define(list_union(T), ?union([?none,?none,?none,?none,T,?none,?none,?none,?none,?none])).
+-define(number_union(T), ?union([?none,?none,?none,?none,?none,T,?none,?none,?none,?none])).
+-define(tuple_union(T), ?union([?none,?none,?none,?none,?none,?none,T,?none,?none,?none])).
+-define(matchstate_union(T), ?union([?none,?none,?none,?none,?none,?none,?none,T,?none,?none])).
+-define(opaque_union(T), ?union([?none,?none,?none,?none,?none,?none,?none,?none,T,?none])).
+-define(map_union(T), ?union([?none,?none,?none,?none,?none,?none,?none,?none,?none,T])).
+-define(integer_union(T), ?number_union(T)).
+-define(float_union(T), ?number_union(T)).
+-define(nil_union(T), ?list_union(T)).
+
+
+%%=============================================================================
+%%
+%% Primitive operations such as type construction and type tests
+%%
+%%=============================================================================
+
+%%-----------------------------------------------------------------------------
+%% Top and bottom
+%%
+
+-spec t_any() -> erl_type().
+
+t_any() ->
+ ?any.
+
+-spec t_is_any(erl_type()) -> boolean().
+
+t_is_any(Type) ->
+ do_opaque(Type, 'universe', fun is_any/1).
+
+is_any(?any) -> true;
+is_any(_) -> false.
+
+-spec t_none() -> erl_type().
+
+t_none() ->
+ ?none.
+
+-spec t_is_none(erl_type()) -> boolean().
+
+t_is_none(?none) -> true;
+t_is_none(_) -> false.
+
+%%-----------------------------------------------------------------------------
+%% Opaque types
+%%
+
+-spec t_opaque(module(), atom(), [_], erl_type()) -> erl_type().
+
+t_opaque(Mod, Name, Args, Struct) ->
+ O = #opaque{mod = Mod, name = Name, args = Args, struct = Struct},
+ ?opaque(set_singleton(O)).
+
+-spec t_is_opaque(erl_type(), [erl_type()]) -> boolean().
+
+t_is_opaque(?opaque(_) = Type, Opaques) ->
+ not is_opaque_type(Type, Opaques);
+t_is_opaque(_Type, _Opaques) -> false.
+
+-spec t_is_opaque(erl_type()) -> boolean().
+
+t_is_opaque(?opaque(_)) -> true;
+t_is_opaque(_) -> false.
+
+-spec t_has_opaque_subtype(erl_type(), opaques()) -> boolean().
+
+t_has_opaque_subtype(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun has_opaque_subtype/1).
+
+has_opaque_subtype(?union(Ts)) ->
+ lists:any(fun t_is_opaque/1, Ts);
+has_opaque_subtype(T) ->
+ t_is_opaque(T).
+
+-spec t_opaque_structure(erl_type()) -> erl_type().
+
+t_opaque_structure(?opaque(Elements)) ->
+ t_sup([Struct || #opaque{struct = Struct} <- ordsets:to_list(Elements)]).
+
+-spec t_contains_opaque(erl_type()) -> boolean().
+
+t_contains_opaque(Type) ->
+ t_contains_opaque(Type, []).
+
+%% Returns 'true' iff there is an opaque type that is *not* one of
+%% the types of the second argument.
+
+-spec t_contains_opaque(erl_type(), [erl_type()]) -> boolean().
+
+t_contains_opaque(?any, _Opaques) -> false;
+t_contains_opaque(?none, _Opaques) -> false;
+t_contains_opaque(?unit, _Opaques) -> false;
+t_contains_opaque(?atom(_Set), _Opaques) -> false;
+t_contains_opaque(?bitstr(_Unit, _Base), _Opaques) -> false;
+t_contains_opaque(?float, _Opaques) -> false;
+t_contains_opaque(?function(Domain, Range), Opaques) ->
+ t_contains_opaque(Domain, Opaques)
+ orelse t_contains_opaque(Range, Opaques);
+t_contains_opaque(?identifier(_Types), _Opaques) -> false;
+t_contains_opaque(?integer(_Types), _Opaques) -> false;
+t_contains_opaque(?int_range(_From, _To), _Opaques) -> false;
+t_contains_opaque(?int_set(_Set), _Opaques) -> false;
+t_contains_opaque(?list(Type, Tail, _), Opaques) ->
+ t_contains_opaque(Type, Opaques) orelse t_contains_opaque(Tail, Opaques);
+t_contains_opaque(?map(_, _, _) = Map, Opaques) ->
+ list_contains_opaque(map_all_types(Map), Opaques);
+t_contains_opaque(?matchstate(_P, _Slots), _Opaques) -> false;
+t_contains_opaque(?nil, _Opaques) -> false;
+t_contains_opaque(?number(_Set, _Tag), _Opaques) -> false;
+t_contains_opaque(?opaque(_)=T, Opaques) ->
+ not is_opaque_type(T, Opaques)
+ orelse t_contains_opaque(t_opaque_structure(T));
+t_contains_opaque(?product(Types), Opaques) ->
+ list_contains_opaque(Types, Opaques);
+t_contains_opaque(?tuple(?any, _, _), _Opaques) -> false;
+t_contains_opaque(?tuple(Types, _, _), Opaques) ->
+ list_contains_opaque(Types, Opaques);
+t_contains_opaque(?tuple_set(_Set) = T, Opaques) ->
+ list_contains_opaque(t_tuple_subtypes(T), Opaques);
+t_contains_opaque(?union(List), Opaques) ->
+ list_contains_opaque(List, Opaques);
+t_contains_opaque(?var(_Id), _Opaques) -> false.
+
+-spec list_contains_opaque([erl_type()], [erl_type()]) -> boolean().
+
+list_contains_opaque(List, Opaques) ->
+ lists:any(fun(E) -> t_contains_opaque(E, Opaques) end, List).
+
+%% t_find_opaque_mismatch/2 of two types should only be used if their
+%% t_inf is t_none() due to some opaque type violation.
+%%
+%% The first argument of the function is the pattern and its second
+%% argument the type we are matching against the pattern.
+
+-spec t_find_opaque_mismatch(erl_type(), erl_type(), [erl_type()]) ->
+ 'error' | {'ok', erl_type(), erl_type()}.
+
+t_find_opaque_mismatch(T1, T2, Opaques) ->
+ t_find_opaque_mismatch(T1, T2, T2, Opaques).
+
+t_find_opaque_mismatch(?any, _Type, _TopType, _Opaques) -> error;
+t_find_opaque_mismatch(?none, _Type, _TopType, _Opaques) -> error;
+t_find_opaque_mismatch(?list(T1, Tl1, _), ?list(T2, Tl2, _), TopType, Opaques) ->
+ t_find_opaque_mismatch_ordlists([T1, Tl1], [T2, Tl2], TopType, Opaques);
+t_find_opaque_mismatch(T1, ?opaque(_) = T2, TopType, Opaques) ->
+ case is_opaque_type(T2, Opaques) of
+ false -> {ok, TopType, T2};
+ true ->
+ t_find_opaque_mismatch(T1, t_opaque_structure(T2), TopType, Opaques)
+ end;
+t_find_opaque_mismatch(?opaque(_) = T1, T2, TopType, Opaques) ->
+ %% The generated message is somewhat misleading:
+ case is_opaque_type(T1, Opaques) of
+ false -> {ok, TopType, T1};
+ true ->
+ t_find_opaque_mismatch(t_opaque_structure(T1), T2, TopType, Opaques)
+ end;
+t_find_opaque_mismatch(?product(T1), ?product(T2), TopType, Opaques) ->
+ t_find_opaque_mismatch_ordlists(T1, T2, TopType, Opaques);
+t_find_opaque_mismatch(?tuple(T1, Arity, _), ?tuple(T2, Arity, _),
+ TopType, Opaques) ->
+ t_find_opaque_mismatch_ordlists(T1, T2, TopType, Opaques);
+t_find_opaque_mismatch(?tuple(_, _, _) = T1, ?tuple_set(_) = T2,
+ TopType, Opaques) ->
+ Tuples1 = t_tuple_subtypes(T1),
+ Tuples2 = t_tuple_subtypes(T2),
+ t_find_opaque_mismatch_lists(Tuples1, Tuples2, TopType, Opaques);
+t_find_opaque_mismatch(T1, ?union(U2), TopType, Opaques) ->
+ t_find_opaque_mismatch_lists([T1], U2, TopType, Opaques);
+t_find_opaque_mismatch(_T1, _T2, _TopType, _Opaques) -> error.
+
+t_find_opaque_mismatch_ordlists(L1, L2, TopType, Opaques) ->
+ List = lists:zipwith(fun(T1, T2) ->
+ t_find_opaque_mismatch(T1, T2, TopType, Opaques)
+ end, L1, L2),
+ t_find_opaque_mismatch_list(List).
+
+t_find_opaque_mismatch_lists(L1, L2, _TopType, Opaques) ->
+ List = [t_find_opaque_mismatch(T1, T2, T2, Opaques) || T1 <- L1, T2 <- L2],
+ t_find_opaque_mismatch_list(List).
+
+t_find_opaque_mismatch_list([]) -> error;
+t_find_opaque_mismatch_list([H|T]) ->
+ case H of
+ {ok, _T1, _T2} -> H;
+ error -> t_find_opaque_mismatch_list(T)
+ end.
+
+-spec t_find_unknown_opaque(erl_type(), erl_type(), opaques()) ->
+ [pos_integer()].
+
+%% The nice thing about using two types and t_inf() as compared to
+%% calling t_contains_opaque/2 is that the traversal stops when
+%% there is a mismatch which means that unknown opaque types "below"
+%% the mismatch are not found.
+t_find_unknown_opaque(_T1, _T2, 'universe') -> [];
+t_find_unknown_opaque(T1, T2, Opaques) ->
+ try t_inf(T1, T2, {match, Opaques}) of
+ _ -> []
+ catch throw:{pos, Ns} -> Ns
+ end.
+
+-spec t_decorate_with_opaque(erl_type(), erl_type(), [erl_type()]) -> erl_type().
+
+%% The first argument can contain opaque types. The second argument
+%% is assumed to be taken from the contract.
+
+t_decorate_with_opaque(T1, T2, Opaques) ->
+ case t_is_equal(T1, T2) orelse not t_contains_opaque(T2) of
+ true -> T1;
+ false ->
+ T = t_inf(T1, T2),
+ case t_contains_opaque(T) of
+ false -> T1;
+ true ->
+ R = decorate(T1, T, Opaques),
+ ?debug(case catch t_is_equal(t_unopaque(R), t_unopaque(T1)) of
+ true -> ok;
+ false ->
+ io:format("T1 = ~p,\n", [T1]),
+ io:format("T2 = ~p,\n", [T2]),
+ io:format("O = ~p,\n", [Opaques]),
+ io:format("erl_types:t_decorate_with_opaque(T1,T2,O).\n"),
+ throw({error, "Failed to handle opaque types"})
+ end),
+ R
+ end
+ end.
+
+decorate(Type, ?none, _Opaques) -> Type;
+decorate(?function(Domain, Range), ?function(D, R), Opaques) ->
+ ?function(decorate(Domain, D, Opaques), decorate(Range, R, Opaques));
+decorate(?list(Types, Tail, Size), ?list(Ts, Tl, _Sz), Opaques) ->
+ ?list(decorate(Types, Ts, Opaques), decorate(Tail, Tl, Opaques), Size);
+decorate(?product(Types), ?product(Ts), Opaques) ->
+ ?product(list_decorate(Types, Ts, Opaques));
+decorate(?tuple(_, _, _)=T, ?tuple(?any, _, _), _Opaques) -> T;
+decorate(?tuple(?any, _, _)=T, ?tuple(_, _, _), _Opaques) -> T;
+decorate(?tuple(Types, Arity, Tag), ?tuple(Ts, Arity, _), Opaques) ->
+ ?tuple(list_decorate(Types, Ts, Opaques), Arity, Tag);
+decorate(?tuple_set(List), ?tuple(_, Arity, _) = T, Opaques) ->
+ decorate_tuple_sets(List, [{Arity, [T]}], Opaques);
+decorate(?tuple_set(List), ?tuple_set(L), Opaques) ->
+ decorate_tuple_sets(List, L, Opaques);
+decorate(?union(List), T, Opaques) when T =/= ?any ->
+ ?union(L) = force_union(T),
+ union_decorate(List, L, Opaques);
+decorate(?opaque(_)=T, _, _Opaques) -> T;
+decorate(T, ?union(L), Opaques) when T =/= ?any ->
+ ?union(List) = force_union(T),
+ union_decorate(List, L, Opaques);
+decorate(Type, ?opaque(_)=T, Opaques) ->
+ decorate_with_opaque(Type, T, Opaques);
+decorate(Type, _T, _Opaques) -> Type.
+
+%% Note: it is important that #opaque.struct is a subtype of the
+%% opaque type.
+decorate_with_opaque(Type, ?opaque(Set2), Opaques) ->
+ case decoration(set_to_list(Set2), Type, Opaques, [], false) of
+ {[], false} -> Type;
+ {List, All} when List =/= [] ->
+ NewType = ?opaque(ordsets:from_list(List)),
+ case All of
+ true -> NewType;
+ false -> t_sup(NewType, Type)
+ end
+ end.
+
+decoration([#opaque{struct = S} = Opaque|OpaqueTypes], Type, Opaques,
+ NewOpaqueTypes0, All) ->
+ IsOpaque = is_opaque_type2(Opaque, Opaques),
+ I = t_inf(Type, S),
+ case not IsOpaque orelse t_is_none(I) of
+ true -> decoration(OpaqueTypes, Type, Opaques, NewOpaqueTypes0, All);
+ false ->
+ NewOpaque = Opaque#opaque{struct = decorate(I, S, Opaques)},
+ NewAll = All orelse t_is_equal(I, Type),
+ NewOpaqueTypes = [NewOpaque|NewOpaqueTypes0],
+ decoration(OpaqueTypes, Type, Opaques, NewOpaqueTypes, NewAll)
+ end;
+decoration([], _Type, _Opaques, NewOpaqueTypes, All) ->
+ {NewOpaqueTypes, All}.
+
+-spec list_decorate([erl_type()], [erl_type()], opaques()) -> [erl_type()].
+
+list_decorate(List, L, Opaques) ->
+ [decorate(Elem, E, Opaques) || {Elem, E} <- lists:zip(List, L)].
+
+union_decorate(U1, U2, Opaques) ->
+ Union = union_decorate(U1, U2, Opaques, 0, []),
+ [A,B,F,I,L,N,T,M,_,Map] = U1,
+ [_,_,_,_,_,_,_,_,Opaque,_] = U2,
+ List = [A,B,F,I,L,N,T,M,Map],
+ DecList = [Dec ||
+ E <- List,
+ not t_is_none(E),
+ not t_is_none(Dec = decorate(E, Opaque, Opaques))],
+ t_sup([Union|DecList]).
+
+union_decorate([?none|Left1], [_|Left2], Opaques, N, Acc) ->
+ union_decorate(Left1, Left2, Opaques, N, [?none|Acc]);
+union_decorate([T1|Left1], [?none|Left2], Opaques, N, Acc) ->
+ union_decorate(Left1, Left2, Opaques, N+1, [T1|Acc]);
+union_decorate([T1|Left1], [T2|Left2], Opaques, N, Acc) ->
+ union_decorate(Left1, Left2, Opaques, N+1, [decorate(T1, T2, Opaques)|Acc]);
+union_decorate([], [], _Opaques, N, Acc) ->
+ if N =:= 0 -> ?none;
+ N =:= 1 ->
+ [Type] = [T || T <- Acc, T =/= ?none],
+ Type;
+ N >= 2 -> ?union(lists:reverse(Acc))
+ end.
+
+decorate_tuple_sets(List, L, Opaques) ->
+ decorate_tuple_sets(List, L, Opaques, []).
+
+decorate_tuple_sets([{Arity, Tuples}|List], [{Arity, Ts}|L], Opaques, Acc) ->
+ DecTs = decorate_tuples_in_sets(Tuples, Ts, Opaques),
+ decorate_tuple_sets(List, L, Opaques, [{Arity, DecTs}|Acc]);
+decorate_tuple_sets([ArTup|List], L, Opaques, Acc) ->
+ decorate_tuple_sets(List, L, Opaques, [ArTup|Acc]);
+decorate_tuple_sets([], _L, _Opaques, Acc) ->
+ ?tuple_set(lists:reverse(Acc)).
+
+decorate_tuples_in_sets([?tuple(Elements, _, ?any)], Ts, Opaques) ->
+ NewList = [list_decorate(Elements, Es, Opaques) || ?tuple(Es, _, _) <- Ts],
+ case t_sup([t_tuple(Es) || Es <- NewList]) of
+ ?tuple_set([{_Arity, Tuples}]) -> Tuples;
+ ?tuple(_, _, _)=Tuple -> [Tuple]
+ end;
+decorate_tuples_in_sets(Tuples, Ts, Opaques) ->
+ decorate_tuples_in_sets(Tuples, Ts, Opaques, []).
+
+decorate_tuples_in_sets([?tuple(Elements, Arity, Tag1) = T1|Tuples] = L1,
+ [?tuple(Es, Arity, Tag2)|Ts] = L2, Opaques, Acc) ->
+ if
+ Tag1 < Tag2 -> decorate_tuples_in_sets(Tuples, L2, Opaques, [T1|Acc]);
+ Tag1 > Tag2 -> decorate_tuples_in_sets(L1, Ts, Opaques, Acc);
+ Tag1 =:= Tag2 ->
+ NewElements = list_decorate(Elements, Es, Opaques),
+ NewAcc = [?tuple(NewElements, Arity, Tag1)|Acc],
+ decorate_tuples_in_sets(Tuples, Ts, Opaques, NewAcc)
+ end;
+decorate_tuples_in_sets([T1|Tuples], L2, Opaques, Acc) ->
+ decorate_tuples_in_sets(Tuples, L2, Opaques, [T1|Acc]);
+decorate_tuples_in_sets([], _L, _Opaques, Acc) ->
+ lists:reverse(Acc).
+
+-spec t_opaque_from_records(type_table()) -> [erl_type()].
+
+t_opaque_from_records(RecDict) ->
+ OpaqueRecDict =
+ dict:filter(fun(Key, _Value) ->
+ case Key of
+ {opaque, _Name, _Arity} -> true;
+ _ -> false
+ end
+ end, RecDict),
+ OpaqueTypeDict =
+ dict:map(fun({opaque, Name, _Arity},
+ {{Module, _FileLine, _Form, ArgNames}, _Type}) ->
+ %% Args = args_to_types(ArgNames),
+ %% List = lists:zip(ArgNames, Args),
+ %% TmpVarTab = maps:to_list(List),
+ %% Rep = t_from_form(Type, RecDict, TmpVarTab),
+ Rep = t_any(), % not used for anything right now
+ Args = [t_any() || _ <- ArgNames],
+ t_opaque(Module, Name, Args, Rep)
+ end, OpaqueRecDict),
+ [OpaqueType || {_Key, OpaqueType} <- dict:to_list(OpaqueTypeDict)].
+
+%% Decompose opaque instances of type arg2 to structured types, in arg1
+%% XXX: Same as t_unopaque
+-spec t_struct_from_opaque(erl_type(), [erl_type()]) -> erl_type().
+
+t_struct_from_opaque(?function(Domain, Range), Opaques) ->
+ ?function(t_struct_from_opaque(Domain, Opaques),
+ t_struct_from_opaque(Range, Opaques));
+t_struct_from_opaque(?list(Types, Term, Size), Opaques) ->
+ ?list(t_struct_from_opaque(Types, Opaques),
+ t_struct_from_opaque(Term, Opaques), Size);
+t_struct_from_opaque(?opaque(_) = T, Opaques) ->
+ case is_opaque_type(T, Opaques) of
+ true -> t_opaque_structure(T);
+ false -> T
+ end;
+t_struct_from_opaque(?product(Types), Opaques) ->
+ ?product(list_struct_from_opaque(Types, Opaques));
+t_struct_from_opaque(?tuple(?any, _, _) = T, _Opaques) -> T;
+t_struct_from_opaque(?tuple(Types, Arity, Tag), Opaques) ->
+ ?tuple(list_struct_from_opaque(Types, Opaques), Arity, Tag);
+t_struct_from_opaque(?tuple_set(Set), Opaques) ->
+ NewSet = [{Sz, [t_struct_from_opaque(T, Opaques) || T <- Tuples]}
+ || {Sz, Tuples} <- Set],
+ ?tuple_set(NewSet);
+t_struct_from_opaque(?union(List), Opaques) ->
+ t_sup(list_struct_from_opaque(List, Opaques));
+t_struct_from_opaque(Type, _Opaques) -> Type.
+
+list_struct_from_opaque(Types, Opaques) ->
+ [t_struct_from_opaque(Type, Opaques) || Type <- Types].
+
+%%-----------------------------------------------------------------------------
+
+-type mod_records() :: dict:dict(module(), type_table()).
+
+%%-----------------------------------------------------------------------------
+%% Unit type. Signals non termination.
+%%
+
+-spec t_unit() -> erl_type().
+
+t_unit() ->
+ ?unit.
+
+-spec t_is_unit(erl_type()) -> boolean().
+
+t_is_unit(?unit) -> true;
+t_is_unit(_) -> false.
+
+-spec t_is_none_or_unit(erl_type()) -> boolean().
+
+t_is_none_or_unit(?none) -> true;
+t_is_none_or_unit(?unit) -> true;
+t_is_none_or_unit(_) -> false.
+
+%%-----------------------------------------------------------------------------
+%% Atoms and the derived type boolean
+%%
+
+-spec t_atom() -> erl_type().
+
+t_atom() ->
+ ?atom(?any).
+
+-spec t_atom(atom()) -> erl_type().
+
+t_atom(A) when is_atom(A) ->
+ ?atom(set_singleton(A)).
+
+-spec t_atoms([atom()]) -> erl_type().
+
+t_atoms(List) when is_list(List) ->
+ t_sup([t_atom(A) || A <- List]).
+
+-spec t_atom_vals(erl_type()) -> 'unknown' | [atom(),...].
+
+t_atom_vals(Type) ->
+ t_atom_vals(Type, 'universe').
+
+-spec t_atom_vals(erl_type(), opaques()) -> 'unknown' | [atom(),...].
+
+t_atom_vals(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun atom_vals/1).
+
+atom_vals(?atom(?any)) -> unknown;
+atom_vals(?atom(Set)) -> set_to_list(Set);
+atom_vals(?opaque(_)) -> unknown;
+atom_vals(Other) ->
+ ?atom(_) = Atm = t_inf(t_atom(), Other),
+ atom_vals(Atm).
+
+-spec t_is_atom(erl_type()) -> boolean().
+
+t_is_atom(Type) ->
+ t_is_atom(Type, 'universe').
+
+-spec t_is_atom(erl_type(), opaques()) -> boolean().
+
+t_is_atom(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_atom1/1).
+
+is_atom1(?atom(_)) -> true;
+is_atom1(_) -> false.
+
+-spec t_is_any_atom(atom(), erl_type()) -> boolean().
+
+t_is_any_atom(Atom, SomeAtomsType) ->
+ t_is_any_atom(Atom, SomeAtomsType, 'universe').
+
+-spec t_is_any_atom(atom(), erl_type(), opaques()) -> boolean().
+
+t_is_any_atom(Atom, SomeAtomsType, Opaques) ->
+ do_opaque(SomeAtomsType, Opaques,
+ fun(AtomsType) -> is_any_atom(Atom, AtomsType) end).
+
+is_any_atom(Atom, ?atom(?any)) when is_atom(Atom) -> false;
+is_any_atom(Atom, ?atom(Set)) when is_atom(Atom) ->
+ set_is_singleton(Atom, Set);
+is_any_atom(Atom, _) when is_atom(Atom) -> false.
+
+%%------------------------------------
+
+-spec t_is_boolean(erl_type()) -> boolean().
+
+t_is_boolean(Type) ->
+ t_is_boolean(Type, 'universe').
+
+-spec t_is_boolean(erl_type(), opaques()) -> boolean().
+
+t_is_boolean(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_boolean/1).
+
+-spec t_boolean() -> erl_type().
+
+t_boolean() ->
+ ?atom(set_from_list([false, true])).
+
+is_boolean(?atom(?any)) -> false;
+is_boolean(?atom(Set)) ->
+ case set_size(Set) of
+ 1 -> set_is_element(true, Set) orelse set_is_element(false, Set);
+ 2 -> set_is_element(true, Set) andalso set_is_element(false, Set);
+ N when is_integer(N), N > 2 -> false
+ end;
+is_boolean(_) -> false.
+
+%%-----------------------------------------------------------------------------
+%% Binaries
+%%
+
+-spec t_binary() -> erl_type().
+
+t_binary() ->
+ ?bitstr(8, 0).
+
+-spec t_is_binary(erl_type()) -> boolean().
+
+t_is_binary(Type) ->
+ t_is_binary(Type, 'universe').
+
+-spec t_is_binary(erl_type(), opaques()) -> boolean().
+
+t_is_binary(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_binary/1).
+
+is_binary(?bitstr(U, B)) ->
+ ((U rem 8) =:= 0) andalso ((B rem 8) =:= 0);
+is_binary(_) -> false.
+
+%%-----------------------------------------------------------------------------
+%% Bitstrings
+%%
+
+-spec t_bitstr() -> erl_type().
+
+t_bitstr() ->
+ ?bitstr(1, 0).
+
+-spec t_bitstr(non_neg_integer(), non_neg_integer()) -> erl_type().
+
+t_bitstr(U, B) ->
+ NewB =
+ if
+ U =:= 0 -> B;
+ B >= (U * (?UNIT_MULTIPLIER + 1)) ->
+ (B rem U) + U * ?UNIT_MULTIPLIER;
+ true ->
+ B
+ end,
+ ?bitstr(U, NewB).
+
+-spec t_bitstr_unit(erl_type()) -> non_neg_integer().
+
+t_bitstr_unit(?bitstr(U, _)) -> U.
+
+-spec t_bitstr_base(erl_type()) -> non_neg_integer().
+
+t_bitstr_base(?bitstr(_, B)) -> B.
+
+-spec t_bitstr_concat([erl_type()]) -> erl_type().
+
+t_bitstr_concat(List) ->
+ t_bitstr_concat_1(List, t_bitstr(0, 0)).
+
+t_bitstr_concat_1([T|Left], Acc) ->
+ t_bitstr_concat_1(Left, t_bitstr_concat(Acc, T));
+t_bitstr_concat_1([], Acc) ->
+ Acc.
+
+-spec t_bitstr_concat(erl_type(), erl_type()) -> erl_type().
+
+t_bitstr_concat(T1, T2) ->
+ T1p = t_inf(t_bitstr(), T1),
+ T2p = t_inf(t_bitstr(), T2),
+ bitstr_concat(t_unopaque(T1p), t_unopaque(T2p)).
+
+-spec t_bitstr_match(erl_type(), erl_type()) -> erl_type().
+
+t_bitstr_match(T1, T2) ->
+ T1p = t_inf(t_bitstr(), T1),
+ T2p = t_inf(t_bitstr(), T2),
+ bitstr_match(t_unopaque(T1p), t_unopaque(T2p)).
+
+-spec t_is_bitstr(erl_type()) -> boolean().
+
+t_is_bitstr(Type) ->
+ t_is_bitstr(Type, 'universe').
+
+-spec t_is_bitstr(erl_type(), opaques()) -> boolean().
+
+t_is_bitstr(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_bitstr/1).
+
+is_bitstr(?bitstr(_, _)) -> true;
+is_bitstr(_) -> false.
+
+%%-----------------------------------------------------------------------------
+%% Matchstates
+%%
+
+-spec t_matchstate() -> erl_type().
+
+t_matchstate() ->
+ ?any_matchstate.
+
+-spec t_matchstate(erl_type(), non_neg_integer()) -> erl_type().
+
+t_matchstate(Init, 0) ->
+ ?matchstate(Init, Init);
+t_matchstate(Init, Max) when is_integer(Max) ->
+ Slots = [Init|[?none || _ <- lists:seq(1, Max)]],
+ ?matchstate(Init, t_product(Slots)).
+
+-spec t_is_matchstate(erl_type()) -> boolean().
+
+t_is_matchstate(?matchstate(_, _)) -> true;
+t_is_matchstate(_) -> false.
+
+-spec t_matchstate_present(erl_type()) -> erl_type().
+
+t_matchstate_present(Type) ->
+ case t_inf(t_matchstate(), Type) of
+ ?matchstate(P, _) -> P;
+ _ -> ?none
+ end.
+
+-spec t_matchstate_slot(erl_type(), non_neg_integer()) -> erl_type().
+
+t_matchstate_slot(Type, Slot) ->
+ RealSlot = Slot + 1,
+ case t_inf(t_matchstate(), Type) of
+ ?matchstate(_, ?any) -> ?any;
+ ?matchstate(_, ?product(Vals)) when length(Vals) >= RealSlot ->
+ lists:nth(RealSlot, Vals);
+ ?matchstate(_, ?product(_)) ->
+ ?none;
+ ?matchstate(_, SlotType) when RealSlot =:= 1 ->
+ SlotType;
+ _ ->
+ ?none
+ end.
+
+-spec t_matchstate_slots(erl_type()) -> erl_type().
+
+t_matchstate_slots(?matchstate(_, Slots)) ->
+ Slots.
+
+-spec t_matchstate_update_present(erl_type(), erl_type()) -> erl_type().
+
+t_matchstate_update_present(New, Type) ->
+ case t_inf(t_matchstate(), Type) of
+ ?matchstate(_, Slots) ->
+ ?matchstate(New, Slots);
+ _ -> ?none
+ end.
+
+-spec t_matchstate_update_slot(erl_type(), erl_type(), non_neg_integer()) -> erl_type().
+
+t_matchstate_update_slot(New, Type, Slot) ->
+ RealSlot = Slot + 1,
+ case t_inf(t_matchstate(), Type) of
+ ?matchstate(Pres, Slots) ->
+ NewSlots =
+ case Slots of
+ ?any ->
+ ?any;
+ ?product(Vals) when length(Vals) >= RealSlot ->
+ NewTuple = setelement(RealSlot, list_to_tuple(Vals), New),
+ NewVals = tuple_to_list(NewTuple),
+ ?product(NewVals);
+ ?product(_) ->
+ ?none;
+ _ when RealSlot =:= 1 ->
+ New;
+ _ ->
+ ?none
+ end,
+ ?matchstate(Pres, NewSlots);
+ _ ->
+ ?none
+ end.
+
+%%-----------------------------------------------------------------------------
+%% Functions
+%%
+
+-spec t_fun() -> erl_type().
+
+t_fun() ->
+ ?function(?any, ?any).
+
+-spec t_fun(erl_type()) -> erl_type().
+
+t_fun(Range) ->
+ ?function(?any, Range).
+
+-spec t_fun([erl_type()] | arity(), erl_type()) -> erl_type().
+
+t_fun(Domain, Range) when is_list(Domain) ->
+ ?function(?product(Domain), Range);
+t_fun(Arity, Range) when is_integer(Arity), 0 =< Arity, Arity =< 255 ->
+ ?function(?product(lists:duplicate(Arity, ?any)), Range).
+
+-spec t_fun_args(erl_type()) -> 'unknown' | [erl_type()].
+
+t_fun_args(Type) ->
+ t_fun_args(Type, 'universe').
+
+-spec t_fun_args(erl_type(), opaques()) -> 'unknown' | [erl_type()].
+
+t_fun_args(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun fun_args/1).
+
+fun_args(?function(?any, _)) ->
+ unknown;
+fun_args(?function(?product(Domain), _)) when is_list(Domain) ->
+ Domain.
+
+-spec t_fun_arity(erl_type()) -> 'unknown' | non_neg_integer().
+
+t_fun_arity(Type) ->
+ t_fun_arity(Type, 'universe').
+
+-spec t_fun_arity(erl_type(), opaques()) -> 'unknown' | non_neg_integer().
+
+t_fun_arity(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun fun_arity/1).
+
+fun_arity(?function(?any, _)) ->
+ unknown;
+fun_arity(?function(?product(Domain), _)) ->
+ length(Domain).
+
+-spec t_fun_range(erl_type()) -> erl_type().
+
+t_fun_range(Type) ->
+ t_fun_range(Type, 'universe').
+
+-spec t_fun_range(erl_type(), opaques()) -> erl_type().
+
+t_fun_range(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun fun_range/1).
+
+fun_range(?function(_, Range)) ->
+ Range.
+
+-spec t_is_fun(erl_type()) -> boolean().
+
+t_is_fun(Type) ->
+ t_is_fun(Type, 'universe').
+
+-spec t_is_fun(erl_type(), opaques()) -> boolean().
+
+t_is_fun(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_fun/1).
+
+is_fun(?function(_, _)) -> true;
+is_fun(_) -> false.
+
+%%-----------------------------------------------------------------------------
+%% Identifiers. Includes ports, pids and refs.
+%%
+
+-spec t_identifier() -> erl_type().
+
+t_identifier() ->
+ ?identifier(?any).
+
+-ifdef(DO_ERL_TYPES_TEST).
+-spec t_is_identifier(erl_type()) -> erl_type().
+
+t_is_identifier(?identifier(_)) -> true;
+t_is_identifier(_) -> false.
+-endif.
+
+%%------------------------------------
+
+-spec t_port() -> erl_type().
+
+t_port() ->
+ ?identifier(set_singleton(?port_qual)).
+
+-spec t_is_port(erl_type()) -> boolean().
+
+t_is_port(Type) ->
+ t_is_port(Type, 'universe').
+
+-spec t_is_port(erl_type(), opaques()) -> boolean().
+
+t_is_port(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_port1/1).
+
+is_port1(?identifier(?any)) -> false;
+is_port1(?identifier(Set)) -> set_is_singleton(?port_qual, Set);
+is_port1(_) -> false.
+
+%%------------------------------------
+
+-spec t_pid() -> erl_type().
+
+t_pid() ->
+ ?identifier(set_singleton(?pid_qual)).
+
+-spec t_is_pid(erl_type()) -> boolean().
+
+t_is_pid(Type) ->
+ t_is_pid(Type, 'universe').
+
+-spec t_is_pid(erl_type(), opaques()) -> boolean().
+
+t_is_pid(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_pid1/1).
+
+is_pid1(?identifier(?any)) -> false;
+is_pid1(?identifier(Set)) -> set_is_singleton(?pid_qual, Set);
+is_pid1(_) -> false.
+
+%%------------------------------------
+
+-spec t_reference() -> erl_type().
+
+t_reference() ->
+ ?identifier(set_singleton(?reference_qual)).
+
+-spec t_is_reference(erl_type()) -> boolean().
+
+t_is_reference(Type) ->
+ t_is_reference(Type, 'universe').
+
+-spec t_is_reference(erl_type(), opaques()) -> boolean().
+
+t_is_reference(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_reference1/1).
+
+is_reference1(?identifier(?any)) -> false;
+is_reference1(?identifier(Set)) -> set_is_singleton(?reference_qual, Set);
+is_reference1(_) -> false.
+
+%%-----------------------------------------------------------------------------
+%% Numbers are divided into floats, integers, chars and bytes.
+%%
+
+-spec t_number() -> erl_type().
+
+t_number() ->
+ ?number(?any, ?unknown_qual).
+
+-spec t_number(integer()) -> erl_type().
+
+t_number(X) when is_integer(X) ->
+ t_integer(X).
+
+-spec t_is_number(erl_type()) -> boolean().
+
+t_is_number(Type) ->
+ t_is_number(Type, 'universe').
+
+-spec t_is_number(erl_type(), opaques()) -> boolean().
+
+t_is_number(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_number/1).
+
+is_number(?number(_, _)) -> true;
+is_number(_) -> false.
+
+%% Currently, the type system collapses all floats to ?float and does
+%% not keep any information about their values. As a result, the list
+%% that this function returns contains only integers.
+
+-spec t_number_vals(erl_type()) -> 'unknown' | [integer(),...].
+
+t_number_vals(Type) ->
+ t_number_vals(Type, 'universe').
+
+-spec t_number_vals(erl_type(), opaques()) -> 'unknown' | [integer(),...].
+
+t_number_vals(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun number_vals/1).
+
+number_vals(?int_set(Set)) -> set_to_list(Set);
+number_vals(?number(_, _)) -> unknown;
+number_vals(?opaque(_)) -> unknown;
+number_vals(Other) ->
+ Inf = t_inf(Other, t_number()),
+ false = t_is_none(Inf), % sanity check
+ number_vals(Inf).
+
+%%------------------------------------
+
+-spec t_float() -> erl_type().
+
+t_float() ->
+ ?float.
+
+-spec t_is_float(erl_type()) -> boolean().
+
+t_is_float(Type) ->
+ t_is_float(Type, 'universe').
+
+-spec t_is_float(erl_type(), opaques()) -> boolean().
+
+t_is_float(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_float1/1).
+
+is_float1(?float) -> true;
+is_float1(_) -> false.
+
+%%------------------------------------
+
+-spec t_integer() -> erl_type().
+
+t_integer() ->
+ ?integer(?any).
+
+-spec t_integer(integer()) -> erl_type().
+
+t_integer(I) when is_integer(I) ->
+ ?int_set(set_singleton(I)).
+
+-spec t_integers([integer()]) -> erl_type().
+
+t_integers(List) when is_list(List) ->
+ t_sup([t_integer(I) || I <- List]).
+
+-spec t_is_integer(erl_type()) -> boolean().
+
+t_is_integer(Type) ->
+ t_is_integer(Type, 'universe').
+
+-spec t_is_integer(erl_type(), opaques()) -> boolean().
+
+t_is_integer(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_integer1/1).
+
+is_integer1(?integer(_)) -> true;
+is_integer1(_) -> false.
+
+%%------------------------------------
+
+-spec t_byte() -> erl_type().
+
+t_byte() ->
+ ?byte.
+
+-ifdef(DO_ERL_TYPES_TEST).
+-spec t_is_byte(erl_type()) -> boolean().
+
+t_is_byte(?int_range(neg_inf, _)) -> false;
+t_is_byte(?int_range(_, pos_inf)) -> false;
+t_is_byte(?int_range(From, To))
+ when is_integer(From), From >= 0, is_integer(To), To =< ?MAX_BYTE -> true;
+t_is_byte(?int_set(Set)) ->
+ (set_min(Set) >= 0) andalso (set_max(Set) =< ?MAX_BYTE);
+t_is_byte(_) -> false.
+-endif.
+
+%%------------------------------------
+
+-spec t_char() -> erl_type().
+
+t_char() ->
+ ?char.
+
+-spec t_is_char(erl_type()) -> boolean().
+
+t_is_char(?int_range(neg_inf, _)) -> false;
+t_is_char(?int_range(_, pos_inf)) -> false;
+t_is_char(?int_range(From, To))
+ when is_integer(From), From >= 0, is_integer(To), To =< ?MAX_CHAR -> true;
+t_is_char(?int_set(Set)) ->
+ (set_min(Set) >= 0) andalso (set_max(Set) =< ?MAX_CHAR);
+t_is_char(_) -> false.
+
+%%-----------------------------------------------------------------------------
+%% Lists
+%%
+
+-spec t_cons() -> erl_type().
+
+t_cons() ->
+ ?nonempty_list(?any, ?any).
+
+%% Note that if the tail argument can be a list, we must collapse the
+%% content of the list to include both the content of the tail list
+%% and the head of the cons. If for example the tail argument is any()
+%% then there can be any list in the tail and the content of the
+%% returned list must be any().
+
+-spec t_cons(erl_type(), erl_type()) -> erl_type().
+
+t_cons(?none, _) -> ?none;
+t_cons(_, ?none) -> ?none;
+t_cons(?unit, _) -> ?none;
+t_cons(_, ?unit) -> ?none;
+t_cons(Hd, ?nil) ->
+ ?nonempty_list(Hd, ?nil);
+t_cons(Hd, ?list(Contents, Termination, _)) ->
+ ?nonempty_list(t_sup(Contents, Hd), Termination);
+t_cons(Hd, Tail) ->
+ case cons_tail(t_inf(Tail, t_maybe_improper_list())) of
+ ?list(Contents, Termination, _Size) ->
+ %% Collapse the list part of the termination but keep the
+ %% non-list part intact.
+ NewTermination = t_sup(t_subtract(Tail, t_maybe_improper_list()),
+ Termination),
+ ?nonempty_list(t_sup(Hd, Contents), NewTermination);
+ ?nil -> ?nonempty_list(Hd, Tail);
+ ?none -> ?nonempty_list(Hd, Tail);
+ ?unit -> ?none
+ end.
+
+cons_tail(Type) ->
+ do_opaque(Type, 'universe', fun(T) -> T end).
+
+-spec t_is_cons(erl_type()) -> boolean().
+
+t_is_cons(Type) ->
+ t_is_cons(Type, 'universe').
+
+-spec t_is_cons(erl_type(), opaques()) -> boolean().
+
+t_is_cons(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_cons/1).
+
+is_cons(?nonempty_list(_, _)) -> true;
+is_cons(_) -> false.
+
+-spec t_cons_hd(erl_type()) -> erl_type().
+
+t_cons_hd(Type) ->
+ t_cons_hd(Type, 'universe').
+
+-spec t_cons_hd(erl_type(), opaques()) -> erl_type().
+
+t_cons_hd(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun cons_hd/1).
+
+cons_hd(?nonempty_list(Contents, _Termination)) -> Contents.
+
+-spec t_cons_tl(erl_type()) -> erl_type().
+
+t_cons_tl(Type) ->
+ t_cons_tl(Type, 'universe').
+
+-spec t_cons_tl(erl_type(), opaques()) -> erl_type().
+
+t_cons_tl(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun cons_tl/1).
+
+cons_tl(?nonempty_list(_Contents, Termination) = T) ->
+ t_sup(Termination, T).
+
+-spec t_nil() -> erl_type().
+
+t_nil() ->
+ ?nil.
+
+-spec t_is_nil(erl_type()) -> boolean().
+
+t_is_nil(Type) ->
+ t_is_nil(Type, 'universe').
+
+-spec t_is_nil(erl_type(), opaques()) -> boolean().
+
+t_is_nil(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_nil/1).
+
+is_nil(?nil) -> true;
+is_nil(_) -> false.
+
+-spec t_list() -> erl_type().
+
+t_list() ->
+ ?list(?any, ?nil, ?unknown_qual).
+
+-spec t_list(erl_type()) -> erl_type().
+
+t_list(?none) -> ?none;
+t_list(?unit) -> ?none;
+t_list(Contents) ->
+ ?list(Contents, ?nil, ?unknown_qual).
+
+-spec t_list_elements(erl_type()) -> erl_type().
+
+t_list_elements(Type) ->
+ t_list_elements(Type, 'universe').
+
+-spec t_list_elements(erl_type(), opaques()) -> erl_type().
+
+t_list_elements(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun list_elements/1).
+
+list_elements(?list(Contents, _, _)) -> Contents;
+list_elements(?nil) -> ?none.
+
+-spec t_list_termination(erl_type(), opaques()) -> erl_type().
+
+t_list_termination(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun t_list_termination/1).
+
+-spec t_list_termination(erl_type()) -> erl_type().
+
+t_list_termination(?nil) -> ?nil;
+t_list_termination(?list(_, Term, _)) -> Term.
+
+-spec t_is_list(erl_type()) -> boolean().
+
+t_is_list(?list(_Contents, ?nil, _)) -> true;
+t_is_list(?nil) -> true;
+t_is_list(_) -> false.
+
+-spec t_nonempty_list() -> erl_type().
+
+t_nonempty_list() ->
+ t_cons(?any, ?nil).
+
+-spec t_nonempty_list(erl_type()) -> erl_type().
+
+t_nonempty_list(Type) ->
+ t_cons(Type, ?nil).
+
+-spec t_nonempty_string() -> erl_type().
+
+t_nonempty_string() ->
+ t_nonempty_list(t_char()).
+
+-spec t_string() -> erl_type().
+
+t_string() ->
+ t_list(t_char()).
+
+-spec t_is_string(erl_type()) -> boolean().
+
+t_is_string(X) ->
+ t_is_list(X) andalso t_is_char(t_list_elements(X)).
+
+-spec t_maybe_improper_list() -> erl_type().
+
+t_maybe_improper_list() ->
+ ?list(?any, ?any, ?unknown_qual).
+
+%% Should only be used if you know what you are doing. See t_cons/2
+-spec t_maybe_improper_list(erl_type(), erl_type()) -> erl_type().
+
+t_maybe_improper_list(_Content, ?unit) -> ?none;
+t_maybe_improper_list(?unit, _Termination) -> ?none;
+t_maybe_improper_list(Content, Termination) ->
+ %% Safety check: would be nice to have but does not work with remote types
+ %% true = t_is_subtype(t_nil(), Termination),
+ ?list(Content, Termination, ?unknown_qual).
+
+-spec t_is_maybe_improper_list(erl_type()) -> boolean().
+
+t_is_maybe_improper_list(Type) ->
+ t_is_maybe_improper_list(Type, 'universe').
+
+-spec t_is_maybe_improper_list(erl_type(), opaques()) -> boolean().
+
+t_is_maybe_improper_list(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_maybe_improper_list/1).
+
+is_maybe_improper_list(?list(_, _, _)) -> true;
+is_maybe_improper_list(?nil) -> true;
+is_maybe_improper_list(_) -> false.
+
+%% %% Should only be used if you know what you are doing. See t_cons/2
+%% -spec t_improper_list(erl_type(), erl_type()) -> erl_type().
+%%
+%% t_improper_list(?unit, _Termination) -> ?none;
+%% t_improper_list(_Content, ?unit) -> ?none;
+%% t_improper_list(Content, Termination) ->
+%% %% Safety check: would be nice to have but does not work with remote types
+%% %% false = t_is_subtype(t_nil(), Termination),
+%% ?list(Content, Termination, ?any).
+
+-spec lift_list_to_pos_empty(erl_type(), opaques()) -> erl_type().
+
+lift_list_to_pos_empty(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun lift_list_to_pos_empty/1).
+
+-spec lift_list_to_pos_empty(erl_type()) -> erl_type().
+
+lift_list_to_pos_empty(?nil) -> ?nil;
+lift_list_to_pos_empty(?list(Content, Termination, _)) ->
+ ?list(Content, Termination, ?unknown_qual).
+
+%%-----------------------------------------------------------------------------
+%% Maps
+%%
+%% Representation:
+%% ?map(Pairs, DefaultKey, DefaultValue)
+%%
+%% Pairs is a sorted dictionary of types with a mandatoriness tag on each pair
+%% (t_map_dict()). DefaultKey and DefaultValue are plain types.
+%%
+%% A map M belongs to this type iff
+%% For each pair {KT, mandatory, VT} in Pairs, there exists a pair {K, V} in M
+%% such that K \in KT and V \in VT.
+%% For each pair {KT, optional, VT} in Pairs, either there exists no key K in
+%% M s.t. K in KT, or there exists a pair {K, V} in M such that K \in KT and
+%% V \in VT.
+%% For each remaining pair {K, V} in M (where remaining means that there is no
+%% key KT in Pairs s.t. K \in KT), K \in DefaultKey and V \in DefaultValue.
+%%
+%% Invariants:
+%% * The keys in Pairs are singleton types.
+%% * The values of Pairs must not be unit, and may only be none if the
+%% mandatoriness tag is 'optional'.
+%% * Optional must contain no pair {K,V} s.t. K is a subtype of DefaultKey and
+%% V is equal to DefaultKey.
+%% * DefaultKey must be the empty type iff DefaultValue is the empty type.
+%% * DefaultKey must not be a singleton type.
+%% * For every key K in Pairs, DefaultKey - K must not be representable; i.e.
+%% t_subtract(DefaultKey, K) must return DefaultKey.
+%% * For every pair {K, 'optional', ?none} in Pairs, K must be a subtype of
+%% DefaultKey.
+%% * Pairs must be sorted and not contain any duplicate keys.
+%%
+%% These invariants ensure that equal map types are represented by equal terms.
+
+-define(mand, mandatory).
+-define(opt, optional).
+
+-type t_map_mandatoriness() :: ?mand | ?opt.
+-type t_map_pair() :: {erl_type(), t_map_mandatoriness(), erl_type()}.
+-type t_map_dict() :: [t_map_pair()].
+
+-spec t_map() -> erl_type().
+
+t_map() ->
+ t_map([], t_any(), t_any()).
+
+-spec t_map([{erl_type(), erl_type()}]) -> erl_type().
+
+t_map(L) ->
+ lists:foldl(fun t_map_put/2, t_map(), L).
+
+-spec t_map(t_map_dict(), erl_type(), erl_type()) -> erl_type().
+
+t_map(Pairs0, DefK0, DefV0) ->
+ DefK1 = lists:foldl(fun({K,_,_},Acc)->t_subtract(Acc,K)end, DefK0, Pairs0),
+ {DefK2, DefV1} =
+ case t_is_none_or_unit(DefK1) orelse t_is_none_or_unit(DefV0) of
+ true -> {?none, ?none};
+ false -> {DefK1, DefV0}
+ end,
+ {Pairs1, DefK, DefV}
+ = case is_singleton_type(DefK2) of
+ true -> {mapdict_insert({DefK2, ?opt, DefV1}, Pairs0), ?none, ?none};
+ false -> {Pairs0, DefK2, DefV1}
+ end,
+ Pairs = normalise_map_optionals(Pairs1, DefK, DefV),
+ %% Validate invariants of the map representation.
+ %% Since we needed to iterate over the arguments in order to normalise anyway,
+ %% we might as well save us some future pain and do this even without
+ %% define(DEBUG, true).
+ try
+ validate_map_elements(Pairs)
+ catch error:badarg -> error(badarg, [Pairs0,DefK0,DefV0]);
+ error:{badarg, E} -> error({badarg, E}, [Pairs0,DefK0,DefV0])
+ end,
+ ?map(Pairs, DefK, DefV).
+
+normalise_map_optionals([], _, _) -> [];
+normalise_map_optionals([E={K,?opt,?none}|T], DefK, DefV) ->
+ Diff = t_subtract(DefK, K),
+ case t_is_subtype(K, DefK) andalso DefK =:= Diff of
+ true -> [E|normalise_map_optionals(T, DefK, DefV)];
+ false -> normalise_map_optionals(T, Diff, DefV)
+ end;
+normalise_map_optionals([E={K,?opt,V}|T], DefK, DefV) ->
+ case t_is_equal(V, DefV) andalso t_is_subtype(K, DefK) of
+ true -> normalise_map_optionals(T, DefK, DefV);
+ false -> [E|normalise_map_optionals(T, DefK, DefV)]
+ end;
+normalise_map_optionals([E|T], DefK, DefV) ->
+ [E|normalise_map_optionals(T, DefK, DefV)].
+
+validate_map_elements([{_,?mand,?none}|_]) -> error({badarg, none_in_mand});
+validate_map_elements([{K1,_,_}|Rest=[{K2,_,_}|_]]) ->
+ case is_singleton_type(K1) andalso K1 < K2 of
+ false -> error(badarg);
+ true -> validate_map_elements(Rest)
+ end;
+validate_map_elements([{K,_,_}]) ->
+ case is_singleton_type(K) of
+ false -> error(badarg);
+ true -> true
+ end;
+validate_map_elements([]) -> true.
+
+-spec t_is_map(erl_type()) -> boolean().
+
+t_is_map(Type) ->
+ t_is_map(Type, 'universe').
+
+-spec t_is_map(erl_type(), opaques()) -> boolean().
+
+t_is_map(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_map1/1).
+
+is_map1(?map(_, _, _)) -> true;
+is_map1(_) -> false.
+
+-spec t_map_entries(erl_type()) -> t_map_dict().
+
+t_map_entries(M) ->
+ t_map_entries(M, 'universe').
+
+-spec t_map_entries(erl_type(), opaques()) -> t_map_dict().
+
+t_map_entries(M, Opaques) ->
+ do_opaque(M, Opaques, fun map_entries/1).
+
+map_entries(?map(Pairs,_,_)) ->
+ Pairs.
+
+-spec t_map_def_key(erl_type()) -> erl_type().
+
+t_map_def_key(M) ->
+ t_map_def_key(M, 'universe').
+
+-spec t_map_def_key(erl_type(), opaques()) -> erl_type().
+
+t_map_def_key(M, Opaques) ->
+ do_opaque(M, Opaques, fun map_def_key/1).
+
+map_def_key(?map(_,DefK,_)) ->
+ DefK.
+
+-spec t_map_def_val(erl_type()) -> erl_type().
+
+t_map_def_val(M) ->
+ t_map_def_val(M, 'universe').
+
+-spec t_map_def_val(erl_type(), opaques()) -> erl_type().
+
+t_map_def_val(M, Opaques) ->
+ do_opaque(M, Opaques, fun map_def_val/1).
+
+map_def_val(?map(_,_,DefV)) ->
+ DefV.
+
+-spec mapdict_store(t_map_pair(), t_map_dict()) -> t_map_dict().
+
+mapdict_store(E={K,_,_}, [{K,_,_}|T]) -> [E|T];
+mapdict_store(E1={K1,_,_}, [E2={K2,_,_}|T]) when K1 > K2 ->
+ [E2|mapdict_store(E1, T)];
+mapdict_store(E={_,_,_}, T) -> [E|T].
+
+-spec mapdict_insert(t_map_pair(), t_map_dict()) -> t_map_dict().
+
+mapdict_insert(E={K,_,_}, D=[{K,_,_}|_]) -> error(badarg, [E, D]);
+mapdict_insert(E1={K1,_,_}, [E2={K2,_,_}|T]) when K1 > K2 ->
+ [E2|mapdict_insert(E1, T)];
+mapdict_insert(E={_,_,_}, T) -> [E|T].
+
+%% Merges the pairs of two maps together. Missing pairs become (?opt, DefV) or
+%% (?opt, ?none), depending on whether K \in DefK.
+-spec map_pairwise_merge(fun((erl_type(),
+ t_map_mandatoriness(), erl_type(),
+ t_map_mandatoriness(), erl_type())
+ -> t_map_pair() | false),
+ erl_type(), erl_type()) -> t_map_dict().
+map_pairwise_merge(F, ?map(APairs, ADefK, ADefV),
+ ?map(BPairs, BDefK, BDefV)) ->
+ map_pairwise_merge(F, APairs, ADefK, ADefV, BPairs, BDefK, BDefV).
+
+map_pairwise_merge(_, [], _, _, [], _, _) -> [];
+map_pairwise_merge(F, As0, ADefK, ADefV, Bs0, BDefK, BDefV) ->
+ {K1, AMNess1, AV1, As1, BMNess1, BV1, Bs1} =
+ case {As0, Bs0} of
+ {[{K,AMNess,AV}|As], [{K, BMNess,BV}|Bs]} ->
+ {K, AMNess, AV, As, BMNess, BV, Bs};
+ {[{K,AMNess,AV}|As], [{BK,_, _ }|_]=Bs} when K < BK ->
+ {K, AMNess, AV, As, ?opt, mapmerge_otherv(K, BDefK, BDefV), Bs};
+ {As, [{K, BMNess,BV}|Bs]} ->
+ {K, ?opt, mapmerge_otherv(K, ADefK, ADefV), As, BMNess, BV, Bs};
+ {[{K,AMNess,AV}|As], []=Bs} ->
+ {K, AMNess, AV, As, ?opt, mapmerge_otherv(K, BDefK, BDefV), Bs}
+ end,
+ MK = K1, %% Rename to make clear that we are matching below
+ case F(K1, AMNess1, AV1, BMNess1, BV1) of
+ false -> map_pairwise_merge(F,As1,ADefK,ADefV,Bs1,BDefK,BDefV);
+ {MK,_,_}=M -> [M|map_pairwise_merge(F,As1,ADefK,ADefV,Bs1,BDefK,BDefV)]
+ end.
+
+%% Folds over the pairs in two maps simultaneously in reverse key order. Missing
+%% pairs become (?opt, DefV) or (?opt, ?none), depending on whether K \in DefK.
+-spec map_pairwise_merge_foldr(fun((erl_type(),
+ t_map_mandatoriness(), erl_type(),
+ t_map_mandatoriness(), erl_type(),
+ Acc) -> Acc),
+ Acc, erl_type(), erl_type()) -> Acc.
+
+map_pairwise_merge_foldr(F, AccIn, ?map(APairs, ADefK, ADefV),
+ ?map(BPairs, BDefK, BDefV)) ->
+ map_pairwise_merge_foldr(F, AccIn, APairs, ADefK, ADefV, BPairs, BDefK, BDefV).
+
+map_pairwise_merge_foldr(_, Acc, [], _, _, [], _, _) -> Acc;
+map_pairwise_merge_foldr(F, AccIn, As0, ADefK, ADefV, Bs0, BDefK, BDefV) ->
+ {K1, AMNess1, AV1, As1, BMNess1, BV1, Bs1} =
+ case {As0, Bs0} of
+ {[{K,AMNess,AV}|As], [{K,BMNess,BV}|Bs]} ->
+ {K, AMNess, AV, As, BMNess, BV, Bs};
+ {[{K,AMNess,AV}|As], [{BK,_, _ }|_]=Bs} when K < BK ->
+ {K, AMNess, AV, As, ?opt, mapmerge_otherv(K, BDefK, BDefV), Bs};
+ {As, [{K,BMNess,BV}|Bs]} ->
+ {K, ?opt, mapmerge_otherv(K, ADefK, ADefV), As, BMNess, BV, Bs};
+ {[{K,AMNess,AV}|As], []=Bs} ->
+ {K, AMNess, AV, As, ?opt, mapmerge_otherv(K, BDefK, BDefV), Bs}
+ end,
+ F(K1, AMNess1, AV1, BMNess1, BV1,
+ map_pairwise_merge_foldr(F,AccIn,As1,ADefK,ADefV,Bs1,BDefK,BDefV)).
+
+%% By observing that a missing pair in a map is equivalent to an optional pair,
+%% with ?none or DefV value, depending on whether K \in DefK, we can simplify
+%% merging by denormalising the map pairs temporarily, removing all 'false'
+%% cases, at the cost of the creation of more tuples:
+mapmerge_otherv(K, ODefK, ODefV) ->
+ case t_inf(K, ODefK) of
+ ?none -> ?none;
+ _KOrOpaque -> ODefV
+ end.
+
+-spec t_map_put({erl_type(), erl_type()}, erl_type()) -> erl_type().
+
+t_map_put(KV, Map) ->
+ t_map_put(KV, Map, 'universe').
+
+-spec t_map_put({erl_type(), erl_type()}, erl_type(), opaques()) -> erl_type().
+
+t_map_put(KV, Map, Opaques) ->
+ do_opaque(Map, Opaques, fun(UM) -> map_put(KV, UM, Opaques) end).
+
+%% Key and Value are *not* unopaqued, but the map is
+map_put(_, ?none, _) -> ?none;
+map_put({Key, Value}, ?map(Pairs,DefK,DefV), Opaques) ->
+ case t_is_none_or_unit(Key) orelse t_is_none_or_unit(Value) of
+ true -> ?none;
+ false ->
+ case is_singleton_type(Key) of
+ true ->
+ t_map(mapdict_store({Key, ?mand, Value}, Pairs), DefK, DefV);
+ false ->
+ t_map([{K, MNess, case t_is_none(t_inf(K, Key, Opaques)) of
+ true -> V;
+ false -> t_sup(V, Value)
+ end} || {K, MNess, V} <- Pairs],
+ t_sup(DefK, Key),
+ t_sup(DefV, Value))
+ end
+ end.
+
+-spec t_map_update({erl_type(), erl_type()}, erl_type()) -> erl_type().
+
+t_map_update(KV, Map) ->
+ t_map_update(KV, Map, 'universe').
+
+-spec t_map_update({erl_type(), erl_type()}, erl_type(), opaques()) -> erl_type().
+
+t_map_update(_, ?none, _) -> ?none;
+t_map_update(KV={Key, _}, M, Opaques) ->
+ case t_is_subtype(t_atom('true'), t_map_is_key(Key, M, Opaques)) of
+ false -> ?none;
+ true -> t_map_put(KV, M, Opaques)
+ end.
+
+-spec t_map_get(erl_type(), erl_type()) -> erl_type().
+
+t_map_get(Key, Map) ->
+ t_map_get(Key, Map, 'universe').
+
+-spec t_map_get(erl_type(), erl_type(), opaques()) -> erl_type().
+
+t_map_get(Key, Map, Opaques) ->
+ do_opaque(Map, Opaques,
+ fun(UM) ->
+ do_opaque(Key, Opaques, fun(UK) -> map_get(UK, UM) end)
+ end).
+
+map_get(_, ?none) -> ?none;
+map_get(Key, ?map(Pairs, DefK, DefV)) ->
+ DefRes =
+ case t_do_overlap(DefK, Key) of
+ false -> t_none();
+ true -> DefV
+ end,
+ case is_singleton_type(Key) of
+ false ->
+ lists:foldl(fun({K, _, V}, Res) ->
+ case t_do_overlap(K, Key) of
+ false -> Res;
+ true -> t_sup(Res, V)
+ end
+ end, DefRes, Pairs);
+ true ->
+ case lists:keyfind(Key, 1, Pairs) of
+ false -> DefRes;
+ {_, _, ValType} -> ValType
+ end
+ end.
+
+-spec t_map_is_key(erl_type(), erl_type()) -> erl_type().
+
+t_map_is_key(Key, Map) ->
+ t_map_is_key(Key, Map, 'universe').
+
+-spec t_map_is_key(erl_type(), erl_type(), opaques()) -> erl_type().
+
+t_map_is_key(Key, Map, Opaques) ->
+ do_opaque(Map, Opaques,
+ fun(UM) ->
+ do_opaque(Key, Opaques, fun(UK) -> map_is_key(UK, UM) end)
+ end).
+
+map_is_key(_, ?none) -> ?none;
+map_is_key(Key, ?map(Pairs, DefK, _DefV)) ->
+ case is_singleton_type(Key) of
+ true ->
+ case lists:keyfind(Key, 1, Pairs) of
+ {Key, ?mand, _} -> t_atom(true);
+ {Key, ?opt, ?none} -> t_atom(false);
+ {Key, ?opt, _} -> t_boolean();
+ false ->
+ case t_do_overlap(DefK, Key) of
+ false -> t_atom(false);
+ true -> t_boolean()
+ end
+ end;
+ false ->
+ case t_do_overlap(DefK, Key)
+ orelse lists:any(fun({_,_,?none}) -> false;
+ ({K,_,_}) -> t_do_overlap(K, Key)
+ end, Pairs)
+ of
+ true -> t_boolean();
+ false -> t_atom(false)
+ end
+ end.
+
+%%-----------------------------------------------------------------------------
+%% Tuples
+%%
+
+-spec t_tuple() -> erl_type().
+
+t_tuple() ->
+ ?tuple(?any, ?any, ?any).
+
+-spec t_tuple(non_neg_integer() | [erl_type()]) -> erl_type().
+
+t_tuple(N) when is_integer(N), N > ?MAX_TUPLE_SIZE ->
+ t_tuple();
+t_tuple(N) when is_integer(N) ->
+ ?tuple(lists:duplicate(N, ?any), N, ?any);
+t_tuple(List) ->
+ case any_none_or_unit(List) of
+ true -> t_none();
+ false ->
+ Arity = length(List),
+ case get_tuple_tags(List) of
+ [Tag] -> ?tuple(List, Arity, Tag); %% Tag can also be ?any here
+ TagList ->
+ SortedTagList = lists:sort(TagList),
+ Tuples = [?tuple([T|tl(List)], Arity, T) || T <- SortedTagList],
+ ?tuple_set([{Arity, Tuples}])
+ end
+ end.
+
+-spec get_tuple_tags([erl_type()]) -> [erl_type(),...].
+
+get_tuple_tags([Tag|_]) ->
+ do_opaque(Tag, 'universe', fun tuple_tags/1);
+get_tuple_tags(_) -> [?any].
+
+tuple_tags(?atom(?any)) -> [?any];
+tuple_tags(?atom(Set)) ->
+ case set_size(Set) > ?TUPLE_TAG_LIMIT of
+ true -> [?any];
+ false -> [t_atom(A) || A <- set_to_list(Set)]
+ end;
+tuple_tags(_) -> [?any].
+
+%% to be used for a tuple with known types for its arguments (not ?any)
+-spec t_tuple_args(erl_type()) -> [erl_type()].
+
+t_tuple_args(Type) ->
+ t_tuple_args(Type, 'universe').
+
+%% to be used for a tuple with known types for its arguments (not ?any)
+-spec t_tuple_args(erl_type(), opaques()) -> [erl_type()].
+
+t_tuple_args(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun tuple_args/1).
+
+tuple_args(?tuple(Args, _, _)) when is_list(Args) -> Args.
+
+%% to be used for a tuple with a known size (not ?any)
+-spec t_tuple_size(erl_type()) -> non_neg_integer().
+
+t_tuple_size(Type) ->
+ t_tuple_size(Type, 'universe').
+
+%% to be used for a tuple with a known size (not ?any)
+-spec t_tuple_size(erl_type(), opaques()) -> non_neg_integer().
+
+t_tuple_size(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun tuple_size1/1).
+
+tuple_size1(?tuple(_, Size, _)) when is_integer(Size) -> Size.
+
+-spec t_tuple_sizes(erl_type()) -> 'unknown' | [non_neg_integer(),...].
+
+t_tuple_sizes(Type) ->
+ do_opaque(Type, 'universe', fun tuple_sizes/1).
+
+tuple_sizes(?tuple(?any, ?any, ?any)) -> unknown;
+tuple_sizes(?tuple(_, Size, _)) when is_integer(Size) -> [Size];
+tuple_sizes(?tuple_set(List)) -> [Size || {Size, _} <- List].
+
+-spec t_tuple_subtypes(erl_type(), opaques()) ->
+ 'unknown' | [erl_type(),...].
+
+t_tuple_subtypes(Type, Opaques) ->
+ Fun = fun(?tuple_set(List)) ->
+ t_tuple_subtypes_tuple_list(List, Opaques);
+ (?opaque(_)) -> unknown;
+ (T) -> t_tuple_subtypes(T)
+ end,
+ do_opaque(Type, Opaques, Fun).
+
+t_tuple_subtypes_tuple_list(List, Opaques) ->
+ lists:append([t_tuple_subtypes_list(Tuples, Opaques) ||
+ {_Size, Tuples} <- List]).
+
+t_tuple_subtypes_list(List, Opaques) ->
+ ListOfLists = [t_tuple_subtypes(E, Opaques) || E <- List, E =/= ?none],
+ lists:append([L || L <- ListOfLists, L =/= 'unknown']).
+
+-spec t_tuple_subtypes(erl_type()) -> 'unknown' | [erl_type(),...].
+
+%% XXX. Not the same as t_tuple_subtypes(T, 'universe')...
+t_tuple_subtypes(?tuple(?any, ?any, ?any)) -> unknown;
+t_tuple_subtypes(?tuple(_, _, _) = T) -> [T];
+t_tuple_subtypes(?tuple_set(List)) ->
+ lists:append([Tuples || {_Size, Tuples} <- List]).
+
+-spec t_is_tuple(erl_type()) -> boolean().
+
+t_is_tuple(Type) ->
+ t_is_tuple(Type, 'universe').
+
+-spec t_is_tuple(erl_type(), opaques()) -> boolean().
+
+t_is_tuple(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_tuple1/1).
+
+is_tuple1(?tuple(_, _, _)) -> true;
+is_tuple1(?tuple_set(_)) -> true;
+is_tuple1(_) -> false.
+
+%%-----------------------------------------------------------------------------
+%% Non-primitive types, including some handy syntactic sugar types
+%%
+
+-spec t_bitstrlist() -> erl_type().
+
+t_bitstrlist() ->
+ t_iolist(1, t_bitstr()).
+
+-spec t_arity() -> erl_type().
+
+t_arity() ->
+ t_from_range(0, 255). % was t_byte().
+
+-spec t_pos_integer() -> erl_type().
+
+t_pos_integer() ->
+ t_from_range(1, pos_inf).
+
+-spec t_non_neg_integer() -> erl_type().
+
+t_non_neg_integer() ->
+ t_from_range(0, pos_inf).
+
+-spec t_is_non_neg_integer(erl_type()) -> boolean().
+
+t_is_non_neg_integer(?integer(_) = T) ->
+ t_is_subtype(T, t_non_neg_integer());
+t_is_non_neg_integer(_) -> false.
+
+-spec t_neg_integer() -> erl_type().
+
+t_neg_integer() ->
+ t_from_range(neg_inf, -1).
+
+-spec t_fixnum() -> erl_type().
+
+t_fixnum() ->
+ t_integer(). % Gross over-approximation
+
+-spec t_pos_fixnum() -> erl_type().
+
+t_pos_fixnum() ->
+ t_pos_integer(). % Gross over-approximation
+
+-spec t_non_neg_fixnum() -> erl_type().
+
+t_non_neg_fixnum() ->
+ t_non_neg_integer(). % Gross over-approximation
+
+-spec t_mfa() -> erl_type().
+
+t_mfa() ->
+ t_tuple([t_atom(), t_atom(), t_arity()]).
+
+-spec t_module() -> erl_type().
+
+t_module() ->
+ t_atom().
+
+-spec t_node() -> erl_type().
+
+t_node() ->
+ t_atom().
+
+-spec t_iodata() -> erl_type().
+
+t_iodata() ->
+ t_sup(t_iolist(), t_binary()).
+
+-spec t_iolist() -> erl_type().
+
+t_iolist() ->
+ t_iolist(1, t_binary()).
+
+%% Added a second argument which currently is t_binary() | t_bitstr()
+-spec t_iolist(non_neg_integer(), erl_type()) -> erl_type().
+
+t_iolist(N, T) when N > 0 ->
+ t_maybe_improper_list(t_sup([t_iolist(N-1, T), T, t_byte()]),
+ t_sup(T, t_nil()));
+t_iolist(0, T) ->
+ t_maybe_improper_list(t_any(), t_sup(T, t_nil())).
+
+-spec t_timeout() -> erl_type().
+
+t_timeout() ->
+ t_sup(t_non_neg_integer(), t_atom('infinity')).
+
+%%------------------------------------
+
+%% ?none is allowed in products. A product of size 1 is not a product.
+
+-spec t_product([erl_type()]) -> erl_type().
+
+t_product([T]) -> T;
+t_product(Types) when is_list(Types) ->
+ ?product(Types).
+
+%% This function is intended to be the inverse of the one above.
+%% It should NOT be used with ?any, ?none or ?unit as input argument.
+
+-spec t_to_tlist(erl_type()) -> [erl_type()].
+
+t_to_tlist(?product(Types)) -> Types;
+t_to_tlist(T) when T =/= ?any orelse T =/= ?none orelse T =/= ?unit -> [T].
+
+%%------------------------------------
+
+-spec t_var(atom() | integer()) -> erl_type().
+
+t_var(Atom) when is_atom(Atom) -> ?var(Atom);
+t_var(Int) when is_integer(Int) -> ?var(Int).
+
+-spec t_is_var(erl_type()) -> boolean().
+
+t_is_var(?var(_)) -> true;
+t_is_var(_) -> false.
+
+-spec t_var_name(erl_type()) -> atom() | integer().
+
+t_var_name(?var(Id)) -> Id.
+
+-spec t_has_var(erl_type()) -> boolean().
+
+t_has_var(?var(_)) -> true;
+t_has_var(?function(Domain, Range)) ->
+ t_has_var(Domain) orelse t_has_var(Range);
+t_has_var(?list(Contents, Termination, _)) ->
+ t_has_var(Contents) orelse t_has_var(Termination);
+t_has_var(?product(Types)) -> t_has_var_list(Types);
+t_has_var(?tuple(?any, ?any, ?any)) -> false;
+t_has_var(?tuple(Elements, _, _)) ->
+ t_has_var_list(Elements);
+t_has_var(?tuple_set(_) = T) ->
+ t_has_var_list(t_tuple_subtypes(T));
+t_has_var(?map(_, DefK, _)= Map) ->
+ t_has_var_list(map_all_values(Map)) orelse
+ t_has_var(DefK);
+t_has_var(?opaque(Set)) ->
+ %% Assume variables in 'args' are also present i 'struct'
+ t_has_var_list([O#opaque.struct || O <- set_to_list(Set)]);
+t_has_var(?union(List)) ->
+ t_has_var_list(List);
+t_has_var(_) -> false.
+
+-spec t_has_var_list([erl_type()]) -> boolean().
+
+t_has_var_list([T|Ts]) ->
+ t_has_var(T) orelse t_has_var_list(Ts);
+t_has_var_list([]) -> false.
+
+-spec t_collect_vars(erl_type()) -> [erl_type()].
+
+t_collect_vars(T) ->
+ t_collect_vars(T, []).
+
+-spec t_collect_vars(erl_type(), [erl_type()]) -> [erl_type()].
+
+t_collect_vars(?var(_) = Var, Acc) ->
+ ordsets:add_element(Var, Acc);
+t_collect_vars(?function(Domain, Range), Acc) ->
+ ordsets:union(t_collect_vars(Domain, Acc), t_collect_vars(Range, []));
+t_collect_vars(?list(Contents, Termination, _), Acc) ->
+ ordsets:union(t_collect_vars(Contents, Acc), t_collect_vars(Termination, []));
+t_collect_vars(?product(Types), Acc) ->
+ t_collect_vars_list(Types, Acc);
+t_collect_vars(?tuple(?any, ?any, ?any), Acc) ->
+ Acc;
+t_collect_vars(?tuple(Types, _, _), Acc) ->
+ t_collect_vars_list(Types, Acc);
+t_collect_vars(?tuple_set(_) = TS, Acc) ->
+ t_collect_vars_list(t_tuple_subtypes(TS), Acc);
+t_collect_vars(?map(_, DefK, _) = Map, Acc0) ->
+ Acc = t_collect_vars_list(map_all_values(Map), Acc0),
+ t_collect_vars(DefK, Acc);
+t_collect_vars(?opaque(Set), Acc) ->
+ %% Assume variables in 'args' are also present i 'struct'
+ t_collect_vars_list([O#opaque.struct || O <- set_to_list(Set)], Acc);
+t_collect_vars(?union(List), Acc) ->
+ t_collect_vars_list(List, Acc);
+t_collect_vars(_, Acc) ->
+ Acc.
+
+t_collect_vars_list([T|Ts], Acc0) ->
+ Acc = t_collect_vars(T, Acc0),
+ t_collect_vars_list(Ts, Acc);
+t_collect_vars_list([], Acc) -> Acc.
+
+%%=============================================================================
+%%
+%% Type construction from Erlang terms.
+%%
+%%=============================================================================
+
+%%-----------------------------------------------------------------------------
+%% Make a type from a term. No type depth is enforced.
+%%
+
+-spec t_from_term(term()) -> erl_type().
+
+t_from_term([H|T]) -> t_cons(t_from_term(H), t_from_term(T));
+t_from_term([]) -> t_nil();
+t_from_term(T) when is_atom(T) -> t_atom(T);
+t_from_term(T) when is_bitstring(T) -> t_bitstr(0, erlang:bit_size(T));
+t_from_term(T) when is_float(T) -> t_float();
+t_from_term(T) when is_function(T) ->
+ {arity, Arity} = erlang:fun_info(T, arity),
+ t_fun(Arity, t_any());
+t_from_term(T) when is_integer(T) -> t_integer(T);
+t_from_term(T) when is_map(T) ->
+ Pairs = [{t_from_term(K), ?mand, t_from_term(V)}
+ || {K, V} <- maps:to_list(T)],
+ {Stons, Rest} = lists:partition(fun({K,_,_}) -> is_singleton_type(K) end,
+ Pairs),
+ {DefK, DefV}
+ = lists:foldl(fun({K,_,V},{AK,AV}) -> {t_sup(K,AK), t_sup(V,AV)} end,
+ {t_none(), t_none()}, Rest),
+ t_map(lists:keysort(1, Stons), DefK, DefV);
+t_from_term(T) when is_pid(T) -> t_pid();
+t_from_term(T) when is_port(T) -> t_port();
+t_from_term(T) when is_reference(T) -> t_reference();
+t_from_term(T) when is_tuple(T) ->
+ t_tuple([t_from_term(E) || E <- tuple_to_list(T)]).
+
+%%-----------------------------------------------------------------------------
+%% Integer types from a range.
+%%-----------------------------------------------------------------------------
+
+%%-define(USE_UNSAFE_RANGES, true).
+
+-spec t_from_range(rng_elem(), rng_elem()) -> erl_type().
+
+-ifdef(USE_UNSAFE_RANGES).
+
+t_from_range(X, Y) ->
+ t_from_range_unsafe(X, Y).
+
+-else.
+
+t_from_range(neg_inf, pos_inf) -> t_integer();
+t_from_range(neg_inf, Y) when is_integer(Y), Y < 0 -> ?integer_neg;
+t_from_range(neg_inf, Y) when is_integer(Y), Y >= 0 -> t_integer();
+t_from_range(X, pos_inf) when is_integer(X), X >= 1 -> ?integer_pos;
+t_from_range(X, pos_inf) when is_integer(X), X >= 0 -> ?integer_non_neg;
+t_from_range(X, pos_inf) when is_integer(X), X < 0 -> t_integer();
+t_from_range(X, Y) when is_integer(X), is_integer(Y), X > Y -> t_none();
+t_from_range(X, Y) when is_integer(X), is_integer(Y) ->
+ case ((Y - X) < ?SET_LIMIT) of
+ true -> t_integers(lists:seq(X, Y));
+ false ->
+ case X >= 0 of
+ false ->
+ if Y < 0 -> ?integer_neg;
+ true -> t_integer()
+ end;
+ true ->
+ if Y =< ?MAX_BYTE, X >= 1 -> ?int_range(1, ?MAX_BYTE);
+ Y =< ?MAX_BYTE -> t_byte();
+ Y =< ?MAX_CHAR, X >= 1 -> ?int_range(1, ?MAX_CHAR);
+ Y =< ?MAX_CHAR -> t_char();
+ X >= 1 -> ?integer_pos;
+ X >= 0 -> ?integer_non_neg
+ end
+ end
+ end;
+t_from_range(pos_inf, neg_inf) -> t_none().
+
+-endif.
+
+-spec t_from_range_unsafe(rng_elem(), rng_elem()) -> erl_type().
+
+t_from_range_unsafe(neg_inf, pos_inf) -> t_integer();
+t_from_range_unsafe(neg_inf, Y) -> ?int_range(neg_inf, Y);
+t_from_range_unsafe(X, pos_inf) -> ?int_range(X, pos_inf);
+t_from_range_unsafe(X, Y) when is_integer(X), is_integer(Y), X =< Y ->
+ if (Y - X) < ?SET_LIMIT -> t_integers(lists:seq(X, Y));
+ true -> ?int_range(X, Y)
+ end;
+t_from_range_unsafe(X, Y) when is_integer(X), is_integer(Y) -> t_none();
+t_from_range_unsafe(pos_inf, neg_inf) -> t_none().
+
+-spec t_is_fixnum(erl_type()) -> boolean().
+
+t_is_fixnum(?int_range(neg_inf, _)) -> false;
+t_is_fixnum(?int_range(_, pos_inf)) -> false;
+t_is_fixnum(?int_range(From, To)) ->
+ is_fixnum(From) andalso is_fixnum(To);
+t_is_fixnum(?int_set(Set)) ->
+ is_fixnum(set_min(Set)) andalso is_fixnum(set_max(Set));
+t_is_fixnum(_) -> false.
+
+-spec is_fixnum(integer()) -> boolean().
+
+is_fixnum(N) when is_integer(N) ->
+ Bits = ?BITS,
+ (N =< ((1 bsl (Bits - 1)) - 1)) andalso (N >= -(1 bsl (Bits - 1))).
+
+infinity_geq(pos_inf, _) -> true;
+infinity_geq(_, pos_inf) -> false;
+infinity_geq(_, neg_inf) -> true;
+infinity_geq(neg_inf, _) -> false;
+infinity_geq(A, B) -> A >= B.
+
+-spec t_is_bitwidth(erl_type()) -> boolean().
+
+t_is_bitwidth(?int_range(neg_inf, _)) -> false;
+t_is_bitwidth(?int_range(_, pos_inf)) -> false;
+t_is_bitwidth(?int_range(From, To)) ->
+ infinity_geq(From, 0) andalso infinity_geq(?BITS, To);
+t_is_bitwidth(?int_set(Set)) ->
+ infinity_geq(set_min(Set), 0) andalso infinity_geq(?BITS, set_max(Set));
+t_is_bitwidth(_) -> false.
+
+-spec number_min(erl_type()) -> rng_elem().
+
+number_min(Type) ->
+ number_min(Type, 'universe').
+
+-spec number_min(erl_type(), opaques()) -> rng_elem().
+
+number_min(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun number_min2/1).
+
+number_min2(?int_range(From, _)) -> From;
+number_min2(?int_set(Set)) -> set_min(Set);
+number_min2(?number(?any, _Tag)) -> neg_inf.
+
+-spec number_max(erl_type()) -> rng_elem().
+
+number_max(Type) ->
+ number_max(Type, 'universe').
+
+-spec number_max(erl_type(), opaques()) -> rng_elem().
+
+number_max(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun number_max2/1).
+
+number_max2(?int_range(_, To)) -> To;
+number_max2(?int_set(Set)) -> set_max(Set);
+number_max2(?number(?any, _Tag)) -> pos_inf.
+
+%% -spec int_range(rgn_elem(), rng_elem()) -> erl_type().
+%%
+%% int_range(neg_inf, pos_inf) -> t_integer();
+%% int_range(neg_inf, To) -> ?int_range(neg_inf, To);
+%% int_range(From, pos_inf) -> ?int_range(From, pos_inf);
+%% int_range(From, To) when From =< To -> t_from_range(From, To);
+%% int_range(From, To) when To < From -> ?none.
+
+in_range(_, ?int_range(neg_inf, pos_inf)) -> true;
+in_range(X, ?int_range(From, pos_inf)) -> X >= From;
+in_range(X, ?int_range(neg_inf, To)) -> X =< To;
+in_range(X, ?int_range(From, To)) -> (X >= From) andalso (X =< To).
+
+-spec min(rng_elem(), rng_elem()) -> rng_elem().
+
+min(neg_inf, _) -> neg_inf;
+min(_, neg_inf) -> neg_inf;
+min(pos_inf, Y) -> Y;
+min(X, pos_inf) -> X;
+min(X, Y) when X =< Y -> X;
+min(_, Y) -> Y.
+
+-spec max(rng_elem(), rng_elem()) -> rng_elem().
+
+max(neg_inf, Y) -> Y;
+max(X, neg_inf) -> X;
+max(pos_inf, _) -> pos_inf;
+max(_, pos_inf) -> pos_inf;
+max(X, Y) when X =< Y -> Y;
+max(X, _) -> X.
+
+expand_range_from_set(Range = ?int_range(From, To), Set) ->
+ Min = min(set_min(Set), From),
+ Max = max(set_max(Set), To),
+ if From =:= Min, To =:= Max -> Range;
+ true -> t_from_range(Min, Max)
+ end.
+
+%%=============================================================================
+%%
+%% Lattice operations
+%%
+%%=============================================================================
+
+%%-----------------------------------------------------------------------------
+%% Supremum
+%%
+
+-spec t_sup([erl_type()]) -> erl_type().
+
+t_sup([]) -> ?none;
+t_sup(Ts) ->
+ case lists:any(fun is_any/1, Ts) of
+ true -> ?any;
+ false ->
+ t_sup1(Ts, [])
+ end.
+
+t_sup1([H1, H2|T], L) ->
+ t_sup1(T, [t_sup(H1, H2)|L]);
+t_sup1([T], []) -> subst_all_vars_to_any(T);
+t_sup1(Ts, L) ->
+ t_sup1(Ts++L, []).
+
+-spec t_sup(erl_type(), erl_type()) -> erl_type().
+
+t_sup(?any, _) -> ?any;
+t_sup(_, ?any) -> ?any;
+t_sup(?none, T) -> T;
+t_sup(T, ?none) -> T;
+t_sup(?unit, T) -> T;
+t_sup(T, ?unit) -> T;
+t_sup(T, T) -> subst_all_vars_to_any(T);
+t_sup(?var(_), _) -> ?any;
+t_sup(_, ?var(_)) -> ?any;
+t_sup(?atom(Set1), ?atom(Set2)) ->
+ ?atom(set_union(Set1, Set2));
+t_sup(?bitstr(U1, B1), ?bitstr(U2, B2)) ->
+ t_bitstr(gcd(gcd(U1, U2), abs(B1-B2)), lists:min([B1, B2]));
+t_sup(?function(Domain1, Range1), ?function(Domain2, Range2)) ->
+ %% The domain is either a product or any.
+ ?function(t_sup(Domain1, Domain2), t_sup(Range1, Range2));
+t_sup(?identifier(Set1), ?identifier(Set2)) ->
+ ?identifier(set_union(Set1, Set2));
+t_sup(?opaque(Set1), ?opaque(Set2)) ->
+ sup_opaque(set_to_list(ordsets:union(Set1, Set2)));
+%%Disallow unions with opaque types
+%%t_sup(T1=?opaque(_,_,_), T2) ->
+%% io:format("Debug: t_sup executed with args ~w and ~w~n",[T1, T2]), ?none;
+%%t_sup(T1, T2=?opaque(_,_,_)) ->
+%% io:format("Debug: t_sup executed with args ~w and ~w~n",[T1, T2]), ?none;
+t_sup(?matchstate(Pres1, Slots1), ?matchstate(Pres2, Slots2)) ->
+ ?matchstate(t_sup(Pres1, Pres2), t_sup(Slots1, Slots2));
+t_sup(?nil, ?nil) -> ?nil;
+t_sup(?nil, ?list(Contents, Termination, _)) ->
+ ?list(Contents, t_sup(?nil, Termination), ?unknown_qual);
+t_sup(?list(Contents, Termination, _), ?nil) ->
+ ?list(Contents, t_sup(?nil, Termination), ?unknown_qual);
+t_sup(?list(Contents1, Termination1, Size1),
+ ?list(Contents2, Termination2, Size2)) ->
+ NewSize =
+ case {Size1, Size2} of
+ {?unknown_qual, ?unknown_qual} -> ?unknown_qual;
+ {?unknown_qual, ?nonempty_qual} -> ?unknown_qual;
+ {?nonempty_qual, ?unknown_qual} -> ?unknown_qual;
+ {?nonempty_qual, ?nonempty_qual} -> ?nonempty_qual
+ end,
+ NewContents = t_sup(Contents1, Contents2),
+ NewTermination = t_sup(Termination1, Termination2),
+ TmpList = t_cons(NewContents, NewTermination),
+ case NewSize of
+ ?nonempty_qual -> TmpList;
+ ?unknown_qual ->
+ ?list(FinalContents, FinalTermination, _) = TmpList,
+ ?list(FinalContents, FinalTermination, ?unknown_qual)
+ end;
+t_sup(?number(_, _), ?number(?any, ?unknown_qual) = T) -> T;
+t_sup(?number(?any, ?unknown_qual) = T, ?number(_, _)) -> T;
+t_sup(?float, ?float) -> ?float;
+t_sup(?float, ?integer(_)) -> t_number();
+t_sup(?integer(_), ?float) -> t_number();
+t_sup(?integer(?any) = T, ?integer(_)) -> T;
+t_sup(?integer(_), ?integer(?any) = T) -> T;
+t_sup(?int_set(Set1), ?int_set(Set2)) ->
+ case set_union(Set1, Set2) of
+ ?any ->
+ t_from_range(min(set_min(Set1), set_min(Set2)),
+ max(set_max(Set1), set_max(Set2)));
+ Set -> ?int_set(Set)
+ end;
+t_sup(?int_range(From1, To1), ?int_range(From2, To2)) ->
+ t_from_range(min(From1, From2), max(To1, To2));
+t_sup(Range = ?int_range(_, _), ?int_set(Set)) ->
+ expand_range_from_set(Range, Set);
+t_sup(?int_set(Set), Range = ?int_range(_, _)) ->
+ expand_range_from_set(Range, Set);
+t_sup(?product(Types1), ?product(Types2)) ->
+ L1 = length(Types1),
+ L2 = length(Types2),
+ if L1 =:= L2 -> ?product(t_sup_lists(Types1, Types2));
+ true -> ?any
+ end;
+t_sup(?product(_), _) ->
+ ?any;
+t_sup(_, ?product(_)) ->
+ ?any;
+t_sup(?tuple(?any, ?any, ?any) = T, ?tuple(_, _, _)) -> T;
+t_sup(?tuple(_, _, _), ?tuple(?any, ?any, ?any) = T) -> T;
+t_sup(?tuple(?any, ?any, ?any) = T, ?tuple_set(_)) -> T;
+t_sup(?tuple_set(_), ?tuple(?any, ?any, ?any) = T) -> T;
+t_sup(?tuple(Elements1, Arity, Tag1) = T1,
+ ?tuple(Elements2, Arity, Tag2) = T2) ->
+ if Tag1 =:= Tag2 -> t_tuple(t_sup_lists(Elements1, Elements2));
+ Tag1 =:= ?any -> t_tuple(t_sup_lists(Elements1, Elements2));
+ Tag2 =:= ?any -> t_tuple(t_sup_lists(Elements1, Elements2));
+ Tag1 < Tag2 -> ?tuple_set([{Arity, [T1, T2]}]);
+ Tag1 > Tag2 -> ?tuple_set([{Arity, [T2, T1]}])
+ end;
+t_sup(?tuple(_, Arity1, _) = T1, ?tuple(_, Arity2, _) = T2) ->
+ sup_tuple_sets([{Arity1, [T1]}], [{Arity2, [T2]}]);
+t_sup(?tuple_set(List1), ?tuple_set(List2)) ->
+ sup_tuple_sets(List1, List2);
+t_sup(?tuple_set(List1), T2 = ?tuple(_, Arity, _)) ->
+ sup_tuple_sets(List1, [{Arity, [T2]}]);
+t_sup(?tuple(_, Arity, _) = T1, ?tuple_set(List2)) ->
+ sup_tuple_sets([{Arity, [T1]}], List2);
+t_sup(?map(_, ADefK, ADefV) = A, ?map(_, BDefK, BDefV) = B) ->
+ Pairs =
+ map_pairwise_merge(
+ fun(K, MNess, V1, MNess, V2) -> {K, MNess, t_sup(V1, V2)};
+ (K, _, V1, _, V2) -> {K, ?opt, t_sup(V1, V2)}
+ end, A, B),
+ t_map(Pairs, t_sup(ADefK, BDefK), t_sup(ADefV, BDefV));
+t_sup(T1, T2) ->
+ ?union(U1) = force_union(T1),
+ ?union(U2) = force_union(T2),
+ sup_union(U1, U2).
+
+sup_opaque([]) -> ?none;
+sup_opaque(List) ->
+ L = sup_opaq(List),
+ ?opaque(ordsets:from_list(L)).
+
+sup_opaq(L0) ->
+ L1 = [{{Mod,Name,Args}, T} ||
+ #opaque{mod = Mod, name = Name, args = Args}=T <- L0],
+ F = family(L1),
+ [supl(Ts) || {_, Ts} <- F].
+
+supl([O]) -> O;
+supl(Ts) -> supl(Ts, t_none()).
+
+supl([#opaque{struct = S}=O|L], S0) ->
+ S1 = t_sup(S, S0),
+ case L =:= [] of
+ true -> O#opaque{struct = S1};
+ false -> supl(L, S1)
+ end.
+
+-spec t_sup_lists([erl_type()], [erl_type()]) -> [erl_type()].
+
+t_sup_lists([T1|Left1], [T2|Left2]) ->
+ [t_sup(T1, T2)|t_sup_lists(Left1, Left2)];
+t_sup_lists([], []) ->
+ [].
+
+sup_tuple_sets(L1, L2) ->
+ TotalArities = ordsets:union([Arity || {Arity, _} <- L1],
+ [Arity || {Arity, _} <- L2]),
+ if length(TotalArities) > ?TUPLE_ARITY_LIMIT -> t_tuple();
+ true ->
+ case sup_tuple_sets(L1, L2, []) of
+ [{_Arity, [OneTuple = ?tuple(_, _, _)]}] -> OneTuple;
+ List -> ?tuple_set(List)
+ end
+ end.
+
+sup_tuple_sets([{Arity, Tuples1}|Left1], [{Arity, Tuples2}|Left2], Acc) ->
+ NewAcc = [{Arity, sup_tuples_in_set(Tuples1, Tuples2)}|Acc],
+ sup_tuple_sets(Left1, Left2, NewAcc);
+sup_tuple_sets([{Arity1, _} = T1|Left1] = L1,
+ [{Arity2, _} = T2|Left2] = L2, Acc) ->
+ if Arity1 < Arity2 -> sup_tuple_sets(Left1, L2, [T1|Acc]);
+ Arity1 > Arity2 -> sup_tuple_sets(L1, Left2, [T2|Acc])
+ end;
+sup_tuple_sets([], L2, Acc) -> lists:reverse(Acc, L2);
+sup_tuple_sets(L1, [], Acc) -> lists:reverse(Acc, L1).
+
+sup_tuples_in_set([?tuple(_, _, ?any) = T], L) ->
+ [t_tuple(sup_tuple_elements([T|L]))];
+sup_tuples_in_set(L, [?tuple(_, _, ?any) = T]) ->
+ [t_tuple(sup_tuple_elements([T|L]))];
+sup_tuples_in_set(L1, L2) ->
+ FoldFun = fun(?tuple(_, _, Tag), AccTag) -> t_sup(Tag, AccTag) end,
+ TotalTag0 = lists:foldl(FoldFun, ?none, L1),
+ TotalTag = lists:foldl(FoldFun, TotalTag0, L2),
+ case TotalTag of
+ ?atom(?any) ->
+ %% We will reach the set limit. Widen now.
+ [t_tuple(sup_tuple_elements(L1 ++ L2))];
+ ?atom(Set) ->
+ case set_size(Set) > ?TUPLE_TAG_LIMIT of
+ true ->
+ %% We will reach the set limit. Widen now.
+ [t_tuple(sup_tuple_elements(L1 ++ L2))];
+ false ->
+ %% We can go on and build the tuple set.
+ sup_tuples_in_set(L1, L2, [])
+ end
+ end.
+
+sup_tuple_elements([?tuple(Elements, _, _)|L]) ->
+ lists:foldl(fun (?tuple(Es, _, _), Acc) -> t_sup_lists(Es, Acc) end,
+ Elements, L).
+
+sup_tuples_in_set([?tuple(Elements1, Arity, Tag1) = T1|Left1] = L1,
+ [?tuple(Elements2, Arity, Tag2) = T2|Left2] = L2, Acc) ->
+ if
+ Tag1 < Tag2 -> sup_tuples_in_set(Left1, L2, [T1|Acc]);
+ Tag1 > Tag2 -> sup_tuples_in_set(L1, Left2, [T2|Acc]);
+ Tag2 =:= Tag2 -> NewElements = t_sup_lists(Elements1, Elements2),
+ NewAcc = [?tuple(NewElements, Arity, Tag1)|Acc],
+ sup_tuples_in_set(Left1, Left2, NewAcc)
+ end;
+sup_tuples_in_set([], L2, Acc) -> lists:reverse(Acc, L2);
+sup_tuples_in_set(L1, [], Acc) -> lists:reverse(Acc, L1).
+
+sup_union(U1, U2) ->
+ sup_union(U1, U2, 0, []).
+
+sup_union([?none|Left1], [?none|Left2], N, Acc) ->
+ sup_union(Left1, Left2, N, [?none|Acc]);
+sup_union([T1|Left1], [T2|Left2], N, Acc) ->
+ sup_union(Left1, Left2, N+1, [t_sup(T1, T2)|Acc]);
+sup_union([], [], N, Acc) ->
+ if N =:= 0 -> ?none;
+ N =:= 1 ->
+ [Type] = [T || T <- Acc, T =/= ?none],
+ Type;
+ N =:= length(Acc) -> ?any;
+ true -> ?union(lists:reverse(Acc))
+ end.
+
+force_union(T = ?atom(_)) -> ?atom_union(T);
+force_union(T = ?bitstr(_, _)) -> ?bitstr_union(T);
+force_union(T = ?function(_, _)) -> ?function_union(T);
+force_union(T = ?identifier(_)) -> ?identifier_union(T);
+force_union(T = ?list(_, _, _)) -> ?list_union(T);
+force_union(T = ?nil) -> ?list_union(T);
+force_union(T = ?number(_, _)) -> ?number_union(T);
+force_union(T = ?opaque(_)) -> ?opaque_union(T);
+force_union(T = ?map(_,_,_)) -> ?map_union(T);
+force_union(T = ?tuple(_, _, _)) -> ?tuple_union(T);
+force_union(T = ?tuple_set(_)) -> ?tuple_union(T);
+force_union(T = ?matchstate(_, _)) -> ?matchstate_union(T);
+force_union(T = ?union(_)) -> T.
+
+%%-----------------------------------------------------------------------------
+%% An attempt to write the inverse operation of t_sup/1 -- XXX: INCOMPLETE !!
+%%
+
+-spec t_elements(erl_type()) -> [erl_type()].
+
+t_elements(?none) -> [];
+t_elements(?unit) -> [];
+t_elements(?any = T) -> [T];
+t_elements(?nil = T) -> [T];
+t_elements(?atom(?any) = T) -> [T];
+t_elements(?atom(Atoms)) ->
+ [t_atom(A) || A <- Atoms];
+t_elements(?bitstr(_, _) = T) -> [T];
+t_elements(?function(_, _) = T) -> [T];
+t_elements(?identifier(?any) = T) -> [T];
+t_elements(?identifier(IDs)) ->
+ [?identifier([T]) || T <- IDs];
+t_elements(?list(_, _, _) = T) -> [T];
+t_elements(?number(_, _) = T) ->
+ case T of
+ ?number(?any, ?unknown_qual) ->
+ [?float, ?integer(?any)];
+ ?float -> [T];
+ ?integer(?any) -> [T];
+ ?int_range(_, _) -> [T];
+ ?int_set(Set) ->
+ [t_integer(I) || I <- Set]
+ end;
+t_elements(?opaque(_) = T) ->
+ do_elements(T);
+t_elements(?map(_,_,_) = T) -> [T];
+t_elements(?tuple(_, _, _) = T) -> [T];
+t_elements(?tuple_set(_) = TS) ->
+ case t_tuple_subtypes(TS) of
+ unknown -> [];
+ Elems -> Elems
+ end;
+t_elements(?union(_) = T) ->
+ do_elements(T);
+t_elements(?var(_)) -> [?any]. %% yes, vars exist -- what else to do here?
+%% t_elements(T) ->
+%% io:format("T_ELEMENTS => ~p\n", [T]).
+
+do_elements(Type0) ->
+ case do_opaque(Type0, 'universe', fun(T) -> T end) of
+ ?union(List) -> lists:append([t_elements(T) || T <- List]);
+ Type -> t_elements(Type)
+ end.
+
+%%-----------------------------------------------------------------------------
+%% Infimum
+%%
+
+-spec t_inf([erl_type()]) -> erl_type().
+
+t_inf([H1, H2|T]) ->
+ case t_inf(H1, H2) of
+ ?none -> ?none;
+ NewH -> t_inf([NewH|T])
+ end;
+t_inf([H]) -> H;
+t_inf([]) -> ?none.
+
+-spec t_inf(erl_type(), erl_type()) -> erl_type().
+
+t_inf(T1, T2) ->
+ t_inf(T1, T2, 'universe').
+
+%% 'match' should be used from t_find_unknown_opaque() only
+-type t_inf_opaques() :: opaques() | {'match', [erl_type() | 'universe']}.
+
+-spec t_inf(erl_type(), erl_type(), t_inf_opaques()) -> erl_type().
+
+t_inf(?var(_), ?var(_), _Opaques) -> ?any;
+t_inf(?var(_), T, _Opaques) -> subst_all_vars_to_any(T);
+t_inf(T, ?var(_), _Opaques) -> subst_all_vars_to_any(T);
+t_inf(?any, T, _Opaques) -> subst_all_vars_to_any(T);
+t_inf(T, ?any, _Opaques) -> subst_all_vars_to_any(T);
+t_inf(?none, _, _Opaques) -> ?none;
+t_inf(_, ?none, _Opaques) -> ?none;
+t_inf(?unit, _, _Opaques) -> ?unit; % ?unit cases should appear below ?none
+t_inf(_, ?unit, _Opaques) -> ?unit;
+t_inf(T, T, _Opaques) -> subst_all_vars_to_any(T);
+t_inf(?atom(Set1), ?atom(Set2), _) ->
+ case set_intersection(Set1, Set2) of
+ ?none -> ?none;
+ NewSet -> ?atom(NewSet)
+ end;
+t_inf(?bitstr(U1, B1), ?bitstr(0, B2), _Opaques) ->
+ if B2 >= B1 andalso (B2-B1) rem U1 =:= 0 -> t_bitstr(0, B2);
+ true -> ?none
+ end;
+t_inf(?bitstr(0, B1), ?bitstr(U2, B2), _Opaques) ->
+ if B1 >= B2 andalso (B1-B2) rem U2 =:= 0 -> t_bitstr(0, B1);
+ true -> ?none
+ end;
+t_inf(?bitstr(U1, B1), ?bitstr(U1, B1), _Opaques) ->
+ t_bitstr(U1, B1);
+t_inf(?bitstr(U1, B1), ?bitstr(U2, B2), _Opaques) when U2 > U1 ->
+ inf_bitstr(U2, B2, U1, B1);
+t_inf(?bitstr(U1, B1), ?bitstr(U2, B2), _Opaques) ->
+ inf_bitstr(U1, B1, U2, B2);
+t_inf(?function(Domain1, Range1), ?function(Domain2, Range2), Opaques) ->
+ case t_inf(Domain1, Domain2, Opaques) of
+ ?none -> ?none;
+ Domain -> ?function(Domain, t_inf(Range1, Range2, Opaques))
+ end;
+t_inf(?identifier(Set1), ?identifier(Set2), _Opaques) ->
+ case set_intersection(Set1, Set2) of
+ ?none -> ?none;
+ Set -> ?identifier(Set)
+ end;
+t_inf(?map(_, ADefK, ADefV) = A, ?map(_, BDefK, BDefV) = B, _Opaques) ->
+ %% Because it simplifies the anonymous function, we allow Pairs to temporarily
+ %% contain mandatory pairs with none values, since all such cases should
+ %% result in a none result.
+ Pairs =
+ map_pairwise_merge(
+ %% For optional keys in both maps, when the infinimum is none, we have
+ %% essentially concluded that K must not be a key in the map.
+ fun(K, ?opt, V1, ?opt, V2) -> {K, ?opt, t_inf(V1, V2)};
+ %% When a key is optional in one map, but mandatory in another, it
+ %% becomes mandatory in the infinumum
+ (K, _, V1, _, V2) -> {K, ?mand, t_inf(V1, V2)}
+ end, A, B),
+ %% If the infinimum of any mandatory values is ?none, the entire map infinimum
+ %% is ?none.
+ case lists:any(fun({_,?mand,?none})->true; ({_,_,_}) -> false end, Pairs) of
+ true -> t_none();
+ false -> t_map(Pairs, t_inf(ADefK, BDefK), t_inf(ADefV, BDefV))
+ end;
+t_inf(?matchstate(Pres1, Slots1), ?matchstate(Pres2, Slots2), _Opaques) ->
+ ?matchstate(t_inf(Pres1, Pres2), t_inf(Slots1, Slots2));
+t_inf(?nil, ?nil, _Opaques) -> ?nil;
+t_inf(?nil, ?nonempty_list(_, _), _Opaques) ->
+ ?none;
+t_inf(?nonempty_list(_, _), ?nil, _Opaques) ->
+ ?none;
+t_inf(?nil, ?list(_Contents, Termination, _), Opaques) ->
+ t_inf(?nil, t_unopaque(Termination), Opaques);
+t_inf(?list(_Contents, Termination, _), ?nil, Opaques) ->
+ t_inf(?nil, t_unopaque(Termination), Opaques);
+t_inf(?list(Contents1, Termination1, Size1),
+ ?list(Contents2, Termination2, Size2), Opaques) ->
+ case t_inf(Termination1, Termination2, Opaques) of
+ ?none -> ?none;
+ Termination ->
+ case t_inf(Contents1, Contents2, Opaques) of
+ ?none ->
+ %% If none of the lists are nonempty, then the infimum is nil.
+ case (Size1 =:= ?unknown_qual) andalso (Size2 =:= ?unknown_qual) of
+ true -> t_nil();
+ false -> ?none
+ end;
+ Contents ->
+ Size =
+ case {Size1, Size2} of
+ {?unknown_qual, ?unknown_qual} -> ?unknown_qual;
+ {?unknown_qual, ?nonempty_qual} -> ?nonempty_qual;
+ {?nonempty_qual, ?unknown_qual} -> ?nonempty_qual;
+ {?nonempty_qual, ?nonempty_qual} -> ?nonempty_qual
+ end,
+ ?list(Contents, Termination, Size)
+ end
+ end;
+t_inf(?number(_, _) = T1, ?number(_, _) = T2, _Opaques) ->
+ case {T1, T2} of
+ {T, T} -> T;
+ {_, ?number(?any, ?unknown_qual)} -> T1;
+ {?number(?any, ?unknown_qual), _} -> T2;
+ {?float, ?integer(_)} -> ?none;
+ {?integer(_), ?float} -> ?none;
+ {?integer(?any), ?integer(_)} -> T2;
+ {?integer(_), ?integer(?any)} -> T1;
+ {?int_set(Set1), ?int_set(Set2)} ->
+ case set_intersection(Set1, Set2) of
+ ?none -> ?none;
+ Set -> ?int_set(Set)
+ end;
+ {?int_range(From1, To1), ?int_range(From2, To2)} ->
+ t_from_range(max(From1, From2), min(To1, To2));
+ {Range = ?int_range(_, _), ?int_set(Set)} ->
+ %% io:format("t_inf range, set args ~p ~p ~n", [T1, T2]),
+ Ans2 =
+ case set_filter(fun(X) -> in_range(X, Range) end, Set) of
+ ?none -> ?none;
+ NewSet -> ?int_set(NewSet)
+ end,
+ %% io:format("Ans2 ~p ~n", [Ans2]),
+ Ans2;
+ {?int_set(Set), ?int_range(_, _) = Range} ->
+ case set_filter(fun(X) -> in_range(X, Range) end, Set) of
+ ?none -> ?none;
+ NewSet -> ?int_set(NewSet)
+ end
+ end;
+t_inf(?product(Types1), ?product(Types2), Opaques) ->
+ L1 = length(Types1),
+ L2 = length(Types2),
+ if L1 =:= L2 -> ?product(t_inf_lists(Types1, Types2, Opaques));
+ true -> ?none
+ end;
+t_inf(?product(_), _, _Opaques) ->
+ ?none;
+t_inf(_, ?product(_), _Opaques) ->
+ ?none;
+t_inf(?tuple(?any, ?any, ?any), ?tuple(_, _, _) = T, _Opaques) ->
+ subst_all_vars_to_any(T);
+t_inf(?tuple(_, _, _) = T, ?tuple(?any, ?any, ?any), _Opaques) ->
+ subst_all_vars_to_any(T);
+t_inf(?tuple(?any, ?any, ?any), ?tuple_set(_) = T, _Opaques) ->
+ subst_all_vars_to_any(T);
+t_inf(?tuple_set(_) = T, ?tuple(?any, ?any, ?any), _Opaques) ->
+ subst_all_vars_to_any(T);
+t_inf(?tuple(Elements1, Arity, _Tag1), ?tuple(Elements2, Arity, _Tag2), Opaques) ->
+ case t_inf_lists_strict(Elements1, Elements2, Opaques) of
+ bottom -> ?none;
+ NewElements -> t_tuple(NewElements)
+ end;
+t_inf(?tuple_set(List1), ?tuple_set(List2), Opaques) ->
+ inf_tuple_sets(List1, List2, Opaques);
+t_inf(?tuple_set(List), ?tuple(_, Arity, _) = T, Opaques) ->
+ inf_tuple_sets(List, [{Arity, [T]}], Opaques);
+t_inf(?tuple(_, Arity, _) = T, ?tuple_set(List), Opaques) ->
+ inf_tuple_sets(List, [{Arity, [T]}], Opaques);
+%% be careful: here and in the next clause T can be ?opaque
+t_inf(?union(U1), T, Opaques) ->
+ ?union(U2) = force_union(T),
+ inf_union(U1, U2, Opaques);
+t_inf(T, ?union(U2), Opaques) ->
+ ?union(U1) = force_union(T),
+ inf_union(U1, U2, Opaques);
+t_inf(?opaque(Set1), ?opaque(Set2), Opaques) ->
+ inf_opaque(Set1, Set2, Opaques);
+t_inf(?opaque(_) = T1, T2, Opaques) ->
+ inf_opaque1(T2, T1, 1, Opaques);
+t_inf(T1, ?opaque(_) = T2, Opaques) ->
+ inf_opaque1(T1, T2, 2, Opaques);
+%% and as a result, the cases for ?opaque should appear *after* ?union
+t_inf(#c{}, #c{}, _) ->
+ ?none.
+
+inf_opaque1(T1, ?opaque(Set2)=T2, Pos, Opaques) ->
+ case Opaques =:= 'universe' orelse inf_is_opaque_type(T2, Pos, Opaques) of
+ false -> ?none;
+ true ->
+ List2 = set_to_list(Set2),
+ case inf_collect(T1, List2, Opaques, []) of
+ [] -> ?none;
+ OpL -> ?opaque(ordsets:from_list(OpL))
+ end
+ end.
+
+inf_is_opaque_type(T, Pos, {match, Opaques}) ->
+ is_opaque_type(T, Opaques) orelse throw({pos, [Pos]});
+inf_is_opaque_type(T, _Pos, Opaques) ->
+ is_opaque_type(T, Opaques).
+
+inf_collect(T1, [T2|List2], Opaques, OpL) ->
+ #opaque{struct = S2} = T2,
+ case t_inf(T1, S2, Opaques) of
+ ?none -> inf_collect(T1, List2, Opaques, OpL);
+ Inf ->
+ Op = T2#opaque{struct = Inf},
+ inf_collect(T1, List2, Opaques, [Op|OpL])
+ end;
+inf_collect(_T1, [], _Opaques, OpL) ->
+ OpL.
+
+combine(S, T1, T2) ->
+ #opaque{mod = Mod1, name = Name1, args = Args1} = T1,
+ #opaque{mod = Mod2, name = Name2, args = Args2} = T2,
+ Comb1 = comb(Mod1, Name1, Args1, S, T1),
+ case is_compat_opaque_names({Mod1, Name1, Args1}, {Mod2, Name2, Args2}) of
+ true -> Comb1;
+ false -> Comb1 ++ comb(Mod2, Name2, Args2, S, T2)
+ end.
+
+comb(Mod, Name, Args, S, T) ->
+ case can_combine_opaque_names(Mod, Name, Args, S) of
+ true ->
+ ?opaque(Set) = S,
+ Set;
+ false ->
+ [T#opaque{struct = S}]
+ end.
+
+can_combine_opaque_names(Mod1, Name1, Args1,
+ ?opaque([#opaque{mod = Mod2, name = Name2, args = Args2}])) ->
+ is_compat_opaque_names({Mod1, Name1, Args1}, {Mod2, Name2, Args2});
+can_combine_opaque_names(_, _, _, _) -> false.
+
+%% Combining two lists this way can be very time consuming...
+%% Note: two parameterized opaque types are not the same if their
+%% actual parameters differ
+inf_opaque(Set1, Set2, Opaques) ->
+ List1 = inf_look_up(Set1, Opaques),
+ List2 = inf_look_up(Set2, Opaques),
+ List0 = [combine(Inf, T1, T2) ||
+ {Is1, ModNameArgs1, T1} <- List1,
+ {Is2, ModNameArgs2, T2} <- List2,
+ not t_is_none(Inf = inf_opaque_types(Is1, ModNameArgs1, T1,
+ Is2, ModNameArgs2, T2,
+ Opaques))],
+ List = lists:sort(lists:append(List0)),
+ sup_opaque(List).
+
+%% Optimization: do just one lookup.
+inf_look_up(Set, Opaques) ->
+ [{Opaques =:= 'universe' orelse inf_is_opaque_type2(T, Opaques),
+ {M, N, Args}, T} ||
+ #opaque{mod = M, name = N, args = Args} = T <- set_to_list(Set)].
+
+inf_is_opaque_type2(T, {match, Opaques}) ->
+ is_opaque_type2(T, Opaques);
+inf_is_opaque_type2(T, Opaques) ->
+ is_opaque_type2(T, Opaques).
+
+inf_opaque_types(IsOpaque1, ModNameArgs1, T1,
+ IsOpaque2, ModNameArgs2, T2, Opaques) ->
+ #opaque{struct = S1}=T1,
+ #opaque{struct = S2}=T2,
+ case
+ Opaques =:= 'universe' orelse
+ is_compat_opaque_names(ModNameArgs1, ModNameArgs2)
+ of
+ true -> t_inf(S1, S2, Opaques);
+ false ->
+ case {IsOpaque1, IsOpaque2} of
+ {true, true} -> t_inf(S1, S2, Opaques);
+ {true, false} -> t_inf(S1, ?opaque(set_singleton(T2)), Opaques);
+ {false, true} -> t_inf(?opaque(set_singleton(T1)), S2, Opaques);
+ {false, false} when element(1, Opaques) =:= match ->
+ throw({pos, [1, 2]});
+ {false, false} -> t_none()
+ end
+ end.
+
+is_compat_opaque_names(ModNameArgs, ModNameArgs) -> true;
+is_compat_opaque_names({Mod,Name,Args1}, {Mod,Name,Args2}) ->
+ is_compat_args(Args1, Args2);
+is_compat_opaque_names(_, _) -> false.
+
+is_compat_args([A1|Args1], [A2|Args2]) ->
+ is_compat_arg(A1, A2) andalso is_compat_args(Args1, Args2);
+is_compat_args([], []) -> true;
+is_compat_args(_, _) -> false.
+
+is_compat_arg(A1, A2) ->
+ is_specialization(A1, A2) orelse is_specialization(A2, A1).
+
+-spec is_specialization(erl_type(), erl_type()) -> boolean().
+
+%% Returns true if the first argument is a specialization of the
+%% second argument in the sense that every type is a specialization of
+%% any(). For example, {_,_} is a specialization of any(), but not of
+%% tuple(). Does not handle variables, but any() and unions (sort of).
+
+is_specialization(T, T) -> true;
+is_specialization(_, ?any) -> true;
+is_specialization(?any, _) -> false;
+is_specialization(?function(Domain1, Range1), ?function(Domain2, Range2)) ->
+ (is_specialization(Domain1, Domain2) andalso
+ is_specialization(Range1, Range2));
+is_specialization(?list(Contents1, Termination1, Size1),
+ ?list(Contents2, Termination2, Size2)) ->
+ (Size1 =:= Size2 andalso
+ is_specialization(Contents1, Contents2) andalso
+ is_specialization(Termination1, Termination2));
+is_specialization(?product(Types1), ?product(Types2)) ->
+ specialization_list(Types1, Types2);
+is_specialization(?tuple(?any, ?any, ?any), ?tuple(_, _, _)) -> false;
+is_specialization(?tuple(_, _, _), ?tuple(?any, ?any, ?any)) -> false;
+is_specialization(?tuple(Elements1, Arity, _),
+ ?tuple(Elements2, Arity, _)) when Arity =/= ?any ->
+ specialization_list(Elements1, Elements2);
+is_specialization(?tuple_set([{Arity, List}]),
+ ?tuple(Elements2, Arity, _)) when Arity =/= ?any ->
+ specialization_list(sup_tuple_elements(List), Elements2);
+is_specialization(?tuple(Elements1, Arity, _),
+ ?tuple_set([{Arity, List}])) when Arity =/= ?any ->
+ specialization_list(Elements1, sup_tuple_elements(List));
+is_specialization(?tuple_set(List1), ?tuple_set(List2)) ->
+ try
+ specialization_list_list([sup_tuple_elements(T) || {_Arity, T} <- List1],
+ [sup_tuple_elements(T) || {_Arity, T} <- List2])
+ catch _:_ -> false
+ end;
+is_specialization(?union(List1)=T1, ?union(List2)=T2) ->
+ case specialization_union2(T1, T2) of
+ {yes, Type1, Type2} -> is_specialization(Type1, Type2);
+ no -> specialization_list(List1, List2)
+ end;
+is_specialization(?union(List), T2) ->
+ case unify_union(List) of
+ {yes, Type} -> is_specialization(Type, T2);
+ no -> false
+ end;
+is_specialization(T1, ?union(List)) ->
+ case unify_union(List) of
+ {yes, Type} -> is_specialization(T1, Type);
+ no -> false
+ end;
+is_specialization(?opaque(_) = T1, T2) ->
+ is_specialization(t_opaque_structure(T1), T2);
+is_specialization(T1, ?opaque(_) = T2) ->
+ is_specialization(T1, t_opaque_structure(T2));
+is_specialization(?var(_), _) -> exit(error);
+is_specialization(_, ?var(_)) -> exit(error);
+is_specialization(?none, _) -> false;
+is_specialization(_, ?none) -> false;
+is_specialization(?unit, _) -> false;
+is_specialization(_, ?unit) -> false;
+is_specialization(#c{}, #c{}) -> false.
+
+specialization_list_list(LL1, LL2) ->
+ length(LL1) =:= length(LL2) andalso specialization_list_list1(LL1, LL2).
+
+specialization_list_list1([], []) -> true;
+specialization_list_list1([L1|LL1], [L2|LL2]) ->
+ specialization_list(L1, L2) andalso specialization_list_list1(LL1, LL2).
+
+specialization_list(L1, L2) ->
+ length(L1) =:= length(L2) andalso specialization_list1(L1, L2).
+
+specialization_list1([], []) -> true;
+specialization_list1([T1|L1], [T2|L2]) ->
+ is_specialization(T1, T2) andalso specialization_list1(L1, L2).
+
+specialization_union2(?union(List1)=T1, ?union(List2)=T2) ->
+ case {unify_union(List1), unify_union(List2)} of
+ {{yes, Type1}, {yes, Type2}} -> {yes, Type1, Type2};
+ {{yes, Type1}, no} -> {yes, Type1, T2};
+ {no, {yes, Type2}} -> {yes, T1, Type2};
+ {no, no} -> no
+ end.
+
+-spec t_inf_lists([erl_type()], [erl_type()]) -> [erl_type()].
+
+t_inf_lists(L1, L2) ->
+ t_inf_lists(L1, L2, 'universe').
+
+-spec t_inf_lists([erl_type()], [erl_type()], t_inf_opaques()) -> [erl_type()].
+
+t_inf_lists(L1, L2, Opaques) ->
+ t_inf_lists(L1, L2, [], Opaques).
+
+-spec t_inf_lists([erl_type()], [erl_type()], [erl_type()], [erl_type()]) -> [erl_type()].
+
+t_inf_lists([T1|Left1], [T2|Left2], Acc, Opaques) ->
+ t_inf_lists(Left1, Left2, [t_inf(T1, T2, Opaques)|Acc], Opaques);
+t_inf_lists([], [], Acc, _Opaques) ->
+ lists:reverse(Acc).
+
+%% Infimum of lists with strictness.
+%% If any element is the ?none type, the value 'bottom' is returned.
+
+-spec t_inf_lists_strict([erl_type()], [erl_type()], [erl_type()]) -> 'bottom' | [erl_type()].
+
+t_inf_lists_strict(L1, L2, Opaques) ->
+ t_inf_lists_strict(L1, L2, [], Opaques).
+
+-spec t_inf_lists_strict([erl_type()], [erl_type()], [erl_type()], [erl_type()]) -> 'bottom' | [erl_type()].
+
+t_inf_lists_strict([T1|Left1], [T2|Left2], Acc, Opaques) ->
+ case t_inf(T1, T2, Opaques) of
+ ?none -> bottom;
+ T -> t_inf_lists_strict(Left1, Left2, [T|Acc], Opaques)
+ end;
+t_inf_lists_strict([], [], Acc, _Opaques) ->
+ lists:reverse(Acc).
+
+inf_tuple_sets(L1, L2, Opaques) ->
+ case inf_tuple_sets(L1, L2, [], Opaques) of
+ [] -> ?none;
+ [{_Arity, [?tuple(_, _, _) = OneTuple]}] -> OneTuple;
+ List -> ?tuple_set(List)
+ end.
+
+inf_tuple_sets([{Arity, Tuples1}|Ts1], [{Arity, Tuples2}|Ts2], Acc, Opaques) ->
+ case inf_tuples_in_sets(Tuples1, Tuples2, Opaques) of
+ [] -> inf_tuple_sets(Ts1, Ts2, Acc, Opaques);
+ [?tuple_set([{Arity, NewTuples}])] ->
+ inf_tuple_sets(Ts1, Ts2, [{Arity, NewTuples}|Acc], Opaques);
+ NewTuples -> inf_tuple_sets(Ts1, Ts2, [{Arity, NewTuples}|Acc], Opaques)
+ end;
+inf_tuple_sets([{Arity1, _}|Ts1] = L1, [{Arity2, _}|Ts2] = L2, Acc, Opaques) ->
+ if Arity1 < Arity2 -> inf_tuple_sets(Ts1, L2, Acc, Opaques);
+ Arity1 > Arity2 -> inf_tuple_sets(L1, Ts2, Acc, Opaques)
+ end;
+inf_tuple_sets([], _, Acc, _Opaques) -> lists:reverse(Acc);
+inf_tuple_sets(_, [], Acc, _Opaques) -> lists:reverse(Acc).
+
+inf_tuples_in_sets([?tuple(Elements1, _, ?any)], L2, Opaques) ->
+ NewList = [t_inf_lists_strict(Elements1, Elements2, Opaques)
+ || ?tuple(Elements2, _, _) <- L2],
+ [t_tuple(Es) || Es <- NewList, Es =/= bottom];
+inf_tuples_in_sets(L1, [?tuple(Elements2, _, ?any)], Opaques) ->
+ NewList = [t_inf_lists_strict(Elements1, Elements2, Opaques)
+ || ?tuple(Elements1, _, _) <- L1],
+ [t_tuple(Es) || Es <- NewList, Es =/= bottom];
+inf_tuples_in_sets(L1, L2, Opaques) ->
+ inf_tuples_in_sets2(L1, L2, [], Opaques).
+
+inf_tuples_in_sets2([?tuple(Elements1, Arity, Tag)|Ts1],
+ [?tuple(Elements2, Arity, Tag)|Ts2], Acc, Opaques) ->
+ case t_inf_lists_strict(Elements1, Elements2, Opaques) of
+ bottom -> inf_tuples_in_sets2(Ts1, Ts2, Acc, Opaques);
+ NewElements ->
+ inf_tuples_in_sets2(Ts1, Ts2, [?tuple(NewElements, Arity, Tag)|Acc],
+ Opaques)
+ end;
+inf_tuples_in_sets2([?tuple(_, _, Tag1)|Ts1] = L1,
+ [?tuple(_, _, Tag2)|Ts2] = L2, Acc, Opaques) ->
+ if Tag1 < Tag2 -> inf_tuples_in_sets2(Ts1, L2, Acc, Opaques);
+ Tag1 > Tag2 -> inf_tuples_in_sets2(L1, Ts2, Acc, Opaques)
+ end;
+inf_tuples_in_sets2([], _, Acc, _Opaques) -> lists:reverse(Acc);
+inf_tuples_in_sets2(_, [], Acc, _Opaques) -> lists:reverse(Acc).
+
+inf_union(U1, U2, Opaques) ->
+ OpaqueFun =
+ fun(Union1, Union2, InfFun) ->
+ [_,_,_,_,_,_,_,_,Opaque,_] = Union1,
+ [A,B,F,I,L,N,T,M,_,Map] = Union2,
+ List = [A,B,F,I,L,N,T,M,Map],
+ inf_union_collect(List, Opaque, InfFun, [], [])
+ end,
+ {O1, ThrowList1} =
+ OpaqueFun(U1, U2, fun(E, Opaque) -> t_inf(Opaque, E, Opaques) end),
+ {O2, ThrowList2}
+ = OpaqueFun(U2, U1, fun(E, Opaque) -> t_inf(E, Opaque, Opaques) end),
+ {Union, ThrowList3} = inf_union(U1, U2, 0, [], [], Opaques),
+ ThrowList = lists:merge3(ThrowList1, ThrowList2, ThrowList3),
+ case t_sup([O1, O2, Union]) of
+ ?none when ThrowList =/= [] -> throw({pos, lists:usort(ThrowList)});
+ Sup -> Sup
+ end.
+
+inf_union_collect([], _Opaque, _InfFun, InfList, ThrowList) ->
+ {t_sup(InfList), lists:usort(ThrowList)};
+inf_union_collect([?none|L], Opaque, InfFun, InfList, ThrowList) ->
+ inf_union_collect(L, Opaque, InfFun, [?none|InfList], ThrowList);
+inf_union_collect([E|L], Opaque, InfFun, InfList, ThrowList) ->
+ try InfFun(E, Opaque)of
+ Inf ->
+ inf_union_collect(L, Opaque, InfFun, [Inf|InfList], ThrowList)
+ catch throw:{pos, Ns} ->
+ inf_union_collect(L, Opaque, InfFun, InfList, Ns ++ ThrowList)
+ end.
+
+inf_union([?none|Left1], [?none|Left2], N, Acc, ThrowList, Opaques) ->
+ inf_union(Left1, Left2, N, [?none|Acc], ThrowList, Opaques);
+inf_union([T1|Left1], [T2|Left2], N, Acc, ThrowList, Opaques) ->
+ try t_inf(T1, T2, Opaques) of
+ ?none -> inf_union(Left1, Left2, N, [?none|Acc], ThrowList, Opaques);
+ T -> inf_union(Left1, Left2, N+1, [T|Acc], ThrowList, Opaques)
+ catch throw:{pos, Ns} ->
+ inf_union(Left1, Left2, N, [?none|Acc], Ns ++ ThrowList, Opaques)
+ end;
+inf_union([], [], N, Acc, ThrowList, _Opaques) ->
+ if N =:= 0 -> {?none, ThrowList};
+ N =:= 1 ->
+ [Type] = [T || T <- Acc, T =/= ?none],
+ {Type, ThrowList};
+ N >= 2 -> {?union(lists:reverse(Acc)), ThrowList}
+ end.
+
+inf_bitstr(U1, B1, U2, B2) ->
+ GCD = gcd(U1, U2),
+ case (B2-B1) rem GCD of
+ 0 ->
+ U = (U1*U2) div GCD,
+ B = findfirst(0, 0, U1, B1, U2, B2),
+ t_bitstr(U, B);
+ _ ->
+ ?none
+ end.
+
+findfirst(N1, N2, U1, B1, U2, B2) ->
+ Val1 = U1*N1+B1,
+ Val2 = U2*N2+B2,
+ if Val1 =:= Val2 ->
+ Val1;
+ Val1 > Val2 ->
+ findfirst(N1, N2+1, U1, B1, U2, B2);
+ Val1 < Val2 ->
+ findfirst(N1+1, N2, U1, B1, U2, B2)
+ end.
+
+%%-----------------------------------------------------------------------------
+%% Substitution of variables
+%%
+
+-type subst_table() :: #{any() => erl_type()}.
+
+-spec t_subst(erl_type(), subst_table()) -> erl_type().
+
+t_subst(T, Map) ->
+ case t_has_var(T) of
+ true -> t_subst_aux(T, Map);
+ false -> T
+ end.
+
+-spec subst_all_vars_to_any(erl_type()) -> erl_type().
+
+subst_all_vars_to_any(T) ->
+ t_subst(T, #{}).
+
+t_subst_aux(?var(Id), Map) ->
+ case maps:find(Id, Map) of
+ error -> ?any;
+ {ok, Type} -> Type
+ end;
+t_subst_aux(?list(Contents, Termination, Size), Map) ->
+ case t_subst_aux(Contents, Map) of
+ ?none -> ?none;
+ NewContents ->
+ %% Be careful here to make the termination collapse if necessary.
+ case t_subst_aux(Termination, Map) of
+ ?nil -> ?list(NewContents, ?nil, Size);
+ ?any -> ?list(NewContents, ?any, Size);
+ Other ->
+ ?list(NewContents2, NewTermination, _) = t_cons(NewContents, Other),
+ ?list(NewContents2, NewTermination, Size)
+ end
+ end;
+t_subst_aux(?function(Domain, Range), Map) ->
+ ?function(t_subst_aux(Domain, Map), t_subst_aux(Range, Map));
+t_subst_aux(?product(Types), Map) ->
+ ?product([t_subst_aux(T, Map) || T <- Types]);
+t_subst_aux(?tuple(?any, ?any, ?any) = T, _Map) ->
+ T;
+t_subst_aux(?tuple(Elements, _Arity, _Tag), Map) ->
+ t_tuple([t_subst_aux(E, Map) || E <- Elements]);
+t_subst_aux(?tuple_set(_) = TS, Map) ->
+ t_sup([t_subst_aux(T, Map) || T <- t_tuple_subtypes(TS)]);
+t_subst_aux(?map(Pairs, DefK, DefV), Map) ->
+ t_map([{K, MNess, t_subst_aux(V, Map)} || {K, MNess, V} <- Pairs],
+ t_subst_aux(DefK, Map), t_subst_aux(DefV, Map));
+t_subst_aux(?opaque(Es), Map) ->
+ List = [Opaque#opaque{args = [t_subst_aux(Arg, Map) || Arg <- Args],
+ struct = t_subst_aux(S, Map)} ||
+ Opaque = #opaque{args = Args, struct = S} <- set_to_list(Es)],
+ ?opaque(ordsets:from_list(List));
+t_subst_aux(?union(List), Map) ->
+ ?union([t_subst_aux(E, Map) || E <- List]);
+t_subst_aux(T, _Map) ->
+ T.
+
+%%-----------------------------------------------------------------------------
+%% Unification
+%%
+
+-type t_unify_ret() :: {erl_type(), [{_, erl_type()}]}.
+
+-spec t_unify(erl_type(), erl_type()) -> t_unify_ret().
+
+t_unify(T1, T2) ->
+ {T, VarMap} = t_unify(T1, T2, #{}),
+ {t_subst(T, VarMap), lists:keysort(1, maps:to_list(VarMap))}.
+
+t_unify(?var(Id) = T, ?var(Id), VarMap) ->
+ {T, VarMap};
+t_unify(?var(Id1) = T, ?var(Id2), VarMap) ->
+ case maps:find(Id1, VarMap) of
+ error ->
+ case maps:find(Id2, VarMap) of
+ error -> {T, VarMap#{Id2 => T}};
+ {ok, Type} -> t_unify(T, Type, VarMap)
+ end;
+ {ok, Type1} ->
+ case maps:find(Id2, VarMap) of
+ error -> {Type1, VarMap#{Id2 => T}};
+ {ok, Type2} -> t_unify(Type1, Type2, VarMap)
+ end
+ end;
+t_unify(?var(Id), Type, VarMap) ->
+ case maps:find(Id, VarMap) of
+ error -> {Type, VarMap#{Id => Type}};
+ {ok, VarType} -> t_unify(VarType, Type, VarMap)
+ end;
+t_unify(Type, ?var(Id), VarMap) ->
+ case maps:find(Id, VarMap) of
+ error -> {Type, VarMap#{Id => Type}};
+ {ok, VarType} -> t_unify(VarType, Type, VarMap)
+ end;
+t_unify(?function(Domain1, Range1), ?function(Domain2, Range2), VarMap) ->
+ {Domain, VarMap1} = t_unify(Domain1, Domain2, VarMap),
+ {Range, VarMap2} = t_unify(Range1, Range2, VarMap1),
+ {?function(Domain, Range), VarMap2};
+t_unify(?list(Contents1, Termination1, Size),
+ ?list(Contents2, Termination2, Size), VarMap) ->
+ {Contents, VarMap1} = t_unify(Contents1, Contents2, VarMap),
+ {Termination, VarMap2} = t_unify(Termination1, Termination2, VarMap1),
+ {?list(Contents, Termination, Size), VarMap2};
+t_unify(?product(Types1), ?product(Types2), VarMap) ->
+ {Types, VarMap1} = unify_lists(Types1, Types2, VarMap),
+ {?product(Types), VarMap1};
+t_unify(?tuple(?any, ?any, ?any) = T, ?tuple(?any, ?any, ?any), VarMap) ->
+ {T, VarMap};
+t_unify(?tuple(Elements1, Arity, _),
+ ?tuple(Elements2, Arity, _), VarMap) when Arity =/= ?any ->
+ {NewElements, VarMap1} = unify_lists(Elements1, Elements2, VarMap),
+ {t_tuple(NewElements), VarMap1};
+t_unify(?tuple_set([{Arity, _}]) = T1,
+ ?tuple(_, Arity, _) = T2, VarMap) when Arity =/= ?any ->
+ unify_tuple_set_and_tuple1(T1, T2, VarMap);
+t_unify(?tuple(_, Arity, _) = T1,
+ ?tuple_set([{Arity, _}]) = T2, VarMap) when Arity =/= ?any ->
+ unify_tuple_set_and_tuple2(T1, T2, VarMap);
+t_unify(?tuple_set(List1) = T1, ?tuple_set(List2) = T2, VarMap) ->
+ try
+ unify_lists(lists:append([T || {_Arity, T} <- List1]),
+ lists:append([T || {_Arity, T} <- List2]), VarMap)
+ of
+ {Tuples, NewVarMap} -> {t_sup(Tuples), NewVarMap}
+ catch _:_ -> throw({mismatch, T1, T2})
+ end;
+t_unify(?map(_, ADefK, ADefV) = A, ?map(_, BDefK, BDefV) = B, VarMap0) ->
+ {DefK, VarMap1} = t_unify(ADefK, BDefK, VarMap0),
+ {DefV, VarMap2} = t_unify(ADefV, BDefV, VarMap1),
+ {Pairs, VarMap} =
+ map_pairwise_merge_foldr(
+ fun(K, MNess, V1, MNess, V2, {Pairs0, VarMap3}) ->
+ %% We know that the keys unify and do not contain variables, or they
+ %% would not be singletons
+ %% TODO: Should V=?none (known missing keys) be handled special?
+ {V, VarMap4} = t_unify(V1, V2, VarMap3),
+ {[{K,MNess,V}|Pairs0], VarMap4};
+ (K, _, V1, _, V2, {Pairs0, VarMap3}) ->
+ %% One mandatory and one optional; what should be done in this case?
+ {V, VarMap4} = t_unify(V1, V2, VarMap3),
+ {[{K,?mand,V}|Pairs0], VarMap4}
+ end, {[], VarMap2}, A, B),
+ {t_map(Pairs, DefK, DefV), VarMap};
+t_unify(?opaque(_) = T1, ?opaque(_) = T2, VarMap) ->
+ t_unify(t_opaque_structure(T1), t_opaque_structure(T2), VarMap);
+t_unify(T1, ?opaque(_) = T2, VarMap) ->
+ t_unify(T1, t_opaque_structure(T2), VarMap);
+t_unify(?opaque(_) = T1, T2, VarMap) ->
+ t_unify(t_opaque_structure(T1), T2, VarMap);
+t_unify(T, T, VarMap) ->
+ {T, VarMap};
+t_unify(?union(_)=T1, ?union(_)=T2, VarMap) ->
+ {Type1, Type2} = unify_union2(T1, T2),
+ t_unify(Type1, Type2, VarMap);
+t_unify(?union(_)=T1, T2, VarMap) ->
+ t_unify(unify_union1(T1, T1, T2), T2, VarMap);
+t_unify(T1, ?union(_)=T2, VarMap) ->
+ t_unify(T1, unify_union1(T2, T1, T2), VarMap);
+t_unify(T1, T2, _) ->
+ throw({mismatch, T1, T2}).
+
+unify_union2(?union(List1)=T1, ?union(List2)=T2) ->
+ case {unify_union(List1), unify_union(List2)} of
+ {{yes, Type1}, {yes, Type2}} -> {Type1, Type2};
+ {{yes, Type1}, no} -> {Type1, T2};
+ {no, {yes, Type2}} -> {T1, Type2};
+ {no, no} -> throw({mismatch, T1, T2})
+ end.
+
+unify_union1(?union(List), T1, T2) ->
+ case unify_union(List) of
+ {yes, Type} -> Type;
+ no -> throw({mismatch, T1, T2})
+ end.
+
+unify_union(List) ->
+ [A,B,F,I,L,N,T,M,O,Map] = List,
+ if O =:= ?none -> no;
+ true ->
+ S = t_opaque_structure(O),
+ {yes, t_sup([A,B,F,I,L,N,T,M,S,Map])}
+ end.
+
+-spec is_opaque_type(erl_type(), [erl_type()]) -> boolean().
+
+%% An opaque type is a union of types. Returns true iff any of the type
+%% names (Module and Name) of the first argument (the opaque type to
+%% check) occurs in any of the opaque types of the second argument.
+is_opaque_type(?opaque(Elements), Opaques) ->
+ lists:any(fun(Opaque) -> is_opaque_type2(Opaque, Opaques) end, Elements).
+
+is_opaque_type2(#opaque{mod = Mod1, name = Name1, args = Args1}, Opaques) ->
+ F1 = fun(?opaque(Es)) ->
+ F2 = fun(#opaque{mod = Mod, name = Name, args = Args}) ->
+ is_type_name(Mod1, Name1, Args1, Mod, Name, Args)
+ end,
+ lists:any(F2, Es)
+ end,
+ lists:any(F1, Opaques).
+
+is_type_name(Mod, Name, Args1, Mod, Name, Args2) ->
+ length(Args1) =:= length(Args2);
+is_type_name(_Mod1, _Name1, _Args1, _Mod2, _Name2, _Args2) ->
+ false.
+
+%% Two functions since t_unify is not symmetric.
+unify_tuple_set_and_tuple1(?tuple_set([{Arity, List}]),
+ ?tuple(Elements2, Arity, _), VarMap) ->
+ %% Can only work if the single tuple has variables at correct places.
+ %% Collapse the tuple set.
+ {NewElements, VarMap1} =
+ unify_lists(sup_tuple_elements(List), Elements2, VarMap),
+ {t_tuple(NewElements), VarMap1}.
+
+unify_tuple_set_and_tuple2(?tuple(Elements2, Arity, _),
+ ?tuple_set([{Arity, List}]), VarMap) ->
+ %% Can only work if the single tuple has variables at correct places.
+ %% Collapse the tuple set.
+ {NewElements, VarMap1} =
+ unify_lists(Elements2, sup_tuple_elements(List), VarMap),
+ {t_tuple(NewElements), VarMap1}.
+
+unify_lists(L1, L2, VarMap) ->
+ unify_lists(L1, L2, VarMap, []).
+
+unify_lists([T1|Left1], [T2|Left2], VarMap, Acc) ->
+ {NewT, NewVarMap} = t_unify(T1, T2, VarMap),
+ unify_lists(Left1, Left2, NewVarMap, [NewT|Acc]);
+unify_lists([], [], VarMap, Acc) ->
+ {lists:reverse(Acc), VarMap}.
+
+%%t_assign_variables_to_subtype(T1, T2) ->
+%% try
+%% Dict = assign_vars(T1, T2, dict:new()),
+%% {ok, dict:map(fun(_Param, List) -> t_sup(List) end, Dict)}
+%% catch
+%% throw:error -> error
+%% end.
+
+%%assign_vars(_, ?var(_), _Dict) ->
+%% erlang:error("Variable in right hand side of assignment");
+%%assign_vars(?any, _, Dict) ->
+%% Dict;
+%%assign_vars(?var(_) = Var, Type, Dict) ->
+%% store_var(Var, Type, Dict);
+%%assign_vars(?function(Domain1, Range1), ?function(Domain2, Range2), Dict) ->
+%% DomainList =
+%% case Domain2 of
+%% ?any -> [];
+%% ?product(List) -> List
+%% end,
+%% case any_none([Range2|DomainList]) of
+%% true -> throw(error);
+%% false ->
+%% Dict1 = assign_vars(Domain1, Domain2, Dict),
+%% assign_vars(Range1, Range2, Dict1)
+%% end;
+%%assign_vars(?list(_Contents, _Termination, ?any), ?nil, Dict) ->
+%% Dict;
+%%assign_vars(?list(Contents1, Termination1, Size1),
+%% ?list(Contents2, Termination2, Size2), Dict) ->
+%% Dict1 = assign_vars(Contents1, Contents2, Dict),
+%% Dict2 = assign_vars(Termination1, Termination2, Dict1),
+%% case {Size1, Size2} of
+%% {S, S} -> Dict2;
+%% {?any, ?nonempty_qual} -> Dict2;
+%% {_, _} -> throw(error)
+%% end;
+%%assign_vars(?product(Types1), ?product(Types2), Dict) ->
+%% case length(Types1) =:= length(Types2) of
+%% true -> assign_vars_lists(Types1, Types2, Dict);
+%% false -> throw(error)
+%% end;
+%%assign_vars(?tuple(?any, ?any, ?any), ?tuple(?any, ?any, ?any), Dict) ->
+%% Dict;
+%%assign_vars(?tuple(?any, ?any, ?any), ?tuple(_, _, _), Dict) ->
+%% Dict;
+%%assign_vars(?tuple(Elements1, Arity, _),
+%% ?tuple(Elements2, Arity, _), Dict) when Arity =/= ?any ->
+%% assign_vars_lists(Elements1, Elements2, Dict);
+%%assign_vars(?tuple_set(_) = T, ?tuple_set(List2), Dict) ->
+%% %% All Rhs tuples must already be subtypes of Lhs, so we can take
+%% %% each one separatly.
+%% assign_vars_lists([T || _ <- List2], List2, Dict);
+%%assign_vars(?tuple(?any, ?any, ?any), ?tuple_set(_), Dict) ->
+%% Dict;
+%%assign_vars(?tuple(_, Arity, _) = T1, ?tuple_set(List), Dict) ->
+%% case reduce_tuple_tags(List) of
+%% [Tuple = ?tuple(_, Arity, _)] -> assign_vars(T1, Tuple, Dict);
+%% _ -> throw(error)
+%% end;
+%%assign_vars(?tuple_set(List), ?tuple(_, Arity, Tag) = T2, Dict) ->
+%% case [T || ?tuple(_, Arity1, Tag1) = T <- List,
+%% Arity1 =:= Arity, Tag1 =:= Tag] of
+%% [] -> throw(error);
+%% [T1] -> assign_vars(T1, T2, Dict)
+%% end;
+%%assign_vars(?union(U1), T2, Dict) ->
+%% ?union(U2) = force_union(T2),
+%% assign_vars_lists(U1, U2, Dict);
+%%assign_vars(T, T, Dict) ->
+%% Dict;
+%%assign_vars(T1, T2, Dict) ->
+%% case t_is_subtype(T2, T1) of
+%% false -> throw(error);
+%% true -> Dict
+%% end.
+
+%%assign_vars_lists([T1|Left1], [T2|Left2], Dict) ->
+%% assign_vars_lists(Left1, Left2, assign_vars(T1, T2, Dict));
+%%assign_vars_lists([], [], Dict) ->
+%% Dict.
+
+%%store_var(?var(Id), Type, Dict) ->
+%% case dict:find(Id, Dict) of
+%% error -> dict:store(Id, [Type], Dict);
+%% {ok, _VarType0} -> dict:update(Id, fun(X) -> [Type|X] end, Dict)
+%% end.
+
+%%-----------------------------------------------------------------------------
+%% Subtraction.
+%%
+%% Note that the subtraction is an approximation since we do not have
+%% negative types. Also, tuples and products should be handled using
+%% the cartesian product of the elements, but this is not feasible to
+%% do.
+%%
+%% Example: {a|b,c|d}\{a,d} = {a,c}|{a,d}|{b,c}|{b,d} \ {a,d} =
+%% = {a,c}|{b,c}|{b,d} = {a|b,c|d}
+%%
+%% Instead, we can subtract if all elements but one becomes none after
+%% subtracting element-wise.
+%%
+%% Example: {a|b,c|d}\{a|b,d} = {a,c}|{a,d}|{b,c}|{b,d} \ {a,d}|{b,d} =
+%% = {a,c}|{b,c} = {a|b,c}
+
+-spec t_subtract_list(erl_type(), [erl_type()]) -> erl_type().
+
+t_subtract_list(T1, [T2|Left]) ->
+ t_subtract_list(t_subtract(T1, T2), Left);
+t_subtract_list(T, []) ->
+ T.
+
+-spec t_subtract(erl_type(), erl_type()) -> erl_type().
+
+t_subtract(_, ?any) -> ?none;
+t_subtract(T, ?var(_)) -> T;
+t_subtract(?any, _) -> ?any;
+t_subtract(?var(_) = T, _) -> T;
+t_subtract(T, ?unit) -> T;
+t_subtract(?unit, _) -> ?unit;
+t_subtract(?none, _) -> ?none;
+t_subtract(T, ?none) -> T;
+t_subtract(?atom(Set1), ?atom(Set2)) ->
+ case set_subtract(Set1, Set2) of
+ ?none -> ?none;
+ Set -> ?atom(Set)
+ end;
+t_subtract(?bitstr(U1, B1), ?bitstr(U2, B2)) ->
+ subtract_bin(t_bitstr(U1, B1), t_inf(t_bitstr(U1, B1), t_bitstr(U2, B2)));
+t_subtract(?function(_, _) = T1, ?function(_, _) = T2) ->
+ case t_is_subtype(T1, T2) of
+ true -> ?none;
+ false -> T1
+ end;
+t_subtract(?identifier(Set1), ?identifier(Set2)) ->
+ case set_subtract(Set1, Set2) of
+ ?none -> ?none;
+ Set -> ?identifier(Set)
+ end;
+t_subtract(?opaque(_)=T1, ?opaque(_)=T2) ->
+ opaque_subtract(T1, t_opaque_structure(T2));
+t_subtract(?opaque(_)=T1, T2) ->
+ opaque_subtract(T1, T2);
+t_subtract(T1, ?opaque(_)=T2) ->
+ t_subtract(T1, t_opaque_structure(T2));
+t_subtract(?matchstate(Pres1, Slots1), ?matchstate(Pres2, _Slots2)) ->
+ Pres = t_subtract(Pres1, Pres2),
+ case t_is_none(Pres) of
+ true -> ?none;
+ false -> ?matchstate(Pres, Slots1)
+ end;
+t_subtract(?matchstate(Present, Slots), _) ->
+ ?matchstate(Present, Slots);
+t_subtract(?nil, ?nil) ->
+ ?none;
+t_subtract(?nil, ?nonempty_list(_, _)) ->
+ ?nil;
+t_subtract(?nil, ?list(_, _, _)) ->
+ ?none;
+t_subtract(?list(Contents, Termination, _Size) = T, ?nil) ->
+ case Termination =:= ?nil of
+ true -> ?nonempty_list(Contents, Termination);
+ false -> T
+ end;
+t_subtract(?list(Contents1, Termination1, Size1) = T,
+ ?list(Contents2, Termination2, Size2)) ->
+ case t_is_subtype(Contents1, Contents2) of
+ true ->
+ case t_is_subtype(Termination1, Termination2) of
+ true ->
+ case {Size1, Size2} of
+ {?nonempty_qual, ?unknown_qual} -> ?none;
+ {?unknown_qual, ?nonempty_qual} -> ?nil;
+ {S, S} -> ?none
+ end;
+ false ->
+ %% If the termination is not covered by the subtracted type
+ %% we cannot really say anything about the result.
+ T
+ end;
+ false ->
+ %% All contents must be covered if there is going to be any
+ %% change to the list.
+ T
+ end;
+t_subtract(?float, ?float) -> ?none;
+t_subtract(?number(_, _) = T1, ?float) -> t_inf(T1, t_integer());
+t_subtract(?float, ?number(_Set, Tag)) ->
+ case Tag of
+ ?unknown_qual -> ?none;
+ _ -> ?float
+ end;
+t_subtract(?number(_, _), ?number(?any, ?unknown_qual)) -> ?none;
+t_subtract(?number(_, _) = T1, ?integer(?any)) -> t_inf(?float, T1);
+t_subtract(?int_set(Set1), ?int_set(Set2)) ->
+ case set_subtract(Set1, Set2) of
+ ?none -> ?none;
+ Set -> ?int_set(Set)
+ end;
+t_subtract(?int_range(From1, To1) = T1, ?int_range(_, _) = T2) ->
+ case t_inf(T1, T2) of
+ ?none -> T1;
+ ?int_range(From1, To1) -> ?none;
+ ?int_range(neg_inf, To) -> t_from_range(To + 1, To1);
+ ?int_range(From, pos_inf) -> t_from_range(From1, From - 1);
+ ?int_range(From, To) -> t_sup(t_from_range(From1, From - 1),
+ t_from_range(To + 1, To))
+ end;
+t_subtract(?int_range(From, To) = T1, ?int_set(Set)) ->
+ NewFrom = case set_is_element(From, Set) of
+ true -> From + 1;
+ false -> From
+ end,
+ NewTo = case set_is_element(To, Set) of
+ true -> To - 1;
+ false -> To
+ end,
+ if (NewFrom =:= From) and (NewTo =:= To) -> T1;
+ true -> t_from_range(NewFrom, NewTo)
+ end;
+t_subtract(?int_set(Set), ?int_range(From, To)) ->
+ case set_filter(fun(X) -> not ((X =< From) orelse (X >= To)) end, Set) of
+ ?none -> ?none;
+ NewSet -> ?int_set(NewSet)
+ end;
+t_subtract(?integer(?any) = T1, ?integer(_)) -> T1;
+t_subtract(?number(_, _) = T1, ?number(_, _)) -> T1;
+t_subtract(?tuple(_, _, _), ?tuple(?any, ?any, ?any)) -> ?none;
+t_subtract(?tuple_set(_), ?tuple(?any, ?any, ?any)) -> ?none;
+t_subtract(?tuple(?any, ?any, ?any) = T1, ?tuple_set(_)) -> T1;
+t_subtract(?tuple(Elements1, Arity1, _Tag1) = T1,
+ ?tuple(Elements2, Arity2, _Tag2)) ->
+ if Arity1 =/= Arity2 -> T1;
+ Arity1 =:= Arity2 ->
+ NewElements = t_subtract_lists(Elements1, Elements2),
+ case [E || E <- NewElements, E =/= ?none] of
+ [] -> ?none;
+ [_] -> t_tuple(replace_nontrivial_element(Elements1, NewElements));
+ _ -> T1
+ end
+ end;
+t_subtract(?tuple_set(List1) = T1, ?tuple(_, Arity, _) = T2) ->
+ case orddict:find(Arity, List1) of
+ error -> T1;
+ {ok, List2} ->
+ TuplesLeft0 = [Tuple || {_Arity, Tuple} <- orddict:erase(Arity, List1)],
+ TuplesLeft1 = lists:append(TuplesLeft0),
+ t_sup([t_subtract(L, T2) || L <- List2] ++ TuplesLeft1)
+ end;
+t_subtract(?tuple(_, Arity, _) = T1, ?tuple_set(List1)) ->
+ case orddict:find(Arity, List1) of
+ error -> T1;
+ {ok, List2} -> t_inf([t_subtract(T1, L) || L <- List2])
+ end;
+t_subtract(?tuple_set(_) = T1, ?tuple_set(_) = T2) ->
+ t_sup([t_subtract(T, T2) || T <- t_tuple_subtypes(T1)]);
+t_subtract(?product(Elements1) = T1, ?product(Elements2)) ->
+ Arity1 = length(Elements1),
+ Arity2 = length(Elements2),
+ if Arity1 =/= Arity2 -> T1;
+ Arity1 =:= Arity2 ->
+ NewElements = t_subtract_lists(Elements1, Elements2),
+ case [E || E <- NewElements, E =/= ?none] of
+ [] -> ?none;
+ [_] -> t_product(replace_nontrivial_element(Elements1, NewElements));
+ _ -> T1
+ end
+ end;
+t_subtract(?map(APairs, ADefK, ADefV) = A, ?map(_, BDefK, BDefV) = B) ->
+ case t_is_subtype(ADefK, BDefK) andalso t_is_subtype(ADefV, BDefV) of
+ false -> A;
+ true ->
+ %% We fold over the maps to produce a list of constraints, where
+ %% constraints are additional key-value pairs to put in Pairs. Only one
+ %% constraint need to be applied to produce a type that excludes the
+ %% right-hand-side type, so if more than one constraint is produced, we
+ %% just return the left-hand-side argument.
+ %%
+ %% Each case of the fold may either conclude that
+ %% * The arguments constrain A at least as much as B, i.e. that A so far
+ %% is a subtype of B. In that case they return false
+ %% * That for the particular arguments, A being a subtype of B does not
+ %% hold, but the infinimum of A and B is nonempty, and by narrowing a
+ %% pair in A, we can create a type that excludes some elements in the
+ %% infinumum. In that case, they will return that pair.
+ %% * That for the particular arguments, A being a subtype of B does not
+ %% hold, and either the infinumum of A and B is empty, or it is not
+ %% possible with the current representation to create a type that
+ %% excludes elements from B without also excluding elements that are
+ %% only in A. In that case, it will return the pair from A unchanged.
+ case
+ map_pairwise_merge(
+ %% If V1 is a subtype of V2, the case that K does not exist in A
+ %% remain.
+ fun(K, ?opt, V1, ?mand, V2) -> {K, ?opt, t_subtract(V1, V2)};
+ (K, _, V1, _, V2) ->
+ %% If we subtract an optional key, that leaves a mandatory key
+ case t_subtract(V1, V2) of
+ ?none -> false;
+ Partial -> {K, ?mand, Partial}
+ end
+ end, A, B)
+ of
+ %% We produce a list of keys that are constrained. As only one of
+ %% these should apply at a time, we can't represent the difference if
+ %% more than one constraint is produced. If we applied all of them,
+ %% that would make an underapproximation, which we must not do.
+ [] -> ?none; %% A is a subtype of B
+ [E] -> t_map(mapdict_store(E, APairs), ADefK, ADefV);
+ _ -> A
+ end
+ end;
+t_subtract(?product(P1), _) ->
+ ?product(P1);
+t_subtract(T, ?product(_)) ->
+ T;
+t_subtract(?union(U1), ?union(U2)) ->
+ subtract_union(U1, U2);
+t_subtract(T1, T2) ->
+ ?union(U1) = force_union(T1),
+ ?union(U2) = force_union(T2),
+ subtract_union(U1, U2).
+
+-spec opaque_subtract(erl_type(), erl_type()) -> erl_type().
+
+opaque_subtract(?opaque(Set1), T2) ->
+ List = [T1#opaque{struct = Sub} ||
+ #opaque{struct = S1}=T1 <- set_to_list(Set1),
+ not t_is_none(Sub = t_subtract(S1, T2))],
+ case List of
+ [] -> ?none;
+ _ -> ?opaque(ordsets:from_list(List))
+ end.
+
+-spec t_subtract_lists([erl_type()], [erl_type()]) -> [erl_type()].
+
+t_subtract_lists(L1, L2) ->
+ t_subtract_lists(L1, L2, []).
+
+-spec t_subtract_lists([erl_type()], [erl_type()], [erl_type()]) -> [erl_type()].
+
+t_subtract_lists([T1|Left1], [T2|Left2], Acc) ->
+ t_subtract_lists(Left1, Left2, [t_subtract(T1, T2)|Acc]);
+t_subtract_lists([], [], Acc) ->
+ lists:reverse(Acc).
+
+-spec subtract_union([erl_type(),...], [erl_type(),...]) -> erl_type().
+
+subtract_union(U1, U2) ->
+ [A1,B1,F1,I1,L1,N1,T1,M1,O1,Map1] = U1,
+ [A2,B2,F2,I2,L2,N2,T2,M2,O2,Map2] = U2,
+ List1 = [A1,B1,F1,I1,L1,N1,T1,M1,?none,Map1],
+ List2 = [A2,B2,F2,I2,L2,N2,T2,M2,?none,Map2],
+ Sub1 = subtract_union(List1, List2, 0, []),
+ O = if O1 =:= ?none -> O1;
+ true -> t_subtract(O1, ?union(U2))
+ end,
+ Sub2 = if O2 =:= ?none -> Sub1;
+ true -> t_subtract(Sub1, t_opaque_structure(O2))
+ end,
+ t_sup(O, Sub2).
+
+-spec subtract_union([erl_type()], [erl_type()], non_neg_integer(), [erl_type()]) -> erl_type().
+
+subtract_union([T1|Left1], [T2|Left2], N, Acc) ->
+ case t_subtract(T1, T2) of
+ ?none -> subtract_union(Left1, Left2, N, [?none|Acc]);
+ T -> subtract_union(Left1, Left2, N+1, [T|Acc])
+ end;
+subtract_union([], [], 0, _Acc) ->
+ ?none;
+subtract_union([], [], 1, Acc) ->
+ [T] = [X || X <- Acc, X =/= ?none],
+ T;
+subtract_union([], [], N, Acc) when is_integer(N), N > 1 ->
+ ?union(lists:reverse(Acc)).
+
+replace_nontrivial_element(El1, El2) ->
+ replace_nontrivial_element(El1, El2, []).
+
+replace_nontrivial_element([T1|Left1], [?none|Left2], Acc) ->
+ replace_nontrivial_element(Left1, Left2, [T1|Acc]);
+replace_nontrivial_element([_|Left1], [T2|_], Acc) ->
+ lists:reverse(Acc) ++ [T2|Left1].
+
+subtract_bin(?bitstr(U1, B1), ?bitstr(U1, B1)) ->
+ ?none;
+subtract_bin(?bitstr(U1, B1), ?none) ->
+ t_bitstr(U1, B1);
+subtract_bin(?bitstr(U1, B1), ?bitstr(0, B1)) ->
+ t_bitstr(U1, B1+U1);
+subtract_bin(?bitstr(U1, B1), ?bitstr(U1, B2)) ->
+ if (B1+U1) =/= B2 -> t_bitstr(0, B1);
+ true -> t_bitstr(U1, B1)
+ end;
+subtract_bin(?bitstr(U1, B1), ?bitstr(U2, B2)) ->
+ if (2 * U1) =:= U2 ->
+ if B1 =:= B2 ->
+ t_bitstr(U2, B1+U1);
+ (B1 + U1) =:= B2 ->
+ t_bitstr(U2, B1);
+ true ->
+ t_bitstr(U1, B1)
+ end;
+ true ->
+ t_bitstr(U1, B1)
+ end.
+
+%%-----------------------------------------------------------------------------
+%% Relations
+%%
+
+-spec t_is_equal(erl_type(), erl_type()) -> boolean().
+
+t_is_equal(T, T) -> true;
+t_is_equal(_, _) -> false.
+
+-spec t_is_subtype(erl_type(), erl_type()) -> boolean().
+
+t_is_subtype(T1, T2) ->
+ Inf = t_inf(T1, T2),
+ subtype_is_equal(T1, Inf).
+
+%% The subtype relation has to behave correctly irrespective of opaque
+%% types.
+subtype_is_equal(T, T) -> true;
+subtype_is_equal(T1, T2) ->
+ t_is_equal(case t_contains_opaque(T1) of
+ true -> t_unopaque(T1);
+ false -> T1
+ end,
+ case t_contains_opaque(T2) of
+ true -> t_unopaque(T2);
+ false -> T2
+ end).
+
+-spec t_is_instance(erl_type(), erl_type()) -> boolean().
+
+%% XXX. To be removed.
+t_is_instance(ConcreteType, Type) ->
+ t_is_subtype(ConcreteType, t_unopaque(Type)).
+
+-spec t_do_overlap(erl_type(), erl_type()) -> boolean().
+
+t_do_overlap(TypeA, TypeB) ->
+ not (t_is_none_or_unit(t_inf(TypeA, TypeB))).
+
+-spec t_unopaque(erl_type()) -> erl_type().
+
+t_unopaque(T) ->
+ t_unopaque(T, 'universe').
+
+-spec t_unopaque(erl_type(), opaques()) -> erl_type().
+
+t_unopaque(?opaque(_) = T, Opaques) ->
+ case Opaques =:= 'universe' orelse is_opaque_type(T, Opaques) of
+ true -> t_unopaque(t_opaque_structure(T), Opaques);
+ false -> T
+ end;
+t_unopaque(?list(ElemT, Termination, Sz), Opaques) ->
+ ?list(t_unopaque(ElemT, Opaques), t_unopaque(Termination, Opaques), Sz);
+t_unopaque(?tuple(?any, _, _) = T, _) -> T;
+t_unopaque(?tuple(ArgTs, Sz, Tag), Opaques) when is_list(ArgTs) ->
+ NewArgTs = [t_unopaque(A, Opaques) || A <- ArgTs],
+ ?tuple(NewArgTs, Sz, Tag);
+t_unopaque(?tuple_set(Set), Opaques) ->
+ NewSet = [{Sz, [t_unopaque(T, Opaques) || T <- Tuples]}
+ || {Sz, Tuples} <- Set],
+ ?tuple_set(NewSet);
+t_unopaque(?product(Types), Opaques) ->
+ ?product([t_unopaque(T, Opaques) || T <- Types]);
+t_unopaque(?function(Domain, Range), Opaques) ->
+ ?function(t_unopaque(Domain, Opaques), t_unopaque(Range, Opaques));
+t_unopaque(?union([A,B,F,I,L,N,T,M,O,Map]), Opaques) ->
+ UL = t_unopaque(L, Opaques),
+ UT = t_unopaque(T, Opaques),
+ UF = t_unopaque(F, Opaques),
+ UM = t_unopaque(M, Opaques),
+ UMap = t_unopaque(Map, Opaques),
+ {OF,UO} = case t_unopaque(O, Opaques) of
+ ?opaque(_) = O1 -> {O1, []};
+ Type -> {?none, [Type]}
+ end,
+ t_sup([?union([A,B,UF,I,UL,N,UT,UM,OF,UMap])|UO]);
+t_unopaque(?map(Pairs,DefK,DefV), Opaques) ->
+ t_map([{K, MNess, t_unopaque(V, Opaques)} || {K, MNess, V} <- Pairs],
+ t_unopaque(DefK, Opaques),
+ t_unopaque(DefV, Opaques));
+t_unopaque(T, _) ->
+ T.
+
+%%-----------------------------------------------------------------------------
+%% K-depth abstraction.
+%%
+%% t_limit/2 is the exported function, which checks the type of the
+%% second argument and calls the module local t_limit_k/2 function.
+%%
+
+-spec t_limit(erl_type(), integer()) -> erl_type().
+
+t_limit(Term, K) when is_integer(K) ->
+ t_limit_k(Term, K).
+
+t_limit_k(_, K) when K =< 0 -> ?any;
+t_limit_k(?tuple(?any, ?any, ?any) = T, _K) -> T;
+t_limit_k(?tuple(Elements, Arity, _), K) ->
+ if K =:= 1 -> t_tuple(Arity);
+ true -> t_tuple([t_limit_k(E, K-1) || E <- Elements])
+ end;
+t_limit_k(?tuple_set(_) = T, K) ->
+ t_sup([t_limit_k(Tuple, K) || Tuple <- t_tuple_subtypes(T)]);
+t_limit_k(?list(Elements, Termination, Size), K) ->
+ NewTermination =
+ if K =:= 1 ->
+ %% We do not want to lose the termination information.
+ t_limit_k(Termination, K);
+ true -> t_limit_k(Termination, K - 1)
+ end,
+ NewElements = t_limit_k(Elements, K - 1),
+ TmpList = t_cons(NewElements, NewTermination),
+ case Size of
+ ?nonempty_qual -> TmpList;
+ ?unknown_qual ->
+ ?list(NewElements1, NewTermination1, _) = TmpList,
+ ?list(NewElements1, NewTermination1, ?unknown_qual)
+ end;
+t_limit_k(?function(Domain, Range), K) ->
+ %% The domain is either a product or any() so we do not decrease the K.
+ ?function(t_limit_k(Domain, K), t_limit_k(Range, K-1));
+t_limit_k(?product(Elements), K) ->
+ ?product([t_limit_k(X, K - 1) || X <- Elements]);
+t_limit_k(?union(Elements), K) ->
+ ?union([t_limit_k(X, K) || X <- Elements]);
+t_limit_k(?opaque(Es), K) ->
+ List = [begin
+ NewS = t_limit_k(S, K),
+ Opaque#opaque{struct = NewS}
+ end || #opaque{struct = S} = Opaque <- set_to_list(Es)],
+ ?opaque(ordsets:from_list(List));
+t_limit_k(?map(Pairs0, DefK0, DefV0), K) ->
+ Fun = fun({EK, MNess, EV}, {Exact, DefK1, DefV1}) ->
+ LV = t_limit_k(EV, K - 1),
+ case t_limit_k(EK, K - 1) of
+ EK -> {[{EK,MNess,LV}|Exact], DefK1, DefV1};
+ LK -> {Exact, t_sup(LK, DefK1), t_sup(LV, DefV1)}
+ end
+ end,
+ {Pairs, DefK2, DefV2} = lists:foldr(Fun, {[], DefK0, DefV0}, Pairs0),
+ t_map(Pairs, t_limit_k(DefK2, K - 1), t_limit_k(DefV2, K - 1));
+t_limit_k(T, _K) -> T.
+
+%%============================================================================
+%%
+%% Abstract records. Used for comparing contracts.
+%%
+%%============================================================================
+
+-spec t_abstract_records(erl_type(), type_table()) -> erl_type().
+
+t_abstract_records(?list(Contents, Termination, Size), RecDict) ->
+ case t_abstract_records(Contents, RecDict) of
+ ?none -> ?none;
+ NewContents ->
+ %% Be careful here to make the termination collapse if necessary.
+ case t_abstract_records(Termination, RecDict) of
+ ?nil -> ?list(NewContents, ?nil, Size);
+ ?any -> ?list(NewContents, ?any, Size);
+ Other ->
+ ?list(NewContents2, NewTermination, _) = t_cons(NewContents, Other),
+ ?list(NewContents2, NewTermination, Size)
+ end
+ end;
+t_abstract_records(?function(Domain, Range), RecDict) ->
+ ?function(t_abstract_records(Domain, RecDict),
+ t_abstract_records(Range, RecDict));
+t_abstract_records(?product(Types), RecDict) ->
+ ?product([t_abstract_records(T, RecDict) || T <- Types]);
+t_abstract_records(?union(Types), RecDict) ->
+ t_sup([t_abstract_records(T, RecDict) || T <- Types]);
+t_abstract_records(?tuple(?any, ?any, ?any) = T, _RecDict) ->
+ T;
+t_abstract_records(?tuple(Elements, Arity, ?atom(_) = Tag), RecDict) ->
+ [TagAtom] = atom_vals(Tag),
+ case lookup_record(TagAtom, Arity - 1, RecDict) of
+ error -> t_tuple([t_abstract_records(E, RecDict) || E <- Elements]);
+ {ok, Fields} -> t_tuple([Tag|[T || {_Name, _Abstr, T} <- Fields]])
+ end;
+t_abstract_records(?tuple(Elements, _Arity, _Tag), RecDict) ->
+ t_tuple([t_abstract_records(E, RecDict) || E <- Elements]);
+t_abstract_records(?tuple_set(_) = Tuples, RecDict) ->
+ t_sup([t_abstract_records(T, RecDict) || T <- t_tuple_subtypes(Tuples)]);
+t_abstract_records(?opaque(_)=Type, RecDict) ->
+ t_abstract_records(t_opaque_structure(Type), RecDict);
+t_abstract_records(T, _RecDict) ->
+ T.
+
+%% Map over types. Depth first. Used by the contract checker. ?list is
+%% not fully implemented so take care when changing the type in Termination.
+
+-spec t_map(fun((erl_type()) -> erl_type()), erl_type()) -> erl_type().
+
+t_map(Fun, ?list(Contents, Termination, Size)) ->
+ Fun(?list(t_map(Fun, Contents), t_map(Fun, Termination), Size));
+t_map(Fun, ?function(Domain, Range)) ->
+ Fun(?function(t_map(Fun, Domain), t_map(Fun, Range)));
+t_map(Fun, ?product(Types)) ->
+ Fun(?product([t_map(Fun, T) || T <- Types]));
+t_map(Fun, ?union(Types)) ->
+ Fun(t_sup([t_map(Fun, T) || T <- Types]));
+t_map(Fun, ?tuple(?any, ?any, ?any) = T) ->
+ Fun(T);
+t_map(Fun, ?tuple(Elements, _Arity, _Tag)) ->
+ Fun(t_tuple([t_map(Fun, E) || E <- Elements]));
+t_map(Fun, ?tuple_set(_) = Tuples) ->
+ Fun(t_sup([t_map(Fun, T) || T <- t_tuple_subtypes(Tuples)]));
+t_map(Fun, ?opaque(Set)) ->
+ L = [Opaque#opaque{struct = NewS} ||
+ #opaque{struct = S} = Opaque <- set_to_list(Set),
+ not t_is_none(NewS = t_map(Fun, S))],
+ Fun(case L of
+ [] -> ?none;
+ _ -> ?opaque(ordsets:from_list(L))
+ end);
+t_map(Fun, ?map(Pairs,DefK,DefV)) ->
+ %% TODO:
+ Fun(t_map(Pairs, Fun(DefK), Fun(DefV)));
+t_map(Fun, T) ->
+ Fun(T).
+
+%%=============================================================================
+%%
+%% Prettyprinter
+%%
+%%=============================================================================
+
+-spec t_to_string(erl_type()) -> string().
+
+t_to_string(T) ->
+ t_to_string(T, dict:new()).
+
+-spec t_to_string(erl_type(), type_table()) -> string().
+
+t_to_string(?any, _RecDict) ->
+ "any()";
+t_to_string(?none, _RecDict) ->
+ "none()";
+t_to_string(?unit, _RecDict) ->
+ "no_return()";
+t_to_string(?atom(?any), _RecDict) ->
+ "atom()";
+t_to_string(?atom(Set), _RecDict) ->
+ case set_size(Set) of
+ 2 ->
+ case set_is_element(true, Set) andalso set_is_element(false, Set) of
+ true -> "boolean()";
+ false -> set_to_string(Set)
+ end;
+ _ ->
+ set_to_string(Set)
+ end;
+t_to_string(?bitstr(0, 0), _RecDict) ->
+ "<<>>";
+t_to_string(?bitstr(8, 0), _RecDict) ->
+ "binary()";
+t_to_string(?bitstr(1, 0), _RecDict) ->
+ "bitstring()";
+t_to_string(?bitstr(0, B), _RecDict) ->
+ flat_format("<<_:~w>>", [B]);
+t_to_string(?bitstr(U, 0), _RecDict) ->
+ flat_format("<<_:_*~w>>", [U]);
+t_to_string(?bitstr(U, B), _RecDict) ->
+ flat_format("<<_:~w,_:_*~w>>", [B, U]);
+t_to_string(?function(?any, ?any), _RecDict) ->
+ "fun()";
+t_to_string(?function(?any, Range), RecDict) ->
+ "fun((...) -> " ++ t_to_string(Range, RecDict) ++ ")";
+t_to_string(?function(?product(ArgList), Range), RecDict) ->
+ "fun((" ++ comma_sequence(ArgList, RecDict) ++ ") -> "
+ ++ t_to_string(Range, RecDict) ++ ")";
+t_to_string(?identifier(Set), _RecDict) ->
+ case Set of
+ ?any -> "identifier()";
+ _ ->
+ string:join([flat_format("~w()", [T]) || T <- set_to_list(Set)], " | ")
+ end;
+t_to_string(?opaque(Set), RecDict) ->
+ string:join([opaque_type(Mod, Name, Args, S, RecDict) ||
+ #opaque{mod = Mod, name = Name, struct = S, args = Args}
+ <- set_to_list(Set)],
+ " | ");
+t_to_string(?matchstate(Pres, Slots), RecDict) ->
+ flat_format("ms(~s,~s)", [t_to_string(Pres, RecDict),
+ t_to_string(Slots,RecDict)]);
+t_to_string(?nil, _RecDict) ->
+ "[]";
+t_to_string(?nonempty_list(Contents, Termination), RecDict) ->
+ ContentString = t_to_string(Contents, RecDict),
+ case Termination of
+ ?nil ->
+ case Contents of
+ ?char -> "nonempty_string()";
+ _ -> "["++ContentString++",...]"
+ end;
+ ?any ->
+ %% Just a safety check.
+ case Contents =:= ?any of
+ true -> ok;
+ false ->
+ %% XXX. See comment below.
+ %% erlang:error({illegal_list, ?nonempty_list(Contents, Termination)})
+ ok
+ end,
+ "nonempty_maybe_improper_list()";
+ _ ->
+ case t_is_subtype(t_nil(), Termination) of
+ true ->
+ "nonempty_maybe_improper_list("++ContentString++","
+ ++t_to_string(Termination, RecDict)++")";
+ false ->
+ "nonempty_improper_list("++ContentString++","
+ ++t_to_string(Termination, RecDict)++")"
+ end
+ end;
+t_to_string(?list(Contents, Termination, ?unknown_qual), RecDict) ->
+ ContentString = t_to_string(Contents, RecDict),
+ case Termination of
+ ?nil ->
+ case Contents of
+ ?char -> "string()";
+ _ -> "["++ContentString++"]"
+ end;
+ ?any ->
+ %% Just a safety check.
+ %% XXX. Types such as "maybe_improper_list(integer(), any())"
+ %% are OK, but cannot be printed!?
+ case Contents =:= ?any of
+ true -> ok;
+ false ->
+ ok
+ %% L = ?list(Contents, Termination, ?unknown_qual),
+ %% erlang:error({illegal_list, L})
+ end,
+ "maybe_improper_list()";
+ _ ->
+ case t_is_subtype(t_nil(), Termination) of
+ true ->
+ "maybe_improper_list("++ContentString++","
+ ++t_to_string(Termination, RecDict)++")";
+ false ->
+ "improper_list("++ContentString++","
+ ++t_to_string(Termination, RecDict)++")"
+ end
+ end;
+t_to_string(?int_set(Set), _RecDict) ->
+ set_to_string(Set);
+t_to_string(?byte, _RecDict) -> "byte()";
+t_to_string(?char, _RecDict) -> "char()";
+t_to_string(?integer_pos, _RecDict) -> "pos_integer()";
+t_to_string(?integer_non_neg, _RecDict) -> "non_neg_integer()";
+t_to_string(?integer_neg, _RecDict) -> "neg_integer()";
+t_to_string(?int_range(From, To), _RecDict) ->
+ flat_format("~w..~w", [From, To]);
+t_to_string(?integer(?any), _RecDict) -> "integer()";
+t_to_string(?float, _RecDict) -> "float()";
+t_to_string(?number(?any, ?unknown_qual), _RecDict) -> "number()";
+t_to_string(?product(List), RecDict) ->
+ "<" ++ comma_sequence(List, RecDict) ++ ">";
+t_to_string(?map([],?any,?any), _RecDict) -> "map()";
+t_to_string(?map(Pairs0,DefK,DefV), RecDict) ->
+ {Pairs, ExtraEl} =
+ case {DefK, DefV} of
+ {?none, ?none} -> {Pairs0, []};
+ _ -> {Pairs0 ++ [{DefK,?opt,DefV}], []}
+ end,
+ Tos = fun(T) -> case T of
+ ?any -> "_";
+ _ -> t_to_string(T, RecDict)
+ end end,
+ StrMand = [{Tos(K),Tos(V)}||{K,?mand,V}<-Pairs],
+ StrOpt = [{Tos(K),Tos(V)}||{K,?opt,V}<-Pairs],
+ "#{" ++ string:join([K ++ ":=" ++ V||{K,V}<-StrMand]
+ ++ [K ++ "=>" ++ V||{K,V}<-StrOpt]
+ ++ ExtraEl, ", ") ++ "}";
+t_to_string(?tuple(?any, ?any, ?any), _RecDict) -> "tuple()";
+t_to_string(?tuple(Elements, _Arity, ?any), RecDict) ->
+ "{" ++ comma_sequence(Elements, RecDict) ++ "}";
+t_to_string(?tuple(Elements, Arity, Tag), RecDict) ->
+ [TagAtom] = atom_vals(Tag),
+ case lookup_record(TagAtom, Arity-1, RecDict) of
+ error -> "{" ++ comma_sequence(Elements, RecDict) ++ "}";
+ {ok, FieldNames} ->
+ record_to_string(TagAtom, Elements, FieldNames, RecDict)
+ end;
+t_to_string(?tuple_set(_) = T, RecDict) ->
+ union_sequence(t_tuple_subtypes(T), RecDict);
+t_to_string(?union(Types), RecDict) ->
+ union_sequence([T || T <- Types, T =/= ?none], RecDict);
+t_to_string(?var(Id), _RecDict) when is_atom(Id) ->
+ flat_format("~s", [atom_to_list(Id)]);
+t_to_string(?var(Id), _RecDict) when is_integer(Id) ->
+ flat_format("var(~w)", [Id]).
+
+
+record_to_string(Tag, [_|Fields], FieldNames, RecDict) ->
+ FieldStrings = record_fields_to_string(Fields, FieldNames, RecDict, []),
+ "#" ++ atom_to_string(Tag) ++ "{" ++ string:join(FieldStrings, ",") ++ "}".
+
+record_fields_to_string([F|Fs], [{FName, _Abstr, DefType}|FDefs],
+ RecDict, Acc) ->
+ NewAcc =
+ case
+ t_is_equal(F, t_any()) orelse
+ (t_is_any_atom('undefined', F) andalso
+ not t_is_none(t_inf(F, DefType)))
+ of
+ true -> Acc;
+ false ->
+ StrFV = atom_to_string(FName) ++ "::" ++ t_to_string(F, RecDict),
+ [StrFV|Acc]
+ end,
+ record_fields_to_string(Fs, FDefs, RecDict, NewAcc);
+record_fields_to_string([], [], _RecDict, Acc) ->
+ lists:reverse(Acc).
+
+-spec record_field_diffs_to_string(erl_type(), type_table()) -> string().
+
+record_field_diffs_to_string(?tuple([_|Fs], Arity, Tag), RecDict) ->
+ [TagAtom] = atom_vals(Tag),
+ {ok, FieldNames} = lookup_record(TagAtom, Arity-1, RecDict),
+ %% io:format("RecCElems = ~p\nRecTypes = ~p\n", [Fs, FieldNames]),
+ FieldDiffs = field_diffs(Fs, FieldNames, RecDict, []),
+ string:join(FieldDiffs, " and ").
+
+field_diffs([F|Fs], [{FName, _Abstr, DefType}|FDefs], RecDict, Acc) ->
+ %% Don't care about opacity for now.
+ NewAcc =
+ case not t_is_none(t_inf(F, DefType)) of
+ true -> Acc;
+ false ->
+ Str = atom_to_string(FName) ++ "::" ++ t_to_string(DefType, RecDict),
+ [Str|Acc]
+ end,
+ field_diffs(Fs, FDefs, RecDict, NewAcc);
+field_diffs([], [], _, Acc) ->
+ lists:reverse(Acc).
+
+comma_sequence(Types, RecDict) ->
+ List = [case T =:= ?any of
+ true -> "_";
+ false -> t_to_string(T, RecDict)
+ end || T <- Types],
+ string:join(List, ",").
+
+union_sequence(Types, RecDict) ->
+ List = [t_to_string(T, RecDict) || T <- Types],
+ string:join(List, " | ").
+
+-ifdef(DEBUG).
+opaque_type(Mod, Name, _Args, S, RecDict) ->
+ ArgsString = comma_sequence(_Args, RecDict),
+ String = t_to_string(S, RecDict),
+ opaque_name(Mod, Name, ArgsString) ++ "[" ++ String ++ "]".
+-else.
+opaque_type(Mod, Name, Args, _S, RecDict) ->
+ ArgsString = comma_sequence(Args, RecDict),
+ opaque_name(Mod, Name, ArgsString).
+-endif.
+
+opaque_name(Mod, Name, Extra) ->
+ S = mod_name(Mod, Name),
+ flat_format("~s(~s)", [S, Extra]).
+
+mod_name(Mod, Name) ->
+ flat_format("~w:~w", [Mod, Name]).
+
+%%=============================================================================
+%%
+%% Build a type from parse forms.
+%%
+%%=============================================================================
+
+-type type_names() :: [type_key() | record_key()].
+
+-type mta() :: {module(), atom(), arity()}.
+-type mra() :: {module(), atom(), arity()}.
+-type site() :: {'type', mta()} | {'spec', mfa()} | {'record', mra()}.
+-type cache_key() :: {module(), atom(), expand_depth(),
+ [erl_type()], type_names()}.
+-opaque cache() :: #{cache_key() => {erl_type(), expand_limit()}}.
+
+-spec t_from_form(parse_form(), sets:set(mfa()), site(), mod_records(),
+ var_table(), cache()) -> {erl_type(), cache()}.
+
+t_from_form(Form, ExpTypes, Site, RecDict, VarTab, Cache) ->
+ t_from_form1(Form, ExpTypes, Site, RecDict, VarTab, Cache).
+
+%% Replace external types with with none().
+-spec t_from_form_without_remote(parse_form(), site(), type_table()) ->
+ {erl_type(), cache()}.
+
+t_from_form_without_remote(Form, Site, TypeTable) ->
+ Module = site_module(Site),
+ RecDict = dict:from_list([{Module, TypeTable}]),
+ ExpTypes = replace_by_none,
+ VarTab = var_table__new(),
+ Cache = cache__new(),
+ t_from_form1(Form, ExpTypes, Site, RecDict, VarTab, Cache).
+
+%% REC_TYPE_LIMIT is used for limiting the depth of recursive types.
+%% EXPAND_LIMIT is used for limiting the size of types by
+%% limiting the number of elements of lists within one type form.
+%% EXPAND_DEPTH is used in conjunction with EXPAND_LIMIT to make the
+%% types balanced (unions will otherwise collapse to any()) by limiting
+%% the depth the same way as t_limit/2 does.
+
+-type expand_limit() :: integer().
+
+-type expand_depth() :: integer().
+
+-record(from_form, {site :: site(),
+ xtypes :: sets:set(mfa()) | 'replace_by_none',
+ mrecs :: mod_records(),
+ vtab :: var_table(),
+ tnames :: type_names()}).
+
+-spec t_from_form1(parse_form(), sets:set(mfa()) | 'replace_by_none',
+ site(), mod_records(), var_table(), cache()) ->
+ {erl_type(), cache()}.
+
+t_from_form1(Form, ET, Site, MR, V, C) ->
+ TypeNames = initial_typenames(Site),
+ State = #from_form{site = Site,
+ xtypes = ET,
+ mrecs = MR,
+ vtab = V,
+ tnames = TypeNames},
+ L = ?EXPAND_LIMIT,
+ {T1, L1, C1} = from_form(Form, State, ?EXPAND_DEPTH, L, C),
+ if
+ L1 =< 0 ->
+ from_form_loop(Form, State, 1, L, C1);
+ true ->
+ {T1, C1}
+ end.
+
+initial_typenames({type, _MTA}=Site) -> [Site];
+initial_typenames({spec, _MFA}) -> [];
+initial_typenames({record, _MRA}) -> [].
+
+from_form_loop(Form, State, D, Limit, C) ->
+ {T1, L1, C1} = from_form(Form, State, D, Limit, C),
+ Delta = Limit - L1,
+ if
+ %% Save some time by assuming next depth will exceed the limit.
+ Delta * 8 > Limit ->
+ {T1, C1};
+ true ->
+ D1 = D + 1,
+ from_form_loop(Form, State, D1, Limit, C1)
+ end.
+
+-spec from_form(parse_form(),
+ #from_form{},
+ expand_depth(),
+ expand_limit(),
+ cache()) -> {erl_type(), expand_limit(), cache()}.
+
+%% If there is something wrong with parse_form()
+%% throw({error, io_lib:chars()} is called;
+%% for unknown remote types
+%% self() ! {self(), ext_types, {RemMod, Name, ArgsLen}}
+%% is called, unless 'replace_by_none' is given.
+%%
+%% It is assumed that site_module(S) can be found in MR.
+
+from_form(_, _S, D, L, C) when D =< 0 ; L =< 0 ->
+ {t_any(), L, C};
+from_form({var, _L, '_'}, _S, _D, L, C) ->
+ {t_any(), L, C};
+from_form({var, _L, Name}, S, _D, L, C) ->
+ V = S#from_form.vtab,
+ case maps:find(Name, V) of
+ error -> {t_var(Name), L, C};
+ {ok, Val} -> {Val, L, C}
+ end;
+from_form({ann_type, _L, [_Var, Type]}, S, D, L, C) ->
+ from_form(Type, S, D, L, C);
+from_form({paren_type, _L, [Type]}, S, D, L, C) ->
+ from_form(Type, S, D, L, C);
+from_form({remote_type, _L, [{atom, _, Module}, {atom, _, Type}, Args]},
+ S, D, L, C) ->
+ remote_from_form(Module, Type, Args, S, D, L, C);
+from_form({atom, _L, Atom}, _S, _D, L, C) ->
+ {t_atom(Atom), L, C};
+from_form({integer, _L, Int}, _S, _D, L, C) ->
+ {t_integer(Int), L, C};
+from_form({op, _L, _Op, _Arg} = Op, _S, _D, L, C) ->
+ case erl_eval:partial_eval(Op) of
+ {integer, _, Val} ->
+ {t_integer(Val), L, C};
+ _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])})
+ end;
+from_form({op, _L, _Op, _Arg1, _Arg2} = Op, _S, _D, L, C) ->
+ case erl_eval:partial_eval(Op) of
+ {integer, _, Val} ->
+ {t_integer(Val), L, C};
+ _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])})
+ end;
+from_form({type, _L, any, []}, _S, _D, L, C) ->
+ {t_any(), L, C};
+from_form({type, _L, arity, []}, _S, _D, L, C) ->
+ {t_arity(), L, C};
+from_form({type, _L, atom, []}, _S, _D, L, C) ->
+ {t_atom(), L, C};
+from_form({type, _L, binary, []}, _S, _D, L, C) ->
+ {t_binary(), L, C};
+from_form({type, _L, binary, [Base, Unit]} = Type, _S, _D, L, C) ->
+ case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of
+ {{integer, _, B}, {integer, _, U}} when B >= 0, U >= 0 ->
+ {t_bitstr(U, B), L, C};
+ _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])})
+ end;
+from_form({type, _L, bitstring, []}, _S, _D, L, C) ->
+ {t_bitstr(), L, C};
+from_form({type, _L, bool, []}, _S, _D, L, C) ->
+ {t_boolean(), L, C}; % XXX: Temporarily
+from_form({type, _L, boolean, []}, _S, _D, L, C) ->
+ {t_boolean(), L, C};
+from_form({type, _L, byte, []}, _S, _D, L, C) ->
+ {t_byte(), L, C};
+from_form({type, _L, char, []}, _S, _D, L, C) ->
+ {t_char(), L, C};
+from_form({type, _L, float, []}, _S, _D, L, C) ->
+ {t_float(), L, C};
+from_form({type, _L, function, []}, _S, _D, L, C) ->
+ {t_fun(), L, C};
+from_form({type, _L, 'fun', []}, _S, _D, L, C) ->
+ {t_fun(), L, C};
+from_form({type, _L, 'fun', [{type, _, any}, Range]}, S, D, L, C) ->
+ {T, L1, C1} = from_form(Range, S, D - 1, L - 1, C),
+ {t_fun(T), L1, C1};
+from_form({type, _L, 'fun', [{type, _, product, Domain}, Range]},
+ S, D, L, C) ->
+ {Dom1, L1, C1} = list_from_form(Domain, S, D, L, C),
+ {Ran1, L2, C2} = from_form(Range, S, D, L1, C1),
+ {t_fun(Dom1, Ran1), L2, C2};
+from_form({type, _L, identifier, []}, _S, _D, L, C) ->
+ {t_identifier(), L, C};
+from_form({type, _L, integer, []}, _S, _D, L, C) ->
+ {t_integer(), L, C};
+from_form({type, _L, iodata, []}, _S, _D, L, C) ->
+ {t_iodata(), L, C};
+from_form({type, _L, iolist, []}, _S, _D, L, C) ->
+ {t_iolist(), L, C};
+from_form({type, _L, list, []}, _S, _D, L, C) ->
+ {t_list(), L, C};
+from_form({type, _L, list, [Type]}, S, D, L, C) ->
+ {T, L1, C1} = from_form(Type, S, D - 1, L - 1, C),
+ {t_list(T), L1, C1};
+from_form({type, _L, map, any}, S, D, L, C) ->
+ builtin_type(map, t_map(), S, D, L, C);
+from_form({type, _L, map, List}, S, D0, L, C) ->
+ {Pairs1, L5, C5} =
+ fun PairsFromForm(_, L1, C1) when L1 =< 0 -> {[{?any,?opt,?any}], L1, C1};
+ PairsFromForm([], L1, C1) -> {[], L1, C1};
+ PairsFromForm([{type, _, Oper, [KF, VF]}|T], L1, C1) ->
+ D = D0 - 1,
+ {Key, L2, C2} = from_form(KF, S, D, L1, C1),
+ {Val, L3, C3} = from_form(VF, S, D, L2, C2),
+ {Pairs0, L4, C4} = PairsFromForm(T, L3 - 1, C3),
+ case Oper of
+ map_field_assoc -> {[{Key,?opt, Val}|Pairs0], L4, C4};
+ map_field_exact -> {[{Key,?mand,Val}|Pairs0], L4, C4}
+ end
+ end(List, L, C),
+ try
+ {Pairs, DefK, DefV} = map_from_form(Pairs1, [], [], [], ?none, ?none),
+ {t_map(Pairs, DefK, DefV), L5, C5}
+ catch none -> {t_none(), L5, C5}
+ end;
+from_form({type, _L, mfa, []}, _S, _D, L, C) ->
+ {t_mfa(), L, C};
+from_form({type, _L, module, []}, _S, _D, L, C) ->
+ {t_module(), L, C};
+from_form({type, _L, nil, []}, _S, _D, L, C) ->
+ {t_nil(), L, C};
+from_form({type, _L, neg_integer, []}, _S, _D, L, C) ->
+ {t_neg_integer(), L, C};
+from_form({type, _L, non_neg_integer, []}, _S, _D, L, C) ->
+ {t_non_neg_integer(), L, C};
+from_form({type, _L, no_return, []}, _S, _D, L, C) ->
+ {t_unit(), L, C};
+from_form({type, _L, node, []}, _S, _D, L, C) ->
+ {t_node(), L, C};
+from_form({type, _L, none, []}, _S, _D, L, C) ->
+ {t_none(), L, C};
+from_form({type, _L, nonempty_list, []}, _S, _D, L, C) ->
+ {t_nonempty_list(), L, C};
+from_form({type, _L, nonempty_list, [Type]}, S, D, L, C) ->
+ {T, L1, C1} = from_form(Type, S, D, L - 1, C),
+ {t_nonempty_list(T), L1, C1};
+from_form({type, _L, nonempty_improper_list, [Cont, Term]}, S, D, L, C) ->
+ {T1, L1, C1} = from_form(Cont, S, D, L - 1, C),
+ {T2, L2, C2} = from_form(Term, S, D, L1, C1),
+ {t_cons(T1, T2), L2, C2};
+from_form({type, _L, nonempty_maybe_improper_list, []}, _S, _D, L, C) ->
+ {t_cons(?any, ?any), L, C};
+from_form({type, _L, nonempty_maybe_improper_list, [Cont, Term]},
+ S, D, L, C) ->
+ {T1, L1, C1} = from_form(Cont, S, D, L - 1, C),
+ {T2, L2, C2} = from_form(Term, S, D, L1, C1),
+ {t_cons(T1, T2), L2, C2};
+from_form({type, _L, nonempty_string, []}, _S, _D, L, C) ->
+ {t_nonempty_string(), L, C};
+from_form({type, _L, number, []}, _S, _D, L, C) ->
+ {t_number(), L, C};
+from_form({type, _L, pid, []}, _S, _D, L, C) ->
+ {t_pid(), L, C};
+from_form({type, _L, port, []}, _S, _D, L, C) ->
+ {t_port(), L, C};
+from_form({type, _L, pos_integer, []}, _S, _D, L, C) ->
+ {t_pos_integer(), L, C};
+from_form({type, _L, maybe_improper_list, []}, _S, _D, L, C) ->
+ {t_maybe_improper_list(), L, C};
+from_form({type, _L, maybe_improper_list, [Content, Termination]},
+ S, D, L, C) ->
+ {T1, L1, C1} = from_form(Content, S, D, L - 1, C),
+ {T2, L2, C2} = from_form(Termination, S, D, L1, C1),
+ {t_maybe_improper_list(T1, T2), L2, C2};
+from_form({type, _L, product, Elements}, S, D, L, C) ->
+ {Lst, L1, C1} = list_from_form(Elements, S, D - 1, L, C),
+ {t_product(Lst), L1, C1};
+from_form({type, _L, range, [From, To]} = Type, _S, _D, L, C) ->
+ case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of
+ {{integer, _, FromVal}, {integer, _, ToVal}} ->
+ {t_from_range(FromVal, ToVal), L, C};
+ _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])})
+ end;
+from_form({type, _L, record, [Name|Fields]}, S, D, L, C) ->
+ record_from_form(Name, Fields, S, D, L, C);
+from_form({type, _L, reference, []}, _S, _D, L, C) ->
+ {t_reference(), L, C};
+from_form({type, _L, string, []}, _S, _D, L, C) ->
+ {t_string(), L, C};
+from_form({type, _L, term, []}, _S, _D, L, C) ->
+ {t_any(), L, C};
+from_form({type, _L, timeout, []}, _S, _D, L, C) ->
+ {t_timeout(), L, C};
+from_form({type, _L, tuple, any}, _S, _D, L, C) ->
+ {t_tuple(), L, C};
+from_form({type, _L, tuple, Args}, S, D, L, C) ->
+ {Lst, L1, C1} = list_from_form(Args, S, D - 1, L, C),
+ {t_tuple(Lst), L1, C1};
+from_form({type, _L, union, Args}, S, D, L, C) ->
+ {Lst, L1, C1} = list_from_form(Args, S, D, L, C),
+ {t_sup(Lst), L1, C1};
+from_form({user_type, _L, Name, Args}, S, D, L, C) ->
+ type_from_form(Name, Args, S, D, L, C);
+from_form({type, _L, Name, Args}, S, D, L, C) ->
+ %% Compatibility: modules compiled before Erlang/OTP 18.0.
+ type_from_form(Name, Args, S, D, L, C);
+from_form({opaque, _L, Name, {Mod, Args, Rep}}, _S, _D, L, C) ->
+ %% XXX. To be removed.
+ {t_opaque(Mod, Name, Args, Rep), L, C}.
+
+builtin_type(Name, Type, S, D, L, C) ->
+ #from_form{site = Site, mrecs = MR} = S,
+ M = site_module(Site),
+ case dict:find(M, MR) of
+ {ok, R} ->
+ case lookup_type(Name, 0, R) of
+ {_, {{_M, _FL, _F, _A}, _T}} ->
+ type_from_form(Name, [], S, D, L, C);
+ error ->
+ {Type, L, C}
+ end;
+ error ->
+ {Type, L, C}
+ end.
+
+type_from_form(Name, Args, S, D, L, C) ->
+ #from_form{site = Site, mrecs = MR, tnames = TypeNames} = S,
+ ArgsLen = length(Args),
+ Module = site_module(Site),
+ TypeName = {type, {Module, Name, ArgsLen}},
+ case can_unfold_more(TypeName, TypeNames) of
+ true ->
+ {ok, R} = dict:find(Module, MR),
+ type_from_form1(Name, Args, ArgsLen, R, TypeName, TypeNames,
+ S, D, L, C);
+ false ->
+ {t_any(), L, C}
+ end.
+
+type_from_form1(Name, Args, ArgsLen, R, TypeName, TypeNames, S, D, L, C) ->
+ case lookup_type(Name, ArgsLen, R) of
+ {Tag, {{Module, _FileName, Form, ArgNames}, Type}} ->
+ NewTypeNames = [TypeName|TypeNames],
+ S1 = S#from_form{tnames = NewTypeNames},
+ {ArgTypes, L1, C1} = list_from_form(Args, S1, D, L, C),
+ CKey = cache_key(Module, Name, ArgTypes, TypeNames, D),
+ case cache_find(CKey, C) of
+ {CachedType, DeltaL} ->
+ {CachedType, L1 - DeltaL, C};
+ error ->
+ List = lists:zip(ArgNames, ArgTypes),
+ TmpV = maps:from_list(List),
+ S2 = S1#from_form{site = TypeName, vtab = TmpV},
+ Fun = fun(DD, LL) -> from_form(Form, S2, DD, LL, C1) end,
+ {NewType, L3, C3} =
+ case Tag of
+ type ->
+ recur_limit(Fun, D, L1, TypeName, TypeNames);
+ opaque ->
+ {Rep, L2, C2} = recur_limit(Fun, D, L1, TypeName, TypeNames),
+ Rep1 = choose_opaque_type(Rep, Type),
+ Rep2 = case cannot_have_opaque(Rep1, TypeName, TypeNames) of
+ true -> Rep1;
+ false ->
+ ArgTypes2 = subst_all_vars_to_any_list(ArgTypes),
+ t_opaque(Module, Name, ArgTypes2, Rep1)
+ end,
+ {Rep2, L2, C2}
+ end,
+ C4 = cache_put(CKey, NewType, L1 - L3, C3),
+ {NewType, L3, C4}
+ end;
+ error ->
+ Msg = io_lib:format("Unable to find type ~w/~w\n",
+ [Name, ArgsLen]),
+ throw({error, Msg})
+ end.
+
+remote_from_form(RemMod, Name, Args, S, D, L, C) ->
+ #from_form{xtypes = ET, mrecs = MR, tnames = TypeNames} = S,
+ if
+ ET =:= replace_by_none ->
+ {t_none(), L, C};
+ true ->
+ ArgsLen = length(Args),
+ MFA = {RemMod, Name, ArgsLen},
+ case dict:find(RemMod, MR) of
+ error ->
+ self() ! {self(), ext_types, MFA},
+ {t_any(), L, C};
+ {ok, RemDict} ->
+ case sets:is_element(MFA, ET) of
+ true ->
+ RemType = {type, MFA},
+ case can_unfold_more(RemType, TypeNames) of
+ true ->
+ remote_from_form1(RemMod, Name, Args, ArgsLen, RemDict,
+ RemType, TypeNames, S, D, L, C);
+ false ->
+ {t_any(), L, C}
+ end;
+ false ->
+ self() ! {self(), ext_types, {RemMod, Name, ArgsLen}},
+ {t_any(), L, C}
+ end
+ end
+ end.
+
+remote_from_form1(RemMod, Name, Args, ArgsLen, RemDict, RemType, TypeNames,
+ S, D, L, C) ->
+ case lookup_type(Name, ArgsLen, RemDict) of
+ {Tag, {{Mod, _FileLine, Form, ArgNames}, Type}} ->
+ NewTypeNames = [RemType|TypeNames],
+ S1 = S#from_form{tnames = NewTypeNames},
+ {ArgTypes, L1, C1} = list_from_form(Args, S1, D, L, C),
+ CKey = cache_key(RemMod, Name, ArgTypes, TypeNames, D),
+ %% case error of
+ case cache_find(CKey, C) of
+ {CachedType, DeltaL} ->
+ {CachedType, L - DeltaL, C};
+ error ->
+ List = lists:zip(ArgNames, ArgTypes),
+ TmpVarTab = maps:from_list(List),
+ S2 = S1#from_form{site = RemType, vtab = TmpVarTab},
+ Fun = fun(DD, LL) -> from_form(Form, S2, DD, LL, C1) end,
+ {NewType, L3, C3} =
+ case Tag of
+ type ->
+ recur_limit(Fun, D, L1, RemType, TypeNames);
+ opaque ->
+ {NewRep, L2, C2} = recur_limit(Fun, D, L1, RemType, TypeNames),
+ NewRep1 = choose_opaque_type(NewRep, Type),
+ NewRep2 =
+ case cannot_have_opaque(NewRep1, RemType, TypeNames) of
+ true -> NewRep1;
+ false ->
+ ArgTypes2 = subst_all_vars_to_any_list(ArgTypes),
+ t_opaque(Mod, Name, ArgTypes2, NewRep1)
+ end,
+ {NewRep2, L2, C2}
+ end,
+ C4 = cache_put(CKey, NewType, L1 - L3, C3),
+ {NewType, L3, C4}
+ end;
+ error ->
+ Msg = io_lib:format("Unable to find remote type ~w:~w()\n",
+ [RemMod, Name]),
+ throw({error, Msg})
+ end.
+
+subst_all_vars_to_any_list(Types) ->
+ [subst_all_vars_to_any(Type) || Type <- Types].
+
+%% Opaque types (both local and remote) are problematic when it comes
+%% to the limits (TypeNames, D, and L). The reason is that if any() is
+%% substituted for a more specialized subtype of an opaque type, the
+%% property stated along with decorate_with_opaque() (the type has to
+%% be a subtype of the declared type) no longer holds.
+%%
+%% The less than perfect remedy: if the opaque type created from a
+%% form is not a subset of the declared type, the declared type is
+%% used instead, effectively bypassing the limits, and potentially
+%% resulting in huge types.
+choose_opaque_type(Type, DeclType) ->
+ case
+ t_is_subtype(subst_all_vars_to_any(Type),
+ subst_all_vars_to_any(DeclType))
+ of
+ true -> Type;
+ false -> DeclType
+ end.
+
+record_from_form({atom, _, Name}, ModFields, S, D0, L0, C) ->
+ #from_form{site = Site, mrecs = MR, tnames = TypeNames} = S,
+ RecordType = {record, Name},
+ case can_unfold_more(RecordType, TypeNames) of
+ true ->
+ M = site_module(Site),
+ {ok, R} = dict:find(M, MR),
+ case lookup_record(Name, R) of
+ {ok, DeclFields} ->
+ NewTypeNames = [RecordType|TypeNames],
+ Site1 = {record, {M, Name, length(DeclFields)}},
+ S1 = S#from_form{site = Site1, tnames = NewTypeNames},
+ Fun = fun(D, L) ->
+ {GetModRec, L1, C1} =
+ get_mod_record(ModFields, DeclFields, S1, D, L, C),
+ case GetModRec of
+ {error, FieldName} ->
+ throw({error,
+ io_lib:format("Illegal declaration of #~w{~w}\n",
+ [Name, FieldName])});
+ {ok, NewFields} ->
+ S2 = S1#from_form{vtab = var_table__new()},
+ {NewFields1, L2, C2} =
+ fields_from_form(NewFields, S2, D, L1, C1),
+ Rec = t_tuple(
+ [t_atom(Name)|[Type
+ || {_FieldName, Type} <- NewFields1]]),
+ {Rec, L2, C2}
+ end
+ end,
+ recur_limit(Fun, D0, L0, RecordType, TypeNames);
+ error ->
+ throw({error, io_lib:format("Unknown record #~w{}\n", [Name])})
+ end;
+ false ->
+ {t_any(), L0, C}
+ end.
+
+get_mod_record([], DeclFields, _S, _D, L, C) ->
+ {{ok, DeclFields}, L, C};
+get_mod_record(ModFields, DeclFields, S, D, L, C) ->
+ DeclFieldsDict = lists:keysort(1, DeclFields),
+ {ModFieldsDict, L1, C1} = build_field_dict(ModFields, S, D, L, C),
+ case get_mod_record_types(DeclFieldsDict, ModFieldsDict, []) of
+ {error, _FieldName} = Error -> {Error, L1, C1};
+ {ok, FinalKeyDict} ->
+ Fields = [lists:keyfind(FieldName, 1, FinalKeyDict)
+ || {FieldName, _, _} <- DeclFields],
+ {{ok, Fields}, L1, C1}
+ end.
+
+build_field_dict(FieldTypes, S, D, L, C) ->
+ build_field_dict(FieldTypes, S, D, L, C, []).
+
+build_field_dict([{type, _, field_type, [{atom, _, Name}, Type]}|Left],
+ S, D, L, C, Acc) ->
+ {T, L1, C1} = from_form(Type, S, D, L - 1, C),
+ NewAcc = [{Name, Type, T}|Acc],
+ build_field_dict(Left, S, D, L1, C1, NewAcc);
+build_field_dict([], _S, _D, L, C, Acc) ->
+ {lists:keysort(1, Acc), L, C}.
+
+get_mod_record_types([{FieldName, _Abstr, _DeclType}|Left1],
+ [{FieldName, TypeForm, ModType}|Left2],
+ Acc) ->
+ get_mod_record_types(Left1, Left2, [{FieldName, TypeForm, ModType}|Acc]);
+get_mod_record_types([{FieldName1, _Abstr, _DeclType} = DT|Left1],
+ [{FieldName2, _FormType, _ModType}|_] = List2,
+ Acc) when FieldName1 < FieldName2 ->
+ get_mod_record_types(Left1, List2, [DT|Acc]);
+get_mod_record_types(Left1, [], Acc) ->
+ {ok, lists:keysort(1, Left1++Acc)};
+get_mod_record_types(_, [{FieldName2, _FormType, _ModType}|_], _Acc) ->
+ {error, FieldName2}.
+
+%% It is important to create a limited version of the record type
+%% since nested record types can otherwise easily result in huge
+%% terms.
+fields_from_form([], _S, _D, L, C) ->
+ {[], L, C};
+fields_from_form([{Name, Abstr, _Type}|Tail], S, D, L, C) ->
+ {T, L1, C1} = from_form(Abstr, S, D, L, C),
+ {F, L2, C2} = fields_from_form(Tail, S, D, L1, C1),
+ {[{Name, T}|F], L2, C2}.
+
+list_from_form([], _S, _D, L, C) ->
+ {[], L, C};
+list_from_form([H|Tail], S, D, L, C) ->
+ {H1, L1, C1} = from_form(H, S, D, L - 1, C),
+ {T1, L2, C2} = list_from_form(Tail, S, D, L1, C1),
+ {[H1|T1], L2, C2}.
+
+%% Sorts, combines non-singleton pairs, and applies precendence and
+%% mandatoriness rules.
+map_from_form([], ShdwPs, MKs, Pairs, DefK, DefV) ->
+ verify_possible(MKs, ShdwPs),
+ {promote_to_mand(MKs, Pairs), DefK, DefV};
+map_from_form([{SKey,MNess,Val}|SPairs], ShdwPs0, MKs0, Pairs0, DefK0, DefV0) ->
+ Key = lists:foldl(fun({K,_},S)->t_subtract(S,K)end, SKey, ShdwPs0),
+ ShdwPs = case Key of ?none -> ShdwPs0; _ -> [{Key,Val}|ShdwPs0] end,
+ MKs = case MNess of ?mand -> [SKey|MKs0]; ?opt -> MKs0 end,
+ if MNess =:= ?mand, SKey =:= ?none -> throw(none);
+ true -> ok
+ end,
+ {Pairs, DefK, DefV} =
+ case is_singleton_type(Key) of
+ true ->
+ MNess1 = case Val =:= ?none of true -> ?opt; false -> MNess end,
+ {mapdict_insert({Key,MNess1,Val}, Pairs0), DefK0, DefV0};
+ false ->
+ case Key =:= ?none orelse Val =:= ?none of
+ true -> {Pairs0, DefK0, DefV0};
+ false -> {Pairs0, t_sup(DefK0, Key), t_sup(DefV0, Val)}
+ end
+ end,
+ map_from_form(SPairs, ShdwPs, MKs, Pairs, DefK, DefV).
+
+%% Verifies that all mandatory keys are possible, throws 'none' otherwise
+verify_possible(MKs, ShdwPs) ->
+ lists:foreach(fun(M) -> verify_possible_1(M, ShdwPs) end, MKs).
+
+verify_possible_1(M, ShdwPs) ->
+ case lists:any(fun({K,_}) -> t_inf(M, K) =/= ?none end, ShdwPs) of
+ true -> ok;
+ false -> throw(none)
+ end.
+
+-spec promote_to_mand([erl_type()], t_map_dict()) -> t_map_dict().
+
+promote_to_mand(_, []) -> [];
+promote_to_mand(MKs, [E={K,_,V}|T]) ->
+ [case lists:any(fun(M) -> t_is_equal(K,M) end, MKs) of
+ true -> {K, ?mand, V};
+ false -> E
+ end|promote_to_mand(MKs, T)].
+
+-define(RECUR_EXPAND_LIMIT, 10).
+-define(RECUR_EXPAND_DEPTH, 2).
+
+%% If more of the limited resources is spent on the non-recursive
+%% forms, more warnings are found. And the analysis is also a bit
+%% faster.
+%%
+%% Setting REC_TYPE_LIMIT to 1 would work also work well.
+
+recur_limit(Fun, D, L, _, _) when L =< ?RECUR_EXPAND_DEPTH,
+ D =< ?RECUR_EXPAND_LIMIT ->
+ Fun(D, L);
+recur_limit(Fun, D, L, TypeName, TypeNames) ->
+ case is_recursive(TypeName, TypeNames) of
+ true ->
+ {T, L1, C1} = Fun(?RECUR_EXPAND_DEPTH, ?RECUR_EXPAND_LIMIT),
+ {T, L - L1, C1};
+ false ->
+ Fun(D, L)
+ end.
+
+-spec t_check_record_fields(parse_form(), sets:set(mfa()), site(),
+ mod_records(), var_table(), cache()) -> cache().
+
+t_check_record_fields(Form, ExpTypes, Site, RecDict, VarTable, Cache) ->
+ State = #from_form{site = Site,
+ xtypes = ExpTypes,
+ mrecs = RecDict,
+ vtab = VarTable,
+ tnames = []},
+ check_record_fields(Form, State, Cache).
+
+-spec check_record_fields(parse_form(), #from_form{}, cache()) -> cache().
+
+%% If there is something wrong with parse_form()
+%% throw({error, io_lib:chars()} is called.
+
+check_record_fields({var, _L, _}, _S, C) -> C;
+check_record_fields({ann_type, _L, [_Var, Type]}, S, C) ->
+ check_record_fields(Type, S, C);
+check_record_fields({paren_type, _L, [Type]}, S, C) ->
+ check_record_fields(Type, S, C);
+check_record_fields({remote_type, _L, [{atom, _, _}, {atom, _, _}, Args]},
+ S, C) ->
+ list_check_record_fields(Args, S, C);
+check_record_fields({atom, _L, _}, _S, C) -> C;
+check_record_fields({integer, _L, _}, _S, C) -> C;
+check_record_fields({op, _L, _Op, _Arg}, _S, C) -> C;
+check_record_fields({op, _L, _Op, _Arg1, _Arg2}, _S, C) -> C;
+check_record_fields({type, _L, tuple, any}, _S, C) -> C;
+check_record_fields({type, _L, map, any}, _S, C) -> C;
+check_record_fields({type, _L, binary, [_Base, _Unit]}, _S, C) -> C;
+check_record_fields({type, _L, 'fun', [{type, _, any}, Range]}, S, C) ->
+ check_record_fields(Range, S, C);
+check_record_fields({type, _L, range, [_From, _To]}, _S, C) -> C;
+check_record_fields({type, _L, record, [Name|Fields]}, S, C) ->
+ check_record(Name, Fields, S, C);
+check_record_fields({type, _L, _, Args}, S, C) ->
+ list_check_record_fields(Args, S, C);
+check_record_fields({user_type, _L, _Name, Args}, S, C) ->
+ list_check_record_fields(Args, S, C).
+
+check_record({atom, _, Name}, ModFields, S, C) ->
+ #from_form{site = Site, mrecs = MR} = S,
+ M = site_module(Site),
+ {ok, R} = dict:find(M, MR),
+ {ok, DeclFields} = lookup_record(Name, R),
+ case check_fields(Name, ModFields, DeclFields, S, C) of
+ {error, FieldName} ->
+ throw({error, io_lib:format("Illegal declaration of #~w{~w}\n",
+ [Name, FieldName])});
+ C1 -> C1
+ end.
+
+check_fields(RecName, [{type, _, field_type, [{atom, _, Name}, Abstr]}|Left],
+ DeclFields, S, C) ->
+ #from_form{site = Site0, xtypes = ET, mrecs = MR, vtab = V} = S,
+ M = site_module(Site0),
+ Site = {record, {M, RecName, length(DeclFields)}},
+ {Type, C1} = t_from_form(Abstr, ET, Site, MR, V, C),
+ {Name, _, DeclType} = lists:keyfind(Name, 1, DeclFields),
+ TypeNoVars = subst_all_vars_to_any(Type),
+ case t_is_subtype(TypeNoVars, DeclType) of
+ false -> {error, Name};
+ true -> check_fields(RecName, Left, DeclFields, S, C1)
+ end;
+check_fields(_RecName, [], _Decl, _S, C) ->
+ C.
+
+list_check_record_fields([], _S, C) ->
+ C;
+list_check_record_fields([H|Tail], S, C) ->
+ C1 = check_record_fields(H, S, C),
+ list_check_record_fields(Tail, S, C1).
+
+site_module({_, {Module, _, _}}) ->
+ Module.
+
+-spec cache__new() -> cache().
+
+cache__new() ->
+ maps:new().
+
+-spec cache_key(module(), atom(), [erl_type()],
+ type_names(), expand_depth()) -> cache_key().
+
+%% If TypeNames is left out from the key, the cache is smaller, and
+%% the form-to-type translation is faster. But it would be a shame if,
+%% for example, any() is used, where a more complex type should be
+%% used. There is also a slight risk of creating unnecessarily big
+%% types.
+
+cache_key(Module, Name, ArgTypes, TypeNames, D) ->
+ {Module, Name, D, ArgTypes, TypeNames}.
+
+-spec cache_find(cache_key(), cache()) ->
+ {erl_type(), expand_limit()} | 'error'.
+
+cache_find(Key, Cache) ->
+ case maps:find(Key, Cache) of
+ {ok, Value} ->
+ Value;
+ error ->
+ error
+ end.
+
+-spec cache_put(cache_key(), erl_type(), expand_limit(), cache()) -> cache().
+
+cache_put(_Key, _Type, DeltaL, Cache) when DeltaL < 0 ->
+ %% The type is truncated; do not reuse it.
+ Cache;
+cache_put(Key, Type, DeltaL, Cache) ->
+ maps:put(Key, {Type, DeltaL}, Cache).
+
+-spec t_var_names([erl_type()]) -> [atom()].
+
+t_var_names([{var, _, Name}|L]) when L =/= '_' ->
+ [Name|t_var_names(L)];
+t_var_names([]) ->
+ [].
+
+-spec t_form_to_string(parse_form()) -> string().
+
+t_form_to_string({var, _L, '_'}) -> "_";
+t_form_to_string({var, _L, Name}) -> atom_to_list(Name);
+t_form_to_string({atom, _L, Atom}) ->
+ io_lib:write_string(atom_to_list(Atom), $'); % To quote or not to quote... '
+t_form_to_string({integer, _L, Int}) -> integer_to_list(Int);
+t_form_to_string({op, _L, _Op, _Arg} = Op) ->
+ case erl_eval:partial_eval(Op) of
+ {integer, _, _} = Int -> t_form_to_string(Int);
+ _ -> io_lib:format("Badly formed type ~w", [Op])
+ end;
+t_form_to_string({op, _L, _Op, _Arg1, _Arg2} = Op) ->
+ case erl_eval:partial_eval(Op) of
+ {integer, _, _} = Int -> t_form_to_string(Int);
+ _ -> io_lib:format("Badly formed type ~w", [Op])
+ end;
+t_form_to_string({ann_type, _L, [Var, Type]}) ->
+ t_form_to_string(Var) ++ "::" ++ t_form_to_string(Type);
+t_form_to_string({paren_type, _L, [Type]}) ->
+ flat_format("(~s)", [t_form_to_string(Type)]);
+t_form_to_string({remote_type, _L, [{atom, _, Mod}, {atom, _, Name}, Args]}) ->
+ ArgString = "(" ++ string:join(t_form_to_string_list(Args), ",") ++ ")",
+ flat_format("~w:~w", [Mod, Name]) ++ ArgString;
+t_form_to_string({type, _L, arity, []}) -> "arity()";
+t_form_to_string({type, _L, binary, []}) -> "binary()";
+t_form_to_string({type, _L, binary, [Base, Unit]} = Type) ->
+ case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of
+ {{integer, _, B}, {integer, _, U}} ->
+ %% the following mirrors the clauses of t_to_string/2
+ case {U, B} of
+ {0, 0} -> "<<>>";
+ {8, 0} -> "binary()";
+ {1, 0} -> "bitstring()";
+ {0, B} -> flat_format("<<_:~w>>", [B]);
+ {U, 0} -> flat_format("<<_:_*~w>>", [U]);
+ {U, B} -> flat_format("<<_:~w,_:_*~w>>", [B, U])
+ end;
+ _ -> io_lib:format("Badly formed bitstr type ~w", [Type])
+ end;
+t_form_to_string({type, _L, bitstring, []}) -> "bitstring()";
+t_form_to_string({type, _L, 'fun', []}) -> "fun()";
+t_form_to_string({type, _L, 'fun', [{type, _, any}, Range]}) ->
+ "fun(...) -> " ++ t_form_to_string(Range);
+t_form_to_string({type, _L, 'fun', [{type, _, product, Domain}, Range]}) ->
+ "fun((" ++ string:join(t_form_to_string_list(Domain), ",") ++ ") -> "
+ ++ t_form_to_string(Range) ++ ")";
+t_form_to_string({type, _L, iodata, []}) -> "iodata()";
+t_form_to_string({type, _L, iolist, []}) -> "iolist()";
+t_form_to_string({type, _L, list, [Type]}) ->
+ "[" ++ t_form_to_string(Type) ++ "]";
+t_form_to_string({type, _L, map, any}) -> "map()";
+t_form_to_string({type, _L, map, Args}) ->
+ "#{" ++ string:join(t_form_to_string_list(Args), ",") ++ "}";
+t_form_to_string({type, _L, map_field_assoc, [Key, Val]}) ->
+ t_form_to_string(Key) ++ "=>" ++ t_form_to_string(Val);
+t_form_to_string({type, _L, map_field_exact, [Key, Val]}) ->
+ t_form_to_string(Key) ++ ":=" ++ t_form_to_string(Val);
+t_form_to_string({type, _L, mfa, []}) -> "mfa()";
+t_form_to_string({type, _L, module, []}) -> "module()";
+t_form_to_string({type, _L, node, []}) -> "node()";
+t_form_to_string({type, _L, nonempty_list, [Type]}) ->
+ "[" ++ t_form_to_string(Type) ++ ",...]";
+t_form_to_string({type, _L, nonempty_string, []}) -> "nonempty_string()";
+t_form_to_string({type, _L, product, Elements}) ->
+ "<" ++ string:join(t_form_to_string_list(Elements), ",") ++ ">";
+t_form_to_string({type, _L, range, [From, To]} = Type) ->
+ case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of
+ {{integer, _, FromVal}, {integer, _, ToVal}} ->
+ flat_format("~w..~w", [FromVal, ToVal]);
+ _ -> flat_format("Badly formed type ~w",[Type])
+ end;
+t_form_to_string({type, _L, record, [{atom, _, Name}]}) ->
+ flat_format("#~w{}", [Name]);
+t_form_to_string({type, _L, record, [{atom, _, Name}|Fields]}) ->
+ FieldString = string:join(t_form_to_string_list(Fields), ","),
+ flat_format("#~w{~s}", [Name, FieldString]);
+t_form_to_string({type, _L, field_type, [{atom, _, Name}, Type]}) ->
+ flat_format("~w::~s", [Name, t_form_to_string(Type)]);
+t_form_to_string({type, _L, term, []}) -> "term()";
+t_form_to_string({type, _L, timeout, []}) -> "timeout()";
+t_form_to_string({type, _L, tuple, any}) -> "tuple()";
+t_form_to_string({type, _L, tuple, Args}) ->
+ "{" ++ string:join(t_form_to_string_list(Args), ",") ++ "}";
+t_form_to_string({type, _L, union, Args}) ->
+ string:join(t_form_to_string_list(Args), " | ");
+t_form_to_string({type, _L, Name, []} = T) ->
+ try
+ M = mod,
+ D0 = dict:new(),
+ MR = dict:from_list([{M, D0}]),
+ Site = {type, {M,Name,0}},
+ V = var_table__new(),
+ C = cache__new(),
+ State = #from_form{site = Site,
+ xtypes = sets:new(),
+ mrecs = MR,
+ vtab = V,
+ tnames = []},
+ {T1, _, _} = from_form(T, State, _Deep=1000, _ALot=1000000, C),
+ t_to_string(T1)
+ catch throw:{error, _} -> atom_to_string(Name) ++ "()"
+ end;
+t_form_to_string({user_type, _L, Name, List}) ->
+ flat_format("~w(~s)",
+ [Name, string:join(t_form_to_string_list(List), ",")]);
+t_form_to_string({type, L, Name, List}) ->
+ %% Compatibility: modules compiled before Erlang/OTP 18.0.
+ t_form_to_string({user_type, L, Name, List}).
+
+t_form_to_string_list(List) ->
+ t_form_to_string_list(List, []).
+
+t_form_to_string_list([H|T], Acc) ->
+ t_form_to_string_list(T, [t_form_to_string(H)|Acc]);
+t_form_to_string_list([], Acc) ->
+ lists:reverse(Acc).
+
+-spec atom_to_string(atom()) -> string().
+
+atom_to_string(Atom) ->
+ flat_format("~w", [Atom]).
+
+%%=============================================================================
+%%
+%% Utilities
+%%
+%%=============================================================================
+
+-spec any_none([erl_type()]) -> boolean().
+
+any_none([?none|_Left]) -> true;
+any_none([_|Left]) -> any_none(Left);
+any_none([]) -> false.
+
+-spec any_none_or_unit([erl_type()]) -> boolean().
+
+any_none_or_unit([?none|_]) -> true;
+any_none_or_unit([?unit|_]) -> true;
+any_none_or_unit([_|Left]) -> any_none_or_unit(Left);
+any_none_or_unit([]) -> false.
+
+-spec is_erl_type(any()) -> boolean().
+
+is_erl_type(?any) -> true;
+is_erl_type(?none) -> true;
+is_erl_type(?unit) -> true;
+is_erl_type(#c{}) -> true;
+is_erl_type(_) -> false.
+
+-spec lookup_record(atom(), type_table()) ->
+ 'error' | {'ok', [{atom(), parse_form(), erl_type()}]}.
+
+lookup_record(Tag, RecDict) when is_atom(Tag) ->
+ case dict:find({record, Tag}, RecDict) of
+ {ok, {_FileLine, [{_Arity, Fields}]}} ->
+ {ok, Fields};
+ {ok, {_FileLine, List}} when is_list(List) ->
+ %% This will have to do, since we do not know which record we
+ %% are looking for.
+ error;
+ error ->
+ error
+ end.
+
+-spec lookup_record(atom(), arity(), type_table()) ->
+ 'error' | {'ok', [{atom(), parse_form(), erl_type()}]}.
+
+lookup_record(Tag, Arity, RecDict) when is_atom(Tag) ->
+ case dict:find({record, Tag}, RecDict) of
+ {ok, {_FileLine, [{Arity, Fields}]}} -> {ok, Fields};
+ {ok, {_FileLine, OrdDict}} -> orddict:find(Arity, OrdDict);
+ error -> error
+ end.
+
+-spec lookup_type(_, _, _) -> {'type' | 'opaque', type_value()} | 'error'.
+lookup_type(Name, Arity, RecDict) ->
+ case dict:find({type, Name, Arity}, RecDict) of
+ error ->
+ case dict:find({opaque, Name, Arity}, RecDict) of
+ error -> error;
+ {ok, Found} -> {opaque, Found}
+ end;
+ {ok, Found} -> {type, Found}
+ end.
+
+-spec type_is_defined('type' | 'opaque', atom(), arity(), type_table()) ->
+ boolean().
+
+type_is_defined(TypeOrOpaque, Name, Arity, RecDict) ->
+ dict:is_key({TypeOrOpaque, Name, Arity}, RecDict).
+
+cannot_have_opaque(Type, TypeName, TypeNames) ->
+ t_is_none(Type) orelse is_recursive(TypeName, TypeNames).
+
+is_recursive(TypeName, TypeNames) ->
+ lists:member(TypeName, TypeNames).
+
+can_unfold_more(TypeName, TypeNames) ->
+ Fun = fun(E, Acc) -> case E of TypeName -> Acc + 1; _ -> Acc end end,
+ lists:foldl(Fun, 0, TypeNames) < ?REC_TYPE_LIMIT.
+
+-spec do_opaque(erl_type(), opaques(), fun((_) -> T)) -> T.
+
+%% Probably a little faster than calling t_unopaque/2.
+%% Unions that are due to opaque types are unopaqued.
+do_opaque(?opaque(_) = Type, Opaques, Pred) ->
+ case Opaques =:= 'universe' orelse is_opaque_type(Type, Opaques) of
+ true -> do_opaque(t_opaque_structure(Type), Opaques, Pred);
+ false -> Pred(Type)
+ end;
+do_opaque(?union(List) = Type, Opaques, Pred) ->
+ [A,B,F,I,L,N,T,M,O,Map] = List,
+ if O =:= ?none -> Pred(Type);
+ true ->
+ case Opaques =:= 'universe' orelse is_opaque_type(O, Opaques) of
+ true ->
+ S = t_opaque_structure(O),
+ do_opaque(t_sup([A,B,F,I,L,N,T,M,S,Map]), Opaques, Pred);
+ false -> Pred(Type)
+ end
+ end;
+do_opaque(Type, _Opaques, Pred) ->
+ Pred(Type).
+
+map_all_values(?map(Pairs,_,DefV)) ->
+ [DefV|[V || {V, _, _} <- Pairs]].
+
+map_all_keys(?map(Pairs,DefK,_)) ->
+ [DefK|[K || {_, _, K} <- Pairs]].
+
+map_all_types(M) ->
+ map_all_keys(M) ++ map_all_values(M).
+
+%% Tests if a type has exactly one possible value.
+-spec t_is_singleton(erl_type()) -> boolean().
+
+t_is_singleton(Type) ->
+ t_is_singleton(Type, 'universe').
+
+-spec t_is_singleton(erl_type(), opaques()) -> boolean().
+
+t_is_singleton(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun is_singleton_type/1).
+
+%% Incomplete; not all representable singleton types are included.
+is_singleton_type(?nil) -> true;
+is_singleton_type(?atom(?any)) -> false;
+is_singleton_type(?atom(Set)) ->
+ ordsets:size(Set) =:= 1;
+is_singleton_type(?int_range(V, V)) -> true;
+is_singleton_type(?int_set(Set)) ->
+ ordsets:size(Set) =:= 1;
+is_singleton_type(?tuple(Types, Arity, _)) when is_integer(Arity) ->
+ lists:all(fun is_singleton_type/1, Types);
+is_singleton_type(?tuple_set([{Arity, [OnlyTuple]}])) when is_integer(Arity) ->
+ is_singleton_type(OnlyTuple);
+is_singleton_type(?map(Pairs, ?none, ?none)) ->
+ lists:all(fun({_,MNess,V}) -> MNess =:= ?mand andalso is_singleton_type(V)
+ end, Pairs);
+is_singleton_type(_) ->
+ false.
+
+%% Returns the only possible value of a singleton type.
+-spec t_singleton_to_term(erl_type(), opaques()) -> term().
+
+t_singleton_to_term(Type, Opaques) ->
+ do_opaque(Type, Opaques, fun singleton_type_to_term/1).
+
+singleton_type_to_term(?nil) -> [];
+singleton_type_to_term(?atom(Set)) when Set =/= ?any ->
+ case ordsets:size(Set) of
+ 1 -> hd(ordsets:to_list(Set));
+ _ -> error(badarg)
+ end;
+singleton_type_to_term(?int_range(V, V)) -> V;
+singleton_type_to_term(?int_set(Set)) ->
+ case ordsets:size(Set) of
+ 1 -> hd(ordsets:to_list(Set));
+ _ -> error(badarg)
+ end;
+singleton_type_to_term(?tuple(Types, Arity, _)) when is_integer(Arity) ->
+ lists:map(fun singleton_type_to_term/1, Types);
+singleton_type_to_term(?tuple_set([{Arity, [OnlyTuple]}]))
+ when is_integer(Arity) ->
+ singleton_type_to_term(OnlyTuple);
+singleton_type_to_term(?map(Pairs, ?none, ?none)) ->
+ maps:from_list([{singleton_type_to_term(K), singleton_type_to_term(V)}
+ || {K,?mand,V} <- Pairs]).
+
+%% -----------------------------------
+%% Set
+%%
+
+set_singleton(Element) ->
+ ordsets:from_list([Element]).
+
+set_is_singleton(Element, Set) ->
+ set_singleton(Element) =:= Set.
+
+set_is_element(Element, Set) ->
+ ordsets:is_element(Element, Set).
+
+set_union(?any, _) -> ?any;
+set_union(_, ?any) -> ?any;
+set_union(S1, S2) ->
+ case ordsets:union(S1, S2) of
+ S when length(S) =< ?SET_LIMIT -> S;
+ _ -> ?any
+ end.
+
+%% The intersection and subtraction can return ?none.
+%% This should always be handled right away since ?none is not a valid set.
+%% However, ?any is considered a valid set.
+
+set_intersection(?any, S) -> S;
+set_intersection(S, ?any) -> S;
+set_intersection(S1, S2) ->
+ case ordsets:intersection(S1, S2) of
+ [] -> ?none;
+ S -> S
+ end.
+
+set_subtract(_, ?any) -> ?none;
+set_subtract(?any, _) -> ?any;
+set_subtract(S1, S2) ->
+ case ordsets:subtract(S1, S2) of
+ [] -> ?none;
+ S -> S
+ end.
+
+set_from_list(List) ->
+ case length(List) of
+ L when L =< ?SET_LIMIT -> ordsets:from_list(List);
+ L when L > ?SET_LIMIT -> ?any
+ end.
+
+set_to_list(Set) ->
+ ordsets:to_list(Set).
+
+set_filter(Fun, Set) ->
+ case ordsets:filter(Fun, Set) of
+ [] -> ?none;
+ NewSet -> NewSet
+ end.
+
+set_size(Set) ->
+ ordsets:size(Set).
+
+set_to_string(Set) ->
+ L = [case is_atom(X) of
+ true -> io_lib:write_string(atom_to_list(X), $'); % stupid emacs '
+ false -> flat_format("~w", [X])
+ end || X <- set_to_list(Set)],
+ string:join(L, " | ").
+
+set_min([H|_]) -> H.
+
+set_max(Set) ->
+ hd(lists:reverse(Set)).
+
+flat_format(F, S) ->
+ lists:flatten(io_lib:format(F, S)).
+
+%%=============================================================================
+%%
+%% Utilities for the binary type
+%%
+%%=============================================================================
+
+-spec gcd(integer(), integer()) -> integer().
+
+gcd(A, B) when B > A ->
+ gcd1(B, A);
+gcd(A, B) ->
+ gcd1(A, B).
+
+-spec gcd1(integer(), integer()) -> integer().
+
+gcd1(A, 0) -> A;
+gcd1(A, B) ->
+ case A rem B of
+ 0 -> B;
+ X -> gcd1(B, X)
+ end.
+
+-spec bitstr_concat(erl_type(), erl_type()) -> erl_type().
+
+bitstr_concat(?none, _) -> ?none;
+bitstr_concat(_, ?none) -> ?none;
+bitstr_concat(?bitstr(U1, B1), ?bitstr(U2, B2)) ->
+ t_bitstr(gcd(U1, U2), B1+B2).
+
+-spec bitstr_match(erl_type(), erl_type()) -> erl_type().
+
+bitstr_match(?none, _) -> ?none;
+bitstr_match(_, ?none) -> ?none;
+bitstr_match(?bitstr(0, B1), ?bitstr(0, B2)) when B1 =< B2 ->
+ t_bitstr(0, B2-B1);
+bitstr_match(?bitstr(0, _B1), ?bitstr(0, _B2)) ->
+ ?none;
+bitstr_match(?bitstr(0, B1), ?bitstr(U2, B2)) when B1 =< B2 ->
+ t_bitstr(U2, B2-B1);
+bitstr_match(?bitstr(0, B1), ?bitstr(U2, B2)) ->
+ t_bitstr(U2, handle_base(U2, B2-B1));
+bitstr_match(?bitstr(_, B1), ?bitstr(0, B2)) when B1 > B2 ->
+ ?none;
+bitstr_match(?bitstr(U1, B1), ?bitstr(U2, B2)) ->
+ GCD = gcd(U1, U2),
+ t_bitstr(GCD, handle_base(GCD, B2-B1)).
+
+-spec handle_base(integer(), integer()) -> integer().
+
+handle_base(Unit, Pos) when Pos >= 0 ->
+ Pos rem Unit;
+handle_base(Unit, Neg) ->
+ (Unit+(Neg rem Unit)) rem Unit.
+
+family(L) ->
+ R = sofs:relation(L),
+ F = sofs:relation_to_family(R),
+ sofs:to_external(F).
+
+%%=============================================================================
+%%
+%% Interface functions for abstract data types defined in this module
+%%
+%%=============================================================================
+
+-spec var_table__new() -> var_table().
+
+var_table__new() ->
+ maps:new().
+
+%%=============================================================================
+%% Consistency-testing function(s) below
+%%=============================================================================
+
+-ifdef(DO_ERL_TYPES_TEST).
+
+test() ->
+ Atom1 = t_atom(),
+ Atom2 = t_atom(foo),
+ Atom3 = t_atom(bar),
+ true = t_is_atom(Atom2),
+
+ True = t_atom(true),
+ False = t_atom(false),
+ Bool = t_boolean(),
+ true = t_is_boolean(True),
+ true = t_is_boolean(Bool),
+ false = t_is_boolean(Atom1),
+
+ Binary = t_binary(),
+ true = t_is_binary(Binary),
+
+ Bitstr = t_bitstr(),
+ true = t_is_bitstr(Bitstr),
+
+ Bitstr1 = t_bitstr(7, 3),
+ true = t_is_bitstr(Bitstr1),
+ false = t_is_binary(Bitstr1),
+
+ Bitstr2 = t_bitstr(16, 8),
+ true = t_is_bitstr(Bitstr2),
+ true = t_is_binary(Bitstr2),
+
+ ?bitstr(8, 16) = t_subtract(t_bitstr(4, 12), t_bitstr(8, 12)),
+ ?bitstr(8, 16) = t_subtract(t_bitstr(4, 12), t_bitstr(8, 12)),
+
+ Int1 = t_integer(),
+ Int2 = t_integer(1),
+ Int3 = t_integer(16#ffffffff),
+ true = t_is_integer(Int2),
+ true = t_is_byte(Int2),
+ false = t_is_byte(Int3),
+ false = t_is_byte(t_from_range(-1, 1)),
+ true = t_is_byte(t_from_range(1, ?MAX_BYTE)),
+
+ Tuple1 = t_tuple(),
+ Tuple2 = t_tuple(3),
+ Tuple3 = t_tuple([Atom1, Int1]),
+ Tuple4 = t_tuple([Tuple1, Tuple2]),
+ Tuple5 = t_tuple([Tuple3, Tuple4]),
+ Tuple6 = t_limit(Tuple5, 2),
+ Tuple7 = t_limit(Tuple5, 3),
+ true = t_is_tuple(Tuple1),
+
+ Port = t_port(),
+ Pid = t_pid(),
+ Ref = t_reference(),
+ Identifier = t_identifier(),
+ false = t_is_reference(Port),
+ true = t_is_identifier(Port),
+
+ Function1 = t_fun(),
+ Function2 = t_fun(Pid),
+ Function3 = t_fun([], Pid),
+ Function4 = t_fun([Port, Pid], Pid),
+ Function5 = t_fun([Pid, Atom1], Int2),
+ true = t_is_fun(Function3),
+
+ List1 = t_list(),
+ List2 = t_list(t_boolean()),
+ List3 = t_cons(t_boolean(), List2),
+ List4 = t_cons(t_boolean(), t_atom()),
+ List5 = t_cons(t_boolean(), t_nil()),
+ List6 = t_cons_tl(List5),
+ List7 = t_sup(List4, List5),
+ List8 = t_inf(List7, t_list()),
+ List9 = t_cons(),
+ List10 = t_cons_tl(List9),
+ true = t_is_boolean(t_cons_hd(List5)),
+ true = t_is_list(List5),
+ false = t_is_list(List4),
+
+ Product1 = t_product([Atom1, Atom2]),
+ Product2 = t_product([Atom3, Atom1]),
+ Product3 = t_product([Atom3, Atom2]),
+
+ Union1 = t_sup(Atom2, Atom3),
+ Union2 = t_sup(Tuple2, Tuple3),
+ Union3 = t_sup(Int2, Atom3),
+ Union4 = t_sup(Port, Pid),
+ Union5 = t_sup(Union4, Int1),
+ Union6 = t_sup(Function1, Function2),
+ Union7 = t_sup(Function4, Function5),
+ Union8 = t_sup(True, False),
+ true = t_is_boolean(Union8),
+ Union9 = t_sup(Int2, t_integer(2)),
+ true = t_is_byte(Union9),
+ Union10 = t_sup(t_tuple([t_atom(true), ?any]),
+ t_tuple([t_atom(false), ?any])),
+
+ ?any = t_sup(Product3, Function5),
+
+ Atom3 = t_inf(Union3, Atom1),
+ Union2 = t_inf(Union2, Tuple1),
+ Int2 = t_inf(Int1, Union3),
+ Union4 = t_inf(Union4, Identifier),
+ Port = t_inf(Union5, Port),
+ Function4 = t_inf(Union7, Function4),
+ ?none = t_inf(Product2, Atom1),
+ Product3 = t_inf(Product1, Product2),
+ Function5 = t_inf(Union7, Function5),
+ true = t_is_byte(t_inf(Union9, t_number())),
+ true = t_is_char(t_inf(Union9, t_number())),
+
+ io:format("3? ~p ~n", [?int_set([3])]),
+
+ RecDict = dict:store({foo, 2}, [bar, baz], dict:new()),
+ Record1 = t_from_term({foo, [1,2], {1,2,3}}),
+
+ Types = [
+ Atom1,
+ Atom2,
+ Atom3,
+ Binary,
+ Int1,
+ Int2,
+ Tuple1,
+ Tuple2,
+ Tuple3,
+ Tuple4,
+ Tuple5,
+ Tuple6,
+ Tuple7,
+ Ref,
+ Port,
+ Pid,
+ Identifier,
+ List1,
+ List2,
+ List3,
+ List4,
+ List5,
+ List6,
+ List7,
+ List8,
+ List9,
+ List10,
+ Function1,
+ Function2,
+ Function3,
+ Function4,
+ Function5,
+ Product1,
+ Product2,
+ Record1,
+ Union1,
+ Union2,
+ Union3,
+ Union4,
+ Union5,
+ Union6,
+ Union7,
+ Union8,
+ Union10,
+ t_inf(Union10, t_tuple([t_atom(true), t_integer()]))
+ ],
+ io:format("~p\n", [[t_to_string(X, RecDict) || X <- Types]]).
+
+-endif.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl b/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl
index c19330eb30..597460ce77 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl
@@ -52,7 +52,7 @@ exact_api_set_type(#exact_api{}=E) -> E.
-record(exact_adt, {}).
exact_adt_test(X) ->
- #exact_adt{} = exact_adt:exact_adt_set_type(X). % breaks the opaqueness
+ #exact_adt{} = exact_adt:exact_adt_set_type(X). % breaks the opacity
exact_adt_new(A) ->
A = #exact_adt{},
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/simple/is_rec.erl b/lib/dialyzer/test/opaque_SUITE_data/src/simple/is_rec.erl
index 2b157483bc..b906431b44 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/simple/is_rec.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/simple/is_rec.erl
@@ -16,11 +16,11 @@ ri11() ->
ri13() ->
A = simple1_adt:d1(),
- if is_record(A, r) -> true end. % breaks the opaqueness
+ if is_record(A, r) -> true end. % breaks the opacity
ri14() ->
A = simple1_adt:d1(),
- if is_record({A, 1}, r) -> true end. % breaks the opaqueness
+ if is_record({A, 1}, r) -> true end. % breaks the opacity
-type '1-3-t'() :: 1..3.
@@ -54,7 +54,7 @@ ri5() ->
ri6() ->
A = simple1_adt:d1(),
- if is_record(A, r) -> true end. % breaks opaqueness
+ if is_record(A, r) -> true end. % breaks opacity
ri7() ->
A = simple1_adt:d1(),
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl b/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl
index fb6d59d263..59b9e0fec4 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl
@@ -30,7 +30,7 @@ t3() ->
adt_t1() ->
R = rec_adt:r1(),
- {r1, a} = R. % breaks the opaqueness
+ {r1, a} = R. % breaks the opacity
-spec adt_t1(rec_adt:r1()) -> rec_adt:r1(). % invalid type spec
@@ -82,7 +82,7 @@ f() ->
r_adt() ->
{{r, rec_adt:f(), 2},
- #r{f = rec_adt:f(), o = 2}}. % breaks the opaqueness
+ #r{f = rec_adt:f(), o = 2}}. % breaks the opacity
-record(r2, % like #r1{}, but with initial value
{f1 = a :: a()}).
@@ -110,7 +110,7 @@ u3() ->
v1() ->
A = #r3{f1 = queue:new()},
- {r3, a} = A. % breaks the opaqueness
+ {r3, a} = A. % breaks the opacity
v2() ->
A = {r3, 10},
@@ -120,4 +120,4 @@ v2() ->
v3() ->
A = {r3, 10},
- #r3{f1 = 10} = A. % breaks the opaqueness
+ #r3{f1 = 10} = A. % breaks the opacity
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl b/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl
index 7db1100597..d67aa913d8 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl
@@ -194,7 +194,7 @@ tt1() ->
tt2() ->
A = simple1_adt:d1(),
- is_integer(A). % breaks the opaqueness
+ is_integer(A). % breaks the opacity
%% Comparison with integers
@@ -262,11 +262,11 @@ f2() ->
adt_f1() ->
T = simple1_adt:n1(),
- if is_function(T) -> ok end. % breaks the opaqueness
+ if is_function(T) -> ok end. % breaks the opacity
adt_f2() ->
T = simple1_adt:n1(),
- is_function(T). % breaks the opaqueness
+ is_function(T). % breaks the opacity
f3() ->
A = i1(),
@@ -281,12 +281,12 @@ f4() ->
adt_f3() ->
A = simple1_adt:i1(),
T = simple1_adt:n1(),
- if is_function(T, A) -> ok end. % breaks the opaqueness
+ if is_function(T, A) -> ok end. % breaks the opacity
adt_f4() ->
A = simple1_adt:i1(),
T = simple1_adt:n1(),
- is_function(T, A). % breaks the opaqueness
+ is_function(T, A). % breaks the opacity
adt_f4_a() ->
A = simple1_adt:i1(),
@@ -297,7 +297,7 @@ adt_f4_a() ->
adt_f4_b() ->
A = i1(),
T = simple1_adt:n1(),
- is_function(T, A). % breaks the opaqueness
+ is_function(T, A). % breaks the opacity
%% A few Boolean examples
@@ -404,7 +404,7 @@ bit_t1() ->
bit_adt_t1() ->
A = simple1_adt:i1(),
- <<100:(A)>>. % breaks the opaqueness
+ <<100:(A)>>. % breaks the opacity
bit_t3(A) ->
B = i1(),
@@ -415,14 +415,14 @@ bit_t3(A) ->
bit_adt_t2() ->
A = simple1_adt:i1(),
case <<"hej">> of
- <<_:A>> -> ok % breaks the opaqueness (but the message is strange)
+ <<_:A>> -> ok % breaks the opacity (but the message is strange)
end.
bit_adt_t3(A) ->
B = simple1_adt:i1(),
case none:none() of
- <<A: % breaks the opaqueness (the message is less than perfect)
+ <<A: % breaks the opacity (the message is less than perfect)
B>> -> 1
end.
@@ -445,7 +445,7 @@ bit_t4(A) ->
bit_adt_t4(A) ->
Sz = simple1_adt:i1(),
case A of
- <<_:Sz>> -> 1 % breaks the opaqueness
+ <<_:Sz>> -> 1 % breaks the opacity
end.
bit_t5() ->
@@ -457,7 +457,7 @@ bit_t5() ->
bit_adt_t5() ->
A = simple1_adt:bit1(),
case A of
- <<_/binary>> -> 1 % breaks the opaqueness
+ <<_/binary>> -> 1 % breaks the opacity
end.
-opaque bit1() :: binary().
@@ -475,7 +475,7 @@ call_f(A) ->
call_f_adt(A) ->
A = simple1_adt:a(),
- foo:A(A). % breaks the opaqueness
+ foo:A(A). % breaks the opacity
call_m(A) ->
A = a(),
@@ -483,7 +483,7 @@ call_m(A) ->
call_m_adt(A) ->
A = simple1_adt:a(),
- A:foo(A). % breaks the opaqueness
+ A:foo(A). % breaks the opacity
-opaque a() :: atom().
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/timer/timer_use.erl b/lib/dialyzer/test/opaque_SUITE_data/src/timer/timer_use.erl
index 9c8ea0af1c..ed6810634f 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/timer/timer_use.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/timer/timer_use.erl
@@ -1,8 +1,8 @@
%%---------------------------------------------------------------------------
%% A test case with:
%% - a genuine matching error -- 1st branch
-%% - a violation of the opaqueness of timer:tref() -- 2nd branch
-%% - a subtle violation of the opaqueness of timer:tref() -- 3rd branch
+%% - a violation of the opacity of timer:tref() -- 2nd branch
+%% - a subtle violation of the opacity of timer:tref() -- 3rd branch
%% The test is supposed to check that these cases are treated properly.
%%---------------------------------------------------------------------------
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning1.erl b/lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning1.erl
new file mode 100644
index 0000000000..094138e72b
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning1.erl
@@ -0,0 +1,18 @@
+-module(weird_warning1).
+-export([public_func/0]).
+
+-record(a, {
+ d = dict:new() :: dict:dict()
+ }).
+
+-record(b, {
+ q = queue:new() :: queue:queue()
+ }).
+
+public_func() ->
+ add_element(#b{}, my_key, my_value).
+
+add_element(#a{d = Dict}, Key, Value) ->
+ dict:store(Key, Value, Dict);
+add_element(#b{q = Queue}, Key, Value) ->
+ queue:in({Key, Value}, Queue).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning2.erl b/lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning2.erl
new file mode 100644
index 0000000000..4e4512157b
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning2.erl
@@ -0,0 +1,14 @@
+-module(weird_warning2).
+-export([public_func/0]).
+
+-record(a, {d = dict:new() :: dict:dict()}).
+
+-record(b, {q = queue:new() :: queue:queue()}).
+
+public_func() ->
+ add_element(#a{}, my_key, my_value).
+
+add_element(#a{d = Dict}, Key, Value) ->
+ dict:store(Key, Value, Dict);
+add_element(#b{q = Queue}, Key, Value) ->
+ queue:in({Key, Value}, Queue).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning3.erl b/lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning3.erl
new file mode 100644
index 0000000000..b70ca645cb
--- /dev/null
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/weird/weird_warning3.erl
@@ -0,0 +1,19 @@
+-module(weird_warning3).
+-export([public_func/0]).
+
+-record(a, {
+ d = dict:new() :: dict:dict()
+ }).
+
+-record(b, {
+ q = queue:new() :: queue:queue()
+ }).
+
+public_func() ->
+ %% Notice that t_to_string() will create "#a{d::queue:queue(_)}".
+ add_element({a, queue:new()}, my_key, my_value).
+
+add_element(#a{d = Dict}, Key, Value) ->
+ dict:store(Key, Value, Dict);
+add_element(#b{q = Queue}, Key, Value) ->
+ queue:in({Key, Value}, Queue).
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl b/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl
index ca6bc0ab4a..6b825d85fe 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl
@@ -14,12 +14,12 @@
rel2fam(Rel) ->
sofs:to_external(sofs:relation_to_family(sofs:relation(Rel))).
-%% a definition that does not violate the opaqueness of gb_trees:tree()
+%% a definition that does not violate the opacity of gb_trees:tree()
gb_trees_smallest_key(Tree) ->
{Key, _V} = gb_trees:smallest(Tree),
Key.
-%% a definition that violates the opaqueness of gb_trees:tree()
+%% a definition that violates the opacity of gb_trees:tree()
gb_trees_largest_key({_, Tree}) ->
largest_key1(Tree).
diff --git a/lib/dialyzer/test/options1_SUITE_data/results/compiler b/lib/dialyzer/test/options1_SUITE_data/results/compiler
index 30b6f4814a..cbb5115c91 100644
--- a/lib/dialyzer/test/options1_SUITE_data/results/compiler
+++ b/lib/dialyzer/test/options1_SUITE_data/results/compiler
@@ -31,6 +31,8 @@ cerl_inline.erl:2756: The pattern <{F, _L, D}, Vs> can never match the type <[1.
compile.erl:788: The pattern {'error', Es} can never match the type {'ok',<<_:64,_:_*8>>}
core_lint.erl:473: The pattern <{'c_atom', _, 'all'}, 'binary', _Def, St> can never match the type <_,#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::{_,_} | {_,_,_} | {_,_,_,_},tl::{_,_} | {_,_,_} | {_,_,_,_}},tl::#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::{_,_} | {_,_,_} | {_,_,_,_},tl::{_,_} | {_,_,_} | {_,_,_,_}}},[any()],_>
core_lint.erl:505: The pattern <_Req, 'unknown', St> can never match the type <non_neg_integer(),non_neg_integer(),_>
+sys_pre_expand.erl:625: Call to missing or unexported function erlang:hash/2
v3_codegen.erl:1569: The call v3_codegen:load_reg_1(V::any(),I::0,Rs::any(),pos_integer()) will never return since it differs in the 4th argument from the success typing arguments: (any(),0,maybe_improper_list(),0)
v3_codegen.erl:1571: The call v3_codegen:load_reg_1(V::any(),I::0,[],pos_integer()) will never return since it differs in the 4th argument from the success typing arguments: (any(),0,maybe_improper_list(),0)
v3_core.erl:646: Matching of pattern {'iprimop', _, _, _} tagged with a record name violates the declared type of #c_nil{anno::[any(),...]} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple' | 'c_var' | 'ibinary' | 'icatch' | 'ireceive1',[any(),...] | {_,_,_,_},_} | #c_cons{anno::[any(),...]} | #c_fname{anno::[any(),...]} | #iletrec{anno::{_,_,_,_},defs::[any(),...],body::[any(),...]} | #icase{anno::{_,_,_,_},args::[any()],clauses::[any()],fc::{_,_,_,_,_,_}} | #ireceive2{anno::{_,_,_,_},clauses::[any()],action::[any()]} | #ifun{anno::{_,_,_,_},id::[any(),...],vars::[any()],clauses::[any(),...],fc::{_,_,_,_,_,_}} | #imatch{anno::{_,_,_,_},guard::[],fc::{_,_,_,_,_,_}} | #itry{anno::{_,_,_,_},args::[any()],vars::[any(),...],body::[any(),...],evars::[any(),...],handler::[any(),...]}
+v3_kernel.erl:1381: Call to missing or unexported function erlang:hash/2
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_disasm.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_disasm.erl
index 0108f91b7f..cf2cbe8e2b 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_disasm.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_disasm.erl
@@ -565,7 +565,7 @@ resolve_inst({make_fun2,Args},_,_,Lbls,Lambdas) ->
[OldIndex] = resolve_args(Args),
{value,{OldIndex,{F,A,_Lbl,_Index,NumFree,OldUniq}}} =
lists:keysearch(OldIndex, 1, Lambdas),
- [{_,{M,_,_}}|_] = Lbls, % Slighly kludgy.
+ [{_,{M,_,_}}|_] = Lbls, % Slightly kludgy.
{make_fun2,{M,F,A},OldIndex,OldUniq,NumFree};
resolve_inst(Instr, Imports, Str, Lbls, _Lambdas) ->
resolve_inst(Instr, Imports, Str, Lbls).
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_inline.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_inline.erl
index 95d2076ccf..8fca202b8c 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_inline.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/cerl_inline.erl
@@ -951,7 +951,7 @@ i_letrec(Es, B, Xs, Ctxt, Ren, Env, S) ->
%% Finally, we create new letrec-bindings for any and all
%% residualised definitions. All referenced functions should have
- %% been visited; the call to `visit' below is expected to retreive a
+ %% been visited; the call to `visit' below is expected to retrieve a
%% cached expression.
Rs1 = keep_referenced(Rs, S4),
{Es1, S5} = mapfoldl(fun (R, S) ->
@@ -997,7 +997,7 @@ i_apply(E, Ctxt, Ren, Env, S) ->
%% location could be recycled after the flag has been tested, but
%% there is no real advantage to that, because in practice, only
%% 4-5% of all created store locations will ever be reused, while
- %% there will be a noticable overhead for managing the free list.)
+ %% there will be a noticeable overhead for managing the free list.)
case st__get_app_inlined(L, S3) of
true ->
%% The application was inlined, so we have the final
@@ -2007,7 +2007,7 @@ residualize_operand(Opnd, E, S) ->
case st__get_opnd_effect(Opnd#opnd.loc, S) of
true ->
%% The operand has not been visited, so we do that now, but
- %% in `effect' context. (Waddell's algoritm does some stuff
+ %% in `effect' context. (Waddell's algorithm does some stuff
%% here to account specially for the operand size, which
%% appears unnecessary.)
{E1, S1} = i(Opnd#opnd.expr, effect, Opnd#opnd.ren,
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/rec_env.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/rec_env.erl
index 01c2512397..76ae871aee 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/rec_env.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/rec_env.erl
@@ -469,7 +469,7 @@ get(Key, Env) ->
-define(MINIMUM_RANGE, 1000).
-define(START_RANGE_FACTOR, 50).
-define(MAX_RETRIES, 2). % retries before enlarging range
--define(ENLARGE_FACTOR, 10). % range enlargment factor
+-define(ENLARGE_FACTOR, 10). % range enlargement factor
-ifdef(DEBUG).
%% If you want to use these process dictionary counters, make sure to
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl
index 49a95a95e5..69139cd568 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/sys_pre_expand.erl
@@ -316,7 +316,7 @@ record_test_in_guard(Line, Term, Name, Vs, St) ->
%% code bloat.)
%% (4) Xref may be run on the abstract code, so the name in the
%% abstract code must be erlang:is_record/3.
- %% (5) To achive both (3) and (4) at the same time, set the name
+ %% (5) To achieve both (3) and (4) at the same time, set the name
%% here to erlang:is_record/3, but mark it as compiler-generated.
%% The v3_core pass will change the name to erlang:internal_is_record/3.
Fs = record_fields(Name, St),
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_codegen.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_codegen.erl
index 33a322b466..acb49b5faf 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_codegen.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/v3_codegen.erl
@@ -1667,7 +1667,7 @@ bs_function({function,Name,Arity,CLabel,Asm0}=Func) ->
%%%
%%% Pass 1: Found out which bs_restore's that are needed. For now we assume
-%%% that a bs_restore is needed unless it is directly preceeded by a bs_save.
+%%% that a bs_restore is needed unless it is directly preceded by a bs_save.
%%%
bs_needed([{bs_save,Name},{bs_restore,Name}|T], N, _BsUsed, Dict) ->
diff --git a/lib/dialyzer/test/options2_SUITE_data/dialyzer_options b/lib/dialyzer/test/options2_SUITE_data/dialyzer_options
index 5db2e50d23..be57e2de72 100644
--- a/lib/dialyzer/test/options2_SUITE_data/dialyzer_options
+++ b/lib/dialyzer/test/options2_SUITE_data/dialyzer_options
@@ -1 +1 @@
-{dialyzer_options, [{defines, [{'vsn', 4}]}, {warnings, [no_return]}]}.
+{dialyzer_options, [{defines, [{'vsn', 4}]}, {warnings, [unknown, no_return]}]}.
diff --git a/lib/dialyzer/test/options2_SUITE_data/results/unknown_type b/lib/dialyzer/test/options2_SUITE_data/results/unknown_type
new file mode 100644
index 0000000000..d308c5a810
--- /dev/null
+++ b/lib/dialyzer/test/options2_SUITE_data/results/unknown_type
@@ -0,0 +1,2 @@
+
+:0: Unknown type unknown:type/0 \ No newline at end of file
diff --git a/lib/dialyzer/test/options2_SUITE_data/results/unused_unknown_type b/lib/dialyzer/test/options2_SUITE_data/results/unused_unknown_type
new file mode 100644
index 0000000000..110d896c76
--- /dev/null
+++ b/lib/dialyzer/test/options2_SUITE_data/results/unused_unknown_type
@@ -0,0 +1,2 @@
+
+:0: Unknown type unknown:type1/0:0: Unknown type unknown:type2/0:0: Unknown type unknown:type3/0 \ No newline at end of file
diff --git a/lib/dialyzer/test/options2_SUITE_data/src/unknown_type.erl b/lib/dialyzer/test/options2_SUITE_data/src/unknown_type.erl
new file mode 100644
index 0000000000..7a891c0831
--- /dev/null
+++ b/lib/dialyzer/test/options2_SUITE_data/src/unknown_type.erl
@@ -0,0 +1,7 @@
+-module(unknown_type).
+
+-export([t/0]).
+
+-spec t() -> unknown:type().
+t() ->
+ a.
diff --git a/lib/dialyzer/test/options2_SUITE_data/src/unused_unknown_type.erl b/lib/dialyzer/test/options2_SUITE_data/src/unused_unknown_type.erl
new file mode 100644
index 0000000000..90df7d528a
--- /dev/null
+++ b/lib/dialyzer/test/options2_SUITE_data/src/unused_unknown_type.erl
@@ -0,0 +1,10 @@
+-module(unused_unknown_type).
+
+-export_type([unused/0]).
+
+-type unused() :: unknown:type1().
+
+-record(unused_rec, {a :: unknown:type2()}).
+
+-record(rec, {a}).
+-type unused_rec() :: #rec{a :: unknown:type3()}.
diff --git a/lib/dialyzer/test/plt_SUITE.erl b/lib/dialyzer/test/plt_SUITE.erl
index 6ebe23b54b..ebe79b2a6d 100644
--- a/lib/dialyzer/test/plt_SUITE.erl
+++ b/lib/dialyzer/test/plt_SUITE.erl
@@ -8,13 +8,15 @@
-export([suite/0, all/0, build_plt/1, beam_tests/1, update_plt/1,
local_fun_same_as_callback/1,
- remove_plt/1, run_plt_check/1, run_succ_typings/1]).
+ remove_plt/1, run_plt_check/1, run_succ_typings/1,
+ bad_dialyzer_attr/1, merge_plts/1]).
suite() ->
[{timetrap, ?plt_timeout}].
all() -> [build_plt, beam_tests, update_plt, run_plt_check,
- remove_plt, run_succ_typings, local_fun_same_as_callback].
+ remove_plt, run_succ_typings, local_fun_same_as_callback,
+ bad_dialyzer_attr, merge_plts].
build_plt(Config) ->
OutDir = ?config(priv_dir, Config),
@@ -24,6 +26,8 @@ build_plt(Config) ->
end.
beam_tests(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Plt = filename:join(PrivDir, "beam_tests.plt"),
Prog = <<"
-module(no_auto_import).
@@ -40,10 +44,12 @@ beam_tests(Config) when is_list(Config) ->
">>,
Opts = [no_auto_import],
{ok, BeamFile} = compile(Config, Prog, no_auto_import, Opts),
- [] = run_dialyzer(plt_build, [BeamFile], []),
+ [] = run_dialyzer(plt_build, [BeamFile], [{output_plt, Plt}]),
ok.
run_plt_check(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Plt = filename:join(PrivDir, "run_plt_check.plt"),
Mod1 = <<"
-module(run_plt_check1).
">>,
@@ -54,7 +60,7 @@ run_plt_check(Config) when is_list(Config) ->
{ok, BeamFile1} = compile(Config, Mod1, run_plt_check1, []),
{ok, BeamFile2} = compile(Config, Mod2A, run_plt_check2, []),
- [] = run_dialyzer(plt_build, [BeamFile1, BeamFile2], []),
+ [] = run_dialyzer(plt_build, [BeamFile1, BeamFile2], [{output_plt, Plt}]),
Mod2B = <<"
-module(run_plt_check2).
@@ -68,11 +74,13 @@ run_plt_check(Config) when is_list(Config) ->
% callgraph warning as run_plt_check2:call/1 makes a call to unexported
% function run_plt_check1:call/1.
- [_] = run_dialyzer(plt_check, [], []),
+ [_] = run_dialyzer(plt_check, [], [{init_plt, Plt}]),
ok.
run_succ_typings(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Plt = filename:join(PrivDir, "run_succ_typings.plt"),
Mod1A = <<"
-module(run_succ_typings1).
@@ -82,7 +90,7 @@ run_succ_typings(Config) when is_list(Config) ->
">>,
{ok, BeamFile1} = compile(Config, Mod1A, run_succ_typings1, []),
- [] = run_dialyzer(plt_build, [BeamFile1], []),
+ [] = run_dialyzer(plt_build, [BeamFile1], [{output_plt, Plt}]),
Mod1B = <<"
-module(run_succ_typings1).
@@ -105,9 +113,11 @@ run_succ_typings(Config) when is_list(Config) ->
{ok, BeamFile2} = compile(Config, Mod2, run_succ_typings2, []),
% contract types warning as run_succ_typings2:call/0 makes a call to
% run_succ_typings1:call/0, which returns a (not b) in the PLT.
- [_] = run_dialyzer(succ_typings, [BeamFile2], [{check_plt, false}]),
+ [_] = run_dialyzer(succ_typings, [BeamFile2],
+ [{check_plt, false}, {init_plt, Plt}]),
% warning not returned as run_succ_typings1 is updated in the PLT.
- [] = run_dialyzer(succ_typings, [BeamFile2], [{check_plt, true}]),
+ [] = run_dialyzer(succ_typings, [BeamFile2],
+ [{check_plt, true}, {init_plt, Plt}]),
ok.
@@ -160,6 +170,7 @@ update_plt(Config) ->
{init_plt, Plt}] ++ Opts),
ok.
+
%%% If a behaviour module contains an non-exported function with the same name
%%% as one of the behaviour's callbacks, the callback info was inadvertently
%%% deleted from the PLT as the dialyzer_plt:delete_list/2 function was cleaning
@@ -249,6 +260,125 @@ remove_plt(Config) ->
{init_plt, Plt}] ++ Opts),
ok.
+%% ERL-283, OTP-13979. As of OTP-14323 this test no longer does what
+%% it is designed to do--the linter stops every attempt to run the
+%% checks of Dialyzer's on bad dialyzer attributes. For the time
+%% being, the linter's error message are checked instead. The test
+%% needs to be updated when/if the Dialyzer can analyze Core Erlang
+%% without compiling abstract code.
+bad_dialyzer_attr(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Source = lists:concat([dial, ".erl"]),
+ Filename = filename:join(PrivDir, Source),
+ ok = dialyzer_common:check_plt(PrivDir),
+ PltFilename = dialyzer_common:plt_file(PrivDir),
+ Opts = [{files, [Filename]},
+ {check_plt, false},
+ {from, src_code},
+ {init_plt, PltFilename}],
+
+ Prog1 = <<"-module(dial).
+ -dialyzer({no_return, [undef/0]}).">>,
+ ok = file:write_file(Filename, Prog1),
+ {dialyzer_error,
+ "Analysis failed with error:\n" ++ Str1} =
+ (catch dialyzer:run(Opts)),
+ P1 = string:str(Str1, "dial.erl:2: function undef/0 undefined"),
+ true = P1 > 0,
+
+ Prog2 = <<"-module(dial).
+ -dialyzer({no_return, [{undef,1,2}]}).">>,
+ ok = file:write_file(Filename, Prog2),
+ {dialyzer_error,
+ "Analysis failed with error:\n" ++ Str2} =
+ (catch dialyzer:run(Opts)),
+ P2 = string:str(Str2, "dial.erl:2: badly formed dialyzer "
+ "attribute: {no_return,{undef,1,2}}"),
+ true = P2 > 0,
+
+ ok.
+
+merge_plts(Config) ->
+ %% A few checks of merging PLTs.
+ fun() ->
+ {Mod1, Mod2} = types(),
+ {BeamFiles, Plt1, Plt2} = create_plts(Mod1, Mod2, Config),
+
+ {dialyzer_error,
+ "Could not merge PLTs since they are not disjoint"++_} =
+ (catch run_dialyzer(succ_typings, BeamFiles,
+ [{plts, [Plt1, Plt1]}])),
+ [{warn_contract_types,_,_}] =
+ run_dialyzer(succ_typings, BeamFiles,
+ [{warnings, [unknown]},
+ {plts, [Plt1, Plt2]}])
+ end(),
+
+ fun() ->
+ {Mod1, Mod2} = callbacks(),
+ {BeamFiles, Plt1, Plt2} = create_plts(Mod1, Mod2, Config),
+
+ {dialyzer_error,
+ "Could not merge PLTs since they are not disjoint"++_} =
+ (catch run_dialyzer(succ_typings, BeamFiles,
+ [{plts, [Plt1, Plt1]}])),
+ [] =
+ run_dialyzer(succ_typings, BeamFiles,
+ [{warnings, [unknown]},
+ {plts, [Plt1, Plt2]}])
+ end(),
+
+ ok.
+
+types() ->
+ Mod1 = <<"-module(merge_plts_1).
+ -export([f/0]).
+ -export_type([t/0]).
+ -type t() :: merge_plts_2:t().
+ -spec f() -> t().
+ f() -> 1. % Not an atom().
+ ">>,
+ Mod2 = <<"-module(merge_plts_2).
+ -export_type([t/0]).
+ -type t() :: atom().
+ ">>,
+ {Mod1, Mod2}.
+
+callbacks() -> % A very shallow test.
+ Mod1 = <<"-module(merge_plts_1).
+ -callback t() -> merge_plts_2:t().
+ ">>,
+ Mod2 = <<"-module(merge_plts_2).
+ -export_type([t/0]).
+ -type t() :: atom().
+ ">>,
+ {Mod1, Mod2}.
+
+create_plts(Mod1, Mod2, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ Plt1 = filename:join(PrivDir, "merge_plts_1.plt"),
+ Plt2 = filename:join(PrivDir, "merge_plts_2.plt"),
+ ErlangBeam = erlang_beam(),
+
+ {ok, BeamFile1} = compile(Config, Mod1, merge_plts_1, []),
+ [] = run_dialyzer(plt_build, [ErlangBeam,BeamFile1], [{output_plt,Plt1}]),
+
+ {ok, BeamFile2} = compile(Config, Mod2, merge_plts_2, []),
+ [] = run_dialyzer(plt_build, [BeamFile2], [{output_plt, Plt2}]),
+ {[BeamFile1, BeamFile2], Plt1, Plt2}.
+
+%% End of merge_plts().
+
+erlang_beam() ->
+ case code:where_is_file("erlang.beam") of
+ non_existing ->
+ filename:join([code:root_dir(),
+ "erts", "preloaded", "ebin",
+ "erlang.beam"]);
+ EBeam ->
+ EBeam
+ end.
+
compile(Config, Prog, Module, CompileOpts) ->
Source = lists:concat([Module, ".erl"]),
PrivDir = ?config(priv_dir,Config),
diff --git a/lib/dialyzer/test/r9c_SUITE_data/results/mnesia b/lib/dialyzer/test/r9c_SUITE_data/results/mnesia
index bf67447ee7..71acdd9c9e 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/results/mnesia
+++ b/lib/dialyzer/test/r9c_SUITE_data/results/mnesia
@@ -17,6 +17,7 @@ mnesia_frag.erl:294: The call mnesia_frag:remote_collect(Ref::reference(),{'erro
mnesia_frag.erl:304: The call mnesia_frag:remote_collect(Ref::reference(),{'error',{'node_not_running',_}},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()]))
mnesia_frag.erl:312: The call mnesia_frag:remote_collect(Ref::reference(),LocalRes::{'error',_},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()]))
mnesia_frag_hash.erl:24: Callback info about the mnesia_frag_hash behaviour is not available
+mnesia_frag_old_hash.erl:105: Call to missing or unexported function erlang:hash/2
mnesia_frag_old_hash.erl:23: Callback info about the mnesia_frag_hash behaviour is not available
mnesia_index.erl:52: The call mnesia_lib:other_val(Var::{_,'commit_work' | 'index' | 'setorbag' | 'storage_type' | {'index',_}},_ReASoN_::any()) will never return since it differs in the 1st argument from the success typing arguments: ({_,'active_replicas' | 'where_to_read' | 'where_to_write'},any())
mnesia_lib.erl:1028: The pattern {'EXIT', Reason} can never match the type [any()] | {'error',_}
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct.erl
index ed38b2f915..3829479a94 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct.erl
@@ -520,7 +520,7 @@ save_automatic_tagged_types([_M|Ms]) ->
%% remove_in_set_imports/3 :
%% input: list with tuples of each module's imports and module name
%% respectively.
-%% output: one list with same format but each occured import from a
+%% output: one list with same format but each occurred import from a
%% module in the input set (IMNameL) is removed.
remove_in_set_imports([{{imports,ImpL},_ModName}|Rest],InputMNameL,Acc) ->
NewImpL = remove_in_set_imports1(ImpL,InputMNameL,[]),
@@ -1628,7 +1628,7 @@ tlv_tag1(<<1:1,PartialTag:7,Buffer/binary>>,Acc) ->
tlv_tag1(Buffer,(Acc bsl 7) bor PartialTag).
%% reads the content from the configuration file and returns the
-%% selected part choosen by InfoType. Assumes that the config file
+%% selected part chosen by InfoType. Assumes that the config file
%% content is an Erlang term.
read_config_file(ModuleName,InfoType) when atom(InfoType) ->
CfgList = read_config_file(ModuleName),
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_check.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_check.erl
index c26b8f851b..a4f39bde74 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_check.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_check.erl
@@ -4028,7 +4028,7 @@ check_sequence(S,Type,Comps) ->
{CRelInf,NewComps2} = componentrelation_leadingattr(S,NewComps),
% io:format("CRelInf: ~p~n",[CRelInf]),
% io:format("NewComps2: ~p~n",[NewComps2]),
- %% CompListWithTblInf has got a lot unecessary info about
+ %% CompListWithTblInf has got a lot unnecessary info about
%% the involved class removed, as the class of the object
%% set.
CompListWithTblInf = get_tableconstraint_info(S,Type,NewComps2),
@@ -4686,7 +4686,7 @@ any_component_relation(_,[],_,_,Acc) ->
%% evaluate_atpath/4 finds out whether the at notation refers to the
%% search level. The list of referenced names in the AtNot list shall
%% begin with a name that exists on the level it refers to. If the
-%% found AtPath is refering to the same sub-branch as the simple table
+%% found AtPath is referring to the same sub-branch as the simple table
%% has, then there shall not be any leading attribute info on this
%% level.
evaluate_atpath(_,[],Cnames,{innermost,AtPath=[Ref|_Refs]}) ->
@@ -4857,7 +4857,7 @@ innertype_comprel1(S,T = #type{def=Def,constraint=Cons,tablecinf=TCI},Path) ->
case Cons of
[{componentrelation,{_,_,ObjectSet},AtList}|_Rest] ->
%% This AtList must have an "outermost" at sign to be
- %% relevent here.
+ %% relevant here.
[{_,AL=[#'Externalvaluereference'{value=_Attr}|_R1]}|_R2]
= AtList,
%% #'ObjectClassFieldType'{class=ClassDef} = Def,
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber.erl
index 392896932a..0b5ea85681 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber.erl
@@ -1259,7 +1259,7 @@ gen_dec_line(Erules,TopType,Cname,CTags,Type,OptOrMand,DecObjInf) ->
end,
case DecObjInf of
{Cname,ObjSet} -> % this must be the component were an object is
- %% choosen from the object set according to the table
+ %% chosen from the object set according to the table
%% constraint.
{[{ObjSet,Cname,asn1ct_gen:mk_var(asn1ct_name:curr(term))}],
PostpDec};
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber_bin_v2.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber_bin_v2.erl
index 9725da4d11..fb9ffb13db 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber_bin_v2.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber_bin_v2.erl
@@ -1096,7 +1096,7 @@ gen_dec_line(Erules,TopType,Cname,CTags,Type,OptOrMand,DecObjInf) ->
end,
case DecObjInf of
{Cname,ObjSet} -> % this must be the component were an object is
- %% choosen from the object set according to the table
+ %% chosen from the object set according to the table
%% constraint.
{[{ObjSet,Cname,asn1ct_gen:mk_var(asn1ct_name:curr(term))}],
PostpDec};
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser2.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser2.erl
index 5f8c7a0de8..32676b3448 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser2.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_parser2.erl
@@ -2721,7 +2721,7 @@ prioritize_error(ErrList) ->
end,
NewErrList),
case SplitErrs of
- {[],UndefPosErrs} -> % if no error with Positon exists
+ {[],UndefPosErrs} -> % if no error with Position exists
lists:last(UndefPosErrs);
{IntPosErrs,_} ->
IntPosReasons = lists:map(fun(X)->element(2,X) end,IntPosErrs),
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin.erl
index 5854f8edbd..8f4d189b5a 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin.erl
@@ -1036,7 +1036,7 @@ decode_real2(Buffer0, Form, Len, RemBytes1) ->
%%
%% bitstring NamedBitList
%% Val can be of:
-%% - [identifiers] where only named identifers are set to one,
+%% - [identifiers] where only named identifiers are set to one,
%% the Constraint must then have some information of the
%% bitlength.
%% - [list of ones and zeroes] all bits
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin_v2.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin_v2.erl
index 0457425445..6e12d36579 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin_v2.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_ber_bin_v2.erl
@@ -1034,7 +1034,7 @@ decode_real_notag(_Buffer, _Form) ->
%%
%% bitstring NamedBitList
%% Val can be of:
-%% - [identifiers] where only named identifers are set to one,
+%% - [identifiers] where only named identifiers are set to one,
%% the Constraint must then have some information of the
%% bitlength.
%% - [list of ones and zeroes] all bits
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per.erl
index b163aa24ac..97c92a2dd1 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per.erl
@@ -823,7 +823,7 @@ decode_enumerated(Buffer,C,NamedNumberTup) when tuple(NamedNumberTup) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% bitstring NamedBitList
%% Val can be of:
-%% - [identifiers] where only named identifers are set to one,
+%% - [identifiers] where only named identifiers are set to one,
%% the Constraint must then have some information of the
%% bitlength.
%% - [list of ones and zeroes] all bits
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin.erl
index 15986cc217..aa2cf5ba88 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin.erl
@@ -1000,7 +1000,7 @@ decode_enumerated(Buffer,C,NamedNumberTup) when tuple(NamedNumberTup) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% bitstring NamedBitList
%% Val can be of:
-%% - [identifiers] where only named identifers are set to one,
+%% - [identifiers] where only named identifiers are set to one,
%% the Constraint must then have some information of the
%% bitlength.
%% - [list of ones and zeroes] all bits
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin_rt2ct.erl b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin_rt2ct.erl
index 43d9bef54e..24f7949c21 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin_rt2ct.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1rt_per_bin_rt2ct.erl
@@ -1059,7 +1059,7 @@ decode_enumerated(Buffer,C,NamedNumberTup) when tuple(NamedNumberTup) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% bitstring NamedBitList
%% Val can be of:
-%% - [identifiers] where only named identifers are set to one,
+%% - [identifiers] where only named identifiers are set to one,
%% the Constraint must then have some information of the
%% bitlength.
%% - [list of ones and zeroes] all bits
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/ftp.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/ftp.erl
index 4f0ca99cce..8be5b0cd6e 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/ftp.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/ftp.erl
@@ -108,7 +108,7 @@ user(Pid, User, Pass) ->
gen_server:call(Pid, {user, User, Pass}, infinity).
%% user(Pid, User, Pass,Acc)
-%% Purpose: Login whith a supplied account name
+%% Purpose: Login with a supplied account name
%% Args: Pid = pid(), User = Pass = Acc = string()
%% Returns: ok | {error, euser} | {error, econn} | {error, eacct}
user(Pid, User, Pass,Acc) ->
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.erl
index cf05431f5a..039960dac7 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/http.erl
@@ -24,7 +24,7 @@
%%% - RFC 3310 Authentication and Key Agreement (AKA) (not yet!)
%%% - HTTP/1.1 Specification Errata found at
%%% http://world.std.com/~lawrence/http_errata.html
-%%% Additionaly follows the following recommendations:
+%%% Additionally follows the following recommendations:
%%% - RFC 3143 Known HTTP Proxy/Caching Problems (not yet!)
%%% - draft-nottingham-hdrreg-http-00.txt (not yet!)
%%%
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/http_lib.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/http_lib.erl
index ebefcd7ad7..28ea42c685 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/http_lib.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/http_lib.erl
@@ -697,7 +697,7 @@ lookup(Key,Val) ->
%%% This code is for parsing trailer headers in chunked messages.
%%% Will be deprecated whenever I have found an alternative working solution!
%%% Note:
-%%% - The header names are returned slighly different from what the what
+%%% - The header names are returned slightly different from what the what
%%% inet_drv returns
read_headers_old(Scheme,Socket,Timeout) ->
read_headers_old(<<>>,Scheme,Socket,Timeout,[],[]).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_manager.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_manager.erl
index 45beaa84f7..d2653184aa 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_manager.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpc_manager.erl
@@ -95,7 +95,7 @@ abort_session(Addr,Sid,Msg) ->
next_request(Addr,Sid) ->
gen_server:call(?HMACALL,{next_request,Addr,Sid},infinity).
-%%% Session handler has succeded to set up a new session, now register
+%%% Session handler has succeed to set up a new session, now register
%%% the socket
register_socket(Addr,Sid,Socket) ->
gen_server:cast(?HMACALL,{register_socket,Addr,Sid,Socket}).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_manager.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_manager.erl
index 85e06f43b6..3058ac3556 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_manager.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_manager.erl
@@ -224,7 +224,7 @@ is_blocked(ServerRef) ->
%%
-%% Module API. Theese functions are intended for use from modules only.
+%% Module API. These functions are intended for use from modules only.
%%
config_lookup(Port, Query) ->
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_parse.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_parse.erl
index d7a698d65a..07f951d057 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_parse.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_parse.erl
@@ -109,7 +109,7 @@ get_persistens(HTTPVersion,ParsedHeader,ConfigDB)->
%%If it is version prio to 1.1 kill the conneciton
[$H, $T, $T, $P, $\/, $1, $.,N] ->
case httpd_util:key1search(ParsedHeader,"connection","keep-alive")of
- %%if the connection isnt ordered to go down let it live
+ %%if the connection isn't ordered to go down let it live
%%The keep-alive value is the older http/1.1 might be older
%%Clients that use it.
"keep-alive" when N >= 49 ->
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_response.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_response.erl
index 47c7fc1b8d..50e0e42786 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_response.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/httpd_response.erl
@@ -34,7 +34,7 @@
-define(PROCEED_RESPONSE(StatusCode, Info),
{proceed,
[{response,{already_sent, StatusCode,
- httpd_util:key1search(Info#mod.data,content_lenght)}}]}).
+ httpd_util:key1search(Info#mod.data,content_length)}}]}).
-include("httpd.hrl").
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/jnets_httpd.hrl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/jnets_httpd.hrl
index 6b872d7c95..73edcf6b92 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/jnets_httpd.hrl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/jnets_httpd.hrl
@@ -60,7 +60,7 @@
% request_line, % string() Request Line
headers, % #req_headers{} Parsed request headers
entity_body= <<>>, % binary() Body of request
- connection, % boolean() true if persistant connection
+ connection, % boolean() true if persistent connection
status_code, % int() Status code
logging % int() 0=No logging
% 1=Only mod_log present
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_mnesia.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_mnesia.erl
index e42494ff76..847d6e97c1 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_mnesia.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_auth_mnesia.erl
@@ -53,7 +53,7 @@ store_directory_data(Directory, DirData) ->
%% API
%%
-%% Compability API
+%% Compatibility API
store_user(UserName, Password, Port, Dir, AccessPassword) ->
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl
index 1203aeaa4c..a48f73274b 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl
@@ -440,7 +440,7 @@ try_new_erl_scheme_method(Info,Env,Input,Mod,Func)->
%%----------------------------------------------------------------------
-%%The function recieves the data from the process that generates the page
+%%The function receives the data from the process that generates the page
%%and send the data to the client through the mod_cgi:send function
%%----------------------------------------------------------------------
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_htaccess.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_htaccess.erl
index f600c65e92..d95c745b07 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_htaccess.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_htaccess.erl
@@ -272,10 +272,10 @@ controlIfAllowed(AllowedNetworks,UserNetwork,IfAllowed,IfDenied)->
end.
-%---------------------------------------------------------------------%
-%The Denycontrol isn't neccessary to preform since the allow control %
-%override the deny control %
-%---------------------------------------------------------------------%
+%--------------------------------------------------------------------%
+%The Denycontrol isn't necessary to preform since the allow control %
+%override the deny control %
+%--------------------------------------------------------------------%
controlDenyAllow(DeniedNetworks,AllowedNetworks,UserNetwork)->
case AllowedNetworks of
[{allow,all}]->
@@ -657,7 +657,7 @@ getData2(HtAccessFileNames,SplittedPath,Info)->
%----------------------------------------------------------------------
%HtAccessFilenames is a list the names the accesssfiles can have
-%Path is the shortest match agains all alias and documentroot
+%Path is the shortest match against all alias and documentroot
%rest of splitted path is a list of the parts of the path
%Info is the mod recod from the server
%----------------------------------------------------------------------
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_range.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_range.erl
index 4e6030d5e2..f2c45c4a3f 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_range.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_range.erl
@@ -80,7 +80,7 @@ send_range_response(Path,Info,Ranges,FileInfo,LastModified)->
send_range_response(Path,Info,Start,Stop,FileInfo,LastModified)
end.
%%More than one range specified
-%%Send a multipart reponse to the user
+%%Send a multipart response to the user
%
%%An example of an multipart range response
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_responsecontrol.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_responsecontrol.erl
index 76168f3890..a997db6880 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_responsecontrol.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_responsecontrol.erl
@@ -48,8 +48,8 @@ do(Info) ->
%%----------------------------------------------------------------------
-%%Control that the request header did not contians any limitations
-%%wheather a response shall be createed or not
+%%Control that the request header did not contains any limitations
+%%whether a response shall be created or not
%%----------------------------------------------------------------------
do_responsecontrol(Info) ->
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl
index 19b571ac47..cc72a9b6fe 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia.erl
@@ -431,7 +431,7 @@ wrap_trans(State, Fun, Args, Retries, Mod, Kind) ->
%% read lock is only set on the first node
%% Nodes may either be a list of nodes or one node as an atom
%% Mnesia on all Nodes must be connected to each other, but
-%% it is not neccessary that they are up and running.
+%% it is not necessary that they are up and running.
lock(LockItem, LockKind) ->
case get(mnesia_activity_state) of
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_bup.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_bup.erl
index fdbf3e4481..a85a08e4f8 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_bup.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_bup.erl
@@ -775,7 +775,7 @@ restore_tables([Rec | Recs], Header, Schema, State = {local, LocalTabs, L}) ->
restore_tables([], _Header, _Schema, State) ->
State.
-%% Creates all neccessary dat files and inserts
+%% Creates all necessary dat files and inserts
%% the table definitions in the schema table
%%
%% Returns a list of local_tab tuples for all local tables
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint.erl
index 2b5c77b3ba..0403c7e978 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_checkpoint.erl
@@ -332,7 +332,7 @@ really_retain(Name, Tab) ->
%%
%% {min, MinTabs}
%% Minimize redundancy and only keep checkpoint info together with
-%% one replica, preferrably at the local node. If any node involved
+%% one replica, preferably at the local node. If any node involved
%% the checkpoint goes down, the checkpoint is deactivated.
%%
%% {max, MaxTabs}
@@ -345,7 +345,7 @@ really_retain(Name, Tab) ->
%% {ram_overrides_dump, Tabs}
%% Only applicable for ram_copies. Bool controls which versions of
%% the records that should be included in the checkpoint state.
-%% true means that the latest comitted records in ram (i.e. the
+%% true means that the latest committed records in ram (i.e. the
%% records that the application accesses) should be included
%% in the checkpoint. false means that the records dumped to
%% dat-files (the records that will be loaded at startup) should
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_loader.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_loader.erl
index 70fee1741e..07667d73f5 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_loader.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_loader.erl
@@ -61,7 +61,7 @@ do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == disc_copies ->
Repair = mnesia_monitor:get_env(auto_repair),
Args = [{keypos, 2}, public, named_table, Type],
case Reason of
- {dumper, _} -> %% Resources allready allocated
+ {dumper, _} -> %% Resources already allocated
ignore;
_ ->
mnesia_monitor:mktab(Tab, Args),
@@ -82,7 +82,7 @@ do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == disc_copies ->
do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == ram_copies ->
Args = [{keypos, 2}, public, named_table, Type],
case Reason of
- {dumper, _} -> %% Resources allready allocated
+ {dumper, _} -> %% Resources already allocated
ignore;
_ ->
mnesia_monitor:mktab(Tab, Args),
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_locker.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_locker.erl
index 701aa8f598..accb631f2a 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_locker.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_locker.erl
@@ -170,14 +170,14 @@ loop(State) ->
end;
%% If test_set_sticky fails, we send this to all nodes
- %% after aquiring a real write lock on Oid
+ %% after acquiring a real write lock on Oid
{stick, {Tab, _}, N} ->
?ets_insert(mnesia_sticky_locks, {Tab, N}),
loop(State);
%% The caller which sends this message, must have first
- %% aquired a write lock on the entire table
+ %% acquired a write lock on the entire table
{unstick, Tab} ->
?ets_delete(mnesia_sticky_locks, Tab),
loop(State);
@@ -738,11 +738,11 @@ dirty_sticky_lock(Tab, Key, Nodes, Lock) ->
sticky_wlock_table(Tid, Store, Tab) ->
sticky_lock(Tid, Store, {Tab, ?ALL}, write).
-%% aquire a wlock on Oid
+%% acquire a wlock on Oid
%% We store a {Tabname, write, Tid} in all locktables
%% on all nodes containing a copy of Tabname
%% We also store an item {{locks, Tab, Key}, write} in the
-%% local store when we have aquired the lock.
+%% local store when we have acquired the lock.
%%
wlock(Tid, Store, Oid) ->
{Tab, Key} = Oid,
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl
index d1ff09ce29..7fd5f70e23 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_monitor.erl
@@ -144,7 +144,7 @@ check_protocol([{Node, {accept, Mon, _Version, Protocol}} | Tail], Protocols) ->
end,
[node(Mon) | check_protocol(Tail, Protocols)];
false ->
- unlink(Mon), % Get rid of unneccessary link
+ unlink(Mon), % Get rid of unnecessary link
check_protocol(Tail, Protocols)
end;
check_protocol([{Node, {reject, _Mon, Version, Protocol}} | Tail], Protocols) ->
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_schema.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_schema.erl
index ec07e1c1ab..fbd1356a7f 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_schema.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_schema.erl
@@ -1265,7 +1265,7 @@ make_change_table_copy_type(Tab, Node, ToS) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% change index functions ....
-%% Pos is allready added by 1 in both of these functions
+%% Pos is already added by 1 in both of these functions
add_table_index(Tab, Pos) ->
schema_transaction(fun() -> do_add_table_index(Tab, Pos) end).
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl
index 3e08354b5a..09e310530d 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl
@@ -1615,7 +1615,7 @@ commit_participant(Coord, Tid, Bin, C0, DiscNs, _RamNs) ->
do_abort(Tid, Bin) when binary(Bin) ->
%% Possible optimization:
- %% If we want we could pass arround a flag
+ %% If we want we could pass around a flag
%% that tells us whether the binary contains
%% schema ops or not. Only if the binary
%% contains schema ops there are meningful
diff --git a/lib/dialyzer/test/small_SUITE_data/results/chars b/lib/dialyzer/test/small_SUITE_data/results/chars
new file mode 100644
index 0000000000..2c1f8f8d17
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/chars
@@ -0,0 +1,4 @@
+
+chars.erl:29: Invalid type specification for function chars:f/1. The success typing is (#{'b':=50}) -> 'ok'
+chars.erl:32: Function t1/0 has no local return
+chars.erl:32: The call chars:f(#{'b':=50}) breaks the contract (#{'a':=49,'b'=>50,'c'=>51}) -> 'ok'
diff --git a/lib/dialyzer/test/small_SUITE_data/results/fun_arity b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
index cc9db65152..e916b2483f 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/fun_arity
+++ b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
@@ -1,37 +1,37 @@
-fun_arity.erl:100: Fun application will fail since _cor1 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:100: Fun application will fail since _@c1 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:100: Function 'Mfa_0_ko'/1 has no local return
-fun_arity.erl:104: Fun application will fail since _cor1 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:104: Fun application will fail since _@c1 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:104: Function 'Mfa_1_ko'/1 has no local return
-fun_arity.erl:111: Fun application will fail since _cor1 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:111: Fun application will fail since _@c1 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:111: Function mFa_0_ko/1 has no local return
-fun_arity.erl:115: Fun application will fail since _cor1 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:115: Fun application will fail since _@c1 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:115: Function mFa_1_ko/1 has no local return
-fun_arity.erl:122: Fun application will fail since _cor2 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:122: Fun application will fail since _@c2 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:122: Function 'MFa_0_ko'/2 has no local return
-fun_arity.erl:126: Fun application will fail since _cor2 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:126: Fun application will fail since _@c2 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:126: Function 'MFa_1_ko'/2 has no local return
-fun_arity.erl:35: Fun application will fail since _cor0 :: fun(() -> 'ok') is not a function of arity 1
+fun_arity.erl:35: Fun application will fail since _@c0 :: fun(() -> 'ok') is not a function of arity 1
fun_arity.erl:35: Function f_0_ko/0 has no local return
-fun_arity.erl:39: Fun application will fail since _cor0 :: fun((_) -> 'ok') is not a function of arity 0
+fun_arity.erl:39: Fun application will fail since _@c0 :: fun((_) -> 'ok') is not a function of arity 0
fun_arity.erl:39: Function f_1_ko/0 has no local return
-fun_arity.erl:48: Fun application will fail since _cor0 :: fun(() -> 'ok') is not a function of arity 1
+fun_arity.erl:48: Fun application will fail since _@c0 :: fun(() -> 'ok') is not a function of arity 1
fun_arity.erl:48: Function fa_0_ko/0 has no local return
-fun_arity.erl:53: Fun application will fail since _cor0 :: fun((_) -> 'ok') is not a function of arity 0
+fun_arity.erl:53: Fun application will fail since _@c0 :: fun((_) -> 'ok') is not a function of arity 0
fun_arity.erl:53: Function fa_1_ko/0 has no local return
-fun_arity.erl:63: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:63: Fun application will fail since _@c0 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:63: Function mfa_0_ko/0 has no local return
-fun_arity.erl:68: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:68: Fun application will fail since _@c0 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:68: Function mfa_1_ko/0 has no local return
-fun_arity.erl:76: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:76: Fun application will fail since _@c0 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:76: Function mfa_ne_0_ko/0 has no local return
fun_arity.erl:78: Function mf_ne/0 will never be called
-fun_arity.erl:81: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:81: Fun application will fail since _@c0 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:81: Function mfa_ne_1_ko/0 has no local return
fun_arity.erl:83: Function mf_ne/1 will never be called
-fun_arity.erl:89: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:89: Fun application will fail since _@c0 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:89: Function mfa_nd_0_ko/0 has no local return
fun_arity.erl:90: Call to missing or unexported function fun_arity:mf_nd/0
-fun_arity.erl:93: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:93: Fun application will fail since _@c0 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:93: Function mfa_nd_1_ko/0 has no local return
fun_arity.erl:94: Call to missing or unexported function fun_arity:mf_nd/1
diff --git a/lib/dialyzer/test/small_SUITE_data/results/guards b/lib/dialyzer/test/small_SUITE_data/results/guards
index 824a7cfa24..cd0d3cace0 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/guards
+++ b/lib/dialyzer/test/small_SUITE_data/results/guards
@@ -10,8 +10,8 @@ guards.erl:136: The call guards:t16('a') will never return since it differs in t
guards.erl:136: The call guards:t16('c') will never return since it differs in the 1st argument from the success typing arguments: ('b')
guards.erl:55: Function t5/1 has no local return
guards.erl:55: Guard test is_integer(A::atom()) can never succeed
-guards.erl:59: Clause guard cannot succeed. The variable A was matched against the type any()
guards.erl:59: Function t6/1 has no local return
+guards.erl:59: Guard test is_integer(A::atom()) can never succeed
guards.erl:67: The call guards:t7({42}) will never return since it differs in the 1st argument from the success typing arguments: (atom() | integer())
guards.erl:75: The call guards:t8({42}) will never return since it differs in the 1st argument from the success typing arguments: (atom() | integer())
guards.erl:92: The variable _ can never match since previous clauses completely covered the type {'true','true'}
diff --git a/lib/dialyzer/test/small_SUITE_data/src/anno.erl b/lib/dialyzer/test/small_SUITE_data/src/anno.erl
new file mode 100644
index 0000000000..70f1d42141
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/anno.erl
@@ -0,0 +1,18 @@
+-module(anno).
+
+%% OTP-14131
+
+-export([t1/0, t2/0, t3/0]).
+
+t1() ->
+ A = erl_parse:anno_from_term({attribute, 1, module, my_test}),
+ compile:forms([A], []).
+
+t2() ->
+ A = erl_parse:new_anno({attribute, 1, module, my_test}),
+ compile:forms([A], []).
+
+t3() ->
+ A = erl_parse:new_anno({attribute, 1, module, my_test}),
+ T = erl_parse:anno_to_term(A),
+ {attribute, 1, module, my_test} = T.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/chars.erl b/lib/dialyzer/test/small_SUITE_data/src/chars.erl
new file mode 100644
index 0000000000..1e9c8ab6b9
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/chars.erl
@@ -0,0 +1,32 @@
+-module(chars).
+
+%% ERL-313
+
+-export([t/0]).
+-export([t1/0]).
+
+-record(r, {f :: $A .. $Z}).
+
+-type cs() :: $A..$Z | $a .. $z | $/.
+
+-spec t() -> $0-$0..$9-$0| $?.
+
+t() ->
+ c(#r{f = $z - 3}),
+ c($z - 3),
+ c($B).
+
+-spec c(cs()) -> $3-$0..$9-$0.
+
+c($A + 1) -> 2;
+c(C) ->
+ case C of
+ $z - 3 -> 3;
+ #r{f = $z - 3} -> 7
+ end.
+
+%% Display contract with character in warning:
+-spec f(#{a := $1, b => $2, c => $3}) -> ok. % invalid type spec
+f(_) -> ok.
+
+t1() -> f(#{b => $2}). % breaks the contract
diff --git a/lib/dialyzer/test/small_SUITE_data/src/ms.erl b/lib/dialyzer/test/small_SUITE_data/src/ms.erl
new file mode 100644
index 0000000000..47a5e886cf
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/ms.erl
@@ -0,0 +1,8 @@
+-module(ms).
+-export([t/0]).
+
+-include_lib("stdlib/include/ms_transform.hrl").
+
+t() ->
+ MS = dbg:fun2ms(fun(All) -> message(All) end),
+ erlang:trace_pattern({m, f, '_'}, MS).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/tuple1.erl b/lib/dialyzer/test/small_SUITE_data/src/tuple1.erl
index d608275efe..88ac486044 100644
--- a/lib/dialyzer/test/small_SUITE_data/src/tuple1.erl
+++ b/lib/dialyzer/test/small_SUITE_data/src/tuple1.erl
@@ -2,7 +2,7 @@
%%% File : tuple1.erl
%%% Author : Tobias Lindahl <[email protected]>
%%% Description : Exposed two bugs in the analysis;
-%%% one supressed warning and one crash.
+%%% one suppressed warning and one crash.
%%%
%%% Created : 13 Nov 2006 by Tobias Lindahl <[email protected]>
%%%-------------------------------------------------------------------
diff --git a/lib/dialyzer/test/typer_SUITE.erl b/lib/dialyzer/test/typer_SUITE.erl
new file mode 100644
index 0000000000..da5b961643
--- /dev/null
+++ b/lib/dialyzer/test/typer_SUITE.erl
@@ -0,0 +1,158 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(typer_SUITE).
+
+-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ smoke/1]).
+
+-include_lib("common_test/include/ct.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [smoke].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ OutDir = proplists:get_value(priv_dir, Config),
+ case dialyzer_common:check_plt(OutDir) of
+ fail -> {skip, "Plt creation/check failed."};
+ ok -> [{dialyzer_options, []}|Config]
+ end.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+smoke(Config) ->
+ Code = <<"-module(typer_test_module).
+ -compile([export_all,nowarn_export_all]).
+ a(L) ->
+ L ++ [1,2,3].">>,
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Src = filename:join(PrivDir, "typer_test_module.erl"),
+ ok = file:write_file(Src, Code),
+ Args = "--plt " ++ PrivDir ++ "dialyzer_plt",
+ Res = ["^$",
+ "^%% File:",
+ "^%% ----",
+ "^-spec a",
+ "^_OK_"],
+ run(Config, Args, Src, Res),
+ ok.
+
+typer() ->
+ case os:find_executable("typer") of
+ false ->
+ ct:fail("Can't find typer");
+ Typer ->
+ Typer
+ end.
+
+%% Runs a command.
+
+run(Config, Args0, Name, Expect) ->
+ Args = Args0 ++ " " ++ Name,
+ Result = run_command(Config, Args),
+ verify_result(Result, Expect).
+
+verify_result(Result, Expect) ->
+ Messages = split(Result, [], []),
+ io:format("Result: ~p", [Messages]),
+ io:format("Expected: ~p", [Expect]),
+ match_messages(Messages, Expect).
+
+split([$\n|Rest], Current, Lines) ->
+ split(Rest, [], [lists:reverse(Current)|Lines]);
+split([$\r|Rest], Current, Lines) ->
+ split(Rest, Current, Lines);
+split([Char|Rest], Current, Lines) ->
+ split(Rest, [Char|Current], Lines);
+split([], [], Lines) ->
+ lists:reverse(Lines);
+split([], Current, Lines) ->
+ split([], [], [lists:reverse(Current)|Lines]).
+
+match_messages([Msg|Rest1], [Regexp|Rest2]) ->
+ case re:run(Msg, Regexp, [{capture,none}, unicode]) of
+ match ->
+ ok;
+ nomatch ->
+ io:format("Not matching: ~s\n", [Msg]),
+ io:format("Regexp : ~s\n", [Regexp]),
+ ct:fail(message_mismatch)
+ end,
+ match_messages(Rest1, Rest2);
+match_messages([], [Expect|Rest]) ->
+ ct:fail({too_few_messages, [Expect|Rest]});
+match_messages([Msg|Rest], []) ->
+ ct:fail({too_many_messages, [Msg|Rest]});
+match_messages([], []) ->
+ ok.
+
+%% Runs the command using os:cmd/1.
+%%
+%% Returns the output from the command (as a list of characters with
+%% embedded newlines). The very last line will indicate the
+%% exit status of the command, where _OK_ means zero, and _ERROR_
+%% a non-zero exit status.
+
+run_command(Config, Args) ->
+ TmpDir = filename:join(proplists:get_value(priv_dir, Config), "tmp"),
+ file:make_dir(TmpDir),
+ {RunFile, Run, Script} = run_command(TmpDir, os:type(), Args),
+ ok = file:write_file(filename:join(TmpDir, RunFile),
+ unicode:characters_to_binary(Script)),
+ io:format("~ts\n", [Script]),
+ os:cmd(Run).
+
+run_command(Dir, {win32, _}, Args) ->
+ BatchFile = filename:join(Dir, "run.bat"),
+ Run = re:replace(filename:rootname(BatchFile), "/", "\\",
+ [global,{return,list}]),
+ Typer = typer(),
+ {BatchFile,
+ Run,
+ ["@echo off\r\n",
+ "\"",Typer,"\" ",Args, "\r\n",
+ "if errorlevel 1 echo _ERROR_\r\n",
+ "if not errorlevel 1 echo _OK_\r\n"]};
+run_command(Dir, {unix, _}, Args) ->
+ TyperDir = filename:dirname(typer()),
+ Name = filename:join(Dir, "run"),
+ {Name,
+ "/bin/sh " ++ Name,
+ ["#!/bin/sh\n",
+ "PATH=\"",TyperDir,":$PATH\"\n",
+ "typer ",Args,"\n",
+ "case $? in\n",
+ " 0) echo '_OK_';;\n",
+ " *) echo '_ERROR_';;\n",
+ "esac\n"]};
+run_command(_Dir, Other, _Args) ->
+ ct:fail("Don't know how to test exit code for ~p", [Other]).
diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk
index 077fe01e85..4a1a7c25a0 100644
--- a/lib/dialyzer/vsn.mk
+++ b/lib/dialyzer/vsn.mk
@@ -1 +1 @@
-DIALYZER_VSN = 3.0
+DIALYZER_VSN = 3.2
diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml
index d68a78ed6d..2cbe48ecce 100644
--- a/lib/diameter/doc/src/diameter.xml
+++ b/lib/diameter/doc/src/diameter.xml
@@ -21,7 +21,7 @@
<copyright>
<year>2011</year>
-<year>2016</year>
+<year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -94,12 +94,12 @@ in this module.</p>
<taglist>
-<tag><c>Address()</c></tag>
-<tag><c>DiameterIdentity()</c></tag>
-<tag><c>Grouped()</c></tag>
-<tag><c>OctetString()</c></tag>
-<tag><c>Time()</c></tag>
-<tag><c>Unsigned32()</c></tag>
+<tag><c>Address()</c></tag><item/>
+<tag><c>DiameterIdentity()</c></tag><item/>
+<tag><c>Grouped()</c></tag><item/>
+<tag><c>OctetString()</c></tag><item/>
+<tag><c>Time()</c></tag><item/>
+<tag><c>Unsigned32()</c></tag><item/>
<tag><c>UTF8String()</c></tag>
<item>
<p>
@@ -159,8 +159,7 @@ Has one the following types.</p>
<p>
Unique identifier for the application in the scope of the
service.
-Defaults to the value of the <c>dictionary</c> option if
-unspecified.</p>
+Defaults to the value of the <c>dictionary</c> option.</p>
</item>
<tag><c>{dictionary, atom()}</c></tag>
@@ -187,7 +186,7 @@ Initial callback state.
The prevailing state is passed to some
&man_app;
callbacks, which can then return a new state.
-Defaults to the value of the <c>alias</c> option if unspecified.</p>
+Defaults to the value of the <c>alias</c> option.</p>
</item>
<tag><c>{call_mutates_state, true|false}</c></tag>
@@ -195,7 +194,7 @@ Defaults to the value of the <c>alias</c> option if unspecified.</p>
<p>
Whether or not the &app_pick_peer;
application callback can modify the application state.
-Defaults to <c>false</c> if unspecified.</p>
+Defaults to <c>false</c>.</p>
<warning>
<p>
@@ -228,7 +227,7 @@ question is as if a callback had taken place and returned
<c>{error, failure}</c>.</p>
<p>
-Defaults to <c>discard</c> if unspecified.</p>
+Defaults to <c>discard</c>.</p>
</item>
<tag><c>{request_errors, answer_3xxx|answer|callback}</c></tag>
@@ -249,7 +248,7 @@ place and its return value determines the answer sent to the peer, if
any.</p>
<p>
-Defaults to <c>answer_3xxx</c> if unspecified.</p>
+Defaults to <c>answer_3xxx</c>.</p>
<note>
<p>
@@ -301,6 +300,17 @@ corresponding list of filters.
Defaults to <c>none</c>.</p>
</item>
+<tag><c>{peer, &app_peer_ref;}</c></tag>
+<item>
+<p>
+Peer to which the request in question can be sent, preempting the
+selection of peers having advertised support for the Diameter
+application in question.
+Multiple options can be specified, and their order is
+respected in the candidate lists passed to a subsequent
+&app_pick_peer; callback.</p>
+</item>
+
<tag><c>{timeout, &dict_Unsigned32;}</c></tag>
<item>
<p>
@@ -339,8 +349,8 @@ Has one of the following types.</p>
<taglist>
-<tag><c>{'Origin-Host', &dict_DiameterIdentity;}</c></tag>
-<tag><c>{'Origin-Realm', &dict_DiameterIdentity;}</c></tag>
+<tag><c>{'Origin-Host', &dict_DiameterIdentity;}</c></tag><item/>
+<tag><c>{'Origin-Realm', &dict_DiameterIdentity;}</c></tag><item/>
<tag><c>{'Host-IP-Address', [&dict_Address;]}</c></tag>
<item>
<p>
@@ -352,8 +362,8 @@ question communicates an address list as described in
&man_transport;</p>
</item>
-<tag><c>{'Vendor-Id', &dict_Unsigned32;}</c></tag>
-<tag><c>{'Product-Name', &dict_UTF8String;}</c></tag>
+<tag><c>{'Vendor-Id', &dict_Unsigned32;}</c></tag><item/>
+<tag><c>{'Product-Name', &dict_UTF8String;}</c></tag><item/>
<tag><c>{'Origin-State-Id', &dict_Unsigned32;}</c></tag>
<item>
<p>
@@ -366,8 +376,8 @@ can be used as to retrieve a value that is computed when the diameter
application is started.</p>
</item>
-<tag><c>{'Supported-Vendor-Id', [&dict_Unsigned32;]}</c></tag>
-<tag><c>{'Auth-Application-Id', [&dict_Unsigned32;]}</c></tag>
+<tag><c>{'Supported-Vendor-Id', [&dict_Unsigned32;]}</c></tag><item/>
+<tag><c>{'Auth-Application-Id', [&dict_Unsigned32;]}</c></tag><item/>
<tag><c>{'Inband-Security-Id', [&dict_Unsigned32;]}</c></tag>
<item>
<p>
@@ -377,9 +387,9 @@ If 1 (TLS) is specified then TLS is selected if the CER/CEA received
from the peer offers it.</p>
</item>
-<tag><c>{'Acct-Application-Id', [&dict_Unsigned32;]}</c></tag>
-<tag><c>{'Vendor-Specific-Application-Id', [&dict_Grouped;]}</c></tag>
-<tag><c>{'Firmware-Revision', &dict_Unsigned32;}</c></tag>
+<tag><c>{'Acct-Application-Id', [&dict_Unsigned32;]}</c></tag><item/>
+<tag><c>{'Vendor-Specific-Application-Id', [&dict_Grouped;]}</c></tag><item/>
+<tag><c>{'Firmware-Revision', &dict_Unsigned32;}</c></tag><item/>
</taglist>
@@ -567,9 +577,8 @@ Can have one of the following types.</p>
<taglist>
-<tag><c>start</c></tag>
+<tag><c>start</c></tag><item/>
<tag><c>stop</c></tag>
-
<item>
<p>
The service is being started or stopped.
@@ -578,8 +587,8 @@ No event follows a <c>stop</c> event, and this event
implies the termination of all transport processes.</p>
</item>
-<tag><c>{up, Ref, Peer, Config, Pkt}</c></tag>
-<tag><c>{up, Ref, Peer, Config}</c></tag>
+<tag><c>{up, Ref, Peer, Config, Pkt}</c></tag><item/>
+<tag><c>{up, Ref, Peer, Config}</c></tag><item/>
<tag><c>{down, Ref, Peer, Config}</c></tag>
<item>
<pre>
@@ -788,8 +797,8 @@ be matched by corresponding &capability; configuration, of
</item>
-<marker id="incoming_maxlen"/>
-<tag><c>{incoming_maxlen, 0..16777215}</c></tag>
+<tag>
+<marker id="incoming_maxlen"/><c>{incoming_maxlen, 0..16777215}</c></tag>
<item>
<p>
Bound on the expected size of incoming Diameter messages.
@@ -917,8 +926,8 @@ Options <c>monitor</c> and <c>link</c> are ignored.</p>
Defaults to the empty list.</p>
</item>
-<marker id="strict_mbit"/>
-<tag><c>{strict_mbit, boolean()}</c></tag>
+<tag>
+<marker id="strict_mbit"/><c>{strict_mbit, boolean()}</c></tag>
<item>
<p>
Whether or not to regard an AVP setting the M-bit as erroneous when
@@ -935,7 +944,7 @@ Defaults to <c>true</c>.</p>
<p>
RFC 6733 is unclear about the semantics of the M-bit.
One the one hand, the CCF specification in section 3.2 documents AVP
-in a command grammar as meaning <b>any</b> arbitrary AVP; on the
+in a command grammar as meaning <em>any</em> arbitrary AVP; on the
other hand, 1.3.4 states that AVPs setting the M-bit cannot be added
to an existing command: the modified command must instead be
placed in a new Diameter application.</p>
@@ -945,7 +954,7 @@ allowing arbitrary AVPs setting the M-bit in a command makes its
interpretation implementation-dependent, since there's no
guarantee that all implementations will understand the same set of
arbitrary AVPs in the context of a given command.
-However, interpreting <c>AVP</c> in a command grammar as <b>any</b>
+However, interpreting <c>AVP</c> in a command grammar as any
AVP, regardless of M-bit, renders 1.3.4 meaningless, since the receiver
can simply ignore any AVP it thinks isn't relevant, regardless of the
sender's intent.</p>
@@ -960,8 +969,8 @@ occur in the message in question.</p>
</item>
-<marker id="string_decode"/>
-<tag><c>{string_decode, boolean()}</c></tag>
+<tag>
+<marker id="string_decode"/><c>{string_decode, boolean()}</c></tag>
<item>
<p>
Whether or not to decode AVPs of type &dict_OctetString; and its
@@ -1031,8 +1040,9 @@ Option passed to &add_transport;.
Has one of the following types.</p>
<taglist>
-<marker id="applications"/>
-<tag><c>{applications, [&application_alias;]}</c></tag>
+
+<tag>
+<marker id="applications"/><c>{applications, [&application_alias;]}</c></tag>
<item>
<p>
Diameter applications to which the transport should be restricted.
@@ -1050,8 +1060,8 @@ implies having to set matching *-Application-Id AVPs in a
</item>
-<marker id="capabilities"/>
-<tag><c>{capabilities, [&capability;]}</c></tag>
+<tag>
+<marker id="capabilities"/><c>{capabilities, [&capability;]}</c></tag>
<item>
<p>
AVPs used to construct outgoing CER/CEA messages.
@@ -1064,8 +1074,8 @@ may be particularly appropriate for Inband-Security-Id, in case
TLS is desired over TCP as implemented by &man_tcp;.</p>
</item>
-<marker id="capabilities_cb"/>
-<tag><c>{capabilities_cb, &evaluable;}</c></tag>
+<tag>
+<marker id="capabilities_cb"/><c>{capabilities_cb, &evaluable;}</c></tag>
<item>
<p>
Callback invoked upon reception of CER/CEA during capabilities
@@ -1112,8 +1122,8 @@ case the corresponding callbacks are applied until either all return
<c>ok</c> or one does not.</p>
</item>
-<marker id="capx_timeout"/>
-<tag><c>{capx_timeout, &dict_Unsigned32;}</c></tag>
+<tag>
+<marker id="capx_timeout"/><c>{capx_timeout, &dict_Unsigned32;}</c></tag>
<item>
<p>
Number of milliseconds after which a transport process having an
@@ -1127,8 +1137,8 @@ For a listening transport, the peer determines the timing.</p>
Defaults to 10000.</p>
</item>
-<marker id="connect_timer"/>
-<tag><c>{connect_timer, Tc}</c></tag>
+<tag>
+<marker id="connect_timer"/><c>{connect_timer, Tc}</c></tag>
<item>
<pre>
Tc = &dict_Unsigned32;
@@ -1158,9 +1168,8 @@ Defaults to 30000 for a connecting transport and 60000 for a listening
transport.</p>
</item>
-<marker id="disconnect_cb"/>
-<tag><c>{disconnect_cb, &evaluable;}</c></tag>
-
+<tag>
+<marker id="disconnect_cb"/><c>{disconnect_cb, &evaluable;}</c></tag>
<item>
<p>
Callback invoked prior to terminating the transport process of a
@@ -1236,8 +1245,8 @@ configured them.</p>
Defaults to a single callback returning <c>dpr</c>.</p>
</item>
-<marker id="dpa_timeout"/>
-<tag><c>{dpa_timeout, &dict_Unsigned32;}</c></tag>
+<tag>
+<marker id="dpa_timeout"/><c>{dpa_timeout, &dict_Unsigned32;}</c></tag>
<item>
<p>
Number of milliseconds after which a transport connection is
@@ -1247,8 +1256,8 @@ terminated following an outgoing DPR if DPA is not received.</p>
Defaults to 1000.</p>
</item>
-<marker id="dpr_timeout"/>
-<tag><c>{dpr_timeout, &dict_Unsigned32;}</c></tag>
+<tag>
+<marker id="dpr_timeout"/><c>{dpr_timeout, &dict_Unsigned32;}</c></tag>
<item>
<p>
Number of milliseconds after which a transport connection is
@@ -1259,8 +1268,8 @@ connection.</p>
Defaults to 5000.</p>
</item>
-<marker id="length_errors"/>
-<tag><c>{length_errors, exit|handle|discard}</c></tag>
+<tag>
+<marker id="length_errors"/><c>{length_errors, exit|handle|discard}</c></tag>
<item>
<p>
How to deal with errors in the Message Length field of the
@@ -1308,8 +1317,8 @@ the same peer.</p>
</item>
-<marker id="spawn_opt"/>
-<tag><c>{spawn_opt, [term()]}</c></tag>
+<tag>
+<marker id="spawn_opt"/><c>{spawn_opt, [term()]}</c></tag>
<item>
<p>
Options passed to &spawn_opt; when spawning a process for an
@@ -1320,15 +1329,15 @@ Options <c>monitor</c> and <c>link</c> are ignored.</p>
Defaults to the list configured on the service if not specified.</p>
</item>
-<marker id="transport_config"/>
-<tag><c>{transport_config, term()}</c></tag>
+<tag>
+<marker id="transport_config"/><c>{transport_config, term()}</c></tag><item/>
<tag><c>{transport_config, term(), &dict_Unsigned32; | infinity}</c></tag>
<item>
<p>
Term passed as the third argument to the &transport_start; function of
the relevant &transport_module; in order to
start a transport process.
-Defaults to the empty list if unspecified.</p>
+Defaults to the empty list.</p>
<p>
The 3-tuple form additionally specifies an interval, in milliseconds,
@@ -1349,12 +1358,12 @@ request a connection with one peer over SCTP or another
To listen on both SCTP and TCP, define one transport for each.</p>
</item>
-<marker id="transport_module"/>
-<tag><c>{transport_module, atom()}</c></tag>
+<tag>
+<marker id="transport_module"/><c>{transport_module, atom()}</c></tag>
<item>
<p>
Module implementing a transport process as defined in &man_transport;.
-Defaults to <c>diameter_tcp</c> if unspecified.</p>
+Defaults to <c>diameter_tcp</c>.</p>
<p>
Multiple <c>transport_module</c> and &transport_config;
@@ -1369,8 +1378,9 @@ modules in order until one establishes a connection within the
corresponding timeout (see below) or all fail.</p>
</item>
-<marker id="watchdog_config"/>
-<tag><c>{watchdog_config, [{okay|suspect, non_neg_integer()}]}</c></tag>
+<tag>
+<marker id="watchdog_config"/><c>{watchdog_config,
+ [{okay|suspect, non_neg_integer()}]}</c></tag>
<item>
<p>
Configuration that alters the behaviour of the watchdog
@@ -1393,8 +1403,8 @@ misbehaving nodes during test.</p>
</warning>
</item>
-<marker id="watchdog_timer"/>
-<tag><c>{watchdog_timer, TwInit}</c></tag>
+<tag>
+<marker id="watchdog_timer"/><c>{watchdog_timer, TwInit}</c></tag>
<item>
<pre>
TwInit = &dict_Unsigned32;
@@ -1412,7 +1422,7 @@ the callback.</p>
<p>
An integer value must be at least 6000 as required by RFC 3539.
-Defaults to 30000 if unspecified.</p>
+Defaults to 30000.</p>
</item>
</taglist>
@@ -1422,10 +1432,10 @@ Unrecognized options are silently ignored but are returned unmodified
by &service_info; and can be referred to
in predicate functions passed to &remove_transport;.</p>
-<marker id="transport_ref"/>
</item>
-<tag><c>transport_ref() = reference()</c></tag>
+<tag>
+<marker id="transport_ref"/><c>transport_ref() = reference()</c></tag>
<item>
<p>
Reference returned by &add_transport; that
@@ -1682,17 +1692,17 @@ returned.</p>
<taglist>
-<tag><c>'Origin-Host'</c></tag>
-<tag><c>'Origin-Realm'</c></tag>
-<tag><c>'Vendor-Id'</c></tag>
-<tag><c>'Product-Name'</c></tag>
-<tag><c>'Origin-State-Id'</c></tag>
-<tag><c>'Host-IP-Address'</c></tag>
-<tag><c>'Supported-Vendor'</c></tag>
-<tag><c>'Auth-Application-Id'</c></tag>
-<tag><c>'Inband-Security-Id'</c></tag>
-<tag><c>'Acct-Application-Id'</c></tag>
-<tag><c>'Vendor-Specific-Application-Id'</c></tag>
+<tag><c>'Origin-Host'</c></tag><item/>
+<tag><c>'Origin-Realm'</c></tag><item/>
+<tag><c>'Vendor-Id'</c></tag><item/>
+<tag><c>'Product-Name'</c></tag><item/>
+<tag><c>'Origin-State-Id'</c></tag><item/>
+<tag><c>'Host-IP-Address'</c></tag><item/>
+<tag><c>'Supported-Vendor'</c></tag><item/>
+<tag><c>'Auth-Application-Id'</c></tag><item/>
+<tag><c>'Inband-Security-Id'</c></tag><item/>
+<tag><c>'Acct-Application-Id'</c></tag><item/>
+<tag><c>'Vendor-Specific-Application-Id'</c></tag><item/>
<tag><c>'Firmware-Revision'</c></tag>
<item>
<p>
diff --git a/lib/diameter/doc/src/diameter_app.xml b/lib/diameter/doc/src/diameter_app.xml
index 973b6eb732..dfcd00975b 100644
--- a/lib/diameter/doc/src/diameter_app.xml
+++ b/lib/diameter/doc/src/diameter_app.xml
@@ -90,17 +90,14 @@ is called in response to an incoming Diameter request message.</p>
</list>
-</description>
-
-<note>
<p>
-The arities given for the the callback functions here assume no extra
-arguments.
+The arities for the the callback functions here assume no extra arguments.
All functions will also be passed any extra arguments configured with
the callback module itself when calling &mod_start_service;
and, for the call-specific callbacks, any extra arguments passed to
&mod_call;.</p>
-</note>
+
+</description>
<!-- ===================================================================== -->
<!-- ===================================================================== -->
@@ -110,9 +107,8 @@ and, for the call-specific callbacks, any extra arguments passed to
<taglist>
-<marker id="capabilities"/>
-
-<tag><c>capabilities() = #diameter_caps{}</c></tag>
+<tag>
+<marker id="capabilities"/><c>capabilities() = #diameter_caps{}</c></tag>
<item>
<p>
A record containing the identities of
@@ -126,9 +122,8 @@ Optional or possibly multiple values are encoded as lists of values,
mandatory values as the bare value.</p>
</item>
-<marker id="message"/>
-
-<tag><c>message() = &codec_message;</c></tag>
+<tag>
+<marker id="message"/><c>message() = &codec_message;</c></tag>
<item>
<p>
The representation of a Diameter message as passed to
@@ -136,9 +131,8 @@ The representation of a Diameter message as passed to
</item>
-<marker id="packet"/>
-
-<tag><c>packet() = &codec_packet;</c></tag>
+<tag>
+<marker id="packet"/><c>packet() = &codec_packet;</c></tag>
<item>
<p>
A container for incoming and outgoing Diameter messages that's passed
@@ -146,25 +140,22 @@ through encode/decode and transport.
Fields should not be set in return values except as documented.</p>
</item>
-<marker id="peer_ref"/>
-
-<tag><c>peer_ref() = term()</c></tag>
+<tag>
+<marker id="peer_ref"/><c>peer_ref() = term()</c></tag>
<item>
<p>
A term identifying a transport connection with a Diameter peer.</p>
</item>
-<marker id="peer"/>
-
-<tag><c>peer() = {&peer_ref;, &capabilities;}</c></tag>
+<tag>
+<marker id="peer"/><c>peer() = {&peer_ref;, &capabilities;}</c></tag>
<item>
<p>
A tuple representing a Diameter peer connection.</p>
</item>
-<marker id="state"/>
-
-<tag><c>state() = term()</c></tag>
+<tag>
+<marker id="state"/><c>state() = term()</c></tag>
<item>
<p>
The state maintained by the application callback functions
diff --git a/lib/diameter/doc/src/diameter_codec.xml b/lib/diameter/doc/src/diameter_codec.xml
index a0313e2877..0117c1c88a 100644
--- a/lib/diameter/doc/src/diameter_codec.xml
+++ b/lib/diameter/doc/src/diameter_codec.xml
@@ -13,7 +13,8 @@
<erlref>
<header>
<copyright>
-<year>2012</year><year>2016</year>
+<year>2012</year>
+<year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -53,17 +54,17 @@ communicated to &man_app; callbacks.
Similarly, outgoing Diameter messages are encoded into binary() before
being passed to the appropriate &man_transport; module for
transmission.
-The functions in this module implement this encode/decode.</p>
+The functions documented here implement the default encode/decode.</p>
-<note>
+<warning>
<p>
-Calls to this module are made by diameter itself as a consequence of
-configuration passed to &mod_start_service;.
-The encode/decode functions may also be useful for other purposes (eg.
-test) but the diameter user does not need to call them explicitly when
+The diameter user does not need to call functions here explicitly when
sending and receiving messages using &mod_call; and the callback
-interface documented in &man_app;.</p>
-</note>
+interface documented in &man_app;: diameter itself provides encode/decode
+as a consequence of configuration passed to &mod_start_service;, and
+the results may differ from those returned by the functions documented
+here, depending on configuration.</p>
+</warning>
<p>
The &header; and &packet; records below
@@ -88,10 +89,9 @@ files resulting from dictionary file compilation.</p>
<taglist>
-<marker id="integers"/>
-
-<tag><c>uint8()&nbsp; = 0..255</c></tag>
-<tag><c>uint24() = 0..16777215</c></tag>
+<tag>
+<marker id="integers"/><c>uint8()&nbsp; = 0..255</c></tag><item/>
+<tag><c>uint24() = 0..16777215</c></tag><item/>
<tag><c>uint32() = 0..4294967295</c></tag>
<item>
<p>
@@ -99,9 +99,8 @@ files resulting from dictionary file compilation.</p>
headers.</p>
</item>
-<marker id="avp"/>
-
-<tag><c>avp() = #diameter_avp{}</c></tag>
+<tag>
+<marker id="avp"/><c>avp() = #diameter_avp{}</c></tag>
<item>
<p>
The application-neutral representation of an AVP.
@@ -116,9 +115,9 @@ Fields have the following types.</p>
<taglist>
-<tag><c>code = uint32()</c></tag>
-<tag><c>is_mandatory = boolean()</c></tag>
-<tag><c>need_encryption = boolean()</c></tag>
+<tag><c>code = uint32()</c></tag><item/>
+<tag><c>is_mandatory = boolean()</c></tag><item/>
+<tag><c>need_encryption = boolean()</c></tag><item/>
<tag><c>vendor_id = uint32() | undefined</c></tag>
<item>
<p>
@@ -167,9 +166,8 @@ Possible types are <c>undefined</c> and the Diameter types:
</item>
-<marker id="dictionary"/>
-
-<tag><c>dictionary() = module()</c></tag>
+<tag>
+<marker id="dictionary"/><c>dictionary() = module()</c></tag>
<item>
<p>
@@ -179,9 +177,8 @@ The interface provided by a dictionary module is an
implementation detail that may change.</p>
</item>
-<marker id="header"/>
-
-<tag><c>header() = #diameter_header{}</c></tag>
+<tag>
+<marker id="header"/><c>header() = #diameter_header{}</c></tag>
<item>
<p>
The record representation of the Diameter header.
@@ -204,11 +201,11 @@ Fields have the following types.</p>
<taglist>
-<tag><c>version = uint8()</c></tag>
-<tag><c>length = uint24()</c></tag>
-<tag><c>cmd_code = uint24()</c></tag>
-<tag><c>application_id = uint32()</c></tag>
-<tag><c>hop_by_hop_id = uint32()</c></tag>
+<tag><c>version = uint8()</c></tag><item/>
+<tag><c>length = uint24()</c></tag><item/>
+<tag><c>cmd_code = uint24()</c></tag><item/>
+<tag><c>application_id = uint32()</c></tag><item/>
+<tag><c>hop_by_hop_id = uint32()</c></tag><item/>
<tag><c>end_to_end_id = uint32()</c></tag>
<item>
<p>
@@ -217,9 +214,9 @@ Hop-by-Hop Identifier and End-to-End Identifier fields of the Diameter
header.</p>
</item>
-<tag><c>is_request = boolean()</c></tag>
-<tag><c>is_proxiable = boolean()</c></tag>
-<tag><c>is_error = boolean()</c></tag>
+<tag><c>is_request = boolean()</c></tag><item/>
+<tag><c>is_proxiable = boolean()</c></tag><item/>
+<tag><c>is_error = boolean()</c></tag><item/>
<tag><c>is_retransmitted = boolean()</c></tag>
<item>
<p>
@@ -232,9 +229,8 @@ header.</p>
</item>
-<marker id="message"/>
-
-<tag><c>message() = record() | list()</c></tag>
+<tag>
+<marker id="message"/><c>message() = record() | list()</c></tag>
<item>
<p>
The representation of a Diameter message as passed to
@@ -257,9 +253,8 @@ question: messages are sent exactly as specified.</p>
</item>
-<marker id="packet"/>
-
-<tag><c>packet() = #diameter_packet{}</c></tag>
+<tag>
+<marker id="packet"/><c>packet() = #diameter_packet{}</c></tag>
<item>
<p>
A container for incoming and outgoing Diameter messages.
@@ -296,7 +291,7 @@ corresponding values.</p>
<warning>
<p>
-A record-valued <c>msg</c> field does <b>not</b> imply an absence of
+A record-valued <c>msg</c> field does <em>not</em> imply an absence of
decode errors.
The <c>errors</c> field should also be examined.</p>
</warning>
diff --git a/lib/diameter/doc/src/diameter_dict.xml b/lib/diameter/doc/src/diameter_dict.xml
index ae40f99aee..94016d9466 100644
--- a/lib/diameter/doc/src/diameter_dict.xml
+++ b/lib/diameter/doc/src/diameter_dict.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE erlref SYSTEM "fileref.dtd" [
+<!DOCTYPE fileref SYSTEM "fileref.dtd" [
<!ENTITY format
'<seealso marker="#FILE_FORMAT">FILE FORMAT</seealso>'>
<!ENTITY records
@@ -16,7 +16,8 @@
<header>
<copyright>
-<year>2011</year><year>2016</year>
+<year>2011</year>
+<year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -121,9 +122,8 @@ The order in which sections are specified is unimportant.</p>
<taglist>
-<marker id="id"/>
-
-<tag><c>@id Number</c></tag>
+<tag>
+<marker id="id"/><c>@id Number</c></tag>
<item>
<p>
Defines the integer Number as the Diameter Application Id of the
@@ -146,14 +146,13 @@ Example:</p>
</item>
-<marker id="name"/>
-
-<tag><c>@name Mod</c></tag>
+<tag>
+<marker id="name"/><c>@name Mod</c></tag>
<item>
<p>
Defines the name of the generated dictionary module.
Can occur at most once and defaults to the name of the dictionary file
-minus any extension if unspecified.
+minus any extension.
The section has empty content.</p>
<p>
@@ -169,9 +168,8 @@ Example:</p>
</item>
-<marker id="prefix"/>
-
-<tag><c>@prefix Name</c></tag>
+<tag>
+<marker id="prefix"/><c>@prefix Name</c></tag>
<item>
<p>
Defines Name as the prefix to be added to record and constant names
@@ -194,9 +192,8 @@ Example:</p>
</item>
-<marker id="vendor"/>
-
-<tag><c>@vendor Number Name</c></tag>
+<tag>
+<marker id="vendor"/><c>@vendor Number Name</c></tag>
<item>
<p>
Defines the integer Number as the the default Vendor-Id of AVPs for
@@ -216,9 +213,8 @@ Example:</p>
</item>
-<marker id="avp_vendor_id"/>
-
-<tag><c>@avp_vendor_id Number</c></tag>
+<tag>
+<marker id="avp_vendor_id"/><c>@avp_vendor_id Number</c></tag>
<item>
<p>
Defines the integer Number as the Vendor-Id of the AVPs listed in the
@@ -238,9 +234,8 @@ Region-Set
</item>
-<marker id="inherits"/>
-
-<tag><c>@inherits Mod</c></tag>
+<tag>
+<marker id="inherits"/><c>@inherits Mod</c></tag>
<item>
<p>
Defines the name of a dictionary module containing AVP
@@ -274,9 +269,8 @@ Example:</p>
</pre>
</item>
-<marker id="avp_types"/>
-
-<tag><c>@avp_types</c></tag>
+<tag>
+<marker id="avp_types"/><c>@avp_types</c></tag>
<item>
<p>
Defines the name, code, type and flags of individual AVPs.
@@ -308,18 +302,17 @@ The P flag has been deprecated by &the_rfc;.</p>
</item>
-<marker id="custom_types"/>
-
-<tag><c>@custom_types Mod</c></tag>
+<tag>
+<marker id="custom_types"/><c>@custom_types Mod</c></tag>
<item>
<p>
Specifies AVPs for which module Mod provides encode/decode functions.
The section contents consists of AVP names.
-For each such name, <c>Mod:Name(encode|decode, Type, Data)</c> is
+For each such name, <c>Mod:Name(encode|decode, Type, Data, Opts)</c> is
expected to provide encode/decode for values of the AVP, where Name is
the name of the AVP, Type is it's type as declared in the
-<c>@avp_types</c> section of the dictionary and Data is the value to
-encode/decode.</p>
+<c>@avp_types</c> section of the dictionary, Data is the value to
+encode/decode, and Opts is a term that is passed through encode/decode.</p>
<p>
Example:</p>
@@ -331,14 +324,13 @@ Framed-IP-Address
</pre>
</item>
-<marker id="codecs"/>
-
-<tag><c>@codecs Mod</c></tag>
+<tag>
+<marker id="codecs"/><c>@codecs Mod</c></tag>
<item>
<p>
Like <c>@custom_types</c> but requires the specified module to export
-<c>Mod:Type(encode|decode, Name, Data)</c> rather than
-<c>Mod:Name(encode|decode, Type, Data)</c>.</p>
+<c>Mod:Type(encode|decode, Name, Data, Opts)</c> rather than
+<c>Mod:Name(encode|decode, Type, Data, Opts)</c>.</p>
<p>
Example:</p>
@@ -350,9 +342,8 @@ Framed-IP-Address
</pre>
</item>
-<marker id="messages"/>
-
-<tag><c>@messages</c></tag>
+<tag>
+<marker id="messages"/><c>@messages</c></tag>
<item>
<p>
Defines the messages of the application.
@@ -397,9 +388,8 @@ RTA ::= &lt; Diameter Header: 287, PXY >
</item>
-<marker id="grouped"/>
-
-<tag><c>@grouped</c></tag>
+<tag>
+<marker id="grouped"/><c>@grouped</c></tag>
<item>
<p>
Defines the contents of the AVPs of the application having type
@@ -424,9 +414,8 @@ Specifying a Vendor-Id in the definition of a grouped AVP is
equivalent to specifying it with <c>@avp_vendor_id</c>.</p>
</item>
-<marker id="enum"/>
-
-<tag><c>@enum Name</c></tag>
+<tag>
+<marker id="enum"/><c>@enum Name</c></tag>
<item>
<p>
Defines values of AVP Name having type Enumerated.
@@ -452,9 +441,8 @@ REMOVE_SIP_SERVER 3
</pre>
</item>
-<marker id="end"/>
-
-<tag><c>@end</c></tag>
+<tag>
+<marker id="end"/><c>@end</c></tag>
<item>
<p>
Causes parsing of the dictionary to terminate:
diff --git a/lib/diameter/doc/src/diameter_examples.xml b/lib/diameter/doc/src/diameter_examples.xml
index 853ef96bb3..2e1f2b3c03 100644
--- a/lib/diameter/doc/src/diameter_examples.xml
+++ b/lib/diameter/doc/src/diameter_examples.xml
@@ -42,4 +42,3 @@ Example code can be found in the diameter application's
<c>examples</c> subdirectory.</p>
</chapter>
-
diff --git a/lib/diameter/doc/src/diameter_tcp.xml b/lib/diameter/doc/src/diameter_tcp.xml
index 00ccc39c15..6ca280c52b 100644
--- a/lib/diameter/doc/src/diameter_tcp.xml
+++ b/lib/diameter/doc/src/diameter_tcp.xml
@@ -150,7 +150,7 @@ Options <c>binary</c>,
<c>packet</c> and <c>active</c> cannot be specified.
Also, option <c>port</c> can be specified for a listening transport
to specify the local listening port, the default being the standardized
-3868 if unspecified.
+3868.
Note that the option <c>ip</c> specifies the local address.</p>
<p>
diff --git a/lib/diameter/doc/src/diameter_transport.xml b/lib/diameter/doc/src/diameter_transport.xml
index 736d4cbfbd..294e8a8864 100644
--- a/lib/diameter/doc/src/diameter_transport.xml
+++ b/lib/diameter/doc/src/diameter_transport.xml
@@ -65,9 +65,8 @@ parent).</p>
<taglist>
-<marker id="message"/>
-
-<tag><c>message() = binary() | &codec_packet;</c></tag>
+<tag>
+<marker id="message"/><c>message() = binary() | &codec_packet;</c></tag>
<item>
<p>
A Diameter message as passed over the transport interface.</p>
@@ -160,9 +159,9 @@ It should exit if its transport connection with its peer is lost.</p>
</funcs>
<!-- ===================================================================== -->
-<marker id="MESSAGES"/>
<section>
+<marker id="MESSAGES"/>
<title>MESSAGES</title>
<p>
@@ -234,7 +233,7 @@ established a connection with the peer.
Not sent if the transport process has <c>Type=connect</c>.</p>
</item>
-<tag><c>{diameter, {self(), connected, Remote}}</c></tag>
+<tag><c>{diameter, {self(), connected, Remote}}</c></tag><item/>
<tag><c>{diameter, {self(), connected, Remote, [LocalAddr]}}</c></tag>
<item>
<p>
diff --git a/lib/diameter/doc/src/diameterc.xml b/lib/diameter/doc/src/diameterc.xml
index 5bffe9a771..8f1c660989 100644
--- a/lib/diameter/doc/src/diameterc.xml
+++ b/lib/diameter/doc/src/diameterc.xml
@@ -11,7 +11,7 @@
<comref>
<header>
<copyright>
-<year>2011</year><year>2013</year>
+<year>2011</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -79,14 +79,14 @@ Write generated source to the specified directory.
Defaults to the current working directory.</p>
</item>
-<tag><![CDATA[-E]]></tag>
+<tag><![CDATA[-E]]></tag><item/>
<tag><![CDATA[-H]]></tag>
<item>
<p>
Suppress erl and hrl generation, respectively.</p>
</item>
-<tag><![CDATA[--name <name>]]></tag>
+<tag><![CDATA[--name <name>]]></tag><item/>
<tag><![CDATA[--prefix <prefix>]]></tag>
<item>
<p>
diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml
index b1be7bdcf7..60478606ad 100644
--- a/lib/diameter/doc/src/notes.xml
+++ b/lib/diameter/doc/src/notes.xml
@@ -11,7 +11,7 @@
<header>
<copyright>
<year>2011</year>
-<year>2016</year>
+<year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -43,6 +43,125 @@ first.</p>
<!-- ===================================================================== -->
+<section><title>diameter 2.0</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Let candidate peers be passed to diameter:call/4</p>
+ <p>
+ With call option peer, to allow a request to be sent to a
+ peer that hasn't advertised support for the application
+ in question.</p>
+ <p>
+ RFC 6733 2.4 requires a node to send the application
+ identifiers of all locally supported applications at
+ capabilities exchange, but not all nodes respect this for
+ the common application, and diameter itself will send
+ D[WP][RA] without the common application having been
+ explicitly advertised. Regarding the common application
+ as implicit renders Result-Code 5010
+ (DIAMETER_NO_COMMON_APPLICATION) meaningless however, so
+ allow any request to be sent as long as there is a
+ configured dictionary to support it.</p>
+ <p>
+ Own Id: OTP-14338</p>
+ </item>
+ <item>
+ <p>
+ Improve performance of message encode/decode and related
+ handling.</p>
+ <p>
+ Dictionaries using @custom_types or @codecs will need to
+ adapt the corresponding functions to accept an additional
+ argument that is now passed through encode/decode, which
+ was required to remove various process dictionary-based
+ workarounds that have been used to solve problems in the
+ past.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14343</p>
+ </item>
+ <item>
+ <p>
+ Add transport options to avoid deadlock and allow for
+ load regulation.</p>
+ <p>
+ Both diameter_tcp and diameter_sctp now accept two new
+ configuration options: sender and message_cb. The former
+ causes outgoing sends to take place in a dedicated
+ process, to avoid the possibility of deadlock when both
+ the transport process and its peer block in send. The
+ latter allows a callback to control the reading of
+ messages on the socket, to allow for backpressure towards
+ peers when the rate of incoming traffic is greater than
+ can otherwise be handled.</p>
+ <p>
+ Neither of these options are yet documented, but are
+ unlikely to change unless problems are discovered. The
+ sender option is not the default since it should probably
+ always be used in combination with message_cb, to prevent
+ incoming requests from being read at a higher rate than a
+ peer allows outgoing answers to be sent.</p>
+ <p>
+ Own Id: OTP-14455 Aux Id: ERL-332 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>diameter 1.12.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ An improvement in the handling of peer failover in
+ diameter 1.12.1 adversely affected performance when
+ sending requests. Further, the inefficient use of a
+ public table to route incoming answers has been removed.</p>
+ <p>
+ Own Id: OTP-14206</p>
+ </item>
+ <item>
+ <p>
+ Fixed xml issues in old release notes</p>
+ <p>
+ Own Id: OTP-14269</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>diameter 1.12.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Close diameter_tcp/sctp listening sockets at
+ diameter:stop_service/1.</p>
+ <p>
+ Broken by OTP-13611.</p>
+ <p>
+ Own Id: OTP-13787 Aux Id: OTP-13611 </p>
+ </item>
+ <item>
+ <p>
+ Update build scripts to not make assumtions about where
+ env, cp and perl are located.</p>
+ <p>
+ Own Id: OTP-13800</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>diameter 1.12</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -230,8 +349,8 @@ first.</p>
Fix decode of Grouped AVPs containing errors.</p>
<p>
RFC 6733 says this of Failed-AVP in 7.5:</p>
- <p>
- <taglist><item><p><c> In the case where the offending AVP
+
+ <taglist><tag></tag><item><p><c> In the case where the offending AVP
is embedded within a Grouped AVP, the Failed-AVP MAY
contain the grouped AVP, which in turn contains the
single offending AVP. The same method MAY be employed if
@@ -240,11 +359,11 @@ first.</p>
the grouped AVP hierarchy up to the single offending AVP.
This enables the recipient to detect the location of the
offending AVP when embedded in a
- group.</c></p></item></taglist></p>
+ group.</c></p></item></taglist>
<p>
It says this of DIAMETER_INVALID_AVP_LENGTH in 7.1.5:</p>
- <p>
- <taglist><item><p><c> The request contained an AVP with
+
+ <taglist><tag></tag><item><p><c> The request contained an AVP with
an invalid length. A Diameter message indicating this
error MUST include the offending AVPs within a Failed-AVP
AVP. In cases where the erroneous AVP length value
@@ -259,7 +378,8 @@ first.</p>
the minimum AVP header length, it is sufficient to
include an offending AVP header that is formulated by
padding the incomplete AVP header with zero up to the
- minimum AVP header length.</c></p></item></taglist></p>
+ minimum AVP header length.</c></p></item></taglist>
+
<p>
The AVPs placed in the errors field of a diameter_packet
record are intended to be appropriate for inclusion in a
@@ -924,8 +1044,8 @@ first.</p>
Be lenient with the M-bit in Grouped AVPs.</p>
<p>
RFC 6733 says this, in 4.4:</p>
- <p>
- <taglist><item><p><c>Receivers of a Grouped AVP that does
+
+ <taglist><tag></tag><item><p><c>Receivers of a Grouped AVP that does
not have the 'M' (mandatory) bit set and one or more of
the encapsulated AVPs within the group has the 'M'
(mandatory) bit set MAY simply be ignored if the Grouped
@@ -933,14 +1053,14 @@ first.</p>
encapsulated AVP with its 'M' (mandatory) bit set is
further encapsulated within other sub-groups, i.e., other
Grouped AVPs embedded within the Grouped
- AVP.</c></p></item></taglist></p>
+ AVP.</c></p></item></taglist>
<p>
The first sentence is mangled but take it to mean this:</p>
- <p>
- <taglist><item><p><c>An unrecognized AVP of type Grouped
+
+ <taglist><tag></tag><item><p><c>An unrecognized AVP of type Grouped
that does not set the 'M' bit MAY be ignored even if one
of its encapsulated AVPs sets the 'M'
- bit.</c></p></item></taglist></p>
+ bit.</c></p></item></taglist>
<p>
This is a bit of a non-statement since if the AVP is
unrecognized then its type is unknown. We therefore don't
diff --git a/lib/diameter/examples/code/relay.erl b/lib/diameter/examples/code/relay.erl
index 3846b1d161..806f79915b 100644
--- a/lib/diameter/examples/code/relay.erl
+++ b/lib/diameter/examples/code/relay.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -53,7 +53,7 @@
{'Auth-Application-Id', [16#FFFFFFFF]},
{string_decode, false},
{application, [{alias, relay},
- {dictionary, diameter_relay},
+ {dictionary, diameter_gen_relay},
{module, relay_cb}]}]).
%% start/1
diff --git a/lib/diameter/include/diameter_gen.hrl b/lib/diameter/include/diameter_gen.hrl
index 611ad796a9..fb6370fe54 100644
--- a/lib/diameter/include/diameter_gen.hrl
+++ b/lib/diameter/include/diameter_gen.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,716 +20,36 @@
%%
%% This file contains code that's included by encode/decode modules
-%% generated by diameter_codegen.erl. This code does most of the work, the
-%% generated code being kept simple.
+%% generated by diameter_codegen.erl. This code used to do most of the
+%% work, but now passes it off to module diameter_gen.
%%
--define(THROW(T), throw({?MODULE, T})).
+%% encode_avps/3
-%% Tag common to generated dictionaries.
--define(TAG, diameter_gen).
+encode_avps(Name, Vals, Opts) ->
+ diameter_gen:encode_avps(Name, Vals, Opts#{module => ?MODULE}).
-%% Key to a value in the process dictionary that determines whether or
-%% not an unrecognized AVP setting the M-bit should be regarded as an
-%% error or not. See is_strict/0. This is only used to relax M-bit
-%% interpretation inside Grouped AVPs not setting the M-bit. The
-%% service_opt() strict_mbit can be used to disable the check
-%% globally.
--define(STRICT_KEY, strict).
+%% decode_avps/2
-%% Key that says whether or not we should do a best-effort decode
-%% within Failed-AVP.
--define(FAILED_KEY, failed).
+decode_avps(Name, Recs, Opts) ->
+ diameter_gen:decode_avps(Name, Recs, Opts#{module => ?MODULE}).
--type parent_name() :: atom(). %% parent = Message or AVP
--type parent_record() :: tuple(). %%
--type avp_name() :: atom().
--type avp_record() :: tuple().
--type avp_values() :: [{avp_name(), term()}].
+%% avp/5
--type non_grouped_avp() :: #diameter_avp{}.
--type grouped_avp() :: nonempty_improper_list(#diameter_avp{}, [avp()]).
--type avp() :: non_grouped_avp() | grouped_avp().
+avp(T, Data, Name, Opts, Mod) ->
+ Mod:avp(T, Data, Name, Opts#{module := Mod}).
-%% Use a (hopefully) unique key when manipulating the process
-%% dictionary.
+%% grouped_avp/4
-putr(K,V) ->
- put({?TAG, K}, V).
+grouped_avp(T, Name, Data, Opts) ->
+ diameter_gen:grouped_avp(T, Name, Data, Opts).
-getr(K) ->
- case get({?TAG, K}) of
- undefined ->
- V = erase({?MODULE, K}), %% written in old code
- V == undefined orelse putr(K,V),
- V;
- V ->
- V
- end.
+%% empty_group/2
-eraser(K) ->
- erase({?TAG, K}).
+empty_group(Name, Opts) ->
+ diameter_gen:empty_group(Name, Opts).
-%% ---------------------------------------------------------------------------
-%% # encode_avps/2
-%% ---------------------------------------------------------------------------
+%% empty/2
--spec encode_avps(parent_name(), parent_record() | avp_values())
- -> binary()
- | no_return().
-
-encode_avps(Name, Vals)
- when is_list(Vals) ->
- encode_avps(Name, '#set-'(Vals, newrec(Name)));
-
-encode_avps(Name, Rec) ->
- try
- list_to_binary(encode(Name, Rec))
- catch
- throw: {?MODULE, Reason} ->
- diameter_lib:log({encode, error},
- ?MODULE,
- ?LINE,
- {Reason, Name, Rec}),
- erlang:error(list_to_tuple(Reason ++ [Name]));
- error: Reason ->
- Stack = erlang:get_stacktrace(),
- diameter_lib:log({encode, failure},
- ?MODULE,
- ?LINE,
- {Reason, Name, Rec, Stack}),
- erlang:error({encode_failure, Reason, Name, Stack})
- end.
-
-%% encode/2
-
-encode(Name, Rec) ->
- lists:flatmap(fun(A) -> encode(Name, A, '#get-'(A, Rec)) end,
- '#info-'(element(1, Rec), fields)).
-
-%% encode/3
-
-encode(Name, AvpName, Values) ->
- e(Name, AvpName, avp_arity(Name, AvpName), Values).
-
-%% e/4
-
-e(_, AvpName, 1, undefined) ->
- ?THROW([mandatory_avp_missing, AvpName]);
-
-e(Name, AvpName, 1, Value) ->
- e(Name, AvpName, [Value]);
-
-e(_, _, {0,_}, []) ->
- [];
-
-e(_, AvpName, _, T)
- when not is_list(T) ->
- ?THROW([repeated_avp_as_non_list, AvpName, T]);
-
-e(_, AvpName, {Min, _}, L)
- when length(L) < Min ->
- ?THROW([repeated_avp_insufficient_arity, AvpName, Min, L]);
-
-e(_, AvpName, {_, Max}, L)
- when Max < length(L) ->
- ?THROW([repeated_avp_excessive_arity, AvpName, Max, L]);
-
-e(Name, AvpName, _, Values) ->
- e(Name, AvpName, Values).
-
-%% e/3
-
-e(Name, 'AVP', Values) ->
- [pack_AVP(Name, A) || A <- Values];
-
-e(_, AvpName, Values) ->
- e(AvpName, Values).
-
-%% e/2
-
-e(AvpName, Values) ->
- H = avp_header(AvpName),
- [diameter_codec:pack_avp(H, avp(encode, V, AvpName)) || V <- Values].
-
-%% pack_AVP/2
-
-%% No value: assume AVP data is already encoded. The normal case will
-%% be when this is passed back from #diameter_packet.errors as a
-%% consequence of a failed decode. Any AVP can be encoded this way
-%% however, which side-steps any arity checks for known AVP's and
-%% could potentially encode something unfortunate.
-pack_AVP(_, #diameter_avp{value = undefined} = A) ->
- diameter_codec:pack_avp(A);
-
-%% Missing name for value encode.
-pack_AVP(_, #diameter_avp{name = N, value = V})
- when N == undefined;
- N == 'AVP' ->
- ?THROW([value_with_nameless_avp, N, V]);
-
-%% Or not. Ensure that 'AVP' is the appropriate field. Note that if we
-%% don't know this AVP at all then the encode will fail.
-pack_AVP(Name, #diameter_avp{name = AvpName,
- value = Data}) ->
- 0 == avp_arity(Name, AvpName)
- orelse ?THROW([known_avp_as_AVP, Name, AvpName, Data]),
- e(AvpName, [Data]).
-
-%% ---------------------------------------------------------------------------
-%% # decode_avps/2
-%% ---------------------------------------------------------------------------
-
--spec decode_avps(parent_name(), [#diameter_avp{}])
- -> {parent_record(), [avp()], Failed}
- when Failed :: [{5000..5999, #diameter_avp{}}].
-
-decode_avps(Name, Recs) ->
- {Avps, {Rec, Failed}}
- = lists:foldl(fun(T,A) -> decode(Name, T, A) end,
- {[], {newrec(Name), []}},
- Recs),
- {Rec, Avps, Failed ++ missing(Rec, Name, Failed)}.
-%% Append 5005 errors so that errors are reported in the order
-%% encountered. Failed-AVP should typically contain the first
-%% encountered error accordg to the RFC.
-
-newrec(Name) ->
- '#new-'(name2rec(Name)).
-
-%% 3588:
-%%
-%% DIAMETER_MISSING_AVP 5005
-%% The request did not contain an AVP that is required by the Command
-%% Code definition. If this value is sent in the Result-Code AVP, a
-%% Failed-AVP AVP SHOULD be included in the message. The Failed-AVP
-%% AVP MUST contain an example of the missing AVP complete with the
-%% Vendor-Id if applicable. The value field of the missing AVP
-%% should be of correct minimum length and contain zeros.
-
-missing(Rec, Name, Failed) ->
- Avps = lists:foldl(fun({_, #diameter_avp{code = C, vendor_id = V}}, A) ->
- sets:add_element({C,V}, A)
- end,
- sets:new(),
- Failed),
- [{5005, A} || F <- '#info-'(element(1, Rec), fields),
- not has_arity(avp_arity(Name, F), '#get-'(F, Rec)),
- #diameter_avp{code = C, vendor_id = V}
- = A <- [empty_avp(F)],
- not sets:is_element({C,V}, Avps)].
-
-%% Maximum arities have already been checked in building the record.
-
-has_arity({Min, _}, L) ->
- has_prefix(Min, L);
-has_arity(N, V) ->
- N /= 1 orelse V /= undefined.
-
-%% Compare a non-negative integer and the length of a list without
-%% computing the length.
-has_prefix(0, _) ->
- true;
-has_prefix(_, []) ->
- false;
-has_prefix(N, L) ->
- has_prefix(N-1, tl(L)).
-
-%% empty_avp/1
-
-empty_avp(Name) ->
- {Code, Flags, VId} = avp_header(Name),
- {Name, Type} = avp_name(Code, VId),
- #diameter_avp{name = Name,
- code = Code,
- vendor_id = VId,
- is_mandatory = 0 /= (Flags band 2#01000000),
- need_encryption = 0 /= (Flags band 2#00100000),
- data = empty_value(Name),
- type = Type}.
-
-%% 3588, ch 7:
-%%
-%% The Result-Code AVP describes the error that the Diameter node
-%% encountered in its processing. In case there are multiple errors,
-%% the Diameter node MUST report only the first error it encountered
-%% (detected possibly in some implementation dependent order). The
-%% specific errors that can be described by this AVP are described in
-%% the following section.
-
-%% decode/3
-
-decode(Name, #diameter_avp{code = Code, vendor_id = Vid} = Avp, Acc) ->
- decode(Name, avp_name(Code, Vid), Avp, Acc).
-
-%% decode/4
-
-%% AVP is defined in the dictionary ...
-decode(Name, {AvpName, Type}, Avp, Acc) ->
- d(Name, Avp#diameter_avp{name = AvpName, type = Type}, Acc);
-
-%% ... or not.
-decode(Name, 'AVP', Avp, Acc) ->
- decode_AVP(Name, Avp, Acc).
-
-%% 6733, 4.4:
-%%
-%% Receivers of a Grouped AVP that does not have the 'M' (mandatory)
-%% bit set and one or more of the encapsulated AVPs within the group
-%% has the 'M' (mandatory) bit set MAY simply be ignored if the
-%% Grouped AVP itself is unrecognized. The rule applies even if the
-%% encapsulated AVP with its 'M' (mandatory) bit set is further
-%% encapsulated within other sub-groups, i.e., other Grouped AVPs
-%% embedded within the Grouped AVP.
-%%
-%% The first sentence is slightly mangled, but take it to mean this:
-%%
-%% An unrecognized AVP of type Grouped that does not set the 'M' bit
-%% MAY be ignored even if one of its encapsulated AVPs sets the 'M'
-%% bit.
-%%
-%% The text above is a change from RFC 3588, which instead says this:
-%%
-%% Further, if any of the AVPs encapsulated within a Grouped AVP has
-%% the 'M' (mandatory) bit set, the Grouped AVP itself MUST also
-%% include the 'M' bit set.
-%%
-%% Both of these texts have problems. If the AVP is unknown then its
-%% type is unknown since the type isn't sent over the wire, so the
-%% 6733 text becomes a non-statement: don't know that the AVP not
-%% setting the M-bit is of type Grouped, therefore can't know that its
-%% data consists of encapsulated AVPs, therefore can't but ignore that
-%% one of these might set the M-bit. It should be no worse if we know
-%% the AVP to have type Grouped.
-%%
-%% Similarly, for the 3588 text: if we receive an AVP that doesn't set
-%% the M-bit and don't know that the AVP has type Grouped then we
-%% can't realize that its data contains an AVP that sets the M-bit, so
-%% can't regard the AVP as erroneous on this account. Again, it should
-%% be no worse if the type is known to be Grouped, but in this case
-%% the RFC forces us to regard the AVP as erroneous. This is
-%% inconsistent, and the 3588 text has never been enforced.
-%%
-%% So, if an AVP doesn't set the M-bit then we're free to ignore it,
-%% regardless of the AVP's type. If we know the type to be Grouped
-%% then we must ignore the M-bit on an encapsulated AVP. That means
-%% packing such an encapsulated AVP into an 'AVP' field if need be,
-%% not regarding the lack of a specific field as an error as is
-%% otherwise the case. (The lack of an AVP-specific field being how we
-%% defined the RFC's "unrecognized", which is slightly stronger than
-%% "not defined".)
-
-%% d/3
-
-d(Name, Avp, Acc) ->
- #diameter_avp{name = AvpName,
- data = Data,
- type = Type,
- is_mandatory = M}
- = Avp,
-
- %% Use the process dictionary is to keep track of whether or not
- %% to ignore an M-bit on an encapsulated AVP. Not ideal, but the
- %% alternative requires widespread changes to be able to pass the
- %% value around through the entire decode. The solution here is
- %% simple in comparison, both to implement and to understand.
-
- Strict = relax(Type, M),
-
- %% Use the process dictionary again to keep track of whether we're
- %% decoding within Failed-AVP and should ignore decode errors
- %% altogether.
-
- Failed = relax(Name), %% Not AvpName or else a failed Failed-AVP
- %% decode is packed into 'AVP'.
- Mod = dict(Failed), %% Dictionary to decode in.
-
- %% On decode, a Grouped AVP is represented as a #diameter_avp{}
- %% list with AVP as head and component AVPs as tail. On encode,
- %% data can be a list of component AVPs.
-
- try Mod:avp(decode, Data, AvpName) of
- V ->
- {Avps, T} = Acc,
- {H, A} = ungroup(V, Avp),
- {[H | Avps], pack_avp(Name, A, T)}
- catch
- throw: {?TAG, {grouped, Error, ComponentAvps}} ->
- g(is_failed(), Error, Name, trim(Avp), Acc, ComponentAvps);
- error: Reason ->
- d(is_failed(), Reason, Name, trim(Avp), Acc)
- after
- reset(?STRICT_KEY, Strict),
- reset(?FAILED_KEY, Failed)
- end.
-
-%% trim/1
-%%
-%% Remove any extra bit that was added in diameter_codec to induce a
-%% 5014 error.
-
-trim(#diameter_avp{data = <<0:1, Bin/binary>>} = Avp) ->
- Avp#diameter_avp{data = Bin};
-
-trim(Avps)
- when is_list(Avps) ->
- lists:map(fun trim/1, Avps);
-
-trim(Avp) ->
- Avp.
-
-%% dict/1
-%%
-%% Retrieve the dictionary for the best-effort decode of Failed-AVP,
-%% as put by diameter_codec:decode/2. See that function for the
-%% explanation.
-
-dict(true) ->
- case get({diameter_codec, dictionary}) of
- undefined ->
- ?MODULE;
- Mod ->
- Mod
- end;
-
-dict(_) ->
- ?MODULE.
-
-%% g/5
-
-%% Ignore decode errors within Failed-AVP (best-effort) ...
-g(true, [_Error | Rec], Name, Avp, Acc, _ComponentAvps) ->
- decode_AVP(Name, Avp#diameter_avp{value = Rec}, Acc);
-g(true, _Error, Name, Avp, Acc, _ComponentAvps) ->
- decode_AVP(Name, Avp, Acc);
-
-%% ... or not.
-g(false, [Error | _Rec], _Name, Avp, Acc, ComponentAvps) ->
- g(Error, Avp, Acc, ComponentAvps);
-g(false, Error, _Name, Avp, Acc, ComponentAvps) ->
- g(Error, Avp, Acc, ComponentAvps).
-
-%% g/4
-
-g({RC, ErrorData}, Avp, Acc, ComponentAvps) ->
- {Avps, {Rec, Errors}} = Acc,
- E = Avp#diameter_avp{data = [ErrorData]},
- {[[Avp | trim(ComponentAvps)] | Avps], {Rec, [{RC, E} | Errors]}}.
-
-%% d/5
-
-%% Ignore a decode error within Failed-AVP ...
-d(true, _, Name, Avp, Acc) ->
- decode_AVP(Name, Avp, Acc);
-
-%% ... or not. Failures here won't be visible since they're a "normal"
-%% occurrence if the peer sends a faulty AVP that we need to respond
-%% sensibly to. Log the occurence for traceability, but the peer will
-%% also receive info in the resulting answer message.
-d(false, Reason, Name, Avp, {Avps, Acc}) ->
- Stack = diameter_lib:get_stacktrace(),
- diameter_lib:log(decode_error,
- ?MODULE,
- ?LINE,
- {Name, Avp#diameter_avp.name, Stack}),
- {Rec, Failed} = Acc,
- {[Avp|Avps], {Rec, [rc(Reason, Avp) | Failed]}}.
-
-%% relax/2
-
-%% Set false in the process dictionary as soon as we see a Grouped AVP
-%% that doesn't set the M-bit, so that is_strict() can say whether or
-%% not to ignore the M-bit on an encapsulated AVP.
-relax('Grouped', M) ->
- case getr(?STRICT_KEY) of
- undefined when not M ->
- putr(?STRICT_KEY, M);
- _ ->
- false
- end;
-relax(_, _) ->
- false.
-
-is_strict() ->
- diameter_codec:getopt(strict_mbit)
- andalso false /= getr(?STRICT_KEY).
-
-%% relax/1
-%%
-%% Set true in the process dictionary as soon as we see Failed-AVP.
-%% Matching on 'Failed-AVP' assumes that this is the RFC AVP.
-%% Strictly, this doesn't need to be the case.
-
-relax('Failed-AVP') ->
- putr(?FAILED_KEY, true);
-
-relax(_) ->
- is_failed().
-
-%% is_failed/0
-%%
-%% Is the AVP currently being decoded nested within Failed-AVP? Note
-%% that this is only true when Failed-AVP is the parent. In
-%% particular, it's not true when Failed-AVP itself is being decoded
-%% (unless nested).
-
-is_failed() ->
- true == getr(?FAILED_KEY).
-
-%% is_failed/1
-
-is_failed(Name) ->
- 'Failed-AVP' == Name orelse is_failed().
-
-%% reset/2
-
-reset(Key, undefined) ->
- eraser(Key);
-reset(_, _) ->
- ok.
-
-%% decode_AVP/3
-%%
-%% Don't know this AVP: see if it can be packed in an 'AVP' field
-%% undecoded. Note that the type field is 'undefined' in this case.
-
-decode_AVP(Name, Avp, {Avps, Acc}) ->
- {[trim(Avp) | Avps], pack_AVP(Name, Avp, Acc)}.
-
-%% rc/1
-
-%% diameter_types will raise an error of this form to communicate
-%% DIAMETER_INVALID_AVP_LENGTH (5014). A module specified to a
-%% @custom_types tag in a dictionary file can also raise an error of
-%% this form.
-rc({'DIAMETER', 5014 = RC, _}, #diameter_avp{name = AvpName} = Avp) ->
- {RC, Avp#diameter_avp{data = empty_value(AvpName)}};
-
-%% 3588:
-%%
-%% DIAMETER_INVALID_AVP_VALUE 5004
-%% The request contained an AVP with an invalid value in its data
-%% portion. A Diameter message indicating this error MUST include
-%% the offending AVPs within a Failed-AVP AVP.
-rc(_, Avp) ->
- {5004, Avp}.
-
-%% ungroup/2
-
--spec ungroup(term(), #diameter_avp{})
- -> {avp(), #diameter_avp{}}.
-
-%% The decoded value in the Grouped case is as returned by grouped_avp/3:
-%% a record and a list of component AVP's.
-ungroup(V, #diameter_avp{type = 'Grouped'} = Avp) ->
- {Rec, As} = V,
- A = Avp#diameter_avp{value = Rec},
- {[A|As], A};
-
-%% Otherwise it's just a plain value.
-ungroup(V, #diameter_avp{} = Avp) ->
- A = Avp#diameter_avp{value = V},
- {A, A}.
-
-%% pack_avp/3
-
-pack_avp(Name, #diameter_avp{name = AvpName} = Avp, Acc) ->
- pack_avp(Name, avp_arity(Name, AvpName), Avp, Acc).
-
-%% pack_avp/4
-
-pack_avp(Name, 0, Avp, Acc) ->
- pack_AVP(Name, Avp, Acc);
-
-pack_avp(_, Arity, Avp, Acc) ->
- pack(Arity, Avp#diameter_avp.name, Avp, Acc).
-
-%% pack_AVP/3
-
-%% Length failure was induced because of a header/payload length
-%% mismatch. The AVP Length is reset to match the received data if
-%% this AVP is encoded in an answer message, since the length is
-%% computed.
-%%
-%% Data is a truncated header if command_code = undefined, otherwise
-%% payload bytes. The former is padded to the length of a header if
-%% the AVP reaches an outgoing encode in diameter_codec.
-%%
-%% RFC 6733 says that an AVP returned with 5014 can contain a minimal
-%% payload for the AVP's type, but in this case we don't know the
-%% type.
-
-pack_AVP(_, #diameter_avp{data = <<0:1, Data/binary>>} = Avp, Acc) ->
- {Rec, Failed} = Acc,
- {Rec, [{5014, Avp#diameter_avp{data = Data}} | Failed]};
-
-pack_AVP(Name, #diameter_avp{is_mandatory = M, name = AvpName} = Avp, Acc) ->
- case pack_arity(Name, AvpName, M) of
- 0 ->
- {Rec, Failed} = Acc,
- {Rec, [{if M -> 5001; true -> 5008 end, Avp} | Failed]};
- Arity ->
- pack(Arity, 'AVP', Avp, Acc)
- end.
-
-%% Give Failed-AVP special treatment since (1) it'll contain any
-%% unrecognized mandatory AVP's and (2) the RFC 3588 grammar failed to
-%% allow for Failed-AVP in an answer-message.
-
-pack_arity(Name, AvpName, M) ->
-
- %% Not testing just Name /= 'Failed-AVP' means we're changing the
- %% packing of AVPs nested within Failed-AVP, but the point of
- %% ignoring errors within Failed-AVP is to decode as much as
- %% possible, and failing because a mandatory AVP couldn't be
- %% packed into a dedicated field defeats that point. Note
- %% is_failed/1 since is_failed/0 will return false when packing
- %% 'AVP' within Failed-AVP.
-
- pack_arity(is_failed(Name)
- orelse {Name, AvpName} == {'answer-message', 'Failed-AVP'}
- orelse not M
- orelse not is_strict(),
- Name).
-
-pack_arity(true, Name) ->
- avp_arity(Name, 'AVP');
-
-pack_arity(false, _) ->
- 0.
-
-%% 3588:
-%%
-%% DIAMETER_AVP_UNSUPPORTED 5001
-%% The peer received a message that contained an AVP that is not
-%% recognized or supported and was marked with the Mandatory bit. A
-%% Diameter message with this error MUST contain one or more Failed-
-%% AVP AVP containing the AVPs that caused the failure.
-%%
-%% DIAMETER_AVP_NOT_ALLOWED 5008
-%% A message was received with an AVP that MUST NOT be present. The
-%% Failed-AVP AVP MUST be included and contain a copy of the
-%% offending AVP.
-
-%% pack/4
-
-pack(Arity, FieldName, Avp, {Rec, _} = Acc) ->
- pack('#get-'(FieldName, Rec), Arity, FieldName, Avp, Acc).
-
-%% pack/5
-
-pack(undefined, 1, FieldName, Avp, Acc) ->
- p(FieldName, fun(V) -> V end, Avp, Acc);
-
-%% 3588:
-%%
-%% DIAMETER_AVP_OCCURS_TOO_MANY_TIMES 5009
-%% A message was received that included an AVP that appeared more
-%% often than permitted in the message definition. The Failed-AVP
-%% AVP MUST be included and contain a copy of the first instance of
-%% the offending AVP that exceeded the maximum number of occurrences
-%%
-
-pack(_, 1, _, Avp, {Rec, Failed}) ->
- {Rec, [{5009, Avp} | Failed]};
-pack(L, {_, Max}, FieldName, Avp, Acc) ->
- case '*' /= Max andalso has_prefix(Max, L) of
- true ->
- {Rec, Failed} = Acc,
- {Rec, [{5009, Avp} | Failed]};
- false ->
- p(FieldName, fun(V) -> [V|L] end, Avp, Acc)
- end.
-
-%% p/4
-
-p(F, Fun, Avp, {Rec, Failed}) ->
- {'#set-'({F, Fun(value(F, Avp))}, Rec), Failed}.
-
-value('AVP', Avp) ->
- Avp;
-value(_, Avp) ->
- Avp#diameter_avp.value.
-
-%% ---------------------------------------------------------------------------
-%% # grouped_avp/3
-%% ---------------------------------------------------------------------------
-
--spec grouped_avp(decode, avp_name(), bitstring())
- -> {avp_record(), [avp()]};
- (encode, avp_name(), avp_record() | avp_values())
- -> binary()
- | no_return().
-
-%% Length error induced by diameter_codec:collect_avps/1: the AVP
-%% length in the header was too short (insufficient for the extracted
-%% header) or too long (past the end of the message). An empty payload
-%% is sufficient according to the RFC text for 5014.
-grouped_avp(decode, _Name, <<0:1, _/binary>>) ->
- throw({?TAG, {grouped, {5014, []}, []}});
-
-grouped_avp(decode, Name, Data) ->
- grouped_decode(Name, diameter_codec:collect_avps(Data));
-
-grouped_avp(encode, Name, Data) ->
- encode_avps(Name, Data).
-
-%% grouped_decode/2
-%%
-%% Note that Grouped is the only AVP type that doesn't just return a
-%% decoded value, also returning the list of component diameter_avp
-%% records.
-
-%% Length error in trailing component AVP.
-grouped_decode(_Name, {Error, Acc}) ->
- {5014, Avp} = Error,
- throw({?TAG, {grouped, Error, [Avp | Acc]}});
-
-%% 7.5. Failed-AVP AVP
-
-%% In the case where the offending AVP is embedded within a Grouped AVP,
-%% the Failed-AVP MAY contain the grouped AVP, which in turn contains
-%% the single offending AVP. The same method MAY be employed if the
-%% grouped AVP itself is embedded in yet another grouped AVP and so on.
-%% In this case, the Failed-AVP MAY contain the grouped AVP hierarchy up
-%% to the single offending AVP. This enables the recipient to detect
-%% the location of the offending AVP when embedded in a group.
-
-%% An error in decoding a component AVP throws the first fauly
-%% component, which the catch in d/3 wraps in the Grouped AVP in
-%% question. A partially decoded record is only used when ignoring
-%% errors in Failed-AVP.
-grouped_decode(Name, ComponentAvps) ->
- {Rec, Avps, Es} = decode_avps(Name, ComponentAvps),
- [] == Es orelse throw({?TAG, {grouped, [{_,_} = hd(Es) | Rec], Avps}}),
- {Rec, Avps}.
-
-%% ---------------------------------------------------------------------------
-%% # empty_group/1
-%% ---------------------------------------------------------------------------
-
-empty_group(Name) ->
- list_to_binary(empty_body(Name)).
-
-empty_body(Name) ->
- [z(F, avp_arity(Name, F)) || F <- '#info-'(name2rec(Name), fields)].
-
-z(Name, 1) ->
- z(Name);
-z(_, {0,_}) ->
- [];
-z(Name, {Min, _}) ->
- lists:duplicate(Min, z(Name)).
-
-z('AVP') ->
- <<0:64/integer>>; %% minimal header
-z(Name) ->
- Bin = diameter_codec:pack_avp(avp_header(Name), empty_value(Name)),
- << <<0>> || <<_>> <= Bin >>.
-
-%% ---------------------------------------------------------------------------
-%% # empty/1
-%% ---------------------------------------------------------------------------
-
-empty(AvpName) ->
- avp(encode, zero, AvpName).
+empty(Name, Opts) ->
+ diameter_gen:empty(Name, Opts).
diff --git a/lib/diameter/src/Makefile b/lib/diameter/src/Makefile
index 7f61620fc1..6bf748a727 100644
--- a/lib/diameter/src/Makefile
+++ b/lib/diameter/src/Makefile
@@ -123,7 +123,7 @@ ERL_COMPILE_FLAGS += \
# erl/hrl from dictionary file.
gen/diameter_gen_%.erl gen/diameter_gen_%.hrl: dict/%.dia
$(dia_verbose) \
- ../bin/diameterc -o gen -i $(EBIN) $<
+ escript ../bin/diameterc -o gen -i $(EBIN) $<
opt: $(TARGET_FILES)
diff --git a/lib/diameter/src/base/diameter.erl b/lib/diameter/src/base/diameter.erl
index e8f2f63f86..bd92e16fba 100644
--- a/lib/diameter/src/base/diameter.erl
+++ b/lib/diameter/src/base/diameter.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -377,6 +377,7 @@ call(SvcName, App, Message) ->
| {capabilities, [capability()]}
| {capabilities_cb, evaluable()}
| {capx_timeout, 'Unsigned32'()}
+ | {capx_strictness, boolean()}
| {disconnect_cb, evaluable()}
| {dpr_timeout, 'Unsigned32'()}
| {dpa_timeout, 'Unsigned32'()}
@@ -405,4 +406,5 @@ call(SvcName, App, Message) ->
:: {extra, list()}
| {filter, peer_filter()}
| {timeout, 'Unsigned32'()}
+ | {peer, peer_ref()}
| detach.
diff --git a/lib/diameter/src/base/diameter_callback.erl b/lib/diameter/src/base/diameter_callback.erl
index f479cb6612..f9cdc66c70 100644
--- a/lib/diameter/src/base/diameter_callback.erl
+++ b/lib/diameter/src/base/diameter_callback.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@
%% in a callback applied to the atom-valued callback name and argument
%% list. For all callbacks not to this module, the 'extra' field is a
%% list of additional arguments, following arguments supplied by
-%% diameter but preceeding those of the diameter:evaluable() being
+%% diameter but preceding those of the diameter:evaluable() being
%% applied.
%%
%% For example, the following config to diameter:start_service/2, in
diff --git a/lib/diameter/src/base/diameter_capx.erl b/lib/diameter/src/base/diameter_capx.erl
index 07a678c617..62b05644b2 100644
--- a/lib/diameter/src/base/diameter_capx.erl
+++ b/lib/diameter/src/base/diameter_capx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -94,6 +94,9 @@ recv_CER(CER, Svc, Dict) ->
recv_CEA(CEA, Svc, Dict) ->
try_it([fun rCEA/3, CEA, Svc, Dict]).
+-spec make_caps(#diameter_caps{}, [{atom(), term()}])
+ -> tried(#diameter_caps{}).
+
make_caps(Caps, Opts) ->
try_it([fun mk_caps/2, Caps, Opts]).
@@ -110,31 +113,20 @@ try_it([Fun | Args]) ->
%% mk_caps/2
mk_caps(Caps0, Opts) ->
- {Caps, _} = lists:foldl(fun set_cap/2,
- {Caps0, #diameter_caps{_ = false}},
- Opts),
- Caps.
-
--define(SC(K,F),
- set_cap({K, Val}, {Caps, #diameter_caps{F = false} = C}) ->
- {Caps#diameter_caps{F = cap(K, copy(Val))},
- C#diameter_caps{F = true}}).
-
-?SC('Origin-Host', origin_host);
-?SC('Origin-Realm', origin_realm);
-?SC('Host-IP-Address', host_ip_address);
-?SC('Vendor-Id', vendor_id);
-?SC('Product-Name', product_name);
-?SC('Origin-State-Id', origin_state_id);
-?SC('Supported-Vendor-Id', supported_vendor_id);
-?SC('Auth-Application-Id', auth_application_id);
-?SC('Inband-Security-Id', inband_security_id);
-?SC('Acct-Application-Id', acct_application_id);
-?SC('Vendor-Specific-Application-Id', vendor_specific_application_id);
-?SC('Firmware-Revision', firmware_revision);
-
-set_cap({Key, _}, _) ->
- ?THROW({duplicate, Key}).
+ Fields = diameter_gen_base_rfc3588:'#info-'(diameter_base_CER, fields),
+ Defs = lists:zip(Fields, tl(tuple_to_list(Caps0))),
+ Unset = maps:from_list([{F, true} || F <- lists:droplast(Fields)]), %% no 'AVP'
+ {Caps, _} = lists:foldl(fun set_cap/2, {Defs, Unset}, Opts),
+ #diameter_caps{} = list_to_tuple([diameter_caps | [V || {_,V} <- Caps]]).
+
+set_cap({F,V}, {Caps, Unset}) ->
+ case Unset of
+ #{F := true} ->
+ {lists:keyreplace(F, 1, Caps, {F, cap(F, copy(V))}),
+ maps:remove(F, Unset)};
+ _ ->
+ ?THROW({duplicate, F})
+ end.
cap(K, V)
when K == 'Origin-Host';
@@ -349,7 +341,7 @@ cs(LS, RS) ->
cea_from_cer(CER, Dict) ->
RecName = Dict:msg2rec('CEA'),
[_ | Values] = Dict:'#get-'(CER),
- Dict:'#set-'(Values, Dict:'#new-'(RecName)).
+ Dict:'#new-'([RecName | Values]).
%% rCEA/3
@@ -424,7 +416,48 @@ bcaps(N, Caps) ->
%% common_applications/3
%%
%% Identify the (local) applications to be supported on the connection
-%% in question.
+%% in question. The RFC says this:
+%%
+%% 2.4 Application Identifiers
+%%
+%% Relay and redirect agents MUST advertise the Relay Application ID,
+%% while all other Diameter nodes MUST advertise locally supported
+%% applications.
+%%
+%% Taken literally, every Diameter node should then advertise support
+%% for the Diameter common messages application, with id 0, since no
+%% node can perform capabilities exchange without it. Expecting this,
+%% or regarding the support as implicit, renders the Result-Code 5010
+%% (DIAMETER_NO_COMMON_APPLICATION) meaningless however, since every
+%% node would regard the common application as being in common with
+%% the peer. In practice, nodes may or may not advertise support for
+%% Diameter common messages.
+%%
+%% That only explicitly advertised applications should be considered
+%% when computing the intersection with the peer is supported here:
+%%
+%% 5.3. Capabilities Exchange
+%%
+%% The receiver of the Capabilities-Exchange-Request (CER) MUST
+%% determine common applications by computing the intersection of its
+%% own set of supported Application Ids against all of the
+%% Application-Id AVPs (Auth-Application-Id, Acct-Application-Id, and
+%% Vendor-Specific-Application-Id) present in the CER.
+%%
+%% The same section also has the following about capabilities exchange
+%% messages.
+%%
+%% The receiver only issues commands to its peers that have advertised
+%% support for the Diameter application that defines the command.
+%%
+%% This statement is also difficult to interpret literally since it
+%% would disallow D[WP]R and more when Diameter common messages isn't
+%% advertised. In practice, diameter lets requests be sent as long as
+%% there's a dictionary configured to support it, peer selection by
+%% advertised application being possible to preempt by passing
+%% candidate peers directly to diameter:call/4. The peer can always
+%% answer 3001 (DIAMETER_COMMAND_UNSUPPORTED) or 3007
+%% (DIAMETER_APPLICATION_UNSUPPORTED) if this is objectionable.
common_applications(LCaps, RCaps, #diameter_service{applications = Apps}) ->
LA = app_union(LCaps),
diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl
index 1ea5357924..82fa796e69 100644
--- a/lib/diameter/src/base/diameter_codec.erl
+++ b/lib/diameter/src/base/diameter_codec.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,11 +20,8 @@
-module(diameter_codec).
--export([encode/2,
- decode/2,
- decode/3,
- setopts/1,
- getopt/1,
+-export([encode/2, encode/3,
+ decode/2, decode/3, decode/4,
collect_avps/1,
decode_header/1,
sequence_numbers/1,
@@ -33,13 +30,17 @@
msg_id/1]).
%% Towards generated encoders (from diameter_gen.hrl).
--export([pack_avp/1,
+-export([pack_data/2,
pack_avp/2]).
-include_lib("diameter/include/diameter.hrl").
-include("diameter_internal.hrl").
--define(MASK(N,I), ((I) band (1 bsl (N)))).
+-define(PAD(Len), ((4 - (Len rem 4)) rem 4)).
+-define(BIT(B,I), (if B -> I; true -> 0 end)).
+-define(BIT(B), ?BIT(B,1)).
+-define(FLAGS(R,P,E,T), ?BIT(R):1, ?BIT(P):1, ?BIT(E):1, ?BIT(T):1, 0:4).
+-define(FLAG(B,D), (if is_boolean(B) -> B; true -> 0 /= (D) end)).
-type u32() :: 0..16#FFFFFFFF.
-type u24() :: 0..16#FFFFFF.
@@ -62,62 +63,29 @@
%% +-+-+-+-+-+-+-+-+-+-+-+-+-
%%% ---------------------------------------------------------------------------
-%%% # setopts/1
-%%% # getopt/1
+%%% # encode/2
%%% ---------------------------------------------------------------------------
-%% These functions are a compromise in the same vein as the use of the
-%% process dictionary in diameter_gen.hrl in generated codec modules.
-%% Instead of rewriting the entire dictionary generation to pass
-%% encode/decode options around, the calling process sets them by
-%% calling setopts/1. At current, the only option is whether or not to
-%% decode binaries as strings, which is used by diameter_types.
-
-setopts(Opts)
- when is_list(Opts) ->
- lists:foreach(fun setopt/1, Opts).
-
-%% The default string_decode true is for backwards compatibility.
-setopt({K, false = B})
- when K == string_decode;
- K == strict_mbit ->
- setopt(K, B);
-
-%% Regard anything but the generated RFC 3588 dictionary as modern.
-%% This affects the interpretation of defaults during the decode
-%% of values of type DiameterURI, this having changed from RFC 3588.
-%% (So much for backwards compatibility.)
-setopt({common_dictionary, diameter_gen_base_rfc3588}) ->
- setopt(rfc, 3588);
-
-setopt(_) ->
- ok.
-
-setopt(Key, Value) ->
- put({diameter, Key}, Value).
-
-getopt(Key) ->
- case get({diameter, Key}) of
- undefined when Key == string_decode;
- Key == strict_mbit ->
- true;
- undefined when Key == rfc ->
- 6733;
- V ->
- V
- end.
+%% The representative encode documented in diameter_codec(3). As of
+%% the options that affect encode (eg. ordered_encode), it's no longer
+%% *the* encode.
+
+encode(Mod, Msg) ->
+ encode(Mod, #{ordered_encode => true}, Msg).
%%% ---------------------------------------------------------------------------
-%%% # encode/2
+%%% # encode/3
%%% ---------------------------------------------------------------------------
--spec encode(module(), Msg :: term())
+-spec encode(module(),
+ map(),
+ Msg :: term())
-> #diameter_packet{}
| no_return().
-encode(Mod, #diameter_packet{} = Pkt) ->
+encode(Mod, Opts, #diameter_packet{} = Pkt) ->
try
- e(Mod, Pkt)
+ enc(Mod, Opts, Pkt)
catch
exit: {Reason, Stack, #diameter_header{} = H} = T ->
%% Exit with a header in the reason to let the caller
@@ -130,91 +98,97 @@ encode(Mod, #diameter_packet{} = Pkt) ->
exit({?MODULE, encode, T})
end;
-encode(Mod, Msg) ->
+encode(Mod, Opts, Msg) ->
Seq = diameter_session:sequence(),
Hdr = #diameter_header{version = ?DIAMETER_VERSION,
end_to_end_id = Seq,
hop_by_hop_id = Seq},
- encode(Mod, #diameter_packet{header = Hdr,
- msg = Msg}).
+ encode(Mod, Opts, #diameter_packet{header = Hdr,
+ msg = Msg}).
+
+%% enc/3
-e(_, #diameter_packet{msg = [#diameter_header{} = Hdr | As]} = Pkt) ->
- try encode_avps(reorder(As)) of
+enc(_, Opts, #diameter_packet{msg = [#diameter_header{} = Hdr | As]}
+ = Pkt) ->
+ try encode_avps(reorder(As), Opts) of
Avps ->
- Length = size(Avps) + 20,
+ Bin = list_to_binary(Avps),
+ Len = 20 + size(Bin),
#diameter_header{version = Vsn,
+ is_request = R,
+ is_proxiable = P,
+ is_error = E,
+ is_retransmitted = T,
cmd_code = Code,
application_id = Aid,
hop_by_hop_id = Hid,
end_to_end_id = Eid}
= Hdr,
- Flags = make_flags(0, Hdr),
-
Pkt#diameter_packet{header = Hdr,
- bin = <<Vsn:8, Length:24,
- Flags:8, Code:24,
+ bin = <<Vsn:8, Len:24,
+ ?FLAGS(R,P,E,T), Code:24,
Aid:32,
Hid:32,
Eid:32,
- Avps/binary>>}
+ Bin/binary>>}
catch
error: Reason ->
exit({Reason, diameter_lib:get_stacktrace(), Hdr})
end;
-e(Mod, #diameter_packet{header = Hdr0, msg = Msg} = Pkt) ->
+enc(Mod, Opts, #diameter_packet{header = Hdr0, msg = Msg} = Pkt) ->
+ MsgName = rec2msg(Mod, Msg),
+ {Code, Flags, Aid} = msg_header(Mod, MsgName, Hdr0),
+
#diameter_header{version = Vsn,
+ is_request = R,
+ is_proxiable = P,
+ is_error = E,
+ is_retransmitted = T,
hop_by_hop_id = Hid,
end_to_end_id = Eid}
= Hdr0,
- MsgName = rec2msg(Mod, Msg),
- {Code, Flags0, Aid} = msg_header(Mod, MsgName, Hdr0),
- Flags = make_flags(Flags0, Hdr0),
- Hdr = Hdr0#diameter_header{cmd_code = Code,
- application_id = Aid,
- is_request = 0 /= ?MASK(7, Flags),
- is_proxiable = 0 /= ?MASK(6, Flags),
- is_error = 0 /= ?MASK(5, Flags),
- is_retransmitted = 0 /= ?MASK(4, Flags)},
+ RB = ?FLAG(R, Flags band 2#10000000),
+ PB = ?FLAG(P, Flags band 2#01000000),
+ EB = ?FLAG(E, Flags band 2#00100000),
+ TB = ?FLAG(T, Flags band 2#00010000),
+
Values = values(Msg),
- try encode_avps(Mod, MsgName, Values) of
+ try encode_avps(Mod, MsgName, Values, Opts) of
Avps ->
- Length = size(Avps) + 20,
- Pkt#diameter_packet{header = Hdr#diameter_header{length = Length},
- bin = <<Vsn:8, Length:24,
- Flags:8, Code:24,
+ Bin = list_to_binary(Avps),
+ Len = 20 + size(Bin),
+
+ Hdr = Hdr0#diameter_header{length = Len,
+ cmd_code = Code,
+ application_id = Aid,
+ is_request = RB,
+ is_proxiable = PB,
+ is_error = EB,
+ is_retransmitted = TB},
+
+ Pkt#diameter_packet{header = Hdr,
+ bin = <<Vsn:8, Len:24,
+ ?FLAGS(RB, PB, EB, TB), Code:24,
Aid:32,
Hid:32,
Eid:32,
- Avps/binary>>}
+ Bin/binary>>}
catch
error: Reason ->
+ Hdr = Hdr0#diameter_header{cmd_code = Code,
+ application_id = Aid,
+ is_request = RB,
+ is_proxiable = PB,
+ is_error = EB,
+ is_retransmitted = TB},
exit({Reason, diameter_lib:get_stacktrace(), Hdr})
end.
-%% make_flags/2
-
-make_flags(Flags0, #diameter_header{is_request = R,
- is_proxiable = P,
- is_error = E,
- is_retransmitted = T}) ->
- {Flags, 3} = lists:foldl(fun(B,{F,N}) -> {mf(B,F,N), N-1} end,
- {Flags0, 7},
- [R,P,E,T]),
- Flags.
-
-mf(undefined, F, _) ->
- F;
-mf(B, F, N) -> %% reset the affected bit
- (F bxor (F band (1 bsl N))) bor bit(B, N).
-
-bit(true, N) -> 1 bsl N;
-bit(false, _) -> 0.
-
%% values/1
values([H|T])
@@ -223,7 +197,7 @@ values([H|T])
values(Avps) ->
Avps.
-%% encode_avps/3
+%% encode_avps/4
%% Specifying values as a #diameter_avp list bypasses arity and other
%% checks: the values are expected to be already encoded and the AVP's
@@ -231,12 +205,12 @@ values(Avps) ->
%% these have to be able to resend whatever comes.
%% Message as a list of #diameter_avp{} ...
-encode_avps(_, _, [#diameter_avp{} | _] = Avps) ->
- encode_avps(reorder(Avps));
+encode_avps(_, _, [#diameter_avp{} | _] = Avps, Opts) ->
+ encode_avps(reorder(Avps), Opts);
%% ... or as a tuple list or record.
-encode_avps(Mod, MsgName, Values) ->
- Mod:encode_avps(MsgName, Values).
+encode_avps(Mod, MsgName, Values, Opts) ->
+ Mod:encode_avps(MsgName, Values, Opts).
%% reorder/1
%%
@@ -277,10 +251,10 @@ reorder([H | T], Acc) ->
reorder([], _) ->
false.
-%% encode_avps/1
+%% encode_avps/2
-encode_avps(Avps) ->
- list_to_binary(lists:map(fun pack_avp/1, Avps)).
+encode_avps(Avps, Opts) ->
+ [pack_avp(A, Opts) || A <- Avps].
%% msg_header/3
@@ -308,38 +282,50 @@ rec2msg(Mod, Rec) ->
%%% # decode/2
%%% ---------------------------------------------------------------------------
+%% The representative default decode documented in diameter_codec(3).
+%% As of the options that affect decode (eg. string_decode), it's no
+%% longer *the* decode.
+
+decode(Mod, Pkt) ->
+ Opts = #{string_decode => true,
+ strict_mbit => true,
+ rfc => 6733},
+ decode(Mod, Opts, Pkt).
+
+%%% ---------------------------------------------------------------------------
+%%% # decode/3
+%%% ---------------------------------------------------------------------------
+
%% Unsuccessfully decoded AVPs will be placed in #diameter_packet.errors.
--spec decode(module() | {module(), module()}, #diameter_packet{} | binary())
+-spec decode(module() | {module(), module()},
+ map(),
+ #diameter_packet{} | binary())
-> #diameter_packet{}.
%% An Answer setting the E-bit. The application dictionary is needed
-%% for the best-effort decode of Failed-AVP, and the best way to make
-%% this available to the AVP decode in diameter_gen.hrl, without
-%% having to rewrite the entire codec generation, is to place it in
-%% the process dictionary. It's the code in diameter_gen.hrl (that's
-%% included by every generated codec module) that looks for the entry.
-%% Not ideal, but it solves the problem relatively simply.
-decode({Mod, Mod}, Pkt) ->
- decode(Mod, Pkt);
-decode({Mod, AppMod}, Pkt) ->
- Key = {?MODULE, dictionary},
- put(Key, AppMod),
- try
- decode(Mod, Pkt)
- after
- erase(Key)
- end;
+%% for the best-effort decode of Failed-AVP.
+decode({Mod, AppMod}, Opts, Pkt) ->
+ decode(Mod, AppMod, Opts, Pkt);
%% Or not: a request, or an answer not setting the E-bit.
-decode(Mod, Pkt) ->
- decode(Mod:id(), Mod, Pkt).
+decode(Mod, Opts, Pkt) ->
+ decode(Mod, Mod, Opts, Pkt).
+
+%% decode/4
+
+decode(Id, Mod, Opts, Pkt)
+ when is_integer(Id) ->
+ decode(Id, Mod, Mod, Opts, Pkt);
-%% decode/3
+decode(Mod, AppMod, Opts, Pkt) ->
+ decode(Mod:id(), Mod, AppMod, Opts, Pkt).
+
+%% decode/5
%% Relay application: just extract the avp's without any decoding of
%% their data since we don't know the application in question.
-decode(?APP_ID_RELAY, _, #diameter_packet{} = Pkt) ->
+decode(?APP_ID_RELAY, _, _, _, #diameter_packet{} = Pkt) ->
case collect_avps(Pkt) of
{E, As} ->
Pkt#diameter_packet{avps = As,
@@ -349,7 +335,7 @@ decode(?APP_ID_RELAY, _, #diameter_packet{} = Pkt) ->
end;
%% Otherwise decode using the dictionary.
-decode(_, Mod, #diameter_packet{header = Hdr} = Pkt) ->
+decode(_, Mod, AppMod, Opts, #diameter_packet{header = Hdr} = Pkt) ->
#diameter_header{cmd_code = CmdCode,
is_request = IsRequest,
is_error = IsError}
@@ -361,29 +347,33 @@ decode(_, Mod, #diameter_packet{header = Hdr} = Pkt) ->
Mod:msg_name(CmdCode, IsRequest)
end,
- decode_avps(MsgName, Mod, Pkt, collect_avps(Pkt));
+ decode_avps(MsgName, Mod, AppMod, Opts, Pkt, collect_avps(Pkt));
-decode(Id, Mod, Bin)
+decode(Id, Mod, AppMod, Opts, Bin)
when is_binary(Bin) ->
- decode(Id, Mod, #diameter_packet{header = decode_header(Bin), bin = Bin}).
+ decode(Id, Mod, AppMod, Opts, #diameter_packet{header = decode_header(Bin),
+ bin = Bin}).
-%% decode_avps/4
+%% decode_avps/6
-decode_avps(MsgName, Mod, Pkt, {E, Avps}) ->
+decode_avps(MsgName, Mod, AppMod, Opts, Pkt, {E, Avps}) ->
?LOG(invalid_avp_length, Pkt#diameter_packet.header),
#diameter_packet{errors = Failed}
= P
- = decode_avps(MsgName, Mod, Pkt, Avps),
+ = decode_avps(MsgName, Mod, AppMod, Opts, Pkt, Avps),
P#diameter_packet{errors = [E | Failed]};
-decode_avps('', _, Pkt, Avps) -> %% unknown message ...
+decode_avps('', _, _, _, Pkt, Avps) -> %% unknown message ...
?LOG(unknown_message, Pkt#diameter_packet.header),
Pkt#diameter_packet{avps = lists:reverse(Avps),
errors = [3001]}; %% DIAMETER_COMMAND_UNSUPPORTED
%% msg = undefined identifies this case.
-decode_avps(MsgName, Mod, Pkt, Avps) -> %% ... or not
- {Rec, As, Errors} = Mod:decode_avps(MsgName, Avps),
+decode_avps(MsgName, Mod, AppMod, Opts, Pkt, Avps) -> %% ... or not
+ {Rec, As, Errors} = Mod:decode_avps(MsgName,
+ Avps,
+ Opts#{dictionary => AppMod,
+ failed_avp => false}),
?LOGC([] /= Errors, decode_errors, Pkt#diameter_packet.header),
Pkt#diameter_packet{msg = Rec,
errors = Errors,
@@ -399,14 +389,12 @@ decode_avps(MsgName, Mod, Pkt, Avps) -> %% ... or not
decode_header(<<Version:8,
MsgLength:24,
- CmdFlags:1/binary,
+ R:1, P:1, E:1, T:1, _:4,
CmdCode:24,
ApplicationId:32,
HopByHopId:32,
EndToEndId:32,
_/binary>>) ->
- <<R:1, P:1, E:1, T:1, _:4>>
- = CmdFlags,
%% 3588 (ch 3) says that reserved bits MUST be set to 0 and ignored
%% by the receiver.
@@ -518,7 +506,7 @@ msg_id(#diameter_packet{header = #diameter_header{} = Hdr}) ->
msg_id(#diameter_header{application_id = A,
cmd_code = C,
is_request = R}) ->
- {A, C, if R -> 1; true -> 0 end};
+ {A, C, ?BIT(R)};
msg_id(<<_:32, Rbit:1, _:7, CmdCode:24, ApplId:32, _/binary>>) ->
{ApplId, CmdCode, Rbit}.
@@ -537,24 +525,14 @@ msg_id(<<_:32, Rbit:1, _:7, CmdCode:24, ApplId:32, _/binary>>) ->
when Avp :: #diameter_avp{},
Error :: {5014, #diameter_avp{}}.
-collect_avps(#diameter_packet{bin = Bin}) ->
- <<_:20/binary, Avps/binary>> = Bin,
- collect_avps(Avps);
+collect_avps(#diameter_packet{bin = <<_:20/binary, Avps/binary>>}) ->
+ collect_avps(Avps, 0, []);
collect_avps(Bin)
when is_binary(Bin) ->
collect_avps(Bin, 0, []).
-collect_avps(<<>>, _, Acc) ->
- Acc;
-collect_avps(Bin, N, Acc) ->
- try split_avp(Bin) of
- {Rest, AVP} ->
- collect_avps(Rest, N+1, [AVP#diameter_avp{index = N} | Acc])
- catch
- ?FAILURE(Error) ->
- {Error, Acc}
- end.
+%% collect_avps/3
%% 0 1 2 3
%% 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -568,32 +546,65 @@ collect_avps(Bin, N, Acc) ->
%% | Data ...
%% +-+-+-+-+-+-+-+-+
-%% split_avp/1
+collect_avps(<<Code:32, V:1, M:1, P:1, _:5, Len:24, I:V/unit:32, Rest/binary>>,
+ N,
+ Acc) ->
+ collect_avps(Code,
+ if 1 == V -> I; 0 == V -> undefined end,
+ 1 == M,
+ 1 == P,
+ Len - 8 - V*4, %% Might be negative, which ensures
+ ?PAD(Len), %% failure of the Data match below.
+ Rest,
+ N,
+ Acc);
-split_avp(Bin) ->
- {Code, V, M, P, Len, HdrLen} = split_head(Bin),
-
- <<_:HdrLen/binary, Rest/binary>> = Bin,
- {Data, B} = split_data(Rest, Len - HdrLen),
-
- {B, #diameter_avp{code = Code,
- vendor_id = V,
- is_mandatory = 1 == M,
- need_encryption = 1 == P,
- data = Data}}.
-
-%% split_head/1
-
-split_head(<<Code:32, 1:1, M:1, P:1, _:5, Len:24, V:32, _/binary>>) ->
- {Code, V, M, P, Len, 12};
+collect_avps(<<>>, _, Acc) ->
+ Acc;
-split_head(<<Code:32, 0:1, M:1, P:1, _:5, Len:24, _/binary>>) ->
- {Code, undefined, M, P, Len, 8};
+%% Header is truncated. pack_avp/1 will pad this at encode if sent in
+%% a Failed-AVP.
+collect_avps(Bin, _, Acc) ->
+ {{5014, #diameter_avp{data = Bin}}, Acc}.
+
+%% collect_avps/9
+
+%% Duplicate the diameter_avp creation in each branch below to avoid
+%% modifying the record, which profiling has shown to be a relatively
+%% costly part of building the list.
+
+collect_avps(Code, VendorId, M, P, Len, Pad, Rest, N, Acc) ->
+ case Rest of
+ <<Data:Len/binary, _:Pad/binary, T/binary>> ->
+ Avp = #diameter_avp{code = Code,
+ vendor_id = VendorId,
+ is_mandatory = M,
+ need_encryption = P,
+ data = Data,
+ index = N},
+ collect_avps(T, N+1, [Avp | Acc]);
+ _ ->
+ %% Length in header points past the end of the message, or
+ %% doesn't span the header. As stated in the 6733 text
+ %% above, it's sufficient to return a zero-filled minimal
+ %% payload if this is a request. Do this (in cases that we
+ %% know the type) by inducing a decode failure and letting
+ %% the dictionary's decode (in diameter_gen) deal with it.
+ %%
+ %% Note that the extra bit can only occur in the trailing
+ %% AVP of a message or Grouped AVP, since a faulty AVP
+ %% Length is otherwise indistinguishable from a correct
+ %% one here, as we don't know the types of the AVPs being
+ %% extracted.
+ Avp = #diameter_avp{code = Code,
+ vendor_id = VendorId,
+ is_mandatory = M,
+ need_encryption = P,
+ data = {5014, Rest},
+ index = N},
+ [Avp | Acc]
+ end.
-%% Header is truncated.
-split_head(Bin) ->
- ?THROW({5014, #diameter_avp{data = Bin}}).
-%% Note that pack_avp/1 will pad this at encode if sent in a Failed-AVP.
%% 3588:
%%
@@ -626,35 +637,8 @@ split_head(Bin) ->
%% the minimum value mean we might not know the identity of the AVP and
%% (2) the last sentence covers this case.
-%% split_data/3
-
-split_data(Bin, Len) ->
- Pad = (4 - (Len rem 4)) rem 4,
-
- %% Len might be negative here, but that ensures the failure of the
- %% binary match.
-
- case Bin of
- <<Data:Len/binary, _:Pad/binary, Rest/binary>> ->
- {Data, Rest};
- _ ->
- %% Header length points past the end of the message, or
- %% doesn't span the header. As stated in the 6733 text
- %% above, it's sufficient to return a zero-filled minimal
- %% payload if this is a request. Do this (in cases that we
- %% know the type) by inducing a decode failure and letting
- %% the dictionary's decode (in diameter_gen) deal with it.
- %%
- %% Note that the extra bit can only occur in the trailing
- %% AVP of a message or Grouped AVP, since a faulty AVP
- %% Length is otherwise indistinguishable from a correct
- %% one here, since we don't know the types of the AVPs
- %% being extracted.
- {<<0:1, Bin/binary>>, <<>>}
- end.
-
%%% ---------------------------------------------------------------------------
-%%% # pack_avp/1
+%%% # pack_avp/2
%%% ---------------------------------------------------------------------------
%% The normal case here is data as an #diameter_avp{} list or an
@@ -664,104 +648,96 @@ split_data(Bin, Len) ->
%% Decoded Grouped AVP with decoded components: ignore components
%% since they're already encoded in the Grouped AVP.
-pack_avp([#diameter_avp{} = Grouped | _Components]) ->
- pack_avp(Grouped);
+pack_avp([#diameter_avp{} = Grouped | _Components], Opts) ->
+ pack_avp(Grouped, Opts);
%% Grouped AVP whose components need packing. It's intentional that
%% this isn't equivalent to [Grouped | Components]: here the
%% components need to be encoded before wrapping with the Grouped AVP,
%% and the list is flat, nesting being accomplished in the data
%% fields.
-pack_avp(#diameter_avp{data = [#diameter_avp{} | _] = Components} = Grouped) ->
- pack_avp(Grouped#diameter_avp{data = encode_avps(Components)});
+pack_avp(#diameter_avp{data = [#diameter_avp{} | _] = Components}
+ = Grouped,
+ Opts) ->
+ pack_data(Grouped, encode_avps(Components, Opts));
%% Data as a type/value tuple ...
-pack_avp(#diameter_avp{data = {Type, Value}} = A)
+pack_avp(#diameter_avp{data = {Type, Value}} = A, Opts)
when is_atom(Type) ->
- pack_avp(A#diameter_avp{data = diameter_types:Type(encode, Value)});
+ pack_data(A, diameter_types:Type(encode, Value, Opts));
%% ... with a header in various forms ...
-pack_avp(#diameter_avp{data = {{_,_,_} = T, {Type, Value}}}) ->
- pack_avp(T, iolist_to_binary(diameter_types:Type(encode, Value)));
+pack_avp(#diameter_avp{data = {T, {Type, Value}}}, Opts) ->
+ pack_data(T, diameter_types:Type(encode, Value, Opts));
-pack_avp(#diameter_avp{data = {{_,_,_} = T, Bin}})
- when is_binary(Bin) ->
- pack_avp(T, Bin);
+pack_avp(#diameter_avp{data = {T, Data}}, _) ->
+ pack_data(T, Data);
-pack_avp(#diameter_avp{data = {Dict, Name, Value}} = A) ->
- {Code, _Flags, Vid} = Hdr = Dict:avp_header(Name),
- {Name, Type} = Dict:avp_name(Code, Vid),
- pack_avp(A#diameter_avp{data = {Hdr, {Type, Value}}});
+pack_avp(#diameter_avp{data = {Dict, Name, Data}}, Opts) ->
+ pack_data(Dict:avp_header(Name), Dict:avp(encode, Data, Name, Opts));
%% ... with a truncated header ...
-pack_avp(#diameter_avp{code = undefined, data = B})
+pack_avp(#diameter_avp{code = undefined, data = B}, _)
when is_binary(B) ->
%% Reset the AVP Length of an AVP Header resulting from a 5014
%% error. The RFC doesn't explicitly say to do this but the
%% receiver can't correctly extract this and following AVP's
%% without a correct length. On the downside, the header doesn't
- %% reveal if the received header has been padded.
- Pad = 8*header_length(B) - bit_size(B),
- Len = size(<<H:5/binary, _:24, T/binary>> = <<B/binary, 0:Pad>>),
- <<H/binary, Len:24, T/binary>>;
-
-%% ... when ignoring errors in Failed-AVP ...
-%% ... during a relay encode ...
-pack_avp(#diameter_avp{data = <<0:1, B/binary>>} = A) ->
- pack_avp(A#diameter_avp{data = B});
-
-%% ... or as an iolist.
-pack_avp(#diameter_avp{code = Code,
- vendor_id = V,
- is_mandatory = M,
- need_encryption = P,
- data = Data}) ->
- Flags = lists:foldl(fun flag_avp/2, 0, [{V /= undefined, 2#10000000},
- {M, 2#01000000},
- {P, 2#00100000}]),
- pack_avp({Code, Flags, V}, iolist_to_binary(Data)).
-
-header_length(<<_:32, 1:1, _/bitstring>>) ->
+ %% reveal if the received header has been padded. Discard bytes
+ %% from the length header for this reason, to avoid creating a sub
+ %% binary for no useful reason.
+ Len = header_length(B),
+ Sz = min(5, size(B)),
+ <<B:Sz/binary, 0:(5-Sz)/unit:8, Len:24, 0:(Len-8)/unit:8>>;
+
+%% Ignoring errors in Failed-AVP or during a relay encode.
+pack_avp(#diameter_avp{data = {5014, Data}} = A, _) ->
+ pack_data(A, Data);
+
+pack_avp(#diameter_avp{data = Data} = A, _) ->
+ pack_data(A, Data).
+
+header_length(<<_:32, 1:1, _/bits>>) ->
12;
header_length(_) ->
8.
-flag_avp({true, B}, F) ->
- F bor B;
-flag_avp({false, _}, F) ->
- F.
-
%%% ---------------------------------------------------------------------------
-%%% # pack_avp/2
+%%% # pack_data/2
%%% ---------------------------------------------------------------------------
-pack_avp({Code, Flags, VendorId}, Bin)
- when is_binary(Bin) ->
- Sz = size(Bin),
- pack_avp(Code, Flags, VendorId, Sz, pad(Sz rem 4, Bin)).
-
-pad(0, Bin) ->
- Bin;
-pad(N, Bin) ->
- P = 8*(4-N),
- <<Bin/binary, 0:P>>.
-%% Note that padding is not included in the length field as mandated by
-%% the RFC.
-
-%% pack_avp/5
+pack_data(#diameter_avp{code = Code,
+ vendor_id = V,
+ is_mandatory = M,
+ need_encryption = P},
+ Data) ->
+ Flags = ?BIT(V /= undefined, 2#10000000)
+ bor ?BIT(M, 2#01000000)
+ bor ?BIT(P, 2#00100000),
+ pack(Code, Flags, V, Data);
+
+pack_data({Code, Flags, VendorId}, Data) ->
+ pack(Code, Flags, VendorId, Data).
+
+%% pack/4
+
+pack(Code, Flags, VendorId, Data) ->
+ Sz = iolist_size(Data),
+ pack(Code, Flags, Sz, VendorId, Data, ?PAD(Sz)).
+%% Padding is not included in the length field, as mandated by the RFC.
+
+%% pack/6
%%
%% Prepend the vendor id as required.
-pack_avp(Code, Flags, Vid, Sz, Bin)
+pack(Code, Flags, Sz, _Vid, Data, Pad)
when 0 == Flags band 2#10000000 ->
- undefined = Vid, %% sanity check
- pack_avp(Code, Flags, Sz, Bin);
+ pack(Code, Flags, Sz, 0, 0, Data, Pad);
-pack_avp(Code, Flags, Vid, Sz, Bin) ->
- pack_avp(Code, Flags, Sz+4, <<Vid:32, Bin/binary>>).
+pack(Code, Flags, Sz, Vid, Data, Pad) ->
+ pack(Code, Flags, Sz+4, Vid, 1, Data, Pad).
-%% pack_avp/4
+%% pack/7
-pack_avp(Code, Flags, Sz, Bin) ->
- Length = Sz + 8,
- <<Code:32, Flags:8, Length:24, Bin/binary>>.
+pack(Code, Flags, Sz, VId, V, Data, Pad) ->
+ [<<Code:32, Flags:8, (8+Sz):24, VId:V/unit:32>>, Data, <<0:Pad/unit:8>>].
diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl
index fdbbd412a1..34018ae6d3 100644
--- a/lib/diameter/src/base/diameter_config.erl
+++ b/lib/diameter/src/base/diameter_config.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -277,7 +277,7 @@ start_link() ->
start_link(T) ->
proc_lib:start_link(?MODULE, init, [T], infinity, []).
-
+
state() ->
call(state).
@@ -535,12 +535,12 @@ stop(SvcName) ->
%% restrict applications so that that there's one while the service
%% has many.
-add(SvcName, Type, Opts) ->
+add(SvcName, Type, Opts0) ->
%% Ensure acceptable transport options. This won't catch all
%% possible errors (faulty callbacks for example) but it catches
%% many. diameter_service:merge_service/2 depends on usable
%% capabilities for example.
- ok = transport_opts(Opts),
+ Opts = transport_opts(Opts0),
Ref = make_ref(),
true = diameter_reg:add_new(?TRANSPORT_KEY(Ref)),
@@ -560,7 +560,17 @@ add(SvcName, Type, Opts) ->
end.
transport_opts(Opts) ->
- lists:foreach(fun(T) -> opt(T) orelse ?THROW({invalid, T}) end, Opts).
+ lists:map(fun topt/1, Opts).
+
+topt(T) ->
+ case opt(T) of
+ {value, X} ->
+ X;
+ true ->
+ T;
+ false ->
+ ?THROW({invalid, T})
+ end.
opt({transport_module, M}) ->
is_atom(M);
@@ -580,6 +590,9 @@ opt({K, Tmo})
K == dpa_timeout ->
?IS_UINT32(Tmo);
+opt({capx_strictness, B}) ->
+ is_boolean(B);
+
opt({length_errors, T}) ->
lists:member(T, [exit, handle, discard]);
@@ -597,8 +610,15 @@ opt({watchdog_timer, Tmo}) ->
opt({watchdog_config, L}) ->
is_list(L) andalso lists:all(fun wdopt/1, L);
-opt({spawn_opt, Opts}) ->
- is_list(Opts);
+opt({spawn_opt, {M,F,A}})
+ when is_atom(M), is_atom(F), is_list(A) ->
+ true;
+opt({spawn_opt = K, Opts}) ->
+ if is_list(Opts) ->
+ {value, {K, spawn_opts(Opts)}};
+ true ->
+ false
+ end;
opt({pool_size, N}) ->
is_integer(N) andalso 0 < N;
@@ -673,7 +693,7 @@ stop_transport(SvcName, Refs) ->
make_config(SvcName, Opts) ->
AppOpts = [T || {application, _} = T <- Opts],
- Apps = init_apps(AppOpts),
+ Apps = [init_app(T) || T <- AppOpts],
[] == Apps andalso ?THROW(no_apps),
@@ -722,9 +742,13 @@ opt(incoming_maxlen, N)
when 0 =< N, N < 1 bsl 24 ->
N;
+opt(spawn_opt, {M,F,A} = T)
+ when is_atom(M), is_atom(F), is_list(A) ->
+ T;
+
opt(spawn_opt, L)
when is_list(L) ->
- L;
+ spawn_opts(L);
opt(K, false = B)
when K == share_peers;
@@ -786,6 +810,9 @@ opt(sequence = K, F) ->
opt(K, _) ->
?THROW({value, K}).
+spawn_opts(L) ->
+ [T || T <- L, T /= link, T /= monitor].
+
sequence({H,N} = T)
when 0 =< N, N =< 32, 0 =< H, 0 == H bsr (32-N) ->
T;
@@ -819,10 +846,7 @@ encode_CER(Opts) ->
?THROW(Reason)
end.
-init_apps(Opts) ->
- lists:foldl(fun app_acc/2, [], lists:reverse(Opts)).
-
-app_acc({application, Opts} = T, Acc) ->
+init_app({application, Opts} = T) ->
is_list(Opts) orelse ?THROW(T),
[Dict, Mod] = get_opt([dictionary, module], Opts),
@@ -831,15 +855,14 @@ app_acc({application, Opts} = T, Acc) ->
M = get_opt(call_mutates_state, Opts, false, [true]),
A = get_opt(answer_errors, Opts, discard, [callback, report]),
P = get_opt(request_errors, Opts, answer_3xxx, [answer, callback]),
- [#diameter_app{alias = Alias,
- dictionary = Dict,
- id = cb(Dict, id),
- module = init_mod(Mod),
- init_state = ModS,
- mutable = M,
- options = [{answer_errors, A},
- {request_errors, P}]}
- | Acc].
+ #diameter_app{alias = Alias,
+ dictionary = Dict,
+ id = cb(Dict, id),
+ module = init_mod(Mod),
+ init_state = ModS,
+ mutable = M,
+ options = [{answer_errors, A},
+ {request_errors, P}]}.
init_mod(#diameter_callback{} = R) ->
init_mod([diameter_callback, R]);
@@ -865,7 +888,7 @@ init_cb(List) ->
V <- [proplists:get_value(F, List, D)]],
#diameter_callback{} = list_to_tuple([diameter_callback | Values]).
-%% Retreive and validate.
+%% Retrieve and validate.
get_opt(Key, List, Def, Other) ->
init_opt(Key, get_opt(Key, List, Def), [Def|Other]).
diff --git a/lib/diameter/src/base/diameter_dict.erl b/lib/diameter/src/base/diameter_dict.erl
deleted file mode 100644
index 7db294a1b1..0000000000
--- a/lib/diameter/src/base/diameter_dict.erl
+++ /dev/null
@@ -1,154 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% This module provide OTP's dict interface built on top of ets.
-%%
-%% Note that while the interface is the same as dict the semantics
-%% aren't quite. A Dict here is just a table identifier (although
-%% this fact can't be used if you want dict/ets-based implementations
-%% to be interchangeable) so changes made to the Dict modify the
-%% underlying table. For merge/3, the first argument table is modified.
-%%
-%% The underlying ets table implementing a dict is deleted when the
-%% process from which new() was invoked exits and the dict is only
-%% writable from this process.
-%%
-%% The reason for this is to be able to swap dict/ets-based
-%% implementations: the former is easier to debug, the latter is
-%% faster for larger tables. It's also just a nice interface even
-%% when there's no need for swapability.
-%%
-
--module(diameter_dict).
-
--export([append/3,
- append_list/3,
- erase/2,
- fetch/2,
- fetch_keys/1,
- filter/2,
- find/2,
- fold/3,
- from_list/1,
- is_key/2,
- map/2,
- merge/3,
- new/0,
- store/3,
- to_list/1,
- update/3,
- update/4,
- update_counter/3]).
-
-%%% ----------------------------------------------------------
-%%% EXPORTED INTERNAL FUNCTIONS
-%%% ----------------------------------------------------------
-
-append(Key, Value, Dict) ->
- append_list(Key, [Value], Dict).
-
-append_list(Key, ValueList, Dict)
- when is_list(ValueList) ->
- update(Key, fun(V) -> V ++ ValueList end, ValueList, Dict).
-
-erase(Key, Dict) ->
- ets:delete(Dict, Key),
- Dict.
-
-fetch(Key, Dict) ->
- {ok, V} = find(Key, Dict),
- V.
-
-fetch_keys(Dict) ->
- ets:foldl(fun({K,_}, Acc) -> [K | Acc] end, [], Dict).
-
-filter(Pred, Dict) ->
- lists:foreach(fun({K,V}) -> filter(Pred(K,V), K, Dict) end, to_list(Dict)),
- Dict.
-
-find(Key, Dict) ->
- case ets:lookup(Dict, Key) of
- [{Key, V}] ->
- {ok, V};
- [] ->
- error
- end.
-
-fold(Fun, Acc0, Dict) ->
- ets:foldl(fun({K,V}, Acc) -> Fun(K, V, Acc) end, Acc0, Dict).
-
-from_list(List) ->
- lists:foldl(fun store/2, new(), List).
-
-is_key(Key, Dict) ->
- ets:member(Dict, Key).
-
-map(Fun, Dict) ->
- lists:foreach(fun({K,V}) -> store(K, Fun(K,V), Dict) end, to_list(Dict)),
- Dict.
-
-merge(Fun, Dict1, Dict2) ->
- fold(fun(K2,V2,_) ->
- update(K2, fun(V1) -> Fun(K2, V1, V2) end, V2, Dict1)
- end,
- Dict1,
- Dict2).
-
-new() ->
- ets:new(?MODULE, [set]).
-
-store(Key, Value, Dict) ->
- store({Key, Value}, Dict).
-
-to_list(Dict) ->
- ets:tab2list(Dict).
-
-update(Key, Fun, Dict) ->
- store(Key, Fun(fetch(Key, Dict)), Dict).
-
-update(Key, Fun, Initial, Dict) ->
- store(Key, map(Key, Fun, Dict, Initial), Dict).
-
-update_counter(Key, Increment, Dict)
- when is_integer(Increment) ->
- update(Key, fun(V) -> V + Increment end, Increment, Dict).
-
-%%% ---------------------------------------------------------
-%%% INTERNAL FUNCTIONS
-%%% ---------------------------------------------------------
-
-store({_,_} = T, Dict) ->
- ets:insert(Dict, T),
- Dict.
-
-filter(true, _, _) ->
- ok;
-filter(false, K, Dict) ->
- erase(K, Dict).
-
-map(Key, Fun, Dict, Error) ->
- case find(Key, Dict) of
- {ok, V} ->
- Fun(V);
- error ->
- Error
- end.
-
diff --git a/lib/diameter/src/base/diameter_gen.erl b/lib/diameter/src/base/diameter_gen.erl
new file mode 100644
index 0000000000..e832832876
--- /dev/null
+++ b/lib/diameter/src/base/diameter_gen.erl
@@ -0,0 +1,709 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%% This file contains code that encode/decode modules generated by
+%% diameter_codegen.erl calls to implement the functionality. This
+%% code does most of the work, the generated code being kept simple.
+%%
+
+-module(diameter_gen).
+
+-export([encode_avps/3,
+ decode_avps/3,
+ grouped_avp/4,
+ empty_group/2,
+ empty/2]).
+
+-include_lib("diameter/include/diameter.hrl").
+
+-define(THROW(T), throw({?MODULE, T})).
+
+-type parent_name() :: atom(). %% parent = Message or AVP
+-type parent_record() :: tuple(). %%
+-type avp_name() :: atom().
+-type avp_record() :: tuple().
+-type avp_values() :: [{avp_name(), term()}].
+
+-type non_grouped_avp() :: #diameter_avp{}.
+-type grouped_avp() :: nonempty_improper_list(#diameter_avp{}, [avp()]).
+-type avp() :: non_grouped_avp() | grouped_avp().
+
+%% ---------------------------------------------------------------------------
+%% # encode_avps/3
+%% ---------------------------------------------------------------------------
+
+-spec encode_avps(parent_name(), parent_record() | avp_values(), map())
+ -> iolist()
+ | no_return().
+
+encode_avps(Name, Vals, #{module := Mod} = Opts) ->
+ try
+ encode(Name, Vals, Opts, Mod)
+ catch
+ throw: {?MODULE, Reason} ->
+ diameter_lib:log({encode, error},
+ ?MODULE,
+ ?LINE,
+ {Reason, Name, Vals, Mod}),
+ erlang:error(list_to_tuple(Reason ++ [Name]));
+ error: Reason ->
+ Stack = erlang:get_stacktrace(),
+ diameter_lib:log({encode, failure},
+ ?MODULE,
+ ?LINE,
+ {Reason, Name, Vals, Mod, Stack}),
+ erlang:error({encode_failure, Reason, Name, Stack})
+ end.
+
+%% encode/4
+
+encode(Name, Vals, #{ordered_encode := false} = Opts, Mod)
+ when is_list(Vals) ->
+ lists:map(fun({F,V}) -> encode(Name, F, V, Opts, Mod) end, Vals);
+
+encode(Name, Vals, Opts, Mod)
+ when is_list(Vals) ->
+ encode(Name, Mod:'#set-'(Vals, newrec(Mod, Name)), Opts, Mod);
+
+encode(Name, Rec, Opts, Mod) ->
+ [encode(Name, F, V, Opts, Mod) || {F,V} <- Mod:'#get-'(Rec)].
+
+%% encode/5
+
+encode(Name, AvpName, Values, Opts, Mod) ->
+ enc(Name, AvpName, Mod:avp_arity(Name, AvpName), Values, Opts, Mod).
+
+%% enc/6
+
+enc(_, AvpName, 1, undefined, _, _) ->
+ ?THROW([mandatory_avp_missing, AvpName]);
+
+enc(Name, AvpName, 1, Value, Opts, Mod) ->
+ enc(Name, AvpName, [Value], Opts, Mod);
+
+enc(_, _, {0,_}, [], _, _) ->
+ [];
+
+enc(_, AvpName, _, T, _, _)
+ when not is_list(T) ->
+ ?THROW([repeated_avp_as_non_list, AvpName, T]);
+
+enc(_, AvpName, {Min, _}, L, _, _)
+ when length(L) < Min ->
+ ?THROW([repeated_avp_insufficient_arity, AvpName, Min, L]);
+
+enc(_, AvpName, {_, Max}, L, _, _)
+ when Max < length(L) ->
+ ?THROW([repeated_avp_excessive_arity, AvpName, Max, L]);
+
+enc(Name, AvpName, _, Values, Opts, Mod) ->
+ enc(Name, AvpName, Values, Opts, Mod).
+
+%% enc/5
+
+enc(Name, 'AVP', Values, Opts, Mod) ->
+ [enc_AVP(Name, A, Opts, Mod) || A <- Values];
+
+enc(_, AvpName, Values, Opts, Mod) ->
+ enc(AvpName, Values, Opts, Mod).
+
+%% enc/4
+
+enc(AvpName, Values, Opts, Mod) ->
+ H = Mod:avp_header(AvpName),
+ [diameter_codec:pack_data(H, Mod:avp(encode, V, AvpName, Opts))
+ || V <- Values].
+
+%% enc_AVP/4
+
+%% No value: assume AVP data is already encoded. The normal case will
+%% be when this is passed back from #diameter_packet.errors as a
+%% consequence of a failed decode. Any AVP can be encoded this way
+%% however, which side-steps any arity checks for known AVP's and
+%% could potentially encode something unfortunate.
+enc_AVP(_, #diameter_avp{value = undefined} = A, Opts, _) ->
+ diameter_codec:pack_avp(A, Opts);
+
+%% Missing name for value encode.
+enc_AVP(_, #diameter_avp{name = N, value = V}, _, _)
+ when N == undefined;
+ N == 'AVP' ->
+ ?THROW([value_with_nameless_avp, N, V]);
+
+%% Or not. Ensure that 'AVP' is the appropriate field. Note that if we
+%% don't know this AVP at all then the encode will fail.
+enc_AVP(Name, #diameter_avp{name = AvpName, value = Data}, Opts, Mod) ->
+ 0 == Mod:avp_arity(Name, AvpName)
+ orelse ?THROW([known_avp_as_AVP, Name, AvpName, Data]),
+ enc(AvpName, [Data], Opts, Mod);
+
+%% The backdoor ...
+enc_AVP(_, {AvpName, Value}, Opts, Mod) ->
+ enc(AvpName, [Value], Opts, Mod);
+
+%% ... and the side door.
+enc_AVP(_Name, {_Dict, _AvpName, _Data} = T, Opts, _) ->
+ diameter_codec:pack_avp(#diameter_avp{data = T}, Opts).
+
+%% ---------------------------------------------------------------------------
+%% # decode_avps/3
+%% ---------------------------------------------------------------------------
+
+-spec decode_avps(parent_name(), [#diameter_avp{}], map())
+ -> {parent_record(), [avp()], Failed}
+ when Failed :: [{5000..5999, #diameter_avp{}}].
+
+decode_avps(Name, Recs, #{module := Mod} = Opts) ->
+ {Avps, {Rec, Failed}}
+ = mapfoldl(fun(T,A) -> decode(Name, Opts, Mod, T, A) end,
+ {newrec(Mod, Name), []},
+ Recs),
+ {Rec, Avps, Failed ++ missing(Rec, Name, Failed, Opts, Mod)}.
+%% Append 5005 errors so that errors are reported in the order
+%% encountered. Failed-AVP should typically contain the first
+%% encountered error accordg to the RFC.
+
+%% mapfoldl/3
+%%
+%% Like lists:mapfoldl/3, but don't reverse the list.
+
+mapfoldl(F, Acc, List) ->
+ mapfoldl(F, Acc, List, []).
+
+mapfoldl(F, Acc0, [T|Rest], List) ->
+ {B, Acc} = F(T, Acc0),
+ mapfoldl(F, Acc, Rest, [B|List]);
+mapfoldl(_, Acc, [], List) ->
+ {List, Acc}.
+
+%% 3588:
+%%
+%% DIAMETER_MISSING_AVP 5005
+%% The request did not contain an AVP that is required by the Command
+%% Code definition. If this value is sent in the Result-Code AVP, a
+%% Failed-AVP AVP SHOULD be included in the message. The Failed-AVP
+%% AVP MUST contain an example of the missing AVP complete with the
+%% Vendor-Id if applicable. The value field of the missing AVP
+%% should be of correct minimum length and contain zeros.
+
+missing(Rec, Name, Failed, Opts, Mod) ->
+ Avps = lists:foldl(fun({_, #diameter_avp{code = C, vendor_id = V}}, A) ->
+ maps:put({C,V}, true, A)
+ end,
+ maps:new(),
+ Failed),
+ missing(Mod:avp_arity(Name), tl(tuple_to_list(Rec)), Avps, Opts, Mod, []).
+
+missing([{Name, Arity} | As], [Value | Vs], Avps, Opts, Mod, Acc) ->
+ missing(As,
+ Vs,
+ Avps,
+ Opts,
+ Mod,
+ case
+ [H || missing_arity(Arity, Value),
+ {C,_,V} = H <- [Mod:avp_header(Name)],
+ not maps:is_key({C,V}, Avps)]
+ of
+ [H] ->
+ [{5005, empty_avp(Name, H, Opts, Mod)} | Acc];
+ [] ->
+ Acc
+ end);
+
+missing([], [], _, _, _, Acc) ->
+ Acc.
+
+%% Maximum arities have already been checked in building the record.
+
+missing_arity(1, V) ->
+ V == undefined;
+missing_arity({0, _}, _) ->
+ false;
+missing_arity({1, _}, L) ->
+ [] == L;
+missing_arity({Min, _}, L) ->
+ not has_prefix(Min, L).
+
+%% Compare a non-negative integer and the length of a list without
+%% computing the length.
+has_prefix(0, _) ->
+ true;
+has_prefix(_, []) ->
+ false;
+has_prefix(N, [_|L]) ->
+ has_prefix(N-1, L).
+
+%% empty_avp/4
+
+empty_avp(Name, {Code, Flags, VId}, Opts, Mod) ->
+ {Name, Type} = Mod:avp_name(Code, VId),
+ #diameter_avp{name = Name,
+ code = Code,
+ vendor_id = VId,
+ is_mandatory = 0 /= (Flags band 2#01000000),
+ need_encryption = 0 /= (Flags band 2#00100000),
+ data = Mod:empty_value(Name, Opts),
+ type = Type}.
+
+%% 3588, ch 7:
+%%
+%% The Result-Code AVP describes the error that the Diameter node
+%% encountered in its processing. In case there are multiple errors,
+%% the Diameter node MUST report only the first error it encountered
+%% (detected possibly in some implementation dependent order). The
+%% specific errors that can be described by this AVP are described in
+%% the following section.
+
+%% decode/5
+
+decode(Name,
+ Opts,
+ Mod,
+ #diameter_avp{code = Code, vendor_id = Vid}
+ = Avp,
+ Acc) ->
+ decode(Name, Opts, Mod, Mod:avp_name(Code, Vid), Avp, Acc).
+
+%% decode/6
+
+%% AVP not in dictionary.
+decode(Name, Opts, Mod, 'AVP', Avp, Acc) ->
+ decode_AVP(Name, Avp, Opts, Mod, Acc);
+
+%% 6733, 4.4:
+%%
+%% Receivers of a Grouped AVP that does not have the 'M' (mandatory)
+%% bit set and one or more of the encapsulated AVPs within the group
+%% has the 'M' (mandatory) bit set MAY simply be ignored if the
+%% Grouped AVP itself is unrecognized. The rule applies even if the
+%% encapsulated AVP with its 'M' (mandatory) bit set is further
+%% encapsulated within other sub-groups, i.e., other Grouped AVPs
+%% embedded within the Grouped AVP.
+%%
+%% The first sentence is slightly mangled, but take it to mean this:
+%%
+%% An unrecognized AVP of type Grouped that does not set the 'M' bit
+%% MAY be ignored even if one of its encapsulated AVPs sets the 'M'
+%% bit.
+%%
+%% The text above is a change from RFC 3588, which instead says this:
+%%
+%% Further, if any of the AVPs encapsulated within a Grouped AVP has
+%% the 'M' (mandatory) bit set, the Grouped AVP itself MUST also
+%% include the 'M' bit set.
+%%
+%% Both of these texts have problems. If the AVP is unknown then its
+%% type is unknown since the type isn't sent over the wire, so the
+%% 6733 text becomes a non-statement: don't know that the AVP not
+%% setting the M-bit is of type Grouped, therefore can't know that its
+%% data consists of encapsulated AVPs, therefore can't but ignore that
+%% one of these might set the M-bit. It should be no worse if we know
+%% the AVP to have type Grouped.
+%%
+%% Similarly, for the 3588 text: if we receive an AVP that doesn't set
+%% the M-bit and don't know that the AVP has type Grouped then we
+%% can't realize that its data contains an AVP that sets the M-bit, so
+%% can't regard the AVP as erroneous on this account. Again, it should
+%% be no worse if the type is known to be Grouped, but in this case
+%% the RFC forces us to regard the AVP as erroneous. This is
+%% inconsistent, and the 3588 text has never been enforced.
+%%
+%% So, if an AVP doesn't set the M-bit then we're free to ignore it,
+%% regardless of the AVP's type. If we know the type to be Grouped
+%% then we must ignore the M-bit on an encapsulated AVP. That means
+%% packing such an encapsulated AVP into an 'AVP' field if need be,
+%% not regarding the lack of a specific field as an error as is
+%% otherwise the case. (The lack of an AVP-specific field being how we
+%% defined the RFC's "unrecognized", which is slightly stronger than
+%% "not defined".)
+
+decode(Name, Opts0, Mod, {AvpName, Type}, Avp, Acc) ->
+ #diameter_avp{data = Data, is_mandatory = M}
+ = Avp,
+
+ %% Whether or not to ignore an M-bit on an encapsulated AVP, or on
+ %% all AVPs with the service_opt() strict_mbit.
+ Opts1 = set_strict(Type, M, Opts0),
+
+ %% Whether or not we're decoding within Failed-AVP and should
+ %% ignore decode errors.
+ #{dictionary := AppMod, failed_avp := Failed}
+ = Opts
+ = set_failed(Name, Opts1), %% Not AvpName or else a failed Failed-AVP
+ %% decode is packed into 'AVP'.
+
+ %% Reset the dictionary for best-effort decode of Failed-AVP.
+ DecMod = if Failed ->
+ AppMod;
+ true ->
+ Mod
+ end,
+
+ %% On decode, a Grouped AVP is represented as a #diameter_avp{}
+ %% list with AVP as head and component AVPs as tail. On encode,
+ %% data can be a list of component AVPs.
+
+ try avp_decode(Data, AvpName, Opts, DecMod, Mod) of
+ {Rec, As} when Type == 'Grouped' ->
+ A = Avp#diameter_avp{name = AvpName,
+ value = Rec,
+ type = Type},
+ {[A|As], pack_avp(Name, A, Opts, Mod, Acc)};
+
+ V when Type /= 'Grouped' ->
+ A = Avp#diameter_avp{name = AvpName,
+ value = V,
+ type = Type},
+ {A, pack_avp(Name, A, Opts, Mod, Acc)}
+ catch
+ throw: {?MODULE, {grouped, Error, ComponentAvps}} ->
+ decode_error(Name,
+ Error,
+ ComponentAvps,
+ Opts,
+ Mod,
+ Avp#diameter_avp{name = AvpName,
+ data = trim(Avp#diameter_avp.data),
+ type = Type},
+ Acc);
+
+ error: Reason ->
+ decode_error(Name,
+ Reason,
+ Opts,
+ Mod,
+ Avp#diameter_avp{name = AvpName,
+ data = trim(Avp#diameter_avp.data),
+ type = Type},
+ Acc)
+ end.
+
+%% avp_decode/5
+
+avp_decode(Data, AvpName, Opts, Mod, Mod) ->
+ Mod:avp(decode, Data, AvpName, Opts);
+
+avp_decode(Data, AvpName, Opts, Mod, _) ->
+ Mod:avp(decode, Data, AvpName, Opts, Mod).
+
+%% trim/1
+%%
+%% Remove any extra bit that was added in diameter_codec to induce a
+%% 5014 error.
+
+trim(#diameter_avp{data = Data} = Avp) ->
+ Avp#diameter_avp{data = trim(Data)};
+
+trim({5014, Bin}) ->
+ Bin;
+
+trim(Avps)
+ when is_list(Avps) ->
+ lists:map(fun trim/1, Avps);
+
+trim(Avp) ->
+ Avp.
+
+%% decode_error/7
+
+decode_error(Name, [_ | Rec], _, #{failed_avp := true} = Opts, Mod, Avp, Acc) ->
+ decode_AVP(Name, Avp#diameter_avp{value = Rec}, Opts, Mod, Acc);
+
+decode_error(Name, _, _, #{failed_avp := true} = Opts, Mod, Avp, Acc) ->
+ decode_AVP(Name, Avp, Opts, Mod, Acc);
+
+decode_error(_, [Error | _], ComponentAvps, _, _, Avp, Acc) ->
+ decode_error(Error, Avp, Acc, ComponentAvps);
+
+decode_error(_, Error, ComponentAvps, _, _, Avp, Acc) ->
+ decode_error(Error, Avp, Acc, ComponentAvps).
+
+%% decode_error/5
+
+decode_error(Name, _Reason, #{failed_avp := true} = Opts, Mod, Avp, Acc) ->
+ decode_AVP(Name, Avp, Opts, Mod, Acc);
+
+decode_error(Name, Reason, Opts, Mod, Avp, {Rec, Failed}) ->
+ Stack = diameter_lib:get_stacktrace(),
+ diameter_lib:log(decode_error,
+ ?MODULE,
+ ?LINE,
+ {Reason, Name, Avp#diameter_avp.name, Mod, Stack}),
+ {Avp, {Rec, [rc(Reason, Avp, Opts, Mod) | Failed]}}.
+
+%% decode_error/4
+
+decode_error({RC, ErrorData}, Avp, {Rec, Failed}, ComponentAvps) ->
+ E = Avp#diameter_avp{data = [ErrorData]},
+ {[Avp | trim(ComponentAvps)], {Rec, [{RC, E} | Failed]}}.
+
+%% set_strict/3
+
+%% Set false as soon as we see a Grouped AVP that doesn't set the
+%% M-bit, to ignore the M-bit on an encapsulated AVP.
+set_strict('Grouped', false = M, #{strict_mbit := true} = Opts) ->
+ Opts#{strict_mbit := M};
+set_strict(_, _, Opts) ->
+ Opts.
+
+%% set_failed/2
+%%
+%% Set true as soon as we see Failed-AVP. Matching on 'Failed-AVP'
+%% assumes that this is the RFC AVP. Strictly, this doesn't need to be
+%% the case.
+
+set_failed('Failed-AVP', #{failed_avp := false} = Opts) ->
+ Opts#{failed_avp := true};
+set_failed(_, Opts) ->
+ Opts.
+
+%% decode_AVP/5
+%%
+%% Don't know this AVP: see if it can be packed in an 'AVP' field
+%% undecoded. Note that the type field is 'undefined' in this case.
+
+decode_AVP(Name, Avp, Opts, Mod, Acc) ->
+ {trim(Avp), pack_AVP(Name, Avp, Opts, Mod, Acc)}.
+
+%% rc/2
+
+%% diameter_types will raise an error of this form to communicate
+%% DIAMETER_INVALID_AVP_LENGTH (5014). A module specified to a
+%% @custom_types tag in a dictionary file can also raise an error of
+%% this form.
+rc({'DIAMETER', 5014 = RC, _}, #diameter_avp{name = AvpName} = Avp, Opts, Mod) ->
+ {RC, Avp#diameter_avp{data = Mod:empty_value(AvpName, Opts)}};
+
+%% 3588:
+%%
+%% DIAMETER_INVALID_AVP_VALUE 5004
+%% The request contained an AVP with an invalid value in its data
+%% portion. A Diameter message indicating this error MUST include
+%% the offending AVPs within a Failed-AVP AVP.
+rc(_, Avp, _, _) ->
+ {5004, Avp}.
+
+%% pack_avp/5
+
+pack_avp(Name, #diameter_avp{name = AvpName} = Avp, Opts, Mod, Acc) ->
+ pack_avp(Name, Mod:avp_arity(Name, AvpName), Avp, Opts, Mod, Acc).
+
+%% pack_avp/6
+
+pack_avp(Name, 0, Avp, Opts, Mod, Acc) ->
+ pack_AVP(Name, Avp, Opts, Mod, Acc);
+
+pack_avp(_, Arity, #diameter_avp{name = AvpName} = Avp, _Opts, Mod, Acc) ->
+ pack(Arity, AvpName, Avp, Mod, Acc).
+
+%% pack_AVP/5
+
+%% Length failure was induced because of a header/payload length
+%% mismatch. The AVP Length is reset to match the received data if
+%% this AVP is encoded in an answer message, since the length is
+%% computed.
+%%
+%% Data is a truncated header if command_code = undefined, otherwise
+%% payload bytes. The former is padded to the length of a header if
+%% the AVP reaches an outgoing encode in diameter_codec.
+%%
+%% RFC 6733 says that an AVP returned with 5014 can contain a minimal
+%% payload for the AVP's type, but in this case we don't know the
+%% type.
+
+pack_AVP(_, #diameter_avp{data = {5014 = RC, Data}} = Avp, _, _, Acc) ->
+ {Rec, Failed} = Acc,
+ {Rec, [{RC, Avp#diameter_avp{data = Data}} | Failed]};
+
+pack_AVP(Name, Avp, Opts, Mod, Acc) ->
+ pack_arity(Name, pack_arity(Name, Opts, Mod, Avp), Avp, Mod, Acc).
+
+%% pack_arity/5
+
+pack_arity(_, 0, #diameter_avp{is_mandatory = M} = Avp, _, Acc) ->
+ {Rec, Failed} = Acc,
+ {Rec, [{if M -> 5001; true -> 5008 end, Avp} | Failed]};
+
+pack_arity(_, Arity, Avp, Mod, Acc) ->
+ pack(Arity, 'AVP', Avp, Mod, Acc).
+
+%% Give Failed-AVP special treatment since (1) it'll contain any
+%% unrecognized mandatory AVP's and (2) the RFC 3588 grammar failed to
+%% allow for Failed-AVP in an answer-message.
+
+pack_arity(Name,
+ #{strict_mbit := Strict,
+ failed_avp := Failed},
+ Mod,
+ #diameter_avp{is_mandatory = M,
+ name = AvpName}) ->
+
+ %% Not testing just Name /= 'Failed-AVP' means we're changing the
+ %% packing of AVPs nested within Failed-AVP, but the point of
+ %% ignoring errors within Failed-AVP is to decode as much as
+ %% possible, and failing because a mandatory AVP couldn't be
+ %% packed into a dedicated field defeats that point.
+
+ if Failed == true;
+ Name == 'Failed-AVP';
+ Name == 'answer-message', AvpName == 'Failed-AVP';
+ not M;
+ not Strict ->
+ Mod:avp_arity(Name, 'AVP');
+ true ->
+ 0
+ end.
+
+%% 3588:
+%%
+%% DIAMETER_AVP_UNSUPPORTED 5001
+%% The peer received a message that contained an AVP that is not
+%% recognized or supported and was marked with the Mandatory bit. A
+%% Diameter message with this error MUST contain one or more Failed-
+%% AVP AVP containing the AVPs that caused the failure.
+%%
+%% DIAMETER_AVP_NOT_ALLOWED 5008
+%% A message was received with an AVP that MUST NOT be present. The
+%% Failed-AVP AVP MUST be included and contain a copy of the
+%% offending AVP.
+
+%% pack/5
+
+pack(Arity, FieldName, Avp, Mod, {Rec, _} = Acc) ->
+ pack(Mod:'#get-'(FieldName, Rec), Arity, FieldName, Avp, Mod, Acc).
+
+%% pack/6
+
+pack(undefined, 1, 'AVP' = F, Avp, Mod, {Rec, Failed}) -> %% unlikely
+ {Mod:'#set-'({F, Avp}, Rec), Failed};
+
+pack(undefined, 1, F, #diameter_avp{value = V}, Mod, {Rec, Failed}) ->
+ {Mod:'#set-'({F, V}, Rec), Failed};
+
+%% 3588:
+%%
+%% DIAMETER_AVP_OCCURS_TOO_MANY_TIMES 5009
+%% A message was received that included an AVP that appeared more
+%% often than permitted in the message definition. The Failed-AVP
+%% AVP MUST be included and contain a copy of the first instance of
+%% the offending AVP that exceeded the maximum number of occurrences
+%%
+
+pack(_, 1, _, Avp, _, {Rec, Failed}) ->
+ {Rec, [{5009, Avp} | Failed]};
+
+pack(L, {_, Max}, F, Avp, Mod, {Rec, Failed}) ->
+ case '*' /= Max andalso has_prefix(Max+1, L) of
+ true ->
+ {Rec, [{5009, Avp} | Failed]};
+ false when F == 'AVP' ->
+ {Mod:'#set-'({F, [Avp | L]}, Rec), Failed};
+ false ->
+ {Mod:'#set-'({F, [Avp#diameter_avp.value | L]}, Rec), Failed}
+ end.
+
+%% ---------------------------------------------------------------------------
+%% # grouped_avp/3
+%% ---------------------------------------------------------------------------
+
+-spec grouped_avp(decode, avp_name(), binary() | {5014, binary()}, term())
+ -> {avp_record(), [avp()]};
+ (encode, avp_name(), avp_record() | avp_values(), term())
+ -> iolist()
+ | no_return().
+
+%% Length error induced by diameter_codec:collect_avps/1: the AVP
+%% length in the header was too short (insufficient for the extracted
+%% header) or too long (past the end of the message). An empty payload
+%% is sufficient according to the RFC text for 5014.
+grouped_avp(decode, _Name, {5014 = RC, _Bin}, _) ->
+ ?THROW({grouped, {RC, []}, []});
+
+grouped_avp(decode, Name, Data, Opts) ->
+ grouped_decode(Name, diameter_codec:collect_avps(Data), Opts);
+
+grouped_avp(encode, Name, Data, Opts) ->
+ encode_avps(Name, Data, Opts).
+
+%% grouped_decode/2
+%%
+%% Note that Grouped is the only AVP type that doesn't just return a
+%% decoded value, also returning the list of component diameter_avp
+%% records.
+
+%% Length error in trailing component AVP.
+grouped_decode(_Name, {Error, Acc}, _) ->
+ {5014, Avp} = Error,
+ ?THROW({grouped, Error, [Avp | Acc]});
+
+%% 7.5. Failed-AVP AVP
+
+%% In the case where the offending AVP is embedded within a Grouped AVP,
+%% the Failed-AVP MAY contain the grouped AVP, which in turn contains
+%% the single offending AVP. The same method MAY be employed if the
+%% grouped AVP itself is embedded in yet another grouped AVP and so on.
+%% In this case, the Failed-AVP MAY contain the grouped AVP hierarchy up
+%% to the single offending AVP. This enables the recipient to detect
+%% the location of the offending AVP when embedded in a group.
+
+%% An error in decoding a component AVP throws the first faulty
+%% component, which the catch in d/3 wraps in the Grouped AVP in
+%% question. A partially decoded record is only used when ignoring
+%% errors in Failed-AVP.
+grouped_decode(Name, ComponentAvps, Opts) ->
+ {Rec, Avps, Es} = decode_avps(Name, ComponentAvps, Opts),
+ [] == Es orelse ?THROW({grouped, [{_,_} = hd(Es) | Rec], Avps}),
+ {Rec, Avps}.
+
+%% ---------------------------------------------------------------------------
+%% # empty_group/2
+%% ---------------------------------------------------------------------------
+
+empty_group(Name, #{module := Mod} = Opts) ->
+ list_to_binary([z(F, A, Opts, Mod) || {F,A} <- Mod:avp_arity(Name)]).
+
+z(Name, 1, Opts, Mod) ->
+ z(Name, Opts, Mod);
+z(_, {0,_}, _, _) ->
+ [];
+z(Name, {Min, _}, Opts, Mod) ->
+ binary:copy(z(Name, Opts, Mod), Min).
+
+z('AVP', _, _) ->
+ <<0:64>>; %% minimal header
+z(Name, Opts, Mod) ->
+ Bin = diameter_codec:pack_data(Mod:avp_header(Name),
+ Mod:empty_value(Name, Opts)),
+ Sz = iolist_size(Bin),
+ <<0:Sz/unit:8>>.
+
+%% ---------------------------------------------------------------------------
+%% # empty/2
+%% ---------------------------------------------------------------------------
+
+empty(Name, #{module := Mod} = Opts) ->
+ Mod:avp(encode, zero, Name, Opts).
+
+%% ------------------------------------------------------------------------------
+
+newrec(Mod, Name) ->
+ Mod:'#new-'(Mod:name2rec(Name)).
diff --git a/lib/diameter/src/base/diameter_lib.erl b/lib/diameter/src/base/diameter_lib.erl
index b835e87967..8792e97621 100644
--- a/lib/diameter/src/base/diameter_lib.erl
+++ b/lib/diameter/src/base/diameter_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -37,7 +37,6 @@
ipaddr/1,
spawn_opts/2,
wait/1,
- fold_tuple/3,
fold_n/3,
for_n/2,
log/4]).
@@ -299,8 +298,28 @@ spawn_opts(server, Opts) ->
spawn_opts(worker, Opts) ->
opts(5000, Opts).
-opts(HeapSize, Opts) ->
- [{min_heap_size, HeapSize} | lists:keydelete(min_heap_size, 1, Opts)].
+%% These setting are historical rather than useful. In particular, the
+%% server setting can bloat many processes unnecessarily. Let them be
+%% disabled with -diameter min_heap_size false.
+
+opts(Def, Opts) ->
+ Key = min_heap_size,
+ case getenv(Key, Def) of
+ N when is_integer(N), 0 =< N ->
+ [{Key, N} | lists:keydelete(Key, 1, Opts)];
+ _ ->
+ Opts
+ end.
+
+%% getenv/1
+
+getenv(Key, Def) ->
+ case application:get_env(Key) of
+ {ok, T} ->
+ T;
+ undefined ->
+ Def
+ end.
%% ---------------------------------------------------------------------------
%% # wait/1
@@ -321,36 +340,6 @@ down(MRef)
receive {'DOWN', MRef, process, _, _} = T -> T end.
%% ---------------------------------------------------------------------------
-%% # fold_tuple/3
-%% ---------------------------------------------------------------------------
-
--spec fold_tuple(N, T0, T)
- -> tuple()
- when N :: pos_integer(),
- T0 :: tuple(),
- T :: tuple()
- | undefined.
-
-%% Replace fields in T0 by those of T starting at index N, unless the
-%% new value is 'undefined'.
-%%
-%% eg. fold_tuple(2, Hdr, #diameter_header{end_to_end_id = 42})
-
-fold_tuple(_, T, undefined) ->
- T;
-
-fold_tuple(N, T0, T1) ->
- {_, T} = lists:foldl(fun(V, {I,_} = IT) -> {I+1, ft(V, IT)} end,
- {N, T0},
- lists:nthtail(N-1, tuple_to_list(T1))),
- T.
-
-ft(undefined, {_, T}) ->
- T;
-ft(Value, {Idx, T}) ->
- setelement(Idx, T, Value).
-
-%% ---------------------------------------------------------------------------
%% # fold_n/3
%% ---------------------------------------------------------------------------
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index 996e75a8d3..1b0dc417e5 100644
--- a/lib/diameter/src/base/diameter_peer_fsm.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -128,6 +128,12 @@
%% outgoing DPR; boolean says whether or not
%% the request was sent explicitly with
%% diameter:call/4.
+ codec :: #{string_decode := boolean(),
+ strict_mbit := boolean(),
+ rfc := 3588 | 6733,
+ ordered_encode := false},
+ strict :: boolean(),
+ ack = false :: boolean(),
length_errors :: exit | handle | discard,
incoming_maxlen :: integer() | infinity}).
@@ -158,10 +164,7 @@
%% # start/3
%% ---------------------------------------------------------------------------
--spec start(T, [Opt], {[diameter:service_opt()],
- [node()],
- module(),
- #diameter_service{}})
+-spec start(T, [Opt], {map(), [node()], module(), #diameter_service{}})
-> {reference(), pid()}
when T :: {connect|accept, diameter:transport_ref()},
Opt :: diameter:transport_opt().
@@ -220,9 +223,10 @@ i({Ack, WPid, {M, Ref} = T, Opts, {SvcOpts, Nodes, Dict0, Svc}}) ->
erlang:monitor(process, WPid),
wait(Ack, WPid),
diameter_stats:reg(Ref),
- diameter_codec:setopts([{common_dictionary, Dict0} | SvcOpts]),
- {_,_} = Mask = proplists:get_value(sequence, SvcOpts),
- Maxlen = proplists:get_value(incoming_maxlen, SvcOpts, 16#FFFFFF),
+
+ #{sequence := Mask, incoming_maxlen := Maxlen}
+ = SvcOpts,
+
{[Cs,Ds], Rest} = proplists:split(Opts, [capabilities_cb, disconnect_cb]),
putr(?CB_KEY, {Ref, [F || {_,F} <- Cs]}),
putr(?DPR_KEY, [F || {_, F} <- Ds]),
@@ -233,7 +237,8 @@ i({Ack, WPid, {M, Ref} = T, Opts, {SvcOpts, Nodes, Dict0, Svc}}) ->
proplists:get_value(dpa_timeout, Opts, ?DPA_TIMEOUT)}),
Tmo = proplists:get_value(capx_timeout, Opts, ?CAPX_TIMEOUT),
- OnLengthErr = proplists:get_value(length_errors, Opts, exit),
+ Strictness = proplists:get_value(capx_strictness, Opts, true),
+ LengthErr = proplists:get_value(length_errors, Opts, exit),
{TPid, Addrs} = start_transport(T, Rest, Svc),
@@ -245,8 +250,14 @@ i({Ack, WPid, {M, Ref} = T, Opts, {SvcOpts, Nodes, Dict0, Svc}}) ->
dictionary = Dict0,
mode = M,
service = svc(Svc, Addrs),
- length_errors = OnLengthErr,
- incoming_maxlen = Maxlen}.
+ length_errors = LengthErr,
+ strict = Strictness,
+ incoming_maxlen = Maxlen,
+ codec = maps:with([string_decode,
+ strict_mbit,
+ rfc,
+ ordered_encode],
+ SvcOpts#{ordered_encode => false})}.
%% The transport returns its local ip addresses so that different
%% transports on the same service can use different local addresses.
%% The local addresses are put into Host-IP-Address avps here when
@@ -356,7 +367,7 @@ handle_info(T, #state{} = State) ->
%% Note that there's no guarantee that the service and transport
%% capabilities are good enough to build a CER/CEA that can be
-%% succesfully encoded. It's not checked at diameter:add_transport/2
+%% successfully encoded. It's not checked at diameter:add_transport/2
%% since this can be called before creating the service.
%% terminate/2
@@ -439,9 +450,18 @@ transition({connection_timeout = T, TPid},
transition({connection_timeout, _}, _) ->
ok;
+%% Requests for acknowledgements to the transport.
+transition({diameter, ack}, S) ->
+ S#state{ack = true};
+
%% Incoming message from the transport.
-transition({diameter, {recv, MsgT}}, S) ->
- incoming(MsgT, S);
+transition({diameter, {recv, Msg}}, S) ->
+ incoming(recv(Msg, S), S);
+
+%% Handler of an incoming request is telling of its existence.
+transition({handler, Pid}, _) ->
+ put_route(Pid),
+ ok;
%% Timeout when still in the same state ...
transition({timeout = T, PS}, #state{state = PS}) ->
@@ -454,6 +474,9 @@ transition({timeout, _}, _) ->
%% Outgoing message.
transition({send, Msg}, S) ->
outgoing(Msg, S);
+transition({send, Msg, Route}, S) ->
+ route_outgoing(Route),
+ outgoing(Msg, S);
%% Request for graceful shutdown at remove_transport, stop_service of
%% application shutdown.
@@ -481,10 +504,13 @@ transition({'DOWN', _, process, WPid, _},
transition({'DOWN', _, process, TPid, _},
#state{transport = TPid}
= S) ->
- start_next(S);
+ start_next(S#state{ack = false});
-%% Transport has died after connection timeout.
-transition({'DOWN', _, process, _, _}, _) ->
+%% Transport has died after connection timeout, or handler process has
+%% died.
+transition({'DOWN', _, process, Pid, _}, #state{transport = TPid}) ->
+ is_reference(erase_route(Pid))
+ andalso send(TPid, false), %% answer not forthcoming
ok;
%% State query.
@@ -494,6 +520,59 @@ transition({state, Pid}, #state{state = S, transport = TPid}) ->
%% Crash on anything unexpected.
+%% route_outgoing/1
+
+%% Map identifiers in an outgoing request to be able to lookup the
+%% handler process when the answer is received.
+route_outgoing({Pid, Ref, Seqs}) -> %% request
+ MRef = monitor(process, Pid),
+ put(Pid, Seqs),
+ put(Seqs, {Pid, Ref, MRef});
+
+%% Remove a mapping made for an incoming request.
+route_outgoing(Pid)
+ when is_pid(Pid) -> %% answer
+ MRef = erase_route(Pid),
+ undefined == MRef orelse demonitor(MRef).
+
+%% put_route/1
+
+%% Monitor on a handler process for an incoming request.
+put_route(Pid) ->
+ MRef = monitor(process, Pid),
+ put(Pid, MRef).
+
+%% get_route/2
+
+%% incoming answer
+get_route(_, #diameter_packet{header = #diameter_header{is_request = false}}
+ = Pkt) ->
+ Seqs = diameter_codec:sequence_numbers(Pkt),
+ case erase(Seqs) of
+ {Pid, Ref, MRef} ->
+ demonitor(MRef),
+ erase(Pid),
+ {Pid, Ref, self()};
+ undefined -> %% request unknown
+ false
+ end;
+
+%% incoming request
+get_route(Ack, _) ->
+ Ack.
+
+%% erase_route/1
+
+erase_route(Pid) ->
+ case erase(Pid) of
+ {_,_} = Seqs ->
+ erase(Seqs);
+ T ->
+ T
+ end.
+
+%% capx/1
+
capx(recv_CER) ->
'CER';
capx({'Wait-CEA', _, _}) ->
@@ -518,7 +597,8 @@ send_CER(#state{state = {'Wait-Conn-Ack', Tmo},
mode = {connect, Remote},
service = #diameter_service{capabilities = LCaps},
transport = TPid,
- dictionary = Dict}
+ dictionary = Dict,
+ codec = Opts}
= S) ->
OH = LCaps#diameter_caps.origin_host,
req_send_CER(OH, Remote)
@@ -528,7 +608,7 @@ send_CER(#state{state = {'Wait-Conn-Ack', Tmo},
#diameter_packet{header = #diameter_header{end_to_end_id = Eid,
hop_by_hop_id = Hid}}
= Pkt
- = encode(CER, Dict),
+ = encode(CER, Opts, Dict),
incr(send, Pkt, Dict),
send(TPid, Pkt),
?LOG(send, 'CER'),
@@ -557,37 +637,36 @@ build_CER(#state{service = #diameter_service{capabilities = LCaps},
{ok, CER} = diameter_capx:build_CER(LCaps, Dict),
CER.
-%% encode/2
+%% encode/3
-encode(Rec, Dict) ->
+encode(Rec, Opts, Dict) ->
Seq = diameter_session:sequence({_,_} = getr(?SEQUENCE_KEY)),
Hdr = #diameter_header{version = ?DIAMETER_VERSION,
end_to_end_id = Seq,
hop_by_hop_id = Seq},
- diameter_codec:encode(Dict, #diameter_packet{header = Hdr,
- msg = Rec}).
+ diameter_codec:encode(Dict, Opts, #diameter_packet{header = Hdr,
+ msg = Rec}).
%% incoming/2
-incoming({Msg, NPid}, S) ->
- try recv(Msg, S) of
- T ->
- NPid ! {diameter, discard},
- T
- catch
- {?MODULE, Name, Pkt} ->
- S#state.parent ! {recv, self(), Name, {Pkt, NPid}},
- rcv(Name, Pkt, S)
- end;
+incoming({recv = T, Name, Pkt}, #state{parent = Pid, ack = Ack} = S) ->
+ Pid ! {T, self(), get_route(Ack, Pkt), Name, Pkt},
+ rcv(Name, Pkt, S);
-incoming(Msg, S) ->
- try
- recv(Msg, S)
- catch
- {?MODULE, Name, Pkt} ->
- S#state.parent ! {recv, self(), Name, Pkt},
- rcv(Name, Pkt, S)
- end.
+incoming(#diameter_header{is_request = R}, #state{transport = TPid,
+ ack = Ack}) ->
+ R andalso Ack andalso send(TPid, false),
+ ok;
+
+incoming(<<_:32, 1:1, _/bits>>, #state{ack = true} = S) ->
+ send(S#state.transport, false),
+ ok;
+
+incoming(<<_/bits>>, _) ->
+ ok;
+
+incoming(T, _) ->
+ T.
%% recv/2
@@ -612,7 +691,19 @@ recv1(_,
#diameter_packet{header = H, bin = Bin},
#state{incoming_maxlen = M})
when M < size(Bin) ->
- invalid(false, incoming_maxlen_exceeded, {size(Bin), H});
+ invalid(false, incoming_maxlen_exceeded, {size(Bin), H}),
+ H;
+
+%% Ignore anything but an expected CER/CEA if so configured. This is
+%% non-standard behaviour.
+recv1(Name, #diameter_packet{header = H}, #state{state = {'Wait-CEA', _, _},
+ strict = false})
+ when Name /= 'CEA' ->
+ H;
+recv1(Name, #diameter_packet{header = H}, #state{state = recv_CER,
+ strict = false})
+ when Name /= 'CER' ->
+ H;
%% Incoming request after outgoing DPR: discard. Don't discard DPR, so
%% both ends don't do so when sending simultaneously.
@@ -620,13 +711,15 @@ recv1(Name,
#diameter_packet{header = #diameter_header{is_request = true} = H},
#state{dpr = {_,_,_}})
when Name /= 'DPR' ->
- invalid(false, recv_after_outgoing_dpr, H);
+ invalid(false, recv_after_outgoing_dpr, H),
+ H;
%% Incoming request after incoming DPR: discard.
recv1(_,
#diameter_packet{header = #diameter_header{is_request = true} = H},
#state{dpr = true}) ->
- invalid(false, recv_after_incoming_dpr, H);
+ invalid(false, recv_after_incoming_dpr, H),
+ H;
%% DPA with identifier mismatch, or in response to a DPR initiated by
%% the service.
@@ -644,7 +737,7 @@ recv1('DPA' = N,
%% Any other message with a header and no length errors: send to the
%% parent.
recv1(Name, Pkt, #state{}) ->
- throw({?MODULE, Name, Pkt}).
+ {recv, Name, Pkt}.
%% recv/3
@@ -663,10 +756,12 @@ recv(#diameter_header{}
#diameter_packet{bin = Bin},
#state{length_errors = E}) ->
T = {size(Bin), bit_size(Bin) rem 8, H},
- invalid(E, message_length_mismatch, T);
+ invalid(E, message_length_mismatch, T),
+ Bin;
recv(false, #diameter_packet{bin = Bin}, #state{length_errors = E}) ->
- invalid(E, truncated_header, Bin).
+ invalid(E, truncated_header, Bin),
+ Bin.
%% Note that counters here only count discarded messages.
invalid(E, Reason, T) ->
@@ -710,26 +805,23 @@ rcv('DPA' = N,
= Pkt,
#state{dictionary = Dict0,
transport = TPid,
- dpr = {X, Hid, Eid}}) ->
+ dpr = {X, Hid, Eid},
+ codec = Opts}) ->
?LOG(recv, N),
X orelse begin
%% Only count DPA in response to a DPR sent by the
%% service: explicit DPR is counted in the same way
%% as other explicitly sent requests.
incr(recv, H, Dict0),
- incr_rc(recv, diameter_codec:decode(Dict0, Pkt), Dict0)
+ incr_rc(recv, diameter_codec:decode(Dict0, Opts, Pkt), Dict0)
end,
diameter_peer:close(TPid),
{stop, N};
-%% Ignore anything else, an unsolicited DPA in particular. Note that
-%% dpa_timeout deals with the case in which the peer sends the wrong
-%% identifiers in DPA.
-rcv(N, #diameter_packet{header = H}, _)
- when N == 'CER';
- N == 'CEA';
- N == 'DPR';
- N == 'DPA' ->
+%% Ignore an unsolicited DPA in particular. Note that dpa_timeout
+%% deals with the case in which the peer sends the wrong identifiers
+%% in DPA.
+rcv('DPA' = N, #diameter_packet{header = H}, _) ->
?LOG(ignored, N),
%% Note that these aren't counted in the normal recv counter.
diameter_stats:incr({diameter_codec:msg_id(H), recv, ignored}),
@@ -782,7 +874,7 @@ outgoing(#diameter_packet{header = #diameter_header{application_id = 0,
invalid(false, dpr_after_dpr, H) %% DPR sent: discard
end;
-%% Explict CER or DWR: discard. These are sent by us.
+%% Explicit CER or DWR: discard. These are sent by us.
outgoing(#diameter_packet{header = #diameter_header{application_id = 0,
cmd_code = C,
is_request = true}
@@ -818,15 +910,21 @@ header(Bin) -> %% DWR
%% Incoming CER or DPR.
handle_request(Name,
- #diameter_packet{header = H} = Pkt,
- #state{dictionary = Dict0} = S) ->
+ #diameter_packet{header = H}
+ = Pkt,
+ #state{dictionary = Dict0,
+ codec = Opts}
+ = S) ->
?LOG(recv, Name),
incr(recv, H, Dict0),
- send_answer(Name, diameter_codec:decode(Dict0, Pkt), S).
+ send_answer(Name, diameter_codec:decode(Dict0, Opts, Pkt), S).
%% send_answer/3
-send_answer(Type, ReqPkt, #state{transport = TPid, dictionary = Dict} = S) ->
+send_answer(Type, ReqPkt, #state{transport = TPid,
+ dictionary = Dict,
+ codec = Opts}
+ = S) ->
incr_error(recv, ReqPkt, Dict),
#diameter_packet{header = H,
@@ -845,7 +943,7 @@ send_answer(Type, ReqPkt, #state{transport = TPid, dictionary = Dict} = S) ->
msg = Msg,
transport_data = TD},
- AnsPkt = diameter_codec:encode(Dict, Pkt),
+ AnsPkt = diameter_codec:encode(Dict, Opts, Pkt),
incr(send, AnsPkt, Dict),
incr_rc(send, AnsPkt, Dict),
@@ -872,8 +970,6 @@ build_answer('CER',
= Pkt,
#state{dictionary = Dict0}
= S) ->
- diameter_codec:setopts([{string_decode, false}]),
-
{SupportedApps, RCaps, CEA} = recv_CER(CER, S),
[RC, IS] = Dict0:'#get-'(['Result-Code', 'Inband-Security-Id'], CEA),
@@ -1074,18 +1170,16 @@ recv_CER(CER, #state{service = Svc, dictionary = Dict}) ->
handle_CEA(#diameter_packet{header = H}
= Pkt,
#state{dictionary = Dict0,
- service = #diameter_service{capabilities = LCaps}}
+ service = #diameter_service{capabilities = LCaps},
+ codec = Opts}
= S) ->
incr(recv, H, Dict0),
#diameter_packet{}
= DPkt
- = diameter_codec:decode(Dict0, Pkt),
-
- diameter_codec:setopts([{string_decode, false}]),
+ = diameter_codec:decode(Dict0, Opts, Pkt),
RC = result_code(incr_rc(recv, DPkt, Dict0)),
-
{SApps, IS, RCaps} = recv_CEA(DPkt, S),
#diameter_caps{origin_host = {OH, DH}}
@@ -1273,8 +1367,9 @@ dpr([], [Reason | _], S) ->
-record(opts, {cause, timeout}).
-send_dpr(Reason, Opts, #state{dictionary = Dict,
- service = #diameter_service{capabilities = Caps}}
+send_dpr(Reason, DprOpts, #state{dictionary = Dict,
+ service = #diameter_service{capabilities = Caps},
+ codec = Opts}
= S) ->
#opts{cause = Cause, timeout = Tmo}
= lists:foldl(fun opt/2,
@@ -1283,7 +1378,7 @@ send_dpr(Reason, Opts, #state{dictionary = Dict,
_ -> ?REBOOT
end,
timeout = dpa_timeout()},
- Opts),
+ DprOpts),
#diameter_caps{origin_host = {OH, _},
origin_realm = {OR, _}}
= Caps,
@@ -1291,6 +1386,7 @@ send_dpr(Reason, Opts, #state{dictionary = Dict,
Pkt = encode(['DPR', {'Origin-Host', OH},
{'Origin-Realm', OR},
{'Disconnect-Cause', Cause}],
+ Opts,
Dict),
send_dpr(false, Pkt, Tmo, S).
diff --git a/lib/diameter/src/base/diameter_reg.erl b/lib/diameter/src/base/diameter_reg.erl
index 9027130063..97e74657bd 100644
--- a/lib/diameter/src/base/diameter_reg.erl
+++ b/lib/diameter/src/base/diameter_reg.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -137,7 +137,7 @@ match(Pat) ->
match(Pat, Pid) ->
ets:match_object(?TABLE, {Pat, Pid}).
-
+
%% ===========================================================================
%% # wait(Pat)
%%
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl
index ccf68f4d93..a976a8b998 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -88,12 +88,6 @@
%% outside of the service process.
-define(STATE_TABLE, ?MODULE).
-%% The default sequence mask.
--define(NOMASK, {0,32}).
-
-%% The default restrict_connections.
--define(RESTRICT, nodes).
-
%% Workaround for dialyzer's lack of understanding of match specs.
-type match(T)
:: T | '_' | '$1' | '$2'.
@@ -110,21 +104,17 @@
service :: #diameter_service{},
watchdogT = ets_new(watchdogs) %% #watchdog{} at start
:: ets:tid(),
- peerT, %% undefined in new code, but remain for upgrade
- shared_peers, %% reasons. Replaced by local/remote.
- local_peers, %%
local :: {ets:tid(), ets:tid(), ets:tid()},
remote :: {ets:tid(), ets:tid(), ets:tid()},
monitor = false :: false | pid(), %% process to die with
- options
- :: [{sequence, diameter:sequence()} %% sequence mask
- | {share_peers, diameter:remotes()} %% broadcast to
- | {use_shared_peers, diameter:remotes()} %% use from
- | {restrict_connections, diameter:restriction()}
- | {strict_mbit, boolean()}
- | {string_decode, boolean()}
- | {incoming_maxlen, diameter:message_length()}]}).
-%% shared_peers reflects the peers broadcast from remote nodes.
+ options :: #{sequence := diameter:sequence(), %% sequence mask
+ share_peers := diameter:remotes(),%% broadcast to
+ use_shared_peers := diameter:remotes(),%% use from
+ restrict_connections := diameter:restriction(),
+ incoming_maxlen := diameter:message_length(),
+ strict_mbit := boolean(),
+ string_decode := boolean(),
+ spawn_opt := list() | {module(), atom(), list()}}}).
%% Record representing an RFC 3539 watchdog process implemented by
%% diameter_watchdog.
@@ -284,7 +274,7 @@ whois(SvcName) ->
%% ---------------------------------------------------------------------------
-spec pick_peer(SvcName, AppOrAlias, Opts)
- -> {{TPid, Caps, App}, Mask, SvcOpts}
+ -> {{{TPid, Caps}, App}, SvcOpts}
| false %% no selection
| {error, no_service}
when SvcName :: diameter:service_name(),
@@ -292,14 +282,12 @@ whois(SvcName) ->
| {alias, diameter:app_alias()},
Opts :: {fun((Dict :: module()) -> [term()]),
diameter:peer_filter(),
- Xtra :: list()},
+ Xtra :: list(),
+ [diameter:peer_ref()]},
TPid :: pid(),
Caps :: #diameter_caps{},
App :: #diameter_app{},
- Mask :: diameter:sequence(),
- SvcOpts :: [diameter:service_opt()].
-%% Extract Mask in the returned tuple so that diameter_traffic doesn't
-%% need to know about the ordering of SvcOpts used here.
+ SvcOpts :: map().
pick_peer(SvcName, App, Opts) ->
pick(lookup_state(SvcName), App, Opts).
@@ -319,16 +307,16 @@ pick(#state{service = #diameter_service{applications = Apps}}
pick(_, false = No, _) ->
No;
-pick(#state{options = [{_, Mask} | SvcOpts]}
+pick(#state{options = SvcOpts}
= S,
#diameter_app{module = ModX, dictionary = Dict}
= App0,
- {DestF, Filter, Xtra}) ->
+ {DestF, Filter, Xtra, TPids}) ->
App = App0#diameter_app{module = ModX ++ Xtra},
[_,_] = RealmAndHost = diameter_lib:eval([DestF, Dict]),
- case pick_peer(App, RealmAndHost, Filter, S) of
- {TPid, Caps} ->
- {{TPid, Caps, App}, Mask, SvcOpts};
+ case pick_peer(App, RealmAndHost, [Filter | TPids], S) of
+ {_TPid, _Caps} = TC ->
+ {{TC, App}, SvcOpts};
false = No ->
No
end.
@@ -556,81 +544,9 @@ terminate(Reason, #state{service_name = Name, local = {PeerT, _, _}} = S) ->
%% # code_change/3
%% ---------------------------------------------------------------------------
-code_change(_FromVsn, #state{} = S, _Extra) ->
- {ok, S};
-
-%% Don't support downgrade since we won't in appup.
-code_change({down = T, _}, _, _Extra) ->
- {error, T};
-
-%% Upgrade local/shared peers dicts populated in old code. Don't
-code_change(_FromVsn, S0, _Extra) ->
- {state, Id, SvcName, Svc, WT, PeerT, SDict, LDict, Monitor, Opts}
- = S0,
-
- init_peers(LT = setelement(1, {PT, _, _} = init_peers(), PeerT),
- fun({_,A}) -> A end),
- init_peers(init_peers(RT = init_peers(), SDict),
- fun(A) -> A end),
-
- S = #state{id = Id,
- service_name = SvcName,
- service = Svc,
- watchdogT = WT,
- peerT = PT, %% empty
- shared_peers = SDict,
- local_peers = LDict,
- local = LT,
- remote = RT,
- monitor = Monitor,
- options = Opts},
-
- %% Replacing the table entry and deleting the old shared tables
- %% can make outgoing requests return {error, no_connection} until
- %% everyone is running new code. Don't delete the tables to avoid
- %% crashing request processes.
- ets:delete_all_objects(SDict),
- ets:delete_all_objects(LDict),
- ets:insert(?STATE_TABLE, S),
+code_change(_FromVsn, S, _Extra) ->
{ok, S}.
-%% init_peers/2
-
-%% Populate app and identity bags from a new-style #peer{} sets.
-init_peers({PeerT, _, _} = T, F)
- when is_function(F) ->
- ets:foldl(fun(#peer{pid = P, apps = As, caps = C}, N) ->
- insert_peer(P, lists:map(F, As), C, T),
- N+1
- end,
- 0,
- PeerT);
-
-%% Populate #peer{} table given a shared peers dict.
-init_peers({PeerT, _, _}, SDict) ->
- dict:fold(fun(P, As, N) ->
- ets:update_element(PeerT, P, {#peer.apps, As}),
- N+1
- end,
- 0,
- diameter_dict:fold(fun(A, Ps, D) ->
- init_peers(A, Ps, PeerT, D)
- end,
- dict:new(),
- SDict)).
-
-%% init_peers/4
-
-init_peers(App, TCs, PeerT, Dict) ->
- lists:foldl(fun({P,C}, D) ->
- ets:insert(PeerT, #peer{pid = P,
- apps = [],
- caps = C}),
- dict:append(P, App, D)
- end,
- Dict,
- TCs).
-
%% ===========================================================================
%% ===========================================================================
@@ -768,7 +684,7 @@ cfg_acc({SvcName, #diameter_service{applications = Apps} = Rec, Opts},
local = init_peers(),
remote = init_peers(),
monitor = mref(get_value(monitor, Opts)),
- options = service_options(Opts)},
+ options = service_options(lists:keydelete(monitor, 1, Opts))},
{S, Acc};
cfg_acc({_Ref, Type, _Opts} = T, {S, Acc})
@@ -784,24 +700,14 @@ init_peers() ->
%% TPid}
service_options(Opts) ->
- [{sequence, proplists:get_value(sequence, Opts, ?NOMASK)},
- {share_peers, get_value(share_peers, Opts)},
- {use_shared_peers, get_value(use_shared_peers, Opts)},
- {restrict_connections, proplists:get_value(restrict_connections,
- Opts,
- ?RESTRICT)},
- {spawn_opt, proplists:get_value(spawn_opt, Opts, [])},
- {string_decode, proplists:get_value(string_decode, Opts, true)},
- {incoming_maxlen, proplists:get_value(incoming_maxlen, Opts, 16#FFFFFF)},
- {strict_mbit, proplists:get_value(strict_mbit, Opts, true)}].
-%% The order of options is significant since we match against the list.
+ maps:from_list(Opts).
mref(false = No) ->
No;
mref(P) ->
monitor(process, P).
-init_shared(#state{options = [_, _, {_,T} | _],
+init_shared(#state{options = #{use_shared_peers := T},
service_name = Svc}) ->
notify(T, Svc, {service, self()}).
@@ -899,7 +805,8 @@ start(Ref, Type, Opts, State) ->
start(Ref, Type, Opts, N, #state{watchdogT = WatchdogT,
local = {PeerT, _, _},
- options = SvcOpts,
+ options = #{string_decode := SD}
+ = SvcOpts0,
service_name = SvcName,
service = Svc0})
when Type == connect;
@@ -907,21 +814,25 @@ start(Ref, Type, Opts, N, #state{watchdogT = WatchdogT,
#diameter_service{applications = Apps}
= Svc1
= merge_service(Opts, Svc0),
- Svc = binary_caps(Svc1, proplists:get_value(string_decode, SvcOpts, true)),
- RecvData = diameter_traffic:make_recvdata([SvcName,
- PeerT,
- Apps,
- SvcOpts]),
- T = {{spawn_opts([Opts, SvcOpts]), RecvData}, Opts, SvcOpts, Svc},
+ Svc = binary_caps(Svc1, SD),
+ SvcOpts = merge_options(Opts, SvcOpts0),
+ RecvData = diameter_traffic:make_recvdata([SvcName, PeerT, Apps, SvcOpts]),
+ T = {Opts, SvcOpts, RecvData, Svc},
Rec = #watchdog{type = Type,
ref = Ref,
options = Opts},
+
diameter_lib:fold_n(fun(_,A) ->
[wd(Type, Ref, T, WatchdogT, Rec) | A]
end,
[],
N).
+merge_options(Opts, SvcOpts) ->
+ Keys = maps:keys(SvcOpts),
+ Map = maps:from_list([KV || {K,_} = KV <- Opts, lists:member(K, Keys)]),
+ maps:merge(SvcOpts, Map).
+
binary_caps(Svc, true) ->
Svc;
binary_caps(#diameter_service{capabilities = Caps} = Svc, false) ->
@@ -936,12 +847,6 @@ wd(Type, Ref, T, WatchdogT, Rec) ->
%% record so that each watchdog may get a different record. This
%% record is what is passed back into application callbacks.
-spawn_opts(Optss) ->
- SpawnOpts = get_value(spawn_opt, Optss, []),
- [T || T <- SpawnOpts,
- T /= link,
- T /= monitor].
-
start_watchdog(Type, Ref, T) ->
{_MRef, Pid} = diameter_watchdog:start({Type, Ref}, T),
Pid.
@@ -1154,18 +1059,6 @@ keyfind([Key | Rest], Pos, L) ->
T
end.
-%% get_value/3
-
-get_value(_, [], Def) ->
- Def;
-get_value(Key, [L | Rest], Def) ->
- case lists:keyfind(Key, 1, L) of
- {_,V} ->
- V;
- _ ->
- get_value(Key, Rest, Def)
- end.
-
%% find_outgoing_app/2
find_outgoing_app(Alias, Apps) ->
@@ -1463,19 +1356,19 @@ send_event(#diameter_event{service = SvcName} = E) ->
%% # share_peer/5
%% ---------------------------------------------------------------------------
-share_peer(up, Caps, Apps, TPid, #state{options = [_, {_,T} | _],
+share_peer(up, Caps, Apps, TPid, #state{options = #{share_peers := SP},
service_name = Svc}) ->
- notify(T, Svc, {peer, TPid, [A || {_,A} <- Apps], Caps});
+ notify(SP, Svc, {peer, TPid, [A || {_,A} <- Apps], Caps});
-share_peer(down, _Caps, _Apps, TPid, #state{options = [_, {_,T} | _],
+share_peer(down, _Caps, _Apps, TPid, #state{options = #{share_peers := SP},
service_name = Svc}) ->
- notify(T, Svc, {peer, TPid}).
+ notify(SP, Svc, {peer, TPid}).
%% ---------------------------------------------------------------------------
%% # share_peers/2
%% ---------------------------------------------------------------------------
-share_peers(Pid, #state{options = [_, {_,SP} | _],
+share_peers(Pid, #state{options = #{share_peers := SP},
local = {PeerT, AppT, _}}) ->
is_remote(Pid, SP)
andalso ets:foldl(fun(T, N) -> N + sp(Pid, AppT, T) end,
@@ -1507,7 +1400,8 @@ is_remote(Pid, T) ->
%% # remote_peer_up/4
%% ---------------------------------------------------------------------------
-remote_peer_up(TPid, Aliases, Caps, #state{options = [_, _, {_,T} | _]} = S) ->
+remote_peer_up(TPid, Aliases, Caps, #state{options = #{use_shared_peers := T}}
+ = S) ->
is_remote(TPid, T) andalso rpu(TPid, Aliases, Caps, S).
rpu(TPid, Aliases, Caps, #state{service = Svc, remote = RT}) ->
@@ -1629,8 +1523,14 @@ pick_peer(Local,
%% peers/4
-peers(Alias, RH, Filter, T) ->
- filter(Alias, RH, Filter, T, true).
+%% No peer options pointing at specific peers: search for them.
+peers(Alias, RH, [Filter], T) ->
+ filter(Alias, RH, Filter, T, true);
+
+%% Or just lookup.
+peers(_Alias, RH, [Filter | TPids], {PeerT, _AppT, _IdentT}) ->
+ {Ts, _} = filter(caps(PeerT, TPids), RH, Filter),
+ Ts.
%% filter/5
%%
@@ -1858,13 +1758,6 @@ eq(Any, Id, PeerId) ->
%% OctetString() can be specified as an iolist() so test for string
%% rather then term equality.
-%% transports/1
-
-transports(#state{watchdogT = WatchdogT}) ->
- ets:select(WatchdogT, [{#watchdog{peer = '$1', _ = '_'},
- [{'is_pid', '$1'}],
- ['$1']}]).
-
%% ---------------------------------------------------------------------------
%% # service_info/2
%% ---------------------------------------------------------------------------
@@ -1887,7 +1780,6 @@ transports(#state{watchdogT = WatchdogT}) ->
-define(ALL_INFO, [capabilities,
applications,
transport,
- pending,
options]).
%% The rest.
@@ -1981,7 +1873,6 @@ complete_info(Item, #state{service = Svc} = S) ->
applications -> info_apps(S);
transport -> info_transport(S);
options -> info_options(S);
- pending -> info_pending(S);
keys -> ?ALL_INFO ++ ?CAP_INFO ++ ?OTHER_INFO;
all -> service_info(?ALL_INFO, S);
statistics -> info_stats(S);
@@ -2189,13 +2080,6 @@ info_apps(#state{service = #diameter_service{applications = Apps}}) ->
mk_app(#diameter_app{} = A) ->
lists:zip(record_info(fields, diameter_app), tl(tuple_to_list(A))).
-%% info_pending/1
-%%
-%% One entry for each outgoing request whose answer is outstanding.
-
-info_pending(#state{} = S) ->
- diameter_traffic:pending(transports(S)).
-
%% info_info/1
%%
%% Extract process_info from connections info.
diff --git a/lib/diameter/src/base/diameter_sup.erl b/lib/diameter/src/base/diameter_sup.erl
index 482289cb9a..01c51f0856 100644
--- a/lib/diameter/src/base/diameter_sup.erl
+++ b/lib/diameter/src/base/diameter_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@
-define(TABLES, [{diameter_sequence, [set]},
{diameter_service, [set, {keypos, 3}]},
- {diameter_request, [bag]},
+ {diameter_request, [set]},
{diameter_config, [bag, {keypos, 2}]}]).
%% start_link/0
diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl
index 2112941d5e..85378babea 100644
--- a/lib/diameter/src/base/diameter_traffic.erl
+++ b/lib/diameter/src/base/diameter_traffic.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@
-export([send_request/4]).
%% towards diameter_watchdog
--export([receive_message/4]).
+-export([receive_message/5]).
%% towards diameter_peer_fsm and diameter_watchdog
-export([incr/4,
@@ -40,11 +40,11 @@
%% towards diameter_service
-export([make_recvdata/1,
peer_up/1,
- peer_down/1,
- pending/1]).
+ peer_down/1]).
-%% towards ?MODULE
--export([send/1]). %% send from remote node
+%% internal
+-export([send/1, %% send from remote node
+ init/1]). %% monitor process start
-include_lib("diameter/include/diameter.hrl").
-include("diameter_internal.hrl").
@@ -54,77 +54,85 @@
-define(RELAY, ?DIAMETER_DICT_RELAY).
-define(BASE, ?DIAMETER_DICT_COMMON). %% Note: the RFC 3588 dictionary
--define(DEFAULT_TIMEOUT, 5000). %% for outgoing requests
--define(DEFAULT_SPAWN_OPTS, []).
+-define(DEFAULT(V, Def), if V == undefined -> Def; true -> V end).
-%% Table containing outgoing requests for which a reply has yet to be
-%% received.
+%% Table containing outgoing entries that live and die with
+%% peer_up/down. The name is historic, since the table used to contain
+%% information about outgoing requests for which an answer has yet to
+%% be received.
-define(REQUEST_TABLE, diameter_request).
-%% Workaround for dialyzer's lack of understanding of match specs.
--type match(T)
- :: T | '_' | '$1' | '$2' | '$3' | '$4'.
-
%% Record diameter:call/4 options are parsed into.
-record(options,
- {filter = none :: diameter:peer_filter(),
+ {peers = [] :: [diameter:peer_ref()],
+ filter = none :: diameter:peer_filter(),
extra = [] :: list(),
- timeout = ?DEFAULT_TIMEOUT :: 0..16#FFFFFFFF,
+ timeout = 5000 :: 0..16#FFFFFFFF, %% for outgoing requests
detach = false :: boolean()}).
-%% Term passed back to receive_message/4 with every incoming message.
+%% Term passed back to receive_message/6 with every incoming message.
-record(recvdata,
{peerT :: ets:tid(),
service_name :: diameter:service_name(),
apps :: [#diameter_app{}],
sequence :: diameter:sequence(),
- codec :: [{string_decode, boolean()}
- | {strict_mbit, boolean()}
- | {incoming_maxlen, diameter:message_length()}]}).
+ codec :: #{string_decode := boolean(),
+ strict_mbit := boolean(),
+ incoming_maxlen := diameter:message_length()}}).
%% Note that incoming_maxlen is currently handled in diameter_peer_fsm,
%% so that any message exceeding the maximum is discarded. Retain the
%% option in case we want to extend the values and semantics.
%% Record stored in diameter_request for each outgoing request.
-record(request,
- {ref :: match(reference()), %% used to receive answer
- caller :: match(pid()), %% calling process
- handler :: match(pid()), %% request process
- transport :: match(pid()), %% peer process
- caps :: match(#diameter_caps{}), %% of connection
- packet :: match(#diameter_packet{})}). %% of request
+ {ref :: reference(), %% used to receive answer
+ caller :: pid() | undefined, %% calling process
+ handler :: pid(), %% request process
+ peer :: undefined | {pid(), #diameter_caps{}},
+ packet :: #diameter_packet{} | undefined}). %% of request
%% ---------------------------------------------------------------------------
-%% # make_recvdata/1
+%% make_recvdata/1
%% ---------------------------------------------------------------------------
make_recvdata([SvcName, PeerT, Apps, SvcOpts | _]) ->
- {_,_} = Mask = proplists:get_value(sequence, SvcOpts),
- #recvdata{service_name = SvcName,
- peerT = PeerT,
- apps = Apps,
- sequence = Mask,
- codec = [T || {K,_} = T <- SvcOpts,
- lists:member(K, [string_decode,
- incoming_maxlen,
- strict_mbit])]}.
+ #{sequence := {_,_} = Mask, spawn_opt := Opts}
+ = SvcOpts,
+ {Opts, #recvdata{service_name = SvcName,
+ peerT = PeerT,
+ apps = Apps,
+ sequence = Mask,
+ codec = maps:with([string_decode,
+ strict_mbit,
+ ordered_encode,
+ incoming_maxlen],
+ SvcOpts)}}.
%% ---------------------------------------------------------------------------
%% peer_up/1
%% ---------------------------------------------------------------------------
-%% Insert an element that is used to detect whether or not there has
-%% been a failover when inserting an outgoing request.
+%% Start a process that dies with peer_down/1, on which request
+%% processes can monitor. There is no other process that dies with
+%% peer_down since failover doesn't imply the loss of transport in the
+%% case of a watchdog transition into state SUSPECT.
peer_up(TPid) ->
- ets:insert(?REQUEST_TABLE, {TPid}).
+ proc_lib:start(?MODULE, init, [TPid]).
+
+init(TPid) ->
+ ets:insert(?REQUEST_TABLE, {TPid, self()}),
+ proc_lib:init_ack(self()),
+ proc_lib:hibernate(erlang, exit, [{shutdown, TPid}]).
%% ---------------------------------------------------------------------------
%% peer_down/1
%% ---------------------------------------------------------------------------
peer_down(TPid) ->
+ [{_, Pid}] = ets:lookup(?REQUEST_TABLE, TPid),
ets:delete(?REQUEST_TABLE, TPid),
- failover(TPid).
+ Pid ! ok, %% make it die
+ Pid.
%% ---------------------------------------------------------------------------
%% incr/4
@@ -199,71 +207,40 @@ incr_rc(Dir, Pkt, TPid, Dict0) ->
incr_rc(Dir, Pkt, TPid, {Dict0, Dict0, Dict0}).
%% ---------------------------------------------------------------------------
-%% pending/1
-%% ---------------------------------------------------------------------------
-
-pending(TPids) ->
- MatchSpec = [{{'$1',
- #request{caller = '$2',
- handler = '$3',
- transport = '$4',
- _ = '_'},
- '_'},
- [?ORCOND([{'==', T, '$4'} || T <- TPids])],
- [{{'$1', [{{caller, '$2'}},
- {{handler, '$3'}},
- {{transport, '$4'}}]}}]}],
-
- try
- ets:select(?REQUEST_TABLE, MatchSpec)
- catch
- error: badarg -> [] %% service has gone down
- end.
-
-%% ---------------------------------------------------------------------------
-%% # receive_message/4
+%% receive_message/5
%%
-%% Handle an incoming Diameter message.
+%% Handle an incoming Diameter message in a watchdog process.
%% ---------------------------------------------------------------------------
-%% Handle an incoming Diameter message in the watchdog process. This
-%% used to come through the service process but this avoids that
-%% becoming a bottleneck.
-
-receive_message(TPid, {Pkt, NPid}, Dict0, RecvData) ->
- NPid ! {diameter, incoming(TPid, Pkt, Dict0, RecvData)};
-
-receive_message(TPid, Pkt, Dict0, RecvData) ->
- incoming(TPid, Pkt, Dict0, RecvData).
-
-%% incoming/4
-
-incoming(TPid, Pkt, Dict0, RecvData)
- when is_pid(TPid) ->
+-spec receive_message(pid(), Route, #diameter_packet{}, module(), RecvData)
+ -> pid() %% request handler
+ | boolean() %% answer, known request or not
+ | discard %% request discarded by MFA
+ when Route :: {Handler, RequestRef, Seqs}
+ | Ack,
+ RecvData :: {[SpawnOpt], #recvdata{}},
+ SpawnOpt :: term(),
+ Handler :: pid(),
+ RequestRef :: reference(),
+ Seqs :: {0..16#FFFFFFFF, 0..16#FFFFFFFF},
+ Ack :: boolean().
+
+receive_message(TPid, Route, Pkt, Dict0, RecvData) ->
#diameter_packet{header = #diameter_header{is_request = R}} = Pkt,
- recv(R,
- (not R) andalso lookup_request(Pkt, TPid),
- TPid,
- Pkt,
- Dict0,
- RecvData).
+ recv(R, Route, TPid, Pkt, Dict0, RecvData).
%% recv/6
%% Incoming request ...
-recv(true, false, TPid, Pkt, Dict0, T) ->
- try
- {request, spawn_request(TPid, Pkt, Dict0, T)}
- catch
- error: system_limit = E -> %% discard
- ?LOG(error, E),
- discard
- end;
+recv(true, Ack, TPid, Pkt, Dict0, T)
+ when is_boolean(Ack) ->
+ {Opts, RecvData} = T,
+ spawn_request(Ack, TPid, Pkt, Dict0, RecvData, Opts);
%% ... answer to known request ...
-recv(false, #request{ref = Ref, handler = Pid} = Req, _, Pkt, Dict0, _) ->
- Pid ! {answer, Ref, Req, Dict0, Pkt},
- {answer, Pid};
+recv(false, {Pid, Ref, TPid}, _, Pkt, Dict0, _) ->
+ Pid ! {answer, Ref, TPid, Dict0, Pkt},
+ true;
%% Note that failover could have happened prior to this message being
%% received and triggering failback. That is, both a failover message
@@ -278,69 +255,91 @@ recv(false, #request{ref = Ref, handler = Pid} = Req, _, Pkt, Dict0, _) ->
recv(false, false, TPid, Pkt, _, _) ->
?LOG(discarded, Pkt#diameter_packet.header),
incr(TPid, {{unknown, 0}, recv, discarded}),
- discard.
+ false.
-%% spawn_request/4
+%% spawn_request/6
-spawn_request(TPid, Pkt, Dict0, {Opts, RecvData}) ->
- spawn_request(TPid, Pkt, Dict0, Opts, RecvData);
-spawn_request(TPid, Pkt, Dict0, RecvData) ->
- spawn_request(TPid, Pkt, Dict0, ?DEFAULT_SPAWN_OPTS, RecvData).
+%% An MFA should return a pid() or the atom 'discard'. The latter
+%% results in an acknowledgment back to the transport process when
+%% appropriate, to ensure that send/recv callbacks can count
+%% outstanding requests. Acknowledgement is implicit if the
+%% handler process dies (in a handle_request callback for example).
+spawn_request(Ack, TPid, Pkt, Dict0, RecvData, {M,F,A}) ->
+ ReqF = fun() ->
+ ack(Ack, TPid, recv_request(Ack, TPid, Pkt, Dict0, RecvData))
+ end,
+ ack(Ack, TPid, apply(M, F, [ReqF | A]));
+
+%% A spawned process acks implicitly when it dies, so there's no need
+%% to handle 'discard'.
+spawn_request(Ack, TPid, Pkt, Dict0, RecvData, Opts) ->
+ spawn_opt(fun() ->
+ recv_request(Ack, TPid, Pkt, Dict0, RecvData)
+ end,
+ Opts).
+
+%% ack/3
-spawn_request(TPid, Pkt, Dict0, Opts, RecvData) ->
- spawn_opt(fun() -> recv_request(TPid, Pkt, Dict0, RecvData) end, Opts).
+ack(Ack, TPid, RC) ->
+ RC == discard andalso Ack andalso (TPid ! {send, false}),
+ RC.
%% ---------------------------------------------------------------------------
-%% recv_request/4
+%% recv_request/5
%% ---------------------------------------------------------------------------
-recv_request(TPid,
+-spec recv_request(Ack :: boolean(),
+ TPid :: pid(),
+ #diameter_packet{},
+ Dict0 :: module(),
+ #recvdata{})
+ -> ok %% answer was sent
+ | discard %% or not
+ | false. %% no transport
+
+recv_request(Ack,
+ TPid,
#diameter_packet{header = #diameter_header{application_id = Id}}
= Pkt,
Dict0,
#recvdata{peerT = PeerT,
- apps = Apps,
- codec = Opts}
+ apps = Apps}
= RecvData) ->
- diameter_codec:setopts([{common_dictionary, Dict0} | Opts]),
- send_A(recv_R(diameter_service:find_incoming_app(PeerT, TPid, Id, Apps),
- TPid,
- Pkt,
- Dict0,
- RecvData),
- TPid,
- Dict0,
- RecvData).
-
-%% recv_R/5
-
-recv_R({#diameter_app{id = Id, dictionary = AppDict} = App, Caps},
- TPid,
- Pkt0,
- Dict0,
- RecvData) ->
- incr(recv, Pkt0, TPid, AppDict),
- Pkt = errors(Id, diameter_codec:decode(Id, AppDict, Pkt0)),
- incr_error(recv, Pkt, TPid, AppDict),
- {Caps, Pkt, App, recv_R(App, TPid, Dict0, Caps, RecvData, Pkt)};
-%% Note that the decode is different depending on whether or not Id is
-%% ?APP_ID_RELAY.
-
-%% DIAMETER_APPLICATION_UNSUPPORTED 3007
-%% A request was sent for an application that is not supported.
-
-recv_R(#diameter_caps{}
- = Caps,
- _TPid,
- #diameter_packet{errors = Es}
- = Pkt,
- _Dict0,
- _RecvData) ->
- {Caps, Pkt#diameter_packet{avps = collect_avps(Pkt),
- errors = [3007 | Es]}};
+ Ack andalso (TPid ! {handler, self()}),
+ case diameter_service:find_incoming_app(PeerT, TPid, Id, Apps) of
+ {#diameter_app{id = Aid, dictionary = AppDict} = App, Caps} ->
+ incr(recv, Pkt, TPid, AppDict),
+ DecPkt = decode(Aid, AppDict, RecvData, Pkt),
+ incr_error(recv, DecPkt, TPid, AppDict),
+ send_A(recv_R(App, TPid, Dict0, Caps, RecvData, DecPkt),
+ TPid,
+ App,
+ Dict0,
+ RecvData,
+ DecPkt,
+ Caps);
+ #diameter_caps{} = Caps ->
+ %% DIAMETER_APPLICATION_UNSUPPORTED 3007
+ %% A request was sent for an application that is not
+ %% supported.
+ RC = 3007,
+ Es = Pkt#diameter_packet.errors,
+ DecPkt = Pkt#diameter_packet{avps = collect_avps(Pkt),
+ errors = [RC | Es]},
+ send_answer(answer_message(RC, Dict0, Caps, DecPkt),
+ TPid,
+ Dict0,
+ Dict0,
+ Dict0,
+ RecvData,
+ DecPkt,
+ [[]]);
+ false = No -> %% transport has gone down
+ No
+ end.
-recv_R(false = No, _, _, _, _) -> %% transport has gone down
- No.
+decode(Id, Dict, #recvdata{codec = Opts}, Pkt) ->
+ errors(Id, diameter_codec:decode(Id, Dict, Opts, Pkt)).
collect_avps(Pkt) ->
case diameter_codec:collect_avps(Pkt) of
@@ -350,6 +349,14 @@ collect_avps(Pkt) ->
Avps
end.
+%% send_A/7
+
+send_A([T | Fs], TPid, App, Dict0, RecvData, DecPkt, Caps) ->
+ send_A(T, TPid, App, Dict0, RecvData, DecPkt, Caps, Fs);
+
+send_A(discard = No, _, _, _, _, _, _) ->
+ No.
+
%% recv_R/6
%% Answer errors ourselves ...
@@ -359,9 +366,9 @@ recv_R(#diameter_app{options = [_, {request_errors, E} | _]},
_Caps,
_RecvData,
#diameter_packet{errors = [RC|_]}) %% a detected 3xxx is hd
- when E == answer, (Dict0 /= ?BASE orelse 3 == RC div 1000);
+ when E == answer, Dict0 /= ?BASE orelse 3 == RC div 1000;
E == answer_3xxx, 3 == RC div 1000 ->
- {{answer_message, rc(RC)}, [], []};
+ [{answer_message, rc(RC)}, []];
%% ... or make a handle_request callback. Note that
%% Pkt#diameter_packet.msg = undefined in the 3001 case.
@@ -453,24 +460,24 @@ errors(_, Pkt) ->
%% command code in this case. It will also then ignore Dict and use
%% the base encoder.
request_cb({reply, _Ans} = T, _App, EvalPktFs, EvalFs) ->
- {T, EvalPktFs, EvalFs};
+ [T, EvalPktFs | EvalFs];
%% An 3xxx result code, for which the E-bit is set in the header.
request_cb({protocol_error, RC}, _App, EvalPktFs, EvalFs)
when 3 == RC div 1000 ->
- {{answer_message, RC}, EvalPktFs, EvalFs};
+ [{answer_message, RC}, EvalPktFs | EvalFs];
request_cb({answer_message, RC} = T, _App, EvalPktFs, EvalFs)
when 3 == RC div 1000;
5 == RC div 1000 ->
- {T, EvalPktFs, EvalFs};
+ [T, EvalPktFs | EvalFs];
%% RFC 3588 says we must reply 3001 to anything unrecognized or
%% unsupported. 'noreply' is undocumented (and inappropriately named)
%% backwards compatibility for this, protocol_error the documented
%% alternative.
request_cb(noreply, _App, EvalPktFs, EvalFs) ->
- {{answer_message, 3001}, EvalPktFs, EvalFs};
+ [{answer_message, 3001}, EvalPktFs | EvalFs];
%% Relay a request to another peer. This is equivalent to doing an
%% explicit call/4 with the message in question except that (1) a loop
@@ -491,7 +498,7 @@ request_cb({A, Opts}, #diameter_app{id = Id}, EvalPktFs, EvalFs)
when A == relay, Id == ?APP_ID_RELAY;
A == proxy, Id /= ?APP_ID_RELAY;
A == resend ->
- {{call, Opts}, EvalPktFs, EvalFs};
+ [{call, Opts}, EvalPktFs | EvalFs];
request_cb(discard = No, _, _, _) ->
No;
@@ -505,71 +512,95 @@ request_cb({eval, RC, F}, App, EvalPktFs, Fs) ->
request_cb(T, App, _, _) ->
?ERROR({invalid_return, T, handle_request, App}).
-%% send_A/4
+%% send_A/8
+
+send_A({reply, Ans}, TPid, App, Dict0, RecvData, Pkt, _Caps, Fs) ->
+ AppDict = App#diameter_app.dictionary,
+ MsgDict = msg_dict(AppDict, Dict0, Ans),
+ send_answer(Ans,
+ TPid,
+ MsgDict,
+ AppDict,
+ Dict0,
+ RecvData,
+ Pkt,
+ Fs);
+
+send_A({call, Opts}, TPid, App, Dict0, RecvData, Pkt, Caps, Fs) ->
+ AppDict = App#diameter_app.dictionary,
+ case resend(Opts, Caps, Pkt, App, Dict0, RecvData) of
+ #diameter_packet{bin = Bin} = Ans -> %% answer: reset hop by hop id
+ #diameter_packet{header = #diameter_header{hop_by_hop_id = Id},
+ transport_data = TD}
+ = Pkt,
+ Reset = diameter_codec:hop_by_hop_id(Id, Bin),
+ MsgDict = msg_dict(AppDict, Dict0, Ans),
+ send_answer(Ans#diameter_packet{bin = Reset,
+ transport_data = TD},
+ TPid,
+ MsgDict,
+ AppDict,
+ Dict0,
+ Fs);
+ RC ->
+ send_answer(answer_message(RC, Dict0, Caps, Pkt),
+ TPid,
+ Dict0,
+ AppDict,
+ Dict0,
+ RecvData,
+ Pkt,
+ Fs)
+ end;
+
+%% RFC 3588 only allows 3xxx errors in an answer-message. RFC 6733
+%% added the possibility of setting 5xxx.
-send_A({Caps, Pkt}, TPid, Dict0, _RecvData) -> %% unsupported application
- #diameter_packet{errors = [RC|_]} = Pkt,
- send_A(answer_message(RC, Caps, Dict0, Pkt),
- TPid,
- {Dict0, Dict0},
- Pkt,
- [],
- []);
+send_A({answer_message, RC} = T, TPid, App, Dict0, RecvData, Pkt, Caps, Fs) ->
+ Dict0 /= ?BASE orelse 3 == RC div 1000
+ orelse ?ERROR({invalid_return, T, handle_request, App}),
+ send_answer(answer_message(RC, Dict0, Caps, Pkt),
+ TPid,
+ Dict0,
+ App#diameter_app.dictionary,
+ Dict0,
+ RecvData,
+ Pkt,
+ Fs).
-send_A({Caps, Pkt, App, {T, EvalPktFs, EvalFs}}, TPid, Dict0, RecvData) ->
- send_A(answer(T, Caps, Pkt, App, Dict0, RecvData),
- TPid,
- {App#diameter_app.dictionary, Dict0},
- Pkt,
- EvalPktFs,
- EvalFs);
+%% send_answer/8
-send_A(_, _, _, _) ->
- ok.
+%% Skip the setting of Result-Code and Failed-AVP's below. This is
+%% undocumented and shouldn't be relied on.
+send_answer([Ans], TPid, MsgDict, AppDict, Dict0, RecvData, Pkt, Fs)
+ when [] == Pkt#diameter_packet.errors ->
+ send_answer(Ans, TPid, MsgDict, AppDict, Dict0, RecvData, Pkt, Fs);
+send_answer([Ans], TPid, MsgDict, AppDict, Dict0, RecvData, Pkt0, Fs) ->
+ Pkt = Pkt0#diameter_packet{errors = []},
+ send_answer(Ans, TPid, MsgDict, AppDict, Dict0, RecvData, Pkt, Fs);
+
+send_answer(Ans, TPid, MsgDict, AppDict, Dict0, RecvData, DecPkt, Fs) ->
+ Pkt = encode({MsgDict, AppDict},
+ TPid,
+ RecvData#recvdata.codec,
+ make_answer_packet(Ans, DecPkt, MsgDict, Dict0)),
+ send_answer(Pkt, TPid, MsgDict, AppDict, Dict0, Fs).
-%% send_A/6
+%% send_answer/6
-send_A(T, TPid, {AppDict, Dict0} = DictT0, ReqPkt, EvalPktFs, EvalFs) ->
- {MsgDict, Pkt} = reply(T, TPid, DictT0, EvalPktFs, ReqPkt),
+send_answer(Pkt, TPid, MsgDict, AppDict, Dict0, [EvalPktFs | EvalFs]) ->
+ eval_packet(Pkt, EvalPktFs),
incr(send, Pkt, TPid, AppDict),
incr_rc(send, Pkt, TPid, {MsgDict, AppDict, Dict0}), %% count outgoing
- send(TPid, Pkt),
+ send(TPid, z(Pkt), _Route = self()),
lists:foreach(fun diameter_lib:eval/1, EvalFs).
-%% answer/6
-
-answer({reply, Ans}, _Caps, _Pkt, App, Dict0, _RecvData) ->
- {msg_dict(App#diameter_app.dictionary, Dict0, Ans), Ans};
-
-answer({call, Opts}, Caps, Pkt, App, Dict0, RecvData) ->
- #diameter_caps{origin_host = {OH,_}}
- = Caps,
- #diameter_packet{avps = Avps}
- = Pkt,
- {Code, _Flags, Vid} = Dict0:avp_header('Route-Record'),
- resend(is_loop(Code, Vid, OH, Dict0, Avps),
- Opts,
- Caps,
- Pkt,
- App,
- Dict0,
- RecvData);
-
-%% RFC 3588 only allows 3xxx errors in an answer-message. RFC 6733
-%% added the possibility of setting 5xxx.
-answer({answer_message, RC} = T, Caps, Pkt, App, Dict0, _RecvData) ->
- Dict0 /= ?BASE orelse 3 == RC div 1000
- orelse ?ERROR({invalid_return, T, handle_request, App}),
- answer_message(RC, Caps, Dict0, Pkt).
-
%% msg_dict/3
%%
%% Return the dictionary defining the message grammar in question: the
%% application dictionary or the common dictionary.
-msg_dict(AppDict, Dict0, [Msg])
- when is_list(Msg);
- is_tuple(Msg) ->
+msg_dict(AppDict, Dict0, [Msg]) ->
msg_dict(AppDict, Dict0, Msg);
msg_dict(AppDict, Dict0, Msg) ->
@@ -600,14 +631,10 @@ is_answer_message(Rec, Dict) ->
error:_ -> false
end.
-%% answer_message/4
+%% resend/6
-answer_message(RC,
- #diameter_caps{origin_host = {OH,_},
- origin_realm = {OR,_}},
- Dict0,
- Pkt) ->
- {Dict0, answer_message(OH, OR, RC, Dict0, Pkt)}.
+resend(Opts, Caps, Pkt, App, Dict0, RecvData) ->
+ resend(is_loop(Dict0, Caps, Pkt), Opts, Caps, Pkt, App, Dict0, RecvData).
%% resend/7
@@ -617,8 +644,8 @@ answer_message(RC,
%% if one is available, but the peer reporting the error has
%% identified a configuration problem.
-resend(true, _Opts, Caps, Pkt, _App, Dict0, _RecvData) ->
- answer_message(3005, Caps, Dict0, Pkt);
+resend(true, _Opts, _Caps, _Pkt, _App, _Dict0, _RecvData) ->
+ 3005;
%% 6.1.8. Relaying and Proxying Requests
%%
@@ -628,11 +655,9 @@ resend(true, _Opts, Caps, Pkt, _App, Dict0, _RecvData) ->
resend(false,
Opts,
- #diameter_caps{origin_host = {_,OH}}
- = Caps,
+ #diameter_caps{origin_host = {_,OH}},
#diameter_packet{header = Hdr0,
- avps = Avps}
- = Pkt,
+ avps = Avps},
App,
Dict0,
#recvdata{service_name = SvcName,
@@ -641,7 +666,12 @@ resend(false,
Seq = diameter_session:sequence(Mask),
Hdr = Hdr0#diameter_header{hop_by_hop_id = Seq},
Msg = [Hdr, Route | Avps], %% reordered at encode
- resend(send_request(SvcName, App, Msg, Opts), Caps, Dict0, Pkt).
+ case send_request(SvcName, App, Msg, Opts) of
+ #diameter_packet{} = Ans ->
+ Ans;
+ _ ->
+ 3002 %% DIAMETER_UNABLE_TO_DELIVER.
+ end.
%% The incoming request is relayed with the addition of a
%% Route-Record. Note the requirement on the return from call/4 below,
%% which places a requirement on the value returned by the
@@ -658,96 +688,38 @@ resend(false,
%% RFC 6.3 says that a relay agent does not modify Origin-Host but
%% says nothing about a proxy. Assume it should behave the same way.
-%% resend/4
-%%
-%% Relay a reply to a relayed request.
-
-%% Answer from the peer: reset the hop by hop identifier.
-resend(#diameter_packet{bin = B}
- = Pkt,
- _Caps,
- _Dict0,
- #diameter_packet{header = #diameter_header{hop_by_hop_id = Id},
- transport_data = TD}) ->
- Pkt#diameter_packet{bin = diameter_codec:hop_by_hop_id(Id, B),
- transport_data = TD};
-%% TODO: counters
+%% is_loop/3
-%% Or not: DIAMETER_UNABLE_TO_DELIVER.
-resend(_, Caps, Dict0, Pkt) ->
- answer_message(3002, Caps, Dict0, Pkt).
+is_loop(Dict0,
+ #diameter_caps{origin_host = {OH,_}},
+ #diameter_packet{avps = Avps}) ->
+ {Code, _Flags, Vid} = Dict0:avp_header('Route-Record'),
+ is_loop(Code, Vid, OH, Avps).
-%% is_loop/5
+%% is_loop/4
%%
%% Is there a Route-Record AVP with our Origin-Host?
-is_loop(Code,
- Vid,
- Bin,
- _Dict0,
- [#diameter_avp{code = Code, vendor_id = Vid, data = Bin} | _]) ->
+is_loop(Code, Vid, Bin, [#diameter_avp{code = Code,
+ vendor_id = Vid,
+ data = Bin}
+ | _]) ->
true;
-is_loop(_, _, _, _, []) ->
+is_loop(_, _, _, []) ->
false;
-is_loop(Code, Vid, OH, Dict0, [_ | Avps])
+is_loop(Code, Vid, OH, [_ | Avps])
when is_binary(OH) ->
- is_loop(Code, Vid, OH, Dict0, Avps);
-
-is_loop(Code, Vid, OH, Dict0, Avps) ->
- is_loop(Code, Vid, Dict0:avp(encode, OH, 'Route-Record'), Dict0, Avps).
-
-%% reply/5
-
-%% Local answer ...
-reply({MsgDict, Ans}, TPid, {AppDict, Dict0}, Fs, ReqPkt) ->
- local(Ans, TPid, {MsgDict, AppDict, Dict0}, Fs, ReqPkt);
-
-%% ... or relayed.
-reply(#diameter_packet{} = Pkt, _TPid, {AppDict, Dict0}, Fs, _ReqPkt) ->
- eval_packet(Pkt, Fs),
- {msg_dict(AppDict, Dict0, Pkt), Pkt}.
-
-%% local/5
-%%
-%% Send a locally originating reply.
-
-%% Skip the setting of Result-Code and Failed-AVP's below. This is
-%% undocumented and shouldn't be relied on.
-local([Msg], TPid, DictT, Fs, ReqPkt)
- when is_list(Msg);
- is_tuple(Msg) ->
- local(Msg, TPid, DictT, Fs, ReqPkt#diameter_packet{errors = []});
-
-local(Msg, TPid, {MsgDict, AppDict, Dict0}, Fs, ReqPkt) ->
- Pkt = encode({MsgDict, AppDict},
- TPid,
- reset(make_answer_packet(Msg, ReqPkt), MsgDict, Dict0),
- Fs),
- {MsgDict, Pkt}.
-
-%% reset/3
+ is_loop(Code, Vid, OH, Avps);
-%% Header/avps list: send as is.
-reset(#diameter_packet{msg = [#diameter_header{} | _]} = Pkt, _, _) ->
- Pkt;
-
-%% No errors to set or errors explicitly ignored.
-reset(#diameter_packet{errors = Es} = Pkt, _, _)
- when Es == [];
- Es == false ->
- Pkt;
-
-%% Otherwise possibly set Result-Code and/or Failed-AVP.
-reset(#diameter_packet{msg = Msg, errors = Es} = Pkt, Dict, Dict0) ->
- {RC, Failed} = select_error(Msg, Es, Dict0),
- Pkt#diameter_packet{msg = reset(Msg, Dict, RC, Failed)}.
+is_loop(Code, Vid, OH, Avps) ->
+ is_loop(Code, Vid, list_to_binary(OH), Avps).
%% select_error/3
%%
%% Extract the first appropriate RC or {RC, #diameter_avp{}}
-%% pair from an errors list, and accumulate all #diameter_avp{}.
+%% pair from an errors list, along with any leading #diameter_avp{}.
%%
%% RFC 6733:
%%
@@ -762,95 +734,138 @@ reset(#diameter_packet{msg = Msg, errors = Es} = Pkt, Dict, Dict0) ->
%% indicated by the Result-Code AVP. For practical purposes, this
%% Failed-AVP would typically refer to the first AVP processing error
%% that a Diameter node encounters.
+%%
+%% 3xxx can only be set in an answer setting the E-bit. RFC 6733 also
+%% allows 5xxx, RFC 3588 doesn't.
-select_error(Msg, Es, Dict0) ->
- {RC, Avps} = lists:foldl(fun(T,A) -> select(T, A, Dict0) end,
- {is_answer_message(Msg, Dict0), []},
- Es),
- {RC, lists:reverse(Avps)}.
+select_error(E, Es, Dict0) ->
+ select(E, Es, Dict0, []).
-%% Only integer() and {integer(), #diameter_avp{}} are the result of
-%% decode. #diameter_avp{} can only be set in a reply for encode.
+%% select/4
-select(#diameter_avp{} = A, {RC, As}, _) ->
- {RC, [A|As]};
+select(E, [{RC, _} = T | Es], Dict0, Avps) ->
+ select(E, RC, T, Es, Dict0, Avps);
-select(_, {RC, _} = Acc, _)
- when is_integer(RC) ->
- Acc;
+select(E, [#diameter_avp{} = A | Es], Dict0, Avps) ->
+ select(E, Es, Dict0, [A | Avps]);
-select({RC, #diameter_avp{} = A}, {IsAns, As} = Acc, Dict0)
- when is_integer(RC) ->
- case is_result(RC, IsAns, Dict0) of
- true -> {RC, [A|As]};
- false -> Acc
- end;
+select(E, [RC | Es], Dict0, Avps) ->
+ select(E, RC, RC, Es, Dict0, Avps);
-select(RC, {IsAns, As} = Acc, Dict0)
- when is_boolean(IsAns), is_integer(RC) ->
- case is_result(RC, IsAns, Dict0) of
- true -> {RC, As};
- false -> Acc
- end.
+select(_, [], _, Avps) ->
+ Avps.
-%% reset/4
+%% select/6
+
+select(E, RC, T, _, Dict0, Avps)
+ when E, 3000 =< RC, RC < 4000; %% E-bit with 3xxx
+ E, ?BASE /= Dict0, 5000 =< RC, RC < 6000; %% E-bit with 5xxx
+ not E, RC < 3000 orelse 4000 =< RC -> %% no E-bit
+ [T | Avps];
-reset(Msg, Dict, RC, Avps) ->
- FailedAVP = failed_avp(Msg, Avps, Dict),
- ResultCode = rc(Msg, RC, Dict),
- set(set(Msg, FailedAVP, Dict), ResultCode, Dict).
+select(E, _, _, Es, Dict0, Avps) ->
+ select(E, Es, Dict0, Avps).
%% eval_packet/2
eval_packet(Pkt, Fs) ->
lists:foreach(fun(F) -> diameter_lib:eval([F,Pkt]) end, Fs).
-%% make_answer_packet/2
+%% make_answer_packet/4
%% Use decode errors to set Result-Code and/or Failed-AVP unless the
%% the errors field has been explicitly set. Unfortunately, the
%% default value is the empty list rather than 'undefined' so use the
%% atom 'false' for "set nothing". (This is historical and changing
-%% the default value would require modules including diameter.hrl to
-%% be recompiled.)
-make_answer_packet(#diameter_packet{errors = []}
- = Pkt,
- #diameter_packet{errors = [_|_] = Es}
- = ReqPkt) ->
- make_answer_packet(Pkt#diameter_packet{errors = Es}, ReqPkt);
+%% the default value would impact anyone expecting relying on the old
+%% default.)
-%% A reply message clears the R and T flags and retains the P flag.
-%% The E flag will be set at encode. 6.2 of 3588 requires the same P
-%% flag on an answer as on the request. A #diameter_packet{} returned
-%% from a handle_request callback can circumvent this by setting its
-%% own header values.
make_answer_packet(#diameter_packet{header = Hdr,
msg = Msg,
errors = Es,
transport_data = TD},
- #diameter_packet{header = ReqHdr}) ->
- Hdr0 = ReqHdr#diameter_header{version = ?DIAMETER_VERSION,
- is_request = false,
- is_error = undefined,
- is_retransmitted = false},
- #diameter_packet{header = fold_record(Hdr0, Hdr),
- msg = Msg,
- errors = Es,
+ #diameter_packet{header = Hdr0,
+ errors = Es0},
+ MsgDict,
+ Dict0) ->
+ #diameter_packet{header = make_answer_header(Hdr0, Hdr),
+ msg = reset(Msg, Es0, Es, MsgDict, Dict0),
transport_data = TD};
%% Binaries and header/avp lists are sent as-is.
-make_answer_packet(Bin, #diameter_packet{transport_data = TD})
+make_answer_packet(Bin, #diameter_packet{transport_data = TD}, _, _)
when is_binary(Bin) ->
#diameter_packet{bin = Bin,
transport_data = TD};
make_answer_packet([#diameter_header{} | _] = Msg,
- #diameter_packet{transport_data = TD}) ->
+ #diameter_packet{transport_data = TD},
+ _,
+ _) ->
#diameter_packet{msg = Msg,
transport_data = TD};
-%% Otherwise, preserve transport_data.
-make_answer_packet(Msg, #diameter_packet{transport_data = TD} = Pkt) ->
- make_answer_packet(#diameter_packet{msg = Msg, transport_data = TD}, Pkt).
+make_answer_packet(Msg,
+ #diameter_packet{header = Hdr,
+ errors = Es,
+ transport_data = TD},
+ MsgDict,
+ Dict0) ->
+ #diameter_packet{header = make_answer_header(Hdr, undefined),
+ msg = reset(Msg, [], Es, MsgDict, Dict0),
+ transport_data = TD}.
+
+%% make_answer_header/2
+
+%% A reply message clears the R and T flags and retains the P flag.
+%% The E flag will be set at encode. 6.2 of 3588 requires the same P
+%% flag on an answer as on the request. A #diameter_packet{} returned
+%% from a handle_request callback can circumvent this by setting its
+%% own header values.
+make_answer_header(ReqHdr, Hdr) ->
+ Hdr0 = ReqHdr#diameter_header{version = ?DIAMETER_VERSION,
+ is_request = false,
+ is_error = undefined,
+ is_retransmitted = false},
+ fold_record(Hdr0, Hdr).
+
+%% reset/5
+
+reset(Msg, [_|_] = Es0, [] = Es, MsgDict, Dict0) ->
+ reset(Msg, Es, Es0, MsgDict, Dict0);
+
+reset(Msg, _, Es, _, _)
+ when Es == false;
+ Es == [] ->
+ Msg;
+
+reset(Msg, _, Es, MsgDict, Dict0) ->
+ E = is_answer_message(Msg, Dict0),
+ reset(Msg, select_error(E, Es, Dict0), choose(E, Dict0, MsgDict)).
+
+%% reset/4
+%%
+%% Set Result-Code and/or Failed-AVP (maybe). Only RC and {RC, AVP}
+%% are the result of decode. AVP or {RC, [AVP]} can be set in an
+%% answer for encode, as a convenience for injecting additional AVPs
+%% into Failed-AVP; eg. 5001 = DIAMETER_AVP_UNSUPPORTED.
+
+reset(Msg, [], _) ->
+ Msg;
+
+reset(Msg, [{RC, As} | Avps], Dict)
+ when is_list(As) ->
+ reset(Msg, [RC | As ++ Avps], Dict);
+
+reset(Msg, [{RC, Avp} | Avps], Dict) ->
+ reset(Msg, [RC, Avp | Avps], Dict);
+
+reset(Msg, [#diameter_avp{} | _] = Avps, Dict) ->
+ set(Msg, failed_avp(Msg, Avps, Dict), Dict);
+
+reset(Msg, [RC | Avps], Dict) ->
+ set(Msg, rc(Msg, RC, Dict) ++ failed_avp(Msg, Avps, Dict), Dict).
+
+%% set/3
%% Reply as name and tuple list ...
set([_|_] = Ans, Avps, _) ->
@@ -864,11 +879,7 @@ set(Rec, Avps, Dict) ->
%%
%% Turn the result code into a list if its optional and only set it if
%% the arity is 1 or {0,1}. In other cases (which probably shouldn't
-%% exist in practise) we can't know what's appropriate.
-
-rc(_, B, _)
- when is_boolean(B) ->
- [];
+%% exist in practice) we can't know what's appropriate.
rc([MsgName | _], RC, Dict) ->
K = 'Result-Code',
@@ -886,8 +897,8 @@ rc(Rec, RC, Dict) ->
failed_avp(_, [] = No, _) ->
No;
-failed_avp(Rec, Avps, Dict) ->
- [failed(Rec, [{'AVP', Avps}], Dict)].
+failed_avp(Msg, [_|_] = Avps, Dict) ->
+ [failed(Msg, [{'AVP', Avps}], Dict)].
%% Reply as name and tuple list ...
failed([MsgName | Values], FailedAvp, Dict) ->
@@ -911,7 +922,7 @@ failed(Rec, FailedAvp, Dict) ->
{'Failed-AVP', [FailedAvp]}
catch
error: _ ->
- Avps = Dict:'get-'('AVP', Rec),
+ Avps = Dict:'#get-'('AVP', Rec),
A = #diameter_avp{name = 'Failed-AVP',
value = FailedAvp},
{'AVP', [A|Avps]}
@@ -984,22 +995,26 @@ failed(Rec, FailedAvp, Dict) ->
%% Error-Message AVP is not intended to be useful in real-time, and
%% SHOULD NOT be expected to be parsed by network entities.
-%% answer_message/5
+%% answer_message/4
-answer_message(OH, OR, RC, Dict0, #diameter_packet{avps = Avps,
- errors = Es}) ->
+answer_message(RC,
+ Dict0,
+ #diameter_caps{origin_host = {OH,_},
+ origin_realm = {OR,_}},
+ #diameter_packet{avps = Avps,
+ errors = Es}) ->
{Code, _, Vid} = Dict0:avp_header('Session-Id'),
['answer-message', {'Origin-Host', OH},
{'Origin-Realm', OR},
{'Result-Code', RC}]
- ++ session_id(Code, Vid, Dict0, Avps)
+ ++ session_id(Code, Vid, Avps)
++ failed_avp(RC, Es).
-session_id(Code, Vid, Dict0, Avps)
+session_id(Code, Vid, Avps)
when is_list(Avps) ->
try
#diameter_avp{data = Bin} = find_avp(Code, Vid, Avps),
- [{'Session-Id', [Dict0:avp(decode, Bin, 'Session-Id')]}]
+ [{'Session-Id', [Bin]}]
catch
error: _ ->
[]
@@ -1219,8 +1234,6 @@ get_result(Dict, Msg) ->
try
[throw(A) || N <- ['Result-Code', 'Experimental-Result'],
#diameter_avp{} = A <- [get_avp(Dict, N, Msg)]]
- of
- [] -> false
catch
#diameter_avp{} = A -> A
end.
@@ -1229,7 +1242,7 @@ x(T) ->
exit(T).
%% ---------------------------------------------------------------------------
-%% # send_request/4
+%% send_request/4
%%
%% Handle an outgoing Diameter request.
%% ---------------------------------------------------------------------------
@@ -1282,11 +1295,10 @@ answer_rc(_, _, Sent) ->
%%
%% In the process spawned for the outgoing request.
-send_R(SvcName, AppOrAlias, Msg, Opts, Caller) ->
- case pick_peer(SvcName, AppOrAlias, Msg, Opts) of
- {Transport, Mask, SvcOpts} ->
- diameter_codec:setopts(SvcOpts),
- send_request(Transport, Mask, Msg, Opts, Caller, SvcName);
+send_R(SvcName, AppOrAlias, Msg, CallOpts, Caller) ->
+ case pick_peer(SvcName, AppOrAlias, Msg, CallOpts) of
+ {{_,_} = Transport, SvcOpts} ->
+ send_request(Transport, SvcOpts, Msg, CallOpts, Caller, SvcName);
{error, _} = No ->
No
end.
@@ -1294,31 +1306,45 @@ send_R(SvcName, AppOrAlias, Msg, Opts, Caller) ->
%% make_options/1
make_options(Options) ->
- lists:foldl(fun mo/2, #options{}, Options).
-
-mo({timeout, T}, Rec)
- when is_integer(T), 0 =< T ->
- Rec#options{timeout = T};
-
-mo({filter, F}, #options{filter = none} = Rec) ->
- Rec#options{filter = F};
-mo({filter, F}, #options{filter = {all, Fs}} = Rec) ->
- Rec#options{filter = {all, [F | Fs]}};
-mo({filter, F}, #options{filter = F0} = Rec) ->
- Rec#options{filter = {all, [F0, F]}};
-
-mo({extra, L}, #options{extra = X} = Rec)
+ make_opts(Options, [], false, [], none, 5000).
+
+%% Do our own recursion since this is faster than a lists:foldl/3
+%% setting elements in an #options{} accumulator.
+
+make_opts([], Peers, Detach, Extra, Filter, Tmo) ->
+ #options{peers = lists:reverse(Peers),
+ detach = Detach,
+ extra = Extra,
+ filter = Filter,
+ timeout = Tmo};
+
+make_opts([{timeout, Tmo} | Rest], Peers, Detach, Extra, Filter, _)
+ when is_integer(Tmo), 0 =< Tmo ->
+ make_opts(Rest, Peers, Detach, Extra, Filter, Tmo);
+
+make_opts([{filter, F} | Rest], Peers, Detach, Extra, none, Tmo) ->
+ make_opts(Rest, Peers, Detach, Extra, F, Tmo);
+make_opts([{filter, F} | Rest], Peers, Detach, Extra, {all, Fs}, Tmo) ->
+ make_opts(Rest, Peers, Detach, Extra, {all, [F|Fs]}, Tmo);
+make_opts([{filter, F} | Rest], Peers, Detach, Extra, F0, Tmo) ->
+ make_opts(Rest, Peers, Detach, Extra, {all, [F0, F]}, Tmo);
+
+make_opts([{extra, L} | Rest], Peers, Detach, Extra, Filter, Tmo)
when is_list(L) ->
- Rec#options{extra = X ++ L};
+ make_opts(Rest, Peers, Detach, Extra ++ L, Filter, Tmo);
+
+make_opts([detach | Rest], Peers, _, Extra, Filter, Tmo) ->
+ make_opts(Rest, Peers, true, Extra, Filter, Tmo);
-mo(detach, Rec) ->
- Rec#options{detach = true};
+make_opts([{peer, TPid} | Rest], Peers, Detach, Extra, Filter, Tmo)
+ when is_pid(TPid) ->
+ make_opts(Rest, [TPid | Peers], Detach, Extra, Filter, Tmo);
-mo(T, _) ->
+make_opts([T | _], _, _, _, _, _) ->
?ERROR({invalid_option, T}).
%% ---------------------------------------------------------------------------
-%% # send_request/6
+%% send_request/6
%% ---------------------------------------------------------------------------
%% Send an outgoing request in its dedicated process.
@@ -1331,44 +1357,51 @@ mo(T, _) ->
%% The module field of the #diameter_app{} here includes any extra
%% arguments passed to diameter:call/4.
-send_request({TPid, Caps, App}
+send_request({{TPid, _Caps} = TC, App}
= Transport,
- Mask,
- Msg,
- Opts,
+ #{sequence := Mask}
+ = SvcOpts,
+ Msg0,
+ CallOpts,
Caller,
SvcName) ->
- Pkt = make_prepare_packet(Mask, Msg),
-
- send_R(cb(App, prepare_request, [Pkt, SvcName, {TPid, Caps}]),
- Pkt,
- Transport,
- Opts,
- Caller,
- SvcName,
- []).
+ Pkt = make_prepare_packet(Mask, Msg0),
+
+ case prepare(cb(App, prepare_request, [Pkt, SvcName, TC]), []) of
+ [Msg | Fs] ->
+ ReqPkt = make_request_packet(Msg, Pkt),
+ EncPkt = encode(App#diameter_app.dictionary,
+ TPid,
+ SvcOpts,
+ ReqPkt),
+ eval_packet(EncPkt, Fs),
+ T = send_R(ReqPkt, EncPkt, Transport, CallOpts, Caller, SvcName),
+ Ans = recv_answer(SvcName, App, CallOpts, T),
+ handle_answer(SvcName, SvcOpts, App, Ans);
+ {discard, Reason} ->
+ {error, Reason};
+ discard ->
+ {error, discarded};
+ {error, Reason} ->
+ ?ERROR({invalid_return, Reason, prepare_request, App})
+ end.
-%% send_R/7
+%% prepare/2
-send_R({send, Msg}, Pkt, Transport, Opts, Caller, SvcName, Fs) ->
- send_R(make_request_packet(Msg, Pkt),
- Transport,
- Opts,
- Caller,
- SvcName,
- Fs);
+prepare({send, Msg}, Fs) ->
+ [Msg | Fs];
-send_R({discard, Reason} , _, _, _, _, _, _) ->
- {error, Reason};
+prepare({eval_packet, RC, F}, Fs) ->
+ prepare(RC, [F|Fs]);
-send_R(discard, _, _, _, _, _, _) ->
- {error, discarded};
+prepare({discard, _Reason} = RC, _) ->
+ RC;
-send_R({eval_packet, RC, F}, Pkt, T, Opts, Caller, SvcName, Fs) ->
- send_R(RC, Pkt, T, Opts, Caller, SvcName, [F|Fs]);
+prepare(discard = RC, _) ->
+ RC;
-send_R(E, _, {_, _, App}, _, _, _, _) ->
- ?ERROR({invalid_return, E, prepare_request, App}).
+prepare(Reason, _) ->
+ {error, Reason}.
%% make_prepare_packet/2
%%
@@ -1388,43 +1421,39 @@ make_prepare_packet(Mask, #diameter_packet{msg = [#diameter_header{} = Hdr
make_prepare_packet(Mask, #diameter_packet{header = Hdr} = Pkt) ->
Pkt#diameter_packet{header = make_prepare_header(Mask, Hdr)};
+make_prepare_packet(Mask, [#diameter_header{} = Hdr | Avps]) ->
+ #diameter_packet{msg = [make_prepare_header(Mask, Hdr) | Avps]};
+
make_prepare_packet(Mask, Msg) ->
- make_prepare_packet(Mask, #diameter_packet{msg = Msg}).
+ #diameter_packet{header = make_prepare_header(Mask, undefined),
+ msg = Msg}.
%% make_prepare_header/2
make_prepare_header(Mask, undefined) ->
Seq = diameter_session:sequence(Mask),
- make_prepare_header(#diameter_header{end_to_end_id = Seq,
- hop_by_hop_id = Seq});
-
-make_prepare_header(Mask, #diameter_header{end_to_end_id = undefined,
- hop_by_hop_id = undefined}
- = H) ->
- Seq = diameter_session:sequence(Mask),
- make_prepare_header(H#diameter_header{end_to_end_id = Seq,
- hop_by_hop_id = Seq});
-
-make_prepare_header(Mask, #diameter_header{end_to_end_id = undefined} = H) ->
- Seq = diameter_session:sequence(Mask),
- make_prepare_header(H#diameter_header{end_to_end_id = Seq});
-
-make_prepare_header(Mask, #diameter_header{hop_by_hop_id = undefined} = H) ->
- Seq = diameter_session:sequence(Mask),
- make_prepare_header(H#diameter_header{hop_by_hop_id = Seq});
-
-make_prepare_header(_, Hdr) ->
- make_prepare_header(Hdr).
-
-%% make_prepare_header/1
-
-make_prepare_header(#diameter_header{version = undefined} = Hdr) ->
- make_prepare_header(Hdr#diameter_header{version = ?DIAMETER_VERSION});
-
-make_prepare_header(#diameter_header{} = Hdr) ->
- Hdr;
-
-make_prepare_header(T) ->
+ #diameter_header{version = ?DIAMETER_VERSION,
+ end_to_end_id = Seq,
+ hop_by_hop_id = Seq};
+
+make_prepare_header(Mask, #diameter_header{version = V,
+ end_to_end_id = EI,
+ hop_by_hop_id = HI}
+ = H)
+ when EI == undefined;
+ HI == undefined ->
+ Id = diameter_session:sequence(Mask),
+ H#diameter_header{version = ?DEFAULT(V, ?DIAMETER_VERSION),
+ end_to_end_id = ?DEFAULT(EI, Id),
+ hop_by_hop_id = ?DEFAULT(HI, Id)};
+
+make_prepare_header(_, #diameter_header{version = undefined} = H) ->
+ H#diameter_header{version = ?DIAMETER_VERSION};
+
+make_prepare_header(_, #diameter_header{} = H) ->
+ H;
+
+make_prepare_header(_, T) ->
?ERROR({invalid_header, T}).
%% make_request_packet/2
@@ -1452,7 +1481,7 @@ make_request_packet(#diameter_packet{header = Hdr} = Pkt,
make_request_packet(Msg, Pkt) ->
Pkt#diameter_packet{msg = Msg}.
-%% make_retransmit_packet/2
+%% make_retransmit_packet/1
make_retransmit_packet(#diameter_packet{msg = [#diameter_header{} = Hdr
| Avps]}
@@ -1468,136 +1497,139 @@ make_retransmit_header(Hdr) ->
Hdr#diameter_header{is_retransmitted = true}.
%% fold_record/2
+%%
+%% Replace elements in the first record by those in the second that
+%% differ from undefined.
-fold_record(undefined, R) ->
- R;
-fold_record(Rec, R) ->
- diameter_lib:fold_tuple(2, Rec, R).
+fold_record(Rec0, undefined) ->
+ Rec0;
+fold_record(Rec0, Rec) ->
+ list_to_tuple(fold(tuple_to_list(Rec0), tuple_to_list(Rec))).
+
+fold([], []) ->
+ [];
+fold([H | T0], [undefined | T]) ->
+ [H | fold(T0, T)];
+fold([_ | T0], [H | T]) ->
+ [H | fold(T0, T)].
%% send_R/6
-send_R(Pkt0,
- {TPid, Caps, #diameter_app{dictionary = AppDict} = App},
- Opts,
+send_R(ReqPkt,
+ EncPkt,
+ {{TPid, _Caps} = TC, #diameter_app{dictionary = AppDict}},
+ #options{timeout = Timeout},
{Pid, Ref},
- SvcName,
- Fs) ->
- Pkt = encode(AppDict, TPid, Pkt0, Fs),
-
- #options{timeout = Timeout}
- = Opts,
-
+ SvcName) ->
Req = #request{ref = Ref,
caller = Pid,
handler = self(),
- transport = TPid,
- caps = Caps,
- packet = Pkt0},
+ peer = TC,
+ packet = ReqPkt},
- incr(send, Pkt, TPid, AppDict),
- TRef = send_request(TPid, Pkt, Req, SvcName, Timeout),
+ incr(send, EncPkt, TPid, AppDict),
+ {TRef, MRef} = zend_requezt(TPid, EncPkt, Req, SvcName, Timeout),
Pid ! Ref, %% tell caller a send has been attempted
- handle_answer(SvcName,
- App,
- recv_A(Timeout, SvcName, App, Opts, {TRef, Req})).
+ {TRef, MRef, Req}.
-%% recv_A/5
+%% recv_answer/4
-recv_A(Timeout, SvcName, App, Opts, {TRef, #request{ref = Ref} = Req}) ->
+recv_answer(SvcName, App, CallOpts, {TRef, MRef, #request{ref = Ref}
+ = Req}) ->
%% Matching on TRef below ensures we ignore messages that pertain
%% to a previous transport prior to failover. The answer message
- %% includes the #request{} since it's not necessarily Req; that
- %% is, from the last peer to which we've transmitted.
+ %% includes the pid of the transport on which it was received,
+ %% which may not be the last peer to which we've transmitted.
receive
- {answer = A, Ref, Rq, Dict0, Pkt} -> %% Answer from peer
- {A, Rq, Dict0, Pkt};
+ {answer = A, Ref, TPid, Dict0, Pkt} -> %% Answer from peer
+ {A, #request{} = erase(TPid), Dict0, Pkt};
{timeout = Reason, TRef, _} -> %% No timely reply
{error, Req, Reason};
- {failover, TRef} -> %% Service says peer has gone down
- retransmit(pick_peer(SvcName, App, Req, Opts),
- Req,
- Opts,
- SvcName,
- Timeout)
+ {'DOWN', MRef, process, _, _} when false /= MRef -> %% local peer_down
+ failover(SvcName, App, Req, CallOpts);
+ {failover, TRef} -> %% local or remote peer_down
+ failover(SvcName, App, Req, CallOpts)
end.
-%% handle_answer/3
+%% failover/4
+
+failover(SvcName, App, Req, CallOpts) ->
+ resend_request(pick_peer(SvcName, App, Req, CallOpts),
+ Req,
+ CallOpts,
+ SvcName).
-handle_answer(SvcName, App, {error, Req, Reason}) ->
- handle_error(App, Req, Reason, SvcName);
+%% handle_answer/4
+
+handle_answer(SvcName, _, App, {error, Req, Reason}) ->
+ #request{packet = Pkt,
+ peer = {_TPid, _Caps} = TC}
+ = Req,
+ cb(App, handle_error, [Reason, msg(Pkt), SvcName, TC]);
handle_answer(SvcName,
- #diameter_app{dictionary = AppDict,
- id = Id}
+ SvcOpts,
+ #diameter_app{id = Id,
+ dictionary = AppDict,
+ options = [{answer_errors, AE} | _]}
= App,
{answer, Req, Dict0, Pkt}) ->
MsgDict = msg_dict(AppDict, Dict0, Pkt),
- handle_A(errors(Id, diameter_codec:decode({MsgDict, AppDict}, Pkt)),
- SvcName,
- MsgDict,
- Dict0,
- App,
- Req).
-
-%% We don't really need to do a full decode if we're a relay and will
-%% just resend with a new hop by hop identifier, but might a proxy
-%% want to examine the answer?
-
-handle_A(Pkt, SvcName, Dict, Dict0, App, #request{transport = TPid} = Req) ->
- AppDict = App#diameter_app.dictionary,
-
- incr(recv, Pkt, TPid, AppDict),
-
- try
- incr_result(recv, Pkt, TPid, {Dict, AppDict, Dict0}) %% count incoming
- of
- _ -> answer(Pkt, SvcName, App, Req)
- catch
- exit: {no_result_code, _} ->
- %% RFC 6733 requires one of Result-Code or
- %% Experimental-Result, but the decode will have detected
- %% a missing AVP. If both are optional in the dictionary
- %% then this isn't a decode error: just continue on.
- answer(Pkt, SvcName, App, Req);
- exit: {invalid_error_bit, {_, _, _, Avp}} ->
- #diameter_packet{errors = Es}
- = Pkt,
- E = {5004, Avp},
- answer(Pkt#diameter_packet{errors = [E|Es]}, SvcName, App, Req)
- end.
+ DecPkt = errors(Id, diameter_codec:decode({MsgDict, AppDict},
+ SvcOpts,
+ Pkt)),
+ #request{peer = {TPid, _}}
+ = Req,
-%% answer/4
-
-answer(Pkt,
- SvcName,
- #diameter_app{module = ModX,
- options = [{answer_errors, AE} | _]},
- Req) ->
- a(Pkt, SvcName, ModX, AE, Req).
-
--spec a(_, _, _) -> no_return(). %% silence dialyzer
-
-a(#diameter_packet{errors = Es}
- = Pkt,
- SvcName,
- ModX,
- AE,
- #request{transport = TPid,
- caps = Caps,
- packet = P})
- when [] == Es;
- callback == AE ->
- cb(ModX, handle_answer, [Pkt, msg(P), SvcName, {TPid, Caps}]);
-
-a(Pkt, SvcName, _, AE, _) ->
- a(Pkt#diameter_packet.header, SvcName, AE).
-
-a(Hdr, SvcName, report) ->
+ incr(recv, DecPkt, TPid, AppDict),
+
+ AnsPkt = try
+ incr_result(recv, DecPkt, TPid, {MsgDict, AppDict, Dict0})
+ of
+ _ -> DecPkt
+ catch
+ exit: {no_result_code, _} ->
+ %% RFC 6733 requires one of Result-Code or
+ %% Experimental-Result, but the decode will have
+ %% detected a missing AVP. If both are optional in
+ %% the dictionary then this isn't a decode error:
+ %% just continue on.
+ DecPkt;
+ exit: {invalid_error_bit, {_, _, _, Avp}} ->
+ #diameter_packet{errors = Es}
+ = DecPkt,
+ E = {5004, Avp},
+ DecPkt#diameter_packet{errors = [E|Es]}
+ end,
+
+ handle_answer(AnsPkt, SvcName, App, AE, Req).
+
+%% handle_answer/5
+
+handle_answer(#diameter_packet{errors = Es}
+ = Pkt,
+ SvcName,
+ App,
+ AE,
+ #request{peer = {_TPid, _Caps} = TC,
+ packet = P})
+ when callback == AE;
+ [] == Es ->
+ cb(App, handle_answer, [Pkt, msg(P), SvcName, TC]);
+
+handle_answer(#diameter_packet{header = H}, SvcName, _, AE, _) ->
+ handle_error(H, SvcName, AE).
+
+%% handle_error/3
+
+-spec handle_error(_, _, _) -> no_return(). %% silence dialyzer
+
+handle_error(Hdr, SvcName, report) ->
MFA = {?MODULE, handle_answer, [SvcName, Hdr]},
diameter_lib:warning_report(errors, MFA),
- a(Hdr, SvcName, discard);
+ handle_error(Hdr, SvcName, discard);
-a(Hdr, SvcName, discard) ->
+handle_error(Hdr, SvcName, discard) ->
x({answer_errors, {SvcName, Hdr}}).
%% Note that we don't check that the application id in the answer's
@@ -1608,16 +1640,38 @@ a(Hdr, SvcName, discard) ->
%% timer value is ignored. This means that an answer could be accepted
%% from a peer after timeout in the case of failover.
-%% retransmit/5
+%% resend_request/4
-retransmit({{_,_,App} = Transport, _, _}, Req, Opts, SvcName, Timeout) ->
- try retransmit(Transport, Req, SvcName, Timeout) of
- T -> recv_A(Timeout, SvcName, App, Opts, T)
- catch
- ?FAILURE(Reason) -> {error, Req, Reason}
+resend_request({{{TPid, _Caps} = TC, App}, SvcOpts},
+ Req0,
+ #options{timeout = Timeout}
+ = CallOpts,
+ SvcName) ->
+ case
+ undefined == get(TPid)
+ andalso prepare_retransmit(TC, App, Req0, SvcName)
+ of
+ [ReqPkt | Fs] ->
+ AppDict = App#diameter_app.dictionary,
+ EncPkt = encode(AppDict, TPid, SvcOpts, ReqPkt),
+ eval_packet(EncPkt, Fs),
+ Req = Req0#request{peer = TC,
+ packet = ReqPkt},
+ ?LOG(retransmission, EncPkt#diameter_packet.header),
+ incr(TPid, {msg_id(EncPkt, AppDict), send, retransmission}),
+ {TRef, MRef} = zend_requezt(TPid, EncPkt, Req, SvcName, Timeout),
+ recv_answer(SvcName, App, CallOpts, {TRef, MRef, Req});
+ false ->
+ {error, Req0, timeout};
+ {discard, Reason} ->
+ {error, Req0, Reason};
+ discard ->
+ {error, Req0, discarded};
+ {error, T} ->
+ ?ERROR({invalid_return, T, prepare_retransmit, App})
end;
-retransmit(_, Req, _, _, _) -> %% no alternate peer
+resend_request(_, Req, _, _) -> %% no alternate peer
{error, Req, failover}.
%% pick_peer/4
@@ -1627,8 +1681,8 @@ retransmit(_, Req, _, _, _) -> %% no alternate peer
pick_peer(SvcName,
App,
#request{packet = #diameter_packet{msg = Msg}},
- Opts) ->
- pick_peer(SvcName, App, Msg, Opts#options{extra = []});
+ CallOpts) ->
+ pick_peer(SvcName, App, Msg, CallOpts#options{extra = []});
pick_peer(_, _, undefined, _) ->
{error, no_connection};
@@ -1636,28 +1690,14 @@ pick_peer(_, _, undefined, _) ->
pick_peer(SvcName,
AppOrAlias,
Msg,
- #options{filter = Filter, extra = Xtra}) ->
- pick(diameter_service:pick_peer(SvcName,
- AppOrAlias,
- {fun(D) -> get_destination(D, Msg) end,
- Filter,
- Xtra})).
-
-pick(false) ->
- {error, no_connection};
-
-pick(T) ->
- T.
-
-%% handle_error/4
-
-handle_error(App,
- #request{packet = Pkt,
- transport = TPid,
- caps = Caps},
- Reason,
- SvcName) ->
- cb(App, handle_error, [Reason, msg(Pkt), SvcName, {TPid, Caps}]).
+ #options{peers = TPids, filter = Filter, extra = Xtra}) ->
+ X = {fun(D) -> get_destination(D, Msg) end, Filter, Xtra, TPids},
+ case diameter_service:pick_peer(SvcName, AppOrAlias, X) of
+ false ->
+ {error, no_connection};
+ T ->
+ T
+ end.
msg(#diameter_packet{msg = undefined, bin = Bin}) ->
Bin;
@@ -1666,27 +1706,20 @@ msg(#diameter_packet{msg = Msg}) ->
%% encode/4
-encode(Dict, TPid, Pkt, Fs) ->
- P = encode(Dict, TPid, Pkt),
- eval_packet(P, Fs),
- P.
-
-%% encode/2
-
%% Note that prepare_request can return a diameter_packet containing a
%% header or transport_data. Even allow the returned record to contain
%% an encoded binary. This isn't the usual case and doesn't properly
%% support retransmission but is useful for test.
-encode(Dict, TPid, Pkt)
+encode(Dict, TPid, Opts, Pkt)
when is_atom(Dict) ->
- encode({Dict, Dict}, TPid, Pkt);
+ encode({Dict, Dict}, TPid, Opts, Pkt);
%% A message to be encoded.
-encode(DictT, TPid, #diameter_packet{bin = undefined} = Pkt) ->
+encode(DictT, TPid, Opts, #diameter_packet{bin = undefined} = Pkt) ->
{Dict, AppDict} = DictT,
try
- diameter_codec:encode(Dict, Pkt)
+ diameter_codec:encode(Dict, Opts, Pkt)
catch
exit: {diameter_codec, encode, T} = Reason ->
incr_error(send, T, TPid, AppDict),
@@ -1694,198 +1727,103 @@ encode(DictT, TPid, #diameter_packet{bin = undefined} = Pkt) ->
end;
%% An encoded binary: just send.
-encode(_, _, #diameter_packet{} = Pkt) ->
+encode(_, _, _, #diameter_packet{} = Pkt) ->
Pkt.
+%% zend_requezt/5
+%%
+%% Strip potentially large record fields that aren't used by the
+%% processes the records can be send to, possibly on a remote node.
+
+zend_requezt(TPid, Pkt, Req, SvcName, Timeout) ->
+ put(TPid, Req),
+ send_request(TPid, z(Pkt), Req, SvcName, Timeout).
+
%% send_request/5
send_request(TPid, #diameter_packet{bin = Bin} = Pkt, Req, _SvcName, Timeout)
when node() == node(TPid) ->
Seqs = diameter_codec:sequence_numbers(Bin),
TRef = erlang:start_timer(Timeout, self(), TPid),
- Entry = {Seqs, Req, TRef},
-
- %% Ensure that request table is cleaned even if we receive an exit
- %% signal. An alternative would be to simply trap exits, but
- %% callbacks are applied in this process, and these could possibly
- %% be expecting the prevailing behaviour.
- Self = self(),
- spawn(fun() -> diameter_lib:wait([Self]), erase_request(Entry) end),
-
- store_request(Entry, TPid),
- send(TPid, Pkt),
- TRef;
+ send(TPid, Pkt, _Route = {self(), Req#request.ref, Seqs}),
+ {TRef, _MRef = peer_monitor(TPid, TRef)};
%% Send using a remote transport: spawn a process on the remote node
%% to relay the answer.
send_request(TPid, #diameter_packet{} = Pkt, Req, SvcName, Timeout) ->
TRef = erlang:start_timer(Timeout, self(), TPid),
- T = {TPid, Pkt, Req, SvcName, Timeout, TRef},
+ T = {TPid, Pkt, z(Req), SvcName, Timeout, TRef},
spawn(node(TPid), ?MODULE, send, [T]),
- TRef.
+ {TRef, false}.
+
+%% z/1
+%%
+%% Avoid sending potentially large terms unnecessarily. The records
+%% themselves are retained since they're sent between nodes in send/1
+%% and changing what's sent causes upgrade issues.
+
+z(#request{ref = Ref, handler = Pid}) ->
+ #request{ref = Ref,
+ handler = Pid};
+
+z(#diameter_packet{header = H, bin = Bin, transport_data = T}) ->
+ #diameter_packet{header = H,
+ bin = Bin,
+ transport_data = T}.
%% send/1
send({TPid, Pkt, #request{handler = Pid} = Req0, SvcName, Timeout, TRef}) ->
Req = Req0#request{handler = self()},
- recv(TPid, Pid, TRef, send_request(TPid, Pkt, Req, SvcName, Timeout)).
+ recv(TPid, Pid, TRef, zend_requezt(TPid, Pkt, Req, SvcName, Timeout)).
%% recv/4
%%
%% Relay an answer from a remote node.
-recv(TPid, Pid, TRef, LocalTRef) ->
+recv(TPid, Pid, TRef, {LocalTRef, MRef}) ->
receive
{answer, _, _, _, _} = A ->
Pid ! A;
+ {'DOWN', MRef, process, _, _} ->
+ Pid ! {failover, TRef};
{failover = T, LocalTRef} ->
Pid ! {T, TRef};
T ->
exit({timeout, LocalTRef, TPid} = T)
end.
-%% send/2
+%% send/3
-send(Pid, Pkt) -> %% Strip potentially large message terms.
- #diameter_packet{header = H,
- bin = Bin,
- transport_data = T}
- = Pkt,
- Pid ! {send, #diameter_packet{header = H,
- bin = Bin,
- transport_data = T}}.
-
-%% retransmit/4
-
-retransmit({TPid, Caps, App}
- = Transport,
- #request{packet = Pkt0}
- = Req,
- SvcName,
- Timeout) ->
- have_request(Pkt0, TPid) %% Don't failover to a peer we've
- andalso ?THROW(timeout), %% already sent to.
-
- Pkt = make_retransmit_packet(Pkt0),
-
- retransmit(cb(App, prepare_retransmit, [Pkt, SvcName, {TPid, Caps}]),
- Transport,
- Req#request{packet = Pkt},
- SvcName,
- Timeout,
- []).
+send(Pid, Pkt, Route) ->
+ Pid ! {send, Pkt, Route}.
-retransmit({send, Msg},
- Transport,
- #request{packet = Pkt}
- = Req,
- SvcName,
- Timeout,
- Fs) ->
- resend_request(make_request_packet(Msg, Pkt),
- Transport,
- Req,
- SvcName,
- Timeout,
- Fs);
+%% prepare_retransmit/4
-retransmit({discard, Reason}, _, _, _, _, _) ->
- ?THROW(Reason);
+prepare_retransmit({_TPid, _Caps} = TC, App, Req, SvcName) ->
+ Pkt = make_retransmit_packet(Req#request.packet),
-retransmit(discard, _, _, _, _, _) ->
- ?THROW(discarded);
+ case prepare(cb(App, prepare_retransmit, [Pkt, SvcName, TC]), []) of
+ [Msg | Fs] ->
+ [make_request_packet(Msg, Pkt) | Fs];
+ No ->
+ No
+ end.
-retransmit({eval_packet, RC, F}, Transport, Req, SvcName, Timeout, Fs) ->
- retransmit(RC, Transport, Req, SvcName, Timeout, [F|Fs]);
+%% When sending a binary, it's up to prepare_retransmit to modify it
+%% accordingly.
-retransmit(T, {_, _, App}, _, _, _, _) ->
- ?ERROR({invalid_return, T, prepare_retransmit, App}).
+%% peer_monitor/2
-resend_request(Pkt0,
- {TPid, Caps, #diameter_app{dictionary = AppDict}},
- Req0,
- SvcName,
- Tmo,
- Fs) ->
- Pkt = encode(AppDict, TPid, Pkt0, Fs),
-
- Req = Req0#request{transport = TPid,
- packet = Pkt0,
- caps = Caps},
-
- ?LOG(retransmission, Pkt#diameter_packet.header),
- incr(TPid, {msg_id(Pkt, AppDict), send, retransmission}),
- TRef = send_request(TPid, Pkt, Req, SvcName, Tmo),
- {TRef, Req}.
-
-%% store_request/2
-
-store_request(T, TPid) ->
- ets:insert(?REQUEST_TABLE, T),
- ets:member(?REQUEST_TABLE, TPid)
- orelse begin
- {_Seqs, _Req, TRef} = T,
- self() ! {failover, TRef} %% failover/1 may have missed
- end.
-
-%% lookup_request/2
-%%
-%% Note the match on both the key and transport pid. The latter is
-%% necessary since the same Hop-by-Hop and End-to-End identifiers are
-%% reused in the case of retransmission.
-
-lookup_request(Msg, TPid) ->
- Seqs = diameter_codec:sequence_numbers(Msg),
- Spec = [{{Seqs, #request{transport = TPid, _ = '_'}, '_'},
- [],
- ['$_']}],
- case ets:select(?REQUEST_TABLE, Spec) of
- [{_, Req, _}] ->
- Req;
- [] ->
+peer_monitor(TPid, TRef) ->
+ case ets:lookup(?REQUEST_TABLE, TPid) of %% at peer_up/1
+ [{_, MPid}] ->
+ monitor(process, MPid);
+ [] -> %% transport has gone down
+ self() ! {failover, TRef},
false
end.
-%% erase_request/1
-
-erase_request(T) ->
- ets:delete_object(?REQUEST_TABLE, T).
-
-%% match_requests/1
-
-match_requests(TPid) ->
- Pat = {'_', #request{transport = TPid, _ = '_'}, '_'},
- ets:select(?REQUEST_TABLE, [{Pat, [], ['$_']}]).
-
-%% have_request/2
-
-have_request(Pkt, TPid) ->
- Seqs = diameter_codec:sequence_numbers(Pkt),
- Pat = {Seqs, #request{transport = TPid, _ = '_'}, '_'},
- '$end_of_table' /= ets:select(?REQUEST_TABLE, [{Pat, [], ['$_']}], 1).
-
-%% ---------------------------------------------------------------------------
-%% # failover/1-2
-%% ---------------------------------------------------------------------------
-
-failover(TPid)
- when is_pid(TPid) ->
- lists:foreach(fun failover/1, match_requests(TPid));
-%% Note that a request process can store its request after failover
-%% notifications are sent here: store_request/2 sends the notification
-%% in that case.
-
-%% Failover as a consequence of peer_down/1: inform the
-%% request process.
-failover({_, Req, TRef}) ->
- #request{handler = Pid,
- packet = #diameter_packet{msg = M}}
- = Req,
- M /= undefined andalso (Pid ! {failover, TRef}).
-%% Failover is not performed when msg = binary() since sending
-%% pre-encoded binaries is only partially supported. (Mostly for
-%% test.)
-
%% get_destination/2
get_destination(Dict, Msg) ->
@@ -1974,7 +1912,7 @@ ungroup(Avp) ->
avp_decode(Dict, Name, #diameter_avp{value = undefined,
data = Bin}
= Avp) ->
- try Dict:avp(decode, Bin, Name) of
+ try Dict:avp(decode, Bin, Name, decode_opts(Dict)) of
V ->
Avp#diameter_avp{value = V}
catch
@@ -1985,8 +1923,6 @@ avp_decode(_, _, #diameter_avp{} = Avp) ->
Avp.
cb(#diameter_app{module = [_|_] = M}, F, A) ->
- eval(M, F, A);
-cb([_|_] = M, F, A) ->
eval(M, F, A).
eval([M|X], F, A) ->
@@ -1994,3 +1930,10 @@ eval([M|X], F, A) ->
choose(true, X, _) -> X;
choose(false, _, X) -> X.
+
+%% Decode options sufficient for AVP extraction.
+decode_opts(Dict) ->
+ #{string_decode => false,
+ strict_mbit => false,
+ failed_avp => false,
+ dictionary => Dict}.
diff --git a/lib/diameter/src/base/diameter_types.erl b/lib/diameter/src/base/diameter_types.erl
index 6ecf385239..86b674dd48 100644
--- a/lib/diameter/src/base/diameter_types.erl
+++ b/lib/diameter/src/base/diameter_types.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -26,32 +26,16 @@
%%
%% Basic types.
--export(['OctetString'/2,
- 'Integer32'/2,
- 'Integer64'/2,
- 'Unsigned32'/2,
- 'Unsigned64'/2,
- 'Float32'/2,
- 'Float64'/2]).
-
-%% Derived types.
--export(['Address'/2,
- 'Time'/2,
- 'UTF8String'/2,
- 'DiameterIdentity'/2,
- 'DiameterURI'/2,
- 'IPFilterRule'/2,
- 'QoSFilterRule'/2]).
-
-%% Functions taking the AVP name in question as second parameter.
-export(['OctetString'/3,
'Integer32'/3,
'Integer64'/3,
'Unsigned32'/3,
'Unsigned64'/3,
'Float32'/3,
- 'Float64'/3,
- 'Address'/3,
+ 'Float64'/3]).
+
+%% Derived types.
+-export(['Address'/3,
'Time'/3,
'UTF8String'/3,
'DiameterIdentity'/3,
@@ -89,81 +73,80 @@
%% AVP Data Format is needed, a new version of this RFC must be created.
%% --------------------
-'OctetString'(decode, Bin)
+'OctetString'(decode, Bin, #{string_decode := true})
when is_binary(Bin) ->
- case diameter_codec:getopt(string_decode) of
- true ->
- binary_to_list(Bin);
- false ->
- Bin
- end;
-
-'OctetString'(decode, B) ->
+ binary_to_list(Bin);
+
+'OctetString'(decode, Bin, _)
+ when is_binary(Bin) ->
+ Bin;
+
+'OctetString'(decode, B, _) ->
?INVALID_LENGTH(B);
-'OctetString'(encode = M, zero) ->
- 'OctetString'(M, []);
+'OctetString'(encode, zero, _) ->
+ <<>>;
-'OctetString'(encode, Str) ->
+'OctetString'(encode, Str, _) ->
iolist_to_binary(Str).
%% --------------------
-'Integer32'(decode, <<X:32/signed>>) ->
+'Integer32'(decode, <<X:32/signed>>, _) ->
X;
-'Integer32'(decode, B) ->
+'Integer32'(decode, B, _) ->
?INVALID_LENGTH(B);
-'Integer32'(encode = M, zero) ->
- 'Integer32'(M, 0);
+'Integer32'(encode, zero, _) ->
+ <<0:32/signed>>;
-'Integer32'(encode, I)
+'Integer32'(encode, I, _)
when ?SINT(32,I) ->
<<I:32/signed>>.
%% --------------------
-'Integer64'(decode, <<X:64/signed>>) ->
+'Integer64'(decode, <<X:64/signed>>, _) ->
X;
-'Integer64'(decode, B) ->
+'Integer64'(decode, B, _) ->
?INVALID_LENGTH(B);
-'Integer64'(encode = M, zero) ->
- 'Integer64'(M, 0);
+'Integer64'(encode, zero, _) ->
+ <<0:64/signed>>;
-'Integer64'(encode, I)
+'Integer64'(encode, I, _)
when ?SINT(64,I) ->
<<I:64/signed>>.
%% --------------------
-'Unsigned32'(decode, <<X:32>>) ->
+'Unsigned32'(decode, <<X:32>>, _) ->
X;
-'Unsigned32'(decode, B) ->
+'Unsigned32'(decode, B, _) ->
?INVALID_LENGTH(B);
-'Unsigned32'(encode = M, zero) ->
- 'Unsigned32'(M, 0);
+'Unsigned32'(encode, zero, _) ->
+ <<0:32>>;
-'Unsigned32'(encode, I)
+'Unsigned32'(encode, I, _)
when ?UINT(32,I) ->
<<I:32>>.
%% --------------------
-'Unsigned64'(decode, <<X:64>>) ->
+'Unsigned64'(decode, <<X:64>>, _) ->
X;
-'Unsigned64'(decode, B) ->
+'Unsigned64'(decode, B, _) ->
?INVALID_LENGTH(B);
-'Unsigned64'(encode = M, zero) ->
- 'Unsigned64'(M, 0);
+'Unsigned64'(encode, zero, _) ->
+ <<0:64>>;
-'Unsigned64'(encode, I)
+'Unsigned64'(encode, I, _)
when ?UINT(64,I) ->
<<I:64>>.
@@ -184,25 +167,25 @@
%% arithmetic is performed on the decoded value. Better to be explicit
%% that precision has been lost.
-'Float32'(decode, <<S:1, 255:8, _:23>>) ->
+'Float32'(decode, <<S:1, 255:8, _:23>>, _) ->
choose(S, infinity, '-infinity');
-'Float32'(decode, <<X:32/float>>) ->
+'Float32'(decode, <<X:32/float>>, _) ->
X;
-'Float32'(decode, B) ->
+'Float32'(decode, B, _) ->
?INVALID_LENGTH(B);
-'Float32'(encode = M, zero) ->
- 'Float32'(M, 0.0);
+'Float32'(encode, zero, _) ->
+ <<0.0:32/float>>;
-'Float32'(encode, infinity) ->
+'Float32'(encode, infinity, _) ->
<<0:1, 255:8, 0:23>>;
-'Float32'(encode, '-infinity') ->
+'Float32'(encode, '-infinity', _) ->
<<1:1, 255:8, 0:23>>;
-'Float32'(encode, X)
+'Float32'(encode, X, _)
when is_float(X) ->
<<X:32/float>>.
%% Note that this could also encode infinity/-infinity for large
@@ -222,25 +205,25 @@
%% The 64 bit format is entirely analogous to the 32 bit format.
-'Float64'(decode, <<S:1, 2047:11, _:52>>) ->
+'Float64'(decode, <<S:1, 2047:11, _:52>>, _) ->
choose(S, infinity, '-infinity');
-'Float64'(decode, <<X:64/float>>) ->
+'Float64'(decode, <<X:64/float>>, _) ->
X;
-'Float64'(decode, B) ->
+'Float64'(decode, B, _) ->
?INVALID_LENGTH(B);
-'Float64'(encode, infinity) ->
+'Float64'(encode, infinity, _) ->
<<0:1, 2047:11, 0:52>>;
-'Float64'(encode, '-infinity') ->
+'Float64'(encode, '-infinity', _) ->
<<1:1, 2047:11, 0:52>>;
-'Float64'(encode = M, zero) ->
- 'Float64'(M, 0.0);
+'Float64'(encode, zero, _) ->
+ <<0.0:64/float>>;
-'Float64'(encode, X)
+'Float64'(encode, X, _)
when is_float(X) ->
<<X:64/float>>.
@@ -256,18 +239,18 @@
%% format.
%% --------------------
-'Address'(encode, zero) ->
+'Address'(encode, zero, _) ->
<<0:48>>;
-'Address'(decode, <<A:16, B/binary>>)
+'Address'(decode, <<A:16, B/binary>>, _)
when 1 == A, 4 == size(B);
2 == A, 16 == size(B) ->
list_to_tuple([N || <<N:A/unit:8>> <= B]);
-'Address'(decode, B) ->
+'Address'(decode, B, _) ->
?INVALID_LENGTH(B);
-'Address'(encode, T) ->
+'Address'(encode, T, _) ->
Ns = tuple_to_list(diameter_lib:ipaddr(T)), %% length 4 or 8
A = length(Ns) div 4, %% 1 or 2
B = << <<N:A/unit:8>> || N <- Ns >>,
@@ -278,36 +261,38 @@
%% A DiameterIdentity is a FQDN as definined in RFC 1035, which is at
%% least one character.
-'DiameterIdentity'(encode = M, zero) ->
- 'OctetString'(M, [0]);
+'DiameterIdentity'(encode, zero, _) ->
+ <<0>>;
-'DiameterIdentity'(encode = M, X) ->
- <<_,_/binary>> = 'OctetString'(M, X);
+'DiameterIdentity'(encode = M, X, Opts) ->
+ <<_,_/binary>> = 'OctetString'(M, X, Opts);
-'DiameterIdentity'(decode = M, <<_,_/binary>> = X) ->
- 'OctetString'(M, X);
+'DiameterIdentity'(decode = M, <<_,_/binary>> = X, Opts) ->
+ 'OctetString'(M, X, Opts);
-'DiameterIdentity'(decode, X) ->
+'DiameterIdentity'(decode, X, _) ->
?INVALID_LENGTH(X).
%% --------------------
-'DiameterURI'(decode, Bin)
+'DiameterURI'(decode, Bin, Opts)
when is_binary(Bin) ->
- scan_uri(Bin);
+ scan_uri(Bin, Opts);
-'DiameterURI'(decode, B) ->
+'DiameterURI'(decode, B, _) ->
?INVALID_LENGTH(B);
%% The minimal DiameterURI is "aaa://x", 7 characters.
-'DiameterURI'(encode = M, zero) ->
- 'OctetString'(M, lists:duplicate(0,7));
-
-'DiameterURI'(encode, #diameter_uri{type = Type,
- fqdn = DN,
- port = PN,
- transport = T,
- protocol = P})
+'DiameterURI'(encode, zero, _) ->
+ <<0:7/unit:8>>;
+
+'DiameterURI'(encode,
+ #diameter_uri{type = Type,
+ fqdn = DN,
+ port = PN,
+ transport = T,
+ protocol = P},
+ _)
when (Type == 'aaa' orelse Type == 'aaas'),
is_integer(PN),
0 =< PN,
@@ -324,48 +309,47 @@
%% defaults, so it's best to be explicit. Interpret defaults on decode
%% since there's no choice.
-'DiameterURI'(encode, Str) ->
+'DiameterURI'(encode, Str, Opts) ->
Bin = iolist_to_binary(Str),
- #diameter_uri{} = scan_uri(Bin), %% assert
+ #diameter_uri{} = scan_uri(Bin, Opts), %% assert
Bin.
%% --------------------
%% This minimal rule is "deny in 0 from 0.0.0.0 to 0.0.0.0", 33 characters.
-'IPFilterRule'(encode = M, zero) ->
- 'OctetString'(M, lists:duplicate(0,33));
+'IPFilterRule'(encode, zero, _) ->
+ <<0:33/unit:8>>;
-'IPFilterRule'(M, X) ->
- 'OctetString'(M, X).
+'IPFilterRule'(M, X, Opts) ->
+ 'OctetString'(M, X, Opts).
%% --------------------
%% This minimal rule is the same as for an IPFilterRule.
-'QoSFilterRule'(encode = M, zero = X) ->
- 'IPFilterRule'(M, X);
+'QoSFilterRule'(encode, zero, _) ->
+ <<0:33/unit:8>>;
-'QoSFilterRule'(M, X) ->
- 'OctetString'(M, X).
+'QoSFilterRule'(M, X, Opts) ->
+ 'OctetString'(M, X, Opts).
%% --------------------
-'UTF8String'(decode, Bin)
+'UTF8String'(decode, Bin, #{string_decode := true})
when is_binary(Bin) ->
- case diameter_codec:getopt(string_decode) of
- true ->
- %% assert list return
- tl([0|_] = unicode:characters_to_list([0, Bin]));
- false ->
- <<_/binary>> = unicode:characters_to_binary(Bin)
- end;
-
-'UTF8String'(decode, B) ->
+ %% assert list return
+ tl([0|_] = unicode:characters_to_list([0, Bin]));
+
+'UTF8String'(decode, Bin, _)
+ when is_binary(Bin) ->
+ <<_/binary>> = unicode:characters_to_binary(Bin);
+
+'UTF8String'(decode, B, _) ->
?INVALID_LENGTH(B);
-'UTF8String'(encode = M, zero) ->
- 'UTF8String'(M, []);
+'UTF8String'(encode, zero, _) ->
+ <<>>;
-'UTF8String'(encode, S) ->
+'UTF8String'(encode, S, _) ->
<<_/binary>> = unicode:characters_to_binary(S). %% assert binary return
%% --------------------
@@ -414,67 +398,23 @@
-define(TIME_MIN, {{1968,1,20},{3,14,8}}). %% TIME_1900 + 1 bsl 31
-define(TIME_MAX, {{2104,2,26},{9,42,24}}). %% TIME_2036 + 1 bsl 31
-'Time'(decode, <<Time:32>>) ->
+'Time'(decode, <<Time:32>>, _) ->
Offset = msb(1 == Time bsr 31),
calendar:gregorian_seconds_to_datetime(Time + Offset);
-'Time'(decode, B) ->
+'Time'(decode, B, _) ->
?INVALID_LENGTH(B);
-'Time'(encode, {{_Y,_M,_D},{_HH,_MM,_SS}} = Datetime)
+'Time'(encode, {{_Y,_M,_D},{_HH,_MM,_SS}} = Datetime, _)
when ?TIME_MIN =< Datetime, Datetime < ?TIME_MAX ->
S = calendar:datetime_to_gregorian_seconds(Datetime),
T = S - msb(S < ?TIME_2036),
0 = T bsr 32, %% sanity check
<<T:32>>;
-'Time'(encode, zero) ->
+'Time'(encode, zero, _) ->
<<0:32>>.
-%% -------------------------------------------------------------------------
-
-'OctetString'(M, _, Data) ->
- 'OctetString'(M, Data).
-
-'Integer32'(M, _, Data) ->
- 'Integer32'(M, Data).
-
-'Integer64'(M, _, Data) ->
- 'Integer64'(M, Data).
-
-'Unsigned32'(M, _, Data) ->
- 'Unsigned32'(M, Data).
-
-'Unsigned64'(M, _, Data) ->
- 'Unsigned64'(M, Data).
-
-'Float32'(M, _, Data) ->
- 'Float32'(M, Data).
-
-'Float64'(M, _, Data) ->
- 'Float64'(M, Data).
-
-'Address'(M, _, Data) ->
- 'Address'(M, Data).
-
-'Time'(M, _, Data) ->
- 'Time'(M, Data).
-
-'UTF8String'(M, _, Data) ->
- 'UTF8String'(M, Data).
-
-'DiameterIdentity'(M, _, Data) ->
- 'DiameterIdentity'(M, Data).
-
-'DiameterURI'(M, _, Data) ->
- 'DiameterURI'(M, Data).
-
-'IPFilterRule'(M, _, Data) ->
- 'IPFilterRule'(M, Data).
-
-'QoSFilterRule'(M, _, Data) ->
- 'QoSFilterRule'(M, Data).
-
%% ===========================================================================
%% ===========================================================================
@@ -564,7 +504,7 @@ msb(false) -> ?TIME_2036.
%%
%% aaa-protocol = ( "diameter" / "radius" / "tacacs+" )
-scan_uri(Bin) ->
+scan_uri(Bin, Opts) ->
RE = "^(aaas?)://"
"([-a-zA-Z0-9.]{1,255})"
"(:0{0,5}([0-9]{1,5}))?"
@@ -583,28 +523,30 @@ scan_uri(Bin) ->
RE,
[{capture, [1,2,4,6,8], binary}]),
Type = to_atom(A),
- {PN0, T0} = defaults(diameter_codec:getopt(rfc), Type),
- PortNr = to_int(PN, PN0),
- 0 = PortNr bsr 16, %% assert
#diameter_uri{type = Type,
- fqdn = 'OctetString'(decode, DN),
- port = PortNr,
- transport = to_atom(T, T0),
+ fqdn = 'OctetString'(decode, DN, Opts),
+ port = portnr(PN, Type, Opts),
+ transport = transport(T, Opts),
protocol = to_atom(P, diameter)}.
%% Choose defaults based on the RFC, since 6733 has changed them.
-defaults(3588, _) ->
- {3868, sctp};
-defaults(6733, aaa) ->
- {3868, tcp};
-defaults(6733, aaas) ->
- {5658, tcp}.
-
-to_int(<<>>, N) ->
- N;
-to_int(B, _) ->
+
+portnr(<<>>, aaa, #{rfc := 6733}) ->
+ 3868;
+portnr(<<>>, aaas, #{rfc := 6733}) ->
+ 5868;
+portnr(<<>>, _, #{rfc := 3588}) ->
+ 3868;
+portnr(B, _, _) ->
binary_to_integer(B).
+transport(<<>>, #{rfc := 6733}) ->
+ tcp;
+transport(<<>>, #{rfc := 3588}) ->
+ sctp;
+transport(B, _) ->
+ to_atom(B).
+
to_atom(<<>>, A) ->
A;
to_atom(B, _) ->
diff --git a/lib/diameter/src/base/diameter_watchdog.erl b/lib/diameter/src/base/diameter_watchdog.erl
index 2ba60a65fb..a63425d92a 100644
--- a/lib/diameter/src/base/diameter_watchdog.erl
+++ b/lib/diameter/src/base/diameter_watchdog.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -50,10 +50,6 @@
-define(IS_NATURAL(N), (is_integer(N) andalso 0 =< N)).
--record(config,
- {suspect = 1 :: non_neg_integer(), %% OKAY -> SUSPECT
- okay = 3 :: non_neg_integer()}). %% REOPEN -> OKAY
-
-record(watchdog,
{%% PCB - Peer Control Block; see RFC 3539, Appendix A
status = initial :: initial | okay | suspect | down | reopen,
@@ -70,12 +66,19 @@
| integer() %% monotonic time
| undefined,
dictionary :: module(), %% common dictionary
- receive_data :: term(),
- %% term passed into diameter_service with incoming message
- sequence :: diameter:sequence(), %% mask
- restrict :: {diameter:restriction(), boolean()},
- shutdown = false :: boolean(),
- config :: #config{}}).
+ receive_data :: term(), %% term passed with incoming message
+ config :: #{sequence := diameter:sequence(), %% mask
+ restrict_connections := diameter:restriction(),
+ restrict := boolean(),
+ suspect := non_neg_integer(), %% OKAY -> SUSPECT
+ okay := non_neg_integer()}, %% REOPEN -> OKAY
+ codec :: #{string_decode := false,
+ strict_mbit := boolean(),
+ failed_avp := false,
+ rfc := 3588 | 6733,
+ ordered_encode := false,
+ incoming_maxlen := diameter:message_length()},
+ shutdown = false :: boolean()}).
%% ---------------------------------------------------------------------------
%% start/2
@@ -85,12 +88,12 @@
%% reason.
%% ---------------------------------------------------------------------------
--spec start(Type, {RecvData, [Opt], SvcOpts, #diameter_service{}})
+-spec start(Type, {[Opt], SvcOpts, RecvData, #diameter_service{}})
-> {reference(), pid()}
when Type :: {connect|accept, diameter:transport_ref()},
- RecvData :: term(),
Opt :: diameter:transport_opt(),
- SvcOpts :: [diameter:service_opt()].
+ SvcOpts :: map(),
+ RecvData :: term().
start({_,_} = Type, T) ->
Ack = make_ref(),
@@ -117,22 +120,28 @@ init(T) ->
proc_lib:init_ack({ok, self()}),
gen_server:enter_loop(?MODULE, [], i(T)).
-i({Ack, T, Pid, {RecvData,
- Opts,
- SvcOpts,
+i({Ack, T, Pid, {Opts,
+ #{restrict_connections := Restrict}
+ = SvcOpts0,
+ RecvData,
#diameter_service{applications = Apps,
capabilities = Caps}
= Svc}}) ->
monitor(process, Pid),
wait(Ack, Pid),
+
+ Dict0 = common_dictionary(Apps),
+ SvcOpts = SvcOpts0#{rfc => rfc(Dict0)},
putr(restart, {T, Opts, Svc, SvcOpts}), %% save seeing it in trace
putr(dwr, dwr(Caps)), %%
- {_,_} = Mask = proplists:get_value(sequence, SvcOpts),
- Restrict = proplists:get_value(restrict_connections, SvcOpts),
Nodes = restrict_nodes(Restrict),
- Dict0 = common_dictionary(Apps),
- diameter_codec:setopts([{common_dictionary, Dict0},
- {string_decode, false}]),
+ CodecKeys = [string_decode,
+ strict_mbit,
+ incoming_maxlen,
+ spawn_opt,
+ rfc,
+ ordered_encode],
+
#watchdog{parent = Pid,
transport = start(T, Opts, SvcOpts, Nodes, Dict0, Svc),
tw = proplists:get_value(watchdog_timer,
@@ -140,9 +149,14 @@ i({Ack, T, Pid, {RecvData,
?DEFAULT_TW_INIT),
receive_data = RecvData,
dictionary = Dict0,
- sequence = Mask,
- restrict = {Restrict, lists:member(node(), Nodes)},
- config = config(Opts)}.
+ config =
+ maps:without(CodecKeys,
+ config(SvcOpts#{restrict => restrict(Nodes),
+ suspect => 1,
+ okay => 3},
+ Opts)),
+ codec = maps:with(CodecKeys, SvcOpts#{string_decode := false,
+ ordered_encode => false})}.
wait(Ref, Pid) ->
receive
@@ -152,22 +166,31 @@ wait(Ref, Pid) ->
exit({shutdown, D})
end.
-%% config/1
+%% Regard anything but the generated RFC 3588 dictionary as modern.
+%% This affects the interpretation of defaults during the decode
+%% of values of type DiameterURI, this having changed from RFC 3588.
+%% (So much for backwards compatibility.)
+rfc(?BASE) ->
+ 3588;
+rfc(_) ->
+ 6733.
+
+%% config/2
%%
%% Could also configure counts for SUSPECT to DOWN and REOPEN to DOWN,
%% but don't.
-config(Opts) ->
+config(Map, Opts) ->
Config = proplists:get_value(watchdog_config, Opts, []),
- lists:foldl(fun config/2, #config{}, Config).
+ lists:foldl(fun cfg/2, Map, Config).
-config({suspect, N}, Rec)
+cfg({suspect, N}, Map)
when ?IS_NATURAL(N) ->
- Rec#config{suspect = N};
+ Map#{suspect := N};
-config({okay, N}, Rec)
+cfg({okay, N}, Map)
when ?IS_NATURAL(N) ->
- Rec#config{okay = N}.
+ Map#{okay := N}.
%% start/6
@@ -283,7 +306,7 @@ event(Msg,
?LOG(transition, {From, To}).
data(Msg, TPid, reopen, okay) ->
- {recv, TPid, 'DWA', _Pkt} = Msg, %% assert
+ {recv, TPid, _, 'DWA', _Pkt} = Msg, %% assert
{TPid, T} = eraser(open),
[T];
@@ -302,6 +325,8 @@ tpid(_, Pid)
tpid(Pid, _) ->
Pid.
+%% send/2
+
send(Pid, T) ->
Pid ! T.
@@ -375,8 +400,8 @@ transition({accepted = T, TPid}, #watchdog{transport = TPid,
transition({open, TPid, Hosts, _} = Open,
#watchdog{transport = TPid,
status = initial,
- restrict = {_,R},
- config = #config{suspect = OS}}
+ config = #{restrict := R,
+ suspect := OS}}
= S) ->
case okay(role(), Hosts, R) of
okay ->
@@ -394,8 +419,8 @@ transition({open, TPid, Hosts, _} = Open,
transition({open = Key, TPid, _Hosts, T},
#watchdog{transport = TPid,
status = down,
- config = #config{suspect = OS,
- okay = RO}}
+ config = #{suspect := OS,
+ okay := RO}}
= S) ->
case RO of
0 -> %% non-standard: skip REOPEN
@@ -428,7 +453,7 @@ transition({'DOWN', _, process, TPid, _Reason},
transition({'DOWN', _, process, TPid, _Reason} = D,
#watchdog{transport = TPid,
status = T,
- restrict = {_,R}}
+ config = #{restrict := R}}
= S0) ->
S = S0#watchdog{pending = false,
transport = undefined},
@@ -447,12 +472,15 @@ transition({'DOWN', _, process, TPid, _Reason} = D,
end;
%% Incoming message.
-transition({recv, TPid, Name, PktT}, #watchdog{transport = TPid} = S) ->
- try
- incoming(Name, PktT, S)
- catch
+transition({recv, TPid, Route, Name, Pkt},
+ #watchdog{transport = TPid}
+ = S) ->
+ try incoming(Route, Name, Pkt, S) of
#watchdog{dictionary = Dict0, receive_data = T} = NS ->
- diameter_traffic:receive_message(TPid, PktT, Dict0, T),
+ diameter_traffic:receive_message(TPid, Route, Pkt, Dict0, T),
+ NS
+ catch
+ #watchdog{} = NS ->
NS
end;
@@ -481,9 +509,9 @@ getr(Key) ->
eraser(Key) ->
erase({?MODULE, Key}).
-%% encode/3
+%% encode/4
-encode(dwr = M, Dict0, Mask) ->
+encode(dwr = M, Dict0, Opts, Mask) ->
Msg = getr(M),
Seq = diameter_session:sequence(Mask),
Hdr = #diameter_header{version = ?DIAMETER_VERSION,
@@ -491,10 +519,10 @@ encode(dwr = M, Dict0, Mask) ->
hop_by_hop_id = Seq},
Pkt = #diameter_packet{header = Hdr,
msg = Msg},
- diameter_codec:encode(Dict0, Pkt);
+ diameter_codec:encode(Dict0, Opts, Pkt);
-encode(dwa, Dict0, #diameter_packet{header = H, transport_data = TD}
- = ReqPkt) ->
+encode(dwa, Dict0, Opts, #diameter_packet{header = H, transport_data = TD}
+ = ReqPkt) ->
AnsPkt = #diameter_packet{header
= H#diameter_header{is_request = false,
is_error = undefined,
@@ -502,7 +530,7 @@ encode(dwa, Dict0, #diameter_packet{header = H, transport_data = TD}
msg = dwa(ReqPkt),
transport_data = TD},
- diameter_codec:encode(Dict0, AnsPkt).
+ diameter_codec:encode(Dict0, Opts, AnsPkt).
%% okay/3
@@ -572,9 +600,10 @@ tw({M,F,A}) ->
send_watchdog(#watchdog{pending = false,
transport = TPid,
dictionary = Dict0,
- sequence = Mask}
+ config = #{sequence := Mask},
+ codec = Opts}
= S) ->
- #diameter_packet{bin = Bin} = EPkt = encode(dwr, Dict0, Mask),
+ #diameter_packet{bin = Bin} = EPkt = encode(dwr, Dict0, Opts, Mask),
diameter_traffic:incr(send, EPkt, TPid, Dict0),
send(TPid, {send, Bin}),
?LOG(send, 'DWR'),
@@ -582,41 +611,32 @@ send_watchdog(#watchdog{pending = false,
%% Don't count encode errors since we don't expect any on DWR/DWA.
-%% incoming/3
-
-incoming(Name, {Pkt, NPid}, S) ->
- NS = recv(Name, Pkt, S),
- NPid ! {diameter, discard},
- NS;
+%% incoming/4
-incoming(Name, Pkt, S) ->
- recv(Name, Pkt, S).
-
-%% recv/3
-
-recv(Name, Pkt, S) ->
- try rcv(Name, Pkt, rcv(Name, S)) of
- #watchdog{} = NS ->
- throw(NS)
+incoming(Route, Name, Pkt, S) ->
+ try rcv(Name, S) of
+ NS -> rcv(Name, Pkt, NS)
catch
- #watchdog{} = NS -> %% throwaway
- NS
+ #watchdog{transport = TPid} = NS when Route -> %% incoming request
+ send(TPid, {send, false}), %% requiring ack
+ throw(NS)
end.
%% rcv/3
rcv('DWR', Pkt, #watchdog{transport = TPid,
- dictionary = Dict0}
+ dictionary = Dict0,
+ codec = Opts}
= S) ->
?LOG(recv, 'DWR'),
- DPkt = diameter_codec:decode(Dict0, Pkt),
+ DPkt = diameter_codec:decode(Dict0, Opts, Pkt),
diameter_traffic:incr(recv, DPkt, TPid, Dict0),
diameter_traffic:incr_error(recv, DPkt, TPid, Dict0),
#diameter_packet{header = H,
transport_data = T,
bin = Bin}
= EPkt
- = encode(dwa, Dict0, Pkt),
+ = encode(dwa, Dict0, Opts, Pkt),
diameter_traffic:incr(send, EPkt, TPid, Dict0),
diameter_traffic:incr_rc(send, EPkt, TPid, Dict0),
@@ -628,12 +648,13 @@ rcv('DWR', Pkt, #watchdog{transport = TPid,
throw(S);
rcv('DWA', Pkt, #watchdog{transport = TPid,
- dictionary = Dict0}
+ dictionary = Dict0,
+ codec = Opts}
= S) ->
?LOG(recv, 'DWA'),
diameter_traffic:incr(recv, Pkt, TPid, Dict0),
diameter_traffic:incr_rc(recv,
- diameter_codec:decode(Dict0, Pkt),
+ diameter_codec:decode(Dict0, Opts, Pkt),
TPid,
Dict0),
throw(S);
@@ -695,12 +716,12 @@ rcv(_, #watchdog{status = okay} = S) ->
%% SUSPECT Receive non-DWA Failback()
%% SetWatchdog() OKAY
-rcv('DWA', #watchdog{status = suspect, config = #config{suspect = OS}} = S) ->
+rcv('DWA', #watchdog{status = suspect, config = #{suspect := OS}} = S) ->
set_watchdog(S#watchdog{status = okay,
num_dwa = OS,
pending = false});
-rcv(_, #watchdog{status = suspect, config = #config{suspect = OS}} = S) ->
+rcv(_, #watchdog{status = suspect, config = #{suspect := OS}} = S) ->
set_watchdog(S#watchdog{status = okay,
num_dwa = OS});
@@ -710,8 +731,8 @@ rcv(_, #watchdog{status = suspect, config = #config{suspect = OS}} = S) ->
rcv('DWA', #watchdog{status = reopen,
num_dwa = N,
- config = #config{suspect = OS,
- okay = RO}}
+ config = #{suspect := OS,
+ okay := RO}}
= S)
when N+1 == RO ->
S#watchdog{status = okay,
@@ -842,18 +863,19 @@ restart(S) -> %% reconnect has won race with timeout
restart({{connect, _} = T, Opts, Svc, SvcOpts},
#watchdog{parent = Pid,
- restrict = {R,_},
+ config = #{restrict_connections := R}
+ = M,
dictionary = Dict0}
= S) ->
send(Pid, {reconnect, self()}),
Nodes = restrict_nodes(R),
S#watchdog{transport = start(T, Opts, SvcOpts, Nodes, Dict0, Svc),
- restrict = {R, lists:member(node(), Nodes)}};
+ config = M#{restrict => restrict(Nodes)}};
%% No restriction on the number of connections to the same peer: just
%% die. Note that a state machine never enters state REOPEN in this
%% case.
-restart({{accept, _}, _, _, _}, #watchdog{restrict = {_, false}}) ->
+restart({{accept, _}, _, _, _}, #watchdog{config = #{restrict := false}}) ->
stop;
%% Otherwise hang around until told to die, either by the service or
@@ -897,3 +919,8 @@ restrict_nodes(Nodes)
restrict_nodes(F) ->
diameter_lib:eval(F).
+
+%% restrict/1
+
+restrict(Nodes) ->
+ lists:member(node(), Nodes).
diff --git a/lib/diameter/src/compiler/diameter_codegen.erl b/lib/diameter/src/compiler/diameter_codegen.erl
index cdaa9aa7f9..f56e4a5249 100644
--- a/lib/diameter/src/compiler/diameter_codegen.erl
+++ b/lib/diameter/src/compiler/diameter_codegen.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -150,20 +150,21 @@ erl_forms(Mod, ParseD) ->
{id, 0},
{vendor_id, 0},
{vendor_name, 0},
- {decode_avps, 2}, %% in diameter_gen.hrl
- {encode_avps, 2}, %%
+ {decode_avps, 3}, %% in diameter_gen.hrl
+ {encode_avps, 3}, %%
+ {grouped_avp, 4}, %%
{msg_name, 2},
{msg_header, 1},
{rec2msg, 1},
{msg2rec, 1},
{name2rec, 1},
{avp_name, 2},
+ {avp_arity, 1},
{avp_arity, 2},
{avp_header, 1},
- {avp, 3},
- {grouped_avp, 3},
+ {avp, 4},
{enumerated_avp, 3},
- {empty_value, 1},
+ {empty_value, 2},
{dict, 0}]},
%% diameter.hrl is included for #diameter_avp
{?attribute, include_lib, "diameter/include/diameter.hrl"},
@@ -178,13 +179,14 @@ erl_forms(Mod, ParseD) ->
f_msg2rec(ParseD),
f_name2rec(ParseD),
f_avp_name(ParseD),
- f_avp_arity(ParseD),
+ f_avp_arity_1(ParseD),
+ f_avp_arity_2(ParseD),
f_avp_header(ParseD),
f_avp(ParseD),
f_enumerated_avp(ParseD),
f_empty_value(ParseD),
f_dict(ParseD),
- {eof, erl_anno:new(?LINE)}]],
+ {eof, ?LINE}]],
lists:append(Forms).
@@ -418,10 +420,32 @@ vendor_id_map(ParseD) ->
get_value(grouped, ParseD)).
%%% ------------------------------------------------------------------------
+%%% # avp_arity/1
+%%% ------------------------------------------------------------------------
+
+f_avp_arity_1(ParseD) ->
+ {?function, avp_arity, 1, avp_arities(ParseD) ++ [?BADARG(1)]}.
+
+avp_arities(ParseD) ->
+ Msgs = get_value(messages, ParseD),
+ Groups = get_value(grouped, ParseD)
+ ++ lists:flatmap(fun avps/1, get_value(import_groups, ParseD)),
+ lists:map(fun c_avp_arities/1, Msgs ++ Groups).
+
+c_avp_arities({N,_,_,_,As}) ->
+ c_avp_arities(N,As);
+c_avp_arities({N,_,_,As}) ->
+ c_avp_arities(N,As).
+
+c_avp_arities(Name, Avps) ->
+ Arities = [{?A(N), A} || T <- Avps, {N,A} <- [avp_info(T)]],
+ {?clause, [?Atom(Name)], [], [?TERM(Arities)]}.
+
+%%% ------------------------------------------------------------------------
%%% # avp_arity/2
%%% ------------------------------------------------------------------------
-f_avp_arity(ParseD) ->
+f_avp_arity_2(ParseD) ->
{?function, avp_arity, 2, avp_arity(ParseD)}.
avp_arity(ParseD) ->
@@ -452,7 +476,7 @@ c_arity(Name, Avp) ->
%%% ------------------------------------------------------------------------
f_avp(ParseD) ->
- {?function, avp, 3, avp(ParseD) ++ [?BADARG(3)]}.
+ {?function, avp, 4, avp(ParseD) ++ [?BADARG(4)]}.
avp(ParseD) ->
Native = get_value(avp_types, ParseD),
@@ -491,19 +515,25 @@ avp(Native, Imported, Custom, Enums) ->
not_in(List, X) ->
not lists:member(X, List).
-c_base_avp({AvpName, T}) ->
- {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName)],
+c_base_avp({AvpName, "Enumerated"}) ->
+ {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName), ?VAR('_')],
[],
- [b_base_avp(AvpName, T)]}.
+ [?CALL(enumerated_avp, [?VAR('T'), ?Atom(AvpName), ?VAR('Data')])]};
-b_base_avp(AvpName, "Enumerated") ->
- ?CALL(enumerated_avp, [?VAR('T'), ?Atom(AvpName), ?VAR('Data')]);
-
-b_base_avp(AvpName, "Grouped") ->
- ?CALL(grouped_avp, [?VAR('T'), ?Atom(AvpName), ?VAR('Data')]);
+c_base_avp({AvpName, "Grouped"}) ->
+ {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName), ?VAR('Opts')],
+ [],
+ [?CALL(grouped_avp, [?VAR('T'),
+ ?Atom(AvpName),
+ ?VAR('Data'),
+ ?VAR('Opts')])]};
-b_base_avp(_, Type) ->
- ?APPLY(diameter_types, ?A(Type), [?VAR('T'), ?VAR('Data')]).
+c_base_avp({AvpName, Type}) ->
+ {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName), ?VAR('Opts')],
+ [],
+ [?APPLY(diameter_types, ?A(Type), [?VAR('T'),
+ ?VAR('Data'),
+ ?VAR('Opts')])]}.
cs_imported_avp({Mod, Avps}, Enums, CustomNames) ->
lists:map(fun(A) -> imported_avp(Mod, A, Enums) end,
@@ -525,11 +555,13 @@ imported_avp(Mod, {AvpName, _, _, _}, _) ->
c_imported_avp(Mod, AvpName).
c_imported_avp(Mod, AvpName) ->
- {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName)],
+ {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName), ?VAR('Opts')],
[],
- [?APPLY(Mod, avp, [?VAR('T'),
- ?VAR('Data'),
- ?Atom(AvpName)])]}.
+ [?CALL(avp, [?VAR('T'),
+ ?VAR('Data'),
+ ?Atom(AvpName),
+ ?VAR('Opts'),
+ ?ATOM(Mod)])]}.
cs_custom_avp({Mod, Key, Avps}, Dict) ->
lists:map(fun(N) -> c_custom_avp(Mod, Key, N, orddict:fetch(N, Dict)) end,
@@ -537,9 +569,12 @@ cs_custom_avp({Mod, Key, Avps}, Dict) ->
c_custom_avp(Mod, Key, AvpName, Type) ->
{F,A} = custom(Key, AvpName, Type),
- {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName)],
+ {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName), ?VAR('Opts')],
[],
- [?APPLY(?A(Mod), ?A(F), [?VAR('T'), ?Atom(A), ?VAR('Data')])]}.
+ [?APPLY(?A(Mod), ?A(F), [?VAR('T'),
+ ?Atom(A),
+ ?VAR('Data'),
+ ?VAR('Opts')])]}.
custom(custom_types, AvpName, Type) ->
{AvpName, Type};
@@ -568,7 +603,11 @@ enumerated_avp(Mod, Es, Enums) ->
Es).
cs_enumerated_avp(true, Mod, Name) ->
- [c_imported_avp(Mod, Name)];
+ [{?clause, [?VAR('T'), ?Atom(Name), ?VAR('Data')],
+ [],
+ [?APPLY(Mod, enumerated_avp, [?VAR('T'),
+ ?Atom(Name),
+ ?VAR('Data')])]}];
cs_enumerated_avp(false, _, _) ->
[].
@@ -682,7 +721,7 @@ v(false, _, _, _) ->
%%% ------------------------------------------------------------------------
f_empty_value(ParseD) ->
- {?function, empty_value, 1, empty_value(ParseD)}.
+ {?function, empty_value, 2, empty_value(ParseD)}.
empty_value(ParseD) ->
Imported = lists:flatmap(fun avps/1, get_value(import_enums, ParseD)),
@@ -692,15 +731,17 @@ empty_value(ParseD) ->
not lists:keymember(N, 1, Imported)]
++ Imported,
lists:map(fun c_empty_value/1, Groups ++ Enums)
- ++ [{?clause, [?VAR('Name')], [], [?CALL(empty, [?VAR('Name')])]}].
+ ++ [{?clause, [?VAR('Name'), ?VAR('Opts')],
+ [],
+ [?CALL(empty, [?VAR('Name'), ?VAR('Opts')])]}].
c_empty_value({Name, _, _, _}) ->
- {?clause, [?Atom(Name)],
+ {?clause, [?Atom(Name), ?VAR('Opts')],
[],
- [?CALL(empty_group, [?Atom(Name)])]};
+ [?CALL(empty_group, [?Atom(Name), ?VAR('Opts')])]};
c_empty_value({Name, _}) ->
- {?clause, [?Atom(Name)],
+ {?clause, [?Atom(Name), ?VAR('_')],
[],
[?TERM(<<0:32>>)]}.
@@ -790,20 +831,7 @@ header() ->
("%% -------------------------------------------------------------------\n"
"%% This is a generated file.\n"
"%% -------------------------------------------------------------------\n"
- "\n"
- "%%\n"
- "%% Copyright (c) Ericsson AB. All rights reserved.\n"
- "%%\n"
- "%% The information in this document is the property of Ericsson.\n"
- "%%\n"
- "%% Except as specifically authorized in writing by Ericsson, the\n"
- "%% receiver of this document shall keep the information contained\n"
- "%% herein confidential and shall protect the same in whole or in\n"
- "%% part from disclosure and dissemination to third parties.\n"
- "%%\n"
- "%% Disclosure and disseminations to the receivers employees shall\n"
- "%% only be made on a strict need to know basis.\n"
- "%%\n\n").
+ "\n").
hrl_header(Name) ->
header() ++ "-hrl_name('" ++ ?S(Name) ++ ".hrl').\n".
diff --git a/lib/diameter/src/diameter.app.src b/lib/diameter/src/diameter.app.src
index d380ebbd92..9a6e47006b 100644
--- a/lib/diameter/src/diameter.app.src
+++ b/lib/diameter/src/diameter.app.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -28,10 +28,10 @@
]},
{registered, [%REGISTERED%]},
{applications, [
- {stdlib, "2.0"}, {kernel, "3.0"}%, {erts, "6.0"}
- %% {syntax-tools, "1.6.14"}
- %% {runtime-tools, "1.8.14"}
- %, {ssl, "5.3.4"}
+ {stdlib, "2.4"}, {kernel, "3.2"}%, {erts, "6.4"}
+ %% {syntax-tools, "1.6,18"}
+ %% {runtime-tools, "1.8.16"}
+ %, {ssl, "6.0"}
]},
{env, []},
{mod, {diameter_app, []}},
diff --git a/lib/diameter/src/diameter.appup.src b/lib/diameter/src/diameter.appup.src
index 618d5a7f10..07d0389bfd 100644
--- a/lib/diameter/src/diameter.appup.src
+++ b/lib/diameter/src/diameter.appup.src
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -49,7 +49,10 @@
{"1.10", [{restart_application, diameter}]}, %% 18.0
{"1.11", [{restart_application, diameter}]}, %% 18.1
{"1.11.1", [{restart_application, diameter}]}, %% 18.2
- {"1.11.2", [{restart_application, diameter}]} %% 18.3
+ {"1.11.2", [{restart_application, diameter}]}, %% 18.3
+ {"1.12", [{restart_application, diameter}]}, %% 19.0
+ {"1.12.1", [{restart_application, diameter}]}, %% 19.1
+ {"1.12.2", [{restart_application, diameter}]} %% 19.3
],
[
{"0.9", [{restart_application, diameter}]},
@@ -80,6 +83,9 @@
{"1.10", [{restart_application, diameter}]},
{"1.11", [{restart_application, diameter}]},
{"1.11.1", [{restart_application, diameter}]},
- {"1.11.2", [{restart_application, diameter}]}
+ {"1.11.2", [{restart_application, diameter}]},
+ {"1.12", [{restart_application, diameter}]},
+ {"1.12.1", [{restart_application, diameter}]},
+ {"1.12.2", [{restart_application, diameter}]}
]
}.
diff --git a/lib/diameter/src/info/diameter_info.erl b/lib/diameter/src/info/diameter_info.erl
index 59a3b94ee4..23a42e48fd 100644
--- a/lib/diameter/src/info/diameter_info.erl
+++ b/lib/diameter/src/info/diameter_info.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -195,7 +195,7 @@ format(Tables, SFun, CFun)
%%%
%%% Description: Pretty-print records in a named tables as collected
%%% from local and remote nodes. Each table listing is
-%%% preceeded by a banner.
+%%% preceded by a banner.
%%% ----------------------------------------------------------
format(Local, Remote, SFun) ->
diff --git a/lib/diameter/src/modules.mk b/lib/diameter/src/modules.mk
index 4e4ce60ddf..bb3b234d20 100644
--- a/lib/diameter/src/modules.mk
+++ b/lib/diameter/src/modules.mk
@@ -1,7 +1,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010-2016. All Rights Reserved.
+# Copyright Ericsson AB 2010-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@ RT_MODULES = \
base/diameter_config \
base/diameter_config_sup \
base/diameter_codec \
- base/diameter_dict \
+ base/diameter_gen \
base/diameter_lib \
base/diameter_misc_sup \
base/diameter_peer \
diff --git a/lib/diameter/src/transport/diameter_sctp.erl b/lib/diameter/src/transport/diameter_sctp.erl
index 4a005b853d..6a9f1f940b 100644
--- a/lib/diameter/src/transport/diameter_sctp.erl
+++ b/lib/diameter/src/transport/diameter_sctp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -52,21 +52,20 @@
%% Keys into process dictionary.
-define(INFO_KEY, info).
-define(REF_KEY, ref).
+-define(TRANSPORT_KEY, transport).
-define(ERROR(T), erlang:error({T, ?MODULE, ?LINE})).
%% The default port for a listener.
-define(DEFAULT_PORT, 3868). %% RFC 3588, ch 2.1
-%% Remote addresses to accept connections from.
--define(DEFAULT_ACCEPT, []). %% any
-
%% How long to wait for a transport process to attach after
%% association establishment.
-define(ACCEPT_TIMEOUT, 5000).
-type connect_option() :: {raddr, inet:ip_address()}
| {rport, inet:port_number()}
+ | option()
| term(). %% gen_sctp:open_option().
-type match() :: inet:ip_address()
@@ -74,8 +73,14 @@
| [match()].
-type listen_option() :: {accept, match()}
+ | option()
| term(). %% gen_sctp:open_option().
+-type option() :: {sender, boolean()}
+ | sender
+ | {packet, boolean() | raw}
+ | {message_cb, false | diameter:evaluable()}.
+
-type uint() :: non_neg_integer().
%% Accepting/connecting transport process state.
@@ -87,20 +92,35 @@
%% {RAs, RP, Errors}
| connect,
socket :: gen_sctp:sctp_socket() | undefined,
- assoc_id :: gen_sctp:assoc_id(), %% association identifier
+ active = false :: boolean(), %% is socket active?
+ recv = true :: boolean(), %% should it be active?
+ assoc_id :: gen_sctp:assoc_id() %% association identifier
+ | undefined
+ | true,
peer :: {[inet:ip_address()], uint()} %% {RAs, RP}
| undefined,
streams :: {uint(), uint()} %% {InStream, OutStream} counts
| undefined,
- os = 0 :: uint()}). %% next output stream
+ os = 0 :: uint(), %% next output stream
+ packet = true :: boolean() %% legacy transport_data?
+ | raw,
+ message_cb = false :: false | diameter:evaluable(),
+ send = false :: pid() | boolean()}). %% sending process
+
+%% Monitor process state.
+-record(monitor,
+ {transport :: pid(),
+ ack = false :: boolean(),
+ socket :: gen_sctp:sctp_socket(),
+ assoc_id :: gen_sctp:assoc_id()}). %% next output stream
%% Listener process state.
-record(listener,
{ref :: reference(),
socket :: gen_sctp:sctp_socket(),
- count = 0 :: uint(), %% attached transport processes
+ service :: pid(), %% service process
pending = {0, queue:new()},
- accept :: [match()]}).
+ opts :: [[match()] | boolean() | diameter:evaluable()]}).
%% Field pending implements two queues: the first of transport-to-be
%% processes to which an association has been assigned but for which
%% diameter hasn't yet spawned a transport process, a short-lived
@@ -129,11 +149,14 @@
-> {ok, pid(), [inet:ip_address()]}
when Ref :: diameter:transport_ref().
-start(T, #diameter_service{capabilities = Caps}, Opts)
+start(T, Svc, Opts)
when is_list(Opts) ->
+ #diameter_service{capabilities = Caps,
+ pid = Pid}
+ = Svc,
diameter_sctp_sup:start(), %% start supervisors on demand
Addrs = Caps#diameter_caps.host_ip_address,
- s(T, Addrs, lists:map(fun ip/1, Opts)).
+ s(T, Addrs, Pid, lists:map(fun ip/1, Opts)).
ip({ifaddr, A}) ->
{ip, A};
@@ -144,18 +167,22 @@ ip(T) ->
%% when there is not yet an association to assign it, or at comm_up on
%% a new association in which case the call retrieves a transport from
%% the pending queue.
-s({accept, Ref} = A, Addrs, Opts) ->
- {LPid, LAs} = listener(Ref, {Opts, Addrs}),
+s({accept, Ref} = A, Addrs, SvcPid, Opts) ->
+ {ok, LPid, LAs} = listener(Ref, {Opts, SvcPid, Addrs}),
try gen_server:call(LPid, {A, self()}, infinity) of
- {ok, TPid} -> {ok, TPid, LAs}
+ {ok, TPid} ->
+ {ok, TPid, LAs};
+ No ->
+ {error, No}
catch
- exit: Reason -> {error, Reason}
+ exit: Reason ->
+ {error, Reason}
end;
%% This implementation is due to there being no accept call in
%% gen_sctp in order to be able to accept a new association only
%% *after* an accepting transport has been spawned.
-s({connect = C, Ref}, Addrs, Opts) ->
+s({connect = C, Ref}, Addrs, _SvcPid, Opts) ->
diameter_sctp_sup:start_child({C, self(), Opts, Addrs, Ref}).
%% start_link/1
@@ -209,22 +236,39 @@ init(T) ->
%% i/1
+i(#monitor{transport = TPid} = S) ->
+ monitor(process, TPid),
+ putr(?TRANSPORT_KEY, TPid),
+ proc_lib:init_ack({ok, self()}),
+ S;
+
%% A process owning a listening socket.
-i({listen, Ref, {Opts, Addrs}}) ->
+i({listen, Ref, {Opts, SvcPid, Addrs}}) ->
+ monitor(process, SvcPid),
[_] = diameter_config:subscribe(Ref, transport), %% assert existence
- {[Matches], Rest} = proplists:split(Opts, [accept]),
+ {Split, Rest}
+ = proplists:split(Opts, [accept, packet, sender, message_cb]),
+ OwnOpts = lists:append(Split),
{LAs, Sock} = AS = open(Addrs, Rest, ?DEFAULT_PORT),
ok = gen_sctp:listen(Sock, true),
true = diameter_reg:add_new({?MODULE, listener, {Ref, AS}}),
proc_lib:init_ack({ok, self(), LAs}),
#listener{ref = Ref,
+ service = SvcPid,
socket = Sock,
- accept = [[M] || {accept, M} <- Matches]};
+ opts = [[[M] || {accept, M} <- OwnOpts],
+ proplists:get_value(packet, OwnOpts, true)
+ | [proplists:get_value(K, OwnOpts, false)
+ || K <- [sender, message_cb]]]};
%% A connecting transport.
i({connect, Pid, Opts, Addrs, Ref}) ->
- {[As, Ps], Rest} = proplists:split(Opts, [raddr, rport]),
- RAs = [diameter_lib:ipaddr(A) || {raddr, A} <- As],
+ {[Ps | Split], Rest}
+ = proplists:split(Opts, [rport, raddr, packet, sender, message_cb]),
+ OwnOpts = lists:append(Split),
+ CB = proplists:get_value(message_cb, OwnOpts, false),
+ false == CB orelse (Pid ! {diameter, ack}),
+ RAs = [diameter_lib:ipaddr(A) || {raddr, A} <- OwnOpts],
[RP] = [P || {rport, P} <- Ps] ++ [P || P <- [?DEFAULT_PORT], [] == Ps],
{LAs, Sock} = open(Addrs, Rest, 0),
putr(?REF_KEY, Ref),
@@ -232,7 +276,10 @@ i({connect, Pid, Opts, Addrs, Ref}) ->
monitor(process, Pid),
#transport{parent = Pid,
mode = {connect, connect(Sock, RAs, RP, [])},
- socket = Sock};
+ socket = Sock,
+ message_cb = CB,
+ packet = proplists:get_value(packet, OwnOpts, true),
+ send = proplists:get_value(sender, OwnOpts, false)};
%% An accepting transport spawned by diameter, not yet owning an
%% association.
@@ -266,11 +313,16 @@ i({K, Ref}, #transport{mode = {accept, _}} = S) ->
receive
{Ref, Pid} when K == parent -> %% transport process started
S#transport{parent = Pid};
- {K, T, Matches} when K == peeloff -> %% association
+ {K, T, Opts} when K == peeloff -> %% association
{sctp, Sock, _RA, _RP, _Data} = T,
+ [Matches, Packet, Sender, CB] = Opts,
ok = accept_peer(Sock, Matches),
demonitor(Ref, [flush]),
- t(T, S#transport{socket = Sock});
+ false == CB orelse (S#transport.parent ! {diameter, ack}),
+ t(T, S#transport{socket = Sock,
+ message_cb = CB,
+ packet = Packet,
+ send = Sender});
accept_timeout = T ->
x(T);
{'DOWN', _, process, _, _} = T ->
@@ -281,24 +333,23 @@ i({K, Ref}, #transport{mode = {accept, _}} = S) ->
%% Accepting processes can be started concurrently: ensure only one
%% listener is started.
-listener(LRef, T) ->
- diameter_sync:call({?MODULE, listener, LRef},
- {?MODULE, listener, [{LRef, T}]},
+listener(Ref, T) ->
+ diameter_sync:call({?MODULE, listener, Ref},
+ {?MODULE, listener, [{Ref, T}]},
infinity,
infinity).
-listener({LRef, T}) ->
- l(diameter_reg:match({?MODULE, listener, {LRef, '_'}}), LRef, T).
+listener({Ref, T}) ->
+ l(diameter_reg:match({?MODULE, listener, {Ref, '_'}}), Ref, T).
%% Existing listening process ...
l([{{?MODULE, listener, {_, AS}}, LPid}], _, _) ->
- {LAs, _Sock} = AS,
- {LPid, LAs};
+ {LAs, _Sock} = AS,
+ {ok, LPid, LAs};
%% ... or not.
-l([], LRef, T) ->
- {ok, LPid, LAs} = diameter_sctp_sup:start_child({listen, LRef, T}),
- {LPid, LAs}.
+l([], Ref, T) ->
+ diameter_sctp_sup:start_child({listen, Ref, T}).
%% open/3
@@ -364,11 +415,13 @@ type(T) ->
%% # handle_call/3
%% ---------------------------------------------------------------------------
-handle_call({{accept, Ref}, Pid}, _, #listener{ref = Ref,
- count = K}
- = S) ->
+handle_call({{accept, Ref}, Pid}, _, #listener{ref = Ref} = S) ->
{TPid, NewS} = accept(Ref, Pid, S),
- {reply, {ok, TPid}, NewS#listener{count = K+1}};
+ {reply, {ok, TPid}, NewS};
+
+%% Transport is telling us of parent death.
+handle_call({stop, _Pid} = Reason, _From, #monitor{} = S) ->
+ {stop, {shutdown, Reason}, ok, S};
handle_call(_, _, State) ->
{reply, nok, State}.
@@ -388,9 +441,13 @@ handle_info(T, #transport{} = S) ->
{noreply, #transport{} = t(T,S)};
handle_info(T, #listener{} = S) ->
- {noreply, #listener{} = l(T,S)}.
+ {noreply, #listener{} = l(T,S)};
+
+handle_info(T, #monitor{} = S) ->
+ m(T,S),
+ {noreply, S}.
-%% Prior to the possiblity of setting pool_size on in transport
+%% Prior to the possibility of setting pool_size on in transport
%% configuration, a new accepting transport was only started following
%% the death of a predecessor, so that there was only at most one
%% previously started transport process waiting for an association.
@@ -410,6 +467,9 @@ code_change(_, State, _) ->
%% # terminate/2
%% ---------------------------------------------------------------------------
+terminate(_, #monitor{}) ->
+ ok;
+
terminate(_, #transport{assoc_id = undefined}) ->
ok;
@@ -433,14 +493,21 @@ getr(Key) ->
%% Incoming message from SCTP.
l({sctp, Sock, _RA, _RP, Data} = T, #listener{socket = Sock,
- accept = Matches}
+ opts = Opts}
= S) ->
Id = assoc_id(Data),
{TPid, NewS} = accept(S),
- TPid ! {peeloff, setelement(2, T, peeloff(Sock, Id, TPid)), Matches},
+ TPid ! {peeloff, setelement(2, T, peeloff(Sock, Id, TPid)), Opts},
setopts(Sock),
NewS;
+%% Service process has died.
+l({'DOWN', _, process, Pid, _} = T, #listener{service = Pid,
+ socket = Sock}) ->
+ gen_sctp:close(Sock),
+ x(T);
+
+%% Accepting process has died.
l({'DOWN', _MRef, process, TPid, _}, #listener{pending = {_,Q}} = S) ->
down(queue:member(TPid, Q), TPid, S);
@@ -454,20 +521,17 @@ l({transport, remove, _} = T, #listener{socket = Sock}) ->
%% Accepting transport has died.
%% One that's waiting for transport start in the pending queue ...
-down(true, TPid, #listener{pending = {N,Q},
- count = K}
- = S) ->
+down(true, TPid, #listener{pending = {N,Q}} = S) ->
NQ = queue:filter(fun(P) -> P /= TPid end, Q),
if N < 0 -> %% awaiting an association ...
- S#listener{count = K-1,
- pending = {N+1, NQ}};
+ S#listener{pending = {N+1, NQ}};
true -> %% ... or one has been assigned
S#listener{pending = {N-1, NQ}}
end;
%% ... or one that's already attached.
-down(false, _TPid, #listener{count = K} = S) ->
- S#listener{count = K-1}.
+down(false, _TPid, S) ->
+ S.
%% t/2
%%
@@ -487,12 +551,21 @@ t(T,S) ->
%% Incoming message.
transition({sctp, Sock, _RA, _RP, Data}, #transport{socket = Sock} = S) ->
- setopts(Sock),
- recv(Data, S);
+ setopts(S, recv(Data, S#transport{active = false}));
%% Outgoing message.
transition({diameter, {send, Msg}}, S) ->
- send(Msg, S);
+ message(send, Msg, S);
+
+%% Monitor has sent an outgoing message.
+transition(Msg, S)
+ when is_record(Msg, diameter_packet);
+ is_binary(Msg) ->
+ message(ack, Msg, S);
+
+%% Deferred actions from a message_cb.
+transition({actions, Dir, Acts}, S) ->
+ actions(Acts, Dir, S);
%% Request to close the transport connection.
transition({diameter, {close, Pid}}, #transport{parent = Pid}) ->
@@ -506,8 +579,18 @@ transition({diameter, {close, Pid}}, #transport{parent = Pid}) ->
transition({diameter, {tls, _Ref, _Type, _Bool}}, _) ->
stop;
-%% Parent process has died.
-transition({'DOWN', _, process, Pid, _}, #transport{parent = Pid}) ->
+%% Parent process has died: call the monitor to not close the socket
+%% during an ongoing send, but don't let it take forever.
+transition({'DOWN', _, process, Pid, _}, #transport{parent = Pid,
+ send = MPid}) ->
+ is_boolean(MPid)
+ orelse ok == (catch gen_server:call(MPid, {stop, Pid}))
+ orelse exit(MPid, kill),
+ stop;
+
+%% Monitor process has died.
+transition({'DOWN', _, process, MPid, _}, #transport{send = MPid})
+ when is_pid(MPid) ->
stop;
%% Timeout after transport process has been started.
@@ -520,6 +603,18 @@ transition({resolve_port, Pid}, #transport{socket = Sock})
Pid ! inet:port(Sock),
ok.
+%% m/2
+
+m({Msg, StreamId}, #monitor{socket = Sock,
+ transport = TPid,
+ assoc_id = AId,
+ ack = B}) ->
+ send(Sock, AId, StreamId, Msg),
+ B andalso (TPid ! Msg);
+
+m({'DOWN', _, process, TPid, _} = T, #monitor{transport = TPid}) ->
+ x(T).
+
%% Crash on anything unexpected.
ok({ok, T}) ->
@@ -562,33 +657,52 @@ q(Ref, Pid, #listener{pending = {_,Q}}) ->
%% send/2
+%% Start monitor process on first send.
+send(Msg, #transport{send = true,
+ socket = Sock,
+ assoc_id = AId,
+ message_cb = CB}
+ = S) ->
+ {ok, MPid} = diameter_sctp_sup:start_child(#monitor{transport = self(),
+ socket = Sock,
+ assoc_id = AId,
+ ack = false /= CB}),
+ monitor(process, MPid),
+ send(Msg, S#transport{send = MPid});
+
%% Outbound Diameter message on a specified stream ...
-send(#diameter_packet{bin = Bin, transport_data = {outstream, SId}},
+send(#diameter_packet{transport_data = {outstream, SId}}
+ = Msg,
#transport{streams = {_, OS}}
= S) ->
- send(SId rem OS, Bin, S),
- S;
+ send(SId rem OS, Msg, S);
%% ... or not: rotate through all streams.
-send(#diameter_packet{bin = Bin}, S) ->
- send(Bin, S);
-send(Bin, #transport{streams = {_, OS},
+send(Msg, #transport{streams = {_, OS},
os = N}
- = S)
- when is_binary(Bin) ->
- send(N, Bin, S),
- S#transport{os = (N + 1) rem OS}.
+ = S) ->
+ send(N, Msg, S#transport{os = (N + 1) rem OS}).
%% send/3
-send(StreamId, Bin, #transport{socket = Sock,
- assoc_id = AId}) ->
- send(Sock, AId, StreamId, Bin).
+send(StreamId, Msg, #transport{send = false,
+ socket = Sock,
+ assoc_id = AId}
+ = S) ->
+ send(Sock, AId, StreamId, Msg),
+ message(ack, Msg, S);
+
+send(StreamId, Msg, #transport{send = MPid} = S) ->
+ MPid ! {Msg, StreamId},
+ S.
%% send/4
-send(Sock, AssocId, Stream, Bin) ->
- case gen_sctp:send(Sock, AssocId, Stream, Bin) of
+send(Sock, AssocId, StreamId, #diameter_packet{bin = Bin}) ->
+ send(Sock, AssocId, StreamId, Bin);
+
+send(Sock, AssocId, StreamId, Bin) ->
+ case gen_sctp:send(Sock, AssocId, StreamId, Bin) of
ok ->
ok;
{error, Reason} ->
@@ -608,7 +722,9 @@ recv({_, #sctp_assoc_change{state = comm_up,
= S) ->
Ref = getr(?REF_KEY),
publish(T, Ref, Id, Sock),
- up(S#transport{assoc_id = Id,
+ %% Deal with different association id after peeloff on Solaris by
+ %% taking the id from the first reception.
+ up(S#transport{assoc_id = T == accept orelse Id,
streams = {IS, OS}});
%% ... or not: try the next address.
@@ -623,17 +739,19 @@ recv({_, #sctp_assoc_change{} = E},
recv({_, #sctp_assoc_change{}}, _) ->
stop;
+%% First inbound on an accepting transport.
+recv({[#sctp_sndrcvinfo{assoc_id = Id}], _Bin}
+ = T,
+ #transport{assoc_id = true}
+ = S) ->
+ recv(T, S#transport{assoc_id = Id});
+
%% Inbound Diameter message.
-recv({[#sctp_sndrcvinfo{stream = Id}], Bin}, #transport{parent = Pid})
+recv({[#sctp_sndrcvinfo{}], Bin} = Msg, S)
when is_binary(Bin) ->
- diameter_peer:recv(Pid, #diameter_packet{transport_data = {stream, Id},
- bin = Bin}),
- ok;
+ message(recv, Msg, S);
-recv({_, #sctp_shutdown_event{assoc_id = A}},
- #transport{assoc_id = Id})
- when A == Id;
- A == 0 ->
+recv({_, #sctp_shutdown_event{}}, _) ->
stop;
%% Note that diameter_sctp(3) documents that sctp_events cannot be
@@ -749,6 +867,23 @@ connect(Sock, [Addr | AT] = As, Port, Reasons) ->
connect(Sock, AT, Port, [{Addr, E} | Reasons])
end.
+%% setopts/2
+
+setopts(_, #transport{socket = Sock,
+ active = A,
+ recv = B}
+ = S)
+ when B, not A ->
+ setopts(Sock),
+ S#transport{active = true};
+
+setopts(_, #transport{} = S) ->
+ S;
+
+setopts(#transport{socket = Sock}, T) ->
+ setopts(Sock),
+ T.
+
%% setopts/1
setopts(Sock) ->
@@ -756,3 +891,83 @@ setopts(Sock) ->
ok -> ok;
X -> x({setopts, Sock, X}) %% possibly on peer disconnect
end.
+
+%% A message_cb is invoked whenever a message is sent or received, or
+%% to provide acknowledgement of a completed send or discarded
+%% request. See diameter_tcp for semantics, the only difference being
+%% that a recv callback can get a diameter_packet record as Msg
+%% depending on how/if option packet has been specified.
+
+%% message/3
+
+message(send, false = M, S) ->
+ message(ack, M, S);
+
+message(ack, _, #transport{message_cb = false} = S) ->
+ S;
+
+message(Dir, Msg, S) ->
+ setopts(S, actions(cb(S, Dir, Msg), Dir, S)).
+
+%% actions/3
+
+actions([], _, S) ->
+ S;
+
+actions([B | As], Dir, S)
+ when is_boolean(B) ->
+ actions(As, Dir, S#transport{recv = B});
+
+actions([Dir | As], _, S)
+ when Dir == send;
+ Dir == recv ->
+ actions(As, Dir, S);
+
+actions([Msg | As], send = Dir, S)
+ when is_record(Msg, diameter_packet);
+ is_binary(Msg) ->
+ actions(As, Dir, send(Msg, S));
+
+actions([Msg | As], recv = Dir, #transport{parent = Pid} = S)
+ when is_record(Msg, diameter_packet);
+ is_binary(Msg) ->
+ diameter_peer:recv(Pid, Msg),
+ actions(As, Dir, S);
+
+actions([{defer, Tmo, Acts} | As], Dir, S) ->
+ erlang:send_after(Tmo, self(), {actions, Dir, Acts}),
+ actions(As, Dir, S);
+
+actions(CB, _, S) ->
+ S#transport{message_cb = CB}.
+
+%% cb/3
+
+cb(#transport{message_cb = false, packet = P}, recv, Msg) ->
+ [pkt(P, true, Msg)];
+
+cb(#transport{message_cb = CB, packet = P}, recv = D, Msg) ->
+ cb(CB, D, pkt(P, false, Msg));
+
+cb(#transport{message_cb = CB}, Dir, Msg) ->
+ cb(CB, Dir, Msg);
+
+cb(false, send, Msg) ->
+ [Msg];
+
+cb(CB, Dir, Msg) ->
+ diameter_lib:eval([CB, Dir, Msg]).
+
+%% pkt/3
+
+pkt(false, _, {_Info, Bin}) ->
+ Bin;
+
+pkt(true, _, {[#sctp_sndrcvinfo{stream = Id}], Bin}) ->
+ #diameter_packet{bin = Bin, transport_data = {stream, Id}};
+
+pkt(raw, true, {[Info], Bin}) ->
+ #diameter_packet{bin = Bin, transport_data = Info};
+
+pkt(raw, false, {[_], _} = Msg) ->
+ Msg.
diff --git a/lib/diameter/src/transport/diameter_sctp_sup.erl b/lib/diameter/src/transport/diameter_sctp_sup.erl
index 36050aaf28..e8e26ec7c5 100644
--- a/lib/diameter/src/transport/diameter_sctp_sup.erl
+++ b/lib/diameter/src/transport/diameter_sctp_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -49,6 +49,7 @@ start() ->
start_child(T) ->
SupRef = case element(1,T) of
+ monitor -> ?TRANSPORT_SUP;
connect -> ?TRANSPORT_SUP;
accept -> ?TRANSPORT_SUP;
listen -> ?LISTENER_SUP
diff --git a/lib/diameter/src/transport/diameter_tcp.erl b/lib/diameter/src/transport/diameter_tcp.erl
index 546c2cfa5e..a2f393d5d4 100644
--- a/lib/diameter/src/transport/diameter_tcp.erl
+++ b/lib/diameter/src/transport/diameter_tcp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@
%%
-module(diameter_tcp).
--dialyzer({no_fail_call, throttle/2}).
-behaviour(gen_server).
@@ -53,6 +52,7 @@
%% Keys into process dictionary.
-define(INFO_KEY, info).
-define(REF_KEY, ref).
+-define(TRANSPORT_KEY, transport).
-define(ERROR(T), erlang:error({T, ?MODULE, ?LINE})).
@@ -68,19 +68,23 @@
%% The same gen_server implementation supports three different kinds
%% of processes: an actual transport process, one that will club it to
%% death should the parent die before a connection is established, and
-%% a process owning the listening port.
+%% a process owning the listening port. The monitor process
+%% historically died after connection establishment, but can now live
+%% on as the sender of outgoing messages, so that a blocking send
+%% doesn't prevent messages from being received.
%% Listener process state.
--record(listener, {socket :: inet:socket(),
- count = 1 :: non_neg_integer()}). %% accepting processes
-%% The count of accepting processes was previously used to terminate
-%% the listening process, but diameter_reg:subscribe/2 is now used for
-%% this. Leave the the count for trace purposes.
+-record(listener, {socket :: inet:socket(),
+ module :: module(),
+ service = false :: false | pid()}). %% service process
%% Monitor process state.
-record(monitor,
- {parent :: pid(),
- transport = self() :: pid()}).
+ {parent :: reference() | false | pid(),
+ transport = self() :: pid(),
+ ack = false :: boolean(),
+ socket :: inet:socket() | ssl:sslsocket() | undefined,
+ module :: module() | undefined}).
-type length() :: 0..16#FFFFFF. %% message length from Diameter header
-type size() :: non_neg_integer(). %% accumulated binary size
@@ -100,25 +104,30 @@
-type listen_option() :: {accept, match()}
| {ssl_options, true | [ssl:listen_option()]}
+ | option()
| ssl:listen_option()
| gen_tcp:listen_option().
-type option() :: {port, non_neg_integer()}
- | {fragment_timer, 0..16#FFFFFFFF}
- | {throttle_cb, diameter:evaluable()}.
+ | {sender, boolean()}
+ | sender
+ | {message_cb, false | diameter:evaluable()}
+ | {fragment_timer, 0..16#FFFFFFFF}.
%% Accepting/connecting transport process state.
-record(transport,
{socket :: inet:socket() | ssl:sslsocket(), %% accept/connect socket
+ active = false :: boolean(), %% is socket active?
+ recv = true :: boolean(), %% should it be active?
parent :: pid(), %% of process that started us
module :: module(), %% gen_tcp-like module
- frag = <<>> :: frag(), %% message fragment
ssl :: [term()] | boolean(), %% ssl options, ssl or not
+ frag = <<>> :: frag(), %% message fragment
timeout :: infinity | 0..16#FFFFFFFF, %% fragment timeout
tref = false :: false | reference(), %% fragment timer reference
flush = false :: boolean(), %% flush fragment at timeout?
- throttle_cb :: false | diameter:evaluable(), %% ask to receive
- throttled :: boolean() | binary()}). %% stopped receiving?
+ message_cb :: false | diameter:evaluable(),
+ send :: pid() | false}). %% sending process
%% The usual transport using gen_tcp can be replaced by anything
%% sufficiently gen_tcp-like by passing a 'module' option as the first
@@ -138,11 +147,15 @@
| {ok, pid()}
when Ref :: diameter:transport_ref().
-start({T, Ref}, #diameter_service{capabilities = Caps}, Opts) ->
+start({T, Ref}, Svc, Opts) ->
+ #diameter_service{capabilities = Caps,
+ pid = SvcPid}
+ = Svc,
+
diameter_tcp_sup:start(), %% start tcp supervisors on demand
{Mod, Rest} = split(Opts),
Addrs = Caps#diameter_caps.host_ip_address,
- Arg = {T, Ref, Mod, self(), Rest, Addrs},
+ Arg = {T, Ref, Mod, self(), Rest, Addrs, SvcPid},
diameter_tcp_sup:start_child(Arg).
split([{module, M} | Opts]) ->
@@ -196,61 +209,65 @@ init(T) ->
%% i/1
%% A transport process.
-i({T, Ref, Mod, Pid, Opts, Addrs})
+i({T, Ref, Mod, Pid, Opts, Addrs, SvcPid})
when T == accept;
T == connect ->
monitor(process, Pid),
%% Since accept/connect might block indefinitely, spawn a process
- %% that does nothing but kill us with the parent until call
- %% returns.
- {ok, MPid} = diameter_tcp_sup:start_child(#monitor{parent = Pid}),
+ %% that kills us with the parent until call returns, and then
+ %% sends outgoing messages.
{[SO|TO], Rest} = proplists:split(Opts, [ssl_options,
- fragment_timer,
- throttle_cb]),
+ sender,
+ message_cb,
+ fragment_timer]),
SslOpts = ssl_opts(SO),
OwnOpts = lists:append(TO),
Tmo = proplists:get_value(fragment_timer,
OwnOpts,
?DEFAULT_FRAGMENT_TIMEOUT),
+ [CB, Sender] = [proplists:get_value(K, OwnOpts, false)
+ || K <- [message_cb, sender]],
?IS_TIMEOUT(Tmo) orelse ?ERROR({fragment_timer, Tmo}),
- Throttle = proplists:get_value(throttle_cb, OwnOpts, false),
- Sock = init(T, Ref, Mod, Pid, SslOpts, Rest, Addrs),
- MPid ! {stop, self()}, %% tell the monitor to die
+ {ok, MPid} = diameter_tcp_sup:start_child(#monitor{parent = Pid}),
+ Sock = init(T, Ref, Mod, Pid, SslOpts, Rest, Addrs, SvcPid),
M = if SslOpts -> ssl; true -> Mod end,
+ Sender andalso monitor(process, MPid),
+ false == CB orelse (Pid ! {diameter, ack}),
+ MPid ! {start, self(), Sender andalso {Sock, M}, false /= CB},
putr(?REF_KEY, Ref),
- throttle(#transport{parent = Pid,
- module = M,
- socket = Sock,
- ssl = SslOpts,
- timeout = Tmo,
- throttle_cb = Throttle,
- throttled = false /= Throttle});
+ setopts(#transport{parent = Pid,
+ module = M,
+ socket = Sock,
+ ssl = SslOpts,
+ message_cb = CB,
+ timeout = Tmo,
+ send = Sender andalso MPid});
%% Put the reference in the process dictionary since we now use it
%% advertise the ssl socket after TLS upgrade.
%% A monitor process to kill the transport if the parent dies.
i(#monitor{parent = Pid, transport = TPid} = S) ->
+ putr(?TRANSPORT_KEY, TPid),
proc_lib:init_ack({ok, self()}),
- monitor(process, Pid),
monitor(process, TPid),
- S;
+ S#monitor{parent = monitor(process, Pid)};
%% In principle a link between the transport and killer processes
%% could do the same thing: have the accepting/connecting process be
%% killed when the killer process dies as a consequence of parent
%% death. However, a link can be unlinked and this is exactly what
-%% gen_tcp seems to so. Links should be left to supervisors.
+%% gen_tcp seems to do. Links should be left to supervisors.
-i({listen, LRef, APid, {Mod, Opts, Addrs}}) ->
- [_] = diameter_config:subscribe(LRef, transport), %% assert existence
+i({listen, Ref, {Mod, Opts, Addrs}}) ->
+ [_] = diameter_config:subscribe(Ref, transport), %% assert existence
{[LA, LP], Rest} = proplists:split(Opts, [ip, port]),
LAddrOpt = get_addr(LA, Addrs),
LPort = get_port(LP),
{ok, LSock} = Mod:listen(LPort, gen_opts(LAddrOpt, Rest)),
LAddr = laddr(LAddrOpt, Mod, LSock),
- true = diameter_reg:add_new({?MODULE, listener, {LRef, {LAddr, LSock}}}),
+ true = diameter_reg:add_new({?MODULE, listener, {Ref, {LAddr, LSock}}}),
proc_lib:init_ack({ok, self(), {LAddr, LSock}}),
- monitor(process, APid),
- #listener{socket = LSock}.
+ #listener{socket = LSock,
+ module = Mod}.
laddr([], Mod, Sock) ->
{ok, {Addr, _Port}} = sockname(Mod, Sock),
@@ -268,21 +285,22 @@ ssl_opts([{ssl_options, Opts}])
ssl_opts(T) ->
?ERROR({ssl_options, T}).
-%% init/7
+%% init/8
%% Establish a TLS connection before capabilities exchange ...
-init(Type, Ref, Mod, Pid, true, Opts, Addrs) ->
- init(Type, Ref, ssl, Pid, [{cb_info, ?TCP_CB(Mod)} | Opts], Addrs);
+init(Type, Ref, Mod, Pid, true, Opts, Addrs, SvcPid) ->
+ init(Type, Ref, ssl, Pid, [{cb_info, ?TCP_CB(Mod)} | Opts], Addrs, SvcPid);
%% ... or not.
-init(Type, Ref, Mod, Pid, _, Opts, Addrs) ->
- init(Type, Ref, Mod, Pid, Opts, Addrs).
+init(Type, Ref, Mod, Pid, _, Opts, Addrs, SvcPid) ->
+ init(Type, Ref, Mod, Pid, Opts, Addrs, SvcPid).
-%% init/6
+%% init/7
-init(accept = T, Ref, Mod, Pid, Opts, Addrs) ->
+init(accept = T, Ref, Mod, Pid, Opts, Addrs, SvcPid) ->
{[Matches], Rest} = proplists:split(Opts, [accept]),
- {LAddr, LSock} = listener(Ref, {Mod, Rest, Addrs}),
+ {ok, LPid, {LAddr, LSock}} = listener(Ref, {Mod, Rest, Addrs}),
+ ok = gen_server:call(LPid, {accept, SvcPid}, infinity),
proc_lib:init_ack({ok, self(), [LAddr]}),
Sock = ok(accept(Mod, LSock)),
ok = accept_peer(Mod, Sock, accept(Matches)),
@@ -290,7 +308,7 @@ init(accept = T, Ref, Mod, Pid, Opts, Addrs) ->
diameter_peer:up(Pid),
Sock;
-init(connect = T, Ref, Mod, Pid, Opts, Addrs) ->
+init(connect = T, Ref, Mod, Pid, Opts, Addrs, _SvcPid) ->
{[LA, RA, RP], Rest} = proplists:split(Opts, [ip, raddr, rport]),
LAddrOpt = get_addr(LA, Addrs),
RAddr = get_addr(RA),
@@ -344,24 +362,26 @@ accept(Opts) ->
%% Accepting processes can be started concurrently: ensure only one
%% listener is started.
-listener(LRef, T) ->
- diameter_sync:call({?MODULE, listener, LRef},
- {?MODULE, listener, [{LRef, T, self()}]},
+listener(Ref, T) ->
+ diameter_sync:call({?MODULE, listener, Ref},
+ {?MODULE, listener, [{Ref, T, self()}]},
infinity,
infinity).
-listener({LRef, T, TPid}) ->
- l(diameter_reg:match({?MODULE, listener, {LRef, '_'}}), LRef, T, TPid).
+%% listener/1
+
+listener({Ref, T, _TPid}) ->
+ l(diameter_reg:match({?MODULE, listener, {Ref, '_'}}), Ref, T).
+
+%% l/3
%% Existing listening process ...
-l([{{?MODULE, listener, {_, AS}}, LPid}], _, _, TPid) ->
- LPid ! {accept, TPid},
- AS;
+l([{{?MODULE, listener, {_, AS}}, LPid}], _, _) ->
+ {ok, LPid, AS};
%% ... or not.
-l([], LRef, T, TPid) ->
- {ok, _, AS} = diameter_tcp_sup:start_child({listen, LRef, TPid, T}),
- AS.
+l([], Ref, T) ->
+ diameter_tcp_sup:start_child({listen, Ref, T}).
%% get_addr/1
@@ -440,6 +460,18 @@ portnr(Sock) ->
%% # handle_call/3
%% ---------------------------------------------------------------------------
+handle_call({accept, SvcPid}, _From, #listener{service = P} = S) ->
+ {reply, ok, if not is_pid(P), is_pid(SvcPid) ->
+ monitor(process, SvcPid),
+ S#listener{service = SvcPid};
+ true ->
+ S
+ end};
+
+%% Transport is telling us of parent death.
+handle_call({stop, _Pid} = Reason, _From, #monitor{} = S) ->
+ {stop, {shutdown, Reason}, ok, S};
+
handle_call(_, _, State) ->
{reply, nok, State}.
@@ -461,8 +493,7 @@ handle_info(T, #listener{} = S) ->
{noreply, #listener{} = l(T,S)};
handle_info(T, #monitor{} = S) ->
- m(T,S),
- x(T).
+ {noreply, #monitor{} = m(T,S)}.
%% ---------------------------------------------------------------------------
%% # code_change/3
@@ -478,6 +509,7 @@ code_change(_, State, _) ->
terminate(_, _) ->
ok.
+
%% ---------------------------------------------------------------------------
putr(Key, Val) ->
@@ -490,35 +522,63 @@ getr(Key) ->
%%
%% Transition monitor state.
-%% Transport is telling us to die.
-m({stop, TPid}, #monitor{transport = TPid}) ->
- ok;
+%% Outgoing message.
+m(Msg, S)
+ when is_record(Msg, diameter_packet);
+ is_binary(Msg) ->
+ send(Msg, S),
+ S;
-%% Transport has died.
-m({'DOWN', _, process, TPid, _}, #monitor{transport = TPid}) ->
- ok;
+%% Transport has established a connection. Stop monitoring on the
+%% parent so as not to die before a send from the transport.
+m({start, TPid, T, Ack} = M, #monitor{transport = TPid} = S) ->
+ case T of
+ {Sock, Mod} ->
+ demonitor(S#monitor.parent, [flush]),
+ S#monitor{parent = false,
+ socket = Sock,
+ module = Mod,
+ ack = Ack};
+ false -> %% monitor not sending
+ x(M)
+ end;
-%% Transport parent has died.
-m({'DOWN', _, process, Pid, _}, #monitor{parent = Pid,
- transport = TPid}) ->
- exit(TPid, {shutdown, parent}).
+%% Transport is telling us to die.
+m({stop, TPid} = T, #monitor{transport = TPid}) ->
+ x(T);
+
+%% Transport is telling us to die.
+m({stop, TPid} = T, #monitor{transport = TPid}) ->
+ x(T);
+
+%% Transport is telling us that TLS has been negotiated after
+%% capabilities exchange.
+m({tls, SSock}, S) ->
+ S#monitor{socket = SSock,
+ module = ssl};
+
+%% Transport or parent has died.
+m({'DOWN', M, process, P, _} = T, #monitor{parent = MRef,
+ transport = TPid})
+ when M == MRef;
+ P == TPid ->
+ x(T).
%% l/2
%%
%% Transition listener state.
-%% An accepting transport is attaching.
-l({accept, TPid}, #listener{count = N} = S) ->
- monitor(process, TPid),
- S#listener{count = N+1};
-
-%% Accepting process has died.
-l({'DOWN', _, process, _, _}, #listener{count = N} = S) ->
- S#listener{count = N-1};
+%% Service process has died.
+l({'DOWN', _, process, Pid, _} = T, #listener{service = Pid,
+ socket = Sock,
+ module = M}) ->
+ M:close(Sock),
+ x(T);
%% Transport has been removed.
-l({transport, remove, _} = T, #listener{socket = Sock}) ->
- gen_tcp:close(Sock),
+l({transport, remove, _} = T, #listener{socket = Sock,
+ module = M}) ->
+ M:close(Sock),
x(T).
%% t/2
@@ -537,21 +597,13 @@ t(T,S) ->
%% transition/2
-%% Incoming message.
+%% Incoming packets.
transition({P, Sock, Bin}, #transport{socket = Sock,
- ssl = B,
- throttled = T}
+ ssl = B}
= S)
when P == ssl, true == B;
P == tcp ->
- false = T, %% assert
- recv(Bin, S);
-
-%% Make a new throttling callback after a timeout.
-transition(throttle, #transport{throttled = false}) ->
- ok;
-transition(throttle, S) ->
- throttle(S);
+ recv(Bin, S#transport{active = false});
%% Capabilties exchange has decided on whether or not to run over TLS.
transition({diameter, {tls, Ref, Type, B}}, #transport{parent = Pid}
@@ -561,7 +613,7 @@ transition({diameter, {tls, Ref, Type, B}}, #transport{parent = Pid}
= NS
= tls_handshake(Type, B, S),
Pid ! {diameter, {tls, Ref}},
- throttle(NS#transport{ssl = B});
+ NS#transport{ssl = B};
transition({C, Sock}, #transport{socket = Sock,
ssl = B})
@@ -577,8 +629,18 @@ transition({E, Sock, _Reason} = T, #transport{socket = Sock,
?ERROR({T,S});
%% Outgoing message.
-transition({diameter, {send, Bin}}, S) ->
- send(Bin, S);
+transition({diameter, {send, Msg}}, #transport{} = S) ->
+ message(send, Msg, S);
+
+%% Monitor has sent an outgoing message.
+transition(Msg, S)
+ when is_record(Msg, diameter_packet);
+ is_binary(Msg) ->
+ message(ack, Msg, S);
+
+%% Deferred actions from a message_cb.
+transition({actions, Dir, Acts}, S) ->
+ actions(Acts, Dir, S);
%% Request to close the transport connection.
transition({diameter, {close, Pid}}, #transport{parent = Pid,
@@ -598,8 +660,18 @@ transition({resolve_port, Pid}, #transport{socket = Sock,
Pid ! portnr(M, Sock),
ok;
-%% Parent process has died.
-transition({'DOWN', _, process, Pid, _}, #transport{parent = Pid}) ->
+%% Parent process has died: call the monitor to not close the socket
+%% during an ongoing send, but don't let it take forever.
+transition({'DOWN', _, process, Pid, _}, #transport{parent = Pid,
+ send = MPid}) ->
+ false == MPid
+ orelse (ok == gen_server:call(MPid, {stop, self()}, 1000))
+ orelse exit(MPid, {shutdown, parent}),
+ stop;
+
+%% Monitor process has died.
+transition({'DOWN', _, process, MPid, _}, #transport{send = MPid})
+ when is_pid(MPid) ->
stop.
%% Crash on anything unexpected.
@@ -623,11 +695,13 @@ tls_handshake(_, true, #transport{ssl = false}) ->
%% Capabilities exchange negotiated TLS: upgrade the connection.
tls_handshake(Type, true, #transport{socket = Sock,
module = M,
- ssl = Opts}
+ ssl = Opts,
+ send = MPid}
= S) ->
{ok, SSock} = tls(Type, Sock, [{cb_info, ?TCP_CB(M)} | Opts]),
Ref = getr(?REF_KEY),
true = diameter_reg:add_new({?MODULE, Type, {Ref, SSock}}),
+ false == MPid orelse (MPid ! {tls, SSock}), %% tell the sender process
S#transport{socket = SSock,
module = ssl};
@@ -646,24 +720,15 @@ tls(accept, Sock, Opts) ->
%% using Nagle.
%% Receive packets until a full message is received,
-recv(Bin, #transport{frag = Head, throttled = false} = S) ->
+recv(Bin, #transport{frag = Head} = S) ->
case rcv(Head, Bin) of
- {Msg, B} ->
- throttle(S#transport{frag = B, throttled = Msg});
- Frag ->
- setopts(S),
- start_fragment_timer(S#transport{frag = Frag,
- flush = false})
+ {Msg, B} -> %% have a complete message ...
+ message(recv, Msg, S#transport{frag = B});
+ Frag -> %% read more on the socket
+ start_fragment_timer(setopts(S#transport{frag = Frag,
+ flush = false}))
end.
-%% recv/1
-
-recv(#transport{throttled = false} = S) ->
- recv(<<>>, S);
-
-recv(#transport{} = S) ->
- S.
-
%% rcv/2
%% No previous fragment.
@@ -723,13 +788,16 @@ recv1(Len, Bin) ->
<<Msg:Len/binary, Rest/binary>> = Bin,
{Msg, Rest}.
-%% bin/1-2
+%% bin/2
bin(Head, Acc) ->
list_to_binary([Head | lists:reverse(Acc)]).
+%% bin/1
+
bin({_, _, Head, Acc}) ->
bin(Head, Acc);
+
bin(Bin)
when is_binary(Bin) ->
Bin.
@@ -748,9 +816,7 @@ bin(Bin)
%% also eventually lead to watchdog failover.
%% No fragment to flush or not receiving messages.
-flush(#transport{frag = Frag, throttled = B} = S)
- when Frag == <<>>;
- B /= false ->
+flush(#transport{frag = <<>>} = S) ->
S;
%% Messages have been received since last timer expiry.
@@ -758,9 +824,8 @@ flush(#transport{flush = false} = S) ->
start_fragment_timer(S#transport{flush = true});
%% No messages since last expiry.
-flush(#transport{frag = Frag, parent = Pid} = S) ->
- diameter_peer:recv(Pid, bin(Frag)),
- S#transport{frag = <<>>}.
+flush(#transport{frag = Frag} = S) ->
+ message(recv, bin(Frag), S#transport{frag = <<>>}).
%% start_fragment_timer/1
%%
@@ -793,9 +858,27 @@ connect(Mod, Host, Port, Opts) ->
%% send/2
-send(Bin, #transport{socket = Sock,
- module = M}) ->
- case send(M, Sock, Bin) of
+send(Msg, #monitor{socket = Sock, module = M, transport = TPid, ack = B}) ->
+ send1(M, Sock, Msg),
+ B andalso (TPid ! Msg);
+
+send(Msg, #transport{socket = Sock, module = M, send = false} = S) ->
+ send1(M, Sock, Msg),
+ message(ack, Msg, S);
+
+%% Send from the monitor process to avoid deadlock if both the
+%% receiver and the peer were to block in send.
+send(Msg, #transport{send = Pid} = S) ->
+ Pid ! Msg,
+ S.
+
+%% send1/3
+
+send1(Mod, Sock, #diameter_packet{bin = Bin}) ->
+ send1(Mod, Sock, Bin);
+
+send1(Mod, Sock, Bin) ->
+ case send(Mod, Sock, Bin) of
ok ->
ok;
{error, Reason} ->
@@ -822,120 +905,19 @@ setopts(M, Sock, Opts) ->
%% setopts/1
-setopts(#transport{socket = Sock, module = M}) ->
- setopts(M, Sock).
-
-%% setopts/2
-
-setopts(M, Sock) ->
+setopts(#transport{socket = Sock,
+ active = A,
+ recv = B,
+ module = M}
+ = S)
+ when B, not A ->
case setopts(M, Sock, [{active, once}]) of
- ok -> ok;
- X -> x({setopts, M, Sock, X}) %% possibly on peer disconnect
- end.
-
-%% throttle/1
-
-%% Still collecting packets for a complete message: keep receiving.
-throttle(#transport{throttled = false} = S) ->
- recv(S);
-
-%% Decide whether to receive another, or whether to accept a message
-%% that's been received.
-throttle(#transport{throttle_cb = F, throttled = T} = S) ->
- Res = cb(F, T),
-
- try throttle(Res, S) of
- #transport{ssl = SB} = NS when is_boolean(SB) ->
- throttle(defrag(NS));
- #transport{throttled = Msg} = NS when is_binary(Msg) ->
- %% Initial incoming message when we might need to upgrade
- %% to TLS: wait for reception of a tls tuple.
- defrag(NS)
- catch
- #transport{} = NS ->
- recv(NS)
- end.
-
-%% cb/2
-
-cb(false, _) ->
- ok;
-
-cb(F, B) ->
- diameter_lib:eval([F, true /= B andalso B]).
-
-%% throttle/2
-
-%% Callback says to receive another message.
-throttle(ok, #transport{throttled = true} = S) ->
- throw(S#transport{throttled = false});
-
-%% Callback says to accept a received message.
-throttle(ok, #transport{parent = Pid, throttled = Msg} = S)
- when is_binary(Msg) ->
- diameter_peer:recv(Pid, Msg),
- S;
-
-throttle({ok = T, F}, S) ->
- throttle(T, S#transport{throttle_cb = F});
-
-%% Callback says to accept a received message and acknowledged the
-%% returned pid with a {request, Pid} message if a request pid is
-%% spawned, a discard message otherwise. The latter does not mean that
-%% the message was necessarily discarded: it could have been an
-%% answer.
-throttle(NPid, #transport{parent = Pid, throttled = Msg} = S)
- when is_pid(NPid), is_binary(Msg) ->
- diameter_peer:recv(Pid, {Msg, NPid}),
- S;
-
-throttle({NPid, F}, #transport{throttled = Msg} = S)
- when is_pid(NPid), is_binary(Msg) ->
- throttle(NPid, S#transport{throttle_cb = F});
-
-%% Callback to accept a received message says to discard it.
-throttle(discard, #transport{throttled = Msg} = S)
- when is_binary(Msg) ->
- S;
-
-throttle({discard = T, F}, #transport{throttled = Msg} = S)
- when is_binary(Msg) ->
- throttle(T, S#transport{throttle_cb = F});
-
-%% Callback to accept a received message says to answer it with the
-%% supplied binary.
-throttle(Bin, #transport{throttled = Msg} = S)
- when is_binary(Bin), is_binary(Msg) ->
- send(Bin, S),
- S;
-
-throttle({Bin, F}, #transport{throttled = Msg} = S)
- when is_binary(Bin), is_binary(Msg) ->
- throttle(Bin, S#transport{throttle_cb = F});
-
-%% Callback says to ask again in the specified number of milliseconds.
-throttle({timeout, Tmo}, S) ->
- erlang:send_after(Tmo, self(), throttle),
- throw(S);
-
-throttle({timeout = T, Tmo, F}, S) ->
- throttle({T, Tmo}, S#transport{throttle_cb = F});
-
-throttle(T, #transport{throttle_cb = F}) ->
- ?ERROR({invalid_return, T, F}).
-
-%% defrag/1
-%%
-%% Try to extract another message from packets already read before
-%% another throttling callback.
+ ok -> S#transport{active = true};
+ X -> x({setopts, Sock, M, X}) %% possibly on peer disconnect
+ end;
-defrag(#transport{frag = Head} = S) ->
- case rcv(Head, <<>>) of
- {Msg, B} ->
- S#transport{throttled = Msg, frag = B};
- _ ->
- S#transport{throttled = true}
- end.
+setopts(S) ->
+ S.
%% portnr/2
@@ -970,3 +952,80 @@ getstat(gen_tcp, Sock) ->
getstat(M, Sock) ->
M:getstat(Sock).
%% Note that ssl:getstat/1 doesn't yet exist in R15B01.
+
+%% A message_cb is invoked whenever a message is sent or received, or
+%% to provide acknowledgement of a completed send or discarded
+%% request. Ignoring possible extra arguments, calls are of the
+%% following form.
+%%
+%% cb(recv, Msg) Receive a message into diameter?
+%% cb(send, Msg) Send a message on the socket?
+%% cb(ack, Msg) Acknowledgement of a completed send.
+%% cb(ack, false) Acknowledgement of a discarded request.
+%%
+%% Msg will be binary() in a recv callback, but can be a
+%% diameter_packet record in a send/ack callback if a recv/send
+%% callback returns a record. Callbacks return a list of the following
+%% form.
+%%
+%% [boolean() | send | recv | binary() | #diameter_packet{}]
+%%
+%% The atoms are meaningless by themselves, but say whether subsequent
+%% messages are to be sent or received. A boolean says whether or not
+%% to continue reading on the socket. Messages can be received even
+%% after false is returned if these arrived in the same packet. A
+%% leading recv or send is implicit on the corresponding callbacks. A
+%% new callback can be returned as the tail of a returned list: any
+%% value not of the aforementioned list type is interpreted as a
+%% callback.
+
+%% message/3
+
+message(send, false = M, S) ->
+ message(ack, M, S);
+
+message(ack, _, #transport{message_cb = false} = S) ->
+ S;
+
+message(Dir, Msg, #transport{message_cb = CB} = S) ->
+ recv(<<>>, actions(cb(CB, Dir, Msg), Dir, S)).
+
+%% actions/3
+
+actions([], _, S) ->
+ S;
+
+actions([B | As], Dir, S)
+ when is_boolean(B) ->
+ actions(As, Dir, S#transport{recv = B});
+
+actions([Dir | As], _, S)
+ when Dir == send;
+ Dir == recv ->
+ actions(As, Dir, S);
+
+actions([Msg | As], send = Dir, S)
+ when is_binary(Msg);
+ is_record(Msg, diameter_packet) ->
+ actions(As, Dir, send(Msg, S));
+
+actions([Msg | As], recv = Dir, #transport{parent = Pid} = S)
+ when is_binary(Msg);
+ is_record(Msg, diameter_packet) ->
+ diameter_peer:recv(Pid, Msg),
+ actions(As, Dir, S);
+
+actions([{defer, Tmo, Acts} | As], Dir, S) ->
+ erlang:send_after(Tmo, self(), {actions, Dir, Acts}),
+ actions(As, Dir, S);
+
+actions(CB, _, S) ->
+ S#transport{message_cb = CB}.
+
+%% cb/3
+
+cb(false, _, Msg) ->
+ [Msg];
+
+cb(CB, Dir, Msg) ->
+ diameter_lib:eval([CB, Dir, Msg]).
diff --git a/lib/diameter/test/diameter_capx_SUITE.erl b/lib/diameter/test/diameter_capx_SUITE.erl
index ed6641b9fb..51b6c1d7f2 100644
--- a/lib/diameter/test/diameter_capx_SUITE.erl
+++ b/lib/diameter/test/diameter_capx_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -384,7 +384,7 @@ load_dict(N) ->
A3 = erl_anno:new(3),
A4 = erl_anno:new(4),
Forms = [{attribute, A1, module, Mod},
- {attribute, A2, compile, [export_all]},
+ {attribute, A2, export, [{id,0}]},
{function, A3, id, 0,
[{clause, A4, [], [], [{integer, A4, N}]}]}],
{ok, Mod, Bin, []} = compile:forms(Forms, [return]),
@@ -433,7 +433,7 @@ server_reject(Config, F, RC) ->
?fail({LRef, OH})
end.
-%% cliient_closed/4
+%% client_closed/4
client_closed(Config, Host, F, RC) ->
true = diameter:subscribe(?CLIENT),
diff --git a/lib/diameter/test/diameter_codec_SUITE.erl b/lib/diameter/test/diameter_codec_SUITE.erl
index 558ba3b848..9f08f49f9f 100644
--- a/lib/diameter/test/diameter_codec_SUITE.erl
+++ b/lib/diameter/test/diameter_codec_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -31,6 +31,8 @@
-export([suite/0,
all/0,
groups/0,
+ init_per_suite/1,
+ end_per_suite/1,
init_per_group/2,
end_per_group/2,
init_per_testcase/2,
@@ -63,6 +65,12 @@ groups() ->
grouped_error,
failed_error]}].
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
init_per_group(recode, Config) ->
ok = diameter:start(),
Config.
@@ -277,7 +285,14 @@ recode(Msg) ->
recode(Msg, diameter_gen_base_rfc6733).
recode(#diameter_packet{} = Pkt, Dict) ->
- diameter_codec:decode(Dict, diameter_codec:encode(Dict, Pkt));
+ diameter_codec:decode(Dict, opts(Dict), diameter_codec:encode(Dict, Pkt));
recode(Msg, Dict) ->
recode(#diameter_packet{msg = Msg}, Dict).
+
+opts(Mod) ->
+ #{dictionary => Mod,
+ string_decode => false,
+ strict_mbit => true,
+ rfc => 6733,
+ failed_avp => false}.
diff --git a/lib/diameter/test/diameter_codec_SUITE_data/diameter_test_unknown.erl b/lib/diameter/test/diameter_codec_SUITE_data/diameter_test_unknown.erl
index 50cc6e7eef..700910878c 100644
--- a/lib/diameter/test/diameter_codec_SUITE_data/diameter_test_unknown.erl
+++ b/lib/diameter/test/diameter_codec_SUITE_data/diameter_test_unknown.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -59,7 +59,7 @@ enc(M, #diameter_packet{msg = Vs} = P) ->
P#diameter_packet{msg = [M|Vs]}).
run(M, Pkt) ->
- dec(M, diameter_codec:decode(diameter_test_recv, Pkt)).
+ dec(M, diameter_codec:decode(diameter_test_recv, opts(M), Pkt)).
%% Note that the recv dictionary defines neither XXX nor YYY.
dec('AR', #diameter_packet
@@ -75,3 +75,10 @@ dec('BR', #diameter_packet
errors = [{5001, ?MANDATORY_XXX},
{5008, ?NOT_MANDATORY_YYY}]}) ->
ok.
+
+opts(Mod) ->
+ #{dictionary => Mod,
+ string_decode => true,
+ strict_mbit => true,
+ rfc => 6733,
+ failed_avp => false}.
diff --git a/lib/diameter/test/diameter_codec_test.erl b/lib/diameter/test/diameter_codec_test.erl
index 37c41a1761..b548f85cb8 100644
--- a/lib/diameter/test/diameter_codec_test.erl
+++ b/lib/diameter/test/diameter_codec_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -94,7 +94,7 @@ base(T) ->
%% Ensure that 'zero' values encode only zeros.
base(zero = T, F) ->
- B = diameter_types:F(encode, T),
+ B = diameter_types:F(encode, T, opts()),
B = z(B);
%% Ensure that we can decode what we encode and vice-versa, and that
@@ -106,7 +106,7 @@ base(decode, F) ->
[] = run([[fun base_invalid/2, F, V] || V <- Is]).
base_decode(F, Eq, Value) ->
- d(fun(X,V) -> diameter_types:F(X,V) end, Eq, Value).
+ d(fun(X,V) -> diameter_types:F(X, V, opts()) end, Eq, Value).
base_invalid(F, Value) ->
try
@@ -171,7 +171,7 @@ gen(M, avp_types, {Name, Code, Type, _Flags}) ->
V = undefined /= VendorId,
V = 0 /= Flags band 2#10000000,
{Name, Type} = M:avp_name(Code, VendorId),
- B = M:empty_value(Name),
+ B = M:empty_value(Name, #{module => M}),
B = z(B),
[] = avp_decode(M, Type, Name);
@@ -207,10 +207,22 @@ avp_decode(Mod, Name, Type, Eq, Value) ->
d(fun(X,V) -> avp(Mod, X, V, Name, Type) end, Eq, Value).
avp(Mod, decode = X, V, Name, 'Grouped') ->
- {Rec, _} = Mod:avp(X, V, Name),
+ {Rec, _} = Mod:avp(X, V, Name, opts(Mod)),
Rec;
-avp(Mod, X, V, Name, _) ->
- Mod:avp(X, V, Name).
+avp(Mod, decode = X, V, Name, _) ->
+ Mod:avp(X, V, Name, opts(Mod));
+avp(Mod, encode = X, V, Name, _) ->
+ iolist_to_binary(Mod:avp(X, V, Name, opts(Mod))).
+
+opts(Mod) ->
+ (opts())#{module => Mod,
+ dictionary => Mod}.
+
+opts() ->
+ #{string_decode => true,
+ strict_mbit => true,
+ rfc => 6733,
+ failed_avp => false}.
%% v/1
@@ -257,8 +269,8 @@ arity(M, Name, AvpName, Rec) ->
enum(M, Name, {_,E}) ->
B = <<E:32>>,
- B = M:avp(encode, E, Name),
- E = M:avp(decode, B, Name).
+ B = M:avp(encode, E, Name, opts(M)),
+ E = M:avp(decode, B, Name, opts(M)).
retag(import_avps) -> avp_types;
retag(import_groups) -> grouped;
@@ -280,7 +292,8 @@ d(F, Eq, V) ->
end.
z(B) ->
- << <<0>> || <<_>> <= B >>.
+ Sz = size(B),
+ <<0:Sz/unit:8>>.
%% values/1
%%
diff --git a/lib/diameter/test/diameter_compiler_SUITE.erl b/lib/diameter/test/diameter_compiler_SUITE.erl
index 7a9ac65ae3..73fe1ef6e0 100644
--- a/lib/diameter/test/diameter_compiler_SUITE.erl
+++ b/lib/diameter/test/diameter_compiler_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@
-export([dict/0]). %% fake dictionary module
%% dictionary callbacks for flatten2/1
--export(['A1'/3, 'Unsigned32'/3]).
+-export(['A1'/4, 'Unsigned32'/4]).
-define(base, "base_rfc3588.dia").
-define(util, diameter_util).
@@ -552,13 +552,13 @@ flatten2(_Config) ->
T <- [encode, decode],
M <- [M2, M3],
Ref <- [make_ref()],
- RC <- [M:avp(T, Ref, A)],
+ RC <- [M:avp(T, Ref, A, #{module => M})],
RC /= {T, Ref}].
-'A1'(T, 'Unsigned32', Ref) ->
+'A1'(T, 'Unsigned32', Ref, _Opts) ->
{T, Ref}.
-'Unsigned32'(T, 'A3', Ref) ->
+'Unsigned32'(T, 'A3', Ref, _Opts) ->
{T, Ref}.
load_forms(Forms) ->
diff --git a/lib/diameter/test/diameter_dict_SUITE.erl b/lib/diameter/test/diameter_dict_SUITE.erl
deleted file mode 100644
index 4c1349f4eb..0000000000
--- a/lib/diameter/test/diameter_dict_SUITE.erl
+++ /dev/null
@@ -1,145 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% Tests of the dict-like diameter_dict.
-%%
-
--module(diameter_dict_SUITE).
-
--export([suite/0,
- all/0,
- groups/0]).
-
-%% testcases
--export([append/1,
- fetch/1,
- fetch_keys/1,
- filter/1,
- find/1,
- fold/1,
- is_key/1,
- map/1,
- merge/1,
- update/1,
- update_counter/1]).
-
--include("diameter_ct.hrl").
-
--define(dict, diameter_dict).
--define(util, diameter_util).
-
-%% ===========================================================================
-
-suite() ->
- [{timetrap, {seconds, 60}}].
-
-all() ->
- [{group, all},
- {group, all, [parallel]}].
-
-groups() ->
- [{all, [], tc()}].
-
-tc() ->
- [append,
- fetch,
- fetch_keys,
- filter,
- find,
- fold,
- is_key,
- map,
- merge,
- update,
- update_counter].
-
-%% ===========================================================================
-
--define(KV100, [{N,[N]} || N <- lists:seq(1,100)]).
-
-append(_) ->
- D = ?dict:append(k, v, ?dict:new()),
- [{k,[v,v]}] = ?dict:to_list(?dict:append(k, v, D)).
-
-fetch(_) ->
- D = ?dict:from_list(?KV100),
- [50] = ?dict:fetch(50, D),
- Ref = make_ref(),
- Ref = try ?dict:fetch(Ref, D) catch _:_ -> Ref end.
-
-fetch_keys(_) ->
- L = ?KV100,
- D = ?dict:from_list(L),
- L = [{N,[N]} || N <- lists:sort(?dict:fetch_keys(D))].
-
-filter(_) ->
- L = ?KV100,
- F = fun(K,[_]) -> 0 == K rem 2 end,
- D = ?dict:filter(F, ?dict:from_list(L)),
- true = [T || {K,V} = T <- L, F(K,V)] == lists:sort(?dict:to_list(D)).
-
-find(_) ->
- D = ?dict:from_list(?KV100),
- {ok, [50]} = ?dict:find(50, D),
- error = ?dict:find(make_ref(), D).
-
-fold(_) ->
- L = ?KV100,
- S = lists:sum([N || {N,_} <- L]),
- S = ?dict:fold(fun(K,[_],A) -> K + A end, 0, ?dict:from_list(L)).
-
-is_key(_) ->
- L = ?KV100,
- D = ?dict:from_list(L),
- true = lists:all(fun({N,_}) -> ?dict:is_key(N,D) end, L),
- false = ?dict:is_key(make_ref(), D).
-
-map(_) ->
- L = ?KV100,
- F = fun(_,V) -> [N] = V, N*2 end,
- D = ?dict:map(F, ?dict:from_list(L)),
- M = [{K, F(K,V)} || {K,V} <- L],
- M = lists:sort(?dict:to_list(D)).
-
-merge(_) ->
- L = ?KV100,
- F = fun(_,V1,V2) -> V1 ++ V2 end,
- D = ?dict:merge(F, ?dict:from_list(L), ?dict:from_list(L)),
- M = [{K, F(K,V,V)} || {K,V} <- L],
- M = lists:sort(?dict:to_list(D)).
-
-update(_) ->
- L = ?KV100,
- F = fun([V]) -> 2*V end,
- D = ?dict:update(50, F, ?dict:from_list(L)),
- 100 = ?dict:fetch(50, D),
- Ref = make_ref(),
- Ref = try ?dict:update(Ref, F, D) catch _:_ -> Ref end,
- [Ref] = ?dict:fetch(Ref, ?dict:update(Ref,
- fun(_,_) -> ?ERROR(i_think_not) end,
- [Ref],
- D)).
-
-update_counter(_) ->
- L = [{N,2*N} || {N,_} <- ?KV100],
- D = ?dict:update_counter(50, 20, ?dict:from_list(L)),
- 120 = ?dict:fetch(50,D),
- 2 = ?dict:fetch(1,D).
diff --git a/lib/diameter/test/diameter_dpr_SUITE.erl b/lib/diameter/test/diameter_dpr_SUITE.erl
index 55702fbf78..779b919d3c 100644
--- a/lib/diameter/test/diameter_dpr_SUITE.erl
+++ b/lib/diameter/test/diameter_dpr_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,6 +27,8 @@
-export([suite/0,
all/0,
groups/0,
+ init_per_suite/1,
+ end_per_suite/1,
init_per_group/2,
end_per_group/2]).
@@ -56,16 +58,12 @@
%% Config for diameter:start_service/2.
-define(SERVICE(Host),
- [{'Origin-Host', Host},
+ [{'Origin-Host', Host ++ ".erlang.org"},
{'Origin-Realm', "erlang.org"},
{'Host-IP-Address', [?ADDR]},
{'Vendor-Id', hd(Host)}, %% match this in disconnect/5
{'Product-Name', "OTP/diameter"},
- {'Acct-Application-Id', [0]},
- {restrict_connections, false},
- {application, [{dictionary, diameter_gen_base_rfc6733},
- {alias, common},
- {module, #diameter_callback{_ = false}}]}]).
+ {restrict_connections, false}]).
%% Disconnect reasons that diameter passes as the first argument of a
%% function configured as disconnect_cb.
@@ -89,13 +87,19 @@ suite() ->
[{timetrap, {seconds, 60}}].
all() ->
- [start, send_dpr, stop | [{group, R} || R <- ?REASONS]].
+ [{group, R} || R <- [client, server, uncommon | ?REASONS]].
%% The group determines how transports are terminated: by remove_transport,
%% stop_service or application stop.
groups() ->
- Ts = tc(),
- [{R, [], Ts} || R <- ?REASONS].
+ [{R, [], [start, send_dpr, stop]} || R <- [client, server, uncommon]]
+ ++ [{R, [], Ts} || Ts <- [tc()], R <- ?REASONS].
+
+init_per_suite(Config) -> %% not need, but a useful place to enable trace
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
init_per_group(Name, Config) ->
[{group, Name} | Config].
@@ -107,29 +111,86 @@ tc() ->
[start, connect, remove_transport, stop_service, check, stop].
%% ===========================================================================
-%% start/stop testcases
-start(_Config) ->
- ok = diameter:start(),
- ok = diameter:start_service(?SERVER, ?SERVICE(?SERVER)),
- ok = diameter:start_service(?CLIENT, ?SERVICE(?CLIENT)).
+%% start/1
-send_dpr(_Config) ->
+start(Config)
+ when is_list(Config) ->
+ Grp = group(Config),
+ ok = diameter:start(),
+ ok = diameter:start_service(?SERVER, service(?SERVER, Grp)),
+ ok = diameter:start_service(?CLIENT, service(?CLIENT, Grp)).
+
+service(?SERVER = Svc, _) ->
+ ?SERVICE(Svc)
+ ++ [{'Acct-Application-Id', [0,3]},
+ {application, [{dictionary, diameter_gen_base_rfc6733},
+ {alias, common},
+ {module, #diameter_callback{_ = false}}]},
+ {application, [{dictionary, diameter_gen_acct_rfc6733},
+ {alias, acct},
+ {module, #diameter_callback{_ = false}}]}];
+
+%% Client that receives a server DPR despite no explicit support for
+%% Diameter common messages.
+service(?CLIENT = Svc, server) ->
+ ?SERVICE(Svc)
+ ++ [{'Acct-Application-Id', [3]},
+ {application, [{dictionary, diameter_gen_acct_rfc6733},
+ {alias, acct},
+ {module, #diameter_callback{_ = false}}]}];
+
+%% Client that sends DPR despite advertised only the accounting
+%% application. The dictionary is required for encode.
+service(?CLIENT = Svc, uncommon) ->
+ ?SERVICE(Svc)
+ ++ [{'Acct-Application-Id', [3]},
+ {application, [{dictionary, diameter_gen_base_rfc6733},
+ {alias, common},
+ {module, #diameter_callback{_ = false}}]},
+ {application, [{dictionary, diameter_gen_acct_rfc6733},
+ {alias, acct},
+ {module, #diameter_callback{_ = false}}]}];
+
+service(?CLIENT = Svc, _) ->
+ ?SERVICE(Svc)
+ ++ [{'Auth-Application-Id', [0]},
+ {application, [{dictionary, diameter_gen_base_rfc6733},
+ {alias, common},
+ {module, #diameter_callback{_ = false}}]}].
+
+%% send_dpr/1
+
+send_dpr(Config) ->
LRef = ?util:listen(?SERVER, tcp),
Ref = ?util:connect(?CLIENT, tcp, LRef, [{dpa_timeout, 10000}]),
+ Svc = sender(group(Config)),
+ [Info] = diameter:service_info(Svc, connections),
+ {_, {TPid, _}} = lists:keyfind(peer, 1, Info),
#diameter_base_DPA{'Result-Code' = 2001}
- = diameter:call(?CLIENT,
+ = diameter:call(Svc,
common,
- ['DPR', {'Origin-Host', "CLIENT.erlang.org"},
- {'Origin-Realm', "erlang.org"},
- {'Disconnect-Cause', 0}]),
- ok = receive %% endure the transport dies on DPA
+ ['DPR', {'Origin-Host', Svc ++ ".erlang.org"},
+ {'Origin-Realm', "erlang.org"},
+ {'Disconnect-Cause', 0}],
+ [{peer, TPid}]),
+ ok = receive %% ensure the transport dies on DPA
#diameter_event{service = ?CLIENT, info = {down, Ref, _, _}} ->
ok
after 5000 ->
erlang:process_info(self(), messages)
end.
+%% sender/1
+
+sender(server) ->
+ ?SERVER;
+
+sender(_) ->
+ ?CLIENT.
+
+%% connect/1
+
connect(Config) ->
Pid = spawn(fun init/0), %% process for disconnect_cb to bang
Grp = group(Config),
@@ -138,16 +199,22 @@ connect(Config) ->
|| RCs <- ?RETURNS],
?util:write_priv(Config, config, [Pid | Refs]).
+%% remove_transport/1
+
%% Remove all the client transports only in the transport group.
remove_transport(Config) ->
transport == group(Config)
andalso (ok = diameter:remove_transport(?CLIENT, true)).
+%% stop_service/1
+
%% Stop the service only in the service group.
stop_service(Config) ->
service == group(Config)
andalso (ok = diameter:stop_service(?CLIENT)).
+%% check/1
+
%% Check for callbacks before diameter:stop/0, not the other way around
%% for the timing reason explained below.
check(Config) ->
@@ -157,9 +224,13 @@ check(Config) ->
Dict = receive {Pid, D} -> D end, %% get it
check(Refs, ?RETURNS, Grp, Dict). %% check for callbacks
+%% stop/1
+
stop(_Config) ->
ok = diameter:stop().
+%% ===========================================================================
+
%% Whether or not there are callbacks after diameter:stop() depends on
%% timing as long as the server runs on the same node: a server
%% transport could close the connection before the client has chance
diff --git a/lib/diameter/test/diameter_examples_SUITE.erl b/lib/diameter/test/diameter_examples_SUITE.erl
index e4ed2b227d..eb99f10fe6 100644
--- a/lib/diameter/test/diameter_examples_SUITE.erl
+++ b/lib/diameter/test/diameter_examples_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -92,12 +92,10 @@ init_per_group(tcp = N, Config) ->
[{group, N} | Config];
init_per_group(sctp = N, Config) ->
- case gen_sctp:open() of
- {ok, Sock} ->
- gen_sctp:close(Sock),
+ case ?util:have_sctp() of
+ true ->
[{group, N} | Config];
- {error, E} when E == eprotonosupport;
- E == esocktnosupport -> %% fail on any other reason
+ false->
{skip, no_sctp}
end.
diff --git a/lib/diameter/test/diameter_gen_sctp_SUITE.erl b/lib/diameter/test/diameter_gen_sctp_SUITE.erl
index 79db39ca45..ccee6baec1 100644
--- a/lib/diameter/test/diameter_gen_sctp_SUITE.erl
+++ b/lib/diameter/test/diameter_gen_sctp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,8 +33,8 @@
end_per_suite/1]).
%% testcases
--export([send_not_from_controlling_process/1,
- send_from_multiple_clients/1, send_from_multiple_clients/0,
+-export([send_one_from_many/1, send_one_from_many/0,
+ send_many_from_one/1, send_many_from_one/0,
receive_what_was_sent/1]).
-include_lib("kernel/include/inet_sctp.hrl").
@@ -45,16 +45,24 @@
%% Open sockets on the loopback address.
-define(ADDR, {127,0,0,1}).
-%% Snooze, nap, siesta.
--define(SLEEP(T), receive after T -> ok end).
-
%% An indescribably long number of milliseconds after which everthing
%% that should have happened has.
-define(FOREVER, 2000).
+%% How many milliseconds to tolerate between the fastest and slowest
+%% turnaround times.
+-define(VARIANCE, 100).
+
%% The first byte in each message we send as a simple guard against
%% not receiving what was sent.
--define(MAGIC, 42).
+-define(MAGIC, 0).
+
+%% Requested number of inbound/outbound streams.
+-define(STREAMS, 5).
+
+%% Success for send_multiple. Match in each testcase rather than in
+%% send_multiple itself for a better failure in common_test.
+-define(OK, {_, true, _, [true, true], [], _}).
%% ===========================================================================
@@ -62,8 +70,8 @@ suite() ->
[{timetrap, {seconds, 10}}].
all() ->
- [send_not_from_controlling_process,
- send_from_multiple_clients,
+ [send_one_from_many,
+ send_many_from_one,
receive_what_was_sent].
init_per_suite(Config) ->
@@ -81,130 +89,37 @@ end_per_suite(_Config) ->
%% ===========================================================================
-%% send_not_from_controlling_process/1
-%%
-%% This testcase failing shows gen_sctp:send/4 hanging when called
-%% outside the controlling process of the socket in question.
-
-send_not_from_controlling_process(_) ->
- Pids = send_not_from_controlling_process(),
- ?SLEEP(?FOREVER),
- try
- [] = [{P,I} || P <- Pids, I <- [process_info(P)], I /= undefined]
- after
- lists:foreach(fun(P) -> exit(P, kill) end, Pids)
- end.
-
-%% send_not_from_controlling_process/0
-%%
-%% Returns the pids of three spawned processes: a listening process, a
-%% connecting process and a sending process.
-%%
-%% The expected behaviour is that all three processes exit:
-%%
-%% - The listening process exits upon receiving an SCTP message
-%% sent by the sending process.
-%% - The connecting process exits upon listening process exit.
-%% - The sending process exits upon gen_sctp:send/4 return.
-%%
-%% The observed behaviour is that all three processes remain alive
-%% indefinitely:
-%%
-%% - The listening process never receives the SCTP message sent
-%% by the sending process.
-%% - The connecting process has an inet_reply message in its mailbox
-%% as a consequence of the call to gen_sctp:send/4 call from the
-%% sending process.
-%% - The call to gen_sctp:send/4 in the sending process doesn't return,
-%% hanging in prim_inet:getopts/2.
-
-send_not_from_controlling_process() ->
- FPid = self(),
- {L, MRef} = spawn_monitor(fun() -> listen(FPid) end),
- receive
- {?MODULE, C, S} ->
- demonitor(MRef, [flush]),
- [L,C,S];
- {'DOWN', MRef, process, _, _} = T ->
- error(T)
- end.
-
-%% listen/1
-
-listen(FPid) ->
- {ok, Sock} = open(),
- ok = gen_sctp:listen(Sock, true),
- {ok, PortNr} = inet:port(Sock),
- LPid = self(),
- spawn(fun() -> connect1(PortNr, FPid, LPid) end), %% connecting process
- Id = assoc(Sock),
- recv(Sock, Id).
-
-%% connect1/3
-
-connect1(PortNr, FPid, LPid) ->
- {ok, Sock} = open(),
- ok = gen_sctp:connect_init(Sock, ?ADDR, PortNr, []),
- Id = assoc(Sock),
- FPid ! {?MODULE,
- self(),
- spawn(fun() -> send(Sock, Id) end)}, %% sending process
- MRef = monitor(process, LPid),
- down(MRef). %% Waits with this as current_function.
-
-%% down/1
-
-down(MRef) ->
- receive {'DOWN', MRef, process, _, Reason} -> Reason end.
-
-%% send/2
-
-send(Sock, Id) ->
- ok = gen_sctp:send(Sock, Id, 0, <<0:32>>).
-
-%% ===========================================================================
-
-%% send_from_multiple_clients/0
+%% send_one_from_many/0
%%
%% Demonstrates sluggish delivery of messages.
-send_from_multiple_clients() ->
- [{timetrap, {seconds, 60}}].
+send_one_from_many() ->
+ [{timetrap, {seconds, 30}}].
-send_from_multiple_clients(_) ->
- {S, Rs} = T = send_from_multiple_clients(8, 1024),
- Max = ?FOREVER*1000,
- {false, [], _} = {Max < S,
- Rs -- [OI || {O,_} = OI <- Rs, is_integer(O)],
- T}.
+send_one_from_many(_) ->
+ ?OK = send_multiple(128, 1, 1024).
-%% send_from_multiple_clients/2
+%% send_one_from_many/2
%%
%% Opens a listening socket and then spawns a specified number of
-%% processes, each of which connects to the listening socket. Each
-%% connecting process then sends a message, whose size in bytes is
-%% passed as an argument, the listening process sends a reply
-%% containing the time at which the message was received, and the
-%% connecting process then exits upon reception of this reply.
+%% processes, each of which connects, sends a message, receives a
+%% reply, and exits.
%%
%% Returns the elapsed time for all connecting process to exit
-%% together with a list of exit reasons for the connecting processes.
-%% In the successful case a connecting process exits with the
-%% outbound/inbound transit times for the sent/received message as
-%% reason.
+%% together with a list of exit reasons. In the successful case a
+%% connecting process exits with the outbound/inbound transit times
+%% for the sent/received message as reason.
%%
%% The observed behaviour is that some outbound messages (that is,
%% from a connecting process to the listening process) can take an
%% unexpectedly long time to complete their journey. The more
-%% connecting processes, the longer the possible delay it seems.
+%% connecting processes, the longer it can take it seems.
%%
-%% eg. (With F = fun send_from_multiple_clients/2.)
-%%
-%% 5> F(2, 1024).
+%% eg. 5> send_one_from_many(2, 1024).
%% {875,[{128,116},{113,139}]}
-%% 6> F(4, 1024).
+%% 6> send_one_from_many(4, 1024).
%% {2995290,[{2994022,250},{2994071,80},{200,130},{211,113}]}
-%% 7> F(8, 1024).
+%% 7> send_one_from_many(8, 1024).
%% {8997461,[{8996161,116},
%% {2996471,86},
%% {2996278,116},
@@ -213,7 +128,7 @@ send_from_multiple_clients(_) ->
%% {213,159},
%% {373,173},
%% {376,118}]}
-%% 8> F(8, 1024).
+%% 8> send_one_from_many(8, 1024).
%% {21001891,[{20999968,128},
%% {8997891,172},
%% {8997927,91},
@@ -223,120 +138,279 @@ send_from_multiple_clients(_) ->
%% {117,98},
%% {149,125}]}
%%
-%% This turns out to have been due to SCTP resends as a consequence of
-%% the listener having an insufficient recbuf. Increasing the size
-%% solves the problem.
-%%
-
-send_from_multiple_clients(N, Sz)
- when is_integer(N), 0 < N, is_integer(Sz), 0 < Sz ->
- timer:tc(fun listen/2, [N, <<?MAGIC, 0:Sz/unit:8>>]).
-%% listen/2
-
-listen(N, Bin) ->
+send_multiple(Clients, Msgs, Sz)
+ when is_integer(Clients), 0 < Clients,
+ is_integer(Msgs), 0 < Msgs,
+ is_integer(Sz), 0 < Sz ->
+ T0 = diameter_lib:now(),
+ {S, Res} = timer:tc(fun listen/3, [Clients, Msgs, Sz]),
+ report(T0, Res),
+ Ts = lists:append(Res),
+ Outgoing = [DT || {_,{_,_,DT},{_,_,_},_} <- Ts],
+ Incoming = [DT || {_,{_,_,_},{_,_,DT},_} <- Ts],
+ Diffs = [lists:max(L) - lists:min(L) || L <- [Outgoing, Incoming]],
+ {S,
+ S < ?FOREVER*1000,
+ Diffs,
+ [D < V || V <- [?VARIANCE*1000], D <- Diffs],
+ [T || T <- Ts, [] == [T || {_,{_,_,_},{_,_,_},_} <- [T]]],
+ Res}.
+
+%% listen/3
+
+listen(Clients, Msgs, Sz) ->
{ok, Sock} = open(),
ok = gen_sctp:listen(Sock, true),
{ok, PortNr} = inet:port(Sock),
%% Spawn a middleman that in turn spawns N connecting processes,
%% collects a list of exit reasons and then exits with the list as
- %% reason. loop/3 returns when we receive this list from the
+ %% reason. accept/2 returns when we receive this list from the
%% middleman's 'DOWN'.
Self = self(),
- Fun = fun() -> exit(connect2(Self, PortNr, Bin)) end,
- {_, MRef} = spawn_monitor(fun() -> exit(fold(N, Fun)) end),
- loop(Sock, MRef, Bin).
+ Fun = fun() -> exit(client(Self, PortNr, Msgs, Sz)) end, %% start clients
+ {_, MRef} = spawn_monitor(fun() -> exit(clients(Clients, Fun)) end),
+ accept_loop(Sock, MRef).
-%% fold/2
+%% fclients/2
%%
%% Spawn N processes and collect their exit reasons in a list.
-fold(N, Fun) ->
+clients(N, Fun) ->
start(N, Fun),
acc(N, []).
+%% start/2
+
start(0, _) ->
ok;
+
start(N, Fun) ->
spawn_monitor(Fun),
start(N-1, Fun).
+%% acc/2
+
acc(0, Acc) ->
Acc;
+
acc(N, Acc) ->
receive
{'DOWN', _MRef, process, _, RC} ->
acc(N-1, [RC | Acc])
end.
-%% loop/3
+%% accept_loop/2
-loop(Sock, MRef, Bin) ->
+accept_loop(Sock, MRef) ->
+ ok = inet:setopts(Sock, [{active, once}]),
receive
- ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], B})
- when is_binary(B) ->
- Sz = size(Bin),
- {Sz, Bin} = {size(B), B}, %% assert
- ok = send(Sock, Id, mark(Bin)),
- loop(Sock, MRef, Bin);
+ ?SCTP(Sock, {_, #sctp_assoc_change{state = comm_up,
+ outbound_streams = OS,
+ assoc_id = Id}}) ->
+ Self = self(),
+ TPid = spawn(fun() -> assoc(monitor(process, Self), Id, OS) end),
+ NewSock = peeloff(Sock, Id, TPid),
+ TPid ! {peeloff, NewSock},
+ accept_loop(Sock, MRef);
?SCTP(Sock, _) ->
- loop(Sock, MRef, Bin);
+ accept_loop(Sock, MRef);
{'DOWN', MRef, process, _, Reason} ->
- Reason
+ Reason;
+ T ->
+ error(T)
end.
-%% connect2/3
+%% assoc/3
+%%
+%% Server process that answers incoming messages as long as the parent
+%% lives.
+
+assoc(MRef, _Id, OS)
+ when is_reference(MRef) ->
+ {peeloff, Sock} = receive T -> T end,
+ recv_loop(Sock, false, sender(Sock, false, OS), MRef).
+
+%% recv_loop/4
+
+recv_loop(Sock, Id, Pid, MRef) ->
+ ok = inet:setopts(Sock, [{active, once}]),
+ recv(Sock, Id, Pid, MRef, receive T -> T end).
+
+%% recv/5
+
+%% Association id can change on a peeloff socket on some versions of
+%% Solaris.
+recv(Sock,
+ false,
+ Pid,
+ MRef,
+ ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], _})
+ = T) ->
+ Pid ! {assoc_id, Id},
+ recv(Sock, Id, Pid, MRef, T);
+
+recv(Sock, Id, Pid, MRef, ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = I}], B}))
+ when is_binary(B) ->
+ T2 = diameter_lib:now(),
+ Id = I, %% assert
+ <<?MAGIC, Bin/binary>> = B, %% assert
+ {[_,_,_,Sz] = L, Bytes} = unmark(Bin),
+ Sz = size(Bin) - Bytes, %% assert
+ <<_:Bytes/binary, Body:Sz/binary>> = Bin,
+ send(Pid, [T2|L], Body), %% answer
+ recv_loop(Sock, Id, Pid, MRef);
+
+recv(Sock, Id, Pid, MRef, ?SCTP(Sock, _)) ->
+ recv_loop(Sock, Id, Pid, MRef);
+
+recv(_, _, _, MRef, {'DOWN', MRef, process, _, Reason}) ->
+ Reason;
+
+recv(_, _, _, _, T) ->
+ error(T).
-connect2(Pid, PortNr, Bin) ->
- monitor(process, Pid),
+%% send/3
- {ok, Sock} = open(),
- ok = gen_sctp:connect_init(Sock, ?ADDR, PortNr, []),
- Id = assoc(Sock),
+send(Pid, Header, Body) ->
+ Pid ! {send, Header, Body}.
- %% T1 = time before send
- %% T2 = time after listening process received our message
- %% T3 = time after reply is received
+%% sender/3
+%%
+%% Start a process that sends, so as not to block the controlling process.
- T1 = diameter_lib:now(),
- ok = send(Sock, Id, Bin),
- T2 = unmark(recv(Sock, Id)),
- T3 = diameter_lib:now(),
- {diameter_lib:micro_diff(T2, T1), %% Outbound
- diameter_lib:micro_diff(T3, T2)}. %% Inbound
+sender(Sock, Id, OS) ->
+ Pid = self(),
+ spawn(fun() -> send_loop(Sock, Id, OS, 1, monitor(process, Pid)) end).
-%% recv/2
+%% send_loop/5
-recv(Sock, Id) ->
+send_loop(Sock, Id, OS, N, MRef) ->
receive
- ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = I}], Bin})
- when is_binary(Bin) ->
- Id = I, %% assert
- Bin;
- ?SCTP(S, _) ->
- Sock = S, %% assert
- recv(Sock, Id);
+ {assoc_id, I} ->
+ send_loop(Sock, I, OS, N, MRef);
+ {send, L, Body} ->
+ Stream = N rem OS,
+ ok = send(Sock, Id, Stream, mark(Body, [N, Stream | L])),
+ send_loop(Sock, Id, OS, N+1, MRef);
+ {'DOWN', MRef, process, _, _} = T ->
+ T;
T ->
- exit(T)
+ error(T)
end.
-%% send/3
+%% peeloff/3
+
+peeloff(LSock, Id, TPid) ->
+ {ok, Sock} = gen_sctp:peeloff(LSock, Id),
+ ok = gen_sctp:controlling_process(Sock, TPid),
+ Sock.
+
+%% client/4
+
+client(Pid, PortNr, Msgs, Sz) ->
+ monitor(process, Pid),
+ {ok, Sock} = open(),
+ ok = gen_sctp:connect_init(Sock, ?ADDR, PortNr, []),
+ recv_loop(Sock, Msgs, Sz).
-send(Sock, Id, Bin) ->
- gen_sctp:send(Sock, Id, 0, Bin).
+%% recv_loop/3
-%% mark/1
+recv_loop(_, 0, T) ->
+ [_,_|Acc] = T,
+ Acc;
+
+recv_loop(Sock, Msgs, T) ->
+ ok = inet:setopts(Sock, [{active, once}]),
+ {I, NewT} = recv(Sock, Msgs, T, receive X -> X end),
+ recv_loop(Sock, Msgs - I, NewT).
+
+%% recv/4
+
+recv(Sock, Msgs, Sz, ?SCTP(Sock, {_, #sctp_assoc_change{} = A})) ->
+ #sctp_assoc_change{state = comm_up, %% assert
+ assoc_id = Id,
+ outbound_streams = OS}
+ = A,
+ true = is_integer(Sz), %% assert
+ send_n(Msgs, sender(Sock, Id, OS), Sz),
+ {0, [Id, OS]};
+
+recv(Sock, _, T, ?SCTP(Sock, {[#sctp_sndrcvinfo{assoc_id = Id}], Bin})) ->
+ T4 = diameter_lib:now(),
+ [Id, OS | Acc] = T,
+ {1, [Id, OS, stat(T4, Bin) | Acc]};
+
+recv(Sock, _, T, ?SCTP(Sock, _)) ->
+ {0, [_,_|_] = T};
+
+recv(_, _, _, T) ->
+ error(T).
+
+%% send_n/3
+%%
+%% Send messages to the server from dedicated processes.
+
+send_n(0, _, _) ->
+ ok;
-mark(Bin) ->
- Info = term_to_binary(diameter_lib:now()),
+send_n(N, Pid, Sz) ->
+ M = rand:uniform(255),
+ send(Pid, [Sz], binary:copy(<<M>>, Sz)),
+ send_n(N-1, Pid, Sz).
+
+%% send/4
+
+send(Sock, Id, Stream, Bin) ->
+ case gen_sctp:send(Sock, Id, Stream, <<?MAGIC, Bin/binary>>) of
+ {error, eagain} ->
+ send(Sock, Id, Stream, Bin);
+ RC ->
+ RC
+ end.
+
+%% stat/2
+
+stat(T4, <<?MAGIC, Bin/binary>>) ->
+ %% T1 = time at send
+ %% T2 = time at reception by server
+ %% T3 = time at reception by server's sender
+ %% T4 = time at reception of answer
+
+ {[T3,NI,SI,T2,T1,NO,SO,Sz], Bytes} = unmark(Bin),
+
+ Sz = size(Bin) - Bytes, %% assert
+
+ {T1,
+ {NO, SO, diameter_lib:micro_diff(T2, T1)}, %% Outbound
+ {NI, SI, diameter_lib:micro_diff(T4, T3)}, %% Inbound
+ T4}.
+
+%% mark/2
+
+mark(Bin, T) ->
+ Info = term_to_binary([diameter_lib:now() | T]),
<<Info/binary, Bin/binary>>.
%% unmark/1
unmark(Bin) ->
- binary_to_term(Bin).
+ T = binary_to_term(Bin),
+ {T, size(term_to_binary(T))}.
+
+%% ===========================================================================
+
+%% send_many_from_one/0
+%%
+%% Demonstrates sluggish delivery of messages.
+
+send_many_from_one() ->
+ [{timetrap, {seconds, 30}}].
+
+send_many_from_one(_) ->
+ ?OK = send_multiple(1, 128, 1024).
%% ===========================================================================
@@ -345,7 +419,7 @@ unmark(Bin) ->
%% Demonstrates reception of a message that differs from that sent.
receive_what_was_sent(_Config) ->
- send_from_multiple_clients(1, 1024*32). %% fails
+ ?OK = send_multiple(1, 1, 1024*32).
%% ===========================================================================
@@ -357,16 +431,23 @@ open() ->
%% open/1
open(Opts) ->
- gen_sctp:open([{ip, ?ADDR}, {port, 0}, {active, true}, binary,
+ gen_sctp:open([{ip, ?ADDR}, {port, 0}, {active, false}, binary,
+ {sctp_initmsg, #sctp_initmsg{num_ostreams = ?STREAMS,
+ max_instreams = ?STREAMS}},
{recbuf, 1 bsl 16}, {sndbuf, 1 bsl 16}
| Opts]).
-%% assoc/1
+%% report/2
-assoc(Sock) ->
- receive
- ?SCTP(Sock, {_, #sctp_assoc_change{state = S,
- assoc_id = Id}}) ->
- comm_up = S, %% assert
- Id
- end.
+report(T0, Ts) ->
+ ct:pal("~p~n", [lists:sort([sort([{diameter_lib:micro_diff(T1,T0),
+ OT,
+ IT,
+ diameter_lib:micro_diff(T4,T0)}
+ || {T1,OT,IT,T4} <- L])
+ || L <- Ts])]).
+
+%% sort/1
+
+sort(L) ->
+ lists:sort(fun({_,{N,_,_},_,_}, {_,{M,_,_},_,_}) -> N =< M end, L).
diff --git a/lib/diameter/test/diameter_gen_tcp_SUITE.erl b/lib/diameter/test/diameter_gen_tcp_SUITE.erl
index 2be2cf4b35..db42ea813e 100644
--- a/lib/diameter/test/diameter_gen_tcp_SUITE.erl
+++ b/lib/diameter/test/diameter_gen_tcp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2014-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -54,7 +54,7 @@ all() ->
send_long(_) ->
{Sock, SendF} = connection(),
- B = list_to_binary(lists:duplicate(1 bsl 20, $X)),
+ B = binary:copy(<<$X>>, 1 bsl 20),
ok = SendF(B),
B = recv(Sock, size(B), []).
diff --git a/lib/diameter/test/diameter_pool_SUITE.erl b/lib/diameter/test/diameter_pool_SUITE.erl
index eadb354a1d..97c16940ff 100644
--- a/lib/diameter/test/diameter_pool_SUITE.erl
+++ b/lib/diameter/test/diameter_pool_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -115,7 +115,7 @@ connect(ClientProt, ServerProt) ->
%% 'up' events. (Although it's likely.)
sleep(),
{9,5} = count("server", LRef, accept), %% 5 connections + 4 accepting
- %% Ensure ther are still the expected number of accepting transports
+ %% Ensure there are still the expected number of accepting transports
%% after stopping the client service.
ok = diameter:stop_service("client"),
sleep(),
diff --git a/lib/diameter/test/diameter_relay_SUITE.erl b/lib/diameter/test/diameter_relay_SUITE.erl
index b5e520e642..9de5cbe685 100644
--- a/lib/diameter/test/diameter_relay_SUITE.erl
+++ b/lib/diameter/test/diameter_relay_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -302,7 +302,7 @@ stats(?RELAY1, L) ->
%% RAR x 2 (send_timeout_[12])
{{{0,257,0},recv},3}, %% CEA
{{{0,257,0},send},1}, %% "
- {{{0,257,1},recv},1}, %% CER
+ {{{0,257,1},recv},1}, %% CER
{{{0,257,1},send},3}, %% "
{{{relay,0},recv,{'Result-Code',2001}},2}, %% STA x 2 (send[34])
{{{relay,0},recv,{'Result-Code',3005}},1}, %% ASA (send_loop)
diff --git a/lib/diameter/test/diameter_traffic_SUITE.erl b/lib/diameter/test/diameter_traffic_SUITE.erl
index 6f3a4801ee..84b41f14b7 100644
--- a/lib/diameter/test/diameter_traffic_SUITE.erl
+++ b/lib/diameter/test/diameter_traffic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,6 +27,8 @@
-export([suite/0,
all/0,
groups/0,
+ init_per_suite/1,
+ end_per_suite/1,
init_per_group/2,
end_per_group/2,
init_per_testcase/2,
@@ -90,7 +92,6 @@
send_multiple_filters_2/1,
send_multiple_filters_3/1,
send_anything/1,
- outstanding/1,
remove_transports/1,
empty/1,
stop_services/1,
@@ -106,6 +107,9 @@
handle_error/6,
handle_request/3]).
+%% diameter_{tcp,sctp} callbacks
+-export([message/3]).
+
-include("diameter.hrl").
-include("diameter_gen_base_rfc3588.hrl").
-include("diameter_gen_base_accounting.hrl").
@@ -145,21 +149,29 @@
%% Whether to decode stringish Diameter types to strings, or leave
%% them as binary.
--define(STRING_DECODES, [true, false]).
+-define(STRING_DECODES, [false, true]).
%% Which transport protocol to use.
-define(TRANSPORTS, [tcp, sctp]).
+%% Send from a dedicated process?
+-define(SENDERS, [true, false]).
+
+%% Message callbacks from diameter_{tcp,sctp}?
+-define(CALLBACKS, [true, false]).
+
-record(group,
{transport,
+ strings,
client_service,
client_encoding,
client_dict0,
- client_strings,
+ client_sender,
server_service,
server_encoding,
server_container,
- server_strings}).
+ server_sender,
+ server_throttle}).
%% Not really what we should be setting unless the message is sent in
%% the common application but diameter doesn't care.
@@ -190,8 +202,7 @@
{'Acct-Application-Id', [?DIAMETER_APP_ID_ACCOUNTING]},
{restrict_connections, false},
{string_decode, Decode},
- {incoming_maxlen, 1 bsl 21},
- {spawn_opt, [{min_heap_size, 5000}]}
+ {incoming_maxlen, 1 bsl 21}
| [{application, [{dictionary, D},
{module, ?MODULE},
{answer_errors, callback}]}
@@ -243,79 +254,128 @@ suite() ->
[{timetrap, {seconds, 10}}].
all() ->
- [start, result_codes, {group, traffic}, outstanding, empty, stop].
+ [start, result_codes, {group, traffic}, empty, stop].
groups() ->
- Ts = tc(),
- Sctp = ?util:have_sctp(),
- [{?util:name([R,D,A,C]), [parallel], Ts} || R <- ?ENCODINGS,
- D <- ?RFCS,
- A <- ?ENCODINGS,
- C <- ?CONTAINERS]
+ [{P, [P], Ts} || Ts <- [tc(tc())], P <- [shuffle, parallel]]
++
- [{?util:name([T,R,D,A,C,SD,CD]),
+ [{?util:name([T,R,D,A,C,S,SS,ST,CS]),
[],
- [start_services,
- add_transports,
- result_codes,
- {group, ?util:name([R,D,A,C])},
- remove_transports,
- stop_services]}
+ [{group, if S -> shuffle; not S -> parallel end}]}
|| T <- ?TRANSPORTS,
- T /= sctp orelse Sctp,
R <- ?ENCODINGS,
D <- ?RFCS,
A <- ?ENCODINGS,
C <- ?CONTAINERS,
- SD <- ?STRING_DECODES,
- CD <- ?STRING_DECODES]
+ S <- ?STRING_DECODES,
+ SS <- ?SENDERS,
+ ST <- ?CALLBACKS,
+ CS <- ?SENDERS]
++
- [{traffic, [], [{group, ?util:name([T,R,D,A,C,SD,CD])}
- || T <- ?TRANSPORTS,
- T /= sctp orelse Sctp,
- R <- ?ENCODINGS,
- D <- ?RFCS,
- A <- ?ENCODINGS,
- C <- ?CONTAINERS,
- SD <- ?STRING_DECODES,
- CD <- ?STRING_DECODES]}].
+ [{T, [], groups([[T,R,D,A,C,S,SS,ST,CS]
+ || R <- ?ENCODINGS,
+ D <- ?RFCS,
+ A <- ?ENCODINGS,
+ C <- ?CONTAINERS,
+ S <- ?STRING_DECODES,
+ SS <- ?SENDERS,
+ ST <- ?CALLBACKS,
+ CS <- ?SENDERS,
+ SS orelse CS])} %% avoid deadlock
+ || T <- ?TRANSPORTS]
+ ++
+ [{traffic, [], [{group, T} || T <- ?TRANSPORTS]}].
+
+%groups(_) -> %% debug
+% Name = [sctp,record,rfc6733,record,pkt,false,false,false,false],
+% [{group, ?util:name(Name)}];
+groups(Names) ->
+ [{group, ?util:name(L)} || L <- Names].
+
+%tc([N|_]) -> %% debug
+% [N];
+tc(L) ->
+ L.
+
+%% --------------------
+
+init_per_suite(Config) ->
+ [{sctp, ?util:have_sctp()} | Config].
+
+end_per_suite(_Config) ->
+ ok.
+
+%% --------------------
+
+init_per_group(Name, Config)
+ when Name == shuffle;
+ Name == parallel ->
+ start_services(Config),
+ add_transports(Config);
+
+init_per_group(sctp = Name, Config) ->
+ {_, Sctp} = lists:keyfind(Name, 1, Config),
+ if Sctp ->
+ Config;
+ true ->
+ {skip, Name}
+ end;
init_per_group(Name, Config) ->
case ?util:name(Name) of
- [T,R,D,A,C,SD,CD] ->
+ [T,R,D,A,C,S,SS,ST,CS] ->
G = #group{transport = T,
+ strings = S,
client_service = [$C|?util:unique_string()],
client_encoding = R,
client_dict0 = dict0(D),
- client_strings = CD,
+ client_sender = CS,
server_service = [$S|?util:unique_string()],
server_encoding = A,
server_container = C,
- server_strings = SD},
- [{group, G} | Config];
+ server_sender = SS,
+ server_throttle = ST},
+ %% Limit the number of testcase, since the number of
+ %% groups is large.
+ All = ?util:scramble(tc()),
+ TCs = lists:sublist(All, rand:uniform(32)),
+ [{group, G}, {runlist, TCs} | Config];
_ ->
Config
end.
+end_per_group(Name, Config)
+ when Name == shuffle;
+ Name == parallel ->
+ remove_transports(Config),
+ stop_services(Config);
+
end_per_group(_, _) ->
ok.
+%% --------------------
+
%% Skip testcases that can reasonably fail under SCTP.
init_per_testcase(Name, Config) ->
- case [skip || #group{transport = sctp}
- <- [proplists:get_value(group, Config)],
- send_maxlen == Name
- orelse send_long == Name]
+ TCs = proplists:get_value(runlist, Config, []),
+ Run = [] == TCs orelse lists:member(Name, TCs),
+ case [G || #group{transport = sctp} = G
+ <- [proplists:get_value(group, Config)]]
of
- [skip] ->
+ [_] when Name == send_maxlen;
+ Name == send_long ->
{skip, sctp};
- [] ->
+ _ when not Run ->
+ {skip, random};
+ _ ->
[{testcase, Name} | Config]
end.
end_per_testcase(_, _) ->
ok.
+%% --------------------
+
%% Testcases to run when services are started and connections
%% established.
tc() ->
@@ -380,28 +440,34 @@ start(_Config) ->
ok = diameter:start().
start_services(Config) ->
- #group{client_service = CN,
- client_strings = CD,
- server_service = SN,
- server_strings = SD}
+ #group{strings = S,
+ client_service = CN,
+ server_service = SN}
= group(Config),
- ok = diameter:start_service(SN, ?SERVICE(SN, SD)),
+ ok = diameter:start_service(SN, ?SERVICE(SN, S)),
ok = diameter:start_service(CN, [{sequence, ?CLIENT_MASK}
- | ?SERVICE(CN, CD)]).
+ | ?SERVICE(CN, S)]).
add_transports(Config) ->
#group{transport = T,
client_service = CN,
- server_service = SN}
- = group(Config),
+ client_sender = CS,
+ server_service = SN,
+ server_sender = SS,
+ server_throttle = ST}
+ = group(Config),
LRef = ?util:listen(SN,
- T,
+ [T,
+ {sender, SS},
+ {message_cb, ST andalso {?MODULE, message, [4]}}
+ | [{packet, hd(?util:scramble([false, raw]))}
+ || T == sctp andalso CS]],
[{capabilities_cb, fun capx/2},
{pool_size, 8},
- {spawn_opt, [{min_heap_size, 8096}]},
- {applications, apps(rfc3588)}]),
+ {applications, apps(rfc3588)}]
+ ++ [{spawn_opt, {erlang, spawn, []}} || CS]),
Cs = [?util:connect(CN,
- T,
+ [T, {sender, CS}],
LRef,
[{id, Id},
{capabilities, [{'Origin-State-Id', origin(Id)}]},
@@ -418,11 +484,6 @@ apps(D0) ->
D = dict0(D0),
[acct(D), D].
-%% Ensure there are no outstanding requests in request table.
-outstanding(_Config) ->
- [] = [T || T <- ets:tab2list(diameter_request),
- is_atom(element(1,T))].
-
remove_transports(Config) ->
#group{client_service = CN,
server_service = SN}
@@ -692,14 +753,14 @@ send_unexpected_mandatory(Config) ->
%% Send something long that will be fragmented by TCP.
send_long(Config) ->
Req = ['STR', {'Termination-Cause', ?LOGOUT},
- {'User-Name', [lists:duplicate(1 bsl 20, $X)]}],
+ {'User-Name', [binary:copy(<<$X>>, 1 bsl 20)]}],
['STA', {'Session-Id', _}, {'Result-Code', ?SUCCESS} | _]
= call(Config, Req).
%% Send something longer than the configure incoming_maxlen.
send_maxlen(Config) ->
Req = ['STR', {'Termination-Cause', ?LOGOUT},
- {'User-Name', [lists:duplicate(1 bsl 21, $X)]}],
+ {'User-Name', [binary:copy(<<$X>>, 1 bsl 21)]}],
{timeout, _} = call(Config, Req).
%% Send something for which pick_peer finds no suitable peer.
@@ -878,7 +939,7 @@ group(Config) ->
#group{} = proplists:get_value(group, Config).
string(V, Config) ->
- #group{client_strings = B} = group(Config),
+ #group{strings = B} = group(Config),
decode(V,B).
decode(S, true)
@@ -998,7 +1059,7 @@ pick_peer(Peers, _, [$C|_], _State, {send_detach, Group}, _, {_,_}) ->
find(#group{client_service = CN,
server_encoding = A,
server_container = C},
- Peers) ->
+ [_|_] = Peers) ->
Id = {A,C},
[P] = [P || P <- Peers, id(Id, P, CN)],
{ok, P}.
@@ -1432,3 +1493,33 @@ request(#diameter_base_STR{'Session-Id' = SId},
%% send_error/send_timeout
request(#diameter_base_RAR{}, _Caps) ->
receive after 2000 -> {protocol_error, ?TOO_BUSY} end.
+
+%% message/3
+%%
+%% Limit the number of messages received. More can be received if read
+%% in the same packet.
+
+message(recv = D, {[_], Bin}, N) ->
+ message(D, Bin, N);
+message(Dir, #diameter_packet{bin = Bin}, N) ->
+ message(Dir, Bin, N);
+
+%% incoming request
+message(recv, <<_:32, 1, _/bits>> = Bin, N) ->
+ [Bin, 1 < N, fun ?MODULE:message/3, N-1];
+
+%% incoming answer
+message(recv, Bin, _) ->
+ [Bin];
+
+%% outgoing
+message(send, Bin, _) ->
+ [Bin];
+
+%% sent request
+message(ack, <<_:32, 1, _/bits>>, _) ->
+ [];
+
+%% sent answer or discarded request
+message(ack, _, N) ->
+ [0 =< N, fun ?MODULE:message/3, N+1].
diff --git a/lib/diameter/test/diameter_transport_SUITE.erl b/lib/diameter/test/diameter_transport_SUITE.erl
index c94f46b7a5..9d981d0a2b 100644
--- a/lib/diameter/test/diameter_transport_SUITE.erl
+++ b/lib/diameter/test/diameter_transport_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -294,10 +294,17 @@ init(gen_accept, {Prot, Ref}) ->
{ok, PortNr} = inet:port(LSock),
true = diameter_reg:add_new(?TEST_LISTENER(Ref, PortNr)),
- %% Accept a connection, receive a message and send it back.
+ %% Accept a connection, receive a message send it back, and wait
+ %% for the peer to close the connection.
{ok, Sock} = gen_accept(Prot, LSock),
Bin = gen_recv(Prot, Sock),
- ok = gen_send(Prot, Sock, Bin);
+ ok = gen_send(Prot, Sock, Bin),
+ receive
+ {tcp_closed, Sock} = T ->
+ T;
+ ?SCTP(Sock, {_, #sctp_assoc_change{}}) = T ->
+ T
+ end;
init(connect, {Prot, Ref}) ->
%% Lookup the peer's listening socket.
@@ -311,12 +318,7 @@ init(connect, {Prot, Ref}) ->
%% Send a message and receive it back.
Bin = make_msg(),
TPid ! ?TMSG({send, Bin}),
- Bin = bin(Prot, ?RECV(?TMSG({recv, P}), P)),
-
- %% Expect the transport process to die as a result of the peer
- %% closing the connection.
- MRef = erlang:monitor(process, TPid),
- ?RECV({'DOWN', MRef, process, _, _}).
+ Bin = bin(Prot, ?RECV(?TMSG({recv, P}), P)).
bin(sctp, #diameter_packet{bin = Bin}) ->
Bin;
@@ -336,15 +338,11 @@ make_msg() ->
<<1:8, Len:24, Bin/binary>>.
%% crypto:rand_bytes/1 isn't available on all platforms (since openssl
-%% isn't) so roll our own.
+%% isn't) so roll our own. Not particularly random, but less verbose
+%% in trace.
rand_bytes(N) ->
- rand_bytes(N, <<>>).
-
-rand_bytes(0, Bin) ->
- Bin;
-rand_bytes(N, Bin) ->
Oct = rand:uniform(256) - 1,
- rand_bytes(N-1, <<Oct, Bin/binary>>).
+ binary:copy(<<Oct>>, N).
%% ===========================================================================
diff --git a/lib/diameter/test/diameter_util.erl b/lib/diameter/test/diameter_util.erl
index 37fcbbc267..03f79096ac 100644
--- a/lib/diameter/test/diameter_util.erl
+++ b/lib/diameter/test/diameter_util.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -172,18 +172,7 @@ recvl([{MRef, F} | L], Ref, Fun, Acc) ->
%% Sort a list into random order.
scramble(L) ->
- foldl(fun(true, _, S, false) -> S end,
- false,
- [[fun s/1, L]]).
-
-s(L) ->
- s([], L).
-
-s(Acc, []) ->
- Acc;
-s(Acc, L) ->
- {H, [T|Rest]} = lists:split(rand:uniform(length(L)) - 1, L),
- s([T|Acc], H ++ Rest).
+ [X || {_,X} <- lists:sort([{rand:uniform(), T} || T <- L])].
%% ---------------------------------------------------------------------------
%% unique_string/0
@@ -195,6 +184,15 @@ unique_string() ->
%% have_sctp/0
have_sctp() ->
+ have_sctp(erlang:system_info(system_architecture)).
+
+%% Don't run SCTP on platforms where it's either known to be flakey or
+%% isn't available.
+
+have_sctp("sparc-sun-solaris2.10") ->
+ false;
+
+have_sctp(_) ->
case gen_sctp:open() of
{ok, Sock} ->
gen_sctp:close(Sock),
@@ -305,17 +303,23 @@ listen(SvcName, Prot, Opts) ->
connect(Client, Prot, LRef) ->
connect(Client, Prot, LRef, []).
-connect(Client, Prot, LRef, Opts) ->
+connect(Client, ProtOpts, LRef, Opts) ->
+ Prot = head(ProtOpts),
[PortNr] = lport(Prot, LRef),
Client = diameter:service_info(Client, name), %% assert
true = diameter:subscribe(Client),
- Ref = add_transport(Client, {connect, opts(Prot, PortNr) ++ Opts}),
+ Ref = add_transport(Client, {connect, opts(ProtOpts, PortNr) ++ Opts}),
true = transport(Client, Ref), %% assert
diameter_lib:for_n(fun(_) -> ok = up(Client, Ref, Prot, PortNr) end,
proplists:get_value(pool_size, Opts, 1)),
Ref.
+head([T|_]) ->
+ T;
+head(T) ->
+ T.
+
up(Client, Ref, Prot, PortNr) ->
receive
{diameter_event, Client, {up, Ref, _, _, _}} -> ok
@@ -358,10 +362,13 @@ tmod(sctp) ->
tmod(any) ->
[diameter_sctp, diameter_tcp].
-opts(Prot, T) ->
- tmo(T, lists:append([[{transport_module, M}, {transport_config, C}]
+opts([Prot | Opts], T) ->
+ tmo(T, lists:append([[{transport_module, M}, {transport_config, C ++ Opts}]
|| M <- tmod(Prot),
- C <- [cfg(M,T) ++ cfg(M) ++ cfg(T)]])).
+ C <- [cfg(M,T) ++ cfg(M) ++ cfg(T)]]));
+
+opts(Prot, T) ->
+ opts([Prot], T).
tmo(listen, Opts) ->
Opts;
diff --git a/lib/diameter/test/diameter_watchdog_SUITE.erl b/lib/diameter/test/diameter_watchdog_SUITE.erl
index 6d22ddcc18..39c4f051a5 100644
--- a/lib/diameter/test/diameter_watchdog_SUITE.erl
+++ b/lib/diameter/test/diameter_watchdog_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -44,13 +44,8 @@
-export([peer_up/3,
peer_down/3]).
-%% gen_tcp-ish interface
--export([listen/2,
- accept/1,
- connect/3,
- send/2,
- setopts/2,
- close/1]).
+%% diameter_tcp message_cb
+-export([message/3]).
-include("diameter.hrl").
-include("diameter_ct.hrl").
@@ -161,9 +156,9 @@ reopen(Type, Test, Ref, Wd, N, M) ->
reopen(Type, Test, SvcName, TRef, Wd, N, M).
cfg(Type, Type, Wd) ->
- {Wd, [], []};
+ {Wd, [], false};
cfg(_Type, _Test, _Wd) ->
- {?WD(?PEER_WD), [{okay, 0}], [{module, ?MODULE}]}.
+ {?WD(?PEER_WD), [{okay, 0}], true}.
%% reopen/7
@@ -346,7 +341,7 @@ recv_reopen(listen, Ref) ->
%% reg/3
%%
%% Lookup the pid of the transport process and publish a term for
-%% send/2 to lookup.
+%% message/3 to lookup.
reg(TRef, SvcName, T) ->
TPid = tpid(TRef, diameter:service_info(SvcName, transport)),
true = diameter_reg:add_new({?MODULE, TPid, T}).
@@ -394,7 +389,7 @@ suspect(_) ->
suspect(Type, Fake, Ref, N)
when is_reference(Ref) ->
{SvcName, TRef}
- = start(Type, Ref, {?WD(10000), [{suspect, N}], mod(Fake)}),
+ = start(Type, Ref, {?WD(10000), [{suspect, N}], Fake}),
{initial, okay} = ?WD_EVENT(TRef),
suspect(TRef, Fake, SvcName, N);
@@ -436,11 +431,6 @@ abuse([F|A], Test) ->
abuse(F, Test) ->
abuse([F], Test).
-mod(true) ->
- [{module, ?MODULE}];
-mod(false) ->
- [].
-
%% ===========================================================================
%% # okay/1
%% ===========================================================================
@@ -456,7 +446,7 @@ okay(Type, Fake, Ref, N)
{SvcName, TRef}
= start(Type, Ref, {?WD(10000),
[{okay, choose(Fake, 0, N)}],
- mod(Fake)}),
+ Fake}),
{initial, okay} = ?WD_EVENT(TRef),
okay(TRef,
Fake,
@@ -515,12 +505,17 @@ start(Type, Ref, T) ->
true = diameter_reg:add_new({Type, Ref, Name}),
{Name, TRef}.
-opts(Type, Ref, {Timer, Config, Mod}) ->
+opts(Type, Ref, {Timer, Config, Fake})
+ when is_boolean(Fake) ->
[{transport_module, diameter_tcp},
- {transport_config, Mod ++ [{ip, ?ADDR}, {port, 0}] ++ cfg(Type, Ref)},
+ {transport_config, mod(Fake) ++ [{ip, ?ADDR}, {port, 0}]
+ ++ cfg(Type, Ref)},
{watchdog_timer, Timer},
{watchdog_config, Config}].
+mod(B) ->
+ [{message_cb, [fun message/3, capx]} || B].
+
cfg(listen, _) ->
[];
cfg(connect, Ref) ->
@@ -531,37 +526,29 @@ cfg(connect, Ref) ->
%% ===========================================================================
-listen(PortNr, Opts) ->
- gen_tcp:listen(PortNr, Opts).
-
-accept(LSock) ->
- gen_tcp:accept(LSock).
+%% message/3
-connect(Addr, Port, Opts) ->
- gen_tcp:connect(Addr, Port, Opts).
+message(send, Bin, X) ->
+ send(Bin, X);
-setopts(Sock, Opts) ->
- inet:setopts(Sock, Opts).
+message(recv, Bin, _) ->
+ [Bin];
-send(Sock, Bin) ->
- send(getr(config), Sock, Bin).
-
-close(Sock) ->
- gen_tcp:close(Sock).
+message(_, _, _) ->
+ [].
-%% send/3
+%% send/2
%% First outgoing message from a new transport process is CER/CEA.
%% Remaining outgoing messages are either DWR or DWA.
-send(undefined, Sock, Bin) ->
- <<_:32, _:8, 257:24, _/binary>> = Bin,
- putr(config, init),
- gen_tcp:send(Sock, Bin);
+send(Bin, capx) ->
+ <<_:32, _:8, 257:24, _/binary>> = Bin, %% assert on CER/CEA
+ [Bin, fun message/3, init];
%% Outgoing DWR: fake reception of DWA. Use the fact that AVP values
%% are ignored. This is to ensure that the peer's watchdog state
%% transitions are only induced by responses to messages it sends.
-send(_, Sock, <<_:32, 1:1, _:7, 280:24, _:32, EId:32, HId:32, _/binary>>) ->
+send(<<_:32, 1:1, _:7, 280:24, _:32, EId:32, HId:32, _/binary>>, _) ->
Pkt = #diameter_packet{header = #diameter_header{version = 1,
end_to_end_id = EId,
hop_by_hop_id = HId},
@@ -569,47 +556,36 @@ send(_, Sock, <<_:32, 1:1, _:7, 280:24, _:32, EId:32, HId:32, _/binary>>) ->
{'Origin-Host', "XXX"},
{'Origin-Realm', ?REALM}]},
#diameter_packet{bin = Bin} = diameter_codec:encode(?BASE, Pkt),
- self() ! {tcp, Sock, Bin},
- ok;
+ [recv, Bin];
%% First outgoing DWA.
-send(init, Sock, Bin) ->
+send(Bin, init) ->
[{{?MODULE, _, T}, _}] = diameter_reg:wait({?MODULE, self(), '_'}),
- putr(config, T),
- send(Sock, Bin);
+ send(Bin, T);
%% First transport process.
-send({SvcName, {_,_,_} = T}, Sock, Bin) ->
+send(Bin, {SvcName, {_,_,_} = T}) ->
[{'Origin-Host', _} = OH, {'Origin-Realm', _} = OR | _]
= ?SERVICE(SvcName),
putr(origin, [OH, OR]),
- putr(config, T),
- send(Sock, Bin);
+ send(Bin, T);
%% Discard DWA, failback after another timeout in the peer.
-send({Wd, 0 = No, Msg}, Sock, Bin) ->
+send(Bin, {Wd, 0 = No, Msg}) ->
Origin = getr(origin),
- spawn(fun() -> failback(?ONE_WD(Wd), Msg, Sock, Bin, Origin) end),
- putr(config, No),
- ok;
+ [{defer, ?ONE_WD(Wd), [msg(Msg, Bin, Origin)]}, fun message/3, No];
%% Send DWA while we're in the mood (aka 0 < N).
-send({Wd, N, Msg}, Sock, Bin) ->
- putr(config, {Wd, N-1, Msg}),
- gen_tcp:send(Sock, Bin);
+send(Bin, {Wd, N, Msg}) ->
+ [Bin, fun message/3, {Wd, N-1, Msg}];
%% Discard DWA.
-send(0, _Sock, _Bin) ->
- ok;
+send(_Bin, 0 = No) ->
+ [fun message/3, No];
%% Send DWA.
-send(N, Sock, <<_:32, 0:1, _:7, 280:24, _/binary>> = Bin) ->
- putr(config, N-1),
- gen_tcp:send(Sock, Bin).
-
-failback(Tmo, Msg, Sock, Bin, Origin) ->
- timer:sleep(Tmo),
- ok = gen_tcp:send(Sock, msg(Msg, Bin, Origin)).
+send(<<_:32, 0:1, _:7, 280:24, _/binary>> = DWA, N) ->
+ [DWA, fun message/3, N-1].
%% msg/2
diff --git a/lib/diameter/test/modules.mk b/lib/diameter/test/modules.mk
index 80d0f8d59c..0c73adca12 100644
--- a/lib/diameter/test/modules.mk
+++ b/lib/diameter/test/modules.mk
@@ -1,7 +1,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010-2015. All Rights Reserved.
+# Copyright Ericsson AB 2010-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -31,7 +31,6 @@ MODULES = \
diameter_codec_test \
diameter_config_SUITE \
diameter_compiler_SUITE \
- diameter_dict_SUITE \
diameter_distribution_SUITE \
diameter_dpr_SUITE \
diameter_event_SUITE \
diff --git a/lib/diameter/vsn.mk b/lib/diameter/vsn.mk
index cb750c69a3..4801f542fb 100644
--- a/lib/diameter/vsn.mk
+++ b/lib/diameter/vsn.mk
@@ -1,6 +1,6 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010-2016. All Rights Reserved.
+# Copyright Ericsson AB 2010-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,5 +17,5 @@
# %CopyrightEnd%
APPLICATION = diameter
-DIAMETER_VSN = 1.12
+DIAMETER_VSN = 2.0
APP_VSN = $(APPLICATION)-$(DIAMETER_VSN)$(PRE_VSN)
diff --git a/lib/edoc/COPYING b/lib/edoc/COPYING
deleted file mode 100644
index 223ede7de3..0000000000
--- a/lib/edoc/COPYING
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/lib/edoc/doc/overview.edoc b/lib/edoc/doc/overview.edoc
index d2bba9d744..981320f1fc 100644
--- a/lib/edoc/doc/overview.edoc
+++ b/lib/edoc/doc/overview.edoc
@@ -276,11 +276,11 @@ The following tags can be used before a module declaration:
```%% @author Richard Carlsson'''
```%% @author Richard Carlsson <[email protected]>
- %% [http://user.it.uu.se/~richardc/]'''
+ %% [http://example.net/richardc/]'''
```%% @author <[email protected]>'''
-```%% @author [email protected] [http://user.it.uu.se/~richardc/]'''
+```%% @author [email protected] [http://example.net/richardc/]'''
</dd>
<dt><a name="mtag-copyright">`@copyright'</a></dt>
@@ -377,6 +377,12 @@ The following tags can be used before a function definition:
Useful for debug/test functions, etc. The content can be
used as a comment; it is ignored by EDoc.</dd>
+ <dt><a name="ftag-param">`@param'</a></dt>
+ <dd>Provide more information on a single parameter of the
+ enclosing function. The content consists of a parameter name,
+ followed by one or more whitespace characters, and XHTML text.
+ </dd>
+
<dt><a name="ftag-private">`@private'</a></dt>
<dd>Marks the function as private (i.e., not part of the public
interface), so that it will not appear in the normal
@@ -386,6 +392,10 @@ The following tags can be used before a function definition:
always "private".) The content can be used as a comment; it is
ignored by EDoc.</dd>
+ <dt><a name="ftag-returns">`@returns'</a></dt>
+ <dd>Specify additional information about the value returned by
+ the function. Content consists of XHTML text.</dd>
+
<dt><a name="ftag-see">`@see'</a></dt>
<dd>Make a reference to a module, function, datatype, or
application. (See {@section References}.)
diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml
index ae8147c564..7894811c78 100644
--- a/lib/edoc/doc/src/notes.xml
+++ b/lib/edoc/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2007</year><year>2016</year>
+ <year>2007</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,6 +32,58 @@
<p>This document describes the changes made to the EDoc
application.</p>
+<section><title>Edoc 0.9</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>To support stable builds, <c>edoc</c> no longer
+ includes time stamps in the footer for generated
+ files.</p>
+ <p>
+ Own Id: OTP-14277</p>
+ </item>
+ <item>
+ <p> Miscellaneous updates due to atoms containing
+ arbitrary Unicode characters. </p>
+ <p>
+ Own Id: OTP-14285</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Edoc 0.8.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Document the function tags <c>@param</c> and
+ <c>@returns</c>. </p>
+ <p>
+ Own Id: OTP-13930 Aux Id: PR-1175 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Edoc 0.8</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Improve types and specs in OTP documentation generated
+ from Erlang source files. </p>
+ <p>
+ Own Id: OTP-13720 Aux Id: ERL-120 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Edoc 0.7.19</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/edoc/include/edoc_doclet.hrl b/lib/edoc/include/edoc_doclet.hrl
index ac6763fb33..1429ee5971 100644
--- a/lib/edoc/include/edoc_doclet.hrl
+++ b/lib/edoc/include/edoc_doclet.hrl
@@ -3,20 +3,25 @@
%%
%% Copyright (C) 2001-2004 Richard Carlsson
%%
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% Author contact: [email protected]
%% =====================================================================
diff --git a/lib/edoc/src/edoc.erl b/lib/edoc/src/edoc.erl
index 94013bb5ac..b641118c5d 100644
--- a/lib/edoc/src/edoc.erl
+++ b/lib/edoc/src/edoc.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2001-2007 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -192,7 +197,7 @@ application(App, Dir, Options) when is_atom(App) ->
?OVERVIEW_FILE),
Opts = Options ++ [{source_path, [Src]},
subpackages,
- {title, io_lib:fwrite("The ~s application", [App])},
+ {title, io_lib:fwrite("The ~ts application", [App])},
{overview, Overview},
{dir, filename:join(Dir, ?EDOC_DIR)},
{includes, [filename:join(Dir, "include")]}],
diff --git a/lib/edoc/src/edoc.hrl b/lib/edoc/src/edoc.hrl
index 5b0fb68cf9..1ec64561a1 100644
--- a/lib/edoc/src/edoc.hrl
+++ b/lib/edoc/src/edoc.hrl
@@ -3,20 +3,25 @@
%%
%% Copyright (C) 2001-2004 Richard Carlsson
%%
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% Author contact: [email protected]
%% =====================================================================
diff --git a/lib/edoc/src/edoc_data.erl b/lib/edoc/src/edoc_data.erl
index b797d74a71..7c077d3acd 100644
--- a/lib/edoc/src/edoc_data.erl
+++ b/lib/edoc/src/edoc_data.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2003 Richard Carlsson
diff --git a/lib/edoc/src/edoc_doclet.erl b/lib/edoc/src/edoc_doclet.erl
index 5961ca8cc0..6e17ec0af0 100644
--- a/lib/edoc/src/edoc_doclet.erl
+++ b/lib/edoc/src/edoc_doclet.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2003-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -147,7 +152,7 @@ title(App, Options) ->
if App == ?NO_APP ->
"Overview";
true ->
- io_lib:fwrite("Application: ~s", [App])
+ io_lib:fwrite("Application: ~ts", [App])
end).
diff --git a/lib/edoc/src/edoc_extract.erl b/lib/edoc/src/edoc_extract.erl
index e7a4c36ca4..390851e9ef 100644
--- a/lib/edoc/src/edoc_extract.erl
+++ b/lib/edoc/src/edoc_extract.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2001-2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -32,9 +37,9 @@
%% %% @headerfile "edoc.hrl" (disabled until it can be made private)
-include("edoc.hrl").
-%% @type filename() = file:filename().
-%% @type proplist() = proplists:property().
-%% @type syntaxTree() = erl_syntax:syntaxTree().
+%% @type filename() = //kernel/file:filename().
+%% @type proplist() = //stdlib/proplists:property().
+%% @type syntaxTree() = //syntax_tools/erl_syntax:syntaxTree().
%% @spec source(File::filename(), Env::edoc_env(), Options::proplist())
%% -> {ModuleName, edoc:edoc_module()}
@@ -483,8 +488,15 @@ find_names([P | Ps], Ns) ->
find_names([P1 | Ps], Ns);
record_expr ->
A = erl_syntax:record_expr_type(P),
- N = list_to_atom(capitalize(erl_syntax:atom_name(A))),
- find_names(Ps, [N | Ns]);
+ AtomName = erl_syntax:atom_name(A),
+ Atom = list_to_atom(AtomName),
+ case AtomName =:= lists:flatten(io_lib:write_atom(Atom)) of
+ true ->
+ N = list_to_atom(capitalize(AtomName)),
+ find_names(Ps, [N | Ns]);
+ false ->
+ find_names(Ps, Ns)
+ end;
infix_expr ->
%% this can only be a '++' operation
P1 = erl_syntax:infix_expr_right(P),
@@ -535,6 +547,7 @@ tidy_name_1(Cs) -> [$_ | Cs].
%% Change initial character from lowercase to uppercase.
capitalize([C | Cs]) when C >= $a, C =< $z -> [C - 32 | Cs];
+capitalize([C | Cs]) when C >= $\340, C =< $\376, C /= $\367 -> [C - 32 | Cs];
capitalize(Cs) -> Cs.
%% Collects the tags belonging to each entry, checks them, expands
@@ -639,11 +652,11 @@ file_macros(_Context, Env) ->
%%
%% The idea is to mimic how the @type tag works.
%% Using @type:
-%% @type t() = t1(). Some docs of t/0;
-%% Further docs of t/0.
+%%```@type t() = t1(). Some docs of t/0;
+%% Further docs of t/0.'''
%% The same thing using -type:
-%% -type t() :: t1(). % Some docs of t/0;
-%% Further docs of t/0.
+%%```-type t() :: t1(). % Some docs of t/0;
+%% Further docs of t/0.'''
find_type_docs(Forms0, Comments, Env, File) ->
Tree = erl_recomment:recomment_forms(Forms0, Comments),
Forms = preprocess_forms(Tree),
diff --git a/lib/edoc/src/edoc_layout.erl b/lib/edoc/src/edoc_layout.erl
index ef57b7b084..eafab0588e 100644
--- a/lib/edoc/src/edoc_layout.erl
+++ b/lib/edoc/src/edoc_layout.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2001-2006 Richard Carlsson
@@ -104,14 +109,20 @@ module(Element, Options) ->
stylesheet,
index_columns,
sort_functions,
+ encoding,
pretty_printer}).
init_opts(Element, Options) ->
+ Encoding = case get_attrval(encoding, Element) of
+ "latin1" -> latin1;
+ _ -> utf8
+ end,
R = #opts{root = get_attrval(root, Element),
index_columns = proplists:get_value(index_columns,
Options, 1),
sort_functions = proplists:get_value(sort_functions,
Options, true),
+ encoding = Encoding,
pretty_printer = proplists:get_value(pretty_printer,
Options, '')
},
@@ -178,8 +189,9 @@ layout_module(#xmlElement{name = module, content = Es}=E, Opts) ->
Desc = get_content(description, Es),
ShortDesc = get_content(briefDescription, Desc),
FullDesc = get_content(fullDescription, Desc),
- Functions = [{function_name(E), E} || E <- get_content(functions, Es)],
- Types = [{type_name(E), E} || E <- get_content(typedecls, Es)],
+ Functions = [{function_name(E, Opts), E} ||
+ E <- get_content(functions, Es)],
+ Types = [{type_name(E, Opts), E} || E <- get_content(typedecls, Es)],
SortedFs = if Opts#opts.sort_functions -> lists:sort(Functions);
true -> Functions
end,
@@ -193,7 +205,7 @@ layout_module(#xmlElement{name = module, content = Es}=E, Opts) ->
++ [?NL]
++ version(Es)
++ since(Es)
- ++ behaviours(Es, Name)
+ ++ behaviours(Es, Name, Opts)
++ authors(Es)
++ references(Es)
++ sees(Es)
@@ -209,8 +221,8 @@ layout_module(#xmlElement{name = module, content = Es}=E, Opts) ->
++ functions(SortedFs, Opts)
++ [hr, ?NL]
++ navigation("bottom")
- ++ timestamp()),
- Encoding = get_attrval(encoding, E),
+ ++ footer()),
+ Encoding = Opts#opts.encoding,
xhtml(Title, stylesheet(Opts), Body, Encoding).
module_params(Es) ->
@@ -223,12 +235,8 @@ module_params(Es) ->
[element(1, First) | [ {[", ",A]} || {A, _D} <- Rest]]
end.
-timestamp() ->
- [?NL, {p, [{i, [io_lib:fwrite("Generated by EDoc, ~s, ~s.",
- [edoc_lib:datestr(date()),
- edoc_lib:timestr(time())])
- ]}]},
- ?NL].
+footer() ->
+ [?NL, {p, [{i, ["Generated by EDoc"]}]}, ?NL].
stylesheet(Opts) ->
case Opts#opts.stylesheet of
@@ -366,7 +374,7 @@ function(Name, E=#xmlElement{content = Es}, Opts) ->
case typespec(get_content(typespec, Es), Opts) of
[] ->
signature(get_content(args, Es),
- get_attrval(name, E));
+ atom(get_attrval(name, E), Opts));
Spec -> Spec
end},
?NL]
@@ -386,8 +394,8 @@ function(Name, E=#xmlElement{content = Es}, Opts) ->
++ sees(Es)
++ todos(Es)).
-function_name(E) ->
- atom(get_attrval(name, E)) ++ "/" ++ get_attrval(arity, E).
+function_name(E, Opts) ->
+ atom(get_attrval(name, E), Opts) ++ "/" ++ get_attrval(arity, E).
function_header(Name, E, Private) ->
case is_exported(E) of
@@ -448,7 +456,7 @@ throws(Es, Opts) ->
[] -> [];
Es1 ->
%% Doesn't use format_type; keep it short!
- [{p, (["throws ", {tt, t_utype(get_elem(type, Es1))}]
+ [{p, (["throws ", {tt, t_utype(get_elem(type, Es1), Opts)}]
++ local_defs(get_elem(localdef, Es1), Opts))},
?NL]
end.
@@ -457,7 +465,7 @@ throws(Es, Opts) ->
typespec([], _Opts) -> [];
typespec(Es, Opts) ->
- Name = t_name(get_elem(erlangName, Es)),
+ Name = t_name(get_elem(erlangName, Es), Opts),
Defs = get_elem(localdef, Es),
[Type] = get_elem(type, Es),
format_spec(Name, Type, Defs, Opts) ++ local_defs(Defs, Opts).
@@ -478,12 +486,12 @@ typedecl(Name, E=#xmlElement{content = Es}, Opts) ->
++ [{p, typedef(get_content(typedef, Es), Opts)}, ?NL]
++ fulldesc(Es)).
-type_name(#xmlElement{content = Es}) ->
- t_name(get_elem(erlangName, get_content(typedef, Es))).
+type_name(#xmlElement{content = Es}, Opts) ->
+ t_name(get_elem(erlangName, get_content(typedef, Es)), Opts).
typedef(Es, Opts) ->
- Name = ([t_name(get_elem(erlangName, Es)), "("]
- ++ seq(fun t_utype_elem/1, get_content(argtypes, Es), [")"])),
+ Name = ([t_name(get_elem(erlangName, Es), Opts), "("]
+ ++ seq(t_utype_elem_fun(Opts), get_content(argtypes, Es), [")"])),
(case get_elem(type, Es) of
[] -> [{b, ["abstract datatype"]}, ": ", {tt, Name}];
Type -> format_type(Name, Name, Type, [], Opts)
@@ -504,7 +512,9 @@ local_defs(Es0, Last, Opts) ->
localdef(E = #xmlElement{content = Es}, Last, Opts) ->
Name = case get_elem(typevar, Es) of
[] ->
- label_anchor(N0 = t_abstype(get_content(abstype, Es)), E);
+ label_anchor(N0 = t_abstype(get_content(abstype, Es),
+ Opts),
+ E);
[V] ->
N0 = t_var(V)
end,
@@ -515,97 +525,99 @@ localdef(E = #xmlElement{content = Es}, Last, Opts) ->
%% (fast) Erlang pretty printer).
format_spec(Name, Type, Defs, #opts{pretty_printer = erl_pp}=Opts) ->
try
- L = t_clause(Name, Type),
- O = pp_clause(Name, Type),
- {R, ".\n"} = etypef(L, O),
+ L = t_clause(Name, Type, Opts),
+ O = pp_clause(Name, Type, Opts),
+ {R, ".\n"} = etypef(L, O, Opts),
[{pre, R}]
catch _:_ ->
%% Should not happen.
format_spec(Name, Type, Defs, Opts#opts{pretty_printer=''})
end;
-format_spec(Sep, Type, Defs, _Opts) ->
+format_spec(Sep, Type, Defs, Opts) ->
%% Very limited formatting.
Br = if Defs =:= [] -> br; true -> [] end,
- [{tt, t_clause(Sep, Type)}, Br].
+ [{tt, t_clause(Sep, Type, Opts)}, Br].
-t_clause(Name, Type) ->
+t_clause(Name, Type, Opts) ->
#xmlElement{content = [#xmlElement{name = 'fun', content = C}]} = Type,
- [Name] ++ t_fun(C).
+ [Name] ++ t_fun(C, Opts).
-pp_clause(Pre, Type) ->
+pp_clause(Pre, Type, Opts) ->
Types = ot_utype([Type]),
- Atom = lists:duplicate(iolist_size(Pre), $a),
+ Atom = lists:duplicate(string:length(Pre), $a),
Attr = {attribute,0,spec,{{list_to_atom(Atom),0},[Types]}},
- L1 = erl_pp:attribute(erl_parse:new_anno(Attr)),
+ L1 = erl_pp:attribute(erl_parse:new_anno(Attr),
+ [{encoding, Opts#opts.encoding}]),
"-spec " ++ L2 = lists:flatten(L1),
L3 = Pre ++ lists:nthtail(length(Atom), L2),
- re:replace(L3, "\n ", "\n", [{return,list},global]).
+ re:replace(L3, "\n ", "\n", [{return,list},global,unicode]).
format_type(Prefix, Name, Type, Last, #opts{pretty_printer = erl_pp}=Opts) ->
try
- L = t_utype(Type),
- O = pp_type(Name, Type),
- {R, ".\n"} = etypef(L, O),
+ L = t_utype(Type, Opts),
+ O = pp_type(Name, Type, Opts),
+ {R, ".\n"} = etypef(L, O, Opts),
[{pre, Prefix ++ [" = "] ++ R ++ Last}]
catch _:_ ->
%% Example: "t() = record(a)."
format_type(Prefix, Name, Type, Last, Opts#opts{pretty_printer =''})
end;
-format_type(Prefix, _Name, Type, Last, _Opts) ->
- [{tt, Prefix ++ [" = "] ++ t_utype(Type) ++ Last}].
+format_type(Prefix, _Name, Type, Last, Opts) ->
+ [{tt, Prefix ++ [" = "] ++ t_utype(Type, Opts) ++ Last}].
-pp_type(Prefix, Type) ->
- Atom = list_to_atom(lists:duplicate(iolist_size(Prefix), $a)),
+pp_type(Prefix, Type, Opts) ->
+ Atom = list_to_atom(lists:duplicate(string:length(Prefix), $a)),
Attr = {attribute,0,type,{Atom,ot_utype(Type),[]}},
- L1 = erl_pp:attribute(erl_parse:new_anno(Attr)),
+ L1 = erl_pp:attribute(erl_parse:new_anno(Attr),
+ [{encoding, Opts#opts.encoding}]),
{L2,N} = case lists:dropwhile(fun(C) -> C =/= $: end, lists:flatten(L1)) of
":: " ++ L3 -> {L3,9}; % compensation for extra "()" and ":"
"::\n" ++ L3 -> {"\n"++L3,6}
end,
Ss = lists:duplicate(N, $\s),
- re:replace(L2, "\n"++Ss, "\n", [{return,list},global]).
+ re:replace(L2, "\n"++Ss, "\n", [{return,list},global,unicode]).
-etypef(L, O0) ->
- {R, O} = etypef(L, [], O0, []),
+etypef(L, O0, Opts) ->
+ {R, O} = etypef(L, [], O0, [], Opts),
{lists:reverse(R), O}.
-etypef([C | L], St, [C | O], R) ->
- etypef(L, St, O, [[C] | R]);
-etypef(" "++L, St, O, R) ->
- etypef(L, St, O, R);
-etypef("", [Cs | St], O, R) ->
- etypef(Cs, St, O, R);
-etypef("", [], O, R) ->
+etypef([C | L], St, [C | O], R, Opts) ->
+ etypef(L, St, O, [[C] | R], Opts);
+etypef(" "++L, St, O, R, Opts) ->
+ etypef(L, St, O, R, Opts);
+etypef("", [Cs | St], O, R, Opts) ->
+ etypef(Cs, St, O, R, Opts);
+etypef("", [], O, R, _Opts) ->
{R, O};
-etypef(L, St, " "++O, R) ->
- etypef(L, St, O, [" " | R]);
-etypef(L, St, "\n"++O, R) ->
+etypef(L, St, " "++O, R, Opts) ->
+ etypef(L, St, O, [" " | R], Opts);
+etypef(L, St, "\n"++O, R, Opts) ->
Ss = lists:takewhile(fun(C) -> C =:= $\s end, O),
- etypef(L, St, lists:nthtail(length(Ss), O), ["\n"++Ss | R]);
-etypef([{a, HRef, S0} | L], St, O0, R) ->
- {S, O} = etypef(S0, app_fix(O0)),
- etypef(L, St, O, [{a, HRef, S} | R]);
-etypef("="++L, St, "::"++O, R) ->
+ etypef(L, St, lists:nthtail(length(Ss), O), ["\n"++Ss | R], Opts);
+etypef([{a, HRef, S0} | L], St, O0, R, Opts) ->
+ {S, O} = etypef(S0, app_fix(O0, Opts), Opts),
+ etypef(L, St, O, [{a, HRef, S} | R], Opts);
+etypef("="++L, St, "::"++O, R, Opts) ->
%% EDoc uses "=" for record field types; Erlang types use "::".
%% Maybe there should be an option for this, possibly affecting
%% other similar discrepancies.
- etypef(L, St, O, ["=" | R]);
-etypef([Cs | L], St, O, R) ->
- etypef(Cs, [L | St], O, R).
+ etypef(L, St, O, ["=" | R], Opts);
+etypef([Cs | L], St, O, R, Opts) ->
+ etypef(Cs, [L | St], O, R, Opts).
-app_fix(L) ->
+app_fix(L, Opts) ->
try
- {"//" ++ R1,L2} = app_fix(L, 1),
+ {"//" ++ R1,L2} = app_fix1(L, 1),
[App, Mod] = string:tokens(R1, "/"),
- "//" ++ atom(App) ++ "/" ++ atom(Mod) ++ L2
+ "//" ++ atom(App, Opts) ++ "/" ++ atom(Mod, Opts) ++ L2
catch _:_ -> L
end.
-app_fix(L, I) -> % a bit slow
+app_fix1(L, I) -> % a bit slow
{L1, L2} = lists:split(I, L),
case erl_scan:tokens([], L1 ++ ". ", 1) of
{done, {ok,[{atom,_,Atom}|_],_}, _} -> {atom_to_list(Atom), L2};
- _ -> app_fix(L, I+1)
+ _ -> app_fix1(L, I+1)
end.
fulldesc(Es) ->
@@ -702,7 +714,7 @@ deprecated(Es, S) ->
?NL]
end.
-behaviours(Es, Name) ->
+behaviours(Es, Name, Opts) ->
CBs = get_content(callbacks, Es),
OCBs = get_content(optional_callbacks, Es),
(case get_elem(behaviour, Es) of
@@ -716,17 +728,18 @@ behaviours(Es, Name) ->
if CBs =:= [], OCBs =:= [] ->
[];
true ->
+ CBFun = fun(E) -> callback(E, Opts) end,
Req = if CBs =:= [] ->
[];
true ->
[br, " Required callback functions: "]
- ++ seq(fun callback/1, CBs, ["."])
+ ++ seq(CBFun, CBs, ["."])
end,
Opt = if OCBs =:= [] ->
[];
true ->
[br, " Optional callback functions: "]
- ++ seq(fun callback/1, OCBs, ["."])
+ ++ seq(CBFun, OCBs, ["."])
end,
[{p, ([{b, ["This module defines the ", {tt, [Name]},
" behaviour."]}]
@@ -737,10 +750,10 @@ behaviours(Es, Name) ->
behaviour(E=#xmlElement{content = Es}) ->
see(E, [{tt, Es}]).
-callback(E=#xmlElement{}) ->
+callback(E=#xmlElement{}, Opts) ->
Name = get_attrval(name, E),
Arity = get_attrval(arity, E),
- [{tt, [Name, "/", Arity]}].
+ [{tt, [atom(Name, Opts), "/", Arity]}].
authors(Es) ->
case get_elem(author, Es) of
@@ -750,7 +763,9 @@ authors(Es) ->
?NL]
end.
-atom(String) ->
+atom(String, #opts{encoding = latin1}) ->
+ io_lib:write_atom_as_latin1(list_to_atom(String));
+atom(String, #opts{encoding = utf8}) ->
io_lib:write_atom(list_to_atom(String)).
%% <!ATTLIST author
@@ -798,70 +813,73 @@ todos(Es) ->
?NL]
end.
-t_name([E]) ->
+t_name([E], Opts) ->
N = get_attrval(name, E),
case get_attrval(module, E) of
- "" -> atom(N);
+ "" -> atom(N, Opts);
M ->
- S = atom(M) ++ ":" ++ atom(N),
+ S = atom(M, Opts) ++ ":" ++ atom(N, Opts),
case get_attrval(app, E) of
"" -> S;
- A -> "//" ++ atom(A) ++ "/" ++ S
+ A -> "//" ++ atom(A, Opts) ++ "/" ++ S
end
end.
-t_utype([E]) ->
- t_utype_elem(E).
+t_utype([E], Opts) ->
+ t_utype_elem(E, Opts).
-t_utype_elem(E=#xmlElement{content = Es}) ->
+t_utype_elem_fun(Opts) ->
+ fun(E) -> t_utype_elem(E, Opts) end.
+
+t_utype_elem(E=#xmlElement{content = Es}, Opts) ->
case get_attrval(name, E) of
- "" -> t_type(Es);
+ "" -> t_type(Es, Opts);
Name ->
- T = t_type(Es),
+ T = t_type(Es, Opts),
case T of
[Name] -> T; % avoid generating "Foo::Foo"
T -> [Name] ++ ["::"] ++ T
end
end.
-t_type([E=#xmlElement{name = typevar}]) ->
+t_type([E=#xmlElement{name = typevar}], _Opts) ->
t_var(E);
-t_type([E=#xmlElement{name = atom}]) ->
- t_atom(E);
-t_type([E=#xmlElement{name = integer}]) ->
+t_type([E=#xmlElement{name = atom}], Opts) ->
+ t_atom(E, Opts);
+t_type([E=#xmlElement{name = integer}], _Opts) ->
t_integer(E);
-t_type([E=#xmlElement{name = range}]) ->
+t_type([E=#xmlElement{name = range}], _Opts) ->
t_range(E);
-t_type([E=#xmlElement{name = binary}]) ->
+t_type([E=#xmlElement{name = binary}], _Opts) ->
t_binary(E);
-t_type([E=#xmlElement{name = float}]) ->
+t_type([E=#xmlElement{name = float}], _Opts) ->
t_float(E);
-t_type([#xmlElement{name = nil}]) ->
+t_type([#xmlElement{name = nil}], _Opts) ->
t_nil();
-t_type([#xmlElement{name = paren, content = Es}]) ->
- t_paren(Es);
-t_type([#xmlElement{name = list, content = Es}]) ->
- t_list(Es);
-t_type([#xmlElement{name = nonempty_list, content = Es}]) ->
- t_nonempty_list(Es);
-t_type([#xmlElement{name = map, content = Es}]) ->
- t_map(Es);
-t_type([#xmlElement{name = tuple, content = Es}]) ->
- t_tuple(Es);
-t_type([#xmlElement{name = 'fun', content = Es}]) ->
- ["fun("] ++ t_fun(Es) ++ [")"];
-t_type([E = #xmlElement{name = record, content = Es}]) ->
- t_record(E, Es);
-t_type([E = #xmlElement{name = abstype, content = Es}]) ->
- t_abstype(E, Es);
-t_type([#xmlElement{name = union, content = Es}]) ->
- t_union(Es).
+t_type([#xmlElement{name = paren, content = Es}], Opts) ->
+ t_paren(Es, Opts);
+t_type([#xmlElement{name = list, content = Es}], Opts) ->
+ t_list(Es, Opts);
+t_type([#xmlElement{name = nonempty_list, content = Es}], Opts) ->
+ t_nonempty_list(Es, Opts);
+t_type([#xmlElement{name = map, content = Es}], Opts) ->
+ t_map(Es, Opts);
+t_type([#xmlElement{name = tuple, content = Es}], Opts) ->
+ t_tuple(Es, Opts);
+t_type([#xmlElement{name = 'fun', content = Es}], Opts) ->
+ ["fun("] ++ t_fun(Es, Opts) ++ [")"];
+t_type([E = #xmlElement{name = record, content = Es}], Opts) ->
+ t_record(E, Es, Opts);
+t_type([E = #xmlElement{name = abstype, content = Es}], Opts) ->
+ t_abstype(E, Es, Opts);
+t_type([#xmlElement{name = union, content = Es}], Opts) ->
+ t_union(Es, Opts).
t_var(E) ->
[get_attrval(name, E)].
-t_atom(E) ->
- [get_attrval(value, E)].
+t_atom(E, Opts) ->
+ [atom(get_attrval(value, E), Opts)].
t_integer(E) ->
[get_attrval(value, E)].
@@ -878,62 +896,64 @@ t_float(E) ->
t_nil() ->
["[]"].
-t_paren(Es) ->
- ["("] ++ t_utype(get_elem(type, Es)) ++ [")"].
+t_paren(Es, Opts) ->
+ ["("] ++ t_utype(get_elem(type, Es), Opts) ++ [")"].
-t_list(Es) ->
- ["["] ++ t_utype(get_elem(type, Es)) ++ ["]"].
+t_list(Es, Opts) ->
+ ["["] ++ t_utype(get_elem(type, Es), Opts) ++ ["]"].
-t_nonempty_list(Es) ->
- ["["] ++ t_utype(get_elem(type, Es)) ++ [", ...]"].
+t_nonempty_list(Es, Opts) ->
+ ["["] ++ t_utype(get_elem(type, Es), Opts) ++ [", ...]"].
-t_tuple(Es) ->
- ["{"] ++ seq(fun t_utype_elem/1, Es, ["}"]).
+t_tuple(Es, Opts) ->
+ ["{"] ++ seq(t_utype_elem_fun(Opts), Es, ["}"]).
-t_fun(Es) ->
- ["("] ++ seq(fun t_utype_elem/1, get_content(argtypes, Es),
- [") -> "] ++ t_utype(get_elem(type, Es))).
+t_fun(Es, Opts) ->
+ ["("] ++ seq(t_utype_elem_fun(Opts), get_content(argtypes, Es),
+ [") -> "] ++ t_utype(get_elem(type, Es), Opts)).
-t_map(Es) ->
+t_map(Es, Opts) ->
Fs = get_elem(map_field, Es),
- ["#{"] ++ seq(fun t_map_field/1, Fs, ["}"]).
+ ["#{"] ++ seq(fun(E) -> t_map_field(E, Opts) end, Fs, ["}"]).
-t_map_field(#xmlElement{content = [K,V]}=E) ->
- KElem = t_utype_elem(K),
- VElem = t_utype_elem(V),
+t_map_field(#xmlElement{content = [K,V]}=E, Opts) ->
+ KElem = t_utype_elem(K, Opts),
+ VElem = t_utype_elem(V, Opts),
AS = case get_attrval(assoc_type, E) of
"assoc" -> " => ";
"exact" -> " := "
end,
KElem ++ [AS] ++ VElem.
-t_record(E, Es) ->
- Name = ["#"] ++ t_type(get_elem(atom, Es)),
+t_record(E, Es, Opts) ->
+ Name = ["#"] ++ t_type(get_elem(atom, Es), Opts),
case get_elem(field, Es) of
[] ->
see(E, [Name, "{}"]);
Fs ->
- see(E, Name) ++ ["{"] ++ seq(fun t_field/1, Fs, ["}"])
+ see(E, Name) ++ ["{"] ++ seq(fun(F) -> t_field(F, Opts) end,
+ Fs, ["}"])
end.
-t_field(#xmlElement{content = Es}) ->
- t_type(get_elem(atom, Es)) ++ [" = "] ++ t_utype(get_elem(type, Es)).
+t_field(#xmlElement{content = Es}, Opts) ->
+ (t_type(get_elem(atom, Es), Opts) ++ [" = "] ++
+ t_utype(get_elem(type, Es), Opts)).
-t_abstype(E, Es) ->
- Name = t_name(get_elem(erlangName, Es)),
+t_abstype(E, Es, Opts) ->
+ Name = t_name(get_elem(erlangName, Es), Opts),
case get_elem(type, Es) of
[] ->
see(E, [Name, "()"]);
Ts ->
- see(E, [Name]) ++ ["("] ++ seq(fun t_utype_elem/1, Ts, [")"])
+ see(E, [Name]) ++ ["("] ++ seq(t_utype_elem_fun(Opts), Ts, [")"])
end.
-t_abstype(Es) ->
- ([t_name(get_elem(erlangName, Es)), "("]
- ++ seq(fun t_utype_elem/1, get_elem(type, Es), [")"])).
+t_abstype(Es, Opts) ->
+ ([t_name(get_elem(erlangName, Es), Opts), "("]
+ ++ seq(t_utype_elem_fun(Opts), get_elem(type, Es), [")"])).
-t_union(Es) ->
- seq(fun t_utype_elem/1, Es, " | ", []).
+t_union(Es, Opts) ->
+ seq(t_utype_elem_fun(Opts), Es, " | ", []).
seq(F, Es) ->
seq(F, Es, []).
@@ -988,8 +1008,8 @@ local_label(R) ->
xhtml(Title, CSS, Body, Encoding) ->
EncString = case Encoding of
- "latin1" -> "ISO-8859-1";
- _ -> "UTF-8"
+ latin1 -> "ISO-8859-1";
+ utf8 -> "UTF-8"
end,
[{html, [?NL,
{head, [?NL,
@@ -1008,11 +1028,11 @@ xhtml(Title, CSS, Body, Encoding) ->
%% ---------------------------------------------------------------------
type(E) ->
- type(E, []).
+ Opts = init_opts(E, []),
+ type(E, [], Opts).
-type(E, Ds) ->
- Opts = [],
- xmerl:export_simple_content(t_utype_elem(E) ++ local_defs(Ds, Opts),
+type(E, Ds, Opts) ->
+ xmerl:export_simple_content(t_utype_elem(E, Opts) ++ local_defs(Ds, Opts),
?HTML_EXPORT).
overview(E=#xmlElement{name = overview, content = Es}, Options) ->
@@ -1034,8 +1054,8 @@ overview(E=#xmlElement{name = overview, content = Es}, Options) ->
++ FullDesc
++ [?NL, hr]
++ navigation("bottom")
- ++ timestamp()),
- Encoding = get_attrval(encoding, E),
+ ++ footer()),
+ Encoding = Opts#opts.encoding,
XML = xhtml(Title, stylesheet(Opts), Body, Encoding),
xmerl:export_simple(XML, ?HTML_EXPORT, []).
@@ -1093,8 +1113,8 @@ ot_var(E) ->
{var,0,list_to_atom(get_attrval(name, E))}.
ot_atom(E) ->
- {ok, [{atom,A,Name}], _} = erl_scan:string(get_attrval(value, E), 0),
- {atom,erl_anno:line(A),Name}.
+ Name = list_to_atom(get_attrval(value, E)),
+ {atom,erl_anno:new(0),Name}.
ot_integer(E) ->
{integer,0,list_to_integer(get_attrval(value, E))}.
diff --git a/lib/edoc/src/edoc_lib.erl b/lib/edoc/src/edoc_lib.erl
index dcc239f6b4..ebdb0f79f6 100644
--- a/lib/edoc/src/edoc_lib.erl
+++ b/lib/edoc/src/edoc_lib.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2001-2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -935,7 +940,7 @@ get_doc_env(Opts) ->
%% Modules = [atom()]
%% proplist() = [term()]
%%
-%% @type proplist() = proplists:property().
+%% @type proplist() = //stdlib/proplists:property().
%% @type edoc_env(). Environment information needed by EDoc for
%% generating references. The data representation is not documented.
%%
diff --git a/lib/edoc/src/edoc_macros.erl b/lib/edoc/src/edoc_macros.erl
index e1a54d5090..d5a11d438b 100644
--- a/lib/edoc/src/edoc_macros.erl
+++ b/lib/edoc/src/edoc_macros.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2001-2005 Richard Carlsson
diff --git a/lib/edoc/src/edoc_parser.yrl b/lib/edoc/src/edoc_parser.yrl
index 68a3439f10..30e09444b0 100644
--- a/lib/edoc/src/edoc_parser.yrl
+++ b/lib/edoc/src/edoc_parser.yrl
@@ -7,20 +7,25 @@
%%
%% Copyright (C) 2002-2005 Richard Carlsson
%%
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% Author contact: [email protected]
%% =====================================================================
@@ -238,58 +243,37 @@ throws -> etype where_defs:
#t_throws{type = '$1',
defs = '$2'}.
-%% (commented out for now)
-%% Header
-%% "%% ========================== -*-Erlang-*- ============================="
-%% "%% EDoc function specification parser, generated from the file"
-%% "%% \"edoc_parser.yrl\" by the Yecc parser generator."
-%% "%%"
-%% "%% Copyright (C) 2002-2005 Richard Carlsson"
-%% "%%"
-%% "%% This library is free software; you can redistribute it and/or modify"
-%% "%% it under the terms of the GNU Lesser General Public License as"
-%% "%% published by the Free Software Foundation; either version 2 of the"
-%% "%% License, or (at your option) any later version."
-%% "%%"
-%% "%% This library is distributed in the hope that it will be useful, but"
-%% "%% WITHOUT ANY WARRANTY; without even the implied warranty of"
-%% "%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU"
-%% "%% Lesser General Public License for more details."
-%% "%%"
-%% "%% You should have received a copy of the GNU Lesser General Public"
-%% "%% License along with this library; if not, write to the Free Software"
-%% "%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307"
-%% "%% USA"
-%% "%%"
-%% "%% @private"
-%% "%% @author Richard Carlsson <[email protected]>"
-%% "%% ===================================================================="
-%% .
+Header
+"%% EDoc function specification parser, generated from the file"
+"%% \"edoc_parser.yrl\" by the Yecc parser generator."
+"%%"
+"%% Licensed under the Apache License, Version 2.0 (the \"License\"); you may"
+"%% not use this file except in compliance with the License. You may obtain"
+"%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>"
+"%%"
+"%% Unless required by applicable law or agreed to in writing, software"
+"%% distributed under the License is distributed on an \"AS IS\" BASIS,"
+"%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."
+"%% See the License for the specific language governing permissions and"
+"%% limitations under the License."
+"%%"
+"%% Alternatively, you may use this file under the terms of the GNU Lesser"
+"%% General Public License (the \"LGPL\") as published by the Free Software"
+"%% Foundation; either version 2.1, or (at your option) any later version."
+"%% If you wish to allow use of your version of this file only under the"
+"%% terms of the LGPL, you should delete the provisions above and replace"
+"%% them with the notice and other provisions required by the LGPL; see"
+"%% <http://www.gnu.org/licenses/>. If you do not delete the provisions"
+"%% above, a recipient may use your version of this file under the terms of"
+"%% either the Apache License or the LGPL."
+"%%"
+"%% @private"
+"%% @copyright 2002-2005 Richard Carlsson"
+"%% @author Richard Carlsson <[email protected]>"
+"".
Erlang code.
-%% ========================== -*-Erlang-*- =============================
-%% EDoc function specification parser, generated from the file
-%% "edoc_parser.yrl" by the Yecc parser generator.
-%%
-%% Copyright (C) 2002-2005 Richard Carlsson
-%%
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
-%% ====================================================================
-
-export([parse_spec/2, parse_typedef/2, parse_throws/2, parse_ref/2,
parse_see/2, parse_param/2]).
diff --git a/lib/edoc/src/edoc_refs.erl b/lib/edoc/src/edoc_refs.erl
index b9a9391053..6ff0da0b75 100644
--- a/lib/edoc/src/edoc_refs.erl
+++ b/lib/edoc/src/edoc_refs.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2003 Richard Carlsson
diff --git a/lib/edoc/src/edoc_report.erl b/lib/edoc/src/edoc_report.erl
index dc6320df6d..76557ef483 100644
--- a/lib/edoc/src/edoc_report.erl
+++ b/lib/edoc/src/edoc_report.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
@@ -89,7 +94,7 @@ where({File, footer}) ->
where({File, header}) ->
io_lib:fwrite("~ts, in header file: ", [File]);
where({File, {F, A}}) ->
- io_lib:fwrite("~ts, function ~s/~w: ", [File, F, A]);
+ io_lib:fwrite("~ts, function ~ts/~w: ", [File, F, A]);
where([]) ->
io_lib:fwrite("~s: ", [?APPLICATION]);
where(File) when is_list(File) ->
diff --git a/lib/edoc/src/edoc_run.erl b/lib/edoc/src/edoc_run.erl
index 261a649c70..c88c6cfd78 100644
--- a/lib/edoc/src/edoc_run.erl
+++ b/lib/edoc/src/edoc_run.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/edoc/src/edoc_scanner.erl b/lib/edoc/src/edoc_scanner.erl
index f1d5e1d4b9..35d00c6c0e 100644
--- a/lib/edoc/src/edoc_scanner.erl
+++ b/lib/edoc/src/edoc_scanner.erl
@@ -86,6 +86,8 @@ scan1([C|Cs], Toks, Pos) when C >= 0, C =< $ -> % Skip blanks
scan1(Cs, Toks, Pos);
scan1([C|Cs], Toks, Pos) when C >= $a, C =< $z -> % Unquoted atom
scan_atom(C, Cs, Toks, Pos);
+scan1([C|Cs], Toks, Pos) when C >= $\337, C =< $\377, C /= $\367 ->
+ scan_atom(C, Cs, Toks, Pos);
scan1([C|Cs], Toks, Pos) when C >= $0, C =< $9 -> % Numbers
scan_number(C, Cs, Toks, Pos);
scan1([$-,C| Cs], Toks, Pos) when C >= $0, C =< $9 -> % Signed numbers
@@ -96,6 +98,8 @@ scan1([C|Cs], Toks, Pos) when C >= $A, C =< $Z -> % Variables
scan_variable(C, Cs, Toks, Pos);
scan1([$_|Cs], Toks, Pos) -> % Variables
scan_variable($_, Cs, Toks, Pos);
+scan1([C|Cs], Toks, Pos) when C >= $\300, C =< $\336, C /= $\327 ->
+ scan_variable(C, Cs, Toks, Pos);
scan1([$$|Cs], Toks, Pos) -> % Character constant
case scan_char_const(Cs, Toks, Pos) of
{ok, Result} ->
@@ -261,6 +265,15 @@ scan_char([], _Pos) ->
%% The following conforms to Standard Erlang escape sequences.
+-define(HEX(C), C >= $0 andalso C =< $9 orelse
+ C >= $A andalso C =< $F orelse
+ C >= $a andalso C =< $f).
+
+-define(UNICODE(C),
+ (C >= 0 andalso C < 16#D800 orelse
+ C > 16#DFFF andalso C < 16#FFFE orelse
+ C > 16#FFFF andalso C =< 16#10FFFF)).
+
scan_escape([O1, O2, O3 | Cs], Pos) when % \<1-3> octal digits
O1 >= $0, O1 =< $3, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 ->
Val = (O1*8 + O2)*8 + O3 - 73*$0,
@@ -272,6 +285,11 @@ scan_escape([O1, O2 | Cs], Pos) when
scan_escape([O1 | Cs], Pos) when
O1 >= $0, O1 =< $7 ->
{O1 - $0,Cs,Pos};
+scan_escape([$x, ${ | Cs], Pos) ->
+ scan_hex(Cs, Pos, []);
+scan_escape([$x, H1, H2 | Cs], Pos) when ?HEX(H1), ?HEX(H2) ->
+ Val = (H1*16 + H2) - 17*$0,
+ {Val,Cs,Pos};
scan_escape([$^, C | Cs], Pos) -> % \^X -> CTL-X
if C >= $\100, C =< $\137 ->
{C - $\100,Cs,Pos};
@@ -285,6 +303,18 @@ scan_escape([C | Cs], Pos) ->
scan_escape([], _Pos) ->
{error, truncated_char}.
+scan_hex([C | Cs], Pos, HCs) when ?HEX(C) ->
+ scan_hex(Cs, Pos, [C | HCs]);
+scan_hex([$} | Cs], Pos, HCs) ->
+ case catch erlang:list_to_integer(lists:reverse(HCs), 16) of
+ Val when ?UNICODE(Val) ->
+ {Val,Cs,Pos};
+ _ ->
+ {error, undefined_escape_sequence}
+ end;
+scan_hex(_Cs, _Pos, _HCs) ->
+ {error, undefined_escape_sequence}.
+
%% Note that we return $\000 for undefined escapes.
escape_char($b) -> $\010; % \b = BS
escape_char($d) -> $\177; % \d = DEL
diff --git a/lib/edoc/src/edoc_specs.erl b/lib/edoc/src/edoc_specs.erl
index c15dfd328f..fb04bfce0e 100644
--- a/lib/edoc/src/edoc_specs.erl
+++ b/lib/edoc/src/edoc_specs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -274,12 +274,19 @@ parms([A | As], [D | Ds]) ->
param(#t_paren{type = Type}, Default) ->
param(Type, Default);
-param(#t_record{name = #t_atom{val = Name}}, _Default) ->
- list_to_atom(capitalize(atom_to_list(Name)));
+param(#t_record{name = #t_atom{val = Name}}=T, Default) ->
+ AtomList = atom_to_list(Name),
+ case AtomList =:= lists:flatten(io_lib:write_atom(Name)) of
+ true ->
+ list_to_atom(capitalize(AtomList));
+ false ->
+ arg_name(?t_ann(T), Default)
+ end;
param(T, Default) ->
arg_name(?t_ann(T), Default).
capitalize([C | Cs]) when C >= $a, C =< $z -> [C - 32 | Cs];
+capitalize([C | Cs]) when C >= $\340, C =< $\376, C /= $\367 -> [C - 32 | Cs];
capitalize(Cs) -> Cs.
%% Like edoc_types:arg_name/1
diff --git a/lib/edoc/src/edoc_tags.erl b/lib/edoc/src/edoc_tags.erl
index 9e2e41e902..da078de0b9 100644
--- a/lib/edoc/src/edoc_tags.erl
+++ b/lib/edoc/src/edoc_tags.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
@@ -213,14 +218,16 @@ filter_tags([#tag{name = N, line = L} = T | Ts], Tags, Where, Ts1) ->
true ->
filter_tags(Ts, Tags, Where, [T | Ts1]);
false ->
- [warning(L, Where, "tag @~s not recognized.", [N]) ||
- Where =/= no],
+ case Where of
+ no -> ok;
+ _ -> warning(L, Where, "tag @~s not recognized.", [N])
+ end,
filter_tags(Ts, Tags, Where, Ts1)
end;
filter_tags([], _, _, Ts) ->
lists:reverse(Ts).
-%% Check occurrances of tags.
+%% Check occurrences of tags.
check_tags(Ts, Allow, Single, Where) ->
check_tags(Ts, Allow, Single, Where, false, sets:new()).
@@ -451,7 +458,7 @@ check_type(#tag{line = L, data = Data}, P0, Ls, Ts) ->
check_type(#t_def{type = Type}, P, Ls, Ts) ->
check_type(Type, P, Ls, Ts);
check_type(#t_type{name = Name, args = Args}, P, Ls, Ts) ->
- _ = check_used_type(Name, Args, P, Ls),
+ check_used_type(Name, Args, P, Ls),
check_types3(Args++Ts, P, Ls);
check_type(#t_var{}, P, Ls, Ts) ->
check_types3(Ts, P, Ls);
@@ -503,7 +510,8 @@ check_used_type(#t_name{name = N, module = Mod}=Name, Args, P, LocalTypes) ->
false ->
#parms{warn = W, line = L, file = File} = P,
%% true = ets:insert(DT, TypeName),
- [type_warning(L, File, "missing type", N, NArgs) || W]
+ _ = [type_warning(L, File, "missing type", N, NArgs) || W],
+ ok
end.
type_warning(Line, File, S, N, NArgs) ->
diff --git a/lib/edoc/src/edoc_types.erl b/lib/edoc/src/edoc_types.erl
index 5bb68e79fb..ccc3169767 100644
--- a/lib/edoc/src/edoc_types.erl
+++ b/lib/edoc/src/edoc_types.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
diff --git a/lib/edoc/src/edoc_types.hrl b/lib/edoc/src/edoc_types.hrl
index 3e5e91484f..99719793d0 100644
--- a/lib/edoc/src/edoc_types.hrl
+++ b/lib/edoc/src/edoc_types.hrl
@@ -3,20 +3,25 @@
%%
%% Copyright (C) 2001-2005 Richard Carlsson
%%
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% Author contact: [email protected]
%% =====================================================================
diff --git a/lib/edoc/src/edoc_wiki.erl b/lib/edoc/src/edoc_wiki.erl
index 5d0d78bf3c..574880703c 100644
--- a/lib/edoc/src/edoc_wiki.erl
+++ b/lib/edoc/src/edoc_wiki.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
diff --git a/lib/edoc/src/otpsgml_layout.erl b/lib/edoc/src/otpsgml_layout.erl
index 052c75b9d4..295daed551 100644
--- a/lib/edoc/src/otpsgml_layout.erl
+++ b/lib/edoc/src/otpsgml_layout.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @author Kenneth Lundin <[email protected]>
diff --git a/lib/edoc/test/edoc_SUITE.erl b/lib/edoc/test/edoc_SUITE.erl
index 00d7550bed..29ca9d1203 100644
--- a/lib/edoc/test/edoc_SUITE.erl
+++ b/lib/edoc/test/edoc_SUITE.erl
@@ -23,12 +23,13 @@
init_per_group/2,end_per_group/2]).
%% Test cases
--export([app/1,appup/1,build_std/1,build_map_module/1,otp_12008/1, build_app/1]).
+-export([app/1,appup/1,build_std/1,build_map_module/1,otp_12008/1,
+ build_app/1, otp_14285/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app,appup,build_std,build_map_module,otp_12008, build_app].
+ [app,appup,build_std,build_map_module,otp_12008, build_app, otp_14285].
groups() ->
[].
@@ -69,7 +70,7 @@ build_std(Config) when is_list(Config) ->
{def, {vsn,"TEST"}},
{dir, PrivDir}]),
- ok = edoc:application(xmerl, [{dir, PrivDir}]),
+ ok = edoc:application(xmerl, [{preprocess,true},{dir, PrivDir}]),
ok.
build_map_module(Config) when is_list(Config) ->
@@ -113,3 +114,18 @@ build_app(Config) ->
true = filelib:is_regular(filename:join(OutDir, "a.html")),
true = filelib:is_regular(filename:join(OutDir, "b.html")),
ok.
+
+otp_14285(Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Un1 = filename:join(DataDir, "un_atom1.erl"),
+ Un2 = filename:join(DataDir, "un_atom2.erl"),
+ %% epp_dodger
+ Opts1 = [{dir, PrivDir}],
+ ok = edoc:files([Un1], Opts1),
+ ok = edoc:files([Un2], Opts1),
+ %% epp
+ Opts2 = [{preprocess, true}, {dir, PrivDir}],
+ ok = edoc:files([Un1], Opts2),
+ ok = edoc:files([Un2], Opts2),
+ ok.
diff --git a/lib/edoc/test/edoc_SUITE_data/un_atom1.erl b/lib/edoc/test/edoc_SUITE_data/un_atom1.erl
new file mode 100644
index 0000000000..20ca50d5d2
--- /dev/null
+++ b/lib/edoc/test/edoc_SUITE_data/un_atom1.erl
@@ -0,0 +1,41 @@
+%% coding:latin-1
+
+-module(un_atom1).
+
+-export(['\x{aaa}memory'/0, 'func-\x{400}'/1, func/1, �func/1]).
+
+-record('rec-\x{400}', {'field-\x{400}'}).
+
+-type cs() :: $\x{a}
+ | $\x{aa}
+ | $\x{aaa}
+ | $\xaa.
+
+-callback 'callback-\x{400}'() -> 'apa'.
+
+-type 'type-\x{400}'() :: 'atom-\x{400}'
+ | cs()
+ | #'rec-\x{400}'{'field-\x{400}' :: 'type-\x{400}'()}.
+
+-spec '\x{aaa}memory'() -> 'type-\x{400}'().
+
+'\x{aaa}memory'() ->
+ apa:foo().
+
+%% @deprecated Please use {@link m:f/1}.
+-spec 'func-\x{400}'(#'rec-\x{400}'{}) -> #'rec-\x{400}'{}.
+
+'func-\x{400}'(_T) ->
+ foo:bar(#'rec-\x{400}'{}).
+
+-record(rec, {}).
+
+-spec func(#rec{}) -> #rec{}.
+
+func(#rec{}) -> #rec{}.
+
+-record(�rec, {}).
+
+-spec �func(#�rec{}) -> #�rec{}.
+
+�func(#�rec{}) -> #�rec{}.
diff --git a/lib/edoc/test/edoc_SUITE_data/un_atom2.erl b/lib/edoc/test/edoc_SUITE_data/un_atom2.erl
new file mode 100644
index 0000000000..66c83e30e0
--- /dev/null
+++ b/lib/edoc/test/edoc_SUITE_data/un_atom2.erl
@@ -0,0 +1,40 @@
+%% coding:utf-8
+-module(un_atom2).
+
+-export(['\x{aaa}memory'/0, 'func-\x{400}'/1, func/1, äfunc/1]).
+
+-record('rec-\x{400}', {'field-\x{400}'}).
+
+-type cs() :: $\x{a}
+ | $\x{aa}
+ | $\x{aaa}
+ | $\xaa.
+
+-callback 'callback-\x{400}'() -> 'apa'.
+
+-type 'type-\x{400}'() :: 'atom-\x{400}'
+ | cs()
+ | #'rec-\x{400}'{'field-\x{400}' :: 'type-\x{400}'()}.
+
+-spec '\x{aaa}memory'() -> 'type-\x{400}'().
+
+'\x{aaa}memory'() ->
+ apa:foo().
+
+%% @deprecated Please use {@link m:f/1}.
+-spec 'func-\x{400}'(#'rec-\x{400}'{}) -> #'rec-\x{400}'{}.
+
+'func-\x{400}'(_T) ->
+ foo:bar(#'rec-\x{400}'{}).
+
+-record(rec, {}).
+
+-spec func(#rec{}) -> #rec{}.
+
+func(#rec{}) -> #rec{}.
+
+-record(ärec, {}).
+
+-spec äfunc(#ärec{}) -> #ärec{}.
+
+äfunc(#ärec{}) -> #ärec{}.
diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk
index f38800b3e0..1a933b2ad8 100644
--- a/lib/edoc/vsn.mk
+++ b/lib/edoc/vsn.mk
@@ -1 +1 @@
-EDOC_VSN = 0.7.19
+EDOC_VSN = 0.9
diff --git a/lib/eldap/doc/src/eldap.xml b/lib/eldap/doc/src/eldap.xml
index 43873e44e2..f2c7889e58 100644
--- a/lib/eldap/doc/src/eldap.xml
+++ b/lib/eldap/doc/src/eldap.xml
@@ -197,7 +197,7 @@
</type>
<desc>
<p> Add an entry. The entry must not exist.</p>
- <pre>
+ <code>
add(Handle,
"cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com",
[{"objectclass", ["person"]},
@@ -205,7 +205,7 @@
{"sn", ["Valentine"]},
{"telephoneNumber", ["545 555 00"]}]
)
- </pre>
+ </code>
</desc>
</func>
<func>
@@ -216,9 +216,9 @@
</type>
<desc>
<p> Delete an entry.</p>
- <pre>
+ <code>
delete(Handle, "cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com")
- </pre>
+ </code>
</desc>
</func>
@@ -259,11 +259,11 @@
</type>
<desc>
<p> Modify an entry.</p>
- <pre>
+ <code>
modify(Handle, "cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com",
[eldap:mod_replace("telephoneNumber", ["555 555 00"]),
eldap:mod_add("description", ["LDAP Hacker"]) ])
- </pre>
+ </code>
</desc>
</func>
<func>
@@ -320,10 +320,10 @@
whether the current RDN should be removed from the attribute list after the after operation.
<c>NewSupDN</c> is the new parent that the RDN shall be moved to. If the old parent should
remain as parent, <c>NewSupDN</c> shall be "".</p>
- <pre>
+ <code>
modify_dn(Handle, "cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com ",
"cn=Bill Jr Valentine", true, "")
- </pre>
+ </code>
</desc>
</func>
<func>
@@ -342,10 +342,10 @@
Default values: scope is <c>wholeSubtree()</c>, deref is <c>derefAlways()</c>,
types_only is <c>false</c> and timeout is <c>0</c> (meaning infinity).
</p>
- <pre>
+ <code>
Filter = eldap:substrings("cn", [{any,"V"}]),
search(Handle, [{base, "dc=example, dc=com"}, {filter, Filter}, {attributes, ["cn"]}]),
- </pre>
+ </code>
<p>The <c>timeout</c> option in the <c>SearchOptions</c> is for the ldap server, while
the timeout in <seealso marker="#open/2">eldap:open/2</seealso> is used for each
individual request in the search operation.
@@ -454,7 +454,7 @@
</type>
<desc> <p>Creates an extensible match filter. For example, </p>
<code>
- eldap:extensibleMatch("Bar", [{type,"sn"}, {matchingRule,"caseExactMatch"}]))
+ eldap:extensibleMatch("Bar", [{type,"sn"}, {matchingRule,"caseExactMatch"}]))
</code>
<p>creates a filter which performs a <c>caseExactMatch</c> on the attribute <c>sn</c> and matches with the value <c>"Bar"</c>. The default value of <c>dnAttributes</c> is <c>false</c>.</p> </desc>
</func>
diff --git a/lib/eldap/test/Makefile b/lib/eldap/test/Makefile
index 21a0da926f..81fa8f187a 100644
--- a/lib/eldap/test/Makefile
+++ b/lib/eldap/test/Makefile
@@ -42,7 +42,7 @@ TARGET_FILES= \
SPEC_FILES = eldap.spec
-# COVER_FILE = eldap.cover
+COVER_FILE = eldap.cover
# ----------------------------------------------------
diff --git a/lib/eldap/test/README b/lib/eldap/test/README
index ec774c1ae3..af1bf6a082 100644
--- a/lib/eldap/test/README
+++ b/lib/eldap/test/README
@@ -16,7 +16,7 @@ To start slapd:
This will however not work, since slapd is guarded by apparmor that checks that slapd does not access other than allowed files...
-To make a local extension of alowed operations:
+To make a local extension of allowed operations:
sudo emacs /etc/apparmor.d/local/usr.sbin.slapd
and, after the change (yes, at least on Ubuntu it is right to edit ../local/.. but run with another file):
diff --git a/lib/eldap/test/eldap.cover b/lib/eldap/test/eldap.cover
new file mode 100644
index 0000000000..8c15956e72
--- /dev/null
+++ b/lib/eldap/test/eldap.cover
@@ -0,0 +1,3 @@
+{incl_app,eldap,details}.
+
+{excl_mods, eldap, ['ELDAPv3']}.
diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl
index ac3447cfe6..4bfb0dd291 100644
--- a/lib/eldap/test/eldap_basic_SUITE.erl
+++ b/lib/eldap/test/eldap_basic_SUITE.erl
@@ -119,7 +119,10 @@ init_per_suite(Config) ->
{ldaps_server, LDAPS_server} | Config].
end_per_suite(_Config) ->
- ssl:stop().
+ try ssl:stop()
+ catch
+ _:_ -> ok
+ end.
init_per_group(return_values, Config) ->
diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml
index 21dc617d55..59a268d6ac 100644
--- a/lib/erl_docgen/doc/src/notes.xml
+++ b/lib/erl_docgen/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,7 +31,74 @@
</header>
<p>This document describes the changes made to the <em>erl_docgen</em> application.</p>
- <section><title>Erl_Docgen 0.5</title>
+ <section><title>Erl_Docgen 0.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Sort index of C functions alphabetically in the sidebar.</p>
+ <p>
+ Own Id: OTP-14333 Aux Id: ERL-393 </p>
+ </item>
+ <item>
+ <p> The right side index of functions now handle
+ functions with same name but different arity. </p>
+ <p>
+ Own Id: OTP-14431</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improvements in the OTP documentation style.</p>
+ <p>
+ (Thanks to Mariano Guerra)</p>
+ <p>
+ Own Id: OTP-14371 Aux Id: PR-1215 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Docgen 0.6.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Docgen would previously emit "utf8" as the default
+ encoding in xml. This has now been remedied by emitting
+ the correct string "UTF-8" instead.</p>
+ <p>
+ Own Id: OTP-13971</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Docgen 0.6</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Improve types and specs in OTP documentation generated
+ from Erlang source files. </p>
+ <p>
+ Own Id: OTP-13720 Aux Id: ERL-120 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Docgen 0.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/erl_docgen/priv/bin/xref_mod_app.escript b/lib/erl_docgen/priv/bin/xref_mod_app.escript
index ac4278bf22..4a418fe144 100755
--- a/lib/erl_docgen/priv/bin/xref_mod_app.escript
+++ b/lib/erl_docgen/priv/bin/xref_mod_app.escript
@@ -84,7 +84,7 @@ preloaded(TopDir) ->
%% It's OK if too much data is generated as long as all applications
%% and all modules are mentioned.
appmods(D) ->
- ErlFiles = filelib:wildcard(filename:join([D,"src","*.erl"])),
+ ErlFiles = filelib:wildcard(filename:join([D,"src","**","*.erl"])),
AppV = filename:basename(D),
App = case string:rstr(AppV, "-") of
0 -> AppV;
diff --git a/lib/erl_docgen/priv/css/Makefile b/lib/erl_docgen/priv/css/Makefile
index c317411d32..e3d2ee7e3f 100644
--- a/lib/erl_docgen/priv/css/Makefile
+++ b/lib/erl_docgen/priv/css/Makefile
@@ -39,7 +39,8 @@ RELSYSDIR = $(RELEASE_PATH)/lib/erl_docgen-$(VSN)
CSS_FILES = \
- otp_doc.css
+ otp_doc.css \
+ highlight.css
# ----------------------------------------------------
diff --git a/lib/erl_docgen/priv/css/highlight.css b/lib/erl_docgen/priv/css/highlight.css
new file mode 100644
index 0000000000..d5bd1d2a9a
--- /dev/null
+++ b/lib/erl_docgen/priv/css/highlight.css
@@ -0,0 +1,96 @@
+/*
+
+Atom One Light by Daniel Gamage
+Original One Light Syntax theme from https://github.com/atom/one-light-syntax
+
+base: #fafafa
+mono-1: #383a42
+mono-2: #686b77
+mono-3: #a0a1a7
+hue-1: #0184bb
+hue-2: #4078f2
+hue-3: #a626a4
+hue-4: #50a14f
+hue-5: #e45649
+hue-5-2: #c91243
+hue-6: #986801
+hue-6-2: #c18401
+
+*/
+
+.hljs {
+ display: block;
+ overflow-x: auto;
+ padding: 0.5em;
+ color: #383a42;
+ background: #fafafa;
+}
+
+.hljs-comment,
+.hljs-quote {
+ color: #a0a1a7;
+ font-style: italic;
+}
+
+.hljs-doctag,
+.hljs-keyword,
+.hljs-formula {
+ color: #a626a4;
+}
+
+.hljs-section,
+.hljs-name,
+.hljs-selector-tag,
+.hljs-deletion,
+.hljs-subst {
+ color: #e45649;
+}
+
+.hljs-literal {
+ color: #0184bb;
+}
+
+.hljs-string,
+.hljs-regexp,
+.hljs-addition,
+.hljs-attribute,
+.hljs-meta-string {
+ color: #50a14f;
+}
+
+.hljs-built_in,
+.hljs-class .hljs-title {
+ color: #c18401;
+}
+
+.hljs-attr,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-type,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo,
+.hljs-number {
+ color: #986801;
+}
+
+.hljs-symbol,
+.hljs-bullet,
+.hljs-link,
+.hljs-meta,
+.hljs-selector-id,
+.hljs-title {
+ color: #4078f2;
+}
+
+.hljs-emphasis {
+ font-style: italic;
+}
+
+.hljs-strong {
+ font-weight: bold;
+}
+
+.hljs-link {
+ text-decoration: underline;
+}
diff --git a/lib/erl_docgen/priv/css/otp_doc.css b/lib/erl_docgen/priv/css/otp_doc.css
index 219740a557..844aad2945 100644
--- a/lib/erl_docgen/priv/css/otp_doc.css
+++ b/lib/erl_docgen/priv/css/otp_doc.css
@@ -1,34 +1,39 @@
/* standard OTP style sheet */
body {
- background: white;
- font-family: Verdana, Arial, Helvetica, sans-serif;
+ background: #fefefe;
+ color: #1a1a1a;
+ font-family: sans-serif;
margin: 0;
padding: 0;
border: 0;
overflow: scroll;
height: 100%;
max-height: 100%;
+ line-height: 1.2em;
+ font-size: 16px;
}
-th { font-family: Verdana, Arial, Helvetica, sans-serif }
-td { font-family: Verdana, Arial, Helvetica, sans-serif }
-p { font-family: Verdana, Arial, Helvetica, sans-serif }
+h1, h2, h3, h4, h5, h6{
+ line-height: 1.2em;
+}
+
+p { max-width: 42em }
-.header { background: #222; color: #fff }
+.header { background: #222; color: #fefefe }
.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 }
+a:link { color: #1862ab; text-decoration: none }
+a:active { color: #1c7cd6; text-decoration: none }
+a:visited { color: #1b6ec2; text-decoration: none }
#container {
width: 100%;
margin: 0;
- background-color: #fff;
+ background-color: #fefefe;
}
#leftnav {
@@ -41,11 +46,12 @@ a:visited { color: blue; text-decoration: none }
overflow:auto;
margin: 0;
padding: 1px;
- border-right: 1px solid red;
+ border-right: 1px solid #ccc;
}
#content {
margin-left: 340px; /* set left value to WidthOfFrameDiv */
+ max-width: 42em;
}
.frontpage
@@ -61,66 +67,67 @@ a:visited { color: blue; text-decoration: none }
.footer
{
margin: 15px; /* Magins for inner DIV inside each DIV (to provide padding) */
+ text-align: center;
}
-span.bold_code { font-family: Courier, monospace; font-weight: bold }
-span.code { font-family: Courier, monospace; font-weight: normal }
+.bold_code { font-family: mono, Courier, monospace; font-weight: bold }
+.code {
+ font-family: mono, Courier, monospace;
+ font-weight: normal;
+ background-color: #f3f3f3;
+}
.note, .warning, .do, .dont {
- border: solid black 1px;
- margin: 1em 3em;
+ border: 1px solid #495057;
+ margin: 1em 0;
}
.note .label {
- background: #30d42a;
- color: white;
+ background-color: #2b8a3e;
+ color: #fefefe;
font-weight: bold;
- padding: 5px 10px;
+ padding: 0.5em 1em;
}
.note .content {
- background: #eafeea;
- color: black;
+ background: #f8f9fa;
line-height: 120%;
- font-size: 90%;
- padding: 5px 10px;
+ font-size: 0.9em;
+ padding: 0.5em 1em;
}
.warning .label {
- background: #C00;
- color: white;
+ background: #c92a2a;
+ color: #fefefe;
font-weight: bold;
- padding: 5px 10px;
+ padding: 0.5em 1em;
}
.warning .content {
- background: #FFF0F0;
- color: black;
+ background-color: #f8f9fa;
line-height: 120%;
- font-size: 90%;
- padding: 5px 10px;
+ font-size: 0.9em;
+ padding: 0.5em 1em;
}
.do .label {
- background: #30d42a;
- color: white;
+ background-color: #2b8a3e;
+ color: #fefefe;
font-weight: bold;
- padding: 5px 10px;
+ padding: 0.5em 1em;
}
.do .content {
- background: #eafeea;
- color: black;
+ background: #f8f9fa;
line-height: 120%;
- font-size: 90%;
- padding: 5px 10px;
+ font-size: 0.9em;
+ padding: 0.5em 1em;
}
.dont .label {
- background: #C00;
- color: white;
+ background: #c92a2a;
+ color: #fefefe;
font-weight: bold;
- padding: 5px 10px;
+ padding: 0.5em 1em;
}
.dont .content {
- background: #FFF0F0;
- color: black;
+ background-color: #f8f9fa;
line-height: 120%;
- font-size: 90%;
- padding: 5px 10px;
+ font-size: 0.9em;
+ padding: 0.5em 1em;
}
.quote {
@@ -128,19 +135,134 @@ span.code { font-family: Courier, monospace; font-weight: normal }
}
.example {
- background-color:#eeeeff;
- padding: 0px 10px;
+ background-color:#f1f3f5;
+ border: 1px solid #dee2e6;
+ padding: 0.5em 1em;
+ margin: 1em 0;
+ font-size: 0.7em;
}
.extrafrontpageinfo {
color: #C00;
font-weight: bold;
- font-size: 120%;
+ font-size: 1.2em;
}
-pre { font-family: Courier, monospace; font-weight: normal }
+pre {
+ font-family: mono, Courier, monospace;
+ font-weight: normal;
+ margin: 0;
+}
-.REFBODY { margin-left: 13mm }
-.REFTYPES { margin-left: 8mm }
+.exports-body, .data-types-body, .REFBODY{
+ margin-left: 2em;
+}
+.REFTYPES { margin-left: 1.5em }
footer { }
+
+.erlang-logo-wrapper{
+ text-align: center;
+ margin-bottom: 1em;
+}
+
+.main-title{
+ text-align: center;
+}
+
+.main-description{
+ text-align: center;
+ margin: 2em 0;
+ font-size: 1.5em;
+ line-height: 1.5em;
+}
+
+.doc-table-wrapper, .doc-image-wrapper{
+ width: 100%;
+}
+
+.doc-image-wrapper{
+ text-align: center;
+}
+
+.doc-table, .doc-image{
+ min-width: 50%;
+ margin: 0 auto;
+ font-size: 0.7em;
+}
+
+.doc-table-caption, .doc-image-caption{
+ margin-top: 1em;
+ font-style: italic;
+ text-align: center;
+}
+
+table {
+ border-collapse: collapse;
+ min-width: 50%;
+ margin: 1em;
+}
+
+table, th, td {
+ border: 1px solid #666;
+}
+
+th, td {
+ padding: 0.5em;
+ text-align: left;
+}
+
+tr:hover {
+ background-color: #f5f5f5;
+}
+
+tr:nth-child(even) {
+ background-color: #f2f2f2;
+}
+
+th {
+ background-color: #777;
+ color: #fefefe;
+}
+
+.section-title, .section-subtitle, .section-version{
+ text-align: center;
+ margin: 0;
+}
+
+.section-title{
+ font-weight: bold;
+}
+
+.section-version{
+ font-size: small;
+}
+
+.expand-collapse-items{
+ font-size: small;
+}
+
+h3>a{
+ color: #1a1a1a !important;
+}
+
+hr{
+ border: 0;
+ border-top: 1px solid #aaa;
+}
+
+.section-links, .panel-sections, .expand-collapse-items{
+ padding: 0 1em;
+}
+
+.section-links, .panel-sections{
+ margin-top: 0;
+}
+
+a > .code {
+ color: #1862ab;
+}
+
+.func-types-title{
+ font-size: 1em;
+}
diff --git a/lib/erl_docgen/priv/dtd/erlref.dtd b/lib/erl_docgen/priv/dtd/erlref.dtd
index 835407520a..615b88b61a 100644
--- a/lib/erl_docgen/priv/dtd/erlref.dtd
+++ b/lib/erl_docgen/priv/dtd/erlref.dtd
@@ -29,7 +29,7 @@
<!-- `name' is used in common.refs.dtd and must therefore
be defined in each *ref. dtd -->
-<!ELEMENT name (#PCDATA) >
+<!ELEMENT name (#PCDATA|seealso)* >
<!ATTLIST name name CDATA #IMPLIED
arity CDATA #IMPLIED
clause_i CDATA #IMPLIED
diff --git a/lib/erl_docgen/priv/images/erlang-logo.gif b/lib/erl_docgen/priv/images/erlang-logo.gif
index abf5f225d7..ae13168429 100644
--- a/lib/erl_docgen/priv/images/erlang-logo.gif
+++ b/lib/erl_docgen/priv/images/erlang-logo.gif
Binary files differ
diff --git a/lib/erl_docgen/priv/images/erlang-logo.png b/lib/erl_docgen/priv/images/erlang-logo.png
index 56291aac15..41bba97417 100644
--- a/lib/erl_docgen/priv/images/erlang-logo.png
+++ b/lib/erl_docgen/priv/images/erlang-logo.png
Binary files differ
diff --git a/lib/erl_docgen/priv/js/flipmenu/Makefile b/lib/erl_docgen/priv/js/flipmenu/Makefile
index 06a13defca..ad6d4acb6c 100644
--- a/lib/erl_docgen/priv/js/flipmenu/Makefile
+++ b/lib/erl_docgen/priv/js/flipmenu/Makefile
@@ -76,6 +76,7 @@ release_spec: opt
release_docs_spec:
$(INSTALL_DIR) "$(RELEASE_PATH)/doc/js/flipmenu"
$(INSTALL_DATA) $(JS_FILES) $(GIF_FILES) "$(RELEASE_PATH)/doc/js/flipmenu"
+ $(INSTALL_DATA) ../highlight.js ../highlight.pack.js "$(RELEASE_PATH)/doc/js/"
release_tests_spec:
diff --git a/lib/erl_docgen/priv/js/flipmenu/flip_closed.gif b/lib/erl_docgen/priv/js/flipmenu/flip_closed.gif
index 9a27c7c25d..a75107a782 100644
--- a/lib/erl_docgen/priv/js/flipmenu/flip_closed.gif
+++ b/lib/erl_docgen/priv/js/flipmenu/flip_closed.gif
Binary files differ
diff --git a/lib/erl_docgen/priv/js/flipmenu/flip_open.gif b/lib/erl_docgen/priv/js/flipmenu/flip_open.gif
index 9dda60e73a..1274637fe0 100644
--- a/lib/erl_docgen/priv/js/flipmenu/flip_open.gif
+++ b/lib/erl_docgen/priv/js/flipmenu/flip_open.gif
Binary files differ
diff --git a/lib/erl_docgen/priv/js/flipmenu/flip_static.gif b/lib/erl_docgen/priv/js/flipmenu/flip_static.gif
index 2b3ddb5382..4cc914a50a 100644
--- a/lib/erl_docgen/priv/js/flipmenu/flip_static.gif
+++ b/lib/erl_docgen/priv/js/flipmenu/flip_static.gif
Binary files differ
diff --git a/lib/erl_docgen/priv/js/highlight.js b/lib/erl_docgen/priv/js/highlight.js
new file mode 100644
index 0000000000..0594b42aa3
--- /dev/null
+++ b/lib/erl_docgen/priv/js/highlight.js
@@ -0,0 +1,39 @@
+/*globals document, window*/
+window.addEventListener("load", function () {
+ "use strict";
+ var body = document.body,
+ base = window.__otpTopDocDir || "/doc/js/",
+ cssLink = document.createElement('link'),
+ script = document.createElement('script'),
+ intervalId, attempts = 0;
+
+ cssLink.rel = "stylesheet";
+ cssLink.href = base + "../highlight.css";
+ script.src = base + "highlight.pack.js";
+
+ body.appendChild(cssLink);
+ body.appendChild(script);
+
+ function doHighlight() {
+ attempts += 1;
+
+ if (attempts > 20) {
+ window.clearInterval(intervalId);
+ return;
+ }
+
+ if (!window.hljs) {
+ return;
+ }
+
+ window.clearInterval(intervalId);
+
+ var i, len, nodes = document.querySelectorAll('.example');
+ for (i = 0, len = nodes.length; i < len; i += 1) {
+ window.hljs.highlightBlock(nodes[i]);
+ }
+
+ }
+
+ intervalId = window.setInterval(doHighlight, 50);
+});
diff --git a/lib/erl_docgen/priv/js/highlight.pack.js b/lib/erl_docgen/priv/js/highlight.pack.js
new file mode 100644
index 0000000000..073d39e644
--- /dev/null
+++ b/lib/erl_docgen/priv/js/highlight.pack.js
@@ -0,0 +1,2 @@
+/*! highlight.js v9.7.0 | BSD3 License | git.io/hljslicense */
+!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/[&<>]/gm,function(e){return I[e]})}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return R(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||R(i))return i}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset<r[0].offset?e:r:"start"===r[0].event?e:r:e.length?e:r}function o(e){function r(e){return" "+e.nodeName+'="'+n(e.value)+'"'}l+="<"+t(e)+w.map.call(e.attributes,r).join("")+">"}function u(e){l+="</"+t(e)+">"}function c(e){("start"===e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):E(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"===e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var a=r?"":y.classPrefix,i='<span class="'+a,o=t?"":C;return i+=e+'">',i+n+o}function p(){var e,t,r,a;if(!E.k)return n(B);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(B);r;)a+=n(B.substr(t,r.index-t)),e=g(E,r),e?(M+=e[1],a+=h(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(B);return a+n(B.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!x[E.sL])return n(B);var t=e?l(E.sL,B,!0,L[E.sL]):f(B,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(L[E.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){k+=null!=E.sL?d():p(),B=""}function v(e){k+=e.cN?h(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(B+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?B+=n:(t.eB&&(B+=n),b(),t.rB||t.eB||(B=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?B+=n:(a.rE||a.eE||(B+=n),b(),a.eE&&(B=n));do E.cN&&(k+=C),E.skip||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"<unnamed>")+'"');return B+=n,n.length||1}var N=R(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,E=i||N,L={},k="";for(w=E;w!==N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var B="",M=0;try{for(var I,j,O=0;;){if(E.t.lastIndex=O,I=E.t.exec(t),!I)break;j=m(t.substr(O,I.index-O),I[0]),O=I.index+j}for(m(t.substr(O)),w=E;w.parent;w=w.parent)w.cN&&(k+=C);return{r:M,value:k,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function f(e,t){t=t||y.languages||E(x);var r={r:0,value:n(e)},a=r;return t.filter(R).forEach(function(n){var t=l(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function g(e){return y.tabReplace||y.useBR?e.replace(M,function(e,n){return y.useBR&&"\n"===e?"<br>":y.tabReplace?n.replace(/\t/g,y.tabReplace):void 0}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n,t,r,o,s,p=i(e);a(p)||(y.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):n=e,s=n.textContent,r=p?l(p,s,!0):f(s),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),s)),r.value=g(r.value),e.innerHTML=r.value,e.className=h(e.className,p,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function d(e){y=o(y,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");w.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function N(){return E(x)}function R(e){return e=(e||"").toLowerCase(),x[e]||x[L[e]]}var w=[],E=Object.keys,x={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="</span>",y={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},I={"&":"&amp;","<":"&lt;",">":"&gt;"};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=R,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("erlang",function(e){var r="[a-z'][a-zA-Z0-9_']*",c="("+r+":"+r+"|"+r+")",b={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor",literal:"false true"},i=e.C("%","$"),n={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},a={b:"fun\\s+"+r+"/\\d+"},d={b:c+"\\(",e:"\\)",rB:!0,r:0,c:[{b:c,r:0},{b:"\\(",e:"\\)",eW:!0,rE:!0,r:0}]},o={b:"{",e:"}",r:0},t={b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0},f={b:"[A-Z][a-zA-Z0-9_]*",r:0},l={b:"#"+e.UIR,r:0,rB:!0,c:[{b:"#"+e.UIR,r:0},{b:"{",e:"}",r:0}]},s={bK:"fun receive if try case",e:"end",k:b};s.c=[i,a,e.inherit(e.ASM,{cN:""}),s,d,e.QSM,n,o,t,f,l];var u=[i,a,s,d,e.QSM,n,o,t,f,l];d.c[1].c=u,o.c=u,l.c[1].c=u;var h={cN:"params",b:"\\(",e:"\\)",c:u};return{aliases:["erl"],k:b,i:"(</|\\*=|\\+=|-=|/\\*|\\*/|\\(\\*|\\*\\))",c:[{cN:"function",b:"^"+r+"\\s*\\(",e:"->",rB:!0,i:"\\(|#|//|/\\*|\\\\|:|;",c:[h,e.inherit(e.TM,{b:r})],starts:{e:";|\\.",k:b,c:u}},i,{b:"^-",e:"\\.",r:0,eE:!0,rB:!0,l:"-"+e.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec",c:[h]},n,e.QSM,l,t,f,o,{b:/\.$/}]}});hljs.registerLanguage("erlang-repl",function(e){return{k:{built_in:"spawn spawn_link self",keyword:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},c:[{cN:"meta",b:"^[0-9]+> ",r:10},e.C("%","$"),{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},e.ASM,e.QSM,{b:"\\?(::)?([A-Z]\\w*(::)?)+"},{b:"->"},{b:"ok"},{b:"!"},{b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{b:"[A-Z][a-zA-Z0-9_']*",r:0}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\._]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}}); \ No newline at end of file
diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl
index fe6c7d3c28..d863c056e9 100644
--- a/lib/erl_docgen/priv/xsl/db_html.xsl
+++ b/lib/erl_docgen/priv/xsl/db_html.xsl
@@ -3,7 +3,7 @@
#
# %CopyrightBegin%
#
- # Copyright Ericsson AB 2009-2016. All Rights Reserved.
+ # Copyright Ericsson AB 2009-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -66,6 +66,10 @@
Additionally, callbacks may be included, as in gen_server.xml:
<name>Module:handle_call(Request, From, State) -> Result</name>
+ For C reference pages the name tag has a substructure where the nametext tag
+ is used in the sort, as in erl_nif.xml
+ <name><ret>void *</ret><nametext>enif_alloc(size_t size)</nametext></name>
+
So first, get the name from either the attribute or the element value.
Then, reverse the case of the first character. This is because xsltproc, used for processing,
orders uppercase before lowercase (even when the 'case-order="lower-first"' option
@@ -82,12 +86,19 @@
<xsl:variable name="base">
<xsl:choose>
- <xsl:when test="string-length($elem/@name) > 0">
- <xsl:value-of select="$elem/@name"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$elem"/>
- </xsl:otherwise>
+ <xsl:when test="ancestor::cref">
+ <xsl:value-of select="$elem/nametext"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="string-length($elem/@name) > 0">
+ <xsl:value-of select="$elem/@name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring-before($elem, '(')"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
</xsl:choose>
</xsl:variable>
@@ -200,13 +211,12 @@
<xsl:template match="head">
<xsl:param name="local_types"/>
<xsl:param name="global_types"/>
- <span class="bold_code">
+ <div class="bold_code func-head">
<xsl:apply-templates mode="local_type">
<xsl:with-param name="local_types" select="$local_types"/>
<xsl:with-param name="global_types" select="$global_types"/>
</xsl:apply-templates>
- </span>
- <br/>
+ </div>
</xsl:template>
<!-- The *last* <name name="..." arity=".."/> -->
@@ -234,7 +244,8 @@
<!-- It is assumed there is no support for overloaded specs
(there is no spec with more than one clause) -->
<xsl:if test="count($clause/guard) > 0 or count($type) > 0">
- <div class="REFBODY"><p>Types:</p>
+ <div class="REFBODY fun-types">
+ <h3 class="func-types-title">Types</h3>
<xsl:choose>
<xsl:when test="$output_subtypes">
@@ -327,13 +338,13 @@
<xsl:for-each select="$subtype">
<xsl:variable name="tname" select="typename"/>
- <div class="REFTYPES">
- <span class="bold_code">
- <xsl:apply-templates select="string" mode="local_type">
- <xsl:with-param name="local_types" select="$local_types"/>
- <xsl:with-param name="global_types" select="$global_types"/>
- </xsl:apply-templates>
- </span>
+ <div class="REFTYPES rt-1">
+ <span class="bold_code bc-2">
+ <xsl:apply-templates select="string" mode="local_type">
+ <xsl:with-param name="local_types" select="$local_types"/>
+ <xsl:with-param name="global_types" select="$global_types"/>
+ </xsl:apply-templates>
+ </span>
</div>
<xsl:apply-templates select="$type_desc[@variable = $tname]"/>
</xsl:for-each>
@@ -345,7 +356,7 @@
<xsl:param name="global_types"/>
<xsl:for-each select="$local_types">
- <div class="REFTYPES">
+ <div class="REFTYPES rt-2">
<xsl:call-template name="type_name">
<xsl:with-param name="mode" select="'local_type'"/>
<xsl:with-param name="local_types" select="$local_types"/>
@@ -366,7 +377,7 @@
<!-- Similar to <d> -->
<xsl:template match="type_desc">
- <div class="REFBODY">
+ <div class="REFBODY rb-1">
<xsl:apply-templates/>
</div>
</xsl:template>
@@ -375,7 +386,7 @@
<xsl:template match="all_etypes">
<xsl:for-each select= "$i//type">
<pre>
- <span class="bold_code">
+ <span class="bold_code bc-3">
<xsl:apply-templates select="typedecl"/>
</span><xsl:text>
</xsl:text>
@@ -386,15 +397,17 @@
<!-- Datatypes -->
<xsl:template match="datatypes">
<h3>
- <xsl:text>DATA TYPES</xsl:text>
+ <a name="data-types" href="#data-types"><xsl:text>Data Types</xsl:text></a>
</h3>
- <xsl:apply-templates/>
+ <div class="data-types-body">
+ <xsl:apply-templates/>
+ </div>
</xsl:template>
<!-- Datatype -->
<xsl:template match="datatype">
- <p><xsl:apply-templates select="name"/></p>
- <xsl:apply-templates select="desc"/>
+ <div class="data-type-name"><xsl:apply-templates select="name"/></div>
+ <div class="data-type-desc"><xsl:apply-templates select="desc"/></div>
</xsl:template>
<!-- The "mode" attribute of apply has been used to separate the case
@@ -454,7 +467,7 @@
</xsl:template>
<xsl:template match="typehead">
- <span class="bold_code">
+ <span class="bold_code bc-4">
<xsl:apply-templates/>
</span><br/>
</xsl:template>
@@ -462,7 +475,7 @@
<xsl:template match="typehead" mode="local_type">
<xsl:param name="local_types"/>
<xsl:param name="global_types"/>
- <span class="bold_code">
+ <span class="bold_code bc-5">
<xsl:apply-templates mode="local_type">
<xsl:with-param name="local_types" select="$local_types"/>
<xsl:with-param name="global_types" select="$global_types"/>
@@ -473,7 +486,7 @@
<!-- Not used right now -->
<!-- local_defs -->
<xsl:template match="local_defs">
- <div class="REFBODY">
+ <div class="REFBODY rb-2">
<xsl:apply-templates>
</xsl:apply-templates>
</div>
@@ -481,8 +494,8 @@
<!-- Not used right now -->
<xsl:template match="local_def">
- <div class="REFTYPES">
- <span class="bold_code">
+ <div class="REFTYPES rt-3">
+ <span class="bold_code bc-6">
<xsl:apply-templates/>
</span>
</div>
@@ -659,7 +672,7 @@
</xsl:otherwise>
</xsl:choose>
</head>
- <body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000">
+ <body>
<div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="{$topdocdir}/js/flipmenu/flipmenu.js"/>
@@ -734,6 +747,8 @@
</div>
</div>
+ <script type="text/javascript"><xsl:text>window.__otpTopDocDir = '</xsl:text><xsl:value-of select="$topdocdir"/><xsl:text>/js/';</xsl:text></script>
+ <script type="text/javascript" src="{$topdocdir}/js/highlight.js"/>
</body>
</html>
</xsl:template>
@@ -796,36 +811,42 @@
</xsl:template>
- <xsl:template name="menu_top">
+ <xsl:template name="erlang_logo">
<xsl:choose>
<xsl:when test="string-length($logo) > 0">
- <img alt="Erlang logo" src="{$topdocdir}/{$logo}"/>
+ <div class="erlang-logo-wrapper">
+ <a href="{$topdocdir}/index.html"><img alt="Erlang Logo" src="{$topdocdir}/{$logo}" class="erlang-logo"/></a>
+ </div>
</xsl:when>
<xsl:otherwise>
- <img alt="Erlang logo" src="{$topdocdir}/erlang-logo.png"/>
+ <div class="erlang-logo-wrapper">
+ <a href="{$topdocdir}/index.html"><img alt="Erlang Logo" src="{$topdocdir}/erlang-logo.png" class="erlang-logo"/></a>
+ </div>
</xsl:otherwise>
</xsl:choose>
- <br/>
- <small>
+ </xsl:template>
+
+ <xsl:template name="menu_top">
+ <ul class="panel-sections">
<xsl:if test="boolean(/book/parts/part)">
- <a href="users_guide.html">User's Guide</a><br/>
+ <li><a href="users_guide.html">User's Guide</a></li>
</xsl:if>
<xsl:if test="boolean(/book/applications)">
- <a href="index.html">Reference Manual</a><br/>
+ <li><a href="index.html">Reference Manual</a></li>
</xsl:if>
<xsl:if test="boolean(/book/releasenotes)">
- <a href="release_notes.html">Release Notes</a><br/>
+ <li><a href="release_notes.html">Release Notes</a></li>
</xsl:if>
<xsl:choose>
<xsl:when test="string-length($pdfname) > 0">
- <a href="{$pdfdir}/{$pdfname}.pdf">PDF</a><br/>
+ <li><a href="{$pdfdir}/{$pdfname}.pdf">PDF</a></li>
</xsl:when>
<xsl:otherwise>
- <a href="{$pdfdir}/{$appname}-{$appver}.pdf">PDF</a><br/>
+ <li><a href="{$pdfdir}/{$appname}-{$appver}.pdf">PDF</a></li>
</xsl:otherwise>
</xsl:choose>
- <a href="{$topdocdir}/index.html">Top</a>
- </small>
+ <li><a href="{$topdocdir}/index.html">Top</a></li>
+ </ul>
</xsl:template>
<xsl:template name="menu_middle">
@@ -841,10 +862,11 @@
</xsl:when>
</xsl:choose>
</small -->
- <br/>
- <a href="javascript:openAllFlips()">Expand All</a><br/>
- <a href="javascript:closeAllFlips()">Contract All</a>
+ <ul class="expand-collapse-items">
+ <li><a href="javascript:openAllFlips()">Expand All</a></li>
+ <li><a href="javascript:closeAllFlips()">Contract All</a></li>
+ </ul>
</xsl:template>
@@ -934,7 +956,7 @@
<xsl:value-of select="title"/>
</a>
</h3>
- <div class="REFBODY">
+ <div class="REFBODY rb-3">
<xsl:apply-templates>
<xsl:with-param name="chapnum" select="$chapnum"/>
</xsl:apply-templates>
@@ -948,7 +970,7 @@
<h4>
<xsl:value-of select="title"/>
</h4>
- <div class="REFBODY">
+ <div class="REFBODY rb-4">
<xsl:apply-templates>
<xsl:with-param name="chapnum" select="$chapnum"/>
</xsl:apply-templates>
@@ -1129,7 +1151,8 @@
<xsl:variable name="tabnum">
<xsl:number level="any" from="chapter" count="table"/>
</xsl:variable>
- <table border="1" cellpadding="2" cellspacing="0">
+ <div class="doc-table-wrapper">
+ <table class="doc-table">
<!-- tbody-->
<xsl:apply-templates select="row">
<xsl:with-param name="chapnum" select="$chapnum"/>
@@ -1141,6 +1164,7 @@
<xsl:with-param name="chapnum" select="$chapnum"/>
<xsl:with-param name="tabnum" select="$tabnum"/>
</xsl:apply-templates>
+ </div>
</xsl:template>
<xsl:template match="row">
@@ -1160,11 +1184,11 @@
<xsl:param name="chapnum"/>
<xsl:param name="tabnum"/>
- <em>Table
+ <p class="doc-table-caption">Table
<xsl:value-of select="$chapnum"/>.<xsl:value-of select="$tabnum"/>:
&#160;
<xsl:apply-templates/>
- </em>
+ </p>
</xsl:template>
@@ -1175,12 +1199,14 @@
<xsl:number level="any" from="chapter" count="image"/>
</xsl:variable>
- <img alt="IMAGE MISSING" src="{@file}"/><br/>
+ <div class="doc-image-wrapper">
+ <img alt="IMAGE MISSING" src="{@file}" class="doc-image"/>
<xsl:apply-templates>
<xsl:with-param name="chapnum" select="$chapnum"/>
<xsl:with-param name="fignum" select="$fignum"/>
</xsl:apply-templates>
+ </div>
</xsl:template>
@@ -1190,11 +1216,11 @@
<xsl:param name="chapnum"/>
<xsl:param name="fignum"/>
- <p><em>Figure
+ <p class="doc-image-caption">Figure
<xsl:value-of select="$chapnum"/>.<xsl:value-of select="$fignum"/>:
&#160;
<xsl:apply-templates/>
- </em></p>
+ </p>
</xsl:template>
@@ -1244,21 +1270,17 @@
<div id="leftnav">
<div class="innertube">
- <xsl:call-template name="menu_top"/>
+ <xsl:call-template name="erlang_logo"/>
- <p>
- <strong><xsl:value-of select="/book/header/title"/></strong><br/>
- <strong>User's Guide</strong><br/>
- <small>Version <xsl:value-of select="$appver"/></small>
- </p>
+ <p class="section-title"><xsl:value-of select="/book/header/title"/></p>
+ <p class="section-subtitle">User's Guide</p>
+ <p class="section-version">Version <xsl:value-of select="$appver"/></p>
+
+ <xsl:call-template name="menu_top"/>
<xsl:call-template name="menu_middle"/>
- <p>
- <small>
- <strong>Chapters</strong>
- </small>
- </p>
+ <h3>Chapters</h3>
<ul class="flipMenu" imagepath="{$topdocdir}/js/flipmenu">
<xsl:call-template name="menu.chapter">
@@ -1409,21 +1431,17 @@
<div id="leftnav">
<div class="innertube">
- <xsl:call-template name="menu_top"/>
+ <xsl:call-template name="erlang_logo"/>
- <p>
- <strong><xsl:value-of select="/book/header/title"/></strong><br/>
- <strong>Reference Manual</strong><br/>
- <small>Version <xsl:value-of select="$appver"/></small>
- </p>
+ <p class="section-title"><xsl:value-of select="/book/header/title"/></p>
+ <p class="section-subtitle">Reference Manual</p>
+ <p class="section-version">Version <xsl:value-of select="$appver"/></p>
+
+ <xsl:call-template name="menu_top"/>
<xsl:call-template name="menu_middle"/>
- <p>
- <small>
- <strong>Table of Contents</strong>
- </small>
- </p>
+ <h3>Table of Contents</h3>
<ul class="flipMenu">
<xsl:call-template name="menu.ref2">
@@ -1773,8 +1791,8 @@
<!-- Module -->
<xsl:template match="module">
<xsl:param name="partnum"/>
- <h3>MODULE</h3>
- <div class="REFBODY">
+ <h3><a name="module" href="#module">Module</a></h3>
+ <div class="REFBODY module-body">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -1785,8 +1803,8 @@
<!-- Modulesummary -->
<xsl:template match="modulesummary">
<xsl:param name="partnum"/>
- <h3>MODULE SUMMARY</h3>
- <div class="REFBODY">
+ <h3><a name="module-sumary" href="#module-sumary">Module Summary</a></h3>
+ <div class="REFBODY module-summary-body">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -1796,8 +1814,8 @@
<!-- Lib -->
<xsl:template match="lib">
<xsl:param name="partnum"/>
- <h3>C LIBRARY</h3>
- <div class="REFBODY">
+ <h3><a name="c-library" href="#c-library">C Library</a></h3>
+ <div class="REFBODY c-library-body">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -1808,8 +1826,8 @@
<!-- Libsummary -->
<xsl:template match="libsummary">
<xsl:param name="partnum"/>
- <h3>LIBRARY SUMMARY</h3>
- <div class="REFBODY">
+ <h3><a name="library-sumary" href="#library-sumary">Library Summary</a></h3>
+ <div class="REFBODY library-summary-body">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -1819,8 +1837,8 @@
<!-- Com -->
<xsl:template match="com">
<xsl:param name="partnum"/>
- <h3>COMMAND</h3>
- <div class="REFBODY">
+ <h3><a name="command" href="#command">Command</a></h3>
+ <div class="REFBODY command-body">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -1831,8 +1849,8 @@
<!-- Comsummary -->
<xsl:template match="comsummary">
<xsl:param name="partnum"/>
- <h3>COMMAND SUMMARY</h3>
- <div class="REFBODY">
+ <h3><a name="command-summary" href="#command-summary">Command Summary</a></h3>
+ <div class="REFBODY command-summary-body">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -1842,8 +1860,8 @@
<!-- File -->
<xsl:template match="file">
<xsl:param name="partnum"/>
- <h3>FILE</h3>
- <div class="REFBODY">
+ <h3><a name="file" href="#file">File</a></h3>
+ <div class="REFBODY file-body">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -1854,8 +1872,8 @@
<!-- Filesummary -->
<xsl:template match="filesummary">
<xsl:param name="partnum"/>
- <h3>FILE SUMMARY</h3>
- <div class="REFBODY">
+ <h3><a name="file-summary" href="#file-summary">File Summary</a></h3>
+ <div class="REFBODY file-summary-body">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -1866,8 +1884,8 @@
<!-- App -->
<xsl:template match="app">
<xsl:param name="partnum"/>
- <h3>APPLICATION</h3>
- <div class="REFBODY">
+ <h3><a name="application" href="#application">Application</a></h3>
+ <div class="REFBODY application-body">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -1878,8 +1896,8 @@
<!-- Appsummary -->
<xsl:template match="appsummary">
<xsl:param name="partnum"/>
- <h3>APPLICATION SUMMARY</h3>
- <div class="REFBODY">
+ <h3><a name="application-summary" href="#application-summary">Application Summary</a></h3>
+ <div class="REFBODY application-summary-body">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -1889,8 +1907,8 @@
<!-- Description -->
<xsl:template match="description">
<xsl:param name="partnum"/>
- <h3>DESCRIPTION</h3>
- <div class="REFBODY">
+ <h3><a name="description" href="#description">Description</a></h3>
+ <div class="REFBODY description-body">
<p>
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
@@ -1903,13 +1921,13 @@
<xsl:template match="funcs">
<xsl:param name="partnum"/>
- <h3>
- <xsl:text>EXPORTS</xsl:text>
- </h3>
+ <h3><a name="exports" href="#exports"><xsl:text>Exports</xsl:text></a></h3>
- <xsl:apply-templates>
- <xsl:with-param name="partnum" select="$partnum"/>
- </xsl:apply-templates>
+ <div class="exports-body">
+ <xsl:apply-templates>
+ <xsl:with-param name="partnum" select="$partnum"/>
+ </xsl:apply-templates>
+ </div>
</xsl:template>
@@ -1980,7 +1998,7 @@
<xsl:choose>
<xsl:when test="ancestor::cref">
<a name="{substring-before(nametext, '(')}">
- <span class="bold_code">
+ <span class="bold_code bc-7">
<xsl:value-of select="ret"/>
<xsl:call-template name="maybe-space-after-ret">
<xsl:with-param name="s" select="ret"/>
@@ -2007,15 +2025,15 @@
</xsl:variable>
<xsl:choose>
<xsl:when test="ancestor::datatype">
- <a name="type-{$fname}"><span class="bold_code"><xsl:value-of select="."/></span></a><br/>
+ <a name="type-{$fname}"></a><span class="bold_code bc-8"><xsl:apply-templates/></span><br/>
</xsl:when>
<xsl:otherwise>
- <a name="{$fname}-{$arity}"><span class="bold_code"><xsl:value-of select="."/></span></a><br/>
+ <a name="{$fname}-{$arity}"></a><span class="bold_code fun-type"><xsl:apply-templates/></span><br/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
- <span class="bold_code"><xsl:value-of select="."/></span>
+ <span class="bold_code bc-10"><xsl:value-of select="."/></span>
</xsl:otherwise>
</xsl:choose>
@@ -2040,12 +2058,13 @@
<!-- The case where @name != 0 is taken care of in "type_name" -->
<xsl:if test="string-length(@name) = 0 and string-length(@variable) = 0">
- <div class="REFBODY"><p>Types:</p>
+ <div class="REFBODY rb-5">
+ <h3 class="func-types-title">Types</h3>
- <xsl:apply-templates>
- <xsl:with-param name="partnum" select="$partnum"/>
- </xsl:apply-templates>
- </div>
+ <xsl:apply-templates>
+ <xsl:with-param name="partnum" select="$partnum"/>
+ </xsl:apply-templates>
+ </div>
</xsl:if>
@@ -2055,8 +2074,8 @@
<!-- V -->
<xsl:template match="v">
<xsl:param name="partnum"/>
- <div class="REFTYPES">
- <span class="bold_code">
+ <div class="REFTYPES rt-4">
+ <span class="bold_code fun-param-type">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -2067,7 +2086,7 @@
<!-- D -->
<xsl:template match="d">
<xsl:param name="partnum"/>
- <div class="REFBODY">
+ <div class="REFBODY rb-6">
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
@@ -2077,7 +2096,7 @@
<!-- Desc -->
<xsl:template match="desc">
<xsl:param name="partnum"/>
- <div class="REFBODY">
+ <div class="REFBODY rb-7">
<p>
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
@@ -2094,7 +2113,7 @@
<xsl:template match="input">
- <span class="bold_code"><xsl:apply-templates/></span>
+ <span class="bold_code bc-12"><xsl:apply-templates/></span>
</xsl:template>
<xsl:template match="seealso">
@@ -2113,7 +2132,7 @@
<xsl:when test="string-length($app_part) > 0">
<!-- "AppPart:ModPart#Linkpart" -->
<xsl:variable name="mod_part"><xsl:value-of select="substring-after($filepart, ':')"/></xsl:variable>
- <span class="bold_code"><a href="javascript:erlhref('{$topdocdir}/../','{$app_part}','{$mod_part}.html#{$linkpart}');"><xsl:apply-templates/></a></span>
+ <span class="bold_code bc-13"><a href="javascript:erlhref('{$topdocdir}/../','{$app_part}','{$mod_part}.html#{$linkpart}');"><xsl:apply-templates/></a></span>
</xsl:when>
<xsl:otherwise>
<!-- "Filepart#Linkpart (there is no ':' in Filepart) -->
@@ -2133,7 +2152,7 @@
<xsl:variable name="app" select="key('mod2app', $filepart)"/>
<xsl:choose>
<xsl:when test="string-length($app) > 0">
- <span class="bold_code"><a href="javascript:erlhref('{$topdocdir}/../','{$app}','{$filepart}.html#{$linkpart}');"><xsl:value-of select="$this"/></a></span>
+ <span class="bold_code bc-14"><a href="javascript:erlhref('{$topdocdir}/../','{$app}','{$filepart}.html#{$linkpart}');"><xsl:value-of select="$this"/></a></span>
</xsl:when>
<xsl:otherwise>
<!-- Unknown application -->
@@ -2146,11 +2165,11 @@
</xsl:when>
<xsl:when test="string-length($linkpart) > 0">
<!-- Still Filepart#Linkpart (there is no ':' in Filepart -->
- <span class="bold_code"><a href="{$filepart}.html#{$linkpart}"><xsl:apply-templates/></a></span>
+ <span class="bold_code bc-15"><a href="{$filepart}.html#{$linkpart}"><xsl:apply-templates/></a></span>
</xsl:when>
<xsl:otherwise>
<!-- "Filepart#" (there is no ':' in Filepart -->
- <span class="bold_code"><a href="{$filepart}.html"><xsl:apply-templates/></a></span>
+ <span class="bold_code bc-16"><a href="{$filepart}.html"><xsl:apply-templates/></a></span>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
@@ -2158,7 +2177,7 @@
</xsl:when> <!-- string-length($filepart) > 0 -->
<xsl:when test="string-length($linkpart) > 0">
<!-- "#Linkpart" -->
- <span class="bold_code"><a href="#{$linkpart}"><xsl:apply-templates/></a></span>
+ <span class="bold_code bc-17"><a href="#{$linkpart}"><xsl:apply-templates/></a></span>
</xsl:when>
<xsl:otherwise>
<!-- "AppPart:Mod" or "Mod" (there is no '#') -->
@@ -2168,11 +2187,11 @@
<xsl:when test="string-length($app_part) > 0">
<!-- "App:Mod" -->
<xsl:variable name="mod_part"><xsl:value-of select="substring-after(@marker, ':')"/></xsl:variable>
- <span class="bold_code"><a href="javascript:erlhref('{$topdocdir}/../','{$app_part}','{$mod_part}.html');"><xsl:apply-templates/></a></span>
+ <span class="bold_code bc-18"><a href="javascript:erlhref('{$topdocdir}/../','{$app_part}','{$mod_part}.html');"><xsl:apply-templates/></a></span>
</xsl:when>
<xsl:otherwise>
<!-- "Mod" -->
- <span class="bold_code"><a href="{@marker}.html"><xsl:apply-templates/></a></span>
+ <span class="bold_code bc-19"><a href="{@marker}.html"><xsl:apply-templates/></a></span>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
@@ -2181,7 +2200,7 @@
</xsl:template>
<xsl:template match="url">
- <span class="bold_code"><a href="{@href}"><xsl:apply-templates/></a></span>
+ <span class="bold_code bc-20"><a href="{@href}"><xsl:apply-templates/></a></span>
</xsl:template>
<xsl:template match="marker">
@@ -2256,21 +2275,17 @@
<div id="leftnav">
<div class="innertube">
- <xsl:call-template name="menu_top"/>
+ <xsl:call-template name="erlang_logo"/>
- <p>
- <strong><xsl:value-of select="/book/header/title"/></strong><br/>
- <strong>Release Notes</strong><br/>
- <small>Version <xsl:value-of select="$appver"/></small>
- </p>
+ <p class="section-title"><xsl:value-of select="/book/header/title"/></p>
+ <p class="section-subtitle">Release Notes</p>
+ <p class="section-version">Version <xsl:value-of select="$appver"/></p>
+
+ <xsl:call-template name="menu_top"/>
<xsl:call-template name="menu_middle"/>
- <p>
- <small>
- <strong>Chapters</strong>
- </small>
- </p>
+ <h3>Chapters</h3>
<ul class="flipMenu" imagepath="{$topdocdir}/js/flipmenu">
<xsl:call-template name="menu.chapter">
diff --git a/lib/erl_docgen/src/docgen_edoc_xml_cb.erl b/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
index 0ac7985a48..7cdbb502d9 100644
--- a/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
+++ b/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +10,10 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
+%% Copyright (c) 2001-2016 Richard Carlsson. Parts written by Ericsson
+%% are Copyright (c) Ericsson AB 2001-2012. All Rights Reserved.
%%
+
-module(docgen_edoc_xml_cb).
%% This is the EDoc callback module for creating erlref
@@ -27,7 +24,7 @@
%% {preprocess,true}]).
%%
%% The origin of this file is the edoc module otpsgml_layout.erl
-%% written by Richard Carlsson.
+%% written by Richard Carlsson and Kenneth Lundin.
-export([module/2, overview/2]).
@@ -111,7 +108,16 @@ root_attributes(Element, Opts) ->
Enc ->
Enc
end,
- [#xmlAttribute{name=encoding, value=Encoding}].
+ [#xmlAttribute{name=encoding, value=reformat_encoding(Encoding)}].
+
+%% epp:default_encoding/0 returns 'utf8'
+reformat_encoding(utf8) -> "UTF-8";
+reformat_encoding(List) when is_list(List) ->
+ case string:to_lower(List) of
+ "utf8" -> "UTF-8";
+ _ -> List
+ end;
+reformat_encoding(Other) -> Other.
layout_chapter(#xmlElement{name=overview, content=Es}) ->
Title = get_text(title, Es),
@@ -563,7 +569,14 @@ otp_xmlify_a_fileref(FileRef1, AppS) ->
true ->
case split(Marker0, "-") of
[Func,Arity] ->
- Func++"/"++Arity;
+ try list_to_integer(Arity) of
+ _ ->
+ Func++"/"++Arity
+ catch
+ _:_ ->
+ %% This is "type-"<a-type>.
+ Marker0
+ end;
_ ->
Marker0
end
@@ -831,19 +844,49 @@ local_types([]) -> [];
local_types(Es) ->
local_defs2(get_elem(localdef, Es)).
+-define(LOCAL_TYPES, edoc_local_defs).
+
local_defs2([]) -> [];
local_defs2(Es) ->
+ case collect_local_types(Es) of
+ [] -> local_defs3(Es);
+ LocalTypes ->
+ ?LOCAL_TYPES = ets:new(?LOCAL_TYPES, [named_table]),
+ true = ets:insert(?LOCAL_TYPES, LocalTypes),
+ try
+ local_defs3(Es)
+ after
+ ets:delete(?LOCAL_TYPES)
+ end
+ end.
+
+local_defs3(Es) ->
{type,[?NL | [{v, localdef2(E)} || E <- Es]]}.
+%% Does not work well for parametrized types.
+collect_local_types(Es) ->
+ lists:append([collect_local_type(E) || E <- Es]).
+
+collect_local_type(#xmlElement{content = Es}) ->
+ case get_elem(typevar, Es) of
+ [] ->
+ [{t_abstype(get_content(abstype, Es))}];
+ [_] ->
+ []
+ end.
+
%% Like localdef/1, but does not use label_anchor/2 -- we don't want any
%% markers or em tags in <v> tag, plain text only!
+%% When used stand-alone, EDoc generates links to local types. An ETS
+%% table holds local types, to avoid generating links to them.
localdef2(#xmlElement{content = Es}) ->
- case get_elem(typevar, Es) of
- [] ->
- t_utype(get_elem(type, Es));
- [V] ->
- t_var(V) ++ [" = "] ++ t_utype(get_elem(type, Es))
- end.
+ Var = case get_elem(typevar, Es) of
+ [] ->
+ [t_abstype(get_content(abstype, Es))];
+ [V] ->
+ t_var(V)
+ end,
+ Var ++ [" = "] ++ t_utype(get_elem(type, Es)).
type_name(#xmlElement{content = Es}) ->
t_name(get_elem(erlangName, get_content(typedef, Es))).
@@ -855,10 +898,9 @@ types(Ts) ->
typedecl(Name, #xmlElement{content = Es}) ->
TypedefEs = get_content(typedef, Es),
Id = "type-"++Name,
- [{tag, typedef(TypedefEs)},
+ [{tag, [{marker,[{id,Id}],[]}] ++ typedef(TypedefEs)},
?NL,
- {item, [{marker,[{id,Id}],[]} |
- local_defs(get_elem(localdef, TypedefEs)) ++ fulldesc(Es)]},
+ {item, local_defs(get_elem(localdef, TypedefEs)) ++ fulldesc(Es)},
?NL].
typedef(Es) ->
@@ -866,14 +908,14 @@ typedef(Es) ->
++ seq(fun t_utype_elem/1, get_content(argtypes, Es), [")"])),
case get_elem(type, Es) of
[] ->
- [{tt, Name}];
+ Name;
Type ->
- [{tt, Name ++ [" = "] ++ t_utype(Type)}]
+ Name ++ [" = "] ++ t_utype(Type)
end.
-local_defs([]) -> [];
+local_defs([]) -> [{p,[]}];
local_defs(Es) ->
- [?NL, {ul, [{li, [{tt, localdef(E)}]} || E <- Es]}].
+ [?NL, {ul, [{li, [{p, localdef(E)}]} || E <- Es]}].
localdef(E = #xmlElement{content = Es}) ->
Var = case get_elem(typevar, Es) of
@@ -917,6 +959,7 @@ seealso_module(Es) ->
Es1 ->
{section,[{title,["See also"]},{p,seq(fun see/1, Es1, [])}]}
end.
+
seealso_function(Es) ->
case get_elem(see, Es) of
[] -> [];
@@ -988,7 +1031,14 @@ t_name([E]) ->
end.
t_utype([E]) ->
- t_utype_elem(E).
+ flatten_type(t_utype_elem(E)).
+
+%% Make sure see also are top elements of lists.
+flatten_type(T) ->
+ [case is_integer(E) of
+ true -> [E];
+ false -> E
+ end || E <- lists:flatten(T)].
t_utype_elem(E=#xmlElement{content = Es}) ->
case get_attrval(name, E) of
@@ -1021,16 +1071,14 @@ t_type([#xmlElement{name = tuple, content = Es}]) ->
t_tuple(Es);
t_type([#xmlElement{name = 'fun', content = Es}]) ->
t_fun(Es);
-t_type([#xmlElement{name = abstype, content = Es}]) ->
- t_abstype(Es);
+t_type([E = #xmlElement{name = abstype, content = Es}]) ->
+ t_abstype(E, Es);
t_type([#xmlElement{name = union, content = Es}]) ->
t_union(Es);
t_type([#xmlElement{name = record, content = Es}]) ->
t_record(Es);
t_type([#xmlElement{name = map, content = Es}]) ->
- t_map(Es);
-t_type([#xmlElement{name = map_field, content = Es}]) ->
- t_map_field(Es).
+ t_map(Es).
t_var(E) ->
[get_attrval(name, E)].
@@ -1065,35 +1113,53 @@ t_fun(Es) ->
t_record([E|Es]) ->
["#", get_attrval(value, E), "{"++ seq(fun t_field/1, Es) ++"}"].
+
t_field(#xmlElement{name=field, content=[Atom,Type]}) ->
[get_attrval(value, Atom), "="] ++ t_utype_elem(Type).
t_map(Es) ->
- ["#{"] ++ seq(fun t_utype_elem/1, Es, ["}"]).
+ ["#{"] ++ seq(fun t_map_field/1, Es, ["}"]).
+
+t_map_field(E = #xmlElement{name = map_field, content = [K,V]}) ->
+ KElem = t_utype_elem(K),
+ VElem = t_utype_elem(V),
+ AS = case get_attrval(assoc_type, E) of
+ "assoc" -> " => ";
+ "exact" -> " := "
+ end,
+ [KElem ++ AS ++ VElem].
-t_map_field([K,V]) ->
- [t_utype_elem(K) ++ " => " ++ t_utype_elem(V)].
+t_abstype(E, Es) ->
+ see_type(E, t_abstype(Es)).
t_abstype(Es) ->
- case split_at_colon(t_name(get_elem(erlangName, Es)),[]) of
- {Mod,Type} ->
- [Type, "("] ++
- seq(fun t_utype_elem/1, get_elem(type, Es), [")"]) ++
- [" (see module ", Mod, ")"];
- Type ->
- [Type, "("] ++
- seq(fun t_utype_elem/1, get_elem(type, Es), [")"])
+ Name = t_name(get_elem(erlangName, Es)),
+ [Name, "("] ++ seq(fun t_utype_elem/1, get_elem(type, Es), [")"]).
+
+see_type(E, Es0) ->
+ case get_attrval(href, E) of
+ [] -> Es0;
+ Href0 ->
+ try
+ false = is_local_type(Es0),
+ %% Fails for parametrized types:
+ Text = #xmlText{value = lists:append(Es0)},
+ {Href, Es} = otp_xmlify_a_href(Href0, [Text]),
+ [{seealso, [{marker, Href}], Es}]
+ catch
+ _:_ ->
+ Es0
+ end
end.
-%% Split at one colon, but not at two (or more)
-split_at_colon([$:,$:|_]=Rest,Acc) ->
- lists:reverse(Acc)++Rest;
-split_at_colon([$:|Type],Acc) ->
- {lists:reverse(Acc),Type};
-split_at_colon([Char|Rest],Acc) ->
- split_at_colon(Rest,[Char|Acc]);
-split_at_colon([],Acc) ->
- lists:reverse(Acc).
+is_local_type(Es) ->
+ try
+ [_] = ets:lookup(?LOCAL_TYPES, Es),
+ true
+ catch
+ _:_->
+ false
+ end.
t_union(Es) ->
seq(fun t_utype_elem/1, Es, " | ", []).
diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk
index 98d1c3f7be..8fad061b26 100644
--- a/lib/erl_docgen/vsn.mk
+++ b/lib/erl_docgen/vsn.mk
@@ -1 +1 @@
-ERL_DOCGEN_VSN = 0.5
+ERL_DOCGEN_VSN = 0.7
diff --git a/lib/erl_interface/doc/src/book.xml b/lib/erl_interface/doc/src/book.xml
index c9194d96ff..94bfef7455 100644
--- a/lib/erl_interface/doc/src/book.xml
+++ b/lib/erl_interface/doc/src/book.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,19 +19,19 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
- <title>Erlang Interface</title>
+ <title>Erl_Interface</title>
<prepared>Gordon Beaton</prepared>
<docno></docno>
<date>1998-11-30</date>
<rev>1.2</rev>
- <file>book.sgml</file>
+ <file>book.xml</file>
</header>
<insidecover>
</insidecover>
- <pagetext>Erlang Interface</pagetext>
+ <pagetext>Erl_Interface</pagetext>
<preamble>
<contents level="2"></contents>
</preamble>
@@ -47,4 +47,3 @@
<listofterms></listofterms>
<index></index>
</book>
-
diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml
index 1177954eb9..9502fb1ee7 100644
--- a/lib/erl_interface/doc/src/ei.xml
+++ b/lib/erl_interface/doc/src/ei.xml
@@ -4,14 +4,14 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2016</year>
+ <year>2001</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -30,361 +30,502 @@
<checked></checked>
<date>2000-11-27</date>
<rev>PA1</rev>
- <file>ei.sgml</file>
+ <file>ei.xml</file>
</header>
<lib>ei</lib>
- <libsummary>routines for handling the erlang binary term format</libsummary>
+ <libsummary>Routines for handling the Erlang binary term format.</libsummary>
<description>
- <p>The library <c><![CDATA[ei]]></c> contains macros and functions to encode
- and decode the erlang binary term format.</p>
- <p>With <c><![CDATA[ei]]></c>, you can convert atoms, lists, numbers and
+ <p>The library <c>ei</c> contains macros and functions to encode
+ and decode the Erlang binary term format.</p>
+
+ <p><c>ei</c> allows you to convert atoms, lists, numbers, and
binaries to and from the binary format. This is useful when
- writing port programs and drivers. <c><![CDATA[ei]]></c> uses a given
- buffer, and no dynamic memory (with the exception of
- <c><![CDATA[ei_decode_fun()]]></c>), and is often quite fast.</p>
- <p>It also handles C-nodes, C-programs that talks erlang
- distribution with erlang nodes (or other C-nodes) using the
- erlang distribution format. The difference between <c><![CDATA[ei]]></c> and
- <c><![CDATA[erl_interface]]></c> is that <c><![CDATA[ei]]></c> uses the binary format
- directly when sending and receiving terms. It is also thread
- safe, and using threads, one process can handle multiple
- C-nodes. The <c><![CDATA[erl_interface]]></c> library is built on top of
- <c><![CDATA[ei]]></c>, but of legacy reasons, it doesn't allow for multiple
- C-nodes. In general, <c><![CDATA[ei]]></c> is the preferred way of doing
- C-nodes.</p>
- <p>The decode and encode functions use a buffer an index into the
+ writing port programs and drivers. <c>ei</c> uses a given
+ buffer, no dynamic memory (except
+ <c>ei_decode_fun()</c>) and is often quite fast.</p>
+
+ <p><c>ei</c> also handles C-nodes, C-programs that talks Erlang
+ distribution with Erlang nodes (or other C-nodes) using the
+ Erlang distribution format. The difference between <c>ei</c>
+ and <c>erl_interface</c> is that <c>ei</c> uses
+ the binary format directly when sending and receiving terms. It is also
+ thread safe, and using threads, one process can handle multiple
+ C-nodes. The <c>erl_interface</c> library is built on top of
+ <c>ei</c>, but of legacy reasons, it does not allow for
+ multiple C-nodes. In general, <c>ei</c> is the preferred way
+ of doing C-nodes.</p>
+
+ <p>The decode and encode functions use a buffer and an index into the
buffer, which points at the point where to encode and
decode. The index is updated to point right after the term
encoded/decoded. No checking is done whether the term fits in
the buffer or not. If encoding goes outside the buffer, the
- program may crash.</p>
- <p>All functions takes two parameter, <c><![CDATA[buf]]></c> is a pointer to
- the buffer where the binary data is / will be, <c><![CDATA[index]]></c> is a
- pointer to an index into the buffer. This parameter will be
- incremented with the size of the term decoded / encoded. The
- data is thus at <c><![CDATA[buf[*index]]]></c> when an <c><![CDATA[ei]]></c> function is
- called.</p>
- <p>The encode functions all assumes that the <c><![CDATA[buf]]></c> and
- <c><![CDATA[index]]></c> parameters points to a buffer big enough for the
- data. To get the size of an encoded term, without encoding it,
- pass <c><![CDATA[NULL]]></c> instead of a buffer pointer. The <c><![CDATA[index]]></c>
- parameter will be incremented, but nothing will be encoded. This
- is the way in <c><![CDATA[ei]]></c> to "preflight" term encoding.</p>
- <p>There are also encode-functions that uses a dynamic buffer. It
+ program can crash.</p>
+
+ <p>All functions take two parameters:</p>
+
+ <list type="bulleted">
+ <item><p><c>buf</c> is a pointer to
+ the buffer where the binary data is or will be.</p>
+ </item>
+ <item><p><c>index</c> is a pointer to an index into the
+ buffer. This parameter is incremented with the size of the term
+ decoded/encoded.</p>
+ </item>
+ </list>
+
+ <p>The data is thus at <c>buf[*index]</c> when an
+ <c>ei</c> function is called.</p>
+
+ <p>All encode functions assume that the <c>buf</c> and
+ <c>index</c> parameters point to a buffer large enough for
+ the data. To get the size of an encoded term, without encoding it,
+ pass <c>NULL</c> instead of a buffer pointer. Parameter
+ <c>index</c> is incremented, but nothing will be encoded. This
+ is the way in <c>ei</c> to "preflight" term encoding.</p>
+
+ <p>There are also encode functions that use a dynamic buffer. It
is often more convenient to use these to encode data. All encode
- functions comes in two versions: those starting with <c><![CDATA[ei_x]]></c>,
- uses a dynamic buffer.</p>
- <p>All functions return <c><![CDATA[0]]></c> if successful, and <c><![CDATA[-1]]></c> if
- not. (For instance, if a term is not of the expected type, or
- the data to decode is not a valid erlang term.)</p>
- <p>Some of the decode-functions needs a preallocated buffer. This
- buffer must be allocated big enough, and for non compound types
- the <c><![CDATA[ei_get_type()]]></c>
- function returns the size required (note that for strings an
- extra byte is needed for the 0 string terminator).</p>
+ functions comes in two versions; those starting with
+ <c>ei_x</c> use a dynamic buffer.</p>
+
+ <p>All functions return <c>0</c> if successful, otherwise
+ <c>-1</c> (for example, if a term is not of the expected
+ type, or the data to decode is an invalid Erlang term).</p>
+
+ <p>Some of the decode functions need a pre-allocated buffer. This
+ buffer must be allocated large enough, and for non-compound types
+ the <c>ei_get_type()</c>
+ function returns the size required (notice that for strings an
+ extra byte is needed for the <c>NULL</c>-terminator).</p>
</description>
- <section>
- <title>DATA TYPES</title>
+ <section>
+ <title>Data Types</title>
<taglist>
<tag><marker id="erlang_char_encoding"/>erlang_char_encoding</tag>
<item>
- <p/>
<code type="none">
typedef enum {
ERLANG_ASCII = 1,
ERLANG_LATIN1 = 2,
ERLANG_UTF8 = 4
-}erlang_char_encoding;
-</code>
- <p>The character encodings used for atoms. <c>ERLANG_ASCII</c> represents 7-bit ASCII.
- Latin1 and UTF8 are different extensions of 7-bit ASCII. All 7-bit ASCII characters
- are valid Latin1 and UTF8 characters. ASCII and Latin1 both represent each character
- by one byte. A UTF8 character can consist of one to four bytes. Note that these
- constants are bit-flags and can be combined with bitwise-or.</p>
+} erlang_char_encoding;</code>
+ <p>The character encodings used for atoms. <c>ERLANG_ASCII</c>
+ represents 7-bit ASCII. Latin-1 and UTF-8 are different extensions
+ of 7-bit ASCII. All 7-bit ASCII characters are valid Latin-1 and
+ UTF-8 characters. ASCII and Latin-1 both represent each character
+ by one byte. An UTF-8 character can consist of 1-4 bytes.
+ Notice that these constants are bit-flags and can be combined with
+ bitwise OR.</p>
</item>
</taglist>
</section>
+
<funcs>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_atom(const char *buf, int *index, char *p)</nametext></name>
+ <fsummary>Decode an atom.</fsummary>
+ <desc>
+ <p>Decodes an atom from the binary format. The <c>NULL</c>-terminated
+ name of the atom is placed at <c>p</c>. At most
+ <c>MAXATOMLEN</c> bytes can be placed in the buffer.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_atom_as(const char *buf, int *index, char *p, int plen, erlang_char_encoding want, erlang_char_encoding* was, erlang_char_encoding* result)</nametext></name>
+ <fsummary>Decode an atom.</fsummary>
+ <desc>
+ <p>Decodes an atom from the binary format. The <c>NULL</c>-terminated
+ name of the atom is placed in buffer at <c>p</c> of length <c>plen</c>
+ bytes.</p>
+ <p>The wanted string encoding is specified by
+ <seealso marker="#erlang_char_encoding"><c>want</c></seealso>.
+ The original encoding used in the binary format (Latin-1 or UTF-8) can
+ be obtained from <c>*was</c>. The encoding of the resulting string
+ (7-bit ASCII, Latin-1, or UTF-8) can be obtained from <c>*result</c>.
+ Both <c>was</c> and <c>result</c> can be <c>NULL</c>. <c>*result</c>
+ can differ from <c>want</c> if <c>want</c> is a bitwise OR'd
+ combination like <c>ERLANG_LATIN1|ERLANG_UTF8</c> or if
+ <c>*result</c> turns out to be pure 7-bit ASCII
+ (compatible with both Latin-1 and UTF-8).</p>
+ <p>This function fails if the atom is too long for the buffer
+ or if it cannot be represented with encoding <c>want</c>.</p>
+ <p>This function was introduced in Erlang/OTP R16 as part of a first
+ step to support UTF-8 atoms.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_bignum(const char *buf, int *index, mpz_t obj)</nametext></name>
+ <fsummary>Decode a GMP arbitrary precision integer.</fsummary>
+ <desc>
+ <p>Decodes an integer in the binary format to a GMP
+ <c>mpz_t</c> integer. To use this function, the <c>ei</c>
+ library must be configured and compiled to use the GMP library.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_binary(const char *buf, int *index, void *p, long *len)</nametext></name>
+ <fsummary>Decode a binary.</fsummary>
+ <desc>
+ <p>Decodes a binary from the binary format. Parameter
+ <c>len</c> is set to the actual size of the
+ binary. Notice that <c>ei_decode_binary()</c> assumes that
+ there is enough room for the binary. The size required can be
+ fetched by <c>ei_get_type()</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_boolean(const char *buf, int *index, int *p)</nametext></name>
+ <fsummary>Decode a boolean.</fsummary>
+ <desc>
+ <p>Decodes a boolean value from the binary format.
+ A boolean is actually an atom, <c>true</c> decodes 1
+ and <c>false</c> decodes 0.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_char(const char *buf, int *index, char *p)</nametext></name>
+ <fsummary>Decode an 8-bit integer between 0-255.</fsummary>
+ <desc>
+ <p>Decodes a char (8-bit) integer between 0-255 from the binary format.
+ For historical reasons the returned integer is of
+ type <c>char</c>. Your C code is to consider the
+ returned value to be of type <c>unsigned char</c> even if
+ the C compilers and system can define <c>char</c> to be
+ signed.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_double(const char *buf, int *index, double *p)</nametext></name>
+ <fsummary>Decode a double.</fsummary>
+ <desc>
+ <p>Decodes a double-precision (64-bit) floating
+ point number from the binary format.</p>
+ </desc>
+ </func>
+
<func>
- <name><ret>void</ret><nametext>ei_set_compat_rel(release_number)</nametext></name>
- <fsummary>Set the ei library in compatibility mode</fsummary>
- <type>
- <v>unsigned release_number;</v>
- </type>
+ <name><ret>int</ret><nametext>ei_decode_ei_term(const char* buf, int* index, ei_term* term)</nametext></name>
+ <fsummary>Decode a term, without previous knowledge of type.</fsummary>
+ <desc>
+ <p>Decodes any term, or at least tries to. If the term
+ pointed at by <c>*index</c> in <c>buf</c> fits
+ in the <c>term</c> union, it is decoded, and the
+ appropriate field in <c>term->value</c> is set, and
+ <c>*index</c> is incremented by the term size.</p>
+ <p>The function returns <c>1</c> on successful decoding, <c>-1</c> on
+ error, and <c>0</c> if the term seems alright, but does not fit in the
+ <c>term</c> structure. If <c>1</c> is returned, the
+ <c>index</c> is incremented, and <c>term</c>
+ contains the decoded term.</p>
+ <p>The <c>term</c> structure contains the arity for a tuple
+ or list, size for a binary, string, or atom. It contains
+ a term if it is any of the following: integer, float, atom,
+ pid, port, or ref.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_fun(const char *buf, int *index, erlang_fun *p)</nametext></name>
+ <name><ret>void</ret><nametext>free_fun(erlang_fun* f)</nametext></name>
+ <fsummary>Decode a fun.</fsummary>
<desc>
- <marker id="ei_set_compat_rel"></marker>
- <p>By default, the <c><![CDATA[ei]]></c> library is only guaranteed
- to be compatible with other Erlang/OTP components from the same
- release as the <c><![CDATA[ei]]></c> library itself. For example, <c><![CDATA[ei]]></c> from
- the OTP R10 release is not compatible with an Erlang emulator
- from the OTP R9 release by default.</p>
- <p>A call to <c><![CDATA[ei_set_compat_rel(release_number)]]></c> sets the
- <c><![CDATA[ei]]></c> library in compatibility mode of release
- <c><![CDATA[release_number]]></c>. Valid range of <c><![CDATA[release_number]]></c>
- is [7, current release]. This makes it possible to
- communicate with Erlang/OTP components from earlier releases.</p>
- <note>
- <p>If this function is called, it may only be called once
- and must be called before any other functions in the <c><![CDATA[ei]]></c>
- library is called.</p>
- </note>
- <warning>
- <p>You may run into trouble if this feature is used
- carelessly. Always make sure that all communicating
- components are either from the same Erlang/OTP release, or
- from release X and release Y where all components
- from release Y are in compatibility mode of release X.</p>
- </warning>
+ <p>Decodes a fun from the binary format. Parameter
+ <c>p</c> is to be <c>NULL</c> or point to an
+ <c>erlang_fun</c> structure. This is the only decode
+ function that allocates memory. When the <c>erlang_fun</c>
+ is no longer needed, it is to be freed with
+ <c>free_fun</c>. (This has to do with the arbitrary size
+ of the environment for a fun.)</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_version(char *buf, int *index)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_version(ei_x_buff* x)</nametext></name>
- <fsummary>Encode version</fsummary>
+ <name><ret>int</ret><nametext>ei_decode_list_header(const char *buf, int *index, int *arity)</nametext></name>
+ <fsummary>Decode a list.</fsummary>
<desc>
- <p>Encodes a version magic number for the binary format. Must
- be the first token in a binary term.</p>
+ <p>Decodes a list header from the binary
+ format. The number of elements is returned in
+ <c>arity</c>. The <c>arity+1</c> elements
+ follow (the last one is the tail of the list, normally an empty list).
+ If <c>arity</c> is <c>0</c>, it is an empty
+ list.</p>
+ <p>Notice that lists are encoded as strings if they consist
+ entirely of integers in the range 0..255. This function do
+ not decode such strings, use <c>ei_decode_string()</c>
+ instead.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_long(char *buf, int *index, long p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_long(ei_x_buff* x, long p)</nametext></name>
- <fsummary>Encode integer</fsummary>
+ <name><ret>int</ret><nametext>ei_decode_long(const char *buf, int *index, long *p)</nametext></name>
+ <fsummary>Decode integer.</fsummary>
<desc>
- <p>Encodes a long integer in the binary format.
- Note that if the code is 64 bits the function ei_encode_long() is
- exactly the same as ei_encode_longlong().</p>
+ <p>Decodes a long integer from the binary format.
+ If the code is 64 bits, the function <c>ei_decode_long()</c> is
+ the same as <c>ei_decode_longlong()</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_ulong(char *buf, int *index, unsigned long p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_ulong(ei_x_buff* x, unsigned long p)</nametext></name>
- <fsummary>Encode unsigned integer</fsummary>
+ <name><ret>int</ret><nametext>ei_decode_longlong(const char *buf, int *index, long long *p)</nametext></name>
+ <fsummary>Decode integer.</fsummary>
<desc>
- <p>Encodes an unsigned long integer in the binary format.
- Note that if the code is 64 bits the function ei_encode_ulong() is
- exactly the same as ei_encode_ulonglong().</p>
+ <p>Decodes a GCC <c>long long</c> or Visual C++
+ <c>__int64</c>
+ (64-bit) integer from the binary format. This
+ function is missing in the VxWorks port.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_longlong(char *buf, int *index, long long p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_longlong(ei_x_buff* x, long long p)</nametext></name>
- <fsummary>Encode integer</fsummary>
+ <name><ret>int</ret><nametext>ei_decode_map_header(const char *buf, int *index, int *arity)</nametext></name>
+ <fsummary>Decode a map.</fsummary>
<desc>
- <p>Encodes a GCC <c><![CDATA[long long]]></c> or Visual C++ <c><![CDATA[__int64]]></c> (64 bit)
- integer in the binary format. Note that this function is missing
- in the VxWorks port.</p>
+ <p>Decodes a map header from the binary
+ format. The number of key-value pairs is returned in
+ <c>*arity</c>. Keys and values follow in this order:
+ <c>K1, V1, K2, V2, ..., Kn, Vn</c>. This makes a total of
+ <c>arity*2</c> terms. If <c>arity</c> is zero, it is an empty map.
+ A correctly encoded map does not have duplicate keys.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_ulonglong(char *buf, int *index, unsigned long long p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_ulonglong(ei_x_buff* x, unsigned long long p)</nametext></name>
- <fsummary>Encode unsigned integer</fsummary>
+ <name><ret>int</ret><nametext>ei_decode_pid(const char *buf, int *index, erlang_pid *p)</nametext></name>
+ <fsummary>Decode a <c>pid</c>.</fsummary>
<desc>
- <p>Encodes a GCC <c><![CDATA[unsigned long long]]></c> or Visual C++ <c><![CDATA[unsigned __int64]]></c> (64 bit) integer in the binary format. Note that
- this function is missing in the VxWorks port.</p>
+ <p>Decodes a process identifier (pid) from the binary format.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_bignum(char *buf, int *index, mpz_t obj)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_bignum(ei_x_buff *x, mpz_t obj)</nametext></name>
- <fsummary>Encode an arbitrary precision integer</fsummary>
+ <name><ret>int</ret><nametext>ei_decode_port(const char *buf, int *index, erlang_port *p)</nametext></name>
+ <fsummary>Decode a port.</fsummary>
<desc>
- <p>Encodes a GMP <c><![CDATA[mpz_t]]></c> integer to binary format.
- To use this function the ei library needs to be configured and compiled
- to use the GMP library. </p>
+ <p>Decodes a port identifier from the binary format.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_double(char *buf, int *index, double p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_double(ei_x_buff* x, double p)</nametext></name>
- <fsummary>Encode a double float</fsummary>
+ <name><ret>int</ret><nametext>ei_decode_ref(const char *buf, int *index, erlang_ref *p)</nametext></name>
+ <fsummary>Decode a reference.</fsummary>
<desc>
- <p>Encodes a double-precision (64 bit) floating point number in
- the binary format.</p>
- <p>
- The function returns <c><![CDATA[-1]]></c> if the floating point number is not finite.
- </p>
+ <p>Decodes a reference from the binary format.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_boolean(char *buf, int *index, int p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_boolean(ei_x_buff* x, int p)</nametext></name>
- <fsummary>Encode a boolean</fsummary>
+ <name><ret>int</ret><nametext>ei_decode_string(const char *buf, int *index, char *p)</nametext></name>
+ <fsummary>Decode a string.</fsummary>
<desc>
- <p>Encodes a boolean value, as the atom <c><![CDATA[true]]></c> if p is not
- zero or <c><![CDATA[false]]></c> if p is zero.</p>
+ <p>Decodes a string from the binary format. A
+ string in Erlang is a list of integers between 0 and
+ 255. Notice that as the string is just a list, sometimes
+ lists are encoded as strings by <c>term_to_binary/1</c>,
+ even if it was not intended.</p>
+ <p>The string is copied to <c>p</c>, and enough space must
+ be allocated. The returned string is <c>NULL</c>-terminated, so you
+ must add an extra byte to the memory requirement.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_char(char *buf, int *index, char p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_char(ei_x_buff* x, char p)</nametext></name>
- <fsummary>Encode an 8-bit integer between 0-255</fsummary>
+ <name><ret>int</ret><nametext>ei_decode_term(const char *buf, int *index, void *t)</nametext></name>
+ <fsummary>Decode a <c>ETERM</c>.</fsummary>
+ <desc>
+ <p>Decodes a term from the binary format. The term
+ is return in <c>t</c> as a <c>ETERM*</c>, so
+ <c>t</c> is actually an <c>ETERM**</c> (see
+ <seealso marker="erl_eterm"><c>erl_eterm</c></seealso>).
+ The term is later to be deallocated.</p>
+ <p>Notice that this function is located in the <c>Erl_Interface</c>
+ library.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_trace(const char *buf, int *index, erlang_trace *p)</nametext></name>
+ <fsummary>Decode a trace token.</fsummary>
<desc>
- <p>Encodes a char (8-bit) as an integer between 0-255 in the binary format.
- Note that for historical reasons the integer argument is of
- type <c><![CDATA[char]]></c>. Your C code should consider the
- given argument to be of type <c><![CDATA[unsigned char]]></c> even if
- the C compilers and system may define <c><![CDATA[char]]></c> to be
- signed.</p>
+ <p>Decodes an Erlang trace token from the binary format.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_string(char *buf, int *index, const char *p)</nametext></name>
- <name><ret>int</ret><nametext>ei_encode_string_len(char *buf, int *index, const char *p, int len)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_string(ei_x_buff* x, const char *p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_string_len(ei_x_buff* x, const char* s, int len)</nametext></name>
- <fsummary>Encode a string</fsummary>
+ <name><ret>int</ret><nametext>ei_decode_tuple_header(const char *buf, int *index, int *arity)</nametext></name>
+ <fsummary>Decode a tuple.</fsummary>
<desc>
- <p>Encodes a string in the binary format. (A string in erlang
- is a list, but is encoded as a character array in the binary
- format.) The string should be zero-terminated, except for
- the <c><![CDATA[ei_x_encode_string_len()]]></c> function.</p>
+ <p>Decodes a tuple header, the number of elements
+ is returned in <c>arity</c>. The tuple elements follow
+ in order in the buffer.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_ulong(const char *buf, int *index, unsigned long *p)</nametext></name>
+ <fsummary>Decode unsigned integer.</fsummary>
+ <desc>
+ <p>Decodes an unsigned long integer from the binary format.
+ If the code is 64 bits, the function <c>ei_decode_ulong()</c> is
+ the same as <c>ei_decode_ulonglong()</c>.</p>
</desc>
</func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_ulonglong(const char *buf, int *index, unsigned long long *p)</nametext></name>
+ <fsummary>Decode unsigned integer.</fsummary>
+ <desc>
+ <p>Decodes a GCC <c>unsigned long long</c> or Visual C++
+ <c>unsigned __int64</c> (64-bit) integer from the binary
+ format. This function is missing in the VxWorks port.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_version(const char *buf, int *index, int *version)</nametext></name>
+ <fsummary>Decode an empty list (<c>nil</c>).</fsummary>
+ <desc>
+ <p>Decodes the version magic number for the
+ Erlang binary term format. It must be the first token in a
+ binary term.</p>
+ </desc>
+ </func>
+
<func>
<name><ret>int</ret><nametext>ei_encode_atom(char *buf, int *index, const char *p)</nametext></name>
<name><ret>int</ret><nametext>ei_encode_atom_len(char *buf, int *index, const char *p, int len)</nametext></name>
<name><ret>int</ret><nametext>ei_x_encode_atom(ei_x_buff* x, const char *p)</nametext></name>
<name><ret>int</ret><nametext>ei_x_encode_atom_len(ei_x_buff* x, const char *p, int len)</nametext></name>
- <fsummary>Encode an atom</fsummary>
+ <fsummary>Encode an atom.</fsummary>
<desc>
- <p>Encodes an atom in the binary format. The <c><![CDATA[p]]></c> parameter
- is the name of the atom in latin1 encoding. Only upto <c>MAXATOMLEN-1</c> bytes
- are encoded. The name should be zero-terminated, except for
- the <c><![CDATA[ei_x_encode_atom_len()]]></c> function.</p>
+ <p>Encodes an atom in the binary format. Parameter <c>p</c>
+ is the name of the atom in Latin-1 encoding. Only up to
+ <c>MAXATOMLEN-1</c> bytes
+ are encoded. The name is to be <c>NULL</c>-terminated, except for
+ the <c>ei_x_encode_atom_len()</c> function.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_encode_atom_as(char *buf, int *index, const char *p, erlang_char_encoding from_enc, erlang_char_encoding to_enc)</nametext></name>
<name><ret>int</ret><nametext>ei_encode_atom_len_as(char *buf, int *index, const char *p, int len, erlang_char_encoding from_enc, erlang_char_encoding to_enc)</nametext></name>
<name><ret>int</ret><nametext>ei_x_encode_atom_as(ei_x_buff* x, const char *p, erlang_char_encoding from_enc, erlang_char_encoding to_enc)</nametext></name>
<name><ret>int</ret><nametext>ei_x_encode_atom_len_as(ei_x_buff* x, const char *p, int len, erlang_char_encoding from_enc, erlang_char_encoding to_enc)</nametext></name>
- <fsummary>Encode an atom</fsummary>
- <desc>
- <p>Encodes an atom in the binary format with character encoding
- <seealso marker="#erlang_char_encoding"><c>to_enc</c></seealso> (latin1 or utf8).
- The <c>p</c> parameter is the name of the atom with character encoding
- <seealso marker="#erlang_char_encoding"><c>from_enc</c></seealso> (ascii, latin1 or utf8).
- The name must either be zero-terminated or a function variant with a <c>len</c>
- parameter must be used. If <c>to_enc</c> is set to the bitwise-or'd combination
- <c>(ERLANG_LATIN1|ERLANG_UTF8)</c>, utf8 encoding is only used if the atom string
- can not be represented in latin1 encoding.</p>
- <p>The encoding will fail if <c>p</c> is not a valid string in encoding <c>from_enc</c>,
- if the string is too long or if it can not be represented with character encoding <c>to_enc</c>.</p>
- <p>These functions were introduced in R16 release of Erlang/OTP as part of a first step
- to support UTF8 atoms. Atoms encoded with <c>ERLANG_UTF8</c>
- can not be decoded by earlier releases than R16.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_encode_binary(char *buf, int *index, const void *p, long len)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_binary(ei_x_buff* x, const void *p, long len)</nametext></name>
- <fsummary>Encode a binary</fsummary>
- <desc>
- <p>Encodes a binary in the binary format. The data is at
- <c><![CDATA[p]]></c>, of <c><![CDATA[len]]></c> bytes length.</p>
+ <fsummary>Encode an atom.</fsummary>
+ <desc>
+ <p>Encodes an atom in the binary format. Parameter <c>p</c> is the name of the atom with
+ character encoding
+ <seealso marker="#erlang_char_encoding"><c>from_enc</c></seealso>
+ (ASCII, Latin-1, or UTF-8). The name must either be <c>NULL</c>-terminated or
+ a function variant with a <c>len</c> parameter must be used.</p>
+ <p>The encoding fails if <c>p</c> is not a valid string in encoding
+ <c>from_enc</c>.</p>
+
+ <p>Argument <c>to_enc</c> is ignored. As from Erlang/OTP 20 the encoding is always
+ done in UTF-8 which is readable by nodes as old as Erlang/OTP R16.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_pid(char *buf, int *index, const erlang_pid *p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_pid(ei_x_buff* x, const erlang_pid *p)</nametext></name>
- <fsummary>Encode a pid</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_bignum(char *buf, int *index, mpz_t obj)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_bignum(ei_x_buff *x, mpz_t obj)</nametext></name>
+ <fsummary>Encode an arbitrary precision integer.</fsummary>
<desc>
- <p>Encodes an erlang process identifier, pid, in the binary
- format. The <c><![CDATA[p]]></c> parameter points to an
- <c><![CDATA[erlang_pid]]></c> structure (which should have been obtained
- earlier with <c><![CDATA[ei_decode_pid()]]></c>).</p>
+ <p>Encodes a GMP <c>mpz_t</c> integer to binary format.
+ To use this function, the <c>ei</c> library must be configured and
+ compiled to use the GMP library.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_fun(char *buf, int *index, const erlang_fun *p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun)</nametext></name>
- <fsummary>Encode a fun</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_binary(char *buf, int *index, const void *p, long len)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_binary(ei_x_buff* x, const void *p, long len)</nametext></name>
+ <fsummary>Encode a binary.</fsummary>
<desc>
- <p>Encodes a fun in the binary format. The <c><![CDATA[p]]></c> parameter
- points to an <c><![CDATA[erlang_fun]]></c> structure. The
- <c><![CDATA[erlang_fun]]></c> is not freed automatically, the
- <c><![CDATA[free_fun]]></c> should be called if the fun is not needed
- after encoding.</p>
+ <p>Encodes a binary in the binary format. The data is at
+ <c>p</c>, of <c>len</c> bytes length.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_port(char *buf, int *index, const erlang_port *p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_port(ei_x_buff* x, const erlang_port *p)</nametext></name>
- <fsummary>Encodes a port</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_boolean(char *buf, int *index, int p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_boolean(ei_x_buff* x, int p)</nametext></name>
+ <fsummary>Encode a boolean.</fsummary>
<desc>
- <p>Encodes an erlang port in the binary format. The <c><![CDATA[p]]></c>
- parameter points to a <c><![CDATA[erlang_port]]></c> structure (which
- should have been obtained earlier with
- <c><![CDATA[ei_decode_port()]]></c>.</p>
+ <p>Encodes a boolean value as the atom <c>true</c> if
+ <c>p</c> is not zero, or <c>false</c> if <c>p</c> is
+ zero.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_ref(char *buf, int *index, const erlang_ref *p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p)</nametext></name>
- <fsummary>Encodes a ref</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_char(char *buf, int *index, char p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_char(ei_x_buff* x, char p)</nametext></name>
+ <fsummary>Encode an 8-bit integer between 0-255.</fsummary>
<desc>
- <p>Encodes an erlang reference in the binary format. The
- <c><![CDATA[p]]></c> parameter points to a <c><![CDATA[erlang_ref]]></c> structure
- (which should have been obtained earlier with
- <c><![CDATA[ei_decode_ref()]]></c>.</p>
+ <p>Encodes a char (8-bit) as an integer between 0-255 in the binary
+ format. For historical reasons the integer argument is of
+ type <c>char</c>. Your C code is to consider the specified
+ argument to be of type <c>unsigned char</c> even if
+ the C compilers and system may define <c>char</c> to be
+ signed.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_term(char *buf, int *index, void *t)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_term(ei_x_buff* x, void *t)</nametext></name>
- <fsummary>Encode an <c><![CDATA[erl_interface]]></c>term</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_double(char *buf, int *index, double p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_double(ei_x_buff* x, double p)</nametext></name>
+ <fsummary>Encode a double float.</fsummary>
<desc>
- <p>This function encodes an <c><![CDATA[ETERM]]></c>, as obtained from
- <c><![CDATA[erl_interface]]></c>. The <c><![CDATA[t]]></c> parameter is actually an
- <c><![CDATA[ETERM]]></c> pointer. This function doesn't free the
- <c><![CDATA[ETERM]]></c>.</p>
+ <p>Encodes a double-precision (64-bit) floating point number in
+ the binary format.</p>
+ <p>Returns <c>-1</c> if the floating point
+ number is not finite.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_trace(char *buf, int *index, const erlang_trace *p)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p)</nametext></name>
- <fsummary>Encode a trace token</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_empty_list(char* buf, int* index)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_empty_list(ei_x_buff* x)</nametext></name>
+ <fsummary>Encode an empty list (<c>nil</c>).</fsummary>
<desc>
- <p>This function encodes an erlang trace token in the binary
- format. The <c><![CDATA[p]]></c> parameter points to a
- <c><![CDATA[erlang_trace]]></c> structure (which should have been
- obtained earlier with <c><![CDATA[ei_decode_trace()]]></c>.</p>
+ <p>Encodes an empty list. It is often used at the tail of a list.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_tuple_header(char *buf, int *index, int arity)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_tuple_header(ei_x_buff* x, int arity)</nametext></name>
- <fsummary>Encode a tuple</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_fun(char *buf, int *index, const erlang_fun *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun)</nametext></name>
+ <fsummary>Encode a fun.</fsummary>
<desc>
- <p>This function encodes a tuple header, with a specified
- arity. The next <c><![CDATA[arity]]></c> terms encoded will be the
- elements of the tuple. Tuples and lists are encoded
- recursively, so that a tuple may contain another tuple or
- list.</p>
- <p>E.g. to encode the tuple <c><![CDATA[{a, {b, {}}}]]></c>:</p>
- <pre>
-ei_encode_tuple_header(buf, &amp;i, 2);
-ei_encode_atom(buf, &amp;i, "a");
-ei_encode_tuple_header(buf, &amp;i, 2);
-ei_encode_atom(buf, &amp;i, "b");
-ei_encode_tuple_header(buf, &amp;i, 0);
- </pre>
+ <p>Encodes a fun in the binary format. Parameter <c>p</c>
+ points to an <c>erlang_fun</c> structure. The
+ <c>erlang_fun</c> is not freed automatically, the
+ <c>free_fun</c> is to be called if the fun is not needed
+ after encoding.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_encode_list_header(char *buf, int *index, int arity)</nametext></name>
<name><ret>int</ret><nametext>ei_x_encode_list_header(ei_x_buff* x, int arity)</nametext></name>
- <fsummary>Encode a list</fsummary>
+ <fsummary>Encode a list.</fsummary>
<desc>
- <p>This function encodes a list header, with a specified
- arity. The next <c><![CDATA[arity+1]]></c> terms are the elements
- (actually its <c><![CDATA[arity]]></c> cons cells) and the tail of the
+ <p>Encodes a list header, with a specified
+ arity. The next <c>arity+1</c> terms are the elements
+ (actually its <c>arity</c> cons cells) and the tail of the
list. Lists and tuples are encoded recursively, so that a
- list may contain another list or tuple.</p>
- <p>E.g. to encode the list <c><![CDATA[[c, d, [e | f]]]]></c>:</p>
+ list can contain another list or tuple.</p>
+ <p>For example, to encode the list
+ <c>[c, d, [e | f]]</c>:</p>
<pre>
ei_encode_list_header(buf, &amp;i, 3);
ei_encode_atom(buf, &amp;i, "c");
@@ -392,14 +533,13 @@ ei_encode_atom(buf, &amp;i, "d");
ei_encode_list_header(buf, &amp;i, 1);
ei_encode_atom(buf, &amp;i, "e");
ei_encode_atom(buf, &amp;i, "f");
-ei_encode_empty_list(buf, &amp;i);
- </pre>
+ei_encode_empty_list(buf, &amp;i);</pre>
<note>
<p>It may seem that there is no way to create a list without
knowing the number of elements in advance. But indeed
- there is a way. Note that the list <c><![CDATA[[a, b, c]]]></c> can be
- written as <c><![CDATA[[a | [b | [c]]]]]></c>. Using this, a list can
- be written as conses.</p>
+ there is a way. Notice that the list <c>[a, b, c]</c>
+ can be written as <c>[a | [b | [c]]]</c>.
+ Using this, a list can be written as conses.</p>
</note>
<p>To encode a list, without knowing the arity in advance:</p>
<pre>
@@ -407,425 +547,350 @@ while (something()) {
ei_x_encode_list_header(&amp;x, 1);
ei_x_encode_ulong(&amp;x, i); /* just an example */
}
-ei_x_encode_empty_list(&amp;x);
- </pre>
+ei_x_encode_empty_list(&amp;x);</pre>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_encode_empty_list(char* buf, int* index)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_encode_empty_list(ei_x_buff* x)</nametext></name>
- <fsummary>Encode an empty list (<c><![CDATA[nil]]></c>)</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_long(char *buf, int *index, long p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_long(ei_x_buff* x, long p)</nametext></name>
+ <fsummary>Encode integer.</fsummary>
+ <desc>
+ <p>Encodes a long integer in the binary format.
+ If the code is 64 bits, the function <c>ei_encode_long()</c> is
+ the same as <c>ei_encode_longlong()</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_longlong(char *buf, int *index, long long p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_longlong(ei_x_buff* x, long long p)</nametext></name>
+ <fsummary>Encode integer.</fsummary>
<desc>
- <p>This function encodes an empty list. It's often used at the
- tail of a list.</p>
+ <p>Encodes a GCC <c>long long</c> or Visual C++
+ <c>__int64</c> (64-bit) integer in the binary format.
+ This function is missing in the VxWorks port.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_encode_map_header(char *buf, int *index, int arity)</nametext></name>
<name><ret>int</ret><nametext>ei_x_encode_map_header(ei_x_buff* x, int arity)</nametext></name>
- <fsummary>Encode a map</fsummary>
+ <fsummary>Encode a map.</fsummary>
<desc>
- <p>This function encodes a map header, with a specified arity. The next
+ <p>Encodes a map header, with a specified arity. The next
<c>arity*2</c> terms encoded will be the keys and values of the map
encoded in the following order: <c>K1, V1, K2, V2, ..., Kn, Vn</c>.
</p>
- <p>E.g. to encode the map <c>#{a => "Apple", b => "Banana"}</c>:</p>
+ <p>For example, to encode the map <c>#{a => "Apple", b =>
+ "Banana"}</c>:</p>
<pre>
ei_x_encode_map_header(&amp;x, 2);
ei_x_encode_atom(&amp;x, "a");
ei_x_encode_string(&amp;x, "Apple");
ei_x_encode_atom(&amp;x, "b");
-ei_x_encode_string(&amp;x, "Banana");
- </pre>
- <p>A correctly encoded map can not have duplicate keys.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_get_type(const char *buf, const int *index, int *type, int *size)</nametext></name>
- <fsummary>Fetch the type and size of an encoded term</fsummary>
- <desc>
- <p>This function returns the type in <c><![CDATA[type]]></c> and size in
- <c><![CDATA[size]]></c> of the encoded term.
- For strings and atoms, size
- is the number of characters <em>not</em> including the
- terminating 0. For binaries, <c><![CDATA[size]]></c> is the number of
- bytes. For lists and tuples, <c><![CDATA[size]]></c> is the arity of the
- object. For other types, <c><![CDATA[size]]></c> is 0. In all cases,
- <c><![CDATA[index]]></c> is left unchanged.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_decode_version(const char *buf, int *index, int *version)</nametext></name>
- <fsummary>Encode an empty list (<c><![CDATA[nil]]></c>)</fsummary>
- <desc>
- <p>This function decodes the version magic number for the
- erlang binary term format. It must be the first token in a
- binary term.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_decode_long(const char *buf, int *index, long *p)</nametext></name>
- <fsummary>Decode integer</fsummary>
- <desc>
- <p>This function decodes a long integer from the binary format.
- Note that if the code is 64 bits the function ei_decode_long() is
- exactly the same as ei_decode_longlong().</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_decode_ulong(const char *buf, int *index, unsigned long *p)</nametext></name>
- <fsummary>Decode unsigned integer</fsummary>
- <desc>
- <p>This function decodes an unsigned long integer from
- the binary format.
- Note that if the code is 64 bits the function ei_decode_ulong() is
- exactly the same as ei_decode_ulonglong().</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_decode_longlong(const char *buf, int *index, long long *p)</nametext></name>
- <fsummary>Decode integer</fsummary>
- <desc>
- <p>This function decodes a GCC <c><![CDATA[long long]]></c> or Visual C++ <c><![CDATA[__int64]]></c>
- (64 bit) integer from the binary format. Note that this
- function is missing in the VxWorks port.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_decode_ulonglong(const char *buf, int *index, unsigned long long *p)</nametext></name>
- <fsummary>Decode unsigned integer</fsummary>
- <desc>
- <p>This function decodes a GCC <c><![CDATA[unsigned long long]]></c> or Visual C++
- <c><![CDATA[unsigned __int64]]></c> (64 bit) integer from the binary format.
- Note that this function is missing in the VxWorks port.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_decode_bignum(const char *buf, int *index, mpz_t obj)</nametext></name>
- <fsummary>Decode a GMP arbitrary precision integer</fsummary>
- <desc>
- <p>This function decodes an integer in the binary format to a GMP <c><![CDATA[mpz_t]]></c> integer.
- To use this function the ei library needs to be configured and compiled
- to use the GMP library. </p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_decode_double(const char *buf, int *index, double *p)</nametext></name>
- <fsummary>Decode a double</fsummary>
- <desc>
- <p>This function decodes an double-precision (64 bit) floating
- point number from the binary format.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_decode_boolean(const char *buf, int *index, int *p)</nametext></name>
- <fsummary>Decode a boolean</fsummary>
- <desc>
- <p>This function decodes a boolean value from the binary
- format. A boolean is actually an atom, <c><![CDATA[true]]></c> decodes 1
- and <c><![CDATA[false]]></c> decodes 0.</p>
+ei_x_encode_string(&amp;x, "Banana");</pre>
+ <p>A correctly encoded map cannot have duplicate keys.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_char(const char *buf, int *index, char *p)</nametext></name>
- <fsummary>Decode an 8-bit integer between 0-255</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_pid(char *buf, int *index, const erlang_pid *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_pid(ei_x_buff* x, const erlang_pid *p)</nametext></name>
+ <fsummary>Encode a pid.</fsummary>
<desc>
- <p>This function decodes a char (8-bit) integer between 0-255
- from the binary format.
- Note that for historical reasons the returned integer is of
- type <c><![CDATA[char]]></c>. Your C code should consider the
- returned value to be of type <c><![CDATA[unsigned char]]></c> even if
- the C compilers and system may define <c><![CDATA[char]]></c> to be
- signed.</p>
+ <p>Encodes an Erlang process identifier (pid) in the binary
+ format. Parameter <c>p</c> points to an
+ <c>erlang_pid</c> structure (which should have been
+ obtained earlier with <c>ei_decode_pid()</c>).</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_string(const char *buf, int *index, char *p)</nametext></name>
- <fsummary>Decode a string</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_port(char *buf, int *index, const erlang_port *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_port(ei_x_buff* x, const erlang_port *p)</nametext></name>
+ <fsummary>Encode a port.</fsummary>
<desc>
- <p>This function decodes a string from the binary format. A
- string in erlang is a list of integers between 0 and
- 255. Note that since the string is just a list, sometimes
- lists are encoded as strings by <c><![CDATA[term_to_binary/1]]></c>,
- even if it was not intended.</p>
- <p>The string is copied to <c><![CDATA[p]]></c>, and enough space must be
- allocated. The returned string is null terminated so you
- need to add an extra byte to the memory requirement.</p>
+ <p>Encodes an Erlang port in the binary format. Parameter
+ <c>p</c> points to a <c>erlang_port</c>
+ structure (which should have been obtained earlier with
+ <c>ei_decode_port()</c>).</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_atom(const char *buf, int *index, char *p)</nametext></name>
- <fsummary>Decode an atom</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_ref(char *buf, int *index, const erlang_ref *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p)</nametext></name>
+ <fsummary>Encode a ref.</fsummary>
<desc>
- <p>This function decodes an atom from the binary format. The
- null terminated name of the atom is placed at <c><![CDATA[p]]></c>. There can be at most
- <c><![CDATA[MAXATOMLEN]]></c> bytes placed in the buffer.</p>
+ <p>Encodes an Erlang reference in the binary format. Parameter
+ <c>p</c> points to a <c>erlang_ref</c>
+ structure (which should have been obtained earlier with
+ <c>ei_decode_ref()</c>).</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_atom_as(const char *buf, int *index, char *p, int plen, erlang_char_encoding want, erlang_char_encoding* was, erlang_char_encoding* result)</nametext></name>
- <fsummary>Decode an atom</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_string(char *buf, int *index, const char *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_encode_string_len(char *buf, int *index, const char *p, int len)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_string(ei_x_buff* x, const char *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_string_len(ei_x_buff* x, const char* s, int len)</nametext></name>
+ <fsummary>Encode a string.</fsummary>
<desc>
- <p>This function decodes an atom from the binary format. The
- null terminated name of the atom is placed in buffer at <c>p</c> of length
- <c>plen</c> bytes.</p>
- <p>The wanted string encoding is specified by <seealso marker="#erlang_char_encoding">
- <c>want</c></seealso>. The original encoding used in the
- binary format (latin1 or utf8) can be obtained from <c>*was</c>. The actual encoding of the resulting string
- (7-bit ascii, latin1 or utf8) can be obtained from <c>*result</c>. Both <c>was</c> and <c>result</c> can be <c>NULL</c>.
-
- <c>*result</c> may differ from <c>want</c> if <c>want</c> is a bitwise-or'd combination like
- <c>ERLANG_LATIN1|ERLANG_UTF8</c> or if <c>*result</c> turn out to be pure 7-bit ascii
- (compatible with both latin1 and utf8).</p>
- <p>This function fails if the atom is too long for the buffer
- or if it can not be represented with encoding <c>want</c>.</p>
- <p>This function was introduced in R16 release of Erlang/OTP as part of a first step
- to support UTF8 atoms.</p>
+ <p>Encodes a string in the binary format. (A string in Erlang
+ is a list, but is encoded as a character array in the binary
+ format.) The string is to be <c>NULL</c>-terminated, except for
+ the <c>ei_x_encode_string_len()</c> function.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_binary(const char *buf, int *index, void *p, long *len)</nametext></name>
- <fsummary>Decode a binary</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_term(char *buf, int *index, void *t)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_term(ei_x_buff* x, void *t)</nametext></name>
+ <fsummary>Encode an <c>erl_interface</c> term.</fsummary>
<desc>
- <p>This function decodes a binary from the binary format. The
- <c><![CDATA[len]]></c> parameter is set to the actual size of the
- binary. Note that <c><![CDATA[ei_decode_binary()]]></c> assumes that there
- are enough room for the binary. The size required can be
- fetched by <c><![CDATA[ei_get_type()]]></c>.</p>
+ <p>Encodes an <c>ETERM</c>, as obtained from
+ <c>erl_interface</c>. Parameter <c>t</c> is
+ actually an <c>ETERM</c> pointer. This function
+ does not free the <c>ETERM</c>.</p>
</desc>
</func>
<func>
- <name><ret>int</ret><nametext>ei_decode_fun(const char *buf, int *index, erlang_fun *p)</nametext></name>
- <name><ret>void</ret><nametext>free_fun(erlang_fun* f)</nametext></name>
- <fsummary>Decode a fun</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_trace(char *buf, int *index, const erlang_trace *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p)</nametext></name>
+ <fsummary>Encode a trace token.</fsummary>
<desc>
- <p>This function decodes a fun from the binary format. The
- <c><![CDATA[p]]></c> parameter should be NULL or point to an
- <c><![CDATA[erlang_fun]]></c> structure. This is the only decode
- function that allocates memory; when the <c><![CDATA[erlang_fun]]></c>
- is no longer needed, it should be freed with
- <c><![CDATA[free_fun]]></c>. (This has to do with the arbitrary size of
- the environment for a fun.)</p>
+ <p>Encodes an Erlang trace token in the binary format.
+ Parameter <c>p</c> points to a
+ <c>erlang_trace</c> structure (which should have been
+ obtained earlier with <c>ei_decode_trace()</c>).</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_pid(const char *buf, int *index, erlang_pid *p)</nametext></name>
- <fsummary>Decode a <c><![CDATA[pid]]></c></fsummary>
+ <name><ret>int</ret><nametext>ei_encode_tuple_header(char *buf, int *index, int arity)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_tuple_header(ei_x_buff* x, int arity)</nametext></name>
+ <fsummary>Encode a tuple.</fsummary>
<desc>
- <p>Decodes a pid, process identifier, from the binary format.</p>
+ <p>Encodes a tuple header, with a specified
+ arity. The next <c>arity</c> terms encoded will be the
+ elements of the tuple. Tuples and lists are encoded
+ recursively, so that a tuple can contain another tuple or list.</p>
+ <p>For example, to encode the tuple <c>{a, {b, {}}}</c>:</p>
+ <pre>
+ei_encode_tuple_header(buf, &amp;i, 2);
+ei_encode_atom(buf, &amp;i, "a");
+ei_encode_tuple_header(buf, &amp;i, 2);
+ei_encode_atom(buf, &amp;i, "b");
+ei_encode_tuple_header(buf, &amp;i, 0);</pre>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_port(const char *buf, int *index, erlang_port *p)</nametext></name>
- <fsummary>Decode a port</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_ulong(char *buf, int *index, unsigned long p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_ulong(ei_x_buff* x, unsigned long p)</nametext></name>
+ <fsummary>Encode unsigned integer.</fsummary>
<desc>
- <p>This function decodes a port identifier from the binary
- format.</p>
+ <p>Encodes an unsigned long integer in the binary format.
+ If the code is 64 bits, the function <c>ei_encode_ulong()</c> is
+ the same as <c>ei_encode_ulonglong()</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_ref(const char *buf, int *index, erlang_ref *p)</nametext></name>
- <fsummary>Decode a reference</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_ulonglong(char *buf, int *index, unsigned long long p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_ulonglong(ei_x_buff* x, unsigned long long p)</nametext></name>
+ <fsummary>Encode unsigned integer.</fsummary>
<desc>
- <p>This function decodes a reference from the binary format.</p>
+ <p>Encodes a GCC <c>unsigned long long</c> or Visual C++
+ <c>unsigned __int64</c> (64-bit) integer in the binary
+ format. This function is missing in the VxWorks port.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_trace(const char *buf, int *index, erlang_trace *p)</nametext></name>
- <fsummary>Decode a trace token</fsummary>
+ <name><ret>int</ret><nametext>ei_encode_version(char *buf, int *index)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_version(ei_x_buff* x)</nametext></name>
+ <fsummary>Encode version.</fsummary>
<desc>
- <p>Decodes an erlang trace token from the binary format.</p>
+ <p>Encodes a version magic number for the binary format. Must
+ be the first token in a binary term.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_tuple_header(const char *buf, int *index, int *arity)</nametext></name>
- <fsummary>Decode a tuple</fsummary>
+ <name><ret>int</ret><nametext>ei_get_type(const char *buf, const int *index, int *type, int *size)</nametext></name>
+ <fsummary>Fetch the type and size of an encoded term.</fsummary>
<desc>
- <p>This function decodes a tuple header, the number of elements
- is returned in <c><![CDATA[arity]]></c>. The tuple elements follows in order in
- the buffer.</p>
+ <p>Returns the type in <c>type</c> and size in
+ <c>size</c> of the encoded term. For strings and atoms,
+ size is the number of characters <em>not</em> including the
+ terminating <c>NULL</c>. For binaries, <c>size</c> is the number of
+ bytes. For lists and tuples, <c>size</c> is the arity of
+ the object. For other types, <c>size</c> is 0. In all
+ cases, <c>index</c> is left unchanged.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_list_header(const char *buf, int *index, int *arity)</nametext></name>
- <fsummary>Decode a list</fsummary>
- <desc>
- <p>This function decodes a list header from the binary
- format. The number of elements is returned in
- <c><![CDATA[arity]]></c>. The <c><![CDATA[arity+1]]></c> elements follows (the last
- one is the tail of the list, normally an empty list.) If
- <c><![CDATA[arity]]></c> is <c><![CDATA[0]]></c>, it's an empty list.</p>
- <p>Note that lists are encoded as strings, if they consist
- entirely of integers in the range 0..255. This function will
- not decode such strings, use <c><![CDATA[ei_decode_string()]]></c>
- instead.</p>
+ <name><ret>int</ret><nametext>ei_print_term(FILE* fp, const char* buf, int* index)</nametext></name>
+ <name><ret>int</ret><nametext>ei_s_print_term(char** s, const char* buf, int* index)</nametext></name>
+ <fsummary>Print a term in clear text.</fsummary>
+ <desc>
+ <p>Prints a term, in clear text, to the file
+ specified by <c>fp</c>, or the buffer pointed to by
+ <c>s</c>. It
+ tries to resemble the term printing in the Erlang shell.</p>
+ <p>In <c>ei_s_print_term()</c>, parameter
+ <c>s</c> is to
+ point to a dynamically (malloc) allocated string of
+ <c>BUFSIZ</c> bytes or a <c>NULL</c> pointer. The string
+ can be reallocated (and <c>*s</c> can be updated) by this
+ function if the result is more than <c>BUFSIZ</c>
+ characters. The string returned is <c>NULL</c>-terminated.</p>
+ <p>The return value is the number of characters written to the file
+ or string, or <c>-1</c> if <c>buf[index]</c> does not
+ contain a valid term.
+ Unfortunately, I/O errors on <c>fp</c> is not checked.</p>
+ <p>Argument <c>index</c> is updated, that is, this function
+ can be viewed as a decode function that decodes a term into a
+ human-readable format.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_map_header(const char *buf, int *index, int *arity)</nametext></name>
- <fsummary>Decode a map</fsummary>
+ <name><ret>void</ret><nametext>ei_set_compat_rel(release_number)</nametext></name>
+ <fsummary>Set the ei library in compatibility mode.</fsummary>
+ <type>
+ <v>unsigned release_number;</v>
+ </type>
<desc>
- <p>This function decodes a map header from the binary
- format. The number of key-value pairs is returned in
- <c>*arity</c>. Keys and values follow in the following order:
- <c>K1, V1, K2, V2, ..., Kn, Vn</c>. This makes a total of
- <c>arity*2</c> terms. If <c>arity</c> is zero, it's an empty map.
- A correctly encoded map does not have duplicate keys.</p>
+ <marker id="ei_set_compat_rel"></marker>
+ <p>By default, the <c>ei</c> library is only guaranteed
+ to be compatible with other Erlang/OTP components from the same
+ release as the <c>ei</c> library itself. For example,
+ <c>ei</c> from
+ Erlang/OTP R10 is not compatible with an Erlang emulator
+ from Erlang/OTP R9 by default.</p>
+ <p>A call to <c>ei_set_compat_rel(release_number)</c> sets
+ the <c>ei</c> library in compatibility mode of release
+ <c>release_number</c>. Valid range of
+ <c>release_number</c>
+ is <c>[7, current release]</c>. This makes it possible to
+ communicate with Erlang/OTP components from earlier releases.</p>
+ <note>
+ <p>If this function is called, it can only be called once
+ and must be called before any other functions in the
+ <c>ei</c> library are called.</p>
+ </note>
+ <warning>
+ <p>You can run into trouble if this feature is used
+ carelessly. Always ensure that all communicating
+ components are either from the same Erlang/OTP release, or
+ from release X and release Y where all components
+ from release Y are in compatibility mode of release X.</p>
+ </warning>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_decode_ei_term(const char* buf, int* index, ei_term* term)</nametext></name>
- <fsummary>Decode a term, without prior knowledge of type</fsummary>
+ <name><ret>int</ret><nametext>ei_skip_term(const char* buf, int* index)</nametext></name>
+ <fsummary>Skip a term.</fsummary>
<desc>
- <p>This function decodes any term, or at least tries to. If the
- term pointed at by <c><![CDATA[*index]]></c> in <c><![CDATA[buf]]></c> fits in the
- <c><![CDATA[term]]></c> union, it is decoded, and the appropriate field
- in <c><![CDATA[term->value]]></c> is set, and <c><![CDATA[*index]]></c> is
- incremented by the term size.</p>
- <p>The function returns 1 on successful decoding, -1 on error,
- and 0 if the term seems alright, but does not fit in the
- <c><![CDATA[term]]></c> structure. If it returns 1, the <c><![CDATA[index]]></c>
- will be incremented, and the <c><![CDATA[term]]></c> contains the
- decoded term.</p>
- <p>The <c><![CDATA[term]]></c> structure will contain the arity for a tuple
- or list, size for a binary, string or atom. It will contains
- a term if it's any of the following: integer, float, atom,
- pid, port or ref.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_decode_term(const char *buf, int *index, void *t)</nametext></name>
- <fsummary>Decode a <c><![CDATA[ETERM]]></c></fsummary>
- <desc>
- <p>This function decodes a term from the binary format. The
- term is return in <c><![CDATA[t]]></c> as a <c><![CDATA[ETERM*]]></c>, so <c><![CDATA[t]]></c>
- is actually an <c><![CDATA[ETERM**]]></c> (see
- <c><![CDATA[erl_interface(3)]]></c>. The term should later be
- deallocated.</p>
- <p>Note that this function is located in the erl_interface
- library.</p>
+ <p>Skips a term in the specified buffer;
+ recursively skips elements of lists and tuples, so that a
+ full term is skipped. This is a way to get the size of an
+ Erlang term.</p>
+ <p><c>buf</c> is the buffer.</p>
+ <p><c>index</c> is updated to point right after the term
+ in the buffer.</p>
+ <note>
+ <p>This can be useful when you want to hold arbitrary
+ terms: skip them and copy the binary term data to some
+ buffer.</p>
+ </note>
+ <p>Returns <c>0</c> on success, otherwise
+ <c>-1</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_print_term(FILE* fp, const char* buf, int* index)</nametext></name>
- <name><ret>int</ret><nametext>ei_s_print_term(char** s, const char* buf, int* index)</nametext></name>
- <fsummary>Print a term in clear text</fsummary>
+ <name><ret>int</ret><nametext>ei_x_append(ei_x_buff* x, const ei_x_buff* x2)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_append_buf(ei_x_buff* x, const char* buf, int len)</nametext></name>
+ <fsummary>Append a buffer at the end.</fsummary>
<desc>
- <p>This function prints a term, in clear text, to the file
- given by <c><![CDATA[fp]]></c>, or the buffer pointed to by <c><![CDATA[s]]></c>. It
- tries to resemble the term printing in the erlang shell.</p>
- <p>In <c><![CDATA[ei_s_print_term()]]></c>, the parameter <c><![CDATA[s]]></c> should
- point to a dynamically (malloc) allocated string of
- <c><![CDATA[BUFSIZ]]></c> bytes or a NULL pointer. The string may be
- reallocated (and <c><![CDATA[*s]]></c> may be updated) by this function
- if the result is more than <c><![CDATA[BUFSIZ]]></c> characters. The
- string returned is zero-terminated.</p>
- <p>The return value is the number of characters written to the
- file or string, or -1 if <c><![CDATA[buf[index]]]></c> doesn't contain a
- valid term. Unfortunately, I/O errors on <c><![CDATA[fp]]></c> is not
- checked.</p>
- <p>The argument <c><![CDATA[index]]></c> is updated, i.e. this function can
- be viewed as en decode function that decodes a term into a
- human readable format.</p>
+ <p>Appends data at the end of buffer <c>x</c>.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_x_format(ei_x_buff* x, const char* fmt, ...)</nametext></name>
<name><ret>int</ret><nametext>ei_x_format_wo_ver(ei_x_buff* x, const char *fmt, ... )</nametext></name>
<fsummary>Format a term from a format string and parameters.</fsummary>
<desc>
- <p>Format a term, given as a string, to a buffer. This
- functions works like a sprintf for erlang terms. The
- <c><![CDATA[fmt]]></c> contains a format string, with arguments like
- <c><![CDATA[~d]]></c>, to insert terms from variables. The following
+ <p>Formats a term, given as a string, to a buffer.
+ Works like a sprintf for Erlang terms.
+ <c>fmt</c> contains a format string, with arguments like
+ <c>~d</c>, to insert terms from variables. The following
formats are supported (with the C types given):</p>
- <p></p>
<pre>
-~a - an atom, char*
-~c - a character, char
-~s - a string, char*
-~i - an integer, int
-~l - a long integer, long int
-~u - a unsigned long integer, unsigned long int
-~f - a float, float
-~d - a double float, double float
-~p - an Erlang PID, erlang_pid*
- </pre>
- <p>For instance, to encode a tuple with some stuff:</p>
+~a An atom, char*
+~c A character, char
+~s A string, char*
+~i An integer, int
+~l A long integer, long int
+~u A unsigned long integer, unsigned long int
+~f A float, float
+~d A double float, double float
+~p An Erlang pid, erlang_pid*</pre>
+ <p>For example, to encode a tuple with some stuff:</p>
<pre>
ei_x_format("{~a,~i,~d}", "numbers", 12, 3.14159)
-encodes the tuple {numbers,12,3.14159}
- </pre>
- <p>The <c><![CDATA[ei_x_format_wo_ver()]]></c> formats into a buffer, without
- the initial version byte.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_x_new(ei_x_buff* x)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_new_with_version(ei_x_buff* x)</nametext></name>
- <fsummary>Allocate a new buffer</fsummary>
- <desc>
- <p>This function allocates a new <c><![CDATA[ei_x_buff]]></c> buffer. The
- fields of the structure pointed to by <c><![CDATA[x]]></c> parameter is
- filled in, and a default buffer is allocated. The
- <c><![CDATA[ei_x_new_with_version()]]></c> also puts an initial version
- byte, that is used in the binary format. (So that
- <c><![CDATA[ei_x_encode_version()]]></c> won't be needed.)</p>
+encodes the tuple {numbers,12,3.14159}</pre>
+ <p><c>ei_x_format_wo_ver()</c> formats into a buffer,
+ without the initial version byte.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_x_free(ei_x_buff* x)</nametext></name>
- <fsummary>Frees a buffer</fsummary>
- <desc>
- <p>This function frees an <c><![CDATA[ei_x_buff]]></c> buffer. The memory
- used by the buffer is returned to the OS.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_x_append(ei_x_buff* x, const ei_x_buff* x2)</nametext></name>
- <name><ret>int</ret><nametext>ei_x_append_buf(ei_x_buff* x, const char* buf, int len)</nametext></name>
- <fsummary>Appends a buffer at the end</fsummary>
+ <fsummary>Free a buffer.</fsummary>
<desc>
- <p>These functions appends data at the end of the buffer <c><![CDATA[x]]></c>.</p>
+ <p>Frees an <c>ei_x_buff</c> buffer.
+ The memory used by the buffer is returned to the OS.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_skip_term(const char* buf, int* index)</nametext></name>
- <fsummary>skip a term</fsummary>
+ <name><ret>int</ret><nametext>ei_x_new(ei_x_buff* x)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_new_with_version(ei_x_buff* x)</nametext></name>
+ <fsummary>Allocate a new buffer.</fsummary>
<desc>
- <p>This function skips a term in the given buffer, it
- recursively skips elements of lists and tuples, so that a
- full term is skipped. This is a way to get the size of an
- erlang term.</p>
- <p><c><![CDATA[buf]]></c> is the buffer.</p>
- <p><c><![CDATA[index]]></c> is updated to point right after the term in the
- buffer.</p>
- <note>
- <p>This can be useful when you want to hold arbitrary
- terms: just skip them and copy the binary term data to some
- buffer.</p>
- </note>
- <p>The function returns <c><![CDATA[0]]></c> on success and <c><![CDATA[-1]]></c> on
- failure.</p>
+ <p>Allocates a new <c>ei_x_buff</c> buffer. The
+ fields of the structure pointed to by parameter <c>x</c>
+ is filled in, and a default buffer is allocated.
+ <c>ei_x_new_with_version()</c> also puts an initial
+ version byte, which is used in the binary format (so that
+ <c>ei_x_encode_version()</c> will not be needed.)</p>
</desc>
</func>
</funcs>
<section>
<title>Debug Information</title>
- <p>Some tips on what to check when the emulator doesn't seem to
- receive the terms that you send.</p>
+ <p>Some tips on what to check when the emulator does not seem to
+ receive the terms that you send:</p>
+
<list type="bulleted">
- <item>be careful with the version header, use
- <c><![CDATA[ei_x_new_with_version()]]></c> when appropriate</item>
- <item>turn on distribution tracing on the erlang node</item>
- <item>check the result codes from ei_decode_-calls</item>
+ <item>Be careful with the version header, use
+ <c>ei_x_new_with_version()</c> when appropriate.</item>
+ <item>Turn on distribution tracing on the Erlang node.</item>
+ <item>Check the result codes from <c>ei_decode_-calls</c>.</item>
</list>
</section>
<section>
<title>See Also</title>
- <p>erl_interface(3)</p>
+ <p><seealso marker="erl_eterm"><c>erl_eterm</c></seealso></p>
</section>
</cref>
-
diff --git a/lib/erl_interface/doc/src/ei_connect.xml b/lib/erl_interface/doc/src/ei_connect.xml
index 516357b6a3..607a7cbff4 100644
--- a/lib/erl_interface/doc/src/ei_connect.xml
+++ b/lib/erl_interface/doc/src/ei_connect.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,100 +19,233 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>ei_connect</title>
<prepared>Jakob Cederlund</prepared>
<docno></docno>
- <approved>?</approved>
- <checked>?</checked>
+ <approved></approved>
+ <checked></checked>
<date>2001-09-01</date>
<rev>A</rev>
- <file>ei_connect.sgml</file>
+ <file>ei_connect.xml</file>
</header>
<lib>ei_connect</lib>
- <libsummary>Communicate with distributed erlang</libsummary>
+ <libsummary>Communicate with distributed Erlang.</libsummary>
<description>
- <p>This module enables C programs to communicate with erlang nodes,
- using the erlang distribution over TCP/IP.</p>
- <p>A C node appears to Erlang as a
- <em>hidden node</em>.
+ <p>This module enables C-programs to communicate with Erlang nodes,
+ using the Erlang distribution over TCP/IP.</p>
+
+ <p>A C-node appears to Erlang as a <em>hidden node</em>.
That is, Erlang processes that know the name of the
- C node are able to communicate with it in a normal manner, but
- the node name will not appear in the listing provided by the
- Erlang function <c><![CDATA[nodes/0]]></c>.</p>
- <p>The environment variable <c><![CDATA[ERL_EPMD_PORT]]></c> can be used
- to indicate which logical cluster a C node belongs to.</p>
+ C-node can communicate with it in a normal manner, but
+ the node name is not shown in the listing provided by
+ <seealso marker="erts:erlang#nodes/0"><c>erlang:nodes/0</c></seealso>
+ in <c>ERTS</c>.</p>
+
+ <p>The environment variable <c>ERL_EPMD_PORT</c> can be used
+ to indicate which logical cluster a C-node belongs to.</p>
</description>
<section>
- <title>Timeout functions</title>
+ <title>Time-Out Functions</title>
<p>Most functions appear in a version with the suffix
- <c><![CDATA[_tmo]]></c> appended to the function name. Those function take
- an additional argument, a timeout in <em>milliseconds</em>. The
- semantics is this; for each communication primitive involved in
+ <c>_tmo</c> appended to the function name. Those functions
+ take an extra argument, a time-out in <em>milliseconds</em>. The
+ semantics is this: for each communication primitive involved in
the operation, if the primitive does not complete within the time
- specified, the function will return an error and
- <c><![CDATA[erl_errno]]></c> will be set to <c><![CDATA[ETIMEDOUT]]></c>. With
- communication primitive is meant an operation on the socket, like
- <c><![CDATA[connect]]></c>, <c><![CDATA[accept]]></c>, <c><![CDATA[recv]]></c> or <c><![CDATA[send]]></c>.</p>
- <p>Obviously the timeouts are for implementing fault tolerance,
- not to keep hard realtime promises. The <c><![CDATA[_tmo]]></c> functions
+ specified, the function returns an error and
+ <c>erl_errno</c> is set to <c>ETIMEDOUT</c>.
+ With communication primitive is meant an operation on the socket, like
+ <c>connect</c>, <c>accept</c>,
+ <c>recv</c>, or <c>send</c>.</p>
+
+ <p>Clearly the time-outs are for implementing fault tolerance,
+ not to keep hard real-time promises. The <c>_tmo</c> functions
are for detecting non-responsive peers and to avoid blocking on
- socket operations. </p>
- <p>A timeout value of <c><![CDATA[0]]></c> (zero), means that timeouts are
- disabled. Calling a <c><![CDATA[_tmo]]></c>-function with the last argument as
- <c><![CDATA[0]]></c> is therefore exactly the same thing as calling the
- function without the <c><![CDATA[_tmo]]></c> suffix.</p>
- <p>As with all other ei functions, you are <em>not</em> expected
- to put the socket in non blocking mode yourself in the program. Every
- use of non blocking mode is embedded inside the timeout
+ socket operations.</p>
+
+ <p>A time-out value of <c>0</c> (zero) means that time-outs are
+ disabled. Calling a <c>_tmo</c> function with the last
+ argument as <c>0</c> is therefore the same thing as calling
+ the function without the <c>_tmo</c> suffix.</p>
+
+ <p>As with all other functions starting with <c>ei_</c>,
+ you are <em>not</em> expected
+ to put the socket in non-blocking mode yourself in the program. Every
+ use of non-blocking mode is embedded inside the time-out
functions. The socket will always be back in blocking mode after
the operations are completed (regardless of the result). To
- avoid problems, leave the socket options alone. Ei will handle
+ avoid problems, leave the socket options alone. <c>ei</c> handles
any socket options that need modification.</p>
- <p>In all other senses, the <c><![CDATA[_tmo]]></c> functions inherit all
- the return values and the semantics from the functions without
- the <c><![CDATA[_tmo]]></c> suffix.</p>
+
+ <p>In all other senses, the <c>_tmo</c> functions inherit all
+ the return values and the semantics from the functions without
+ the <c>_tmo</c> suffix.</p>
</section>
+
<funcs>
<func>
+ <name><ret>struct hostent</ret><nametext>*ei_gethostbyaddr(const char *addr, int len, int type)</nametext></name>
+ <name><ret>struct hostent</ret><nametext>*ei_gethostbyaddr_r(const char *addr, int length, int type, struct hostent *hostp, char *buffer, int buflen, int *h_errnop)</nametext></name>
+ <name><ret>struct hostent</ret><nametext>*ei_gethostbyname(const char *name)</nametext></name>
+ <name><ret>struct hostent</ret><nametext>*ei_gethostbyname_r(const char *name, struct hostent *hostp, char *buffer, int buflen, int *h_errnop)</nametext></name>
+ <fsummary>Name lookup functions.</fsummary>
+ <desc>
+ <p>Convenience functions for some common name lookup functions.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_accept(ei_cnode *ec, int listensock, ErlConnect *conp)</nametext></name>
+ <fsummary>Accept a connection from another node.</fsummary>
+ <desc>
+ <p>Used by a server process to accept a
+ connection from a client process.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>ec</c> is the C-node structure.</p>
+ </item>
+ <item>
+ <p><c>listensock</c> is an open socket descriptor on
+ which <c>listen()</c> has previously been called.</p>
+ </item>
+ <item>
+ <p><c>conp</c> is a pointer to an
+ <c>ErlConnect</c> struct, described as follows:</p>
+ <code type="none"><![CDATA[
+typedef struct {
+ char ipadr[4];
+ char nodename[MAXNODELEN];
+} ErlConnect;
+ ]]></code>
+ </item>
+ </list>
+ <p>On success, <c>conp</c> is filled in with the address and
+ node name of the connecting client and a file descriptor is
+ returned. On failure, <c>ERL_ERROR</c> is returned and
+ <c>erl_errno</c> is set to <c>EIO</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_accept_tmo(ei_cnode *ec, int listensock, ErlConnect *conp, unsigned timeout_ms)</nametext></name>
+ <fsummary>Accept a connection from another node with optional
+ time-out.</fsummary>
+ <desc>
+ <p>Equivalent to
+ <c>ei_accept</c> with an optional time-out argument,
+ see the description at the beginning of this manual page.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_connect(ei_cnode* ec, char *nodename)</nametext></name>
+ <name><ret>int</ret><nametext>ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename)</nametext></name>
+ <fsummary>Establish a connection to an Erlang node.</fsummary>
+ <desc>
+ <p>Sets up a connection to an Erlang node.</p>
+ <p><c>ei_xconnect()</c> requires the IP address of the
+ remote host and the alive name of the remote node to be
+ specified. <c>ei_connect()</c> provides an alternative
+ interface and determines the information from the node name
+ provided.</p>
+ <list type="bulleted">
+ <item><c>addr</c> is the 32-bit IP address of the remote
+ host.</item>
+ <item><c>alive</c> is the alivename of the remote node.
+ </item>
+ <item><c>node</c> is the name of the remote node.</item>
+ </list>
+ <p>These functions return an open file descriptor on success, or
+ a negative value indicating that an error occurred. In the latter
+ case they set <c>erl_errno</c> to one of the
+ following:</p>
+ <taglist>
+ <tag><c>EHOSTUNREACH</c></tag>
+ <item>The remote host <c>node</c> is unreachable.</item>
+ <tag><c>ENOMEM</c></tag>
+ <item>No more memory is available.</item>
+ <tag><c>EIO</c></tag>
+ <item>I/O error.</item>
+ </taglist>
+ <p>Also, <c>errno</c> values from
+ <c>socket</c><em>(2)</em> and
+ <c>connect</c><em>(2)</em>
+ system calls may be propagated into <c>erl_errno</c>.</p>
+ <p><em>Example:</em></p>
+ <code type="none"><![CDATA[
+#define NODE "[email protected]"
+#define ALIVE "madonna"
+#define IP_ADDR "150.236.14.75"
+
+/*** Variant 1 ***/
+int fd = ei_connect(&ec, NODE);
+
+/*** Variant 2 ***/
+struct in_addr addr;
+addr.s_addr = inet_addr(IP_ADDR);
+fd = ei_xconnect(&ec, &addr, ALIVE);
+ ]]></code>
+ </desc>
+ </func>
+
+ <func>
<name><ret>int</ret><nametext>ei_connect_init(ei_cnode* ec, const char* this_node_name, const char *cookie, short creation)</nametext></name>
<name><ret>int</ret><nametext>ei_connect_xinit(ei_cnode* ec, const char *thishostname, const char *thisalivename, const char *thisnodename, Erl_IpAddr thisipaddr, const char *cookie, short creation)</nametext></name>
<fsummary>Initialize for a connection.</fsummary>
<desc>
- <p>These function initializes the <c><![CDATA[ec]]></c> structure, to
+ <p>Initializes the <c>ec</c> structure, to
identify the node name and cookie of the server. One of them
- has to be called before other functions that works on the
- type <c><![CDATA[ei_cnode]]></c> or a file descriptor associated with a
- connection to another node are used.</p>
- <p><c><![CDATA[ec]]></c> is a structure containing information about the
- C-node. It is used in other <c><![CDATA[ei]]></c> functions for
- connecting and receiving data.</p>
- <p><c><![CDATA[this_node_name]]></c> is the registered name of the process
- (the name before '@').</p>
- <p><c><![CDATA[cookie]]></c> is the cookie for the node.</p>
- <p><c><![CDATA[creation]]></c> identifies a specific instance of a C
- node. It can help prevent the node from receiving messages
- sent to an earlier process with the same registered name.</p>
- <p><c><![CDATA[thishostname]]></c> is the name of the machine we're running
- on. If long names are to be used, it should be fully
- qualified (i.e. <c><![CDATA[durin.erix.ericsson.se]]></c> instead of
- <c><![CDATA[durin]]></c>).</p>
- <p><c><![CDATA[thisalivename]]></c> is the registered name of the process.</p>
- <p><c><![CDATA[thisnodename]]></c> is the full name of the node,
- i.e. <c><![CDATA[einode@durin]]></c>.</p>
- <p><c><![CDATA[thispaddr]]></c> if the IP address of the host.</p>
- <p>A C node acting as a server will be assigned a creation
- number when it calls <c><![CDATA[ei_publish()]]></c>.</p>
- <p>A connection is closed by simply closing the socket. Refer
- to system documentation to close the socket gracefully (when
- there are outgoing packets before close).</p>
- <p>This function return a negative value indicating that an error
+ must be called before other functions that works on the
+ <c>ei_cnode</c> type or a file descriptor associated with
+ a connection to another node is used.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>ec</c> is a structure containing information about
+ the C-node. It is used in other <c>ei</c> functions
+ for connecting and receiving data.</p>
+ </item>
+ <item>
+ <p><c>this_node_name</c> is the registered name of the
+ process (the name before '@').</p>
+ </item>
+ <item>
+ <p><c>cookie</c> is the cookie for the node.</p>
+ </item>
+ <item>
+ <p><c>creation</c> identifies a specific instance of a
+ C-node. It can help prevent the node from receiving messages
+ sent to an earlier process with the same registered name.</p>
+ </item>
+ <item>
+ <p><c>thishostname</c> is the name of the machine we are
+ running on. If long names are to be used, they are to be fully
+ qualified (that is, <c>durin.erix.ericsson.se</c>
+ instead of <c>durin</c>).</p>
+ </item>
+ <item>
+ <p><c>thisalivename</c> is the registered name of the
+ process.</p>
+ </item>
+ <item>
+ <p><c>thisnodename</c> is the full name of the node,
+ that is, <c>einode@durin</c>.</p>
+ </item>
+ <item>
+ <p><c>thispaddr</c> if the IP address of the host.</p>
+ </item>
+ </list>
+ <p>A C-node acting as a server is assigned a creation
+ number when it calls <c>ei_publish()</c>.</p>
+ <p>A connection is closed by simply closing the socket.
+ For information about how to close the socket gracefully (when
+ there are outgoing packets before close), see the relevant system
+ documentation.</p>
+ <p>These functions return a negative value indicating that an error
occurred.</p>
- <p>Example 1:
- </p>
+ <p><em>Example 1:</em></p>
<code type="none"><![CDATA[
int n = 0;
struct in_addr addr;
@@ -129,8 +262,7 @@ if (ei_connect_xinit(&ec,
exit(-1);
}
]]></code>
- <p>Example 2:
- </p>
+ <p><em>Example 2:</em></p>
<code type="none"><![CDATA[
if (ei_connect_init(&ec, "madonna", "cookie...", n++) < 0) {
fprintf(stderr,"ERROR when initializing: %d",erl_errno);
@@ -139,114 +271,184 @@ if (ei_connect_init(&ec, "madonna", "cookie...", n++) < 0) {
]]></code>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_connect(ei_cnode* ec, char *nodename)</nametext></name>
- <name><ret>int</ret><nametext>ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename)</nametext></name>
- <fsummary>Establishe a connection to an Erlang node</fsummary>
+ <name><ret>int</ret><nametext>ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned timeout_ms)</nametext></name>
+ <name><ret>int</ret><nametext>ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned timeout_ms)</nametext></name>
+ <fsummary>Establish a connection to an Erlang node with optional
+ time-out.</fsummary>
<desc>
- <p>These functions set up a connection to an Erlang node.</p>
- <p><c><![CDATA[ei_xconnect()]]></c> requires the IP address of the remote
- host and the alive name of the remote node
- to be specified. <c><![CDATA[ei_connect()]]></c> provides an alternative
- interface, and determines the information from the node name
- provided.</p>
- <p><c><![CDATA[addr]]></c> is the 32-bit IP address of the remote host.</p>
- <p><c><![CDATA[alive]]></c> is the alivename of the remote node.</p>
- <p><c><![CDATA[node]]></c> is the name of the remote node.</p>
- <p>These functions return an open file descriptor on success, or
- a negative value indicating that an error occurred --- in
- which case they will set <c><![CDATA[erl_errno]]></c> to one of:</p>
- <taglist>
- <tag><c><![CDATA[EHOSTUNREACH]]></c></tag>
- <item>The remote host <c><![CDATA[node]]></c> is unreachable</item>
- <tag><c><![CDATA[ENOMEM]]></c></tag>
- <item>No more memory available.</item>
- <tag><c><![CDATA[EIO]]></c></tag>
- <item>I/O error.</item>
- </taglist>
- <p>Additionally, <c><![CDATA[errno]]></c> values from
- <c><![CDATA[socket]]></c><em>(2)</em> and <c><![CDATA[connect]]></c><em>(2)</em>
- system calls may be propagated into <c><![CDATA[erl_errno]]></c>.</p>
- <p>Example:</p>
- <code type="none"><![CDATA[
-#define NODE "[email protected]"
-#define ALIVE "madonna"
-#define IP_ADDR "150.236.14.75"
+ <p>Equivalent to
+ <c>ei_connect</c> and <c>ei_xconnect</c> with an optional time-out
+ argument, see the description at the beginning of this manual
+ page.</p>
+ </desc>
+ </func>
-/*** Variant 1 ***/
-int fd = ei_connect(&ec, NODE);
+ <func>
+ <name><ret>int</ret><nametext>ei_get_tracelevel(void)</nametext></name>
+ <name><ret>void</ret><nametext>ei_set_tracelevel(int level)</nametext></name>
+ <fsummary>Get and set functions for tracing.</fsummary>
+ <desc>
+ <p>Used to set tracing on the distribution. The levels are different
+ verbosity levels. A higher level means more information. See also
+ section <seealso marker="#debug_information">
+ Debug Information</seealso>.</p>
+ <p>These functions are not thread safe.</p>
+ </desc>
+ </func>
-/*** Variant 2 ***/
-struct in_addr addr;
-addr.s_addr = inet_addr(IP_ADDR);
-fd = ei_xconnect(&ec, &addr, ALIVE);
- ]]></code>
+ <func>
+ <name><ret>int</ret><nametext>ei_publish(ei_cnode *ec, int port)</nametext></name>
+ <fsummary>Publish a node name.</fsummary>
+ <desc>
+ <p>Used by a server process to register
+ with the local name server EPMD, thereby allowing
+ other processes to send messages by using the registered name.
+ Before calling either of these functions, the process should
+ have called <c>bind()</c> and <c>listen()</c>
+ on an open socket.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>ec</c> is the C-node structure.</p>
+ </item>
+ <item>
+ <p><c>port</c> is the local name to register, and is to
+ be the same as the port number that was previously bound to the
+ socket.</p>
+ </item>
+ <item>
+ <p><c>addr</c> is the 32-bit IP address of the local
+ host.</p>
+ </item>
+ </list>
+ <p>To unregister with EPMD, simply close the returned descriptor. Do
+ not use <c>ei_unpublish()</c>, which is deprecated
+ anyway.</p>
+ <p>On success, the function returns a descriptor connecting the
+ calling process to EPMD. On failure, <c>-1</c> is returned and
+ <c>erl_errno</c> is set to <c>EIO</c>.</p>
+ <p>Also, <c>errno</c> values from
+ <c>socket</c><em>(2)</em> and
+ <c>connect</c><em>(2)</em> system calls may be propagated
+ into <c>erl_errno</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned timeout_ms)</nametext></name>
- <name><ret>int</ret><nametext>ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned timeout_ms)</nametext></name>
- <fsummary>Establish a connection to an Erlang node with optional timeout</fsummary>
+ <name><ret>int</ret><nametext>ei_publish_tmo(ei_cnode *ec, int port, unsigned timeout_ms)</nametext></name>
+ <fsummary>Publish a node name with optional time-out.</fsummary>
<desc>
- <p>ei_connect and ei_xconnect with an optional timeout argument,
- see the description at the beginning of this document.</p>
+ <p>Equivalent to
+ <c>ei_publish</c> with an optional time-out argument,
+ see the description at the beginning of this manual page.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_receive(int fd, unsigned char* bufp, int bufsize)</nametext></name>
- <fsummary>Receive a message</fsummary>
+ <fsummary>Receive a message.</fsummary>
<desc>
- <p>This function receives a message consisting of a sequence
+ <p>Receives a message consisting of a sequence
of bytes in the Erlang external format.</p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection. It
- is obtained from a previous <c><![CDATA[ei_connect]]></c> or
- <c><![CDATA[ei_accept]]></c>.</p>
- <p><c><![CDATA[bufp]]></c> is a buffer large enough to hold the expected
- message. </p>
- <p><c><![CDATA[bufsize]]></c> indicates the size of <c><![CDATA[bufp]]></c>.</p>
- <p>If a <em>tick</em> occurs, i.e., the Erlang node on the
+ <list type="bulleted">
+ <item>
+ <p><c>fd</c> is an open descriptor to an Erlang
+ connection. It is obtained from a previous
+ <c>ei_connect</c> or <c>ei_accept</c>.</p>
+ </item>
+ <item>
+ <p><c>bufp</c> is a buffer large enough to hold the
+ expected message.</p>
+ </item>
+ <item>
+ <p><c>bufsize</c> indicates the size of
+ <c>bufp</c>.</p>
+ </item>
+ </list>
+ <p>If a <em>tick</em> occurs, that is, the Erlang node on the
other end of the connection has polled this node to see if it
- is still alive, the function will return <c><![CDATA[ERL_TICK]]></c> and
- no message will be placed in the buffer. Also,
- <c><![CDATA[erl_errno]]></c> will be set to <c><![CDATA[EAGAIN]]></c>.</p>
+ is still alive, the function returns <c>ERL_TICK</c> and
+ no message is placed in the buffer. Also,
+ <c>erl_errno</c> is set to <c>EAGAIN</c>.</p>
<p>On success, the message is placed in the specified buffer
and the function returns the number of bytes actually read. On
- failure, the function returns <c><![CDATA[ERL_ERROR]]></c> and will set
- <c><![CDATA[erl_errno]]></c> to one of:</p>
+ failure, the function returns <c>ERL_ERROR</c> and sets
+ <c>erl_errno</c> to one of the following:</p>
<taglist>
- <tag><c><![CDATA[EAGAIN]]></c></tag>
+ <tag><c>EAGAIN</c></tag>
<item>Temporary error: Try again.</item>
- <tag><c><![CDATA[EMSGSIZE]]></c></tag>
- <item>Buffer too small.</item>
- <tag><c><![CDATA[EIO]]></c></tag>
+ <tag><c>EMSGSIZE</c></tag>
+ <item>Buffer is too small.</item>
+ <tag><c>EIO</c></tag>
<item>I/O error.</item>
</taglist>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_receive_tmo(int fd, unsigned char* bufp, int bufsize, unsigned timeout_ms)</nametext></name>
- <fsummary>Receive a message with optional timeout</fsummary>
+ <name><ret>int</ret><nametext>ei_receive_encoded(int fd, char **mbufp, int *bufsz, erlang_msg *msg, int *msglen)</nametext></name>
+ <fsummary>Obsolete function for receiving a message.</fsummary>
<desc>
- <p>ei_receive with an optional timeout argument,
- see the description at the beginning of this document.</p>
+ <p>This function is retained for compatibility with code
+ generated by the interface compiler and with code following
+ examples in the same application.</p>
+ <p>In essence, the function performs the same operation as
+ <c>ei_xreceive_msg</c>, but instead of using an
+ <c>ei_x_buff</c>, the function expects a pointer to a character
+ pointer (<c>mbufp</c>), where the character pointer
+ is to point to a memory area allocated by <c>malloc</c>.
+ Argument <c>bufsz</c> is to be a pointer to an integer
+ containing the exact size (in bytes) of the memory area. The function
+ may reallocate the memory area and will in such cases put the new
+ size in <c>*bufsz</c> and update
+ <c>*mbufp</c>.</p>
+ <p>Returns either <c>ERL_TICK</c> or the
+ <c>msgtype</c> field of the
+ <c>erlang_msg *msg</c>. The length
+ of the message is put in <c>*msglen</c>. On error
+ a value <c>&lt; 0</c> is returned.</p>
+ <p>It is recommended to use <c>ei_xreceive_msg</c> instead when
+ possible, for the sake of readability. However, the function will
+ be retained in the interface for compatibility and
+ will <em>not</em> be removed in future releases without prior
+ notice.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_receive_encoded_tmo(int fd, char **mbufp, int *bufsz, erlang_msg *msg, int *msglen, unsigned timeout_ms)</nametext></name>
+ <fsummary>Obsolete function for receiving a message with time-out.
+ </fsummary>
+ <desc>
+ <p>Equivalent to
+ <c>ei_receive_encoded</c> with an optional time-out argument,
+ see the description at the beginning of this manual page.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_receive_msg(int fd, erlang_msg* msg, ei_x_buff* x)</nametext></name>
<name><ret>int</ret><nametext>ei_xreceive_msg(int fd, erlang_msg* msg, ei_x_buff* x)</nametext></name>
- <fsummary>Receive a message</fsummary>
+ <fsummary>Receive a message.</fsummary>
<desc>
- <p>These functions receives a message to the buffer in
- <c><![CDATA[x]]></c>. <c><![CDATA[ei_xreceive_msg]]></c> allows the buffer in
- <c><![CDATA[x]]></c> to grow, but <c><![CDATA[ei_receive_msg]]></c> fails if the
- message is bigger than the preallocated buffer in <c><![CDATA[x]]></c>.</p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
- <p><c><![CDATA[msg]]></c> is a pointer to an <c><![CDATA[erlang_msg]]></c> structure
- and contains information on the message received.</p>
- <p><c><![CDATA[x]]></c> is buffer obtained from <c><![CDATA[ei_x_new]]></c>.</p>
- <p>On success, the function returns <c><![CDATA[ERL_MSG]]></c> and the
- <c><![CDATA[msg]]></c> struct will be initialized. <c><![CDATA[erlang_msg]]></c>
- is defined as follows:</p>
+ <p>Receives a message to the buffer in <c>x</c>.
+ <c>ei_xreceive_msg</c> allows the buffer in
+ <c>x</c> to grow, but <c>ei_receive_msg</c>
+ fails if the message is larger than the pre-allocated buffer in
+ <c>x</c>.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open descriptor to an Erlang
+ connection.</item>
+ <item><c>msg</c> is a pointer to an
+ <c>erlang_msg</c> structure
+ and contains information on the message received.</item>
+ <item><c>x</c> is buffer obtained from
+ <c>ei_x_new</c>.</item>
+ </list>
+ <p>On success, the functions return <c>ERL_MSG</c> and the
+ <c>msg</c> struct is initialized.
+ <c>erlang_msg</c> is defined as follows:</p>
<code type="none"><![CDATA[
typedef struct {
long msgtype;
@@ -257,125 +459,82 @@ typedef struct {
erlang_trace token;
} erlang_msg;
]]></code>
- <p><c><![CDATA[msgtype]]></c> identifies the type of message, and is one of
- <c><![CDATA[ERL_SEND]]></c>, <c><![CDATA[ERL_REG_SEND]]></c>, <c><![CDATA[ERL_LINK]]></c>,
- <c><![CDATA[ERL_UNLINK]]></c> and <c><![CDATA[ERL_EXIT]]></c>.</p>
- <p>If <c><![CDATA[msgtype]]></c> is <c><![CDATA[ERL_SEND]]></c> this indicates that an
- ordinary send operation has taken place, and <c><![CDATA[msg->to]]></c>
- contains the Pid of the recipient (the C-node). If
- <c><![CDATA[type]]></c> is <c><![CDATA[ERL_REG_SEND]]></c> then a registered send
- operation took place, and <c><![CDATA[msg->from]]></c> contains the Pid
- of the sender.</p>
- <p>If <c><![CDATA[msgtype]]></c> is <c><![CDATA[ERL_LINK]]></c> or <c><![CDATA[ERL_UNLINK]]></c>, then
- <c><![CDATA[msg->to]]></c> and <c><![CDATA[msg->from]]></c> contain the pids of the
- sender and recipient of the link or unlink.</p>
- <p>If <c><![CDATA[msgtype]]></c> is <c><![CDATA[ERL_EXIT]]></c>, then this indicates that
- a link has been broken. In this case, <c><![CDATA[msg->to]]></c> and
- <c><![CDATA[msg->from]]></c> contain the pids of the linked processes.</p>
- <p>The return value is the same as for <c><![CDATA[ei_receive]]></c>, see
- above.</p>
+ <p><c>msgtype</c> identifies the type of message, and is
+ one of the following:</p>
+ <taglist>
+ <tag><c>ERL_SEND</c></tag>
+ <item>
+ <p>Indicates that an ordinary send operation has occurred.
+ <c>msg-&gt;to</c> contains the pid of the recipient (the
+ C-node).</p>
+ </item>
+ <tag><c>ERL_REG_SEND</c></tag>
+ <item>
+ <p>A registered send operation occurred.
+ <c>msg-&gt;from</c> contains the pid of the sender.</p>
+ </item>
+ <tag><c>ERL_LINK</c> or
+ <c>ERL_UNLINK</c></tag>
+ <item>
+ <p><c>msg-&gt;to</c> and
+ <c>msg-&gt;from</c> contain the pids of the
+ sender and recipient of the link or unlink.</p>
+ </item>
+ <tag><c>ERL_EXIT</c></tag>
+ <item>
+ <p>Indicates a broken link. <c>msg-&gt;to</c> and
+ <c>msg-&gt;from</c> contain the pids of the linked
+ processes.</p>
+ </item>
+ </taglist>
+ <p>The return value is the same as for
+ <seealso marker="#ei_receive"><c>ei_receive</c></seealso>.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_receive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned imeout_ms)</nametext></name>
<name><ret>int</ret><nametext>ei_xreceive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned timeout_ms)</nametext></name>
- <fsummary>Receive a message with optional timeout</fsummary>
- <desc>
- <p>ei_receive_msg and ei_xreceive_msg with an optional timeout argument,
- see the description at the beginning of this document.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_receive_encoded(int fd, char **mbufp, int *bufsz, erlang_msg *msg, int *msglen)</nametext></name>
- <fsummary>Obsolete function for receiving a message</fsummary>
- <desc>
- <p>This function is retained for compatibility with code
- generated by the interface compiler and with code following
- examples in the same application.</p>
- <p>In essence the function performs the same operation as
- <c><![CDATA[ei_xreceive_msg]]></c>, but instead of using an ei_x_buff, the
- function expects a pointer to a character pointer
- (<c><![CDATA[mbufp]]></c>), where the character pointer should point to a
- memory area allocated by <c><![CDATA[malloc]]></c>. The argument
- <c><![CDATA[bufsz]]></c> should be a pointer to an integer containing the
- exact size (in bytes) of the memory area. The function may
- reallocate the memory area and will in such cases put the new
- size in <c><![CDATA[*bufsz]]></c> and update <c><![CDATA[*mbufp]]></c>.</p>
- <p>Furthermore the function returns either ERL_TICK or the
- <c><![CDATA[msgtype]]></c> field of the <c><![CDATA[erlang_msg *msg]]></c>. The actual
- length of the message is put in <c><![CDATA[*msglen]]></c>. On error it
- will return a value <c><![CDATA[< 0]]></c>.</p>
- <p>It is recommended to use ei_xreceive_msg instead when
- possible, for the sake of readability. The function will
- however be retained in the interface for compatibility and
- will <em>not</em> be removed not be removed in future releases
- without notice.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_receive_encoded_tmo(int fd, char **mbufp, int *bufsz, erlang_msg *msg, int *msglen, unsigned timeout_ms)</nametext></name>
- <fsummary>Obsolete function for receiving a message with timeout</fsummary>
- <desc>
- <p>ei_receive_encoded with an optional timeout argument,
- see the description at the beginning of this document.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_send(int fd, erlang_pid* to, char* buf, int len)</nametext></name>
- <fsummary>Send a message</fsummary>
- <desc>
- <p>This function sends an Erlang term to a process.</p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
- <p><c><![CDATA[to]]></c> is the Pid of the intended recipient of the
- message.</p>
- <p><c><![CDATA[buf]]></c> is the buffer containing the term in binary
- format.</p>
- <p><c><![CDATA[len]]></c> is the length of the message in bytes.</p>
- <p>The function returns 0 if successful, otherwise -1, in the
- latter case it will set <c><![CDATA[erl_errno]]></c> to <c><![CDATA[EIO]]></c>.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_send_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms)</nametext></name>
- <fsummary>Send a message with optional timeout</fsummary>
+ <fsummary>Receive a message with optional time-out.</fsummary>
<desc>
- <p>ei_send with an optional timeout argument,
- see the description at the beginning of this document.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_send_encoded(int fd, erlang_pid* to, char* buf, int len)</nametext></name>
- <fsummary>Obsolete function to send a message</fsummary>
- <desc>
- <p>Works exactly as ei_send, the alternative name retained for
- backward compatibility. The function will <em>not</em> be
- removed without notice.</p>
+ <p>Equivalent to <c>ei_receive_msg</c> and <c>ei_xreceive_msg</c>
+ with an optional time-out argument,
+ see the description at the beginning of this manual page.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_send_encoded_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms)</nametext></name>
- <fsummary>Obsolete function to send a message with optional timeout</fsummary>
+ <name><ret>int</ret><nametext>ei_receive_tmo(int fd, unsigned char* bufp, int bufsize, unsigned timeout_ms)</nametext></name>
+ <fsummary>Receive a message with optional time-out.</fsummary>
<desc>
- <p>ei_send_encoded with an optional timeout argument,
- see the description at the beginning of this document.</p>
+ <p>Equivalent to
+ <c>ei_receive</c> with an optional time-out argument,
+ see the description at the beginning of this manual page.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_reg_send(ei_cnode* ec, int fd, char* server_name, char* buf, int len)</nametext></name>
- <fsummary>Send a message to a registered name</fsummary>
+ <fsummary>Send a message to a registered name.</fsummary>
<desc>
- <p>This function sends an Erlang term to a registered process.
- </p>
- <p>This function sends an Erlang term to a process.</p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
- <p><c><![CDATA[server_name]]></c> is the registered name of the intended
- recipient.</p>
- <p><c><![CDATA[buf]]></c> is the buffer containing the term in binary
- format.</p>
- <p><c><![CDATA[len]]></c> is the length of the message in bytes.</p>
- <p>The function returns 0 if successful, otherwise -1, in the
- latter case it will set <c><![CDATA[erl_errno]]></c> to <c><![CDATA[EIO]]></c>.</p>
- <p>Example, send the atom "ok" to the process "worker":</p>
+ <p>Sends an Erlang term to a registered process.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>fd</c> is an open descriptor to an Erlang
+ connection.</p>
+ </item>
+ <item><c>server_name</c> is the registered name of the
+ intended recipient.</item>
+ <item><c>buf</c> is the buffer containing the term in
+ binary format.</item>
+ <item><c>len</c> is the length of the message in bytes.
+ </item>
+ </list>
+ <p>Returns <c>0</c> if successful, otherwise <c>-1</c>. In
+ the latter case it sets <c>erl_errno</c> to
+ <c>EIO</c>.</p>
+ <p><em>Example:</em></p>
+ <p>Send the atom "ok" to the process "worker":</p>
<code type="none"><![CDATA[
ei_x_buff x;
ei_x_new_with_version(&x);
@@ -385,96 +544,98 @@ if (ei_reg_send(&ec, fd, x.buff, x.index) < 0)
]]></code>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_reg_send_tmo(ei_cnode* ec, int fd, char* server_name, char* buf, int len, unsigned timeout_ms)</nametext></name>
- <fsummary>Send a message to a registered name with optional timeout</fsummary>
- <desc>
- <p>ei_reg_send with an optional timeout argument,
- see the description at the beginning of this document.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_send_reg_encoded(int fd, const erlang_pid *from, const char *to, const char *buf, int len)</nametext></name>
- <fsummary>Obsolete function to send a message to a registered name</fsummary>
- <desc>
- <p>This function is retained for compatibility with code
- generated by the interface compiler and with code following
- examples in the same application.</p>
- <p>The function works as <c><![CDATA[ei_reg_send]]></c> with one
- exception. Instead of taking the <c><![CDATA[ei_cnode]]></c> as a first
- argument, it takes a second argument, an <c><![CDATA[erlang_pid]]></c>
- which should be the process identifier of the sending process
- (in the erlang distribution protocol). </p>
- <p>A suitable <c><![CDATA[erlang_pid]]></c> can be constructed from the
- <c><![CDATA[ei_cnode]]></c> structure by the following example code:</p>
- <code type="none"><![CDATA[
- ei_cnode ec;
- erlang_pid *self;
- int fd; /* the connection fd */
- ...
- self = ei_self(&ec);
- self->num = fd;
- ]]></code>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to, const char *buf, int len)</nametext></name>
- <fsummary>Obsolete function to send a message to a registered name with timeout</fsummary>
+ <fsummary>Send a message to a registered name with optional time-out
+ </fsummary>
<desc>
- <p>ei_send_reg_encoded with an optional timeout argument,
- see the description at the beginning of this document.</p>
+ <p>Equivalent to
+ <c>ei_reg_send</c> with an optional time-out argument,
+ see the description at the beginning of this manual page.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_rpc(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf, int argbuflen, ei_x_buff *x)</nametext></name>
<name><ret>int</ret><nametext>ei_rpc_to(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf, int argbuflen)</nametext></name>
<name><ret>int</ret><nametext>ei_rpc_from(ei_cnode *ec, int fd, int timeout, erlang_msg *msg, ei_x_buff *x)</nametext></name>
- <fsummary>Remote Procedure Call from C to Erlang</fsummary>
+ <fsummary>Remote Procedure Call from C to Erlang.</fsummary>
<desc>
- <p>These functions support calling Erlang functions on remote nodes.
- <c><![CDATA[ei_rpc_to()]]></c> sends an rpc request to a remote node and
- <c><![CDATA[ei_rpc_from()]]></c> receives the results of such a call.
- <c><![CDATA[ei_rpc()]]></c> combines the functionality of these two functions
- by sending an rpc request and waiting for the results. See also
- <c><![CDATA[rpc:call/4]]></c>. </p>
- <p><c><![CDATA[ec]]></c> is the C-node structure previously initiated by a
- call to <c><![CDATA[ei_connect_init()]]></c> or
- <c><![CDATA[ei_connect_xinit()]]></c></p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
- <p><c><![CDATA[timeout]]></c> is the maximum time (in ms) to wait for
- results. Specify <c><![CDATA[ERL_NO_TIMEOUT]]></c> to wait forever.
- <c><![CDATA[ei_rpc()]]></c> will wait infinitely for the answer,
- i.e. the call will never time out.</p>
- <p><c><![CDATA[mod]]></c> is the name of the module containing the function
- to be run on the remote node.</p>
- <p><c><![CDATA[fun]]></c> is the name of the function to run.</p>
- <p><c><![CDATA[argbuf]]></c> is a pointer to a buffer with an encoded
- Erlang list, without a version magic number, containing the
- arguments to be passed to the function.</p>
- <p><c><![CDATA[argbuflen]]></c> is the length of the buffer containing the
- encoded Erlang list.</p>
- <p><c><![CDATA[msg]]></c> structure of type <c><![CDATA[erlang_msg]]></c> and contains
- information on the message received. See <c><![CDATA[ei_receive_msg()]]></c>
- for a description of the <c><![CDATA[erlang_msg]]></c> format.</p>
- <p><c><![CDATA[x]]></c> points to the dynamic buffer that receives the
- result. For for <c><![CDATA[ei_rpc()]]></c> this will be the result
- without the version magic number. For <c><![CDATA[ei_rpc_from()]]></c>
- the result will return a version magic number and a 2-tuple
- <c><![CDATA[{rex,Reply}]]></c>.</p>
- <p><c><![CDATA[ei_rpc()]]></c> returns the number of bytes in the result
- on success and -1 on failure. <c><![CDATA[ei_rpc_from()]]></c> returns
- number of bytes or one of <c><![CDATA[ERL_TICK]]></c>, <c><![CDATA[ERL_TIMEOUT]]></c>
- and <c><![CDATA[ERL_ERROR]]></c> otherwise. When failing,
- all three functions set <c><![CDATA[erl_errno]]></c> to one of:</p>
+ <p>Supports calling Erlang functions on remote nodes.
+ <c>ei_rpc_to()</c> sends an RPC request to a remote node
+ and <c>ei_rpc_from()</c> receives the results of such a
+ call. <c>ei_rpc()</c> combines the functionality of these
+ two functions by sending an RPC request and waiting for the results.
+ See also <seealso marker="kernel:rpc#call/4">
+ <c>rpc:call/4</c></seealso> in Kernel.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>ec</c> is the C-node structure previously
+ initiated by a call to <c>ei_connect_init()</c> or
+ <c>ei_connect_xinit()</c>.</p>
+ </item>
+ <item>
+ <p><c>fd</c> is an open descriptor to an Erlang
+ connection.</p>
+ </item>
+ <item>
+ <p><c>timeout</c> is the maximum time (in milliseconds)
+ to wait for results. Specify <c>ERL_NO_TIMEOUT</c> to
+ wait forever.
+ <c>ei_rpc()</c> waits infinitely for the answer,
+ that is, the call will never time out.</p>
+ </item>
+ <item>
+ <p><c>mod</c> is the name of the module containing the
+ function to be run on the remote node.</p>
+ </item>
+ <item>
+ <p><c>fun</c> is the name of the function to run.</p>
+ </item>
+ <item>
+ <p><c>argbuf</c> is a pointer to a buffer with an
+ encoded Erlang list, without a version magic number, containing
+ the arguments to be passed to the function.</p>
+ </item>
+ <item>
+ <p><c>argbuflen</c> is the length of the buffer
+ containing the encoded Erlang list.</p>
+ </item>
+ <item>
+ <p><c>msg</c> is structure of type
+ <c>erlang_msg</c> and contains information on the
+ message
+ received. For a description of the <c>erlang_msg</c>
+ format, see <seealso marker="#ei_receive_msg">
+ <c>ei_receive_msg</c></seealso>.</p>
+ </item>
+ <item>
+ <p><c>x</c> points to the dynamic buffer that receives
+ the result. For <c>ei_rpc()</c> this is the result
+ without the version magic number. For
+ <c>ei_rpc_from()</c> the result returns a version
+ magic number and a 2-tuple <c>{rex,Reply}</c>.</p>
+ </item>
+ </list>
+ <p><c>ei_rpc()</c> returns the number of bytes in the
+ result on success and <c>-1</c> on failure.
+ <c>ei_rpc_from()</c> returns the
+ number of bytes, otherwise one of <c>ERL_TICK</c>,
+ <c>ERL_TIMEOUT</c>,
+ and <c>ERL_ERROR</c>. When failing, all three
+ functions set <c>erl_errno</c> to one of the
+ following:</p>
<taglist>
- <tag><c><![CDATA[EIO]]></c></tag>
+ <tag><c>EIO</c></tag>
<item>I/O error.</item>
- <tag><c><![CDATA[ETIMEDOUT]]></c></tag>
- <item>Timeout expired.</item>
- <tag><c><![CDATA[EAGAIN]]></c></tag>
+ <tag><c>ETIMEDOUT</c></tag>
+ <item>Time-out expired.</item>
+ <tag><c>EAGAIN</c></tag>
<item>Temporary error: Try again.</item>
</taglist>
- <p>Example, check to see if an erlang process is alive:</p>
+ <p><em>Example:</em></p>
+ <p>Check to see if an Erlang process is alive:</p>
<code type="none"><![CDATA[
int index = 0, is_alive;
ei_x_buff args, result;
@@ -495,170 +656,190 @@ if (ei_decode_version(result.buff, &index) < 0
]]></code>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_publish(ei_cnode *ec, int port)</nametext></name>
- <fsummary>Publish a node name</fsummary>
+ <name><ret>erlang_pid *</ret><nametext>ei_self(ei_cnode *ec)</nametext></name>
+ <fsummary>Retrieve the pid of the C-node.</fsummary>
<desc>
- <p>These functions are used by a server process to register
- with the local name server <em>epmd</em>, thereby allowing
- other processes to send messages by using the registered name.
- Before calling either of these functions, the process should
- have called <c><![CDATA[bind()]]></c> and <c><![CDATA[listen()]]></c> on an open socket.</p>
- <p><c><![CDATA[ec]]></c> is the C-node structure.</p>
- <p><c><![CDATA[port]]></c> is the local name to register, and should be the
- same as the port number that was previously bound to the socket.</p>
- <p><c><![CDATA[addr]]></c> is the 32-bit IP address of the local host.</p>
- <p>To unregister with epmd, simply close the returned
- descriptor. Do not use <c><![CDATA[ei_unpublish()]]></c>, which is deprecated anyway.</p>
- <p>On success, the functions return a descriptor connecting the
- calling process to epmd. On failure, they return -1 and set
- <c><![CDATA[erl_errno]]></c> to <c><![CDATA[EIO]]></c>.</p>
- <p>Additionally, <c><![CDATA[errno]]></c> values from <c><![CDATA[socket]]></c><em>(2)</em>
- and <c><![CDATA[connect]]></c><em>(2)</em> system calls may be propagated
- into <c><![CDATA[erl_errno]]></c>.</p>
+ <p>Retrieves the pid of the C-node. Every C-node
+ has a (pseudo) pid used in <c>ei_send_reg</c>,
+ <c>ei_rpc</c>,
+ and others. This is contained in a field in the <c>ec</c>
+ structure. It will be safe for a long time to fetch this
+ field directly from the <c>ei_cnode</c> structure.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_publish_tmo(ei_cnode *ec, int port, unsigned timeout_ms)</nametext></name>
- <fsummary>Publish a node name with optional timeout</fsummary>
+ <name><ret>int</ret><nametext>ei_send(int fd, erlang_pid* to, char* buf, int len)</nametext></name>
+ <fsummary>Send a message.</fsummary>
<desc>
- <p>ei_publish with an optional timeout argument,
- see the description at the beginning of this document.</p>
+ <p>Sends an Erlang term to a process.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open descriptor to an Erlang
+ connection.</item>
+ <item><c>to</c> is the pid of the intended recipient of
+ the message.</item>
+ <item><c>buf</c> is the buffer containing the term in
+ binary format.</item>
+ <item><c>len</c> is the length of the message in bytes.
+ </item>
+ </list>
+ <p>Returns <c>0</c> if successful, otherwise <c>-1</c>. In
+ the latter case it sets <c>erl_errno</c> to
+ <c>EIO</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_accept(ei_cnode *ec, int listensock, ErlConnect *conp)</nametext></name>
- <fsummary>Accept a connection from another node</fsummary>
+ <name><ret>int</ret><nametext>ei_send_encoded(int fd, erlang_pid* to, char* buf, int len)</nametext></name>
+ <fsummary>Obsolete function to send a message.</fsummary>
<desc>
- <p>This function is used by a server process to accept a
- connection from a client process.</p>
- <p><c><![CDATA[ec]]></c> is the C-node structure.</p>
- <p><c><![CDATA[listensock]]></c> is an open socket descriptor on which
- <c><![CDATA[listen()]]></c> has previously been called.</p>
- <p><c><![CDATA[conp]]></c> is a pointer to an <c><![CDATA[ErlConnect]]></c> struct,
- described as follows:</p>
- <code type="none"><![CDATA[
-typedef struct {
- char ipadr[4];
- char nodename[MAXNODELEN];
-} ErlConnect;
- ]]></code>
- <p>On success, <c><![CDATA[conp]]></c> is filled in with the address and
- node name of the connecting client and a file descriptor is
- returned. On failure, <c><![CDATA[ERL_ERROR]]></c> is returned and
- <c><![CDATA[erl_errno]]></c> is set to <c><![CDATA[EIO]]></c>.</p>
+ <p>Works exactly as <c>ei_send</c>, the alternative name is retained for
+ backward compatibility. The function will <em>not</em> be
+ removed without prior notice.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_accept_tmo(ei_cnode *ec, int listensock, ErlConnect *conp, unsigned timeout_ms)</nametext></name>
- <fsummary>Accept a connection from another node with optional timeout</fsummary>
+ <name><ret>int</ret><nametext>ei_send_encoded_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms)</nametext></name>
+ <fsummary>Obsolete function to send a message with optional time-out.
+ </fsummary>
<desc>
- <p>ei_accept with an optional timeout argument,
- see the description at the beginning of this document.</p>
+ <p>Equivalent to
+ <c>ei_send_encoded</c> with an optional time-out argument,
+ see the description at the beginning of this manual page.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_unpublish(ei_cnode *ec)</nametext></name>
- <fsummary>Forcefully unpublish a node name</fsummary>
+ <name><ret>int</ret><nametext>ei_send_reg_encoded(int fd, const erlang_pid *from, const char *to, const char *buf, int len)</nametext></name>
+ <fsummary>Obsolete function to send a message to a registered name.
+ </fsummary>
<desc>
- <p>This function can be called by a process to unregister a
- specified node from epmd on the localhost. This is however usually not
- allowed, unless epmd was started with the -relaxed_command_check
- flag, which it normally isn't.</p>
-
- <p>To unregister a node you have published, you should
- close the descriptor that was returned by
- <c><![CDATA[ei_publish()]]></c>.</p>
+ <p>This function is retained for compatibility with code
+ generated by the interface compiler and with code following
+ examples in the same application.</p>
+ <p>The function works as <c>ei_reg_send</c> with one
+ exception. Instead of taking <c>ei_cnode</c> as first
+ argument, it takes a second argument, an
+ <c>erlang_pid</c>,
+ which is to be the process identifier of the sending process
+ (in the Erlang distribution protocol).</p>
+ <p>A suitable <c>erlang_pid</c> can be constructed from the
+ <c>ei_cnode</c> structure by the following example
+ code:</p>
+ <code type="none"><![CDATA[
+ei_cnode ec;
+erlang_pid *self;
+int fd; /* the connection fd */
+...
+self = ei_self(&ec);
+self->num = fd;
+ ]]></code>
+ </desc>
+ </func>
- <warning>
- <p>This function is deprecated and will be removed in a future
- release.</p>
- </warning>
- <p><c><![CDATA[ec]]></c> is the node structure of the node to unregister.</p>
- <p>If the node was successfully unregistered from epmd, the
- function returns 0. Otherwise, it returns -1 and sets
- <c><![CDATA[erl_errno]]></c> is to <c><![CDATA[EIO]]></c>.</p>
+ <func>
+ <name><ret>int</ret><nametext>ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to, const char *buf, int len)</nametext></name>
+ <fsummary>Obsolete function to send a message to a registered name with
+ time-out.</fsummary>
+ <desc>
+ <p>Equivalent to
+ <c>ei_send_reg_encoded</c> with an optional time-out argument,
+ see the description at the beginning of this manual page.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_unpublish_tmo(ei_cnode *ec, unsigned timeout_ms)</nametext></name>
- <fsummary>Unpublish a node name with optional timeout</fsummary>
+ <name><ret>int</ret><nametext>ei_send_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms)</nametext></name>
+ <fsummary>Send a message with optional time-out.</fsummary>
<desc>
- <p>ei_unpublish with an optional timeout argument,
- see the description at the beginning of this document.</p>
+ <p>Equivalent to
+ <c>ei_send</c> with an optional time-out argument,
+ see the description at the beginning of this manual page.</p>
</desc>
</func>
+
<func>
<name><ret>const char *</ret><nametext>ei_thisnodename(ei_cnode *ec)</nametext></name>
<name><ret>const char *</ret><nametext>ei_thishostname(ei_cnode *ec)</nametext></name>
<name><ret>const char *</ret><nametext>ei_thisalivename(ei_cnode *ec)</nametext></name>
- <fsummary>Retrieve some values</fsummary>
+ <fsummary>Retrieve some values.</fsummary>
<desc>
- <p>These functions can be used to retrieve information about
- the C Node. These values are initially set with
- <c><![CDATA[ei_connect_init()]]></c> or <c><![CDATA[ei_connect_xinit()]]></c>.</p>
- <p>They simply fetches the appropriate field from the <c><![CDATA[ec]]></c>
+ <p>Can be used to retrieve information about
+ the C-node. These values are initially set with
+ <c>ei_connect_init()</c> or
+ <c>ei_connect_xinit()</c>.</p>
+ <p>These function simply fetch the appropriate field from the
+ <c>ec</c>
structure. Read the field directly will probably be safe for
a long time, so these functions are not really needed.</p>
</desc>
</func>
+
<func>
- <name><ret>erlang_pid *</ret><nametext>ei_self(ei_cnode *ec)</nametext></name>
- <fsummary>Retrieve the Pid of the C-node</fsummary>
- <desc>
- <p>This function retrieves the Pid of the C-node. Every C-node
- has a (pseudo) pid used in <c><![CDATA[ei_send_reg]]></c>, <c><![CDATA[ei_rpc]]></c>
- and others. This is contained in a field in the <c><![CDATA[ec]]></c>
- structure. It will be safe for a long time to fetch this
- field directly from the <c><![CDATA[ei_cnode]]></c> structure.</p>
- </desc>
- </func>
- <func>
- <name><ret>struct hostent</ret><nametext>*ei_gethostbyname(const char *name)</nametext></name>
- <name><ret>struct hostent</ret><nametext>*ei_gethostbyaddr(const char *addr, int len, int type)</nametext></name>
- <name><ret>struct hostent</ret><nametext>*ei_gethostbyname_r(const char *name, struct hostent *hostp, char *buffer, int buflen, int *h_errnop)</nametext></name>
- <name><ret>struct hostent</ret><nametext>*ei_gethostbyaddr_r(const char *addr, int length, int type, struct hostent *hostp, char *buffer, int buflen, int *h_errnop)</nametext></name>
- <fsummary>Name lookup functions</fsummary>
+ <name><ret>int</ret><nametext>ei_unpublish(ei_cnode *ec)</nametext></name>
+ <fsummary>Forcefully unpublish a node name.</fsummary>
<desc>
- <p>These are convenience functions for some common name lookup functions.</p>
+ <p>Can be called by a process to unregister a
+ specified node from EPMD on the local host. This is, however, usually
+ not allowed, unless EPMD was started with flag
+ <c>-relaxed_command_check</c>, which it normally is not.</p>
+ <p>To unregister a node you have published, you should
+ close the descriptor that was returned by
+ <c>ei_publish()</c>.</p>
+ <warning>
+ <p>This function is deprecated and will be removed in a future
+ release.</p>
+ </warning>
+ <p><c>ec</c> is the node structure of the node to
+ unregister.</p>
+ <p>If the node was successfully unregistered from EPMD, the
+ function returns <c>0</c>. Otherwise, <c>-1</c> is returned and
+ <c>erl_errno</c> is set to <c>EIO</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_get_tracelevel(void)</nametext></name>
- <name><ret>void</ret><nametext>ei_set_tracelevel(int level)</nametext></name>
- <fsummary>Get and set functions for tracing.</fsummary>
+ <name><ret>int</ret><nametext>ei_unpublish_tmo(ei_cnode *ec, unsigned timeout_ms)</nametext></name>
+ <fsummary>Unpublish a node name with optional time-out.</fsummary>
<desc>
- <p>These functions are used to set tracing on the distribution. The levels are different verbosity levels. A higher level means more information.
- See also Debug Information and <c><![CDATA[EI_TRACELEVEL]]></c> below. </p>
- <p> <c><![CDATA[ei_set_tracelevel]]></c> and <c><![CDATA[ei_get_tracelevel]]></c> are not thread safe. </p>
+ <p>Equivalent to
+ <c>ei_unpublish</c> with an optional time-out argument,
+ see the description at the beginning of this manual page.</p>
</desc>
</func>
</funcs>
<section>
+ <marker id="debug_information"></marker>
<title>Debug Information</title>
<p>If a connection attempt fails, the following can be checked:</p>
+
<list type="bulleted">
- <item><c><![CDATA[erl_errno]]></c></item>
- <item>that the right cookie was used</item>
- <item>that <em>epmd</em> is running</item>
- <item>the remote Erlang node on the other side is running the
- same version of Erlang as the <c><![CDATA[ei]]></c>
- library.</item>
- <item>the environment variable <c><![CDATA[ERL_EPMD_PORT]]></c>
- is set correctly.</item>
+ <item><c>erl_errno</c>.</item>
+ <item>That the correct cookie was used</item>
+ <item>That EPMD is running</item>
+ <item>That the remote Erlang node on the other side is running the
+ same version of Erlang as the <c>ei</c> library</item>
+ <item>That environment variable <c>ERL_EPMD_PORT</c>
+ is set correctly</item>
</list>
- <p>The connection attempt can be traced by setting a tracelevel by either using
- <c><![CDATA[ei_set_tracelevel]]></c> or by setting the environment variable <c><![CDATA[EI_TRACELEVEL]]></c>.
- The different tracelevels has the following messages:</p>
+
+ <p>The connection attempt can be traced by setting a trace level by either
+ using <c>ei_set_tracelevel</c> or by setting environment
+ variable <c>EI_TRACELEVEL</c>.
+ The trace levels have the following messages:</p>
+
<list>
- <item>1: Verbose error messages</item>
- <item>2: Above messages and verbose warning messages </item>
- <item>3: Above messages and progress reports for connection handling</item>
- <item>4: Above messages and progress reports for communication</item>
- <item>5: Above messages and progress reports for data conversion</item>
+ <item>1: Verbose error messages</item>
+ <item>2: Above messages and verbose warning messages</item>
+ <item>3: Above messages and progress reports for connection handling
+ </item>
+ <item>4: Above messages and progress reports for communication</item>
+ <item>5: Above messages and progress reports for data conversion</item>
</list>
</section>
</cref>
-
diff --git a/lib/erl_interface/doc/src/ei_users_guide.xml b/lib/erl_interface/doc/src/ei_users_guide.xml
index 4b9809aee4..0eed50b50b 100644
--- a/lib/erl_interface/doc/src/ei_users_guide.xml
+++ b/lib/erl_interface/doc/src/ei_users_guide.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,10 +19,10 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
- <title>The El Library User's Guide</title>
+ <title>Erl_Interface User's Guide</title>
<prepared>Kent Boortz</prepared>
<responsible>Kent Boortz</responsible>
<docno></docno>
@@ -32,100 +32,158 @@
<rev></rev>
<file>ei_users_guide.xml</file>
</header>
- <p>The Erl_Interface library contains functions. which help you
- integrate programs written in C and Erlang. The functions in
- Erl_Interface support the following:</p>
- <list type="bulleted">
- <item>manipulation of data represented as Erlang data types</item>
- <item>conversion of data between C and Erlang formats</item>
- <item>encoding and decoding of Erlang data types for transmission or storage</item>
- <item>communication between C nodes and Erlang processes</item>
- <item>backup and restore of C node state to and from Mnesia</item>
- </list>
- <p>In the following sections, these topics are described:</p>
- <list type="bulleted">
- <item>compiling your code for use with Erl_Interface</item>
- <item>initializing Erl_Interface</item>
- <item>encoding, decoding, and sending Erlang terms</item>
- <item>building terms and patterns</item>
- <item>pattern matching</item>
- <item>connecting to a distributed Erlang node</item>
- <item>using EPMD</item>
- <item>sending and receiving Erlang messages</item>
- <item>remote procedure calls</item>
- <item>global names</item>
- <item>the registry</item>
- </list>
+
+ <section>
+ <title>Introduction</title>
+ <p>The <c>Erl_Interface</c> library contains functions that help you
+ integrate programs written in C and Erlang. The functions in
+ <c>Erl_Interface</c> support the following:</p>
+ <list type="bulleted">
+ <item>Manipulation of data represented as Erlang data types</item>
+ <item>Conversion of data between C and Erlang formats</item>
+ <item>Encoding and decoding of Erlang data types for transmission or
+ storage</item>
+ <item>Communication between C nodes and Erlang processes</item>
+ <item>Backup and restore of C node state to and from
+ <seealso marker="mnesia:mnesia">Mnesia</seealso></item>
+ </list>
+ <note>
+ <p>By default, the <c>Erl_Interface</c> libraries are only guaranteed
+ to be compatible with other Erlang/OTP components from the same
+ release as the libraries themselves. For information about how to
+ communicate with Erlang/OTP components from earlier releases, see
+ function <seealso marker="ei#ei_set_compat_rel">
+ <c>ei:ei_set_compat_rel</c></seealso> and
+ <seealso marker="erl_eterm#erl_set_compat_rel">
+ <c>erl_eterm:erl_set_compat_rel</c></seealso>.</p>
+ </note>
+
+ <section>
+ <title>Scope</title>
+ <p>In the following sections, these topics are described:</p>
+ <list type="bulleted">
+ <item>Compiling your code for use with <c>Erl_Interface</c></item>
+ <item>Initializing <c>Erl_Interface</c></item>
+ <item>Encoding, decoding, and sending Erlang terms</item>
+ <item>Building terms and patterns</item>
+ <item>Pattern matching</item>
+ <item>Connecting to a distributed Erlang node</item>
+ <item>Using the Erlang Port Mapper Daemon (EPMD)</item>
+ <item>Sending and receiving Erlang messages</item>
+ <item>Remote procedure calls</item>
+ <item>Using global names</item>
+ <item>Using the registry</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Prerequisites</title>
+ <p>It is assumed that the reader is familiar with the Erlang programming
+ language.</p>
+ </section>
+ </section>
<section>
<title>Compiling and Linking Your Code</title>
- <p>In order to use any of the Erl_Interface functions, include the
+ <p>To use any of the <c>Erl_Interface</c> functions, include the
following lines in your code:</p>
+
<code type="none"><![CDATA[
#include "erl_interface.h"
#include "ei.h" ]]></code>
- <p>Determine where the top directory of your OTP installation is. You
- can find this out by starting Erlang and entering the following
+
+ <p>Determine where the top directory of your OTP installation is.
+ To find this, start Erlang and enter the following
command at the Eshell prompt:</p>
+
<code type="none"><![CDATA[
Eshell V4.7.4 (abort with ^G)
1> code:root_dir().
/usr/local/otp ]]></code>
- <p>To compile your code, make sure that your C compiler knows where
- to find <c><![CDATA[erl_interface.h]]></c> by specifying an appropriate <c><![CDATA[-I]]></c>
- argument on the command line, or by adding it to the <c><![CDATA[CFLAGS]]></c>
- definition in your <c><![CDATA[Makefile]]></c>. The correct value for this path is
- <c><![CDATA[$OTPROOT/lib/erl_interface]]></c><em>Vsn</em><c><![CDATA[/include]]></c>, where <c><![CDATA[$OTPROOT]]></c> is the path
- reported by <c><![CDATA[code:root_dir/0]]></c> in the above example, and <em>Vsn</em> is
- the version of the Erl_interface application, for example
- <c><![CDATA[erl_interface-3.2.3]]></c></p>
+
+ <p>To compile your code, ensure that your C compiler knows where
+ to find <c>erl_interface.h</c> by specifying an appropriate
+ <c>-I</c> argument on the command line, or add it to
+ the <c>CFLAGS</c> definition in your
+ <c>Makefile</c>. The correct value for this path is
+ <c>$OTPROOT/lib/erl_interface-$EIVSN/include</c>,
+ where:</p>
+
+ <list type="bulleted">
+ <item>
+ <p><c>$OTPROOT</c> is the path reported by
+ <c>code:root_dir/0</c> in the example above.</p>
+ </item>
+ <item>
+ <p><c>$EIVSN</c> is the version of the <c>Erl_Interface</c> application,
+ for example, <c>erl_interface-3.2.3</c>.</p>
+ </item>
+ </list>
+
+ <p>Compiling the code:</p>
+
<code type="none"><![CDATA[
$ cc -c -I/usr/local/otp/lib/erl_interface-3.2.3/include myprog.c ]]></code>
- <p>When linking, you will need to specify the path to
- <c><![CDATA[liberl_interface.a]]></c> and <c><![CDATA[libei.a]]></c> with
- <c><![CDATA[-L$OTPROOT/lib/erl_interface-3.2.3/lib]]></c>, and you will need to specify the
- name of the libraries with <c><![CDATA[-lerl_interface -lei]]></c>. You can do
- this on the command line or by adding the flags to the <c><![CDATA[LDFLAGS]]></c>
- definition in your <c><![CDATA[Makefile]]></c>.</p>
+
+ <p>When linking:</p>
+
+ <list type="bulleted">
+ <item>Specify the path to <c>liberl_interface.a</c> and
+ <c>libei.a</c> with
+ <c>-L$OTPROOT/lib/erl_interface-3.2.3/lib</c>.</item>
+ <item>Specify the name of the libraries with
+ <c>-lerl_interface -lei</c>.</item>
+ </list>
+
+ <p>Do this on the command line or add the flags to the
+ <c>LDFLAGS</c> definition in your
+ <c>Makefile</c>.</p>
+
+ <p>Linking the code:</p>
+
<code type="none"><![CDATA[
$ ld -L/usr/local/otp/lib/erl_interface-3.2.3/
lib myprog.o -lerl_interface -lei -o myprog ]]></code>
- <p>Also, on some systems it may be necessary to link with some
- additional libraries (e.g. <c><![CDATA[libnsl.a]]></c> and <c><![CDATA[libsocket.a]]></c> on
- Solaris, or <c><![CDATA[wsock32.lib]]></c> on Windows) in order to use the
- communication facilities of Erl_Interface.</p>
- <p>If you are using Erl_Interface functions in a threaded
+
+ <p>On some systems it can be necessary to link with some more
+ libraries (for example, <c>libnsl.a</c> and
+ <c>libsocket.a</c> on Solaris, or
+ <c>wsock32.lib</c> on Windows) to use the
+ communication facilities of <c>Erl_Interface</c>.</p>
+
+ <p>If you use the <c>Erl_Interface</c> functions in a threaded
application based on POSIX threads or Solaris threads, then
- Erl_Interface needs access to some of the synchronization
- facilities in your threads package, and you will need to specify
- additional compiler flags in order to indicate which of the packages
- you are using. Define <c><![CDATA[_REENTRANT]]></c> and either <c><![CDATA[STHREADS]]></c> or
- <c><![CDATA[PTHREADS]]></c>. The default is to use POSIX threads if
- <c><![CDATA[_REENTRANT]]></c> is specified.</p>
+ <c>Erl_Interface</c> needs access to some of the synchronization
+ facilities in your threads package. You must specify extra
+ compiler flags to indicate which of the packages you use. Define
+ <c>_REENTRANT</c> and either <c>STHREADS</c> or
+ <c>PTHREADS</c>. The default is to use POSIX threads if
+ <c>_REENTRANT</c> is specified.</p>
</section>
<section>
- <title>Initializing the erl_interface Library</title>
- <p>Before calling any of the other Erl_Interface functions, you
- must call <c><![CDATA[erl_init()]]></c> exactly once to initialize the library.
- <c><![CDATA[erl_init()]]></c> takes two arguments, however the arguments are no
- longer used by Erl_Interface, and should therefore be specified
- as <c><![CDATA[erl_init(NULL,0)]]></c>.</p>
+ <title>Initializing the Erl_Interface Library</title>
+ <p>Before calling any of the other <c>Erl_Interface</c> functions, call
+ <c>erl_init()</c> exactly once to initialize the library.
+ <c>erl_init()</c> takes two arguments. However, the arguments
+ are no longer used by <c>Erl_Interface</c> and are therefore to be
+ specified as <c>erl_init(NULL,0)</c>.</p>
</section>
<section>
- <title>Encoding, Decoding and Sending Erlang Terms</title>
+ <title>Encoding, Decoding, and Sending Erlang Terms</title>
<p>Data sent between distributed Erlang nodes is encoded in the
- Erlang external format. Consequently, you have to encode and decode
+ Erlang external format. You must therefore encode and decode
Erlang terms into byte streams if you want to use the distribution
- protocol to communicate between a C program and Erlang. </p>
- <p>The Erl_Interface library supports this activity. It has a
- number of C functions which create and manipulate Erlang data
+ protocol to communicate between a C program and Erlang.</p>
+
+ <p>The <c>Erl_Interface</c> library supports this activity. It has
+ several C functions that create and manipulate Erlang data
structures. The library also contains an encode and a decode function.
- The example below shows how to create and encode an Erlang tuple
- <c><![CDATA[{tobbe,3928}]]></c>:</p>
- <code type="none"><![CDATA[
+ The following example shows how to create and encode an Erlang tuple
+ <c>{tobbe,3928}</c>:</p>
+ <code type="none"><![CDATA[
ETERM *arr[2], *tuple;
char buf[BUFSIZ];
int i;
@@ -134,58 +192,70 @@ arr[0] = erl_mk_atom("tobbe");
arr[1] = erl_mk_integer(3928);
tuple = erl_mk_tuple(arr, 2);
i = erl_encode(tuple, buf); ]]></code>
- <p>Alternatively, you can use <c><![CDATA[erl_send()]]></c> and
- <c><![CDATA[erl_receive_msg]]></c>, which handle the encoding and decoding of
- messages transparently.</p>
- <p>Refer to the Reference Manual for a complete description of the
- following modules:</p>
+
+ <p>Alternatively, you can use <c>erl_send()</c> and
+ <c>erl_receive_msg</c>, which handle the encoding and
+ decoding of messages transparently.</p>
+
+ <p>For a complete description, see the following modules:</p>
<list type="bulleted">
- <item>the <c><![CDATA[erl_eterm]]></c> module for creating Erlang terms</item>
- <item>the <c><![CDATA[erl_marshal]]></c> module for encoding and decoding routines.</item>
+ <item><seealso marker="erl_eterm"><c>erl_eterm</c></seealso>
+ for creating Erlang terms</item>
+ <item><seealso marker="erl_marshal"><c>erl_marshal</c></seealso>
+ for encoding and decoding routines</item>
</list>
</section>
<section>
+ <marker id="building_terms_and_patterns"/>
<title>Building Terms and Patterns</title>
- <p>The previous example can be simplified by using
- <c><![CDATA[erl_format()]]></c> to create an Erlang term.</p>
- <code type="none"><![CDATA[
+ <p>The previous example can be simplified by using the
+ <seealso marker="erl_format"><c>erl_format</c></seealso> module
+ to create an Erlang term:</p>
+ <code type="none"><![CDATA[
ETERM *ep;
ep = erl_format("{~a,~i}", "tobbe", 3928); ]]></code>
- <p>Refer to the Reference Manual, the <c><![CDATA[erl_format]]></c> module, for a
- full description of the different format directives. The following
- example is more complex:</p>
- <code type="none"><![CDATA[
+ <p>For a complete description of the different format directives, see
+ the <seealso marker="erl_format"><c>erl_format</c></seealso> module.</p>
+
+ <p>The following example is more complex:</p>
+
+ <code type="none"><![CDATA[
ETERM *ep;
ep = erl_format("[{name,~a},{age,~i},{data,~w}]",
"madonna",
21,
erl_format("[{adr,~s,~i}]", "E-street", 42));
erl_free_compound(ep); ]]></code>
- <p>As in previous examples, it is your responsibility to free the
- memory allocated for Erlang terms. In this example,
- <c><![CDATA[erl_free_compound()]]></c> ensures that the complete term pointed to
- by <c><![CDATA[ep]]></c> is released. This is necessary, because the pointer from
- the second call to <c><![CDATA[erl_format()]]></c> is lost. </p>
- <p>The following
- example shows a slightly different solution:</p>
- <code type="none"><![CDATA[
+ <p>As in the previous examples, it is your responsibility to free the
+ memory allocated for Erlang terms. In this example,
+ <c>erl_free_compound()</c> ensures that the complete term
+ pointed to by <c>ep</c> is released. This is necessary
+ because the pointer from the second call to <c>erl_format</c> is lost.</p>
+
+ <p>The following example shows a slightly different solution:</p>
+
+ <code type="none"><![CDATA[
ETERM *ep,*ep2;
ep2 = erl_format("[{adr,~s,~i}]","E-street",42);
ep = erl_format("[{name,~a},{age,~i},{data,~w}]",
"madonna", 21, ep2);
erl_free_term(ep);
erl_free_term(ep2); ]]></code>
+
<p>In this case, you free the two terms independently. The order in
- which you free the terms <c><![CDATA[ep]]></c> and <c><![CDATA[ep2]]></c> is not important,
- because the Erl_Interface library uses reference counting to
- determine when it is safe to actually remove objects. </p>
- <p>If you are not sure whether you have freed the terms properly, you
+ which you free the terms <c>ep</c> and <c>ep2</c>
+ is not important,
+ because the <c>Erl_Interface</c> library uses reference counting to
+ determine when it is safe to remove objects.</p>
+
+ <p>If you are unsure whether you have freed the terms properly, you
can use the following function to see the status of the fixed term
allocator:</p>
+
<code type="none"><![CDATA[
long allocated, freed;
@@ -196,36 +266,49 @@ printf("length of freelist: %ld\n",freed);
/* really free the freelist */
erl_eterm_release();
]]></code>
- <p>Refer to the Reference Manual, the <c><![CDATA[erl_malloc]]></c> module for more
- information.</p>
+
+ <p>For more information, see the
+ <seealso marker="erl_malloc"><c>erl_malloc</c></seealso> module.</p>
</section>
<section>
<title>Pattern Matching</title>
- <p>An Erlang pattern is a term that may contain unbound variables or
- <c><![CDATA["do not care"]]></c> symbols. Such a pattern can be matched against a
+ <p>An Erlang pattern is a term that can contain unbound variables or
+ <c>"do not care"</c> symbols. Such a pattern can be matched
+ against a
term and, if the match is successful, any unbound variables in the
pattern will be bound as a side effect. The content of a bound
- variable can then be retrieved.</p>
- <code type="none"><![CDATA[
+ variable can then be retrieved:</p>
+ <code type="none"><![CDATA[
ETERM *pattern;
pattern = erl_format("{madonna,Age,_}"); ]]></code>
- <p><c><![CDATA[erl_match()]]></c> is used to perform pattern matching. It takes a
+
+ <p>The <seealso marker="erl_format#erl_match">
+ <c>erl_format:erl_match</c></seealso> function
+ performs pattern matching. It takes a
pattern and a term and tries to match them. As a side effect any unbound
- variables in the pattern will be bound. In the following example, we
- create a pattern with a variable <em>Age</em> which appears at two
+ variables in the pattern will be bound. In the following example, a
+ pattern is created with a variable <c>Age</c>, which is included at two
positions in the tuple. The pattern match is performed as follows:</p>
- <list type="ordered">
- <item><c><![CDATA[erl_match()]]></c> will bind the contents of
- <em>Age</em> to <em>21</em> the first time it reaches the variable</item>
- <item>the second occurrence of <em>Age</em> will cause a test for
- equality between the terms since <em>Age</em> is already bound to
- <em>21</em>. Since <em>Age</em> is bound to 21, the equality test will
- succeed and the match continues until the end of the pattern.</item>
- <item>if the end of the pattern is reached, the match succeeds and you
- can retrieve the contents of the variable</item>
+
+ <list type="bulleted">
+ <item>
+ <p><c>erl_match</c> binds the contents of <c>Age</c> to <c>21</c>
+ the first time it reaches the variable.</p>
+ </item>
+ <item>
+ <p>The second occurrence of <c>Age</c> causes a test for
+ equality between the terms, as <c>Age</c> is already bound to
+ <c>21</c>. As <c>Age</c> is bound to <c>21</c>, the equality test
+ succeeds and the match continues until the end of the pattern.</p>
+ </item>
+ <item>
+ <p>If the end of the pattern is reached, the match succeeds and you
+ can retrieve the contents of the variable.</p>
+ </item>
</list>
+
<code type="none"><![CDATA[
ETERM *pattern,*term;
pattern = erl_format("{madonna,Age,Age}");
@@ -239,99 +322,136 @@ if (erl_match(pattern, term)) {
}
erl_free_term(pattern);
erl_free_term(term); ]]></code>
- <p>Refer to the Reference Manual, the <c><![CDATA[erl_match()]]></c> function for
- more information.</p>
+
+ <p>For more information, see the
+ <seealso marker="erl_format#erl_match">
+ <c>erl_format:erl_match</c></seealso> function.</p>
</section>
<section>
<title>Connecting to a Distributed Erlang Node</title>
- <p>In order to connect to a distributed Erlang node you need to first
- initialize the connection routine with <c><![CDATA[erl_connect_init()]]></c>,
- which stores information such as the host name, node name, and IP
+ <p>To connect to a distributed Erlang node, you must first
+ initialize the connection routine with
+ <seealso marker="erl_connect#erl_connect_init">
+ <c>erl_connect:erl_connect_init</c></seealso>,
+ which stores information, such as the hostname, node name, and IP
address for later use:</p>
+
<code type="none"><![CDATA[
int identification_number = 99;
int creation=1;
char *cookie="a secret cookie string"; /* An example */
erl_connect_init(identification_number, cookie, creation); ]]></code>
- <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information.</p>
+
+ <p>For more information, see the
+ <seealso marker="erl_connect"><c>erl_connect</c></seealso> module.</p>
+
<p>After initialization, you set up the connection to the Erlang node.
- Use <c><![CDATA[erl_connect()]]></c> to specify the Erlang node you want to
- connect to. The following example sets up the connection and should
- result in a valid socket file descriptor:</p>
+ To specify the Erlang node you want to connect to, use
+ <c>erl_connect()</c>. The following example sets up the
+ connection and is to result in a valid socket file descriptor:</p>
+
<code type="none"><![CDATA[
int sockfd;
char *nodename="[email protected]"; /* An example */
if ((sockfd = erl_connect(nodename)) < 0)
erl_err_quit("ERROR: erl_connect failed"); ]]></code>
- <p><c><![CDATA[erl_err_quit()]]></c> prints the specified string and terminates
- the program. Refer to the Reference Manual, the <c><![CDATA[erl_error()]]></c>
- function for more information.</p>
+
+ <p><c>erl_err_quit()</c> prints the specified string and
+ terminates the program. For more information, see the
+ <seealso marker="erl_error"><c>erl_error</c></seealso> module.</p>
</section>
<section>
<title>Using EPMD</title>
- <p><c><![CDATA[Epmd]]></c> is the Erlang Port Mapper Daemon. Distributed Erlang nodes
- register with <c><![CDATA[epmd]]></c> on the localhost to indicate to other nodes that
- they exist and can accept connections. <c><![CDATA[Epmd]]></c> maintains a register of
+ <p><seealso marker="erts:epmd"><c>erts:epmd</c></seealso>
+ is the Erlang Port Mapper Daemon. Distributed
+ Erlang nodes register with <c>epmd</c> on the local host to
+ indicate to other nodes that they exist and can accept connections.
+ <c>epmd</c> maintains a register of
node and port number information, and when a node wishes to connect to
- another node, it first contacts <c><![CDATA[epmd]]></c> in order to find out the correct
- port number to connect to.</p>
- <p>When you use <c><![CDATA[erl_connect()]]></c> to connect to an Erlang node, a
- connection is first made to <c><![CDATA[epmd]]></c> and, if the node is known, a
+ another node, it first contacts <c>epmd</c> to find the
+ correct port number to connect to.</p>
+
+ <p>When you use
+ <seealso marker="erl_connect"><c>erl_connect</c></seealso>
+ to connect to an Erlang node, a connection is first made to
+ <c>epmd</c> and, if the node is known, a
connection is then made to the Erlang node.</p>
- <p>C nodes can also register themselves with <c><![CDATA[epmd]]></c> if they want other
+
+ <p>C nodes can also register themselves with <c>epmd</c>
+ if they want other
nodes in the system to be able to find and connect to them.</p>
- <p>Before registering with <c><![CDATA[epmd]]></c>, you need to first create a listen socket
- and bind it to a port. Then:</p>
+
+ <p>Before registering with <c>epmd</c>, you must first
+ create a listen socket and bind it to a port. Then:</p>
+
<code type="none"><![CDATA[
int pub;
pub = erl_publish(port); ]]></code>
- <p><c><![CDATA[pub]]></c> is a file descriptor now connected to <c><![CDATA[epmd]]></c>. <c><![CDATA[Epmd]]></c>
- monitors the other end of the connection, and if it detects that the
- connection has been closed, the node will be unregistered. So, if you
- explicitly close the descriptor or if your node fails, it will be
- unregistered from <c><![CDATA[epmd]]></c>.</p>
- <p>Be aware that on some systems (such as VxWorks), a failed node will
- not be detected by this mechanism since the operating system does not
+
+ <p><c>pub</c> is a file descriptor now connected to
+ <c>epmd</c>. <c>epmd</c>
+ monitors the other end of the connection. If it detects that the
+ connection has been closed, the node becomes unregistered. So, if you
+ explicitly close the descriptor or if your node fails, it becomes
+ unregistered from <c>epmd</c>.</p>
+
+ <p>Notice that on some systems (such as VxWorks), a failed node is
+ not detected by this mechanism, as the operating system does not
automatically close descriptors that were left open when the node
- failed. If a node has failed in this way, <c><![CDATA[epmd]]></c> will prevent you from
- registering a new node with the old name, since it thinks that the old
+ failed. If a node has failed in this way, <c>epmd</c>
+ prevents you from
+ registering a new node with the old name, as it thinks that the old
name is still in use. In this case, you must unregister the name
explicitly:</p>
+
<code type="none"><![CDATA[
erl_unpublish(node); ]]></code>
- <p>This will cause <c><![CDATA[epmd]]></c> to close the connection from the far end. Note
+
+ <p>This causes <c>epmd</c> to close the connection from the
+ far end. Notice
that if the name was in fact still in use by a node, the results of
this operation are unpredictable. Also, doing this does not cause the
- local end of the connection to close, so resources may be consumed.</p>
+ local end of the connection to close, so resources can be consumed.</p>
</section>
<section>
<title>Sending and Receiving Erlang Messages</title>
<p>Use one of the following two functions to send messages:</p>
+
<list type="bulleted">
- <item><c><![CDATA[erl_send()]]></c></item>
- <item><c><![CDATA[erl_reg_send()]]></c></item>
+ <item><seealso marker="erl_connect#erl_send">
+ <c>erl_connect:erl_send</c></seealso></item>
+ <item><seealso marker="erl_connect#erl_reg_send">
+ <c>erl_connect:erl_reg_send</c></seealso></item>
</list>
- <p>As in Erlang, it is possible to send messages to a
- <em>Pid</em> or to a registered name. It is easier to send a
- message to a registered name because it avoids the problem of finding
- a suitable <em>Pid</em>.</p>
+
+ <p>As in Erlang, messages can be sent to a
+ pid or to a registered name. It is easier to send a
+ message to a registered name, as it avoids the problem of finding
+ a suitable pid.</p>
+
<p>Use one of the following two functions to receive messages:</p>
+
<list type="bulleted">
- <item><c><![CDATA[erl_receive()]]></c></item>
- <item><c><![CDATA[erl_receive_msg()]]></c></item>
+ <item><seealso marker="erl_connect#erl_receive">
+ <c>erl_connect:erl_receive</c></seealso></item>
+ <item><seealso marker="erl_connect#erl_receive_msg">
+ <c>erl_connect:erl_receive_msg</c></seealso></item>
</list>
- <p><c><![CDATA[erl_receive()]]></c> receives the message into a buffer, while
- <c><![CDATA[erl_receive_msg()]]></c> decodes the message into an Erlang term. </p>
+
+ <p><c>erl_receive()</c> receives the message into a buffer,
+ while <c>erl_receive_msg()</c> decodes the message into an
+ Erlang term.</p>
<section>
<title>Example of Sending Messages</title>
- <p>In the following example, <c><![CDATA[{Pid, hello_world}]]></c> is
- sent to a registered process <c><![CDATA[my_server]]></c>. The message is encoded
- by <c><![CDATA[erl_send()]]></c>:</p>
+ <p>In the following example, <c>{Pid, hello_world}</c> is
+ sent to a registered process <c>my_server</c>. The message
+ is encoded by <c>erl_send()</c>:</p>
+
<code type="none"><![CDATA[
extern const char *erl_thisnodename(void);
extern short erl_thiscreation(void);
@@ -345,16 +465,19 @@ emsg = erl_mk_tuple(arr, 2);
erl_reg_send(sockfd, "my_server", emsg);
erl_free_term(emsg); ]]></code>
+
<p>The first element of the tuple that is sent is your own
- <em>Pid</em>. This enables <c><![CDATA[my_server]]></c> to reply. Refer to the
- Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information
- about send primitives.</p>
+ pid. This enables <c>my_server</c> to reply.
+ For more information about the primitives, see the
+ <seealso marker="erl_connect"><c>erl_connect</c></seealso> module.</p>
</section>
<section>
<title>Example of Receiving Messages</title>
- <p>In this example <c><![CDATA[{Pid, Something}]]></c> is received. The
- received Pid is then used to return <c><![CDATA[{goodbye,Pid}]]></c></p>
+ <p>In this example, <c>{Pid, Something}</c> is received. The
+ received pid is then used to return
+ <c>{goodbye,Pid}</c>.</p>
+
<code type="none"><![CDATA[
ETERM *arr[2], *answer;
int sockfd,rc;
@@ -370,22 +493,25 @@ if ((rc = erl_receive_msg(sockfd , buf, BUFSIZE, &emsg)) == ERL_MSG) {
erl_free_term(emsg.msg);
erl_free_term(emsg.to);
} ]]></code>
- <p>In order to provide robustness, a distributed Erlang node
- occasionally polls all its connected neighbours in an attempt to
- detect failed nodes or communication links. A node which receives such
- a message is expected to respond immediately with an <c><![CDATA[ERL_TICK]]></c> message.
- This is done automatically by <c><![CDATA[erl_receive()]]></c>, however when this
- has occurred <c><![CDATA[erl_receive]]></c> returns <c><![CDATA[ERL_TICK]]></c> to the caller
- without storing a message into the <c><![CDATA[ErlMessage]]></c> structure.</p>
+
+ <p>To provide robustness, a distributed Erlang node
+ occasionally polls all its connected neighbors in an attempt to
+ detect failed nodes or communication links. A node that receives such
+ a message is expected to respond immediately with an
+ <c>ERL_TICK</c> message. This is done automatically by
+ <c>erl_receive()</c>. However, when this has occurred,
+ <c>erl_receive</c> returns <c>ERL_TICK</c> to
+ the caller without storing a message into the
+ <c>ErlMessage</c> structure.</p>
+
<p>When a message has been received, it is the caller's responsibility
- to free the received message <c><![CDATA[emsg.msg]]></c> as well as <c><![CDATA[emsg.to]]></c>
- or <c><![CDATA[emsg.from]]></c>, depending on the type of message received.</p>
- <p>Refer to the Reference Manual for additional information about the
- following modules:</p>
- <list type="bulleted">
- <item><c><![CDATA[erl_connect]]></c></item>
- <item><c><![CDATA[erl_eterm]]></c>.</item>
- </list>
+ to free the received message <c>emsg.msg</c> and
+ <c>emsg.to</c> or <c>emsg.from</c>,
+ depending on the type of message received.</p>
+
+ <p>For more information, see the
+ <seealso marker="erl_connect"><c>erl_connect</c></seealso> and
+ <seealso marker="erl_eterm"><c>erl_eterm</c></seealso> modules.</p>
</section>
</section>
@@ -394,10 +520,12 @@ if ((rc = erl_receive_msg(sockfd , buf, BUFSIZE, &emsg)) == ERL_MSG) {
<p>An Erlang node acting as a client to another Erlang node
typically sends a request and waits for a reply. Such a request is
included in a function call at a remote node and is called a remote
- procedure call. The following example shows how the
- Erl_Interface library supports remote procedure calls:</p>
- <code type="none"><![CDATA[
+ procedure call.</p>
+ <p>The following example shows how the
+ <c>Erl_Interface</c> library supports remote procedure calls:</p>
+
+ <code type="none"><![CDATA[
char modname[]=THE_MODNAME;
ETERM *reply,*ep;
ep = erl_format("[~a,[]]", modname);
@@ -409,26 +537,34 @@ if (!erl_match(ep, reply))
erl_err_msg("<ERROR> compiler errors !\n");
erl_free_term(ep);
erl_free_term(reply); ]]></code>
- <p><c><![CDATA[c:c/1]]></c> is called to compile the specified module on the
- remote node. <c><![CDATA[erl_match()]]></c> checks that the compilation was
- successful by testing for the expected <c><![CDATA[ok]]></c>.</p>
- <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for
- more information about <c><![CDATA[erl_rpc()]]></c>, and its companions
- <c><![CDATA[erl_rpc_to()]]></c> and <c><![CDATA[erl_rpc_from()]]></c>.</p>
+
+ <p><c>c:c/1</c> is called to compile the specified module on
+ the remote node. <c>erl_match()</c> checks that the
+ compilation was
+ successful by testing for the expected <c>ok</c>.</p>
+
+ <p>For more information about <c>erl_rpc()</c> and its
+ companions <c>erl_rpc_to()</c> and
+ <c>erl_rpc_from()</c>, see the
+ <seealso marker="erl_connect"><c>erl_connect</c></seealso> module.</p>
</section>
<section>
<title>Using Global Names</title>
- <p>A C node has access to names registered through the Erlang Global
- module. Names can be looked up, allowing the C node to send messages
+ <p>A C node has access to names registered through the
+ <seealso marker="kernel:global"><c>global</c></seealso>
+ module in Kernel. Names can be looked up, allowing the C node to send messages
to named Erlang services. C nodes can also register global names,
allowing them to provide named services to Erlang processes or other C
- nodes. </p>
- <p>Erl_Interface does not provide a native implementation of the global
- service. Instead it uses the global services provided by a "nearby"
- Erlang node. In order to use the services described in this section,
+ nodes.</p>
+
+ <p><c>Erl_Interface</c> does not provide a native implementation of the
+ global service. Instead it uses the global services provided by a "nearby"
+ Erlang node. To use the services described in this section,
it is necessary to first open a connection to an Erlang node.</p>
+
<p>To see what names there are:</p>
+
<code type="none"><![CDATA[
char **names;
int count;
@@ -441,71 +577,102 @@ if (names)
printf("%s\n",names[i]);
free(names); ]]></code>
- <p><c><![CDATA[erl_global_names()]]></c> allocates and returns a buffer containing
- all the names known to global. <c><![CDATA[count]]></c> will be initialized to
- indicate how many names are in the array. The array of strings in
- names is terminated by a NULL pointer, so it is not necessary to use
- <c><![CDATA[count]]></c> to determine when the last name is reached.</p>
+
+ <p><seealso marker="erl_global#erl_global_names">
+ <c>erl_global:erl_global_names</c></seealso>
+ allocates and returns a buffer containing
+ all the names known to the <c>global</c> module in <c>Kernel</c>.
+ <c>count</c> is initialized to
+ indicate the number of names in the array. The array of strings in names
+ is terminated by a <c>NULL</c> pointer, so it is not necessary to use
+ <c>count</c> to determine when the last name is reached.</p>
+
<p>It is the caller's responsibility to free the array.
- <c><![CDATA[erl_global_names()]]></c> allocates the array and all of the strings
- using a single call to <c><![CDATA[malloc()]]></c>, so <c><![CDATA[free(names)]]></c> is all
- that is necessary.</p>
+ <c>erl_global_names</c> allocates the array and all the strings
+ using a single call to <c>malloc()</c>, so
+ <c>free(names)</c> is all that is necessary.</p>
+
<p>To look up one of the names:</p>
+
<code type="none"><![CDATA[
ETERM *pid;
char node[256];
pid = erl_global_whereis(fd,"schedule",node); ]]></code>
- <p>If <c><![CDATA["schedule"]]></c> is known to global, an Erlang pid is returned
- that can be used to send messages to the schedule service.
- Additionally, <c><![CDATA[node]]></c> will be initialized to contain the name of
+
+ <p>If <c>"schedule"</c> is known to the
+ <c>global</c> module in <c>Kernel</c>, an Erlang pid is
+ returned that can be used to send messages to the schedule service.
+ Also, <c>node</c> is initialized to contain the name of
the node where the service is registered, so that you can make a
- connection to it by simply passing the variable to <c><![CDATA[erl_connect()]]></c>.</p>
+ connection to it by simply passing the variable to
+ <seealso marker="erl_connect"><c>erl_connect</c></seealso>.</p>
+
<p>Before registering a name, you should already have registered your
- port number with <c><![CDATA[epmd]]></c>. This is not strictly necessary, but if you
+ port number with <c>epmd</c>. This is not strictly necessary,
+ but if you
neglect to do so, then other nodes wishing to communicate with your
- service will be unable to find or connect to your process.</p>
+ service cannot find or connect to your process.</p>
+
<p>Create a pid that Erlang processes can use to communicate with your
service:</p>
+
<code type="none"><![CDATA[
ETERM *pid;
pid = erl_mk_pid(thisnode,14,0,0);
erl_global_register(fd,servicename,pid); ]]></code>
- <p>After registering the name, you should use <c><![CDATA[erl_accept()]]></c> to wait for
- incoming connections.</p>
- <p>Do not forget to free <c><![CDATA[pid]]></c> later with <c><![CDATA[erl_free_term()]]></c>!</p>
+
+ <p>After registering the name, use
+ <seealso marker="erl_connect#erl_accept">
+ <c>erl_connect:erl_accept</c></seealso>
+ to wait for incoming connections.</p>
+
+ <note>
+ <p>Remember to free <c>pid</c> later with
+ <seealso marker="erl_malloc#erl_free_term">
+ <c>erl_malloc:erl_free_term</c></seealso>.</p>
+ </note>
+
<p>To unregister a name:</p>
+
<code type="none"><![CDATA[
erl_global_unregister(fd,servicename); ]]></code>
</section>
<section>
- <title>The Registry</title>
+ <title>Using the Registry</title>
<p>This section describes the use of the registry, a simple mechanism
for storing key-value pairs in a C-node, as well as backing them up or
- restoring them from a Mnesia table on an Erlang node. More detailed
- information about the individual API functions can be found in the
- Reference Manual.</p>
- <p>Keys are strings, i.e. 0-terminated arrays of characters, and values
- are arbitrary objects. Although integers and floating point numbers
+ restoring them from an <c>Mnesia</c> table on an Erlang node. For more
+ detailed information about the individual API functions, see the
+ <seealso marker="registry"><c>registry</c></seealso> module.</p>
+
+ <p>Keys are strings, that is, <c>NULL</c>-terminated arrays of characters, and
+ values are arbitrary objects. Although integers and floating point numbers
are treated specially by the registry, you can store strings or binary
objects of any type as pointers.</p>
- <p>To start, you need to open a registry:</p>
+
+ <p>To start, open a registry:</p>
+
<code type="none"><![CDATA[
ei_reg *reg;
reg = ei_reg_open(45); ]]></code>
- <p>The number 45 in the example indicates the approximate number of
+
+ <p>The number <c>45</c> in the example indicates the approximate number of
objects that you expect to store in the registry. Internally the
registry uses hash tables with collision chaining, so there is no
absolute upper limit on the number of objects that the registry can
- contain, but if performance or memory usage are important, then you
- should choose a number accordingly. The registry can be resized later.</p>
+ contain, but if performance or memory usage is important, then you
+ are to choose a number accordingly. The registry can be resized later.</p>
+
<p>You can open as many registries as you like (if memory permits).</p>
- <p>Objects are stored and retrieved through set and get functions. In
- the following examples you see how to store integers, floats, strings
+
+ <p>Objects are stored and retrieved through set and get functions.
+ The following example shows how to store integers, floats, strings,
and arbitrary binary objects:</p>
+
<code type="none"><![CDATA[
struct bonk *b = malloc(sizeof(*b));
char *name = malloc(7);
@@ -519,13 +686,16 @@ ei_reg_setsval(reg,"name",name);
b->l = 42;
b->m = 12;
ei_reg_setpval(reg,"jox",b,sizeof(*b)); ]]></code>
- <p>If you attempt to store an object in the registry and there is an
- existing object with the same key, the new value will replace the old
+
+ <p>If you try to store an object in the registry and there is an
+ existing object with the same key, the new value replaces the old
one. This is done regardless of whether the new object and the old one
have the same type, so you can, for example, replace a string with an
- integer. If the existing value is a string or binary, it will be freed
+ integer. If the existing value is a string or binary, it is freed
before the new value is assigned.</p>
+
<p>Stored values are retrieved from the registry as follows:</p>
+
<code type="none"><![CDATA[
long i;
double f;
@@ -537,77 +707,100 @@ i = ei_reg_getival(reg,"age");
f = ei_reg_getfval(reg,"height");
s = ei_reg_getsval(reg,"name");
b = ei_reg_getpval(reg,"jox",&size); ]]></code>
- <p>In all of the above examples, the object must exist and it must be of
+
+ <p>In all the above examples, the object must exist and it must be of
the right type for the specified operation. If you do not know the
- type of a given object, you can ask:</p>
+ type of an object, you can ask:</p>
+
<code type="none"><![CDATA[
struct ei_reg_stat buf;
ei_reg_stat(reg,"name",&buf); ]]></code>
- <p>Buf will be initialized to contain object attributes.</p>
+
+ <p>Buf is initialized to contain object attributes.</p>
+
<p>Objects can be removed from the registry:</p>
+
<code type="none"><![CDATA[
ei_reg_delete(reg,"name"); ]]></code>
+
<p>When you are finished with a registry, close it to remove all the
objects and free the memory back to the system:</p>
+
<code type="none"><![CDATA[
ei_reg_close(reg); ]]></code>
<section>
<title>Backing Up the Registry to Mnesia</title>
- <p>The contents of a registry can be backed up to Mnesia on a "nearby"
- Erlang node. You need to provide an open connection to the Erlang node
- (see <c><![CDATA[erl_connect()]]></c>). Also, Mnesia 3.0 or later must be running
+ <p>The contents of a registry can be backed up to
+ <seealso marker="mnesia:mnesia"><c>Mnesia</c></seealso> on a "nearby" Erlang
+ node. You must provide an open connection to the Erlang node
+ (see <seealso marker="erl_connect"><c>erl_connect</c></seealso>).
+ Also, <c>Mnesia</c> 3.0 or later must be running
on the Erlang node before the backup is initiated:</p>
+
<code type="none"><![CDATA[
ei_reg_dump(fd, reg, "mtab", dumpflags); ]]></code>
- <p>The example above will backup the contents of the registry to the
- specified Mnesia table <c><![CDATA["mtab"]]></c>. Once a registry has been backed
- up to Mnesia in this manner, additional backups will only affect
- objects that have been modified since the most recent backup, i.e.
- objects that have been created, changed or deleted. The backup
- operation is done as a single atomic transaction, so that the entire
- backup will be performed or none of it will.</p>
- <p>In the same manner, a registry can be restored from a Mnesia table:</p>
+
+ <p>This example back up the contents of the registry to the
+ specified <c>Mnesia</c> table <c>"mtab"</c>.
+ Once a registry has been backed
+ up to <c>Mnesia</c> like this, more backups only affect
+ objects that have been modified since the most recent backup, that is,
+ objects that have been created, changed, or deleted. The backup
+ operation is done as a single atomic transaction, so that either the
+ entire backup is performed or none of it.</p>
+
+ <p>Likewise, a registry can be restored from a <c>Mnesia</c> table:</p>
+
<code type="none"><![CDATA[
ei_reg_restore(fd, reg, "mtab"); ]]></code>
- <p>This will read the entire contents of <c><![CDATA["mtab"]]></c> into the specified
- registry. After the restore, all of the objects in the registry will
- be marked as unmodified, so a subsequent backup will only affect
+
+ <p>This reads the entire contents of <c>"mtab"</c> into the
+ specified registry. After the restore, all the objects in the registry
+ are marked as unmodified, so a later backup only affects
objects that you have modified since the restore.</p>
- <p>Note that if you restore to a non-empty registry, objects in the
- table will overwrite objects in the registry with the same keys. Also,
+
+ <p>Notice that if you restore to a non-empty registry, objects in the
+ table overwrite objects in the registry with the same keys. Also,
the <em>entire</em> contents of the registry is marked as unmodified
after the restore, including any modified objects that were not
- overwritten by the restore operation. This may not be your intention.</p>
+ overwritten by the restore operation. This may not be your
+ intention.</p>
</section>
<section>
<title>Storing Strings and Binaries</title>
<p>When string or binary objects are stored in the registry it is
- important that a number of simple guidelines are followed. </p>
+ important that some simple guidelines are followed.</p>
+
<p>Most importantly, the object must have been created with a single call
- to <c><![CDATA[malloc()]]></c> (or similar), so that it can later be removed by a
- single call to <c><![CDATA[free()]]></c>. Objects will be freed by the registry
+ to <c>malloc()</c> (or similar), so that it can later be
+ removed by a single call to <c>free()</c>.
+ Objects are freed by the registry
when it is closed, or when you assign a new value to an object that
previously contained a string or binary.</p>
- <p>You should also be aware that if you store binary objects that are
- context-dependent (e.g. containing pointers or open file descriptors),
- they will lose their meaning if they are backed up to a Mnesia table
- and subsequently restored in a different context.</p>
+
+ <p>Notice that if you store binary objects that are context-dependent
+ (for example, containing pointers or open file descriptors),
+ they lose their meaning if they are backed up to a <c>Mnesia</c> table
+ and later restored in a different context.</p>
+
<p>When you retrieve a stored string or binary value from the registry,
the registry maintains a pointer to the object and you are passed a
copy of that pointer. You should never free an object retrieved in
this manner because when the registry later attempts to free it, a
- runtime error will occur that will likely cause the C-node to crash.</p>
+ runtime error occurs that likely causes the C-node to crash.</p>
+
<p>You are free to modify the contents of an object retrieved this way.
- However when you do so, the registry will not be aware of the changes
- you make, possibly causing it to be missed the next time you make a
- Mnesia backup of the registry contents. This can be avoided if you
- mark the object as dirty after any such changes with
- <c><![CDATA[ei_reg_markdirty()]]></c>, or pass appropriate flags to
- <c><![CDATA[ei_reg_dump()]]></c>.</p>
+ However, when you do so, the registry is not aware of your changes,
+ possibly causing it to be missed the next time you make an
+ <c>Mnesia</c> backup of the registry contents. This can be avoided if
+ you mark the object as dirty after any such changes with
+ <seealso marker="registry#ei_reg_markdirty">
+ <c>registry:ei_reg_markdirty</c></seealso>, or pass appropriate flags to
+ <seealso marker="registry#ei_reg_dump">
+ <c>registry:ei_reg_dump</c></seealso>.</p>
</section>
</section>
</chapter>
-
diff --git a/lib/erl_interface/doc/src/erl_call.xml b/lib/erl_interface/doc/src/erl_call.xml
index 46015621ac..73b9b13e4d 100644
--- a/lib/erl_interface/doc/src/erl_call.xml
+++ b/lib/erl_interface/doc/src/erl_call.xml
@@ -4,14 +4,14 @@
<comref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -28,135 +28,146 @@
<docno></docno>
<approved>Bjarne D&auml;cker</approved>
<checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
- <date>97-05-16</date>
+ <date>1997-05-16</date>
<rev>B</rev>
- <file>erl_call.sgml</file>
+ <file>erl_call.xml</file>
</header>
<com>erl_call</com>
- <comsummary>Call/Start a Distributed Erlang Node</comsummary>
+ <comsummary>Call/start a distributed Erlang node.</comsummary>
<description>
- <p><c><![CDATA[erl_call]]></c> makes it possible to start and/or communicate with
- a distributed Erlang node. It is built upon the <c><![CDATA[erl_interface]]></c>
- library as an example application. Its purpose is to use an Unix shell script to interact with a distributed Erlang node. It performs all
- communication with the Erlang <em>rex server</em>, using the standard Erlang RPC facility. It does not require any special
- software to be run at the Erlang target node.</p>
+ <p><c>erl_call</c> makes it possible to start and/or
+ communicate with a distributed Erlang node. It is built upon the
+ <c>Erl_Interface</c> library as an example application.
+ Its purpose is to use a Unix shell script to interact with a distributed
+ Erlang node. It performs all communication with the Erlang
+ <em>rex server</em>, using the standard Erlang RPC facility. It does not
+ require any special software to be run at the Erlang target node.</p>
+
<p>The main use is to either start a distributed Erlang node
or to make an ordinary function call. However, it is also
- possible to pipe an Erlang module to <c><![CDATA[erl_call]]></c> and have it
- compiled, or to pipe a sequence of Erlang expressions to be evaluated
+ possible to pipe an Erlang module to <c>erl_call</c> and have
+ it compiled, or to pipe a sequence of Erlang expressions to be evaluated
(similar to the Erlang shell).</p>
- <p>Options, which cause <c><![CDATA[stdin]]></c> to be read, can be used with
- advantage
- as scripts from within (Unix) shell scripts. Another
- nice use of <c><![CDATA[erl_call]]></c> could be from (http) CGI-bin scripts.</p>
+
+ <p>Options, which cause <c>stdin</c> to be read, can be used
+ with advantage,
+ as scripts from within (Unix) shell scripts. Another nice use
+ of <c>erl_call</c> could be from (HTTP) CGI-bin scripts.</p>
</description>
+
<funcs>
<func>
<name>erl_call &lt;options></name>
- <fsummary>Start/Call Erlang</fsummary>
+ <fsummary>Start/call Erlang.</fsummary>
<desc>
- <p>Each option flag is described below with its name, type and
- meaning. </p>
+ <p>Starts/calls Erlang.</p>
+ <p>Each option flag is described below with its name, type, and
+ meaning.</p>
<taglist>
- <tag>-a [Mod [Fun [Args]]]]</tag>
+ <tag><c>-a [Mod [Fun [Args]]]]</c></tag>
<item>
- <p>(<em>optional</em>): Applies the specified function
- and returns the result. <c><![CDATA[Mod]]></c> must be specified, however
- <c>start</c> and <c>[]</c> are assumed for unspecified <c><![CDATA[Fun]]></c> and <c><![CDATA[Args]]></c>, respectively. <c><![CDATA[Args]]></c> should
- be in the same format as for <c><![CDATA[erlang:apply/3]]></c>. Note
- that this flag takes exactly one argument, so quoting
- may be necessary in order to group <c><![CDATA[Mod]]></c>, <c><![CDATA[Fun]]></c>
- and <c><![CDATA[Args]]></c>, in a manner dependent on the behavior
- of your command shell.</p>
- <p></p>
+ <p>(<em>Optional.</em>) Applies the specified function
+ and returns the result. <c>Mod</c> must be specified.
+ However, <c>start</c> and <c>[]</c> are assumed for unspecified
+ <c>Fun</c> and <c>Args</c>, respectively.
+ <c>Args</c> is to be in the same format as for
+ <seealso marker="erts:erlang#apply/3">
+ <c>erlang:apply/3</c></seealso> in <c>ERTS</c>.</p>
+ <p>Notice that this flag takes exactly one argument, so quoting
+ can be necessary to group <c>Mod</c>,
+ <c>Fun</c>, and <c>Args</c> in a manner
+ dependent on the behavior of your command shell.</p>
</item>
- <tag>-c Cookie</tag>
+ <tag><c>-c Cookie</c></tag>
<item>
- <p>(<em>optional</em>): Use this option to specify a certain cookie. If no cookie is specified, the <c><![CDATA[~/.erlang.cookie]]></c> file is read and its content are used as cookie. The Erlang node we want to communicate with must have the same cookie.</p>
+ <p>(<em>Optional.</em>) Use this option to specify a certain cookie.
+ If no cookie is specified, the <c>~/.erlang.cookie</c>
+ file is read and its content is used as cookie. The Erlang node
+ we want to communicate with must have the same cookie.</p>
</item>
- <tag>-d</tag>
+ <tag><c>-d</c></tag>
<item>
- <p>(<em>optional</em>): Debug mode. This causes all IO to be output
- to the file <c><![CDATA[~/.erl_call.out.Nodename]]></c>, where <c><![CDATA[Nodename]]></c>
+ <p>(<em>Optional.</em>) Debug mode. This causes all I/O to be output
+ to the <c>~/.erl_call.out.Nodename</c> file, where
+ <c>Nodename</c>
is the node name of the Erlang node in question.</p>
- <p></p>
</item>
- <tag>-e</tag>
+ <tag><c>-e</c></tag>
<item>
- <p>(<em>optional</em>): Reads a sequence of Erlang expressions, separated
- by '<em>,</em>' and ended with a '<em>.</em>', from <c><![CDATA[stdin]]></c> until
- EOF (Control-D). Evaluates the expressions and returns the result from
- the last expression. Returns <c><![CDATA[{ok,Result}]]></c> if successful.</p>
- <p></p>
+ <p>(<em>Optional.</em>) Reads a sequence of Erlang expressions,
+ separated by comma (,) and ended with a full stop (.), from
+ <c>stdin</c> until EOF (Control-D). Evaluates the
+ expressions and returns the result from the last expression.
+ Returns <c>{ok,Result}</c> on success.</p>
</item>
- <tag>-h HiddenName</tag>
+ <tag><c>-h HiddenName</c></tag>
<item>
- <p>(<em>optional</em>): Specifies the name of the hidden node
- that <c><![CDATA[erl_call]]></c> represents.</p>
- <p></p>
+ <p>(<em>Optional.</em>) Specifies the name of the hidden node
+ that <c>erl_call</c> represents.</p>
</item>
- <tag>-m</tag>
+ <tag><c>-m</c></tag>
<item>
- <p>(<em>optional</em>): Reads an Erlang module from <c><![CDATA[stdin]]></c> and
- compiles it.</p>
- <p></p>
+ <p>(<em>Optional.</em>) Reads an Erlang module from
+ <c>stdin</c> and compiles it.</p>
</item>
- <tag>-n Node</tag>
+ <tag><c>-n Node</c></tag>
<item>
- <p>(one of <c><![CDATA[-n, -name, -sname]]></c> is required):
- Has the same meaning as <c><![CDATA[-name]]></c> and can still be used for
- backwards compatibility reasons.</p>
- <p></p>
+ <p>(One of <c>-n, -name, -sname</c> is required.)
+ Has the same meaning as <c>-name</c> and can still be
+ used for backward compatibility reasons.</p>
</item>
- <tag>-name Node</tag>
+ <tag><c>-name Node</c></tag>
<item>
- <p>(one of <c><![CDATA[-n, -name, -sname]]></c> is required): <c><![CDATA[Node]]></c> is the name of the node to be
- started or communicated with. It is assumed that
- <c><![CDATA[Node]]></c> is started with <c><![CDATA[erl -name]]></c>, which means that fully
- qualified long node names are used.
- If the <c><![CDATA[-s]]></c> option is given, an Erlang node will (if necessary)
- be started with <c><![CDATA[erl -name]]></c>.</p>
- <p></p>
+ <p>(One of <c>-n, -name, -sname</c> is required.)
+ <c>Node</c> is the name of the node to be
+ started or communicated with. It is assumed that
+ <c>Node</c> is started with
+ <c>erl -name</c>, which means that fully
+ qualified long node names are used. If option
+ <c>-s</c> is specified, an Erlang node will (if
+ necessary) be started with <c>erl -name</c>.</p>
</item>
- <tag>-q</tag>
+ <tag><c>-q</c></tag>
<item>
- <p>(<em>optional</em>): Halts the Erlang node specified
- with the -n switch. This switch overrides the -s switch.</p>
- <p></p>
+ <p>(<em>Optional.</em>) Halts the Erlang node specified
+ with switch <c>-n</c>. This switch overrides switch <c>-s</c>.</p>
</item>
- <tag>-r</tag>
+ <tag><c>-r</c></tag>
<item>
- <p>(<em>optional</em>): Generates a random name of the hidden node
- that <c><![CDATA[erl_call]]></c> represents.</p>
- <p></p>
+ <p>(<em>Optional.</em>) Generates a random name of the hidden node
+ that <c>erl_call</c> represents.</p>
</item>
- <tag>-s</tag>
+ <tag><c>-s</c></tag>
<item>
- <p>(<em>optional</em>): Starts a distributed Erlang node if necessary.
- This means that in a sequence of calls, where the '<c><![CDATA[-s]]></c>'
- and '<c><![CDATA[-n Node]]></c>' are constant, only the first call will start
- the Erlang node. This makes the rest of the communication
- very fast. This flag is currently only available on the Unix platform.</p>
- <p></p>
+ <p>(<em>Optional.</em>) Starts a distributed Erlang node if
+ necessary. This means that in a sequence of calls, where
+ '<c>-s</c>' and '<c>-n Node</c>' are
+ constant, only the first call starts the Erlang node. This makes
+ the rest of the communication very fast. This flag is currently
+ only available on Unix-like platforms (Linux, Mac OS X, Solaris,
+ and so on).</p>
</item>
- <tag>-sname Node</tag>
+ <tag><c>-sname Node</c></tag>
<item>
- <p>(one of <c><![CDATA[-n, -name, -sname]]></c> is required): <c><![CDATA[Node]]></c> is the name of the node to
- be started or communicated with. It is assumed that <c><![CDATA[Node]]></c> is started with <c><![CDATA[erl -sname]]></c> which means that short node names are used.
- If <c><![CDATA[-s]]></c> option is given, an Erlang node will be started (if necessary) with <c><![CDATA[erl -sname]]></c>.</p>
- <p></p>
+ <p>(One of <c>-n, -name, -sname</c> is required.)
+ <c>Node</c> is the name of the node to be started
+ or communicated with. It is assumed that <c>Node</c>
+ is started with <c>erl -sname</c>, which means that
+ short node names are used. If option <c>-s</c> is
+ specified, an Erlang node is started (if necessary) with
+ <c>erl -sname</c>.</p>
</item>
- <tag>-v</tag>
+ <tag><c>-v</c></tag>
<item>
- <p>(<em>optional</em>): Prints a lot of <c><![CDATA[verbose]]></c> information.
- This is only useful for the developer and maintainer of <c><![CDATA[erl_call]]></c>.</p>
- <p></p>
+ <p>(<em>Optional.</em>) Prints a lot of <c>verbose</c>
+ information. This is only useful for the developer and maintainer
+ of <c>erl_call</c>.</p>
</item>
- <tag>-x ErlScript</tag>
+ <tag><c>-x ErlScript</c></tag>
<item>
- <p>(<em>optional</em>): Specifies another name of the Erlang start-up script
- to be used. If not specified, the standard <c><![CDATA[erl]]></c> start-up script
- is used.</p>
+ <p>(<em>Optional.</em>) Specifies another name of the Erlang
+ startup script to be used. If not specified, the standard
+ <c>erl</c> startup script is used.</p>
</item>
</taglist>
</desc>
@@ -165,20 +176,29 @@
<section>
<title>Examples</title>
- <p>Starts an Erlang node and calls <c><![CDATA[erlang:time/0]]></c>.</p>
+ <p>To start an Erlang node and call <c>erlang:time/0</c>:</p>
+
<code type="none"><![CDATA[
erl_call -s -a 'erlang time' -n madonna
{18,27,34}
]]></code>
- <p>Terminates an Erlang node by calling <c><![CDATA[erlang:halt/0]]></c>.</p>
+
+ <p>To terminate an Erlang node by calling
+ <c>erlang:halt/0</c>:</p>
+
<code type="none"><![CDATA[
erl_call -s -a 'erlang halt' -n madonna
]]></code>
- <p>An apply with several arguments.</p>
+
+ <p>To apply with many arguments:</p>
+
<code type="none"><![CDATA[
-erl_call -s -a 'lists map [{math,sqrt},[1,4,9,16,25]]' -n madonna
+erl_call -s -a 'lists seq [1,10]' -n madonna
]]></code>
- <p>Evaluates a couple of expressions. <em>The input ends with EOF (Control-D)</em>.</p>
+
+ <p>To evaluate some expressions
+ (<em>the input ends with EOF (Control-D)</em>):</p>
+
<code type="none"><![CDATA[
erl_call -s -e -n madonna
statistics(runtime),
@@ -189,10 +209,14 @@ Y=2,
^D
{ok,{3,0}}
]]></code>
- <p>Compiles a module and runs it. <em>Again, the input ends with EOF (Control-D)</em>. (In the example shown, the output has been formatted afterwards).</p>
+
+ <p>To compile a module and run it (<em>again, the input ends with EOF
+ (Control-D)</em>):</p>
+ <p>(In the example, the output has been formatted afterwards.)</p>
+
<code type="none"><![CDATA[
-erl_call -s -m -a lolita -n madonna
--module(lolita).
+erl_call -s -m -a procnames -n madonna
+-module(procnames).
-compile(export_all).
start() ->
P = processes(),
@@ -238,4 +262,3 @@ start() ->
]]></code>
</section>
</comref>
-
diff --git a/lib/erl_interface/doc/src/erl_connect.xml b/lib/erl_interface/doc/src/erl_connect.xml
index 0fad98cd17..76ef6588c2 100644
--- a/lib/erl_interface/doc/src/erl_connect.xml
+++ b/lib/erl_interface/doc/src/erl_connect.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>erl_connect</title>
@@ -28,127 +28,110 @@
<docno></docno>
<approved>Bjarne D&auml;cker</approved>
<checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
- <date>980703</date>
+ <date>1998-07-03</date>
<rev>A</rev>
- <file>erl_connect.sgml</file>
+ <file>erl_connect.xml</file>
</header>
<lib>erl_connect</lib>
- <libsummary>Communicate with Distributed Erlang</libsummary>
+ <libsummary>Communicate with distributed Erlang.</libsummary>
<description>
<p>This module provides support for communication between distributed
- Erlang nodes and C nodes, in a manner that is transparent to Erlang
+ Erlang nodes and C-nodes, in a manner that is transparent to Erlang
processes.</p>
- <p>A C node appears to Erlang as a
- <em>hidden node</em>.
+
+ <p>A C-node appears to Erlang as a <em>hidden node</em>.
That is, Erlang processes that know the name of the
- C node are able to communicate with it in a normal manner, but
- the node name will not appear in the listing provided by the
- Erlang function <c><![CDATA[nodes/0]]></c>.</p>
+ C-node can communicate with it in a normal manner, but
+ the node name does not appear in the listing provided by
+ <seealso marker="erts:erlang#nodes/0"><c>erlang:nodes/0</c></seealso>
+ in <c>ERTS</c>.</p>
</description>
+
<funcs>
<func>
- <name><ret>int</ret><nametext>erl_connect_init(number, cookie, creation)</nametext></name>
- <name><ret>int</ret><nametext>erl_connect_xinit(host, alive, node, addr, cookie, creation)</nametext></name>
- <fsummary>Initialize communication</fsummary>
+ <name><ret>int</ret><nametext>erl_accept(listensock, conp)</nametext></name>
+ <fsummary>Accept a connection.</fsummary>
<type>
- <v>int number;</v>
- <v>char *cookie;</v>
- <v>short creation;</v>
- <v>char *host,*alive,*node;</v>
- <v>struct in_addr *addr;</v>
+ <v>int listensock;</v>
+ <v>ErlConnect *conp;</v>
</type>
<desc>
- <p>These functions initialize the <c><![CDATA[erl_connect]]></c>
- module. In particular, they are used to identify the name of the
- C-node from which they are called. One of these functions must
- be called before any of the other functions in the erl_connect
- module are used.</p>
- <p><c><![CDATA[erl_connect_xinit()]]></c> stores for later use information about
- the node's host name <c><![CDATA[host]]></c>, alive name <c><![CDATA[alive]]></c>, node
- name <c><![CDATA[node]]></c>, IP address <c><![CDATA[addr]]></c>, cookie <c><![CDATA[cookie]]></c>,
- and creation number <c><![CDATA[creation]]></c>. <c><![CDATA[erl_connect_init()]]></c>
- provides an alternative interface which does not require as much
- information from the caller. Instead, <c><![CDATA[erl_connect_init()]]></c>
- uses <c><![CDATA[gethostbyname()]]></c> to obtain default values.
- </p>
- <p>If you use <c><![CDATA[erl_connect_init()]]></c> your node will have a
- short name, i.e., it will not be fully qualified. If you need to
- use fully qualified (a.k.a. long) names, use
- <c><![CDATA[erl_connect_xinit()]]></c> instead.
- </p>
- <p><c><![CDATA[host]]></c> is the name of the host on which the node is running.</p>
- <p><c><![CDATA[alive]]></c> is the alivename of the node.</p>
- <p><c><![CDATA[node]]></c> is the name of the node. The nodename should
- be of the form <em>alivename@hostname</em>.</p>
- <p><c><![CDATA[addr]]></c> is the 32-bit IP address of <c><![CDATA[host]]></c>.</p>
- <p><c><![CDATA[cookie]]></c> is the authorization string required for access
- to the remote node. If NULL the user HOME directory is
- searched for a cookie file <c><![CDATA[.erlang.cookie]]></c>. The path to
- the home directory is retrieved from the environment variable
- <c><![CDATA[HOME]]></c> on Unix and from the <c><![CDATA[HOMEDRIVE]]></c> and
- <c><![CDATA[HOMEPATH]]></c> variables on Windows. Refer to the <c><![CDATA[auth]]></c>
- module for more details.</p>
- <p><c><![CDATA[creation]]></c> helps identify a particular instance of a C
- node. In particular, it can help prevent us from receiving
- messages sent to an earlier process with the same registered
- name.</p>
- <p>A C node acting as a server will be assigned a creation number
- when it calls <c><![CDATA[erl_publish()]]></c>.</p>
- <p><c><![CDATA[number]]></c> is used by <c><![CDATA[erl_connect_init()]]></c> to
- construct the actual node name. In the second example shown
- below, <em>"[email protected]"</em> will be the resulting node
- name.</p>
- <p>Example 1:</p>
- <code type="none"><![CDATA[
-struct in_addr addr;
-addr = inet_addr("150.236.14.75");
-if (!erl_connect_xinit("chivas",
- "madonna",
- &addr;
- "samplecookiestring..."),
- 0)
- erl_err_quit("<ERROR> when initializing !");
- ]]></code>
- <p>Example 2:</p>
+ <p>This function is used by a server process to accept a
+ connection from a client process.</p>
+ <list type="bulleted">
+ <item><c>listensock</c> is an open socket descriptor on
+ which <c>listen()</c> has previously been called.</item>
+ <item><c>conp</c> is a pointer to an
+ <c>ErlConnect</c> struct, described as follows:</item>
+ </list>
<code type="none"><![CDATA[
-if (!erl_connect_init(17, "samplecookiestring...", 0))
- erl_err_quit("<ERROR> when initializing !");
+typedef struct {
+ char ipadr[4];
+ char nodename[MAXNODELEN];
+} ErlConnect;
]]></code>
+ <p>On success, <c>conp</c> is filled in with the address and
+ node name of the connecting client and a file descriptor is
+ returned. On failure, <c>ERL_ERROR</c> is returned and
+ <c>erl_errno</c> is set to <c>EIO</c>.</p>
</desc>
</func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_close_connection(fd)</nametext></name>
+ <fsummary>Close a connection to an Erlang node.</fsummary>
+ <type>
+ <v>int fd;</v>
+ </type>
+ <desc>
+ <p>Closes an open connection to an Erlang node.</p>
+ <p><c>Fd</c> is a file descriptor obtained from
+ <c>erl_connect()</c> or
+ <c>erl_xconnect()</c>.</p>
+ <p>Returns <c>0</c> on success. If the call fails, a non-zero value
+ is returned, and the reason for the error can be obtained with the
+ appropriate platform-dependent call.</p>
+ </desc>
+ </func>
+
<func>
<name><ret>int</ret><nametext>erl_connect(node)</nametext></name>
<name><ret>int</ret><nametext>erl_xconnect(addr, alive)</nametext></name>
- <fsummary>Establishe a connection to an Erlang node</fsummary>
+ <fsummary>Establish a connection to an Erlang node.</fsummary>
<type>
<v>char *node, *alive;</v>
<v>struct in_addr *addr;</v>
</type>
<desc>
- <p>These functions set up a connection to an Erlang node.</p>
- <p><c><![CDATA[erl_xconnect()]]></c> requires the IP address of the remote
- host and the alive name of the remote node
- to be specified. <c><![CDATA[erl_connect()]]></c> provides an alternative
+ <p>Sets up a connection to an Erlang node.</p>
+ <p><c>erl_xconnect()</c> requires the IP address of the
+ remote host and the alivename of the remote node to be
+ specified. <c>erl_connect()</c> provides an alternative
interface, and determines the information from the node name
provided.</p>
- <p><c><![CDATA[addr]]></c> is the 32-bit IP address of the remote host.</p>
- <p><c><![CDATA[alive]]></c> is the alivename of the remote node.</p>
- <p><c><![CDATA[node]]></c> is the name of the remote node.</p>
- <p>These functions return an open file descriptor on success, or
- a negative value indicating that an error occurred --- in
- which case they will set <c><![CDATA[erl_errno]]></c> to one of:</p>
+ <list type="bulleted">
+ <item><c>addr</c> is the 32-bit IP address of the remote
+ host.</item>
+ <item><c>alive</c> is the alivename of the remote node.
+ </item>
+ <item><c>node</c> is the name of the remote node.</item>
+ </list>
+ <p>Returns an open file descriptor on success, otherwise a negative
+ value. In the latter case <c>erl_errno</c> is set to one
+ of:</p>
<taglist>
- <tag><c><![CDATA[EHOSTUNREACH]]></c></tag>
- <item>The remote host <c><![CDATA[node]]></c> is unreachable</item>
- <tag><c><![CDATA[ENOMEM]]></c></tag>
- <item>No more memory available.</item>
- <tag><c><![CDATA[EIO]]></c></tag>
+ <tag><c>EHOSTUNREACH</c></tag>
+ <item>The remote host <c>node</c> is unreachable.</item>
+ <tag><c>ENOMEM</c></tag>
+ <item>No more memory is available.</item>
+ <tag><c>EIO</c></tag>
<item>I/O error.</item>
</taglist>
- <p>Additionally, <c><![CDATA[errno]]></c> values from
- <c><![CDATA[socket]]></c><em>(2)</em> and <c><![CDATA[connect]]></c><em>(2)</em>
- system calls may be propagated into <c><![CDATA[erl_errno]]></c>.</p>
+ <p>Also, <c>errno</c> values from
+ <c>socket</c><em>(2)</em> and
+ <c>connect</c><em>(2)</em>
+ system calls can be propagated into <c>erl_errno</c>.</p>
+ <p><em>Example:</em></p>
<code type="none"><![CDATA[
#define NODE "[email protected]"
#define ALIVE "madonna"
@@ -164,59 +147,177 @@ erl_xconnect( &addr , ALIVE );
]]></code>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>erl_close_connection(fd)</nametext></name>
- <fsummary>Close a connection to an Erlang node</fsummary>
+ <name><ret>int</ret><nametext>erl_connect_init(number, cookie, creation)</nametext></name>
+ <name><ret>int</ret><nametext>erl_connect_xinit(host, alive, node, addr, cookie, creation)</nametext></name>
+ <fsummary>Initialize communication.</fsummary>
<type>
- <v>int fd;</v>
+ <v>int number;</v>
+ <v>char *cookie;</v>
+ <v>short creation;</v>
+ <v>char *host,*alive,*node;</v>
+ <v>struct in_addr *addr;</v>
+ </type>
+ <desc>
+ <p>Initializes the <c>erl_connect</c> module.
+ In particular, these functions are used to identify the name of the
+ C-node from which they are called. One of these functions must
+ be called before any of the other functions in the <c>erl_connect</c>
+ module are used.</p>
+ <p><c>erl_connect_xinit()</c> stores for later use
+ information about:</p>
+ <list type="bulleted">
+ <item>Hostname of the node, <c>host</c></item>
+ <item>Alivename, <c>alive</c></item>
+ <item>Node name, <c>node</c></item>
+ <item>IP address, <c>addr</c></item>
+ <item>Cookie, <c>cookie</c></item>
+ <item>Creation number, <c>creation</c></item>
+ </list>
+ <p><c>erl_connect_init()</c>
+ provides an alternative interface that does not require as much
+ information from the caller. Instead,
+ <c>erl_connect_init()</c>
+ uses <c>gethostbyname()</c> to obtain default values.</p>
+ <p>If you use <c>erl_connect_init()</c>, your node will
+ have a short name, that is, it will not be fully qualified. If you
+ need to use fully qualified (long) names, use
+ <c>erl_connect_xinit()</c> instead.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>host</c> is the name of the host on which the node
+ is running.</p>
+ </item>
+ <item>
+ <p><c>alive</c> is the alivename of the node.</p>
+ </item>
+ <item>
+ <p><c>node</c> is the node name. It is to
+ be of the form <em>alivename@hostname</em>.</p>
+ </item>
+ <item>
+ <p><c>addr</c> is the 32-bit IP address of
+ <c>host</c>.</p>
+ </item>
+ <item>
+ <p><c>cookie</c> is the authorization string required
+ for access to the remote node. If <c>NULL</c>, the user
+ <c>HOME</c> directory is searched for a cookie file
+ <c>.erlang.cookie</c>. The path to
+ the home directory is retrieved from environment variable
+ <c>HOME</c> on Unix and from the
+ <c>HOMEDRIVE</c> and
+ <c>HOMEPATH</c> variables on Windows. For more
+ details, see the <seealso marker="kernel:auth">
+ <c>auth</c></seealso> module in Kernel.</p>
+ </item>
+ <item>
+ <p><c>creation</c> helps identifying a particular
+ instance of a C-node. In particular, it can help prevent us from
+ receiving messages sent to an earlier process with the same
+ registered name.</p>
+ </item>
+ </list>
+ <p>A C-node acting as a server is assigned a creation number
+ when it calls <c>erl_publish()</c>.</p>
+ <p><c>number</c> is used by
+ <c>erl_connect_init()</c> to
+ construct the actual node name. In Example 2
+ below, <em>"[email protected]"</em> is the resulting node name.</p>
+ <p><em>Example 1:</em></p>
+ <code type="none"><![CDATA[
+struct in_addr addr;
+addr = inet_addr("150.236.14.75");
+if (!erl_connect_xinit("chivas",
+ "madonna",
+ &addr;
+ "samplecookiestring..."),
+ 0)
+ erl_err_quit("<ERROR> when initializing !");
+ ]]></code>
+ <p><em>Example 2:</em></p>
+ <code type="none"><![CDATA[
+if (!erl_connect_init(17, "samplecookiestring...", 0))
+ erl_err_quit("<ERROR> when initializing !");
+ ]]></code>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_publish(port)</nametext></name>
+ <fsummary>Publish a node name.</fsummary>
+ <type>
+ <v>int port;</v>
</type>
<desc>
- <p>This function closes an open connection to an Erlang node.</p>
- <p><c><![CDATA[Fd]]></c> is a file descriptor obtained from
- <c><![CDATA[erl_connect()]]></c> or <c><![CDATA[erl_xconnect()]]></c>.</p>
- <p>On success, 0 is returned. If the call fails, a non-zero value
- is returned, and the reason for
- the error can be obtained with the appropriate platform-dependent
- call.</p>
+ <p>This function is used by a server process to register
+ with the local name server EPMD, thereby allowing
+ other processes to send messages by using the registered name.
+ Before calling this function, the process should
+ have called <c>bind()</c> and <c>listen()</c>
+ on an open socket.</p>
+ <p><c>port</c> is the local name to register, and is to be
+ the same as the port number that was previously bound to the
+ socket.</p>
+ <p>To unregister with EPMD, simply close the returned descriptor.</p>
+ <p>On success, a descriptor connecting the calling process to EPMD is
+ returned. On failure, <c>-1</c> is returned and
+ <c>erl_errno</c> is set to:</p>
+ <taglist>
+ <tag><c>EIO</c></tag>
+ <item>I/O error.</item>
+ </taglist>
+ <p>Also, <c>errno</c> values from
+ <c>socket</c><em>(2)</em>
+ and <c>connect</c><em>(2)</em> system calls can be
+ propagated into <c>erl_errno</c>.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_receive(fd, bufp, bufsize)</nametext></name>
- <fsummary>Receive a message</fsummary>
+ <fsummary>Receive a message.</fsummary>
<type>
<v>int fd;</v>
<v>char *bufp;</v>
<v>int bufsize;</v>
</type>
<desc>
- <p>This function receives a message consisting of a sequence
+ <p>Receives a message consisting of a sequence
of bytes in the Erlang external format.</p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
- <p><c><![CDATA[bufp]]></c> is a buffer large enough to hold the expected
- message. </p>
- <p><c><![CDATA[bufsize]]></c> indicates the size of <c><![CDATA[bufp]]></c>.</p>
- <p>If a <em>tick</em> occurs, i.e., the Erlang node on the
+ <list type="bulleted">
+ <item><c>fd</c> is an open descriptor to an Erlang
+ connection.</item>
+ <item><c>bufp</c> is a buffer large enough to hold the
+ expected message.</item>
+ <item><c>bufsize</c> indicates the size of
+ <c>bufp</c>.</item>
+ </list>
+ <p>If a <em>tick</em> occurs, that is, the Erlang node on the
other end of the connection has polled this node to see if it
- is still alive, the function will return <c><![CDATA[ERL_TICK]]></c> and
- no message will be placed in the buffer. Also,
- <c><![CDATA[erl_errno]]></c> will be set to <c><![CDATA[EAGAIN]]></c>.</p>
+ is still alive, the function returns <c>ERL_TICK</c> and
+ no message is placed in the buffer. Also,
+ <c>erl_errno</c> is set to <c>EAGAIN</c>.</p>
<p>On success, the message is placed in the specified buffer
and the function returns the number of bytes actually read. On
- failure, the function returns a negative value and will set
- <c><![CDATA[erl_errno]]></c> to one of:</p>
+ failure, the function returns a negative value and sets
+ <c>erl_errno</c> to one of:</p>
<taglist>
- <tag><c><![CDATA[EAGAIN]]></c></tag>
+ <tag><c>EAGAIN</c></tag>
<item>Temporary error: Try again.</item>
- <tag><c><![CDATA[EMSGSIZE]]></c></tag>
- <item>Buffer too small.</item>
- <tag><c><![CDATA[EIO]]></c></tag>
+ <tag><c>EMSGSIZE</c></tag>
+ <item>Buffer is too small.</item>
+ <tag><c>EIO</c></tag>
<item>I/O error.</item>
</taglist>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_receive_msg(fd, bufp, bufsize, emsg)</nametext></name>
- <fsummary>Receive and decodes a message</fsummary>
+ <fsummary>Receive and decode a message.</fsummary>
<type>
<v>int fd;</v>
<v>unsigned char *bufp;</v>
@@ -224,14 +325,20 @@ erl_xconnect( &addr , ALIVE );
<v>ErlMessage *emsg;</v>
</type>
<desc>
- <p>This function receives the message into the specified buffer,
- and decodes into the <c><![CDATA[(ErlMessage *) emsg]]></c>.</p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
- <p><c><![CDATA[bufp]]></c> is a buffer large enough to hold the expected message.</p>
- <p><c><![CDATA[bufsize]]></c> indicates the size of <c><![CDATA[bufp]]></c>.</p>
- <p><c><![CDATA[emsg]]></c> is a pointer to an <c><![CDATA[ErlMessage]]></c> structure,
- into which the message will be decoded. <c><![CDATA[ErlMessage]]></c> is
- defined as follows:</p>
+ <p>Receives the message into the specified buffer
+ and decodes into <c>(ErlMessage *) emsg</c>.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open descriptor to an Erlang
+ connection.</item>
+ <item><c>bufp</c> is a buffer large enough to hold the
+ expected message.</item>
+ <item><c>bufsize</c> indicates the size of
+ <c>bufp</c>.</item>
+ <item>><c>emsg</c> is a pointer to an
+ <c>ErlMessage</c> structure
+ into which the message will be decoded.
+ <c>ErlMessage</c> is defined as follows:</item>
+ </list>
<code type="none"><![CDATA[
typedef struct {
int type;
@@ -242,144 +349,100 @@ typedef struct {
} ErlMessage;
]]></code>
<note>
- <p>The definition of <c><![CDATA[ErlMessage]]></c> has changed since
- earlier versions of Erl_Interface.</p>
+ <p>The definition of <c>ErlMessage</c> has changed since
+ earlier versions of <c>Erl_Interface</c>.</p>
</note>
- <p><c><![CDATA[type]]></c> identifies the type of message, one of
- <c><![CDATA[ERL_SEND]]></c>, <c><![CDATA[ERL_REG_SEND]]></c>, <c><![CDATA[ERL_LINK]]></c>,
- <c><![CDATA[ERL_UNLINK]]></c> and <c><![CDATA[ERL_EXIT]]></c>.
- </p>
- <p>If <c><![CDATA[type]]></c> contains <c><![CDATA[ERL_SEND]]></c>
- this indicates that an ordinary send operation has taken
- place, and <c><![CDATA[emsg->to]]></c> contains the Pid of the
- recipient. If <c><![CDATA[type]]></c> contains <c><![CDATA[ERL_REG_SEND]]></c> then a
- registered send operation took place, and <c><![CDATA[emsg->from]]></c>
- contains the Pid of the sender. In both cases, the actual
- message will be in <c><![CDATA[emsg->msg]]></c>.
- </p>
- <p>If <c><![CDATA[type]]></c> contains one of <c><![CDATA[ERL_LINK]]></c> or
- <c><![CDATA[ERL_UNLINK]]></c>, then <c><![CDATA[emsg->to]]></c> and <c><![CDATA[emsg->from]]></c>
- contain the pids of the sender and recipient of the link or unlink.
- <c><![CDATA[emsg->msg]]></c> is not used in these cases.
- </p>
- <p>If <c><![CDATA[type]]></c> contains <c><![CDATA[ERL_EXIT]]></c>, then this
- indicates that a link has been broken. In this case,
- <c><![CDATA[emsg->to]]></c> and <c><![CDATA[emsg->from]]></c> contain the pids of the
- linked processes, and <c><![CDATA[emsg->msg]]></c> contains the reason for
- the exit.
- </p>
+ <p><c>type</c> identifies the type of message, one of the
+ following:</p>
+ <taglist>
+ <tag><c>ERL_SEND</c></tag>
+ <item>
+ <p>An ordinary send operation has occurred and
+ <c>emsg->to</c> contains the pid of the recipient.
+ The message is in <c>emsg->msg</c>.</p>
+ </item>
+ <tag><c>ERL_REG_SEND</c></tag>
+ <item>
+ <p>A registered send operation has occurred and
+ <c>emsg->from</c> contains the pid of the sender.
+ The message is in <c>emsg->msg</c>.</p>
+ </item>
+ <tag><c>ERL_LINK</c> or <c>ERL_UNLINK</c>
+ </tag>
+ <item>
+ <p><c>emsg->to</c> and <c>emsg->from</c>
+ contain the pids of the sender and recipient of the link or
+ unlink. <c>emsg->msg</c> is not used.</p>
+ </item>
+ <tag><c>ERL_EXIT</c></tag>
+ <item>
+ <p>A link is broken. <c>emsg->to</c> and
+ <c>emsg->from</c> contain the pids of the linked
+ processes, and <c>emsg->msg</c> contains the reason
+ for the exit.</p>
+ </item>
+ </taglist>
<note>
<p>It is the caller's responsibility to release the
- memory pointed to by <c><![CDATA[emsg->msg]]></c>, <c><![CDATA[emsg->to]]></c> and
- <c><![CDATA[emsg->from]]></c>.</p>
+ memory pointed to by <c>emsg->msg</c>,
+ <c>emsg->to</c>, and
+ <c>emsg->from</c>.</p>
</note>
- <p>If a <em>tick</em> occurs, i.e., the Erlang node on the
+ <p>If a <em>tick</em> occurs, that is, the Erlang node on the
other end of the connection has polled this node to see if it
- is still alive, the function will return <c><![CDATA[ERL_TICK]]></c>
+ is still alive, the function returns <c>ERL_TICK</c>
indicating that the tick has been received and responded to,
- but no message will be placed in the buffer. In this case you
- should call <c><![CDATA[erl_receive_msg()]]></c> again.</p>
- <p>On success, the function returns <c><![CDATA[ERL_MSG]]></c> and the
- <c><![CDATA[Emsg]]></c> struct will be initialized as described above, or
- <c><![CDATA[ERL_TICK]]></c>, in which case no message is returned. On
- failure, the function returns <c><![CDATA[ERL_ERROR]]></c> and will set
- <c><![CDATA[erl_errno]]></c> to one of:</p>
+ but no message is placed in the buffer. In this case you
+ are to call <c>erl_receive_msg()</c> again.</p>
+ <p>On success, the function returns <c>ERL_MSG</c> and the
+ <c>Emsg</c> struct is initialized as described above, or
+ <c>ERL_TICK</c>, in which case no message is returned. On
+ failure, the function returns <c>ERL_ERROR</c> and sets
+ <c>erl_errno</c> to one of:</p>
<taglist>
- <tag><c><![CDATA[EMSGSIZE]]></c></tag>
- <item>Buffer too small.</item>
- <tag><c><![CDATA[ENOMEM]]></c></tag>
- <item>No more memory available.</item>
- <tag><c><![CDATA[EIO]]></c></tag>
- <item>I/O error.</item>
- </taglist>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>erl_xreceive_msg(fd, bufpp, bufsizep, emsg)</nametext></name>
- <fsummary>Receive and decodes a message</fsummary>
- <type>
- <v>int fd;</v>
- <v>unsigned char **bufpp;</v>
- <v>int *bufsizep;</v>
- <v>ErlMessage *emsg;</v>
- </type>
- <desc>
- <p>This function is similar to <c><![CDATA[erl_receive_msg]]></c>. The
- difference is that <c><![CDATA[erl_xreceive_msg]]></c> expects the buffer to
- have been allocated by <c><![CDATA[malloc]]></c>, and reallocates it if the received
- message does not fit into the original buffer. For that reason,
- both buffer and buffer length are given as pointers - their values
- may change by the call.
- </p>
- <p>On success, the function returns <c><![CDATA[ERL_MSG]]></c> and the
- <c><![CDATA[Emsg]]></c> struct will be initialized as described above, or
- <c><![CDATA[ERL_TICK]]></c>, in which case no message is returned. On
- failure, the function returns <c><![CDATA[ERL_ERROR]]></c> and will set
- <c><![CDATA[erl_errno]]></c> to one of:</p>
- <taglist>
- <tag><c><![CDATA[EMSGSIZE]]></c></tag>
- <item>Buffer too small.</item>
- <tag><c><![CDATA[ENOMEM]]></c></tag>
- <item>No more memory available.</item>
- <tag><c><![CDATA[EIO]]></c></tag>
- <item>I/O error.</item>
- </taglist>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>erl_send(fd, to, msg)</nametext></name>
- <fsummary>Send a message</fsummary>
- <type>
- <v>int fd;</v>
- <v>ETERM *to, *msg;</v>
- </type>
- <desc>
- <p>This function sends an Erlang term to a process.</p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
- <p><c><![CDATA[to]]></c> is an Erlang term containing the Pid of the
- intended recipient of the message.</p>
- <p><c><![CDATA[msg]]></c> is the Erlang term to be sent.</p>
- <p>The function returns 1 if successful, otherwise 0 --- in
- which case it will set <c><![CDATA[erl_errno]]></c> to one of:</p>
- <taglist>
- <tag><c><![CDATA[EINVAL]]></c></tag>
- <item>Invalid argument: <c><![CDATA[to]]></c> is not a valid Erlang pid.</item>
- <tag><c><![CDATA[ENOMEM]]></c></tag>
- <item>No more memory available.</item>
- <tag><c><![CDATA[EIO]]></c></tag>
+ <tag><c>EMSGSIZE</c></tag>
+ <item>Buffer is too small.</item>
+ <tag><c>ENOMEM</c></tag>
+ <item>No more memory is available.</item>
+ <tag><c>EIO</c></tag>
<item>I/O error.</item>
</taglist>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_reg_send(fd, to, msg)</nametext></name>
- <fsummary>Send a message to a registered name</fsummary>
+ <fsummary>Send a message to a registered name.</fsummary>
<type>
<v>int fd;</v>
<v>char *to;</v>
<v>ETERM *msg;</v>
</type>
<desc>
- <p>This function sends an Erlang term to a registered process.</p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
- <p><c><![CDATA[to]]></c> is a string containing the registered name of
- the intended recipient of the message.</p>
- <p><c><![CDATA[msg]]></c> is the Erlang term to be sent.</p>
- <p>The function returns 1 if successful, otherwise 0 --- in
- which case it will set <c><![CDATA[erl_errno]]></c> to one of:</p>
+ <p>Sends an Erlang term to a registered process.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open descriptor to an Erlang
+ connection.</item>
+ <item><c>to</c> is a string containing the registered name
+ of the intended recipient of the message.</item>
+ <item><c>msg</c> is the Erlang term to be sent.</item>
+ </list>
+ <p>Returns <c>1</c> on success, otherwise <c>0</c>. In
+ the latter case <c>erl_errno</c> is set to one of:</p>
<taglist>
- <tag><c><![CDATA[ENOMEM]]></c></tag>
- <item>No more memory available.</item>
- <tag><c><![CDATA[EIO]]></c></tag>
+ <tag><c>ENOMEM</c></tag>
+ <item>No more memory is available.</item>
+ <tag><c>EIO</c></tag>
<item>I/O error.</item>
</taglist>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_rpc(fd, mod, fun, args)</nametext></name>
- <name><ret>int</ret><nametext>erl_rpc_to(fd, mod, fun, args)</nametext></name>
<name><ret>int</ret><nametext>erl_rpc_from(fd, timeout, emsg)</nametext></name>
- <fsummary>Remote Procedure Call</fsummary>
+ <name><ret>int</ret><nametext>erl_rpc_to(fd, mod, fun, args)</nametext></name>
+ <fsummary>Remote Procedure Call.</fsummary>
<type>
<v>int fd, timeout;</v>
<v>char *mod, *fun;</v>
@@ -387,158 +450,178 @@ typedef struct {
<v>ErlMessage *emsg;</v>
</type>
<desc>
- <p>These functions support calling Erlang functions on remote nodes.
- <c><![CDATA[erl_rpc_to()]]></c> sends an rpc request to a remote node and
- <c><![CDATA[erl_rpc_from()]]></c> receives the results of such a call.
- <c><![CDATA[erl_rpc()]]></c> combines the functionality of these two functions
- by sending an rpc request and waiting for the results. See also
- <c><![CDATA[rpc:call/4]]></c>. </p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
- <p><c><![CDATA[timeout]]></c> is the maximum time (in ms) to wait for
- results. Specify <c><![CDATA[ERL_NO_TIMEOUT]]></c> to wait forever.
- When erl_rpc() calls erl_rpc_from(), the call will never
- timeout.</p>
- <p><c><![CDATA[mod]]></c> is the name of the module containing the function
- to be run on the remote node.</p>
- <p><c><![CDATA[fun]]></c> is the name of the function to run.</p>
- <p><c><![CDATA[args]]></c> is an Erlang list, containing the arguments to be
- passed to the function. </p>
- <p><c><![CDATA[emsg]]></c> is a message containing the result of the
- function call.</p>
- <p>The actual message returned by the rpc server
- is a 2-tuple <c><![CDATA[{rex,Reply}]]></c>. If you are using
- <c><![CDATA[erl_rpc_from()]]></c> in your code then this is the message you
- will need to parse. If you are using <c><![CDATA[erl_rpc()]]></c> then the
+ <p>Supports calling Erlang functions on remote nodes.
+ <c>erl_rpc_to()</c> sends an RPC request to a remote node
+ and <c>erl_rpc_from()</c> receives the results of such a
+ call. <c>erl_rpc()</c> combines the functionality of
+ these two functions by sending an RPC request and waiting for the
+ results. See also <seealso marker="kernel:rpc#call/4">
+ <c>rpc:call/4</c></seealso> in <c>Kernel</c>.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open descriptor to an Erlang
+ connection.</item>
+ <item><c>timeout</c> is the maximum time (in milliseconds)
+ to wait for
+ results. To wait forever, specify <c>ERL_NO_TIMEOUT</c>.
+ When <c>erl_rpc()</c> calls <c>erl_rpc_from()</c>, the call will
+ never timeout.</item>
+ <item><c>mod</c> is the name of the module containing the
+ function to be run on the remote node.</item>
+ <item><c>fun</c> is the name of the function to run.
+ </item>
+ <item><c>args</c> is an Erlang list, containing the
+ arguments to be passed to the function.</item>
+ <item><c>emsg</c> is a message containing the result of
+ the function call.</item>
+ </list>
+ <p>The actual message returned by the RPC server
+ is a 2-tuple <c>{rex,Reply}</c>. If you use
+ <c>erl_rpc_from()</c> in your code, this is the message
+ you will need to parse. If you use <c>erl_rpc()</c>, the
tuple itself is parsed for you, and the message returned to your
- program is the erlang term containing <c><![CDATA[Reply]]></c> only. Replies
- to rpc requests are always ERL_SEND messages.
- </p>
+ program is the Erlang term containing <c>Reply</c> only.
+ Replies to RPC requests are always <c>ERL_SEND</c> messages.</p>
<note>
<p>It is the caller's responsibility to free the returned
- <c><![CDATA[ETERM]]></c> structure as well as the memory pointed to by
- <c><![CDATA[emsg->msg]]></c> and <c><![CDATA[emsg->to]]></c>. </p>
+ <c>ETERM</c> structure and the memory pointed to by
+ <c>emsg->msg</c> and <c>emsg->to</c>.</p>
</note>
- <p><c><![CDATA[erl_rpc()]]></c> returns the remote function's return value (or
- <c><![CDATA[NULL]]></c> if it failed). <c><![CDATA[erl_rpc_to()]]></c> returns 0 on
- success, and a negative number on failure. <c><![CDATA[erl_rcp_from()]]></c>
- returns <c><![CDATA[ERL_MSG]]></c> when successful (with <c><![CDATA[Emsg]]></c> now
- containing the reply tuple), and one of <c><![CDATA[ERL_TICK]]></c>,
- <c><![CDATA[ERL_TIMEOUT]]></c> and <c><![CDATA[ERL_ERROR]]></c> otherwise. When failing,
- all three functions set <c><![CDATA[erl_errno]]></c> to one of:</p>
+ <p><c>erl_rpc()</c> returns the remote function's return
+ value on success, otherwise <c>NULL</c>.</p>
+ <p><c>erl_rpc_to()</c> returns <c>0</c> on
+ success, otherwise a negative number.</p>
+ <p><c>erl_rcp_from()</c> returns <c>ERL_MSG</c>
+ on success (with <c>Emsg</c> now
+ containing the reply tuple), otherwise one of
+ <c>ERL_TICK</c>, <c>ERL_TIMEOUT</c>, or
+ <c>ERL_ERROR</c>.</p>
+ <p>When failing,
+ all three functions set <c>erl_errno</c> to one of:</p>
<taglist>
- <tag><c><![CDATA[ENOMEM]]></c></tag>
- <item>No more memory available.</item>
- <tag><c><![CDATA[EIO]]></c></tag>
+ <tag><c>ENOMEM</c></tag>
+ <item>No more memory is available.</item>
+ <tag><c>EIO</c></tag>
<item>I/O error.</item>
- <tag><c><![CDATA[ETIMEDOUT]]></c></tag>
- <item>Timeout expired.</item>
- <tag><c><![CDATA[EAGAIN]]></c></tag>
+ <tag><c>ETIMEDOUT</c></tag>
+ <item>Timeout has expired.</item>
+ <tag><c>EAGAIN</c></tag>
<item>Temporary error: Try again.</item>
</taglist>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>erl_publish(port)</nametext></name>
- <fsummary>Publish a node name</fsummary>
+ <name><ret>int</ret><nametext>erl_send(fd, to, msg)</nametext></name>
+ <fsummary>Send a message.</fsummary>
<type>
- <v>int port;</v>
+ <v>int fd;</v>
+ <v>ETERM *to, *msg;</v>
</type>
<desc>
- <p>These functions are used by a server process to register
- with the local name server <em>epmd</em>, thereby allowing
- other processes to send messages by using the registered name.
- Before calling either of these functions, the process should
- have called <c><![CDATA[bind()]]></c> and <c><![CDATA[listen()]]></c> on an open socket.</p>
- <p><c><![CDATA[port]]></c> is the local name to register, and should be the
- same as the port number that was previously bound to the socket.</p>
- <p>To unregister with epmd, simply close the returned
- descriptor.
- </p>
- <p>On success, the functions return a descriptor connecting the
- calling process to epmd. On failure, they return -1 and set
- <c><![CDATA[erl_errno]]></c> to:</p>
+ <p>Sends an Erlang term to a process.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open descriptor to an Erlang
+ connection.</item>
+ <item><c>to</c> is an Erlang term containing the pid of
+ the intended recipient of the message.</item>
+ <item>><c>msg</c> is the Erlang term to be sent.</item>
+ </list>
+ <p>Returns <c>1</c> on success, otherwise <c>0</c>. In
+ the latter case <c>erl_errno</c> is set to one of:</p>
<taglist>
- <tag><c><![CDATA[EIO]]></c></tag>
- <item>I/O error</item>
+ <tag><c>EINVAL</c></tag>
+ <item>Invalid argument: <c>to</c> is not a valid Erlang
+ pid.</item>
+ <tag><c>ENOMEM</c></tag>
+ <item>No more memory is available.</item>
+ <tag><c>EIO</c></tag>
+ <item>I/O error.</item>
</taglist>
- <p>Additionally, <c><![CDATA[errno]]></c> values from <c><![CDATA[socket]]></c><em>(2)</em>
- and <c><![CDATA[connect]]></c><em>(2)</em> system calls may be propagated
- into <c><![CDATA[erl_errno]]></c>.
- </p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>erl_accept(listensock, conp)</nametext></name>
- <fsummary>Accept a connection</fsummary>
- <type>
- <v>int listensock;</v>
- <v>ErlConnect *conp;</v>
- </type>
- <desc>
- <p>This function is used by a server process to accept a
- connection from a client process.</p>
- <p><c><![CDATA[listensock]]></c> is an open socket descriptor on which
- <c><![CDATA[listen()]]></c> has previously been called.</p>
- <p><c><![CDATA[conp]]></c> is a pointer to an <c><![CDATA[ErlConnect]]></c> struct,
- described as follows:</p>
- <code type="none"><![CDATA[
-typedef struct {
- char ipadr[4];
- char nodename[MAXNODELEN];
-} ErlConnect;
- ]]></code>
- <p>On success, <c><![CDATA[conp]]></c> is filled in with the address and
- node name of the connecting client and a file descriptor is
- returned. On failure, <c><![CDATA[ERL_ERROR]]></c> is returned and
- <c><![CDATA[erl_errno]]></c> is set to <c><![CDATA[EIO]]></c>.</p>
</desc>
</func>
+
<func>
- <name><ret>const char *</ret><nametext>erl_thiscookie()</nametext></name>
- <name><ret>const char *</ret><nametext>erl_thisnodename()</nametext></name>
- <name><ret>const char *</ret><nametext>erl_thishostname()</nametext></name>
<name><ret>const char *</ret><nametext>erl_thisalivename()</nametext></name>
+ <name><ret>const char *</ret><nametext>erl_thiscookie()</nametext></name>
<name><ret>short</ret><nametext>erl_thiscreation()</nametext></name>
- <fsummary>Retrieve some values</fsummary>
+ <name><ret>const char *</ret><nametext>erl_thishostname()</nametext></name>
+ <name><ret>const char *</ret><nametext>erl_thisnodename()</nametext></name>
+ <fsummary>Retrieve some values.</fsummary>
<desc>
- <p>These functions can be used to retrieve information about
- the C Node. These values are initially set with
- <c><![CDATA[erl_connect_init()]]></c> or <c><![CDATA[erl_connect_xinit()]]></c>.</p>
+ <p>Retrieves information about
+ the C-node. These values are initially set with
+ <c>erl_connect_init()</c> or
+ <c>erl_connect_xinit()</c>.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_unpublish(alive)</nametext></name>
- <fsummary>Forcefully unpublish a node name</fsummary>
+ <fsummary>Forcefully unpublish a node name.</fsummary>
<type>
<v>char *alive;</v>
</type>
<desc>
<p>This function can be called by a process to unregister a
- specified node from epmd on the localhost. This is however usually not
- allowed, unless epmd was started with the -relaxed_command_check
- flag, which it normally isn't.</p>
-
- <p>To unregister a node you have published, you should instead
- close the descriptor that was returned by
- <c><![CDATA[ei_publish()]]></c>.</p>
-
+ specified node from EPMD on the local host. This is, however, usually
+ not allowed, unless EPMD was started with flag
+ <c>-relaxed_command_check</c>, which it normally is not.</p>
+ <p>To unregister a node you have published, you should instead
+ close the descriptor that was returned by
+ <c>ei_publish()</c>.</p>
<warning>
- <p>This function is deprecated and will be removed in a future
- release.</p>
+ <p>This function is deprecated and will be removed in a future
+ release.</p>
</warning>
- <p><c><![CDATA[alive]]></c> is the name of the node to unregister, i.e., the
- first component of the nodename, without the <c><![CDATA[@hostname]]></c>.</p>
- <p>If the node was successfully unregistered from epmd, the
- function returns 0. Otherwise, it returns -1 and sets
- <c><![CDATA[erl_errno]]></c> is to <c><![CDATA[EIO]]></c>.</p>
+ <p><c>alive</c> is the name of the node to unregister, that
+ is, the first component of the node name, without
+ <c>@hostname</c>.</p>
+ <p>If the node was successfully unregistered from EPMD, <c>0</c> is
+ returned, otherwise <c>-1</c> is returned and
+ <c>erl_errno</c> is set to <c>EIO</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_xreceive_msg(fd, bufpp, bufsizep, emsg)</nametext></name>
+ <fsummary>Receive and decode a message.</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>unsigned char **bufpp;</v>
+ <v>int *bufsizep;</v>
+ <v>ErlMessage *emsg;</v>
+ </type>
+ <desc>
+ <p>Similar to <c>erl_receive_msg</c>. The difference is
+ that <c>erl_xreceive_msg</c> expects the buffer to
+ have been allocated by <c>malloc</c>, and reallocates it
+ if the received
+ message does not fit into the original buffer. Therefore
+ both buffer and buffer length are given as pointers; their values
+ can change by the call.</p>
+ <p>On success, the function returns <c>ERL_MSG</c> and the
+ <c>Emsg</c> struct is initialized as described above, or
+ <c>ERL_TICK</c>, in which case no message is returned. On
+ failure, the function returns <c>ERL_ERROR</c> and sets
+ <c>erl_errno</c> to one of:</p>
+ <taglist>
+ <tag><c>EMSGSIZE</c></tag>
+ <item>Buffer is too small.</item>
+ <tag><c>ENOMEM</c></tag>
+ <item>No more memory is available.</item>
+ <tag><c>EIO</c></tag>
+ <item>I/O error.</item>
+ </taglist>
</desc>
</func>
+
<func>
- <name><ret>struct hostent</ret><nametext>*erl_gethostbyname(name)</nametext></name>
<name><ret>struct hostent</ret><nametext>*erl_gethostbyaddr(addr, length, type)</nametext></name>
- <name><ret>struct hostent</ret><nametext>*erl_gethostbyname_r(name, hostp, buffer, buflen, h_errnop)</nametext></name>
<name><ret>struct hostent</ret><nametext>*erl_gethostbyaddr_r(addr, length, type, hostp, buffer, buflen, h_errnop)</nametext></name>
- <fsummary>Name lookup functions</fsummary>
+ <name><ret>struct hostent</ret><nametext>*erl_gethostbyname(name)</nametext></name>
+ <name><ret>struct hostent</ret><nametext>*erl_gethostbyname_r(name, hostp, buffer, buflen, h_errnop)</nametext></name>
+
+ <fsummary>Name lookup functions.</fsummary>
<type>
<v>const char *name;</v>
<v>const char *addr;</v>
@@ -550,7 +633,7 @@ typedef struct {
<v>int *h_errnop;</v>
</type>
<desc>
- <p>These are convenience functions for some common name lookup functions.</p>
+ <p>Convenience functions for some common name lookup functions.</p>
</desc>
</func>
</funcs>
@@ -558,13 +641,13 @@ typedef struct {
<section>
<title>Debug Information</title>
<p>If a connection attempt fails, the following can be checked:</p>
+
<list type="bulleted">
- <item><c><![CDATA[erl_errno]]></c></item>
- <item>that the right cookie was used</item>
- <item>that <em>epmd</em> is running</item>
- <item>the remote Erlang node on the other side is running the same
- version of Erlang as the <c><![CDATA[erl_interface]]></c> library.</item>
+ <item><c>erl_errno</c></item>
+ <item>That the correct cookie was used</item>
+ <item>That EPMD is running</item>
+ <item>That the remote Erlang node on the other side is running the same
+ version of Erlang as the <c>erl_interface</c> library</item>
</list>
</section>
</cref>
-
diff --git a/lib/erl_interface/doc/src/erl_error.xml b/lib/erl_interface/doc/src/erl_error.xml
index abe84780e1..8139c9b343 100644
--- a/lib/erl_interface/doc/src/erl_error.xml
+++ b/lib/erl_interface/doc/src/erl_error.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>erl_error</title>
@@ -28,61 +28,66 @@
<docno></docno>
<approved>Bjarne D&auml;cker</approved>
<checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
- <date>961014</date>
+ <date>1996-10-14</date>
<rev>A</rev>
- <file>erl_error.sgml</file>
+ <file>erl_error.xml</file>
</header>
<lib>erl_error</lib>
- <libsummary>Error Print Routines</libsummary>
+ <libsummary>Error print routines.</libsummary>
<description>
<p>This module contains some error printing routines taken
- from <em>Advanced Programming in the UNIX Environment</em>
- by W. Richard Stevens. </p>
+ from "Advanced Programming in the UNIX Environment"
+ by W. Richard Stevens.</p>
+
<p>These functions are all called in the same manner as
- <c><![CDATA[printf()]]></c>, i.e. with a string containing format specifiers
- followed by a list of corresponding arguments. All output from
- these functions is to <c><![CDATA[stderr]]></c>.</p>
+ <c>printf()</c>, that is, with a string containing format
+ specifiers followed by a list of corresponding arguments. All output from
+ these functions is to <c>stderr</c>.</p>
</description>
+
<funcs>
<func>
<name><ret>void</ret><nametext>erl_err_msg(FormatStr, ... )</nametext></name>
- <fsummary>Non-fatal error, and not system call error</fsummary>
+ <fsummary>Non-fatal error, and not system call error.</fsummary>
<type>
<v>const char *FormatStr;</v>
</type>
<desc>
<p>The message provided by the caller is printed. This
- function is simply a wrapper for <c><![CDATA[fprintf()]]></c>.</p>
+ function is simply a wrapper for <c>fprintf()</c>.</p>
</desc>
</func>
+
<func>
<name><ret>void</ret><nametext>erl_err_quit(FormatStr, ... )</nametext></name>
- <fsummary>Fatal error, but not system call error</fsummary>
+ <fsummary>Fatal error, but not system call error.</fsummary>
<type>
<v>const char *FormatStr;</v>
</type>
<desc>
<p>Use this function when a fatal error has occurred that
- is not due to a system call. The message provided by the
- caller is printed and the process terminates with an exit
- value of 1. The function does not return.</p>
+ is not because of a system call. The message provided by the
+ caller is printed and the process terminates with exit
+ value <c>1</c>. This function does not return.</p>
</desc>
</func>
+
<func>
<name><ret>void</ret><nametext>erl_err_ret(FormatStr, ... )</nametext></name>
- <fsummary>Non-fatal system call error</fsummary>
+ <fsummary>Non-fatal system call error.</fsummary>
<type>
<v>const char *FormatStr;</v>
</type>
<desc>
<p>Use this function after a failed system call. The message
provided by the caller is printed followed by a string
- describing the reason for failure. </p>
+ describing the reason for failure.</p>
</desc>
</func>
+
<func>
<name><ret>void</ret><nametext>erl_err_sys(FormatStr, ... )</nametext></name>
- <fsummary>Fatal system call error</fsummary>
+ <fsummary>Fatal system call error.</fsummary>
<type>
<v>const char *FormatStr;</v>
</type>
@@ -90,7 +95,7 @@
<p>Use this function after a failed system call. The message
provided by the caller is printed followed by a string
describing the reason for failure, and the process
- terminates with an exit value of 1. The function does not
+ terminates with exit value <c>1</c>. This function does not
return.</p>
</desc>
</func>
@@ -98,40 +103,43 @@
<section>
<title>Error Reporting</title>
- <p>Most functions in erl_interface report failures to the caller by
- returning some otherwise meaningless value (typically <c><![CDATA[NULL]]></c>
+ <p>Most functions in <c>Erl_Interface</c> report failures to the caller by
+ returning some otherwise meaningless value (typically
+ <c>NULL</c>
or a negative number). As this only tells you that things did not
- go well, you will have to examine the error code in
- <c><![CDATA[erl_errno]]></c> if you want to find out more about the failure.</p>
+ go well, examine the error code in <c>erl_errno</c> if you
+ want to find out more about the failure.</p>
</section>
+
<funcs>
<func>
<name><ret>volatile int</ret><nametext>erl_errno</nametext></name>
- <fsummary>The variable <c><![CDATA[erl_errno]]></c>contains the erl_interface error number. You can change the value if you wish. </fsummary>
+ <fsummary>Variable <c>erl_errno</c> contains the
+ Erl_Interface error number. You can change the value if you wish.
+ </fsummary>
<desc>
- <p><c><![CDATA[erl_errno]]></c> is initially (at program startup) zero and
- is then set by many erl_interface functions on failure to a
- non-zero error code to indicate what kind of error it
- encountered. A successful function call might change
- <c><![CDATA[erl_errno]]></c> (by calling some other function that
- fails), but no function will ever set it to zero. This means
- that you cannot use <c><![CDATA[erl_errno]]></c> to see <em>if</em> a
+ <p><c>erl_errno</c> is initially (at program startup) zero
+ and is then set by many <c>Erl_Interface</c> functions on failure to
+ a non-zero error code to indicate what kind of error it
+ encountered. A successful function call can change
+ <c>erl_errno</c> (by calling some other function that
+ fails), but no function does never set it to zero. This means
+ that you cannot use <c>erl_errno</c> to see <em>if</em> a
function call failed. Instead, each function reports failure
in its own way (usually by returning a negative number or
- <c><![CDATA[NULL]]></c>), in which case you can examine <c><![CDATA[erl_errno]]></c>
- for details.</p>
- <p><c><![CDATA[erl_errno]]></c> uses the error codes defined in your
- system's <c><![CDATA[<errno.h>]]></c>.</p>
+ <c>NULL</c>), in which case you can examine
+ <c>erl_errno</c> for details.</p>
+ <p><c>erl_errno</c> uses the error codes defined in your
+ system's <c>&lt;errno.h&gt;</c>.</p>
<note>
- <p>Actually, <c><![CDATA[erl_errno]]></c> is a "modifiable lvalue" (just
- like ISO C defines <c><![CDATA[errno]]></c> to be) rather than a
- variable. This means it might be implemented as a macro
- (expanding to, e.g., <c><![CDATA[*_erl_errno()]]></c>). For reasons of
- thread- (or task-)safety, this is exactly what we do on most
- platforms.</p>
+ <p><c>erl_errno</c> is a "modifiable lvalue" (just
+ like ISO C defines <c>errno</c> to be) rather than a
+ variable. This means it can be implemented as a macro
+ (expanding to, for example, <c>*_erl_errno()</c>).
+ For reasons of thread safety (or task safety), this is exactly what
+ we do on most platforms.</p>
</note>
</desc>
</func>
</funcs>
</cref>
-
diff --git a/lib/erl_interface/doc/src/erl_eterm.xml b/lib/erl_interface/doc/src/erl_eterm.xml
index 800f8a3207..9a05196a70 100644
--- a/lib/erl_interface/doc/src/erl_eterm.xml
+++ b/lib/erl_interface/doc/src/erl_eterm.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>erl_eterm</title>
@@ -28,131 +28,145 @@
<docno></docno>
<approved>Bjarne D&auml;cker</approved>
<checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
- <date>980703</date>
+ <date>1998-07-03</date>
<rev>A</rev>
- <file>erl_eterm.sgml</file>
+ <file>erl_eterm.xml</file>
</header>
<lib>erl_eterm</lib>
- <libsummary>Functions for Erlang Term Construction</libsummary>
+ <libsummary>Functions for Erlang term construction.</libsummary>
<description>
- <p>This module contains functions for creating and manipulating
- Erlang terms. </p>
+ <p>This module provides functions for creating and manipulating
+ Erlang terms.</p>
+
<p>An Erlang term is represented by a C structure of type
- <c><![CDATA[ETERM]]></c>. Applications should not reference any fields in this
- structure directly, because it may be changed in future releases
+ <c>ETERM</c>. Applications should not reference any fields
+ in this structure directly, as it can be changed in future releases
to provide faster and more compact term storage. Instead,
- applications should us the macros and functions provided. </p>
- <p>The following macros each take a single ETERM pointer as an
- argument. They return a non-zero value if the test is true, and 0
- otherwise:</p>
+ applications should use the macros and functions provided.</p>
+
+ <p>Each of the following macros takes a single <c>ETERM</c> pointer as an
+ argument. The macros return a non-zero value if the test is true,
+ otherwise <c>0</c>.</p>
+
<taglist>
- <tag><c><![CDATA[ERL_IS_INTEGER(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is an integer.</item>
- <tag><c><![CDATA[ERL_IS_UNSIGNED_INTEGER(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is an integer.</item>
- <tag><c><![CDATA[ERL_IS_FLOAT(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is a floating point number.</item>
- <tag><c><![CDATA[ERL_IS_ATOM(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is an atom.</item>
- <tag><c><![CDATA[ERL_IS_PID(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is a Pid (process identifier).</item>
- <tag><c><![CDATA[ERL_IS_PORT(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is a port.</item>
- <tag><c><![CDATA[ERL_IS_REF(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is a reference.</item>
- <tag><c><![CDATA[ERL_IS_TUPLE(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is a tuple.</item>
- <tag><c><![CDATA[ERL_IS_BINARY(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is a binary.</item>
- <tag><c><![CDATA[ERL_IS_LIST(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is a list with zero or more elements.</item>
- <tag><c><![CDATA[ERL_IS_EMPTY_LIST(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is an empty list.</item>
- <tag><c><![CDATA[ERL_IS_CONS(t)]]></c></tag>
- <item>True if <c><![CDATA[t]]></c> is a list with at least one element.</item>
+ <tag><c>ERL_IS_INTEGER(t)</c></tag>
+ <item>True if <c>t</c> is an integer.</item>
+ <tag><c>ERL_IS_UNSIGNED_INTEGER(t)</c></tag>
+ <item>True if <c>t</c> is an integer.</item>
+ <tag><c>ERL_IS_FLOAT(t)</c></tag>
+ <item>True if <c>t</c> is a floating point number.</item>
+ <tag><c>ERL_IS_ATOM(t)</c></tag>
+ <item>True if <c>t</c> is an atom.</item>
+ <tag><c>ERL_IS_PID(t)</c></tag>
+ <item>True if <c>t</c> is a pid (process identifier).</item>
+ <tag><c>ERL_IS_PORT(t)</c></tag>
+ <item>True if <c>t</c> is a port.</item>
+ <tag><c>ERL_IS_REF(t)</c></tag>
+ <item>True if <c>t</c> is a reference.</item>
+ <tag><c>ERL_IS_TUPLE(t)</c></tag>
+ <item>True if <c>t</c> is a tuple.</item>
+ <tag><c>ERL_IS_BINARY(t)</c></tag>
+ <item>True if <c>t</c> is a binary.</item>
+ <tag><c>ERL_IS_LIST(t)</c></tag>
+ <item>True if <c>t</c> is a list with zero or more
+ elements.</item>
+ <tag><c>ERL_IS_EMPTY_LIST(t)</c></tag>
+ <item>True if <c>t</c> is an empty list.</item>
+ <tag><c>ERL_IS_CONS(t)</c></tag>
+ <item>True if <c>t</c> is a list with at least one
+ element.</item>
</taglist>
+
<p>The following macros can be used for retrieving parts of Erlang
- terms. None of these do any type checking; results are undefined
- if you pass an ETERM* containing the wrong type. For example,
- passing a tuple to ERL_ATOM_PTR() will likely result in garbage.
- </p>
+ terms. None of these do any type checking. Results are undefined
+ if you pass an <c>ETERM*</c> containing the wrong type. For example,
+ passing a tuple to <c>ERL_ATOM_PTR()</c> likely results in garbage.</p>
+
<taglist>
- <tag><c><![CDATA[char *ERL_ATOM_PTR(t)]]></c></tag>
- <item/>
- <tag><c><![CDATA[char *ERL_ATOM_PTR_UTF8(t)]]></c></tag>
- <item>A string representing atom <c><![CDATA[t]]></c>.
- </item>
- <tag><c><![CDATA[int ERL_ATOM_SIZE(t)]]></c></tag>
- <item/>
- <tag><c><![CDATA[int ERL_ATOM_SIZE_UTF8(t)]]></c></tag>
- <item>The length (in bytes) of atom t.</item>
- <tag><c><![CDATA[void *ERL_BIN_PTR(t)]]></c></tag>
- <item>A pointer to the contents of <c><![CDATA[t]]></c></item>
- <tag><c><![CDATA[int ERL_BIN_SIZE(t)]]></c></tag>
- <item>The length (in bytes) of binary object <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[int ERL_INT_VALUE(t)]]></c></tag>
- <item>The integer of <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[unsigned int ERL_INT_UVALUE(t)]]></c></tag>
- <item>The unsigned integer value of <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[double ERL_FLOAT_VALUE(t)]]></c></tag>
- <item>The floating point value of <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[ETERM *ERL_PID_NODE(t)]]></c></tag>
- <item/>
- <tag><c><![CDATA[ETERM *ERL_PID_NODE_UTF8(t)]]></c></tag>
- <item>The Node in pid <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[int ERL_PID_NUMBER(t)]]></c></tag>
- <item>The sequence number in pid <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[int ERL_PID_SERIAL(t)]]></c></tag>
- <item>The serial number in pid <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[int ERL_PID_CREATION(t)]]></c></tag>
- <item>The creation number in pid <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[int ERL_PORT_NUMBER(t)]]></c></tag>
- <item>The sequence number in port <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[int ERL_PORT_CREATION(t)]]></c></tag>
- <item>The creation number in port <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[ETERM *ERL_PORT_NODE(t)]]></c></tag>
- <item/>
- <tag><c><![CDATA[ETERM *ERL_PORT_NODE_UTF8(t)]]></c></tag>
- <item>The node in port <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[int ERL_REF_NUMBER(t)]]></c></tag>
- <item>The first part of the reference number in ref <c><![CDATA[t]]></c>. Use
- only for compatibility.</item>
- <tag><c><![CDATA[int ERL_REF_NUMBERS(t)]]></c></tag>
- <item>Pointer to the array of reference numbers in ref <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[int ERL_REF_LEN(t)]]></c></tag>
- <item>The number of used reference numbers in ref <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[int ERL_REF_CREATION(t)]]></c></tag>
- <item>The creation number in ref <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[int ERL_TUPLE_SIZE(t)]]></c></tag>
- <item>The number of elements in tuple <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[ETERM *ERL_CONS_HEAD(t)]]></c></tag>
- <item>The head element of list <c><![CDATA[t]]></c>.</item>
- <tag><c><![CDATA[ETERM *ERL_CONS_TAIL(t)]]></c></tag>
- <item>A List representing the tail elements of list <c><![CDATA[t]]></c>.</item>
+ <tag><c>char *ERL_ATOM_PTR(t)</c></tag>
+ <item></item>
+ <tag><c>char *ERL_ATOM_PTR_UTF8(t)</c></tag>
+ <item>A string representing atom <c>t</c>.</item>
+ <tag><c>int ERL_ATOM_SIZE(t)</c></tag>
+ <item></item>
+ <tag><c>int ERL_ATOM_SIZE_UTF8(t)</c></tag>
+ <item>The length (in bytes) of atom <c>t</c>.</item>
+ <tag><c>void *ERL_BIN_PTR(t)</c></tag>
+ <item>A pointer to the contents of <c>t</c>.</item>
+ <tag><c>int ERL_BIN_SIZE(t)</c></tag>
+ <item>The length (in bytes) of binary object <c>t</c>.</item>
+ <tag><c>int ERL_INT_VALUE(t)</c></tag>
+ <item>The integer of <c>t</c>.</item>
+ <tag><c>unsigned int ERL_INT_UVALUE(t)</c></tag>
+ <item>The unsigned integer value of <c>t</c>.</item>
+ <tag><c>double ERL_FLOAT_VALUE(t)</c></tag>
+ <item>The floating point value of <c>t</c>.</item>
+ <tag><c>ETERM *ERL_PID_NODE(t)</c></tag>
+ <item></item>
+ <tag><c>ETERM *ERL_PID_NODE_UTF8(t)</c></tag>
+ <item>The node in pid <c>t</c>.</item>
+ <tag><c>int ERL_PID_NUMBER(t)</c></tag>
+ <item>The sequence number in pid <c>t</c>.</item>
+ <tag><c>int ERL_PID_SERIAL(t)</c></tag>
+ <item>The serial number in pid <c>t</c>.</item>
+ <tag><c>int ERL_PID_CREATION(t)</c></tag>
+ <item>The creation number in pid <c>t</c>.</item>
+ <tag><c>int ERL_PORT_NUMBER(t)</c></tag>
+ <item>The sequence number in port <c>t</c>.</item>
+ <tag><c>int ERL_PORT_CREATION(t)</c></tag>
+ <item>The creation number in port <c>t</c>.</item>
+ <tag><c>ETERM *ERL_PORT_NODE(t)</c></tag>
+ <item></item>
+ <tag><c>ETERM *ERL_PORT_NODE_UTF8(t)</c></tag>
+ <item>The node in port <c>t</c>.</item>
+ <tag><c>int ERL_REF_NUMBER(t)</c></tag>
+ <item>The first part of the reference number in ref <c>t</c>.
+ Use only for compatibility.</item>
+ <tag><c>int ERL_REF_NUMBERS(t)</c></tag>
+ <item>Pointer to the array of reference numbers in ref
+ <c>t</c>.</item>
+ <tag><c>int ERL_REF_LEN(t)</c></tag>
+ <item>The number of used reference numbers in ref
+ <c>t</c>.</item>
+ <tag><c>int ERL_REF_CREATION(t)</c></tag>
+ <item>The creation number in ref <c>t</c>.</item>
+ <tag><c>int ERL_TUPLE_SIZE(t)</c></tag>
+ <item>The number of elements in tuple <c>t</c>.</item>
+ <tag><c>ETERM *ERL_CONS_HEAD(t)</c></tag>
+ <item>The head element of list <c>t</c>.</item>
+ <tag><c>ETERM *ERL_CONS_TAIL(t)</c></tag>
+ <item>A list representing the tail elements of list
+ <c>t</c>.</item>
</taglist>
</description>
+
<funcs>
<func>
<name><ret>ETERM *</ret><nametext>erl_cons(head, tail)</nametext></name>
- <fsummary>Prepends a term to the head of a list.</fsummary>
+ <fsummary>Prepend a term to the head of a list.</fsummary>
<type>
<v>ETERM *head;</v>
<v>ETERM *tail;</v>
</type>
<desc>
- <p>This function concatenates two Erlang terms, prepending
- <c><![CDATA[head]]></c> onto <c><![CDATA[tail]]></c> and thereby creating a <c><![CDATA[cons]]></c> cell.
- To make a proper list, <c><![CDATA[tail]]></c> should always be a
- list or an empty list. Note that NULL is not a valid list.</p>
- <p><c><![CDATA[head]]></c> is the new term to be added.</p>
- <p><c><![CDATA[tail]]></c> is the existing list to which <c><![CDATA[head]]></c> will
- be concatenated.</p>
+ <p>Concatenates two Erlang terms, prepending <c>head</c>
+ onto <c>tail</c> and thereby creating a
+ <c>cons</c> cell.
+ To make a proper list, <c>tail</c> is always to be a list
+ or an empty list. Notice that <c>NULL</c> is not a valid list.</p>
+ <list type="bulleted">
+ <item><c>head</c> is the new term to be added.</item>
+ <item><c>tail</c> is the existing list to which
+ <c>head</c> is concatenated.</item>
+ </list>
<p>The function returns a new list.</p>
- <p><c><![CDATA[ERL_CONS_HEAD(list)]]></c> and <c><![CDATA[ERL_CONS_TAIL(list)]]></c>
+ <p><c>ERL_CONS_HEAD(list)</c> and
+ <c>ERL_CONS_TAIL(list)</c>
can be used to retrieve the head and tail components
- from the list. <c><![CDATA[erl_hd(list)]]></c> and <c><![CDATA[erl_tl(list)]]></c> will do
+ from the list. <c>erl_hd(list)</c> and
+ <c>erl_tl(list)</c> do
the same thing, but check that the argument really is a list.</p>
- <p>For example:</p>
+ <p><em>Example:</em></p>
<code type="none"><![CDATA[
ETERM *list,*anAtom,*anInt;
anAtom = erl_mk_atom("madonna");
@@ -165,79 +179,102 @@ erl_free_compound(list);
]]></code>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_copy_term(term)</nametext></name>
- <fsummary>Creates a copy of an Erlang term</fsummary>
+ <fsummary>Create a copy of an Erlang term.</fsummary>
<type>
<v>ETERM *term;</v>
</type>
<desc>
- <p>This function creates and returns a copy of the Erlang term
- <c><![CDATA[term]]></c>.</p>
+ <p>Creates and returns a copy of the Erlang term
+ <c>term</c>.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_element(position, tuple)</nametext></name>
- <fsummary>Extracts an element from an Erlang tuple</fsummary>
+ <fsummary>Extract an element from an Erlang tuple.</fsummary>
<type>
<v>int position;</v>
<v>ETERM *tuple;</v>
</type>
<desc>
- <p>This function extracts a specified element from an Erlang
- tuple. </p>
- <p><c><![CDATA[position]]></c> specifies which element to retrieve from
- <c><![CDATA[tuple]]></c>. The elements are numbered starting from 1.</p>
- <p><c><![CDATA[tuple]]></c> is an Erlang term containing at least
- <c><![CDATA[position]]></c> elements.</p>
- <p>The function returns a new Erlang term corresponding to the
- requested element, or NULL if <c><![CDATA[position]]></c> was greater than
- the arity of <c><![CDATA[tuple]]></c>.</p>
+ <p>Extracts a specified element from an Erlang tuple.</p>
+ <list type="bulleted">
+ <item><c>position</c> specifies which element to retrieve
+ from <c>tuple</c>. The elements are numbered starting
+ from 1.</item>
+ <item><c>tuple</c> is an Erlang term containing at least
+ <c>position</c> elements.</item>
+ </list>
+ <p>Returns a new Erlang term corresponding to the requested element, or
+ <c>NULL</c> if <c>position</c> was greater
+ than the arity of <c>tuple</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_hd(list)</nametext></name>
+ <fsummary>Extract the first element from a list.</fsummary>
+ <type>
+ <v>ETERM *list;</v>
+ </type>
+ <desc>
+ <p>Extracts the first element from a list.</p>
+ <p><c>list</c> is an Erlang term containing a list.</p>
+ <p>Returns an Erlang term corresponding to the head
+ head element in the list, or a <c>NULL</c> pointer if
+ <c>list</c> was not a list.</p>
</desc>
</func>
+
<func>
<name><ret>void</ret><nametext>erl_init(NULL, 0)</nametext></name>
- <fsummary>Initialization routine</fsummary>
+ <fsummary>Initialization routine.</fsummary>
<type>
<v>void *NULL;</v>
<v>int 0;</v>
</type>
<desc>
- <marker id="erl_init"></marker>
- <p>This function must be called before any of the others in
- the <c><![CDATA[erl_interface]]></c> library in order to initialize the
- library functions. The arguments must be specified as
- <c><![CDATA[erl_init(NULL,0)]]></c>.</p>
+ <p>This function must be called before any of the others in the
+ <c>Erl_Interface</c> library to initialize the
+ library functions. The arguments must be specified as
+ <c>erl_init(NULL,0)</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>ETERM *</ret><nametext>erl_hd(list)</nametext></name>
- <fsummary>Extracts the first element from a list</fsummary>
+ <name><ret>int</ret><nametext>erl_iolist_length(list)</nametext></name>
+ <fsummary>Return the length of an I/O list.</fsummary>
<type>
<v>ETERM *list;</v>
</type>
<desc>
- <p>Extracts the first element from a list.</p>
- <p><c><![CDATA[list]]></c> is an Erlang term containing a list.</p>
- <p>The function returns an Erlang term corresponding to the
- head element in the list, or a NULL pointer if <c><![CDATA[list]]></c> was
- not a list.</p>
+ <p>Returns the length of an I/O list.</p>
+ <p><c>list</c> is an Erlang term containing an I/O list.</p>
+ <p>Returns the length of <c>list</c>, or
+ <c>-1</c> if <c>list</c> is not an I/O list.</p>
+ <p>For the definition of an I/O list, see
+ <seealso marker="#erl_iolist_to_binary">
+ <c>erl_iolist_to_binary</c></seealso>.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_iolist_to_binary(term)</nametext></name>
- <fsummary>Converts an IO list to a binary</fsummary>
+ <fsummary>Convert an I/O list to a binary.</fsummary>
<type>
<v>ETERM *list;</v>
</type>
<desc>
- <p>This function converts an IO list to a binary term.</p>
- <p><c><![CDATA[list]]></c> is an Erlang term containing a list.</p>
- <p>This function an Erlang binary term, or NULL if <c><![CDATA[list]]></c>
- was not an IO list. </p>
- <p>Informally, an IO list is a deep list of characters and
- binaries which can be sent to an Erlang port. In BNF, an IO
- list is formally defined as follows: </p>
+ <p>Converts an I/O list to a binary term.</p>
+ <p><c>list</c> is an Erlang term containing a list.</p>
+ <p>Returns an Erlang binary term, or <c>NULL</c> if
+ <c>list</c> was not an I/O list.</p>
+ <p>Informally, an I/O list is a deep list of characters and
+ binaries that can be sent to an Erlang port. In BNF, an I/O
+ list is formally defined as follows:</p>
<code type="none"><![CDATA[
iolist ::= []
| Binary
@@ -250,158 +287,164 @@ iohead ::= Binary
]]></code>
</desc>
</func>
+
<func>
<name><ret>char *</ret><nametext>erl_iolist_to_string(list)</nametext></name>
- <fsummary>Converts an IO list to a zero terminated string</fsummary>
+ <fsummary>Convert an I/O list to a <c>NULL</c>-terminated string.</fsummary>
<type>
<v>ETERM *list;</v>
</type>
<desc>
- <p>This function converts an IO list to a '\0' terminated C
- string. </p>
- <p><c><![CDATA[list]]></c> is an Erlang term containing an IO list. The IO
- list must not contain the integer 0, since C strings may not
+ <p>Converts an I/O list to a <c>NULL</c>-terminated C string.</p>
+ <p><c>list</c> is an Erlang term containing an I/O list.
+ The I/O list must not contain the integer 0, as C strings may not
contain this value except as a terminating marker.</p>
- <p>This function returns a pointer to a dynamically allocated
- buffer containing a string. If <c><![CDATA[list]]></c> is not an IO list,
- or if <c><![CDATA[list]]></c> contains the integer 0, NULL is returned. It
- is the caller's responsibility free the allocated buffer
- with <c><![CDATA[erl_free()]]></c>. </p>
- <p>Refer to <c><![CDATA[erl_iolist_to_binary()]]></c> for the definition of an
- IO list. </p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>erl_iolist_length(list)</nametext></name>
- <fsummary>Return the length of an IO list</fsummary>
- <type>
- <v>ETERM *list;</v>
- </type>
- <desc>
- <p>Returns the length of an IO list.
- </p>
- <p><c><![CDATA[list]]></c> is an Erlang term containing an IO list. </p>
- <p>The function returns the length of <c><![CDATA[list]]></c>, or -1 if
- <c><![CDATA[list]]></c> is not an IO list.</p>
- <p>Refer to <c><![CDATA[erl_iolist_to_binary()]]></c> for the definition of
- an IO list. </p>
+ <p>Returns a pointer to a dynamically allocated
+ buffer containing a string. If <c>list</c> is not an I/O
+ list, or if <c>list</c> contains the integer 0,
+ <c>NULL</c> is returned. It
+ is the caller's responsibility to free the allocated buffer
+ with <c>erl_free()</c>.</p>
+ <p>For the definition of an I/O list, see
+ <seealso marker="#erl_iolist_to_binary">
+ <c>erl_iolist_to_binary</c></seealso>.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_length(list)</nametext></name>
- <fsummary>Determines the length of a list</fsummary>
+ <fsummary>Determine the length of a list.</fsummary>
<type>
<v>ETERM *list;</v>
</type>
<desc>
<p>Determines the length of a proper list.</p>
- <p><c><![CDATA[list]]></c> is an Erlang term containing proper list. In a
- proper list, all tails except the last point to another list
+ <p><c>list</c> is an Erlang term containing a proper list.
+ In a proper list, all tails except the last point to another list
cell, and the last tail points to an empty list.</p>
- <p>Returns -1 if <c><![CDATA[list]]></c> is not a proper list.</p>
+ <p>Returns <c>-1</c> if <c>list</c> is not a proper
+ list.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_mk_atom(string)</nametext></name>
- <fsummary>Creates an atom</fsummary>
+ <fsummary>Create an atom.</fsummary>
<type>
<v>const char *string;</v>
</type>
<desc>
<p>Creates an atom.</p>
- <p><c><![CDATA[string]]></c> is the sequence of characters that will be
+ <p><c>string</c> is the sequence of characters that will be
used to create the atom.</p>
- <p>Returns an Erlang term containing an atom. Note that it is
- the callers responsibility to make sure that <c><![CDATA[string]]></c>
+ <p>Returns an Erlang term containing an atom. Notice that it is
+ the caller's responsibility to ensure that <c>string</c>
contains a valid name for an atom.</p>
- <p><c><![CDATA[ERL_ATOM_PTR(atom)]]></c> and <c><![CDATA[ERL_ATOM_PTR_UTF8(atom)]]></c>
- can be used to retrieve the atom name (as a null terminated string). <c><![CDATA[ERL_ATOM_SIZE(atom)]]></c>
- and <c><![CDATA[ERL_ATOM_SIZE_UTF8(atom)]]></c> returns the length of the atom name.</p>
- <note><p>Note that the UTF8 variants were introduced in Erlang/OTP releases R16
- and the string returned by <c>ERL_ATOM_PTR(atom)</c> was not null terminated on older releases.</p>
+ <p><c>ERL_ATOM_PTR(atom)</c> and
+ <c>ERL_ATOM_PTR_UTF8(atom)</c>
+ can be used to retrieve the atom name (as a <c>NULL</c>-terminated string).
+ <c>ERL_ATOM_SIZE(atom)</c>
+ and <c>ERL_ATOM_SIZE_UTF8(atom)</c> return the length
+ of the atom name.</p>
+ <note>
+ <p>The UTF-8 variants were introduced in Erlang/OTP R16 and the
+ string returned by <c>ERL_ATOM_PTR(atom)</c> was not
+ <c>NULL</c>-terminated on older releases.</p>
</note>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_mk_binary(bptr, size)</nametext></name>
- <fsummary>Creates a binary object</fsummary>
+ <fsummary>Create a binary object.</fsummary>
<type>
<v>char *bptr;</v>
<v>int size;</v>
</type>
<desc>
- <p>This function produces an Erlang binary object from a
+ <p>Produces an Erlang binary object from a
buffer containing a sequence of bytes.</p>
- <p><c><![CDATA[bptr]]></c> is a pointer to a buffer containing data to be converted.</p>
- <p><c><![CDATA[size]]></c> indicates the length of <c><![CDATA[bptr]]></c>.</p>
- <p>The function returns an Erlang binary object.</p>
- <p><c><![CDATA[ERL_BIN_PTR(bin)]]></c> retrieves a pointer to
- the binary data. <c><![CDATA[ERL_BIN_SIZE(bin)]]></c> retrieves the
- size. </p>
+ <list type="bulleted">
+ <item><c>bptr</c> is a pointer to a buffer containing
+ data to be converted.</item>
+ <item><c>size</c> indicates the length of
+ <c>bptr</c>.</item>
+ </list>
+ <p>Returns an Erlang binary object.</p>
+ <p><c>ERL_BIN_PTR(bin)</c> retrieves a pointer to
+ the binary data. <c>ERL_BIN_SIZE(bin)</c> retrieves the
+ size.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_mk_empty_list()</nametext></name>
- <fsummary>Creates an empty Erlang list</fsummary>
+ <fsummary>Create an empty Erlang list.</fsummary>
<desc>
- <p>This function creates and returns an empty Erlang list.
- Note that NULL is not used to represent an empty list;
+ <p>Creates and returns an empty Erlang list.
+ Notice that <c>NULL</c> is not used to represent an empty list;
Use this function instead.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_mk_estring(string, len)</nametext></name>
- <fsummary>Creates an Erlang string</fsummary>
+ <fsummary>Create an Erlang string.</fsummary>
<type>
<v>char *string;</v>
<v>int len;</v>
</type>
<desc>
- <p>This function creates a list from a sequence of bytes.</p>
- <p><c><![CDATA[string]]></c> is a buffer containing a sequence of
- bytes. The buffer does not need to be zero-terminated.</p>
- <p><c><![CDATA[len]]></c> is the length of <c><![CDATA[string]]></c>.</p>
- <p>The function returns an Erlang list object corresponding to
- the character sequence in <c><![CDATA[string]]></c>.</p>
+ <p>Creates a list from a sequence of bytes.</p>
+ <list type="bulleted">
+ <item><c>string</c> is a buffer containing a sequence of
+ bytes. The buffer does not need to be <c>NULL</c>-terminated.</item>
+ <item><c>len</c> is the length of
+ <c>string</c>.</item>
+ </list>
+ <p>Returns an Erlang list object corresponding to
+ the character sequence in <c>string</c>.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_mk_float(f)</nametext></name>
- <fsummary>Creates an Erlang float</fsummary>
+ <fsummary>Create an Erlang float.</fsummary>
<type>
<v>double f;</v>
</type>
<desc>
<p>Creates an Erlang float.</p>
- <p><c><![CDATA[f]]></c> is a value to be converted to an Erlang float.</p>
- <p></p>
- <p>The function returns an Erlang float object with the value
- specified in <c><![CDATA[f]]></c> or <c><![CDATA[NULL]]></c> if
- <c><![CDATA[f]]></c> is not finite.
- </p>
- <p><c><![CDATA[ERL_FLOAT_VALUE(t)]]></c> can be used to retrieve the
- value from an Erlang float.</p>
+ <p><c>f</c> is a value to be converted to an Erlang
+ float.</p>
+ <p>Returns an Erlang float object with the value
+ specified in <c>f</c> or <c>NULL</c> if
+ <c>f</c> is not finite.</p>
+ <p><c>ERL_FLOAT_VALUE(t)</c> can be used to retrieve the
+ value from an Erlang float.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_mk_int(n)</nametext></name>
- <fsummary>Creates an Erlang integer</fsummary>
+ <fsummary>Create an Erlang integer.</fsummary>
<type>
<v>int n;</v>
</type>
<desc>
<p>Creates an Erlang integer.</p>
- <p><c><![CDATA[n]]></c> is a value to be converted to an Erlang integer.</p>
- <p></p>
- <p>The function returns an Erlang integer object with the
- value specified in <c><![CDATA[n]]></c>.</p>
- <p><c><![CDATA[ERL_INT_VALUE(t)]]></c> can be used to retrieve the value
+ <p><c>n</c> is a value to be converted to an Erlang
+ integer.</p>
+ <p>Returns an Erlang integer object with the
+ value specified in <c>n</c>.</p>
+ <p><c>ERL_INT_VALUE(t)</c> can be used to retrieve the
value from an Erlang integer.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_mk_list(array, arrsize)</nametext></name>
- <fsummary>Creates a list from an array</fsummary>
+ <fsummary>Create a list from an array.</fsummary>
<type>
<v>ETERM **array;</v>
<v>int arrsize;</v>
@@ -409,280 +452,316 @@ iohead ::= Binary
<desc>
<p>Creates an Erlang list from an array of Erlang terms, such
that each element in the list corresponds to one element in
- the array. </p>
- <p><c><![CDATA[array]]></c> is an array of Erlang terms.</p>
- <p><c><![CDATA[arrsize]]></c> is the number of elements in <c><![CDATA[array]]></c>.</p>
+ the array.</p>
+ <list type="bulleted">
+ <item><c>array</c> is an array of Erlang terms.</item>
+ <item><c>arrsize</c> is the number of elements in
+ <c>array</c>.</item>
+ </list>
<p>The function creates an Erlang list object, whose length
- <c><![CDATA[arrsize]]></c> and whose elements are taken from the terms in
- <c><![CDATA[array]]></c>.</p>
+ <c>arrsize</c> and whose elements are taken from the
+ terms in <c>array</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>ETERM *</ret><nametext>erl_mk_pid(node, number, serial, creation)</nametext></name>
- <fsummary>Creates a process identifier</fsummary>
+ <name><ret>ETERM *</ret><nametext>erl_mk_long_ref(node, n1, n2, n3, creation)</nametext></name>
+ <fsummary>Create an Erlang reference.</fsummary>
<type>
<v>const char *node;</v>
- <v>unsigned int number;</v>
- <v>unsigned int serial;</v>
+ <v>unsigned int n1, n2, n3;</v>
<v>unsigned int creation;</v>
</type>
<desc>
- <p>This function creates an Erlang process identifier. The
- resulting pid can be used by Erlang processes wishing to
- communicate with the C node.</p>
- <p><c><![CDATA[node]]></c> is the name of the C node.</p>
- <p><c><![CDATA[number]]></c>, <c><![CDATA[serial]]></c> and <c><![CDATA[creation]]></c> are
- arbitrary numbers. Note though, that these are limited in
- precision, so only the low 15, 3 and 2 bits of these numbers
- are actually used.</p>
- <p>The function returns an Erlang pid object.</p>
- <p><c><![CDATA[ERL_PID_NODE(pid)]]></c>, <c><![CDATA[ERL_PID_NUMBER(pid)]]></c>,
- <c><![CDATA[ERL_PID_SERIAL(pid)]]></c> and <c><![CDATA[ERL_PID_CREATION(pid)]]></c>
- can be used to retrieve the four values used to create the pid.</p>
+ <p>Creates an Erlang reference, with 82 bits.</p>
+ <list type="bulleted">
+ <item><c>node</c> is the name of the C-node.</item>
+ <item><c>n1</c>, <c>n2</c>, and
+ <c>n3</c> can be seen as one big number
+ <c>n1*2^64+n2*2^32+n3</c>, which is to be chosen
+ uniquely for each reference created for a given C-node.</item>
+ <item><c>creation</c> is an arbitrary number.</item>
+ </list>
+ <p>Notice that <c>n3</c> and <c>creation</c>
+ are limited in precision, so only the low 18 and 2 bits of these
+ numbers are used.</p>
+ <p>Returns an Erlang reference object.</p>
+ <p><c>ERL_REF_NODE(ref)</c>,
+ <c>ERL_REF_NUMBERS(ref)</c>,
+ <c>ERL_REF_LEN(ref)</c>, and
+ <c>ERL_REF_CREATION(ref)</c> can be used to retrieve the
+ values used to create the reference.</p>
</desc>
</func>
+
<func>
- <name><ret>ETERM *</ret><nametext>erl_mk_port(node, number, creation)</nametext></name>
- <fsummary>Creates a port identifier</fsummary>
+ <name><ret>ETERM *</ret><nametext>erl_mk_pid(node, number, serial, creation)</nametext></name>
+ <fsummary>Create a process identifier.</fsummary>
<type>
<v>const char *node;</v>
<v>unsigned int number;</v>
+ <v>unsigned int serial;</v>
<v>unsigned int creation;</v>
</type>
<desc>
- <p>This function creates an Erlang port identifier. </p>
- <p><c><![CDATA[node]]></c> is the name of the C node.</p>
- <p><c><![CDATA[number]]></c> and <c><![CDATA[creation]]></c> are arbitrary numbers.
- Note though, that these are limited in
- precision, so only the low 18 and 2 bits of these numbers
- are actually used.</p>
- <p>The function returns an Erlang port object.</p>
- <p><c><![CDATA[ERL_PORT_NODE(port)]]></c>, <c><![CDATA[ERL_PORT_NUMBER(port)]]></c>
- and <c><![CDATA[ERL_PORT_CREATION]]></c> can be used to retrieve the three
- values used to create the port. </p>
+ <p>Creates an Erlang process identifier (pid). The
+ resulting pid can be used by Erlang processes wishing to
+ communicate with the C-node.</p>
+ <list type="bulleted">
+ <item><c>node</c> is the name of the C-node.</item>
+ <item><c>number</c>, <c>serial</c>, and
+ <c>creation</c> are
+ arbitrary numbers. Notice that these are limited in
+ precision, so only the low 15, 3, and 2 bits of these numbers
+ are used.</item>
+ </list>
+ <p>Returns an Erlang pid object.</p>
+ <p><c>ERL_PID_NODE(pid)</c>,
+ <c>ERL_PID_NUMBER(pid)</c>,
+ <c>ERL_PID_SERIAL(pid)</c>, and
+ <c>ERL_PID_CREATION(pid)</c>
+ can be used to retrieve the four values used to create the pid.</p>
</desc>
</func>
+
<func>
- <name><ret>ETERM *</ret><nametext>erl_mk_ref(node, number, creation)</nametext></name>
- <fsummary>Creates an old Erlang reference</fsummary>
+ <name><ret>ETERM *</ret><nametext>erl_mk_port(node, number, creation)</nametext></name>
+ <fsummary>Create a port identifier.</fsummary>
<type>
<v>const char *node;</v>
<v>unsigned int number;</v>
<v>unsigned int creation;</v>
</type>
<desc>
- <p>This function creates an old Erlang reference, with
- only 18 bits - use <c><![CDATA[erl_mk_long_ref]]></c> instead.</p>
- <p><c><![CDATA[node]]></c> is the name of the C node.</p>
- <p><c><![CDATA[number]]></c> should be chosen uniquely for each reference
- created for a given C node.</p>
- <p><c><![CDATA[creation]]></c> is an arbitrary number.</p>
- <p>Note that <c><![CDATA[number]]></c> and <c><![CDATA[creation]]></c> are limited in
- precision, so only the low 18 and 2 bits of these numbers
- are actually used.
- </p>
- <p>The function returns an Erlang reference object.</p>
- <p><c><![CDATA[ERL_REF_NODE(ref)]]></c>, <c><![CDATA[ERL_REF_NUMBER(ref)]]></c>, and
- <c><![CDATA[ERL_REF_CREATION(ref)]]></c> to retrieve the three values used
- to create the reference. </p>
+ <p>Creates an Erlang port identifier.</p>
+ <list type="bulleted">
+ <item><c>node</c> is the name of the C-node.</item>
+ <item><c>number</c> and <c>creation</c> are
+ arbitrary numbers. Notice that these are limited in
+ precision, so only the low 18 and 2 bits of these numbers
+ are used.</item>
+ </list>
+ <p>Returns an Erlang port object.</p>
+ <p><c>ERL_PORT_NODE(port)</c>,
+ <c>ERL_PORT_NUMBER(port)</c>,
+ and <c>ERL_PORT_CREATION</c> can be used to retrieve the
+ three values used to create the port.</p>
</desc>
</func>
+
<func>
- <name><ret>ETERM *</ret><nametext>erl_mk_long_ref(node, n1, n2, n3, creation)</nametext></name>
- <fsummary>Creates an Erlang reference</fsummary>
+ <name><ret>ETERM *</ret><nametext>erl_mk_ref(node, number, creation)</nametext></name>
+ <fsummary>Create an old Erlang reference.</fsummary>
<type>
<v>const char *node;</v>
- <v>unsigned int n1, n2, n3;</v>
+ <v>unsigned int number;</v>
<v>unsigned int creation;</v>
</type>
<desc>
- <p>This function creates an Erlang reference, with 82 bits.</p>
- <p><c><![CDATA[node]]></c> is the name of the C node.</p>
- <p><c><![CDATA[n1]]></c>, <c><![CDATA[n2]]></c> and <c><![CDATA[n3]]></c> can be seen as one big number
- <c><![CDATA[n1*2^64+n2*2^32+n3]]></c> which should be chosen uniquely for
- each reference
- created for a given C node.</p>
- <p><c><![CDATA[creation]]></c> is an arbitrary number.</p>
- <p>Note that <c><![CDATA[n3]]></c> and <c><![CDATA[creation]]></c> are limited in
- precision, so only the low 18 and 2 bits of these numbers
- are actually used.
- </p>
- <p>The function returns an Erlang reference object.</p>
- <p><c><![CDATA[ERL_REF_NODE(ref)]]></c>, <c><![CDATA[ERL_REF_NUMBERS(ref)]]></c>,
- <c><![CDATA[ERL_REF_LEN(ref)]]></c> and
- <c><![CDATA[ERL_REF_CREATION(ref)]]></c> to retrieve the values used
- to create the reference. </p>
+ <p>Creates an old Erlang reference, with
+ only 18 bits - use <c>erl_mk_long_ref</c> instead.</p>
+ <list type="bulleted">
+ <item><c>node</c> is the name of the C-node.</item>
+ <item><c>number</c> is to be chosen uniquely for each
+ reference created for a given C-node.</item>
+ <item><c>creation</c> is an arbitrary number.</item>
+ </list>
+ <p>Notice that <c>number</c> and <c>creation</c>
+ are limited in precision, so only the low 18 and 2 bits of these
+ numbers are used.</p>
+ <p>Returns an Erlang reference object.</p>
+ <p><c>ERL_REF_NODE(ref)</c>,
+ <c>ERL_REF_NUMBER(ref)</c>, and
+ <c>ERL_REF_CREATION(ref)</c> can be used to retrieve the
+ three values used to create the reference.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_mk_string(string)</nametext></name>
- <fsummary>Creates a string</fsummary>
+ <fsummary>Create a string.</fsummary>
<type>
<v>char *string;</v>
</type>
<desc>
- <p>This function creates a list from a zero terminated string.</p>
- <p><c><![CDATA[string]]></c> is the zero-terminated sequence of characters
- (i.e. a C string) from which the list will be created.</p>
- <p>The function returns an Erlang list.</p>
+ <p>Creates a list from a <c>NULL</c>-terminated string.</p>
+ <p><c>string</c> is a <c>NULL</c>-terminated sequence of
+ characters
+ (that is, a C string) from which the list will be created.</p>
+ <p>Returns an Erlang list.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_mk_tuple(array, arrsize)</nametext></name>
- <fsummary>Creates an Erlang tuple from an array</fsummary>
+ <fsummary>Create an Erlang tuple from an array.</fsummary>
<type>
<v>ETERM **array;</v>
<v>int arrsize;</v>
</type>
<desc>
<p>Creates an Erlang tuple from an array of Erlang terms.</p>
- <p><c><![CDATA[array]]></c> is an array of Erlang terms.</p>
- <p><c><![CDATA[arrsize]]></c> is the number of elements in <c><![CDATA[array]]></c>.</p>
+ <list type="bulleted">
+ <item><c>array</c> is an array of Erlang terms.</item>
+ <item><c>arrsize</c> is the number of elements in
+ <c>array</c>.</item>
+ </list>
<p>The function creates an Erlang tuple, whose arity is
- <c><![CDATA[size]]></c> and whose elements are taken from the terms in
- <c><![CDATA[array]]></c>.</p>
- <p>To retrieve the size of a tuple, either use the
- <c><![CDATA[erl_size]]></c> function (which checks the type of the checked
- term and works for a binary as well as for a tuple), or the
- <c><![CDATA[ERL_TUPLE_SIZE(tuple)]]></c> returns the arity of a tuple.
- <c><![CDATA[erl_size()]]></c> will do the same thing, but it checks that
- the argument really is a tuple.
- <c><![CDATA[erl_element(index,tuple)]]></c> returns the element
- corresponding to a given position in the tuple. </p>
+ <c>size</c> and whose elements are taken from the terms
+ in <c>array</c>.</p>
+ <p>To retrieve the size of a tuple, either use function
+ <c>erl_size</c> (which checks the type of the
+ checked term and works for a binary as well as for a tuple) or
+ <c>ERL_TUPLE_SIZE(tuple)</c> returns the arity of a tuple.
+ <c>erl_size()</c> does the same thing, but it checks
+ that the argument is a tuple.
+ <c>erl_element(index,tuple)</c> returns the element
+ corresponding to a given position in the tuple.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_mk_uint(n)</nametext></name>
- <fsummary>Creates an unsigned integer</fsummary>
+ <fsummary>Create an unsigned integer.</fsummary>
<type>
<v>unsigned int n;</v>
</type>
<desc>
<p>Creates an Erlang unsigned integer.</p>
- <p><c><![CDATA[n]]></c> is a value to be converted to an Erlang
+ <p><c>n</c> is a value to be converted to an Erlang
unsigned integer.</p>
- <p></p>
- <p>The function returns an Erlang unsigned integer object with
- the value specified in <c><![CDATA[n]]></c>.</p>
- <p><c><![CDATA[ERL_INT_UVALUE(t)]]></c> can be used to retrieve the
+ <p>Returns an Erlang unsigned integer object with
+ the value specified in <c>n</c>.</p>
+ <p><c>ERL_INT_UVALUE(t)</c> can be used to retrieve the
value from an Erlang unsigned integer.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_mk_var(name)</nametext></name>
- <fsummary>Creates an Erlang variable</fsummary>
+ <fsummary>Create an Erlang variable.</fsummary>
<type>
<v>char *name;</v>
</type>
<desc>
- <p>This function creates an unbound Erlang variable. The
- variable can later be bound through pattern matching or assignment.</p>
- <p><c><![CDATA[name]]></c> specifies a name for the variable.</p>
- <p>The function returns an Erlang variable object with the
- name <c><![CDATA[name]]></c>. </p>
+ <p>Creates an unbound Erlang variable. The variable can later be bound
+ through pattern matching or assignment.</p>
+ <p><c>name</c> specifies a name for the variable.</p>
+ <p>Returns an Erlang variable object with the
+ name <c>name</c>.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_print_term(stream, term)</nametext></name>
- <fsummary>Prints an Erlang term</fsummary>
+ <fsummary>Print an Erlang term.</fsummary>
<type>
<v>FILE *stream;</v>
<v>ETERM *term;</v>
</type>
<desc>
- <p>This function prints the specified Erlang term to the given
- output stream.</p>
- <p><c><![CDATA[stream]]></c> indicates where the function should send its
- output.</p>
- <p><c><![CDATA[term]]></c> is the Erlang term to print.</p>
- <p>The function returns the number of characters written, or a
- negative value if there was an error.</p>
+ <p>Prints the specified Erlang term to the specified output stream.</p>
+ <list type="bulleted">
+ <item><c>stream</c> indicates where the function is to
+ send its output.</item>
+ <item><c>term</c> is the Erlang term to print.</item>
+ </list>
+ <p>Returns the number of characters written on success, otherwise a
+ negative value.</p>
</desc>
</func>
+
<func>
<name><ret>void</ret><nametext>erl_set_compat_rel(release_number)</nametext></name>
- <fsummary>Set the erl_interface library in compatibility mode</fsummary>
+ <fsummary>Set the Erl_Interface library in compatibility mode.</fsummary>
<type>
<v>unsigned release_number;</v>
</type>
<desc>
- <marker id="erl_set_compat_rel"></marker>
- <p>By default, the <c><![CDATA[erl_interface]]></c> library is only guaranteed
- to be compatible with other Erlang/OTP components from the same
- release as the <c><![CDATA[erl_interface]]></c> library itself. For example,
- <c><![CDATA[erl_interface]]></c> from the OTP R10 release is not compatible
- with an Erlang emulator from the OTP R9 release by default.</p>
- <p>A call to <c><![CDATA[erl_set_compat_rel(release_number)]]></c> sets the
- <c><![CDATA[erl_interface]]></c> library in compatibility mode of release
- <c><![CDATA[release_number]]></c>. Valid range of <c><![CDATA[release_number]]></c>
+ <p>By default, the <c>Erl_Interface</c> library is only
+ guaranteed to be compatible with other Erlang/OTP components from the
+ same release as the <c>Erl_Interface</c> library itself.
+ For example, <c>Erl_Interface</c> from Erlang/OTP R10
+ is not compatible
+ with an Erlang emulator from Erlang/OTP R9 by default.</p>
+ <p>A call to <c>erl_set_compat_rel(release_number)</c> sets
+ the <c>Erl_Interface</c> library in compatibility mode of
+ release <c>release_number</c>. Valid range of
+ <c>release_number</c>
is [7, current release]. This makes it possible to
communicate with Erlang/OTP components from earlier releases.</p>
<note>
<p>If this function is called, it may only be called once
- directly after the call to the
- <seealso marker="#erl_init">erl_init()</seealso> function.</p>
+ directly after the call to function
+ <seealso marker="#erl_init">erl_init()</seealso>.</p>
</note>
<warning>
<p>You may run into trouble if this feature is used
- carelessly. Always make sure that all communicating
+ carelessly. Always ensure that all communicating
components are either from the same Erlang/OTP release, or
from release X and release Y where all components
from release Y are in compatibility mode of release X.</p>
</warning>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_size(term)</nametext></name>
- <fsummary>Return the arity of a tuple or binary</fsummary>
+ <fsummary>Return the arity of a tuple or binary.</fsummary>
<type>
<v>ETERM *term;</v>
</type>
<desc>
- <p>Returns the arity of an Erlang tuple, or the
- number of bytes in an Erlang binary object. </p>
- <p><c><![CDATA[term]]></c> is an Erlang tuple or an Erlang binary object.</p>
- <p>The function returns the size of <c><![CDATA[term]]></c> as described
- above, or -1 if <c><![CDATA[term]]></c> is not one of the two supported
- types. </p>
+ <p>Returns either the arity of an Erlang tuple or the
+ number of bytes in an Erlang binary object.</p>
+ <p><c>term</c> is an Erlang tuple or an Erlang binary
+ object.</p>
+ <p>Returns the size of <c>term</c> as described
+ above, or <c>-1</c> if <c>term</c> is not one of the two
+ supported types.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_tl(list)</nametext></name>
- <fsummary>Extracts the tail from a list</fsummary>
+ <fsummary>Extract the tail from a list.</fsummary>
<type>
<v>ETERM *list;</v>
</type>
<desc>
<p>Extracts the tail from a list.</p>
- <p><c><![CDATA[list]]></c> is an Erlang term containing a list.</p>
- <p>The function returns an Erlang list corresponding to the
- original list minus the first element, or NULL pointer if
- <c><![CDATA[list]]></c> was not a list.</p>
+ <p><c>list</c> is an Erlang term containing a list.</p>
+ <p>Returns an Erlang list corresponding to the
+ original list minus the first element, or <c>NULL</c> pointer if
+ <c>list</c> was not a list.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_var_content(term, name)</nametext></name>
- <fsummary>Extracts the content of a variable</fsummary>
+ <fsummary>Extract the content of a variable.</fsummary>
<type>
<v>ETERM *term;</v>
<v>char *name;</v>
</type>
<desc>
- <p>This function returns the contents of the specified
- variable in an Erlang term.
- </p>
- <p><c><![CDATA[term]]></c> is an Erlang term. In order for this function
- to succeed, <c><![CDATA[term]]></c> must be an Erlang variable with the
- specified name, or it must be an Erlang list or tuple
- containing a variable with the specified name. Other Erlang
- types cannot contain variables.</p>
- <p><c><![CDATA[name]]></c> is the name of an Erlang variable.</p>
+ <p>Returns the contents of the specified variable in an Erlang term.</p>
+ <list type="bulleted">
+ <item><c>term</c> is an Erlang term. In order for this
+ function to succeed,
+ <c>term</c> must either be an Erlang variable with
+ the specified name, or it must be an Erlang list or tuple
+ containing a variable with the specified name. Other Erlang
+ types cannot contain variables.</item>
+ <item><c>name</c> is the name of an Erlang variable.
+ </item>
+ </list>
<p>Returns the Erlang object corresponding to the value of
- <c><![CDATA[name]]></c> in <c><![CDATA[term]]></c>. If no variable with the name
- <c><![CDATA[name]]></c> was found in <c><![CDATA[term]]></c>, or if <c><![CDATA[term]]></c> is
- not a valid Erlang term, NULL is returned.</p>
+ <c>name</c> in <c>term</c>. If no variable
+ with the name <c>name</c> is found in
+ <c>term</c>, or if <c>term</c> is
+ not a valid Erlang term, <c>NULL</c> is returned.</p>
</desc>
</func>
</funcs>
</cref>
-
diff --git a/lib/erl_interface/doc/src/erl_format.xml b/lib/erl_interface/doc/src/erl_format.xml
index 6e3ac4f0c9..5b8b7b5e78 100644
--- a/lib/erl_interface/doc/src/erl_format.xml
+++ b/lib/erl_interface/doc/src/erl_format.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>erl_format</title>
@@ -28,51 +28,42 @@
<docno></docno>
<approved>Bjarne D&auml;cker</approved>
<checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
- <date>961016</date>
+ <date>1996-10-16</date>
<rev>A</rev>
- <file>erl_format.sgml</file>
+ <file>erl_format.xml</file>
</header>
<lib>erl_format</lib>
- <libsummary>Create and Match Erlang Terms</libsummary>
+ <libsummary>Create and match Erlang terms.</libsummary>
<description>
- <p>This module contains two routines - one general function for
+ <p>This module contains two routines: one general function for
creating Erlang terms and one for pattern matching Erlang terms.</p>
</description>
+
<funcs>
<func>
- <name><ret>ETERM *</ret><nametext>erl_format(FormatStr, ... )</nametext></name>
- <fsummary>Creates an Erlang term</fsummary>
+ <name><ret>ETERM *</ret><nametext>erl_format(FormatStr, ...)</nametext></name>
+ <fsummary>Create an Erlang term.</fsummary>
<type>
<v>char *FormatStr;</v>
</type>
<desc>
- <p>This is a general function for creating Erlang terms using
+ <p>A general function for creating Erlang terms using
a format specifier and a corresponding set of arguments, much
- in the way <c><![CDATA[printf()]]></c> works.</p>
- <p><c><![CDATA[FormatStr]]></c> is a format specification string. The set
- of valid format specifiers is as follows:</p>
+ in the way <c>printf()</c> works.</p>
+ <p><c>FormatStr</c> is a format specification string.
+ The valid format specifiers are as follows:</p>
<list type="bulleted">
- <item>
- <p>~i - Integer</p>
- </item>
- <item>
- <p>~f - Floating point</p>
- </item>
- <item>
- <p>~a - Atom</p>
- </item>
- <item>
- <p>~s - String</p>
- </item>
- <item>
- <p>~w - Arbitrary Erlang term</p>
- </item>
+ <item><c>~i</c> - Integer</item>
+ <item><c>~f</c> - Floating point</item>
+ <item><c>~a</c> - Atom</item>
+ <item><c>~s</c> - String</item>
+ <item><c>~w</c> - Arbitrary Erlang term</item>
</list>
- <p>For each format specifier that appears in <c><![CDATA[FormatStr]]></c>,
+ <p>For each format specifier included in <c>FormatStr</c>,
there must be a corresponding argument following
- <c><![CDATA[FormatStr]]></c>. An Erlang term is built according to the
- <c><![CDATA[FormatStr]]></c> with values and Erlang terms substituted from
- the corresponding arguments and according to the individual
+ <c>FormatStr</c>. An Erlang term is built according to
+ <c>FormatStr</c> with values and Erlang terms substituted
+ from the corresponding arguments, and according to the individual
format specifiers. For example:</p>
<code type="none"><![CDATA[
erl_format("[{name,~a},{age,~i},{data,~w}]",
@@ -80,34 +71,40 @@ erl_format("[{name,~a},{age,~i},{data,~w}]",
21,
erl_format("[{adr,~s,~i}]","E-street",42));
]]></code>
- <p>This will create an <c><![CDATA[(ETERM *)]]></c> structure corresponding
- to the Erlang term:
- <c><![CDATA[[{name,madonna},{age,21},{data,[{adr,"E-street",42}]}]]]></c></p>
- <p>The function returns an Erlang term, or NULL if
- <c><![CDATA[FormatStr]]></c> does not describe a valid Erlang term.</p>
+ <p>This creates an <c>(ETERM *)</c> structure corresponding
+ to the Erlang term
+ <c>[{name,madonna},{age,21},{data,[{adr,"E-street",42}]}]</c></p>
+ <p>The function returns an Erlang term, or <c>NULL</c> if
+ <c>FormatStr</c> does not describe a valid Erlang
+ term.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_match(Pattern, Term)</nametext></name>
- <fsummary>Performs pattern matching</fsummary>
+ <fsummary>Perform pattern matching.</fsummary>
<type>
<v>ETERM *Pattern,*Term;</v>
</type>
<desc>
<p>This function is used to perform pattern matching similar
- to that done in Erlang. Refer to an Erlang manual for matching
- rules and more examples.</p>
- <p><c><![CDATA[Pattern]]></c> is an Erlang term, possibly containing unbound
- variables. </p>
- <p><c><![CDATA[Term]]></c> is an Erlang term that we wish to match against
- <c><![CDATA[Pattern]]></c>.</p>
- <p><c><![CDATA[Term]]></c> and <c><![CDATA[Pattern]]></c> are compared, and any
- unbound variables in <c><![CDATA[Pattern]]></c> are bound to corresponding
- values in <c><![CDATA[Term]]></c>. </p>
- <p>If <c><![CDATA[Term]]></c> and <c><![CDATA[Pattern]]></c> can be matched, the
- function returns a non-zero value and binds any unbound
- variables in <c><![CDATA[Pattern]]></c>. If <c><![CDATA[Term]]></c> <c><![CDATA[Pattern]]></c> do
- not match, the function returns 0. For example:</p>
+ to that done in Erlang. For matching rules and more examples, see
+ section <seealso marker="doc/reference_manual:patterns">
+ Pattern Matching</seealso> in the Erlang Reference Manual.</p>
+ <list type="bulleted">
+ <item><c>Pattern</c> is an Erlang term, possibly
+ containing unbound variables.</item>
+ <item><c>Term</c> is an Erlang term that we wish to match
+ against <c>Pattern</c>.</item>
+ </list>
+ <p><c>Term</c> and <c>Pattern</c> are compared
+ and any unbound variables in <c>Pattern</c> are bound to
+ corresponding values in <c>Term</c>.</p>
+ <p>If <c>Term</c> and <c>Pattern</c> can be
+ matched, the function returns a non-zero value and binds any unbound
+ variables in <c>Pattern</c>. If <c>Term</c>
+ and <c>Pattern</c> do
+ not match, <c>0</c> is returned. For example:</p>
<code type="none"><![CDATA[
ETERM *term, *pattern, *pattern2;
term1 = erl_format("{14,21}");
@@ -132,11 +129,10 @@ if (erl_match(pattern2, term2)) {
...
}
]]></code>
- <p><c><![CDATA[erl_var_content()]]></c> can be used to retrieve the
+ <p><c>erl_var_content()</c> can be used to retrieve the
content of any variables bound as a result of a call to
- <c><![CDATA[erl_match()]]></c>.</p>
+ <c>erl_match()</c>.</p>
</desc>
</func>
</funcs>
</cref>
-
diff --git a/lib/erl_interface/doc/src/erl_global.xml b/lib/erl_interface/doc/src/erl_global.xml
index d6bfffc69d..2fa0045adf 100644
--- a/lib/erl_interface/doc/src/erl_global.xml
+++ b/lib/erl_interface/doc/src/erl_global.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>erl_global</title>
@@ -28,115 +28,125 @@
<docno></docno>
<approved>Gordon Beaton</approved>
<checked>Gordon Beaton</checked>
- <date>980703</date>
+ <date>1998-07-03</date>
<rev>A</rev>
- <file>erl_global.sgml</file>
+ <file>erl_global.xml</file>
</header>
<lib>erl_global</lib>
- <libsummary>Access globally registered names</libsummary>
+ <libsummary>Access globally registered names.</libsummary>
<description>
<p>This module provides support for registering, looking
- up and unregistering names in the Erlang Global module. For more
- information, see the description of Global in the reference manual.</p>
- <p>Note that the functions below perform an RPC using an open file
- descriptor provided by the caller. This file descriptor must
- not be used for other traffic during the global operation or the
- function may receive unexpected data and fail.</p>
+ up, and unregistering names in the <c>global</c> module.
+ For more information, see
+ <seealso marker="kernel:global"><c>kernel:global</c></seealso>.</p>
+
+ <p>Notice that the functions below perform an RPC using an open file
+ descriptor provided by the caller. This file descriptor must
+ not be used for other traffic during the global operation, as the
+ function can then receive unexpected data and fail.</p>
</description>
+
<funcs>
<func>
<name><ret>char **</ret><nametext>erl_global_names(fd,count)</nametext></name>
- <fsummary>Obtain list of Global names</fsummary>
+ <fsummary>Obtain list of global names.</fsummary>
<type>
<v>int fd;</v>
<v>int *count;</v>
</type>
<desc>
- <p>Retrieve a list of all known global names.
- </p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.
- </p>
- <p><c><![CDATA[count]]></c> is the address of an integer, or NULL. If
- <c><![CDATA[count]]></c> is not NULL, it will be set by the function to
- the number of names found.
- </p>
+ <p>Retrieves a list of all known global names.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open descriptor to an Erlang
+ connection.</item>
+ <item><c>count</c> is the address of an integer, or
+ <c>NULL</c>. If <c>count</c> is not <c>NULL</c>, it is
+ set by the function to the number of names found.</item>
+ </list>
<p>On success, the function returns an array of strings, each
- containing a single registered name, and sets <c><![CDATA[count]]></c> to
+ containing a single registered name, and sets
+ <c>count</c> to
the number of names found. The array is terminated
- by a single NULL pointer. On failure, the function returns
- NULL and <c><![CDATA[count]]></c> is not modified.
- </p>
+ by a single <c>NULL</c> pointer. On failure, the function returns
+ <c>NULL</c> and <c>count</c> is not modified.</p>
<note>
<p>It is the caller's responsibility to free the array
afterwards. It has been allocated by the function with a
- single call to <c><![CDATA[malloc()]]></c>, so a single <c><![CDATA[free()]]></c> is
- all that is necessary.</p>
+ single call to <c>malloc()</c>, so a single
+ <c>free()</c> is all that is necessary.</p>
</note>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_global_register(fd,name,pid)</nametext></name>
- <fsummary>Register a name in Global</fsummary>
+ <fsummary>Register a name in global.</fsummary>
<type>
<v>int fd;</v>
<v>const char *name;</v>
<v>ETERM *pid;</v>
</type>
<desc>
- <p>This function registers a name in Global.
- </p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.
- </p>
- <p><c><![CDATA[name]]></c> is the name to register in Global.
- </p>
- <p><c><![CDATA[pid]]></c> is the pid that should be associated with
- <c><![CDATA[name]]></c>. This is the value that Global will return when
- processes request the location of <c><![CDATA[name]]></c>.
- </p>
- <p>The function returns 0 on success, or -1 on failure.</p>
+ <p>Registers a name in <c>global</c>.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open descriptor to an Erlang
+ connection.</item>
+ <item><c>name</c> is the name to register in
+ <c>global</c>.</item>
+ <item><c>pid</c> is the pid that is to be associated with
+ <c>name</c>. This value is returned by <c>global</c>
+ when processes request the location of <c>name</c>.
+ </item>
+ </list>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_global_unregister(fd,name)</nametext></name>
- <fsummary>Unregister a name in Global</fsummary>
+ <fsummary>Unregister a name from global.</fsummary>
<type>
<v>int fd;</v>
<v>const char *name;</v>
</type>
<desc>
- <p>This function unregisters a name from Global.
- </p>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.
- </p>
- <p><c><![CDATA[name]]></c> is the name to unregister from Global.
- </p>
- <p>The function returns 0 on success, or -1 on failure.</p>
+ <p>Unregisters a name from <c>global</c>.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open descriptor to an Erlang
+ connection.</item>
+ <item><c>name</c> is the name to unregister from
+ <c>global</c>.</item>
+ </list>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_global_whereis(fd,name,node)</nametext></name>
- <fsummary>Look up a name in global</fsummary>
+ <fsummary>Look up a name in global.</fsummary>
<type>
<v>int fd;</v>
<v>const char *name;</v>
<v>char *node;</v>
</type>
<desc>
- <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.
- </p>
- <p><c><![CDATA[name]]></c> is the name that is to be looked up in Global.
- </p>
- <p>If <c><![CDATA[node]]></c> is not NULL, it is a pointer to a buffer
- where the function can fill in the name of the node where
- <c><![CDATA[name]]></c> is found. <c><![CDATA[node]]></c> can be passed directly to
- <c><![CDATA[erl_connect()]]></c> if necessary.
- </p>
- <p>On success, the function returns an Erlang Pid containing the address
- of the given name, and node will be initialized to
- the nodename where <c><![CDATA[name]]></c> is found. On failure NULL will be
- returned and <c><![CDATA[node]]></c> will not be modified.</p>
+ <p>Looks up a name in <c>global</c>.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open descriptor to an Erlang
+ connection.</item>
+ <item><c>name</c> is the name that is to be looked up in
+ <c>global</c>.</item>
+ </list>
+ <p>If <c>node</c> is not <c>NULL</c>, it is a pointer to a
+ buffer where the function can fill in the name of the node where
+ <c>name</c> is found. <c>node</c> can be
+ passed directly to <c>erl_connect()</c> if necessary.</p>
+ <p>On success, the function returns an Erlang pid containing the address
+ of the specified name, and the node is initialized to
+ the node name where <c>name</c> is found. On failure,
+ <c>NULL</c> is returned and <c>node</c> is not
+ modified.</p>
</desc>
</func>
</funcs>
</cref>
-
diff --git a/lib/erl_interface/doc/src/erl_interface.xml b/lib/erl_interface/doc/src/erl_interface.xml
index a9d421bbeb..4e66655b39 100644
--- a/lib/erl_interface/doc/src/erl_interface.xml
+++ b/lib/erl_interface/doc/src/erl_interface.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>The Erl_Interface Library</title>
@@ -72,51 +72,51 @@ Eshell V4.7.4 (abort with ^G)
1> code:root_dir().
/usr/local/otp ]]></code>
<p>To compile your code, make sure that your C compiler knows where
- to find <c><![CDATA[erl_interface.h]]></c> by specifying an appropriate <c><![CDATA[-I]]></c>
- argument on the command line, or by adding it to the <c><![CDATA[CFLAGS]]></c>
- definition in your <c><![CDATA[Makefile]]></c>. The correct value for this path is
- <c><![CDATA[$OTPROOT/lib/erl_interface]]></c><em>Vsn</em><c><![CDATA[/include]]></c>, where <c><![CDATA[$OTPROOT]]></c> is the path
- reported by <c><![CDATA[code:root_dir/0]]></c> in the above example, and <em>Vsn</em> is
+ to find <c>erl_interface.h</c> by specifying an appropriate <c>-I</c>
+ argument on the command line, or by adding it to the <c>CFLAGS</c>
+ definition in your <c>Makefile</c>. The correct value for this path is
+ <c>$OTPROOT/lib/erl_interface</c><em>Vsn</em><c>/include</c>, where <c>$OTPROOT</c> is the path
+ reported by <c>code:root_dir/0</c> in the above example, and <em>Vsn</em> is
the version of the Erl_interface application, for example
- <c><![CDATA[erl_interface-3.2.3]]></c></p>
+ <c>erl_interface-3.2.3</c></p>
<code type="none"><![CDATA[
$ cc -c -I/usr/local/otp/lib/erl_interface-3.2.3/include myprog.c ]]></code>
<p>When linking, you will need to specify the path to
- <c><![CDATA[liberl_interface.a]]></c> and <c><![CDATA[libei.a]]></c> with
- <c><![CDATA[-L$OTPROOT/lib/erl_interface-3.2.3/lib]]></c>, and you will need to specify the
- name of the libraries with <c><![CDATA[-lerl_interface -lei]]></c>. You can do
- this on the command line or by adding the flags to the <c><![CDATA[LDFLAGS]]></c>
- definition in your <c><![CDATA[Makefile]]></c>.</p>
+ <c>liberl_interface.a</c> and <c>libei.a</c> with
+ <c>-L$OTPROOT/lib/erl_interface-3.2.3/lib</c>, and you will need to specify the
+ name of the libraries with <c>-lerl_interface -lei</c>. You can do
+ this on the command line or by adding the flags to the <c>LDFLAGS</c>
+ definition in your <c>Makefile</c>.</p>
<code type="none"><![CDATA[
$ ld -L/usr/local/otp/lib/erl_interface-3.2.3/
lib myprog.o -lerl_interface -lei -o myprog ]]></code>
<p>Also, on some systems it may be necessary to link with some
- additional libraries (e.g. <c><![CDATA[libnsl.a]]></c> and <c><![CDATA[libsocket.a]]></c> on
- Solaris, or <c><![CDATA[wsock32.lib]]></c> on Windows) in order to use the
+ additional libraries (e.g. <c>libnsl.a</c> and <c>libsocket.a</c> on
+ Solaris, or <c>wsock32.lib</c> on Windows) in order to use the
communication facilities of Erl_Interface.</p>
<p>If you are using Erl_Interface functions in a threaded
application based on POSIX threads or Solaris threads, then
Erl_Interface needs access to some of the synchronization
facilities in your threads package, and you will need to specify
additional compiler flags in order to indicate which of the packages
- you are using. Define <c><![CDATA[_REENTRANT]]></c> and either <c><![CDATA[STHREADS]]></c> or
- <c><![CDATA[PTHREADS]]></c>. The default is to use POSIX threads if
- <c><![CDATA[_REENTRANT]]></c> is specified.</p>
+ you are using. Define <c>_REENTRANT</c> and either <c>STHREADS</c> or
+ <c>PTHREADS</c>. The default is to use POSIX threads if
+ <c>_REENTRANT</c> is specified.</p>
<p>Note that both single threaded and default versions of the Erl_interface
and Ei libraries are provided. (The single threaded versions are named
- <c><![CDATA[liberl_interface_st]]></c> and <c><![CDATA[libei_st]]></c>). Whether the default
+ <c>liberl_interface_st</c> and <c>libei_st</c>). Whether the default
versions of the libraries have support for threads or not is determined by if
the platform in question has support for POSIX or Solaris threads. To check this,
- have a look in the <c><![CDATA[eidefs.mk]]></c> file in the erl_interface src directory.</p>
+ have a look in the <c>eidefs.mk</c> file in the erl_interface src directory.</p>
</section>
<section>
<title>Initializing the erl_interface Library</title>
<p>Before calling any of the other Erl_Interface functions, you
- must call <c><![CDATA[erl_init()]]></c> exactly once to initialize the library.
- <c><![CDATA[erl_init()]]></c> takes two arguments, however the arguments are no
+ must call <c>erl_init()</c> exactly once to initialize the library.
+ <c>erl_init()</c> takes two arguments, however the arguments are no
longer used by Erl_Interface, and should therefore be specified
- as <c><![CDATA[erl_init(NULL,0)]]></c>.</p>
+ as <c>erl_init(NULL,0)</c>.</p>
</section>
<section>
@@ -129,7 +129,7 @@ $ ld -L/usr/local/otp/lib/erl_interface-3.2.3/
number of C functions which create and manipulate Erlang data
structures. The library also contains an encode and a decode function.
The example below shows how to create and encode an Erlang tuple
- <c><![CDATA[{tobbe,3928}]]></c>:</p>
+ <c>{tobbe,3928}</c>:</p>
<code type="none"><![CDATA[
ETERM *arr[2], *tuple;
@@ -140,26 +140,26 @@ arr[0] = erl_mk_atom("tobbe");
arr[1] = erl_mk_integer(3928);
tuple = erl_mk_tuple(arr, 2);
i = erl_encode(tuple, buf); ]]></code>
- <p>Alternatively, you can use <c><![CDATA[erl_send()]]></c> and
- <c><![CDATA[erl_receive_msg]]></c>, which handle the encoding and decoding of
+ <p>Alternatively, you can use <c>erl_send()</c> and
+ <c>erl_receive_msg</c>, which handle the encoding and decoding of
messages transparently.</p>
<p>Refer to the Reference Manual for a complete description of the
following modules:</p>
<list type="bulleted">
- <item>the <c><![CDATA[erl_eterm]]></c> module for creating Erlang terms</item>
- <item>the <c><![CDATA[erl_marshal]]></c> module for encoding and decoding routines.</item>
+ <item>the <c>erl_eterm</c> module for creating Erlang terms</item>
+ <item>the <c>erl_marshal</c> module for encoding and decoding routines.</item>
</list>
</section>
<section>
<title>Building Terms and Patterns</title>
- <p>The previous example can be simplified by using
- <c><![CDATA[erl_format()]]></c> to create an Erlang term.</p>
+ <p>The previous example can be simplified by using
+ <c>erl_format()</c> to create an Erlang term.</p>
<code type="none"><![CDATA[
ETERM *ep;
ep = erl_format("{~a,~i}", "tobbe", 3928); ]]></code>
- <p>Refer to the Reference Manual, the <c><![CDATA[erl_format]]></c> module, for a
+ <p>Refer to the Reference Manual, the <c>erl_format</c> module, for a
full description of the different format directives. The following
example is more complex:</p>
<code type="none"><![CDATA[
@@ -171,10 +171,10 @@ ep = erl_format("[{name,~a},{age,~i},{data,~w}]",
erl_format("[{adr,~s,~i}]", "E-street", 42));
erl_free_compound(ep); ]]></code>
<p>As in previous examples, it is your responsibility to free the
- memory allocated for Erlang terms. In this example,
- <c><![CDATA[erl_free_compound()]]></c> ensures that the complete term pointed to
- by <c><![CDATA[ep]]></c> is released. This is necessary, because the pointer from
- the second call to <c><![CDATA[erl_format()]]></c> is lost. </p>
+ memory allocated for Erlang terms. In this example,
+ <c>erl_free_compound()</c> ensures that the complete term pointed to
+ by <c>ep</c> is released. This is necessary, because the pointer from
+ the second call to <c>erl_format()</c> is lost. </p>
<p>The following
example shows a slightly different solution:</p>
<code type="none"><![CDATA[
@@ -186,7 +186,7 @@ ep = erl_format("[{name,~a},{age,~i},{data,~w}]",
erl_free_term(ep);
erl_free_term(ep2); ]]></code>
<p>In this case, you free the two terms independently. The order in
- which you free the terms <c><![CDATA[ep]]></c> and <c><![CDATA[ep2]]></c> is not important,
+ which you free the terms <c>ep</c> and <c>ep2</c> is not important,
because the Erl_Interface library uses reference counting to
determine when it is safe to actually remove objects. </p>
<p>If you are not sure whether you have freed the terms properly, you
@@ -204,14 +204,14 @@ printf("length of freelist: %ld\
/* really free the freelist */
erl_eterm_release();
]]></code>
- <p>Refer to the Reference Manual, the <c><![CDATA[erl_malloc]]></c> module for more
+ <p>Refer to the Reference Manual, the <c>erl_malloc</c> module for more
information.</p>
</section>
<section>
<title>Pattern Matching</title>
<p>An Erlang pattern is a term that may contain unbound variables or
- <c><![CDATA["do not care"]]></c> symbols. Such a pattern can be matched against a
+ <c>"do not care"</c> symbols. Such a pattern can be matched against a
term and, if the match is successful, any unbound variables in the
pattern will be bound as a side effect. The content of a bound
variable can then be retrieved.</p>
@@ -219,13 +219,13 @@ erl_eterm_release();
ETERM *pattern;
pattern = erl_format("{madonna,Age,_}"); ]]></code>
- <p><c><![CDATA[erl_match()]]></c> is used to perform pattern matching. It takes a
+ <p><c>erl_match()</c> is used to perform pattern matching. It takes a
pattern and a term and tries to match them. As a side effect any unbound
variables in the pattern will be bound. In the following example, we
create a pattern with a variable <em>Age</em> which appears at two
positions in the tuple. The pattern match is performed as follows:</p>
<list type="ordered">
- <item><c><![CDATA[erl_match()]]></c> will bind the contents of
+ <item><c>erl_match()</c> will bind the contents of
<em>Age</em> to <em>21</em> the first time it reaches the variable</item>
<item>the second occurrence of <em>Age</em> will cause a test for
equality between the terms since <em>Age</em> is already bound to
@@ -248,14 +248,14 @@ if (erl_match(pattern, term)) {
}
erl_free_term(pattern);
erl_free_term(term); ]]></code>
- <p>Refer to the Reference Manual, the <c><![CDATA[erl_match()]]></c> function for
+ <p>Refer to the Reference Manual, the <c>erl_match()</c> function for
more information.</p>
</section>
<section>
<title>Connecting to a Distributed Erlang Node</title>
<p>In order to connect to a distributed Erlang node you need to first
- initialize the connection routine with <c><![CDATA[erl_connect_init()]]></c>,
+ initialize the connection routine with <c>erl_connect_init()</c>,
which stores information such as the host name, node name, and IP
address for later use:</p>
<code type="none"><![CDATA[
@@ -263,9 +263,9 @@ int identification_number = 99;
int creation=1;
char *cookie="a secret cookie string"; /* An example */
erl_connect_init(identification_number, cookie, creation); ]]></code>
- <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information.</p>
+ <p>Refer to the Reference Manual, the <c>erl_connect</c> module for more information.</p>
<p>After initialization, you set up the connection to the Erlang node.
- Use <c><![CDATA[erl_connect()]]></c> to specify the Erlang node you want to
+ Use <c>erl_connect()</c> to specify the Erlang node you want to
connect to. The following example sets up the connection and should
result in a valid socket file descriptor:</p>
<code type="none"><![CDATA[
@@ -273,45 +273,45 @@ int sockfd;
char *nodename="[email protected]"; /* An example */
if ((sockfd = erl_connect(nodename)) < 0)
erl_err_quit("ERROR: erl_connect failed"); ]]></code>
- <p><c><![CDATA[erl_err_quit()]]></c> prints the specified string and terminates
- the program. Refer to the Reference Manual, the <c><![CDATA[erl_error()]]></c>
+ <p><c>erl_err_quit()</c> prints the specified string and terminates
+ the program. Refer to the Reference Manual, the <c>erl_error()</c>
function for more information.</p>
</section>
<section>
<title>Using EPMD</title>
- <p><c><![CDATA[Epmd]]></c> is the Erlang Port Mapper Daemon. Distributed Erlang nodes
- register with <c><![CDATA[epmd]]></c> on the localhost to indicate to other nodes that
- they exist and can accept connections. <c><![CDATA[Epmd]]></c> maintains a register of
+ <p><c>Epmd</c> is the Erlang Port Mapper Daemon. Distributed Erlang nodes
+ register with <c>epmd</c> on the localhost to indicate to other nodes that
+ they exist and can accept connections. <c>Epmd</c> maintains a register of
node and port number information, and when a node wishes to connect to
- another node, it first contacts <c><![CDATA[epmd]]></c> in order to find out the correct
+ another node, it first contacts <c>epmd</c> in order to find out the correct
port number to connect to.</p>
- <p>When you use <c><![CDATA[erl_connect()]]></c> to connect to an Erlang node, a
- connection is first made to <c><![CDATA[epmd]]></c> and, if the node is known, a
+ <p>When you use <c>erl_connect()</c> to connect to an Erlang node, a
+ connection is first made to <c>epmd</c> and, if the node is known, a
connection is then made to the Erlang node.</p>
- <p>C nodes can also register themselves with <c><![CDATA[epmd]]></c> if they want other
+ <p>C nodes can also register themselves with <c>epmd</c> if they want other
nodes in the system to be able to find and connect to them.</p>
- <p>Before registering with <c><![CDATA[epmd]]></c>, you need to first create a listen socket
+ <p>Before registering with <c>epmd</c>, you need to first create a listen socket
and bind it to a port. Then:</p>
<code type="none"><![CDATA[
int pub;
pub = erl_publish(port); ]]></code>
- <p><c><![CDATA[pub]]></c> is a file descriptor now connected to <c><![CDATA[epmd]]></c>. <c><![CDATA[Epmd]]></c>
+ <p><c>pub</c> is a file descriptor now connected to <c>epmd</c>. <c>Epmd</c>
monitors the other end of the connection, and if it detects that the
connection has been closed, the node will be unregistered. So, if you
explicitly close the descriptor or if your node fails, it will be
- unregistered from <c><![CDATA[epmd]]></c>.</p>
+ unregistered from <c>epmd</c>.</p>
<p>Be aware that on some systems (such as VxWorks), a failed node will
not be detected by this mechanism since the operating system does not
automatically close descriptors that were left open when the node
- failed. If a node has failed in this way, <c><![CDATA[epmd]]></c> will prevent you from
+ failed. If a node has failed in this way, <c>epmd</c> will prevent you from
registering a new node with the old name, since it thinks that the old
name is still in use. In this case, you must unregister the name
explicitly:</p>
<code type="none"><![CDATA[
erl_unpublish(node); ]]></code>
- <p>This will cause <c><![CDATA[epmd]]></c> to close the connection from the far end. Note
+ <p>This will cause <c>epmd</c> to close the connection from the far end. Note
that if the name was in fact still in use by a node, the results of
this operation are unpredictable. Also, doing this does not cause the
local end of the connection to close, so resources may be consumed.</p>
@@ -321,8 +321,8 @@ erl_unpublish(node); ]]></code>
<title>Sending and Receiving Erlang Messages</title>
<p>Use one of the following two functions to send messages:</p>
<list type="bulleted">
- <item><c><![CDATA[erl_send()]]></c></item>
- <item><c><![CDATA[erl_reg_send()]]></c></item>
+ <item><c>erl_send()</c></item>
+ <item><c>erl_reg_send()</c></item>
</list>
<p>As in Erlang, it is possible to send messages to a
<em>Pid</em> or to a registered name. It is easier to send a
@@ -330,17 +330,17 @@ erl_unpublish(node); ]]></code>
a suitable <em>Pid</em>.</p>
<p>Use one of the following two functions to receive messages:</p>
<list type="bulleted">
- <item><c><![CDATA[erl_receive()]]></c></item>
- <item><c><![CDATA[erl_receive_msg()]]></c></item>
+ <item><c>erl_receive()</c></item>
+ <item><c>erl_receive_msg()</c></item>
</list>
- <p><c><![CDATA[erl_receive()]]></c> receives the message into a buffer, while
- <c><![CDATA[erl_receive_msg()]]></c> decodes the message into an Erlang term. </p>
+ <p><c>erl_receive()</c> receives the message into a buffer, while
+ <c>erl_receive_msg()</c> decodes the message into an Erlang term. </p>
<section>
<title>Example of Sending Messages</title>
- <p>In the following example, <c><![CDATA[{Pid, hello_world}]]></c> is
- sent to a registered process <c><![CDATA[my_server]]></c>. The message is encoded
- by <c><![CDATA[erl_send()]]></c>:</p>
+ <p>In the following example, <c>{Pid, hello_world}</c> is
+ sent to a registered process <c>my_server</c>. The message is encoded
+ by <c>erl_send()</c>:</p>
<code type="none"><![CDATA[
extern const char *erl_thisnodename(void);
extern short erl_thiscreation(void);
@@ -355,15 +355,15 @@ emsg = erl_mk_tuple(arr, 2);
erl_reg_send(sockfd, "my_server", emsg);
erl_free_term(emsg); ]]></code>
<p>The first element of the tuple that is sent is your own
- <em>Pid</em>. This enables <c><![CDATA[my_server]]></c> to reply. Refer to the
- Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information
+ <em>Pid</em>. This enables <c>my_server</c> to reply. Refer to the
+ Reference Manual, the <c>erl_connect</c> module for more information
about send primitives.</p>
</section>
<section>
<title>Example of Receiving Messages</title>
- <p>In this example <c><![CDATA[{Pid, Something}]]></c> is received. The
- received Pid is then used to return <c><![CDATA[{goodbye,Pid}]]></c></p>
+ <p>In this example <c>{Pid, Something}</c> is received. The
+ received Pid is then used to return <c>{goodbye,Pid}</c></p>
<code type="none"><![CDATA[
ETERM *arr[2], *answer;
int sockfd,rc;
@@ -383,18 +383,18 @@ if ((rc = erl_receive_msg(sockfd , buf, BUFSIZE, &emsg)) == ERL_MSG) {
<p>In order to provide robustness, a distributed Erlang node
occasionally polls all its connected neighbours in an attempt to
detect failed nodes or communication links. A node which receives such
- a message is expected to respond immediately with an <c><![CDATA[ERL_TICK]]></c> message.
- This is done automatically by <c><![CDATA[erl_receive()]]></c>, however when this
- has occurred <c><![CDATA[erl_receive]]></c> returns <c><![CDATA[ERL_TICK]]></c> to the caller
- without storing a message into the <c><![CDATA[ErlMessage]]></c> structure.</p>
+ a message is expected to respond immediately with an <c>ERL_TICK</c> message.
+ This is done automatically by <c>erl_receive()</c>, however when this
+ has occurred <c>erl_receive</c> returns <c>ERL_TICK</c> to the caller
+ without storing a message into the <c>ErlMessage</c> structure.</p>
<p>When a message has been received, it is the caller's responsibility
- to free the received message <c><![CDATA[emsg.msg]]></c> as well as <c><![CDATA[emsg.to]]></c>
- or <c><![CDATA[emsg.from]]></c>, depending on the type of message received.</p>
+ to free the received message <c>emsg.msg</c> as well as <c>emsg.to</c>
+ or <c>emsg.from</c>, depending on the type of message received.</p>
<p>Refer to the Reference Manual for additional information about the
following modules:</p>
<list type="bulleted">
- <item><c><![CDATA[erl_connect]]></c></item>
- <item><c><![CDATA[erl_eterm]]></c>.</item>
+ <item><c>erl_connect</c></item>
+ <item><c>erl_eterm</c>.</item>
</list>
</section>
</section>
@@ -421,12 +421,12 @@ if (!erl_match(ep, reply))
");
erl_free_term(ep);
erl_free_term(reply); ]]></code>
- <p><c><![CDATA[c:c/1]]></c> is called to compile the specified module on the
- remote node. <c><![CDATA[erl_match()]]></c> checks that the compilation was
- successful by testing for the expected <c><![CDATA[ok]]></c>.</p>
- <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for
- more information about <c><![CDATA[erl_rpc()]]></c>, and its companions
- <c><![CDATA[erl_rpc_to()]]></c> and <c><![CDATA[erl_rpc_from()]]></c>.</p>
+ <p><c>c:c/1</c> is called to compile the specified module on the
+ remote node. <c>erl_match()</c> checks that the compilation was
+ successful by testing for the expected <c>ok</c>.</p>
+ <p>Refer to the Reference Manual, the <c>erl_connect</c> module for
+ more information about <c>erl_rpc()</c>, and its companions
+ <c>erl_rpc_to()</c> and <c>erl_rpc_from()</c>.</p>
</section>
<section>
@@ -454,14 +454,14 @@ if (names)
",names[i]);
free(names); ]]></code>
- <p><c><![CDATA[erl_global_names()]]></c> allocates and returns a buffer containing
- all the names known to global. <c><![CDATA[count]]></c> will be initialized to
+ <p><c>erl_global_names()</c> allocates and returns a buffer containing
+ all the names known to global. <c>count</c> will be initialized to
indicate how many names are in the array. The array of strings in
names is terminated by a NULL pointer, so it is not necessary to use
- <c><![CDATA[count]]></c> to determine when the last name is reached.</p>
+ <c>count</c> to determine when the last name is reached.</p>
<p>It is the caller's responsibility to free the array.
- <c><![CDATA[erl_global_names()]]></c> allocates the array and all of the strings
- using a single call to <c><![CDATA[malloc()]]></c>, so <c><![CDATA[free(names)]]></c> is all
+ <c>erl_global_names()</c> allocates the array and all of the strings
+ using a single call to <c>malloc()</c>, so <c>free(names)</c> is all
that is necessary.</p>
<p>To look up one of the names:</p>
<code type="none"><![CDATA[
@@ -469,13 +469,13 @@ ETERM *pid;
char node[256];
pid = erl_global_whereis(fd,"schedule",node); ]]></code>
- <p>If <c><![CDATA["schedule"]]></c> is known to global, an Erlang pid is returned
+ <p>If <c>"schedule"</c> is known to global, an Erlang pid is returned
that can be used to send messages to the schedule service.
- Additionally, <c><![CDATA[node]]></c> will be initialized to contain the name of
+ Additionally, <c>node</c> will be initialized to contain the name of
the node where the service is registered, so that you can make a
- connection to it by simply passing the variable to <c><![CDATA[erl_connect()]]></c>.</p>
+ connection to it by simply passing the variable to <c>erl_connect()</c>.</p>
<p>Before registering a name, you should already have registered your
- port number with <c><![CDATA[epmd]]></c>. This is not strictly necessary, but if you
+ port number with <c>epmd</c>. This is not strictly necessary, but if you
neglect to do so, then other nodes wishing to communicate with your
service will be unable to find or connect to your process.</p>
<p>Create a pid that Erlang processes can use to communicate with your
@@ -485,9 +485,9 @@ ETERM *pid;
pid = erl_mk_pid(thisnode,14,0,0);
erl_global_register(fd,servicename,pid); ]]></code>
- <p>After registering the name, you should use <c><![CDATA[erl_accept()]]></c> to wait for
+ <p>After registering the name, you should use <c>erl_accept()</c> to wait for
incoming connections.</p>
- <p>Do not forget to free <c><![CDATA[pid]]></c> later with <c><![CDATA[erl_free_term()]]></c>!</p>
+ <p>Do not forget to free <c>pid</c> later with <c>erl_free_term()</c>!</p>
<p>To unregister a name:</p>
<code type="none"><![CDATA[
erl_global_unregister(fd,servicename); ]]></code>
@@ -500,7 +500,7 @@ erl_global_unregister(fd,servicename); ]]></code>
restoring them from a Mnesia table on an Erlang node. More detailed
information about the individual API functions can be found in the
Reference Manual.</p>
- <p>Keys are strings, i.e. 0-terminated arrays of characters, and values
+ <p>Keys are strings, i.e. <c>NULL</c>-terminated arrays of characters, and values
are arbitrary objects. Although integers and floating point numbers
are treated specially by the registry, you can store strings or binary
objects of any type as pointers.</p>
@@ -570,12 +570,12 @@ ei_reg_close(reg); ]]></code>
<title>Backing Up the Registry to Mnesia</title>
<p>The contents of a registry can be backed up to Mnesia on a "nearby"
Erlang node. You need to provide an open connection to the Erlang node
- (see <c><![CDATA[erl_connect()]]></c>). Also, Mnesia 3.0 or later must be running
+ (see <c>erl_connect()</c>). Also, Mnesia 3.0 or later must be running
on the Erlang node before the backup is initiated:</p>
<code type="none"><![CDATA[
ei_reg_dump(fd, reg, "mtab", dumpflags); ]]></code>
<p>The example above will backup the contents of the registry to the
- specified Mnesia table <c><![CDATA["mtab"]]></c>. Once a registry has been backed
+ specified Mnesia table <c>"mtab"</c>. Once a registry has been backed
up to Mnesia in this manner, additional backups will only affect
objects that have been modified since the most recent backup, i.e.
objects that have been created, changed or deleted. The backup
@@ -584,7 +584,7 @@ ei_reg_dump(fd, reg, "mtab", dumpflags); ]]></code>
<p>In the same manner, a registry can be restored from a Mnesia table:</p>
<code type="none"><![CDATA[
ei_reg_restore(fd, reg, "mtab"); ]]></code>
- <p>This will read the entire contents of <c><![CDATA["mtab"]]></c> into the specified
+ <p>This will read the entire contents of <c>"mtab"</c> into the specified
registry. After the restore, all of the objects in the registry will
be marked as unmodified, so a subsequent backup will only affect
objects that you have modified since the restore.</p>
@@ -600,8 +600,8 @@ ei_reg_restore(fd, reg, "mtab"); ]]></code>
<p>When string or binary objects are stored in the registry it is
important that a number of simple guidelines are followed. </p>
<p>Most importantly, the object must have been created with a single call
- to <c><![CDATA[malloc()]]></c> (or similar), so that it can later be removed by a
- single call to <c><![CDATA[free()]]></c>. Objects will be freed by the registry
+ to <c>malloc()</c> (or similar), so that it can later be removed by a
+ single call to <c>free()</c>. Objects will be freed by the registry
when it is closed, or when you assign a new value to an object that
previously contained a string or binary.</p>
<p>You should also be aware that if you store binary objects that are
@@ -618,9 +618,8 @@ ei_reg_restore(fd, reg, "mtab"); ]]></code>
you make, possibly causing it to be missed the next time you make a
Mnesia backup of the registry contents. This can be avoided if you
mark the object as dirty after any such changes with
- <c><![CDATA[ei_reg_markdirty()]]></c>, or pass appropriate flags to
- <c><![CDATA[ei_reg_dump()]]></c>.</p>
+ <c>ei_reg_markdirty()</c>, or pass appropriate flags to
+ <c>ei_reg_dump()</c>.</p>
</section>
</section>
</chapter>
-
diff --git a/lib/erl_interface/doc/src/erl_malloc.xml b/lib/erl_interface/doc/src/erl_malloc.xml
index 799c903b1a..c0eebc29e9 100644
--- a/lib/erl_interface/doc/src/erl_malloc.xml
+++ b/lib/erl_interface/doc/src/erl_malloc.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>erl_malloc</title>
@@ -28,174 +28,177 @@
<docno></docno>
<approved>Bjarne D&auml;cker</approved>
<checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
- <date>980703</date>
+ <date>1998-07-03</date>
<rev>A</rev>
- <file>erl_malloc.sgml</file>
+ <file>erl_malloc.xml</file>
</header>
<lib>erl_malloc</lib>
- <libsummary>Memory Allocation Functions</libsummary>
+ <libsummary>Memory allocation functions.</libsummary>
<description>
<p>This module provides functions for allocating and deallocating
memory.</p>
</description>
+
<funcs>
<func>
<name><ret>ETERM *</ret><nametext>erl_alloc_eterm(etype)</nametext></name>
- <fsummary>Allocates an ETERM structure</fsummary>
+ <fsummary>Allocate an ETERM structure.</fsummary>
<type>
<v>unsigned char etype;</v>
</type>
<desc>
- <p>This function allocates an <c><![CDATA[(ETERM)]]></c> structure.
- Specify <c><![CDATA[etype]]></c> as one of the following constants:</p>
+ <p>Allocates an <c>(ETERM)</c> structure.</p>
+ <p>Specify <c>etype</c> as one of the following
+ constants:</p>
<list type="bulleted">
- <item>
- <p>ERL_INTEGER</p>
+ <item><c>ERL_INTEGER</c>
</item>
- <item>
- <p>ERL_U_INTEGER <c><![CDATA[/* unsigned integer */]]></c></p>
+ <item><c>ERL_U_INTEGER</c> (unsigned integer)
</item>
- <item>
- <p>ERL_ATOM</p>
+ <item><c>ERL_ATOM</c>
</item>
- <item>
- <p>ERL_PID <c><![CDATA[/* Erlang process identifier */]]></c></p>
+ <item><c>ERL_PID</c> (Erlang process identifier)
</item>
- <item>
- <p>ERL_PORT</p>
+ <item><c>ERL_PORT</c>
</item>
- <item>
- <p>ERL_REF <c><![CDATA[/* Erlang reference */]]></c></p>
+ <item><c>ERL_REF</c> (Erlang reference)
</item>
- <item>
- <p>ERL_LIST</p>
+ <item><c>ERL_LIST</c>
</item>
- <item>
- <p>ERL_EMPTY_LIST</p>
+ <item><c>ERL_EMPTY_LIST</c>
</item>
- <item>
- <p>ERL_TUPLE</p>
+ <item><c>ERL_TUPLE</c>
</item>
- <item>
- <p>ERL_BINARY</p>
+ <item><c>ERL_BINARY</c>
</item>
- <item>
- <p>ERL_FLOAT</p>
+ <item><c>ERL_FLOAT</c>
</item>
- <item>
- <p>ERL_VARIABLE</p>
+ <item><c>ERL_VARIABLE</c>
</item>
- <item>
- <p>ERL_SMALL_BIG <c><![CDATA[/* bignum */]]></c></p>
+ <item><c>ERL_SMALL_BIG</c> (bignum)
</item>
- <item>
- <p>ERL_U_SMALL_BIG <c><![CDATA[/* bignum */]]></c></p>
+ <item><c>ERL_U_SMALL_BIG</c> (bignum)
</item>
</list>
- <p><c><![CDATA[ERL_SMALL_BIG]]></c> and <c><![CDATA[ERL_U_SMALL_BIG]]></c> are for
- creating Erlang <c><![CDATA[bignums]]></c>, which can contain integers of
- arbitrary size. The size of an integer in Erlang is machine
- dependent, but in general any integer larger than 2^28
- requires a bignum.</p>
+ <p><c>ERL_SMALL_BIG</c> and
+ <c>ERL_U_SMALL_BIG</c> are for
+ creating Erlang <c>bignums</c>, which can contain integers
+ of any size. The size of an integer in Erlang is machine-dependent,
+ but any integer &gt; 2^28 requires a bignum.</p>
</desc>
</func>
+
<func>
<name><ret>void</ret><nametext>erl_eterm_release(void)</nametext></name>
- <fsummary>Clears the ETERM freelist</fsummary>
+ <fsummary>Clear the ETERM freelist.</fsummary>
<desc>
- <p>Clears the
- freelist, where blocks are placed when they are
- released by <c><![CDATA[erl_free_term()]]></c> and
- <c><![CDATA[erl_free_compound()]]></c>. </p>
+ <p>Clears the freelist, where blocks are placed when they are
+ released by <c>erl_free_term()</c> and
+ <c>erl_free_compound()</c>.</p>
</desc>
</func>
+
<func>
<name><ret>void</ret><nametext>erl_eterm_statistics(allocated, freed)</nametext></name>
- <fsummary>Reports term allocation statistics</fsummary>
+ <fsummary>Report term allocation statistics.</fsummary>
<type>
<v>long *allocated;</v>
<v>long *freed;</v>
</type>
<desc>
- <p><c><![CDATA[allocated]]></c> and <c><![CDATA[freed]]></c> are initialized to
+ <p>Reports term allocation statistics.</p>
+ <p><c>allocated</c> and <c>freed</c> are
+ initialized to
contain information about the fix-allocator used to allocate
- ETERM components. <c><![CDATA[allocated]]></c> is the number of blocks
- currently allocated to ETERM objects. <c><![CDATA[freed]]></c> is the
- length of the freelist, where blocks are placed when they are
- released by <c><![CDATA[erl_free_term()]]></c> and
- <c><![CDATA[erl_free_compound()]]></c>. </p>
+ <c>ETERM</c> components.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>allocated</c> is the number of blocks currently
+ allocated to <c>ETERM</c> objects.</p>
+ </item>
+ <item>
+ <p><c>freed</c> is the length of the freelist, where
+ blocks are placed when they are
+ released by <c>erl_free_term()</c> and
+ <c>erl_free_compound()</c>.</p>
+ </item>
+ </list>
</desc>
</func>
+
<func>
- <name><ret>void</ret><nametext>erl_free_array(array, size)</nametext></name>
- <fsummary>Frees an array of ETERM structures</fsummary>
+ <name><ret>void</ret><nametext>erl_free(ptr)</nametext></name>
+ <fsummary>Free some memory.</fsummary>
<type>
- <v>ETERM **array;</v>
- <v>int size;</v>
+ <v>void *ptr;</v>
</type>
<desc>
- <p>This function frees an array of Erlang terms.</p>
- <p><c><![CDATA[array]]></c> is an array of ETERM* objects.
- </p>
- <p><c><![CDATA[size]]></c> is the number of terms in the array.</p>
+ <p>Calls the standard
+ <c>free()</c> function.</p>
</desc>
</func>
+
<func>
- <name><ret>void</ret><nametext>erl_free_term(t)</nametext></name>
- <fsummary>Frees an ETERM structure</fsummary>
+ <name><ret>void</ret><nametext>erl_free_array(array, size)</nametext></name>
+ <fsummary>Free an array of ETERM structures.</fsummary>
<type>
- <v>ETERM *t;</v>
+ <v>ETERM **array;</v>
+ <v>int size;</v>
</type>
<desc>
- <p>Use this function to free an Erlang term.</p>
+ <p>Frees an array of Erlang terms.</p>
+ <list type="bulleted">
+ <item><c>array</c> is an array of ETERM* objects.</item>
+ <item><c>size</c> is the number of terms in the array.
+ </item>
+ </list>
</desc>
</func>
+
<func>
<name><ret>void</ret><nametext>erl_free_compound(t)</nametext></name>
- <fsummary>Frees an array of ETERM structures</fsummary>
+ <fsummary>Free an array of ETERM structures.</fsummary>
<type>
<v>ETERM *t;</v>
</type>
<desc>
<p>Normally it is the programmer's responsibility to free each
Erlang term that has been returned from any of the
- <c><![CDATA[erl_interface]]></c> functions. However since many of the
+ <c>Erl_Interface</c> functions. However, as many of the
functions that build new Erlang terms in fact share objects
- with other existing terms, it may be difficult for the
- programmer to maintain pointers to all such terms in order to
- free them individually.
- </p>
- <p><c><![CDATA[erl_free_compound()]]></c> will recursively free all of the
- sub-terms associated with a given Erlang term, regardless of
- whether we are still holding pointers to the sub-terms.
- </p>
- <p>There is an example in the User Manual under "Building
- Terms and Patterns"
- </p>
+ with other existing terms, it can be difficult for the
+ programmer to maintain pointers to all such terms to
+ free them individually.</p>
+ <p><c>erl_free_compound()</c> recursively frees all of the
+ subterms associated with a specified Erlang term, regardless of
+ whether we are still holding pointers to the subterms.</p>
+ <p>For an example, see section
+ <seealso marker="ei_users_guide#building_terms_and_patterns">Building Terms and Patterns</seealso>
+ in the User's Guide.</p>
</desc>
</func>
+
<func>
- <name><ret>void</ret><nametext>erl_malloc(size)</nametext></name>
- <fsummary>Allocates some memory</fsummary>
+ <name><ret>void</ret><nametext>erl_free_term(t)</nametext></name>
+ <fsummary>Free an ETERM structure.</fsummary>
<type>
- <v>long size;</v>
+ <v>ETERM *t;</v>
</type>
<desc>
- <p>This function calls the standard
- <c><![CDATA[malloc()]]></c> function. </p>
+ <p>Frees an Erlang term.</p>
</desc>
</func>
+
<func>
- <name><ret>void</ret><nametext>erl_free(ptr)</nametext></name>
- <fsummary>Frees some memory</fsummary>
+ <name><ret>void</ret><nametext>erl_malloc(size)</nametext></name>
+ <fsummary>Allocate some memory.</fsummary>
<type>
- <v>void *ptr;</v>
+ <v>long size;</v>
</type>
<desc>
- <p>This function calls the standard
- <c><![CDATA[free()]]></c> function. </p>
+ <p>Calls the standard
+ <c>malloc()</c> function.</p>
</desc>
</func>
</funcs>
</cref>
-
diff --git a/lib/erl_interface/doc/src/erl_marshal.xml b/lib/erl_interface/doc/src/erl_marshal.xml
index 7c56089016..2ad658f78b 100644
--- a/lib/erl_interface/doc/src/erl_marshal.xml
+++ b/lib/erl_interface/doc/src/erl_marshal.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>erl_marshal</title>
@@ -28,246 +28,241 @@
<docno></docno>
<approved>Bjarne D&auml;cker</approved>
<checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
- <date>980703</date>
+ <date>1998-07-03</date>
<rev>A</rev>
- <file>erl_marshal.sgml</file>
+ <file>erl_marshal.xml</file>
</header>
<lib>erl_marshal</lib>
- <libsummary>Encoding and Decoding of Erlang terms</libsummary>
+ <libsummary>Encoding and decoding of Erlang terms.</libsummary>
<description>
<p>This module contains functions for encoding Erlang terms into
a sequence of bytes, and for decoding Erlang terms from a
sequence of bytes.</p>
</description>
+
<funcs>
<func>
<name><ret>int</ret><nametext>erl_compare_ext(bufp1, bufp2)</nametext></name>
- <fsummary>Compares encoded byte sequences</fsummary>
+ <fsummary>Compare encoded byte sequences.</fsummary>
<type>
<v>unsigned char *bufp1,*bufp2;</v>
</type>
<desc>
- <p>This function compares two encoded terms.
- </p>
- <p><c><![CDATA[bufp1]]></c> is a buffer containing an encoded Erlang
- term term1.
- </p>
- <p><c><![CDATA[bufp2]]></c> is a buffer containing an encoded Erlang
- term term2.
- </p>
- <p>The function returns 0 if the terms are equal, -1 if term1
- is less than term2, or 1 if term2 is less than term1.
- </p>
+ <p>Compares two encoded terms.</p>
+ <list type="bulleted">
+ <item><c>bufp1</c> is a buffer containing an encoded
+ Erlang term term1.</item>
+ <item><c>bufp2</c> is a buffer containing an encoded
+ Erlang term term2.</item>
+ </list>
+ <p>Returns <c>0</c> if the terms are equal, <c>-1</c> if
+ <c>term1</c> &lt; <c>term2</c>, or <c>1</c> if <c>term2</c> &lt;
+ <c>term1</c>.</p>
</desc>
</func>
+
<func>
<name><ret>ETERM *</ret><nametext>erl_decode(bufp)</nametext></name>
<name><ret>ETERM *</ret><nametext>erl_decode_buf(bufpp)</nametext></name>
- <fsummary>Converts a term from Erlang external format</fsummary>
+ <fsummary>Convert a term from Erlang external format.</fsummary>
<type>
<v>unsigned char *bufp;</v>
<v>unsigned char **bufpp;</v>
</type>
<desc>
- <p><c><![CDATA[erl_decode()]]></c> and <c><![CDATA[erl_decode_buf()]]></c> decode
+ <p><c>erl_decode()</c> and
+ <c>erl_decode_buf()</c> decode
the contents of a buffer and return the corresponding
- Erlang term. <c><![CDATA[erl_decode_buf()]]></c> provides a simple
+ Erlang term. <c>erl_decode_buf()</c> provides a simple
mechanism for dealing with several encoded terms stored
consecutively in the buffer.</p>
- <p><c><![CDATA[bufp]]></c> is a pointer to a buffer containing one or
- more encoded Erlang terms.
- </p>
- <p><c><![CDATA[bufpp]]></c> is the address of a buffer pointer. The buffer
- contains one or more consecutively encoded Erlang terms.
- Following a successful call to <c><![CDATA[erl_decode_buf()]]></c>,
- <c><![CDATA[bufpp]]></c> will be updated so that it points to the next
- encoded term.
- </p>
- <p><c><![CDATA[erl_decode()]]></c> returns an Erlang term
- corresponding to the contents of <c><![CDATA[bufp]]></c> on success, or
- NULL on failure. <c><![CDATA[erl_decode_buf()]]></c> returns an Erlang
+ <list type="bulleted">
+ <item>
+ <p><c>bufp</c> is a pointer to a buffer containing one
+ or more encoded Erlang terms.</p>
+ </item>
+ <item>
+ <p><c>bufpp</c> is the address of a buffer pointer. The
+ buffer contains one or more consecutively encoded Erlang terms.
+ Following a successful call to
+ <c>erl_decode_buf()</c>, <c>bufpp</c> is
+ updated so that it points to the next encoded term.</p>
+ </item>
+ </list>
+ <p><c>erl_decode()</c> returns an Erlang term
+ corresponding to the contents of <c>bufp</c> on success,
+ otherwise <c>NULL</c>. <c>erl_decode_buf()</c>
+ returns an Erlang
term corresponding to the first of the consecutive terms in
- <c><![CDATA[bufpp]]></c> and moves <c><![CDATA[bufpp]]></c> forward to point to the
+ <c>bufpp</c> and moves <c>bufpp</c> forward
+ to point to the
next term in the buffer. On failure, each of the functions
- returns NULL.
- </p>
+ return <c>NULL</c>.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_encode(term, bufp)</nametext></name>
<name><ret>int</ret><nametext>erl_encode_buf(term, bufpp)</nametext></name>
- <fsummary>Converts a term into Erlang external format</fsummary>
+ <fsummary>Convert a term into Erlang external format.</fsummary>
<type>
<v>ETERM *term;</v>
<v>unsigned char *bufp;</v>
<v>unsigned char **bufpp;</v>
</type>
<desc>
- <p><c><![CDATA[erl_encode()]]></c> and <c><![CDATA[erl_encode_buf()]]></c> encode
+ <p><c>erl_encode()</c> and
+ <c>erl_encode_buf()</c> encode
Erlang terms into external format for storage or transmission.
- <c><![CDATA[erl_encode_buf()]]></c> provides a simple mechanism for
- encoding several terms consecutively in the same
- buffer.
- </p>
- <p><c>term</c> is an Erlang term to be encoded.
- </p>
- <p><c>bufp</c> is a pointer to a buffer containing one or
- more encoded Erlang terms.
- </p>
- <p><c>bufpp</c> is a pointer to a pointer to a buffer
- containing one or more consecutively encoded Erlang terms.
- Following a successful call to <c><![CDATA[erl_encode_buf()]]></c>,
- <c>bufpp</c> will be updated so that it points to the
- position for the next encoded term.
- </p>
- <p>
- These functions returns the number of bytes written to buffer
- if successful, otherwise returns 0.
- </p>
- <p>Note that no bounds checking is done on the buffer. It is
- the caller's responsibility to make sure that the buffer is
+ <c>erl_encode_buf()</c> provides a simple mechanism for
+ encoding several terms consecutively in the same buffer.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>term</c> is an Erlang term to be encoded.</p>
+ </item>
+ <item>
+ <p><c>bufp</c> is a pointer to a buffer containing one or
+ more encoded Erlang terms.</p>
+ </item>
+ <item>
+ <p><c>bufpp</c> is a pointer to a pointer to a buffer
+ containing one or more consecutively encoded Erlang terms.
+ Following a successful call to
+ <c>erl_encode_buf()</c>, <c>bufpp</c> is updated so
+ that it points to the
+ position for the next encoded term.</p>
+ </item>
+ </list>
+ <p>These functions return the number of bytes written to buffer
+ on success, otherwise <c>0</c>.</p>
+ <p>Notice that no bounds checking is done on the buffer. It is
+ the caller's responsibility to ensure that the buffer is
large enough to hold the encoded terms. You can either use a
- static buffer that is large enough to hold the terms you
- expect to need in your program, or use <c><![CDATA[erl_term_len()]]></c>
- to determine the exact requirements for a given term.
- </p>
+ static buffer that is large enough to hold the terms you expect
+ to need in your program, or use <c>erl_term_len()</c>
+ to determine the exact requirements for a given term.</p>
<p>The following can help you estimate the buffer
- requirements for a term. Note that this information is
- implementation specific, and may change in future versions.
- If you are unsure, use <c><![CDATA[erl_term_len()]]></c>.
- </p>
+ requirements for a term. Notice that this information is
+ implementation-specific, and can change in future versions.
+ If you are unsure, use <c>erl_term_len()</c>.</p>
<p>Erlang terms are encoded with a 1 byte tag that
identifies the type of object, a 2- or 4-byte length field,
- and then the data itself. Specifically:
- </p>
+ and then the data itself. Specifically:</p>
<taglist>
- <tag><c><![CDATA[Tuples]]></c></tag>
- <item>need 5 bytes, plus the space for each element.</item>
- <tag><c><![CDATA[Lists]]></c></tag>
- <item>need 5 bytes, plus the space for each element, and 1
- additional byte for the empty list at the end.</item>
- <tag><c><![CDATA[Strings and atoms]]></c></tag>
- <item>need 3 bytes, plus 1 byte for each character (the
- terminating 0 is not encoded). Really long strings (more
- than 64k characters) are encoded as lists. Atoms cannot
- contain more than 256 characters.</item>
- <tag><c><![CDATA[Integers]]></c></tag>
- <item>need 5 bytes.</item>
- <tag><c><![CDATA[Characters]]></c></tag>
- <item>(integers &lt; 256) need 2 bytes.</item>
- <tag><c><![CDATA[Floating point numbers]]></c></tag>
- <item>need 32 bytes.</item>
- <tag><c><![CDATA[Pids]]></c></tag>
- <item>need 10 bytes, plus the space for the node name, which
- is an atom.</item>
- <tag><c><![CDATA[Ports and Refs]]></c></tag>
- <item>need 6 bytes, plus the space for the node name, which
- is an atom.</item>
+ <tag><c>Tuples</c></tag>
+ <item>Need 5 bytes, plus the space for each element.</item>
+ <tag><c>Lists</c></tag>
+ <item>Need 5 bytes, plus the space for each element, and 1
+ more byte for the empty list at the end.</item>
+ <tag><c>Strings and atoms</c></tag>
+ <item>Need 3 bytes, plus 1 byte for each character (the
+ terminating 0 is not encoded). Really long strings (more
+ than 64k characters) are encoded as lists. Atoms cannot
+ contain more than 256 characters.</item>
+ <tag><c>Integers</c></tag>
+ <item>Need 5 bytes.</item>
+ <tag><c>Characters</c></tag>
+ <item>(Integers &lt; 256) need 2 bytes.</item>
+ <tag><c>Floating point numbers</c></tag>
+ <item>Need 32 bytes.</item>
+ <tag><c>Pids</c></tag>
+ <item>Need 10 bytes, plus the space for the node name, which
+ is an atom.</item>
+ <tag><c>Ports and Refs</c></tag>
+ <item>Need 6 bytes, plus the space for the node name, which
+ is an atom.</item>
</taglist>
- <p>The total space required will be the result calculated
- from the information above, plus 1 additional byte for a
- version identifier.
- </p>
+ <p>The total space required is the result calculated
+ from the information above, plus 1 more byte for a
+ version identifier.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_ext_size(bufp)</nametext></name>
- <fsummary>Counts elements in encoded term</fsummary>
+ <fsummary>Count elements in encoded term.</fsummary>
<type>
<v>unsigned char *bufp;</v>
</type>
<desc>
- <p>This function returns the number of elements in an
- encoded term.</p>
+ <p>Returns the number of elements in an encoded term.</p>
</desc>
</func>
+
<func>
<name><ret>unsigned char</ret><nametext>erl_ext_type(bufp)</nametext></name>
- <fsummary>Determines type of an encoded byte sequence</fsummary>
+ <fsummary>Determine type of an encoded byte sequence.</fsummary>
<type>
<v>unsigned char *bufp;</v>
</type>
<desc>
- <p>This function identifies and returns the type of Erlang term encoded
- in a buffer. It will skip a trailing <em>magic</em> identifier.
- Returns <c><![CDATA[0]]></c> if the type can't be determined or one of</p>
+ <p>Identifies and returns the type of Erlang term encoded
+ in a buffer. It skips a trailing <em>magic</em> identifier.</p>
+ <p>Returns <c>0</c> if the type cannot be determined or
+ one of:</p>
<list type="bulleted">
- <item>
- <p>ERL_INTEGER</p>
+ <item><c>ERL_INTEGER</c>
</item>
- <item>
- <p>ERL_ATOM</p>
+ <item><c>ERL_ATOM</c>
</item>
- <item>
- <p>ERL_PID <c><![CDATA[/* Erlang process identifier */]]></c></p>
+ <item><c>ERL_PID</c> (Erlang process identifier)
</item>
- <item>
- <p>ERL_PORT</p>
+ <item><c>ERL_PORT</c>
</item>
- <item>
- <p>ERL_REF <c><![CDATA[/* Erlang reference */]]></c></p>
+ <item><c>ERL_REF</c> (Erlang reference)
</item>
- <item>
- <p>ERL_EMPTY_LIST</p>
+ <item><c>ERL_EMPTY_LIST</c>
</item>
- <item>
- <p>ERL_LIST</p>
+ <item><c>ERL_LIST</c>
</item>
- <item>
- <p>ERL_TUPLE</p>
+ <item><c>ERL_TUPLE</c>
</item>
- <item>
- <p>ERL_FLOAT</p>
+ <item><c>ERL_FLOAT</c>
</item>
- <item>
- <p>ERL_BINARY</p>
+ <item><c>ERL_BINARY</c>
</item>
- <item>
- <p>ERL_FUNCTION</p>
+ <item><c>ERL_FUNCTION</c>
</item>
</list>
</desc>
</func>
+
<func>
<name><ret>unsigned char *</ret><nametext>erl_peek_ext(bufp, pos)</nametext></name>
- <fsummary>Steps over encoded term</fsummary>
+ <fsummary>Step over encoded term.</fsummary>
<type>
<v>unsigned char *bufp;</v>
<v>int pos;</v>
</type>
<desc>
<p>This function is used for stepping over one or more
- encoded terms in a buffer, in order to directly access a
- later term.
- </p>
- <p><c><![CDATA[bufp]]></c> is a pointer to a buffer containing one or
- more encoded Erlang terms.
- </p>
- <p><c><![CDATA[pos]]></c> indicates how many terms to step over in the
- buffer.
- </p>
- <p>The function returns a pointer to a sub-term that can be
- used in a subsequent call to <c><![CDATA[erl_decode()]]></c> in order to retrieve
- the term at that position. If there is no term, or <c><![CDATA[pos]]></c>
- would exceed the size of the terms in the buffer, NULL is returned.
- </p>
+ encoded terms in a buffer, to directly access later term.</p>
+ <list type="bulleted">
+ <item><c>bufp</c> is a pointer to a buffer containing one
+ or more encoded Erlang terms.</item>
+ <item><c>pos</c> indicates how many terms to step over in
+ the buffer.</item>
+ </list>
+ <p>Returns a pointer to a subterm that can be
+ used in a later call to <c>erl_decode()</c> to retrieve
+ the term at that position. If there is no term, or
+ <c>pos</c> would exceed the size of the terms in the
+ buffer, <c>NULL</c> is returned.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>erl_term_len(t)</nametext></name>
- <fsummary>Determines encoded size of term</fsummary>
+ <fsummary>Determine encoded size of term.</fsummary>
<type>
<v>ETERM *t;</v>
</type>
<desc>
- <p>This function determines the buffer space that would be
- needed by <c><![CDATA[t]]></c> if it were encoded into Erlang external
- format by <c><![CDATA[erl_encode()]]></c>.
- </p>
- <p>The size in bytes is returned.
- </p>
+ <p>Determines the buffer space that would be
+ needed by <c>t</c> if it were encoded into Erlang external
+ format by <c>erl_encode()</c>.</p>
+ <p>Returns the size in bytes.</p>
</desc>
</func>
</funcs>
</cref>
-
diff --git a/lib/erl_interface/doc/src/fascicules.xml b/lib/erl_interface/doc/src/fascicules.xml
deleted file mode 100644
index f7edd8a973..0000000000
--- a/lib/erl_interface/doc/src/fascicules.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
-
-<fascicules>
- <fascicule file="part_ei" href="part_ei_frame.html" entry="no">
- EI User's Guide
- </fascicule>
- <fascicule file="ref_man_ei" href="ref_man_ei_frame.html" entry="yes">
- EI Library Reference
- </fascicule>
- <fascicule file="ref_man_erl_interface" href="ref_man_erl_interface_frame.html" entry="no">
- Erl_interface Library Reference
- </fascicule>
- <fascicule file="ref_man" href="ref_man_frame.html" entry="no">
- Command Reference
- </fascicule>
- <fascicule file="part_notes" href="part_notes_frame.html" entry="no">
- Release Notes
- </fascicule>
- <fascicule file="" href="../../../../doc/print.html" entry="no">
- Off-Print
- </fascicule>
-</fascicules>
-
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
index a69c5aac11..ec20f3c67f 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,106 @@
</header>
<p>This document describes the changes made to the Erl_interface application.</p>
+<section><title>Erl_Interface 3.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix bug where gethostname would incorrectly fail with
+ enametoolong on Linux.</p>
+ <p>
+ Own Id: OTP-14310</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Remove generation of atoms in old latin1 external format
+ in the distribution between erlang nodes,
+ <c>erl_interface</c>, and <c>jinterface</c>. The new utf8
+ format for atoms was introduced in OTP R16. An OTP 20
+ node can therefore not connect to nodes older than R16.</p>
+ <p>
+ Atoms that can be encoded using latin1 are still encoded
+ by <c>term_to_binary()</c> using latin1 encoding. Note
+ that all atoms will by default be encoded using utf8 in a
+ future Erlang/OTP release. For more information see the
+ documentation of <seealso
+ marker="erts:erlang#term_to_binary/2"><c>erlang:term_to_binary/2</c></seealso>.</p>
+ <p>
+ Own Id: OTP-14337</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.9.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Minor documentation update</p>
+ <p>
+ Own Id: OTP-14233 Aux Id: PR-1343 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.9.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix <c>ei_connect_init</c> and <c>ei_connect_xinit</c> to
+ adjust the <c>creation</c> argument to be compatible with
+ nodes older than OTP-19.</p>
+ <p>
+ Own Id: OTP-13981</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Editorial documentation changes</p>
+ <p>
+ Own Id: OTP-13980</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.9.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Look for .erlang.cookie in windows system directory if
+ HOMEDRIVE and HOMEPATH is not set. The same behaviour as
+ the VM.</p>
+ <p>
+ Own Id: OTP-13849</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erl_Interface 3.9</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/erl_interface/doc/src/part.xml b/lib/erl_interface/doc/src/part.xml
index d044e2b981..3b761df221 100644
--- a/lib/erl_interface/doc/src/part.xml
+++ b/lib/erl_interface/doc/src/part.xml
@@ -22,7 +22,7 @@
</legalnotice>
- <title>EI User's Guide</title>
+ <title>Erl_Interface User's Guide</title>
<prepared>Gordon Beaton</prepared>
<docno></docno>
<date>1998-11-30</date>
diff --git a/lib/erl_interface/doc/src/part_erl_interface.xml b/lib/erl_interface/doc/src/part_erl_interface.xml
index 2abe7ecd60..e256cfa193 100644
--- a/lib/erl_interface/doc/src/part_erl_interface.xml
+++ b/lib/erl_interface/doc/src/part_erl_interface.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>Erl_Interface User's Guide</title>
@@ -31,4 +31,3 @@
</header>
<xi:include href="erl_interface.xml"/>
</part>
-
diff --git a/lib/erl_interface/doc/src/ref_man.xml b/lib/erl_interface/doc/src/ref_man.xml
index 0cf060829b..1e20637cb7 100644
--- a/lib/erl_interface/doc/src/ref_man.xml
+++ b/lib/erl_interface/doc/src/ref_man.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,9 +19,9 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
- <title>Erl_Interface Command Reference</title>
+ <title>Erl_Interface Reference Manual</title>
<prepared>Gordon Beaton</prepared>
<docno></docno>
<date>1998-11.30</date>
@@ -29,17 +29,6 @@
<file>ref_man.xml</file>
</header>
<description>
- <p>The <c>ei</c> and <c>erl_interface</c> are <c>C</c> interface libraries for
- communication with <c>Erlang</c>.</p>
- <note>
- <p>By default, the <c>ei</c> and <c>erl_interface</c> libraries are only guaranteed
- to be compatible with other Erlang/OTP components from the same
- release as the libraries themself. See the documentation of the
- <seealso marker="ei#ei_set_compat_rel">ei_set_compat_rel()</seealso> and
- <seealso marker="erl_eterm#erl_set_compat_rel">erl_set_compat_rel()</seealso>
- functions on how to communicate with Erlang/OTP components from earlier
- releases.</p>
- </note>
</description>
<xi:include href="ei.xml"/>
<xi:include href="ei_connect.xml"/>
@@ -53,4 +42,3 @@
<xi:include href="erl_marshal.xml"/>
<xi:include href="erl_call.xml"/>
</application>
-
diff --git a/lib/erl_interface/doc/src/ref_man_ei.xml b/lib/erl_interface/doc/src/ref_man_ei.xml
index d24828c394..92ff9ed328 100644
--- a/lib/erl_interface/doc/src/ref_man_ei.xml
+++ b/lib/erl_interface/doc/src/ref_man_ei.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>EI Library Reference</title>
@@ -30,12 +30,12 @@
<file>ref_man_ei.xml</file>
</header>
<description>
- <p>The <c><![CDATA[ei]]></c> library is a <c><![CDATA[C]]></c> interface library for
- communication with <c><![CDATA[Erlang]]></c>.</p>
+ <p>The <c>ei</c> library is a <c>C</c> interface library for
+ communication with <c>Erlang</c>.</p>
<note>
- <p>By default, the <c><![CDATA[ei]]></c> library is only guaranteed
+ <p>By default, the <c>ei</c> library is only guaranteed
to be compatible with other Erlang/OTP components from the same
- release as the <c><![CDATA[ei]]></c> library itself. See the documentation of the
+ release as the <c>ei</c> library itself. See the documentation of the
<seealso marker="ei#ei_set_compat_rel">ei_set_compat_rel()</seealso>
function on how to communicate with Erlang/OTP components from earlier
releases.</p>
@@ -45,4 +45,3 @@
<xi:include href="ei_connect.xml"/>
<xi:include href="registry.xml"/>
</application>
-
diff --git a/lib/erl_interface/doc/src/ref_man_erl_interface.xml b/lib/erl_interface/doc/src/ref_man_erl_interface.xml
index fb39c5a7e4..4b1d0e9981 100644
--- a/lib/erl_interface/doc/src/ref_man_erl_interface.xml
+++ b/lib/erl_interface/doc/src/ref_man_erl_interface.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>Erl_Interface Library Reference</title>
@@ -50,4 +50,3 @@
<xi:include href="erl_malloc.xml"/>
<xi:include href="erl_marshal.xml"/>
</application>
-
diff --git a/lib/erl_interface/doc/src/registry.xml b/lib/erl_interface/doc/src/registry.xml
index 285a2402b8..6d70fb3475 100644
--- a/lib/erl_interface/doc/src/registry.xml
+++ b/lib/erl_interface/doc/src/registry.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>registry</title>
@@ -28,457 +28,585 @@
<docno></docno>
<approved>Gordon Beaton</approved>
<checked>Gordon Beaton</checked>
- <date>980707</date>
+ <date>1998-07-07</date>
<rev>A</rev>
- <file>registry.sgml</file>
+ <file>registry.xml</file>
</header>
<lib>registry</lib>
- <libsummary>Store and backup key-value pairs</libsummary>
+ <libsummary>Store and back up key-value pairs.</libsummary>
<description>
<p>This module provides support for storing key-value
pairs in a table known as a registry, backing up registries to
- Mnesia in an atomic manner, and later restoring the contents of a
- registry from Mnesia.</p>
+ <seealso marker="mnesia:mnesia">Mnesia</seealso>
+ in an atomic manner, and later restoring the contents of a
+ registry from <c>Mnesia</c>.</p>
</description>
+
<funcs>
<func>
- <name><ret>ei_reg *</ret><nametext>ei_reg_open(size)</nametext></name>
- <fsummary>Create and open a registry</fsummary>
+ <name><ret>int</ret><nametext>ei_reg_close(reg)</nametext></name>
+ <fsummary>Close a registry.</fsummary>
<type>
- <v>int size;</v>
+ <v>ei_reg *reg;</v>
</type>
<desc>
- <p>Open (create) a registry. The registry will be
- initially empty. Use <c><![CDATA[ei_reg_close()]]></c> to close the registry
- later.
- </p>
- <p><c><![CDATA[size]]></c> is the approximate number of objects you intend
- to store in the registry. Since the registry uses a hash table
- with collision chaining, there is no absolute upper limit on the
- number of objects that can be stored in it. However for reasons
- of efficiency, it is a good idea to choose a number that is
- appropriate for your needs. It is possible to use
- <c><![CDATA[ei_reg_resize()]]></c> to change the size later. Note that the
- number you provide will be increased to the nearest larger prime
- number.
- </p>
- <p>On success, an empty registry will be returned. On failure, NULL
- will be returned.</p>
+ <p>A registry that has previously been created with
+ <c>ei_reg_open()</c> is closed, and all the objects it
+ contains are freed.</p>
+ <p><c>reg</c> is the registry to close.</p>
+ <p>Returns <c>0</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_reg_resize(reg,newsize)</nametext></name>
- <fsummary>Resize a registry</fsummary>
+ <name><ret>int</ret><nametext>ei_reg_delete(reg,key)</nametext></name>
+ <fsummary>Delete an object from the registry.</fsummary>
<type>
<v>ei_reg *reg;</v>
- <v>int newsize;</v>
+ <v>const char *key;</v>
</type>
<desc>
- <p>Change the size of a registry.
- </p>
- <p><c><![CDATA[newsize]]></c> is the new size to make the registry. The
- number will be increased to the nearest larger prime number.
- </p>
- <p>On success, the registry will be resized, all contents
- rehashed, and the function will return 0. On failure, the
- registry will be left unchanged and the function will return -1.</p>
+ <p>Deletes an object from the registry. The object is not
+ removed from the registry, it is only marked for later
+ removal so that on later backups to <c>Mnesia</c>, the
+ corresponding object can be removed from the <c>Mnesia</c> table as
+ well. If another object is later created with the same key, the
+ object will be reused. </p>
+ <p>The object is removed from the registry after a call to
+ <c>ei_reg_dump()</c> or <c>ei_reg_purge()</c>.
+ </p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry containing
+ <c>key</c>.</item>
+ <item><c>key</c> is the object to remove.</item>
+ </list>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_reg_close(reg)</nametext></name>
- <fsummary>Close a registry </fsummary>
+ <name><ret>int</ret><nametext>ei_reg_dump(fd,reg,mntab,flags)</nametext></name>
+ <fsummary>Back up a registry to Mnesia.</fsummary>
<type>
+ <v>int fd;</v>
<v>ei_reg *reg;</v>
+ <v>const char *mntab;</v>
+ <v>int flags;</v>
</type>
<desc>
- <p>A registry that has previously been created with
- <c><![CDATA[ei_reg_open()]]></c> is closed, and all the objects it contains
- are freed.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry to close.
- </p>
- <p>The function returns 0.</p>
+ <p>Dumps the contents of a registry to a <c>Mnesia</c> table in an
+ atomic manner, that is, either all data or no data is updated.
+ If any errors are encountered while backing up
+ the data, the entire operation is aborted.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open connection to Erlang.
+ <c>Mnesia</c> 3.0 or later must be running on the Erlang node.
+ </item>
+ <item><c>reg</c> is the registry to back up.</item>
+ <item><c>mntab</c> is the name of the <c>Mnesia</c> table
+ where the backed up data is to be placed. If the table does not
+ exist, it is created automatically using configurable defaults.
+ For information about configuring this behavior, see
+ <seealso marker="mnesia:mnesia"><c>Mnesia</c></seealso>.</item>
+ </list>
+ <p>If <c>flags</c> is <c>0</c>, the backup includes only
+ those objects that have been created, modified, or deleted since the
+ last backup or restore (that is, an incremental backup). After the
+ backup, any objects that were marked dirty are now clean, and any
+ objects that had been marked for deletion are deleted.</p>
+ <p>Alternatively, setting flags to <c>EI_FORCE</c> causes a full
+ backup to be done, and <c>EI_NOPURGE</c> causes the deleted objects
+ to be left in the registry afterwards. These can be bitwise OR'ed
+ together if both behaviors are desired. If <c>EI_NOPURGE</c> was
+ specified, <c>ei_reg_purge()</c> can be used to
+ explicitly remove the deleted items from the registry later.</p>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_reg_setival(reg,key,i)</nametext></name>
- <fsummary>Assign an integer object</fsummary>
+ <name><ret>double</ret><nametext>ei_reg_getfval(reg,key)</nametext></name>
+ <fsummary>Get a floating point object.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
- <v>int i;</v>
</type>
<desc>
- <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> and integer
- value <c><![CDATA[i]]></c>. If an object already existed with the same
- <c><![CDATA[key]]></c>, the new value replaces the old one. If the previous
- value was a binary or string, it is freed with <c><![CDATA[free()]]></c>.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry where the object should be placed.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object.
- </p>
- <p><c><![CDATA[i]]></c> is the integer value to assign.
- </p>
- <p>The function returns 0 on success, or -1 on failure.</p>
+ <p>Gets the value associated with <c>key</c> in the
+ registry. The value must be a floating point type.</p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry where the object will be
+ looked up.</item>
+ <item><c>key</c> is the name of the object to look up.
+ </item>
+ </list>
+ <p>On success, the function returns the value associated with
+ <c>key</c>.
+ If the object is not found or if it is not a floating point
+ object, <c>-1.0</c> is returned. To avoid problems with in-band error
+ reporting (that is, if you cannot distinguish between <c>-1.0</c> and
+ a valid result), use the more general function
+ <c>ei_reg_getval()</c> instead.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_reg_setfval(reg,key,f)</nametext></name>
- <fsummary>Assign a floating point object</fsummary>
+ <name><ret>int</ret><nametext>ei_reg_getival(reg,key)</nametext></name>
+ <fsummary>Get an integer object.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
- <v>double f;</v>
</type>
<desc>
- <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> and
- floating point value <c><![CDATA[f]]></c>. If an object already existed with
- the same <c><![CDATA[key]]></c>, the new value replaces the old one. If the
- previous value was a binary or string, it is freed with <c><![CDATA[free()]]></c>.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry where the object should be placed.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object.
- </p>
- <p><c><![CDATA[f]]></c> is the floating point value to assign.
- </p>
- <p>The function returns 0 on success, or -1 on failure.</p>
+ <p>Gets the value associated with <c>key</c> in the
+ registry. The value must be an integer.</p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry where the object will be
+ looked up.</item>
+ <item><c>key</c> is the name of the object to look up.
+ </item>
+ </list>
+ <p>On success, the function returns the value associated with
+ <c>key</c>.
+ If the object is not found or if it is not an integer
+ object, <c>-1</c> is returned. To avoid problems with in-band error
+ reporting (that is, if you cannot distinguish between <c>-1</c> and a
+ valid result), use the more general function
+ <c>ei_reg_getval()</c> instead.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_reg_setsval(reg,key,s)</nametext></name>
- <fsummary>Assign a string object</fsummary>
+ <name><ret>const void *</ret><nametext>ei_reg_getpval(reg,key,size)</nametext></name>
+ <fsummary>Get a binary object.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
- <v>const char *s;</v>
+ <v>int size;</v>
</type>
<desc>
- <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> whose
- "value" is the specified string <c><![CDATA[s]]></c>. If an object already
- existed with the same <c><![CDATA[key]]></c>, the new value replaces the old
- one. If the previous value was a binary or string, it is freed
- with <c><![CDATA[free()]]></c>.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry where the object should be placed.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object.
- </p>
- <p><c><![CDATA[s]]></c> is the string to assign. The string itself
- must have been created through a single call to <c><![CDATA[malloc()]]></c> or
- similar function, so that the registry can later delete it if
- necessary by calling <c><![CDATA[free()]]></c>.
- </p>
- <p>The function returns 0 on success, or -1 on failure.</p>
+ <p>Gets the value associated with <c>key</c> in the
+ registry. The value must be a binary (pointer) type.</p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry where the object will be
+ looked up.</item>
+ <item><c>key</c> is the name of the object to look up.
+ </item>
+ <item><c>size</c> is initialized to contain the length in
+ bytes of the object, if it is found.</item>
+ </list>
+ <p>On success, the function returns the value associated with
+ <c>key</c> and indicates its length in
+ <c>size</c>.
+ If the object is not found or if it is not a binary object,
+ <c>NULL</c> is returned. To avoid problems with in-band error
+ reporting (that is, if you cannot distinguish between <c>NULL</c> and
+ a valid result), use the more general function
+ <c>ei_reg_getval()</c> instead.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_reg_setpval(reg,key,p,size)</nametext></name>
- <fsummary>Assign a binary object</fsummary>
+ <name><ret>const char *</ret><nametext>ei_reg_getsval(reg,key)</nametext></name>
+ <fsummary>Get a string object.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
- <v>const void *p;</v>
- <v>int size;</v>
</type>
<desc>
- <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> whose
- "value" is the binary object pointed to by <c><![CDATA[p]]></c>. If an
- object already existed with the same <c><![CDATA[key]]></c>, the new value
- replaces the old one. If the previous value was a binary or
- string, it is freed with <c><![CDATA[free()]]></c>.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry where the object should be placed.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object.
- </p>
- <p><c><![CDATA[p]]></c> is a pointer to the binary object. The object itself
- must have been created through a single call to <c><![CDATA[malloc()]]></c> or
- similar function, so that the registry can later delete it if
- necessary by calling <c><![CDATA[free()]]></c>.
- </p>
- <p><c><![CDATA[size]]></c> is the length in bytes of the binary object.
- </p>
- <p>The function returns 0 on success, or -1 on failure.</p>
+ <p>Gets the value associated with <c>key</c> in the
+ registry. The value must be a string.</p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry where the object will be
+ looked up.</item>
+ <item><c>key</c> is the name of the object to look up.
+ </item>
+ </list>
+ <p>On success, the function returns the value associated with
+ <c>key</c>. If the object is not found or if it is not a
+ string, <c>NULL</c> is returned. To avoid problems with in-band error
+ reporting (that is, if you cannot distinguish between <c>NULL</c> and
+ a valid result), use the more general function
+ <c>ei_reg_getval()</c> instead.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_reg_setval(reg,key,flags,v,...)</nametext></name>
- <fsummary>Assign a value to any object type</fsummary>
+ <name><ret>int</ret><nametext>ei_reg_getval(reg,key,flags,v,...)</nametext></name>
+ <fsummary>Get any object.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
<v>int flags;</v>
- <v>v (see below)</v>
+ <v>void *v (see below)</v>
</type>
<desc>
- <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> whose
- value is specified by <c><![CDATA[v]]></c>. If an object already
- existed with the same <c><![CDATA[key]]></c>, the new value replaces the old
- one. If the previous value was a binary or string, it is freed
- with <c><![CDATA[free()]]></c>.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry where the object should be placed.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object.
- </p>
- <p><c><![CDATA[flags]]></c> indicates the type of the object specified by
- <c><![CDATA[v]]></c>. Flags must be one of EI_INT, EI_FLT, EI_STR and
- EI_BIN, indicating whether <c><![CDATA[v]]></c> is <c><![CDATA[int]]></c>, <c><![CDATA[double]]></c>,
- <c><![CDATA[char*]]></c> or <c><![CDATA[void*]]></c>. If <c><![CDATA[flags]]></c> is EI_BIN, then a
- fifth argument <c><![CDATA[size]]></c> is required, indicating the size
- in bytes of the object pointed to by <c><![CDATA[v]]></c>.
- </p>
- <p>If you wish to store an arbitrary pointer in the registry,
- specify a <c><![CDATA[size]]></c> of 0. In this case, the object itself will
- not be transferred by an <c><![CDATA[ei_reg_dump()]]></c> operation, just
- the pointer value.
- </p>
- <p>The function returns 0 on success, or -1 on failure.</p>
+ <p>A general function for retrieving any kind of
+ object from the registry.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>reg</c> is the registry where the object will be
+ looked up.</p>
+ </item>
+ <item>
+ <p><c>key</c> is the name of the object to look up.</p>
+ </item>
+ <item>
+ <p><c>flags</c> indicates the type of object that you
+ are looking for. If <c>flags</c> is <c>0</c>, any
+ kind of object is returned.
+ If <c>flags</c> is <c>EI_INT</c>, <c>EI_FLT</c>,
+ <c>EI_STR</c>, or <c>EI_BIN</c>, then only values of
+ that kind are returned.</p>
+ <p>The buffer pointed to by <c>v</c>
+ must be large enough to hold the return data, that is, it must be
+ a pointer to one of <c>int</c>,
+ <c>double</c>, <c>char*</c>, or
+ <c>void*</c>, respectively.</p>
+ <p>If <c>flags</c> is <c>EI_BIN</c>, a fifth argument
+ <c>int *size</c> is required, so that the size of the
+ object can be returned.</p>
+ </item>
+ </list>
+ <p>On success, <c>v</c> (and <c>size</c> if the
+ object is binary) is initialized with the value associated
+ with <c>key</c>, and the function returns <c>EI_INT</c>,
+ <c>EI_FLT</c>, <c>EI_STR</c>, or <c>EI_BIN</c>, indicating the type
+ of object. On failure, <c>-1</c> is returned and the
+ arguments are not updated.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_reg_getival(reg,key)</nametext></name>
- <fsummary>Get an integer object</fsummary>
+ <name><ret>int</ret><nametext>ei_reg_markdirty(reg,key)</nametext></name>
+ <fsummary>Mark an object as dirty.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
</type>
<desc>
- <p>Get the value associated with <c><![CDATA[key]]></c> in the
- registry. The value must be an integer.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry where the object will be looked
- up.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object to look up.
- </p>
- <p>On success, the function returns the value associated with <c><![CDATA[key]]></c>.
- If the object was not found or it was not an integer
- object, -1 is returned. To avoid problems with in-band error
- reporting (i.e. if you cannot distinguish between -1 and a
- valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c>
- instead.</p>
+ <p>Marks a registry object as dirty. This ensures that
+ it is included in the next backup to <c>Mnesia</c>. Normally this
+ operation is not necessary, as all of the normal registry
+ 'set' functions do this automatically. However, if you have
+ retrieved the value of a string or binary object from the
+ registry and modified the contents, then the change is
+ invisible to the registry and the object is assumed to be
+ unmodified. This function allows you to make such modifications
+ and then let the registry know about them.</p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry containing the object.
+ </item>
+ <item><c>key</c> is the name of the object to mark.
+ </item>
+ </list>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>double</ret><nametext>ei_reg_getfval(reg,key)</nametext></name>
- <fsummary>Get a floating point object</fsummary>
+ <name><ret>ei_reg *</ret><nametext>ei_reg_open(size)</nametext></name>
+ <fsummary>Create and open a registry.</fsummary>
+ <type>
+ <v>int size;</v>
+ </type>
+ <desc>
+ <p>Opens (creates) a registry, which initially is empty. To
+ close the registry later, use <c>ei_reg_close()</c>.</p>
+ <p><c>size</c> is the approximate number of objects you
+ intend to store in the registry. As the registry uses a hash table
+ with collision chaining, no absolute upper limit exists on the
+ number of objects that can be stored in it. However, for reasons
+ of efficiency, it is a good idea to choose a number that is
+ appropriate for your needs. To change the size later, use
+ <c>ei_reg_resize()</c>. Notice that the number
+ you provide is increased to the nearest larger prime number.</p>
+ <p>Returns an empty registry on success, otherwise <c>NULL</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_purge(reg)</nametext></name>
+ <fsummary>Remove deleted objects.</fsummary>
<type>
<v>ei_reg *reg;</v>
- <v>const char *key;</v>
</type>
<desc>
- <p>Get the value associated with <c><![CDATA[key]]></c> in the
- registry. The value must be a floating point type.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry where the object will be looked
- up.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object to look up.
- </p>
- <p>On success, the function returns the value associated with <c><![CDATA[key]]></c>.
- If the object was not found or it was not a floating point
- object, -1.0 is returned. To avoid problems with in-band error
- reporting (i.e. if you cannot distinguish between -1.0 and a
- valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c>
- instead.</p>
+ <p>Removes all objects marked for deletion. When objects
+ are deleted with <c>ei_reg_delete()</c> they are not
+ removed from the registry, only marked for later removal.
+ On a later backup to <c>Mnesia</c>, the
+ objects can also be removed from the <c>Mnesia</c> table. If you are
+ not backing up to <c>Mnesia</c>, you may wish to remove the objects
+ manually with this function.</p>
+ <p><c>reg</c> is a registry containing objects marked for
+ deletion.</p>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>const char *</ret><nametext>ei_reg_getsval(reg,key)</nametext></name>
- <fsummary>Get a string object</fsummary>
+ <name><ret>int</ret><nametext>ei_reg_resize(reg,newsize)</nametext></name>
+ <fsummary>Resize a registry.</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>int newsize;</v>
+ </type>
+ <desc>
+ <p>Changes the size of a registry.</p>
+ <p><c>newsize</c> is the new size to make the registry. The
+ number is increased to the nearest larger prime number.</p>
+ <p>On success, the registry is resized, all contents
+ rehashed, and <c>0</c> is returned. On failure, the
+ registry is left unchanged and <c>-1</c> is returned.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_restore(fd,reg,mntab)</nametext></name>
+ <fsummary>Restore a registry from Mnesia.</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>ei_reg *reg;</v>
+ <v>const char *mntab;</v>
+ </type>
+ <desc>
+ <p>The contents of a <c>Mnesia</c> table are read into the registry.</p>
+ <list type="bulleted">
+ <item><c>fd</c> is an open connection to Erlang.
+ <c>Mnesia</c> 3.0 or later must be running on the Erlang node.
+ </item>
+ <item><c>reg</c> is the registry where the data is to be
+ placed.</item>
+ <item><c>mntab</c> is the name of the <c>Mnesia</c> table
+ to read data from.</item>
+ </list>
+ <p>Notice that only tables of a certain format can be
+ restored, that is, those that have been created and backed up to
+ with <c>ei_reg_dump()</c>. If the registry was not empty
+ before the operation, the contents of the table are added to the
+ contents of the registry. If the table contains objects with the
+ same keys as those already in the registry, the registry objects
+ are overwritten with the new values. If the registry
+ contains objects that were not in the table, they are
+ unchanged by this operation.</p>
+ <p>After the restore operation, the entire contents of the
+ registry is marked as unmodified. Notice that this includes any
+ objects that were modified before the restore and not
+ overwritten by the restore.</p>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_setfval(reg,key,f)</nametext></name>
+ <fsummary>Assign a floating point object.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
+ <v>double f;</v>
</type>
<desc>
- <p>Get the value associated with <c><![CDATA[key]]></c> in the
- registry. The value must be a string.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry where the object will be looked
- up.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object to look up.
- </p>
- <p>On success, the function returns the value associated with
- <c><![CDATA[key]]></c>. If the object was not found or it was not a string,
- NULL is returned. To avoid problems with in-band error
- reporting (i.e. if you cannot distinguish between NULL and a
- valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c>
- instead.</p>
+ <p>Creates a key-value pair with the specified <c>key</c>
+ and floating point value <c>f</c>. If an object already
+ exists with the same <c>key</c>, the new value replaces
+ the old one. If the previous value was a binary or string, it is
+ freed with <c>free()</c>.</p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry where the object is to be
+ placed.</item>
+ <item><c>key</c> is the object name.</item>
+ <item><c>f</c> is the floating point value to assign.
+ </item>
+ </list>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>const void *</ret><nametext>ei_reg_getpval(reg,key,size)</nametext></name>
- <fsummary>Get a binary object</fsummary>
+ <name><ret>int</ret><nametext>ei_reg_setival(reg,key,i)</nametext></name>
+ <fsummary>Assign an integer object.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
- <v>int size;</v>
+ <v>int i;</v>
</type>
<desc>
- <p>Get the value associated with <c><![CDATA[key]]></c> in the
- registry. The value must be a binary (pointer) type.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry where the object will be looked
- up.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object to look up.
- </p>
- <p><c><![CDATA[size]]></c> will be initialized to contain the length in
- bytes of the object, if it is found.
- </p>
- <p>On success, the function returns the value associated with
- <c><![CDATA[key]]></c> and indicates its length in <c><![CDATA[size]]></c>.
- If the object was not found or it was not a binary object,
- NULL is returned. To avoid problems with in-band error
- reporting (i.e. if you cannot distinguish between NULL and a
- valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c>
- instead.</p>
+ <p>Creates a key-value pair with the specified <c>key</c>
+ and integer value <c>i</c>. If an object already exists
+ with the same <c>key</c>, the new value replaces the old
+ one. If the previous value was a binary or string, it is freed with
+ <c>free()</c>.</p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry where the object is to be
+ placed.</item>
+ <item><c>key</c> is the object name.</item>
+ <item><c>i</c> is the integer value to assign.</item>
+ </list>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_reg_getval(reg,key,flags,v,...)</nametext></name>
- <fsummary>Get any object</fsummary>
+ <name><ret>int</ret><nametext>ei_reg_setpval(reg,key,p,size)</nametext></name>
+ <fsummary>Assign a binary object.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
- <v>int flags;</v>
- <v>void *v (see below)</v>
+ <v>const void *p;</v>
+ <v>int size;</v>
</type>
<desc>
- <p>This is a general function for retrieving any kind of
- object from the registry.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry where the object will be looked
- up.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object to look up.
- </p>
- <p><c><![CDATA[flags]]></c> indicates the type of object that you are
- looking for. If <c><![CDATA[flags]]></c> is 0, then any kind of object will
- be returned. If <c><![CDATA[flags]]></c> is one of EI_INT, EI_FLT, EI_STR or
- EI_BIN, then only values of that kind will be returned. The
- buffer pointed to by <c><![CDATA[v]]></c> must be large enough to hold the return
- data, i.e. it must be a pointer to one of <c><![CDATA[int]]></c>,
- <c><![CDATA[double]]></c>, <c><![CDATA[char*]]></c> or <c><![CDATA[void*]]></c>, respectively. Also,
- if <c><![CDATA[flags]]></c> is EI_BIN, then a fifth argument <c><![CDATA[int *size]]></c> is required, so that the size of the object can be
- returned.
- </p>
- <p>If the function succeeds, <c><![CDATA[v]]></c> (and <c><![CDATA[size]]></c> if the
- object is binary) will be initialized with the value associated
- with <c><![CDATA[key]]></c>, and the function will return one of EI_INT,
- EI_FLT, EI_STR or EI_BIN, indicating the type of object. On failure the
- function will return -1 and the arguments will not be updated.</p>
+ <p>Creates a key-value pair with the specified <c>key</c>
+ whose "value" is the binary object pointed to by <c>p</c>.
+ If an object already exists with the same <c>key</c>,
+ the new value replaces the old one. If the previous value was a
+ binary or string, it is freed with <c>free()</c>.</p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry where the object is to be
+ placed.</item>
+ <item><c>key</c> is the object name.</item>
+ <item><c>p</c> is a pointer to the binary object. The
+ object itself must have been created through a single call to
+ <c>malloc()</c> or a similar function, so that the
+ registry can later delete it if necessary by calling
+ <c>free()</c>.</item>
+ <item><c>size</c> is the length in bytes of the binary
+ object.</item>
+ </list>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_reg_markdirty(reg,key)</nametext></name>
- <fsummary>Mark an object as dirty </fsummary>
+ <name><ret>int</ret><nametext>ei_reg_setsval(reg,key,s)</nametext></name>
+ <fsummary>Assign a string object.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
+ <v>const char *s;</v>
</type>
<desc>
- <p>Mark a registry object as dirty. This will ensure that
- it is included in the next backup to Mnesia. Normally this
- operation will not be necessary since all of the normal registry
- 'set' functions do this automatically. However if you have
- retrieved the value of a string or binary object from the
- registry and modified the contents, then the change will be
- invisible to the registry and the object will be assumed to be
- unmodified. This function allows you to make such modifications
- and then let the registry know about them.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry containing the object.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object to mark.
- </p>
- <p>The function returns 0 on success, or -1 on failure.</p>
+ <p>Creates a key-value pair with the specified <c>key</c>
+ whose "value" is the specified string <c>s</c>. If an
+ object already exists with the same <c>key</c>, the new
+ value replaces the old one. If the previous value was a binary or
+ string, it is freed with <c>free()</c>.</p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry where the object is to be
+ placed.</item>
+ <item><c>key</c> is the object name.</item>
+ <item><c>s</c> is the string to assign. The string itself
+ must have been created through a single call to
+ <c>malloc()</c> or similar a function,
+ so that the registry can later delete it if
+ necessary by calling <c>free()</c>.</item>
+ </list>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
- <name><ret>int</ret><nametext>ei_reg_delete(reg,key)</nametext></name>
- <fsummary>Delete an object from the registry</fsummary>
+ <name><ret>int</ret><nametext>ei_reg_setval(reg,key,flags,v,...)</nametext></name>
+ <fsummary>Assign a value to any object type.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
+ <v>int flags;</v>
+ <v>v (see below)</v>
</type>
<desc>
- <p>Delete an object from the registry. The object is not
- actually removed from the registry, it is only marked for later
- removal so that on subsequent backups to Mnesia, the
- corresponding object can be removed from the Mnesia table as
- well. If another object is later created with the same key, the
- object will be reused.
- </p>
- <p>The object will be removed from the registry after a call to
- <c><![CDATA[ei_reg_dump()]]></c> or <c><![CDATA[ei_reg_purge()]]></c>.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry containing <c><![CDATA[key]]></c>.
- </p>
- <p><c><![CDATA[key]]></c> is the object to remove.
- </p>
- <p>If the object was found, the function returns 0 indicating
- success. Otherwise the function returns -1.</p>
+ <p>Creates a key-value pair with the specified <c>key</c>
+ whose value is specified by <c>v</c>. If an object already
+ exists with the same <c>key</c>, the new value replaces
+ the old one. If the previous value was a binary or string, it is freed
+ with <c>free()</c>.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>reg</c> is the registry where the object is to be
+ placed.</p>
+ </item>
+ <item>
+ <p><c>key</c> is the object name.</p>
+ </item>
+ <item>
+ <p><c>flags</c> indicates the type of the object
+ specified by <c>v</c>. Flags must be one of
+ <c>EI_INT</c>, <c>EI_FLT</c>, <c>EI_STR</c>, and <c>EI_BIN</c>,
+ indicating whether
+ <c>v</c> is <c>int</c>,
+ <c>double</c>, <c>char*</c>, or
+ <c>void*</c>.</p>
+ <p>If <c>flags</c> is <c>EI_BIN</c>, a fifth argument
+ <c>size</c> is required, indicating the size
+ in bytes of the object pointed to by <c>v</c>.</p>
+ </item>
+ </list>
+ <p>If you wish to store an arbitrary pointer in the registry,
+ specify a <c>size</c> of <c>0</c>. In this case, the
+ object itself is not transferred by an
+ <c>ei_reg_dump()</c> operation, only the pointer
+ value.</p>
+ <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_reg_stat(reg,key,obuf)</nametext></name>
- <fsummary>Get object information</fsummary>
+ <fsummary>Get object information.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>const char *key;</v>
<v>struct ei_reg_stat *obuf;</v>
</type>
<desc>
- <p>Return information about an object.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry containing the object.
- </p>
- <p><c><![CDATA[key]]></c> is the name of the object.
- </p>
- <p><c><![CDATA[obuf]]></c> is a pointer to an <c><![CDATA[ei_reg_stat]]></c> structure,
- defined below:
- </p>
+ <p>Returns information about an object.</p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry containing the object.
+ </item>
+ <item><c>key</c> is the object name.</item>
+ <item><c>obuf</c> is a pointer to an
+ <c>ei_reg_stat</c> structure, defined as follows:</item>
+ </list>
<code type="none"><![CDATA[
struct ei_reg_stat {
int attr;
int size;
};
]]></code>
- <p>In <c><![CDATA[attr]]></c> the object's attributes are stored as the logical
- OR of its type (one of EI_INT, EI_FLT, EI_BIN and EI_STR),
- whether it is marked for deletion (EI_DELET) and whether it has
- been modified since the last backup to Mnesia (EI_DIRTY).
- </p>
- <p>The <c><![CDATA[size]]></c> field indicates the size in bytes required to store
- EI_STR (including the terminating 0) and EI_BIN objects, or 0
- for EI_INT and EI_FLT.
- </p>
- <p>The function returns 0 and initializes <c><![CDATA[obuf]]></c> on
- success, or returns -1 on failure.</p>
+ <p>In <c>attr</c> the attributes of the object are stored
+ as the logical <em>OR</em> of its type (one of <c>EI_INT</c>,
+ <c>EI_FLT</c>, <c>EI_BIN</c>, and <c>EI_STR</c>),
+ whether it is marked for deletion (<c>EI_DELET</c>), and whether it
+ has been modified since the last backup to <c>Mnesia</c>
+ (<c>EI_DIRTY</c>).</p>
+ <p>Field <c>size</c> indicates the size in bytes required
+ to store <c>EI_STR</c> (including the terminating <c>0</c>) and
+ <c>EI_BIN</c> objects, or <c>0</c> for <c>EI_INT</c> and
+ <c>EI_FLT</c>.</p>
+ <p>Returns <c>0</c> and initializes <c>obuf</c> on success,
+ otherwise <c>-1</c>.</p>
</desc>
</func>
+
<func>
<name><ret>int</ret><nametext>ei_reg_tabstat(reg,obuf)</nametext></name>
- <fsummary>Get registry information</fsummary>
+ <fsummary>Get registry information.</fsummary>
<type>
<v>ei_reg *reg;</v>
<v>struct ei_reg_tabstat *obuf;</v>
</type>
<desc>
- <p>Return information about a registry. Using information
+ <p>Returns information about a registry. Using information
returned by this function, you can see whether the size of the
- registry is suitable for the amount of data it contains.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry to return information about.
- </p>
- <p><c><![CDATA[obuf]]></c> is a pointer to an <c><![CDATA[ei_reg_tabstat]]></c> structure,
- defined below:
- </p>
+ registry is suitable for the amount of data it contains.</p>
+ <list type="bulleted">
+ <item><c>reg</c> is the registry to return information
+ about.</item>
+ <item><c>obuf</c> is a pointer to an
+ <c>ei_reg_tabstat</c> structure, defined as follows:
+ </item>
+ </list>
<code type="none"><![CDATA[
struct ei_reg_tabstat {
int size;
@@ -487,126 +615,23 @@ struct ei_reg_tabstat {
int collisions;
};
]]></code>
- <p>The <c><![CDATA[size]]></c> field indicates the number of hash positions
+ <p>Field <c>size</c> indicates the number of hash positions
in the registry. This is the number you provided when you
created or last resized the registry, rounded up to the nearest
- prime.
- </p>
- <p><c><![CDATA[nelem]]></c> indicates the number of elements stored in the
- registry. It includes objects that are deleted but not purged.
- </p>
- <p><c><![CDATA[npos]]></c> indicates the number of unique positions that are
- occupied in the registry.
- </p>
- <p><c><![CDATA[collisions]]></c> indicates how many elements are sharing
- positions in the registry.
- </p>
- <p>On success, the function returns 0 and <c><![CDATA[obuf]]></c> is
- initialized to contain table statistics. On failure, the function
- returns -1.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_reg_dump(fd,reg,mntab,flags)</nametext></name>
- <fsummary>Back up a registry to Mnesia</fsummary>
- <type>
- <v>int fd;</v>
- <v>ei_reg *reg;</v>
- <v>const char *mntab;</v>
- <v>int flags;</v>
- </type>
- <desc>
- <p>Dump the contents of a registry to a Mnesia table in an
- atomic manner, i.e. either all data will be updated, or none of
- it will. If any errors are encountered while backing up
- the data, the entire operation is aborted.
- </p>
- <p><c><![CDATA[fd]]></c> is an open connection to Erlang.
- Mnesia 3.0 or later must be running on the Erlang node.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry to back up.
- </p>
- <p><c><![CDATA[mntab]]></c> is the name of the Mnesia table where the backed
- up data should be placed. If the table does not exist, it will
- be created automatically using configurable defaults. See your
- Mnesia documentation for information about configuring this
- behaviour.
- </p>
- <p>If <c><![CDATA[flags]]></c> is 0, the backup will include only those
- objects which have been created, modified or deleted since the
- last backup or restore (i.e. an incremental backup). After the
- backup, any objects that were marked dirty are now clean, and any
- objects that had been marked for deletion are deleted.
- </p>
- <p>Alternatively, setting flags to EI_FORCE will cause a full
- backup to be done, and EI_NOPURGE will cause the deleted objects
- to be left in the registry afterwards. These can be bitwise ORed
- together if both behaviours are desired. If EI_NOPURGE was
- specified, you can use <c><![CDATA[ei_reg_purge()]]></c> to explicitly remove
- the deleted items from the registry later.
- </p>
- <p>The function returns 0 on success, or -1 on failure.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_reg_restore(fd,reg,mntab)</nametext></name>
- <fsummary>Restore a registry from Mnesia</fsummary>
- <type>
- <v>int fd;</v>
- <v>ei_reg *reg;</v>
- <v>const char *mntab;</v>
- </type>
- <desc>
- <p>The contents of a Mnesia table are read into the
- registry.
- </p>
- <p><c><![CDATA[fd]]></c> is an open connection to Erlang.
- Mnesia 3.0 or later must be running on the Erlang node.
- </p>
- <p><c><![CDATA[reg]]></c> is the registry where the data should be placed.
- </p>
- <p><c><![CDATA[mntab]]></c> is the name of the Mnesia table to read data
- from.
- </p>
- <p>Note that only tables of a certain format can be
- restored, i.e. those that have been created and backed up to
- with <c><![CDATA[ei_reg_dump()]]></c>. If the registry was not empty before
- the operation, then the contents of the table are added to the
- contents of the registry. If the table contains objects with the
- same keys as those already in the registry, the registry objects
- will be overwritten with the new values. If the registry
- contains objects that were not in the table, they will be
- unchanged by this operation.
- </p>
- <p>After the restore operation, the entire contents of the
- registry is marked as unmodified. Note that this includes any
- objects that were modified before the restore and not
- overwritten by the restore.
- </p>
- <p>The function returns 0 on success, or -1 on failure.</p>
- </desc>
- </func>
- <func>
- <name><ret>int</ret><nametext>ei_reg_purge(reg)</nametext></name>
- <fsummary>Remove deleted objects</fsummary>
- <type>
- <v>ei_reg *reg;</v>
- </type>
- <desc>
- <p>Remove all objects marked for deletion. When objects
- are deleted with <c><![CDATA[ei_reg_delete()]]></c> they are not actually
- removed from the registry, only marked for later removal. This
- is so that on a subsequent backup to Mnesia, the
- objects can also be removed from the Mnesia table. If you are
- not backing up to Mnesia then you may wish to remove the objects
- manually with this function.
- </p>
- <p><c><![CDATA[reg]]></c> is a registry containing objects marked for
- deletion.
- </p>
- <p>The function returns 0 on success, or -1 on failure.</p>
+ prime number.</p>
+ <list type="bulleted">
+ <item><c>nelem</c> indicates the number of elements stored
+ in the registry. It includes objects that are deleted but not
+ purged.</item>
+ <item><c>npos</c> indicates the number of unique positions
+ that are occupied in the registry.</item>
+ <item><c>collisions</c> indicates how many elements are
+ sharing positions in the registry.</item>
+ </list>
+ <p>On success, <c>0</c> is returned and
+ <c>obuf</c> is initialized to contain table statistics,
+ otherwise <c>-1</c> is returned.</p>
</desc>
</func>
</funcs>
</cref>
-
diff --git a/lib/erl_interface/src/README b/lib/erl_interface/src/README
index feee2e48e8..7591615f78 100644
--- a/lib/erl_interface/src/README
+++ b/lib/erl_interface/src/README
@@ -11,7 +11,7 @@ Also, assertions are enabled, meaning that the code will be a
little bit slower. In the final release, there will be two
alternative libraries shipped, with and without assertions.
-If an assertion triggers, there will be a printout similiar to this
+If an assertion triggers, there will be a printout similar to this
one:
Assertion failed: ep != NULL in erl_eterm.c, line 694
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index 6dc51adee1..ea9ecb31d5 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2000-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -423,7 +423,7 @@ int ei_connect_xinit(ei_cnode* ec, const char *thishostname,
}
#endif /* _REENTRANT */
- ec->creation = creation;
+ ec->creation = creation & 0x3; /* 2 bits */
if (cookie) {
if (strlen(cookie) >= sizeof(ec->ei_connect_cookie)) {
@@ -462,7 +462,7 @@ int ei_connect_xinit(ei_cnode* ec, const char *thishostname,
strcpy(ec->self.node,thisnodename);
ec->self.num = 0;
ec->self.serial = 0;
- ec->self.creation = creation;
+ ec->self.creation = creation & 0x3; /* 2 bits */
if ((dbglevel = getenv("EI_TRACELEVEL")) != NULL ||
(dbglevel = getenv("ERL_DEBUG_DIST")) != NULL)
@@ -497,7 +497,8 @@ int ei_connect_init(ei_cnode* ec, const char* this_node_name,
}
#endif /* _REENTRANT */
- if (gethostname(thishostname, EI_MAXHOSTNAMELEN) == -1) {
+ /* gethostname requires len to be max(hostname) + 1 */
+ if (gethostname(thishostname, EI_MAXHOSTNAMELEN+1) == -1) {
#ifdef __WIN32__
EI_TRACE_ERR1("ei_connect_init","Failed to get host name: %d",
WSAGetLastError());
@@ -613,7 +614,8 @@ int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned ms)
hp = ei_gethostbyname_r(hostname,&host,buffer,1024,&ei_h_errno);
if (hp == NULL) {
char thishostname[EI_MAXHOSTNAMELEN+1];
- if (gethostname(thishostname,EI_MAXHOSTNAMELEN) < 0) {
+ /* gethostname requies len to be max(hostname) + 1*/
+ if (gethostname(thishostname,EI_MAXHOSTNAMELEN+1) < 0) {
EI_TRACE_ERR0("ei_connect_tmo",
"Failed to get name of this host");
erl_errno = EHOSTUNREACH;
@@ -636,7 +638,8 @@ int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned ms)
#else /* __WIN32__ */
if ((hp = ei_gethostbyname(hostname)) == NULL) {
char thishostname[EI_MAXHOSTNAMELEN+1];
- if (gethostname(thishostname,EI_MAXHOSTNAMELEN) < 0) {
+ /* gethostname requires len to be max(hostname) + 1 */
+ if (gethostname(thishostname,EI_MAXHOSTNAMELEN+1) < 0) {
EI_TRACE_ERR1("ei_connect_tmo",
"Failed to get name of this host: %d",
WSAGetLastError());
@@ -1708,28 +1711,36 @@ error:
static int get_home(char *buf, int size)
{
- char* homedrive;
- char* homepath;
-
#ifdef __WIN32__
- homedrive = getenv("HOMEDRIVE");
- homepath = getenv("HOMEPATH");
-#else
- homedrive = "";
- homepath = getenv("HOME");
-#endif
+ char* homedrive = getenv("HOMEDRIVE");
+ char* homepath = getenv("HOMEPATH");
- if (!homedrive || !homepath) {
- buf[0] = '.';
- buf[1] = '\0';
- return 1;
- } else if (strlen(homedrive)+strlen(homepath) < size-1) {
+ if (homedrive && homepath) {
+ if (strlen(homedrive)+strlen(homepath) >= size)
+ return 0;
strcpy(buf, homedrive);
strcat(buf, homepath);
return 1;
}
-
- return 0;
+ else {
+ int len = GetWindowsDirectory(buf, size);
+ if (len) {
+ return (len < size);
+ }
+ }
+#else
+ char* homepath = getenv("HOME");
+ if (homepath) {
+ if (strlen(homepath) >= size)
+ return 0;
+ strcpy(buf, homepath);
+ return 1;
+ }
+#endif
+
+ buf[0] = '.';
+ buf[1] = '\0';
+ return 1;
}
diff --git a/lib/erl_interface/src/encode/encode_atom.c b/lib/erl_interface/src/encode/encode_atom.c
index c1817628e5..6117aae37e 100644
--- a/lib/erl_interface/src/encode/encode_atom.c
+++ b/lib/erl_interface/src/encode/encode_atom.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2016. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,6 @@
static int verify_ascii_atom(const char* src, int slen);
static int verify_utf8_atom(const char* src, int slen);
-static int is_latin1_as_utf8(const char *p, int len);
int ei_encode_atom(char *buf, int *index, const char *p)
{
@@ -34,7 +33,7 @@ int ei_encode_atom(char *buf, int *index, const char *p)
if (len >= MAXATOMLEN)
len = MAXATOMLEN - 1;
- return ei_encode_atom_len_as(buf, index, p, len, ERLANG_LATIN1, ERLANG_LATIN1);
+ return ei_encode_atom_len_as(buf, index, p, len, ERLANG_LATIN1, 0);
}
int ei_encode_atom_len(char *buf, int *index, const char *p, int len)
@@ -42,7 +41,7 @@ int ei_encode_atom_len(char *buf, int *index, const char *p, int len)
/* This function is documented to truncate at MAXATOMLEN (256) */
if (len >= MAXATOMLEN)
len = MAXATOMLEN - 1;
- return ei_encode_atom_len_as(buf, index, p, len, ERLANG_LATIN1, ERLANG_LATIN1);
+ return ei_encode_atom_len_as(buf, index, p, len, ERLANG_LATIN1, 0);
}
int ei_encode_atom_as(char *buf, int *index, const char *p,
@@ -64,46 +63,11 @@ int ei_encode_atom_len_as(char *buf, int *index, const char *p, int len,
return -1;
}
- if (to_enc == (ERLANG_LATIN1 | ERLANG_UTF8)) {
- if (from_enc == ERLANG_UTF8) {
- to_enc = is_latin1_as_utf8(p, len) ? ERLANG_LATIN1 : ERLANG_UTF8;
- }
- else {
- to_enc = from_enc;
- }
- }
- switch(to_enc) {
- case ERLANG_LATIN1:
- if (buf) {
- put8(s,ERL_ATOM_EXT);
- switch (from_enc) {
- case ERLANG_UTF8:
- len = utf8_to_latin1(s+2, p, len, MAXATOMLEN-1, NULL);
- if (len < 0) return -1;
- break;
- case ERLANG_ASCII:
- if (verify_ascii_atom(p, len) < 0) return -1;
- memcpy(s+2, p, len);
- break;
- case ERLANG_LATIN1:
- memcpy(s+2, p, len);
- break;
- default:
- return -1;
- }
- put16be(s,len);
- }
- else {
- s += 3;
- if (from_enc == ERLANG_UTF8) {
- len = utf8_to_latin1(NULL, p, len, MAXATOMLEN-1, NULL);
- if (len < 0) return -1;
- } else if (from_enc == ERLANG_ASCII)
- if (verify_ascii_atom(p, len) < 0) return -1;
- }
- break;
-
- case ERLANG_UTF8:
+ /*
+ * Since OTP 20 we totally ignore 'to_enc'
+ * and alway encode as UTF8.
+ */
+ {
offs = 1 + 1;
switch (from_enc) {
case ERLANG_LATIN1:
@@ -133,10 +97,6 @@ int ei_encode_atom_len_as(char *buf, int *index, const char *p, int len,
}
}
else s+= offs;
- break;
-
- default:
- return -1;
}
s += len;
@@ -197,13 +157,3 @@ static int verify_utf8_atom(const char* src, int slen)
return 0;
}
-/* Only latin1 code points in utf8 string?
- */
-static int is_latin1_as_utf8(const char *p, int len)
-{
- int i;
- for (i=0; i<len; i++) {
- if ((unsigned char)p[i] > 0xC3) return 0;
- }
- return 1;
-}
diff --git a/lib/erl_interface/src/encode/encode_boolean.c b/lib/erl_interface/src/encode/encode_boolean.c
index 61e7e5e6e7..4350c258ee 100644
--- a/lib/erl_interface/src/encode/encode_boolean.c
+++ b/lib/erl_interface/src/encode/encode_boolean.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2016. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,12 +32,12 @@ int ei_encode_boolean(char *buf, int *index, int p)
val = p ? "true" : "false";
len = strlen(val);
- if (!buf) s += 3;
+ if (!buf) s += 2;
else {
- put8(s,ERL_ATOM_EXT);
- put16be(s,len);
+ put8(s, ERL_SMALL_ATOM_UTF8_EXT);
+ put8(s, len);
- memmove(s,val,len); /* unterminated string */
+ memcpy(s,val,len); /* unterminated string */
}
s += len;
diff --git a/lib/erl_interface/src/legacy/erl_eterm.c b/lib/erl_interface/src/legacy/erl_eterm.c
index e4b3b49c7d..9ad92121f4 100644
--- a/lib/erl_interface/src/legacy/erl_eterm.c
+++ b/lib/erl_interface/src/legacy/erl_eterm.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -188,14 +188,20 @@ char* erl_atom_ptr_latin1(Erl_Atom_data* a)
char* erl_atom_ptr_utf8(Erl_Atom_data* a)
{
if (a->utf8 == NULL) {
- int dlen = a->lenL * 2; /* over estimation */
- a->utf8 = malloc(dlen + 1);
- a->lenU = latin1_to_utf8(a->utf8, a->latin1, a->lenL, dlen, NULL);
- a->utf8[a->lenU] = '\0';
+ erlang_char_encoding enc;
+ a->lenU = latin1_to_utf8(NULL, a->latin1, a->lenL, a->lenL*2, &enc);
+ if (enc == ERLANG_ASCII) {
+ a->utf8 = a->latin1;
+ }
+ else {
+ a->utf8 = malloc(a->lenU + 1);
+ latin1_to_utf8(a->utf8, a->latin1, a->lenL, a->lenU, NULL);
+ a->utf8[a->lenU] = '\0';
+ }
}
return a->utf8;
-
}
+
int erl_atom_size_latin1(Erl_Atom_data* a)
{
if (a->latin1 == NULL) {
diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c
index 2bdf5f2134..caa171858d 100644
--- a/lib/erl_interface/src/legacy/erl_marshal.c
+++ b/lib/erl_interface/src/legacy/erl_marshal.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -175,10 +175,9 @@ static void encode_atom(Erl_Atom_data* a, unsigned char **ext)
int ix = 0;
if (a->latin1) {
ei_encode_atom_len_as((char*)*ext, &ix, a->latin1, a->lenL,
- ERLANG_LATIN1, ERLANG_LATIN1);
+ ERLANG_LATIN1, ERLANG_UTF8);
}
- else if (ei_encode_atom_len_as((char*)*ext, &ix, a->utf8, a->lenU,
- ERLANG_UTF8, ERLANG_LATIN1) < 0) {
+ else {
ei_encode_atom_len_as((char*)*ext, &ix, a->utf8, a->lenU,
ERLANG_UTF8, ERLANG_UTF8);
}
@@ -542,12 +541,8 @@ int erl_term_len(ETERM *ep)
static int atom_len_helper(Erl_Atom_data* a)
{
- if (erl_atom_ptr_latin1(a)) {
- return 1 + 2 + a->lenL; /* ERL_ATOM_EXT */
- }
- else {
- return 1 + 1 + (a->lenU > 255) + a->lenU;
- }
+ (void) erl_atom_ptr_utf8(a);
+ return 1 + 1 + (a->lenU > 255) + a->lenU;
}
static int erl_term_len_helper(ETERM *ep, int dist)
@@ -1626,7 +1621,7 @@ static int cmp_refs(unsigned char **e1, unsigned char **e2)
if (cre1 != cre2)
return cre1 < cre2 ? -1 : 1;
- /* ... and then finaly ids. */
+ /* ... and then finally ids. */
if (n1 != n2) {
unsigned char zero[] = {0, 0, 0, 0};
if (n1 > n2)
@@ -1791,7 +1786,7 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2)
if (port1.creation < port2.creation) return -1;
else if (port1.creation > port2.creation) return 1;
- /* ... and then finaly ids. */
+ /* ... and then finally ids. */
if (port1.id < port2.id) return -1;
else if (port1.id > port2.id) return 1;
diff --git a/lib/erl_interface/src/misc/ei_locking.c b/lib/erl_interface/src/misc/ei_locking.c
index 85b2a5fd8b..a5ddbb85f2 100644
--- a/lib/erl_interface/src/misc/ei_locking.c
+++ b/lib/erl_interface/src/misc/ei_locking.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1997-2016. All Rights Reserved.
+ * Copyright Ericsson AB 1997-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -76,8 +76,8 @@ ei_mutex_t *ei_mutex_create(void)
return l;
}
-/*
- * Free a mutex and the structure asociated with it.
+/*
+ * Free a mutex and the structure associated with it.
*
* This function attempts to obtain the mutex before releasing it;
* If nblock == 1 and the mutex was unavailable, the function will
diff --git a/lib/erl_interface/src/misc/ei_portio.h b/lib/erl_interface/src/misc/ei_portio.h
index fbb61b0ccf..bded811a35 100644
--- a/lib/erl_interface/src/misc/ei_portio.h
+++ b/lib/erl_interface/src/misc/ei_portio.h
@@ -21,7 +21,7 @@
*/
#ifndef _EI_PORTIO_H
#define _EI_PORTIO_H
-#if !defined(__WIN32__) || !defined(VXWORKS)
+#if !defined(__WIN32__) && !defined(VXWORKS)
#ifdef HAVE_WRITEV
/* Declaration of struct iovec *iov should be visible in this scope. */
#include <sys/uio.h>
diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c
index d233ed26a2..7577a07a3e 100644
--- a/lib/erl_interface/src/prog/erl_call.c
+++ b/lib/erl_interface/src/prog/erl_call.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -325,7 +325,8 @@ int erl_call(int argc, char **argv)
initWinSock();
#endif
- if (gethostname(h_hostname, EI_MAXHOSTNAMELEN) < 0) {
+ /* gethostname requires len to be max(hostname) + 1 */
+ if (gethostname(h_hostname, EI_MAXHOSTNAMELEN+1) < 0) {
fprintf(stderr,"erl_call: failed to get host name: %d\n", errno);
exit(1);
}
diff --git a/lib/erl_interface/src/prog/erl_start.c b/lib/erl_interface/src/prog/erl_start.c
index d8f0632341..670a5900c9 100644
--- a/lib/erl_interface/src/prog/erl_start.c
+++ b/lib/erl_interface/src/prog/erl_start.c
@@ -17,7 +17,6 @@
*
* %CopyrightEnd%
*
-
*/
/* An exception from using eidef.h, use config.h directly */
@@ -45,7 +44,7 @@
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
-#include <netinet/tcp.h>
+#include <netinet/tcp.h>
#include <symLib.h>
#include <sysSymTbl.h>
#include <sysLib.h>
@@ -117,9 +116,9 @@ static int unique_id(void);
static unsigned long spawn_erlang_epmd(ei_cnode *ec,
char *alive,
Erl_IpAddr adr,
- int flags,
- char *erl_or_epmd,
- char *args[],
+ int flags,
+ char *erl_or_epmd,
+ char *args[],
int port,
int is_erlang);
#else
@@ -161,10 +160,10 @@ int erl_start_sys(ei_cnode *ec, char *alive, Erl_IpAddr adr, int flags,
r = ERL_SYS_ERROR;
goto done;
}
-
+
memset(&addr,0,sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = 0;
if (bind(sockd,(struct sockaddr *)&addr,sizeof(addr))<0) {
@@ -179,12 +178,12 @@ int erl_start_sys(ei_cnode *ec, char *alive, Erl_IpAddr adr, int flags,
listen(sockd,5);
#if defined(VXWORKS) || defined(__WIN32__)
- if((pid = spawn_erlang_epmd(ec,alive,adr,flags,erl,args,port,1))
+ if((pid = spawn_erlang_epmd(ec,alive,adr,flags,erl,args,port,1))
== 0)
return ERL_SYS_ERROR;
timeout.tv_usec = 0;
timeout.tv_sec = 10; /* ignoring ERL_START_TIME */
- if((r = wait_for_erlang(sockd,unique_id(),&timeout))
+ if((r = wait_for_erlang(sockd,unique_id(),&timeout))
== ERL_TIMEOUT) {
#if defined(VXWORKS)
taskDelete((int) pid);
@@ -262,7 +261,7 @@ done:
static int unique_id(void){
#if defined(VXWORKS)
return taskIdSelf();
-#else
+#else
return (int) GetCurrentThreadId();
#endif
}
@@ -285,7 +284,7 @@ static int enquote_args(char **oargs, char ***qargs){
for(len=0;oargs[len] != NULL; ++len)
;
args = malloc(sizeof(char *) * (len + 1));
-
+
for(i = 0; i < len; ++i){
qwhole = strchr(oargs[i],' ') != NULL;
extra = qwhole * 2;
@@ -337,16 +336,16 @@ static FUNCPTR lookup_function(char *symname){
static unsigned long spawn_erlang_epmd(ei_cnode *ec,
char *alive,
Erl_IpAddr adr,
- int flags,
- char *erl_or_epmd,
- char *args[],
+ int flags,
+ char *erl_or_epmd,
+ char *args[],
int port,
int is_erlang)
{
#if defined(VXWORKS)
FUNCPTR erlfunc;
#else /* Windows */
- STARTUPINFO sinfo;
+ STARTUPINFO sinfo;
SECURITY_ATTRIBUTES sa;
PROCESS_INFORMATION pinfo;
#endif
@@ -364,7 +363,7 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec,
if(is_erlang){
get_addr(ei_thishostname(ec), &myaddr);
#if defined(VXWORKS)
- inet_ntoa_b(myaddr, iaddrbuf);
+ inet_ntoa_b(myaddr, iaddrbuf);
#else /* Windows */
if((ptr = inet_ntoa(myaddr)) == NULL)
return 0;
@@ -372,7 +371,7 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec,
strcpy(iaddrbuf,ptr);
#endif
}
- if ((flags & ERL_START_REMOTE) ||
+ if ((flags & ERL_START_REMOTE) ||
(is_erlang && (hisaddr->s_addr != myaddr.s_addr))) {
return 0;
} else {
@@ -382,19 +381,17 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec,
#if !defined(VXWORKS)
/* On VxWorks, we dont actually run a command,
we call start_erl() */
- if(!erl_or_epmd)
+ if(!erl_or_epmd)
#endif
erl_or_epmd = (is_erlang) ? DEF_ERL_COMMAND :
DEF_EPMD_COMMAND;
if(is_erlang){
name_format = (flags & ERL_START_LONG) ? ERL_NAME_FMT :
ERL_SNAME_FMT;
- cmdlen +=
+ cmdlen +=
strlen(erl_or_epmd) + (*erl_or_epmd != '\0') +
strlen(name_format) + 1 + strlen(alive) +
- strlen(ERL_REPLY_FMT) + 1 + strlen(iaddrbuf) +
- 2 * FORMATTED_INT_LEN +
- 1;
+ strlen(ERL_REPLY_FMT) + 1 + strlen(iaddrbuf) + 2 * FORMATTED_INT_LEN + 1;
ptr = cmdbuf = malloc(cmdlen);
if(*erl_or_epmd != '\0')
ptr += sprintf(ptr,"%s ",erl_or_epmd);
@@ -484,11 +481,11 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec,
* arguments we use here.
*/
static int exec_erlang(ei_cnode *ec,
- char *alive,
+ char *alive,
Erl_IpAddr adr,
- int flags,
- char *erl,
- char *args[],
+ int flags,
+ char *erl,
+ char *args[],
int port)
{
#if !defined(__WIN32__) && !defined(VXWORKS)
@@ -498,8 +495,11 @@ static int exec_erlang(ei_cnode *ec,
char argbuf[BUFSIZ];
struct in_addr myaddr;
struct in_addr *hisaddr = (struct in_addr *)adr;
-
- get_addr(ei_thishostname(ec), &myaddr);
+
+ if (!get_addr(ei_thishostname(ec), &myaddr)) {
+ fprintf(stderr,"erl_call: failed to find hostname\r\n");
+ return ERL_SYS_ERROR;
+ }
/* on this host? */
/* compare ip addresses, unless forced by flag setting to use rsh */
@@ -525,8 +525,8 @@ static int exec_erlang(ei_cnode *ec,
/* *must* be noinput or node (seems to) hang... */
/* long or short names? */
- sprintf(&argbuf[len], "-noinput %s %s ",
- ((flags & ERL_START_LONG) ? "-name" : "-sname"),
+ sprintf(&argbuf[len], "-noinput %s %s ",
+ ((flags & ERL_START_LONG) ? "-name" : "-sname"),
alive);
len = strlen(argbuf);
@@ -572,7 +572,7 @@ static int exec_erlang(ei_cnode *ec,
fprintf(stderr,"\n\n===== Log started ======\n%s \n",ctime(&t));
fprintf(stderr,"erl_call: %s %s %s\n",argv[0],argv[1],argv[2]);
}
- }
+ }
/* start the system */
execvp(argv[0], argv);
@@ -609,7 +609,7 @@ static void gettimeofday(struct timeval *now, void *dummy){
now->tv_usec = ((ctick - (now->tv_sec * rate))*1000000)/rate;
}
#endif
-
+
/* wait for the remote system to reply */
/*
@@ -648,7 +648,7 @@ static int wait_for_erlang(int sockd, int magic, struct timeval *timeout)
"will timeout at %ld.%06ld\n",
now.tv_sec,now.tv_usec,stop_time.tv_sec,stop_time.tv_usec);
#endif
-
+
while (1) {
FD_ZERO(&rdset);
FD_SET(sockd,&rdset);
@@ -662,7 +662,7 @@ static int wait_for_erlang(int sockd, int magic, struct timeval *timeout)
to.tv_sec--;
}
if (to.tv_sec < 0) return ERL_TIMEOUT;
-
+
#ifdef DEBUG
fprintf(stderr,"erl_call: debug remaining to timeout: %ld.%06ld\n",
to.tv_sec,to.tv_usec);
@@ -690,7 +690,7 @@ static int wait_for_erlang(int sockd, int magic, struct timeval *timeout)
if (FD_ISSET(sockd,&rdset)) {
if ((fd = accept(sockd,(struct sockaddr *)&peer,&len)) < 0)
return ERL_SYS_ERROR;
-
+
/* now get sign-on message and terminate it */
#if defined(__WIN32__)
if ((n=recv(fd,buf,16,0)) >= 0) buf[n]=0x0;
@@ -703,7 +703,6 @@ static int wait_for_erlang(int sockd, int magic, struct timeval *timeout)
fprintf(stderr,"erl_call: debug got %d, expected %d\n",
atoi(buf),magic);
#endif
-
if (atoi(buf) == magic) return 0; /* success */
} /* if FD_SET */
} /* switch */
diff --git a/lib/erl_interface/test/ei_decode_SUITE.erl b/lib/erl_interface/test/ei_decode_SUITE.erl
index 1495a0d5d9..74fb9b8916 100644
--- a/lib/erl_interface/test/ei_decode_SUITE.erl
+++ b/lib/erl_interface/test/ei_decode_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -99,7 +99,7 @@ test_ei_decode_ulonglong(Config) when is_list(Config) ->
%% ######################################################################## %%
-%% A "character" for us is an 8 bit integer, alwasy positive, i.e.
+%% A "character" for us is an 8 bit integer, always positive, i.e.
%% it is unsigned.
%% FIXME maybe the API should change to use "unsigned char" to be clear?!
@@ -179,7 +179,8 @@ test_ei_decode_misc(Config) when is_list(Config) ->
send_term_as_binary(P,foo),
send_term_as_binary(P,''),
- send_term_as_binary(P,'ÅÄÖåäö'),
+ %%send_term_as_binary(P,'ÅÄÖåäö'),
+ send_latin1_atom_as_binary(P, "ÅÄÖåäö"),
send_term_as_binary(P,"foo"),
send_term_as_binary(P,""),
@@ -200,18 +201,19 @@ test_ei_decode_misc(Config) when is_list(Config) ->
test_ei_decode_utf8_atom(Config) ->
P = runner:start(?test_ei_decode_utf8_atom),
- send_utf8_atom_as_binary(P,"å"),
- send_utf8_atom_as_binary(P,"ä"),
- send_term_as_binary(P,'ö'),
- send_term_as_binary(P,'õ'),
+ send_latin1_atom_as_binary(P,"å"),
+ send_latin1_atom_as_binary(P,"ä"),
+ send_latin1_atom_as_binary(P,"ö"),
+ send_latin1_atom_as_binary(P,"õ"),
send_utf8_atom_as_binary(P,[1758]),
send_utf8_atom_as_binary(P,[1758,1758]),
send_utf8_atom_as_binary(P,[1758,1758,1758]),
send_utf8_atom_as_binary(P,[1758,1758,1758,1758]),
- send_utf8_atom_as_binary(P,"a"),
- send_utf8_atom_as_binary(P,"b"),
+ send_latin1_atom_as_binary(P,"a"),
+ send_latin1_atom_as_binary(P,"b"),
+
send_term_as_binary(P,'c'),
send_term_as_binary(P,'d'),
@@ -230,6 +232,9 @@ send_raw(Port, Bin) when is_port(Port) ->
send_utf8_atom_as_binary(Port, String) ->
Port ! {self(), {command, term_to_binary(uc_atup(String))}}.
+send_latin1_atom_as_binary(Port, String) ->
+ Port ! {self(), {command, encode_latin1_atom(String)}}.
+
send_integers(P) ->
send_term_as_binary(P,0), % SMALL_INTEGER_EXT smallest
send_term_as_binary(P,255), % SMALL_INTEGER_EXT largest
@@ -304,6 +309,12 @@ send_integers2(P) ->
send_term_as_binary(P, []), % illegal type
ok.
+encode_latin1_atom(String) ->
+ Len = length(String),
+ %% Use ATOM_EXT (not SMALL_*) to simulate old term_to_binary
+ TagLen = [$d, Len bsr 8, Len band 16#ff],
+ list_to_binary([131, TagLen, String]).
+
uc_atup(ATxt) ->
string_to_atom(ATxt).
diff --git a/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
index cfe9083065..b7a2c4bb8b 100644
--- a/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
+++ b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2004-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2004-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -102,7 +102,7 @@ int ei_decode_my_string(const char *buf, int *index, char *to,
} \
\
if (size1 != SIZE) { \
- fail("size of encoded data is incorrect"); \
+ fail1("size of encoded data (%d) is incorrect", size1); \
return; \
} \
} \
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE.erl b/lib/erl_interface/test/ei_decode_encode_SUITE.erl
index 570a91e2da..160720b413 100644
--- a/lib/erl_interface/test/ei_decode_encode_SUITE.erl
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -125,7 +125,7 @@ test_ei_decode_encode(Config) when is_list(Config) ->
% We read two packets for each test, the ei_decode_encode and ei_x_decode_encode version....
send_rec(P, Term) when is_port(P) ->
- P ! {self(), {command, term_to_binary(Term)}},
+ P ! {self(), {command, term_to_binary(Term, [{minor_version, 2}])}},
{_B,Term} = get_buf_and_term(P).
@@ -170,7 +170,6 @@ get_binary(P) ->
-define(VERSION_MAGIC, 131).
--define(ATOM_EXT, 100).
-define(REFERENCE_EXT, 101).
-define(PORT_EXT, 102).
-define(PID_EXT, 103).
diff --git a/lib/erl_interface/test/ei_encode_SUITE.erl b/lib/erl_interface/test/ei_encode_SUITE.erl
index ac6ec9cf4e..8857b092f3 100644
--- a/lib/erl_interface/test/ei_encode_SUITE.erl
+++ b/lib/erl_interface/test/ei_encode_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -184,17 +184,17 @@ test_ei_encode_misc(Config) when is_list(Config) ->
{<<70,_:8/binary>>,Fp1} = get_buf_and_term(P),
true = match_float(Fp1, 1.0),
- {<<100,0,5,"false">>,false} = get_buf_and_term(P),
- {<<100,0,4,"true">> ,true} = get_buf_and_term(P),
- {<<100,0,4,"true">> ,true} = get_buf_and_term(P),
- {<<100,0,4,"true">> ,true} = get_buf_and_term(P),
+ {<<$w,5,"false">>,false} = get_buf_and_term(P),
+ {<<$w,4,"true">> ,true} = get_buf_and_term(P),
+ {<<$w,4,"true">> ,true} = get_buf_and_term(P),
+ {<<$w,4,"true">> ,true} = get_buf_and_term(P),
- {<<100,0,3,"foo">>,foo} = get_buf_and_term(P),
- {<<100,0,3,"foo">>,foo} = get_buf_and_term(P),
- {<<100,0,0,"">>,''} = get_buf_and_term(P),
- {<<100,0,0,"">>,''} = get_buf_and_term(P),
- {<<100,0,6,"ÅÄÖåäö">>,'ÅÄÖåäö'} = get_buf_and_term(P),
- {<<100,0,6,"ÅÄÖåäö">>,'ÅÄÖåäö'} = get_buf_and_term(P),
+ {<<$w,3,"foo">>,foo} = get_buf_and_term(P),
+ {<<$w,3,"foo">>,foo} = get_buf_and_term(P),
+ {<<$w,0,"">>,''} = get_buf_and_term(P),
+ {<<$w,0,"">>,''} = get_buf_and_term(P),
+ {<<$w,12,"ÅÄÖåäö"/utf8>>,'ÅÄÖåäö'} = get_buf_and_term(P),
+ {<<$w,12,"ÅÄÖåäö"/utf8>>,'ÅÄÖåäö'} = get_buf_and_term(P),
{<<107,0,3,"foo">>,"foo"} = get_buf_and_term(P),
{<<107,0,3,"foo">>,"foo"} = get_buf_and_term(P),
@@ -239,12 +239,12 @@ test_ei_encode_utf8_atom(Config) ->
P = runner:start(?test_ei_encode_utf8_atom),
{<<119,2,195,133>>,'Å'} = get_buf_and_term(P),
- {<<100,0,1,197>>,'Å'} = get_buf_and_term(P),
- {<<100,0,1,197>>,'Å'} = get_buf_and_term(P),
+ {<<119,2,195,133>>,'Å'} = get_buf_and_term(P),
+ {<<119,2,195,133>>,'Å'} = get_buf_and_term(P),
{<<119,2,195,133>>,'Å'} = get_buf_and_term(P),
{<<119,1,$A>>,'A'} = get_buf_and_term(P),
- {<<100,0,1,$A>>,'A'} = get_buf_and_term(P),
+ {<<119,1,$A>>,'A'} = get_buf_and_term(P),
runner:recv_eot(P),
ok.
@@ -254,13 +254,13 @@ test_ei_encode_utf8_atom_len(Config) ->
P = runner:start(?test_ei_encode_utf8_atom_len),
{<<119,2,195,133>>,'Å'} = get_buf_and_term(P),
- {<<100,0,2,197,196>>,'ÅÄ'} = get_buf_and_term(P),
- {<<100,0,1,197>>,'Å'} = get_buf_and_term(P),
+ {<<119,4,195,133,195,132>>,'ÅÄ'} = get_buf_and_term(P),
+ {<<119,2,195,133>>,'Å'} = get_buf_and_term(P),
{<<119,4,195,133,195,132>>,'ÅÄ'} = get_buf_and_term(P),
{<<119,1,$A>>,'A'} = get_buf_and_term(P),
- {<<100,0,2,$A,$B>>,'AB'} = get_buf_and_term(P),
- {<<100,0,255,_:(255*8)>>,_} = get_buf_and_term(P),
+ {<<119,2,$A,$B>>,'AB'} = get_buf_and_term(P),
+ {<<119,255,_:(255*8)>>,_} = get_buf_and_term(P),
runner:recv_eot(P),
ok.
diff --git a/lib/erl_interface/test/erl_eterm_SUITE.erl b/lib/erl_interface/test/erl_eterm_SUITE.erl
index 0e51a50c19..3d1e33081b 100644
--- a/lib/erl_interface/test/erl_eterm_SUITE.erl
+++ b/lib/erl_interface/test/erl_eterm_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@
%%% 2. Constructing terms (the erl_mk_xxx() functions and erl_copy_term()).
%%% 3. Extracting & info functions (erl_hd(), erl_length() etc).
%%% 4. I/O list functions.
-%%% 5. Miscellanous functions.
+%%% 5. Miscellaneous functions.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-export([all/0, suite/0,
diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
index 36cf086ed2..1e986feacf 100644
--- a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
+++ b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2002-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -407,7 +407,7 @@ test_compare_ext(char *test_desc,
}
-#define ATOM_EXT (100)
+#define SMALL_ATOM_UTF8_EXT (119)
#define REFERENCE_EXT (101)
#define PORT_EXT (102)
#define PID_EXT (103)
@@ -429,13 +429,13 @@ write_atom(unsigned char *buf, char *atom)
len = 0;
while(atom[len]) {
- buf[len + 3] = atom[len];
+ buf[len + 2] = atom[len];
len++;
}
- buf[0] = ATOM_EXT;
- PUT_UINT16(&buf[1], len);
+ buf[0] = SMALL_ATOM_UTF8_EXT;
+ buf[1] = len;
- return buf + 3 + len;
+ return buf + 2 + len;
}
static unsigned char *
diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk
index 33705d1e8b..01fcee86dd 100644
--- a/lib/erl_interface/vsn.mk
+++ b/lib/erl_interface/vsn.mk
@@ -1,2 +1,2 @@
-EI_VSN = 3.9
+EI_VSN = 3.10
ERL_INTERFACE_VSN = $(EI_VSN)
diff --git a/lib/eunit/COPYING b/lib/eunit/COPYING
deleted file mode 100644
index 223ede7de3..0000000000
--- a/lib/eunit/COPYING
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/lib/eunit/doc/overview.edoc b/lib/eunit/doc/overview.edoc
index 3a46e991cb..dc9f858812 100644
--- a/lib/eunit/doc/overview.edoc
+++ b/lib/eunit/doc/overview.edoc
@@ -578,7 +578,7 @@ results for equality, if testing is enabled. If the values are not
equal, an informative exception will be generated; see the `assert'
macro for further details.
-`assertEqual' is more suitable than than `assertMatch' when the
+`assertEqual' is more suitable than `assertMatch' when the
left-hand side is a computed value rather than a simple pattern, and
gives more details than `?assert(Expect =:= Expr)'.
@@ -994,7 +994,7 @@ specified node. `local' means that the current process will handle both
setup/teardown and running the tests - the drawback is that if a test
times out so that the process is killed, the <em>cleanup will not be
performed</em>; hence, avoid this for persistent fixtures such as file
-operations. In general, 'local' should only be used when:
+operations. In general, `local' should only be used when:
<ul>
<li>the setup/teardown needs to be executed by the process that will
run the tests;</li>
diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml
index 88602e8222..2a4ca6d12c 100644
--- a/lib/eunit/doc/src/notes.xml
+++ b/lib/eunit/doc/src/notes.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -33,6 +33,54 @@
</header>
<p>This document describes the changes made to the EUnit application.</p>
+<section><title>Eunit 2.3.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The surefire reports from <c>eunit</c> will no longer
+ have names with embedded double quotes.</p>
+ <p>
+ Own Id: OTP-14287</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Eunit 2.3.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The address to the FSF in the license header has been
+ updated.</p>
+ <p>
+ Own Id: OTP-14084</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Eunit 2.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ When asserts were moved out to a separate header file,
+ the automatic enabling of asserts when testing is enabled
+ stopped working.</p>
+ <p>
+ Own Id: OTP-13892</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Eunit 2.3</title>
<section><title>Improvements and New Features</title>
@@ -465,7 +513,7 @@
<list>
<item>
<p>
- Miscellanous updates.</p>
+ Miscellaneous updates.</p>
<p>
Own Id: OTP-8038</p>
</item>
diff --git a/lib/eunit/include/eunit.hrl b/lib/eunit/include/eunit.hrl
index 7fd6c206a4..3cc36a27bc 100644
--- a/lib/eunit/include/eunit.hrl
+++ b/lib/eunit/include/eunit.hrl
@@ -1,17 +1,26 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
+%%
+%% NOTE: An object file that uses the macros in this header file shall
+%% never be considered a derived work under the the LGPL; these macros
+%% shall be regarded as "small" regardless of the exact line count.
%%
%% Copyright (C) 2004-2006 Mickaël Rémond, Richard Carlsson
@@ -51,7 +60,9 @@
%% note that the main switch used within this file is NOTEST; however,
%% both TEST and EUNIT may be used to check whether testing is enabled
-ifndef(NOTEST).
--undef(NOASSERT). % testing requires that assertions are enabled
+-ifndef(ASSERT).
+-define(ASSERT, true). % testing requires that assertions are enabled
+-endif.
-ifndef(TEST).
-define(TEST, true).
-endif.
diff --git a/lib/eunit/src/Makefile b/lib/eunit/src/Makefile
index 86a6d8831e..3510d3cc93 100644
--- a/lib/eunit/src/Makefile
+++ b/lib/eunit/src/Makefile
@@ -24,7 +24,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/eunit-$(VSN)
EBIN = ../ebin
INCLUDE=../include
-ERL_COMPILE_FLAGS += -pa $(EBIN) -pa ../../stdlib/ebin -I$(INCLUDE) +warn_unused_vars +nowarn_shadow_vars +warn_unused_import +warn_obsolete_guard
+ERL_COMPILE_FLAGS += -pa $(EBIN) -pa ../../stdlib/ebin -I$(INCLUDE) +nowarn_shadow_vars +warn_unused_import
PARSE_TRANSFORM = eunit_autoexport.erl
diff --git a/lib/eunit/src/eunit.erl b/lib/eunit/src/eunit.erl
index fbfd123c43..1ace85ffde 100644
--- a/lib/eunit/src/eunit.erl
+++ b/lib/eunit/src/eunit.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2004-2009 Mickaël Rémond, Richard Carlsson
%% @author Mickaël Rémond <[email protected]>
@@ -251,7 +256,7 @@ all_options(Opts) ->
false -> Opts;
S ->
{ok, Ts, _} = erl_scan:string(S),
- {ok, V} = erl_parse:parse_term(Ts ++ [{dot,1}]),
+ {ok, V} = erl_parse:parse_term(Ts ++ [{dot,erl_anno:new(1)}]),
if is_list(V) -> Opts ++ V;
true -> Opts ++ [V]
end
diff --git a/lib/eunit/src/eunit_autoexport.erl b/lib/eunit/src/eunit_autoexport.erl
index 7bb78f5ea8..6d52620629 100644
--- a/lib/eunit/src/eunit_autoexport.erl
+++ b/lib/eunit/src/eunit_autoexport.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_data.erl b/lib/eunit/src/eunit_data.erl
index cc002cb449..a16faf2e80 100644
--- a/lib/eunit/src/eunit_data.erl
+++ b/lib/eunit/src/eunit_data.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_internal.hrl b/lib/eunit/src/eunit_internal.hrl
index 8e1e27811f..65f4c433e7 100644
--- a/lib/eunit/src/eunit_internal.hrl
+++ b/lib/eunit/src/eunit_internal.hrl
@@ -1,5 +1,22 @@
-%% -------------------------------------------------------------------
-%% File: eunit_internal.hrl
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% Copyright (C) 2006 Richard Carlsson <[email protected]>
diff --git a/lib/eunit/src/eunit_lib.erl b/lib/eunit/src/eunit_lib.erl
index 9dbb4835f8..aa2cffc66d 100644
--- a/lib/eunit/src/eunit_lib.erl
+++ b/lib/eunit/src/eunit_lib.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2004-2007 Mickaël Rémond, Richard Carlsson
%% @author Mickaël Rémond <[email protected]>
diff --git a/lib/eunit/src/eunit_listener.erl b/lib/eunit/src/eunit_listener.erl
index c34eacb1d6..e652c5b2f6 100644
--- a/lib/eunit/src/eunit_listener.erl
+++ b/lib/eunit/src/eunit_listener.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2009 Richard Carlsson
diff --git a/lib/eunit/src/eunit_proc.erl b/lib/eunit/src/eunit_proc.erl
index 8bdf94c877..e075005238 100644
--- a/lib/eunit/src/eunit_proc.erl
+++ b/lib/eunit/src/eunit_proc.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_serial.erl b/lib/eunit/src/eunit_serial.erl
index da76064a53..d85cc520f2 100644
--- a/lib/eunit/src/eunit_serial.erl
+++ b/lib/eunit/src/eunit_serial.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_server.erl b/lib/eunit/src/eunit_server.erl
index 387976eba1..e46394d88c 100644
--- a/lib/eunit/src/eunit_server.erl
+++ b/lib/eunit/src/eunit_server.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_striptests.erl b/lib/eunit/src/eunit_striptests.erl
index c6ade389ba..2911c90022 100644
--- a/lib/eunit/src/eunit_striptests.erl
+++ b/lib/eunit/src/eunit_striptests.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @author Eric Merritt <[email protected]>
diff --git a/lib/eunit/src/eunit_surefire.erl b/lib/eunit/src/eunit_surefire.erl
index 1b468551d8..2b9f82b075 100644
--- a/lib/eunit/src/eunit_surefire.erl
+++ b/lib/eunit/src/eunit_surefire.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Mickaël Rémond <[email protected]>
%% @copyright 2009 Mickaël Rémond, Paul Guyot
@@ -419,6 +424,7 @@ escape_suitename(String) ->
escape_suitename([], Acc) -> lists:reverse(Acc);
escape_suitename([$ | Tail], Acc) -> escape_suitename(Tail, [$_ | Acc]);
escape_suitename([$' | Tail], Acc) -> escape_suitename(Tail, Acc);
+escape_suitename([$" | Tail], Acc) -> escape_suitename(Tail, Acc);
escape_suitename([$/ | Tail], Acc) -> escape_suitename(Tail, [$: | Acc]);
escape_suitename([$\\ | Tail], Acc) -> escape_suitename(Tail, [$: | Acc]);
escape_suitename([Char | Tail], Acc) when Char < $! -> escape_suitename(Tail, Acc);
diff --git a/lib/eunit/src/eunit_test.erl b/lib/eunit/src/eunit_test.erl
index 62d30b1930..6036537178 100644
--- a/lib/eunit/src/eunit_test.erl
+++ b/lib/eunit/src/eunit_test.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_tests.erl b/lib/eunit/src/eunit_tests.erl
index 5dee1cb49e..07a415eeb1 100644
--- a/lib/eunit/src/eunit_tests.erl
+++ b/lib/eunit/src/eunit_tests.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2007 Richard Carlsson
diff --git a/lib/eunit/src/eunit_tty.erl b/lib/eunit/src/eunit_tty.erl
index f604ca5ba3..77a7cf1fd5 100644
--- a/lib/eunit/src/eunit_tty.erl
+++ b/lib/eunit/src/eunit_tty.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006-2009 Richard Carlsson
diff --git a/lib/eunit/vsn.mk b/lib/eunit/vsn.mk
index b551ee6eb6..107ad5c101 100644
--- a/lib/eunit/vsn.mk
+++ b/lib/eunit/vsn.mk
@@ -1 +1 @@
-EUNIT_VSN = 2.3
+EUNIT_VSN = 2.3.3
diff --git a/lib/gs/AUTHORS b/lib/gs/AUTHORS
deleted file mode 100644
index d19b290592..0000000000
--- a/lib/gs/AUTHORS
+++ /dev/null
@@ -1,16 +0,0 @@
-This application contains source code from Tcl/Tk, see c_src/lib for
-more information.
-
-Original Authors and Contributors:
-
-Anders Dahlin
-Ola Samuelsson
-Klas Eriksson
-Gunilla Arendt
-Peter Olin
-Kent Boortz
-
-contribs/othello Magnus Fr�berg and Torbj�rn T�rnqvist
-contribs/cols Klas Eriksson
-contribs/gsb Fredrik Str�m, Peter Molin
-contribs/mandel Klas Eriksson and Martin Bj�rklund
diff --git a/lib/gs/Makefile b/lib/gs/Makefile
deleted file mode 100644
index 22f935fd38..0000000000
--- a/lib/gs/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1996-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-#
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-#
-# Macros
-#
-
-SUB_DIRECTORIES = src tcl examples doc/src
-
-include vsn.mk
-VSN = $(GS_VSN)
-
-SPECIAL_TARGETS =
-
-#
-# Default Subdir Targets
-#
-include $(ERL_TOP)/make/otp_subdir.mk
-
diff --git a/lib/gs/configure.in b/lib/gs/configure.in
deleted file mode 100644
index e809ba475f..0000000000
--- a/lib/gs/configure.in
+++ /dev/null
@@ -1,46 +0,0 @@
-define([AC_CACHE_LOAD], )dnl
-define([AC_CACHE_SAVE], )dnl
-
-dnl Process this file with autoconf to produce a configure script.
-AC_INIT(src/gs.erl)
-
-if test -z "$ERL_TOP" || test ! -d $ERL_TOP ; then
- AC_MSG_ERROR(You need to set the environment variable ERL_TOP!)
-fi
-erl_top=${ERL_TOP}
-AC_CONFIG_AUX_DIRS($erl_top/erts/autoconf)
-
-dnl FIXME: Should be AC_CANONICAL_TARGET but we follow pattern in
-dnl main configure.in.
-
-if test "X$host" != "Xfree_source" -a "X$host" != "Xwin32"; then
- AC_CANONICAL_HOST
- system_type=${host_cpu}_`echo $host_os | sed 's/^\([[^\.]]*\)\.\(.*\)$/\1/'`
-else
- system_type=$host
-fi
-
-
-
-dnl
-dnl We try to find a prebuilt Tcl/Tk distribution that will later
-dnl be unpacked into "priv/tcl". The 'gstk_port_handler' module
-dnl seach for the "wish" program int this direcory first before
-dnl searching the operating system executable search path.
-dnl
-
-AC_SUBST(TCL_TAR)
-
-AC_MSG_CHECKING(for prebuilt tcl/tk in tcl/binaries/$system_type.tar.gz)
-if test -f "tcl/binaries/$system_type.tar.gz" ; then
- TCL_TAR="binaries/$system_type.tar.gz"
- AC_MSG_RESULT(found)
-else
- TCL_TAR=""
- AC_MSG_RESULT(not found, using PATH at runtime)
-fi
-
-AC_OUTPUT(
- tcl/$host/Makefile:tcl/Makefile.in
- tcl/win32/Makefile:tcl/Makefile.in
- )
diff --git a/lib/gs/doc/html/.gitignore b/lib/gs/doc/html/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/gs/doc/html/.gitignore
+++ /dev/null
diff --git a/lib/gs/doc/man3/.gitignore b/lib/gs/doc/man3/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/gs/doc/man3/.gitignore
+++ /dev/null
diff --git a/lib/gs/doc/pdf/.gitignore b/lib/gs/doc/pdf/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/gs/doc/pdf/.gitignore
+++ /dev/null
diff --git a/lib/gs/doc/src/Makefile b/lib/gs/doc/src/Makefile
deleted file mode 100644
index b270bc84fe..0000000000
--- a/lib/gs/doc/src/Makefile
+++ /dev/null
@@ -1,158 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-#
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include ../../vsn.mk
-VSN=$(GS_VSN)
-APPLICATION=gs
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-XML_APPLICATION_FILES = ref_man.xml
-XML_REF3_FILES = gs.xml
-
-XML_PART_FILES = part.xml \
- part_notes.xml
-XML_CHAPTER_FILES = \
- gs_chapter1.xml \
- gs_chapter2.xml \
- gs_chapter3.xml \
- gs_chapter4.xml \
- gs_chapter5.xml \
- gs_chapter6.xml \
- gs_chapter7.xml \
- gs_chapter8.xml \
- notes.xml
-
-BOOK_FILES = book.xml
-
-GEN_XML = \
- gs_chapter2.xml \
- gs_chapter4.xml \
- gs_chapter5.xml \
- gs_chapter6.xml \
- gs_chapter7.xml \
- gs_chapter8.xml \
-
-XML_FILES = \
- $(BOOK_FILES) $(XML_CHAPTER_FILES) \
- $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES)
-
-GIF_FILES = images/arc.gif \
- images/buttons.gif \
- images/ex1.gif \
- images/ex10.gif \
- images/ex11.gif \
- images/ex12.gif \
- images/ex13.gif \
- images/ex14.gif \
- images/ex15.gif \
- images/ex16.gif \
- images/ex8.gif \
- images/ex9.gif \
- images/gs1-1-image-1.gif \
- images/gs1-1-image-2.gif \
- images/gs1-1-image-3.gif \
- images/gs1-1-image-4.gif \
- images/image.gif \
- images/line.gif \
- images/oval.gif \
- images/packer1.gif \
- images/packer2.gif \
- images/polygon.gif \
- images/rectangle.gif \
- images/text.gif \
- images/window.gif
-
-# ----------------------------------------------------
-
-HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
- $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
-
-INFO_FILE = ../../info
-
-MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3)
-
-HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
-
-TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-XML_FLAGS +=
-DVIPS_FLAGS +=
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-$(HTMLDIR)/%.gif: %.gif
- $(INSTALL_DIR) $(HTMLDIR)/images
- $(INSTALL_DATA) $< $@
-
-docs: pdf html man
-
-$(TOP_PDF_FILE): $(XML_FILES)
-
-pdf: $(TOP_PDF_FILE)
-
-html: gifs $(HTML_REF_MAN_FILE)
-
-clean clean_docs:
- rm -rf $(HTMLDIR)/*
- rm -f $(MAN3DIR)/*
- rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
- rm -f errs core *~ $(GEN_XML)
-
-man: $(MAN3_FILES)
-
-gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
-
-debug opt:
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-release_docs_spec: docs
- $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf"
- $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf"
- $(INSTALL_DIR) "$(RELSYSDIR)/doc/html"
- (/bin/cp -rf $(HTMLDIR) "$(RELSYSDIR)/doc")
- $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)"
- $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3"
- $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3"
-
-
-release_spec:
-
diff --git a/lib/gs/doc/src/book.xml b/lib/gs/doc/src/book.xml
deleted file mode 100644
index 15d911072e..0000000000
--- a/lib/gs/doc/src/book.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE book SYSTEM "book.dtd">
-
-<book xmlns:xi="http://www.w3.org/2001/XInclude">
- <header titlestyle="normal">
- <copyright>
- <year>1997</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>Graphics System (GS)</title>
- <prepared>Klas Eriksson</prepared>
- <docno></docno>
- <date>1997-05-02</date>
- <rev>1.3</rev>
- <file>book.sgml</file>
- </header>
- <insidecover>
- </insidecover>
- <pagetext>Graphics System (GS)</pagetext>
- <preamble>
- <contents level="2"></contents>
- </preamble>
- <parts lift="no">
- <xi:include href="part.xml"/>
- </parts>
- <applications>
- <xi:include href="ref_man.xml"/>
- </applications>
- <releasenotes>
- <xi:include href="notes.xml"/>
- </releasenotes>
- <listofterms></listofterms>
- <index></index>
-</book>
-
diff --git a/lib/gs/doc/src/examples/die_icon b/lib/gs/doc/src/examples/die_icon
deleted file mode 100644
index 52be1869fa..0000000000
--- a/lib/gs/doc/src/examples/die_icon
+++ /dev/null
@@ -1,9 +0,0 @@
-#define die_icon_width 22
-#define die_icon_height 22
-static char die_icon_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x7f, 0x00, 0x80, 0xff, 0x00,
- 0xc0, 0xdd, 0x01, 0xc0, 0x88, 0x01, 0xc0, 0xdd, 0x01, 0xc0, 0xff, 0x01,
- 0xc0, 0xff, 0x01, 0x80, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x3e, 0x00,
- 0x00, 0x3e, 0x00, 0x00, 0x3e, 0x00, 0x08, 0x1c, 0x07, 0xf0, 0xc0, 0x01,
- 0x00, 0x73, 0x00, 0x00, 0x1c, 0x00, 0x80, 0x77, 0x00, 0x60, 0xc0, 0x03,
- 0x00, 0x00, 0x06, 0x00, 0x00, 0x00};
diff --git a/lib/gs/doc/src/examples/ex1.erl b/lib/gs/doc/src/examples/ex1.erl
deleted file mode 100644
index 8ba353a1d7..0000000000
--- a/lib/gs/doc/src/examples/ex1.erl
+++ /dev/null
@@ -1,20 +0,0 @@
--module(ex1).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([init/0]).
-
-init() ->
- S = gs:start(),
- %% the parent of a top-level window is the gs server
- Win = gs:create(window,S,[{width,200},{height,100}]),
- Butt = gs:create(button,Win,[{label, {text,"Press Me"}}]),
- gs:config(Win, {map,true}),
- loop(Butt).
-
-loop(Butt) ->
- receive
- {gs, Butt, click, Data, Args} ->
- io:format("Hello There~n",[]),
- loop(Butt)
- end.
diff --git a/lib/gs/doc/src/examples/ex10.erl b/lib/gs/doc/src/examples/ex10.erl
deleted file mode 100644
index d414aca940..0000000000
--- a/lib/gs/doc/src/examples/ex10.erl
+++ /dev/null
@@ -1,59 +0,0 @@
--module(ex10).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([start/0, init/3]).
-
-start() ->
- start("Pick a fruit:",
- [apple, banana, lemon, orange, strawberry,
- mango, kiwi, pear, cherry,pineapple,peach,apricot]).
-
-start(Text,Items) ->
- spawn(ex10,init,[self(),Text,Items]),
- receive
- {browser,Result} -> Result
- end.
-
-init(Pid,Text,Items) ->
- S=gs:start(),
- Win=gs:window(S,[{width,250},{height,270},
- {title,"Browser"}]),
- Lbl=gs:label(Win,[{label,{text,Text}},{width,250}]),
- Entry=gs:entry(Win,[{y,35},{width,240},{x,5},
- {keypress,true},
- {setfocus,true}]),
- Lb=gs:listbox(Win,[{x,5},{y,65},{width,160},
- {height,195},{vscroll,right},
- {click,true},{doubleclick,true}]),
- Ok=gs:button(Win,[{label,{text,"OK"}},
- {width,40},{x,185},{y,175}]),
- Cancel=gs:button(Win,[{label,{text,"Cancel"}},
- {x,175},{y,225},{width,65}]),
- gs:config(Lb,[{items,Items}]),
- gs:config(Win,{map,true}),
- browser_loop(Pid,Ok,Cancel,Entry,Lb).
-
-browser_loop(Pid,Ok,Cancel,Entry,Lb) ->
- receive
- {gs,Ok,click,_,_} ->
- Txt=gs:read(Entry,text),
- Pid ! {browser,{ok,Txt}};
- {gs,Cancel,click,_,_} ->
- Pid ! {browser,cancel};
- {gs,Entry,keypress,_,['Return'|_]} ->
- Txt=gs:read(Entry,text),
- Pid ! {browser,{ok,Txt}};
- {gs,Entry,keypress,_,_} ->
- browser_loop(Pid,Ok,Cancel,Entry,Lb);
- {gs,Lb,click,_,[Idx, Txt|_]} ->
- gs:config(Entry,{text,Txt}),
- browser_loop(Pid,Ok,Cancel,Entry,Lb);
- {gs,Lb,doubleclick,_,[Idx, Txt|_]} ->
- Pid ! {browser,{ok,Txt}};
- {gs,_,destroy,_,_} ->
- Pid ! {browser,cancel};
- X ->
- io:format("Got X=~w~n",[X]),
- browser_loop(Pid,Ok,Cancel,Entry,Lb)
- end.
diff --git a/lib/gs/doc/src/examples/ex11.erl b/lib/gs/doc/src/examples/ex11.erl
deleted file mode 100644
index 96343c3c22..0000000000
--- a/lib/gs/doc/src/examples/ex11.erl
+++ /dev/null
@@ -1,42 +0,0 @@
--module(ex11).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/3 $ ').
-
--export([start/0,init/0]).
-
-start() ->
- spawn(ex11,init,[]).
-
-init() ->
- I= gs:start(),
- W= gs:window(I,[{title,"Color Demo"},
- {width,300},{height,195}]),
- B=gs:button(W,[{label,{image,"die_icon"}},{x,271},{y,166},
- {width,30}]),
- gs:config(B,[{bg,yellow},{fg,hotpink1},{data,quit}]),
- gs:scale(W,[{text,"Red"},{y,0},{range,{0,255}},
- {orient,horizontal},
- {height,65},{data,red},{pos,42}]),
- gs:scale(W,[{text,"Blue"},{y,65},{range,{0,255}},
- {orient,horizontal},
- {height,65},{data,blue},{pos,42}]),
- gs:scale(W,[{text,"Green"},{y,130},{range,{0,255}},
- {orient,horizontal},
- {height,65},{data,green},{pos,42}]),
- gs:config(W,{map,true}),
- loop(W,0,0,0).
-
-loop(W,R,G,B) ->
- gs:config(W,{bg,{R,G,B}}),
- receive
- {gs,_,click,red,[New_R|_]} ->
- loop(W,New_R,G,B);
- {gs,_,click,green,[New_G|_]} ->
- loop(W,R,New_G,B);
- {gs,_,click,blue,[New_B|_]} ->
- loop(W,R,G,New_B);
- {gs,_,click,quit,_} ->
- true;
- {gs,W,destroy,_,_} ->
- true
- end.
diff --git a/lib/gs/doc/src/examples/ex12.erl b/lib/gs/doc/src/examples/ex12.erl
deleted file mode 100644
index 4af0205061..0000000000
--- a/lib/gs/doc/src/examples/ex12.erl
+++ /dev/null
@@ -1,33 +0,0 @@
--module(ex12).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([start/0,init/0]).
-
-start() -> spawn(ex12, init, []).
-
-init() ->
- R=[{window,[{width,200},{height,200},{title,"grid"},{map, true}],
- {grid, [{x,10},{y,10},{height,180},{width,180},{columnwidths,[80,60]},
- {rows,{1, 20}}],
- [{gridline,[{text,{1,"NAME"}},{text,{2,"PHONE"}},
- {font,{screen,bold,12}},{row,1},{click,false}]},
- {gridline,[{text,{1,"Adam"}},{text,{2,"1234"}},{row,2}]},
- {gridline,[{text,{1,"Beata"}},{text,{2,"4321"}},{row,3}]},
- {gridline,[{text,{1,"Thomas"}},{text,{2,"1432"}},{row,4}]},
- {gridline,[{text,{1,"Bond"}},{text,{2,"007"}},{row,5}]},
- {gridline,[{text,{1,"King"}},{text,{2,"112"}},{row,6}]},
- {gridline,[{text,{1,"Eva"}},{text,{2,"4123"}},{row,7}]}]}}],
- gs:create_tree(gs:start(),R),
- loop().
-
-loop() ->
- receive
- {gs,_Win,destroy,_Data,_Args} -> bye;
- {gs,_Gridline,click,_Data,[Col,Row,Text|_]} ->
- io:format("Click at col:~p row:~p text:~p~n",[Col,Row,Text]),
- loop();
- Msg ->
- io:format("Got ~p~n",[Msg]),
- loop()
- end.
diff --git a/lib/gs/doc/src/examples/ex13.erl b/lib/gs/doc/src/examples/ex13.erl
deleted file mode 100644
index f8af1f34c6..0000000000
--- a/lib/gs/doc/src/examples/ex13.erl
+++ /dev/null
@@ -1,74 +0,0 @@
--module(ex13).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([start/0,init/0]).
-
-start() -> spawn(ex13, init, []).
-
-init() ->
- I=gs:start(),
- Win=gs:window(I, [{width,200},{height,100},
- {title,"menu"},{map, true}]),
- Bar = gs:create(menubar, Win, []),
- Fmb = gs:create(menubutton, Bar,
- [{label,{text,"File"}}]),
- Emb = gs:create(menubutton, Bar,
- [{label,{text,"Edit"}}]),
- Hmb = gs:create(menubutton, Bar,
- [{label,{text,"Help"}},{side,right}]),
- Fmnu = gs:create(menu, Fmb, []),
- Emnu = gs:create(menu, Emb, []),
- Hmnu = gs:create(menu, Hmb, []),
- gs:create(menuitem, load, Fmnu,
- [{label,{text, "Load"}}]),
- gs:create(menuitem, save, Fmnu,
- [{label,{text, "Save"}}]),
- Exit = gs:create(menuitem, Fmnu,
- [{label,{text, "Exit"}}]),
- Color = gs:create(menuitem, Emnu,
- [{label,{text, "Color"}},
- {itemtype, cascade}]),
- Cmnu = gs:create(menu, Color, [{disabledfg,gray}]),
- gs:create(menuitem, Cmnu, [{label, {text,"Red"}},
- {data, {new_color, red}},
- {itemtype,radio},{group,gr1}]),
- gs:create(menuitem, Cmnu, [{label, {text,"Blue"}},
- {data, {new_color, blue}},
- {itemtype,radio},{group,gr1}]),
- gs:create(menuitem,Cmnu, [{label, {text,"Black"}},
- {data, {new_color, black}},
- {itemtype,radio},{group,gr1}]),
- Y = gs:create(menuitem, Hmnu, [{label, {text,"You"}},
- {itemtype, check}]),
- M = gs:create(menuitem, me, Hmnu, [{label, {text, "Me"}},
- {itemtype, check}]),
- gs:create(menuitem, Hmnu, [{itemtype, separator}]),
- gs:create(menuitem, Hmnu, [{label, {text, "Other"}},
- {itemtype, check},
- {enable,false}]),
- gs:create(menuitem, doit, Hmnu, [{label, {text, "Doit!"}},
- {data, {doit, Y, M}}]),
- loop(Exit, Win).
-
-loop(Exit, Win) ->
- receive
- {gs, save, click, _Data, [Txt, Index | Rest]} ->
- io:format("Save~n");
- {gs, load, click, _Data, [Txt, Index | Rest]} ->
- io:format("Load~n");
- {gs, Exit, click, _Data, [Txt, Index | Rest]} ->
- io:format("Exit~n"),
- exit(normal);
- {gs, _MnuItem, click, {new_color, Color}, Args} ->
- io:format("Change color to ~w. Args:~p~n",
- [Color, Args]),
- gs:config(Win, [{bg, Color}]);
- {gs, doit, click, {doit, YouId, MeId}, Args} ->
- HelpMe = gs:read(MeId, select),
- HelpYou = gs:read(YouId, select),
- io:format("Doit. HelpMe:~w, HelpYou:~w, Args:~p~n",
- [HelpMe, HelpYou, Args]);
- Other -> io:format("Other:~p~n",[Other])
- end,
- loop(Exit, Win).
diff --git a/lib/gs/doc/src/examples/ex14.erl b/lib/gs/doc/src/examples/ex14.erl
deleted file mode 100644
index b35de6cb1c..0000000000
--- a/lib/gs/doc/src/examples/ex14.erl
+++ /dev/null
@@ -1,46 +0,0 @@
--module(ex14).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([start/0,init/0]).
-
-start() -> spawn(ex14, init, []).
-
-init() ->
- Y = [{y,0},{height, 30},{width, 90}],
- R=[{window, [{width, 400},{height, 300}, {title,"editor"},{map, true}],
- [{editor,editor,[{x,0},{y, 35},{width,300},{height,250},
- {insert,{'end',"Edit this text!"}},{vscroll,right}]},
- {button, clear, [{label, {text, "Clear"}},{x,0} | Y]},
- {checkbutton,enable,[{label,{text,"Enable"}},{select,false},{x,100}|Y]},
- {button, time, [{label, {text, "Insert Time"}},{x,200} | Y]},
- {button, quit, [{label, {text, "Quit"}},{x,300} | Y]}]}],
- gs:create_tree(gs:start(),R),
- gs:config(editor,{enable,false}),
- loop().
-
-loop() ->
- receive
- {gs, clear, _, _, _} ->
- io:format("clear editor~n"),
- Enable = gs:read(editor, enable),
- gs:config(editor,{enable, true}),
- gs:config(editor,clear),
- gs:config(editor,{enable, Enable});
- {gs, enable, _, _, [_Txt, _Grp, Enable|_]} ->
- io:format("Enable: ~w~n", [Enable]),
- gs:config(editor,{enable, Enable});
- {gs, time, _, _, _} ->
- TimeStr = io_lib:format("Hr:Min:Sec is now ~w:~w:~w~n",
- tuple_to_list(time())),
- io:format("Insert Time: ~s~n", [TimeStr]),
- Enable = gs:read(editor, enable),
- gs:config(editor,{enable, true}),
- gs:config(editor,{insert, {insert, TimeStr}}),
- gs:config(editor,{enable, Enable});
- {gs, quit, _, _, _} ->
- exit(normal);
- Other ->
- io:format("Other:~w~n",[Other])
- end,
- loop().
diff --git a/lib/gs/doc/src/examples/ex15.erl b/lib/gs/doc/src/examples/ex15.erl
deleted file mode 100644
index 864bdd93b2..0000000000
--- a/lib/gs/doc/src/examples/ex15.erl
+++ /dev/null
@@ -1,30 +0,0 @@
--module(ex15).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/3 $ ').
-
--export([start/0,init/0]).
-
-start() -> spawn(ex15, init, []).
-
-init() ->
- I=gs:start(),
- Win=gs:create(window, I,
- [{width, 400},{height, 250},
- {title,"Font Demo"},{map, true}]),
- E = gs:create(canvas, can1,Win,
- [{x,0},{y, 0},{width,400},{height,250}]),
- Fonts = [{times,19},{screen,16},{helvetica,bold,21},
- {symbol,12},{times,[bold,italic],33},{courier,6}],
- show_fonts_in_boxes(Fonts,0),
- receive
- {gs,_Id,destroy,_Data,_Arg} -> bye
- end.
-
-show_fonts_in_boxes([],_) -> done;
-show_fonts_in_boxes([Font|Fonts],Y) ->
- Txt = io_lib:format("Hi! ~p",[Font]),
- {Width,Height} = gs:read(can1,{font_wh,{Font,Txt}}),
- Y2=Y+Height+2,
- gs:create(rectangle,can1,[{coords,[{0,Y},{Width,Y2}]}]),
- gs:create(text,can1,[{font,Font},{text,Txt},{coords,[{0,Y+1}]}]),
- show_fonts_in_boxes(Fonts,Y2+1).
diff --git a/lib/gs/doc/src/examples/ex16.erl b/lib/gs/doc/src/examples/ex16.erl
deleted file mode 100644
index 9c995d16bf..0000000000
--- a/lib/gs/doc/src/examples/ex16.erl
+++ /dev/null
@@ -1,40 +0,0 @@
--module(ex16).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/3 $ ').
-
--export([start/0,init/0]).
-
-start() -> spawn(ex16, init, []).
-
-init() ->
- I=gs:start(),
- Win=gs:create(window, I,
- [{width, 200},{height, 200},
- {title,"Default Demo"},{map, true}]),
- gs:create(canvas, can1,Win,
- [{x,0},{y, 0},{width,200},{height,200},
- {default,text,{font,{courier,bold,19}}},
- {default,text,{fg,blue}},
- {default,rectangle,{fill,red}},{default,text,{text,"Pow!"}},
- {default,oval,{fill,green}}]),
- {A,B,C} = erlang:now(),
- random:seed(A,B,C),
- loop().
-
-loop() ->
- receive
- {gs,_Id,destroy,_Data,_Arg} -> bye
- after 500 ->
- XY = {random:uniform(200),random:uniform(200)},
- draw(random:uniform(3),XY),
- loop()
- end.
-
-draw(1,XY) ->
- gs:create(text,can1,[{coords,[XY]}]);
-draw(2,XY) ->
- XY2 = {random:uniform(200),random:uniform(200)},
- gs:create(rectangle,can1,[{coords,[XY,XY2]}]);
-draw(3,XY) ->
- XY2 = {random:uniform(200),random:uniform(200)},
- gs:create(oval,can1,[{coords,[XY,XY2]}]).
diff --git a/lib/gs/doc/src/examples/ex17.erl b/lib/gs/doc/src/examples/ex17.erl
deleted file mode 100644
index f659b42ae3..0000000000
--- a/lib/gs/doc/src/examples/ex17.erl
+++ /dev/null
@@ -1,32 +0,0 @@
--module(ex17).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/1 $ ').
-
--export([start/0,init/0]).
-
-start() -> spawn(ex17, init, []).
-
-init() ->
- WH = [{width,200},{height,300}],
- Win = gs:window(gs:start(),[{map,true},{configure,true},
- {title,"Packer Demo"}|WH]),
- gs:frame(packer,Win,[{packer_x,[{stretch,1,50},{stretch,2,50},
- {stretch,1,50}]},
- {packer_y,[{fixed,30},{stretch,1}]}]),
- gs:button(packer,[{label,{text,"left"}},{pack_xy,{1,1}}]),
- gs:button(packer,[{label,{text,"middle"}},{pack_xy,{2,1}}]),
- gs:button(packer,[{label,{text,"right"}},{pack_xy,{3,1}}]),
- gs:editor(packer,[{pack_xy,{{1,3},2}},{vscroll,true},{hscroll,true}]),
- gs:config(packer,WH), % refresh to initial size
- loop().
-
-loop() ->
- receive
- {gs,_Id,destroy,_Data,_Arg} -> bye;
- {gs,_Id,configure,_Data,[W,H|_]} ->
- gs:config(packer,[{width,W},{height,H}]), % repack
- loop();
- Other ->
- io:format("loop got: ~p~n",[Other]),
- loop()
- end.
diff --git a/lib/gs/doc/src/examples/ex2.erl b/lib/gs/doc/src/examples/ex2.erl
deleted file mode 100644
index 833d189602..0000000000
--- a/lib/gs/doc/src/examples/ex2.erl
+++ /dev/null
@@ -1,19 +0,0 @@
--module(ex2).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([init/0]).
-
-init() ->
- S = gs:start(),
- gs:create(window,win1,S,[{width,200},{height,100}]),
- gs:create(button,b1,win1,[{label, {text,"Press Me"}}]),
- gs:config(win1, {map,true}),
- loop().
-
-loop() ->
- receive
- {gs, b1, click, Data, Args} ->
- io:format("Hello World!~n",[]),
- loop()
- end.
diff --git a/lib/gs/doc/src/examples/ex3.erl b/lib/gs/doc/src/examples/ex3.erl
deleted file mode 100644
index 486cec0e4e..0000000000
--- a/lib/gs/doc/src/examples/ex3.erl
+++ /dev/null
@@ -1,23 +0,0 @@
--module(ex3).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([init/0]).
-
-init() ->
- S = gs:start(),
- W = gs:create(window,S,[{width,300},{height,200}]),
- B1 = gs:create(button,W,[{label, {text,"Button1"}},{y,0}]),
- B2 = gs:create(button,W,[{label, {text,"Button2"}},{y,40}]),
- gs:config(W, {map,true}),
- loop(B1,B2).
-
-loop(B1,B2) ->
- receive
- {gs,B1,click,_Data,_Arg} -> % button 1 pressed
- io:format("Button 1 pressed!~n",[]),
- loop(B1,B2);
- {gs,B2,click,_Data,_Arg} -> % button 2 pressed
- io:format("Button 2 pressed!~n",[]),
- loop(B1,B2)
- end.
diff --git a/lib/gs/doc/src/examples/ex4.erl b/lib/gs/doc/src/examples/ex4.erl
deleted file mode 100644
index 21a0fe3e96..0000000000
--- a/lib/gs/doc/src/examples/ex4.erl
+++ /dev/null
@@ -1,23 +0,0 @@
--module(ex4).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([init/0]).
-
-init() ->
- S = gs:start(),
- gs:create(window,win1,S,[{width,300},{height,200}]),
- gs:create(button,b1,win1,[{label, {text,"Button1"}},{y,0}]),
- gs:create(button,b2,win1,[{label, {text,"Button2"}},{y,40}]),
- gs:config(win1, {map,true}),
- loop(). %% look, no args!
-
-loop() ->
- receive
- {gs,b1,click,_,_} -> % button 1 pressed
- io:format("Button 1 pressed!~n",[]),
- loop();
- {gs,b2,click,_,_} -> % button 2 pressed
- io:format("Button 2 pressed!~n",[]),
- loop()
- end.
diff --git a/lib/gs/doc/src/examples/ex5.erl b/lib/gs/doc/src/examples/ex5.erl
deleted file mode 100644
index e608709991..0000000000
--- a/lib/gs/doc/src/examples/ex5.erl
+++ /dev/null
@@ -1,27 +0,0 @@
--module(ex5).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([start/0, init/0, b1/0, b2/0]).
-
-start() ->
- spawn(ex5, init, []).
-
-init() ->
- S = gs:start(),
- W = gs:create(window,S,[{map,true}]),
- gs:create(button,W,[{label,{text,"Button1"}},{data,{ex5,b1,[]}},{y,0}]),
- gs:create(button,W,[{label,{text,"Button2"}},{data,{ex5,b2,[]}},{y,40}]),
- loop().
-
-loop()->
- receive
- {gs,_,click,{M,F,A},_} -> % any button pressed
- apply(M,F,A),
- loop()
- end.
-
-b1() ->
- io:format("Button 1 pressed!~n",[]).
-b2() ->
- io:format("Button 2 pressed!~n",[]).
diff --git a/lib/gs/doc/src/examples/ex6.erl b/lib/gs/doc/src/examples/ex6.erl
deleted file mode 100644
index ca73deb78e..0000000000
--- a/lib/gs/doc/src/examples/ex6.erl
+++ /dev/null
@@ -1,23 +0,0 @@
--module(ex6).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([start/0,init/0]).
-
-start() ->
- spawn(ex6,init,[]).
-
-init() ->
- S = gs:start(),
- W = gs:create(window,S,[{map,true},{keypress,true},
- {buttonpress,true},{motion,true}]),
- gs:create(button,W,[{label,{text,"PressMe"}},{enter,true},
- {leave,true}]),
- event_loop().
-
-event_loop() ->
- receive
- X ->
- io:format("Got event: ~w~n",[X]),
- event_loop()
- end.
diff --git a/lib/gs/doc/src/examples/ex7.erl b/lib/gs/doc/src/examples/ex7.erl
deleted file mode 100644
index a80c36fdcb..0000000000
--- a/lib/gs/doc/src/examples/ex7.erl
+++ /dev/null
@@ -1,42 +0,0 @@
--module(ex7).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([mk_window/0]).
-
-mk_window() ->
- S= gs:start(),
- Win= gs:create(window,S,[{motion,true},{map,true}]),
- gs:config(Win,[{configure,true},{keypress,true}]),
- gs:config(Win,[{buttonpress,true}]),
- gs:config(Win,[{buttonrelease,true}]),
- event_loop(Win).
-
-event_loop(Win) ->
- receive
- {gs,Win,motion,Data,[X,Y | Rest]} ->
- %% mouse moved to position X Y
- io:format("mouse moved to X:~w Y:~w~n",[X,Y]);
- {gs,Win,configure,Data,[W,H | Rest]} ->
- %% window was resized by user
- io:format("window resized W:~w H:~w~n",[W,H]);
- {gs,Win,buttonpress,Data,[1,X,Y | Rest]} ->
- %% button 1 was pressed at location X Y
- io:format("button 1 pressed X:~w Y:~w~n",[X,Y]);
- {gs,Win,buttonrelease,Data,[_,X,Y | Rest]} ->
- %% Any button (1-3) was released over X Y
- io:format("Any button released X:~w Y:~w~n",[X,Y]);
- {gs,Win,keypress,Data,[a | Rest]} ->
- %% key `a' was pressed in window
- io:format("key a was pressed in window~n");
- {gs,Win,keypress,Data,[_,65,1 | Rest]} ->
- %% Key shift-a
- io:format("shift-a was pressed in window~n");
- {gs,Win,keypress,Data,[c,_,_,1 | Rest]} ->
- %% CTRL_C pressed
- io:format("CTRL_C was pressed in window~n");
- {gs,Win,keypress,Data, ['Return' | Rest]} ->
- %% Return key pressed
- io:format("Return key was pressed in window~n")
- end,
- event_loop(Win).
diff --git a/lib/gs/doc/src/examples/ex8.erl b/lib/gs/doc/src/examples/ex8.erl
deleted file mode 100644
index 3081cb6114..0000000000
--- a/lib/gs/doc/src/examples/ex8.erl
+++ /dev/null
@@ -1,22 +0,0 @@
--module(ex8).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([start/0]).
-
-start() ->
- gs:window(win,gs:start(),{map,true}),
- gs:radiobutton(rb1,win,[{label,{text,"rb1"}},{value,a},{y,0}]),
- gs:radiobutton(rb2,win,[{label,{text,"rb2"}},{value,a},{y,30}]),
- gs:radiobutton(rb3,win,[{label,{text,"rb3"}},{value,b},{y,60}]),
- rb_loop().
-
-rb_loop() ->
- receive
- {gs,Any_Rb,click,Data,[Text, Grp, a | Rest]} ->
- io:format("either rb1 or rb2 is on.~n",[]),
- rb_loop();
- {gs,rb3,click,Data,[Text, Grp, b | Rest]} ->
- io:format("rb3 is selected.~n",[]),
- rb_loop()
- end.
diff --git a/lib/gs/doc/src/examples/ex9.erl b/lib/gs/doc/src/examples/ex9.erl
deleted file mode 100644
index 2034520c6c..0000000000
--- a/lib/gs/doc/src/examples/ex9.erl
+++ /dev/null
@@ -1,43 +0,0 @@
--module(ex9).
--copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
--vsn('$Revision: /main/release/2 $ ').
-
--export([start/0,init/1]).
-
-start() ->
- spawn(ex9, init, [self()]),
- receive
- {entry_reply, Reply} -> Reply
- end.
-
-init(Pid) ->
- S = gs:start(),
- Win = gs:create(window,S,[{title,"Entry Demo"},
- {width,150},{height,100}]),
- gs:create(label,Win,[{label,{text,"What's your name?"}},
- {width,150}]),
- gs:create(entry,entry,Win,[{x,10},{y,30},{width,130},
- {keypress,true}]),
- gs:create(button,ok,Win,[{width,45},{y,60},{x,10},
- {label,{text,"Ok"}}]),
- gs:create(button,cancel,Win,[{width,60},{y,60},{x,80},
- {label,{text,"Cancel"}}]),
- gs:config(Win,{map,true}),
- loop(Pid).
-
-loop(Pid) ->
- receive
- {gs,entry,keypress,_,['Return'|_]} ->
- Text=gs:read(entry,text),
- Pid ! {entry_reply,{name,Text}};
- {gs,entry,keypress,_,_} -> % all other keypresses
- loop(Pid);
- {gs,ok,click,_,_} ->
- Text=gs:read(entry,text),
- Pid ! {entry_reply,{name,Text}};
- {gs,cancel,click,_,_} ->
- Pid ! {entry_reply,cancel};
- X ->
- io:format("Got X=~w~n",[X]),
- loop(Pid)
- end.
diff --git a/lib/gs/doc/src/fascicules.xml b/lib/gs/doc/src/fascicules.xml
deleted file mode 100644
index 37feca543f..0000000000
--- a/lib/gs/doc/src/fascicules.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
-
-<fascicules>
- <fascicule file="part" href="part_frame.html" entry="no">
- User's Guide
- </fascicule>
- <fascicule file="ref_man" href="ref_man_frame.html" entry="yes">
- Reference Manual
- </fascicule>
- <fascicule file="part_notes" href="part_notes_frame.html" entry="no">
- Release Notes
- </fascicule>
- <fascicule file="" href="../../../../doc/print.html" entry="no">
- Off-Print
- </fascicule>
-</fascicules>
-
diff --git a/lib/gs/doc/src/gs.xml b/lib/gs/doc/src/gs.xml
deleted file mode 100644
index 3cbb6dca62..0000000000
--- a/lib/gs/doc/src/gs.xml
+++ /dev/null
@@ -1,158 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE erlref SYSTEM "erlref.dtd">
-
-<erlref>
- <header>
- <copyright>
- <year>2000</year>
- <year>2016</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>gs</title>
- <prepared>Gunilla Hugosson</prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- </header>
- <module>gs</module>
- <modulesummary>The Graphics System for Erlang.</modulesummary>
- <description>
- <warning>
- <p>
- GS is not recommended for use in new applications.
- Instead we recommend WX for applications that need a
- graphical user interface.
- </p>
- <p>
- GS is deprecated and will be removed in the 18.0 release.
- </p>
- </warning>
- <p>The Graphics System, GS, is easy to learn and
- designed to be portable to many different platforms.</p>
- <p>In the description below, the type <c><![CDATA[gsobj()]]></c> denotes a
- reference to a graphical object created with GS. Such a reference
- is either a GS object identifier or the name of the object (an atom),
- if such a name exists.
- The functions all return the specified values or <c><![CDATA[{error,Reason}]]></c>
- if an error occurs.</p>
- <p>Please refer to the GS User's Guide for a description of
- the different object types and possible options.</p>
- </description>
- <funcs>
- <func>
- <name>config(GSObj, Options) -> ok</name>
- <fsummary>Configure a graphical object.</fsummary>
- <type>
- <v>GSOBj = gsobj()</v>
- <v>Options = [Option] | Option</v>
- <v>&nbsp;Option = {Key,Value}</v>
- </type>
- <desc>
- <p>Configures a graphical object according to the specified
- options.</p>
- </desc>
- </func>
- <func>
- <name>create(ObjType, Parent) -> ObjId</name>
- <name>create(ObjType, Parent, Options) -> ObjId</name>
- <name>create(ObjType, Name, Parent, Options) -> ObjId</name>
- <fsummary>Create a new graphical object.</fsummary>
- <type>
- <v>ObjType = atom()</v>
- <v>Parent = gsobj()</v>
- <v>Name = atom()</v>
- <v>Options = [Option] | Option</v>
- <v>&nbsp;Option = {Key,Value}</v>
- </type>
- <desc>
- <p>Creates a new graphical object of the specified type as a child
- to the specified parent object. The object is configured according
- to the options and its identifier is returned. If no options
- are provided, default option values are used.</p>
- <p>If a name is provided, this name can be used to reference
- the object instead of the object identifier. The name is local
- to the process which creates the object.</p>
- <p>The following object types exist: <c><![CDATA[window | button | radiobutton | checkbutton | label | frame | entry | listbox | canvas | arc | image | line | oval | polygon | rectangle | text | menubar | menubutton | menu | menuitem | grid | gridline | editor | scale]]></c></p>
- </desc>
- </func>
- <func>
- <name>create_tree(Parent, Tree) -> ok</name>
- <fsummary>Create a hierarchy of graphical objects.</fsummary>
- <type>
- <v>Parent = gsobj()</v>
- <v>Tree = [Object]</v>
- <v>&nbsp;Object = {ObjType,Options} | {ObjType,Options,Tree} | {ObjType,Name,Options,Tree}</v>
- </type>
- <desc>
- <p>Creates a hierarchy of graphical objects.</p>
- </desc>
- </func>
- <func>
- <name>destroy(GSObj) -> void()</name>
- <fsummary>Destroy a graphical object.</fsummary>
- <type>
- <v>GSObj = gsobj()</v>
- </type>
- <desc>
- <p>Destroys a graphical object and all its children.</p>
- </desc>
- </func>
- <func>
- <name>ObjType(Parent)</name>
- <name>ObjType(Parent, Options)</name>
- <name>ObjType(Name, Parent, Options)</name>
- <fsummary>Shorthand equivalents of <c><![CDATA[create]]></c>.</fsummary>
- <desc>
- <p>These functions are shorthand equivalents of <c><![CDATA[create/2]]></c>,
- <c><![CDATA[create/3]]></c>, and <c><![CDATA[create/4]]></c>, respectively.</p>
- </desc>
- </func>
- <func>
- <name>read(GSObj, Key) -> Value</name>
- <fsummary>Return the value of an object option.</fsummary>
- <type>
- <v>GSObj = gsobj()</v>
- <v>Key = atom()</v>
- <v>Value = term()</v>
- </type>
- <desc>
- <p>Returns the value of an option key for the specified graphical
- object.</p>
- </desc>
- </func>
- <func>
- <name>start() -> ObjId</name>
- <fsummary>Start GS.</fsummary>
- <desc>
- <p>Starts GS, unless it is already started, and returns its object
- identifier.</p>
- </desc>
- </func>
- <func>
- <name>stop() -> void()</name>
- <fsummary>Stop GS.</fsummary>
- <desc>
- <p>Stops GS and closes all windows. This function is not the opposite
- of <c><![CDATA[start/0]]></c> as it will cause <em>all</em> applications
- to lose their GS objects.</p>
- </desc>
- </func>
- </funcs>
-</erlref>
-
diff --git a/lib/gs/doc/src/gs_chapter1.xml b/lib/gs/doc/src/gs_chapter1.xml
deleted file mode 100644
index 65e0ee208a..0000000000
--- a/lib/gs/doc/src/gs_chapter1.xml
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2000</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>GS - The Graphics System</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- <file>gs_chapter1.xml</file>
- </header>
-
- <section>
- <title>Introduction</title>
- <warning>
- <p>
- GS is not recommended for use in new applications.
- Instead we recommend WX for applications that need a
- graphical user interface.
- </p>
- <p>
- GS is not maintained and we plan to deprecate and remove it from
- the distribution as soon as possible, maybe already in the next
- major release (R15).
- </p>
- </warning>
- <p>This section describes the general graphics interface to Erlang. This system was designed with the following requirements in mind:</p>
- <list type="bulleted">
- <item>a graphics system which is easy to learn</item>
- <item>a graphics system which is portable to many different platforms.</item>
- </list>
- <p>Erlang has been implemented on a wide range of platforms and the graphics system works on all these platforms. Erlang applications can be written towards the same graphics API and the application can run on all supported platforms without modification.</p>
- <marker id="gs_fig1"/>
- <image file="images/gs1-1-image-1.gif">
- <icaption>Graphics Interface for Erlang</icaption>
- </image>
- </section>
-
- <section>
- <title>Basic Architecture of GS</title>
- <p>The basic building block in the graphics system is the graphical object. Objects are created in a hierarchical fashion where each object has a parent. The most common object types are:</p>
- <list type="bulleted">
- <item>window</item>
- <item>button</item>
- <item>label</item>
- <item>list box</item>
- <item>frame.</item>
- </list>
- <p>Whenever a new object is created, a unique object identifier is returned. This object identifier makes it possible to configure the object by changing its appearance and behaviour. This configuration of the object is controlled by the <em>Options</em>, also known as attributes or properties. These include width and height. Most options have a value of a specified type, but not all.</p>
- <p>Whenever an Erlang process creates a graphical object, it is said
- to own the object. The graphics system must keep track of the owner
- of every graphical object in order to forward incoming events to
- the owner-process and kill the appropriate graphics window if the owner
- process suddenly dies.</p>
- <marker id="gs_fig2"/>
- <image file="images/gs1-1-image-2.gif">
- <icaption>Owner Process</icaption>
- </image>
- <p>Events are messages which are sent from the graphical object to the owner-process. The events the owner-process is informed about may include:</p>
- <list type="bulleted">
- <item>the user has clicked on a button</item>
- <item>the user has entered text into an entry field</item>
- <item>the user has taken some action on the object, like moving the window.</item>
- </list>
- <marker id="gs_fig3"/>
- <image file="images/gs1-1-image-3.gif">
- <icaption>Events Delivered to Owner Process</icaption>
- </image>
- </section>
-</chapter>
-
diff --git a/lib/gs/doc/src/gs_chapter2.xmlsrc b/lib/gs/doc/src/gs_chapter2.xmlsrc
deleted file mode 100644
index f3ec878bc6..0000000000
--- a/lib/gs/doc/src/gs_chapter2.xmlsrc
+++ /dev/null
@@ -1,165 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2000</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>Interface Functions</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- <file>gs_chapter2.xml</file>
- </header>
-
- <section>
- <title>Overview</title>
- <p>The following interface functions are included with the graphics system:</p>
- <list type="bulleted">
- <item><c><![CDATA[gs:start().]]></c> This function starts the graphics server and returns its object identifier. If the graphics server has already been started, it returns its original identifier.</item>
- <item><c><![CDATA[gs:stop().]]></c> This function stops the graphics server and closes all windows which <c><![CDATA[gs]]></c> has launched. This function is not the opposite of <c><![CDATA[gs:start/0]]></c> because <c><![CDATA[gs:stop/1]]></c> causes all applications to lose the graphics server and the objects created with the <c><![CDATA[gs]]></c> system.</item>
- <item><c><![CDATA[gs:create(Objtype, Parent, Options).]]></c> This function creates a new object of specified <c><![CDATA[Objtype]]></c> as a child to the specified <c><![CDATA[Parent]]></c>. It configures the object with <c><![CDATA[Options]]></c> and returns the identifier for the object, or <c><![CDATA[{error,Reason}]]></c>.</item>
- <item><c><![CDATA[gs:create(Objtype, Name, Parent, Options).]]></c> This function is identical to the previously listed function, except that a <c><![CDATA[Name]]></c> is specified to reference the object. <c><![CDATA[Name]]></c> is an atom.</item>
- <item><c><![CDATA[gs:destroy(IdOrName).]]></c> This function destroys an object and all its children.</item>
- <item><c><![CDATA[gs:config(IdOrNeme, Options).]]></c> This function configures an object with <c><![CDATA[Options]]></c>. It returns <c><![CDATA[ok]]></c>, or <c><![CDATA[{error,Reason}]]></c>.</item>
- <item><c><![CDATA[gs:read(Id_or_Name, OptionKey).]]></c> This function reads the value of an object option. It returns the value, or <c><![CDATA[{error,Reason}]]></c>.</item>
- </list>
- <p>The above list contains all the function which are <em>needed</em> with the graphics system. For convenience, the following aliases also exist:</p>
- <list type="bulleted">
- <item><c><![CDATA[gs:create(Obttype, Parent).]]></c></item>
- <item><c><![CDATA[gs:create(Objtype, Parent, Options).]]></c></item>
- <item><c><![CDATA[gs:create(Objtype, Parent, Option).]]></c></item>
- <item><c><![CDATA[gs:create(Objtype, Name, Parent, Options).]]></c></item>
- <item><c><![CDATA[gs:create(Objtype, Name, Parent, Option).]]></c></item>
- <item><c><![CDATA[gs:Objecttype(Parent).]]></c></item>
- <item><c><![CDATA[gs:Objecttype(Parent,Options).]]></c></item>
- <item><c><![CDATA[gs:Objecttype(Parent, Option).]]></c></item>
- <item><c><![CDATA[gs:Objecttype(Name, Parent, Options).]]></c></item>
- <item><c><![CDATA[gs:Objecttype(Name, Parent, Option).]]></c></item>
- <item><c><![CDATA[gs:config(IdOrName, Option).]]></c></item>
- </list>
- <p>These shorthands can be used as follows:</p>
- <list type="bulleted">
- <item><c><![CDATA[gs:window(gs:start(), {map,true}).]]></c></item>
- <item><c><![CDATA[gs:button(W).]]></c></item>
- <item><c><![CDATA[gs:config(B,{label,{text,"Hi!"}}).]]></c></item>
- </list>
- <p>The <c><![CDATA[create_tree/2]]></c> function is useful for creating a large hierarchy of objects. It has the following syntax: </p>
- <code type="none"><![CDATA[
-create_tree(ParentId,Tree) -> | {error,Reason}
- ]]></code>
- <p><c><![CDATA[Tree]]></c> is a list of <c><![CDATA[Object]]></c>, and <c><![CDATA[Object]]></c> is any of the following:</p>
- <list type="bulleted">
- <item><c><![CDATA[{ObjectType,Name,Options,Tree}]]></c></item>
- <item><c><![CDATA[{ObjectType,Options,Tree}]]></c></item>
- <item><c><![CDATA[{ObjectType,Options}]]></c></item>
- </list>
- <p>The following example constructs a window which contains two objects, a button and a frame with a label:</p>
- <code type="none"><![CDATA[
-R = [{window,[{map,true}],
- [{button,[{label,{text,"Butt1"}}]},
- {frame,[{y,40}],[{label,[{label,{text,"Lbl1"}}]}]}]}],
-gs:create_tree(gs:start(),R).
- ]]></code>
- </section>
-
- <section>
- <title>A First Example</title>
- <p>The first action required is to start up the graphics server. This operation returns an identifier for the server process, which registers itself under the name <c><![CDATA[gs]]></c>. If a graphics server was already started, its identifier is returned. We can now create objects and configure the behavior and appearance of these objects. When all objects are created and configured in a top level window, we map it on the screen to make it visible. The example below shows how to create a window with a button that says "Press Me".</p>
- <codeinclude file="examples/ex1.erl" tag="" type="erl"></codeinclude>
- <p>The following steps were completed in this code:</p>
- <list type="bulleted">
- <item>start a graphics server</item>
- <item>create a window of specified width and height</item>
- <item>create a button with the text "Press Me"</item>
- <item>map the window on the screen</item>
- <item>enter the event loop.</item>
- </list>
- <p>The event loop is where we receive events from <c><![CDATA[gs]]></c>. In this case, we want to receive a click event from the button. This event is delivered when the user presses the button.</p>
- <marker id="gs_fig4"></marker>
- <image file="images/ex1.gif">
- <icaption>
-"Press Me" Button Example</icaption>
- </image>
- <p>The Erlang <c><![CDATA[gs]]></c> system includes many examples. All examples in this document can be found in the <c><![CDATA[doc/users_guide/examples/]]></c> directory. In addition, there is an example directory which contains examples of fractal trees, bouncing balls, a color editor, and a couple of other <c><![CDATA[gs]]></c> applications.</p>
- </section>
-
- <section>
- <title>Creating Objects</title>
- <p>You create an object of a specified type with the <c><![CDATA[create/3]]></c> or the <c><![CDATA[create/4]]></c> function. The difference is that the <c><![CDATA[create/4]]></c> function allows you to assign names to the objects. You can then refer to the object instead of using the object identifier. The two forms of the <c><![CDATA[create]]></c> function look as follows:</p>
- <code type="none"><![CDATA[
-ObjId = gs:create(Objtype, Parent, Options)
-ObjId = gs:create(Objtype, Name, Parent, Options)
- ]]></code>
- <p>Examples of built-in object types are:</p>
- <list type="bulleted">
- <item>window</item>
- <item>frame</item>
- <item>menu</item>
- <item>button</item>
- <item>radio button</item>
- <item>list box.</item>
- </list>
- <p>Objects are created in a hierarchical order. The top level object is the window object which is a container object for most other object types.</p>
- <marker id="gs_fig5"></marker>
- <image file="images/gs1-1-image-4.gif">
- <icaption>Hierarchy of Objects</icaption>
- </image>
- <p>A frame object is like a sub-window but also a container object which can have children objects.</p>
- <p>The <c><![CDATA[create/3]]></c> or <c><![CDATA[create/4]]></c> functions return an object identifier, or the tuple <c><![CDATA[{error, Reason}]]></c>. The object identifier uniquely identifies the object within the system. The object identifier is used to:</p>
- <list type="bulleted">
- <item>reconfigure an object</item>
- <item>identify events from a particular object.</item>
- </list>
- </section>
-
- <section>
- <title>Ownership</title>
- <p>The process which creates an object is said to own the object. When a process dies, all objects owned by the process are destroyed. The ownership also means that all events generated by a specific object are delivered to the owner process. The graphics server keeps track of all Erlang processes that create objects. It is therefore able to take appropriate actions if a process should die.</p>
- </section>
-
- <section>
- <title>Naming Objects</title>
- <p>As shown previously, the <c><![CDATA[create/4]]></c> function can be used to name objects. The name should be a unique atom which is used to reference the object. The advantage of naming objects is that we do not have to pass object identifiers as arguments to the event loop. Instead, we can use the object name in our code. To name objects in the following example, the code gives the name <c><![CDATA[win1]]></c> to the window, and <c><![CDATA[b1]]></c> to the button.</p>
- <codeinclude file="examples/ex2.erl" tag="" type="erl"></codeinclude>
- <p>The name is <em>local</em> for the process which creates the object. This means that the name have a meaning only for one process. Different processes can give different objects the same name. When passing references to objects between processes, the object identifier has to be used because names only has a meaning in a process context. If necessary, the object identifier can be retrieved by reading the <c><![CDATA[id]]></c> option.</p>
- <p>When using distributed Erlang, objects should be named carefully. A named object always refers to an object in the graphics system on the node where it was created. The syntax <c><![CDATA[{Name,Node}]]></c> should be used when referring to a named object on another node.</p>
- <p>The following example receives a canvas object from another node and creates a line named <c><![CDATA[myline1]]></c> that will appear in the canvas. Also, this example demonstrates how to configure the line using the special syntax.</p>
- <code type="none"><![CDATA[
-foo() ->
- receive
- {gs_obj,Canvas,FromNode} -> ok
- end,
- gs:create(line,myline1,Canvas,[{coords,[{10,10},{20,20}]}]),
- gs:config({myline1,FromNode},[{buttonpress,true}]).
- ]]></code>
- <p>Unnamed objects are transparent. For example, a line object can be created from a canvas on another node and then configured as any other object.</p>
- <code type="none"><![CDATA[
-bar() ->
- receive
- {gs_obj,Canvas,_FromNode} -> ok
- end,
- L = gs:create(line,Canvas,[{coords,[{10,10},{20,20}]}]),
- gs:config(L,[{buttonpress,true}]).
- ]]></code>
- </section>
-</chapter>
-
diff --git a/lib/gs/doc/src/gs_chapter3.xml b/lib/gs/doc/src/gs_chapter3.xml
deleted file mode 100644
index f21e75d970..0000000000
--- a/lib/gs/doc/src/gs_chapter3.xml
+++ /dev/null
@@ -1,177 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2000</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>Options</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- <file>gs_chapter3.xml</file>
- </header>
-
- <section>
- <title>The Option Concept</title>
- <p>Each object has a set of options. The options are key-value tuples and the key is an atom. Depending on the option, the value can be any Erlang term. Typical options are: x, y, width, height, text, and color. A list of options should be supplied when an object is created . It is also possible to reconfigure an object with the function <c><![CDATA[gs:config/2]]></c>. The following example shows one way to create a red button with the text "Press Me" on it:</p>
- <code type="none"><![CDATA[
-Butt = gs:create(button,Win, [{x,10},{y,10}]),
-gs:config(Butt, [{width,50},{height,50},{bg,red}]),
-gs:config(Butt, [{label, {text,"Press Me"}},{y,20}]),
- ]]></code>
- <p>The evaluation order of options is not defined. This implies that the grouping of options shown in the following example is not recommended:</p>
- <code type="none"><![CDATA[
-Rect = gs:create(rectangle,Can, [{coords,[{10,10},{20,20}]},
- {move,{5,5}}]),
- ]]></code>
- <p>After the operation, the rectangle can be at position <c><![CDATA[[{10,10},{20,20}]]]></c> or <c><![CDATA[[{15,15},{25,25}]]]></c>. The following example produces a deterministic behaviour:</p>
- <code type="none"><![CDATA[
-Rect = gs:create(rectangle,Can,[{coords,[{10,10},{20,20}]},
-gs:config(Rect,[{move,{5,5}}]),
- ]]></code>
- <p>The value of each option can be read individually with the <c><![CDATA[read/2]]></c> function as shown in the following example:</p>
- <code type="none"><![CDATA[
-Value = gs:read(ObjectId,Option)
- ]]></code>
- <p>The next example shows how to read the text and the width options from a button:</p>
- <code type="none"><![CDATA[
-Text = gs:read(Butt, text),
-Width = gs:read(Butt, width),
- ]]></code>
- </section>
-
- <section>
- <title>The Option Tables</title>
- <p>Each object is described in terms of its options. The options are listed in a table as is shown in the following example:</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Foreground color of the object</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{map, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">Visibility on the screen</cell>
- </row>
- <row>
- <cell align="left" valign="middle">...</cell>
- <cell align="left" valign="middle">...</cell>
- <cell align="left" valign="middle">...</cell>
- </row>
- <tcaption>Options</tcaption>
- </table>
- <p>The &lt;unspec&gt; default value means that either <c><![CDATA[gs]]></c> or the back-end provides the default value. For example, the <c><![CDATA[fg]]></c> option can be used as follows:</p>
- <code type="none"><![CDATA[
-Rect = gs:create(rectangle, Window, [{fg, red}]),
-Color = gs:read(Rect, fg),
- ]]></code>
- </section>
-
- <section>
- <title>Config-Only Options</title>
- <p>Most options are read/write key-value tuples such as <c><![CDATA[{select,true|false}]]></c> and <c><![CDATA[{map,true|false]]></c>, but some options are by nature write-only, or read-only. For example, buttons can flash for a short time and canvas objects can be moved dx, dy. The following table exemplifies some config-only options:</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Config-Only</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">flash</cell>
- <cell align="left" valign="middle">Causes the object to flash for 2 seconds.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">raise</cell>
- <cell align="left" valign="middle">Raises the object on top of other overlapping objects.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{move, {Dx, Dy}}</cell>
- <cell align="left" valign="middle">Moves the object relative to its current position.</cell>
- </row>
- <tcaption>Config-Only Options</tcaption>
- </table>
- <p><c><![CDATA[gs:config(Button,[flash]),]]></c> causes the button to flash.</p>
- </section>
-
- <section>
- <title>Read-Only Options</title>
- <p>The opposite of config-only options are read-only options. The following table exemplifies some read-only options:</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Read-Only</em></cell>
- <cell align="left" valign="middle"><em>Return</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">size</cell>
- <cell align="left" valign="middle">Int</cell>
- <cell align="left" valign="middle">The number of items (entries).</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{get, Index}</cell>
- <cell align="left" valign="middle">String</cell>
- <cell align="left" valign="middle">The entry at index <c><![CDATA[Index]]></c>.</cell>
- </row>
- <tcaption>Read-Only Options</tcaption>
- </table>
- <p><c><![CDATA[EntryString = gs:read(Listbox,{get, Index}),]]></c> is an example.</p>
- </section>
-
- <section>
- <title>Data Types</title>
- <p>As previously stated, each object is described in terms of its options. This section defines the data types for options.</p>
- <taglist>
- <tag><em>Anchor|Align.</em></tag>
- <item><c><![CDATA[n|w|s|e|nw|se|ne|sw|center]]></c></item>
- <tag><em>Atom.</em></tag>
- <item>An Erlang atom such as <c><![CDATA[myWay]]></c>.</item>
- <tag><em>Bool.</em></tag>
- <item><c><![CDATA[true]]></c> or <c><![CDATA[false]]></c></item>
- <tag><em>Color.</em></tag>
- <item><c><![CDATA[{R,G,B}]]></c>, or a the predefined name <c><![CDATA[red]]></c>,<c><![CDATA[green]]></c>, <c><![CDATA[blue]]></c>, <c><![CDATA[white]]></c>, <c><![CDATA[black]]></c>, <c><![CDATA[grey]]></c>, or <c><![CDATA[yellow]]></c>. For example <c><![CDATA[{0,0,0}]]></c> is black and <c><![CDATA[{255,255,255}]]></c> is white.</item>
- <tag><em>Cursor.</em></tag>
- <item>A mouse cursor, or any of the following: <c><![CDATA[arrow]]></c>, <c><![CDATA[busy]]></c>, <c><![CDATA[cross]]></c>, <c><![CDATA[hand]]></c>, <c><![CDATA[help]]></c>, <c><![CDATA[resize]]></c>, <c><![CDATA[text]]></c>, or <c><![CDATA[parent]]></c>. <c><![CDATA[parent]]></c> has a special meaning, namely that this object will have the same cursor as its <c><![CDATA[parent]]></c>.</item>
- <tag><em>FileName.</em></tag>
- <item><c><![CDATA[FileName]]></c> is a string. The file name may include a directory path and should point out a file of a suitable type. The path can be either absolute or relative to the directory from where Erlang was started.</item>
- <tag><em>Float.</em></tag>
- <item>Any float, for example 3.1415.</item>
- <tag><em>Font.</em></tag>
- <item>A Font is represented as a two or three tuple:<c><![CDATA[{Family,Size}]]></c> or <c><![CDATA[{Family,Style,Size}]]></c>, where <c><![CDATA[Style]]></c> is <c><![CDATA[bold]]></c>, <c><![CDATA[italic]]></c>, or a combination of those in a list. <c><![CDATA[Size]]></c> is an arbitrary integer. <c><![CDATA[Family]]></c> is a typeface of type <c><![CDATA[times]]></c>, <c><![CDATA[courier]]></c>, <c><![CDATA[helvetica]]></c>, <c><![CDATA[symbol]]></c>, <c><![CDATA[new_century_schoolbook]]></c>, or <c><![CDATA[screen]]></c> (which is a suitable screen font).</item>
- <tag><em>Int.</em></tag>
- <item>Any integer number, for example 42.</item>
- <tag><em>Label.</em></tag>
- <item>A label can either be a plain text label <c><![CDATA[{text, String}]]></c>, or an image <c><![CDATA[{image, FileName}]]></c> where <c><![CDATA[FileName]]></c> should point out a bitmap.</item>
- <tag><em>String.</em></tag>
- <item>An Erlang list of ASCII bytes. For example,
- <c><![CDATA["Hi there"=[72,105,32,116,104,101,114,101]]]></c></item>
- <tag><em>Term.</em></tag>
- <item>Any Erlang term.</item>
- </taglist>
- <p>In cases where the type is self-explanatory, the name of the parameter is used. For example, <c><![CDATA[{move, {Dx,Dy}}]]></c>.</p>
- </section>
-</chapter>
-
diff --git a/lib/gs/doc/src/gs_chapter4.xmlsrc b/lib/gs/doc/src/gs_chapter4.xmlsrc
deleted file mode 100644
index 9085bdbe24..0000000000
--- a/lib/gs/doc/src/gs_chapter4.xmlsrc
+++ /dev/null
@@ -1,197 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2000</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>Events</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- <file>gs_chapter4.xml</file>
- </header>
-
- <section>
- <title>Event Messages</title>
- <p>Events are messages which are sent to the owner process of the object when the user interacts with the object in some way. A simple case is the user pressing a button. An event is then delivered to the owner process of the button (the process that created the button). In the following example, the program creates a button object and enables the events click and enter. This example shows that events are enabled in the same way as objects are configured with options.</p>
- <p></p>
- <code type="none"><![CDATA[
-B = gs:create(button,Win, [{click,true},{enter,true}]),
-event_loop(B).
- ]]></code>
- <p>The process is now ready to receive click and enter events from the button. The events delivered are always five tuples and consist of:</p>
- <code type="none"><![CDATA[
-{gs, IdOrName, EventType, Data, Args}
- ]]></code>
- <list type="bulleted">
- <item><c><![CDATA[gs]]></c> is a tag which says it is an event from the <c><![CDATA[gs]]></c> graphics server.</item>
- <item><c><![CDATA[IdOrName]]></c> contains the object identifier or the name of the object in which the event occurred.</item>
- <item><c><![CDATA[EventType]]></c> contains the type of event which has occurred. In the example shown, it is either <c><![CDATA[click]]></c> or <c><![CDATA[enter]]></c>.</item>
- <item><c><![CDATA[Data]]></c> is a field which the user can set to any Erlang term. It is very useful to have the object store arbitrary data which is delivered with the event.</item>
- <item><c><![CDATA[Args]]></c> is a list which contains event specific information. In a motion event, the Args argument would contain the x and y coordinates.</item>
- </list>
- <p>There are two categories of events:</p>
- <list type="bulleted">
- <item><em>generic events</em></item>
- <item><em>object specific events</em>.</item>
- </list>
- </section>
-
- <section>
- <title>Generic Events</title>
- <p>Generic events are the same for all types of objects. The following table shows a list of generic event types which the graphics server can send to
- a process. For generic events, the <c><![CDATA[Args]]></c> argument always contains the same data, independent of which object delivers it.</p>
- <p>The following sub-sections explains the event types and what they are used for.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Event</em></cell>
- <cell align="left" valign="middle"><em>Args</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">buttonpress</cell>
- <cell align="left" valign="middle">[ButtonNo,X,Y|_]</cell>
- <cell align="left" valign="middle">A mouse button was pressed over the object.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">buttonrelease</cell>
- <cell align="left" valign="middle">[ButtonNo,X,Y|_]</cell>
- <cell align="left" valign="middle">A mouse button was released over the object. </cell>
- </row>
- <row>
- <cell align="left" valign="middle">enter</cell>
- <cell align="left" valign="middle">[]</cell>
- <cell align="left" valign="middle">Delivered when the mouse pointer enters the objects area.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">focus</cell>
- <cell align="left" valign="middle">[Int|_]</cell>
- <cell align="left" valign="middle">Keyboard focus has changed. 0 means lost focus. 1 means gained focus.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">keypress</cell>
- <cell align="left" valign="middle">[KeySym,Keycode, Shift, Control|_]</cell>
- <cell align="left" valign="middle">A key has been pressed. </cell>
- </row>
- <row>
- <cell align="left" valign="middle">leave</cell>
- <cell align="left" valign="middle">[]</cell>
- <cell align="left" valign="middle">Mouse pointer leaves the object.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">motion</cell>
- <cell align="left" valign="middle">[X,Y|_]</cell>
- <cell align="left" valign="middle">The mouse pointer is moving in the object. Used when tracking the mouse in a window.</cell>
- </row>
- <tcaption>Generic Event Types</tcaption>
- </table>
-
- <section>
- <title>The Buttonpress and Buttonrelease Events</title>
- <p>These events are generated when a mouse button is pressed or released inside the object frame of a window, or frame object type. The button events are not object specific (compare to click). The format of the buttonpress event is:</p>
- <code type="none"><![CDATA[
-{gs,ObjectId,buttonpress,Data,[MouseButton,X,Y|_]}
- ]]></code>
- <p>The mouse button number which was pressed is the first argument in the <c><![CDATA[Args]]></c> field list. This number is either 1, 2 or 3, if you have a three button mouse. The <c><![CDATA[X]]></c> and <c><![CDATA[Y]]></c> coordinates are sent along to track in what position the user pressed down the button. These events are useful for programming things like "rubberbanding", which is to draw out an area with the mouse. In detail, this event can be described as pressing the mouse button at a specific coordinate and releasing it at another coordinate in order to define a rectangular area. This action is often used in combination with motion events.</p>
- </section>
-
- <section>
- <title>The Enter and Leave Events</title>
- <p>These events are generated when the mouse pointer (cursor) enters or leaves an object.</p>
- </section>
-
- <section>
- <title>The Focus Event</title>
- <p>The focus event tracks which object currently holds the keyboard focus. Only one object at a time can hold the keyboard focus. To have the keyboard focus means that all keypresses from the keyboard will be delivered to that object. The format of a focus event is:</p>
- <code type="none"><![CDATA[
-{gs,ObjectId,focus, Data,[FocusFlag|_]}
- ]]></code>
- <p>The FocusFlag argument is either 1, which means that the object has gained keyboard focus, or 0, which means that the object has lost keyboard focus.</p>
- </section>
-
- <section>
- <title>The Keypress Event</title>
- <p>This event is generated by an object which receives text input from the user, like entry objects. It can also be generated by window objects. The format of a keypress event is:</p>
- <code type="none"><![CDATA[
-{gs,ObjectId,keypress,Data,[Keysym,Keycode,Shift,Control|_]}
- ]]></code>
- <p>The <c><![CDATA[Keysym]]></c> argument is either the character key which was pressed, or a word which describes which key it was. Examples of <c><![CDATA[Keysyms]]></c> are; <c><![CDATA[a]]></c>,<c><![CDATA[b]]></c>,<c><![CDATA[c]]></c>.., 1,2,3..., <c><![CDATA['Return']]></c>, <c><![CDATA['Delete']]></c>, <c><![CDATA['Insert']]></c>, <c><![CDATA['Home']]></c>, <c><![CDATA['BackSpace']]></c>, <c><![CDATA['End']]></c>. The <c><![CDATA[Keycode]]></c> argument is the keycode number for the key that was pressed. Either the <c><![CDATA[Keysym]]></c> or the <c><![CDATA[Keycode]]></c> argument can be used to find out which key was pressed. The <c><![CDATA[Shift]]></c> argument contains either a 0 or a 1 to indicate if the Shift key was held down when the character key was pressed. The Control argument is similar to the Shift key argument, but applies to the Control key instead of the Shift key.</p>
- </section>
-
- <section>
- <title>The Motion Event</title>
- <p>The motion event is used to track the mouse position in a window. When the user moves the mouse pointer (cursor) to a new position a motion event is generated. The format of a motion event is:</p>
- <code type="none"><![CDATA[
-{gs,ObjectId,motion,Data,[X,Y|_]}
- ]]></code>
- <p>The current x and y coordinates of the cursor are sent along in the <c><![CDATA[Args]]></c> field.</p>
- </section>
- </section>
-
- <section>
- <title>Object Specific Events</title>
- <p>The click and doubleclick events are the object specific event types. Only some objects have these events and the <c><![CDATA[Args]]></c> field of the events vary for different type of objects. A click on a check button generates a click event where the data field contains the on/off value of the indicator. On the other hand, the click event for a list box contains information on which item was chosen.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Event</em></cell>
- <cell align="left" valign="middle"><em>Args</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">click</cell>
- <cell align="left" valign="middle">&lt;object specific&gt;</cell>
- <cell align="left" valign="middle">Pressing a button or operating on a object in some predefined way. </cell>
- </row>
- <row>
- <cell align="left" valign="middle">double-click</cell>
- <cell align="left" valign="middle">&lt;object specific&gt;</cell>
- <cell align="left" valign="middle">Pressing the mouse button twice quickly. Useful with list boxes.</cell>
- </row>
- <tcaption>Object Specific Events</tcaption>
- </table>
- </section>
-
- <section>
- <title>Matching Events Against Object Identifiers</title>
- <p>Events can be matched against the object identifier in the receive statement. The disadvantage of matching against identifiers is that the program must pass the object identifiers as arguments to the event loop.</p>
- <codeinclude file="examples/ex3.erl" tag="" type="erl"></codeinclude>
- </section>
-
- <section>
- <title>Matching Events Against Object Names</title>
- <p>Another solution is to name the objects using the <c><![CDATA[create/4]]></c> function. In this way, the program does not have to pass any parameters which contain object identifiers for each function call made.</p>
- <codeinclude file="examples/ex4.erl" tag="" type="erl"></codeinclude>
- </section>
-
- <section>
- <title>Matching Events Against the Data Field</title>
- <p>A third solution is to set the <c><![CDATA[data]]></c> option to some value and then match against this value. All built-in objects have an option called <c><![CDATA[data]]></c> which can be set to any Erlang term. For example, we could set the data field to a tuple <c><![CDATA[{Mod, Fun,Args}]]></c> and have the receiving function make an <c><![CDATA[apply]]></c> on the contents of the data field whenever certain events arrive.</p>
- <codeinclude file="examples/ex5.erl" tag="" type="erl"></codeinclude>
- </section>
-
- <section>
- <title>Experimenting with Events</title>
- <p>A good way of learning how events work is to write a short demo program like the one shown below and test how different events work.</p>
- <codeinclude file="examples/ex6.erl" tag="" type="erl"></codeinclude>
- </section>
-</chapter>
-
diff --git a/lib/gs/doc/src/gs_chapter5.xmlsrc b/lib/gs/doc/src/gs_chapter5.xmlsrc
deleted file mode 100644
index 1cad8d56bb..0000000000
--- a/lib/gs/doc/src/gs_chapter5.xmlsrc
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2000</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>Fonts</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- <file>gs_chapter5.xml</file>
- </header>
-
- <section>
- <title>The Font Model</title>
- <p>Text related objects can be handled with the font option <c><![CDATA[{font,Font}]]></c>. A <c><![CDATA[Font]]></c> is represented as a two or three tuple:</p>
- <list type="bulleted">
- <item><c><![CDATA[{Family,Size}]]></c></item>
- <item><c><![CDATA[{Family,Style,Size}]]></c></item>
- </list>
- <p>Examples of fonts are: <c><![CDATA[{times,12}]]></c>, <c><![CDATA[{symbol,bold,18}]]></c>, <c><![CDATA[{courier,[bold,italic],6}]]></c>, <c><![CDATA[{screen,12}]]></c>.</p>
- <p>The most important requirement with the font model is to ensure that there is always a "best possible" font present. For example, if an application tries to use the font <c><![CDATA[{times,17}]]></c> on a computer system which does not have this font available, the <c><![CDATA[gs]]></c> font model automatically substitutes <c><![CDATA[{times,16}]]></c>.</p>
- <p>Note that GS requires that the following fonts are available if using an X-server display:</p>
- <list type="bulleted">
- <item>fixed</item>
- <item>-*-courier-*</item>
- <item>-*-times-*</item>
- <item>-*-helvetica-*</item>
- <item>-*-symbol-*</item>
- <item>"-*-new century schoolbook-"</item>
- <item>-*-screen-*</item>
- </list>
- <p>To find out which font is actually chosen by the <c><![CDATA[gs]]></c>, use the option <c><![CDATA[{choose_font,Font}]]></c>. For example, the following situation might occur:</p>
- <pre><![CDATA[
-1> <input>G=gs:start().</input>
-{1,<0.20.0>}
-2><input>gs:read(G,{choose_font,{times,38}}).</input>
-{times,[],38}
-3> <input>gs:read(G,{choose_font,{screen,italic,6}}).</input>
-{courier,italic,6}
-4>
- ]]></pre>
- <p>When programming with fonts, it is often necessary to find the size of a string which uses a specific font. <c><![CDATA[{font_wh,Font}]]></c> returns the width and height of any string and any font. The following example illustrates its usage:</p>
- <marker id="gs_fig6"></marker>
- <image file="images/ex15.gif">
- <icaption>Font Examples</icaption>
- </image>
- <codeinclude file="examples/ex15.erl" tag="" type="erl"></codeinclude>
- </section>
-</chapter>
-
diff --git a/lib/gs/doc/src/gs_chapter6.xmlsrc b/lib/gs/doc/src/gs_chapter6.xmlsrc
deleted file mode 100644
index ecb891ad6f..0000000000
--- a/lib/gs/doc/src/gs_chapter6.xmlsrc
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2000</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>Default Values</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- <file>gs_chapter6.xml</file>
- </header>
-
- <section>
- <title>The Default Value Model</title>
- <p>When a new object is created, a set of options is provided by the application. Options which are not explicitly given are taken care of by the parent (the container object).</p>
- <code type="none"><![CDATA[
-B=gs:create(button,Win,[{x,0},{label,{text,"press Me"}}]).
- ]]></code>
- <p>In the example shown above, the window provides default values for options like location and background color. If an application cannot use the default values provided by GS, new ones can be configured. For example, the following code creates a red button at location y=30.</p>
- <code type="none"><![CDATA[
-gs:config(Win,[{default,button,{y,30}},
-{default,button,{font,{courier,18}}}]),
-B=gs:create(button,Win,[{x,0},{label,{text,"press Me"}}]).
- ]]></code>
- <p>The syntax for the default option is <c><![CDATA[{default,Objecttype,{Option,DefaultValue}}]]></c>, where <c><![CDATA[Objecttype]]></c> is the name of any GS object. The special keywords <c><![CDATA[all]]></c> or <c><![CDATA[buttons]]></c> which denote button, radio button, and check button can be used.</p>
- <p>The semantics for the default option can be expressed as follows: If an object of kind <c><![CDATA[Objecttype]]></c> is created and no value for <c><![CDATA[Option]]></c> is given, then use <c><![CDATA[DefaultValue]]></c> as the value. Only options of <c><![CDATA[{Key,Value}]]></c> syntax can be given a default values. Default values may be inherited in several steps. In the following example, the button will show the text "Cancel".</p>
- <code type="none"><![CDATA[
-gs:config(Win,[{default,button,{label,{text,"Cancel"}}}]),
-F=gs:create(frame,Win,[]),
-B=gs:create(button,F,[]).
- ]]></code>
- <p>Default values are inherited so that changed default values only affect new objects, not existing objects.</p>
- <p>Default values only have meaning when creating child objects, since objects which cannot have children cannot have default options. An example is buttons.</p>
- <p>The following example illustrates how default options can be used:</p>
- <marker id="gs_fig7"></marker>
- <image file="images/ex16.gif">
- <icaption>Example of Default Options</icaption>
- </image>
- <codeinclude file="examples/ex16.erl" tag="" type="erl"></codeinclude>
- </section>
-</chapter>
-
diff --git a/lib/gs/doc/src/gs_chapter7.xmlsrc b/lib/gs/doc/src/gs_chapter7.xmlsrc
deleted file mode 100644
index d0b0859a8f..0000000000
--- a/lib/gs/doc/src/gs_chapter7.xmlsrc
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2000</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>The Packer</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- <file>gs_chapter7.xml</file>
- </header>
-
- <section>
- <title>The Packer</title>
- <p>This section describes the geometry manager in GS.</p>
- <p>When the user resizes a window, the application normally has to resize and move the graphical objects in the window to fit its new size. This can be handled by a so called <em>packer</em> or <em>geometry manager</em>. In GS, the packer functionality is a property of the <c><![CDATA[frame]]></c> object. A frame with the packer property may control the size and position of its children.</p>
- <p>A packer frame organises its children according to a grid pattern of rows and columns. Each row or column has a stretching property associated to it. Some columns may expand more than others and some may have a fixed size. The grid pattern is in itself invisible, but the objects contained by it snap to fit the grid.</p>
- <p>The packer controlled by the following options:</p>
- <p>Frame options:<br></br><c><![CDATA[{packer_x,Packlist}]]></c> where <c><![CDATA[Packlist]]></c> is list() of
- <c><![CDATA[PackOption]]></c>, and<br></br><c><![CDATA[{packer_y,Packlist}]]></c> where <c><![CDATA[Packlist]]></c> is list() of
- <c><![CDATA[PackOption]]></c>.</p>
- <p><c><![CDATA[PackOption]]></c> is:<br></br><c><![CDATA[{stretch, Weight}]]></c> where <c><![CDATA[Weight]]></c> is integer() &gt; 0, or<br></br><c><![CDATA[{stretch, Weight, MinPixelSize, or}]]></c><br></br><c><![CDATA[{stretch, Weight, MinPixelSize, MaxPixelSize}, or]]></c><br></br><c><![CDATA[{fixed, PixelSize}]]></c></p>
- <p>A <c><![CDATA[Weight]]></c> is a relative number that specifies how much of the total space of the frame a row or column will get. If the frame has three columns with the weights 2, 1, 3 it tells the geometry manager that the first column should have 2/6, the second 1/6 and the third 3/6 of the space.</p>
- <p>Note that giving a minimum or maximum width of one or more columns will change the relation and the way the space is divided.</p>
- <p>Then the objects contained by the frame use the following options to position themselves in the grid:<br></br><c><![CDATA[{pack_x,Column}]]></c> where <c><![CDATA[Column]]></c> is integer(), or<br></br><c><![CDATA[{pack_x,{StartColumn,EndColumn}}]]></c></p>
- <p>and<br></br><c><![CDATA[{pack_y,row}]]></c> where <c><![CDATA[row]]></c> is integer(), or<br></br><c><![CDATA[{pack_y,{Startrow,Endrow}}]]></c></p>
- <p>or, the the following option is a convenient shorthand:<br></br><c><![CDATA[{pack_xy,{Column,row}}]]></c></p>
- <p>Consider the following example.</p>
- <codeinclude file="examples/ex17.erl" tag="" type="erl"></codeinclude>
- <p>It defines a frame with three columns where the second should be twice as wide as the other but no column should be smaller than 50 pixels wide. The frame has two rows where the first has a fixed height of 30 pixels and the last row is totally flexible. Three buttons are placed next to each other on the first row, and below them an editor. The editor covers all three columns.</p>
- <marker id="pic:packer1"></marker>
- <image file="images/packer1.gif">
- <icaption>
-Frame with three columns</icaption>
- </image>
- <p>The picture below illustrates what happens when the window is resized.</p>
- <marker id="pic:packer2"></marker>
- <image file="images/packer2.gif">
- <icaption>Resized Frame</icaption>
- </image>
- <p>To repack the objects, the size of the packer frame has to be set explicitly. This is done by using the height and width options as usual. Since the packer frame controls the size of its children, using the standard x, y, width, height options, packer frames may be nested recursively.</p>
- <p>The packer is very useful since it simplifies the programming. The programmer will not have to spend time fine tuning x, y, width, height of each object, since these options are handled by the frame.</p>
- </section>
-</chapter>
-
diff --git a/lib/gs/doc/src/gs_chapter8.xmlsrc b/lib/gs/doc/src/gs_chapter8.xmlsrc
deleted file mode 100644
index 5c74c63aef..0000000000
--- a/lib/gs/doc/src/gs_chapter8.xmlsrc
+++ /dev/null
@@ -1,1691 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2000</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>Built-In Objects</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- <file>gs_chapter8.xml</file>
- </header>
-
- <section>
- <title>Overview</title>
- <p>This section describes the built-in objects of the graphics interface. The following objects exist:</p>
- <taglist>
- <tag><em>Window</em></tag>
- <item>An ordinary window.</item>
- <tag><em>Button</em></tag>
- <item>A simple press button.</item>
- <tag><em>Checkbutton</em></tag>
- <item>A button with a check-mark indicator.</item>
- <tag><em>Radiobutton</em></tag>
- <item>A button with an indicator that has an only-one-selected-at-a-time property.</item>
- <tag><em>Label</em></tag>
- <item>Shows a text or bitmap.</item>
- <tag><em>Frame</em></tag>
- <item>A plain container object. It is used for logical and visual grouping of objects.</item>
- <tag><em>Entry</em></tag>
- <item>A one-line object for entering text.</item>
- <tag><em>Listbox</em></tag>
- <item>A list of text strings.</item>
- <tag><em>Canvas</em></tag>
- <item>A drawing area which contains light-weight objects such as rectangle, line, etc.</item>
- <tag><em>Menu</em></tag>
- <item>A collection of objects for constructing pull-down and pop-up menus.</item>
- <tag><em>Grid</em></tag>
- <item>An object for showing tables. A kind of multi-column listbox.</item>
- <tag><em>Editor</em></tag>
- <item>A multi-line text editor.</item>
- <tag><em>Scale</em></tag>
- <item>To select a value within a range.</item>
- </taglist>
- <p>Some objects can act as container objects. The following table describes these relationships:</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Objects</em></cell>
- <cell align="left" valign="middle"><em>Valid Parents</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">window</cell>
- <cell align="left" valign="middle">window, gs</cell>
- </row>
- <row>
- <cell align="left" valign="middle">buttons, canvas, editor, entry, frame, grid, label, listbox, menubar, scale</cell>
- <cell align="left" valign="middle">frame, window</cell>
- </row>
- <row>
- <cell align="left" valign="middle">arc, image, line, oval, polygon, rectangle, text</cell>
- <cell align="left" valign="middle">canvas</cell>
- </row>
- <row>
- <cell align="left" valign="middle">menubutton</cell>
- <cell align="left" valign="middle">menubar, window, frame</cell>
- </row>
- <row>
- <cell align="left" valign="middle">gridline</cell>
- <cell align="left" valign="middle">grid</cell>
- </row>
- <row>
- <cell align="left" valign="middle">menuitem</cell>
- <cell align="left" valign="middle">menu</cell>
- </row>
- <row>
- <cell align="left" valign="middle">menu</cell>
- <cell align="left" valign="middle">menubutton, menuitem (with {itemtype, cascade}), window, frame (the last two are for pop-up menus)</cell>
- </row>
- <tcaption>Relations Between Objects and Container Objects</tcaption>
- </table>
- </section>
-
- <section>
- <title>Generic Options</title>
- <p>Most objects have a common subset of options and will be referred to as generic options. They apply to most objects.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">beep</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">A beep will sound. Applies to all objects.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Background color. Applies to objects which have a background color.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{data, Term}</cell>
- <cell align="left" valign="middle">[]</cell>
- <cell align="left" valign="middle">Always delivered with the event in the data field. Applies to all objects.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{default,Objecttype,{Key,Value}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Applies to all container objects. Specifies the default value for an option for children of type Objecttype.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{enable, Bool}</cell>
- <cell align="left" valign="middle">true</cell>
- <cell align="left" valign="middle">Objects can be enabled or disabled. A disabled object cannot be clicked on, and text cannot be entered. Applies to buttons, menuitem, entry, editor, scale.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{font, Font}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Applies to all text related objects and the grid.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Foreground color. Applies to objects which have a foreground color.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">flush</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Ensures that front-end and back-end are synchronized. Applies to all objects.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{setfocus, Bool}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Set or remove keyboard focus to this object. Applies to objects which can receive keyboard events.</cell>
- </row>
- <tcaption>Generic Options</tcaption>
- </table>
- <p>The following options apply to objects which can have a <em>frame</em> as parent. Coordinates are relative to the parent.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{cursor, Cursor}</cell>
- <cell align="left" valign="middle">parent</cell>
- <cell align="left" valign="middle">The appearance of the mouse cursor.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{height, Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The height in pixels.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{pack_x, Column|{StartColumn,EndColumn}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Packing position. See The Packer section.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{pack_y, row|{Startrow,Endrow}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Packing position. See The Packer section.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{pack_xy, {Column,row}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Packing position. See The Packer section.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{width, Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The width in pixels.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{x, Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The x coordinate within the parent objects frame in pixels. 0 is to the left.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{y, Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The y coordinate in pixels. 0 is at the top.</cell>
- </row>
- <tcaption>Generic Options (Frame as Parent)</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Config-Only</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">lower</cell>
- <cell align="left" valign="middle">Lowers this object to the bottom in the visual hierarchy.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">raise</cell>
- <cell align="left" valign="middle">Lowers this object in the visual hierarchy.</cell>
- </row>
- <tcaption>Generic Config-Only Options</tcaption>
- </table>
- <p>The following table lists generic Read-Only options:</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Read-Only</em></cell>
- <cell align="left" valign="middle"><em>Return</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">children</cell>
- <cell align="left" valign="middle">[ObjectId1, ..., ObjectIdN]</cell>
- <cell align="left" valign="middle">All children</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{choose_font,Font}</cell>
- <cell align="left" valign="middle">Font</cell>
- <cell align="left" valign="middle">Return the font that is actually used if a particular font is given.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">id</cell>
- <cell align="left" valign="middle">ObjectId</cell>
- <cell align="left" valign="middle">Return the object id for this object. Useful if the object is a named object.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{font_wh,{Font,Text}}</cell>
- <cell align="left" valign="middle">{Width,Height}</cell>
- <cell align="left" valign="middle">Return the size of a text in a specified font. It returns the size of the font that is actually chosen by the back-end.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">type</cell>
- <cell align="left" valign="middle">Atom</cell>
- <cell align="left" valign="middle">The type of this object.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">parent</cell>
- <cell align="left" valign="middle">ObjectId</cell>
- <cell align="left" valign="middle">The parent of this object.</cell>
- </row>
- <tcaption>Generic Read-Only Options</tcaption>
- </table>
-
- <section>
- <title>Generic Event Options</title>
- <p>The table below lists all generic event options:
- </p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{buttonpress, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{buttonrelease, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{enter, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{leave, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{keypress, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{motion, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- </row>
- <tcaption>Generic Event Options</tcaption>
- </table>
- </section>
- </section>
-
- <section>
- <title>Window</title>
- <p>The basic object is the window object. It is the most common container object. All graphical applications use at least one (top-level) window.</p>
- <marker id="gs_fig8"></marker>
- <image file="images/window.gif">
- <icaption>Empty Window titled "A Window".</icaption>
- </image>
- <p>The following tables show all window specific options:</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">{R,G,B} or a color name</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{configure,Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">Will generate a <c><![CDATA[configure]]></c>event when the window has been resized or moved. The <c><![CDATA[Args]]></c>field contains [Width,Height,X,Y|_]</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{destroy,Bool}</cell>
- <cell align="left" valign="middle">true</cell>
- <cell align="left" valign="middle">Will generate a <c><![CDATA[destroy]]></c>event when the window is destroyed from the window manager. All GS applications should handle this event.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{iconname, String}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{iconify, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{map, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">Make it visible on the screen</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{title, String}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The title of the window. The default is the internal widget name which is platform specific.</cell>
- </row>
- <tcaption>Window Options</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Config-Only</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">raise</cell>
- <cell align="left" valign="middle">Raise window on top of all other windows.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">lower</cell>
- <cell align="left" valign="middle">Lower window to background.</cell>
- </row>
- <tcaption>Window Config-Only Options</tcaption>
- </table>
- <p>The following example shows how to create a window and configure it to enable various events.</p>
- <codeinclude file="examples/ex7.erl" tag="" type="erl"></codeinclude>
- </section>
-
- <section>
- <title>Button</title>
- <marker id="gs_fig9"></marker>
- <image file="images/buttons.gif">
- <icaption>Radio Buttons, Check Buttons, and Ordinary Button</icaption>
- </image>
- <p>Buttons are the simplest and the most commonly used objects. You press them and get a click event. The following tables show the options for all button types.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{align, Align}</cell>
- <cell align="left" valign="middle">center</cell>
- <cell align="left" valign="middle">Text alignment within the frame.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{justify, left | center | right}</cell>
- <cell align="left" valign="middle">center</cell>
- <cell align="left" valign="middle">Justification is only valid when there are several lines of text.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{label, Label}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Text or image to show.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{select, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">Check buttons and radio buttons. true means that the button is selected.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{underline, Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Underline character N to indicate a keyboard accelerator.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{group, Atom}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Radio button: only one per group is selected at one time. Check button: All in the same group are selected automatically.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{value, Atom}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Radio buttons only. Groups radio buttons together within a group.</cell>
- </row>
- <tcaption>Options for all Button Types</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Config-Only</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">flash</cell>
- <cell align="left" valign="middle">Flash button</cell>
- </row>
- <row>
- <cell align="left" valign="middle">invoke</cell>
- <cell align="left" valign="middle">Explicit button press.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">toggle</cell>
- <cell align="left" valign="middle">Check buttons only. Toggles select value.</cell>
- </row>
- <tcaption>Config-Only Options for all Button types</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Buttontype</em></cell>
- <cell align="left" valign="middle"><em>Event</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">normal</cell>
- <cell align="left" valign="middle">{gs, itemId, click, Data, [Text| _]}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">check</cell>
- <cell align="left" valign="middle">{gs, itemId, click, Data, [Text, Group, Bool | _]}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">radio</cell>
- <cell align="left" valign="middle">{gs, itemId, click, Data, [Text, Group, Value | _]}</cell>
- </row>
- <tcaption>>Events for all Button types</tcaption>
- </table>
- <p>Buttons and check buttons are simple to understand, radio buttons are more difficult. Each radio button has a group and a value option. The group option is used to group together two or more radio buttons. Normally, each radio button within a group has a unique value which means that only one radio button can be selected at a time. If two (or more) radio buttons share the same value and one of them is selected, then both will be selected and all others are de-selected. The following short example shows how to program radio button logic in a situation where two of them share the same value.</p>
- <codeinclude file="examples/ex8.erl" tag="" type="erl"></codeinclude>
- <marker id="gs_fig10"></marker>
- <image file="images/ex8.gif">
- <icaption>Radio Button Group with Last Button Selected</icaption>
- </image>
- <p>The example shown creates three radio buttons which are members of the same group. The default behavior is that all radio buttons created by the same process are members of the same group. Normally, only one in a group may be selected at the same time, but since we defined the value-option to have the same value for <c><![CDATA[rb1]]></c> and <c><![CDATA[rb2]]></c>, they will both be selected/de-selected simultaneously. The normal radio button group behavior is that all radio buttons within the same group have unique default values.</p>
- </section>
-
- <section>
- <title>Label</title>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{align,Align}</cell>
- <cell align="left" valign="middle">center</cell>
- <cell align="left" valign="middle">How the text is aligned within the frame.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{justify,left|right|center}</cell>
- <cell align="left" valign="middle">left</cell>
- <cell align="left" valign="middle">How to justify several lines of text.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{label,Label}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Text or image to show.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{underline,Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Underline character N to indicate a keyboard accelerator.</cell>
- </row>
- <tcaption>Label Options</tcaption>
- </table>
- <p>A label is a simple text field which is used to display text to the user. It is possible to have several lines of text by inserting newline '\
- ' characters between each line. The label object does not automatically adjust its size so that text will fit inside. This has to be done manually, or the text may be clipped at the edges.</p>
- </section>
-
- <section>
- <title>Frame</title>
- <p>The frame object acts as a container for other objects. Its main use is to logically and visually group objects together. Grouped objects can then be moved, displayed, or hidden in one single operation.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bw,Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Border width</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{packer_x,PackList}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Makes the frame pack its children. See the packer section.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{packer_y,PackList}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Makes the frame pack its children. See the packer section.</cell>
- </row>
- <tcaption>Frame Options</tcaption>
- </table>
- <p>It is possible to have frame objects within frame objects so that large hierarchical structures of objects can be created.</p>
- </section>
-
- <section>
- <title>Entry</title>
- <marker id="gs_fig11"></marker>
- <image file="images/ex9.gif">
- <icaption>Label and Entry Objects for User Input</icaption>
- </image>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{justify, left|right|center}</cell>
- <cell align="left" valign="middle">left</cell>
- <cell align="left" valign="middle">Text justification in entry field.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{text, String}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Use this option to initially set some text, and to read the text.</cell>
- </row>
- <tcaption>Entry Options</tcaption>
- </table>
- <p>Entrys are used to prompt the user for text input.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Config-Only</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{delete, {From, To}}</cell>
- <cell align="left" valign="middle">Deletes the characters within index {From,To}.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{delete, last}</cell>
- <cell align="left" valign="middle">Deletes the last character.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{delete, Index}</cell>
- <cell align="left" valign="middle">Deletes the character at position Index.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{insert, {Index, String}}</cell>
- <cell align="left" valign="middle">Inserts text at the specific character position. Index starts from 0.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{select, {From, To}}</cell>
- <cell align="left" valign="middle">Selects a range.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{select, clear}</cell>
- <cell align="left" valign="middle">De-selects selected text.</cell>
- </row>
- <tcaption>Entry Config-Only Options</tcaption>
- </table>
- <p>A common usage of the entry object is to listen for the 'Return' key event and then read the text field. The following example shows a simple dialog which prompts the user for a name and returns the tuple <c><![CDATA[{name,Name}]]></c> when a name is entered, or <c><![CDATA[cancel]]></c> if the cancel button is pressed.</p>
- <codeinclude file="examples/ex9.erl" tag="" type="erl"></codeinclude>
- <p>The program draws the dialog and waits for the user to either press the return key or click one of the buttons. It then reads the text option of the entry and returns the string to the client process.</p>
- </section>
-
- <section>
- <title>Listbox</title>
- <p>A listbox is a list of labels with optional scroll bars attached. The user selects one or more predefined alternative entries. You can add and remove entries in the listbox. The first element in a listbox has index 0.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{hscroll, Bool | top | bottom}</cell>
- <cell align="left" valign="middle">true</cell>
- <cell align="left" valign="middle">Horizontal scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{items, [String, String ... String]}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">All items (entries) in the listbox.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{scrollbg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Foreground color of scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{scrollfg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Background color of scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{selectmode, single | multiple}</cell>
- <cell align="left" valign="middle">single</cell>
- <cell align="left" valign="middle">Controls if it is possible to have several items selected at the same time.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{vscroll, Bool | left | right}</cell>
- <cell align="left" valign="middle">true</cell>
- <cell align="left" valign="middle">Vertical scroll bar.</cell>
- </row>
- <tcaption>Listbox Options</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Config-Only</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{add, {Index, String}}</cell>
- <cell align="left" valign="middle">Add an item at specified index.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{add, String}</cell>
- <cell align="left" valign="middle">Add an item last.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{change, {Index,String}}</cell>
- <cell align="left" valign="middle">Change one item.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">clear</cell>
- <cell align="left" valign="middle">Delete all items.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{del, Index | {From, To}}</cell>
- <cell align="left" valign="middle">Delete an item at specified index, or all from index From to index To.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{see, Index}</cell>
- <cell align="left" valign="middle">Make the item at specified index visible.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{selection, Index | {From,To}| clear}</cell>
- <cell align="left" valign="middle">Select an item (highlight it). Clear erases the selection.</cell>
- </row>
- <tcaption>Listbox Cinfig-only Options</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Read-Only</em></cell>
- <cell align="left" valign="middle"><em>Return</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">selection</cell>
- <cell align="left" valign="middle">ListOfStrings</cell>
- <cell align="left" valign="middle">Returns current selection. All selected item indices will be returned in a list.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">size</cell>
- <cell align="left" valign="middle">Int</cell>
- <cell align="left" valign="middle">The number of items (entries) in the listbox.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{get, Index}</cell>
- <cell align="left" valign="middle">String</cell>
- <cell align="left" valign="middle">Returns item at specified index.</cell>
- </row>
- <tcaption>Listbox Read-Only Options</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Event</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{gs, ListBox, click, Data, [Index, Text,Bool | _]}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{gs, ListBox, doubleclick, Data, [Index, Text,Bool | _]}</cell>
- </row>
- <tcaption>Listbox Events</tcaption>
- </table>
- <p><c><![CDATA[Bool]]></c> is true if object is selected, false if de-selected.</p>
- <p>Note that <c><![CDATA[click]]></c> and <c><![CDATA[doubleclick]]></c> are two discrete events: if you have subscribed to both, you will receive both a <c><![CDATA[click]]></c> event and a <c><![CDATA[doubleclick]]></c> event when double-clicking on one item (since two rapid clickings are regarded as both a <c><![CDATA[click]]></c> and a <c><![CDATA[doubleclick]]></c>). The subscription of <c><![CDATA[doubleclick]]></c> events does <c><![CDATA[not]]></c> result in the <c><![CDATA[click]]></c> events being unsubscribed!</p>
- <p>The following example shows a simple application which prompts the user for a text item. The user has the following options:</p>
- <list type="bulleted">
- <item>browse the items and then double-click the required item</item>
- <item>type the name into the entry field and then press the Return key</item>
- <item>select the required item and then click the OK button.</item>
- </list>
- <marker id="gs_fig12"></marker>
- <image file="images/ex1.gif">
- <icaption>
-Simple Browser Dialog</icaption>
- </image>
- <codeinclude file="examples/ex10.erl" tag="" type="erl"></codeinclude>
- </section>
-
- <section>
- <title>Canvas</title>
- <p>The canvas object is a simple drawing area. The user can draw graphical objects and move them around the drawing area. The canvas also has optional scroll bars which can be used to scroll the drawing area. The graphical objects that can be created on a canvas object are:</p>
- <list type="bulleted">
- <item>arc</item>
- <item>image</item>
- <item>line</item>
- <item>oval</item>
- <item>polygon</item>
- <item>rectangle</item>
- <item>text.</item>
- </list>
- <p>These objects must have a canvas object as a parent, but they are otherwise similar to all other basic objects. The following tables show the options which apply to canvas objects.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Color of the drawing area.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{hscroll, Bool | top | bottom}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">Horizontal scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{scrollbg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Foreground color of scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{scrollfg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Background color of scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{scrollregion, {X1,Y1,X2,Y2}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The size of the drawing area to be scrolled. </cell>
- </row>
- <row>
- <cell align="left" valign="middle">{vscroll, Bool | left | right}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">Vertical scroll bar.</cell>
- </row>
- <tcaption>Canvas Options</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Read-Only</em></cell>
- <cell align="left" valign="middle"><em>Return</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{hit, {X,Y}}</cell>
- <cell align="left" valign="middle">list of ObjectId</cell>
- <cell align="left" valign="middle">Returns the canvas objects at X,Y.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{hit, [{X1,Y1},{X2,Y2}]}</cell>
- <cell align="left" valign="middle">list of ObjectId</cell>
- <cell align="left" valign="middle">Returns the canvas objects which are hit by the rectangle.</cell>
- </row>
- <tcaption>Canvas Read-Only Options</tcaption>
- </table>
- <p>Canvas objects have the same types of events as other objects. The following Config-Only options also apply to canvas objects:</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Config-Only</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">lower</cell>
- <cell align="left" valign="middle">Lowers the object.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{move, {Dx, Dy}}</cell>
- <cell align="left" valign="middle">Moves object relative to its current position.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">raise</cell>
- <cell align="left" valign="middle">Raises the object above all other objects.</cell>
- </row>
- <tcaption>Canvas Config-Only Options</tcaption>
- </table>
- <p>The following sections describe the graphical objects which can be drawn on a canvas object.</p>
-
- <section>
- <title>The Canvas Arc Object</title>
- <p>The canvas arc object is defined within a rectangle and is drawn from a start angle to the extent angle. Origo is in the center of the rectangle.</p>
- <marker id="gs_fig13"></marker>
- <image file="images/arc.gif">
- <icaption>Canvas Arc Object</icaption>
- </image>
- <code type="none"><![CDATA[
-gs:create(arc,Canvas,[{coords,[{10,10},{80,80}]},{fill,yellow}]).
- ]]></code>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bw, Int}</cell>
- <cell align="left" valign="middle">1</cell>
- <cell align="left" valign="middle">Defines the width.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{coords, [{X1,Y1},{X2,Y2}]}</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">Defines a rectangle to draw the arc within.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{extent, Degrees}</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, Color}</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fill, Color|none}</cell>
- <cell align="left" valign="middle">none</cell>
- <cell align="left" valign="middle">Defines fill color of arc object.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{start, Degrees}</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{style, arc}</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">No line segments.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{style, chord}</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">A single line segment connects the two end points of the perimeter section.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{style, pieslice}</cell>
- <cell align="left" valign="middle">This Style</cell>
- <cell align="left" valign="middle">Two lines are drawn between the center of the oval and each end of the perimeter section.</cell>
- </row>
- <tcaption>Canvas Arc Options</tcaption>
- </table>
- </section>
-
- <section>
- <title>The Canvas Image Object</title>
- <p>The canvas image object displays images and moves them around in a simple way. The currently supported image formats are bitmap and gif.</p>
- <marker id="gs_fig14"></marker>
- <image file="images/image.gif">
- <icaption>Canvas Image Object</icaption>
- </image>
- <code type="none"><![CDATA[
-gs:create(image,Canvas,[{load_gif,"brick.gif"}]).
- ]]></code>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{anchor, Anchor}</cell>
- <cell align="left" valign="middle">nw</cell>
- <cell align="left" valign="middle">Anchor reference specified by {X,Y} .</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Background color. Pixel value 0.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bitmap, FileName}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">A bitmap file which contains a bmp bitmap.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{coords, [{X,Y}]}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Position on the canvas.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Foreground color. Pixel value 1.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{load_gif, FileName}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Loads a gif image.</cell>
- </row>
- <tcaption>Canvas Image Object Options</tcaption>
- </table>
- </section>
-
- <section>
- <title>The Canvas Line Object</title>
- <marker id="gs_fig15"></marker>
- <image file="images/line.gif">
- <icaption>Line Object Drawn on a Canvas</icaption>
- </image>
- <code type="none"><![CDATA[
-gs:create(line,Canvas,
- [{coords,[{25,25},{50,50},{50,40},{85,75}]},
- {arrow,last},{width,2}]).
- ]]></code>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{arrow, both | none | first | last}</cell>
- <cell align="left" valign="middle">none</cell>
- <cell align="left" valign="middle">Draws arrows at the end points of the line.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{coords, [{X1,Y1},{X2,Y2}, ... {Xn,Yn}]}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">A list of coordinates. The line will be drawn between all pairs in the list.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The color of the line.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{smooth, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">Smoothing with Bezier splines.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{splinesteps, Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{width, Int}</cell>
- <cell align="left" valign="middle">1</cell>
- <cell align="left" valign="middle">The width of the line.</cell>
- </row>
- <tcaption>Canvas Line Object Options</tcaption>
- </table>
- </section>
-
- <section>
- <title>The Canvas Oval Object</title>
- <marker id="gs_fig16"></marker>
- <image file="images/oval.gif">
- <icaption>Oval Object Drawn on a Canvas</icaption>
- </image>
- <code type="none"><![CDATA[
-gs:create(oval,Canvas,
- [{coords,[{25,25},{125,75}]},{fill,red},{bw,2}]).
- ]]></code>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bw, Int}</cell>
- <cell align="left" valign="middle">1</cell>
- <cell align="left" valign="middle">Width.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{coords, [{X1,Y1},{X2,Y2}]}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Bounding rectangle which defines shape of object.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, Color}</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fill, Color|none}</cell>
- <cell align="left" valign="middle">none</cell>
- <cell align="left" valign="middle">Object fill color.</cell>
- </row>
- <tcaption>Canvas Oval Object Options</tcaption>
- </table>
- </section>
-
- <section>
- <title>The Canvas Polygon Object</title>
- <marker id="gs_fig17"></marker>
- <image file="images/polygon.gif">
- <icaption>Canvas Polygon Object</icaption>
- </image>
- <code type="none"><![CDATA[
-gs:create(polygon,Canvas,
- [{coords,[{10,10},{50,50},{75,30}]}]).
- ]]></code>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bw, Int}</cell>
- <cell align="left" valign="middle">1</cell>
- <cell align="left" valign="middle">Width.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{coords, [{X1,Y1},{X2,Y2} | {Xn,Yn}]}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Defines all points in the polygon. There may be any number of points in the polygon.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, Color}</cell>
- <cell align="left" valign="middle">black</cell>
- <cell align="left" valign="middle">The color of the polygon outline. </cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fill, Color|none}</cell>
- <cell align="left" valign="middle">none</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{smooth, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">Smoothing with Bezier splines.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{splinesteps, Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <tcaption>Canvas Polygon Object Options</tcaption>
- </table>
- </section>
-
- <section>
- <title>The Canvas Rectangle Object</title>
- <marker id="gs_fig18"></marker>
- <image file="images/rectangle.gif">
- <icaption>Rectangle Object Created on a Canvas</icaption>
- </image>
- <code type="none"><![CDATA[
-gs:create(rectangle,Canvas,
- [{coords,[{30,30},{70,70}]},{fill,cyan},{bw,2}]).
- ]]></code>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bw, Int}</cell>
- <cell align="left" valign="middle">1</cell>
- <cell align="left" valign="middle">The width of the border line.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{coords, [{X1,Y1},{X2,Y2}]}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Defines rectangle coordinates.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The color of the border line.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fill, Color|none}</cell>
- <cell align="left" valign="middle">none</cell>
- <cell align="left" valign="middle">Fill color of rectangle.</cell>
- </row>
- <tcaption>Canvas Rectangle Object Options</tcaption>
- </table>
- </section>
-
- <section>
- <title>The Canvas Text Object</title>
- <marker id="gs_fig19"></marker>
- <image file="images/text.gif">
- <icaption>Canvas Text Object</icaption>
- </image>
- <code type="none"><![CDATA[
-gs:create(text,C,[{coords,[{50,50}]},
- {font,{times,18}},
- {fg,red},
- {text,"Hello World!"}]).
- ]]></code>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{anchor, Anchor}</cell>
- <cell align="left" valign="middle">nw</cell>
- <cell align="left" valign="middle">Anchor reference specified by {X,Y}.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{coords, [{X, Y}]}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Position in the canvas.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Text color (background color is the canvas color).</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{justify, left | center | right}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Tex justification. Only valid with several lines of text.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{text, String}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The text string to display.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{width, Int}</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">The width in pixels. The text will be wrapped into several lines to fit inside the width.</cell>
- </row>
- <tcaption>Canvas Text Object Options</tcaption>
- </table>
- </section>
- </section>
-
- <section>
- <title>Menu</title>
- <p>Menus consist of four object types:</p>
- <list type="bulleted">
- <item>the menu bar</item>
- <item>the menu button</item>
- <item>the menu</item>
- <item>the menu item.</item>
- </list>
-
- <section>
- <title>Menu Bar</title>
- <p>The menu bar is a simple object. It is placed at the top of the window and contains menu items. {x,y} or width cannot be controlled since, by definition, the menu bar is placed at the top of the window.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">&lt;only generic options&gt;</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <tcaption>Menu Bar Options</tcaption>
- </table>
- </section>
-
- <section>
- <title>Menu Button</title>
- <p>The menu button displays a menu when pressed. The width of the menu button is automatically determined by the size of the text.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{align, Align}</cell>
- <cell align="left" valign="middle">center</cell>
- <cell align="left" valign="middle">Text alignment within the frame.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{justify, left | center | right}</cell>
- <cell align="left" valign="middle">center</cell>
- <cell align="left" valign="middle">Justification is only valid when there are several lines of text.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{label,{text,Text}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{side, left | right}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Placement on the menu bar. The menu button created first will have the left/right position.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{underline, Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Underline character N to indicate an keyboard accelerator.</cell>
- </row>
- <tcaption>Menu Button Options</tcaption>
- </table>
- </section>
-
- <section>
- <title>Menu</title>
- <p>The menu contains menu items, which are displayed vertically. Its width is automatically determined by the width of the menu items it contains.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{selectcolor, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The indicator color of radio buttons and check buttons.</cell>
- </row>
- <tcaption>Menu Options</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Config-Only</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{post_at,{X,Y}}</cell>
- <cell align="left" valign="middle">Displays the menu as a pop-up menu at {X,Y} (coordinate system of the parent).</cell>
- </row>
- <tcaption>Menu Config-Only Options</tcaption>
- </table>
- </section>
-
- <section>
- <title>Menu Item</title>
- <p>The menu item is an object of its own. It can send events when the user selects it.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{group, Atom}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">For {type, radio|check}.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{itemtype, type}</cell>
- <cell align="left" valign="middle">normal</cell>
- <cell align="left" valign="middle">The type of this item. Cannot be reconfigured.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{label, {text,Text}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The text of the item.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{underline, Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Underline character N to indicate an keyboard accelerator.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{value, Atom}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">&nbsp;</cell>
- </row>
- <tcaption>Menu Item Options</tcaption>
- </table>
- <p><c><![CDATA[type: normal | separator | check | radio | cascade]]></c></p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>itemtype</em></cell>
- <cell align="left" valign="middle"><em>Event</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">normal</cell>
- <cell align="left" valign="middle">{gs, itemId, click, Data, [Text, Index | _]}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">check</cell>
- <cell align="left" valign="middle">{gs, itemId, click, Data, [Text, Index, Group, Bool| _]}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">radio</cell>
- <cell align="left" valign="middle">{gs, itemId, click, Data, [Text, Index, Group, Value| _]}</cell>
- </row>
- <tcaption>Menu Item Events</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Read-Only</em></cell>
- <cell align="left" valign="middle"><em>Return</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">index</cell>
- <cell align="left" valign="middle">Int</cell>
- <cell align="left" valign="middle">Index in the menu. Starts counting from 0.</cell>
- </row>
- <tcaption>Menu Item Read-Only Options</tcaption>
- </table>
- </section>
-
- <section>
- <title>Menu Demo</title>
- <marker id="gs_fig20"></marker>
- <image file="images/ex13.gif">
- <icaption>Simple Menu</icaption>
- </image>
- <p>The following example shows a short demo of the <c><![CDATA[gs]]></c> menus:</p>
- <codeinclude file="examples/ex13.erl" tag="" type="erl"></codeinclude>
- </section>
- </section>
-
- <section>
- <title>Grid</title>
- <p>The grid object is similar to the listbox object. The main difference is that the grid is a multi-column object which is used to display tables. If needed, the grid can send click events when a user presses the mouse button in a table cell. Although the grid has a behavior which is similar to the listbox, the programming is somewhat different. The data in a table cell is represented as a pure <c><![CDATA[gs]]></c> object and can be treated as such. This object is called a grid line. It is located at a row in the parent grid. If a grid line is clicked, it sends an event to its owner.</p>
-
- <section>
- <title>Grid Line</title>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{{bg, Column},Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The background color of a cell.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bg, {Column,Color}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Equivalent to {{bg, Column},Color}.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The background color of all cells.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{click, Bool}</cell>
- <cell align="left" valign="middle">true</cell>
- <cell align="left" valign="middle">Turns click events on/off.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{doubleclick, Bool}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">Turns double-click events on/off.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{{fg, Column},Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The foreground color of a cell.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, {Column,Color}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Equivalent to {{fg, Column},Color}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg,Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The foreground color of all cells.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{text, {Column,Text}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The text in the cell.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{{text, Column},Text}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Equivalent to {text,{Column,Text}}.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{text,Text}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The text for all cells.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{row, {row}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The grid row. Must not be occupied by another grid line.</cell>
- </row>
- <tcaption>Grid Line Options</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Event</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{gs, GridLineId, click, Data, [Col, row, Text | _]}</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{gs, GridLineId, doubleclick, Data, [Col, row, Text | _]}</cell>
- </row>
- <tcaption>Gride Line Events</tcaption>
- </table>
- </section>
-
- <section>
- <title>Grid</title>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{font,Font}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">A "global" grid font.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{hscroll, Bool|top|bottom}</cell>
- <cell align="left" valign="middle">true</cell>
- <cell align="left" valign="middle">Horizontal scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{vscoll, Bool|left|right}</cell>
- <cell align="left" valign="middle">true</cell>
- <cell align="left" valign="middle">Vertical scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{rows, {Minrow,Maxrow}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The rows which are currently displayed.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{columnwidths, [WidthCol1,WidthCol2, ..., WidthColN}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Defines the number of columns and their widths in coordinates. The size of the columns can be reconfigured, but not the number of columns.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The color of the grid pattern and the text.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{bg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The background color.</cell>
- </row>
- <tcaption>Grid Options</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Read-Only</em></cell>
- <cell align="left" valign="middle"><em>Return</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{obj_at_row, row}</cell>
- <cell align="left" valign="middle">Object |undefined</cell>
- <cell align="left" valign="middle">The grid line at row.</cell>
- </row>
- <tcaption>Grid Read-Only Options</tcaption>
- </table>
- <p>The rows and columns start counting at 1.</p>
- </section>
-
- <section>
- <title>Grid Demo</title>
- <marker id="gs_fig21"></marker>
- <image file="images/ex12.gif">
- <icaption>Simple Grid</icaption>
- </image>
- <p>The following simple example shows how to use the grid.</p>
- <codeinclude file="examples/ex12.erl" tag="" type="erl"></codeinclude>
- </section>
- </section>
-
- <section>
- <title>Editor</title>
- <p>The editor object is a simple text editor.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{hscroll, Bool | top | bottom}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">Horizontal scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{insertpos,{row,Col}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The position of the cursor.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{insertpos,'end'}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The position of the cursor.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{justify, left| right| center}</cell>
- <cell align="left" valign="middle">left</cell>
- <cell align="left" valign="middle">Text justification.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{scrollbg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Background color of scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{scrollfg, Color}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">Foreground color of scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{selection, {FromIndex,ToIndex}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The text range that is currently selected.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{vscroll, Bool | left | right}</cell>
- <cell align="left" valign="middle">false</cell>
- <cell align="left" valign="middle">Vertical scroll bar.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{vscrollpos, row}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The top most visible row in the editor.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{wrap, none|char | word}</cell>
- <cell align="left" valign="middle">none</cell>
- <cell align="left" valign="middle">How to wrap text when the line is full.</cell>
- </row>
- <tcaption>Editor Options</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Config-Only</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">clear</cell>
- <cell align="left" valign="middle">Clears the editor.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{del, {FromIndex, ToIndex}}}</cell>
- <cell align="left" valign="middle">Deletes text.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg, {{FromIndex,ToIndex},Color}}</cell>
- <cell align="left" valign="middle">Sets the foreground color of a range of text.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{load, FileName}</cell>
- <cell align="left" valign="middle">Read FileName into the editor.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{insert, {Index, Text}}</cell>
- <cell align="left" valign="middle">Inserts new text.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{overwrite, {Index, Text}}</cell>
- <cell align="left" valign="middle">Writes new text at index.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{save, FileName}</cell>
- <cell align="left" valign="middle">Writes editor contents to file.</cell>
- </row>
- <tcaption>Editor Config-Only Options</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Read-Only</em></cell>
- <cell align="left" valign="middle"><em>Return</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">char_height</cell>
- <cell align="left" valign="middle">Int</cell>
- <cell align="left" valign="middle">The height of the editor window measured in characters.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">char_width</cell>
- <cell align="left" valign="middle">Int</cell>
- <cell align="left" valign="middle">The width of the editor window measured in characters.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{fg,Index}</cell>
- <cell align="left" valign="middle">Int</cell>
- <cell align="left" valign="middle">The foreground color of the text at Index.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{get,{FromIndex, ToIndex}}</cell>
- <cell align="left" valign="middle">Text</cell>
- <cell align="left" valign="middle">The text between the indices.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">size</cell>
- <cell align="left" valign="middle">Int</cell>
- <cell align="left" valign="middle">The number of rows in the editor.</cell>
- </row>
- <tcaption>Editor Read-Only Options</tcaption>
- </table>
- <code type="none"><![CDATA[
-Index: 'end'|insert|{row,Col}|{row,lineend}
- ]]></code>
-
- <section>
- <title>Editor Demo</title>
- <marker id="gs_fig22"></marker>
- <image file="images/ex14.gif">
- <icaption>Simple Editor</icaption>
- </image>
- <codeinclude file="examples/ex14.erl" tag="" type="erl"></codeinclude>
- </section>
- </section>
-
- <section>
- <title>Scale</title>
- <p>A scale object is used to select a value within a specified range.</p>
- <table>
- <row>
- <cell align="left" valign="middle"><em>{Option,Value}</em></cell>
- <cell align="left" valign="middle"><em>Default</em></cell>
- <cell align="left" valign="middle"><em>Description</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{orient, vertical | horizontal}</cell>
- <cell align="left" valign="middle">horizontal</cell>
- <cell align="left" valign="middle">The orientation of the scale.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{pos, Int}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The current value of the scale objects within the range.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{range, {Min, Max}}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">The value range.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{showvalue, Bool}</cell>
- <cell align="left" valign="middle">true</cell>
- <cell align="left" valign="middle">Turns showing of scale value on/off.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">{text, String}</cell>
- <cell align="left" valign="middle">&lt;unspec&gt;</cell>
- <cell align="left" valign="middle">If specified, a label will be attached to the scale.</cell>
- </row>
- <tcaption>Scale Object Options</tcaption>
- </table>
- <table>
- <row>
- <cell align="left" valign="middle"><em>Event</em></cell>
- </row>
- <row>
- <cell align="left" valign="middle">{gs, Scale, click, Data, [Value | _]}</cell>
- </row>
- <tcaption>Scale Object Options</tcaption>
- </table>
- <p>The following example prompts a user to specify an RGB-value for the background color of a window.</p>
- <marker id="gs_fig23"></marker>
- <image file="images/ex11.gif">
- <icaption>Scale Objects for Selecting RGB Values for a Window</icaption>
- </image>
- <codeinclude file="examples/ex11.erl" tag="" type="erl"></codeinclude>
- </section>
-</chapter>
-
diff --git a/lib/gs/doc/src/images/arc.gif b/lib/gs/doc/src/images/arc.gif
deleted file mode 100644
index 27563bae58..0000000000
--- a/lib/gs/doc/src/images/arc.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/arc.ps b/lib/gs/doc/src/images/arc.ps
deleted file mode 100644
index 293c10a6d2..0000000000
--- a/lib/gs/doc/src/images/arc.ps
+++ /dev/null
@@ -1,1385 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/arc.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 353 338 460
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 411 string def
-
-% define space for color conversions
-/grays 137 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 353 translate
-
-% size of image (on paper, in 1/72inch coords)
-137.01600 106.99200 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-137 107 8 % dimensions of data
-[137 0 0 -107 0 107] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffff000000000080000080ffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000000000
-c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffffffffffffffffffff000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000000000
-c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000
-c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080000080ffffff000080000080ffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080000080000080000080000080000080000080
-ffffff000080000080ffffff000080000080ffffffffffff000080ffffffffffff000080
-ffffffffffffffffffffffff000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffffffffff000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffffffffffffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffffffffffffffffffffffffffff000080ffffffffffff000080000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080ffffffffffff
-000080000080000080000080ffffffffffffffffffffffff000080000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080ffffffffffff
-000080000080000080000080ffffffffffffffffffffffff000080000080000080ffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0
-000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000
-c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080ffffffffffff
-000080000080000080000080ffffffffffffffffffffffff000080000080000080000080
-ffffffffffffffffffffffff000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0
-000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000000000
-c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffff737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373000000
-ffffff737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373000000000080000080ffffff737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000080000080000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/buttons.gif b/lib/gs/doc/src/images/buttons.gif
deleted file mode 100644
index 449e33892b..0000000000
--- a/lib/gs/doc/src/images/buttons.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/buttons.ps b/lib/gs/doc/src/images/buttons.ps
deleted file mode 100644
index 4563cbf295..0000000000
--- a/lib/gs/doc/src/images/buttons.ps
+++ /dev/null
@@ -1,6003 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/buttons.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 232 511 459
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 930 string def
-
-% define space for color conversions
-/grays 310 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 232 translate
-
-% size of image (on paper, in 1/72inch coords)
-310.03200 227.01600 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-310 227 8 % dimensions of data
-[310 0 0 -227 0 227] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000000080000080ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffff000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080ffffffffffff000080000080
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000
-000000000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080ffffffffffff000080000080
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000
-000000000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffffffffffffffff000080
-ffffffffffffffffffffffff000080000080ffffffffffffffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080000080ffffffffffffffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffffffffff000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080000080ffffffffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080000080000080ffffffffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080ffffffffffffffffff000080000080ffffffffffff000080ffffff
-000080ffffffffffff000080ffffffffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080ffffffffffff000080ffffffffffff000080000080000080ffffffffffff000080
-000080000080ffffffffffff000080000080ffffffffffffffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffffffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000
-000000000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffff737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373000000ffffff737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373000000000080000080ffffff
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000080000080000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffff828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-ffffffd9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-828282d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff828282828282828282828282828282
-828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff828282828282828282828282828282828282
-828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282828282828282828282
-828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282828282828282828282
-828282828282828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-ffffffd9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-828282d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffff828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-828282b03060b03060828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282
-b03060b03060b03060b03060828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9828282828282828282b03060
-b03060b03060b03060b03060b03060828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9ffffffffffffffffffb03060b03060
-b03060b03060b03060b03060b03060b03060ffffffffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9ffffffffffffffffffb03060
-b03060b03060b03060b03060b03060ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffff
-b03060b03060b03060b03060ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-ffffffb03060b03060ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff828282828282828282828282828282
-828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff828282828282828282828282828282828282
-828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282828282828282828282
-828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282828282828282828282
-828282828282828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282b03060b03060b03060b03060b03060
-b03060b03060ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffff828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/ex1.gif b/lib/gs/doc/src/images/ex1.gif
deleted file mode 100644
index 2337fafd28..0000000000
--- a/lib/gs/doc/src/images/ex1.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/ex1.ps b/lib/gs/doc/src/images/ex1.ps
deleted file mode 100644
index 1bb750b7a9..0000000000
--- a/lib/gs/doc/src/images/ex1.ps
+++ /dev/null
@@ -1,2387 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/ex1.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 332 411 459
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 630 string def
-
-% define space for color conversions
-/grays 210 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 332 translate
-
-% size of image (on paper, in 1/72inch coords)
-210.02400 127.00800 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-210 127 8 % dimensions of data
-[210 0 0 -127 0 127] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff000000000080000080ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffffffffffffffffffff000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080ffffffffffff000080ffffffffffff
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080ffffffffffff000080ffffffffffff
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080ffffffffffff000080ffffffffffff
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080ffffffffffffffffffffffff000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffff737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-000000ffffff737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373000000000080000080ffffff737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000080000080000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000
-d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffff828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/ex10.gif b/lib/gs/doc/src/images/ex10.gif
deleted file mode 100644
index d4f2a8fb51..0000000000
--- a/lib/gs/doc/src/images/ex10.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/ex10.ps b/lib/gs/doc/src/images/ex10.ps
deleted file mode 100644
index 49b44ae7e3..0000000000
--- a/lib/gs/doc/src/images/ex10.ps
+++ /dev/null
@@ -1,6635 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/ex10.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 163 461 460
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 780 string def
-
-% define space for color conversions
-/grays 260 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 163 translate
-
-% size of image (on paper, in 1/72inch coords)
-259.99200 297.00000 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-260 297 8 % dimensions of data
-[260 0 0 -297 0 297] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffff000000000080000080ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000
-000000000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000
-000000000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080ffffffffffff000080ffffffffffffffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffffffffffffffff000080000080000080ffffffffffffffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffffffffffffffffffffffffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffffffffffffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-ffffffffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffffffffff000080000080000080000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffffffffff000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080ffffffffffff000080000080000080
-000080ffffffffffffffffff000080000080ffffffffffffffffffffffffffffffffffff
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080ffffffffffff000080000080000080
-000080000080ffffffffffffffffff000080ffffffffffff000080000080000080000080
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-ffffffffffff000080000080000080000080ffffffffffffffffffffffff000080000080
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-ffffffffffffffffffffffff000080000080000080ffffffffffffffffffffffff000080
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000
-000000000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373000000ffffff737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373000000000080000080ffffff737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000080000080000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282ffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282828282ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-828282ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282ffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffff828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffff828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3ffffffffffff828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3ffffffffffffd9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffff828282
-828282828282828282828282828282828282828282828282828282828282828282c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffff828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffc3c3c3000000000000000000c3c3c3c3c3c3c3c3c3000000c3c3c3
-000000000000c3c3c3c3c3c3c3c3c3c3c3c3000000000000000000c3c3c3c3c3c3c3c3c3
-000000c3c3c3000000000000c3c3c3c3c3c3c3c3c3c3c3c3000000000000c3c3c3000000
-c3c3c3c3c3c3c3c3c3000000000000000000c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffff000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3000000000000
-c3c3c3c3c3c3000000c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3
-000000000000c3c3c3c3c3c3000000c3c3c3c3c3c3000000c3c3c3c3c3c3000000000000
-c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffff000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3000000c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3
-000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3000000
-c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffff000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3000000c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3000000000000000000000000c3c3c3c3c3c3
-000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3000000
-c3c3c3c3c3c3000000000000000000000000000000c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffff000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3000000c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3
-000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3000000
-c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffff000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3000000c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3
-000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3000000c3c3c3c3c3c3000000000000
-c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffc3c3c3000000000000000000c3c3c3c3c3c3c3c3c3000000c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3000000000000000000000000c3c3c3c3c3c3
-000000c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3000000000000c3c3c3000000
-c3c3c3c3c3c3c3c3c3000000000000000000c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3000000
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3000000c3c3c3c3c3c3c3c3c3000000
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3000000000000000000c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffff757575757575757575757575757575757575757575757575757575
-757575757575757575757575757575757575757575757575757575757575757575757575
-757575757575757575757575757575757575757575757575757575757575757575757575
-757575757575757575757575757575757575757575757575757575757575757575757575
-757575757575757575757575757575757575757575757575757575757575757575757575
-757575757575757575757575757575757575757575757575757575757575757575757575
-757575757575757575757575757575757575757575757575757575757575757575757575
-757575757575757575757575757575757575757575757575757575757575757575757575
-757575757575757575757575757575757575757575757575757575757575757575757575
-757575757575757575757575757575757575757575757575757575757575757575757575
-757575757575757575757575757575757575757575757575757575757575757575757575
-757575757575757575ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffff828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffff828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffff828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3ffffffffffffd9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffff828282828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffff828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3ffffffc3c3c3ffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffc3c3c3ffffffffffffc3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-ffffffffffff828282c3c3c3ffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff828282c3c3c3ffffffffffffffffffffffffc3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff
-ffffff828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffffffffffffffffffffffffff
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffffffffffffff
-d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9ffffffffffff
-ffffffffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffffffffffffffd9d9d9d9d9d9
-d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffffffffffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ffffffffffffffffffffffffc3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffc3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282828282828282c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282828282828282828282d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffff828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282828282828282828282
-d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9828282828282
-828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffff828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282828282
-828282828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffff828282828282828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-828282828282828282c3c3c3ffffffffffff828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282c3c3c3ffffffffffff828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3828282c3c3c3ffffff828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282c3c3c3ffffff828282c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/ex11.gif b/lib/gs/doc/src/images/ex11.gif
deleted file mode 100644
index 052a380abc..0000000000
--- a/lib/gs/doc/src/images/ex11.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/ex11.ps b/lib/gs/doc/src/images/ex11.ps
deleted file mode 100644
index 99c79577c7..0000000000
--- a/lib/gs/doc/src/images/ex11.ps
+++ /dev/null
@@ -1,5873 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/ex11.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 238 511 460
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 930 string def
-
-% define space for color conversions
-/grays 310 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 238 translate
-
-% size of image (on paper, in 1/72inch coords)
-310.03200 221.97600 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-310 222 8 % dimensions of data
-[310 0 0 -222 0 222] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000000080000080ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffff000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080ffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080ffffffffffffffffffffffffffffff000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000
-000000000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000
-000000000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080000080
-ffffffffffffffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080000080
-000080000080ffffffffffff000080000080000080ffffffffffff000080000080ffffff
-ffffffffffffffffff000080000080ffffff000080ffffffffffffffffff000080ffffff
-ffffffffffff000080000080000080ffffffffffffffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffffffffffffffffffffff000080000080000080
-000080000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffffffffff000080000080000080000080000080
-000080000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080000080000080000080000080
-000080000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffff
-ffffffffffffffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080000080000080000080000080
-000080000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffff
-000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080000080000080ffffffffffff000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080000080000080000080000080
-000080000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080000080000080ffffffffffffffffffffffff000080000080
-ffffffffffffffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-ffffffffffff000080000080ffffffffffff000080000080000080000080000080000080
-000080000080ffffffffffffffffffffffffffffff000080000080000080000080ffffff
-ffffffffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080000080ffffffffffffffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000
-000000000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffff737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373000000ffffff737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373000000000080000080ffffff
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000080000080000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffff828282828282828282828282828282828282828282828282828282828282828282
-828282828282ffffff828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff828282828282828282828282828282
-828282828282828282828282828282828282828282828282ffffff828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7f
-ffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7f
-ffff7fffff7fffff7fffff7fffff7fc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7f
-ffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7fffff7f
-ffff7fffff7fffff7fffff7fffff7fc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffff828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4
-ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4
-ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4ff6eb4
-ffff00ff6eb4ff6eb4ff6eb4ffff00ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4ffff00
-ffff00ffff00ff6eb4ffff00ffff00ffff00ff6eb4ff6eb4ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4ff6eb4
-ffff00ff6eb4ff6eb4ff6eb4ffff00ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4ff6eb4
-ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4ff6eb4
-ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4
-ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4
-ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ff6eb4ff6eb4ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-ffffff828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ff6eb4ffff00ffff00ffff00ffff00ffff00
-ffff00ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ff6eb4ff6eb4ff6eb4ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4ff6eb4ff6eb4ffff00
-ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4
-ff6eb4ffff00ffff00ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4
-ff6eb4ff6eb4ffff00ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4ff6eb4ff6eb4ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ff6eb4ff6eb4ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7fffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00
-ffff00ffff00ffff00ffff00999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95d34f95
-ffff7fffff7f999900999900999900999900999900999900999900999900999900999900
-999900999900999900999900999900999900999900999900999900999900999900999900
-999900999900999900999900999900c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/ex12.gif b/lib/gs/doc/src/images/ex12.gif
deleted file mode 100644
index 4c75c3f611..0000000000
--- a/lib/gs/doc/src/images/ex12.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/ex12.ps b/lib/gs/doc/src/images/ex12.ps
deleted file mode 100644
index c3654e992a..0000000000
--- a/lib/gs/doc/src/images/ex12.ps
+++ /dev/null
@@ -1,4187 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/ex12.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 232 411 459
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 630 string def
-
-% define space for color conversions
-/grays 210 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 232 translate
-
-% size of image (on paper, in 1/72inch coords)
-210.02400 227.01600 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-210 227 8 % dimensions of data
-[210 0 0 -227 0 227] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff000000000080000080ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080000080ffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080ffffffffffff000080ffffffffffff
-000080ffffffffffffffffffffffff000080000080ffffffffffff000080ffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080ffffffffffff000080ffffffffffffffffff000080ffffffffffff
-ffffffffffffffffffffffffffffff000080ffffffffffff000080ffffffffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080ffffffffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080ffffffffffff
-000080000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080ffffffffffff
-000080000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080ffffffffffff000080ffffffffffffffffff000080ffffffffffff
-000080000080000080ffffffffffff000080ffffffffffff000080ffffffffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080ffffffffffff000080ffffffffffff000080ffffffffffff
-000080000080000080ffffffffffff000080000080ffffffffffff000080ffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffff737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-000000ffffff737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373000000000080000080ffffff737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000080000080000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3ffffff828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000bebebebebebe000000
-000000bebebebebebebebebebebebe000000bebebebebebebebebebebebe000000000000
-bebebebebebebebebe000000000000bebebebebebe000000000000000000000000000000
-000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000000000000000000000bebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebebebebe000000000000000000
-000000bebebebebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000000000000000000000000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3ffffff828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000bebebebebebe000000
-000000bebebebebebebebebe000000000000000000bebebebebebebebebe000000000000
-bebebebebebebebebe000000000000bebebebebebe000000000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffff828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000bebebe000000
-000000bebebebebebebebebe000000000000000000bebebebebebebebebe000000000000
-000000bebebe000000000000000000bebebebebebe000000000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebe000000000000000000bebebe000000000000bebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000bebebe000000
-000000bebebebebebe000000000000bebebe000000000000bebebebebebe000000000000
-000000bebebe000000000000000000bebebebebebe000000000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebe000000000000000000bebebe000000000000bebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000000000000000
-000000bebebebebebe000000000000bebebe000000000000bebebebebebe000000000000
-000000000000000000000000000000bebebebebebe000000000000000000000000000000
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000000000000000000000bebebebebebebebebe
-000000000000000000000000000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebe000000000000000000000000000000000000bebebebebebe
-000000000000000000000000000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000bebebe000000000000
-000000bebebe000000000000bebebebebebebebebe000000000000bebebe000000000000
-bebebe000000bebebe000000000000bebebebebebe000000000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebe000000000000bebebe000000000000000000bebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000bebebe000000000000
-000000bebebe000000000000000000000000000000000000000000bebebe000000000000
-bebebe000000bebebe000000000000bebebebebebe000000000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebe000000000000bebebe000000000000000000bebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000bebebebebebe000000
-000000bebebe000000000000bebebebebebebebebe000000000000bebebe000000000000
-bebebebebebebebebe000000000000bebebebebebe000000000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000bebebebebebe000000
-000000bebebe000000000000bebebebebebebebebe000000000000bebebe000000000000
-bebebebebebebebebe000000000000bebebebebebe000000000000000000000000000000
-000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000bebebebebebebebebe000000000000000000
-000000bebebebebebebebebe000000000000bebebebebebe000000000000bebebebebebe
-000000000000000000000000000000000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-828282828282828282828282828282828282828282828282828282828282828282828282
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffff828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebe000000bebebebebebe
-bebebebebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-000000000000000000bebebebebebebebebebebebe000000000000000000bebebebebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebe000000bebebebebebe
-bebebebebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000000000bebebebebebebebebebebebe000000
-bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe000000bebebe
-bebebebebebebebebebebebe000000000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebe000000bebebe000000bebebe
-bebebebebebebebebe000000000000bebebe000000bebebebebebebebebe000000000000
-000000bebebebebebebebebe000000000000bebebe000000bebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000bebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebebebebe000000bebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebe000000bebebe000000bebebe
-bebebebebebe000000bebebebebebe000000000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebe000000bebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebe000000bebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebe000000bebebe000000bebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebebebebe000000bebebe000000bebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebe000000bebebebebebebebebebebebebebebe000000000000bebebebebebe
-bebebe000000bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe000000000000
-000000000000bebebebebebe000000bebebe000000bebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe000000bebebe
-bebebe000000bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000000000000000
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebe000000bebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-000000bebebebebebebebebebebebebebebebebebebebebebebebebebebe000000bebebe
-bebebe000000000000000000000000000000000000bebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebe000000bebebebebebe000000000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebe000000bebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebe000000
-bebebebebebebebebebebebebebebebebebe000000bebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebebebebe000000000000bebebe000000bebebebebebebebebe000000000000
-000000000000bebebebebebe000000bebebe000000bebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000000000000000000000bebebebebebe000000
-000000000000000000000000bebebebebebebebebe000000000000000000bebebebebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000bebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebe000000bebebebebebebebebe
-000000000000000000bebebebebebebebebebebebe000000000000000000bebebebebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebe000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebe000000000000bebebebebebe000000
-bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe000000bebebe
-bebebebebebe000000000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebe000000bebebe
-bebebebebebebebebe000000000000000000bebebebebebebebebebebebe000000000000
-000000bebebebebebebebebe000000000000000000000000000000bebebebebebebebebe
-000000000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebe000000bebebebebebebebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe000000bebebe
-bebebe000000bebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebe000000bebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebebebebebebebe000000bebebebebebebebebebebebe000000
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000000000bebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe
-bebebe000000000000bebebebebebebebebebebebebebebebebebe000000bebebebebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebe000000000000000000000000000000bebebebebebebebebe000000000000
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-000000000000000000000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebe000000bebebebebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebe000000bebebebebebebebebebebebebebebebebebe000000bebebebebebe
-bebebe000000bebebebebebebebebebebebe000000bebebebebebebebebebebebe000000
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000000000000000000000000000bebebebebebe
-bebebebebebebebebe000000bebebebebebebebebe000000bebebebebebebebebebebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebebebebebebebe000000bebebebebebebebebebebebe000000
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebe000000bebebebebebe000000
-bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000000000bebebe
-bebebebebebebebebe000000000000000000bebebebebebebebebebebebe000000000000
-000000000000bebebebebebebebebebebebebebebe000000000000bebebebebebebebebe
-000000000000000000000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebe000000bebebebebebebebebe
-000000000000000000bebebebebebebebebe000000000000000000000000000000bebebe
-bebebe000000000000000000000000000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffff828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000000000000000
-bebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebe000000bebebebebebebebebe000000000000000000bebebebebebe
-bebebebebebe000000000000000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebe000000bebebebebebe
-bebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000000000bebebebebebebebebebebebebebebe
-bebebebebebe000000000000bebebebebebe000000bebebebebebebebebe000000bebebe
-bebebe000000bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebe000000bebebebebebe
-bebebebebebe000000bebebe000000000000bebebebebebebebebebebebe000000000000
-000000bebebebebebebebebe000000000000bebebe000000bebebebebebebebebebebebe
-000000000000000000bebebebebebebebebebebebe000000000000000000bebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000bebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebe000000bebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebe000000bebebebebebe
-bebebebebebe000000000000bebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebe000000bebebe000000bebebebebebe000000
-bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-000000bebebebebebe000000bebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebe000000bebebebebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebe000000bebebe000000bebebebebebebebebe
-bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebe000000
-bebebebebebebebebe000000bebebebebebebebebebebebe000000000000bebebebebebe
-bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebe000000bebebebebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebe000000bebebe000000bebebebebebebebebe
-000000000000000000000000bebebebebebebebebe000000000000000000bebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebe000000
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebe000000bebebebebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebe000000bebebe000000bebebebebebe000000
-bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebe000000
-000000000000000000000000000000bebebebebebebebebebebebebebebe000000bebebe
-bebebebebebe000000bebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebe000000bebebebebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebe000000bebebe000000bebebebebebe000000
-bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe000000bebebe
-bebebe000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebe000000bebebebebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe000000000000
-000000bebebebebebebebebe000000bebebe000000bebebe000000bebebebebebebebebe
-000000000000000000000000bebebebebebebebebe000000000000000000bebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000000000000000000000bebebebebebebebebe
-bebebebebebebebebe000000bebebebebebebebebe000000000000000000bebebebebebe
-bebebe000000000000000000000000000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000bebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000000000bebebebebebebebebebebebe
-bebebe000000000000bebebebebebebebebe000000000000000000000000000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebe000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe
-000000bebebebebebe000000bebebebebebe000000bebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebe000000bebebe
-bebebebebebebebebe000000000000000000bebebebebebebebebe000000bebebe000000
-000000bebebebebebebebebebebebe000000000000bebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe
-000000bebebebebebe000000bebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebe000000bebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000000000bebebe
-bebebe000000bebebebebebe000000bebebebebebe000000000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe
-000000bebebebebebe000000bebebebebebebebebebebebebebebe000000bebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000000000bebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe
-000000bebebebebebe000000bebebebebebebebebebebebebebebe000000bebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe
-000000bebebebebebe000000bebebebebebebebebebebebebebebe000000bebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe
-000000bebebebebebe000000bebebebebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebebebebe000000000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe
-000000bebebebebebe000000bebebebebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000000000bebebe
-bebebebebebebebebe000000000000000000bebebebebebebebebe000000bebebebebebe
-bebebe000000bebebebebebebebebe000000000000bebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000000000bebebebebebebebebebebebe
-bebebe000000000000bebebebebebebebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebebebebebebebebebebebebebe000000000000000000bebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebe000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000000000bebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebe000000bebebebebebe
-bebebebebebebebebe000000000000000000bebebebebebebebebe000000bebebe000000
-000000bebebebebebebebebebebebe000000000000bebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000bebebe000000bebebebebebebebebebebebe000000
-bebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000bebebebebebebebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebe000000000000bebebe
-bebebe000000bebebebebebe000000bebebebebebe000000000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebe000000bebebebebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebebebebebebebebebebebebebebebebebebebe000000bebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebe000000bebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebebebebebebebebebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebe000000bebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebebebebebebebebebebe000000bebebebebebebebebe000000bebebebebebe
-bebebe000000bebebebebebe000000bebebebebebe000000000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebe000000
-bebebebebebebebebebebebebebebe000000bebebebebebebebebe000000bebebebebebe
-bebebe000000bebebebebebebebebe000000000000bebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000000000000000000000bebebebebebe000000
-000000000000000000000000bebebebebebe000000000000000000000000000000bebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebe000000000000000000bebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000000000000000
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebe000000bebebebebebebebebe
-bebebe000000bebebebebebebebebebebebebebebe000000000000000000bebebebebebe
-bebebebebebe000000000000000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebe000000000000bebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebebebebebebebe000000bebebe
-bebebe000000bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebebebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe000000000000
-000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebe000000bebebe000000bebebebebebe000000
-bebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebebebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebe000000bebebebebebe
-bebebe000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebe000000bebebebebebe000000bebebebebebebebebe
-bebebe000000bebebebebebebebebebebebebebebebebebebebebebebebe000000bebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000000000bebebe
-bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe
-bebebe000000bebebebebebebebebebebebebebebebebebebebebe000000bebebebebebe
-bebebebebebebebebe000000000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebebebebe
-bebebebebebebebebe000000bebebe000000bebebebebebebebebebebebe000000000000
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000bebebebebebebebebe000000bebebebebebebebebe
-bebebe000000bebebebebebebebebebebebebebebebebebe000000bebebebebebebebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebebebebe
-bebebebebebebebebe000000bebebe000000bebebebebebebebebe000000bebebebebebe
-bebebe000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebe000000000000000000000000000000000000bebebebebebe
-bebebe000000bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebe
-bebebebebebebebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000bebebebebebebebebebebebe
-bebebebebebebebebebebebe000000bebebebebebebebebebebebe000000bebebebebebe
-bebebe000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebe000000bebebebebebebebebe
-bebebe000000bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe
-bebebe000000bebebebebebebebebe000000bebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebe000000000000000000000000000000
-bebebebebebebebebebebebe000000bebebebebebebebebebebebebebebe000000000000
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebe000000bebebebebebe000000
-000000000000000000000000bebebebebebe000000000000000000000000000000bebebe
-bebebebebebe000000000000000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3ffffff828282828282828282c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3ffffff828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000bebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-000000000000bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe
-bebebe000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffc3c3c3ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffc3c3c3ffffffffffffc3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff828282c3c3c3ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffff828282c3c3c3ffffffffffffffffffffffffc3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffffffff828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffffffffffffffffffff
-ffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3ffffffffffffffffffffffffd9d9d9828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9ffffff
-ffffffffffffffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff
-ffffffffffffffffffd9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffffffffffffffc3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffc3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3ffffffffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffc3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282828282828282828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3828282828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282828282c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3828282828282828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282828282828282c3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282
-828282828282828282d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9828282828282828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3828282828282828282828282d9d9d9828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffffd9d9d9d9d9d9828282
-828282828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3828282828282828282828282828282c3c3c3ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3ffffffffffff828282828282828282
-828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282828282828282c3c3c3ffffffffffff828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282c3c3c3ffffffffffff828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282c3c3c3ffffff828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282c3c3c3ffffff828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282ffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/ex13.gif b/lib/gs/doc/src/images/ex13.gif
deleted file mode 100644
index 3b323d6fd4..0000000000
--- a/lib/gs/doc/src/images/ex13.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/ex13.ps b/lib/gs/doc/src/images/ex13.ps
deleted file mode 100644
index 1955c73470..0000000000
--- a/lib/gs/doc/src/images/ex13.ps
+++ /dev/null
@@ -1,2369 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/ex13.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 334 411 460
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 630 string def
-
-% define space for color conversions
-/grays 210 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 334 translate
-
-% size of image (on paper, in 1/72inch coords)
-210.02400 126.00000 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-210 126 8 % dimensions of data
-[210 0 0 -126 0 126] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff000000000080000080ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080ffffff000080ffffffffffffffffff000080ffffffffffffffffff
-000080000080000080ffffffffffffffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080ffffffffffffffffff
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffffffffffffffffffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080000080000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080ffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080000080ffffffffffffffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffff737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-000000ffffff737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373000000000080000080ffffff737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000080000080000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffff828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffff828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffff828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d98e8e8e8e8e8ed9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d98e8e8e8e8e8e8e8e8e
-8e8e8ed9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffecececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d98e8e8e8e8e8e8e8e8e
-8e8e8e8e8e8ed9d9d9d9d9d9d9d9d9ffffffffffffffffffecececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d98e8e8e8e8e8eececec
-ececec8e8e8e8e8e8e8e8e8ed9d9d9ffffffffffffffffffecececececececececececec
-ecececececececececececec828282828282ecececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d98e8e8e8e8e8eececec
-ececececececffffffffffffffffffffffffffffffffffffecececececececececececec
-ececececececececec828282828282828282828282ececececececececececececececec
-ececececececececec000000000000000000000000ececececececececececececececec
-ececececececececececececececececececececececececececec000000ecececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d98e8e8e8e8e8eececec
-ecececffffffffffffffffffd9d9d9ffffffffffffffffffecececececececececececec
-ecececececec828282828282828282828282828282828282ecececececececececececec
-ececececececececec000000ececececececececec000000ecececececececececececec
-ececececececececececececececececececececececececececec000000ecececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d98e8e8e8e8e8effffff
-ffffffffffffd9d9d9d9d9d9d9d9d9ffffffffffffffffffecececececececececececec
-ececec828282828282828282b03060b03060828282828282828282ececececececececec
-ececececececececec000000ececececececececec000000ececececececececec000000
-000000000000ecececececececececececec000000000000ececec000000ecececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d98e8e8e8e8e8effffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffecececececececececececec
-828282828282828282b03060b03060b03060b03060828282828282828282ecececececec
-ececececececececec000000ececececececececec000000ecececececec000000ececec
-ecececececec000000ecececececec000000ecececececec000000000000ecececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d98e8e8effffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffececececececececec828282
-828282828282b03060b03060b03060b03060b03060b03060828282828282828282ececec
-ececececececececec000000000000000000000000ececececececececec000000ececec
-ecececececec000000ecececececec000000ececececececececec000000ecececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffececececececffffffffffff
-ffffffb03060b03060b03060b03060b03060b03060b03060b03060ffffffffffffffffff
-ececececececececec000000ecececececec000000ececececececececec000000000000
-000000000000000000ecececececec000000ececececececececec000000ecececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffecececececececececffffff
-ffffffffffffb03060b03060b03060b03060b03060b03060ffffffffffffffffffececec
-ececececececececec000000ececececececececec000000ecececececec000000ececec
-ececececececececececececececec000000ececececececececec000000ecececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffecececececececececececec
-ffffffffffffffffffb03060b03060b03060b03060ffffffffffffffffffecececececec
-ececececececececec000000ececececececececec000000ecececececec000000ececec
-ecececececec000000ecececececec000000ecececececec000000000000ecececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffecececececececececececec
-ecececffffffffffffffffffb03060b03060ffffffffffffffffffececececececececec
-ececececececececec000000ececececececececec000000ececececececececec000000
-000000000000ecececececececececececec000000000000ececec000000ecececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282ffffffffffffffffffecececececececececececec
-ececececececffffffffffffffffffffffffffffffffffffecececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282ffffffffffffffffffecececececececececececec
-ecececececececececffffffffffffffffffffffffececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffecececececececececececec
-ececececececececececececffffffffffffecececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffecececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ecececececececececececececececececececececececececececececececececececec
-ececececececececec8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff8e8e8e8e8e8e8e8e8e8e8e8e
-8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e
-8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e
-8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e
-8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e
-8e8e8e8e8e8e8e8e8e8e8e8e828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282828282d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9828282
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9ffffffffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffff
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffffffffd9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282828282d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9828282
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9ffffffffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffff
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffffffffd9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffffffffff828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ffffff828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/ex14.gif b/lib/gs/doc/src/images/ex14.gif
deleted file mode 100644
index d52e06be06..0000000000
--- a/lib/gs/doc/src/images/ex14.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/ex14.ps b/lib/gs/doc/src/images/ex14.ps
deleted file mode 100644
index 5a215f803a..0000000000
--- a/lib/gs/doc/src/images/ex14.ps
+++ /dev/null
@@ -1,11546 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/ex14.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 132 611 459
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 1230 string def
-
-% define space for color conversions
-/grays 410 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 132 translate
-
-% size of image (on paper, in 1/72inch coords)
-409.96800 327.02400 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-410 327 8 % dimensions of data
-[410 0 0 -327 0 327] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000000080000080ffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffff000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080ffffffffffff000080000080000080000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffff000080000080000080ffffff
-ffffff000080ffffffffffff000080ffffffffffff000080ffffffffffffffffffffffff
-000080000080ffffffffffffffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080ffffffffffff
-000080ffffffffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffffffffffffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080ffffffffffffffffffffffffffffffffffff000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080ffffffffffff
-000080ffffffffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000
-000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffff000080000080000080ffffff
-ffffff000080ffffffffffff000080ffffffffffff000080000080000080ffffffffffff
-000080000080ffffffffffffffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000
-000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffff737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373000000ffffff737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-000000000080000080ffffff737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000080000080000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffff828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282828282828282828282828282828282828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282828282828282828282828282828282828282828282ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282b03060b03060b03060b03060b03060b03060b03060ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282b03060b03060b03060b03060b03060b03060b03060ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282b03060b03060b03060b03060b03060b03060b03060ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282b03060b03060b03060b03060b03060b03060b03060ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282b03060b03060b03060b03060b03060b03060b03060ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282b03060b03060b03060b03060b03060b03060b03060ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282b03060b03060b03060b03060b03060b03060b03060ffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282ffffffffffffffffffffffffffffffffffffffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffff828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffff828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffff828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282ffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff828282c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffff828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffff828282828282828282828282828282828282828282828282828282828282
-828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffff828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffff828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffff828282828282828282828282828282828282828282828282828282828282
-828282828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffff828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffff828282ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9828282828282
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9828282828282c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff828282828282828282c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3ffffff828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282828282ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282828282c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000828282ffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000000000828282828282
-c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3828282c3c3c3c3c3c3c3c3c3c3c3c3
-c3c3c3c3c3c3c3c3c3ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000828282828282
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000828282ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/ex15.gif b/lib/gs/doc/src/images/ex15.gif
deleted file mode 100644
index 06753cd77b..0000000000
--- a/lib/gs/doc/src/images/ex15.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/ex15.ps b/lib/gs/doc/src/images/ex15.ps
deleted file mode 100644
index 7c757e3ba4..0000000000
--- a/lib/gs/doc/src/images/ex15.ps
+++ /dev/null
@@ -1,9796 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/ex15.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 101 257 511 534
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 1230 string def
-
-% define space for color conversions
-/grays 410 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-101 257 translate
-
-% size of image (on paper, in 1/72inch coords)
-409.96800 276.98400 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-410 277 8 % dimensions of data
-[410 0 0 -277 0 277] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000000080000080ffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffff000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080000080000080000080000080ffffffffffff
-ffffffffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080000080000080000080000080ffffffffffff
-000080000080ffffffffffff000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffffffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-ffffffffffffffffffffffff000080000080000080000080000080000080ffffffffffff
-000080000080000080ffffffffffff000080000080ffffffffffffffffffffffff000080
-000080ffffff000080ffffffffffffffffff000080ffffffffffffffffff000080000080
-000080ffffffffffffffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080000080000080000080000080000080000080ffffffffffff
-000080000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffff000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080000080000080000080000080000080000080ffffffffffff
-000080000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080000080000080000080000080000080000080ffffffffffff
-000080000080000080ffffffffffff000080ffffffffffffffffffffffffffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080000080000080000080000080000080000080ffffffffffff
-000080000080000080ffffffffffff000080ffffffffffff000080000080000080000080
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffff000080000080000080000080000080ffffffffffff
-000080000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000
-000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffffffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-000080000080ffffffffffff000080000080000080000080000080000080ffffffffffff
-ffffffffffffffffff000080000080000080000080ffffffffffffffffffffffff000080
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffffffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000
-000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffff737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373000000ffffff737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-000000000080000080ffffff737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000080000080000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000d9d9d9
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000
-000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000000000000000000000
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000d9d9d9
-000000000000000000000000000000000000d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000d9d9d9000000
-000000000000000000d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-000000d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9000000000000000000000000000000000000000000
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9000000000000000000000000000000000000000000
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000d9d9d9000000
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000
-000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000d9d9d9000000
-000000000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000d9d9d9000000
-000000000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000000000
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9000000000000000000d9d9d9000000000000000000000000d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000d9d9d9000000
-000000000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9000000000000000000000000000000000000000000000000000000
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000d9d9d9000000
-000000000000d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9000000000000000000000000000000000000000000000000000000
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000d9d9d9000000
-000000000000d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000d9d9d9000000
-000000000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000000000
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9000000000000000000d9d9d9000000000000000000000000d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000d9d9d9000000
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9d9d9d9000000
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000
-000000d9d9d9000000000000000000d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9000000000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000d9d9d9d9d9d9000000000000000000000000000000000000d9d9d9000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000d9d9d9000000000000000000000000000000000000
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9000000000000d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000
-d9d9d9000000000000000000000000d9d9d9000000000000d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000d9d9d9
-000000000000000000000000d9d9d9d9d9d9000000000000d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9000000000000000000d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9000000000000000000000000d9d9d9000000000000000000
-d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000000000000000000000d9d9d9000000000000000000d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000d9d9d9d9d9d9000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000d9d9d9000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9000000000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9000000000000000000d9d9d9000000000000000000000000000000000000000000
-d9d9d9000000000000000000000000000000000000d9d9d9d9d9d9000000000000000000
-d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9000000000000000000d9d9d9000000000000000000d9d9d9000000000000000000
-000000000000000000000000d9d9d9000000000000000000d9d9d9000000000000000000
-d9d9d9000000000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/ex16.gif b/lib/gs/doc/src/images/ex16.gif
deleted file mode 100644
index 1c12160dd0..0000000000
--- a/lib/gs/doc/src/images/ex16.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/ex16.ps b/lib/gs/doc/src/images/ex16.ps
deleted file mode 100644
index a3ad9b907a..0000000000
--- a/lib/gs/doc/src/images/ex16.ps
+++ /dev/null
@@ -1,4187 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/ex16.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 101 307 311 534
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 630 string def
-
-% define space for color conversions
-/grays 210 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-101 307 translate
-
-% size of image (on paper, in 1/72inch coords)
-210.02400 227.01600 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-210 227 8 % dimensions of data
-[210 0 0 -227 0 227] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff000000000080000080ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080ffffffffffffffffffffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-000080ffffffffffffffffffffffff000080000080ffffffffffffffffffffffff000080
-000080ffffffffffffffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080ffffffffffffffffffffffff000080000080000080
-000080000080000080ffffffffffff000080000080000080ffffffffffff000080000080
-ffffffffffffffffffffffff000080000080ffffff000080ffffffffffffffffff000080
-ffffffffffffffffff000080000080000080ffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080ffffffffffff000080000080000080ffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080ffffffffffff000080000080000080ffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffffffffffffffffffffffffffff000080000080ffffffffffff000080000080
-000080ffffffffffffffffffffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080ffffffffffff000080000080000080ffffffffffff000080ffffff
-ffffffffffffffffffffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080000080000080000080000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080ffffffffffff000080000080000080ffffffffffff000080ffffff
-ffffff000080000080000080000080000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080ffffffffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080ffffff000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffffffffff000080000080000080
-000080ffffffffffffffffffffffff000080000080000080ffffffffffff000080000080
-000080ffffffffffffffffff000080ffffffffffff000080ffffffffffff000080ffffff
-ffffff000080ffffffffffff000080000080000080ffffffffffff000080000080000080
-000080000080000080ffffffffffffffffffffffffffffff000080000080000080000080
-ffffffffffffffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080000080ffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffff737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-000000ffffff737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373000000000080000080ffffff737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000080000080000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000000000000000
-000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000000000000000ff0000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-000000000000000000000000000000000000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000000000ff0000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff000000000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000ff0000000000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff000000000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff00000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff00000000ff0000ffff0000ff000000000000ff000000ff0000ff000000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff00000000ff0000ffff0000ff000000000000ff000000ff0000ff00ff00
-000000ff0000ff0000ff00000000ff0000ff0000ff0000ffff0000ff0000ff00000000ff
-0000ff0000ff0000ffff0000ff0000ff00000000ff0000ff0000ff00000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff00000000ff0000ffff0000ff000000000000ff000000ff0000ff00ff00
-00ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffff00000000ff
-0000ff0000ff0000ffff0000ff0000ff00000000ff0000ff00000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff00ff0000ff00
-00ff000000ff0000ff0000ffff0000ff0000ff0000ff00000000ff0000ff0000ffff0000
-0000ff0000ffff0000ff00000000ff0000ffff00000000ff00000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff00ff0000ff0000ff00
-00ff000000ff0000ff000000ff0000ff0000ff0000ff0000ff00000000ff0000ffff0000
-0000ff0000ffff00000000ff0000ff0000ffff00000000ff00000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff00000000ff0000ffff0000ff000000000000ff0000ff0000ff0000ff00
-00ff000000ff0000ff000000ff0000ff0000ff0000ff0000ff00000000ff0000ffff0000
-ff00000000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000000000ff0000ff0000ff00000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff00000000ff0000ffff0000ff000000000000ff0000ff0000ff0000ff00
-00ff000000ff0000ff00ff00000000ff0000ff0000ff0000ff00000000ff0000ffff0000
-ff00000000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff00000000ff0000ffff0000ff000000000000ff0000ff0000ff0000ff00
-00ff000000ff0000ff0000ff000000ff0000ff0000ff00000000ff0000ff0000ffff0000
-ff00000000ff0000ff0000ffff00000000ff0000ff00000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff00ff0000ff0000ff0000ff00
-00ff0000ff000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffff0000ff0000
-ff00000000ff0000ff0000ffff00000000ff0000ff00000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff00ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff000000ff0000ff0000ff0000ffff0000ff0000ff0000ff0000
-ff0000ff00000000ff0000ffff0000ff00000000ff00000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff000000ff0000ff00ff00000000ff0000ff00000000ff0000ffff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff000000ff0000ff00ff00000000ff0000ff00000000ff0000ffff0000
-ff0000ff0000ff0000ff00000000ff0000ff0000ff00000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d900000000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000000000000000000000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000000000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff000000ff0000ff00ff00000000ff0000ff00000000ff0000ffff0000
-ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-000000d9d9d9d9d9d900000000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff000000ff0000ff0000ff0000ff0000ff0000ff0000ffff0000ff0000
-ff00000000ff0000ff0000ffff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-000000d9d9d900000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff000000ff0000ff0000ff0000ff0000ff0000ffff0000ff0000ff0000
-ff00000000ff0000ffff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff000000ff0000ff00ff00000000ff0000ff0000ff0000ff0000ff0000
-ff00000000ff0000ffff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-d9d9d900000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff000000ff0000ff00ff00000000ff0000ff0000ff0000ff0000ff0000
-ff00000000ff0000ffff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff000000ff0000ff000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff00000000ff0000ff0000ffff0000ff0000ff0000ff00000000ff0000ff00000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff000000ff0000ff0000ff0000ff0000ff0000ff0000ffff0000ff0000ff0000ff0000
-ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff000000ff0000ff0000ff0000ff0000ff0000ff0000ffff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ffff0000ff0000ff0000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000000000000000000000000000000000000000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000000000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000000000ff0000ff0000ff0000ff00000000000000ff0000ff0000
-00000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-000000ff0000ff000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000000000ff0000ff0000ff000000000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-000000000000ff0000ff000000000000000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000000000000000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000ff0000ff0000ff0000ff0000ff0000000000000000000000000000000000
-000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff000000000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff000000000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff000000000000000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000000000
-000000000000000000000000000000000000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff000000000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff00000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00000000
-000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000000000000000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff
-0000ffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff
-0000ffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d900000000000000000000000000000000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000000000000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d900000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff
-0000ffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-00000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff
-0000ffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d900000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d900000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-00000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-00000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d900000000000000ff0000ff0000ff0000ff00000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d900000000000000ff0000ff00000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000000000000000000000000000000000000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000000000ff0000ff0000ff0000ff0000ff0000ff00000000000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000000000d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff00
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000ff0000ff00000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000000000000000000000000ff00000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000000000d9d9d900000000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff00000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-00000000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-00000000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff000000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff000000000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff000000000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000ff
-0000ff0000ff0000ff0000ff0000ff0000ff0000ff00ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000ff
-0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000000000000000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff000000ff0000ff00ff0000ff0000ff0000ff000000ff0000ff00ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff000000ff0000ff00ff0000ff0000ff0000ff000000ff0000ff00ff0000ff0000ff00
-00ff0000ff000000ff0000ff0000ff0000ff00ff0000ff0000ff000000ff00000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d900000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff000000ff0000ff00ff0000ff0000ff0000ff000000ff0000ff00ff0000ff0000ff00
-0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00ff000000ff0000ff000000
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d900000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff000000ff0000ff0000ff0000ff0000ff0000ff0000ff00ff0000ff0000ff000000ff
-0000ff0000ff00ff0000ff0000ff0000ff000000ff0000ff0000ff00ff000000ff000000
-00000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d900000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff000000ff0000ff0000ff0000ff0000ff0000ff00ff0000ff0000ff0000ff000000ff
-0000ff00ff0000ff0000ff0000ff0000ff0000ff000000ff0000ff00ff000000ff0000ff
-00ff0000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-0000000000ff00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000000000ff0000ff0000ff0000ff0000ff00
-00ff000000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000ff
-0000ff00ff0000ff0000ff0000ff0000ff0000ff000000ff0000ff00ff0000ff000000ff
-0000ff0000ff00000000000000ff0000ff0000ff0000ff0000ff0000ff00000000000000
-0000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000000000ff0000ff0000ff00
-00ff000000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000ff
-0000ff00ff0000ff0000ff0000ff0000ff0000ff000000ff0000ff00ff0000ff000000ff
-0000ff0000ff0000ff0000ff00000000000000000000000000000000000000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000000000ff0000ff00
-00ff000000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff000000ff
-0000ff0000ff00ff0000ff0000ff0000ff000000ff0000ff0000ff00ff0000ff000000ff
-0000ff0000ff00ff000000ff0000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff00
-0000ff0000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d90000000000ff
-0000ff0000ff0000ff0000ff0000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff00
-0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00ff0000ff0000ff000000ff
-0000ff0000ff00ff000000ff0000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff00
-0000ff0000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d90000ff
-0000ff0000ff0000ff0000ff0000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff000000ff0000ff0000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff00
-0000ff0000ff00ff0000ff000000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff00
-0000ff0000ff0000ff00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d900000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff00000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000000000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff00000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d90000ff0000ff
-0000ffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d900000000000000000000000000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d90000ff0000ff0000ff
-0000ff0000ff0000ff0000ff0000ffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d90000ff0000ff
-0000ffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff00000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d90000ff0000ff0000ff
-0000ff0000ff0000ff0000ff0000ff0000ffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d90000ff0000ff
-0000ffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d900000000000000000000000000000000000000ff0000ff0000ff0000ff00
-00ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff00
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d90000ff
-0000ffd9d9d9d9d9d9d9d9d9d9d9d90000ff0000ffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d90000ff0000ff
-0000ffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d90000ff
-0000ffd9d9d9d9d9d9d9d9d9d9d9d90000ff0000ffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-0000ff0000ff0000ff0000ffd9d9d9d9d9d9d9d9d90000ff0000ff0000ff0000ffd9d9d9
-d9d9d9d9d9d90000ff0000ff0000ff0000ffd9d9d9d9d9d9d9d9d9d9d9d90000ff0000ff
-0000ffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/ex8.gif b/lib/gs/doc/src/images/ex8.gif
deleted file mode 100644
index a79c488216..0000000000
--- a/lib/gs/doc/src/images/ex8.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/ex8.ps b/lib/gs/doc/src/images/ex8.ps
deleted file mode 100644
index f1138530ac..0000000000
--- a/lib/gs/doc/src/images/ex8.ps
+++ /dev/null
@@ -1,6003 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/ex8.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 232 511 459
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 930 string def
-
-% define space for color conversions
-/grays 310 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 232 translate
-
-% size of image (on paper, in 1/72inch coords)
-310.03200 227.01600 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-310 227 8 % dimensions of data
-[310 0 0 -227 0 227] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000000080000080ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffff000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffffffffffffffffffff000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000
-000000000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000
-000000000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080ffffffffffff000080ffffffffffff
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080ffffffffffff000080ffffffffffff
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080ffffffffffff000080ffffffffffff
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080ffffffffffffffffffffffff000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000
-000000000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffff737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373000000ffffff737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373000000000080000080ffffff
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000080000080000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffffffffd9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282828282d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffffffffd9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282828282d9d9d9d9d9d9828282828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9828282828282828282828282828282828282d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9828282828282828282b03060b03060828282828282828282d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-828282828282828282b03060b03060b03060b03060828282828282828282d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282828282b03060b03060b03060b03060b03060b03060828282828282828282d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff
-ffffffb03060b03060b03060b03060b03060b03060b03060b03060ffffffffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-ffffffffffffb03060b03060b03060b03060b03060b03060ffffffffffffffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffffffffffffffb03060b03060b03060b03060ffffffffffffffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffffffffb03060b03060ffffffffffffffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/ex9.gif b/lib/gs/doc/src/images/ex9.gif
deleted file mode 100644
index 948d3b7092..0000000000
--- a/lib/gs/doc/src/images/ex9.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/ex9.ps b/lib/gs/doc/src/images/ex9.ps
deleted file mode 100644
index e15d03e02f..0000000000
--- a/lib/gs/doc/src/images/ex9.ps
+++ /dev/null
@@ -1,1879 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/ex9.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 332 361 459
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 480 string def
-
-% define space for color conversions
-/grays 160 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 332 translate
-
-% size of image (on paper, in 1/72inch coords)
-159.98400 127.00800 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-160 127 8 % dimensions of data
-[160 0 0 -127 0 127] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffff000000000080000080ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffffffffffffffff000080ffffff
-ffffff000080ffffffffffffffffffffffff000080000080000080ffffffffffff000080
-000080000080000080000080000080ffffffffffff000080000080000080ffffffffffff
-000080000080ffffffffffffffffffffffff000080000080ffffff000080ffffffffffff
-ffffff000080ffffffffffffffffff000080000080000080ffffffffffffffffffffffff
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffffffffffffffffffffffffffffffffff000080000080000080ffffffffffff000080
-000080000080000080000080000080ffffffffffff000080000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffffffffff000080000080000080ffffffffffff000080ffffffffffff000080000080
-000080000080000080000080000080ffffffffffff000080000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080ffffffffffff000080ffffffffffff000080000080
-000080000080000080000080000080ffffffffffff000080000080000080ffffffffffff
-000080ffffffffffffffffffffffffffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080ffffffffffffffffff000080000080000080
-000080000080000080000080000080ffffffffffff000080000080000080ffffffffffff
-000080ffffffffffff000080000080000080000080000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080000080ffffffffffff000080ffffffffffff
-ffffff000080000080000080000080000080ffffffffffffffffff000080000080000080
-000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080000080000080ffffffffffff000080ffffff
-ffffff000080000080000080000080000080000080ffffffffffff000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffffffffff000080000080
-000080000080ffffffffffffffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffffffffffffffff
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffff737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373000000ffffff
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373000000000080000080ffffff737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffffffff000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000080000080000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282ffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282828282ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000828282ffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffffffff828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffffffffff828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffff828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ffffff828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282828282828282828282828282828282828282828282828282828282828282828282
-828282d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/gs1-1-image-1.gif b/lib/gs/doc/src/images/gs1-1-image-1.gif
deleted file mode 100644
index ad8c877b8a..0000000000
--- a/lib/gs/doc/src/images/gs1-1-image-1.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/gs1-1-image-1.ps b/lib/gs/doc/src/images/gs1-1-image-1.ps
deleted file mode 100644
index 64de86f70a..0000000000
--- a/lib/gs/doc/src/images/gs1-1-image-1.ps
+++ /dev/null
@@ -1,171 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: gs_fig1.fig
-%%Creator: fig2dev Version 3.1 Patchlevel 2
-%%CreationDate: Wed Nov 20 21:06:25 1996
-%%For: hans@skeppet (Hans Nilsson,EUA/SU)
-%Magnification: 1.00
-%%Orientation: Portrait
-%%BoundingBox: 0 0 328 210
-%%Pages: 0
-%%BeginSetup
-%%IncludeFeature: *PageSize A4
-%%EndSetup
-%%EndComments
-/$F2psDict 200 dict def
-$F2psDict begin
-$F2psDict /mtrx matrix put
-/col-1 {0 setgray} bind def
-/col0 {0.000 0.000 0.000 srgb} bind def
-/col1 {0.000 0.000 1.000 srgb} bind def
-/col2 {0.000 1.000 0.000 srgb} bind def
-/col3 {0.000 1.000 1.000 srgb} bind def
-/col4 {1.000 0.000 0.000 srgb} bind def
-/col5 {1.000 0.000 1.000 srgb} bind def
-/col6 {1.000 1.000 0.000 srgb} bind def
-/col7 {1.000 1.000 1.000 srgb} bind def
-/col8 {0.000 0.000 0.560 srgb} bind def
-/col9 {0.000 0.000 0.690 srgb} bind def
-/col10 {0.000 0.000 0.820 srgb} bind def
-/col11 {0.530 0.810 1.000 srgb} bind def
-/col12 {0.000 0.560 0.000 srgb} bind def
-/col13 {0.000 0.690 0.000 srgb} bind def
-/col14 {0.000 0.820 0.000 srgb} bind def
-/col15 {0.000 0.560 0.560 srgb} bind def
-/col16 {0.000 0.690 0.690 srgb} bind def
-/col17 {0.000 0.820 0.820 srgb} bind def
-/col18 {0.560 0.000 0.000 srgb} bind def
-/col19 {0.690 0.000 0.000 srgb} bind def
-/col20 {0.820 0.000 0.000 srgb} bind def
-/col21 {0.560 0.000 0.560 srgb} bind def
-/col22 {0.690 0.000 0.690 srgb} bind def
-/col23 {0.820 0.000 0.820 srgb} bind def
-/col24 {0.500 0.190 0.000 srgb} bind def
-/col25 {0.630 0.250 0.000 srgb} bind def
-/col26 {0.750 0.380 0.000 srgb} bind def
-/col27 {1.000 0.500 0.500 srgb} bind def
-/col28 {1.000 0.630 0.630 srgb} bind def
-/col29 {1.000 0.750 0.750 srgb} bind def
-/col30 {1.000 0.880 0.880 srgb} bind def
-/col31 {1.000 0.840 0.000 srgb} bind def
-
-end
-save
--88.0 308.0 translate
-1 -1 scale
-
-/cp {closepath} bind def
-/ef {eofill} bind def
-/gr {grestore} bind def
-/gs {gsave} bind def
-/sa {save} bind def
-/rs {restore} bind def
-/l {lineto} bind def
-/m {moveto} bind def
-/rm {rmoveto} bind def
-/n {newpath} bind def
-/s {stroke} bind def
-/sh {show} bind def
-/slc {setlinecap} bind def
-/slj {setlinejoin} bind def
-/slw {setlinewidth} bind def
-/srgb {setrgbcolor} bind def
-/rot {rotate} bind def
-/sc {scale} bind def
-/sd {setdash} bind def
-/ff {findfont} bind def
-/sf {setfont} bind def
-/scf {scalefont} bind def
-/sw {stringwidth} bind def
-/tr {translate} bind def
-/tnt {dup dup currentrgbcolor
- 4 -2 roll dup 1 exch sub 3 -1 roll mul add
- 4 -2 roll dup 1 exch sub 3 -1 roll mul add
- 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
- bind def
-/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
- 4 -2 roll mul srgb} bind def
- /DrawEllipse {
- /endangle exch def
- /startangle exch def
- /yrad exch def
- /xrad exch def
- /y exch def
- /x exch def
- /savematrix mtrx currentmatrix def
- x y tr xrad yrad sc 0 0 1 startangle endangle arc
- closepath
- savematrix setmatrix
- } def
-
-/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
-/$F2psEnd {$F2psEnteredState restore end} def
-%%EndProlog
-
-$F2psBegin
-10 setmiterlimit
-n 0 842 m 0 0 l 595 0 l 595 842 l cp clip
- 0.06000 0.06000 sc
-7.500 slw
-% Ellipse
-n 6000 2025 900 375 0 360 DrawEllipse gs col-1 s gr
-
-/Helvetica ff 210.00 scf sf
-5400 2100 m
-gs 1 -1 sc (GUI Builder) col-1 sh gr
-% Ellipse
-n 2550 2025 1050 375 0 360 DrawEllipse gs col-1 s gr
-
-/Helvetica ff 210.00 scf sf
-1800 2100 m
-gs 1 -1 sc (GUI Applications) col-1 sh gr
-% Polyline
-gs clippath
-3484 2904 m 3576 2987 l 3456 2957 l 3599 3034 l 3627 2981 l cp clip
-n 2475 2400 m 3600 3000 l gs col-1 s gr gr
-
-% arrowhead
-n 3484 2904 m 3576 2987 l 3456 2957 l 3470 2931 l 3484 2904 l cp gs 0.00 setgray ef gr col-1 s
-% Polyline
-gs clippath
-5239 2943 m 5122 2985 l 5206 2893 l 5071 2983 l 5104 3033 l cp clip
-n 6000 2400 m 5100 3000 l gs col-1 s gr gr
-
-% arrowhead
-n 5239 2943 m 5122 2985 l 5206 2893 l 5222 2918 l 5239 2943 l cp gs 0.00 setgray ef gr col-1 s
-30.000 slw
-% Polyline
-n 1500 3750 m 6900 3750 l gs col-1 s gr
-7.500 slw
-% Polyline
-n 6225 4500 m 6900 4500 l 6900 5100 l 6225 5100 l cp gs col-1 s gr
-% Polyline
-n 5100 4500 m 5775 4500 l 5775 5100 l 5100 5100 l cp gs col-1 s gr
-% Polyline
-n 3975 4500 m 4650 4500 l 4650 5100 l 3975 5100 l cp gs col-1 s gr
-% Polyline
-n 1575 4500 m 2250 4500 l 2250 5100 l 1575 5100 l cp gs col-1 s gr
-% Polyline
-n 2775 4500 m 3555 4500 l 3555 5115 l 2775 5115 l cp gs col-1 s gr
-/Helvetica ff 210.00 scf sf
-4350 3450 m
-gs 1 -1 sc (General Graphics Interface \(API\)) dup sw pop 2 div neg 0 rm col-1 sh gr
-/Helvetica ff 210.00 scf sf
-4350 4125 m
-gs 1 -1 sc (Possible backends to many systems and platforms) dup sw pop 2 div neg 0 rm col-1 sh gr
-/Helvetica ff 210.00 scf sf
-1680 4882 m
-gs 1 -1 sc (Motif) col-1 sh gr
-/Helvetica ff 210.00 scf sf
-2820 4905 m
-gs 1 -1 sc (Win3.2) col-1 sh gr
-/Helvetica ff 210.00 scf sf
-4095 4905 m
-gs 1 -1 sc (OS/2) col-1 sh gr
-/Helvetica ff 210.00 scf sf
-5115 4890 m
-gs 1 -1 sc (Tcl/Tk) col-1 sh gr
-/Helvetica ff 210.00 scf sf
-6330 4875 m
-gs 1 -1 sc (PXW) col-1 sh gr
-$F2psEnd
-rs
diff --git a/lib/gs/doc/src/images/gs1-1-image-2.gif b/lib/gs/doc/src/images/gs1-1-image-2.gif
deleted file mode 100644
index fc5829fc93..0000000000
--- a/lib/gs/doc/src/images/gs1-1-image-2.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/gs1-1-image-2.ps b/lib/gs/doc/src/images/gs1-1-image-2.ps
deleted file mode 100644
index 407eafe2d1..0000000000
--- a/lib/gs/doc/src/images/gs1-1-image-2.ps
+++ /dev/null
@@ -1,2832 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: Adobe Illustrator(r) 6.0
-%%For: (Anna Fedoriw) (Ericsson Telecom)
-%%Title: (Process_in_Erlang.eps)
-%%CreationDate: (97-05-22) (12.55)
-%%BoundingBox: 117 590 392 730
-%%HiResBoundingBox: 117.7663 590.1667 391.1347 729.3677
-%%DocumentProcessColors: Black
-%%DocumentFonts: Univers
-%%DocumentSuppliedResources: procset Adobe_level2_AI5 1.0 0
-%%+ procset Adobe_typography_AI5 1.0 0
-%%+ procset Adobe_Illustrator_AI6_vars Adobe_Illustrator_AI6
-%%+ procset Adobe_Illustrator_AI5 1.0 0
-%AI5_FileFormat 2.0
-%AI3_ColorUsage: Black&White
-%%AI6_ColorSeparationSet: 1 1 (AI6 Default Color Separation Set)
-%%+ Options: 1 16 0 1 0 1 1 1 0 1 1 1 1 18 0 0 0 0 0 0 0 0 -1 -1
-%%+ PPD: 1 21 0 0 60 45 2 2 1 0 0 1 0 0 0 0 0 0 0 0 0 0 ()
-%AI3_TemplateBox: 306 396 306 396
-%AI3_TileBox: 21 -12 588 802
-%AI3_DocumentPreview: Macintosh_ColorPic
-%AI5_ArtSize: 595.2756 841.8898
-%AI5_RulerUnits: 1
-%AI5_ArtFlags: 0 0 0 1 0 0 1 1 0
-%AI5_TargetResolution: 800
-%AI5_NumLayers: 1
-%AI5_OpenToView: -174 876 1 1058 826 58 1 1 2 40
-%AI5_OpenViewLayers: 7
-%%EndComments
-%%BeginProlog
-%%BeginResource: procset Adobe_level2_AI5 1.2 0
-%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation)
-%%Version: 1.2
-%%CreationDate: (04/10/93) ()
-%%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved)
-userdict /Adobe_level2_AI5 23 dict dup begin
- put
- /packedarray where not
- {
- userdict begin
- /packedarray
- {
- array astore readonly
- } bind def
- /setpacking /pop load def
- /currentpacking false def
- end
- 0
- } if
- pop
- userdict /defaultpacking currentpacking put true setpacking
- /initialize
- {
- Adobe_level2_AI5 begin
- } bind def
- /terminate
- {
- currentdict Adobe_level2_AI5 eq
- {
- end
- } if
- } bind def
- mark
- /setcustomcolor where not
- {
- /findcmykcustomcolor
- {
- 5 packedarray
- } bind def
- /setcustomcolor
- {
- exch aload pop pop
- 4
- {
- 4 index mul 4 1 roll
- } repeat
- 5 -1 roll pop
- setcmykcolor
- }
- def
- } if
-
- /gt38? mark {version cvr cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def
- userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put
- userdict /level2?
- systemdict /languagelevel known dup
- {
- pop systemdict /languagelevel get 2 ge
- } if
- put
-/level2ScreenFreq
-{
- begin
- 60
- HalftoneType 1 eq
- {
- pop Frequency
- } if
- HalftoneType 2 eq
- {
- pop GrayFrequency
- } if
- HalftoneType 5 eq
- {
- pop Default level2ScreenFreq
- } if
- end
-} bind def
-userdict /currentScreenFreq
- level2? {currenthalftone level2ScreenFreq} {currentscreen pop pop} ifelse put
-level2? not
- {
- /setcmykcolor where not
- {
- /setcmykcolor
- {
- exch .11 mul add exch .59 mul add exch .3 mul add
- 1 exch sub setgray
- } def
- } if
- /currentcmykcolor where not
- {
- /currentcmykcolor
- {
- 0 0 0 1 currentgray sub
- } def
- } if
- /setoverprint where not
- {
- /setoverprint /pop load def
- } if
- /selectfont where not
- {
- /selectfont
- {
- exch findfont exch
- dup type /arraytype eq
- {
- makefont
- }
- {
- scalefont
- } ifelse
- setfont
- } bind def
- } if
- /cshow where not
- {
- /cshow
- {
- [
- 0 0 5 -1 roll aload pop
- ] cvx bind forall
- } bind def
- } if
- } if
- cleartomark
- /anyColor?
- {
- add add add 0 ne
- } bind def
- /testColor
- {
- gsave
- setcmykcolor currentcmykcolor
- grestore
- } bind def
- /testCMYKColorThrough
- {
- testColor anyColor?
- } bind def
- userdict /composite?
- level2?
- {
- gsave 1 1 1 1 setcmykcolor currentcmykcolor grestore
- add add add 4 eq
- }
- {
- 1 0 0 0 testCMYKColorThrough
- 0 1 0 0 testCMYKColorThrough
- 0 0 1 0 testCMYKColorThrough
- 0 0 0 1 testCMYKColorThrough
- and and and
- } ifelse
- put
- composite? not
- {
- userdict begin
- gsave
- /cyan? 1 0 0 0 testCMYKColorThrough def
- /magenta? 0 1 0 0 testCMYKColorThrough def
- /yellow? 0 0 1 0 testCMYKColorThrough def
- /black? 0 0 0 1 testCMYKColorThrough def
- grestore
- /isCMYKSep? cyan? magenta? yellow? black? or or or def
- /customColor? isCMYKSep? not def
- end
- } if
- end defaultpacking setpacking
-%%EndResource
-%%BeginResource: procset Adobe_typography_AI5 1.0 1
-%%Title: (Typography Operators)
-%%Version: 1.0
-%%CreationDate:(03/26/93) ()
-%%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved)
-currentpacking true setpacking
-userdict /Adobe_typography_AI5 54 dict dup begin
-put
-/initialize
-{
- begin
- begin
- Adobe_typography_AI5 begin
- Adobe_typography_AI5
- {
- dup xcheck
- {
- bind
- } if
- pop pop
- } forall
- end
- end
- end
- Adobe_typography_AI5 begin
-} def
-/terminate
-{
- currentdict Adobe_typography_AI5 eq
- {
- end
- } if
-} def
-/modifyEncoding
-{
- /_tempEncode exch ddef
- /_pntr 0 ddef
- {
- counttomark -1 roll
- dup type dup /marktype eq
- {
- pop pop exit
- }
- {
- /nametype eq
- {
- _tempEncode /_pntr dup load dup 3 1 roll 1 add ddef 3 -1 roll
- put
- }
- {
- /_pntr exch ddef
- } ifelse
- } ifelse
- } loop
- _tempEncode
-} def
-/TE
-{
- StandardEncoding 256 array copy modifyEncoding
- /_nativeEncoding exch def
-} def
-%
-/TZ
-{
- dup type /arraytype eq
- {
- /_wv exch def
- }
- {
- /_wv 0 def
- } ifelse
- /_useNativeEncoding exch def
- pop pop
- findfont _wv type /arraytype eq
- {
- _wv makeblendedfont
- } if
- dup length 2 add dict
- begin
- mark exch
- {
- 1 index /FID ne
- {
- def
- } if
- cleartomark mark
- } forall
- pop
- /FontName exch def
- counttomark 0 eq
- {
- 1 _useNativeEncoding eq
- {
- /Encoding _nativeEncoding def
- } if
- cleartomark
- }
- {
- /Encoding load 256 array copy
- modifyEncoding /Encoding exch def
- } ifelse
- FontName currentdict
- end
- definefont pop
-} def
-/tr
-{
- _ax _ay 3 2 roll
-} def
-/trj
-{
- _cx _cy _sp _ax _ay 6 5 roll
-} def
-/a0
-{
- /Tx
- {
- dup
- currentpoint 3 2 roll
- tr _psf
- newpath moveto
- tr _ctm _pss
- } ddef
- /Tj
- {
- dup
- currentpoint 3 2 roll
- trj _pjsf
- newpath moveto
- trj _ctm _pjss
- } ddef
-} def
-/a1
-{
- /Tx
- {
- dup currentpoint 4 2 roll gsave
- dup currentpoint 3 2 roll
- tr _psf
- newpath moveto
- tr _ctm _pss
- grestore 3 1 roll moveto tr sp
- } ddef
- /Tj
- {
- dup currentpoint 4 2 roll gsave
- dup currentpoint 3 2 roll
- trj _pjsf
- newpath moveto
- trj _ctm _pjss
- grestore 3 1 roll moveto tr jsp
- } ddef
-} def
-/e0
-{
- /Tx
- {
- tr _psf
- } ddef
- /Tj
- {
- trj _pjsf
- } ddef
-} def
-/e1
-{
- /Tx
- {
- dup currentpoint 4 2 roll gsave
- tr _psf
- grestore 3 1 roll moveto tr sp
- } ddef
- /Tj
- {
- dup currentpoint 4 2 roll gsave
- trj _pjsf
- grestore 3 1 roll moveto tr jsp
- } ddef
-} def
-/i0
-{
- /Tx
- {
- tr sp
- } ddef
- /Tj
- {
- trj jsp
- } ddef
-} def
-/i1
-{
- W N
-} def
-/o0
-{
- /Tx
- {
- tr sw rmoveto
- } ddef
- /Tj
- {
- trj swj rmoveto
- } ddef
-} def
-/r0
-{
- /Tx
- {
- tr _ctm _pss
- } ddef
- /Tj
- {
- trj _ctm _pjss
- } ddef
-} def
-/r1
-{
- /Tx
- {
- dup currentpoint 4 2 roll currentpoint gsave newpath moveto
- tr _ctm _pss
- grestore 3 1 roll moveto tr sp
- } ddef
- /Tj
- {
- dup currentpoint 4 2 roll currentpoint gsave newpath moveto
- trj _ctm _pjss
- grestore 3 1 roll moveto tr jsp
- } ddef
-} def
-/To
-{
- pop _ctm currentmatrix pop
-} def
-/TO
-{
- iTe _ctm setmatrix newpath
-} def
-/Tp
-{
- pop _tm astore pop _ctm setmatrix
- _tDict begin
- /W
- {
- } def
- /h
- {
- } def
-} def
-/TP
-{
- end
- iTm 0 0 moveto
-} def
-/Tr
-{
- _render 3 le
- {
- currentpoint newpath moveto
- } if
- dup 8 eq
- {
- pop 0
- }
- {
- dup 9 eq
- {
- pop 1
- } if
- } ifelse
- dup /_render exch ddef
- _renderStart exch get load exec
-} def
-/iTm
-{
- _ctm setmatrix _tm concat 0 _rise translate _hs 1 scale
-} def
-/Tm
-{
- _tm astore pop iTm 0 0 moveto
-} def
-/Td
-{
- _mtx translate _tm _tm concatmatrix pop iTm 0 0 moveto
-} def
-/iTe
-{
- _render -1 eq
- {
- }
- {
- _renderEnd _render get dup null ne
- {
- load exec
- }
- {
- pop
- } ifelse
- } ifelse
- /_render -1 ddef
-} def
-/Ta
-{
- pop
-} def
-/Tf
-{
- dup 1000 div /_fScl exch ddef
-%
- selectfont
-} def
-/Tl
-{
- pop
- 0 exch _leading astore pop
-} def
-/Tt
-{
- pop
-} def
-/TW
-{
- 3 npop
-} def
-/Tw
-{
- /_cx exch ddef
-} def
-/TC
-{
- 3 npop
-} def
-/Tc
-{
- /_ax exch ddef
-} def
-/Ts
-{
- /_rise exch ddef
- currentpoint
- iTm
- moveto
-} def
-/Ti
-{
- 3 npop
-} def
-/Tz
-{
- 100 div /_hs exch ddef
- iTm
-} def
-/TA
-{
- pop
-} def
-/Tq
-{
- pop
-} def
-/Th
-{
- pop pop pop pop pop
-} def
-/TX
-{
- pop
-} def
-/Tk
-{
- exch pop _fScl mul neg 0 rmoveto
-} def
-/TK
-{
- 2 npop
-} def
-/T*
-{
- _leading aload pop neg Td
-} def
-/T*-
-{
- _leading aload pop Td
-} def
-/T-
-{
- _ax neg 0 rmoveto
- _hyphen Tx
-} def
-/T+
-{
-} def
-/TR
-{
- _ctm currentmatrix pop
- _tm astore pop
- iTm 0 0 moveto
-} def
-/TS
-{
- currentfont 3 1 roll
- /_Symbol_ _fScl 1000 mul selectfont
-
- 0 eq
- {
- Tx
- }
- {
- Tj
- } ifelse
- setfont
-} def
-/Xb
-{
- pop pop
-} def
-/Tb /Xb load def
-/Xe
-{
- pop pop pop pop
-} def
-/Te /Xe load def
-/XB
-{
-} def
-/TB /XB load def
-currentdict readonly pop
-end
-setpacking
-%%EndResource
-%%BeginProcSet: Adobe_ColorImage_AI6 1.0 0
-userdict /Adobe_ColorImage_AI6 known not
-{
- userdict /Adobe_ColorImage_AI6 17 dict put
-} if
-userdict /Adobe_ColorImage_AI6 get begin
-
- /initialize
- {
- Adobe_ColorImage_AI6 begin
- Adobe_ColorImage_AI6
- {
- dup type /arraytype eq
- {
- dup xcheck
- {
- bind
- } if
- } if
- pop pop
- } forall
- } def
- /terminate { end } def
-
- currentdict /Adobe_ColorImage_AI6_Vars known not
- {
- /Adobe_ColorImage_AI6_Vars 14 dict def
- } if
-
- Adobe_ColorImage_AI6_Vars begin
- /channelcount 0 def
- /sourcecount 0 def
- /sourcearray 4 array def
- /plateindex -1 def
- /XIMask 0 def
- /XIBinary 0 def
- /XIChannelCount 0 def
- /XIBitsPerPixel 0 def
- /XIImageHeight 0 def
- /XIImageWidth 0 def
- /XIImageMatrix null def
- /XIBuffer null def
- /XIDataProc null def
- end
-
- /WalkRGBString null def
- /WalkCMYKString null def
-
- /StuffRGBIntoGrayString null def
- /RGBToGrayImageProc null def
- /StuffCMYKIntoGrayString null def
- /CMYKToGrayImageProc null def
- /ColorImageCompositeEmulator null def
-
- /SeparateCMYKImageProc null def
-
- /FourEqual null def
- /TestPlateIndex null def
-
- currentdict /_colorimage known not
- {
- /colorimage where
- {
- /colorimage get /_colorimage exch def
- }
- {
- /_colorimage null def
- } ifelse
- } if
-
- /_currenttransfer systemdict /currenttransfer get def
-
- /colorimage null def
- /XI null def
-
-
- /WalkRGBString
- {
- 0 3 index
-
- dup length 1 sub 0 3 3 -1 roll
- {
- 3 getinterval { } forall
-
- 5 index exec
-
- 3 index
- } for
-
- 5 { pop } repeat
-
- } def
-
-
- /WalkCMYKString
- {
- 0 3 index
-
- dup length 1 sub 0 4 3 -1 roll
- {
- 4 getinterval { } forall
-
- 6 index exec
-
- 3 index
-
- } for
-
- 5 { pop } repeat
-
- } def
-
-
- /StuffRGBIntoGrayString
- {
- .11 mul exch
-
- .59 mul add exch
-
- .3 mul add
-
- cvi 3 copy put
-
- pop 1 add
- } def
-
-
- /RGBToGrayImageProc
- {
- Adobe_ColorImage_AI6_Vars begin
- sourcearray 0 get exec
- dup length 3 idiv string
- dup 3 1 roll
-
- /StuffRGBIntoGrayString load exch
- WalkRGBString
- end
- } def
-
-
- /StuffCMYKIntoGrayString
- {
- exch .11 mul add
-
- exch .59 mul add
-
- exch .3 mul add
-
- dup 255 gt { pop 255 } if
-
- 255 exch sub cvi 3 copy put
-
- pop 1 add
- } def
-
-
- /CMYKToGrayImageProc
- {
- Adobe_ColorImage_AI6_Vars begin
- sourcearray 0 get exec
- dup length 4 idiv string
- dup 3 1 roll
-
- /StuffCMYKIntoGrayString load exch
- WalkCMYKString
- end
- } def
-
-
- /ColorImageCompositeEmulator
- {
- pop true eq
- {
- Adobe_ColorImage_AI6_Vars /sourcecount get 5 add { pop } repeat
- }
- {
- Adobe_ColorImage_AI6_Vars /channelcount get 1 ne
- {
- Adobe_ColorImage_AI6_Vars begin
- sourcearray 0 3 -1 roll put
-
- channelcount 3 eq
- {
- /RGBToGrayImageProc
- }
- {
- /CMYKToGrayImageProc
- } ifelse
- load
- end
- } if
- image
- } ifelse
- } def
-
-
- /SeparateCMYKImageProc
- {
- Adobe_ColorImage_AI6_Vars begin
-
- sourcecount 0 ne
- {
- sourcearray plateindex get exec
- }
- {
- sourcearray 0 get exec
-
- dup length 4 idiv string
-
- 0 2 index
-
- plateindex 4 2 index length 1 sub
- {
- get 255 exch sub
-
- 3 copy put pop 1 add
-
- 2 index
- } for
-
- pop pop exch pop
- } ifelse
- end
- } def
-
-
- /FourEqual
- {
- 4 index ne
- {
- pop pop pop false
- }
- {
- 4 index ne
- {
- pop pop false
- }
- {
- 4 index ne
- {
- pop false
- }
- {
- 4 index eq
- } ifelse
- } ifelse
- } ifelse
- } def
-
-
- /TestPlateIndex
- {
- Adobe_ColorImage_AI6_Vars begin
- /plateindex -1 def
-
- /setcmykcolor where
- {
- pop
- gsave
- 1 0 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
- 0 1 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
- 0 0 1 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
- 0 0 0 1 setcmykcolor systemdict /currentgray get exec 1 exch sub
- grestore
-
- 1 0 0 0 FourEqual
- {
- /plateindex 0 def
- }
- {
- 0 1 0 0 FourEqual
- {
- /plateindex 1 def
- }
- {
- 0 0 1 0 FourEqual
- {
- /plateindex 2 def
- }
- {
- 0 0 0 1 FourEqual
- {
- /plateindex 3 def
- }
- {
- 0 0 0 0 FourEqual
- {
- /plateindex 5 def
- } if
- } ifelse
- } ifelse
- } ifelse
- } ifelse
- pop pop pop pop
- } if
- plateindex
- end
- } def
-
-
- /colorimage
- {
- Adobe_ColorImage_AI6_Vars begin
- /channelcount 1 index def
- /sourcecount 2 index 1 eq { channelcount 1 sub } { 0 } ifelse def
-
- 4 sourcecount add index dup
- 8 eq exch 1 eq or not
- end
-
- {
- /_colorimage load null ne
- {
- _colorimage
- }
- {
- Adobe_ColorImage_AI6_Vars /sourcecount get
- 7 add { pop } repeat
- } ifelse
- }
- {
- dup 3 eq
- TestPlateIndex
- dup -1 eq exch 5 eq or or
- {
- /_colorimage load null eq
- {
- ColorImageCompositeEmulator
- }
- {
- dup 1 eq
- {
- pop pop image
- }
- {
- Adobe_ColorImage_AI6_Vars /plateindex get 5 eq
- {
- gsave
-
- 0 _currenttransfer exec
- 1 _currenttransfer exec
- eq
- { 0 _currenttransfer exec 0.5 lt }
- { 0 _currenttransfer exec 1 _currenttransfer exec gt } ifelse
-
- { { pop 0 } } { { pop 1 } } ifelse
- systemdict /settransfer get exec
- } if
-
- _colorimage
-
- Adobe_ColorImage_AI6_Vars /plateindex get 5 eq
- {
- grestore
- } if
- } ifelse
- } ifelse
- }
- {
- dup 1 eq
- {
- pop pop
- image
- }
- {
- pop pop
-
- Adobe_ColorImage_AI6_Vars begin
- sourcecount -1 0
- {
- exch sourcearray 3 1 roll put
- } for
-
- /SeparateCMYKImageProc load
- end
-
- systemdict /image get exec
- } ifelse
- } ifelse
- } ifelse
- } def
-
- /XI
- {
- Adobe_ColorImage_AI6_Vars begin
- gsave
- /XIMask exch 0 ne def
- /XIBinary exch 0 ne def
- pop
- pop
- /XIChannelCount exch def
- /XIBitsPerPixel exch def
- /XIImageHeight exch def
- /XIImageWidth exch def
- pop pop pop pop
- /XIImageMatrix exch def
-
- XIBitsPerPixel 1 eq
- {
- XIImageWidth 8 div ceiling cvi
- }
- {
- XIImageWidth XIChannelCount mul
- } ifelse
- /XIBuffer exch string def
-
- XIBinary
- {
- /XIDataProc { currentfile XIBuffer readstring pop } def
- currentfile 128 string readline pop pop
- }
- {
- /XIDataProc { currentfile XIBuffer readhexstring pop } def
- } ifelse
-
- 0 0 moveto
- XIImageMatrix concat
- XIImageWidth XIImageHeight scale
-
- XIMask
- {
- XIImageWidth XIImageHeight
- false
- [ XIImageWidth 0 0 XIImageHeight neg 0 0 ]
- /XIDataProc load
-
- /_lp /null ddef
- _fc
- /_lp /imagemask ddef
-
- imagemask
- }
- {
- XIImageWidth XIImageHeight
- XIBitsPerPixel
- [ XIImageWidth 0 0 XIImageHeight neg 0 0 ]
- /XIDataProc load
-
- XIChannelCount 1 eq
- {
-
- gsave
- 0 setgray
-
- image
-
- grestore
- }
- {
- false
- XIChannelCount
- colorimage
- } ifelse
- } ifelse
- grestore
- end
- } def
-
-end
-%%EndProcSet
-%%BeginResource: procset Adobe_Illustrator_AI5 1.1 0
-%%Title: (Adobe Illustrator (R) Version 5.0 Full Prolog)
-%%Version: 1.1
-%%CreationDate: (3/7/1994) ()
-%%Copyright: ((C) 1987-1994 Adobe Systems Incorporated All Rights Reserved)
-currentpacking true setpacking
-userdict /Adobe_Illustrator_AI5_vars 81 dict dup begin
-put
-/_eo false def
-/_lp /none def
-/_pf
-{
-} def
-/_ps
-{
-} def
-/_psf
-{
-} def
-/_pss
-{
-} def
-/_pjsf
-{
-} def
-/_pjss
-{
-} def
-/_pola 0 def
-/_doClip 0 def
-/cf currentflat def
-/_tm matrix def
-/_renderStart
-[
-/e0 /r0 /a0 /o0 /e1 /r1 /a1 /i0
-] def
-/_renderEnd
-[
-null null null null /i1 /i1 /i1 /i1
-] def
-/_render -1 def
-/_rise 0 def
-/_ax 0 def
-/_ay 0 def
-/_cx 0 def
-/_cy 0 def
-/_leading
-[
-0 0
-] def
-/_ctm matrix def
-/_mtx matrix def
-/_sp 16#020 def
-/_hyphen (-) def
-/_fScl 0 def
-/_cnt 0 def
-/_hs 1 def
-/_nativeEncoding 0 def
-/_useNativeEncoding 0 def
-/_tempEncode 0 def
-/_pntr 0 def
-/_tDict 2 dict def
-/_wv 0 def
-/Tx
-{
-} def
-/Tj
-{
-} def
-/CRender
-{
-} def
-/_AI3_savepage
-{
-} def
-/_gf null def
-/_cf 4 array def
-/_if null def
-/_of false def
-/_fc
-{
-} def
-/_gs null def
-/_cs 4 array def
-/_is null def
-/_os false def
-/_sc
-{
-} def
-/_pd 1 dict def
-/_ed 15 dict def
-/_pm matrix def
-/_fm null def
-/_fd null def
-/_fdd null def
-/_sm null def
-/_sd null def
-/_sdd null def
-/_i null def
-/discardSave null def
-/buffer 256 string def
-/beginString null def
-/endString null def
-/endStringLength null def
-/layerCnt 1 def
-/layerCount 1 def
-/perCent (%) 0 get def
-/perCentSeen? false def
-/newBuff null def
-/newBuffButFirst null def
-/newBuffLast null def
-/clipForward? false def
-end
-userdict /Adobe_Illustrator_AI5 known not {
- userdict /Adobe_Illustrator_AI5 91 dict put
-} if
-userdict /Adobe_Illustrator_AI5 get begin
-/initialize
-{
- Adobe_Illustrator_AI5 dup begin
- Adobe_Illustrator_AI5_vars begin
- discardDict
- {
- bind pop pop
- } forall
- dup /nc get begin
- {
- dup xcheck 1 index type /operatortype ne and
- {
- bind
- } if
- pop pop
- } forall
- end
- newpath
-} def
-/terminate
-{
- end
- end
-} def
-/_
-null def
-/ddef
-{
- Adobe_Illustrator_AI5_vars 3 1 roll put
-} def
-/xput
-{
- dup load dup length exch maxlength eq
- {
- dup dup load dup
- length 2 mul dict copy def
- } if
- load begin
- def
- end
-} def
-/npop
-{
- {
- pop
- } repeat
-} def
-/sw
-{
- dup length exch stringwidth
- exch 5 -1 roll 3 index mul add
- 4 1 roll 3 1 roll mul add
-} def
-/swj
-{
- dup 4 1 roll
- dup length exch stringwidth
- exch 5 -1 roll 3 index mul add
- 4 1 roll 3 1 roll mul add
- 6 2 roll /_cnt 0 ddef
- {
- 1 index eq
- {
- /_cnt _cnt 1 add ddef
- } if
- } forall
- pop
- exch _cnt mul exch _cnt mul 2 index add 4 1 roll 2 index add 4 1 roll pop pop
-} def
-/ss
-{
- 4 1 roll
- {
- 2 npop
- (0) exch 2 copy 0 exch put pop
- gsave
- false charpath currentpoint
- 4 index setmatrix
- stroke
- grestore
- moveto
- 2 copy rmoveto
- } exch cshow
- 3 npop
-} def
-/jss
-{
- 4 1 roll
- {
- 2 npop
- (0) exch 2 copy 0 exch put
- gsave
- _sp eq
- {
- exch 6 index 6 index 6 index 5 -1 roll widthshow
- currentpoint
- }
- {
- false charpath currentpoint
- 4 index setmatrix stroke
- } ifelse
- grestore
- moveto
- 2 copy rmoveto
- } exch cshow
- 6 npop
-} def
-/sp
-{
- {
- 2 npop (0) exch
- 2 copy 0 exch put pop
- false charpath
- 2 copy rmoveto
- } exch cshow
- 2 npop
-} def
-/jsp
-{
- {
- 2 npop
- (0) exch 2 copy 0 exch put
- _sp eq
- {
- exch 5 index 5 index 5 index 5 -1 roll widthshow
- }
- {
- false charpath
- } ifelse
- 2 copy rmoveto
- } exch cshow
- 5 npop
-} def
-/pl
-{
- transform
- 0.25 sub round 0.25 add exch
- 0.25 sub round 0.25 add exch
- itransform
-} def
-/setstrokeadjust where
-{
- pop true setstrokeadjust
- /c
- {
- curveto
- } def
- /C
- /c load def
- /v
- {
- currentpoint 6 2 roll curveto
- } def
- /V
- /v load def
- /y
- {
- 2 copy curveto
- } def
- /Y
- /y load def
- /l
- {
- lineto
- } def
- /L
- /l load def
- /m
- {
- moveto
- } def
-}
-{
- /c
- {
- pl curveto
- } def
- /C
- /c load def
- /v
- {
- currentpoint 6 2 roll pl curveto
- } def
- /V
- /v load def
- /y
- {
- pl 2 copy curveto
- } def
- /Y
- /y load def
- /l
- {
- pl lineto
- } def
- /L
- /l load def
- /m
- {
- pl moveto
- } def
-} ifelse
-/d
-{
- setdash
-} def
-/cf
-{
-} def
-/i
-{
- dup 0 eq
- {
- pop cf
- } if
- setflat
-} def
-/j
-{
- setlinejoin
-} def
-/J
-{
- setlinecap
-} def
-/M
-{
- setmiterlimit
-} def
-/w
-{
- setlinewidth
-} def
-/XR
-{
- 0 ne
- /_eo exch ddef
-} def
-/H
-{
-} def
-/h
-{
- closepath
-} def
-/N
-{
- _pola 0 eq
- {
- _doClip 1 eq
- {
- _eo {eoclip} {clip} ifelse /_doClip 0 ddef
- } if
- newpath
- }
- {
- /CRender
- {
- N
- } ddef
- } ifelse
-} def
-/n
-{
- N
-} def
-/F
-{
- _pola 0 eq
- {
- _doClip 1 eq
- {
- gsave _pf grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _fc
- /_doClip 0 ddef
- }
- {
- _pf
- } ifelse
- }
- {
- /CRender
- {
- F
- } ddef
- } ifelse
-} def
-/f
-{
- closepath
- F
-} def
-/S
-{
- _pola 0 eq
- {
- _doClip 1 eq
- {
- gsave _ps grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
- /_doClip 0 ddef
- }
- {
- _ps
- } ifelse
- }
- {
- /CRender
- {
- S
- } ddef
- } ifelse
-} def
-/s
-{
- closepath
- S
-} def
-/B
-{
- _pola 0 eq
- {
- _doClip 1 eq
- gsave F grestore
- {
- gsave S grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
- /_doClip 0 ddef
- }
- {
- S
- } ifelse
- }
- {
- /CRender
- {
- B
- } ddef
- } ifelse
-} def
-/b
-{
- closepath
- B
-} def
-/W
-{
- /_doClip 1 ddef
-} def
-/*
-{
- count 0 ne
- {
- dup type /stringtype eq
- {
- pop
- } if
- } if
- newpath
-} def
-/u
-{
-} def
-/U
-{
-} def
-/q
-{
- _pola 0 eq
- {
- gsave
- } if
-} def
-/Q
-{
- _pola 0 eq
- {
- grestore
- } if
-} def
-/*u
-{
- _pola 1 add /_pola exch ddef
-} def
-/*U
-{
- _pola 1 sub /_pola exch ddef
- _pola 0 eq
- {
- CRender
- } if
-} def
-/D
-{
- pop
-} def
-/*w
-{
-} def
-/*W
-{
-} def
-/`
-{
- /_i save ddef
- clipForward?
- {
- nulldevice
- } if
- 6 1 roll 4 npop
- concat pop
- userdict begin
- /showpage
- {
- } def
- 0 setgray
- 0 setlinecap
- 1 setlinewidth
- 0 setlinejoin
- 10 setmiterlimit
- [] 0 setdash
- /setstrokeadjust where {pop false setstrokeadjust} if
- newpath
- 0 setgray
- false setoverprint
-} def
-/~
-{
- end
- _i restore
-} def
-/O
-{
- 0 ne
- /_of exch ddef
- /_lp /none ddef
-} def
-/R
-{
- 0 ne
- /_os exch ddef
- /_lp /none ddef
-} def
-/g
-{
- /_gf exch ddef
- /_fc
- {
- _lp /fill ne
- {
- _of setoverprint
- _gf setgray
- /_lp /fill ddef
- } if
- } ddef
- /_pf
- {
- _fc
- _eo {eofill} {fill} ifelse
- } ddef
- /_psf
- {
- _fc
- ashow
- } ddef
- /_pjsf
- {
- _fc
- awidthshow
- } ddef
- /_lp /none ddef
-} def
-/G
-{
- /_gs exch ddef
- /_sc
- {
- _lp /stroke ne
- {
- _os setoverprint
- _gs setgray
- /_lp /stroke ddef
- } if
- } ddef
- /_ps
- {
- _sc
- stroke
- } ddef
- /_pss
- {
- _sc
- ss
- } ddef
- /_pjss
- {
- _sc
- jss
- } ddef
- /_lp /none ddef
-} def
-/k
-{
- _cf astore pop
- /_fc
- {
- _lp /fill ne
- {
- _of setoverprint
- _cf aload pop setcmykcolor
- /_lp /fill ddef
- } if
- } ddef
- /_pf
- {
- _fc
- _eo {eofill} {fill} ifelse
- } ddef
- /_psf
- {
- _fc
- ashow
- } ddef
- /_pjsf
- {
- _fc
- awidthshow
- } ddef
- /_lp /none ddef
-} def
-/K
-{
- _cs astore pop
- /_sc
- {
- _lp /stroke ne
- {
- _os setoverprint
- _cs aload pop setcmykcolor
- /_lp /stroke ddef
- } if
- } ddef
- /_ps
- {
- _sc
- stroke
- } ddef
- /_pss
- {
- _sc
- ss
- } ddef
- /_pjss
- {
- _sc
- jss
- } ddef
- /_lp /none ddef
-} def
-/x
-{
- /_gf exch ddef
- findcmykcustomcolor
- /_if exch ddef
- /_fc
- {
- _lp /fill ne
- {
- _of setoverprint
- _if _gf 1 exch sub setcustomcolor
- /_lp /fill ddef
- } if
- } ddef
- /_pf
- {
- _fc
- _eo {eofill} {fill} ifelse
- } ddef
- /_psf
- {
- _fc
- ashow
- } ddef
- /_pjsf
- {
- _fc
- awidthshow
- } ddef
- /_lp /none ddef
-} def
-/X
-{
- /_gs exch ddef
- findcmykcustomcolor
- /_is exch ddef
- /_sc
- {
- _lp /stroke ne
- {
- _os setoverprint
- _is _gs 1 exch sub setcustomcolor
- /_lp /stroke ddef
- } if
- } ddef
- /_ps
- {
- _sc
- stroke
- } ddef
- /_pss
- {
- _sc
- ss
- } ddef
- /_pjss
- {
- _sc
- jss
- } ddef
- /_lp /none ddef
-} def
-/A
-{
- pop
-} def
-/annotatepage
-{
-userdict /annotatepage 2 copy known {get exec} {pop pop} ifelse
-} def
-/XT {
- pop pop
-} def
-/discard
-{
- save /discardSave exch store
- discardDict begin
- /endString exch store
- gt38?
- {
- 2 add
- } if
- load
- stopped
- pop
- end
- discardSave restore
-} bind def
-userdict /discardDict 7 dict dup begin
-put
-/pre38Initialize
-{
- /endStringLength endString length store
- /newBuff buffer 0 endStringLength getinterval store
- /newBuffButFirst newBuff 1 endStringLength 1 sub getinterval store
- /newBuffLast newBuff endStringLength 1 sub 1 getinterval store
-} def
-/shiftBuffer
-{
- newBuff 0 newBuffButFirst putinterval
- newBuffLast 0
- currentfile read not
- {
- stop
- } if
- put
-} def
-0
-{
- pre38Initialize
- mark
- currentfile newBuff readstring exch pop
- {
- {
- newBuff endString eq
- {
- cleartomark stop
- } if
- shiftBuffer
- } loop
- }
- {
- stop
- } ifelse
-} def
-1
-{
- pre38Initialize
- /beginString exch store
- mark
- currentfile newBuff readstring exch pop
- {
- {
- newBuff beginString eq
- {
- /layerCount dup load 1 add store
- }
- {
- newBuff endString eq
- {
- /layerCount dup load 1 sub store
- layerCount 0 eq
- {
- cleartomark stop
- } if
- } if
- } ifelse
- shiftBuffer
- } loop
- } if
-} def
-2
-{
- mark
- {
- currentfile buffer readline not
- {
- stop
- } if
- endString eq
- {
- cleartomark stop
- } if
- } loop
-} def
-3
-{
- /beginString exch store
- /layerCnt 1 store
- mark
- {
- currentfile buffer readline not
- {
- stop
- } if
- dup beginString eq
- {
- pop /layerCnt dup load 1 add store
- }
- {
- endString eq
- {
- layerCnt 1 eq
- {
- cleartomark stop
- }
- {
- /layerCnt dup load 1 sub store
- } ifelse
- } if
- } ifelse
- } loop
-} def
-end
-userdict /clipRenderOff 15 dict dup begin
-put
-{
- /n /N /s /S /f /F /b /B
-}
-{
- {
- _doClip 1 eq
- {
- /_doClip 0 ddef _eo {eoclip} {clip} ifelse
- } if
- newpath
- } def
-} forall
-/Tr /pop load def
-/Bb {} def
-/BB /pop load def
-/Bg {12 npop} def
-/Bm {6 npop} def
-/Bc /Bm load def
-/Bh {4 npop} def
-end
-/Lb
-{
- 4 npop
- 6 1 roll
- pop
- 4 1 roll
- pop pop pop
- 0 eq
- {
- 0 eq
- {
- (%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard
- }
- {
-
- /clipForward? true def
-
- /Tx /pop load def
- /Tj /pop load def
-
- currentdict end clipRenderOff begin begin
- } ifelse
- }
- {
- 0 eq
- {
- save /discardSave exch store
- } if
- } ifelse
-} bind def
-/LB
-{
- discardSave dup null ne
- {
- restore
- }
- {
- pop
- clipForward?
- {
- currentdict
- end
- end
- begin
-
- /clipForward? false ddef
- } if
- } ifelse
-} bind def
-/Pb
-{
- pop pop
- 0 (%AI5_EndPalette) discard
-} bind def
-/Np
-{
- 0 (%AI5_End_NonPrinting--) discard
-} bind def
-/Ln /pop load def
-/Ap
-/pop load def
-/Ar
-{
- 72 exch div
- 0 dtransform dup mul exch dup mul add sqrt
- dup 1 lt
- {
- pop 1
- } if
- setflat
-} def
-/Mb
-{
- q
-} def
-/Md
-{
-} def
-/MB
-{
- Q
-} def
-/nc 3 dict def
-nc begin
-/setgray
-{
- pop
-} bind def
-/setcmykcolor
-{
- 4 npop
-} bind def
-/setcustomcolor
-{
- 2 npop
-} bind def
-currentdict readonly pop
-end
-end
-setpacking
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeFont: Univers
-Adobe_level2_AI5 /initialize get exec
-Adobe_Illustrator_AI5_vars Adobe_Illustrator_AI5 Adobe_typography_AI5 /initialize get exec
-Adobe_ColorImage_AI6 /initialize get exec
-Adobe_Illustrator_AI5 /initialize get exec
-[
-39/quotesingle 96/grave 128/Adieresis/Aring/Ccedilla/Eacute/Ntilde/Odieresis
-/Udieresis/aacute/agrave/acircumflex/adieresis/atilde/aring/ccedilla/eacute
-/egrave/ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis/ntilde
-/oacute/ograve/ocircumflex/odieresis/otilde/uacute/ugrave/ucircumflex
-/udieresis/dagger/degree/cent/sterling/section/bullet/paragraph/germandbls
-/registered/copyright/trademark/acute/dieresis/.notdef/AE/Oslash
-/.notdef/plusminus/.notdef/.notdef/yen/mu/.notdef/.notdef
-/.notdef/.notdef/.notdef/ordfeminine/ordmasculine/.notdef/ae/oslash
-/questiondown/exclamdown/logicalnot/.notdef/florin/.notdef/.notdef
-/guillemotleft/guillemotright/ellipsis/.notdef/Agrave/Atilde/Otilde/OE/oe
-/endash/emdash/quotedblleft/quotedblright/quoteleft/quoteright/divide
-/.notdef/ydieresis/Ydieresis/fraction/currency/guilsinglleft/guilsinglright
-/fi/fl/daggerdbl/periodcentered/quotesinglbase/quotedblbase/perthousand
-/Acircumflex/Ecircumflex/Aacute/Edieresis/Egrave/Iacute/Icircumflex
-/Idieresis/Igrave/Oacute/Ocircumflex/.notdef/Ograve/Uacute/Ucircumflex
-/Ugrave/dotlessi/circumflex/tilde/macron/breve/dotaccent/ring/cedilla
-/hungarumlaut/ogonek/caron
-TE
-%AI3_BeginEncoding: _Univers Univers
-[/_Univers/Univers 0 0 1 TZ
-%AI3_EndEncoding AdobeType
-%AI5_Begin_NonPrinting
-Np
-8 Bn
-%AI5_BeginGradient: (Black & White)
-(Black & White) 0 2 Bd
-[
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0 %_Br
-[
-0 0 50 100 %_Bs
-1 0 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Green & Blue)
-(Green & Blue) 0 2 Bd
-[
-<
-99999A9A9B9B9B9C9C9D9D9D9E9E9F9F9FA0A0A1A1A1A2A2A3A3A3A4A4A5A5A5A6A6A7A7A7A8A8A9
-A9A9AAAAABABABACACADADADAEAEAFAFAFB0B0B1B1B1B2B2B3B3B3B4B4B5B5B5B6B6B7B7B7B8B8B9
-B9B9BABABBBBBBBCBCBDBDBDBEBEBFBFBFC0C0C1C1C1C2C2C3C3C3C4C4C5C5C5C6C6C7C7C7C8C8C9
-C9C9CACACBCBCBCCCCCDCDCDCECECFCFCFD0D0D1D1D1D2D2D3D3D3D4D4D5D5D5D6D6D7D7D7D8D8D9
-D9D9DADADBDBDBDCDCDDDDDDDEDEDFDFDFE0E0E1E1E1E2E2E3E3E3E4E4E5E5E5E6E6E7E7E7E8E8E9
-E9E9EAEAEBEBEBECECEDEDEDEEEEEFEFEFF0F0F1F1F1F2F2F3F3F3F4F4F5F5F5F6F6F7F7F7F8F8F9
-F9F9FAFAFBFBFBFCFCFDFDFDFEFEFFFF
->
-<
-000102020304050506070808090A0B0B0C0D0E0E0F101111121314141516171718191A1A1B1C1D1D
-1E1F20202122232324252626272829292A2B2C2C2D2E2F2F303132323334353536373838393A3B3B
-3C3D3E3E3F404141424344444546474748494A4A4B4C4D4D4E4F5050515253535455565657585959
-5A5B5C5C5D5E5F5F606162626364656566676868696A6B6B6C6D6E6E6F7071717273747475767777
-78797A7A7B7C7D7D7E7F80808182828384858586878888898A8B8B8C8D8E8E8F9091919293949495
-96979798999A9A9B9C9D9D9E9FA0A0A1A2A3A3A4A5A6A6A7A8A9A9AAABACACADAEAFAFB0B1B2B2B3
-B4B5B5B6B7B8B8B9BABBBBBCBDBEBEBF
->
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0
-1 %_Br
-[
-1 0.75 0 0 1 50 100 %_Bs
-0.6 0 1 0 1 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Pink, Yellow, Green)
-(Pink, Yellow, Green) 0 3 Bd
-[
-<
-00000000000000000000000000000000000000010101010101010101010101010101010101010101
-01010101010202020202020202020202020202020202020202020203030303030303030303030303
-03030303030303030404040404040404040404040404040404040404050505050505050505050505
-05050505050505060606060606060606060606060606060606060707070707070707070707070707
-07070707080808080808080808080808080808080809090909090909090909090909090909090A0A
-0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0C0C0C0C0C0C0C0C0C
-0C0C0C0C0C0C0C0D0D0D0D0D
->
-<
-050506060606070708080809090A0A0A0B0B0C0C0D0D0E0E0F0F1010111112121313141415151617
-17181819191A1A1B1C1C1D1D1E1F1F202021222223232425252626272828292A2A2B2C2C2D2D2E2F
-2F3031313233333435353637373839393A3B3B3C3D3E3E3F4040414242434445454647474849494A
-4B4C4C4D4E4F4F505151525354545556575758595A5A5B5C5C5D5E5F5F6061626363646566666768
-69696A6B6C6C6D6E6F707071727373747576777778797A7B7B7C7D7E7F7F80818283838485868787
-88898A8B8B8C8D8E8F8F9091929394949596979898999A9B9C9D9D9E9FA0A1A2A2A3A4A5A6A7A7A8
-A9AAABACADADAEAFB0B1B2B2
->
-<
-CCCCCBCBCBCACACAC9C9C8C8C7C7C6C6C5C5C4C4C3C2C2C1C1C0C0BFBEBEBDBDBCBBBBBAB9B9B8B7
-B7B6B6B5B4B4B3B2B1B1B0AFAFAEADADACABAAAAA9A8A8A7A6A5A5A4A3A2A2A1A0A09F9E9D9C9C9B
-9A999998979696959493929291908F8E8E8D8C8B8A8A8988878686858483828181807F7E7D7C7C7B
-7A7978777776757473727171706F6E6D6C6B6A6A69686766656463636261605F5E5D5C5B5B5A5958
-5756555453525151504F4E4D4C4B4A49484746464544434241403F3E3D3C3B3A3938383736353433
-3231302F2E2D2C2B2A29282726252423222221201F1E1D1C1B1A191817161514131211100F0E0D0C
-0B0A09080706050403020100
->
-0
-1 %_Br
-<
-737271706F6E6D6C6B6A696867666564636261605F5E5D5C5B5B5A59585756555453525150504F4E
-4D4C4B4A4949484746454443434241403F3E3E3D3C3B3A3A393837363635343333323130302F2E2D
-2D2C2B2A2A29282827262525242323222121201F1F1E1D1D1C1C1B1A1A1918181717161615141413
-1312121111100F0F0E0E0D0D0C0C0C0B0B0A0A090908080807070606060505050404040303030202
-020201010101010000000000
->
-<
-00000000000000000000000001010101010101010101010101010101010101010101010102020202
-02020202020202020202020202020202020202020202030303030303030303030303030303030303
-03030303030303030303030303040404040404040404040404040404040404040404040404040404
-04040404040404040404050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505
->
-<
-BFBFBFC0C0C0C0C0C0C0C0C0C1C1C1C1C1C1C1C1C1C2C2C2C2C2C2C2C2C2C2C3C3C3C3C3C3C3C3C3
-C3C4C4C4C4C4C4C4C4C4C4C5C5C5C5C5C5C5C5C5C5C5C6C6C6C6C6C6C6C6C6C6C6C6C7C7C7C7C7C7
-C7C7C7C7C7C7C8C8C8C8C8C8C8C8C8C8C8C8C8C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9CACACACACACA
-CACACACACACACACACACACBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCCCCCCCCCCCCCCCC
-CCCCCCCCCCCCCCCCCCCCCCCC
->
-0
-1 %_Br
-[
-0.05 0.7 0 0 1 50 100 %_Bs
-0 0.02 0.8 0 1 57 36 %_Bs
-0.45 0 0.75 0 1 37 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Purple, Red & Yellow)
-(Purple, Red & Yellow) 0 3 Bd
-[
-0
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A
->
-<
-CCCCCCCDCDCDCDCDCECECECECECFCFCFCFD0D0D0D0D0D1D1D1D1D1D2D2D2D2D2D3D3D3D3D3D4D4D4
-D4D5D5D5D5D5D6D6D6D6D6D7D7D7D7D7D8D8D8D8D8D9D9D9D9DADADADADADBDBDBDBDBDCDCDCDCDC
-DDDDDDDDDDDEDEDEDEDFDFDFDFDFE0E0E0E0E0E1E1E1E1E1E2E2E2E2E2E3E3E3E3E4E4E4E4E4E5E5
-E5E5E5E6E6E6E6E6E7E7E7E7E7E8E8E8E8E9E9E9E9E9EAEAEAEAEAEBEBEBEBEBECECECECECEDEDED
-EDEEEEEEEEEEEFEFEFEFEFF0F0F0F0F0F1F1F1F1F1F2F2F2F2F3F3F3F3F3F4F4F4F4F4F5F5F5F5F5
-F6F6F6F6F6F7F7F7F7F8F8F8F8F8F9F9F9F9F9FAFAFAFAFAFBFBFBFBFBFCFCFCFCFDFDFDFDFDFEFE
-FEFEFEFFFFFF
->
-0
-1 %_Br
-<
-E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBE
-BDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A99989796
-9594939291908F8E8D8C8B8A898887868584838281807F7E7D7C7B7A797877767574737271706F6E
-6D6C6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746
-4544434241403F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E
-1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100
->
-<
-E5E6E6E6E6E6E6E6E6E7E7E7E7E7E7E7E7E7E8E8E8E8E8E8E8E8E8E9E9E9E9E9E9E9E9E9EAEAEAEA
-EAEAEAEAEAEBEBEBEBEBEBEBEBEBECECECECECECECECECEDEDEDEDEDEDEDEDEDEEEEEEEEEEEEEEEE
-EEEFEFEFEFEFEFEFEFEFF0F0F0F0F0F0F0F0F0F1F1F1F1F1F1F1F1F1F2F2F2F2F2F2F2F2F2F3F3F3
-F3F3F3F3F3F3F4F4F4F4F4F4F4F4F4F5F5F5F5F5F5F5F5F5F6F6F6F6F6F6F6F6F6F7F7F7F7F7F7F7
-F7F7F8F8F8F8F8F8F8F8F8F9F9F9F9F9F9F9F9F9FAFAFAFAFAFAFAFAFAFBFBFBFBFBFBFBFBFBFCFC
-FCFCFCFCFCFCFCFDFDFDFDFDFDFDFDFDFEFEFEFEFEFEFEFEFEFFFFFFFFFF
->
-<
-00010203040405060708090A0B0C0C0D0E0F10111213141415161718191A1B1C1D1D1E1F20212223
-242525262728292A2B2C2D2D2E2F30313233343535363738393A3B3C3D3D3E3F4041424344454546
-4748494A4B4C4D4E4E4F50515253545556565758595A5B5C5D5E5E5F60616263646566666768696A
-6B6C6D6E6E6F70717273747576767778797A7B7C7D7E7F7F80818283848586878788898A8B8C8D8E
-8F8F90919293949596979798999A9B9C9D9E9F9FA0A1A2A3A4A5A6A7A7A8A9AAABACADAEAFAFB0B1
-B2B3B4B5B6B7B8B8B9BABBBCBDBEBFC0C0C1C2C3C4C5C6C7C8C8C9CACBCC
->
-0
-1 %_Br
-[
-0 0.04 1 0 1 50 100 %_Bs
-0 1 0.8 0 1 50 50 %_Bs
-0.9 0.9 0 0 1 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Rainbow)
-(Rainbow) 0 6 Bd
-[
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-1
-0
-0
-1 %_Br
-1
-<
-0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E
-2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556
-5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E
-7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6
-A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE
-CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6
-F7F8F9FAFBFCFDFEFF
->
-0
-0
-1 %_Br
-1
-<
-00000000000000000000000000000000000001010101010101010101010101010101010101010101
-01010101010101010101010101010202020202020202020202020202020202020202020202020202
-02020202020202020202030303030303030303030303030303030303030303030303030303030303
-03030303030304040404040404040404040404040404040404040404040404040404040404040404
-04040505050505050505050505050505050505050505050505050505050505050505050505050606
-06060606060606060606060606060606060606060606060606060606060606060606070707070707
-07070707070707070707070707070707
->
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0
-1 %_Br
-<
-000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
-28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
-505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
-78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
-A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
-C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
-F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
->
-0
-1
-0
-1 %_Br
-0
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-1
-0
-1 %_Br
-[
-0 1 0 0 1 50 100 %_Bs
-1 1 0 0 1 50 80 %_Bs
-1 0.0279 0 0 1 50 60 %_Bs
-1 0 1 0 1 50 40 %_Bs
-0 0 1 0 1 50 20 %_Bs
-0 1 1 0 1 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Steel Bar)
-(Steel Bar) 0 3 Bd
-[
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0 %_Br
-<
-000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
-28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
-505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
-78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
-A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
-C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
-F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
->
-0 %_Br
-[
-0 0 50 100 %_Bs
-1 0 50 70 %_Bs
-0 0 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Yellow & Orange Radial)
-(Yellow & Orange Radial) 1 2 Bd
-[
-0
-<
-0001010203040506060708090A0B0C0C0D0E0F10111213131415161718191A1B1C1D1D1E1F202122
-232425262728292A2B2B2C2D2E2F303132333435363738393A3B3C3D3E3E3F404142434445464748
-494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60606162636465666768696A6B6C6D6E6F
-707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C
->
-<
-FFFFFFFFFEFEFEFEFEFEFEFDFDFDFDFDFDFCFCFCFCFCFCFBFBFBFBFBFBFAFAFAFAFAFAF9F9F9F9F9
-F9F8F8F8F8F8F8F7F7F7F7F7F7F6F6F6F6F6F6F5F5F5F5F5F5F4F4F4F4F4F3F3F3F3F3F3F2F2F2F2
-F2F2F1F1F1F1F1F0F0F0F0F0F0EFEFEFEFEFEFEEEEEEEEEEEDEDEDEDEDEDECECECECECEBEBEBEBEB
-EBEAEAEAEAEAE9E9E9E9E9E9E8E8E8E8E8E8E7E7E7E7E7E6E6E6E6E6E5
->
-0
-1 %_Br
-[
-0 0 1 0 1 52 19 %_Bs
-0 0.55 0.9 0 1 50 100 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Yellow & Purple Radial)
-(Yellow & Purple Radial) 1 2 Bd
-[
-<
-000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
-28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
-505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
-78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
-A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
-C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
-F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
->
-<
-1415161718191A1B1C1D1E1F1F202122232425262728292A2A2B2C2D2E2F30313233343536363738
-393A3B3C3D3E3F40414142434445464748494A4B4C4D4D4E4F50515253545556575858595A5B5C5D
-5E5F60616263646465666768696A6B6C6D6E6F6F707172737475767778797A7B7B7C7D7E7F808182
-83848586868788898A8B8C8D8E8F90919292939495969798999A9B9C9D9D9E9FA0A1A2A3A4A5A6A7
-A8A9A9AAABACADAEAFB0B1B2B3B4B4B5B6B7B8B9BABBBCBDBEBFC0C0C1C2C3C4C5C6C7C8C9CACBCB
-CCCDCECFD0D1D2D3D4D5D6D7D7D8D9DADBDCDDDEDFE0E1E2E2E3E4E5E6E7E8E9EAEBECEDEEEEEFF0
-F1F2F3F4F5F6F7F8F9F9FAFBFCFDFEFF
->
-<
-ABAAAAA9A8A7A7A6A5A5A4A3A3A2A1A1A09F9F9E9D9D9C9B9B9A9999989797969595949393929191
-908F8F8E8D8D8C8B8B8A8989888787868585848383828181807F7F7E7D7D7C7B7B7A797978777776
-7575747373727171706F6F6E6D6D6C6B6B6A6969686767666565646362626160605F5E5E5D5C5C5B
-5A5A5958585756565554545352525150504F4E4E4D4C4C4B4A4A4948484746464544444342424140
-403F3E3E3D3C3C3B3A3A3938383736363534343332323130302F2E2E2D2C2C2B2A2A292828272626
-25242423222121201F1F1E1D1D1C1B1B1A1919181717161515141313121111100F0F0E0D0D0C0B0B
-0A090908070706050504030302010100
->
-0
-1 %_Br
-[
-0 0.08 0.67 0 1 50 14 %_Bs
-1 1 0 0 1 50 100 %_Bs
-BD
-%AI5_EndGradient
-%AI5_End_NonPrinting--
-%AI5_BeginPalette
-0 0 Pb
-Pn
-Pc
-1 g
-Pc
-0 g
-Pc
-0 0 0 0 k
-Pc
-0.75 g
-Pc
-0.5 g
-Pc
-0.25 g
-Pc
-0 g
-Pc
-Bb
-2 (Black & White) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.25 0 0 0 k
-Pc
-0.5 0 0 0 k
-Pc
-0.75 0 0 0 k
-Pc
-1 0 0 0 k
-Pc
-0.25 0.25 0 0 k
-Pc
-0.5 0.5 0 0 k
-Pc
-0.75 0.75 0 0 k
-Pc
-1 1 0 0 k
-Pc
-Bb
-2 (Pink, Yellow, Green) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0 0.25 0 0 k
-Pc
-0 0.5 0 0 k
-Pc
-0 0.75 0 0 k
-Pc
-0 1 0 0 k
-Pc
-0 0.25 0.25 0 k
-Pc
-0 0.5 0.5 0 k
-Pc
-0 0.75 0.75 0 k
-Pc
-0 1 1 0 k
-Pc
-Bb
-0 0 0 0 Bh
-2 (Yellow & Purple Radial) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0 0 0.25 0 k
-Pc
-0 0 0.5 0 k
-Pc
-0 0 0.75 0 k
-Pc
-0 0 1 0 k
-Pc
-0.25 0 0.25 0 k
-Pc
-0.5 0 0.5 0 k
-Pc
-0.75 0 0.75 0 k
-Pc
-1 0 1 0 k
-Pc
-Bb
-2 (Rainbow) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.25 0.125 0 0 k
-Pc
-0.5 0.25 0 0 k
-Pc
-0.75 0.375 0 0 k
-Pc
-1 0.5 0 0 k
-Pc
-0.125 0.25 0 0 k
-Pc
-0.25 0.5 0 0 k
-Pc
-0.375 0.75 0 0 k
-Pc
-0.5 1 0 0 k
-Pc
-Bb
-2 (Steel Bar) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0 0.25 0.125 0 k
-Pc
-0 0.5 0.25 0 k
-Pc
-0 0.75 0.375 0 k
-Pc
-0 1 0.5 0 k
-Pc
-0 0.125 0.25 0 k
-Pc
-0 0.25 0.5 0 k
-Pc
-0 0.375 0.75 0 k
-Pc
-0 0.5 1 0 k
-Pc
-Bb
-2 (Purple, Red & Yellow) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.125 0 0.25 0 k
-Pc
-0.25 0 0.5 0 k
-Pc
-0.375 0 0.75 0 k
-Pc
-0.5 0 1 0 k
-Pc
-0.25 0 0.125 0 k
-Pc
-0.5 0 0.25 0 k
-Pc
-0.75 0 0.375 0 k
-Pc
-1 0 0.5 0 k
-Pc
-Bb
-2 (Green & Blue) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.25 0.125 0.125 0 k
-Pc
-0.5 0.25 0.25 0 k
-Pc
-0.75 0.375 0.375 0 k
-Pc
-1 0.5 0.5 0 k
-Pc
-0.25 0.25 0.125 0 k
-Pc
-0.5 0.5 0.25 0 k
-Pc
-0.75 0.75 0.375 0 k
-Pc
-1 1 0.5 0 k
-Pc
-Bb
-0 0 0 0 Bh
-2 (Yellow & Orange Radial) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.125 0.25 0.125 0 k
-Pc
-0.25 0.5 0.25 0 k
-Pc
-0.375 0.75 0.375 0 k
-Pc
-0.5 1 0.5 0 k
-Pc
-0.125 0.25 0.25 0 k
-Pc
-0.25 0.5 0.5 0 k
-Pc
-0.375 0.75 0.75 0 k
-Pc
-0.5 1 1 0 k
-Pc
-0 0 0 0 k
-Pc
-0.125 0.125 0.25 0 k
-Pc
-0.25 0.25 0.5 0 k
-Pc
-0.375 0.375 0.75 0 k
-Pc
-0.5 0.5 1 0 k
-Pc
-0.25 0.125 0.25 0 k
-Pc
-0.5 0.25 0.5 0 k
-Pc
-0.75 0.375 0.75 0 k
-Pc
-1 0.5 1 0 k
-Pc
-PB
-%AI5_EndPalette
-%%EndSetup
-%AI5_BeginLayer
-1 1 1 1 0 0 0 79 128 255 Lb
-(Layer 1) Ln
-0 A
-800 Ar
-0 J 0 j 1 w 4 M []0 d
-%AI3_Note:
-0 D
-0 XR
--4014 283.5 m
-4626 283.5 L
-(N) *
-453.5 4716 m
-453.5 -3924 L
-(N) *
-85 4716 m
-85 -3924 L
-(N) *
--4014 765.5 m
-4626 765.5 L
-(N) *
-0 O
-1 g
-0 R
-0 G
-186.2136 638 m
-278.1654 638 l
-B
-3 w
-329.9252 666 m
-329.9252 609.5 l
-B
-0 To
-1 0 0 1 336.4252 652.5 0 Tp
-TP
-0 Tr
-0 g
-1 w
-/_Univers 10 Tf
-0 Ts
-100 Tz
-0 Tt
-1 TA
-%_ 0 XL
-36 0 Xb
-XB
-0 0 5 TC
-100 100 200 TW
-0 0 0 Ti
-0 Ta
-0 0 2 2 3 Th
-0 Tq
-0 0 Tl
-0 Tc
-0 Tw
-(Underlying\r) Tx
-0 -12 Td
-(Graphics\r) Tx
-0 -12 Td
-(System\r) Tx
-0 -12 Td
-(backend) Tx
-(\r) TX
-TO
-0 To
-1 0 0 1 224.9252 640.5 0 Tp
-TP
-0 Tr
-(link) Tx
-(\r) TX
-TO
-0 To
-1 0 0 1 300.9252 634 0 Tp
-TP
--7.2241 0 Td
-0 Tr
-1 Ta
-(GS) Tx
-(\r) TX
-TO
-0 To
-1 0 0 1 164.4252 606 0 Tp
-TP
--46.6589 0 Td
-0 Tr
-(Application Process) Tx
-(\r) TX
-TO
-0 R
-0 G
-2 J [5 7 ]0 d
-168.4252 660.0625 m
-173.7289 670.9058 189.4252 678.5625 v
-209.9252 688.5625 228.9252 691.5625 248.4252 695.0625 c
-277.9615 700.3639 350.9252 709.0625 y
-S
-1 Ap
-0 O
-0.75 g
-[]0 d
-363.5118 702.4134 m
-363.5118 716.5866 L
-349.3386 716.5866 L
-349.3386 702.4134 L
-363.5118 702.4134 L
-b
-0 To
-1 0 0 1 356.4252 720 0 Tp
-TP
--34.7095 0 Td
-0 Tr
-0 g
-0 J
-(window object) Tx
-(\r) TX
-TO
-0 To
-1 0 0 1 239.9252 704 0 Tp
-TP
--44.4373 0 Td
-0 Tr
-(owner relationship) Tx
-(\r) TX
-TO
-0 To
-1 0 0 1 301.9252 604.6667 0 Tp
-TP
--20.2759 0 Td
-0 Tr
-(graphics\r) Tx
-5.5481 -12 Td
-(server) Tx
-(\r) TX
-TO
-u
-0 Ap
-0 R
-0 G
-278.1654 638 m
-278.1654 644.2129 280.5848 650.0538 284.9781 654.447 c
-289.3713 658.8403 295.2123 661.2599 301.4252 661.2599 c
-307.638 661.2599 313.4791 658.8403 317.8723 654.447 c
-322.2656 650.0538 324.685 644.2129 324.685 638 c
-324.685 625.1744 314.2507 614.7402 301.4252 614.7402 c
-295.2123 614.7402 289.3713 617.1596 284.9781 621.5529 c
-280.5848 625.9461 278.1654 631.7872 278.1654 638 c
-s
-1 Ap
-301.4252 616.7402 m
-313.1665 616.7402 322.685 626.2586 322.685 638 c
-322.685 649.7413 313.1665 659.2599 301.4252 659.2599 c
-289.6839 659.2599 280.1654 649.7413 280.1654 638 c
-280.1654 626.2586 289.6839 616.7402 301.4252 616.7402 c
-s
-U
-164.9538 616.7116 m
-176.6951 616.7116 186.2136 626.2301 186.2136 637.9714 c
-186.2136 649.7127 176.6951 659.2312 164.9538 659.2312 c
-153.2125 659.2312 143.694 649.7127 143.694 637.9714 c
-143.694 626.2301 153.2125 616.7116 164.9538 616.7116 c
-s
-LB
-%AI5_EndLayer--
-%%PageTrailer
-gsave annotatepage grestore showpage
-%%Trailer
-Adobe_Illustrator_AI5 /terminate get exec
-Adobe_ColorImage_AI6 /terminate get exec
-Adobe_typography_AI5 /terminate get exec
-Adobe_level2_AI5 /terminate get exec
-%%EOF
diff --git a/lib/gs/doc/src/images/gs1-1-image-3.gif b/lib/gs/doc/src/images/gs1-1-image-3.gif
deleted file mode 100644
index 5f795194f9..0000000000
--- a/lib/gs/doc/src/images/gs1-1-image-3.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/gs1-1-image-3.ps b/lib/gs/doc/src/images/gs1-1-image-3.ps
deleted file mode 100644
index 7d95e0339c..0000000000
--- a/lib/gs/doc/src/images/gs1-1-image-3.ps
+++ /dev/null
@@ -1,2830 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: Adobe Illustrator(r) 6.0
-%%For: (Anna Fedoriw) (Ericsson Telecom)
-%%Title: (All_events.eps)
-%%CreationDate: (97-05-23) (14.00)
-%%BoundingBox: 122 566 396 709
-%%HiResBoundingBox: 122.3411 566.1667 395.7095 708.3677
-%%DocumentProcessColors: Black
-%%DocumentFonts: Geneva
-%%+ Univers
-%%DocumentSuppliedResources: procset Adobe_level2_AI5 1.0 0
-%%+ procset Adobe_typography_AI5 1.0 0
-%%+ procset Adobe_Illustrator_AI6_vars Adobe_Illustrator_AI6
-%%+ procset Adobe_Illustrator_AI5 1.0 0
-%AI5_FileFormat 2.0
-%AI3_ColorUsage: Black&White
-%%AI6_ColorSeparationSet: 1 1 (AI6 Default Color Separation Set)
-%%+ Options: 1 16 0 1 0 1 1 1 0 1 1 1 1 18 0 0 0 0 0 0 0 0 -1 -1
-%%+ PPD: 1 21 0 0 60 45 2 2 1 0 0 1 0 0 0 0 0 0 0 0 0 0 ()
-%AI3_TemplateBox: 306 396 306 396
-%AI3_TileBox: 21 -12 588 802
-%AI3_DocumentPreview: Macintosh_ColorPic
-%AI5_ArtSize: 595.2756 841.8898
-%AI5_RulerUnits: 1
-%AI5_ArtFlags: 0 0 0 1 0 0 1 1 0
-%AI5_TargetResolution: 800
-%AI5_NumLayers: 1
-%AI5_OpenToView: -126 900 1 1058 826 58 1 1 2 40
-%AI5_OpenViewLayers: 7
-%%EndComments
-%%BeginProlog
-%%BeginResource: procset Adobe_level2_AI5 1.2 0
-%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation)
-%%Version: 1.2
-%%CreationDate: (04/10/93) ()
-%%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved)
-userdict /Adobe_level2_AI5 23 dict dup begin
- put
- /packedarray where not
- {
- userdict begin
- /packedarray
- {
- array astore readonly
- } bind def
- /setpacking /pop load def
- /currentpacking false def
- end
- 0
- } if
- pop
- userdict /defaultpacking currentpacking put true setpacking
- /initialize
- {
- Adobe_level2_AI5 begin
- } bind def
- /terminate
- {
- currentdict Adobe_level2_AI5 eq
- {
- end
- } if
- } bind def
- mark
- /setcustomcolor where not
- {
- /findcmykcustomcolor
- {
- 5 packedarray
- } bind def
- /setcustomcolor
- {
- exch aload pop pop
- 4
- {
- 4 index mul 4 1 roll
- } repeat
- 5 -1 roll pop
- setcmykcolor
- }
- def
- } if
-
- /gt38? mark {version cvr cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def
- userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put
- userdict /level2?
- systemdict /languagelevel known dup
- {
- pop systemdict /languagelevel get 2 ge
- } if
- put
-/level2ScreenFreq
-{
- begin
- 60
- HalftoneType 1 eq
- {
- pop Frequency
- } if
- HalftoneType 2 eq
- {
- pop GrayFrequency
- } if
- HalftoneType 5 eq
- {
- pop Default level2ScreenFreq
- } if
- end
-} bind def
-userdict /currentScreenFreq
- level2? {currenthalftone level2ScreenFreq} {currentscreen pop pop} ifelse put
-level2? not
- {
- /setcmykcolor where not
- {
- /setcmykcolor
- {
- exch .11 mul add exch .59 mul add exch .3 mul add
- 1 exch sub setgray
- } def
- } if
- /currentcmykcolor where not
- {
- /currentcmykcolor
- {
- 0 0 0 1 currentgray sub
- } def
- } if
- /setoverprint where not
- {
- /setoverprint /pop load def
- } if
- /selectfont where not
- {
- /selectfont
- {
- exch findfont exch
- dup type /arraytype eq
- {
- makefont
- }
- {
- scalefont
- } ifelse
- setfont
- } bind def
- } if
- /cshow where not
- {
- /cshow
- {
- [
- 0 0 5 -1 roll aload pop
- ] cvx bind forall
- } bind def
- } if
- } if
- cleartomark
- /anyColor?
- {
- add add add 0 ne
- } bind def
- /testColor
- {
- gsave
- setcmykcolor currentcmykcolor
- grestore
- } bind def
- /testCMYKColorThrough
- {
- testColor anyColor?
- } bind def
- userdict /composite?
- level2?
- {
- gsave 1 1 1 1 setcmykcolor currentcmykcolor grestore
- add add add 4 eq
- }
- {
- 1 0 0 0 testCMYKColorThrough
- 0 1 0 0 testCMYKColorThrough
- 0 0 1 0 testCMYKColorThrough
- 0 0 0 1 testCMYKColorThrough
- and and and
- } ifelse
- put
- composite? not
- {
- userdict begin
- gsave
- /cyan? 1 0 0 0 testCMYKColorThrough def
- /magenta? 0 1 0 0 testCMYKColorThrough def
- /yellow? 0 0 1 0 testCMYKColorThrough def
- /black? 0 0 0 1 testCMYKColorThrough def
- grestore
- /isCMYKSep? cyan? magenta? yellow? black? or or or def
- /customColor? isCMYKSep? not def
- end
- } if
- end defaultpacking setpacking
-%%EndResource
-%%BeginResource: procset Adobe_typography_AI5 1.0 1
-%%Title: (Typography Operators)
-%%Version: 1.0
-%%CreationDate:(03/26/93) ()
-%%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved)
-currentpacking true setpacking
-userdict /Adobe_typography_AI5 54 dict dup begin
-put
-/initialize
-{
- begin
- begin
- Adobe_typography_AI5 begin
- Adobe_typography_AI5
- {
- dup xcheck
- {
- bind
- } if
- pop pop
- } forall
- end
- end
- end
- Adobe_typography_AI5 begin
-} def
-/terminate
-{
- currentdict Adobe_typography_AI5 eq
- {
- end
- } if
-} def
-/modifyEncoding
-{
- /_tempEncode exch ddef
- /_pntr 0 ddef
- {
- counttomark -1 roll
- dup type dup /marktype eq
- {
- pop pop exit
- }
- {
- /nametype eq
- {
- _tempEncode /_pntr dup load dup 3 1 roll 1 add ddef 3 -1 roll
- put
- }
- {
- /_pntr exch ddef
- } ifelse
- } ifelse
- } loop
- _tempEncode
-} def
-/TE
-{
- StandardEncoding 256 array copy modifyEncoding
- /_nativeEncoding exch def
-} def
-%
-/TZ
-{
- dup type /arraytype eq
- {
- /_wv exch def
- }
- {
- /_wv 0 def
- } ifelse
- /_useNativeEncoding exch def
- pop pop
- findfont _wv type /arraytype eq
- {
- _wv makeblendedfont
- } if
- dup length 2 add dict
- begin
- mark exch
- {
- 1 index /FID ne
- {
- def
- } if
- cleartomark mark
- } forall
- pop
- /FontName exch def
- counttomark 0 eq
- {
- 1 _useNativeEncoding eq
- {
- /Encoding _nativeEncoding def
- } if
- cleartomark
- }
- {
- /Encoding load 256 array copy
- modifyEncoding /Encoding exch def
- } ifelse
- FontName currentdict
- end
- definefont pop
-} def
-/tr
-{
- _ax _ay 3 2 roll
-} def
-/trj
-{
- _cx _cy _sp _ax _ay 6 5 roll
-} def
-/a0
-{
- /Tx
- {
- dup
- currentpoint 3 2 roll
- tr _psf
- newpath moveto
- tr _ctm _pss
- } ddef
- /Tj
- {
- dup
- currentpoint 3 2 roll
- trj _pjsf
- newpath moveto
- trj _ctm _pjss
- } ddef
-} def
-/a1
-{
- /Tx
- {
- dup currentpoint 4 2 roll gsave
- dup currentpoint 3 2 roll
- tr _psf
- newpath moveto
- tr _ctm _pss
- grestore 3 1 roll moveto tr sp
- } ddef
- /Tj
- {
- dup currentpoint 4 2 roll gsave
- dup currentpoint 3 2 roll
- trj _pjsf
- newpath moveto
- trj _ctm _pjss
- grestore 3 1 roll moveto tr jsp
- } ddef
-} def
-/e0
-{
- /Tx
- {
- tr _psf
- } ddef
- /Tj
- {
- trj _pjsf
- } ddef
-} def
-/e1
-{
- /Tx
- {
- dup currentpoint 4 2 roll gsave
- tr _psf
- grestore 3 1 roll moveto tr sp
- } ddef
- /Tj
- {
- dup currentpoint 4 2 roll gsave
- trj _pjsf
- grestore 3 1 roll moveto tr jsp
- } ddef
-} def
-/i0
-{
- /Tx
- {
- tr sp
- } ddef
- /Tj
- {
- trj jsp
- } ddef
-} def
-/i1
-{
- W N
-} def
-/o0
-{
- /Tx
- {
- tr sw rmoveto
- } ddef
- /Tj
- {
- trj swj rmoveto
- } ddef
-} def
-/r0
-{
- /Tx
- {
- tr _ctm _pss
- } ddef
- /Tj
- {
- trj _ctm _pjss
- } ddef
-} def
-/r1
-{
- /Tx
- {
- dup currentpoint 4 2 roll currentpoint gsave newpath moveto
- tr _ctm _pss
- grestore 3 1 roll moveto tr sp
- } ddef
- /Tj
- {
- dup currentpoint 4 2 roll currentpoint gsave newpath moveto
- trj _ctm _pjss
- grestore 3 1 roll moveto tr jsp
- } ddef
-} def
-/To
-{
- pop _ctm currentmatrix pop
-} def
-/TO
-{
- iTe _ctm setmatrix newpath
-} def
-/Tp
-{
- pop _tm astore pop _ctm setmatrix
- _tDict begin
- /W
- {
- } def
- /h
- {
- } def
-} def
-/TP
-{
- end
- iTm 0 0 moveto
-} def
-/Tr
-{
- _render 3 le
- {
- currentpoint newpath moveto
- } if
- dup 8 eq
- {
- pop 0
- }
- {
- dup 9 eq
- {
- pop 1
- } if
- } ifelse
- dup /_render exch ddef
- _renderStart exch get load exec
-} def
-/iTm
-{
- _ctm setmatrix _tm concat 0 _rise translate _hs 1 scale
-} def
-/Tm
-{
- _tm astore pop iTm 0 0 moveto
-} def
-/Td
-{
- _mtx translate _tm _tm concatmatrix pop iTm 0 0 moveto
-} def
-/iTe
-{
- _render -1 eq
- {
- }
- {
- _renderEnd _render get dup null ne
- {
- load exec
- }
- {
- pop
- } ifelse
- } ifelse
- /_render -1 ddef
-} def
-/Ta
-{
- pop
-} def
-/Tf
-{
- dup 1000 div /_fScl exch ddef
-%
- selectfont
-} def
-/Tl
-{
- pop
- 0 exch _leading astore pop
-} def
-/Tt
-{
- pop
-} def
-/TW
-{
- 3 npop
-} def
-/Tw
-{
- /_cx exch ddef
-} def
-/TC
-{
- 3 npop
-} def
-/Tc
-{
- /_ax exch ddef
-} def
-/Ts
-{
- /_rise exch ddef
- currentpoint
- iTm
- moveto
-} def
-/Ti
-{
- 3 npop
-} def
-/Tz
-{
- 100 div /_hs exch ddef
- iTm
-} def
-/TA
-{
- pop
-} def
-/Tq
-{
- pop
-} def
-/Th
-{
- pop pop pop pop pop
-} def
-/TX
-{
- pop
-} def
-/Tk
-{
- exch pop _fScl mul neg 0 rmoveto
-} def
-/TK
-{
- 2 npop
-} def
-/T*
-{
- _leading aload pop neg Td
-} def
-/T*-
-{
- _leading aload pop Td
-} def
-/T-
-{
- _ax neg 0 rmoveto
- _hyphen Tx
-} def
-/T+
-{
-} def
-/TR
-{
- _ctm currentmatrix pop
- _tm astore pop
- iTm 0 0 moveto
-} def
-/TS
-{
- currentfont 3 1 roll
- /_Symbol_ _fScl 1000 mul selectfont
-
- 0 eq
- {
- Tx
- }
- {
- Tj
- } ifelse
- setfont
-} def
-/Xb
-{
- pop pop
-} def
-/Tb /Xb load def
-/Xe
-{
- pop pop pop pop
-} def
-/Te /Xe load def
-/XB
-{
-} def
-/TB /XB load def
-currentdict readonly pop
-end
-setpacking
-%%EndResource
-%%BeginProcSet: Adobe_ColorImage_AI6 1.0 0
-userdict /Adobe_ColorImage_AI6 known not
-{
- userdict /Adobe_ColorImage_AI6 17 dict put
-} if
-userdict /Adobe_ColorImage_AI6 get begin
-
- /initialize
- {
- Adobe_ColorImage_AI6 begin
- Adobe_ColorImage_AI6
- {
- dup type /arraytype eq
- {
- dup xcheck
- {
- bind
- } if
- } if
- pop pop
- } forall
- } def
- /terminate { end } def
-
- currentdict /Adobe_ColorImage_AI6_Vars known not
- {
- /Adobe_ColorImage_AI6_Vars 14 dict def
- } if
-
- Adobe_ColorImage_AI6_Vars begin
- /channelcount 0 def
- /sourcecount 0 def
- /sourcearray 4 array def
- /plateindex -1 def
- /XIMask 0 def
- /XIBinary 0 def
- /XIChannelCount 0 def
- /XIBitsPerPixel 0 def
- /XIImageHeight 0 def
- /XIImageWidth 0 def
- /XIImageMatrix null def
- /XIBuffer null def
- /XIDataProc null def
- end
-
- /WalkRGBString null def
- /WalkCMYKString null def
-
- /StuffRGBIntoGrayString null def
- /RGBToGrayImageProc null def
- /StuffCMYKIntoGrayString null def
- /CMYKToGrayImageProc null def
- /ColorImageCompositeEmulator null def
-
- /SeparateCMYKImageProc null def
-
- /FourEqual null def
- /TestPlateIndex null def
-
- currentdict /_colorimage known not
- {
- /colorimage where
- {
- /colorimage get /_colorimage exch def
- }
- {
- /_colorimage null def
- } ifelse
- } if
-
- /_currenttransfer systemdict /currenttransfer get def
-
- /colorimage null def
- /XI null def
-
-
- /WalkRGBString
- {
- 0 3 index
-
- dup length 1 sub 0 3 3 -1 roll
- {
- 3 getinterval { } forall
-
- 5 index exec
-
- 3 index
- } for
-
- 5 { pop } repeat
-
- } def
-
-
- /WalkCMYKString
- {
- 0 3 index
-
- dup length 1 sub 0 4 3 -1 roll
- {
- 4 getinterval { } forall
-
- 6 index exec
-
- 3 index
-
- } for
-
- 5 { pop } repeat
-
- } def
-
-
- /StuffRGBIntoGrayString
- {
- .11 mul exch
-
- .59 mul add exch
-
- .3 mul add
-
- cvi 3 copy put
-
- pop 1 add
- } def
-
-
- /RGBToGrayImageProc
- {
- Adobe_ColorImage_AI6_Vars begin
- sourcearray 0 get exec
- dup length 3 idiv string
- dup 3 1 roll
-
- /StuffRGBIntoGrayString load exch
- WalkRGBString
- end
- } def
-
-
- /StuffCMYKIntoGrayString
- {
- exch .11 mul add
-
- exch .59 mul add
-
- exch .3 mul add
-
- dup 255 gt { pop 255 } if
-
- 255 exch sub cvi 3 copy put
-
- pop 1 add
- } def
-
-
- /CMYKToGrayImageProc
- {
- Adobe_ColorImage_AI6_Vars begin
- sourcearray 0 get exec
- dup length 4 idiv string
- dup 3 1 roll
-
- /StuffCMYKIntoGrayString load exch
- WalkCMYKString
- end
- } def
-
-
- /ColorImageCompositeEmulator
- {
- pop true eq
- {
- Adobe_ColorImage_AI6_Vars /sourcecount get 5 add { pop } repeat
- }
- {
- Adobe_ColorImage_AI6_Vars /channelcount get 1 ne
- {
- Adobe_ColorImage_AI6_Vars begin
- sourcearray 0 3 -1 roll put
-
- channelcount 3 eq
- {
- /RGBToGrayImageProc
- }
- {
- /CMYKToGrayImageProc
- } ifelse
- load
- end
- } if
- image
- } ifelse
- } def
-
-
- /SeparateCMYKImageProc
- {
- Adobe_ColorImage_AI6_Vars begin
-
- sourcecount 0 ne
- {
- sourcearray plateindex get exec
- }
- {
- sourcearray 0 get exec
-
- dup length 4 idiv string
-
- 0 2 index
-
- plateindex 4 2 index length 1 sub
- {
- get 255 exch sub
-
- 3 copy put pop 1 add
-
- 2 index
- } for
-
- pop pop exch pop
- } ifelse
- end
- } def
-
-
- /FourEqual
- {
- 4 index ne
- {
- pop pop pop false
- }
- {
- 4 index ne
- {
- pop pop false
- }
- {
- 4 index ne
- {
- pop false
- }
- {
- 4 index eq
- } ifelse
- } ifelse
- } ifelse
- } def
-
-
- /TestPlateIndex
- {
- Adobe_ColorImage_AI6_Vars begin
- /plateindex -1 def
-
- /setcmykcolor where
- {
- pop
- gsave
- 1 0 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
- 0 1 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
- 0 0 1 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
- 0 0 0 1 setcmykcolor systemdict /currentgray get exec 1 exch sub
- grestore
-
- 1 0 0 0 FourEqual
- {
- /plateindex 0 def
- }
- {
- 0 1 0 0 FourEqual
- {
- /plateindex 1 def
- }
- {
- 0 0 1 0 FourEqual
- {
- /plateindex 2 def
- }
- {
- 0 0 0 1 FourEqual
- {
- /plateindex 3 def
- }
- {
- 0 0 0 0 FourEqual
- {
- /plateindex 5 def
- } if
- } ifelse
- } ifelse
- } ifelse
- } ifelse
- pop pop pop pop
- } if
- plateindex
- end
- } def
-
-
- /colorimage
- {
- Adobe_ColorImage_AI6_Vars begin
- /channelcount 1 index def
- /sourcecount 2 index 1 eq { channelcount 1 sub } { 0 } ifelse def
-
- 4 sourcecount add index dup
- 8 eq exch 1 eq or not
- end
-
- {
- /_colorimage load null ne
- {
- _colorimage
- }
- {
- Adobe_ColorImage_AI6_Vars /sourcecount get
- 7 add { pop } repeat
- } ifelse
- }
- {
- dup 3 eq
- TestPlateIndex
- dup -1 eq exch 5 eq or or
- {
- /_colorimage load null eq
- {
- ColorImageCompositeEmulator
- }
- {
- dup 1 eq
- {
- pop pop image
- }
- {
- Adobe_ColorImage_AI6_Vars /plateindex get 5 eq
- {
- gsave
-
- 0 _currenttransfer exec
- 1 _currenttransfer exec
- eq
- { 0 _currenttransfer exec 0.5 lt }
- { 0 _currenttransfer exec 1 _currenttransfer exec gt } ifelse
-
- { { pop 0 } } { { pop 1 } } ifelse
- systemdict /settransfer get exec
- } if
-
- _colorimage
-
- Adobe_ColorImage_AI6_Vars /plateindex get 5 eq
- {
- grestore
- } if
- } ifelse
- } ifelse
- }
- {
- dup 1 eq
- {
- pop pop
- image
- }
- {
- pop pop
-
- Adobe_ColorImage_AI6_Vars begin
- sourcecount -1 0
- {
- exch sourcearray 3 1 roll put
- } for
-
- /SeparateCMYKImageProc load
- end
-
- systemdict /image get exec
- } ifelse
- } ifelse
- } ifelse
- } def
-
- /XI
- {
- Adobe_ColorImage_AI6_Vars begin
- gsave
- /XIMask exch 0 ne def
- /XIBinary exch 0 ne def
- pop
- pop
- /XIChannelCount exch def
- /XIBitsPerPixel exch def
- /XIImageHeight exch def
- /XIImageWidth exch def
- pop pop pop pop
- /XIImageMatrix exch def
-
- XIBitsPerPixel 1 eq
- {
- XIImageWidth 8 div ceiling cvi
- }
- {
- XIImageWidth XIChannelCount mul
- } ifelse
- /XIBuffer exch string def
-
- XIBinary
- {
- /XIDataProc { currentfile XIBuffer readstring pop } def
- currentfile 128 string readline pop pop
- }
- {
- /XIDataProc { currentfile XIBuffer readhexstring pop } def
- } ifelse
-
- 0 0 moveto
- XIImageMatrix concat
- XIImageWidth XIImageHeight scale
-
- XIMask
- {
- XIImageWidth XIImageHeight
- false
- [ XIImageWidth 0 0 XIImageHeight neg 0 0 ]
- /XIDataProc load
-
- /_lp /null ddef
- _fc
- /_lp /imagemask ddef
-
- imagemask
- }
- {
- XIImageWidth XIImageHeight
- XIBitsPerPixel
- [ XIImageWidth 0 0 XIImageHeight neg 0 0 ]
- /XIDataProc load
-
- XIChannelCount 1 eq
- {
-
- gsave
- 0 setgray
-
- image
-
- grestore
- }
- {
- false
- XIChannelCount
- colorimage
- } ifelse
- } ifelse
- grestore
- end
- } def
-
-end
-%%EndProcSet
-%%BeginResource: procset Adobe_Illustrator_AI5 1.1 0
-%%Title: (Adobe Illustrator (R) Version 5.0 Full Prolog)
-%%Version: 1.1
-%%CreationDate: (3/7/1994) ()
-%%Copyright: ((C) 1987-1994 Adobe Systems Incorporated All Rights Reserved)
-currentpacking true setpacking
-userdict /Adobe_Illustrator_AI5_vars 81 dict dup begin
-put
-/_eo false def
-/_lp /none def
-/_pf
-{
-} def
-/_ps
-{
-} def
-/_psf
-{
-} def
-/_pss
-{
-} def
-/_pjsf
-{
-} def
-/_pjss
-{
-} def
-/_pola 0 def
-/_doClip 0 def
-/cf currentflat def
-/_tm matrix def
-/_renderStart
-[
-/e0 /r0 /a0 /o0 /e1 /r1 /a1 /i0
-] def
-/_renderEnd
-[
-null null null null /i1 /i1 /i1 /i1
-] def
-/_render -1 def
-/_rise 0 def
-/_ax 0 def
-/_ay 0 def
-/_cx 0 def
-/_cy 0 def
-/_leading
-[
-0 0
-] def
-/_ctm matrix def
-/_mtx matrix def
-/_sp 16#020 def
-/_hyphen (-) def
-/_fScl 0 def
-/_cnt 0 def
-/_hs 1 def
-/_nativeEncoding 0 def
-/_useNativeEncoding 0 def
-/_tempEncode 0 def
-/_pntr 0 def
-/_tDict 2 dict def
-/_wv 0 def
-/Tx
-{
-} def
-/Tj
-{
-} def
-/CRender
-{
-} def
-/_AI3_savepage
-{
-} def
-/_gf null def
-/_cf 4 array def
-/_if null def
-/_of false def
-/_fc
-{
-} def
-/_gs null def
-/_cs 4 array def
-/_is null def
-/_os false def
-/_sc
-{
-} def
-/_pd 1 dict def
-/_ed 15 dict def
-/_pm matrix def
-/_fm null def
-/_fd null def
-/_fdd null def
-/_sm null def
-/_sd null def
-/_sdd null def
-/_i null def
-/discardSave null def
-/buffer 256 string def
-/beginString null def
-/endString null def
-/endStringLength null def
-/layerCnt 1 def
-/layerCount 1 def
-/perCent (%) 0 get def
-/perCentSeen? false def
-/newBuff null def
-/newBuffButFirst null def
-/newBuffLast null def
-/clipForward? false def
-end
-userdict /Adobe_Illustrator_AI5 known not {
- userdict /Adobe_Illustrator_AI5 91 dict put
-} if
-userdict /Adobe_Illustrator_AI5 get begin
-/initialize
-{
- Adobe_Illustrator_AI5 dup begin
- Adobe_Illustrator_AI5_vars begin
- discardDict
- {
- bind pop pop
- } forall
- dup /nc get begin
- {
- dup xcheck 1 index type /operatortype ne and
- {
- bind
- } if
- pop pop
- } forall
- end
- newpath
-} def
-/terminate
-{
- end
- end
-} def
-/_
-null def
-/ddef
-{
- Adobe_Illustrator_AI5_vars 3 1 roll put
-} def
-/xput
-{
- dup load dup length exch maxlength eq
- {
- dup dup load dup
- length 2 mul dict copy def
- } if
- load begin
- def
- end
-} def
-/npop
-{
- {
- pop
- } repeat
-} def
-/sw
-{
- dup length exch stringwidth
- exch 5 -1 roll 3 index mul add
- 4 1 roll 3 1 roll mul add
-} def
-/swj
-{
- dup 4 1 roll
- dup length exch stringwidth
- exch 5 -1 roll 3 index mul add
- 4 1 roll 3 1 roll mul add
- 6 2 roll /_cnt 0 ddef
- {
- 1 index eq
- {
- /_cnt _cnt 1 add ddef
- } if
- } forall
- pop
- exch _cnt mul exch _cnt mul 2 index add 4 1 roll 2 index add 4 1 roll pop pop
-} def
-/ss
-{
- 4 1 roll
- {
- 2 npop
- (0) exch 2 copy 0 exch put pop
- gsave
- false charpath currentpoint
- 4 index setmatrix
- stroke
- grestore
- moveto
- 2 copy rmoveto
- } exch cshow
- 3 npop
-} def
-/jss
-{
- 4 1 roll
- {
- 2 npop
- (0) exch 2 copy 0 exch put
- gsave
- _sp eq
- {
- exch 6 index 6 index 6 index 5 -1 roll widthshow
- currentpoint
- }
- {
- false charpath currentpoint
- 4 index setmatrix stroke
- } ifelse
- grestore
- moveto
- 2 copy rmoveto
- } exch cshow
- 6 npop
-} def
-/sp
-{
- {
- 2 npop (0) exch
- 2 copy 0 exch put pop
- false charpath
- 2 copy rmoveto
- } exch cshow
- 2 npop
-} def
-/jsp
-{
- {
- 2 npop
- (0) exch 2 copy 0 exch put
- _sp eq
- {
- exch 5 index 5 index 5 index 5 -1 roll widthshow
- }
- {
- false charpath
- } ifelse
- 2 copy rmoveto
- } exch cshow
- 5 npop
-} def
-/pl
-{
- transform
- 0.25 sub round 0.25 add exch
- 0.25 sub round 0.25 add exch
- itransform
-} def
-/setstrokeadjust where
-{
- pop true setstrokeadjust
- /c
- {
- curveto
- } def
- /C
- /c load def
- /v
- {
- currentpoint 6 2 roll curveto
- } def
- /V
- /v load def
- /y
- {
- 2 copy curveto
- } def
- /Y
- /y load def
- /l
- {
- lineto
- } def
- /L
- /l load def
- /m
- {
- moveto
- } def
-}
-{
- /c
- {
- pl curveto
- } def
- /C
- /c load def
- /v
- {
- currentpoint 6 2 roll pl curveto
- } def
- /V
- /v load def
- /y
- {
- pl 2 copy curveto
- } def
- /Y
- /y load def
- /l
- {
- pl lineto
- } def
- /L
- /l load def
- /m
- {
- pl moveto
- } def
-} ifelse
-/d
-{
- setdash
-} def
-/cf
-{
-} def
-/i
-{
- dup 0 eq
- {
- pop cf
- } if
- setflat
-} def
-/j
-{
- setlinejoin
-} def
-/J
-{
- setlinecap
-} def
-/M
-{
- setmiterlimit
-} def
-/w
-{
- setlinewidth
-} def
-/XR
-{
- 0 ne
- /_eo exch ddef
-} def
-/H
-{
-} def
-/h
-{
- closepath
-} def
-/N
-{
- _pola 0 eq
- {
- _doClip 1 eq
- {
- _eo {eoclip} {clip} ifelse /_doClip 0 ddef
- } if
- newpath
- }
- {
- /CRender
- {
- N
- } ddef
- } ifelse
-} def
-/n
-{
- N
-} def
-/F
-{
- _pola 0 eq
- {
- _doClip 1 eq
- {
- gsave _pf grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _fc
- /_doClip 0 ddef
- }
- {
- _pf
- } ifelse
- }
- {
- /CRender
- {
- F
- } ddef
- } ifelse
-} def
-/f
-{
- closepath
- F
-} def
-/S
-{
- _pola 0 eq
- {
- _doClip 1 eq
- {
- gsave _ps grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
- /_doClip 0 ddef
- }
- {
- _ps
- } ifelse
- }
- {
- /CRender
- {
- S
- } ddef
- } ifelse
-} def
-/s
-{
- closepath
- S
-} def
-/B
-{
- _pola 0 eq
- {
- _doClip 1 eq
- gsave F grestore
- {
- gsave S grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
- /_doClip 0 ddef
- }
- {
- S
- } ifelse
- }
- {
- /CRender
- {
- B
- } ddef
- } ifelse
-} def
-/b
-{
- closepath
- B
-} def
-/W
-{
- /_doClip 1 ddef
-} def
-/*
-{
- count 0 ne
- {
- dup type /stringtype eq
- {
- pop
- } if
- } if
- newpath
-} def
-/u
-{
-} def
-/U
-{
-} def
-/q
-{
- _pola 0 eq
- {
- gsave
- } if
-} def
-/Q
-{
- _pola 0 eq
- {
- grestore
- } if
-} def
-/*u
-{
- _pola 1 add /_pola exch ddef
-} def
-/*U
-{
- _pola 1 sub /_pola exch ddef
- _pola 0 eq
- {
- CRender
- } if
-} def
-/D
-{
- pop
-} def
-/*w
-{
-} def
-/*W
-{
-} def
-/`
-{
- /_i save ddef
- clipForward?
- {
- nulldevice
- } if
- 6 1 roll 4 npop
- concat pop
- userdict begin
- /showpage
- {
- } def
- 0 setgray
- 0 setlinecap
- 1 setlinewidth
- 0 setlinejoin
- 10 setmiterlimit
- [] 0 setdash
- /setstrokeadjust where {pop false setstrokeadjust} if
- newpath
- 0 setgray
- false setoverprint
-} def
-/~
-{
- end
- _i restore
-} def
-/O
-{
- 0 ne
- /_of exch ddef
- /_lp /none ddef
-} def
-/R
-{
- 0 ne
- /_os exch ddef
- /_lp /none ddef
-} def
-/g
-{
- /_gf exch ddef
- /_fc
- {
- _lp /fill ne
- {
- _of setoverprint
- _gf setgray
- /_lp /fill ddef
- } if
- } ddef
- /_pf
- {
- _fc
- _eo {eofill} {fill} ifelse
- } ddef
- /_psf
- {
- _fc
- ashow
- } ddef
- /_pjsf
- {
- _fc
- awidthshow
- } ddef
- /_lp /none ddef
-} def
-/G
-{
- /_gs exch ddef
- /_sc
- {
- _lp /stroke ne
- {
- _os setoverprint
- _gs setgray
- /_lp /stroke ddef
- } if
- } ddef
- /_ps
- {
- _sc
- stroke
- } ddef
- /_pss
- {
- _sc
- ss
- } ddef
- /_pjss
- {
- _sc
- jss
- } ddef
- /_lp /none ddef
-} def
-/k
-{
- _cf astore pop
- /_fc
- {
- _lp /fill ne
- {
- _of setoverprint
- _cf aload pop setcmykcolor
- /_lp /fill ddef
- } if
- } ddef
- /_pf
- {
- _fc
- _eo {eofill} {fill} ifelse
- } ddef
- /_psf
- {
- _fc
- ashow
- } ddef
- /_pjsf
- {
- _fc
- awidthshow
- } ddef
- /_lp /none ddef
-} def
-/K
-{
- _cs astore pop
- /_sc
- {
- _lp /stroke ne
- {
- _os setoverprint
- _cs aload pop setcmykcolor
- /_lp /stroke ddef
- } if
- } ddef
- /_ps
- {
- _sc
- stroke
- } ddef
- /_pss
- {
- _sc
- ss
- } ddef
- /_pjss
- {
- _sc
- jss
- } ddef
- /_lp /none ddef
-} def
-/x
-{
- /_gf exch ddef
- findcmykcustomcolor
- /_if exch ddef
- /_fc
- {
- _lp /fill ne
- {
- _of setoverprint
- _if _gf 1 exch sub setcustomcolor
- /_lp /fill ddef
- } if
- } ddef
- /_pf
- {
- _fc
- _eo {eofill} {fill} ifelse
- } ddef
- /_psf
- {
- _fc
- ashow
- } ddef
- /_pjsf
- {
- _fc
- awidthshow
- } ddef
- /_lp /none ddef
-} def
-/X
-{
- /_gs exch ddef
- findcmykcustomcolor
- /_is exch ddef
- /_sc
- {
- _lp /stroke ne
- {
- _os setoverprint
- _is _gs 1 exch sub setcustomcolor
- /_lp /stroke ddef
- } if
- } ddef
- /_ps
- {
- _sc
- stroke
- } ddef
- /_pss
- {
- _sc
- ss
- } ddef
- /_pjss
- {
- _sc
- jss
- } ddef
- /_lp /none ddef
-} def
-/A
-{
- pop
-} def
-/annotatepage
-{
-userdict /annotatepage 2 copy known {get exec} {pop pop} ifelse
-} def
-/XT {
- pop pop
-} def
-/discard
-{
- save /discardSave exch store
- discardDict begin
- /endString exch store
- gt38?
- {
- 2 add
- } if
- load
- stopped
- pop
- end
- discardSave restore
-} bind def
-userdict /discardDict 7 dict dup begin
-put
-/pre38Initialize
-{
- /endStringLength endString length store
- /newBuff buffer 0 endStringLength getinterval store
- /newBuffButFirst newBuff 1 endStringLength 1 sub getinterval store
- /newBuffLast newBuff endStringLength 1 sub 1 getinterval store
-} def
-/shiftBuffer
-{
- newBuff 0 newBuffButFirst putinterval
- newBuffLast 0
- currentfile read not
- {
- stop
- } if
- put
-} def
-0
-{
- pre38Initialize
- mark
- currentfile newBuff readstring exch pop
- {
- {
- newBuff endString eq
- {
- cleartomark stop
- } if
- shiftBuffer
- } loop
- }
- {
- stop
- } ifelse
-} def
-1
-{
- pre38Initialize
- /beginString exch store
- mark
- currentfile newBuff readstring exch pop
- {
- {
- newBuff beginString eq
- {
- /layerCount dup load 1 add store
- }
- {
- newBuff endString eq
- {
- /layerCount dup load 1 sub store
- layerCount 0 eq
- {
- cleartomark stop
- } if
- } if
- } ifelse
- shiftBuffer
- } loop
- } if
-} def
-2
-{
- mark
- {
- currentfile buffer readline not
- {
- stop
- } if
- endString eq
- {
- cleartomark stop
- } if
- } loop
-} def
-3
-{
- /beginString exch store
- /layerCnt 1 store
- mark
- {
- currentfile buffer readline not
- {
- stop
- } if
- dup beginString eq
- {
- pop /layerCnt dup load 1 add store
- }
- {
- endString eq
- {
- layerCnt 1 eq
- {
- cleartomark stop
- }
- {
- /layerCnt dup load 1 sub store
- } ifelse
- } if
- } ifelse
- } loop
-} def
-end
-userdict /clipRenderOff 15 dict dup begin
-put
-{
- /n /N /s /S /f /F /b /B
-}
-{
- {
- _doClip 1 eq
- {
- /_doClip 0 ddef _eo {eoclip} {clip} ifelse
- } if
- newpath
- } def
-} forall
-/Tr /pop load def
-/Bb {} def
-/BB /pop load def
-/Bg {12 npop} def
-/Bm {6 npop} def
-/Bc /Bm load def
-/Bh {4 npop} def
-end
-/Lb
-{
- 4 npop
- 6 1 roll
- pop
- 4 1 roll
- pop pop pop
- 0 eq
- {
- 0 eq
- {
- (%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard
- }
- {
-
- /clipForward? true def
-
- /Tx /pop load def
- /Tj /pop load def
-
- currentdict end clipRenderOff begin begin
- } ifelse
- }
- {
- 0 eq
- {
- save /discardSave exch store
- } if
- } ifelse
-} bind def
-/LB
-{
- discardSave dup null ne
- {
- restore
- }
- {
- pop
- clipForward?
- {
- currentdict
- end
- end
- begin
-
- /clipForward? false ddef
- } if
- } ifelse
-} bind def
-/Pb
-{
- pop pop
- 0 (%AI5_EndPalette) discard
-} bind def
-/Np
-{
- 0 (%AI5_End_NonPrinting--) discard
-} bind def
-/Ln /pop load def
-/Ap
-/pop load def
-/Ar
-{
- 72 exch div
- 0 dtransform dup mul exch dup mul add sqrt
- dup 1 lt
- {
- pop 1
- } if
- setflat
-} def
-/Mb
-{
- q
-} def
-/Md
-{
-} def
-/MB
-{
- Q
-} def
-/nc 3 dict def
-nc begin
-/setgray
-{
- pop
-} bind def
-/setcmykcolor
-{
- 4 npop
-} bind def
-/setcustomcolor
-{
- 2 npop
-} bind def
-currentdict readonly pop
-end
-end
-setpacking
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeFont: Geneva
-%%IncludeFont: Univers
-Adobe_level2_AI5 /initialize get exec
-Adobe_Illustrator_AI5_vars Adobe_Illustrator_AI5 Adobe_typography_AI5 /initialize get exec
-Adobe_ColorImage_AI6 /initialize get exec
-Adobe_Illustrator_AI5 /initialize get exec
-[
-39/quotesingle 96/grave 128/Adieresis/Aring/Ccedilla/Eacute/Ntilde/Odieresis
-/Udieresis/aacute/agrave/acircumflex/adieresis/atilde/aring/ccedilla/eacute
-/egrave/ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis/ntilde
-/oacute/ograve/ocircumflex/odieresis/otilde/uacute/ugrave/ucircumflex
-/udieresis/dagger/degree/cent/sterling/section/bullet/paragraph/germandbls
-/registered/copyright/trademark/acute/dieresis/.notdef/AE/Oslash
-/.notdef/plusminus/.notdef/.notdef/yen/mu/.notdef/.notdef
-/.notdef/.notdef/.notdef/ordfeminine/ordmasculine/.notdef/ae/oslash
-/questiondown/exclamdown/logicalnot/.notdef/florin/.notdef/.notdef
-/guillemotleft/guillemotright/ellipsis/.notdef/Agrave/Atilde/Otilde/OE/oe
-/endash/emdash/quotedblleft/quotedblright/quoteleft/quoteright/divide
-/.notdef/ydieresis/Ydieresis/fraction/currency/guilsinglleft/guilsinglright
-/fi/fl/daggerdbl/periodcentered/quotesinglbase/quotedblbase/perthousand
-/Acircumflex/Ecircumflex/Aacute/Edieresis/Egrave/Iacute/Icircumflex
-/Idieresis/Igrave/Oacute/Ocircumflex/.notdef/Ograve/Uacute/Ucircumflex
-/Ugrave/dotlessi/circumflex/tilde/macron/breve/dotaccent/ring/cedilla
-/hungarumlaut/ogonek/caron
-TE
-%AI3_BeginEncoding: _Geneva Geneva
-[/_Geneva/Geneva 0 0 0 TZ
-%AI3_EndEncoding TrueType
-%AI3_BeginEncoding: _Univers Univers
-[/_Univers/Univers 0 0 1 TZ
-%AI3_EndEncoding AdobeType
-%AI5_Begin_NonPrinting
-Np
-8 Bn
-%AI5_BeginGradient: (Black & White)
-(Black & White) 0 2 Bd
-[
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0 %_Br
-[
-0 0 50 100 %_Bs
-1 0 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Green & Blue)
-(Green & Blue) 0 2 Bd
-[
-<
-99999A9A9B9B9B9C9C9D9D9D9E9E9F9F9FA0A0A1A1A1A2A2A3A3A3A4A4A5A5A5A6A6A7A7A7A8A8A9
-A9A9AAAAABABABACACADADADAEAEAFAFAFB0B0B1B1B1B2B2B3B3B3B4B4B5B5B5B6B6B7B7B7B8B8B9
-B9B9BABABBBBBBBCBCBDBDBDBEBEBFBFBFC0C0C1C1C1C2C2C3C3C3C4C4C5C5C5C6C6C7C7C7C8C8C9
-C9C9CACACBCBCBCCCCCDCDCDCECECFCFCFD0D0D1D1D1D2D2D3D3D3D4D4D5D5D5D6D6D7D7D7D8D8D9
-D9D9DADADBDBDBDCDCDDDDDDDEDEDFDFDFE0E0E1E1E1E2E2E3E3E3E4E4E5E5E5E6E6E7E7E7E8E8E9
-E9E9EAEAEBEBEBECECEDEDEDEEEEEFEFEFF0F0F1F1F1F2F2F3F3F3F4F4F5F5F5F6F6F7F7F7F8F8F9
-F9F9FAFAFBFBFBFCFCFDFDFDFEFEFFFF
->
-<
-000102020304050506070808090A0B0B0C0D0E0E0F101111121314141516171718191A1A1B1C1D1D
-1E1F20202122232324252626272829292A2B2C2C2D2E2F2F303132323334353536373838393A3B3B
-3C3D3E3E3F404141424344444546474748494A4A4B4C4D4D4E4F5050515253535455565657585959
-5A5B5C5C5D5E5F5F606162626364656566676868696A6B6B6C6D6E6E6F7071717273747475767777
-78797A7A7B7C7D7D7E7F80808182828384858586878888898A8B8B8C8D8E8E8F9091919293949495
-96979798999A9A9B9C9D9D9E9FA0A0A1A2A3A3A4A5A6A6A7A8A9A9AAABACACADAEAFAFB0B1B2B2B3
-B4B5B5B6B7B8B8B9BABBBBBCBDBEBEBF
->
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0
-1 %_Br
-[
-1 0.75 0 0 1 50 100 %_Bs
-0.6 0 1 0 1 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Pink, Yellow, Green)
-(Pink, Yellow, Green) 0 3 Bd
-[
-<
-00000000000000000000000000000000000000010101010101010101010101010101010101010101
-01010101010202020202020202020202020202020202020202020203030303030303030303030303
-03030303030303030404040404040404040404040404040404040404050505050505050505050505
-05050505050505060606060606060606060606060606060606060707070707070707070707070707
-07070707080808080808080808080808080808080809090909090909090909090909090909090A0A
-0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0C0C0C0C0C0C0C0C0C
-0C0C0C0C0C0C0C0D0D0D0D0D
->
-<
-050506060606070708080809090A0A0A0B0B0C0C0D0D0E0E0F0F1010111112121313141415151617
-17181819191A1A1B1C1C1D1D1E1F1F202021222223232425252626272828292A2A2B2C2C2D2D2E2F
-2F3031313233333435353637373839393A3B3B3C3D3E3E3F4040414242434445454647474849494A
-4B4C4C4D4E4F4F505151525354545556575758595A5A5B5C5C5D5E5F5F6061626363646566666768
-69696A6B6C6C6D6E6F707071727373747576777778797A7B7B7C7D7E7F7F80818283838485868787
-88898A8B8B8C8D8E8F8F9091929394949596979898999A9B9C9D9D9E9FA0A1A2A2A3A4A5A6A7A7A8
-A9AAABACADADAEAFB0B1B2B2
->
-<
-CCCCCBCBCBCACACAC9C9C8C8C7C7C6C6C5C5C4C4C3C2C2C1C1C0C0BFBEBEBDBDBCBBBBBAB9B9B8B7
-B7B6B6B5B4B4B3B2B1B1B0AFAFAEADADACABAAAAA9A8A8A7A6A5A5A4A3A2A2A1A0A09F9E9D9C9C9B
-9A999998979696959493929291908F8E8E8D8C8B8A8A8988878686858483828181807F7E7D7C7C7B
-7A7978777776757473727171706F6E6D6C6B6A6A69686766656463636261605F5E5D5C5B5B5A5958
-5756555453525151504F4E4D4C4B4A49484746464544434241403F3E3D3C3B3A3938383736353433
-3231302F2E2D2C2B2A29282726252423222221201F1E1D1C1B1A191817161514131211100F0E0D0C
-0B0A09080706050403020100
->
-0
-1 %_Br
-<
-737271706F6E6D6C6B6A696867666564636261605F5E5D5C5B5B5A59585756555453525150504F4E
-4D4C4B4A4949484746454443434241403F3E3E3D3C3B3A3A393837363635343333323130302F2E2D
-2D2C2B2A2A29282827262525242323222121201F1F1E1D1D1C1C1B1A1A1918181717161615141413
-1312121111100F0F0E0E0D0D0C0C0C0B0B0A0A090908080807070606060505050404040303030202
-020201010101010000000000
->
-<
-00000000000000000000000001010101010101010101010101010101010101010101010102020202
-02020202020202020202020202020202020202020202030303030303030303030303030303030303
-03030303030303030303030303040404040404040404040404040404040404040404040404040404
-04040404040404040404050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505
->
-<
-BFBFBFC0C0C0C0C0C0C0C0C0C1C1C1C1C1C1C1C1C1C2C2C2C2C2C2C2C2C2C2C3C3C3C3C3C3C3C3C3
-C3C4C4C4C4C4C4C4C4C4C4C5C5C5C5C5C5C5C5C5C5C5C6C6C6C6C6C6C6C6C6C6C6C6C7C7C7C7C7C7
-C7C7C7C7C7C7C8C8C8C8C8C8C8C8C8C8C8C8C8C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9CACACACACACA
-CACACACACACACACACACACBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCCCCCCCCCCCCCCCC
-CCCCCCCCCCCCCCCCCCCCCCCC
->
-0
-1 %_Br
-[
-0.05 0.7 0 0 1 50 100 %_Bs
-0 0.02 0.8 0 1 57 36 %_Bs
-0.45 0 0.75 0 1 37 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Purple, Red & Yellow)
-(Purple, Red & Yellow) 0 3 Bd
-[
-0
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A
->
-<
-CCCCCCCDCDCDCDCDCECECECECECFCFCFCFD0D0D0D0D0D1D1D1D1D1D2D2D2D2D2D3D3D3D3D3D4D4D4
-D4D5D5D5D5D5D6D6D6D6D6D7D7D7D7D7D8D8D8D8D8D9D9D9D9DADADADADADBDBDBDBDBDCDCDCDCDC
-DDDDDDDDDDDEDEDEDEDFDFDFDFDFE0E0E0E0E0E1E1E1E1E1E2E2E2E2E2E3E3E3E3E4E4E4E4E4E5E5
-E5E5E5E6E6E6E6E6E7E7E7E7E7E8E8E8E8E9E9E9E9E9EAEAEAEAEAEBEBEBEBEBECECECECECEDEDED
-EDEEEEEEEEEEEFEFEFEFEFF0F0F0F0F0F1F1F1F1F1F2F2F2F2F3F3F3F3F3F4F4F4F4F4F5F5F5F5F5
-F6F6F6F6F6F7F7F7F7F8F8F8F8F8F9F9F9F9F9FAFAFAFAFAFBFBFBFBFBFCFCFCFCFDFDFDFDFDFEFE
-FEFEFEFFFFFF
->
-0
-1 %_Br
-<
-E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBE
-BDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A99989796
-9594939291908F8E8D8C8B8A898887868584838281807F7E7D7C7B7A797877767574737271706F6E
-6D6C6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746
-4544434241403F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E
-1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100
->
-<
-E5E6E6E6E6E6E6E6E6E7E7E7E7E7E7E7E7E7E8E8E8E8E8E8E8E8E8E9E9E9E9E9E9E9E9E9EAEAEAEA
-EAEAEAEAEAEBEBEBEBEBEBEBEBEBECECECECECECECECECEDEDEDEDEDEDEDEDEDEEEEEEEEEEEEEEEE
-EEEFEFEFEFEFEFEFEFEFF0F0F0F0F0F0F0F0F0F1F1F1F1F1F1F1F1F1F2F2F2F2F2F2F2F2F2F3F3F3
-F3F3F3F3F3F3F4F4F4F4F4F4F4F4F4F5F5F5F5F5F5F5F5F5F6F6F6F6F6F6F6F6F6F7F7F7F7F7F7F7
-F7F7F8F8F8F8F8F8F8F8F8F9F9F9F9F9F9F9F9F9FAFAFAFAFAFAFAFAFAFBFBFBFBFBFBFBFBFBFCFC
-FCFCFCFCFCFCFCFDFDFDFDFDFDFDFDFDFEFEFEFEFEFEFEFEFEFFFFFFFFFF
->
-<
-00010203040405060708090A0B0C0C0D0E0F10111213141415161718191A1B1C1D1D1E1F20212223
-242525262728292A2B2C2D2D2E2F30313233343535363738393A3B3C3D3D3E3F4041424344454546
-4748494A4B4C4D4E4E4F50515253545556565758595A5B5C5D5E5E5F60616263646566666768696A
-6B6C6D6E6E6F70717273747576767778797A7B7C7D7E7F7F80818283848586878788898A8B8C8D8E
-8F8F90919293949596979798999A9B9C9D9E9F9FA0A1A2A3A4A5A6A7A7A8A9AAABACADAEAFAFB0B1
-B2B3B4B5B6B7B8B8B9BABBBCBDBEBFC0C0C1C2C3C4C5C6C7C8C8C9CACBCC
->
-0
-1 %_Br
-[
-0 0.04 1 0 1 50 100 %_Bs
-0 1 0.8 0 1 50 50 %_Bs
-0.9 0.9 0 0 1 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Rainbow)
-(Rainbow) 0 6 Bd
-[
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-1
-0
-0
-1 %_Br
-1
-<
-0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E
-2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556
-5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E
-7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6
-A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE
-CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6
-F7F8F9FAFBFCFDFEFF
->
-0
-0
-1 %_Br
-1
-<
-00000000000000000000000000000000000001010101010101010101010101010101010101010101
-01010101010101010101010101010202020202020202020202020202020202020202020202020202
-02020202020202020202030303030303030303030303030303030303030303030303030303030303
-03030303030304040404040404040404040404040404040404040404040404040404040404040404
-04040505050505050505050505050505050505050505050505050505050505050505050505050606
-06060606060606060606060606060606060606060606060606060606060606060606070707070707
-07070707070707070707070707070707
->
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0
-1 %_Br
-<
-000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
-28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
-505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
-78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
-A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
-C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
-F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
->
-0
-1
-0
-1 %_Br
-0
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-1
-0
-1 %_Br
-[
-0 1 0 0 1 50 100 %_Bs
-1 1 0 0 1 50 80 %_Bs
-1 0.0279 0 0 1 50 60 %_Bs
-1 0 1 0 1 50 40 %_Bs
-0 0 1 0 1 50 20 %_Bs
-0 1 1 0 1 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Steel Bar)
-(Steel Bar) 0 3 Bd
-[
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0 %_Br
-<
-000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
-28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
-505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
-78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
-A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
-C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
-F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
->
-0 %_Br
-[
-0 0 50 100 %_Bs
-1 0 50 70 %_Bs
-0 0 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Yellow & Orange Radial)
-(Yellow & Orange Radial) 1 2 Bd
-[
-0
-<
-0001010203040506060708090A0B0C0C0D0E0F10111213131415161718191A1B1C1D1D1E1F202122
-232425262728292A2B2B2C2D2E2F303132333435363738393A3B3C3D3E3E3F404142434445464748
-494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60606162636465666768696A6B6C6D6E6F
-707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C
->
-<
-FFFFFFFFFEFEFEFEFEFEFEFDFDFDFDFDFDFCFCFCFCFCFCFBFBFBFBFBFBFAFAFAFAFAFAF9F9F9F9F9
-F9F8F8F8F8F8F8F7F7F7F7F7F7F6F6F6F6F6F6F5F5F5F5F5F5F4F4F4F4F4F3F3F3F3F3F3F2F2F2F2
-F2F2F1F1F1F1F1F0F0F0F0F0F0EFEFEFEFEFEFEEEEEEEEEEEDEDEDEDEDEDECECECECECEBEBEBEBEB
-EBEAEAEAEAEAE9E9E9E9E9E9E8E8E8E8E8E8E7E7E7E7E7E6E6E6E6E6E5
->
-0
-1 %_Br
-[
-0 0 1 0 1 52 19 %_Bs
-0 0.55 0.9 0 1 50 100 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Yellow & Purple Radial)
-(Yellow & Purple Radial) 1 2 Bd
-[
-<
-000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
-28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
-505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
-78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
-A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
-C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
-F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
->
-<
-1415161718191A1B1C1D1E1F1F202122232425262728292A2A2B2C2D2E2F30313233343536363738
-393A3B3C3D3E3F40414142434445464748494A4B4C4D4D4E4F50515253545556575858595A5B5C5D
-5E5F60616263646465666768696A6B6C6D6E6F6F707172737475767778797A7B7B7C7D7E7F808182
-83848586868788898A8B8C8D8E8F90919292939495969798999A9B9C9D9D9E9FA0A1A2A3A4A5A6A7
-A8A9A9AAABACADAEAFB0B1B2B3B4B4B5B6B7B8B9BABBBCBDBEBFC0C0C1C2C3C4C5C6C7C8C9CACBCB
-CCCDCECFD0D1D2D3D4D5D6D7D7D8D9DADBDCDDDEDFE0E1E2E2E3E4E5E6E7E8E9EAEBECEDEEEEEFF0
-F1F2F3F4F5F6F7F8F9F9FAFBFCFDFEFF
->
-<
-ABAAAAA9A8A7A7A6A5A5A4A3A3A2A1A1A09F9F9E9D9D9C9B9B9A9999989797969595949393929191
-908F8F8E8D8D8C8B8B8A8989888787868585848383828181807F7F7E7D7D7C7B7B7A797978777776
-7575747373727171706F6F6E6D6D6C6B6B6A6969686767666565646362626160605F5E5E5D5C5C5B
-5A5A5958585756565554545352525150504F4E4E4D4C4C4B4A4A4948484746464544444342424140
-403F3E3E3D3C3C3B3A3A3938383736363534343332323130302F2E2E2D2C2C2B2A2A292828272626
-25242423222121201F1F1E1D1D1C1B1B1A1919181717161515141313121111100F0F0E0D0D0C0B0B
-0A090908070706050504030302010100
->
-0
-1 %_Br
-[
-0 0.08 0.67 0 1 50 14 %_Bs
-1 1 0 0 1 50 100 %_Bs
-BD
-%AI5_EndGradient
-%AI5_End_NonPrinting--
-%AI5_BeginPalette
-0 0 Pb
-Pn
-Pc
-1 g
-Pc
-0 g
-Pc
-0 0 0 0 k
-Pc
-0.75 g
-Pc
-0.5 g
-Pc
-0.25 g
-Pc
-0 g
-Pc
-Bb
-2 (Black & White) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.25 0 0 0 k
-Pc
-0.5 0 0 0 k
-Pc
-0.75 0 0 0 k
-Pc
-1 0 0 0 k
-Pc
-0.25 0.25 0 0 k
-Pc
-0.5 0.5 0 0 k
-Pc
-0.75 0.75 0 0 k
-Pc
-1 1 0 0 k
-Pc
-Bb
-2 (Pink, Yellow, Green) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0 0.25 0 0 k
-Pc
-0 0.5 0 0 k
-Pc
-0 0.75 0 0 k
-Pc
-0 1 0 0 k
-Pc
-0 0.25 0.25 0 k
-Pc
-0 0.5 0.5 0 k
-Pc
-0 0.75 0.75 0 k
-Pc
-0 1 1 0 k
-Pc
-Bb
-0 0 0 0 Bh
-2 (Yellow & Purple Radial) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0 0 0.25 0 k
-Pc
-0 0 0.5 0 k
-Pc
-0 0 0.75 0 k
-Pc
-0 0 1 0 k
-Pc
-0.25 0 0.25 0 k
-Pc
-0.5 0 0.5 0 k
-Pc
-0.75 0 0.75 0 k
-Pc
-1 0 1 0 k
-Pc
-Bb
-2 (Rainbow) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.25 0.125 0 0 k
-Pc
-0.5 0.25 0 0 k
-Pc
-0.75 0.375 0 0 k
-Pc
-1 0.5 0 0 k
-Pc
-0.125 0.25 0 0 k
-Pc
-0.25 0.5 0 0 k
-Pc
-0.375 0.75 0 0 k
-Pc
-0.5 1 0 0 k
-Pc
-Bb
-2 (Steel Bar) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0 0.25 0.125 0 k
-Pc
-0 0.5 0.25 0 k
-Pc
-0 0.75 0.375 0 k
-Pc
-0 1 0.5 0 k
-Pc
-0 0.125 0.25 0 k
-Pc
-0 0.25 0.5 0 k
-Pc
-0 0.375 0.75 0 k
-Pc
-0 0.5 1 0 k
-Pc
-Bb
-2 (Purple, Red & Yellow) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.125 0 0.25 0 k
-Pc
-0.25 0 0.5 0 k
-Pc
-0.375 0 0.75 0 k
-Pc
-0.5 0 1 0 k
-Pc
-0.25 0 0.125 0 k
-Pc
-0.5 0 0.25 0 k
-Pc
-0.75 0 0.375 0 k
-Pc
-1 0 0.5 0 k
-Pc
-Bb
-2 (Green & Blue) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.25 0.125 0.125 0 k
-Pc
-0.5 0.25 0.25 0 k
-Pc
-0.75 0.375 0.375 0 k
-Pc
-1 0.5 0.5 0 k
-Pc
-0.25 0.25 0.125 0 k
-Pc
-0.5 0.5 0.25 0 k
-Pc
-0.75 0.75 0.375 0 k
-Pc
-1 1 0.5 0 k
-Pc
-Bb
-0 0 0 0 Bh
-2 (Yellow & Orange Radial) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.125 0.25 0.125 0 k
-Pc
-0.25 0.5 0.25 0 k
-Pc
-0.375 0.75 0.375 0 k
-Pc
-0.5 1 0.5 0 k
-Pc
-0.125 0.25 0.25 0 k
-Pc
-0.25 0.5 0.5 0 k
-Pc
-0.375 0.75 0.75 0 k
-Pc
-0.5 1 1 0 k
-Pc
-0 0 0 0 k
-Pc
-0.125 0.125 0.25 0 k
-Pc
-0.25 0.25 0.5 0 k
-Pc
-0.375 0.375 0.75 0 k
-Pc
-0.5 0.5 1 0 k
-Pc
-0.25 0.125 0.25 0 k
-Pc
-0.5 0.25 0.5 0 k
-Pc
-0.75 0.375 0.75 0 k
-Pc
-1 0.5 1 0 k
-Pc
-PB
-%AI5_EndPalette
-%%EndSetup
-%AI5_BeginLayer
-1 1 1 1 0 0 0 79 128 255 Lb
-(Layer 1) Ln
-0 A
-800 Ar
-0 J 0 j 1 w 4 M []0 d
-%AI3_Note:
-0 D
-0 XR
--4014 283.5 m
-4626 283.5 L
-(N) *
-453.5 4716 m
-453.5 -3924 L
-(N) *
-85 4716 m
-85 -3924 L
-(N) *
--4014 765.5 m
-4626 765.5 L
-(N) *
-0 O
-1 g
-0 R
-0 G
-3 w
-334.5 645 m
-334.5 588.5 l
-B
-0 To
-1 0 0 1 169 583.3333 0 Tp
-TP
--46.6589 0 Td
-0 Tr
-0 g
-1 w
-/_Univers 10 Tf
-0 Ts
-100 Tz
-0 Tt
-1 TA
-%_ 0 XL
-36 0 Xb
-XB
-0 0 5 TC
-100 100 200 TW
-0 0 0 Ti
-1 Ta
-0 0 2 2 3 Th
-0 Tq
-0 0 Tl
-0 Tc
-0 Tw
-(Application Process) Tx
-(\r) TX
-TO
-1 Ap
-0.75 g
-0 R
-0 G
-2 J
-368.0866 681.4134 m
-368.0866 695.5866 L
-353.9134 695.5866 L
-353.9134 681.4134 L
-368.0866 681.4134 L
-b
-0 To
-1 0 0 1 361 699 0 Tp
-TP
--34.7095 0 Td
-0 Tr
-0 g
-0 J
-(window object) Tx
-(\r) TX
-TO
-0 To
-1 0 0 1 306.5 580.6667 0 Tp
-TP
--20.2759 0 Td
-0 Tr
-(graphics\r) Tx
-5.5481 -12 Td
-(server) Tx
-(\r) TX
-TO
-u
-u
-0 Ap
-0 R
-0 G
-361 679.5 m
-360.5015 662.0213 359.5 647 v
-359 639.5 356.5 630.5 y
-348 614.5 332 617 306 617 c
-291.9911 617 209.5 617 y
-S
-0 O
-0 g
-207.138 615.9751 m
-208.7913 615.4759 209.8659 615.0159 211.1924 614.4835 c
-211.1924 619.5278 l
-210.7176 619.3026 208.7913 618.5353 207.138 618.0364 c
-205.3686 617.5017 203.7641 617.1361 202.7234 617.0056 c
-203.7641 616.8751 205.3686 616.5096 207.138 615.9751 c
-f
-U
-U
-0 To
-1 0 0 1 357.5 593 0 Tp
-TP
--19.7217 0 Td
-0 Tr
-(backend) Tx
-(\r) TX
-TO
-0 To
-1 0 0 1 196 623.3333 0 Tp
-TP
-0 Tr
-/_Geneva 8 Tf
-0 Ta
-({event, ObjectId ...}) Tx
-(\r) TX
-TO
-1 Ap
-0 R
-0 G
-169.5286 595.7116 m
-181.2699 595.7116 190.7884 605.2301 190.7884 616.9714 c
-190.7884 628.7127 181.2699 638.2312 169.5286 638.2312 c
-157.7873 638.2312 148.2688 628.7127 148.2688 616.9714 c
-148.2688 605.2301 157.7873 595.7116 169.5286 595.7116 c
-s
-u
-0 Ap
-282.7402 617 m
-282.7402 623.2129 285.1596 629.0538 289.5529 633.447 c
-293.9461 637.8403 299.7871 640.2599 306 640.2599 c
-312.2128 640.2599 318.0539 637.8403 322.4471 633.447 c
-326.8404 629.0538 329.2598 623.2129 329.2598 617 c
-329.2598 604.1744 318.8255 593.7402 306 593.7402 c
-299.7871 593.7402 293.9461 596.1596 289.5529 600.5529 c
-285.1596 604.9461 282.7402 610.7872 282.7402 617 c
-s
-1 Ap
-306 595.7402 m
-317.7413 595.7402 327.2598 605.2586 327.2598 617 c
-327.2598 628.7413 317.7413 638.2599 306 638.2599 c
-294.2587 638.2599 284.7402 628.7413 284.7402 617 c
-284.7402 605.2586 294.2587 595.7402 306 595.7402 c
-s
-U
-LB
-%AI5_EndLayer--
-%%PageTrailer
-gsave annotatepage grestore showpage
-%%Trailer
-Adobe_Illustrator_AI5 /terminate get exec
-Adobe_ColorImage_AI6 /terminate get exec
-Adobe_typography_AI5 /terminate get exec
-Adobe_level2_AI5 /terminate get exec
-%%EOF
diff --git a/lib/gs/doc/src/images/gs1-1-image-4.gif b/lib/gs/doc/src/images/gs1-1-image-4.gif
deleted file mode 100644
index efbb2483ea..0000000000
--- a/lib/gs/doc/src/images/gs1-1-image-4.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/gs1-1-image-4.ps b/lib/gs/doc/src/images/gs1-1-image-4.ps
deleted file mode 100644
index 4660ce768c..0000000000
--- a/lib/gs/doc/src/images/gs1-1-image-4.ps
+++ /dev/null
@@ -1,2761 +0,0 @@
-%!PS-Adobe-3.0 EPSF-3.0
-%%Creator: Adobe Illustrator(r) 6.0
-%%For: (Anna Fedoriw) (Ericsson Telecom)
-%%Title: (Object_hierarchy.eps)
-%%CreationDate: (97-05-22) (12.54)
-%%BoundingBox: 184 668 330 732
-%%HiResBoundingBox: 184.4556 668.5 329.7661 731.3677
-%%DocumentProcessColors: Black
-%%DocumentFonts: Univers
-%%DocumentSuppliedResources: procset Adobe_level2_AI5 1.0 0
-%%+ procset Adobe_typography_AI5 1.0 0
-%%+ procset Adobe_Illustrator_AI6_vars Adobe_Illustrator_AI6
-%%+ procset Adobe_Illustrator_AI5 1.0 0
-%AI5_FileFormat 2.0
-%AI3_ColorUsage: Black&White
-%%AI6_ColorSeparationSet: 1 1 (AI6 Default Color Separation Set)
-%%+ Options: 1 16 0 1 0 1 1 1 0 1 1 1 1 18 0 0 0 0 0 0 0 0 -1 -1
-%%+ PPD: 1 21 0 0 60 45 2 2 1 0 0 1 0 0 0 0 0 0 0 0 0 0 ()
-%AI3_TemplateBox: 306 396 306 396
-%AI3_TileBox: 21 -12 588 802
-%AI3_DocumentPreview: Macintosh_ColorPic
-%AI5_ArtSize: 595.2756 841.8898
-%AI5_RulerUnits: 1
-%AI5_ArtFlags: 0 0 0 1 0 0 1 1 0
-%AI5_TargetResolution: 800
-%AI5_NumLayers: 1
-%AI5_OpenToView: -62 780 1.5 1058 826 58 1 1 2 40
-%AI5_OpenViewLayers: 7
-%%EndComments
-%%BeginProlog
-%%BeginResource: procset Adobe_level2_AI5 1.2 0
-%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation)
-%%Version: 1.2
-%%CreationDate: (04/10/93) ()
-%%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved)
-userdict /Adobe_level2_AI5 23 dict dup begin
- put
- /packedarray where not
- {
- userdict begin
- /packedarray
- {
- array astore readonly
- } bind def
- /setpacking /pop load def
- /currentpacking false def
- end
- 0
- } if
- pop
- userdict /defaultpacking currentpacking put true setpacking
- /initialize
- {
- Adobe_level2_AI5 begin
- } bind def
- /terminate
- {
- currentdict Adobe_level2_AI5 eq
- {
- end
- } if
- } bind def
- mark
- /setcustomcolor where not
- {
- /findcmykcustomcolor
- {
- 5 packedarray
- } bind def
- /setcustomcolor
- {
- exch aload pop pop
- 4
- {
- 4 index mul 4 1 roll
- } repeat
- 5 -1 roll pop
- setcmykcolor
- }
- def
- } if
-
- /gt38? mark {version cvr cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def
- userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put
- userdict /level2?
- systemdict /languagelevel known dup
- {
- pop systemdict /languagelevel get 2 ge
- } if
- put
-/level2ScreenFreq
-{
- begin
- 60
- HalftoneType 1 eq
- {
- pop Frequency
- } if
- HalftoneType 2 eq
- {
- pop GrayFrequency
- } if
- HalftoneType 5 eq
- {
- pop Default level2ScreenFreq
- } if
- end
-} bind def
-userdict /currentScreenFreq
- level2? {currenthalftone level2ScreenFreq} {currentscreen pop pop} ifelse put
-level2? not
- {
- /setcmykcolor where not
- {
- /setcmykcolor
- {
- exch .11 mul add exch .59 mul add exch .3 mul add
- 1 exch sub setgray
- } def
- } if
- /currentcmykcolor where not
- {
- /currentcmykcolor
- {
- 0 0 0 1 currentgray sub
- } def
- } if
- /setoverprint where not
- {
- /setoverprint /pop load def
- } if
- /selectfont where not
- {
- /selectfont
- {
- exch findfont exch
- dup type /arraytype eq
- {
- makefont
- }
- {
- scalefont
- } ifelse
- setfont
- } bind def
- } if
- /cshow where not
- {
- /cshow
- {
- [
- 0 0 5 -1 roll aload pop
- ] cvx bind forall
- } bind def
- } if
- } if
- cleartomark
- /anyColor?
- {
- add add add 0 ne
- } bind def
- /testColor
- {
- gsave
- setcmykcolor currentcmykcolor
- grestore
- } bind def
- /testCMYKColorThrough
- {
- testColor anyColor?
- } bind def
- userdict /composite?
- level2?
- {
- gsave 1 1 1 1 setcmykcolor currentcmykcolor grestore
- add add add 4 eq
- }
- {
- 1 0 0 0 testCMYKColorThrough
- 0 1 0 0 testCMYKColorThrough
- 0 0 1 0 testCMYKColorThrough
- 0 0 0 1 testCMYKColorThrough
- and and and
- } ifelse
- put
- composite? not
- {
- userdict begin
- gsave
- /cyan? 1 0 0 0 testCMYKColorThrough def
- /magenta? 0 1 0 0 testCMYKColorThrough def
- /yellow? 0 0 1 0 testCMYKColorThrough def
- /black? 0 0 0 1 testCMYKColorThrough def
- grestore
- /isCMYKSep? cyan? magenta? yellow? black? or or or def
- /customColor? isCMYKSep? not def
- end
- } if
- end defaultpacking setpacking
-%%EndResource
-%%BeginResource: procset Adobe_typography_AI5 1.0 1
-%%Title: (Typography Operators)
-%%Version: 1.0
-%%CreationDate:(03/26/93) ()
-%%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved)
-currentpacking true setpacking
-userdict /Adobe_typography_AI5 54 dict dup begin
-put
-/initialize
-{
- begin
- begin
- Adobe_typography_AI5 begin
- Adobe_typography_AI5
- {
- dup xcheck
- {
- bind
- } if
- pop pop
- } forall
- end
- end
- end
- Adobe_typography_AI5 begin
-} def
-/terminate
-{
- currentdict Adobe_typography_AI5 eq
- {
- end
- } if
-} def
-/modifyEncoding
-{
- /_tempEncode exch ddef
- /_pntr 0 ddef
- {
- counttomark -1 roll
- dup type dup /marktype eq
- {
- pop pop exit
- }
- {
- /nametype eq
- {
- _tempEncode /_pntr dup load dup 3 1 roll 1 add ddef 3 -1 roll
- put
- }
- {
- /_pntr exch ddef
- } ifelse
- } ifelse
- } loop
- _tempEncode
-} def
-/TE
-{
- StandardEncoding 256 array copy modifyEncoding
- /_nativeEncoding exch def
-} def
-%
-/TZ
-{
- dup type /arraytype eq
- {
- /_wv exch def
- }
- {
- /_wv 0 def
- } ifelse
- /_useNativeEncoding exch def
- pop pop
- findfont _wv type /arraytype eq
- {
- _wv makeblendedfont
- } if
- dup length 2 add dict
- begin
- mark exch
- {
- 1 index /FID ne
- {
- def
- } if
- cleartomark mark
- } forall
- pop
- /FontName exch def
- counttomark 0 eq
- {
- 1 _useNativeEncoding eq
- {
- /Encoding _nativeEncoding def
- } if
- cleartomark
- }
- {
- /Encoding load 256 array copy
- modifyEncoding /Encoding exch def
- } ifelse
- FontName currentdict
- end
- definefont pop
-} def
-/tr
-{
- _ax _ay 3 2 roll
-} def
-/trj
-{
- _cx _cy _sp _ax _ay 6 5 roll
-} def
-/a0
-{
- /Tx
- {
- dup
- currentpoint 3 2 roll
- tr _psf
- newpath moveto
- tr _ctm _pss
- } ddef
- /Tj
- {
- dup
- currentpoint 3 2 roll
- trj _pjsf
- newpath moveto
- trj _ctm _pjss
- } ddef
-} def
-/a1
-{
- /Tx
- {
- dup currentpoint 4 2 roll gsave
- dup currentpoint 3 2 roll
- tr _psf
- newpath moveto
- tr _ctm _pss
- grestore 3 1 roll moveto tr sp
- } ddef
- /Tj
- {
- dup currentpoint 4 2 roll gsave
- dup currentpoint 3 2 roll
- trj _pjsf
- newpath moveto
- trj _ctm _pjss
- grestore 3 1 roll moveto tr jsp
- } ddef
-} def
-/e0
-{
- /Tx
- {
- tr _psf
- } ddef
- /Tj
- {
- trj _pjsf
- } ddef
-} def
-/e1
-{
- /Tx
- {
- dup currentpoint 4 2 roll gsave
- tr _psf
- grestore 3 1 roll moveto tr sp
- } ddef
- /Tj
- {
- dup currentpoint 4 2 roll gsave
- trj _pjsf
- grestore 3 1 roll moveto tr jsp
- } ddef
-} def
-/i0
-{
- /Tx
- {
- tr sp
- } ddef
- /Tj
- {
- trj jsp
- } ddef
-} def
-/i1
-{
- W N
-} def
-/o0
-{
- /Tx
- {
- tr sw rmoveto
- } ddef
- /Tj
- {
- trj swj rmoveto
- } ddef
-} def
-/r0
-{
- /Tx
- {
- tr _ctm _pss
- } ddef
- /Tj
- {
- trj _ctm _pjss
- } ddef
-} def
-/r1
-{
- /Tx
- {
- dup currentpoint 4 2 roll currentpoint gsave newpath moveto
- tr _ctm _pss
- grestore 3 1 roll moveto tr sp
- } ddef
- /Tj
- {
- dup currentpoint 4 2 roll currentpoint gsave newpath moveto
- trj _ctm _pjss
- grestore 3 1 roll moveto tr jsp
- } ddef
-} def
-/To
-{
- pop _ctm currentmatrix pop
-} def
-/TO
-{
- iTe _ctm setmatrix newpath
-} def
-/Tp
-{
- pop _tm astore pop _ctm setmatrix
- _tDict begin
- /W
- {
- } def
- /h
- {
- } def
-} def
-/TP
-{
- end
- iTm 0 0 moveto
-} def
-/Tr
-{
- _render 3 le
- {
- currentpoint newpath moveto
- } if
- dup 8 eq
- {
- pop 0
- }
- {
- dup 9 eq
- {
- pop 1
- } if
- } ifelse
- dup /_render exch ddef
- _renderStart exch get load exec
-} def
-/iTm
-{
- _ctm setmatrix _tm concat 0 _rise translate _hs 1 scale
-} def
-/Tm
-{
- _tm astore pop iTm 0 0 moveto
-} def
-/Td
-{
- _mtx translate _tm _tm concatmatrix pop iTm 0 0 moveto
-} def
-/iTe
-{
- _render -1 eq
- {
- }
- {
- _renderEnd _render get dup null ne
- {
- load exec
- }
- {
- pop
- } ifelse
- } ifelse
- /_render -1 ddef
-} def
-/Ta
-{
- pop
-} def
-/Tf
-{
- dup 1000 div /_fScl exch ddef
-%
- selectfont
-} def
-/Tl
-{
- pop
- 0 exch _leading astore pop
-} def
-/Tt
-{
- pop
-} def
-/TW
-{
- 3 npop
-} def
-/Tw
-{
- /_cx exch ddef
-} def
-/TC
-{
- 3 npop
-} def
-/Tc
-{
- /_ax exch ddef
-} def
-/Ts
-{
- /_rise exch ddef
- currentpoint
- iTm
- moveto
-} def
-/Ti
-{
- 3 npop
-} def
-/Tz
-{
- 100 div /_hs exch ddef
- iTm
-} def
-/TA
-{
- pop
-} def
-/Tq
-{
- pop
-} def
-/Th
-{
- pop pop pop pop pop
-} def
-/TX
-{
- pop
-} def
-/Tk
-{
- exch pop _fScl mul neg 0 rmoveto
-} def
-/TK
-{
- 2 npop
-} def
-/T*
-{
- _leading aload pop neg Td
-} def
-/T*-
-{
- _leading aload pop Td
-} def
-/T-
-{
- _ax neg 0 rmoveto
- _hyphen Tx
-} def
-/T+
-{
-} def
-/TR
-{
- _ctm currentmatrix pop
- _tm astore pop
- iTm 0 0 moveto
-} def
-/TS
-{
- currentfont 3 1 roll
- /_Symbol_ _fScl 1000 mul selectfont
-
- 0 eq
- {
- Tx
- }
- {
- Tj
- } ifelse
- setfont
-} def
-/Xb
-{
- pop pop
-} def
-/Tb /Xb load def
-/Xe
-{
- pop pop pop pop
-} def
-/Te /Xe load def
-/XB
-{
-} def
-/TB /XB load def
-currentdict readonly pop
-end
-setpacking
-%%EndResource
-%%BeginProcSet: Adobe_ColorImage_AI6 1.0 0
-userdict /Adobe_ColorImage_AI6 known not
-{
- userdict /Adobe_ColorImage_AI6 17 dict put
-} if
-userdict /Adobe_ColorImage_AI6 get begin
-
- /initialize
- {
- Adobe_ColorImage_AI6 begin
- Adobe_ColorImage_AI6
- {
- dup type /arraytype eq
- {
- dup xcheck
- {
- bind
- } if
- } if
- pop pop
- } forall
- } def
- /terminate { end } def
-
- currentdict /Adobe_ColorImage_AI6_Vars known not
- {
- /Adobe_ColorImage_AI6_Vars 14 dict def
- } if
-
- Adobe_ColorImage_AI6_Vars begin
- /channelcount 0 def
- /sourcecount 0 def
- /sourcearray 4 array def
- /plateindex -1 def
- /XIMask 0 def
- /XIBinary 0 def
- /XIChannelCount 0 def
- /XIBitsPerPixel 0 def
- /XIImageHeight 0 def
- /XIImageWidth 0 def
- /XIImageMatrix null def
- /XIBuffer null def
- /XIDataProc null def
- end
-
- /WalkRGBString null def
- /WalkCMYKString null def
-
- /StuffRGBIntoGrayString null def
- /RGBToGrayImageProc null def
- /StuffCMYKIntoGrayString null def
- /CMYKToGrayImageProc null def
- /ColorImageCompositeEmulator null def
-
- /SeparateCMYKImageProc null def
-
- /FourEqual null def
- /TestPlateIndex null def
-
- currentdict /_colorimage known not
- {
- /colorimage where
- {
- /colorimage get /_colorimage exch def
- }
- {
- /_colorimage null def
- } ifelse
- } if
-
- /_currenttransfer systemdict /currenttransfer get def
-
- /colorimage null def
- /XI null def
-
-
- /WalkRGBString
- {
- 0 3 index
-
- dup length 1 sub 0 3 3 -1 roll
- {
- 3 getinterval { } forall
-
- 5 index exec
-
- 3 index
- } for
-
- 5 { pop } repeat
-
- } def
-
-
- /WalkCMYKString
- {
- 0 3 index
-
- dup length 1 sub 0 4 3 -1 roll
- {
- 4 getinterval { } forall
-
- 6 index exec
-
- 3 index
-
- } for
-
- 5 { pop } repeat
-
- } def
-
-
- /StuffRGBIntoGrayString
- {
- .11 mul exch
-
- .59 mul add exch
-
- .3 mul add
-
- cvi 3 copy put
-
- pop 1 add
- } def
-
-
- /RGBToGrayImageProc
- {
- Adobe_ColorImage_AI6_Vars begin
- sourcearray 0 get exec
- dup length 3 idiv string
- dup 3 1 roll
-
- /StuffRGBIntoGrayString load exch
- WalkRGBString
- end
- } def
-
-
- /StuffCMYKIntoGrayString
- {
- exch .11 mul add
-
- exch .59 mul add
-
- exch .3 mul add
-
- dup 255 gt { pop 255 } if
-
- 255 exch sub cvi 3 copy put
-
- pop 1 add
- } def
-
-
- /CMYKToGrayImageProc
- {
- Adobe_ColorImage_AI6_Vars begin
- sourcearray 0 get exec
- dup length 4 idiv string
- dup 3 1 roll
-
- /StuffCMYKIntoGrayString load exch
- WalkCMYKString
- end
- } def
-
-
- /ColorImageCompositeEmulator
- {
- pop true eq
- {
- Adobe_ColorImage_AI6_Vars /sourcecount get 5 add { pop } repeat
- }
- {
- Adobe_ColorImage_AI6_Vars /channelcount get 1 ne
- {
- Adobe_ColorImage_AI6_Vars begin
- sourcearray 0 3 -1 roll put
-
- channelcount 3 eq
- {
- /RGBToGrayImageProc
- }
- {
- /CMYKToGrayImageProc
- } ifelse
- load
- end
- } if
- image
- } ifelse
- } def
-
-
- /SeparateCMYKImageProc
- {
- Adobe_ColorImage_AI6_Vars begin
-
- sourcecount 0 ne
- {
- sourcearray plateindex get exec
- }
- {
- sourcearray 0 get exec
-
- dup length 4 idiv string
-
- 0 2 index
-
- plateindex 4 2 index length 1 sub
- {
- get 255 exch sub
-
- 3 copy put pop 1 add
-
- 2 index
- } for
-
- pop pop exch pop
- } ifelse
- end
- } def
-
-
- /FourEqual
- {
- 4 index ne
- {
- pop pop pop false
- }
- {
- 4 index ne
- {
- pop pop false
- }
- {
- 4 index ne
- {
- pop false
- }
- {
- 4 index eq
- } ifelse
- } ifelse
- } ifelse
- } def
-
-
- /TestPlateIndex
- {
- Adobe_ColorImage_AI6_Vars begin
- /plateindex -1 def
-
- /setcmykcolor where
- {
- pop
- gsave
- 1 0 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
- 0 1 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
- 0 0 1 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
- 0 0 0 1 setcmykcolor systemdict /currentgray get exec 1 exch sub
- grestore
-
- 1 0 0 0 FourEqual
- {
- /plateindex 0 def
- }
- {
- 0 1 0 0 FourEqual
- {
- /plateindex 1 def
- }
- {
- 0 0 1 0 FourEqual
- {
- /plateindex 2 def
- }
- {
- 0 0 0 1 FourEqual
- {
- /plateindex 3 def
- }
- {
- 0 0 0 0 FourEqual
- {
- /plateindex 5 def
- } if
- } ifelse
- } ifelse
- } ifelse
- } ifelse
- pop pop pop pop
- } if
- plateindex
- end
- } def
-
-
- /colorimage
- {
- Adobe_ColorImage_AI6_Vars begin
- /channelcount 1 index def
- /sourcecount 2 index 1 eq { channelcount 1 sub } { 0 } ifelse def
-
- 4 sourcecount add index dup
- 8 eq exch 1 eq or not
- end
-
- {
- /_colorimage load null ne
- {
- _colorimage
- }
- {
- Adobe_ColorImage_AI6_Vars /sourcecount get
- 7 add { pop } repeat
- } ifelse
- }
- {
- dup 3 eq
- TestPlateIndex
- dup -1 eq exch 5 eq or or
- {
- /_colorimage load null eq
- {
- ColorImageCompositeEmulator
- }
- {
- dup 1 eq
- {
- pop pop image
- }
- {
- Adobe_ColorImage_AI6_Vars /plateindex get 5 eq
- {
- gsave
-
- 0 _currenttransfer exec
- 1 _currenttransfer exec
- eq
- { 0 _currenttransfer exec 0.5 lt }
- { 0 _currenttransfer exec 1 _currenttransfer exec gt } ifelse
-
- { { pop 0 } } { { pop 1 } } ifelse
- systemdict /settransfer get exec
- } if
-
- _colorimage
-
- Adobe_ColorImage_AI6_Vars /plateindex get 5 eq
- {
- grestore
- } if
- } ifelse
- } ifelse
- }
- {
- dup 1 eq
- {
- pop pop
- image
- }
- {
- pop pop
-
- Adobe_ColorImage_AI6_Vars begin
- sourcecount -1 0
- {
- exch sourcearray 3 1 roll put
- } for
-
- /SeparateCMYKImageProc load
- end
-
- systemdict /image get exec
- } ifelse
- } ifelse
- } ifelse
- } def
-
- /XI
- {
- Adobe_ColorImage_AI6_Vars begin
- gsave
- /XIMask exch 0 ne def
- /XIBinary exch 0 ne def
- pop
- pop
- /XIChannelCount exch def
- /XIBitsPerPixel exch def
- /XIImageHeight exch def
- /XIImageWidth exch def
- pop pop pop pop
- /XIImageMatrix exch def
-
- XIBitsPerPixel 1 eq
- {
- XIImageWidth 8 div ceiling cvi
- }
- {
- XIImageWidth XIChannelCount mul
- } ifelse
- /XIBuffer exch string def
-
- XIBinary
- {
- /XIDataProc { currentfile XIBuffer readstring pop } def
- currentfile 128 string readline pop pop
- }
- {
- /XIDataProc { currentfile XIBuffer readhexstring pop } def
- } ifelse
-
- 0 0 moveto
- XIImageMatrix concat
- XIImageWidth XIImageHeight scale
-
- XIMask
- {
- XIImageWidth XIImageHeight
- false
- [ XIImageWidth 0 0 XIImageHeight neg 0 0 ]
- /XIDataProc load
-
- /_lp /null ddef
- _fc
- /_lp /imagemask ddef
-
- imagemask
- }
- {
- XIImageWidth XIImageHeight
- XIBitsPerPixel
- [ XIImageWidth 0 0 XIImageHeight neg 0 0 ]
- /XIDataProc load
-
- XIChannelCount 1 eq
- {
-
- gsave
- 0 setgray
-
- image
-
- grestore
- }
- {
- false
- XIChannelCount
- colorimage
- } ifelse
- } ifelse
- grestore
- end
- } def
-
-end
-%%EndProcSet
-%%BeginResource: procset Adobe_Illustrator_AI5 1.1 0
-%%Title: (Adobe Illustrator (R) Version 5.0 Full Prolog)
-%%Version: 1.1
-%%CreationDate: (3/7/1994) ()
-%%Copyright: ((C) 1987-1994 Adobe Systems Incorporated All Rights Reserved)
-currentpacking true setpacking
-userdict /Adobe_Illustrator_AI5_vars 81 dict dup begin
-put
-/_eo false def
-/_lp /none def
-/_pf
-{
-} def
-/_ps
-{
-} def
-/_psf
-{
-} def
-/_pss
-{
-} def
-/_pjsf
-{
-} def
-/_pjss
-{
-} def
-/_pola 0 def
-/_doClip 0 def
-/cf currentflat def
-/_tm matrix def
-/_renderStart
-[
-/e0 /r0 /a0 /o0 /e1 /r1 /a1 /i0
-] def
-/_renderEnd
-[
-null null null null /i1 /i1 /i1 /i1
-] def
-/_render -1 def
-/_rise 0 def
-/_ax 0 def
-/_ay 0 def
-/_cx 0 def
-/_cy 0 def
-/_leading
-[
-0 0
-] def
-/_ctm matrix def
-/_mtx matrix def
-/_sp 16#020 def
-/_hyphen (-) def
-/_fScl 0 def
-/_cnt 0 def
-/_hs 1 def
-/_nativeEncoding 0 def
-/_useNativeEncoding 0 def
-/_tempEncode 0 def
-/_pntr 0 def
-/_tDict 2 dict def
-/_wv 0 def
-/Tx
-{
-} def
-/Tj
-{
-} def
-/CRender
-{
-} def
-/_AI3_savepage
-{
-} def
-/_gf null def
-/_cf 4 array def
-/_if null def
-/_of false def
-/_fc
-{
-} def
-/_gs null def
-/_cs 4 array def
-/_is null def
-/_os false def
-/_sc
-{
-} def
-/_pd 1 dict def
-/_ed 15 dict def
-/_pm matrix def
-/_fm null def
-/_fd null def
-/_fdd null def
-/_sm null def
-/_sd null def
-/_sdd null def
-/_i null def
-/discardSave null def
-/buffer 256 string def
-/beginString null def
-/endString null def
-/endStringLength null def
-/layerCnt 1 def
-/layerCount 1 def
-/perCent (%) 0 get def
-/perCentSeen? false def
-/newBuff null def
-/newBuffButFirst null def
-/newBuffLast null def
-/clipForward? false def
-end
-userdict /Adobe_Illustrator_AI5 known not {
- userdict /Adobe_Illustrator_AI5 91 dict put
-} if
-userdict /Adobe_Illustrator_AI5 get begin
-/initialize
-{
- Adobe_Illustrator_AI5 dup begin
- Adobe_Illustrator_AI5_vars begin
- discardDict
- {
- bind pop pop
- } forall
- dup /nc get begin
- {
- dup xcheck 1 index type /operatortype ne and
- {
- bind
- } if
- pop pop
- } forall
- end
- newpath
-} def
-/terminate
-{
- end
- end
-} def
-/_
-null def
-/ddef
-{
- Adobe_Illustrator_AI5_vars 3 1 roll put
-} def
-/xput
-{
- dup load dup length exch maxlength eq
- {
- dup dup load dup
- length 2 mul dict copy def
- } if
- load begin
- def
- end
-} def
-/npop
-{
- {
- pop
- } repeat
-} def
-/sw
-{
- dup length exch stringwidth
- exch 5 -1 roll 3 index mul add
- 4 1 roll 3 1 roll mul add
-} def
-/swj
-{
- dup 4 1 roll
- dup length exch stringwidth
- exch 5 -1 roll 3 index mul add
- 4 1 roll 3 1 roll mul add
- 6 2 roll /_cnt 0 ddef
- {
- 1 index eq
- {
- /_cnt _cnt 1 add ddef
- } if
- } forall
- pop
- exch _cnt mul exch _cnt mul 2 index add 4 1 roll 2 index add 4 1 roll pop pop
-} def
-/ss
-{
- 4 1 roll
- {
- 2 npop
- (0) exch 2 copy 0 exch put pop
- gsave
- false charpath currentpoint
- 4 index setmatrix
- stroke
- grestore
- moveto
- 2 copy rmoveto
- } exch cshow
- 3 npop
-} def
-/jss
-{
- 4 1 roll
- {
- 2 npop
- (0) exch 2 copy 0 exch put
- gsave
- _sp eq
- {
- exch 6 index 6 index 6 index 5 -1 roll widthshow
- currentpoint
- }
- {
- false charpath currentpoint
- 4 index setmatrix stroke
- } ifelse
- grestore
- moveto
- 2 copy rmoveto
- } exch cshow
- 6 npop
-} def
-/sp
-{
- {
- 2 npop (0) exch
- 2 copy 0 exch put pop
- false charpath
- 2 copy rmoveto
- } exch cshow
- 2 npop
-} def
-/jsp
-{
- {
- 2 npop
- (0) exch 2 copy 0 exch put
- _sp eq
- {
- exch 5 index 5 index 5 index 5 -1 roll widthshow
- }
- {
- false charpath
- } ifelse
- 2 copy rmoveto
- } exch cshow
- 5 npop
-} def
-/pl
-{
- transform
- 0.25 sub round 0.25 add exch
- 0.25 sub round 0.25 add exch
- itransform
-} def
-/setstrokeadjust where
-{
- pop true setstrokeadjust
- /c
- {
- curveto
- } def
- /C
- /c load def
- /v
- {
- currentpoint 6 2 roll curveto
- } def
- /V
- /v load def
- /y
- {
- 2 copy curveto
- } def
- /Y
- /y load def
- /l
- {
- lineto
- } def
- /L
- /l load def
- /m
- {
- moveto
- } def
-}
-{
- /c
- {
- pl curveto
- } def
- /C
- /c load def
- /v
- {
- currentpoint 6 2 roll pl curveto
- } def
- /V
- /v load def
- /y
- {
- pl 2 copy curveto
- } def
- /Y
- /y load def
- /l
- {
- pl lineto
- } def
- /L
- /l load def
- /m
- {
- pl moveto
- } def
-} ifelse
-/d
-{
- setdash
-} def
-/cf
-{
-} def
-/i
-{
- dup 0 eq
- {
- pop cf
- } if
- setflat
-} def
-/j
-{
- setlinejoin
-} def
-/J
-{
- setlinecap
-} def
-/M
-{
- setmiterlimit
-} def
-/w
-{
- setlinewidth
-} def
-/XR
-{
- 0 ne
- /_eo exch ddef
-} def
-/H
-{
-} def
-/h
-{
- closepath
-} def
-/N
-{
- _pola 0 eq
- {
- _doClip 1 eq
- {
- _eo {eoclip} {clip} ifelse /_doClip 0 ddef
- } if
- newpath
- }
- {
- /CRender
- {
- N
- } ddef
- } ifelse
-} def
-/n
-{
- N
-} def
-/F
-{
- _pola 0 eq
- {
- _doClip 1 eq
- {
- gsave _pf grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _fc
- /_doClip 0 ddef
- }
- {
- _pf
- } ifelse
- }
- {
- /CRender
- {
- F
- } ddef
- } ifelse
-} def
-/f
-{
- closepath
- F
-} def
-/S
-{
- _pola 0 eq
- {
- _doClip 1 eq
- {
- gsave _ps grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
- /_doClip 0 ddef
- }
- {
- _ps
- } ifelse
- }
- {
- /CRender
- {
- S
- } ddef
- } ifelse
-} def
-/s
-{
- closepath
- S
-} def
-/B
-{
- _pola 0 eq
- {
- _doClip 1 eq
- gsave F grestore
- {
- gsave S grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
- /_doClip 0 ddef
- }
- {
- S
- } ifelse
- }
- {
- /CRender
- {
- B
- } ddef
- } ifelse
-} def
-/b
-{
- closepath
- B
-} def
-/W
-{
- /_doClip 1 ddef
-} def
-/*
-{
- count 0 ne
- {
- dup type /stringtype eq
- {
- pop
- } if
- } if
- newpath
-} def
-/u
-{
-} def
-/U
-{
-} def
-/q
-{
- _pola 0 eq
- {
- gsave
- } if
-} def
-/Q
-{
- _pola 0 eq
- {
- grestore
- } if
-} def
-/*u
-{
- _pola 1 add /_pola exch ddef
-} def
-/*U
-{
- _pola 1 sub /_pola exch ddef
- _pola 0 eq
- {
- CRender
- } if
-} def
-/D
-{
- pop
-} def
-/*w
-{
-} def
-/*W
-{
-} def
-/`
-{
- /_i save ddef
- clipForward?
- {
- nulldevice
- } if
- 6 1 roll 4 npop
- concat pop
- userdict begin
- /showpage
- {
- } def
- 0 setgray
- 0 setlinecap
- 1 setlinewidth
- 0 setlinejoin
- 10 setmiterlimit
- [] 0 setdash
- /setstrokeadjust where {pop false setstrokeadjust} if
- newpath
- 0 setgray
- false setoverprint
-} def
-/~
-{
- end
- _i restore
-} def
-/O
-{
- 0 ne
- /_of exch ddef
- /_lp /none ddef
-} def
-/R
-{
- 0 ne
- /_os exch ddef
- /_lp /none ddef
-} def
-/g
-{
- /_gf exch ddef
- /_fc
- {
- _lp /fill ne
- {
- _of setoverprint
- _gf setgray
- /_lp /fill ddef
- } if
- } ddef
- /_pf
- {
- _fc
- _eo {eofill} {fill} ifelse
- } ddef
- /_psf
- {
- _fc
- ashow
- } ddef
- /_pjsf
- {
- _fc
- awidthshow
- } ddef
- /_lp /none ddef
-} def
-/G
-{
- /_gs exch ddef
- /_sc
- {
- _lp /stroke ne
- {
- _os setoverprint
- _gs setgray
- /_lp /stroke ddef
- } if
- } ddef
- /_ps
- {
- _sc
- stroke
- } ddef
- /_pss
- {
- _sc
- ss
- } ddef
- /_pjss
- {
- _sc
- jss
- } ddef
- /_lp /none ddef
-} def
-/k
-{
- _cf astore pop
- /_fc
- {
- _lp /fill ne
- {
- _of setoverprint
- _cf aload pop setcmykcolor
- /_lp /fill ddef
- } if
- } ddef
- /_pf
- {
- _fc
- _eo {eofill} {fill} ifelse
- } ddef
- /_psf
- {
- _fc
- ashow
- } ddef
- /_pjsf
- {
- _fc
- awidthshow
- } ddef
- /_lp /none ddef
-} def
-/K
-{
- _cs astore pop
- /_sc
- {
- _lp /stroke ne
- {
- _os setoverprint
- _cs aload pop setcmykcolor
- /_lp /stroke ddef
- } if
- } ddef
- /_ps
- {
- _sc
- stroke
- } ddef
- /_pss
- {
- _sc
- ss
- } ddef
- /_pjss
- {
- _sc
- jss
- } ddef
- /_lp /none ddef
-} def
-/x
-{
- /_gf exch ddef
- findcmykcustomcolor
- /_if exch ddef
- /_fc
- {
- _lp /fill ne
- {
- _of setoverprint
- _if _gf 1 exch sub setcustomcolor
- /_lp /fill ddef
- } if
- } ddef
- /_pf
- {
- _fc
- _eo {eofill} {fill} ifelse
- } ddef
- /_psf
- {
- _fc
- ashow
- } ddef
- /_pjsf
- {
- _fc
- awidthshow
- } ddef
- /_lp /none ddef
-} def
-/X
-{
- /_gs exch ddef
- findcmykcustomcolor
- /_is exch ddef
- /_sc
- {
- _lp /stroke ne
- {
- _os setoverprint
- _is _gs 1 exch sub setcustomcolor
- /_lp /stroke ddef
- } if
- } ddef
- /_ps
- {
- _sc
- stroke
- } ddef
- /_pss
- {
- _sc
- ss
- } ddef
- /_pjss
- {
- _sc
- jss
- } ddef
- /_lp /none ddef
-} def
-/A
-{
- pop
-} def
-/annotatepage
-{
-userdict /annotatepage 2 copy known {get exec} {pop pop} ifelse
-} def
-/XT {
- pop pop
-} def
-/discard
-{
- save /discardSave exch store
- discardDict begin
- /endString exch store
- gt38?
- {
- 2 add
- } if
- load
- stopped
- pop
- end
- discardSave restore
-} bind def
-userdict /discardDict 7 dict dup begin
-put
-/pre38Initialize
-{
- /endStringLength endString length store
- /newBuff buffer 0 endStringLength getinterval store
- /newBuffButFirst newBuff 1 endStringLength 1 sub getinterval store
- /newBuffLast newBuff endStringLength 1 sub 1 getinterval store
-} def
-/shiftBuffer
-{
- newBuff 0 newBuffButFirst putinterval
- newBuffLast 0
- currentfile read not
- {
- stop
- } if
- put
-} def
-0
-{
- pre38Initialize
- mark
- currentfile newBuff readstring exch pop
- {
- {
- newBuff endString eq
- {
- cleartomark stop
- } if
- shiftBuffer
- } loop
- }
- {
- stop
- } ifelse
-} def
-1
-{
- pre38Initialize
- /beginString exch store
- mark
- currentfile newBuff readstring exch pop
- {
- {
- newBuff beginString eq
- {
- /layerCount dup load 1 add store
- }
- {
- newBuff endString eq
- {
- /layerCount dup load 1 sub store
- layerCount 0 eq
- {
- cleartomark stop
- } if
- } if
- } ifelse
- shiftBuffer
- } loop
- } if
-} def
-2
-{
- mark
- {
- currentfile buffer readline not
- {
- stop
- } if
- endString eq
- {
- cleartomark stop
- } if
- } loop
-} def
-3
-{
- /beginString exch store
- /layerCnt 1 store
- mark
- {
- currentfile buffer readline not
- {
- stop
- } if
- dup beginString eq
- {
- pop /layerCnt dup load 1 add store
- }
- {
- endString eq
- {
- layerCnt 1 eq
- {
- cleartomark stop
- }
- {
- /layerCnt dup load 1 sub store
- } ifelse
- } if
- } ifelse
- } loop
-} def
-end
-userdict /clipRenderOff 15 dict dup begin
-put
-{
- /n /N /s /S /f /F /b /B
-}
-{
- {
- _doClip 1 eq
- {
- /_doClip 0 ddef _eo {eoclip} {clip} ifelse
- } if
- newpath
- } def
-} forall
-/Tr /pop load def
-/Bb {} def
-/BB /pop load def
-/Bg {12 npop} def
-/Bm {6 npop} def
-/Bc /Bm load def
-/Bh {4 npop} def
-end
-/Lb
-{
- 4 npop
- 6 1 roll
- pop
- 4 1 roll
- pop pop pop
- 0 eq
- {
- 0 eq
- {
- (%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard
- }
- {
-
- /clipForward? true def
-
- /Tx /pop load def
- /Tj /pop load def
-
- currentdict end clipRenderOff begin begin
- } ifelse
- }
- {
- 0 eq
- {
- save /discardSave exch store
- } if
- } ifelse
-} bind def
-/LB
-{
- discardSave dup null ne
- {
- restore
- }
- {
- pop
- clipForward?
- {
- currentdict
- end
- end
- begin
-
- /clipForward? false ddef
- } if
- } ifelse
-} bind def
-/Pb
-{
- pop pop
- 0 (%AI5_EndPalette) discard
-} bind def
-/Np
-{
- 0 (%AI5_End_NonPrinting--) discard
-} bind def
-/Ln /pop load def
-/Ap
-/pop load def
-/Ar
-{
- 72 exch div
- 0 dtransform dup mul exch dup mul add sqrt
- dup 1 lt
- {
- pop 1
- } if
- setflat
-} def
-/Mb
-{
- q
-} def
-/Md
-{
-} def
-/MB
-{
- Q
-} def
-/nc 3 dict def
-nc begin
-/setgray
-{
- pop
-} bind def
-/setcmykcolor
-{
- 4 npop
-} bind def
-/setcustomcolor
-{
- 2 npop
-} bind def
-currentdict readonly pop
-end
-end
-setpacking
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeFont: Univers
-Adobe_level2_AI5 /initialize get exec
-Adobe_Illustrator_AI5_vars Adobe_Illustrator_AI5 Adobe_typography_AI5 /initialize get exec
-Adobe_ColorImage_AI6 /initialize get exec
-Adobe_Illustrator_AI5 /initialize get exec
-[
-39/quotesingle 96/grave 128/Adieresis/Aring/Ccedilla/Eacute/Ntilde/Odieresis
-/Udieresis/aacute/agrave/acircumflex/adieresis/atilde/aring/ccedilla/eacute
-/egrave/ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis/ntilde
-/oacute/ograve/ocircumflex/odieresis/otilde/uacute/ugrave/ucircumflex
-/udieresis/dagger/degree/cent/sterling/section/bullet/paragraph/germandbls
-/registered/copyright/trademark/acute/dieresis/.notdef/AE/Oslash
-/.notdef/plusminus/.notdef/.notdef/yen/mu/.notdef/.notdef
-/.notdef/.notdef/.notdef/ordfeminine/ordmasculine/.notdef/ae/oslash
-/questiondown/exclamdown/logicalnot/.notdef/florin/.notdef/.notdef
-/guillemotleft/guillemotright/ellipsis/.notdef/Agrave/Atilde/Otilde/OE/oe
-/endash/emdash/quotedblleft/quotedblright/quoteleft/quoteright/divide
-/.notdef/ydieresis/Ydieresis/fraction/currency/guilsinglleft/guilsinglright
-/fi/fl/daggerdbl/periodcentered/quotesinglbase/quotedblbase/perthousand
-/Acircumflex/Ecircumflex/Aacute/Edieresis/Egrave/Iacute/Icircumflex
-/Idieresis/Igrave/Oacute/Ocircumflex/.notdef/Ograve/Uacute/Ucircumflex
-/Ugrave/dotlessi/circumflex/tilde/macron/breve/dotaccent/ring/cedilla
-/hungarumlaut/ogonek/caron
-TE
-%AI3_BeginEncoding: _Univers Univers
-[/_Univers/Univers 0 0 1 TZ
-%AI3_EndEncoding AdobeType
-%AI5_Begin_NonPrinting
-Np
-8 Bn
-%AI5_BeginGradient: (Black & White)
-(Black & White) 0 2 Bd
-[
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0 %_Br
-[
-0 0 50 100 %_Bs
-1 0 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Green & Blue)
-(Green & Blue) 0 2 Bd
-[
-<
-99999A9A9B9B9B9C9C9D9D9D9E9E9F9F9FA0A0A1A1A1A2A2A3A3A3A4A4A5A5A5A6A6A7A7A7A8A8A9
-A9A9AAAAABABABACACADADADAEAEAFAFAFB0B0B1B1B1B2B2B3B3B3B4B4B5B5B5B6B6B7B7B7B8B8B9
-B9B9BABABBBBBBBCBCBDBDBDBEBEBFBFBFC0C0C1C1C1C2C2C3C3C3C4C4C5C5C5C6C6C7C7C7C8C8C9
-C9C9CACACBCBCBCCCCCDCDCDCECECFCFCFD0D0D1D1D1D2D2D3D3D3D4D4D5D5D5D6D6D7D7D7D8D8D9
-D9D9DADADBDBDBDCDCDDDDDDDEDEDFDFDFE0E0E1E1E1E2E2E3E3E3E4E4E5E5E5E6E6E7E7E7E8E8E9
-E9E9EAEAEBEBEBECECEDEDEDEEEEEFEFEFF0F0F1F1F1F2F2F3F3F3F4F4F5F5F5F6F6F7F7F7F8F8F9
-F9F9FAFAFBFBFBFCFCFDFDFDFEFEFFFF
->
-<
-000102020304050506070808090A0B0B0C0D0E0E0F101111121314141516171718191A1A1B1C1D1D
-1E1F20202122232324252626272829292A2B2C2C2D2E2F2F303132323334353536373838393A3B3B
-3C3D3E3E3F404141424344444546474748494A4A4B4C4D4D4E4F5050515253535455565657585959
-5A5B5C5C5D5E5F5F606162626364656566676868696A6B6B6C6D6E6E6F7071717273747475767777
-78797A7A7B7C7D7D7E7F80808182828384858586878888898A8B8B8C8D8E8E8F9091919293949495
-96979798999A9A9B9C9D9D9E9FA0A0A1A2A3A3A4A5A6A6A7A8A9A9AAABACACADAEAFAFB0B1B2B2B3
-B4B5B5B6B7B8B8B9BABBBBBCBDBEBEBF
->
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0
-1 %_Br
-[
-1 0.75 0 0 1 50 100 %_Bs
-0.6 0 1 0 1 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Pink, Yellow, Green)
-(Pink, Yellow, Green) 0 3 Bd
-[
-<
-00000000000000000000000000000000000000010101010101010101010101010101010101010101
-01010101010202020202020202020202020202020202020202020203030303030303030303030303
-03030303030303030404040404040404040404040404040404040404050505050505050505050505
-05050505050505060606060606060606060606060606060606060707070707070707070707070707
-07070707080808080808080808080808080808080809090909090909090909090909090909090A0A
-0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0C0C0C0C0C0C0C0C0C
-0C0C0C0C0C0C0C0D0D0D0D0D
->
-<
-050506060606070708080809090A0A0A0B0B0C0C0D0D0E0E0F0F1010111112121313141415151617
-17181819191A1A1B1C1C1D1D1E1F1F202021222223232425252626272828292A2A2B2C2C2D2D2E2F
-2F3031313233333435353637373839393A3B3B3C3D3E3E3F4040414242434445454647474849494A
-4B4C4C4D4E4F4F505151525354545556575758595A5A5B5C5C5D5E5F5F6061626363646566666768
-69696A6B6C6C6D6E6F707071727373747576777778797A7B7B7C7D7E7F7F80818283838485868787
-88898A8B8B8C8D8E8F8F9091929394949596979898999A9B9C9D9D9E9FA0A1A2A2A3A4A5A6A7A7A8
-A9AAABACADADAEAFB0B1B2B2
->
-<
-CCCCCBCBCBCACACAC9C9C8C8C7C7C6C6C5C5C4C4C3C2C2C1C1C0C0BFBEBEBDBDBCBBBBBAB9B9B8B7
-B7B6B6B5B4B4B3B2B1B1B0AFAFAEADADACABAAAAA9A8A8A7A6A5A5A4A3A2A2A1A0A09F9E9D9C9C9B
-9A999998979696959493929291908F8E8E8D8C8B8A8A8988878686858483828181807F7E7D7C7C7B
-7A7978777776757473727171706F6E6D6C6B6A6A69686766656463636261605F5E5D5C5B5B5A5958
-5756555453525151504F4E4D4C4B4A49484746464544434241403F3E3D3C3B3A3938383736353433
-3231302F2E2D2C2B2A29282726252423222221201F1E1D1C1B1A191817161514131211100F0E0D0C
-0B0A09080706050403020100
->
-0
-1 %_Br
-<
-737271706F6E6D6C6B6A696867666564636261605F5E5D5C5B5B5A59585756555453525150504F4E
-4D4C4B4A4949484746454443434241403F3E3E3D3C3B3A3A393837363635343333323130302F2E2D
-2D2C2B2A2A29282827262525242323222121201F1F1E1D1D1C1C1B1A1A1918181717161615141413
-1312121111100F0F0E0E0D0D0C0C0C0B0B0A0A090908080807070606060505050404040303030202
-020201010101010000000000
->
-<
-00000000000000000000000001010101010101010101010101010101010101010101010102020202
-02020202020202020202020202020202020202020202030303030303030303030303030303030303
-03030303030303030303030303040404040404040404040404040404040404040404040404040404
-04040404040404040404050505050505050505050505050505050505050505050505050505050505
-050505050505050505050505
->
-<
-BFBFBFC0C0C0C0C0C0C0C0C0C1C1C1C1C1C1C1C1C1C2C2C2C2C2C2C2C2C2C2C3C3C3C3C3C3C3C3C3
-C3C4C4C4C4C4C4C4C4C4C4C5C5C5C5C5C5C5C5C5C5C5C6C6C6C6C6C6C6C6C6C6C6C6C7C7C7C7C7C7
-C7C7C7C7C7C7C8C8C8C8C8C8C8C8C8C8C8C8C8C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9CACACACACACA
-CACACACACACACACACACACBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCCCCCCCCCCCCCCCC
-CCCCCCCCCCCCCCCCCCCCCCCC
->
-0
-1 %_Br
-[
-0.05 0.7 0 0 1 50 100 %_Bs
-0 0.02 0.8 0 1 57 36 %_Bs
-0.45 0 0.75 0 1 37 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Purple, Red & Yellow)
-(Purple, Red & Yellow) 0 3 Bd
-[
-0
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A
->
-<
-CCCCCCCDCDCDCDCDCECECECECECFCFCFCFD0D0D0D0D0D1D1D1D1D1D2D2D2D2D2D3D3D3D3D3D4D4D4
-D4D5D5D5D5D5D6D6D6D6D6D7D7D7D7D7D8D8D8D8D8D9D9D9D9DADADADADADBDBDBDBDBDCDCDCDCDC
-DDDDDDDDDDDEDEDEDEDFDFDFDFDFE0E0E0E0E0E1E1E1E1E1E2E2E2E2E2E3E3E3E3E4E4E4E4E4E5E5
-E5E5E5E6E6E6E6E6E7E7E7E7E7E8E8E8E8E9E9E9E9E9EAEAEAEAEAEBEBEBEBEBECECECECECEDEDED
-EDEEEEEEEEEEEFEFEFEFEFF0F0F0F0F0F1F1F1F1F1F2F2F2F2F3F3F3F3F3F4F4F4F4F4F5F5F5F5F5
-F6F6F6F6F6F7F7F7F7F8F8F8F8F8F9F9F9F9F9FAFAFAFAFAFBFBFBFBFBFCFCFCFCFDFDFDFDFDFEFE
-FEFEFEFFFFFF
->
-0
-1 %_Br
-<
-E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBE
-BDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A99989796
-9594939291908F8E8D8C8B8A898887868584838281807F7E7D7C7B7A797877767574737271706F6E
-6D6C6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746
-4544434241403F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E
-1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100
->
-<
-E5E6E6E6E6E6E6E6E6E7E7E7E7E7E7E7E7E7E8E8E8E8E8E8E8E8E8E9E9E9E9E9E9E9E9E9EAEAEAEA
-EAEAEAEAEAEBEBEBEBEBEBEBEBEBECECECECECECECECECEDEDEDEDEDEDEDEDEDEEEEEEEEEEEEEEEE
-EEEFEFEFEFEFEFEFEFEFF0F0F0F0F0F0F0F0F0F1F1F1F1F1F1F1F1F1F2F2F2F2F2F2F2F2F2F3F3F3
-F3F3F3F3F3F3F4F4F4F4F4F4F4F4F4F5F5F5F5F5F5F5F5F5F6F6F6F6F6F6F6F6F6F7F7F7F7F7F7F7
-F7F7F8F8F8F8F8F8F8F8F8F9F9F9F9F9F9F9F9F9FAFAFAFAFAFAFAFAFAFBFBFBFBFBFBFBFBFBFCFC
-FCFCFCFCFCFCFCFDFDFDFDFDFDFDFDFDFEFEFEFEFEFEFEFEFEFFFFFFFFFF
->
-<
-00010203040405060708090A0B0C0C0D0E0F10111213141415161718191A1B1C1D1D1E1F20212223
-242525262728292A2B2C2D2D2E2F30313233343535363738393A3B3C3D3D3E3F4041424344454546
-4748494A4B4C4D4E4E4F50515253545556565758595A5B5C5D5E5E5F60616263646566666768696A
-6B6C6D6E6E6F70717273747576767778797A7B7C7D7E7F7F80818283848586878788898A8B8C8D8E
-8F8F90919293949596979798999A9B9C9D9E9F9FA0A1A2A3A4A5A6A7A7A8A9AAABACADAEAFAFB0B1
-B2B3B4B5B6B7B8B8B9BABBBCBDBEBFC0C0C1C2C3C4C5C6C7C8C8C9CACBCC
->
-0
-1 %_Br
-[
-0 0.04 1 0 1 50 100 %_Bs
-0 1 0.8 0 1 50 50 %_Bs
-0.9 0.9 0 0 1 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Rainbow)
-(Rainbow) 0 6 Bd
-[
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-1
-0
-0
-1 %_Br
-1
-<
-0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E
-2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556
-5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E
-7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6
-A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE
-CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6
-F7F8F9FAFBFCFDFEFF
->
-0
-0
-1 %_Br
-1
-<
-00000000000000000000000000000000000001010101010101010101010101010101010101010101
-01010101010101010101010101010202020202020202020202020202020202020202020202020202
-02020202020202020202030303030303030303030303030303030303030303030303030303030303
-03030303030304040404040404040404040404040404040404040404040404040404040404040404
-04040505050505050505050505050505050505050505050505050505050505050505050505050606
-06060606060606060606060606060606060606060606060606060606060606060606070707070707
-07070707070707070707070707070707
->
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0
-1 %_Br
-<
-000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
-28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
-505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
-78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
-A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
-C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
-F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
->
-0
-1
-0
-1 %_Br
-0
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-1
-0
-1 %_Br
-[
-0 1 0 0 1 50 100 %_Bs
-1 1 0 0 1 50 80 %_Bs
-1 0.0279 0 0 1 50 60 %_Bs
-1 0 1 0 1 50 40 %_Bs
-0 0 1 0 1 50 20 %_Bs
-0 1 1 0 1 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Steel Bar)
-(Steel Bar) 0 3 Bd
-[
-<
-FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
-D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
-AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
-87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
-5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
-37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
-0F0E0D0C0B0A09080706050403020100
->
-0 %_Br
-<
-000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
-28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
-505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
-78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
-A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
-C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
-F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
->
-0 %_Br
-[
-0 0 50 100 %_Bs
-1 0 50 70 %_Bs
-0 0 50 0 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Yellow & Orange Radial)
-(Yellow & Orange Radial) 1 2 Bd
-[
-0
-<
-0001010203040506060708090A0B0C0C0D0E0F10111213131415161718191A1B1C1D1D1E1F202122
-232425262728292A2B2B2C2D2E2F303132333435363738393A3B3C3D3E3E3F404142434445464748
-494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60606162636465666768696A6B6C6D6E6F
-707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C
->
-<
-FFFFFFFFFEFEFEFEFEFEFEFDFDFDFDFDFDFCFCFCFCFCFCFBFBFBFBFBFBFAFAFAFAFAFAF9F9F9F9F9
-F9F8F8F8F8F8F8F7F7F7F7F7F7F6F6F6F6F6F6F5F5F5F5F5F5F4F4F4F4F4F3F3F3F3F3F3F2F2F2F2
-F2F2F1F1F1F1F1F0F0F0F0F0F0EFEFEFEFEFEFEEEEEEEEEEEDEDEDEDEDEDECECECECECEBEBEBEBEB
-EBEAEAEAEAEAE9E9E9E9E9E9E8E8E8E8E8E8E7E7E7E7E7E6E6E6E6E6E5
->
-0
-1 %_Br
-[
-0 0 1 0 1 52 19 %_Bs
-0 0.55 0.9 0 1 50 100 %_Bs
-BD
-%AI5_EndGradient
-%AI5_BeginGradient: (Yellow & Purple Radial)
-(Yellow & Purple Radial) 1 2 Bd
-[
-<
-000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
-28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
-505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
-78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
-A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
-C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
-F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
->
-<
-1415161718191A1B1C1D1E1F1F202122232425262728292A2A2B2C2D2E2F30313233343536363738
-393A3B3C3D3E3F40414142434445464748494A4B4C4D4D4E4F50515253545556575858595A5B5C5D
-5E5F60616263646465666768696A6B6C6D6E6F6F707172737475767778797A7B7B7C7D7E7F808182
-83848586868788898A8B8C8D8E8F90919292939495969798999A9B9C9D9D9E9FA0A1A2A3A4A5A6A7
-A8A9A9AAABACADAEAFB0B1B2B3B4B4B5B6B7B8B9BABBBCBDBEBFC0C0C1C2C3C4C5C6C7C8C9CACBCB
-CCCDCECFD0D1D2D3D4D5D6D7D7D8D9DADBDCDDDEDFE0E1E2E2E3E4E5E6E7E8E9EAEBECEDEEEEEFF0
-F1F2F3F4F5F6F7F8F9F9FAFBFCFDFEFF
->
-<
-ABAAAAA9A8A7A7A6A5A5A4A3A3A2A1A1A09F9F9E9D9D9C9B9B9A9999989797969595949393929191
-908F8F8E8D8D8C8B8B8A8989888787868585848383828181807F7F7E7D7D7C7B7B7A797978777776
-7575747373727171706F6F6E6D6D6C6B6B6A6969686767666565646362626160605F5E5E5D5C5C5B
-5A5A5958585756565554545352525150504F4E4E4D4C4C4B4A4A4948484746464544444342424140
-403F3E3E3D3C3C3B3A3A3938383736363534343332323130302F2E2E2D2C2C2B2A2A292828272626
-25242423222121201F1F1E1D1D1C1B1B1A1919181717161515141313121111100F0F0E0D0D0C0B0B
-0A090908070706050504030302010100
->
-0
-1 %_Br
-[
-0 0.08 0.67 0 1 50 14 %_Bs
-1 1 0 0 1 50 100 %_Bs
-BD
-%AI5_EndGradient
-%AI5_End_NonPrinting--
-%AI5_BeginPalette
-0 0 Pb
-Pn
-Pc
-1 g
-Pc
-0 g
-Pc
-0 0 0 0 k
-Pc
-0.75 g
-Pc
-0.5 g
-Pc
-0.25 g
-Pc
-0 g
-Pc
-Bb
-2 (Black & White) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.25 0 0 0 k
-Pc
-0.5 0 0 0 k
-Pc
-0.75 0 0 0 k
-Pc
-1 0 0 0 k
-Pc
-0.25 0.25 0 0 k
-Pc
-0.5 0.5 0 0 k
-Pc
-0.75 0.75 0 0 k
-Pc
-1 1 0 0 k
-Pc
-Bb
-2 (Pink, Yellow, Green) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0 0.25 0 0 k
-Pc
-0 0.5 0 0 k
-Pc
-0 0.75 0 0 k
-Pc
-0 1 0 0 k
-Pc
-0 0.25 0.25 0 k
-Pc
-0 0.5 0.5 0 k
-Pc
-0 0.75 0.75 0 k
-Pc
-0 1 1 0 k
-Pc
-Bb
-0 0 0 0 Bh
-2 (Yellow & Purple Radial) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0 0 0.25 0 k
-Pc
-0 0 0.5 0 k
-Pc
-0 0 0.75 0 k
-Pc
-0 0 1 0 k
-Pc
-0.25 0 0.25 0 k
-Pc
-0.5 0 0.5 0 k
-Pc
-0.75 0 0.75 0 k
-Pc
-1 0 1 0 k
-Pc
-Bb
-2 (Rainbow) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.25 0.125 0 0 k
-Pc
-0.5 0.25 0 0 k
-Pc
-0.75 0.375 0 0 k
-Pc
-1 0.5 0 0 k
-Pc
-0.125 0.25 0 0 k
-Pc
-0.25 0.5 0 0 k
-Pc
-0.375 0.75 0 0 k
-Pc
-0.5 1 0 0 k
-Pc
-Bb
-2 (Steel Bar) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0 0.25 0.125 0 k
-Pc
-0 0.5 0.25 0 k
-Pc
-0 0.75 0.375 0 k
-Pc
-0 1 0.5 0 k
-Pc
-0 0.125 0.25 0 k
-Pc
-0 0.25 0.5 0 k
-Pc
-0 0.375 0.75 0 k
-Pc
-0 0.5 1 0 k
-Pc
-Bb
-2 (Purple, Red & Yellow) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.125 0 0.25 0 k
-Pc
-0.25 0 0.5 0 k
-Pc
-0.375 0 0.75 0 k
-Pc
-0.5 0 1 0 k
-Pc
-0.25 0 0.125 0 k
-Pc
-0.5 0 0.25 0 k
-Pc
-0.75 0 0.375 0 k
-Pc
-1 0 0.5 0 k
-Pc
-Bb
-2 (Green & Blue) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.25 0.125 0.125 0 k
-Pc
-0.5 0.25 0.25 0 k
-Pc
-0.75 0.375 0.375 0 k
-Pc
-1 0.5 0.5 0 k
-Pc
-0.25 0.25 0.125 0 k
-Pc
-0.5 0.5 0.25 0 k
-Pc
-0.75 0.75 0.375 0 k
-Pc
-1 1 0.5 0 k
-Pc
-Bb
-0 0 0 0 Bh
-2 (Yellow & Orange Radial) -4014 4716 0 0 1 0 0 1 0 0 Bg
-0 BB
-Pc
-0.125 0.25 0.125 0 k
-Pc
-0.25 0.5 0.25 0 k
-Pc
-0.375 0.75 0.375 0 k
-Pc
-0.5 1 0.5 0 k
-Pc
-0.125 0.25 0.25 0 k
-Pc
-0.25 0.5 0.5 0 k
-Pc
-0.375 0.75 0.75 0 k
-Pc
-0.5 1 1 0 k
-Pc
-0 0 0 0 k
-Pc
-0.125 0.125 0.25 0 k
-Pc
-0.25 0.25 0.5 0 k
-Pc
-0.375 0.375 0.75 0 k
-Pc
-0.5 0.5 1 0 k
-Pc
-0.25 0.125 0.25 0 k
-Pc
-0.5 0.25 0.5 0 k
-Pc
-0.75 0.375 0.75 0 k
-Pc
-1 0.5 1 0 k
-Pc
-PB
-%AI5_EndPalette
-%%EndSetup
-%AI5_BeginLayer
-1 1 1 1 0 0 0 79 128 255 Lb
-(Layer 1) Ln
-0 A
-800 Ar
-0 J 0 j 1 w 4 M []0 d
-%AI3_Note:
-0 D
-0 XR
--4014 283.5 m
-4626 283.5 L
-(N) *
-453.5 4716 m
-453.5 -3924 L
-(N) *
-85 4716 m
-85 -3924 L
-(N) *
--4014 765.5 m
-4626 765.5 L
-(N) *
-0 To
-1 0 0 1 234 722 0 Tp
-TP
--18.8794 0 Td
-0 Tr
-0 O
-0 g
-/_Univers 10 Tf
-0 Ts
-100 Tz
-0 Tt
-1 TA
-%_ 0 XL
-36 0 Xb
-XB
-0 0 5 TC
-100 100 200 TW
-0 0 0 Ti
-1 Ta
-0 0 2 2 3 Th
-0 Tq
-0 0 Tl
-0 Tc
-0 Tw
-(window) Tx
-(\r) TX
-TO
-0 To
-1 0 0 1 200 696.5 0 Tp
-TP
--15.5444 0 Td
-0 Tr
-(button) Tx
-(\r) TX
-TO
-0 To
-1 0 0 1 268 696.5 0 Tp
-TP
--13.8867 0 Td
-0 Tr
-(frame) Tx
-(\r) TX
-TO
-0 To
-1 0 0 1 234 671 0 Tp
-TP
--27.7661 0 Td
-0 Tr
-(radiobutton) Tx
-(\r) TX
-TO
-0 To
-1 0 0 1 302 671 0 Tp
-TP
--27.7661 0 Td
-0 Tr
-(radiobutton) Tx
-(\r) TX
-TO
-0 R
-0 G
-200 705 m
-234 719 l
-268 705 l
-S
-234 679.5 m
-268 693.5 l
-302 679.5 l
-S
-LB
-%AI5_EndLayer--
-%%PageTrailer
-gsave annotatepage grestore showpage
-%%Trailer
-Adobe_Illustrator_AI5 /terminate get exec
-Adobe_ColorImage_AI6 /terminate get exec
-Adobe_typography_AI5 /terminate get exec
-Adobe_level2_AI5 /terminate get exec
-%%EOF
diff --git a/lib/gs/doc/src/images/image.gif b/lib/gs/doc/src/images/image.gif
deleted file mode 100644
index 62aef94dc3..0000000000
--- a/lib/gs/doc/src/images/image.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/image.ps b/lib/gs/doc/src/images/image.ps
deleted file mode 100644
index 98d19a2047..0000000000
--- a/lib/gs/doc/src/images/image.ps
+++ /dev/null
@@ -1,2103 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/image.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 317 357 460
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 468 string def
-
-% define space for color conversions
-/grays 156 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 317 translate
-
-% size of image (on paper, in 1/72inch coords)
-156.02400 142.99200 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-156 143 8 % dimensions of data
-[156 0 0 -143 0 143] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000080
-000080ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000
-000000000000000000000000000000000000000000c0c0c0c0c0c0737373000000000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000
-000000000000000000000000000000000000000000c0c0c0c0c0c0737373000000000080
-000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080000080ffffff000080000080ffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080000080000080000080000080000080ffffff
-ffffff000080ffffff000080ffffffffffffffffff000080ffffffffffffffffff000080
-000080000080ffffffffffffffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffffffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000
-c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffffffffff000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080ffffff
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080000080000080000080000080ffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffffffffffffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffffffffffffffffffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000
-c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080ffffff
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080
-000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffffffffff000080ffffffffffff000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffffffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000
-000000000000000000000000000000000000000000c0c0c0c0c0c0737373000000000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffffffff000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080ffffffffffff000080000080
-ffffffffffff000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffff737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373000000ffffff737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373000000000080
-000080ffffff737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffffffffffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000080
-000080000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d99c8c6fa5906b9c8c6fa58c7baf9f94a08883a4a196a1988d948677
-a1988da08883a088839687879687879687879687879687878e7778a1988d948677a3908c
-8e7778a4a196a08883a1988da3908cb19ca3b19ca3b19ca3b1a8a2a1988db7b5a0a4a196
-b1a8a2a3908c948677a1988daf9f94948677a4a196a4a196bfadb0a4a196bcb8aea1988d
-a08883a0947f948677b9ada5a1988da0947fb1a488a08883a4a196a08883a4a196a4a196
-a4a196bda49ebfadb0968787b9ada5c7beb3cebdada4a196bcb8aed7d1c0bcb8aeb1a8a2
-b1a8a2a4a196948677a4a196a3908c968787a4a1968e7778b19ca3a1988da4a196a1988d
-a4a196c7beb3c7beb3c7beb3a4a196b19ca3a4a196a4a196a1988da1988db1a8a2b7b5a0
-a3908ca4a196a3908cd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b5947b9c7b63bd94848e6352cea594bd9c94a58c7ba08883b99c8c
-a58c7bc6ad94a58c7bc6a594a58c7ba58c7ba0947fb19494a58c7b9c8c6faf9f94b19494
-a3908ca1988dc6b598b1a8a2bcb8aec7beb3bfadb0b1a8a2a4a196b1a8a2b2aa94b9ada5
-b1a8a2a0947faf9f94bd9c94a0947faf9f948c7f6ba4a196a0947fbda49ea4a196c6b598
-948677af9f94af9f94a4a196b1a488d0ba99ad9c84bda49ec6a5a0bda49ea08883a4a196
-a088838e7778bda49eb1a8a2d7d1c0d2c7afc6b598eddfc8d7d1c0d7d1c08c7f6bad948c
-caab9ea58c7bceb59cccb1abaf9f94bda49eaf9f94d2c7afa0947fd7d1c0d7d1c0eddfc8
-b1a8a2b7b5a0bcb8aea3908ca4a196d7d1c0bfadb0a4a196a4a196c7beb3d2c7afb1a8a2
-b1a8a2eddfc8b1a8a2d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9bd8c73b57f6bbd8c73a7735dc08c7e9c675a8c634aa57f679c735e
-bd8c739c7352ad7367996d478c634a9c7352ad7b63ad8c7bc6a58cb58c73a5846bb19494
-846b6e968787b19494a4a196a4a196b7b5a0b1a8a2d2c7afc7beb3d2c7afb9ada5c7beb3
-ccb1abd7d1c0e4bda2bdaa91c6ad94ad9484caab9ead9c84c6b598c6b598caab9ea58c7b
-b59c84b99c8ca59473a0947fc6ad94bda58cc1a584a58c7bbda49e9c7b6d8c7f6b948677
-ceb59cb19494af9f94a4a196a4a196af9f947d584a9c8c63948463ceb594a5846b9c735e
-ad9473a57f67ad946bad9c73ad9473c6ad8cad9473947b63b1a488b1a488bdb594a3908c
-bcb8aeb9ada5bda49ebcb8aea3908cb1a8a2bcb8aea1988db9ada5b7b5a0a0947fbcb8ae
-b7b5a0a1988dbda49ed9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9daa08caa7052daa08cda9c848d4938a7735d996040a7735d985e52
-9c7352da9c8490573d90573d8d4938996040bd9168b57f6be2b399ad7e4f9c7b63d6b9a9
-6750438e777880695eb1a8a2d7d1c0eddfc8d2c7afd2c7afad9c84c6b598b19ca391706d
-9473637d584a7d584ac69c8c7d584a9c7b63a5846ba5906bcaab9ec6ad8cbda58c886b46
-a5846b9c7b63886b46948677bd9c7b9f7e5ab5947b8c634a9c7b6d67504383584dad947b
-b99c8cbd9c942b181c4f362fd5c2bead947b8c634aa5845aad8c6bad8c6bb58c738c634a
-906f4ee4bda2c69c73906f4ebd9c73ad946bad9473a5906bad9c7bd6b9a9b1a488af9f94
-a08883a0947fa0947fa1988da4a196cebdada08883c7beb3a0947fb1a8a2a4a196c6b598
-b2aa94b59c84b1a488d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d99c7352e2b3999c7352a36150bd9168c69473a7735dad8463462113
-ad7b6b9c675ab57f6b844832b77b5dbd9168d69c7bd0927ba77047b58456b58c73cea594
-a088832d0f0b5e4542d7d1c0c7beb3ad9c84a59473b59c7b947b63846b6e5e4542675043
-7d584a462113986d5e9c7352906f4e906f4ec69c84a5906ba57f67bd9c7bad94738c634a
-7e5b39947b569c7b6379483d886040906f469c7352906f4e986d5e9c776bad8c735e3e28
-ad947bc69c942d0f0b2b181cb7b5a0d6b9a9ad846b9f7e5a8c634ac69c84947b569c7b63
-cea58c76533e947b56cead8cb5947bcead8cbd9c84ad8c73bda58c9c8c6fa58c7bbda49e
-a4a196ad948c948677a08883b2aa94ccb1ab94846ba4a196a08883af9f94af9f94a0947f
-ad947ba0947fbda58cd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b58c7390573d985e52996d47bd8c73b58c6bbd9473b58c739c735e
-bd9484e2b399ad73679c675aad7b63a7735db57f6baa7052bd8c63bd8c63ce9c77c6a58c
-5e4542250814180814d2c7afbdb5949c8c6fa5846ba5846b948677a57f679c7b6d9c7b6d
-9c7b6d1b0500e2b399ad8c7bb58c6be4bda2996d47ad8c6bad846bb5947bad8c6b703d29
-7e5b398e63529c7b638e6352ad846bad8463ad7f5a844a4483584d8e63528c634aa58c63
-c69c8c99797b1000002b181cbfadb0eacba5ad7b63b58c73ad846ba5846ba57f679c7b6d
-a59473a57f679c8463b58c73bd9c7b9c7b63b5947bad9484c6ad94d6b9a9caab9e9c9178
-ccb1abbdaa91a08883bdb594b19494ad9c84a08883948677a1988da0888380695e948677
-a5846b80695e947b63d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9bd947b996d47906f4ea7735dc08c7e985e52b58c73bd947b844a44
-ad8c739c675a9c73528d49389c675aad7b63b57f6bb57f6bda9c84e2b399b5946b947b63
-2b181c2b181c100008d6bd98b1a4889c735e9473639c776bbd9484a5846ba5847391706d
-5e3e28986d5ebd9c84bd947bad846bceb5949c7b63947b56b5947bb58c73a5846b462113
-8e63527d584a844a447e5b399c7352996d47b58c6b703d2983584d9c7b639c7b6db5946b
-947b56bd9c9418001425101cc7beb3b18a87ad846bad7b63a7735d9c7b63ad8c738e6352
-a5846bad9473b5947bad846b8e6352a59473734c2e947b63a58c7bc6ad8c948677ceb59c
-a58c7ba59473ad9c7baf9f94ad9484af9f94947b63b9ada5a08883ad9484a088838c7360
-94846bad948c76533ed9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ad846bad7b6bbd8c7379483d985e52ad7b638e63529c735e906f4e
-a7735dcea084985e529c7352844832a56b4eb87158d6ad96bd9473a5845a9c7b635e3e28
-210810180014100000c1a584dab28ccea594bd94848e6352a97b779c735eb5947b3b1820
-260608947363a5846b734c2ecead8c8c634ab5947b947b569c735ec69c84ad847379483d
-94685a9c735e8c634a8e635279483d9c7352a7735d76533e5526179c776b9c7b63b5946b
-bd948c6a5055100008180814846b6eebcfb89c7352a7735db77b5dad7b639c7b63ad8c6b
-c1a5848c634aad8c63bd9c84ad8c738c634aa5906b9c7b63c1a584c1a584c1a584b1a488
-bda58cb99c8cb99c8cc6b5988c7f6b91706da088839486779c7b6d8e7778947b63948677
-80695ea08883947b63d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9bd9473b58c73906f469c7352ad846b844a44a97b778a5a58ad7b63
-c6947fa36150a77047b87158c07c66b58456cead78c08c7e8d49389f7e5aa57f67250814
-1800141800141000088c6b5ad6b9a9ad9c848c6b5a80695e9473637e5c586d463c462113
-4f362f9c7b63947b569c7b63b58c737d584aad8c6b947b56bd9473bd9c7b947b63846b52
-8e635294685a846b528c634a734c2ead846bbd91689c7352b58c739f7e5ac69c849c7b63
-ad846b6d463c10000025101c80695ecaab9ebd8c63ad7b63bd947bad8c6b9c7b63947b56
-ad8c6b906f4e886b46947b569c7352bd94738e6352ad8c6bc6a58ca5906bad9c73c6ad8c
-9c8c6fb99c8c948677a0947fa0947fa1988d9c91789c847b73575580695e7e5c589c847b
-80695e9c7b6d947b63d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ad7b63906f46ad7b63b58c6bc08c7ecea58c986d5e986d5ec08c7e
-d69c7b844832b87158ca946fd0927bdaad84daad8476533e8c634aa7735d947363350c1a
-382328100008080008947b63c6ad8c552617947b6380695e947b569c7b6db594847e5c58
-7e5c58b5947bb5947bbd9c7bc1a5849c7b63bd9484bd9168bd9473b5947bbd9c7b947b56
-9c7b639c735e9c7352cea084b5947b9c7352b58c6b9c73529c73529f7e5a9c7b63a7735d
-b5947b986d5e180014080008382328c6ad94cea0847e5b398c634a886040bd947376533e
-ad946bb5947bad946bad7f5a947b56bd8c73734c2ead8c73b58c73c6b584b5a57bb59c7b
-ad9484bda58cbda49ea0947faf9f948e77788c7f6baf9f948c736080695e735755735755
-6750438c73609c7b6dd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9bd9473bd8c73ad846bbd8c73a7735dad8473986d5e8e6352ad7367
-985e52996040844832d0927bd0927bd0927bdaad84703d298c634a996d473c160a350c1a
-180008180814180008886b46ceb59cc1a584b5947bc6a58cad8c7bb5947bad8c7ba97b77
-b59484bd9c849c7352996d47bd9c7bbd947b9c776bbd9168c69c739f7e5a9c73529c735e
-9c73528c634aad7b63906f4ea7735dad8463b57f6bad7e4fad8463a7735dbd9473c39565
-b58c73a97b771b0500180920382328caab9ead7f5ab58c6bd0927bad846ba7735dc1a584
-ad846b947b56ad8c7b8c634a9f7e5abd947b9c7b63ad846bb5947bc1a584b59c73bd9c84
-9c8463b59484a58c7bb19494948677a58c7bbda49ea088838c736094846ba58c7b9c8c6f
-9c7b6d94846b947b63d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ad846bc6947fad7b63c08c7e76533ea7735d986d5ead7367da9c84
-8d4938906f4ecea084bd9484cea594703d29844a44b57f6bb57f6bad846b7d584a675043
-2a142b10000010000876533eceb594bd9c84b5947b996d47ad846b9c7b63d6ad9694685a
-846b529c735ec1a584c69c7bad8c6bb58c73ad846bcea084ad8463bd9168985e528c634a
-8c634aad8463886040b58c6be2b399b58456bd8c63ad8463a77047ad8463bd9473bd8c63
-ad8c63c69c8c18001425101c100810ceb59c9c735e996d47734c2ea07b4ead846bcea084
-8c634a9c735e9c7b63bd9473c69c84bd9473bd9c7b9c7b63a57f67bd9c7bad8c6b9c7b63
-b5947bd6b9a9a59473ad9484947b63a3908ca58c7baf9f949486779c7b6da1988d9c7b6d
-a08883a58c7b948677d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9985e529c7352cea084cea58c945852cea084985e529c7b63b77b5d
-90573db57f6bbd94845526175a2e2779483d5a2e27844832703d29996d477d584a846b6e
-180014180014100810734c2eebcfb8bd9c7beacba5cead8ccea084cea084ad846b947b56
-8c634a9c735ecead8ccea084ad8c6bbd8c73c69c7bca946fd69c7bda9c84a07b4ec69c7b
-9c7352a7735dad7e4fbd9473ad8463b77b5d996040a77047c395658448329c7352bd9168
-bd9473c69c8c100000100008100008d5c2bea7735dbd9473ad846bad8463bd9473985e52
-5e3e2883584dbd947bc08c7e9f7e5a9f7e5a9f7e5abd9473906f4eb5947b996d479c8463
-bd9c7bc6a58ccea594ad9484947b63846b6ead948c9486779c847b8e7778ad947b8c7f6b
-a58c7bad948cb59c84d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d99c73529c675aad7b6bc08c7e9c7352b5887ba7735d985e52c08c7e
-844a449c675a55261784483279483dad7367985e5290573dad7b638c634a9c7b6d3b1820
-25101c100000100810846b52eacba5d6bd98bd9c7bcea084c69c7bcea0849c735eb58c73
-bd9473bd9473ad846ba07b4eb58c73c69c7bbd9168ca946faa7052ad8463cea084a7735d
-9c7352a7735dad84639c7352ad84639c7352b77b5dc69c73cea084ad7f5ab58c73c39565
-b59c73b5887b100008100008180814d6b9a9985e52bd9168ad846b9f7e5a9c735e996d47
-703d297e5b39c69c8cad846bb58c73bd9c7bcead8ccead8ca5845ab58c73ad846bcead8c
-ad94739c7b63b59c7bceb59ca088839c7b6da3908c5e454280695e94846bad948c91706d
-947b63846b6e947b63d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d99c675a9c7352844a449c735ea9695cad7367cead8ca7735db57f6b
-703d298448328d4938a5635a844a445526179c735e844832ad7b639c735e7d584a44272e
-21081018001418000880695eccb1abc1a584d7c69abd9168cead8c9c735ed6ad96ad7f5a
-ad8c6bbd9168c69c7bd0927bbd9473b58c6bd0927bb77b5db77b5d985e52a7735d9c7352
-9c7352886040bd9473bd9473b58c73bd8c639f7e5aa7735dbd94739c7352b5947ba5845a
-bd9c7bb594842b181c080008100000c6a5a0a7735dc69c7b76533eb58c73c69c84ad8c6b
-7e5b39ad84738c634a9c7b63c69c7bb58c73b59c73886b46985e528c634aad7b63b59c7b
-cead8cc1a584947b63d6b9a9af9f94a088835e4542948677bda49eaf9f94ad948494846b
-947b638c7360a08883d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ad846b9458529c735eb5736bb58473bd8c73da9c84ad7e4fb5887b
-844832844a44a5635a8d4938844832a9695c7e5b39844a44ad846b8c634a46211344272e
-180014180008100008735755ebcfb8ceb594cead8cbd9c73b58c73c69c7bad846b9c7352
-ad7f5abd91689f7e5aad846bbd8c63a7735dad7f5abd9473b57f6bb57f6bb58c739f7e5a
-9c73529f7e5aad7e4f9c7b63ad846b996d47bd9473ce9c77cea084c69c7bbd947bbd9c7b
-bd9c7b83584d180814180008180814cea594b87158bd9c84947b568e6352a57f67886040
-8e6352a5846bc69c847e5b39986d5ead7f5a947b56b5946bb5946bb58c73ad846bad8c6b
-b59c7ba5906bb1a488ad947b7e5c588c7f6bbfadb0846b6ea58c7b8c7f6b80695e91706d
-91706d8c7360a58c7bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d99c73529c7352ad7b6b844a44bd9473b57f6b9c73529c675a844832
-985e52844832844832703d29a97b778e63525e3e2894685a986d5e76533e8448327e5c58
-2508141000080b0319735755decaa4d2c7afd7c69aad9c73a58c639c8c63ad8c6bb5947b
-b59c739f7e5aa7735db5946bad7f5ac69c73c69c73a77047ad7f5ab58456ad8c63ad7e4f
-b58c73ad7f5a9c7b63b29460ad7f5abd9c7bbd94739c7b639c7b63ad947b947b638c6b5a
-ad8c7344272e180008180920100000a58c7bbd9473906f46ad846b9c7b63947b56a58c7b
-ad846bb5947bb5947b9c8463ad8c6ba59473bd9c84b5947bad947ba59473bd9c94ad947b
-9c7b6d9c7b6dad8c73ad9c84947b63846b6ea0947f8c7360948677af9f948c7f6ba0947f
-a58c7b947b63a58c7bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c395659c7352c68c84a7735dda9c84ad7e4fd0927b9c7352945852
-a5635a844a44552617ad7367906f4e8e63528c634a8c634a9c7352985e52986d5e552617
-1000081800140b0319846b52d7d1c0b1a488ceb5949c8463947b63a58c63a5846b7d584a
-b58c73a57f67c1a584ad8463bd9473b58c6ba7735dca986bc39565b58c6bc39565ad7b63
-b58c73b58c73b58c739c7352c69c7bbd9473b58c73cea084b5947b947b63ad8c73b59c7b
-e4bda2a08883180014100008180014bd94849c7352b58c73996d478e63529c7b639c776b
-a58473bd94847e5b39bda58cc6ad8c8c7360c6a58cc6ad8cb59484b59c84947b63a5846b
-a58c7bb59c84ceb59cccb1aba59473a08883a0947f91706daf9f94a0947f91706d8c7360
-91706dad948cad948cd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9daa08cc08c7e9c7352ad7b63daa08cbd9168ad7b63945852a36150
-844832a7735db77b5d8d49387e5b39bd846fad846bb58c6bc6947f9c73529c735e5e3e28
-2508141800080b0319735755ebcfb8caab9ead947bceb594ad8c73d6b9a9bd9c84ad8c6b
-c6a58cb5947bbd9c7b996d47bd9473d0927bb58c6bb77b5dad8463b58c6bdaa08cc69c73
-b58c739f7e5a9f7e5abd8c73bd8c73c08c7ebd9473bd9473bd947bbd9c7bb59c7bb59c73
-bd9c7bc69c8c180014180008100008ad8c7bb77b5d906f4e9c776bb58c739c7b6d8c6b5a
-83584dad8c739c7b6db59c7bbd9c84ceb594bda58c8c7360947b63947b63a59473bd9c84
-a5846bbda58ca59473ad9c7bad9484a58c7b9c847b8c73608e7778a58c7b9c847b8c7360
-947b63a0947f948677d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d98d4938b57f6b9c675ada9c84da9c84b58456a56b4ea5635aa56b4e
-a36150985e52a361508c634aa7735da7735d9c7352bd8c63c69c73bd9473b584738a5a58
-1b05001800082a142b846b52caab9ead947bd6b9a9b59c7bad8c73c6a58ca57f67a5906b
-a5846bb5947bad846b9c7352b58c6bc69c7ba770479c7352a770479c7352bd9473ad846b
-ad846bad846bb58c73ad8463c08c7ead8c63a7735dbd9168bd9168ad8c6bc69c73cead78
-cead8cceb59c2d0f0b100000250814b5887b985e529c7b6394685a7d584aa58c7b5e3e28
-9c7b6da58473947363ceb59c9c8463b59c84947b5676533ea59473a5846bb5947ba5846b
-a59473a59473a59473ad947ba5846baf9f947e5c589c847b7e5c58a58c7b947b639c7b6d
-af9f94a0947fcaab9ed9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9cea084ad7b63985e52b58c6bda9c84a56b4e9c73525526178d4938
-b87158ad7b63844832703d29844832985e529c7352daad84c08c7ecea084b99c8c735755
-210810291021080010846b52decaa4d6b9a98c6b5ad6bd98cea594c1a584bd9c7bad9c7b
-ad946bc1a584b59c73ad846bad8463bd8c63ad7e4fbd8c63ad8463bd8c63ce9c77ad8c6b
-ad8c63bd9473ceb594bd9473bd9c7bc69c73cea084cea084cead78c1a584c6a577cead8c
-c1a5849c7b6d382328100000180814b59484985e52a57f679c7b6d8e6352986d5e8a5a58
-ad847ba58c7bcea5949c84639c7b6da5906bad8c73a5846ba59473c6a58ca59473a58c7b
-a5846bc6ad94a59473a59473b99c8cad9484947b636750436d463c99797b6750439c7b6d
-ad9484a5846baf9f94d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ad7b63ad7b6b844a44ad8463ca946fa7735dbd846fa9695cb57f6b
-b57f6b844832703d29985e529c675a985e52daad849c735e947b565a2e275a2e272b181c
-25101c2a142b18001476533eebcfb8947b635e3e28947b63ceb59c9c7b6dbda58cc6ad94
-bda58cbd9c84c6a58c886040a57f67ad8c6bc69c84cea084c69c7bbd9c7bc6a58ca57f67
-9c7b6da5846bb59c84b59c848c6b5aad8c7bc6a58ca57f67b5947bceb594ad9473846b52
-4f362f21080425101c100810180014b99c8ccea0847d584a4621135526174f362f8c6b5a
-ad847bad8c7bad8c73947b63947b63a59473a5846ba59473a59473b5947b9c7b63c6ad94
-bd9c949c84639c7b6d9c7b6d9c7b6d9c847b7357557d584aad8484a088839c776bb99c8c
-ad8c73ad9c7bad8c73d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d99c735eb5887b8c634ac08c7ee2b399cea0849c73528a5a58985e52
-703d29552617844a445526175a2e278c634ab58c6b7d584a9c847b5e3e28250814180014
-1800080800102a142bad948c5e4542350c1a38232821081021081044272e462113210810
-350c1a3b182044272e2d0f0b4621133b18205e3e285e45425a2e273b18203c160a1b0500
-21080425081444272e2108043b18201b05001b05002d0f0b2108041b05003823282d0f0b
-3823281000081000000800082b181cbd9c94ad946b5a2e2746211376533ecaab9e462113
-9c776bb58c73b5947b9486779c7b63b99c8c8e635276533e886b46a5846bd0ba99ad9484
-a57f677e5c5883584d7d584a8a5a585a2e2744272e9c7b6da58c7b5e3e28846b52947363
-9c7b63b5947bad8c6bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b58c73b58c73c69c84d0927bcead789c7352bd846f94685a90573d
-8c634a985e525a2e2779483d844a44ad73678c634a2606082d0f0b210810180014382328
-1800142a142b0b0319a586869687872108102508141800142b181c210810180014250814
-21081025101c1b050025101c2b181c180c08250814260608210810210804350c1a180014
-210810180014180014180c0818081418001425081424061e180008100008180014180814
-2108101800080b03191809201008088c7360886b46734c2ea97b77cea594ad8473ad8c7b
-83584d734c2ead94739c7b6d9c84637d584a948463ceb59cbd9c84c6ad949f7e5a7e5c58
-9473636d463c6d463c4621135a2e275a2e278a5a5880695e5a2e271000087e5b398e6352
-b59c7bad846bb5946bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9382328180c083823283823287e5c587d584a8a5a5876533e76533e
-bd9473734c2e844832844a44b58c732606083c160a18001418081418001424061e100008
-1809201808141809205e454244272e44272e44272e1800141800080b0319180920100008
-100800180c08100008100000100008180c08180c0818000818000825101c180008180008
-24061e180014180c081000082508142b181c18001425101c180814100008080008180814
-18001410000825101c10000025101c3b18204f362f44272e7e5b397e5b3983584d947b63
-56363d3b1820b5946bad847b9c776bbd9484b5947bad84739c7b6d7d584a76533e675043
-3c160a4f362f4f362f7d584a2b181c56363d6750436a505521081010000844272e7d584a
-7357557d584a94846bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d925101c1800141b0500100008210804210810350c1a260608210810
-10000821081025101c38232818001424061e080010291021250814250814180c08100008
-18001425081418081491706db1949499797b99797b846b6e56363d3823282a142b25101c
-18001418000818001418081429102124061e24061e2b181c2b181c210810180014180014
-250814100000180c082b181c1800081800142a142b18001410000038232825101c180014
-3823281800142910212b181c1800144f362f100008350c1a21081044272e44272e210810
-25081425081444272e4f362f3b182044272e5526173823283c160a2108102108103c160a
-44272e350c1a1b05002b181c2d0f0b1000082b181c250814250814350c1a2d0f0b350c1a
-3c160a2d0f0b3b1820d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d925081425101c25101c2b181c25081425101c1800142108100b0319
-2a142b0b031924061e1000081809202a142b0b03192108101b05004f362f6a50558c7360
-735755846b6e8e7778bda49eccb1abbda49e9c847bb18a8799797bad848cad948c846b6e
-56363d18001418001424061e24061e24061e24061e8e77787357553823283b18202b181c
-3823281000082b181c38232856363d44272e2a142b25101c382328846b6e38232825101c
-2a142b24061e2a142b44272e8e7778a3908c99797b5e3e285e45427e5b39735755675043
-6750437357559c8c6f56363d4f362f5e4542735755846b6e846b6e8e77788e77788e7778
-6a5055846b6e9687877357556a50556a50556a505556363d73575573575556363d350c1a
-260608260608210810d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d918081425081425081438232825101c2a142b2508142b181c2b181c
-350c1a1b05002606083b18201000082508142b181c6a50556a505591706d94846ba08883
-9c847ba0947f968787bda49e7357559c847b6a50559c7b6da08883ad948c99797ba08883
-8c73607357557e5c5899797b91706d846b6e7e5c58846b6e9c7b6d91706da3908c846b6e
-846b6e5e45428e7778b19ca3bfadb0b19ca3b19ca3bfadb0b19ca3bfadb0bfadb0bfadb0
-b19ca3bfadb0bfadb0b19ca3d5c2bea3908ca4a196a3908cb19494a4a196a4a196bfadb0
-d5c2bebfadb0bfadb0bfadb0bfadb0c7beb3c7beb3b9ada5bcb8aebcb8aebfadb0bfadb0
-c7beb3c7beb3b19ca3b19ca3c7beb3b19ca3b19ca3968787b19ca3968787846b6e7e5c58
-735755846b6e91706dd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d944272e5e45428e7778a3908ca3908c80695e5e454256363d2b181c
-3b18204f362f99797ba97b777e5c58a58c7ba58686a3908cb19ca3a08883846b6e80695e
-a1988da4a196948677bcb8ae846b6eb1a8a2a3908cb19494bd9c94a1988dad948c948677
-9c8c6fa08883a58c7ba08883a58c7ba0888394846bad948ca0888373575599797bb19494
-c7beb3b19ca3c6a5a0a4a196a3908cbfadb0b19ca3bfadb0a4a196a3908cbda49ea0947f
-a4a196b1a8a2d5c2bec7beb3a1988db1a8a2af9f94bda49ec7beb3d5c2bed5c2bec7beb3
-d5c2bed5c2bebfadb0b1a8a2c7beb3c7beb3b1a8a2b1a488b9ada5c7beb3c7beb3b1a488
-b1a8a2c6b598a1988db9ada5ceb59cb2aa94b1a488a1988dbda49ea4a196a3908ca3908c
-968787a3908cbda49ed9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9a58c7baf9f94bda49ec6b598c6a5a0af9f94ad948ccaab9ea4a196
-bfadb0a3908ca08883a3908ca3908cbfadb0bfadb0b19494a3908ca3908ca4a196a0947f
-b1a8a2b99c8ca4a196a0947fb1a8a29c847bc6a5a0af9f94bd9c94a0947fccb1abbda49e
-bfadb0b9ada5b19494a3908ca3908ca3908ca4a196b5887ba08883948677bd9c94b19494
-af9f94ad948ccaab9ebda49ea0947fd2c7afc6b598bda49eceb59cceb59cbdaa91b99c8c
-b99c8cb2aa94a1988d9486779c9178a4a196bdb594b59c73c6ad8cb99c8cbdb594ceb594
-a58c639c8c6fc6b598b99c8cd0ba99d0ba99bdb594b1a488c6ad8cd2c7afd0ba99c6b58c
-9c8c63ad9c84ceb59cc6ad94bda58cc6b58cbd9c7ba0947fd0ba99af9f94b1a8a2a4a196
-948677a1988d9c9178d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b7b5a0bda49ebda49ecebdadcaab9ec6ad94b99c8cc6a594a4a196
-af9f94b19ca38c7360b194944f362f2d0f0b180c08350c1a2d0f0b5e3e28a59473b59c84
-ad94739c8c6fad948cb59c84ceb5948e6352bdb594d6b9a9d6b9a9ad9c849c8c6f9c7b6d
-a58c7bad948cbda49ebd9c94bda49ebda49eccb1abbd9c94947b637e5c58b19494af9f94
-bda58cd6b9a9ceb594d6b9a99c8c6fcaab9eceb59cc6a58cb59484c6b584ceb594dab28c
-cead8cc1a584a5906b76533eb59c84947b56ad8c7bad846b9473635e3e287e5c58cead94
-9c7b636750439c847bad8c6bbd9c7bc1a584dab28cceb184bd9c7bd0ba99c6b584b59c73
-cead8c8c6b5a947b56b5947bc1a584cead8ccead78b5947bbd9c849486779c847ba1988d
-a3908cb1a8a2b1a488d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d7d1c0ccb1aba08883bda49eb59c84b99c8c94685a8e6352906f4e
-ad8463d0927bcea084996040a7735da7735d8e63528e63528c634aad8c73c69c8cd6bd98
-cead8cd6bd98ceb594c69c73bd9473cead8ccea084b59c73cea084d0ba99c6ad8ccead8c
-bd9c7bb5947bbd9168ad9473a57f67a57f67ad8c6b9c847b6d463c6a5055bdaa91c7beb3
-bda58cbda58ca5906bad846bc69c7bbd947ba7735dad846ba7735dad8463b58456bd8c63
-a77047985e5290573d8c634ab58c73cea58cdab28cd2a575daad84bd947bcea084cead78
-b29460d2a575b5947bbd8c73bd8c73ad8c63c69c7bbd9168a5845aad8c6bad846bad7f5a
-9f7e5a7e5b39cea594c69c84bd9473c69c73ad7f5adaa08cb584736d463c6750438e7778
-8e7778a4a196bda49ed9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9caab9ebda58c9f7e5a886b46ad8c6bad7f5abd9168d2a575c6ad8c
-dab28cb5a57bc6ad8cc6ad94a5846bb99c8cbda58cbd9c94b59c84c6b584bd9c7bceb594
-b59c7b846b52c6b584a59473ceb59cceb59cbdb594cea594d0ba99decaa4bda58cbda58c
-c6ad8ca5846bad9c84bda58cad9c7bbd9c849c8c6fc1a5842b181c56363daf9f94c6ad94
-caab9eb5947ba07b4ead7f5ac6a577b5946bb5946b9c7b637e5b39947b56a5845a986d5e
-703d29996d47996d47906f46c39565ca946fad7e4fa77047a07b4ead7e4f886040886040
-7e5b3976533e90573d886040ad7f5a996d479c7352985e52996d47a7735d7e5b398c634a
-906f4ec69c7b9c7b638c634a9c7352734c2ead7e4fa07b4ea5846b3b1820180c08b19494
-947b63a08883b7b5a0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d98c6b5ab1a488bd9c7bb59c7bbd9c7bc1a584c6a577cead8cd0ba99
-ebcfb8ceb594decaa4d6b9a9d0ba99af9f94947b63a08883a59473d6bd98d7c69ad6b9a9
-d6b9a9decaa4d6bd98d2c7afc6ad94d2c7afeacba5d2c7afdecaa4b5a98cd2c7afeacba5
-c6b598bda58ca59473b59c84ceb59cd6b9a9c6ad94c6ad8c2b181c291021a3908caf9f94
-ceb59cd6b9a9b29460ad7f5abd9168b5947bad8c6bbd9c73bd9c7bb5947bc1a584c08c7e
-7e5b39b58473bd94739f7e5abd8c63ad8463d0927bbd8c63b58456ad84639f7e5ab58c73
-9c7352985e52b58c73bd8c638c634a886040ad7f5ac69c7bad846b703d29b58c73a5845a
-c69c7bbd947bad8473986d5ead7b639c7352ad7f5aad7f5a83584d2d0f0b100008a08883
-a08883af9f94a4a196d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9a59473caab9ead9c7bb59c73ad946bb5a57bc6ad8cceb594c6b584
-d6bd98b1a488decaa4d6b9a9ccb1abc6b598bda49e94846bceb59cd0ba99d0ba99d2c7af
-d2c7afd6b9a9d0ba99d0ba99d0ba99ccb1abd2c7afd0ba99b5a98cbdb594d2c7afebcfb8
-bda58cb99c8cb59c84bdaa91d0ba99bdaa91d2c7afbd9c7b180814180014968787bd9c94
-d5c2becead94b29460bd9473c69c7bc69c7b9f7e5ab58c73c1a5849c7b63ad8c6bd6ad96
-8c634aad846b9c7b638c634ab58c73ad7e4fc69c73b58456ad7e4fad8c639c7352ad846b
-886040886040ad846b9c735e8c634ab58c73a57f67ad846bb58c73734c2eb5946b9f7e5a
-bd947be2b399a57f6783584db5947b9f7e5ac1a5849c73526d463c180c0810000844272e
-968787ccb1abd7d1c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ceb59cebcfb8bda58cc6ad8cb5a98cd0ba99ceb59cceb59cdecaa4
-d6b9a9ceb594ccb1abebcfb8b5a98ccebdadd2c7afb19ca3d2c7afbdb594d2c7afceb59c
-d2c7afbda58cd2c7afd2c7afebcfb8d0ba99d0ba99d2c7afebcfb8eddfc8ceb594ccb1ab
-b1a488ad947bbdaa91ad9c84c6ad94a59473bd9c94a5846b1800142a142b735755b2aa94
-d5c2beb59484ad8c6bad8463d0927bbd9c7bb58c73bd9c7bc1a584ad8c7bc6a58cb5947b
-947b56ad8c7bad8c6bad8c6bcead8cad846bad7f5ab58c5acea084e4bda2bd9473b5947b
-9c7352986d5ebd94737d584a83584dad8c73c6a58ca5846bb5947bc6b584e4bda2b58c73
-ad8c6bb58c7394685a947b63cea594a5846ba5906b4621135e454225101c2a142b25101c
-846b6ea1988da4a196d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ccb1abdecaa4d0ba99d0ba99ccb1abd2c7afd7d1c0eddfc8d2c7af
-decaa4ceb59cc1a584d2c7afccb1abd0ba99af9f94caab9ea58c7bbda58cc6ad8cad9c84
-cebdadccb1abd7c69ac6b598b1a488bdb594bda58cbdaa91bdaa91ad9c7bc6b58cad9c84
-bda58cb59c849c8c6f948677b5947ba58c7b9c8c6f947b6338232824061e2b181ca1988d
-ceb59cbd9c94bd9c73c69c7bdab28ccea084d0927bc1a584ad8c73ad8c73b5947bad8c6b
-9c776ba57f67ad9473b5947bb5947bb5946bc69c73ad8463cea084cea084b59c739c7b63
-9c735e996d47c69c7b8c7360a57f67986d5ea5947394685a9c8463bd9c7b947b63b58c73
-cead8c8c634ab59c7bbd9c84a5846bad947b8c6b5aa57f67a58c7b1808140b0319180014
-56363da4a196d5c2bed9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ceb59cceb59cc6ad94d2c7afd7c69ad0ba99d2c7afc7beb3b59c73
-bd9c84ad947bb59c84b59c7bbda58cad947bb59c84bda49e8c7f6bceb59494846bb1a488
-bd9c94bdaa91a0947fc6ad8cad9c7bbda58cbda58cad9c7b9c8c6f9c8c6fb59c84948677
-a5846bbda58c948677b5947b8c7360a5846b80695ea5906b6a50550b03191b0500ad948c
-d6b9a9d6b9a9c69c73ad8463bd9168ad846bc69c73c1a584b5947bbd9c84b59c7bad846b
-a5906b83584d76533e8c7360a5846bbd947bb59c73cea084bd9168a57f67bd947b947b56
-9c7b63906f4ec69c849c776ba97b779c776b8e63529c8463cea594b59c7ba58c63a5845a
-cead8cb5947bceb594bd9c8494685aa5846ba5906bc1a584ad948c2b181c0b0319382328
-180008a1988dd7d1c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9bd9c94d6bd98cea594ebcfb8d2c7afdecaa4bda58ca5846bb59c7b
-bd947bb5947bc1a584a59473a5846ba5846bc6ad94bda49eb1a488c6ad8cad9c7bceb59c
-ad948ca59473ad947bc6ad8cc6ad94947b63a5906bb1a488b59c7bb59c84886b46947363
-7d584aa59473a58c7bad8c7b846b5276533ea5846ba58c7b6a5055180014210810947b63
-e4bda2c6a58cb58456d69c7bca946fc69c7bd0927bbd9c7bb5947bb5946b947b63a57f67
-ad8c6b94736383584da58c7bcea58cb5947ba7735ddaad84a57f67947b56b58c73947b56
-947b5694685ab5946bad8c7b8e635294685aa5846ba5846ba5906b886b46b59c84bd9c7b
-b5946bc69c7bc1a584bd9c7bbd9c7b8c634aad8473a5845a80695e24061e180014291021
-2d0f0ba08883d0ba99d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9a58c7bd6b9a9b59c84ceb594947b63b5947bad9473a58c7bad846b
-ad8c6bbd9c7ba5846bb5947bb5947bb59c7bc1a584ad948c947b63947b63decaa4ad947b
-b59c84b59c84c1a584b59c7bb59484c6ad8cb5947bad947bbd9c84a59473ad8c738c7360
-7d584a947363ad84737d584a9473636d463cb59484b58c7325101c24061e2108044f362f
-ebcfb8906f4ec39565bd8c63ad8463d69c7bc69c73ad846bb59c73ad8c6b9f7e5ab5947b
-a5846bad8c73a58c7bbd9c94bd94849f7e5acea084c69c7ba5845ab5947bb5947b9c7b63
-a5846bb5947bbd9473ad846b8c634a9c7b63bd947b9c7b63b5947bc6ad8cc1a584c6b584
-bd9c7bcead8ccead8cb58c73ad846b8c634aad846bad8c6394736318081424061e250814
-8c7360c6b598bdaa91d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9948463decaa4eacba5c1a5849c7b63c1a584cead8cc1a584b59c73
-ad8c6b8e6352996d479c735eb5947ba58c63b59c73a5906bceb594ad947b9c8463ad9484
-8c7360ad947ba59473a08883b99c8cb2aa94bda58ca58c7b80695e947b63a08883bd9c7b
-9c7b6dc69c8483584d947363a5846b76533ea59473b59c7376533e250814180008382328
-eacba5dab28cbd9168ad7e4fb77b5dc69c7bb58c6b985e52886040bd9c84a5846bbd947b
-b59c7bcea5949c8463ad8c73b5947b9f7e5aa7735dad946bbd9c7b947b56bd9c7ba59473
-ceb59ca5906bbd9c94ad8c6b94736383584db594849c7b6dad947bbda58ca5906bbd9c7b
-c6ad8cc6ad8cad947b846b52a5846b947b63ceb594b1a488ad9484180c0825101c100810
-b19ca3b1a8a2ceb59cd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d98c7360eddfc8c1a584947b56ad8c73d6bd98bd9c84c1a584c6ad8c
-bd9c84bd9c7bb5947bc69c84bd9c7bb5947bbd9c73a58c63c1a584ad9c7ba58c7bc6a594
-a5846bad947bad947bb1a488c6b598bd9c94ad9c84b59c84ad9484ad947b9c7b63846b52
-a57f67947b6376533e8c6b5a9c776bad8c73947b637e5b3980695e1800141800085a2e27
-decaa4daad84b29460bd9168d69c7bcea084daad84c69c7bad846bc69c84c6a58cb5947b
-ad8c6bad9473a5846ba5906bad846bad846bad8c6bb59c739c7b637e5b39cead8ccead8c
-9c7b636d463c947b63c1a584a5846bc6a58ca59473b99c8cb5947bad9c7bc1a584ad946b
-bd9c7bb1a488eacba5947363b59c84bda58cb5947bc1a584948677382328180014180008
-b19ca3a4a196d7d1c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d96d463ceddfc8b5947b94685ab5947bb5947b846b52bd9c7bad9473
-a57f67bd9c7bbd9c84c1a584ad8c6bb59c73b59c73bd9c7bb5a57bc6ad8cbd9c94d6b9a9
-ad9c84a59473b59c84c6ad94b59c84948463a58c7bc1a584ad947ba5846b947363cea594
-ad9c7b5e3e28ad8c7bb59484ad8c739c7b639c8463b59484a08883210810100000a59473
-c6b584ce9c77bd9473ca946fad7e4fad8463daad84bd9473ad8c73b5947b9c7b63cead8c
-cead8cc6ad94ad8c73947b5683584da57f67ad846bb58c73b5946ba57f67b5947bad8c73
-8e6352947b639c8463ad8c739c7b639c7b639c8463bd9c84c6a58ca5906bbda58ccead8c
-b5a57bcea594948463a58c7bbda58ca57f67bda58cad8c6ba594733823281b0500180814
-a3908cccb1abc6b598d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d98c7360ebcfb88e63529c7b63c6a58cad846b846b52b5947b9f7e5a
-9c8463ad8c73bd9c7bbd9c7bb5947bceb184c6b584c6ad8cc1a584bda58cc1a584bd9c94
-b59c84a5846bb59484ad8c73bd9c84b59c84cead8ca58c7b947b56a57f67c6ad94a5906b
-8e6352947b6383584da57f679473639c7b638c6b5ac6a58c846b6e1000082d0f0bebcfb8
-decaa4cead8ccea084c69c73daad84c39565ce9c77d6bd98cead8c9c7b63bda58c9c7352
-a5846bb5947b8e6352846b528c6b5aceb594b58c73996d479c7b63b58c73ad8c6bbd9c7b
-7d584aad8c6bad8473c6b584bd9c849f7e5abda58ccead8cc1a584bd9c84bd9c7bc1a584
-bd9c84947b63c1a584947b56b5947bb59c7bad8c73c1a584bd9c844f362f2b181c250814
-846b6eaf9f94decaa4d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9bda58ccea594846b52ad846ba57f679c776bb58c73bd9c84ad8c6b
-b5947bad8c6bbd9c84ad9473c1a584ceb594cead8cc6b584b59c7bc6a58cb59c84bda58c
-bd9c94ad9473b99c8cb59c7bbd9c849c7b63ad8c73b5947bcea594bd9c84ad8c73ad9c7b
-846b52947363947363a57f67ad8c7b947b56a5846b9c7b6d4f362f2b181c100000a59473
-d6bd98eacba5cea084ca986bca986bc6a577daad84b5946bb5947bad8c73b59484b59c73
-bd947ba5846b948463947363a5846bbd9c7b7e5b39b58c73ad846b9c73528e6352ad8c6b
-8c634ac1a584ad8c73b5947b9c8463b59c7bb5947bb59c73846b52b59c7ba5906bb5947b
-76533ead9473a5906bb5947bbda58cbd9c84c6ad8c8c634a9c7b63a08883250814180014
-bda49ebda49eeddfc8d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b5947ba5846b8c6b5aa57f6779483d7e5b39b58c739c7b63b58c73
-bd94739c7b63b59c7bad8c73c1a584daad84c69c73c1a584bd9c7bbda58cc6a58cb59484
-c6a594a58c7bbd9c849c7b63b59484a5846bb5947b9c7b6da59473ad8c73b59c84b59c84
-846b528c73605e3e28ad84739c776bb58c735e3e28ad947b56363d180008180008100008
-d7c69ad6bd98cea084ce9c77cea084b58c5aad7b63c1a584c69c849c7b63bd9c84ad8c6b
-ad846b8e6352bda58ca5846bb99c8ca5846b947363906f4e9c7b63bd947bb5947bc1a584
-ad846bb59c7b906f4ebd9c84947b63cea594b5a57bb5947ba57f67c1a584b5947ba58473
-bd9c84947b56bd9c84c6ad8ccead8cb5947bceb594947b56ad8c739c847b180014100008
-bfadb0ad9484ad947bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9bd9c848e6352846b529c73528c634a7d584a9f7e5a7e5b39bd9473
-bd947b9c735eb5947bc69c7bb5947bc69c7bbd9c7bc6b584b5947bad9473b99c8cad8c73
-a58473947b63a58473ad8c73b594849c7b6dbd9c84a59473a58c7ba58473ad9c84b59c84
-886b465e45429c7b63a97b777e5b39a57f67a5846bad947b210810180014180814180c08
-ceb59cebcfb8c69c73cea0848c634a8c634a996d47b58473b58c739c7b639c7b639f7e5a
-9c7b639c7b63b5947b8c6b5aa5846b80695ead8473a5846b8c634a9c7b63c1a584bd9c7b
-8c7360a57f67c6ad8cb59c84a59473b59c7bb5947bad8c6bb59c84ad8c73a58473b99c8c
-947363ceb59ccead8cc1a584c1a584b5947b947b56ad846b80695e2d0f0b1000002a142b
-a3908cccb1abd7d1c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9cea5949c7b639f7e5aad7b63ad7b638c634aa7735db5946bcea084
-bd947b906f4ead846bc1a584906f4eb58c6bc69c7bdab28cc1a584ad8c73cea594ad947b
-a57f679c7b6db59c849c7b6dcea594ad9484a58c7b947363a58c7ba59473948677bda58c
-9484638e63528c6b5a9c7b638a5a58bd947ba5846bb59c7b21081018001424061e100000
-c6a594eddfc8c69c73ad7367844832945852985e52ad846b9c73528c634ab58c73cea084
-b59c73c69c848c6b5a947b63947b639c776bad8c73a5846b947b639f7e5abd9c84ad9473
-c1a584b59c7bc1a5847e5c58947b63a594738e6352b5a57b947b56bd948cad8c7bbd9484
-bd9c84ad8c739c7b63a57f67bd9c7bad9473a57f67a5846bad94845e454224061e180814
-bfadb0bfadb0ceb59cd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ceb594947b56986d5e76533e94685a8c634abd9473bd9168a58473
-8e63528c634a9c776ba57f67c6a58cbd947bbd9c7bbd9c7bc69c84b5947bad8c6bb5947b
-a57f67b59c739f7e5ab59c73c1a584886b46a59473ad8c738c7360a57f67a5906b76533e
-7e5c585e4542ad9c7b846b525e3e286d463ca584737d584a25081408000808001025101c
-bda49ee4bda2b294607d584a985e52b5946b996d47ad84639f7e5a9f7e5a947b568c634a
-7d584a9c7b63bd9c94b59c84b59484906f4e9c7b639c7b6d735755947b63ad9c7bc1a584
-948463ad9c7bceb59476533e947b56caab9ea584739c7b6db59484a58473c6a58c8c6b5a
-a5906ba5846b7e5b39a5846bbd9c7bbd947b9c7b639c7b638e63522d0f0b2a142b180014
-af9f94c6b598d0ba99d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9eacba59c776b83584d9c776b83584db584739c7352b5947b9c7352
-8c634aa58c7bad846bb99c8cb5947bc69c84c1a584b58c73c1a584c69c7bc1a584b58c73
-bd9c7b9c7b63ad846b9c84638e635276533ead947ba5847376533e886b46ad94738c7360
-846b525e3e28846b5280695e8e6352a5947383584d7357551b05001000080b0319100000
-a3908cebcfb8996d479f7e5a9c7352c08c7e9c7352ad8463bd9473ad7f5abd9c7bad8c6b
-ad8c73b5947bb59484ad947ba5846bad8c7bb58c73947b63a58c7ba59473bd9c84bd9c7b
-7d584abd9c7bc1a584a5846bb59c84caab9eb59c84b5947b947363947b639c8463886b46
-a59473b5947bc6a58cc6a58c9c7b63947b56947b567d584a5e3e285e4542382328180814
-b19ca3b7b5a0bda58cd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c69c84846b52985e527d584a945852734c2ebd9484bd9473b58c73
-a57f67bd9473cea594bd9c84c6a58cb5947bb5947bdab28cc6ad8cb58c73a57f678c634a
-b5947b9c7b63bd9c84bd9c7bc1a5849c7b6d9c7b6376533ead8c739c7b63906f4e7d584a
-b59c845e3e288c736076533eceb59c76533e8e63525e4542250814210810180014100008
-a08883d6bd987e5b39a7735dad846ba7735dbd8c63ad8463b58c6bb58c73bd9473b58c73
-9c7b63cea594a5906bb59484bd9c849c7b639c735e5e3e28947b56947363a5906bbd9c7b
-9f7e5aeacba5d6bd98bda58cc6a58ca594738c6b5aa594738c6b5ac6a58cc6ad8c8c7360
-cea594c6ad8cb5947b947b568e6352b5946bc1a584cea0849486775e4542382328180008
-b19ca3c6b598c7beb3d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9e2b39994685a9c7b6383584d79483db5887bad846b9c7352ad846b
-947b56ad846bc1a584bd947bceb59ccea594decaa4d6bd98c1a584bd9c7bb59c73bd9c84
-c6a58cad8c7bad8c7bc6a58ccea5945e3e28ad847b6d463c947363a5846b76533ebd9484
-76533e9c7b63a5846b9c7b6d8a5a586d463ca57f67382328350c1a1800081800142a142b
-bd9c94caab9eb58c73b58c739f7e5ada9c84c69c73b58c6bcea084906f46b5947b9c7b63
-ad8c6b846b527e5b398c7360906f4ead8c739c7b63ad8c73ad8473b5947b9c735eb5947b
-ad8c6bb5947ba5906bad9473c6a58c947363846b528c6b5a846b52ad94739c7b63a59473
-bd9c84a5906b8c6b5aa58c63bd9c7bd6bd98ad8c6bc6ad9480695e382328180014180014
-b1a8a2a3908cd2c7afd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c6a58cb5947bad8473a97b779c7b63ad7b6bb5887b7d584aad8c6b
-a5845ac69c849c7b6d9c7b638c6b5ab59c7bd6bd98c1a584c6b584c69c7bcea594ceb594
-bd9c84bd9484a57f67ad847b7d584a6d463cad848476533e986d5e83584d9c7b63846b52
-9c776b8e63528c6b5aad847b94736344272e76533e3b182056363d1800141800142b181c
-bfadb0ceb594c1a584b58c73c69c84bd9c7bce9c77d2a5759f7e5a9c7b639c735ea5846b
-9c776bad8c73a5846ba57f67b99c8c9c776bbd9c84bd9c7bad8c6b9c7b639c7b63c69c84
-b5947ba5846b9c776bad8c6bb1a488a59473a58473a58473c1a584bd9c84bda58cad8c73
-a5846b9c8463ad946bceb594b5947bbda58cad8c73af9f943c160a250814100000100008
-8e777880695ea0947fd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ceb59cc6a58ccaab9ed6ad9683584d9c776b79483d9c7b63a5846b
-9c7b6dad8473947b63947b56ad8c73c6ad8ce4bda2ceb594c6ad8cad9473c6ad8c9c7b63
-9c735eb5947b9c776b7e5c585e3e2891706d6d463c3b18204f362f79483d846b5283584d
-9c7b6d76533e5a2e274f362f5e3e28846b6e2b181c3b182056363d291021180014180014
-ceb59cd6b9a9a5906bb59484a5846bdab28cad8c6bad8c63c08c7e9c735ebd9484a58c7b
-b99c8c947b56bd9484c69c8cbd9484a59473a58c7b9c7b63ad8473734c2e9c7b6da97b77
-83584d83584d7d584aad9473ad846b9c7b63b5947ba5846bad947b947b56bd9c84b5947b
-947b63b5947bc1a584c6ad94ad9473a08883a58c7b99797b250814180008180814180014
-382328a4a196846b6ed9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b59c84a59473ad8c73a5846bc69c8c9c7b6db59c84b99c8cbd9c94
-b594849c7b6d9c7b6d947363ceb59ccea594ceb594d0ba99ad9473bd9c84c6ad94a5846b
-ad846bc6a58c9c7b63846b6e8a5a584f362f6a505544272e2d0f0b9c7b63947b637e5c58
-83584d5e454276533e91706d3b182044272e25081421081024061e18001418081456363d
-c7beb3cebdada59473a08883b59c7bbd9c7bb59c73bd9473c69c84a58473a08883675043
-7d584a986d5ead8473bd9484a584735e3e286d463c83584d8e63523c160a6750435e4542
-5e3e2856363d7d584a76533e7d584a947b56bd9484bd9c84c6a58cad846bc6a58cb5947b
-a5846ba5906bad9473ad947bcaab9e7e5c5844272e3823281000001000082a142b2b181c
-4f362fc7beb394846bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ad9c84c6ad94b59c84b99c8c9c7b639c7b6d5e3e287e5c588c6b5a
-7357557e5c586d463c846b52ad8c73c6ad8cc6b584c6ad9476533ead9c7ba5846bb59c7b
-bd9c84e4bda2b58c7373575544272e250814462113350c1a94736380695eb59484ad948c
-7d584a5a2e273b18203b182044272e2b181c21081024061e25101c1800142a142b968787
-ccb1aba0947f9c8c6f947b63a58c7bb59c7bbd9c7ba57f67bd9c846750436d463c3b1820
-76533e99797b8e63527e5c585a2e274f362f735755a57f6780695e3c160a3b1820350c1a
-3b18202d0f0b6d463c8c634a947b568e6352906f4e9c735ead846bad846bb5947bad8c73
-a5906bad8c73a5906b5e3e2880695e2b181c180014100008180014291021080010180920
-a3908ca1988db99c8cd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9a08883bda49e8e77785e45421800142a142b2b181c180014180014
-2508141000080b031918001418081408001025101c25101c25101c180920180014080010
-180014100008180008080008100008180014180008180014180014180014100000080010
-18001418081425101c2508141800141800140b031918001425101c180c088c7f6bccb1ab
-a4a196d5c2be44272e2108046d463c7d584a5e3e2876533e5a2e275e3e285a2e2776533e
-5e3e284f362f7d584a5a2e274621135a2e275a2e275e3e28675043260608350c1a350c1a
-83584d9c7b6398734e76533e886b46bd9c7bc1a584bd947b947b63a5906ba5846b947b63
-b5947b9c7b6d5e3e2844272e2b181c1808141000001000081809200b03191800142b181c
-80695e8c7360735755d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d99c9178a1988d9c847b846b6e44272e25101c180014250814180814
-24061e38232824061e18001418001425101c1000080800080800080800101800140b0319
-0800101000081800140b03190b03190800080b03190b0319100008080008180920100810
-1800141808141800141808141800141800141800141808141800085e4542ceb59cb7b5a0
-ad94849c7b6d5e45423b182044272e5e3e2899797ba088835e3e2899797b7e5c586a5055
-91706d56363d56363d350c1a350c1aa08883bd9c94ad948c9c7b6d382328250814382328
-5e45426d463c76533e7357557e5c588c73607e5c585e45425a2e275e45426a50556d463c
-5e45424f362f56363d3823281000001800141809201809201809201000083823286a5055
-b19ca3b9ada5b7b5a0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ccb1abad9c84af9f94bd9c94bda49eb19494b19494c6b598b19ca3
-a08883a3908ca3908c968787b19494a4a1966a505529102124061e1800141800140b0319
-1800141000080800080b03190b03190b0319180920080008180920180014180920180014
-25101c08000818092010000810000818081425101c210810a08883948677b1a488cebdad
-d2c7afceb59cc7beb3ccb1ab3b18203c160a1000001000081b05001800142b181c250814
-3823281800142b181c18001425081425081410000025101c100000180814180014250814
-2d0f0b3823282d0f0b2b181c210810210804210810350c1a2508142b181c210810180014
-1b05002508142508141000081800142a142b180814180c08100000180814735755a4a196
-c7beb3bcb8aeb1a8a2d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b1a488ad948cceb59cbda49ed6b9a9c7beb3c6b598a0947fa58c7b
-a08883ad9484bd9c94a08883af9f94b19ca3a3908cbda49e99797b5e4542180014100008
-1b0500180c081000001000001808141000082b181c44272e948677a3908ca4a196b19494
-a4a196a4a196a4a196968787968787ccb1abd5c2becaab9ed5c2bed6b9a9d6b9a9eddfc8
-ccb1abdecaa4bdb594d5c2bed6b9a9b1949480695e210804210810100008100008180014
-100008100000180014100000180c0808000810080010000818000810000810000880695e
-bfadb0b1a8a2d5c2bec7beb3d5c2bed5c2bea088834f362f21081044272e5e45424f362f
-2a142b99797b56363d56363dbda49e91706da08883bd9c94bda49ec6b598ccb1abc7beb3
-cebdadceb59cceb59cd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9947b56ad8c73ad948c947b6394846bbd9c84ceb59cc6ad94b5947b
-bd9c84c6a594a594739c7b6d83584d80695e8c6b5a947363947b63a58c7ba58c7bc6a5a0
-bd9c94caab9ead947bcaab9ed6ada5c6a58cc1a584c6ad8ccea594ad8c737d584a6d463c
-675043af9f94a1988da0947faf9f948e6352ad7b63bd9484bd9c84ebcfb8b59484a5846b
-9c8c639c8463948463b5947bceb594ad9473947b639c7b6dd7d1c0a3908c968787a08883
-a4a1968e7778d5c2beeddfc8d7d1c0d7d1c0cebdadd7d1c0c7beb3eddfc8eddfc8d2c7af
-eddfc8d7d1c0bda49ed2c7afd6b9a9bdb594ceb59ccaab9ed6b9a9d2c7afd2c7afc6b598
-d2c7afceb59cceb59cd6b9a9c6ad8cc6ad94c1a584b5947bcea58ccea594b59c7bad846b
-a5906bad947bb1a488d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c69c84e4bda2ebcfb8e4bda2e4bda2decaa4decaa4bd9c848c634a
-a57f67bd9484906f4ec69c84b58c73c6a58cb5947bd6bd98c69c84cea58cbd947bc69c84
-9c7b63ad8c6bc69c7be4bda2bd9473ad7f5aad7f5ac6a577c69c73b59c73b58c73b59c7b
-ad8c6b76533e67504376533e7d584aad8c6bb57f6bad846bad846b79483d4621131b0500
-260608703d29eacba5d6bd98bd9c7bcead8c906f4ead84739c7b6d2508144f362f80695e
-bda49ebcb8aed5c2bebcb8aec7beb3d0ba99d0ba99948677cea594d0ba99d0ba99bdb594
-ad9c7b9c8c6fd2c7afc6ad8cbdaf81c6b584d7c69ad6bd98decaa4d7c69ad0ba99d0ba99
-b5a57bdecaa4c1a584d6bd98d7c69aa58c63d7c69acea084cead8cd7c69ae2b399dab28c
-ad946bad8c6bad8c6bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b57f6bc395658c634aa5846bad947bad8473ad8c7b906f4e844a44
-9c7352b5887bad7b639f7e5aad7b63ce9c77cead8ccea084b58c73ad846b9c7352ad7b6b
-985e52b77b5db58c73bd8c739f7e5aa07b4ec69c73bd9c7bbd9c7bb58c73ad8c7ba5846b
-9c7b6d4621134621135526175a2e27b77b5d9c73525e3e288d49385a2e277e5b395a2e27
-886040cea58cb77b5db59c73c69c73996d47906f4ead847b4f362f3823286a5055a08883
-b1a8a2d7d1c0d7d1c0d2c7afeddfc8b59c73b59c73bd9c7bb59c73c1a584bda58cb5a57b
-a59473b5a57bceb594c6b58cc6ad8cb1a488c6ad8cad9473bda58cbdb594d0ba99d7c69a
-c1a584decaa4c1a584bd9c7bd6bd98b59c7bd2c7afcead8cbd9c84c6ad8cc6b584ceb594
-c1a584cea594d6bd98d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b77b5dbd94738c634ab58c73ad8c73ad846bad8c7b8e6352b57f6b
-a9695c945852c6947f886040bd9473c39565d0927bc69c7b9c7b639c73528448329c675a
-ad7b63c69473a36150a57f67ad8c7bad846bd6ad96bd9c7bb99c8c99797b99797b83584d
-79483d94685a844a44945852bd7b7bb87158c6947fd2a575cea084bd9484c68c84e2b399
-a9695caa7052c6947fbd9473ad7b63844a44844a449458526d463c1b050056363daf9f94
-d5c2bec7beb3d7d1c0d0ba99b1a488b58c73bd9473ad8c63bd9c7bc1a584a59473c6a594
-ad8c6bceb594cead8cc6b598bda58cad947bc6ad94bda58cd6b9a9c6ad94bdaa91d0ba99
-bd9c73cead8cceb594c6a58cc6ad94d6b9a9d7d1c0d2c7afc6b598bdaa91a59473b59c84
-b59c84d0ba99ccb1abd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d99c7352a7735db77b5db57f6bc69c7bb57f6bbd8c739c675a7e5b39
-9458529c735ea7735dc08c7ebd9168bd9473ce9c77a7735dad7e4f9c7352985e52a56b4e
-c69473a36150a36150985e52bd8c63906f4ec69c7bcea58cbd947bbd8c73bd9473886040
-9c7352945852a7735dbd8c63bd9168c39565daad84cead8cc69c73c39565c69c7bcea084
-bd8c63ad846bbd947bbd8c63ad8c63996040ad84638e63523b1820100000180920b7b5a0
-ebcfb8d2c7afd2c7af9c8463a57f67d0927bb58c73b59c73dab28ca5906bc6a58ca5906b
-bd9c7bb5a57bc6b584c1a584bd9c7bad946bb59c73c6ad8cbd9c7bb5a57bd0ba99b5a57b
-c6b58cd7c69aceb184bd9c7bc6b584cea594c6ad8ccaab9ea58c7ba59473a58c7bceb594
-b5a57bceb594ceb594d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ca946fb77b5dad7b63a77047bd846fc6947fad7b6b9c735e9c675a
-ad7b63bd94739c7b63bd9168c69c84cead8cca946fa7735db57f6bb77b5d996040b77b5d
-ad7367c69473b871589c7352886040a7735dbd9473bd9473886040a7735d9c735e886040
-703d29bd8c63985e52996040b58c6bb58c6bc69c7bbd9473b58c6bad8463b58456b58456
-ad7f5a9c73529c7b63ca946fa7735d8d4938ad7b638c634a3b1820180008080010c6b598
-c7beb3bdb594b59c7bb1a488bd9c7bbd9473bd9473cead8cceb594cea58cad9473bda58c
-c1a584decaa4c1a584b5947bbd9c7bc1a584ad9473c1a584cead8cb5a57bd0ba99d2c7af
-ceb594ceb594cead8cc6b584d0ba99c1a584bda58cbd9c84b59c84bda58cc6ad94bdb594
-ceb594d0ba99d2c7afd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b58c6ba7735dd0927bca946fda9c84c08c7e79483d552617734c2e
-94685abd947bb58c73bd947bcea084ca946f996d47996040a7735d9c7352b57f6bda9c84
-b77b5dc08c7e985e52ad7e4fad7b63ad846bb58c6bc08c7e7e5b397e5b39bd846fa7735d
-76533eb57f6b996d47b57f6bd69c7bdaad84d6ad96b58c6bb58c6bc69c7bbd8c63ce9c77
-daad84cea084c69c8cda9c849c7352ad7b63b57f6b83584d2d0f0b180014180920675043
-bdb594ebcfb8a59473bda58cbd9c7bbd947bcea084bd9c7bceb594b5947bad8c73947b63
-b59c7bc1a584b59c73b59c7bc6ad94ceb594ad8c73ad9473c6ad8cceb594ceb594c6b584
-eacba5a5906bc6b584cead8cc6b584ceb59cb1a488ceb594c6ad8cceb59cad9473bdaa91
-b5a98cd0ba99b7b5a0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b57f6ba77047b58456a7735db58c6bb5887b947b567e5c587d584a
-8c634a9c7b639c7b63ad846bad7b63ad7b639458529c7352ca946fa56b4eb57f6bad7b63
-985e52a56b4e996040ad7b63d0927bbd9168c69473ad846bad7b639c7352d6ad96703d29
-cea084da9c84ad7b63da9c84ad7b6bcea084a7735dc08c7ec69c73da9c84c69c7bce9c77
-da9c84ad846bbd9473c08c7ead7b63da9c84a5635a8a5a5826060825081424061e462113
-bda49ed6b9a9ad8c73bda58cc1a584c1a584b5947bb5947bb5946bad8c73ad8c73a59473
-ad8c73bda58cd6bd98ad947bc6ad94b99c8ca5906ba5846bc1a584c6ad8cc1a584ad947b
-ceb59cb59c73b5947bb5947bd0ba99b5a57bc6ad8cceb594c6ad8cb59c84a59473ceb59c
-d7d1c0eddfc8b7b5a0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b57f6bca946fda9c84daad84da9c84ad7b6b83584d79483d906f4e
-9c7b63bd947bad7b63ad846ba7735da7735d90573d844832a7735d9c73529c735290573d
-a7735dad7b63b57f6bb57f6ba7735dbd9168c08c7e886040c08c7edaa08cc694738c634a
-9c675a3c160a703d29ad7367a7735dd6ad96ad846bb58c6bad8463bd9168bd846fb57f6b
-ad7e4f90573d9f7e5abd846fad7b6bad7367703d298a5a582d0f0b180014180920735755
-ceb59cc6a594b59c84a5846b9c7b63b5947bb59c73b5947bbd9c7b947b63c6ad8c9c7b63
-ceb594b5947bd0ba99c6ad94d6b9a9bda58cceb59cceb59cceb594decaa4bda58cb5947b
-eacba5947b63c1a584c69c84ad9c73c6ad94b1a488a58c63ceb594c6a58cbdb594a58473
-c6b598af9f94a1988dd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9a7735dbd9473c69473cea084b57f6ba7735d94685a94685a8c634a
-b58473bd947b9c7b63b58473ad846b9c675a90573d9c7352ad7b6bc08c7e76533e996040
-ad7b639c7352844832a56b4ea7735dbd9473a7735d9f7e5abd9473d6ad969c73529c675a
-844a44886040b57f6b9c7352985e52b58c6bbd9473ad7b639c73529c675ab77b5dad8463
-a56b4e9c7352bd9473bd947bbd94849c675a703d29986d5e260608180014180814948677
-d6b9a9caab9ebd9c848e6352947b63b5947bb5947bbd9c7ba57f67ad8c738c7360bd9c84
-bda58cc1a5849c8c6fcea594bda58ca5846bb59c84b59c7ba5846bbda58cad8c6bceb594
-b59c7ba57f67c69c84c6a58cc6a58ca5906bceb594ceb594c1a584ad8c73947363947363
-91706d7357554f362fd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9bd9c84c69c84c68c84d0927ba7735d996d477e5b398c634a986d5e
-b57f6b9c7b637d584aad7b63ad846bad7b639c735eb58473ad7b63ad846b8448329c7352
-c69473ad7367a56b4e996040daad84c08c7ea7735dcea58cbd9473bd8c73ad7b638e6352
-76533ec68c84a7735d996040dab28ceacba5c69c7bb57f6ba7735d8c634aa7735db57f6b
-996d47ad7b63d0927bbd9c84c08c7e9c7352945852a97b771b0500180814180920ad9484
-bd9c94bd9c94a5846ba57f67cea58cad8c6b9c7b63ad8c6ba57f679c7b63a5846bb59484
-decaa4bda58cb59c7bceb5949c8c6f9c8c6fad8c73a5906ba5906bb5947bbd9c7bc6ad8c
-b5a57ba5846bbda58cc6a58cad8c7bc1a584c6b584b5947bb99c8ccea5948e6352735755
-5a2e277e5c587e5c58d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b99c8cbd947bcea084c69c7ba7735db58473945852a7735dad7b63
-bd846f9c735e9c7352c69c8cb5887b9c735ead7b6b9c675a986d5ebd8c73d6ad96c68c84
-bd846fa56b4ec08c7ea7735de2b399bd9168c1a584c69c7bb5947bad846bad846b79483d
-5526179c675a985e52bd9168ca946fc39565c39565ad7b63ad7367844832b87158c69473
-aa7052bd9473d0927bbd9c7b947b56734c2e986d5ebd94842108042b181c100008a0947f
-a08883d6b9a9a57f67ad847bb58c738c634acea58cc6ad8cb5947ba5906bb99c8cb5947b
-c6a58ca5906bb59c7ba594737d584aad9c73c1a584b59c7bcead8cb59c7bceb594b5a57b
-c6ad8cceb59cbd9c84ad847bbd947bbd9c7bc1a584c6a594c1a58483584d9c7b6d6d463c
-8a5a586d463c7d584ad9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d99c7352daa08cad7b639c675aad73679c7b6394685a846b529c7352
-9c735e906f4e8e6352b5947bad846b7d584aa7735d9c8c6fc1a584ad8c73ad846b9c7352
-ad846b996d47cead8c90573d734c2ead846bad8c6bb5947bb5947b906f4eb5947b844a44
-844a44734c2ead8463ad8c63c39565c08c7ead7e4fb57f6bbd8c639f7e5aa7735dad846b
-947b56ad8463b59c73b58c739f7e5a886040ad846bad7b6b21081024061e180920735755
-bda49ed0ba99bda58ca57f67986d5e734c2ebd9484bd9c7bad9473a58c7bbd9c7bb59484
-ceb59cb5947bbd9c7ba5846bad9c84c6a594846b52c6ad8cc6ad94b59c7bad94739c8463
-947b56b5947b9c7b6dad8c73ad8473b5947bb99c8cc6b584bd9c7b846b529c7b6d734c2e
-6750437357557e5c58d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9552617d0927bad846b844a449c675a734c2e79483d8c6b5a9c7b63
-986d5ec69c8ca5846b947363ad8c7b886040bd9473a5846bb59c84ad8c739c7b63ad846b
-bd947b9c7b63bd9473ad7b63bd9c7bcea58cbd9c84b5947bbd9473a5846b996d47552617
-844832ad7b63bd9473bd9473ce9c77daad849c7352b57f6ba7735dad7e4fbd8c73bd9473
-bd9473cea58cd6ad96bd9c7bad846b703d29c08c7ea57f672508141000080b0319af9f94
-b99c8cb1a488947b639c7b6da97b779c7b63bd8c73ad8c73bd9c84a5846b9c7b63947b56
-7d584aad8c6bc1a584948677cea594ad947ba59473c6a58cad947bad94739c8463c6ad94
-b59c7bb5947bad8c73ad8c7bc69c84bd9c84ceb59cd6bd98bda58c734c2e8c6b5a7e5c58
-76533e8c73605e4542d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9703d29bd8c739c675aad7b6b703d2976533e76533e7d584a844a44
-b58c73ad9473ad8c7bcea594c69c8c985e529f7e5abd9c84c6ad94b5947bad846b9c7b63
-cead8cb58473a57f67bd947bd6b9a9bd947ba5846b9c7b63ad846bbd9c848e635279483d
-ad7367ad846bc69c7b7e5b39dab28ccea58cb58c6bb58c6ba7735d906f4ead846bad846b
-9c7b63ad8c73ad8c6b9c7b63cead8cb58c73bd947383584d21080424061e180920af9f94
-bda58cd6bd98b5947b886040a57f67b5887bad846bb5947bad8c6bc6ad8ca58473bd9c84
-a594739c7b63bd9c7ba5846bc6ad94ad947bceb59cc6a58cc1a584bda58cd6b9a9c6ad8c
-b59c7bad9473c6a58cbd9c84cea594b59c84cea594ad947b76533e947b638a5a58ad847b
-9c847b8c6b5a8c6b5ad9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ad7b6bad7367b584738e6352844a4483584d8a5a58703d29bd9c84
-a5846b8c6b5aa57f678a5a58ad846bbd8c739c675aa5906bb5947b9c7b63b58c73ad846b
-d6b9a9c69c84b5947b9c7b63bd9c84a58c7bb99c8cc6a58cad8c7bc69c8c986d5e9c675a
-9f7e5ac69c84ad846bad846bcea084a57f67906f4eb58c73b5887bad846bb58c73bd9c84
-b58c73a58c7bbd9c84e4bda2bd9c7b9c73529c735ead8c7b350c1a25101c0b0319846b6e
-a59473decaa4ad8c6b9c7b639c7b63cea0848c634acead8cb5947bc6a58c947b56ad8c7b
-caab9ead8c6bcea594bdb594c6a58cc6a58ccea594ad9c7bc6a594a5906bcea594ad9c84
-ad9c7bb5947bc6ad8cc6ad8cc6ad94b59c84ad9c84ceb59cad948cad847b947b6391706d
-8a5a588c6b5a80695ed9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ad7b63b5887bad7b639c675a79483da97b77703d298a5a58b58c73
-a5846ba97b778e635283584d9c776b734c2eb58473c69c84c69c8cb5947bbd9484b5947b
-ad8c739c7b6d906f4e9c776ba58473b5947bc6a58cc6a594b5947bad7b6b94685a7d584a
-9f7e5a9c735ecead8ccea084ebcfb89c7b63c6a58ca57f67c6a594a58c7bad8473cea594
-b5947ba58473cea594c6ad8cbd947bc69c84c08c7e9c7b631b050018000818092044272e
-a58c7bbd9c7bb5946b8c634abd947bb5947bb5946b9f7e5acead8cbd9c84b99c8cbd947b
-bda58cbda58cc1a584c6a58ca59473b5947bb59c84c6a58cd6b9a9c1a584bda58cceb59c
-c6ad94c1a5849c8463ad8c73b59c7bceb59cc6b598a58c7bad847b947363ad84848a5a58
-947b634f362f5e3e28d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ad73679c7352bd94848c634aad7b6bad847b9c675a986d5ead7b6b
-7e5b399c776b9c7b637d584a83584db58c73b5887bbd9484b5887bcead8cad8473d6b9a9
-9c7b63b99c8cbd9484a5846bad8473ad948ca5846b947b63a58473947363906f4ec69c84
-b5947bcea084b5947be2b399b5947b8c6b5ac6ad949c7b6dd6b9a9c6a58cb59484ceb59c
-b99c8cb5947bd6bd98ad947bbd947bb5947bc08c7e986d5e7357552108100b0319180c08
-ad948cc6b584c69c7b9c7b63bd9473ad8c6bc1a584ad8c6bcea084c1a584bd9c84a58473
-bda58cd6b9a9ceb59cbd9c7bbd9c84c1a584cea594c6ad8ca58c7bcea594a5846b947363
-ad947bc6ad8cbd9c7bceb594c6ad94c6a59494846ba088839c776b94736399797b76533e
-a586865e3e2891706dd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ad7b639c675abd8c73ad846b9c776bb584739c776b945852734c2e
-9458528e6352a58c7bcea5949c7b6dc6a58c9c776bbd9473c69c8ce2b399ad947bd6b9a9
-947b56b5887bad948c9c735eb58c73cea594b59c84ad947bb5947ba5846b9c7b6da5906b
-9c7b63b5947bc1a584cea58cbd9c84947b63b194948e6352bda58cb59c84a59473b59484
-bd9c7bbda58cc6ad94ceb59c9c7b639f7e5ab5887ba57f6799797b180014291021382328
-a58c7bd6b9a9ad846bdab28cad8c73ad8c73947b63ad8c6ba5845ac69c84c6ad94bd9c84
-c6ad94b99c8ca594739c735e9c7b63ad9473c6a58cb5947b9c7b63c6a594ad8c73a58473
-a58c7bad846ba57f67bd9c7bc1a584ad948c947b63947b63a58c7b7d584a7e5c5856363d
-44272e44272e44272ed9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d99c7352c6947fbd9473906f4eb5887b79483d844a44844832b57f6b
-83584dad847ba97b77ad8c73a58c7bc69c8c947b56844a44bd8c73bd9c84cea594ceb59c
-948677947363a5846ba57f67b58c73bd9c84b5947bad9473a59473bd9c84c6a594e4bda2
-c1a584ceb59ccead8ccea594b59484ad94849c7b6db1a488d6b9a9decaa4c6a594b59c84
-c1a584c6ad94bd9c7bc6ad94bd9c84cea58c9c735e844a44947b632108101800142b181c
-c7beb3bd9484eacba5985e52ad8c737e5b39a59473cead8ccead8cb58c73c6ad94b59484
-8c7360ceb59ca5846bceb5949c7b63b5947bbd9c84ad8c73b5947ba584739c776bad8c73
-bd94849c7b63bd9c7bcead8cc6a58ca5846b675043bda58c9c776b76533e3b18206d463c
-56363d5e4542735755d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ad7b63b77b5dad846ba7735dad846b8860409c675a9c7352ad7b63
-ad846bb58c6bad846bb58c73906f4e986d5ead7b6b9c7b639c7b63b58c73b58c73c69c7b
-ad7b63c6ad8cad846bad8c6bc1a584c6ad8cc6a58cc6a58ccea594b59c7ba58c7bc6b584
-a57f67a58c63bda58cd7c69aad947bbda58cb59484bd9484b99c8ca58c7bbd9484bd9c84
-cead8cad9473a5846bad8c6bb99c8cb5887bcead8c9c8c6f382328180920180920100800
-ceb59cad947bc6ad8ca5906bad9c84b59c84cea084bd9c7bb59c73b59c7bb5947ba5846b
-ad8c73c1a584c1a584a58c7ba58c7b986d5e947b63a58c7ba58c7ba58c7ba57f67ad9473
-bd9c7bbd9c7bb5947bcead8cbd9c848c6b5aa584739c84637e5c585e3e288a5a583b1820
-5a2e278e6352a5846bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d99960409c7352a7735d844a44985e52886040ad7b639c7352a7735d
-9c7352ad846bcea58cbd9484b58473985e52bd9473b58c739c7352906f4ec08c7e9f7e5a
-a7735d9c7b63ad8c73bd9c7bcead8cbd947bad8c739c7b63b5947bb5947bc69c84ad8c73
-ad9473bda58cceb59cc6ad949c7b6dad9484ad847bc6a594c6a58ccea594d6bd98bd9c84
-cea594ceb594ceb59cd6bd98c69c8ca58c7bb59c73bd947b44272e180920100000180c08
-af9f94a5906bcea594d0ba9994846ba59473b58c73947b56ad8c6bc6a58cbd9c84bda58c
-b5947bbda58cbd9c7bad9484a58c7bd6b9a9b59484a5846b846b52cea594ad9473cea594
-c6b584ad8c73c6ad8cc6ad94c6a58cbda58cb99c8c947b568c73608c7360a08883a08883
-ad847b947b63ad8c7bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9985e52b87158ad7b6ba36150ad7367985e52ad7367985e52ad8463
-ad7b63c69473ad7b6b906f4ead7b6b79483d9c7352a36150985e52ad7b638c634a90573d
-7e5b39ad846bc1a584bd947bad8c7bcea58c9c735ebd9473a57f67cea084bd9c7b8e6352
-a57f67c69c8cc6a594b59484947b63a58c7ba08883cea594b59c7bad9484cea594b59c84
-c6ad8cd6bd98ceb59cb59c73ad847bce9c8cc69c7bc1a5842108102508142a142b100800
-d6b9a9ceb59cc6ad94d7d1c0ad947bcea594a5906bbd947bc1a584d6bd98ad947bc6a594
-ad947bc6ad94bdb594ad8c73ad9473a5906b9c8463ad947bb5a57bd6bd98b59c7bbda58c
-ad947bb1a488d6b9a9ceb594c6ad94b5947b8c7360a5846ba58c7b7d584a735755ad847b
-8c7360ad847ba58c7bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c07c66aa705290573d8448328448328448328e6352a36150703d29
-90573dad846b9c675aa9695c986d5e8c634a8d4938ad7b6384483290573dd0927bc68c84
-d0927b947b56b58c73ad7b6bb58c73ad846bc08c7ead846bcea084b58c739f7e5a945852
-9c7b63c69c8cb99c8cbd9c84bd9c94c6a594b5887bd6b9a9b59c7bb5947bc1a584bda58c
-cea594c6ad94bd9c84b59c73bd9484c68c84a7735dbd94733b1820291021100000180814
-ccb1abc6ad94ceb59cd7d1c0947b63b99c8cc1a584cea58ccead8cd6b9a9b5947bb99c8c
-ad947bbda58ca59473ad948cd0ba99a58c7bad947bad9c7bbda58cad947ba59473b59c84
-bda58cceb59ca59473d6b9a9ebcfb8bdaa91ceb59ca58c7b9473639c847b8c6b5a8c7360
-a58473a59473b59484d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9c07c66ad6b63a5635aa5635ab5736ba5635aa5635aa56b4ead7367
-ad7b6b9c675a945852985e52844832985e52a56b4e996040b77b5dbd846fda9c84ad7b63
-ca946f9c73529c7b63ad7b63ad84739c7b63b58c73985e52b58c739f7e5aa7735d9c7352
-b57f6bc69c84bd9c7bb5947bcead8cc6ad8cbd947bc6ad8cc6a58cbd9c84bd9c84cea594
-c6a58cb5947bad8c73c1a584b5887bb5887bbd9168c69473350c1a25081425101c25101c
-c6a5a0bd9c94ceb59cd7d1c0948677c6ad94cea594ceb594c1a584c6ad94c6a594ad9484
-ad948cc6ad8c9c8c6fad94849c847bbd9c94bdaa91ad948c948677ceb59cad9c84bd9c94
-8c7360d2c7afd6b9a9ad948c947b63bd9c9467504376533e947b63947b63ad847b9c7b6d
-948677c69c8cb59c7bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b87158b87158985e528d4938985e52a36150a7735d90573d844a44
-a7735d844a449c735e8e63529c675ab57f6bad7367c07c66996040a361508d4938b87158
-985e529c7352bd8c73ad846b9c735ecea58c9c73529c7b63985e52c69c73ad846bad846b
-b58c6bc1a584c69c7bad946bc1a584c1a584c69c7bbd947bad8c73b58c73b5947bd6ad96
-bd9484a5846b94685ab5947b844a445a2e278c634aa7735d2d0f0b180014180c08180008
-b9ada5caab9ec6ad94d2c7afd2c7afebcfb8ceb594d0ba99bda58cbda58cbd9c94a58c7b
-b59c84ad9484a5846bad948ca08883a58c7bb19494ad9484948677a08883947b63b59c84
-bdaa91ad948cceb59cd6b9a9675043a088837e5c58948677ad847bbd948c948677ad8c73
-b99c8c947b56b59c84d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9a36150a77047a36150a56b4ea36150a36150a56b4e844832985e52
-ad846b83584d886040945852ad7367ad7b63a36150844832b57f6baa7052a56b4e90573d
-b57f6bbd9168c69473ad846bbd8c73bd947bbd947b9c7352ad846bad84739c7b63cea084
-c69c84cead8ccead8cb59c7bd6ad96bd9c7bc69c84bd947b8c634a9c7b63c69c8ccea084
-a57f67a97b778c634a9c7b63ad847b94585290573d844a44350c1a291021180014180814
-9c7b6dad948cceb59cd7d1c0ccb1abdecaa4d7c69aad9c84bdaa91bd9c94ad9484ad9484
-8c6b5a7e5c58846b527e5c58a58c7b8c7360b59484a58c7bb99c8ca58473c6a594b59c84
-d0ba99bd9c94c6b598a088833823285e45423823283c160a5e3e2876533e83584db59c84
-bd9c84bda58cc6ad94d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9b77b5daa7052a36150a77047a7735da56b4eaa7052b8715894685a
-8e635294685a9c776bc69c8cbd846fad7367a56b4eaa7052b57f6ba77047844832b77b5d
-b87158c6947fa7735dc69c7bb5947bb58c73b58c73906f4e9c735e9c735e7d584aceb59c
-bd9484b59c84bd9c94b59c84c6a58ca57f679c776bad7b635e3e28ad7b63cea5949c735e
-79483d9c735e8e6352a58c7b6a50555a2e27945852ad7b6b3b182024061e100810180814
-a08883d6b9a9bda58cc6b598cebdaddecaa4b5a57bd0ba99d7d1c0c6b5988c7360a58c7b
-6a50557d584abd9c84b99c8cad8c73a59473b59484b59c84c6a58cceb59ca5846bc6ad8c
-ad9c84ad947b6a50552d0f0b3c160a3823283823287e5c585a2e27a584738c7360947b63
-a5846bb1a488b5947bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9a36150844a44996040b57f6b985e52985e528c634a90573d8c634a
-b87158886040b57f6bbd8c73c08c7e9c73528c634a996d47ad7e4fb57f6b996040b77b5d
-bd9168a7735dcea084734c2ead8c639f7e5aa57f679c776bb58c73947b56c69c73bdb594
-a59473a58c7ba58c7b947b637e5c587e5c584621133c160a5a2e27caab9ea58c7b9c7b6d
-94685a6d463cad6b63ad847bce9c8ca9695ca57f679c847b3b1820180814100810180c08
-675043c6ad94a5906bb59c73c6b584ad947b94846ba08883947b637e5c589c7b6d675043
-846b52947b63ad947bbd9c84ad8c6bad8c6bcead8cb59c73c1a584bd9c84b99c8ccaab9e
-ad847b7d584a4f362f2d0f0b38232844272e3b18205e3e285e45429c7b63a58c7bad8c73
-8c7360ad8c6ba59473d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d93c160a734c2e3c160a552617ad736779483d90573d9c7352ad7367
-c08c7e886040bd9484cea084cea58c906f4e9c675a8c634a886040a7735da7735d9c675a
-9c675a76533e886040ad846b9c776b5e3e284f362f5526178c6b5aad846bcead8cc1a584
-a5906bd6bd989c7b63a57f67734c2ea7735dbd8c73b59c73cead8ca57f67bd9c7bbd947b
-985e52c6947fa7735dc39565b58c6bb57f6bc6947394685a26060825081425101c180008
-8e7778ceb59ca5906ba57f67a59473b5947bad948ca5846b9486779c7b638c6b5ac6ad94
-ad947bad8c73a59473b99c8cc6a58cc1a584bd9c7bb59c7bc6ad8c947b6344272e2d0f0b
-3c160a2b181c4f362f38232856363d56363d44272e5e454276533e948677b5947bb59c84
-ad947bad948cad9484d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d92d0f0b2108043b18203c160a4621135a2e277d584a94685a83584d
-4621134621134621135a2e273b18207d584a7d584aad847b8a5a58986d5e7d584a5e3e28
-5a2e274621133b182044272e3c160a25081444272e3b18207d584a986d5ead8473b5947b
-b5947bad846b8c634ab58c73e2b399ad7f5abd8c63dab28cce9c77a07b4ea5845aa07b4e
-996040c39565a7735dd2a575ad7e4fb58456a7735d703d292d0f0b2508140b0319180814
-d5c2bebda49e80695e8c6b5a5e3e282108043b18204621136d463c76533e80695e846b52
-a58c7b9c847b9486779c7b6d8c73608c736094846b5e45423c160a1000082108041b0500
-1800081800081800141800142a142b2b181c25101c2d0f0b735755caab9eb19494947b63
-735755948677ad948cd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d93823281800142b181c2108101b05003823282108043b1820250814
-3823282508142d0f0b3823281b05001b050044272e3823281b05003b1820210810250814
-2508142508141b0500210810250814180014180014100008350c1a3b18204621135a2e27
-7d584a7d584a7e5c5894685ad6ad969c735ead8463b584737d584a9c7b638e635276533e
-8e6352906f4e9c735ebd9473a7735dad7b636d463c260608210810291021180920250814
-c7beb3c7beb3d6b9a9bd9c949486778a5a587357556d463c1000082d0f0b2108043c160a
-1b05002b181c3b18202b181c250814180c081b05001b05002d0f0b2b181c18001425101c
-1809201800140b031918000824061e2508142508142a142b2b181c25101c21081025101c
-2b181c2b181c250814d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d90b0319291021180014382328180014291021350c1a2a142b2b181c
-18001424061e44272e08001029102129102125081425081425101c25101c100008210810
-2b181c350c1a2a142b2108103823282108101800143823286750436a50558a5a58382328
-1800141000081b05002508142108042108043c160a2b181c2108102606082508141b0500
-24061e2b181c25101c2d0f0b2508143b18201800141b05002a142b1800140b0319180c08
-ccb1abbda49ebda49eccb1abad948ca4a196ccb1abbfadb0d7d1c0b194942d0f0b180008
-180c082b181c21081018001418001418001424061e180814180014180014382328080010
-1809201808142a142b2a142b2a142b18001418001408001018001424061e25101c180814
-1800141800142a142bd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d92a142b18000829102118001424061e2b181c2a142b382328180014
-25101c2a142b18000825081429102129102138232829102144272e2508142b181c2d0f0b
-6a50555e45427e5c5873575596878799797b80695e99797ba0888391706d9c847b99797b
-5e454224061e2a142b18001424061e25101c10000024061e0b03191800142a142b180014
-24061e18081418001424061e24061e1800142910212a142b2a142b1800083823288e7778
-b9ada5b9ada5c6b598a3908c948677b19ca3a3908ca1988dbd9c94a08883bfadb0bfadb0
-b19ca36a505538232824061e25101c25101c10000029102125101c29102108001025101c
-2b181c180c0818081418001425101c18081425101c24061e2a142b25101c2a142b2b181c
-25101c0b031924061ed9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d97e5c5856363d4f362f382328b59484c7beb380695ebda49ec7beb3
-b19ca3a3908ca3908c56363da08883a3908cbfadb0b19494bd9c94b19ca3d5c2beaf9f94
-bda49ebda49ebd9c94c6ad94d6b9a9caab9eb99c8cb99c8cad9484ad9484bd9c94ad9484
-caab9eaf9f94846b6e18001425101c18000825101c100008180814382328382328250814
-25101c1800082b181c1808142508141808142b181c10000821080444272ead948cb19494
-ad948caf9f94b1a8a2d7d1c0d7d1c0bcb8aed5c2bec7beb3c6b598ccb1abc7beb3d5c2be
-a1988dbda49e6a5055af9f94a08883a088839687878e77784f362f5e4542846b6e948677
-b2aa94b9ada5c7beb3a4a196846b6e2b181c1008006a50558e7778a3908cb1a8a2b19ca3
-8e777856363d180920d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9e4bda2cea084dab28cebcfb8caab9ecaab9ebd9c94af9f94c6b598
-bda49ed2c7afd6b9a9bda49ed6b9a9caab9ebd9c94c6a594947b63bd9c94ccb1abccb1ab
-ad9c7bd6b9a9c6ad94ebcfb8cead8ccead8cd0ba99d0ba99c6b598d6b9a9d6b9a9d0ba99
-cead8cebcfb8ceb59cd5c2bed5c2bec7beb3d5c2bec7beb3d7d1c0d2c7afebcfb8ccb1ab
-d0ba99c7beb3d7d1c0ebcfb8ceb59cbdaa91d6b9a9caab9ecaab9ecaab9ed6b9a9d6b9a9
-ad9c84ccb1abbcb8aed7d1c0bcb8aebcb8aed7d1c0bdb594d7d1c0ad9c84c7beb3decaa4
-d7d1c0d7d1c0bdaa91d2c7afdecaa4d2c7afcaab9eebcfb8d2c7afd2c7afd6b9a9eacba5
-ebcfb8c6b598c6a5a0b9ada5c7beb3ccb1abd7d1c0af9f94cebdadaf9f94b99c8cb1a8a2
-d5c2bec7beb3ccb1abd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373000000
-
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/line.gif b/lib/gs/doc/src/images/line.gif
deleted file mode 100644
index 4f4faa9477..0000000000
--- a/lib/gs/doc/src/images/line.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/line.ps b/lib/gs/doc/src/images/line.ps
deleted file mode 100644
index e1419ba499..0000000000
--- a/lib/gs/doc/src/images/line.ps
+++ /dev/null
@@ -1,1613 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/line.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 334 337 460
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 408 string def
-
-% define space for color conversions
-/grays 136 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 334 translate
-
-% size of image (on paper, in 1/72inch coords)
-136.00800 126.00000 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-136 126 8 % dimensions of data
-[136 0 0 -126 0 126] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffff000000000080000080ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffff000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080000080ffffff000080000080ffffff000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff
-000080ffffffffffff000080ffffffffffff000080000080000080ffffffffffffffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff
-000080ffffffffffffffffff000080ffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffffffffffffffff
-ffffffffffff000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffffffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffffffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffff
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080ffffff737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373000000ffffff
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373000000000080000080ffffff737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000080000080000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/oval.gif b/lib/gs/doc/src/images/oval.gif
deleted file mode 100644
index 53162ecbd4..0000000000
--- a/lib/gs/doc/src/images/oval.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/oval.ps b/lib/gs/doc/src/images/oval.ps
deleted file mode 100644
index 6add5803ed..0000000000
--- a/lib/gs/doc/src/images/oval.ps
+++ /dev/null
@@ -1,2321 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/oval.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 311 370 459
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 507 string def
-
-% define space for color conversions
-/grays 169 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 311 translate
-
-% size of image (on paper, in 1/72inch coords)
-168.98400 148.03200 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-169 148 8 % dimensions of data
-[169 0 0 -148 0 148] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
-000080000080ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffff000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffffffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000
-000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373000000
-000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffffffff000080000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000
-000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373000000
-000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080000080ffffff000080000080ffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080000080000080000080000080000080ffffff
-ffffff000080000080000080000080ffffffffffff000080ffffffffffff000080000080
-000080ffffffffffff000080000080ffffffffffffffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000
-000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffffffffff000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080000080000080000080ffffffffffff000080ffffffffffff000080000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000
-000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080000080000080000080000080ffffffffffff000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000
-000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080000080ffffffffffffffffffffffffffffff000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000
-000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080000080000080000080ffffffffffff000080000080000080ffffffffffff
-ffffff000080000080000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000
-000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080000080
-ffffffffffff000080000080ffffffffffff000080000080000080000080ffffffffffff
-ffffff000080000080000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000
-000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000
-000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080000080
-000080ffffffffffffffffffffffff000080000080000080000080000080000080ffffff
-000080000080000080000080000080ffffffffffffffffff000080ffffffffffffffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000
-000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000
-000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373000000
-000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffff737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373000000ffffff737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373000000
-000080000080ffffff737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000080000080000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000ff0000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000
-000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000000000000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000000000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-000000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000000000000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000000000000000
-000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/packer1.gif b/lib/gs/doc/src/images/packer1.gif
deleted file mode 100644
index d10622aacd..0000000000
--- a/lib/gs/doc/src/images/packer1.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/packer1.ps b/lib/gs/doc/src/images/packer1.ps
deleted file mode 100644
index 50952e706f..0000000000
--- a/lib/gs/doc/src/images/packer1.ps
+++ /dev/null
@@ -1,5987 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/ntmp/packer1.ps
-%%Creator: XV Version 3.10a Rev: 12/29/94 - by John Bradley
-%%BoundingBox: 201 232 411 559
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 630 string def
-
-% define space for color conversions
-/grays 210 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 232 translate
-
-% size of image (on paper, in 1/72inch coords)
-210.02400 327.02400 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-210 327 8 % dimensions of data
-[210 0 0 -327 0 327] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffff000000000080000080ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffffffffffffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffff000080000080ffffffffffff000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffffffffffffffff000080000080000080ffffffffffffffffffffffff000080
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080000080000080
-000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff
-ffffffffffff000080000080ffffff000080ffffffffffffffffff000080ffffffffffff
-ffffff000080000080000080ffffffffffffffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffffffffffffffffffffff000080000080000080000080
-000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080ffffffffffff000080ffffffffffff000080000080000080000080
-000080ffffffffffffffffffffffff000080000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffffffffff000080000080000080000080000080000080
-000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080000080
-ffffffffffffffffffffffffffffff000080ffffffffffff000080000080000080000080
-000080ffffffffffffffffffffffff000080000080000080ffffffffffffffffffffffff
-ffffffffffff000080ffffffffffff000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffffffffff
-ffffffffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080000080000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080ffffffffffff000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffff000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080000080000080000080000080000080
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080000080
-ffffffffffffffffff000080ffffffffffff000080ffffffffffffffffffffffff000080
-000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080000080
-000080ffffffffffffffffffffffffffffff000080000080000080000080ffffffffffff
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffffffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000
-000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffff737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-000000ffffff737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373000000000080000080ffffff737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000080000080000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9
-000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffffd9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-ffffffd9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffffd9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffff
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0ffffffd9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-d9d9d9ffffffd9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-ffffffd9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0ffffff
-d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0ffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0ffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-d9d9d9ffffffd9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-ffffffd9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0ffffffd9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-ffffffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9c0c0c0d9d9d9ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-000000c0c0c0ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9000000c0c0c0ffffffd9d9d9ffffffd9d9d9
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9
-ffffffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9ffffffd9d9d9d9d9d9d9d9d9
-000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9
-ffffffd9d9d9ffffffd9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9
-ffffffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9ffffffd9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffd9d9d9ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0ffffffd9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9ffffffd9d9d9c0c0c0c0c0c0c0c0c0d9d9d9
-ffffffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-d9d9d9ffffffd9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9ffffffc0c0c0ffffff
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9
-ffffffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000c0c0c0ffffff
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0d9d9d9
-ffffffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9
-000000d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9
-ffffffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9000000
-d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000d9d9d9
-000000c0c0c0ffffffd9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000c0c0c0ffffffd9d9d9000000d9d9d9
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9
-ffffffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-d9d9d9c0c0c0d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9c0c0c0d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffc0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/packer2.gif b/lib/gs/doc/src/images/packer2.gif
deleted file mode 100644
index 588a4675b4..0000000000
--- a/lib/gs/doc/src/images/packer2.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/packer2.ps b/lib/gs/doc/src/images/packer2.ps
deleted file mode 100644
index f4ab9cb03f..0000000000
--- a/lib/gs/doc/src/images/packer2.ps
+++ /dev/null
@@ -1,5176 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/ntmp/packer2.ps
-%%Creator: XV Version 3.10a Rev: 12/29/94 - by John Bradley
-%%BoundingBox: 201 384 540 559
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 1017 string def
-
-% define space for color conversions
-/grays 339 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 384 translate
-
-% size of image (on paper, in 1/72inch coords)
-338.97600 175.03200 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-339 175 8 % dimensions of data
-[339 0 0 -175 0 175] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffff000000000080000080ffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffff000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffffffffffffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0
-c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0
-737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffff000080000080ffffffffffff000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0
-c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0
-737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffffffffffffffff000080000080000080ffffffffffffffffffffffff000080
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080000080000080
-000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff
-ffffffffffff000080000080ffffff000080ffffffffffffffffff000080ffffffffffff
-ffffff000080000080000080ffffffffffffffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0
-c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0
-737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffffffffffffffffffffff000080000080000080000080
-000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0
-c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0
-737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000
-000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080ffffffffffff000080ffffffffffff000080000080000080000080
-000080ffffffffffffffffffffffff000080000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffffffffff000080000080000080000080000080000080
-000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0
-c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0
-737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080000080
-ffffffffffffffffffffffffffffff000080ffffffffffff000080000080000080000080
-000080ffffffffffffffffffffffff000080000080000080ffffffffffffffffffffffff
-ffffffffffff000080ffffffffffff000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffffffffff
-ffffffffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0
-c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0
-737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000
-000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080000080000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080ffffffffffff000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffff000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0
-c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0
-737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080000080000080000080000080000080
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000
-000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0
-c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0
-737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080000080
-ffffffffffffffffff000080ffffffffffff000080ffffffffffffffffffffffff000080
-000080ffffffffffff000080000080000080ffffffffffff000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080000080000080000080000080000080000080
-000080ffffffffffffffffffffffffffffff000080000080000080000080ffffffffffff
-ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080000080ffffffffffffffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000
-000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0
-c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0
-737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080ffffff737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373000000ffffff737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373000000000080000080ffffff737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000080000080000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9000000000000d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9
-d9d9d9000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9000000000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9
-d9d9d9d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000d9d9d9000000d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9ffffffd9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-ffffffd9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffd9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9ffffffd9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffff
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0ffffffd9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-d9d9d9ffffffd9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-ffffffd9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0ffffff
-d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0ffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9000000d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0ffffffd9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0d9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9
-ffffffd9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-d9d9d9ffffffd9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-ffffffd9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0ffffffd9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffff
-d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000d9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9ffffffd9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9c0c0c0d9d9d9ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9
-000000c0c0c0ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9000000c0c0c0ffffffd9d9d9ffffffd9d9d9c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9ffffffd9d9d9d9d9d9d9d9d9
-000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9ffffffd9d9d9ffffffd9d9d9
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9ffffffd9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffff
-d9d9d9ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0ffffffd9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-ffffffd9d9d9ffffffd9d9d9c0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-d9d9d9ffffffd9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ffffffd9d9d9ffffffc0c0c0ffffffd9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9ffffffd9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0000000d9d9d9000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000d9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9000000d9d9d9d9d9d9d9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000d9d9d9000000d9d9d9d9d9d9d9d9d9
-000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000c0c0c0ffffffd9d9d9d9d9d9d9d9d9000000d9d9d9000000d9d9d9
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9000000d9d9d9000000
-d9d9d9c0c0c0d9d9d9ffffffd9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000d9d9d9c0c0c0d9d9d9ffffffd9d9d9000000d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000d9d9d9
-000000c0c0c0ffffffd9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9
-000000d9d9d9000000c0c0c0ffffffd9d9d9000000d9d9d9c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d9d9d9ffffffd9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-d9d9d9c0c0c0d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000d9d9d9000000
-d9d9d9000000d9d9d9c0c0c0d9d9d9000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffd9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000d9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9
-ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffff
-d9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9ffffffd9d9d9d9d9d9c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/polygon.gif b/lib/gs/doc/src/images/polygon.gif
deleted file mode 100644
index 34ffedc4dd..0000000000
--- a/lib/gs/doc/src/images/polygon.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/polygon.ps b/lib/gs/doc/src/images/polygon.ps
deleted file mode 100644
index bb59c8022f..0000000000
--- a/lib/gs/doc/src/images/polygon.ps
+++ /dev/null
@@ -1,1963 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/polygon.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 327 366 460
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 495 string def
-
-% define space for color conversions
-/grays 165 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 327 translate
-
-% size of image (on paper, in 1/72inch coords)
-165.02400 132.98400 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-165 133 8 % dimensions of data
-[165 0 0 -133 0 133] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffff000000000080000080ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffff000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000
-000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffff000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000
-000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080000080ffffff000080000080ffffff000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffffffffffffffff000080000080ffffffffffff000080ffffffffffff000080
-000080000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffffffffffffffff000080000080ffffffffffff000080ffffffffffff
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffffffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080ffffffffffff000080
-000080000080ffffffffffff000080ffffffffffff000080ffffffffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffffffffff000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080000080ffffff
-ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080ffffffffffff000080000080000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080000080ffffff
-ffffffffffff000080000080000080ffffffffffff000080ffffffffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0
-c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080ffffffffffff000080000080000080000080000080000080
-ffffffffffffffffffffffff000080000080ffffffffffff000080000080000080000080
-ffffffffffff000080000080000080000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffffffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000
-000000000000000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffff000080000080000080000080000080000080000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080ffffff
-ffffff000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-ffffff737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373000000ffffff737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373000000000080000080ffffff737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffffffff
-000080000080000080000080000080000080ffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000080000080000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000000000
-000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000000000000000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000000000000000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000000000000000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000000000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/rectangle.gif b/lib/gs/doc/src/images/rectangle.gif
deleted file mode 100644
index 9085943255..0000000000
--- a/lib/gs/doc/src/images/rectangle.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/rectangle.ps b/lib/gs/doc/src/images/rectangle.ps
deleted file mode 100644
index 11262035d8..0000000000
--- a/lib/gs/doc/src/images/rectangle.ps
+++ /dev/null
@@ -1,2173 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/rectangle.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 311 364 459
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 489 string def
-
-% define space for color conversions
-/grays 163 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 311 translate
-
-% size of image (on paper, in 1/72inch coords)
-163.00800 148.03200 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-163 148 8 % dimensions of data
-[163 0 0 -148 0 148] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffff000000000080000080ffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffff000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080000080ffffff000080000080ffffff000080000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-000080ffffffffffffffffffffffff000080000080000080ffffffffffffffffffffffff
-000080000080ffffffffffffffffffffffff000080000080ffffffffffffffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080000080000080ffffffffffff
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffffffffffffffff
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffffffffff000080ffffffffffff000080ffffffffffff000080
-ffffffffffffffffff000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080000080
-000080000080000080ffffffffffff000080000080000080000080000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffffffffffffffffffffffffffff000080ffffffffffff000080000080000080
-000080000080000080ffffffffffff000080000080000080ffffffffffffffffffffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080ffffffffffffffffffffffffffffff
-ffffff000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080000080000080000080ffffffffffff000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-ffffffffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffffffffff000080000080ffffff
-ffffff000080ffffffffffff000080000080ffffffffffff000080ffffffffffff000080
-ffffffffffffffffff000080ffffffffffff000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080
-000080ffffffffffffffffffffffff000080000080000080ffffffffffffffffffffffff
-000080000080000080000080ffffffffffff000080000080ffffffffffffffffff000080
-ffffffffffffffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffffffffffffffff
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080ffffffffffff000080
-000080ffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffff737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373000000ffffff737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373000000000080000080ffffff737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffffffff
-ffffffffffff000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000080000080000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff
-00ffff00ffff000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/text.gif b/lib/gs/doc/src/images/text.gif
deleted file mode 100644
index d3971d5da0..0000000000
--- a/lib/gs/doc/src/images/text.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/text.ps b/lib/gs/doc/src/images/text.ps
deleted file mode 100644
index d5575e3dac..0000000000
--- a/lib/gs/doc/src/images/text.ps
+++ /dev/null
@@ -1,1767 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/text.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 340 364 459
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 489 string def
-
-% define space for color conversions
-/grays 163 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 340 translate
-
-% size of image (on paper, in 1/72inch coords)
-163.00800 119.01600 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-163 119 8 % dimensions of data
-[163 0 0 -119 0 119] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffff737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffff000000000080000080ffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080ffffffffffffffffffffffffffffffffffffffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080ffffffffffff000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffff000080000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080ffffffffffff000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080000080ffffff000080000080ffffff000080000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-ffffffffffffffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffffffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080ffffff
-ffffff000080000080ffffffffffff000080000080ffffffffffffffffffffffff000080
-000080000080ffffffffffff000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080ffffff
-ffffffffffffffffffffffffffffff000080000080000080ffffffffffff000080000080
-000080000080ffffffffffff000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080000080000080ffffffffffff000080000080000080ffffff
-ffffff000080000080000080000080000080000080ffffffffffffffffffffffff000080
-000080000080ffffffffffff000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080000080000080ffffffffffff000080000080000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080ffffff000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-ffffffffffffffffffffffff000080000080ffffffffffff000080000080ffffffffffff
-000080000080000080ffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000
-000000000000c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffffc0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080ffffffc0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080ffffff737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373000000ffffff737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373000000000080000080ffffff737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000080000080000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000ff0000
-d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000d9d9d9d9d9d9ff0000ff0000ff0000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000ff0000ff0000d9d9d9d9d9d9ff0000ff0000
-ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000ff0000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9ff0000ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000
-ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000
-ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9
-ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000
-ff0000ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000d9d9d9ff0000ff0000
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000ff0000
-ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9
-ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9ff0000ff0000
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000d9d9d9d9d9d9ff0000
-ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000ff0000d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000ff0000ff0000
-ff0000ff0000ff0000ff0000d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000
-d9d9d9ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000
-d9d9d9ff0000ff0000d9d9d9ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9ff0000d9d9d9
-d9d9d9ff0000ff0000d9d9d9ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9ff0000d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000d9d9d9
-d9d9d9ff0000ff0000ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000
-d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9ff0000
-ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000ff0000
-d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000
-ff0000ff0000d9d9d9d9d9d9ff0000ff0000ff0000ff0000d9d9d9ff0000ff0000ff0000
-ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9
-d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9ff0000
-ff0000ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000ff0000d9d9d9d9d9d9
-d9d9d9ff0000ff0000ff0000ff0000d9d9d9d9d9d9d9d9d9ff0000ff0000ff0000ff0000
-ff0000ff0000d9d9d9d9d9d9ff0000ff0000d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/images/window.gif b/lib/gs/doc/src/images/window.gif
deleted file mode 100644
index 7d0f4500ed..0000000000
--- a/lib/gs/doc/src/images/window.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/images/window.ps b/lib/gs/doc/src/images/window.ps
deleted file mode 100644
index a17aa009ac..0000000000
--- a/lib/gs/doc/src/images/window.ps
+++ /dev/null
@@ -1,3221 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/eklas/erlang/gs/doc/sgml/pics/window.ps
-%%Creator: XV Version 3.10 Rev: 12/16/94 - by John Bradley
-%%BoundingBox: 201 303 431 459
-%%Pages: 1
-%%DocumentFonts:
-%%EndComments
-%%EndProlog
-
-%%Page: 1 1
-
-% remember original state
-/origstate save def
-
-% build a temporary dictionary
-20 dict begin
-
-% define string to hold a scanline's worth of data
-/pix 690 string def
-
-% define space for color conversions
-/grays 230 string def % space for gray scale line
-/npixls 0 def
-/rgbindx 0 def
-
-% lower left corner
-201 303 translate
-
-% size of image (on paper, in 1/72inch coords)
-229.96800 156.02400 scale
-
-% define 'colorimage' if it isn't defined
-% ('colortogray' and 'mergeprocs' come from xwd2ps
-% via xgrab)
-/colorimage where % do we know about 'colorimage'?
- { pop } % yes: pop off the 'dict' returned
- { % no: define one
- /colortogray { % define an RGB->I function
- /rgbdata exch store % call input 'rgbdata'
- rgbdata length 3 idiv
- /npixls exch store
- /rgbindx 0 store
- 0 1 npixls 1 sub {
- grays exch
- rgbdata rgbindx get 20 mul % Red
- rgbdata rgbindx 1 add get 32 mul % Green
- rgbdata rgbindx 2 add get 12 mul % Blue
- add add 64 idiv % I = .5G + .31R + .18B
- put
- /rgbindx rgbindx 3 add store
- } for
- grays 0 npixls getinterval
- } bind def
-
- % Utility procedure for colorimage operator.
- % This procedure takes two procedures off the
- % stack and merges them into a single procedure.
-
- /mergeprocs { % def
- dup length
- 3 -1 roll
- dup
- length
- dup
- 5 1 roll
- 3 -1 roll
- add
- array cvx
- dup
- 3 -1 roll
- 0 exch
- putinterval
- dup
- 4 2 roll
- putinterval
- } bind def
-
- /colorimage { % def
- pop pop % remove 'false 3' operands
- {colortogray} mergeprocs
- image
- } bind def
- } ifelse % end of 'false' case
-
-
-
-230 156 8 % dimensions of data
-[230 0 0 -156 0 156] % mapping matrix
-{currentfile pix readhexstring pop}
-false 3 colorimage
-
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0000000
-c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000000080000080ffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffff000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080ff0000ff0000ff0000
-ff0000ff0000000080000080000080000080000080000080000080ff0000000080000080
-000080000080000080000080000080000080ffffffffffff000080000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffffffffffffffff000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000ff0000
-ff0000ff0000ff0000000080000080000080000080000080ff0000000080000080000080
-000080000080000080000080000080ffffffffffffffffffffffff000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffff000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-ff0000ff0000ff0000ff0000000080000080000080ff0000000080000080000080000080
-000080000080000080000080000080ffffff000080000080ffffff000080000080000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff
-ffffffffffffffffff000080ffffffffffff000080ffffffffffff000080000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffffffffffffffff000080
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000ff0000ff0000ff0000ff0000000080ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080ffffff000080000080ffffffffffff000080000080ffffff
-000080ffffffffffff000080ffffffffffffffffff000080ffffffffffff000080ffffff
-ffffff000080ffffffffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000ff0000ff0000000080ff0000000080000080000080000080000080000080
-000080000080000080000080ffffffffffff000080000080ffffffffffff000080000080
-000080000080000080000080ffffffffffff000080ffffffffffff000080ffffffffffff
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080ff0000000080ff0000ff0000ff0000000080000080000080000080000080
-000080000080000080000080ffffffffffffffffffffffffffffffffffff000080000080
-000080000080000080000080ffffffffffff000080ffffffffffff000080ffffffffffff
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000
-000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080ff0000000080ff0000ff0000ff0000ff0000ff0000000080000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080000080ffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080ffffffffffff000080ffffffffffff000080ffffffffffff000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0
-000000000000c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-ff0000000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080ffffff
-ffffff000080ffffffffffffffffff000080ffffffffffff000080000080ffffffffffff
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000
-000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0
-c0c0c0000000000000c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080ff0000
-000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080000080
-000080000080000080ffffffffffff000080000080000080000080ffffffffffff000080
-000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080
-000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080
-ffffffffffff000080ffffffffffff000080000080ffffffffffffffffffffffff000080
-000080000080000080ffffffffffff000080000080ffffffffffff000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000000000
-000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080ff0000000080
-000080000080000080000080000080000080ff0000ff0000ff0000ff0000ff0000000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000ffffffc0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373
-000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080ffffff737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373000000ffffff737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-000000000080000080ffffff737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000080000080000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080000080000080000080
-000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
-737373000000
-c0c0c0737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373737373737373737373737373737373737373737373737373737373737373737373
-737373000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000
-000000000000
-
-showpage
-
-% stop using temporary dictionary
-end
-
-% restore original state
-origstate restore
-
-%%Trailer
diff --git a/lib/gs/doc/src/inofficial_options b/lib/gs/doc/src/inofficial_options
deleted file mode 100644
index e3fa222943..0000000000
--- a/lib/gs/doc/src/inofficial_options
+++ /dev/null
@@ -1,65 +0,0 @@
-The following options should be used with extreme care since they will
-most likely be removed or changed in a future release.
-
-Object Options
-----------------------------------------------------------------------------
-Window highlightbw,highlightbg
-Button disabledfg,activebg,activefg,highlightbw,highlightfg,
-Entry highlightbg,highlightbw,highlightfg,
- selectbg,selectfg,insertbg
-Label highlightbg,highlightbw,highlightfg,
-Listbox highlightbg,highlightbw,highlightfg,
- selectbg,selectbw,selectfg,activebg,scrollbg,scrollfg
-Canvas activebg,highlightbg,highlightbw,highlightfg,
- selectbg,selectbw,selectfg
-CanvasObj {stipple, Bool} fills object with gray bitmap pattern.
- Will be changed or removed.
-Image {load_gif, Filename},{save_gif,Filename},
- Config: {pix_val,{{X,Y},Color}}|{pix_val,{{{X1,Y1},{X2,Y2}},Color}
- Read: {pix_val, {X,Y}} -> Color
-Scale activebghighlightbg,highlightbw,highlightfg
-Menubar highlightbg,highlightbw,highlightfg
-Menubutton activebg/fg,disabledfg,highlightbg,highlightbw,highlightfg,
-Menu activebg/fg/bw,disabledfg
-Menuitem activefg/bg, {accelerator, TkKbdString} syntax will change.
-Editor activebg,highlightbg,highlightbw,highlightfg
- selectbg,selectbw,selectfg,insertbw,insertbg
-
-======================================================================
-Description of the meaning of the options
------------------------------------------
-
-{anchor, n|w|s|e|nw|se|ne|sw|center}:
-Where {X,Y} refers to. Default is nw. Applies to all objects that can
-have a frame as parent.
-
-{activebg/fg, Color}:
-Specifies (foreground-) background color to use when drawing active
-elements. An element (a widget or portion of a widget) is active if
-the mouse cursor is positioned over the element and pressing a mouse
-button will cause some action to occur.
-
-{disabledfg/bg,Color}:
-The color of the object when 'enable' option is false.
-
-{highlightbg, Color}:
-Specifies the color to display in the traversal highlight region when
-the widget does not have the input focus.
-
-{highlightbw,Npixels}:
-The width of the highlight rectangle to draw around the outside of the
-widget when it has the input focus.
-
-{highlightfg,Color}:
-Specifies the color to display in the traversal highlight region when
-the widget does not have the input focus.
-
-{insertbg,Color}:
-Specifies the color to use as background in the area covered by the
-insertion cursor.
-
-{selectbg/fg,Color}:
-Appearance of selected text.
-
-{insertbg,Color}:
-Color of insertion cursor.
diff --git a/lib/gs/doc/src/note.gif b/lib/gs/doc/src/note.gif
deleted file mode 100644
index 6fffe30419..0000000000
--- a/lib/gs/doc/src/note.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/doc/src/notes.xml b/lib/gs/doc/src/notes.xml
deleted file mode 100644
index 20188c75e2..0000000000
--- a/lib/gs/doc/src/notes.xml
+++ /dev/null
@@ -1,363 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2004</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>GS Release Notes</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- <file>notes.xml</file>
- </header>
- <p>This document describes the changes made to the GS application.</p>
-
- <section><title>GS 1.6.1</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Internal changes</p>
- <p>
- Own Id: OTP-13551</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>GS 1.6</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Change license text from Erlang Public License to Apache
- Public License v2</p>
- <p>
- Own Id: OTP-12845</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>GS 1.5.16</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Application upgrade (appup) files are corrected for the
- following applications: </p>
- <p>
- <c>asn1, common_test, compiler, crypto, debugger,
- dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe,
- inets, observer, odbc, os_mon, otp_mibs, parsetools,
- percept, public_key, reltool, runtime_tools, ssh,
- syntax_tools, test_server, tools, typer, webtool, wx,
- xmerl</c></p>
- <p>
- A new test utility for testing appup files is added to
- test_server. This is now used by most applications in
- OTP.</p>
- <p>
- (Thanks to Tobias Schlager)</p>
- <p>
- Own Id: OTP-11744</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>GS 1.5.15.2</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>Where necessary a comment stating encoding has been
- added to Erlang files. The comment is meant to be removed
- in Erlang/OTP R17B when UTF-8 becomes the default
- encoding. </p>
- <p>
- Own Id: OTP-10630</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>GS 1.5.15.1</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>The GS applications is now deprecated and will be
- removed in the R16 release. The following GS-based
- applications have been superseded by the Observer
- application and will removed in R16: Appmon, Pman,
- Tv.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-9907</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>GS 1.5.15</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>Erlang/OTP can now be built using parallel make if you
- limit the number of jobs, for instance using '<c>make
- -j6</c>' or '<c>make -j10</c>'. '<c>make -j</c>' does not
- work at the moment because of some missing
- dependencies.</p>
- <p>
- Own Id: OTP-9451</p>
- </item>
- <item>
- <p>
- Eliminate use of deprecated regexp module</p>
- <p>
- Own Id: OTP-9810</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>GS 1.5.14</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>Remove misc. compiler warnings</p>
- <p>
- Own Id: OTP-9542</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>GS 1.5.13</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- The documentation for GS is updated with the warning that
- it should not be used in new applications. GS is planned
- to be deprecated soon and might be removed from the
- distribution already in the next major release (R15). For
- graphical applications we recommend the use of WX
- instead.</p>
- <p>
- Own Id: OTP-8824</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section>
- <title>GS 1.5.10</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>
- Updated the application with new tags for automatic updates
- of copyright notices.
- </p>
- <p>Own Id: OTP-7851</p>
- </item>
- </list>
- </section>
- </section>
-
- <section><title>GS 1.5.12</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Warnings due to new autoimported BIFs removed</p>
- <p>
- Own Id: OTP-8674 Aux Id: OTP-8579 </p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>GS 1.5.11</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- The documentation is now built with open source tools
- (xsltproc and fop) that exists on most platforms. One
- visible change is that the frames are removed.</p>
- <p>
- Own Id: OTP-8201</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>GS 1.5.9</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fixed grid_line crash, which caused tv, debugger and pman
- crashes. Thanks Jan Jacobs and others.</p>
- <p>
- Own Id: OTP-7242</p>
- </item>
- </list>
- </section>
-
- </section>
-
- <section><title>GS 1.5.8</title>
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Uses wish85 if available and fixed 'gs error:
- gstk_port_handler: error in input : unknown option
- "-sta"' error. Thanks Vance Shipley</p>
- <p>
- Own Id: OTP-7115</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>GS 1.5.7</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Fixed font size and some bugs in the generic file dialog,
- which is undocumented and mainly intended for internal
- use (today it is only used by Pman).</p>
- <p>The file <c><![CDATA[priv/bitmap/fup.bm]]></c> has been added and the
- module <c><![CDATA[tool_genfd]]></c> removed.</p>
- <p>Also fixed dialyzer warning in <c><![CDATA[gs_packer]]></c>.</p>
- <p>Own Id: OTP-6682</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>GS 1.5.6</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Removed some dead code from <c><![CDATA[gstk_editor]]></c> and
- <c><![CDATA[tcl2erl]]></c>.</p>
- <p>Own Id: OTP-6541</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>GS 1.5.5</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Corrected some bugs in the examples.</p>
- <p>Own Id: OTP-5988</p>
- </item>
- <item>
- <p>Removed <c><![CDATA[export_all]]></c> from <c><![CDATA[gs_widgets]]></c>,
- <c><![CDATA[gs_frontend]]></c>, <c><![CDATA[gstk]]></c>, <c><![CDATA[gstk_db]]></c>,
- <c><![CDATA[gstk_generic]]></c>, <c><![CDATA[gstk_gs]]></c>, <c><![CDATA[gstk_widgets]]></c>,
- <c><![CDATA[tcl2erl]]></c>, <c><![CDATA[tool_file_dialog]]></c>,
- <c><![CDATA[tool_genfd]]></c>.</p>
- <p>Own Id: OTP-6008</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Fixed the functions for creating help windows
- (notify/confirm/request) in the internal module
- <c><![CDATA[tool_utils]]></c>, so that the help window can be
- centered over its parent window (instead of at a random
- position).</p>
- <p>Own Id: OTP-5987</p>
- </item>
- <item>
- <p>Eliminated some dead code from <c><![CDATA[gstk]]></c>, found by
- Dialyzer.</p>
- <p>Own Id: OTP-6045</p>
- </item>
- <item>
- <p>Upgraded tcl/tk binaries to version 8.4.13</p>
- <p>Own Id: OTP-6106</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>GS 1.5.4</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The graphic applications now search for HTML
- documentation in the correct place.</p>
- <p>Own Id: OTP-5381</p>
- </item>
- </list>
- </section>
- </section>
-</chapter>
-
diff --git a/lib/gs/doc/src/part.xml b/lib/gs/doc/src/part.xml
deleted file mode 100644
index 99c3f20243..0000000000
--- a/lib/gs/doc/src/part.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>1996</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>GS User's Guide</title>
- <prepared>Klas Eriksson</prepared>
- <docno></docno>
- <date>1997-05-15</date>
- <rev>1.3</rev>
- <file>part.sgml</file>
- </header>
- <description>
- <p>The Graphics System application, <em>GS</em>, is a library of
- routines for writing graphical user interfaces. Programs written
- using GS work on all Erlang platforms and do not depend upon the
- underlying windowing system. </p>
- </description>
- <xi:include href="gs_chapter1.xml"/>
- <xi:include href="gs_chapter2.xml"/>
- <xi:include href="gs_chapter3.xml"/>
- <xi:include href="gs_chapter4.xml"/>
- <xi:include href="gs_chapter5.xml"/>
- <xi:include href="gs_chapter6.xml"/>
- <xi:include href="gs_chapter7.xml"/>
- <xi:include href="gs_chapter8.xml"/>
-</part>
-
diff --git a/lib/gs/doc/src/part_notes.xml b/lib/gs/doc/src/part_notes.xml
deleted file mode 100644
index c8876a14d4..0000000000
--- a/lib/gs/doc/src/part_notes.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>2004</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>GS Release Notes</title>
- <prepared>Ingela Anderton Andin</prepared>
- <docno></docno>
- <date>2004-09-08</date>
- <rev></rev>
- <file>part_notes.sgml</file>
- </header>
- <description>
- <p>The Graphics System application, <em>GS</em>, is a library of
- routines for writing graphical user interfaces. Programs written
- using GS work on all Erlang platforms and do not depend upon the
- underlying windowing system.</p>
- </description>
- <xi:include href="notes.xml"/>
-</part>
-
diff --git a/lib/gs/doc/src/ref_man.xml b/lib/gs/doc/src/ref_man.xml
deleted file mode 100644
index 1e701ab71b..0000000000
--- a/lib/gs/doc/src/ref_man.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE application SYSTEM "application.dtd">
-
-<application xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>1997</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>GS Reference Manual</title>
- <prepared>Klas Eriksson</prepared>
- <docno></docno>
- <date>1997-05-15</date>
- <rev>1.3</rev>
- <file>application.sgml</file>
- </header>
- <description>
- <p>The Graphics System application, <em>GS</em>, is a library of
- routines for writing graphical user interfaces. Programs written
- using GS work on all Erlang platforms and do not depend upon the
- underlying windowing system. </p>
- </description>
- <xi:include href="gs.xml"/>
-</application>
-
diff --git a/lib/gs/doc/src/removed_options b/lib/gs/doc/src/removed_options
deleted file mode 100644
index 045024f6f6..0000000000
--- a/lib/gs/doc/src/removed_options
+++ /dev/null
@@ -1,31 +0,0 @@
-The following options are implemented but should not be a part of gs.
-======================================================================
-
-Option Removed for reason
----------------------------------
-relief 1) Backend should do decoration.
- 1) If we should have decoration it should be
- less tk dependent. Ex: {3d, on/off}
-iconbitmask Makes us even more X11 depndent.
-bw 1) Borders are decoration.
- 2) Borders introduce more color programming option unless a
- color model exists. If we have this option,bc (border color),
- selectbw and highlightbw, are soon coming.
-padx/y Nitty-gritty programming. Simple padding can be achieved
- with space. We can set width of a button and use align.
-wraplength Wrapping is ok for the editor but overkill for buttons.
- tk has support for it but how about other backends?
-xselection X11 dependent.
-scale Simple canvas objects such as oval and rectangle are simple
- to scale manually. We should thing more before intruducing it
- on bitmaps and text objects.
-capstyle + (Look of a line's endpoints.)
-joinstyle (How joined line segments should look.)
- These options should be one {pentype, circle/rectangle}
- (simplified and less tk inspired).
-menu (For menuitem.)
- This is taker care of implicitely by gs parent-child relation.
-invoke (For menuitem.)
- Only useful for explicit keyboard traversing of menues and
- that should not be controlled by the programmer.
-selectbg The color of the indicator can only be set at menu level.
diff --git a/lib/gs/doc/src/warning.gif b/lib/gs/doc/src/warning.gif
deleted file mode 100644
index 96af52360e..0000000000
--- a/lib/gs/doc/src/warning.gif
+++ /dev/null
Binary files differ
diff --git a/lib/gs/ebin/.gitignore b/lib/gs/ebin/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/gs/ebin/.gitignore
+++ /dev/null
diff --git a/lib/gs/examples/Makefile b/lib/gs/examples/Makefile
deleted file mode 100644
index 2612e67f88..0000000000
--- a/lib/gs/examples/Makefile
+++ /dev/null
@@ -1,96 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1996-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-#
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include ../vsn.mk
-VSN=$(GS_VSN)
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/gs-$(VSN)/examples
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-
-MODULES= \
- ball \
- browser \
- calc \
- calc2 \
- color_demo \
- color_demo2 \
- distrib_draw \
- entry_demo \
- event_test \
- file_dialog \
- focus_demo \
- frac \
- line_demo \
- man \
- menu_demo \
- rubber
-
-HRL_FILES=
-
-ERL_FILES= $(MODULES:%=%.erl)
-
-TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-ERL_COMPILE_FLAGS +=
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-debug opt: $(TARGET_FILES)
-
-docs:
-
-clean:
- rm -f $(TARGET_FILES)
- rm -f core
-
-# ----------------------------------------------------
-# Special Build Targets
-# ----------------------------------------------------
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-release_spec: opt
- $(INSTALL_DIR) "$(RELSYSDIR)/ebin"
- $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin"
- $(INSTALL_DIR) "$(RELSYSDIR)/src"
- $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/src"
-
-release_docs_spec:
diff --git a/lib/gs/examples/README b/lib/gs/examples/README
deleted file mode 100644
index 07c2bcb005..0000000000
--- a/lib/gs/examples/README
+++ /dev/null
@@ -1,24 +0,0 @@
-Purpose:
- Provide short example programs
-
-
-File Description
-------------------------------------------------------------------------
-ball.erl A bouncing ball in a window. Demonstrates canvas and oval.
-browser.erl How to program a listbox.
-calc.erl Simple calculator. The example shows how silly it is to always
- pass along object identifiers as arguments.
-calc2.erl Using the data field instead.
-color_demo.erl Shows hot to program scales.
-color_demo2.erl Using Motion events to select a color.
-distrib_draw.erl Simple drawing area shared by two nodes.
-entry_demo.erl How to use an entry object.
-event_test.erl Demonstration of events in gs.
-file_dialog.erl A complete(?) file browser using a listbox.
-focus_demo.erl A test for focus.
-frac.erl Joe's old pxw demo converted to gs.
-line_demo.erl A bouncing line in a canvas.
-man.erl A Manual page viewer.
-menu_demo.erl Menu Demo. How to create menues.
-rubber.erl Shows how to do rubberbanding (on a canvas) in Erlang.
-
diff --git a/lib/gs/examples/ball.erl b/lib/gs/examples/ball.erl
deleted file mode 100644
index c5d1e10db5..0000000000
--- a/lib/gs/examples/ball.erl
+++ /dev/null
@@ -1,78 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% A simple demo showing a ball
-%% bouncing in a window.
-%% ------------------------------------------------------------
-
--module(ball).
--compile([{nowarn_deprecated_function,{gs,button,2}},
- {nowarn_deprecated_function,{gs,canvas,2}},
- {nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,oval,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,2}}]).
-
--export([start/0,init/0]).
-
-start() ->
- spawn(ball,init,[]).
-
-init() ->
- I= gs:start(),
- W= gs:window(I,[{title,"Ball"},{width,300},{height,300},{map,true}]),
- C= gs:canvas(W,[{width,300},{height,300},{bg,yellow}]),
- gs:button(W,[{label, {text,"Quit Demo"}},{x,100}]),
- Ball = gs:oval(C,[{coords,[{0,0},{50,50}]},{fill,red}]),
- ball(Ball,0,0,5.5,4.1).
-
-ball(Ball,X,Y,DX,DY) ->
- {NX,NDX} = cc(X,DX),
- {NY,NDY} = cc(Y,DY),
- gs:config(Ball,{move,{DX,DY}}),
- receive
- {gs,_,click,_,_} -> exit(normal);
- {gs,_,destroy,_,_} -> exit(normal)
- after 20 ->
- true
- end,
- ball(Ball,NX,NY,NDX,NDY).
-
-cc(X,DX) ->
- if
- DX>0 ->
- if
- X=<250 ->
- {X+DX,DX};
- x>250 ->
- {X-DX,-DX}
- end;
- DX<0 ->
- if
- X>=0 ->
- {X+DX,DX};
- X<0 ->
- {X-DX,-DX}
- end
- end.
-
-%% ------------------------------------------------------------
diff --git a/lib/gs/examples/browser.erl b/lib/gs/examples/browser.erl
deleted file mode 100644
index 14aca11662..0000000000
--- a/lib/gs/examples/browser.erl
+++ /dev/null
@@ -1,98 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Simple Browser
-%% ------------------------------------------------------------
-
--module(browser).
--compile([{nowarn_deprecated_function,{gs,button,2}},
- {nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,entry,2}},
- {nowarn_deprecated_function,{gs,label,2}},
- {nowarn_deprecated_function,{gs,listbox,2}},
- {nowarn_deprecated_function,{gs,read,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,2}}]).
-
--export([start/0,start/2,init/3]).
-
-start() ->
- spawn(browser,init,[self(),text(),items()]),
- receive
- {browser,Result} -> Result
- end.
-
-text() -> "Pick an erlangian: ".
-
-items() ->
- lists:sort(["marcus","bjorn","anders","dalle","henrik","mk",
- "keisu","klas","patric","ola","torpvret","lelle",
- "eklas","mbj","janne","martin","kent","pippi",
- "gunilla","uwiger","macr"]).
-
-
-start(Text,Items) ->
- spawn(browser,init,[self(),Text,Items]),
- receive
- {browser,Result} -> Result
- end.
-
-init(Pid,Text,Items) ->
- S=gs:start(),
- Win=gs:window(S,[{width,250},{height,270},{title,"Browser"}]),
- gs:label(Win,[{label,{text,Text}},{width,250}]),
- Entry=gs:entry(Win,[{y,35},{width,240},{x,5},
- {keypress,true},{setfocus,true}]),
- Lb=gs:listbox(Win,[{x,5},{y,65},{width,160},{height,195},
- {vscroll,right},{click,true},{doubleclick,true}]),
- Ok=gs:button(Win,[{label,{text,"OK"}},{width,40},{x,185},{y,175}]),
- Cancel=gs:button(Win,[{label,{text,"Cancel"}},{x,175},{y,225},{width,65}]),
- gs:config(Lb,[{items,Items}]),
- gs:config(Win,{map,true}),
- browser_loop(Pid,Ok,Cancel,Entry,Lb).
-
-browser_loop(Pid,Ok,Cancel,Entry,Lb) ->
- receive
- {gs,Ok,click,_,_} ->
- Txt=gs:read(Entry,text),
- Pid ! {browser,{ok,Txt}};
- {gs,Cancel,click,_,_} ->
- Pid ! {browser,cancel};
- {gs,Entry,keypress,_,['Return'|_]} ->
- Txt=gs:read(Entry,text),
- Pid ! {browser,{ok,Txt}};
- {gs,Entry,keypress,_,_} ->
- browser_loop(Pid,Ok,Cancel,Entry,Lb);
- {gs,Lb,click,_,[_Idx, Txt|_]} ->
- gs:config(Entry,{text,Txt}),
- browser_loop(Pid,Ok,Cancel,Entry,Lb);
- {gs,Lb,doubleclick,_,[_Idx, Txt|_]} ->
- Pid ! {browser,{ok,Txt}};
- {gs,_,destroy,_,_} ->
- Pid ! {browser,cancel};
- X ->
- io:format("Got X=~w~n",[X]),
- browser_loop(Pid,Ok,Cancel,Entry,Lb)
- end.
-
-%% ------------------------------------------------------------
-%% end of browser.erl
diff --git a/lib/gs/examples/calc.erl b/lib/gs/examples/calc.erl
deleted file mode 100644
index 6a58475f13..0000000000
--- a/lib/gs/examples/calc.erl
+++ /dev/null
@@ -1,114 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% A Simple Calculator demo in Erlang
-%% ------------------------------------------------------------
-
--module(calc).
--compile([{nowarn_deprecated_function,{gs,button,2}},
- {nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,label,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,2}}]).
-
--export([start/0,calc/0]).
-
-start() ->
- spawn(calc,calc,[]).
-
-calc() ->
- I = gs:start(),
- Win = gs:window(I,[{title,"Calc1"},{width,120},{height,150}]),
- Label = gs:label(Win,[{label,{text,"0"}},{width,120}]),
- B1 = gs:button(Win,[{label,{text,"1"}},{width,30},{x,0},{y,30}]),
- B2 = gs:button(Win,[{label,{text,"2"}},{width,30},{x,30},{y,30}]),
- B3 = gs:button(Win,[{label,{text,"3"}},{width,30},{x,60},{y,30}]),
- B4 = gs:button(Win,[{label,{text,"4"}},{width,30},{x,0},{y,60}]),
- B5 = gs:button(Win,[{label,{text,"5"}},{width,30},{x,30},{y,60}]),
- B6 = gs:button(Win,[{label,{text,"6"}},{width,30},{x,60},{y,60}]),
- B7 = gs:button(Win,[{label,{text,"7"}},{width,30},{x,0},{y,90}]),
- B8 = gs:button(Win,[{label,{text,"8"}},{width,30},{x,30},{y,90}]),
- B9 = gs:button(Win,[{label,{text,"9"}},{width,30},{x,60},{y,90}]),
- B0 = gs:button(Win,[{label,{text,"0"}},{width,60},{x,0},{y,120}]),
- C = gs:button(Win,[{label,{text,"C"}},{width,30},{x,60},{y,120}]),
- AC = gs:button(Win,[{label,{text,"AC"}},{width,30},{x,90},{y,120},{fg,red}]),
- Plus = gs:button(Win,[{label,{text,"+"}},{width,30},{x,90},{y,30}]),
- Times = gs:button(Win,[{label,{text,"*"}},{width,30},{x,90},{y,60}]),
- Minus = gs:button(Win,[{label,{text,"-"}},{width,30},{x,90},{y,90}]),
- gs:config(Win,{map,true}),
- Ids = [Label,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,Minus,Plus,Times,C,AC],
- calc_loop(Ids,0,0,'+').
-
-calc_loop(Ids,M,V,Op) ->
- [_Label,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,Minus,Plus,Times,C,AC] = Ids,
- receive
- {gs,B0,click,_,_} -> digit_press(Ids,M,V*10+0,Op);
- {gs,B1,click,_,_} -> digit_press(Ids,M,V*10+1,Op);
- {gs,B2,click,_,_} -> digit_press(Ids,M,V*10+2,Op);
- {gs,B3,click,_,_} -> digit_press(Ids,M,V*10+3,Op);
- {gs,B4,click,_,_} -> digit_press(Ids,M,V*10+4,Op);
- {gs,B5,click,_,_} -> digit_press(Ids,M,V*10+5,Op);
- {gs,B6,click,_,_} -> digit_press(Ids,M,V*10+6,Op);
- {gs,B7,click,_,_} -> digit_press(Ids,M,V*10+7,Op);
- {gs,B8,click,_,_} -> digit_press(Ids,M,V*10+8,Op);
- {gs,B9,click,_,_} -> digit_press(Ids,M,V*10+9,Op);
- {gs,Minus,click,_,_} -> calc(Ids,Op,M,V,'-');
- {gs,Plus,click,_,_} -> calc(Ids,Op,M,V,'+');
- {gs,Times,click,_,_} -> calc(Ids,Op,M,V,'*');
- {gs,AC,click,_,_} -> ac(Ids,M,V,Op);
- {gs,C,click,_,_} -> c(Ids,M,V,Op);
- {gs,_,destroy,_,_} -> exit(normal);
- _Other -> calc_loop(Ids,M,V,Op)
- end.
-
-digit_press(Ids,M,V,Op) ->
- [Label|_]=Ids,
- gs:config(Label,[{label,{text,V}}]),
- calc_loop(Ids,M,V,Op).
-
-calc(Ids,'+',M,V,Op) ->
- NewM = M + V,
- [Label|_]=Ids,
- gs:config(Label,[{label,{text,NewM}}]),
- calc_loop(Ids,NewM,0,Op);
-calc(Ids,'-',M,V,Op) ->
- NewM = M - V,
- [Label|_]=Ids,
- gs:config(Label,[{label,{text,NewM}}]),
- calc_loop(Ids,NewM,0,Op);
-calc(Ids,'*',M,V,Op) ->
- NewM = M * V,
- [Label|_]=Ids,
- gs:config(Label,[{label,{text,NewM}}]),
- calc_loop(Ids,NewM,0,Op).
-
-c(Ids,M,_V,Op) ->
- [Label|_]=Ids,
- gs:config(Label,[{label,{text,0}}]),
- calc_loop(Ids,M,0,Op).
-
-ac(Ids,_M,_V,_Op) ->
- [Label|_]=Ids,
- gs:config(Label,[{label,{text,0}}]),
- calc_loop(Ids,0,0,'+').
-
-%% ------------------------------------------------------------
diff --git a/lib/gs/examples/calc2.erl b/lib/gs/examples/calc2.erl
deleted file mode 100644
index bf9f9b7bbd..0000000000
--- a/lib/gs/examples/calc2.erl
+++ /dev/null
@@ -1,103 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% A Simple Calculator demo in Erlang
-%% Describes how to match against the data field.
-%% ------------------------------------------------------------
-
--module(calc2).
--compile([{nowarn_deprecated_function,{gs,button,2}},
- {nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,label,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,2}}]).
-
--export([start/0,calc/0]).
-
-start() ->
- spawn(calc2,calc,[]).
-
-calc() ->
- I = gs:start(),
- Win = gs:window(I,[{title,"Calc2"},{width,120},{height,150}]),
- Lbl = gs:label(Win,[{label,{text,"0"}},{width,120}]),
- gs:button(Win,[{label,{text,"1"}},{width,30},{x,0},{y,30},{data,1}]),
- gs:button(Win,[{label,{text,"2"}},{width,30},{x,30},{y,30},{data,2}]),
- gs:button(Win,[{label,{text,"3"}},{width,30},{x,60},{y,30},{data,3}]),
- gs:button(Win,[{label,{text,"4"}},{width,30},{x,0},{y,60},{data,4}]),
- gs:button(Win,[{label,{text,"5"}},{width,30},{x,30},{y,60},{data,5}]),
- gs:button(Win,[{label,{text,"6"}},{width,30},{x,60},{y,60},{data,6}]),
- gs:button(Win,[{label,{text,"7"}},{width,30},{x,0},{y,90},{data,7}]),
- gs:button(Win,[{label,{text,"8"}},{width,30},{x,30},{y,90},{data,8}]),
- gs:button(Win,[{label,{text,"9"}},{width,30},{x,60},{y,90},{data,9}]),
- gs:button(Win,[{label,{text,"0"}},{width,60},{x,0},{y,120},{data,0}]),
- gs:button(Win,[{label,{text,"C"}},{width,30},{x,60},{y,120},{data,'C'}]),
- gs:button(Win,[{label,{text,"AC"}},{width,30},{x,90},{y,120},{data,'AC'},
- {fg,red}]),
- gs:button(Win,[{label,{text,"+"}},{width,30},{x,90},{y,30},{data,'+'}]),
- gs:button(Win,[{label,{text,"*"}},{width,30},{x,90},{y,60},{data,'*'}]),
- gs:button(Win,[{label,{text,"-"}},{width,30},{x,90},{y,90},{data,'-'}]),
- gs:config(Win,{map,true}),
- calc_loop(Lbl,0,0,'+').
-
-calc_loop(Lbl,M,V,Op) ->
- receive
- {gs,_,click,D,_} when is_integer(D) ->
- digit_press(Lbl,M,V*10+D,Op);
- {gs,_,click,'C',_} ->
- c(Lbl,M,V,Op);
- {gs,_,click,'AC',_} ->
- ac(Lbl,M,V,Op);
- {gs,_,click,NewOp,_} ->
- calc(Lbl,Op,M,V,NewOp);
- {gs,_,destroy,_,_} ->
- exit(normal);
- _Other ->
- calc_loop(Lbl,M,V,Op)
- end.
-
-digit_press(Lbl,M,V,Op) ->
- gs:config(Lbl,[{label,{text,V}}]),
- calc_loop(Lbl,M,V,Op).
-
-calc(Lbl,'+',M,V,Op) ->
- NewM = M + V,
- gs:config(Lbl,[{label,{text,NewM}}]),
- calc_loop(Lbl,NewM,0,Op);
-calc(Lbl,'-',M,V,Op) ->
- NewM = M - V,
- gs:config(Lbl,[{label,{text,NewM}}]),
- calc_loop(Lbl,NewM,0,Op);
-calc(Lbl,'*',M,V,Op) ->
- NewM = M * V,
- gs:config(Lbl,[{label,{text,NewM}}]),
- calc_loop(Lbl,NewM,0,Op).
-
-c(Lbl,M,_V,Op) ->
- gs:config(Lbl,[{label,{text,0}}]),
- calc_loop(Lbl,M,0,Op).
-
-ac(Lbl,_M,_V,_Op) ->
- gs:config(Lbl,[{label,{text,0}}]),
- calc_loop(Lbl,0,0,'+').
-
-%% ------------------------------------------------------------
diff --git a/lib/gs/examples/color_demo.erl b/lib/gs/examples/color_demo.erl
deleted file mode 100644
index 5d2170a394..0000000000
--- a/lib/gs/examples/color_demo.erl
+++ /dev/null
@@ -1,68 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% A simple demo for choosing
-%% colors in a window.
-%% ------------------------------------------------------------
-
--module(color_demo).
--compile([{nowarn_deprecated_function,{gs,button,2}},
- {nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,scale,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,2}}]).
-
--export([start/0,init/0]).
-
-start() ->
- spawn(color_demo,init,[]).
-
-init() ->
- I= gs:start(),
- W= gs:window(I,[{title,"Color Demo"},{width,300},{height,195}]),
- B=gs:button(W,[{label,{text,"Quit"}},{x,261},{y,166},{width,40}]),
- gs:config(B,[{bg,yellow},{fg,hotpink1},{data,quit}]),
- gs:scale(W,[{text,"Red"},{y,0},{range,{0,255}},{orient,horizontal},
- {height,65},{data,red},{pos,42}]),
- gs:scale(W,[{text,"Blue"},{y,65},{range,{0,255}},{orient,horizontal},
- {height,65},{data,blue},{pos,42}]),
- gs:scale(W,[{text,"Green"},{y,130},{range,{0,255}},{orient,horizontal},
- {height,65},{data,green},{pos,42}]),
- gs:config(W,{map,true}),
- loop(W,0,0,0).
-
-loop(W,R,G,B) ->
- gs:config(W,{bg,{R,G,B}}),
- receive
- {gs,_,click,red,[New_R|_]} ->
- loop(W,New_R,G,B);
- {gs,_,click,green,[New_G|_]} ->
- loop(W,R,New_G,B);
- {gs,_,click,blue,[New_B|_]} ->
- loop(W,R,G,New_B);
- {gs,_,click,quit,_} ->
- true;
- {gs,W,destroy,_,_} ->
- true
- end.
-
-%% ------------------------------------------------------------
diff --git a/lib/gs/examples/color_demo2.erl b/lib/gs/examples/color_demo2.erl
deleted file mode 100644
index 3e0115c831..0000000000
--- a/lib/gs/examples/color_demo2.erl
+++ /dev/null
@@ -1,113 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Another simple demo for choosing
-%% colors in a window.
-%% ------------------------------------------------------------
-
--module(color_demo2).
--compile([{nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,create,3}},
- {nowarn_deprecated_function,{gs,create,4}},
- {nowarn_deprecated_function,{gs,start,0}}]).
-
--export([start/0,init/0]).
-
-start() ->
- spawn(color_demo2,init,[]).
-
-
-init() ->
- S=gs:start(),
- Win = gs:create(window,S,[{width,380},{height,430},{motion,true},
- {buttonpress,true}]),
- gs:create(button,b1,Win,[{x,200},{label,{text,""}}]),
- gs:create(button,Win,[{data,quit},{label,{text,"Quit"}},{bg,yellow},
- {width,40}]),
- Side = 200,
- Tri = equi_tri(100, 400, Side),
- %% draw_lines(Win, Tri),
- gs:config(Win,[{title,"Color Demo 2"},{map,true}]),
- server(Win, Side, Tri, {0,0,0}).
-
-server(Win, Side, [Point1, Point2, Point3], OldCol) ->
- receive
- {gs,Win,motion,_,[X,Y|_]} ->
- R = col({X,Y}, Point1, Side),
- G = col({X,Y}, Point2, Side),
- B = col({X,Y}, Point3, Side),
- Txt = lists:flatten(io_lib:format("~w ~w ~w",[R,G,B])),
- gs:config(b1,[{label,{text,Txt}}]),
- Col = {R, G, B},
- gs:config(Win, [{bg,Col}]),
- server(Win, Side, [Point1, Point2, Point3], Col);
- {gs,Win,buttonpress,_,[_X,_Y|_]} ->
- io:format("{color, ~w}\n", [OldCol]),
- server(Win, Side, [Point1, Point2, Point3], OldCol);
- {gs,_,click,quit,_} ->
- exit(die);
- {gs,Win,destroy,_,_} ->
- exit(die);
- _Any ->
- server(Win, Side, [Point1, Point2, Point3], OldCol)
- end.
-
-
-col(Point1, Point2, Side) ->
- D = dist(Point1, Point2),
- %% All FFFFFF is white
- %% when Col = 255 when D = Side
- %% when Col = 0 when D = 0
- %% Assume Col = A * D + B
- B = 0,
- A = (255 - B)/Side,
- Col = trunc(A*D + B),
- map(Col).
-
-map(X) ->
- X band 255.
-
-equi_tri(X1, Y1, L) ->
- X2 = trunc(X1 + L/2),
- Y2 = trunc(Y1 - L * math:sqrt(3)),
- [{X1,Y1},{X2,Y2},{X1+L,Y1}].
-
-%draw_line(Win, {X1, Y1}, {X2, Y2}) ->
-% gs:create(line,Win,[{coords,[{X1,Y1},{X2,Y2}]},{width,2}]).
-
-%draw_lines(Win, L) ->
-% draw1(Win, L),
-% draw_line(Win, hd(L), lists:last(L)).
-
-%draw1(Win, [X,Y|T]) ->
-% draw_line(Win, X, Y),
-% draw1(Win, [Y|T]);
-%draw1(Win, _) ->
-% [].
-
-dist({X1,Y1},{X2,Y2}) ->
- XX = X1 - X2,
- YY = Y1 - Y2,
- math:sqrt(XX*XX+YY*YY).
-
-%% ------------------------------------------------------------
-%% end of color_demo2.erl
diff --git a/lib/gs/examples/distrib_draw.erl b/lib/gs/examples/distrib_draw.erl
deleted file mode 100644
index f704e2479e..0000000000
--- a/lib/gs/examples/distrib_draw.erl
+++ /dev/null
@@ -1,122 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% distrib_draw
-%% Shows one way of making two nodes draw on the same
-%% area.
-%%
-%% ------------------------------------------------------------
-
-%% HOW TO USE:
-%% 1) start up two nodes with same cookie.
-%% They can be on any machines.
-%%
-%% sid.ericsson.se> erl -cookie kaka -name hans
-%%
-%% ozzy.ericsson.se> erl -cookie kaka -name greta
-%%
-%%
-%% 2) Make them aware of each other.
-%%
-%% 3) Start up distrib_draw from either node.
-%%
-
--module(distrib_draw).
--compile([{nowarn_deprecated_function,{gs,canvas,3}},
- {nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,line,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,3}}]).
-
--export([start/2,init/0]).
-
-start(Node1,Node2) ->
- Pid1=spawn(Node1,distrib_draw,init,[]),
- Pid2=spawn(Node2,distrib_draw,init,[]),
- Pid1 ! {connect,red,Pid2},
- Pid2 ! {connect,green,Pid1}.
-
-init() ->
- process_flag(trap_exit,true),
- S=gs:start(),
- receive
- {connect,Color,Pid} ->
- link(Pid),
- gs:window(win,S,[{buttonpress,true},{buttonrelease,true},
- {configure,true},{title,Color},{map,true}]),
- gs:canvas(canvas,win,[{bg,grey},{width,300},{height,200}]),
- draw0(0,0,Color,Pid)
- after
- 3000 -> exit(timeout)
- end.
-
-%% not drawing state
-draw0(X0,Y0,Color,Pid) ->
- receive
- {gs,_,buttonpress,_,[1,X,Y|_]} ->
- gs:config(win,{motion,true}),
- draw1(X,Y,Color,Pid);
- {draw,Coords,Col2} ->
- gs:line(canvas,[{coords,Coords},{width,2},{fg,Col2}]),
- draw0(X0,Y0,Color,Pid);
- {gs,_,configure,_,[300,200|_]} ->
- draw0(X0,Y0,Color,Pid);
- {gs,_,configure,_,_} ->
- gs:config(win,[{width,300},{height,200}]),
- draw0(X0,Y0,Color,Pid);
- {gs,_,destroy,_,_} ->
- exit(normal);
- {'EXIT',_,_} ->
- exit(normal);
- _X -> draw1(X0,Y0,Color,Pid)
- end.
-
-%% i'm now drawing
-draw1(X0,Y0,Color,Pid) ->
- receive
- {gs,_,motion,_,[X,Y|_]} ->
- Pid ! {draw,[{X0,Y0},{X,Y}],Color},
- gs:line(canvas,[{coords,[{X0,Y0},{X,Y}]},{width,2},{fg,Color}]),
- draw1(X,Y,Color,Pid);
- {draw,Coords,Col2} ->
- gs:line(canvas,[{coords,Coords},{width,2},{fg,Col2}]),
- draw1(X0,Y0,Color,Pid);
- {gs,_,buttonrelease,_,[1,X,Y|_]} ->
- gs:config(win,{motion,false}),
- draw0(X,Y,Color,Pid);
- {gs,_,configure,_,[300,200|_]} ->
- draw0(X0,Y0,Color,Pid);
- {gs,_,configure,_,_} ->
- gs:config(win,[{width,300},{height,200}]),
- draw0(X0,Y0,Color,Pid);
- {gs,_,destroy,_,_} ->
- exit(normal);
- {'EXIT',_,_} ->
- exit(normal);
- _X -> draw1(X0,Y0,Color,Pid)
- end.
-
-%% ------------------------------------------------------------
-%% end of 'distrib_draw'
diff --git a/lib/gs/examples/entry_demo.erl b/lib/gs/examples/entry_demo.erl
deleted file mode 100644
index f37780f352..0000000000
--- a/lib/gs/examples/entry_demo.erl
+++ /dev/null
@@ -1,70 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Entry Demo
-%% ------------------------------------------------------------
-
--module(entry_demo).
--compile([{nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,create,3}},
- {nowarn_deprecated_function,{gs,create,4}},
- {nowarn_deprecated_function,{gs,read,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,2}}]).
-
--export([start/0,init/1]).
-
-start() ->
- spawn(entry_demo,init,[self()]),
- receive
- {entry_reply,Reply} -> Reply
- end.
-
-init(Pid) ->
- S=gs:start(),
- Win=gs:window(S,[{title,"Entry Demo"},{width,150},{height,100}]),
- gs:create(label,Win,[{width,150},{label,{text,"What's your name?"}}]),
- gs:create(entry,entry,Win,[{x,10},{y,30},{width,130},{keypress,true}]),
- gs:create(button,ok,Win,[{width,45},{y,60},{x,10},{label,{text,"Ok"}}]),
- gs:create(button,cancel,Win,[{width,60},{y,60},{x,80},{label,{text,"Cancel"}}]),
- gs:config(Win,{map,true}),
- loop(Pid).
-
-loop(Pid) ->
- receive
- {gs,entry,keypress,_,['Return'|_]} ->
- Text=gs:read(entry,text),
- Pid ! {entry_reply,{name,Text}};
- {gs,entry,keypress,_,_} ->
- loop(Pid);
- {gs,ok,click,_,_} ->
- Text=gs:read(entry,text),
- Pid ! {entry_reply,{name,Text}};
- {gs,cancel,click,_,_} ->
- Pid ! {entry_reply,cancel};
- X ->
- io:format("Got X=~w~n",[X]),
- loop(Pid)
- end.
-
-%% ----------------------------------------
-%% done
diff --git a/lib/gs/examples/event_test.erl b/lib/gs/examples/event_test.erl
deleted file mode 100644
index ff2029ca01..0000000000
--- a/lib/gs/examples/event_test.erl
+++ /dev/null
@@ -1,52 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% Demo for testing some events
-
--module(event_test).
--compile([{nowarn_deprecated_function,{gs,button,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,2}}]).
-
--export([start/0,init/0]).
-
-
-
-start() ->
- spawn(event_test,init,[]).
-
-init() ->
- S=gs:start(),
- W=gs:window(S,[{map,true},{keypress,true},{buttonpress,true}]),
- gs:button(W,[{label,{text,"Press Me"}},{enter,true},{leave,true}]),
- event_loop().
-
-
-event_loop() ->
- receive
- X ->
- io:format("Got event: ~p~n",[X]),
- event_loop()
- end.
-
-
-
-
diff --git a/lib/gs/examples/file_dialog.erl b/lib/gs/examples/file_dialog.erl
deleted file mode 100644
index 1dffc5b009..0000000000
--- a/lib/gs/examples/file_dialog.erl
+++ /dev/null
@@ -1,261 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% File Selection Dialog
-%% ------------------------------------------------------------
-
--module(file_dialog).
--compile([{nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,create,4}},
- {nowarn_deprecated_function,{gs,label,2}},
- {nowarn_deprecated_function,{gs,read,2}},
- {nowarn_deprecated_function,{gs,start,0}}]).
-
--export([start/0,start/1,start/2,fs_init/3]).
-
--include_lib("kernel/include/file.hrl").
-
-
-%% ----- File Selection ----
-start() ->
- {ok,Dir}=file:get_cwd(),
- start(Dir,[]).
-
-start(Dir) ->
- start(Dir,[]).
-
-start(Dir,File) ->
- Dir0 = case lists:last(Dir) of
- $/ -> Dir;
- _ -> lists:append(Dir,"/")
- end,
- Pid=spawn(file_dialog,fs_init,[Dir0,File,self()]),
- receive
- {file_dialog,Pid,Result} -> Result
- end.
-
-
-%% ------------------------------------------------------------
-fs_init(Dir,File,Owner) ->
- S=gs:start(),
- gs:create(window,win,S,[{width,250},{height,265},{title,"File Dialog"},
- {configure,true}]),
- gs:create(label,label,win,[{y,0},{width,250},{label, {text,Dir}}]),
- gs:label(win,[{width,50},{y,30},{x,5},{label, {text,"File:"}}]),
- gs:create(entry,entry,win,[{y,30},{width,190},{x,55},
- {keypress,true},{focus,true}]),
- gs:create(listbox,lb,win,[{x,5},{y,60},{width,160},{height,199},
- {vscroll,right},{click,true},{doubleclick,true}]),
- gs:create(button,ok,win,[{label, {text,"OK"}},{width,40},{x,185},{y,170}]),
- gs:create(button,cancel,win,[{label, {text,"Cancel"}},{x,175},{y,220},{width,65}]),
- Items=refresh(Dir),
- %% --- select File if it's given ---
- case index_member(File,Items) of
- {ok,Index} ->
- gs:config(lb,{selection,clear}),
- gs:config(lb,{selection,Index});
- _ -> true
- end,
- gs:config(win,{map,true}),
- fs_loop(Dir,Owner).
-
-fs_loop(Dir,Owner) ->
- receive
- {gs,ok,click,_,_} ->
- entered_name(Dir,Owner);
- {gs,cancel,click,_,_} ->
- Owner ! {file_dialog,self(),cancel};
- {gs,entry,keypress,_,['Return'|_]} ->
- entered_name(Dir,Owner);
- {gs,entry,keypress,_,[_Keysym|_]} ->
- fs_loop(Dir,Owner);
- {gs,lb,click,_,_} ->
- clicked(Dir,Owner);
- {gs,lb,doubleclick,_,_} ->
- double_clicked(Dir,Owner);
- {gs,win,configure,_,[250,265|_]} -> % already got that size
- fs_loop(Dir,Owner);
- {gs,win,configure,_,_} ->
- gs:config(win,[{geometry,{250,265}}]),
- fs_loop(Dir,Owner);
- stop ->
- exit(normal);
- {gs,_,destroy,_,_} ->
- Owner ! {file_dialog,self(),cancel};
- X ->
- io:format("file_dialog: got other: ~w.~n",[X]),
- fs_loop(Dir,Owner)
- end.
-
-
-
-refresh(Dir) ->
- gs:config(lb,clear),
- gs:config(label,{label, {text,Dir}}),
- gs:config(entry,{text,""}),
- Items=["../"|get_files(Dir)],
- gs:config(lb,[{items,Items}]),
- Items.
-
-
-entered_name(Dir,Owner) ->
- File=gs:read(entry,text),
- case check_file(Dir,File) of
- {file,Dir2,File2} ->
- Owner ! {file_dialog,self(),{ok,Dir2,File2}};
- {dir,Dir2} ->
- refresh(Dir2),
- fs_loop(Dir2,Owner);
- {error,no_file} ->
- double_clicked(Dir,Owner);
- _ ->
- fs_loop(Dir,Owner)
- end.
-
-
-clicked(Dir,Owner) ->
- [Idx|_]=gs:read(lb,selection),
- File=gs:read(lb,{get,Idx}),
- case lists:last(File) of
- $/ -> %it's a dir
- true;
- _ -> % it's a file
- gs:config(entry,{text,File})
- end,
- fs_loop(Dir,Owner).
-
-
-double_clicked(Dir,Owner) ->
- case gs:read(lb,selection) of
- [0] -> % up one dir
- NewDir=up_one_dir(Dir),
- refresh(NewDir),
- fs_loop(NewDir,Owner);
- [] ->
- fs_loop(Dir,Owner);
- [Idx] ->
- File=gs:read(lb,{get,Idx}),
- case lists:last(File) of
- $/ -> % down a dir
- NewDir=lists:append(Dir,File),
- refresh(NewDir),
- fs_loop(NewDir,Owner);
- _ -> % done
- Owner!{file_dialog,self(),{ok,Dir,File}}
- end
- end.
-
-
-%% checks if a file exists
-%% returns {file,Dir,File}
-%% {dir,Dir}
-%% or {error,What}
-check_file(Dir,File) ->
- case catch lists:last(File) of
- $/ -> % File is a Dir
- NewDir = case File of
- [$/|_] -> %absolute path
- File;
- _ -> %relative path
- lists:append(Dir,File)
- end,
- case file:list_dir(NewDir) of
- {ok,_} -> {dir,NewDir};
- _ -> {error,bad_dir}
- end;
- {'EXIT',_Why} -> {error,no_file};
- _ ->
- Words=string:tokens(File,[$/,$\\]),
- NewFile=lists:last(Words),
- NewDir = case File of
- [$/|_] -> %absolute path
- up_one_dir(File);
- _ -> %relative path
- case up_one_dir(File) of
- [$/] -> Dir;
- [$/|SubDir] -> lists:flatten([Dir,SubDir,$/])
- end
- end,
- case file:read_file_info(lists:append(NewDir,NewFile)) of
- {ok,_} ->
- {file,NewDir,NewFile};
- _ ->
- {error,bad_file}
- end
- end.
-
-
-get_files(Dir) ->
- {ok,Files} = file:list_dir(Dir),
- add_slash(Dir,lists:sort(Files)).
-
-add_slash(_,[]) -> [];
-add_slash(Dir,[H|T]) ->
- case file:read_file_info(lists:append(Dir,[$/|H])) of
- {ok,FI} when FI#file_info.type==directory ->
- [lists:append(H,"/")|add_slash(Dir,T)];
- _ ->
- [H|add_slash(Dir,T)]
- end.
-
-
-%filter([H|T]) ->
-% case lists:last(H) of
-% $/ -> [H|filter(T)];
-% _ ->
-% Len =length(H),
-% if Len>4 ->
-% case lists:nthtail(Len-4,H) of
-% ".erl" -> [H|filter(T)];
-% _ -> filter(T)
-% end;
-% true -> filter(T)
-% end
-% end;
-%filter([]) ->
-% [].
-
-
-%% like member but also returns index
-index_member(Item,List) ->
- i_m(0,Item,List).
-
-i_m(N,Item,[Item|_List]) ->
- {ok,N};
-i_m(N,Item,[_|List]) ->
- i_m(N+1,Item,List);
-i_m(_N,_Item,[]) ->
- false.
-
-up_one_dir(Dir) ->
- L =string:tokens(Dir,[$/,$\\]),
- lists:flatten(rem_last(L)).
-
-rem_last([_Last]) ->
- [$/];
-rem_last([Head|Tail]) ->
- [$/,Head|rem_last(Tail)];
-rem_last([]) ->
- [$/].
-
-%% ----------------------------------------
-%% done
diff --git a/lib/gs/examples/focus_demo.erl b/lib/gs/examples/focus_demo.erl
deleted file mode 100644
index 1a69241a38..0000000000
--- a/lib/gs/examples/focus_demo.erl
+++ /dev/null
@@ -1,103 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Focus Demo
-%% ------------------------------------------------------------
-
--module(focus_demo).
--compile([{nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,create,4}},
- {nowarn_deprecated_function,{gs,read,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,2}}]).
-
--export([start/0,init/0]).
-
-
-%% ----- File Selection ----
-start() ->
- spawn(focus_demo,init,[]).
-
-
-init() ->
- S=gs:start(),
- Font = case gs:read(S,{choose_font,{screen,12}}) of
- {screen,_,12} = Screen ->
- Screen;
- _ ->
- gs:read(S,{choose_font,{courier,12}})
- end,
- Win=gs:window(S,[{title,"Focus Demo"},{width,200},{height,150}]),
- gs:create(entry,e1,Win,[{y,0},{focus,true}]),
- gs:create(entry,e2,Win,[{y,30},{focus,true}]),
- gs:create(entry,e3,Win,[{y,60},{focus,true}]),
- gs:create(entry,e4,Win,[{y,90},{focus,true}]),
- gs:create(button,b1,Win,[{x,100},{width,30},
- {label,{text,"e1"}},{font,Font}]),
- gs:create(button,b2,Win,[{y,30},{x,100},{width,30},
- {label,{text,"e2"}},{font,Font}]),
- gs:create(button,b3,Win,[{y,60},{x,100},{width,30},
- {label,{text,"e3"}},{font,Font}]),
- gs:create(button,b4,Win,[{y,90},{x,100},{width,30},
- {label,{text,"e4"}},{font,Font}]),
- gs:create(button,clear,Win,[{y,120},{x,35},{width,50},
- {label,{text,"Clear"}},{font,Font}]),
- gs:create(button,ask,Win,[{y,120},{x,85},{width,30},
- {label,{text,"?"}},{font,Font}]),
- gs:create(button,quit,Win,[{y,120},{x,115},{width,50},
- {label,{text,"Quit"}},{font,Font}]),
- gs:config(Win,{map,true}),
- loop().
-
-loop() ->
- receive
- {gs,quit,_,_,_} -> exit(normal);
- {gs,ask,_,_,_} ->
- R1=gs:read(e1,setfocus),R2=gs:read(e2,setfocus),
- R3=gs:read(e3,setfocus),R4=gs:read(e4,setfocus),
- R= if R1==true -> e1;
- R2==true -> e2;
- R3==true -> e3;
- R4==true -> e4;
- true -> nobody
- end,
- io:format("Focus status: ~w has focus.~n",[R]);
- {gs,clear,_,_,_} ->
- gs:config(clear,{setfocus,true}),
- io:format("Focus is cleared.~n",[]);
- {gs,b1,_,_,_} -> gs:config(e1,{setfocus,true});
- {gs,b2,_,_,_} -> gs:config(e2,{setfocus,true});
- {gs,b3,_,_,_} -> gs:config(e3,{setfocus,true});
- {gs,b4,_,_,_} -> gs:config(e4,{setfocus,true});
- {gs,Id,focus,_,[0|_]} ->
- io:format("~w lost focus.~n",[Id]);
- {gs,Id,focus,_,[1|_]} ->
- io:format("~w gained focus.~n",[Id]);
- {gs,_,destroy,_,_} ->
- exit(normal);
- X ->
- io:format("Got X=~w~n",[X])
- end,
- loop().
-
-%% ----------------------------------------
-%% done
diff --git a/lib/gs/examples/frac.erl b/lib/gs/examples/frac.erl
deleted file mode 100644
index 33d25d34ec..0000000000
--- a/lib/gs/examples/frac.erl
+++ /dev/null
@@ -1,158 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% Purpose : Fractal trees
-
--module(frac).
--compile([{nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,create,3}},
- {nowarn_deprecated_function,{gs,start,0}}]).
-
--export([start/0, go/0, test/0, grow/2, expand/3, subst/2]).
-
-%% 0L - grammer -- context insensitive lindenmayer grammer
-
-start() ->
- spawn(frac,go,[]).
-
-go() ->
- draw(),
- receive
- _X -> true
- end.
-
-draw() ->
- S=gs:start(),
- Width = 800,
- Ht = 520,
- Title="Context Insensitive Lindenmayer Grammer (L0) Trees",
- Win=gs:create(window,S,[{title,Title},{width,Width},{height,Ht}]),
- Canvas=gs:create(canvas,Win,[{width,Width},{height,Ht},{bg,{237,224,189}}]),
- gs:config(Win,[{iconname,"Plants"},{map,true}]),
- draw(Canvas, 1, Width, Ht),
- draw(Canvas, 2, Width, Ht),
- draw(Canvas, 3, Width, Ht),
- draw(Canvas, 4, Width, Ht).
-
-draw(Graph, Index, Width, Ht) ->
- draw_frac(Graph, Index, Width, Ht).
-
-test() ->
- grow(3,1).
-
-grow(NGens, RuleNumber) ->
- lists:flatten(expand(NGens, RuleNumber, [a])).
-
-rule(1,a) -> [b,'[',a,']',b,'(',a,')',a];
-rule(1,b) -> [b,b];
-
-rule(2,a) -> [b,'[',a,'[',b,a,']',']'];
-rule(2,b) -> [b,'(','(',b,')',a,')',c];
-rule(2,c) -> [c,d];
-
-rule(3,a) -> [d,'[',d,b,e,']','(',d,c,e,')'];
-rule(3,b) -> [d,'[',d,a,f,']','(',d,c,f,')',f];
-rule(3,c) -> [d,'[',d,b,g,']','(',d,a,g,')',g];
-
-rule(4,a) -> [c,'(',b,a,'(',b,')',')',c,'[',b,a,'[',b,']',']'];
-rule(4,b) -> [c,'(',b,e,')',c,'[',b,f,']'];
-rule(4,c) -> [g,c,c];
-
-rule(_,X) -> X.
-
-
-step(a) -> 1.0;
-step(b) -> 0.8;
-step(c) -> 0.6;
-step(d) -> 0.7;
-step(e) -> 0.6;
-step(f) -> 0.65;
-step(g) -> 0.75;
-step(_) -> 1.0.
-
-start_coords(1) -> {0.8,0.8};
-start_coords(2) -> {0.6,0.8};
-start_coords(3) -> {0.4,0.8};
-start_coords(4) -> {0.2,0.8};
-start_coords(_) -> {0.5, 0.5}.
-
-gens(1) -> 5;
-gens(_) -> 5.
-
-scale(1) -> 5;
-scale(2) -> 40;
-scale(3) -> 40;
-scale(4) -> 4;
-scale(_) -> 5.
-
-expand(0,_,X) ->
- X;
-expand(N,Index,X) ->
- expand(N - 1, Index, lists:flatten(subst(X, Index))).
-
-
-subst([],_) -> [];
-subst([H|T],Index) ->
- [rule(Index,H)|subst(T,Index)].
-
-
-draw_frac(Id, Index, Width, Ht) ->
- X0 = 100,
- Y0 = 100,
- {XScale,YScale} = start_coords(Index),
- Xstart = trunc(X0 + Width*XScale),
- Ystart = trunc(Y0 + Ht*YScale),
- Angle = 270.0 * 3.14159 / 180.0,
- Scale = scale(Index),
- N = gens(Index),
- Tree = grow(N,Index),
- drawit(Tree, Id, Xstart, Ystart, Angle, Scale, []).
-
-% drawit(Tree,S0,S).
-
-drawit([],_,_,_,_,_,_) ->
- true;
-drawit(['('|T],Id,X0,Y0,Ang,Scale,Stack) ->
- Ang1 = Ang + (20.0 * 3.14159 / 180.0),
- Scale1 = Scale * 0.8,
- drawit(T,Id,X0,Y0,Ang1,Scale1,[{X0,Y0,Ang,Scale}|Stack]);
-drawit(['['|T],Id,X0,Y0,Ang,Scale,Stack) ->
- Ang1 = Ang - (40.0 * 3.14159 / 180.0),
- Scale1 = Scale * 0.8,
- drawit(T,Id,X0,Y0,Ang1,Scale1,[{X0,Y0,Ang,Scale}|Stack]);
-drawit([')'|T],Id,_,_,_,_,[{X1,Y1,Ang1,Scale1}|Stack]) ->
- drawit(T,Id,X1,Y1,Ang1,Scale1,Stack);
-drawit([']'|T],Id,_,_,_,_,[{X1,Y1,Ang1,Scale1}|Stack]) ->
- drawit(T,Id,X1,Y1,Ang1,Scale1,Stack);
-drawit([Symbol|T],Id,X0,Y0,Ang,Scale,Stack) ->
- Size = step(Symbol),
- L = Size * Scale,
- {X1, Y1} = plotit(Id,X0,Y0,L,Ang),
- drawit(T,Id,X1,Y1,Ang,Scale,Stack).
-
-plotit(Id,X0,Y0,L,A) ->
- CosA = math:cos(A),
- SinA = math:sin(A),
- X = trunc(X0 + L*CosA),
- Y = trunc(Y0 + L*SinA),
- gs:create(line,Id,[{coords,[{X0,Y0},{X,Y}]}]),
- {X,Y}.
-
diff --git a/lib/gs/examples/line_demo.erl b/lib/gs/examples/line_demo.erl
deleted file mode 100644
index 25390d09b5..0000000000
--- a/lib/gs/examples/line_demo.erl
+++ /dev/null
@@ -1,82 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% A simple demo showing a line
-%% bouncing within a window.
-%% ------------------------------------------------------------
-
--module(line_demo).
--compile([{nowarn_deprecated_function,{gs,button,2}},
- {nowarn_deprecated_function,{gs,canvas,2}},
- {nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,line,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,2}}]).
-
--export([start/0,init/0,line/3]).
-
-start() ->
- spawn(line_demo,init,[]).
-
-init() ->
- I= gs:start(),
- W= gs:window(I,[{title,"Line Demo"},{width,300},{height,300},{map,true}]),
- C= gs:canvas(W,[{width,300},{height,300},{bg,blue}]),
- gs:button(W,[{label,{text,"Quit"}},{width,40},{bg,yellow}]),
- Line2 = gs:line(C,[{coords,[{0,0},{50,50}]},{fg,white},{width,3}]),
- line(Line2,{100,100,9.5,5},{0,0,-6,-8.4}).
-
-
-
-line(Line,{X1,Y1,DX1,DY1},{X2,Y2,DX2,DY2}) ->
- {NX1,NDX1} = cc(X1,DX1),
- {NY1,NDY1} = cc(Y1,DY1),
- {NX2,NDX2} = cc(X2,DX2),
- {NY2,NDY2} = cc(Y2,DY2),
- gs:config(Line,{coords,[{NX1,NY1},{NX2,NY2}]}),
- receive
- {gs,_,click,_,_} -> exit(normal);
- {gs,_,destroy,_,_} -> exit(normal)
- after 50 ->
- true
- end,
- line(Line,{NX1,NY1,NDX1,NDY1},{NX2,NY2,NDX2,NDY2}).
-
-cc(X,DX) ->
- if
- DX>0 ->
- if
- X<300 ->
- {X+DX,DX};
- x>=300 ->
- {X-DX,-DX}
- end;
- DX<0 ->
- if
- X>0 ->
- {X+DX,DX};
- X=<0 ->
- {X-DX,-DX}
- end
- end.
-
-%% ------------------------------------------------------------
diff --git a/lib/gs/examples/man.erl b/lib/gs/examples/man.erl
deleted file mode 100644
index 97d897e191..0000000000
--- a/lib/gs/examples/man.erl
+++ /dev/null
@@ -1,202 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Simple Manual Page Browser
-%% ------------------------------------------------------------
-
--module(man).
--compile([{nowarn_deprecated_function,{gs,button,2}},
- {nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,create,4}},
- {nowarn_deprecated_function,{gs,entry,2}},
- {nowarn_deprecated_function,{gs,label,2}},
- {nowarn_deprecated_function,{gs,listbox,2}},
- {nowarn_deprecated_function,{gs,read,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,3}}]).
-
--export([start/0,init/0]).
--export([man_list/0]).
--export([browser/1,browser_init/2]).
-
-
-start() ->
- case whereis(man) of
- undefined ->
- register(man,Pid=spawn(man,init,[])),
- Pid;
- Pid ->
- Pid
- end.
-
-
-%% ---- Man Directories -----
-dirManual() ->
- filename:join([code:root_dir(), "man", "cat3"]).
-
-
-%% ----- init -----
-init() ->
- S=gs:start(),
- Width=520,Height=520,
- gs:create(window,win,S,[{title,"Manual Browser"},
- {width,Width},{height,Height}]),
- gs:create(button,quit,win,[{width,60},{label,{text,"Quit"}}]),
- gs:create(button,select,win,[{x,60},{label,{text,"Select Page"}}]),
- gs:create(editor,editor,win,[{y,30},{width,Width},{height,Height-30},
- {hscroll,false},{vscroll,left}]),
- gs:config(win,[{map,true},{configure,true}]),
- man_loop(Width,Height).
-
-man_loop(Width0,Height0) ->
- receive
- {gs,_Win,configure,_,[Width0,Height0|_]} -> %% already got that size!
- man_loop(Width0,Height0);
- {gs,_Win,configure,_,[Width,Height|_]} ->
- %%io:format("man: width=~w, height=~w ~n",[Width,Height]),
- gs:config(editor,[{width,Width},{height,Height-30}]),
- man_loop(Width,Height);
- {gs,quit,click,_,_} ->
- %%io:format("man: exiting.~n",[]),
- exit(normal);
- {gs,select,click,_,_} ->
- case browser(man_list()) of
- cancel -> true;
- {ok,Page} -> load_page(Page);
- O -> io:format("man: bad browser result: ~w~n",[O])
- end,
- man_loop(Width0,Height0);
- {gs,_,destroy,_,_} ->
- exit(normal);
- X ->
- io:format("man: got other: ~w~n",[X]),
- man_loop(Width0,Height0)
- end.
-
-
-%% ----- man_list ----
-%%
-man_list() ->
- {ok,FirstList} = file:list_dir(dirManual()),
- SecondList =
- mapfilter(fun(File) ->
- case filename:extension(File) of
- ".3" ->
- {true, filename:basename(File, ".3")};
- _ -> false
- end
- end,
- FirstList),
- lists:sort(SecondList).
-
-mapfilter(Fun, [H|T]) ->
- case Fun(H) of
- {true, Val} ->
- [Val|mapfilter(Fun, T)];
- false ->
- mapfilter(Fun, T)
- end;
-mapfilter(_Fun, []) ->
- [].
-
-
-%% ------------------------------------------------------------
-%% Load in the Page
-
-load_page(Page) ->
- %%io:format("man: load page start ~p.~n",[Page]),
- Filename = filename:join([dirManual(),Page++".3"]),
- {ok,Bin}=file:read_file(Filename),
- _Txt=binary_to_list(Bin),
- gs:config(editor,{enable,true}),
- gs:config(editor,{load,Filename}),
- gs:config(editor,{enable,false}),
- %%io:format("man: load page done.~n",[]),
- true.
-
-
-%% ------------------------------------------------------------
-%% Simple Browser
-%% ------------------------------------------------------------
-
-browser(Items) ->
- Browser=spawn_link(man,browser_init,[self(),Items]),
- await_reply(Browser).
-
-await_reply(Browser) ->
- receive
- {browser,Result} ->
- Result;
- {gs,_,destroy,_,_} -> exit(normal);
- {gs,quit,click,_,_} -> exit(normal);
- {gs,select,click,_,_} ->
- Browser ! wake_up,
- await_reply(Browser)
- end.
-
-browser_init(Pid,Items) ->
- process_flag(trap_exit,true),
- S=gs:start(),
- Win=gs:window(win,S,[{width,250},{height,270},{title,"Browser"}]),
- _Lbl=gs:label(Win,[{label,{text,"Select a Manual Page"}},{width,250}]),
- gs:label(Win,[{width,40},{y,35},{label,{text,"Page:"}}]),
- Entry=gs:entry(Win,[{y,35},{width,205},{x,40},
- {keypress,true},{focus,true}]),
- Lb=gs:listbox(Win,[{x,5},{y,65},{width,160},{height,195},
- {vscroll,right},{click,true},{doubleclick,true}]),
- Ok=gs:button(Win,[{label,{text,"OK"}},{width,40},{x,185},{y,175}]),
- Cancel=gs:button(Win,[{label,{text,"Cancel"}},{x,175},{y,225},{width,65}]),
- gs:config(Lb,[{items,Items}]),
- gs:config(Win,{map,true}),
- browser_loop(Pid,Ok,Cancel,Entry,Lb).
-
-browser_loop(Pid,Ok,Cancel,Entry,Lb) ->
- receive
- {gs,Ok,click,_,_} ->
- Txt=gs:read(Entry,text),
- Pid ! {browser,{ok,Txt}};
- {gs,Cancel,click,_,_} ->
- Pid ! {browser,cancel};
- {gs,Entry,keypress,_,['Return'|_]} ->
- Txt=gs:read(Entry,text),
- Pid ! {browser,{ok,Txt}};
- {gs,Entry,keypress,_,_} ->
- browser_loop(Pid,Ok,Cancel,Entry,Lb);
- {gs,Lb,click,_,[_Idx, Txt| _Rest]} ->
- gs:config(Entry,{text,Txt}),
- browser_loop(Pid,Ok,Cancel,Entry,Lb);
- {gs,Lb,doubleclick,_,[_Idx, Txt| _Rest]} ->
- Pid ! {browser,{ok,Txt}};
- {gs,_,destroy,_,_} ->
- Pid ! {browser,cancel};
- wake_up ->
- gs:config(win,[{iconify,false},raise]),
- browser_loop(Pid,Ok,Cancel,Entry,Lb);
- {'EXIT',_Man,Why} ->
- exit(Why);
- X ->
- io:format("man: browser got other: ~w.~n",[X]),
- browser_loop(Pid,Ok,Cancel,Entry,Lb)
- end.
-
-%% ------------------------------------------------------------
-%% end of man.erl
diff --git a/lib/gs/examples/menu_demo.erl b/lib/gs/examples/menu_demo.erl
deleted file mode 100644
index c739e1dc87..0000000000
--- a/lib/gs/examples/menu_demo.erl
+++ /dev/null
@@ -1,81 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
--module(menu_demo).
--compile([{nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,create,3}},
- {nowarn_deprecated_function,{gs,create,4}},
- {nowarn_deprecated_function,{gs,read,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,2}}]).
-
--compile(export_all).
-
-start() -> spawn(menu_demo, init, []).
-
-init() ->
- I=gs:start(),
- Win=gs:window(I, [{title,"menu"},{width,200},{height,100}, {map, true}]),
- Bar = gs:create(menubar, Win, []),
- Fmb = gs:create(menubutton, Bar, [{label, {text, "File"}}]),
- Emb = gs:create(menubutton, Bar, [{label, {text, "Edit"}}]),
- Hmb = gs:create(menubutton, Bar, [{label, {text, "Help"}}, {side, right}]),
- Fmnu = gs:create(menu, Fmb, []),
- Emnu = gs:create(menu, Emb, []),
- Hmnu = gs:create(menu, Hmb, []),
- gs:create(menuitem, load, Fmnu, [{label,{text, "Load"}}]),
- gs:create(menuitem, save, Fmnu, [{label,{text, "Save"}}]),
- Exit = gs:create(menuitem, Fmnu, [{label,{text, "Exit"}}]),
- Color=gs:create(menuitem,Emnu,[{label,{text,"Color"}},{itemtype,cascade}]),
- Cmnu = gs:create(menu, Color, [{disabledfg,gray}]),
- gs:create(menuitem, Cmnu, [{label, {text,"Red"}}, {data, {new_color, red}},
- {fg,red}, {itemtype,radio},{group,gr1}]),
- gs:create(menuitem, Cmnu, [{label, {text,"Blue"}},{data, {new_color, blue}},
- {fg,blue}, {itemtype,radio},{group,gr1}]),
- gs:create(menuitem,Cmnu,[{label, {text,"Black"}},{data, {new_color, black}},
- {fg,black}, {itemtype,radio},{group,gr1}]),
- Y = gs:create(menuitem, Hmnu, [{label, {text,"You"}}, {itemtype, check}]),
- M = gs:create(menuitem,me,Hmnu,[{label,{text,"Me"}},{itemtype,check}]),
- gs:create(menuitem, Hmnu, [{label, {text, "Other"}}, {itemtype, check},
- {enable,false},{click,false}]),
- gs:create(menuitem,doit,Hmnu,[{label,{text,"Doit!"}},{data,{doit,Y,M}}]),
- loop(Exit, Win).
-
-loop(Exit, Win) ->
- receive
- {gs, save, click, _Data, [_Txt, _Index | _Rest]} ->
- io:format("Save~n");
- {gs, load, click, _Data, [_Txt, _Index | _Rest]} ->
- io:format("Load~n");
- {gs, Exit, click, _Data, [_Txt, _Index | _Rest]} ->
- io:format("Exit~n"),
- exit(normal);
- {gs, _MnuItem, click, {new_color, Color}, Args} ->
- io:format("Change color to ~w. Args:~p~n", [Color, Args]),
- gs:config(Win, [{bg, Color}]);
- {gs, doit, click, {doit, YouId, MeId}, Args} ->
- HelpMe = gs:read(MeId, select),
- HelpYou = gs:read(YouId, select),
- io:format("Doit. HelpMe:~w, HelpYou:~w, Args:~p~n",
- [HelpMe, HelpYou, Args]);
- Other -> io:format("Other:~p~n",[Other])
- end,
- loop(Exit, Win).
diff --git a/lib/gs/examples/rubber.erl b/lib/gs/examples/rubber.erl
deleted file mode 100644
index 129359dd03..0000000000
--- a/lib/gs/examples/rubber.erl
+++ /dev/null
@@ -1,113 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% A rubberbanding example in Erlang
-%% ------------------------------------------------------------
-
--module(rubber).
--compile([{nowarn_deprecated_function,{gs,button,2}},
- {nowarn_deprecated_function,{gs,canvas,2}},
- {nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,create,3}},
- {nowarn_deprecated_function,{gs,destroy,1}},
- {nowarn_deprecated_function,{gs,radiobutton,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,2}}]).
-
--export([start/0, init/0]).
-
-start() ->
- spawn(rubber,init,[]).
-
-init() ->
- I=gs:start(),
- Win = gs:window(I,[{title,"Rubberbanding in Erlang"},
- {width,300},{height,200}]),
- C= gs:canvas(Win,[{width,300},{height,200},{bg,green}]),
- gs:radiobutton(Win,[{width,100},{label,{text,"Oval"}},{align,w},
- {data,oval},{y,0},{select,true}]),
- gs:radiobutton(Win,[{width,100},{label,{text,"Rectangle"}},{align,w},
- {data,rectangle},{y,30}]),
- gs:radiobutton(Win,[{width,100},{label,{text,"Line"}},{align,w},
- {data,line},{y,60}]),
- gs:button(Win,[{label,{text,"Quit"}},{data,quit},{y,90}]),
- gs:config(Win,[{motion,true},{buttonpress,true},{buttonrelease,true}]),
- gs:config(Win,{map,true}),
- loop(C,nil,oval,0,0).
-
-
-loop(Win,Obj,Objtype,X1,Y1) ->
- receive
- {gs,_,motion,_,[X2,Y2]} ->
- flush(Win,Obj,Objtype,X1,Y1,X2,Y2);
- {gs,_,buttonpress,_,[1,X2,Y2]} ->
- down(Win,Obj,Objtype,X2,Y2);
- {gs,_,buttonrelease,_,[1,X2,Y2]} ->
- up(Win,Obj,Objtype,X1,Y1,X2,Y2);
- {gs,_,click,quit,_} ->
- exit(normal);
- {gs,_,click,Newtype,_} ->
- loop(Win,Obj,Newtype,X1,Y1);
- {gs,_,destroy,_,_} ->
- exit(normal);
- Other ->
- io:format("Other:~w~n",[Other]),
- loop(Win,Obj,Objtype,X1,Y1)
- end.
-
-
-down(Win,nil,oval,X1,Y1) ->
- Obj = gs:create(oval,Win,[{coords,[{X1,Y1},{X1+1,Y1+1}]},{fill,red}]),
- loop(Win,Obj,oval,X1,Y1);
-down(Win,nil,line,X1,Y1) ->
- Obj = gs:create(line,Win,[{coords,[{X1,Y1},{X1+1,Y1+1}]},{width,3},{fg,black}]),
- loop(Win,Obj,line,X1,Y1);
-down(Win,nil,Objtype,X1,Y1) ->
- Obj = gs:create(Objtype,Win,[{coords,[{X1,Y1},{X1+1,Y1+1}]},{bw,2},{fg,blue}]),
- loop(Win,Obj,Objtype,X1,Y1);
-down(Win,Obj,Objtype,X1,Y1) ->
- gs:destroy(Obj),
- down(Win,nil,Objtype,X1,Y1).
-
-up(Win,nil,Objtype,_X1,_Y1,X2,Y2) ->
- loop(Win,nil,Objtype,X2,Y2);
-up(Win,Obj,Objtype,X1,Y1,X2,Y2) ->
- gs:config(Obj,{coords,[{X1,Y1},{X2,Y2}]}),
- loop(Win,nil,Objtype,X2,Y2).
-
-
-move(Win,nil,Objtype,X1,Y1,_X2,_Y2) ->
- loop(Win,nil,Objtype,X1,Y1);
-move(Win,Obj,Objtype,X1,Y1,X2,Y2) ->
- gs:config(Obj,{coords,[{X1,Y1},{X2,Y2}]}),
- loop(Win,Obj,Objtype,X1,Y1).
-
-
-flush(Win,Obj,Objtype,X1,Y1,X2,Y2) ->
- receive
- {gs,_,motion,_,[XX2,YY2]} ->
- flush(Win,Obj,Objtype,X1,Y1,XX2,YY2)
- after
- 0 -> move(Win,Obj,Objtype,X1,Y1,X2,Y2)
- end.
-
-%% ------------------------------------------------------------
diff --git a/lib/gs/info b/lib/gs/info
deleted file mode 100644
index 05982e7318..0000000000
--- a/lib/gs/info
+++ /dev/null
@@ -1,2 +0,0 @@
-group: comm
-short: A Graphics System used to write platform independent user interfaces
diff --git a/lib/gs/prebuild.skip b/lib/gs/prebuild.skip
deleted file mode 100644
index e9bec68bc5..0000000000
--- a/lib/gs/prebuild.skip
+++ /dev/null
@@ -1 +0,0 @@
-tcl
diff --git a/lib/gs/priv/bitmap/fup.bm b/lib/gs/priv/bitmap/fup.bm
deleted file mode 100644
index a00b838db0..0000000000
--- a/lib/gs/priv/bitmap/fup.bm
+++ /dev/null
@@ -1,7 +0,0 @@
-#define fup_width 23
-#define fup_height 17
-static char fup_bits[] = {
- 0x00,0x00,0x00,0xf0,0x03,0x00,0x08,0x04,0x00,0x04,0x08,0x00,0xfe,0xff,0x3f,
- 0x02,0x00,0x20,0x42,0x00,0x20,0xe2,0x00,0x20,0xf2,0x01,0x20,0x42,0x00,0x20,
- 0x42,0x00,0x20,0x42,0x00,0x20,0xc2,0xff,0x20,0x02,0x00,0x20,0x02,0x00,0x20,
- 0xfe,0xff,0x3f,0x00,0x00,0x00};
diff --git a/lib/gs/priv/gs-xdefaults b/lib/gs/priv/gs-xdefaults
deleted file mode 100644
index ad096f2882..0000000000
--- a/lib/gs/priv/gs-xdefaults
+++ /dev/null
@@ -1,88 +0,0 @@
-*activeBackground: #ececec
-*activeBorderWidth: 1
-*activeForeground: Black
-*activeRelief: raised
-*anchor: center
-*aspect: 150
-*background: #d9d9d9
-*bigIncrement: 0
-!*bitmap:
-*borderWidth: 0
-!*class: Frame
-*closeEnough: 1
-!*colormap:
-!*command:
-*confine: 1
-!*cursor: arrow
-*digits: 0
-*disabledForeground: #a3a3a3
-!*doubleBuffer:
-*elementBorderWidth: -1
-*exportSelection: 1
-!*font: screen12
-*foreground: Black
-*from: 0
-!*height: 0
-*highlightBackground: #d9d9d9
-*highlightColor: Black
-*highlightThickness: 0
-!*image:
-*indicatorOn: 0
-*insertBackground: Black
-*insertBorderWidth: 0
-*insertOffTime: 300
-*insertOnTime: 600
-*insertWidth: 2
-*jump: 0
-*justify: left
-!*label:
-*length: 100
-!*menu:
-*offValue: 0
-*onValue: 1
-*orient: vertical
-*padX: 0
-*padY: 0
-!*postCommand:
-*relief: flat
-*repeatDelay: 300
-*repeatInterval: 100
-*resolution: 1
-!*screen:
-!*scrollRegion:
-*selectBackground: #c3c3c3
-*selectBorderWidth: 1
-*selectColor: #b03060
-*selectForeground: Black
-!*selectImage:
-*selectMode: browse
-*setGrid: 0
-!*show:
-*showValue: 1
-*sliderLength: 30
-*sliderRelief: sunken
-*spacing1: 0
-*spacing2: 0
-*spacing3: 0
-*state: normal
-!*tabs:
-*takeFocus: 0
-*tearOff: 1
-!*tearOffCommand:
-!*text:
-!*textVariable:
-*tickInterval: 0
-*to: 100
-*transient: 1
-*troughColor: #c3c3c3
-*underline: -1
-!*value:
-!*variable:
-!*visual:
-!*width: 0
-*wrap: char
-*wrapLength: 0
-!*xScrollCommand:
-*xScrollIncrement: 0
-!*yScrollCommand:
-*yScrollIncrement: 0
diff --git a/lib/gs/priv/gstk.tcl b/lib/gs/priv/gstk.tcl
deleted file mode 100644
index 63151ef952..0000000000
--- a/lib/gs/priv/gstk.tcl
+++ /dev/null
@@ -1,366 +0,0 @@
-# ------------------------------------------------------------
-# Some tcl scripts used from erlang
-# By Ola Samuelsson in May 1995
-# � Ericsson Software Technology / Erlang System
-# ------------------------------------------------------------
-
-package require Tk 8.3
-
-# Scrolled object.
-# This is a script that creates a
-# scrolled object of specified type
-# and connects it with scrollbars.
-#
-# Give a name for the frame and you'll find
-# name.z,
-# name.sy,
-# name.pad.sx
-# name.pad.it
-#
-
-proc so_create {type w} {
- set parent [frame $w]
- eval {$type $parent.z -highlightt 0}
- $parent.z config -yscrollcommand [list $parent.sy set] \
- -xscrollcommand [list $parent.pad.sx set]
- scrollbar $parent.sy -orient vertical -takefocus 0 \
- -command [list $parent.z yview]
- # create extra frame to hold pad
- frame $parent.pad
- scrollbar $parent.pad.sx -orient horizontal -takefocus 0 \
- -command [list $parent.z xview]
- #create padding based on the scrollbars width
- set pad [expr [$parent.sy cget -width] + 2 * \
- ([$parent.sy cget -bd] + \
- [$parent.sy cget -highlightthickness])]
- frame $parent.pad.it -width $pad -height $pad
- # Arrange everything
- so_plain $parent
- return $parent
-}
-
-proc so_top_right {w} {
- so_unpack $w
- pack $w.pad -side top -fill x
- pack $w.pad.it -side right
- pack $w.pad.sx -side top -fill x
- pack $w.sy -side right -fill y
- pack $w.z -side left -fill both -expand true
-}
-
-proc so_top_left {w} {
- so_unpack $w
- pack $w.pad -side top -fill x
- pack $w.pad.it -side left
- pack $w.pad.sx -side top -fill x
- pack $w.sy -side left -fill y
- pack $w.z -side right -fill both -expand true
-}
-
-proc so_bottom_right {w} {
- so_unpack $w
- pack $w.pad -side bottom -fill x
- pack $w.pad.it -side right
- pack $w.pad.sx -side bottom -fill x
- pack $w.sy -side right -fill y
- pack $w.z -side left -fill both -expand true
-}
-
-proc so_bottom_left {w} {
- so_unpack $w
- pack $w.pad -side bottom -fill x
- pack $w.pad.it -side left
- pack $w.pad.sx -side bottom -fill x
- pack $w.sy -side left -fill y
- pack $w.z -side right -fill both -expand true
-}
-
-proc so_bottom {w} {
- so_unpack $w
- pack $w.pad -side bottom -fill x
- pack $w.pad.sx -side bottom -fill x
- pack $w.z -side left -fill both -expand true
-}
-
-proc so_top {w} {
- so_unpack $w
- pack $w.pad -side top -fill x
- pack $w.pad.sx -side top -fill x
- pack $w.z -side left -fill both -expand true
-}
-
-proc so_right {w} {
- so_unpack $w
- pack $w.sy -side right -fill y
- pack $w.z -side left -fill both -expand true
-}
-
-proc so_left {w} {
- so_unpack $w
- pack $w.sy -side left -fill y
- pack $w.z -side right -fill both -expand true
-}
-
-proc so_plain {w} {
- so_unpack $w
- pack $w.z -side left -fill both -expand true
-}
-
-proc so_unpack {w} {
- pack forget $w.pad.it
- pack forget $w.pad.sx
- pack forget $w.pad
- pack forget $w.sy
- pack forget $w.z
-}
-
-# ------------------------------------------------------------
-# editor stuff
-
-proc ed_load {w file} {
- if [catch {open $file r} fileId] {
- report "$fileId"
- return -code error
- } else {
- $w delete 1.0 end
- while {![eof $fileId]} {
- $w insert end [read $fileId 1000]
- }
- close $fileId
- }
-}
-
-proc ed_save {w file} {
- if [catch {open $file w} fileId] {
- report "$fileId"
- return -code error
- } else {
- puts -nonewline $fileId [$w get 1.0 end]
- close $fileId
- }
-}
-
-# returns rect1 text1 rect2 text2 ...
-proc mkgrid {canvas colws startrow endrow height font fg bg} {
- set res [list]
- set ncols [llength $colws]
- set y [expr ($startrow-1)*$height+$startrow]
- for {set row $startrow} {$row <= $endrow} {incr row} {
- set x 1
- for {set col 0} {$col < $ncols} {incr col} {
- set colw [lindex $colws $col]
-# each object is tagged q<columnNo>
-# is this (ugly) way we can find to what column an object belongs
-# even later...
- set r [$canvas create re $x $y [expr $x+$colw] [expr $y+$height]\
- -f $bg -outline $fg -tag "q$col"]
- set t [$canvas create te [expr $x+2] [expr $y+2]\
- -anch nw -fo $font -fi $fg -tag "q$col"]
- $canvas raise $t
- lappend res $r $t
- set x [expr $x+$colw+1]
- }
- set y [expr $y+$height+1]
- }
- return $res
-}
-
-# new x values
-proc calc_new_xs {colws} {
- set ncols [llength $colws]
- set res [list]
- set x 1
- for {set col 0} {$col < $ncols} {incr col} {
- lappend res $x
- set x [expr $x+1+[lindex $colws $col]]
- }
- lappend res $x
- return $res
-}
-
-proc resize_grid_cols {canvas colws} {
- set item 1
- set xs [calc_new_xs $colws]
- while {[set nbr_of_coords\
- [llength [set coords [$canvas coords $item]]]] > 0} {
- set tags [$canvas itemcget $item -tag]
- set first [string first "q" $tags]
-# find the column of the current object by
-# searching for the q tag.
- set col [string range $tags [expr 1 + $first]\
- [expr [string wordend $tags $first] -1]]
- switch $nbr_of_coords {
- 2 { # a text object
- set y [lindex $coords 1]
- set newx [expr [lindex $xs $col] + 2]
- $canvas coords $item $newx $y
- }
- 4 { # a rectangle object
- set y1 [lindex $coords 1]
- set y2 [lindex $coords 3]
- set newx1 [lindex $xs $col]
- set newx2 [expr [lindex $xs [expr $col + 1]]-1]
- $canvas coords $item $newx1 $y1 $newx2 $y2
- }
- }
- set item [expr $item+1]
- }
-}
-
-# ------------------------------------------------------------
-# A wish init script to make it possible for
-# Tcl/Tk and erlang to communicate.
-# Written by Ola Samuelsson in August 1995
-# � Ericsson Software Technology AB / Erlang Systems
-# ------------------------------------------------------------
-
-# Protocol:
-# \1 = it's an event
-# \2 = it's a reply for a call
-# \3 = it's a error reply for call
-# \4 = it's an error
-# \5 = stopbyte (end of message)
-
-proc erlsend {args} {
- global outstream
- set msg [join $args]
- puts -nonewline $outstream [binary format Ica* \
- [expr 1 + [string length $msg]] 1 $msg]
- flush $outstream
-}
-
-proc erlcall {w} {
- global outstream
- set errcode [catch $w result]
- if {$errcode == 0} {
- puts -nonewline $outstream [binary format Ica* \
- [expr 1 + [string length $result]] 2 $result]
- flush $outstream
- } else {
- puts -nonewline $outstream [binary format Ica* \
- [expr 1 + [string length $result]] 3 $result]
- flush $outstream
- }
-}
-
-proc erlexec {w} {
- set errcode [catch $w result]
- if {$errcode != 0} {
- global outstream
- puts -nonewline $outstream [binary format Ica* \
- [expr 1 + [string length $result]] 4 $result]
- flush $outstream
- }
-}
-
-proc erlerror {w} {
- global outstream
- puts -nonewline $outstream [binary format Ica* \
- [expr 1 + [string length $w]] 4 $w]
- flush $outstream
-}
-
-proc report {s} {
- catch {console show}
- puts -nonewline stderr "$s\r\n"
-}
-
-wm withdraw .
-
-# The stdin stream is by default in line buffering mode.
-# We set non blocking so that if the line is large we are
-# not blocked until we get all data. The gets command
-# will never give us a line until we have read it all
-# so we do nothing if we get the return code -1.
-# Note that -1 also means eof so we check that.
-
-# FIXME: What is the default encoding on Unix?
-# Do we need to set "-encoding iso8859-1" ?
-
-# FIXME: If pipe we should do "catch {close $pipe}"
-# but we don't do that on stdin do we? If not how
-# do we unregister from 'fileevent'?
-
-# The ending "vwait forever" will block
-# until all streams are closed.
-# FIXME: How are we terminated? No check for eof?
-
-# If we got something on the command line after --
-# we have a port number and we are to use sockets
-# for the communication.
-
-set privdir [lindex $argv 0]
-set portno [lindex $argv 1]
-#report $argv
-#report $privdir
-#report $portno
-set resfile [file join $privdir gs-xdefaults]
-
-# FIXME we may use 'startupFile' as priority level to enable the user
-# to use .Xdefaults to override things but I think this require that
-# we change gs-xdefaults to use Tk*Option format?
-
-if [catch {option readfile $resfile} err] {
- report "Error reading $resfile: $err"
-}
-
-if {$portno == ""} {
-
- global use_socket
- set use_socket 0
- set instream stdin
- set outstream stdout
-
- # We are only allowed to set non blocking output
- # for pipes because sockets are bidirectional
- # and the fconfigure sets both input and output.
-
- fconfigure stdout -buffering none -blocking false \
- -translation binary -encoding binary
-} else {
-
- global use_socket
- set use_socket 1
- set sock [socket 127.0.0.1 $portno]
- set instream $sock
- set outstream $sock
-
-}
-
-fconfigure $instream -buffering none -blocking true \
- -translation binary -encoding binary
-
-fileevent $instream readable do_read
-
-proc do_read {} {
- global instream
-
- binary scan [read $instream 4] I len
-
- if {[eof $instream]} {
- catch {close $instream}
- exit
- }
-
-# report {"LEN $len"}
-
- # FIXME need to read again if less then $len ?????
- set command [read $instream $len]
-
- if {[eof $instream]} {
- catch {close $instream}
- exit
- }
-
-# report {"INMSG $command EOMSG"}
-
- if [catch {uplevel #0 $command} msg] {
- report {$msg}
- } else {
- if {[string length $msg] != 0} {
-# report {"OUTMSG $msg EOMSG"}
- puts -nonewline $instream [binary format Ia* \
- [string length $msg] $msg]
- }
- }
-}
diff --git a/lib/gs/src/Makefile b/lib/gs/src/Makefile
deleted file mode 100644
index e19ce822b9..0000000000
--- a/lib/gs/src/Makefile
+++ /dev/null
@@ -1,121 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1996-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-#
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include ../vsn.mk
-VSN=$(GS_VSN)
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/gs-$(VSN)
-
-ERL = erl
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-MODULES= gs gs_frontend gs_make gs_widgets gstk gstk_arc gstk_button\
- gstk_canvas gstk_checkbutton gstk_db gstk_editor gstk_entry \
- gstk_font gstk_frame gstk_grid gstk_gridline gs_packer \
- gstk_gs gstk_image gstk_label gstk_line gstk_listbox gstk_menu\
- gstk_menubar gstk_menubutton gstk_menuitem gstk_oval gstk_polygon \
- gstk_port_handler gstk_radiobutton gstk_rectangle gstk_scale \
- gstk_text gstk_widgets gstk_window tcl2erl tool_utils \
- tool_file_dialog gse
-
-GSTK_GENERIC = gstk_generic.erl
-
-HRL_FILES = gstk.hrl
-GEN_HRL_FILES = gstk_generic.hrl
-GSTK_GENERIC_TARGET = $(EBIN)/gstk_generic.$(EMULATOR)
-
-ERL_FILES= $(MODULES:%=%.erl)
-
-TARGET_FILES= $(MODULES:%=../ebin/%.$(EMULATOR)) $(GEN_HRL_FILES) \
- $(GSTK_GENERIC_TARGET) $(APP_TARGET) $(APPUP_TARGET)
-
-APP_FILE= gs.app
-APPUP_FILE= gs.appup
-
-APP_SRC= $(APP_FILE).src
-APPUP_SRC= $(APPUP_FILE).src
-
-APP_TARGET= ../ebin/$(APP_FILE)
-APPUP_TARGET= ../ebin/$(APPUP_FILE)
-
-IMAGES=../priv/bitmap/fup.bm
-
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_obsolete_guard -Werror
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-debug opt: $(TARGET_FILES)
-
-docs:
-
-clean:
- rm -f $(TARGET_FILES)
- rm -f core *~
-
-# ----------------------------------------------------
-# Special Build Targets
-# ----------------------------------------------------
-
-gstk_generic.hrl: gs_make.erl ../ebin/gs_make.$(EMULATOR) ../ebin/gs.$(EMULATOR)
- $(gen_verbose)$(ERL) -pa $(EBIN) -s gs_make -s erlang halt -noshell
-
-$(APP_TARGET): $(APP_SRC) ../vsn.mk
- $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
-
-$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
-
-$(GSTK_GENERIC_TARGET): gstk_generic.hrl
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-release_spec: opt
- $(INSTALL_DIR) "$(RELSYSDIR)/src"
- $(INSTALL_DATA) $(APP_SRC) $(ERL_FILES) $(HRL_FILES) $(GEN_HRL_FILES) \
- $(GSTK_GENERIC) "$(RELSYSDIR)/src"
- $(INSTALL_DIR) "$(RELSYSDIR)/ebin"
- $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin"
- $(INSTALL_DIR) "$(RELSYSDIR)/priv/bitmap"
- $(INSTALL_DATA) $(IMAGES) "$(RELSYSDIR)/priv/bitmap"
-
-
-release_docs_spec:
-
diff --git a/lib/gs/src/gs.app.src b/lib/gs/src/gs.app.src
deleted file mode 100644
index c6f88e5144..0000000000
--- a/lib/gs/src/gs.app.src
+++ /dev/null
@@ -1,14 +0,0 @@
-{application, gs,
- [{description, "GS The Graphics System"},
- {vsn, "%VSN%"},
- {modules, [gs,gs_frontend,gs_make,gs_widgets,gstk,gstk_arc,gstk_button,
- gstk_canvas,gstk_checkbutton,gstk_db,gstk_editor,gstk_entry,
- gstk_font,gstk_frame,gstk_generic,gstk_grid,gstk_gridline,gstk_gs,
- gstk_image,gstk_label,gstk_line,gstk_listbox,gstk_menu,gstk_menubar,
- gstk_menubutton,gstk_menuitem,gstk_oval,gstk_polygon,gstk_port_handler,
- gstk_radiobutton,gstk_rectangle,gstk_scale,gstk_text,gstk_widgets,
- gstk_window,tcl2erl,tool_file_dialog,tool_utils,
- gs_packer,gse]},
- {registered, [gs_frontend]},
- {applications, [kernel, stdlib]},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0"]}]}.
diff --git a/lib/gs/src/gs.erl b/lib/gs/src/gs.erl
deleted file mode 100644
index 23012da75d..0000000000
--- a/lib/gs/src/gs.erl
+++ /dev/null
@@ -1,410 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Erlang Graphics Interface and front end server
-%% ------------------------------------------------------------
-%%
-
--module(gs).
--deprecated(module).
--compile([{nowarn_deprecated_function,{gs,create,3}},
- {nowarn_deprecated_function,{gs,create,4}},
- {nowarn_deprecated_function,{gs,create_tree,2}},
- {nowarn_deprecated_function,{gs,foreach,3}},
- {nowarn_deprecated_function,{gs,read,2}},
- {nowarn_deprecated_function,{gs,start,1}}]).
-
-%% ----- Exports -----
--export([start/0, stop/0, start/1]).
--export([create/3, create/4, is_id/1]).
--export([info/1,create_tree/2]).
--export([config/2, read/2, destroy/1]).
--export([get_id/1]).
-
-%% ----- Not standard but convenient -----
--export([error/2,creation_error/2,assq/2,pair/2,val/2,val/3,foreach/3]).
--export([create/2]).
--export([window/1,window/2,window/3,button/1,button/2,button/3]).
--export([radiobutton/1,radiobutton/2,radiobutton/3]).
--export([checkbutton/1,checkbutton/2,checkbutton/3]).
--export([frame/1,frame/2,frame/3,label/1,label/2,label/3]).
--export([message/1,message/2,message/3]).
--export([listbox/1,listbox/2,listbox/3,entry/1,entry/2,entry/3]).
--export([scrollbar/1,scrollbar/2,scrollbar/3]).
--export([scale/1,scale/2,scale/3]).
--export([canvas/1,canvas/2,canvas/3,editor/1,editor/2,editor/3]).
--export([prompter/1,prompter/2,prompter/3]).
--export([line/1,line/2,line/3,oval/1,oval/2,oval/3]).
--export([rectangle/1,rectangle/2,rectangle/3]).
--export([polygon/1,polygon/2,polygon/3]).
--export([text/1,text/2,text/3,image/1,image/2,image/3,arc/1,arc/2,arc/3]).
--export([menu/1,menu/2,menu/3,menubutton/1,menubutton/2,menubutton/3]).
--export([menubar/1,menubar/2,menubar/3]).
--export([grid/1,grid/2,grid/3]).
--export([gridline/1,gridline/2,gridline/3]).
--export([menuitem/1,menuitem/2,menuitem/3]).
-
--include("gstk.hrl").
-
-%% ----- Start/Stop -----
-
-start() ->
- start([]).
-
-start(Opts) ->
- Opts2 = gstk_generic:merge_default_options(gs_widgets:default_options(gs),
- lists:sort(Opts)),
- gs_frontend:start(Opts2).
-
-stop() ->
- gs_frontend:stop().
-
-%% ----- Widget Commands -----
-
-create(Objtype, Parent) ->
- GsPid = frontend(Parent),
- tag_if_ok(gs_frontend:create(GsPid,{Objtype, undefined, obj_id(Parent),[]})
- ,GsPid).
-
-create(Objtype, Parent, Opts) when is_list(Opts) ->
- GsPid = frontend(Parent),
- tag_if_ok(gs_frontend:create(GsPid,{Objtype,undefined,obj_id(Parent),Opts}),
- GsPid);
-create(Objtype, Parent, Opt) ->
- GsPid = frontend(Parent),
- tag_if_ok(gs_frontend:create(GsPid,
- {Objtype,undefined,obj_id(Parent),[Opt]}),
- GsPid).
-
-create(Objtype, Name, Parent, Opts) when is_list(Opts) ->
- GsPid = frontend(Parent),
- tag_if_ok(gs_frontend:create(GsPid,{Objtype, Name, obj_id(Parent),Opts}),
- GsPid);
-create(Objtype, Name, Parent, Opt) ->
- GsPid = frontend(Parent),
- tag_if_ok(gs_frontend:create(GsPid,{Objtype,Name,obj_id(Parent),[Opt]}),
- GsPid).
-
-tag_if_ok(Int,Pid) when is_integer(Int) ->
- {Int,Pid};
-tag_if_ok(Err,_) ->
- Err.
-
-config(IdOrName, Options) when is_list(Options) ->
- gs_frontend:config(frontend(IdOrName),{obj_id(IdOrName),Options});
-config(IdOrName, Option) ->
- gs_frontend:config(frontend(IdOrName),{obj_id(IdOrName),[Option]}).
-
-read(IdOrName, Option) ->
- gs_frontend:read(frontend(IdOrName),{obj_id(IdOrName),Option}).
-
-destroy(IdOrName) ->
- gs_frontend:destroy(frontend(IdOrName),obj_id(IdOrName)).
-
-get_id(Name) ->
- read(Name,id).
-
-info(version) -> "1.3.2";
-info(Option) ->
- gs_frontend:info(Option).
-
-is_id({Int,Pid}) when is_integer(Int), is_pid(Pid) -> true;
-is_id(_) -> false.
-
-frontend({_,Pid}) when is_pid(Pid) -> Pid;
-frontend({AtomName,Node}) when is_atom(AtomName),is_atom(Node) ->
- rpc:call(Node,erlang,whereis,[gs_frontend]);
-frontend(Atom) when is_atom(Atom) -> whereis(gs_frontend).
-
-obj_id({Id,_}) -> Id;
-obj_id(Atom) when is_atom(Atom) -> Atom.
-
-error(Format, Data) ->
- io:format("gs error: "),
- ok = io:format(Format, Data), % don't be quiet when Format is malformed
- io:format("~n").
-
-creation_error(#gstkid{objtype=Ot}, {bad_result, BadResult}) ->
- {error, {creation_error,Ot,BadResult}};
-creation_error(#gstkid{objtype=Ot}, BadResult) ->
- {error, {creation_error,Ot,BadResult}}.
-
-
-create_tree(ParentId,[{Type,Name,Options,Children}|R]) ->
- case create(Type,Name,ParentId,Options) of
- {error,_Reason} -> {error,{create_tree,aborted_at,Type,Name}};
- Id ->
- case create_tree(Id,Children) of
- ok -> create_tree(ParentId,R);
- Err -> Err
- end
- end;
-create_tree(ParentId,[{Type,Name,Options}|R]) when is_atom(Name) ->
- create_tree(ParentId,[{Type,Name,Options,[]}|R]);
-create_tree(ParentId,[{Type,Options,Children}|R]) ->
- case create(Type,ParentId,Options) of
- {error,_Reason} -> {error,{create_tree,aborted_at,Type,Options}};
- Id ->
- case create_tree(Id,Children) of
- ok -> create_tree(ParentId,R);
- Err -> Err
- end
- end;
-create_tree(ParentId,[{Type,Options}|R]) ->
- create_tree(ParentId,[{Type,Options,[]}|R]);
-create_tree(ParentId,Tuple) when is_tuple(Tuple) ->
- create_tree(ParentId,[Tuple]);
-create_tree(_,[]) ->
- ok.
-
-
-window(ParentId) ->
- create(window,ParentId,[]).
-window(ParentId,Options) ->
- create(window,ParentId,Options).
-window(Name,ParentId,Options) ->
- create(window,Name,ParentId,Options).
-
-button(ParentId) ->
- create(button,ParentId,[]).
-button(ParentId,Options) ->
- create(button,ParentId,Options).
-button(Name,ParentId,Options) ->
- create(button,Name,ParentId,Options).
-
-checkbutton(ParentId) ->
- create(checkbutton,ParentId,[]).
-checkbutton(ParentId,Options) ->
- create(checkbutton,ParentId,Options).
-
-checkbutton(Name,ParentId,Options) ->
- create(checkbutton,Name,ParentId,Options).
-
-radiobutton(ParentId) ->
- create(radiobutton,ParentId,[]).
-radiobutton(ParentId,Options) ->
- create(radiobutton,ParentId,Options).
-radiobutton(Name,ParentId,Options) ->
- create(radiobutton,Name,ParentId,Options).
-
-frame(ParentId) ->
- create(frame,ParentId,[]).
-frame(ParentId,Options) ->
- create(frame,ParentId,Options).
-frame(Name,ParentId,Options) ->
- create(frame,Name,ParentId,Options).
-
-canvas(ParentId) ->
- create(canvas,ParentId,[]).
-canvas(ParentId,Options) ->
- create(canvas,ParentId,Options).
-canvas(Name,ParentId,Options) ->
- create(canvas,Name,ParentId,Options).
-
-label(ParentId) ->
- create(label,ParentId,[]).
-label(ParentId,Options) ->
- create(label,ParentId,Options).
-label(Name,ParentId,Options) ->
- create(label,Name,ParentId,Options).
-
-message(ParentId) ->
- create(message,ParentId,[]).
-message(ParentId,Options) ->
- create(message,ParentId,Options).
-message(Name,ParentId,Options) ->
- create(message,Name,ParentId,Options).
-
-listbox(ParentId) ->
- create(listbox,ParentId,[]).
-listbox(ParentId,Options) ->
- create(listbox,ParentId,Options).
-listbox(Name,ParentId,Options) ->
- create(listbox,Name,ParentId,Options).
-
-entry(ParentId) ->
- create(entry,ParentId,[]).
-entry(ParentId,Options) ->
- create(entry,ParentId,Options).
-entry(Name,ParentId,Options) ->
- create(entry,Name,ParentId,Options).
-
-scrollbar(ParentId) ->
- create(scrollbar,ParentId,[]).
-scrollbar(ParentId,Options) ->
- create(scrollbar,ParentId,Options).
-scrollbar(Name,ParentId,Options) ->
- create(scrollbar,Name,ParentId,Options).
-
-scale(ParentId) ->
- create(scale,ParentId,[]).
-scale(ParentId,Options) ->
- create(scale,ParentId,Options).
-scale(Name,ParentId,Options) ->
- create(scale,Name,ParentId,Options).
-
-editor(ParentId) ->
- create(editor,ParentId,[]).
-editor(ParentId,Options) ->
- create(editor,ParentId,Options).
-editor(Name,ParentId,Options) ->
- create(editor,Name,ParentId,Options).
-
-prompter(ParentId) ->
- create(prompter,ParentId,[]).
-prompter(ParentId,Options) ->
- create(prompter,ParentId,Options).
-prompter(Name,ParentId,Options) ->
- create(prompter,Name,ParentId,Options).
-
-line(ParentId) ->
- create(line,ParentId,[]).
-line(ParentId,Options) ->
- create(line,ParentId,Options).
-line(Name,ParentId,Options) ->
- create(line,Name,ParentId,Options).
-
-oval(ParentId) ->
- create(oval,ParentId,[]).
-oval(ParentId,Options) ->
- create(oval,ParentId,Options).
-oval(Name,ParentId,Options) ->
- create(oval,Name,ParentId,Options).
-
-rectangle(ParentId) ->
- create(rectangle,ParentId,[]).
-rectangle(ParentId,Options) ->
- create(rectangle,ParentId,Options).
-rectangle(Name,ParentId,Options) ->
- create(rectangle,Name,ParentId,Options).
-
-polygon(ParentId) ->
- create(polygon,ParentId,[]).
-polygon(ParentId,Options) ->
- create(polygon,ParentId,Options).
-polygon(Name,ParentId,Options) ->
- create(polygon,Name,ParentId,Options).
-
-text(ParentId) ->
- create(text,ParentId,[]).
-text(ParentId,Options) ->
- create(text,ParentId,Options).
-text(Name,ParentId,Options) ->
- create(text,Name,ParentId,Options).
-
-image(ParentId) ->
- create(image,ParentId,[]).
-image(ParentId,Options) ->
- create(image,ParentId,Options).
-image(Name,ParentId,Options) ->
- create(image,Name,ParentId,Options).
-
-arc(ParentId) ->
- create(arc,ParentId,[]).
-arc(ParentId,Options) ->
- create(arc,ParentId,Options).
-arc(Name,ParentId,Options) ->
- create(arc,Name,ParentId,Options).
-
-menu(ParentId) ->
- create(menu,ParentId,[]).
-menu(ParentId, Options) ->
- create(menu,ParentId,Options).
-menu(Name,ParentId,Options) ->
- create(menu,Name,ParentId,Options).
-
-menubutton(ParentId) ->
- create(menubutton,ParentId,[]).
-menubutton(ParentId,Options) ->
- create(menubutton,ParentId,Options).
-menubutton(Name,ParentId,Options) ->
- create(menubutton,Name,ParentId,Options).
-
-menubar(ParentId) ->
- create(menubar,ParentId,[]).
-menubar(ParentId,Options) ->
- create(menubar,ParentId,Options).
-menubar(Name,ParentId,Options) ->
- create(menubar,Name,ParentId,Options).
-
-menuitem(ParentId) ->
- create(menuitem,ParentId,[]).
-menuitem(ParentId,Options) ->
- create(menuitem,ParentId,Options).
-menuitem(Name,ParentId,Options) ->
- create(menuitem,Name,ParentId,Options).
-
-grid(ParentId) ->
- create(grid,ParentId,[]).
-grid(ParentId,Options) ->
- create(grid,ParentId,Options).
-grid(Name,ParentId,Options) ->
- create(grid,Name,ParentId,Options).
-
-gridline(ParentId) ->
- create(gridline,ParentId,[]).
-gridline(ParentId,Options) ->
- create(gridline,ParentId,Options).
-gridline(Name,ParentId,Options) ->
- create(gridline,Name,ParentId,Options).
-
-%%----------------------------------------------------------------------
-%% Waiting for erl44
-%%----------------------------------------------------------------------
-foreach(F, ExtraArgs, [H | T]) ->
- apply(F, [H | ExtraArgs]),
- foreach(F, ExtraArgs, T);
-foreach(_F, _ExtraArgs, []) -> ok.
-
-%%----------------------------------------------------------------------
-%% ASSociation with eQual key (scheme standard)
-%%----------------------------------------------------------------------
-assq(Key, List) ->
- case lists:keysearch(Key, 1, List) of
- {value, {_, Val}} -> {value, Val};
- _ -> false
- end.
-
-%%----------------------------------------------------------------------
-%% When we need the whole pair.
-%%----------------------------------------------------------------------
-pair(Key, List) ->
- case lists:keysearch(Key, 1, List) of
- {value, Pair} -> Pair;
- _ -> false
- end.
-
-%%----------------------------------------------------------------------
-%% When we know there is a value
-%%----------------------------------------------------------------------
-val(Key, List) when is_list(List) ->
- {value, {_,Val}} = lists:keysearch(Key, 1, List),
- Val.
-
-val(Key,List,ElseVal) when is_list(List) ->
- case lists:keysearch(Key, 1, List) of
- {value, {_, Val}} -> Val;
- _ -> ElseVal
- end.
-
-%% ----------------------------------------
-%% done
diff --git a/lib/gs/src/gs_frontend.erl b/lib/gs/src/gs_frontend.erl
deleted file mode 100644
index f46fdb36bb..0000000000
--- a/lib/gs/src/gs_frontend.erl
+++ /dev/null
@@ -1,371 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Erlang Graphics Interface front-end server
-%% ------------------------------------------------------------
-%%
-
--module(gs_frontend).
--compile([{nowarn_deprecated_function,{gs,assq,2}},
- {nowarn_deprecated_function,{gs,error,2}}]).
-
--export([create/2,
- config/2,
- read/2,
- destroy/2,
- info/1,
- start/1,
- stop/0,
- init/1,
- event/3]).
-
-
--include("gstk.hrl").
-
-
-%%----------------------------------------------------------------------
-%% The ets contains: {Obj,lives}|{Obj,{Name,Pid}}
-%% new obj is {Int,Node}
-%% {{Name,Pid},Obj}
-%%----------------------------------------------------------------------
--record(state, {db,user,user_count,kernel,kernel_count,self}).
-
-%%----------------------------------------------------------------------
-%% The interface.
-%%----------------------------------------------------------------------
-create(GsPid,Args) ->
- request(GsPid,{create,Args}).
-
-config(GsPid,Args) ->
- request(GsPid,{config, Args}).
-
-read(GsPid,Args) ->
- request(GsPid,{read, Args}).
-
-destroy(GsPid,IdOrName) ->
- request(GsPid,{destroy, IdOrName}).
-
-info(Option) ->
- request(gs_frontend,{info,Option}).
-
-
-%%----------------------------------------------------------------------
-%% Comment: Frontend is only locally registered. These functions are called
-%% by any backend.
-%%----------------------------------------------------------------------
-event(FrontEnd,ToOwner,EventMsg) ->
- FrontEnd ! {event, ToOwner,EventMsg}.
-
-
-request(GsPid,Msg) ->
- GsPid ! {self(),Msg},
- receive
- {gs_reply,R} -> R
- end.
-
-%%----------------------------------------------------------------------
-%% The server
-%%----------------------------------------------------------------------
-
-start(Opts) ->
- case whereis(gs_frontend) of
- undefined ->
- P = spawn_link(gs_frontend,init,[Opts]),
- case catch register(gs_frontend, P) of
- true ->
- request(gs_frontend,{instance, backend_name(Opts), Opts});
- {'EXIT', _} ->
- exit(P,kill), % a raise... and I lost this time
- start(Opts)
- end;
- P ->
- request(P,{instance,backend_name(Opts),Opts})
- end.
-
-backend_name(Opts) ->
- case gs:assq(kernel,Opts) of
- {value,true} -> kernel;
- _ -> user
- end.
-
-
-stop() ->
- request(gs_frontend,stop).
-
-%% ------------------------------------------------------------
-%% THE FRONT END SERVER
-%% ------------------------------------------------------------
-%% Initialize
-%%
-init(_Opts) ->
- process_flag(trap_exit, true),
- DB=ets:new(gs_names,[set,public]),
- loop(#state{db=DB,self=self()}).
-
-loop(State) ->
- receive
- X ->
- % io:format("frontend received: ~p~n",[X]),
- case catch (doit(X,State)) of
- done -> loop(State);
- NewState when is_record(NewState,state) ->
- loop(NewState);
- stop -> stop;
- Reason ->
- io:format("GS frontend. Last mgs in was:~p~n",[X]),
- io:format("exit:~p~n",[X]),
- io:format("Reason: ~p~n", [Reason]),
- terminate(Reason,State),
- exit(Reason)
- end
- end.
-
-reply(To,Msg) ->
- To ! {gs_reply,Msg},
- done.
-
-doit({FromOwner,{config, Args}},State) ->
- {IdOrName, Opts} = Args,
- #state{db=DB} = State,
- case idOrName_to_id(DB,IdOrName,FromOwner) of
- undefined ->
- reply(FromOwner,{error,{no_such_object,IdOrName}});
- Obj ->
- reply(FromOwner,gstk:config(backend(State,Obj),{Obj,Opts}))
- end;
-
-doit({event,ToOwner,{gs,Obj,Etype,Data,Args}}, #state{db=DB,self=Self}) ->
- case ets:lookup(DB,Obj) of
- [{_,{Name,ToOwner}}] -> ToOwner ! {gs,Name,Etype,Data,Args};
- _ -> ToOwner ! {gs,{Obj,Self},Etype,Data,Args}
- end,
- done;
-
-doit({FromOwner,{create,Args}}, State) ->
- {Objtype, Name, Parent, Opts} = Args,
- #state{db=DB} = State,
- NameOccupied = case {Name, ets:lookup(DB,{Name,FromOwner})} of
- {undefined,_} -> false;
- {_, []} -> false;
- _ -> true
- end,
- if NameOccupied == true ->
- reply(FromOwner, {error,{name_occupied,Name}});
- true ->
- case idOrName_to_id(DB,Parent,FromOwner) of
- undefined ->
- reply(FromOwner, {error,{no_such_parent,Parent}});
- ParentObj ->
- {Id,NewState} = inc(ParentObj,State),
- case gstk:create(backend(State,ParentObj),
- {FromOwner,{Objtype,Id,ParentObj,Opts}}) of
- ok ->
- link(FromOwner),
- if Name == undefined ->
- ets:insert(DB,{Id,lives}),
- reply(FromOwner, Id),
- NewState;
- true -> % it's a real name, register it
- NamePid = {Name,FromOwner},
- ets:insert(DB,{NamePid,Id}),
- ets:insert(DB,{Id,NamePid}),
- reply(FromOwner,Id),
- NewState
- end;
- Err -> reply(FromOwner,Err)
- end
- end
- end;
-
-doit({FromOwner,{read, Args}}, State) ->
- #state{db=DB} = State,
- {IdOrName, Opt} = Args,
- case idOrName_to_id(DB,IdOrName,FromOwner) of
- undefined ->
- reply(FromOwner,{error,{no_such_object,IdOrName}});
- Obj ->
- reply(FromOwner,gstk:read(backend(State,Obj),{Obj,Opt}))
- end;
-
-doit({'EXIT', UserBackend, Reason}, State)
- when State#state.user == UserBackend ->
- gs:error("user backend died reason ~w~n", [Reason]),
- remove_user_objects(State#state.db),
- State#state{user=undefined};
-
-doit({'EXIT', KernelBackend, Reason}, State)
- when State#state.kernel == KernelBackend ->
- gs:error("kernel backend died reason ~w~n", [Reason]),
- exit({gs_kernel_died,Reason});
-
-doit({'EXIT', Pid, _Reason}, #state{kernel=K,user=U,db=DB}) ->
- %% io:format("Pid ~w died reason ~w~n", [Pid, _Reason]),
- if is_pid(U) ->
- DeadObjU = gstk:pid_died(U,Pid),
- remove_objs(DB,DeadObjU);
- true -> ok
- end,
- if is_pid(K) ->
- DeadObjK = gstk:pid_died(K,Pid),
- remove_objs(DB,DeadObjK);
- true -> true end,
- done;
-
-doit({FromOwner,{destroy, IdOrName}}, State) ->
- #state{db=DB} = State,
- case idOrName_to_id(DB,IdOrName,FromOwner) of
- undefined ->
- reply(FromOwner, {error,{no_such_object,IdOrName}});
- Obj ->
- DeadObj = gstk:destroy(backend(State,Obj),Obj),
- remove_objs(DB,DeadObj),
- reply(FromOwner,done)
- end;
-
-doit({From,{instance,user,Opts}},State) ->
- #state{db=DB, self=Self, user_count=UC} = State,
- case ets:lookup(DB,1) of
- [_] -> reply(From, {1,Self});
- [] ->
- ets:insert(DB,{1,lives}), % parent of all user gs objs
- case gstk:start_link(1, Self, Self, Opts) of
- {ok, UserBackend} ->
- reply(From, {1, Self}),
- case UC of
- undefined ->
- State#state{user_count=1, user=UserBackend};
- _N ->
- State#state{user_count=UC+2, user=UserBackend}
- end;
- {error, Reason} ->
- reply(From, {error, Reason}),
- stop
- end
- end;
-
-doit({From,{instance,kernel,Opts}},State) ->
- #state{db=DB,self=Self} = State,
- case ets:lookup(DB,0) of
- [_] -> reply(From, {0,Self});
- [] ->
- ets:insert(DB,{0,lives}), % parent of all user gs objs
- case gstk:start_link(0,Self,Self,Opts) of
- {ok, KernelBackend} ->
- reply(From, {0,Self}),
- State#state{kernel_count=0,kernel=KernelBackend};
- {error, Reason} ->
- reply(From, {error,Reason}),
- stop
- end
- end;
-
-
-doit({From,stop}, State) ->
- #state{kernel=K,user=U} = State,
- if is_pid(U) -> gstk:stop(U);
- true -> true end,
- if is_pid(K) -> gstk:stop(K);
- true -> true end,
- reply(From,stopped),
- stop;
-
-doit({From,{gstk,user,Msg}},State) ->
- reply(From,gstk:request(State#state.user,Msg));
-doit({From,{gstk,kernel,Msg}},State) ->
- reply(From,gstk:request(State#state.kernel,Msg));
-
-doit({From,{info,gs_db}},State) ->
- io:format("gs_db:~p~n",[ets:tab2list(State#state.db)]),
- reply(From,State);
-doit({From,{info,kernel_db}},State) ->
- reply(From,gstk:request(State#state.kernel,dump_db));
-doit({From,{info,user_db}},State) ->
- reply(From,gstk:request(State#state.user,dump_db));
-doit({From,{info,Unknown}},_State) ->
- io:format("gs: unknown info option '~w', use one of 'gs_db', 'kernel_db' or 'user_db'~n",[Unknown]),
- reply(From,ok).
-
-terminate(_Reason,#state{db=DB}) ->
- if DB==undefined -> ok;
- true ->
- % io:format("frontend db:~p~n",[ets:tab2list(DB)])
- ok
- end.
-
-
-backend(#state{user=Upid,kernel=Kpid},Obj) ->
- if Obj rem 2 == 0 -> Kpid;
- true -> Upid
- end.
-
-%%----------------------------------------------------------------------
-%% Returns: {NewId,NewState}
-%%----------------------------------------------------------------------
-inc(ParInt,State) when ParInt rem 2 == 1 ->
- X=State#state.user_count+2,
- {X,State#state{user_count=X}};
-inc(ParInt,State) when ParInt rem 2 == 0 ->
- X=State#state.kernel_count+2,
- {X,State#state{kernel_count=X}}.
-
-remove_user_objects(DB) ->
- DeadObj = find_user_obj(ets:first(DB),DB),
- remove_objs(DB,DeadObj).
-
-find_user_obj(Int,DB) when is_integer(Int) ->
- if Int rem 2 == 0 -> %% a kernel obj
- find_user_obj(ets:next(DB,Int),DB);
- true -> %% a user obj
- [Int|find_user_obj(ets:next(DB,Int),DB)]
- end;
-find_user_obj('$end_of_table',_DB) ->
- [];
-find_user_obj(OtherKey,DB) ->
- find_user_obj(ets:next(DB,OtherKey),DB).
-
-remove_objs(DB,[Obj|Objs]) ->
- case ets:lookup(DB, Obj) of
- [{_,NamePid}] ->
- ets:delete(DB,Obj),
- ets:delete(DB,NamePid);
- [] -> backend_only
- end,
- remove_objs(DB,Objs);
-remove_objs(_DB,[]) -> done.
-
-idOrName_to_id(DB,IdOrName,Pid) when is_atom(IdOrName) ->
- case ets:lookup(DB,{IdOrName,Pid}) of
- [{_,Obj}] -> Obj;
- _ -> undefined
- end;
-idOrName_to_id(DB,Obj,_Pid) ->
- case ets:lookup(DB,Obj) of
- [_] -> Obj;
- _ -> undefined
- end.
-
-
-
-
-%% ----------------------------------------
-%% done
-
diff --git a/lib/gs/src/gs_make.erl b/lib/gs/src/gs_make.erl
deleted file mode 100644
index 061b1944d1..0000000000
--- a/lib/gs/src/gs_make.erl
+++ /dev/null
@@ -1,266 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
--module(gs_make).
--compile([{nowarn_deprecated_function,{gs,assq,2}}]).
-
--export([start/0]).
-
-start() ->
- Terms = the_config(),
- DB=fill_ets(Terms),
- {ok,OutFd} = file:open("gstk_generic.hrl", [write]),
- put(stdout,OutFd),
-% io:format("terms: ~p ~n ets:~p~n",[Terms,ets:tab2list(DB)]),
- p("% Don't edit this file. It was generated by gs_make:start/0 "),
- p("at ~p-~p-~p, ~p:~p:~p.\n\n",
- lists:append(tuple_to_list(date()),tuple_to_list(time()))),
- gen_out_opts(DB),
- gen_read(DB),
- file:close(OutFd),
- {ok,"gstk_generic.hrl",DB}.
-
-fill_ets(Terms) ->
- DB = ets:new(gs_mapping,[bag,public]),
- fill_ets(DB,Terms).
-
-fill_ets(DB,[]) -> DB;
-fill_ets(DB,[{Objs,Opt,Fun,Access}|Terms]) ->
- fill_ets(DB,lists:flatten(Objs),Opt,Fun,Access),
- fill_ets(DB,Terms).
-
-fill_ets(_DB,[],_,_,_) -> done;
-fill_ets(DB,[Obj|Objs],Opt,Fun,rw) ->
- ets:insert(DB,{Obj,Opt,Fun,read}),
- ets:insert(DB,{Obj,Opt,Fun,write}),
- fill_ets(DB,Objs,Opt,Fun,rw);
-fill_ets(DB,[Obj|Objs],Opt,Fun,r) ->
- ets:insert(DB,{Obj,Opt,Fun,read}),
- fill_ets(DB,Objs,Opt,Fun,r);
-fill_ets(DB,[Obj|Objs],Opt,Fun,w) ->
- ets:insert(DB,{Obj,Opt,Fun,write}),
- fill_ets(DB,Objs,Opt,Fun,w).
-
-
-
-gen_out_opts(DB) ->
- ObjTypes = lists:flatten(ordsets:from_list(ets:match(DB,{'$1','_','_',write}))),
- p("out_opts([Option|Options],Gstkid,TkW,DB,ExtraArg,S,P,C) ->\n"),
- p(" {Opt,Val} =\n"),
- p(" case Option of \n"),
- p(" {{default,Cat,Key},V} -> {default,{Cat,{Key,V}}};\n"),
- p(" {_Key,_V} -> Option;\n"),
- p(" {default,Cat,Opti} -> {default,{Cat,Opti}};\n"),
- p(" Atom when is_atom(Atom) -> {Atom,undefined};\n"),
- p(" _ -> {error, {invalid_option,Option}}\n"),
- p(" end,\n"),
- p(" case Gstkid#gstkid.objtype of\n"),
- gen_out_type_case_clauses(merge_types(ObjTypes),DB),
- p(" Q -> exit({internal_error,unknown_objtype,Q})\n"),
- p(" end;\n"),
- p("out_opts([],_Gstkid,_TkW,_DB,_ExtraArg,S,P,C) -> \n"),
- p(" {S,P,C}.\n").
-
-
-gen_out_type_case_clauses([],_DB) -> done;
-gen_out_type_case_clauses([Objtype|Objtypes],DB) ->
- OptsFuns = lists:map(fun(L) -> list_to_tuple(L) end,
- ets:match(DB,{Objtype,'$1','$2',write})),
- p(" ~p -> \ncase Opt of\n",[Objtype]),
- gen_opt_case_clauses(merge_opts(opt_prio(),OptsFuns)),
- p(" _ -> \n"),
- p(" handle_external_opt_call([Option|Options],Gstkid,TkW,DB,ExtraArg,"
- " gstk_~p:option(Option,Gstkid,TkW,DB,ExtraArg),S,P,C)\n",
- [Objtype]),
- p(" end;\n"),
- gen_out_type_case_clauses(Objtypes,DB).
-
-gen_opt_case_clauses([]) ->
- done;
-gen_opt_case_clauses([{Opt,Fun}|OptFuncs]) ->
- p(" ~p ->\n",[Opt]),
- p(" ~p(Val,Options,Gstkid,TkW,DB,ExtraArg,S,P,C);\n",[Fun]),
- gen_opt_case_clauses(OptFuncs).
-
-gen_read(DB) ->
- ObjTypes = lists:flatten(ordsets:from_list(ets:match(DB,{'$1','_','_',read}))),
- p("read_option(DB,Gstkid,TkW,Option,ExtraArg) ->\n"),
- p(" Key = case Option of\n"),
- p(" Atom when is_atom(Atom) -> Atom;\n"),
- p(" Opt when is_tuple(Opt) -> element(1,Opt)\n"),
- p(" end,\n"),
- p(" case Gstkid#gstkid.objtype of\n"),
- gen_read_type_clauses(merge_types(ObjTypes),DB),
- p(" Q -> exit({internal_error,unknown_objtype,Q})\n"),
- p(" end.\n").
-
-
-gen_read_type_clauses([],_) -> done;
-gen_read_type_clauses([Objtype|Objtypes],DB) ->
- OptsFuns = lists:map(fun(L) -> list_to_tuple(L) end,
- ets:match(DB,{Objtype,'$1','$2',read})),
- p(" ~p -> \ncase Key of\n",[Objtype]),
- gen_readopt_case_clauses(merge_opts(opt_prio(),OptsFuns)),
- p(" _ -> \nhandle_external_read(gstk_~p:read_option(Option,Gstkid,TkW,DB,ExtraArg))\n",[Objtype]),
- p(" end;\n"),
- gen_read_type_clauses(Objtypes,DB).
-
-gen_readopt_case_clauses([]) ->
- done;
-gen_readopt_case_clauses([{Opt,Fun}|OptFuncs]) ->
- p(" ~p -> \n~p(Option,Gstkid,TkW,DB,ExtraArg);\n",[Opt,Fun]),
- gen_readopt_case_clauses(OptFuncs).
-
-
-p(Str) ->
- ok = io:format(get(stdout),Str,[]).
-
-p(Format,Data) ->
- ok = io:format(get(stdout),Format,Data).
-
-%%----------------------------------------------------------------------
-%% There items should be placed early in a case statement.
-%%----------------------------------------------------------------------
-obj_prio() -> [rectangle,line,gridline,image,button,canvas,checkbutton,radiobutton].
-opt_prio() -> [x,y,width,height,move,coords,data].
-
-merge_types(Types) ->
- T2 = ordsets:from_list(Types),
- P2 = ordsets:from_list(obj_prio()),
- obj_prio() ++ ordsets:subtract(T2, P2).
-
-merge_opts([],L) -> L;
-merge_opts([Opt|Opts],Dict) ->
- case gs:assq(Opt,Dict) of
- {value,V} -> [{Opt,V}|merge_opts(Opts,lists:keydelete(Opt,1,Dict))];
- false -> merge_opts(Opts,Dict)
- end.
-
-the_config() ->
- Buttons=[button,checkbutton,radiobutton],
- AllPureTk = [Buttons,canvas,editor,entry,frame,label,listbox,
- menubar,menubutton,scale,window],
- CanvasObj = [arc,image,line,oval,polygon,rectangle,text],
- All = [AllPureTk,CanvasObj,grid,gridline,menu,menuitem,gs],
- Containers = [canvas,frame,grid,menu,menubar,menubutton,menuitem,window],
- Ob1 = [Buttons,canvas,grid,frame,label,entry,editor,listbox,scale],
- Ob2 = [button,checkbutton,radiobutton,label,menubutton],
- Ob3 = [Buttons,frame,label,entry,editor,listbox,scale,menubutton,
- menubar,menu],
- Ob4 = [canvas,editor,listbox],
- [{[Buttons,entry,scale,menubutton],enable,gen_enable,rw},
- {[Buttons,label,entry,scale,menubutton,menu],fg,gen_fg,rw},
- {[Buttons,label,entry,scale,menubutton,menu],bg,gen_bg,rw},
- {Ob1,anchor,gen_anchor,rw},
- {Ob1,height,gen_height,r},
- {Ob1--[frame],height,gen_height,w},
- {Ob1,width,gen_width,r},
- {Ob1--[frame],width,gen_width,w},
- {Ob1,pack_x,gen_pack_x,rw},
- {Ob1,pack_y,gen_pack_y,rw},
- {Ob1,pack_xy,gen_pack_xy,w},
- {Ob1,x,gen_x,rw},
- {Ob1,y,gen_y,rw},
- {Ob1,raise,gen_raise,w},
- {Ob1,lower,gen_lower,w},
- {Ob2,align,gen_align,rw},
- {Ob2,font,gen_font,rw},
- {Ob2,justify,gen_justify,rw},
- {Ob2,padx,gen_padx,rw},
- {Ob2,pady,gen_pady,rw},
- {Containers,default,gen_default,w},
- {[AllPureTk,menu],relief,gen_relief,rw},
- {[AllPureTk,menu],bw,gen_bw,rw},
- {[Buttons,canvas,frame,label,entry,scale,menubutton,menu,menubar],
- setfocus,gen_setfocus,rw},
- {Ob3,buttonpress,gen_buttonpress,rw},
- {Ob3,buttonrelease,gen_buttonrelease,rw},
- {Ob3,configure,gen_configure,rw},
- {[Ob3,window],destroy,gen_destroy,rw},
- {[Ob3,window],enter,gen_enter,rw},
- {[Ob3,window],leave,gen_leave,rw},
- {[Ob3,window],focus,gen_focus_ev,rw},
- {[Ob3,window],keypress,gen_keypress,rw},
- {[Ob3,window],keyrelease,gen_keyrelease,rw},
- {Ob3,motion,gen_motion,rw},
- %% events containing x,y are special
- {[window],buttonpress,gen_buttonpress,r},
- {[window],buttonrelease,gen_buttonrelease,r},
- {[window],motion,gen_motion,r},
- {All,font_wh,gen_font_wh,r},
- {All,choose_font,gen_choose_font,r},
- {All,data,gen_data,rw},
- {All,children,gen_children,r},
- {All,id,gen_id,r},
- {All,parent,gen_parent,r},
- {All,type,gen_type,r},
- {All,beep,gen_beep,w},
- {All,keep_opt,gen_keep_opt,w},
- {All,flush,gen_flush,rw},
- {AllPureTk,highlightbw,gen_highlightbw,rw},
- {AllPureTk,highlightbg,gen_highlightbg,rw},
- {AllPureTk,highlightfg,gen_highlightfg,rw},
- {AllPureTk,cursor,gen_cursor,rw}, % bug
- {[Buttons,label,menubutton],label,gen_label,rw},
- {[Buttons,menubutton,menu],activebg,gen_activebg,rw},
- {[Buttons,menubutton,menu],activefg,gen_activefg,rw},
- {[entry],selectbg,gen_selectbg,rw},
- {[entry],selectbw,gen_selectbw,rw},
- {[entry],selectfg,gen_selectfg,rw},
- {Ob4,activebg,gen_so_activebg,rw},
- {Ob4,bc,gen_so_bc,rw},
- {Ob4,bg,gen_so_bg,rw},
- {Ob4,hscroll,gen_so_hscroll,r},
- {Ob4,scrollbg,gen_so_scrollbg,rw},
- {Ob4,scrollfg,gen_so_scrollfg,rw},
- {Ob4,scrolls,gen_so_scrolls,w},
- {Ob4,selectbg,gen_so_selectbg,rw},
- {Ob4,selectbg,gen_so_selectbg,rw},
- {Ob4,selectbw,gen_so_selectbw,rw},
- {Ob4,selectbw,gen_so_selectbw,rw},
- {Ob4,selectfg,gen_so_selectfg,rw},
- {Ob4,selectfg,gen_so_selectfg,rw},
- {Ob4,vscroll,gen_so_vscroll,r},
- {CanvasObj,coords,gen_citem_coords,rw},
- {CanvasObj,lower,gen_citem_lower,w},
- {CanvasObj,raise,gen_citem_raise,w},
- {CanvasObj,move,gen_citem_move,w},
- {CanvasObj,setfocus,gen_citem_setfocus,rw},
- {CanvasObj,buttonpress,gen_citem_buttonpress,w}, % should be rw
- {CanvasObj,buttonrelease,gen_citem_buttonrelease,w},
- {CanvasObj,enter,gen_citem_enter,w},
- {CanvasObj,focus,gen_citem_setfocus,w},
- {CanvasObj,keypress,gen_citem_keypress,w},
- {CanvasObj,keyrelease,gen_citem_keyrelease,w},
- {CanvasObj,leave,gen_citem_leave,w},
- {CanvasObj,motion,gen_citem_motion,w},
- {CanvasObj,buttonpress,gen_buttonpress,r},
- {CanvasObj,buttonrelease,gen_buttonrelease,r},
- {CanvasObj,configure,gen_configure,r},
- {CanvasObj,destroy,gen_destroy,r},
- {CanvasObj,enter,gen_enter,r},
- {CanvasObj,leave,gen_leave,r},
- {CanvasObj,focus,gen_focus_ev,r},
- {CanvasObj,keypress,gen_keypress,r},
- {CanvasObj,keyrelease,gen_keyrelease,r},
- {CanvasObj,motion,gen_motion,r},
- {[arc,oval,polygon,rectangle],fill,gen_citem_fill,rw}].
-
diff --git a/lib/gs/src/gs_packer.erl b/lib/gs/src/gs_packer.erl
deleted file mode 100644
index d16849e4e9..0000000000
--- a/lib/gs/src/gs_packer.erl
+++ /dev/null
@@ -1,276 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Erlang Graphics Interface geometry manager caclulator
-%% ------------------------------------------------------------
-
-
--module(gs_packer).
-
--export([pack/2]).
-%-compile(export_all).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%
-%%%% This is a simple packer that take a specification in the format
-%%%%
-%%%% Spec -> [WidthSpec, WidthSpec....]
-%%%% WidthSpec -> {fixed,Size} | {stretch,Weight} |
-%%%% {stretch,Weight,Min} | {stretch,Weight,Min,Max}
-%%%%
-%%%% and a given total size it produces a list of sizes of the
-%%%% individual elements. Simple heuristics are used to make the code
-%%%% fast and simple.
-%%%%
-%%%% The Weight is simply a number that is the relative size to the
-%%%% other elements that has weights. If for example the weights
-%%%% for a frame that has three columns are 40 20 100 it means that
-%%%% column 1 has 40/160'th of the space, column 2 20/160'th of
-%%%% the space and column 3 100/160'th of the space.
-%%%%
-%%%% The program try to solve the equation with the constraints given.
-%%%% We have tree cases
-%%%%
-%%%% o We can fullfil the request in the space given
-%%%% o We have less space than needed
-%%%% o We have more space than allowed
-%%%%
-%%%% The algorithm is as follows:
-%%%%
-%%%% 1. Subtract the fixed size, nothing to do about that.
-%%%%
-%%%% 2. Calculate the Unit (or whatever it should be called), the
-%%%% given space minus the fixed sise divided by the Weights.
-%%%%
-%%%% 3. If we in total can fullfill the request we try to
-%%%% fullfill the individual constraints. See remove_failure/2.
-%%%%
-%%%% 4. If we have too little or too much pixels we take our
-%%%% specification and create a new more relaxed one. See
-%%%% cnvt_to_min/1 and cnvt_to_max/1.
-%%%%
-%%%% In general we adjust the specification and redo the whole process
-%%%% until we have a specification that meet the total constraints
-%%%% and individual constraints. When we know that the constraints
-%%%% are satisfied we finally call distribute_space/2 to set the
-%%%% resulting size values for the individual elements.
-%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-pack(Size, SpecSizes) when Size < 0 ->
- pack(0, SpecSizes);
-pack(Size, SpecSizes) ->
- {Weights,_Stretched,Fixed,Min,Max} = get_size_info(SpecSizes),
- Left = Size - Fixed,
- Unit = if Weights == 0 -> 0; true -> Left / Weights end,
- if
- Left < Min ->
- NewSpecs = cnvt_to_min(SpecSizes),
- pack(Size,NewSpecs);
- is_integer(Max), Max =/= 0, Left > Max ->
- NewSpecs = cnvt_to_max(SpecSizes),
- pack(Size,NewSpecs);
- true ->
- case remove_failure(SpecSizes, Unit) of
- {no,NewSpecs} ->
- distribute_space(NewSpecs,Unit);
- {yes,NewSpecs} ->
- pack(Size, NewSpecs)
- end
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%
-%%%% remove_failure(Specs, Unit)
-%%%%
-%%%% We know that we in total have enough space to fit within the total
-%%%% maximum and minimum requirements. But we have to take care of
-%%%% individual minimum and maximum requirements.
-%%%%
-%%%% This is done with a simple heuristic. We pick the element that
-%%%% has the largest diff from the required min or max, change this
-%%%% {stretch,W,Mi,Ma} to a {fixed,Mi} or {fixed,Ma} and redo the
-%%%% whole process again.
-%%%%
-%%%% **** BUGS ****
-%%%% No known. But try to understand this function and you get a medal ;-)
-%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-remove_failure(Specs, Unit) ->
- case remove_failure(Specs, Unit, 0) of
- {done,NewSpecs} ->
- {yes,NewSpecs};
- {_,_NewSpecs} ->
- {no,Specs} % NewSpecs == Specs but
- end. % we choose the old one
-
-remove_failure([], _Unit, MaxFailure) ->
- {MaxFailure,[]};
-remove_failure([{stretch,W,Mi} | Specs], Unit, MaxFailure) ->
- {MinMax,NewMaxFailure} = max_failure(MaxFailure, Mi-W*Unit, 0),
- case {MinMax,remove_failure(Specs, Unit, NewMaxFailure)} of
- {min,{NewMaxFailure,Rest}} ->
- {done,[{fixed,Mi} | Rest]};
- {_,{OtherMaxFailure, Rest}} ->
- {OtherMaxFailure,[{stretch,W,Mi} | Rest]}
- end;
-remove_failure([{stretch,W,Mi,Ma} | Specs], Unit, MaxFailure) ->
- {MinMax,NewMaxFailure} = max_failure(MaxFailure, Mi-W*Unit, W*Unit-Ma),
- case {MinMax,remove_failure(Specs, Unit, NewMaxFailure)} of
- {min,{NewMaxFailure,Rest}} ->
- {done,[{fixed,Mi} | Rest]};
- {max,{NewMaxFailure,Rest}} ->
- {done,[{fixed,Ma} | Rest]};
- {_,{OtherMaxFailure, Rest}} ->
- {OtherMaxFailure,[{stretch,W,Mi,Ma} | Rest]}
- end;
-remove_failure([Spec | Specs], Unit, MaxFailure) ->
- {NewMaxFailure,NewSpecs} = remove_failure(Specs, Unit, MaxFailure),
- {NewMaxFailure, [Spec | NewSpecs]}.
-
-max_failure(LastDiff, DMi, DMa)
- when DMi > LastDiff, DMi > DMa ->
- {min,DMi};
-max_failure(LastDiff, _DMi, DMa)
- when DMa > LastDiff ->
- {max,DMa};
-max_failure(MaxFailure, _DMi, _DMa) ->
- {other,MaxFailure}.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%
-%%%% distribute_space(Spec,Unit)
-%%%%
-%%%% We now know that we can distribute the space to the elements in
-%%%% the list.
-%%%%
-%%%% **** BUGS ****
-%%%% No known bugs. It try hard to distribute the pixels so that
-%%%% there should eb no pixels left when done but there is no proof
-%%%% that this is the case. The distribution of pixels may also
-%%%% not be optimal. The rounding error from giving one element some
-%%%% pixels is added to the next even if it would be better to add
-%%%% it to an element later in the list (for example the weights
-%%%% 1000, 2, 1000). But this should be good enough.
-%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-distribute_space(Specs, Unit) ->
- distribute_space(Specs, Unit, 0.0).
-
-distribute_space([], _Unit, _Err) ->
- [];
-distribute_space([Spec | Specs], Unit, Err) ->
- distribute_space(Spec, Specs, Unit, Err).
-
-distribute_space({fixed,P}, Specs, Unit, Err) ->
- [P | distribute_space(Specs, Unit, Err)];
-distribute_space({stretch,Weight}, Specs, Unit, Err) ->
- Size = Weight * Unit + Err,
- Pixels = round(Size),
- NewErr = Size - Pixels,
- [Pixels | distribute_space(Specs, Unit, NewErr)];
-distribute_space({stretch,W,_Mi}, Specs, Unit, Err) ->
- distribute_space({stretch,W}, Specs, Unit, Err);
-distribute_space({stretch,W,_Mi,_Ma}, Specs, Unit, Err) ->
- distribute_space({stretch,W}, Specs, Unit, Err).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%
-%%%% cnvt_to_min(Spec)
-%%%% cnvt_to_max(Spec)
-%%%%
-%%%% If the space we got isn't enough for the total minimal or maximal
-%%%% requirements then we convert the specification to a more relaxed
-%%%% one that we always can satisfy.
-%%%%
-%%%% This is fun! We do a simple transformation from one specification
-%%%% to a new one. The min, max and fixed size are our new weights!
-%%%% This way the step from a specification we can satisfy and one
-%%%% close that we can't is only a few pixels away, i.e. the transition
-%%%% from within the constraints and outside will be smooth.
-%%%%
-%%%% **** BUGS ****
-%%%% No known bugs.
-%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-cnvt_to_min([]) ->
- [];
-cnvt_to_min([Spec | Specs]) ->
- cnvt_to_min(Spec, Specs).
-
-cnvt_to_max([]) ->
- [];
-cnvt_to_max([Spec | Specs]) ->
- cnvt_to_max(Spec, Specs).
-
-cnvt_to_min({fixed,P}, Specs) ->
- [{stretch,P} | cnvt_to_min(Specs)];
-cnvt_to_min({stretch,_W}, Specs) ->
- [{fixed,0} | cnvt_to_min(Specs)];
-cnvt_to_min({stretch,_W,Mi}, Specs) ->
- [{stretch,Mi} | cnvt_to_min(Specs)];
-cnvt_to_min({stretch,_W,Mi,_Ma}, Specs) ->
- [{stretch,Mi} | cnvt_to_min(Specs)].
-
-%% We know that there can only be {fixed,P} and {stretch,W,Mi,Ma}
-%% in this list.
-
-cnvt_to_max({fixed,P}, Specs) ->
- [{stretch,P} | cnvt_to_max(Specs)];
-cnvt_to_max({stretch,_W,_Mi,Ma}, Specs) ->
- [{stretch,Ma} | cnvt_to_max(Specs)].
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%
-%%%% Sum the Weights, Min and Max etc
-%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-get_size_info(Specs) ->
- get_size_info(Specs, 0, 0, 0, 0, 0).
-
-get_size_info([], TotW, NumW, TotFixed, TotMin, TotMax) ->
- {TotW, NumW, TotFixed, TotMin, TotMax};
-get_size_info([Spec | Specs], TotW, NumW, TotFixed, TotMin, TotMax) ->
- get_size_info(Spec, TotW, NumW, TotFixed, TotMin, TotMax, Specs).
-
-get_size_info({fixed,P}, TotW, NumW, TotFixed, TotMin, TotMax, Specs) ->
- get_size_info(Specs, TotW, NumW, TotFixed+P, TotMin, TotMax);
-get_size_info({stretch,W}, TotW, NumW, TotFixed, TotMin, _TotMax, Specs) ->
- get_size_info(Specs, TotW+W, NumW+1, TotFixed, TotMin, infinity);
-get_size_info({stretch,W,Mi}, TotW, NumW, TotFixed, TotMin, _TotMax, Specs) ->
- get_size_info(Specs, TotW+W, NumW+1, TotFixed, TotMin+Mi, infinity);
-get_size_info({stretch,W,Mi,_Ma}, TotW, NumW, TotFixed, TotMin, infinity, Specs) ->
- get_size_info(Specs, TotW+W, NumW+1, TotFixed, TotMin+Mi, infinity);
-get_size_info({stretch,W,Mi,Ma}, TotW, NumW, TotFixed, TotMin, TotMax, Specs) ->
- get_size_info(Specs, TotW+W, NumW+1, TotFixed, TotMin+Mi, TotMax+Ma).
diff --git a/lib/gs/src/gs_widgets.erl b/lib/gs/src/gs_widgets.erl
deleted file mode 100644
index f0351049f9..0000000000
--- a/lib/gs/src/gs_widgets.erl
+++ /dev/null
@@ -1,99 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Widget specific data
-%% ------------------------------------------------------------
-%%
-
--module(gs_widgets).
-
-
-%% ----- Exports -----
--export([default_options/1,
- container/1]).
-
-
-%% ------------------------------------------------------------
-%% default_options for widgets
-%% Keep the options in the list sorted!
-%% ------------------------------------------------------------
-
-default_options(arc) -> [{coords, [{0,0}, {0,0}]}];
-default_options(button) -> [{click,true}, {height,30}, {width,100}, {x,0},
- {y,0}];
-default_options(canvas) -> [{height,200}, {scrollregion,{0,0,300,200}},
- {width,300}, {x,0}, {y,0}];
-default_options(checkbutton) -> [{click,true}, {height,30}, {width,100}, {x,0},
- {y,0}];
-default_options(editor) -> [{height,200}, {width,300}, {x,0}, {y,0}];
-default_options(entry) -> [{height,30}, {width,100}, {x,0}, {y,0}];
-default_options(frame) -> [{height,100}, {width,150}, {x,0}, {y,0}];
-default_options(grid) -> [{bg,grey}, {cellheight,20},
- {columnwidths, [80,80,80,80]},
- {fg,black}, {font,{screen, 12}},
- {height,100},
- {hscroll,bottom},
- {rows,{1,10}},
- {vscroll,right},
- {width,300},
- {x,0}, {y,0}];
- % Keep the options in the list sorted!
-default_options(gridline) -> [{click,true}, {doubleclick,false}, {row,undefined}];
-default_options(gs) -> [{kernel,false},
- {{default,all,font}, {screen,12}}];
-default_options(image) -> [{anchor,nw}, {coords,[{0,0}]}];
-default_options(label) -> [{height,30}, {width,100}, {x,0}, {y,0}];
-default_options(line) -> [{coords, [{-1,-1},{-1,-1}]}];
-default_options(listbox) -> [{height,130}, {hscroll,true},
- {selectmode,single}, {vscroll,true},
- {width,125}, {x,0}, {y,0}];
-default_options(menu) -> [];
- % Keep the options in the list sorted!
-default_options(menubar) -> [{bw,2}, {height,25}, {highlightbw,0},
- {relief,raised}];
-default_options(menubutton) -> [{anchor,nw}, {side,left}];
-default_options(menuitem) -> [{click,true}, {index,last}, {itemtype,normal}];
-default_options(message) -> [{height,75}, {width,100}];
-default_options(oval) -> [{coords, [{0,0},{0,0}]}];
-default_options(polygon) -> [{coords, [{0,0},{0,0}]}, {fg,black}, {fill,none}];
-default_options(prompter) -> [{height,200}, {prompt,[]}, {width,300}];
-default_options(radiobutton) -> [{click,true}, {height,30}, {width,100},
- {x,0}, {y,0}];
-default_options(rectangle) -> [{coords, [{0,0},{0,0}]}];
-default_options(scale) -> [{click,true}, {height,50}, {width,100},
- {x,0}, {y,0}];
- % Keep the options in the list sorted!
-default_options(scrollbar) -> [];
-default_options(text) -> [{anchor,nw}, {coords,[{0,0}]}, {justify,left}];
-default_options(window) -> [{configure,false}, {cursor,arrow}, {destroy,true},
- {height,200}, {map,false}, {width,300}];
-default_options(_) -> [].
-
-container(canvas) -> true;
-container(frame) -> true;
-container(grid) -> true;
-container(menu) -> true;
-container(menubar) -> true;
-container(menubutton) -> true;
-container(menuitem) -> true;
-container(window) -> true;
-container(_) -> false.
diff --git a/lib/gs/src/gse.erl b/lib/gs/src/gse.erl
deleted file mode 100644
index 10fb341894..0000000000
--- a/lib/gs/src/gse.erl
+++ /dev/null
@@ -1,788 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%%%----------------------------------------------------------------------
-%%% Purpose : Wrapper library for GS to provide proper error handling
-%%%----------------------------------------------------------------------
-
--module(gse).
--compile([{nowarn_deprecated_function,{gs,arc,2}},
- {nowarn_deprecated_function,{gs,arc,3}},
- {nowarn_deprecated_function,{gs,button,2}},
- {nowarn_deprecated_function,{gs,button,3}},
- {nowarn_deprecated_function,{gs,canvas,2}},
- {nowarn_deprecated_function,{gs,canvas,3}},
- {nowarn_deprecated_function,{gs,checkbutton,2}},
- {nowarn_deprecated_function,{gs,checkbutton,3}},
- {nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,create,3}},
- {nowarn_deprecated_function,{gs,create,4}},
- {nowarn_deprecated_function,{gs,create_tree,2}},
- {nowarn_deprecated_function,{gs,destroy,1}},
- {nowarn_deprecated_function,{gs,editor,2}},
- {nowarn_deprecated_function,{gs,editor,3}},
- {nowarn_deprecated_function,{gs,entry,2}},
- {nowarn_deprecated_function,{gs,entry,3}},
- {nowarn_deprecated_function,{gs,frame,2}},
- {nowarn_deprecated_function,{gs,frame,3}},
- {nowarn_deprecated_function,{gs,grid,2}},
- {nowarn_deprecated_function,{gs,grid,3}},
- {nowarn_deprecated_function,{gs,gridline,2}},
- {nowarn_deprecated_function,{gs,gridline,3}},
- {nowarn_deprecated_function,{gs,image,2}},
- {nowarn_deprecated_function,{gs,image,3}},
- {nowarn_deprecated_function,{gs,label,2}},
- {nowarn_deprecated_function,{gs,label,3}},
- {nowarn_deprecated_function,{gs,line,2}},
- {nowarn_deprecated_function,{gs,line,3}},
- {nowarn_deprecated_function,{gs,listbox,2}},
- {nowarn_deprecated_function,{gs,listbox,3}},
- {nowarn_deprecated_function,{gs,menu,2}},
- {nowarn_deprecated_function,{gs,menu,3}},
- {nowarn_deprecated_function,{gs,menubar,2}},
- {nowarn_deprecated_function,{gs,menubar,3}},
- {nowarn_deprecated_function,{gs,menubutton,2}},
- {nowarn_deprecated_function,{gs,menubutton,3}},
- {nowarn_deprecated_function,{gs,menuitem,2}},
- {nowarn_deprecated_function,{gs,menuitem,3}},
- {nowarn_deprecated_function,{gs,message,2}},
- {nowarn_deprecated_function,{gs,message,3}},
- {nowarn_deprecated_function,{gs,oval,2}},
- {nowarn_deprecated_function,{gs,oval,3}},
- {nowarn_deprecated_function,{gs,polygon,2}},
- {nowarn_deprecated_function,{gs,polygon,3}},
- {nowarn_deprecated_function,{gs,prompter,2}},
- {nowarn_deprecated_function,{gs,prompter,3}},
- {nowarn_deprecated_function,{gs,radiobutton,2}},
- {nowarn_deprecated_function,{gs,radiobutton,3}},
- {nowarn_deprecated_function,{gs,read,2}},
- {nowarn_deprecated_function,{gs,rectangle,2}},
- {nowarn_deprecated_function,{gs,rectangle,3}},
- {nowarn_deprecated_function,{gs,scale,2}},
- {nowarn_deprecated_function,{gs,scale,3}},
- {nowarn_deprecated_function,{gs,scrollbar,2}},
- {nowarn_deprecated_function,{gs,scrollbar,3}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,start,1}},
- {nowarn_deprecated_function,{gs,text,2}},
- {nowarn_deprecated_function,{gs,text,3}},
- {nowarn_deprecated_function,{gs,window,2}},
- {nowarn_deprecated_function,{gs,window,3}}]).
-
-%%-compile(export_all).
--export([
- start/0,
- start/1,
- create/3,
- create_named/4,
- config/2,
- read/2,
- destroy/1,
- create_tree/2,
- window/2,
- named_window/3,
- button/2,
- named_button/3,
- checkbutton/2,
- named_checkbutton/3,
- radiobutton/2,
- named_radiobutton/3,
- frame/2,
- named_frame/3,
- canvas/2,
- named_canvas/3,
- label/2,
- named_label/3,
- message/2,
- named_message/3,
- listbox/2,
- named_listbox/3,
- entry/2,
- named_entry/3,
- scrollbar/2,
- named_scrollbar/3,
- scale/2,
- named_scale/3,
- editor/2,
- named_editor/3,
- prompter/2,
- named_prompter/3,
- line/2,
- named_line/3,
- oval/2,
- named_oval/3,
- rectangle/2,
- named_rectangle/3,
- polygon/2,
- named_polygon/3,
- text/2,
- named_text/3,
- image/2,
- named_image/3,
- arc/2,
- named_arc/3,
- menu/2,
- named_menu/3,
- menubutton/2,
- named_menubutton/3,
- menubar/2,
- named_menubar/3,
- menuitem/2,
- named_menuitem/3,
- grid/2,
- named_grid/3,
- gridline/2,
- named_gridline/3,
- %% Convenience functions
- enable/1,
- disable/1,
- select/1,
- deselect/1,
- map/1,
- unmap/1,
- resize/3,
- name_occupied/1
-
- ]).
-
-
-%%
-%% gse:start()
-%% Returns:
-%% An identifier to a top object for the graphic system
-%%
-%% Errors:
-%% Exits with a {?MODULE,start,Reason} if there is a problem
-%% creating the top level graphic object.
-%%
-
-
-start() ->
- case gs:start() of
- {error,Reason} ->
- exit({?MODULE, start,Reason});
- Return -> Return
- end.
-
-%%
-%% gse:start(Opts)
-%% Returns:
-%% An identifier to a top object for the graphic system
-%%
-%% Errors:
-%% Exits with a {?MODULE,start,Reason} if there is a problem
-%% creating the top level graphic object.
-%%
-
-
-start(Opts) ->
- case gs:start(Opts) of
- {error,Reason} ->
- exit({?MODULE, start,Reason});
- Return -> Return
- end.
-
-%%
-%% gse:create(Objtype,Parent,Opts) replaces
-%% the unnecessary functions:
-%% gs:create(Obj,Parent)
-%% gs:create(Obj,Parent,Opt)
-%% gs:create(Obj,Parent)
-%% gs:create(Obj,Parent)
-%%
-%% Returns:
-%% An identifier for the created object
-%%
-%% Errors: {?MODULE, create, Reason}, where Reason is one of:
-%% {no_such_parent, Parent}
-%% {unknown_type, Type}
-%% {incvalid_option, Type, {Option,Value}}
-%%
-%%
-create(Objtype,Parent,Opts) when is_list(Opts) ->
- case gs:create(Objtype,Parent,Opts) of
- {error,Reason} ->
- exit({?MODULE, create,Reason});
- Return -> Return
- end.
-
-
-%%
-%% gse:create_named(Name, Objtype,Parent, Opts) replaces
-%% the confusing
-%% gs:create(Name,Objtype, Parent, Opts)
-%%
-%% Returns:
-%% An identifier for the created object
-%%
-%% Errors: {?MODULE, create, Reason}, where Reason is one of:
-%% {no_such_parent, Parent}
-%% {unknown_type, Type}
-%% {incvalid_option, Type, {Option,Value}}
-%% {name_occupied,Name}
-%%
-
-create_named(Name,Objtype,Parent,Opts) when is_list(Opts) ->
- case gs:create(Objtype,Name,Parent,Opts) of
- {error,Reason} ->
- exit({?MODULE, create_named,Reason});
- Return -> Return
- end.
-
-
-
-%%
-%% gse:config(Object, Options) replaces
-%% the unnecessary
-%% gs:config(Object, Opt)
-%%
-
-config(Object,Opts) when is_list(Opts) ->
- case gs:config(Object,Opts) of
- {error,Reason} ->
- exit({?MODULE, config,Reason});
- Return -> Return
- end.
-
-%%
-%% gs:read(Object, OptionKey)
-%%
-read(Object,OptionKey) ->
- case gs:read(Object,OptionKey) of
- {error,Reason} ->
- exit({?MODULE, read,Reason});
- Return -> Return
- end.
-
-%%
-%% gs:destroy(Object)
-%%
-
-destroy(Object)->
- case gs:destroy(Object) of
- {error,Reason} ->
- exit({?MODULE, destroy,Reason});
- Return -> Return
- end.
-
-%%
-%% gs:create_tree
-%%
-
-create_tree(Parent, Tree)->
- case gs:create_tree(Parent,Tree) of
- {error,Reason} ->
- exit({?MODULE, create_tree,Reason});
- Return -> Return
- end.
-
-
-window(Parent,Options) when is_list(Options) ->
- case gs:window(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,window,Reason});
- Return -> Return
- end.
-
-named_window(Name,Parent,Options) when is_list(Options) ->
- case gs:window(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_window,Reason});
- Return -> Return
- end.
-
-
-button(Parent,Options) when is_list(Options) ->
- case gs:button(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,button,Reason});
- Return -> Return
- end.
-
-
-named_button(Name,Parent,Options) when is_list(Options) ->
- case gs:button(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_button,Reason});
- Return -> Return
- end.
-
-
-checkbutton(Parent,Options) when is_list(Options) ->
- case gs:checkbutton(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,checkbutton,Reason});
- Return -> Return
- end.
-
-
-named_checkbutton(Name,Parent,Options) when is_list(Options) ->
- case gs:checkbutton(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_checkbutton,Reason});
- Return -> Return
- end.
-
-
-radiobutton(Parent,Options) when is_list(Options) ->
- case gs:radiobutton(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,radiobutton,Reason});
- Return -> Return
- end.
-
-
-named_radiobutton(Name,Parent,Options) when is_list(Options) ->
- case gs:radiobutton(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_radiobutton,Reason});
- Return -> Return
- end.
-
-
-frame(Parent,Options) when is_list(Options) ->
- case gs:frame(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,frame,Reason});
- Return -> Return
- end.
-
-
-named_frame(Name,Parent,Options) when is_list(Options) ->
- case gs:frame(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_frame,Reason});
- Return -> Return
- end.
-
-
-canvas(Parent,Options) when is_list(Options) ->
- case gs:canvas(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,canvas,Reason});
- Return -> Return
- end.
-
-
-named_canvas(Name,Parent,Options) when is_list(Options) ->
- case gs:canvas(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_canvas,Reason});
- Return -> Return
- end.
-
-
-label(Parent,Options) when is_list(Options) ->
- case gs:label(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,label,Reason});
- Return -> Return
- end.
-
-
-named_label(Name,Parent,Options) when is_list(Options) ->
- case gs:label(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_label,Reason});
- Return -> Return
- end.
-
-
-message(Parent,Options) when is_list(Options) ->
- case gs:message(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,message,Reason});
- Return -> Return
- end.
-
-
-named_message(Name,Parent,Options) when is_list(Options) ->
- case gs:message(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_message,Reason});
- Return -> Return
- end.
-
-
-listbox(Parent,Options) when is_list(Options) ->
- case gs:listbox(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,listbox,Reason});
- Return -> Return
- end.
-
-
-named_listbox(Name,Parent,Options) when is_list(Options) ->
- case gs:listbox(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_listbox,Reason});
- Return -> Return
- end.
-
-
-entry(Parent,Options) when is_list(Options) ->
- case gs:entry(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,entry,Reason});
- Return -> Return
- end.
-
-
-named_entry(Name,Parent,Options) when is_list(Options) ->
- case gs:entry(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_entry,Reason});
- Return -> Return
- end.
-
-
-scrollbar(Parent,Options) when is_list(Options) ->
- case gs:scrollbar(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,scrollbar,Reason});
- Return -> Return
- end.
-
-
-named_scrollbar(Name,Parent,Options) when is_list(Options) ->
- case gs:scrollbar(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_scrollbar,Reason});
- Return -> Return
- end.
-
-
-scale(Parent,Options) when is_list(Options) ->
- case gs:scale(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,scale,Reason});
- Return -> Return
- end.
-
-
-named_scale(Name,Parent,Options) when is_list(Options) ->
- case gs:scale(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_scale,Reason});
- Return -> Return
- end.
-
-
-editor(Parent,Options) when is_list(Options) ->
- case gs:editor(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,editor,Reason});
- Return -> Return
- end.
-
-
-named_editor(Name,Parent,Options) when is_list(Options) ->
- case gs:editor(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_editor,Reason});
- Return -> Return
- end.
-
-
-prompter(Parent,Options) when is_list(Options) ->
- case gs:prompter(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,prompter,Reason});
- Return -> Return
- end.
-
-
-named_prompter(Name,Parent,Options) when is_list(Options) ->
- case gs:prompter(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_prompter,Reason});
- Return -> Return
- end.
-
-
-line(Parent,Options) when is_list(Options) ->
- case gs:line(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,line,Reason});
- Return -> Return
- end.
-
-
-named_line(Name,Parent,Options) when is_list(Options) ->
- case gs:line(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_line,Reason});
- Return -> Return
- end.
-
-
-oval(Parent,Options) when is_list(Options) ->
- case gs:oval(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,oval,Reason});
- Return -> Return
- end.
-
-
-named_oval(Name,Parent,Options) when is_list(Options) ->
- case gs:oval(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_oval,Reason});
- Return -> Return
- end.
-
-
-rectangle(Parent,Options) when is_list(Options) ->
- case gs:rectangle(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,rectangle,Reason});
- Return -> Return
- end.
-
-
-named_rectangle(Name,Parent,Options) when is_list(Options) ->
- case gs:rectangle(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_rectangle,Reason});
- Return -> Return
- end.
-
-
-polygon(Parent,Options) when is_list(Options) ->
- case gs:polygon(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,polygon,Reason});
- Return -> Return
- end.
-
-
-named_polygon(Name,Parent,Options) when is_list(Options) ->
- case gs:polygon(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_polygon,Reason});
- Return -> Return
- end.
-
-
-text(Parent,Options) when is_list(Options) ->
- case gs:text(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,text,Reason});
- Return -> Return
- end.
-
-
-named_text(Name,Parent,Options) when is_list(Options) ->
- case gs:text(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_text,Reason});
- Return -> Return
- end.
-
-
-image(Parent,Options) when is_list(Options) ->
- case gs:image(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,image,Reason});
- Return -> Return
- end.
-
-
-named_image(Name,Parent,Options) when is_list(Options) ->
- case gs:image(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_image,Reason});
- Return -> Return
- end.
-
-
-arc(Parent,Options) when is_list(Options) ->
- case gs:arc(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,arc,Reason});
- Return -> Return
- end.
-
-
-named_arc(Name,Parent,Options) when is_list(Options) ->
- case gs:arc(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_arc,Reason});
- Return -> Return
- end.
-
-
-menu(Parent,Options) when is_list(Options) ->
- case gs:menu(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,menu,Reason});
- Return -> Return
- end.
-
-
-named_menu(Name,Parent,Options) when is_list(Options) ->
- case gs:menu(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_menu,Reason});
- Return -> Return
- end.
-
-
-menubutton(Parent,Options) when is_list(Options) ->
- case gs:menubutton(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,menubutton,Reason});
- Return -> Return
- end.
-
-
-named_menubutton(Name,Parent,Options) when is_list(Options) ->
- case gs:menubutton(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_menubutton,Reason});
- Return -> Return
- end.
-
-
-menubar(Parent,Options) when is_list(Options) ->
- case gs:menubar(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,menubar,Reason});
- Return -> Return
- end.
-
-
-named_menubar(Name,Parent,Options) when is_list(Options) ->
- case gs:menubar(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_menubar,Reason});
- Return -> Return
- end.
-
-
-menuitem(Parent,Options) when is_list(Options) ->
- case gs:menuitem(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,menuitem,Reason});
- Return -> Return
- end.
-
-
-named_menuitem(Name,Parent,Options) when is_list(Options) ->
- case gs:menuitem(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_menuitem,Reason});
- Return -> Return
- end.
-
-
-grid(Parent,Options) when is_list(Options) ->
- case gs:grid(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,grid,Reason});
- Return -> Return
- end.
-
-
-named_grid(Name,Parent,Options) when is_list(Options) ->
- case gs:grid(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_grid,Reason});
- Return -> Return
- end.
-
-
-gridline(Parent,Options) when is_list(Options) ->
- case gs:gridline(Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,gridline,Reason});
- Return -> Return
- end.
-
-
-named_gridline(Name,Parent,Options) when is_list(Options) ->
- case gs:gridline(Name, Parent,Options) of
- {error, Reason} ->
- exit({?MODULE,named_gridline,Reason});
- Return -> Return
- end.
-
-
-
-%% gs:config - Utility functions
-
-
-%%
-%% enable/disable
-%%
-
-enable(Object) ->
- gse:config(Object,[{enable,true}]).
-
-disable(Object) ->
- gse:config(Object,[{enable,false}]).
-
-
-
-%%
-%% select/deselect
-%%
-
-deselect(Object) ->
- gse:config(Object,[{select,false}]).
-
-select(Object) ->
- gse:config(Object,[{select,true}]).
-
-
-%%
-%% map/unmap
-%%
-
-map(Object) ->
- gse:config(Object,[{map,true}]).
-
-unmap(Object) ->
- gse:config(Object,[{map,false}]).
-
-
-
-%%
-%% resize
-%%
-
-resize(Object, Width, Height) ->
- gse:config(Object,[{width,Width}, {height, Height}]).
-
-
-
-%%
-%% Misc utility functions
-%%
-
-name_occupied(Name) ->
- case gs:read(Name,id) of
- {error,_Reason} ->
- false;
- _Id -> true
- end.
-
-
diff --git a/lib/gs/src/gstk.erl b/lib/gs/src/gstk.erl
deleted file mode 100644
index 3119245db7..0000000000
--- a/lib/gs/src/gstk.erl
+++ /dev/null
@@ -1,389 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-
--module(gstk).
--compile([{nowarn_deprecated_function,{gs,assq,2}},
- {nowarn_deprecated_function,{gs,creation_error,2}}]).
-
--export([start_link/4,
- stop/1,
- create/2,
- config/2,
- read/2,
- destroy/2,
- pid_died/2,
- event/2,
- request/2,
- init/1,
- create_impl/2,
- config_impl/3,
- read_impl/3,
- destroy_impl/2,
- worker_init/1,
- worker_do/1,
- make_extern_id/2,
- to_color/1,
- to_ascii/1,
- exec/1,
- call/1]).
-
--include("gstk.hrl").
-
-start_link(GsId,FrontendNode,Owner,Options) ->
- case gs:assq(node,Options) of
- false ->
- Gstk = spawn_link(gstk, init,[{GsId, FrontendNode, Owner, Options}]),
- receive
- {ok, _PortHandler} ->
- {ok, Gstk};
- {error, Reason} ->
- {error, Reason}
- end;
- {value, Node} ->
- rpc:call(Node,gen_server,start_link,[gstk, {Owner,Options},[]])
- end.
-
-stop(BackendServ) ->
- request(BackendServ,stop).
-
-create(BackendServ,Args) ->
- request(BackendServ,{create,Args}).
-
-config(BackendServ,Args) ->
- request(BackendServ,{config,Args}).
-
-read(BackendServ,Args) ->
- request(BackendServ,{read,Args}).
-
-destroy(BackendServ,Args) ->
- request(BackendServ,{destroy,Args}).
-
-pid_died(BackendServ,Pid) ->
- request(BackendServ,{pid_died,Pid}).
-
-call(Cmd) ->
- %%io:format("Call:~p~n",[Cmd]),
- gstk_port_handler:call(get(port_handler),Cmd).
-
-exec(Cmd) ->
- gstk_port_handler:exec(Cmd).
-
-make_extern_id(IntId, DB) ->
- [{_,Node}] = ets:lookup(DB,frontend_node),
- {IntId,Node}.
-
-event(BackendServ,Event) ->
- BackendServ!{event,Event}.
-
-%% -----------------------------------------------------------------------------
-
-request(Who,Msg) ->
- Who ! {self(),Msg},
- receive
- {gstk_reply,R} -> R;
- {'EXIT',Who,Reason} ->
- self() ! {'EXIT',Who,Reason},
- {error,Reason}
- end.
-
-
--record(state,{db,frontendnode,port_handler}).
-
-%% ------------------------------------------------------------
-%% Initialize
-%%
-init({GsId,FrontendNode,Owner,Opts}) ->
- put(gs_frontend,Owner),
- case gstk_port_handler:start_link(self()) of
- {error, Reason} ->
- FrontendNode ! {error, Reason},
- exit(normal);
- {ok, PortHandler} ->
- FrontendNode ! {ok, PortHandler},
- put(port_handler,PortHandler),
- {ok,Port} = gstk_port_handler:ping(PortHandler),
- put(port,Port),
- exec("wm withdraw ."),
- DB = gstk_db:init(Opts),
- ets:insert(DB,{frontend_node,FrontendNode}),
- put(worker,spawn_link(gstk,worker_init,[0])),
- Gstkid = #gstkid{id=GsId,widget="",owner=Owner,objtype=gs},
- gstk_db:insert_gs(DB,Gstkid),
- gstk_font:init(),
- loop(#state{db=DB,frontendnode=FrontendNode})
- end.
-
-loop(State) ->
- receive
- X ->
- case (doit(X,State)) of
- done -> loop(State);
- stop -> bye
- end
- end.
-
-reply(To,Msg) ->
- To ! {gstk_reply,Msg},
- done.
-
-doit({From,{config, {Id, Opts}}},#state{db=DB}) ->
- reply(From,config_impl(DB,Id,Opts));
-doit({From,{create, Args}}, #state{db=DB}) ->
- reply(From,create_impl(DB,Args));
-doit({From,{read,{Id,Opt}}},#state{db=DB}) ->
- reply(From,read_impl(DB,Id,Opt));
-doit({From,{pid_died, Pid}}, #state{db=DB}) ->
- pid_died_impl(DB, Pid),
- reply(From,gstk_db:get_deleted(DB));
-doit({From,{destroy, Id}}, #state{db=DB}) ->
- destroy_impl(DB, gstk_db:lookup_gstkid(DB,Id)),
- reply(From,gstk_db:get_deleted(DB));
-
-doit({From,dump_db},State) ->
- io:format("gstk_db:~p~n",[lists:sort(ets:tab2list(State#state.db))]),
- io:format("events:~p~n",[lists:sort(ets:tab2list(get(events)))]),
- io:format("options:~p~n",[lists:sort(ets:tab2list(get(options)))]),
- io:format("defaults:~p~n",[lists:sort(ets:tab2list(get(defaults)))]),
- io:format("kids:~p~n",[lists:sort(ets:tab2list(get(kids)))]),
- reply(From,State);
-
-doit({From,stop},_State) ->
- gstk_port_handler:stop(get(port_handler)),
- exit(get(worker),kill),
- reply(From,stopped),
- stop;
-
-doit({event,{Id, Etag, Args}},#state{db=DB}) ->
- case gstk_db:lookup_event(DB, Id, Etag) of
- {Etype, Edata} ->
- Gstkid = gstk_db:lookup_gstkid(DB, Id),
- apply(gstk_widgets:objmod(Gstkid),event,[DB,Gstkid,Etype,Edata,Args]);
- _ -> true
- end,
- done.
-
-
-%%----------------------------------------------------------------------
-%% Implementation of create,config,read,destroy
-%% Comment: In the gstk process there is not concept call 'name', only
-%% pure oids. Names are stripped of by 'gs' and this simplifies
-%% gstk a lot.
-%% Comment: For performance reasons gstk.erl ans gs.erl communicats through
-%% tuples. This is unfortunate but we don't want to pack the same
-%% thing too many times.
-%% Pre (for all functions): GS guarantees that the object (and parent if
-%% necessary) exists.
-%%----------------------------------------------------------------------
-
-
-create_impl(DB, {Owner, {Objtype, Id, Parent, Opts}}) ->
- Pgstkid = gstk_db:lookup_gstkid(DB, Parent),
- GstkId=#gstkid{id=Id,owner=Owner,parent=Parent,objtype=Objtype},
- gstk_db:insert_opt(DB,Id,{data,[]}),
- RealOpts=apply(gstk_widgets:objmod(Pgstkid),
- mk_create_opts_for_child,[DB,GstkId,Pgstkid,Opts]),
- case gstk_widgets:type2mod(Objtype) of
- {error,Reason} -> {error,Reason};
- ObjMod ->
- case apply(ObjMod, create, [DB, GstkId, RealOpts]) of
- {bad_result, BR} ->
- gstk_db:delete_gstkid(DB,GstkId),
- gs:creation_error(GstkId,{bad_result, BR});
- Ngstkid when is_record(Ngstkid,gstkid) ->
- gstk_db:insert_widget(DB, Ngstkid),
- ok;
- {error,Reason} -> {error,Reason};
- ok -> ok
- end
- end.
-
-config_impl(DB,Id,Opts) ->
- Gstkid = gstk_db:lookup_gstkid(DB, Id),
- case apply(gstk_widgets:objmod(Gstkid), config, [DB, Gstkid, Opts]) of
- ok -> ok;
- {bad_result,R} -> {error,R};
- {error,Reason} -> {error,Reason};
- Q -> {error,Q}
- end.
-
-
-read_impl(DB,Id,Opt) ->
- Gstkid = gstk_db:lookup_gstkid(DB, Id),
- case apply(gstk_widgets:objmod(Gstkid), read, [DB, Gstkid, Opt]) of
- {bad_result,R} -> {error,R};
- {error,R} -> {error,R};
- Res -> Res
- end.
-
-
-
-%%-----------------------------------------------------------------------------
-%% DESTROYING A WIDGET
-%%-----------------------------------------------------------------------------
-
-destroy_impl(DB, Gstkid) ->
- worker_do({delay_is,50}),
- Widget = delete_only_this_widget(DB,Gstkid),
- destroy_widgets([Widget], DB),
- worker_do({delay_is,5}),
- true.
-
-delete_only_this_widget(DB,Gstkid) ->
- #gstkid{id=ID,objtype=OT,parent=P} = Gstkid,
- delete_widgets(gstk_db:lookup_kids(DB, ID), DB),
- Widget = apply(gstk_widgets:type2mod(OT), delete, [DB, Gstkid]),
- gstk_db:delete_kid(DB, P, ID),
- Widget.
-
-
-pid_died_impl(DB, Pid) ->
- case lists:sort(gstk_db:lookup_ids(DB, Pid)) of
- [ID | IDs] ->
- Gstkid = gstk_db:lookup_gstkid(DB, ID),
- destroy_impl(DB, Gstkid),
- Tops = get_tops(IDs, DB),
- destroy_widgets(Tops, DB);
- _ ->
- true
- end.
-
-
-get_tops([ID | IDs], DB) ->
- case gstk_db:lookup_gstkid(DB, ID) of
- undefined ->
- get_tops(IDs, DB);
- Gstkid ->
- Parent = Gstkid#gstkid.parent,
- case lists:member(Parent, IDs) of
- true ->
- delete_widgets([ID], DB),
- get_tops(IDs, DB);
- false ->
- Widget = delete_only_this_widget(DB,Gstkid),
- [Widget | get_tops(IDs, DB)]
- end
- end;
-get_tops([], _DB) -> [].
-
-
-delete_widgets([ID | Rest], DB) ->
- delete_widgets(gstk_db:lookup_kids(DB, ID), DB),
- case gstk_db:lookup_gstkid(DB, ID) of
- undefined ->
- delete_widgets(Rest, DB);
- Gstkid ->
- apply(gstk_widgets:objmod(Gstkid), delete, [DB, Gstkid]),
- delete_widgets(Rest, DB)
- end;
-delete_widgets([], _) -> true.
-
-
-
-destroy_widgets(Widgets, DB) ->
- case destroy_wids(Widgets, DB) of
- [] -> true;
- Destroys -> exec(["destroy ", Destroys])
- end.
-
-
-destroy_wids([{Parent, ID, Objmod, Args} | Rest], DB) ->
- gstk_db:delete_kid(DB, Parent, ID),
- apply(Objmod, destroy, [DB | Args]),
- destroy_wids(Rest, DB);
-
-destroy_wids([W | Rest], DB) ->
- [W, " "| destroy_wids(Rest, DB)];
-
-destroy_wids([], _DB) -> [].
-
-
-%% ----- The Color Model -----
-
-to_color({R,G,B}) ->
- [$#,dec2hex(2,R),dec2hex(2,G),dec2hex(2,B)];
-to_color(Color) when is_atom(Color) -> atom_to_list(Color).
-
-%% ------------------------------------------------------------
-%% Decimal to Hex converter
-%% M is number of digits we want
-%% N is the decimal to be converted
-
-dec2hex(M,N) -> dec2hex(M,N,[]).
-
-dec2hex(0,_N,Ack) -> Ack;
-dec2hex(M,N,Ack) -> dec2hex(M-1,N bsr 4,[d2h(N band 15)|Ack]).
-
-d2h(N) when N<10 -> N+$0;
-d2h(N) -> N+$a-10.
-
-
-%% ----- Value to String -----
-
-to_ascii(V) when is_list(V) -> [$",to_ascii(V,[],[]),$"]; %% it's a string
-to_ascii(V) when is_integer(V) -> integer_to_list(V);
-to_ascii(V) when is_float(V) -> float_to_list(V);
-to_ascii(V) when is_atom(V) -> to_ascii( atom_to_list(V));
-to_ascii(V) when is_tuple(V) -> to_ascii(lists:flatten(io_lib:format("~w",[V])));
-to_ascii(V) when is_pid(V) -> pid_to_list(V).
-
- % FIXME: Currently we accept newlines in strings and handle this at
- % the Tcl side. Is this the best way or should we translate to "\n"
- % here?
-to_ascii([$[|R], Y, X) -> to_ascii(R, Y, [$[, $\\ | X]);
- to_ascii([$]|R], Y, X) -> to_ascii(R, Y, [$], $\\ | X]);
-to_ascii([${|R], Y, X) -> to_ascii(R, Y, [${, $\\ | X]);
- to_ascii([$}|R], Y, X) -> to_ascii(R, Y, [$}, $\\ | X]);
-to_ascii([$"|R], Y, X) -> to_ascii(R, Y, [$", $\\ | X]);
-to_ascii([$$|R], Y, X) -> to_ascii(R, Y, [$$, $\\ | X]);
-to_ascii([$\\|R], Y, X) -> to_ascii(R, Y, [$\\, $\\ | X]);
-to_ascii([C|R], Y, X) when is_list(C) -> to_ascii(C, [R|Y], X);
-to_ascii([C|R], Y, X) -> to_ascii(R, Y, [C|X]);
-to_ascii([], [Y1|Y], X) -> to_ascii(Y1, Y, X);
-to_ascii([], [], X) -> lists:reverse(X).
-
-worker_do(Msg) ->
- get(worker) ! Msg.
-
-worker_init(Delay) ->
- receive
- {delay_is,D} ->
- worker_init(D);
- {match_delete,DBExprs} ->
- worker_match(DBExprs),
- if Delay > 0 ->
- receive
- {delay_is,D} ->
- worker_init(D)
- after Delay ->
- worker_init(Delay)
- end;
- true ->
- worker_init(Delay)
- end
- end.
-
-worker_match([{DB,[Expr|Exprs]}|DbExprs]) ->
- ets:match_delete(DB,Expr),
- worker_match([{DB,Exprs}|DbExprs]);
-worker_match([{_DB,[]}|DbExprs]) ->
- worker_match(DbExprs);
-worker_match([]) -> done.
diff --git a/lib/gs/src/gstk_arc.erl b/lib/gs/src/gstk_arc.erl
deleted file mode 100644
index c38bbf4756..0000000000
--- a/lib/gs/src/gstk_arc.erl
+++ /dev/null
@@ -1,192 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Arc Type
-%% ------------------------------------------------------------
-
--module(gstk_arc).
--compile([{nowarn_deprecated_function,{gs,creation_error,2}}]).
-
-%%-----------------------------------------------------------------------------
-%% ARC OPTIONS
-%%
-%% Attributes:
-%% bw Int
-%% coords [{X1,Y1}, {X2,Y2}]
-%% data Data
-%% extent Degrees
-%% fg Color
-%% fill Color
-%% start Degrees
-%% stipple Bool
-%% style pieslice, chord, arc
-%%
-%% Commands:
-%% lower
-%% move {Dx, Dy}
-%% raise
-%% scale {Xo, Yo, Sx, Sy}
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-
--export([create/3, config/3, read/3, delete/2, destroy/3, event/5,
- option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/7
-%% Purpose : Create a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Objmod - An atom, this module
-%% Objtype - An atom, the logical widget type
-%% Owner - Pid of the creator
-%% Name - An atom naming the widget
-%% Parent - Gsid of the parent
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [Gsid_of_new_widget | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- case gstk_canvas:pickout_coords(Opts, [],GstkId#gstkid.objtype,2) of
- {error, Error} ->
- gs:creation_error(GstkId,Error);
- {Coords, NewOpts} ->
- Ngstkid=gstk_canvas:upd_gstkid(DB, GstkId, Opts),
- #gstkid{widget=CanvasTkW}=Ngstkid,
- MCmd = [CanvasTkW, " create ar ", Coords],
- gstk_canvas:mk_cmd_and_call(NewOpts,Ngstkid,CanvasTkW,MCmd,DB)
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- gstk_canvas:item_config(DB, Gstkid, Opts).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- Item = Gstkid#gstkid.widget_data,
- gstk_generic:read_option(DB,Gstkid,Opt,[gstk:to_ascii(Item)]).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy | {Parent, Objmod, Args}.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_canvas:item_delete_impl(DB,Gstkid).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : destroy/3
-%% Purpose : Destroy a widget
-%% Args : DB - The Database
-%% Canvas - The canvas tk widget
-%% Item - The item number to destroy
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-destroy(_DB, Canvas, Item) ->
- gstk:exec([Canvas, " delete ", gstk:to_ascii(Item)]).
-
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-%%------------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/5
-%% Purpose : Take care of options
-%% Args : MainW - The main tk-widget
-%% Canvas - The canvas tk-widget
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, _Gstkid, _Canvas, _DB, _AItem) ->
- case Option of
- {bw, Int} -> {s, [" -w ", gstk:to_ascii(Int)]};
- {extent, Degrees} -> {s, [" -e ", gstk:to_ascii(Degrees)]};
- {fg, Color} -> {s, [" -outline ", gstk:to_color(Color)]};
- {start, Degrees} -> {s, [" -start ", gstk:to_ascii(Degrees)]};
- {style, Style} -> {s, [" -sty ", gstk:to_ascii(Style)]};
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option, Gstkid, Canvas, _DB, AItem) ->
- case Option of
- bw -> tcl2erl:ret_int([Canvas, " itemcg ", AItem, " -w"]);
- extent -> tcl2erl:ret_int([Canvas, " itemcg ", AItem, " -e"]);
- fg -> tcl2erl:ret_color([Canvas, " itemcg ", AItem, " -outline"]);
- start -> tcl2erl:ret_int([Canvas, " itemcg ", AItem, " -start"]);
- stipple -> tcl2erl:ret_stipple([Canvas, " itemcg ", AItem, " -sti"]);
- style -> tcl2erl:ret_atom([Canvas, " itemcg ", AItem, " -sty"]);
-
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-%% ----- Done -----
diff --git a/lib/gs/src/gstk_button.erl b/lib/gs/src/gstk_button.erl
deleted file mode 100644
index 2b466c30c3..0000000000
--- a/lib/gs/src/gstk_button.erl
+++ /dev/null
@@ -1,221 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Button Type
-%% ------------------------------------------------------------
-
--module(gstk_button).
-
-%%------------------------------------------------------------------------------
-%% BUTTON OPTIONS
-%%
-%% Attributes:
-%% activebg Color
-%% activefg Color
-%% align n,w,s,e,nw,se,ne,sw,center
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% bg Color
-%% bw Int
-%% data Data
-%% disabledfg Color
-%% fg Color
-%% font Font
-%% height Int
-%% highlightbg Color
-%% highlightbw Int
-%% highlightfg Color
-%% justify left|right|center
-%% label {text, String} | {image, BitmapFile}
-%% padx Int (Pixels)
-%% pady Int (Pixels)
-%% relief Relief [flat|raised|sunken|ridge|groove]
-%% underline Int
-%% width Int
-%% wraplength Int
-%% x Int
-%% y Int
-%%
-%% Commands:
-%% enable Bool
-%% flash
-%% invoke
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% click [Bool | {Bool, Data}]
-%% configure [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%% cursor ??????
-%% font ??????
-%%
-
--export([create/3,config/3,read/3,delete/2,event/5,option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%---------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%---------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/3
-%% Purpose : Create a widget of the type defined in this module.
-%% Return : [Gsid_of_new_widget | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- TkW = gstk_generic:mk_tkw_child(DB,GstkId),
- NGstkId=GstkId#gstkid{widget=TkW},
- PlacePreCmd = [";place ", TkW],
- case gstk_generic:make_command(Opts,NGstkId,TkW,"",PlacePreCmd,DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(["button ", TkW," -rel raised -bo 2 ",Cmd]),
- NGstkId
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- TkW = Gstkid#gstkid.widget,
- SimplePreCmd = [TkW, " conf"],
- gstk_generic:mk_cmd_and_exec(Opts,Gstkid,SimplePreCmd,DB).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-%%------------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% TkW - The tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, TkW, DB,_) ->
- case Option of
- {bitmap, Bitmap} -> {s, [" -bi @", Bitmap]};
- {disabledfg, Color} -> {s, [" -disabledf ", gstk:to_color(Color)]};
- {underline, Int} -> {s, [" -un ", gstk:to_ascii(Int)]};
- {wraplength, Int} -> {s, [" -wr ", gstk:to_ascii(Int)]};
- invoke -> {c, [TkW, " i;"]};
- flash -> {c, [TkW, " f;"]};
- {click, On} -> cbind(DB, Gstkid, click, On);
- _ -> invalid_option
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/4
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,Gstkid, TkW,DB,_) ->
- case Option of
- disabledfg -> tcl2erl:ret_color([TkW, " cg -disabledf"]);
- underline -> tcl2erl:ret_int([TkW, " cg -un"]);
- wraplength -> tcl2erl:ret_int([TkW, " cg -wr"]);
-
- click -> gstk_db:is_inserted(DB, Gstkid, click);
-
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-%%------------------------------------------------------------------------------
-%% PRIMITIVES
-%%------------------------------------------------------------------------------
-
-%%
-%% Config bind
-%%
-cbind(DB, Gstkid, Etype, On) ->
- TkW = Gstkid#gstkid.widget,
- Cmd = case On of
- {true, Edata} ->
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, Edata),
- [" -command {erlsend ", Eref, " \\\"[", TkW, " cg -text]\\\"}"];
- true ->
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, ""),
- [" -command {erlsend ", Eref, " \\\"[", TkW, " cg -text]\\\"}"];
- _Other ->
- gstk_db:delete_event(DB, Gstkid, Etype),
- " -command {}"
- end,
- {s, Cmd}.
-
-%% ----- Done -----
-
diff --git a/lib/gs/src/gstk_canvas.erl b/lib/gs/src/gstk_canvas.erl
deleted file mode 100644
index 102b81df7a..0000000000
--- a/lib/gs/src/gstk_canvas.erl
+++ /dev/null
@@ -1,516 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Canvas Type
-%% ------------------------------------------------------------
-
--module(gstk_canvas).
--compile([{nowarn_deprecated_function,{gs,pair,2}},
- {nowarn_deprecated_function,{gs,val,2}}]).
-
-%%-----------------------------------------------------------------------------
-%% CANVAS OPTIONS
-%%
-%% Attributes:
-%% activebg Color
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% bc Color
-%% bg Color
-%% bw Wth
-%% data Data
-%% height Int
-%% highlightbg Color
-%% highlightbw Wth
-%% highlightfg Color
-%% hscroll Bool | top | bottom
-%% relief Relief
-%% scrollbg Color
-%% scrollfg Color
-%% scrollregion {X1, Y1, X2, Y2}
-%% selectbg Color
-%% selectbw Width
-%% selectfg Color
-%% vscroll Bool | left | right
-%% width Int
-%% x Int
-%% y Int
-%%
-%%
-%% Commands:
-%% find {X, Y} => Item at pos X,Y or false
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% configure [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%% fg Color
-%%
-
--export([create/3,config/3,read/3,delete/2,event/5,option/5,read_option/5]).
--export([make_command/5,make_command/6,pickout_coords/4, coords/1,
- item_config/3,mk_create_opts_for_child/4,
- upd_gstkid/3,item_delete_impl/2,mk_cmd_and_exec/6,mk_cmd_and_call/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/3
-%% Return : [Gsid_of_new_widget | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, Gstkid, Opts) ->
- MainW = gstk_generic:mk_tkw_child(DB,Gstkid),
- Canvas = lists:append(MainW,".z"),
- {Vscroll, Hscroll, NewOpts} = gstk_generic:parse_scrolls(Opts),
- WidgetD = #so{main=MainW, object=Canvas,
- hscroll=Hscroll, vscroll=Vscroll},
- NGstkid=Gstkid#gstkid{widget=MainW, widget_data=WidgetD},
- MandatoryCmd = ["so_create canvas ", MainW],
- case gstk:call(MandatoryCmd) of
- {result, _} ->
- SimplePreCmd = [MainW, " conf"],
- PlacePreCmd = [";place ", MainW],
- gstk_db:insert_opt(DB,Gstkid,gs:pair(scrollregion,Opts)),
- case gstk_generic:make_command(NewOpts, NGstkid, MainW,
- SimplePreCmd, PlacePreCmd, DB,Canvas) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(Cmd),
- gstk:exec([MainW,".sy conf -rel sunken -bo 2;",
- MainW,".pad.sx conf -rel sunken -bo 2;"]),
- NGstkid
- end;
- Bad_Result ->
- {bad_result, Bad_Result}
- end.
-
-mk_create_opts_for_child(DB,Cgstkid, Pgstkid, Opts) ->
- gstk_generic:mk_create_opts_for_child(DB,Cgstkid,Pgstkid,Opts).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Options) ->
- SO = Gstkid#gstkid.widget_data,
- MainW = Gstkid#gstkid.widget,
- Canvas = SO#so.object,
- NewOpts = gstk_generic:parse_scrolls(Gstkid, Options),
- SimplePreCmd = [MainW, " conf"],
- PlacePreCmd = [";place ", MainW],
- gstk_generic:mk_cmd_and_exec(NewOpts, Gstkid, MainW,
- SimplePreCmd, PlacePreCmd, DB,Canvas).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- SO = Gstkid#gstkid.widget_data,
- gstk_generic:read_option(DB, Gstkid, Opt,SO#so.object).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/5
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% MainW - The main tk-widget
-%% Canvas - The canvas tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option,Gstkid,_MainW,DB,Canvas) ->
- case Option of
- {scrollregion, {X1, Y1, X2, Y2}} ->
- gstk_db:insert_opt(DB,Gstkid,Option),
- {c, [Canvas, " conf -scrollr {",
- gstk:to_ascii(X1), " ", gstk:to_ascii(Y1), " ",
- gstk:to_ascii(X2), " ", gstk:to_ascii(Y2),"}"]};
- {yscrollpos, Y} ->
- {_,Ymin,_,Ymax} = gstk_db:opt(DB,Gstkid,scrollregion),
- K = 1/(Ymax-Ymin),
- M = -K*Ymin,
- PercentOffViewTop = K*Y+M,
- {c, [Canvas," yvi mo ",gstk:to_ascii(PercentOffViewTop)]};
- {xscrollpos, X} ->
- {Xmin,_,Xmax,_} = gstk_db:opt(DB,Gstkid,scrollregion),
- K = 1/(Xmax-Xmin),
- M = -K*Xmin,
- PercentOffViewLeft = K*X+M,
- {c, [Canvas," xvi mo ",gstk:to_ascii(PercentOffViewLeft)]};
- {buttonpress, On} -> bind(DB, Gstkid, Canvas, buttonpress, On);
- {buttonrelease, On} -> bind(DB, Gstkid, Canvas, buttonrelease, On);
- {configure, On} -> bind(DB, Gstkid, Canvas, configure, On);
- {destroy, On} -> bind(DB, Gstkid, Canvas, destroy, On);
- {enter, On} -> bind(DB, Gstkid, Canvas, enter, On);
- {focus, On} -> bind(DB, Gstkid, Canvas, focus, On);
- {keypress, On} -> bind(DB, Gstkid, Canvas, keypress, On);
- {keyrelease, On} -> bind(DB, Gstkid, Canvas, keyrelease, On);
- {leave, On} -> bind(DB, Gstkid, Canvas, leave, On);
- {motion, On} -> bind(DB, Gstkid, Canvas, motion, On);
-
- {secret_hack_gridit, GridGstkid} ->
- CRef = gstk_db:insert_event(DB, GridGstkid, click, []),
- ClickCmd = [Canvas, " bind all <ButtonRelease-1> {erlsend ", CRef,
- " [",Canvas, " find withtag current]};"],
- DRef = gstk_db:insert_event(DB, GridGstkid, doubleclick, []),
- DclickCmd = [Canvas," bind all <Double-ButtonRelease-1> {erlsend ",
- DRef," [",Canvas, " find withtag current]}"],
- %% bind all at once for preformance reasons.
- {c, [ClickCmd,DclickCmd]};
- {secret_forwarded_grid_event, {Event,On},GridGstkid} ->
- bind(DB,GridGstkid,Canvas,Event,On);
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,Gstkid,_MainW,DB,Canvas) ->
- case Option of
- scrollregion -> gstk_db:opt(DB,Gstkid,scrollregion);
- {hit, {X,Y}} ->
- hit(DB,Canvas,X,Y,X,Y);
- {hit, [{X1,Y1},{X2,Y2}]} ->
- hit(DB,Canvas,X1,Y1,X2,Y2);
- % {% hidden above, % of total area that is visible + % hidden above}
- yscrollpos ->
- {PercentOffViewTop,_} = tcl2erl:ret_tuple([Canvas," yvi"]),
- {_,Ymin,_,Ymax} = gstk_db:opt(DB,Gstkid,scrollregion),
- K = 1/(Ymax-Ymin),
- M = -K*Ymin,
- _Y = round((PercentOffViewTop - M)/K);
- xscrollpos ->
- {PercentOffViewLeft,_} = tcl2erl:ret_tuple([Canvas," xvi"]),
- {Xmin,_,Xmax,_} = gstk_db:opt(DB,Gstkid,scrollregion),
- K = 1/(Xmax-Xmin),
- M = -K*Xmin,
- _X = round((PercentOffViewLeft-M)/K);
- buttonpress -> gstk_db:is_inserted(DB, Gstkid, buttonpress);
- buttonrelease -> gstk_db:is_inserted(DB, Gstkid, buttonrelease);
- configure -> gstk_db:is_inserted(DB, Gstkid, configure);
- destroy -> gstk_db:is_inserted(DB, Gstkid, destroy);
- enter -> gstk_db:is_inserted(DB, Gstkid, enter);
- focus -> gstk_db:is_inserted(DB, Gstkid, focus);
- keypress -> gstk_db:is_inserted(DB, Gstkid, keypress);
- keyrelease -> gstk_db:is_inserted(DB, Gstkid, keyrelease);
- leave -> gstk_db:is_inserted(DB, Gstkid, leave);
- motion -> gstk_db:is_inserted(DB, Gstkid, motion);
-
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-hit(DB,Canvas,X1,Y1,X2,Y2) ->
- Ax1 = gstk:to_ascii(X1),
- Ay1 = gstk:to_ascii(Y1),
- Ax2 = gstk:to_ascii(X2),
- Ay2 = gstk:to_ascii(Y2),
- case tcl2erl:ret_list([Canvas," find overlapping ",
- Ax1,$ ,Ay1,$ ,Ax2,$ ,Ay2]) of
- Items when is_list(Items) ->
- [{_,Node}] = ets:lookup(DB,frontend_node),
- fix_ids(Items,DB,Canvas,Node);
- Other ->
- {bad_result, Other}
- end.
-
-fix_ids([Item|Items],DB,Canvas,Node) ->
- [{gstk_db:lookup_item(DB,Canvas,Item),Node}|fix_ids(Items,DB,Canvas,Node)];
-fix_ids([],_,_,_) -> [].
-
-%%-----------------------------------------------------------------------------
-%% PRIMITIVES
-%%-----------------------------------------------------------------------------
-
-%%
-%% Event bind main function
-%%
-%% Should return a list of tcl commands or invalid_option
-%%
-%% WS = Widget suffix for c widgets
-%%
-bind(DB, Gstkid, TkW, Etype, On) ->
- case bind(DB, Gstkid, TkW, Etype, On, "") of
- invalid_option -> invalid_option;
- Cmd -> {c, Cmd}
- end.
-
-bind(DB, Gstkid, TkW, Etype, On, WS) ->
- case On of
- true -> ebind(DB, Gstkid, TkW, Etype, WS, "");
- false -> eunbind(DB, Gstkid, TkW, Etype, WS, "");
- {true, Edata} -> ebind(DB, Gstkid, TkW, Etype, WS, Edata);
- {false, Edata} -> eunbind(DB, Gstkid, TkW, Etype, WS, Edata);
- _ -> invalid_option
- end.
-
-
-%%
-%% Event bind on
-%%
-%% Should return a list of tcl commands or invalid_option
-%%
-%% WS = Widget suffix for complex widgets
-%%
-ebind(DB, Gstkid, TkW, Etype, WS, Edata) ->
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, Edata),
- P = ["bind ", TkW, WS],
- Cmd = case Etype of
- motion -> [P, " <Motion> {erlsend ", Eref, " [",
- TkW, " canvasx %x] [", TkW, " canvasy %y] %x %y}"];
- keypress ->
- [P, " <Key> {erlsend ", Eref," %K %N 0 0 [",
- TkW, " canvasx %x] [", TkW, " canvasy %y]};",
- P, " <Shift-Key> {erlsend ", Eref, " %K %N 1 0 [",
- TkW, " canvasx %x] [", TkW, " canvasy %y]};",
- P, " <Control-Key> {erlsend ", Eref, " %K %N 0 1 [",
- TkW, " canvasx %x] [", TkW, " canvasy %y]};",
- P, " <Control-Shift-Key> {erlsend ", Eref," %K %N 1 1 [",
- TkW, " canvasx %x] [", TkW, " canvasy %y]}"];
- keyrelease ->
- [P, " <KeyRelease> {erlsend ", Eref," %K %N 0 0 [",
- TkW, " canvasx %x] [", TkW, " canvasy %y]};",
- P, " <Shift-KeyRelease> {erlsend ", Eref, " %K %N 1 0 [",
- TkW, " canvasx %x] [", TkW, " canvasy %y]};",
- P, " <Control-KeyRelease> {erlsend ", Eref, " %K %N 0 1 [",
- TkW, " canvasx %x] [", TkW, " canvasy %y]};",
- P," <Control-Shift-KeyRelease> {erlsend ",Eref," %K %N 1 1[",
- TkW, " canvasx %x] [", TkW, " canvasy %y]}"];
- buttonpress ->
- [P, " <Button> {erlsend ", Eref, " %b [",
- TkW, " canvasx %x] [", TkW, " canvasy %y] %x %y}"];
- buttonrelease ->
- [P, " <ButtonRelease> {erlsend ", Eref, " %b [",
- TkW, " canvasx %x] [", TkW, " canvasy %y] %x %y}"];
- leave -> [P, " <Leave> {erlsend ", Eref, "}"];
- enter -> [P, " <Enter> {erlsend ", Eref, "}"];
- destroy ->
- [P, " <Destroy> {if {\"%W\"==\"", [TkW, WS],
- "\"} {erlsend ", Eref, "}}"];
- focus ->
- [P, " <FocusIn> {erlsend ", Eref, " true};" ,
- P, " <FocusOut> {erlsend ", Eref, " false}"];
- configure ->
- [P, " <Configure> {if {\"%W\"==\"", [TkW, WS],
- "\"} {erlsend ", Eref, " %w %h %x %y}}"]
- end,
- Cmd.
-
-
-%%
-%% Unbind event
-%%
-%% Should return a list of tcl commands
-%% Already checked for validation in bind/5
-%%
-%% WS = Widget suffix for complex widgets
-%%
-eunbind(DB, Gstkid, TkW, Etype, WS, _Edata) ->
- gstk_db:delete_event(DB, Gstkid, Etype),
- P = ["bind ", TkW, WS],
- Cmd = case Etype of
- motion ->
- [P, " <Motion> {}"];
- keypress ->
- [P, " <KeyRelease> {};",
- P, " <Shift-KeyRelease> {};",
- P, " <Control-KeyRelease> {};",
- P, " <Control-Shift-KeyRelease> {}"];
- keyrelease ->
- [P, " <KeyRelease> {};",
- P, " <Shift-KeyRelease> {};",
- P, " <Control-KeyRelease> {};",
- P, " <Control-Shift-KeyRelease> {}"];
- buttonpress ->
- [P, " <ButtonPress> {}"];
- buttonrelease ->
- [P, " <ButtonRelease> {}"];
- leave ->
- [P, " <Leave> {}"];
- enter ->
- [P, " <Enter> {}"];
- destroy ->
- [P, " <Destroy> {}"];
- focus ->
- [P, " <FocusIn> {};",
- P, " <FocusOut> {}"];
- configure ->
- [P, " <Configure> {}"]
- end,
- Cmd.
-
-%%======================================================================
-%% Item library
-%%======================================================================
-
-mk_cmd_and_exec(Options, Gstkid, Canvas, AItem, SCmd, DB) ->
- case make_command(Options, Gstkid, Canvas, AItem, SCmd, DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(Cmd)
- end.
-
-mk_cmd_and_call(Opts,Gstkid, CanvasTkW, MCmd, DB) ->
- case make_command(Opts,Gstkid, CanvasTkW, MCmd, DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- case tcl2erl:ret_int(Cmd) of
- Item when is_integer(Item) ->
- G2 = gstk_db:lookup_gstkid(DB,Gstkid#gstkid.id), % buu, not nice
- NewGstkid = G2#gstkid{widget_data=Item},
- NewGstkid;
- Bad_result ->
- {error,Bad_result}
- end
- end.
-
-
-%%----------------------------------------------------------------------
-%% MCmd = Mandatory command
-%% Comment: The problem: Create everything in one async command and
-%% get the canvas obj integer id no back then.
-%% The trick is to do:
-%% set w [canvas create rectangle x1 y1 x2 y2 -Option Value ...];
-%% canvas Action $w ;$w
-%% Comment: no placer options (we don't have to consider all permutations)
-%%----------------------------------------------------------------------
-make_command(Options, Gstkid, Canvas, AItem, SCmd, DB) ->
- case gstk_generic:out_opts(Options,Gstkid,Canvas,DB,AItem, [],[],[]) of
- {[], [], []} -> [];
- {Si, [], []} -> [SCmd, Si];
- {[], [], Co} -> Co;
- {Si, [], Co} -> [SCmd, Si, $;, Co];
- {error,Reason} -> {error,Reason}
- end.
-
-make_command(Options, Gstkid, Canvas, MCmd, DB) ->
- case gstk_generic:out_opts(Options,Gstkid,Canvas,DB,"$w",[],[],[]) of
- {[], [], []} -> MCmd;
- {Si, [], []} -> [MCmd, Si];
- {[], [], Co} -> ["set w [", MCmd, "];", Co, "set d $w"];
- {Si, [], Co} -> ["set w [", MCmd, Si, "];", Co, "set d $w"];
- {error,Reason} -> {error,Reason}
- end.
-
-item_config(DB, Gstkid, Opts) ->
- #gstkid{widget=Canvas,widget_data=Item}=Gstkid,
- AItem = gstk:to_ascii(Item),
- SCmd = [Canvas, " itemconf ", AItem],
- case make_command(Opts, Gstkid, Canvas, AItem, SCmd, DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(Cmd)
- end.
-
-pickout_coords([{coords,Coords} | Rest], Opts, ObjType, NbrOfCoords)
- when length(Coords) == NbrOfCoords ->
- case coords(Coords) of
- invalid ->
- {error, io_lib:format("A ~w must have ~w coordinates",
- [ObjType,NbrOfCoords])};
- RealCoords ->
- {RealCoords, lists:append(Rest, Opts)}
- end;
-pickout_coords([Opt | Rest], Opts, ObjType, NbrOfCoords) ->
- pickout_coords(Rest, [Opt|Opts], ObjType, NbrOfCoords);
-pickout_coords([], _Opts, ObjType, NbrOfCoords) ->
- {error, io_lib:format("A ~w must have ~w coordinates",
- [ObjType,NbrOfCoords])}.
-
-coords([{X,Y} | R]) when is_number(X),is_number(Y) ->
- [gstk:to_ascii(X), " ", gstk:to_ascii(Y), " ", coords(R)];
-coords([_]) -> %% not a pair
- invalid;
-coords([]) ->
- [].
-
-item_delete_impl(DB,Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- #gstkid{widget=Canvas,widget_data=Item,parent=P,id=ID,objtype=Type}=Gstkid,
- {P,ID,gstk_widgets:type2mod(Type), [Canvas, Item]}.
-
-
-upd_gstkid(DB, Gstkid, Opts) ->
- #gstkid{parent=Parent,owner=Owner}=Gstkid,
- Pgstkid = gstk_db:lookup_gstkid(DB, Parent, Owner),
- SO = Pgstkid#gstkid.widget_data,
- CanvasTkW = SO#so.object,
- gstk_db:insert_opt(DB,Gstkid,{coords,gs:val(coords,Opts)}),
- gstk_db:update_widget(DB,Gstkid#gstkid{widget=CanvasTkW,widget_data=no_item}).
-
-
-%%% ----- Done -----
-
-
diff --git a/lib/gs/src/gstk_checkbutton.erl b/lib/gs/src/gstk_checkbutton.erl
deleted file mode 100644
index ac8abaedf3..0000000000
--- a/lib/gs/src/gstk_checkbutton.erl
+++ /dev/null
@@ -1,320 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic CheckButton Type
-%% ------------------------------------------------------------
-
--module(gstk_checkbutton).
-
-%%------------------------------------------------------------------------------
-%% CHECKBUTTON OPTIONS
-%%
-%% Attributes:
-%% activebg Color
-%% activefg Color
-%% align n,w,s,e,nw,se,ne,sw,center
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% bg Color
-%% bw Int
-%% data Data
-%% disabledfg Color
-%% fg Color
-%% group Atom
-%% groupid Groupid
-%% height Int
-%% highlightbg Color
-%% highlightbw Int
-%% highlightfg Color
-%% justify left|right|center
-%% label {text, String} | {image, BitmapFile}
-%% padx Int (Pixels)
-%% pady Int (Pixels)
-%% relief Relief [flat|raised|sunken|ridge|groove]
-%% select Bool
-%% selectbg Color
-%% underline Int
-%% width Int
-%% wraplength Int
-%% x Int
-%% y Int
-%%
-%% Commands:
-%% enable Bool
-%% flash
-%% invoke
-%% setfocus Bool
-%% toggle
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% click [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%% cursor ??????
-%% focus ?????? (-takefocus)
-%% font ??????
-%%
-
--export([create/3,config/3,read/3,delete/2,event/5,option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/7
-%% Purpose : Create a widget of the type defined in this module.
-%% Return : [Gsid_of_new_widget | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- TkW = gstk_generic:mk_tkw_child(DB,GstkId),
- {G, GID, _NOpts} = fix_group(Opts, DB, GstkId#gstkid.owner),
- NGstkId=GstkId#gstkid{widget=TkW,widget_data={G, GID}},
- PlacePreCmd = [";place ", TkW],
- case gstk_generic:make_command(Opts,NGstkId,TkW,"",PlacePreCmd,DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(["checkbutton ", TkW," -bo 2 -indi true ",Cmd]),
- NGstkId
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- TkW = Gstkid#gstkid.widget,
- {NOpts, NGstkid} = fix_group(Opts, DB, Gstkid#gstkid.owner, Gstkid),
- SimplePreCmd = [TkW, " conf"],
- PlacePreCmd = [";place ", TkW],
- gstk_generic:mk_cmd_and_exec(NOpts,NGstkid,TkW,SimplePreCmd,PlacePreCmd,DB).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- {_, Gid} = Gstkid#gstkid.widget_data,
- gstk_db:delete_bgrp(DB, Gid),
- Gstkid#gstkid.widget.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : event/5
-%% Purpose : Construct the event and send it to the owner of the widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Etype - The event type
-%% Edata - The event data
-%% Args - The data from tcl/tk
-%%
-%% Return : true
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-event(DB, Gstkid, Etype, Edata, Args) ->
- Arg2 = case Etype of
- click ->
- [Text, Bool | Rest] = Args,
- RBool = case Bool of
- 1 -> true;
- _Other2 -> false
- end,
- {G, _Gid} = Gstkid#gstkid.widget_data,
- [Text, G, RBool | Rest];
- _Other3 ->
- Args
- end,
- gstk_generic:event(DB, Gstkid, Etype, Edata, Arg2).
-
-
-
-%%------------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% TkW - The tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, TkW, DB,_) ->
- case Option of
- {disabledfg, Color} -> {s, [" -disabledforegr ", gstk:to_color(Color)]};
- {group, Group} -> {s, [" -var ", gstk:to_ascii(Group)]};
- {selectbg, Color} -> {s, [" -selectc ", gstk:to_color(Color)]};
- {underline, Int} -> {s, [" -un ", gstk:to_ascii(Int)]};
- {wraplength, Int} -> {s, [" -wr ", gstk:to_ascii(Int)]};
-
- flash -> {c, [TkW, " f;"]};
- invoke -> {c, [TkW, " i;"]};
- toggle -> {c, [TkW, " to;"]};
- {select, true} -> {c, [TkW, " se;"]};
- {select, false} -> {c, [TkW, " de;"]};
- {click, On} -> cbind(DB, Gstkid, click, On);
- _ -> invalid_option
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/3
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,Gstkid, TkW,DB,_) ->
- case Option of
- disabledfg -> tcl2erl:ret_color([TkW," cg -disabledforegr"]);
- group -> {G, _} = Gstkid#gstkid.widget_data, G;
- selectbg -> tcl2erl:ret_color([TkW," cg -selectc"]);
- groupid -> {_, Gid} = Gstkid#gstkid.widget_data, Gid;
- underline -> tcl2erl:ret_int([TkW," cg -un"]);
- wraplength -> tcl2erl:ret_int([TkW," cg -wr"]);
- select -> tcl2erl:ret_bool(["set x [", TkW,
- " cg -va];global $x;set $x"]);
-
- click -> gstk_db:is_inserted(DB, Gstkid, click);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-%%------------------------------------------------------------------------------
-%% PRIMITIVES
-%%------------------------------------------------------------------------------
-%% check button version
-%% create version
-fix_group(Opts, DB, Owner) ->
- {G, GID, NOpts} = fg(Opts, erlNIL, erlNIL, []),
- NG = case G of
- erlNIL ->
- Vref = gstk_db:counter(DB, variable),
- list_to_atom(lists:flatten(["cb", gstk:to_ascii(Vref)]));
- Other1 -> Other1
- end,
- RGID = case GID of
- erlNIL -> {cbgrp, NG, Owner};
- Other2 -> Other2
- end,
- RG = gstk_db:insert_bgrp(DB, RGID),
- {NG, RGID, [{group, RG} | NOpts]}.
-
-%% config version
-fix_group(Opts, DB, Owner, Gstkid) ->
- {RG, RGID} = Gstkid#gstkid.widget_data,
- {G, GID, NOpts} = fg(Opts, RG, RGID, []),
- case {G, GID} of
- {RG, RGID} ->
- {NOpts, Gstkid};
- {NG, RGID} ->
- NGID = {cbgrp, NG, Owner},
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={NG,NGID}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG} | NOpts], NGstkid};
- {_, NGID} when NGID =/= RGID ->
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={RG,NGID}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG} | NOpts], NGstkid}
- end.
-
-
-
-fg([{group, G} | Opts], _, GID, Nopts) ->
- fg(Opts, G, GID, Nopts);
-
-fg([{groupid, GID} | Opts], G, _, Nopts) ->
- fg(Opts, G, GID, Nopts);
-
-fg([Opt | Opts], G, GID, Nopts) ->
- fg(Opts, G, GID, [Opt | Nopts]);
-
-fg([], Group, GID, Opts) ->
- {Group, GID, Opts}.
-
-
-%%
-%% Config bind
-%%
-cbind(DB, Gstkid, Etype, On) ->
- TkW = Gstkid#gstkid.widget,
- Cmd = case On of
- {true, Edata} ->
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, Edata),
- [" -command {erlsend ", Eref, " \\\"[", TkW,
- " cg -text]\\\" \[expr \$[", TkW, " cg -va]\]}"];
- true ->
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, ""),
- [" -command {erlsend ", Eref, " \\\"[", TkW,
- " cg -text]\\\" \[expr \$[", TkW, " cg -va]\]}"];
- _Other ->
- gstk_db:delete_event(DB, Gstkid, Etype),
- " -command {}"
- end,
- {s, Cmd}.
-
-%% ----- Done -----
-
diff --git a/lib/gs/src/gstk_db.erl b/lib/gs/src/gstk_db.erl
deleted file mode 100644
index d9379cb3c8..0000000000
--- a/lib/gs/src/gstk_db.erl
+++ /dev/null
@@ -1,413 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%%
-%% Database interface for `gstk'.
-%%
-%% ------------------------------------------------------------
-
--module(gstk_db).
-
--export([init/1,
- insert/3,
- lookup/2,
- lookup_event/3,
- insert_bgrp/2,
- delete_bgrp/2,
- insert_gs/2,
- insert_widget/2,
- delete_kid/3,
- insert_opts/3,
- lookup_def/3,
- opt_or_not/3,
- lookup_gstkid/3,
- lookup_ids/2,
- lookup_item/3,
- delete_widget/2,
- delete_gstkid/2,
- get_deleted/1,
- delete_event/3,
- insert_event/4,
- update_widget/2,
- is_inserted/3,
- lookup_kids/2,
- insert_def/3,
- opt/4,
- opt/3,
- insert_opt/3,
- default_container_opts/3,
- default_opts/3,
- counter/2,
- lookup_gstkid/2]).
-
--include("gstk.hrl").
-
-
-%% ------------------------------------------------------------
-%% INITIALIZATION
-%% ------------------------------------------------------------
-
-init(_Opts) ->
- put(events,ets:new(gstk_db, [public, set])),
- put(kids,ets:new(gstk_db, [public, bag])),
- put(defaults,ets:new(gstk_db, [public, bag])),
- put(deleted,ets:new(gstk_db, [public, bag])),
- put(options,ets:new(gstk_db, [public, set])),
- ets:new(gstk_db, [public, set]).
-
-%% -----------------------------------------------------------------
-%% PRIMITIVE DB INTERFACE
-%% -----------------------------------------------------------------
-
-insert(DB, Key, Value) ->
- ets:insert(DB, {Key, Value}).
-
-
-lookup(DB, Key) ->
- Result =
- case ets:lookup(DB, Key) of
- [{Key, Value}] -> Value;
- _ -> undefined
- end,
- Result.
-
-
-delete(DB, Key) ->
- ets:delete(DB, Key).
-
-
-
-%% -----------------------------------------------------------------
-%% NOT SO PRIMITIVE DB INTERFACE
-%% -----------------------------------------------------------------
-
-%% -----------------------------------------------------------------
-%% HANDLE EVENTS
-%% -----------------------------------------------------------------
-insert_event(DB, Gstkid, Etype, Edata) ->
- ID = Gstkid#gstkid.id,
- Rdata =
- case Edata of
- [] -> opt(DB,ID,data);
- _Other1 -> Edata
- end,
- Events = lookup_events(DB, ID),
- case lists:keysearch(Etype, 2, Events) of
- {value, {Etag, _, _}} ->
- NewEvents =
- lists:keyreplace(Etype, 2, Events, {Etag, Etype, Rdata}),
- ets:insert(get(events), {{events, ID}, NewEvents}),
- [$#, gstk:to_ascii(ID), " ", Etag];
- _Other2 ->
- Etag = etag(Etype),
- NewEvents = [{Etag, Etype, Rdata} | Events],
- ets:insert(get(events), {{events, ID}, NewEvents}),
- [$#, gstk:to_ascii(ID), " ", Etag]
- end.
-
-etag(Etype) ->
- case Etype of
- click -> "c";
- doubleclick -> "dc";
- configure -> "co";
- enter -> "e";
- leave -> "l";
- motion -> "m";
- buttonpress -> "bp";
- buttonrelease -> "br";
- focus -> "f";
- destroy -> "d";
- keypress -> "kp";
- keyrelease -> "kr"
- end.
-
-lookup_events(_DB, ID) ->
- case lookup(get(events), {events, ID}) of
- undefined -> [];
- Events -> Events
- end.
-
-lookup_event(DB, ID, Etag) ->
- case lists:keysearch(Etag, 1, lookup_events(DB, ID)) of
- {value, {Etag, Etype, Edata}} ->
- {Etype, Edata};
- _Other ->
- nonexisting_event
- end.
-
-delete_event(DB, Gstkid, Etype) ->
- ID = Gstkid#gstkid.id,
- NewEvents = lists:keydelete(Etype, 2, lookup_events(DB, ID)),
- ets:insert(get(events), {{events, ID}, NewEvents}).
-
-%% -----------------------------------------------------------------
-%% HANDLE BUTTON GROUPS
-%% -----------------------------------------------------------------
-insert_bgrp(DB, Key) ->
- case ets:lookup(DB, Key) of
- [] ->
- {_Bgrp, RG, _Owner} = Key,
- insert(DB, Key, {0, RG}),
- RG;
- [{_, {Counter, RG}}] ->
- insert(DB, Key, {Counter+1, RG}),
- RG
- end.
-
-
-delete_bgrp(DB, Key) ->
- case ets:lookup(DB, Key) of
- [] ->
- true;
- [{_, {0, _RG}}] ->
- delete(DB, Key),
- true;
- [{_, {Counter, RG}}] ->
- insert(DB, Key, {Counter-1, RG}),
- true
- end.
-
-
-%% -----------------------------------------------------------------
-%% insert things
-
-update_widget(DB, Gstkid) ->
- ID = Gstkid#gstkid.id,
- insert(DB, ID, Gstkid),
- Gstkid.
-
-insert_gs(DB,Gstkid) ->
- update_widget(DB,Gstkid).
-
-insert_widget(DB, Gstkid) ->
- ID = Gstkid#gstkid.id,
- insert_kid(DB, Gstkid#gstkid.parent, ID),
- insert(DB, ID, Gstkid),
- Gstkid.
-
-insert_kid(_DB, Parent, Kid) ->
- ets:insert(get(kids), {{kids, Parent},Kid}).
-
-delete_kid(_DB, Parent, Kid) ->
- ets:match_delete(get(kids), {{kids, Parent},Kid}).
-
-lookup_kids(_DB, Parent) ->
- ril(ets:match(get(kids), {{kids, Parent},'$1'})).
-
-%%----------------------------------------------------------------------
-%% Options are stored as {{Id,Opt},Val}
-%%----------------------------------------------------------------------
-insert_opt(_DB,Id,{default,ObjType,Opt}) ->
- insert_def(Id,ObjType,Opt);
-insert_opt(_DB,#gstkid{id=Id},{Key,Val}) ->
- ets:insert(get(options),{{Id,Key},Val});
-insert_opt(_DB,Id,{Key,Val}) ->
- ets:insert(get(options),{{Id,Key},Val}).
-
-insert_opts(_DB,_Id,[]) -> done;
-insert_opts(DB,Id,[Opt|Opts]) ->
- insert_opt(DB,Id,Opt),
- insert_opts(DB,Id,Opts).
-
-insert_def(#gstkid{id=ID},ObjType,{Key,Val}) ->
- insert_def(ID,ObjType,{Key,Val});
-insert_def(ID,ObjType,{Key,Val}) ->
- Def = get(defaults),
- ets:match_delete(Def,{{ID,ObjType},{Key,'_'}}),
- ets:insert(Def,{{ID,ObjType},{Key,Val}}).
-
-lookup_def(ID,ObjType,Key) ->
- case ets:match(get(defaults),{{ID,ObjType},{Key,'$1'}}) of
- [] -> false;
- [[Val]] -> {value,Val}
- end.
-
-opt(DB,#gstkid{id=Id},Opt) -> opt(DB,Id,Opt);
-opt(_DB,Id,Opt) ->
- [{_, Value}] = ets:lookup(get(options), {Id,Opt}),
- Value.
-
-opt_or_not(DB,#gstkid{id=Id},Opt) -> opt_or_not(DB,Id,Opt);
-opt_or_not(_DB,Id,Opt) ->
- case ets:lookup(get(options), {Id,Opt}) of
- [{_, Value}] -> {value, Value};
- _ -> false
- end.
-
-opt(DB,#gstkid{id=Id},Opt,ElseVal) -> opt(DB,Id,Opt,ElseVal);
-opt(_DB,Id,Opt,ElseVal) ->
- case ets:lookup(get(options), {Id,Opt}) of
- [{_, Value}] ->
- Value;
- _ -> ElseVal
- end.
-
-%%----------------------------------------------------------------------
-%% Returns: list of {Key,Val}
-%%----------------------------------------------------------------------
-default_container_opts(_DB,Id,ChildType) ->
- L = ets:match(get(defaults),{{Id,'$1'},'$2'}),
- lists:sort(fix_def_for_container(L,ChildType)).
-
-default_opts(_DB,Id,ChildType) ->
- L1 = ets:lookup(get(defaults),{Id,ChildType}),
- L2 = ets:lookup(get(defaults),{Id,all}),
- lists:sort(fix_def(L1,L2)).
-
-fix_def([{_,Opt}|Opts],Opts2) ->
- [Opt|fix_def(Opts,Opts2)];
-fix_def([],[]) -> [];
-fix_def([],Opts) ->
- fix_def(Opts,[]).
-
-%%----------------------------------------------------------------------
-%% Purpose: Extracs {default,ObjType,DefsultOpt} for the ChildType
-%% and keeps default options since it is a container object.
-%% Returns: list of options
-%%----------------------------------------------------------------------
-fix_def_for_container([[all,{Key,Val}]|Opts],ChildType) ->
- [{{default,all,Key},Val},{Key,Val}
- |fix_def_for_container(Opts,ChildType)];
-fix_def_for_container([[ChildType,{Key,Val}]|Opts],ChildType) ->
- [{{default,ChildType,Key},Val},{Key,Val}
- |fix_def_for_container(Opts,ChildType)];
-fix_def_for_container([[ChildType2,{Key,Val}]|Opts],_ChildType) ->
- [{{default,ChildType2,Key},Val}|fix_def_for_container(Opts,ChildType2)];
-fix_def_for_container([],_) -> [].
-
-%% -----------------------------------------------------------------
-%% lookup things
-
-lookup_gstkid(DB, Name, Owner) when is_atom(Name) ->
- ID = lookup(DB, {Owner, Name}),
- lookup(DB, ID);
-
-lookup_gstkid(DB, ID, _Owner) ->
- lookup(DB, ID).
-
-
-lookup_gstkid(_DB, Name) when is_atom(Name) ->
- exit({'must use owner',Name});
-
-lookup_gstkid(DB, ID) ->
- lookup(DB, ID).
-
-
-lookup_ids(DB, Pid) ->
- ril(ets:match(DB, {'$1', {gstkid,'_','_','_',Pid,'_','_'}})).
-
-lookup_item(DB, TkW, Item) ->
- % [[Id]] = ets:match(DB, {'$1', {gstkid,'_',TkW, Item,'_','_','_'}}),
- % Id.
- %% OTP-4167 Gif images gstkids are stored differently from other objects
- case ets:match(DB, {'$1', {gstkid,'_',TkW, Item,'_','_','_'}}) of
- [[Id]] ->
- Id;
- [] ->
- Pattern = {'$1', {gstkid,'_',TkW, {'_',Item},'_','_',image}},
- [[Id]] = ets:match(DB, Pattern),
- Id
- end.
-
-
-%% -----------------------------------------------------------------
-%% counters
-
-counter(DB, Key) ->
- Result =
- case ets:lookup(DB, Key) of
- [{Key, Value}] -> Value+1;
- _ -> 0
- end,
- ets:insert(DB, {Key, Result}),
- Result.
-
-
-%% -----------------------------------------------------------------
-%% delete things
-
-delete_widgets(DB, [ID | Rest]) ->
- delete_widget(DB, ID),
- delete_widgets(DB, Rest);
-delete_widgets(_, []) ->
- true.
-
-
-delete_widget(DB, #gstkid{id = ID}) ->
- delete_widget(DB, ID);
-delete_widget(DB, ID) ->
- delete_widgets(DB, lookup_kids(DB, ID)),
- delete_id(DB, ID).
-
-delete_gstkid(DB,Gstkid) ->
- delete_id(DB,Gstkid).
-
-delete_id(DB, ID) ->
- case lookup_gstkid(DB, ID) of
- undefined ->
- true;
- _Gstkid ->
- gstk:worker_do({match_delete,[{get(options),[{{ID,'_'},'_'}]},
- {get(defaults),[{{ID,'_'},'_'}]}]}),
- ets:insert(get(deleted),{deleted,ID}),
- delete(DB, ID)
- end,
- ets:delete(get(kids), {kids, ID}),
- delete(get(events), {events, ID}),
- true.
-
-get_deleted(_DB) ->
- Dd = get(deleted),
- R=fix_deleted(ets:lookup(Dd,deleted)),
- ets:delete(Dd,deleted),
- R.
-
-fix_deleted([{_,Id}|Dd]) ->
- [Id | fix_deleted(Dd)];
-fix_deleted([]) -> [].
-
-%% -----------------------------------------------------------------
-%% odd stuff
-
-%% check if an event is in the database, used by read_option
-is_inserted(DB, #gstkid{id = ID}, What) ->
- is_inserted(DB, ID, What);
-is_inserted(_DB, ID, What) ->
- case lookup(get(events), {events, ID}) of
- undefined -> false;
- Events ->
- case lists:keysearch(What, 2, Events) of
- {value, _} -> true;
- _Other -> false
- end
- end.
-
-%% -----------------------------------------------------------------
-%% PRIMITIVES
-%% -----------------------------------------------------------------
-
-%% remove irritating lists
-ril([[Foo] | Rest]) -> [Foo | ril(Rest)];
-ril([]) -> [].
-
-
-
diff --git a/lib/gs/src/gstk_editor.erl b/lib/gs/src/gstk_editor.erl
deleted file mode 100644
index 6376efc851..0000000000
--- a/lib/gs/src/gstk_editor.erl
+++ /dev/null
@@ -1,400 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Editor Type
-%% ------------------------------------------------------------
-
--module(gstk_editor).
--compile([{nowarn_deprecated_function,{gs,assq,2}},
- {nowarn_deprecated_function,{gs,error,2}},
- {nowarn_deprecated_function,{gs,val,2}}]).
-
-%%------------------------------------------------------------------------------
-%% CANVAS OPTIONS
-%%
-%% Attributes:
-%% activebg Color
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% bc Color
-%% bg Color
-%% bw Wth
-%% data Data
-%% fg Color
-%% font Font
-%% height Int
-%% highlightbg Color
-%% highlightbw Wth
-%% highlightfg Color
-%% hscroll Bool | top | bottom
-%% insertbg Color
-%% insertbw Wth
-%% insertpos {Row,Col}|'end' (Row: 1..Max, Col: 0..Max)
-%% justify left|right|center
-%% padx Int (Pixels)
-%% pady Int (Pixels)
-%% relief Relief
-%% scrollbg Color
-%% scrollfg Color
-%% selectbg Color
-%% selectbw Width
-%% selectfg Color
-%% vscroll Bool | left | right
-%% width Int
-%% wrap none | char | word
-%% x Int
-%% y Int
-%%
-%%
-%% Commands:
-%% clear
-%% del {FromIdx, ToIdx}
-%% enable Bool
-%% file String
-%% get {FromIdx, ToIdx} => Text
-%% insert {Index, Text}Index = [insert,{Row,lineend},end,{Row,Col}]
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-
-%.t tag names 2.7 -> red blue (blue is the colour)
-%.t tag add blue 2.1 2.10 tag the text
-%.t tag configure blue -foregr blue create tag
-% .t index end -> MaxRows.cols
-% .t yview moveto (Row-1)/MaxRows
-
--export([create/3, config/3, read/3, delete/2,event/5,option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/3
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, Gstkid, Opts) ->
- MainW = gstk_generic:mk_tkw_child(DB,Gstkid),
- Editor = lists:append(MainW,".z"),
- {Vscroll, Hscroll, NewOpts} = gstk_generic:parse_scrolls(Opts),
- WidgetD = #so{main=MainW, object=Editor,
- hscroll=Hscroll, vscroll=Vscroll,misc=[{1,white}]},
- NGstkid=Gstkid#gstkid{widget=MainW, widget_data=WidgetD},
- gstk_db:insert_widget(DB,NGstkid),
- MandatoryCmd = ["so_create text ", MainW],
- case gstk:call(MandatoryCmd) of
- {result, _} ->
- SimplePreCmd = [MainW, " conf"],
- PlacePreCmd = [";place ", MainW],
- case gstk_generic:make_command(NewOpts, NGstkid, MainW, SimplePreCmd,
- PlacePreCmd, DB,Editor) of
- {error,Reason} -> {error,Reason};
- Cmd ->
- gstk:exec(Cmd),
- gstk:exec(
- [Editor," conf -bo 2 -relief sunken -highlightth 2;",
- MainW,".sy conf -rel sunken -bo 2;",
- MainW,".pad.sx conf -rel sunken -bo 2;",
- Editor, " tag co c1 -for white;"]),
- ok
- end
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Options) ->
- SO = Gstkid#gstkid.widget_data,
- MainW = Gstkid#gstkid.widget,
- Editor = SO#so.object,
- NewOpts =
- case {gs:assq(vscroll,Options),gs:assq(hscroll,Options)} of
- {false,false} -> Options;
- _ -> gstk_generic:parse_scrolls(Gstkid, Options)
- end,
- SimplePreCmd = [MainW, " conf"],
- PlacePreCmd = [";place ", MainW],
- gstk_generic:mk_cmd_and_exec(NewOpts, Gstkid, MainW, SimplePreCmd,
- PlacePreCmd, DB, Editor).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- SO = Gstkid#gstkid.widget_data,
- gstk_generic:read_option(DB, Gstkid, Opt,SO#so.object).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/5
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% MainW - The main tk-widget
-%% Editor - The Editor tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, _MainW, DB, Editor) ->
- case Option of
- {font,Font} when is_tuple(Font) ->
- gstk_db:insert_opt(DB,Gstkid,Option),
- {c, [Editor, " conf -font ", gstk_font:choose_ascii(DB,Font)]};
- {font_style, {{Start,End},Font}} -> % should be only style
- {Tag,Ngstkid} = get_style_tag(DB,Editor,Font,Gstkid),
- gstk_db:update_widget(DB,Ngstkid),
- {c, Ngstkid, [Editor, " tag ad ", Tag, " ", p_index(Start), " ",
- p_index(End)]};
- {fg, {{Start,End},Color}} ->
- {Tag,Ngstkid} = get_color_tag(Editor,Color,Gstkid),
- gstk_db:update_widget(DB,Ngstkid),
- {c, Ngstkid, [Editor, " tag ad ", Tag, " ", p_index(Start), " ",
- p_index(End)]};
- {padx, Pad} -> {c, [Editor," conf -padx ",gstk:to_ascii(Pad)]};
- {pady, Pad} -> {c, [Editor," conf -pady ",gstk:to_ascii(Pad)]};
- {selection, {From, To}} ->
- {c, [Editor," tag ad sel ",p_index(From)," ", p_index(To)]};
- {vscrollpos, Row} ->
- {MaxRow,_Col} = ret_ed_index([Editor," ind end"]),
- {c, [Editor, " yv mo ",gstk:to_ascii(Row/MaxRow)]};
- {wrap, How} ->
- {c, [Editor, " conf -wrap ", gstk:to_ascii(How)]};
- {fg, Color} ->
- {c, [Editor, " conf -fg ", gstk:to_color(Color)]};
- {insertbw, Wth} ->
- {c, [Editor, " conf -insertbo ", gstk:to_ascii(Wth)]};
- {insertbg, Color} ->
- {c, [Editor, " conf -insertba ", gstk:to_color(Color)]};
- {insertpos, Index} ->
- {c, [Editor, " m s insert ", p_index(Index)]};
- {insert, {Index, Text}} ->
- {c, [Editor, " ins ", p_index(Index), " ", gstk:to_ascii(Text)]};
- {del, {From, To}} ->
- {c, [Editor, " del ", p_index(From), " ", p_index(To)]};
- {overwrite, {Index, Text}} ->
- AI = p_index(Index),
- Len = gstk:to_ascii(lists:flatlength(Text)),
- {c, [Editor, " del ",AI," \"",AI,"+",Len,"c\";",
- Editor, " ins ",AI," ", gstk:to_ascii(Text)]};
- clear -> {c, [Editor, " delete 1.0 end"]};
- {load, File} ->
- F2 = re:replace(File, [92,92], "/", [global,{return,list}]),
- case gstk:call(["ed_load ", Editor, " ", gstk:to_ascii(F2)]) of
- {result, _} -> none;
- {bad_result,Re} ->
- {error,{no_such_file,editor,load,F2,Re}}
- end;
- {save, File} ->
- F2 = re:replace(File, [92,92], "/", [global,{return,list}]),
- case gstk:call(["ed_save ",Editor," ",gstk:to_ascii(F2)]) of
- {result, _} -> none;
- {bad_result,Re} ->
- {error,{no_such_file,editor,save,F2,Re}}
- end;
- {enable, true} -> {c, [Editor, " conf -state normal"]};
- {enable, false} -> {c, [Editor, " conf -state disabled"]};
-
- {setfocus, true} -> {c, ["focus ", Editor]};
- {setfocus, false} -> {c, ["focus ."]};
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,GstkId,_MainW,DB,Editor) ->
- case Option of
- font -> gstk_db:opt(DB,GstkId,font,undefined);
- padx -> tcl2erl:ret_atom([Editor," cg -padx"]);
- pady -> tcl2erl:ret_atom([Editor," cg -pady"]);
- enable -> tcl2erl:ret_enable([Editor," cg -st"]);
- fg -> tcl2erl:ret_color([Editor," cg -fg"]);
- {fg, Pos} ->
- L=tcl2erl:ret_list([Editor," tag nam ", p_index(Pos)]),
- SO = GstkId#gstkid.widget_data,
- case last_tag_val(undefined, $c, L, SO#so.misc) of
- undefined -> tcl2erl:ret_color([Editor," cg -fg"]);
- Color -> Color
- end;
- {font_style, Pos} ->
- L=tcl2erl:ret_list([Editor," tag nam ", p_index(Pos)]),
- SO = GstkId#gstkid.widget_data,
- case last_tag_val(undefined, $f, L, SO#so.misc) of
- undefined -> 'my style? nyi';
- Style -> Style
- end;
- selection -> ret_ed_indexes([Editor," tag ne sel 1.0"]);
- char_height -> tcl2erl:ret_int([Editor, " cg -he"]);
- char_width -> tcl2erl:ret_int([Editor, " cg -wi"]);
- insertbg -> tcl2erl:ret_color([Editor," cg -insertba"]);
- insertbw -> tcl2erl:ret_int([Editor," cg -insertbo"]);
- insertpos -> ret_ed_index([Editor, " ind insert"]);
- setfocus -> tcl2erl:ret_focus(Editor, "focus");
- wrap -> tcl2erl:ret_atom([Editor," cg -wrap"]);
- size -> {MaxRow,_Col} = ret_ed_index([Editor," ind end"]),
- MaxRow-1;
- vscrollpos ->
- {MaxRow,_Col} = ret_ed_index([Editor," ind end"]),
- [Top,_Bot] = tcl2erl:ret_list([Editor," yvi"]),
- round(Top*(MaxRow-1))+1;
- {get, {From, To}} ->
- tcl2erl:ret_str([Editor, " get ", p_index(From), " ", p_index(To)]);
- _ -> {bad_result, {GstkId#gstkid.objtype, invalid_option, Option}}
- end.
-
-
-%%------------------------------------------------------------------------------
-%% PRIMITIVES
-%%------------------------------------------------------------------------------
-
-p_index({Line, lineend}) -> [$",gstk:to_ascii(Line), ".1 lineend",$"];
-p_index({Line, Char}) -> [gstk:to_ascii(Line), $., gstk:to_ascii(Char)];
-p_index(insert) -> "insert";
-p_index('end') -> "end";
-p_index(Idx) -> gs:error("bad index in editor: ~w~n",[Idx]),0.
-
-ret_ed_index(Cmd) ->
- case gstk:call(Cmd) of
- {result, Val} ->
- case io_lib:fread("~d.~d", Val) of
- {ok, [Row,Col], []} -> {Row, Col};
- Other -> {bad_result, Other}
- end;
- Bad_result -> Bad_result
- end.
-
-ret_ed_indexes(Cmd) ->
- case gstk:call(Cmd) of
- {result, ""} -> undefined;
- {result, Val} ->
- case io_lib:fread("~d.~d ~d.~d", Val) of
- {ok, [Row1,Col1,Row2,Col2], []} -> {{Row1, Col1}, {Row2,Col2}};
- Other -> {bad_result, Other}
- end;
- Bad_result -> Bad_result
- end.
-
-
-%%----------------------------------------------------------------------
-%% Returns: {Tag text(), NewGstkId}
-%%----------------------------------------------------------------------
-%% The misc field of the so record is a list of {ColorNo, Color|Font|...}
-get_color_tag(Editor,Color,Gstkid) ->
- SO = Gstkid#gstkid.widget_data,
- Tags = SO#so.misc,
- case lists:keysearch(Color, 2, Tags) of
-% {value, {No, _}} -> {["c",gstk:to_ascii(No)], Gstkid};
-% false -> % don't reuse tags, priority order spoils that
- _Any ->
- {No,_} = lists:max(Tags),
- N=No+1,
- SO2 = SO#so{misc=[{N,Color}|Tags]},
- TagStr=["c",gstk:to_ascii(N)],
- gstk:exec([Editor," tag co ",TagStr," -for ", gstk:to_color(Color)]),
- {TagStr,Gstkid#gstkid{widget_data=SO2}}
- end.
-
-get_style_tag(DB,Editor,Style,Gstkid) ->
- SO = Gstkid#gstkid.widget_data,
- Tags = SO#so.misc,
- case lists:keysearch(Style, 2, Tags) of
-% {value, {No, _}} -> {["f",gstk:to_ascii(No)], Gstkid};
-% false -> % don't reuse tags, priority order spoils that
- _Any ->
- {No,_} = lists:max(Tags),
- N=No+1,
- SO2 = SO#so{misc=[{N,Style}|Tags]},
- TagStr=["f",gstk:to_ascii(N)],
- gstk:exec([Editor," tag co ",TagStr," -font ",
- gstk_font:choose_ascii(DB,Style)]), % should be style only
- {TagStr,Gstkid#gstkid{widget_data=SO2}}
- end.
-
-%%----------------------------------------------------------------------
-%% Purpose: Given a list of tags for a char, return its visible color
-%% (that is that last color tag in the list).
-%%----------------------------------------------------------------------
-last_tag_val(TagVal, _Chr, [], _TagDict) -> TagVal;
-last_tag_val(TagVal, Chr, [Tag|Ts],TagDict) ->
- case atom_to_list(Tag) of
- [Chr|ANo] ->
- No = list_to_integer(ANo),
- last_tag_val(gs:val(No, TagDict),Chr,Ts,TagDict);
- _NoAcolor ->
- last_tag_val(TagVal,Chr, Ts,TagDict)
- end.
-
-%%% ----- Done -----
diff --git a/lib/gs/src/gstk_entry.erl b/lib/gs/src/gstk_entry.erl
deleted file mode 100644
index a83bf2f896..0000000000
--- a/lib/gs/src/gstk_entry.erl
+++ /dev/null
@@ -1,234 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Entry Type
-%% ------------------------------------------------------------
-
--module(gstk_entry).
--compile([{nowarn_deprecated_function,{gs,error,2}}]).
-
-%%------------------------------------------------------------------------------
-%% ENTRY OPTIONS
-%%
-%% Attributes:
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% bg Color
-%% bw Int
-%% data Data
-%% fg Color
-%% font Font
-%% height Int
-%% highlightbg Color
-%% highlightbw Int (Pixels)
-%% highlightfg Color
-%% insertbg Color
-%% insertbw Int (0 or 1 Pixels ???)
-%% justify left|right|center
-%% relief Relief [flat|raised|sunken|ridge|groove]
-%% selectbg Color
-%% selectbw Int (Pixels)
-%% selectfg Color
-%% text String
-%% width Int
-%% x Int
-%% xselection Bool
-%% y Int
-%%
-%% Commands:
-%% delete Index | {From, To}
-%% enable Bool
-%% insert {index,String}
-%% select {From, To} | clear
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% configure [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read options:
-%% children
-%% id
-%% index Index => Int
-%% parent
-%% type
-%%
-%%
-%% Not Implemented:
-%% cursor ??????
-%% focus ?????? (-takefocus)
-%% font ??????
-%% hscroll ??????
-%% show ??????
-%% state ??????
-%%
-
--export([create/3,config/3,read/3,delete/2,event/5,option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/7
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- TkW = gstk_generic:mk_tkw_child(DB,GstkId),
- PlacePreCmd = [";place ", TkW],
- Ngstkid = GstkId#gstkid{widget=TkW},
- case gstk_generic:make_command(Opts,Ngstkid,TkW,"", PlacePreCmd,DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- case gstk:call(["entry ", TkW,Cmd]) of
- {result, _} ->
- gstk:exec(
- [TkW," conf -bo 2 -relief sunken -highlightth 2;"]),
- Ngstkid;
- Bad_Result ->
- {error, Bad_Result}
- end
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- TkW = Gstkid#gstkid.widget,
- SimplePreCmd = [TkW, " conf"],
- PlacePreCmd = [";place ", TkW],
- gstk_generic:mk_cmd_and_exec(Opts,Gstkid,TkW,SimplePreCmd,PlacePreCmd,DB).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-
-%%------------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% TkW - The tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, TkW, DB,_) ->
- case Option of
- {font, Font} ->
- gstk_db:insert_opt(DB,Gstkid,Option),
- {s, [" -font ", gstk_font:choose_ascii(DB,Font)]};
- {insertbg, Color} -> {s, [" -insertba ", gstk:to_color(Color)]};
- {insertbw, Width} -> {s, [" -insertbo ", gstk:to_ascii(Width)]};
- {justify, How} -> {s, [" -ju ", gstk:to_ascii(How)]};
- {text, Str} ->
- {c, [TkW," del 0 end; ",TkW," ins 0 ", gstk:to_ascii(Str)]};
- {xselection, Bool} -> {s, [" -exportse ", gstk:to_ascii(Bool)]};
-
- {delete, {From, To}} ->
- {c, [TkW, " del ", p_index(From), $ , p_index(To)]};
- {delete, Index} -> {c, [TkW, " de ", p_index(Index)]};
- {insert, {Idx, Str}} ->
- {c, [TkW, " ins ", gstk:to_ascii(Idx),$ , gstk:to_ascii(Str)]};
- {select, clear} -> {c, [TkW, " sel clear"]};
- {select, {From, To}} ->
- {c, [TkW, " sel range ", p_index(From), $ , p_index(To)]};
- _ -> invalid_option
-
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,Gstkid,TkW,DB,_) ->
- case Option of
- insertbg -> tcl2erl:ret_color([TkW," cg -insertba"]);
- insertbw -> tcl2erl:ret_int([TkW," cg -insertbo"]);
- font -> gstk_db:opt(DB,Gstkid,font,undefined);
- justify -> tcl2erl:ret_atom([TkW," cg -jus"]);
- text -> tcl2erl:ret_str([TkW," get"]);
- xselection -> tcl2erl:ret_bool([TkW," cg -exports"]);
- {index, Idx} -> tcl2erl:ret_int([TkW, "cg ind ", p_index(Idx)]);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-%%------------------------------------------------------------------------------
-%% PRIMITIVES
-%%------------------------------------------------------------------------------
-p_index(Index) when is_integer(Index) -> gstk:to_ascii(Index);
-p_index(insert) -> "insert";
-p_index(last) -> "end";
-p_index(Idx) -> gs:error("Bad index in entry: ~w~n",[Idx]),0.
-
-
-%%% ----- Done -----
diff --git a/lib/gs/src/gstk_font.erl b/lib/gs/src/gstk_font.erl
deleted file mode 100644
index 80cc46d493..0000000000
--- a/lib/gs/src/gstk_font.erl
+++ /dev/null
@@ -1,255 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%%% Purpose : The font model
-
-%% ###########################################################################
-%%
-%% This module handle fonts. It was changed for Tcl 8.2 but it could
-%% probably be simplified more.
-%%
-%% In Tcl 8.2 we can use named fonts. So the whe get a font request we
-%% first check if it already exists and if not we name it and insert it
-%% into the database.
-%%
-%% The font naming is also changedin Tcl 8.2.
-%%
-%% In Tcl 8.2 there is a way to find out the width of a string in
-%% a specified font.
-%%
-%% ###########################################################################
-
--module(gstk_font).
-
-%-compile(export_all).
-
--export([init/0,choose_ascii/2,choose/2,width_height/3]).
-
-
--ifndef(NEW_WIDTH_HEIGHT).
-init() ->
- %% hack. the only way to find the size of a text seems to be to put
- %% it into a label in an unmappen window (DummyFontWindow)
- gstk:exec("toplevel .dfw;wm withdraw .dfw;" %deiconify
- "label .dfw.l -text dummyinittxt -padx 0 -pady 0 -borderwidth 0;"
- "pack .dfw.l").
--else.
-init() -> true.
--endif.
-
-%%----------------------------------------------------------------------
-%% Returns: undefined if font doesn't exist
-%% {WidthPixels, HeightPixels}
-%%----------------------------------------------------------------------
--ifndef(NEW_WIDTH_HEIGHT).
-width_height(_DB, FontSpec, Txt) ->
- FontSpecStr = tk_font_spec(norm_font_spec(FontSpec)),
- case gstk:call([".dfw.l co -font {", FontSpecStr,"}",
- " -text ", gstk:to_ascii(Txt)]) of
- {result, _} ->
- Width = tcl2erl:ret_int("update idletasks;winfo w .dfw.l"),
- Height = tcl2erl:ret_int("winfo h .dfw.l"),
-% io:format("width_height(~p,~p) =>\n~p\n\n",[FontSpec,Txt,{Width,Height}]),
- {Width,Height};
- _Bad_Result ->
-% io:format("width_height(~p,~p) =>\nundefined\n\n",[FontSpec,Txt]),
- undefined
- end.
--else.
-%% This code should work but does't. Tk gives incorrect
-%% values if asking to fast or something /kent
-width_height(DB, FontSpec, Txt) when tuple(FontSpec) ->
- NormFontSpec = norm_font_spec(FontSpec),
- FontSpecStr = tk_font_spec(NormFontSpec),
- {Family,_,Size} = NormFontSpec,
- LineHeight =
- case cached_line_height(DB, {Family,Size}) of
- undefined ->
- LineH = tcl2erl:ret_int(
- ["font metrics {",FontSpecStr,"} -linespace"]),
- cache_line_height(DB, {Family,Size}, LineH),
- LineH;
- LineH ->
- LineH
- end,
- EscapedText = gstk:to_ascii(Txt),
- Width = tcl2erl:ret_int(
- ["font measure {",FontSpecStr,"} ",EscapedText]),
- Height = LineHeight * line_count(Txt),
- {Width,Height};
-
-width_height(_DB, FontSpec, Txt) when list(FontSpec) ->
- EscapedText = gstk:to_ascii(Txt),
- Width =
- tcl2erl:ret_int(["font measure {",FontSpec,"} ",EscapedText]),
- LineHeight =
- tcl2erl:ret_int(["font metrics {",FontSpec,"} -linespace"]),
- Height = LineHeight * line_count(Txt),
- {Width,Height}.
-
-cached_line_height(DB,FontSpec) ->
- gstk_db:lookup(DB, {cached_line_height,FontSpec}).
-
-cache_line_height(DB,FontSpec,Size) ->
- gstk_db:insert(DB, {cached_line_height,FontSpec}, Size).
-
-line_count(Line) ->
- line_count(Line, 1).
-
-line_count([H | T], Count) ->
- Count + line_count(H, 0) + line_count(T, 0);
-line_count($\n, Count) -> Count + 1;
-line_count(Char, Count) when integer(Char) -> Count;
-line_count([], Count) -> Count.
--endif.
-
-% "expr [font metrics ",FSpec," -linespace] * \
-% [regsub -all \\n ",Txt," {} ignore]"
-
-%%----------------------------------------------------------------------
-%% Returns: Font specification string in Tk format
-%%
-%% The input is {Family,Size} or {Family,Style,Size} where Family and
-%% Style are atoms ?! FIXME true???
-%%----------------------------------------------------------------------
-choose_ascii(DB, Font) ->
- {Fam,Styl,Siz} = choose(DB, Font),
- {variable,V} =gstk_db:lookup(DB,{font,Fam,Styl,Siz}),
-% io:format("choose_ascii(~p) =>\n~p\n\n",[Font,V]),
- V.
-
-%% DB contains: {font,Fam,Style,Size} -> {replaced_by,{font,Fam,Style,Size}} or
-%% {variable, TkVariableStrInclDollar}
-
-%% ###########################################################################
-%%
-%% We create a new font name on the other side and store the name in the
-%% database. We reorder the options so that they have a predefined order.
-%%
-%% ###########################################################################
-
-choose(DB, FontSpec) ->
- choose_font(DB, norm_font_spec(FontSpec)).
-
-choose_font(DB, {Fam,Styl,Siz}) ->
- Fam0 = map_family(Fam),
- case gstk_db:lookup(DB,{font,Fam0,Styl,Siz}) of
- {variable,_OwnFontName} -> true;
- undefined ->
- N = gstk_db:counter(DB,font), % FIXME: Can use "font create"
- % without name to get unique name
- NewName=["f",gstk:to_ascii(N)],
-% io:format("~s\n\n",
-% [lists:flatten(["font create ",NewName," ",
-% tk_font_spec({Fam0,Styl,Siz})])]),
- gstk:exec(["font create ",NewName," ",
- tk_font_spec({Fam0,Styl,Siz})]),
- %% should us variable syntax gs(f1) instead
- %% have to recompile erlcall to define this global gs var
- V2 = {variable,NewName},
- gstk_db:insert(DB,{font,Fam0,Styl,Siz},V2),
- true
- end,
-% io:format("choose(~p,~p,~p) =>\n~p\n\n",[Fam,Styl,Siz,{Fam0,Styl,Siz}]),
- {Fam0,Styl,Siz}.
-
-
-%% ----- The Font Model -----
-
-%% Guaranteed system fonts to exists in Tk 8.2 are:
-%%
-%% Windows : system systemfixed ansi ansifixed device oemfixed
-%% Unix : fixed
-%%
-%% Times, Courier and Helvetica always exists. Tk try to substitute
-%% others with the best matchin font.
-
-%% We map GS font style and names to something we know Tk 8 have.
-%% We know Tk have 'times', 'courier', 'helvetica' and 'fixed'.
-%%
-%% GS style specification is 'bold' or 'italic'.
-%% GS family is a typeface of type 'times', 'courier', 'helvetica',
-%% 'symbol', 'new_century_schoolbook', or 'screen' (which is a suitable
-%% screen font).
-%%
-%% Note that 'symbol' may not be present and this is not handled.
-%%
-%% The X/Tk8 font handling don't work very well. The fonts are
-%% scaled "tk scaling", we can display a 9 and 10 point helvetica
-%% but "font actual {helvetica 9}" will return 10 points....
-
-map_family(new_century_schoolbook) ->
- times;
-map_family(Fam) ->
- Fam.
-
-% Normalize so can make the coding easier and compare font
-% specifications stored in database with new ones. We ignore invalid
-% entries in the list.
-
-norm_font_spec({Family,Size}) ->
- {Family,[],Size};
-norm_font_spec({Family,Style,Size}) ->
- {Family,norm_style(Style),Size}.
-
-norm_style(bold) ->
- [bold];
-norm_style(italic) ->
- [italic];
-norm_style([italic]) ->
- [italic];
-norm_style([bold]) ->
- [bold];
-norm_style([bold,italic] = Style) ->
- Style;
-norm_style([italic,bold]) ->
- [bold,italic];
-norm_style(List) when is_list(List) -> % not well formed list, ignore garbage
- case {lists:member(bold, List),lists:member(italic, List)} of
- {true,true} ->
- [bold,italic];
- {true,_} ->
- [bold];
- {_,true} ->
- [italic];
- _ ->
- [] % ignore garbage
- end;
-norm_style(_Any) -> % ignore garbage
- [].
-
-
-% Create a tcl string from a normalized font specification
-% The style list is normalized.
-
-tk_font_spec({Fam,Style,Size}) ->
- ["-family ",gstk:to_ascii(Fam),
- " -size ",gstk:to_ascii(-Size),
- tk_font_spec_style(Style)].
-
-tk_font_spec_style([]) ->
- "";
-tk_font_spec_style([bold]) ->
- " -weight bold";
-tk_font_spec_style([italic]) ->
- " -slant italic";
-tk_font_spec_style([bold,italic]) ->
- " -weight bold -slant italic".
diff --git a/lib/gs/src/gstk_frame.erl b/lib/gs/src/gstk_frame.erl
deleted file mode 100644
index 2e9d160eef..0000000000
--- a/lib/gs/src/gstk_frame.erl
+++ /dev/null
@@ -1,282 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Frame Type.
-%% ------------------------------------------------------------
-
--module(gstk_frame).
-
-%%-----------------------------------------------------------------------------
-%% FRAME OPTIONS
-%%
-%% Attributes:
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% bg Color
-%% bw Int
-%% data Data
-%% height Int
-%% highlightbg Color
-%% highlightbw Int
-%% highlightfg Color
-%% relief Relief [flat|raised|sunken|ridge|groove]
-%% width Int
-%% x Int
-%% y Int
-%% cursor arrow|busy|cross|hand|help|resize|text
-%%
-%% Commands:
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% configure [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-
--export([create/3,config/3,read/3,delete/2,event/5,option/5,read_option/5,
- mk_create_opts_for_child/4]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/3
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- TkW = gstk_generic:mk_tkw_child(DB,GstkId),
- NGstkid=GstkId#gstkid{widget=TkW},
- PlacePreCmd = [";place ", TkW],
- case gstk_generic:make_command(Opts, NGstkid, TkW, "", PlacePreCmd, DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(["frame ", TkW,
- " -relief raised -bo 0",Cmd]),
- NGstkid
- end.
-
-mk_create_opts_for_child(DB,Cgstkid, Pgstkid, Opts) ->
- gstk_generic:mk_create_opts_for_child(DB,Cgstkid,Pgstkid,Opts).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- TkW = Gstkid#gstkid.widget,
- SimplePreCmd = [TkW, " conf"],
- PlacePreCmd = [";place ", TkW],
- Opts2 = atomic_width_height(false,false,Opts),
- gstk_generic:mk_cmd_and_exec(Opts2,Gstkid,TkW,SimplePreCmd,PlacePreCmd,DB).
-
-atomic_width_height(false,false,[]) ->
- [];
-atomic_width_height(false,Width,[]) ->
- [{width,Width}];
-atomic_width_height(Height,false,[]) ->
- [{height,Height}];
-atomic_width_height(H,W,[]) ->
- [{width_height,{W,H}}];
-atomic_width_height(_,W,[{height,H}|Opts]) ->
- atomic_width_height(H,W,Opts);
-atomic_width_height(H,_,[{width,W}|Opts]) ->
- atomic_width_height(H,W,Opts);
-atomic_width_height(H,W,[Opt|Opts]) ->
- [Opt|atomic_width_height(H,W,Opts)].
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% TkW - The tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, _TkW, DB,_) ->
- case Option of
- {bg, Color} -> {s, [" -bg ", gstk:to_color(Color)]};
- {packer_x, _Pack} ->
- gstk_db:insert_opt(DB,Gstkid,Option),
- none;
- {packer_y, _Pack} ->
- gstk_db:insert_opt(DB,Gstkid,Option),
- none;
- {width, W} ->
- execute_pack_cmds(DB,xpack(W,DB,Gstkid)),
- {s,[" -wi ", gstk:to_ascii(W)]};
- {height, H} ->
- execute_pack_cmds(DB,ypack(H,DB,Gstkid)),
- {s,[" -he ", gstk:to_ascii(H)]};
- {width_height,{W,H}} ->
- execute_pack_cmds(DB, merge_pack_cmds(xpack(W,DB,Gstkid),
- ypack(H,DB,Gstkid))),
- {s,[" -he ", gstk:to_ascii(H)," -wi ", gstk:to_ascii(W)]};
- _ -> invalid_option
- end.
-
-xpack(W,DB,Gstkid) ->
- gstk_db:insert_opt(DB,Gstkid,{width,W}),
- case gstk_db:opt_or_not(DB,Gstkid,packer_x) of
- {value,Pack} when is_list(Pack) ->
- ColSiz = gs_packer:pack(W,Pack),
- pack_children(pack_x,x,width,DB,
- gstk_db:lookup_kids(DB,Gstkid#gstkid.id),
- ColSiz);
- _Else -> []
- end.
-
-ypack(H,DB,Gstkid) ->
- gstk_db:insert_opt(DB,Gstkid,{height,H}),
- case gstk_db:opt_or_not(DB,Gstkid,packer_y) of
- {value,Pack} when is_list(Pack) ->
- ColSiz = gs_packer:pack(H,Pack),
- pack_children(pack_y,y,height,DB,
- gstk_db:lookup_kids(DB,Gstkid#gstkid.id),
- ColSiz);
- _Else -> []
- end.
-
-merge_pack_cmds([{Id,Opts1}|Cmds1],[{Id,Opts2}|Cmds2]) ->
- [{Id,Opts1++Opts2}|merge_pack_cmds(Cmds1,Cmds2)];
-merge_pack_cmds(L1,L2) ->
- L1++L2.
-
-execute_pack_cmds(DB,[{Id,Opts}|Cmds]) ->
- gstk:config_impl(DB,Id,Opts),
- execute_pack_cmds(DB,Cmds);
-execute_pack_cmds(_,[]) ->
- ok.
-
-%%----------------------------------------------------------------------
-%% Returns: list of {Id,Opts} to be executed (or merged with other first)
-%%----------------------------------------------------------------------
-pack_children(PackOpt,PosOpt,SizOpt,DB,Kids,Sizes) ->
- Schildren = keep_packed(Kids,PackOpt,DB),
- pack_children2(PackOpt,PosOpt,SizOpt,Schildren,Sizes).
-
-pack_children2(PackOpt,PosOpt,SizOpt,[{StartStop,Id}|Childs],Sizes) ->
- [pack_child(Id,StartStop,SizOpt,PosOpt,Sizes)
- | pack_children2(PackOpt,PosOpt,SizOpt,Childs,Sizes)];
-pack_children2(_,_,_,[],_) ->
- [].
-
-pack_child(Id,{StartPos,StopPos},SizOpt,PosOpt,Sizes) ->
- {Pos,Size} = find_pos(StartPos,StopPos,1,0,0,Sizes),
- {Id,[{PosOpt,Pos},{SizOpt,Size}]}.
-
-%%----------------------------------------------------------------------
-%% Returns: {PixelPos,PixelSize}
-%%----------------------------------------------------------------------
-find_pos(_StartPos,Pos,Pos,AccPixelPos,AccPixelSize,[Size|_]) ->
- {AccPixelPos,Size+AccPixelSize};
-find_pos(StartPos,StopPos,Pos,AccPixelPos,0,[Size|Sizes])
- when Pos < StartPos ->
- find_pos(StartPos,StopPos,Pos+1,Size+AccPixelPos,0,Sizes);
-find_pos(_StartPos,StopPos,Pos,AccPixelPos,AccPixelSize,[Size|Sizes])
- when Pos < StopPos ->
- find_pos(Pos,StopPos,Pos+1,AccPixelPos,Size+AccPixelSize,Sizes).
-
-
-
-keep_packed([Id|Ids],PackOpt,DB) ->
- case gstk:read_impl(DB,Id,PackOpt) of
- undefined ->
- keep_packed(Ids,PackOpt,DB);
- StartStop ->
- [{StartStop,Id} | keep_packed(Ids,PackOpt,DB)]
- end;
-keep_packed([],_,_) ->
- [].
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/3
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,Gstkid,TkW,_DB,_) ->
- case Option of
- bg -> tcl2erl:ret_color([TkW," cg -bg"]);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-%% ----- Done -----
diff --git a/lib/gs/src/gstk_generic.erl b/lib/gs/src/gstk_generic.erl
deleted file mode 100644
index db4e2fdff4..0000000000
--- a/lib/gs/src/gstk_generic.erl
+++ /dev/null
@@ -1,1089 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-
--module(gstk_generic).
--compile([{nowarn_deprecated_function,{gs,assq,2}}]).
-
--export([out_opts/8,
- read_option/5,
- mk_tkw_child/2,
- merge_default_options/3,
- merge_default_options/2,
- opts_for_child/3,
- mk_cmd_and_exec/4,
- mk_cmd_and_exec/5,
- mk_cmd_and_exec/6,
- mk_cmd_and_exec/7,
- make_command/5,
- make_command/6,
- make_command/7,
- read_option/4,
- handle_external_opt_call/9,
- handle_external_read/1,
- gen_anchor/9,
- gen_anchor/5,
- gen_height/9,
- gen_height/5,
- gen_width/9,
- gen_width/5,
- gen_x/9,
- gen_x/5,
- gen_y/9,
- gen_y/5,
- gen_raise/9,
- gen_raise/5,
- gen_lower/9,
- gen_lower/5,
- gen_enable/9,
- gen_enable/5,
- gen_align/9,
- gen_align/5,
- gen_justify/9,
- gen_justify/5,
- gen_padx/9,
- gen_padx/5,
- gen_pady/9,
- gen_pady/5,
- gen_font/9,
- gen_font/5,
- gen_label/9,
- gen_label/5,
- gen_activebg/9,
- gen_activebg/5,
- gen_activefg/9,
- gen_activefg/5,
- gen_default/9,
- gen_relief/9,
- gen_relief/5,
- gen_bw/9,
- gen_bw/5,
- gen_font_wh/5,
- gen_choose_font/5,
- gen_data/9,
- gen_data/5,
- gen_pack_x/9,
- gen_pack_x/5,
- gen_pack_y/9,
- gen_pack_y/5,
- gen_pack_xy/9,
- gen_flush/9,
- gen_flush/5,
- gen_keep_opt/9,
- gen_children/5,
- make_extern_id/2,
- gen_id/5,
- gen_parent/5,
- gen_type/5,
- gen_beep/9,
- gen_setfocus/9,
- gen_setfocus/5,
- gen_buttonpress/9,
- gen_buttonpress/5,
- gen_buttonrelease/9,
- gen_buttonrelease/5,
- gen_configure/9,
- gen_configure/5,
- gen_destroy/9,
- gen_destroy/5,
- gen_enter/9,
- gen_enter/5,
- gen_focus_ev/9,
- gen_focus_ev/5,
- gen_keypress/9,
- gen_keypress/5,
- gen_keyrelease/9,
- gen_keyrelease/5,
- gen_leave/9,
- gen_leave/5,
- gen_motion/9,
- gen_motion/5,
- gen_highlightbw/9,
- gen_highlightbw/5,
- gen_highlightbg/9,
- gen_highlightbg/5,
- gen_highlightfg/9,
- gen_highlightfg/5,
- gen_selectbw/9,
- gen_selectbw/5,
- gen_selectfg/9,
- gen_selectfg/5,
- gen_selectbg/9,
- gen_selectbg/5,
- gen_fg/9,
- gen_fg/5,
- gen_bg/9,
- gen_bg/5,
- gen_so_activebg/9,
- gen_so_activebg/5,
- gen_so_bc/9,
- gen_so_bc/5,
- gen_so_scrollfg/9,
- gen_so_scrollfg/5,
- gen_so_scrollbg/9,
- gen_so_scrollbg/5,
- obj/1,
- gen_so_bg/9,
- gen_so_bg/5,
- gen_so_selectbw/9,
- gen_so_selectbw/5,
- gen_so_selectfg/9,
- gen_so_selectfg/5,
- gen_so_selectbg/9,
- gen_so_selectbg/5,
- gen_so_scrolls/9,
- gen_so_hscroll/5,
- gen_so_vscroll/5,
- cursors/0,
- gen_cursor/9,
- gen_cursor/5,
- gen_citem_coords/9,
- gen_citem_coords/5,
- gen_citem_fill/9,
- gen_citem_fill/5,
- gen_citem_lower/9,
- gen_citem_raise/9,
- gen_citem_move/9,
- move_coords/3,
- add_to_coords/3,
- gen_citem_setfocus/9,
- gen_citem_setfocus/5,
- gen_citem_buttonpress/9,
- gen_citem_buttonrelease/9,
- gen_citem_enter/9,
- gen_citem_keypress/9,
- gen_citem_keyrelease/9,
- gen_citem_leave/9,
- gen_citem_motion/9,
- scrolls_vh/3,
- parse_scrolls/1,
- parse_scrolls/2,
- parse_scrolls/4,
- bind/5,
- bind/6,
- ebind/6,
- eunbind/6,
- item_bind/6,
- item_ebind/6,
- item_eunbind/5,
- event/5,
- read_option/3,
- make_command/4,
- mk_create_opts_for_child/4]).
-
--include("gstk.hrl").
--include("gstk_generic.hrl").
-
-%%----------------------------------------------------------------------
-%% Returns: a new unique TkWidget (string())
-%%----------------------------------------------------------------------
-mk_tkw_child(DB,#gstkid{parent=P,objtype=Ot}) ->
- Pgstkid = gstk_db:lookup_gstkid(DB, P),
- PW = Pgstkid#gstkid.widget,
- Oref = gstk_db:counter(DB, Ot),
- PF = gstk_widgets:suffix(Ot),
- _TkW = lists:concat([PW, PF, Oref]).
-
-%%----------------------------------------------------------------------
-%% Purpose: Merges options. Opts have higher priority than BuiltIn
-%% (and ParentOpts have higher than BuiltIn)
-%% Returns: A list of new options.
-%%----------------------------------------------------------------------
-merge_default_options(ParOpts, BuildInOpts, Opts) ->
- %% parents options first
- Tmp=merge_default_options(ParOpts, lists:sort(Opts)),
- merge_default_options(BuildInOpts,Tmp).
-
-merge_default_options([Def|Ds],[Opt|Os])
- when element(1,Def) < element(1,Opt) ->
- [Def | merge_default_options(Ds,[Opt|Os])];
-
-merge_default_options([Def|Ds],[Opt|Os])
- when element(1,Def) > element(1,Opt) ->
- [Opt | merge_default_options([Def|Ds],Os)];
-
-merge_default_options([Def|Ds],[Opt|Os])
- when element(1,Def) == element(1,Opt) ->
- [Opt | merge_default_options(Ds,Os)];
-
-merge_default_options(Defs,[Opt|Os]) ->
- [Opt | merge_default_options(Defs,Os)];
-
-merge_default_options([],Opts) -> Opts;
-merge_default_options(Defs,[]) -> Defs.
-
-opts_for_child(DB,Childtype,ParId) ->
- case gs_widgets:container(Childtype) of
- true ->
- gstk_db:default_container_opts(DB,ParId,Childtype);
- false ->
- gstk_db:default_opts(DB,ParId,Childtype)
- end.
-
-mk_create_opts_for_child(DB,#gstkid{objtype=ChildType}, Pgstkid, Opts) ->
- merge_default_options(
- opts_for_child(DB,ChildType,Pgstkid#gstkid.id),
- gs_widgets:default_options(ChildType),
- Opts).
-
-mk_cmd_and_exec(Opts,Gstkid,Scmd,DB) ->
- TkW = Gstkid#gstkid.widget,
- mk_cmd_and_exec(Opts,Gstkid,TkW,Scmd,[";place ", TkW],DB,dummy).
-mk_cmd_and_exec(Opts,Gstkid,Scmd,Pcmd,DB) ->
- mk_cmd_and_exec(Opts,Gstkid,Gstkid#gstkid.widget,Scmd,Pcmd,DB,dummy).
-mk_cmd_and_exec(Options, Gstkid, TkW, SCmd, PCmd, DB) ->
- mk_cmd_and_exec(Options, Gstkid, TkW, SCmd, PCmd, DB,dummy).
-mk_cmd_and_exec(Options, Gstkid, TkW, SCmd, PCmd, DB,ExtraArg) ->
- case gstk_generic:make_command(Options,Gstkid,TkW,SCmd,PCmd,DB,ExtraArg) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(Cmd)
- end.
-
-%%----------------------------------------------------------------------
-%% SCmd: SimplePreCommand - prepended to simple (s) options
-%% PCmd: PlacePreCommand - prepended to placer (p) options
-%% (should start with ';' (at least if preceeded with simple cmds))
-%% Comment: If some function changes the gstkid,
-%% it's responsible for storing it in the DB.
-%%----------------------------------------------------------------------
-make_command(Opts,Gstkid,Scmd,DB) ->
- TkW = Gstkid#gstkid.widget,
- make_command(Opts,Gstkid,TkW,Scmd,[";place ", TkW],DB,dummy).
-make_command(Opts,Gstkid,Scmd,Pcmd,DB) ->
- make_command(Opts,Gstkid,Gstkid#gstkid.widget,Scmd,Pcmd,DB,dummy).
-make_command(Options, Gstkid, TkW, SCmd, PCmd, DB) ->
- make_command(Options, Gstkid, TkW, SCmd, PCmd, DB,dummy).
-make_command(Options, Gstkid, TkW, SCmd, PCmd, DB,ExtraArg) ->
- case out_opts(Options, Gstkid, TkW, DB, ExtraArg, [], [], []) of
- {[], [], []} -> [];
- {Si, [], []} -> [SCmd, Si,$;];
- {[], Pl, []} -> [PCmd, Pl,$;];
- {[], [], Co} -> [$;,Co];
- {[], Pl, Co} -> [PCmd, Pl, $;, Co];
- {Si, [], Co} -> [SCmd, Si, $;, Co];
- {Si, Pl, []} -> [SCmd, Si, PCmd, Pl, $;];
- {Si, Pl, Co} -> [SCmd, Si, PCmd, Pl, $;, Co];
- {error,Reason} -> {error,Reason}
- end.
-
-read_option(DB,Gstkid,Opt) ->
- read_option(DB,Gstkid,Gstkid#gstkid.widget,Opt,dummy).
-read_option(DB,Gstkid,Opt,ExtraArg) ->
- read_option(DB,Gstkid,Gstkid#gstkid.widget,Opt,ExtraArg).
-
-%%----------------------------------------------------------------------
-%% Args: Args is [Gstkid, TkW, DB, ExtraArg]
-%% Comment: An optimization:don't reconstruct the arg list for apply each time.
-%% This is the option-engine so we should optimize.
-%%----------------------------------------------------------------------
-handle_external_opt_call([Opt|Options],Gstkid,TkW,DB,ExtraArg,ExtRes,S,P,C) ->
- case ExtRes of
- {s, Cmd} ->
- out_opts(Options,Gstkid, TkW,DB, ExtraArg, [Cmd|S], P, C);
- {p, Cmd} ->
- out_opts(Options, Gstkid,TkW,DB, ExtraArg, S, [Cmd|P], C);
- {c, Cmd} ->
- out_opts(Options, Gstkid,TkW,DB, ExtraArg,S, P, [Cmd,$;|C]);
- none ->
- out_opts(Options, Gstkid,TkW,DB,ExtraArg, S, P, C);
- % {s, NGstkid, Cmd} ->
- % out_opts(Options,NGstkid,TkW,DB,ExtraArg, [Cmd|S], P, C);
- % {p, NGstkid, Cmd} ->
- % out_opts(Options,NGstkid,TkW,DB,ExtraArg, S, [Cmd|P], C);
- {c, NGstkid, Cmd} ->
- out_opts(Options,NGstkid,TkW,DB, ExtraArg,S,P,[Cmd,$;|C]);
- {none, NGstkid} ->
- out_opts(Options,NGstkid,TkW,DB, ExtraArg, S, P, C);
- {sp,{Scmd,Pcmd}} ->
- out_opts(Options,Gstkid,TkW,DB,ExtraArg,[Scmd|S],[Pcmd|P],C);
- invalid_option ->
- {error,{invalid_option,Gstkid#gstkid.objtype,Opt}};
- break -> % a hack. it is possible to abort generic option handling at
- %% any time (without even inserting the gstkid inte to DB (for
- %% performance reasons)).
- {S, P, C}
- end.
-
-handle_external_read(Res) ->
- %% We have removed dead code here that attempted to translate
- %% a bad return value from {bad_result,{A,B,C}} to {error,{A,B,C}}.
- %% Since the gs application is deprecated, we don't want to introduce
- %% a potential incompatibility; thus we have removed the dead code
- %% instead of correcting it.
- Res.
-
-%%----------------------------------------------------------------------
-%% Generic options
-%%----------------------------------------------------------------------
-
-gen_anchor(How,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,[" -anc ", gstk:to_ascii(How)|P],C).
-gen_anchor(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_place(anchor, TkW).
-
-gen_height(Height,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- gstk_db:insert_opt(DB,Gstkid,{height,Height}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,
- [" -he ", gstk:to_ascii(Height)|P],C).
-gen_height(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:opt(DB,Gstkid,height).
-
-gen_width(Width,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- gstk_db:insert_opt(DB,Gstkid,{width,Width}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,
- [" -wi ", gstk:to_ascii(Width)|P],C).
-gen_width(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:opt(DB,Gstkid,width).
-
-gen_x(X,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- gstk_db:insert_opt(DB,Gstkid,{x,X}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,
- [" -x ", gstk:to_ascii(X)|P],C).
-gen_x(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:opt(DB,Gstkid,x).
-
-gen_y(Y,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- gstk_db:insert_opt(DB,Gstkid,{y,Y}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,
- [" -y ", gstk:to_ascii(Y)|P],C).
-gen_y(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:opt(DB,Gstkid,y).
-
-gen_raise(_,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,["raise ", TkW,$;|C]).
-gen_raise(_Opt,_Gstkid,_TkW,_DB,_ExtraArg) ->
- undefined.
-
-gen_lower(_,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,["lower ", TkW,$;|C]).
-gen_lower(_Opt,_Gstkid,_TkW,_DB,_ExtraArg) ->
- undefined.
-
-gen_enable(true,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -st normal"|S],P,C);
-gen_enable(false,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -st disabled"|S],P,C).
-gen_enable(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_enable([TkW, " cg -st"]).
-
-gen_align(How,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -an ", gstk:to_ascii(How)|S],P,C).
-gen_align(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_atom([TkW, " cg -anch"]).
-
-gen_justify(How,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -ju ", gstk:to_ascii(How)|S],P,C).
-gen_justify(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_atom([TkW, " cg -ju"]).
-
-gen_padx(Pad,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -padx ", gstk:to_ascii(Pad)|S],P,C).
-gen_padx(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_atom([TkW, " cg -padx"]).
-
-gen_pady(Pad,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -pady ", gstk:to_ascii(Pad)|S],P,C).
-gen_pady(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_atom([TkW, " cg -pady"]).
-
-
-gen_font(Font,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- gstk_db:insert_opt(DB,Gstkid,{font,Font}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,
- [" -font ", gstk_font:choose_ascii(DB,Font)|S],P,C).
-gen_font(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:opt(DB,Gstkid,font,undefined).
-
-gen_label({text,Text},Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -text ", gstk:to_ascii(Text), " -bi {}"|S],P,C);
-gen_label({image,Img},Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- I2 = re:replace(Img, [92,92], "/", [global,{return,list}]),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -bi \"@", I2, "\" -text {}"|S],P,C).
-gen_label(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- case gstk:call([TkW, " cg -bit"]) of
- {result, [$@|Image]} -> {image,Image};
- _Nope ->
- case gstk:call([TkW, " cg -text"]) of
- {result, Txt} -> {text, Txt};
- Bad_Result -> Bad_Result
- end
- end.
-
-gen_activebg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -activeba ", gstk:to_color(Color)|S],P,C).
-gen_activebg(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW, " cg -activeba"]).
-
-gen_activefg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -activef ", gstk:to_color(Color)|S],P,C).
-gen_activefg(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW, " cg -activef"]).
-
-
-gen_default(Opt,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- case Opt of
- {all, {font, Font}} ->
- C2 = ["option a *",tl(TkW), % have to remove preceeding dot
- "*font ",gstk_font:choose_ascii(DB, Font)],
- gstk_db:insert_def(Gstkid,grid,{font,Font}),
- gstk_db:insert_def(Gstkid,text,{font,Font}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[C2,$;|C]);
- {buttons, {font, Font}} ->
- C2 = ["option a *",tl(TkW), % have to remove preceeding dot
- ".Button.font ",gstk_font:choose_ascii(DB, Font)],
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[C2,$;|C]);
- {buttons,{Key,Val}} ->
- gstk_db:insert_def(Gstkid,button,{Key,Val}),
- gstk_db:insert_def(Gstkid,checkbutton,{Key,Val}),
- gstk_db:insert_def(Gstkid,radiobutton,{Key,Val}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C);
- {ObjType, {Key,Val}} ->
- gstk_db:insert_def(Gstkid,ObjType,{Key,Val}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C)
- end.
-
-
-gen_relief(Relief,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -reli ",gstk:to_ascii(Relief)|S],P,C).
-gen_relief(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_atom([TkW, " cg -reli"]).
-
-gen_bw(Wth,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -bd ", gstk:to_ascii(Wth)|S],P,C).
-gen_bw(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_int([TkW, " cg -bd"]).
-
-
-
-gen_font_wh({font_wh,{Font, Txt}},_Gstkid,_TkW,DB,_) ->
- gstk_font:width_height(DB, gstk_font:choose(DB,Font), Txt).
-
-gen_choose_font({choose_font,Font},_Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_font:choose(DB,Font).
-
-gen_data(Data,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- gstk_db:insert_opt(DB,Gstkid,{data,Data}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C).
-gen_data(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:opt(DB,Gstkid,data).
-
-gen_pack_x({Start,Stop},Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- gstk_db:insert_opt(DB,Gstkid,{pack_x,{Start,Stop}}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C);
-gen_pack_x(Col,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) when is_integer(Col) ->
- gstk_db:insert_opt(DB,Gstkid,{pack_x,{Col,Col}}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C).
-gen_pack_x(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:opt(DB,Gstkid,pack_x, undefined).
-
-gen_pack_y({Start,Stop},Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- gstk_db:insert_opt(DB,Gstkid,{pack_y,{Start,Stop}}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C);
-gen_pack_y(Row,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) when is_integer(Row) ->
- gstk_db:insert_opt(DB,Gstkid,{pack_y,{Row,Row}}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C).
-gen_pack_y(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:opt(DB,Gstkid,pack_y, undefined).
-
-gen_pack_xy({Col,Row},Opts,Gstkid,TkW,DB,ExtraArg,S,P,C)
- when is_integer(Col), is_integer(Row) ->
- gstk_db:insert_opt(DB,Gstkid,{pack_x,{Col,Col}}),
- gstk_db:insert_opt(DB,Gstkid,{pack_y,{Row,Row}}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C);
-gen_pack_xy({Col,{StartRow,StopRow}},Opts,Gstkid,TkW,DB,ExtraArg,S,P,C)
- when is_integer(Col) ->
- gstk_db:insert_opt(DB,Gstkid,{pack_x,{Col,Col}}),
- gstk_db:insert_opt(DB,Gstkid,{pack_y,{StartRow,StopRow}}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C);
-gen_pack_xy({{StartCol,StopCol},Row},Opts,Gstkid,TkW,DB,ExtraArg,S,P,C)
- when is_integer(Row) ->
- gstk_db:insert_opt(DB,Gstkid,{pack_x,{StartCol,StopCol}}),
- gstk_db:insert_opt(DB,Gstkid,{pack_y,{Row,Row}}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C);
-gen_pack_xy({Col,Row},Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- gstk_db:insert_opt(DB,Gstkid,{pack_x,Col}),
- gstk_db:insert_opt(DB,Gstkid,{pack_y,Row}),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C).
-
-
-gen_flush(_Opt,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- tcl2erl:ret_int(["update idletasks;expr 1+1"]),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C).
-gen_flush(_Opt,_Gstkid,_TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_int(["update idletasks;expr 1+1"]).
-
- % a hidden impl option.
-gen_keep_opt(Opt,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- gstk_db:insert_opt(DB,Gstkid,Opt),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,C).
-
-gen_children(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- make_extern_id(gstk_db:lookup_kids(DB, Gstkid#gstkid.id), DB).
-
-make_extern_id([Id|Ids], DB) ->
- [gstk:make_extern_id(Id, DB) | make_extern_id(Ids, DB)];
-make_extern_id([], _) -> [].
-
-gen_id(_Opt,#gstkid{id=Id},_TkW,DB,_ExtraArg) ->
- gstk:make_extern_id(Id, DB).
-
-gen_parent(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk:make_extern_id(Gstkid#gstkid.parent, DB).
-
-gen_type(_Opt,Gstkid,_TkW,_DB,_ExtraArg) ->
- Gstkid#gstkid.objtype.
-
-gen_beep(_,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,["bell;",$;|C]).
-
-gen_setfocus(true,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,["focus ", TkW,$;|C]);
-gen_setfocus(false,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,["focus .",$;|C]).
-
-gen_setfocus(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_focus(TkW, "focus").
-
-gen_buttonpress(On,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Cmd = bind(DB, Gstkid, TkW, buttonpress, On),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[Cmd,$;|C]).
-gen_buttonpress(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:is_inserted(DB, Gstkid, buttonpress).
-
-gen_buttonrelease(On,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Cmd = bind(DB, Gstkid, TkW, buttonrelease, On),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[Cmd,$;|C]).
-gen_buttonrelease(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:is_inserted(DB,Gstkid,buttonrelease).
-
-gen_configure(On,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Cmd = bind(DB, Gstkid, TkW, configure, On),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[Cmd,$;|C]).
-gen_configure(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:is_inserted(DB,Gstkid,configure).
-
-gen_destroy(On,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Cmd = bind(DB, Gstkid, TkW, destroy, On),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[Cmd,$;|C]).
-gen_destroy(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:is_inserted(DB,Gstkid,destroy).
-
-gen_enter(On,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Cmd = bind(DB, Gstkid, TkW, enter, On),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[Cmd,$;|C]).
-gen_enter(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:is_inserted(DB,Gstkid,enter).
-
-gen_focus_ev(On,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Cmd = bind(DB, Gstkid, TkW, focus, On),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[Cmd,$;|C]).
-gen_focus_ev(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:is_inserted(DB,Gstkid,focus).
-
-gen_keypress(On,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Cmd = bind(DB, Gstkid, TkW, keypress, On),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[Cmd,$;|C]).
-gen_keypress(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:is_inserted(DB,Gstkid,keypress).
-
-gen_keyrelease(On,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Cmd = bind(DB, Gstkid, TkW, keyrelease, On),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[Cmd,$;|C]).
-gen_keyrelease(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:is_inserted(DB,Gstkid,keyrelease).
-
-gen_leave(On,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Cmd = bind(DB, Gstkid, TkW, leave, On),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[Cmd,$;|C]).
-gen_leave(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:is_inserted(DB,Gstkid,leave).
-
-gen_motion(On,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Cmd = bind(DB, Gstkid, TkW, motion, On),
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[Cmd,$;|C]).
-gen_motion(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:is_inserted(DB,Gstkid,motion).
-
-gen_highlightbw(Wth,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -highlightt ", gstk:to_ascii(Wth)|S],P,C).
-gen_highlightbw(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_int([TkW, " cg -highlightt"]).
-
-gen_highlightbg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -highlightb ", gstk:to_color(Color)|S],P,C).
-gen_highlightbg(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW, " cg -highlightb"]).
-
-gen_highlightfg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -highlightc ", gstk:to_color(Color)|S],P,C).
-gen_highlightfg(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW, " cg -highlightc"]).
-
-
-gen_selectbw(Width,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[TkW, " conf -selectbo ", gstk:to_ascii(Width),$;|C]).
-gen_selectbw(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_int([TkW," cg -selectbo"]).
-
-gen_selectfg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[TkW, " conf -selectfo ", gstk:to_color(Color),$;|C]).
-gen_selectfg(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW," cg -selectfo"]).
-
-gen_selectbg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[TkW, " conf -selectba ", gstk:to_color(Color),$;|C]).
-gen_selectbg(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW," cg -selectba"]).
-
-gen_fg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -fg ", gstk:to_color(Color)|S],P,C).
-gen_fg(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW, " cg -fg"]).
-
-gen_bg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -bg ", gstk:to_color(Color)|S],P,C).
-gen_bg(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW, " cg -bg"]).
-
-%%----------------------------------------------------------------------
-%% Generic functions for scrolled objects
-%%----------------------------------------------------------------------
-gen_so_activebg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Col = gstk:to_color(Color),
- C2 = [TkW, ".sy conf -activeba ", Col,$;,
- TkW, ".pad.sx conf -activeba ", Col],
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[C2,$;|C]).
-gen_so_activebg(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW,".sy cg -activeba"]).
-
-gen_so_bc(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Col = gstk:to_color(Color),
- C2= [TkW, " conf -bg ", Col,$;,
- TkW, ".sy conf -highlightba ", Col,$;,
- TkW, ".pad.it conf -bg ", Col,$;,
- TkW, ".pad.sx conf -highlightba ", Col],
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[C2,$;|C]).
-gen_so_bc(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW," cg -bg"]).
-
-gen_so_scrollfg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Col = gstk:to_color(Color),
- C2=[TkW, ".sy conf -bg ", Col,$;,
- TkW, ".pad.sx conf -bg ", Col],
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[C2,$;|C]).
-gen_so_scrollfg(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW,".sy cg -bg"]).
-
-
-gen_so_scrollbg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- Col = gstk:to_color(Color),
- C2 = [TkW, ".sy conf -troughc ", Col, $;,
- TkW, ".pad.sx conf -troughc ", Col],
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[C2,$;|C]).
-
-gen_so_scrollbg(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([TkW,".sy cg -troughc"]).
-
-obj(#gstkid{widget_data=SO}) ->
- SO#so.object.
-
-gen_so_bg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- C2= [obj(Gstkid), " conf -bg ", gstk:to_color(Color)],
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[C2,$;|C]).
-gen_so_bg(_Opt,Gstkid,_TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([obj(Gstkid)," cg -bg"]).
-
-gen_so_selectbw(Width,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- C2 = [obj(Gstkid), " conf -selectbo ", gstk:to_ascii(Width)],
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[C2,$;|C]).
-gen_so_selectbw(_Opt,Gstkid,_TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_int([obj(Gstkid)," cg -selectbo"]).
-
-gen_so_selectfg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- C2 = [obj(Gstkid), " conf -selectfo ", gstk:to_color(Color)],
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[C2,$;|C]).
-gen_so_selectfg(_Opt,Gstkid,_TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([obj(Gstkid)," cg -selectfo"]).
-
-gen_so_selectbg(Color,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- C2 = [obj(Gstkid), " conf -selectba ", gstk:to_color(Color)],
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,S,P,[C2,$;|C]).
-gen_so_selectbg(_Opt,Gstkid,_TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_color([obj(Gstkid)," cg -selectba"]).
-
-gen_so_scrolls({Vscroll, Hscroll},Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- SO = Gstkid#gstkid.widget_data,
- NewSO = SO#so{hscroll=Hscroll, vscroll=Vscroll},
- C2 = scrolls_vh(TkW, Vscroll, Hscroll),
- Ngstkid = Gstkid#gstkid{widget_data=NewSO},
- gstk_db:update_widget(DB,Ngstkid),
- out_opts(Opts,Ngstkid,TkW,DB,ExtraArg,S,P,[C2,$;|C]).
-
- % read-only
-gen_so_hscroll(_Opt,#gstkid{widget_data=SO},_TkW,_DB,_) ->
- SO#so.hscroll.
-
- % read-only
-gen_so_vscroll(_Opt,#gstkid{widget_data=SO},_TkW,_DB,_) ->
- SO#so.vscroll.
-
-cursors() -> [{arrow,"top_left_arrow"},{busy,"watch"},{cross,"X_cursor"},
- {hand,"hand2"},{help,"question_arrow"},{resize,"fleur"},
- {text,"xterm"}].
-
-gen_cursor(parent,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -cur {}"|S],P,C);
-gen_cursor(Cur,Opts,Gstkid,TkW,DB,ExtraArg,S,P,C) ->
- case gs:assq(Cur,cursors()) of
- {value, TxtCur} ->
- out_opts(Opts,Gstkid,TkW,DB,ExtraArg,[" -cur ",TxtCur|S],P,C);
- _ ->
- {error,{invalid_cursor,Gstkid#gstkid.objtype,Cur}}
- end.
-gen_cursor(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- case tcl2erl:ret_str([TkW," cg -cur"]) of
- "" -> parent;
- Txt when is_list(Txt) ->
- case lists:keysearch(Txt,2,cursors()) of
- {value,{Cur,_}} -> Cur;
- _ -> {bad_result, read_cursor}
- end;
- Bad_Result -> Bad_Result
- end.
-
-gen_citem_coords(Coords,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- gstk_db:insert_opt(DB,Gstkid,{coords,Coords}),
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [TkW, " coords ", AItem," ",gstk_canvas:coords(Coords),$;|C]).
-gen_citem_coords(_Opt,Gstkid,_TkW,DB,_ExtraArg) ->
- gstk_db:opt(DB,Gstkid, coords).
-
-gen_citem_fill(none,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,[" -f {}"|S],P,C);
-gen_citem_fill(Color,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,[" -f ",gstk:to_color(Color)|S],P,C).
-gen_citem_fill(_Opt,_Gstkid,TkW,_DB,AItem) ->
- tcl2erl:ret_color([TkW, " itemcg ", AItem, " -f"]).
-
-gen_citem_lower(_,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [TkW, " lower ", AItem,$;|C]).
-
-gen_citem_raise(_,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [TkW, " raise ", AItem,$;|C]).
-
-gen_citem_move({Dx,Dy},Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- NewCoords = move_coords(Dx,Dy,gstk_db:opt(DB,Gstkid,coords)),
- gstk_db:insert_opt(DB,Gstkid,NewCoords),
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [TkW, " move ", AItem, " ",
- gstk:to_ascii(Dx), " ", gstk:to_ascii(Dy),$;|C]).
-
-move_coords(Dx,Dy,Coords) ->
- Coords2 = add_to_coords(Dx,Dy, Coords),
- {coords,Coords2}.
-
-add_to_coords(Dx,Dy,[{X,Y}|Coords]) ->
- [{X+Dx,Y+Dy}|add_to_coords(Dx,Dy,Coords)];
-add_to_coords(_,_,[]) -> [].
-
-
-gen_citem_setfocus(true,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [TkW, " focus ", AItem,$;|C]);
-gen_citem_setfocus(false,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [TkW, " focus {}",$;|C]).
-gen_citem_setfocus(_Opt,_Gstkid,TkW,_DB,_ExtraArg) ->
- tcl2erl:ret_focus(gstk:to_ascii(bug_aitem),[TkW, " focus"]).
-
-gen_citem_buttonpress(On,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [item_bind(DB, Gstkid, TkW, AItem,buttonpress, On),$;|C]).
-gen_citem_buttonrelease(On,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [item_bind(DB,Gstkid,TkW,AItem,buttonrelease, On),$;|C]).
-gen_citem_enter(On,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [item_bind(DB, Gstkid, TkW, AItem, enter, On),$;|C]).
-
-gen_citem_keypress(On,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [item_bind(DB, Gstkid, TkW, AItem, keypress, On),$;|C]).
-gen_citem_keyrelease(On,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [item_bind(DB, Gstkid, TkW, AItem, keyrelease, On),$;|C]).
-
-gen_citem_leave(On,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [item_bind(DB, Gstkid, TkW, AItem, leave, On),$;|C]).
-gen_citem_motion(On,Opts,Gstkid,TkW,DB,AItem,S,P,C) ->
- out_opts(Opts,Gstkid,TkW,DB,AItem,S,P,
- [item_bind(DB, Gstkid, TkW, AItem, motion, On),$;|C]).
-
-
-scrolls_vh(W, V, true) -> scrolls_vh(W, V, bottom);
-scrolls_vh(W, true, H) -> scrolls_vh(W, left, H);
-scrolls_vh(W, left, bottom) -> ["so_bottom_left ",W];
-scrolls_vh(W, left, top) -> ["so_top_left ",W];
-scrolls_vh(W, left, _) -> ["so_left ",W];
-scrolls_vh(W, right, bottom) -> ["so_bottom_right ",W];
-scrolls_vh(W, right, top) -> ["so_top_right ",W];
-scrolls_vh(W, right, _) -> ["so_right ",W];
-scrolls_vh(W, _, bottom) -> ["so_bottom ",W];
-scrolls_vh(W, _, top) -> ["so_top ",W];
-scrolls_vh(W, _, _) -> ["so_plain ",W].
-
-%% create version
-parse_scrolls(Opts) ->
- {Vscroll, Hscroll, NewOpts} = parse_scrolls(Opts, false, false, []),
- {Vscroll, Hscroll, [{scrolls, {Vscroll, Hscroll}} | NewOpts]}.
-
-%% config version
-parse_scrolls(Gstkid, Opts) ->
- SO = Gstkid#gstkid.widget_data,
- Vscroll = SO#so.vscroll,
- Hscroll = SO#so.hscroll,
- case parse_scrolls(Opts, Vscroll, Hscroll, []) of
- {Vscroll, Hscroll, Opts} -> Opts;
- {NewVscroll, NewHscroll, NewOpts} ->
- [{scrolls, {NewVscroll, NewHscroll}} | NewOpts]
- end.
-
-
-parse_scrolls([Option | Rest], Vscroll, Hscroll, Opts) when is_tuple(Option) ->
- case element(1, Option) of
- vscroll ->
- parse_scrolls(Rest, element(2, Option), Hscroll, Opts);
- hscroll ->
- parse_scrolls(Rest, Vscroll, element(2, Option), Opts);
- _ ->
- parse_scrolls(Rest, Vscroll, Hscroll, [Option | Opts])
- end;
-
-parse_scrolls([Option | Rest], Vscroll, Hscroll, Opts) ->
- parse_scrolls(Rest, Vscroll, Hscroll, [Option | Opts]);
-
-parse_scrolls([], Vscroll, Hscroll, Opts) ->
- {Vscroll, Hscroll, Opts}.
-
-
-%%
-%% Event bind main function
-%%
-%% Should return a list of tcl commands or invalid_option
-%%
-%% WS = Widget suffix for complex widgets
-%%
-bind(DB, Gstkid, TkW, Etype, On) ->
- WD = Gstkid#gstkid.widget_data,
- TkW2 = if is_record(WD, so) ->
- WD#so.object;
- true -> TkW
- end,
- case bind(DB, Gstkid, TkW2, Etype, On, "") of
- invalid_option -> invalid_option;
- Cmd ->
- Cmd
- end.
-
-bind(DB, Gstkid, TkW, Etype, On, WS) ->
- case On of
- true -> ebind(DB, Gstkid, TkW, Etype, WS, "");
- false -> eunbind(DB, Gstkid, TkW, Etype, WS, "");
- {true, Edata} -> ebind(DB, Gstkid, TkW, Etype, WS, Edata);
- {false, Edata} -> eunbind(DB, Gstkid, TkW, Etype, WS, Edata);
- _ -> invalid_option
- end.
-
-
-%%
-%% Event bind on
-%%
-%% Should return a list of tcl commands or invalid_option
-%%
-%% WS = Widget suffix for complex widgets
-%%
-ebind(DB, Gstkid, TkW, Etype, WS, Edata) ->
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, Edata),
- P = ["bind ", TkW, WS],
- Cmd = case Etype of
- motion -> [P, " <Motion> {erlsend ", Eref, " %x %y}"];
- keypress ->
- [P, " <KeyPress> {erlsend ", Eref," %K %N 0 0};",
- P, " <Shift-KeyPress> {erlsend ", Eref, " %K %N 1 0};",
- P, " <Control-KeyPress> {erlsend ", Eref, " %K %N 0 1};",
- P," <Control-Shift-KeyPress> {erlsend ", Eref," %K %N 1 1}"];
- keyrelease ->
- [P, " <KeyRelease> {erlsend ", Eref," %K %N 0 0};",
- P, " <Shift-KeyRelease> {erlsend ", Eref, " %K %N 1 0};",
- P, " <Control-KeyRelease> {erlsend ", Eref, " %K %N 0 1};",
- P," <Control-Shift-KeyRelease> {erlsend ",Eref," %K %N 1 1}"];
- buttonpress ->
- [P, " <ButtonPress> {erlsend ", Eref, " %b %x %y}"];
- buttonrelease ->
- [P, " <ButtonRelease> {erlsend ", Eref, " %b %x %y}"];
- leave -> [P, " <Leave> {erlsend ", Eref, "}"];
- enter -> [P, " <Enter> {erlsend ", Eref, "}"];
- destroy ->
- [P, " <Destroy> {if {\"%W\"==\"", [TkW, WS],
- "\"} {erlsend ", Eref, "}}"];
- focus ->
- [P, " <FocusIn> {erlsend ", Eref, " 1};" ,
- P, " <FocusOut> {erlsend ", Eref, " 0}"];
- configure ->
- [P, " <Configure> {if {\"%W\"==\"", [TkW, WS],
- "\"} {erlsend ", Eref, " %w %h %x %y}}"]
- end,
- Cmd.
-
-
-%%
-%% Unbind event
-%%
-%% Should return a list of tcl commands
-%% Already checked for validation in bind/5
-%%
-%% WS = Widget suffix for complex widgets
-%%
-eunbind(DB, Gstkid, TkW, Etype, WS, _Edata) ->
- gstk_db:delete_event(DB, Gstkid, Etype),
- P = ["bind ", TkW, WS],
- Cmd = case Etype of
- motion ->
- [P, " <Motion> {}"];
- keypress ->
- [P, " <KeyPress> {};",
- P, " <Shift-KeyPress> {};",
- P, " <Control-KeyPress> {};",
- P, " <Control-Shift-KeyPress> {}"];
- keyrelease ->
- [P, " <KeyRelease> {};",
- P, " <Shift-KeyRelease> {};",
- P, " <Control-KeyRelease> {};",
- P, " <Control-Shift-KeyRelease> {}"];
- buttonpress ->
- [P, " <ButtonPress> {}"];
- buttonrelease ->
- [P, " <ButtonRelease> {}"];
- leave ->
- [P, " <Leave> {}"];
- enter ->
- [P, " <Enter> {}"];
- destroy ->
- [P, " <Destroy> {}"];
- focus ->
- [P, " <FocusIn> {};",
- P, " <FocusOut> {}"];
- configure ->
- [P, " <Configure> {}"]
- end,
- Cmd.
-
-
-%%
-%% Event item bind main function
-%%
-%% Should return a list of tcl commands or invalid_option
-%%
-item_bind(DB, Gstkid, Canvas, Item, Etype, On) ->
- case On of
- true -> item_ebind(DB, Gstkid, Canvas, Item, Etype, "");
- {true, Edata} -> item_ebind(DB, Gstkid, Canvas, Item, Etype, Edata);
- _Other -> item_eunbind(DB, Gstkid, Canvas, Item, Etype)
- end.
-
-%%
-%% Event bind on
-%%
-%% Should return a list of tcl commands or invalid_option
-%%
-item_ebind(DB, Gstkid, Canvas, Item, Etype, Edata) ->
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, Edata),
- P = [Canvas, " bind ", Item],
- case Etype of
- enter -> [P, " <Enter> {erlsend ", Eref, "}"];
- leave -> [P, " <Leave> {erlsend ", Eref, "}"];
- motion -> [P, " <Motion> {erlsend ", Eref, " [",
- Canvas, " canvasx %x] [", Canvas, " canvasy %y] %x %y}"];
- keypress ->
- [P, " <Key> {erlsend ", Eref," %K %N 0 0 [",
- Canvas, " canvasx %x] [", Canvas, " canvasy %y]};",
- P, " <Shift-Key> {erlsend ", Eref, " %K %N 1 0 [",
- Canvas, " canvasx %x] [", Canvas, " canvasy %y]};",
- P, " <Control-Key> {erlsend ", Eref, " %K %N 0 1 [",
- Canvas, " canvasx %x] [", Canvas, " canvasy %y]};",
- P, " <Control-Shift-Key> {erlsend ", Eref," %K %N 1 1 [",
- Canvas, " canvasx %x] [", Canvas, " canvasy %y]}"];
- keyrelease ->
- [P, " <KeyRelease> {erlsend ", Eref," %K %N 0 0 [",
- Canvas, " canvasx %x] [", Canvas, " canvasy %y]};",
- P, " <Shift-KeyRelease> {erlsend ", Eref, " %K %N 1 0 [",
- Canvas, " canvasx %x] [", Canvas, " canvasy %y]};",
- P, " <Control-KeyRelease> {erlsend ", Eref, " %K %N 0 1 [",
- Canvas, " canvasx %x] [", Canvas, " canvasy %y]};",
- P, " <Control-Shift-KeyRelease> {erlsend ", Eref," %K %N 1 1[",
- Canvas, " canvasx %x] [", Canvas, " canvasy %y]}"];
- buttonpress ->
- [P, " <Button> {erlsend ", Eref, " %b [",
- Canvas, " canvasx %x] [", Canvas, " canvasy %y] %x %y}"];
- buttonrelease ->
- [P, " <ButtonRelease> {erlsend ", Eref, " %b [",
- Canvas, " canvasx %x] [", Canvas, " canvasy %y] %x %y}"]
- end.
-
-
-%%
-%% Unbind event
-%%
-%% Should return a list of tcl commands
-%% Already checked for validation in bind/5
-%%
-item_eunbind(DB, Gstkid, Canvas, Item, Etype) ->
- gstk_db:delete_event(DB, Gstkid, Etype),
- P = [Canvas, " bind ", Item],
- Cmd = case Etype of
- enter -> [P, " <Enter> {}"];
- leave -> [P, " <Leave> {}"];
- motion -> [P, " <Motion> {}"];
- keypress ->
- [P, " <KeyPress> {};",
- P, " <Shift-KeyPress> {};",
- P, " <Control-KeyPress> {};",
- P, " <Control-Shift-KeyPress> {}"];
- keyrelease ->
- [P, " <KeyRelease> {};",
- P, " <Shift-KeyRelease> {};",
- P, " <Control-KeyRelease> {};",
- P, " <Control-Shift-KeyRelease> {}"];
- buttonpress -> [P, " <Button> {}"];
- buttonrelease -> [P, " <ButtonRelease> {}"]
- end,
- Cmd.
-
-
-
-event(DB, Gstkid, Etype, _Edata, Args) ->
- #gstkid{owner=Ow,id=Id} = Gstkid,
- Data = gstk_db:opt(DB,Gstkid,data),
- gs_frontend:event(get(gs_frontend),Ow,{gs,Id,Etype,Data,Args}).
diff --git a/lib/gs/src/gstk_grid.erl b/lib/gs/src/gstk_grid.erl
deleted file mode 100644
index 4e8cffc018..0000000000
--- a/lib/gs/src/gstk_grid.erl
+++ /dev/null
@@ -1,284 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
--module(gstk_grid).
--compile([{nowarn_deprecated_function,{gs,val,2}}]).
-
--export([event/5,create/3,config/3,option/5,read/3,delete/2,destroy/2,
- mk_create_opts_for_child/4,read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% GRID OPTIONS
-%%
-%% rows {ViewFrom, ViewTo}
-%% columnwidths [CW1, CW2, ..., CWn]
-%% vscroll Bool | left | right
-%% hscroll Bool | top | bottom
-%% x Coord
-%% y Coord
-%% width Int
-%% height Int
-%% fg Color (lines and default line color)
-%% bg Color
-%%-----------------------------------------------------------------------------
-
--record(state,{canvas,ncols,max_range,cell_id, cell_pos,ids,db,tkcanvas}).
--record(item,{text_id,rect_id,line_id}).
-
-%%======================================================================
-%% Interfaces
-%%======================================================================
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_gridline:event(DB, Gstkid, Etype, Edata, Args).
-
-create(DB, Gstkid, Options) ->
- WinParent=Gstkid#gstkid.parent,
- {OtherOpts,CanvasOpts} = parse_opts(Options,[],[]),
- %% Why this (secret) hack? Performance reasons.
- %% if we ".canvas bind all" once and for all, then we can
- %% create lines twice as fast since we don't have to bind each line.
- C = make_ref(),
- gstk:create_impl(DB,{a_grid, {canvas,C,WinParent,
- [{secret_hack_gridit, Gstkid}
- | CanvasOpts]}}),
- CanvasGstkid = gstk_db:lookup_gstkid(DB, C),
- Wid = CanvasGstkid#gstkid.widget,
- SO = CanvasGstkid#gstkid.widget_data,
- TkCanvas = SO#so.object,
- CI=ets:new(gstk_grid_cellid,[private,set]),
- CP=ets:new(gstk_grid_cellpos,[private,set]),
- IDs=ets:new(gstk_grid_id,[private,set]),
- S=#state{db=DB,ncols=length(gs:val(columnwidths,OtherOpts)),
- canvas=C,cell_id=CI,tkcanvas=TkCanvas,cell_pos=CP,ids=IDs},
- Ngstkid = Gstkid#gstkid{widget=Wid,widget_data=S},
- gstk_db:insert_opts(DB,Ngstkid,OtherOpts),
- gstk_db:insert_widget(DB,Ngstkid),
- gstk_generic:mk_cmd_and_exec(lists:keydelete(columnwidths,1,OtherOpts),
- Ngstkid, TkCanvas,"","", DB,nop).
-
-config(DB, Gstkid, Options) ->
- #gstkid{widget=TkW,widget_data=State}=Gstkid,
- {OtherOpts,CanvasOpts} = parse_opts(Options,[],[]),
- case gstk:config_impl(DB,State#state.canvas,CanvasOpts) of
- ok ->
- SimplePreCmd = "nyi?",
- PlacePreCmd = [";place ", TkW],
- gstk_generic:mk_cmd_and_exec(OtherOpts,Gstkid,TkW,
- SimplePreCmd,PlacePreCmd,DB,State);
- Err -> Err
- end.
-
-
-option(Option, Gstkid, _TkW, DB,State) ->
- case Option of
- {rows,{From,To}} ->
- Ngstkid = reconfig_rows(From,To,Gstkid),
- gstk_db:insert_opt(DB,Gstkid,Option),
- gstk_db:update_widget(DB,Ngstkid),
- {none,Ngstkid};
- {fg,_Color} ->
- reconfig_grid(DB,Option,State),
- gstk_db:insert_opt(DB,Gstkid,Option),
- none;
- {bg,_Color} ->
- reconfig_grid(DB,Option,State),
- gstk_db:insert_opt(DB,Gstkid,Option),
- none;
- {font,_Font} ->
- reconfig_grid(DB,Option,State),
- gstk_db:insert_opt(DB,Gstkid,Option),
- none;
- {columnwidths,ColWs} ->
- gstk_db:insert_opt(DB,Gstkid,Option),
- Rows = gstk_db:opt(DB,Gstkid,rows),
- CellHeight = gstk_db:opt(DB,Gstkid,cellheight),
- gstk:config_impl(DB,State#state.canvas,
- [calc_scrollregion(Rows,ColWs,CellHeight)]),
- %% Crash upon an error msg (so we know WHY)
- {result,_} = gstk:call(["resize_grid_cols ",State#state.tkcanvas,
- " [list ",asc_tcl_colw(ColWs),"]"]),
- none;
- {cellheight,_Height} ->
- gstk_db:insert_opt(DB,Gstkid,Option),
- none;
- _ ->
- invalid_option
- end.
-
-reconfig_grid(_,_,nop) -> done;
-reconfig_grid(DB,Option,#state{tkcanvas=TkW,cell_pos=CP,
- ncols=Ncols,max_range={From,To}}) ->
- reconfig_grid(DB,TkW,Option,From,To,CP,Ncols).
-
-reconfig_grid(DB,TkW,Opt,Row,MaxRow,CellPos,Ncols) when Row =< MaxRow ->
- [{_,Item}] = ets:lookup(CellPos,{1,Row}),
- case Item#item.line_id of
- free -> empty_cell_config(DB,TkW,Row,1,Ncols,CellPos,Opt);
- GridLine ->
- gstk_gridline:config(DB,gstk_db:lookup_gstkid(DB,GridLine),
- [Opt])
- end,
- reconfig_grid(DB,TkW,Opt,Row+1,MaxRow,CellPos,Ncols);
-reconfig_grid(_,_,_,_,_,_,_) -> done.
-
-%%----------------------------------------------------------------------
-%% Purpose: Config an empty cell (i.e. has no gridline)
-%%----------------------------------------------------------------------
-empty_cell_config(DB,TkW,Row,Col,Ncols,CellPos,Opt) when Col =< Ncols ->
- [{_,Item}] = ets:lookup(CellPos,{Col,Row}),
- empty_cell_config(DB,TkW,Item,Opt),
- empty_cell_config(DB,TkW,Row,Col+1,Ncols,CellPos,Opt);
-empty_cell_config(_,_,_,_,_,_,_) -> done.
-
-empty_cell_config(_,TkW,#item{rect_id=Rid},{bg,Color}) ->
- gstk:exec([TkW," itemconf ",gstk:to_ascii(Rid)," -f ",gstk:to_color(Color)]);
-empty_cell_config(_,TkW,#item{rect_id=Rid,text_id=Tid},{fg,Color}) ->
- Acolor = gstk:to_color(Color),
- Pre = [TkW," itemconf "],
- RectStr = [Pre, gstk:to_ascii(Rid)," -outline ",Acolor],
- TexdStr = [Pre, gstk:to_ascii(Tid)," -fi ",Acolor],
- gstk:exec([RectStr,$;,TexdStr]);
-empty_cell_config(DB,TkW,#item{text_id=Tid},{font,Font}) ->
- gstk:exec([TkW," itemconf ",gstk:to_ascii(Tid)," -font ",
- gstk_font:choose_ascii(DB,Font)]);
-empty_cell_config(_,_,_,_) -> done.
-
-
-
-reconfig_rows(From, To, Gstkid) ->
- #gstkid{widget_data=State,id=Id} = Gstkid,
- #state{tkcanvas=TkCanvas,cell_pos=CP,cell_id=CI,
- canvas=C,db=DB,max_range=Range}=State,
- NewRange =
- if Range == undefined ->
- mkgrid(DB,CP,CI,TkCanvas,Id,From,To),
- {From,To};
- true ->
- {Top,Bot} = Range,
- if
- From < Top -> % we need more rects above
- mkgrid(DB,CP,CI,TkCanvas,Id,From,Top-1);
- true -> true
- end,
- if
- To > Bot -> % we need more rects below
- mkgrid(DB,CP,CI,TkCanvas,Id,Bot+1,To);
- true -> true
- end,
- {lists:min([Top, From]), lists:max([Bot, To])}
- end,
- gstk:config_impl(DB,C,[calc_scrollregion({From,To},
- gstk_db:opt(DB,Id,columnwidths),
- gstk_db:opt(DB,Id,cellheight))]),
- S2 = State#state{max_range=NewRange},
- Gstkid#gstkid{widget_data=S2}.
-
-read(DB,Gstkid,Opt) ->
- State = Gstkid#gstkid.widget_data,
- case lists:member(Opt,[x,y,width,height,hscroll,vscroll]) of
- true -> gstk:read_impl(DB,State#state.canvas,Opt);
- false ->
- gstk_generic:read_option(DB, Gstkid, Opt,State)
- end.
-
-read_option(Option,Gstkid,_TkW,DB,State) ->
- case Option of
- {obj_at_row,Row} ->
- case ets:lookup(State#state.cell_pos,{1,Row}) of
- [{_pos,Item}] ->
- case Item#item.line_id of
- free -> undefined;
- GridLine ->
- gstk:make_extern_id(GridLine, DB)
- end;
- _ -> undefined
- end;
- Opt -> gstk_db:opt(DB,Gstkid#gstkid.id,Opt,undefined)
- end.
-
-
-%%----------------------------------------------------------------------
-%% Is always called.
-%% Clean-up my specific side-effect stuff.
-%%----------------------------------------------------------------------
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- State = Gstkid#gstkid.widget_data,
- #state{canvas=C,cell_pos=CP,cell_id=CIs, ids=IDs} = State,
- ets:delete(CP),
- ets:delete(CIs),
- ets:delete(IDs),
- {Gstkid#gstkid.parent, Gstkid#gstkid.id, gstk_grid, [C]}.
-
-%%----------------------------------------------------------------------
-%% Is called iff my parent is not also destroyed.
-%%----------------------------------------------------------------------
-destroy(DB, Canvas) ->
- gstk:destroy_impl(DB,gstk_db:lookup_gstkid(DB,Canvas)).
-
-mk_create_opts_for_child(DB,Cgstkid, Pgstkid, Opts) ->
- gstk_generic:mk_create_opts_for_child(DB,Cgstkid,Pgstkid,Opts).
-
-mkgrid(DB,CellPos,CellIds,TkCanvas,Id,From,To) ->
- ColWs = gstk_db:opt(DB,Id,columnwidths),
- AscColW = ["[list ",asc_tcl_colw(ColWs),"]"],
- Font = gstk_font:choose_ascii(DB,gstk_db:opt(DB,Id,font)),
- Fg = gstk:to_color(gstk_db:opt(DB,Id,fg)),
- Bg = gstk:to_color(gstk_db:opt(DB,Id,bg)),
- Objs = tcl2erl:ret_list(["mkgrid ",TkCanvas," ",AscColW," ",
- gstk:to_ascii(From)," ",
- gstk:to_ascii(To)," ",
- gstk:to_ascii(gstk_db:opt(DB,Id,cellheight))," ",
- Font," ",Fg," ",Bg]),
- insert_objs(CellPos,CellIds,From,To,1,length(ColWs)+1,Objs).
-
-insert_objs(_,_,_,_,_,_,[]) -> done;
-insert_objs(CP,CI,Row,T,MaxCol,MaxCol,Objs) ->
- insert_objs(CP,CI,Row+1,T,1,MaxCol,Objs);
-insert_objs(CellPos,CellIds,Row,To,Col,Ncols,[RectId,TextId|Objs]) ->
- ets:insert(CellPos,{{Col,Row},
- #item{text_id=TextId,rect_id=RectId,line_id=free}}),
- ets:insert(CellIds,{RectId,{Col,Row}}),
- ets:insert(CellIds,{TextId,{Col,Row}}),
- insert_objs(CellPos,CellIds,Row,To,Col+1,Ncols,Objs).
-
-asc_tcl_colw([]) -> "";
-asc_tcl_colw([Int|T]) -> [gstk:to_ascii(Int)," "|asc_tcl_colw(T)].
-
-%%----------------------------------------------------------------------
-%% Args: Cols list of column sizes (measured in n-chars)
-%%----------------------------------------------------------------------
-calc_scrollregion({From, To}, Cols, Height) ->
- {scrollregion, {0, ((From-1) * Height) + From,
- lists:sum(Cols)+length(Cols)+1, (To * Height)+ To+1}}.
-
-parse_opts([],OtherOpts,CanvasOpts) -> {OtherOpts,CanvasOpts};
-parse_opts([{Key,Val}|Opts],OtherOpts,CanvasOpts) ->
- case lists:member(Key,[x,y,width,height,vscroll,hscroll]) of
- true -> parse_opts(Opts,OtherOpts,[{Key,Val}|CanvasOpts]);
- false -> parse_opts(Opts,[{Key,Val}|OtherOpts],CanvasOpts)
- end;
-parse_opts([Opt|Opts],OtherOpts,CanvasOpts) ->
- parse_opts(Opts,[Opt|OtherOpts],CanvasOpts).
-
diff --git a/lib/gs/src/gstk_gridline.erl b/lib/gs/src/gstk_gridline.erl
deleted file mode 100644
index d504ed5319..0000000000
--- a/lib/gs/src/gstk_gridline.erl
+++ /dev/null
@@ -1,301 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
--module(gstk_gridline).
--compile([{nowarn_deprecated_function,{gs,val,2}},
- {nowarn_deprecated_function,{gs,val,3}}]).
-
--export([event/5,create/3,config/3,option/5,read/3,delete/2,destroy/3,
- read_option/5]).
-
--include("gstk.hrl").
--record(state,{canvas,ncols,max_range,cell_id, cell_pos,ids,db,tkcanvas}).
--record(item,{text_id,rect_id,line_id}).
-
-%%-----------------------------------------------------------------------------
-%% GRIDLINE OPTIONS
-%%
-%% text Text
-%% row Row
-%% data Data
-%% fg Color (default is the same as grid fg)
-%% click Bool
-%%
-%%-----------------------------------------------------------------------------
-
-create(DB, Gstkid, Options) ->
- Pgstkid = gstk_db:lookup_gstkid(DB,Gstkid#gstkid.parent),
- Id = Gstkid#gstkid.id,
- #gstkid{widget_data=State} = Pgstkid,
- #state{cell_pos=CP,tkcanvas=TkW,ncols=Ncols} = State,
- Row = gs:val(row,Options),
- case check_row(CP,Row) of
- {error,Reason} -> {error,Reason};
- ok ->
- Ngstkid = Gstkid#gstkid{widget=TkW},
- gstk_db:insert_opts(DB,Id,[{data,[]},{row,Row}]),
- update_cp_db(Ncols,Row,Id,CP),
- config_line(DB,Pgstkid,Ngstkid,Row,Options),
- Ngstkid
- end.
-
-%%----------------------------------------------------------------------
-%% Returns: ok|false
-%%----------------------------------------------------------------------
-check_row(_CellPos,undefined) ->
- {error,{gridline,{row,undefined}}};
-check_row(CellPos,Row) ->
- case ets:lookup(CellPos,{1,Row}) of
- [] ->
- {error,{gridline,row_outside_range,Row}};
- [{_,Item}] ->
- case Item#item.line_id of
- free -> ok;
- _ ->
- {error,{gridline,row_is_occupied,Row}}
- end
- end.
-
-%%----------------------------------------------------------------------
-%% s => text item
-%% p => rect item
-%%----------------------------------------------------------------------
-option(Option, _Gstkid, _TkW, DB,_) ->
- case Option of
- {{bg,_Item}, Color} -> {p,[" -f ", gstk:to_color(Color)]};
- {{text,_Item},Text} -> {s, [" -te ", gstk:to_ascii(Text)]};
- {{fg,_Item},Color} -> {sp,{[" -fi ", gstk:to_color(Color)],
- [" -outline ", gstk:to_color(Color)]}};
- {{font,_Item},Font} -> {s,[" -font ",gstk_font:choose_ascii(DB,Font)]};
- _ -> invalid_option
- end.
-
-%%----------------------------------------------------------------------
-%% Is always called.
-%% Clean-up my specific side-effect stuff.
-%%----------------------------------------------------------------------
-delete(DB, Gstkid) ->
- Row = gstk_db:opt(DB,Gstkid,row),
- gstk_db:delete_widget(DB, Gstkid),
- {Gstkid#gstkid.parent, Gstkid#gstkid.id, gstk_gridline,[Gstkid, Row]}.
-
-%%----------------------------------------------------------------------
-%% Is called iff my parent is not also destroyed.
-%%----------------------------------------------------------------------
-destroy(DB, Lgstkid, Row) ->
- Ggstkid = gstk_db:lookup_gstkid(DB,Lgstkid#gstkid.parent),
- #gstkid{widget_data=State} = Ggstkid,
- config_line(DB,Ggstkid,Lgstkid,Row,
- [{bg,gstk_db:opt(DB,Ggstkid,bg)},
- {fg,gstk_db:opt(DB,Ggstkid,fg)},{text,""}]),
- Ncols = State#state.ncols,
- update_cp_db(Ncols,Row,free,State#state.cell_pos).
-
-
-config(DB, Gstkid, Opts) ->
- Pgstkid = gstk_db:lookup_gstkid(DB,Gstkid#gstkid.parent),
- case {gs:val(row,Opts,missing),gstk_db:opt(DB,Gstkid,row)} of
- {Row,Row} -> % stay here...
- config_line(DB,Pgstkid,Gstkid,Row,Opts);
- {missing,Row} -> % stay here...
- config_line(DB,Pgstkid,Gstkid,Row,Opts);
- {NewRow,OldRow} ->
- config_line(DB,Pgstkid,Gstkid,OldRow,Opts),
- Ngstkid = gstk_db:lookup_gstkid(DB,Gstkid#gstkid.id),
- case move_line(NewRow,OldRow,DB,Pgstkid#gstkid.widget_data,Ngstkid) of
- true ->
- gstk_db:insert_opt(DB,Ngstkid,{row,NewRow}),
- ok;
- {error,_Reason} -> ok
- end
- end,
- ok.
-
-%%----------------------------------------------------------------------
-%% Returns: true|false depending on if operation succeeded
-%%----------------------------------------------------------------------
-move_line(NewRow,OldRow,_DB,State,_Ngstkid) ->
- case ets:lookup(State#state.cell_pos,{1,NewRow}) of
- [] ->
- {error,{gridline,row_outside_grid,NewRow}};
- [{_,#item{line_id=Lid}}] when Lid =/= free->
- {error,{gridline,new_row_occupied,NewRow}};
- [{_,_NewItem}] ->
- #state{tkcanvas=TkW,ncols=Ncols,cell_pos=CP} = State,
- swap_lines(TkW,OldRow,NewRow,1,Ncols,CP),
- true
- end.
-
-%%----------------------------------------------------------------------
-%% Purpose: swaps an empty newrow with a (oldrow) gridline
-%%----------------------------------------------------------------------
-swap_lines(TkW,OldRow,NewRow,Col,MaxCol,CellPos) when Col =< MaxCol ->
- [{_,NewItem}] = ets:lookup(CellPos,{Col,NewRow}),
- [{_,OldItem}] = ets:lookup(CellPos,{Col,OldRow}),
- swap_cells(TkW,NewItem,OldItem),
- ets:insert(CellPos,{{Col,NewRow},OldItem}),
- ets:insert(CellPos,{{Col,OldRow},NewItem}),
- swap_lines(TkW,OldRow,NewRow,Col+1,MaxCol,CellPos);
-swap_lines(_,_,_,_,_,_) -> done.
-
-swap_cells(TkW,#item{rect_id=NewRectId,text_id=NewTextId},
- #item{rect_id=OldRectId,text_id=OldTextId}) ->
- Aorid = gstk:to_ascii(OldRectId),
- Aotid = gstk:to_ascii(OldTextId),
- Anrid = gstk:to_ascii(NewRectId),
- Antid = gstk:to_ascii(NewTextId),
- Pre = [TkW," coords "],
- OldRectCoords = tcl2erl:ret_str([Pre,Aorid]),
- OldTextCoords = tcl2erl:ret_str([Pre,Aotid]),
- NewRectCoords = tcl2erl:ret_str([Pre,Anrid]),
- NewTextCoords = tcl2erl:ret_str([Pre,Antid]),
- gstk:exec([Pre,Aotid," ",NewTextCoords]),
- gstk:exec([Pre,Antid," ",OldTextCoords]),
- gstk:exec([Pre,Aorid," ",NewRectCoords]),
- gstk:exec([Pre,Anrid," ",OldRectCoords]).
-
-%%----------------------------------------------------------------------
-%% Pre: {row,Row} option is taken care of.
-%%----------------------------------------------------------------------
-config_line(DB,Pgstkid,Lgstkid,Row,Opts) ->
- #gstkid{widget_data=State, widget=TkW} = Pgstkid,
- #state{cell_pos=CP,ncols=Ncols} = State,
- Ropts = transform_opts(Opts,Ncols),
- RestOpts = config_gridline(DB,CP,Lgstkid,Ncols,Row,Ropts),
- gstk_generic:mk_cmd_and_exec(RestOpts,Lgstkid,TkW,"","",DB).
-
-%%----------------------------------------------------------------------
-%% Returns: non-processed options
-%%----------------------------------------------------------------------
-config_gridline(_DB,_CP,_Gstkid,0,_Row,Opts) ->
- Opts;
-config_gridline(DB,CP,Gstkid,Col,Row,Opts) ->
- {ColOpts,OtherOpts} = opts_for_col(Col,Opts,[],[]),
- if
- ColOpts==[] -> done;
- true ->
- [{_pos,Item}] = ets:lookup(CP,{Col,Row}),
- TkW = Gstkid#gstkid.widget,
- TextPre = [TkW," itemconf ",gstk:to_ascii(Item#item.text_id)],
- RectPre = [$;,TkW," itemconf ",gstk:to_ascii(Item#item.rect_id)],
- case gstk_generic:make_command(ColOpts,Gstkid,TkW,
- TextPre,RectPre,DB) of
- [] -> ok;
- {error,_Reason} -> ok;
- Cmd -> gstk:exec(Cmd)
- end
- end,
- config_gridline(DB,CP,Gstkid,Col-1,Row,OtherOpts).
-
-opts_for_col(Col,[{{Key,Col},Val}|Opts],ColOpts,RestOpts) ->
- opts_for_col(Col,Opts,[{{Key,Col},Val}|ColOpts],RestOpts);
-opts_for_col(Col,[Opt|Opts],ColOpts,RestOpts) ->
- opts_for_col(Col,Opts,ColOpts,[Opt|RestOpts]);
-opts_for_col(_Col,[],ColOpts,RestOpts) -> {ColOpts,RestOpts}.
-
-%%----------------------------------------------------------------------
-%% {Key,{Col,Val}} becomes {{Key,Col},Val}
-%% {Key,Val} becomes {{Key,1},Val}...{{Key,Ncol},Val}
-%%----------------------------------------------------------------------
-transform_opts([], _Ncols) -> [];
-transform_opts([{{Key,Col},Val} | Opts],Ncols) ->
- [{{Key,Col},Val}|transform_opts(Opts,Ncols)];
-transform_opts([{Key,{Col,Val}}|Opts],Ncols) when is_integer(Col) ->
- [{{Key,Col},Val}|transform_opts(Opts,Ncols)];
-transform_opts([{Key,Val}|Opts],Ncols) ->
- case lists:member(Key,[fg,bg,text,font]) of
- true ->
- lists:append(expand_to_all_cols(Key,Val,Ncols),
- transform_opts(Opts,Ncols));
- false ->
- case lists:member(Key,[click,doubleclick,row]) of
- true ->
- [{keep_opt,{Key,Val}}|transform_opts(Opts,Ncols)];
- false ->
- [{Key,Val}|transform_opts(Opts,Ncols)]
- end
- end;
-transform_opts([Opt|Opts],Ncols) ->
- [Opt|transform_opts(Opts,Ncols)].
-
-expand_to_all_cols(Key,Val,1) ->
- [{{Key,1},Val}];
-expand_to_all_cols(Key,Val,Col) ->
- [{{Key,Col},Val}|expand_to_all_cols(Key,Val,Col-1)].
-
-
-read(DB, Gstkid, Opt) ->
- Pgstkid = gstk_db:lookup_gstkid(DB,Gstkid#gstkid.parent),
- gstk_generic:read_option(DB, Gstkid, Opt,Pgstkid).
-
-read_option({font,Column},Gstkid, _TkW,DB,Pgstkid) ->
- case gstk_db:opt_or_not(DB,Gstkid,{font,Column}) of
- false -> gstk_db:opt(DB,Pgstkid,font);
- {value,V} -> V
- end;
-read_option({Opt,Column},Gstkid, TkW,DB,#gstkid{widget_data=State}) ->
- Row = gstk_db:opt(DB,Gstkid,row),
- [{_pos,Item}] = ets:lookup(State#state.cell_pos,{Column,Row}),
- Rid = gstk:to_ascii(Item#item.rect_id),
- Tid = gstk:to_ascii(Item#item.text_id),
- Pre = [TkW," itemcg "],
- case Opt of
- bg -> tcl2erl:ret_color([Pre,Rid," -f"]);
- fg -> tcl2erl:ret_color([Pre,Tid," -fi"]);
- text -> tcl2erl:ret_str([Pre,Tid," -te"]);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, {Opt,Column}}}
- end;
-read_option(Option,Gstkid,TkW,DB,Pgstkid) ->
- case lists:member(Option,[bg,fg,text]) of
- true -> read_option({Option,1},Gstkid,TkW,DB,Pgstkid);
- false -> gstk_db:opt(DB,Gstkid,Option,undefined)
- end.
-
-update_cp_db(0,_Row,_,_) -> ok;
-update_cp_db(Col,Row,ID,CP) ->
- [{_,Item}] = ets:lookup(CP,{Col,Row}),
- ets:insert(CP,{{Col,Row},Item#item{line_id = ID}}),
- update_cp_db(Col-1,Row,ID,CP).
-
-
-event(DB, GridGstkid, Etype, _Edata, [CanItem]) ->
- State = GridGstkid#gstkid.widget_data,
- #state{cell_pos=CP,cell_id=CIs,tkcanvas=TkW} = State,
- case ets:lookup(CIs,CanItem) of
- [{_id,{Col,Row}}] ->
- [{_pos,Item}] = ets:lookup(CP,{Col,Row}),
- case Item#item.line_id of
- free -> ok;
- Id ->
- Lgstkid = gstk_db:lookup_gstkid(DB,Id),
- case gstk_db:opt_or_not(DB,Lgstkid,Etype) of
- {value,true} ->
- Txt = read_option({text,Col},Lgstkid,TkW,
- DB,GridGstkid),
- gstk_generic:event(DB,Lgstkid,Etype,dummy,
- [Col,Row,Txt]);
- _ -> ok
- end
- end;
- _ -> ok
- end;
-event(_DB, _Gstkid, _Etype, _Edata, _Args) ->
- ok.
diff --git a/lib/gs/src/gstk_gs.erl b/lib/gs/src/gstk_gs.erl
deleted file mode 100644
index 80be066626..0000000000
--- a/lib/gs/src/gstk_gs.erl
+++ /dev/null
@@ -1,54 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%%% Purpose : The GS object
-
--module(gstk_gs).
-
--export([mk_create_opts_for_child/4,
- config/3,
- read/3,
- read_option/5,
- option/5]).
-
--include("gstk.hrl").
-
-%%----------------------------------------------------------------------
-%% The GS object implementation
-%%----------------------------------------------------------------------
-
-mk_create_opts_for_child(DB,Cgstkid, Pgstkid, Opts) ->
- gstk_generic:mk_create_opts_for_child(DB,Cgstkid,Pgstkid,Opts).
-
-config(DB, Gstkid, Opts) ->
- Cmd=gstk_generic:make_command(Opts,Gstkid,"",DB),
- gstk:exec(Cmd),
- ok.
-
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-% No options of my own
-read_option(Option,Gstkid, _TkW,_DB,_) ->
- {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}.
-
-option(_Option, _Gstkid, _TkW, _DB,_) ->
- invalid_option.
diff --git a/lib/gs/src/gstk_image.erl b/lib/gs/src/gstk_image.erl
deleted file mode 100644
index 124bda77a2..0000000000
--- a/lib/gs/src/gstk_image.erl
+++ /dev/null
@@ -1,321 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Image Type
-%% ------------------------------------------------------------
-
--module(gstk_image).
--compile([{nowarn_deprecated_function,{gs,pair,2}}]).
-
-%%-----------------------------------------------------------------------------
-%% BITMAP OPTIONS
-%%
-%% Attributes:
-%% anchor n|w|e|s|nw|sw|ne|se|center
-%% bg Color
-%% bitmap String
-%% coords [{X,Y}]
-%% data Data
-%% fg Color
-%%
-%% Attributes for gifs only:
-%% pix_val {{X,Y},Color}|{{{X1,Y1},{X2,Y2}},Color]
-%% save String
-%% refresh
-%%
-%% Commands:
-%% lower
-%% move {Dx, Dy}
-%% raise
-%% scale {Xo, Yo, Sx, Sy}
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% pix_val {X,Y}
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%%
-
--export([create/3, config/3, read/3, delete/2, destroy/3, event/5,
- option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%------------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/7
-%% Purpose : Create a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Objmod - An atom, this module
-%% Objtype - An atom, the logical widget type
-%% Owner - Pid of the creator
-%% Name - An atom naming the widget
-%% Parent - Gsid of the parent
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [Gsid_of_new_widget | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, Gstkid, Opts) ->
- case pickout_type(Opts) of
- bitmap ->
- create(bitmap,DB, Gstkid, Opts);
- _gif -> %%Default gif
- create(gif,DB, Gstkid, Opts)
- end.
-
-create(gif,DB, Gstkid, Opts) ->
- case pickout_coords(Opts, []) of
- {error, Error} ->
- {bad_result, Error};
- {Coords, NewOpts} ->
- CCmd = "image create photo",
- case tcl2erl:ret_atom(CCmd) of
- Photo_item when is_atom(Photo_item) ->
- #gstkid{parent=Parent,owner=Owner,id=Id}=Gstkid,
- Pgstkid = gstk_db:lookup_gstkid(DB, Parent, Owner),
- SO = Pgstkid#gstkid.widget_data,
- CanvasTkW = SO#so.object,
- Photo_item_s = atom_to_list(Photo_item),
- gstk_db:insert_opt(DB,Id,gs:pair(coords,Opts)),
- Ngstkid=Gstkid#gstkid{widget=CanvasTkW,
- widget_data={Photo_item_s,unknown}},
- gstk_db:update_widget(DB,Ngstkid),
- MCmd = [CanvasTkW," create image ",Coords," -image ",
- Photo_item_s," -anchor nw"],
- case gstk_canvas:make_command(NewOpts, Ngstkid,
- CanvasTkW, MCmd, DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- case tcl2erl:ret_int(Cmd) of
- Item when is_integer(Item) ->
- %% buu, not nice
- G2 = gstk_db:lookup_gstkid(DB,Id),
- NewWidget = {Photo_item_s,Item},
- NewGstkid = G2#gstkid{widget_data=NewWidget},
- gstk_db:insert_widget(DB, NewGstkid),
- NewGstkid;
- Bad_result ->
- {error,Bad_result}
- end
- end;
- Bad_result ->
- {error,Bad_result}
- end
- end;
-
-create(bitmap,DB, Gstkid, Opts) ->
- case pickout_coords(Opts, []) of
- {error, Error} ->
- {bad_result, Error};
- {Coords, NewOpts} ->
- #gstkid{parent=Parent,owner=Owner,id=Id}=Gstkid,
- Pgstkid = gstk_db:lookup_gstkid(DB, Parent, Owner),
- SO = Pgstkid#gstkid.widget_data,
- CanvasTkW = SO#so.object,
- gstk_db:insert_opt(DB,Id,gs:pair(coords,Opts)),
- Ngstkid=Gstkid#gstkid{widget=CanvasTkW, widget_data=no_item},
- gstk_db:update_widget(DB,Ngstkid),
- MCmd = [CanvasTkW," create bi ", Coords],
- gstk_canvas:mk_cmd_and_call(NewOpts,Ngstkid, CanvasTkW, MCmd,DB)
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- {Canvas, Item} = get_widget(Gstkid),
- AItem = gstk:to_ascii(Item),
- SCmd = [Canvas, " itemconf ", AItem],
- gstk_canvas:mk_cmd_and_exec(Opts, Gstkid, Canvas, AItem, SCmd, DB).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- {_, Item} = get_widget(Gstkid),
- gstk_generic:read_option(DB,Gstkid,Opt,[gstk:to_ascii(Item)]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy | {Parent, Objmod, Args}.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- #gstkid{parent=P,id=ID}=Gstkid,
- {Canvas, Item} = get_widget(Gstkid),
- {P, ID, gstk_image, [Canvas, Item]}.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : destroy/3
-%% Purpose : Destroy a widget
-%% Args : DB - The Database
-%% Canvas - The canvas tk widget
-%% Item - The item number to destroy
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-destroy(_DB, Canvas, Item) ->
- gstk:exec([Canvas, " delete ", gstk:to_ascii(Item)]).
-
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-%%------------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/5
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% MainW - The main tk-widget
-%% Canvas - The canvas tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, _Canvas, _DB, _AItem) ->
- case Option of
- {bitmap, Bitmap} ->
- BF = re:replace(Bitmap, [92,92], "/", [global,{return,list}]),
- {s, [" -bi @", BF]};
- {load_gif, File} ->
- F2 = re:replace(File, [92,92], "/", [global,{return,list}]),
- {Photo_item, _item} = Gstkid#gstkid.widget_data,
- {c,[Photo_item, " configure -file ", gstk:to_ascii(F2)]};
- {pix_val, {Coords,Color}} ->
- {Photo_item, _item} = Gstkid#gstkid.widget_data,
- {c, [Photo_item, " put ", gstk:to_color(Color), " -to ",
- coords(Coords)]};
- {save_gif, Name} ->
- {Photo_item, _item} = Gstkid#gstkid.widget_data,
- {c, [Photo_item, " write ", gstk:to_ascii(Name)]};
- {fg, Color} -> {s, [" -fo ", gstk:to_color(Color)]};
- {bg, Color} -> {s, [" -ba ", gstk:to_color(Color)]};
- {anchor, How} -> {s, [" -anchor ", gstk:to_ascii(How)]};
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option, Gstkid, Canvas, _DB, AItem) ->
- case Option of
- anchor -> tcl2erl:ret_atom([Canvas," itemcget ",AItem," -anchor"]);
- bg -> tcl2erl:ret_color([Canvas, " itemcget ", AItem, " -ba"]);
- bitmap -> tcl2erl:ret_file([Canvas, " itemcget ", AItem, " -bi"]);
- fg -> tcl2erl:ret_color([Canvas, " itemcget ", AItem, " -fo"]);
- {pix_val,{X,Y}} ->
- {Photo_item, _item} = Gstkid#gstkid.widget_data,
- ret_photo_color([Photo_item," get ",coords({X,Y})]);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-ret_photo_color(Cmd) ->
- case gstk:call(Cmd) of
- {result,Str} ->
- {ok, [R,G,B],[]} = io_lib:fread("~d ~d ~d", Str),
- {R,G,B};
- Bad_result -> Bad_result
- end.
-
-
-%%------------------------------------------------------------------------------
-%% PRIMITIVES
-%%------------------------------------------------------------------------------
-get_widget(#gstkid{widget=Canvas,widget_data={_Photo_item,Item}}) ->
- {Canvas,Item};
-get_widget(#gstkid{widget=Canvas,widget_data=Item}) ->
- {Canvas,Item}.
-
-pickout_coords([{coords,Coords} | Rest], Opts) when length(Coords) == 1 ->
- case coords(Coords) of
- invalid ->
- {error, "An image must have two coordinates"};
- RealCoords ->
- {RealCoords, lists:append(Rest, Opts)}
- end;
-pickout_coords([Opt | Rest], Opts) ->
- pickout_coords(Rest, [Opt|Opts]);
-pickout_coords([], _Opts) ->
- {error, "An image must have two coordinates"}.
-
-coords({X,Y}) when is_number(X),is_number(Y) ->
- [gstk:to_ascii(X), " ", gstk:to_ascii(Y), " "];
-coords([{X,Y} | R]) when is_number(X),is_number(Y) ->
- [gstk:to_ascii(X), " ", gstk:to_ascii(Y), " ", coords(R)];
-coords({{X1,Y1},{X2,Y2}}) when is_number(X1),is_number(Y1),is_number(X2),is_number(Y2) ->
- [gstk:to_ascii(X1), " ", gstk:to_ascii(Y1)," ",
- gstk:to_ascii(X2), " ", gstk:to_ascii(Y2)];
-coords([_]) -> %% not a pair
- invalid;
-coords([]) ->
- [].
-
-
-pickout_type([{bitmap,_Str}|_Options]) ->
- bitmap;
-pickout_type([{gif,_Str}|_Options]) ->
- gif;
-pickout_type([]) ->
- none;
-pickout_type([_|Tail]) ->
- pickout_type(Tail).
-
-%% ----- Done -----
-
diff --git a/lib/gs/src/gstk_label.erl b/lib/gs/src/gstk_label.erl
deleted file mode 100644
index 2cdd36f331..0000000000
--- a/lib/gs/src/gstk_label.erl
+++ /dev/null
@@ -1,183 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Label Type
-%% ------------------------------------------------------------
-
--module(gstk_label).
-%%------------------------------------------------------------------------------
-%% LABEL OPTIONS
-%%
-%% Attributes:
-%% align n,w,s,e,nw,se,ne,sw,center
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% bg Color
-%% bw Int
-%% data Data
-%% fg Color
-%% font Font
-%% height Int
-%% highlightbg Color
-%% highlightbw Int
-%% highlightfg Color
-%% justify left|right|center
-%% label {text, String} | {image, BitmapFile}
-%% padx Int (Pixels)
-%% pady Int (Pixels)
-%% relief Relief [flat|raised|sunken|ridge|groove]
-%% underline Int
-%% width Int
-%% wraplength Int
-%% x Int
-%% y Int
-%%
-%% Commands:
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% configure [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%% cursor ??????
-%% focus ?????? (-takefocus)
-%%
-
--export([create/3,config/3,read/3,delete/2,event/5,option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/3
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- TkW = gstk_generic:mk_tkw_child(DB,GstkId),
- PlacePreCmd = [";place ", TkW],
- Ngstkid = GstkId#gstkid{widget=TkW},
- case gstk_generic:make_command(Opts,Ngstkid,TkW,"",PlacePreCmd,DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(["label ", TkW,Cmd]),
- Ngstkid
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- TkW = Gstkid#gstkid.widget,
- SimplePreCmd = [TkW, " conf"],
- PlacePreCmd = [";place ", TkW],
- gstk_generic:mk_cmd_and_exec(Opts,Gstkid,TkW,SimplePreCmd,PlacePreCmd,DB).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% TkW - The tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, _Gstkid, _TkW, _DB,_) ->
- case Option of
- {underline, Int} -> {s, [" -und ", gstk:to_ascii(Int)]};
- {wraplength, Int} -> {s, [" -wra ", gstk:to_ascii(Int)]};
- _ -> invalid_option
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/4
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,Gstkid,TkW,_DB,_) ->
- case Option of
- underline -> tcl2erl:ret_int([TkW," cg -und"]);
- wraplength -> tcl2erl:ret_int([TkW," cg -wra"]);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-%%% ----- Done -----
-
diff --git a/lib/gs/src/gstk_line.erl b/lib/gs/src/gstk_line.erl
deleted file mode 100644
index 18c87b2011..0000000000
--- a/lib/gs/src/gstk_line.erl
+++ /dev/null
@@ -1,203 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Line Type
-%% ------------------------------------------------------------
-
--module(gstk_line).
-
-
-%%-----------------------------------------------------------------------------
-%% LINE OPTIONS
-%%
-%% Attributes:
-%% arrow none | first | last | both
-%% capstyle butt | projecting | round
-%% coords [{X1,Y1}, {X2,Y2} | {Xn,Yn}]
-%% data Data
-%% fg Color
-%% joinstyle miter | bevel | round
-%% smooth Bool
-%% splinesteps Int
-%% stipple Bool
-%% width Wth
-%%
-%% Commands:
-%% lower
-%% move {Dx, Dy}
-%% raise
-%% scale {Xo, Yo, Sx, Sy}
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%%
-
--export([create/3, config/3, read/3, delete/2, destroy/3, event/5,
- option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/3
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, Gstkid, Opts) ->
- case pickout_coords(Opts, []) of
- {error, Error} ->
- {bad_result, Error};
- {Coords, NewOpts} ->
- Ngstkid=gstk_canvas:upd_gstkid(DB, Gstkid, Opts),
- #gstkid{widget=CanvasTkW}=Ngstkid,
- MCmd = [CanvasTkW, " create li ", Coords],
- gstk_canvas:mk_cmd_and_call(NewOpts,Ngstkid, CanvasTkW, MCmd, DB)
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- gstk_canvas:item_config(DB, Gstkid, Opts).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- Item = Gstkid#gstkid.widget_data,
- gstk_generic:read_option(DB,Gstkid,Opt,[gstk:to_ascii(Item)]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy | {Parent, Objmod, Args}.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_canvas:item_delete_impl(DB,Gstkid).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : destroy/3
-%% Purpose : Destroy a widget
-%% Args : DB - The Database
-%% Canvas - The canvas tk widget
-%% Item - The item number to destroy
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-destroy(_DB, Canvas, Item) ->
- gstk:exec([Canvas, " delete ", gstk:to_ascii(Item)]).
-
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/5
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% MainW - The main tk-widget
-%% Canvas - The canvas tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, _Gstkid, _Canvas, _DB, _AItem) ->
- case Option of
- {arrow, Where} -> {s, [" -arrow ", gstk:to_ascii(Where)]};
- {capstyle, Style} -> {s, [" -ca ", gstk:to_ascii(Style)]};
- {fg, Color} -> {s, [" -f ", gstk:to_color(Color)]};
- {joinstyle, Style} -> {s, [" -jo ", gstk:to_ascii(Style)]};
- {smooth, Bool} -> {s, [" -sm ", gstk:to_ascii(Bool)]};
- {splinesteps, Int} -> {s, [" -sp ", gstk:to_ascii(Int)]};
- {width, Int} -> {s, [" -w ", gstk:to_ascii(Int)]};
-
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option, Gstkid, Canvas, _DB, AItem) ->
- case Option of
- arrow -> tcl2erl:ret_atom([Canvas, " itemcg ",AItem, " -arrow"]);
- capstyle -> tcl2erl:ret_atom([Canvas, " itemcg ", AItem, " -ca"]);
- fg -> tcl2erl:ret_color([Canvas, " itemcg ", AItem, " -f"]);
- joinstyle -> tcl2erl:ret_atom([Canvas, " itemcg ", AItem, " -jo"]);
- smooth -> tcl2erl:ret_bool([Canvas, " itemcg ", AItem, " -sm"]);
- splinesteps -> tcl2erl:ret_int([Canvas, " itemcg ", AItem, " -sp"]);
- stipple ->
- tcl2erl:ret_stipple([Canvas," itemcg ",AItem," -stipple"]);
- width -> tcl2erl:ret_int([Canvas, " itemcg ", AItem, " -w"]);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-pickout_coords([{coords,Coords} | Rest], Opts) when length(Coords) >= 2 ->
- case gstk_canvas:coords(Coords) of
- invalid ->
- {error, "A line must have at least four coordinates"};
- RealCoords ->
- {RealCoords, lists:append(Rest, Opts)}
- end;
-pickout_coords([Opt | Rest], Opts) ->
- pickout_coords(Rest, [Opt|Opts]);
-pickout_coords([], _Opts) ->
- {error, "A line must have at least four coordinates"}.
-
-%% ----- Done -----
-
diff --git a/lib/gs/src/gstk_listbox.erl b/lib/gs/src/gstk_listbox.erl
deleted file mode 100644
index 50d0503629..0000000000
--- a/lib/gs/src/gstk_listbox.erl
+++ /dev/null
@@ -1,324 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% -----------------------------------------------------------
-%% Basic Listbox Type
-%% ------------------------------------------------------------
-
--module(gstk_listbox).
-
-%%-----------------------------------------------------------------------------
-%% LISTBOX OPTIONS
-%%
-%% Attributes:
-%% activebg Color
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% bc Color
-%% bg Color
-%% bw Wth
-%% data Data
-%% fg Color
-%% height Int
-%% highlightbg Color
-%% highlightbw Wth
-%% highlightfg Color
-%% hscroll Bool | top | bottom
-%% items [String, String, ... String]
-%% relief Relief
-%% scrollbg Color
-%% scrollfg Color
-%% selectbg Color
-%% selectbw Width
-%% selectfg Color
-%% selection Index | clear
-%% selectmode single|browse|multiple|extended
-%% vscroll Bool | left | right
-%% width Int
-%% x Int
-%% xselection Bool (Good name?????)
-%% y Int
-%%
-%% Commands:
-%% add {Index, String} | String
-%% change {Index, String}
-%% clear
-%% del Index | {FromIdx, ToIdx}
-%% get Index
-%% see Index
-%% selection => [Idx1,Idx2,Idx3...]
-%% setfocus Bool
-%% size Int
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% click [Bool | {Bool, Data}]
-%% configure [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% doubleclick [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-
--export([create/3,config/3,read/3,delete/2,event/5,wid_event/5,option/5,
- read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/7
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- MainW = gstk_generic:mk_tkw_child(DB,GstkId),
- Listbox = lists:append(MainW,".z"),
- {Vscroll, Hscroll, NewOpts} = gstk_generic:parse_scrolls(Opts),
- WidgetD = #so{main=MainW, object=Listbox,
- hscroll=Hscroll, vscroll=Vscroll},
- Gstkid=GstkId#gstkid{widget=MainW, widget_data=WidgetD},
- MandatoryCmd = ["so_create listbox ", MainW],
- case gstk:call(MandatoryCmd) of
- {result, _} ->
- SimplePreCmd = [MainW, " conf"],
- PlacePreCmd = [";place ", MainW],
- case gstk_generic:make_command(NewOpts, Gstkid, MainW,SimplePreCmd,
- PlacePreCmd, DB,Listbox) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(Cmd),
- gstk:exec([MainW,".sy conf -rel sunken -bo 2;",
- MainW,".pad.sx conf -rel sunken -bo 2;",Listbox,
- " conf -bo 2 -relief sunken -highlightth 2 -expo 0;"]),
- Gstkid
- end;
- Bad_Result ->
- {error, Bad_Result}
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Options) ->
- SO = Gstkid#gstkid.widget_data,
- MainW = Gstkid#gstkid.widget,
- Listbox = SO#so.object,
- NewOpts = gstk_generic:parse_scrolls(Gstkid, Options),
- SimplePreCmd = [MainW, " conf"],
- PlacePreCmd = [";place ", MainW],
- gstk_generic:mk_cmd_and_exec(NewOpts, Gstkid, MainW,
- SimplePreCmd, PlacePreCmd, DB,Listbox).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- SO = Gstkid#gstkid.widget_data,
- gstk_generic:read_option(DB, Gstkid, Opt,SO#so.object).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : event/5
-%% Purpose : Construct the event and send it to the owner of the widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Etype - The event type
-%% Edata - The event data
-%% Args - The data from tcl/tk
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-event(DB, Gstkid, click, Edata, Args) ->
- wid_event(DB, Gstkid, click, Edata, Args);
-event(DB, Gstkid, doubleclick, Edata, Args) ->
- wid_event(DB, Gstkid, doubleclick, Edata, Args);
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-
-%% widget specific events
-wid_event(DB, Gstkid, Etype, Edata, _Args) ->
- SO = Gstkid#gstkid.widget_data,
- TkW = SO#so.object,
- CurIdx = tcl2erl:ret_int([TkW," index active;"]),
- CurTxt = tcl2erl:ret_str([TkW," get active;"]),
- CurSel = tcl2erl:ret_list([TkW," curselection;"]),
- Arg2 = [CurIdx,CurTxt,lists:member(CurIdx,CurSel)],
- gstk_generic:event(DB, Gstkid, Etype, Edata, Arg2).
-
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/5
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% MainW - The main tk-widget
-%% Listbox - The listbox tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, MainW,DB, Listbox) ->
- case Option of
- {items, Items} when is_list(Items) ->
- {c, [Listbox," del 0 end ;", Listbox," ins 0 ",item_list(Items)]};
- {selection, {From, To}} when is_integer(From),is_integer(To) ->
- {c,[Listbox," sel set ",gstk:to_ascii(From)," " ,gstk:to_ascii(To)]};
- {font, Font} when is_tuple(Font) ->
- gstk_db:insert_opt(DB,Gstkid,Option),
- {c, [Listbox," conf -font ",gstk_font:choose_ascii(DB,Font)]};
- {selection, clear} ->
- {c, [Listbox," sel clear 0 end"]};
- {selection, Idx} when is_integer(Idx) ->
- {c, [Listbox, " select set ", gstk:to_ascii(Idx)]};
- {selectmode, Mode} ->
- {c, [Listbox, " conf -selectm ", gstk:to_ascii(Mode)]};
- {xselection, Bool} ->
- {c, [Listbox, " conf -exportse ", gstk:to_ascii(Bool)]};
- {fg, Color} ->
- {c, [Listbox, " conf -fg ", gstk:to_color(Color)]};
-
- {del, {From, To}} ->
- {c, [Listbox, " del ", integer_to_list(From), " ",
- integer_to_list(To)]};
- {del, Idx} ->
- {c, [Listbox, " del ", integer_to_list(Idx)]};
- clear -> {c, [Listbox," del 0 end"]};
- {add, {Idx, Str}} ->
- {c, [Listbox, " ins ", integer_to_list(Idx), " ",
- gstk:to_ascii(Str)]};
- {add, Str} ->
- {c, [Listbox," ins end ",gstk:to_ascii(Str)]};
- {change, {Idx, Str}} ->
- {c, [Listbox, " del ", integer_to_list(Idx), $;,
- Listbox, " ins ", integer_to_list(Idx), " " ,
- gstk:to_ascii(Str)]};
- {see, Idx} ->
- {c, [Listbox," see ",gstk:to_ascii(Idx)]};
-
- {setfocus, true} -> {c, ["focus ", MainW]};
- {setfocus, false} -> {c, ["focus ."]};
-
- {click, On} -> cbind(DB, Gstkid, Listbox, click, On);
- {doubleclick, On} -> cbind(DB, Gstkid, Listbox, doubleclick, On);
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/3
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,GstkId,_MainW,DB,Listbox) ->
- case Option of
- fg -> tcl2erl:ret_color([Listbox," cg -fg"]);
- font -> gstk_db:opt(DB,GstkId,font,undefined);
- selection -> tcl2erl:ret_list([Listbox, " curselection"]);
- setfocus -> tcl2erl:ret_focus(Listbox, "focus");
-
- items -> tcl2erl:ret_str_list([Listbox, " get 0 end"]);
- selectmode -> tcl2erl:ret_atom([Listbox, " cg -selectmode"]);
- size -> tcl2erl:ret_int([Listbox, " size"]);
- xselection -> tcl2erl:ret_bool([Listbox, " cg -exportsel"]);
- {get, Idx} -> tcl2erl:ret_str([Listbox, " get ",gstk:to_ascii(Idx)]);
- click -> gstk_db:is_inserted(DB, GstkId, click);
- doubleclick -> gstk_db:is_inserted(DB, GstkId, doubleclick);
-
- _ -> {bad_result, {GstkId#gstkid.objtype, invalid_option, Option}}
- end.
-
-
-%%-----------------------------------------------------------------------------
-%% PRIMITIVES
-%%-----------------------------------------------------------------------------
-
-item_list([H|T]) ->
- [gstk:to_ascii(H),$ |item_list(T)];
-item_list([]) ->
- [].
-
-cbind(DB, Gstkid, Listbox, Etype, {true, Edata}) ->
- Button = case Etype of
- click -> " <ButtonRelease-1> ";
- doubleclick -> " <Double-ButtonRelease-1> "
- end,
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, Edata),
- {c, ["bind " ,Listbox, Button, "{erlsend ", Eref," }"]};
-
-cbind(DB, Gstkid, Listbox, Etype, true) ->
- cbind(DB, Gstkid, Listbox, Etype, {true, []});
-
-cbind(DB, Gstkid, Listbox, Etype, _On) ->
- Button = case Etype of
- click -> " <Button-1> {}";
- doubleclick -> " <Double-Button-1> {}"
- end,
- gstk_db:delete_event(DB, Gstkid, Etype),
- {c, ["bind ",Listbox, Button]}.
-
-
-%%% ----- Done -----
diff --git a/lib/gs/src/gstk_menu.erl b/lib/gs/src/gstk_menu.erl
deleted file mode 100644
index 2f12a20a7d..0000000000
--- a/lib/gs/src/gstk_menu.erl
+++ /dev/null
@@ -1,268 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%%-----------------------------------------------------------------------------
-%% BASIC MENU TYPE
-%%------------------------------------------------------------------------------
-
--module(gstk_menu).
--compile([{nowarn_deprecated_function,{gs,error,2}}]).
-
-%%------------------------------------------------------------------------------
-%% MENU OPTIONS
-%%
-%% Attribute:
-%% activebg Color
-%% activebw Int
-%% activefg Color
-%% bg Color
-%% bw Int
-%% data Data
-%% disabledfg Color
-%% fg Color
-%% relief Relief [flat|raised|sunken|ridge|groove]
-%% selectcolor Color
-%%
-%% Commands:
-%% setfocus [Bool | {Bool, Data}]
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% configure [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%% post {X,Y}
-%% unpost
-%% align n,w,s,e,nw,se,ne,sw,center
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% cursor ??????
-%% focus ?????? (-takefocus)
-%% height Int
-%% justify left|right|center (multiline text only)
-%% width Int
-%% x Int (valid only for popup menus)
-%% y Int (valid only for popup menus)
-%%
-
--export([create/3, config/3, read/3, delete/2, event/5,option/5,read_option/5]).
--export([delete_menuitem/3, insert_menuitem/4, lookup_menuitem_pos/3,
- mk_create_opts_for_child/4]).
-
--include("gstk.hrl").
-
-%%------------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/3
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- #gstkid{parent=Parent,owner=Owner,objtype=Objtype}=GstkId,
- Pgstkid = gstk_db:lookup_gstkid(DB, Parent, Owner),
- Oref = gstk_db:counter(DB, Objtype),
- PF = gstk_widgets:suffix(Objtype),
- case Pgstkid#gstkid.objtype of
- menuitem ->
- PMenu = Pgstkid#gstkid.parent,
- PMgstkid = gstk_db:lookup_gstkid(DB, PMenu, Owner),
- PMW = PMgstkid#gstkid.widget,
- Index = gstk_menu:lookup_menuitem_pos(DB, PMgstkid, Pgstkid#gstkid.id),
- TkW = lists:concat([PMW, PF, Oref]),
- Gstkid=GstkId#gstkid{widget=TkW, widget_data=[]},
- MPreCmd = ["menu ", TkW, " -tearoff 0 -relief raised -bo 2"],
- MPostCmd = [$;,PMW," entryco ",gstk:to_ascii(Index)," -menu ",TkW],
- case gstk_generic:make_command(Opts, Gstkid, TkW, "", "", DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec([MPreCmd,Cmd,MPostCmd]),
- Gstkid
- end;
- OtherParent ->
- true = lists:member(OtherParent,
- %% grid+canvas har skumma coord system
- [menubutton,window,frame]),
- PW = Pgstkid#gstkid.widget,
- TkW = lists:concat([PW, PF, Oref]),
- Gstkid=GstkId#gstkid{widget=TkW, widget_data=[]},
- MPreCmd = ["menu ", TkW, " -tearoff 0 -relief raised -bo 2 "],
- MPostCmd = if OtherParent == menubutton ->
- [$;, PW, " conf -menu ", TkW];
- true -> []
- end,
- case gstk_generic:make_command(Opts, Gstkid, TkW, "","", DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec([MPreCmd,Cmd,MPostCmd]),
- Gstkid
- end
- end.
-
-mk_create_opts_for_child(DB,Cgstkid, Pgstkid, Opts) ->
- gstk_generic:mk_create_opts_for_child(DB,Cgstkid,Pgstkid,Opts).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- TkW = Gstkid#gstkid.widget,
- PreCmd = [TkW, " conf"],
- gstk_generic:mk_cmd_and_exec(Opts, Gstkid, TkW, PreCmd, "", DB).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-%%------------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% TkW - The tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, TkW, DB,_) ->
- case Option of
- {activebw, Int} -> {s, [" -activebo ", gstk:to_ascii(Int)]};
- {disabledfg, Color} -> {s, [" -disabledf ", gstk:to_color(Color)]};
- {selectcolor, Color} -> {s, [" -selectc ", gstk:to_color(Color)]};
- {post_at, {X,Y}} -> post_at(X,Y,Gstkid,TkW,DB);
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option, Gstkid, TkW, _DB, _AItem) ->
- case Option of
- activebw -> tcl2erl:ret_int([TkW," cg -activebo"]);
- disabledfg -> tcl2erl:ret_color([TkW," cg -disabledfo"]);
- selectcolor -> tcl2erl:ret_color([TkW," cg -selectc"]);
- _ -> {error,{invalid_option,Option, Gstkid#gstkid.objtype}}
- end.
-
-post_at(X,Y,Gstkid,TkW,DB) ->
- Pgstkid = gstk_db:lookup_gstkid(DB, Gstkid#gstkid.parent),
- PtkW = Pgstkid#gstkid.widget,
- RootX = tcl2erl:ret_int(["winfo rootx ",PtkW]),
- RootY = tcl2erl:ret_int(["winfo rooty ",PtkW]),
- {c,[" tk_popup ",TkW," ",gstk:to_ascii(RootX+X)," ",gstk:to_ascii(RootY+Y)]}.
-
-
-%%-----------------------------------------------------------------------------
-%% PRIMITIVES
-%%-----------------------------------------------------------------------------
-%%----------------------------------------------------------------------
-%% gstk_db functions for menuitem handling
-%% Tk menuitems are numbered from 0, thus we have to recalc the position.
-%%----------------------------------------------------------------------
-insert_menuitem(DB, MenuId, ItemId, Pos) ->
- Mgstkid = gstk_db:lookup_gstkid(DB, MenuId),
- Items = Mgstkid#gstkid.widget_data,
- NewItems = insert_at(ItemId, Pos+1, Items),
- gstk_db:update_widget(DB, Mgstkid#gstkid{widget_data=NewItems}).
-
-
-delete_menuitem(DB, MenuId, ItemId) ->
- Mgstkid = gstk_db:lookup_gstkid(DB, MenuId),
- Items = Mgstkid#gstkid.widget_data,
- NewItems = lists:delete(ItemId, Items),
- gstk_db:insert_widget(DB, Mgstkid#gstkid{widget_data=NewItems}).
-
-
-lookup_menuitem_pos(_DB, Mgstkid, ItemId) ->
- Items = Mgstkid#gstkid.widget_data,
- find_pos(ItemId, Items) - 1.
-
-%%----------------------------------------------------------------------
-%% Generic list processing
-%%----------------------------------------------------------------------
-find_pos(ItemId, Items) ->
- find_pos(ItemId, Items, 1).
-
-find_pos(_ItemId, [], _N) -> gs:error("Couldn't find item in menu~n", []);
-find_pos(ItemId, [ItemId|_Items], N) -> N;
-find_pos(ItemId, [_|Items], N) ->
- find_pos(ItemId, Items, N + 1).
-
-insert_at(Elem, 1, L) -> [Elem | L];
-insert_at(Elem, N, [H|T]) ->
- [H|insert_at(Elem, N-1, T)].
-
-%% ----- Done -----
diff --git a/lib/gs/src/gstk_menubar.erl b/lib/gs/src/gstk_menubar.erl
deleted file mode 100644
index 9916f64e00..0000000000
--- a/lib/gs/src/gstk_menubar.erl
+++ /dev/null
@@ -1,176 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Menubar Type
-%% ------------------------------------------------------------
-
--module(gstk_menubar).
-
-%%------------------------------------------------------------------------------
-%% MENUBAR OPTIONS
-%%
-%% Attributes:
-%% bg Color
-%% bw Int
-%% data Data
-%% height Int
-%% highlightbg Color
-%% highlightbw Int
-%% highlightfg Color
-%% relief Relief [flat|raised|sunken|ridge|groove]
-%%
-%% Commands:
-%% setfocus [Bool | {Bool, Data}]
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% configure [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%% align How
-%%
-
--export([create/3,config/3,read/3,delete/2,event/5,option/5,read_option/5,
- mk_create_opts_for_child/4]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/7
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- TkW = gstk_generic:mk_tkw_child(DB,GstkId),
- MPreCmd = ["frame ", TkW],
- PlaceCmd = [";place ", TkW],
- Ngstkid = GstkId#gstkid{widget=TkW},
- case gstk_generic:make_command(Opts, Ngstkid,TkW, MPreCmd, PlaceCmd, DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec([Cmd,";pack ", TkW, " -side top -fill x;"]),
- Ngstkid
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- TkW = Gstkid#gstkid.widget,
- SimplePreCmd = [TkW, " conf"],
- PlacePreCmd = ["place ", TkW],
- gstk_generic:mk_cmd_and_exec(Opts,Gstkid,TkW,SimplePreCmd,PlacePreCmd,DB).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : Opt - An option to read
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-mk_create_opts_for_child(DB,Cgstkid, Pgstkid, Opts)
-when Cgstkid#gstkid.objtype==menubutton ->
- case gstk_db:lookup_def(Pgstkid,menubutton,bg) of
- false ->
- MbarTkW=Pgstkid#gstkid.widget,
- Color=tcl2erl:ret_color([MbarTkW," cg -bg"]),
- gstk_db:insert_def(Pgstkid,menubutton,{bg,Color});
- _ -> done
- end,
- gstk_generic:mk_create_opts_for_child(DB,Cgstkid,Pgstkid,Opts).
-
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% TkW - The tk-widget
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option,_Gstkid,_TkW,_DB,_) ->
- case Option of
- {bg, Color} -> {s, [" -bg ", gstk:to_color(Color)]};
- {height, Height} -> {s, [" -height ", gstk:to_ascii(Height)]};
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,GstkId,TkW,_DB,_) ->
- case Option of
- bg -> tcl2erl:ret_color([TkW," cg -bg"]);
- height -> tcl2erl:ret_int(["update idletasks;winfo he ",TkW]);
- _ -> {bad_result, {GstkId#gstkid.objtype, invalid_option, Option}}
- end.
-
-
-%% ----- Done -----
-
-
diff --git a/lib/gs/src/gstk_menubutton.erl b/lib/gs/src/gstk_menubutton.erl
deleted file mode 100644
index 3f51a9df99..0000000000
--- a/lib/gs/src/gstk_menubutton.erl
+++ /dev/null
@@ -1,238 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Menubutton Type
-%% ------------------------------------------------------------
-
--module(gstk_menubutton).
-
-%%------------------------------------------------------------------------------
-%% MENUBUTTON OPTIONS
-%%
-%% Attributes:
-%% activebg Color
-%% activefg Color
-%% align n,w,s,e,nw,se,ne,sw,center
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% bg Color
-%% bw Int
-%% data Data
-%% disabledfg Color
-%% fg Color
-%% font Font
-%% height Int
-%% highlightbg Color
-%% highlightbw Int
-%% highlightfg Color
-%% justify left|right|center (multiline text only)
-%% label {text, String} | {image, BitmapFile}
-%% padx Int (Pixels)
-%% pady Int (Pixels)
-%% relief Relief [flat|raised| sunken | ridge | groove]
-%% side left | right (valid only in menubars)
-%% underline Int
-%% width Int
-%% wraplength Int
-%% x Int (not valid in menubars)
-%% y Int (not valid in menubars)
-%%
-%% Commands:
-%% enable Bool
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% configure [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%% activate ?????? (kontra enable, true)
-%% state ??????
-%% cursor ??????
-%% image ??????
-%% focus ?????? (-takefocus)
-%%
-
--export([create/3,config/3,read/3,delete/2,event/5,option/5,read_option/5,
- mk_create_opts_for_child/4]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/7
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- TkW = gstk_generic:mk_tkw_child(DB,GstkId),
- NGstkId=GstkId#gstkid{widget=TkW},
- PlacePreCmd = [";place ", TkW],
- case gstk_generic:make_command(Opts, NGstkId, TkW, "", PlacePreCmd, DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(["menubutton ", TkW," -padx 4 -pady 3",Cmd]),
- NGstkId
- end.
-
-mk_create_opts_for_child(DB,Cgstkid, Pgstkid, Opts) ->
- gstk_generic:mk_create_opts_for_child(DB,Cgstkid,Pgstkid,Opts).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- TkW = Gstkid#gstkid.widget,
- SimplePreCmd = [TkW, " conf"],
- PlacePreCmd = [";place ", TkW],
- gstk_generic:mk_cmd_and_exec(Opts,Gstkid,TkW,SimplePreCmd,PlacePreCmd,DB).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% TkW - The tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, TkW, DB,_) ->
- case Option of
- {anchor, How} -> fix_anchor(How, Gstkid, TkW, DB);
- {disabledfg, Color} -> {s, [" -disabledf ", gstk:to_color(Color)]};
- {height, Height} -> {s, [" -he ", gstk:to_ascii(Height)]};
- {side, Side} -> fix_side(Side, Gstkid, TkW, DB);
- {underline, Int} -> {s, [" -und ", gstk:to_ascii(Int)]};
- {width, Width} -> {s, [" -wi ", gstk:to_ascii(Width)]};
- {wraplength, Int} -> {s, [" -wr ", gstk:to_ascii(Int)]};
- {x, X} -> fix_placement(x, X, Gstkid, TkW, DB);
- {y, Y} -> fix_placement(y, Y, Gstkid, TkW, DB);
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/3
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,GstkId,TkW,_DB,_) ->
- case Option of
- anchor -> tcl2erl:ret_place(anchor, TkW);
- disabledfg -> tcl2erl:ret_color([TkW," cg -disabledfo"]);
- height -> tcl2erl:ret_int([TkW," cg -he"]);
- side -> tcl2erl:ret_pack(side, TkW);
- underline -> tcl2erl:ret_int([TkW," cg -underl"]);
- width -> tcl2erl:ret_int([TkW," cg -wi"]);
- wraplength -> tcl2erl:ret_int([TkW," cg -wr"]);
- x -> tcl2erl:ret_place(x, TkW);
- y -> tcl2erl:ret_place(y, TkW);
- _ -> {error,{invalid_option,Option, GstkId#gstkid.objtype}}
- end.
-
-%%-----------------------------------------------------------------------------
-%% PRIMITIVES
-%%-----------------------------------------------------------------------------
-
-fix_placement(Attr, Value, Gstkid, _TkW, DB) ->
- Pgstkid = gstk_db:lookup_gstkid(DB, Gstkid#gstkid.parent),
- case Pgstkid#gstkid.objtype of
- menubar -> invalid_option;
- _ -> {p, [" -", atom_to_list(Attr), " ", gstk:to_ascii(Value)]}
- end.
-
-
-fix_anchor(How, Gstkid, TkW, DB) ->
- Pgstkid = gstk_db:lookup_gstkid(DB, Gstkid#gstkid.parent),
- case Pgstkid#gstkid.objtype of
- menubar -> {c, ["pack ", TkW, " -an ", gstk:to_ascii(How)]};
- _ -> {p, [" -anch ", gstk:to_ascii(How)]}
- end.
-
-
-fix_side(Side, Gstkid, TkW, DB) ->
- Pgstkid = gstk_db:lookup_gstkid(DB, Gstkid#gstkid.parent),
- case Pgstkid#gstkid.objtype of
- menubar -> {c, ["pack ", TkW, " -fill y -si ", gstk:to_ascii(Side)]};
- _ -> none
- end.
-
-
-%% ----- Done -----
-
diff --git a/lib/gs/src/gstk_menuitem.erl b/lib/gs/src/gstk_menuitem.erl
deleted file mode 100644
index 968568a9a7..0000000000
--- a/lib/gs/src/gstk_menuitem.erl
+++ /dev/null
@@ -1,584 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Menuitem Type
-%% ------------------------------------------------------------
-
--module(gstk_menuitem).
--compile([{nowarn_deprecated_function,{gs,error,2}}]).
-
-%%-----------------------------------------------------------------------------
-%% MENUITEM OPTIONS
-%%
-%% Attribute:
-%% accelerator String
-%% activebg Color
-%% activefg Color
-%% bg Color
-%% color Color (same as fg)
-%% data Data
-%% fg Color
-%% font Font
-%% group Atom (valid only for radio type)
-%% index Int
-%% itemtype normal|check|radio|separator|cascade (|tearoff)
-%% label {text, String} | {image, BitmapFile}
-%% menu Menu (valid only for cascade type)
-%% selectbg Color
-%% underline Int
-%% value Atom
-%%
-%% Commands:
-%% activate
-%% enable Bool
-%% invoke
-%%
-%% Events:
-%% click [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%% font Font
-%% read menu on cascades
-%%
-
--export([create/3, config/3, read/3, delete/2, destroy/3, event/5,
- option/5,read_option/5,mk_create_opts_for_child/4]).
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/3
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- #gstkid{parent=Parent,owner=Owner,id=Id}=GstkId,
- Pgstkid = gstk_db:lookup_gstkid(DB, Parent),
- TkMenu = Pgstkid#gstkid.widget,
- Widget = "",
- {Index, Type, Options} = parse_opts(Opts, TkMenu),
- PreCmd = [TkMenu, " insert ", gstk:to_ascii(Index)],
- InsertArgs = [DB, Parent,Id, Index],
- case Type of
- check ->
- {G, GID, NOpts} = fix_group(Options, DB, Owner),
- TypeCmd = " ch",
- Ngstkid=GstkId#gstkid{widget=Widget,widget_data={Type, G, GID}},
- GenArgs = [NOpts,Ngstkid,TkMenu,"","",DB,{Type,Index}],
- CallArgs = [PreCmd,TypeCmd],
- mk_it(GenArgs,CallArgs,InsertArgs,Ngstkid);
- radio ->
- {G, GID, V, NOpts} = fix_group_and_value(Options, DB, Owner),
- Ngstkid=GstkId#gstkid{widget=Widget, widget_data={Type,G,GID,V}},
- TypeCmd = " ra",
- GenArgs = [NOpts,Ngstkid,TkMenu,"", "",DB,{Type,Index}],
- CallArgs = [PreCmd,TypeCmd],
- mk_it(GenArgs,CallArgs,InsertArgs,Ngstkid);
- _ ->
- Ngstkid=GstkId#gstkid{widget=Widget, widget_data=Type},
- TypeCmd = case Type of
- normal -> " co";
- separator -> " se";
- cascade -> " ca"
- end,
- GenArgs = [Options,Ngstkid,TkMenu,"","",DB,{Type,Index}],
- CallArgs = [PreCmd,TypeCmd],
- mk_it(GenArgs,CallArgs,InsertArgs,Ngstkid)
- end.
-
-mk_it(GenArgs,CallArgs,InsertArgs,Ngstkid) ->
- case apply(gstk_generic,make_command,GenArgs) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- case apply(gstk,call,[[CallArgs|Cmd]]) of
- {result,_} ->
- apply(gstk_menu,insert_menuitem,InsertArgs),
- Ngstkid;
- Bad_Result -> {error,Bad_Result}
- end
- end.
-
-mk_create_opts_for_child(DB,Cgstkid, Pgstkid, Opts) ->
- gstk_generic:mk_create_opts_for_child(DB,Cgstkid,Pgstkid,Opts).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Options - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-% FIXME: Could we really trust Index? If we create a menu and put one
-% entry in the middle of the meny, don't the entrys after that one
-% renumber?
-
-config(DB, Gstkid, Options) ->
- Parent = Gstkid#gstkid.parent,
- Pgstkid = gstk_db:lookup_gstkid(DB, Parent),
- TkMenu = Pgstkid#gstkid.widget,
- case Gstkid#gstkid.widget_data of
- {Type, _, _, _} ->
- Owner = Gstkid#gstkid.owner,
- {NOpts, NGstkid} = fix_group_and_value(Options, DB, Owner, Gstkid),
- Index = gstk_menu:lookup_menuitem_pos(DB, Pgstkid, NGstkid#gstkid.id),
- PreCmd = [TkMenu, " entryco ", gstk:to_ascii(Index)],
- gstk_generic:mk_cmd_and_exec(NOpts,NGstkid,TkMenu,PreCmd,"",DB,
- {Type,Index});
- {Type, _, _} ->
- Owner = Gstkid#gstkid.owner,
- {NOpts, NGstkid} = fix_group(Options, DB, Owner, Gstkid),
- Index = gstk_menu:lookup_menuitem_pos(DB, Pgstkid, NGstkid#gstkid.id),
- PreCmd = [TkMenu, " entryco ", gstk:to_ascii(Index)],
- gstk_generic:mk_cmd_and_exec(NOpts,NGstkid,TkMenu,PreCmd,"",DB,
- {Type,Index});
- Type ->
- Index = gstk_menu:lookup_menuitem_pos(DB, Pgstkid, Gstkid#gstkid.id),
- PreCmd = [TkMenu, " entryco ", gstk:to_ascii(Index)],
- gstk_generic:mk_cmd_and_exec(Options,Gstkid,TkMenu,PreCmd,"",
- DB, {Type,Index})
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- Parent = Gstkid#gstkid.parent,
- Id = Gstkid#gstkid.id,
- gstk_db:delete_widget(DB, Gstkid),
- case Gstkid#gstkid.widget_data of
- {radio, _, Gid, _} -> gstk_db:delete_bgrp(DB, Gid);
- {check, _, Gid} -> gstk_db:delete_bgrp(DB, Gid);
- _Other -> true
- end,
- {Parent, Id, gstk_menuitem, [Id, Parent]}.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : destroy/3
-%% Purpose : Destroy a widget
-%% Args : Menu - The menu tk widget
-%% Item - The index of the menuitem to destroy
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-destroy(DB, Id, Parent) ->
- Pgstkid = gstk_db:lookup_gstkid(DB, Parent),
- PW = Pgstkid#gstkid.widget,
- Idx = gstk_menu:lookup_menuitem_pos(DB, Pgstkid, Id),
- gstk_menu:delete_menuitem(DB, Parent, Id),
- gstk:exec([PW, " delete ", gstk:to_ascii(Idx)]).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : event/5
-%% Purpose : Construct the event and send it to the owner of the widget
-%% Args : Etype - The event type
-%% Edata - The event data
-%% Args - The data from tcl/tk
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-event(DB, Gstkid, Etype, Edata, Args) ->
- Arg2 =
- case Gstkid#gstkid.widget_data of
- {radio, G, _GID, V} ->
- [_Grp, Text, Idx | Args1] = Args,
- [Text, Idx, G, V | Args1];
- {check, G, _Gid} ->
- [Bool, Text, Idx | Args1] = Args,
- RBool = case Bool of
- 0 -> false;
- 1 -> true
- end,
- [Text, Idx, G, RBool | Args1];
- _Other2 ->
- Args
- end,
- gstk_generic:event(DB, Gstkid, Etype, Edata, Arg2).
-
-
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% TkW - The tk-widget
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option({click,true}, _Gstkid, _TkW, _DB, {separator,_Index}) ->
- none; % workaround to be able to have {click,true} as default.
-option(_Option, _Gstkid, _TkW, _DB, {separator,_Index}) ->
- invalid_option;
-
-option({menu,{Menu,_RestOfExternalId}}, _Gstkid, _TkW, DB, {cascade,_Index}) ->
- Mgstkid = gstk_db:lookup_gstkid(DB, Menu),
- MenuW = Mgstkid#gstkid.widget,
- {s, [" -menu ", MenuW]};
-
-option({select,false}, _Gstkid, TkW, _DB, {check,Index}) ->
- {c, ["set x [", TkW, " entrycg ", gstk:to_ascii(Index),
- " -var];global $x;set $x 0"]};
-option({select,true}, _Gstkid, TkW, _DB, {check,Index}) ->
- {c, ["set x [", TkW, " entrycg ", gstk:to_ascii(Index),
- " -var];global $x;set $x 1"]};
-
-option({value,Val}, _Gstkid, _TkW, _DB, {radio,_Index}) ->
- {s, [" -val ", gstk:to_ascii(Val)]};
-option({select,false}, _Gstkid, TkW, _DB, {radio,Index}) ->
- {c, ["set x [", TkW, " entrycg ", gstk:to_ascii(Index),
- " -var];global $x;set $x {}"]};
-option({select,true}, _Gstkid, TkW, _DB, {radio,Index}) ->
- {c, ["set x [", TkW, " entrycg ", gstk:to_ascii(Index),
- " -var]; set y [", TkW, " entrycg ", gstk:to_ascii(Index),
- " -val]; global $x; set $x $y"]};
-
-option(Option, Gstkid, TkW, DB, {Kind,Index}) ->
- case Option of
- activate -> {c, [TkW, " act ", gstk:to_ascii(Index)]};
- invoke -> {c, [TkW, " inv ", gstk:to_ascii(Index)]};
- {accelerator, Acc} -> {s, [" -acc ", gstk:to_ascii(Acc)]};
- {click, On} -> cbind(On, Gstkid, TkW, Index, Kind, DB);
- {font, Font} when is_tuple(Font) ->
- gstk_db:insert_opt(DB,Gstkid,Option),
- {s, [" -font ", gstk_font:choose_ascii(DB,Font)]};
- {label, {image,Img}} -> {s, [" -bitm @", Img, " -lab {}"]};
- % FIXME: insert -command here.....
- % FIXME: how to get value from image entry???
- {label, {text,Text}} -> {s, [" -lab ",gstk:to_ascii(Text)," -bitm {}"]};
- {underline, Int} -> {s, [" -underl ", gstk:to_ascii(Int)]};
- {activebg, Color} -> {s, [" -activeba ", gstk:to_color(Color)]};
- {activefg, Color} -> {s, [" -activefo ", gstk:to_color(Color)]};
- {bg, Color} -> {s, [" -backg ", gstk:to_color(Color)]};
- {enable, true} -> {s, " -st normal"};
- {enable, false} -> {s, " -st disabled"};
- {fg, Color} -> {s, [" -foreg ", gstk:to_color(Color)]};
- _Other ->
- case lists:member(Kind,[radio,check]) of
- true ->
- case Option of
- {group,Group} -> {s, [" -var ", gstk:to_ascii(Group)]};
- {selectbg,Col} -> {s,[" -selectc ",gstk:to_color(Col)]};
- _ -> invalid_option
- end;
- _ -> invalid_option
- end
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,GstkId,_TkW,DB,_) ->
- ItemId = GstkId#gstkid.id,
- MenuId = GstkId#gstkid.parent,
- MenuGstkid = gstk_db:lookup_gstkid(DB, MenuId),
- MenuW = MenuGstkid#gstkid.widget,
- Idx = gstk_menu:lookup_menuitem_pos(DB, MenuGstkid, ItemId),
- PreCmd = [MenuW, " entrycg ", gstk:to_ascii(Idx)],
- case Option of
- accelerator -> tcl2erl:ret_str([PreCmd, " -acc"]);
- activebg -> tcl2erl:ret_color([PreCmd, " -activeba"]);
- activefg -> tcl2erl:ret_color([PreCmd, " -activefo"]);
- bg -> tcl2erl:ret_color([PreCmd, " -backg"]);
- fg -> tcl2erl:ret_color([PreCmd, " -foreg"]);
- group -> read_group(GstkId, Option);
- groupid -> read_groupid(GstkId, Option);
- index -> Idx;
- itemtype -> case GstkId#gstkid.widget_data of
- {Type, _, _, _} -> Type;
- {Type, _, _} -> Type;
- Type -> Type
- end;
- enable -> tcl2erl:ret_enable([PreCmd, " -st"]);
- font -> gstk_db:opt(DB,GstkId,font,undefined);
- label -> tcl2erl:ret_label(["list [", PreCmd, " -lab] [",
- PreCmd, " -bit]"]);
- selectbg -> tcl2erl:ret_color([PreCmd, " -selectco"]);
- underline -> tcl2erl:ret_int([PreCmd, " -underl"]);
- value -> tcl2erl:ret_atom([PreCmd, " -val"]);
- select -> read_select(MenuW, Idx, GstkId);
- click -> gstk_db:is_inserted(DB, GstkId, click);
- _ -> {bad_result, {GstkId#gstkid.objtype, invalid_option, Option}}
- end.
-
-read_group(Gstkid, Option) ->
- case Gstkid#gstkid.widget_data of
- {_, G, _, _} -> G;
- {_, G, _} -> G;
- _Other -> {bad_result,{Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-read_groupid(Gstkid, Option) ->
- case Gstkid#gstkid.widget_data of
- {_, _, Gid, _} -> Gid;
- {_, _, Gid} -> Gid;
- _Other -> {bad_result,{Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-
-
-
-read_select(TkMenu, Idx, Gstkid) ->
- case Gstkid#gstkid.widget_data of
- {radio, _, _, _} ->
- Cmd = ["list [set x [", TkMenu, " entrycg ", gstk:to_ascii(Idx),
- " -var];global $x;set $x] [", TkMenu,
- " entrycg ", gstk:to_ascii(Idx)," -val]"],
- case tcl2erl:ret_tuple(Cmd) of
- {X, X} -> true;
- _Other -> false
- end;
- {check, _, _} ->
- Cmd = ["set x [", TkMenu, " entrycg ", gstk:to_ascii(Idx),
- " -var];global $x;set $x"],
- tcl2erl:ret_bool(Cmd);
- _Other ->
- {error,{invalid_option,menuitem,select}}
- end.
-
-
-
-%%-----------------------------------------------------------------------------
-%% PRIMITIVES
-%%-----------------------------------------------------------------------------
-
-%% create version
-fix_group_and_value(Opts, DB, Owner) ->
- {G, GID, V, NOpts} = fgav(Opts, erlNIL, erlNIL, erlNIL, []),
- RV = case V of
- erlNIL ->
- list_to_atom(lists:concat([v,gstk_db:counter(DB,value)]));
- Other0 -> Other0
- end,
- NG = case G of
- erlNIL -> mrb;
- Other1 -> Other1
- end,
- RGID = case GID of
- erlNIL -> {mrbgrp, NG, Owner};
- Other2 -> Other2
- end,
- RG = gstk_db:insert_bgrp(DB, RGID),
- {NG, RGID, RV, [{group, RG}, {value, RV} | NOpts]}.
-
-%% config version
-fix_group_and_value(Opts, DB, Owner, Gstkid) ->
- {Type, RG, RGID, RV} = Gstkid#gstkid.widget_data,
- {G, GID, V, NOpts} = fgav(Opts, RG, RGID, RV, []),
- case {G, GID, V} of
- {RG, RGID, RV} ->
- {NOpts, Gstkid};
- {NG, RGID, RV} ->
- NGID = {rbgrp, NG, Owner},
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={Type,NG,NGID,RV}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG} | NOpts], NGstkid};
- {RG, RGID, NRV} ->
- NGstkid = Gstkid#gstkid{widget_data={Type,RG,RGID,NRV}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{value,NRV} | NOpts], NGstkid};
- {_, NGID, RV} when NGID =/= RGID ->
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={Type,RG,NGID,RV}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG} | NOpts], NGstkid};
- {_, NGID, NRV} when NGID =/= RGID ->
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={Type,RG,NGID,NRV}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG}, {value,NRV} | NOpts], NGstkid};
- {NG, RGID, NRV} ->
- NGID = {rbgrp, NG, Owner},
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={Type,NG,NGID,NRV}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG}, {value,NRV} | NOpts], NGstkid}
- end.
-
-
-
-fgav([{group, G} | Opts], _, GID, V, Nopts) ->
- fgav(Opts, G, GID, V, Nopts);
-
-fgav([{groupid, GID} | Opts], G, _, V, Nopts) ->
- fgav(Opts, G, GID, V, Nopts);
-
-fgav([{value, V} | Opts], G, GID, _, Nopts) ->
- fgav(Opts, G, GID, V, Nopts);
-
-fgav([Opt | Opts], G, GID, V, Nopts) ->
- fgav(Opts, G, GID, V, [Opt | Nopts]);
-
-fgav([], Group, GID, Value, Opts) ->
- {Group, GID, Value, Opts}.
-
-
-%% check button version
-%% create version
-fix_group(Opts, DB, Owner) ->
- {G, GID, NOpts} = fg(Opts, erlNIL, erlNIL, []),
- NG = case G of
- erlNIL ->
- Vref = gstk_db:counter(DB, variable),
- list_to_atom(lists:flatten(["mcb", gstk:to_ascii(Vref)]));
- Other1 -> Other1
- end,
- RGID = case GID of
- erlNIL -> {mcbgrp, NG, Owner};
- Other2 -> Other2
- end,
- RG = gstk_db:insert_bgrp(DB, RGID),
- {NG, RGID, [{group, RG} | NOpts]}.
-
-%% config version
-fix_group(Opts, DB, Owner, Gstkid) ->
- {Type, RG, RGID} = Gstkid#gstkid.widget_data,
- {G, GID, NOpts} = fg(Opts, RG, RGID, []),
- case {G, GID} of
- {RG, RGID} ->
- {NOpts, Gstkid};
- {NG, RGID} ->
- NGID = {cbgrp, NG, Owner},
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={Type,NG,NGID}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG} | NOpts], NGstkid};
- {_, NGID} when NGID =/= RGID ->
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={Type,RG,NGID}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG} | NOpts], NGstkid}
- end.
-
-
-
-fg([{group, G} | Opts], _, GID, Nopts) ->
- fg(Opts, G, GID, Nopts);
-
-fg([{groupid, GID} | Opts], G, _, Nopts) ->
- fg(Opts, G, GID, Nopts);
-
-fg([Opt | Opts], G, GID, Nopts) ->
- fg(Opts, G, GID, [Opt | Nopts]);
-
-fg([], Group, GID, Opts) ->
- {Group, GID, Opts}.
-
-
-
-parse_opts(Opts, TkMenu) ->
- parse_opts(Opts, TkMenu, none, none, []).
-
-
-parse_opts([Option | Rest], TkMenu, Idx, Type, Options) ->
- case Option of
- {index, I} -> parse_opts(Rest, TkMenu, I, Type, Options);
- {itemtype, T} -> parse_opts(Rest, TkMenu, Idx, T, Options);
- _Other -> parse_opts(Rest, TkMenu, Idx, Type,[Option | Options])
- end;
-parse_opts([], TkMenu, Index, Type, Options) ->
- RealIdx =
- case Index of
- Idx when is_integer(Idx) -> Idx;
- last -> find_last_index(TkMenu);
- Other -> gs:error("Invalid index ~p~n",[Other])
- end,
- {RealIdx, Type, Options}.
-
-find_last_index(TkMenu) ->
- case tcl2erl:ret_int([TkMenu, " index last"]) of
- Last when is_integer(Last) -> Last+1;
- none -> 0;
- Other -> gs:error("Couldn't find index ~p~n",[Other])
- end.
-
-cbind({true, Edata}, Gstkid, TkMenu, Index, Type, DB) ->
- Eref = gstk_db:insert_event(DB, Gstkid, click, Edata),
- IdxStr = gstk:to_ascii(Index),
- case Type of
- normal ->
- Cmd = [" -command {erlsend ", Eref,
- " \\\"[",TkMenu," entrycg ",IdxStr," -label]\\\" ",
- IdxStr,"}"],
- {s, Cmd};
- check ->
- Cmd = [" -command {erlsend ", Eref,
- " \[expr \$[", TkMenu, " entrycg ",IdxStr," -var]\] \\\"[",
- TkMenu, " entrycg ",IdxStr," -label]\\\" ",IdxStr,"}"],
- {s, Cmd};
- radio ->
- Cmd = [" -command {erlsend ", Eref,
- " [", TkMenu, " entrycg ",IdxStr," -var] \\\"[",
- TkMenu, " entrycg ",IdxStr," -label]\\\" ",IdxStr,"}"],
- {s, Cmd};
- _Other ->
- none
- end;
-
-cbind({false, _}, Gstkid, _TkMenu, _Index, _Type, DB) ->
- gstk_db:delete_event(DB, Gstkid, click),
- none;
-
-cbind(On, Gstkid, TkMenu, Index, Type, DB) when is_atom(On) ->
- cbind({On, []}, Gstkid, TkMenu, Index, Type, DB).
-
-
-%%% ----- Done -----
-
diff --git a/lib/gs/src/gstk_oval.erl b/lib/gs/src/gstk_oval.erl
deleted file mode 100644
index 8e06378c0b..0000000000
--- a/lib/gs/src/gstk_oval.erl
+++ /dev/null
@@ -1,189 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Oval Type
-%% ------------------------------------------------------------
-
--module(gstk_oval).
-
-%%-----------------------------------------------------------------------------
-%% OVAL OPTIONS
-%%
-%% Options:
-%% bw Int
-%% coords [{X1,Y1}, {X2,Y2}]
-%% data Data
-%% fg Color
-%% fill Color
-%% stipple Bool
-%%
-%% Commands:
-%% lower
-%% move {Dx, Dy}
-%% raise
-%% scale {Xo, Yo, Sx, Sy}
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%%
-
--export([create/3, config/3, read/3, delete/2, destroy/3, event/5,
- option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/3
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, Gstkid, Opts) ->
- case gstk_canvas:pickout_coords(Opts, [],oval,2) of
- {error, Error} ->
- {bad_result, Error};
- {Coords, NewOpts} ->
- Ngstkid=gstk_canvas:upd_gstkid(DB, Gstkid, Opts),
- #gstkid{widget=CanvasTkW}=Ngstkid,
- MCmd = [CanvasTkW, " create ov ", Coords],
- gstk_canvas:mk_cmd_and_call(NewOpts,Ngstkid, CanvasTkW, MCmd, DB)
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- gstk_canvas:item_config(DB, Gstkid, Opts).
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- Item = Gstkid#gstkid.widget_data,
- gstk_generic:read_option(DB,Gstkid,Opt,[gstk:to_ascii(Item)]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy | {Parent, Objmod, Args}.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_canvas:item_delete_impl(DB,Gstkid).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : destroy/3
-%% Purpose : Destroy a widget
-%% Args : DB - The Database
-%% Canvas - The canvas tk widget
-%% Item - The item number to destroy
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-destroy(_DB, Canvas, Item) ->
- gstk:exec([Canvas, " delete ", gstk:to_ascii(Item)]).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : event/5
-%% Purpose : Construct the event and send it to the owner of the widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Etype - The event type
-%% Edata - The event data
-%% Args - The data from tcl/tk
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/5
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% MainW - The main tk-widget
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, _Gstkid, _Canvas, _DB, _AItem) ->
- case Option of
- {fg, Color} -> {s, [" -outline ", gstk:to_color(Color)]};
- {bw, Int} -> {s, [" -w ", gstk:to_ascii(Int)]};
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option, Gstkid, Canvas, _DB, AItem) ->
- case Option of
- bw -> tcl2erl:ret_int([Canvas, " itemcg ", AItem, " -w"]);
- fg -> tcl2erl:ret_color([Canvas, " itemcg ", AItem," -outline"]);
- stipple -> tcl2erl:ret_stipple([Canvas," itemcg ",AItem," -stipple"]);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-
-
-%% ----- Done -----
-
diff --git a/lib/gs/src/gstk_polygon.erl b/lib/gs/src/gstk_polygon.erl
deleted file mode 100644
index 013682d353..0000000000
--- a/lib/gs/src/gstk_polygon.erl
+++ /dev/null
@@ -1,196 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Polygon Type
-%% ------------------------------------------------------------
-
--module(gstk_polygon).
-
-
-%%-----------------------------------------------------------------------------
-%% POLYGON OPTIONS
-%%
-%% Attributes:
-%% bw Int
-%% coords [{X1,Y1}, {X2,Y2} | {Xn,Yn}]
-%% data Data
-%% fg Color
-%% fill Color
-%% smooth Bool
-%% splinesteps Int
-%% stipple Bool
-%%
-%% Commands:
-%% lower
-%% move {Dx, Dy}
-%% raise
-%% scale {Xo, Yo, Sx, Sy}
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-
--export([create/3, config/3, read/3, delete/2, destroy/3, event/5,
- option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/7
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, Gstkid, Opts) ->
- case pickout_coords(Opts, []) of
- {error, Error} ->
- {bad_result, Error};
- {Coords, NewOpts} ->
- Ngstkid=gstk_canvas:upd_gstkid(DB, Gstkid, Opts),
- #gstkid{widget=CanvasTkW}=Ngstkid,
- MCmd = [CanvasTkW, " create po ", Coords],
- gstk_canvas:mk_cmd_and_call(NewOpts, Ngstkid,CanvasTkW, MCmd, DB)
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- gstk_canvas:item_config(DB, Gstkid, Opts).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- Item = Gstkid#gstkid.widget_data,
- gstk_generic:read_option(DB,Gstkid,Opt,[gstk:to_ascii(Item)]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy | {Parent, Objmod, Args}.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_canvas:item_delete_impl(DB,Gstkid).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : destroy/3
-%% Purpose : Destroy a widget
-%% Args : DB - The Database
-%% Canvas - The canvas tk widget
-%% Item - The item number to destroy
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-destroy(_DB, Canvas, Item) ->
- gstk:exec([Canvas, " delete ", gstk:to_ascii(Item)]).
-
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/5
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% MainW - The main tk-widget
-%% Canvas - The canvas tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, _Gstkid, _Canvas, _DB, _AItem) ->
- case Option of
- {fg, Color} -> {s, [" -outline ", gstk:to_color(Color)]};
- {bw, Int} -> {s, [" -w ", gstk:to_ascii(Int)]};
- {smooth, Bool} -> {s, [" -sm ", gstk:to_ascii(Bool)]};
- {splinesteps, Int} -> {s, [" -sp ", gstk:to_ascii(Int)]};
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option, Gstkid, Canvas, _DB, AItem) ->
- case Option of
- bw -> tcl2erl:ret_int([Canvas, " itemcg ", AItem, " -w"]);
- fg ->
- tcl2erl:ret_color([Canvas, " itemcg ", AItem, " -outline"]);
- smooth -> tcl2erl:ret_bool([Canvas, " itemcg ", AItem, " -sm"]);
- splinesteps -> tcl2erl:ret_int([Canvas, " itemcg ", AItem, " -sp"]);
- stipple ->
- tcl2erl:ret_stipple([Canvas," itemcg ",AItem," -stipple"]);
-
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-%%-----------------------------------------------------------------------------
-%% PRIMITIVES
-%%-----------------------------------------------------------------------------
-
-pickout_coords([{coords,Coords} | Rest], Opts) when length(Coords) >= 2 ->
- case gstk_canvas:coords(Coords) of
- invalid ->
- {error, "A polygon must have at least four coordinates"};
- RealCoords ->
- {RealCoords, lists:append(Rest, Opts)}
- end;
-pickout_coords([Opt | Rest], Opts) ->
- pickout_coords(Rest, [Opt|Opts]);
-pickout_coords([], _Opts) ->
- {error, "A polygon must have at least four coordinates"}.
-%% ----- Done -----
-
diff --git a/lib/gs/src/gstk_port_handler.erl b/lib/gs/src/gstk_port_handler.erl
deleted file mode 100644
index fee3dc7dac..0000000000
--- a/lib/gs/src/gstk_port_handler.erl
+++ /dev/null
@@ -1,467 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%%
-%% This is a driver for the 'gstk' application modified to
-%% handle events for gs. 'gstk' is a modified standalone wish.
-%%
-%% FIXME
-%% mkdir tcl ; cd tcl
-%% ( cd /usr/local/pgm/tcl-8.3.3 ; tar -cf - * ) | tar -xf -
-%% ( cd /usr/local/pgm/tk-8.3.3 ; tar -cf - * ) | tar -xf -
-%% rm -fr include man bin/tclsh
-%% cd ..
-%% tar -cf tcl.tar *
-%%
-%% ------------------------------------------------------------
-
--module(gstk_port_handler).
--compile([{nowarn_deprecated_function,{gs,error,2}}]).
-
--include("gstk.hrl").
-
-% The executable can have many names. There is not always
-% a plain "wish" program.
-% FIXME There has to be a better solution....
-% FIXME Add option in app file or environmen variable.
-
--define(WISHNAMES, ["wish85","wish8.5",
- "wish84","wish8.4",
- "wish83","wish8.3",
- "wish82","wish8.2",
- "wish"]).
-
-%% ------------------------------------------------------------
-%% DEBUG FUNCTIONS
-%% ------------------------------------------------------------
--export([exec/1,call/2,
- start_link/1,init/2,ping/1,stop/1]).
--export([wait_for_connection/2]).
-
--define(START_TIMEOUT , 1000 * 30).
--define(ACCEPT_TIMEOUT, 1000 * 20).
-
--define(DEBUGLEVEL, 4).
-
--ifdef(DEBUG).
-
--define(DBG(DbgLvl,Format, Data),dbg(DbgLvl, Format, Data)).
--define(DBG_STR(DbgLvl, What, Str),dbg_str(DbgLvl, What, Str)).
-
-dbg(DbgLvl, Format, Data) when DbgLvl =< ?DEBUGLEVEL ->
- ok = io:format("DBG: " ++ Format, Data);
-dbg(_DbgLvl, _Format, _Data) -> ok.
-
-dbg_str(DbgLvl, What, Str) when DbgLvl =< ?DEBUGLEVEL ->
- ok = io:format("DBG: ~s~s\n", [What,dbg_s(Str)]);
-dbg_str(_DbgLvl, _What, _Data) -> ok.
-
-dbg_s([]) ->
- [];
-dbg_s([C | Str]) when list(C) ->
- [dbg_s(C) | dbg_s(Str)];
-dbg_s([C | Str]) when C >= 20, C < 255 ->
- [C | dbg_s(Str)];
-dbg_s([$\n | Str]) ->
- ["\\n" | dbg_s(Str)];
-dbg_s([$\r | Str]) ->
- ["\\r" | dbg_s(Str)];
-dbg_s([$\t | Str]) ->
- ["\\t" | dbg_s(Str)];
-dbg_s([C | Str]) when integer(C) ->
- [io_lib:format("\\~.3.0w",[C]) | dbg_s(Str)].
-
--else.
-
--define(DBG(DbgLvl,Format, Data), true).
--define(DBG_STR(DbgLvl, What, Str), true).
-
--endif.
-
-%% ------------------------------------------------------------
-%% INTERFACE FUNCTIONS
-%% ------------------------------------------------------------
-
-% Note: gs is not a true application so this doesn't work :-(
-% Communication protocol between Erlang backend and wish program
-% that can be set in the application environment, e.i. tested
-% with "erl -gs backend_comm socket"
-%
-% backend_comm = socket | port
-%
-% We fake reading the application variables from the command line.
-% Note that multiple -gs arguments can't be used.
-
-get_env(App, KeyAtom) ->
- KeyStr = atom_to_list(KeyAtom),
- ?DBG(1,"Result from init:get_argument(~w): ~p\n",
- [KeyAtom,init:get_argument(App)]),
- case init:get_argument(App) of
- {ok,[[KeyStr,ValStr]]} ->
- {ok,list_to_atom(ValStr)};
- _ ->
- undefined
- end.
-
-start_link(Gstk) ->
- ?DBG(1, "start_link(~w)~n", [Gstk]),
-% io:format("STARTS ~p\n",[erlang:localtime()]),
- Mode =
- % FIXME: Want to use application:get_env() if we where an true app
- case {os:type(),get_env(gs,backend_comm)} of
- {{win32,_Flavor},undefined} ->
- use_socket;
- {_OS,undefined} ->
- use_port;
- {_OS,{ok,socket}} ->
- use_socket;
- {_OS,{ok,port}} ->
- use_port
- end,
- ?DBG(1,"We use mode: ~w (~w)\n",[Mode,get_env(gs,backend_comm)]),
- Pid = spawn_link(gstk_port_handler, init, [Gstk,Mode]),
- receive
- {Pid, ok} ->
- {ok, Pid};
- {Pid, error, Reason} ->
- {error, Reason}
- after ?START_TIMEOUT ->
- {error, timeout}
- end.
-
-call(PortHandler, Cmd) ->
- PortHandler ! {call, ["erlcall {",Cmd,$}]},
- receive
- {result, Result} ->
- ?DBG(1, "call reply: ~p~n", [Result]),
- {result, Result};
- {bad_result, Bad_Result} ->
- ?DBG(1, "bad call reply: ~p~n", [Bad_Result]),
- {bad_result, Bad_Result}
- end.
-
-ping(PortHandler) ->
- ?DBG(1, "ping~n", []),
- PortHandler ! {ping, self()},
- receive
- {pong,_From,PortOrSock} -> {ok,PortOrSock}
- end.
-
-stop(PortHandler) ->
- ?DBG(1, "stop~n", []),
- PortHandler ! {stop,self()},
- receive
- {stopped,PortHandler} -> ok
- end.
-
-%% Purpose: asyncron call to tk
-%% too expensive
-% FIXME
-exec(Cmd) ->
- get(port_handler) ! {exec, ["erlexec {",Cmd,$}]},
- ok.
-
-% in gstk context, but I don't want "ifndef nt40" in other
-% modules than this one.
-%exec(Cmd) ->
-% ?DBG_STR(1, "", ["erlexec {",Cmd,"}"]),
-% case get(port) of
-% {socket,Sock} ->
-% gen_tcp:send(Sock, ["erlexec {",Cmd,$}]);
-% {port,Port} ->
-% Port ! {get(port_handler),{command,["erlexec {",Cmd,$}]}}
-% end,
-% ok.
-
-%% ===========================================================================
-%% The server
-%% ===========================================================================
-
-%% ---------------------------------------------------------------------
-%% We initiate by starting the wish port program and use the pipe
-%% or a socket to communicate with it.
-%%
-%% gstk: is the pid of the gstk process that started me.
-%% all my input (from the port) is forwarded to it.
-%%----------------------------------------------------------------------
--record(state,{out,gstk}).
-
-init(Gstk, Mode) ->
- process_flag(trap_exit,true),
-
- % ------------------------------------------------------------
- % Set up paths
- % ------------------------------------------------------------
-
- PrivDir = code:priv_dir(gs),
- TclDir = filename:join(PrivDir,"tcl"),
- TclBinDir = filename:join(TclDir,"bin"),
- TclLibDir = filename:join(TclDir,"lib"),
-
- InitScript = filename:nativename(filename:join(PrivDir,"gstk.tcl")),
-
- ?DBG(1, "TclBinDir : ~s\n", [TclBinDir]),
- ?DBG(1, "TclLibDir : ~s\n", [TclLibDir]),
- ?DBG(1, "InitScript : ~s\n", [InitScript]),
-
- % ------------------------------------------------------------
- % Search for wish in priv and in system search path
- % ------------------------------------------------------------
-
- {Wish,Options} =
- case filelib:wildcard(filename:join(TclBinDir,"wish*")) of
- % If more than one wish in priv we assume they are the same
- [PrivWish | _] ->
- % ------------------------------------------------
- % We have to set TCL_LIBRARY and TK_LIBRARY because else
- % 'wish' will search in the original installation directory
- % for 'tclIndex' and this may be an incompatible version on
- % the host we run on.
- % ------------------------------------------------
-
- [TclLibrary] =
- filelib:wildcard(filename:join(PrivDir,
- "tcl/lib/tcl[1-9]*")),
- [TkLibrary] =
- filelib:wildcard(filename:join(PrivDir,
- "tcl/lib/tk[1-9]*")),
-
- Opts = [{env,[{"TCL_LIBRARY", TclLibrary},
- {"TK_LIBRARY", TkLibrary},
- {"LD_LIBRARY_PATH",TclLibDir}]},
- {packet,4}],
- {PrivWish,Opts};
- _ ->
- % We use the system wish program
- {search_wish(?WISHNAMES, Gstk),[{packet,4}]}
- end,
-
-
- ?DBG(1, "Wish : ~s\n", [Wish]),
-
- Cmd =
- case Mode of
- use_socket ->
- % ------------------------------------------------------------
- % Set up a listening socket and call accept in another process
- % ------------------------------------------------------------
- SocketOpts =
- [
- {nodelay, true},
- {packet,4},
- {reuseaddr,true}
- ],
- % Let OS pick a number
- {ok,ListenSocket} = gen_tcp:listen(0, SocketOpts),
- {ok,ListenPort} = inet:port(ListenSocket),
-
- % Wait in another process
- spawn_link(?MODULE,wait_for_connection,[self(),ListenSocket]),
- lists:concat([Wish," ",InitScript," -- ",PrivDir," ",
- ListenPort]);
- use_port ->
- lists:concat([Wish," ",InitScript," -- ",PrivDir])
- end,
-
- ?DBG(1, "Port opts :\n~p\n", [Options]),
-
- % FIXME remove timing if not debugging
- Port =
- case timer:tc(erlang,open_port,[{spawn, Cmd}, Options]) of
- {_T,Port1} when is_port(Port1) ->
- ?DBG(1,"open_port takes ~p milliseconds\n",[_T/1000]),
- link(Port1),
- Port1;
- {_T,{error,_Reason1}} -> % FIXME: Why throw away reason?!
- ?DBG(1,"ERROR: ~p\n",[_Reason1]),
- Gstk ! {self(), error, backend_died},
- exit(normal)
- end,
-
- State =
- case Mode of
- use_socket ->
- % ------------------------------------------------------------
- % Wait for a connection
- % ------------------------------------------------------------
- Sock =
- receive
- {connected,Socket} ->
- Socket;
- % FIXME: Why throw away reason?!
- {'EXIT', _Pid, _Reason2} ->
- Gstk ! {self(), error, backend_died},
- exit(normal)
- end,
-
- ?DBG(1,"Got socket ~p~n",[Sock]),
- #state{out={socket,Sock}, gstk=Gstk};
- use_port ->
- #state{out={port,Port}, gstk=Gstk}
- end,
-
- Gstk ! {self(), ok}, % Tell caller we are prepared
- idle(State).
-
-search_wish([], Gstk) ->
- Gstk ! {self(), error, backend_died},
- exit(normal);
-search_wish([WishName | WishNames], Gstk) ->
- case os:find_executable(WishName) of
- false ->
- search_wish(WishNames, Gstk);
- Wish ->
- Wish
- end.
-
-%%----------------------------------------------------------------------
-%% If we use sockets we wait for connection from port prog
-%%----------------------------------------------------------------------
-
-wait_for_connection(CallerPid, ListenSocket) ->
- {ok,Sock} = gen_tcp:accept(ListenSocket, ?ACCEPT_TIMEOUT),
- ?DBG(1,"Got accept ~p~p~n",[self(),Sock]),
- ok = gen_tcp:controlling_process(Sock,CallerPid),
- CallerPid ! {connected,Sock}.
-
-%% ===========================================================================
-%% The main loop
-%% ===========================================================================
-
-idle(State) ->
- ?DBG(1, "idle~n", []),
-% io:format("IDLE ~p\n",[erlang:localtime()]),
- receive
-
- {call, Cmd} ->
- output(State, Cmd),
- idle(State);
-
- {exec, Cmd} ->
- collect_exec_calls(Cmd, [], 0, State),
- idle(State);
-
- {_Port, {data, Input}} ->
- ?DBG_STR(2, "INPUT[port]: ", [Input]),
- handle_input(State, Input),
- idle(State);
-
- {tcp, _Sock, Input} ->
- ?DBG_STR(2, "INPUT[sock]: ", [Input]),
- handle_input(State, Input),
- idle(State);
-
- {ping,From} ->
- From ! {pong,self(),State#state.out},
- idle(State);
-
- {stop,From} ->
- From ! {stopped,self()};
-
- % FIXME: We are we not to terminate if watforsocket
- % terminated but what about the port???????
- {'EXIT',_Pid,normal} ->
- ?DBG(1, "EXIT[~w]: normal~n", [_Pid]),
- idle(State);
-
- {'EXIT',Pid,Reason} ->
- %%io:format("Port died when in idle loop!~n"),
- ?DBG(1,"EXIT[~w]~n~p~n",[Pid,Reason]),
- exit({port_handler,Pid,Reason});
-
- Other ->
- ?DBG(1,"OTHER: ~p~n",[Other]),
- gs:error("gstk_port_handler: got other: ~w~n",[Other]),
- idle(State)
- end.
-
-%% ----------------------------------------------------------------------
-
--define(MAXQUEUE, 4). % FIXME find value...
-
-collect_exec_calls(Cmd, Queue, QueueLen, State) when QueueLen < ?MAXQUEUE ->
- receive
- {exec, NewCmd} ->
-% io:format("collect~p~n", [NewCmd]),
- collect_exec_calls(NewCmd, [Cmd | Queue], QueueLen+1, State)
- after 0 ->
- if
- QueueLen == 0 ->
- output(State, Cmd);
- true ->
- output(State, join_cmd_reverse(Cmd, Queue, []))
- end
- end;
-collect_exec_calls(Cmd, Queue, _QueueLen, State) -> % Queue is full, output
- String = join_cmd_reverse(Cmd, Queue, []),
-% io:format("queue full: ~p~n", [String]),
- output(State, String).
-
-
-join_cmd_reverse(Cmd, [], DeepStr) ->
- [DeepStr | Cmd];
-join_cmd_reverse(Cmd, [Cmd1 | Cmds], DeepStr) ->
- join_cmd_reverse(Cmd, Cmds, [Cmd1,$; | DeepStr]).
-
-%% ----------------------------------------------------------------------
-%%
-%% Handle incoming data
-%% 1 - Event
-%% 2 - Reply from call
-%% 3 - Bad reply from call
-%% 4 - Error
-%% 5 - End of message
-%%
-
-handle_input(State,[Type | Data]) ->
- GstkPid = State#state.gstk,
- case Type of
- 1 ->
- handle_event(GstkPid,Data);
-
- 2 ->
- GstkPid ! {result, Data};
-
- 3 ->
- GstkPid ! {bad_result, Data};
-
- 4 ->
- gs:error("gstk_port_handler: error in input : ~s~n",[Data])
- end.
-
-%% ----------------------------------------------------------------------
-%% output a command to the port
-%% buffer several incoming execs
-%%
-output(#state{out = {socket,Sock}}, Cmd) ->
- ?DBG_STR(1, "OUTPUT[sock]: ", [Cmd]),
- ok = gen_tcp:send(Sock, Cmd);
-
-output(#state{out = {port,Port}}, Cmd) ->
- ?DBG_STR(1, "OUTPUT[port]: ", [Cmd]),
- Port ! {self(), {command, Cmd}}.
-
-% FIXME why test list?
-handle_event(GstkPid, Bytes) when is_list(Bytes) ->
- Event = tcl2erl:parse_event(Bytes),
- ?DBG(1,"Event = ~p\n",[Event]),
- gstk:event(GstkPid, Event). %% Event is {ID, Etag, Args}
diff --git a/lib/gs/src/gstk_radiobutton.erl b/lib/gs/src/gstk_radiobutton.erl
deleted file mode 100644
index a778f46038..0000000000
--- a/lib/gs/src/gstk_radiobutton.erl
+++ /dev/null
@@ -1,343 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Radiobutton Type
-%% ------------------------------------------------------------
-
--module(gstk_radiobutton).
-
-%%------------------------------------------------------------------------------
-%% RADIOBUTTON OPTIONS
-%%
-%% Attributes:
-%% activebg Color
-%% activefg Color
-%% align n,w,s,e,nw,se,ne,sw,center
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% bg Color
-%% bw Int
-%% data Data
-%% disabledfg Color
-%% enable Bool
-%% fg Color
-%% group Atom
-%% groupid Groupid
-%% height Int
-%% highlightbg Color
-%% highlightbw Int
-%% highlightfg Color
-%% justify left|right|center
-%% label {text, String} | {image, BitmapFile}
-%% padx Int (Pixels)
-%% pady Int (Pixels)
-%% relief Relief [flat|raised|sunken|ridge|groove]
-%% selectbg Color
-%% underline Int
-%% value Atom
-%% width Int
-%% wraplength Int
-%% x Int
-%% y Int
-%%
-%% Commands:
-%% flash
-%% invoke
-%% select Bool
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% click [Bool | {Bool, Data}]
-%% configure [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%% cursor ??????
-%% focus ?????? (-takefocus)
-%% font ??????
-%%
-
--export([create/3,config/3,read/3,delete/2,event/5,option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%------------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/3
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- TkW = gstk_generic:mk_tkw_child(DB,GstkId),
- {G, GID, V, NOpts} = fix_group_and_value(Opts, DB, GstkId#gstkid.owner),
- NGstkId=GstkId#gstkid{widget=TkW,widget_data={G, GID, V}},
- PlacePreCmd = [";place ", TkW],
- case gstk_generic:make_command(NOpts, NGstkId, TkW, "", PlacePreCmd, DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(["radiobutton ", TkW," -bo 2 -indi true ",Cmd]),
- NGstkId
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- TkW = Gstkid#gstkid.widget,
- {NOpts, NGstkid} = fix_group_and_value(Opts, DB, Gstkid#gstkid.owner, Gstkid),
- SimplePreCmd = [TkW, " conf"],
- PlacePreCmd = [";place ", TkW],
- gstk_generic:mk_cmd_and_exec(NOpts,NGstkid,TkW,SimplePreCmd,PlacePreCmd,DB).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- {_, Gid, _} = Gstkid#gstkid.widget_data,
- gstk_db:delete_bgrp(DB, Gid),
- Gstkid#gstkid.widget.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : event/5
-%% Purpose : Construct the event and send it to the owner of the widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Etype - The event type
-%% Edata - The event data
-%% Args - The data from tcl/tk
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-event(DB, Gstkid, Etype, Edata, Args) ->
- Arg2 = case Etype of
- click ->
- [Text, _Grp | Rest] = Args,
- {G, _Gid, V} = Gstkid#gstkid.widget_data,
- [Text, G, V | Rest];
- _Other ->
- Args
- end,
- gstk_generic:event(DB, Gstkid, Etype, Edata, Arg2).
-
-
-
-%%------------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% TkW - The tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, TkW, DB,_) ->
- case Option of
- {disabledfg, Color} -> {s, [" -disabledforegr ", gstk:to_color(Color)]};
- {group, Group} -> {s, [" -var ", gstk:to_ascii(Group)]};
- {selectbg, Color} -> {s, [" -selectc ", gstk:to_color(Color)]};
- {underline, Int} -> {s, [" -un ", gstk:to_ascii(Int)]};
- {value, V} -> {s, [" -val ", gstk:to_ascii(V)]};
- {wraplength, Int} -> {s, [" -wr ", gstk:to_ascii(Int)]};
- flash -> {c, [TkW, " f;"]};
- invoke -> {c, [TkW, " i;"]};
- {select, true} -> {c, [TkW, " se;"]};
- {select, false} -> {c, [TkW, " des;"]};
- {click, On} -> cbind(DB, Gstkid, click, On);
- _ -> invalid_option
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/4
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,Gstkid, TkW,DB,_) ->
- case Option of
- disabledfg -> tcl2erl:ret_color([TkW," cg -disabledforegr"]);
- group -> {G, _, _} = Gstkid#gstkid.widget_data, G;
- groupid -> {_, Gid, _} = Gstkid#gstkid.widget_data, Gid;
- selectbg -> tcl2erl:ret_color([TkW," cg -selectc"]);
- underline -> tcl2erl:ret_int([TkW," cg -un"]);
- value -> {_, _, V} = Gstkid#gstkid.widget_data, V;
- wraplength -> tcl2erl:ret_int([TkW," cg -wr"]);
-
- select ->
- Cmd = ["list [set x [",TkW," cg -var];global $x;set $x] [",
- TkW," cg -val]"],
- case tcl2erl:ret_tuple(Cmd) of
- {X, X} -> true;
- _Other -> false
- end;
-
- click -> gstk_db:is_inserted(DB, Gstkid, click);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-%%------------------------------------------------------------------------------
-%% PRIMITIVES
-%%------------------------------------------------------------------------------
-
-%% create version
-fix_group_and_value(Opts, DB, Owner) ->
- {G, GID, V, NOpts} = fgav(Opts, erlNIL, erlNIL, erlNIL, []),
- RV = case V of
- erlNIL -> list_to_atom(lists:concat([v,gstk_db:counter(DB,value)]));
- Other0 -> Other0
- end,
- NG = case G of
- erlNIL -> rb;
- Other1 -> Other1
- end,
- RGID = case GID of
- erlNIL -> {rbgrp, NG, Owner};
- Other2 -> Other2
- end,
- RG = gstk_db:insert_bgrp(DB, RGID),
- {NG, RGID, RV, [{group, RG}, {value, RV} | NOpts]}.
-
-%% config version
-fix_group_and_value(Opts, DB, Owner, Gstkid) ->
- {RG, RGID, RV} = Gstkid#gstkid.widget_data,
- {G, GID, V, NOpts} = fgav(Opts, RG, RGID, RV, []),
- case {G, GID, V} of
- {RG, RGID, RV} ->
- {NOpts, Gstkid};
- {NG, RGID, RV} ->
- NGID = {rbgrp, NG, Owner},
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={NG,NGID,RV}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG} | NOpts], NGstkid};
- {RG, RGID, NRV} ->
- NGstkid = Gstkid#gstkid{widget_data={RG,RGID,NRV}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{value,NRV} | NOpts], NGstkid};
- {_, NGID, RV} when NGID =/= RGID ->
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={RG,NGID,RV}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG} | NOpts], NGstkid};
- {_, NGID, NRV} when NGID =/= RGID ->
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={RG,NGID,NRV}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG}, {value,NRV} | NOpts], NGstkid};
- {NG, RGID, NRV} ->
- NGID = {rbgrp, NG, Owner},
- gstk_db:delete_bgrp(DB, RGID),
- NRG = gstk_db:insert_bgrp(DB, NGID),
- NGstkid = Gstkid#gstkid{widget_data={NG,NGID,NRV}},
- gstk_db:insert_widget(DB, NGstkid),
- {[{group, NRG}, {value,NRV} | NOpts], NGstkid}
- end.
-
-
-
-fgav([{group, G} | Opts], _, GID, V, Nopts) ->
- fgav(Opts, G, GID, V, Nopts);
-
-fgav([{groupid, GID} | Opts], G, _, V, Nopts) ->
- fgav(Opts, G, GID, V, Nopts);
-
-fgav([{value, V} | Opts], G, GID, _, Nopts) ->
- fgav(Opts, G, GID, V, Nopts);
-
-fgav([Opt | Opts], G, GID, V, Nopts) ->
- fgav(Opts, G, GID, V, [Opt | Nopts]);
-
-fgav([], Group, GID, Value, Opts) ->
- {Group, GID, Value, Opts}.
-
-%%
-%% Config bind
-%%
-cbind(DB, Gstkid, Etype, On) ->
- TkW = Gstkid#gstkid.widget,
- Cmd = case On of
- {true, Edata} ->
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, Edata),
- [" -command {erlsend ", Eref,
- " \\\"[", TkW, " cg -text]\\\" [", TkW, " cg -var]}"];
- true ->
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, ""),
- [" -command {erlsend ", Eref,
- " \\\"[", TkW, " cg -text]\\\" [", TkW, " cg -var]}"];
- _Other ->
- gstk_db:delete_event(DB, Gstkid, Etype),
- " -command {}"
- end,
- {s, Cmd}.
-
-%% ----- Done -----
-
diff --git a/lib/gs/src/gstk_rectangle.erl b/lib/gs/src/gstk_rectangle.erl
deleted file mode 100644
index 21e2a06cb4..0000000000
--- a/lib/gs/src/gstk_rectangle.erl
+++ /dev/null
@@ -1,186 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Rectangle Type
-%% ------------------------------------------------------------
-
--module(gstk_rectangle).
--compile([{nowarn_deprecated_function,{gs,pair,2}}]).
-
-%%-----------------------------------------------------------------------------
-%% RECTANGLE OPTIONS
-%%
-%% Attributes:
-%% bw Int
-%% coords [{X1,Y1}, {X2,Y2}]
-%% data Data
-%% fg Color
-%% fill Color
-%% stipple Bool
-%%
-%% Commands:
-%% lower
-%% move {Dx, Dy}
-%% raise
-%% scale {Xo, Yo, Sx, Sy}
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-
-
--export([create/3, config/3, read/3, delete/2, destroy/3, event/5,
- option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/7
-%% Purpose : Create a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Objmod - An atom, this module
-%% Objtype - An atom, the logical widget type
-%% Owner - Pid of the creator
-%% Name - An atom naming the widget
-%% Parent - Gsid of the parent
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [Gsid_of_new_widget | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB,Gstkid, Opts) ->
- case gstk_canvas:pickout_coords(Opts, [],rectangle,2) of
- {error, Error} ->
- {bad_result, Error};
- {Coords, NewOpts} ->
- gstk_db:insert_opt(DB,Gstkid,gs:pair(coords,Opts)),
- Ngstkid=gstk_canvas:upd_gstkid(DB, Gstkid, Opts),
- #gstkid{widget=CanvasTkW}=Ngstkid,
- MCmd = [CanvasTkW, " create re ", Coords],
- gstk_canvas:mk_cmd_and_call(NewOpts, Ngstkid,CanvasTkW, MCmd, DB)
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- gstk_canvas:item_config(DB, Gstkid, Opts).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- Item = Gstkid#gstkid.widget_data,
- gstk_generic:read_option(DB,Gstkid,Opt,[gstk:to_ascii(Item)]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy | {Parent, Objmod, Args}.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_canvas:item_delete_impl(DB,Gstkid).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : destroy/3
-%% Purpose : Destroy a widget
-%% Args : DB - The Database
-%% Canvas - The canvas tk widget
-%% Item - The item number to destroy
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-destroy(_DB, Canvas, Item) ->
- gstk:exec([Canvas, " delete ", gstk:to_ascii(Item)]).
-
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-%%------------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/5
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% MainW - The main tk-widget
-%% Canvas - The canvas tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, _Gstkid, _Canvas, _DB, _AItem) ->
- case Option of
- {bw, Int} -> {s, [" -w ", gstk:to_ascii(Int)]};
- {fg, Color} -> {s, [" -outline ", gstk:to_color(Color)]};
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option, Gstkid, Canvas, _DB, AItem) ->
- case Option of
- bw -> tcl2erl:ret_int([Canvas, " itemcg ", AItem, " -w"]);
- fg -> tcl2erl:ret_color([Canvas," itemcg ", AItem, " -outline"]);
- stipple ->
- tcl2erl:ret_stipple([Canvas, " itemcg ", AItem, " -stipple"]);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-%% ----- Done -----
diff --git a/lib/gs/src/gstk_scale.erl b/lib/gs/src/gstk_scale.erl
deleted file mode 100644
index 3512304867..0000000000
--- a/lib/gs/src/gstk_scale.erl
+++ /dev/null
@@ -1,215 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Scale Type
-%% ------------------------------------------------------------
-
--module(gstk_scale).
-
-%%-------------------------------------------------------------------------
-%% SCALE OPTIONS
-%%
-%% Attributes:
-%% activebg Color
-%% anchor n,w,s,e,nw,se,ne,sw,center
-%% bg Color
-%% bw Int
-%% data Data
-%% fg Color
-%% height Int
-%% highlightbg Color
-%% highlightbw Int
-%% highlightfg Color
-%% orient vertical | horizontal
-%% range {From, To}
-%% relief Relief [flat|raised|sunken|ridge|groove]
-%% showvalue Bool
-%% text String
-%% width Int
-%% x Int
-%% y Int
-%%
-%% Commands:
-%% enable Bool
-%% pos Int
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% click [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-
--export([create/3,config/3,read/3,delete/2,event/5,
- option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%------------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/7
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, GstkId, Opts) ->
- TkW = gstk_generic:mk_tkw_child(DB,GstkId),
- PlacePreCmd = [";place ", TkW],
- Ngstkid = GstkId#gstkid{widget=TkW},
- case gstk_generic:make_command(Opts, Ngstkid, TkW,"", PlacePreCmd, DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- gstk:exec(["scale ", TkW,Cmd,$;,TkW,
- " conf -bo 2 -sliderrelief raised -highlightth 2"]),
- Ngstkid
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- TkW = Gstkid#gstkid.widget,
- SimplePreCmd = [TkW, " conf"],
- PlacePreCmd = [";place ", TkW],
- gstk_generic:mk_cmd_and_exec(Opts,Gstkid,TkW,SimplePreCmd,PlacePreCmd,DB).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% TkW - The tk-widget
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, TkW, DB,_) ->
- case Option of
- {activebg, Color} -> {s, [" -activeb ", gstk:to_color(Color)]};
- {orient, How} -> {s, [" -or ", gstk:to_ascii(How)]};
- {range, {From, To}} -> {s, [" -fr ", gstk:to_ascii(From),
- " -to ", gstk:to_ascii(To)]};
- {relief, Relief} -> {s, [" -rel ", gstk:to_ascii(Relief)]};
- {bw, Wth} -> {s, [" -bd ", gstk:to_ascii(Wth)]};
- {text, String} -> {s, [" -la ",gstk:to_ascii(String)]};
- {showvalue, Bool} -> {s, [" -showvalue ",gstk:to_ascii(Bool)]};
- {pos, Pos} -> {c, [TkW, " set ", gstk:to_ascii(Pos)]};
- {click, On} -> cbind(DB, Gstkid, click, On);
- _ -> invalid_option
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option,Gstkid,TkW,DB,_) ->
- case Option of
- activebg -> tcl2erl:ret_color([TkW," cg -activeb"]);
- orient -> tcl2erl:ret_atom([TkW," cg -ori"]);
- range ->
- tcl2erl:ret_tuple(["list [",TkW," cg -fr] [",TkW," cg -to]"]);
- bw -> tcl2erl:ret_int([TkW," cg -bd"]);
- relief -> tcl2erl:ret_atom([TkW, " cg -reli"]);
- text -> tcl2erl:ret_str([TkW," cg -lab"]);
- showvalue -> tcl2erl:ret_bool([TkW," cg -showvalue"]);
- pos -> tcl2erl:ret_int([TkW," get"]);
- click -> gstk_db:is_inserted(DB, Gstkid, click);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-%%-----------------------------------------------------------------------------
-%% PRIMITIVES
-%%-----------------------------------------------------------------------------
-
-
-%%
-%% Config bind
-%%
-cbind(DB, Gstkid, Etype, On) ->
- Cmd = case On of
- {true, Edata} ->
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, Edata),
- [" -command {erlsend ", Eref, "}"];
- true ->
- Eref = gstk_db:insert_event(DB, Gstkid, Etype, ""),
- [" -command {erlsend ", Eref, "}"];
- _Other ->
- gstk_db:delete_event(DB, Gstkid, Etype),
- " -command {}"
- end,
- {s, Cmd}.
-
-%% ----- Done -----
diff --git a/lib/gs/src/gstk_text.erl b/lib/gs/src/gstk_text.erl
deleted file mode 100644
index b931030a3f..0000000000
--- a/lib/gs/src/gstk_text.erl
+++ /dev/null
@@ -1,190 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Text Type
-%% ------------------------------------------------------------
-
--module(gstk_text).
-
-%%-----------------------------------------------------------------------------
-%% TEXT OPTIONS
-%%
-%% Attributes:
-%% anchor n|w|e|s|nw|sw|ne|se|center
-%% coords [{X,Y}]
-%% data Data
-%% fg Color
-%% font Font
-%% justify left | center | right
-%% stipple Bool
-%% text String
-%% width Int (line length in characters)
-%%
-%% Commands:
-%% lower
-%% move {Dx, Dy}
-%% raise
-%% scale {Xo, Yo, Sx, Sy}
-%% setfocus Bool
-%%
-%% Events:
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%%
-%% Read Options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%% fontfamily ?????? Family
-%% fontsize ?????? Size
-%% style ?????? [bold,italic]
-%%
-
--export([create/3, config/3, read/3, delete/2, destroy/3, event/5,
- option/5,read_option/5]).
-
--include("gstk.hrl").
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%----------------------------------------------------------------------------
-create(DB, Gstkid, Opts) ->
- case gstk_canvas:pickout_coords(Opts, [],text,1) of
- {error, Error} ->
- {bad_result, Error};
- {Coords, NewOpts} ->
- Ngstkid=gstk_canvas:upd_gstkid(DB, Gstkid, Opts),
- #gstkid{widget=CanvasTkW}=Ngstkid,
- MCmd = [CanvasTkW, " create te ", Coords],
- gstk_canvas:mk_cmd_and_call(NewOpts,Ngstkid,CanvasTkW, MCmd, DB)
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- gstk_canvas:item_config(DB, Gstkid, Opts).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- Item = Gstkid#gstkid.widget_data,
- gstk_generic:read_option(DB,Gstkid,Opt,[gstk:to_ascii(Item)]).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy | {Parent, Objmod, Args}.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_canvas:item_delete_impl(DB,Gstkid).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : destroy/3
-%% Purpose : Destroy a widget
-%% Args : DB - The Database
-%% Canvas - The canvas tk widget
-%% Item - The item number to destroy
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-destroy(_DB, Canvas, Item) ->
- gstk:exec([Canvas, " delete ", gstk:to_ascii(Item)]).
-
-
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/5
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% MainW - The main tk-widget
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-option(Option, Gstkid, _Canvas, DB, _AItem) ->
- case Option of
- {anchor, How} -> {s, [" -anchor ", gstk:to_ascii(How)]};
- {fg, Color} -> {s, [" -fi ", gstk:to_color(Color)]};
- {font, Font} when is_tuple(Font) ->
- gstk_db:insert_opt(DB,Gstkid,Option),
- {s, [" -fo ", gstk_font:choose_ascii(DB,Font)]};
- {justify, How} -> {s, [" -j ", gstk:to_ascii(How)]};
- {text, Text} -> {s, [" -te ", gstk:to_ascii(Text)]};
- {width, Width} -> {s, [" -w ", gstk:to_ascii(Width)]};
- _ -> invalid_option
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/5
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option, Gstkid, Canvas, DB, AItem) ->
- case Option of
- anchor -> tcl2erl:ret_atom([Canvas, " itemcg ", AItem, " -anchor"]);
- fg -> tcl2erl:ret_color([Canvas, " itemcg ", AItem, " -fi"]);
- font -> gstk_db:opt(DB,Gstkid,font,undefined);
- justify -> tcl2erl:ret_atom([Canvas, " itemcg ", AItem, " -j"]);
- stipple -> tcl2erl:ret_stipple([Canvas," itemcg ",AItem," -stipple"]);
- text -> tcl2erl:ret_str([Canvas, " itemcg ", AItem, " -te"]);
- width -> tcl2erl:ret_int([Canvas, " itemcg ", AItem, " -w"]);
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-
-%% ----- Done -----
diff --git a/lib/gs/src/gstk_widgets.erl b/lib/gs/src/gstk_widgets.erl
deleted file mode 100644
index 52c955af50..0000000000
--- a/lib/gs/src/gstk_widgets.erl
+++ /dev/null
@@ -1,94 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Widget specific data
-%% ------------------------------------------------------------
-%%
-
--module(gstk_widgets).
-
--export([type2mod/1, objmod/1, suffix/1]).
-
--include("gstk.hrl").
-
-
-
-
-%%
-%% Map primitive types to modules or false (false should not be a module!)
-%%
-%% ordered for efficiency
-
-type2mod(window) -> gstk_window;
-type2mod(frame) -> gstk_frame;
-type2mod(button) -> gstk_button;
-type2mod(canvas) -> gstk_canvas;
-type2mod(checkbutton) -> gstk_checkbutton;
-type2mod(rectangle) -> gstk_rectangle;
-type2mod(gs) -> gstk_gs;
-type2mod(grid) -> gstk_grid;
-type2mod(gridline) -> gstk_gridline;
-type2mod(text) -> gstk_text;
-type2mod(image) -> gstk_image;
-type2mod(label) -> gstk_label;
-type2mod(line) -> gstk_line;
-type2mod(entry) -> gstk_entry;
-type2mod(listbox) -> gstk_listbox;
-type2mod(editor) -> gstk_editor;
-type2mod(menu) -> gstk_menu;
-type2mod(menubar) -> gstk_menubar;
-type2mod(menubutton) -> gstk_menubutton;
-type2mod(menuitem) -> gstk_menuitem;
-type2mod(message) -> gstk_message;
-type2mod(oval) -> gstk_oval;
-type2mod(polygon) -> gstk_polygon;
-type2mod(prompter) -> gstk_prompter;
-type2mod(radiobutton) -> gstk_radiobutton;
-type2mod(scale) -> gstk_scale;
-type2mod(scrollbar) -> gstk_scrollbar;
-type2mod(arc) -> gstk_arc;
-type2mod(Type) -> {error,{unknown_type, Type}}.
-
-objmod(#gstkid{objtype=OT}) -> type2mod(OT).
-
-%%
-%% The suffix to add to the parent tk widget
-%%
-suffix(button) -> ".b";
-suffix(canvas) -> ".c";
-suffix(checkbutton) -> ".cb";
-suffix(editor) -> ".ed";
-suffix(entry) -> ".e";
-suffix(frame) -> ".f";
-suffix(label) -> ".l";
-suffix(listbox) -> ".lb";
-suffix(menu) -> ".m";
-suffix(menubar) -> ".bar";
-suffix(menubutton) -> ".mb";
-suffix(message) -> ".ms";
-suffix(prompter) -> ".p";
-suffix(radiobutton) -> ".rb";
-suffix(scale) -> ".sc";
-suffix(window) -> ".w";
-suffix(Objtype) -> apply(type2mod(Objtype), suffix, []).
-
-
diff --git a/lib/gs/src/gstk_window.erl b/lib/gs/src/gstk_window.erl
deleted file mode 100644
index c14cf2fd81..0000000000
--- a/lib/gs/src/gstk_window.erl
+++ /dev/null
@@ -1,371 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%% Basic Window Type.
-%% ------------------------------------------------------------
-
--module(gstk_window).
--compile([{nowarn_deprecated_function,{gs,destroy,1}}]).
-
-%%------------------------------------------------------------------------------
-%% WINDOW OPTIONS
-%%
-%% Attributes:
-%% x Int
-%% y Int
-%% width Int
-%% height Int
-%% bg Color
-%% bw Int
-%% relief Relief [flat|raised|sunken|ridge|groove]
-%% highlightbw Int
-%% highlightbg Color
-%% highlightfg Color
-%% map Bool
-%% iconify Bool
-%% title String
-%% iconname String
-%% iconbitmap Bitmap
-%% iconmask Bitmap
-%% data Data
-%% cursor arrow|busy|cross|hand|help|resize|text
-%%
-%% Commands:
-%% raise
-%% lower
-%% setfocus Bool
-%%
-%% Events:
-%% configure [Bool | {Bool, Data}]
-%% enter [Bool | {Bool, Data}]
-%% leave [Bool | {Bool, Data}]
-%% motion [Bool | {Bool, Data}]
-%% keypress [Bool | {Bool, Data}]
-%% keyrelease [Bool | {Bool, Data}]
-%% buttonpress [Bool | {Bool, Data}]
-%% buttonrelease [Bool | {Bool, Data}]
-%% focus [Bool | {Bool, Data}]
-%% destroy [Bool | {Bool, Data}]
-%%
-%% Read options:
-%% children
-%% id
-%% parent
-%% type
-%%
-%% Not Implemented:
-%% screen ?????????
-%% map
-%% unmap
-%% iconify
-%% deiconify
-%% focusmodel [active|passive] (wm focusmodel)
-%%
-
--export([create/3, config/3, read/3, delete/2, event/5,destroy_win/1]).
--export([option/5,read_option/5,mk_create_opts_for_child/4]).
-
--include("gstk.hrl").
-% bind . <1> {puts "x: [expr %X - [winfo rootx .]] y: [expr %Y - [wi rooty .]]"}
-
-%%-----------------------------------------------------------------------------
-%% MANDATORY INTERFACE FUNCTIONS
-%%-----------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : create/3
-%% Purpose : Create a widget of the type defined in this module.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-create(DB, Gstkid, Opts) ->
- TkW = gstk_generic:mk_tkw_child(DB,Gstkid),
- NGstkid=Gstkid#gstkid{widget=TkW},
- case gstk_generic:make_command(transform_geometry_opts(Opts),
- NGstkid, TkW, "", ";", DB) of
- {error,Reason} -> {error,Reason};
- Cmd when is_list(Cmd) ->
- BindCmd = gstk_generic:bind(DB, Gstkid, TkW, configure, true),
-% io:format("\nWINDOW1: ~p\n",[TkW]),
-% io:format("\nWINDOW1: ~p\n",[Cmd]),
-% io:format("\nWINDOW1: ~p\n",[BindCmd]),
- gstk:exec(["toplevel ", TkW,Cmd,$;,BindCmd]),
- NGstkid
- end.
-
-mk_create_opts_for_child(DB,Cgstkid, Pgstkid, Opts) ->
- gstk_generic:mk_create_opts_for_child(DB,Cgstkid,Pgstkid,Opts).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : config/3
-%% Purpose : Configure a widget of the type defined in this module.
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opts - A list of options for configuring the widget
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-config(DB, Gstkid, Opts) ->
- TkW = Gstkid#gstkid.widget,
- SimplePreCmd = [TkW, " conf"],
- gstk_generic:mk_cmd_and_exec(transform_geometry_opts(Opts),
- Gstkid,TkW,SimplePreCmd,"",DB).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read/3
-%% Purpose : Read one option from a widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Opt - An option to read
-%%
-%% Return : [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read(DB, Gstkid, Opt) ->
- gstk_generic:read_option(DB, Gstkid, Opt).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : delete/2
-%% Purpose : Delete widget from databas and return tkwidget to destroy
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%%
-%% Return : TkWidget to destroy
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(DB, Gstkid) ->
- gstk_db:delete_widget(DB, Gstkid),
- Gstkid#gstkid.widget.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : event/5
-%% Purpose : Construct the event and send it to the owner of the widget
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Etype - The event type
-%% Edata - The event data
-%% Args - The data from tcl/tk
-%%
-%% Return : [true | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-event(DB, Gstkid, configure, Edata, Args) ->
- [W,H|_] = Args,
- gstk_db:insert_opt(DB,Gstkid,{width,W}),
- gstk_db:insert_opt(DB,Gstkid,{height,H}),
- case gstk_db:opt(DB,Gstkid,configure) of
- true ->
- apply(gstk_generic,event,[DB,Gstkid,configure,Edata,Args]);
- false ->
- ok
- end;
-event(DB, Gstkid, destroy, Edata, Args) ->
- spawn(gstk_window,destroy_win,[gstk:make_extern_id(Gstkid#gstkid.id,DB)]),
- gstk_generic:event(DB, Gstkid, destroy, Edata, Args);
-event(DB, Gstkid, Etype, Edata, Args) ->
- gstk_generic:event(DB, Gstkid, Etype, Edata, Args).
-
-destroy_win(ID) ->
- gs:destroy(ID).
-%%------------------------------------------------------------------------------
-%% MANDATORY FUNCTIONS
-%%------------------------------------------------------------------------------
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : option/4
-%% Purpose : Take care of options
-%% Args : Option - An option tuple
-%% Gstkid - The gstkid of the widget
-%% TkW - The tk-widget
-%% DB - The Database
-%%
-%% Return : A tuple {OptionType, OptionCmd}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%-define(REGEXP,"regexp {(\\d+)x(\\d+)\\+?(-?\\d+)\\+?(-?\\d+)} ").
-% FIXME: Is this ok? Always positive?
--define(REGEXP,"regexp {(\\d+)x(\\d+)\\+(\\d+)\\+(\\d+)} ").
-
-option(Option, Gstkid, TkW, DB,_) ->
- case Option of
-%% Bug in tcl/tk complicates setting of a single x,y,width,height.
- {x, X} ->
- {c,
- [?REGEXP,"[wm ge ",TkW, "] g w h x y;wm ge ", TkW,
- " ${w}x$h",signed(X),"+$y;update idletasks"]};
- {y, Y} ->
- {c,[?REGEXP,"[wm ge ",TkW, "] g w h x y;wm ge ", TkW,
- " ${w}x$h+$x",signed(Y),"; update idletasks"]};
- {width, Width} when Width >= 0 -> % FIXME: Needed test?
- case gstk_db:opt_or_not(DB,Gstkid,width) of
- {value,Width} -> none;
- _Q ->
- gstk_db:insert_opt(DB,Gstkid,{width,Width}),
- {c,[?REGEXP,"[wm ge ",TkW, "] g w h x y;wm ge ", TkW," ",
- gstk:to_ascii(Width),"x$h+$x+$y;update idletasks"]}
- end;
- {height, Height} when Height >= 0 -> % FIXME: Needed test?
- case gstk_db:opt_or_not(DB,Gstkid,height) of
- {value,Height} -> none;
- _Q -> % FIXME: Why different?
- gstk_db:insert_opt(DB,Gstkid,{height,Height}),
- {c,
- ["wm ge ",TkW,
- " [winfo w ", TkW, "]x",gstk:to_ascii(Height),
- ";update idletasks"]}
- end;
- {width_height, {W,H}} when W >= 0, H >= 0 ->
- case {gstk_db:opt_or_not(DB,Gstkid,width),
- gstk_db:opt_or_not(DB,Gstkid,height)} of
- {{value,W},{value,H}} ->
- none;
- _OtherSize ->
- gstk_db:insert_opt(DB,Gstkid,{height,H}),
- gstk_db:insert_opt(DB,Gstkid,{width,W}),
- {c, ["update idletasks;wm ge ", TkW, " ",
- gstk:to_ascii(W),"x",gstk:to_ascii(H),
- ";update idletasks"]}
- end;
- {xy, {X,Y}} ->
- {c, [?REGEXP,"[wm ge ",TkW, "] g w h x y;wm ge ", TkW,
- " ${w}x$h", signed(X),signed(Y),
- ";update idletasks"]};
- {bg, Color} -> {s, [" -bg ", gstk:to_color(Color)]};
- {map, true} -> {c, ["wm deiconify ", TkW]};
- {map, false} -> {c, ["wm withdraw ", TkW]};
- {configure, On} ->
- gstk_db:insert_opt(DB,Gstkid,{configure,On}),
- none;
- {iconify, true} -> {c, ["wm iconify ", TkW]};
- {iconify, false} -> {c, ["wm deiconify ", TkW]};
- {title, Title} -> {c, ["wm title ", TkW, " " ,
- gstk:to_ascii(Title)]};
- {iconname, Name} -> {c, ["wm iconn ",TkW, " ",
- gstk:to_ascii(Name)]};
- {iconbitmap, Bitmap} -> {c, ["wm iconb ",TkW, " ",
- gstk:to_ascii(Bitmap)]};
- {iconmask, Bitmap} -> {c, ["wm iconm ",TkW, " ",
- gstk:to_ascii(Bitmap)]};
- raise -> {c, ["raise ", TkW]};
- lower -> {c, ["lower ", TkW]};
- {setfocus, true} -> {c, ["focus ", TkW]};
- {setfocus, false} -> {c, ["focus {}"]};
- {buttonpress, On} ->
- Eref = mk_eref(On, DB, Gstkid, buttonpress),
- {c,["bind ",TkW," <ButtonPress> ",
- event_onoff(["{erlsend ",Eref," %b ",xy_abs_str(TkW),"};"],On)]};
- {buttonrelease, On} ->
- Eref = mk_eref(On, DB, Gstkid, buttonrelease),
- {c,["bind ",TkW," <ButtonRelease> ",
- event_onoff(["{erlsend ",Eref," %b ",xy_abs_str(TkW),"};"],On)]};
- {motion, On} ->
- Eref = mk_eref(On, DB, Gstkid, motion),
- {c,["bind ",TkW," <Motion> ",
- event_onoff(["{erlsend ",Eref," ",xy_abs_str(TkW),"};"],On)]};
- _ -> invalid_option
- end.
-
-xy_abs_str(TkW) ->
- ["[expr %X-[winfo rootx ",TkW,"]] [expr %Y-[winfo rooty ",TkW,"]]"].
-
-event_onoff(Str, true) -> Str;
-event_onoff(_,false) -> "{}".
-
-mk_eref(false, DB, Gstkid, Etype) ->
- gstk_db:delete_event(DB, Gstkid, Etype),
- dummy;
-mk_eref(true,DB,Gstkid,Etype) ->
- gstk_db:insert_event(DB, Gstkid, Etype, []).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Function : read_option/3
-%% Purpose : Take care of a read option
-%% Args : DB - The Database
-%% Gstkid - The gstkid of the widget
-%% Option - An option
-%%
-%% Return : The value of the option or invalid_option
-%% [OptionValue | {bad_result, Reason}]
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-read_option(Option, Gstkid, TkW, DB,_) ->
- case Option of
- x -> tcl2erl:ret_x(geo_str(TkW));
- y -> tcl2erl:ret_y(geo_str(TkW));
- width -> tcl2erl:ret_width(geo_str(TkW));
- height -> tcl2erl:ret_height(geo_str(TkW));
- configure -> gstk_db:opt(DB,Gstkid,configure);
- bg -> tcl2erl:ret_color([TkW," cg -bg"]);
- map -> tcl2erl:ret_mapped(["winfo is ", TkW]);
- iconify -> tcl2erl:ret_iconified(["wm st ", TkW]);
- title -> tcl2erl:ret_str(["wm ti ", TkW]);
- iconname -> tcl2erl:ret_str(["wm iconn ", TkW]);
- iconbitmap -> tcl2erl:ret_str(["wm iconb ", TkW]);
- iconmask -> tcl2erl:ret_str(["wm iconm ", TkW]);
- setfocus -> tcl2erl:ret_focus(TkW, "focus");
- _ -> {bad_result, {Gstkid#gstkid.objtype, invalid_option, Option}}
- end.
-
-geo_str(TkW) ->
- ["update idletasks;",?REGEXP,"[wm geometry ", TkW,
- "] g w h x y;set tmp \"$w $h $x $y\""].
-
-
-
-%%----------------------------------------------------------------------
-%% PRIMITIVES
-%%----------------------------------------------------------------------
-
-%% Return {+,-}Int to be used in a geometry option
-signed(X) when X>=0 ->
- [$+,integer_to_list(X)];
-signed(X) when X<0 ->
- integer_to_list(X).
-
-%%----------------------------------------------------------------------
-%% Purpose: tcl/tk: wm .window geo sets WxH+x+y at one time.
-%% flushing every time is expensive. Do (almost) as much as
-%% possible in one operation.
-%%----------------------------------------------------------------------
-transform_geometry_opts(Opts) ->
- {Geo,RestOpts} = collect_geo_opts(Opts,[],[]),
- Geo2 = make_atomic(lists:sort(Geo)),
- lists:append(Geo2,RestOpts).
-
-make_atomic([{height,H},{width,W},{x,X},{y,Y}]) ->
- [{width_height,{W,H}},{xy,{X,Y}}];
-make_atomic([{height,H},{width,W}|XY]) ->
- [{width_height,{W,H}}|XY];
-make_atomic([WH,{x,X},{y,Y}]) ->
- [WH,{xy,{X,Y}}];
-make_atomic(L) -> L.
-
-%%----------------------------------------------------------------------
-%% Returns: {(list of x,y,width,height options),list of other opts}
-%%----------------------------------------------------------------------
-collect_geo_opts([{x,X}|Opts],Geo,Rest) ->
- collect_geo_opts(Opts,[{x,X}|Geo],Rest);
-collect_geo_opts([{y,Y}|Opts],Geo,Rest) ->
- collect_geo_opts(Opts,[{y,Y}|Geo],Rest);
-collect_geo_opts([{height,H}|Opts],Geo,Rest) ->
- collect_geo_opts(Opts,[{height,H}|Geo],Rest);
-collect_geo_opts([{width,W}|Opts],Geo,Rest) ->
- collect_geo_opts(Opts,[{width,W}|Geo],Rest);
-collect_geo_opts([Opt|Opts],Geo,Rest) ->
- collect_geo_opts(Opts,Geo,[Opt|Rest]);
-collect_geo_opts([],Geo,Rest) -> {Geo,Rest}.
-
-%%% ----- Done -----
diff --git a/lib/gs/src/tcl2erl.erl b/lib/gs/src/tcl2erl.erl
deleted file mode 100644
index 04229ccf49..0000000000
--- a/lib/gs/src/tcl2erl.erl
+++ /dev/null
@@ -1,459 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% ------------------------------------------------------------
-%%
-%% Handle conversion from tcl string to erlang terms
-%%
-%% ------------------------------------------------------------
-
--module(tcl2erl).
--compile([{nowarn_deprecated_function,{gs,error,2}}]).
-
--export([parse_event/1,
- ret_int/1,
- ret_atom/1,
- ret_str/1,
- ret_tuple/1,
- ret_pack/2,
- ret_place/2,
- ret_x/1,
- ret_y/1,
- ret_width/1,
- ret_height/1,
- ret_list/1,
- ret_str_list/1,
- ret_label/1,
- ret_mapped/1,
- ret_iconified/1,
- ret_focus/2,
- ret_file/1,
- ret_bool/1,
- ret_enable/1,
- ret_color/1,
- ret_stipple/1]).
-
--include("gstk.hrl").
-
-
-
-%% ----------------------------------------
-%% Parse an incoming event represented as
-%% a list of bytes
-%%
-parse_event(Bytes) ->
- {[$#|ID], Cont1} = first_word(Bytes),
- {Etag, Cont} = first_word(Cont1),
- {tokens, Toks} = scan(Cont),
- {term_seq, Args}= parse_term_seq(Toks),
- {list_to_integer(ID), Etag, Args}.
-
-
-%%---first word returns {Word,Cont}---%%
-first_word(Bytes) ->
- fw(Bytes,[]).
-
-fw([],Ack) ->
- {lists:reverse(Ack),[]};
-fw([$ |R],Ack) ->
- {lists:reverse(Ack),R};
-fw([Char|R],Ack) ->
- fw(R,[Char|Ack]).
-
-
-%% ---------------------------------------------
-%% str_to_term(Str)
-%% Transforms a string to the corresponding Erlang
-%% term. Note that the string "Hello" will be
-%% transformed to an Erlang atom: 'Hello' .
-%% If it is impossible to convert the string into
-%% a term the original string is just returned.
-%% str_to_term(Str) <---> {string, Str} or {term, Term}
-%% 'so that we can be able to tell if conversion succeded or not.'
-%%
-
-str_to_term(Str) ->
- {tokens,Tokens} = scan(Str),
- case catch parse_term(Tokens) of
- {_Type, Term,[]} -> {term,Term};
- _ -> {string, Str}
- end.
-
-
-%% ---------------------------------------------
-%% Simple Parser. ;-)
-%% Parses tokens or fails.
-%% Better catch result.
-%% Tokens should be generated by scan.
-%% parse_term(Toks) <----> {term, Term, Cont}
-%% parse_call(Toks) <----> {call, Mod, Fun, Args, Cont}
-%% parse_list(Toks) <----> {list, ListTerm, Cont}
-%% parse_tuple(Toks) <----> {tuple, TupleTerm, Cont}
-%% parse_fun_args(Toks) <-> {fun_args, FunArgs, Cont} %% like (arg1, arg2...)
-%% parse_term_seq(Toks) <-> {term_seq, Term_Sequence} %% no continuation
-%%
-
-parse_term([{var,Var}|R]) -> {var,Var,R};
-parse_term([{atom,Atom}|R]) -> {atom,Atom,R};
-parse_term([{float,Float}|R]) -> {float,Float,R};
-parse_term([{integer,Integer}|R]) -> {integer,Integer,R};
-parse_term([{string,String}|R]) -> {string,String,R};
-parse_term(['-',{integer,Integer}|R]) -> {integer,-Integer,R};
-parse_term(['-',{float,Float}|R]) -> {float,-Float,R};
-parse_term(['+',{integer,Integer}|R]) -> {integer,Integer,R};
-parse_term(['+',{float,Float}|R]) -> {float,Float,R};
-parse_term(['['|R]) -> {list,_Term,_C}=parse_list(['['|R]);
-parse_term(['{'|R]) -> {tuple,_Term,_C}=parse_tuple(['{'|R]);
-parse_term([Char|R]) -> {char,Char,R}.
-
-%%--- parse list ---
-parse_list(['[',']'|C]) ->
- {list, [], C};
-parse_list(['['|R]) ->
- {list,_List,_C}= list_args(R,[]).
-
-list_args(Toks,Ack) ->
- cont_list(parse_term(Toks),Ack).
-
-cont_list({_Tag, Term,[','|C]},Ack) ->
- list_args(C,[Term|Ack]);
-cont_list({_Tag, Term,[']'|C]},Ack) ->
- {list,lists:reverse([Term|Ack]),C}.
-
-%%--- parse tuple ---
-parse_tuple(['{','}'|C]) ->
- {tuple,{}, C};
-parse_tuple(['{'|R]) ->
- {tuple,_Tuple,_C}=tuple_args(R,[]).
-
-tuple_args(Toks,Ack) ->
- cont_tuple(parse_term(Toks),Ack).
-
-cont_tuple({_Tag, Term,[','|C]},Ack) ->
- tuple_args(C,[Term|Ack]);
-cont_tuple({_Tag, Term,['}'|C]},Ack) ->
- {tuple,list_to_tuple(lists:reverse([Term|Ack])),C}.
-
-%%--- parse sequence of terms ---
-parse_term_seq(Toks) ->
- p_term_seq(Toks,[]).
-
-p_term_seq([],Ack) ->
- {term_seq, lists:reverse(Ack)}; % never any continuation left
-p_term_seq(Toks,Ack) ->
- {_Type,Term,C} = parse_term(Toks),
- p_term_seq(C,[Term|Ack]).
-
-
-
-%% ----------------------------------------
-%% Simple Scanner
-
-scan(Bytes) ->
- {tokens, scan(Bytes,[])}.
-
-scan([],Ack) ->
- lists:reverse(Ack);
-scan([$ |R],Ack) -> % delete whitespace
- scan(R,Ack);
-scan([X|R],Ack) when is_integer(X),X>=$a,X=<$z ->
- scan_atom(R,[X],Ack);
-scan([X|R],Ack) when is_integer(X),X>=$A,X=<$Z ->
- scan_var(R,[X],Ack);
-scan([X|R],Ack) when is_integer(X),X>=$0,X=<$9 ->
- scan_number(R,[X],Ack);
-scan([$"|R],Ack) ->
- scan_string(R,[],Ack);
-scan([X|R],Ack) when is_integer(X) ->
- scan(R,[list_to_atom([X])|Ack]).
-
-scan_atom([X|R],Ack1,Ack2) when is_integer(X),X>=$a,X=<$z ->
- scan_atom(R,[X|Ack1],Ack2);
-scan_atom([X|R],Ack1,Ack2) when is_integer(X),X>=$A,X=<$Z ->
- scan_atom(R,[X|Ack1],Ack2);
-scan_atom([X|R],Ack1,Ack2) when is_integer(X),X>=$0,X=<$9 ->
- scan_atom(R,[X|Ack1],Ack2);
-scan_atom([$_|R],Ack1,Ack2) ->
- scan_atom(R,[$_|Ack1],Ack2);
-scan_atom(L,Ack1,Ack2) ->
- scan(L,[{atom,list_to_atom(lists:reverse(Ack1))}|Ack2]).
-
-scan_var([X|R],Ack1,Ack2) when is_integer(X),X>=$a,X=<$z ->
- scan_var(R,[X|Ack1],Ack2);
-scan_var([X|R],Ack1,Ack2) when is_integer(X),X>=$A,X=<$Z ->
- scan_var(R,[X|Ack1],Ack2);
-scan_var([X|R],Ack1,Ack2) when is_integer(X),X>=$0,X=<$9 ->
- scan_var(R,[X|Ack1],Ack2);
-scan_var([$_|R],Ack1,Ack2) ->
- scan_var(R,[$_|Ack1],Ack2);
-scan_var(L,Ack1,Ack2) ->
- scan(L,[{var,list_to_atom(lists:reverse(Ack1))}|Ack2]).
-
-scan_number([X|R],Ack1,Ack2) when is_integer(X),X>=$0,X=<$9 ->
- scan_number(R,[X|Ack1],Ack2);
-scan_number([$.|R],Ack1,Ack2) ->
- scan_float(R,[$.|Ack1],Ack2);
-scan_number(L,Ack1,Ack2) ->
- scan(L,[{integer,list_to_integer(lists:reverse(Ack1))}|Ack2]).
-
-scan_float([X|R],Ack1,Ack2) when is_integer(X),X>=$0,X=<$9 ->
- scan_float(R,[X|Ack1],Ack2);
-scan_float(L,Ack1,Ack2) ->
- Float = list_to_float(lists:reverse(Ack1)),
- Int = trunc(Float),
- if
- Int==Float ->
- scan(L,[{integer,Int}|Ack2]);
- true ->
- scan(L,[{float,Float}|Ack2])
- end.
-
-
-scan_string([$"|R],Ack1,Ack2) ->
- scan(R,[{string,lists:reverse(Ack1)}|Ack2]);
-scan_string([X|R],Ack1,Ack2) when is_integer(X) ->
- scan_string(R,[X|Ack1],Ack2);
-scan_string([],_Ack1,_Ack2) ->
- throw({error,"unterminated string."}).
-
-
-
-%% ---------- Checking Return values -----------
-%% Used by read to return a proper type or fail.
-
-ret_int(Str) ->
- case gstk:call(Str) of
- {result, Result} ->
- {_,Value} = str_to_term(Result),
- Value;
- Bad_result -> Bad_result
- end.
-
-ret_atom(Str) ->
- case gstk:call(Str) of
- {result, Result} ->
- {_,Value} = str_to_term(Result),
- Value;
- Bad_result -> Bad_result
- end.
-
-ret_str(Str) ->
- case gstk:call(Str) of
- {result, Val} -> Val;
- Bad_result -> Bad_result
- end.
-
-ret_tuple(Str) ->
- case gstk:call(Str) of
- {result,S} ->
- {tokens,Toks} = scan(S),
- {term_seq,Seq} = parse_term_seq(Toks),
- list_to_tuple(Seq);
- Bad_result -> Bad_result
- end.
-
-%%----------------------------------------------------------------------
-%% Returns: Coords or error.
-%%----------------------------------------------------------------------
-ret_pack(Key, TkW) ->
- Str = ret_list(["pack info ", TkW]),
- pick_out(Str, Key).
-
-ret_place(Key, TkW) ->
- Str = ret_list(["place info ", TkW]),
- pick_out(Str, Key).
-
-pick_out([Key, Value | _Rest], Key) -> Value;
-pick_out([Key, {} | _Rest], Key) -> 0;
-pick_out(['-' | Rest], Key) -> pick_out(Rest, Key);
-pick_out([_, _ | Rest], Key) -> pick_out(Rest, Key);
-pick_out(Other, _Key) -> Other.
-
-
-ret_x(Str) ->
- case ret_geometry(Str) of
- {_W,_H,X,_Y} -> X;
- Other -> Other
- end.
-
-ret_y(Str) ->
- case ret_geometry(Str) of
- {_W,_H,_X,Y} -> Y;
- Other -> Other
- end.
-
-ret_width(Str) ->
- case ret_geometry(Str) of
- {W,_H,_X,_Y} -> W;
- Other -> Other
- end.
-
-ret_height(Str) ->
- case ret_geometry(Str) of
- {_W,H,_X,_Y} -> H;
- Other -> Other
- end.
-
-
-
-ret_geometry(Str) ->
- case ret_tuple(Str) of
- {W,H,X,Y} when is_atom(H) ->
- [_|Height]=atom_to_list(H),
- {W,list_to_integer(Height),X,Y};
- Other -> Other
- end.
-
-ret_list(Str) ->
- case gstk:call(Str) of
- {result,S} ->
- {tokens,Toks} = scan(S),
- {term_seq,Seq} = parse_term_seq(Toks),
- Seq;
- Bad_result -> Bad_result
- end.
-
-ret_str_list(Str) ->
- case gstk:call(Str) of
- {result,S} ->
- mk_quotes0(S,[]);
- Bad_result -> Bad_result
- end.
-
-
-ret_label(Str) ->
- case ret_str_list(Str) of
- [[], [$@|Img]] -> {image, Img};
- [Text, []] -> {text, Text};
- Bad_Result -> Bad_Result
- end.
-
-
-
-ret_mapped(Str) ->
- case ret_int(Str) of
- 1 -> true;
- 0 -> false;
- Bad_Result -> Bad_Result
- end.
-
-
-ret_iconified(Str) ->
- case ret_atom(Str) of
- iconic -> true;
- normal -> false;
- Bad_Result -> Bad_Result
- end.
-
-
-ret_focus(W, Str) ->
- case gstk:call(Str) of
- {result, W} -> true;
- _ -> false
- end.
-
-
-ret_file(Str) ->
- case gstk:call(Str) of
- {result, [$@|File]} -> File;
- {result, []} -> [];
- Bad_result -> Bad_result
- end.
-
-
-ret_bool(Str) ->
- case ret_int(Str) of
- 1 -> true;
- 0 -> false;
- Bad_Result -> Bad_Result
- end.
-
-ret_enable(Str) ->
- case ret_atom(Str) of
- normal -> true;
- active -> true;
- disabled -> false;
- Bad_Result -> Bad_Result
- end.
-
-
-
-ret_color(Str) ->
- case gstk:call(Str) of
- {result,[$#,R1,G1,B1]} ->
- {hex2dec([R1,$0]),hex2dec([G1,$0]),hex2dec([B1,$0])};
- {result,[$#,R1,R2,G1,G2,B1,B2]} ->
- {hex2dec([R1,R2]),hex2dec([G1,G2]),hex2dec([B1,B2])};
- {result,[$#,R1,R2,_R3,G1,G2,_G3,B1,B2,_B3]} ->
- {hex2dec([R1,R2]),hex2dec([G1,G2]),hex2dec([B1,B2])};
- {result,[$#,R1,R2,_R3,_R4,G1,G2,_G3,_G4,B1,B2,_B3,_B4]} ->
- {hex2dec([R1,R2]),hex2dec([G1,G2]),hex2dec([B1,B2])};
- {result,[Char|Word]} when Char>=$A, Char=<$Z ->
- list_to_atom([Char+32|Word]);
- {result,[Char|Word]} when Char>=$a, Char=<$z ->
- list_to_atom([Char|Word]);
- {result,Color} ->
- gs:error("error in tcl2erl:ret_color got ~w.~n",[Color]);
- Bad_result -> Bad_result
- end.
-
-
-ret_stipple(Str) ->
- case gstk:call(Str) of
- {result, _Any} -> true;
- _Other -> false
- end.
-
-
-%% ------------------------------------------------------------
-%% Hexadecimal to Decimal converter
-%%
-
-hex2dec(Hex) -> hex2dec(Hex,0).
-
-hex2dec([H|T],N) when H>=$0,H=<$9 ->
- hex2dec(T,(N bsl 4) bor (H-$0));
-hex2dec([H|T],N) when H>=$a,H=<$f ->
- hex2dec(T,(N bsl 4) bor (H-$a+10));
-hex2dec([H|T],N) when H>=$A,H=<$F ->
- hex2dec(T,(N bsl 4) bor (H-$A+10));
-hex2dec([],N) -> N.
-
-
-mk_quotes0([${|T],Res) -> mk_quotes2(T,"",Res);
-mk_quotes0([$ |T],Res) -> mk_quotes0(T,Res);
-mk_quotes0([$\\,X |T],Res) -> mk_quotes1(T,[X],Res);
-mk_quotes0([X|T],Res) -> mk_quotes1(T,[X],Res);
-mk_quotes0([],Res) -> lists:reverse(Res).
-
-mk_quotes1([$}|T],Ack,Res) -> mk_quotes0(T,[lists:reverse(Ack)|Res]);
-mk_quotes1([$\\,X |T],Ack,Res) -> mk_quotes1(T,[X|Ack],Res);
-mk_quotes1([$ |T],Ack,Res) -> mk_quotes0(T,[lists:reverse(Ack)|Res]);
-mk_quotes1([X|T],Ack,Res) -> mk_quotes1(T,[X|Ack],Res);
-mk_quotes1([],Ack,Res) -> lists:reverse([lists:reverse(Ack)|Res]).
-
-%% grouped using {bla bla} syntax
-mk_quotes2([$}|T],Ack,Res) -> mk_quotes0(T,[lists:reverse(Ack)|Res]);
-mk_quotes2([$\\,X |T],Ack,Res) -> mk_quotes2(T,[X|Ack],Res);
-mk_quotes2([X|T],Ack,Res) -> mk_quotes2(T,[X|Ack],Res);
-mk_quotes2([],Ack,Res) -> lists:reverse([lists:reverse(Ack)|Res]).
-
-
diff --git a/lib/gs/src/tool_file_dialog.erl b/lib/gs/src/tool_file_dialog.erl
deleted file mode 100644
index a6d6f55f1f..0000000000
--- a/lib/gs/src/tool_file_dialog.erl
+++ /dev/null
@@ -1,456 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
--module(tool_file_dialog).
--compile([{nowarn_deprecated_function,{gs,button,3}},
- {nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,entry,3}},
- {nowarn_deprecated_function,{gs,frame,3}},
- {nowarn_deprecated_function,{gs,label,3}},
- {nowarn_deprecated_function,{gs,listbox,3}},
- {nowarn_deprecated_function,{gs,read,2}},
- {nowarn_deprecated_function,{gs,start,0}},
- {nowarn_deprecated_function,{gs,window,3}}]).
-
--export([start/1]).
-
--record(opts, {type, % open | save | multiselect
- dir, % string() Current directory
- file, % string() Filename, no path
- extensions, % [string()] Filtered file extensions
- hidden}). % [{Dir, [File]}] Hidden files per dir.
-
--define(WIDTH, 250).
--define(HEIGHT, 400).
--define(BTNW, 65).
--define(BTNH, 30).
-
-%% start(Opts) -> {ok, AbsFile, Dir} | {error,cancel} | pid()
-%% Opts = [Opt]
-%% Opt = {type, open|save|multiselect}
-%% | {extensions, [string()]} % For example ".erl"
-%% | {dir, string()} % Absolute path
-%% ! {file, string() % Filename (no path)
-%% AbsFile = string()
-%% Dir = string()
-%% An open/save dialog returns {ok, AbsFile, Dir} or {error,cancel}
-%% (the latter, ridiculous, return value is kept for backwards
-%% compatibility reasons only).
-%%
-%% A multiselect box returns a pid and delivers messages on the form:
-%% {select, AbsFile} | {close, Dir}
-%%
-%% Dir is the current directory displayed and can be used to start a
-%% a new filedialog with the same directory.
-
-start(Opts0) ->
- Opts = parse_opts(Opts0),
- Self = self(),
- case Opts#opts.type of
- multiselect ->
- spawn_link(fun() -> init(Self, Opts) end);
- _Type -> % open | save
- spawn_link(fun() -> init(Self, Opts) end),
- receive
- {fd_result, Res} ->
- Res
- end
- end.
-
-parse_opts(Opts) ->
- {ok, CWD} = file:get_cwd(),
- DefOpts = #opts{type=open, dir=CWD, file="NoName",
- extensions=[], hidden=[]},
- parse_opts(Opts, DefOpts).
-
-parse_opts([{type, Type}|Opts], DefOpts) ->
- if
- Type==open; Type==save; Type==multiselect ->
- parse_opts(Opts, DefOpts#opts{type=Type});
- true ->
- erlang:error(badarg, [{type,Type}])
- end;
-parse_opts([{extensions, Exts}|Opts], DefOpts) ->
- case lists:all(fun(Ext) -> is_list(Ext) end, Exts) of
- true ->
- parse_opts(Opts, DefOpts#opts{extensions=Exts});
- false ->
- erlang:error(badarg, [{extension, Exts}])
- end;
-parse_opts([{dir, Dir}|Opts], DefOpts) ->
- case filelib:is_dir(Dir) of
- true ->
- case filename:pathtype(Dir) of
- absolute ->
- parse_opts(Opts, DefOpts#opts{dir=Dir});
- _ ->
- parse_opts(Opts,
- DefOpts#opts{dir=filename:absname(Dir)})
- end;
- false ->
- erlang:error(badarg, [{dir, Dir}])
- end;
-parse_opts([{file, Name}|Opts], DefOpts) ->
- if
- is_list(Name) ->
- parse_opts(Opts, DefOpts#opts{file=Name});
- true ->
- erlang:error(badarg, [{file, Name}])
- end;
-parse_opts([_|Opts], DefOpts) -> % ignore unknown options
- parse_opts(Opts, DefOpts);
-parse_opts([], DefOpts) ->
- DefOpts.
-
-%%--Loop----------------------------------------------------------------
-
-init(From, Opts) ->
- make_window(Opts),
- loop(From, {?WIDTH,?HEIGHT}, Opts).
-
-loop(From, {OldW,OldH}=Size, Opts) ->
- receive
-
- %% Window is closed
- {gs, win, destroy, _, _} when Opts#opts.type==multiselect ->
- From ! {close, Opts#opts.dir};
- {gs, win, destroy, _, _} ->
- From ! {fd_result, {error, cancel}};
-
- %% Window is moved or resized
- {gs, win, configure, _, [OldW,OldH|_]} ->
- loop(From, Size, Opts);
- {gs, win, configure, _, [W,H|_]} ->
- gs:config(resizer, [{width,W},{height,H}]),
- loop(From, {W,H}, Opts);
-
- %% Up button is selected
- {gs, up, click, _, _} ->
- Opts2 = set_dir(up, Opts),
- loop(From, Size, Opts2);
-
- %% A listbox item (dir or file) is selected
- {gs, lb, click, _, [_I,Item|_]} ->
- Entry = case lists:last(Item) of
- $/ -> "";
- _Ch -> Item
- end,
- gs:config(entry, {text,Entry}),
- loop(From, Size, Opts);
-
- %% A listbox item (dir or file) is double-clicked
- {gs, lb, doubleclick, _, [_I,Item|_]} ->
- case lists:last(Item) of
- $/ -> do_select({dir, Item}, From, Size, Opts);
- _Ch -> do_select({file, Item}, From, Size, Opts)
- end;
-
- %% Open/Save/Select button is selected
- {gs, select, click, _, _} ->
- case gs:read(entry, text) of
- "" ->
- case gs:read(lb, selection) of
- [] ->
- gs:config(select, beep),
- loop(From, Size, Opts);
- [I] ->
- Item = gs:read(lb, {get,I}),
- case lists:last(Item) of
- $/ ->
- do_select({dir, Item},
- From, Size, Opts);
- _Ch ->
- do_select({file, Item},
- From, Size, Opts)
- end
- end;
- Item -> do_select(Item, From, Size, Opts)
- end;
-
- %% 'Return' is pressed
- {gs, entry, keypress, _, ['Return'|_]} ->
- case gs:read(entry, text) of
- "" ->
- gs:config(select, beep),
- loop(From, Size, Opts);
- Item ->
- do_select(Item, From, Size, Opts)
- end;
-
- %% All button is selected (multiselect dialog)
- {gs, all, click, _, _} ->
- {_Dirs, Files} = select_all(),
- lists:foreach(fun(File) ->
- AbsFile = filename:join(Opts#opts.dir,
- File),
- From ! {select, AbsFile}
- end,
- Files),
- From ! {close, Opts#opts.dir};
-
- %% Cancel button is selected (open/save dialog)
- {gs, cancel, click, _, _} ->
- From ! {fd_result, {error, cancel}};
-
- %% Close button is selected (multiselect dialog)
- {gs, close, click, _, _} ->
- From ! {close, Opts#opts.dir};
-
- Msg ->
- io:format("GOT: ~p~n", [Msg]),
- loop(From, Size, Opts)
- end.
-
-do_select({dir, Name}, From, Size, Opts) ->
- do_select_dir(filename:join(Opts#opts.dir, Name), From, Size, Opts);
-do_select({file, Name}, From, Size, Opts) ->
- do_select_file(filename:join(Opts#opts.dir, Name), From, Size,Opts);
-do_select(Entry, From, Size, Opts) ->
- AbsName = case filename:pathtype(Entry) of
- absolute -> Entry;
- _ -> filename:join(Opts#opts.dir, Entry)
- end,
- case filelib:is_dir(AbsName) of
- true -> do_select_dir(AbsName, From, Size, Opts);
- false -> do_select_file(AbsName, From, Size, Opts)
- end.
-
-do_select_dir(Dir, From, Size, Opts) ->
- Opts2 = set_dir(Dir, Opts),
- loop(From, Size, Opts2).
-
-do_select_file(File, From, Size, Opts) ->
- case filelib:is_file(File) of
- true when Opts#opts.type==multiselect ->
- From ! {select, File},
- Opts2 = update(File, Opts),
- loop(From, Size, Opts2);
- true -> % open | save
- From ! {fd_result, {ok, File, Opts#opts.dir}};
- false when Opts#opts.type==save ->
- case filelib:is_dir(filename:dirname(File)) of
- true ->
- From ! {fd_result, {ok, File, Opts#opts.dir}};
- false ->
- gs:config(select, beep),
- loop(From, Size, Opts)
- end;
- false -> % multiselect | open
- gs:config(select, beep),
- loop(From, Size, Opts)
- end.
-
-%%--Common GUI functions------------------------------------------------
-
--define(UPW, 35).
--define(UPH, 30).
--define(ENTRYH, 30).
-
-make_window(Opts) ->
- GS = gs:start(),
-
- Title = case Opts#opts.type of
- open -> "Open File";
- save -> "Save File";
- multiselect -> "Select Files"
- end,
-
- Font = case gs:read(GS, {choose_font,{screen,[],12}}) of
- Font0 when element(1, Font0)==screen ->
- Font0;
- _ ->
- gs:read(GS, {choose_font,{courier,[],12}})
- end,
-
- gs:window(win, GS, [{title,Title},
- {width,?WIDTH}, {height,?HEIGHT},
- {configure,true}]),
-
- Marg = {fixed,5},
- Parent = gs:frame(resizer, win, [{packer_x,[Marg,{stretch,1},Marg]},
- {packer_y,[Marg,
- {stretch,10},
- {stretch,1,2*?BTNH},
- Marg]}]),
- gs:frame(btnframe, resizer, [{packer_x, [{stretch,1},
- {fixed,?BTNW},
- {stretch,1},
- {fixed,?BTNW},
- {stretch,1},
- {fixed,?BTNW},
- {stretch,1}]},
- {packer_y, [{stretch,1},
- {fixed,?BTNH},
- {stretch,1}]},
- {pack_x,2}, {pack_y,3}]),
-
- gs:frame(frame, Parent, [{packer_x,[{fixed,?UPW},{stretch,1}]},
- {packer_y,[{fixed,?UPH},{fixed,?ENTRYH},
- {stretch,1}]},
- {pack_x,2}, {pack_y,2}]),
-
- Fup = filename:join([code:priv_dir(gs),"bitmap","fup.bm"]),
- gs:button(up, frame, [{label,{image, Fup}},
- {pack_x,1}, {pack_y,1}]),
- gs:label(infodir, frame, [{label,{text," Dir:"}}, {font,Font},
- {pack_x,2}, {pack_y,1}, {align,w}]),
- gs:label(l1, frame, [{label,{text,"File:"}}, {font,Font}, {align,e},
- {pack_x,1}, {pack_y,2}]),
-
- gs:entry(entry, frame, [{font,Font}, {keypress,true},
- {pack_x,2}, {pack_y,2}]),
- gs:listbox(lb, frame, [{font,Font}, {pack_x,{1,2}}, {pack_y,3},
- {selectmode,single},
- {vscroll,right},
- {click,true}, {doubleclick,true}]),
-
- set_dir(Opts#opts.dir, Opts),
-
- case Opts#opts.type of
- multiselect ->
- gs:button(select, btnframe, [{label,{text,"Select"}},
- {font,Font},
- {pack_x,2}, {pack_y,2}]),
- gs:button(all, btnframe, [{label,{text,"All"}}, {font,Font},
- {pack_x,4}, {pack_y,2}]),
- gs:button(close,btnframe,[{label,{text,"Done"}},
- {font,Font},
- {pack_x,6}, {pack_y,2}]);
- Type ->
- Text = case Type of
- open -> "Open";
- save -> "Save"
- end,
- gs:button(select, btnframe, [{label,{text,Text}},
- {font,Font},
- {pack_x,2}, {pack_y,2}]),
- gs:button(cancel, btnframe, [{label,{text,"Cancel"}},
- {font,Font},
- {pack_x,6}, {pack_y,2}])
- end,
-
- gs:config(resizer, [{width,?WIDTH}, {height,?HEIGHT}]),
- gs:config(win, {map,true}).
-
-%% update(AbsFile, Opts) -> Opts'
-update(AbsFile, Opts) ->
- Dir = filename:dirname(AbsFile),
- File = filename:basename(AbsFile),
-
- %% Hide the file
- Hidden0 = Opts#opts.hidden,
- Hidden = case lists:keysearch(Dir, 1, Hidden0) of
- {value, {_Dir, Files}} ->
- lists:keyreplace(Dir, 1, Hidden0,
- {Dir, [File|Files]});
- false ->
- [{Dir, [File]} | Hidden0]
- end,
- Opts2 = Opts#opts{hidden=Hidden},
- set_dir(Dir, Opts2).
-
-%% select_all() -> {Dirs, Files}
-select_all() ->
- Is = lists:seq(0, gs:read(lb, size)-1),
- sort_selected(Is, [], []).
-
-sort_selected([I|Is], Dirs, Files) ->
- FileOrDir = gs:read(lb, {get,I}),
- case lists:last(FileOrDir) of
- $/ ->
- sort_selected(Is, [drop_last(FileOrDir)|Dirs], Files);
- _Ch ->
- sort_selected(Is, Dirs, [FileOrDir|Files])
- end;
-sort_selected([], Dirs, Files) ->
- {Dirs, Files}.
-
-drop_last(Str) ->
- lists:sublist(Str, length(Str)-1).
-
-%% set_dir(Dir0, Opts) -> Opts'
-%% Dir0 = up | string() absolute path only
-set_dir(Dir0, Opts) ->
- Dir = if
- Dir0==up -> filename:dirname(Opts#opts.dir);
- true ->Dir0
- end,
-
- case filelib:is_dir(Dir) of
- true ->
- gs:config(frame, {cursor,busy}),
- gs:config(lb, clear),
- Items = get_files(Dir, Opts#opts.hidden,
- Opts#opts.extensions),
- case Opts#opts.type of
- save ->
- gs:config(entry, {text,Opts#opts.file});
- _ ->
- gs:config(entry, {text,""})
- end,
- gs:config(lb, [{items,Items}]),
- gs:config(lb, {selection, clear}),
- gs:config(infodir, {label,{text,["Dir: "|Dir]}}),
- gs:config(frame, {cursor,parent}),
- Opts#opts{dir=Dir};
- false ->
- gs:config(select, beep),
- Opts
- end.
-
-get_files(Dir, Hidden, Exts) ->
- {ok, Items0} = file:list_dir(Dir),
-
- Items = case lists:keysearch(Dir, 1, Hidden) of
- {value, {_Dir, HiddenHere}} ->
- lists:filter(fun(Item0) ->
- not lists:member(Item0,
- HiddenHere)
- end,
- Items0);
- false ->
- Items0
- end,
-
- get_files(Dir, Items, [], [], Exts).
-
-get_files(Dir, [Item0|Items], Dirs, Files, Exts) ->
- Item = filename:join(Dir, Item0),
- case filelib:is_dir(Item) of
- true ->
- get_files(Dir, Items, [Item0++"/"|Dirs], Files, Exts);
- false ->
- case filelib:is_regular(Item) of
- true when Exts==[] ->
- get_files(Dir, Items, Dirs, [Item0|Files], Exts);
- true ->
- case lists:member(filename:extension(Item), Exts) of
- true ->
- get_files(Dir,Items,Dirs,[Item0|Files],Exts);
- false ->
- get_files(Dir, Items, Dirs, Files, Exts)
- end;
- false ->
- get_files(Dir, Items, Dirs, Files, Exts)
- end
- end;
-get_files(_Dir, [], Dirs, Files, _Exts) ->
- lists:sort(Dirs) ++ lists:sort(Files).
diff --git a/lib/gs/src/tool_utils.erl b/lib/gs/src/tool_utils.erl
deleted file mode 100644
index 841aa926da..0000000000
--- a/lib/gs/src/tool_utils.erl
+++ /dev/null
@@ -1,438 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
--module(tool_utils).
--compile([{nowarn_deprecated_function,{gs,config,2}},
- {nowarn_deprecated_function,{gs,create,3}},
- {nowarn_deprecated_function,{gs,destroy,1}},
- {nowarn_deprecated_function,{gs,read,2}}]).
-
--include_lib("kernel/include/file.hrl").
-
-%%%---------------------------------------------------------------------
-%%% Auxiliary functions to be used by the tools (internal module)
-%%%---------------------------------------------------------------------
-
-%% External exports
--export([open_help/2]).
--export([file_dialog/1]).
--export([notify/2, confirm/2, confirm_yesno/2, request/2]).
-
--record(state, {type, % notify | confirm[_yesno] | request
- win, % gsobj(), window
- entry, % gsobj(), entry
- in_focus, % 0 | 1 | undefined Entry is in focus
- is_cursor, % bool() | undefined Cursor is over Entry
- buttons, % [gsobj()], buttons
- highlighted % int() highlighted buttone
- }).
-
-
-%%----------------------------------------------------------------------
-%% open_help(Parent, File)
-%% Parent = gsobj() (GS root object or parent window)
-%% File = string() | nofile
-%% View the help file File, which can be an URL, an HTML file or a text
-%% file.
-%% This function is OS dependant.
-%% Unix: Assumes Netscape is up & running, and use Netscape remote
-%% commands to display the file.
-%% NT: If File is a file, use the NT command 'start' which will open the
-%% default tool for viewing the file.
-%% If File is an URL, try to view it using Netscape.exe which
-%% requires that the path Netscape.exe must be in TBD.
-%% (TEMPORARY solution..., can be done better)
-%%----------------------------------------------------------------------
-open_help(Parent, nofile) ->
- notify(Parent, "Sorry, no help information exists");
-open_help(Parent, File) ->
- case application:get_env(kernel, browser_cmd) of
- undefined ->
- open_help_default(Parent, File);
- {ok, Cmd} when is_list(Cmd) ->
- spawn(os, cmd, [Cmd ++ " " ++ File]);
- {ok, {M, F, A}} ->
- apply(M, F, [File|A]);
- _Other ->
- Str = ["Bad Kernel configuration parameter browser_cmd",
- "Do not know how to display help file"],
- notify(Parent, Str)
- end.
-
-open_help_default(Parent, File) ->
- Cmd = case file_type(File) of
-
- %% Local file
- local ->
- case os:type() of
- {unix,Type} ->
- case Type of
- darwin -> "open " ++ File;
- _Else -> "netscape -remote \"openURL(file:" ++ File ++ ")\""
- end;
- {win32,_AnyType} ->
- "start " ++ filename:nativename(File);
-
- _Other ->
- unknown
- end;
-
- %% URL
- remote ->
- case os:type() of
- {unix,Type} ->
- case Type of
- darwin -> "open " ++ File;
- _Else -> "netscape -remote \"openURL(file:" ++ File ++ ")\""
- end;
- {win32,_AnyType} ->
- "netscape.exe -h " ++
- re:replace(File,"\\\\","/",[global,{return,list}]);
- _Other ->
- unknown
- end;
-
- Error -> % {error,Reason}
- Error
- end,
-
- if
- is_list(Cmd) ->
- spawn(os, cmd, [Cmd]);
- Cmd==unknown ->
- Str = ["Sorry, do not know how to",
- "display HTML files at this platform"],
- notify(Parent, Str);
- true ->
- {error, Reason} = Cmd,
- Str = file:format_error(Reason),
- notify(Parent, [File,Str])
- end.
-
-%% file_type(File) -> local | remote | {error,Reason}
-%% File = string()
-%% Reason - see file(3)
-%% Returns local if File is an existing, readable file
-%% Returns remote if File is a remote URL (ie begins with 'http:')
-file_type(File) ->
- case File of
- "http://"++_URL ->
- remote;
- _ ->
- %% HTML files can have a tag (<name>.html#tag), this must be
- %% removed when checking if the file exists
- File2 = case filename:extension(File) of
- ".html#"++_Index ->
- filename:rootname(File)++".html";
- _ ->
- File
- end,
-
- case file:read_file_info(File2) of
- {ok, FileInfo} when FileInfo#file_info.type==regular,
- FileInfo#file_info.access/=none ->
- local;
- {ok, FileInfo} when FileInfo#file_info.type/=regular ->
- {error,einval};
- {ok, FileInfo} when FileInfo#file_info.access==none ->
- {error,eacces};
- Error ->
- Error
- end
- end.
-
-
-%%----------------------------------------------------------------------
-%% file_dialog(Options) -> tbd
-%%----------------------------------------------------------------------
-file_dialog(Options) ->
- tool_file_dialog:start(Options).
-
-
-%%----------------------------------------------------------------------
-%% notify(Parent, Strings) -> ok
-%% confirm(Parent, Strings) -> ok | cancel
-%% confirm_yesno(Parent, Strings) -> yes | no | cancel
-%% request(Parent, Strings) -> {ok,string()} | cancel
-%% Parent = gsobj() (GS root object or parent window)
-%% Strings = string() | [string()]
-%% Opens a window with the specified message (Strings) and locks the GUI
-%% until the user confirms the message.
-%% If the Parent argument is the parent window, the help window will be
-%% centered above it, otherwise it can end up anywhere on the screen.
-%% A 'notify' window contains an 'Ok' button.
-%% A 'confirm' window contains an 'Ok' and a 'Cancel' button.
-%% A 'confirm_yesno' window contains a 'Yes', a 'No', and a 'Cancel'
-%% button.
-%% A 'request' window contains an entry, an 'Ok' and a 'Cancel' button.
-%%----------------------------------------------------------------------
--define(Wlbl, 130).
--define(Hlbl, 30).
--define(Hent, 30).
--define(Wbtn, 50).
--define(Hbtn, 30).
--define(PAD, 10).
-
-notify(Parent, Strings) ->
- help_win(notify, Parent, Strings).
-confirm(Parent, Strings) ->
- help_win(confirm, Parent, Strings).
-confirm_yesno(Parent, Strings) ->
- help_win(confirm_yesno, Parent, Strings).
-request(Parent, Strings) ->
- help_win(request, Parent, Strings).
-
-help_win(Type, Parent, Strings) ->
- GenOpts = [{keypress,true}],
- GenOpts2 = [{font,{screen,12}} | GenOpts],
- Buttons = buttons(Type),
- Nbtn = length(Buttons),
-
- %% Create the window and its contents
- Win = gs:create(window, Parent, [{title,title(Type)} | GenOpts]),
- Top = gs:create(frame, Win, GenOpts),
- Lbl = gs:create(label, Top, [{align,c}, {justify,center}|GenOpts2]),
- Mid = if
- Type==request -> gs:create(frame, Win, GenOpts);
- true -> ignore
- end,
- Ent = if
- Type==request ->
- Events = [{setfocus,true},
- {focus,true},{enter,true},{leave,true}],
- gs:create(entry, Mid, GenOpts2++Events);
- true -> ignore
- end,
- Bot = gs:create(frame, Win, GenOpts),
-
- %% Find out minimum size required for label, entry and buttons
- Font = gs:read(Parent, {choose_font, {screen,12}}),
- Text = insert_newlines(Strings),
- {Wlbl0,Hlbl0} = gs:read(Lbl, {font_wh,{Font,Text}}),
- {_Went0,Hent0} = gs:read(Lbl, {font_wh,{Font,"Entry"}}),
- {Wbtn0,Hbtn0} = gs:read(Lbl, {font_wh,{Font,"Cancel"}}),
-
- %% Compute size of the objects and adjust the graphics accordingly
- Wbtn = erlang:max(Wbtn0+10, ?Wbtn),
- Hbtn = erlang:max(Hbtn0+10, ?Hbtn),
- Hent = erlang:max(Hent0+10, ?Hent),
- Wlbl = erlang:max(Wlbl0, erlang:max(Nbtn*Wbtn+(Nbtn-1)*?PAD, ?Wlbl)),
- Hlbl = erlang:max(Hlbl0, ?Hlbl),
-
- Wwin = ?PAD+Wlbl+?PAD,
-
- Htop = ?PAD+Hlbl,
- Hmid = if Type==request -> ?PAD+Hent; true -> 0 end,
- Hbot = ?PAD+Hbtn+?PAD,
- Hwin = Htop+Hmid+Hbot,
-
- case catch get_coords(Parent, Wwin, Hwin) of
- {Xw, Yw} when is_integer(Xw), is_integer(Yw) ->
- gs:config(Win, [{x,Xw}, {y,Yw}]);
- _ ->
- ignore
- end,
-
- gs:config(Win, [ {width,Wwin},{height,Hwin}]),
-
- gs:config(Top, [{x,0}, {y,0}, {width,Wwin},{height,Htop}]),
- gs:config(Lbl, [{x,?PAD},{y,?PAD}, {width,Wlbl},{height,Hlbl}]),
-
- gs:config(Mid, [{x,0}, {y,Htop}, {width,Wwin},{height,Hmid}]),
- gs:config(Ent, [{x,?PAD},{y,?PAD}, {width,Wlbl},{height,Hent}]),
-
- gs:config(Bot, [{x,0}, {y,Htop+Hmid},{width,Wwin},{height,Hbot}]),
-
- %% Insert the label text
- gs:config(Lbl, {label,{text,Text}}),
-
- %% Add the buttons
- Xbtns = xbuttons(Buttons, Wbtn, Wwin, Wlbl),
- BtnObjs =
- lists:map(fun({Btext,BX}) ->
- gs:create(button, Bot, [{x,BX-1}, {y,?PAD-1},
- {width,Wbtn+2},
- {height,Hbtn+2},
- {label,{text,Btext}},
- {data,data(Btext)}
- | GenOpts2])
- end,
- Xbtns),
- Highlighted = highlight(undef, 1, BtnObjs),
-
- gs:config(Win, [{map,true}]),
-
- State = if
- Type==request ->
- #state{in_focus=1, is_cursor=false};
- true ->
- #state{}
- end,
- event_loop(State#state{type=Type, win=Win, entry=Ent,
- buttons=BtnObjs, highlighted=Highlighted}).
-
-title(notify) -> "Notification";
-title(confirm) -> "Confirmation";
-title(confirm_yesno) -> "Confirmation";
-title(request) -> "Request".
-
-buttons(notify) -> ["Ok"];
-buttons(confirm) -> ["Ok", "Cancel"];
-buttons(confirm_yesno) -> ["Yes", "No", "Cancel"];
-buttons(request) -> ["Ok", "Cancel"].
-
-data("Ok") -> {helpwin,ok};
-data("Yes") -> {helpwin,yes};
-data("No") -> {helpwin,no};
-data("Cancel") -> {helpwin,cancel}.
-
-get_coords(Parent, W, H) ->
- case gs:read(Parent, x) of
- X when is_integer(X) ->
- case gs:read(Parent, y) of
- Y when is_integer(Y) ->
- case gs:read(Parent, width) of
- W0 when is_integer(W0) ->
- case gs:read(Parent, height) of
- H0 when is_integer(H0) ->
- {round((X+W0/2)-W/2),
- round((Y+H0/2)-H/2)};
- _ -> error
- end;
- _ -> error
- end;
- _ -> error
- end;
- _ -> error
- end.
-
-xbuttons([B], Wbtn, Wwin, _Wlbl) ->
- [{B, round(Wwin/2-Wbtn/2)}];
-xbuttons([B1,B2], Wbtn, Wwin, Wlbl) ->
- Margin = (Wwin-Wlbl)/2,
- [{B1,round(Margin)}, {B2,round(Wwin-Margin-Wbtn)}];
-xbuttons([B1,B2,B3], Wbtn, Wwin, Wlbl) ->
- Margin = (Wwin-Wlbl)/2,
- [{B1,round(Margin)},
- {B2,round(Wwin/2-Wbtn/2)},
- {B3,round(Wwin-Margin-Wbtn)}].
-
-highlight(Prev, New, BtnObjs) when New>0, New=<length(BtnObjs) ->
- if
- Prev==undef -> ignore;
- true ->
- gs:config(lists:nth(Prev, BtnObjs), [{highlightbw,0}])
- end,
- gs:config(lists:nth(New, BtnObjs), [{highlightbw,1},
- {highlightbg,black}]),
- New;
-highlight(Prev, _New, _BtnObjs) -> % New is outside allowed range
- Prev.
-
-event_loop(State) ->
- receive
- GsEvent when element(1, GsEvent)==gs ->
- case handle_event(GsEvent, State) of
- {continue, NewState} ->
- event_loop(NewState);
-
- {return, Result} ->
- gs:destroy(State#state.win),
- Result
- end
- end.
-
-handle_event({gs,_,click,{helpwin,Result},_}, State) ->
- if
- State#state.type/=request; Result==cancel ->
- {return, Result};
-
- State#state.type==request, Result==ok ->
- case gs:read(State#state.entry, text) of
- "" ->
- {continue, State};
- Info ->
- {return, {ok, Info}}
- end
- end;
-
-%% When the entry (Type==request) is in focus and the mouse pointer is
-%% over it, don't let 'Left'|'Right' keypresses affect which button is
-%% selected
-handle_event({gs,Ent,enter,_,_}, #state{entry=Ent}=State) ->
- {continue, State#state{is_cursor=true}};
-handle_event({gs,Ent,leave,_,_}, #state{entry=Ent}=State) ->
- {continue, State#state{is_cursor=false}};
-handle_event({gs,Ent,focus,_,[Int|_]}, #state{entry=Ent}=State) ->
- {continue, State#state{in_focus=Int}};
-
-handle_event({gs,Win,keypress,_,['Right'|_]}, #state{win=Win}=State) ->
- if
- State#state.type==request,
- State#state.in_focus==1, State#state.is_cursor==true ->
- {continue, State};
- true ->
- Prev = State#state.highlighted,
- New = highlight(Prev, Prev+1, State#state.buttons),
- {continue, State#state{highlighted=New}}
- end;
-handle_event({gs,Win,keypress,_,['Left'|_]}, #state{win=Win}=State) ->
- if
- State#state.type==request,
- State#state.in_focus==1, State#state.is_cursor==true ->
- {continue, State};
- true ->
- Prev = State#state.highlighted,
- New = highlight(Prev, Prev-1, State#state.buttons),
- {continue, State#state{highlighted=New}}
- end;
-
-handle_event({gs,Ent,keypress,_,['Tab'|_]}, #state{entry=Ent}=State) ->
- gs:config(hd(State#state.buttons), {setfocus,true}),
- gs:config(Ent, {select,clear}),
- {continue, State#state{in_focus=0}};
-
-handle_event({gs,Win,keypress,_,['Return'|_]}, #state{win=Win}=State) ->
- Selected = lists:nth(State#state.highlighted, State#state.buttons),
- Data = gs:read(Selected, data),
- handle_event({gs,Win,click,Data,undef}, State);
-
-handle_event({gs,Win,destroy,_,_}, #state{win=Win}=State) ->
- if
- State#state.type==notify -> {return, ok};
- true -> {return, cancel}
- end;
-
-%% Flush any other GS events
-handle_event({gs,_Obj,_Event,_Data,_Arg}, State) ->
- {continue, State}.
-
-%% insert_newlines(Strings) => string()
-%% Strings - string() | [string()]
-%% If Strings is a list of strings, return a string where all these
-%% strings are concatenated with newlines in between,otherwise return
-%% Strings.
-insert_newlines([String|Rest]) when is_list(String),Rest/=[]->
- String ++ "\n" ++ insert_newlines(Rest);
-insert_newlines([Last]) ->
- [Last];
-insert_newlines(Other) ->
- Other.
diff --git a/lib/gs/tcl/Makefile b/lib/gs/tcl/Makefile
deleted file mode 100644
index 2eb06cec61..0000000000
--- a/lib/gs/tcl/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-#
-# Invoke with GNU make or clearmake -C gnu.
-#
-
-include $(ERL_TOP)/make/run_make.mk
diff --git a/lib/gs/tcl/Makefile.in b/lib/gs/tcl/Makefile.in
deleted file mode 100644
index 762973bd72..0000000000
--- a/lib/gs/tcl/Makefile.in
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2002-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-#
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include ../vsn.mk
-VSN=$(GS_VSN)
-
-# ----------------------------------------------------
-# The following variables differ on different systems, we set
-# reasonable defaults, if something different is needed it should
-# be set for that system only.
-# ----------------------------------------------------
-
-ifeq ($(TARGET),win32)
-TCL_TAR = binaries/win32.tar.gz
-else
-TCL_TAR = @TCL_TAR@
-endif
-
-CONFIGURE_FILES = ../configure ../configure.in
-
-ROOTDIR = ..
-BINDIR = $(ROOTDIR)/priv/bin
-LIBDIR = ./lib
-
-RELSYSDIR = $(RELEASE_PATH)/lib/gs-$(VSN)
-
-# ----------------------------------------------------
-# Common Macros
-# ----------------------------------------------------
-TCL_FILES = ../priv/gstk.tcl
-EXTRA_FILES = ../priv/gs-xdefaults
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-ifeq ($(TCL_TAR),)
-debug opt:
-else
-debug opt:
- gzip -dc $(TCL_TAR) | (cd ../priv && tar -xf -)
-endif
-
-clean:
-
-docs:
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-release_spec:
- $(INSTALL_DIR) "$(RELSYSDIR)/priv"
- $(INSTALL_DATA) $(TCL_FILES) $(EXTRA_FILES) "$(RELSYSDIR)/priv"
-ifneq ($(TCL_TAR),)
- gzip -dc $(TCL_TAR) | (cd "$(RELSYSDIR)/priv" && tar -xf -)
-endif
-
-release_docs_spec:
diff --git a/lib/gs/tcl/README b/lib/gs/tcl/README
deleted file mode 100644
index 5fc1836349..0000000000
--- a/lib/gs/tcl/README
+++ /dev/null
@@ -1,156 +0,0 @@
-==============================================================================
- How to create prebuilt Tcl/Tk binaries
-==============================================================================
-
-Please look further down in this text for Windows instructions...
-
-Unixish OS
-----------
-
-For commercial releases we use a prebuilt binary release of Tcl/Tk 8.X
-where X >= 2. This release is placed into "gs-VSN/priv/tcl" and the
-'gstk_port_handler' module searches this directory first to find the
-"wish" executable program.
-
-It is possible to pack the files from a standard installation on a
-machine into a TAR file but it is preferable to build Tcl/Tk from
-sources. The steps are
-
- 0. Set some environment variables
-
- % setenv BUILDDIR /tmp/build
- % setenv GNUTAR gtar
-
- 1. Download unpack the sources from http://sourceforge.net/projects/tcl.
- Use the latest stable release. When this README was written
- the latest stable version was 8.3.4.
-
- % mkdir -p $BUILDDIR/tcl
- % cd $BUILDDIR
- % $GNUTAR -xzf /my/src/path/tcl8.3.4.tar.gz
- % $GNUTAR -xzf /my/src/path/tk8.3.4.tar.gz
-
- % cd tcl8.3.4/unix
- % ./configure --enable-gcc --enable-threads --disable-load \
- --disable-shared --prefix=$BUILDDIR/tcl
- % make
- % make install
-
- % cd ../../tk8.3.4/unix
- % ./configure --enable-gcc --enable-threads --disable-load \
- --disable-shared --prefix=$BUILDDIR/tcl \
- --with-tcl=$BUILDDIR/tcl/lib
- % make
- % make install
-
- 2. Check that the executable wish program don't depend on libtcl
- or libtk. If it does we have to redo this or keep them
- where they are, else we can remove the libraries
-
- % cd $BUILDDIR
- % ldd tcl/bin/wish8.3
-
- and if the executables doesn't depend on libtcl or libtk we remove them
-
- % rm -f tcl/lib/libt*
-
- 3. Remove other things we don't need. There may be other things in
- later releases but only remove the obvious things
-
- % rm -fr tcl/include tcl/man
- % rm -f tcl/bin/tclsh*
- % rm -f tcl/lib/*.sh
- % rm -fr tcl/lib/tcl*/http*
- % rm -fr tcl/lib/tcl*/tcltest*
- % rm -fr tcl/lib/tk*/demos
- % rm -fr tcl/lib/tk*/images
- % rm -f tcl/lib/*/*.c
-
- 4. Some releases of Tcl/Tk contains soft links that make the directory
- structure circular making it impossible to use 'cp' to copy the
- tcl directory. You can find them with
-
- % find tcl -type l
-
- 5. Find out the name of the resulting TAR archive. Run the GS configure
- script on the target platform to view the name
-
- % cd $ERL_TOP/lib/gs
- % rm -f config.cache
- % autoconf
- % ./configure
-
- 6. Use the TAR program on the system to pack the resulting Tcl/Tk
- distribution. Keep the top "tcl" library
-
- % tar -cf - tcl | gzip > xxxxxxxx.tar.gz
-
- 7. Copy and check in this TAR archive into the directory
-
- /clearcase/otp/erts/lib/gs/tcl/binaries
-
- 8. We are done........
-
-
-Windows
--------
-
-These instructions are aimed at the 8.5.7 release of both tcl and tk,
-but should work for 8.4 as well as 8.6 releases with appropriate
-modifications.
-
-0. Download the source tar files for both tcl and tk and unpack the
-tar files from the same root.
-
-1. Start with tcl. Open a command prompt with the appropriate Visual
-C++ command environment (there is usually a shortcut under VC++ tools
-or something in the start menu. With this command prompt, cd to the
-tcl<version>/win directory and issue the following commands:
-
-dos_prompt> nmake -f makefile.vc OPTS=static INSTALLDIR=<some temp dir>\tcl
-...
-dos_prompt> nmake -f makefile.vc OPTS=static INSTALLDIR=<some temp dir>\tcl install
-
-2. Move further to tk. Using the same command prompt, cd
-..\..\tk<version>\win and build there:
-
-dos_prompt> nmake -f makefile.vc OPTS=static TCLDIR=<top dir of sources>\tcl<version> INSTALLDIR=<some temp dir>\tcl
-...
-dos_prompt> nmake -f makefile.vc OPTS=static TCLDIR=<top dir of sources>\tcl<version> INSTALLDIR=<some temp dir>\tcl install
-
-3. Now you will need to strip the installation you put in <some temp
-dir>\tcl. To do this, you will want a more appropriate command
-shell. Start cygwin bash and cd to the cygwin equivalent of <some temp
-dir>, i.e. where tcl/tk was installed. Now clean away what's not
-needed (this is not optional, gs won't work with a full version...)
-
- % rm -fr tcl/include tcl/man
- % rm -f tcl/bin/tclsh*
- % rm -f tcl/lib/*.sh
- % rm -fr tcl/lib/tcl*/http*
- % rm -fr tcl/lib/tcl*/tcltest*
- % rm -fr tcl/lib/tcl*/tzdata
- % rm -fr tcl/lib/tcl*/msgs
- % rm -fr tcl/lib/tk*/demos
- % rm -fr tcl/lib/tk*/images
- % rm -fr tcl/lib/tk*/tzdata
- % rm -f tcl/lib/*/*.c
- % rm -f tcl/lib/*.lib
- % rm -fr tcl/lib/tcl8
-
-(The last line is especially important, gs will crash otherwise...)
-
-4. Now copy license.terms from the sources, otherwise you may break the redistribution policy.
-
- % cp <top of sources/tcl<version>/license.terms tcl/
-
-5. Pack the tar file:
-
- % tar zcf win32.tar.gz tcl
-
-6. Put it in $ERL_TOP/lib/gs/tcl/binaries (as described for Unixes)
-
-7. You are done!
-
-
-
diff --git a/lib/gs/test/Makefile b/lib/gs/test/Makefile
deleted file mode 100644
index 067e1adbb6..0000000000
--- a/lib/gs/test/Makefile
+++ /dev/null
@@ -1,65 +0,0 @@
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-
-MODULES= \
- gs_SUITE
-
-ERL_FILES= $(MODULES:%=%.erl)
-
-TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
-INSTALL_PROGS= $(TARGET_FILES)
-
-EMAKEFILE=Emakefile
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/gs_test
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-
-ERL_MAKE_FLAGS +=
-ERL_COMPILE_FLAGS +=
-
-EBIN = .
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-make_emakefile:
- $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
- > $(EMAKEFILE)
- $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' \
- >> $(EMAKEFILE)
-
-tests debug opt: make_emakefile
- erl $(ERL_MAKE_FLAGS) -make
-
-clean:
- rm -f $(EMAKEFILE)
- rm -f $(TARGET_FILES) $(GEN_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) $(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)"
- $(INSTALL_DATA) gs.spec "$(RELSYSDIR)"
- chmod -R u+w "$(RELSYSDIR)"
-
-release_docs_spec:
diff --git a/lib/gs/test/gs.spec b/lib/gs/test/gs.spec
deleted file mode 100644
index 46e6b2061e..0000000000
--- a/lib/gs/test/gs.spec
+++ /dev/null
@@ -1 +0,0 @@
-{suites,"../gs_test",all}.
diff --git a/lib/gs/test/gs_SUITE.erl b/lib/gs/test/gs_SUITE.erl
deleted file mode 100644
index 3f36019728..0000000000
--- a/lib/gs/test/gs_SUITE.erl
+++ /dev/null
@@ -1,51 +0,0 @@
-%% ``Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% 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(gs_SUITE).
-
--compile([export_all]).
--include_lib("common_test/include/ct.hrl").
-
-suite() ->
- [{ct_hooks, [ts_install_cth]}].
-
-all() ->
- [app, appup].
-
-groups() ->
- [].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-app() ->
- [{doc, "Test that the gs app file is ok"}].
-app(Config) when is_list(Config) ->
- ok = ?t:app_test(gs, tolerant).
-
-appup() ->
- [{doc, "Test that the gs appup file is ok"}].
-appup(Config) when is_list(Config) ->
- ok = ?t:appup_test(gs).
diff --git a/lib/gs/vsn.mk b/lib/gs/vsn.mk
deleted file mode 100644
index c762507bab..0000000000
--- a/lib/gs/vsn.mk
+++ /dev/null
@@ -1,2 +0,0 @@
-GS_VSN = 1.6.1
-
diff --git a/lib/hipe/amd64/Makefile b/lib/hipe/amd64/Makefile
index 8dc2af2679..1b6e4ea947 100644
--- a/lib/hipe/amd64/Makefile
+++ b/lib/hipe/amd64/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2016. All Rights Reserved.
+# Copyright Ericsson AB 2004-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -57,10 +57,11 @@ MODULES=hipe_amd64_assemble \
hipe_amd64_ra_naive \
hipe_amd64_ra_postconditions \
hipe_amd64_ra_sse2_postconditions \
- hipe_amd64_ra_x87_ls \
hipe_amd64_registers \
hipe_amd64_spill_restore \
+ hipe_amd64_subst \
hipe_amd64_x87 \
+ hipe_amd64_sse2 \
hipe_rtl_to_amd64
ERL_FILES=$(MODULES:%=%.erl)
@@ -125,10 +126,11 @@ $(EBIN)/hipe_amd64_ra_ls.beam: ../main/hipe.hrl ../x86/hipe_x86_ra_ls.erl
$(EBIN)/hipe_amd64_ra_naive.beam: ../main/hipe.hrl ../x86/hipe_x86.hrl ../x86/hipe_x86_ra_naive.erl
$(EBIN)/hipe_amd64_ra_postconditions.beam: ../main/hipe.hrl ../x86/hipe_x86.hrl ../x86/hipe_x86_ra_postconditions.erl
$(EBIN)/hipe_amd64_ra_sse2_postconditions.beam: ../main/hipe.hrl
-$(EBIN)/hipe_amd64_ra_x87_ls.beam: ../main/hipe.hrl ../x86/hipe_x86_ra_x87_ls.erl
$(EBIN)/hipe_amd64_registers.beam: ../rtl/hipe_literals.hrl
$(EBIN)/hipe_amd64_spill_restore.beam: ../main/hipe.hrl ../x86/hipe_x86.hrl ../flow/cfg.hrl ../x86/hipe_x86_spill_restore.erl
+$(EBIN)/hipe_amd64_subst.beam: ../x86/hipe_x86_subst.erl
$(EBIN)/hipe_amd64_x87.beam: ../x86/hipe_x86_x87.erl
+$(EBIN)/hipe_amd64_sse2.beam: ../main/hipe.hrl ../x86/hipe_x86.hrl
$(EBIN)/hipe_rtl_to_amd64.beam: ../x86/hipe_rtl_to_x86.erl ../rtl/hipe_rtl.hrl
$(TARGET_FILES): ../x86/hipe_x86.hrl ../misc/hipe_consttab.hrl
diff --git a/lib/hipe/amd64/hipe_amd64_assemble.erl b/lib/hipe/amd64/hipe_amd64_assemble.erl
index a7b11f7c72..1379850515 100644
--- a/lib/hipe/amd64/hipe_amd64_assemble.erl
+++ b/lib/hipe/amd64/hipe_amd64_assemble.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,7 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
+
-include("../x86/hipe_x86_assemble.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_defuse.erl b/lib/hipe/amd64/hipe_amd64_defuse.erl
index 907f078f3f..9074c3e05e 100644
--- a/lib/hipe/amd64/hipe_amd64_defuse.erl
+++ b/lib/hipe/amd64/hipe_amd64_defuse.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_defuse.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_encode.erl b/lib/hipe/amd64/hipe_amd64_encode.erl
index df15732cea..bda2824ffc 100644
--- a/lib/hipe/amd64/hipe_amd64_encode.erl
+++ b/lib/hipe/amd64/hipe_amd64_encode.erl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Copyright (C) 2000-2004 Mikael Pettersson
%%% Copyright (C) 2004 Daniel Luna
@@ -63,7 +56,7 @@
-export([% condition codes
cc/1,
% 8-bit registers
- %% al/0, cl/0, dl/0, bl/0, ah/0, ch/0, dh/0, bh/0,
+ %% al/0, cl/0, dl/0, bl/0,
% 32-bit registers
%% eax/0, ecx/0, edx/0, ebx/0, esp/0, ebp/0, esi/0, edi/0,
% operands
@@ -127,19 +120,15 @@ cc(g) -> ?CC_G.
-define(CL, 2#001).
-define(DL, 2#010).
-define(BL, 2#011).
--define(AH, 2#100).
--define(CH, 2#101).
--define(DH, 2#110).
--define(BH, 2#111).
+-define(SPL, 2#100).
+-define(BPL, 2#101).
+-define(SIL, 2#110).
+-define(DIL, 2#111).
%% al() -> ?AL.
%% cl() -> ?CL.
%% dl() -> ?DL.
%% bl() -> ?BL.
-%% ah() -> ?AH.
-%% ch() -> ?CH.
-%% dh() -> ?DH.
-%% bh() -> ?BH.
%%% 32-bit registers
@@ -208,6 +197,7 @@ rex_([]) -> 0;
rex_([{r8, Reg8}| Rest]) -> % 8 bit registers
case Reg8 of
{rm_mem, _} -> rex_(Rest);
+ {rm_reg, R} -> rex_([{r8, R} | Rest]);
4 -> (1 bsl 8) bor rex_(Rest);
5 -> (1 bsl 8) bor rex_(Rest);
6 -> (1 bsl 8) bor rex_(Rest);
@@ -825,12 +815,26 @@ shd_op_encode(Opcode, Opnds) ->
test_encode(Opnds) ->
case Opnds of
+ {al, {imm8,Imm8}} ->
+ [16#A8, Imm8];
+ {ax, {imm16,Imm16}} ->
+ [?PFX_OPND_16BITS, 16#A9 | le16(Imm16, [])];
{eax, {imm32,Imm32}} ->
[16#A9 | le32(Imm32, [])];
+ {rax, {imm32,Imm32}} ->
+ [rex([{w,1}]), 16#A9 | le32(Imm32, [])];
+ {{rm8,RM8}, {imm8,Imm8}} ->
+ [rex([{r8,RM8}]), 16#F6 | encode_rm(RM8, 2#000, [Imm8])];
+ {{rm16,RM16}, {imm16,Imm16}} ->
+ [?PFX_OPND_16BITS, 16#F7 | encode_rm(RM16, 2#000, le16(Imm16, []))];
{{rm32,RM32}, {imm32,Imm32}} ->
[16#F7 | encode_rm(RM32, 2#000, le32(Imm32, []))];
+ {{rm64,RM64}, {imm32,Imm32}} ->
+ [rex([{w,1}]), 16#F7 | encode_rm(RM64, 2#000, le32(Imm32, []))];
{{rm32,RM32}, {reg32,Reg32}} ->
- [16#85 | encode_rm(RM32, Reg32, [])]
+ [16#85 | encode_rm(RM32, Reg32, [])];
+ {{rm64,RM64}, {reg64,Reg64}} ->
+ [rex([{w,1}]), 16#85 | encode_rm(RM64, Reg64, [])]
end.
%% test_sizeof(Opnds) ->
@@ -1309,18 +1313,22 @@ dotest1(OS) ->
Imm32 = {imm32,Word32},
Imm16 = {imm16,Word16},
Imm8 = {imm8,Word8},
+ RM64 = {rm64,rm_reg(?EDX)},
RM32 = {rm32,rm_reg(?EDX)},
RM16 = {rm16,rm_reg(?EDX)},
+ RM16REX = {rm16,rm_reg(?R13)},
RM8 = {rm8,rm_reg(?EDX)},
+ RM8REX = {rm8,rm_reg(?SIL)},
Rel32 = {rel32,Word32},
Rel8 = {rel8,Word8},
Moffs32 = {moffs32,Word32},
Moffs16 = {moffs16,Word32},
Moffs8 = {moffs8,Word32},
CC = {cc,?CC_G},
+ Reg64 = {reg64,?EAX},
Reg32 = {reg32,?EAX},
Reg16 = {reg16,?EAX},
- Reg8 = {reg8,?AH},
+ Reg8 = {reg8,?SPL},
EA = {ea,ea_base(?ECX)},
% exercise each instruction definition
t(OS,'adc',{eax,Imm32}),
@@ -1465,9 +1473,18 @@ dotest1(OS) ->
t(OS,'sub',{RM32,Imm8}),
t(OS,'sub',{RM32,Reg32}),
t(OS,'sub',{Reg32,RM32}),
+ t(OS,'test',{al,Imm8}),
+ t(OS,'test',{ax,Imm16}),
t(OS,'test',{eax,Imm32}),
+ t(OS,'test',{rax,Imm32}),
+ t(OS,'test',{RM8,Imm8}),
+ t(OS,'test',{RM8REX,Imm8}),
+ t(OS,'test',{RM16,Imm16}),
+ t(OS,'test',{RM16REX,Imm16}),
t(OS,'test',{RM32,Imm32}),
+ t(OS,'test',{RM64,Imm32}),
t(OS,'test',{RM32,Reg32}),
+ t(OS,'test',{RM64,Reg64}),
t(OS,'xor',{eax,Imm32}),
t(OS,'xor',{RM32,Imm32}),
t(OS,'xor',{RM32,Imm8}),
diff --git a/lib/hipe/amd64/hipe_amd64_frame.erl b/lib/hipe/amd64/hipe_amd64_frame.erl
index f3bcdf302a..800f1c1a08 100644
--- a/lib/hipe/amd64/hipe_amd64_frame.erl
+++ b/lib/hipe/amd64/hipe_amd64_frame.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_frame.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_liveness.erl b/lib/hipe/amd64/hipe_amd64_liveness.erl
index 5cfdbb0f3e..a1e8403df1 100644
--- a/lib/hipe/amd64/hipe_amd64_liveness.erl
+++ b/lib/hipe/amd64/hipe_amd64_liveness.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_liveness.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_main.erl b/lib/hipe/amd64/hipe_amd64_main.erl
index c22c6cd73b..75b7746500 100644
--- a/lib/hipe/amd64/hipe_amd64_main.erl
+++ b/lib/hipe/amd64/hipe_amd64_main.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_main.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_pp.erl b/lib/hipe/amd64/hipe_amd64_pp.erl
index 7c3ee8458a..9dfe571122 100644
--- a/lib/hipe/amd64/hipe_amd64_pp.erl
+++ b/lib/hipe/amd64/hipe_amd64_pp.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_pp.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra.erl b/lib/hipe/amd64/hipe_amd64_ra.erl
index 1d8453d54d..052e9c1e63 100644
--- a/lib/hipe/amd64/hipe_amd64_ra.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_ra.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra_finalise.erl b/lib/hipe/amd64/hipe_amd64_ra_finalise.erl
index d835c3ec14..82d462fad7 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_finalise.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_finalise.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_ra_finalise.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra_ls.erl b/lib/hipe/amd64/hipe_amd64_ra_ls.erl
index 9361b91f04..9fa0edca47 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_ls.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_ls.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_ra_ls.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra_naive.erl b/lib/hipe/amd64/hipe_amd64_ra_naive.erl
index 38218a65dc..1aa40121c9 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_naive.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_naive.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_ra_naive.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl b/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl
index 2d03239ea6..9359e0db0a 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_ra_postconditions.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl b/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
index 5451f1fe7d..891c874a15 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,13 +11,10 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_amd64_ra_sse2_postconditions).
--export([check_and_rewrite/2]).
+-export([check_and_rewrite/2, check_and_rewrite/3]).
-include("../x86/hipe_x86.hrl").
-define(HIPE_INSTRUMENT_COMPILER, true).
@@ -29,40 +22,50 @@
-define(count_temp(T), ?cons_counter(counter_mfa_mem_temps, T)).
-check_and_rewrite(AMD64Defun, Coloring) ->
+check_and_rewrite(AMD64CFG, Coloring) ->
+ check_and_rewrite(AMD64CFG, Coloring, 'normal').
+
+check_and_rewrite(AMD64CFG, Coloring, Strategy) ->
%%io:format("Converting\n"),
- TempMap = hipe_temp_map:cols2tuple(Coloring,hipe_amd64_specific_sse2),
+ TempMap = hipe_temp_map:cols2tuple(Coloring,hipe_amd64_specific_sse2,no_context),
%%io:format("Rewriting\n"),
- #defun{code=Code0} = AMD64Defun,
- {Code1, DidSpill} = do_insns(Code0, TempMap, [], false),
- {AMD64Defun#defun{code=Code1, var_range={0, hipe_gensym:get_var(x86)}},
- DidSpill}.
-
-do_insns([I|Insns], TempMap, Accum, DidSpill0) ->
- {NewIs, DidSpill1} = do_insn(I, TempMap),
- do_insns(Insns, TempMap, lists:reverse(NewIs, Accum), DidSpill0 or DidSpill1);
-do_insns([], _TempMap, Accum, DidSpill) ->
+ do_bbs(hipe_x86_cfg:labels(AMD64CFG), TempMap, Strategy, AMD64CFG, false).
+
+do_bbs([], _, _, CFG, DidSpill) -> {CFG, DidSpill};
+do_bbs([Lbl|Lbls], TempMap, Strategy, CFG0, DidSpill0) ->
+ Code0 = hipe_bb:code(BB = hipe_x86_cfg:bb(CFG0, Lbl)),
+ {Code, DidSpill} = do_insns(Code0, TempMap, Strategy, [], DidSpill0),
+ CFG = hipe_x86_cfg:bb_add(CFG0, Lbl, hipe_bb:code_update(BB, Code)),
+ do_bbs(Lbls, TempMap, Strategy, CFG, DidSpill).
+
+do_insns([I|Insns], TempMap, Strategy, Accum, DidSpill0) ->
+ {NewIs, DidSpill1} = do_insn(I, TempMap, Strategy),
+ do_insns(Insns, TempMap, Strategy, lists:reverse(NewIs, Accum),
+ DidSpill0 or DidSpill1);
+do_insns([], _TempMap, _Strategy, Accum, DidSpill) ->
{lists:reverse(Accum), DidSpill}.
-do_insn(I, TempMap) -> % Insn -> {Insn list, DidSpill}
+do_insn(I, TempMap, Strategy) -> % Insn -> {Insn list, DidSpill}
case I of
#fmove{} ->
- do_fmove(I, TempMap);
+ do_fmove(I, TempMap, Strategy);
#fp_unop{} ->
- do_fp_unop(I, TempMap);
+ do_fp_unop(I, TempMap, Strategy);
#fp_binop{} ->
- do_fp_binop(I, TempMap);
+ do_fp_binop(I, TempMap, Strategy);
+ #pseudo_spill_fmove{} ->
+ do_pseudo_spill_fmove(I, TempMap, Strategy);
_ ->
%% All non sse2 ops
{[I], false}
end.
%%% Fix an fp_binop.
-do_fp_binop(I, TempMap) ->
+do_fp_binop(I, TempMap, Strategy) ->
#fp_binop{src=Src,dst=Dst} = I,
case is_mem_opnd(Dst, TempMap) of
true ->
- Tmp = clone(Dst),
+ Tmp = clone(Dst, Strategy),
{[#fmove{src=Dst, dst=Tmp},
I#fp_binop{src=Src,dst=Tmp},
#fmove{src=Tmp,dst=Dst}],
@@ -71,11 +74,11 @@ do_fp_binop(I, TempMap) ->
{[I], false}
end.
-do_fp_unop(I, TempMap) ->
+do_fp_unop(I, TempMap, Strategy) ->
#fp_unop{arg=Arg} = I,
case is_mem_opnd(Arg, TempMap) of
true ->
- Tmp = clone(Arg),
+ Tmp = clone(Arg, Strategy),
{[#fmove{src=Arg, dst=Tmp},
I#fp_unop{arg=Tmp},
#fmove{src=Tmp,dst=Arg}],
@@ -85,97 +88,72 @@ do_fp_unop(I, TempMap) ->
end.
%%% Fix an fmove op.
-do_fmove(I, TempMap) ->
+do_fmove(I, TempMap, Strategy) ->
#fmove{src=Src,dst=Dst} = I,
- case is_mem_opnd(Dst, TempMap) and is_mem_opnd(Src, TempMap) of
+ case
+ (is_mem_opnd(Src, TempMap) andalso is_mem_opnd(Dst, TempMap))
+ orelse (is_mem_opnd(Src, TempMap) andalso (not is_float_temp(Dst)))
+ orelse ((not is_float_temp(Src)) andalso is_mem_opnd(Dst, TempMap))
+ of
true ->
- Tmp = clone(Src),
- {[#fmove{src=Src, dst=Tmp},I#fmove{src=Tmp,dst=Dst}],
- true};
+ Tmp = spill_temp(double, Strategy),
+ %% pseudo_spill_fmove allows spill slot move coalescing, but must not
+ %% contain memory operands (except for spilled temps)
+ Is = case is_float_temp(Src) andalso is_float_temp(Dst) of
+ true -> [#pseudo_spill_fmove{src=Src, temp=Tmp, dst=Dst}];
+ false -> [#fmove{src=Src, dst=Tmp},I#fmove{src=Tmp,dst=Dst}]
+ end,
+ {Is, true};
false ->
{[I], false}
end.
+is_float_temp(#x86_temp{type=Type}) -> Type =:= double;
+is_float_temp(#x86_mem{}) -> false.
+
+%%% Fix an pseudo_spill_fmove op.
+do_pseudo_spill_fmove(I = #pseudo_spill_fmove{temp=Temp}, TempMap, _Strategy) ->
+ %% Temp is above the low water mark and must not have been spilled
+ false = is_mem_opnd(Temp, TempMap),
+ {[I], false}. % nothing to do
+
%%% Check if an operand denotes a memory cell (mem or pseudo).
is_mem_opnd(Opnd, TempMap) ->
- R =
- case Opnd of
- #x86_mem{} -> true;
- #x86_temp{} ->
- Reg = hipe_x86:temp_reg(Opnd),
- case hipe_x86:temp_is_allocatable(Opnd) of
- true ->
- case tuple_size(TempMap) > Reg of
- true ->
- case
- hipe_temp_map:is_spilled(Reg, TempMap) of
- true ->
- ?count_temp(Reg),
- true;
- false -> false
- end;
- _ -> false
- end;
- false -> true
- end;
- _ -> false
- end,
- %% io:format("Op ~w mem: ~w\n",[Opnd,R]),
- R.
-
-%%% Check if an operand is a spilled Temp.
-
-%%src_is_spilled(Src, TempMap) ->
-%% case hipe_x86:is_temp(Src) of
-%% true ->
-%% Reg = hipe_x86:temp_reg(Src),
-%% case hipe_x86:temp_is_allocatable(Src) of
-%% true ->
-%% case tuple_size(TempMap) > Reg of
-%% true ->
-%% case hipe_temp_map:is_spilled(Reg, TempMap) of
-%% true ->
-%% ?count_temp(Reg),
-%% true;
-%% false ->
-%% false
-%% end;
-%% false ->
-%% false
-%% end;
-%% false -> true
-%% end;
-%% false -> false
-%% end.
-
-%% is_spilled(Temp, TempMap) ->
-%% case hipe_x86:temp_is_allocatable(Temp) of
-%% true ->
-%% Reg = hipe_x86:temp_reg(Temp),
-%% case tuple_size(TempMap) > Reg of
-%% true ->
-%% case hipe_temp_map:is_spilled(Reg, TempMap) of
-%% true ->
-%% ?count_temp(Reg),
-%% true;
-%% false ->
-%% false
-%% end;
-%% false ->
-%% false
-%% end;
-%% false -> true
-%% end.
+ case Opnd of
+ #x86_mem{} -> true;
+ #x86_temp{type=double} ->
+ Reg = hipe_x86:temp_reg(Opnd),
+ case hipe_x86:temp_is_allocatable(Opnd) of
+ true ->
+ case hipe_temp_map:is_spilled(Reg, TempMap) of
+ true ->
+ ?count_temp(Reg),
+ true;
+ false -> false
+ end;
+ false -> true
+ end;
+ _ -> false
+ end.
%%% Make Reg a clone of Dst (attach Dst's type to Reg).
-clone(Dst) ->
+clone(Dst, Strategy) ->
Type =
case Dst of
#x86_mem{} -> hipe_x86:mem_type(Dst);
#x86_temp{} -> hipe_x86:temp_type(Dst)
end,
+ spill_temp(Type, Strategy).
+
+spill_temp(Type, 'normal') ->
+ hipe_x86:mk_new_temp(Type);
+spill_temp(double, 'linearscan') ->
+ hipe_x86:mk_temp(hipe_amd64_specific_sse2:temp0(no_context), double);
+spill_temp(Type, 'linearscan') when Type =:= tagged; Type =/= untagged ->
+ %% We can make a new temp here since we have yet to allocate registers for
+ %% these types
hipe_x86:mk_new_temp(Type).
%%% Make a certain reg into a clone of Dst
diff --git a/lib/hipe/amd64/hipe_amd64_registers.erl b/lib/hipe/amd64/hipe_amd64_registers.erl
index 780c2cc547..a5cecef5a1 100644
--- a/lib/hipe/amd64/hipe_amd64_registers.erl
+++ b/lib/hipe/amd64/hipe_amd64_registers.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_amd64_registers).
@@ -52,6 +45,7 @@
tailcall_clobbered/0,
temp0/0,
temp1/0,
+ sse2_temp0/0,
%% fixed/0,
wordsize/0
]).
@@ -107,6 +101,8 @@ heap_limit_offset() -> ?P_HP_LIMIT.
-define(TEMP0, ?R14).
-define(TEMP1, ?R13).
+-define(SSE2_TEMP0, 00).
+
-define(PROC_POINTER, ?RBP).
reg_name(R) ->
@@ -204,24 +200,21 @@ allocatable() ->
allocatable_sse2() ->
[00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15]. %% xmm0 - xmm15
+sse2_temp0() -> ?SSE2_TEMP0.
+
allocatable_x87() ->
[0,1,2,3,4,5,6].
nr_args() -> ?AMD64_NR_ARG_REGS.
-arg(N) ->
- if N < ?AMD64_NR_ARG_REGS ->
- case N of
- 0 -> ?ARG0;
- 1 -> ?ARG1;
- 2 -> ?ARG2;
- 3 -> ?ARG3;
- 4 -> ?ARG4;
- 5 -> ?ARG5;
- _ -> exit({?MODULE, arg, N})
- end;
- true ->
- exit({?MODULE, arg, N})
+arg(N) when N < ?AMD64_NR_ARG_REGS ->
+ case N of
+ 0 -> ?ARG0;
+ 1 -> ?ARG1;
+ 2 -> ?ARG2;
+ 3 -> ?ARG3;
+ 4 -> ?ARG4;
+ 5 -> ?ARG5
end.
is_arg(R) ->
@@ -242,12 +235,11 @@ args(Arity) when is_integer(Arity), Arity >= 0 ->
args(I, Rest) when I < 0 -> Rest;
args(I, Rest) -> args(I-1, [arg(I) | Rest]).
-ret(N) ->
- case N of
- 0 -> ?RAX;
- _ -> exit({?MODULE, ret, N})
- end.
+ret(0) -> ?RAX.
+%% Note: the fact that (allocatable() UNION allocatable_x87() UNION
+%% allocatable_sse2()) is a subset of call_clobbered() is hard-coded in
+%% hipe_x86_defuse:insn_defs_all/1
call_clobbered() ->
[{?RAX,tagged},{?RAX,untagged}, % does the RA strip the type or not?
{?RDX,tagged},{?RDX,untagged},
diff --git a/lib/hipe/amd64/hipe_amd64_spill_restore.erl b/lib/hipe/amd64/hipe_amd64_spill_restore.erl
index 61e2dfa26d..915ac1adc4 100644
--- a/lib/hipe/amd64/hipe_amd64_spill_restore.erl
+++ b/lib/hipe/amd64/hipe_amd64_spill_restore.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_spill_restore.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_sse2.erl b/lib/hipe/amd64/hipe_amd64_sse2.erl
new file mode 100644
index 0000000000..1a2d3eac48
--- /dev/null
+++ b/lib/hipe/amd64/hipe_amd64_sse2.erl
@@ -0,0 +1,76 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Fix {mem, mem} floating point operations that result from linear scan
+%% allocated floats.
+
+-module(hipe_amd64_sse2).
+
+-export([map/1]).
+
+-include("../x86/hipe_x86.hrl").
+-include("../main/hipe.hrl").
+
+%%----------------------------------------------------------------------
+
+map(CFG) ->
+ hipe_x86_cfg:map_bbs(fun do_bb/2, CFG).
+
+do_bb(_Lbl, BB) ->
+ Code = do_insns(hipe_bb:code(BB), []),
+ hipe_bb:code_update(BB, Code).
+
+do_insns([I|Insns], Accum) ->
+ NewIs = do_insn(I),
+ do_insns(Insns, lists:reverse(NewIs, Accum));
+do_insns([], Accum) ->
+ lists:reverse(Accum).
+
+do_insn(I) ->
+ case I of
+ #fp_binop{} -> do_fp_binop(I);
+ #fmove{} -> do_fmove(I);
+ _ -> [I]
+ end.
+
+do_fp_binop(I = #fp_binop{src=Src0,dst=Dst}) ->
+ {FixSrc, Src} = fix_binary(Src0, Dst),
+ FixSrc ++ [I#fp_binop{src=Src}].
+
+do_fmove(I = #fmove{src=Src0,dst=Dst}) ->
+ {FixSrc, Src} = fix_binary(Src0, Dst),
+ FixSrc ++ [I#fmove{src=Src}].
+
+fix_binary(Src0, Dst) ->
+ case is_mem_opnd(Src0) of
+ false -> {[], Src0};
+ true ->
+ case is_mem_opnd(Dst) of
+ false -> {[], Src0};
+ true ->
+ Src1 = spill_temp(),
+ {[hipe_x86:mk_fmove(Src0, Src1)], Src1}
+ end
+ end.
+
+is_mem_opnd(#x86_fpreg{reg=Reg}) ->
+ not hipe_amd64_registers:is_precoloured_sse2(Reg);
+is_mem_opnd(#x86_temp{type=double, reg=Reg}) ->
+ not hipe_amd64_registers:is_precoloured_sse2(Reg);
+is_mem_opnd(#x86_temp{type=_, reg=Reg}) ->
+ not hipe_amd64_registers:is_precoloured(Reg);
+is_mem_opnd(#x86_mem{}) -> true.
+
+spill_temp() ->
+ hipe_x86:mk_temp(hipe_amd64_registers:sse2_temp0(), double).
diff --git a/lib/gs/src/gs.appup.src b/lib/hipe/amd64/hipe_amd64_subst.erl
index 6cc21676e8..b0b9ccbe38 100644
--- a/lib/gs/src/gs.appup.src
+++ b/lib/hipe/amd64/hipe_amd64_subst.erl
@@ -1,8 +1,3 @@
-%% -*- erlang -*-
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2014-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,9 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-{"%VSN%",
- [{<<".*">>,[{restart_application, gs}]}],
- [{<<".*">>,[{restart_application, gs}]}]
-}.
+
+-include("../x86/hipe_x86_subst.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_x87.erl b/lib/hipe/amd64/hipe_amd64_x87.erl
index 1f42e4749d..afb3aa63e7 100644
--- a/lib/hipe/amd64/hipe_amd64_x87.erl
+++ b/lib/hipe/amd64/hipe_amd64_x87.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_x87.erl").
diff --git a/lib/hipe/amd64/hipe_rtl_to_amd64.erl b/lib/hipe/amd64/hipe_rtl_to_amd64.erl
index d55b5b2c22..7243e75f84 100644
--- a/lib/hipe/amd64/hipe_rtl_to_amd64.erl
+++ b/lib/hipe/amd64/hipe_rtl_to_amd64.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_rtl_to_x86.erl").
diff --git a/lib/hipe/arm/Makefile b/lib/hipe/arm/Makefile
index 00b6732afa..ed2eccf428 100644
--- a/lib/hipe/arm/Makefile
+++ b/lib/hipe/arm/Makefile
@@ -61,6 +61,7 @@ MODULES=hipe_arm \
hipe_arm_ra_naive \
hipe_arm_ra_postconditions \
hipe_arm_registers \
+ hipe_arm_subst \
hipe_rtl_to_arm
HRL_FILES=hipe_arm.hrl
diff --git a/lib/hipe/arm/hipe_arm.erl b/lib/hipe/arm/hipe_arm.erl
index f34525fa3b..3b090b501a 100644
--- a/lib/hipe/arm/hipe_arm.erl
+++ b/lib/hipe/arm/hipe_arm.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm).
-export([
@@ -86,6 +79,9 @@
pseudo_move_dst/1,
pseudo_move_src/1,
+ mk_pseudo_spill_move/3,
+ is_pseudo_spill_move/1,
+
mk_pseudo_switch/3,
mk_pseudo_tailcall/4,
@@ -257,6 +253,10 @@ is_pseudo_move(I) -> case I of #pseudo_move{} -> true; _ -> false end.
pseudo_move_dst(#pseudo_move{dst=Dst}) -> Dst.
pseudo_move_src(#pseudo_move{src=Src}) -> Src.
+mk_pseudo_spill_move(Dst, Temp, Src) ->
+ #pseudo_spill_move{dst=Dst, temp=Temp, src=Src}.
+is_pseudo_spill_move(I) -> is_record(I, pseudo_spill_move).
+
mk_pseudo_switch(JTab, Index, Labels) ->
#pseudo_switch{jtab=JTab, index=Index, labels=Labels}.
diff --git a/lib/hipe/arm/hipe_arm.hrl b/lib/hipe/arm/hipe_arm.hrl
index 558174e3fc..be06b1ebd7 100644
--- a/lib/hipe/arm/hipe_arm.hrl
+++ b/lib/hipe/arm/hipe_arm.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%--------------------------------------------------------------------
%%% Basic Values:
@@ -108,6 +101,7 @@
-record(pseudo_call_prepare, {nrstkargs}).
-record(pseudo_li, {dst, imm, label}). % pre-generated label for use by the assembler
-record(pseudo_move, {dst, src}).
+-record(pseudo_spill_move, {dst, temp, src}).
-record(pseudo_switch, {jtab, index, labels}).
-record(pseudo_tailcall, {funv, arity, stkargs, linkage}).
-record(pseudo_tailcall_prepare, {}).
diff --git a/lib/hipe/arm/hipe_arm_assemble.erl b/lib/hipe/arm/hipe_arm_assemble.erl
index 4a245cd853..9aa730afa9 100644
--- a/lib/hipe/arm/hipe_arm_assemble.erl
+++ b/lib/hipe/arm/hipe_arm_assemble.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_assemble).
-export([assemble/4]).
@@ -38,7 +31,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
|| {MFA, Defun} <- CompiledCode],
%%
{ConstAlign,ConstSize,ConstMap,RefsFromConsts} =
- hipe_pack_constants:pack_constants(Code, 4),
+ hipe_pack_constants:pack_constants(Code),
%%
{CodeSize,CodeBinary,AccRefs,LabelMap,ExportMap} =
encode(translate(Code, ConstMap), Options),
diff --git a/lib/hipe/arm/hipe_arm_cfg.erl b/lib/hipe/arm/hipe_arm_cfg.erl
index f2fa0a5164..0bc3df30b9 100644
--- a/lib/hipe/arm/hipe_arm_cfg.erl
+++ b/lib/hipe/arm/hipe_arm_cfg.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,26 +11,26 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_cfg).
-export([init/1,
labels/1, start_label/1,
succ/2,
+ map_bbs/2, fold_bbs/3,
bb/2, bb_add/3]).
-export([postorder/1]).
-export([linearise/1]).
-export([params/1, reverse_postorder/1]).
-export([arity/1]). % for linear scan
%%-export([redirect_jmp/3]).
+-export([branch_preds/1]).
%%% these tell cfg.inc what to define (ugly as hell)
-define(BREADTH_ORDER,true). % for linear scan
-define(PARAMS_NEEDED,true).
-define(START_LABEL_UPDATE_NEEDED,true).
+-define(MAP_FOLD_NEEDED,true).
-include("hipe_arm.hrl").
-include("../flow/cfg.hrl").
@@ -80,6 +76,26 @@ branch_successors(Branch) ->
#pseudo_tailcall{} -> []
end.
+branch_preds(Branch) ->
+ case Branch of
+ #pseudo_bc{true_label=TrueLab,false_label=FalseLab,pred=Pred} ->
+ [{FalseLab, 1.0-Pred}, {TrueLab, Pred}];
+ #pseudo_call{contlab=ContLab, sdesc=#arm_sdesc{exnlab=[]}} ->
+ %% A function can still cause an exception, even if we won't catch it
+ [{ContLab, 1.0-hipe_bb_weights:call_exn_pred()}];
+ #pseudo_call{contlab=ContLab, sdesc=#arm_sdesc{exnlab=ExnLab}} ->
+ CallExnPred = hipe_bb_weights:call_exn_pred(),
+ [{ContLab, 1.0-CallExnPred}, {ExnLab, CallExnPred}];
+ #pseudo_switch{labels=Labels} ->
+ Prob = 1.0/length(Labels),
+ [{L, Prob} || L <- Labels];
+ _ ->
+ case branch_successors(Branch) of
+ [] -> [];
+ [Single] -> [{Single, 1.0}]
+ end
+ end.
+
-ifdef(REMOVE_TRIVIAL_BBS_NEEDED).
fails_to(_Instr) -> [].
-endif.
diff --git a/lib/hipe/arm/hipe_arm_defuse.erl b/lib/hipe/arm/hipe_arm_defuse.erl
index f57b0e601c..652299a514 100644
--- a/lib/hipe/arm/hipe_arm_defuse.erl
+++ b/lib/hipe/arm/hipe_arm_defuse.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,13 +11,11 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_defuse).
-export([insn_def_all/1, insn_use_all/1]).
-export([insn_def_gpr/1, insn_use_gpr/1]).
+-export([insn_defs_all_gpr/1]).
-include("hipe_arm.hrl").
%%%
@@ -46,6 +40,7 @@ insn_def_gpr(I) ->
#pseudo_call{} -> call_clobbered_gpr();
#pseudo_li{dst=Dst} -> [Dst];
#pseudo_move{dst=Dst} -> [Dst];
+ #pseudo_spill_move{dst=Dst, temp=Temp} -> [Dst, Temp];
#pseudo_tailcall_prepare{} -> tailcall_clobbered_gpr();
#smull{dstlo=DstLo,dsthi=DstHi,src1=Src1} ->
%% ARM requires DstLo, DstHi, and Src1 to be distinct.
@@ -55,6 +50,12 @@ insn_def_gpr(I) ->
_ -> []
end.
+insn_defs_all_gpr(I) ->
+ case I of
+ #pseudo_call{} -> true;
+ _ -> false
+ end.
+
call_clobbered_gpr() ->
[hipe_arm:mk_temp(R, T)
|| {R,T} <- hipe_arm_registers:call_clobbered() ++ all_fp_pseudos()].
@@ -83,6 +84,7 @@ insn_use_gpr(I) ->
#pseudo_call{funv=FunV,sdesc=#arm_sdesc{arity=Arity}} ->
funv_use(FunV, arity_use_gpr(Arity));
#pseudo_move{src=Src} -> [Src];
+ #pseudo_spill_move{src=Src} -> [Src];
#pseudo_switch{jtab=JTabR,index=IndexR} -> addtemp(JTabR, [IndexR]);
#pseudo_tailcall{funv=FunV,arity=Arity,stkargs=StkArgs} ->
addargs(StkArgs, addtemps(tailcall_clobbered_gpr(), funv_use(FunV, arity_use_gpr(Arity))));
diff --git a/lib/hipe/arm/hipe_arm_encode.erl b/lib/hipe/arm/hipe_arm_encode.erl
index 9368cbf628..dedb6547bb 100644
--- a/lib/hipe/arm/hipe_arm_encode.erl
+++ b/lib/hipe/arm/hipe_arm_encode.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Encode symbolic ARM instructions to binary form.
%%% Copyright (C) 2005 Mikael Pettersson
diff --git a/lib/hipe/arm/hipe_arm_finalise.erl b/lib/hipe/arm/hipe_arm_finalise.erl
index a4b2f9c73c..3a6fd5a2dd 100644
--- a/lib/hipe/arm/hipe_arm_finalise.erl
+++ b/lib/hipe/arm/hipe_arm_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,18 +11,19 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_finalise).
--export([finalise/1]).
+-export([finalise/2]).
-include("hipe_arm.hrl").
-finalise(Defun) ->
+finalise(Defun, Options) ->
#defun{code=Code0} = Defun,
- Code1 = peep(expand(Code0)),
- Defun#defun{code=Code1}.
+ Code1Rev = expand(Code0),
+ Code2 = case proplists:get_bool(peephole, Options) of
+ true -> peep(Code1Rev);
+ false -> lists:reverse(Code1Rev)
+ end,
+ Defun#defun{code=Code2}.
expand(Insns) ->
expand_list(Insns, []).
@@ -34,7 +31,7 @@ expand(Insns) ->
expand_list([I|Insns], Accum) ->
expand_list(Insns, expand_insn(I, Accum));
expand_list([], Accum) ->
- lists:reverse(Accum).
+ Accum.
expand_insn(I, Accum) ->
case I of
@@ -63,12 +60,67 @@ expand_insn(I, Accum) ->
[I|Accum]
end.
-peep(Insns) ->
- peep_list(Insns, []).
+%% We do peephole "bottom-up" (in reverse, but applying rules to the correctly
+%% ordered list). This way, we can do replacements that would take multiple
+%% passes with an in-order peephole optimiser.
+%%
+%% N.B., if a rule wants to produce multiple instructions (even if some of them
+%% are unchanged, it should push the additional instructions on the More list,
+%% so that only the top instruction on Insns is new or changed, i.e. tl(Insns)
+%% should have been peepholed previously.
+peep(RevInsns) ->
+ peep_list_skip([], RevInsns).
+
+peep_list([#b_label{'cond'='al',label=Label}
+ | (Insns = [#label{label=Label}|_])], More) ->
+ peep_list_skip(Insns, More);
+
+peep_list([#move{movop='mov',s=false,dst=#arm_temp{reg=Dst}
+ ,am1=#arm_temp{reg=Dst}}|Insns], More) ->
+ peep_list_skip(Insns, More);
+
+peep_list([#move{movop='mov',s=false,dst=Dst,am1={Src,lsr,Imm}},
+ #move{movop='mov',s=false,dst=Dst,am1={Dst,lsl,Imm}}
+ |Insns], More) when Imm > 0, Imm =< 8 ->
+ peep_list([#alu{aluop='bic',s=false,dst=Dst,src=Src,am1={(1 bsl Imm)-1,0}}
+ |Insns], More);
+peep_list([#move{movop='mov',s=false,dst=Dst,am1={Src,lsl,Imm}},
+ #move{movop='mov',s=false,dst=Dst,am1={Dst,lsr,Imm}}
+ |Insns], More) when Imm >= 24, Imm < 32 ->
+ peep_list([#alu{aluop='and',s=false,dst=Dst,src=Src
+ ,am1={(1 bsl (32-Imm))-1,0}} | Insns], More);
+
+%% XXX: Load-after-store optimisation should also be applied to RTL, where it
+%% can be more general, expose opportunities for constant propagation, etc.
+peep_list([#store{stop='strb',src=Src,am2=Mem}=Str,
+ #load {ldop='ldrb',dst=Dst,am2=Mem} | Insns], More) ->
+ peep_list([#alu{aluop='and',s=false,dst=Dst,src=Src,am1={16#ff,0}}|Insns],
+ [Str|More]);
+peep_list([#store{stop='str',src=Src,am2=Mem}=Str,
+ #load {ldop='ldr',dst=Dst,am2=Mem} | Insns], More) ->
+ peep_list([#move{movop='mov',s=false,dst=Dst,am1=Src}|Insns], [Str|More]);
+
+peep_list([#alu{aluop='and',s=false,dst=Dst,src=Src,am1={Mask,0}},
+ #alu{aluop='bic',s=false,dst=Dst,src=Dst,am1={InvMask,0}}
+ |Insns], More) ->
+ peep_list([#alu{aluop='and',s=false,dst=Dst,src=Src
+ ,am1={Mask band (bnot InvMask),0}} | Insns], More);
+
+%% XXX: The place that generates brain-dead code like the following should be
+%% fixed rather than trying to patch it over here.
+peep_list([#load{ldop='ldrb',dst=Dst,am2=_Mem},
+ #alu{aluop='bic',s=false,dst=Dst,src=Dst,am1={16#ff,0}}
+ | Insns], More) ->
+ peep_list([#move{movop='mov',s=false,dst=Dst,am1={0,0}}|Insns], More);
+
+peep_list(Insns, [I|More]) ->
+ peep_list([I|Insns], More);
+peep_list(Accum, []) ->
+ Accum.
-peep_list([#b_label{'cond'='al',label=Label} | (Insns = [#label{label=Label}|_])], Accum) ->
- peep_list(Insns, Accum);
-peep_list([I|Insns], Accum) ->
- peep_list(Insns, [I|Accum]);
-peep_list([], Accum) ->
- lists:reverse(Accum).
+%% Used as an optimisation instead of tailcalling peep_list/2 when Insns has
+%% already been peeped or is otherwise uninteresting (such as empty).
+peep_list_skip(Insns, [I|More]) ->
+ peep_list([I|Insns], More);
+peep_list_skip(Accum, []) ->
+ Accum.
diff --git a/lib/hipe/arm/hipe_arm_frame.erl b/lib/hipe/arm/hipe_arm_frame.erl
index e1e441a967..a1004fb609 100644
--- a/lib/hipe/arm/hipe_arm_frame.erl
+++ b/lib/hipe/arm/hipe_arm_frame.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_frame).
-export([frame/1]).
@@ -27,16 +20,14 @@
-define(LIVENESS_ALL, hipe_arm_liveness_gpr). % since we have no FP yet
-frame(Defun) ->
- Formals = fix_formals(hipe_arm:defun_formals(Defun)),
- Temps0 = all_temps(hipe_arm:defun_code(Defun), Formals),
- MinFrame = defun_minframe(Defun),
+frame(CFG) ->
+ Formals = fix_formals(hipe_arm_cfg:params(CFG)),
+ Temps0 = all_temps(CFG, Formals),
+ MinFrame = defun_minframe(CFG),
Temps = ensure_minframe(MinFrame, Temps0),
- ClobbersLR = clobbers_lr(hipe_arm:defun_code(Defun)),
- CFG0 = hipe_arm_cfg:init(Defun),
- Liveness = ?LIVENESS_ALL:analyse(CFG0),
- CFG1 = do_body(CFG0, Liveness, Formals, Temps, ClobbersLR),
- hipe_arm_cfg:linearise(CFG1).
+ ClobbersLR = clobbers_lr(CFG),
+ Liveness = ?LIVENESS_ALL:analyse(CFG),
+ do_body(CFG, Liveness, Formals, Temps, ClobbersLR).
fix_formals(Formals) ->
fix_formals(hipe_arm_registers:nr_args(), Formals).
@@ -51,32 +42,21 @@ do_body(CFG0, Liveness, Formals, Temps, ClobbersLR) ->
do_prologue(CFG1, Context).
do_blocks(CFG, Context) ->
- Labels = hipe_arm_cfg:labels(CFG),
- do_blocks(Labels, CFG, Context).
+ hipe_arm_cfg:map_bbs(fun(Lbl, BB) -> do_block(Lbl, BB, Context) end, CFG).
-do_blocks([Label|Labels], CFG, Context) ->
+do_block(Label, Block, Context) ->
Liveness = context_liveness(Context),
LiveOut = ?LIVENESS_ALL:liveout(Liveness, Label),
- Block = hipe_arm_cfg:bb(CFG, Label),
Code = hipe_bb:code(Block),
- NewCode = do_block(Code, LiveOut, Context),
- NewBlock = hipe_bb:code_update(Block, NewCode),
- NewCFG = hipe_arm_cfg:bb_add(CFG, Label, NewBlock),
- do_blocks(Labels, NewCFG, Context);
-do_blocks([], CFG, _) ->
- CFG.
-
-do_block(Insns, LiveOut, Context) ->
- do_block(Insns, LiveOut, Context, context_framesize(Context), []).
+ NewCode = do_block(Code, LiveOut, Context, context_framesize(Context), []),
+ hipe_bb:code_update(Block, NewCode).
do_block([I|Insns], LiveOut, Context, FPoff0, RevCode) ->
{NewIs, FPoff1} = do_insn(I, LiveOut, Context, FPoff0),
do_block(Insns, LiveOut, Context, FPoff1, lists:reverse(NewIs, RevCode));
do_block([], _, Context, FPoff, RevCode) ->
FPoff0 = context_framesize(Context),
- if FPoff =:= FPoff0 -> [];
- true -> exit({?MODULE,do_block,FPoff})
- end,
+ FPoff0 = FPoff,
lists:reverse(RevCode, []).
do_insn(I, LiveOut, Context, FPoff) ->
@@ -89,6 +69,8 @@ do_insn(I, LiveOut, Context, FPoff) ->
do_pseudo_call_prepare(I, FPoff);
#pseudo_move{} ->
{do_pseudo_move(I, Context, FPoff), FPoff};
+ #pseudo_spill_move{} ->
+ {do_pseudo_spill_move(I, Context, FPoff), FPoff};
#pseudo_tailcall{} ->
{do_pseudo_tailcall(I, Context), context_framesize(Context)};
_ ->
@@ -120,6 +102,26 @@ pseudo_offset(Temp, FPoff, Context) ->
FPoff + context_offset(Context, Temp).
%%%
+%%% Moves from one spill slot to another
+%%%
+
+do_pseudo_spill_move(I, Context, FPoff) ->
+ #pseudo_spill_move{dst=Dst, temp=Temp, src=Src} = I,
+ case temp_is_pseudo(Src) andalso temp_is_pseudo(Dst) of
+ false -> % Register allocator changed its mind, turn back to move
+ do_pseudo_move(hipe_arm:mk_pseudo_move(Dst, Src), Context, FPoff);
+ true ->
+ SrcOffset = pseudo_offset(Src, FPoff, Context),
+ DstOffset = pseudo_offset(Dst, FPoff, Context),
+ case SrcOffset =:= DstOffset of
+ true -> []; % omit move-to-self
+ false ->
+ mk_load('ldr', Temp, SrcOffset, mk_sp(),
+ mk_store('str', Temp, DstOffset, mk_sp(), []))
+ end
+ end.
+
+%%%
%%% Return - deallocate frame and emit 'ret $N' insn.
%%%
@@ -543,39 +545,46 @@ temp_is_pseudo(Temp) ->
%%% Detect if a Defun's body clobbers LR.
%%%
-clobbers_lr(Insns) ->
+clobbers_lr(CFG) ->
LRreg = hipe_arm_registers:lr(),
LRtagged = hipe_arm:mk_temp(LRreg, 'tagged'),
LRuntagged = hipe_arm:mk_temp(LRreg, 'untagged'),
- clobbers_lr(Insns, LRtagged, LRuntagged).
-
-clobbers_lr([I|Insns], LRtagged, LRuntagged) ->
- Defs = hipe_arm_defuse:insn_def_gpr(I),
- case lists:member(LRtagged, Defs) of
- true -> true;
- false ->
- case lists:member(LRuntagged, Defs) of
- true -> true;
- false -> clobbers_lr(Insns, LRtagged, LRuntagged)
- end
- end;
-clobbers_lr([], _LRtagged, _LRuntagged) -> false.
+ any_insn(fun(I) ->
+ Defs = hipe_arm_defuse:insn_def_gpr(I),
+ lists:member(LRtagged, Defs)
+ orelse lists:member(LRuntagged, Defs)
+ end, CFG).
+
+any_insn(Pred, CFG) ->
+ %% Abuse fold to do an efficient "any"-operation using nonlocal control flow
+ FoundSatisfying = make_ref(),
+ try fold_insns(fun (I, _) ->
+ case Pred(I) of
+ true -> throw(FoundSatisfying);
+ false -> false
+ end
+ end, false, CFG)
+ of _ -> false
+ catch FoundSatisfying -> true
+ end.
%%%
%%% Build the set of all temps used in a Defun's body.
%%%
-all_temps(Code, Formals) ->
- S0 = find_temps(Code, tset_empty()),
+all_temps(CFG, Formals) ->
+ S0 = fold_insns(fun find_temps/2, tset_empty(), CFG),
S1 = tset_del_list(S0, Formals),
tset_filter(S1, fun(T) -> temp_is_pseudo(T) end).
-find_temps([I|Insns], S0) ->
+find_temps(I, S0) ->
S1 = tset_add_list(S0, hipe_arm_defuse:insn_def_all(I)),
- S2 = tset_add_list(S1, hipe_arm_defuse:insn_use_all(I)),
- find_temps(Insns, S2);
-find_temps([], S) ->
- S.
+ tset_add_list(S1, hipe_arm_defuse:insn_use_all(I)).
+
+fold_insns(Fun, InitAcc, CFG) ->
+ hipe_arm_cfg:fold_bbs(
+ fun(_, BB, Acc0) -> lists:foldl(Fun, Acc0, hipe_bb:code(BB)) end,
+ InitAcc, CFG).
tset_empty() ->
gb_sets:new().
@@ -604,16 +613,11 @@ tset_to_list(S) ->
%%% in the middle of a tailcall.
%%%
-defun_minframe(Defun) ->
- MaxTailArity = body_mta(hipe_arm:defun_code(Defun), 0),
- MyArity = length(fix_formals(hipe_arm:defun_formals(Defun))),
+defun_minframe(CFG) ->
+ MaxTailArity = fold_insns(fun insn_mta/2, 0, CFG),
+ MyArity = length(fix_formals(hipe_arm_cfg:params(CFG))),
erlang:max(MaxTailArity - MyArity, 0).
-body_mta([I|Code], MTA) ->
- body_mta(Code, insn_mta(I, MTA));
-body_mta([], MTA) ->
- MTA.
-
insn_mta(I, MTA) ->
case I of
#pseudo_tailcall{arity=Arity} ->
diff --git a/lib/hipe/arm/hipe_arm_liveness_gpr.erl b/lib/hipe/arm/hipe_arm_liveness_gpr.erl
index 82cc5a7a67..ae845e5385 100644
--- a/lib/hipe/arm/hipe_arm_liveness_gpr.erl
+++ b/lib/hipe/arm/hipe_arm_liveness_gpr.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_liveness_gpr).
-export([analyse/1]).
diff --git a/lib/hipe/arm/hipe_arm_main.erl b/lib/hipe/arm/hipe_arm_main.erl
index dce1193b24..b87a300a9d 100644
--- a/lib/hipe/arm/hipe_arm_main.erl
+++ b/lib/hipe/arm/hipe_arm_main.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,24 +11,23 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_main).
-export([rtl_to_arm/3]).
rtl_to_arm(MFA, RTL, Options) ->
Defun1 = hipe_rtl_to_arm:translate(RTL),
+ CFG1 = hipe_arm_cfg:init(Defun1),
%% io:format("~w: after translate\n", [?MODULE]),
%% hipe_arm_pp:pp(Defun1),
- Defun2 = hipe_arm_ra:ra(Defun1, Options),
+ CFG2 = hipe_arm_ra:ra(CFG1, Options),
%% io:format("~w: after regalloc\n", [?MODULE]),
- %% hipe_arm_pp:pp(Defun2),
- Defun3 = hipe_arm_frame:frame(Defun2),
+ %% hipe_arm_pp:pp(hipe_arm_cfg:linearise(CFG2)),
+ CFG3 = hipe_arm_frame:frame(CFG2),
+ Defun3 = hipe_arm_cfg:linearise(CFG3),
%% io:format("~w: after frame\n", [?MODULE]),
%% hipe_arm_pp:pp(Defun3),
- Defun4 = hipe_arm_finalise:finalise(Defun3),
+ Defun4 = hipe_arm_finalise:finalise(Defun3, Options),
%% io:format("~w: after finalise\n", [?MODULE]),
pp(Defun4, MFA, Options),
{native, arm, {unprofiled, Defun4}}.
diff --git a/lib/hipe/arm/hipe_arm_pp.erl b/lib/hipe/arm/hipe_arm_pp.erl
index 18aca1fc6b..f49e998d06 100644
--- a/lib/hipe/arm/hipe_arm_pp.erl
+++ b/lib/hipe/arm/hipe_arm_pp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_pp).
-export([pp/1, pp/2, pp_insn/1]).
diff --git a/lib/hipe/arm/hipe_arm_ra.erl b/lib/hipe/arm/hipe_arm_ra.erl
index 2f65e864fd..b360fc05c4 100644
--- a/lib/hipe/arm/hipe_arm_ra.erl
+++ b/lib/hipe/arm/hipe_arm_ra.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,43 +11,44 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_ra).
-export([ra/2]).
-ra(Defun0, Options) ->
- %% hipe_arm_pp:pp(Defun0),
- {Defun1, Coloring_fp, SpillIndex}
+ra(CFG0, Options) ->
+ %% hipe_arm_pp:pp(hipe_arm_cfg:linearise(CFG0)),
+ {CFG1, _FPLiveness1, Coloring_fp, SpillIndex}
= case proplists:get_bool(inline_fp, Options) of
%% true ->
-%% hipe_regalloc_loop:ra_fp(Defun0, Options,
+%% FPLiveness0 = hipe_arm_specific_fp:analyze(CFG0, no_context),
+%% hipe_regalloc_loop:ra_fp(CFG0, FPLiveness0, Options,
%% hipe_coalescing_regalloc,
-%% hipe_arm_specific_fp);
+%% hipe_arm_specific_fp, no_context);
false ->
- {Defun0,[],0}
+ {CFG0,undefined,[],0}
end,
- %% hipe_arm_pp:pp(Defun1),
- {Defun2, Coloring}
+ %% hipe_arm_pp:pp(hipe_arm_cfg:linearise(CFG1)),
+ GPLiveness1 = hipe_arm_specific:analyze(CFG1, no_context),
+ {CFG2, _GPLiveness2, Coloring}
= case proplists:get_value(regalloc, Options, coalescing) of
coalescing ->
- ra(Defun1, SpillIndex, Options, hipe_coalescing_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options, hipe_coalescing_regalloc);
optimistic ->
- ra(Defun1, SpillIndex, Options, hipe_optimistic_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options, hipe_optimistic_regalloc);
graph_color ->
- ra(Defun1, SpillIndex, Options, hipe_graph_coloring_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options,
+ hipe_graph_coloring_regalloc);
linear_scan ->
- hipe_arm_ra_ls:ra(Defun1, SpillIndex, Options);
+ hipe_arm_ra_ls:ra(CFG1, GPLiveness1, SpillIndex, Options);
naive ->
- hipe_arm_ra_naive:ra(Defun1, Coloring_fp, Options);
+ hipe_arm_ra_naive:ra(CFG1, GPLiveness1, Coloring_fp, Options);
_ ->
exit({unknown_regalloc_compiler_option,
proplists:get_value(regalloc,Options)})
end,
- %% hipe_arm_pp:pp(Defun2),
- hipe_arm_ra_finalise:finalise(Defun2, Coloring, Coloring_fp).
+ %% hipe_arm_pp:pp(hipe_arm_cfg:linearise(CFG2)),
+ hipe_arm_ra_finalise:finalise(CFG2, Coloring, Coloring_fp).
-ra(Defun, SpillIndex, Options, RegAllocMod) ->
- hipe_regalloc_loop:ra(Defun, SpillIndex, Options, RegAllocMod, hipe_arm_specific).
+ra(CFG, Liveness, SpillIndex, Options, RegAllocMod) ->
+ hipe_regalloc_loop:ra(CFG, Liveness, SpillIndex, Options, RegAllocMod,
+ hipe_arm_specific, no_context).
diff --git a/lib/hipe/arm/hipe_arm_ra_finalise.erl b/lib/hipe/arm/hipe_arm_ra_finalise.erl
index 4faeadcd7f..80cd470708 100644
--- a/lib/hipe/arm/hipe_arm_ra_finalise.erl
+++ b/lib/hipe/arm/hipe_arm_ra_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,27 +11,31 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_ra_finalise).
-export([finalise/3]).
-include("hipe_arm.hrl").
-finalise(Defun, TempMap, _FPMap0=[]) ->
- Code = hipe_arm:defun_code(Defun),
- {_, SpillLimit} = hipe_arm:defun_var_range(Defun),
+finalise(CFG, TempMap, _FPMap0=[]) ->
+ {_, SpillLimit} = hipe_gensym:var_range(arm),
Map = mk_ra_map(TempMap, SpillLimit),
- NewCode = ra_code(Code, Map, []),
- Defun#defun{code=NewCode}.
+ hipe_arm_cfg:map_bbs(fun(_Lbl, BB) -> ra_bb(BB, Map) end, CFG).
+
+ra_bb(BB, Map) ->
+ hipe_bb:code_update(BB, ra_code(hipe_bb:code(BB), Map, [])).
ra_code([I|Insns], Map, Accum) ->
- ra_code(Insns, Map, [ra_insn(I, Map) | Accum]);
+ ra_code(Insns, Map, ra_insn(I, Map, Accum));
ra_code([], _Map, Accum) ->
lists:reverse(Accum).
-ra_insn(I, Map) ->
+ra_insn(I, Map, Accum) ->
+ case I of
+ #pseudo_move{} -> ra_pseudo_move(I, Map, Accum);
+ _ -> [ra_insn_1(I, Map) | Accum]
+ end.
+
+ra_insn_1(I, Map) ->
case I of
#alu{} -> ra_alu(I, Map);
#cmp{} -> ra_cmp(I, Map);
@@ -44,7 +44,7 @@ ra_insn(I, Map) ->
#move{} -> ra_move(I, Map);
#pseudo_call{} -> ra_pseudo_call(I, Map);
#pseudo_li{} -> ra_pseudo_li(I, Map);
- #pseudo_move{} -> ra_pseudo_move(I, Map);
+ #pseudo_spill_move{} -> ra_pseudo_spill_move(I, Map);
#pseudo_switch{} -> ra_pseudo_switch(I, Map);
#pseudo_tailcall{} -> ra_pseudo_tailcall(I, Map);
#smull{} -> ra_smull(I, Map);
@@ -86,10 +86,19 @@ ra_pseudo_li(I=#pseudo_li{dst=Dst}, Map) ->
NewDst = ra_temp(Dst, Map),
I#pseudo_li{dst=NewDst}.
-ra_pseudo_move(I=#pseudo_move{dst=Dst,src=Src}, Map) ->
+ra_pseudo_move(I=#pseudo_move{dst=Dst,src=Src}, Map, Accum) ->
+ NewDst = ra_temp(Dst, Map),
+ NewSrc = ra_temp(Src, Map),
+ case NewSrc#arm_temp.reg =:= NewDst#arm_temp.reg of
+ true -> Accum;
+ false -> [I#pseudo_move{dst=NewDst,src=NewSrc} | Accum]
+ end.
+
+ra_pseudo_spill_move(I=#pseudo_spill_move{dst=Dst,temp=Temp,src=Src}, Map) ->
NewDst = ra_temp(Dst, Map),
+ NewTemp = ra_temp(Temp, Map),
NewSrc = ra_temp(Src, Map),
- I#pseudo_move{dst=NewDst,src=NewSrc}.
+ I#pseudo_spill_move{dst=NewDst, temp=NewTemp, src=NewSrc}.
ra_pseudo_switch(I=#pseudo_switch{jtab=JTab,index=Index}, Map) ->
NewJTab = ra_temp(JTab, Map),
diff --git a/lib/hipe/arm/hipe_arm_ra_ls.erl b/lib/hipe/arm/hipe_arm_ra_ls.erl
index d9a360d00c..bbb75f9c55 100644
--- a/lib/hipe/arm/hipe_arm_ra_ls.erl
+++ b/lib/hipe/arm/hipe_arm_ra_ls.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,43 +11,39 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Linear Scan register allocator for ARM
-module(hipe_arm_ra_ls).
--export([ra/3]).
+-export([ra/4]).
-ra(Defun, SpillIndex, Options) ->
- NewDefun = Defun, %% hipe_${ARCH}_ra_rename:rename(Defun,Options),
- CFG = hipe_arm_cfg:init(NewDefun),
- SpillLimit = hipe_arm_specific:number_of_temporaries(CFG),
- alloc(NewDefun, SpillIndex, SpillLimit, Options).
+ra(CFG, Liveness, SpillIndex, Options) ->
+ SpillLimit = hipe_arm_specific:number_of_temporaries(CFG, no_context),
+ alloc(CFG, Liveness, SpillIndex, SpillLimit, Options).
-alloc(Defun, SpillIndex, SpillLimit, Options) ->
- CFG = hipe_arm_cfg:init(Defun),
+alloc(CFG, Liveness, SpillIndex, SpillLimit, Options) ->
{Coloring, _NewSpillIndex} =
regalloc(
- CFG,
+ CFG, Liveness,
hipe_arm_registers:allocatable_gpr()--
[hipe_arm_registers:temp3(),
hipe_arm_registers:temp2(),
hipe_arm_registers:temp1()],
[hipe_arm_cfg:start_label(CFG)],
SpillIndex, SpillLimit, Options,
- hipe_arm_specific),
- {NewDefun, _DidSpill} =
+ hipe_arm_specific, no_context),
+ {NewCFG, _DidSpill} =
hipe_arm_ra_postconditions:check_and_rewrite(
- Defun, Coloring, 'linearscan'),
- TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_arm_specific),
+ CFG, Coloring, 'linearscan'),
+ TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_arm_specific, no_context),
{SpillMap, _NewSpillIndex2} =
- hipe_spillmin:stackalloc(CFG, [], SpillIndex, Options,
- hipe_arm_specific, TempMap),
+ hipe_spillmin:stackalloc(CFG, Liveness, [], SpillIndex, Options,
+ hipe_arm_specific, no_context, TempMap),
Coloring2 =
hipe_spillmin:mapmerge(hipe_temp_map:to_substlist(TempMap), SpillMap),
- {NewDefun, Coloring2}.
+ {NewCFG, Liveness, Coloring2}.
-regalloc(CFG, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options, Target) ->
- hipe_ls_regalloc:regalloc(
- CFG, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options, Target).
+regalloc(CFG, Liveness, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options,
+ TgtMod, TgtCtx) ->
+ hipe_ls_regalloc:regalloc(CFG, Liveness, PhysRegs, Entrypoints, SpillIndex,
+ DontSpill, Options, TgtMod, TgtCtx).
diff --git a/lib/hipe/arm/hipe_arm_ra_naive.erl b/lib/hipe/arm/hipe_arm_ra_naive.erl
index 6201269f44..e3fe9877ad 100644
--- a/lib/hipe/arm/hipe_arm_ra_naive.erl
+++ b/lib/hipe/arm/hipe_arm_ra_naive.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,16 +11,13 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_ra_naive).
--export([ra/3]).
+-export([ra/4]).
-include("hipe_arm.hrl").
-ra(Defun, _Coloring_fp, _Options) -> % -> {Defun, Coloring}
- {NewDefun,_DidSpill} =
- hipe_arm_ra_postconditions:check_and_rewrite2(Defun, [], 'naive'),
- {NewDefun, []}.
+ra(CFG, Liveness, _Coloring_fp, _Options) -> % -> {CFG, Liveness, Coloring}
+ {NewCFG,_DidSpill} =
+ hipe_arm_ra_postconditions:check_and_rewrite2(CFG, [], 'naive'),
+ {NewCFG, Liveness, []}.
diff --git a/lib/hipe/arm/hipe_arm_ra_postconditions.erl b/lib/hipe/arm/hipe_arm_ra_postconditions.erl
index 40978e65f6..23c305511f 100644
--- a/lib/hipe/arm/hipe_arm_ra_postconditions.erl
+++ b/lib/hipe/arm/hipe_arm_ra_postconditions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_ra_postconditions).
@@ -25,17 +18,13 @@
-include("hipe_arm.hrl").
-check_and_rewrite(Defun, Coloring, Allocator) ->
- TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_arm_specific),
- check_and_rewrite2(Defun, TempMap, Allocator).
+check_and_rewrite(CFG, Coloring, Allocator) ->
+ TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_arm_specific, no_context),
+ check_and_rewrite2(CFG, TempMap, Allocator).
-check_and_rewrite2(Defun, TempMap, Allocator) ->
+check_and_rewrite2(CFG, TempMap, Allocator) ->
Strategy = strategy(Allocator),
- #defun{code=Code0} = Defun,
- {Code1,DidSpill} = do_insns(Code0, TempMap, Strategy, [], false),
- VarRange = {0, hipe_gensym:get_var(arm)},
- {Defun#defun{code=Code1, var_range=VarRange},
- DidSpill}.
+ do_bbs(hipe_arm_cfg:labels(CFG), TempMap, Strategy, CFG, false).
strategy(Allocator) ->
case Allocator of
@@ -44,6 +33,13 @@ strategy(Allocator) ->
'naive' -> 'fixed'
end.
+do_bbs([], _, _, CFG, DidSpill) -> {CFG, DidSpill};
+do_bbs([Lbl|Lbls], TempMap, Strategy, CFG0, DidSpill0) ->
+ Code0 = hipe_bb:code(BB = hipe_arm_cfg:bb(CFG0, Lbl)),
+ {Code, DidSpill} = do_insns(Code0, TempMap, Strategy, [], DidSpill0),
+ CFG = hipe_arm_cfg:bb_add(CFG0, Lbl, hipe_bb:code_update(BB, Code)),
+ do_bbs(Lbls, TempMap, Strategy, CFG, DidSpill).
+
do_insns([I|Insns], TempMap, Strategy, Accum, DidSpill0) ->
{NewIs, DidSpill1} = do_insn(I, TempMap, Strategy),
do_insns(Insns, TempMap, Strategy, lists:reverse(NewIs, Accum), DidSpill0 or DidSpill1);
@@ -60,6 +56,7 @@ do_insn(I, TempMap, Strategy) ->
#pseudo_call{} -> do_pseudo_call(I, TempMap, Strategy);
#pseudo_li{} -> do_pseudo_li(I, TempMap, Strategy);
#pseudo_move{} -> do_pseudo_move(I, TempMap, Strategy);
+ #pseudo_spill_move{} -> do_pseudo_spill_move(I, TempMap, Strategy);
#pseudo_switch{} -> do_pseudo_switch(I, TempMap, Strategy);
#pseudo_tailcall{} -> do_pseudo_tailcall(I, TempMap, Strategy);
#smull{} -> do_smull(I, TempMap, Strategy);
@@ -112,18 +109,25 @@ do_pseudo_li(I=#pseudo_li{dst=Dst}, TempMap, Strategy) ->
do_pseudo_move(I=#pseudo_move{dst=Dst,src=Src}, TempMap, Strategy) ->
%% Either Dst or Src (but not both) may be a pseudo temp.
- %% pseudo_move and pseudo_tailcall are special cases: in
- %% all other instructions, all temps must be non-pseudos
- %% after register allocation.
- case temp_is_spilled(Dst, TempMap) of
- true -> % Src must not be a pseudo
- {FixSrc,NewSrc,DidSpill} = fix_src1(Src, TempMap, Strategy),
- NewI = I#pseudo_move{src=NewSrc},
- {FixSrc ++ [NewI], DidSpill};
+ %% pseudo_move, pseudo_spill_move, and pseudo_tailcall
+ %% are special cases: in all other instructions, all
+ %% temps must be non-pseudos after register allocation.
+ case temp_is_spilled(Dst, TempMap)
+ andalso temp_is_spilled(Dst, TempMap)
+ of
+ true -> % Turn into pseudo_spill_move
+ Temp = clone(Src, temp1(Strategy)),
+ NewI = #pseudo_spill_move{dst=Dst, temp=Temp, src=Src},
+ {[NewI], true};
_ ->
{[I], false}
end.
+do_pseudo_spill_move(I = #pseudo_spill_move{temp=Temp}, TempMap, _Strategy) ->
+ %% Temp is above the low water mark and must not have been spilled
+ false = temp_is_spilled(Temp, TempMap),
+ {[I], false}. % nothing to do
+
do_pseudo_switch(I=#pseudo_switch{jtab=JTab,index=Index}, TempMap, Strategy) ->
{FixJTab,NewJTab,DidSpill1} = fix_src1(JTab, TempMap, Strategy),
{FixIndex,NewIndex,DidSpill2} = fix_src2(Index, TempMap, Strategy),
diff --git a/lib/hipe/arm/hipe_arm_registers.erl b/lib/hipe/arm/hipe_arm_registers.erl
index 24cd929d41..59545c2e64 100644
--- a/lib/hipe/arm/hipe_arm_registers.erl
+++ b/lib/hipe/arm/hipe_arm_registers.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_registers).
@@ -67,6 +60,8 @@
-define(R15, 15).
-define(LAST_PRECOLOURED, 15). % must handle both GPR and FPR ranges
+-define(LR, ?R14).
+
-define(ARG0, ?R1).
-define(ARG1, ?R2).
-define(ARG2, ?R3).
@@ -114,7 +109,7 @@ stack_pointer() -> ?STACK_POINTER.
proc_pointer() -> ?PROC_POINTER.
-lr() -> ?R14.
+lr() -> ?LR.
pc() -> ?R15.
@@ -178,6 +173,8 @@ is_arg(R) ->
_ -> false
end.
+%% Note: the fact that allocatable_gpr() is a subset of call_clobbered() is
+%% hard-coded in hipe_arm_defuse:insn_defs_all_gpr/1
call_clobbered() -> % does the RA strip the type or not?
[{?R0,tagged},{?R0,untagged},
{?R1,tagged},{?R1,untagged},
@@ -198,7 +195,9 @@ call_clobbered() -> % does the RA strip the type or not?
].
tailcall_clobbered() -> % tailcall crapola needs one temp
- [{?TEMP1,tagged},{?TEMP1,untagged}].
+ [{?TEMP1,tagged},{?TEMP1,untagged}
+ ,{?LR,tagged},{?LR,untagged}
+ ].
live_at_return() ->
[%%{?LR,untagged},
diff --git a/lib/hipe/arm/hipe_arm_subst.erl b/lib/hipe/arm/hipe_arm_subst.erl
new file mode 100644
index 0000000000..4ff245f414
--- /dev/null
+++ b/lib/hipe/arm/hipe_arm_subst.erl
@@ -0,0 +1,127 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+-module(hipe_arm_subst).
+-export([insn_temps/2, insn_lbls/2]).
+-include("hipe_arm.hrl").
+
+%% These should be moved to hipe_arm and exported
+-type temp() :: #arm_temp{}.
+-type shiftop() :: lsl | lsr | asr | ror.
+-type imm4() :: 0..15.
+-type imm5() :: 0..31.
+-type imm8() :: 0..255.
+-type am1() :: {imm8(),imm4()}
+ | temp()
+ | {temp(), rrx}
+ | {temp(), shiftop(), imm5()}
+ | {temp(), shiftop(), temp()}.
+-type am2() :: #am2{}.
+-type am3() :: #am3{}.
+-type arg() :: temp() | integer().
+-type funv() :: #arm_mfa{} | #arm_prim{} | temp().
+-type label() :: non_neg_integer().
+-type insn() :: tuple(). % for now
+
+-type subst_fun() :: fun((temp()) -> temp()).
+
+%% @doc Maps over the temporaries in an instruction
+-spec insn_temps(subst_fun(), insn()) -> insn().
+insn_temps(T, I) ->
+ AM1 = fun(O) -> am1_temps(T, O) end,
+ AM2 = fun(O) -> am2_temps(T, O) end,
+ AM3 = fun(O) -> am3_temps(T, O) end,
+ Arg = fun(O) -> arg_temps(T, O) end,
+ case I of
+ #alu {dst=D,src=L,am1=R} -> I#alu{dst=T(D),src=T(L),am1=AM1(R)};
+ #cmp {src=L,am1=R} -> I#cmp {src=T(L),am1=AM1(R)};
+ #load {dst=D,am2=S} -> I#load {dst=T(D),am2=AM2(S)};
+ #ldrsb {dst=D,am3=S} -> I#ldrsb {dst=T(D),am3=AM3(S)};
+ #move {dst=D,am1=S} -> I#move {dst=T(D),am1=AM1(S)};
+ #pseudo_move{dst=D,src=S} -> I#pseudo_move {dst=T(D),src=T(S)};
+ #store {src=S,am2=D} -> I#store {src=T(S),am2=AM2(D)};
+ #b_label{} -> I;
+ #comment{} -> I;
+ #label{} -> I;
+ #pseudo_bc{} -> I;
+ #pseudo_blr{} -> I;
+ #pseudo_call{funv=F} -> I#pseudo_call{funv=funv_temps(T, F)};
+ #pseudo_call_prepare{} -> I;
+ #pseudo_li{dst=D} -> I#pseudo_li{dst=T(D)};
+ #pseudo_spill_move{dst=D,temp=U,src=S} ->
+ I#pseudo_spill_move{dst=T(D),temp=T(U),src=T(S)};
+ #pseudo_switch{jtab=J=#arm_temp{},index=Ix=#arm_temp{}} ->
+ I#pseudo_switch{jtab=T(J),index=T(Ix)};
+ #pseudo_tailcall{funv=F,stkargs=Stk} ->
+ I#pseudo_tailcall{funv=funv_temps(T,F),stkargs=lists:map(Arg,Stk)};
+ #pseudo_tailcall_prepare{} -> I;
+ #smull{dstlo=DL,dsthi=DH,src1=L,src2=R} ->
+ I#smull{dstlo=T(DL),dsthi=T(DH),src1=T(L),src2=T(R)}
+ end.
+
+-spec am1_temps(subst_fun(), am1()) -> am1().
+am1_temps(_SubstTemp, T={C,R}) when is_integer(C), is_integer(R) -> T;
+am1_temps(SubstTemp, T=#arm_temp{}) -> SubstTemp(T);
+am1_temps(SubstTemp, {T=#arm_temp{},rrx}) -> {SubstTemp(T),rrx};
+am1_temps(SubstTemp, {A=#arm_temp{},Op,B=#arm_temp{}}) when is_atom(Op) ->
+ {SubstTemp(A),Op,SubstTemp(B)};
+am1_temps(SubstTemp, {T=#arm_temp{},Op,I}) when is_atom(Op), is_integer(I) ->
+ {SubstTemp(T),Op,I}.
+
+-spec am2_temps(subst_fun(), am2()) -> am2().
+am2_temps(SubstTemp, T=#am2{src=A=#arm_temp{},offset=O0}) ->
+ O = case O0 of
+ _ when is_integer(O0) -> O0;
+ #arm_temp{} -> SubstTemp(O0);
+ {B=#arm_temp{},rrx} -> {SubstTemp(B),rrx};
+ {B=#arm_temp{},Op,I} when is_atom(Op), is_integer(I) ->
+ {SubstTemp(B),Op,I}
+ end,
+ T#am2{src=SubstTemp(A),offset=O}.
+
+-spec am3_temps(subst_fun(), am3()) -> am3().
+am3_temps(SubstTemp, T=#am3{src=A=#arm_temp{},offset=O0}) ->
+ O = case O0 of
+ _ when is_integer(O0) -> O0;
+ #arm_temp{} -> SubstTemp(O0)
+ end,
+ T#am3{src=SubstTemp(A),offset=O}.
+
+-spec funv_temps(subst_fun(), funv()) -> funv().
+funv_temps(_SubstTemp, M=#arm_mfa{}) -> M;
+funv_temps(_SubstTemp, P=#arm_prim{}) -> P;
+funv_temps(SubstTemp, T=#arm_temp{}) -> SubstTemp(T).
+
+-spec arg_temps(subst_fun(), arg()) -> arg().
+arg_temps(_SubstTemp, Imm) when is_integer(Imm) -> Imm;
+arg_temps(SubstTemp, T=#arm_temp{}) -> SubstTemp(T).
+
+-type lbl_subst_fun() :: fun((label()) -> label()).
+
+%% @doc Maps over the branch targets in an instruction
+-spec insn_lbls(lbl_subst_fun(), insn()) -> insn().
+insn_lbls(SubstLbl, I) ->
+ case I of
+ #b_label{label=Label} ->
+ I#b_label{label=SubstLbl(Label)};
+ #pseudo_bc{true_label=T, false_label=F} ->
+ I#pseudo_bc{true_label=SubstLbl(T), false_label=SubstLbl(F)};
+ #pseudo_call{sdesc=Sdesc, contlab=Contlab} ->
+ I#pseudo_call{sdesc=sdesc_lbls(SubstLbl, Sdesc),
+ contlab=SubstLbl(Contlab)}
+ end.
+
+sdesc_lbls(_SubstLbl, Sdesc=#arm_sdesc{exnlab=[]}) -> Sdesc;
+sdesc_lbls(SubstLbl, Sdesc=#arm_sdesc{exnlab=Exnlab}) ->
+ Sdesc#arm_sdesc{exnlab=SubstLbl(Exnlab)}.
diff --git a/lib/hipe/arm/hipe_rtl_to_arm.erl b/lib/hipe/arm/hipe_rtl_to_arm.erl
index ad5a559995..59e0a79b0d 100644
--- a/lib/hipe/arm/hipe_rtl_to_arm.erl
+++ b/lib/hipe/arm/hipe_rtl_to_arm.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_rtl_to_arm).
-export([translate/1]).
@@ -62,7 +55,6 @@ conv_insn(I, Map, Data) ->
case I of
#alu{} -> conv_alu(I, Map, Data);
#alub{} -> conv_alub(I, Map, Data);
- #branch{} -> conv_branch(I, Map, Data);
#call{} -> conv_call(I, Map, Data);
#comment{} -> conv_comment(I, Map, Data);
#enter{} -> conv_enter(I, Map, Data);
@@ -111,6 +103,17 @@ commute_arithop(ArithOp) ->
_ -> ArithOp
end.
+conv_cmpop('add') -> 'cmn';
+conv_cmpop('sub') -> 'cmp';
+conv_cmpop('and') -> 'tst';
+conv_cmpop('xor') -> 'teq';
+conv_cmpop(_) -> none.
+
+cmpop_commutes('cmp') -> false;
+cmpop_commutes('cmn') -> true;
+cmpop_commutes('tst') -> true;
+cmpop_commutes('teq') -> true.
+
mk_alu(S, Dst, Src1, RtlAluOp, Src2) ->
case hipe_rtl:is_shift_op(RtlAluOp) of
true ->
@@ -138,7 +141,6 @@ mk_shift(S, Dst, Src1, ShiftOp, Src2) ->
end.
mk_shift_ii(S, Dst, Src1, ShiftOp, Src2) ->
- io:format("~w: RTL alu with two immediates\n", [?MODULE]),
Tmp = new_untagged_temp(),
mk_li(Tmp, Src1,
mk_shift_ri(S, Dst, Tmp, ShiftOp, Src2)).
@@ -148,10 +150,11 @@ mk_shift_ir(S, Dst, Src1, ShiftOp, Src2) ->
mk_li(Tmp, Src1,
mk_shift_rr(S, Dst, Tmp, ShiftOp, Src2)).
-mk_shift_ri(S, Dst, Src1, ShiftOp, Src2) when is_integer(Src2) ->
- if Src2 >= 0, Src2 < 32 -> ok;
- true -> io:format("~w: excessive immediate shift ~w\n", [?MODULE,Src2])
- end,
+mk_shift_ri(S, Dst, Src1, ShiftOp, 0)
+ when ShiftOp =:= lsl; ShiftOp =:= lsr; ShiftOp =:= asr ->
+ [hipe_arm:mk_move(S, Dst, Src1)];
+mk_shift_ri(S, Dst, Src1, ShiftOp, Src2)
+ when is_integer(Src2), Src2 > 0, Src2 < 32 ->
Am1 = {Src1,ShiftOp,Src2},
[hipe_arm:mk_move(S, Dst, Am1)].
@@ -178,7 +181,6 @@ mk_arith(S, Dst, Src1, ArithOp, Src2) ->
end.
mk_arith_ii(S, Dst, Src1, ArithOp, Src2) ->
- io:format("~w: RTL alu with two immediates\n", [?MODULE]),
Tmp = new_untagged_temp(),
mk_li(Tmp, Src1,
mk_arith_ri(S, Dst, Tmp, ArithOp, Src2)).
@@ -224,72 +226,77 @@ fix_aluop_imm(AluOp, Imm) -> % {FixAm1,NewAluOp,Am1}
conv_alub(I, Map, Data) ->
%% dst = src1 aluop src2; if COND goto label
- {Dst, Map0} = conv_dst(hipe_rtl:alub_dst(I), Map),
- {Src1, Map1} = conv_src(hipe_rtl:alub_src1(I), Map0),
- {Src2, Map2} = conv_src(hipe_rtl:alub_src2(I), Map1),
+ {Src1, Map0} = conv_src(hipe_rtl:alub_src1(I), Map),
+ {Src2, Map1} = conv_src(hipe_rtl:alub_src2(I), Map0),
RtlAluOp = hipe_rtl:alub_op(I),
- Cond0 = conv_alub_cond(RtlAluOp, hipe_rtl:alub_cond(I)),
- Cond =
- case {RtlAluOp,Cond0} of
- {'mul','vs'} -> 'ne'; % overflow becomes not-equal
- {'mul','vc'} -> 'eq'; % no-overflow becomes equal
- {'mul',_} -> exit({?MODULE,I});
- {_,_} -> Cond0
- end,
- I2 = mk_pseudo_bc(
- Cond,
- hipe_rtl:alub_true_label(I),
- hipe_rtl:alub_false_label(I),
- hipe_rtl:alub_pred(I)),
- S = true,
- I1 = mk_alu(S, Dst, Src1, RtlAluOp, Src2),
- {I1 ++ I2, Map2, Data}.
-
-conv_branch(I, Map, Data) ->
- %% <unused> = src1 - src2; if COND goto label
- {Src1, Map0} = conv_src(hipe_rtl:branch_src1(I), Map),
- {Src2, Map1} = conv_src(hipe_rtl:branch_src2(I), Map0),
- Cond = conv_branch_cond(hipe_rtl:branch_cond(I)),
- I2 = mk_branch(Src1, Cond, Src2,
- hipe_rtl:branch_true_label(I),
- hipe_rtl:branch_false_label(I),
- hipe_rtl:branch_pred(I)),
- {I2, Map1, Data}.
+ RtlCond = hipe_rtl:alub_cond(I),
+ HasDst = hipe_rtl:alub_has_dst(I),
+ CmpOp = conv_cmpop(RtlAluOp),
+ Cond0 = conv_alub_cond(RtlAluOp, RtlCond),
+ case (not HasDst) andalso CmpOp =/= none of
+ true ->
+ I1 = mk_branch(Src1, CmpOp, Src2, Cond0,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I)),
+ {I1, Map1, Data};
+ false ->
+ {Dst, Map2} =
+ case HasDst of
+ false -> {new_untagged_temp(), Map1};
+ true -> conv_dst(hipe_rtl:alub_dst(I), Map1)
+ end,
+ Cond =
+ case {RtlAluOp,Cond0} of
+ {'mul','vs'} -> 'ne'; % overflow becomes not-equal
+ {'mul','vc'} -> 'eq'; % no-overflow becomes equal
+ {'mul',_} -> exit({?MODULE,I});
+ {_,_} -> Cond0
+ end,
+ I2 = mk_pseudo_bc(
+ Cond,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I)),
+ S = true,
+ I1 = mk_alu(S, Dst, Src1, RtlAluOp, Src2),
+ {I1 ++ I2, Map2, Data}
+ end.
-mk_branch(Src1, Cond, Src2, TrueLab, FalseLab, Pred) ->
+mk_branch(Src1, CmpOp, Src2, Cond, TrueLab, FalseLab, Pred) ->
case hipe_arm:is_temp(Src1) of
true ->
case hipe_arm:is_temp(Src2) of
true ->
- mk_branch_rr(Src1, Src2, Cond, TrueLab, FalseLab, Pred);
+ mk_branch_rr(Src1, CmpOp, Src2, Cond, TrueLab, FalseLab, Pred);
_ ->
- mk_branch_ri(Src1, Cond, Src2, TrueLab, FalseLab, Pred)
+ mk_branch_ri(Src1, CmpOp, Src2, Cond, TrueLab, FalseLab, Pred)
end;
_ ->
case hipe_arm:is_temp(Src2) of
true ->
- NewCond = commute_cond(Cond),
- mk_branch_ri(Src2, NewCond, Src1, TrueLab, FalseLab, Pred);
+ NewCond =
+ case cmpop_commutes(CmpOp) of
+ true -> Cond;
+ false -> commute_cond(Cond)
+ end,
+ mk_branch_ri(Src2, CmpOp, Src1, NewCond, TrueLab, FalseLab, Pred);
_ ->
- mk_branch_ii(Src1, Cond, Src2, TrueLab, FalseLab, Pred)
+ mk_branch_ii(Src1, CmpOp, Src2, Cond, TrueLab, FalseLab, Pred)
end
end.
-mk_branch_ii(Imm1, Cond, Imm2, TrueLab, FalseLab, Pred) ->
- io:format("~w: RTL branch with two immediates\n", [?MODULE]),
+mk_branch_ii(Imm1, CmpOp, Imm2, Cond, TrueLab, FalseLab, Pred) ->
Tmp = new_untagged_temp(),
mk_li(Tmp, Imm1,
- mk_branch_ri(Tmp, Cond, Imm2,
+ mk_branch_ri(Tmp, CmpOp, Imm2, Cond,
TrueLab, FalseLab, Pred)).
-mk_branch_ri(Src, Cond, Imm, TrueLab, FalseLab, Pred) ->
- {FixAm1,NewCmpOp,Am1} = fix_aluop_imm('cmp', Imm),
- FixAm1 ++ mk_cmp_bc(NewCmpOp, Src, Am1, Cond, TrueLab, FalseLab, Pred).
-
-mk_branch_rr(Src1, Src2, Cond, TrueLab, FalseLab, Pred) ->
- mk_cmp_bc('cmp', Src1, Src2, Cond, TrueLab, FalseLab, Pred).
+mk_branch_ri(Src, CmpOp, Imm, Cond, TrueLab, FalseLab, Pred) ->
+ {FixAm1,NewCmpOp,Am1} = fix_aluop_imm(CmpOp, Imm),
+ FixAm1 ++ mk_branch_rr(Src, NewCmpOp, Am1, Cond, TrueLab, FalseLab, Pred).
-mk_cmp_bc(CmpOp, Src, Am1, Cond, TrueLab, FalseLab, Pred) ->
+mk_branch_rr(Src, CmpOp, Am1, Cond, TrueLab, FalseLab, Pred) ->
[hipe_arm:mk_cmp(CmpOp, Src, Am1) |
mk_pseudo_bc(Cond, TrueLab, FalseLab, Pred)].
@@ -471,7 +478,6 @@ mk_load(Dst, Base1, Base2, LoadSize, LoadSign) ->
end.
mk_load_ii(Dst, Base1, Base2, LdOp) ->
- io:format("~w: RTL load with two immediates\n", [?MODULE]),
Tmp = new_untagged_temp(),
mk_li(Tmp, Base1,
mk_load_ri(Dst, Tmp, Base2, LdOp)).
@@ -484,7 +490,6 @@ mk_load_rr(Dst, Base1, Base2, LdOp) ->
[hipe_arm:mk_load(LdOp, Dst, Am2)].
mk_ldrsb_ii(Dst, Base1, Base2) ->
- io:format("~w: RTL load signed byte with two immediates\n", [?MODULE]),
Tmp = new_untagged_temp(),
mk_li(Tmp, Base1,
mk_ldrsb_ri(Dst, Tmp, Base2)).
@@ -542,7 +547,7 @@ conv_return(I, Map, Data) ->
{I2, Map0, Data}.
conv_store(I, Map, Data) ->
- {Base, Map0} = conv_dst(hipe_rtl:store_base(I), Map),
+ {Base, Map0} = conv_src(hipe_rtl:store_base(I), Map),
{Src, Map1} = conv_src(hipe_rtl:store_src(I), Map0),
{Offset, Map2} = conv_src(hipe_rtl:store_offset(I), Map1),
StoreSize = hipe_rtl:store_size(I),
@@ -566,13 +571,28 @@ mk_store(Src, Base, Offset, StoreSize) ->
end.
mk_store2(Src, Base, Offset, StOp) ->
- case hipe_arm:is_temp(Offset) of
+ case hipe_arm:is_temp(Base) of
true ->
- mk_store_rr(Src, Base, Offset, StOp);
- _ ->
- mk_store_ri(Src, Base, Offset, StOp)
+ case hipe_arm:is_temp(Offset) of
+ true ->
+ mk_store_rr(Src, Base, Offset, StOp);
+ _ ->
+ mk_store_ri(Src, Base, Offset, StOp)
+ end;
+ false ->
+ case hipe_arm:is_temp(Offset) of
+ true ->
+ mk_store_ri(Src, Offset, Base, StOp);
+ _ ->
+ mk_store_ii(Src, Base, Offset, StOp)
+ end
end.
-
+
+mk_store_ii(Src, Base, Offset, StOp) ->
+ Tmp = new_untagged_temp(),
+ mk_li(Tmp, Base,
+ mk_store_ri(Src, Tmp, Offset, StOp)).
+
mk_store_ri(Src, Base, Offset, StOp) ->
hipe_arm:mk_store(StOp, Src, Base, Offset, 'new', []).
@@ -626,6 +646,7 @@ conv_alub_cond(RtlAluOp, Cond) -> % may be unsigned, depends on aluop
case {RtlAluOp, Cond} of % handle allowed alub unsigned conditions
{'add', 'ltu'} -> 'hs'; % add+ltu == unsigned overflow == carry set == hs
%% add more cases when needed
+ {'sub', _} -> conv_branch_cond(Cond);
_ -> conv_cond(Cond)
end.
diff --git a/lib/hipe/cerl/cerl_cconv.erl b/lib/hipe/cerl/cerl_cconv.erl
index ac9d01ab0e..122e6ef039 100644
--- a/lib/hipe/cerl/cerl_cconv.erl
+++ b/lib/hipe/cerl/cerl_cconv.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,11 +9,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-%% @author Richard Carlsson <[email protected]>
%% @copyright 2000-2004 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Closure conversion of Core Erlang modules. This is done as a
%% step in the translation from Core Erlang down to HiPE Icode, and is
%% very much tied to the calling conventions used in HiPE native code.
diff --git a/lib/hipe/cerl/cerl_closurean.erl b/lib/hipe/cerl/cerl_closurean.erl
index d37c91e5c6..a2bd7fe0f0 100644
--- a/lib/hipe/cerl/cerl_closurean.erl
+++ b/lib/hipe/cerl/cerl_closurean.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,15 +10,9 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% =====================================================================
-%% Closure analysis of Core Erlang programs.
-%%
-%% Copyright (C) 2001-2002 Richard Carlsson
-%%
-%% Author contact: [email protected]
-%% =====================================================================
+%% @copyright 2001-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
+%% @doc Closure analysis of Core Erlang programs.
%% TODO: might need a "top" (`any') element for any-length value lists.
diff --git a/lib/hipe/cerl/cerl_hipe_primops.hrl b/lib/hipe/cerl/cerl_hipe_primops.hrl
index 3efb9a3bdd..6e4d830b61 100644
--- a/lib/hipe/cerl/cerl_hipe_primops.hrl
+++ b/lib/hipe/cerl/cerl_hipe_primops.hrl
@@ -1,9 +1,3 @@
-%% ========================-*-erlang-*-=================================
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,15 +9,10 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%% Predefined Core Erlang primitive operations used by HiPE
-%%
-%% Copyright (C) 2000 Richard Carlsson
%%
-%% Author contact: [email protected]
-%% =====================================================================
+%% @copyright 2000 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
+%% @doc Predefined Core Erlang primitive operations used by HiPE.
%% These definitions give the names of Core Erlang primops recognized by
%% HiPE. Many of them (e.g., 'not'/'and'/'or', and the type tests), are
diff --git a/lib/hipe/cerl/cerl_hipeify.erl b/lib/hipe/cerl/cerl_hipeify.erl
index 6611abd204..137a54ba32 100644
--- a/lib/hipe/cerl/cerl_hipeify.erl
+++ b/lib/hipe/cerl/cerl_hipeify.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,11 +9,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-%% @author Richard Carlsson <[email protected]>
%% @copyright 2000-2004 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc HiPE-ification of Core Erlang code. Prepares Core Erlang code
%% for translation to ICode.
%% @see cerl_to_icode
diff --git a/lib/hipe/cerl/cerl_lib.erl b/lib/hipe/cerl/cerl_lib.erl
index 0bc77909d9..3a6fb1cf51 100644
--- a/lib/hipe/cerl/cerl_lib.erl
+++ b/lib/hipe/cerl/cerl_lib.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,10 +9,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-
+%% @copyright 1999-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Utility functions for Core Erlang abstract syntax trees.
%%
%% <p>Syntax trees are defined in the module <a
diff --git a/lib/hipe/cerl/cerl_messagean.erl b/lib/hipe/cerl/cerl_messagean.erl
index 7df0a245fb..c79e045bd0 100644
--- a/lib/hipe/cerl/cerl_messagean.erl
+++ b/lib/hipe/cerl/cerl_messagean.erl
@@ -1,8 +1,3 @@
-%% =====================================================================
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,14 +10,9 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% Message analysis of Core Erlang programs.
-%%
-%% Copyright (C) 2002 Richard Carlsson
-%%
-%% Author contact: [email protected]
-%% =====================================================================
+%% @copyright 2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
+%% @doc Message analysis of Core Erlang programs.
%% TODO: might need a "top" (`any') element for any-length value lists.
diff --git a/lib/hipe/cerl/cerl_pmatch.erl b/lib/hipe/cerl/cerl_pmatch.erl
index ca27fff1dd..fd7f589f08 100644
--- a/lib/hipe/cerl/cerl_pmatch.erl
+++ b/lib/hipe/cerl/cerl_pmatch.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,11 +9,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-%% @author Richard Carlsson <[email protected]>
%% @copyright 2000-2006 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%%
%% @doc Core Erlang pattern matching compiler.
%%
diff --git a/lib/hipe/cerl/cerl_prettypr.erl b/lib/hipe/cerl/cerl_prettypr.erl
index f0acab99e3..c1c7250bbd 100644
--- a/lib/hipe/cerl/cerl_prettypr.erl
+++ b/lib/hipe/cerl/cerl_prettypr.erl
@@ -1,8 +1,3 @@
-%% =====================================================================
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,16 +9,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%% Core Erlang prettyprinter, using the 'prettypr' module.
-%%
-%% Copyright (C) 1999-2002 Richard Carlsson
-%%
-%% Author contact: [email protected]
-%% =====================================================================
%%
+%% @copyright 1999-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Core Erlang prettyprinter.
%%
%% <p>This module is a front end to the pretty-printing library module
diff --git a/lib/hipe/cerl/cerl_to_icode.erl b/lib/hipe/cerl/cerl_to_icode.erl
index ab131c2d01..e37eae8a03 100644
--- a/lib/hipe/cerl/cerl_to_icode.erl
+++ b/lib/hipe/cerl/cerl_to_icode.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 4 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,11 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-%% @author Richard Carlsson <[email protected]>
%% @copyright 2000-2006 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Translation from Core Erlang to HiPE Icode.
%% TODO: annotate Icode leaf functions as such.
@@ -2627,7 +2621,7 @@ icode_switch_val(Arg, Fail, Length, Cases) ->
hipe_icode:mk_switch_val(Arg, Fail, Length, Cases).
icode_switch_tuple_arity(Arg, Fail, Length, Cases) ->
- SortedCases = lists:keysort(1, Cases), %% immitate BEAM compiler - Kostis
+ SortedCases = lists:keysort(1, Cases), %% imitate BEAM compiler - Kostis
hipe_icode:mk_switch_tuple_arity(Arg, Fail, Length, SortedCases).
diff --git a/lib/hipe/cerl/cerl_typean.erl b/lib/hipe/cerl/cerl_typean.erl
index ddc48c7915..c5d84bdf2b 100644
--- a/lib/hipe/cerl/cerl_typean.erl
+++ b/lib/hipe/cerl/cerl_typean.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 4 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,15 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%% Type analysis of Core Erlang programs.
-%%
-%% Copyright (C) 2001-2002 Richard Carlsson
-%%
-%% Author contact: [email protected]
%%
+%% @copyright 2001-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Type analysis of Core Erlang programs.
%% TODO: filters must handle conjunctions for better precision!
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 9453ca6c6f..a3a936322a 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,16 +12,12 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% =====================================================================
-%% Type information for Erlang Built-in functions (implemented in C)
-%%
-%% Copyright (C) 2002 Richard Carlsson
-%% Copyright (C) 2006 Richard Carlsson, Tobias Lindahl and Kostis Sagonas
-%%
-%% =====================================================================
+%% @doc Type information for Erlang Built-in functions (implemented in C)
+%% @copyright 2002 Richard Carlsson, 2006 Richard Carlsson, Tobias Lindahl
+%% and Kostis Sagonas
+%% @author Richard Carlsson <[email protected]>
+%% @author Tobias Lindahl <[email protected]>
+%% @author Kostis Sagonas <[email protected]>
-module(erl_bif_types).
@@ -124,7 +116,7 @@
t_map_entries/2,
t_map_put/3,
t_map_update/3,
- map_pairwise_merge/3
+ t_map_pairwise_merge/4
]).
-ifdef(DO_ERL_BIF_TYPES_TEST).
@@ -560,6 +552,9 @@ type(erlang, byte_size, 1, Xs, Opaques) ->
strict(erlang, byte_size, 1, Xs,
fun (_) -> t_non_neg_integer() end, Opaques);
%% Guard bif, needs to be here.
+type(erlang, ceil, 1, Xs, Opaques) ->
+ strict(erlang, ceil, 1, Xs, fun (_) -> t_integer() end, Opaques);
+%% Guard bif, needs to be here.
%% Also much more expressive than anything you could write in a spec...
type(erlang, element, 2, Xs, Opaques) ->
strict(erlang, element, 2, Xs,
@@ -588,6 +583,9 @@ type(erlang, element, 2, Xs, Opaques) ->
type(erlang, float, 1, Xs, Opaques) ->
strict(erlang, float, 1, Xs, fun (_) -> t_float() end, Opaques);
%% Guard bif, needs to be here.
+type(erlang, floor, 1, Xs, Opaques) ->
+ strict(erlang, floor, 1, Xs, fun (_) -> t_integer() end, Opaques);
+%% Guard bif, needs to be here.
type(erlang, hd, 1, Xs, Opaques) ->
strict(erlang, hd, 1, Xs, fun ([X]) -> t_cons_hd(X) end, Opaques);
type(erlang, info, 1, Xs, _) -> type(erlang, system_info, 1, Xs); % alias
@@ -997,9 +995,9 @@ type(erlang, tuple_to_list, 1, Xs, Opaques) ->
end, Opaques);
%%-- hipe_bifs ----------------------------------------------------------------
type(hipe_bifs, add_ref, 2, Xs, Opaques) ->
- strict(hipe_bifs, add_ref, 2, Xs, fun (_) -> t_nil() end, Opaques);
-type(hipe_bifs, alloc_data, 2, Xs, Opaques) ->
- strict(hipe_bifs, alloc_data, 2, Xs,
+ strict(hipe_bifs, add_ref, 2, Xs, fun (_) -> t_atom('ok') end, Opaques);
+type(hipe_bifs, alloc_data, 3, Xs, Opaques) ->
+ strict(hipe_bifs, alloc_data, 3, Xs,
fun (_) -> t_integer() end, Opaques); % address
type(hipe_bifs, array, 2, Xs, Opaques) ->
strict(hipe_bifs, array, 2, Xs, fun (_) -> t_immarray() end, Opaques);
@@ -1046,16 +1044,16 @@ type(hipe_bifs, call_count_on, 1, Xs, Opaques) ->
fun (_) -> t_sup(t_atom('true'), t_nil()) end, Opaques);
type(hipe_bifs, check_crc, 1, Xs, Opaques) ->
strict(hipe_bifs, check_crc, 1, Xs, fun (_) -> t_boolean() end, Opaques);
-type(hipe_bifs, enter_code, 2, Xs, Opaques) ->
- strict(hipe_bifs, enter_code, 2, Xs,
+type(hipe_bifs, enter_code, 3, Xs, Opaques) ->
+ strict(hipe_bifs, enter_code, 3, Xs,
fun (_) -> t_tuple([t_integer(),
%% XXX: The tuple below contains integers and
%% is of size same as the length of the MFA list
t_sup(t_nil(), t_binary())]) end, Opaques);
-type(hipe_bifs, enter_sdesc, 1, Xs, Opaques) ->
- strict(hipe_bifs, enter_sdesc, 1, Xs, fun (_) -> t_nil() end, Opaques);
-type(hipe_bifs, find_na_or_make_stub, 2, Xs, Opaques) ->
- strict(hipe_bifs, find_na_or_make_stub, 2, Xs,
+type(hipe_bifs, enter_sdesc, 2, Xs, Opaques) ->
+ strict(hipe_bifs, enter_sdesc, 2, Xs, fun (_) -> t_nil() end, Opaques);
+type(hipe_bifs, find_na_or_make_stub, 1, Xs, Opaques) ->
+ strict(hipe_bifs, find_na_or_make_stub, 1, Xs,
fun (_) -> t_integer() end, Opaques); % address
type(hipe_bifs, fun_to_address, 1, Xs, Opaques) ->
strict(hipe_bifs, fun_to_address, 1, Xs,
@@ -1065,12 +1063,6 @@ type(hipe_bifs, get_fe, 2, Xs, Opaques) ->
type(hipe_bifs, get_rts_param, 1, Xs, Opaques) ->
strict(hipe_bifs, get_rts_param, 1, Xs,
fun (_) -> t_sup(t_integer(), t_nil()) end, Opaques);
-type(hipe_bifs, invalidate_funinfo_native_addresses, 1, Xs, Opaques) ->
- strict(hipe_bifs, invalidate_funinfo_native_addresses, 1, Xs,
- fun (_) -> t_nil() end, Opaques);
-type(hipe_bifs, mark_referred_from, 1, Xs, Opaques) ->
- strict(hipe_bifs, mark_referred_from, 1, Xs,
- fun (_) -> t_nil() end, Opaques);
type(hipe_bifs, merge_term, 1, Xs, Opaques) ->
strict(hipe_bifs, merge_term, 1, Xs, fun ([X]) -> X end, Opaques);
type(hipe_bifs, nstack_used_size, 0, _, _Opaques) ->
@@ -1082,21 +1074,18 @@ type(hipe_bifs, patch_insn, 3, Xs, Opaques) ->
type(hipe_bifs, primop_address, 1, Xs, Opaques) ->
strict(hipe_bifs, primop_address, 1, Xs,
fun (_) -> t_sup(t_integer(), t_atom('false')) end, Opaques);
-type(hipe_bifs, redirect_referred_from, 1, Xs, Opaques) ->
- strict(hipe_bifs, redirect_referred_from, 1, Xs,
- fun (_) -> t_nil() end, Opaques);
type(hipe_bifs, ref, 1, Xs, Opaques) ->
strict(hipe_bifs, ref, 1, Xs, fun (_) -> t_immarray() end, Opaques);
type(hipe_bifs, ref_get, 1, Xs, Opaques) ->
strict(hipe_bifs, ref_get, 1, Xs, fun (_) -> t_immediate() end, Opaques);
type(hipe_bifs, ref_set, 2, Xs, Opaques) ->
strict(hipe_bifs, ref_set, 2, Xs, fun (_) -> t_nil() end, Opaques);
-type(hipe_bifs, remove_refs_from, 1, Xs, Opaques) ->
- strict(hipe_bifs, remove_refs_from, 1, Xs,
- fun (_) -> t_atom('ok') end, Opaques);
type(hipe_bifs, set_funinfo_native_address, 3, Xs, Opaques) ->
strict(hipe_bifs, set_funinfo_native_address, 3, Xs,
fun (_) -> t_nil() end, Opaques);
+type(hipe_bifs, commit_patch_load, 1, Xs, Opaques) ->
+ strict(hipe_bifs, commit_patch_load, 1, Xs,
+ fun (_) -> t_atom() end, Opaques);
type(hipe_bifs, set_native_address, 3, Xs, Opaques) ->
strict(hipe_bifs, set_native_address, 3, Xs,
fun (_) -> t_nil() end, Opaques);
@@ -1108,15 +1097,14 @@ type(hipe_bifs, system_crc, 0, _, _Opaques) ->
type(hipe_bifs, term_to_word, 1, Xs, Opaques) ->
strict(hipe_bifs, term_to_word, 1, Xs,
fun (_) -> t_integer() end, Opaques);
-type(hipe_bifs, update_code_size, 3, Xs, Opaques) ->
- strict(hipe_bifs, update_code_size, 3, Xs,
- fun (_) -> t_nil() end, Opaques);
type(hipe_bifs, write_u8, 2, Xs, Opaques) ->
strict(hipe_bifs, write_u8, 2, Xs, fun (_) -> t_nil() end, Opaques);
type(hipe_bifs, write_u32, 2, Xs, Opaques) ->
strict(hipe_bifs, write_u32, 2, Xs, fun (_) -> t_nil() end, Opaques);
type(hipe_bifs, write_u64, 2, Xs, Opaques) ->
strict(hipe_bifs, write_u64, 2, Xs, fun (_) -> t_nil() end, Opaques);
+type(hipe_bifs, alloc_loader_state, 1, Xs, Opaques) ->
+ strict(hipe_bifs, alloc_loader_state, 1, Xs, fun (_) -> t_binary() end, Opaques);
%%-- lists --------------------------------------------------------------------
type(lists, all, 2, Xs, Opaques) ->
strict(lists, all, 2, Xs,
@@ -1689,10 +1677,10 @@ type(maps, merge, 2, Xs, Opaques) ->
BDefK = t_map_def_key(MapB, Opaques),
ADefV = t_map_def_val(MapA, Opaques),
BDefV = t_map_def_val(MapB, Opaques),
- t_map(map_pairwise_merge(
+ t_map(t_map_pairwise_merge(
fun(K, _, _, mandatory, V) -> {K, mandatory, V};
(K, MNess, VA, optional, VB) -> {K, MNess, t_sup(VA,VB)}
- end, MapA, MapB),
+ end, MapA, MapB, Opaques),
t_sup(ADefK, BDefK), t_sup(ADefV, BDefV))
end, Opaques);
type(maps, put, 3, Xs, Opaques) ->
@@ -2038,17 +2026,14 @@ arith_rem(Min1, Max1, Min2, Max2) ->
Min1_geq_zero = infinity_geq(Min1, 0),
Max1_leq_zero = infinity_geq(0, Max1),
Max_range2 = infinity_max([infinity_abs(Min2), infinity_abs(Max2)]),
- Max_range2_leq_zero = infinity_geq(0, Max_range2),
- New_min =
+ New_min =
if Min1_geq_zero -> 0;
Max_range2 =:= 0 -> 0;
- Max_range2_leq_zero -> infinity_add(Max_range2, 1);
true -> infinity_add(infinity_inv(Max_range2), 1)
end,
New_max =
if Max1_leq_zero -> 0;
Max_range2 =:= 0 -> 0;
- Max_range2_leq_zero -> infinity_add(infinity_inv(Max_range2), -1);
true -> infinity_add(Max_range2, -1)
end,
{New_min, New_max}.
@@ -2341,6 +2326,9 @@ arg_types(erlang, bit_size, 1) ->
%% Guard bif, needs to be here.
arg_types(erlang, byte_size, 1) ->
[t_bitstr()];
+%% Guard bif, needs to be here.
+arg_types(erlang, ceil, 1) ->
+ [t_number()];
arg_types(erlang, halt, 0) ->
[];
arg_types(erlang, halt, 1) ->
@@ -2361,6 +2349,9 @@ arg_types(erlang, element, 2) ->
arg_types(erlang, float, 1) ->
[t_number()];
%% Guard bif, needs to be here.
+arg_types(erlang, floor, 1) ->
+ [t_number()];
+%% Guard bif, needs to be here.
arg_types(erlang, hd, 1) ->
[t_cons()];
arg_types(erlang, info, 1) ->
@@ -2458,9 +2449,9 @@ arg_types(hipe_bifs, add_ref, 2) ->
t_integer(),
t_sup(t_atom('call'), t_atom('load_mfa')),
t_trampoline(),
- t_sup(t_atom('remote'), t_atom('local'))])];
-arg_types(hipe_bifs, alloc_data, 2) ->
- [t_integer(), t_integer()];
+ t_binary()])];
+arg_types(hipe_bifs, alloc_data, 3) ->
+ [t_integer(), t_integer(), t_binary()];
arg_types(hipe_bifs, array, 2) ->
[t_non_neg_fixnum(), t_immediate()];
arg_types(hipe_bifs, array_length, 1) ->
@@ -2495,22 +2486,19 @@ arg_types(hipe_bifs, call_count_on, 1) ->
[t_mfa()];
arg_types(hipe_bifs, check_crc, 1) ->
[t_crc32()];
-arg_types(hipe_bifs, enter_code, 2) ->
- [t_binary(), t_sup(t_nil(), t_tuple())];
-arg_types(hipe_bifs, enter_sdesc, 1) ->
- [t_tuple([t_integer(), t_integer(), t_integer(), t_integer(), t_integer(), t_mfa()])];
-arg_types(hipe_bifs, find_na_or_make_stub, 2) ->
- [t_mfa(), t_boolean()];
+arg_types(hipe_bifs, enter_code, 3) ->
+ [t_binary(), t_sup(t_nil(), t_tuple()), t_binary()];
+arg_types(hipe_bifs, enter_sdesc, 2) ->
+ [t_tuple([t_integer(), t_integer(), t_integer(), t_integer(), t_integer(), t_mfa()]),
+ t_binary()];
+arg_types(hipe_bifs, find_na_or_make_stub, 1) ->
+ [t_mfa()];
arg_types(hipe_bifs, fun_to_address, 1) ->
[t_mfa()];
arg_types(hipe_bifs, get_fe, 2) ->
[t_atom(), t_tuple([t_integer(), t_integer(), t_integer()])];
arg_types(hipe_bifs, get_rts_param, 1) ->
[t_fixnum()];
-arg_types(hipe_bifs, invalidate_funinfo_native_addresses, 1) ->
- [t_list(t_mfa())];
-arg_types(hipe_bifs, mark_referred_from, 1) ->
- [t_mfa()];
arg_types(hipe_bifs, merge_term, 1) ->
[t_any()];
arg_types(hipe_bifs, nstack_used_size, 0) ->
@@ -2521,18 +2509,16 @@ arg_types(hipe_bifs, patch_insn, 3) ->
[t_integer(), t_integer(), t_insn_type()];
arg_types(hipe_bifs, primop_address, 1) ->
[t_atom()];
-arg_types(hipe_bifs, redirect_referred_from, 1) ->
- [t_mfa()];
arg_types(hipe_bifs, ref, 1) ->
[t_immediate()];
arg_types(hipe_bifs, ref_get, 1) ->
[t_hiperef()];
arg_types(hipe_bifs, ref_set, 2) ->
[t_hiperef(), t_immediate()];
-arg_types(hipe_bifs, remove_refs_from, 1) ->
- [t_sup([t_mfa(), t_atom('all')])];
arg_types(hipe_bifs, set_funinfo_native_address, 3) ->
arg_types(hipe_bifs, set_native_address, 3);
+arg_types(hipe_bifs, commit_patch_load, 1) ->
+ [t_binary()];
arg_types(hipe_bifs, set_native_address, 3) ->
[t_mfa(), t_integer(), t_boolean()];
arg_types(hipe_bifs, set_native_address_in_fe, 2) ->
@@ -2541,14 +2527,15 @@ arg_types(hipe_bifs, system_crc, 0) ->
[];
arg_types(hipe_bifs, term_to_word, 1) ->
[t_any()];
-arg_types(hipe_bifs, update_code_size, 3) ->
- [t_atom(), t_sup(t_nil(), t_binary()), t_integer()];
arg_types(hipe_bifs, write_u8, 2) ->
[t_integer(), t_byte()];
arg_types(hipe_bifs, write_u32, 2) ->
[t_integer(), t_integer()];
arg_types(hipe_bifs, write_u64, 2) ->
[t_integer(), t_integer()];
+arg_types(hipe_bifs, alloc_loader_state, 1) ->
+ [t_atom()];
+
%%------- lists ---------------------------------------------------------------
arg_types(lists, all, 2) ->
[t_fun([t_any()], t_boolean()), t_list()];
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 7826dada9d..0883a69918 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,14 +12,13 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% ======================================================================
-%% Copyright (C) 2000-2003 Richard Carlsson
-%%
-%% ======================================================================
-%% Provides a representation of Erlang types.
-%%
+%% @copyright 2000-2003 Richard Carlsson, 2006-2009 Tobias Lindahl
+%% @author Richard Carlsson <[email protected]>
+%% @author Tobias Lindahl <[email protected]>
+%% @author Kostis Sagonas <[email protected]>
+%% @author Manouk Manoukian
+%% @doc Provides a representation of Erlang types.
+
%% The initial author of this file is Richard Carlsson (2000-2004).
%% In July 2006, the type representation was totally re-designed by
%% Tobias Lindahl. This is the representation which is used currently.
@@ -31,9 +26,6 @@
%% opaque types to the structure-based representation of types.
%% During February and March 2009, Kostis Sagonas significantly
%% cleaned up the type representation and added spec declarations.
-%%
-%% ======================================================================
-module(erl_types).
@@ -159,6 +151,7 @@
t_map_get/2, t_map_get/3,
t_map_is_key/2, t_map_is_key/3,
t_map_update/2, t_map_update/3,
+ t_map_pairwise_merge/4,
t_map_put/2, t_map_put/3,
t_matchstate/0,
t_matchstate/2,
@@ -219,8 +212,7 @@
is_erl_type/1,
atom_to_string/1,
var_table__new/0,
- cache__new/0,
- map_pairwise_merge/3
+ cache__new/0
]).
%%-define(DO_ERL_TYPES_TEST, true).
@@ -236,7 +228,8 @@
-export([t_is_identifier/1]).
-endif.
--export_type([erl_type/0, opaques/0, type_table/0, var_table/0, cache/0]).
+-export_type([erl_type/0, opaques/0, type_table/0,
+ var_table/0, cache/0]).
%%-define(DEBUG, true).
@@ -373,14 +366,17 @@
-type opaques() :: [erl_type()] | 'universe'.
+-type file_line() :: {file:name(), erl_anno:line()}.
-type record_key() :: {'record', atom()}.
-type type_key() :: {'type' | 'opaque', mfa()}.
--type record_value() :: [{atom(), erl_parse:abstract_expr(), erl_type()}].
--type type_value() :: {{module(), {file:name(), erl_anno:line()},
+-type field() :: {atom(), erl_parse:abstract_expr(), erl_type()}.
+-type record_value() :: {file_line(),
+ [{RecordSize :: non_neg_integer(), [field()]}]}.
+-type type_value() :: {{module(), file_line(),
erl_parse:abstract_type(), ArgNames :: [atom()]},
erl_type()}.
--type type_table() :: dict:dict(record_key() | type_key(),
- record_value() | type_value()).
+-type type_table() :: #{record_key() | type_key() =>
+ record_value() | type_value()}.
-opaque var_table() :: #{atom() => erl_type()}.
@@ -494,9 +490,9 @@ t_contains_opaque(?function(Domain, Range), Opaques) ->
t_contains_opaque(Domain, Opaques)
orelse t_contains_opaque(Range, Opaques);
t_contains_opaque(?identifier(_Types), _Opaques) -> false;
-t_contains_opaque(?integer(_Types), _Opaques) -> false;
t_contains_opaque(?int_range(_From, _To), _Opaques) -> false;
t_contains_opaque(?int_set(_Set), _Opaques) -> false;
+t_contains_opaque(?integer(_Types), _Opaques) -> false;
t_contains_opaque(?list(Type, Tail, _), Opaques) ->
t_contains_opaque(Type, Opaques) orelse t_contains_opaque(Tail, Opaques);
t_contains_opaque(?map(_, _, _) = Map, Opaques) ->
@@ -524,7 +520,8 @@ list_contains_opaque(List, Opaques) ->
lists:any(fun(E) -> t_contains_opaque(E, Opaques) end, List).
%% t_find_opaque_mismatch/2 of two types should only be used if their
-%% t_inf is t_none() due to some opaque type violation.
+%% t_inf is t_none() due to some opaque type violation. However,
+%% 'error' is returned if a structure mismatch is found.
%%
%% The first argument of the function is the pattern and its second
%% argument the type we are matching against the pattern.
@@ -533,22 +530,32 @@ list_contains_opaque(List, Opaques) ->
'error' | {'ok', erl_type(), erl_type()}.
t_find_opaque_mismatch(T1, T2, Opaques) ->
- t_find_opaque_mismatch(T1, T2, T2, Opaques).
+ try t_find_opaque_mismatch(T1, T2, T2, Opaques)
+ catch throw:error -> error
+ end.
t_find_opaque_mismatch(?any, _Type, _TopType, _Opaques) -> error;
-t_find_opaque_mismatch(?none, _Type, _TopType, _Opaques) -> error;
+t_find_opaque_mismatch(?none, _Type, _TopType, _Opaques) -> throw(error);
t_find_opaque_mismatch(?list(T1, Tl1, _), ?list(T2, Tl2, _), TopType, Opaques) ->
t_find_opaque_mismatch_ordlists([T1, Tl1], [T2, Tl2], TopType, Opaques);
t_find_opaque_mismatch(T1, ?opaque(_) = T2, TopType, Opaques) ->
case is_opaque_type(T2, Opaques) of
- false -> {ok, TopType, T2};
+ false ->
+ case t_is_opaque(T1) andalso compatible_opaque_types(T1, T2) =/= [] of
+ true -> error;
+ false -> {ok, TopType, T2}
+ end;
true ->
t_find_opaque_mismatch(T1, t_opaque_structure(T2), TopType, Opaques)
end;
t_find_opaque_mismatch(?opaque(_) = T1, T2, TopType, Opaques) ->
%% The generated message is somewhat misleading:
case is_opaque_type(T1, Opaques) of
- false -> {ok, TopType, T1};
+ false ->
+ case t_is_opaque(T2) andalso compatible_opaque_types(T1, T2) =/= [] of
+ true -> error;
+ false -> {ok, TopType, T1}
+ end;
true ->
t_find_opaque_mismatch(t_opaque_structure(T1), T2, TopType, Opaques)
end;
@@ -564,7 +571,11 @@ t_find_opaque_mismatch(?tuple(_, _, _) = T1, ?tuple_set(_) = T2,
t_find_opaque_mismatch_lists(Tuples1, Tuples2, TopType, Opaques);
t_find_opaque_mismatch(T1, ?union(U2), TopType, Opaques) ->
t_find_opaque_mismatch_lists([T1], U2, TopType, Opaques);
-t_find_opaque_mismatch(_T1, _T2, _TopType, _Opaques) -> error.
+t_find_opaque_mismatch(T1, T2, _TopType, Opaques) ->
+ case t_is_none(t_inf(T1, T2, Opaques)) of
+ false -> error;
+ true -> throw(error)
+ end.
t_find_opaque_mismatch_ordlists(L1, L2, TopType, Opaques) ->
List = lists:zipwith(fun(T1, T2) ->
@@ -573,10 +584,12 @@ t_find_opaque_mismatch_ordlists(L1, L2, TopType, Opaques) ->
t_find_opaque_mismatch_list(List).
t_find_opaque_mismatch_lists(L1, L2, _TopType, Opaques) ->
- List = [t_find_opaque_mismatch(T1, T2, T2, Opaques) || T1 <- L1, T2 <- L2],
+ List = [try t_find_opaque_mismatch(T1, T2, T2, Opaques)
+ catch throw:error -> error
+ end || T1 <- L1, T2 <- L2],
t_find_opaque_mismatch_list(List).
-t_find_opaque_mismatch_list([]) -> error;
+t_find_opaque_mismatch_list([]) -> throw(error);
t_find_opaque_mismatch_list([H|T]) ->
case H of
{ok, _T1, _T2} -> H;
@@ -603,7 +616,9 @@ t_find_unknown_opaque(T1, T2, Opaques) ->
%% is assumed to be taken from the contract.
t_decorate_with_opaque(T1, T2, Opaques) ->
- case t_is_equal(T1, T2) orelse not t_contains_opaque(T2) of
+ case
+ Opaques =:= [] orelse t_is_equal(T1, T2) orelse not t_contains_opaque(T2)
+ of
true -> T1;
false ->
T = t_inf(T1, T2),
@@ -611,9 +626,13 @@ t_decorate_with_opaque(T1, T2, Opaques) ->
false -> T1;
true ->
R = decorate(T1, T, Opaques),
- ?debug(case catch t_is_equal(t_unopaque(R), t_unopaque(T1)) of
- true -> ok;
- false ->
+ ?debug(case catch
+ not t_is_equal(t_unopaque(R), t_unopaque(T1))
+ orelse
+ t_is_equal(T1, T) andalso not t_is_equal(T1, R)
+ of
+ false -> ok;
+ _ ->
io:format("T1 = ~p,\n", [T1]),
io:format("T2 = ~p,\n", [T2]),
io:format("O = ~p,\n", [Opaques]),
@@ -642,7 +661,6 @@ decorate(?tuple_set(List), ?tuple_set(L), Opaques) ->
decorate(?union(List), T, Opaques) when T =/= ?any ->
?union(L) = force_union(T),
union_decorate(List, L, Opaques);
-decorate(?opaque(_)=T, _, _Opaques) -> T;
decorate(T, ?union(L), Opaques) when T =/= ?any ->
?union(List) = force_union(T),
union_decorate(List, L, Opaques);
@@ -656,7 +674,7 @@ decorate_with_opaque(Type, ?opaque(Set2), Opaques) ->
case decoration(set_to_list(Set2), Type, Opaques, [], false) of
{[], false} -> Type;
{List, All} when List =/= [] ->
- NewType = ?opaque(ordsets:from_list(List)),
+ NewType = sup_opaque(List),
case All of
true -> NewType;
false -> t_sup(NewType, Type)
@@ -670,9 +688,10 @@ decoration([#opaque{struct = S} = Opaque|OpaqueTypes], Type, Opaques,
case not IsOpaque orelse t_is_none(I) of
true -> decoration(OpaqueTypes, Type, Opaques, NewOpaqueTypes0, All);
false ->
- NewOpaque = Opaque#opaque{struct = decorate(I, S, Opaques)},
+ NewI = decorate(I, S, Opaques),
+ NewOpaque = combine(NewI, [Opaque]),
NewAll = All orelse t_is_equal(I, Type),
- NewOpaqueTypes = [NewOpaque|NewOpaqueTypes0],
+ NewOpaqueTypes = NewOpaque ++ NewOpaqueTypes0,
decoration(OpaqueTypes, Type, Opaques, NewOpaqueTypes, NewAll)
end;
decoration([], _Type, _Opaques, NewOpaqueTypes, All) ->
@@ -745,16 +764,16 @@ decorate_tuples_in_sets([], _L, _Opaques, Acc) ->
-spec t_opaque_from_records(type_table()) -> [erl_type()].
-t_opaque_from_records(RecDict) ->
- OpaqueRecDict =
- dict:filter(fun(Key, _Value) ->
+t_opaque_from_records(RecMap) ->
+ OpaqueRecMap =
+ maps:filter(fun(Key, _Value) ->
case Key of
{opaque, _Name, _Arity} -> true;
_ -> false
end
- end, RecDict),
- OpaqueTypeDict =
- dict:map(fun({opaque, Name, _Arity},
+ end, RecMap),
+ OpaqueTypeMap =
+ maps:map(fun({opaque, Name, _Arity},
{{Module, _FileLine, _Form, ArgNames}, _Type}) ->
%% Args = args_to_types(ArgNames),
%% List = lists:zip(ArgNames, Args),
@@ -763,8 +782,8 @@ t_opaque_from_records(RecDict) ->
Rep = t_any(), % not used for anything right now
Args = [t_any() || _ <- ArgNames],
t_opaque(Module, Name, Args, Rep)
- end, OpaqueRecDict),
- [OpaqueType || {_Key, OpaqueType} <- dict:to_list(OpaqueTypeDict)].
+ end, OpaqueRecMap),
+ [OpaqueType || {_Key, OpaqueType} <- maps:to_list(OpaqueTypeMap)].
%% Decompose opaque instances of type arg2 to structured types, in arg1
%% XXX: Same as t_unopaque
@@ -798,10 +817,6 @@ list_struct_from_opaque(Types, Opaques) ->
[t_struct_from_opaque(Type, Opaques) || Type <- Types].
%%-----------------------------------------------------------------------------
-
--type mod_records() :: dict:dict(module(), type_table()).
-
-%%-----------------------------------------------------------------------------
%% Unit type. Signals non termination.
%%
@@ -1664,10 +1679,12 @@ t_map(Pairs0, DefK0, DefV0) ->
%% define(DEBUG, true).
try
validate_map_elements(Pairs)
- catch error:badarg -> error(badarg, [Pairs0,DefK0,DefV0]);
- error:{badarg, E} -> error({badarg, E}, [Pairs0,DefK0,DefV0])
+ catch error:badarg -> error(badarg, [Pairs0,DefK0,DefV0])
end,
- ?map(Pairs, DefK, DefV).
+ case map_pairs_are_none(Pairs) of
+ true -> ?none;
+ false -> ?map(Pairs, DefK, DefV)
+ end.
normalise_map_optionals([], _, _) -> [];
normalise_map_optionals([E={K,?opt,?none}|T], DefK, DefV) ->
@@ -1684,7 +1701,6 @@ normalise_map_optionals([E={K,?opt,V}|T], DefK, DefV) ->
normalise_map_optionals([E|T], DefK, DefV) ->
[E|normalise_map_optionals(T, DefK, DefV)].
-validate_map_elements([{_,?mand,?none}|_]) -> error({badarg, none_in_mand});
validate_map_elements([{K1,_,_}|Rest=[{K2,_,_}|_]]) ->
case is_singleton_type(K1) andalso K1 < K2 of
false -> error(badarg);
@@ -1697,6 +1713,10 @@ validate_map_elements([{K,_,_}]) ->
end;
validate_map_elements([]) -> true.
+map_pairs_are_none([]) -> false;
+map_pairs_are_none([{_,?mand,?none}|_]) -> true;
+map_pairs_are_none([_|Ps]) -> map_pairs_are_none(Ps).
+
-spec t_is_map(erl_type()) -> boolean().
t_is_map(Type) ->
@@ -1763,13 +1783,26 @@ mapdict_insert(E1={K1,_,_}, [E2={K2,_,_}|T]) when K1 > K2 ->
[E2|mapdict_insert(E1, T)];
mapdict_insert(E={_,_,_}, T) -> [E|T].
+-type map_pairwise_merge_fun() :: fun((erl_type(),
+ t_map_mandatoriness(), erl_type(),
+ t_map_mandatoriness(), erl_type())
+ -> t_map_pair() | false).
+
+-spec t_map_pairwise_merge(map_pairwise_merge_fun(), erl_type(), erl_type(),
+ opaques()) -> t_map_dict().
+t_map_pairwise_merge(F, MapA, MapB, Opaques) ->
+ do_opaque(MapA, Opaques,
+ fun(UMapA) ->
+ do_opaque(MapB, Opaques,
+ fun(UMapB) ->
+ map_pairwise_merge(F, UMapA, UMapB)
+ end)
+ end).
+
%% Merges the pairs of two maps together. Missing pairs become (?opt, DefV) or
%% (?opt, ?none), depending on whether K \in DefK.
--spec map_pairwise_merge(fun((erl_type(),
- t_map_mandatoriness(), erl_type(),
- t_map_mandatoriness(), erl_type())
- -> t_map_pair() | false),
- erl_type(), erl_type()) -> t_map_dict().
+-spec map_pairwise_merge(map_pairwise_merge_fun(), erl_type(), erl_type())
+ -> t_map_dict().
map_pairwise_merge(F, ?map(APairs, ADefK, ADefV),
?map(BPairs, BDefK, BDefV)) ->
map_pairwise_merge(F, APairs, ADefK, ADefV, BPairs, BDefK, BDefV).
@@ -2223,16 +2256,21 @@ t_has_var_list([]) -> false.
-spec t_collect_vars(erl_type()) -> [erl_type()].
t_collect_vars(T) ->
- t_collect_vars(T, []).
+ Vs = t_collect_vars(T, maps:new()),
+ [V || {V, _} <- maps:to_list(Vs)].
+
+-type ctab() :: #{erl_type() => 'any'}.
--spec t_collect_vars(erl_type(), [erl_type()]) -> [erl_type()].
+-spec t_collect_vars(erl_type(), ctab()) -> ctab().
t_collect_vars(?var(_) = Var, Acc) ->
- ordsets:add_element(Var, Acc);
+ maps:put(Var, any, Acc);
t_collect_vars(?function(Domain, Range), Acc) ->
- ordsets:union(t_collect_vars(Domain, Acc), t_collect_vars(Range, []));
+ Acc1 = t_collect_vars(Domain, Acc),
+ t_collect_vars(Range, Acc1);
t_collect_vars(?list(Contents, Termination, _), Acc) ->
- ordsets:union(t_collect_vars(Contents, Acc), t_collect_vars(Termination, []));
+ Acc1 = t_collect_vars(Contents, Acc),
+ t_collect_vars(Termination, Acc1);
t_collect_vars(?product(Types), Acc) ->
t_collect_vars_list(Types, Acc);
t_collect_vars(?tuple(?any, ?any, ?any), Acc) ->
@@ -2833,12 +2871,7 @@ t_inf(?map(_, ADefK, ADefV) = A, ?map(_, BDefK, BDefV) = B, _Opaques) ->
%% becomes mandatory in the infinumum
(K, _, V1, _, V2) -> {K, ?mand, t_inf(V1, V2)}
end, A, B),
- %% If the infinimum of any mandatory values is ?none, the entire map infinimum
- %% is ?none.
- case lists:any(fun({_,?mand,?none})->true; ({_,_,_}) -> false end, Pairs) of
- true -> t_none();
- false -> t_map(Pairs, t_inf(ADefK, BDefK), t_inf(ADefV, BDefV))
- end;
+ t_map(Pairs, t_inf(ADefK, BDefK), t_inf(ADefV, BDefV));
t_inf(?matchstate(Pres1, Slots1), ?matchstate(Pres2, Slots2), _Opaques) ->
?matchstate(t_inf(Pres1, Pres2), t_inf(Slots1, Slots2));
t_inf(?nil, ?nil, _Opaques) -> ?nil;
@@ -2978,27 +3011,21 @@ inf_collect(_T1, [], _Opaques, OpL) ->
OpL.
combine(S, T1, T2) ->
- #opaque{mod = Mod1, name = Name1, args = Args1} = T1,
- #opaque{mod = Mod2, name = Name2, args = Args2} = T2,
- Comb1 = comb(Mod1, Name1, Args1, S, T1),
- case is_compat_opaque_names({Mod1, Name1, Args1}, {Mod2, Name2, Args2}) of
- true -> Comb1;
- false -> Comb1 ++ comb(Mod2, Name2, Args2, S, T2)
+ case is_compat_opaque_names(T1, T2) of
+ true -> combine(S, [T1]);
+ false -> combine(S, [T1, T2])
end.
-comb(Mod, Name, Args, S, T) ->
- case can_combine_opaque_names(Mod, Name, Args, S) of
- true ->
- ?opaque(Set) = S,
- Set;
- false ->
- [T#opaque{struct = S}]
- end.
+combine(?opaque(Set), Ts) ->
+ [comb2(O, T) || O <- Set, T <- Ts];
+combine(S, Ts) ->
+ [T#opaque{struct = S} || T <- Ts].
-can_combine_opaque_names(Mod1, Name1, Args1,
- ?opaque([#opaque{mod = Mod2, name = Name2, args = Args2}])) ->
- is_compat_opaque_names({Mod1, Name1, Args1}, {Mod2, Name2, Args2});
-can_combine_opaque_names(_, _, _, _) -> false.
+comb2(O, T) ->
+ case is_compat_opaque_names(O, T) of
+ true -> O;
+ false -> T#opaque{struct = ?opaque(set_singleton(O))}
+ end.
%% Combining two lists this way can be very time consuming...
%% Note: two parameterized opaque types are not the same if their
@@ -3007,32 +3034,27 @@ inf_opaque(Set1, Set2, Opaques) ->
List1 = inf_look_up(Set1, Opaques),
List2 = inf_look_up(Set2, Opaques),
List0 = [combine(Inf, T1, T2) ||
- {Is1, ModNameArgs1, T1} <- List1,
- {Is2, ModNameArgs2, T2} <- List2,
- not t_is_none(Inf = inf_opaque_types(Is1, ModNameArgs1, T1,
- Is2, ModNameArgs2, T2,
- Opaques))],
- List = lists:sort(lists:append(List0)),
+ {Is1, T1} <- List1,
+ {Is2, T2} <- List2,
+ not t_is_none(Inf = inf_opaque_types(Is1, T1, Is2, T2, Opaques))],
+ List = lists:append(List0),
sup_opaque(List).
%% Optimization: do just one lookup.
inf_look_up(Set, Opaques) ->
- [{Opaques =:= 'universe' orelse inf_is_opaque_type2(T, Opaques),
- {M, N, Args}, T} ||
- #opaque{mod = M, name = N, args = Args} = T <- set_to_list(Set)].
+ [{Opaques =:= 'universe' orelse inf_is_opaque_type2(T, Opaques), T} ||
+ T <- set_to_list(Set)].
inf_is_opaque_type2(T, {match, Opaques}) ->
is_opaque_type2(T, Opaques);
inf_is_opaque_type2(T, Opaques) ->
is_opaque_type2(T, Opaques).
-inf_opaque_types(IsOpaque1, ModNameArgs1, T1,
- IsOpaque2, ModNameArgs2, T2, Opaques) ->
+inf_opaque_types(IsOpaque1, T1, IsOpaque2, T2, Opaques) ->
#opaque{struct = S1}=T1,
#opaque{struct = S2}=T2,
case
- Opaques =:= 'universe' orelse
- is_compat_opaque_names(ModNameArgs1, ModNameArgs2)
+ Opaques =:= 'universe' orelse is_compat_opaque_names(T1, T2)
of
true -> t_inf(S1, S2, Opaques);
false ->
@@ -3046,98 +3068,109 @@ inf_opaque_types(IsOpaque1, ModNameArgs1, T1,
end
end.
-is_compat_opaque_names(ModNameArgs, ModNameArgs) -> true;
-is_compat_opaque_names({Mod,Name,Args1}, {Mod,Name,Args2}) ->
- is_compat_args(Args1, Args2);
-is_compat_opaque_names(_, _) -> false.
+compatible_opaque_types(?opaque(Es1), ?opaque(Es2)) ->
+ [{O1, O2} || O1 <- Es1, O2 <- Es2, is_compat_opaque_names(O1, O2)].
+
+is_compat_opaque_names(Opaque1, Opaque2) ->
+ #opaque{mod = Mod1, name = Name1, args = Args1} = Opaque1,
+ #opaque{mod = Mod2, name = Name2, args = Args2} = Opaque2,
+ case {{Mod1, Name1, Args1}, {Mod2, Name2, Args2}} of
+ {ModNameArgs, ModNameArgs} -> true;
+ {{Mod, Name, Args1}, {Mod, Name, Args2}} ->
+ is_compat_args(Args1, Args2);
+ _ -> false
+ end.
is_compat_args([A1|Args1], [A2|Args2]) ->
is_compat_arg(A1, A2) andalso is_compat_args(Args1, Args2);
is_compat_args([], []) -> true;
is_compat_args(_, _) -> false.
-is_compat_arg(A1, A2) ->
- is_specialization(A1, A2) orelse is_specialization(A2, A1).
-
--spec is_specialization(erl_type(), erl_type()) -> boolean().
-
-%% Returns true if the first argument is a specialization of the
-%% second argument in the sense that every type is a specialization of
-%% any(). For example, {_,_} is a specialization of any(), but not of
-%% tuple(). Does not handle variables, but any() and unions (sort of).
-
-is_specialization(T, T) -> true;
-is_specialization(_, ?any) -> true;
-is_specialization(?any, _) -> false;
-is_specialization(?function(Domain1, Range1), ?function(Domain2, Range2)) ->
- (is_specialization(Domain1, Domain2) andalso
- is_specialization(Range1, Range2));
-is_specialization(?list(Contents1, Termination1, Size1),
- ?list(Contents2, Termination2, Size2)) ->
+-spec is_compat_arg(erl_type(), erl_type()) -> boolean().
+
+%% The intention is that 'true' is to be returned iff one of the
+%% arguments is a specialization of the other argument in the sense
+%% that every type is a specialization of any(). For example, {_,_} is
+%% a specialization of any(), but not of tuple(). Does not handle
+%% variables, but any() and unions (sort of). However, the
+%% implementation is more relaxed as any() is compatible to anything.
+
+is_compat_arg(T, T) -> true;
+is_compat_arg(_, ?any) -> true;
+is_compat_arg(?any, _) -> true;
+is_compat_arg(?function(Domain1, Range1), ?function(Domain2, Range2)) ->
+ (is_compat_arg(Domain1, Domain2) andalso
+ is_compat_arg(Range1, Range2));
+is_compat_arg(?list(Contents1, Termination1, Size1),
+ ?list(Contents2, Termination2, Size2)) ->
(Size1 =:= Size2 andalso
- is_specialization(Contents1, Contents2) andalso
- is_specialization(Termination1, Termination2));
-is_specialization(?product(Types1), ?product(Types2)) ->
- specialization_list(Types1, Types2);
-is_specialization(?tuple(?any, ?any, ?any), ?tuple(_, _, _)) -> false;
-is_specialization(?tuple(_, _, _), ?tuple(?any, ?any, ?any)) -> false;
-is_specialization(?tuple(Elements1, Arity, _),
- ?tuple(Elements2, Arity, _)) when Arity =/= ?any ->
- specialization_list(Elements1, Elements2);
-is_specialization(?tuple_set([{Arity, List}]),
- ?tuple(Elements2, Arity, _)) when Arity =/= ?any ->
- specialization_list(sup_tuple_elements(List), Elements2);
-is_specialization(?tuple(Elements1, Arity, _),
- ?tuple_set([{Arity, List}])) when Arity =/= ?any ->
- specialization_list(Elements1, sup_tuple_elements(List));
-is_specialization(?tuple_set(List1), ?tuple_set(List2)) ->
+ is_compat_arg(Contents1, Contents2) andalso
+ is_compat_arg(Termination1, Termination2));
+is_compat_arg(?product(Types1), ?product(Types2)) ->
+ is_compat_list(Types1, Types2);
+is_compat_arg(?map(Pairs1, DefK1, DefV1), ?map(Pairs2, DefK2, DefV2)) ->
+ (is_compat_list(Pairs1, Pairs2) andalso
+ is_compat_arg(DefK1, DefK2) andalso
+ is_compat_arg(DefV1, DefV2));
+is_compat_arg(?tuple(?any, ?any, ?any), ?tuple(_, _, _)) -> false;
+is_compat_arg(?tuple(_, _, _), ?tuple(?any, ?any, ?any)) -> false;
+is_compat_arg(?tuple(Elements1, Arity, _),
+ ?tuple(Elements2, Arity, _)) when Arity =/= ?any ->
+ is_compat_list(Elements1, Elements2);
+is_compat_arg(?tuple_set([{Arity, List}]),
+ ?tuple(Elements2, Arity, _)) when Arity =/= ?any ->
+ is_compat_list(sup_tuple_elements(List), Elements2);
+is_compat_arg(?tuple(Elements1, Arity, _),
+ ?tuple_set([{Arity, List}])) when Arity =/= ?any ->
+ is_compat_list(Elements1, sup_tuple_elements(List));
+is_compat_arg(?tuple_set(List1), ?tuple_set(List2)) ->
try
- specialization_list_list([sup_tuple_elements(T) || {_Arity, T} <- List1],
- [sup_tuple_elements(T) || {_Arity, T} <- List2])
+ is_compat_list_list([sup_tuple_elements(T) || {_Arity, T} <- List1],
+ [sup_tuple_elements(T) || {_Arity, T} <- List2])
catch _:_ -> false
end;
-is_specialization(?union(List1)=T1, ?union(List2)=T2) ->
- case specialization_union2(T1, T2) of
- {yes, Type1, Type2} -> is_specialization(Type1, Type2);
- no -> specialization_list(List1, List2)
+is_compat_arg(?opaque(_) = T1, T2) ->
+ is_compat_arg(t_opaque_structure(T1), T2);
+is_compat_arg(T1, ?opaque(_) = T2) ->
+ is_compat_arg(T1, t_opaque_structure(T2));
+is_compat_arg(?union(List1)=T1, ?union(List2)=T2) ->
+ case is_compat_union2(T1, T2) of
+ {yes, Type1, Type2} -> is_compat_arg(Type1, Type2);
+ no -> is_compat_list(List1, List2)
end;
-is_specialization(?union(List), T2) ->
+is_compat_arg(?union(List), T2) ->
case unify_union(List) of
- {yes, Type} -> is_specialization(Type, T2);
+ {yes, Type} -> is_compat_arg(Type, T2);
no -> false
end;
-is_specialization(T1, ?union(List)) ->
+is_compat_arg(T1, ?union(List)) ->
case unify_union(List) of
- {yes, Type} -> is_specialization(T1, Type);
+ {yes, Type} -> is_compat_arg(T1, Type);
no -> false
end;
-is_specialization(?opaque(_) = T1, T2) ->
- is_specialization(t_opaque_structure(T1), T2);
-is_specialization(T1, ?opaque(_) = T2) ->
- is_specialization(T1, t_opaque_structure(T2));
-is_specialization(?var(_), _) -> exit(error);
-is_specialization(_, ?var(_)) -> exit(error);
-is_specialization(?none, _) -> false;
-is_specialization(_, ?none) -> false;
-is_specialization(?unit, _) -> false;
-is_specialization(_, ?unit) -> false;
-is_specialization(#c{}, #c{}) -> false.
-
-specialization_list_list(LL1, LL2) ->
- length(LL1) =:= length(LL2) andalso specialization_list_list1(LL1, LL2).
-
-specialization_list_list1([], []) -> true;
-specialization_list_list1([L1|LL1], [L2|LL2]) ->
- specialization_list(L1, L2) andalso specialization_list_list1(LL1, LL2).
-
-specialization_list(L1, L2) ->
- length(L1) =:= length(L2) andalso specialization_list1(L1, L2).
-
-specialization_list1([], []) -> true;
-specialization_list1([T1|L1], [T2|L2]) ->
- is_specialization(T1, T2) andalso specialization_list1(L1, L2).
-
-specialization_union2(?union(List1)=T1, ?union(List2)=T2) ->
+is_compat_arg(?var(_), _) -> exit(error);
+is_compat_arg(_, ?var(_)) -> exit(error);
+is_compat_arg(?none, _) -> false;
+is_compat_arg(_, ?none) -> false;
+is_compat_arg(?unit, _) -> false;
+is_compat_arg(_, ?unit) -> false;
+is_compat_arg(#c{}, #c{}) -> false.
+
+is_compat_list_list(LL1, LL2) ->
+ length(LL1) =:= length(LL2) andalso is_compat_list_list1(LL1, LL2).
+
+is_compat_list_list1([], []) -> true;
+is_compat_list_list1([L1|LL1], [L2|LL2]) ->
+ is_compat_list(L1, L2) andalso is_compat_list_list1(LL1, LL2).
+
+is_compat_list(L1, L2) ->
+ length(L1) =:= length(L2) andalso is_compat_list1(L1, L2).
+
+is_compat_list1([], []) -> true;
+is_compat_list1([T1|L1], [T2|L2]) ->
+ is_compat_arg(T1, T2) andalso is_compat_list1(L1, L2).
+
+is_compat_union2(?union(List1)=T1, ?union(List2)=T2) ->
case {unify_union(List1), unify_union(List2)} of
{{yes, Type1}, {yes, Type2}} -> {yes, Type1, Type2};
{{yes, Type1}, no} -> {yes, Type1, T2};
@@ -4170,7 +4203,7 @@ t_map(Fun, T) ->
-spec t_to_string(erl_type()) -> string().
t_to_string(T) ->
- t_to_string(T, dict:new()).
+ t_to_string(T, maps:new()).
-spec t_to_string(erl_type(), type_table()) -> string().
@@ -4223,8 +4256,8 @@ t_to_string(?opaque(Set), RecDict) ->
<- set_to_list(Set)],
" | ");
t_to_string(?matchstate(Pres, Slots), RecDict) ->
- flat_format("ms(~s,~s)", [t_to_string(Pres, RecDict),
- t_to_string(Slots,RecDict)]);
+ flat_format("ms(~ts,~ts)", [t_to_string(Pres, RecDict),
+ t_to_string(Slots,RecDict)]);
t_to_string(?nil, _RecDict) ->
"[]";
t_to_string(?nonempty_list(Contents, Termination), RecDict) ->
@@ -4366,7 +4399,7 @@ record_field_diffs_to_string(?tuple([_|Fs], Arity, Tag), RecDict) ->
string:join(FieldDiffs, " and ").
field_diffs([F|Fs], [{FName, _Abstr, DefType}|FDefs], RecDict, Acc) ->
- %% Don't care about opaqueness for now.
+ %% Don't care about opacity for now.
NewAcc =
case not t_is_none(t_inf(F, DefType)) of
true -> Acc;
@@ -4402,10 +4435,10 @@ opaque_type(Mod, Name, Args, _S, RecDict) ->
opaque_name(Mod, Name, Extra) ->
S = mod_name(Mod, Name),
- flat_format("~s(~s)", [S, Extra]).
+ flat_format("~ts(~ts)", [S, Extra]).
mod_name(Mod, Name) ->
- flat_format("~w:~w", [Mod, Name]).
+ flat_format("~w:~tw", [Mod, Name]).
%%=============================================================================
%%
@@ -4420,9 +4453,17 @@ mod_name(Mod, Name) ->
-type site() :: {'type', mta()} | {'spec', mfa()} | {'record', mra()}.
-type cache_key() :: {module(), atom(), expand_depth(),
[erl_type()], type_names()}.
--opaque cache() :: #{cache_key() => {erl_type(), expand_limit()}}.
+-type mod_type_table() :: ets:tid().
+-type mod_records() :: dict:dict(module(), type_table()).
+-record(cache,
+ {
+ types = maps:new() :: #{cache_key() => {erl_type(), expand_limit()}},
+ mod_recs = {mrecs, dict:new()} :: {'mrecs', mod_records()}
+ }).
+
+-opaque cache() :: #cache{}.
--spec t_from_form(parse_form(), sets:set(mfa()), site(), mod_records(),
+-spec t_from_form(parse_form(), sets:set(mfa()), site(), mod_type_table(),
var_table(), cache()) -> {erl_type(), cache()}.
t_from_form(Form, ExpTypes, Site, RecDict, VarTab, Cache) ->
@@ -4434,11 +4475,12 @@ t_from_form(Form, ExpTypes, Site, RecDict, VarTab, Cache) ->
t_from_form_without_remote(Form, Site, TypeTable) ->
Module = site_module(Site),
- RecDict = dict:from_list([{Module, TypeTable}]),
+ ModRecs = dict:from_list([{Module, TypeTable}]),
ExpTypes = replace_by_none,
VarTab = var_table__new(),
- Cache = cache__new(),
- t_from_form1(Form, ExpTypes, Site, RecDict, VarTab, Cache).
+ Cache0 = cache__new(),
+ Cache = Cache0#cache{mod_recs = {mrecs, ModRecs}},
+ t_from_form1(Form, ExpTypes, Site, undefined, VarTab, Cache).
%% REC_TYPE_LIMIT is used for limiting the depth of recursive types.
%% EXPAND_LIMIT is used for limiting the size of types by
@@ -4453,13 +4495,13 @@ t_from_form_without_remote(Form, Site, TypeTable) ->
-record(from_form, {site :: site(),
xtypes :: sets:set(mfa()) | 'replace_by_none',
- mrecs :: mod_records(),
+ mrecs :: 'undefined' | mod_type_table(),
vtab :: var_table(),
tnames :: type_names()}).
-spec t_from_form1(parse_form(), sets:set(mfa()) | 'replace_by_none',
- site(), mod_records(), var_table(), cache()) ->
- {erl_type(), cache()}.
+ site(), 'undefined' | mod_type_table(), var_table(),
+ cache()) -> {erl_type(), cache()}.
t_from_form1(Form, ET, Site, MR, V, C) ->
TypeNames = initial_typenames(Site),
@@ -4469,28 +4511,31 @@ t_from_form1(Form, ET, Site, MR, V, C) ->
vtab = V,
tnames = TypeNames},
L = ?EXPAND_LIMIT,
- {T1, L1, C1} = from_form(Form, State, ?EXPAND_DEPTH, L, C),
+ {T0, L0, C0} = from_form(Form, State, ?EXPAND_DEPTH, L, C),
if
- L1 =< 0 ->
- from_form_loop(Form, State, 1, L, C1);
+ L0 =< 0 ->
+ {T1, _, C1} = from_form(Form, State, 1, L, C0),
+ from_form_loop(Form, State, 2, L, C1, T1);
true ->
- {T1, C1}
+ {T0, C0}
end.
initial_typenames({type, _MTA}=Site) -> [Site];
initial_typenames({spec, _MFA}) -> [];
initial_typenames({record, _MRA}) -> [].
-from_form_loop(Form, State, D, Limit, C) ->
+from_form_loop(Form, State, D, Limit, C, T0) ->
{T1, L1, C1} = from_form(Form, State, D, Limit, C),
Delta = Limit - L1,
if
- %% Save some time by assuming next depth will exceed the limit.
+ L1 =< 0 ->
+ {T0, C1};
Delta * 8 > Limit ->
+ %% Save some time by assuming next depth will exceed the limit.
{T1, C1};
true ->
D1 = D + 1,
- from_form_loop(Form, State, D1, Limit, C1)
+ from_form_loop(Form, State, D1, Limit, C1, T1)
end.
-spec from_form(parse_form(),
@@ -4528,6 +4573,8 @@ from_form({atom, _L, Atom}, _S, _D, L, C) ->
{t_atom(Atom), L, C};
from_form({integer, _L, Int}, _S, _D, L, C) ->
{t_integer(Int), L, C};
+from_form({char, _L, Char}, _S, _D, L, C) ->
+ {t_integer(Char), L, C};
from_form({op, _L, _Op, _Arg} = Op, _S, _D, L, C) ->
case erl_eval:partial_eval(Op) of
{integer, _, Val} ->
@@ -4700,13 +4747,13 @@ from_form({opaque, _L, Name, {Mod, Args, Rep}}, _S, _D, L, C) ->
builtin_type(Name, Type, S, D, L, C) ->
#from_form{site = Site, mrecs = MR} = S,
M = site_module(Site),
- case dict:find(M, MR) of
- {ok, R} ->
+ case lookup_module_types(M, MR, C) of
+ {R, C1} ->
case lookup_type(Name, 0, R) of
{_, {{_M, _FL, _F, _A}, _T}} ->
- type_from_form(Name, [], S, D, L, C);
+ type_from_form(Name, [], S, D, L, C1);
error ->
- {Type, L, C}
+ {Type, L, C1}
end;
error ->
{Type, L, C}
@@ -4719,9 +4766,9 @@ type_from_form(Name, Args, S, D, L, C) ->
TypeName = {type, {Module, Name, ArgsLen}},
case can_unfold_more(TypeName, TypeNames) of
true ->
- {ok, R} = dict:find(Module, MR),
+ {R, C1} = lookup_module_types(Module, MR, C),
type_from_form1(Name, Args, ArgsLen, R, TypeName, TypeNames,
- S, D, L, C);
+ S, D, L, C1);
false ->
{t_any(), L, C}
end.
@@ -4749,7 +4796,7 @@ type_from_form1(Name, Args, ArgsLen, R, TypeName, TypeNames, S, D, L, C) ->
{Rep, L2, C2} = recur_limit(Fun, D, L1, TypeName, TypeNames),
Rep1 = choose_opaque_type(Rep, Type),
Rep2 = case cannot_have_opaque(Rep1, TypeName, TypeNames) of
- true -> Rep1;
+ true -> Rep;
false ->
ArgTypes2 = subst_all_vars_to_any_list(ArgTypes),
t_opaque(Module, Name, ArgTypes2, Rep1)
@@ -4760,7 +4807,7 @@ type_from_form1(Name, Args, ArgsLen, R, TypeName, TypeNames, S, D, L, C) ->
{NewType, L3, C4}
end;
error ->
- Msg = io_lib:format("Unable to find type ~w/~w\n",
+ Msg = io_lib:format("Unable to find type ~tw/~w\n",
[Name, ArgsLen]),
throw({error, Msg})
end.
@@ -4773,24 +4820,24 @@ remote_from_form(RemMod, Name, Args, S, D, L, C) ->
true ->
ArgsLen = length(Args),
MFA = {RemMod, Name, ArgsLen},
- case dict:find(RemMod, MR) of
+ case lookup_module_types(RemMod, MR, C) of
error ->
self() ! {self(), ext_types, MFA},
{t_any(), L, C};
- {ok, RemDict} ->
+ {RemDict, C1} ->
case sets:is_element(MFA, ET) of
true ->
RemType = {type, MFA},
case can_unfold_more(RemType, TypeNames) of
true ->
remote_from_form1(RemMod, Name, Args, ArgsLen, RemDict,
- RemType, TypeNames, S, D, L, C);
+ RemType, TypeNames, S, D, L, C1);
false ->
- {t_any(), L, C}
+ {t_any(), L, C1}
end;
false ->
self() ! {self(), ext_types, {RemMod, Name, ArgsLen}},
- {t_any(), L, C}
+ {t_any(), L, C1}
end
end
end.
@@ -4821,7 +4868,7 @@ remote_from_form1(RemMod, Name, Args, ArgsLen, RemDict, RemType, TypeNames,
NewRep1 = choose_opaque_type(NewRep, Type),
NewRep2 =
case cannot_have_opaque(NewRep1, RemType, TypeNames) of
- true -> NewRep1;
+ true -> NewRep;
false ->
ArgTypes2 = subst_all_vars_to_any_list(ArgTypes),
t_opaque(Mod, Name, ArgTypes2, NewRep1)
@@ -4832,7 +4879,7 @@ remote_from_form1(RemMod, Name, Args, ArgsLen, RemDict, RemType, TypeNames,
{NewType, L3, C4}
end;
error ->
- Msg = io_lib:format("Unable to find remote type ~w:~w()\n",
+ Msg = io_lib:format("Unable to find remote type ~w:~tw()\n",
[RemMod, Name]),
throw({error, Msg})
end.
@@ -4865,33 +4912,33 @@ record_from_form({atom, _, Name}, ModFields, S, D0, L0, C) ->
case can_unfold_more(RecordType, TypeNames) of
true ->
M = site_module(Site),
- {ok, R} = dict:find(M, MR),
+ {R, C1} = lookup_module_types(M, MR, C),
case lookup_record(Name, R) of
{ok, DeclFields} ->
NewTypeNames = [RecordType|TypeNames],
Site1 = {record, {M, Name, length(DeclFields)}},
S1 = S#from_form{site = Site1, tnames = NewTypeNames},
Fun = fun(D, L) ->
- {GetModRec, L1, C1} =
- get_mod_record(ModFields, DeclFields, S1, D, L, C),
+ {GetModRec, L1, C2} =
+ get_mod_record(ModFields, DeclFields, S1, D, L, C1),
case GetModRec of
{error, FieldName} ->
throw({error,
- io_lib:format("Illegal declaration of #~w{~w}\n",
+ io_lib:format("Illegal declaration of #~tw{~tw}\n",
[Name, FieldName])});
{ok, NewFields} ->
S2 = S1#from_form{vtab = var_table__new()},
- {NewFields1, L2, C2} =
- fields_from_form(NewFields, S2, D, L1, C1),
+ {NewFields1, L2, C3} =
+ fields_from_form(NewFields, S2, D, L1, C2),
Rec = t_tuple(
[t_atom(Name)|[Type
|| {_FieldName, Type} <- NewFields1]]),
- {Rec, L2, C2}
+ {Rec, L2, C3}
end
end,
recur_limit(Fun, D0, L0, RecordType, TypeNames);
error ->
- throw({error, io_lib:format("Unknown record #~w{}\n", [Name])})
+ throw({error, io_lib:format("Unknown record #~tw{}\n", [Name])})
end;
false ->
{t_any(), L0, C}
@@ -5017,7 +5064,7 @@ recur_limit(Fun, D, L, TypeName, TypeNames) ->
end.
-spec t_check_record_fields(parse_form(), sets:set(mfa()), site(),
- mod_records(), var_table(), cache()) -> cache().
+ mod_type_table(), var_table(), cache()) -> cache().
t_check_record_fields(Form, ExpTypes, Site, RecDict, VarTable, Cache) ->
State = #from_form{site = Site,
@@ -5042,6 +5089,7 @@ check_record_fields({remote_type, _L, [{atom, _, _}, {atom, _, _}, Args]},
list_check_record_fields(Args, S, C);
check_record_fields({atom, _L, _}, _S, C) -> C;
check_record_fields({integer, _L, _}, _S, C) -> C;
+check_record_fields({char, _L, _}, _S, C) -> C;
check_record_fields({op, _L, _Op, _Arg}, _S, C) -> C;
check_record_fields({op, _L, _Op, _Arg1, _Arg2}, _S, C) -> C;
check_record_fields({type, _L, tuple, any}, _S, C) -> C;
@@ -5060,13 +5108,13 @@ check_record_fields({user_type, _L, _Name, Args}, S, C) ->
check_record({atom, _, Name}, ModFields, S, C) ->
#from_form{site = Site, mrecs = MR} = S,
M = site_module(Site),
- {ok, R} = dict:find(M, MR),
+ {R, C1} = lookup_module_types(M, MR, C),
{ok, DeclFields} = lookup_record(Name, R),
- case check_fields(Name, ModFields, DeclFields, S, C) of
+ case check_fields(Name, ModFields, DeclFields, S, C1) of
{error, FieldName} ->
- throw({error, io_lib:format("Illegal declaration of #~w{~w}\n",
- [Name, FieldName])});
- C1 -> C1
+ throw({error, io_lib:format("Illegal declaration of #~tw{~tw}\n",
+ [Name, FieldName])});
+ C2 -> C2
end.
check_fields(RecName, [{type, _, field_type, [{atom, _, Name}, Abstr]}|Left],
@@ -5096,7 +5144,7 @@ site_module({_, {Module, _, _}}) ->
-spec cache__new() -> cache().
cache__new() ->
- maps:new().
+ #cache{}.
-spec cache_key(module(), atom(), [erl_type()],
type_names(), expand_depth()) -> cache_key().
@@ -5113,8 +5161,8 @@ cache_key(Module, Name, ArgTypes, TypeNames, D) ->
-spec cache_find(cache_key(), cache()) ->
{erl_type(), expand_limit()} | 'error'.
-cache_find(Key, Cache) ->
- case maps:find(Key, Cache) of
+cache_find(Key, #cache{types = Types}) ->
+ case maps:find(Key, Types) of
{ok, Value} ->
Value;
error ->
@@ -5126,12 +5174,13 @@ cache_find(Key, Cache) ->
cache_put(_Key, _Type, DeltaL, Cache) when DeltaL < 0 ->
%% The type is truncated; do not reuse it.
Cache;
-cache_put(Key, Type, DeltaL, Cache) ->
- maps:put(Key, {Type, DeltaL}, Cache).
+cache_put(Key, Type, DeltaL, #cache{types = Types} = Cache) ->
+ NewTypes = maps:put(Key, {Type, DeltaL}, Types),
+ Cache#cache{types = NewTypes}.
--spec t_var_names([erl_type()]) -> [atom()].
+-spec t_var_names([parse_form()]) -> [atom()].
-t_var_names([{var, _, Name}|L]) when L =/= '_' ->
+t_var_names([{var, _, Name}|L]) when Name =/= '_' ->
[Name|t_var_names(L)];
t_var_names([]) ->
[].
@@ -5143,6 +5192,7 @@ t_form_to_string({var, _L, Name}) -> atom_to_list(Name);
t_form_to_string({atom, _L, Atom}) ->
io_lib:write_string(atom_to_list(Atom), $'); % To quote or not to quote... '
t_form_to_string({integer, _L, Int}) -> integer_to_list(Int);
+t_form_to_string({char, _L, Char}) -> integer_to_list(Char);
t_form_to_string({op, _L, _Op, _Arg} = Op) ->
case erl_eval:partial_eval(Op) of
{integer, _, _} = Int -> t_form_to_string(Int);
@@ -5156,10 +5206,10 @@ t_form_to_string({op, _L, _Op, _Arg1, _Arg2} = Op) ->
t_form_to_string({ann_type, _L, [Var, Type]}) ->
t_form_to_string(Var) ++ "::" ++ t_form_to_string(Type);
t_form_to_string({paren_type, _L, [Type]}) ->
- flat_format("(~s)", [t_form_to_string(Type)]);
+ flat_format("(~ts)", [t_form_to_string(Type)]);
t_form_to_string({remote_type, _L, [{atom, _, Mod}, {atom, _, Name}, Args]}) ->
ArgString = "(" ++ string:join(t_form_to_string_list(Args), ",") ++ ")",
- flat_format("~w:~w", [Mod, Name]) ++ ArgString;
+ flat_format("~w:~tw", [Mod, Name]) ++ ArgString;
t_form_to_string({type, _L, arity, []}) -> "arity()";
t_form_to_string({type, _L, binary, []}) -> "binary()";
t_form_to_string({type, _L, binary, [Base, Unit]} = Type) ->
@@ -5209,12 +5259,12 @@ t_form_to_string({type, _L, range, [From, To]} = Type) ->
_ -> flat_format("Badly formed type ~w",[Type])
end;
t_form_to_string({type, _L, record, [{atom, _, Name}]}) ->
- flat_format("#~w{}", [Name]);
+ flat_format("#~tw{}", [Name]);
t_form_to_string({type, _L, record, [{atom, _, Name}|Fields]}) ->
FieldString = string:join(t_form_to_string_list(Fields), ","),
- flat_format("#~w{~s}", [Name, FieldString]);
+ flat_format("#~tw{~ts}", [Name, FieldString]);
t_form_to_string({type, _L, field_type, [{atom, _, Name}, Type]}) ->
- flat_format("~w::~s", [Name, t_form_to_string(Type)]);
+ flat_format("~tw::~ts", [Name, t_form_to_string(Type)]);
t_form_to_string({type, _L, term, []}) -> "term()";
t_form_to_string({type, _L, timeout, []}) -> "timeout()";
t_form_to_string({type, _L, tuple, any}) -> "tuple()";
@@ -5225,14 +5275,12 @@ t_form_to_string({type, _L, union, Args}) ->
t_form_to_string({type, _L, Name, []} = T) ->
try
M = mod,
- D0 = dict:new(),
- MR = dict:from_list([{M, D0}]),
Site = {type, {M,Name,0}},
V = var_table__new(),
C = cache__new(),
State = #from_form{site = Site,
xtypes = sets:new(),
- mrecs = MR,
+ mrecs = 'undefined',
vtab = V,
tnames = []},
{T1, _, _} = from_form(T, State, _Deep=1000, _ALot=1000000, C),
@@ -5240,7 +5288,7 @@ t_form_to_string({type, _L, Name, []} = T) ->
catch throw:{error, _} -> atom_to_string(Name) ++ "()"
end;
t_form_to_string({user_type, _L, Name, List}) ->
- flat_format("~w(~s)",
+ flat_format("~tw(~ts)",
[Name, string:join(t_form_to_string_list(List), ",")]);
t_form_to_string({type, L, Name, List}) ->
%% Compatibility: modules compiled before Erlang/OTP 18.0.
@@ -5257,7 +5305,7 @@ t_form_to_string_list([], Acc) ->
-spec atom_to_string(atom()) -> string().
atom_to_string(Atom) ->
- flat_format("~w", [Atom]).
+ flat_format("~tw", [Atom]).
%%=============================================================================
%%
@@ -5286,11 +5334,29 @@ is_erl_type(?unit) -> true;
is_erl_type(#c{}) -> true;
is_erl_type(_) -> false.
+-spec lookup_module_types(module(), mod_type_table(), cache()) ->
+ 'error' | {type_table(), cache()}.
+
+lookup_module_types(Module, CodeTable, Cache) ->
+ #cache{mod_recs = {mrecs, MRecs}} = Cache,
+ case dict:find(Module, MRecs) of
+ {ok, R} ->
+ {R, Cache};
+ error ->
+ try ets:lookup_element(CodeTable, Module, 2) of
+ R ->
+ NewMRecs = dict:store(Module, R, MRecs),
+ {R, Cache#cache{mod_recs = {mrecs, NewMRecs}}}
+ catch
+ _:_ -> error
+ end
+ end.
+
-spec lookup_record(atom(), type_table()) ->
'error' | {'ok', [{atom(), parse_form(), erl_type()}]}.
-lookup_record(Tag, RecDict) when is_atom(Tag) ->
- case dict:find({record, Tag}, RecDict) of
+lookup_record(Tag, Table) when is_atom(Tag) ->
+ case maps:find({record, Tag}, Table) of
{ok, {_FileLine, [{_Arity, Fields}]}} ->
{ok, Fields};
{ok, {_FileLine, List}} when is_list(List) ->
@@ -5304,18 +5370,18 @@ lookup_record(Tag, RecDict) when is_atom(Tag) ->
-spec lookup_record(atom(), arity(), type_table()) ->
'error' | {'ok', [{atom(), parse_form(), erl_type()}]}.
-lookup_record(Tag, Arity, RecDict) when is_atom(Tag) ->
- case dict:find({record, Tag}, RecDict) of
+lookup_record(Tag, Arity, Table) when is_atom(Tag) ->
+ case maps:find({record, Tag}, Table) of
{ok, {_FileLine, [{Arity, Fields}]}} -> {ok, Fields};
{ok, {_FileLine, OrdDict}} -> orddict:find(Arity, OrdDict);
error -> error
end.
-spec lookup_type(_, _, _) -> {'type' | 'opaque', type_value()} | 'error'.
-lookup_type(Name, Arity, RecDict) ->
- case dict:find({type, Name, Arity}, RecDict) of
+lookup_type(Name, Arity, Table) ->
+ case maps:find({type, Name, Arity}, Table) of
error ->
- case dict:find({opaque, Name, Arity}, RecDict) of
+ case maps:find({opaque, Name, Arity}, Table) of
error -> error;
{ok, Found} -> {opaque, Found}
end;
@@ -5325,8 +5391,8 @@ lookup_type(Name, Arity, RecDict) ->
-spec type_is_defined('type' | 'opaque', atom(), arity(), type_table()) ->
boolean().
-type_is_defined(TypeOrOpaque, Name, Arity, RecDict) ->
- dict:is_key({TypeOrOpaque, Name, Arity}, RecDict).
+type_is_defined(TypeOrOpaque, Name, Arity, Table) ->
+ maps:is_key({TypeOrOpaque, Name, Arity}, Table).
cannot_have_opaque(Type, TypeName, TypeNames) ->
t_is_none(Type) orelse is_recursive(TypeName, TypeNames).
@@ -5488,7 +5554,7 @@ set_size(Set) ->
set_to_string(Set) ->
L = [case is_atom(X) of
true -> io_lib:write_string(atom_to_list(X), $'); % stupid emacs '
- false -> flat_format("~w", [X])
+ false -> flat_format("~tw", [X])
end || X <- set_to_list(Set)],
string:join(L, " | ").
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index e2a1524be6..9167d0aaec 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2006</year><year>2016</year>
+ <year>2006</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,206 @@
</header>
<p>This document describes the changes made to HiPE.</p>
+<section><title>Hipe 3.16</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix hipe compiler flags <c>o0</c> and <c>o1</c> that have
+ previously been ignored by mistake.</p>
+ <p>
+ Own Id: OTP-13862 Aux Id: PR-1154 </p>
+ </item>
+ <item>
+ <p>
+ Fix LLVM backend to not convert all remote calls to own
+ module, like <c>?MODULE:foo()</c>, into local calls.</p>
+ <p>
+ Own Id: OTP-13983</p>
+ </item>
+ <item>
+ <p>
+ Hipe optional LLVM backend does require LLVM version 3.9
+ or later as older versions forced strong dependencies on
+ erts internals structures.</p>
+ <p>
+ Own Id: OTP-14238</p>
+ </item>
+ <item>
+ <p>
+ Fix a bug that has been seen causing failed loading of
+ hipe compiled modules on NetBSD due to unaligned data
+ pointers.</p>
+ <p>
+ Own Id: OTP-14302 Aux Id: ERL-376, PR-1386 </p>
+ </item>
+ <item>
+ <p>
+ Fix miscompilation bug in hipe that could cause wrong
+ function clause to be called from non-tail calls, where
+ the return value is unused, if the right function clause
+ is only reachable from those non-tail calls.</p>
+ <p>
+ Own Id: OTP-14306 Aux Id: ERL-278, PR-1392 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improve hipe compilation time for large functions.</p>
+ <p>
+ Own Id: OTP-13810 Aux Id: PR-1124 </p>
+ </item>
+ <item>
+ <p>Replaced usage of deprecated symbolic <seealso
+ marker="erts:erlang#type-time_unit"><c>time
+ unit</c></seealso> representations.</p>
+ <p>
+ Own Id: OTP-13831 Aux Id: OTP-13735 </p>
+ </item>
+ <item>
+ <p>
+ Speed up hipe compile time register allocation for larger
+ function.</p>
+ <p>
+ Own Id: OTP-13879</p>
+ </item>
+ <item>
+ <p>
+ Various code generation improvements.</p>
+ <p>
+ Own Id: OTP-14261 Aux Id: PR-1360 </p>
+ </item>
+ <item>
+ <p>
+ Improve hipe compiler to generate code with better CPU
+ register utilization at runtime by the use of 'Live Range
+ Splitting' techniques.</p>
+ <p>
+ Own Id: OTP-14293 Aux Id: PR-1380 </p>
+ </item>
+ <item>
+ <p>
+ Allow HiPE to run on VM built with
+ <c>--enable-m32-build</c>.</p>
+ <p>
+ Own Id: OTP-14330 Aux Id: PR-1397 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Hipe 3.15.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix a bug concerning parameterized opaque types. </p>
+ <p>
+ Own Id: OTP-14130</p>
+ </item>
+ <item>
+ <p>
+ Fixed xml issues in old release notes</p>
+ <p>
+ Own Id: OTP-14269</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Hipe 3.15.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix flow control bug in hipe compiler that may cause
+ compile time crash.</p>
+ <p>
+ Own Id: OTP-13965 Aux Id: PR-1253 </p>
+ </item>
+ <item>
+ <p>
+ Fix bug in native compilation of bitstring pattern
+ matching causing erroneous runtime matching result. The
+ bug only affects code containing constant-valued segments
+ whose size is expressed in bits; it is triggered when the
+ pattern matching against these segments fails (i.e., when
+ the next clause needs to be tried).</p>
+ <p>
+ Own Id: OTP-14005</p>
+ </item>
+ <item>
+ <p>
+ Workaround in HiPE LLVM backend for a bug in LLVM 3.9.
+ The bug could cause LLVM-compiled modules to be rejected
+ during loading with a badarg exception in
+ hipe_bifs:enter_sdecs/1, but also cause corruption or
+ segmentation faults i runtime.</p>
+ <p>
+ Own Id: OTP-14027 Aux Id: ERL-292, PR-1237 </p>
+ </item>
+ <item>
+ <p>
+ Fix a bug in HiPE LLVM backend involving incorrect type
+ tests of atoms sometimes causing incorrect behaviour or
+ even segfaults.</p>
+ <p>
+ Own Id: OTP-14028 Aux Id: PR-1237 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Hipe 3.15.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed various hipe compiler backend bugs affecting mostly
+ ARM and SPARC.</p>
+ <p>
+ Own Id: OTP-13846 Aux Id: PR-1146 </p>
+ </item>
+ <item>
+ <p>
+ Fixed some Dialyzer warnings and code cleanup for the
+ Sparc compiler backend.</p>
+ <p>
+ Own Id: OTP-13861 Aux Id: PR-1148 </p>
+ </item>
+ <item>
+ <p> Fix erl_bif_types opaque bug. </p>
+ <p>
+ Own Id: OTP-13878 Aux Id: PR-1161, ERL-249 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Fix erl_types opaque match order</p>
+ <p>
+ Own Id: OTP-13876</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Hipe 3.15.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -45,12 +245,12 @@
</item>
<item>
<p>
- Various fixes and improvements to the HiPE LLVM backend.
+ Various fixes and improvements to the HiPE LLVM backend.</p>
<list> <item>Add support for LLVM 3.7 and 3.8 in the
HiPE/LLVM x86_64 backend</item> <item>Reinstate support
for the LLVM backend on x86 (works OK for LLVM 3.5 to 3.7
-- LLVM 3.8 has a bug that prevents it from generating
- correct native code on x86)</item> </list></p>
+ correct native code on x86)</item> </list>
<p>
Own Id: OTP-13626</p>
</item>
@@ -106,7 +306,7 @@
<item>
<p>
Fix various binary construction inconsistencies for hipe
- compiled code. <list> <item>Passing bad field sizes to
+ compiled code.</p> <list> <item>Passing bad field sizes to
binary constructions would throw <c>badarith</c> rather
than <c>badarg</c>. Worse, in guards, when the unit size
of the field was 1, the exception would leak rather than
@@ -126,7 +326,7 @@
missing check for unit size match when inserting a
binary. For example, a faulty expression like
<c>&lt;&lt;&lt;&lt;1:7&gt;&gt;/binary&gt;&gt;</c> would
- succeed.</item> </list></p>
+ succeed.</item> </list>
<p>
Own Id: OTP-13272</p>
</item>
@@ -1212,7 +1412,7 @@
<list>
<item>
<p>
- Miscellanous updates.</p>
+ Miscellaneous updates.</p>
<p>
Own Id: OTP-8038</p>
</item>
diff --git a/lib/hipe/flow/cfg.hrl b/lib/hipe/flow/cfg.hrl
index 2575b9e38a..8d0f8855bb 100644
--- a/lib/hipe/flow/cfg.hrl
+++ b/lib/hipe/flow/cfg.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,15 +11,11 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%============================================================================
%% File : cfg.hrl
%% Author : Kostis Sagonas <[email protected]>
%% Purpose : Contains typed record declarations for the CFG data structures
-%%
-%% $Id$
%%============================================================================
-type cfg_lbl() :: non_neg_integer().
diff --git a/lib/hipe/flow/cfg.inc b/lib/hipe/flow/cfg.inc
index 0bad2a8dd7..17342d3b60 100644
--- a/lib/hipe/flow/cfg.inc
+++ b/lib/hipe/flow/cfg.inc
@@ -2,10 +2,6 @@
%% -*- erlang-indent-level: 2 -*-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -17,8 +13,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -32,6 +26,8 @@
%% bb(CFG, Label) - returns the basic block named 'Label' from the CFG.
%% bb_add(CFG, Label, NewBB) - makes NewBB the basic block associated
%% with Label.
+%% map_bbs(Fun, CFG) - map over all code without changing control flow.
+%% fold_bbs(Fun, Acc, CFG) - fold over the basic blocks in a CFG.
%% succ(Map, Label) - returns a list of successors of basic block 'Label'.
%% pred(Map, Label) - returns the predecessors of basic block 'Label'.
%% fallthrough(CFG, Label) - returns fall-through successor of basic
@@ -89,6 +85,7 @@
-define(BREADTH_ORDER,true). % for linear scan
-define(PARAMS_NEEDED,true).
-define(START_LABEL_UPDATE_NEEDED,true).
+-define(MAP_FOLD_NEEDED,true).
-endif.
%%=====================================================================
@@ -215,7 +212,7 @@ info_update(CFG, I) ->
-ifndef(GEN_CFG).
-spec other_entrypoints(cfg()) -> [cfg_lbl()].
-%% @doc Returns a list of labels that are refered to from the data section.
+%% @doc Returns a list of labels that are referred to from the data section.
other_entrypoints(CFG) ->
hipe_consttab:referred_labels(data(CFG)).
@@ -307,11 +304,7 @@ redirect_phis([I|Rest], OldPred, NewPred, Acc) ->
%% @doc Adds a new basic block to a CFG (or updates an existing block).
bb_add(CFG, Label, NewBB) ->
%% Asserting that the NewBB is a legal basic block
- Last = hipe_bb:last(NewBB),
- case is_branch(Last) of
- true -> ok;
- false -> throw({?MODULE, {"Basic block ends without branch", Last}})
- end,
+ Last = assert_bb(NewBB),
%% The order of the elements from branch_successors/1 is
%% significant. It determines the basic block order when the CFG is
%% converted to linear form. That order may have been tuned for
@@ -339,11 +332,53 @@ bb_add(CFG, Label, NewBB) ->
HT2, OldSucc -- Succ),
CFG#cfg{table = HT3}.
+-ifdef(MAP_FOLD_NEEDED).
+-spec map_bbs(fun((cfg_lbl(), hipe_bb:bb()) -> hipe_bb:bb()), cfg()) -> cfg().
+%% @doc Map over the code in a CFG without changing any control flow.
+map_bbs(Fun, CFG = #cfg{table=HT0}) ->
+ HT = gb_trees:map(
+ fun(Lbl, {OldBB, OldSucc, OldPred}) ->
+ NewBB = Fun(Lbl, OldBB),
+ %% Assert preconditions
+ NewLast = assert_bb(NewBB),
+ OldSucc = remove_duplicates(branch_successors(NewLast)),
+ {NewBB, OldSucc, OldPred}
+ end, HT0),
+ CFG#cfg{table=HT}.
+
+-spec fold_bbs(fun((cfg_lbl(), hipe_bb:bb(), Acc) -> Acc), Acc, cfg()) -> Acc.
+%% @doc Fold over the basic blocks in a CFG in unspecified order.
+fold_bbs(Fun, InitAcc, #cfg{table=HT}) ->
+ gb_trees_fold(fun(Lbl, {BB, _, _}, Acc) -> Fun(Lbl, BB, Acc) end,
+ InitAcc, HT).
+
+gb_trees_fold(Fun, InitAcc, Tree) ->
+ gb_trees_fold_1(Fun, InitAcc, gb_trees:iterator(Tree)).
+
+gb_trees_fold_1(Fun, InitAcc, Iter0) ->
+ case gb_trees:next(Iter0) of
+ none -> InitAcc;
+ {Key, Value, Iter} ->
+ gb_trees_fold_1(Fun, Fun(Key, Value, InitAcc), Iter)
+ end.
+-endif. % MAP_FOLD_NEEDED
+
+assert_bb(BB) ->
+ assert_bb_is(hipe_bb:code(BB)).
+
+assert_bb_is([Last]) ->
+ true = is_branch(Last),
+ Last;
+assert_bb_is([I|Is]) ->
+ false = is_branch(I),
+ false = is_label(I),
+ assert_bb_is(Is).
+
remove_pred(HT, FromL, PredL) ->
case gb_trees:lookup(FromL, HT) of
{value, {Block, Succ, Preds}} ->
Code = hipe_bb:code(Block),
- NewCode = remove_pred_from_phis(Code, PredL, []),
+ NewCode = remove_pred_from_phis(PredL, Code),
NewBlock = hipe_bb:code_update(Block, NewCode),
gb_trees:update(FromL, {NewBlock,Succ,lists:delete(PredL,Preds)}, HT);
none ->
@@ -374,20 +409,20 @@ add_pred(HT, ToL, PredL) ->
-ifdef(CFG_CAN_HAVE_PHI_NODES).
%% phi-instructions in a removed block's successors must be aware of
%% the change.
-remove_pred_from_phis(List = [I|Left], Label, Acc) ->
+remove_pred_from_phis(Label, List = [I|Left]) ->
case is_phi(I) of
- true ->
- NewAcc = [phi_remove_pred(I, Label)|Acc],
- remove_pred_from_phis(Left, Label, NewAcc);
+ true ->
+ NewI = phi_remove_pred(I, Label),
+ [NewI | remove_pred_from_phis(Label, Left)];
false ->
- lists:reverse(Acc) ++ List
+ List
end;
-remove_pred_from_phis([], _Label, Acc) ->
- lists:reverse(Acc).
+remove_pred_from_phis(_Label, []) ->
+ [].
-else.
%% this is used for code representations like those of back-ends which
%% do not have phi-nodes.
-remove_pred_from_phis(Code, _Label, _Acc) ->
+remove_pred_from_phis(_Label, Code) ->
Code.
-endif.
@@ -927,24 +962,52 @@ merge(BB, BB2, BB2_Label) ->
remove_unreachable_code(CFG) ->
Start = start_label(CFG),
- Reachable = find_reachable([Start], CFG, gb_sets:from_list([Start])),
- %% Reachable is an ordset: it comes from gb_sets:to_list/1.
- %% So use ordset:subtract instead of '--' below.
- Labels = ordsets:from_list(labels(CFG)),
- case ordsets:subtract(Labels, Reachable) of
- [] ->
- CFG;
+ %% No unreachable block will make another block reachable, so no fixpoint
+ %% looping is required
+ Reachable = find_reachable([], [Start], CFG, #{Start=>[]}),
+ case [L || L <- labels(CFG), not maps:is_key(L, Reachable)] of
+ [] -> CFG;
Remove ->
- NewCFG = lists:foldl(fun(X, Acc) -> bb_remove(Acc, X) end, CFG, Remove),
- remove_unreachable_code(NewCFG)
+ HT0 = CFG#cfg.table,
+ HT1 = lists:foldl(fun gb_trees:delete/2, HT0, Remove),
+ ReachableP = fun(Lbl) -> maps:is_key(Lbl, Reachable) end,
+ HT = gb_trees:map(fun(_,B)->prune_preds(B, ReachableP)end, HT1),
+ CFG#cfg{table=HT}
end.
-find_reachable([Label|Left], CFG, Acc) ->
- NewAcc = gb_sets:add(Label, Acc),
- Succ = succ(CFG, Label),
- find_reachable([X || X <- Succ, not gb_sets:is_member(X, Acc)] ++ Left,
- CFG, NewAcc);
-find_reachable([], _CFG, Acc) ->
- gb_sets:to_list(Acc).
+find_reachable([], [], _CFG, Acc) -> Acc;
+find_reachable([Succ|Succs], Left, CFG, Acc) ->
+ case Acc of
+ #{Succ := _} -> find_reachable(Succs, Left, CFG, Acc);
+ #{} -> find_reachable(Succs, [Succ|Left], CFG, Acc#{Succ => []})
+ end;
+find_reachable([], [Label|Left], CFG, Acc) ->
+ find_reachable(succ(CFG, Label), Left, CFG, Acc).
+
+%% Batch prune unreachable predecessors. Asymptotically faster than deleting
+%% unreachable blocks one at a time with bb_remove, at least when
+%% CFG_CAN_HAVE_PHI_NODES is undefined. Otherwise a phi_remove_preds might be
+%% needed to achieve that.
+prune_preds(B={Block, Succ, Preds}, ReachableP) ->
+ case lists:partition(ReachableP, Preds) of
+ {_, []} -> B;
+ {NewPreds, Unreach} ->
+ NewCode = remove_preds_from_phis(Unreach, hipe_bb:code(Block)),
+ {hipe_bb:code_update(Block, NewCode), Succ, NewPreds}
+ end.
+-ifdef(CFG_CAN_HAVE_PHI_NODES).
+remove_preds_from_phis(_, []) -> [];
+remove_preds_from_phis(Preds, List=[I|Left]) ->
+ case is_phi(I) of
+ false -> List;
+ true ->
+ NewI = lists:foldl(fun(L,IA)->phi_remove_pred(IA,L)end,
+ I, Preds),
+ [NewI | remove_preds_from_phis(Preds, Left)]
+ end.
+-else.
+remove_preds_from_phis(_, Code) -> Code.
-endif.
+
+-endif. %% -ifdef(REMOVE_UNREACHABLE_CODE)
diff --git a/lib/hipe/flow/ebb.inc b/lib/hipe/flow/ebb.inc
index 529be72dc8..e4b7fd0efb 100644
--- a/lib/hipe/flow/ebb.inc
+++ b/lib/hipe/flow/ebb.inc
@@ -1,9 +1,5 @@
%% -*- Erlang -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -46,12 +40,14 @@
%% | {ebb_leaf, SuccesorLabel}
%%--------------------------------------------------------------------
-%% XXX: Cheating big time! no recursive types
--type ebb() :: {ebb_node, icode_lbl(), _}
- | {ebb_leaf, icode_lbl()}.
+-type ebb() :: ebb_node()
+ | ebb_leaf().
-record(ebb_node, {label :: icode_lbl(), successors :: [ebb()]}).
+-type ebb_node() :: #ebb_node{}.
+
-record(ebb_leaf, {successor :: icode_lbl()}).
+-type ebb_leaf() :: #ebb_leaf{}.
%%--------------------------------------------------------------------
%% Returns a list of extended basic blocks.
@@ -199,7 +195,7 @@ add_succ([Lbl|Lbls], Visited, Node, MkFun, EBBs, CFG) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec mk_node(icode_lbl(), [ebb()]) -> #ebb_node{}.
+-spec mk_node(icode_lbl(), [ebb()]) -> ebb_node().
mk_node(Label, Successors) -> #ebb_node{label=Label, successors=Successors}.
-spec node_label(#ebb_node{}) -> icode_lbl().
@@ -208,11 +204,11 @@ node_label(#ebb_node{label=Label}) -> Label.
-spec node_successors(#ebb_node{}) -> [ebb()].
node_successors(#ebb_node{successors=Successors}) -> Successors.
--spec mk_leaf(icode_lbl()) -> #ebb_leaf{}.
+-spec mk_leaf(icode_lbl()) -> ebb_leaf().
mk_leaf(NextEbb) -> #ebb_leaf{successor=NextEbb}.
%% leaf_next(Leaf) -> Leaf#ebb_leaf.successor.
--spec type(#ebb_node{}) -> 'node' ; (#ebb_leaf{}) -> 'leaf'.
+-spec type(ebb_node()) -> 'node' ; (ebb_leaf()) -> 'leaf'.
type(#ebb_node{}) -> node;
type(#ebb_leaf{}) -> leaf.
diff --git a/lib/hipe/flow/hipe_bb.erl b/lib/hipe/flow/hipe_bb.erl
index 2da3a6dc99..f4dad59e61 100644
--- a/lib/hipe/flow/hipe_bb.erl
+++ b/lib/hipe/flow/hipe_bb.erl
@@ -1,8 +1,4 @@
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +10,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -41,6 +35,8 @@
-include("hipe_bb.hrl").
+-export_type([bb/0]).
+
%%
%% Constructs a basic block.
%% Returns a basic block: {bb, Code}
diff --git a/lib/hipe/flow/hipe_bb.hrl b/lib/hipe/flow/hipe_bb.hrl
index cd4d788aef..5cb5c1b370 100644
--- a/lib/hipe/flow/hipe_bb.hrl
+++ b/lib/hipe/flow/hipe_bb.hrl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%-------------------------------------------------------------------
%%% File : bb.hrl
diff --git a/lib/hipe/flow/hipe_dominators.erl b/lib/hipe/flow/hipe_dominators.erl
index 72c16b5688..749edd4f72 100644
--- a/lib/hipe/flow/hipe_dominators.erl
+++ b/lib/hipe/flow/hipe_dominators.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%------------------------------------------------------------------------
%% File : hipe_dominators.erl
%% Author : Christoffer Vikström <[email protected]>
@@ -323,7 +317,7 @@ updateCell(Value, Field, WD) ->
%%>----------------------------------------------------------------------<
%% Procedure : dfs/1
%% Purpose : The main purpose of this function is to traverse the CFG in
-%% a depth first order. It is aslo used to initialize certain
+%% a depth first order. It is also used to initialize certain
%% elements defined in a workDataCell.
%% Arguments : CFG - a Control Flow Graph representation
%% Returns : A table (WorkData) and the total number of elements in
diff --git a/lib/hipe/flow/hipe_gen_cfg.erl b/lib/hipe/flow/hipe_gen_cfg.erl
index a6d053f505..cc3a1b5b73 100644
--- a/lib/hipe/flow/hipe_gen_cfg.erl
+++ b/lib/hipe/flow/hipe_gen_cfg.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,9 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_gen_cfg).
@@ -35,4 +27,3 @@
-spec pred(cfg(), cfg_lbl()) -> [cfg_lbl()].
-include("cfg.inc").
-
diff --git a/lib/hipe/flow/liveness.inc b/lib/hipe/flow/liveness.inc
index a1caa3e0ad..3e9d7b3c96 100644
--- a/lib/hipe/flow/liveness.inc
+++ b/lib/hipe/flow/liveness.inc
@@ -1,10 +1,6 @@
%% -*- Erlang -*-
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -49,6 +43,10 @@
-endif.
-include("../flow/cfg.hrl").
+-include("../main/hipe.hrl").
+
+-opaque liveness() :: map().
+-export_type([liveness/0]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -72,7 +70,7 @@
%% The generic liveness analysis
%%
--spec analyze(cfg()) -> gb_trees:tree().
+-spec analyze(cfg()) -> liveness().
-ifdef(HIPE_LIVENESS_CALC_LARGEST_LIVESET).
analyze(CFG) ->
@@ -188,6 +186,7 @@ update_livein(Label, NewLiveIn, Liveness) ->
%%
%% LiveOut for a block is the union of the successors LiveIn
%%
+-spec liveout(liveness(), _) -> [_].
liveout(Liveness, L) ->
Succ = successors(L, Liveness),
@@ -210,7 +209,7 @@ successors(L, Liveness) ->
{_GK, _LiveIn, Successors} = liveness_lookup(L, Liveness),
Successors.
--spec livein(gb_trees:tree(), _) -> [_].
+-spec livein(liveness(), _) -> [_].
livein(Liveness, L) ->
{_GK, LiveIn, _Successors} = liveness_lookup(L, Liveness),
@@ -292,18 +291,15 @@ strip([{_,Y}|Xs]) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
+-compile({inline, [liveness_lookup/2, liveness_update/3]}).
+
liveness_init(List) ->
- liveness_init(List, gb_trees:empty()).
+ maps:from_list(List).
-liveness_init([{Lbl, Data}|Left], Acc) ->
- liveness_init(Left, gb_trees:insert(Lbl, Data, Acc));
-liveness_init([], Acc) ->
- Acc.
-
liveness_lookup(Label, Liveness) ->
- gb_trees:get(Label, Liveness).
+ maps:get(Label, Liveness).
liveness_update(Label, Val, Liveness) ->
- gb_trees:update(Label, Val, Liveness).
+ maps:update(Label, Val, Liveness).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl
index 224aacd8d7..2abecf7f18 100644
--- a/lib/hipe/icode/hipe_beam_to_icode.erl
+++ b/lib/hipe/icode/hipe_beam_to_icode.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%=======================================================================
%% File : hipe_beam_to_icode.erl
%% Author : Kostis Sagonas
@@ -154,7 +148,8 @@ trans_mfa_code(M,F,A, FunBeamCode, ClosureInfo) ->
{Code3,_Env3} = mk_debug_calltrace(MFA, Env1, Code2),
{Code3,_Env3} = {Code2,Env1}),
%% For stack optimization
- Leafness = leafness(Code3),
+ IsClosure = get_closure_info(MFA, ClosureInfo) =/= not_a_closure,
+ Leafness = leafness(Code3, IsClosure),
IsLeaf = is_leaf_code(Leafness),
Code4 =
[FunLbl |
@@ -162,7 +157,6 @@ trans_mfa_code(M,F,A, FunBeamCode, ClosureInfo) ->
false -> Code3;
true -> [mk_redtest()|Code3]
end],
- IsClosure = get_closure_info(MFA, ClosureInfo) =/= not_a_closure,
Code5 = hipe_icode:mk_icode(MFA, FunArgs, IsClosure, IsLeaf,
remove_dead_code(Code4),
hipe_gensym:var_range(icode),
@@ -179,12 +173,12 @@ trans_mfa_code(M,F,A, FunBeamCode, ClosureInfo) ->
mk_redtest() -> hipe_icode:mk_primop([], redtest, []).
-leafness(Is) -> % -> true, selfrec, or false
- leafness(Is, true).
+leafness(Is, IsClosure) -> % -> true, selfrec, closure, or false
+ leafness(Is, IsClosure, true).
-leafness([], Leafness) ->
+leafness([], _IsClosure, Leafness) ->
Leafness;
-leafness([I|Is], Leafness) ->
+leafness([I|Is], IsClosure, Leafness) ->
case I of
#icode_comment{} ->
%% BEAM self-tailcalls become gotos, but they leave
@@ -197,7 +191,7 @@ leafness([I|Is], Leafness) ->
'self_tail_recursive' -> selfrec; % call_only to selfrec
_ -> Leafness
end,
- leafness(Is, NewLeafness);
+ leafness(Is, IsClosure, NewLeafness);
#icode_call{} ->
case hipe_icode:call_type(I) of
'primop' ->
@@ -205,12 +199,12 @@ leafness([I|Is], Leafness) ->
call_fun -> false; % Calls closure
enter_fun -> false; % Calls closure
#apply_N{} -> false;
- _ -> leafness(Is, Leafness) % Other primop calls are ok
+ _ -> leafness(Is, IsClosure, Leafness) % Other primop calls are ok
end;
T when T =:= 'local' orelse T =:= 'remote' ->
{M,F,A} = hipe_icode:call_fun(I),
case erlang:is_builtin(M, F, A) of
- true -> leafness(Is, Leafness);
+ true -> leafness(Is, IsClosure, Leafness);
false -> false
end
end;
@@ -229,11 +223,12 @@ leafness([I|Is], Leafness) ->
T when T =:= 'local' orelse T =:= 'remote' ->
{M,F,A} = hipe_icode:enter_fun(I),
case erlang:is_builtin(M, F, A) of
- true -> leafness(Is, Leafness);
+ true -> leafness(Is, IsClosure, Leafness);
+ _ when IsClosure -> leafness(Is, IsClosure, closure);
_ -> false
end
end;
- _ -> leafness(Is, Leafness)
+ _ -> leafness(Is, IsClosure, Leafness)
end.
%% XXX: this old stuff is passed around but essentially unused
@@ -241,12 +236,20 @@ is_leaf_code(Leafness) ->
case Leafness of
true -> true;
selfrec -> true;
+ closure -> false;
false -> false
end.
needs_redtest(Leafness) ->
case Leafness of
true -> false;
+ %% A "leaf" closure may contain tailcalls to non-closures in addition to
+ %% what other leaves may contain. Omitting the redtest is useful to generate
+ %% shorter code for closures generated by (fun F/A), and is safe since
+ %% control flow cannot return to a "leaf" closure again without a reduction
+ %% being consumed. This is true since no function that can call a closure
+ %% will ever have its redtest omitted.
+ closure -> false;
selfrec -> true;
false -> true
end.
@@ -510,6 +513,19 @@ trans_fun([{test,test_arity,{f,Lbl},[Reg,N]}|Instructions], Env) ->
I = hipe_icode:mk_type([trans_arg(Reg)],{tuple,N},
hipe_icode:label_name(True),map_label(Lbl)),
[I,True | trans_fun(Instructions,Env)];
+%%--- test_is_tagged_tuple ---
+trans_fun([{test,is_tagged_tuple,{f,Lbl},[Reg,N,Atom]}|Instructions], Env) ->
+ TrueArity = mk_label(new),
+ IArity = hipe_icode:mk_type([trans_arg(Reg)],{tuple,N},
+ hipe_icode:label_name(TrueArity),map_label(Lbl)),
+ Var = hipe_icode:mk_new_var(),
+ IGet = hipe_icode:mk_primop([Var],
+ #unsafe_element{index=1},
+ [trans_arg(Reg)]),
+ TrueAtom = mk_label(new),
+ IEQ = hipe_icode:mk_type([Var], Atom, hipe_icode:label_name(TrueAtom),
+ map_label(Lbl)),
+ [IArity,TrueArity,IGet,IEQ,TrueAtom | trans_fun(Instructions,Env)];
%%--- is_map ---
trans_fun([{test,is_map,{f,Lbl},[Arg]}|Instructions], Env) ->
{Code,Env1} = trans_type_test(map,Lbl,Arg,Env),
@@ -763,32 +779,10 @@ trans_fun([{test,bs_test_unit,{f,Lbl},[Ms,Unit]}|
[MsVar], [], Env, Instructions);
trans_fun([{test,bs_match_string,{f,Lbl},[Ms,BitSize,Bin]}|
Instructions], Env) ->
- True = mk_label(new),
- FalseLabName = map_label(Lbl),
- TrueLabName = hipe_icode:label_name(True),
+ %% the current match buffer
MsVar = mk_var(Ms),
- TmpVar = mk_var(new),
- ByteSize = BitSize div 8,
- ExtraBits = BitSize rem 8,
- WordSize = hipe_rtl_arch:word_size(),
- if ExtraBits =:= 0 ->
- trans_op_call({hipe_bs_primop,{bs_match_string,Bin,ByteSize}}, Lbl,
- [MsVar], [MsVar], Env, Instructions);
- BitSize =< ((WordSize * 8) - 5) ->
- <<Int:BitSize, _/bits>> = Bin,
- {I1,Env1} = trans_one_op_call({hipe_bs_primop,{bs_get_integer,BitSize,0}}, Lbl,
- [MsVar], [TmpVar, MsVar], Env),
- I2 = hipe_icode:mk_type([TmpVar], {integer,Int}, TrueLabName, FalseLabName),
- I1 ++ [I2,True] ++ trans_fun(Instructions, Env1);
- true ->
- <<RealBin:ByteSize/binary, Int:ExtraBits, _/bits>> = Bin,
- {I1,Env1} = trans_one_op_call({hipe_bs_primop,{bs_match_string,RealBin,ByteSize}}, Lbl,
- [MsVar], [MsVar], Env),
- {I2,Env2} = trans_one_op_call({hipe_bs_primop,{bs_get_integer,ExtraBits,0}}, Lbl,
- [MsVar], [TmpVar, MsVar], Env1),
- I3 = hipe_icode:mk_type([TmpVar], {integer,Int}, TrueLabName, FalseLabName),
- I1 ++ I2 ++ [I3,True] ++ trans_fun(Instructions, Env2)
- end;
+ Primop = {hipe_bs_primop, {bs_match_string, Bin, BitSize}},
+ trans_op_call(Primop, Lbl, [MsVar], [MsVar], Env, Instructions);
trans_fun([{bs_context_to_binary,Var}|Instructions], Env) ->
%% the current match buffer
IVars = [trans_arg(Var)],
diff --git a/lib/hipe/icode/hipe_icode.erl b/lib/hipe/icode/hipe_icode.erl
index 78508dff22..24b7ac4783 100644
--- a/lib/hipe/icode/hipe_icode.erl
+++ b/lib/hipe/icode/hipe_icode.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% HiPE Intermediate Code
%% ====================================================================
@@ -30,9 +24,6 @@
%% 2003-03-15 ES ([email protected]):
%% Started commenting in Edoc.
%% Moved pretty printer to separate file.
-%%
-%% $Id$
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%@doc
@@ -438,6 +429,7 @@
if_true_label/1,
if_false_label/1,
if_args/1,
+ if_args_update/2,
if_pred/1,
%% is_if/1,
@@ -594,6 +586,7 @@
uses/1,
defines/1,
is_safe/1,
+ reduce_unused/1,
strip_comments/1,
subst/2,
subst_uses/2,
@@ -713,6 +706,9 @@ if_op_update(IF, NewOp) -> IF#icode_if{op=NewOp}.
-spec if_args(#icode_if{}) -> [icode_term_arg()].
if_args(#icode_if{args=Args}) -> Args.
+-spec if_args_update(#icode_if{}, [icode_term_arg()]) -> #icode_if{}.
+if_args_update(IF, Args) -> IF#icode_if{args=Args}.
+
-spec if_true_label(#icode_if{}) -> icode_lbl().
if_true_label(#icode_if{true_label=TrueLbl}) -> TrueLbl.
@@ -1765,6 +1761,18 @@ is_safe(Instr) ->
#icode_end_try{} -> false
end.
+%% @doc Produces a simplified instruction sequence that is equivalent to [Instr]
+%% under the assumption that all results of Instr are unused, or 'false' if
+%% there is no such sequence (other than [Instr] itself).
+
+-spec reduce_unused(icode_instr()) -> false | [icode_instr()].
+
+reduce_unused(Instr) ->
+ case is_safe(Instr) of
+ true -> [];
+ false -> false
+ end.
+
%%-----------------------------------------------------------------------
-spec highest_var(icode_instrs()) -> non_neg_integer().
diff --git a/lib/hipe/icode/hipe_icode.hrl b/lib/hipe/icode/hipe_icode.hrl
index b2e0d86b28..380ddd8371 100644
--- a/lib/hipe/icode/hipe_icode.hrl
+++ b/lib/hipe/icode/hipe_icode.hrl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%=====================================================================
%%
diff --git a/lib/hipe/icode/hipe_icode_bincomp.erl b/lib/hipe/icode/hipe_icode_bincomp.erl
index 5a27519141..f88637e526 100644
--- a/lib/hipe/icode/hipe_icode_bincomp.erl
+++ b/lib/hipe/icode/hipe_icode_bincomp.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_icode_bincomp.erl
@@ -40,8 +34,8 @@
-spec cfg(cfg()) -> cfg().
cfg(Cfg1) ->
- StartLbls = ordsets:from_list([hipe_icode_cfg:start_label(Cfg1)]),
- find_bs_get_integer(StartLbls, Cfg1, StartLbls).
+ StartLbl = hipe_icode_cfg:start_label(Cfg1),
+ find_bs_get_integer([StartLbl], Cfg1, set_from_list([StartLbl])).
find_bs_get_integer([Lbl|Rest], Cfg, Visited) ->
BB = hipe_icode_cfg:bb(Cfg, Lbl),
@@ -55,10 +49,10 @@ find_bs_get_integer([Lbl|Rest], Cfg, Visited) ->
not_ok ->
Cfg
end,
- Succs = ordsets:from_list(hipe_icode_cfg:succ(NewCfg, Lbl)),
- NewSuccs = ordsets:subtract(Succs, Visited),
- NewLbls = ordsets:union(NewSuccs, Rest),
- NewVisited = ordsets:union(NewSuccs, Visited),
+ Succs = hipe_icode_cfg:succ(NewCfg, Lbl),
+ NewSuccs = not_visited(Succs, Visited),
+ NewLbls = NewSuccs ++ Rest,
+ NewVisited = set_union(set_from_list(NewSuccs), Visited),
find_bs_get_integer(NewLbls, NewCfg, NewVisited);
find_bs_get_integer([], Cfg, _) ->
Cfg.
@@ -177,3 +171,19 @@ make_butlast([{Res, Size}|Rest], Var) ->
[Var, hipe_icode:mk_const((1 bsl Size)-1)]),
hipe_icode:mk_primop([NewVar], 'bsr', [Var, hipe_icode:mk_const(Size)])
|make_butlast(Rest, NewVar)].
+
+%%--------------------------------------------------------------------
+%% Sets
+
+set_from_list([]) -> #{};
+set_from_list(L) ->
+ maps:from_list([{E, []} || E <- L]).
+
+not_visited([], _) -> [];
+not_visited([E|T], M) ->
+ case M of
+ #{E := _} -> not_visited(T, M);
+ _ -> [E|not_visited(T, M)]
+ end.
+
+set_union(A, B) -> maps:merge(A, B).
diff --git a/lib/hipe/icode/hipe_icode_call_elim.erl b/lib/hipe/icode/hipe_icode_call_elim.erl
index 6a22133962..367ce7cfe5 100644
--- a/lib/hipe/icode/hipe_icode_call_elim.erl
+++ b/lib/hipe/icode/hipe_icode_call_elim.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%----------------------------------------------------------------------
%% File : hipe_icode_call_elim.erl
%% Authors : Daniel S. McCain <[email protected]>,
@@ -46,7 +39,8 @@ cfg(IcodeSSA) ->
-spec elim_insn(icode_instr()) -> icode_instr().
elim_insn(Insn=#icode_call{'fun'={_,_,_}=MFA, args=Args, type=remote,
dstlist=[Dst=#icode_variable{
- annotation={type_anno, RetType, _}}]}) ->
+ annotation={type_anno, RetType, _}}],
+ continuation=[], fail_label=[]}) ->
Opaques = 'universe',
case erl_types:t_is_singleton(RetType, Opaques) of
true ->
diff --git a/lib/hipe/icode/hipe_icode_callgraph.erl b/lib/hipe/icode/hipe_icode_callgraph.erl
index 12c2cd2b44..365c65315e 100644
--- a/lib/hipe/icode/hipe_icode_callgraph.erl
+++ b/lib/hipe/icode/hipe_icode_callgraph.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-----------------------------------------------------------------------
%% File : hipe_icode_callgraph.erl
diff --git a/lib/hipe/icode/hipe_icode_cfg.erl b/lib/hipe/icode/hipe_icode_cfg.erl
index 9a602c0283..c5f5592cc9 100644
--- a/lib/hipe/icode/hipe_icode_cfg.erl
+++ b/lib/hipe/icode/hipe_icode_cfg.erl
@@ -1,10 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
-%%======================================================================
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_icode_cfg).
diff --git a/lib/hipe/icode/hipe_icode_coordinator.erl b/lib/hipe/icode/hipe_icode_coordinator.erl
index d2f8748535..4ef210eca4 100644
--- a/lib/hipe/icode/hipe_icode_coordinator.erl
+++ b/lib/hipe/icode/hipe_icode_coordinator.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%--------------------------------------------------------------------
%% File : hipe_icode_coordinator.erl
@@ -106,12 +100,29 @@ handle_no_change_done(MFA, {Queue, Busy}) ->
{Queue, Busy -- [MFA]}.
last_action(PM, ServerPid, Mod, All) ->
- lists:foreach(fun (MFA) ->
- gb_trees:get(MFA, PM) ! {done, final_funs(ServerPid, Mod)},
- receive
- {done_rewrite, MFA} -> ok
- end
- end, All).
+ last_action(PM, ServerPid, Mod, All, []).
+
+last_action(_, _, _, [], []) -> ok;
+last_action(PM, ServerPid, Mod, [], [MFA|Busy]) ->
+ receive
+ {done_rewrite, MFA} ->
+ last_action(PM, ServerPid, Mod, [], Busy)
+ end;
+last_action(PM, ServerPid, Mod, All0, Busy) ->
+ receive
+ {done_rewrite, MFA} ->
+ last_action(PM, ServerPid, Mod, All0, Busy -- [MFA])
+ after 0 ->
+ case ?MAX_CONCURRENT - length(Busy) of
+ X when is_integer(X), X > 0 ->
+ [MFA|All1] = All0,
+ gb_trees:get(MFA, PM) ! {done, final_funs(ServerPid, Mod)},
+ last_action(PM, ServerPid, Mod, All1, [MFA|Busy]);
+ X when is_integer(X) ->
+ Busy1 = receive {done_rewrite, MFA} -> Busy -- [MFA] end,
+ last_action(PM, ServerPid, Mod, All0, Busy1)
+ end
+ end.
restart_funs({Queue, Busy} = QB, PM, All, ServerPid) ->
case ?MAX_CONCURRENT - length(Busy) of
diff --git a/lib/hipe/icode/hipe_icode_ebb.erl b/lib/hipe/icode/hipe_icode_ebb.erl
index 2aac9d2f42..2cc4321fb8 100644
--- a/lib/hipe/icode/hipe_icode_ebb.erl
+++ b/lib/hipe/icode/hipe_icode_ebb.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,14 +9,12 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Icode version of extended basic blocks.
%%
-
+
-module(hipe_icode_ebb).
-define(CFG, hipe_icode_cfg).
diff --git a/lib/hipe/icode/hipe_icode_exceptions.erl b/lib/hipe/icode/hipe_icode_exceptions.erl
index f03ce2faaa..0039eb5091 100644
--- a/lib/hipe/icode/hipe_icode_exceptions.erl
+++ b/lib/hipe/icode/hipe_icode_exceptions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ====================================================================
%% Filename : hipe_icode_exceptions.erl
@@ -71,9 +65,6 @@
%% exit value and jump directly to the catch handler. An
%% alternative solution would be to have a new type of
%% fail instruction that takes a fail-to label...
-%%
-%% CVS:
-%% $Id$
%% ====================================================================
-module(hipe_icode_exceptions).
diff --git a/lib/hipe/icode/hipe_icode_fp.erl b/lib/hipe/icode/hipe_icode_fp.erl
index 4a5877074c..4933ee96b4 100644
--- a/lib/hipe/icode/hipe_icode_fp.erl
+++ b/lib/hipe/icode/hipe_icode_fp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%--------------------------------------------------------------------
%% File : hipe_icode_fp.erl
diff --git a/lib/hipe/icode/hipe_icode_heap_test.erl b/lib/hipe/icode/hipe_icode_heap_test.erl
index ec754d5ee9..1a4f28e1af 100644
--- a/lib/hipe/icode/hipe_icode_heap_test.erl
+++ b/lib/hipe/icode/hipe_icode_heap_test.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2000 by Erik Johansson. All Rights Reserved
@@ -27,9 +21,6 @@
%% Notes :
%% History : * 2000-11-07 Erik Johansson ([email protected]):
%% Created.
-%%
-%% $Id$
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(hipe_icode_heap_test).
diff --git a/lib/hipe/icode/hipe_icode_inline_bifs.erl b/lib/hipe/icode/hipe_icode_inline_bifs.erl
index 79f67c2db6..7a6947f190 100644
--- a/lib/hipe/icode/hipe_icode_inline_bifs.erl
+++ b/lib/hipe/icode/hipe_icode_inline_bifs.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%--------------------------------------------------------------------
%% File : hipe_icode_inline_bifs.erl
@@ -24,7 +18,7 @@
%% Purpose : Inlines BIFs which can be expressed easily in ICode.
%% This allows for optimizations in later ICode passes
%% and makes the code faster.
-%%
+%%
%% Created : 14 May 2007 by Per Gustafsson <[email protected]>
%%--------------------------------------------------------------------
diff --git a/lib/hipe/icode/hipe_icode_instruction_counter.erl b/lib/hipe/icode/hipe_icode_instruction_counter.erl
index afa70e495b..97a19753a1 100644
--- a/lib/hipe/icode/hipe_icode_instruction_counter.erl
+++ b/lib/hipe/icode/hipe_icode_instruction_counter.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-------------------------------------------------------------------
%% File : icode_instruction_counter.erl
diff --git a/lib/hipe/icode/hipe_icode_liveness.erl b/lib/hipe/icode/hipe_icode_liveness.erl
index 317d2e54c2..51e2855108 100644
--- a/lib/hipe/icode/hipe_icode_liveness.erl
+++ b/lib/hipe/icode/hipe_icode_liveness.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/icode/hipe_icode_mulret.erl b/lib/hipe/icode/hipe_icode_mulret.erl
index d927a46222..227cfadfda 100644
--- a/lib/hipe/icode/hipe_icode_mulret.erl
+++ b/lib/hipe/icode/hipe_icode_mulret.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_icode_mulret.erl
diff --git a/lib/hipe/icode/hipe_icode_pp.erl b/lib/hipe/icode/hipe_icode_pp.erl
index a736b54c38..5b017dca32 100644
--- a/lib/hipe/icode/hipe_icode_pp.erl
+++ b/lib/hipe/icode/hipe_icode_pp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2003 by Erik Stenman.
@@ -26,10 +20,6 @@
%% Purpose : Pretty-printer for Icode.
%% Notes :
%% History : * 2003-04-16 ([email protected]): Created.
-%% CVS :
-%% $Author$
-%% $Date$
-%% $Revision$
%% ====================================================================
%%
%% @doc
diff --git a/lib/hipe/icode/hipe_icode_primops.erl b/lib/hipe/icode/hipe_icode_primops.erl
index cee37b6a57..50ece05259 100644
--- a/lib/hipe/icode/hipe_icode_primops.erl
+++ b/lib/hipe/icode/hipe_icode_primops.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
%% ====================================================================
@@ -287,8 +281,8 @@ pp(Dev, Op) ->
io:format(Dev, "bs_start_match<~w>", [Max]);
{{bs_start_match, Type}, Max} ->
io:format(Dev, "bs_start_match<~w,~w>", [Type,Max]);
- {bs_match_string, String, SizeInBytes} ->
- io:format(Dev, "bs_match_string<~w, ~w>", [String, SizeInBytes]);
+ {bs_match_string, String, SizeInBits} ->
+ io:format(Dev, "bs_match_string<~w, ~w>", [String, SizeInBits]);
{bs_get_integer, Size, Flags} ->
io:format(Dev, "bs_get_integer<~w, ~w>", [Size, Flags]);
{bs_get_float, Size, Flags} ->
@@ -596,10 +590,10 @@ type(Primop, Args) ->
erl_types:t_subtract(Type, erl_types:t_matchstate()),
erl_types:t_matchstate_slot(
erl_types:t_inf(Type, erl_types:t_matchstate()), 0));
- {hipe_bs_primop, {bs_match_string,_,Bytes}} ->
+ {hipe_bs_primop, {bs_match_string,_,Bits}} ->
[MatchState] = Args,
BinType = erl_types:t_matchstate_present(MatchState),
- NewBinType = match_bin(erl_types:t_bitstr(0, Bytes*8), BinType),
+ NewBinType = match_bin(erl_types:t_bitstr(0, Bits), BinType),
erl_types:t_matchstate_update_present(NewBinType, MatchState);
{hipe_bs_primop, {bs_test_unit,Unit}} ->
[MatchState] = Args,
diff --git a/lib/hipe/icode/hipe_icode_primops.hrl b/lib/hipe/icode/hipe_icode_primops.hrl
index a0aee165ba..6c6fbd3dad 100644
--- a/lib/hipe/icode/hipe_icode_primops.hrl
+++ b/lib/hipe/icode/hipe_icode_primops.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,16 +11,12 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%=======================================================================
%% File : hipe_icode_primops.hrl
%% Author : Kostis Sagonas
%% Description : Contains definitions for HiPE's primitive operations.
%%=======================================================================
-%% $Id$
-%%=======================================================================
-record(apply_N, {arity :: arity()}).
diff --git a/lib/hipe/icode/hipe_icode_range.erl b/lib/hipe/icode/hipe_icode_range.erl
index 12ed796690..287b1c80fe 100644
--- a/lib/hipe/icode/hipe_icode_range.erl
+++ b/lib/hipe/icode/hipe_icode_range.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : hipe_icode_range.erl
%%% Author : Per Gustafsson <[email protected]>
@@ -73,8 +67,8 @@
-type final_fun() :: fun((mfa(), [range()]) -> 'ok').
-type data() :: {mfa(), args_fun(), call_fun(), final_fun()}.
-type label() :: non_neg_integer().
--type info() :: gb_trees:tree().
--type work_list() :: {[label()], [label()], sets:set()}.
+-type info() :: map().
+-type work_list() :: {[label()], [label()], set(label())}.
-type variable() :: #icode_variable{}.
-type annotated_variable() :: #icode_variable{}.
-type argument() :: #icode_const{} | variable().
@@ -82,10 +76,9 @@
-type instr_split_info() :: {icode_instr(), [{label(),info()}]}.
-type last_instr_return() :: {instr_split_info(), range()}.
--record(state, {info_map = gb_trees:empty() :: info(),
- counter = dict:new() :: dict:dict(),
- cfg :: cfg(),
- liveness = gb_trees:empty() :: gb_trees:tree(),
+-record(state, {info_map = #{} :: info(),
+ cfg :: cfg(),
+ liveness :: hipe_icode_ssa:liveness(),
ret_type :: range(),
lookup_fun :: call_fun(),
result_action :: final_fun()}).
@@ -187,17 +180,16 @@ safe_analyse(CFG, Data={MFA,_,_,_}) ->
rewrite_blocks(State) ->
CFG = state__cfg(State),
Start = hipe_icode_cfg:start_label(CFG),
- rewrite_blocks([Start], State, [Start]).
+ rewrite_blocks([Start], State, set_from_list([Start])).
--spec rewrite_blocks([label()], state(), [label()]) -> state().
+-spec rewrite_blocks([label()], state(), set(label())) -> state().
rewrite_blocks([Next|Rest], State, Visited) ->
Info = state__info_in(State, Next),
{NewState, NewLabels} = analyse_block(Next, Info, State, true),
- NewLabelsSet = ordsets:from_list(NewLabels),
- RealNew = ordsets:subtract(NewLabelsSet, Visited),
- NewVisited = ordsets:union([RealNew, Visited, [Next]]),
- NewWork = ordsets:union([RealNew, Rest]),
+ RealNew = not_visited(NewLabels, Visited),
+ NewVisited = set_union(set_from_list(RealNew), Visited),
+ NewWork = RealNew ++ Rest,
rewrite_blocks(NewWork, NewState, NewVisited);
rewrite_blocks([], State, _) ->
State.
@@ -400,14 +392,17 @@ widen(#range{range=Old}, #range{range=New}, T = #range{range=Wide}) ->
-spec analyse_call(#icode_call{}, call_fun()) -> #icode_call{}.
analyse_call(Call, LookupFun) ->
+ Args = hipe_icode:args(Call),
+ Fun = hipe_icode:call_fun(Call),
+ Type = hipe_icode:call_type(Call),
+ %% This call has side-effects (it might call LookupFun which sends messages to
+ %% hipe_icode_coordinator to update the argument ranges of Fun), and must thus
+ %% not be moved into the case statement.
+ DstRanges = analyse_call_or_enter_fun(Fun, Args, Type, LookupFun),
case hipe_icode:call_dstlist(Call) of
[] ->
Call;
Dsts ->
- Args = hipe_icode:args(Call),
- Fun = hipe_icode:call_fun(Call),
- Type = hipe_icode:call_type(Call),
- DstRanges = analyse_call_or_enter_fun(Fun, Args, Type, LookupFun),
NewDefs = [update_info(Var, R) || {Var,R} <- lists:zip(Dsts, DstRanges)],
hipe_icode:subst_defines(lists:zip(Dsts, NewDefs), Call)
end.
@@ -1314,16 +1309,15 @@ range_rem(Range1, Range2) ->
Min1_geq_zero = inf_geq(Min1, 0),
Max1_leq_zero = inf_geq(0, Max1),
Max_range2 = inf_max([inf_abs(Min2), inf_abs(Max2)]),
- Max_range2_leq_zero = inf_geq(0, Max_range2),
New_min =
if Min1_geq_zero -> 0;
- Max_range2_leq_zero -> Max_range2;
- true -> inf_inv(Max_range2)
+ Max_range2 =:= 0 -> 0;
+ true -> inf_add(inf_inv(Max_range2), 1)
end,
New_max =
if Max1_leq_zero -> 0;
- Max_range2_leq_zero -> inf_inv(Max_range2);
- true -> Max_range2
+ Max_range2 =:= 0 -> 0;
+ true -> inf_add(Max_range2, -1)
end,
range_init({New_min, New_max}, false).
@@ -1661,8 +1655,8 @@ state__init(Cfg, {MFA, ArgsFun, CallFun, FinalFun}) ->
false ->
NewParams = lists:zipwith(fun update_info/2, Params, Ranges),
NewCfg = hipe_icode_cfg:params_update(Cfg, NewParams),
- Info = enter_defines(NewParams, gb_trees:empty()),
- InfoMap = gb_trees:insert({Start, in}, Info, gb_trees:empty()),
+ Info = enter_defines(NewParams, #{}),
+ InfoMap = #{{Start, in} => Info},
#state{info_map=InfoMap, cfg=NewCfg, liveness=Liveness,
ret_type=none_type(),
lookup_fun=CallFun, result_action=FinalFun}
@@ -1700,7 +1694,7 @@ state__info_in(S, Label) ->
state__info(S, {Label, in}).
state__info(#state{info_map=IM}, Key) ->
- gb_trees:get(Key, IM).
+ maps:get(Key, IM).
state__update_info(State, LabelInfo, Rewrite) ->
update_info(LabelInfo, State, [], Rewrite).
@@ -1721,60 +1715,58 @@ update_info([], State, LabelAcc, _Rewrite) ->
state__info_in_update(S=#state{info_map=IM,liveness=Liveness}, Label, Info) ->
LabelIn = {Label, in},
- case gb_trees:lookup(LabelIn, IM) of
- none ->
+ case IM of
+ #{LabelIn := OldInfo} ->
+ OldVars = maps:keys(OldInfo),
+ case join_info_in(OldVars, OldInfo, Info) of
+ fixpoint ->
+ fixpoint;
+ NewInfo ->
+ S#state{info_map=IM#{LabelIn := NewInfo}}
+ end;
+ _ ->
LiveIn = hipe_icode_ssa:ssa_liveness__livein(Liveness, Label),
NamesLiveIn = [hipe_icode:var_name(Var) || Var <- LiveIn,
hipe_icode:is_var(Var)],
- OldInfo = gb_trees:empty(),
+ OldInfo = #{},
case join_info_in(NamesLiveIn, OldInfo, Info) of
fixpoint ->
- S#state{info_map=gb_trees:insert(LabelIn, OldInfo, IM)};
+ S#state{info_map=IM#{LabelIn => OldInfo}};
NewInfo ->
- S#state{info_map=gb_trees:enter(LabelIn, NewInfo, IM)}
- end;
- {value, OldInfo} ->
- OldVars = gb_trees:keys(OldInfo),
- case join_info_in(OldVars, OldInfo, Info) of
- fixpoint ->
- fixpoint;
- NewInfo ->
- S#state{info_map=gb_trees:update(LabelIn, NewInfo, IM)}
+ S#state{info_map=IM#{LabelIn => NewInfo}}
end
end.
join_info_in(Vars, OldInfo, NewInfo) ->
- case join_info_in(Vars, OldInfo, NewInfo, gb_trees:empty(), false) of
+ case join_info_in(Vars, OldInfo, NewInfo, #{}, false) of
{Res, true} -> Res;
{_, false} -> fixpoint
end.
join_info_in([Var|Left], Info1, Info2, Acc, Changed) ->
- Type1 = gb_trees:lookup(Var, Info1),
- Type2 = gb_trees:lookup(Var, Info2),
- case {Type1, Type2} of
- {none, none} ->
- NewTree = gb_trees:insert(Var, none_type(), Acc),
- join_info_in(Left, Info1, Info2, NewTree, true);
- {none, {value, Val}} ->
- NewTree = gb_trees:insert(Var, Val, Acc),
- join_info_in(Left, Info1, Info2, NewTree, true);
- {{value, Val}, none} ->
- NewTree = gb_trees:insert(Var, Val, Acc),
- join_info_in(Left, Info1, Info2, NewTree, Changed);
- {{value, Val}, {value, Val}} ->
- NewTree = gb_trees:insert(Var, Val, Acc),
+ case {Info1, Info2} of
+ {#{Var := Val}, #{Var := Val}} ->
+ NewTree = Acc#{Var => Val},
join_info_in(Left, Info1, Info2, NewTree, Changed);
- {{value, Val1}, {value, Val2}} ->
- {NewChanged, NewVal} =
+ {#{Var := Val1}, #{Var := Val2}} ->
+ {NewChanged, NewVal} =
case sup(Val1, Val2) of
Val1 ->
{Changed, Val1};
Val ->
{true, Val}
end,
- NewTree = gb_trees:insert(Var, NewVal, Acc),
- join_info_in(Left, Info1, Info2, NewTree, NewChanged)
+ NewTree = Acc#{Var => NewVal},
+ join_info_in(Left, Info1, Info2, NewTree, NewChanged);
+ {_, #{Var := Val}} ->
+ NewTree = Acc#{Var => Val},
+ join_info_in(Left, Info1, Info2, NewTree, true);
+ {#{Var := Val}, _} ->
+ NewTree = Acc#{Var => Val},
+ join_info_in(Left, Info1, Info2, NewTree, Changed);
+ {_, _} ->
+ NewTree = Acc#{Var => none_type()},
+ join_info_in(Left, Info1, Info2, NewTree, true)
end;
join_info_in([], _Info1, _Info2, Acc, NewChanged) ->
{Acc, NewChanged}.
@@ -1786,7 +1778,7 @@ enter_defines([], Info) -> Info.
enter_define({PossibleVar, Range = #range{}}, Info) ->
case hipe_icode:is_var(PossibleVar) of
true ->
- gb_trees:enter(hipe_icode:var_name(PossibleVar), Range, Info);
+ Info#{hipe_icode:var_name(PossibleVar) => Range};
false ->
Info
end;
@@ -1795,7 +1787,7 @@ enter_define(PossibleVar, Info) ->
true ->
case hipe_icode:variable_annotation(PossibleVar) of
{range_anno, #ann{range=Range}, _} ->
- gb_trees:enter(hipe_icode:var_name(PossibleVar), Range, Info);
+ Info#{hipe_icode:var_name(PossibleVar) => Range};
_ ->
Info
end;
@@ -1810,11 +1802,10 @@ enter_vals(Ins, Info) ->
lookup(PossibleVar, Info) ->
case hipe_icode:is_var(PossibleVar) of
true ->
- case gb_trees:lookup(hipe_icode:var_name(PossibleVar), Info) of
- none ->
- none_type();
- {value, Val} ->
- Val
+ PossibleVarName = hipe_icode:var_name(PossibleVar),
+ case Info of
+ #{PossibleVarName := Val} -> Val;
+ _ -> none_type()
end;
false ->
none_type()
@@ -1828,10 +1819,10 @@ lookup(PossibleVar, Info) ->
init_work(State) ->
%% Labels = hipe_icode_cfg:reverse_postorder(state__cfg(State)),
Labels = [hipe_icode_cfg:start_label(state__cfg(State))],
- {Labels, [], sets:from_list(Labels)}.
+ {Labels, [], set_from_list(Labels)}.
get_work({[Label|Left], List, Set}) ->
- NewWork = {Left, List, sets:del_element(Label, Set)},
+ NewWork = {Left, List, maps:remove(Label, Set)},
{Label, NewWork};
get_work({[], [], _Set}) ->
fixpoint;
@@ -1839,12 +1830,12 @@ get_work({[], List, Set}) ->
get_work({lists:reverse(List), [], Set}).
add_work(Work = {List1, List2, Set}, [Label|Left]) ->
- case sets:is_element(Label, Set) of
- true ->
+ case Set of
+ #{Label := _} ->
add_work(Work, Left);
- false ->
+ _ ->
%% io:format("Adding work: ~w\n", [Label]),
- add_work({List1, [Label|List2], sets:add_element(Label, Set)}, Left)
+ add_work({List1, [Label|List2], Set#{Label => []}}, Left)
end;
add_work(Work, []) ->
Work.
@@ -1959,3 +1950,21 @@ next_down_limit(X) when is_integer(X), X > -16#8000000 -> -16#8000000;
next_down_limit(X) when is_integer(X), X > -16#80000000 -> -16#80000000;
next_down_limit(X) when is_integer(X), X > -16#800000000000000 -> -16#800000000000000;
next_down_limit(_X) -> neg_inf.
+
+%%--------------------------------------------------------------------
+%% Sets
+
+-type set(E) :: #{E => []}.
+
+set_from_list([]) -> #{};
+set_from_list(L) ->
+ maps:from_list([{E, []} || E <- L]).
+
+not_visited([], _) -> [];
+not_visited([E|T], M) ->
+ case M of
+ #{E := []} -> not_visited(T, M);
+ _ -> [E|not_visited(T, M)]
+ end.
+
+set_union(A, B) -> maps:merge(A, B).
diff --git a/lib/hipe/icode/hipe_icode_split_arith.erl b/lib/hipe/icode/hipe_icode_split_arith.erl
index e00a13f82e..44c1a9578d 100644
--- a/lib/hipe/icode/hipe_icode_split_arith.erl
+++ b/lib/hipe/icode/hipe_icode_split_arith.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-------------------------------------------------------------------
%% File : hipe_icode_split_arith.erl
diff --git a/lib/hipe/icode/hipe_icode_ssa.erl b/lib/hipe/icode/hipe_icode_ssa.erl
index b222fbc7d2..88317e9629 100644
--- a/lib/hipe/icode/hipe_icode_ssa.erl
+++ b/lib/hipe/icode/hipe_icode_ssa.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_icode_ssa.erl
@@ -34,13 +28,16 @@
-define(LIVENESS, hipe_icode_liveness).
-define(LIVENESS_NEEDED, true).
+-export_type([liveness/0]).
+
-include("hipe_icode.hrl").
-include("../ssa/hipe_ssa.inc").
%% Declarations for exported functions which are Icode-specific.
--spec ssa_liveness__analyze(#cfg{}) -> gb_trees:tree().
--spec ssa_liveness__livein(_, icode_lbl()) -> [#icode_variable{}].
-%% -spec ssa_liveness__livein(_, icode_lbl(), _) -> [#icode_var{}].
+-opaque liveness() :: liveness(icode_lbl(), #icode_variable{}).
+-spec ssa_liveness__analyze(#cfg{}) -> liveness().
+-spec ssa_liveness__livein(liveness(), icode_lbl()) -> [#icode_variable{}].
+%% -spec ssa_liveness__livein(liveness(), icode_lbl(), _) -> [#icode_var{}].
%%----------------------------------------------------------------------
%% Auxiliary operations which seriously differ between Icode and RTL.
diff --git a/lib/hipe/icode/hipe_icode_ssa_const_prop.erl b/lib/hipe/icode/hipe_icode_ssa_const_prop.erl
index 4ab4d7e95d..e2cd013b4c 100644
--- a/lib/hipe/icode/hipe_icode_ssa_const_prop.erl
+++ b/lib/hipe/icode/hipe_icode_ssa_const_prop.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -97,11 +91,13 @@ visit_expression(Instruction, Environment) ->
visit_begin_handler (Instruction, EvaluatedArguments, Environment);
#icode_begin_try{} ->
visit_begin_try (Instruction, EvaluatedArguments, Environment);
- #icode_fail{} ->
+ #icode_fail{} ->
visit_fail (Instruction, EvaluatedArguments, Environment);
- _ ->
- %% label, end_try, comment, return,
- {[], [], Environment}
+ #icode_comment{} -> {[], [], Environment};
+ #icode_end_try{} -> {[], [], Environment};
+ #icode_enter{} -> {[], [], Environment};
+ #icode_label{} -> {[], [], Environment};
+ #icode_return{} -> {[], [], Environment}
end.
%%-----------------------------------------------------------------------------
@@ -463,11 +459,15 @@ update_instruction(Instruction, Environment) ->
update_type(Instruction, Environment);
#icode_switch_tuple_arity{} ->
update_switch_tuple_arity(Instruction, Environment);
- _ ->
- %% goto, comment, label, return, begin_handler, end_try,
- %% begin_try, fail
- %% We could but don't handle: catch?, fail?
- [Instruction]
+ %% We could but don't handle: catch?, fail?
+ #icode_begin_handler{} -> [Instruction];
+ #icode_begin_try{} -> [Instruction];
+ #icode_comment{} -> [Instruction];
+ #icode_end_try{} -> [Instruction];
+ #icode_fail{} -> [Instruction];
+ #icode_goto{} -> [Instruction];
+ #icode_label{} -> [Instruction];
+ #icode_return{} -> [Instruction]
end.
%%-----------------------------------------------------------------------------
@@ -502,14 +502,12 @@ update_call(Instruction, Environment) ->
[Instruction, NewInstructions]),
NewInstructions
end;
-%% %% [] -> %% No destination; we don't touch this
-%% [] ->
-%% NewArguments = update_arguments(hipe_icode:call_args(Instruction),
-%% Environment),
-%% [hipe_icode:call_args_update(Instruction, NewArguments)];
+ %% [] -> %% No destination; we don't touch this
%% List-> %% Means register allocation; not implemented at this point
_ ->
- [Instruction]
+ NewArguments = update_arguments(hipe_icode:call_args(Instruction),
+ Environment),
+ [hipe_icode:call_args_update(Instruction, NewArguments)]
end.
%%-----------------------------------------------------------------------------
@@ -574,7 +572,9 @@ update_if(Instruction, Environment) ->
%% Convert the if-test to a type test if possible.
Op = hipe_icode:if_op(Instruction),
case Op =:= '=:=' orelse Op =:= '=/=' of
- false -> [Instruction];
+ false ->
+ [hipe_icode:if_args_update(
+ Instruction, update_arguments(Args, Environment))];
true ->
[Arg1, Arg2] = Args,
case EvaluatedArguments of
@@ -604,8 +604,9 @@ conv_if_to_type(I, Const, Arg) when is_atom(Const);
NewI = hipe_icode:mk_type([Arg], Test, T, F),
?CONST_PROP_MSG("if: ~w ---> type ~w\n", [I, NewI]),
[NewI];
-conv_if_to_type(I, _, _) ->
- [I].
+conv_if_to_type(I, Const, Arg) ->
+ %% Note: we are potentially commuting the (equality) comparison here
+ [hipe_icode:if_args_update(I, [Arg, hipe_icode:mk_const(Const)])].
%%-----------------------------------------------------------------------------
diff --git a/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl b/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl
index 5e5bd2a178..b92b7cfa7a 100644
--- a/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl
+++ b/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-------------------------------------------------------------------
%% File : hipe_icode_ssa_copy_prop.erl
diff --git a/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl b/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
index 7613024787..ec4840980d 100644
--- a/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
+++ b/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%=======================================================================
%% File : hipe_icode_ssa_struct_reuse.erl
diff --git a/lib/hipe/icode/hipe_icode_type.erl b/lib/hipe/icode/hipe_icode_type.erl
index 794c27ebcc..aafaeb5a0a 100644
--- a/lib/hipe/icode/hipe_icode_type.erl
+++ b/lib/hipe/icode/hipe_icode_type.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%--------------------------------------------------------------------
%%% File : hipe_icode_type.erl
%%% Author : Tobias Lindahl <[email protected]>
@@ -100,7 +94,7 @@
-record(state, {info_map = gb_trees:empty() :: gb_trees:tree(),
cfg :: cfg(),
- liveness = gb_trees:empty() :: gb_trees:tree(),
+ liveness :: hipe_icode_ssa:liveness(),
arg_types :: [erl_types:erl_type()],
ret_type = [t_none()] :: [erl_types:erl_type()],
lookupfun :: call_fun(),
@@ -1416,9 +1410,10 @@ transform_element2(I) ->
NewIndex =
case test_type(integer, IndexType) of
true ->
- case t_number_vals(IndexType) of
- unknown -> unknown;
- [_|_] = Vals -> {number, Vals}
+ case {number_min(IndexType), number_max(IndexType)} of
+ {Lb0, Ub0} when is_integer(Lb0), is_integer(Ub0) ->
+ {number, Lb0, Ub0};
+ {_, _} -> unknown
end;
_ -> unknown
end,
@@ -1433,19 +1428,19 @@ transform_element2(I) ->
_ -> unknown
end,
case {NewIndex, MinSize} of
- {{number, [_|_] = Ns}, {tuple, A}} when is_integer(A) ->
- case lists:all(fun(X) -> 0 < X andalso X =< A end, Ns) of
+ {{number, Lb, Ub}, {tuple, A}} when is_integer(A) ->
+ case 0 < Lb andalso Ub =< A of
true ->
- case Ns of
- [Idx] ->
+ case {Lb, Ub} of
+ {Idx, Idx} ->
[_, Tuple] = hipe_icode:args(I),
update_call_or_enter(I, #unsafe_element{index = Idx}, [Tuple]);
- [_|_] ->
+ {_, _} ->
NewFun = {element, [MinSize, valid]},
update_call_or_enter(I, NewFun)
end;
false ->
- case lists:all(fun(X) -> hipe_tagscheme:is_fixnum(X) end, Ns) of
+ case lists:all(fun(X) -> hipe_tagscheme:is_fixnum(X) end, [Lb, Ub]) of
true ->
NewFun = {element, [MinSize, fixnums]},
update_call_or_enter(I, NewFun);
@@ -1460,7 +1455,7 @@ transform_element2(I) ->
NewFun = {element, [MinSize, fixnums]},
update_call_or_enter(I, NewFun);
false ->
- NewFun = {element, [MinSize, NewIndex]},
+ NewFun = {element, [MinSize, NewIndex]},
update_call_or_enter(I, NewFun)
end
end.
diff --git a/lib/hipe/icode/hipe_icode_type.hrl b/lib/hipe/icode/hipe_icode_type.hrl
index 466e157646..b7c200eef1 100644
--- a/lib/hipe/icode/hipe_icode_type.hrl
+++ b/lib/hipe/icode/hipe_icode_type.hrl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_icode_type.hrl
diff --git a/lib/hipe/llvm/Makefile b/lib/hipe/llvm/Makefile
index 88016a7d8b..817ff67dcd 100644
--- a/lib/hipe/llvm/Makefile
+++ b/lib/hipe/llvm/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2001-2016. All Rights Reserved.
+# Copyright Ericsson AB 2001-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -73,8 +73,7 @@ include ../native.mk
ERL_COMPILE_FLAGS += -Werror +inline +warn_export_vars #+warn_missing_spec
# if in 32 bit backend define BIT32 symbol
-ARCH = $(shell echo $(TARGET) | sed 's/^\(x86_64\)-.*/64bit/')
-ifneq ($(ARCH), 64bit)
+ifneq ($(BITS64),yes)
ERL_COMPILE_FLAGS += -DBIT32
endif
diff --git a/lib/hipe/llvm/hipe_llvm.erl b/lib/hipe/llvm/hipe_llvm.erl
index b22f8fb320..641d3fda0a 100644
--- a/lib/hipe/llvm/hipe_llvm.erl
+++ b/lib/hipe/llvm/hipe_llvm.erl
@@ -862,7 +862,7 @@ pp_ins(Dev, Ver, I) ->
true -> write(Dev, "volatile ");
false -> ok
end,
- pp_dereference_type(Dev, Ver, load_p_type(I)),
+ pp_dereference_type(Dev, load_p_type(I)),
write(Dev, [" ", load_pointer(I), " "]),
case load_alignment(I) of
[] -> ok;
@@ -898,7 +898,7 @@ pp_ins(Dev, Ver, I) ->
true -> write(Dev, "inbounds ");
false -> ok
end,
- pp_dereference_type(Dev, Ver, getelementptr_p_type(I)),
+ pp_dereference_type(Dev, getelementptr_p_type(I)),
write(Dev, [" ", getelementptr_value(I)]),
pp_typed_idxs(Dev, getelementptr_typed_idxs(I)),
write(Dev, "\n");
@@ -959,10 +959,8 @@ pp_ins(Dev, Ver, I) ->
pp_args(Dev, fun_def_arglist(I)),
write(Dev, ") "),
pp_options(Dev, fun_def_fn_attrs(I)),
- case Ver >= {3,7} of false -> ok; true ->
- write(Dev, "personality i32 (i32, i64, i8*,i8*)* "
- "@__gcc_personality_v0 ")
- end,
+ write(Dev, "personality i32 (i32, i64, i8*,i8*)* "
+ "@__gcc_personality_v0 "),
case fun_def_align(I) of
[] -> ok;
N -> write(Dev, ["align ", N])
@@ -997,12 +995,7 @@ pp_ins(Dev, Ver, I) ->
pp_type(Dev, const_decl_type(I)),
write(Dev, [" ", const_decl_value(I), "\n"]);
#llvm_landingpad{} ->
- write(Dev, "landingpad { i8*, i32 } "),
- case Ver < {3,7} of false -> ok; true ->
- write(Dev, "personality i32 (i32, i64, i8*,i8*)* "
- "@__gcc_personality_v0 ")
- end,
- write(Dev, "cleanup\n");
+ write(Dev, "landingpad { i8*, i32 } cleanup\n");
#llvm_asm{} ->
write(Dev, [asm_instruction(I), "\n"]);
#llvm_adj_stack{} ->
@@ -1011,15 +1004,7 @@ pp_ins(Dev, Ver, I) ->
pp_type(Dev, adj_stack_type(I)),
write(Dev, [" ", adj_stack_offset(I),")\n"]);
#llvm_meta{} ->
- write(Dev, ["!", meta_id(I), " = "]),
- Named = case string:to_integer(meta_id(I)) of
- {_, ""} -> false;
- _ -> true
- end,
- case Ver < {3,6} andalso not Named of
- true -> write(Dev, "metadata !{metadata ");
- false -> write(Dev, "!{ ")
- end,
+ write(Dev, ["!", meta_id(I), " = !{ "]),
write(Dev, string:join([if is_list(Op) -> ["!\"", Op, "\""];
is_integer(Op) -> ["i32 ", integer_to_list(Op)];
is_record(Op, llvm_meta) ->
@@ -1030,15 +1015,10 @@ pp_ins(Dev, Ver, I) ->
exit({?MODULE, pp_ins, {"Unknown LLVM instruction", Other}})
end.
-%% @doc Print the type of a dereference in an LLVM instruction using syntax
-%% parsable by the specified LLVM version.
-pp_dereference_type(Dev, Ver, Type) ->
- case Ver >= {3,7} of
- false -> ok;
- true ->
- pp_type(Dev, pointer_type(Type)),
- write(Dev, ", ")
- end,
+%% @doc Print the type of a dereference in an LLVM instruction.
+pp_dereference_type(Dev, Type) ->
+ pp_type(Dev, pointer_type(Type)),
+ write(Dev, ", "),
pp_type(Dev, Type).
%% @doc Pretty-print a list of types
diff --git a/lib/hipe/llvm/hipe_llvm_main.erl b/lib/hipe/llvm/hipe_llvm_main.erl
index 476d6fb49c..4eec0c752b 100644
--- a/lib/hipe/llvm/hipe_llvm_main.erl
+++ b/lib/hipe/llvm/hipe_llvm_main.erl
@@ -84,7 +84,7 @@ compile_with_llvm(FunName, Arity, LLVMCode, Options, UseBuffer) ->
__ = file:close(File_llvm),
%% Invoke LLVM compiler tools to produce an object file
llvm_opt(Dir, Filename, Options),
- llvm_llc(Dir, Filename, Options),
+ llvm_llc(Dir, Filename, Ver, Options),
compile(Dir, Filename, "gcc"), %%FIXME: use llc -filetype=obj and skip this!
{ok, Dir, Dir ++ Filename ++ ".o"}.
@@ -103,12 +103,16 @@ llvm_opt(Dir, Filename, Options) ->
%% @doc Invoke llc tool to compile the bitcode to object file
%% (_name.bc -> _name.o).
-llvm_llc(Dir, Filename, Options) ->
+llvm_llc(Dir, Filename, Ver, Options) ->
Source = Dir ++ Filename ++ ".bc",
OptLevel = trans_optlev_flag(llc, Options),
+ VerFlags = llc_ver_flags(Ver),
Align = find_stack_alignment(),
+ Target = llc_target_opt(),
LlcFlags = [OptLevel, "-code-model=medium", "-stack-alignment=" ++ Align
- , "-tailcallopt", "-filetype=asm"], %%FIXME
+ , "-tailcallopt", "-filetype=asm" %FIXME
+ , Target
+ | VerFlags],
Command = "llc " ++ fix_opts(LlcFlags) ++ " " ++ Source,
%% io:format("LLC: ~s~n", [Command]),
case os:cmd(Command) of
@@ -121,7 +125,8 @@ llvm_llc(Dir, Filename, Options) ->
compile(Dir, Fun_Name, Compiler) ->
Source = Dir ++ Fun_Name ++ ".s",
Dest = Dir ++ Fun_Name ++ ".o",
- Command = Compiler ++ " -c " ++ Source ++ " -o " ++ Dest,
+ Target = compiler_target_opt(),
+ Command = Compiler ++ " " ++ Target ++ " -c " ++ Source ++ " -o " ++ Dest,
%% io:format("~s: ~s~n", [Compiler, Command]),
case os:cmd(Command) of
"" -> ok;
@@ -135,6 +140,18 @@ find_stack_alignment() ->
_ -> exit({?MODULE, find_stack_alignment, "Unimplemented architecture"})
end.
+llc_target_opt() ->
+ case get(hipe_target_arch) of
+ x86 -> "-march=x86";
+ amd64 -> "-march=x86-64"
+ end.
+
+compiler_target_opt() ->
+ case get(hipe_target_arch) of
+ x86 -> "-m32";
+ amd64 -> "-m64"
+ end.
+
%% @doc Join options.
fix_opts(Opts) ->
string:join(Opts, " ").
@@ -153,6 +170,12 @@ trans_optlev_flag(Tool, Options) ->
undefined -> "-O2"
end.
+llc_ver_flags(Ver = {_, _}) when Ver >= {3,9} ->
+ %% Works around a bug in the x86-call-frame-opt pass (as of LLVM 3.9) that
+ %% break the garbage collection stack descriptors.
+ ["-no-x86-call-frame-opt"];
+llc_ver_flags({_, _}) -> [].
+
%%------------------------------------------------------------------------------
%% Functions to manage Relocations
%%------------------------------------------------------------------------------
@@ -257,15 +280,11 @@ fix_relocations(Relocs, RelocsDict, MFA) ->
fix_reloc(#elf_rel{symbol=#elf_sym{name=Name, section=undefined, type=notype},
offset=Offset, type=?PCREL_T, addend=?PCREL_A},
- RelocsDict, {ModName,_,_}) when Name =/= "" ->
+ RelocsDict, {_,_,_}) when Name =/= "" ->
case dict:fetch(Name, RelocsDict) of
- {call, {bif, BifName, _}} -> {?CALL_LOCAL, Offset, BifName};
- %% MFA calls to functions in the same module are of type 3, while all
- %% other MFA calls are of type 2.
- %% XXX: Does this code break hot code loading (by transforming external
- %% calls into local calls?)
- {call, {ModName,_F,_A}=CallMFA} -> {?CALL_LOCAL, Offset, CallMFA};
- {call, CallMFA} -> {?CALL_REMOTE, Offset, CallMFA}
+ {call, _, {bif, BifName, _}} -> {?CALL_LOCAL, Offset, BifName};
+ {call, not_remote, CallMFA} -> {?CALL_LOCAL, Offset, CallMFA};
+ {call, remote, CallMFA} -> {?CALL_REMOTE, Offset, CallMFA}
end;
fix_reloc(#elf_rel{symbol=#elf_sym{name=Name, section=undefined, type=notype},
offset=Offset, type=?ABS_T, addend=?ABS_A},
@@ -280,7 +299,7 @@ fix_reloc(#elf_rel{symbol=#elf_sym{name=Name, section=#elf_shdr{name=?TEXT},
offset=Offset, type=?PCREL_T, addend=?PCREL_A},
RelocsDict, MFA) when Name =/= "" ->
case dict:fetch(Name, RelocsDict) of
- {call, MFA} -> {?CALL_LOCAL, Offset, MFA}
+ {call, not_remote, MFA} -> {?CALL_LOCAL, Offset, MFA}
end;
fix_reloc(#elf_rel{symbol=#elf_sym{name=Name, section=#elf_shdr{name=?RODATA},
type=object},
@@ -408,7 +427,7 @@ calls_with_stack_args(Dict) ->
calls_with_stack_args(dict:to_list(Dict), []).
calls_with_stack_args([], Calls) -> Calls;
-calls_with_stack_args([ {_Name, {call, {M, F, A}}} | Rest], Calls)
+calls_with_stack_args([ {_Name, {call, _, {M, F, A}}} | Rest], Calls)
when A > ?NR_ARG_REGS ->
Call =
case M of
diff --git a/lib/hipe/llvm/hipe_llvm_merge.erl b/lib/hipe/llvm/hipe_llvm_merge.erl
index 6e891ac3b0..58d862fbb2 100644
--- a/lib/hipe/llvm/hipe_llvm_merge.erl
+++ b/lib/hipe/llvm/hipe_llvm_merge.erl
@@ -13,7 +13,7 @@ finalize(CompiledCode, Closures, Exports) ->
Code = [{MFA, [], ConstTab}
|| {MFA, _, _ , ConstTab, _, _} <- CompiledCode1],
{ConstAlign, ConstSize, ConstMap, RefsFromConsts} =
- hipe_pack_constants:pack_constants(Code, ?ARCH_REGISTERS:alignment()),
+ hipe_pack_constants:pack_constants(Code),
%% Compute total code size separately as a sanity check for alignment
CodeSize = compute_code_size(CompiledCode1, 0),
%% io:format("Code Size (pre-computed): ~w~n", [CodeSize]),
diff --git a/lib/hipe/llvm/hipe_rtl_to_llvm.erl b/lib/hipe/llvm/hipe_rtl_to_llvm.erl
index 66b2e10fb8..79e1bfd381 100644
--- a/lib/hipe/llvm/hipe_rtl_to_llvm.erl
+++ b/lib/hipe/llvm/hipe_rtl_to_llvm.erl
@@ -10,7 +10,8 @@
-include("../rtl/hipe_literals.hrl").
-include("hipe_llvm_arch.hrl").
--define(WORD_WIDTH, (?bytes_to_bits(hipe_rtl_arch:word_size()))).
+-define(BITS_IN_WORD, (?bytes_to_bits(hipe_rtl_arch:word_size()))).
+-define(BITS_IN_BYTE, (?bytes_to_bits(1))).
-define(BRANCH_META_TAKEN, "0").
-define(BRANCH_META_NOT_TAKEN, "1").
-define(FIRST_FREE_META_NO, 2).
@@ -95,9 +96,9 @@ do_alloca_stack([], _, _, Acc) ->
Acc;
do_alloca_stack([D|Ds], Params, Roots, Acc) ->
{Name, _I} = trans_dst(D),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
- ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(8)),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
case hipe_rtl:is_var(D) of
true ->
Num = hipe_rtl:var_index(D),
@@ -155,9 +156,6 @@ translate_instr(I, Relocs, Data) ->
#alub{} ->
{I2, Relocs2} = trans_alub(I, Relocs),
{I2, Relocs2, Data};
- #branch{} ->
- {I2, Relocs2} = trans_branch(I, Relocs),
- {I2, Relocs2, Data};
#call{} ->
{I2, Relocs2} =
case hipe_rtl:call_fun(I) of
@@ -233,7 +231,7 @@ trans_alu(I, Relocs) ->
{Src1, I1} = trans_src(hipe_rtl:alu_src1(I)),
{Src2, I2} = trans_src(hipe_rtl:alu_src2(I)),
Op = trans_op(hipe_rtl:alu_op(I)),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
I3 = hipe_llvm:mk_operation(TmpDst, Op, WordTy, Src1, Src2, []),
I4 = store_stack_dst(TmpDst, RtlDst),
{[I4, I3, I2, I1], Relocs}.
@@ -254,18 +252,20 @@ trans_alub(I, Relocs) ->
trans_alub_overflow(I, Sign, Relocs) ->
{Src1, I1} = trans_src(hipe_rtl:alub_src1(I)),
{Src2, I2} = trans_src(hipe_rtl:alub_src2(I)),
- RtlDst = hipe_rtl:alub_dst(I),
TmpDst = mk_temp(),
Name = trans_alub_op(I, Sign),
- NewRelocs = relocs_store(Name, {call, {llvm, Name, 2}}, Relocs),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ NewRelocs = relocs_store(Name, {call, remote, {llvm, Name, 2}}, Relocs),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
ReturnType = hipe_llvm:mk_struct([WordTy, hipe_llvm:mk_int(1)]),
T1 = mk_temp(),
I3 = hipe_llvm:mk_call(T1, false, [], [], ReturnType, "@" ++ Name,
[{WordTy, Src1}, {WordTy, Src2}], []),
%% T1{0}: result of the operation
I4 = hipe_llvm:mk_extractvalue(TmpDst, ReturnType, T1 , "0", []),
- I5 = store_stack_dst(TmpDst, RtlDst),
+ I5 = case hipe_rtl:alub_has_dst(I) of
+ false -> [];
+ true -> store_stack_dst(TmpDst, hipe_rtl:alub_dst(I))
+ end,
T2 = mk_temp(),
%% T1{1}: Boolean variable indicating overflow
I6 = hipe_llvm:mk_extractvalue(T2, ReturnType, T1, "1", []),
@@ -310,42 +310,35 @@ trans_alub_op(I, Sign) ->
Name ++ Type.
trans_alub_no_overflow(I, Relocs) ->
+ {Src1, I1} = trans_src(hipe_rtl:alub_src1(I)),
+ {Src2, I2} = trans_src(hipe_rtl:alub_src2(I)),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
%% alu
- T = hipe_rtl:mk_alu(hipe_rtl:alub_dst(I), hipe_rtl:alub_src1(I),
- hipe_rtl:alub_op(I), hipe_rtl:alub_src2(I)),
- %% A trans_alu instruction cannot change relocations
- {I1, _} = trans_alu(T, Relocs),
+ {CmpLhs, CmpRhs, I5, Cond} =
+ case {hipe_rtl:alub_has_dst(I), hipe_rtl:alub_op(I)} of
+ {false, 'sub'} ->
+ Cond0 = trans_branch_rel_op(hipe_rtl:alub_cond(I)),
+ {Src1, Src2, [], Cond0};
+ {HasDst, AlubOp} ->
+ TmpDst = mk_temp(),
+ Op = trans_op(AlubOp),
+ I3 = hipe_llvm:mk_operation(TmpDst, Op, WordTy, Src1, Src2, []),
+ I4 = case HasDst of
+ false -> [];
+ true -> store_stack_dst(TmpDst, hipe_rtl:alub_dst(I))
+ end,
+ Cond0 = trans_alub_rel_op(hipe_rtl:alub_cond(I)),
+ {TmpDst, "0", [I4, I3], Cond0}
+ end,
%% icmp
- %% Translate destination as src, to match with the semantics of instruction
- {Dst, I2} = trans_src(hipe_rtl:alub_dst(I)),
- Cond = trans_rel_op(hipe_rtl:alub_cond(I)),
T3 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- I5 = hipe_llvm:mk_icmp(T3, Cond, WordTy, Dst, "0"),
+ I6 = hipe_llvm:mk_icmp(T3, Cond, WordTy, CmpLhs, CmpRhs),
%% br
Metadata = branch_metadata(hipe_rtl:alub_pred(I)),
True_label = mk_jump_label(hipe_rtl:alub_true_label(I)),
False_label = mk_jump_label(hipe_rtl:alub_false_label(I)),
- I6 = hipe_llvm:mk_br_cond(T3, True_label, False_label, Metadata),
- {[I6, I5, I2, I1], Relocs}.
-
-%%
-%% branch
-%%
-trans_branch(I, Relocs) ->
- {Src1, I1} = trans_src(hipe_rtl:branch_src1(I)),
- {Src2, I2} = trans_src(hipe_rtl:branch_src2(I)),
- Cond = trans_rel_op(hipe_rtl:branch_cond(I)),
- %% icmp
- T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- I3 = hipe_llvm:mk_icmp(T1, Cond, WordTy, Src1, Src2),
- %% br
- True_label = mk_jump_label(hipe_rtl:branch_true_label(I)),
- False_label = mk_jump_label(hipe_rtl:branch_false_label(I)),
- Metadata = branch_metadata(hipe_rtl:branch_pred(I)),
- I4 = hipe_llvm:mk_br_cond(T1, True_label, False_label, Metadata),
- {[I4, I3, I2, I1], Relocs}.
+ I7 = hipe_llvm:mk_br_cond(T3, True_label, False_label, Metadata),
+ {[I7, I6, I5, I2, I1], Relocs}.
branch_metadata(X) when X =:= 0.5 -> [];
branch_metadata(X) when X > 0.5 -> ?BRANCH_META_TAKEN;
@@ -364,9 +357,9 @@ trans_call(I, Relocs) ->
{LoadedFixedRegs, I2} = load_fixed_regs(FixedRegs),
FinalArgs = fix_reg_args(LoadedFixedRegs) ++ CallArgs,
{Name, I3, Relocs2} =
- trans_call_name(RtlCallName, Relocs1, CallArgs, FinalArgs),
+ trans_call_name(RtlCallName, hipe_rtl:call_type(I), Relocs1, CallArgs, FinalArgs),
T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
I4 =
case hipe_rtl:call_fail(I) of
@@ -430,17 +423,17 @@ expose_closure(CallName, CallArgs, Relocs) ->
{[], Relocs}
end.
-trans_call_name(RtlCallName, Relocs, CallArgs, FinalArgs) ->
+trans_call_name(RtlCallName, RtlCallType, Relocs, CallArgs, FinalArgs) ->
case RtlCallName of
PrimOp when is_atom(PrimOp) ->
LlvmName = trans_prim_op(PrimOp),
Relocs1 =
- relocs_store(LlvmName, {call, {bif, PrimOp, length(CallArgs)}}, Relocs),
+ relocs_store(LlvmName, {call, not_remote, {bif, PrimOp, length(CallArgs)}}, Relocs),
{"@" ++ LlvmName, [], Relocs1};
{M, F, A} when is_atom(M), is_atom(F), is_integer(A) ->
- LlvmName = trans_mfa_name({M, F, A}),
+ LlvmName = trans_mfa_name({M, F, A}, RtlCallType),
Relocs1 =
- relocs_store(LlvmName, {call, {M, F, length(CallArgs)}}, Relocs),
+ relocs_store(LlvmName, {call, RtlCallType, {M, F, length(CallArgs)}}, Relocs),
{"@" ++ LlvmName, [], Relocs1};
Reg ->
case hipe_rtl:is_reg(Reg) of
@@ -450,7 +443,7 @@ trans_call_name(RtlCallName, Relocs, CallArgs, FinalArgs) ->
%% order to make the call
TT1 = mk_temp(),
{RegName, II1} = trans_src(Reg),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
II2 =
hipe_llvm:mk_conversion(TT1, inttoptr, WordTy, RegName, WordTyPtr),
@@ -501,9 +494,9 @@ trans_enter(I, Relocs) ->
{LoadedFixedRegs, I1} = load_fixed_regs(FixedRegs),
FinalArgs = fix_reg_args(LoadedFixedRegs) ++ CallArgs,
{Name, I2, NewRelocs} =
- trans_call_name(hipe_rtl:enter_fun(I), Relocs, CallArgs, FinalArgs),
+ trans_call_name(hipe_rtl:enter_fun(I), hipe_rtl:enter_type(I), Relocs, CallArgs, FinalArgs),
T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
I3 = hipe_llvm:mk_call(T1, true, "cc 11", [], FunRetTy, Name, FinalArgs, []),
I4 = hipe_llvm:mk_ret([{FunRetTy, T1}]),
@@ -518,7 +511,7 @@ trans_fconv(I, Relocs) ->
TmpDst = mk_temp(),
{Src, I1} = trans_float_src(hipe_rtl:fconv_src(I)),
FloatTy = hipe_llvm:mk_double(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
I2 = hipe_llvm:mk_conversion(TmpDst, sitofp, WordTy, Src, FloatTy),
I3 = store_float_stack(TmpDst, RtlDst),
{[I3, I2, I1], Relocs}.
@@ -538,7 +531,7 @@ trans_fload(I, Relocs) ->
{Src, I1} = trans_float_src(RtlSrc),
{Offset, I2} = trans_float_src(_Offset),
T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FloatTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_double()),
I3 = hipe_llvm:mk_operation(T1, add, WordTy, Src, Offset, []),
T2 = mk_temp(),
@@ -619,7 +612,7 @@ trans_fstore(I, Relocs) ->
trans_fstore_reg(I, Relocs) ->
{Base, I0} = trans_reg(hipe_rtl:fstore_base(I), dst),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
FloatTy = hipe_llvm:mk_double(),
FloatTyPtr = hipe_llvm:mk_pointer(FloatTy),
@@ -659,7 +652,7 @@ trans_load(I, Relocs) ->
{Src, I1} = trans_src(hipe_rtl:load_src(I)),
{Offset, I2} = trans_src(hipe_rtl:load_offset(I)),
T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
I3 = hipe_llvm:mk_operation(T1, add, WordTy, Src, Offset, []),
%%----------------------------------------------------------------
@@ -737,7 +730,7 @@ trans_move(I, Relocs) ->
%% return
%%
trans_return(I, Relocs) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
{VarRet, I1} =
case hipe_rtl:return_varlist(I) of
[] ->
@@ -777,7 +770,7 @@ trans_store(I, Relocs) ->
{Offset, I2} = trans_src(hipe_rtl:store_offset(I)),
{Value, I3} = trans_src(hipe_rtl:store_src(I)),
T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
I4 = hipe_llvm:mk_operation(T1, add, WordTy, Base, Offset, []),
I5 =
@@ -811,14 +804,14 @@ trans_switch(I, Relocs, Data) ->
JumpLabels = [mk_jump_label(L) || L <- Labels],
SortOrder = hipe_rtl:switch_sort_order(I),
NrLabels = length(Labels),
- ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(8)),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
TableType = hipe_llvm:mk_array(NrLabels, ByteTyPtr),
TableTypeP = hipe_llvm:mk_pointer(TableType),
TypedJumpLabels = [{hipe_llvm:mk_label_type(), X} || X <- JumpLabels],
T1 = mk_temp(),
{Src2, []} = trans_dst(RtlSrc),
TableName = "table_" ++ tl(Src2),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
I2 = hipe_llvm:mk_getelementptr(T1, TableTypeP, "@"++TableName,
[{WordTy, "0"}, {WordTy, Src}], false),
T2 = mk_temp(),
@@ -933,7 +926,7 @@ create_fail_blocks(Label, FailLabels, Acc) ->
false ->
Acc;
{value, {Label, FailLabel, SpAdj}, RestFailLabels} ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
I1 = hipe_llvm:mk_label(FailLabel),
LP = hipe_llvm:mk_landingpad(),
I2 =
@@ -962,7 +955,7 @@ create_fail_blocks(Label, FailLabels, Acc) ->
%% @doc Convert RTL argument list to LLVM argument list.
trans_args(ArgList) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
MakeArg =
fun(A) ->
{Name, I1} = trans_src(A),
@@ -972,13 +965,13 @@ trans_args(ArgList) ->
%% @doc Convert a list of Precoloured registers to LLVM argument list.
fix_reg_args(ArgList) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
[{WordTy, A} || A <- ArgList].
%% @doc Load Precoloured registers.
load_fixed_regs(RegList) ->
Names = [mk_temp_reg(R) || R <- RegList],
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
Fun1 =
fun (X, Y) ->
@@ -991,7 +984,7 @@ load_fixed_regs(RegList) ->
store_fixed_regs(RegList, Name) ->
Names = [mk_temp_reg(R) || R <- RegList],
Indexes = lists:seq(0, erlang:length(RegList) - 1),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
Fun1 =
@@ -1035,8 +1028,12 @@ llvm_id(C) ->
io_lib:format("_~2.16.0B_",[C]).
%% @doc Create an acceptable LLVM identifier for an MFA.
-trans_mfa_name({M,F,A}) ->
- N = atom_to_list(M) ++ "." ++ atom_to_list(F) ++ "." ++ integer_to_list(A),
+trans_mfa_name({M,F,A}, Linkage) ->
+ N0 = atom_to_list(M) ++ "." ++ atom_to_list(F) ++ "." ++ integer_to_list(A),
+ N = case Linkage of
+ not_remote -> N0;
+ remote -> "rem." ++ N0
+ end,
make_llvm_id(N).
%%------------------------------------------------------------------------------
@@ -1060,7 +1057,7 @@ mk_temp_reg(Name) ->
store_stack_dst(TempDst, Dst) ->
{Dst2, II1} = trans_dst(Dst),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
II2 = hipe_llvm:mk_store(WordTy, TempDst, WordTyPtr, Dst2, [], [], false),
[II2, II1].
@@ -1078,7 +1075,7 @@ trans_float_src(Src) ->
Name = "@DL" ++ integer_to_list(hipe_rtl:const_label_label(Src)),
T1 = mk_temp(),
%% XXX: Hardcoded offset
- ByteTy = hipe_llvm:mk_int(8),
+ ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
ByteTyPtr = hipe_llvm:mk_pointer(ByteTy),
I1 = hipe_llvm:mk_getelementptr(T1, ByteTyPtr, Name,
[{ByteTy, integer_to_list(?FLOAT_OFFSET)}], true),
@@ -1094,7 +1091,7 @@ trans_float_src(Src) ->
end.
trans_src(A) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
case hipe_rtl:is_imm(A) of
true ->
@@ -1157,7 +1154,7 @@ trans_dst(A) ->
true ->
"%DL" ++ integer_to_list(hipe_rtl:const_label_label(A)) ++ "_var";
false ->
- exit({?MODULE, trans_dst, {"Bad RTL argument",A}})
+ error(badarg, [A])
end
end
end,
@@ -1197,7 +1194,7 @@ map_precoloured_reg(Index) ->
fix_reg_dst(Register) ->
case Register of
{Name, Offset} -> %% Case of %fcalls, %hplim
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
pointer_from_reg(Name, WordTy, Offset);
Name -> %% Case of %p and %hp
{Name, []}
@@ -1205,7 +1202,7 @@ fix_reg_dst(Register) ->
%% @doc Load precoloured src register.
fix_reg_src(Register) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
case Register of
{Name, Offset} -> %% Case of %fcalls, %hplim
@@ -1255,14 +1252,19 @@ trans_op(Op) ->
Other -> exit({?MODULE, trans_op, {"Unknown RTL operator", Other}})
end.
-trans_rel_op(Op) ->
+trans_branch_rel_op(Op) ->
case Op of
- eq -> eq;
- ne -> ne;
gtu -> ugt;
geu -> uge;
ltu -> ult;
leu -> ule;
+ _ -> trans_alub_rel_op(Op)
+ end.
+
+trans_alub_rel_op(Op) ->
+ case Op of
+ eq -> eq;
+ ne -> ne;
gt -> sgt;
ge -> sge;
lt -> slt;
@@ -1295,7 +1297,10 @@ insn_dst(I) ->
#alu{} ->
[hipe_rtl:alu_dst(I)];
#alub{} ->
- [hipe_rtl:alub_dst(I)];
+ case hipe_rtl:alub_has_dst(I) of
+ true -> [hipe_rtl:alub_dst(I)];
+ false -> []
+ end;
#call{} ->
case hipe_rtl:call_dstlist(I) of
[] -> [];
@@ -1327,10 +1332,10 @@ insn_dst(I) ->
llvm_type_from_size(Size) ->
case Size of
- byte -> hipe_llvm:mk_int(8);
+ byte -> hipe_llvm:mk_int(?BITS_IN_BYTE);
int16 -> hipe_llvm:mk_int(16);
int32 -> hipe_llvm:mk_int(32);
- word -> hipe_llvm:mk_int(64)
+ word -> hipe_llvm:mk_int(?BITS_IN_WORD)
end.
%% @doc Create definition for the compiled function. The parameters that are
@@ -1338,7 +1343,7 @@ llvm_type_from_size(Size) ->
%% precoloured registers that are passed as arguments must be stored to
%% the corresonding stack slots.
create_function_definition(Fun, Params, Code, LocalVars) ->
- FunctionName = trans_mfa_name(Fun),
+ FunctionName = trans_mfa_name(Fun, not_remote),
FixedRegs = fixed_registers(),
%% Reverse parameters to match with the Erlang calling convention
ReversedParams =
@@ -1359,14 +1364,14 @@ create_function_definition(Fun, Params, Code, LocalVars) ->
EntryBlock =
lists:flatten([EntryLabel, ExceptionSync, I2, LocalVars, StoredParams, I3]),
Final_Code = EntryBlock ++ Code,
- FunctionOptions = [nounwind, noredzone, list_to_atom("gc \"erlang\"")],
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ FunctionOptions = [nounwind, noredzone, 'gc "erlang"'],
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
hipe_llvm:mk_fun_def([], [], "cc 11", [], FunRetTy, FunctionName, Args,
FunctionOptions, [], Final_Code).
header_params(Params) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
[{WordTy, "%v" ++ integer_to_list(hipe_rtl:var_index(P))} || P <- Params].
store_params(Params) ->
@@ -1375,7 +1380,7 @@ store_params(Params) ->
Index = hipe_rtl:var_index(X),
{Name, _} = trans_dst(X),
ParamName = "%v" ++ integer_to_list(Index),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
hipe_llvm:mk_store(WordTy, ParamName, WordTyPtr, Name, [], [], false)
end,
@@ -1392,11 +1397,11 @@ fixed_registers() ->
end.
header_regs(Registers) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
[{WordTy, "%" ++ X ++ "_in"} || X <- Registers].
load_regs(Registers) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
Fun1 =
fun(X) ->
@@ -1426,7 +1431,7 @@ relocs_to_list(Relocs) ->
%% constants/labels.
handle_relocations(Relocs, Data, Fun) ->
RelocsList = relocs_to_list(Relocs),
- %% Seperate Relocations according to their type
+ %% Separate Relocations according to their type
{CallList, AtomList, ClosureList, ClosureLabels, SwitchList} =
seperate_relocs(RelocsList),
%% Create code to declare atoms
@@ -1457,9 +1462,9 @@ handle_relocations(Relocs, Data, Fun) ->
Relocs2 = lists:foldl(fun const_to_dict/2, Relocs1, ConstLabels),
%% Temporary Store inc_stack and llvm_fix_pinned_regs to Dictionary
%% TODO: Remove this
- Relocs3 = dict:store("inc_stack_0", {call, {bif, inc_stack_0, 0}}, Relocs2),
+ Relocs3 = dict:store("inc_stack_0", {call, not_remote, {bif, inc_stack_0, 0}}, Relocs2),
Relocs4 = dict:store("hipe_bifs.llvm_fix_pinned_regs.0",
- {call, {hipe_bifs, llvm_fix_pinned_regs, 0}}, Relocs3),
+ {call, remote, {hipe_bifs, llvm_fix_pinned_regs, 0}}, Relocs3),
BranchMetaData = [
hipe_llvm:mk_meta(?BRANCH_META_TAKEN, ["branch_weights", 99, 1])
, hipe_llvm:mk_meta(?BRANCH_META_NOT_TAKEN, ["branch_weights", 1, 99])
@@ -1469,7 +1474,7 @@ handle_relocations(Relocs, Data, Fun) ->
LocalVariables = AtomLoad ++ ClosureLoad ++ ConstLoad,
{Relocs4, ExternalDeclarations, LocalVariables}.
-%% @doc Seperate relocations according to their type.
+%% @doc Separate relocations according to their type.
seperate_relocs(Relocs) ->
seperate_relocs(Relocs, [], [], [], [], []).
@@ -1477,9 +1482,10 @@ seperate_relocs([], CallAcc, AtomAcc, ClosureAcc, LabelAcc, JmpTableAcc) ->
{CallAcc, AtomAcc, ClosureAcc, LabelAcc, JmpTableAcc};
seperate_relocs([R|Rs], CallAcc, AtomAcc, ClosureAcc, LabelAcc, JmpTableAcc) ->
case R of
- {_, {call, _}} ->
+ {_, {call, _, _}} ->
seperate_relocs(Rs, [R | CallAcc], AtomAcc, ClosureAcc, LabelAcc,
JmpTableAcc);
+
{_, {atom, _}} ->
seperate_relocs(Rs, CallAcc, [R | AtomAcc], ClosureAcc, LabelAcc,
JmpTableAcc);
@@ -1496,33 +1502,35 @@ seperate_relocs([R|Rs], CallAcc, AtomAcc, ClosureAcc, LabelAcc, JmpTableAcc) ->
%% @doc External declaration of an atom.
declare_atom({AtomName, _}) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- hipe_llvm:mk_const_decl("@" ++ AtomName, "external constant", WordTy, "").
+ %% The type has to be byte, or a backend might assume the constant is aligned
+ %% and incorrectly optimise away type tests
+ ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
+ hipe_llvm:mk_const_decl("@" ++ AtomName, "external constant", ByteTy, "").
%% @doc Creation of local variable for an atom.
load_atom({AtomName, _}) ->
Dst = "%" ++ AtomName ++ "_var",
Name = "@" ++ AtomName,
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- WordTyPtr = hipe_llvm:mk_pointer(WordTy),
- hipe_llvm:mk_conversion(Dst, ptrtoint, WordTyPtr, Name, WordTy).
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
+ hipe_llvm:mk_conversion(Dst, ptrtoint, ByteTyPtr, Name, WordTy).
%% @doc External declaration of a closure.
declare_closure({ClosureName, _})->
- ByteTy = hipe_llvm:mk_int(8),
+ ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
hipe_llvm:mk_const_decl("@" ++ ClosureName, "external constant", ByteTy, "").
%% @doc Creation of local variable for a closure.
load_closure({ClosureName, _})->
Dst = "%" ++ ClosureName ++ "_var",
Name = "@" ++ ClosureName,
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(8)),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
hipe_llvm:mk_conversion(Dst, ptrtoint, ByteTyPtr, Name, WordTy).
%% @doc Declaration of a local variable for a switch jump table.
declare_switches(JumpTableList, Fun) ->
- FunName = trans_mfa_name(Fun),
+ FunName = trans_mfa_name(Fun, not_remote),
[declare_switch_table(X, FunName) || X <- JumpTableList].
declare_switch_table({Name, {switch, {TableType, Labels, _, _}, _}}, FunName) ->
@@ -1538,7 +1546,7 @@ declare_switch_table({Name, {switch, {TableType, Labels, _, _}, _}}, FunName) ->
declare_closure_labels([], Relocs, _Fun) ->
{[], Relocs};
declare_closure_labels(ClosureLabels, Relocs, Fun) ->
- FunName = trans_mfa_name(Fun),
+ FunName = trans_mfa_name(Fun, not_remote),
{LabelList, ArityList} =
lists:unzip([{mk_jump_label(Label), A} ||
{_, {closure_label, Label, A}} <- ClosureLabels]),
@@ -1548,22 +1556,22 @@ declare_closure_labels(ClosureLabels, Relocs, Fun) ->
List3 = string:join(List2, ",\n"),
List4 = "[\n" ++ List3 ++ "\n]\n",
NrLabels = length(LabelList),
- ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(8)),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
TableType = hipe_llvm:mk_array(NrLabels, ByteTyPtr),
ConstDecl =
hipe_llvm:mk_const_decl("@table_closures", "constant", TableType, List4),
{[ConstDecl], Relocs1}.
-%% @doc A call is treated as non external only in a case of a recursive
+%% @doc A call is treated as non external only in a case of a local recursive
%% function.
-is_external_call({_, {call, Fun}}, Fun) -> false;
+is_external_call({_, {call, not_remote, MFA}}, MFA) -> false;
is_external_call(_, _) -> true.
%% @doc External declaration of a function.
-call_to_decl({Name, {call, MFA}}) ->
+call_to_decl({Name, {call, _, MFA}}) ->
{M, _F, A} = MFA,
CConv = "cc 11",
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
{Type, Args} =
case M of
@@ -1578,14 +1586,14 @@ call_to_decl({Name, {call, MFA}}) ->
%% @doc These functions are always declared, even if not used.
fixed_fun_decl() ->
- ByteTy = hipe_llvm:mk_int(8),
+ ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
ByteTyPtr = hipe_llvm:mk_pointer(ByteTy),
LandPad = hipe_llvm:mk_fun_decl([], [], [], [], hipe_llvm:mk_int(32),
"@__gcc_personality_v0", [hipe_llvm:mk_int(32), hipe_llvm:mk_int(64),
ByteTyPtr, ByteTyPtr], []),
GCROOTDecl = hipe_llvm:mk_fun_decl([], [], [], [], hipe_llvm:mk_void(),
"@llvm.gcroot", [hipe_llvm:mk_pointer(ByteTyPtr), ByteTyPtr], []),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
FixPinnedRegs = hipe_llvm:mk_fun_decl([], [], [], [], FunRetTy,
"@hipe_bifs.llvm_fix_pinned_regs.0", [], []),
@@ -1599,7 +1607,7 @@ fixed_fun_decl() ->
%% values, add the offset and convert them again to pointers.
declare_constant(Label) ->
Name = "@DL" ++ integer_to_list(Label),
- ByteTy = hipe_llvm:mk_int(8),
+ ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
hipe_llvm:mk_const_decl(Name, "external constant", ByteTy, "").
%% @doc Load a constant is achieved by converting a pointer to an integer of
@@ -1607,8 +1615,8 @@ declare_constant(Label) ->
load_constant(Label) ->
Dst = "%DL" ++ integer_to_list(Label) ++ "_var",
Name = "@DL" ++ integer_to_list(Label),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(8)),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
hipe_llvm:mk_conversion(Dst, ptrtoint, ByteTyPtr, Name, WordTy).
%% @doc Store external constants and calls to dictionary.
diff --git a/lib/hipe/main/hipe.app.src b/lib/hipe/main/hipe.app.src
index f8487151d7..3c3a1004f1 100644
--- a/lib/hipe/main/hipe.app.src
+++ b/lib/hipe/main/hipe.app.src
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -49,12 +49,13 @@
hipe_amd64_ra_naive,
hipe_amd64_ra_postconditions,
hipe_amd64_ra_sse2_postconditions,
- hipe_amd64_ra_x87_ls,
hipe_amd64_registers,
hipe_amd64_specific,
hipe_amd64_specific_sse2,
hipe_amd64_specific_x87,
hipe_amd64_spill_restore,
+ hipe_amd64_sse2,
+ hipe_amd64_subst,
hipe_amd64_x87,
hipe_arm,
hipe_arm_assemble,
@@ -73,7 +74,9 @@
hipe_arm_ra_postconditions,
hipe_arm_registers,
hipe_arm_specific,
+ hipe_arm_subst,
hipe_bb,
+ hipe_bb_weights,
hipe_beam_to_icode,
hipe_coalescing_regalloc,
hipe_consttab,
@@ -81,6 +84,7 @@
hipe_digraph,
hipe_dominators,
hipe_dot,
+ hipe_dsets,
hipe_gen_cfg,
hipe_gensym,
hipe_graph_coloring_regalloc,
@@ -142,9 +146,13 @@
hipe_ppc_registers,
hipe_ppc_specific,
hipe_ppc_specific_fp,
+ hipe_ppc_subst,
hipe_profile,
+ hipe_range_split,
hipe_reg_worklists,
hipe_regalloc_loop,
+ hipe_regalloc_prepass,
+ hipe_restore_reuse,
hipe_rtl,
hipe_rtl_arch,
hipe_rtl_arith_32,
@@ -171,6 +179,7 @@
hipe_rtl_to_sparc,
hipe_rtl_to_x86,
hipe_rtl_varmap,
+ hipe_segment_trees,
hipe_sdi,
hipe_sparc,
hipe_sparc_assemble,
@@ -193,6 +202,7 @@
hipe_sparc_registers,
hipe_sparc_specific,
hipe_sparc_specific_fp,
+ hipe_sparc_subst,
hipe_spillcost,
hipe_spillmin,
hipe_spillmin_color,
@@ -216,14 +226,14 @@
hipe_x86_ra_ls,
hipe_x86_ra_naive,
hipe_x86_ra_postconditions,
- hipe_x86_ra_x87_ls,
hipe_x86_registers,
hipe_x86_specific,
hipe_x86_specific_x87,
hipe_x86_spill_restore,
+ hipe_x86_subst,
hipe_x86_x87]},
{registered,[]},
{applications, [kernel,stdlib]},
{env, []},
{runtime_dependencies, ["syntax_tools-1.6.14","stdlib-2.5","kernel-3.0",
- "erts-7.1","compiler-5.0"]}]}.
+ "erts-9.0","compiler-5.0"]}]}.
diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl
index 6c525dd143..19b4e8bfe2 100644
--- a/lib/hipe/main/hipe.erl
+++ b/lib/hipe/main/hipe.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%% ====================================================================
%% Copyright (c) 1998 by Erik Johansson. All Rights Reserved
%% ====================================================================
@@ -447,7 +441,7 @@ compile(Name, File, Opts0) when is_atom(Name) ->
?error_msg("Cannot get Core Erlang code from BEAM binary.",[]),
?EXIT({cant_compile_core_from_binary});
true ->
- case filename:find_src(filename:rootname(File, ".beam")) of
+ case filelib:find_source(filename:rootname(File,".beam") ++ ".beam") of
{error, _} ->
?error_msg("Cannot find source code for ~p.", [File]),
?EXIT({cant_find_source_code});
@@ -635,44 +629,51 @@ run_compiler(Name, DisasmFun, IcodeFun, Opts0) ->
Opts = expand_basic_options(Opts0 ++ ?COMPILE_DEFAULTS),
?when_option(verbose, Opts, ?debug_msg("Compiling: ~p\n",[Name])),
?option_start_time("Compile", Opts),
- Res = run_compiler_1(DisasmFun, IcodeFun, Opts),
+ Res = run_compiler_1(Name, DisasmFun, IcodeFun, Opts),
?option_stop_time("Compile", Opts),
Res.
-run_compiler_1(DisasmFun, IcodeFun, Options) ->
+run_compiler_1(Name, DisasmFun, IcodeFun, Options) ->
Parent = self(),
{trap_exit,TrapExit} = process_info(Parent, trap_exit),
%% Spawn a compilation process CompProc. In case this process gets
%% killed, the trap_exit flag is restored to that of the Parent process.
process_flag(trap_exit, true),
- CompProc = spawn_link(fun () ->
- %% Compiler process
- set_architecture(Options),
- pre_init(Options),
- %% The full option expansion is not done
- %% until the DisasmFun returns.
- {Code, CompOpts} = DisasmFun(Options),
- Opts0 = expand_options(Options ++ CompOpts,
- get(hipe_target_arch)),
- Opts =
- case proplists:get_bool(to_llvm, Opts0) andalso
- not llvm_support_available() of
- true ->
- ?error_msg("No LLVM version 3.4 or greater "
- "found in $PATH; aborting "
- "native code compilation.\n", []),
- ?EXIT(cant_find_required_llvm_version);
- false ->
- Opts0
- end,
- check_options(Opts),
- ?when_option(verbose, Options,
- ?debug_msg("Options: ~p.\n",[Opts])),
- init(Opts),
- {Icode, WholeModule} = IcodeFun(Code, Opts),
- CompRes = compile_finish(Icode, WholeModule, Opts),
- compiler_return(CompRes, Parent)
- end),
+ CompProc =
+ spawn_link(
+ fun () ->
+ try
+ %% Compiler process
+ set_architecture(Options),
+ pre_init(Options),
+ %% The full option expansion is not done
+ %% until the DisasmFun returns.
+ {Code, CompOpts} = DisasmFun(Options),
+ Opts0 = expand_options(Options ++ CompOpts,
+ get(hipe_target_arch)),
+ Opts =
+ case proplists:get_bool(to_llvm, Opts0) andalso
+ not llvm_support_available() of
+ true ->
+ ?error_msg("No LLVM version 3.9 or greater "
+ "found in $PATH; aborting "
+ "native code compilation.\n", []),
+ ?EXIT(cant_find_required_llvm_version);
+ false ->
+ Opts0
+ end,
+ check_options(Opts),
+ ?when_option(verbose, Options,
+ ?debug_msg("Options: ~p.\n",[Opts])),
+ init(Opts),
+ {Icode, WholeModule} = IcodeFun(Code, Opts),
+ CompRes = compile_finish(Icode, WholeModule, Opts),
+ compiler_return(CompRes, Parent)
+ catch error:Error ->
+ print_crash_message(Name, Error),
+ exit(Error)
+ end
+ end),
Timeout = case proplists:get_value(timeout, Options) of
N when is_integer(N), N >= 0 -> N;
undefined -> ?DEFAULT_TIMEOUT;
@@ -691,7 +692,7 @@ run_compiler_1(DisasmFun, IcodeFun, Options) ->
exit(CompProc, kill),
receive {'EXIT', CompProc, _} -> ok end,
flush(),
- ?error_msg("ERROR: Compilation timed out.\n",[]),
+ ?error_msg("ERROR: Compilation of ~w timed out.\n",[Name]),
exit(timed_out)
end,
Result = receive {CompProc, Res} -> Res end,
@@ -844,11 +845,25 @@ finalize_fun_sequential({MFA, Icode}, Opts, Servers) ->
catch
error:Error ->
?when_option(verbose, Opts, ?debug_untagged_msg("\n", [])),
- ErrorInfo = {Error, erlang:get_stacktrace()},
- ?error_msg("ERROR: ~p~n", [ErrorInfo]),
- ?EXIT(ErrorInfo)
+ print_crash_message(MFA, Error),
+ exit(Error)
end.
+print_crash_message(What, Error) ->
+ StackFun = fun(_,_,_) -> false end,
+ FormatFun = fun (Term, _) -> io_lib:format("~p", [Term]) end,
+ StackTrace = lib:format_stacktrace(1, erlang:get_stacktrace(),
+ StackFun, FormatFun),
+ WhatS = case What of
+ {M,F,A} -> io_lib:format("~w:~w/~w", [M,F,A]);
+ Mod -> io_lib:format("~w", [Mod])
+ end,
+ ?error_msg("INTERNAL ERROR~n"
+ "while compiling ~s~n"
+ "crash reason: ~p~n"
+ "~s~n",
+ [WhatS, Error, StackTrace]).
+
pp_server_start(Opts) ->
set_architecture(Opts),
garbage_collect(),
@@ -1118,9 +1133,10 @@ help_hiper() ->
help_options() ->
HostArch = erlang:system_info(hipe_architecture),
- O1 = expand_options([o1], HostArch),
- O2 = expand_options([o2], HostArch),
- O3 = expand_options([o3], HostArch),
+ O0 = expand_options([o0] ++ ?COMPILE_DEFAULTS, HostArch),
+ O1 = expand_options([o1] ++ ?COMPILE_DEFAULTS, HostArch),
+ O2 = expand_options([o2] ++ ?COMPILE_DEFAULTS, HostArch),
+ O3 = expand_options([o3] ++ ?COMPILE_DEFAULTS, HostArch),
io:format("HiPE Compiler Options\n" ++
" Boolean-valued options generally have corresponding " ++
"aliases `no_...',\n" ++
@@ -1139,15 +1155,16 @@ help_options() ->
" pp_x86 = pp_native,\n" ++
" pp_amd64 = pp_native,\n" ++
" pp_ppc = pp_native,\n" ++
- " o0,\n" ++
- " o1 = ~p,\n" ++
+ " o0 = ~p,\n" ++
+ " o1 = ~p ++ o0,\n" ++
" o2 = ~p ++ o1,\n" ++
" o3 = ~p ++ o2.\n",
[ordsets:from_list([verbose, debug, time, load, pp_beam,
pp_icode, pp_rtl, pp_native, pp_asm,
timeout]),
expand_options([pp_all], HostArch),
- O1 -- [o1],
+ O0 -- [o0],
+ (O1 -- O0) -- [o1],
(O2 -- O1) -- [o2],
(O3 -- O2) -- [o3]]),
ok.
@@ -1213,6 +1230,18 @@ option_text(regalloc) ->
" optimistic - another variant of a coalescing allocator";
option_text(remove_comments) ->
"Strip comments from intermediate code";
+option_text(ra_range_split) ->
+ "Split live ranges of temporaries live over call instructions\n"
+ "before performing register allocation.\n"
+ "Heuristically tries to move stack accesses to the cold path of function.\n"
+ "This range splitter is more sophisticated than 'ra_restore_reuse', but has\n"
+ "a significantly larger impact on compile time.\n"
+ "Should only be used with move coalescing register allocators.";
+option_text(ra_restore_reuse) ->
+ "Split live ranges of temporaries such that straight-line\n"
+ "code will not need to contain multiple restores from the same stack\n"
+ "location.\n"
+ "Should only be used with move coalescing register allocators.";
option_text(rtl_ssa) ->
"Perform SSA conversion on the RTL level -- default starting at O2";
option_text(rtl_ssa_const_prop) ->
@@ -1352,6 +1381,14 @@ opt_keys() ->
pp_rtl_lcm,
pp_rtl_ssapre,
pp_rtl_linear,
+ ra_partitioned,
+ ra_prespill,
+ ra_range_split,
+ ra_restore_reuse,
+ range_split_min_gain,
+ range_split_mode1_fudge,
+ range_split_weight_power,
+ range_split_weights,
regalloc,
remove_comments,
rtl_ssa,
@@ -1382,8 +1419,16 @@ opt_keys() ->
%% Definitions:
+o0_opts(_TargetArch) ->
+ [concurrent_comp, {regalloc,linear_scan}].
+
o1_opts(TargetArch) ->
- Common = [inline_fp, pmatch, peephole],
+ Common = [inline_fp, pmatch, peephole, ra_prespill, ra_partitioned,
+ icode_ssa_const_prop, icode_ssa_copy_prop, icode_inline_bifs,
+ rtl_ssa, rtl_ssa_const_prop, rtl_ssapre,
+ spillmin_color, use_indexing, remove_comments,
+ binary_opt, {regalloc,coalescing}, ra_restore_reuse
+ | o0_opts(TargetArch)],
case TargetArch of
ultrasparc ->
Common;
@@ -1402,11 +1447,9 @@ o1_opts(TargetArch) ->
end.
o2_opts(TargetArch) ->
- Common = [icode_ssa_const_prop, icode_ssa_copy_prop, % icode_ssa_struct_reuse,
- icode_type, icode_inline_bifs, icode_call_elim, rtl_lcm,
- rtl_ssa, rtl_ssa_const_prop,
- spillmin_color, use_indexing, remove_comments,
- concurrent_comp, binary_opt | o1_opts(TargetArch)],
+ Common = [icode_type, icode_call_elim, % icode_ssa_struct_reuse,
+ ra_range_split, range_split_weights, % XXX: Having defaults here is ugly
+ rtl_lcm | (o1_opts(TargetArch) -- [rtl_ssapre, ra_restore_reuse])],
case TargetArch of
T when T =:= amd64 orelse T =:= ppc64 -> % 64-bit targets
[icode_range | Common];
@@ -1416,7 +1459,7 @@ o2_opts(TargetArch) ->
o3_opts(TargetArch) ->
%% no point checking for target architecture since this is checked in 'o1'
- [icode_range, {regalloc,coalescing} | o2_opts(TargetArch)].
+ [icode_range | o2_opts(TargetArch)].
%% Note that in general, the normal form for options should be positive.
%% This is a good programming convention, so that tests in the code say
@@ -1452,6 +1495,11 @@ opt_negations() ->
{no_pp_native, pp_native},
{no_pp_rtl_lcm, pp_rtl_lcm},
{no_pp_rtl_ssapre, pp_rtl_ssapre},
+ {no_ra_partitioned, ra_partitioned},
+ {no_ra_prespill, ra_prespill},
+ {no_ra_range_split, ra_range_split},
+ {no_ra_restore_reuse, ra_restore_reuse},
+ {no_range_split_weights, range_split_weights},
{no_remove_comments, remove_comments},
{no_rtl_ssa, rtl_ssa},
{no_rtl_ssa_const_prop, rtl_ssa_const_prop},
@@ -1481,7 +1529,8 @@ opt_basic_expansions() ->
[{pp_all, [pp_beam, pp_icode, pp_rtl, pp_native]}].
opt_expansions(TargetArch) ->
- [{o1, o1_opts(TargetArch)},
+ [{o0, o0_opts(TargetArch)},
+ {o1, o1_opts(TargetArch)},
{o2, o2_opts(TargetArch)},
{o3, o3_opts(TargetArch)},
{to_llvm, llvm_opts(o3, TargetArch)},
@@ -1528,13 +1577,21 @@ expand_kt2(Opts) ->
-spec expand_options(comp_options(), hipe_architecture()) -> comp_options().
-expand_options(Opts, TargetArch) ->
+expand_options(Opts0, TargetArch) ->
+ Opts1 = proplists:normalize(Opts0, [{aliases, opt_aliases()}]),
+ Opts = normalise_opt_options(Opts1),
proplists:normalize(Opts, [{negations, opt_negations()},
- {aliases, opt_aliases()},
{expand, opt_basic_expansions()},
{expand, opt_expansions(TargetArch)},
{negations, opt_negations()}]).
+normalise_opt_options([o0|Opts]) -> [o0] ++ (Opts -- [o0, o1, o2, o3]);
+normalise_opt_options([o1|Opts]) -> [o1] ++ (Opts -- [o0, o1, o2, o3]);
+normalise_opt_options([o2|Opts]) -> [o2] ++ (Opts -- [o0, o1, o2, o3]);
+normalise_opt_options([o3|Opts]) -> [o3] ++ (Opts -- [o0, o1, o2, o3]);
+normalise_opt_options([O|Opts]) -> [O|normalise_opt_options(Opts)];
+normalise_opt_options([]) -> [].
+
-spec check_options(comp_options()) -> 'ok'.
check_options(Opts) ->
@@ -1551,7 +1608,7 @@ check_options(Opts) ->
-spec llvm_support_available() -> boolean().
llvm_support_available() ->
- get_llvm_version() >= {3,4}.
+ get_llvm_version() >= {3,9}.
-type llvm_version() :: {Major :: integer(), Minor :: integer()}.
diff --git a/lib/hipe/main/hipe.hrl.src b/lib/hipe/main/hipe.hrl.src
index 53b59f88f0..b9accf0054 100644
--- a/lib/hipe/main/hipe.hrl.src
+++ b/lib/hipe/main/hipe.hrl.src
@@ -1,9 +1,5 @@
-%% -*- erlang-indent-level: 2 -*-
+%% -*- mode: erlang; erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Filename : hipe.hrl (automatically generated by hipe.hrl.src)
@@ -70,20 +64,24 @@
code_server:info_msg(?MSGTAG ++ Msg, Args)).
-define(untagged_msg(Msg, Args),
code_server:info_msg(Msg, Args)).
+-define(untagged_error_msg(Msg, Args),
+ code_server:error_msg(Msg, Args)).
-else.
-define(msg(Msg, Args),
io:format(?MSGTAG ++ Msg, Args)).
-define(untagged_msg(Msg, Args),
io:format(Msg, Args)).
+-define(untagged_error_msg(Msg, Args),
+ io:format(Msg, Args)).
-endif.
%%
%% Define error and warning messages.
%%
-define(error_msg(Msg, Args),
- code_server:error_msg(?MSGTAG ++
+ ?untagged_error_msg(?MSGTAG ++
"Error: [~s:~w]: " ++ Msg,
- [?MODULE,?LINE|Args])).
+ [?MODULE,?LINE|Args])).
-define(WARNING_MSG(Msg, Args),
?msg("Warning: [~s:~w]: " ++ Msg, [?MODULE,?LINE|Args])).
diff --git a/lib/hipe/main/hipe_main.erl b/lib/hipe/main/hipe_main.erl
index 4b89feb48a..dca6fddec3 100644
--- a/lib/hipe/main/hipe_main.erl
+++ b/lib/hipe/main/hipe_main.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%% @doc This is the HiPE compiler's main "loop".
%%
%% <h3>Purpose</h3>
diff --git a/lib/hipe/misc/Makefile b/lib/hipe/misc/Makefile
index 72cfff21a8..e5033e444b 100644
--- a/lib/hipe/misc/Makefile
+++ b/lib/hipe/misc/Makefile
@@ -44,7 +44,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/hipe-$(VSN)
# Target Specs
# ----------------------------------------------------
ifdef HIPE_ENABLED
-HIPE_MODULES = hipe_data_pp hipe_pack_constants hipe_sdi
+HIPE_MODULES = hipe_data_pp hipe_pack_constants hipe_sdi hipe_segment_trees
else
HIPE_MODULES =
endif
diff --git a/lib/hipe/misc/hipe_consttab.erl b/lib/hipe/misc/hipe_consttab.erl
index 226b20fa46..741bdb2094 100644
--- a/lib/hipe/misc/hipe_consttab.erl
+++ b/lib/hipe/misc/hipe_consttab.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% @doc
@@ -69,9 +63,7 @@
%% A hipe_consttab is a tuple {Data, ReferedLabels, NextConstLabel}
%% @type hipe_constlbl().
%% An abstract datatype for referring to data.
-%% @type element_type() = byte | word | ctab_array()
-%% @type ctab_array() = {ctab_array, Type::element_type(),
-%% NoElements::pos_integer()}
+%% @type element_type() = byte | word
%% @type block() = [integer() | label_ref()]
%% @type label_ref() = {label, Label::code_label()}
%% @type code_label() = hipe_sparc:label_name() | hipe_x86:label_name()
@@ -116,8 +108,7 @@
-type label_ref() :: {'label', code_label()}.
-type block() :: [hipe_constlbl() | label_ref()].
--type ctab_array() :: {'ctab_array', 'byte' | 'word', pos_integer()}.
--type element_type() :: 'byte' | 'word' | ctab_array().
+-type element_type() :: 'byte' | 'word'.
-type sort_order() :: term(). % XXX: FIXME
@@ -193,7 +184,7 @@ insert_block({ConstTab, RefToLabels, NextLabel}, ElementType, InitList) ->
ReferredLabels = get_labels(InitList, []),
NewRefTo = ReferredLabels ++ RefToLabels,
{NewTa, Id} = insert_const({ConstTab, NewRefTo, NextLabel},
- block, word_size(), false,
+ block, size_of(ElementType), false,
{ElementType,InitList}),
{insert_backrefs(NewTa, Id, ReferredLabels), Id}.
@@ -262,13 +253,9 @@ get_labels([], Acc) ->
%% @spec size_of(element_type()) -> pos_integer()
%% @doc Returns the size in bytes of an element_type.
-%% The is_atom/1 guard in the clause handling arrays
-%% constraints the argument to 'byte' | 'word'
-spec size_of(element_type()) -> pos_integer().
size_of(byte) -> 1;
-size_of(word) -> word_size();
-size_of({ctab_array,S,N}) when is_atom(S), is_integer(N), N > 0 ->
- N * size_of(S).
+size_of(word) -> word_size().
%% @spec decompose({element_type(), block()}) -> [byte()]
%% @doc Turns a block into a list of bytes.
diff --git a/lib/hipe/misc/hipe_consttab.hrl b/lib/hipe/misc/hipe_consttab.hrl
index 550da0455c..4d2d357a0b 100644
--- a/lib/hipe/misc/hipe_consttab.hrl
+++ b/lib/hipe/misc/hipe_consttab.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-----------------------------------------------------------------------------
diff --git a/lib/hipe/misc/hipe_data_pp.erl b/lib/hipe/misc/hipe_data_pp.erl
index 6cdc6c5ad2..2c737b6d78 100644
--- a/lib/hipe/misc/hipe_data_pp.erl
+++ b/lib/hipe/misc/hipe_data_pp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,12 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
-%% Time-stamp: <2008-04-20 14:57:08 richard>
%% ====================================================================
%% Module : hipe_data_pp
%% Purpose :
diff --git a/lib/hipe/misc/hipe_gensym.erl b/lib/hipe/misc/hipe_gensym.erl
index da7c4f9a5d..548071fd8f 100644
--- a/lib/hipe/misc/hipe_gensym.erl
+++ b/lib/hipe/misc/hipe_gensym.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,16 +11,12 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%=======================================================================
%% File : hipe_gensym.erl
%% Author : Eric Johansson and Kostis Sagonas
%% Description : Generates unique symbols and fresh integer counts.
%%=======================================================================
-%% $Id$
-%%=======================================================================
%% Notes: Written while we were in Montreal, Canada for PPDP-2000 as an
%% exercise in Principles and Practice of Declarative Programming!
%%=======================================================================
diff --git a/lib/hipe/misc/hipe_pack_constants.erl b/lib/hipe/misc/hipe_pack_constants.erl
index b54830dd57..6736d1f503 100644
--- a/lib/hipe/misc/hipe_pack_constants.erl
+++ b/lib/hipe/misc/hipe_pack_constants.erl
@@ -1,10 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
-%%=============================================================================
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,12 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_pack_constants).
--export([pack_constants/2, slim_refs/1, slim_constmap/1,
+-export([pack_constants/1, slim_refs/1, slim_constmap/1,
find_const/2, mk_data_relocs/2, slim_sorted_exportmap/3]).
-include("hipe_consttab.hrl").
@@ -45,8 +37,8 @@
-record(pcm_entry, {mfa :: mfa(),
label :: hipe_constlbl(),
- const_num :: const_num(),
- start :: addr(),
+ const_num :: const_num(),
+ start :: addr(),
type :: 0 | 1 | 2,
raw_data :: raw_data()}).
-type pcm_entry() :: #pcm_entry{}.
@@ -61,11 +53,11 @@
%%-----------------------------------------------------------------------------
--spec pack_constants([{mfa(),[_],hipe_consttab()}], ct_alignment()) ->
+-spec pack_constants([{mfa(),[_],hipe_consttab()}]) ->
{ct_alignment(), non_neg_integer(), packed_const_map(), mfa_refs_map()}.
-pack_constants(Data, Align) ->
- pack_constants(Data, 0, Align, 0, [], []).
+pack_constants(Data) ->
+ pack_constants(Data, 0, 1, 0, [], []). % 1 = byte alignment
pack_constants([{MFA,_,ConstTab}|Rest], Size, Align, ConstNo, Acc, Refs) ->
Labels = hipe_consttab:labels(ConstTab),
diff --git a/lib/hipe/misc/hipe_sdi.erl b/lib/hipe/misc/hipe_sdi.erl
index fbb4b105f6..9a60382686 100644
--- a/lib/hipe/misc/hipe_sdi.erl
+++ b/lib/hipe/misc/hipe_sdi.erl
@@ -1,10 +1,6 @@
%%% -*- erlang-indent-level: 2 -*-
%%%======================================================================
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% An implementation of the algorithm described in:
%%% "Assembling Code for Machines with Span-Dependent Instructions",
@@ -36,10 +30,13 @@
%%------------------------------------------------------------------------
-type hipe_array() :: integer(). % declare this in hipe.hrl or builtin?
+-type hipe_vector(E) :: {} | {E} | {E, E} | {E, E, E} | tuple().
-type label() :: non_neg_integer().
-type address() :: non_neg_integer().
+-type parents() :: {hipe_vector(_ :: integer()), hipe_segment_trees:tree()}.
+
%%------------------------------------------------------------------------
-record(label_data, {address :: address(),
@@ -168,9 +165,11 @@ mk_long(N) ->
%%% - Since the graph is traversed from child to parent nodes in
%%% Step 3, the edges are represented by a vector PARENTS[0..n-1]
%%% such that PARENTS[j] = { i | i is a parent of j }.
-%%% - An explicit PARENTS graph would have size O(n^2). Instead we
-%%% compute PARENTS[j] from the SDI vector when needed. This
-%%% reduces memory overheads, and may reduce time overheads too.
+%%% - An explicit PARENTS graph would have size O(n^2). Instead, we
+%%% observe that (i is a parent of j) iff (j \in range(i)), where
+%%% range(i) is a constant function. We can thus precompute all the
+%%% ranges i and insert them into a data structure built for such
+%%% queries. In this case, we use a segment tree.
-spec mk_span(non_neg_integer(), tuple()) -> hipe_array().
mk_span(N, SDIS) ->
@@ -188,7 +187,29 @@ initSPAN(SdiNr, N, SDIS, SPAN) ->
initSPAN(SdiNr+1, N, SDIS, SPAN)
end.
-mk_parents(N, SDIS) -> {N,SDIS}.
+-spec mk_parents(non_neg_integer(), tuple()) -> parents().
+mk_parents(N, SDIS) ->
+ PrevSDIS = vector_from_list(select_prev_sdis(N-1, SDIS, [])),
+ Ranges = parents_generate_ranges(N-1, PrevSDIS, []),
+ {PrevSDIS, hipe_segment_trees:build(Ranges)}.
+
+select_prev_sdis(-1, _SDIS, Acc) -> Acc;
+select_prev_sdis(SdiNr, SDIS, Acc) ->
+ #sdi_data{prevSdi=PrevSdi} = vector_sub(SDIS, SdiNr),
+ select_prev_sdis(SdiNr-1, SDIS, [PrevSdi|Acc]).
+
+parents_generate_ranges(-1, _PrevSDIS, Acc) -> Acc;
+parents_generate_ranges(SdiNr, PrevSDIS, Acc) ->
+ %% inclusive
+ {LO,HI} = parents_generate_range(SdiNr, PrevSDIS),
+ parents_generate_ranges(SdiNr-1, PrevSDIS, [{LO,HI}|Acc]).
+
+-compile({inline, parents_generate_range/2}).
+parents_generate_range(SdiNr, PrevSDIS) ->
+ PrevSdi = vector_sub(PrevSDIS, SdiNr),
+ if SdiNr =< PrevSdi -> {SdiNr+1, PrevSdi}; % forwards
+ true -> {PrevSdi+1, SdiNr-1} % backwards
+ end.
%%% "After the structure is built we process it as follows.
%%% For any node i whose listed span exceeds the architectural
@@ -209,7 +230,7 @@ mk_parents(N, SDIS) -> {N,SDIS}.
%%% and PARENTS are no longer useful.
-spec update_long(non_neg_integer(), tuple(), hipe_array(),
- {non_neg_integer(),tuple()},hipe_array()) -> 'ok'.
+ parents(),hipe_array()) -> 'ok'.
update_long(N, SDIS, SPAN, PARENTS, LONG) ->
WKL = initWKL(N-1, SDIS, SPAN, []),
processWKL(WKL, SDIS, SPAN, PARENTS, LONG).
@@ -225,46 +246,32 @@ initWKL(SdiNr, SDIS, SPAN, WKL) ->
end.
-spec processWKL([non_neg_integer()], tuple(), hipe_array(),
- {non_neg_integer(), tuple()}, hipe_array()) -> 'ok'.
+ parents(), hipe_array()) -> 'ok'.
processWKL([], _SDIS, _SPAN, _PARENTS, _LONG) -> ok;
-processWKL([Child|WKL], SDIS, SPAN, PARENTS, LONG) ->
- WKL2 = updateChild(Child, WKL, SDIS, SPAN, PARENTS, LONG),
+processWKL([Child|WKL], SDIS, SPAN, PARENTS0, LONG) ->
+ {WKL2, PARENTS} =
+ case array_sub(SPAN, Child) of
+ 0 -> {WKL, PARENTS0}; % removed
+ _ ->
+ SdiData = vector_sub(SDIS, Child),
+ Incr = sdiLongIncr(SdiData),
+ array_update(LONG, Child, Incr),
+ array_update(SPAN, Child, 0), % remove child
+ PARENTS1 = deleteParent(PARENTS0, Child),
+ PS = parentsOfChild(PARENTS1, Child),
+ {updateParents(PS, Child, Incr, SDIS, SPAN, WKL), PARENTS1}
+ end,
processWKL(WKL2, SDIS, SPAN, PARENTS, LONG).
--spec updateChild(non_neg_integer(), [non_neg_integer()], tuple(), hipe_array(),
- {non_neg_integer(),tuple()}, hipe_array()) -> [non_neg_integer()].
-updateChild(Child, WKL, SDIS, SPAN, PARENTS, LONG) ->
- case array_sub(SPAN, Child) of
- 0 -> WKL; % removed
- _ ->
- SdiData = vector_sub(SDIS, Child),
- Incr = sdiLongIncr(SdiData),
- array_update(LONG, Child, Incr),
- array_update(SPAN, Child, 0), % remove child
- PS = parentsOfChild(PARENTS, Child),
- updateParents(PS, Child, Incr, SDIS, SPAN, WKL)
- end.
+-spec parentsOfChild(parents(), non_neg_integer()) -> [non_neg_integer()].
+parentsOfChild({_PrevSDIS, SegTree}, Child) ->
+ hipe_segment_trees:intersect(Child, SegTree).
--spec parentsOfChild({non_neg_integer(),tuple()},
- non_neg_integer()) -> [non_neg_integer()].
-parentsOfChild({N,SDIS}, Child) ->
- parentsOfChild(N-1, SDIS, Child, []).
-
--spec parentsOfChild(integer(), tuple(), non_neg_integer(),
- [non_neg_integer()]) -> [non_neg_integer()].
-parentsOfChild(-1, _SDIS, _Child, PS) -> PS;
-parentsOfChild(SdiNr, SDIS, Child, PS) ->
- SdiData = vector_sub(SDIS, SdiNr),
- #sdi_data{prevSdi=PrevSdi} = SdiData,
- {LO,HI} = % inclusive
- if SdiNr =< PrevSdi -> {SdiNr+1, PrevSdi}; % forwards
- true -> {PrevSdi+1, SdiNr-1} % backwards
- end,
- NewPS =
- if LO =< Child, Child =< HI -> [SdiNr | PS];
- true -> PS
- end,
- parentsOfChild(SdiNr-1, SDIS, Child, NewPS).
+-spec deleteParent(parents(), non_neg_integer()) -> parents().
+deleteParent({PrevSDIS, SegTree0}, Parent) ->
+ {LO,HI} = parents_generate_range(Parent, PrevSDIS),
+ SegTree = hipe_segment_trees:delete(Parent, LO, HI, SegTree0),
+ {PrevSDIS, SegTree}.
-spec updateParents([non_neg_integer()], non_neg_integer(),
byte(), tuple(), hipe_array(),
@@ -297,10 +304,12 @@ updateWKL(SdiNr, SDIS, SdiSpan, WKL) ->
false -> [SdiNr|WKL]
end.
+-compile({inline, sdiSpanIsShort/2}). %% Only called once
-spec sdiSpanIsShort(#sdi_data{}, integer()) -> boolean().
sdiSpanIsShort(#sdi_data{si = #sdi_info{lb = LB, ub = UB}}, SdiSpan) ->
SdiSpan >= LB andalso SdiSpan =< UB.
+-compile({inline, sdiLongIncr/1}). %% Only called once
-spec sdiLongIncr(#sdi_data{}) -> byte().
sdiLongIncr(#sdi_data{si = #sdi_info{incr = Incr}}) -> Incr.
@@ -361,9 +370,11 @@ applyIncr([{Label,LabelData}|List], INCREMENT, LabelMap) ->
%%% Currently implemented as tuples.
%%% Used for the 'SDIS' and 'PARENTS' vectors.
--spec vector_from_list([#sdi_data{}]) -> tuple().
+-spec vector_from_list([E]) -> hipe_vector(E).
vector_from_list(Values) -> list_to_tuple(Values).
+-compile({inline, vector_sub/2}).
+-spec vector_sub(hipe_vector(E), non_neg_integer()) -> V when V :: E.
vector_sub(Vec, I) -> element(I+1, Vec).
%%% ADT for mutable integer arrays, indexed from 0 to N-1.
@@ -373,8 +384,10 @@ vector_sub(Vec, I) -> element(I+1, Vec).
-spec mk_array_of_zeros(non_neg_integer()) -> hipe_array().
mk_array_of_zeros(N) -> hipe_bifs:array(N, 0).
+-compile({inline, array_update/3}).
-spec array_update(hipe_array(), non_neg_integer(), integer()) -> hipe_array().
array_update(A, I, V) -> hipe_bifs:array_update(A, I, V).
+-compile({inline, array_sub/2}).
-spec array_sub(hipe_array(), non_neg_integer()) -> integer().
array_sub(A, I) -> hipe_bifs:array_sub(A, I).
diff --git a/lib/hipe/misc/hipe_sdi.hrl b/lib/hipe/misc/hipe_sdi.hrl
index a1e12f9df2..def697549c 100644
--- a/lib/hipe/misc/hipe_sdi.hrl
+++ b/lib/hipe/misc/hipe_sdi.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,10 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-record(sdi_info,
{lb :: integer(), % span lower bound for short form
diff --git a/lib/hipe/misc/hipe_segment_trees.erl b/lib/hipe/misc/hipe_segment_trees.erl
new file mode 100644
index 0000000000..3d6a7487ec
--- /dev/null
+++ b/lib/hipe/misc/hipe_segment_trees.erl
@@ -0,0 +1,174 @@
+%%% Licensed under the Apache License, Version 2.0 (the "License");
+%%% you may not use this file except in compliance with the License.
+%%% You may obtain a copy of the License at
+%%%
+%%% http://www.apache.org/licenses/LICENSE-2.0
+%%%
+%%% Unless required by applicable law or agreed to in writing, software
+%%% distributed under the License is distributed on an "AS IS" BASIS,
+%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%%% See the License for the specific language governing permissions and
+%%% limitations under the License.
+%%%
+%%% Segment trees, with a delete operation.
+%%%
+%%% Keys are the (0-based) indices into the list passed to build/1.
+%%%
+%%% Range bounds are inclusive.
+%%%
+
+-module(hipe_segment_trees).
+
+-export([build/1, intersect/2, delete/4]).
+
+-record(segment_tree, {
+ lo :: integer(),
+ hi :: integer(),
+ root :: tnode()
+ }).
+
+%% X =< Mid belongs in Left
+-define(NODE(Left, Right, Mid, Segments), {Left, Right, Mid, Segments}).
+
+-define(POINT_LEAF(Val), Val).
+-define(RANGE_LEAF(Lo, Hi), {Lo, Hi}).
+
+-type segments() :: [non_neg_integer()].
+-type leaf() :: segments().
+-type tnode() :: ?NODE(tnode(), tnode(), integer(), segments()) | leaf().
+
+-opaque tree() :: #segment_tree{} | nil.
+-export_type([tree/0]).
+
+%% @doc Builds a segment tree of the given intervals.
+-spec build([{integer(), integer()}]) -> tree().
+build(ListOfIntervals) ->
+ case
+ lists:usort(
+ lists:append(
+ [[Lo, Hi] || {Lo, Hi} <- ListOfIntervals, Lo =< Hi]))
+ of
+ [] -> nil;
+ Endpoints ->
+ Tree0 = empty_tree_from_endpoints(Endpoints),
+ [Lo|_] = Endpoints,
+ Hi = lists:last(Endpoints),
+ Tree1 = insert_intervals(0, ListOfIntervals, Lo, Hi, Tree0),
+ Tree = squash_empty_subtrees(Tree1),
+ #segment_tree{lo=Lo, hi=Hi, root=Tree}
+ end.
+
+empty_tree_from_endpoints(Endpoints) ->
+ Leaves = leaves(Endpoints),
+ {T, [], _, _} = balanced_bst(Leaves, length(Leaves)),
+ T.
+
+leaves([Endpoint]) -> [?POINT_LEAF(Endpoint)];
+leaves([A | [B|_] = Tail]) ->
+ %% We omit the range leaf if it's empty
+ case A<B-1 of
+ true -> [?POINT_LEAF(A),?RANGE_LEAF(A+1,B-1) | leaves(Tail)];
+ false -> [?POINT_LEAF(A) | leaves(Tail)]
+ end.
+
+balanced_bst(L, S) when S > 1 ->
+ Sm = S, %% - 1
+ S2 = Sm div 2,
+ S1 = Sm - S2,
+ {Left, L1, LeftLo, LeftHi} = balanced_bst(L, S1),
+ {Right, L2, _, RightHi} = balanced_bst(L1, S2),
+ T = ?NODE(Left, Right, LeftHi, []),
+ {T, L2, LeftLo, RightHi};
+balanced_bst([?RANGE_LEAF(Lo, Hi) | L], 1) ->
+ {[], L, Lo, Hi};
+balanced_bst([?POINT_LEAF(Val) | L], 1) ->
+ {[], L, Val, Val}.
+
+insert_intervals(_Ix, [], _Lo, _Hi, Tree) -> Tree;
+insert_intervals(Ix, [Int|Ints], Lo, Hi, Tree) ->
+ insert_intervals(Ix + 1, Ints, Lo, Hi,
+ insert_interval(Ix, Int, Lo, Hi, Tree)).
+
+insert_interval(_, {Lo, Hi}, _, _, Node) when Lo > Hi -> Node;
+insert_interval(I, Int={Lo,Hi}, NLo, NHi,
+ ?NODE(Left0, Right0, Mid, Segments)) ->
+ if Lo =< NLo, NHi =< Hi ->
+ ?NODE(Left0, Right0, Mid, [I|Segments]);
+ true ->
+ Left = case intervals_intersect(Lo, Hi, NLo, Mid) of
+ true -> insert_interval(I, Int, NLo, Mid, Left0);
+ false -> Left0
+ end,
+ Right = case intervals_intersect(Lo, Hi, Mid+1, NHi) of
+ true -> insert_interval(I, Int, Mid+1, NHi, Right0);
+ false -> Right0
+ end,
+ ?NODE(Left, Right, Mid, Segments)
+ end;
+insert_interval(I, {_Lo,_Hi}, _NLo, _NHi, Leaf) -> [I|Leaf].
+
+intervals_intersect(ALo, AHi, BLo, BHi) ->
+ (ALo =< AHi) andalso (BLo =< BHi) %% both nonempty
+ andalso nonempty_intervals_intersect(ALo, AHi, BLo, BHi).
+
+%% Purely optional optimisation
+squash_empty_subtrees(?NODE(Left0, Right0, Mid, Segs)) ->
+ build_squash_node(squash_empty_subtrees(Left0),
+ squash_empty_subtrees(Right0),
+ Mid, Segs);
+squash_empty_subtrees(Leaf) -> Leaf.
+
+build_squash_node([], [], _, Segs) -> Segs;
+build_squash_node(Left, Right, Mid, Segs) ->
+ ?NODE(Left, Right, Mid, Segs).
+
+%% @doc Returns the indices of the intervals in the tree that contains Point.
+-spec intersect(integer(), tree()) -> [non_neg_integer()].
+intersect(Point, nil) when is_integer(Point) -> [];
+intersect(Point, #segment_tree{lo=Lo, hi=Hi, root=Root})
+ when is_integer(Point) ->
+ case Lo =< Point andalso Point =< Hi of
+ false -> [];
+ true -> intersect_1(Point, Root, [])
+ end.
+
+intersect_1(Point, ?NODE(Left, Right, Mid, Segs), Acc0) ->
+ Child = if Point =< Mid -> Left; true -> Right end,
+ intersect_1(Point, Child, Segs ++ Acc0);
+intersect_1(_, LeafSegs, Acc) -> LeafSegs ++ Acc.
+
+%% @doc Deletes the interval {Lo, Hi}, which had index Index in the list passed
+%% to build/1.
+-spec delete(non_neg_integer(), integer(), integer(), tree()) -> tree().
+delete(_, _, _, nil) -> nil;
+delete(_, Lo, Hi, Tree) when Lo > Hi -> Tree;
+delete(_, Lo, Hi, Tree = #segment_tree{lo=TLo, hi=THi})
+ when Hi < TLo; Lo > THi -> Tree;
+delete(Index, Lo, Hi, Tree = #segment_tree{lo=TLo, hi=THi, root=Root0})
+ when is_integer(Lo), is_integer(Hi) ->
+ Root = delete_1(Index, Lo, Hi, TLo, THi, Root0),
+ Tree#segment_tree{root=Root}.
+
+delete_1(I, Lo, Hi, NLo, NHi, ?NODE(Left0, Right0, Mid, Segments)) ->
+ if Lo =< NLo, NHi =< Hi ->
+ ?NODE(Left0, Right0, Mid, delete_2(Segments, I));
+ true ->
+ Left = case nonempty_intervals_intersect(Lo, Hi, NLo, Mid) of
+ true -> delete_1(I, Lo, Hi, NLo, Mid, Left0);
+ false -> Left0
+ end,
+ Right = case nonempty_intervals_intersect(Lo, Hi, Mid+1, NHi) of
+ true -> delete_1(I, Lo, Hi, Mid+1, NHi, Right0);
+ false -> Right0
+ end,
+ %% We could do build_squash_node here, is it worth it?
+ ?NODE(Left, Right, Mid, Segments)
+ end;
+delete_1(I, _Lo, _Hi, _NLo, _NHi, Leaf) -> delete_2(Leaf, I).
+
+delete_2([I|Segs], I) -> Segs;
+delete_2([S|Segs], I) -> [S|delete_2(Segs,I)].
+
+-compile({inline,nonempty_intervals_intersect/4}).
+nonempty_intervals_intersect(ALo, AHi, BLo, BHi) ->
+ (BLo =< AHi) andalso (ALo =< BHi).
diff --git a/lib/hipe/opt/Makefile b/lib/hipe/opt/Makefile
index 684d6f45b4..5a729d04ae 100644
--- a/lib/hipe/opt/Makefile
+++ b/lib/hipe/opt/Makefile
@@ -43,7 +43,8 @@ RELSYSDIR = $(RELEASE_PATH)/lib/hipe-$(VSN)
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
-MODULES = hipe_spillmin hipe_spillmin_color hipe_spillmin_scan
+MODULES = hipe_spillmin hipe_spillmin_color hipe_spillmin_scan \
+ hipe_bb_weights
HRL_FILES=
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/hipe/opt/hipe_bb_weights.erl b/lib/hipe/opt/hipe_bb_weights.erl
new file mode 100644
index 0000000000..8ef113b94c
--- /dev/null
+++ b/lib/hipe/opt/hipe_bb_weights.erl
@@ -0,0 +1,449 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%@doc
+%% BASIC BLOCK WEIGHTING
+%%
+%% Computes basic block weights by using branch probabilities as weights in a
+%% linear equation system, that is then solved using Gauss-Jordan Elimination.
+%%
+%% The equation system representation is intentionally sparse, since most blocks
+%% have at most two successors.
+-module(hipe_bb_weights).
+-export([compute/3, compute_fast/3, weight/2, call_exn_pred/0]).
+-export_type([bb_weights/0]).
+
+-compile(inline).
+
+%%-define(DO_ASSERT,1).
+%%-define(DEBUG,1).
+-include("../main/hipe.hrl").
+
+%% If the equation system is large, it might take too long to solve it exactly.
+%% Thus, if there are more than ?HEUR_MAX_SOLVE labels, we use the iterative
+%% approximation.
+-define(HEUR_MAX_SOLVE, 10000).
+
+-opaque bb_weights() :: #{label() => float()}.
+
+-type cfg() :: any().
+-type target_module() :: module().
+-type target_context() :: any().
+-type target() :: {target_module(), target_context()}.
+
+-type label() :: integer().
+-type var() :: label().
+-type assignment() :: {var(), float()}.
+-type eq_assoc() :: [{var(), key()}].
+-type solution() :: [assignment()].
+
+%% Constant. Predicted probability of a call resulting in an exception.
+-spec call_exn_pred() -> float().
+call_exn_pred() -> 0.01.
+
+-spec compute(cfg(), target_module(), target_context()) -> bb_weights().
+compute(CFG, TgtMod, TgtCtx) ->
+ Target = {TgtMod, TgtCtx},
+ Labels = labels(CFG, Target),
+ if length(Labels) > ?HEUR_MAX_SOLVE ->
+ ?debug_msg("~w: Too many labels (~w), approximating.~n",
+ [?MODULE, length(Labels)]),
+ compute_fast(CFG, TgtMod, TgtCtx);
+ true ->
+ {EqSys, EqAssoc} = build_eq_system(CFG, Labels, Target),
+ case solve(EqSys, EqAssoc) of
+ {ok, Solution} ->
+ maps:from_list(Solution)
+ end
+ end.
+
+-spec build_eq_system(cfg(), [label()], target()) -> {eq_system(), eq_assoc()}.
+build_eq_system(CFG, Labels, Target) ->
+ StartLb = hipe_gen_cfg:start_label(CFG),
+ EQS0 = eqs_new(),
+ {EQS1, Assoc} = build_eq_system(Labels, CFG, Target, [], EQS0),
+ {StartLb, StartKey} = lists:keyfind(StartLb, 1, Assoc),
+ StartRow0 = eqs_get(StartKey, EQS1),
+ StartRow = row_set_const(-1.0, StartRow0), % -1.0 since StartLb coef is -1.0
+ EQS = eqs_put(StartKey, StartRow, EQS1),
+ {EQS, Assoc}.
+
+build_eq_system([], _CFG, _Target, Map, EQS) -> {EQS, lists:reverse(Map)};
+build_eq_system([L|Ls], CFG, Target, Map, EQS0) ->
+ PredProb = pred_prob(L, CFG, Target),
+ {Key, EQS} = eqs_insert(row_new([{L, -1.0}|PredProb], 0.0), EQS0),
+ build_eq_system(Ls, CFG, Target, [{L, Key}|Map], EQS).
+
+pred_prob(L, CFG, Target) ->
+ [begin
+ BB = bb(CFG, Pred, Target),
+ Ps = branch_preds(hipe_bb:last(BB), Target),
+ ?ASSERT(length(lists:ukeysort(1, Ps))
+ =:= length(hipe_gen_cfg:succ(CFG, Pred))),
+ case lists:keyfind(L, 1, Ps) of
+ {L, Prob} when is_float(Prob) -> {Pred, Prob}
+ end
+ end || Pred <- hipe_gen_cfg:pred(CFG, L)].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec triangelise(eq_system(), eq_assoc()) -> {eq_system(), eq_assoc()}.
+triangelise(EQS, VKs) ->
+ triangelise_1(mk_triix(EQS, VKs), []).
+
+triangelise_1(TIX0, Acc) ->
+ case triix_is_empty(TIX0) of
+ true -> {triix_eqs(TIX0), lists:reverse(Acc)};
+ false ->
+ {V,Key,TIX1} = triix_pop_smallest(TIX0),
+ Row0 = triix_get(Key, TIX1),
+ case row_get(V, Row0) of
+ Coef when Coef > -0.0001, Coef < 0.0001 ->
+ throw(error);
+ _ ->
+ Row = row_normalise(V, Row0),
+ TIX2 = triix_put(Key, Row, TIX1),
+ TIX = eliminate_triix(V, Key, Row, TIX2),
+ triangelise_1(TIX, [{V,Key}|Acc])
+ end
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Triangelisation maintains its own index, outside of eqs. This index is
+%% essentially a BST (used as a heap) of all equations by size, with {Key,Var}
+%% as the values and only containing a subset of all the keys in the whole
+%% equation system. The key operation is triix_pop_smallest/1, which pops a
+%% {Key,Var} from the heap corresponding to one of the smallest equations. This
+%% is critical in order to prevent the equations from growing during
+%% triangelisation, which would make the algorithm O(n^2) in the common case.
+-type tri_eq_system() :: {eq_system(),
+ gb_trees:tree(non_neg_integer(),
+ gb_trees:tree(key(), var()))}.
+
+triix_eqs({EQS, _}) -> EQS.
+triix_get(Key, {EQS, _}) -> eqs_get(Key, EQS).
+triix_is_empty({_, Tree}) -> gb_trees:is_empty(Tree).
+triix_lookup(V, {EQS, _}) -> eqs_lookup(V, EQS).
+
+mk_triix(EQS, VKs) ->
+ {EQS,
+ lists:foldl(fun({V,Key}, Tree) ->
+ Size = row_size(eqs_get(Key, EQS)),
+ sitree_insert(Size, Key, V, Tree)
+ end, gb_trees:empty(), VKs)}.
+
+sitree_insert(Size, Key, V, SiTree) ->
+ SubTree1 =
+ case gb_trees:lookup(Size, SiTree) of
+ none -> gb_trees:empty();
+ {value, SubTree0} -> SubTree0
+ end,
+ SubTree = gb_trees:insert(Key, V, SubTree1),
+ gb_trees:enter(Size, SubTree, SiTree).
+
+sitree_update_subtree(Size, SubTree, SiTree) ->
+ case gb_trees:is_empty(SubTree) of
+ true -> gb_trees:delete(Size, SiTree);
+ false -> gb_trees:update(Size, SubTree, SiTree)
+ end.
+
+triix_put(Key, Row, {EQS, Tree0}) ->
+ OldSize = row_size(eqs_get(Key, EQS)),
+ case row_size(Row) of
+ OldSize -> {eqs_put(Key, Row, EQS), Tree0};
+ Size ->
+ Tree =
+ case gb_trees:lookup(OldSize, Tree0) of
+ none -> Tree0;
+ {value, SubTree0} ->
+ case gb_trees:lookup(Key, SubTree0) of
+ none -> Tree0;
+ {value, V} ->
+ SubTree = gb_trees:delete(Key, SubTree0),
+ Tree1 = sitree_update_subtree(OldSize, SubTree, Tree0),
+ sitree_insert(Size, Key, V, Tree1)
+ end
+ end,
+ {eqs_put(Key, Row, EQS), Tree}
+ end.
+
+triix_pop_smallest({EQS, Tree}) ->
+ {Size, SubTree0} = gb_trees:smallest(Tree),
+ {Key, V, SubTree} = gb_trees:take_smallest(SubTree0),
+ {V, Key, {EQS, sitree_update_subtree(Size, SubTree, Tree)}}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+row_normalise(Var, Row) ->
+ %% Normalise v's coef to 1.0
+ %% row_set_coef ensures the coef is exactly 1.0 (no rounding errors)
+ row_set_coef(Var, 1.0, row_scale(Row, 1.0/row_get(Var, Row))).
+
+%% Precondition: Row must be normalised; i.e. Vars coef must be 1.0 (mod
+%% rounding errors)
+-spec eliminate(var(), key(), row(), eq_system()) -> eq_system().
+eliminate(Var, Key, Row, TIX0) ->
+ eliminate_abstr(Var, Key, Row, TIX0,
+ fun eqs_get/2, fun eqs_lookup/2, fun eqs_put/3).
+
+-spec eliminate_triix(var(), key(), row(), tri_eq_system()) -> tri_eq_system().
+eliminate_triix(Var, Key, Row, TIX0) ->
+ eliminate_abstr(Var, Key, Row, TIX0,
+ fun triix_get/2, fun triix_lookup/2, fun triix_put/3).
+
+%% The same function implemented for two data types, eqs and triix.
+-compile({inline, eliminate_abstr/7}).
+-spec eliminate_abstr(var(), key(), row(), ADT, fun((key(), ADT) -> row()),
+ fun((var(), ADT) -> [key()]),
+ fun((key(), row(), ADT) -> ADT)) -> ADT.
+eliminate_abstr(Var, Key, Row, ADT0, GetFun, LookupFun, PutFun) ->
+ ?ASSERT(1.0 =:= row_get(Var, Row)),
+ ADT =
+ lists:foldl(fun(RK, ADT1) when RK =:= Key -> ADT1;
+ (RK, ADT1) ->
+ R = GetFun(RK, ADT1),
+ PutFun(RK, row_addmul(R, Row, -row_get(Var, R)), ADT1)
+ end, ADT0, LookupFun(Var, ADT0)),
+ [Key] = LookupFun(Var, ADT),
+ ADT.
+
+-spec solve(eq_system(), eq_assoc()) -> error | {ok, solution()}.
+solve(EQS0, EqAssoc0) ->
+ try triangelise(EQS0, EqAssoc0)
+ of {EQS1, EqAssoc} ->
+ {ok, solve_1(EqAssoc, maps:from_list(EqAssoc), EQS1, [])}
+ catch error -> error
+ end.
+
+solve_1([], _VarEqs, _EQS, Acc) -> Acc;
+solve_1([{V,K}|Ps], VarEqs, EQS0, Acc0) ->
+ Row0 = eqs_get(K, EQS0),
+ VarsToKill = [Var || {Var, _} <- row_coefs(Row0), Var =/= V],
+ Row1 = kill_vars(VarsToKill, VarEqs, EQS0, Row0),
+ [{V,_}] = row_coefs(Row1), % assertion
+ Row = row_normalise(V, Row1),
+ [{V,1.0}] = row_coefs(Row), % assertion
+ EQS = eliminate(V, K, Row, EQS0),
+ [K] = eqs_lookup(V, EQS),
+ solve_1(Ps, VarEqs, eqs_remove(K, EQS), [{V, row_const(Row)}|Acc0]).
+
+kill_vars([], _VarEqs, _EQS, Row) -> Row;
+kill_vars([V|Vs], VarEqs, EQS, Row0) ->
+ VRow0 = eqs_get(maps:get(V, VarEqs), EQS),
+ VRow = row_normalise(V, VRow0),
+ ?ASSERT(1.0 =:= row_get(V, VRow)),
+ Row = row_addmul(Row0, VRow, -row_get(V, Row0)),
+ ?ASSERT(0.0 =:= row_get(V, Row)), % V has been killed
+ kill_vars(Vs, VarEqs, EQS, Row).
+
+-spec weight(label(), bb_weights()) -> float().
+weight(Lbl, Weights) ->
+ maps:get(Lbl, Weights).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Row datatype
+%% Invariant: No 0.0 coefficiets!
+-spec row_empty() -> row().
+row_empty() -> {orddict:new(), 0.0}.
+
+-spec row_new([{var(), float()}], float()) -> row().
+row_new(Coefs, Const) when is_float(Const) ->
+ row_ensure_invar({row_squash_multiples(lists:keysort(1, Coefs)), Const}).
+
+row_squash_multiples([{K, C1},{K, C2}|Ps]) ->
+ row_squash_multiples([{K,C1+C2}|Ps]);
+row_squash_multiples([P|Ps]) -> [P|row_squash_multiples(Ps)];
+row_squash_multiples([]) -> [].
+
+row_ensure_invar({Coef, Const}) ->
+ {orddict:filter(fun(_, 0.0) -> false; (_, F) when is_float(F) -> true end,
+ Coef), Const}.
+
+row_const({_, Const}) -> Const.
+row_coefs({Coefs, _}) -> orddict:to_list(Coefs).
+row_size({Coefs, _}) -> orddict:size(Coefs).
+
+row_get(Var, {Coefs, _}) ->
+ case lists:keyfind(Var, 1, Coefs) of
+ false -> 0.0;
+ {_, Coef} -> Coef
+ end.
+
+row_set_coef(Var, 0.0, {Coefs, Const}) ->
+ {orddict:erase(Var, Coefs), Const};
+row_set_coef(Var, Coef, {Coefs, Const}) ->
+ {orddict:store(Var, Coef, Coefs), Const}.
+
+row_set_const(Const, {Coefs, _}) -> {Coefs, Const}.
+
+%% Lhs + Rhs*Factor
+-spec row_addmul(row(), row(), float()) -> row().
+row_addmul({LhsCoefs, LhsConst}, {RhsCoefs, RhsConst}, Factor)
+ when is_float(Factor) ->
+ Coefs = row_addmul_coefs(LhsCoefs, RhsCoefs, Factor),
+ Const = LhsConst + RhsConst * Factor,
+ {Coefs, Const}.
+
+row_addmul_coefs(Ls, [], Factor) when is_float(Factor) -> Ls;
+row_addmul_coefs([], Rs, Factor) when is_float(Factor) ->
+ row_scale_coefs(Rs, Factor);
+row_addmul_coefs([L={LV, _}|Ls], Rs=[{RV,_}|_], Factor)
+ when LV < RV, is_float(Factor) ->
+ [L|row_addmul_coefs(Ls, Rs, Factor)];
+row_addmul_coefs(Ls=[{LV, _}|_], [{RV, RC}|Rs], Factor)
+ when LV > RV, is_float(RC), is_float(Factor) ->
+ [{RV, RC*Factor}|row_addmul_coefs(Ls, Rs, Factor)];
+row_addmul_coefs([{V, LC}|Ls], [{V, RC}|Rs], Factor)
+ when is_float(LC), is_float(RC), is_float(Factor) ->
+ case LC + RC * Factor of
+ 0.0 -> row_addmul_coefs(Ls, Rs, Factor);
+ C -> [{V,C}|row_addmul_coefs(Ls, Rs, Factor)]
+ end.
+
+row_scale(_, 0.0) -> row_empty();
+row_scale({RowCoefs, RowConst}, Factor) when is_float(Factor) ->
+ {row_scale_coefs(RowCoefs, Factor), RowConst * Factor}.
+
+row_scale_coefs([{V,C}|Cs], Factor) when is_float(Factor), is_float(C) ->
+ [{V,C*Factor}|row_scale_coefs(Cs, Factor)];
+row_scale_coefs([], Factor) when is_float(Factor) ->
+ [].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Equation system ADT
+%%
+%% Stores a linear equation system, allowing for efficient updates and efficient
+%% queries for all equations mentioning a variable.
+%%
+%% It is sort of like a "database" table of {Primary, Terms, Const} indexed both
+%% on Primary as well as the vars (map keys) in Terms.
+-type row() :: {Terms :: orddict:orddict(var(), float()),
+ Const :: float()}.
+-type key() :: non_neg_integer().
+-type rev_index() :: #{var() => ordsets:ordset(key())}.
+-record(eq_system, {
+ rows = #{} :: #{key() => row()},
+ revidx = revidx_empty() :: rev_index(),
+ next_key = 0 :: key()
+ }).
+-type eq_system() :: #eq_system{}.
+
+eqs_new() -> #eq_system{}.
+
+-spec eqs_insert(row(), eq_system()) -> {key(), eq_system()}.
+eqs_insert(Row, EQS=#eq_system{next_key=NextKey0}) ->
+ Key = NextKey0,
+ NextKey = NextKey0 + 1,
+ {Key, eqs_insert(Key, Row, EQS#eq_system{next_key=NextKey})}.
+
+eqs_insert(Key, Row, EQS=#eq_system{rows=Rows, revidx=RevIdx0}) ->
+ RevIdx = revidx_add(Key, Row, RevIdx0),
+ EQS#eq_system{rows=Rows#{Key => Row}, revidx=RevIdx}.
+
+eqs_put(Key, Row, EQS0) ->
+ eqs_insert(Key, Row, eqs_remove(Key, EQS0)).
+
+eqs_remove(Key, EQS=#eq_system{rows=Rows, revidx=RevIdx0}) ->
+ OldRow = maps:get(Key, Rows),
+ RevIdx = revidx_remove(Key, OldRow, RevIdx0),
+ EQS#eq_system{rows = maps:remove(Key, Rows), revidx=RevIdx}.
+
+-spec eqs_get(key(), eq_system()) -> row().
+eqs_get(Key, #eq_system{rows=Rows}) -> maps:get(Key, Rows).
+
+%% Keys of all equations containing a nonzero coefficient for Var
+-spec eqs_lookup(var(), eq_system()) -> ordsets:ordset(key()).
+eqs_lookup(Var, #eq_system{revidx=RevIdx}) -> maps:get(Var, RevIdx).
+
+%% eqs_rows(#eq_system{rows=Rows}) -> maps:to_list(Rows).
+
+%% eqs_print(EQS) ->
+%% lists:foreach(fun({_, Row}) ->
+%% row_print(Row)
+%% end, lists:sort(eqs_rows(EQS))).
+
+%% row_print(Row) ->
+%% CoefStrs = [io_lib:format("~wl~w", [Coef, Var])
+%% || {Var, Coef} <- row_coefs(Row)],
+%% CoefStr = lists:join(" + ", CoefStrs),
+%% io:format("~w = ~s~n", [row_const(Row), CoefStr]).
+
+revidx_empty() -> #{}.
+
+-spec revidx_add(key(), row(), rev_index()) -> rev_index().
+revidx_add(Key, Row, RevIdx0) ->
+ orddict:fold(fun(Var, _Coef, RevIdx1) ->
+ ?ASSERT(_Coef /= 0.0),
+ RevIdx1#{Var => ordsets:add_element(
+ Key, maps:get(Var, RevIdx1, ordsets:new()))}
+ end, RevIdx0, row_coefs(Row)).
+
+-spec revidx_remove(key(), row(), rev_index()) -> rev_index().
+revidx_remove(Key, {Coefs, _}, RevIdx0) ->
+ orddict:fold(fun(Var, _Coef, RevIdx1) ->
+ case RevIdx1 of
+ #{Var := Keys0} ->
+ case ordsets:del_element(Key, Keys0) of
+ [] -> maps:remove(Var, RevIdx1);
+ Keys -> RevIdx1#{Var := Keys}
+ end
+ end
+ end, RevIdx0, Coefs).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-define(FAST_ITERATIONS, 5).
+
+%% @doc Computes a rough approximation of BB weights. The approximation is
+%% particularly poor (converges slowly) for recursive functions and loops.
+-spec compute_fast(cfg(), target_module(), target_context()) -> bb_weights().
+compute_fast(CFG, TgtMod, TgtCtx) ->
+ Target = {TgtMod, TgtCtx},
+ StartLb = hipe_gen_cfg:start_label(CFG),
+ RPO = reverse_postorder(CFG, Target),
+ PredProbs = [{L, pred_prob(L, CFG, Target)} || L <- RPO, L =/= StartLb],
+ Probs0 = (maps:from_list([{L, 0.0} || L <- RPO]))#{StartLb := 1.0},
+ fast_iterate(?FAST_ITERATIONS, PredProbs, Probs0).
+
+fast_iterate(0, _Pred, Probs) -> Probs;
+fast_iterate(Iters, Pred, Probs0) ->
+ fast_iterate(Iters-1, Pred,
+ fast_one(Pred, Probs0)).
+
+fast_one([{L, Pred}|Ls], Probs0) ->
+ Weight = fast_sum(Pred, Probs0, 0.0),
+ Probs = Probs0#{L => Weight},
+ fast_one(Ls, Probs);
+fast_one([], Probs) ->
+ Probs.
+
+fast_sum([{P,EWt}|Pred], Probs, Acc) when is_float(EWt), is_float(Acc) ->
+ case Probs of
+ #{P := PWt} when is_float(PWt) ->
+ fast_sum(Pred, Probs, Acc + PWt * EWt)
+ end;
+fast_sum([], _Probs, Acc) when is_float(Acc) ->
+ Acc.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Target module interface functions
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-define(TGT_IFACE_0(N), N( {M,C}) -> M:N( C)).
+-define(TGT_IFACE_1(N), N(A1, {M,C}) -> M:N(A1, C)).
+-define(TGT_IFACE_2(N), N(A1,A2, {M,C}) -> M:N(A1,A2, C)).
+-define(TGT_IFACE_3(N), N(A1,A2,A3,{M,C}) -> M:N(A1,A2,A3,C)).
+
+?TGT_IFACE_2(bb).
+?TGT_IFACE_1(branch_preds).
+?TGT_IFACE_1(labels).
+?TGT_IFACE_1(reverse_postorder).
diff --git a/lib/hipe/opt/hipe_schedule.erl b/lib/hipe/opt/hipe_schedule.erl
index 00ad487620..0f25940e3d 100644
--- a/lib/hipe/opt/hipe_schedule.erl
+++ b/lib/hipe/opt/hipe_schedule.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -1344,10 +1337,10 @@ cd([{N,I}|Xs], DAG, PrevBr, PrevUnsafe, PrevOthers) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Function : cd_branch_to_other_deps
%% Argument : N - index of branch
-%% Ms - list of indexes of "others" preceeding instrs
+%% Ms - list of indexes of "others" preceding instrs
%% DAG - dependence graph
%% Returns : DAG - new graph
-%% Description : Makes preceeding instrs fixed so they don't bypass a branch
+%% Description : Makes preceding instrs fixed so they don't bypass a branch
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cd_branch_to_other_deps(_, [], DAG) ->
DAG;
diff --git a/lib/hipe/opt/hipe_schedule_prio.erl b/lib/hipe/opt/hipe_schedule_prio.erl
index 3dcc0845e0..339bb82aab 100644
--- a/lib/hipe/opt/hipe_schedule_prio.erl
+++ b/lib/hipe/opt/hipe_schedule_prio.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/opt/hipe_spillmin.erl b/lib/hipe/opt/hipe_spillmin.erl
index 4eeb1d71db..b28a6bfd13 100644
--- a/lib/hipe/opt/hipe_spillmin.erl
+++ b/lib/hipe/opt/hipe_spillmin.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ==========================================================================
%% Module : hipe_spillmin
@@ -24,12 +18,11 @@
%% by a function. This is done using an algorithm for register
%% allocation. The implementation is target-independent and
%% requires a target-specific interface module as argument.
-%%
-%% $Id$
%% ==========================================================================
%% Exported functions (short description):
%%
-%% stackalloc(CFG, StackSlots, SpillIndex, Options, Target, TempMap) ->
+%% stackalloc(CFG, StackSlots, SpillIndex, Options, TgtMod, TgtCtx,
+%% TempMap) ->
%% {Coloring, NumberOfSpills}
%% Takes a CFG and the TempMap from register allocation and returns
%% a coloring of stack slots.
@@ -49,7 +42,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(hipe_spillmin).
--export([stackalloc/6, mapmerge/2]).
+-export([stackalloc/7, stackalloc/8, mapmerge/2]).
%%-define(DEBUG, 1).
-define(HIPE_INSTRUMENT_COMPILER, true).
@@ -59,6 +52,8 @@
-include("../main/hipe.hrl").
-include("../flow/cfg.hrl").
+-type target_context() :: any().
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% stackalloc(CFG, StackSlots, SpillIndex, Options, Target, TempMap)
@@ -68,18 +63,29 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec stackalloc(#cfg{}, [_], non_neg_integer(),
- comp_options(), module(), hipe_temp_map()) ->
- {hipe_spill_map(), non_neg_integer()}.
+ comp_options(), module(), target_context(), hipe_temp_map()) ->
+ {hipe_spill_map(), non_neg_integer()}.
-stackalloc(CFG, StackSlots, SpillIndex, Options, Target, TempMap) ->
+stackalloc(CFG, StackSlots, SpillIndex, Options, TgtMod, TgtCtx, TempMap) ->
+ Liveness = TgtMod:analyze(CFG,TgtCtx),
+ stackalloc(CFG, Liveness, StackSlots, SpillIndex, Options, TgtMod, TgtCtx, TempMap).
+
+-spec stackalloc(#cfg{}, _, [_], non_neg_integer(),
+ comp_options(), module(), target_context(), hipe_temp_map()) ->
+ {hipe_spill_map(), non_neg_integer()}.
+
+stackalloc(CFG, Liveness, StackSlots, SpillIndex, Options, TgtMod, TgtCtx,
+ TempMap) ->
case proplists:get_bool(spillmin_color, Options) of
false ->
- ?option_time(hipe_spillmin_scan:stackalloc(CFG, StackSlots, SpillIndex,
- Options, Target, TempMap),
+ ?option_time(hipe_spillmin_scan:stackalloc(
+ CFG, Liveness, StackSlots, SpillIndex, Options, TgtMod,
+ TgtCtx, TempMap),
"Spill minimize, linear scan", Options);
true ->
- ?option_time(hipe_spillmin_color:stackalloc(CFG, StackSlots, SpillIndex,
- Options, Target, TempMap),
+ ?option_time(hipe_spillmin_color:stackalloc(
+ CFG, Liveness, StackSlots, SpillIndex, Options, TgtMod,
+ TgtCtx, TempMap),
"Spill minimize, graph coloring", Options)
end.
diff --git a/lib/hipe/opt/hipe_spillmin_color.erl b/lib/hipe/opt/hipe_spillmin_color.erl
index 7c23de44b4..f87d9a5b61 100644
--- a/lib/hipe/opt/hipe_spillmin_color.erl
+++ b/lib/hipe/opt/hipe_spillmin_color.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ===========================================================================
%%@doc
@@ -41,7 +35,7 @@
-module(hipe_spillmin_color).
--export([stackalloc/6]).
+-export([stackalloc/8]).
%%-ifndef(DO_ASSERT).
%%-define(DO_ASSERT, true).
@@ -66,13 +60,17 @@
%% where Location is {spill,M}.
%% {spill,M} denotes the Mth spilled node
--spec stackalloc(#cfg{}, [_], non_neg_integer(),
- comp_options(), module(), hipe_temp_map()) ->
+-type target_context() :: any().
+
+-spec stackalloc(#cfg{}, _, [_], non_neg_integer(),
+ comp_options(), module(), target_context(), hipe_temp_map()) ->
{hipe_spill_map(), non_neg_integer()}.
-stackalloc(CFG, _StackSlots, SpillIndex, _Options, Target, TempMap) ->
+stackalloc(CFG, Live, _StackSlots, SpillIndex, _Options, TargetMod,
+ TargetContext, TempMap) ->
+ Target = {TargetMod, TargetContext},
?report2("building IG~n", []),
- {IG, NumNodes} = build_ig(CFG, Target, TempMap),
+ {IG, NumNodes} = build_ig(CFG, Live, Target, TempMap),
{Cols, MaxColors} =
color_heuristic(IG, 0, NumNodes, NumNodes, NumNodes, Target, 1),
SortedCols = lists:sort(Cols),
@@ -121,7 +119,7 @@ color_heuristic(IG, Min, Max, Safe, MaxNodes, Target, MaxDepth) ->
end;
_ ->
%% This can be increased from 2, and by this the heuristic can be
- %% exited earlier, but the same can be achived by decreasing the
+ %% exited earlier, but the same can be achieved by decreasing the
%% recursion depth. This should not be decreased below 2.
case (Max - Min) < 2 of
true ->
@@ -167,10 +165,14 @@ remap_temp_map0(Cols, [_Y|Ys], SpillIndex) ->
%% Returns {Interference_graph, Number_Of_Nodes}
%%
-build_ig(CFG, Target, TempMap) ->
- try build_ig0(CFG, Target, TempMap)
- catch error:Rsn -> exit({regalloc, build_ig, Rsn})
- end.
+build_ig(CFG, Live, Target, TempMap) ->
+ TempMapping = map_spilled_temporaries(TempMap),
+ TempMappingTable = setup_ets(TempMapping),
+ NumSpilled = length(TempMapping),
+ IG = build_ig_bbs(labels(CFG, Target), CFG, Live, empty_ig(NumSpilled),
+ Target, TempMap, TempMappingTable),
+ ets:delete(TempMappingTable),
+ {normalize_ig(IG), NumSpilled}.
%% Creates an ETS table consisting of the keys given in List, with the values
%% being an integer which is the position of the key in List.
@@ -185,16 +187,6 @@ setup_ets0([X|Xs], Table, N) ->
ets:insert(Table, {X, N}),
setup_ets0(Xs, Table, N+1).
-build_ig0(CFG, Target, TempMap) ->
- Live = Target:analyze(CFG),
- TempMapping = map_spilled_temporaries(TempMap),
- TempMappingTable = setup_ets(TempMapping),
- NumSpilled = length(TempMapping),
- IG = build_ig_bbs(Target:labels(CFG), CFG, Live, empty_ig(NumSpilled),
- Target, TempMap, TempMappingTable),
- ets:delete(TempMappingTable),
- {normalize_ig(IG), NumSpilled}.
-
build_ig_bbs([], _CFG, _Live, IG, _Target, _TempMap, _TempMapping) ->
IG;
build_ig_bbs([L|Ls], CFG, Live, IG, Target, TempMap, TempMapping) ->
@@ -215,16 +207,26 @@ build_ig_bb([X|Xs], LiveOut, IG, Target, TempMap, TempMapping) ->
build_ig_bb(Xs, LiveOut, IG, Target, TempMap, TempMapping),
build_ig_instr(X, Live, NewIG, Target, TempMap, TempMapping).
-build_ig_instr(X, Live, IG, Target, TempMap, TempMapping) ->
+build_ig_instr(X, Live0, IG0, Target, TempMap, TempMapping) ->
{Def, Use} = def_use(X, Target, TempMap),
- ?report3("Live ~w\n~w : Def: ~w Use ~w\n",[Live, X, Def,Use]),
+ ?report3("Live ~w\n~w : Def: ~w Use ~w\n",[Live0, X, Def,Use]),
DefListMapped = list_map(Def, TempMapping, []),
UseListMapped = list_map(Use, TempMapping, []),
DefSetMapped = ordsets:from_list(DefListMapped),
UseSetMapped = ordsets:from_list(UseListMapped),
- NewIG = interference_arcs(DefListMapped, ordsets:to_list(Live), IG),
- NewLive = ordsets:union(UseSetMapped, ordsets:subtract(Live, DefSetMapped)),
- {NewLive, NewIG}.
+ {Live1, IG1} =
+ analyze_move(X, Live0, IG0, Target, DefSetMapped, UseSetMapped),
+ IG = interference_arcs(DefListMapped, ordsets:to_list(Live1), IG1),
+ Live = ordsets:union(UseSetMapped, ordsets:subtract(Live1, DefSetMapped)),
+ {Live, IG}.
+
+analyze_move(X, Live0, IG0, Target, DefSetMapped, UseSetMapped) ->
+ case {is_spill_move(X, Target), DefSetMapped, UseSetMapped} of
+ {true, [Dst], [Src]} ->
+ {ordsets:del_element(Src, Live0), add_move(Src, Dst, IG0)};
+ {_, _, _} ->
+ {Live0, IG0}
+ end.
%% Given a list of Keys and an ets-table returns a list of the elements
%% in Mapping corresponding to the Keys and appends Acc to this list.
@@ -274,15 +276,6 @@ i_arcs(X, [Y|Ys], IG) ->
%% throw an exception (the caller should retry with more stack slots)
color(IG, StackSlots, NumNodes, Target) ->
- try
- color_0(IG, StackSlots, NumNodes, Target)
- catch
- error:Rsn ->
- ?error_msg("Coloring failed with ~p~n", [Rsn]),
- ?EXIT(Rsn)
- end.
-
-color_0(IG, StackSlots, NumNodes, Target) ->
?report("simplification of IG~n", []),
K = ordsets:size(StackSlots),
Nodes = list_ig(IG),
@@ -385,7 +378,8 @@ select_colors([{X,colorable}|Xs], IG, Cols, PhysRegs) ->
select_color(X, IG, Cols, PhysRegs) ->
UsedColors = get_colors(neighbors(X, IG), Cols),
- Reg = select_unused_color(UsedColors, PhysRegs),
+ Preferences = get_colors(move_connected(X, IG), Cols),
+ Reg = select_unused_color(UsedColors, Preferences, PhysRegs),
{Reg, set_color(X, Reg, Cols)}.
%%%%%%%%%%%%%%%%%%%%
@@ -399,10 +393,14 @@ get_colors([X|Xs], Cols) ->
[R|get_colors(Xs, Cols)]
end.
-select_unused_color(UsedColors, PhysRegs) ->
+select_unused_color(UsedColors, Preferences, PhysRegs) ->
Summary = ordsets:from_list(UsedColors),
- AvailRegs = ordsets:to_list(ordsets:subtract(PhysRegs, Summary)),
- hd(AvailRegs).
+ case ordsets:subtract(ordsets:from_list(Preferences), Summary) of
+ [PreferredColor|_] -> PreferredColor;
+ _ ->
+ AvailRegs = ordsets:to_list(ordsets:subtract(PhysRegs, Summary)),
+ hd(AvailRegs)
+ end.
push_colored(X, Stk) ->
[{X, colorable} | Stk].
@@ -459,7 +457,11 @@ init_stackslots(NumSlots, Acc) ->
%%
%% Note: later on, we may wish to add 'move-related' support.
--record(ig_info, {neighbors = [] :: [_], degree = 0 :: non_neg_integer()}).
+-record(ig_info, {
+ neighbors = [] :: [_],
+ degree = 0 :: non_neg_integer(),
+ move_connected = [] :: [_]
+ }).
empty_ig(NumNodes) ->
hipe_vectors:new(NumNodes, #ig_info{}).
@@ -470,16 +472,29 @@ degree(Info) ->
neighbors(Info) ->
Info#ig_info.neighbors.
+move_connected(Info) ->
+ Info#ig_info.move_connected.
+
add_edge(X, X, IG) -> IG;
add_edge(X, Y, IG) ->
add_arc(X, Y, add_arc(Y, X, IG)).
+add_move(X, X, IG) -> IG;
+add_move(X, Y, IG) ->
+ add_move_arc(X, Y, add_move_arc(Y, X, IG)).
+
add_arc(X, Y, IG) ->
Info = hipe_vectors:get(IG, X),
Old = neighbors(Info),
New = Info#ig_info{neighbors = [Y|Old]},
hipe_vectors:set(IG,X,New).
+add_move_arc(X, Y, IG) ->
+ Info = hipe_vectors:get(IG, X),
+ Old = move_connected(Info),
+ New = Info#ig_info{move_connected = [Y|Old]},
+ hipe_vectors:set(IG,X,New).
+
normalize_ig(IG) ->
Size = hipe_vectors:size(IG),
normalize_ig(Size-1, IG).
@@ -489,7 +504,8 @@ normalize_ig(-1, IG) ->
normalize_ig(I, IG) ->
Info = hipe_vectors:get(IG, I),
N = ordsets:from_list(neighbors(Info)),
- NewInfo = Info#ig_info{neighbors = N, degree = length(N)},
+ M = ordsets:subtract(ordsets:from_list(move_connected(Info)), N),
+ NewInfo = Info#ig_info{neighbors = N, degree = length(N), move_connected = M},
NewIG = hipe_vectors:set(IG, I, NewInfo),
normalize_ig(I-1, NewIG).
@@ -497,6 +513,10 @@ neighbors(X, IG) ->
Info = hipe_vectors:get(IG, X),
Info#ig_info.neighbors.
+move_connected(X, IG) ->
+ Info = hipe_vectors:get(IG, X),
+ Info#ig_info.move_connected.
+
decrement_degree(X, IG) ->
Info = hipe_vectors:get(IG, X),
Degree = degree(Info),
@@ -540,18 +560,24 @@ is_visited(X, Vis) ->
%% *** INTERFACES TO OTHER MODULES ***
%%
-liveout(CFG, L, Target) ->
- ordsets:from_list(reg_names(Target:liveout(CFG, L), Target)).
+labels(CFG, {TgtMod,TgtCtx}) ->
+ TgtMod:labels(CFG, TgtCtx).
+
+liveout(CFG, L, Target={TgtMod,TgtCtx}) ->
+ ordsets:from_list(reg_names(TgtMod:liveout(CFG, L, TgtCtx), Target)).
-bb(CFG, L, Target) ->
- hipe_bb:code(Target:bb(CFG, L)).
+bb(CFG, L, {TgtMod,TgtCtx}) ->
+ hipe_bb:code(TgtMod:bb(CFG, L, TgtCtx)).
-def_use(X, Target, TempMap) ->
- Defines = [Y || Y <- reg_names(Target:defines(X), Target),
+def_use(X, Target={TgtMod,TgtCtx}, TempMap) ->
+ Defines = [Y || Y <- reg_names(TgtMod:defines(X,TgtCtx), Target),
hipe_temp_map:is_spilled(Y, TempMap)],
- Uses = [Z || Z <- reg_names(Target:uses(X), Target),
+ Uses = [Z || Z <- reg_names(TgtMod:uses(X,TgtCtx), Target),
hipe_temp_map:is_spilled(Z, TempMap)],
{Defines, Uses}.
-reg_names(Regs, Target) ->
- [Target:reg_nr(X) || X <- Regs].
+reg_names(Regs, {TgtMod,TgtCtx}) ->
+ [TgtMod:reg_nr(X,TgtCtx) || X <- Regs].
+
+is_spill_move(Instr, {TgtMod,TgtCtx}) ->
+ TgtMod:is_spill_move(Instr, TgtCtx).
diff --git a/lib/hipe/opt/hipe_spillmin_scan.erl b/lib/hipe/opt/hipe_spillmin_scan.erl
index 06b68e1934..484b05b790 100644
--- a/lib/hipe/opt/hipe_spillmin_scan.erl
+++ b/lib/hipe/opt/hipe_spillmin_scan.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ===========================================================================
%% Copyright (c) 2002 by Niklas Andersson, Andreas Lundin, and Erik Johansson.
@@ -60,7 +54,7 @@
-module(hipe_spillmin_scan).
--export([stackalloc/6]).
+-export([stackalloc/8]).
%%-define(DEBUG, 1).
-define(HIPE_INSTRUMENT_COMPILER, true).
@@ -70,6 +64,8 @@
-include("../main/hipe.hrl").
-include("../flow/cfg.hrl").
+-type target_context() :: any().
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% stackalloc(CFG, StackSlots, SpillIndex, Options, Target, TempMap)
@@ -85,15 +81,14 @@
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec stackalloc(#cfg{}, [_], non_neg_integer(),
- comp_options(), module(), hipe_temp_map()) ->
+-spec stackalloc(#cfg{}, _, [_], non_neg_integer(),
+ comp_options(), module(), target_context(), hipe_temp_map()) ->
{hipe_spill_map(), non_neg_integer()}.
-stackalloc(CFG, StackSlots, SpillIndex, Options, Target, TempMap) ->
+stackalloc(CFG, Liveness, StackSlots, SpillIndex, Options, TargetMod,
+ TargetContext, TempMap) ->
+ Target = {TargetMod, TargetContext},
?debug_msg("LinearScan: ~w\n", [erlang:statistics(runtime)]),
- %% Step 1: Calculate liveness (Call external implementation.)
- Liveness = liveness(CFG, Target),
- ?debug_msg("liveness (done)~w\n", [erlang:statistics(runtime)]),
USIntervals = calculate_intervals(CFG, Liveness, Options,
Target, TempMap),
%% ?debug_msg("intervals (done) ~w\n", [erlang:statistics(runtime)]),
@@ -124,8 +119,8 @@ stackalloc(CFG, StackSlots, SpillIndex, Options, Target, TempMap) ->
%% all other.
%%- - - - - - - - - - - - - - - - - - - - - - - -
calculate_intervals(CFG, Liveness, _Options, Target, TempMap) ->
- Interval = empty_interval(Target:number_of_temporaries(CFG)),
- Worklist = Target:reverse_postorder(CFG),
+ Interval = empty_interval(number_of_temporaries(CFG, Target)),
+ Worklist = reverse_postorder(CFG, Target),
intervals(Worklist, Interval, 1, CFG, Liveness, Target, TempMap).
%%- - - - - - - - - - - - - - - - - - - - - - - -
@@ -538,23 +533,26 @@ extend_interval(Pos, {Beginning, End})
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-liveness(CFG, Target) ->
- Target:analyze(CFG).
+bb(CFG, L, {TgtMod,TgtCtx}) ->
+ TgtMod:bb(CFG, L, TgtCtx).
+
+livein(Liveness, L, Target={TgtMod,TgtCtx}) ->
+ regnames(TgtMod:livein(Liveness, L, TgtCtx), Target).
-bb(CFG, L, Target) ->
- Target:bb(CFG, L).
+liveout(Liveness, L, Target={TgtMod,TgtCtx}) ->
+ regnames(TgtMod:liveout(Liveness, L, TgtCtx), Target).
-livein(Liveness, L, Target) ->
- regnames(Target:livein(Liveness, L), Target).
+number_of_temporaries(CFG, {TgtMod,TgtCtx}) ->
+ TgtMod:number_of_temporaries(CFG, TgtCtx).
-liveout(Liveness, L, Target) ->
- regnames(Target:liveout(Liveness, L), Target).
+uses(I, Target={TgtMod,TgtCtx}) ->
+ regnames(TgtMod:uses(I,TgtCtx), Target).
-uses(I, Target) ->
- regnames(Target:uses(I), Target).
+defines(I, Target={TgtMod,TgtCtx}) ->
+ regnames(TgtMod:defines(I,TgtCtx), Target).
-defines(I, Target) ->
- regnames(Target:defines(I), Target).
+regnames(Regs, {TgtMod,TgtCtx}) ->
+ [TgtMod:reg_nr(X,TgtCtx) || X <- Regs].
-regnames(Regs, Target) ->
- [Target:reg_nr(X) || X <- Regs].
+reverse_postorder(CFG, {TgtMod,TgtCtx}) ->
+ TgtMod:reverse_postorder(CFG, TgtCtx).
diff --git a/lib/hipe/opt/hipe_target_machine.erl b/lib/hipe/opt/hipe_target_machine.erl
index f64bb8b518..75993cb95e 100644
--- a/lib/hipe/opt/hipe_target_machine.erl
+++ b/lib/hipe/opt/hipe_target_machine.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/opt/hipe_ultra_mod2.erl b/lib/hipe/opt/hipe_ultra_mod2.erl
index f28c4e6939..cec9c56a1e 100644
--- a/lib/hipe/opt/hipe_ultra_mod2.erl
+++ b/lib/hipe/opt/hipe_ultra_mod2.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/opt/hipe_ultra_prio.erl b/lib/hipe/opt/hipe_ultra_prio.erl
index 423dc0d6bf..6dd240a33a 100644
--- a/lib/hipe/opt/hipe_ultra_prio.erl
+++ b/lib/hipe/opt/hipe_ultra_prio.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/ppc/Makefile b/lib/hipe/ppc/Makefile
index 1901dfa671..1ca1d51846 100644
--- a/lib/hipe/ppc/Makefile
+++ b/lib/hipe/ppc/Makefile
@@ -63,6 +63,7 @@ MODULES=hipe_ppc \
hipe_ppc_ra_postconditions \
hipe_ppc_ra_postconditions_fp \
hipe_ppc_registers \
+ hipe_ppc_subst \
hipe_rtl_to_ppc
HRL_FILES=hipe_ppc.hrl
diff --git a/lib/hipe/ppc/hipe_ppc.erl b/lib/hipe/ppc/hipe_ppc.erl
index 0fa96162f6..63ecd0a0b8 100644
--- a/lib/hipe/ppc/hipe_ppc.erl
+++ b/lib/hipe/ppc/hipe_ppc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,10 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-module(hipe_ppc).
-export([
@@ -106,6 +98,9 @@
pseudo_move_dst/1,
pseudo_move_src/1,
+ mk_pseudo_spill_move/3,
+ is_pseudo_spill_move/1,
+
mk_pseudo_tailcall/4,
pseudo_tailcall_func/1,
pseudo_tailcall_stkargs/1,
@@ -139,6 +134,9 @@
pseudo_fmove_dst/1,
pseudo_fmove_src/1,
+ mk_pseudo_spill_fmove/3,
+ is_pseudo_spill_fmove/1,
+
mk_defun/8,
defun_mfa/1,
defun_formals/1,
@@ -167,8 +165,10 @@ temp_is_precoloured(#ppc_temp{reg=Reg,type=Type}) ->
_ -> hipe_ppc_registers:is_precoloured_gpr(Reg)
end.
-mk_simm16(Value) -> #ppc_simm16{value=Value}.
-mk_uimm16(Value) -> #ppc_uimm16{value=Value}.
+mk_simm16(Value) when Value >= -(1 bsl 15), Value < (1 bsl 15) ->
+ #ppc_simm16{value=Value}.
+mk_uimm16(Value) when Value >= 0, Value < (1 bsl 16) ->
+ #ppc_uimm16{value=Value}.
mk_mfa(M, F, A) -> #ppc_mfa{m=M, f=F, a=A}.
@@ -240,7 +240,11 @@ mk_li(Dst, Value, Tail) -> % Dst can be R0
Value =< 16#7FFFFFFF ->
mk_li32(Dst, R0, Value, Tail);
true ->
- Highest = (Value bsr 48), % Value@highest
+ Highest = case (Value bsr 48) of % Value@highest
+ TopBitSet when TopBitSet >= (1 bsl 15) ->
+ TopBitSet - (1 bsl 16); % encoder needs it to be negative
+ FitsSimm16 -> FitsSimm16
+ end,
Higher = (Value bsr 32) band 16#FFFF, % Value@higher
High = (Value bsr 16) band 16#FFFF, % Value@h
Low = Value band 16#FFFF, % Value@l
@@ -414,6 +418,10 @@ is_pseudo_move(I) -> case I of #pseudo_move{} -> true; _ -> false end.
pseudo_move_dst(#pseudo_move{dst=Dst}) -> Dst.
pseudo_move_src(#pseudo_move{src=Src}) -> Src.
+mk_pseudo_spill_move(Dst, Temp, Src) ->
+ #pseudo_spill_move{dst=Dst, temp=Temp, src=Src}.
+is_pseudo_spill_move(I) -> is_record(I, pseudo_spill_move).
+
mk_pseudo_tailcall(FunC, Arity, StkArgs, Linkage) ->
#pseudo_tailcall{func=FunC, arity=Arity, stkargs=StkArgs, linkage=Linkage}.
pseudo_tailcall_func(#pseudo_tailcall{func=FunC}) -> FunC.
@@ -497,6 +505,10 @@ is_pseudo_fmove(I) -> case I of #pseudo_fmove{} -> true; _ -> false end.
pseudo_fmove_dst(#pseudo_fmove{dst=Dst}) -> Dst.
pseudo_fmove_src(#pseudo_fmove{src=Src}) -> Src.
+mk_pseudo_spill_fmove(Dst, Temp, Src) ->
+ #pseudo_spill_fmove{dst=Dst, temp=Temp, src=Src}.
+is_pseudo_spill_fmove(I) -> is_record(I, pseudo_spill_fmove).
+
mk_defun(MFA, Formals, IsClosure, IsLeaf, Code, Data, VarRange, LabelRange) ->
#defun{mfa=MFA, formals=Formals, code=Code, data=Data,
isclosure=IsClosure, isleaf=IsLeaf,
diff --git a/lib/hipe/ppc/hipe_ppc.hrl b/lib/hipe/ppc/hipe_ppc.hrl
index aa8ff4a3f7..3eef8be487 100644
--- a/lib/hipe/ppc/hipe_ppc.hrl
+++ b/lib/hipe/ppc/hipe_ppc.hrl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,10 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
-%%%
-
%%%--------------------------------------------------------------------
%%% Basic Values:
@@ -95,6 +87,7 @@
-record(pseudo_call_prepare, {nrstkargs}).
-record(pseudo_li, {dst, imm}).
-record(pseudo_move, {dst, src}).
+-record(pseudo_spill_move, {dst, temp, src}).
-record(pseudo_tailcall, {func, arity, stkargs, linkage}).
-record(pseudo_tailcall_prepare, {}).
-record(store, {stop, src, disp, base}). % non-indexed, non-update form
@@ -107,6 +100,7 @@
-record(fp_binary, {fp_binop, dst, src1, src2}).
-record(fp_unary, {fp_unop, dst, src}).
-record(pseudo_fmove, {dst, src}).
+-record(pseudo_spill_fmove, {dst, temp, src}).
%%% Function definitions.
diff --git a/lib/hipe/ppc/hipe_ppc_assemble.erl b/lib/hipe/ppc/hipe_ppc_assemble.erl
index ff9da01b11..b0f57e5582 100644
--- a/lib/hipe/ppc/hipe_ppc_assemble.erl
+++ b/lib/hipe/ppc/hipe_ppc_assemble.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,10 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-module(hipe_ppc_assemble).
-export([assemble/4]).
@@ -40,7 +32,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
|| {MFA, Defun} <- CompiledCode],
%%
{ConstAlign,ConstSize,ConstMap,RefsFromConsts} =
- hipe_pack_constants:pack_constants(Code, hipe_rtl_arch:word_size()),
+ hipe_pack_constants:pack_constants(Code),
%%
{CodeSize,CodeBinary,AccRefs,LabelMap,ExportMap} =
encode(translate(Code, ConstMap), Options),
@@ -175,7 +167,8 @@ do_slwi_opnds(Dst, Src1, {uimm,N}) when is_integer(N), 0 =< N, N < 32 ->
{Dst, Src1, {sh,N}, {mb,0}, {me,31-N}}.
do_srwi_opnds(Dst, Src1, {uimm,N}) when is_integer(N), 0 =< N, N < 32 ->
- {Dst, Src1, {sh,32-N}, {mb,N}, {me,31}}.
+ %% SH should be 0 (not 32) when N is 0
+ {Dst, Src1, {sh,(32-N) band 31}, {mb,N}, {me,31}}.
do_srawi_src2({uimm,N}) when is_integer(N), 0 =< N, N < 32 -> {sh,N}.
@@ -184,7 +177,8 @@ do_sldi_opnds(Dst, Src1, {uimm,N}) when is_integer(N), 0 =< N, N < 64 ->
{Dst, Src1, {sh6,N}, {me6,63-N}}.
do_srdi_opnds(Dst, Src1, {uimm,N}) when is_integer(N), 0 =< N, N < 64 ->
- {Dst, Src1, {sh6,64-N}, {mb6,N}}.
+ %% SH should be 0 (not 64) when N is 0
+ {Dst, Src1, {sh6,(64-N) band 63}, {mb6,N}}.
do_sradi_src2({uimm,N}) when is_integer(N), 0 =< N, N < 64 -> {sh6,N}.
@@ -246,6 +240,7 @@ do_load(I) ->
case LdOp of
'ld' -> do_disp_ds(Disp);
'ldu' -> do_disp_ds(Disp);
+ 'lwa' -> do_disp_ds(Disp);
_ -> do_disp(Disp)
end,
NewBase = do_reg(Base),
diff --git a/lib/hipe/ppc/hipe_ppc_cfg.erl b/lib/hipe/ppc/hipe_ppc_cfg.erl
index 34d4bf54c5..d44d38f38d 100644
--- a/lib/hipe/ppc/hipe_ppc_cfg.erl
+++ b/lib/hipe/ppc/hipe_ppc_cfg.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,25 +11,24 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_cfg).
-export([init/1,
labels/1, start_label/1,
succ/2,
+ map_bbs/2, fold_bbs/3,
bb/2, bb_add/3]).
-export([postorder/1]).
-export([linearise/1, params/1, reverse_postorder/1]).
--export([arity/1]).
-%%%-export([redirect_jmp/3, arity/1]).
+-export([redirect_jmp/3, arity/1]).
+-export([branch_preds/1]).
%%% these tell cfg.inc what to define (ugly as hell)
-define(BREADTH_ORDER,true).
-define(PARAMS_NEEDED,true).
-define(START_LABEL_UPDATE_NEEDED,true).
+-define(MAP_FOLD_NEEDED,true).
-include("hipe_ppc.hrl").
-include("../flow/cfg.hrl").
@@ -80,11 +75,30 @@ branch_successors(Branch) ->
#pseudo_tailcall{} -> []
end.
+branch_preds(Branch) ->
+ case Branch of
+ #bctr{labels=Labels} ->
+ Prob = 1.0/length(Labels),
+ [{L, Prob} || L <- Labels];
+ #pseudo_bc{true_label=TrueLab,false_label=FalseLab,pred=Pred} ->
+ [{FalseLab, 1.0-Pred}, {TrueLab, Pred}];
+ #pseudo_call{contlab=ContLab, sdesc=#ppc_sdesc{exnlab=[]}} ->
+ %% A function can still cause an exception, even if we won't catch it
+ [{ContLab, 1.0-hipe_bb_weights:call_exn_pred()}];
+ #pseudo_call{contlab=ContLab, sdesc=#ppc_sdesc{exnlab=ExnLab}} ->
+ CallExnPred = hipe_bb_weights:call_exn_pred(),
+ [{ContLab, 1.0-CallExnPred}, {ExnLab, CallExnPred}];
+ _ ->
+ case branch_successors(Branch) of
+ [] -> [];
+ [Single] -> [{Single, 1.0}]
+ end
+ end.
+
-ifdef(REMOVE_TRIVIAL_BBS_NEEDED).
fails_to(_Instr) -> [].
-endif.
--ifdef(notdef).
redirect_jmp(I, Old, New) ->
case I of
#b_label{label=Label} ->
@@ -98,10 +112,16 @@ redirect_jmp(I, Old, New) ->
if Old =:= FalseLab -> I1#pseudo_bc{false_label=New};
true -> I1
end;
- %% handle pseudo_call too?
- _ -> I
+ #pseudo_call{sdesc=SDesc0, contlab=ContLab0} ->
+ SDesc = case SDesc0 of
+ #ppc_sdesc{exnlab=Old} -> SDesc0#ppc_sdesc{exnlab=New};
+ #ppc_sdesc{exnlab=_} -> SDesc0
+ end,
+ ContLab = if Old =:= ContLab0 -> New;
+ true -> ContLab0
+ end,
+ I#pseudo_call{sdesc=SDesc, contlab=ContLab}
end.
--endif.
mk_goto(Label) ->
hipe_ppc:mk_b_label(Label).
diff --git a/lib/hipe/ppc/hipe_ppc_defuse.erl b/lib/hipe/ppc/hipe_ppc_defuse.erl
index 77b84dc574..d8a864f7d5 100644
--- a/lib/hipe/ppc/hipe_ppc_defuse.erl
+++ b/lib/hipe/ppc/hipe_ppc_defuse.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,13 +11,11 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_defuse).
-export([insn_def_all/1, insn_use_all/1]).
-export([insn_def_gpr/1, insn_use_gpr/1]).
+-export([insn_defs_all_gpr/1, insn_defs_all_fpr/1]).
-export([insn_def_fpr/1, insn_use_fpr/1]).
-include("hipe_ppc.hrl").
@@ -47,11 +41,15 @@ insn_def_gpr(I) ->
#pseudo_call{} -> call_clobbered_gpr();
#pseudo_li{dst=Dst} -> [Dst];
#pseudo_move{dst=Dst} -> [Dst];
+ #pseudo_spill_move{dst=Dst,temp=Temp} -> [Dst, Temp];
#pseudo_tailcall_prepare{} -> tailcall_clobbered_gpr();
#unary{dst=Dst} -> [Dst];
_ -> []
end.
+insn_defs_all_gpr(#pseudo_call{}) -> true;
+insn_defs_all_gpr(_) -> false.
+
call_clobbered_gpr() ->
[hipe_ppc:mk_temp(R, T)
|| {R,T} <- hipe_ppc_registers:call_clobbered() ++ all_fp_pseudos()].
@@ -74,6 +72,7 @@ insn_use_gpr(I) ->
#mtspr{src=Src} -> [Src];
#pseudo_call{sdesc=#ppc_sdesc{arity=Arity}} -> arity_use_gpr(Arity);
#pseudo_move{src=Src} -> [Src];
+ #pseudo_spill_move{src=Src} -> [Src];
#pseudo_tailcall{arity=Arity,stkargs=StkArgs} ->
addsrcs(StkArgs, addtemps(tailcall_clobbered_gpr(), arity_use_gpr(Arity)));
#store{src=Src,base=Base} -> addtemp(Src, [Base]);
@@ -113,9 +112,13 @@ insn_def_fpr(I) ->
#fp_binary{dst=Dst} -> [Dst];
#fp_unary{dst=Dst} -> [Dst];
#pseudo_fmove{dst=Dst} -> [Dst];
+ #pseudo_spill_fmove{dst=Dst,temp=Temp} -> [Dst, Temp];
_ -> []
end.
+insn_defs_all_fpr(#pseudo_call{}) -> true;
+insn_defs_all_fpr(_) -> false.
+
call_clobbered_fpr() ->
[hipe_ppc:mk_temp(R, 'double') || R <- hipe_ppc_registers:allocatable_fpr()].
@@ -126,6 +129,7 @@ insn_use_fpr(I) ->
#fp_binary{src1=Src1,src2=Src2} -> addtemp(Src1, [Src2]);
#fp_unary{src=Src} -> [Src];
#pseudo_fmove{src=Src} -> [Src];
+ #pseudo_spill_fmove{src=Src} -> [Src];
_ -> []
end.
diff --git a/lib/hipe/ppc/hipe_ppc_encode.erl b/lib/hipe/ppc/hipe_ppc_encode.erl
index 793f6ccc02..1d0ce4f510 100644
--- a/lib/hipe/ppc/hipe_ppc_encode.erl
+++ b/lib/hipe/ppc/hipe_ppc_encode.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 4 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Encode symbolic PowerPC instructions to binary form.
%%% Copyright (C) 2003-2005, 2009 Mikael Pettersson
diff --git a/lib/hipe/ppc/hipe_ppc_finalise.erl b/lib/hipe/ppc/hipe_ppc_finalise.erl
index 8bb9520f89..8db2bf48a5 100644
--- a/lib/hipe/ppc/hipe_ppc_finalise.erl
+++ b/lib/hipe/ppc/hipe_ppc_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_finalise).
-export([finalise/1]).
diff --git a/lib/hipe/ppc/hipe_ppc_frame.erl b/lib/hipe/ppc/hipe_ppc_frame.erl
index ff0450270f..b88b75a5bd 100644
--- a/lib/hipe/ppc/hipe_ppc_frame.erl
+++ b/lib/hipe/ppc/hipe_ppc_frame.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,25 +11,20 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_frame).
-export([frame/1]).
-include("hipe_ppc.hrl").
-include("../rtl/hipe_literals.hrl").
-frame(Defun) ->
- Formals = fix_formals(hipe_ppc:defun_formals(Defun)),
- Temps0 = all_temps(hipe_ppc:defun_code(Defun), Formals),
- MinFrame = defun_minframe(Defun),
+frame(CFG) ->
+ Formals = fix_formals(hipe_ppc_cfg:params(CFG)),
+ Temps0 = all_temps(CFG, Formals),
+ MinFrame = defun_minframe(CFG),
Temps = ensure_minframe(MinFrame, Temps0),
- ClobbersLR = clobbers_lr(hipe_ppc:defun_code(Defun)),
- CFG0 = hipe_ppc_cfg:init(Defun),
- Liveness = hipe_ppc_liveness_all:analyse(CFG0),
- CFG1 = do_body(CFG0, Liveness, Formals, Temps, ClobbersLR),
- hipe_ppc_cfg:linearise(CFG1).
+ ClobbersLR = clobbers_lr(CFG),
+ Liveness = hipe_ppc_liveness_all:analyse(CFG),
+ do_body(CFG, Liveness, Formals, Temps, ClobbersLR).
fix_formals(Formals) ->
fix_formals(hipe_ppc_registers:nr_args(), Formals).
@@ -44,27 +35,16 @@ fix_formals(_, []) -> [].
do_body(CFG0, Liveness, Formals, Temps, ClobbersLR) ->
Context = mk_context(Liveness, Formals, Temps, ClobbersLR),
- CFG1 = do_blocks(CFG0, Context),
+ CFG1 = hipe_ppc_cfg:map_bbs(
+ fun(Lbl, BB) -> do_block(Lbl, BB, Context) end, CFG0),
do_prologue(CFG1, Context).
-do_blocks(CFG, Context) ->
- Labels = hipe_ppc_cfg:labels(CFG),
- do_blocks(Labels, CFG, Context).
-
-do_blocks([Label|Labels], CFG, Context) ->
+do_block(Label, Block, Context) ->
Liveness = context_liveness(Context),
LiveOut = hipe_ppc_liveness_all:liveout(Liveness, Label),
- Block = hipe_ppc_cfg:bb(CFG, Label),
Code = hipe_bb:code(Block),
- NewCode = do_block(Code, LiveOut, Context),
- NewBlock = hipe_bb:code_update(Block, NewCode),
- NewCFG = hipe_ppc_cfg:bb_add(CFG, Label, NewBlock),
- do_blocks(Labels, NewCFG, Context);
-do_blocks([], CFG, _) ->
- CFG.
-
-do_block(Insns, LiveOut, Context) ->
- do_block(Insns, LiveOut, Context, context_framesize(Context), []).
+ NewCode = do_block(Code, LiveOut, Context, context_framesize(Context), []),
+ hipe_bb:code_update(Block, NewCode).
do_block([I|Insns], LiveOut, Context, FPoff0, RevCode) ->
{NewIs, FPoff1} = do_insn(I, LiveOut, Context, FPoff0),
@@ -86,10 +66,14 @@ do_insn(I, LiveOut, Context, FPoff) ->
do_pseudo_call_prepare(I, FPoff);
#pseudo_move{} ->
{do_pseudo_move(I, Context, FPoff), FPoff};
+ #pseudo_spill_move{} ->
+ {do_pseudo_spill_move(I, Context, FPoff), FPoff};
#pseudo_tailcall{} ->
{do_pseudo_tailcall(I, Context), context_framesize(Context)};
#pseudo_fmove{} ->
{do_pseudo_fmove(I, Context, FPoff), FPoff};
+ #pseudo_spill_fmove{} ->
+ {do_pseudo_spill_fmove(I, Context, FPoff), FPoff};
_ ->
{[I], FPoff}
end.
@@ -111,7 +95,26 @@ do_pseudo_move(I, Context, FPoff) ->
Offset = pseudo_offset(Src, FPoff, Context),
mk_load(hipe_ppc:ldop_word(), Dst, Offset, mk_sp(), []);
_ ->
- [hipe_ppc:mk_alu('or', Dst, Src, Src)]
+ case hipe_ppc:temp_reg(Dst) =:= hipe_ppc:temp_reg(Src) of
+ true -> [];
+ false -> [hipe_ppc:mk_alu('or', Dst, Src, Src)]
+ end
+ end
+ end.
+
+do_pseudo_spill_move(I, Context, FPoff) ->
+ #pseudo_spill_move{dst=Dst,temp=Temp,src=Src} = I,
+ case temp_is_pseudo(Src) andalso temp_is_pseudo(Dst) of
+ false -> % Register allocator changed its mind, turn back to move
+ do_pseudo_move(hipe_ppc:mk_pseudo_move(Dst, Src), Context, FPoff);
+ true ->
+ SrcOffset = pseudo_offset(Src, FPoff, Context),
+ DstOffset = pseudo_offset(Dst, FPoff, Context),
+ case SrcOffset =:= DstOffset of
+ true -> []; % omit move-to-self
+ false ->
+ mk_load(hipe_ppc:ldop_word(), Temp, SrcOffset, mk_sp(),
+ mk_store(hipe_ppc:stop_word(), Temp, DstOffset, mk_sp(), []))
end
end.
@@ -132,6 +135,22 @@ do_pseudo_fmove(I, Context, FPoff) ->
end
end.
+do_pseudo_spill_fmove(I, Context, FPoff) ->
+ #pseudo_spill_fmove{dst=Dst,temp=Temp,src=Src} = I,
+ case temp_is_pseudo(Src) andalso temp_is_pseudo(Dst) of
+ false -> % Register allocator changed its mind, turn back to move
+ do_pseudo_fmove(hipe_ppc:mk_pseudo_fmove(Dst, Src), Context, FPoff);
+ true ->
+ SrcOffset = pseudo_offset(Src, FPoff, Context),
+ DstOffset = pseudo_offset(Dst, FPoff, Context),
+ case SrcOffset =:= DstOffset of
+ true -> []; % omit move-to-self
+ false ->
+ hipe_ppc:mk_fload(Temp, SrcOffset, mk_sp(), 0)
+ ++ hipe_ppc:mk_fstore(Temp, DstOffset, mk_sp(), 0)
+ end
+ end.
+
pseudo_offset(Temp, FPoff, Context) ->
FPoff + context_offset(Context, Temp).
@@ -573,29 +592,41 @@ temp_is_pseudo(Temp) ->
%%% Detect if a Defun's body clobbers LR.
%%%
-clobbers_lr([I|Insns]) ->
- case I of
- #pseudo_call{} -> true;
- %% mtspr to lr cannot occur yet
- _ -> clobbers_lr(Insns)
- end;
-clobbers_lr([]) -> false.
+clobbers_lr(CFG) ->
+ any_insn(fun(#pseudo_call{}) -> true;
+ (_) -> false
+ end, CFG).
+
+any_insn(Pred, CFG) ->
+ %% Abuse fold to do an efficient "any"-operation using nonlocal control flow
+ FoundSatisfying = make_ref(),
+ try fold_insns(fun (I, _) ->
+ case Pred(I) of
+ true -> throw(FoundSatisfying);
+ false -> false
+ end
+ end, false, CFG)
+ of _ -> false
+ catch FoundSatisfying -> true
+ end.
%%%
%%% Build the set of all temps used in a Defun's body.
%%%
-all_temps(Code, Formals) ->
- S0 = find_temps(Code, tset_empty()),
+all_temps(CFG, Formals) ->
+ S0 = fold_insns(fun find_temps/2, tset_empty(), CFG),
S1 = tset_del_list(S0, Formals),
tset_filter(S1, fun(T) -> temp_is_pseudo(T) end).
-find_temps([I|Insns], S0) ->
+find_temps(I, S0) ->
S1 = tset_add_list(S0, hipe_ppc_defuse:insn_def_all(I)),
- S2 = tset_add_list(S1, hipe_ppc_defuse:insn_use_all(I)),
- find_temps(Insns, S2);
-find_temps([], S) ->
- S.
+ tset_add_list(S1, hipe_ppc_defuse:insn_use_all(I)).
+
+fold_insns(Fun, InitAcc, CFG) ->
+ hipe_ppc_cfg:fold_bbs(
+ fun(_, BB, Acc0) -> lists:foldl(Fun, Acc0, hipe_bb:code(BB)) end,
+ InitAcc, CFG).
tset_empty() ->
gb_sets:new().
@@ -624,16 +655,11 @@ tset_to_list(S) ->
%%% in the middle of a tailcall.
%%%
-defun_minframe(Defun) ->
- MaxTailArity = body_mta(hipe_ppc:defun_code(Defun), 0),
- MyArity = length(fix_formals(hipe_ppc:defun_formals(Defun))),
+defun_minframe(CFG) ->
+ MaxTailArity = fold_insns(fun insn_mta/2, 0, CFG),
+ MyArity = length(fix_formals(hipe_ppc_cfg:params(CFG))),
erlang:max(MaxTailArity - MyArity, 0).
-body_mta([I|Code], MTA) ->
- body_mta(Code, insn_mta(I, MTA));
-body_mta([], MTA) ->
- MTA.
-
insn_mta(I, MTA) ->
case I of
#pseudo_tailcall{arity=Arity} ->
diff --git a/lib/hipe/ppc/hipe_ppc_liveness_all.erl b/lib/hipe/ppc/hipe_ppc_liveness_all.erl
index cab7605967..42138eea08 100644
--- a/lib/hipe/ppc/hipe_ppc_liveness_all.erl
+++ b/lib/hipe/ppc/hipe_ppc_liveness_all.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_liveness_all).
-export([analyse/1]).
diff --git a/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl b/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl
index 1437e27508..eeca0e523e 100644
--- a/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl
+++ b/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_liveness_fpr).
-export([analyse/1]).
diff --git a/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl b/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl
index 074fada918..ab9d28266c 100644
--- a/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl
+++ b/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_liveness_gpr).
-export([analyse/1]).
diff --git a/lib/hipe/ppc/hipe_ppc_main.erl b/lib/hipe/ppc/hipe_ppc_main.erl
index fd5cc2befb..a094aa65f7 100644
--- a/lib/hipe/ppc/hipe_ppc_main.erl
+++ b/lib/hipe/ppc/hipe_ppc_main.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,17 +11,16 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_main).
-export([rtl_to_ppc/3]).
rtl_to_ppc(MFA, RTL, Options) ->
PPC1 = hipe_rtl_to_ppc:translate(RTL),
- PPC2 = hipe_ppc_ra:ra(PPC1, Options),
- PPC3 = hipe_ppc_frame:frame(PPC2),
+ PPC1CFG = hipe_ppc_cfg:init(PPC1),
+ PPC2CFG = hipe_ppc_ra:ra(PPC1CFG, Options),
+ PPC3CFG = hipe_ppc_frame:frame(PPC2CFG),
+ PPC3 = hipe_ppc_cfg:linearise(PPC3CFG),
PPC4 = hipe_ppc_finalise:finalise(PPC3),
ppc_pp(PPC4, MFA, Options),
{native, powerpc, {unprofiled, PPC4}}.
diff --git a/lib/hipe/ppc/hipe_ppc_pp.erl b/lib/hipe/ppc/hipe_ppc_pp.erl
index e69e6b64a2..4ee91f771e 100644
--- a/lib/hipe/ppc/hipe_ppc_pp.erl
+++ b/lib/hipe/ppc/hipe_ppc_pp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_pp).
-export([pp/1, pp/2, pp_insn/1]).
@@ -170,6 +163,12 @@ pp_insn(Dev, I, Pre) ->
io:format(Dev, ", ", []),
pp_temp(Dev, Base2),
io:format(Dev, "\n", []);
+ #unary{unop={UnOp,I1,I2,I3}, dst=Dst, src=Src} ->
+ io:format(Dev, "\t~s ", [UnOp]),
+ pp_temp(Dev, Dst),
+ io:format(Dev, ", ", []),
+ pp_temp(Dev, Src),
+ io:format(Dev, ", ~s, ~s, ~s\n", [to_hex(I1),to_hex(I2),to_hex(I3)]);
#unary{unop=UnOp, dst=Dst, src=Src} ->
io:format(Dev, "\t~w ", [unop_name(UnOp)]),
pp_temp(Dev, Dst),
diff --git a/lib/hipe/ppc/hipe_ppc_ra.erl b/lib/hipe/ppc/hipe_ppc_ra.erl
index 87c776f5d1..b8daf72cef 100644
--- a/lib/hipe/ppc/hipe_ppc_ra.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,43 +11,44 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_ra).
-export([ra/2]).
-ra(Defun0, Options) ->
- %% hipe_ppc_pp:pp(Defun0),
- {Defun1, Coloring_fp, SpillIndex}
+ra(CFG0, Options) ->
+ %% hipe_ppc_pp:pp(hipe_ppc_cfg:linearise(CFG0)),
+ {CFG1, _FPLiveness1, Coloring_fp, SpillIndex}
= case proplists:get_bool(inline_fp, Options) of
true ->
- hipe_regalloc_loop:ra_fp(Defun0, Options,
+ FPLiveness0 = hipe_ppc_specific_fp:analyze(CFG0, no_context),
+ hipe_regalloc_loop:ra_fp(CFG0, FPLiveness0, Options,
hipe_coalescing_regalloc,
- hipe_ppc_specific_fp);
+ hipe_ppc_specific_fp, no_context);
false ->
- {Defun0,[],0}
+ {CFG0,undefined,[],0}
end,
- %% hipe_ppc_pp:pp(Defun1),
- {Defun2, Coloring}
+ %% hipe_ppc_pp:pp(hipe_ppc_cfg:linearise(CFG1)),
+ GPLiveness1 = hipe_ppc_specific:analyze(CFG1, no_context),
+ {CFG2, _GPLiveness2, Coloring}
= case proplists:get_value(regalloc, Options, coalescing) of
coalescing ->
- ra(Defun1, SpillIndex, Options, hipe_coalescing_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options, hipe_coalescing_regalloc);
optimistic ->
- ra(Defun1, SpillIndex, Options, hipe_optimistic_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options, hipe_optimistic_regalloc);
graph_color ->
- ra(Defun1, SpillIndex, Options, hipe_graph_coloring_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options,
+ hipe_graph_coloring_regalloc);
linear_scan ->
- hipe_ppc_ra_ls:ra(Defun1, SpillIndex, Options);
+ hipe_ppc_ra_ls:ra(CFG1, GPLiveness1, SpillIndex, Options);
naive ->
- hipe_ppc_ra_naive:ra(Defun1, Coloring_fp, Options);
+ hipe_ppc_ra_naive:ra(CFG1, GPLiveness1, Coloring_fp, Options);
_ ->
exit({unknown_regalloc_compiler_option,
proplists:get_value(regalloc,Options)})
end,
- %% hipe_ppc_pp:pp(Defun2),
- hipe_ppc_ra_finalise:finalise(Defun2, Coloring, Coloring_fp).
+ %% hipe_ppc_pp:pp(hipe_ppc_cfg:linearise(CFG2)),
+ hipe_ppc_ra_finalise:finalise(CFG2, Coloring, Coloring_fp).
-ra(Defun, SpillIndex, Options, RegAllocMod) ->
- hipe_regalloc_loop:ra(Defun, SpillIndex, Options, RegAllocMod, hipe_ppc_specific).
+ra(CFG, Liveness, SpillIndex, Options, RegAllocMod) ->
+ hipe_regalloc_loop:ra(CFG, Liveness, SpillIndex, Options, RegAllocMod,
+ hipe_ppc_specific, no_context).
diff --git a/lib/hipe/ppc/hipe_ppc_ra_finalise.erl b/lib/hipe/ppc/hipe_ppc_ra_finalise.erl
index ea163221c2..bca504d754 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_finalise.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,21 +11,19 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_ra_finalise).
-export([finalise/3]).
-include("hipe_ppc.hrl").
-finalise(Defun, TempMap, FPMap0) ->
- Code = hipe_ppc:defun_code(Defun),
- {_, SpillLimit} = hipe_ppc:defun_var_range(Defun),
+finalise(CFG, TempMap, FPMap0) ->
+ {_, SpillLimit} = hipe_gensym:var_range(ppc),
Map = mk_ra_map(TempMap, SpillLimit),
FPMap1 = mk_ra_map_fp(FPMap0, SpillLimit),
- NewCode = ra_code(Code, Map, FPMap1, []),
- Defun#defun{code=NewCode}.
+ hipe_ppc_cfg:map_bbs(fun(_Lbl, BB) -> ra_bb(BB, Map, FPMap1) end, CFG).
+
+ra_bb(BB, Map, FpMap) ->
+ hipe_bb:code_update(BB, ra_code(hipe_bb:code(BB), Map, FpMap, [])).
ra_code([I|Insns], Map, FPMap, Accum) ->
ra_code(Insns, Map, FPMap, [ra_insn(I, Map, FPMap) | Accum]);
@@ -47,6 +41,7 @@ ra_insn(I, Map, FPMap) ->
#mtspr{} -> ra_mtspr(I, Map);
#pseudo_li{} -> ra_pseudo_li(I, Map);
#pseudo_move{} -> ra_pseudo_move(I, Map);
+ #pseudo_spill_move{} -> ra_pseudo_spill_move(I, Map);
#pseudo_tailcall{} -> ra_pseudo_tailcall(I, Map);
#store{} -> ra_store(I, Map);
#storex{} -> ra_storex(I, Map);
@@ -58,6 +53,7 @@ ra_insn(I, Map, FPMap) ->
#fp_binary{} -> ra_fp_binary(I, FPMap);
#fp_unary{} -> ra_fp_unary(I, FPMap);
#pseudo_fmove{} -> ra_pseudo_fmove(I, FPMap);
+ #pseudo_spill_fmove{} -> ra_pseudo_spill_fmove(I, FPMap);
_ -> I
end.
@@ -104,6 +100,12 @@ ra_pseudo_move(I=#pseudo_move{dst=Dst,src=Src}, Map) ->
NewSrc = ra_temp(Src, Map),
I#pseudo_move{dst=NewDst,src=NewSrc}.
+ra_pseudo_spill_move(I=#pseudo_spill_move{dst=Dst,temp=Temp,src=Src}, Map) ->
+ NewDst = ra_temp(Dst, Map),
+ NewTemp = ra_temp(Temp, Map),
+ NewSrc = ra_temp(Src, Map),
+ I#pseudo_spill_move{dst=NewDst,temp=NewTemp,src=NewSrc}.
+
ra_pseudo_tailcall(I=#pseudo_tailcall{stkargs=StkArgs}, Map) ->
NewStkArgs = ra_args(StkArgs, Map),
I#pseudo_tailcall{stkargs=NewStkArgs}.
@@ -162,6 +164,13 @@ ra_pseudo_fmove(I=#pseudo_fmove{dst=Dst,src=Src}, FPMap) ->
NewSrc = ra_temp_fp(Src, FPMap),
I#pseudo_fmove{dst=NewDst,src=NewSrc}.
+ra_pseudo_spill_fmove(I=#pseudo_spill_fmove{dst=Dst,temp=Temp,src=Src},
+ FPMap) ->
+ NewDst = ra_temp_fp(Dst, FPMap),
+ NewTemp = ra_temp_fp(Temp, FPMap),
+ NewSrc = ra_temp_fp(Src, FPMap),
+ I#pseudo_spill_fmove{dst=NewDst,temp=NewTemp,src=NewSrc}.
+
ra_args([Arg|Args], Map) ->
[ra_temp_or_imm(Arg, Map) | ra_args(Args, Map)];
ra_args([], _) ->
diff --git a/lib/hipe/ppc/hipe_ppc_ra_ls.erl b/lib/hipe/ppc/hipe_ppc_ra_ls.erl
index 6e8304467e..d8b2087919 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_ls.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_ls.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,43 +11,39 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Linear Scan register allocator for PowerPC
-module(hipe_ppc_ra_ls).
--export([ra/3]).
+-export([ra/4]).
-ra(Defun, SpillIndex, Options) ->
- NewDefun = Defun, %% hipe_${ARCH}_ra_rename:rename(Defun,Options),
- CFG = hipe_ppc_cfg:init(NewDefun),
- SpillLimit = hipe_ppc_specific:number_of_temporaries(CFG),
- alloc(NewDefun, SpillIndex, SpillLimit, Options).
+ra(CFG, Liveness, SpillIndex, Options) ->
+ SpillLimit = hipe_ppc_specific:number_of_temporaries(CFG, no_context),
+ alloc(CFG, Liveness, SpillIndex, SpillLimit, Options).
-alloc(Defun, SpillIndex, SpillLimit, Options) ->
- CFG = hipe_ppc_cfg:init(Defun),
+alloc(CFG, Liveness, SpillIndex, SpillLimit, Options) ->
{Coloring, _NewSpillIndex} =
regalloc(
- CFG,
+ CFG, Liveness,
hipe_ppc_registers:allocatable_gpr()--
[hipe_ppc_registers:temp3(),
hipe_ppc_registers:temp2(),
hipe_ppc_registers:temp1()],
[hipe_ppc_cfg:start_label(CFG)],
SpillIndex, SpillLimit, Options,
- hipe_ppc_specific),
- {NewDefun, _DidSpill} =
+ hipe_ppc_specific, no_context),
+ {NewCFG, _DidSpill} =
hipe_ppc_ra_postconditions:check_and_rewrite(
- Defun, Coloring, 'linearscan'),
- TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_ppc_specific),
+ CFG, Coloring, 'linearscan'),
+ TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_ppc_specific, no_context),
{TempMap2,_NewSpillIndex2} =
- hipe_spillmin:stackalloc(CFG, [], SpillIndex, Options,
- hipe_ppc_specific, TempMap),
+ hipe_spillmin:stackalloc(CFG, Liveness, [], SpillIndex, Options,
+ hipe_ppc_specific, no_context, TempMap),
Coloring2 =
hipe_spillmin:mapmerge(hipe_temp_map:to_substlist(TempMap), TempMap2),
- {NewDefun, Coloring2}.
+ {NewCFG, Liveness, Coloring2}.
-regalloc(CFG, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options, Target) ->
- hipe_ls_regalloc:regalloc(
- CFG, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options, Target).
+regalloc(CFG, Liveness, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options,
+ TgtMod, TgtCtx) ->
+ hipe_ls_regalloc:regalloc(CFG, Liveness, PhysRegs, Entrypoints, SpillIndex,
+ DontSpill, Options, TgtMod, TgtCtx).
diff --git a/lib/hipe/ppc/hipe_ppc_ra_naive.erl b/lib/hipe/ppc/hipe_ppc_ra_naive.erl
index 24995be252..dee89f66f9 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_naive.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_naive.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,16 +11,13 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_ra_naive).
--export([ra/3]).
+-export([ra/4]).
-include("hipe_ppc.hrl").
-ra(Defun, _Coloring_fp, _Options) -> % -> {Defun, Coloring}
- {NewDefun,_DidSpill} =
- hipe_ppc_ra_postconditions:check_and_rewrite2(Defun, [], 'naive'),
- {NewDefun, []}.
+ra(CFG, Liveness, _Coloring_fp, _Options) -> % -> {CFG, Liveness, Coloring}
+ {NewCFG,_DidSpill} =
+ hipe_ppc_ra_postconditions:check_and_rewrite2(CFG, [], 'naive'),
+ {NewCFG, Liveness, []}.
diff --git a/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl b/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl
index 0b16ec3891..0a97129666 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_ra_postconditions).
@@ -25,17 +18,13 @@
-include("hipe_ppc.hrl").
-check_and_rewrite(Defun, Coloring, Allocator) ->
- TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_ppc_specific),
- check_and_rewrite2(Defun, TempMap, Allocator).
+check_and_rewrite(CFG, Coloring, Allocator) ->
+ TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_ppc_specific, no_context),
+ check_and_rewrite2(CFG, TempMap, Allocator).
-check_and_rewrite2(Defun, TempMap, Allocator) ->
+check_and_rewrite2(CFG, TempMap, Allocator) ->
Strategy = strategy(Allocator),
- #defun{code=Code0} = Defun,
- {Code1,DidSpill} = do_insns(Code0, TempMap, Strategy, [], false),
- VarRange = {0, hipe_gensym:get_var(ppc)},
- {Defun#defun{code=Code1, var_range=VarRange},
- DidSpill}.
+ do_bbs(hipe_ppc_cfg:labels(CFG), TempMap, Strategy, CFG, false).
strategy(Allocator) ->
case Allocator of
@@ -44,6 +33,13 @@ strategy(Allocator) ->
'naive' -> 'fixed'
end.
+do_bbs([], _, _, CFG, DidSpill) -> {CFG, DidSpill};
+do_bbs([Lbl|Lbls], TempMap, Strategy, CFG0, DidSpill0) ->
+ Code0 = hipe_bb:code(BB = hipe_ppc_cfg:bb(CFG0, Lbl)),
+ {Code, DidSpill} = do_insns(Code0, TempMap, Strategy, [], DidSpill0),
+ CFG = hipe_ppc_cfg:bb_add(CFG0, Lbl, hipe_bb:code_update(BB, Code)),
+ do_bbs(Lbls, TempMap, Strategy, CFG, DidSpill).
+
do_insns([I|Insns], TempMap, Strategy, Accum, DidSpill0) ->
{NewIs, DidSpill1} = do_insn(I, TempMap, Strategy),
do_insns(Insns, TempMap, Strategy, lists:reverse(NewIs, Accum), DidSpill0 or DidSpill1);
@@ -61,6 +57,7 @@ do_insn(I, TempMap, Strategy) ->
#mtspr{} -> do_mtspr(I, TempMap, Strategy);
#pseudo_li{} -> do_pseudo_li(I, TempMap, Strategy);
#pseudo_move{} -> do_pseudo_move(I, TempMap, Strategy);
+ #pseudo_spill_move{} -> do_pseudo_spill_move(I, TempMap, Strategy);
#store{} -> do_store(I, TempMap, Strategy);
#storex{} -> do_storex(I, TempMap, Strategy);
#unary{} -> do_unary(I, TempMap, Strategy);
@@ -121,18 +118,25 @@ do_pseudo_li(I=#pseudo_li{dst=Dst}, TempMap, Strategy) ->
do_pseudo_move(I=#pseudo_move{dst=Dst,src=Src}, TempMap, Strategy) ->
%% Either Dst or Src (but not both) may be a pseudo temp.
- %% pseudo_move and pseudo_tailcall are special cases: in
- %% all other instructions, all temps must be non-pseudos
- %% after register allocation.
- case temp_is_spilled(Dst, TempMap) of
- true -> % Src must not be a pseudo
- {FixSrc,NewSrc,DidSpill} = fix_src1(Src, TempMap, Strategy),
- NewI = I#pseudo_move{src=NewSrc},
- {FixSrc ++ [NewI], DidSpill};
+ %% pseudo_move, pseudo_spill_move, and pseudo_tailcall are
+ %% special cases: in all other instructions, all temps
+ %% must be non-pseudos after register allocation.
+ case temp_is_spilled(Src, TempMap)
+ andalso temp_is_spilled(Dst, TempMap)
+ of
+ true -> % Turn into pseudo_spill_move
+ Temp = clone(Src, temp1(Strategy)),
+ NewI = #pseudo_spill_move{dst=Dst,temp=Temp,src=Src},
+ {[NewI], true};
_ ->
{[I], false}
end.
+do_pseudo_spill_move(I=#pseudo_spill_move{temp=Temp}, TempMap, _Strategy) ->
+ %% Temp is above the low water mark and must not have been spilled
+ false = temp_is_spilled(Temp, TempMap),
+ {[I], false}.
+
do_store(I=#store{src=Src,base=Base}, TempMap, Strategy) ->
{FixSrc,NewSrc,DidSpill1} = fix_src1(Src, TempMap, Strategy),
{FixBase,NewBase,DidSpill2} = fix_src2(Base, TempMap, Strategy),
diff --git a/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl b/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl
index 821aa66c11..7342053620 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,21 +11,21 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_ra_postconditions_fp).
-export([check_and_rewrite/2]).
-include("hipe_ppc.hrl").
-check_and_rewrite(Defun, Coloring) ->
- TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_ppc_specific_fp),
- #defun{code=Code0} = Defun,
- {Code1,DidSpill} = do_insns(Code0, TempMap, [], false),
- VarRange = {0, hipe_gensym:get_var(ppc)},
- {Defun#defun{code=Code1, var_range=VarRange},
- DidSpill}.
+check_and_rewrite(CFG, Coloring) ->
+ TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_ppc_specific_fp, no_context),
+ do_bbs(hipe_ppc_cfg:labels(CFG), TempMap, CFG, false).
+
+do_bbs([], _TempMap, CFG, DidSpill) -> {CFG, DidSpill};
+do_bbs([Lbl|Lbls], TempMap, CFG0, DidSpill0) ->
+ Code0 = hipe_bb:code(BB = hipe_ppc_cfg:bb(CFG0, Lbl)),
+ {Code, DidSpill} = do_insns(Code0, TempMap, [], DidSpill0),
+ CFG = hipe_ppc_cfg:bb_add(CFG0, Lbl, hipe_bb:code_update(BB, Code)),
+ do_bbs(Lbls, TempMap, CFG, DidSpill).
do_insns([I|Insns], TempMap, Accum, DidSpill0) ->
{NewIs, DidSpill1} = do_insn(I, TempMap),
@@ -46,6 +42,7 @@ do_insn(I, TempMap) ->
#fp_binary{} -> do_fp_binary(I, TempMap);
#fp_unary{} -> do_fp_unary(I, TempMap);
#pseudo_fmove{} -> do_pseudo_fmove(I, TempMap);
+ #pseudo_spill_fmove{} -> do_pseudo_spill_fmove(I, TempMap);
_ -> {[I], false}
end.
@@ -85,15 +82,22 @@ do_fp_unary(I=#fp_unary{dst=Dst,src=Src}, TempMap) ->
{FixSrc ++ [NewI | FixDst], DidSpill1 or DidSpill2}.
do_pseudo_fmove(I=#pseudo_fmove{dst=Dst,src=Src}, TempMap) ->
- case temp_is_spilled(Dst, TempMap) of
- true ->
- {FixSrc,NewSrc,DidSpill} = fix_src(Src, TempMap),
- NewI = I#pseudo_fmove{src=NewSrc},
- {FixSrc ++ [NewI], DidSpill};
+ case temp_is_spilled(Src, TempMap)
+ andalso temp_is_spilled(Dst, TempMap)
+ of
+ true -> % Turn into pseudo_spill_fmove
+ Temp = clone(Src),
+ NewI = #pseudo_spill_fmove{dst=Dst,temp=Temp,src=Src},
+ {[NewI], true};
_ ->
{[I], false}
end.
+do_pseudo_spill_fmove(I=#pseudo_spill_fmove{temp=Temp}, TempMap) ->
+ %% Temp is above the low water mark and must not have been spilled
+ false = temp_is_spilled(Temp, TempMap),
+ {[I], false}.
+
%%% Fix Dst and Src operands.
fix_src(Src, TempMap) ->
diff --git a/lib/hipe/ppc/hipe_ppc_registers.erl b/lib/hipe/ppc/hipe_ppc_registers.erl
index f4781d5ed7..86bea784f1 100644
--- a/lib/hipe/ppc/hipe_ppc_registers.erl
+++ b/lib/hipe/ppc/hipe_ppc_registers.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_registers).
@@ -201,6 +194,8 @@ is_arg(R) ->
_ -> false
end.
+%% Note: the fact that allocatable_gpr() is a subset of call_clobbered() is
+%% hard-coded in hipe_ppc_defuse:insn_defs_all_gpr/1
call_clobbered() -> % does the RA strip the type or not?
[{?R0,tagged},{?R0,untagged},
%% R1 is reserved for C
diff --git a/lib/hipe/ppc/hipe_ppc_subst.erl b/lib/hipe/ppc/hipe_ppc_subst.erl
new file mode 100644
index 0000000000..e282b22774
--- /dev/null
+++ b/lib/hipe/ppc/hipe_ppc_subst.erl
@@ -0,0 +1,79 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+-module(hipe_ppc_subst).
+-export([insn_temps/2]).
+-include("hipe_ppc.hrl").
+
+%% These should be moved to hipe_ppc and exported
+-type temp() :: #ppc_temp{}.
+-type oper() :: temp() | #ppc_simm16{} | #ppc_uimm16{}.
+-type arg() :: temp() | integer().
+-type insn() :: tuple(). % for now
+
+-type subst_fun() :: fun((temp()) -> temp()).
+
+%% @doc Maps over the temporaries in an instruction
+-spec insn_temps(subst_fun(), insn()) -> insn().
+insn_temps(T, I) ->
+ A = fun(O) -> arg_temps(T, O) end,
+ O = fun(O) -> oper_temps(T, O) end,
+ case I of
+ #alu{dst=D,src1=L,src2=R} -> I#alu{dst=T(D),src1=T(L),src2=O(R)};
+ #b_label{} -> I;
+ %% #bc{} -> I;
+ #bctr{} -> I;
+ #blr{} -> I;
+ #cmp{src1=L,src2=R} -> I#cmp{src1=T(L),src2=O(R)};
+ #comment{} -> I;
+ #label{} -> I;
+ #load{dst=D,base=B} -> I#load{dst=T(D),base=T(B)};
+ #loadx{dst=D,base1=L,base2=R} -> I#loadx{dst=T(D),base1=T(L),base2=T(R)};
+ #mfspr{dst=D} -> I#mfspr{dst=T(D)};
+ #mtcr{src=S} -> I#mtcr{src=T(S)};
+ #mtspr{src=S} -> I#mtspr{src=T(S)};
+ #pseudo_bc{} -> I;
+ #pseudo_call{func=F} when not is_record(F, ppc_temp) -> I;
+ #pseudo_call_prepare{} -> I;
+ #pseudo_li{dst=D} -> I#pseudo_li{dst=T(D)};
+ #pseudo_move{dst=D,src=S} -> I#pseudo_move{dst=T(D),src=T(S)};
+ #pseudo_spill_move{dst=D,temp=U,src=S} ->
+ I#pseudo_spill_move{dst=T(D),temp=T(U),src=T(S)};
+ #pseudo_tailcall{func=F,stkargs=Stk} when not is_record(F, ppc_temp) ->
+ I#pseudo_tailcall{stkargs=lists:map(A,Stk)};
+ #pseudo_tailcall_prepare{} -> I;
+ #store{src=S,base=B} -> I#store{src=T(S),base=T(B)};
+ #storex{src=S,base1=L,base2=R} ->
+ I#storex{src=T(S),base1=T(L),base2=T(R)};
+ #unary{dst=D,src=S} -> I#unary{dst=T(D),src=T(S)};
+ #lfd{dst=D,base=B} -> I#lfd{dst=T(D),base=T(B)};
+ #lfdx{dst=D,base1=L,base2=R} -> I#lfdx{dst=T(D),base1=T(L),base2=T(R)};
+ #stfd{src=S,base=B} -> I#stfd{src=T(S),base=T(B)};
+ #stfdx{src=S,base1=L,base2=R} -> I#stfdx{src=T(S),base1=T(L),base2=T(R)};
+ #fp_binary{dst=D,src1=L,src2=R} ->
+ I#fp_binary{dst=T(D),src1=T(L),src2=T(R)};
+ #fp_unary{dst=D,src=S} -> I#fp_unary{dst=T(D),src=T(S)};
+ #pseudo_fmove{dst=D,src=S} -> I#pseudo_fmove{dst=T(D),src=T(S)};
+ #pseudo_spill_fmove{dst=D,temp=U,src=S} ->
+ I#pseudo_spill_fmove{dst=T(D),temp=T(U),src=T(S)}
+ end.
+
+-spec oper_temps(subst_fun(), oper()) -> oper().
+oper_temps(SubstTemp, T=#ppc_temp{}) -> SubstTemp(T);
+oper_temps(_SubstTemp, I=#ppc_simm16{}) -> I;
+oper_temps(_SubstTemp, I=#ppc_uimm16{}) -> I.
+
+-spec arg_temps(subst_fun(), arg()) -> arg().
+arg_temps(_SubstTemp, Imm) when is_integer(Imm) -> Imm;
+arg_temps(SubstTemp, T=#ppc_temp{}) -> SubstTemp(T).
diff --git a/lib/hipe/ppc/hipe_rtl_to_ppc.erl b/lib/hipe/ppc/hipe_rtl_to_ppc.erl
index a994659616..c0010a8690 100644
--- a/lib/hipe/ppc/hipe_rtl_to_ppc.erl
+++ b/lib/hipe/ppc/hipe_rtl_to_ppc.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
%%%
-%%% %CopyrightEnd%
-%%%
%%% The PowerPC instruction set is quite irregular.
%%% The following quirks must be handled by the translation:
%%%
@@ -80,7 +74,6 @@ conv_insn(I, Map, Data) ->
case I of
#alu{} -> conv_alu(I, Map, Data);
#alub{} -> conv_alub(I, Map, Data);
- #branch{} -> conv_branch(I, Map, Data);
#call{} -> conv_call(I, Map, Data);
#comment{} -> conv_comment(I, Map, Data);
#enter{} -> conv_enter(I, Map, Data);
@@ -441,36 +434,53 @@ mk_alu_rr(Dst, Src1, RtlAluOp, Src2) ->
conv_alub(I, Map, Data) ->
%% dst = src1 aluop src2; if COND goto label
- {Dst, Map0} = conv_dst(hipe_rtl:alub_dst(I), Map),
- {Src1, Map1} = conv_src(hipe_rtl:alub_src1(I), Map0),
- {Src2, Map2} = conv_src(hipe_rtl:alub_src2(I), Map1),
- {AluOp, BCond} =
- case {hipe_rtl:alub_op(I), hipe_rtl:alub_cond(I)} of
- {'add', 'ltu'} ->
- {'addc', 'eq'};
- {RtlAlubOp, RtlAlubCond} ->
- {conv_alub_op(RtlAlubOp), conv_alub_cond(RtlAlubCond)}
- end,
- BC = mk_pseudo_bc(BCond,
- hipe_rtl:alub_true_label(I),
- hipe_rtl:alub_false_label(I),
- hipe_rtl:alub_pred(I)),
- I2 =
- case {AluOp, BCond} of
- {'addc', 'eq'} -> % copy XER[CA] to CR0[EQ] before the BC
- TmpR = new_untagged_temp(),
- [hipe_ppc:mk_mfspr(TmpR, 'xer'),
- hipe_ppc:mk_mtcr(TmpR) |
- BC];
- _ -> BC
- end,
- {NewSrc1, NewSrc2} =
- case AluOp of
- 'subf' -> {Src2, Src1};
- _ -> {Src1, Src2}
- end,
- I1 = mk_alub(Dst, NewSrc1, AluOp, NewSrc2, BCond),
- {I1 ++ I2, Map2, Data}.
+ HasDst = hipe_rtl:alub_has_dst(I),
+ {Src1, Map0} = conv_src(hipe_rtl:alub_src1(I), Map),
+ {Src2, Map1} = conv_src(hipe_rtl:alub_src2(I), Map0),
+ RtlAlubOp = hipe_rtl:alub_op(I),
+ RtlAlubCond = hipe_rtl:alub_cond(I),
+ case {HasDst, RtlAlubOp} of
+ {false, sub} ->
+ {BCond,Sign} = conv_branch_cond(RtlAlubCond),
+ I2 = mk_branch(Src1, BCond, Sign, Src2,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I)),
+ {I2, Map1, Data};
+ _ ->
+ {Dst, Map2} =
+ case HasDst of
+ false -> {new_untagged_temp(), Map1};
+ true -> conv_dst(hipe_rtl:alub_dst(I), Map1)
+ end,
+ {AluOp, BCond} =
+ case {RtlAlubOp, RtlAlubCond} of
+ {'add', 'ltu'} ->
+ {'addc', 'eq'};
+ {_, _} ->
+ {conv_alub_op(RtlAlubOp), conv_alub_cond(RtlAlubCond)}
+ end,
+ BC = mk_pseudo_bc(BCond,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I)),
+ I2 =
+ case {AluOp, BCond} of
+ {'addc', 'eq'} -> % copy XER[CA] to CR0[EQ] before the BC
+ TmpR = new_untagged_temp(),
+ [hipe_ppc:mk_mfspr(TmpR, 'xer'),
+ hipe_ppc:mk_mtcr(TmpR) |
+ BC];
+ _ -> BC
+ end,
+ {NewSrc1, NewSrc2} =
+ case AluOp of
+ 'subf' -> {Src2, Src1};
+ _ -> {Src1, Src2}
+ end,
+ I1 = mk_alub(Dst, NewSrc1, AluOp, NewSrc2, BCond),
+ {I1 ++ I2, Map2, Data}
+ end.
conv_alub_op(RtlAluOp) ->
case {get(hipe_target_arch), RtlAluOp} of
@@ -689,17 +699,6 @@ mk_alub_rr_Rc(Dst, Src1, AluOp, Src2) ->
end,
[hipe_ppc:mk_alu(AluOpDot, Dst, Src1, Src2)].
-conv_branch(I, Map, Data) ->
- %% <unused> = src1 - src2; if COND goto label
- {Src1, Map0} = conv_src(hipe_rtl:branch_src1(I), Map),
- {Src2, Map1} = conv_src(hipe_rtl:branch_src2(I), Map0),
- {BCond,Sign} = conv_branch_cond(hipe_rtl:branch_cond(I)),
- I2 = mk_branch(Src1, BCond, Sign, Src2,
- hipe_rtl:branch_true_label(I),
- hipe_rtl:branch_false_label(I),
- hipe_rtl:branch_pred(I)),
- {I2, Map1, Data}.
-
conv_branch_cond(Cond) -> % may be unsigned
case Cond of
gtu -> {'gt', 'unsigned'};
@@ -1031,7 +1030,7 @@ conv_return(I, Map, Data) ->
{I2, Map0, Data}.
conv_store(I, Map, Data) ->
- {Base1, Map0} = conv_dst(hipe_rtl:store_base(I), Map),
+ {Base1, Map0} = conv_src(hipe_rtl:store_base(I), Map),
{Src, Map1} = conv_src(hipe_rtl:store_src(I), Map0),
{Base2, Map2} = conv_src(hipe_rtl:store_offset(I), Map1),
StoreSize = hipe_rtl:store_size(I),
@@ -1056,13 +1055,28 @@ mk_store(Src, Base1, Base2, StoreSize) ->
end.
mk_store2(Src, Base1, Base2, StOp) ->
- case hipe_ppc:is_temp(Base2) of
+ case hipe_ppc:is_temp(Base1) of
true ->
- mk_store_rr(Src, Base1, Base2, StOp);
+ case hipe_ppc:is_temp(Base2) of
+ true ->
+ mk_store_rr(Src, Base1, Base2, StOp);
+ _ ->
+ mk_store_ri(Src, Base1, Base2, StOp)
+ end;
_ ->
- mk_store_ri(Src, Base1, Base2, StOp)
+ case hipe_ppc:is_temp(Base2) of
+ true ->
+ mk_store_ri(Src, Base2, Base1, StOp);
+ _ ->
+ mk_store_ii(Src, Base1, Base2, StOp)
+ end
end.
-
+
+mk_store_ii(Src, Base, Disp, StOp) ->
+ Tmp = new_untagged_temp(),
+ mk_li(Tmp, Base,
+ mk_store_ri(Src, Tmp, Disp, StOp)).
+
mk_store_ri(Src, Base, Disp, StOp) ->
hipe_ppc:mk_store(StOp, Src, Disp, Base, 'new', []).
diff --git a/lib/hipe/regalloc/Makefile b/lib/hipe/regalloc/Makefile
index aaa4418f37..662efc9707 100644
--- a/lib/hipe/regalloc/Makefile
+++ b/lib/hipe/regalloc/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2001-2016. All Rights Reserved.
+# Copyright Ericsson AB 2001-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -50,7 +50,10 @@ MODULES = hipe_ig hipe_ig_moves hipe_moves \
hipe_optimistic_regalloc \
hipe_coalescing_regalloc \
hipe_graph_coloring_regalloc \
+ hipe_range_split \
hipe_regalloc_loop \
+ hipe_regalloc_prepass \
+ hipe_restore_reuse \
hipe_ls_regalloc \
hipe_ppc_specific hipe_ppc_specific_fp \
hipe_sparc_specific hipe_sparc_specific_fp \
@@ -123,7 +126,6 @@ $(EBIN)/hipe_amd64_specific_x87.beam: hipe_x86_specific_x87.erl
$(EBIN)/hipe_coalescing_regalloc.beam: ../main/hipe.hrl
$(EBIN)/hipe_graph_coloring_regalloc.beam: ../main/hipe.hrl
$(EBIN)/hipe_ig.beam: ../main/hipe.hrl ../flow/cfg.hrl hipe_spillcost.hrl
-$(EBIN)/hipe_ig_moves.beam: ../util/hipe_vectors.hrl
$(EBIN)/hipe_ls_regalloc.beam: ../main/hipe.hrl
$(EBIN)/hipe_optimistic_regalloc.beam: ../main/hipe.hrl
$(EBIN)/hipe_regalloc_loop.beam: ../main/hipe.hrl
diff --git a/lib/hipe/regalloc/hipe_adj_list.erl b/lib/hipe/regalloc/hipe_adj_list.erl
index de59da2410..5066106074 100644
--- a/lib/hipe/regalloc/hipe_adj_list.erl
+++ b/lib/hipe/regalloc/hipe_adj_list.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_adj_list.erl
diff --git a/lib/hipe/regalloc/hipe_amd64_specific.erl b/lib/hipe/regalloc/hipe_amd64_specific.erl
index 6937e71ac7..72900563e6 100644
--- a/lib/hipe/regalloc/hipe_amd64_specific.erl
+++ b/lib/hipe/regalloc/hipe_amd64_specific.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
+
-define(HIPE_AMD64, true).
-include("hipe_x86_specific.erl").
diff --git a/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl b/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
index 50e5869d45..d592ba391c 100644
--- a/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
+++ b/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,44 +11,58 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_amd64_specific_sse2).
--export([number_of_temporaries/1]).
+-export([number_of_temporaries/2]).
% The following exports are used as M:F(...) calls from other modules;
%% e.g. hipe_amd64_ra_ls.
--export([analyze/1,
- bb/2,
- args/1,
- labels/1,
- livein/2,
- liveout/2,
- uses/1,
- defines/1,
- def_use/1,
- is_arg/1, %% used by hipe_ls_regalloc
- is_move/1,
- is_fixed/1, %% used by hipe_graph_coloring_regalloc
- is_global/1,
- is_precoloured/1,
- reg_nr/1,
- non_alloc/1,
- allocatable/0,
- physical_name/1,
- all_precoloured/0,
- new_spill_index/1, %% used by hipe_ls_regalloc
- var_range/1,
- breadthorder/1,
- postorder/1,
- reverse_postorder/1]).
+-export([analyze/2,
+ bb/3,
+ args/2,
+ labels/2,
+ livein/3,
+ liveout/3,
+ uses/2,
+ defines/2,
+ defines_all_alloc/2,
+ def_use/2,
+ is_arg/2, %% used by hipe_ls_regalloc
+ is_move/2,
+ is_spill_move/2,
+ is_fixed/2, %% used by hipe_graph_coloring_regalloc
+ is_global/2,
+ is_precoloured/2,
+ reg_nr/2,
+ non_alloc/2,
+ allocatable/1,
+ allocatable/2,
+ temp0/1,
+ physical_name/2,
+ all_precoloured/1,
+ new_spill_index/2, %% used by hipe_ls_regalloc
+ var_range/2,
+ breadthorder/2,
+ postorder/2,
+ reverse_postorder/2]).
%% callbacks for hipe_regalloc_loop
--export([defun_to_cfg/1,
- check_and_rewrite/2]).
+-export([check_and_rewrite/3,
+ check_and_rewrite/4]).
+
+%% callbacks for hipe_regalloc_prepass, hipe_range_split
+-export([mk_move/3,
+ mk_goto/2,
+ redirect_jmp/4,
+ new_label/1,
+ new_reg_nr/1,
+ update_reg_nr/3,
+ update_bb/4,
+ subst_temps/3]).
+
+%% callbacks for hipe_bb_weights
+-export([branch_preds/2]).
%%----------------------------------------------------------------------------
@@ -60,86 +70,102 @@
%%----------------------------------------------------------------------------
-defun_to_cfg(Defun) ->
- hipe_x86_cfg:init(Defun).
+check_and_rewrite(CFG, Coloring, no_context) ->
+ hipe_amd64_ra_sse2_postconditions:check_and_rewrite(CFG, Coloring).
-check_and_rewrite(Defun, Coloring) ->
- hipe_amd64_ra_sse2_postconditions:check_and_rewrite(Defun, Coloring).
+check_and_rewrite(CFG, Coloring, Strategy, no_context) ->
+ hipe_amd64_ra_sse2_postconditions:check_and_rewrite(
+ CFG, Coloring, Strategy).
-reverse_postorder(CFG) ->
+reverse_postorder(CFG, _) ->
hipe_x86_cfg:reverse_postorder(CFG).
-breadthorder(CFG) ->
+breadthorder(CFG, _) ->
hipe_x86_cfg:breadthorder(CFG).
-postorder(CFG) ->
+postorder(CFG, _) ->
hipe_x86_cfg:postorder(CFG).
-is_global(_Reg) ->
- false.
+is_global(Reg, _) ->
+ hipe_amd64_registers:sse2_temp0() =:= Reg.
-is_fixed(_Reg) ->
+is_fixed(_Reg, _) ->
false.
-is_arg(_Reg) ->
+is_arg(_Reg, _) ->
false.
--spec args(#cfg{}) -> [].
-args(_CFG) ->
+-spec args(#cfg{}, no_context) -> [].
+args(_CFG, _) ->
[].
-non_alloc(_) ->
+non_alloc(_, _) ->
[].
%% Liveness stuff
-analyze(CFG) ->
+analyze(CFG, _) ->
hipe_amd64_liveness:analyze(CFG).
-livein(Liveness, L) ->
+livein(Liveness, L, _) ->
[X || X <- hipe_amd64_liveness:livein(Liveness, L),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_type(X) =:= 'double'].
-liveout(BB_in_out_liveness, Label) ->
+liveout(BB_in_out_liveness, Label, _) ->
[X || X <- hipe_amd64_liveness:liveout(BB_in_out_liveness, Label),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_type(X) =:= 'double'].
%% Registers stuff
-allocatable() ->
- hipe_amd64_registers:allocatable_sse2().
+allocatable(Ctx) ->
+ allocatable('normal', Ctx).
+
+allocatable('normal', _) ->
+ hipe_amd64_registers:allocatable_sse2();
+allocatable('linearscan', _) ->
+ hipe_amd64_registers:allocatable_sse2() --
+ [hipe_amd64_registers:sse2_temp0()].
+
+temp0(_) ->
+ hipe_amd64_registers:sse2_temp0().
-all_precoloured() ->
- allocatable().
+all_precoloured(Ctx) ->
+ allocatable(Ctx).
-is_precoloured(Reg) ->
- lists:member(Reg,all_precoloured()).
+is_precoloured(Reg, _) ->
+ hipe_amd64_registers:is_precoloured_sse2(Reg).
-physical_name(Reg) ->
+physical_name(Reg, _) ->
Reg.
%% CFG stuff
-labels(CFG) ->
+labels(CFG, _) ->
hipe_x86_cfg:labels(CFG).
-var_range(_CFG) ->
+var_range(_CFG, _) ->
hipe_gensym:var_range(x86).
--spec number_of_temporaries(#cfg{}) -> non_neg_integer().
-number_of_temporaries(_CFG) ->
+-spec number_of_temporaries(#cfg{}, no_context) -> non_neg_integer().
+number_of_temporaries(_CFG, _) ->
Highest_temporary = hipe_gensym:get_var(x86),
%% Since we can have temps from 0 to Max adjust by +1.
Highest_temporary + 1.
-bb(CFG, L) ->
+bb(CFG, L, _) ->
hipe_x86_cfg:bb(CFG, L).
+update_bb(CFG,L,BB,_) ->
+ hipe_x86_cfg:bb_add(CFG,L,BB).
+
+branch_preds(Instr,_) ->
+ hipe_x86_cfg:branch_preds(Instr).
+
%% AMD64 stuff
-def_use(Instruction) ->
+def_use(Instruction, _) ->
{[X || X <- hipe_amd64_defuse:insn_def(Instruction),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_type(X) =:= 'double'],
@@ -148,17 +174,19 @@ def_use(Instruction) ->
hipe_x86:temp_type(X) =:= 'double']
}.
-uses(I) ->
+uses(I, _) ->
[X || X <- hipe_amd64_defuse:insn_use(I),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_type(X) =:= 'double'].
-defines(I) ->
+defines(I, _) ->
[X || X <- hipe_amd64_defuse:insn_def(I),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_type(X) =:= 'double'].
-is_move(Instruction) ->
+defines_all_alloc(I, _) -> hipe_amd64_defuse:insn_defs_all(I).
+
+is_move(Instruction, _) ->
case hipe_x86:is_fmove(Instruction) of
true ->
Src = hipe_x86:fmove_src(Instruction),
@@ -167,10 +195,51 @@ is_move(Instruction) ->
andalso hipe_x86:is_temp(Dst) andalso hipe_x86:temp_is_allocatable(Dst);
false -> false
end.
+
+is_spill_move(Instruction,_) ->
+ hipe_x86:is_pseudo_spill_fmove(Instruction).
-reg_nr(Reg) ->
+reg_nr(Reg, _) ->
hipe_x86:temp_reg(Reg).
--spec new_spill_index(non_neg_integer()) -> pos_integer().
-new_spill_index(SpillIndex) when is_integer(SpillIndex) ->
+mk_move(Src, Dst, _) ->
+ hipe_x86:mk_fmove(Src, Dst).
+
+mk_goto(Label, _) ->
+ hipe_x86:mk_jmp_label(Label).
+
+redirect_jmp(Jmp, ToOld, ToNew, _) when is_integer(ToOld), is_integer(ToNew) ->
+ Ref = make_ref(),
+ put(Ref, false),
+ I = hipe_x86_subst:insn_lbls(
+ fun(Tgt) ->
+ if Tgt =:= ToOld -> put(Ref, true), ToNew;
+ is_integer(Tgt) -> Tgt
+ end
+ end, Jmp),
+ true = erase(Ref), % Assert that something was rewritten
+ I.
+
+new_label(_) ->
+ hipe_gensym:get_next_label(x86).
+
+new_reg_nr(_) ->
+ hipe_gensym:get_next_var(x86).
+
+update_reg_nr(Nr, _Temp, _) ->
+ hipe_x86:mk_temp(Nr, 'double').
+
+subst_temps(SubstFun, Instr, _) ->
+ hipe_amd64_subst:insn_temps(
+ fun(Op) ->
+ case hipe_x86:temp_is_allocatable(Op)
+ andalso hipe_x86:temp_type(Op) =:= 'double'
+ of
+ true -> SubstFun(Op);
+ false -> Op
+ end
+ end, Instr).
+
+-spec new_spill_index(non_neg_integer(), no_context) -> pos_integer().
+new_spill_index(SpillIndex, _) when is_integer(SpillIndex) ->
SpillIndex + 1.
diff --git a/lib/hipe/regalloc/hipe_amd64_specific_x87.erl b/lib/hipe/regalloc/hipe_amd64_specific_x87.erl
index 2160e93d24..918f72f5f2 100644
--- a/lib/hipe/regalloc/hipe_amd64_specific_x87.erl
+++ b/lib/hipe/regalloc/hipe_amd64_specific_x87.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
+
-define(HIPE_AMD64, true).
-include("hipe_x86_specific_x87.erl").
diff --git a/lib/hipe/regalloc/hipe_arm_specific.erl b/lib/hipe/regalloc/hipe_arm_specific.erl
index 4e34cb1d99..7ebc6aa336 100644
--- a/lib/hipe/regalloc/hipe_arm_specific.erl
+++ b/lib/hipe/regalloc/hipe_arm_specific.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,121 +11,138 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_specific).
%% for hipe_coalescing_regalloc:
--export([number_of_temporaries/1
- ,analyze/1
- ,labels/1
- ,all_precoloured/0
- ,bb/2
- ,liveout/2
- ,reg_nr/1
- ,def_use/1
- ,is_move/1
- ,is_precoloured/1
- ,var_range/1
- ,allocatable/0
- ,non_alloc/1
- ,physical_name/1
- ,reverse_postorder/1
- ,livein/2
- ,uses/1
- ,defines/1
+-export([number_of_temporaries/2
+ ,analyze/2
+ ,labels/2
+ ,all_precoloured/1
+ ,bb/3
+ ,liveout/3
+ ,reg_nr/2
+ ,def_use/2
+ ,is_move/2
+ ,is_spill_move/2
+ ,is_precoloured/2
+ ,var_range/2
+ ,allocatable/1
+ ,non_alloc/2
+ ,physical_name/2
+ ,reverse_postorder/2
+ ,livein/3
+ ,uses/2
+ ,defines/2
+ ,defines_all_alloc/2
]).
%% for hipe_graph_coloring_regalloc:
--export([is_fixed/1]).
+-export([is_fixed/2]).
%% for hipe_ls_regalloc:
--export([args/1, is_arg/1, is_global/1, new_spill_index/1]).
--export([breadthorder/1, postorder/1]).
+-export([args/2, is_arg/2, is_global/2, new_spill_index/2]).
+-export([breadthorder/2, postorder/2]).
%% callbacks for hipe_regalloc_loop
--export([defun_to_cfg/1,
- check_and_rewrite/2]).
+-export([check_and_rewrite/3]).
+
+%% callbacks for hipe_regalloc_prepass, hipe_range_split
+-export([mk_move/3,
+ mk_goto/2,
+ redirect_jmp/4,
+ new_label/1,
+ new_reg_nr/1,
+ update_reg_nr/3,
+ update_bb/4,
+ subst_temps/3]).
-defun_to_cfg(Defun) ->
- hipe_arm_cfg:init(Defun).
+%% callbacks for hipe_bb_weights, hipe_range_split
+-export([branch_preds/2]).
-check_and_rewrite(Defun, Coloring) ->
- hipe_arm_ra_postconditions:check_and_rewrite(Defun, Coloring, 'normal').
+check_and_rewrite(CFG, Coloring, no_context) ->
+ hipe_arm_ra_postconditions:check_and_rewrite(CFG, Coloring, 'normal').
-reverse_postorder(CFG) ->
+reverse_postorder(CFG, _) ->
hipe_arm_cfg:reverse_postorder(CFG).
-non_alloc(CFG) ->
- non_alloc(hipe_arm_registers:nr_args(), hipe_arm_cfg:params(CFG)).
+non_alloc(CFG, no_context) ->
+ non_alloc_1(hipe_arm_registers:nr_args(), hipe_arm_cfg:params(CFG)).
%% same as hipe_arm_frame:fix_formals/2
-non_alloc(0, Rest) -> Rest;
-non_alloc(N, [_|Rest]) -> non_alloc(N-1, Rest);
-non_alloc(_, []) -> [].
+non_alloc_1(0, Rest) -> Rest;
+non_alloc_1(N, [_|Rest]) -> non_alloc_1(N-1, Rest);
+non_alloc_1(_, []) -> [].
%% Liveness stuff
-analyze(CFG) ->
+analyze(CFG, _) ->
hipe_arm_liveness_gpr:analyse(CFG).
-livein(Liveness,L) ->
+livein(Liveness,L,_) ->
[X || X <- hipe_arm_liveness_gpr:livein(Liveness,L),
hipe_arm:temp_is_allocatable(X)].
-liveout(BB_in_out_liveness,Label) ->
+liveout(BB_in_out_liveness,Label,_) ->
[X || X <- hipe_arm_liveness_gpr:liveout(BB_in_out_liveness,Label),
hipe_arm:temp_is_allocatable(X)].
%% Registers stuff
-allocatable() ->
+allocatable(no_context) ->
hipe_arm_registers:allocatable_gpr().
-all_precoloured() ->
+all_precoloured(no_context) ->
hipe_arm_registers:all_precoloured().
-is_precoloured(Reg) ->
+is_precoloured(Reg, _) ->
hipe_arm_registers:is_precoloured_gpr(Reg).
-is_fixed(R) ->
+is_fixed(R, _) ->
hipe_arm_registers:is_fixed(R).
-physical_name(Reg) ->
+physical_name(Reg, _) ->
Reg.
%% CFG stuff
-labels(CFG) ->
+labels(CFG, _) ->
hipe_arm_cfg:labels(CFG).
-var_range(_CFG) ->
+var_range(_CFG, _) ->
hipe_gensym:var_range(arm).
-number_of_temporaries(_CFG) ->
+number_of_temporaries(_CFG, _) ->
Highest_temporary = hipe_gensym:get_var(arm),
%% Since we can have temps from 0 to Max adjust by +1.
Highest_temporary + 1.
-bb(CFG,L) ->
+bb(CFG,L,_) ->
hipe_arm_cfg:bb(CFG,L).
+update_bb(CFG,L,BB,_) ->
+ hipe_arm_cfg:bb_add(CFG,L,BB).
+
+branch_preds(Branch,_) ->
+ hipe_arm_cfg:branch_preds(Branch).
+
%% ARM stuff
-def_use(Instruction) ->
- {defines(Instruction), uses(Instruction)}.
+def_use(Instruction, Ctx) ->
+ {defines(Instruction, Ctx), uses(Instruction, Ctx)}.
-uses(I) ->
+uses(I, _) ->
[X || X <- hipe_arm_defuse:insn_use_gpr(I),
hipe_arm:temp_is_allocatable(X)].
-defines(I) ->
+defines(I, _) ->
[X || X <- hipe_arm_defuse:insn_def_gpr(I),
hipe_arm:temp_is_allocatable(X)].
-is_move(Instruction) ->
+defines_all_alloc(I, _) ->
+ hipe_arm_defuse:insn_defs_all_gpr(I).
+
+is_move(Instruction, _) ->
case hipe_arm:is_pseudo_move(Instruction) of
true ->
Dst = hipe_arm:pseudo_move_dst(Instruction),
@@ -142,28 +155,67 @@ is_move(Instruction) ->
false -> false
end.
-reg_nr(Reg) ->
+is_spill_move(Instruction, _) ->
+ hipe_arm:is_pseudo_spill_move(Instruction).
+
+reg_nr(Reg, _) ->
hipe_arm:temp_reg(Reg).
+mk_move(Src, Dst, _) ->
+ hipe_arm:mk_pseudo_move(Dst, Src).
+
+mk_goto(Label, _) ->
+ hipe_arm:mk_b_label(Label).
+
+redirect_jmp(Jmp, ToOld, ToNew, _) when is_integer(ToOld), is_integer(ToNew) ->
+ Ref = make_ref(),
+ put(Ref, false),
+ I = hipe_arm_subst:insn_lbls(
+ fun(Tgt) ->
+ if Tgt =:= ToOld -> put(Ref, true), ToNew;
+ is_integer(Tgt) -> Tgt
+ end
+ end, Jmp),
+ true = erase(Ref), % Assert that something was rewritten
+ I.
+
+new_label(_) ->
+ hipe_gensym:get_next_label(arm).
+
+new_reg_nr(_) ->
+ hipe_gensym:get_next_var(arm).
+
+update_reg_nr(Nr, Temp, _) ->
+ hipe_arm:mk_temp(Nr, hipe_arm:temp_type(Temp)).
+
+subst_temps(SubstFun, Instr, _) ->
+ hipe_arm_subst:insn_temps(
+ fun(Op) ->
+ case hipe_arm:temp_is_allocatable(Op) of
+ true -> SubstFun(Op);
+ false -> Op
+ end
+ end, Instr).
+
%%% Linear Scan stuff
-new_spill_index(SpillIndex) when is_integer(SpillIndex) ->
+new_spill_index(SpillIndex, _) when is_integer(SpillIndex) ->
SpillIndex+1.
-breadthorder(CFG) ->
+breadthorder(CFG, _) ->
hipe_arm_cfg:breadthorder(CFG).
-postorder(CFG) ->
+postorder(CFG, _) ->
hipe_arm_cfg:postorder(CFG).
-is_global(R) ->
+is_global(R, _) ->
R =:= hipe_arm_registers:temp1() orelse
R =:= hipe_arm_registers:temp2() orelse
R =:= hipe_arm_registers:temp3() orelse
hipe_arm_registers:is_fixed(R).
-is_arg(R) ->
+is_arg(R, _) ->
hipe_arm_registers:is_arg(R).
-args(CFG) ->
+args(CFG, _) ->
hipe_arm_registers:args(hipe_arm_cfg:arity(CFG)).
diff --git a/lib/hipe/regalloc/hipe_coalescing_regalloc.erl b/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
index e2f817d369..b8f0a1974c 100644
--- a/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-----------------------------------------------------------------------
%% File : hipe_coalescing_regalloc.erl
@@ -30,7 +24,7 @@
%%-----------------------------------------------------------------------
-module(hipe_coalescing_regalloc).
--export([regalloc/5]).
+-export([regalloc/7]).
%%-ifndef(DEBUG).
%%-define(DEBUG,true).
@@ -51,19 +45,21 @@
%%
%% Returns:
%% Coloring -- A coloring for specified CFG
-%% SpillIndex0 -- A new spill index
+%% SpillIndex2 -- A new spill index
%%-----------------------------------------------------------------------
-regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
+regalloc(CFG, Liveness, SpillIndex, SpillLimit, TargetMod, TargetContext,
+ _Options) ->
+ Target = {TargetMod, TargetContext},
%% Build interference graph
?debug_msg("Build IG\n", []),
- IG = hipe_ig:build(CFG, Target),
+ IG = hipe_ig:build(CFG, Liveness, TargetMod, TargetContext),
%% io:format("IG: ~p\n", [IG]),
?debug_msg("Init\n", []),
- Num_Temps = Target:number_of_temporaries(CFG),
+ Num_Temps = TargetMod:number_of_temporaries(CFG,TargetContext),
?debug_msg("Coalescing RA: num_temps = ~p~n", [Num_Temps]),
- Allocatable = Target:allocatable(),
+ Allocatable = TargetMod:allocatable(TargetContext),
K = length(Allocatable),
All_colors = colset_from_list(Allocatable),
@@ -72,7 +68,8 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
Move_sets = hipe_moves:new(IG),
?debug_msg("Build Worklist\n", []),
- Worklists = hipe_reg_worklists:new(IG, Target, CFG, Move_sets, K, Num_Temps),
+ Worklists = hipe_reg_worklists:new(IG, TargetMod, TargetContext, CFG,
+ Move_sets, K, Num_Temps),
Alias = initAlias(Num_Temps),
?debug_msg("Do coloring\n~p~n", [Worklists]),
@@ -81,10 +78,10 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
%% io:format("SelStk0 ~w\n",[SelStk0]),
?debug_msg("Init node sets\n", []),
Node_sets = hipe_node_sets:new(),
- %% io:format("NodeSet: ~w\n NonAlloc ~w\n",[Node_sets,Target:non_alloc(CFG)]),
+ %% io:format("NodeSet: ~w\n NonAlloc ~w\n",[Node_sets,non_alloc(CFG,Target)]),
?debug_msg("Default coloring\n", []),
{Color0,Node_sets1} =
- defaultColoring(Target:all_precoloured(),
+ defaultColoring(TargetMod:all_precoloured(TargetContext),
initColor(Num_Temps), Node_sets, Target),
?debug_msg("Assign colors\n", []),
@@ -94,9 +91,10 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
%% io:format("color0:~w\nColor1:~w\nNodes:~w\nNodes2:~w\nNum_Temps:~w\n",[Color0,Color1,Node_sets,Node_sets2,Num_Temps]),
?debug_msg("Build mapping ~p\n", [Node_sets2]),
- Coloring = build_namelist(Node_sets2, SpillIndex, Alias0, Color1),
+ {Coloring, SpillIndex2} =
+ build_namelist(Node_sets2, SpillIndex, Alias0, Color1),
?debug_msg("Coloring ~p\n", [Coloring]),
- Coloring.
+ {Coloring, SpillIndex2}.
%%----------------------------------------------------------------------
%% Function: do_coloring
@@ -379,7 +377,7 @@ assignColors(Stack, NodeSets, Color, Alias, AllColors, Target) ->
false -> % Colour case
Col = colset_smallest(OkColors),
NodeSets1 = hipe_node_sets:add_colored(Node, NodeSets),
- Color1 = setColor(Node, Target:physical_name(Col), Color),
+ Color1 = setColor(Node, physical_name(Col,Target), Color),
assignColors(Stack1, NodeSets1, Color1, Alias, AllColors, Target)
end
end.
@@ -402,7 +400,7 @@ assignColors(Stack, NodeSets, Color, Alias, AllColors, Target) ->
defaultColoring([], Color, NodeSets, _Target) ->
{Color,NodeSets};
defaultColoring([Reg|Regs], Color, NodeSets, Target) ->
- Color1 = setColor(Reg,Target:physical_name(Reg), Color),
+ Color1 = setColor(Reg,physical_name(Reg,Target), Color),
NodeSets1 = hipe_node_sets:add_colored(Reg, NodeSets),
defaultColoring(Regs, Color1, NodeSets1, Target).
@@ -567,7 +565,7 @@ coalesce(Moves, IG, Worklists, Alias, K, Target) ->
?debug_msg("Testing nodes ~p and ~p for coalescing~n",[Dest,Source]),
Alias_src = getAlias(Source, Alias),
Alias_dst = getAlias(Dest, Alias),
- {U,V} = case Target:is_precoloured(Alias_dst) of
+ {U,V} = case is_precoloured(Alias_dst,Target) of
true -> {Alias_dst, Alias_src};
false -> {Alias_src, Alias_dst}
end,
@@ -577,7 +575,7 @@ coalesce(Moves, IG, Worklists, Alias, K, Target) ->
Worklists1 = add_worklist(Worklists, U, K, Moves1, IG, Target),
{Moves1, IG, Worklists1, Alias};
true ->
- case (Target:is_precoloured(V) orelse
+ case (is_precoloured(V,Target) orelse
hipe_ig:nodes_are_adjacent(U, V, IG)) of
true ->
Moves1 = Moves0, % drop constrained move Move
@@ -585,7 +583,7 @@ coalesce(Moves, IG, Worklists, Alias, K, Target) ->
Worklists2 = add_worklist(Worklists1, V, K, Moves1, IG, Target),
{Moves1, IG, Worklists2, Alias};
false ->
- case (case Target:is_precoloured(U) of
+ case (case is_precoloured(U,Target) of
true ->
AdjV = hipe_ig:node_adj_list(V, IG),
all_adjacent_ok(AdjV, U, Worklists, IG, K, Target);
@@ -627,7 +625,7 @@ coalesce(Moves, IG, Worklists, Alias, K, Target) ->
%%----------------------------------------------------------------------
add_worklist(Worklists, U, K, Moves, IG, Target) ->
- case (not(Target:is_precoloured(U))
+ case (not(is_precoloured(U,Target))
andalso not(hipe_moves:move_related(U, Moves))
andalso (hipe_ig:is_trivially_colourable(U, K, IG))) of
true ->
@@ -711,7 +709,7 @@ combine(U, V, IG, Worklists, Moves, Alias, K, Target) ->
combine_edges([], _U, IG, Worklists, Moves, _K, _Target) ->
{IG, Worklists, Moves};
-combine_edges([T|Ts], U, IG, Worklists, Moves, K, Target) ->
+combine_edges([T|Ts], U, IG, Worklists, Moves, K, Target={TgtMod,TgtCtx}) ->
case hipe_reg_worklists:member_stack_or_coalesced(T, Worklists) of
true -> combine_edges(Ts, U, IG, Worklists, Moves, K, Target);
_ ->
@@ -728,7 +726,7 @@ combine_edges([T|Ts], U, IG, Worklists, Moves, K, Target) ->
%% worklist, and that's where decrement_degree() expects to find it.
%% This issue is not covered in the published algorithm.
OldDegree = hipe_ig:get_node_degree(T, IG),
- IG1 = hipe_ig:add_edge(T, U, IG, Target),
+ IG1 = hipe_ig:add_edge(T, U, IG, TgtMod, TgtCtx),
NewDegree = hipe_ig:get_node_degree(T, IG1),
Worklists0 =
if NewDegree =:= K, OldDegree =:= K-1 ->
@@ -767,7 +765,7 @@ combine_edges([T|Ts], U, IG, Worklists, Moves, K, Target) ->
ok(T, R, IG, K, Target) ->
((hipe_ig:is_trivially_colourable(T, K, IG))
- orelse Target:is_precoloured(T)
+ orelse is_precoloured(T,Target)
orelse hipe_ig:nodes_are_adjacent(T, R, IG)).
%%----------------------------------------------------------------------
@@ -916,7 +914,7 @@ findCheapest([Node|Nodes], IG, Cost, Cheapest, SpillLimit) ->
%% limit are extremely expensive.
getCost(Node, IG, SpillLimit) ->
- case Node > SpillLimit of
+ case Node >= SpillLimit of
true -> inf;
false -> hipe_ig:node_spill_cost(Node, IG)
end.
@@ -1028,3 +1026,15 @@ freezeEm3(_U, V, _M, K, WorkLists, Moves, IG, _Alias) ->
false ->
{WorkLists, Moves1}
end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Interface to external functions.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+is_precoloured(R, {TgtMod,TgtCtx}) ->
+ TgtMod:is_precoloured(R,TgtCtx).
+
+physical_name(R, {TgtMod,TgtCtx}) ->
+ TgtMod:physical_name(R,TgtCtx).
diff --git a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
index bc6e442236..f82d3a2cbc 100644
--- a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%@doc
@@ -51,7 +45,7 @@
%%
-module(hipe_graph_coloring_regalloc).
--export([regalloc/5]).
+-export([regalloc/7]).
%%-ifndef(DO_ASSERT).
%%-define(DO_ASSERT, true).
@@ -77,18 +71,21 @@
%% that the coloring agrees with the interference graph (that is, that
%% no neighbors have the same register or spill location).
-%% @spec regalloc(#cfg{}, non_neg_fixnum(), non_neg_fixnum(), atom(), list()) -> {, non_neg_fixnum()}
+%% @spec regalloc(#cfg{}, liveness(), non_neg_fixnum(), non_neg_fixnum(),
+%% module(), tgt_ctx(), list()) -> {, non_neg_fixnum()}
-regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
- PhysRegs = Target:allocatable(),
+regalloc(CFG, Live, SpillIndex, SpillLimit, TargetMod, TargetContext,
+ _Options) ->
+ Target = {TargetMod, TargetContext},
+ PhysRegs = allocatable(Target),
?report2("building IG~n", []),
- {IG, Spill} = build_ig(CFG, Target),
+ {IG, Spill} = build_ig(CFG, Live, Target),
%% check_ig(IG),
?report3("graph: ~p~nphysical regs: ~p~n", [list_ig(IG), PhysRegs]),
%% These nodes *can't* be allocated to registers.
- NotAllocatable = [Target:reg_nr(X) || X <- Target:non_alloc(CFG)],
+ NotAllocatable = non_alloc(CFG, Target),
%% i.e. Arguments on x86
?report2("Nonalloc ~w~n", [NotAllocatable]),
@@ -97,7 +94,7 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
ordsets:from_list(PhysRegs),
SpillIndex,
SpillLimit,
- Target:number_of_temporaries(CFG),
+ number_of_temporaries(CFG, Target),
Target, NotAllocatable),
Coloring = [{X, {reg, X}} || X <- NotAllocatable] ++ Cols,
?ASSERT(check_coloring(Coloring, IG, Target)),
@@ -112,15 +109,9 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
%% Returns {Interference_graph, Spill_cost_dictionary}
%%
-build_ig(CFG, Target) ->
- try build_ig0(CFG, Target)
- catch error:Rsn -> exit({?MODULE, build_ig, Rsn})
- end.
-
-build_ig0(CFG, Target) ->
- Live = Target:analyze(CFG),
- NumN = Target:number_of_temporaries(CFG), % poss. N-1?
- {IG, Spill} = build_ig_bbs(Target:labels(CFG),
+build_ig(CFG, Live, Target) ->
+ NumN = number_of_temporaries(CFG, Target), % poss. N-1?
+ {IG, Spill} = build_ig_bbs(labels(CFG, Target),
CFG,
Live,
empty_ig(NumN),
@@ -208,17 +199,8 @@ set_spill_cost(X, N, Spill) ->
%% * add low-degree neighbors of z to low
%% * restart the while-loop above
-color(IG, Spill, PhysRegs, SpillIx, SpillLimit, NumNodes, Target, NotAllocatable) ->
- try color_0(IG, Spill, PhysRegs, SpillIx, SpillLimit,
- NumNodes, Target, NotAllocatable)
- catch
- error:Rsn ->
- ?error_msg("Coloring failed with ~p~n", [Rsn]),
- ?EXIT(Rsn)
- end.
-
-color_0(IG, Spill, PhysRegs, SpillIx, SpillLimit, NumNodes, Target,
- NotAllocatable) ->
+color(IG, Spill, PhysRegs, SpillIx, SpillLimit, NumNodes, Target,
+ NotAllocatable) ->
?report("simplification of IG~n", []),
K = ordsets:size(PhysRegs),
Nodes = list_ig(IG),
@@ -227,14 +209,14 @@ color_0(IG, Spill, PhysRegs, SpillIx, SpillLimit, NumNodes, Target,
%% Any nodes above the spillimit must be colored first...
MustNotSpill =
- if NumNodes > SpillLimit+1 ->
- sort_on_degree(lists:seq(SpillLimit+1,NumNodes-1) -- Low,IG);
+ if NumNodes > SpillLimit ->
+ sort_on_degree(lists:seq(SpillLimit,NumNodes-1) -- Low,IG);
true -> []
end,
?report(" starting with low degree nodes ~p~n",[Low]),
EmptyStk = [],
- Precolored = Target:all_precoloured(),
+ Precolored = all_precoloured(Target),
{Stk, NewSpillIx} =
simplify(Low, NumNodes, Precolored,
IG, Spill, K, SpillIx, EmptyStk,
@@ -415,11 +397,11 @@ spill_costs([{N,Info}|Ns], IG, Vis, Spill, SpillLimit, Target) ->
true ->
spill_costs(Ns,IG,Vis,Spill, SpillLimit, Target);
_ ->
- case Target:is_fixed(N) of
+ case is_fixed(N, Target) of
true ->
spill_costs(Ns, IG, Vis, Spill, SpillLimit, Target);
false ->
- if N > SpillLimit ->
+ if N >= SpillLimit ->
spill_costs(Ns, IG, Vis, Spill, SpillLimit, Target);
true ->
[{spill_cost_of(N,Spill)/Deg,N} |
@@ -772,18 +754,36 @@ valid_coloring(X, C, [_|Ys]) ->
%% *** INTERFACES TO OTHER MODULES ***
%%
-liveout(CFG, L, Target) ->
- ordsets:from_list(reg_names(Target:liveout(CFG, L), Target)).
+all_precoloured({TgtMod,TgtCtx}) ->
+ TgtMod:all_precoloured(TgtCtx).
+
+allocatable({TgtMod,TgtCtx}) ->
+ TgtMod:allocatable(TgtCtx).
+
+is_fixed(Reg, {TgtMod,TgtCtx}) ->
+ TgtMod:is_fixed(Reg, TgtCtx).
+
+labels(CFG, {TgtMod,TgtCtx}) ->
+ TgtMod:labels(CFG, TgtCtx).
+
+liveout(CFG, L, Target={TgtMod,TgtCtx}) ->
+ ordsets:from_list(reg_names(TgtMod:liveout(CFG, L, TgtCtx), Target)).
+
+bb(CFG, L, {TgtMod,TgtCtx}) ->
+ hipe_bb:code(TgtMod:bb(CFG, L, TgtCtx)).
+
+def_use(X, Target={TgtMod,TgtCtx}) ->
+ {ordsets:from_list(reg_names(TgtMod:defines(X,TgtCtx), Target)),
+ ordsets:from_list(reg_names(TgtMod:uses(X,TgtCtx), Target))}.
-bb(CFG, L, Target) ->
- hipe_bb:code(Target:bb(CFG, L)).
+non_alloc(CFG, Target={TgtMod,TgtCtx}) ->
+ reg_names(TgtMod:non_alloc(CFG, TgtCtx), Target).
-def_use(X, Target) ->
- {ordsets:from_list(reg_names(Target:defines(X), Target)),
- ordsets:from_list(reg_names(Target:uses(X), Target))}.
+number_of_temporaries(CFG, {TgtMod,TgtCtx}) ->
+ TgtMod:number_of_temporaries(CFG, TgtCtx).
-reg_names(Regs, Target) ->
- [Target:reg_nr(X) || X <- Regs].
+reg_names(Regs, {TgtMod,TgtCtx}) ->
+ [TgtMod:reg_nr(X,TgtCtx) || X <- Regs].
%%
%% Precoloring: use this version when a proper implementation of
@@ -803,5 +803,5 @@ precolor0([R|Rs], Cols, Target) ->
{[{R, {reg, physical_name(R, Target)}}|Cs],
set_color(R, physical_name(R, Target), Cols1)}.
-physical_name(X, Target) ->
- Target:physical_name(X).
+physical_name(X, {TgtMod,TgtCtx}) ->
+ TgtMod:physical_name(X, TgtCtx).
diff --git a/lib/hipe/regalloc/hipe_ig.erl b/lib/hipe/regalloc/hipe_ig.erl
index 8fd5d0df1f..14a1ae77f2 100644
--- a/lib/hipe/regalloc/hipe_ig.erl
+++ b/lib/hipe/regalloc/hipe_ig.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_ig.erl
@@ -28,7 +22,7 @@
-module(hipe_ig).
--export([build/2,
+-export([build/4,
nodes_are_adjacent/3,
node_spill_cost/2,
node_adj_list/2,
@@ -38,8 +32,8 @@
spill_costs/1,
adj_list/1,
%% adj_set/1,
- add_edge/4,
- remove_edge/4,
+ add_edge/5,
+ remove_edge/5,
%% set_adj_set/2,
%% set_adj_list/2,
%% set_ig_moves/2,
@@ -64,6 +58,9 @@
-include("../flow/cfg.hrl").
-include("hipe_spillcost.hrl").
+-type target_context() :: any().
+-type target() :: {TargetMod :: module(), TargetContext :: target_context()}.
+
%%----------------------------------------------------------------------
-record(igraph, {adj_set, adj_list, ig_moves, degree,
@@ -78,11 +75,11 @@
%% degree, and testing for trivial colourability (degree < K).
%%----------------------------------------------------------------------
-degree_new(No_temporaries, Target) ->
+degree_new(No_temporaries, {TargetMod, TargetCtx}) ->
Degree = hipe_bifs:array(No_temporaries, 0),
- K = length(Target:allocatable()),
+ K = length(TargetMod:allocatable(TargetCtx)),
Inf = K + No_temporaries,
- precoloured_to_inf_degree(Target:all_precoloured(), Inf, Degree).
+ precoloured_to_inf_degree(TargetMod:all_precoloured(TargetCtx), Inf, Degree).
precoloured_to_inf_degree([], _Inf, Degree) -> Degree;
precoloured_to_inf_degree([P|Ps], Inf, Degree) ->
@@ -344,7 +341,7 @@ set_spill_costs(Spill_costs, IG) -> IG#igraph{spill_costs = Spill_costs}.
%% A new interference record
%%----------------------------------------------------------------------
--spec initial_ig(non_neg_integer(), atom()) -> #igraph{}.
+-spec initial_ig(non_neg_integer(), target()) -> #igraph{}.
initial_ig(NumTemps, Target) ->
#igraph{adj_set = adjset_new(NumTemps),
@@ -361,20 +358,21 @@ initial_ig(NumTemps, Target) ->
%% Description: Constructs an interference graph for the specifyed CFG.
%%
%% Parameters:
-%% CFG -- A Control Flow Graph
-%% Target -- The module that contains the target-specific functions
+%% CFG -- A Control Flow Graph
+%% TargetMod -- The module that contains the target-specific functions
+%% TargetCtx -- Context data to pass to TargetMod
%%
%% Returns:
%% An interference graph for the given CFG.
%%----------------------------------------------------------------------
--spec build(#cfg{}, atom()) -> #igraph{}.
+-spec build(#cfg{}, Liveness::_, module(), target_context()) -> #igraph{}.
-build(CFG, Target) ->
- BBs_in_out_liveness = Target:analyze(CFG),
- Labels = Target:labels(CFG),
+build(CFG, BBs_in_out_liveness, TargetMod, TargetCtx) ->
+ Target = {TargetMod, TargetCtx},
+ Labels = TargetMod:labels(CFG, TargetCtx),
%% How many temporaries exist?
- NumTemps = Target:number_of_temporaries(CFG),
+ NumTemps = TargetMod:number_of_temporaries(CFG, TargetCtx),
IG0 = initial_ig(NumTemps, Target),
%%?debug_msg("initial adjset: ~p\n",[element(2, IG0)]),
%%?debug_msg("initial adjset array: ~.16b\n",[element(3, element(2, IG0))]),
@@ -395,7 +393,7 @@ build(CFG, Target) ->
%% CFG -- The Control Flow Graph that we constructs
%% the interference graph from.
%% Target -- The module containing the target-specific
-%% functions
+%% functions, along with its context data
%%
%% Returns:
%% An interference graph for the given CFG.
@@ -404,13 +402,11 @@ build(CFG, Target) ->
analyze_bbs([], _, IG, _, _) -> IG;
analyze_bbs([L|Ls], BBs_in_out_liveness, IG, CFG, Target) ->
% Get basic block associated with label L
- BB = Target:bb(CFG, L),
+ BB = bb(CFG, L, Target),
% Get basic block code
BB_code = hipe_bb:code(BB),
- % Temporaries that are live out from this basic block
- BB_liveout = Target:liveout(BBs_in_out_liveness, L),
- % Only temporary numbers
- BB_liveout_numbers = reg_numbers(BB_liveout, Target),
+ % Temporaries that are live out from this basic block, only numbers
+ BB_liveout_numbers = liveout(BBs_in_out_liveness, L, Target),
% {Liveness, New Interference Graph}
{_, New_ig, Ref} = analyze_bb_instructions(BB_code,
ordsets:from_list(BB_liveout_numbers),
@@ -433,7 +429,8 @@ analyze_bbs([L|Ls], BBs_in_out_liveness, IG, CFG, Target) ->
%% Live -- All temporaries that are live at the time.
%% Live is a set of temporary "numbers only".
%% IG -- The interference graph in it's current state
-%% Target -- The mopdule containing the target-specific functions
+%% Target -- The mopdule containing the target-specific functions,
+%% along with its context data.
%%
%% Returns:
%% Live -- Temporaries that are live at entery of basic block
@@ -449,7 +446,7 @@ analyze_bb_instructions([Instruction|Instructions], Live, IG, Target) ->
{Live0, IG0, Ref} = analyze_bb_instructions(Instructions, Live,
IG, Target),
%% Check for temporaries that are defined and used in instruction
- {Def, Use} = Target:def_use(Instruction),
+ {Def, Use} = def_use(Instruction, Target),
%% Convert to register numbers
Def_numbers = ordsets:from_list(reg_numbers(Def, Target)),
Use_numbers = ordsets:from_list(reg_numbers(Use, Target)),
@@ -501,14 +498,15 @@ analyze_bb_instructions([Instruction|Instructions], Live, IG, Target) ->
%% Def_numbers -- Temporaries that are defined at this instruction
%% Use_numbers -- Temporaries that are used at this instruction
%% IG -- The interference graph in its current state
-%% Target -- The module containing the target-specific functions
+%% Target -- The module containing the target-specific functions, along
+%% with its context data
%% Returns:
%% Live -- An updated live set
%% IG -- An updated interference graph
%%----------------------------------------------------------------------
analyze_move(Instruction, Live, Def_numbers, Use_numbers, IG, Target) ->
- case Target:is_move(Instruction) of
+ case is_move(Instruction,Target) of
true ->
case {Def_numbers, Use_numbers} of
{[Dst], [Src]} ->
@@ -554,8 +552,9 @@ interfere([Define|Defines], Living, IG, Target) ->
%% Live -- Current live set
%% Lives -- Rest of living temporaries.
%% IG -- An interference graph
-%% Target -- The module containing the target-specific functions
-%% Returns:
+%% Target -- The module containing the target-specific functions, along
+%% with its context data.
+%% Returns:
%% An updated interference graph
%%----------------------------------------------------------------------
@@ -623,11 +622,15 @@ get_moves(IG) ->
%% Parameters:
%% U -- A temporary number
%% V -- A temporary number
-%% Target -- The module containing the target-specific functions
+%% TargetMod -- The module containing the target-specific functions.
+%% TargetCtx -- Context data to pass to TargetMod
%% Returns:
%% An updated interference graph.
%%----------------------------------------------------------------------
+add_edge(U, V, IG, TargetMod, TargetCtx) ->
+ add_edge(U, V, IG, {TargetMod, TargetCtx}).
+
add_edge(U, U, IG, _) -> IG;
add_edge(U, V, IG, Target) ->
case nodes_are_adjacent(U, V, IG) of
@@ -652,11 +655,15 @@ add_edge(U, V, IG, Target) ->
%% Parameters:
%% U -- A temporary number
%% V -- A temporary number
-%% Target -- The module containing the target-specific functions
+%% TargetMod -- The module containing the target-specific functions.
+%% TargetCtx -- Context data for TargetMod.
%% Returns:
%% An updated interference graph.
%%----------------------------------------------------------------------
+remove_edge(U, V, IG, TargetMod, TargetCtx) ->
+ remove_edge(U, V, IG, {TargetMod, TargetCtx}).
+
remove_edge(U, U, IG, _) -> IG;
remove_edge(U, V, IG, Target) ->
case nodes_are_adjacent(U, V, IG) of
@@ -683,8 +690,8 @@ remove_edge(U, V, IG, Target) ->
%% precoloured.
%% Adj_list -- An adj_list
%% Degree -- The degree that all nodes currently have
-%% Target -- The module containing the target-specific
-%% functions
+%% Target -- The module containing the target-specific
+%% functions, along with its context data.
%%
%% Returns:
%% Adj_list -- An updated adj_list data structure
@@ -692,7 +699,7 @@ remove_edge(U, V, IG, Target) ->
%%----------------------------------------------------------------------
remove_if_uncolored(Temp, InterfereTemp, Adj_list, Degree, Target) ->
- case Target:is_precoloured(Temp) of
+ case is_precoloured(Temp,Target) of
false ->
New_adj_list = hipe_adj_list:remove_edge(Temp, InterfereTemp, Adj_list),
degree_dec(Temp, Degree),
@@ -714,8 +721,8 @@ remove_if_uncolored(Temp, InterfereTemp, Adj_list, Degree, Target) ->
%% precoloured.
%% Adj_list -- An adj_list
%% Degree -- The degree that all nodes currently have
-%% Target -- The module containing the target-specific
-%% functions
+%% Target -- The module containing the target-specific
+%% functions, along with its context data.
%%
%% Returns:
%% Adj_list -- An updated adj_list data structure
@@ -723,7 +730,7 @@ remove_if_uncolored(Temp, InterfereTemp, Adj_list, Degree, Target) ->
%%----------------------------------------------------------------------
interfere_if_uncolored(Temp, InterfereTemp, Adj_list, Degree, Target) ->
- case Target:is_precoloured(Temp) of
+ case is_precoloured(Temp, Target) of
false ->
New_adj_list = hipe_adj_list:add_edge(Temp, InterfereTemp, Adj_list),
degree_inc(Temp, Degree),
@@ -740,13 +747,14 @@ interfere_if_uncolored(Temp, InterfereTemp, Adj_list, Degree, Target) ->
%%
%% Parameters:
%% TRs -- A list of temporary registers
-%% Target -- The module containing the target-specific functions
+%% Target -- The module containing the target-specific functions, along with
+%% its context data.
%% Returns:
%% A list of register numbers.
%%----------------------------------------------------------------------
-reg_numbers(Regs, Target) ->
- [Target:reg_nr(X) || X <- Regs].
+reg_numbers(Regs, {TgtMod, TgtCtx}) ->
+ [TgtMod:reg_nr(X,TgtCtx) || X <- Regs].
%%---------------------------------------------------------------------
%% Print functions - only used for debugging
@@ -775,3 +783,24 @@ dec_node_degree(Node, IG) ->
is_trivially_colourable(Node, K, IG) ->
degree_is_trivially_colourable(Node, K, degree(IG)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Interface to external functions.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+bb(CFG, L, {TgtMod,TgtCtx}) ->
+ TgtMod:bb(CFG,L,TgtCtx).
+
+def_use(Instruction, {TgtMod,TgtCtx}) ->
+ TgtMod:def_use(Instruction, TgtCtx).
+
+is_move(Instruction, {TgtMod,TgtCtx}) ->
+ TgtMod:is_move(Instruction, TgtCtx).
+
+is_precoloured(R, {TgtMod,TgtCtx}) ->
+ TgtMod:is_precoloured(R,TgtCtx).
+
+liveout(Liveness,L, Target={TgtMod,TgtCtx}) ->
+ reg_numbers(TgtMod:liveout(Liveness,L,TgtCtx), Target).
diff --git a/lib/hipe/regalloc/hipe_ig_moves.erl b/lib/hipe/regalloc/hipe_ig_moves.erl
index b679453de0..e193a682bf 100644
--- a/lib/hipe/regalloc/hipe_ig_moves.erl
+++ b/lib/hipe/regalloc/hipe_ig_moves.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%=============================================================================
@@ -25,8 +19,6 @@
new_move/3,
get_moves/1]).
--include("../util/hipe_vectors.hrl").
-
%%-----------------------------------------------------------------------------
%% The main data structure; its fields are:
%% - movelist : mapping from temp to set of associated move numbers
@@ -34,11 +26,13 @@
%% - moveinsns : list of move instructions, in descending move number order
%% - moveset : set of move instructions
--record(ig_moves, {movelist :: hipe_vector(),
+-record(ig_moves, {movelist :: movelist(),
nrmoves = 0 :: non_neg_integer(),
moveinsns = [] :: [{_,_}],
moveset = gb_sets:empty() :: gb_sets:set()}).
+-type movelist() :: hipe_vectors:vector(ordsets:ordset(non_neg_integer())).
+
%%-----------------------------------------------------------------------------
-spec new(non_neg_integer()) -> #ig_moves{}.
@@ -66,7 +60,8 @@ new_move(Dst, Src, IG_moves) ->
moveset = gb_sets:insert(MoveInsn, MoveSet)}
end.
--spec add_movelist(non_neg_integer(), non_neg_integer(), hipe_vector()) -> hipe_vector().
+-spec add_movelist(non_neg_integer(), non_neg_integer(), movelist())
+ -> movelist().
add_movelist(MoveNr, Temp, MoveList) ->
AssocMoves = hipe_vectors:get(MoveList, Temp),
@@ -74,7 +69,7 @@ add_movelist(MoveNr, Temp, MoveList) ->
%% ordset due to the ordsets:union in hipe_coalescing_regalloc:combine().
hipe_vectors:set(MoveList, Temp, ordsets:add_element(MoveNr, AssocMoves)).
--spec get_moves(#ig_moves{}) -> {hipe_vector(), non_neg_integer(), tuple()}.
+-spec get_moves(#ig_moves{}) -> {movelist(), non_neg_integer(), tuple()}.
get_moves(IG_moves) -> % -> {MoveList, NrMoves, MoveInsns}
{IG_moves#ig_moves.movelist,
diff --git a/lib/hipe/regalloc/hipe_ls_regalloc.erl b/lib/hipe/regalloc/hipe_ls_regalloc.erl
index d24b803524..785aa2b080 100644
--- a/lib/hipe/regalloc/hipe_ls_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_ls_regalloc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% =====================================================================
%% @doc
@@ -56,7 +50,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(hipe_ls_regalloc).
--export([regalloc/7]).
+-export([regalloc/9]).
%%-define(DEBUG,1).
-define(HIPE_INSTRUMENT_COMPILER, true).
@@ -95,11 +89,10 @@
%% </ol>
%% @end
%%- - - - - - - - - - - - - - - - - - - - - - - -
-regalloc(CFG, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options, Target) ->
+regalloc(CFG, Liveness, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options,
+ TargetMod, TargetContext) ->
+ Target = {TargetMod, TargetContext},
?debug_msg("LinearScan: ~w\n", [erlang:statistics(runtime)]),
- %% Step 1: Calculate liveness (Call external implementation.)
- Liveness = liveness(CFG, Target),
- ?debug_msg("liveness (done)~w\n", [erlang:statistics(runtime)]),
USIntervals = calculate_intervals(CFG, Liveness,
Entrypoints, Options, Target),
?debug_msg("intervals (done) ~w\n", [erlang:statistics(runtime)]),
@@ -108,10 +101,10 @@ regalloc(CFG, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options, Target) ->
%% ?debug_msg("Intervals ~w\n", [Intervals]),
?debug_msg("No intervals: ~w\n",[length(Intervals)]),
?debug_msg("count intervals (done) ~w\n", [erlang:statistics(runtime)]),
- Allocation = allocate(Intervals, PhysRegs, SpillIndex, DontSpill, Target),
+ {Coloring, NewSpillIndex}
+ = allocate(Intervals, PhysRegs, SpillIndex, DontSpill, Target),
?debug_msg("allocation (done) ~w\n", [erlang:statistics(runtime)]),
- Allocation.
-
+ {Coloring, NewSpillIndex}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%
@@ -125,32 +118,33 @@ regalloc(CFG, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options, Target) ->
%% Liveness: A map of live-in and live-out sets for each Basic-Block.
%% Entrypoints: A set of BB names that have external entrypoints.
%%
-calculate_intervals(CFG,Liveness,_Entrypoints, Options, Target) ->
+calculate_intervals(CFG,Liveness,_Entrypoints, Options,
+ Target={TgtMod,TgtCtx}) ->
%% Add start point for the argument registers.
Args = arg_vars(CFG, Target),
Interval =
- add_def_point(Args, 0, empty_interval(Target:number_of_temporaries(CFG))),
+ add_def_point(Args, 0, empty_interval(number_of_temporaries(CFG, Target))),
%% Interval = add_livepoint(Args, 0, empty_interval()),
Worklist =
case proplists:get_value(ls_order, Options) of
reversepostorder ->
- Target:reverse_postorder(CFG);
+ TgtMod:reverse_postorder(CFG, TgtCtx);
breadth ->
- Target:breadthorder(CFG);
+ TgtMod:breadthorder(CFG, TgtCtx);
postorder ->
- Target:postorder(CFG);
+ TgtMod:postorder(CFG, TgtCtx);
inorder ->
- Target:inorder(CFG);
+ TgtMod:inorder(CFG, TgtCtx);
reverse_inorder ->
- Target:reverse_inorder(CFG);
+ TgtMod:reverse_inorder(CFG, TgtCtx);
preorder ->
- Target:preorder(CFG);
+ TgtMod:preorder(CFG, TgtCtx);
prediction ->
- Target:predictionorder(CFG);
+ TgtMod:predictionorder(CFG, TgtCtx);
random ->
- Target:labels(CFG);
+ TgtMod:labels(CFG, TgtCtx);
_ ->
- Target:reverse_postorder(CFG)
+ TgtMod:reverse_postorder(CFG, TgtCtx)
end,
%% ?inc_counter(bbs_counter, length(Worklist)),
%% ?debug_msg("No BBs ~w\n",[length(Worklist)]),
@@ -290,7 +284,7 @@ allocate([RegInt|RIS], Free, Active, Alloc, SpillIndex, DontSpill, Target) ->
alloc(OtherTemp,NewPhys,NewAlloc),
SpillIndex, DontSpill, Target);
false ->
- NewSpillIndex = Target:new_spill_index(SpillIndex),
+ NewSpillIndex = new_spill_index(SpillIndex, Target),
{NewAlloc2, NewActive4} =
spill(OtherTemp, OtherEnd, OtherStart, NewActive3,
NewAlloc, SpillIndex, DontSpill, Target),
@@ -306,7 +300,7 @@ allocate([RegInt|RIS], Free, Active, Alloc, SpillIndex, DontSpill, Target) ->
case NewFree of
[] ->
%% No physical registers available, we have to spill.
- NewSpillIndex = Target:new_spill_index(SpillIndex),
+ NewSpillIndex = new_spill_index(SpillIndex, Target),
{NewAlloc, NewActive2} =
spill(Temp, endpoint(RegInt), startpoint(RegInt),
Active, Alloc, SpillIndex, DontSpill, Target),
@@ -752,38 +746,41 @@ create_freeregs([]) ->
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-liveness(CFG, Target) ->
- Target:analyze(CFG).
+bb(CFG, L, {TgtMod, TgtCtx}) ->
+ TgtMod:bb(CFG,L,TgtCtx).
+
+livein(Liveness,L, Target={TgtMod,TgtCtx}) ->
+ regnames(TgtMod:livein(Liveness,L,TgtCtx), Target).
-bb(CFG, L, Target) ->
- Target:bb(CFG,L).
+liveout(Liveness,L, Target={TgtMod,TgtCtx}) ->
+ regnames(TgtMod:liveout(Liveness,L,TgtCtx), Target).
-livein(Liveness,L, Target) ->
- regnames(Target:livein(Liveness,L), Target).
+uses(I, Target={TgtMod,TgtCtx}) ->
+ regnames(TgtMod:uses(I,TgtCtx), Target).
-liveout(Liveness,L, Target) ->
- regnames(Target:liveout(Liveness,L), Target).
+defines(I, Target={TgtMod,TgtCtx}) ->
+ regnames(TgtMod:defines(I,TgtCtx), Target).
-uses(I, Target) ->
- regnames(Target:uses(I), Target).
+is_precoloured(R, {TgtMod,TgtCtx}) ->
+ TgtMod:is_precoloured(R,TgtCtx).
-defines(I, Target) ->
- regnames(Target:defines(I), Target).
+is_global(R, {TgtMod,TgtCtx}) ->
+ TgtMod:is_global(R,TgtCtx).
-is_precoloured(R, Target) ->
- Target:is_precoloured(R).
+new_spill_index(SpillIndex, {TgtMod,TgtCtx}) ->
+ TgtMod:new_spill_index(SpillIndex, TgtCtx).
-is_global(R, Target) ->
- Target:is_global(R).
+number_of_temporaries(CFG, {TgtMod,TgtCtx}) ->
+ TgtMod:number_of_temporaries(CFG, TgtCtx).
-physical_name(R, Target) ->
- Target:physical_name(R).
+physical_name(R, {TgtMod,TgtCtx}) ->
+ TgtMod:physical_name(R,TgtCtx).
-regnames(Regs, Target) ->
- [Target:reg_nr(X) || X <- Regs].
+regnames(Regs, {TgtMod,TgtCtx}) ->
+ [TgtMod:reg_nr(X,TgtCtx) || X <- Regs].
-arg_vars(CFG, Target) ->
- Target:args(CFG).
+arg_vars(CFG, {TgtMod,TgtCtx}) ->
+ TgtMod:args(CFG,TgtCtx).
-is_arg(Reg, Target) ->
- Target:is_arg(Reg).
+is_arg(Reg, {TgtMod,TgtCtx}) ->
+ TgtMod:is_arg(Reg,TgtCtx).
diff --git a/lib/hipe/regalloc/hipe_moves.erl b/lib/hipe/regalloc/hipe_moves.erl
index 39ccfb4a2f..409217bb03 100644
--- a/lib/hipe/regalloc/hipe_moves.erl
+++ b/lib/hipe/regalloc/hipe_moves.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_moves).
-export([new/1,
diff --git a/lib/hipe/regalloc/hipe_node_sets.erl b/lib/hipe/regalloc/hipe_node_sets.erl
index 01922a34d4..3cdfb62090 100644
--- a/lib/hipe/regalloc/hipe_node_sets.erl
+++ b/lib/hipe/regalloc/hipe_node_sets.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_node_sets).
diff --git a/lib/hipe/regalloc/hipe_optimistic_regalloc.erl b/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
index 2ed9ec3b45..a019c46b90 100644
--- a/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-----------------------------------------------------------------------
%% File : hipe_optimistic_regalloc.erl
@@ -29,7 +23,7 @@
%%-----------------------------------------------------------------------
-module(hipe_optimistic_regalloc).
--export([regalloc/5]).
+-export([regalloc/7]).
-ifndef(DEBUG).
%%-define(DEBUG,true).
@@ -74,20 +68,22 @@
%% SpillLimit -- Temporaris with numbers higher than this have
%% infinit spill cost.
%% Consider changing this to a set.
-%% Target -- The module containing the target-specific functions.
+%% TgtMod -- The module containing the target-specific functions.
+%% TgtCtx -- Context data for TgtMod
%%
%% Returns:
%% Coloring -- A coloring for specified CFG
-%% SpillIndex0 -- A new spill index
+%% SpillIndex2 -- A new spill index
%%-----------------------------------------------------------------------
-ifdef(COMPARE_ITERATED_OPTIMISTIC).
-regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
- ?debug_msg("optimistic ~w\n",[Target]),
+regalloc(CFG, Liveness, SpillIndex, SpillLimit, TgtMod, TgtCtx, _Options) ->
+ Target = {TgtMod, TgtCtx},
+ ?debug_msg("optimistic ~w\n",[TgtMod]),
?debug_msg("CFG: ~p\n",[CFG]),
%% Build interference graph
?debug_msg("Build IG\n",[]),
- IG_O = hipe_ig:build(CFG, Target),
- IG = hipe_ig:build(CFG, Target),
+ IG_O = hipe_ig:build(CFG, Liveness, TgtMod, TgtCtx),
+ IG = hipe_ig:build(CFG, Liveness, TgtMod, TgtCtx),
?debug_msg("adjlist: ~p\n",[hipe_ig:adj_list(IG)]),
?debug_msg("IG:\n",[]),
?print_adjacent(IG),
@@ -98,9 +94,9 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
SavedAdjList = hipe_ig:adj_list(IG),
?debug_msg("Init\n",[]),
- No_temporaries = Target:number_of_temporaries(CFG),
+ No_temporaries = number_of_temporaries(CFG, Target),
?debug_msg("Coalescing RA: num_temps = ~p~n", [No_temporaries]),
- Allocatable = Target:allocatable(),
+ Allocatable = allocatable(Target),
K = length(Allocatable),
All_colors = colset_from_list(Allocatable),
?debug_msg("K: ~w~nAll_colors: ~p\n",[K, All_colors]),
@@ -113,11 +109,13 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
?mov_print_memberships(Move_sets),
?debug_msg("Build Worklist\n",[]),
- Worklists_O = hipe_reg_worklists:new(IG_O, Target, CFG, Move_sets_O, K, No_temporaries),
+ Worklists_O = hipe_reg_worklists:new(IG_O, TgtMod, TgtCtx, CFG, Move_sets_O,
+ K, No_temporaries),
?debug_msg("Worklists:\n ~p\n", [Worklists_O]),
?reg_print_memberships(Worklists_O),
- Worklists = hipe_reg_worklists:new(IG, Target, CFG, K, No_temporaries),
+ Worklists = hipe_reg_worklists:new(IG, TgtMod, TgtCtx, CFG, K,
+ No_temporaries),
?debug_msg("New Worklists:\n ~p\n", [Worklists]),
?reg_print_memberships(Worklists),
@@ -175,10 +173,10 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
?debug_msg("Init node sets\n",[]),
Node_sets = hipe_node_sets:new(),
- %% ?debug_msg("NodeSet: ~w\n NonAlloc ~w\n",[Node_sets,Target:non_alloc(CFG)]),
+ %% ?debug_msg("NodeSet: ~w\n NonAlloc ~w\n",[Node_sets,non_alloc(CFG,Target)]),
?debug_msg("Default coloring\n",[]),
{Color0,Node_sets1} =
- defaultColoring(Target:all_precoloured(),
+ defaultColoring(all_precoloured(Target),
initColor(No_temporaries), Node_sets, Target),
?debug_msg("Color0\n",[]),
?print_colors(No_temporaries, Color0),
@@ -199,9 +197,10 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
?debug_msg("Nodes:~w\nNodes2:~w\nNo_temporaries:~w\n",[Node_sets,Node_sets2,No_temporaries]),
?debug_msg("Build mapping _N ~w\n",[Node_sets2]),
- Coloring = build_namelist(Node_sets2,SpillIndex,Alias2,Color1),
+ {Coloring,SpillIndex2} =
+ build_namelist(Node_sets2,SpillIndex,Alias2,Color1),
?debug_msg("Coloring ~p\n",[Coloring]),
- SortedColoring = { sort_stack(element(1, Coloring)), element(2, Coloring)},
+ SortedColoring = {sort_stack(Coloring), SpillIndex2},
?debug_msg("SortedColoring ~p\n",[SortedColoring]),
%%Coloring.
?debug_msg("----------------------Assign colors _O\n",[]),
@@ -217,14 +216,15 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
SortedColoring_O = {sort_stack(element(1, Coloring_O)), element(2, Coloring_O)},
?debug_msg("SortedColoring_O ~p\n",[SortedColoring_O]),
sanity_compare(SortedColoring_O, SortedColoring),
- Coloring.
+ {Coloring,SpillIndex2}.
-else.
-regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
- ?debug_msg("optimistic ~w\n",[Target]),
+regalloc(CFG, Liveness, SpillIndex, SpillLimit, TgtMod, TgtCtx, _Options) ->
+ Target = {TgtMod, TgtCtx},
+ ?debug_msg("optimistic ~w\n",[TgtMod]),
?debug_msg("CFG: ~p\n",[CFG]),
%% Build interference graph
?debug_msg("Build IG\n",[]),
- IG = hipe_ig:build(CFG, Target),
+ IG = hipe_ig:build(CFG, Liveness, TgtMod, TgtCtx),
?debug_msg("adjlist: ~p\n",[hipe_ig:adj_list(IG)]),
?debug_msg("IG:\n",[]),
?print_adjacent(IG),
@@ -235,9 +235,9 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
SavedAdjList = hipe_ig:adj_list(IG),
?debug_msg("Init\n",[]),
- No_temporaries = Target:number_of_temporaries(CFG),
+ No_temporaries = number_of_temporaries(CFG, Target),
?debug_msg("Coalescing RA: num_temps = ~p~n", [No_temporaries]),
- Allocatable = Target:allocatable(),
+ Allocatable = allocatable(Target),
K = length(Allocatable),
All_colors = colset_from_list(Allocatable),
?debug_msg("K: ~w~nAll_colors: ~p\n",[K, All_colors]),
@@ -250,7 +250,8 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
?debug_msg("Build Worklist\n",[]),
- Worklists = hipe_reg_worklists:new(IG, Target, CFG, K, No_temporaries),
+ Worklists = hipe_reg_worklists:new(IG, TgtMod, TgtCtx, CFG, K,
+ No_temporaries),
?debug_msg("New Worklists:\n ~p\n", [Worklists]),
?reg_print_memberships(Worklists),
@@ -292,10 +293,10 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
?debug_msg("Init node sets\n",[]),
Node_sets = hipe_node_sets:new(),
- %% ?debug_msg("NodeSet: ~w\n NonAlloc ~w\n",[Node_sets,Target:non_alloc(CFG)]),
+ %% ?debug_msg("NodeSet: ~w\n NonAlloc ~w\n",[Node_sets,non_alloc(CFG,Target)]),
?debug_msg("Default coloring\n",[]),
{Color0,Node_sets1} =
- defaultColoring(Target:all_precoloured(),
+ defaultColoring(all_precoloured(Target),
initColor(No_temporaries), Node_sets, Target),
?debug_msg("Color0\n",[]),
?print_colors(No_temporaries, Color0),
@@ -316,9 +317,9 @@ regalloc(CFG, SpillIndex, SpillLimit, Target, _Options) ->
?debug_msg("Nodes:~w\nNodes2:~w\nNo_temporaries:~w\n",[Node_sets,Node_sets2,No_temporaries]),
?debug_msg("Build mapping _N ~w\n",[Node_sets2]),
- Coloring = build_namelist(Node_sets2,SpillIndex,Alias2,Color1),
+ {Coloring, SpillIndex2} = build_namelist(Node_sets2,SpillIndex,Alias2,Color1),
?debug_msg("Coloring ~p\n",[Coloring]),
- Coloring.
+ {Coloring,SpillIndex2}.
-endif.
%%----------------------------------------------------------------------
@@ -834,7 +835,8 @@ sort_stack_split(Pivot, [H|T], Smaller, Bigger) ->
%% been coalesced, this mapping shows the alias for that
%% node.
%% AllColors -- This is an ordset containing all the available colors
-%% Target -- The module containing the target-specific functions.
+%% Target -- The module containing the target-specific functions,
+%% along with its context data.
%%
%% Returns:
%% Color -- A mapping from nodes to their respective color.
@@ -874,7 +876,7 @@ assignColors(Worklists, Stack, NodeSets, Color, No_Temporaries,
false -> % Color case
Col = colset_smallest(OkColors),
NodeSets1 = hipe_node_sets:add_colored(Node, NodeSets),
- Color1 = setColor(Node, Target:physical_name(Col), Color),
+ Color1 = setColor(Node, physical_name(Col,Target), Color),
?debug_msg("Color case. Assigning color ~p to node.~n", [Col]),
assignColors(Worklists, Stack1, NodeSets1, Color1, No_Temporaries, SavedAdjList, SavedSpillCosts, IG, Alias, AllColors, Target)
end
@@ -902,7 +904,8 @@ assignColors(Worklists, Stack, NodeSets, Color, No_Temporaries,
%% Alias -- This is a mapping from nodes to nodes. If a node has
%% been coalesced, this mapping shows the alias for that
%% node.
-%% Target -- The module containing the target-specific functions.
+%% Target -- The module containing the target-specific functions,
+%% along with its context data.
%%
%% Returns:
%% Alias -- The restored aliases after the uncoalescing.
@@ -1006,7 +1009,7 @@ colorSplit([], _Col, NodeSets, Color, _Target) ->
colorSplit([Node|Nodes], Col, NodeSets, Color, Target) ->
?debug_msg(" Coloring node ~p with color ~p.~n", [Node, Col]),
NodeSets1 = hipe_node_sets:add_colored(Node, NodeSets),
- Color1 = setColor(Node, Target:physical_name(Col), Color),
+ Color1 = setColor(Node, physical_name(Col,Target), Color),
colorSplit(Nodes, Col, NodeSets1, Color1, Target).
%% Place non-colorable nodes in a split at the bottom of the SelectStack.
@@ -1035,7 +1038,8 @@ enqueueSplit([Node|Nodes], IG, Stack) ->
%% node.
%% AllColors -- This is an ordset containing all the available colors
%%
-%% Target -- The module containing the target-specific functions.
+%% Target -- The module containing the target-specific functions,
+%% along with its context data.
%%
%% Returns:
%% Color -- A mapping from nodes to their respective color.
@@ -1065,7 +1069,7 @@ assignColors_O(Stack,NodeSets,Color,Alias,AllColors,Target) ->
false -> % Colour case
Col = colset_smallest(OkColors),
NodeSets1 = hipe_node_sets:add_colored(Node, NodeSets),
- Color1 = setColor(Node, Target:physical_name(Col), Color),
+ Color1 = setColor(Node, physical_name(Col,Target), Color),
assignColors_O(Stack1, NodeSets1, Color1, Alias, AllColors, Target)
end
end.
@@ -1079,7 +1083,8 @@ assignColors_O(Stack,NodeSets,Color,Alias,AllColors,Target) ->
%% Regs -- The list of registers to be default colored
%% Color -- The color mapping that shall be changed
%% NodeSets -- The node sets that shall be updated
-%% Target -- The module containing the target-specific functions.
+%% Target -- The module containing the target-specific functions,
+%% along with its context data.
%%
%% Returns:
%% NewColor -- The updated color mapping
@@ -1089,7 +1094,7 @@ assignColors_O(Stack,NodeSets,Color,Alias,AllColors,Target) ->
defaultColoring([], Color, NodeSets, _Target) ->
{Color,NodeSets};
defaultColoring([Reg|Regs], Color, NodeSets, Target) ->
- Color1 = setColor(Reg,Target:physical_name(Reg), Color),
+ Color1 = setColor(Reg,physical_name(Reg,Target), Color),
NodeSets1 = hipe_node_sets:add_colored(Reg, NodeSets),
defaultColoring(Regs, Color1, NodeSets1, Target).
@@ -1283,7 +1288,7 @@ coalesce(Moves, IG, Worklists, Alias, K, Target) ->
?debug_msg("Testing nodes ~p and ~p for coalescing~n",[Dest,Source]),
Alias_src = getAlias(Source, Alias),
Alias_dst = getAlias(Dest, Alias),
- {U,V} = case Target:is_precoloured(Alias_dst) of
+ {U,V} = case is_precoloured(Alias_dst, Target) of
true -> {Alias_dst, Alias_src};
false -> {Alias_src, Alias_dst}
end,
@@ -1293,13 +1298,13 @@ coalesce(Moves, IG, Worklists, Alias, K, Target) ->
%% drop coalesced move Move
{Moves0, IG, Alias, Worklists};
_ ->
- case (Target:is_precoloured(V) orelse
+ case (is_precoloured(V, Target) orelse
hipe_ig:nodes_are_adjacent(U, V, IG)) of
true ->
%% drop constrained move Move
{Moves0, IG, Alias, Worklists};
false ->
- case (case Target:is_precoloured(U) of
+ case (case is_precoloured(U, Target) of
true ->
AdjV = hipe_ig:node_adj_list(V, IG),
all_adjacent_ok(AdjV, U, Worklists, IG, K, Target);
@@ -1350,7 +1355,7 @@ coalesce_O(Moves, IG, Worklists, Alias, K, Target) ->
?debug_msg("Testing nodes ~p and ~p for coalescing~n",[Dest,Source]),
Alias_src = getAlias(Source, Alias),
Alias_dst = getAlias(Dest, Alias),
- {U,V} = case Target:is_precoloured(Alias_dst) of
+ {U,V} = case is_precoloured(Alias_dst, Target) of
true -> {Alias_dst, Alias_src};
false -> {Alias_src, Alias_dst}
end,
@@ -1361,7 +1366,7 @@ coalesce_O(Moves, IG, Worklists, Alias, K, Target) ->
Worklists1 = add_worklist(Worklists, U, K, Moves1, IG, Target),
{Moves1, IG, Worklists1, Alias};
_ ->
- case (Target:is_precoloured(V) orelse
+ case (is_precoloured(V, Target) orelse
hipe_ig:nodes_are_adjacent(U, V, IG)) of
true ->
Moves1 = Moves0, % drop constrained move Move
@@ -1369,7 +1374,7 @@ coalesce_O(Moves, IG, Worklists, Alias, K, Target) ->
Worklists2 = add_worklist(Worklists1, V, K, Moves1, IG, Target),
{Moves1, IG, Worklists2, Alias};
false ->
- case (case Target:is_precoloured(U) of
+ case (case is_precoloured(U, Target) of
true ->
AdjV = hipe_ig:node_adj_list(V, IG),
all_adjacent_ok(AdjV, U, Worklists, IG, K, Target);
@@ -1405,7 +1410,8 @@ coalesce_O(Moves, IG, Worklists, Alias, K, Target) ->
%% K -- Number of registers
%% Moves -- Current move information
%% IG -- Interference graph
-%% Target -- The containing the target-specific functions
+%% Target -- The containing the target-specific functions, along with
+%% its context data.
%%
%% Returns:
%% Worklists (updated)
@@ -1413,7 +1419,7 @@ coalesce_O(Moves, IG, Worklists, Alias, K, Target) ->
-ifdef(COMPARE_ITERATED_OPTIMISTIC).
add_worklist(Worklists, U, K, Moves, IG, Target) ->
- case (not(Target:is_precoloured(U))
+ case (not(is_precoloured(U, Target))
andalso not(hipe_moves:move_related(U, Moves))
andalso (hipe_ig:is_trivially_colourable(U, K, IG))) of
true ->
@@ -1524,12 +1530,12 @@ combine(U, V, IG, Alias, Worklists, K, Target) ->
combine_edges([], _U, IG, _Worklists, _K, _Target) ->
IG;
-combine_edges([T|Ts], U, IG, Worklists, K, Target) ->
+combine_edges([T|Ts], U, IG, Worklists, K, Target={TgtMod,TgtCtx}) ->
case hipe_reg_worklists:member_stack_or_coalesced(T, Worklists) of
true -> combine_edges(Ts, U, IG, Worklists, K, Target);
_ ->
- IG1 = hipe_ig:add_edge(T, U, IG, Target),
- IG2 = case Target:is_precoloured(T) of
+ IG1 = hipe_ig:add_edge(T, U, IG, TgtMod, TgtCtx),
+ IG2 = case is_precoloured(T, Target) of
true -> IG1;
false -> hipe_ig:dec_node_degree(T, IG1)
end,
@@ -1559,7 +1565,7 @@ combine_edges([T|Ts], U, IG, Worklists, K, Target) ->
-ifdef(COMPARE_ITERATED_OPTIMISTIC).
combine_edges_O([], _U, IG, Worklists, Moves, _K, _Target) ->
{IG, Worklists, Moves};
-combine_edges_O([T|Ts], U, IG, Worklists, Moves, K, Target) ->
+combine_edges_O([T|Ts], U, IG, Worklists, Moves, K, Target={TgtMod,TgtCtx}) ->
case hipe_reg_worklists:member_stack_or_coalesced(T, Worklists) of
true -> combine_edges_O(Ts, U, IG, Worklists, Moves, K, Target);
_ ->
@@ -1576,7 +1582,7 @@ combine_edges_O([T|Ts], U, IG, Worklists, Moves, K, Target) ->
%% worklist, and that's where decrement_degree() expects to find it.
%% This issue is not covered in the published algorithm.
OldDegree = hipe_ig:get_node_degree(T, IG),
- IG1 = hipe_ig:add_edge(T, U, IG, Target),
+ IG1 = hipe_ig:add_edge(T, U, IG, TgtMod, TgtCtx),
NewDegree = hipe_ig:get_node_degree(T, IG1),
Worklists0 =
if NewDegree =:= K, OldDegree =:= K-1 ->
@@ -1609,7 +1615,8 @@ combine_edges_O([T|Ts], U, IG, Worklists, Moves, K, Target) ->
%% Alias -- The Alias vector before undoing
%% SavedAdj -- Saved adjacency list
%% IG -- Interference graph
-%% Target -- The module containing the target-specific functions.
+%% Target -- The module containing the target-specific functions,
+%% along with its context data.
%%
%% Returns:
%% list of primitive nodes, that is all nodes that were previously
@@ -1676,7 +1683,8 @@ findPrimitiveNodes(Node, N, Alias, PrimitiveNodes) ->
%% N -- Node that should be uncoalesced
%% SavedAdj -- Saved adjacency list
%% IG -- Interference graph
-%% Target -- The module containing the target-specific functions.
+%% Target -- The module containing the target-specific functions, along
+%% with its context data.
%%
%% Returns:
%% updated Interferece graph
@@ -1702,16 +1710,16 @@ fixAdj(N, SavedAdj, IG, Target) ->
removeAdj([], _N, _IG, _Target) ->
true;
-removeAdj([V| New], N, IG, Target) ->
- hipe_ig:remove_edge(V, N, IG, Target),
+removeAdj([V| New], N, IG, Target={TgtMod,TgtCtx}) ->
+ hipe_ig:remove_edge(V, N, IG, TgtMod, TgtCtx),
removeAdj(New, N, IG, Target).
%%restoreAdj([], _N, IG, _Alias, _Target) ->
%% %%?debug_msg("adj_lists__after_restore_o ~n~p~n", [hipe_ig:adj_list(IG)]),
%% IG;
-%%restoreAdj([V| AdjToN], N, IG, Alias, Target) ->
+%%restoreAdj([V| AdjToN], N, IG, Alias, Target={TgtMod,TgtCtx}) ->
%% AliasToV = getAlias(V, Alias),
-%% IG1 = hipe_ig:add_edge(N, AliasToV, IG, Target),
+%% IG1 = hipe_ig:add_edge(N, AliasToV, IG, TgtMod, TgtCtx),
%% restoreAdj(AdjToN, N, IG1, Alias, Target).
%% XXX This is probably a clumsy way of doing it
@@ -1744,7 +1752,8 @@ findNew([A| Adj], Saved, New) ->
%% R -- Other node to test
%% IG -- Interference graph
%% K -- Number of registers
-%% Target -- The module containing the target-specific functions
+%% Target -- The module containing the target-specific functions, along
+%% with its context data.
%%
%% Returns:
%% true iff coalescing is OK
@@ -1752,7 +1761,7 @@ findNew([A| Adj], Saved, New) ->
ok(T, R, IG, K, Target) ->
((hipe_ig:is_trivially_colourable(T, K, IG))
- orelse Target:is_precoloured(T)
+ orelse is_precoloured(T, Target)
orelse hipe_ig:nodes_are_adjacent(T, R, IG)).
%%----------------------------------------------------------------------
@@ -1765,7 +1774,8 @@ ok(T, R, IG, K, Target) ->
%% U -- Node to test for coalescing
%% IG -- Interference graph
%% K -- Number of registers
-%% Target -- The module containing the target-specific functions
+%% Target -- The module containing the target-specific functions, along
+%% with its context data.
%%
%% Returns:
%% true iff coalescing is OK for all nodes in the list
@@ -1923,7 +1933,7 @@ findCheapest([Node|Nodes], IG, Cost, Cheapest, SpillLimit) ->
%% limit are extremely expensive.
getCost(Node, IG, SpillLimit) ->
- case Node > SpillLimit of
+ case Node >= SpillLimit of
true -> inf;
false ->
SpillCost = hipe_ig:node_spill_cost(Node, IG),
@@ -2042,3 +2052,24 @@ freezeEm3(_U,V,_M,K,WorkLists,Moves,IG,_Alias) ->
{WorkLists,Moves1}
end.
-endif.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Interface to external functions.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all_precoloured({TgtMod,TgtCtx}) ->
+ TgtMod:all_precoloured(TgtCtx).
+
+allocatable({TgtMod,TgtCtx}) ->
+ TgtMod:allocatable(TgtCtx).
+
+is_precoloured(R, {TgtMod,TgtCtx}) ->
+ TgtMod:is_precoloured(R,TgtCtx).
+
+number_of_temporaries(CFG, {TgtMod,TgtCtx}) ->
+ TgtMod:number_of_temporaries(CFG, TgtCtx).
+
+physical_name(R, {TgtMod,TgtCtx}) ->
+ TgtMod:physical_name(R,TgtCtx).
diff --git a/lib/hipe/regalloc/hipe_ppc_specific.erl b/lib/hipe/regalloc/hipe_ppc_specific.erl
index c49b1e510f..81bb551bd2 100644
--- a/lib/hipe/regalloc/hipe_ppc_specific.erl
+++ b/lib/hipe/regalloc/hipe_ppc_specific.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,121 +11,138 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_specific).
%% for hipe_coalescing_regalloc:
--export([number_of_temporaries/1
- ,analyze/1
- ,labels/1
- ,all_precoloured/0
- ,bb/2
- ,liveout/2
- ,reg_nr/1
- ,def_use/1
- ,is_move/1
- ,is_precoloured/1
- ,var_range/1
- ,allocatable/0
- ,non_alloc/1
- ,physical_name/1
- ,reverse_postorder/1
- ,livein/2
- ,uses/1
- ,defines/1
+-export([number_of_temporaries/2
+ ,analyze/2
+ ,labels/2
+ ,all_precoloured/1
+ ,bb/3
+ ,liveout/3
+ ,reg_nr/2
+ ,def_use/2
+ ,is_move/2
+ ,is_spill_move/2
+ ,is_precoloured/2
+ ,var_range/2
+ ,allocatable/1
+ ,non_alloc/2
+ ,physical_name/2
+ ,reverse_postorder/2
+ ,livein/3
+ ,uses/2
+ ,defines/2
+ ,defines_all_alloc/2
]).
%% for hipe_graph_coloring_regalloc:
--export([is_fixed/1]).
+-export([is_fixed/2]).
%% for hipe_ls_regalloc:
--export([args/1, is_arg/1, is_global/1, new_spill_index/1]).
--export([breadthorder/1, postorder/1]).
+-export([args/2, is_arg/2, is_global/2, new_spill_index/2]).
+-export([breadthorder/2, postorder/2]).
%% callbacks for hipe_regalloc_loop
--export([defun_to_cfg/1,
- check_and_rewrite/2]).
+-export([check_and_rewrite/3]).
+
+%% callbacks for hipe_regalloc_prepass, hipe_range_split
+-export([mk_move/3,
+ mk_goto/2,
+ redirect_jmp/4,
+ new_label/1,
+ new_reg_nr/1,
+ update_reg_nr/3,
+ update_bb/4,
+ subst_temps/3]).
-defun_to_cfg(Defun) ->
- hipe_ppc_cfg:init(Defun).
+%% callbacks for hipe_bb_weights
+-export([branch_preds/2]).
-check_and_rewrite(Defun, Coloring) ->
- hipe_ppc_ra_postconditions:check_and_rewrite(Defun, Coloring, 'normal').
+check_and_rewrite(CFG, Coloring, _) ->
+ hipe_ppc_ra_postconditions:check_and_rewrite(CFG, Coloring, 'normal').
-reverse_postorder(CFG) ->
+reverse_postorder(CFG, _) ->
hipe_ppc_cfg:reverse_postorder(CFG).
-non_alloc(CFG) ->
- non_alloc(hipe_ppc_registers:nr_args(), hipe_ppc_cfg:params(CFG)).
+non_alloc(CFG, no_context) ->
+ non_alloc_1(hipe_ppc_registers:nr_args(), hipe_ppc_cfg:params(CFG)).
%% same as hipe_ppc_frame:fix_formals/2
-non_alloc(0, Rest) -> Rest;
-non_alloc(N, [_|Rest]) -> non_alloc(N-1, Rest);
-non_alloc(_, []) -> [].
+non_alloc_1(0, Rest) -> Rest;
+non_alloc_1(N, [_|Rest]) -> non_alloc_1(N-1, Rest);
+non_alloc_1(_, []) -> [].
%% Liveness stuff
-analyze(CFG) ->
+analyze(CFG, _) ->
hipe_ppc_liveness_gpr:analyse(CFG).
-livein(Liveness,L) ->
+livein(Liveness,L,_) ->
[X || X <- hipe_ppc_liveness_gpr:livein(Liveness,L),
hipe_ppc:temp_is_allocatable(X)].
-liveout(BB_in_out_liveness,Label) ->
+liveout(BB_in_out_liveness,Label,_) ->
[X || X <- hipe_ppc_liveness_gpr:liveout(BB_in_out_liveness,Label),
hipe_ppc:temp_is_allocatable(X)].
%% Registers stuff
-allocatable() ->
+allocatable(no_context) ->
hipe_ppc_registers:allocatable_gpr().
-all_precoloured() ->
+all_precoloured(no_context) ->
hipe_ppc_registers:all_precoloured().
-is_precoloured(Reg) ->
+is_precoloured(Reg, _) ->
hipe_ppc_registers:is_precoloured_gpr(Reg).
-is_fixed(R) ->
+is_fixed(R, _) ->
hipe_ppc_registers:is_fixed(R).
-physical_name(Reg) ->
+physical_name(Reg, _) ->
Reg.
%% CFG stuff
-labels(CFG) ->
+labels(CFG, _) ->
hipe_ppc_cfg:labels(CFG).
-var_range(_CFG) ->
+var_range(_CFG, _) ->
hipe_gensym:var_range(ppc).
-number_of_temporaries(_CFG) ->
+number_of_temporaries(_CFG, _) ->
Highest_temporary = hipe_gensym:get_var(ppc),
%% Since we can have temps from 0 to Max adjust by +1.
Highest_temporary + 1.
-bb(CFG,L) ->
+bb(CFG,L,_) ->
hipe_ppc_cfg:bb(CFG,L).
+update_bb(CFG,L,BB,_) ->
+ hipe_ppc_cfg:bb_add(CFG,L,BB).
+
+branch_preds(Instr,_) ->
+ hipe_ppc_cfg:branch_preds(Instr).
+
%% PowerPC stuff
-def_use(Instruction) ->
- {defines(Instruction), uses(Instruction)}.
+def_use(Instruction, Ctx) ->
+ {defines(Instruction, Ctx), uses(Instruction, Ctx)}.
-uses(I) ->
+uses(I, _) ->
[X || X <- hipe_ppc_defuse:insn_use_gpr(I),
hipe_ppc:temp_is_allocatable(X)].
-defines(I) ->
+defines(I, _) ->
[X || X <- hipe_ppc_defuse:insn_def_gpr(I),
hipe_ppc:temp_is_allocatable(X)].
-is_move(Instruction) ->
+defines_all_alloc(I, _) ->
+ hipe_ppc_defuse:insn_defs_all_gpr(I).
+
+is_move(Instruction, _) ->
case hipe_ppc:is_pseudo_move(Instruction) of
true ->
Dst = hipe_ppc:pseudo_move_dst(Instruction),
@@ -142,28 +155,60 @@ is_move(Instruction) ->
false -> false
end.
-reg_nr(Reg) ->
+is_spill_move(Instruction, _) ->
+ hipe_ppc:is_pseudo_spill_move(Instruction).
+
+reg_nr(Reg, _) ->
hipe_ppc:temp_reg(Reg).
+mk_move(Src, Dst, _) ->
+ hipe_ppc:mk_pseudo_move(Dst, Src).
+
+mk_goto(Label, _) ->
+ hipe_ppc:mk_b_label(Label).
+
+redirect_jmp(Jmp, ToOld, ToNew, _) when is_integer(ToOld), is_integer(ToNew) ->
+ hipe_ppc_cfg:redirect_jmp(Jmp, ToOld, ToNew).
+
+new_label(_) ->
+ hipe_gensym:get_next_label(ppc).
+
+new_reg_nr(_) ->
+ hipe_gensym:get_next_var(ppc).
+
+update_reg_nr(Nr, Temp, _) ->
+ hipe_ppc:mk_temp(Nr, hipe_ppc:temp_type(Temp)).
+
+subst_temps(SubstFun, Instr, _) ->
+ hipe_ppc_subst:insn_temps(
+ fun(Op) ->
+ case hipe_ppc:temp_is_allocatable(Op)
+ andalso hipe_ppc:temp_type(Op) =/= 'double'
+ of
+ true -> SubstFun(Op);
+ false -> Op
+ end
+ end, Instr).
+
%%% Linear Scan stuff
-new_spill_index(SpillIndex) when is_integer(SpillIndex) ->
+new_spill_index(SpillIndex, _) when is_integer(SpillIndex) ->
SpillIndex+1.
-breadthorder(CFG) ->
+breadthorder(CFG, _) ->
hipe_ppc_cfg:breadthorder(CFG).
-postorder(CFG) ->
+postorder(CFG, _) ->
hipe_ppc_cfg:postorder(CFG).
-is_global(R) ->
+is_global(R, _) ->
R =:= hipe_ppc_registers:temp1() orelse
R =:= hipe_ppc_registers:temp2() orelse
R =:= hipe_ppc_registers:temp3() orelse
hipe_ppc_registers:is_fixed(R).
-is_arg(R) ->
+is_arg(R, _) ->
hipe_ppc_registers:is_arg(R).
-args(CFG) ->
+args(CFG, _) ->
hipe_ppc_registers:args(hipe_ppc_cfg:arity(CFG)).
diff --git a/lib/hipe/regalloc/hipe_ppc_specific_fp.erl b/lib/hipe/regalloc/hipe_ppc_specific_fp.erl
index 454aa4c686..dcfdf6592c 100644
--- a/lib/hipe/regalloc/hipe_ppc_specific_fp.erl
+++ b/lib/hipe/regalloc/hipe_ppc_specific_fp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,133 +11,182 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_specific_fp).
%% for hipe_coalescing_regalloc:
--export([number_of_temporaries/1
- ,analyze/1
- ,labels/1
- ,all_precoloured/0
- ,bb/2
- ,liveout/2
- ,reg_nr/1
- ,def_use/1
- ,is_move/1
- ,is_precoloured/1
- ,var_range/1
- ,allocatable/0
- ,non_alloc/1
- ,physical_name/1
- ,reverse_postorder/1
- ,livein/2
- ,uses/1
- ,defines/1
+-export([number_of_temporaries/2
+ ,analyze/2
+ ,labels/2
+ ,all_precoloured/1
+ ,bb/3
+ ,liveout/3
+ ,reg_nr/2
+ ,def_use/2
+ ,is_move/2
+ ,is_spill_move/2
+ ,is_precoloured/2
+ ,var_range/2
+ ,allocatable/1
+ ,non_alloc/2
+ ,physical_name/2
+ ,reverse_postorder/2
+ ,livein/3
+ ,uses/2
+ ,defines/2
+ ,defines_all_alloc/2
]).
%% for hipe_graph_coloring_regalloc:
--export([is_fixed/1]).
+-export([is_fixed/2]).
%% for hipe_ls_regalloc:
-%%-export([args/1, is_arg/1, is_global, new_spill_index/1]).
-%%-export([breadthorder/1, postorder/1]).
+%%-export([args/2, is_arg/2, is_global, new_spill_index/2]).
+%%-export([breadthorder/2, postorder/2]).
%% callbacks for hipe_regalloc_loop
--export([defun_to_cfg/1,
- check_and_rewrite/2]).
+-export([check_and_rewrite/3]).
+
+%% callbacks for hipe_regalloc_prepass, hipe_range_split
+-export([mk_move/3,
+ mk_goto/2,
+ redirect_jmp/4,
+ new_label/1,
+ new_reg_nr/1,
+ update_reg_nr/3,
+ update_bb/4,
+ subst_temps/3]).
-defun_to_cfg(Defun) ->
- hipe_ppc_cfg:init(Defun).
+%% callbacks for hipe_bb_weights
+-export([branch_preds/2]).
-check_and_rewrite(Defun, Coloring) ->
- hipe_ppc_ra_postconditions_fp:check_and_rewrite(Defun, Coloring).
+check_and_rewrite(CFG, Coloring, _) ->
+ hipe_ppc_ra_postconditions_fp:check_and_rewrite(CFG, Coloring).
-reverse_postorder(CFG) ->
+reverse_postorder(CFG, _) ->
hipe_ppc_cfg:reverse_postorder(CFG).
-non_alloc(_CFG) ->
+non_alloc(_CFG, _) ->
[].
%% Liveness stuff
-analyze(CFG) ->
+analyze(CFG, _) ->
hipe_ppc_liveness_fpr:analyse(CFG).
-livein(Liveness, L) ->
+livein(Liveness, L, _) ->
hipe_ppc_liveness_fpr:livein(Liveness, L).
-liveout(BB_in_out_liveness, Label) ->
+liveout(BB_in_out_liveness, Label, _) ->
hipe_ppc_liveness_fpr:liveout(BB_in_out_liveness, Label).
%% Registers stuff
-allocatable() ->
+allocatable(no_context) ->
hipe_ppc_registers:allocatable_fpr().
-all_precoloured() ->
- allocatable().
+all_precoloured(Ctx) ->
+ allocatable(Ctx).
-is_precoloured(Reg) ->
+is_precoloured(Reg, _) ->
hipe_ppc_registers:is_precoloured_fpr(Reg).
-is_fixed(_Reg) ->
+is_fixed(_Reg, _) ->
false.
-physical_name(Reg) ->
+physical_name(Reg, _) ->
Reg.
%% CFG stuff
-labels(CFG) ->
+labels(CFG, _) ->
hipe_ppc_cfg:labels(CFG).
-var_range(_CFG) ->
+var_range(_CFG, _) ->
hipe_gensym:var_range(ppc).
-number_of_temporaries(_CFG) ->
+number_of_temporaries(_CFG, _) ->
Highest_temporary = hipe_gensym:get_var(ppc),
%% Since we can have temps from 0 to Max adjust by +1.
Highest_temporary + 1.
-bb(CFG, L) ->
+bb(CFG, L, _) ->
hipe_ppc_cfg:bb(CFG, L).
+update_bb(CFG,L,BB,_) ->
+ hipe_ppc_cfg:bb_add(CFG,L,BB).
+
+branch_preds(Instr,_) ->
+ hipe_ppc_cfg:branch_preds(Instr).
+
%% PowerPC stuff
-def_use(I) ->
- {defines(I), uses(I)}.
+def_use(I, Ctx) ->
+ {defines(I, Ctx), uses(I, Ctx)}.
-uses(I) ->
+uses(I, _) ->
hipe_ppc_defuse:insn_use_fpr(I).
-defines(I) ->
+defines(I, _) ->
hipe_ppc_defuse:insn_def_fpr(I).
-is_move(I) ->
+defines_all_alloc(I, _) ->
+ hipe_ppc_defuse:insn_defs_all_fpr(I).
+
+is_move(I, _) ->
hipe_ppc:is_pseudo_fmove(I).
-reg_nr(Reg) ->
+is_spill_move(I, _) ->
+ hipe_ppc:is_pseudo_spill_fmove(I).
+
+reg_nr(Reg, _) ->
hipe_ppc:temp_reg(Reg).
+mk_move(Src, Dst, _) ->
+ hipe_ppc:mk_pseudo_fmove(Dst, Src).
+
+mk_goto(Label, _) ->
+ hipe_ppc:mk_b_label(Label).
+
+redirect_jmp(Jmp, ToOld, ToNew, _) when is_integer(ToOld), is_integer(ToNew) ->
+ hipe_ppc_cfg:redirect_jmp(Jmp, ToOld, ToNew).
+
+new_label(_) ->
+ hipe_gensym:get_next_label(ppc).
+
+new_reg_nr(_) ->
+ hipe_gensym:get_next_var(ppc).
+
+update_reg_nr(Nr, _Temp, _) ->
+ hipe_ppc:mk_temp(Nr, 'double').
+
+subst_temps(SubstFun, Instr, _) ->
+ hipe_ppc_subst:insn_temps(
+ fun(Op) ->
+ case hipe_ppc:temp_is_allocatable(Op)
+ andalso hipe_ppc:temp_type(Op) =:= 'double'
+ of
+ true -> SubstFun(Op);
+ false -> Op
+ end
+ end, Instr).
+
-ifdef(notdef).
-new_spill_index(SpillIndex) ->
+new_spill_index(SpillIndex, _) ->
SpillIndex+1.
-breadthorder(CFG) ->
+breadthorder(CFG, _) ->
hipe_ppc_cfg:breadthorder(CFG).
-postorder(CFG) ->
+postorder(CFG, _) ->
hipe_ppc_cfg:postorder(CFG).
-is_global(_R) ->
+is_global(_R, _) ->
false.
-is_arg(_R) ->
+is_arg(_R, _) ->
false.
-args(_CFG) ->
+args(_CFG, _) ->
[].
-endif.
diff --git a/lib/hipe/regalloc/hipe_range_split.erl b/lib/hipe/regalloc/hipe_range_split.erl
new file mode 100644
index 0000000000..385df695f2
--- /dev/null
+++ b/lib/hipe/regalloc/hipe_range_split.erl
@@ -0,0 +1,1187 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%@doc
+%% TEMPORARY LIVE RANGE SPLITTING PASS
+%%
+%% Live range splitting is useful to allow a register allocator to allocate a
+%% temporary to register for a part of its lifetime, even if it cannot be for
+%% the entirety. This improves register allocation quality, at the cost of
+%% making the allocation problem more time and memory intensive to solve.
+%%
+%% Optimal allocation can be achieved if all temporaries are split at every
+%% program point (between all instructions), but this makes register allocation
+%% infeasably slow in practice. Instead, this module uses heuristics to choose
+%% which temporaries should have their live ranges split, and at which points.
+%%
+%% The range splitter only considers temps which are live during a call
+%% instruction, since they're known to be spilled. The control-flow graph is
+%% partitioned at call instructions and splitting decisions are made separately
+%% for each partition. The register copy of a temp (if any) gets a separate name
+%% in each partition.
+%%
+%% There are three different ways the range splitter may choose to split a
+%% temporary in a program partition:
+%%
+%% * Mode1: Spill the temp before calls, and restore it after them
+%% * Mode2: Spill the temp after definitions, restore it after calls
+%% * Mode3: Spill the temp after definitions, restore it before uses
+%%
+%% To pick which of these should be used for each temp×partiton pair, the range
+%% splitter uses a cost function. The cost is simply the sum of the cost of all
+%% expected stack accesses, and the cost for an individual stack access is based
+%% on the probability weight of the basic block that it resides in. This biases
+%% the range splitter so that it attempts moving stack accesses from a functions
+%% hot path to the cold path.
+%%
+%% The heuristic has a couple of tuning knobs, adjusting its preference for
+%% different spilling modes, aggressiveness, and how much influence the basic
+%% block probability weights have.
+%%
+%% Edge case not handled: Call instructions directly defining a pseudo. In that
+%% case, if that pseudo has been selected for mode2 spills, no spill is inserted
+%% after the call.
+-module(hipe_range_split).
+
+-export([split/5]).
+
+-compile(inline).
+
+%% -define(DO_ASSERT, 1).
+%% -define(DEBUG, 1).
+-include("../main/hipe.hrl").
+
+%% Heuristic tuning constants
+-define(DEFAULT_MIN_GAIN, 1.1). % option: range_split_min_gain
+-define(DEFAULT_MODE1_FUDGE, 1.1). % option: range_split_mode1_fudge
+-define(DEFAULT_WEIGHT_POWER, 2). % option: range_split_weight_power
+-define(WEIGHT_CONST_FUN(Power), math:log(Power)/math:log(100)).
+-define(WEIGHT_FUN(Wt, Const), math:pow(Wt, Const)).
+-define(HEUR_MAX_TEMPS, 20000).
+
+-type target_cfg() :: any().
+-type target_instr() :: any().
+-type target_temp() :: any().
+-type liveness() :: any().
+-type target_module() :: module().
+-type target_context() :: any().
+-type target() :: {target_module(), target_context()}.
+-type liveset() :: ordsets:ordset(temp()).
+-type temp() :: non_neg_integer().
+-type label() :: non_neg_integer().
+
+-spec split(target_cfg(), liveness(), target_module(), target_context(),
+ comp_options())
+ -> target_cfg().
+split(TCFG0, Liveness, TargetMod, TargetContext, Options) ->
+ Target = {TargetMod, TargetContext},
+ NoTemps = number_of_temporaries(TCFG0, Target),
+ if NoTemps > ?HEUR_MAX_TEMPS ->
+ ?debug_msg("~w: Too many temps (~w), falling back on restore_reuse.~n",
+ [?MODULE, NoTemps]),
+ hipe_restore_reuse:split(TCFG0, Liveness, TargetMod, TargetContext);
+ true ->
+ Wts = compute_weights(TCFG0, TargetMod, TargetContext, Options),
+ {CFG0, Temps} = convert(TCFG0, Target),
+ Avail = avail_analyse(TCFG0, Liveness, Target),
+ Defs = def_analyse(CFG0, TCFG0),
+ RDefs = rdef_analyse(CFG0),
+ PLive = plive_analyse(CFG0),
+ {CFG, DUCounts, Costs, DSets0} =
+ scan(CFG0, Liveness, PLive, Wts, Defs, RDefs, Avail, Target),
+ {DSets, _} = hipe_dsets:to_map(DSets0),
+ Renames = decide(DUCounts, Costs, Target, Options),
+ rewrite(CFG, TCFG0, Target, Liveness, PLive, Defs, Avail, DSets, Renames,
+ Temps)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Internal program representation
+%%
+%% Second pass: Convert cfg to internal representation
+
+-record(cfg, {
+ rpo_labels :: [label()],
+ bbs :: #{label() => bb()}
+ }).
+-type cfg() :: #cfg{}.
+
+cfg_bb(L, #cfg{bbs=BBS}) -> maps:get(L, BBS).
+
+cfg_postorder(#cfg{rpo_labels=RPO}) -> lists:reverse(RPO).
+
+-record(bb, {
+ code :: [code_elem()],
+ %% If the last instruction of code defines all allocatable registers
+ has_call :: boolean(),
+ succ :: [label()]
+ }).
+-type bb() :: #bb{}.
+-type code_elem() :: instr() | mode2_spills() | mode3_restores().
+
+bb_code(#bb{code=Code}) -> Code.
+bb_has_call(#bb{has_call=HasCall}) -> HasCall.
+bb_succ(#bb{succ=Succ}) -> Succ.
+
+bb_butlast(#bb{code=Code}) ->
+ bb_butlast_1(Code).
+
+bb_butlast_1([_Last]) -> [];
+bb_butlast_1([I|Is]) -> [I|bb_butlast_1(Is)].
+
+bb_last(#bb{code=Code}) -> lists:last(Code).
+
+-record(instr, {
+ i :: target_instr(),
+ def :: ordsets:ordset(temp()),
+ use :: ordsets:ordset(temp())
+ }).
+-type instr() :: #instr{}.
+
+-record(mode2_spills, {
+ temps :: ordsets:ordset(temp())
+ }).
+-type mode2_spills() :: #mode2_spills{}.
+
+-record(mode3_restores, {
+ temps :: ordsets:ordset(temp())
+ }).
+-type mode3_restores() :: #mode3_restores{}.
+
+-spec convert(target_cfg(), target()) -> {cfg(), temps()}.
+convert(CFG, Target) ->
+ RPO = reverse_postorder(CFG, Target),
+ {BBsList, Temps} = convert_bbs(RPO, CFG, Target, #{}, []),
+ {#cfg{rpo_labels = RPO,
+ bbs = maps:from_list(BBsList)},
+ Temps}.
+
+convert_bbs([], _CFG, _Target, Temps, Acc) -> {Acc, Temps};
+convert_bbs([L|Ls], CFG, Target, Temps0, Acc) ->
+ Succs = hipe_gen_cfg:succ(CFG, L),
+ TBB = bb(CFG, L, Target),
+ TCode = hipe_bb:code(TBB),
+ {Code, Last, Temps} = convert_code(TCode, Target, Temps0, []),
+ HasCall = defines_all_alloc(Last#instr.i, Target),
+ BB = #bb{code = Code,
+ has_call = HasCall,
+ succ = Succs},
+ convert_bbs(Ls, CFG, Target, Temps, [{L,BB}|Acc]).
+
+convert_code([], _Target, Temps, [Last|_]=Acc) ->
+ {lists:reverse(Acc), Last, Temps};
+convert_code([TI|TIs], Target, Temps0, Acc) ->
+ {TDef, TUse} = def_use(TI, Target),
+ I = #instr{i = TI,
+ def = ordsets:from_list(reg_names(TDef, Target)),
+ use = ordsets:from_list(reg_names(TUse, Target))},
+ Temps = add_temps(TUse, Target, add_temps(TDef, Target, Temps0)),
+ convert_code(TIs, Target, Temps, [I|Acc]).
+
+-type temps() :: #{temp() => target_temp()}.
+add_temps([], _Target, Temps) -> Temps;
+add_temps([T|Ts], Target, Temps) ->
+ add_temps(Ts, Target, Temps#{reg_nr(T, Target) => T}).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Fourth pass: P({DEF}) lattice fwd dataflow (for eliding stores at SPILL
+%% splits)
+-type defsi() :: #{label() => defseti() | {call, defseti(), defseti()}}.
+-type defs() :: #{label() => defsetf()}.
+
+-spec def_analyse(cfg(), target_cfg()) -> defs().
+def_analyse(CFG = #cfg{rpo_labels = RPO}, TCFG) ->
+ Defs0 = def_init(CFG),
+ def_dataf(RPO, TCFG, Defs0).
+
+-spec def_init(cfg()) -> defsi().
+def_init(#cfg{bbs = BBs}) ->
+ maps:from_list(
+ [begin
+ {L, case HasCall of
+ false -> def_init_scan(bb_code(BB), defseti_new());
+ true ->
+ {call, def_init_scan(bb_butlast(BB), defseti_new()),
+ defseti_from_ordset((bb_last(BB))#instr.def)}
+ end}
+ end || {L, BB = #bb{has_call=HasCall}} <- maps:to_list(BBs)]).
+
+def_init_scan([], Defset) -> Defset;
+def_init_scan([#instr{def=Def}|Is], Defset0) ->
+ Defset = defseti_add_ordset(Def, Defset0),
+ def_init_scan(Is, Defset).
+
+-spec def_dataf([label()], target_cfg(), defsi()) -> defs().
+def_dataf(Labels, TCFG, Defs0) ->
+ case def_dataf_once(Labels, TCFG, Defs0, 0) of
+ {Defs, 0} ->
+ def_finalise(Defs);
+ {Defs, _Changed} ->
+ def_dataf(Labels, TCFG, Defs)
+ end.
+
+-spec def_finalise(defsi()) -> defs().
+def_finalise(Defs) ->
+ maps:from_list([{K, defseti_finalise(BL)}
+ || {K, {call, BL, _}} <- maps:to_list(Defs)]).
+
+-spec def_dataf_once([label()], target_cfg(), defsi(), non_neg_integer())
+ -> {defsi(), non_neg_integer()}.
+def_dataf_once([], _TCFG, Defs, Changed) -> {Defs, Changed};
+def_dataf_once([L|Ls], TCFG, Defs0, Changed0) ->
+ AddPreds =
+ fun(Defset1) ->
+ lists:foldl(fun(P, Defset2) ->
+ defseti_union(defout(P, Defs0), Defset2)
+ end, Defset1, hipe_gen_cfg:pred(TCFG, L))
+ end,
+ Defset =
+ case Defset0 = maps:get(L, Defs0) of
+ {call, Butlast, Defout} -> {call, AddPreds(Butlast), Defout};
+ _ -> AddPreds(Defset0)
+ end,
+ Changed = case Defset =:= Defset0 of
+ true -> Changed0;
+ false -> Changed0+1
+ end,
+ def_dataf_once(Ls, TCFG, Defs0#{L := Defset}, Changed).
+
+-spec defout(label(), defsi()) -> defseti().
+defout(L, Defs) ->
+ case maps:get(L, Defs) of
+ {call, _DefButLast, Defout} -> Defout;
+ Defout -> Defout
+ end.
+
+-spec defbutlast(label(), defs()) -> defsetf().
+defbutlast(L, Defs) -> maps:get(L, Defs).
+
+-spec defseti_new() -> defseti().
+-spec defseti_union(defseti(), defseti()) -> defseti().
+-spec defseti_add_ordset(ordsets:ordset(temp()), defseti()) -> defseti().
+-spec defseti_from_ordset(ordsets:ordset(temp())) -> defseti().
+-spec defseti_finalise(defseti()) -> defsetf().
+-spec defsetf_member(temp(), defsetf()) -> boolean().
+-spec defsetf_intersect_ordset(ordsets:ordset(temp()), defsetf())
+ -> ordsets:ordset(temp()).
+
+-type defseti() :: bitord().
+defseti_new() -> bitord_new().
+defseti_union(A, B) -> bitord_union(A, B).
+defseti_add_ordset(OS, D) -> defseti_union(defseti_from_ordset(OS), D).
+defseti_from_ordset(OS) -> bitord_from_ordset(OS).
+defseti_finalise(D) -> bitarr_from_bitord(D).
+
+-type defsetf() :: bitarr().
+defsetf_member(E, D) -> bitarr_get(E, D).
+
+defsetf_intersect_ordset([], _D) -> [];
+defsetf_intersect_ordset([E|Es], D) ->
+ case bitarr_get(E, D) of
+ true -> [E|defsetf_intersect_ordset(Es,D)];
+ false -> defsetf_intersect_ordset(Es,D)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Fifth pass: P({DEF}) lattice reverse dataflow (for eliding stores at defines
+%% in mode2)
+-type rdefsi() :: #{label() =>
+ {call, rdefseti(), [label()]}
+ | {nocall, rdefseti(), rdefseti(), [label()]}}.
+-type rdefs() :: #{label() => {final, rdefsetf(), [label()]}}.
+
+-spec rdef_analyse(cfg()) -> rdefs().
+rdef_analyse(CFG = #cfg{rpo_labels=RPO}) ->
+ Defs0 = rdef_init(CFG),
+ PO = rdef_postorder(RPO, CFG, []),
+ rdef_dataf(PO, Defs0).
+
+%% Filter out 'call' labels, since they don't change
+-spec rdef_postorder([label()], cfg(), [label()]) -> [label()].
+rdef_postorder([], _CFG, Acc) -> Acc;
+rdef_postorder([L|Ls], CFG, Acc) ->
+ case bb_has_call(cfg_bb(L, CFG)) of
+ true -> rdef_postorder(Ls, CFG, Acc);
+ false -> rdef_postorder(Ls, CFG, [L|Acc])
+ end.
+
+-spec rdef_init(cfg()) -> rdefsi().
+rdef_init(#cfg{bbs = BBs}) ->
+ maps:from_list(
+ [{L, case HasCall of
+ true ->
+ Defin = rdef_init_scan(bb_butlast(BB), rdefseti_empty()),
+ {call, Defin, Succs};
+ false ->
+ Gen = rdef_init_scan(bb_code(BB), rdefseti_empty()),
+ {nocall, Gen, rdefseti_top(), Succs}
+ end}
+ || {L, BB = #bb{has_call=HasCall, succ=Succs}} <- maps:to_list(BBs)]).
+
+-spec rdef_init_scan([instr()], rdefseti()) -> rdefseti().
+rdef_init_scan([], Defset) -> Defset;
+rdef_init_scan([#instr{def=Def}|Is], Defset0) ->
+ Defset = rdefseti_add_ordset(Def, Defset0),
+ rdef_init_scan(Is, Defset).
+
+-spec rdef_dataf([label()], rdefsi()) -> rdefs().
+rdef_dataf(Labels, Defs0) ->
+ case rdef_dataf_once(Labels, Defs0, 0) of
+ {Defs, 0} ->
+ rdef_finalise(Defs);
+ {Defs, _Changed} ->
+ rdef_dataf(Labels, Defs)
+ end.
+
+-spec rdef_finalise(rdefsi()) -> rdefs().
+rdef_finalise(Defs) ->
+ maps:map(fun(L, V) ->
+ Succs = rsuccs_val(V),
+ Defout0 = rdefout_intersect(L, Defs, rdefseti_top()),
+ {final, rdefset_finalise(Defout0), Succs}
+ end, Defs).
+
+-spec rdef_dataf_once([label()], rdefsi(), non_neg_integer())
+ -> {rdefsi(), non_neg_integer()}.
+rdef_dataf_once([], Defs, Changed) -> {Defs, Changed};
+rdef_dataf_once([L|Ls], Defs0, Changed0) ->
+ #{L := {nocall, Gen, Defin0, Succs}} = Defs0,
+ Defin = rdefseti_union(Gen, rdefout_intersect(L, Defs0, Defin0)),
+ Defset = {nocall, Gen, Defin, Succs},
+ Changed = case Defin =:= Defin0 of
+ true -> Changed0;
+ false -> Changed0+1
+ end,
+ rdef_dataf_once(Ls, Defs0#{L := Defset}, Changed).
+
+-spec rdefin(label(), rdefsi()) -> rdefseti().
+rdefin(L, Defs) -> rdefin_val(maps:get(L, Defs)).
+rdefin_val({nocall, _Gen, Defin, _Succs}) -> Defin;
+rdefin_val({call, Defin, _Succs}) -> Defin.
+
+-spec rsuccs(label(), rdefsi()) -> [label()].
+rsuccs(L, Defs) -> rsuccs_val(maps:get(L, Defs)).
+rsuccs_val({nocall, _Gen, _Defin, Succs}) -> Succs;
+rsuccs_val({call, _Defin, Succs}) -> Succs.
+
+-spec rdefout(label(), rdefs()) -> rdefsetf().
+rdefout(L, Defs) ->
+ #{L := {final, Defout, _Succs}} = Defs,
+ Defout.
+
+-spec rdefout_intersect(label(), rdefsi(), rdefseti()) -> rdefseti().
+rdefout_intersect(L, Defs, Init) ->
+ lists:foldl(fun(S, Acc) ->
+ rdefseti_intersect(rdefin(S, Defs), Acc)
+ end, Init, rsuccs(L, Defs)).
+
+-type rdefseti() :: bitord() | top.
+rdefseti_top() -> top.
+rdefseti_empty() -> bitord_new().
+-spec rdefseti_from_ordset(ordsets:ordset(temp())) -> rdefseti().
+rdefseti_from_ordset(OS) -> bitord_from_ordset(OS).
+
+-spec rdefseti_add_ordset(ordsets:ordset(temp()), rdefseti()) -> rdefseti().
+rdefseti_add_ordset(_, top) -> top; % Should never happen in rdef_dataf
+rdefseti_add_ordset(OS, D) -> rdefseti_union(rdefseti_from_ordset(OS), D).
+
+-spec rdefseti_union(rdefseti(), rdefseti()) -> rdefseti().
+rdefseti_union(top, _) -> top;
+rdefseti_union(_, top) -> top;
+rdefseti_union(A, B) -> bitord_union(A, B).
+
+-spec rdefseti_intersect(rdefseti(), rdefseti()) -> rdefseti().
+rdefseti_intersect(top, D) -> D;
+rdefseti_intersect(D, top) -> D;
+rdefseti_intersect(A, B) -> bitord_intersect(A, B).
+
+-type rdefsetf() :: {arr, bitarr()} | top.
+-spec rdefset_finalise(rdefseti()) -> rdefsetf().
+rdefset_finalise(top) -> top;
+rdefset_finalise(Ord) -> {arr, bitarr_from_bitord(Ord)}.
+
+%% rdefsetf_top() -> top.
+rdefsetf_empty() -> {arr, bitarr_new()}.
+
+-spec rdefsetf_add_ordset(ordsets:ordset(temp()), rdefsetf()) -> rdefsetf().
+rdefsetf_add_ordset(_, top) -> top;
+rdefsetf_add_ordset(OS, {arr, Arr}) ->
+ {arr, lists:foldl(fun bitarr_set/2, Arr, OS)}.
+
+-spec rdef_step(instr(), rdefsetf()) -> rdefsetf().
+rdef_step(#instr{def=Def}, Defset) ->
+ %% ?ASSERT(not defines_all_alloc(I, Target)),
+ rdefsetf_add_ordset(Def, Defset).
+
+-spec ordset_subtract_rdefsetf(ordsets:ordset(temp()), rdefsetf())
+ -> ordsets:ordset(temp()).
+ordset_subtract_rdefsetf(_, top) -> [];
+ordset_subtract_rdefsetf(OS, {arr, Arr}) ->
+ %% Lazy implementation; could do better if OS can grow
+ lists:filter(fun(E) -> not bitarr_get(E, Arr) end, OS).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Integer sets represented as bit sets
+%%
+%% Two representations; bitord() and bitarr()
+-define(LIMB_IX_BITS, 11).
+-define(LIMB_BITS, (1 bsl ?LIMB_IX_BITS)).
+-define(LIMB_IX(Index), (Index bsr ?LIMB_IX_BITS)).
+-define(BIT_IX(Index), (Index band (?LIMB_BITS - 1))).
+-define(BIT_MASK(Index), (1 bsl ?BIT_IX(Index))).
+
+%% bitord(): fast at union/2 and can be compared for equality with '=:='
+-type bitord() :: orddict:orddict(non_neg_integer(), 0..((1 bsl ?LIMB_BITS)-1)).
+
+-spec bitord_new() -> bitord().
+bitord_new() -> [].
+
+-spec bitord_union(bitord(), bitord()) -> bitord().
+bitord_union(Lhs, Rhs) ->
+ orddict:merge(fun(_, L, R) -> L bor R end, Lhs, Rhs).
+
+-spec bitord_intersect(bitord(), bitord()) -> bitord().
+bitord_intersect([], _) -> [];
+bitord_intersect(_, []) -> [];
+bitord_intersect([{K, L}|Ls], [{K, R}|Rs]) ->
+ [{K, L band R} | bitord_intersect(Ls, Rs)];
+bitord_intersect([{LK, _}|Ls], [{RK, _}|_]=Rs) when LK < RK ->
+ bitord_intersect(Ls, Rs);
+bitord_intersect([{LK, _}|_]=Ls, [{RK, _}|Rs]) when LK > RK ->
+ bitord_intersect(Ls, Rs).
+
+-spec bitord_from_ordset(ordsets:ordset(non_neg_integer())) -> bitord().
+bitord_from_ordset([]) -> [];
+bitord_from_ordset([B|Bs]) ->
+ bitord_from_ordset_1(Bs, ?LIMB_IX(B), ?BIT_MASK(B)).
+
+bitord_from_ordset_1([B|Bs], Key, Val) when Key =:= ?LIMB_IX(B) ->
+ bitord_from_ordset_1(Bs, Key, Val bor ?BIT_MASK(B));
+bitord_from_ordset_1([B|Bs], Key, Val) ->
+ [{Key,Val} | bitord_from_ordset_1(Bs, ?LIMB_IX(B), ?BIT_MASK(B))];
+bitord_from_ordset_1([], Key, Val) -> [{Key, Val}].
+
+%% bitarr(): fast (enough) at get/2
+-type bitarr() :: array:array(0..((1 bsl ?LIMB_BITS)-1)).
+
+-spec bitarr_new() -> bitarr().
+bitarr_new() -> array:new({default, 0}).
+
+-spec bitarr_get(non_neg_integer(), bitarr()) -> boolean().
+bitarr_get(Index, Array) ->
+ Limb = array:get(?LIMB_IX(Index), Array),
+ 0 =/= (Limb band ?BIT_MASK(Index)).
+
+-spec bitarr_set(non_neg_integer(), bitarr()) -> bitarr().
+bitarr_set(Index, Array) ->
+ Limb0 = array:get(?LIMB_IX(Index), Array),
+ Limb = Limb0 bor ?BIT_MASK(Index),
+ array:set(?LIMB_IX(Index), Limb, Array).
+
+-spec bitarr_from_bitord(bitord()) -> bitarr().
+bitarr_from_bitord(Ord) ->
+ array:from_orddict(Ord, 0).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Sixth pass: Partition-local liveness analysis
+%%
+%% As temps are not spilled when exiting a partition in mode2, only
+%% partition-local uses need to be considered when deciding which temps need
+%% restoring at partition entry.
+
+-type plive() :: #{label() =>
+ {call, liveset(), [label()]}
+ | {nocall, {liveset(), liveset()}, liveset(), [label()]}}.
+
+-spec plive_analyse(cfg()) -> plive().
+plive_analyse(CFG) ->
+ Defs0 = plive_init(CFG),
+ PO = cfg_postorder(CFG),
+ plive_dataf(PO, Defs0).
+
+-spec plive_init(cfg()) -> plive().
+plive_init(#cfg{bbs = BBs}) ->
+ maps:from_list(
+ [begin
+ {L, case HasCall of
+ true ->
+ {Gen, _} = plive_init_scan(bb_code(BB)),
+ {call, Gen, Succs};
+ false ->
+ GenKill = plive_init_scan(bb_code(BB)),
+ {nocall, GenKill, liveset_empty(), Succs}
+ end}
+ end || {L, BB = #bb{has_call=HasCall, succ=Succs}} <- maps:to_list(BBs)]).
+
+-spec plive_init_scan([instr()]) -> {liveset(), liveset()}.
+plive_init_scan([]) -> {liveset_empty(), liveset_empty()};
+plive_init_scan([#instr{def=InstrKill, use=InstrGen}|Is]) ->
+ {Gen0, Kill0} = plive_init_scan(Is),
+ Gen1 = liveset_subtract(Gen0, InstrKill),
+ Gen = liveset_union(Gen1, InstrGen),
+ Kill1 = liveset_union(Kill0, InstrKill),
+ Kill = liveset_subtract(Kill1, InstrGen),
+ {Gen, Kill}.
+
+-spec plive_dataf([label()], plive()) -> plive().
+plive_dataf(Labels, PLive0) ->
+ case plive_dataf_once(Labels, PLive0, 0) of
+ {PLive, 0} -> PLive;
+ {PLive, _Changed} ->
+ plive_dataf(Labels, PLive)
+ end.
+
+-spec plive_dataf_once([label()], plive(), non_neg_integer()) ->
+ {plive(), non_neg_integer()}.
+plive_dataf_once([], PLive, Changed) -> {PLive, Changed};
+plive_dataf_once([L|Ls], PLive0, Changed0) ->
+ Liveset =
+ case Liveset0 = maps:get(L, PLive0) of
+ {call, Livein, Succs} ->
+ {call, Livein, Succs};
+ {nocall, {Gen, Kill} = GenKill, _OldLivein, Succs} ->
+ Liveout = pliveout(L, PLive0),
+ Livein = liveset_union(Gen, liveset_subtract(Liveout, Kill)),
+ {nocall, GenKill, Livein, Succs}
+ end,
+ Changed = case Liveset =:= Liveset0 of
+ true -> Changed0;
+ false -> Changed0+1
+ end,
+ plive_dataf_once(Ls, PLive0#{L := Liveset}, Changed).
+
+-spec pliveout(label(), plive()) -> liveset().
+pliveout(L, PLive) ->
+ liveset_union([plivein(S, PLive) || S <- psuccs(L, PLive)]).
+
+-spec psuccs(label(), plive()) -> [label()].
+psuccs(L, PLive) -> psuccs_val(maps:get(L, PLive)).
+psuccs_val({call, _Livein, Succs}) -> Succs;
+psuccs_val({nocall, _GenKill, _Livein, Succs}) -> Succs.
+
+-spec plivein(label(), plive()) -> liveset().
+plivein(L, PLive) -> plivein_val(maps:get(L, PLive)).
+plivein_val({call, Livein, _Succs}) -> Livein;
+plivein_val({nocall, _GenKill, Livein, _Succs}) -> Livein.
+
+liveset_empty() -> ordsets:new().
+liveset_subtract(A, B) -> ordsets:subtract(A, B).
+liveset_union(A, B) -> ordsets:union(A, B).
+liveset_union(LivesetList) -> ordsets:union(LivesetList).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Third pass: Compute dataflow analyses required for placing mode3
+%% spills/restores.
+%% Reuse analysis implementation in hipe_restore_reuse.
+%% XXX: hipe_restore_reuse has it's own "rdef"; we would like to reuse that one
+%% too.
+-type avail() :: hipe_restore_reuse:avail().
+
+-spec avail_analyse(target_cfg(), liveness(), target()) -> avail().
+avail_analyse(CFG, Liveness, Target) ->
+ hipe_restore_reuse:analyse(CFG, Liveness, Target).
+
+-spec mode3_split_in_block(label(), avail()) -> ordsets:ordset(temp()).
+mode3_split_in_block(L, Avail) ->
+ hipe_restore_reuse:split_in_block(L, Avail).
+
+-spec mode3_block_renameset(label(), avail()) -> ordsets:ordset(temp()).
+mode3_block_renameset(L, Avail) ->
+ hipe_restore_reuse:renamed_in_block(L, Avail).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Seventh pass
+%%
+%% Compute program space partitioning, collect information required by the
+%% heuristic.
+-type part_key() :: label().
+-type part_dsets() :: hipe_dsets:dsets(part_key()).
+-type part_dsets_map() :: #{part_key() => part_key()}.
+-type ducounts() :: #{part_key() => ducount()}.
+
+-spec scan(cfg(), liveness(), plive(), weights(), defs(), rdefs(), avail(),
+ target()) -> {cfg(), ducounts(), costs(), part_dsets()}.
+scan(CFG0, Liveness, PLive, Weights, Defs, RDefs, Avail, Target) ->
+ #cfg{rpo_labels = Labels, bbs = BBs0} = CFG0,
+ CFG = CFG0#cfg{bbs=#{}}, % kill reference
+ DSets0 = hipe_dsets:new(Labels),
+ Costs0 = costs_new(),
+ {BBs, DUCounts0, Costs1, DSets1} =
+ scan_bbs(maps:to_list(BBs0), Liveness, PLive, Weights, Defs, RDefs, Avail,
+ Target, #{}, Costs0, DSets0, []),
+ {RLList, DSets2} = hipe_dsets:to_rllist(DSets1),
+ {Costs, DSets} = costs_map_roots(DSets2, Costs1),
+ DUCounts = collect_ducounts(RLList, DUCounts0, #{}),
+ {CFG#cfg{bbs=maps:from_list(BBs)}, DUCounts, Costs, DSets}.
+
+-spec collect_ducounts([{label(), [label()]}], ducounts(), ducounts())
+ -> ducounts().
+collect_ducounts([], _, Acc) -> Acc;
+collect_ducounts([{R,Ls}|RLs], DUCounts, Acc) ->
+ DUCount = lists:foldl(
+ fun(Key, FAcc) ->
+ ducount_merge(maps:get(Key, DUCounts, ducount_new()), FAcc)
+ end, ducount_new(), Ls),
+ collect_ducounts(RLs, DUCounts, Acc#{R => DUCount}).
+
+-spec scan_bbs([{label(), bb()}], liveness(), plive(), weights(), defs(),
+ rdefs(), avail(), target(), ducounts(), costs(), part_dsets(),
+ [{label(), bb()}])
+ -> {[{label(), bb()}], ducounts(), costs(), part_dsets()}.
+scan_bbs([], _Liveness, _PLive, _Weights, _Defs, _RDefs, _Avail, _Target,
+ DUCounts, Costs, DSets, Acc) ->
+ {Acc, DUCounts, Costs, DSets};
+scan_bbs([{L,BB}|BBs], Liveness, PLive, Weights, Defs, RDefs, Avail, Target,
+ DUCounts0, Costs0, DSets0, Acc) ->
+ Wt = weight(L, Weights),
+ {DSets, Costs5, EntryCode, ExitCode, RDefout, Liveout} =
+ case bb_has_call(BB) of
+ false ->
+ DSets1 = lists:foldl(fun(S, DS) -> hipe_dsets:union(L, S, DS) end,
+ DSets0, bb_succ(BB)),
+ {DSets1, Costs0, bb_code(BB), [], rdefout(L, RDefs),
+ liveout(Liveness, L, Target)};
+ true ->
+ LastI = #instr{def=LastDef} = bb_last(BB),
+ LiveBefore = ordsets:subtract(liveout(Liveness, L, Target), LastDef),
+ %% We can omit the spill of a temp that has not been defined since the
+ %% last time it was spilled
+ SpillSet = defsetf_intersect_ordset(LiveBefore, defbutlast(L, Defs)),
+ Costs1 = costs_insert(exit, L, Wt, SpillSet, Costs0),
+ Costs4 = lists:foldl(fun({S, BranchWt}, Costs2) ->
+ SLivein = livein(Liveness, S, Target),
+ SPLivein = plivein(S, PLive),
+ SWt = weight_scaled(L, BranchWt, Weights),
+ Costs3 = costs_insert(entry1, S, SWt, SLivein, Costs2),
+ costs_insert(entry2, S, SWt, SPLivein, Costs3)
+ end, Costs1, branch_preds(LastI#instr.i, Target)),
+ {DSets0, Costs4, bb_butlast(BB), [LastI], rdefsetf_empty(), LiveBefore}
+ end,
+ Mode3Splits = mode3_split_in_block(L, Avail),
+ {RevEntryCode, Restored} = scan_bb_fwd(EntryCode, Mode3Splits, [], []),
+ {Code, DUCount, Mode2Spills} =
+ scan_bb(RevEntryCode, Wt, RDefout, Liveout, ducount_new(), [], ExitCode),
+ DUCounts = DUCounts0#{L => DUCount},
+ M2SpillSet = ordsets:from_list(Mode2Spills),
+ Costs6 = costs_insert(spill, L, Wt, M2SpillSet, Costs5),
+ Mode3Renames = mode3_block_renameset(L, Avail),
+ Costs7 = costs_insert(restore, L, Wt, ordsets:intersection(M2SpillSet, Mode3Renames), Costs6),
+ Costs8 = costs_insert(restore, L, Wt, ordsets:from_list(Restored), Costs7),
+ Costs = add_unsplit_mode3_costs(DUCount, Mode3Renames, L, Costs8),
+ scan_bbs(BBs, Liveness, PLive, Weights, Defs, RDefs, Avail, Target, DUCounts,
+ Costs, DSets, [{L,BB#bb{code=Code}}|Acc]).
+
+-spec add_unsplit_mode3_costs(ducount(), ordsets:ordset(temp()), label(), costs())
+ -> costs().
+add_unsplit_mode3_costs(DUCount, Mode3Renames, L, Costs) ->
+ Unsplit = orddict_without_ordset(Mode3Renames,
+ orddict:from_list(ducount_to_list(DUCount))),
+ add_unsplit_mode3_costs_1(Unsplit, L, Costs).
+
+-spec add_unsplit_mode3_costs_1([{temp(),float()}], label(), costs())
+ -> costs().
+add_unsplit_mode3_costs_1([], _L, Costs) -> Costs;
+add_unsplit_mode3_costs_1([{T,C}|Cs], L, Costs) ->
+ add_unsplit_mode3_costs_1(Cs, L, costs_insert(restore, L, C, [T], Costs)).
+
+%% @doc Returns a new orddict without keys in Set and their associated values.
+-spec orddict_without_ordset(ordsets:ordset(K), orddict:orddict(K, V))
+ -> orddict:orddict(K, V).
+orddict_without_ordset([S|Ss], [{K,_}|_]=Dict) when S < K ->
+ orddict_without_ordset(Ss, Dict);
+orddict_without_ordset([S|_]=Set, [D={K,_}|Ds]) when S > K ->
+ [D|orddict_without_ordset(Set, Ds)];
+orddict_without_ordset([_S|Ss], [{_K,_}|Ds]) -> % _S == _K
+ orddict_without_ordset(Ss, Ds);
+orddict_without_ordset(_, []) -> [];
+orddict_without_ordset([], Dict) -> Dict.
+
+%% Scans the code forward, collecting and inserting mode3 restores
+-spec scan_bb_fwd([instr()], ordsets:ordset(temp()), ordsets:ordset(temp()),
+ [code_elem()])
+ -> {[code_elem()], ordsets:ordset(temp())}.
+scan_bb_fwd([], [], Restored, Acc) -> {Acc, Restored};
+scan_bb_fwd([I|Is], SplitHere0, Restored0, Acc0) ->
+ #instr{def=Def, use=Use} = I,
+ {ToRestore, SplitHere1} =
+ lists:partition(fun(R) -> lists:member(R, Use) end, SplitHere0),
+ SplitHere = lists:filter(fun(R) -> not lists:member(R, Def) end, SplitHere1),
+ Acc =
+ case ToRestore of
+ [] -> [I | Acc0];
+ _ -> [I, #mode3_restores{temps=ToRestore} | Acc0]
+ end,
+ scan_bb_fwd(Is, SplitHere, ToRestore ++ Restored0, Acc).
+
+%% Scans the code backwards, collecting def/use counts and mode2 spills
+-spec scan_bb([code_elem()], float(), rdefsetf(), liveset(), ducount(),
+ [temp()], [code_elem()])
+ -> {[code_elem()], ducount(), [temp()]}.
+scan_bb([], _Wt, _RDefout, _Liveout, DUCount, Spills, Acc) ->
+ {Acc, DUCount, Spills};
+scan_bb([I=#mode3_restores{}|Is], Wt, RDefout, Liveout, DUCount, Spills, Acc) ->
+ scan_bb(Is, Wt, RDefout, Liveout, DUCount, Spills, [I|Acc]);
+scan_bb([I|Is], Wt, RDefout, Liveout, DUCount0, Spills0, Acc0) ->
+ #instr{def=Def,use=Use} = I,
+ DUCount = ducount_add(Use, Wt, ducount_add(Def, Wt, DUCount0)),
+ Livein = liveness_step(I, Liveout),
+ RDefin = rdef_step(I, RDefout),
+ %% The temps that would be spilled after I in mode 2
+ NewSpills = ordset_subtract_rdefsetf(
+ ordsets:intersection(Def, Liveout),
+ RDefout),
+ ?ASSERT(NewSpills =:= (NewSpills -- Spills0)),
+ Spills = NewSpills ++ Spills0,
+ Acc1 = case NewSpills of
+ [] -> Acc0;
+ _ -> [#mode2_spills{temps=NewSpills}|Acc0]
+ end,
+ scan_bb(Is, Wt, RDefin, Livein, DUCount, Spills, [I|Acc1]).
+
+-spec liveness_step(instr(), liveset()) -> liveset().
+liveness_step(#instr{def=Def, use=Use}, Liveout) ->
+ ordsets:union(Use, ordsets:subtract(Liveout, Def)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% First pass: compute basic-block weighting
+
+-type weights() :: no_bb_weights
+ | {hipe_bb_weights:bb_weights(), float()}.
+
+-spec weight(label(), weights()) -> float().
+weight(L, Weights) -> weight_scaled(L, 1.0, Weights).
+
+-spec compute_weights(target_cfg(), target_module(), target_context(),
+ comp_options()) -> weights().
+compute_weights(CFG, TargetMod, TargetContext, Options) ->
+ case proplists:get_bool(range_split_weights, Options) of
+ false -> no_bb_weights;
+ true ->
+ {hipe_bb_weights:compute(CFG, TargetMod, TargetContext),
+ ?WEIGHT_CONST_FUN(proplists:get_value(range_split_weight_power,
+ Options, ?DEFAULT_WEIGHT_POWER))}
+ end.
+
+-spec weight_scaled(label(), float(), weights()) -> float().
+weight_scaled(_L, _Scale, no_bb_weights) -> 1.0;
+weight_scaled(L, Scale, {Weights, Const}) ->
+ Wt0 = hipe_bb_weights:weight(L, Weights) * Scale,
+ Wt = erlang:min(erlang:max(Wt0, 0.0000000000000000001), 10000.0),
+ ?WEIGHT_FUN(Wt, Const).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Heuristic splitting decision.
+%%
+%% Decide which temps to split, in which parts, and pick new names for them.
+-type spill_mode() :: mode1 % Spill temps at partition exits
+ | mode2 % Spill temps at definitions
+ | mode3.% Spill temps at definitions, restore temps at uses
+-type ren() :: #{temp() => {spill_mode(), temp()}}.
+-type renames() :: #{label() => ren()}.
+
+-record(heur_par, {
+ mode1_fudge :: float(),
+ min_gain :: float()
+ }).
+-type heur_par() :: #heur_par{}.
+
+-spec decide(ducounts(), costs(), target(), comp_options()) -> renames().
+decide(DUCounts, Costs, Target, Options) ->
+ Par = #heur_par{
+ mode1_fudge = proplists:get_value(range_split_mode1_fudge, Options,
+ ?DEFAULT_MODE1_FUDGE),
+ min_gain = proplists:get_value(range_split_min_gain, Options,
+ ?DEFAULT_MIN_GAIN)},
+ decide_parts(maps:to_list(DUCounts), Costs, Target, Par, #{}).
+
+-spec decide_parts([{part_key(), ducount()}], costs(), target(),
+ heur_par(), renames())
+ -> renames().
+decide_parts([], _Costs, _Target, _Par, Acc) -> Acc;
+decide_parts([{Part,DUCount}|Ps], Costs, Target, Par, Acc) ->
+ Spills = decide_temps(ducount_to_list(DUCount), Part, Costs, Target, Par,
+ #{}),
+ decide_parts(Ps, Costs, Target, Par, Acc#{Part => Spills}).
+
+-spec decide_temps([{temp(), float()}], part_key(), costs(), target(),
+ heur_par(), ren())
+ -> ren().
+decide_temps([], _Part, _Costs, _Target, _Par, Acc) -> Acc;
+decide_temps([{Temp, SpillGain}|Ts], Part, Costs, Target, Par, Acc0) ->
+ SpillCost1 = costs_query(Temp, entry1, Part, Costs)
+ + costs_query(Temp, exit, Part, Costs),
+ SpillCost2 = costs_query(Temp, entry2, Part, Costs)
+ + costs_query(Temp, spill, Part, Costs),
+ SpillCost3 = costs_query(Temp, restore, Part, Costs),
+ Acc =
+ %% SpillCost1 =:= 0.0 usually means the temp is local to the partition;
+ %% hence no need to split it
+ case (SpillCost1 =/= 0.0) %% maps:is_key(Temp, S)
+ andalso (not is_precoloured(Temp, Target))
+ andalso ((Par#heur_par.min_gain*SpillCost1 < SpillGain)
+ orelse (Par#heur_par.min_gain*SpillCost2 < SpillGain)
+ orelse (Par#heur_par.min_gain*SpillCost3 < SpillGain))
+ of
+ false -> Acc0;
+ true ->
+ Mode =
+ if Par#heur_par.mode1_fudge*SpillCost1 < SpillCost2,
+ Par#heur_par.mode1_fudge*SpillCost1 < SpillCost3 ->
+ mode1;
+ SpillCost2 < SpillCost3 ->
+ mode2;
+ true ->
+ mode3
+ end,
+ Acc0#{Temp => {Mode, new_reg_nr(Target)}}
+ end,
+ decide_temps(Ts, Part, Costs, Target, Par, Acc).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Eighth pass: Rewrite program performing range splitting.
+
+-spec rewrite(cfg(), target_cfg(), target(), liveness(), plive(), defs(),
+ avail(), part_dsets_map(), renames(), temps())
+ -> target_cfg().
+rewrite(#cfg{bbs=BBs}, TCFG, Target, Liveness, PLive, Defs, Avail, DSets,
+ Renames, Temps) ->
+ rewrite_bbs(maps:to_list(BBs), Target, Liveness, PLive, Defs, Avail, DSets,
+ Renames, Temps, TCFG).
+
+-spec rewrite_bbs([{label(), bb()}], target(), liveness(), plive(), defs(),
+ avail(), part_dsets_map(), renames(), temps(), target_cfg())
+ -> target_cfg().
+rewrite_bbs([], _Target, _Liveness, _PLive, _Defs, _Avail, _DSets, _Renames,
+ _Temps, TCFG) ->
+ TCFG;
+rewrite_bbs([{L,BB}|BBs], Target, Liveness, PLive, Defs, Avail, DSets, Renames,
+ Temps, TCFG0) ->
+ Code0Rev = lists:reverse(bb_code(BB)),
+ EntryRen = maps:get(maps:get(L,DSets), Renames),
+ M3Ren = mode3_block_renameset(L, Avail),
+ SubstFun = rewrite_subst_fun(Target, EntryRen, M3Ren),
+ Fun = fun(I) -> subst_temps(SubstFun, I, Target) end,
+ {Code, TCFG} =
+ case bb_has_call(BB) of
+ false ->
+ Code1 = rewrite_instrs(Code0Rev, Fun, EntryRen, M3Ren, Temps, Target,
+ []),
+ {Code1, TCFG0};
+ true ->
+ CallI0 = hd(Code0Rev),
+ Succ = bb_succ(BB),
+ {CallTI, TCFG1} = inject_restores(Succ, Target, Liveness, PLive, DSets,
+ Renames, Temps, CallI0#instr.i, TCFG0),
+ Liveout1 = liveness_step(CallI0, liveout(Liveness, L, Target)),
+ Defout = defbutlast(L, Defs),
+ SpillMap = mk_spillmap(EntryRen, Liveout1, Defout, Temps, Target),
+ Code1 = rewrite_instrs(tl(Code0Rev), Fun, EntryRen, M3Ren, Temps,
+ Target, []),
+ Code2 = lift_spills(lists:reverse(Code1), Target, SpillMap, [CallTI]),
+ {Code2, TCFG1}
+ end,
+ TBB = hipe_bb:code_update(bb(TCFG, L, Target), Code),
+ rewrite_bbs(BBs, Target, Liveness, PLive, Defs, Avail, DSets, Renames, Temps,
+ update_bb(TCFG, L, TBB, Target)).
+
+-spec rewrite_instrs([code_elem()], rewrite_fun(), ren(),
+ ordsets:ordset(temp()), temps(), target(),
+ [target_instr()])
+ -> [target_instr()].
+rewrite_instrs([], _Fun, _Ren, _M3Ren, _Temps, _Target, Acc) -> Acc;
+rewrite_instrs([I|Is], Fun, Ren, M3Ren, Temps, Target, Acc0) ->
+ Acc =
+ case I of
+ #instr{i=TI} -> [Fun(TI)|Acc0];
+ #mode2_spills{temps=Mode2Spills} ->
+ add_mode2_spills(Mode2Spills, Target, Ren, M3Ren, Temps, Acc0);
+ #mode3_restores{temps=Mode3Restores} ->
+ add_mode3_restores(Mode3Restores, Target, Ren, Temps, Acc0)
+ end,
+ rewrite_instrs(Is, Fun, Ren, M3Ren, Temps, Target, Acc).
+
+-spec add_mode2_spills(ordsets:ordset(temp()), target(), ren(),
+ ordsets:ordset(temp()), temps(), [target_instr()])
+ -> [target_instr()].
+add_mode2_spills([], _Target, _Ren, _M3Ren, _Temps, Acc) -> Acc;
+add_mode2_spills([R|Rs], Target, Ren, M3Ren, Temps, Acc0) ->
+ Acc =
+ case Ren of
+ #{R := {Mode, NewName}} when Mode =:= mode2; Mode =:= mode3 ->
+ case Mode =/= mode3 orelse lists:member(R, M3Ren) of
+ false -> Acc0;
+ true ->
+ #{R := T} = Temps,
+ SpillInstr = mk_move(update_reg_nr(NewName, T, Target), T, Target),
+ [SpillInstr|Acc0]
+ end;
+ #{} ->
+ Acc0
+ end,
+ add_mode2_spills(Rs, Target, Ren, M3Ren, Temps, Acc).
+
+-spec add_mode3_restores(ordsets:ordset(temp()), target(), ren(), temps(),
+ [target_instr()])
+ -> [target_instr()].
+add_mode3_restores([], _Target, _Ren, _Temps, Acc) -> Acc;
+add_mode3_restores([R|Rs], Target, Ren, Temps, Acc) ->
+ case Ren of
+ #{R := {mode3, NewName}} ->
+ #{R := T} = Temps,
+ RestoreInstr = mk_move(T, update_reg_nr(NewName, T, Target), Target),
+ add_mode3_restores(Rs, Target, Ren, Temps, [RestoreInstr|Acc]);
+ #{} ->
+ add_mode3_restores(Rs, Target, Ren, Temps, Acc)
+ end.
+
+-type rewrite_fun() :: fun((target_instr()) -> target_instr()).
+-type subst_fun() :: fun((target_temp()) -> target_temp()).
+-spec rewrite_subst_fun(target(), ren(), ordsets:ordset(temp())) -> subst_fun().
+rewrite_subst_fun(Target, Ren, M3Ren) ->
+ fun(Temp) ->
+ Reg = reg_nr(Temp, Target),
+ case Ren of
+ #{Reg := {Mode, NewName}} ->
+ case Mode =/= mode3 orelse lists:member(Reg, M3Ren) of
+ false -> Temp;
+ true -> update_reg_nr(NewName, Temp, Target)
+ end;
+ #{} -> Temp
+ end
+ end.
+
+-type spillmap() :: [{temp(), target_instr()}].
+-spec mk_spillmap(ren(), liveset(), defsetf(), temps(), target())
+ -> spillmap().
+mk_spillmap(Ren, Livein, Defout, Temps, Target) ->
+ [begin
+ Temp = maps:get(Reg, Temps),
+ {NewName, mk_move(update_reg_nr(NewName, Temp, Target), Temp, Target)}
+ end || {Reg, {mode1, NewName}} <- maps:to_list(Ren),
+ lists:member(Reg, Livein), defsetf_member(Reg, Defout)].
+
+-spec mk_restores(ren(), liveset(), liveset(), temps(), target())
+ -> [target_instr()].
+mk_restores(Ren, Livein, PLivein, Temps, Target) ->
+ [begin
+ Temp = maps:get(Reg, Temps),
+ mk_move(Temp, update_reg_nr(NewName, Temp, Target), Target)
+ end || {Reg, {Mode, NewName}} <- maps:to_list(Ren),
+ ( (Mode =:= mode1 andalso lists:member(Reg, Livein ))
+ orelse (Mode =:= mode2 andalso lists:member(Reg, PLivein)))].
+
+-spec inject_restores([label()], target(), liveness(), plive(),
+ part_dsets_map(), renames(), temps(), target_instr(),
+ target_cfg())
+ -> {target_instr(), target_cfg()}.
+inject_restores([], _Target, _Liveness, _PLive, _DSets, _Renames, _Temps, CFTI,
+ TCFG) ->
+ {CFTI, TCFG};
+inject_restores([L|Ls], Target, Liveness, PLive, DSets, Renames, Temps, CFTI0,
+ TCFG0) ->
+ Ren = maps:get(maps:get(L,DSets), Renames),
+ Livein = livein(Liveness, L, Target),
+ PLivein = plivein(L, PLive),
+ {CFTI, TCFG} =
+ case mk_restores(Ren, Livein, PLivein, Temps, Target) of
+ [] -> {CFTI0, TCFG0}; % optimisation
+ Restores ->
+ RestBBLbl = new_label(Target),
+ Code = Restores ++ [mk_goto(L, Target)],
+ CFTI1 = redirect_jmp(CFTI0, L, RestBBLbl, Target),
+ TCFG1 = update_bb(TCFG0, RestBBLbl, hipe_bb:mk_bb(Code), Target),
+ {CFTI1, TCFG1}
+ end,
+ inject_restores(Ls, Target, Liveness, PLive, DSets, Renames, Temps, CFTI,
+ TCFG).
+
+%% Heuristic. Move spills up until we meet the edge of the BB or a definition of
+%% that temp.
+-spec lift_spills([target_instr()], target(), spillmap(), [target_instr()])
+ -> [target_instr()].
+lift_spills([], _Target, SpillMap, Acc) ->
+ [SpillI || {_, SpillI} <- SpillMap] ++ Acc;
+lift_spills([I|Is], Target, SpillMap0, Acc) ->
+ Def = reg_defines(I, Target),
+ {Spills0, SpillMap} =
+ lists:partition(fun({Reg,_}) -> lists:member(Reg, Def) end, SpillMap0),
+ Spills = [SpillI || {_, SpillI} <- Spills0],
+ lift_spills(Is, Target, SpillMap, [I|Spills ++ Acc]).
+
+reg_defines(I, Target) ->
+ reg_names(defines(I,Target), Target).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Costs ADT
+%%
+%% Keeps track of cumulative cost of spilling temps in particular partitions
+%% using particular spill modes.
+-type cost_map() :: #{[part_key()|temp()] => float()}.
+-type cost_key() :: entry1 | entry2 | exit | spill | restore.
+-record(costs, {entry1 = #{} :: cost_map()
+ ,entry2 = #{} :: cost_map()
+ ,exit = #{} :: cost_map()
+ ,spill = #{} :: cost_map()
+ ,restore = #{} :: cost_map()
+ }).
+-type costs() :: #costs{}.
+
+-spec costs_new() -> costs().
+costs_new() -> #costs{}.
+
+-spec costs_insert(cost_key(), part_key(), float(), liveset(), costs())
+ -> costs().
+costs_insert(entry1, A, Weight, Liveset, Costs=#costs{entry1=Entry1}) ->
+ Costs#costs{entry1=costs_insert_1(A, Weight, Liveset, Entry1)};
+costs_insert(entry2, A, Weight, Liveset, Costs=#costs{entry2=Entry2}) ->
+ Costs#costs{entry2=costs_insert_1(A, Weight, Liveset, Entry2)};
+costs_insert(exit, A, Weight, Liveset, Costs=#costs{exit=Exit}) ->
+ Costs#costs{exit=costs_insert_1(A, Weight, Liveset, Exit)};
+costs_insert(spill, A, Weight, Liveset, Costs=#costs{spill=Spill}) ->
+ Costs#costs{spill=costs_insert_1(A, Weight, Liveset, Spill)};
+costs_insert(restore, A, Weight, Liveset, Costs=#costs{restore=Restore}) ->
+ Costs#costs{restore=costs_insert_1(A, Weight, Liveset, Restore)}.
+
+costs_insert_1(A, Weight, Liveset, CostMap0) when is_float(Weight) ->
+ lists:foldl(fun(Live, CostMap1) ->
+ map_update_counter([A|Live], Weight, CostMap1)
+ end, CostMap0, Liveset).
+
+-spec costs_map_roots(part_dsets(), costs()) -> {costs(), part_dsets()}.
+costs_map_roots(DSets0, Costs) ->
+ {Entry1, DSets1} = costs_map_roots_1(DSets0, Costs#costs.entry1),
+ {Entry2, DSets2} = costs_map_roots_1(DSets1, Costs#costs.entry2),
+ {Exit, DSets3} = costs_map_roots_1(DSets2, Costs#costs.exit),
+ {Spill, DSets4} = costs_map_roots_1(DSets3, Costs#costs.spill),
+ {Restore, DSets} = costs_map_roots_1(DSets4, Costs#costs.restore),
+ {#costs{entry1=Entry1,entry2=Entry2,exit=Exit,spill=Spill,restore=Restore},
+ DSets}.
+
+costs_map_roots_1(DSets0, CostMap) ->
+ {NewEs, DSets} = lists:mapfoldl(fun({[A|T], Wt}, DSets1) ->
+ {AR, DSets2} = hipe_dsets:find(A, DSets1),
+ {{[AR|T], Wt}, DSets2}
+ end, DSets0, maps:to_list(CostMap)),
+ {maps_from_list_merge(NewEs, fun erlang:'+'/2, #{}), DSets}.
+
+maps_from_list_merge([], _MF, Acc) -> Acc;
+maps_from_list_merge([{K,V}|Ps], MF, Acc) ->
+ maps_from_list_merge(Ps, MF, case Acc of
+ #{K := OV} -> Acc#{K := MF(V, OV)};
+ #{} -> Acc#{K => V}
+ end).
+
+-spec costs_query(temp(), cost_key(), part_key(), costs()) -> float().
+costs_query(Temp, entry1, Part, #costs{entry1=Entry1}) ->
+ costs_query_1(Temp, Part, Entry1);
+costs_query(Temp, entry2, Part, #costs{entry2=Entry2}) ->
+ costs_query_1(Temp, Part, Entry2);
+costs_query(Temp, exit, Part, #costs{exit=Exit}) ->
+ costs_query_1(Temp, Part, Exit);
+costs_query(Temp, spill, Part, #costs{spill=Spill}) ->
+ costs_query_1(Temp, Part, Spill);
+costs_query(Temp, restore, Part, #costs{restore=Restore}) ->
+ costs_query_1(Temp, Part, Restore).
+
+costs_query_1(Temp, Part, CostMap) ->
+ Key = [Part|Temp],
+ case CostMap of
+ #{Key := Wt} -> Wt;
+ #{} -> 0.0
+ end.
+
+-spec map_update_counter(Key, number(), #{Key => number(), OK => OV})
+ -> #{Key := number(), OK => OV}.
+map_update_counter(Key, Incr, Map) ->
+ case Map of
+ #{Key := Orig} -> Map#{Key := Orig + Incr};
+ #{} -> Map#{Key => Incr}
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Def and use counting ADT
+-type ducount() :: #{temp() => float()}.
+
+-spec ducount_new() -> ducount().
+ducount_new() -> #{}.
+
+-spec ducount_add([temp()], float(), ducount()) -> ducount().
+ducount_add([], _Weight, DUCount) -> DUCount;
+ducount_add([T|Ts], Weight, DUCount0) ->
+ DUCount =
+ case DUCount0 of
+ #{T := Count} -> DUCount0#{T := Count + Weight};
+ #{} -> DUCount0#{T => Weight}
+ end,
+ ducount_add(Ts, Weight, DUCount).
+
+ducount_to_list(DUCount) -> maps:to_list(DUCount).
+
+-spec ducount_merge(ducount(), ducount()) -> ducount().
+ducount_merge(DCA, DCB) when map_size(DCA) < map_size(DCB) ->
+ ducount_merge_1(ducount_to_list(DCA), DCB);
+ducount_merge(DCA, DCB) when map_size(DCA) >= map_size(DCB) ->
+ ducount_merge_1(ducount_to_list(DCB), DCA).
+
+ducount_merge_1([], DUCount) -> DUCount;
+ducount_merge_1([{T,AC}|Ts], DUCount0) ->
+ DUCount =
+ case DUCount0 of
+ #{T := BC} -> DUCount0#{T := AC + BC};
+ #{} -> DUCount0#{T => AC}
+ end,
+ ducount_merge_1(Ts, DUCount).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Target module interface functions
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-define(TGT_IFACE_0(N), N( {M,C}) -> M:N( C)).
+-define(TGT_IFACE_1(N), N(A1, {M,C}) -> M:N(A1, C)).
+-define(TGT_IFACE_2(N), N(A1,A2, {M,C}) -> M:N(A1,A2, C)).
+-define(TGT_IFACE_3(N), N(A1,A2,A3,{M,C}) -> M:N(A1,A2,A3,C)).
+
+?TGT_IFACE_2(bb).
+?TGT_IFACE_1(def_use).
+?TGT_IFACE_1(defines).
+?TGT_IFACE_1(defines_all_alloc).
+?TGT_IFACE_1(is_precoloured).
+?TGT_IFACE_1(mk_goto).
+?TGT_IFACE_2(mk_move).
+?TGT_IFACE_0(new_label).
+?TGT_IFACE_0(new_reg_nr).
+?TGT_IFACE_1(number_of_temporaries).
+?TGT_IFACE_3(redirect_jmp).
+?TGT_IFACE_1(reg_nr).
+?TGT_IFACE_1(reverse_postorder).
+?TGT_IFACE_2(subst_temps).
+?TGT_IFACE_3(update_bb).
+?TGT_IFACE_2(update_reg_nr).
+
+branch_preds(Instr, {TgtMod,TgtCtx}) ->
+ merge_sorted_preds(lists:keysort(1, TgtMod:branch_preds(Instr, TgtCtx))).
+
+livein(Liveness, L, Target={TgtMod,TgtCtx}) ->
+ ordsets:from_list(reg_names(TgtMod:livein(Liveness, L, TgtCtx), Target)).
+
+liveout(Liveness, L, Target={TgtMod,TgtCtx}) ->
+ ordsets:from_list(reg_names(TgtMod:liveout(Liveness, L, TgtCtx), Target)).
+
+merge_sorted_preds([]) -> [];
+merge_sorted_preds([{L, P1}, {L, P2}|LPs]) ->
+ merge_sorted_preds([{L, P1+P2}|LPs]);
+merge_sorted_preds([LP|LPs]) -> [LP|merge_sorted_preds(LPs)].
+
+reg_names(Regs, {TgtMod,TgtCtx}) ->
+ [TgtMod:reg_nr(X,TgtCtx) || X <- Regs].
diff --git a/lib/hipe/regalloc/hipe_reg_worklists.erl b/lib/hipe/regalloc/hipe_reg_worklists.erl
index 88585f9f38..415f1d6122 100644
--- a/lib/hipe/regalloc/hipe_reg_worklists.erl
+++ b/lib/hipe/regalloc/hipe_reg_worklists.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%----------------------------------------------------------------------
%%% File : hipe_reg_worklists.erl
@@ -30,8 +24,8 @@
-module(hipe_reg_worklists).
-author(['Andreas Wallin', 'Thorild Selén']).
--export([new/5, % only used by optimistic allocator
- new/6,
+-export([new/6, % only used by optimistic allocator
+ new/7,
simplify/1,
spill/1,
freeze/1,
@@ -90,29 +84,32 @@
%%
%%%----------------------------------------------------------------------
-new(IG, Target, CFG, K, No_temporaries) -> % only used by optimistic allocator
+%% only used by optimistic allocator
+new(IG, TargetMod, TargetCtx, CFG, K, No_temporaries) ->
CoalescedTo = hipe_bifs:array(No_temporaries, 'none'),
- init(initial(Target, CFG), K, IG, empty(No_temporaries, CoalescedTo)).
+ init(initial(TargetMod, TargetCtx, CFG), K, IG,
+ empty(No_temporaries, CoalescedTo)).
-new(IG, Target, CFG, Move_sets, K, No_temporaries) ->
- init(initial(Target, CFG), K, IG, Move_sets, empty(No_temporaries, [])).
+new(IG, TargetMod, TargetCtx, CFG, Move_sets, K, No_temporaries) ->
+ init(initial(TargetMod, TargetCtx, CFG), K, IG, Move_sets,
+ empty(No_temporaries, [])).
-initial(Target, CFG) ->
- {Min_temporary, Max_temporary} = Target:var_range(CFG),
- NonAlloc = Target:non_alloc(CFG),
- non_precoloured(Target, Min_temporary, Max_temporary, [])
- -- [Target:reg_nr(X) || X <- NonAlloc].
+initial(TargetMod, TargetCtx, CFG) ->
+ {Min_temporary, Max_temporary} = TargetMod:var_range(CFG, TargetCtx),
+ NonAlloc = TargetMod:non_alloc(CFG, TargetCtx),
+ non_precoloured(TargetMod, TargetCtx, Min_temporary, Max_temporary, [])
+ -- [TargetMod:reg_nr(X, TargetCtx) || X <- NonAlloc].
-non_precoloured(Target, Current, Max_temporary, Initial) ->
+non_precoloured(TargetMod, TargetCtx, Current, Max_temporary, Initial) ->
if Current > Max_temporary ->
Initial;
true ->
NewInitial =
- case Target:is_precoloured(Current) of
+ case TargetMod:is_precoloured(Current, TargetCtx) of
true -> Initial;
false -> [Current|Initial]
end,
- non_precoloured(Target, Current+1, Max_temporary, NewInitial)
+ non_precoloured(TargetMod, TargetCtx, Current+1, Max_temporary, NewInitial)
end.
%% construct an empty initialized worklists data structure
diff --git a/lib/hipe/regalloc/hipe_regalloc_loop.erl b/lib/hipe/regalloc/hipe_regalloc_loop.erl
index d29615a3a0..29ef3adcc2 100644
--- a/lib/hipe/regalloc/hipe_regalloc_loop.erl
+++ b/lib/hipe/regalloc/hipe_regalloc_loop.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,44 +11,50 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Common wrapper for graph_coloring and coalescing regallocs.
-module(hipe_regalloc_loop).
--export([ra/5, ra_fp/4]).
+-export([ra/7, ra_fp/6]).
%%-define(HIPE_INSTRUMENT_COMPILER, true). %% Turn on instrumentation.
-include("../main/hipe.hrl").
-ra(Defun, SpillIndex, Options, RegAllocMod, TargetMod) ->
- {NewDefun, Coloring, _NewSpillIndex} =
- ra_common(Defun, SpillIndex, Options, RegAllocMod, TargetMod),
- {NewDefun, Coloring}.
+ra(CFG, Liveness0, SpillIndex, Options, RegAllocMod, TargetMod, TargetCtx) ->
+ {NewCFG, Liveness, Coloring, _NewSpillIndex} =
+ ra_common(CFG, Liveness0, SpillIndex, Options, RegAllocMod, TargetMod,
+ TargetCtx),
+ {NewCFG, Liveness, Coloring}.
-ra_fp(Defun, Options, RegAllocMod, TargetMod) ->
- ra_common(Defun, 0, Options, RegAllocMod, TargetMod).
+ra_fp(CFG, Liveness, Options, RegAllocMod, TargetMod, TargetCtx) ->
+ ra_common(CFG, Liveness, 0, Options, RegAllocMod, TargetMod, TargetCtx).
-ra_common(Defun, SpillIndex, Options, RegAllocMod, TargetMod) ->
+ra_common(CFG0, Liveness0, SpillIndex, Options, RegAllocMod, TargetMod,
+ TargetCtx) ->
?inc_counter(ra_calls_counter, 1),
- CFG = TargetMod:defun_to_cfg(Defun),
- SpillLimit = TargetMod:number_of_temporaries(CFG),
- alloc(Defun, SpillLimit, SpillIndex, Options, RegAllocMod, TargetMod).
+ {CFG1, Liveness1} =
+ do_range_split(CFG0, Liveness0, TargetMod, TargetCtx, Options),
+ SpillLimit0 = TargetMod:number_of_temporaries(CFG1, TargetCtx),
+ {Coloring, _, CFG, Liveness} =
+ call_allocator_initial(CFG1, Liveness1, SpillLimit0, SpillIndex, Options,
+ RegAllocMod, TargetMod, TargetCtx),
+ %% The first iteration, the hipe_regalloc_prepass may create new temps, these
+ %% should not end up above SpillLimit.
+ SpillLimit = TargetMod:number_of_temporaries(CFG, TargetCtx),
+ alloc(Coloring, CFG, Liveness, SpillLimit, SpillIndex, Options,
+ RegAllocMod, TargetMod, TargetCtx).
-alloc(Defun, SpillLimit, SpillIndex, Options, RegAllocMod, TargetMod) ->
+alloc(Coloring, CFG0, Liveness, SpillLimit, SpillIndex, Options,
+ RegAllocMod, TargetMod, TargetCtx) ->
?inc_counter(ra_iteration_counter, 1),
- CFG = TargetMod:defun_to_cfg(Defun),
- {Coloring, _NewSpillIndex} =
- RegAllocMod:regalloc(CFG, SpillIndex, SpillLimit, TargetMod, Options),
- {NewDefun, DidSpill} = TargetMod:check_and_rewrite(Defun, Coloring),
+ {CFG, DidSpill} = TargetMod:check_and_rewrite(CFG0, Coloring, TargetCtx),
case DidSpill of
false -> %% No new temps, we are done.
?add_spills(Options, _NewSpillIndex),
- TempMap = hipe_temp_map:cols2tuple(Coloring, TargetMod),
- {TempMap2, NewSpillIndex2} =
- hipe_spillmin:stackalloc(CFG, [], SpillIndex, Options,
- TargetMod, TempMap),
+ TempMap = hipe_temp_map:cols2tuple(Coloring, TargetMod, TargetCtx),
+ {TempMap2, NewSpillIndex2} =
+ hipe_spillmin:stackalloc(CFG0, Liveness, [], SpillIndex, Options,
+ TargetMod, TargetCtx, TempMap),
Coloring2 =
hipe_spillmin:mapmerge(hipe_temp_map:to_substlist(TempMap), TempMap2),
%% case proplists:get_bool(verbose_spills, Options) of
@@ -61,9 +63,55 @@ alloc(Defun, SpillLimit, SpillIndex, Options, RegAllocMod, TargetMod) ->
%% false ->
%% ok
%% end,
- {NewDefun, Coloring2, NewSpillIndex2};
+ {CFG, Liveness, Coloring2, NewSpillIndex2};
_ ->
%% Since SpillLimit is used as a low-water-mark
%% the list of temps not to spill is uninteresting.
- alloc(NewDefun, SpillLimit, SpillIndex, Options, RegAllocMod, TargetMod)
+ {NewColoring, _NewSpillIndex} =
+ call_allocator(CFG, Liveness, SpillLimit, SpillIndex, Options,
+ RegAllocMod, TargetMod, TargetCtx),
+ alloc(NewColoring, CFG, Liveness, SpillLimit, SpillIndex, Options,
+ RegAllocMod, TargetMod, TargetCtx)
+ end.
+
+call_allocator_initial(CFG, Liveness, SpillLimit, SpillIndex, Options,
+ RegAllocMod, TargetMod, TargetCtx) ->
+ case proplists:get_bool(ra_prespill, Options) of
+ true ->
+ hipe_regalloc_prepass:regalloc_initial(
+ RegAllocMod, CFG, Liveness, SpillIndex, SpillLimit, TargetMod,
+ TargetCtx, Options);
+ false ->
+ {C, SI} = RegAllocMod:regalloc(CFG, Liveness, SpillIndex, SpillLimit,
+ TargetMod, TargetCtx, Options),
+ {C, SI, CFG, Liveness}
+ end.
+
+call_allocator(CFG, Liveness, SpillLimit, SpillIndex, Options, RegAllocMod,
+ TargetMod, TargetCtx) ->
+ case proplists:get_bool(ra_prespill, Options) of
+ true ->
+ hipe_regalloc_prepass:regalloc(
+ RegAllocMod, CFG, Liveness, SpillIndex, SpillLimit, TargetMod,
+ TargetCtx, Options);
+ false ->
+ RegAllocMod:regalloc(CFG, Liveness, SpillIndex, SpillLimit, TargetMod,
+ TargetCtx, Options)
+ end.
+
+do_range_split(CFG0, Liveness0, TgtMod, TgtCtx, Options) ->
+ {CFG2, Liveness1} =
+ case proplists:get_bool(ra_restore_reuse, Options) of
+ true ->
+ CFG1 = hipe_restore_reuse:split(CFG0, Liveness0, TgtMod, TgtCtx),
+ {CFG1, TgtMod:analyze(CFG1, TgtCtx)};
+ false ->
+ {CFG0, Liveness0}
+ end,
+ case proplists:get_bool(ra_range_split, Options) of
+ true ->
+ CFG3 = hipe_range_split:split(CFG2, Liveness1, TgtMod, TgtCtx, Options),
+ {CFG3, TgtMod:analyze(CFG3, TgtCtx)};
+ false ->
+ {CFG2, Liveness1}
end.
diff --git a/lib/hipe/regalloc/hipe_regalloc_prepass.erl b/lib/hipe/regalloc/hipe_regalloc_prepass.erl
new file mode 100644
index 0000000000..5024840237
--- /dev/null
+++ b/lib/hipe/regalloc/hipe_regalloc_prepass.erl
@@ -0,0 +1,953 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%@doc
+%% PREPASS FOR ITERATED REGISTER ALLOCATORS
+%%
+%% Implements a trivial partial but optimal fast register allocator to be used
+%% as the first pass of the register allocation loop.
+%%
+%% The idea is to drastically reduce the number of temporaries, so as to speed
+%% up the real register allocators.
+%%
+%% * Spills trivially unallocatable temps
+%% This relies on the fact that calls intentionally clobber all registers.
+%% Since this is the case, any temp that is alive over a call can't possibly
+%% be allocated to anything but a spill slot.
+%%
+%% * Partitions the program at points where no pseudos that were not spiled are
+%% live, and then do register allocation on these partitions independently.
+%% These program points are commonly, but not exclusively, the call
+%% instructions.
+%%
+%% TODO
+%% * This module seems very successful at finding every single spill; register
+%% allocation performance should be improved if we short-circuit the first
+%% hipe_regalloc_loop iteration, skipping directly to rewrite without ever
+%% calling RegAllocMod.
+-module(hipe_regalloc_prepass).
+-export([regalloc/8, regalloc_initial/8]).
+
+-ifndef(DEBUG).
+-compile(inline).
+-endif.
+
+%%-define(DO_ASSERT, 1).
+-include("../main/hipe.hrl").
+
+%%% TUNABLES
+
+%% Partitions with fewer than ?TUNE_TOO_FEW_BBS basic block halves are merged
+%% together before register allocation.
+-define(TUNE_TOO_FEW_BBS, 256).
+
+%% Ignore the ra_partitioned option (and do whole function RA instead) when
+%% there are fewer than ?TUNE_MIN_SPLIT_BBS basic blocks.
+-define(TUNE_MIN_SPLIT_BBS, 384).
+
+%% We present a "pseudo-target" to the register allocator we wrap.
+-export([analyze/2,
+ all_precoloured/1,
+ allocatable/1,
+ args/2,
+ bb/3,
+ def_use/2,
+ defines/2,
+ is_fixed/2, % used by hipe_graph_coloring_regalloc
+ is_global/2,
+ is_move/2,
+ is_precoloured/2,
+ labels/2,
+ livein/3,
+ liveout/3,
+ non_alloc/2,
+ number_of_temporaries/2,
+ physical_name/2,
+ postorder/2,
+ reg_nr/2,
+ uses/2,
+ var_range/2,
+ reverse_postorder/2]).
+
+-record(prepass_ctx,
+ {target_mod :: module()
+ ,target_ctx :: target_context()
+ ,sub :: sub_map() % Translates temp numbers found in CFG and understood by
+ % Target to temp numbers passed to RegAllocMod.
+ ,inv :: inv_map() % Translates temp numbers passed to RegAllocMod
+ % to temp numbers found in CFG and understood by
+ % Target
+ ,max_phys :: temp() % Exclusive upper bound on physical registers
+ }).
+
+-record(cfg,
+ {cfg :: target_cfg()
+ ,bbs :: transformed_bbs()
+ ,max_reg :: temp() % Exclusive upper bound on temp numbers
+ ,rpostorder :: undefined % Only precomputed with partitioned cfg
+ | [label()]
+ }).
+
+-type bb() :: hipe_bb:bb(). % containing instr()
+-type liveset() :: ordsets:ordset(temp()).
+-record(transformed_bb,
+ {bb :: bb()
+ ,livein :: liveset()
+ ,liveout :: liveset()
+ }).
+-type transformed_bb() :: #transformed_bb{}.
+-type transformed_bbs() :: #{label() => transformed_bb()}.
+
+-record(instr,
+ {defuse :: {[temp()], [temp()]}
+ ,is_move :: boolean()
+ }).
+-type instr() :: #instr{}.
+
+-type target_cfg() :: any().
+-type target_instr() :: any().
+-type target_temp() :: any().
+-type target_reg() :: non_neg_integer().
+-type target_liveness() :: any().
+-type target_liveset() :: ordsets:ordset(target_reg()).
+-type target_context() :: any().
+-type spillno() :: non_neg_integer().
+-type temp() :: non_neg_integer().
+-type label() :: non_neg_integer().
+
+-spec regalloc(module(), target_cfg(), target_liveness(), spillno(), spillno(),
+ module(), target_context(), proplists:proplist())
+ -> {hipe_map(), spillno()}.
+regalloc(RegAllocMod, CFG, Liveness, SpillIndex0, SpillLimit, TargetMod,
+ TargetCtx, Options) ->
+ {Coloring, SpillIndex, same} =
+ regalloc_1(RegAllocMod, CFG, SpillIndex0, SpillLimit, TargetMod,
+ TargetCtx, Options, Liveness),
+ {Coloring, SpillIndex}.
+
+%% regalloc_initial/7 is allowed to introduce new temporaries, unlike
+%% regalloc/7.
+%% In order for regalloc/7 to never introduce temporaries, regalloc/7 must never
+%% choose to do split allocation unless regalloc_initial/7 does. This is the
+%% reason that the splitting heuristic is solely based on the number of basic
+%% blocks, which does not change during the register allocation loop.
+-spec regalloc_initial(module(), target_cfg(), target_liveness(), spillno(),
+ spillno(), module(), target_context(),
+ proplists:proplist())
+ -> {hipe_map(), spillno(), target_cfg(),
+ target_liveness()}.
+regalloc_initial(RegAllocMod, CFG0, Liveness0, SpillIndex0, SpillLimit,
+ TargetMod, TargetCtx, Options) ->
+ {Coloring, SpillIndex, NewCFG} =
+ regalloc_1(RegAllocMod, CFG0, SpillIndex0, SpillLimit, TargetMod, TargetCtx,
+ Options, Liveness0),
+ {CFG, Liveness} =
+ case NewCFG of
+ same -> {CFG0, Liveness0};
+ {rewritten, CFG1} -> {CFG1, TargetMod:analyze(CFG1, TargetCtx)}
+ end,
+ {Coloring, SpillIndex, CFG, Liveness}.
+
+regalloc_1(RegAllocMod, CFG0, SpillIndex0, SpillLimit, TargetMod, TargetCtx,
+ Options, Liveness) ->
+ {ScanBBs, Seen, SpillMap, SpillIndex1} =
+ scan_cfg(CFG0, Liveness, SpillIndex0, TargetMod, TargetCtx),
+
+ {PartColoring, SpillIndex, NewCFG} =
+ case proplists:get_bool(ra_partitioned, Options)
+ andalso length(TargetMod:labels(CFG0, TargetCtx)) > ?TUNE_MIN_SPLIT_BBS
+ of
+ true ->
+ regalloc_partitioned(SpillMap, SpillIndex1, SpillLimit, ScanBBs,
+ CFG0, TargetMod, TargetCtx, RegAllocMod, Options);
+ _ ->
+ regalloc_whole(Seen, SpillMap, SpillIndex1, SpillLimit, ScanBBs,
+ CFG0, TargetMod, TargetCtx, RegAllocMod, Options)
+ end,
+
+ SpillColors = [{T, {spill, S}} || {T, S} <- maps:to_list(SpillMap)],
+ Coloring = SpillColors ++ PartColoring,
+
+ ?ASSERT(begin
+ AllPrecoloured = TargetMod:all_precoloured(TargetCtx),
+ MaxPhys = lists:max(AllPrecoloured) + 1,
+ Unused = unused(live_pseudos(Seen, SpillMap, MaxPhys),
+ SpillMap, CFG0, TargetMod, TargetCtx),
+ unused_unused(Unused, CFG0, TargetMod, TargetCtx)
+ end),
+ ?ASSERT(begin
+ CFG =
+ case NewCFG of
+ same -> CFG0;
+ {rewritten, CFG1} -> CFG1
+ end,
+ check_coloring(Coloring, CFG, TargetMod, TargetCtx)
+ end), % Sanity-check
+ ?ASSERT(just_as_good_as(RegAllocMod, CFG, Liveness, SpillIndex0, SpillLimit,
+ TargetMod, TargetCtx, Options, SpillMap, Coloring,
+ Unused)),
+ {Coloring, SpillIndex, NewCFG}.
+
+regalloc_whole(Seen, SpillMap, SpillIndex0, SpillLimit, ScanBBs,
+ CFG, TargetMod, TargetCtx, RegAllocMod, Options) ->
+ AllPrecoloured = TargetMod:all_precoloured(TargetCtx),
+ MaxPhys = lists:max(AllPrecoloured) + 1,
+ LivePseudos = live_pseudos(Seen, SpillMap, MaxPhys),
+ {SubMap, InvMap, MaxPhys, MaxR, SubSpillLimit} =
+ number_and_map(AllPrecoloured, LivePseudos, SpillLimit),
+ BBs = transform_whole_cfg(ScanBBs, SubMap),
+ SubMod = #cfg{cfg=CFG, bbs=BBs, max_reg=MaxR},
+ SubContext = #prepass_ctx{target_mod=TargetMod, target_ctx=TargetCtx,
+ max_phys=MaxPhys, inv=InvMap, sub=SubMap},
+ {SubColoring, SpillIndex} =
+ RegAllocMod:regalloc(SubMod, SubMod, SpillIndex0, SubSpillLimit, ?MODULE,
+ SubContext, Options),
+ ?ASSERT(check_coloring(SubColoring, SubMod, ?MODULE, SubContext)),
+ {translate_coloring(SubColoring, InvMap), SpillIndex, same}.
+
+regalloc_partitioned(SpillMap, SpillIndex0, SpillLimit, ScanBBs,
+ CFG, TargetMod, TargetCtx, RegAllocMod, Options) ->
+ AllPrecoloured = TargetMod:all_precoloured(TargetCtx),
+ MaxPhys = lists:max(AllPrecoloured) + 1,
+
+ DSets0 = initial_dsets(CFG, TargetMod, TargetCtx),
+ PartBBList = part_cfg(ScanBBs, SpillMap, MaxPhys),
+ DSets1 = join_whole_blocks(PartBBList, DSets0),
+ {PartBBsRLList, DSets2} = merge_small_parts(DSets1),
+ {PartBBs, DSets3} = merge_pointless_splits(PartBBList, ScanBBs, DSets2),
+ SeenMap = collect_seenmap(PartBBsRLList, PartBBs),
+ {RPostMap, _DSets4} = part_order(TargetMod:reverse_postorder(CFG, TargetCtx),
+ DSets3),
+
+ {Allocations, SpillIndex} =
+ lists:mapfoldl(
+ fun({Root, Elems}, SpillIndex1) ->
+ #{Root := Seen} = SeenMap,
+ #{Root := RPost} = RPostMap,
+ LivePseudos = live_pseudos(Seen, SpillMap, MaxPhys),
+ {SubMap, InvMap, MaxPhys, MaxR, SubSpillLimit} =
+ number_and_map(AllPrecoloured, LivePseudos, SpillLimit),
+ BBs = transform_cfg(Elems, PartBBs, SubMap),
+ SubMod = #cfg{cfg=CFG, bbs=BBs, max_reg=MaxR, rpostorder=RPost},
+ SubContext = #prepass_ctx{target_mod=TargetMod, target_ctx=TargetCtx,
+ max_phys=MaxPhys, inv=InvMap, sub=SubMap},
+ {SubColoring, SpillIndex2} =
+ RegAllocMod:regalloc(SubMod, SubMod, SpillIndex1, SubSpillLimit,
+ ?MODULE, SubContext, Options),
+ ?ASSERT(check_coloring(SubColoring, SubMod, ?MODULE, SubContext)),
+ {{translate_coloring(SubColoring, InvMap), Elems}, SpillIndex2}
+ end, SpillIndex0, PartBBsRLList),
+ {Coloring, NewCFG} =
+ combine_allocations(Allocations, MaxPhys, PartBBs, TargetMod, TargetCtx,
+ CFG),
+ {Coloring, SpillIndex, NewCFG}.
+
+-spec number_and_map([target_reg()], target_liveset(), target_reg())
+ -> {sub_map(), inv_map(), temp(), temp(), temp()}.
+number_and_map(Phys, Pseud, SpillLimit) ->
+ MaxPhys = lists:max(Phys) + 1,
+ ?ASSERT(Pseud =:= [] orelse lists:min(Pseud) >= MaxPhys),
+ NrPseuds = length(Pseud),
+ MaxR = MaxPhys+NrPseuds,
+ PseudNrs = lists:zip(Pseud, lists:seq(MaxPhys, MaxR-1)),
+ MapList = lists:zip(Phys, Phys) % Physicals are identity-mapped
+ ++ PseudNrs,
+ ?ASSERT(MapList =:= lists:ukeysort(1, MapList)),
+ SubMap = {s,maps:from_list(MapList)},
+ InvMap = {i,maps:from_list([{Fake, Real} || {Real, Fake} <- MapList])},
+ SubSpillLimit = translate_spill_limit(MapList, SpillLimit),
+ {SubMap, InvMap, MaxPhys, MaxR, SubSpillLimit}.
+
+-spec translate_spill_limit([{target_reg(), temp()}], target_reg()) -> temp().
+translate_spill_limit([{Real,Fake}], SpillLimit) when Real < SpillLimit ->
+ Fake + 1;
+translate_spill_limit([{Real,_}|Ps], SpillLimit) when Real < SpillLimit ->
+ translate_spill_limit(Ps, SpillLimit);
+translate_spill_limit([{Real,Fake}|_], SpillLimit) when Real >= SpillLimit ->
+ Fake.
+
+-spec live_pseudos(seen(), spill_map(), target_reg()) -> target_liveset().
+live_pseudos(Seen, SpillMap, MaxPhys) ->
+ %% When SpillMap is much larger than Seen (which is typical in the partitioned
+ %% case), it is much more efficient doing it like this than making an ordset
+ %% of the spills and subtracting.
+ ordsets:from_list(
+ lists:filter(fun(R) -> R >= MaxPhys andalso not maps:is_key(R, SpillMap)
+ end, maps:keys(Seen))).
+
+-spec translate_coloring(hipe_map(), inv_map()) -> hipe_map().
+translate_coloring(SubColoring, InvMap) ->
+ lists:map(fun({T, P}) -> {imap_get(T, InvMap), P} end, SubColoring).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% First pass
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Spill trivially unallocatable temps, create internal target-independent
+%% program representation, and collect a set of all used temps.
+-record(spill_state,
+ {map :: spill_map()
+ ,ix :: spillno()
+ }).
+-type spill_state() :: #spill_state{}.
+-type spill_map() :: #{target_reg() => spillno()}.
+
+-spec scan_cfg(target_cfg(), target_liveness(), spillno(), module(),
+ target_context())
+ -> {scan_bbs()
+ ,seen()
+ ,spill_map()
+ ,spillno()
+ }.
+scan_cfg(CFG, Liveness, SpillIndex0, TgtMod, TgtCtx) ->
+ State0 = #spill_state{map=#{}, ix=SpillIndex0},
+ {BBs, Seen, #spill_state{map=Spill, ix=SpillIndex}} =
+ scan_bbs(TgtMod:labels(CFG,TgtCtx), CFG, Liveness, #{}, State0, #{}, TgtMod,
+ TgtCtx),
+ {BBs, Seen, Spill, SpillIndex}.
+
+-type seen() :: #{target_reg() => []}. % set
+-type scan_bb() :: {[instr()], target_liveset(), target_liveset()}.
+-type scan_bbs() :: #{label() => scan_bb()}.
+
+-spec scan_bbs([label()], target_cfg(), target_liveness(), seen(),
+ spill_state(), scan_bbs(), module(), target_context())
+ -> {scan_bbs(), seen(), spill_state()}.
+scan_bbs([], _CFG, _Liveness, Seen, State, BBs, _TgtMod, _TgtCtx) ->
+ {BBs, Seen, State};
+scan_bbs([L|Ls], CFG, Liveness, Seen0, State0, BBs, TgtMod, TgtCtx) ->
+ Liveout = t_liveout(Liveness, L, TgtMod, TgtCtx),
+ {Code, Livein, Seen, State} =
+ scan_bb(lists:reverse(hipe_bb:code(TgtMod:bb(CFG, L, TgtCtx))), Liveout,
+ Seen0, State0, [], TgtMod, TgtCtx),
+ BB = {Code, Livein, Liveout},
+ scan_bbs(Ls, CFG, Liveness, Seen, State, BBs#{L=>BB}, TgtMod, TgtCtx).
+
+-spec scan_bb([target_instr()], target_liveset(), seen(), spill_state(),
+ [instr()], module(), target_context())
+ -> {[instr()]
+ ,target_liveset()
+ ,seen()
+ ,spill_state()
+ }.
+scan_bb([], Live, Seen, State, IAcc, _TgtMod, _TgtCtx) ->
+ {IAcc, Live, Seen, State};
+scan_bb([I|Is], Live0, Seen0, State0, IAcc0, TgtMod, TgtCtx) ->
+ {TDef, TUse} = TgtMod:def_use(I,TgtCtx),
+ ?ASSERT(TDef =:= TgtMod:defines(I,TgtCtx)),
+ ?ASSERT(TUse =:= TgtMod:uses(I,TgtCtx)),
+ Def = ordsets:from_list(reg_names(TDef, TgtMod, TgtCtx)),
+ Use = ordsets:from_list(reg_names(TUse, TgtMod, TgtCtx)),
+ Live = ordsets:union(Use, ToSpill = ordsets:subtract(Live0, Def)),
+ Seen = add_seen(Def, add_seen(Use, Seen0)),
+ NewI = #instr{defuse={Def, Use}, is_move=TgtMod:is_move(I,TgtCtx)},
+ IAcc = [NewI|IAcc0],
+ State =
+ case TgtMod:defines_all_alloc(I,TgtCtx) of
+ false -> State0;
+ true -> spill_all(ToSpill, TgtMod, TgtCtx, State0)
+ end,
+ %% We can drop "no-ops" here; where (if anywhere) is it worth it?
+ scan_bb(Is, Live, Seen, State, IAcc, TgtMod, TgtCtx).
+
+-spec t_liveout(target_liveness(), label(), module(), target_context()) ->
+ target_liveset().
+t_liveout(Liveness, L, TgtMod, TgtCtx) ->
+ %% FIXME: unnecessary sort; liveout is sorted, reg_names(...) should be sorted
+ %% or consist of a few sorted subsequences (per type)
+ ordsets:from_list(reg_names(TgtMod:liveout(Liveness, L, TgtCtx), TgtMod,
+ TgtCtx)).
+
+-spec reg_names([target_temp()], module(), target_context()) -> [target_reg()].
+reg_names(Regs, TgtMod, TgtCtx) ->
+ [TgtMod:reg_nr(X,TgtCtx) || X <- Regs].
+
+-spec add_seen([target_reg()], seen()) -> seen().
+add_seen([], Seen) -> Seen;
+add_seen([R|Rs], Seen) -> add_seen(Rs, Seen#{R=>[]}).
+
+-spec spill_all([target_reg()], module(), target_context(), spill_state()) ->
+ spill_state().
+spill_all([], _TgtMod, _TgtCtx, State) -> State;
+spill_all([R|Rs], TgtMod, TgtCtx, State=#spill_state{map=Map, ix=Ix}) ->
+ case TgtMod:is_precoloured(R,TgtCtx) or maps:is_key(R, Map) of
+ true -> spill_all(Rs, TgtMod, TgtCtx, State);
+ false -> spill_all(Rs, TgtMod, TgtCtx,
+ State#spill_state{map=Map#{R=>Ix}, ix=Ix+1})
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Second pass (without split)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Rewrite CFG to the new temp names.
+-spec transform_whole_cfg(scan_bbs(), sub_map()) -> transformed_bbs().
+transform_whole_cfg(BBs0, SubMap) ->
+ maps:map(fun(_, BB) -> transform_whole_bb(BB, SubMap) end, BBs0).
+
+-spec transform_whole_bb(scan_bb(), sub_map()) -> transformed_bb().
+transform_whole_bb({Code, Livein, Liveout}, SubMap) ->
+ #transformed_bb{
+ bb=hipe_bb:mk_bb([I#instr{defuse={smap_get_all_partial(Def, SubMap),
+ smap_get_all_partial(Use, SubMap)}}
+ || I = #instr{defuse={Def,Use}} <- Code])
+ %% Assume mapping preserves monotonicity
+ ,livein=smap_get_all_partial(Livein, SubMap)
+ ,liveout=smap_get_all_partial(Liveout, SubMap)
+ }.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Second pass (with split)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Discover program partitioning
+%% Regretfully, this needs to be a separate pass, as having the global live set
+%% is crucial to get a useful partitioning.
+
+%% Single-block parts are merged if there are multiple in a single block, as it
+%% is judged to not be beneficial to make them too small.
+
+-type part_bb_part() :: {[instr()], target_liveset(), target_liveset()}.
+-type part_bb() :: {single, part_bb_part()}
+ | {split, part_bb_part(), part_bb_part()}.
+-type part_bb_list() :: [{label(), part_bb()}].
+-type part_bbs() :: #{label() => part_bb()}.
+-type part_bb_sofar() :: single
+ | {split, [instr()], target_liveset()}. % , target_liveset()
+
+-spec part_cfg(scan_bbs(), spill_map(), target_reg()) -> part_bb_list().
+part_cfg(ScanBBs, SpillMap, MaxPhys) ->
+ Liveset = mk_part_liveset(SpillMap, MaxPhys),
+ lists:map(fun(BB) -> part_bb(BB, Liveset) end, maps:to_list(ScanBBs)).
+
+-spec part_bb({label(), scan_bb()}, part_liveset()) -> {label(), part_bb()}.
+part_bb({L, BB0={Code0, Livein, Liveout}}, Liveset) ->
+ {Sofar, NewCode} = part_bb_1(lists:reverse(Code0), Liveset, Liveout, []),
+ BB = case Sofar of
+ single ->
+ ?ASSERT(Code0 =:= NewCode),
+ {single, BB0};
+ {split, ExitCode, ExitLivein = EntryLiveout} ->
+ {split, {NewCode, Livein, EntryLiveout},
+ {ExitCode, ExitLivein, Liveout}}
+ end,
+ {L, BB}.
+
+-spec part_bb_1([instr()], part_liveset(), target_liveset(), [instr()])
+ -> {part_bb_sofar(), [instr()]}.
+part_bb_1([], _Liveset, _Livein, IAcc) -> {single, IAcc};
+part_bb_1([I=#instr{defuse={Def,Use}}|Is], Liveset, Live0, IAcc0) ->
+ Live = ordsets:union(Use, ordsets:subtract(Live0, Def)),
+ IAcc = [I|IAcc0],
+ case part_none_live(Live, Liveset) of
+ false -> part_bb_1(Is, Liveset, Live, IAcc);
+ %% One split point will suffice
+ true -> {{split, IAcc, Live}, lists:reverse(Is)}
+ end.
+
+-spec part_none_live(target_liveset(), part_liveset()) -> boolean().
+part_none_live(Live, Liveset) ->
+ not lists:any(fun(R) -> part_liveset_is_live(R, Liveset) end, Live).
+
+-type part_liveset() :: {spill_map(), target_reg()}.
+
+-spec mk_part_liveset(spill_map(), target_reg()) -> part_liveset().
+mk_part_liveset(SpillMap, MaxPhys) -> {SpillMap, MaxPhys}.
+
+-spec part_liveset_is_live(target_reg(), part_liveset()) -> boolean().
+part_liveset_is_live(R, {SpillMap, MaxPhys}) when is_integer(R) ->
+ R >= MaxPhys andalso not maps:is_key(R, SpillMap).
+
+%% @doc Merges split blocks where entry and exit belong to the same DSet.
+%% Does not change DSets
+-spec merge_pointless_splits(part_bb_list(), scan_bbs(), bb_dsets())
+ -> {part_bbs(), bb_dsets()}.
+merge_pointless_splits(PartBBList0, ScanBBs, DSets0) ->
+ {PartBBList, DSets} =
+ merge_pointless_splits_1(PartBBList0, ScanBBs, DSets0, []),
+ {maps:from_list(PartBBList), DSets}.
+
+-spec merge_pointless_splits_1(
+ part_bb_list(), scan_bbs(), bb_dsets(), part_bb_list())
+ -> {part_bb_list(), bb_dsets()}.
+merge_pointless_splits_1([], _ScanBBs, DSets, Acc) -> {Acc, DSets};
+merge_pointless_splits_1([P={_,{single,_}}|Ps], ScanBBs, DSets, Acc) ->
+ merge_pointless_splits_1(Ps, ScanBBs, DSets, [P|Acc]);
+merge_pointless_splits_1([P0={L,{split,_,_}}|Ps], ScanBBs, DSets0, Acc) ->
+ {EntryRoot, DSets1} = hipe_dsets:find({entry,L}, DSets0),
+ {ExitRoot, DSets} = hipe_dsets:find({exit,L}, DSets1),
+ case EntryRoot =:= ExitRoot of
+ false -> merge_pointless_splits_1(Ps, ScanBBs, DSets, [P0|Acc]);
+ true ->
+ %% Reuse the code list from ScanBBs rather than concatenating the split
+ %% parts
+ #{L := BB} = ScanBBs,
+ ?ASSERT(begin
+ {L,{split,{_EntryCode,_,_},{_ExitCode,_,_}}}=P0, % [_|
+ {_Code,_,_}=BB,
+ _Code =:= (_EntryCode ++ _ExitCode)
+ end),
+ merge_pointless_splits_1(Ps, ScanBBs, DSets, [{L,{single, BB}}|Acc])
+ end.
+
+-spec merge_small_parts(bb_dsets()) -> {bb_dsets_rllist(), bb_dsets()}.
+merge_small_parts(DSets0) ->
+ {RLList, DSets1} = hipe_dsets:to_rllist(DSets0),
+ RLLList = [{R, length(Elems), Elems} || {R, Elems} <- RLList],
+ merge_small_parts_1(RLLList, DSets1, []).
+
+-spec merge_small_parts_1(
+ [{bb_dset_key(), non_neg_integer(), [bb_dset_key()]}],
+ bb_dsets(), bb_dsets_rllist()
+ ) -> {bb_dsets_rllist(), bb_dsets()}.
+merge_small_parts_1([], DSets, Acc) -> {Acc, DSets};
+merge_small_parts_1([{R, _, Es}], DSets, Acc) -> {[{R, Es}|Acc], DSets};
+merge_small_parts_1([{R, L, Es}|Ps], DSets, Acc) when L >= ?TUNE_TOO_FEW_BBS ->
+ merge_small_parts_1(Ps, DSets, [{R,Es}|Acc]);
+merge_small_parts_1([Fst,{R, L, Es}|Ps], DSets, Acc)
+ when L >= ?TUNE_TOO_FEW_BBS ->
+ merge_small_parts_1([Fst|Ps], DSets, [{R,Es}|Acc]);
+merge_small_parts_1([{R1,L1,Es1},{R2,L2,Es2}|Ps], DSets0, Acc) ->
+ ?ASSERT(L1 < ?TUNE_TOO_FEW_BBS andalso L2 < ?TUNE_TOO_FEW_BBS),
+ DSets1 = hipe_dsets:union(R1, R2, DSets0),
+ {R, DSets} = hipe_dsets:find(R1, DSets1),
+ merge_small_parts_1([{R,L2+L1,Es2++Es1}|Ps], DSets, Acc).
+
+%% @doc Partition an ordering over BBs into subsequences for the dsets that
+%% contain them.
+%% Does not change dsets.
+-spec part_order([label()], bb_dsets())
+ -> {#{bb_dset_key() => [label()]}, bb_dsets()}.
+part_order(Lbs, DSets) -> part_order(Lbs, DSets, #{}).
+
+part_order([], DSets, Acc) -> {Acc, DSets};
+part_order([L|Ls], DSets0, Acc0) ->
+ {EntryRoot, DSets1} = hipe_dsets:find({entry,L}, DSets0),
+ {ExitRoot, DSets2} = hipe_dsets:find({exit,L}, DSets1),
+ Acc1 = map_append(EntryRoot, L, Acc0),
+ %% Only include the label once if both entry and exit is in same partition
+ Acc2 = case EntryRoot =:= ExitRoot of
+ true -> Acc1;
+ false -> map_append(ExitRoot, L, Acc1)
+ end,
+ part_order(Ls, DSets2, Acc2).
+
+map_append(Key, Elem, Map) ->
+ case Map of
+ #{Key := List} -> Map#{Key := [Elem|List]};
+ #{} -> Map#{Key => [Elem]}
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Interference graph partitioning
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% We partition the program
+
+%% The algorithm considers two kinds of components; those that are local to a
+%% basic block, and those that are not. The key is that any basic block belongs
+%% to at most two non-local components; one from the beginning to the first
+%% split point, and one from the end to the last split point.
+
+-type bb_dset_key() :: {entry | exit, label()}.
+-type bb_dsets() :: hipe_dsets:dsets(bb_dset_key()).
+-type bb_dsets_rllist() :: [{bb_dset_key(), [bb_dset_key()]}].
+
+-spec initial_dsets(target_cfg(), module(), target_context()) -> bb_dsets().
+initial_dsets(CFG, TgtMod, TgtCtx) ->
+ Labels = TgtMod:labels(CFG, TgtCtx),
+ DSets0 = hipe_dsets:new(lists:append([[{entry,L},{exit,L}] || L <- Labels])),
+ Edges = lists:append([[{L, S} || S <- hipe_gen_cfg:succ(CFG, L)]
+ || L <- Labels]),
+ lists:foldl(fun({X, Y}, DS) -> hipe_dsets:union({exit,X}, {entry,Y}, DS) end,
+ DSets0, Edges).
+
+-spec join_whole_blocks(part_bb_list(), bb_dsets()) -> bb_dsets().
+join_whole_blocks(PartBBList, DSets0) ->
+ lists:foldl(fun({L, {single, _}}, DS) ->
+ hipe_dsets:union({entry,L}, {exit,L}, DS);
+ ({_, {split, _, _}}, DS) -> DS
+ end, DSets0, PartBBList).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Third pass
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Collect all referenced temps in each partition.
+
+%% Note: The temps could be collected during the partition pass for each
+%% half-bb, and then combined here. Would that be beneficial?
+
+collect_seenmap(PartBBsRLList, PartBBs) ->
+ collect_seenmap(PartBBsRLList, #{}, PartBBs).
+
+collect_seenmap([], Acc, _PartBBs) -> Acc;
+collect_seenmap([{R,Elems}|Ps], Acc, PartBBs) ->
+ Seen = collect_seen_part(Elems, #{}, PartBBs),
+ collect_seenmap(Ps, Acc#{R => Seen}, PartBBs).
+
+collect_seen_part([], Acc, _PartBBs) -> Acc;
+collect_seen_part([{Half,L}|Es], Acc0, PartBBs) ->
+ BB = maps:get(L, PartBBs),
+ Code = case {Half, BB} of
+ {entry, {single, {C,_,_}}} -> C;
+ {entry, {split, {C,_,_}, _}} -> C;
+ {exit, {split, _, {C,_,_}}} -> C;
+ {exit, {single, _}} -> [] % Ignore; was collected by its entry half
+ end,
+ Acc = collect_seen_code(Code, Acc0),
+ collect_seen_part(Es, Acc, PartBBs).
+
+collect_seen_code([], Acc) -> Acc;
+collect_seen_code([#instr{defuse={Def,Use}}|Is], Acc) ->
+ collect_seen_code(Is, add_seen(Def, add_seen(Use, Acc))).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Fourth pass
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Rewrite CFG to the new temp names.
+-spec transform_cfg([bb_dset_key()], part_bbs(), sub_map()) -> transformed_bbs().
+
+transform_cfg(Elems, PartBBs, SubMap) ->
+ transform_cfg(Elems, PartBBs, SubMap, #{}).
+
+transform_cfg([], _PartBBs, _SubMap, Acc) -> Acc;
+transform_cfg([{Half,L}|Es], PartBBs, SubMap, Acc0) ->
+ #{L := PBB} = PartBBs,
+ Acc = case {Half, PBB} of
+ {entry, {single,BB}} -> Acc0#{L=>transform_bb(BB, SubMap)};
+ {entry, {split,BB,_}} -> Acc0#{L=>transform_bb(BB, SubMap)};
+ {exit, {split,_,BB}} -> Acc0#{L=>transform_bb(BB, SubMap)};
+ {exit, {single, _}} -> Acc0 % Was included by the entry half
+ end,
+ transform_cfg(Es, PartBBs, SubMap, Acc).
+
+-spec transform_bb(part_bb_part(), sub_map()) -> transformed_bb().
+transform_bb(BB, SubMap) ->
+ %% For now, part_bb_part() and split_bb() share representation
+ transform_whole_bb(BB, SubMap).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Fifth pass
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Combine colorings and substitute temps in actual cfg if there were
+%% collisions.
+
+%% A temp can sometimes appear in more than one partition. For example, defining
+%% an unused value. If these are found by combine_allocations, we have to
+%% rename this temp in one of the partitions on the real cfg.
+%%
+%% We optimistically assume that there will be no such collisions, and when
+%% there are, we fix them up as they're found.
+
+-spec combine_allocations([{hipe_map(), [bb_dset_key()]}], target_reg(),
+ part_bbs(), module(), target_context(), target_cfg())
+ -> {hipe_map(), same | {rewritten, target_cfg()}}.
+combine_allocations([{A,_}|As], MaxPhys, PartBBs, TgtMod, TgtCtx, CFG) ->
+ {Phys, Pseuds} = lists:partition(fun({R,_}) -> R < MaxPhys end, A),
+ {Seen, _, []} = partition_by_seen(Pseuds, #{}, [], []),
+ combine_allocations(As, MaxPhys, PartBBs, TgtMod, TgtCtx, Phys, Seen, Pseuds,
+ {same, CFG}).
+
+-spec combine_allocations([{hipe_map(), [bb_dset_key()]}], target_reg(),
+ part_bbs(), module(), target_context(), hipe_map(),
+ seen(), hipe_map(), {same|rewritten, target_cfg()})
+ -> {hipe_map(), same | {rewritten, target_cfg()}}.
+combine_allocations([], _MaxPhys, _PartBBs, _TgtMod, _TgtCtx, Phys, _Seen,
+ Pseuds, CFGT) ->
+ {Phys ++ Pseuds, case CFGT of
+ {same, _} -> same;
+ {rewritten, _} -> CFGT
+ end};
+combine_allocations([{A,PartElems}|As], MaxPhys, PartBBs, TgtMod, TgtCtx, Phys,
+ Seen0, Acc, CFGT={_,CFG0}) ->
+ {Phys, Pseuds0} = lists:partition(fun({R,_}) -> R < MaxPhys end, A),
+ {Seen, Pseuds, Collisions} = partition_by_seen(Pseuds0, Seen0, [], []),
+ case Collisions of
+ [] -> combine_allocations(As, MaxPhys, PartBBs, TgtMod, TgtCtx, Phys, Seen,
+ Pseuds++Acc, CFGT);
+ _ ->
+ %% There were collisions; rename all the temp numbers in Collisions
+ {CFG, Renamed} = rename(Collisions, PartElems, PartBBs, TgtMod, TgtCtx,
+ CFG0),
+ combine_allocations(As, MaxPhys, PartBBs, TgtMod, TgtCtx, Phys, Seen,
+ Pseuds++Renamed++Acc, {rewritten,CFG})
+ end.
+
+%% @doc Partitions a coloring on whether the registers are in the Seen set,
+%% adding any new registers to the set.
+-spec partition_by_seen(hipe_map(), seen(), hipe_map(), hipe_map())
+ -> {seen(), hipe_map(), hipe_map()}.
+partition_by_seen([], Seen, Acc, Collisions) -> {Seen, Acc, Collisions};
+partition_by_seen([C={R,_}|Cs], Seen, Acc, Colls) ->
+ case Seen of
+ #{R := _} -> partition_by_seen(Cs, Seen, Acc, [C|Colls]);
+ #{} -> partition_by_seen(Cs, Seen#{R => []}, [C|Acc], Colls)
+ end.
+
+-spec rename(hipe_map(), [bb_dset_key()], part_bbs(), module(),
+ target_context(), target_cfg())
+ -> {target_cfg(), hipe_map()}.
+rename(CollisionList, PartElems, PartBBs, TgtMod, TgtCtx, CFG0) ->
+ {Map, Renamed} = new_names(CollisionList, TgtMod, TgtCtx, #{}, []),
+ Fun = fun(I) ->
+ TgtMod:subst_temps(
+ fun(Temp) ->
+ N = TgtMod:reg_nr(Temp, TgtCtx),
+ case Map of
+ #{N := Subst} -> TgtMod:update_reg_nr(Subst, Temp, TgtCtx);
+ #{} -> Temp
+ end
+ end, I, TgtCtx)
+ end,
+ {rename_1(PartElems, PartBBs, TgtMod, TgtCtx, Fun, CFG0), Renamed}.
+
+-type rename_map() :: #{target_reg() => target_reg()}.
+-type rename_fun() :: fun((target_instr()) -> target_instr()).
+
+-spec new_names(hipe_map(), module(), target_context(), rename_map(),
+ hipe_map())
+ -> {rename_map(), hipe_map()}.
+new_names([], _TgtMod, _TgtCtx, Map, Renamed) -> {Map, Renamed};
+new_names([{R,C}|As], TgtMod, TgtCtx, Map, Renamed) ->
+ Subst = TgtMod:new_reg_nr(TgtCtx),
+ new_names(As, TgtMod, TgtCtx, Map#{R => Subst}, [{Subst, C} | Renamed]).
+
+%% @doc Maps over all instructions in a partition on the original CFG.
+-spec rename_1([bb_dset_key()], part_bbs(), module(), target_context(),
+ rename_fun(), target_cfg()) -> target_cfg().
+rename_1([], _PartBBs, _TgtMod, _TgtCtx, _Fun, CFG) -> CFG;
+rename_1([{Half,L}|Es], PartBBs, TgtMod, TgtCtx, Fun, CFG0) ->
+ Code0 = hipe_bb:code(BB = TgtMod:bb(CFG0, L, TgtCtx)),
+ Code = case {Half, maps:get(L, PartBBs)} of
+ {entry, {single,_}} -> lists:map(Fun, Code0);
+ {entry, {split,PBBP,_}} ->
+ map_start(Fun, part_bb_part_len(PBBP), Code0);
+ {exit, {split,_,PBBP}} ->
+ map_end(Fun, part_bb_part_len(PBBP), Code0);
+ {exit, {single, _}} -> Code0
+ end,
+ CFG = TgtMod:update_bb(CFG0, L, hipe_bb:code_update(BB, Code), TgtCtx),
+ rename_1(Es, PartBBs, TgtMod, TgtCtx, Fun, CFG).
+
+-spec part_bb_part_len(part_bb_part()) -> non_neg_integer().
+part_bb_part_len({Code, _Livein, _Liveout}) -> length(Code).
+
+%% @doc Map the first N elements of a list
+-spec map_start(fun((X) -> Y), non_neg_integer(), [X]) -> [X|Y].
+map_start(_Fun, 0, List) -> List;
+map_start(Fun, N, [E|Es]) ->
+ [Fun(E)|map_start(Fun, N-1, Es)].
+
+%% @doc Map the last N elements of a list
+-spec map_end(fun((X) -> Y), non_neg_integer(), [X]) -> [X|Y].
+map_end(Fun, N, List) ->
+ map_end(Fun, N, length(List), List).
+
+map_end(Fun, N, Len, [E|Es]) when Len > N -> [E|map_end(Fun, N, Len-1, Es)];
+map_end(Fun, N, Len, List) when Len =:= N -> lists:map(Fun, List).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Temp map ADT
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-type sub_map() :: {s,#{target_reg() => temp()}}.
+-type inv_map() :: {i,#{temp() => target_reg()}}.
+
+-spec smap_get(target_reg(), sub_map()) -> temp().
+smap_get(Temp, {s,Map}) when is_integer(Temp) -> maps:get(Temp, Map).
+
+-spec imap_get(temp(), inv_map()) -> target_reg().
+imap_get(Temp, {i,Map}) when is_integer(Temp) -> maps:get(Temp, Map).
+
+-spec smap_get_all_partial([target_reg()], sub_map()) -> [temp()].
+smap_get_all_partial([], _) -> [];
+smap_get_all_partial([T|Ts], SMap={s,Map}) when is_integer(T) ->
+ case Map of
+ #{T := R} -> [R|smap_get_all_partial(Ts, SMap)];
+ #{} -> smap_get_all_partial(Ts, SMap)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Validation
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-ifdef(DO_ASSERT).
+%%%%%%%%%%%%%%%%%%%%
+%% Check that the coloring is correct (if the IG is correct):
+%%
+
+%% Define these as 'ok' or 'report(X,Y)' depending on how much output you want.
+-define(report0(X,Y), ?IF_DEBUG_LEVEL(0,?msg(X, Y),ok)).
+-define(report(X,Y), ?IF_DEBUG_LEVEL(1,?msg(X, Y),ok)).
+-define(report2(X,Y), ?IF_DEBUG_LEVEL(2,?msg(X, Y),ok)).
+-define(report3(X,Y), ?IF_DEBUG_LEVEL(3,?msg(X, Y),ok)).
+
+check_coloring(Coloring, CFG, TgtMod, TgtCtx) ->
+ ?report0("checking coloring ~p~n",[Coloring]),
+ IG = hipe_ig:build(CFG, TgtMod:analyze(CFG,TgtCtx), TgtMod, TgtCtx),
+ check_cols(hipe_vectors:list(hipe_ig:adj_list(IG)),
+ init_coloring(Coloring, TgtMod, TgtCtx)).
+
+init_coloring(Xs, TgtMod, TgtCtx) ->
+ hipe_temp_map:cols2tuple(Xs, TgtMod, TgtCtx).
+
+check_color_of(X, Cols) ->
+ case hipe_temp_map:find(X, Cols) of
+ unknown ->
+ uncolored;
+ C ->
+ C
+ end.
+
+check_cols([], _Cols) ->
+ ?report("coloring valid~n",[]),
+ true;
+check_cols([{X,Neighbours}|Xs], Cols) ->
+ Cs = [{N, check_color_of(N, Cols)} || N <- Neighbours],
+ C = check_color_of(X, Cols),
+ case valid_coloring(X, C, Cs) of
+ yes ->
+ check_cols(Xs, Cols);
+ {no,Invalids} ->
+ ?msg("node ~p has same color (~p) as ~p~n", [X,C,Invalids]),
+ check_cols(Xs, Cols) andalso false
+ end.
+
+valid_coloring(_X, _C, []) ->
+ yes;
+valid_coloring(X, C, [{Y,C}|Ys]) ->
+ case valid_coloring(X, C, Ys) of
+ yes -> {no, [Y]};
+ {no,Zs} -> {no, [Y|Zs]}
+ end;
+valid_coloring(X, C, [_|Ys]) ->
+ valid_coloring(X, C, Ys).
+
+unused_unused(Unused, CFG, TgtMod, TgtCtx) ->
+ IG = hipe_ig:build(CFG, TgtMod:analyze(CFG,TgtCtx), TgtMod, TgtCtx),
+ lists:all(fun(R) -> case hipe_ig:get_node_degree(R, IG) of
+ 0 -> true;
+ Deg ->
+ ?msg("Temp ~w is in unused but has degree ~w~n",
+ [R, Deg]),
+ false
+ end end, Unused).
+
+%%%%%%%%%%%%%%%%%%%%
+%% Check that no register allocation opportunities were missed due to ?MODULE
+%%
+just_as_good_as(RegAllocMod, CFG, Liveness, SpillIndex0, SpillLimit, TgtMod,
+ TgtCtx, Options, SpillMap, Coloring, Unused) ->
+ {CheckColoring, _} =
+ RegAllocMod:regalloc(CFG, Liveness, SpillIndex0, SpillLimit, TgtMod, TgtCtx,
+ Options),
+ Now = lists:sort([{R,Kind} || {R,{Kind,_}} <- Coloring,
+ not ordsets:is_element(R, Unused)]),
+ Check = lists:sort([{R,Kind} || {R,{Kind,_}} <- CheckColoring,
+ not ordsets:is_element(R, Unused)]),
+ CheckMap = maps:from_list(Check),
+ SaneSpills = all_spills_sane_1(CheckColoring, SpillMap),
+ case SaneSpills
+ andalso lists:all(fun({R, spill}) -> maps:get(R, CheckMap) =:= spill;
+ ({_,reg}) -> true
+ end, Now)
+ of
+ true -> true;
+ false ->
+ {NowRegs, _} = _NowCount = count(Now),
+ {CheckRegs, _} = _CheckCount = count(Check),
+ {M,F,A} = element(2, element(3, CFG)),
+ io:fwrite(standard_error, "Colorings differ (~w, ~w)!~n"
+ "MFA: ~w:~w/~w~n"
+ "Unused: ~w~n"
+ "Now:~w~nCorrect:~w~n",
+ [TgtMod, RegAllocMod,
+ M,F,A,
+ Unused,
+ Now -- Check, Check -- Now]),
+ SaneSpills andalso NowRegs >= CheckRegs
+ end.
+
+count(C) -> {length([[] || {_, reg} <- C]),
+ length([[] || {_, spill} <- C])}.
+
+unused(LivePseudos, SpillMap, CFG, TgtMod, TgtCtx) ->
+ {TMin, TMax} = TgtMod:var_range(CFG,TgtCtx),
+ SpillOSet = ordsets:from_list(maps:keys(SpillMap)),
+ PhysOSet = ordsets:from_list(TgtMod:all_precoloured(TgtCtx)),
+ Used = ordsets:union(LivePseudos, ordsets:union(PhysOSet, SpillOSet)),
+ ordsets:subtract(lists:seq(TMin, TMax), Used).
+
+%% Check that no temp that we wrote off was actually allocatable.
+all_spills_sane_1(_, Empty) when map_size(Empty) =:= 0 -> true;
+all_spills_sane_1([], _Nonempty) -> false;
+all_spills_sane_1([{T, {reg, _}}|Cs], SpillMap) ->
+ not maps:is_key(T, SpillMap) andalso all_spills_sane_1(Cs, SpillMap);
+all_spills_sane_1([{T, {spill, _}}|Cs], SpillMap) ->
+ all_spills_sane_1(Cs, maps:remove(T, SpillMap)).
+
+-endif. % DO_ASSERT
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Pseudo-target interface
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+analyze(Cfg, _ModRec) -> Cfg.
+bb(Cfg=#cfg{bbs=BBs}, Ix, _ModRec) ->
+ case BBs of
+ #{Ix := #transformed_bb{bb=BB}} -> BB;
+ _ -> error(badarg, [Cfg, Ix])
+ end.
+args(Arity, #prepass_ctx{target_mod=TgtMod, target_ctx=TgtCtx, sub=SubM}) ->
+ smap_get(TgtMod:args(Arity,TgtCtx), SubM).
+labels(#cfg{bbs=BBs}, _ModRec) -> maps:keys(BBs).
+livein(#cfg{bbs=BBs}, Lb, _SubMod) ->
+ #{Lb := #transformed_bb{livein=Livein}} = BBs,
+ Livein.
+liveout(#cfg{bbs=BBs}, Lb, _SubMod) ->
+ #{Lb := #transformed_bb{liveout=Liveout}} = BBs,
+ Liveout.
+uses(I, MR) -> element(2, def_use(I, MR)).
+defines(I, MR) -> element(1, def_use(I, MR)).
+def_use(#instr{defuse=DefUse}, _ModRec) -> DefUse.
+is_move(#instr{is_move=IM}, _ModRec) -> IM.
+is_fixed(Reg, #prepass_ctx{target_mod=TgtMod,target_ctx=TgtCtx,inv=InvM}) ->
+ TgtMod:is_fixed(imap_get(Reg, InvM),TgtCtx). % XXX: Is this hot?
+is_global(Reg, #prepass_ctx{target_mod=TgtMod,target_ctx=TgtCtx,
+ max_phys=MaxPhys}) when Reg < MaxPhys ->
+ TgtMod:is_global(Reg,TgtCtx). % assume id-map
+is_precoloured(Reg, #prepass_ctx{max_phys=MaxPhys}) -> Reg < MaxPhys.
+reg_nr(Reg, _ModRec) -> Reg. % After mapping (naturally)
+non_alloc(#cfg{cfg=CFG}, #prepass_ctx{target_mod=TgtMod,target_ctx=TgtCtx,
+ sub=SubM}) ->
+ smap_get_all_partial(reg_names(TgtMod:non_alloc(CFG,TgtCtx), TgtMod, TgtCtx),
+ SubM).
+number_of_temporaries(#cfg{max_reg=MaxR}, _ModRec) -> MaxR.
+allocatable(#prepass_ctx{target_mod=TgtMod, target_ctx=TgtCtx}) ->
+ TgtMod:allocatable(TgtCtx). % assume id-map
+physical_name(Reg, _ModRec) -> Reg.
+all_precoloured(#prepass_ctx{target_mod=TgtMod, target_ctx=TgtCtx}) ->
+ TgtMod:all_precoloured(TgtCtx). % dito
+var_range(#cfg{cfg=_CFG, max_reg=MaxReg},
+ #prepass_ctx{target_mod=_TgtMod, target_ctx=_TgtCtx}) ->
+ ?ASSERT(begin {TgtMin, _} = _TgtMod:var_range(_CFG,_TgtCtx),
+ TgtMin =:= 0
+ end),
+ {0, MaxReg-1}.
+
+postorder(#cfg{cfg=CFG,rpostorder=undefined},
+ #prepass_ctx{target_mod=TgtMod,target_ctx=TgtCtx}) ->
+ TgtMod:postorder(CFG,TgtCtx);
+postorder(#cfg{rpostorder=Labels}, _ModRec) when is_list(Labels) ->
+ lists:reverse(Labels).
+
+reverse_postorder(#cfg{cfg=CFG,rpostorder=undefined},
+ #prepass_ctx{target_mod=TgtMod,target_ctx=TgtCtx}) ->
+ TgtMod:reverse_postorder(CFG,TgtCtx);
+reverse_postorder(#cfg{rpostorder=Labels}, _ModRec) when is_list(Labels) ->
+ Labels.
diff --git a/lib/hipe/regalloc/hipe_restore_reuse.erl b/lib/hipe/regalloc/hipe_restore_reuse.erl
new file mode 100644
index 0000000000..2158bd185e
--- /dev/null
+++ b/lib/hipe/regalloc/hipe_restore_reuse.erl
@@ -0,0 +1,516 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%@doc
+%% RESTORE REUSE LIVE RANGE SPLITTING PASS
+%%
+%% This is a simple live range splitter that tries to avoid sequences where a
+%% temporary is accessed on stack multiple times by keeping a copy of that temp
+%% around in a register.
+%%
+%% At any point where a temporary that is expected to be spilled (see uses of
+%% spills_add_list/2) is defined or used, this pass considers that temporary
+%% "available".
+%%
+%% Limitations:
+%% * If a live range part starts with several different restores, this module
+%% will introduce a new temp number for each of them, and later be forced to
+%% generate phi blocks. It would be more efficient to introduce just a
+%% single temp number. That would also remove the need for the phi blocks.
+%% * If a live range part ends in a definition, that definition should just
+%% define the base temp rather than the substitution, since some CISC
+%% targets might be able to inline the memory access in the instruction.
+-module(hipe_restore_reuse).
+
+-export([split/4]).
+
+%% Exports for hipe_range_split, which uses restore_reuse as one possible spill
+%% "mode"
+-export([analyse/3
+ ,renamed_in_block/2
+ ,split_in_block/2
+ ]).
+-export_type([avail/0]).
+
+-compile(inline).
+
+%% -define(DO_ASSERT, 1).
+-include("../main/hipe.hrl").
+
+-type target_cfg() :: any().
+-type liveness() :: any().
+-type target_module() :: module().
+-type target_context() :: any().
+-type target() :: {target_module(), target_context()}.
+-type label() :: non_neg_integer().
+-type reg() :: non_neg_integer().
+-type instr() :: any().
+-type temp() :: any().
+
+-spec split(target_cfg(), liveness(), target_module(), target_context())
+ -> target_cfg().
+split(CFG, Liveness, TargetMod, TargetContext) ->
+ Target = {TargetMod, TargetContext},
+ Avail = analyse(CFG, Liveness, Target),
+ rewrite(CFG, Target, Avail).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-opaque avail() :: #{label() => avail_bb()}.
+
+-record(avail_bb, {
+ %% Blocks where HasCall is true are considered to have too high
+ %% register pressure to support a register copy of a temp
+ has_call :: boolean(),
+ %% AvailOut: Temps that can be split (are available)
+ out :: availset(),
+ %% Gen: AvailOut generated locally
+ gen :: availset(),
+ %% WantIn: Temps that are split
+ want :: regset(),
+ %% Self: Temps with avail-want pairs locally
+ self :: regset(),
+ %% DefIn: Temps shadowed by later def in same live range part
+ defin :: regset(),
+ pred :: [label()],
+ succ :: [label()]
+ }).
+-type avail_bb() :: #avail_bb{}.
+
+avail_get(L, Avail) -> maps:get(L, Avail).
+avail_set(L, Val, Avail) -> maps:put(L, Val, Avail).
+avail_has_call(L, Avail) -> (avail_get(L, Avail))#avail_bb.has_call.
+avail_out(L, Avail) -> (avail_get(L, Avail))#avail_bb.out.
+avail_self(L, Avail) -> (avail_get(L, Avail))#avail_bb.self.
+avail_pred(L, Avail) -> (avail_get(L, Avail))#avail_bb.pred.
+avail_succ(L, Avail) -> (avail_get(L, Avail))#avail_bb.succ.
+
+avail_in(L, Avail) ->
+ case avail_pred(L, Avail) of
+ [] -> availset_empty(); % entry
+ Pred ->
+ lists:foldl(fun(P, ASet) ->
+ availset_intersect(avail_out(P, Avail), ASet)
+ end, availset_top(), Pred)
+ end.
+
+want_in(L, Avail) -> (avail_get(L, Avail))#avail_bb.want.
+want_out(L, Avail) ->
+ lists:foldl(fun(S, Set) ->
+ ordsets:union(want_in(S, Avail), Set)
+ end, ordsets:new(), avail_succ(L, Avail)).
+
+def_in(L, Avail) -> (avail_get(L, Avail))#avail_bb.defin.
+def_out(L, Avail) ->
+ case avail_succ(L, Avail) of
+ [] -> ordsets:new(); % entry
+ Succ ->
+ ordsets:intersection([def_in(S, Avail) || S <- Succ])
+ end.
+
+-type regset() :: ordsets:ordset(reg()).
+-type availset() :: top | regset().
+availset_empty() -> [].
+availset_top() -> top.
+availset_intersect(top, B) -> B;
+availset_intersect(A, top) -> A;
+availset_intersect(A, B) -> ordsets:intersection(A, B).
+availset_union(top, _) -> top;
+availset_union(_, top) -> top;
+availset_union(A, B) -> ordsets:union(A, B).
+ordset_intersect_availset(OS, top) -> OS;
+ordset_intersect_availset(OS, AS) -> ordsets:intersection(OS, AS).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Analysis pass
+%%
+%% The analysis pass collects the set of temps we're interested in splitting
+%% (Spills), and computes three dataflow analyses for this subset of temps.
+%%
+%% Avail, which is the set of temps which are available in register from a
+%% previous (potential) spill or restore without going through a HasCall
+%% block.
+%% Want, which is a liveness analysis for the subset of temps used by an
+%% instruction that are also in Avail at that point. In other words, Want is
+%% the set of temps that are split (has a register copy) at a particular
+%% point.
+%% Def, which are the temps that are already going to be spilled later, and so
+%% need not be spilled when they're defined.
+%%
+%% Lastly, it computes the set Self for each block, which is the temps that have
+%% avail-want pairs in the same block, and so should be split in that block even
+%% if they're not in WantIn for the block.
+
+-spec analyse(target_cfg(), liveness(), target()) -> avail().
+analyse(CFG, Liveness, Target) ->
+ Avail0 = analyse_init(CFG, Liveness, Target),
+ RPO = reverse_postorder(CFG, Target),
+ AvailLs = [L || L <- RPO, not avail_has_call(L, Avail0)],
+ Avail1 = avail_dataf(AvailLs, Avail0),
+ Avail2 = analyse_filter_want(maps:keys(Avail1), Avail1),
+ PO = lists:reverse(RPO),
+ want_dataf(PO, Avail2).
+
+-spec analyse_init(target_cfg(), liveness(), target()) -> avail().
+analyse_init(CFG, Liveness, Target) ->
+ analyse_init(labels(CFG, Target), CFG, Liveness, Target, #{}, []).
+
+-spec analyse_init([label()], target_cfg(), liveness(), target(), spillset(),
+ [{label(), avail_bb()}])
+ -> avail().
+analyse_init([], _CFG, _Liveness, Target, Spills0, Acc) ->
+ %% Precoloured temps can't be spilled
+ Spills = spills_filter(fun(R) -> not is_precoloured(R, Target) end, Spills0),
+ analyse_init_1(Acc, Spills, []);
+analyse_init([L|Ls], CFG, Liveness, Target, Spills0, Acc) ->
+ {DefIn, Gen, Self, Want, HasCall0} =
+ analyse_scan(hipe_bb:code(bb(CFG, L, Target)), Target,
+ ordsets:new(), ordsets:new(), ordsets:new(),
+ ordsets:new()),
+ {Spills, Out, HasCall} =
+ case HasCall0 of
+ false -> {Spills0, availset_top(), false};
+ {true, CallDefs} ->
+ Spill = ordsets:subtract(liveout(Liveness, L, Target), CallDefs),
+ {spills_add_list(Spill, Spills0), Gen, true}
+ end,
+ Pred = hipe_gen_cfg:pred(CFG, L),
+ Succ = hipe_gen_cfg:succ(CFG, L),
+ Val = #avail_bb{gen=Gen, want=Want, self=Self, out=Out, has_call=HasCall,
+ pred=Pred, succ=Succ, defin=DefIn},
+ analyse_init(Ls, CFG, Liveness, Target, Spills, [{L, Val} | Acc]).
+
+-spec analyse_init_1([{label(), avail_bb()}], spillset(),
+ [{label(), avail_bb()}])
+ -> avail().
+analyse_init_1([], _Spills, Acc) -> maps:from_list(Acc);
+analyse_init_1([{L, Val0}|Vs], Spills, Acc) ->
+ #avail_bb{out=Out,gen=Gen,want=Want,self=Self} = Val0,
+ Val = Val0#avail_bb{
+ out = spills_filter_availset(Out, Spills),
+ gen = spills_filter_availset(Gen, Spills),
+ want = spills_filter_availset(Want, Spills),
+ self = spills_filter_availset(Self, Spills)},
+ analyse_init_1(Vs, Spills, [{L, Val} | Acc]).
+
+-type spillset() :: #{reg() => []}.
+-spec spills_add_list([reg()], spillset()) -> spillset().
+spills_add_list([], Spills) -> Spills;
+spills_add_list([R|Rs], Spills) -> spills_add_list(Rs, Spills#{R => []}).
+
+-spec spills_filter_availset(availset(), spillset()) -> availset().
+spills_filter_availset([E|Es], Spills) ->
+ case Spills of
+ #{E := _} -> [E|spills_filter_availset(Es, Spills)];
+ #{} -> spills_filter_availset(Es, Spills)
+ end;
+spills_filter_availset([], _) -> [];
+spills_filter_availset(top, _) -> top.
+
+spills_filter(Fun, Spills) -> maps:filter(fun(K, _) -> Fun(K) end, Spills).
+
+-spec analyse_scan([instr()], target(), Defset, Gen, Self, Want)
+ -> {Defset, Gen, Self, Want, HasCall} when
+ HasCall :: false | {true, regset()},
+ Defset :: regset(),
+ Gen :: availset(),
+ Self :: regset(),
+ Want :: regset().
+analyse_scan([], _Target, Defs, Gen, Self, Want) ->
+ {Defs, Gen, Self, Want, false};
+analyse_scan([I|Is], Target, Defs0, Gen0, Self0, Want0) ->
+ {DefL, UseL} = reg_def_use(I, Target),
+ Use = ordsets:from_list(UseL),
+ Def = ordsets:from_list(DefL),
+ Self = ordsets:union(ordsets:intersection(Use, Gen0), Self0),
+ Want = ordsets:union(ordsets:subtract(Use, Defs0), Want0),
+ Defs = ordsets:union(Def, Defs0),
+ case defines_all_alloc(I, Target) of
+ true ->
+ [] = Is, %assertion
+ {Defs, ordsets:new(), Self, Want, {true, Def}};
+ false ->
+ Gen = ordsets:union(ordsets:union(Def, Use), Gen0),
+ analyse_scan(Is, Target, Defs, Gen, Self, Want)
+ end.
+
+-spec avail_dataf([label()], avail()) -> avail().
+avail_dataf(RPO, Avail0) ->
+ case avail_dataf_once(RPO, Avail0, 0) of
+ {Avail, 0} -> Avail;
+ {Avail, _Changed} ->
+ avail_dataf(RPO, Avail)
+ end.
+
+-spec avail_dataf_once([label()], avail(), non_neg_integer())
+ -> {avail(), non_neg_integer()}.
+avail_dataf_once([], Avail, Changed) -> {Avail, Changed};
+avail_dataf_once([L|Ls], Avail0, Changed0) ->
+ ABB = #avail_bb{out=OldOut, gen=Gen} = avail_get(L, Avail0),
+ In = avail_in(L, Avail0),
+ {Changed, Avail} =
+ case availset_union(In, Gen) of
+ OldOut -> {Changed0, Avail0};
+ Out -> {Changed0+1, avail_set(L, ABB#avail_bb{out=Out}, Avail0)}
+ end,
+ avail_dataf_once(Ls, Avail, Changed).
+
+-spec analyse_filter_want([label()], avail()) -> avail().
+analyse_filter_want([], Avail) -> Avail;
+analyse_filter_want([L|Ls], Avail0) ->
+ ABB = #avail_bb{want=Want0, defin=DefIn0} = avail_get(L, Avail0),
+ In = avail_in(L, Avail0),
+ Want = ordset_intersect_availset(Want0, In),
+ DefIn = ordset_intersect_availset(DefIn0, In),
+ Avail = avail_set(L, ABB#avail_bb{want=Want, defin=DefIn}, Avail0),
+ analyse_filter_want(Ls, Avail).
+
+-spec want_dataf([label()], avail()) -> avail().
+want_dataf(PO, Avail0) ->
+ case want_dataf_once(PO, Avail0, 0) of
+ {Avail, 0} -> Avail;
+ {Avail, _Changed} ->
+ want_dataf(PO, Avail)
+ end.
+
+-spec want_dataf_once([label()], avail(), non_neg_integer())
+ -> {avail(), non_neg_integer()}.
+want_dataf_once([], Avail, Changed) -> {Avail, Changed};
+want_dataf_once([L|Ls], Avail0, Changed0) ->
+ ABB0 = #avail_bb{want=OldIn,defin=OldDef} = avail_get(L, Avail0),
+ AvailIn = avail_in(L, Avail0),
+ Out = want_out(L, Avail0),
+ DefOut = def_out(L, Avail0),
+ {Changed, Avail} =
+ case {ordsets:union(ordset_intersect_availset(Out, AvailIn), OldIn),
+ ordsets:union(ordset_intersect_availset(DefOut, AvailIn), OldDef)}
+ of
+ {OldIn, OldDef} -> {Changed0, Avail0};
+ {In, DefIn} ->
+ ABB = ABB0#avail_bb{want=In,defin=DefIn},
+ {Changed0+1, avail_set(L, ABB, Avail0)}
+ end,
+ want_dataf_once(Ls, Avail, Changed).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Rewrite pass
+-type subst_dict() :: orddict:orddict(reg(), reg()).
+-type input() :: #{label() => subst_dict()}.
+
+-spec rewrite(target_cfg(), target(), avail()) -> target_cfg().
+rewrite(CFG, Target, Avail) ->
+ RPO = reverse_postorder(CFG, Target),
+ rewrite(RPO, Target, Avail, #{}, CFG).
+
+-spec rewrite([label()], target(), avail(), input(), target_cfg())
+ -> target_cfg().
+rewrite([], _Target, _Avail, _Input, CFG) -> CFG;
+rewrite([L|Ls], Target, Avail, Input0, CFG0) ->
+ SplitHere = split_in_block(L, Avail),
+ {Input1, LInput} =
+ case Input0 of
+ #{L := LInput0} -> {Input0, LInput0};
+ #{} -> {Input0#{L => []}, []} % entry block
+ end,
+ ?ASSERT([] =:= [X || X <- SplitHere, orddict:is_key(X, LInput)]),
+ ?ASSERT(want_in(L, Avail) =:= orddict:fetch_keys(LInput)),
+ {CFG1, LOutput} =
+ case {SplitHere, LInput} of
+ {[], []} -> % optimisation (rewrite will do nothing, so skip it)
+ {CFG0, LInput};
+ _ ->
+ Code0 = hipe_bb:code(BB=bb(CFG0, L, Target)),
+ DefOut = def_out(L, Avail),
+ {Code, LOutput0, _DefIn} =
+ rewrite_instrs(Code0, Target, LInput, DefOut, SplitHere),
+ {update_bb(CFG0, L, hipe_bb:code_update(BB, Code), Target), LOutput0}
+ end,
+ {Input, CFG} = rewrite_succs(avail_succ(L, Avail), Target, L, LOutput, Avail,
+ Input1, CFG1),
+ rewrite(Ls, Target, Avail, Input, CFG).
+
+-spec renamed_in_block(label(), avail()) -> ordsets:ordset(reg()).
+renamed_in_block(L, Avail) ->
+ ordsets:union([avail_self(L, Avail), want_in(L, Avail),
+ want_out(L, Avail)]).
+
+-spec split_in_block(label(), avail()) -> ordsets:ordset(reg()).
+split_in_block(L, Avail) ->
+ ordsets:subtract(ordsets:union(avail_self(L, Avail), want_out(L, Avail)),
+ want_in(L, Avail)).
+
+-spec rewrite_instrs([instr()], target(), subst_dict(), regset(), [reg()])
+ -> {[instr()], subst_dict(), regset()}.
+rewrite_instrs([], _Target, Output, DefOut, []) ->
+ {[], Output, DefOut};
+rewrite_instrs([I|Is], Target, Input0, BBDefOut, SplitHere0) ->
+ {TDef, TUse} = def_use(I, Target),
+ {Def, Use} = {reg_names(TDef, Target), reg_names(TUse, Target)},
+ %% Restores are generated in forward order by picking temps from SplitHere as
+ %% they're used or defined. After the last instruction, all temps have been
+ %% picked.
+ {ISplits, SplitHere} =
+ lists:partition(fun(R) ->
+ lists:member(R, Def) orelse lists:member(R, Use)
+ end, SplitHere0),
+ {Input, Restores} =
+ case ISplits of
+ [] -> {Input0, []};
+ _ ->
+ make_splits(ISplits, Target, TDef, TUse, Input0, [])
+ end,
+ %% Here's the recursive call
+ {Acc0, Output, DefOut} =
+ rewrite_instrs(Is, Target, Input, BBDefOut, SplitHere),
+ %% From here we're processing instructions in reverse order, because to avoid
+ %% redundant spills we need to walk the 'def' dataflow, which is in reverse.
+ SubstFun = fun(Temp) ->
+ case orddict:find(reg_nr(Temp, Target), Input) of
+ {ok, NewTemp} -> NewTemp;
+ error -> Temp
+ end
+ end,
+ Acc1 = insert_spills(TDef, Target, Input, DefOut, Acc0),
+ Acc = Restores ++ [subst_temps(SubstFun, I, Target) | Acc1],
+ DefIn = ordsets:union(DefOut, ordsets:from_list(Def)),
+ {Acc, Output, DefIn}.
+
+-spec make_splits([reg()], target(), [temp()], [temp()], subst_dict(),
+ [instr()])
+ -> {subst_dict(), [instr()]}.
+make_splits([], _Target, _TDef, _TUse, Input, Acc) ->
+ {Input, Acc};
+make_splits([S|Ss], Target, TDef, TUse, Input0, Acc0) ->
+ SubstReg = new_reg_nr(Target),
+ {Acc, Subst} =
+ case find_reg_temp(S, TUse, Target) of
+ error ->
+ {ok, Temp} = find_reg_temp(S, TDef, Target),
+ {Acc0, update_reg_nr(SubstReg, Temp, Target)};
+ {ok, Temp} ->
+ Subst0 = update_reg_nr(SubstReg, Temp, Target),
+ Acc1 = [mk_move(Temp, Subst0, Target) | Acc0],
+ {Acc1, Subst0}
+ end,
+ Input = orddict:store(S, Subst, Input0),
+ make_splits(Ss, Target, TDef, TUse, Input, Acc).
+
+-spec find_reg_temp(reg(), [temp()], target()) -> error | {ok, temp()}.
+find_reg_temp(_Reg, [], _Target) -> error;
+find_reg_temp(Reg, [T|Ts], Target) ->
+ case reg_nr(T, Target) of
+ Reg -> {ok, T};
+ _ -> find_reg_temp(Reg, Ts, Target)
+ end.
+
+-spec insert_spills([temp()], target(), subst_dict(), regset(), [instr()])
+ -> [instr()].
+insert_spills([], _Target, _Input, _DefOut, Acc) -> Acc;
+insert_spills([T|Ts], Target, Input, DefOut, Acc0) ->
+ R = reg_nr(T, Target),
+ Acc =
+ case orddict:find(R, Input) of
+ error -> Acc0;
+ {ok, Subst} ->
+ case lists:member(R, DefOut) of
+ true -> Acc0;
+ false -> [mk_move(Subst, T, Target) | Acc0]
+ end
+ end,
+ insert_spills(Ts, Target, Input, DefOut, Acc).
+
+-spec rewrite_succs([label()], target(), label(), subst_dict(), avail(),
+ input(), target_cfg()) -> {input(), target_cfg()}.
+rewrite_succs([], _Target, _P, _POutput, _Avail, Input, CFG) -> {Input, CFG};
+rewrite_succs([L|Ls], Target, P, POutput, Avail, Input0, CFG0) ->
+ NewLInput = orddict_with_ordset(want_in(L, Avail), POutput),
+ {Input, CFG} =
+ case Input0 of
+ #{L := LInput} ->
+ CFG2 =
+ case required_phi_moves(LInput, NewLInput) of
+ [] -> CFG0;
+ ReqMovs ->
+ PhiLb = new_label(Target),
+ Code = [mk_move(S,D,Target) || {S,D} <- ReqMovs]
+ ++ [mk_goto(L, Target)],
+ PhiBB = hipe_bb:mk_bb(Code),
+ CFG1 = update_bb(CFG0, PhiLb, PhiBB, Target),
+ bb_redirect_jmp(L, PhiLb, P, CFG1, Target)
+ end,
+ {Input0, CFG2};
+ #{} ->
+ {Input0#{L => NewLInput}, CFG0}
+ end,
+ rewrite_succs(Ls, Target, P, POutput, Avail, Input, CFG).
+
+-spec bb_redirect_jmp(label(), label(), label(), target_cfg(), target())
+ -> target_cfg().
+bb_redirect_jmp(From, To, Lb, CFG, Target) ->
+ BB0 = bb(CFG, Lb, Target),
+ Last = redirect_jmp(hipe_bb:last(BB0), From, To, Target),
+ BB = hipe_bb:code_update(BB0, hipe_bb:butlast(BB0) ++ [Last]),
+ update_bb(CFG, Lb, BB, Target).
+
+-spec required_phi_moves(subst_dict(), subst_dict()) -> [{reg(), reg()}].
+required_phi_moves([], []) -> [];
+required_phi_moves([P|Is], [P|Os]) -> required_phi_moves(Is, Os);
+required_phi_moves([{K, In}|Is], [{K, Out}|Os]) ->
+ [{Out, In}|required_phi_moves(Is, Os)].
+
+%% @doc Returns a new orddict with the keys in Set and their associated values.
+-spec orddict_with_ordset(ordsets:ordset(K), orddict:orddict(K, V))
+ -> orddict:orddict(K, V).
+orddict_with_ordset([S|Ss], [{K, _}|_]=Dict) when S < K ->
+ orddict_with_ordset(Ss, Dict);
+orddict_with_ordset([S|_]=Set, [{K, _}|Ds]) when S > K ->
+ orddict_with_ordset(Set, Ds);
+orddict_with_ordset([_S|Ss], [{_K, _}=P|Ds]) -> % _S == _K
+ [P|orddict_with_ordset(Ss, Ds)];
+orddict_with_ordset([], _) -> [];
+orddict_with_ordset(_, []) -> [].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Target module interface functions
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-define(TGT_IFACE_0(N), N( {M,C}) -> M:N( C)).
+-define(TGT_IFACE_1(N), N(A1, {M,C}) -> M:N(A1, C)).
+-define(TGT_IFACE_2(N), N(A1,A2, {M,C}) -> M:N(A1,A2, C)).
+-define(TGT_IFACE_3(N), N(A1,A2,A3,{M,C}) -> M:N(A1,A2,A3,C)).
+
+?TGT_IFACE_2(bb).
+?TGT_IFACE_1(def_use).
+?TGT_IFACE_1(defines_all_alloc).
+?TGT_IFACE_1(is_precoloured).
+?TGT_IFACE_1(labels).
+?TGT_IFACE_1(mk_goto).
+?TGT_IFACE_2(mk_move).
+?TGT_IFACE_0(new_label).
+?TGT_IFACE_0(new_reg_nr).
+?TGT_IFACE_3(redirect_jmp).
+?TGT_IFACE_1(reg_nr).
+?TGT_IFACE_1(reverse_postorder).
+?TGT_IFACE_2(subst_temps).
+?TGT_IFACE_3(update_bb).
+?TGT_IFACE_2(update_reg_nr).
+
+liveout(Liveness, L, Target={TgtMod,TgtCtx}) ->
+ ordsets:from_list(reg_names(TgtMod:liveout(Liveness, L, TgtCtx), Target)).
+
+reg_names(Regs, {TgtMod,TgtCtx}) ->
+ [TgtMod:reg_nr(X,TgtCtx) || X <- Regs].
+
+reg_def_use(I, Target) ->
+ {TDef, TUse} = def_use(I, Target),
+ {reg_names(TDef, Target), reg_names(TUse, Target)}.
diff --git a/lib/hipe/regalloc/hipe_sparc_specific.erl b/lib/hipe/regalloc/hipe_sparc_specific.erl
index 8d34604f84..78b6379eba 100644
--- a/lib/hipe/regalloc/hipe_sparc_specific.erl
+++ b/lib/hipe/regalloc/hipe_sparc_specific.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,121 +11,138 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_specific).
%% for hipe_coalescing_regalloc:
--export([number_of_temporaries/1
- ,analyze/1
- ,labels/1
- ,all_precoloured/0
- ,bb/2
- ,liveout/2
- ,reg_nr/1
- ,def_use/1
- ,is_move/1
- ,is_precoloured/1
- ,var_range/1
- ,allocatable/0
- ,non_alloc/1
- ,physical_name/1
- ,reverse_postorder/1
- ,livein/2
- ,uses/1
- ,defines/1
+-export([number_of_temporaries/2
+ ,analyze/2
+ ,labels/2
+ ,all_precoloured/1
+ ,bb/3
+ ,liveout/3
+ ,reg_nr/2
+ ,def_use/2
+ ,is_move/2
+ ,is_spill_move/2
+ ,is_precoloured/2
+ ,var_range/2
+ ,allocatable/1
+ ,non_alloc/2
+ ,physical_name/2
+ ,reverse_postorder/2
+ ,livein/3
+ ,uses/2
+ ,defines/2
+ ,defines_all_alloc/2
]).
%% for hipe_graph_coloring_regalloc:
--export([is_fixed/1]).
+-export([is_fixed/2]).
%% for hipe_ls_regalloc:
--export([args/1, is_arg/1, is_global/1, new_spill_index/1]).
--export([breadthorder/1, postorder/1]).
+-export([args/2, is_arg/2, is_global/2, new_spill_index/2]).
+-export([breadthorder/2, postorder/2]).
%% callbacks for hipe_regalloc_loop
--export([defun_to_cfg/1,
- check_and_rewrite/2]).
+-export([check_and_rewrite/3]).
+
+%% callbacks for hipe_regalloc_prepass, hipe_range_split
+-export([mk_move/3,
+ mk_goto/2,
+ redirect_jmp/4,
+ new_label/1,
+ new_reg_nr/1,
+ update_reg_nr/3,
+ update_bb/4,
+ subst_temps/3]).
-defun_to_cfg(Defun) ->
- hipe_sparc_cfg:init(Defun).
+%% callbacks for hipe_bb_weights, hipe_range_split
+-export([branch_preds/2]).
-check_and_rewrite(Defun, Coloring) ->
- hipe_sparc_ra_postconditions:check_and_rewrite(Defun, Coloring, 'normal').
+check_and_rewrite(CFG, Coloring, no_context) ->
+ hipe_sparc_ra_postconditions:check_and_rewrite(CFG, Coloring, 'normal').
-reverse_postorder(CFG) ->
+reverse_postorder(CFG, _) ->
hipe_sparc_cfg:reverse_postorder(CFG).
-non_alloc(CFG) ->
- non_alloc(hipe_sparc_registers:nr_args(), hipe_sparc_cfg:params(CFG)).
+non_alloc(CFG, no_context) ->
+ non_alloc_1(hipe_sparc_registers:nr_args(), hipe_sparc_cfg:params(CFG)).
%% same as hipe_sparc_frame:fix_formals/2
-non_alloc(0, Rest) -> Rest;
-non_alloc(N, [_|Rest]) -> non_alloc(N-1, Rest);
-non_alloc(_, []) -> [].
+non_alloc_1(0, Rest) -> Rest;
+non_alloc_1(N, [_|Rest]) -> non_alloc_1(N-1, Rest);
+non_alloc_1(_, []) -> [].
%% Liveness stuff
-analyze(CFG) ->
+analyze(CFG, _) ->
hipe_sparc_liveness_gpr:analyse(CFG).
-livein(Liveness,L) ->
+livein(Liveness,L,_) ->
[X || X <- hipe_sparc_liveness_gpr:livein(Liveness,L),
hipe_sparc:temp_is_allocatable(X)].
-liveout(BB_in_out_liveness,Label) ->
+liveout(BB_in_out_liveness,Label,_) ->
[X || X <- hipe_sparc_liveness_gpr:liveout(BB_in_out_liveness,Label),
hipe_sparc:temp_is_allocatable(X)].
%% Registers stuff
-allocatable() ->
+allocatable(no_context) ->
hipe_sparc_registers:allocatable_gpr().
-all_precoloured() ->
+all_precoloured(no_context) ->
hipe_sparc_registers:all_precoloured().
-is_precoloured(Reg) ->
+is_precoloured(Reg, _) ->
hipe_sparc_registers:is_precoloured_gpr(Reg).
-is_fixed(R) ->
+is_fixed(R, _) ->
hipe_sparc_registers:is_fixed(R).
-physical_name(Reg) ->
+physical_name(Reg, _) ->
Reg.
%% CFG stuff
-labels(CFG) ->
+labels(CFG, _) ->
hipe_sparc_cfg:labels(CFG).
-var_range(_CFG) ->
+var_range(_CFG, _) ->
hipe_gensym:var_range(sparc).
-number_of_temporaries(_CFG) ->
+number_of_temporaries(_CFG, _) ->
Highest_temporary = hipe_gensym:get_var(sparc),
%% Since we can have temps from 0 to Max adjust by +1.
Highest_temporary + 1.
-bb(CFG,L) ->
+bb(CFG,L,_) ->
hipe_sparc_cfg:bb(CFG,L).
+update_bb(CFG,L,BB,_) ->
+ hipe_sparc_cfg:bb_add(CFG,L,BB).
+
+branch_preds(Branch,_) ->
+ hipe_sparc_cfg:branch_preds(Branch).
+
%% SPARC stuff
-def_use(Instruction) ->
- {defines(Instruction), uses(Instruction)}.
+def_use(Instruction, Ctx) ->
+ {defines(Instruction, Ctx), uses(Instruction, Ctx)}.
-uses(I) ->
+uses(I, _) ->
[X || X <- hipe_sparc_defuse:insn_use_gpr(I),
hipe_sparc:temp_is_allocatable(X)].
-defines(I) ->
+defines(I, _) ->
[X || X <- hipe_sparc_defuse:insn_def_gpr(I),
hipe_sparc:temp_is_allocatable(X)].
-is_move(Instruction) ->
+defines_all_alloc(I, _) ->
+ hipe_sparc_defuse:insn_defs_all_gpr(I).
+
+is_move(Instruction, _) ->
case hipe_sparc:is_pseudo_move(Instruction) of
true ->
Dst = hipe_sparc:pseudo_move_dst(Instruction),
@@ -142,28 +155,60 @@ is_move(Instruction) ->
false -> false
end.
-reg_nr(Reg) ->
+is_spill_move(Instruction, _) ->
+ hipe_sparc:is_pseudo_spill_move(Instruction).
+
+reg_nr(Reg, _) ->
hipe_sparc:temp_reg(Reg).
+mk_move(Src, Dst, _) ->
+ hipe_sparc:mk_pseudo_move(Src, Dst).
+
+mk_goto(Label, _) ->
+ hipe_sparc:mk_b_label(Label).
+
+redirect_jmp(Jmp, ToOld, ToNew, _) when is_integer(ToOld), is_integer(ToNew) ->
+ hipe_sparc_cfg:redirect_jmp(Jmp, ToOld, ToNew).
+
+new_label(_) ->
+ hipe_gensym:get_next_label(sparc).
+
+new_reg_nr(_) ->
+ hipe_gensym:get_next_var(sparc).
+
+update_reg_nr(Nr, Temp, _) ->
+ hipe_sparc:mk_temp(Nr, hipe_sparc:temp_type(Temp)).
+
+subst_temps(SubstFun, Instr, _) ->
+ hipe_sparc_subst:insn_temps(
+ fun(Op) ->
+ case hipe_sparc:temp_is_allocatable(Op)
+ andalso hipe_sparc:temp_type(Op) =/= 'double'
+ of
+ true -> SubstFun(Op);
+ false -> Op
+ end
+ end, Instr).
+
%%% Linear Scan stuff
-new_spill_index(SpillIndex) when is_integer(SpillIndex) ->
+new_spill_index(SpillIndex, _) when is_integer(SpillIndex) ->
SpillIndex+1.
-breadthorder(CFG) ->
+breadthorder(CFG, _) ->
hipe_sparc_cfg:breadthorder(CFG).
-postorder(CFG) ->
+postorder(CFG, _) ->
hipe_sparc_cfg:postorder(CFG).
-is_global(R) ->
+is_global(R, _) ->
R =:= hipe_sparc_registers:temp1() orelse
R =:= hipe_sparc_registers:temp2() orelse
R =:= hipe_sparc_registers:temp3() orelse
hipe_sparc_registers:is_fixed(R).
-is_arg(R) ->
+is_arg(R, _) ->
hipe_sparc_registers:is_arg(R).
-args(CFG) ->
+args(CFG, _) ->
hipe_sparc_registers:args(hipe_sparc_cfg:arity(CFG)).
diff --git a/lib/hipe/regalloc/hipe_sparc_specific_fp.erl b/lib/hipe/regalloc/hipe_sparc_specific_fp.erl
index 2edd3cb47e..485fdc212a 100644
--- a/lib/hipe/regalloc/hipe_sparc_specific_fp.erl
+++ b/lib/hipe/regalloc/hipe_sparc_specific_fp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,133 +11,182 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_specific_fp).
%% for hipe_coalescing_regalloc:
--export([number_of_temporaries/1
- ,analyze/1
- ,labels/1
- ,all_precoloured/0
- ,bb/2
- ,liveout/2
- ,reg_nr/1
- ,def_use/1
- ,is_move/1
- ,is_precoloured/1
- ,var_range/1
- ,allocatable/0
- ,non_alloc/1
- ,physical_name/1
- ,reverse_postorder/1
- ,livein/2
- ,uses/1
- ,defines/1
+-export([number_of_temporaries/2
+ ,analyze/2
+ ,labels/2
+ ,all_precoloured/1
+ ,bb/3
+ ,liveout/3
+ ,reg_nr/2
+ ,def_use/2
+ ,is_move/2
+ ,is_spill_move/2
+ ,is_precoloured/2
+ ,var_range/2
+ ,allocatable/1
+ ,non_alloc/2
+ ,physical_name/2
+ ,reverse_postorder/2
+ ,livein/3
+ ,uses/2
+ ,defines/2
+ ,defines_all_alloc/2
]).
%% for hipe_graph_coloring_regalloc:
--export([is_fixed/1]).
+-export([is_fixed/2]).
%% for hipe_ls_regalloc:
-%%-export([args/1, is_arg/1, is_global, new_spill_index/1]).
-%%-export([breadthorder/1, postorder/1]).
+%%-export([args/2, is_arg/2, is_global, new_spill_index/2]).
+%%-export([breadthorder/2, postorder/2]).
%% callbacks for hipe_regalloc_loop
--export([defun_to_cfg/1,
- check_and_rewrite/2]).
+-export([check_and_rewrite/3]).
+
+%% callbacks for hipe_regalloc_prepass, hipe_range_split
+-export([mk_move/3,
+ mk_goto/2,
+ redirect_jmp/4,
+ new_label/1,
+ new_reg_nr/1,
+ update_reg_nr/3,
+ update_bb/4,
+ subst_temps/3]).
-defun_to_cfg(Defun) ->
- hipe_sparc_cfg:init(Defun).
+%% callbacks for hipe_bb_weights, hipe_range_split
+-export([branch_preds/2]).
-check_and_rewrite(Defun, Coloring) ->
- hipe_sparc_ra_postconditions_fp:check_and_rewrite(Defun, Coloring).
+check_and_rewrite(CFG, Coloring, no_context) ->
+ hipe_sparc_ra_postconditions_fp:check_and_rewrite(CFG, Coloring).
-reverse_postorder(CFG) ->
+reverse_postorder(CFG, _) ->
hipe_sparc_cfg:reverse_postorder(CFG).
-non_alloc(_CFG) ->
+non_alloc(_CFG, _) ->
[].
%% Liveness stuff
-analyze(CFG) ->
+analyze(CFG, _) ->
hipe_sparc_liveness_fpr:analyse(CFG).
-livein(Liveness, L) ->
+livein(Liveness, L, _) ->
hipe_sparc_liveness_fpr:livein(Liveness, L).
-liveout(BB_in_out_liveness, Label) ->
+liveout(BB_in_out_liveness, Label, _) ->
hipe_sparc_liveness_fpr:liveout(BB_in_out_liveness, Label).
%% Registers stuff
-allocatable() ->
+allocatable(no_context) ->
hipe_sparc_registers:allocatable_fpr().
-all_precoloured() ->
- allocatable().
+all_precoloured(Ctx) ->
+ allocatable(Ctx).
-is_precoloured(Reg) ->
+is_precoloured(Reg, _) ->
hipe_sparc_registers:is_precoloured_fpr(Reg).
-is_fixed(_Reg) ->
+is_fixed(_Reg, _) ->
false.
-physical_name(Reg) ->
+physical_name(Reg, _) ->
Reg.
%% CFG stuff
-labels(CFG) ->
+labels(CFG, _) ->
hipe_sparc_cfg:labels(CFG).
-var_range(_CFG) ->
+var_range(_CFG, _) ->
hipe_gensym:var_range(sparc).
-number_of_temporaries(_CFG) ->
+number_of_temporaries(_CFG, _) ->
Highest_temporary = hipe_gensym:get_var(sparc),
%% Since we can have temps from 0 to Max adjust by +1.
Highest_temporary + 1.
-bb(CFG, L) ->
+bb(CFG, L, _) ->
hipe_sparc_cfg:bb(CFG, L).
+update_bb(CFG,L,BB,_) ->
+ hipe_sparc_cfg:bb_add(CFG,L,BB).
+
+branch_preds(Branch,_) ->
+ hipe_sparc_cfg:branch_preds(Branch).
+
%% SPARC stuff
-def_use(I) ->
- {defines(I), uses(I)}.
+def_use(I, Ctx) ->
+ {defines(I,Ctx), uses(I,Ctx)}.
-uses(I) ->
+uses(I, _) ->
hipe_sparc_defuse:insn_use_fpr(I).
-defines(I) ->
+defines(I, _) ->
hipe_sparc_defuse:insn_def_fpr(I).
-is_move(I) ->
+defines_all_alloc(I, _) ->
+ hipe_sparc_defuse:insn_defs_all_fpr(I).
+
+is_move(I, _) ->
hipe_sparc:is_pseudo_fmove(I).
-reg_nr(Reg) ->
+is_spill_move(I, _) ->
+ hipe_sparc:is_pseudo_spill_fmove(I).
+
+reg_nr(Reg, _) ->
hipe_sparc:temp_reg(Reg).
+mk_move(Src, Dst, _) ->
+ hipe_sparc:mk_pseudo_fmove(Src, Dst).
+
+mk_goto(Label, _) ->
+ hipe_sparc:mk_b_label(Label).
+
+redirect_jmp(Jmp, ToOld, ToNew, _) when is_integer(ToOld), is_integer(ToNew) ->
+ hipe_sparc_cfg:redirect_jmp(Jmp, ToOld, ToNew).
+
+new_label(_) ->
+ hipe_gensym:get_next_label(sparc).
+
+new_reg_nr(_) ->
+ hipe_gensym:get_next_var(sparc).
+
+update_reg_nr(Nr, _Temp, _) ->
+ hipe_sparc:mk_temp(Nr, 'double').
+
+subst_temps(SubstFun, Instr, _) ->
+ hipe_sparc_subst:insn_temps(
+ fun(Op) ->
+ case hipe_sparc:temp_is_allocatable(Op)
+ andalso hipe_sparc:temp_type(Op) =:= 'double'
+ of
+ true -> SubstFun(Op);
+ false -> Op
+ end
+ end, Instr).
+
-ifdef(notdef).
-new_spill_index(SpillIndex)->
+new_spill_index(SpillIndex, _)->
SpillIndex+1.
-breadthorder(CFG) ->
+breadthorder(CFG, _) ->
hipe_sparc_cfg:breadthorder(CFG).
-postorder(CFG) ->
+postorder(CFG, _) ->
hipe_sparc_cfg:postorder(CFG).
-is_global(_R) ->
+is_global(_R, _) ->
false.
-is_arg(_R) ->
+is_arg(_R, _) ->
false.
-args(_CFG) ->
+args(_CFG, _) ->
[].
-endif.
diff --git a/lib/hipe/regalloc/hipe_spillcost.erl b/lib/hipe/regalloc/hipe_spillcost.erl
index b241e637d9..906cdac1aa 100644
--- a/lib/hipe/regalloc/hipe_spillcost.erl
+++ b/lib/hipe/regalloc/hipe_spillcost.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_spillcost).
diff --git a/lib/hipe/regalloc/hipe_spillcost.hrl b/lib/hipe/regalloc/hipe_spillcost.hrl
index 3cadcbe432..b1e84cee16 100644
--- a/lib/hipe/regalloc/hipe_spillcost.hrl
+++ b/lib/hipe/regalloc/hipe_spillcost.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-type hipe_array() :: integer().
@@ -25,4 +18,3 @@
{uses :: hipe_array(), % number of uses of each temp
bb_uses :: hipe_array() % number of basic blocks each temp occurs in
}).
-
diff --git a/lib/hipe/regalloc/hipe_temp_map.erl b/lib/hipe/regalloc/hipe_temp_map.erl
index 4085a0e1a7..58145efb3e 100644
--- a/lib/hipe/regalloc/hipe_temp_map.erl
+++ b/lib/hipe/regalloc/hipe_temp_map.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,12 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ===========================================================================
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
-%% Time-stamp: <2008-04-20 14:54:00 richard>
%% ===========================================================================
%% Module : hipe_temp_map
%% Purpose :
@@ -33,10 +26,12 @@
-module(hipe_temp_map).
--export([cols2tuple/2, is_spilled/2, to_substlist/1]).
+-export([cols2tuple/3, find/2, is_spilled/2, to_substlist/1]).
-include("../main/hipe.hrl").
+-type target_context() :: any().
+
%%----------------------------------------------------------------------------
%% Convert a list of [{R0, C1}, {R1, C2}, ...] to a temp_map
%% (Currently implemented as a tuple) tuple {C1, C2, ...}.
@@ -47,34 +42,32 @@
%% element 1
%%----------------------------------------------------------------------------
--spec cols2tuple(hipe_map(), atom()) -> hipe_temp_map().
+-spec cols2tuple(hipe_map(), module(), target_context()) -> hipe_temp_map().
-cols2tuple(Map, Target) ->
- ?ASSERT(check_list(Map)),
- SortedMap = lists:keysort(1, Map),
- cols2tuple(0, SortedMap, [], Target).
+cols2tuple(Map, TgtMod, TgtCtx) ->
+ SortedMap = lists:keysort(1, Map),
+ cols2tuple(0, SortedMap, [], TgtMod, TgtCtx).
-%% sorted_cols2tuple(Map, Target) ->
-%% ?ASSERT(check_list(Map)),
+%% sorted_cols2tuple(Map, TgtMod, TgtCtx) ->
%% ?ASSERT(Map =:= lists:keysort(1, Map)),
-%% cols2tuple(0, Map, [], Target).
+%% cols2tuple(0, Map, [], TgtMod, TgtCtx).
%% Build a dense mapping
-cols2tuple(_, [], Vs, _) ->
+cols2tuple(_, [], Vs, _, _) ->
%% Done reverse the list and convert to tuple.
list_to_tuple(lists:reverse(Vs));
-cols2tuple(N, [{R, C}|Ms], Vs, Target) when N =:= R ->
+cols2tuple(N, [{R, C}|Ms], Vs, TgtMod, TgtCtx) when N =:= R ->
%% N makes sure the mapping is dense. N is he next key.
- cols2tuple(N+1, Ms, [C|Vs], Target);
-cols2tuple(N, SourceMapping, Vs, Target) ->
+ cols2tuple(N+1, Ms, [C|Vs], TgtMod, TgtCtx);
+cols2tuple(N, SourceMapping=[{R,_}|_], Vs, TgtMod, TgtCtx) when N < R ->
%% The source was sparse, make up some placeholders...
Val =
- case Target:is_precoloured(N) of
+ case TgtMod:is_precoloured(N, TgtCtx) of
%% If it is precoloured, we know what to map it to.
true -> {reg, N};
false -> unknown
end,
- cols2tuple(N+1, SourceMapping, [Val|Vs], Target).
+ cols2tuple(N+1, SourceMapping, [Val|Vs], TgtMod, TgtCtx).
%%
%% True if temp Temp is spilled.
@@ -82,7 +75,7 @@ cols2tuple(N, SourceMapping, Vs, Target) ->
-spec is_spilled(non_neg_integer(), hipe_temp_map()) -> boolean().
is_spilled(Temp, Map) ->
- case element(Temp+1, Map) of
+ case find(Temp, Map) of
{reg, _R} -> false;
{fp_reg, _R}-> false;
{spill, _N} -> true;
@@ -106,9 +99,10 @@ is_spilled(Temp, Map) ->
%% {spill, _N} -> false;
%% unknown -> false
%% end.
-%%
-%% %% Returns the inf temp Temp is mapped to.
-%% find(Temp, Map) -> element(Temp+1, Map).
+
+%% Returns the inf temp Temp is mapped to.
+find(Temp, Map) when Temp < tuple_size(Map) -> element(Temp+1, Map);
+find(_, Map) when is_tuple(Map) -> unknown. % consistency with cols2tuple/3
%%
diff --git a/lib/hipe/regalloc/hipe_x86_specific.erl b/lib/hipe/regalloc/hipe_x86_specific.erl
index 4edf8674b7..dacfb71b00 100644
--- a/lib/hipe/regalloc/hipe_x86_specific.erl
+++ b/lib/hipe/regalloc/hipe_x86_specific.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-ifdef(HIPE_AMD64).
-define(HIPE_X86_SPECIFIC, hipe_amd64_specific).
@@ -25,100 +18,113 @@
-define(HIPE_X86_REGISTERS, hipe_amd64_registers).
-define(HIPE_X86_LIVENESS, hipe_amd64_liveness).
-define(HIPE_X86_DEFUSE, hipe_amd64_defuse).
+-define(HIPE_X86_SUBST, hipe_amd64_subst).
-else.
-define(HIPE_X86_SPECIFIC, hipe_x86_specific).
-define(HIPE_X86_RA_POSTCONDITIONS, hipe_x86_ra_postconditions).
-define(HIPE_X86_REGISTERS, hipe_x86_registers).
-define(HIPE_X86_LIVENESS, hipe_x86_liveness).
-define(HIPE_X86_DEFUSE, hipe_x86_defuse).
+-define(HIPE_X86_SUBST, hipe_x86_subst).
-endif.
-module(?HIPE_X86_SPECIFIC).
--export([number_of_temporaries/1]).
+-export([number_of_temporaries/2]).
%% The following exports are used as M:F(...) calls from other modules;
%% e.g. hipe_x86_ra_ls.
--export([analyze/1,
- bb/2,
- args/1,
- labels/1,
- livein/2,
- liveout/2,
- uses/1,
- defines/1,
- def_use/1,
- is_arg/1, % used by hipe_ls_regalloc
- is_move/1,
- is_fixed/1, % used by hipe_graph_coloring_regalloc
- is_global/1,
- is_precoloured/1,
- reg_nr/1,
- non_alloc/1,
- allocatable/0,
- physical_name/1,
- all_precoloured/0,
- new_spill_index/1, % used by hipe_ls_regalloc
- var_range/1,
- breadthorder/1,
- postorder/1,
- reverse_postorder/1]).
+-export([analyze/2,
+ bb/3,
+ args/2,
+ labels/2,
+ livein/3,
+ liveout/3,
+ uses/2,
+ defines/2,
+ defines_all_alloc/2,
+ def_use/2,
+ is_arg/2, % used by hipe_ls_regalloc
+ is_move/2,
+ is_spill_move/2,
+ is_fixed/2, % used by hipe_graph_coloring_regalloc
+ is_global/2,
+ is_precoloured/2,
+ reg_nr/2,
+ non_alloc/2,
+ allocatable/1,
+ physical_name/2,
+ all_precoloured/1,
+ new_spill_index/2, % used by hipe_ls_regalloc
+ var_range/2,
+ breadthorder/2,
+ postorder/2,
+ reverse_postorder/2]).
%% callbacks for hipe_regalloc_loop
--export([defun_to_cfg/1,
- check_and_rewrite/2]).
+-export([check_and_rewrite/3]).
+
+%% callbacks for hipe_regalloc_prepass, hipe_range_split
+-export([mk_move/3,
+ mk_goto/2,
+ redirect_jmp/4,
+ new_label/1,
+ new_reg_nr/1,
+ update_reg_nr/3,
+ update_bb/4,
+ subst_temps/3]).
-defun_to_cfg(Defun) ->
- hipe_x86_cfg:init(Defun).
+%% callbacks for hipe_bb_weights
+-export([branch_preds/2]).
-check_and_rewrite(Defun, Coloring) ->
- ?HIPE_X86_RA_POSTCONDITIONS:check_and_rewrite(Defun, Coloring, 'normal').
+check_and_rewrite(CFG, Coloring, _) ->
+ ?HIPE_X86_RA_POSTCONDITIONS:check_and_rewrite(CFG, Coloring, 'normal').
-reverse_postorder(CFG) ->
+reverse_postorder(CFG, _) ->
hipe_x86_cfg:reverse_postorder(CFG).
-breadthorder(CFG) ->
+breadthorder(CFG, _) ->
hipe_x86_cfg:breadthorder(CFG).
-postorder(CFG) ->
+postorder(CFG, _) ->
hipe_x86_cfg:postorder(CFG).
%% Globally defined registers for linear scan
-is_global(R) ->
+is_global(R, _) ->
?HIPE_X86_REGISTERS:temp1() =:= R orelse
?HIPE_X86_REGISTERS:temp0() =:= R orelse
?HIPE_X86_REGISTERS:is_fixed(R).
-is_fixed(R) ->
+is_fixed(R, _) ->
?HIPE_X86_REGISTERS:is_fixed(R).
-is_arg(R) ->
+is_arg(R, _) ->
?HIPE_X86_REGISTERS:is_arg(R).
-args(CFG) ->
+args(CFG, _) ->
?HIPE_X86_REGISTERS:args(hipe_x86_cfg:arity(CFG)).
-non_alloc(CFG) ->
- non_alloc(?HIPE_X86_REGISTERS:nr_args(), hipe_x86_cfg:params(CFG)).
+non_alloc(CFG, _) ->
+ non_alloc_1(?HIPE_X86_REGISTERS:nr_args(), hipe_x86_cfg:params(CFG)).
%% same as hipe_x86_frame:fix_formals/2
-non_alloc(0, Rest) -> Rest;
-non_alloc(N, [_|Rest]) -> non_alloc(N-1, Rest);
-non_alloc(_, []) -> [].
+non_alloc_1(0, Rest) -> Rest;
+non_alloc_1(N, [_|Rest]) -> non_alloc_1(N-1, Rest);
+non_alloc_1(_, []) -> [].
%% Liveness stuff
-analyze(CFG) ->
+analyze(CFG, _) ->
?HIPE_X86_LIVENESS:analyze(CFG).
-livein(Liveness,L) ->
+livein(Liveness,L,_) ->
[X || X <- ?HIPE_X86_LIVENESS:livein(Liveness,L),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_reg(X) =/= ?HIPE_X86_REGISTERS:fcalls(),
hipe_x86:temp_reg(X) =/= ?HIPE_X86_REGISTERS:heap_limit(),
hipe_x86:temp_type(X) =/= 'double'].
-liveout(BB_in_out_liveness,Label) ->
+liveout(BB_in_out_liveness,Label,_) ->
[X || X <- ?HIPE_X86_LIVENESS:liveout(BB_in_out_liveness,Label),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_reg(X) =/= ?HIPE_X86_REGISTERS:fcalls(),
@@ -127,37 +133,43 @@ liveout(BB_in_out_liveness,Label) ->
%% Registers stuff
-allocatable() ->
+allocatable(_) ->
?HIPE_X86_REGISTERS:allocatable().
-all_precoloured() ->
+all_precoloured(_) ->
?HIPE_X86_REGISTERS:all_precoloured().
-is_precoloured(Reg) ->
+is_precoloured(Reg,_) ->
?HIPE_X86_REGISTERS:is_precoloured(Reg).
-physical_name(Reg) ->
+physical_name(Reg,_) ->
Reg.
%% CFG stuff
-labels(CFG) ->
+labels(CFG,_) ->
hipe_x86_cfg:labels(CFG).
-var_range(_CFG) ->
+var_range(_CFG,_) ->
hipe_gensym:var_range(x86).
-number_of_temporaries(_CFG) ->
+number_of_temporaries(_CFG,_) ->
Highest_temporary = hipe_gensym:get_var(x86),
%% Since we can have temps from 0 to Max adjust by +1.
Highest_temporary + 1.
-bb(CFG,L) ->
+bb(CFG,L,_) ->
hipe_x86_cfg:bb(CFG,L).
+update_bb(CFG,L,BB,_) ->
+ hipe_x86_cfg:bb_add(CFG,L,BB).
+
+branch_preds(Instr,_) ->
+ hipe_x86_cfg:branch_preds(Instr).
+
%% X86 stuff
-def_use(Instruction) ->
+def_use(Instruction,_) ->
{[X || X <- ?HIPE_X86_DEFUSE:insn_def(Instruction),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_type(X) =/= 'double'],
@@ -166,17 +178,19 @@ def_use(Instruction) ->
hipe_x86:temp_type(X) =/= 'double']
}.
-uses(I) ->
+uses(I,_) ->
[X || X <- ?HIPE_X86_DEFUSE:insn_use(I),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_type(X) =/= 'double'].
-defines(I) ->
+defines(I,_) ->
[X || X <- ?HIPE_X86_DEFUSE:insn_def(I),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_type(X) =/= 'double'].
-is_move(Instruction) ->
+defines_all_alloc(I,_) -> ?HIPE_X86_DEFUSE:insn_defs_all(I).
+
+is_move(Instruction,_) ->
case hipe_x86:is_move(Instruction) of
true ->
Src = hipe_x86:move_src(Instruction),
@@ -197,8 +211,49 @@ is_move(Instruction) ->
false -> false
end.
-reg_nr(Reg) ->
+is_spill_move(Instruction,_) ->
+ hipe_x86:is_pseudo_spill_move(Instruction).
+
+reg_nr(Reg,_) ->
hipe_x86:temp_reg(Reg).
-new_spill_index(SpillIndex) when is_integer(SpillIndex) ->
+mk_move(Src, Dst, _) ->
+ hipe_x86:mk_move(Src, Dst).
+
+mk_goto(Label, _) ->
+ hipe_x86:mk_jmp_label(Label).
+
+redirect_jmp(Jmp, ToOld, ToNew, _) when is_integer(ToOld), is_integer(ToNew) ->
+ Ref = make_ref(),
+ put(Ref, false),
+ I = hipe_x86_subst:insn_lbls(
+ fun(Tgt) ->
+ if Tgt =:= ToOld -> put(Ref, true), ToNew;
+ is_integer(Tgt) -> Tgt
+ end
+ end, Jmp),
+ true = erase(Ref), % Assert that something was rewritten
+ I.
+
+new_label(_) ->
+ hipe_gensym:get_next_label(x86).
+
+new_reg_nr(_) ->
+ hipe_gensym:get_next_var(x86).
+
+update_reg_nr(Nr, Temp, _) ->
+ hipe_x86:mk_temp(Nr, hipe_x86:temp_type(Temp)).
+
+subst_temps(SubstFun, Instr, _) ->
+ ?HIPE_X86_SUBST:insn_temps(
+ fun(Op) ->
+ case hipe_x86:temp_is_allocatable(Op)
+ andalso hipe_x86:temp_type(Op) =/= 'double'
+ of
+ true -> SubstFun(Op);
+ false -> Op
+ end
+ end, Instr).
+
+new_spill_index(SpillIndex, _) when is_integer(SpillIndex) ->
SpillIndex+1.
diff --git a/lib/hipe/regalloc/hipe_x86_specific_x87.erl b/lib/hipe/regalloc/hipe_x86_specific_x87.erl
index ece07cb2f9..3fe49e1f00 100644
--- a/lib/hipe/regalloc/hipe_x86_specific_x87.erl
+++ b/lib/hipe/regalloc/hipe_x86_specific_x87.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-ifdef(HIPE_AMD64).
-define(HIPE_X86_SPECIFIC_X87, hipe_amd64_specific_x87).
@@ -32,110 +25,119 @@
-endif.
-module(?HIPE_X86_SPECIFIC_X87).
--export([allocatable/0,
- is_precoloured/1,
- %% var_range/1,
- %% def_use/1,
- %% is_fixed/1,
- is_arg/1,
- %% non_alloc/1,
- new_spill_index/1,
- number_of_temporaries/1
+-export([allocatable/2,
+ is_precoloured/2,
+ %% var_range/2,
+ %% def_use/2,
+ %% is_fixed/2,
+ is_arg/2,
+ %% non_alloc/2,
+ new_spill_index/2,
+ number_of_temporaries/2
]).
%% The following exports are used as M:F(...) calls from other modules;
%% e.g. hipe_x86_ra_ls.
--export([analyze/1,
- bb/2,
- args/1,
- labels/1,
- livein/2,
- liveout/2,
- uses/1,
- defines/1,
- is_global/1,
- reg_nr/1,
- physical_name/1,
- breadthorder/1,
- postorder/1,
- reverse_postorder/1]).
-
-breadthorder(CFG) ->
+-export([analyze/2,
+ bb/3,
+ args/2,
+ labels/2,
+ livein/3,
+ liveout/3,
+ uses/2,
+ defines/2,
+ defines_all_alloc/2,
+ is_spill_move/2,
+ is_global/2,
+ reg_nr/2,
+ physical_name/2,
+ breadthorder/2,
+ postorder/2,
+ reverse_postorder/2]).
+
+%% callbacks for hipe_x86_ra_ls
+-export([check_and_rewrite/4]).
+
+%% Rewrite happens in hipe_x86_ra_finalise:finalise/4
+check_and_rewrite(CFG, _Coloring, 'linearscan', _) ->
+ {CFG, false}.
+
+breadthorder(CFG, _) ->
hipe_x86_cfg:breadthorder(CFG).
-postorder(CFG) ->
+postorder(CFG, _) ->
hipe_x86_cfg:postorder(CFG).
-reverse_postorder(CFG) ->
+reverse_postorder(CFG, _) ->
hipe_x86_cfg:reverse_postorder(CFG).
-is_global(_) ->
+is_global(_, _) ->
false.
-ifdef(notdef).
-is_fixed(_) ->
+is_fixed(_, _) ->
false.
-endif.
-is_arg(_) ->
+is_arg(_, _) ->
false.
-args(_) ->
+args(_, _) ->
[].
-ifdef(notdef).
-non_alloc(_) ->
+non_alloc(_, _) ->
[].
-endif.
%% Liveness stuff
-analyze(CFG) ->
+analyze(CFG, _) ->
?HIPE_X86_LIVENESS:analyze(CFG).
-livein(Liveness,L) ->
+livein(Liveness,L,_) ->
[X || X <- ?HIPE_X86_LIVENESS:livein(Liveness,L),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_type(X) =:= 'double'].
-liveout(BB_in_out_liveness,Label) ->
+liveout(BB_in_out_liveness,Label,_) ->
[X || X <- ?HIPE_X86_LIVENESS:liveout(BB_in_out_liveness,Label),
hipe_x86:temp_is_allocatable(X),
hipe_x86:temp_type(X) =:= 'double'].
%% Registers stuff
-allocatable() ->
+allocatable('linearscan', _) ->
?HIPE_X86_REGISTERS:allocatable_x87().
-is_precoloured(Reg) ->
+is_precoloured(Reg, _) ->
?HIPE_X86_REGISTERS:is_precoloured_x87(Reg).
-physical_name(Reg) ->
+physical_name(Reg, _) ->
Reg.
%% CFG stuff
-labels(CFG) ->
+labels(CFG, _) ->
hipe_x86_cfg:labels(CFG).
-ifdef(notdef).
-var_range(_CFG) ->
+var_range(_CFG, _) ->
{Min,Max} = hipe_gensym:var_range(x86),
%% io:format("Var_range: ~w\n",[{Min,Max}]),
{Min,Max}.
-endif.
-number_of_temporaries(_CFG) ->
+number_of_temporaries(_CFG, _) ->
Highest_temporary = hipe_gensym:get_var(x86),
%% Since we can have temps from 0 to Max adjust by +1.
Highest_temporary + 1.
-bb(CFG,L) ->
+bb(CFG,L,_) ->
hipe_x86_cfg:bb(CFG,L).
%% X86 stuff
-ifdef(notdef).
-def_use(Instruction) ->
+def_use(Instruction, _) ->
{[X || X <- ?HIPE_X86_DEFUSE:insn_def(Instruction),
hipe_x86:temp_is_allocatable(X),
temp_is_double(X)],
@@ -145,21 +147,26 @@ def_use(Instruction) ->
}.
-endif.
-uses(I) ->
+uses(I, _) ->
[X || X <- ?HIPE_X86_DEFUSE:insn_use(I),
hipe_x86:temp_is_allocatable(X),
temp_is_double(X)].
-defines(I) ->
+defines(I, _) ->
[X || X <- ?HIPE_X86_DEFUSE:insn_def(I),
hipe_x86:temp_is_allocatable(X),
temp_is_double(X)].
+defines_all_alloc(I, _) -> hipe_amd64_defuse:insn_defs_all(I).
+
+is_spill_move(I, _) ->
+ hipe_x86:is_pseudo_spill_fmove(I).
+
temp_is_double(Temp) ->
hipe_x86:temp_type(Temp) =:= 'double'.
-reg_nr(Reg) ->
+reg_nr(Reg, _) ->
hipe_x86:temp_reg(Reg).
-new_spill_index(SpillIndex) ->
+new_spill_index(SpillIndex, _) ->
SpillIndex+1.
diff --git a/lib/hipe/rtl/Makefile b/lib/hipe/rtl/Makefile
index b4cdf8b1f2..5abc9ec049 100644
--- a/lib/hipe/rtl/Makefile
+++ b/lib/hipe/rtl/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2001-2016. All Rights Reserved.
+# Copyright Ericsson AB 2001-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -118,10 +118,12 @@ else
TYPE_STR=
endif
-ifeq ($(FLAVOR),smp)
-FLAVOR_STR=.smp
-else
+FLAVOR=$(DEFAULT_FLAVOR)
+
+ifeq ($(FLAVOR),plain)
FLAVOR_STR=
+else
+FLAVOR_STR=.smp
endif
ifeq ($(XCOMP),yes)
diff --git a/lib/hipe/rtl/hipe_icode2rtl.erl b/lib/hipe/rtl/hipe_icode2rtl.erl
index 22feca47cc..6da8a76d34 100644
--- a/lib/hipe/rtl/hipe_icode2rtl.erl
+++ b/lib/hipe/rtl/hipe_icode2rtl.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,17 +11,12 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%=======================================================================
%% File : hipe_icode2rtl.erl
%% Author(s) : Erik Johansson
%% Description : Translates Icode to RTL
%%=======================================================================
-%%
-%% $Id$
-%%
%% TODO: Better handling of switches...
-module(hipe_icode2rtl).
@@ -541,8 +532,12 @@ gen_cond(CondOp, Args, TrueLbl, FalseLbl, Pred) ->
FalseLbl, Pred)];
'=:=' ->
[Arg1, Arg2] = Args,
+ TypeTestLbl = hipe_rtl:mk_new_label(),
[hipe_rtl:mk_branch(Arg1, eq, Arg2, TrueLbl,
- hipe_rtl:label_name(GenLbl), Pred),
+ hipe_rtl:label_name(TypeTestLbl), Pred),
+ TypeTestLbl,
+ hipe_tagscheme:test_either_immed(Arg1, Arg2, FalseLbl,
+ hipe_rtl:label_name(GenLbl)),
GenLbl,
hipe_rtl:mk_call([Tmp], op_exact_eqeq_2, Args,
TestRetName, [], not_remote),
@@ -555,8 +550,12 @@ gen_cond(CondOp, Args, TrueLbl, FalseLbl, Pred) ->
TrueLbl, 1-Pred)];
'=/=' ->
[Arg1, Arg2] = Args,
+ TypeTestLbl = hipe_rtl:mk_new_label(),
[hipe_rtl:mk_branch(Arg1, eq, Arg2, FalseLbl,
- hipe_rtl:label_name(GenLbl), 1-Pred),
+ hipe_rtl:label_name(TypeTestLbl), 1-Pred),
+ TypeTestLbl,
+ hipe_tagscheme:test_either_immed(Arg1, Arg2, TrueLbl,
+ hipe_rtl:label_name(GenLbl)),
GenLbl,
hipe_rtl:mk_call([Tmp], op_exact_eqeq_2, Args,
TestRetName, [], not_remote),
diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl
index 0726827299..04c9728d5c 100644
--- a/lib/hipe/rtl/hipe_rtl.erl
+++ b/lib/hipe/rtl/hipe_rtl.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% @doc
@@ -187,18 +181,14 @@
mk_branch/5,
mk_branch/6,
- branch_src1/1,
- branch_src2/1,
- branch_cond/1,
- branch_true_label/1,
- branch_false_label/1,
- branch_pred/1,
+ mk_branch/7,
%% is_branch/1,
%% branch_true_label_update/2,
%% branch_false_label_update/2,
mk_alub/7,
mk_alub/8,
+ alub_has_dst/1,
alub_dst/1,
alub_src1/1,
alub_op/1,
@@ -338,6 +328,7 @@
defines/1,
redirect_jmp/3,
is_safe/1,
+ reduce_unused/1,
%% highest_var/1,
pp/1,
pp/2,
@@ -588,37 +579,25 @@ is_label(#label{}) -> true;
is_label(_) -> false.
%%
-%% branch
-%%
-
-mk_branch(Src1, Op, Src2, True, False) ->
- mk_branch(Src1, Op, Src2, True, False, 0.5).
-mk_branch(Src1, Op, Src2, True, False, P) ->
- #branch{src1=Src1, 'cond'=Op, src2=Src2, true_label=True,
- false_label=False, p=P}.
-branch_src1(#branch{src1=Src1}) -> Src1.
-branch_src1_update(Br, NewSrc) -> Br#branch{src1=NewSrc}.
-branch_src2(#branch{src2=Src2}) -> Src2.
-branch_src2_update(Br, NewSrc) -> Br#branch{src2=NewSrc}.
-branch_cond(#branch{'cond'=Cond}) -> Cond.
-branch_true_label(#branch{true_label=TrueLbl}) -> TrueLbl.
-branch_true_label_update(Br, NewTrue) -> Br#branch{true_label=NewTrue}.
-branch_false_label(#branch{false_label=FalseLbl}) -> FalseLbl.
-branch_false_label_update(Br, NewFalse) -> Br#branch{false_label=NewFalse}.
-branch_pred(#branch{p=P}) -> P.
-
-%%
%% alub
%%
-type alub_cond() :: 'eq' | 'ne' | 'ge' | 'geu' | 'gt' | 'gtu' | 'le'
| 'leu' | 'lt' | 'ltu' | 'overflow' | 'not_overflow'.
+mk_branch(Src1, Cond, Src2, True, False) ->
+ mk_branch(Src1, Cond, Src2, True, False, 0.5).
+mk_branch(Src1, Cond, Src2, True, False, P) ->
+ mk_branch(Src1, 'sub', Src2, Cond, True, False, P).
+mk_branch(Src1, Op, Src2, Cond, True, False, P) ->
+ mk_alub([], Src1, Op, Src2, Cond, True, False, P).
+
mk_alub(Dst, Src1, Op, Src2, Cond, True, False) ->
mk_alub(Dst, Src1, Op, Src2, Cond, True, False, 0.5).
mk_alub(Dst, Src1, Op, Src2, Cond, True, False, P) ->
#alub{dst=Dst, src1=Src1, op=Op, src2=Src2, 'cond'=Cond,
true_label=True, false_label=False, p=P}.
+alub_has_dst(#alub{dst=Dst}) -> Dst =/= [].
alub_dst(#alub{dst=Dst}) -> Dst.
alub_dst_update(A, NewDst) -> A#alub{dst=NewDst}.
alub_src1(#alub{src1=Src1}) -> Src1.
@@ -943,8 +922,7 @@ args(I) ->
case I of
#alu{} -> [alu_src1(I), alu_src2(I)];
#alub{} -> [alub_src1(I), alub_src2(I)];
- #branch{} -> [branch_src1(I), branch_src2(I)];
- #call{} ->
+ #call{} ->
Args = call_arglist(I) ++ hipe_rtl_arch:call_used(),
case call_is_known(I) of
false -> [call_fun(I) | Args];
@@ -987,8 +965,8 @@ args(I) ->
defines(Instr) ->
Defs = case Instr of
#alu{} -> [alu_dst(Instr)];
+ #alub{dst=[]} -> [];
#alub{} -> [alub_dst(Instr)];
- #branch{} -> [];
#call{} -> call_dstlist(Instr) ++ hipe_rtl_arch:call_defined();
#comment{} -> [];
#enter{} -> [];
@@ -1042,9 +1020,6 @@ subst_uses(Subst, I) ->
#alub{} ->
I0 = alub_src1_update(I, subst1(Subst, alub_src1(I))),
alub_src2_update(I0, subst1(Subst, alub_src2(I)));
- #branch{} ->
- I0 = branch_src1_update(I, subst1(Subst, branch_src1(I))),
- branch_src2_update(I0, subst1(Subst, branch_src2(I)));
#call{} ->
case call_is_known(I) of
false ->
@@ -1126,11 +1101,6 @@ subst_uses_llvm(Subst, I) ->
{NewSrc1, _ } = subst1_llvm(Subst1, alub_src1(I)),
I0 = alub_src1_update(I, NewSrc1),
alub_src2_update(I0, NewSrc2);
- #branch{} ->
- {NewSrc2, Subst1} = subst1_llvm(Subst, branch_src2(I)),
- {NewSrc1, _ } = subst1_llvm(Subst1, branch_src1(I)),
- I0 = branch_src1_update(I, NewSrc1),
- branch_src2_update(I0, NewSrc2);
#call{} ->
case call_is_known(I) of
false ->
@@ -1243,10 +1213,10 @@ subst_defines(Subst, I)->
case I of
#alu{} ->
alu_dst_update(I, subst1(Subst, alu_dst(I)));
+ #alub{dst=[]} ->
+ I;
#alub{} ->
alub_dst_update(I, subst1(Subst, alub_dst(I)));
- #branch{} ->
- I;
#call{} ->
call_dstlist_update(I, subst_list(Subst, call_dstlist(I)));
#comment{} ->
@@ -1313,7 +1283,6 @@ is_safe(Instr) ->
case Instr of
#alu{} -> true;
#alub{} -> false;
- #branch{} -> false;
#call{} -> false;
#comment{} -> false;
#enter{} -> false;
@@ -1340,6 +1309,24 @@ is_safe(Instr) ->
#switch{} -> false %% Maybe this is safe...
end.
+%% @spec reduce_unused(rtl_instruction())
+%% -> false | [rtl_instruction()].
+%%
+%% @doc Produces a simplified instruction sequence that is equivalent to [Instr]
+%% under the assumption that all results of Instr are unused, or 'false' if
+%% there is no such sequence (other than [Instr] itself).
+
+reduce_unused(Instr) ->
+ case Instr of
+ #alub{dst=Dst} when Dst =/= [] ->
+ [Instr#alub{dst=[]}];
+ _ ->
+ case is_safe(Instr) of
+ true -> [];
+ false -> false
+ end
+ end.
+
%%
%% True if argument is an alu-operator
%%
@@ -1386,17 +1373,6 @@ redirect_jmp(Jmp, ToOld, ToNew) ->
%% OBS: In a jmp instruction more than one labels may be identical
%% and thus need redirection!
case Jmp of
- #branch{} ->
- TmpJmp = case branch_true_label(Jmp) of
- ToOld -> branch_true_label_update(Jmp, ToNew);
- _ -> Jmp
- end,
- case branch_false_label(TmpJmp) of
- ToOld ->
- branch_false_label_update(TmpJmp, ToNew);
- _ ->
- TmpJmp
- end;
#switch{} ->
NewLbls = [case Lbl =:= ToOld of
true -> ToNew;
@@ -1591,13 +1567,6 @@ pp_instr(Dev, I) ->
io:format(Dev, "~n", []);
#label{} ->
io:format(Dev, "L~w:~n", [label_name(I)]);
- #branch{} ->
- io:format(Dev, " if (", []),
- pp_arg(Dev, branch_src1(I)),
- io:format(Dev, " ~w ", [branch_cond(I)]),
- pp_arg(Dev, branch_src2(I)),
- io:format(Dev, ") then L~w (~.2f) else L~w~n",
- [branch_true_label(I), branch_pred(I), branch_false_label(I)]);
#switch{} ->
io:format(Dev, " switch (", []),
pp_arg(Dev, switch_src(I)),
@@ -1606,7 +1575,10 @@ pp_instr(Dev, I) ->
io:format(Dev, ">\n", []);
#alub{} ->
io:format(Dev, " ", []),
- pp_arg(Dev, alub_dst(I)),
+ case alub_has_dst(I) of
+ true -> pp_arg(Dev, alub_dst(I));
+ false -> io:format(Dev, "_", [])
+ end,
io:format(Dev, " <- ", []),
pp_arg(Dev, alub_src1(I)),
io:format(Dev, " ~w ", [alub_op(I)]),
diff --git a/lib/hipe/rtl/hipe_rtl.hrl b/lib/hipe/rtl/hipe_rtl.hrl
index cc76e7e5c4..50059693aa 100644
--- a/lib/hipe/rtl/hipe_rtl.hrl
+++ b/lib/hipe/rtl/hipe_rtl.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -28,7 +22,6 @@
-record(alu, {dst, src1, op, src2}).
-record(alub, {dst, src1, op, src2, 'cond', true_label, false_label, p}).
--record(branch, {src1, src2, 'cond', true_label, false_label, p}).
-record(call, {dstlist, 'fun', arglist, type, continuation,
failcontinuation, normalcontinuation = []}).
-record(comment, {text}).
diff --git a/lib/hipe/rtl/hipe_rtl_arch.erl b/lib/hipe/rtl/hipe_rtl_arch.erl
index 397b96120e..65149ea7db 100644
--- a/lib/hipe/rtl/hipe_rtl_arch.erl
+++ b/lib/hipe/rtl/hipe_rtl_arch.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson.
%%=====================================================================
diff --git a/lib/hipe/rtl/hipe_rtl_arith.inc b/lib/hipe/rtl/hipe_rtl_arith.inc
index 0c396c8e76..c05b7aa160 100644
--- a/lib/hipe/rtl/hipe_rtl_arith.inc
+++ b/lib/hipe/rtl/hipe_rtl_arith.inc
@@ -1,10 +1,6 @@
%% -*- Erlang -*-
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_rtl_arith.inc
diff --git a/lib/hipe/rtl/hipe_rtl_arith_32.erl b/lib/hipe/rtl/hipe_rtl_arith_32.erl
index 12075ed609..1f911642d5 100644
--- a/lib/hipe/rtl/hipe_rtl_arith_32.erl
+++ b/lib/hipe/rtl/hipe_rtl_arith_32.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2002 by Erik Johansson.
diff --git a/lib/hipe/rtl/hipe_rtl_arith_64.erl b/lib/hipe/rtl/hipe_rtl_arith_64.erl
index 6dac8fb145..5fa067b98e 100644
--- a/lib/hipe/rtl/hipe_rtl_arith_64.erl
+++ b/lib/hipe/rtl/hipe_rtl_arith_64.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_rtl_arith_64.erl
diff --git a/lib/hipe/rtl/hipe_rtl_binary.erl b/lib/hipe/rtl/hipe_rtl_binary.erl
index fb9c0c196d..c11f61d567 100644
--- a/lib/hipe/rtl/hipe_rtl_binary.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary.erl
@@ -1,9 +1,5 @@
-%% -*- erlang-indent-level: 2 -*-
+%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,11 +11,9 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
-%%% File : hipe_rtl_binary_2.erl
+%%% File : hipe_rtl_binary.erl
%%% Author : Per Gustafsson <[email protected]>
%%% Description :
%%%
@@ -106,10 +100,20 @@ create_lbls(0) ->
%%------------------------------------------------------------------------------
get_word_integer(Var, Register, SystemLimitLblName, FalseLblName) ->
- [EndLbl] = create_lbls(1),
- EndName = hipe_rtl:label_name(EndLbl),
- get_word_integer(Var, Register,SystemLimitLblName, FalseLblName, EndName, EndName,
- [EndLbl]).
+ case hipe_rtl:is_imm(Var) of
+ true ->
+ TaggedVal = hipe_rtl:imm_value(Var),
+ true = hipe_tagscheme:is_fixnum(TaggedVal),
+ Val = hipe_tagscheme:fixnum_val(TaggedVal),
+ if Val < 0 -> [hipe_rtl:mk_goto(FalseLblName)];
+ true -> [hipe_rtl:mk_move(Register, hipe_rtl:mk_imm(Val))]
+ end;
+ false ->
+ [EndLbl] = create_lbls(1),
+ EndName = hipe_rtl:label_name(EndLbl),
+ get_word_integer(Var, Register,SystemLimitLblName, FalseLblName,
+ EndName, EndName, [EndLbl])
+ end.
get_word_integer(Var, Register, SystemLimitLblName, FalseLblName, TrueLblName,
BigLblName, Tail) ->
diff --git a/lib/hipe/rtl/hipe_rtl_binary_construct.erl b/lib/hipe/rtl/hipe_rtl_binary_construct.erl
index 367d76b24d..52ea5db382 100644
--- a/lib/hipe/rtl/hipe_rtl_binary_construct.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary_construct.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ====================================================================
%% Module : hipe_rtl_binary_construct
@@ -143,43 +137,6 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
end
end;
- {bs_put_integer, Size, Flags, ConstInfo} ->
- Aligned = aligned(Flags),
- LittleEndian = littleendian(Flags),
- [NewOffset] = get_real(Dst),
- case is_illegal_const(Size) of
- true ->
- [hipe_rtl:mk_goto(FalseLblName)];
- false ->
- case ConstInfo of
- fail ->
- [hipe_rtl:mk_goto(FalseLblName)];
- _ ->
- case Args of
- [Src, Base, Offset] ->
- CCode = static_int_c_code(NewOffset, Src,
- Base, Offset, Size,
- Flags, TrueLblName,
- FalseLblName),
- put_static_int(NewOffset, Src, Base, Offset, Size,
- CCode, Aligned, LittleEndian, TrueLblName);
- [Src, Bits, Base, Offset] ->
- {SizeCode, SizeReg} =
- hipe_rtl_binary:make_size(Size, Bits,
- SystemLimitLblName,
- FalseLblName),
- CCode = int_c_code(NewOffset, Src, Base,
- Offset, SizeReg, Flags,
- TrueLblName, FalseLblName),
- InCode =
- put_dynamic_int(NewOffset, Src, Base, Offset,
- SizeReg, CCode, Aligned,
- LittleEndian, TrueLblName),
- SizeCode ++ InCode
- end
- end
- end;
-
{unsafe_bs_put_integer, 0, _Flags, _ConstInfo} ->
[NewOffset] = get_real(Dst),
case Args of
@@ -192,44 +149,12 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
end;
{unsafe_bs_put_integer, Size, Flags, ConstInfo} ->
- case is_illegal_const(Size) of
- true ->
- [hipe_rtl:mk_goto(FalseLblName)];
- false ->
- Aligned = aligned(Flags),
- LittleEndian = littleendian(Flags),
- [NewOffset] = get_real(Dst),
- case ConstInfo of
- fail ->
- [hipe_rtl:mk_goto(FalseLblName)];
- _ ->
- case Args of
- [Src, Base, Offset] ->
- CCode = static_int_c_code(NewOffset, Src,
- Base, Offset, Size,
- Flags, TrueLblName,
- FalseLblName),
- put_unsafe_static_int(NewOffset, Src, Base,
- Offset, Size,
- CCode, Aligned, LittleEndian,
- TrueLblName);
- [Src, Bits, Base, Offset] ->
- {SizeCode, SizeReg} =
- hipe_rtl_binary:make_size(Size, Bits,
- SystemLimitLblName,
- FalseLblName),
- CCode = int_c_code(NewOffset, Src, Base,
- Offset, SizeReg, Flags,
- TrueLblName, FalseLblName),
- InCode =
- put_unsafe_dynamic_int(NewOffset, Src, Base,
- Offset, SizeReg, CCode,
- Aligned, LittleEndian,
- TrueLblName),
- SizeCode ++ InCode
- end
- end
- end;
+ do_bs_put_integer(Dst, Args, Size, Flags, ConstInfo, true,
+ TrueLblName, FalseLblName, SystemLimitLblName);
+
+ {bs_put_integer, Size, Flags, ConstInfo} ->
+ do_bs_put_integer(Dst, Args, Size, Flags, ConstInfo, false,
+ TrueLblName, FalseLblName, SystemLimitLblName);
bs_utf8_size ->
case Dst of
@@ -366,6 +291,40 @@ gen_rtl(BsOP, Dst, Args, TrueLblName, FalseLblName, SystemLimitLblName, ConstTab
{Code, ConstTab}
end.
+%% Common implementation of bs_put_integer and unsafe_bs_put_integer
+do_bs_put_integer(Dst, Args, Size, Flags, ConstInfo, SrcUnsafe,
+ TrueLblName, FalseLblName, SystemLimitLblName) ->
+ case is_illegal_const(Size) of
+ true ->
+ [hipe_rtl:mk_goto(FalseLblName)];
+ false ->
+ Aligned = aligned(Flags),
+ LittleEndian = littleendian(Flags),
+ [NewOffset] = get_real(Dst),
+ case ConstInfo of
+ fail ->
+ [hipe_rtl:mk_goto(FalseLblName)];
+ _ ->
+ case Args of
+ [Src, Base, Offset] ->
+ CCode = static_int_c_code(NewOffset, Src, Base, Offset, Size,
+ Flags, TrueLblName, FalseLblName),
+ put_static_int(NewOffset, Src, Base, Offset, Size, CCode, Aligned,
+ LittleEndian, SrcUnsafe, TrueLblName);
+ [Src, Bits, Base, Offset] ->
+ {SizeCode, SizeReg} =
+ hipe_rtl_binary:make_size(Size, Bits, SystemLimitLblName,
+ FalseLblName),
+ CCode = int_c_code(NewOffset, Src, Base, Offset, SizeReg, Flags,
+ TrueLblName, FalseLblName),
+ InCode = put_dynamic_int(NewOffset, Src, Base, Offset, SizeReg,
+ CCode, Aligned, LittleEndian, SrcUnsafe,
+ TrueLblName),
+ SizeCode ++ InCode
+ end
+ end
+ end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Code that is used in the append and init writeable functions
@@ -429,8 +388,8 @@ realloc_binary(SizeReg, ProcBin, Base) ->
hipe_tagscheme:set_field_from_term(ProcBinFlagsTag, ProcBin, Flags),
hipe_tagscheme:get_field_from_term(ProcBinValTag, ProcBin, BinPointer),
hipe_tagscheme:get_field_from_pointer(BinOrigSizeTag, BinPointer, OrigSize),
- hipe_rtl:mk_branch(OrigSize, 'ltu', ResultingSize,
- ReallocLblName, NoReallocLblName),
+ hipe_rtl:mk_branch(OrigSize, 'geu', ResultingSize, NoReallocLblName,
+ ReallocLblName),
NoReallocLbl,
hipe_tagscheme:get_field_from_term(ProcBinBytesTag, ProcBin, Base),
hipe_rtl:mk_goto(ContLblName),
@@ -757,9 +716,9 @@ test_alignment(SrcOffset, NumBits, Offset, AlignedCode, CCode) ->
[AlignedLbl, CLbl] = create_lbls(2),
[hipe_rtl:mk_alu(Tmp, SrcOffset, 'or', NumBits),
hipe_rtl:mk_alu(Tmp, Tmp, 'or', Offset),
- hipe_rtl:mk_alub(Tmp, Tmp, 'and', ?LOW_BITS, 'eq',
- hipe_rtl:label_name(AlignedLbl),
- hipe_rtl:label_name(CLbl)),
+ hipe_rtl:mk_branch(Tmp, 'and', ?LOW_BITS, 'eq',
+ hipe_rtl:label_name(AlignedLbl),
+ hipe_rtl:label_name(CLbl), 0.5),
AlignedLbl,
AlignedCode,
CLbl,
@@ -813,28 +772,8 @@ put_float(_NewOffset, _Src, _Base, _Offset, _Size, CCode, _Aligned,
CCode.
put_static_int(NewOffset, Src, Base, Offset, Size, CCode, Aligned,
- LittleEndian, TrueLblName) ->
- {Init, End, UntaggedSrc} = make_init_end(Src, CCode, TrueLblName),
- case {Aligned, LittleEndian} of
- {true, true} ->
- Init ++
- copy_int_little(Base, Offset, NewOffset, Size, UntaggedSrc) ++
- End;
- {true, false} ->
- Init ++
- copy_int_big(Base, Offset, NewOffset, Size, UntaggedSrc) ++
- End;
- {false, true} ->
- CCode;
- {false, false} ->
- Init ++
- copy_offset_int_big(Base, Offset, NewOffset, Size, UntaggedSrc) ++
- End
- end.
-
-put_unsafe_static_int(NewOffset, Src, Base, Offset, Size, CCode, Aligned,
- LittleEndian, TrueLblName) ->
- {Init, End, UntaggedSrc} = make_init_end(Src, TrueLblName),
+ LittleEndian, SrcUnsafe, TrueLblName) ->
+ {Init, End, UntaggedSrc} = make_init_end(Src, CCode, SrcUnsafe, TrueLblName),
case {Aligned, LittleEndian} of
{true, true} ->
Init ++
@@ -853,27 +792,8 @@ put_unsafe_static_int(NewOffset, Src, Base, Offset, Size, CCode, Aligned,
end.
put_dynamic_int(NewOffset, Src, Base, Offset, SizeReg, CCode, Aligned,
- LittleEndian, TrueLblName) ->
- {Init, End, UntaggedSrc} = make_init_end(Src, CCode, TrueLblName),
- case Aligned of
- true ->
- case LittleEndian of
- true ->
- Init ++
- copy_int_little(Base, Offset, NewOffset, SizeReg, UntaggedSrc) ++
- End;
- false ->
- Init ++
- copy_int_big(Base, Offset, NewOffset, SizeReg, UntaggedSrc) ++
- End
- end;
- false ->
- CCode
- end.
-
-put_unsafe_dynamic_int(NewOffset, Src, Base, Offset, SizeReg, CCode, Aligned,
- LittleEndian, TrueLblName) ->
- {Init, End, UntaggedSrc} = make_init_end(Src, TrueLblName),
+ LittleEndian, SrcUnsafe, TrueLblName) ->
+ {Init, End, UntaggedSrc} = make_init_end(Src, CCode, SrcUnsafe, TrueLblName),
case Aligned of
true ->
case LittleEndian of
@@ -890,14 +810,13 @@ put_unsafe_dynamic_int(NewOffset, Src, Base, Offset, SizeReg, CCode, Aligned,
CCode
end.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Help functions used by the above
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-make_init_end(Src, CCode, TrueLblName) ->
+make_init_end(Src, CCode, false, TrueLblName) ->
[CLbl, SuccessLbl] = create_lbls(2),
[UntaggedSrc] = create_regs(1),
Init = [hipe_tagscheme:test_fixnum(Src, hipe_rtl:label_name(SuccessLbl),
@@ -905,9 +824,8 @@ make_init_end(Src, CCode, TrueLblName) ->
SuccessLbl,
hipe_tagscheme:untag_fixnum(UntaggedSrc,Src)],
End = [hipe_rtl:mk_goto(TrueLblName), CLbl| CCode],
- {Init, End, UntaggedSrc}.
-
-make_init_end(Src, TrueLblName) ->
+ {Init, End, UntaggedSrc};
+make_init_end(Src, _CCode, true, TrueLblName) ->
[UntaggedSrc] = create_regs(1),
Init = [hipe_tagscheme:untag_fixnum(UntaggedSrc,Src)],
End = [hipe_rtl:mk_goto(TrueLblName)],
@@ -1284,8 +1202,7 @@ is_divisible(Dividend, Divisor, SuccLbl, FailLbl) ->
true -> %% Divisor is a power of 2
%% Test that the Log2-1 lowest bits are clear
Mask = hipe_rtl:mk_imm(Divisor - 1),
- [Tmp] = create_regs(1),
- [hipe_rtl:mk_alub(Tmp, Dividend, 'and', Mask, eq, SuccLbl, FailLbl, 0.99)];
+ [hipe_rtl:mk_branch(Dividend, 'and', Mask, eq, SuccLbl, FailLbl, 0.99)];
false ->
%% We need division, fall back to a primop
[hipe_rtl:mk_call([], is_divisible, [Dividend, hipe_rtl:mk_imm(Divisor)],
diff --git a/lib/hipe/rtl/hipe_rtl_binary_match.erl b/lib/hipe/rtl/hipe_rtl_binary_match.erl
index 528672b893..362a52f8fe 100644
--- a/lib/hipe/rtl/hipe_rtl_binary_match.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary_match.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_rtl_binary_match.erl
@@ -270,24 +264,23 @@ gen_rtl({bs_save, Slot}, [NewMs], [Ms], TrueLblName, _FalseLblName) ->
set_field_from_term({matchstate, {saveoffset, Slot}}, Ms, Offset),
hipe_rtl:mk_goto(TrueLblName)];
%% ----- bs_match_string -----
-gen_rtl({bs_match_string, String, ByteSize}, Dst, [Ms],
+gen_rtl({bs_match_string, String, BitSize}, Dst, [Ms],
TrueLblName, FalseLblName) ->
{[Offset, BinSize, Base], Instrs} =
extract_matchstate_vars([offset, binsize, base], Ms),
[SuccessLbl, ALbl, ULbl] = create_lbls(3),
[NewOffset, BitOffset] = create_gcsafe_regs(2),
- Unit = hipe_rtl_arch:word_size() - 1,
- Loops = ByteSize div Unit,
- Init =
+ Unit = (hipe_rtl_arch:word_size() - 1) * ?BYTE_SIZE,
+ Init =
[Instrs,
opt_update_ms(Dst, Ms),
- check_size(Offset, hipe_rtl:mk_imm(ByteSize*?BYTE_SIZE), BinSize,
+ check_size(Offset, hipe_rtl:mk_imm(BitSize), BinSize,
NewOffset, hipe_rtl:label_name(SuccessLbl), FalseLblName),
SuccessLbl],
SplitCode =
[hipe_rtl:mk_alub(BitOffset, Offset, 'and', hipe_rtl:mk_imm(?LOW_BITS), eq,
hipe_rtl:label_name(ALbl), hipe_rtl:label_name(ULbl))],
- Loops = ByteSize div Unit,
+ Loops = BitSize div Unit,
SkipSize = Loops * Unit,
{ACode1, UCode1} =
case Loops of
@@ -297,9 +290,9 @@ gen_rtl({bs_match_string, String, ByteSize}, Dst, [Ms],
create_loops(Loops, Unit, String, Base,
Offset, BitOffset, FalseLblName)
end,
- <<_:SkipSize/binary, RestString/binary>> = String,
+ <<_:SkipSize/bits, RestString/bits>> = String,
{ACode2, UCode2} =
- case ByteSize rem Unit of
+ case BitSize rem Unit of
0 ->
{[], []};
Rem ->
@@ -393,12 +386,12 @@ validate_unicode_retract_c_code(Src, Ms, TrueLblName, FalseLblName) ->
create_loops(Loops, Unit, String, Base, Offset, BitOffset, FalseLblName) ->
[Reg] = create_gcsafe_regs(1),
AlignedFun = fun(Value) ->
- [get_int_to_reg(Reg, Unit*?BYTE_SIZE, Base, Offset, 'srl',
+ [get_int_to_reg(Reg, Unit, Base, Offset, 'srl',
{unsigned, big}),
update_and_test(Reg, Unit, Offset, Value, FalseLblName)]
end,
UnAlignedFun = fun(Value) ->
- [get_unaligned_int_to_reg(Reg, Unit*?BYTE_SIZE,
+ [get_unaligned_int_to_reg(Reg, Unit,
Base, Offset, BitOffset,
'srl', {unsigned, big})|
update_and_test(Reg, Unit, Offset, Value, FalseLblName)]
@@ -406,31 +399,31 @@ create_loops(Loops, Unit, String, Base, Offset, BitOffset, FalseLblName) ->
{create_loops(Loops, Unit, String, AlignedFun),
create_loops(Loops, Unit, String, UnAlignedFun)}.
-create_rests(Rem, String, Base, Offset, BitOffset, FalseLblName) ->
+create_rests(RemBits, String, Base, Offset, BitOffset, FalseLblName) ->
[Reg] = create_gcsafe_regs(1),
AlignedFun = fun(Value) ->
- [get_int_to_reg(Reg, Rem*?BYTE_SIZE, Base, Offset, 'srl',
+ [get_int_to_reg(Reg, RemBits, Base, Offset, 'srl',
{unsigned, big})|
just_test(Reg, Value, FalseLblName)]
end,
UnAlignedFun = fun(Value) ->
- [get_unaligned_int_to_reg(Reg, Rem*?BYTE_SIZE,
+ [get_unaligned_int_to_reg(Reg, RemBits,
Base, Offset, BitOffset,
'srl', {unsigned, big})|
just_test(Reg, Value, FalseLblName)]
end,
- {create_loops(1, Rem, String, AlignedFun),
- create_loops(1, Rem, String, UnAlignedFun)}.
+ {create_loops(1, RemBits, String, AlignedFun),
+ create_loops(1, RemBits, String, UnAlignedFun)}.
create_loops(0, _Unit, _String, _IntFun) ->
[];
create_loops(N, Unit, String, IntFun) ->
- {Value, RestString} = get_value(Unit,String),
+ {Value, RestString} = get_value(Unit, String),
[IntFun(Value),
create_loops(N-1, Unit, RestString, IntFun)].
update_and_test(Reg, Unit, Offset, Value, FalseLblName) ->
- [add_to_offset(Offset, Offset, hipe_rtl:mk_imm(Unit*?BYTE_SIZE), FalseLblName),
+ [add_to_offset(Offset, Offset, hipe_rtl:mk_imm(Unit), FalseLblName),
just_test(Reg, Value, FalseLblName)].
just_test(Reg, Value, FalseLblName) ->
@@ -439,8 +432,8 @@ just_test(Reg, Value, FalseLblName) ->
hipe_rtl:label_name(ContLbl), FalseLblName),
ContLbl].
-get_value(N,String) ->
- <<I:N/integer-unit:8, Rest/binary>> = String,
+get_value(N, String) ->
+ <<I:N, Rest/bits>> = String,
{I, Rest}.
make_int_gc_code(I) when is_integer(I) ->
@@ -660,9 +653,8 @@ test_alignment_code(Size, Unit, SLblName, FalseLblName) ->
end.
get_fast_test_code(Size, AndTest, SLblName, FalseLblName) ->
- [Tmp] = create_gcsafe_regs(1),
- [hipe_rtl:mk_alub(Tmp, Size, 'and', hipe_rtl:mk_imm(AndTest),
- 'eq', SLblName, FalseLblName)].
+ [hipe_rtl:mk_branch(Size, 'and', hipe_rtl:mk_imm(AndTest), 'eq',
+ SLblName, FalseLblName, 0.5)].
%% This is really slow
get_slow_test_code(Size, Unit, SLblName, FalseLblName) ->
diff --git a/lib/hipe/rtl/hipe_rtl_cfg.erl b/lib/hipe/rtl/hipe_rtl_cfg.erl
index f49e8f815f..ce399498d6 100644
--- a/lib/hipe/rtl/hipe_rtl_cfg.erl
+++ b/lib/hipe/rtl/hipe_rtl_cfg.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_rtl_cfg).
@@ -83,9 +76,7 @@ mk_goto(Name) ->
branch_successors(Instr) ->
case Instr of
- #branch{} -> [hipe_rtl:branch_true_label(Instr),
- hipe_rtl:branch_false_label(Instr)];
- #alub{} -> [hipe_rtl:alub_true_label(Instr),
+ #alub{} -> [hipe_rtl:alub_true_label(Instr),
hipe_rtl:alub_false_label(Instr)];
#switch{} -> hipe_rtl:switch_labels(Instr);
#call{} ->
@@ -106,7 +97,6 @@ fails_to(Instr) ->
is_branch(Instr) ->
case Instr of
- #branch{} -> true;
#alub{} -> true;
#switch{} -> true;
#goto{} -> true;
@@ -127,7 +117,7 @@ is_branch(Instr) ->
is_pure_branch(Instr) ->
case Instr of
- #branch{} -> true;
+ #alub{} -> not hipe_rtl:alub_has_dst(Instr);
#switch{} -> true;
#goto{} -> true;
_ -> false
diff --git a/lib/hipe/rtl/hipe_rtl_cleanup_const.erl b/lib/hipe/rtl/hipe_rtl_cleanup_const.erl
index 0a1cdbacb8..bfa6b9682e 100644
--- a/lib/hipe/rtl/hipe_rtl_cleanup_const.erl
+++ b/lib/hipe/rtl/hipe_rtl_cleanup_const.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_rtl_cleanup_const.erl
diff --git a/lib/hipe/rtl/hipe_rtl_exceptions.erl b/lib/hipe/rtl/hipe_rtl_exceptions.erl
index 331719f344..03dc959bcf 100644
--- a/lib/hipe/rtl/hipe_rtl_exceptions.erl
+++ b/lib/hipe/rtl/hipe_rtl_exceptions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
@@ -27,8 +21,6 @@
%% Notes :
%% History : * 2001-04-10 Erik Johansson ([email protected]):
%% Created.
-%% CVS :
-%% $Id$
%% ====================================================================
%% Exports :
%%
diff --git a/lib/hipe/rtl/hipe_rtl_lcm.erl b/lib/hipe/rtl/hipe_rtl_lcm.erl
index 71bd06c0df..9dcdd05fb1 100644
--- a/lib/hipe/rtl/hipe_rtl_lcm.erl
+++ b/lib/hipe/rtl/hipe_rtl_lcm.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% File : hipe_rtl_lcm.erl
@@ -378,7 +372,6 @@ is_expr(I) ->
%% end;
#alub{} -> false; %% TODO: Split instruction to consider alu expression?
- #branch{} -> false;
#call{} -> false; %% We cannot prove that a call has no side-effects
#comment{} -> false;
#enter{} -> false;
diff --git a/lib/hipe/rtl/hipe_rtl_liveness.erl b/lib/hipe/rtl/hipe_rtl_liveness.erl
index 674043ec3c..98376439f3 100644
--- a/lib/hipe/rtl/hipe_rtl_liveness.erl
+++ b/lib/hipe/rtl/hipe_rtl_liveness.erl
@@ -1,9 +1,3 @@
-%% $Id$
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_mk_switch.erl b/lib/hipe/rtl/hipe_rtl_mk_switch.erl
index 5f9dffa8cf..d5cc6bd5df 100644
--- a/lib/hipe/rtl/hipe_rtl_mk_switch.erl
+++ b/lib/hipe/rtl/hipe_rtl_mk_switch.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
diff --git a/lib/hipe/rtl/hipe_rtl_primops.erl b/lib/hipe/rtl/hipe_rtl_primops.erl
index 062fab842f..850a75f71b 100644
--- a/lib/hipe/rtl/hipe_rtl_primops.erl
+++ b/lib/hipe/rtl/hipe_rtl_primops.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
@@ -26,9 +20,6 @@
%% Notes :
%% History : * 2001-03-15 Erik Johansson ([email protected]):
%% Created.
-%%
-%% $Id$
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(hipe_rtl_primops).
@@ -760,12 +751,9 @@ gen_fun_thing_skeleton(FunP, FunName={_Mod,_FunId,Arity}, NumFree,
%% And creates a fe (at load time).
FeVar = hipe_rtl:mk_new_reg(),
PidVar = hipe_rtl:mk_new_reg_gcsafe(),
- NativeVar = hipe_rtl:mk_new_reg(),
[hipe_rtl:mk_load_address(FeVar, {FunName, MagicNr, Index}, closure),
store_struct_field(FunP, ?EFT_FE, FeVar),
- load_struct_field(NativeVar, FeVar, ?EFE_NATIVE_ADDRESS),
- store_struct_field(FunP, ?EFT_NATIVE_ADDRESS, NativeVar),
store_struct_field(FunP, ?EFT_ARITY, hipe_rtl:mk_imm(Arity-NumFree)),
@@ -845,7 +833,7 @@ gen_free_vars([], _, _, _, AccCode) -> AccCode.
%% call_fun (also handles enter_fun when Continuation = [])
gen_call_fun(Dst, ArgsAndFun, Continuation, Fail) ->
- NAddressReg = hipe_rtl:mk_new_reg(),
+ NCNAddressReg = hipe_rtl:mk_new_reg(),
ArityReg = hipe_rtl:mk_new_reg_gcsafe(),
[Fun|RevArgs] = lists:reverse(ArgsAndFun),
@@ -856,7 +844,7 @@ gen_call_fun(Dst, ArgsAndFun, Continuation, Fail) ->
BadFunLabName = hipe_rtl:label_name(NonClosureLabel),
BadFunCode =
[NonClosureLabel,
- hipe_rtl:mk_call([NAddressReg],
+ hipe_rtl:mk_call([NCNAddressReg],
'nonclosure_address',
[Fun, hipe_rtl:mk_imm(length(Args))],
hipe_rtl:label_name(CallNonClosureLabel),
@@ -865,25 +853,26 @@ gen_call_fun(Dst, ArgsAndFun, Continuation, Fail) ->
CallNonClosureLabel,
case Continuation of
[] ->
- hipe_rtl:mk_enter(NAddressReg, Args, not_remote);
+ hipe_rtl:mk_enter(NCNAddressReg, Args, not_remote);
_ ->
- hipe_rtl:mk_call(Dst, NAddressReg, Args,
+ hipe_rtl:mk_call(Dst, NCNAddressReg, Args,
Continuation, Fail, not_remote)
end],
{BadArityLabName, BadArityCode} = gen_fail_code(Fail, {badarity, Fun}),
- CheckGetCode =
- hipe_tagscheme:if_fun_get_arity_and_address(ArityReg, NAddressReg,
+ CNAddressReg = hipe_rtl:mk_new_reg(),
+ CheckGetCode =
+ hipe_tagscheme:if_fun_get_arity_and_address(ArityReg, CNAddressReg,
Fun, BadFunLabName,
0.9),
CheckArityCode = check_arity(ArityReg, length(RevArgs), BadArityLabName),
CallCode =
case Continuation of
[] -> %% This is a tailcall
- [hipe_rtl:mk_enter(NAddressReg, ArgsAndFun, not_remote)];
+ [hipe_rtl:mk_enter(CNAddressReg, ArgsAndFun, not_remote)];
_ -> %% Ordinary call
- [hipe_rtl:mk_call(Dst, NAddressReg, ArgsAndFun,
+ [hipe_rtl:mk_call(Dst, CNAddressReg, ArgsAndFun,
Continuation, Fail, not_remote)]
end,
[CheckGetCode, CheckArityCode, CallCode, BadFunCode, BadArityCode].
diff --git a/lib/hipe/rtl/hipe_rtl_ssa.erl b/lib/hipe/rtl/hipe_rtl_ssa.erl
index 1e3b21d6be..70f9eeedc9 100644
--- a/lib/hipe/rtl/hipe_rtl_ssa.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssa.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_rtl_ssa.erl
@@ -37,7 +31,7 @@
-include("hipe_rtl.hrl").
-include("../ssa/hipe_ssa.inc").
-
+
%%----------------------------------------------------------------------
%% Auxiliary operations which seriously differ between Icode and RTL.
%%----------------------------------------------------------------------
diff --git a/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl b/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl
index f08ff22ed9..3fbbf6287f 100644
--- a/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_rtl_ssa_avail_expr.erl
diff --git a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
index 7158383010..cad43e2df5 100644
--- a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -110,8 +104,6 @@ visit_expression(Instruction, Environment) ->
visit_alu(Instruction, Environment);
#alub{} ->
visit_alub(Instruction, Environment);
- #branch{} ->
- visit_branch(Instruction, Environment);
#call{} ->
visit_call(Instruction, Environment);
%% #comment{} ->
@@ -184,42 +176,6 @@ set_to(Dst, Val, Env) ->
{[], SSAWork, Env1}.
%%-----------------------------------------------------------------------------
-%% Procedure : visit_branch/2
-%% Purpose : do symbolic exection of branch instructions.
-%% Arguments : Inst - The instruction
-%% Env - The environment
-%% Returns : { FlowWorkList, SSAWorkList, NewEnvironment}
-%%-----------------------------------------------------------------------------
-
-visit_branch(Inst, Env) -> %% Titta också på exekverbarflagga
- Val1 = lookup_lattice_value(hipe_rtl:branch_src1(Inst), Env),
- Val2 = lookup_lattice_value(hipe_rtl:branch_src2(Inst), Env),
- CFGWL = case evaluate_relop(Val1, hipe_rtl:branch_cond(Inst), Val2) of
- true -> [hipe_rtl:branch_true_label(Inst)];
- false -> [hipe_rtl:branch_false_label(Inst)];
- bottom -> [hipe_rtl:branch_true_label(Inst),
- hipe_rtl:branch_false_label(Inst)];
- top -> []
- end,
- {CFGWL, [], Env}.
-
-%%-----------------------------------------------------------------------------
-%% Procedure : evaluate_relop/3
-%% Purpose : evaluate the given relop. While taking care to handle top &
-%% bottom in some sane way.
-%% Arguments : Val1, Val2 - The operands Integers or top or bottom
-%% RelOp - some relop atom from rtl.
-%% Returns : bottom, top, true or false
-%%-----------------------------------------------------------------------------
-
-evaluate_relop(Val1, RelOp, Val2) ->
- if
- (Val1==bottom) or (Val2==bottom) -> bottom ;
- (Val1==top) or (Val2==top) -> top;
- true -> hipe_rtl_arch:eval_cond(RelOp, Val1, Val2)
- end.
-
-%%-----------------------------------------------------------------------------
%% Procedure : evaluate_fixnumop/2
%% Purpose : try to evaluate a fixnumop.
%% Arguments : Val1 - operand (an integer, 'top' or 'bottom')
@@ -408,6 +364,7 @@ partial_eval_branch(Cond, N0, Z0, V0, C0) ->
Cond =:= 'ne' -> {true, Z0, true, true};
Cond =:= 'gt';
Cond =:= 'le' -> {N0, Z0, V0, true};
+ Cond =:= 'leu';
Cond =:= 'gtu' -> {true, Z0, true, C0 };
Cond =:= 'lt';
Cond =:= 'ge' -> {N0, true, V0, true};
@@ -450,7 +407,11 @@ visit_alub(Inst, Env) ->
false -> [hipe_rtl:alub_false_label(Inst)]
end
end,
- {[], NewSSA, NewEnv} = set_to(hipe_rtl:alub_dst(Inst), NewVal, Env),
+ {[], NewSSA, NewEnv} =
+ case hipe_rtl:alub_has_dst(Inst) of
+ false -> {[], [], Env};
+ true -> set_to(hipe_rtl:alub_dst(Inst), NewVal, Env)
+ end,
{Labels, NewSSA, NewEnv}.
%%-----------------------------------------------------------------------------
@@ -688,8 +649,6 @@ update_instruction(Inst, Env) ->
update_alu(Inst, Env);
#alub{} ->
update_alub(Inst, Env);
- #branch{} ->
- update_branch(Inst, Env);
#call{} ->
subst_all_uses(Inst, Env);
%% #comment{} ->
@@ -902,33 +861,6 @@ update_alu(Inst, Env) ->
{Val,_,_,_,_} = evaluate_alu(Val1, hipe_rtl:alu_op(Inst), Val2),
[hipe_rtl:mk_move(hipe_rtl:alu_dst(Inst), hipe_rtl:mk_imm(Val))]
end.
-
-%%-----------------------------------------------------------------------------
-%% Procedure : update_branch/2
-%% Purpose : update an branch-instruction
-%% Arguments : Inst - the instruction.
-%% Env - in which everything happens.
-%% Returns : list of new instruction
-%%-----------------------------------------------------------------------------
-
-update_branch(Inst, Env) ->
- Src1 = hipe_rtl:branch_src1(Inst),
- Src2 = hipe_rtl:branch_src2(Inst),
- Val1 = lookup_lattice_value(Src1, Env),
- Val2 = lookup_lattice_value(Src2, Env),
- if
- (Val1 =:= bottom) and (Val2 =:= bottom) ->
- [Inst];
- Val1 =:= bottom ->
- [hipe_rtl:subst_uses([{Src2, hipe_rtl:mk_imm(Val2)}], Inst)];
- Val2 =:= bottom ->
- [hipe_rtl:subst_uses([{Src1, hipe_rtl:mk_imm(Val1)}], Inst)];
- true ->
- case hipe_rtl_arch:eval_cond(hipe_rtl:branch_cond(Inst), Val1, Val2) of
- true -> [hipe_rtl:mk_goto(hipe_rtl:branch_true_label(Inst))];
- false -> [hipe_rtl:mk_goto(hipe_rtl:branch_false_label(Inst))]
- end
- end.
%%-----------------------------------------------------------------------------
%% Procedure : update_alub/2
@@ -943,8 +875,12 @@ update_branch(Inst, Env) ->
%% some small helpers.
alub_to_move(Inst, Res, Lab) ->
- [hipe_rtl:mk_move(hipe_rtl:alub_dst(Inst), Res),
- hipe_rtl:mk_goto(Lab)].
+ Goto = [hipe_rtl:mk_goto(Lab)],
+ case hipe_rtl:alub_has_dst(Inst) of
+ false -> Goto;
+ true ->
+ [hipe_rtl:mk_move(hipe_rtl:alub_dst(Inst), Res) | Goto]
+ end.
make_alub_subst_list(bottom, _, Tail) -> Tail;
make_alub_subst_list(top, Src, _) ->
diff --git a/lib/hipe/rtl/hipe_rtl_ssapre.erl b/lib/hipe/rtl/hipe_rtl_ssapre.erl
index df1a4b9376..eacaa28196 100644
--- a/lib/hipe/rtl/hipe_rtl_ssapre.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssapre.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% File : hipe_rtl_ssapre.erl
diff --git a/lib/hipe/rtl/hipe_rtl_symbolic.erl b/lib/hipe/rtl/hipe_rtl_symbolic.erl
index 1d7e0ec55e..8ca307952b 100644
--- a/lib/hipe/rtl/hipe_rtl_symbolic.erl
+++ b/lib/hipe/rtl/hipe_rtl_symbolic.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-------------------------------------------------------------------
%% File : hipe_rtl_symbolic.erl
diff --git a/lib/hipe/rtl/hipe_rtl_varmap.erl b/lib/hipe/rtl/hipe_rtl_varmap.erl
index 31165d91a4..375a8f85c0 100644
--- a/lib/hipe/rtl/hipe_rtl_varmap.erl
+++ b/lib/hipe/rtl/hipe_rtl_varmap.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,12 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
-%% Time-stamp: <2008-04-20 14:55:35 richard>
%% ====================================================================
%% Module : hipe_rtl_varmap
%% Purpose :
diff --git a/lib/hipe/rtl/hipe_tagscheme.erl b/lib/hipe/rtl/hipe_tagscheme.erl
index 8825a3ade3..68cbe75e85 100644
--- a/lib/hipe/rtl/hipe_tagscheme.erl
+++ b/lib/hipe/rtl/hipe_tagscheme.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%========================================================================
%%
@@ -25,9 +19,6 @@
%%
%% Modifications:
%% 020904: Happi - added support for external pids and ports.
-%%
-%%========================================================================
-%% $Id$
%%========================================================================
-module(hipe_tagscheme).
@@ -49,6 +40,7 @@
fixnum_gt/5, fixnum_lt/5, fixnum_ge/5, fixnum_le/5, fixnum_val/1,
fixnum_mul/4, fixnum_addsub/5, fixnum_andorxor/4, fixnum_not/2,
fixnum_bsr/3, fixnum_bsl/3]).
+-export([test_either_immed/4]).
-export([unsafe_car/2, unsafe_cdr/2,
unsafe_constant_element/3, unsafe_update_element/3, element/6]).
-export([unsafe_closure_element/3]).
@@ -68,9 +60,7 @@
-include("hipe_rtl.hrl").
-include("hipe_literals.hrl").
--ifdef(EFT_NATIVE_ADDRESS).
-export([if_fun_get_arity_and_address/5]).
--endif.
-undef(TAG_PRIMARY_BOXED).
-undef(TAG_IMMED2_MASK).
@@ -173,22 +163,21 @@ test_nil(X, TrueLab, FalseLab, Pred) ->
hipe_rtl:mk_branch(X, eq, hipe_rtl:mk_imm(?NIL), TrueLab, FalseLab, Pred).
test_cons(X, TrueLab, FalseLab, Pred) ->
- Tmp = hipe_rtl:mk_new_reg_gcsafe(),
Mask = hipe_rtl:mk_imm(?TAG_PRIMARY_MASK - ?TAG_PRIMARY_LIST),
- hipe_rtl:mk_alub(Tmp, X, 'and', Mask, 'eq', TrueLab, FalseLab, Pred).
+ hipe_rtl:mk_branch(X, 'and', Mask, 'eq', TrueLab, FalseLab, Pred).
test_is_boxed(X, TrueLab, FalseLab, Pred) ->
- Tmp = hipe_rtl:mk_new_reg_gcsafe(),
Mask = hipe_rtl:mk_imm(?TAG_PRIMARY_MASK - ?TAG_PRIMARY_BOXED),
- hipe_rtl:mk_alub(Tmp, X, 'and', Mask, 'eq', TrueLab, FalseLab, Pred).
+ hipe_rtl:mk_branch(X, 'and', Mask, 'eq', TrueLab, FalseLab, Pred).
get_header(Res, X) ->
hipe_rtl:mk_load(Res, X, hipe_rtl:mk_imm(-(?TAG_PRIMARY_BOXED))).
mask_and_compare(X, Mask, Value, TrueLab, FalseLab, Pred) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
- [hipe_rtl:mk_alu(Tmp, X, 'and', hipe_rtl:mk_imm(Mask)),
- hipe_rtl:mk_branch(Tmp, 'eq', hipe_rtl:mk_imm(Value), TrueLab, FalseLab, Pred)].
+ [hipe_rtl:mk_alu(Tmp, X, 'sub', hipe_rtl:mk_imm(Value)),
+ hipe_rtl:mk_branch(Tmp, 'and', hipe_rtl:mk_imm(Mask),
+ eq, TrueLab, FalseLab, Pred)].
test_immed1(X, Value, TrueLab, FalseLab, Pred) ->
mask_and_compare(X, ?TAG_IMMED1_MASK, Value, TrueLab, FalseLab, Pred).
@@ -240,13 +229,12 @@ test_atom(X, TrueLab, FalseLab, Pred) ->
test_tuple(X, TrueLab, FalseLab, Pred) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
- Tmp2 = hipe_rtl:mk_new_reg_gcsafe(),
HalfTrueLab = hipe_rtl:mk_new_label(),
[test_is_boxed(X, hipe_rtl:label_name(HalfTrueLab), FalseLab, Pred),
HalfTrueLab,
get_header(Tmp, X),
- hipe_rtl:mk_alub(Tmp2, Tmp, 'and', hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
- TrueLab, FalseLab, Pred)].
+ hipe_rtl:mk_branch(Tmp, 'and', hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
+ TrueLab, FalseLab, Pred)].
test_tuple_N(X, N, TrueLab, FalseLab, Pred) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
@@ -282,7 +270,6 @@ test_ref(X, TrueLab, FalseLab, Pred) ->
TrueLab, FalseLab, Pred)
].
--ifdef(EFT_NATIVE_ADDRESS).
test_closure(X, TrueLab, FalseLab, Pred) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
HalfTrueLab = hipe_rtl:mk_new_label(),
@@ -291,7 +278,6 @@ test_closure(X, TrueLab, FalseLab, Pred) ->
get_header(Tmp, X),
mask_and_compare(Tmp, ?TAG_HEADER_MASK, ?TAG_HEADER_FUN,
TrueLab, FalseLab, Pred)].
--endif.
test_fun(X, TrueLab, FalseLab, Pred) ->
Hdr = hipe_rtl:mk_new_reg_gcsafe(),
@@ -378,14 +364,17 @@ test_matchstate(X, TrueLab, FalseLab, Pred) ->
mask_and_compare(Tmp, ?TAG_HEADER_MASK, ?TAG_HEADER_BIN_MATCHSTATE,
TrueLab, FalseLab, Pred)].
+test_bitstr_header(HdrTmp, TrueLab, FalseLab, Pred) ->
+ Mask = ?TAG_HEADER_MASK - ?BINARY_XXX_MASK,
+ mask_and_compare(HdrTmp, Mask, ?TAG_HEADER_REFC_BIN, TrueLab, FalseLab, Pred).
+
test_bitstr(X, TrueLab, FalseLab, Pred) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
HalfTrueLab = hipe_rtl:mk_new_label(),
- Mask = ?TAG_HEADER_MASK - ?BINARY_XXX_MASK,
[test_is_boxed(X, hipe_rtl:label_name(HalfTrueLab), FalseLab, Pred),
HalfTrueLab,
get_header(Tmp, X),
- mask_and_compare(Tmp, Mask, ?TAG_HEADER_REFC_BIN, TrueLab, FalseLab, Pred)].
+ test_bitstr_header(Tmp, TrueLab, FalseLab, Pred)].
test_binary(X, TrueLab, FalseLab, Pred) ->
Tmp1 = hipe_rtl:mk_new_reg_gcsafe(),
@@ -393,12 +382,10 @@ test_binary(X, TrueLab, FalseLab, Pred) ->
IsBoxedLab = hipe_rtl:mk_new_label(),
IsBitStrLab = hipe_rtl:mk_new_label(),
IsSubBinLab = hipe_rtl:mk_new_label(),
- Mask = ?TAG_HEADER_MASK - ?BINARY_XXX_MASK,
[test_is_boxed(X, hipe_rtl:label_name(IsBoxedLab), FalseLab, Pred),
IsBoxedLab,
get_header(Tmp1, X),
- mask_and_compare(Tmp1, Mask, ?TAG_HEADER_REFC_BIN,
- hipe_rtl:label_name(IsBitStrLab), FalseLab, Pred),
+ test_bitstr_header(Tmp1, hipe_rtl:label_name(IsBitStrLab), FalseLab, Pred),
IsBitStrLab,
mask_and_compare(Tmp1, ?TAG_HEADER_MASK, ?TAG_HEADER_SUB_BIN,
hipe_rtl:label_name(IsSubBinLab), TrueLab, 0.5),
@@ -468,14 +455,23 @@ test_fixnums_1([Arg1, Arg2|Args], Acc) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
test_fixnums_1([Tmp|Args], [hipe_rtl:mk_alu(Tmp, Arg1, 'and', Arg2)|Acc]).
+test_two_fixnums(Arg, Arg, FalseLab) ->
+ TrueLab = hipe_rtl:mk_new_label(),
+ [test_fixnum(Arg, hipe_rtl:label_name(TrueLab), FalseLab, 0.99),
+ TrueLab];
test_two_fixnums(Arg1, Arg2, FalseLab) ->
TrueLab = hipe_rtl:mk_new_label(),
- case hipe_rtl:is_imm(Arg2) of
+ case hipe_rtl:is_imm(Arg1) orelse hipe_rtl:is_imm(Arg2) of
true ->
- Value = hipe_rtl:imm_value(Arg2),
+ {Imm, Var} =
+ case hipe_rtl:is_imm(Arg1) of
+ true -> {Arg1, Arg2};
+ false -> {Arg2, Arg1}
+ end,
+ Value = hipe_rtl:imm_value(Imm),
case Value band ?TAG_IMMED1_MASK of
?TAG_IMMED1_SMALL ->
- [test_fixnum(Arg1, hipe_rtl:label_name(TrueLab), FalseLab, 0.99),
+ [test_fixnum(Var, hipe_rtl:label_name(TrueLab), FalseLab, 0.99),
TrueLab];
_ ->
[hipe_rtl:mk_goto(FalseLab)]
@@ -516,28 +512,48 @@ unsafe_fixnum_sub(Arg1, Arg2, Res) ->
%%% (16X+tag)+((16Y+tag)-tag) = 16X+tag+16Y = 16(X+Y)+tag
%%% (16X+tag)-((16Y+tag)-tag) = 16X+tag-16Y = 16(X-Y)+tag
-fixnum_addsub(AluOp, Arg1, Arg2, Res, OtherLab) ->
- Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+fixnum_addsub(AluOp, Arg1, Arg2, FinalRes, OtherLab) ->
+ NoOverflowLab = hipe_rtl:mk_new_label(),
%% XXX: Consider moving this test to the users of fixnum_addsub.
- case Arg1 =/= Res andalso Arg2 =/= Res of
- true ->
- %% Args differ from res.
- NoOverflowLab = hipe_rtl:mk_new_label(),
- [hipe_rtl:mk_alu(Tmp, Arg2, sub, hipe_rtl:mk_imm(?TAG_IMMED1_SMALL)),
- hipe_rtl:mk_alub(Res, Arg1, AluOp, Tmp, not_overflow,
- hipe_rtl:label_name(NoOverflowLab),
- hipe_rtl:label_name(OtherLab), 0.99),
- NoOverflowLab];
+ {Res, Tail} =
+ case Arg1 =/= FinalRes andalso Arg2 =/= FinalRes of
+ true ->
+ %% Args differ from res.
+ {FinalRes, [NoOverflowLab]};
+ false ->
+ %% At least one of the arguments is the same as Res.
+ Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+ {Tmp, [NoOverflowLab, hipe_rtl:mk_move(FinalRes, Tmp)]}
+ end,
+ case (hipe_rtl:is_imm(Arg1) andalso AluOp =:= 'add')
+ orelse hipe_rtl:is_imm(Arg2)
+ of
+ true ->
+ %% Pre-compute the untagged immediate. The optimisers won't do this for us
+ %% since they don't know that the untag never underflows.
+ {Var, Imm0} =
+ case hipe_rtl:is_imm(Arg2) of
+ true -> {Arg1, Arg2};
+ false -> {Arg2, Arg1}
+ end,
+ Imm = hipe_rtl:mk_imm(hipe_rtl:imm_value(Imm0) - ?TAG_IMMED1_SMALL),
+ [hipe_rtl:mk_alub(Res, Var, AluOp, Imm, not_overflow,
+ hipe_rtl:label_name(NoOverflowLab),
+ hipe_rtl:label_name(OtherLab), 0.99)
+ |Tail];
false ->
- %% At least one of the arguments is the same as Res.
- Tmp2 = hipe_rtl:mk_new_var(), % XXX: shouldn't this var be a reg?
- NoOverflowLab = hipe_rtl:mk_new_label(),
- [hipe_rtl:mk_alu(Tmp, Arg2, sub, hipe_rtl:mk_imm(?TAG_IMMED1_SMALL)),
- hipe_rtl:mk_alub(Tmp2, Arg1, AluOp, Tmp, not_overflow,
+ %% Commute add to save a move on x86
+ {UntagFirst, Lhs, Rhs} =
+ case AluOp of
+ 'add' -> {Arg1, Res, Arg2};
+ 'sub' -> {Arg2, Arg1, Res}
+ end,
+ [hipe_rtl:mk_alu(Res, UntagFirst, sub,
+ hipe_rtl:mk_imm(?TAG_IMMED1_SMALL)),
+ hipe_rtl:mk_alub(Res, Lhs, AluOp, Rhs, not_overflow,
hipe_rtl:label_name(NoOverflowLab),
- hipe_rtl:label_name(OtherLab), 0.99),
- NoOverflowLab,
- hipe_rtl:mk_move(Res, Tmp2)]
+ hipe_rtl:label_name(OtherLab), 0.99)
+ |Tail]
end.
%%% ((16X+tag) div 16) * ((16Y+tag)-tag) + tag = X*16Y+tag = 16(XY)+tag
@@ -557,8 +573,8 @@ fixnum_andorxor(AluOp, Arg1, Arg2, Res) ->
case AluOp of
'xor' ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
- [hipe_rtl:mk_alu(Tmp, Arg1, 'xor', Arg2), % clears tag :-(
- hipe_rtl:mk_alu(Res, Tmp, 'or', hipe_rtl:mk_imm(?TAG_IMMED1_SMALL))];
+ [hipe_rtl:mk_alu(Tmp, Arg1, 'sub', hipe_rtl:mk_imm(?TAG_IMMED1_SMALL)),
+ hipe_rtl:mk_alu(Res, Tmp, 'xor', Arg2)];
_ -> hipe_rtl:mk_alu(Res, Arg1, AluOp, Arg2)
end.
@@ -585,6 +601,21 @@ fixnum_bsl(Arg1, Arg2, Res) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Test if either of two values are immediate (primary tag IMMED1, 0x3)
+test_either_immed(Arg1, Arg2, TrueLab, FalseLab) ->
+ %% This test assumes primary tag 0x0 is reserved and immed has tag 0x3
+ 16#0 = ?TAG_PRIMARY_HEADER,
+ 16#3 = ?TAG_PRIMARY_IMMED1,
+ Tmp1 = hipe_rtl:mk_new_reg_gcsafe(),
+ Tmp2 = hipe_rtl:mk_new_reg_gcsafe(),
+ [hipe_rtl:mk_alu(Tmp1, Arg1, 'sub', hipe_rtl:mk_imm(1)),
+ hipe_rtl:mk_alu(Tmp2, Arg2, 'sub', hipe_rtl:mk_imm(1)),
+ hipe_rtl:mk_alu(Tmp2, Tmp2, 'or', Tmp1),
+ hipe_rtl:mk_branch(Tmp2, 'and', hipe_rtl:mk_imm(2), eq,
+ FalseLab, TrueLab, 0.01)].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
unsafe_car(Dst, Arg) ->
hipe_rtl:mk_load(Dst, Arg, hipe_rtl:mk_imm(-(?TAG_PRIMARY_LIST))).
@@ -621,14 +652,13 @@ unsafe_update_element(Tuple, Index, Value) -> % Index is an immediate
element(Dst, Index, Tuple, FailLabName, {tuple, A}, IndexInfo) ->
FixnumOkLab = hipe_rtl:mk_new_label(),
IndexOkLab = hipe_rtl:mk_new_label(),
- Ptr = hipe_rtl:mk_new_reg(), % offset from Tuple
UIndex = hipe_rtl:mk_new_reg_gcsafe(),
Arity = hipe_rtl:mk_imm(A),
- InvIndex = hipe_rtl:mk_new_reg_gcsafe(),
- Offset = hipe_rtl:mk_new_reg_gcsafe(),
case IndexInfo of
valid ->
%% This is no branch, 1 load and 3 alus = 4 instr
+ Offset = hipe_rtl:mk_new_reg_gcsafe(),
+ Ptr = hipe_rtl:mk_new_reg(), % offset from Tuple
[untag_fixnum(UIndex, Index),
hipe_rtl:mk_alu(Ptr, Tuple, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED)),
hipe_rtl:mk_alu(Offset, UIndex, 'sll',
@@ -637,97 +667,78 @@ element(Dst, Index, Tuple, FailLabName, {tuple, A}, IndexInfo) ->
fixnums ->
%% This is 1 branch, 1 load and 4 alus = 6 instr
[untag_fixnum(UIndex, Index),
- hipe_rtl:mk_alu(Ptr, Tuple, 'sub',hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED))|
- gen_element_tail(Dst, Ptr, InvIndex, Arity, Offset, UIndex,
- FailLabName, IndexOkLab)];
+ gen_element_tail(Dst, Tuple, Arity, UIndex, FailLabName, IndexOkLab)];
_ ->
%% This is 3 branches, 1 load and 5 alus = 9 instr
[test_fixnum(Index, hipe_rtl:label_name(FixnumOkLab),
FailLabName, 0.99),
FixnumOkLab,
untag_fixnum(UIndex, Index),
- hipe_rtl:mk_alu(Ptr, Tuple, 'sub',hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED))|
- gen_element_tail(Dst, Ptr, InvIndex, Arity, Offset, UIndex,
- FailLabName, IndexOkLab)]
+ gen_element_tail(Dst, Tuple, Arity, UIndex, FailLabName, IndexOkLab)]
end;
element(Dst, Index, Tuple, FailLabName, tuple, IndexInfo) ->
FixnumOkLab = hipe_rtl:mk_new_label(),
IndexOkLab = hipe_rtl:mk_new_label(),
- Ptr = hipe_rtl:mk_new_reg(), % offset from Tuple
Header = hipe_rtl:mk_new_reg_gcsafe(),
UIndex = hipe_rtl:mk_new_reg_gcsafe(),
Arity = hipe_rtl:mk_new_reg_gcsafe(),
- InvIndex = hipe_rtl:mk_new_reg_gcsafe(),
- Offset = hipe_rtl:mk_new_reg_gcsafe(),
case IndexInfo of
fixnums ->
%% This is 1 branch, 2 loads and 5 alus = 8 instr
- [hipe_rtl:mk_alu(Ptr, Tuple, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED)),
- hipe_rtl:mk_load(Header, Ptr, hipe_rtl:mk_imm(0)),
+ [get_header(Header, Tuple),
untag_fixnum(UIndex, Index),
hipe_rtl:mk_alu(Arity,Header,'srl',hipe_rtl:mk_imm(?HEADER_ARITY_OFFS))|
- gen_element_tail(Dst, Ptr, InvIndex, Arity, Offset, UIndex,
- FailLabName, IndexOkLab)];
+ gen_element_tail(Dst, Tuple, Arity, UIndex, FailLabName, IndexOkLab)];
Num when is_integer(Num) ->
%% This is 1 branch, 1 load and 3 alus = 5 instr
- [hipe_rtl:mk_alu(Ptr, Tuple, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED))|
- gen_element_tail(Dst, Ptr, InvIndex, hipe_rtl:mk_imm(Num),
- Offset, UIndex, FailLabName, IndexOkLab)];
+ gen_element_tail(Dst, Tuple, hipe_rtl:mk_imm(Num), UIndex, FailLabName,
+ IndexOkLab);
_ ->
%% This is 2 branches, 2 loads and 6 alus = 10 instr
[test_fixnum(Index, hipe_rtl:label_name(FixnumOkLab), FailLabName, 0.99),
FixnumOkLab,
- hipe_rtl:mk_alu(Ptr, Tuple, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED)),
- hipe_rtl:mk_load(Header, Ptr, hipe_rtl:mk_imm(0)),
+ get_header(Header, Tuple),
untag_fixnum(UIndex, Index),
hipe_rtl:mk_alu(Arity,Header,'srl',hipe_rtl:mk_imm(?HEADER_ARITY_OFFS))|
- gen_element_tail(Dst, Ptr, InvIndex, Arity, Offset, UIndex,
- FailLabName, IndexOkLab)]
+ gen_element_tail(Dst, Tuple, Arity, UIndex, FailLabName, IndexOkLab)]
end;
element(Dst, Index, Tuple, FailLabName, unknown, IndexInfo) ->
FixnumOkLab = hipe_rtl:mk_new_label(),
BoxedOkLab = hipe_rtl:mk_new_label(),
TupleOkLab = hipe_rtl:mk_new_label(),
IndexOkLab = hipe_rtl:mk_new_label(),
- Ptr = hipe_rtl:mk_new_reg(), % offset from Tuple
Header = hipe_rtl:mk_new_reg_gcsafe(),
- Tmp = hipe_rtl:mk_new_reg_gcsafe(),
UIndex = hipe_rtl:mk_new_reg_gcsafe(),
Arity = hipe_rtl:mk_new_reg_gcsafe(),
- InvIndex = hipe_rtl:mk_new_reg_gcsafe(),
- Offset = hipe_rtl:mk_new_reg_gcsafe(),
case IndexInfo of
fixnums ->
%% This is 3 branches, 2 loads and 5 alus = 10 instr
[test_is_boxed(Tuple, hipe_rtl:label_name(BoxedOkLab),
FailLabName, 0.99),
BoxedOkLab,
- hipe_rtl:mk_alu(Ptr, Tuple, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED)),
- hipe_rtl:mk_load(Header, Ptr, hipe_rtl:mk_imm(0)),
- hipe_rtl:mk_alub(Tmp, Header, 'and',
- hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
- hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
+ get_header(Header, Tuple),
+ hipe_rtl:mk_branch(Header, 'and',
+ hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
+ hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
TupleOkLab,
untag_fixnum(UIndex, Index),
hipe_rtl:mk_alu(Arity, Header, 'srl',
hipe_rtl:mk_imm(?HEADER_ARITY_OFFS))|
- gen_element_tail(Dst, Ptr, InvIndex, Arity, Offset,
- UIndex, FailLabName, IndexOkLab)];
+ gen_element_tail(Dst, Tuple, Arity, UIndex, FailLabName, IndexOkLab)];
Num when is_integer(Num) ->
%% This is 3 branches, 2 loads and 4 alus = 9 instr
[test_is_boxed(Tuple, hipe_rtl:label_name(BoxedOkLab),
FailLabName, 0.99),
BoxedOkLab,
- hipe_rtl:mk_alu(Ptr, Tuple, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED)),
- hipe_rtl:mk_load(Header, Ptr, hipe_rtl:mk_imm(0)),
- hipe_rtl:mk_alub(Tmp, Header, 'and',
- hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
- hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
+ get_header(Header, Tuple),
+ hipe_rtl:mk_branch(Header, 'and',
+ hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
+ hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
TupleOkLab,
hipe_rtl:mk_alu(Arity, Header, 'srl',
hipe_rtl:mk_imm(?HEADER_ARITY_OFFS))|
- gen_element_tail(Dst, Ptr, InvIndex, Arity, Offset,
- hipe_rtl:mk_imm(Num), FailLabName, IndexOkLab)];
+ gen_element_tail(Dst, Tuple, Arity, hipe_rtl:mk_imm(Num), FailLabName,
+ IndexOkLab)];
_ ->
%% This is 4 branches, 2 loads, and 6 alus = 12 instr :(
[test_fixnum(Index, hipe_rtl:label_name(FixnumOkLab),
@@ -736,29 +747,29 @@ element(Dst, Index, Tuple, FailLabName, unknown, IndexInfo) ->
test_is_boxed(Tuple, hipe_rtl:label_name(BoxedOkLab),
FailLabName, 0.99),
BoxedOkLab,
- hipe_rtl:mk_alu(Ptr, Tuple, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED)),
- hipe_rtl:mk_load(Header, Ptr, hipe_rtl:mk_imm(0)),
- hipe_rtl:mk_alub(Tmp, Header, 'and',
- hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
- hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
+ get_header(Header, Tuple),
+ hipe_rtl:mk_branch(Header, 'and',
+ hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
+ hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
TupleOkLab,
untag_fixnum(UIndex, Index),
hipe_rtl:mk_alu(Arity, Header, 'srl',
hipe_rtl:mk_imm(?HEADER_ARITY_OFFS))|
- gen_element_tail(Dst, Ptr, InvIndex, Arity, Offset,
- UIndex, FailLabName, IndexOkLab)]
+ gen_element_tail(Dst, Tuple, Arity, UIndex, FailLabName, IndexOkLab)]
end.
-gen_element_tail(Dst, Ptr, InvIndex, Arity, Offset,
- UIndex, FailLabName, IndexOkLab) ->
+gen_element_tail(Dst, Tuple, Arity, UIndex, FailLabName, IndexOkLab) ->
+ ZeroIndex = hipe_rtl:mk_new_reg_gcsafe(),
+ Offset = hipe_rtl:mk_new_reg_gcsafe(),
+ Ptr = hipe_rtl:mk_new_reg(), % offset from Tuple
%% now check that 1 <= UIndex <= Arity
- %% if UIndex < 1, then (Arity - UIndex) >= Arity
- %% if UIndex > Arity, then (Arity - UIndex) < 0, which is >=u Arity
- %% otherwise, 0 <= (Arity - UIndex) < Arity
- [hipe_rtl:mk_alu(InvIndex, Arity, 'sub', UIndex),
- hipe_rtl:mk_branch(InvIndex, 'geu', Arity, FailLabName,
+ %% by checking the equivalent (except for when Arity>=2^(WordSize-1))
+ %% (UIndex - 1) <u Arity
+ [hipe_rtl:mk_alu(ZeroIndex, UIndex, 'sub', hipe_rtl:mk_imm(1)),
+ hipe_rtl:mk_branch(ZeroIndex, 'geu', Arity, FailLabName,
hipe_rtl:label_name(IndexOkLab), 0.01),
IndexOkLab,
+ hipe_rtl:mk_alu(Ptr, Tuple, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED)),
hipe_rtl:mk_alu(Offset, UIndex, 'sll',
hipe_rtl:mk_imm(hipe_rtl_arch:log2_word_size())),
hipe_rtl:mk_load(Dst, Ptr, Offset)].
@@ -781,10 +792,9 @@ tag_fun(Res, X) ->
%% untag_fun(Res, X) ->
%% hipe_rtl:mk_alu(Res, X, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED)).
--ifdef(EFT_NATIVE_ADDRESS).
if_fun_get_arity_and_address(ArityReg, AddressReg, FunP, BadFunLab, Pred) ->
%% EmuAddressPtrReg = hipe_rtl:mk_new_reg(),
- %% FEPtrReg = hipe_rtl:mk_new_reg(),
+ FEPtrReg = hipe_rtl:mk_new_reg(),
%% ArityReg = hipe_rtl:mk_new_reg(),
%% NumFreeReg = hipe_rtl:mk_new_reg(),
%% RealArityReg = hipe_rtl:mk_new_reg(),
@@ -797,11 +807,12 @@ if_fun_get_arity_and_address(ArityReg, AddressReg, FunP, BadFunLab, Pred) ->
hipe_rtl:mk_load(ArityReg, FunP,
hipe_rtl:mk_imm(-(?TAG_PRIMARY_BOXED)+
?EFT_ARITY)),
- hipe_rtl:mk_load(AddressReg, FunP,
+ hipe_rtl:mk_load(FEPtrReg, FunP,
hipe_rtl:mk_imm(-(?TAG_PRIMARY_BOXED)+
- ?EFT_NATIVE_ADDRESS))],
+ ?EFT_FE)),
+ hipe_rtl:mk_load(AddressReg, FEPtrReg,
+ hipe_rtl:mk_imm(?EFE_NATIVE_ADDRESS))],
IsFunCode ++ GetArityCode.
--endif.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -874,12 +885,10 @@ heap_arch_spec(HP) ->
hipe_rtl_arch:pcb_store(?P_OFF_HEAP_FIRST, HP)].
test_heap_binary(Binary, TrueLblName, FalseLblName) ->
- Tmp1 = hipe_rtl:mk_new_reg_gcsafe(),
- Tmp2 = hipe_rtl:mk_new_reg_gcsafe(),
- [get_header(Tmp1, Binary),
- hipe_rtl:mk_alu(Tmp2, Tmp1, 'and', hipe_rtl:mk_imm(?TAG_HEADER_MASK)),
- hipe_rtl:mk_branch(Tmp2, eq, hipe_rtl:mk_imm(?TAG_HEADER_HEAP_BIN),
- TrueLblName, FalseLblName)].
+ Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+ [get_header(Tmp, Binary),
+ mask_and_compare(Tmp, ?TAG_HEADER_MASK, ?TAG_HEADER_HEAP_BIN,
+ TrueLblName, FalseLblName, 0.5)].
mk_sub_binary(Dst, ByteSize, ByteOffs, BitSize, BitOffs, Orig) ->
mk_sub_binary(Dst, ByteSize, ByteOffs, BitSize, BitOffs,
@@ -907,11 +916,10 @@ build_sub_binary(Dst, ByteSize, ByteOffs, BitSize, BitOffs,
set_field_from_term({sub_binary, orig}, Dst, Orig)].
test_subbinary(Binary, TrueLblName, FalseLblName) ->
- Tmp1 = hipe_rtl:mk_new_reg_gcsafe(),
- Tmp2 = hipe_rtl:mk_new_reg_gcsafe(),
- [get_header(Tmp1, Binary),
- hipe_rtl:mk_alu(Tmp2, Tmp1, 'and', hipe_rtl:mk_imm(?TAG_HEADER_MASK)),
- hipe_rtl:mk_branch(Tmp2, eq, hipe_rtl:mk_imm(?TAG_HEADER_SUB_BIN), TrueLblName, FalseLblName)].
+ Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+ [get_header(Tmp, Binary),
+ mask_and_compare(Tmp, ?TAG_HEADER_MASK, ?TAG_HEADER_SUB_BIN,
+ TrueLblName, FalseLblName, 0.5)].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/sparc/Makefile b/lib/hipe/sparc/Makefile
index 0e36a43d8e..ac1230df7c 100644
--- a/lib/hipe/sparc/Makefile
+++ b/lib/hipe/sparc/Makefile
@@ -63,7 +63,8 @@ MODULES=hipe_rtl_to_sparc \
hipe_sparc_ra_naive \
hipe_sparc_ra_postconditions \
hipe_sparc_ra_postconditions_fp \
- hipe_sparc_registers
+ hipe_sparc_registers \
+ hipe_sparc_subst
HRL_FILES=hipe_sparc.hrl
ERL_FILES=$(MODULES:%=%.erl)
diff --git a/lib/hipe/sparc/hipe_rtl_to_sparc.erl b/lib/hipe/sparc/hipe_rtl_to_sparc.erl
index eef5ba8d96..d1a6b15508 100644
--- a/lib/hipe/sparc/hipe_rtl_to_sparc.erl
+++ b/lib/hipe/sparc/hipe_rtl_to_sparc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_rtl_to_sparc).
@@ -63,7 +56,6 @@ conv_insn(I, Map, Data) ->
case I of
#alu{} -> conv_alu(I, Map, Data);
#alub{} -> conv_alub(I, Map, Data);
- #branch{} -> conv_branch(I, Map, Data);
#call{} -> conv_call(I, Map, Data);
#comment{} -> conv_comment(I, Map, Data);
#enter{} -> conv_enter(I, Map, Data);
@@ -281,7 +273,12 @@ mk_alu_rs(XAluOp, Src1, Src2, Dst) ->
conv_alub(I, Map, Data) ->
%% dst = src1 aluop src2; if COND goto label
- {Dst, Map0} = conv_dst(hipe_rtl:alub_dst(I), Map),
+ HasDst = hipe_rtl:alub_has_dst(I),
+ {Dst, Map0} =
+ case HasDst of
+ false -> {hipe_sparc:mk_g0(), Map};
+ true -> conv_dst(hipe_rtl:alub_dst(I), Map)
+ end,
{Src1, Map1} = conv_src(hipe_rtl:alub_src1(I), Map0),
{Src2, Map2} = conv_src(hipe_rtl:alub_src2(I), Map1),
Cond = conv_cond(hipe_rtl:alub_cond(I)),
@@ -307,67 +304,33 @@ conv_alub(I, Map, Data) ->
I1 ++
[hipe_sparc:mk_rdy(TmpHi),
hipe_sparc:mk_alu('sra', Dst, hipe_sparc:mk_uimm5(31), TmpSign) |
- conv_alub2(G0, TmpSign, 'sub', NewCond, TmpHi, I)];
+ conv_alub2(G0, TmpSign, 'cmpcc', NewCond, TmpHi, I)];
_ ->
- conv_alub2(Dst, Src1, RtlAlubOp, Cond, Src2, I)
+ XAluOp =
+ case (not HasDst) andalso RtlAlubOp =:= 'sub' of
+ true -> 'cmpcc'; % == a subcc that commutes
+ false -> conv_alubop_cc(RtlAlubOp)
+ end,
+ conv_alub2(Dst, Src1, XAluOp, Cond, Src2, I)
end,
{I2, Map2, Data}.
--ifdef(notdef). % XXX: only for sparc64, alas
-conv_alub2(Dst, Src1, RtlAlubOp, Cond, Src2, I) ->
- case conv_cond_rcond(Cond) of
- [] ->
- conv_alub_bp(Dst, Src1, RtlAlubOp, Cond, Src2, I);
- RCond ->
- conv_alub_br(Dst, Src1, RtlAlubOp, RCond, Src2, I)
- end.
+conv_alub2(Dst, Src1, XAluOp, Cond, Src2, I) ->
+ conv_alub_bp(Dst, Src1, XAluOp, Cond, Src2, I).
-conv_alub_br(Dst, Src1, RtlAlubOp, RCond, Src2, I) ->
- TrueLab = hipe_rtl:alub_true_label(I),
- FalseLab = hipe_rtl:alub_false_label(I),
- Pred = hipe_rtl:alub_pred(I),
- %% "Dst = Src1 AluOp Src2; if COND" becomes
- %% "Dst = Src1 AluOp Src2; if-COND(Dst)"
- {I2, _DidCommute} = mk_alu(conv_alubop_nocc(RtlAlubOp), Src1, Src2, Dst),
- I2 ++ mk_pseudo_br(RCond, Dst, TrueLab, FalseLab, Pred).
-
-conv_cond_rcond(Cond) ->
- case Cond of
- 'e' -> 'z';
- 'ne' -> 'nz';
- 'g' -> 'gz';
- 'ge' -> 'gez';
- 'l' -> 'lz';
- 'le' -> 'lez';
- _ -> [] % vs, vc, gu, geu, lu, leu
- end.
-
-conv_alubop_nocc(RtlAlubOp) ->
- case RtlAlubOp of
- 'add' -> 'add';
- 'sub' -> 'sub';
- %% mul: handled elsewhere
- 'or' -> 'or';
- 'and' -> 'and';
- 'xor' -> 'xor'
- %% no shift ops
- end.
-
-mk_pseudo_br(RCond, Dst, TrueLab, FalseLab, Pred) ->
- [hipe_sparc:mk_pseudo_br(RCond, Dst, TrueLab, FalseLab, Pred)].
--else.
-conv_alub2(Dst, Src1, RtlAlubOp, Cond, Src2, I) ->
- conv_alub_bp(Dst, Src1, RtlAlubOp, Cond, Src2, I).
--endif.
-
-conv_alub_bp(Dst, Src1, RtlAlubOp, Cond, Src2, I) ->
+conv_alub_bp(Dst, Src1, XAluOp, Cond, Src2, I) ->
TrueLab = hipe_rtl:alub_true_label(I),
FalseLab = hipe_rtl:alub_false_label(I),
Pred = hipe_rtl:alub_pred(I),
%% "Dst = Src1 AluOp Src2; if COND" becomes
%% "Dst = Src1 AluOpCC Src22; if-COND(CC)"
- {I2, _DidCommute} = mk_alu(conv_alubop_cc(RtlAlubOp), Src1, Src2, Dst),
- I2 ++ mk_pseudo_bp(Cond, TrueLab, FalseLab, Pred).
+ {I2, DidCommute} = mk_alu(XAluOp, Src1, Src2, Dst),
+ NewCond =
+ case DidCommute andalso XAluOp =:= 'cmpcc' of
+ true -> commute_cond(Cond); % subcc does not commute; its conditions do
+ false -> Cond
+ end,
+ I2 ++ mk_pseudo_bp(NewCond, TrueLab, FalseLab, Pred).
conv_alubop_cc(RtlAlubOp) ->
case RtlAlubOp of
@@ -380,69 +343,6 @@ conv_alubop_cc(RtlAlubOp) ->
%% no shift ops
end.
-conv_branch(I, Map, Data) ->
- %% <unused> = src1 - src2; if COND goto label
- {Src1, Map0} = conv_src(hipe_rtl:branch_src1(I), Map),
- {Src2, Map1} = conv_src(hipe_rtl:branch_src2(I), Map0),
- Cond = conv_cond(hipe_rtl:branch_cond(I)),
- I2 = conv_branch2(Src1, Cond, Src2, I),
- {I2, Map1, Data}.
-
--ifdef(notdef). % XXX: only for sparc64, alas
-conv_branch2(Src1, Cond, Src2, I) ->
- case conv_cond_rcond(Cond) of
- [] ->
- conv_branch_bp(Src1, Cond, Src2, I);
- RCond ->
- conv_branch_br(Src1, RCond, Src2, I)
- end.
-
-conv_branch_br(Src1, RCond, Src2, I) ->
- TrueLab = hipe_rtl:branch_true_label(I),
- FalseLab = hipe_rtl:branch_false_label(I),
- Pred = hipe_rtl:branch_pred(I),
- %% "if src1-COND-src2" becomes
- %% "sub src1,src2,tmp; if-COND(tmp)"
- Dst = hipe_sparc:mk_new_temp('untagged'),
- XAluOp = 'cmp', % == a sub that commutes
- {I1, DidCommute} = mk_alu(XAluOp, Src1, Src2, Dst),
- NewRCond =
- case DidCommute of
- true -> commute_rcond(RCond);
- false -> RCond
- end,
- I1 ++ mk_pseudo_br(NewRCond, Dst, TrueLab, FalseLab, Pred).
-
-commute_rcond(RCond) -> % if x RCond y, then y commute_rcond(RCond) x
- case RCond of
- 'z' -> 'z'; % ==, ==
- 'nz' -> 'nz'; % !=, !=
- 'gz' -> 'lz'; % >, <
- 'gez' -> 'lez'; % >=, <=
- 'lz' -> 'gz'; % <, >
- 'lez' -> 'gez' % <=, >=
- end.
--else.
-conv_branch2(Src1, Cond, Src2, I) ->
- conv_branch_bp(Src1, Cond, Src2, I).
--endif.
-
-conv_branch_bp(Src1, Cond, Src2, I) ->
- TrueLab = hipe_rtl:branch_true_label(I),
- FalseLab = hipe_rtl:branch_false_label(I),
- Pred = hipe_rtl:branch_pred(I),
- %% "if src1-COND-src2" becomes
- %% "subcc src1,src2,%g0; if-COND(CC)"
- Dst = hipe_sparc:mk_g0(),
- XAluOp = 'cmpcc', % == a subcc that commutes
- {I1, DidCommute} = mk_alu(XAluOp, Src1, Src2, Dst),
- NewCond =
- case DidCommute of
- true -> commute_cond(Cond);
- false -> Cond
- end,
- I1 ++ mk_pseudo_bp(NewCond, TrueLab, FalseLab, Pred).
-
conv_call(I, Map, Data) ->
{Args, Map0} = conv_src_list(hipe_rtl:call_arglist(I), Map),
{Dsts, Map1} = conv_dst_list(hipe_rtl:call_dstlist(I), Map0),
@@ -625,7 +525,7 @@ conv_return(I, Map, Data) ->
{I2, Map0, Data}.
conv_store(I, Map, Data) ->
- {Base1, Map0} = conv_dst(hipe_rtl:store_base(I), Map), % no immediates allowed
+ {Base1, Map0} = conv_src(hipe_rtl:store_base(I), Map),
{Src, Map1} = conv_src(hipe_rtl:store_src(I), Map0),
{Base2, Map2} = conv_src(hipe_rtl:store_offset(I), Map1),
StOp = conv_stop(hipe_rtl:store_size(I)),
@@ -649,13 +549,27 @@ mk_store(StOp, Src, Base1, Base2) ->
end.
mk_store2(StOp, Src, Base1, Base2) ->
- case hipe_sparc:is_temp(Base2) of
+ case hipe_sparc:is_temp(Base1) of
true ->
- mk_store_rr(StOp, Src, Base1, Base2);
+ case hipe_sparc:is_temp(Base2) of
+ true ->
+ mk_store_rr(StOp, Src, Base1, Base2);
+ _ ->
+ mk_store_ri(StOp, Src, Base1, Base2)
+ end;
_ ->
- mk_store_ri(StOp, Src, Base1, Base2)
+ case hipe_sparc:is_temp(Base2) of
+ true ->
+ mk_store_ri(StOp, Src, Base2, Base1);
+ _ ->
+ mk_store_ii(StOp, Src, Base1, Base2)
+ end
end.
+mk_store_ii(StOp, Src, Base, Disp) ->
+ Tmp = new_untagged_temp(),
+ mk_set(Base, Tmp, mk_store_ri(StOp, Src, Tmp, Disp)).
+
mk_store_ri(StOp, Src, Base, Disp) ->
hipe_sparc:mk_store(StOp, Src, Base, Disp, 'new', []).
@@ -750,13 +664,25 @@ xaluop_commutes(XAluOp) ->
xaluop_is_shift(XAluOp) ->
case XAluOp of
+ 'add' -> false;
+ 'addcc' -> false;
+ 'and' -> false;
+ 'andcc' -> false;
+ 'cmpcc' -> false;
+ 'ldsb' -> false;
+ 'ldub' -> false;
+ 'lduw' -> false;
+ 'or' -> false;
'sll' -> true;
- 'srl' -> true;
+ %% 'sllx' -> true;
+ 'smul' -> false;
'sra' -> true;
- 'sllx' -> true;
- 'srlx' -> true;
- 'srax' -> true;
- _ -> false
+ %% 'srax' -> true;
+ 'srl' -> true;
+ %% 'srlx' -> true;
+ 'sub' -> false;
+ 'subcc' -> false;
+ 'xor' -> false
end.
%%% Convert an extended SPARC AluOp back to a plain AluOp.
@@ -764,9 +690,23 @@ xaluop_is_shift(XAluOp) ->
xaluop_normalise(XAluOp) ->
case XAluOp of
- 'cmp' -> 'sub';
+ 'add' -> 'add';
+ 'addcc' -> 'addcc';
+ 'and' -> 'and';
+ 'andcc' -> 'andcc';
+ %% 'cmp' -> 'sub';
'cmpcc' -> 'subcc';
- _ -> XAluOp
+ 'ldsb' -> 'ldsb';
+ 'ldub' -> 'ldub';
+ 'lduw' -> 'lduw';
+ 'or' -> 'or';
+ 'sll' -> 'sll';
+ 'smul' -> 'smul';
+ 'sra' -> 'sra';
+ 'srl' -> 'srl';
+ 'sub' -> 'sub';
+ 'subcc' -> 'subcc';
+ 'xor' -> 'xor'
end.
%%% Convert an RTL condition code.
diff --git a/lib/hipe/sparc/hipe_sparc.erl b/lib/hipe/sparc/hipe_sparc.erl
index 5ecb6aa8b9..22e0761b69 100644
--- a/lib/hipe/sparc/hipe_sparc.erl
+++ b/lib/hipe/sparc/hipe_sparc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc).
-export([
@@ -94,6 +87,9 @@
mk_pseudo_set/2,
+ mk_pseudo_spill_move/3,
+ is_pseudo_spill_move/1,
+
mk_pseudo_tailcall/4,
pseudo_tailcall_funv/1,
pseudo_tailcall_linkage/1,
@@ -124,6 +120,9 @@
pseudo_fmove_src/1,
pseudo_fmove_dst/1,
+ mk_pseudo_spill_fmove/3,
+ is_pseudo_spill_fmove/1,
+
mk_pseudo_fstore/3,
mk_fstore/4,
@@ -276,6 +275,10 @@ mk_pseudo_ret() -> #pseudo_ret{}.
mk_pseudo_set(Imm, Dst) -> #pseudo_set{imm=Imm, dst=Dst}.
+mk_pseudo_spill_move(Src, Temp, Dst) ->
+ #pseudo_spill_move{src=Src, temp=Temp, dst=Dst}.
+is_pseudo_spill_move(I) -> is_record(I, pseudo_spill_move).
+
mk_pseudo_tailcall(FunV, Arity, StkArgs, Linkage) ->
#pseudo_tailcall{funv=FunV, arity=Arity, stkargs=StkArgs, linkage=Linkage}.
pseudo_tailcall_funv(#pseudo_tailcall{funv=FunV}) -> FunV.
@@ -382,6 +385,10 @@ is_pseudo_fmove(I) -> case I of #pseudo_fmove{} -> true; _ -> false end.
pseudo_fmove_src(#pseudo_fmove{src=Src}) -> Src.
pseudo_fmove_dst(#pseudo_fmove{dst=Dst}) -> Dst.
+mk_pseudo_spill_fmove(Src, Temp, Dst) ->
+ #pseudo_spill_fmove{src=Src, temp=Temp, dst=Dst}.
+is_pseudo_spill_fmove(I) -> is_record(I, pseudo_spill_fmove).
+
mk_pseudo_fstore(Src, Base, Disp) ->
#pseudo_fstore{src=Src, base=Base, disp=Disp}.
diff --git a/lib/hipe/sparc/hipe_sparc.hrl b/lib/hipe/sparc/hipe_sparc.hrl
index 01c8d07f22..f60e516e59 100644
--- a/lib/hipe/sparc/hipe_sparc.hrl
+++ b/lib/hipe/sparc/hipe_sparc.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%--------------------------------------------------------------------
%%% Basic Values:
@@ -95,6 +88,8 @@
-record(pseudo_move, {src, dst}).
-record(pseudo_ret, {}).
-record(pseudo_set, {imm, dst}).
+-record(pseudo_spill_fmove, {src, temp, dst}).
+-record(pseudo_spill_move, {src, temp, dst}).
-record(pseudo_tailcall, {funv, arity, stkargs, linkage}).
-record(pseudo_tailcall_prepare, {}).
-record(rdy, {dst}).
diff --git a/lib/hipe/sparc/hipe_sparc_assemble.erl b/lib/hipe/sparc/hipe_sparc_assemble.erl
index e92f024968..2b82f41d23 100644
--- a/lib/hipe/sparc/hipe_sparc_assemble.erl
+++ b/lib/hipe/sparc/hipe_sparc_assemble.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_assemble).
-export([assemble/4]).
@@ -39,7 +32,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
|| {MFA, Defun} <- CompiledCode],
%%
{ConstAlign,ConstSize,ConstMap,RefsFromConsts} =
- hipe_pack_constants:pack_constants(Code, 4),
+ hipe_pack_constants:pack_constants(Code),
%%
{CodeSize,CodeBinary,AccRefs,LabelMap,ExportMap} =
encode(translate(Code, ConstMap), Options),
diff --git a/lib/hipe/sparc/hipe_sparc_cfg.erl b/lib/hipe/sparc/hipe_sparc_cfg.erl
index 0b2c77f27b..45c8e887b5 100644
--- a/lib/hipe/sparc/hipe_sparc_cfg.erl
+++ b/lib/hipe/sparc/hipe_sparc_cfg.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,20 +11,19 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_cfg).
-export([init/1,
labels/1, start_label/1,
succ/2,
+ map_bbs/2, fold_bbs/3,
bb/2, bb_add/3]).
-export([postorder/1, reverse_postorder/1]).
-export([linearise/1]).
-export([params/1]).
-export([arity/1]). % for linear scan
+-export([redirect_jmp/3, branch_preds/1]).
-define(SPARC_CFG, true). % needed for cfg.inc
@@ -83,28 +78,53 @@ branch_successors(Branch) ->
#pseudo_tailcall{} -> []
end.
+branch_preds(Branch) ->
+ case Branch of
+ #jmp{labels=Labels} ->
+ Prob = 1.0/length(Labels),
+ [{L, Prob} || L <- Labels];
+ #pseudo_bp{true_label=TrueLab,false_label=FalseLab,pred=Pred} ->
+ [{FalseLab, 1.0-Pred}, {TrueLab, Pred}];
+ #pseudo_call{contlab=ContLab, sdesc=#sparc_sdesc{exnlab=[]}} ->
+ %% A function can still cause an exception, even if we won't catch it
+ [{ContLab, 1.0-hipe_bb_weights:call_exn_pred()}];
+ #pseudo_call{contlab=ContLab, sdesc=#sparc_sdesc{exnlab=ExnLab}} ->
+ CallExnPred = hipe_bb_weights:call_exn_pred(),
+ [{ContLab, 1.0-CallExnPred}, {ExnLab, CallExnPred}];
+ _ ->
+ case branch_successors(Branch) of
+ [] -> [];
+ [Single] -> [{Single, 1.0}]
+ end
+ end.
+
-ifdef(REMOVE_TRIVIAL_BBS_NEEDED).
fails_to(_Instr) -> [].
-endif.
--ifdef(notdef).
redirect_jmp(I, Old, New) ->
case I of
- #b_label{label=Label} ->
- if Old =:= Label -> I#b_label{label=New};
+ #bp{'cond'='a',label=Label} ->
+ if Old =:= Label -> I#bp{label=New};
true -> I
end;
- #pseudo_bc{true_label=TrueLab, false_label=FalseLab} ->
- I1 = if Old =:= TrueLab -> I#pseudo_bc{true_label=New};
+ #pseudo_bp{true_label=TrueLab, false_label=FalseLab} ->
+ I1 = if Old =:= TrueLab -> I#pseudo_bp{true_label=New};
true -> I
end,
- if Old =:= FalseLab -> I1#pseudo_bc{false_label=New};
+ if Old =:= FalseLab -> I1#pseudo_bp{false_label=New};
true -> I1
end;
- %% handle pseudo_call too?
- _ -> I
+ #pseudo_call{contlab=ContLab0, sdesc=SDesc0} ->
+ SDesc = case SDesc0 of
+ #sparc_sdesc{exnlab=Old} -> SDesc0#sparc_sdesc{exnlab=New};
+ #sparc_sdesc{exnlab=_} -> SDesc0
+ end,
+ ContLab = if Old =:= ContLab0 -> New;
+ true -> ContLab0
+ end,
+ I#pseudo_call{sdesc=SDesc, contlab=ContLab}
end.
--endif.
mk_goto(Label) ->
hipe_sparc:mk_b_label(Label).
diff --git a/lib/hipe/sparc/hipe_sparc_defuse.erl b/lib/hipe/sparc/hipe_sparc_defuse.erl
index 4f66299f1d..4d4b11e301 100644
--- a/lib/hipe/sparc/hipe_sparc_defuse.erl
+++ b/lib/hipe/sparc/hipe_sparc_defuse.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,14 +11,12 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_defuse).
-export([insn_def_all/1, insn_use_all/1]).
-export([insn_def_gpr/1, insn_use_gpr/1]).
-export([insn_def_fpr/1, insn_use_fpr/1]).
+-export([insn_defs_all_gpr/1, insn_defs_all_fpr/1]).
-include("hipe_sparc.hrl").
%%%
@@ -45,12 +39,19 @@ insn_def_gpr(I) ->
#pseudo_call{} -> call_clobbered_gpr();
#pseudo_move{dst=Dst} -> [Dst];
#pseudo_set{dst=Dst} -> [Dst];
+ #pseudo_spill_move{temp=Temp, dst=Dst} -> [Temp, Dst];
#pseudo_tailcall_prepare{} -> tailcall_clobbered_gpr();
#rdy{dst=Dst} -> [Dst];
#sethi{dst=Dst} -> [Dst];
_ -> []
end.
+insn_defs_all_gpr(I) ->
+ case I of
+ #pseudo_call{} -> true;
+ _ -> false
+ end.
+
call_clobbered_gpr() ->
[hipe_sparc:mk_temp(R, T)
|| {R,T} <- hipe_sparc_registers:call_clobbered() ++ all_fp_pseudos()].
@@ -72,6 +73,7 @@ insn_use_gpr(I) ->
funv_use(FunV, arity_use_gpr(Arity));
#pseudo_move{src=Src} -> [Src];
#pseudo_ret{} -> [hipe_sparc:mk_rv()];
+ #pseudo_spill_move{src=Src} -> [Src];
#pseudo_tailcall{funv=FunV,arity=Arity,stkargs=StkArgs} ->
addsrcs(StkArgs, addtemps(tailcall_clobbered_gpr(), funv_use(FunV, arity_use_gpr(Arity))));
#store{src=Src,base=Base,disp=Disp} ->
@@ -112,9 +114,16 @@ insn_def_fpr(I) ->
#fp_unary{dst=Dst} -> [Dst];
#pseudo_fload{dst=Dst} -> [Dst];
#pseudo_fmove{dst=Dst} -> [Dst];
+ #pseudo_spill_fmove{temp=Temp, dst=Dst} -> [Temp, Dst];
_ -> []
end.
+insn_defs_all_fpr(I) ->
+ case I of
+ #pseudo_call{} -> true;
+ _ -> false
+ end.
+
call_clobbered_fpr() ->
[hipe_sparc:mk_temp(R, 'double') || R <- hipe_sparc_registers:allocatable_fpr()].
@@ -124,6 +133,7 @@ insn_use_fpr(I) ->
#fp_unary{src=Src} -> [Src];
#pseudo_fmove{src=Src} -> [Src];
#pseudo_fstore{src=Src} -> [Src];
+ #pseudo_spill_fmove{src=Src} -> [Src];
_ -> []
end.
diff --git a/lib/hipe/sparc/hipe_sparc_encode.erl b/lib/hipe/sparc/hipe_sparc_encode.erl
index 6a7d502fd3..f0ee2d1647 100644
--- a/lib/hipe/sparc/hipe_sparc_encode.erl
+++ b/lib/hipe/sparc/hipe_sparc_encode.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Encode symbolic SPARC instructions to binary form.
%%% Copyright (C) 2007-2008 Mikael Pettersson
diff --git a/lib/hipe/sparc/hipe_sparc_finalise.erl b/lib/hipe/sparc/hipe_sparc_finalise.erl
index 2b7125fb73..3634a4d14c 100644
--- a/lib/hipe/sparc/hipe_sparc_finalise.erl
+++ b/lib/hipe/sparc/hipe_sparc_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_finalise).
-export([finalise/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_frame.erl b/lib/hipe/sparc/hipe_sparc_frame.erl
index a42c1983f4..1f2a259ca1 100644
--- a/lib/hipe/sparc/hipe_sparc_frame.erl
+++ b/lib/hipe/sparc/hipe_sparc_frame.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_frame).
-export([frame/1]).
@@ -25,16 +18,14 @@
-include("hipe_sparc.hrl").
-include("../rtl/hipe_literals.hrl").
-frame(Defun) ->
- Formals = fix_formals(hipe_sparc:defun_formals(Defun)),
- Temps0 = all_temps(hipe_sparc:defun_code(Defun), Formals),
- MinFrame = defun_minframe(Defun),
+frame(CFG) ->
+ Formals = fix_formals(hipe_sparc_cfg:params(CFG)),
+ Temps0 = all_temps(CFG, Formals),
+ MinFrame = defun_minframe(CFG),
Temps = ensure_minframe(MinFrame, Temps0),
- ClobbersRA = clobbers_ra(hipe_sparc:defun_code(Defun)),
- CFG0 = hipe_sparc_cfg:init(Defun),
- Liveness = hipe_sparc_liveness_all:analyse(CFG0),
- CFG1 = do_body(CFG0, Liveness, Formals, Temps, ClobbersRA),
- hipe_sparc_cfg:linearise(CFG1).
+ ClobbersRA = clobbers_ra(CFG),
+ Liveness = hipe_sparc_liveness_all:analyse(CFG),
+ do_body(CFG, Liveness, Formals, Temps, ClobbersRA).
fix_formals(Formals) ->
fix_formals(hipe_sparc_registers:nr_args(), Formals).
@@ -91,6 +82,10 @@ do_insn(I, LiveOut, Context, FPoff) ->
{do_pseudo_tailcall(I, Context), context_framesize(Context)};
#pseudo_fmove{} ->
{do_pseudo_fmove(I, Context, FPoff), FPoff};
+ #pseudo_spill_move{} ->
+ {do_pseudo_spill_move(I, Context, FPoff), FPoff};
+ #pseudo_spill_fmove{} ->
+ {do_pseudo_spill_fmove(I, Context, FPoff), FPoff};
_ ->
{[I], FPoff}
end.
@@ -112,7 +107,26 @@ do_pseudo_move(I, Context, FPoff) ->
Offset = pseudo_offset(Src, FPoff, Context),
mk_load(hipe_sparc:mk_sp(), Offset, Dst, []);
_ ->
- [hipe_sparc:mk_mov(Src, Dst)]
+ case hipe_sparc:temp_reg(Dst) =:= hipe_sparc:temp_reg(Src) of
+ true -> [];
+ false -> [hipe_sparc:mk_mov(Src, Dst)]
+ end
+ end
+ end.
+
+do_pseudo_spill_move(I, Context, FPoff) ->
+ #pseudo_spill_move{src=Src,temp=Temp,dst=Dst} = I,
+ case temp_is_pseudo(Src) andalso temp_is_pseudo(Dst) of
+ false -> % Register allocator changed its mind, turn back to move
+ do_pseudo_move(hipe_sparc:mk_pseudo_move(Src, Dst), Context, FPoff);
+ true ->
+ SrcOffset = pseudo_offset(Src, FPoff, Context),
+ DstOffset = pseudo_offset(Dst, FPoff, Context),
+ case SrcOffset =:= DstOffset of
+ true -> []; % omit move-to-self
+ false ->
+ mk_load(hipe_sparc:mk_sp(), SrcOffset, Temp,
+ mk_store(Temp, hipe_sparc:mk_sp(), DstOffset, []))
end
end.
@@ -133,6 +147,22 @@ do_pseudo_fmove(I, Context, FPoff) ->
end
end.
+do_pseudo_spill_fmove(I, Context, FPoff) ->
+ #pseudo_spill_fmove{src=Src,temp=Temp,dst=Dst} = I,
+ case temp_is_pseudo(Src) andalso temp_is_pseudo(Dst) of
+ false -> % Register allocator changed its mind, turn back to fmove
+ do_pseudo_fmove(hipe_sparc:mk_pseudo_fmove(Src, Dst), Context, FPoff);
+ true ->
+ SrcOffset = pseudo_offset(Src, FPoff, Context),
+ DstOffset = pseudo_offset(Dst, FPoff, Context),
+ case SrcOffset =:= DstOffset of
+ true -> []; % omit move-to-self
+ false ->
+ mk_fload(hipe_sparc:mk_sp(), SrcOffset, Temp)
+ ++ mk_fstore(Temp, hipe_sparc:mk_sp(), DstOffset)
+ end
+ end.
+
pseudo_offset(Temp, FPoff, Context) ->
FPoff + context_offset(Context, Temp).
@@ -550,29 +580,41 @@ temp_is_pseudo(Temp) ->
%%% Detect if a Defun's body clobbers RA.
%%%
-clobbers_ra(Insns) ->
- case Insns of
- [#pseudo_call{}|_] -> true;
- %% moves to RA cannot occur yet
- [_|Rest] -> clobbers_ra(Rest);
- [] -> false
+clobbers_ra(CFG) ->
+ any_insn(fun(#pseudo_call{}) -> true;
+ (_) -> false
+ end, CFG).
+
+any_insn(Pred, CFG) ->
+ %% Abuse fold to do an efficient "any"-operation using nonlocal control flow
+ FoundSatisfying = make_ref(),
+ try fold_insns(fun (I, _) ->
+ case Pred(I) of
+ true -> throw(FoundSatisfying);
+ false -> false
+ end
+ end, false, CFG)
+ of _ -> false
+ catch FoundSatisfying -> true
end.
%%%
%%% Build the set of all temps used in a Defun's body.
%%%
-all_temps(Code, Formals) ->
- S0 = find_temps(Code, tset_empty()),
+all_temps(CFG, Formals) ->
+ S0 = fold_insns(fun find_temps/2, tset_empty(), CFG),
S1 = tset_del_list(S0, Formals),
tset_filter(S1, fun(T) -> temp_is_pseudo(T) end).
-find_temps([I|Insns], S0) ->
+find_temps(I, S0) ->
S1 = tset_add_list(S0, hipe_sparc_defuse:insn_def_all(I)),
- S2 = tset_add_list(S1, hipe_sparc_defuse:insn_use_all(I)),
- find_temps(Insns, S2);
-find_temps([], S) ->
- S.
+ tset_add_list(S1, hipe_sparc_defuse:insn_use_all(I)).
+
+fold_insns(Fun, InitAcc, CFG) ->
+ hipe_sparc_cfg:fold_bbs(
+ fun(_, BB, Acc0) -> lists:foldl(Fun, Acc0, hipe_bb:code(BB)) end,
+ InitAcc, CFG).
tset_empty() ->
gb_sets:new().
@@ -601,16 +643,11 @@ tset_to_list(S) ->
%%% in the middle of a tailcall.
%%%
-defun_minframe(Defun) ->
- MaxTailArity = body_mta(hipe_sparc:defun_code(Defun), 0),
- MyArity = length(fix_formals(hipe_sparc:defun_formals(Defun))),
+defun_minframe(CFG) ->
+ MaxTailArity = fold_insns(fun insn_mta/2, 0, CFG),
+ MyArity = length(fix_formals(hipe_sparc_cfg:params(CFG))),
erlang:max(MaxTailArity - MyArity, 0).
-body_mta([I|Code], MTA) ->
- body_mta(Code, insn_mta(I, MTA));
-body_mta([], MTA) ->
- MTA.
-
insn_mta(I, MTA) ->
case I of
#pseudo_tailcall{arity=Arity} ->
diff --git a/lib/hipe/sparc/hipe_sparc_liveness_all.erl b/lib/hipe/sparc/hipe_sparc_liveness_all.erl
index b7c3e1962a..f67b6c0fca 100644
--- a/lib/hipe/sparc/hipe_sparc_liveness_all.erl
+++ b/lib/hipe/sparc/hipe_sparc_liveness_all.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_liveness_all).
-export([analyse/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl b/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl
index 497c554c3e..bd2c0c75ee 100644
--- a/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl
+++ b/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_liveness_fpr).
-export([analyse/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl b/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl
index 55d639e3a2..848148e301 100644
--- a/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl
+++ b/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_liveness_gpr).
-export([analyse/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_main.erl b/lib/hipe/sparc/hipe_sparc_main.erl
index c16751c7bd..ea05721f60 100644
--- a/lib/hipe/sparc/hipe_sparc_main.erl
+++ b/lib/hipe/sparc/hipe_sparc_main.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,21 +11,20 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_main).
-export([rtl_to_sparc/3]).
rtl_to_sparc(MFA, RTL, Options) ->
Defun1 = hipe_rtl_to_sparc:translate(RTL),
+ CFG1 = hipe_sparc_cfg:init(Defun1),
%% io:format("~w: after translate\n", [?MODULE]),
%% hipe_sparc_pp:pp(Defun1),
- Defun2 = hipe_sparc_ra:ra(Defun1, Options),
+ CFG2 = hipe_sparc_ra:ra(CFG1, Options),
%% io:format("~w: after regalloc\n", [?MODULE]),
- %% hipe_sparc_pp:pp(Defun2),
- Defun3 = hipe_sparc_frame:frame(Defun2),
+ %% hipe_sparc_pp:pp(hipe_sparc_cfg:linearise(CFG2)),
+ CFG3 = hipe_sparc_frame:frame(CFG2),
+ Defun3 = hipe_sparc_cfg:linearise(CFG3),
%% io:format("~w: after frame\n", [?MODULE]),
%% hipe_sparc_pp:pp(Defun3),
Defun4 = hipe_sparc_finalise:finalise(Defun3),
diff --git a/lib/hipe/sparc/hipe_sparc_pp.erl b/lib/hipe/sparc/hipe_sparc_pp.erl
index 8fa0a9c788..d893094eb7 100644
--- a/lib/hipe/sparc/hipe_sparc_pp.erl
+++ b/lib/hipe/sparc/hipe_sparc_pp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_pp).
-export([pp/1, pp/2, pp_insn/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_ra.erl b/lib/hipe/sparc/hipe_sparc_ra.erl
index afea8c9b4c..ba1a9aa3d8 100644
--- a/lib/hipe/sparc/hipe_sparc_ra.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,43 +11,43 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_ra).
-export([ra/2]).
-ra(Defun0, Options) ->
- %% hipe_sparc_pp:pp(Defun0),
- {Defun1, Coloring_fp, SpillIndex}
+ra(CFG0, Options) ->
+ %% hipe_sparc_pp:pp(hipe_sparc_cfg:linearise(CFG0)),
+ {CFG1, _FPLiveness1, Coloring_fp, SpillIndex}
= case proplists:get_bool(inline_fp, Options) of
true ->
- hipe_regalloc_loop:ra_fp(Defun0, Options,
+ FPLiveness0 = hipe_sparc_specific_fp:analyze(CFG0, no_context),
+ hipe_regalloc_loop:ra_fp(CFG0, FPLiveness0, Options,
hipe_coalescing_regalloc,
- hipe_sparc_specific_fp);
+ hipe_sparc_specific_fp, no_context);
false ->
- {Defun0,[],0}
+ {CFG0,undefined,[],0}
end,
- %% hipe_sparc_pp:pp(Defun1),
- {Defun2, Coloring}
+ %% hipe_sparc_pp:pp(hipe_sparc_cfg:linearise(CFG1)),
+ GPLiveness1 = hipe_sparc_specific:analyze(CFG1, no_context),
+ {CFG2, _GPLiveness2, Coloring}
= case proplists:get_value(regalloc, Options, coalescing) of
coalescing ->
- ra(Defun1, SpillIndex, Options, hipe_coalescing_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options, hipe_coalescing_regalloc);
optimistic ->
- ra(Defun1, SpillIndex, Options, hipe_optimistic_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options, hipe_optimistic_regalloc);
graph_color ->
- ra(Defun1, SpillIndex, Options, hipe_graph_coloring_regalloc);
+ ra(CFG1, GPLiveness1, SpillIndex, Options, hipe_graph_coloring_regalloc);
linear_scan ->
- hipe_sparc_ra_ls:ra(Defun1, SpillIndex, Options);
+ hipe_sparc_ra_ls:ra(CFG1, GPLiveness1, SpillIndex, Options);
naive ->
- hipe_sparc_ra_naive:ra(Defun1, Coloring_fp, Options);
+ hipe_sparc_ra_naive:ra(CFG1, GPLiveness1, Coloring_fp, Options);
_ ->
exit({unknown_regalloc_compiler_option,
proplists:get_value(regalloc,Options)})
end,
- %% hipe_sparc_pp:pp(Defun2),
- hipe_sparc_ra_finalise:finalise(Defun2, Coloring, Coloring_fp).
+ %% hipe_sparc_pp:pp(hipe_sparc_cfg:linearise(CFG2)),
+ hipe_sparc_ra_finalise:finalise(CFG2, Coloring, Coloring_fp).
-ra(Defun, SpillIndex, Options, RegAllocMod) ->
- hipe_regalloc_loop:ra(Defun, SpillIndex, Options, RegAllocMod, hipe_sparc_specific).
+ra(CFG, Liveness, SpillIndex, Options, RegAllocMod) ->
+ hipe_regalloc_loop:ra(CFG, Liveness, SpillIndex, Options, RegAllocMod,
+ hipe_sparc_specific, no_context).
diff --git a/lib/hipe/sparc/hipe_sparc_ra_finalise.erl b/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
index dc1e69c101..a724821992 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,21 +11,19 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_ra_finalise).
-export([finalise/3]).
-include("hipe_sparc.hrl").
-finalise(Defun, TempMap, FPMap0) ->
- Code = hipe_sparc:defun_code(Defun),
- {_, SpillLimit} = hipe_sparc:defun_var_range(Defun),
+finalise(CFG, TempMap, FPMap0) ->
+ {_, SpillLimit} = hipe_gensym:var_range(sparc),
Map = mk_ra_map(TempMap, SpillLimit),
FPMap1 = mk_ra_map_fp(FPMap0, SpillLimit),
- NewCode = ra_code(Code, Map, FPMap1, []),
- Defun#defun{code=NewCode}.
+ hipe_sparc_cfg:map_bbs(fun(_Lbl, BB) -> ra_bb(BB, Map, FPMap1) end, CFG).
+
+ra_bb(BB, Map, FpMap) ->
+ hipe_bb:code_update(BB, ra_code(hipe_bb:code(BB), Map, FpMap, [])).
ra_code([I|Insns], Map, FPMap, Accum) ->
ra_code(Insns, Map, FPMap, [ra_insn(I, Map, FPMap) | Accum]);
@@ -44,6 +38,7 @@ ra_insn(I, Map, FPMap) ->
#pseudo_call{} -> ra_pseudo_call(I, Map);
#pseudo_move{} -> ra_pseudo_move(I, Map);
#pseudo_set{} -> ra_pseudo_set(I, Map);
+ #pseudo_spill_move{} -> ra_pseudo_spill_move(I, Map);
#pseudo_tailcall{} -> ra_pseudo_tailcall(I, Map);
#rdy{} -> ra_rdy(I, Map);
#sethi{} -> ra_sethi(I, Map);
@@ -53,6 +48,7 @@ ra_insn(I, Map, FPMap) ->
#pseudo_fload{} -> ra_pseudo_fload(I, Map, FPMap);
#pseudo_fmove{} -> ra_pseudo_fmove(I, FPMap);
#pseudo_fstore{} -> ra_pseudo_fstore(I, Map, FPMap);
+ #pseudo_spill_fmove{} -> ra_pseudo_spill_fmove(I, FPMap);
_ -> I
end.
@@ -86,6 +82,12 @@ ra_pseudo_set(I=#pseudo_set{dst=Dst}, Map) ->
NewDst = ra_temp(Dst, Map),
I#pseudo_set{dst=NewDst}.
+ra_pseudo_spill_move(I=#pseudo_spill_move{src=Src,temp=Temp,dst=Dst}, Map) ->
+ NewSrc = ra_temp(Src, Map),
+ NewTemp = ra_temp(Temp, Map),
+ NewDst = ra_temp(Dst, Map),
+ I#pseudo_spill_move{src=NewSrc,temp=NewTemp,dst=NewDst}.
+
ra_pseudo_tailcall(I=#pseudo_tailcall{funv=FunV,stkargs=StkArgs}, Map) ->
NewFunV = ra_funv(FunV, Map),
NewStkArgs = ra_args(StkArgs, Map),
@@ -126,6 +128,13 @@ ra_pseudo_fmove(I=#pseudo_fmove{src=Src,dst=Dst}, FPMap) ->
NewDst = ra_temp_fp(Dst, FPMap),
I#pseudo_fmove{src=NewSrc,dst=NewDst}.
+ra_pseudo_spill_fmove(I=#pseudo_spill_fmove{src=Src,temp=Temp,dst=Dst},
+ FPMap) ->
+ NewSrc = ra_temp_fp(Src, FPMap),
+ NewTemp = ra_temp_fp(Temp, FPMap),
+ NewDst = ra_temp_fp(Dst, FPMap),
+ I#pseudo_spill_fmove{src=NewSrc,temp=NewTemp,dst=NewDst}.
+
ra_pseudo_fstore(I=#pseudo_fstore{src=Src,base=Base}, Map, FPMap) ->
NewSrc = ra_temp_fp(Src, FPMap),
NewBase = ra_temp(Base, Map),
diff --git a/lib/hipe/sparc/hipe_sparc_ra_ls.erl b/lib/hipe/sparc/hipe_sparc_ra_ls.erl
index 19e7c92d2f..1b8659ab70 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_ls.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_ls.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,43 +11,39 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% Linear Scan register allocator for SPARC
-module(hipe_sparc_ra_ls).
--export([ra/3]).
+-export([ra/4]).
-ra(Defun, SpillIndex, Options) ->
- NewDefun = Defun, %% hipe_${ARCH}_ra_rename:rename(Defun,Options),
- CFG = hipe_sparc_cfg:init(NewDefun),
- SpillLimit = hipe_sparc_specific:number_of_temporaries(CFG),
- alloc(NewDefun, SpillIndex, SpillLimit, Options).
+ra(CFG, Liveness, SpillIndex, Options) ->
+ SpillLimit = hipe_sparc_specific:number_of_temporaries(CFG, no_context),
+ alloc(CFG, Liveness, SpillIndex, SpillLimit, Options).
-alloc(Defun, SpillIndex, SpillLimit, Options) ->
- CFG = hipe_sparc_cfg:init(Defun),
+alloc(CFG, Liveness, SpillIndex, SpillLimit, Options) ->
{Coloring, _NewSpillIndex} =
regalloc(
- CFG,
+ CFG, Liveness,
hipe_sparc_registers:allocatable_gpr()--
[hipe_sparc_registers:temp3(),
hipe_sparc_registers:temp2(),
hipe_sparc_registers:temp1()],
[hipe_sparc_cfg:start_label(CFG)],
SpillIndex, SpillLimit, Options,
- hipe_sparc_specific),
- {NewDefun, _DidSpill} =
+ hipe_sparc_specific, no_context),
+ {NewCFG, _DidSpill} =
hipe_sparc_ra_postconditions:check_and_rewrite(
- Defun, Coloring, 'linearscan'),
- TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific),
+ CFG, Coloring, 'linearscan'),
+ TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific, no_context),
{TempMap2,_NewSpillIndex2} =
- hipe_spillmin:stackalloc(CFG, [], SpillIndex, Options,
- hipe_sparc_specific, TempMap),
+ hipe_spillmin:stackalloc(CFG, Liveness, [], SpillIndex, Options,
+ hipe_sparc_specific, no_context, TempMap),
Coloring2 =
hipe_spillmin:mapmerge(hipe_temp_map:to_substlist(TempMap), TempMap2),
- {NewDefun, Coloring2}.
+ {NewCFG, Liveness, Coloring2}.
-regalloc(CFG, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options, Target) ->
- hipe_ls_regalloc:regalloc(
- CFG, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options, Target).
+regalloc(CFG, Liveness, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options,
+ TgtMod, TgtCtx) ->
+ hipe_ls_regalloc:regalloc(CFG, Liveness, PhysRegs, Entrypoints, SpillIndex,
+ DontSpill, Options, TgtMod, TgtCtx).
diff --git a/lib/hipe/sparc/hipe_sparc_ra_naive.erl b/lib/hipe/sparc/hipe_sparc_ra_naive.erl
index b6c33dec6c..5ea9ead6bc 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_naive.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_naive.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,16 +11,13 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_ra_naive).
--export([ra/3]).
+-export([ra/4]).
-include("hipe_sparc.hrl").
-ra(Defun, _Coloring_fp, _Options) -> % -> {Defun, Coloring}
- {NewDefun,_DidSpill} =
- hipe_sparc_ra_postconditions:check_and_rewrite2(Defun, [], 'naive'),
- {NewDefun, []}.
+ra(CFG, Liveness, _Coloring_fp, _Options) -> % -> {CFG, Liveness, Coloring}
+ {NewCFG,_DidSpill} =
+ hipe_sparc_ra_postconditions:check_and_rewrite2(CFG, [], 'naive'),
+ {NewCFG, Liveness, []}.
diff --git a/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl b/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
index ab31b3c8d9..d3ecb43ec6 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_ra_postconditions).
@@ -25,17 +18,13 @@
-include("hipe_sparc.hrl").
-check_and_rewrite(Defun, Coloring, Allocator) ->
- TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific),
- check_and_rewrite2(Defun, TempMap, Allocator).
+check_and_rewrite(CFG, Coloring, Allocator) ->
+ TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific, no_context),
+ check_and_rewrite2(CFG, TempMap, Allocator).
-check_and_rewrite2(Defun, TempMap, Allocator) ->
+check_and_rewrite2(CFG, TempMap, Allocator) ->
Strategy = strategy(Allocator),
- #defun{code=Code0} = Defun,
- {Code1,DidSpill} = do_insns(Code0, TempMap, Strategy, [], false),
- VarRange = {0, hipe_gensym:get_var(sparc)},
- {Defun#defun{code=Code1, var_range=VarRange},
- DidSpill}.
+ do_bbs(hipe_sparc_cfg:labels(CFG), TempMap, Strategy, CFG, false).
strategy(Allocator) ->
case Allocator of
@@ -44,6 +33,13 @@ strategy(Allocator) ->
'naive' -> 'fixed'
end.
+do_bbs([], _, _, CFG, DidSpill) -> {CFG, DidSpill};
+do_bbs([Lbl|Lbls], TempMap, Strategy, CFG0, DidSpill0) ->
+ Code0 = hipe_bb:code(BB = hipe_sparc_cfg:bb(CFG0, Lbl)),
+ {Code, DidSpill} = do_insns(Code0, TempMap, Strategy, [], DidSpill0),
+ CFG = hipe_sparc_cfg:bb_add(CFG0, Lbl, hipe_bb:code_update(BB, Code)),
+ do_bbs(Lbls, TempMap, Strategy, CFG, DidSpill).
+
do_insns([I|Insns], TempMap, Strategy, Accum, DidSpill0) ->
{NewIs, DidSpill1} = do_insn(I, TempMap, Strategy),
do_insns(Insns, TempMap, Strategy, lists:reverse(NewIs, Accum), DidSpill0 or DidSpill1);
@@ -58,6 +54,7 @@ do_insn(I, TempMap, Strategy) ->
#pseudo_call{} -> do_pseudo_call(I, TempMap, Strategy);
#pseudo_move{} -> do_pseudo_move(I, TempMap, Strategy);
#pseudo_set{} -> do_pseudo_set(I, TempMap, Strategy);
+ #pseudo_spill_move{} -> do_pseudo_spill_move(I, TempMap, Strategy);
#pseudo_tailcall{} -> do_pseudo_tailcall(I, TempMap, Strategy);
#rdy{} -> do_rdy(I, TempMap, Strategy);
#sethi{} -> do_sethi(I, TempMap, Strategy);
@@ -96,14 +93,16 @@ do_pseudo_call(I=#pseudo_call{funv=FunV}, TempMap, Strategy) ->
do_pseudo_move(I=#pseudo_move{src=Src,dst=Dst}, TempMap, Strategy) ->
%% Either Dst or Src (but not both) may be a pseudo temp.
- %% pseudo_move is a special case: in [XXX: not pseudo_tailcall]
- %% all other instructions, all temps must be non-pseudos
- %% after register allocation.
- case temp_is_spilled(Dst, TempMap) of
- true -> % Src must not be a pseudo
- {FixSrc,NewSrc,DidSpill} = fix_src1(Src, TempMap, Strategy),
- NewI = I#pseudo_move{src=NewSrc},
- {FixSrc ++ [NewI], DidSpill};
+ %% pseudo_move and pseudo_spill_move [XXX: not pseudo_tailcall]
+ %% are special cases: in all other instructions, all temps must
+ %% be non-pseudos after register allocation.
+ case temp_is_spilled(Src, TempMap)
+ andalso temp_is_spilled(Dst, TempMap)
+ of
+ true -> % Turn into pseudo_spill_move
+ Temp = clone(Src, temp1(Strategy)),
+ NewI = #pseudo_spill_move{src=Src,temp=Temp,dst=Dst},
+ {[NewI], true};
_ ->
{[I], false}
end.
@@ -113,6 +112,11 @@ do_pseudo_set(I=#pseudo_set{dst=Dst}, TempMap, Strategy) ->
NewI = I#pseudo_set{dst=NewDst},
{[NewI | FixDst], DidSpill}.
+do_pseudo_spill_move(I=#pseudo_spill_move{temp=Temp}, TempMap, _Strategy) ->
+ %% Temp is above the low water mark and must not have been spilled
+ false = temp_is_spilled(Temp, TempMap),
+ {[I], false}.
+
do_pseudo_tailcall(I=#pseudo_tailcall{funv=FunV}, TempMap, Strategy) ->
{FixFunV,NewFunV,DidSpill} = fix_funv(FunV, TempMap, Strategy),
NewI = I#pseudo_tailcall{funv=NewFunV},
diff --git a/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl b/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
index d893ac26e9..5fa3a5fc59 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_ra_postconditions_fp).
@@ -25,13 +18,17 @@
-include("hipe_sparc.hrl").
-check_and_rewrite(Defun, Coloring) ->
- TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific_fp),
- #defun{code=Code0} = Defun,
- {Code1,DidSpill} = do_insns(Code0, TempMap, [], false),
- VarRange = {0, hipe_gensym:get_var(sparc)},
- {Defun#defun{code=Code1, var_range=VarRange},
- DidSpill}.
+check_and_rewrite(CFG, Coloring) ->
+ TempMap = hipe_temp_map:cols2tuple(Coloring, hipe_sparc_specific_fp,
+ no_context),
+ do_bbs(hipe_sparc_cfg:labels(CFG), TempMap, CFG, false).
+
+do_bbs([], _TempMap, CFG, DidSpill) -> {CFG, DidSpill};
+do_bbs([Lbl|Lbls], TempMap, CFG0, DidSpill0) ->
+ Code0 = hipe_bb:code(BB = hipe_sparc_cfg:bb(CFG0, Lbl)),
+ {Code, DidSpill} = do_insns(Code0, TempMap, [], DidSpill0),
+ CFG = hipe_sparc_cfg:bb_add(CFG0, Lbl, hipe_bb:code_update(BB, Code)),
+ do_bbs(Lbls, TempMap, CFG, DidSpill).
do_insns([I|Insns], TempMap, Accum, DidSpill0) ->
{NewIs, DidSpill1} = do_insn(I, TempMap),
@@ -46,6 +43,7 @@ do_insn(I, TempMap) ->
#pseudo_fload{} -> do_pseudo_fload(I, TempMap);
#pseudo_fmove{} -> do_pseudo_fmove(I, TempMap);
#pseudo_fstore{} -> do_pseudo_fstore(I, TempMap);
+ #pseudo_spill_fmove{} -> do_pseudo_spill_fmove(I, TempMap);
_ -> {[I], false}
end.
@@ -70,11 +68,13 @@ do_pseudo_fload(I=#pseudo_fload{dst=Dst}, TempMap) ->
{[NewI | FixDst], DidSpill}.
do_pseudo_fmove(I=#pseudo_fmove{src=Src,dst=Dst}, TempMap) ->
- case temp_is_spilled(Dst, TempMap) of
- true ->
- {FixSrc,NewSrc,DidSpill} = fix_src(Src, TempMap),
- NewI = I#pseudo_fmove{src=NewSrc},
- {FixSrc ++ [NewI], DidSpill};
+ case temp_is_spilled(Src, TempMap)
+ andalso temp_is_spilled(Dst, TempMap)
+ of
+ true -> % Turn into pseudo_spill_fmove
+ Temp = clone(Src),
+ NewI = #pseudo_spill_fmove{src=Src,temp=Temp,dst=Dst},
+ {[NewI], true};
_ ->
{[I], false}
end.
@@ -84,6 +84,11 @@ do_pseudo_fstore(I=#pseudo_fstore{src=Src}, TempMap) ->
NewI = I#pseudo_fstore{src=NewSrc},
{FixSrc ++ [NewI], DidSpill}.
+do_pseudo_spill_fmove(I=#pseudo_spill_fmove{temp=Temp}, TempMap) ->
+ %% Temp is above the low water mark and must not have been spilled
+ false = temp_is_spilled(Temp, TempMap),
+ {[I], false}.
+
%%% Fix Dst and Src operands.
fix_src(Src, TempMap) ->
diff --git a/lib/hipe/sparc/hipe_sparc_registers.erl b/lib/hipe/sparc/hipe_sparc_registers.erl
index 884215702b..47876e21d2 100644
--- a/lib/hipe/sparc/hipe_sparc_registers.erl
+++ b/lib/hipe/sparc/hipe_sparc_registers.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_registers).
@@ -86,6 +79,8 @@
-define(I7, 31).
-define(LAST_PRECOLOURED,31). % must handle both GRP and FPR ranges
+-define(RA, ?O7).
+
-define(ARG0, ?O1).
-define(ARG1, ?O2).
-define(ARG2, ?O3).
@@ -174,7 +169,7 @@ stack_pointer() -> ?STACK_POINTER.
proc_pointer() -> ?PROC_POINTER.
-return_address() -> ?O7.
+return_address() -> ?RA.
g0() -> ?G0.
@@ -247,6 +242,8 @@ is_arg(R) ->
_ -> false
end.
+%% Note: the fact that allocatable_gpr() is a subset of call_clobbered() is
+%% hard-coded in hipe_sparc_defuse:insn_defs_all_gpr/1
call_clobbered() -> % does the RA strip the type or not?
[%% ?G0 is the non-allocatable constant zero
{?G1,tagged},{?G1,untagged},
@@ -283,7 +280,9 @@ call_clobbered() -> % does the RA strip the type or not?
].
tailcall_clobbered() -> % tailcall crapola needs one temp
- [{?TEMP1,tagged},{?TEMP1,untagged}].
+ [{?TEMP1,tagged},{?TEMP1,untagged}
+ ,{?RA,tagged},{?RA,untagged}
+ ].
live_at_return() ->
[{?HEAP_POINTER,untagged},
diff --git a/lib/hipe/sparc/hipe_sparc_subst.erl b/lib/hipe/sparc/hipe_sparc_subst.erl
new file mode 100644
index 0000000000..ce3bbb813a
--- /dev/null
+++ b/lib/hipe/sparc/hipe_sparc_subst.erl
@@ -0,0 +1,82 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+-module(hipe_sparc_subst).
+-export([insn_temps/2]).
+-include("hipe_sparc.hrl").
+
+%% These should be moved to hipe_sparc and exported
+-type temp() :: #sparc_temp{}.
+-type src2() :: temp() | #sparc_simm13{}.
+-type src2b() :: src2() | #sparc_uimm5{}.
+-type funv() :: #sparc_mfa{} | #sparc_prim{} | temp().
+-type arg() :: temp() | integer().
+-type insn() :: tuple(). % for now
+
+-type subst_fun() :: fun((temp()) -> temp()).
+
+%% @doc Maps over the temporaries in an instruction
+-spec insn_temps(subst_fun(), insn()) -> insn().
+insn_temps(T, I) ->
+ S2 = fun(O) -> src2_temps(T, O) end,
+ S2B = fun(O) -> src2b_temps(T, O) end,
+ Arg = fun(O) -> arg_temps(T, O) end,
+ case I of
+ #alu{src1=L,src2=R,dst=D} -> I#alu{src1=T(L),src2=S2B(R),dst=T(D)};
+ #bp{} -> I;
+ #comment{} -> I;
+ #jmp{src1=L,src2=R} -> I#jmp{src1=T(L),src2=S2(R)};
+ #label{} -> I;
+ #pseudo_bp{} -> I;
+ #pseudo_call{funv=F} -> I#pseudo_call{funv=funv_temps(T,F)};
+ #pseudo_call_prepare{} -> I;
+ #pseudo_move{src=S,dst=D} -> I#pseudo_move{src=T(S),dst=T(D)};
+ #pseudo_ret{} -> I;
+ #pseudo_set{dst=D}-> I#pseudo_set{dst=T(D)};
+ #pseudo_spill_move{src=S,temp=U,dst=D} ->
+ I#pseudo_spill_move{src=T(S),temp=T(U),dst=T(D)};
+ #pseudo_tailcall{funv=F,stkargs=Stk} ->
+ I#pseudo_tailcall{funv=funv_temps(T,F),stkargs=lists:map(Arg,Stk)};
+ #pseudo_tailcall_prepare{} -> I;
+ #rdy{dst=D} -> I#rdy{dst=T(D)};
+ #sethi{dst=D} -> I#sethi{dst=T(D)};
+ #store{src=S,base=B,disp=D} -> I#store{src=T(S),base=T(B),disp=S2(D)};
+ #fp_binary{src1=L,src2=R,dst=D} ->
+ I#fp_binary{src1=T(L),src2=T(R),dst=T(D)};
+ #fp_unary{src=S,dst=D} -> I#fp_unary{src=T(S),dst=T(D)};
+ #pseudo_fload{base=B,disp=Di,dst=Ds} ->
+ I#pseudo_fload{base=T(B),disp=S2(Di),dst=T(Ds)};
+ #pseudo_fmove{src=S,dst=D} -> I#pseudo_fmove{src=T(S),dst=T(D)};
+ #pseudo_fstore{src=S,base=B,disp=D} ->
+ I#pseudo_fstore{src=T(S),base=T(B),disp=S2(D)};
+ #pseudo_spill_fmove{src=S,temp=U,dst=D} ->
+ I#pseudo_spill_fmove{src=T(S),temp=T(U),dst=T(D)}
+ end.
+
+-spec src2_temps(subst_fun(), src2()) -> src2().
+src2_temps(_SubstTemp, I=#sparc_simm13{}) -> I;
+src2_temps(SubstTemp, T=#sparc_temp{}) -> SubstTemp(T).
+
+-spec src2b_temps(subst_fun(), src2b()) -> src2b().
+src2b_temps(_SubstTemp, I=#sparc_uimm5{}) -> I;
+src2b_temps(SubstTemp, Op) -> src2_temps(SubstTemp, Op).
+
+-spec funv_temps(subst_fun(), funv()) -> funv().
+funv_temps(_SubstTemp, M=#sparc_mfa{}) -> M;
+funv_temps(_SubstTemp, P=#sparc_prim{}) -> P;
+funv_temps(SubstTemp, T=#sparc_temp{}) -> SubstTemp(T).
+
+-spec arg_temps(subst_fun(), arg()) -> arg().
+arg_temps(_SubstTemp, Imm) when is_integer(Imm) -> Imm;
+arg_temps(SubstTemp, T=#sparc_temp{}) -> SubstTemp(T).
diff --git a/lib/hipe/ssa/hipe_ssa.inc b/lib/hipe/ssa/hipe_ssa.inc
index 83ab320306..c7c1a8e1d7 100644
--- a/lib/hipe/ssa/hipe_ssa.inc
+++ b/lib/hipe/ssa/hipe_ssa.inc
@@ -1,9 +1,5 @@
-%% -*- erlang-indent-level: 2 -*-
+%% -*- mode: erlang; erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_ssa.inc
@@ -943,9 +937,9 @@ do_code([Instr|Instrs], LiveOut, Changed, Acc) ->
false ->
do_code(Instrs, LiveIn, Changed, [Instr|Acc]);
true ->
- case ?CODE:is_safe(Instr) of
+ case ?CODE:is_call(Instr) of
true ->
- case ?CODE:is_call(Instr) of
+ case ?CODE:is_safe(Instr) of
true ->
case ?CODE:call_continuation(Instr) of
[] ->
@@ -955,11 +949,6 @@ do_code([Instr|Instrs], LiveOut, Changed, Acc) ->
do_code(Instrs, LiveOut, true, [NewInstr|Acc])
end;
false ->
- do_code(Instrs, LiveOut, true, Acc)
- end;
- false -> %% not a safe instruction - cannot be removed
- case ?CODE:is_call(Instr) of
- true ->
case ?CODE:call_dstlist(Instr) of
[] -> %% result was not used anyway; no change
do_code(Instrs, LiveIn, Changed, [Instr|Acc]);
@@ -968,9 +957,14 @@ do_code([Instr|Instrs], LiveOut, Changed, Acc) ->
do_code(Instrs, LiveIn, true, [NewInstr|Acc]);
[_|_] -> %% calls with multiple dests are left untouched
do_code(Instrs, LiveIn, Changed, [Instr|Acc])
- end;
- false ->
- do_code(Instrs, LiveIn, Changed, [Instr|Acc])
+ end
+ end;
+ false ->
+ case ?CODE:reduce_unused(Instr) of
+ false -> % not a safe instruction - cannot be removed
+ do_code(Instrs, LiveIn, Changed, [Instr|Acc]);
+ Replacement ->
+ do_code(lists:reverse(Replacement, Instrs), LiveOut, true, Acc)
end
end
end;
diff --git a/lib/hipe/ssa/hipe_ssa_const_prop.inc b/lib/hipe/ssa/hipe_ssa_const_prop.inc
index 648490f9a3..9c157e0833 100644
--- a/lib/hipe/ssa/hipe_ssa_const_prop.inc
+++ b/lib/hipe/ssa/hipe_ssa_const_prop.inc
@@ -1,10 +1,6 @@
%% -*- Erlang -*-
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-----------------------------------------------------------------------------
%% File : hipe_ssa_const_prop.inc
diff --git a/lib/hipe/ssa/hipe_ssa_copy_prop.inc b/lib/hipe/ssa/hipe_ssa_copy_prop.inc
index fd80d97b02..8677263213 100644
--- a/lib/hipe/ssa/hipe_ssa_copy_prop.inc
+++ b/lib/hipe/ssa/hipe_ssa_copy_prop.inc
@@ -1,10 +1,6 @@
%%% -*- Erlang -*-
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_ssa_copy_prop.inc
diff --git a/lib/hipe/ssa/hipe_ssa_liveness.inc b/lib/hipe/ssa/hipe_ssa_liveness.inc
index 78488c65fc..a1b49d5d35 100644
--- a/lib/hipe/ssa/hipe_ssa_liveness.inc
+++ b/lib/hipe/ssa/hipe_ssa_liveness.inc
@@ -1,10 +1,6 @@
%% -*- Erlang -*-
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -40,6 +34,15 @@
ssa_liveness__livein/2]).
%% ssa_liveness__livein/3],
%% ssa_liveness__liveout/2]).
+-type set(E) :: gb_sets:set(E).
+-type liveness(Label, Var) ::
+ #{Label => {{Gen :: set(Var),
+ Kill :: set(Var),
+ {TotalDirGen :: set(Var),
+ DirGen :: gb_trees:tree(Label, set(Var))}},
+ LiveIn :: set(Var),
+ LiveOut :: set(Var),
+ Successors :: [Label]}}.
-endif.
%% -ifdef(DEBUG_LIVENESS).
%% -export([pp_liveness/1]).
@@ -262,21 +265,15 @@ update_directed_gen({Pred, Var}, Map)->
%%
%% liveness
%%
+-compile({inline, [liveness_lookup/2, liveness_update/3]}).
liveness_init(List) ->
- liveness_init1(List, gb_trees:empty()).
+ maps:from_list(List).
-liveness_init1([{Label, Info}|Left], Map) ->
- liveness_init1(Left, gb_trees:insert(Label, Info, Map));
-liveness_init1([], Map) ->
- Map.
-
-liveness_lookup(Label, Map) ->
- {value, Info} = gb_trees:lookup(Label, Map),
- Info.
-
-liveness_update(Label, NewInfo, Map) ->
- gb_trees:update(Label, NewInfo, Map).
+liveness_lookup(Label, Liveness) ->
+ maps:get(Label, Liveness).
+liveness_update(Label, Val, Liveness) ->
+ maps:update(Label, Val, Liveness).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl b/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl
index caa0e71d0b..430e097b91 100644
--- a/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl
+++ b/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl
@@ -18,6 +18,7 @@ test() ->
ok = test_R12B5_seg_fault(),
ok = test_switch_neg_int(),
ok = test_icode_range_anal(),
+ ok = test_icode_range_call(),
ok.
%%-----------------------------------------------------------------------
@@ -461,3 +462,44 @@ g(X, Z) ->
test -> non_zero_test;
other -> other
end.
+
+%%-----------------------------------------------------------------------
+%% From: Rich Neswold
+%% Date: Oct 5, 2016
+%%
+%% The following was a bug in the HiPE compiler's range analysis. The
+%% function range_client/2 below would would not stop when N reached 0,
+%% but keep recursing into the second clause forever.
+%%
+%% The problem turned out to be in hipe_icode_range:analyse_call/2,
+%% which would note update the argument ranges of the callee if the
+%% result of the call was ignored.
+%% -----------------------------------------------------------------------
+-define(TIMEOUT, 42).
+
+test_icode_range_call() ->
+ Self = self(),
+ Client = spawn_link(fun() -> range_client(Self, 4) end),
+ range_server(4, Client).
+
+range_server(0, _Client) ->
+ receive
+ stopping -> ok;
+ {called_with, 0} -> error(failure)
+ after ?TIMEOUT -> error(timeout)
+ end;
+range_server(N, Client) ->
+ receive
+ {called_with, N} ->
+ Client ! proceed
+ after ?TIMEOUT -> error(timeout)
+ end,
+ range_server(N-1, Client). % tailcall (so the bug does not affect it)
+
+range_client(Server, 0) ->
+ Server ! stopping;
+range_client(Server, N) ->
+ Server ! {called_with, N},
+ receive proceed -> ok end,
+ range_client(Server, N - 1), % non-tailrecursive call with ignored result
+ ok.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_edge_cases.erl b/lib/hipe/test/basic_SUITE_data/basic_edge_cases.erl
new file mode 100644
index 0000000000..9bf5cf52cd
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_edge_cases.erl
@@ -0,0 +1,142 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%----------------------------------------------------------------------
+%%% Contains
+%%%----------------------------------------------------------------------
+-module(basic_edge_cases).
+
+-export([test/0]).
+
+test() ->
+ ok = test_float_spills(),
+ ok = test_infinite_loops(),
+ ok.
+
+%% Contains more float temps live at a single point than there are float
+%% registers in any backend
+
+test_float_spills() ->
+ {{{2942.0,4670.0,3198.0,4926.0,2206.0,4734.0},
+ {3118.0,2062.0,5174.0,3038.0,3618.0,3014.0},
+ {2542.0,2062.0,4934.0,2590.0,3098.0,3062.0},
+ {2950.0,3666.0,2574.0,5038.0,1866.0,2946.0},
+ {3126.0,3050.0,3054.0,5070.0,2258.0,2714.0},
+ {4734.0,2206.0,4926.0,3198.0,4670.0,2942.0}},
+ 58937.0} =
+ mat66_flip_sum(35.0,86.0,32.0,88.0,33.0,57.0,
+ 22.0,77.0,91.0,80.0,14.0,33.0,
+ 51.0,28.0,87.0,20.0,91.0,11.0,
+ 68.0,83.0,64.0,82.0,10.0,86.0,
+ 74.0,18.0,08.0,52.0,10.0,14.0,
+ 89.0,34.0,64.0,66.0,58.0,55.0,
+ 0.0, 5),
+ ok.
+
+mat66_flip_sum(M11, M12, M13, M14, M15, M16,
+ M21, M22, M23, M24, M25, M26,
+ M31, M32, M33, M34, M35, M36,
+ M41, M42, M43, M44, M45, M46,
+ M51, M52, M53, M54, M55, M56,
+ M61, M62, M63, M64, M65, M66,
+ Acc, Ctr)
+ when is_float(M11), is_float(M12), is_float(M13),
+ is_float(M14), is_float(M15), is_float(M16),
+ is_float(M21), is_float(M22), is_float(M23),
+ is_float(M24), is_float(M25), is_float(M26),
+ is_float(M31), is_float(M32), is_float(M33),
+ is_float(M34), is_float(M35), is_float(M36),
+ is_float(M41), is_float(M42), is_float(M43),
+ is_float(M44), is_float(M45), is_float(M46),
+ is_float(M51), is_float(M52), is_float(M53),
+ is_float(M54), is_float(M55), is_float(M56),
+ is_float(M61), is_float(M62), is_float(M63),
+ is_float(M64), is_float(M65), is_float(M66),
+ is_float(Acc) ->
+ R11 = M66+M11, R12 = M65+M12, R13 = M64+M13,
+ R14 = M63+M14, R15 = M62+M15, R16 = M61+M16,
+ R21 = M56+M21, R22 = M55+M22, R23 = M54+M23,
+ R24 = M53+M24, R25 = M52+M25, R26 = M51+M26,
+ R31 = M46+M31, R32 = M45+M32, R33 = M44+M33,
+ R34 = M43+M34, R35 = M42+M35, R36 = M41+M36,
+ R41 = M26+M41, R42 = M25+M42, R43 = M24+M43,
+ R44 = M23+M44, R45 = M22+M45, R46 = M21+M46,
+ R51 = M36+M51, R52 = M35+M52, R53 = M34+M53,
+ R54 = M33+M54, R55 = M32+M55, R56 = M31+M56,
+ R61 = M16+M61, R62 = M15+M62, R63 = M14+M63,
+ R64 = M13+M64, R65 = M12+M65, R66 = M11+M66,
+ case Ctr of
+ 0 ->
+ {{{R11, R12, R13, R14, R15, R16},
+ {R21, R22, R23, R24, R25, R26},
+ {R31, R32, R33, R34, R35, R36},
+ {R41, R42, R43, R44, R45, R46},
+ {R51, R52, R53, R54, R55, R56},
+ {R61, R62, R63, R64, R65, R66}},
+ Acc};
+ _ ->
+ NewAcc = 0.0 + M11 + M12 + M13 + M14 + M15 + M16 +
+ + M21 + M22 + M23 + M24 + M25 + M26
+ + M31 + M32 + M33 + M34 + M35 + M36
+ + M41 + M42 + M43 + M44 + M45 + M46
+ + M51 + M52 + M53 + M54 + M55 + M56
+ + M61 + M62 + M63 + M64 + M65 + M66
+ + Acc,
+ mat66_flip_sum(R11+1.0, R12+1.0, R13+1.0, R14+1.0, R15+1.0, R16+1.0,
+ R21+1.0, R22+1.0, R23+1.0, R24+1.0, R25+1.0, R26+1.0,
+ R31+1.0, R32+1.0, R33+1.0, R34+1.0, R35+1.0, R36+1.0,
+ R41+1.0, R42+1.0, R43+1.0, R44+1.0, R45+1.0, R46+1.0,
+ R51+1.0, R52+1.0, R53+1.0, R54+1.0, R55+1.0, R56+1.0,
+ R61+1.0, R62+1.0, R63+1.0, R64+1.0, R65+1.0, R66+1.0,
+ NewAcc, Ctr-1)
+ end.
+
+%% Infinite loops must receive reduction tests, and might trip up basic block
+%% weighting, leading to infinite weights and/or divisions by zero.
+
+test_infinite_loops() ->
+ OldTrapExit = process_flag(trap_exit, true),
+ ok = test_infinite_loop(fun infinite_recursion/0),
+ ok = test_infinite_loop(fun infinite_corecursion/0),
+ RecursiveFun = fun RecursiveFun() -> RecursiveFun() end,
+ ok = test_infinite_loop(RecursiveFun),
+ CorecursiveFunA = fun CorecursiveFunA() ->
+ CorecursiveFunA1 = fun () -> CorecursiveFunA() end,
+ CorecursiveFunA1()
+ end,
+ ok = test_infinite_loop(CorecursiveFunA),
+ CorecursiveFunB1 = fun(CorecursiveFunB) -> CorecursiveFunB() end,
+ CorecursiveFunB = fun CorecursiveFunB() ->
+ CorecursiveFunB1(CorecursiveFunB)
+ end,
+ ok = test_infinite_loop(CorecursiveFunB),
+ CorecursiveFunC1 = fun CorecursiveFunC1(Other) ->
+ Other(CorecursiveFunC1)
+ end,
+ CorecursiveFunC = fun CorecursiveFunC(Other) ->
+ Other(CorecursiveFunC)
+ end,
+ ok = test_infinite_loop(fun() -> CorecursiveFunC(CorecursiveFunC1) end),
+ ok = test_infinite_loop(fun() -> CorecursiveFunC(CorecursiveFunC) end),
+ true = process_flag(trap_exit, OldTrapExit),
+ ok.
+
+-define(INFINITE_LOOP_TIMEOUT, 100).
+test_infinite_loop(Fun) ->
+ Tester = spawn_link(Fun),
+ kill_soon(Tester),
+ receive {'EXIT', Tester, awake} ->
+ undefined = process_info(Tester),
+ ok
+ after ?INFINITE_LOOP_TIMEOUT -> error(timeout)
+ end.
+
+infinite_recursion() -> infinite_recursion().
+
+infinite_corecursion() -> infinite_corecursion_1().
+infinite_corecursion_1() -> infinite_corecursion().
+
+kill_soon(Pid) ->
+ _ = spawn_link(fun() ->
+ timer:sleep(1),
+ erlang:exit(Pid, awake)
+ end),
+ ok.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_num_bif.erl b/lib/hipe/test/basic_SUITE_data/basic_num_bif.erl
new file mode 100644
index 0000000000..807c4b0d0d
--- /dev/null
+++ b/lib/hipe/test/basic_SUITE_data/basic_num_bif.erl
@@ -0,0 +1,217 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%-------------------------------------------------------------------
+%%% File : basic_num_bif.erl
+%%% Description : Taken from the compiler test suite
+%%%-------------------------------------------------------------------
+-module(basic_num_bif).
+
+-export([test/0]).
+
+%% Tests optimization of the BIFs:
+%% abs/1
+%% float/1
+%% float_to_list/1
+%% integer_to_list/1
+%% list_to_float/1
+%% list_to_integer/1
+%% round/1
+%% trunc/1
+
+test() ->
+ Funs = [fun t_abs/0, fun t_float/0,
+ fun t_float_to_list/0, fun t_integer_to_list/0,
+ fun t_list_to_float_safe/0, fun t_list_to_float_risky/0,
+ fun t_list_to_integer/0, fun t_round/0, fun t_trunc/0],
+ lists:foreach(fun (F) -> ok = F() end, Funs).
+
+t_abs() ->
+ %% Floats.
+ 5.5 = abs(5.5),
+ 0.0 = abs(0.0),
+ 100.0 = abs(-100.0),
+ %% Integers.
+ 5 = abs(5),
+ 0 = abs(0),
+ 100 = abs(-100),
+ %% The largest smallnum. OTP-3190.
+ X = (1 bsl 27) - 1,
+ X = abs(X),
+ X = abs(X-1)+1,
+ X = abs(X+1)-1,
+ X = abs(-X),
+ X = abs(-X-1)-1,
+ X = abs(-X+1)+1,
+ %% Bignums.
+ BigNum = 13984792374983749,
+ BigNum = abs(BigNum),
+ BigNum = abs(-BigNum),
+ ok.
+
+t_float() ->
+ 0.0 = float(0),
+ 2.5 = float(2.5),
+ 0.0 = float(0.0),
+ -100.55 = float(-100.55),
+ 42.0 = float(42),
+ -100.0 = float(-100),
+ %% Bignums.
+ 4294967305.0 = float(4294967305),
+ -4294967305.0 = float(-4294967305),
+ %% Extremely big bignums.
+ Big = list_to_integer(lists:duplicate(2000, $1)),
+ {'EXIT', {badarg, _}} = (catch float(Big)),
+ ok.
+
+%% Tests float_to_list/1.
+
+t_float_to_list() ->
+ test_ftl("0.0e+0", 0.0),
+ test_ftl("2.5e+1", 25.0),
+ test_ftl("2.5e+0", 2.5),
+ test_ftl("2.5e-1", 0.25),
+ test_ftl("-3.5e+17", -350.0e15),
+ ok.
+
+test_ftl(Expect, Float) ->
+ %% No on the next line -- we want the line number from t_float_to_list.
+ Expect = remove_zeros(lists:reverse(float_to_list(Float)), []).
+
+%% Removes any non-significant zeros in a floating point number.
+%% Example: 2.500000e+01 -> 2.5e+1
+
+remove_zeros([$+, $e|Rest], [$0, X|Result]) ->
+ remove_zeros([$+, $e|Rest], [X|Result]);
+remove_zeros([$-, $e|Rest], [$0, X|Result]) ->
+ remove_zeros([$-, $e|Rest], [X|Result]);
+remove_zeros([$0, $.|Rest], [$e|Result]) ->
+ remove_zeros(Rest, [$., $0, $e|Result]);
+remove_zeros([$0|Rest], [$e|Result]) ->
+ remove_zeros(Rest, [$e|Result]);
+remove_zeros([Char|Rest], Result) ->
+ remove_zeros(Rest, [Char|Result]);
+remove_zeros([], Result) ->
+ Result.
+
+%% Tests integer_to_list/1.
+
+t_integer_to_list() ->
+ "0" = integer_to_list(0),
+ "42" = integer_to_list(42),
+ "-42" = integer_to_list(-42),
+ "-42" = integer_to_list(-42),
+ "32768" = integer_to_list(32768),
+ "268435455" = integer_to_list(268435455),
+ "-268435455" = integer_to_list(-268435455),
+ "123456932798748738738" = integer_to_list(123456932798748738738),
+ Big_List = lists:duplicate(2000, $1),
+ Big = list_to_integer(Big_List),
+ Big_List = integer_to_list(Big),
+ ok.
+
+%% Tests list_to_float/1.
+
+t_list_to_float_safe() ->
+ 0.0 = list_to_float("0.0"),
+ 0.0 = list_to_float("-0.0"),
+ 0.5 = list_to_float("0.5"),
+ -0.5 = list_to_float("-0.5"),
+ 100.0 = list_to_float("1.0e2"),
+ 127.5 = list_to_float("127.5"),
+ -199.5 = list_to_float("-199.5"),
+ ok.
+
+%% This might crash the emulator...
+%% (Known to crash the Unix version of Erlang 4.4.1)
+
+t_list_to_float_risky() ->
+ Many_Ones = lists:duplicate(25000, $1),
+ _ = list_to_float("2."++Many_Ones),
+ {'EXIT', {badarg, _}} = (catch list_to_float("2"++Many_Ones)),
+ ok.
+
+%% Tests list_to_integer/1.
+
+t_list_to_integer() ->
+ 0 = list_to_integer("0"),
+ 0 = list_to_integer("00"),
+ 0 = list_to_integer("-0"),
+ 1 = list_to_integer("1"),
+ -1 = list_to_integer("-1"),
+ 42 = list_to_integer("42"),
+ -12 = list_to_integer("-12"),
+ 32768 = list_to_integer("32768"),
+ 268435455 = list_to_integer("268435455"),
+ -268435455 = list_to_integer("-268435455"),
+ %% Bignums.
+ 123456932798748738738 = list_to_integer("123456932798748738738"),
+ _ = list_to_integer(lists:duplicate(2000, $1)),
+ ok.
+
+%% Tests round/1.
+
+t_round() ->
+ 0 = round(0.0),
+ 0 = round(0.4),
+ 1 = round(0.5),
+ 0 = round(-0.4),
+ -1 = round(-0.5),
+ 255 = round(255.3),
+ 256 = round(255.6),
+ -1033 = round(-1033.3),
+ -1034 = round(-1033.6),
+ %% OTP-3722:
+ X = (1 bsl 27) - 1,
+ MX = -X,
+ MXm1 = -X-1,
+ MXp1 = -X+1,
+ F = X + 0.0,
+ X = round(F),
+ X = round(F+1)-1,
+ X = round(F-1)+1,
+ MX = round(-F),
+ MXm1 = round(-F-1),
+ MXp1 = round(-F+1),
+ X = round(F+0.1),
+ X = round(F+1+0.1)-1,
+ X = round(F-1+0.1)+1,
+ MX = round(-F+0.1),
+ MXm1 = round(-F-1+0.1),
+ MXp1 = round(-F+1+0.1),
+ X = round(F-0.1),
+ X = round(F+1-0.1)-1,
+ X = round(F-1-0.1)+1,
+ MX = round(-F-0.1),
+ MXm1 = round(-F-1-0.1),
+ MXp1 = round(-F+1-0.1),
+ 0.5 = abs(round(F+0.5)-(F+0.5)),
+ 0.5 = abs(round(F-0.5)-(F-0.5)),
+ 0.5 = abs(round(-F-0.5)-(-F-0.5)),
+ 0.5 = abs(round(-F+0.5)-(-F+0.5)),
+ %% Bignums.
+ 4294967296 = round(4294967296.1),
+ 4294967297 = round(4294967296.9),
+ -4294967296 = -round(4294967296.1),
+ -4294967297 = -round(4294967296.9),
+ ok.
+
+t_trunc() ->
+ 0 = trunc(0.0),
+ 5 = trunc(5.3333),
+ -10 = trunc(-10.978987),
+ %% The largest smallnum, converted to float (OTP-3722):
+ X = (1 bsl 27) - 1,
+ F = X + 0.0,
+ %% io:format("X = ~p/~w/~w, F = ~p/~w/~w, trunc(F) = ~p/~w/~w~n",
+ %% [X, X, binary_to_list(term_to_binary(X)),
+ %% F, F, binary_to_list(term_to_binary(F)),
+ %% trunc(F), trunc(F), binary_to_list(term_to_binary(trunc(F)))]),
+ X = trunc(F),
+ X = trunc(F+1)-1,
+ X = trunc(F-1)+1,
+ X = -trunc(-F),
+ X = -trunc(-F-1)-1,
+ X = -trunc(-F+1)+1,
+ %% Bignums.
+ 4294967305 = trunc(4294967305.7),
+ -4294967305 = trunc(-4294967305.7),
+ ok.
diff --git a/lib/hipe/test/basic_SUITE_data/basic_tuples.erl b/lib/hipe/test/basic_SUITE_data/basic_tuples.erl
index 94c187e364..96e39d565a 100644
--- a/lib/hipe/test/basic_SUITE_data/basic_tuples.erl
+++ b/lib/hipe/test/basic_SUITE_data/basic_tuples.erl
@@ -55,6 +55,8 @@ test_element(T0, T1, T2, N) ->
List = lists:seq(1, N),
Tuple = list_to_tuple(List),
ok = get_elements(List, Tuple, 1),
+ %% element/2 of larger tuple with omitted bounds test
+ true = lists:all(fun(I) -> I * I =:= square(I) end, lists:seq(1, 20)),
%% some cases that throw exceptions
{'EXIT', _} = (catch my_element(0, T2)),
{'EXIT', _} = (catch my_element(3, T2)),
@@ -73,6 +75,18 @@ get_elements([Element|Rest], Tuple, Pos) ->
get_elements([], _Tuple, _Pos) ->
ok.
+squares() ->
+ {1*1, 2*2, 3*3, 4*4, 5*5, 6*6, 7*7, 8*8, 9*9, 10*10,
+ 11*11, 12*12, 13*13, 14*14, 15*15, 16*16, 17*17, 18*18, 19*19, 20*20}.
+
+square(N) when is_integer(N), N >= 1, N =< 20 ->
+ %% The guard tests lets the range analysis conclude N to be an integer in the
+ %% 1..20 range. 20-1=19 is bigger than ?SET_LIMIT in erl_types.erl, and will
+ %% thus be represented by an ?int_range() rather than an ?int_set().
+ %% Because of the range analysis, the bounds test of this element/2 call
+ %% should be omitted.
+ element(N, squares()).
+
%%--------------------------------------------------------------------
%% Tests set_element/3.
diff --git a/lib/hipe/test/bs_SUITE_data/bs_pmatch_bugs.erl b/lib/hipe/test/bs_SUITE_data/bs_pmatch_bugs.erl
index b280705a47..d9f3278b45 100644
--- a/lib/hipe/test/bs_SUITE_data/bs_pmatch_bugs.erl
+++ b/lib/hipe/test/bs_SUITE_data/bs_pmatch_bugs.erl
@@ -9,6 +9,7 @@ test() ->
<<49,50,51>> = lex_digits1(Bin, 1, []),
<<49,50,51>> = lex_digits2(Bin, 1, []),
ok = var_bind_bug(<<1, 2, 3, 4, 5, 6, 7, 8>>),
+ ok = bs_match_string_bug(),
ok.
%%--------------------------------------------------------------------
@@ -65,3 +66,50 @@ var_bind_bug(<<A:1/binary, B:8/integer, _C:B/binary, _Rest/binary>>) ->
B -> wrong;
_ -> ok
end.
+
+%%--------------------------------------------------------------------
+%% From: Andreas Schultz
+%% Date: 2/11/2016
+%%
+%% Either HiPE is messing up binary matches in some cases or I'm not
+%% seeing the problem. ... <SNIP PROGRAM - CLEANED UP VERSION BELOW>
+%% With Erlang 19.1.3 the HiPE compiled version behaves differently
+%% than the non-HiPE version: ... <SNIP TEST RUNS>
+%% So, do I do something wrong here or is this a legitimate HiPE bug?
+%%
+%% Yes, this was a legitimate HiPE bug: The BEAM to ICode tranaslation
+%% of the bs_match_string instruction, written long ago for binaries
+%% (i.e., with byte-sized strings), tried to do a `clever' translation
+%% of even bit-sized strings using a HiPE primop that took a `Size'
+%% argument expressed in *bytes*. ICode is not really the place to do
+%% such a thing, and moreover there is really no reason for the HiPE
+%% primop not to take a Size argument expressed in *bits* instead.
+%% The bug was fixed by changing the `Size' argument to be in bits,
+%% postponing the translation of the bs_match_string primop until RTL
+%% and doing a proper translation using bit-sized quantities there.
+%%--------------------------------------------------------------------
+
+bs_match_string_bug() ->
+ ok = test0(<<50>>),
+ Bin = data(),
+ ok = test1(Bin),
+ ok = test2(Bin),
+ ok.
+
+%% Minimal test case showing the problem matching with strings
+test0(<<6:5, 0:1, 0:2>>) -> weird;
+test0(<<6:5, _:1, _:2>>) -> ok;
+test0(_) -> default.
+
+data() -> <<50,16,0>>.
+
+%% This was the problematic test case in HiPE: 'default' was returned
+test1(<<1:3, 1:1, _:1, 0:1, 0:1, 0:1, _/binary>>) -> weird;
+test1(<<1:3, 1:1, _:1, _:1, _:1, _:1, _/binary>>) -> ok;
+test1(_) -> default.
+
+%% This variation of test1/1 above worked OK, even in HiPE
+test2(<<1:3, 1:1, _:1, A:1, B:1, C:1, _/binary>>)
+ when A =:= 1; B =:= 1; C =:= 1 -> ok;
+test2(<<1:3, 1:1, _:1, 0:1, 0:1, 0:1, _/binary>>) -> weird;
+test2(_) -> default.
diff --git a/lib/hipe/test/hipe_SUITE.erl b/lib/hipe/test/hipe_SUITE.erl
index a5b3924aa8..b9adb660f2 100644
--- a/lib/hipe/test/hipe_SUITE.erl
+++ b/lib/hipe/test/hipe_SUITE.erl
@@ -16,7 +16,11 @@
%%
-module(hipe_SUITE).
--compile([export_all]).
+-export([all/0, groups/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_group/2, end_per_group/2,
+ app/0, app/1, appup/0, appup/1]).
+
-include_lib("common_test/include/ct.hrl").
all() ->
diff --git a/lib/hipe/test/hipe_testsuite_driver.erl b/lib/hipe/test/hipe_testsuite_driver.erl
index 03ec7adfd0..88576775ca 100644
--- a/lib/hipe/test/hipe_testsuite_driver.erl
+++ b/lib/hipe/test/hipe_testsuite_driver.erl
@@ -99,7 +99,7 @@ write_suite(Suite) ->
write_header(#suite{suitename = SuiteName, outputfile = OutputFile,
testcases = TestCases}) ->
Exports = format_export(TestCases),
- TimeLimit = 3, %% with 1 or 2 it fails on some slow machines...
+ TimeLimit = 6, %% with 1, 2, or 3 it fails on some slow machines...
io:format(OutputFile,
"%% ATTENTION!\n"
"%% This is an automatically generated file. Do not edit.\n\n"
@@ -168,6 +168,10 @@ run(TestCase, Dir, _OutDir) ->
HiPEOpts = try TestCase:hipe_options() catch error:undef -> [] end,
{ok, TestCase} = hipe:c(TestCase, HiPEOpts),
ok = TestCase:test(),
+ {ok, TestCase} = hipe:c(TestCase, [o1|HiPEOpts]),
+ ok = TestCase:test(),
+ {ok, TestCase} = hipe:c(TestCase, [o0|HiPEOpts]),
+ ok = TestCase:test(),
ToLLVM = try TestCase:to_llvm() catch error:undef -> true end,
case ToLLVM andalso hipe:llvm_support_available() of
true ->
diff --git a/lib/hipe/test/maps_SUITE_data/maps_redundant_branch_is_key.erl b/lib/hipe/test/maps_SUITE_data/maps_redundant_branch_is_key.erl
new file mode 100644
index 0000000000..17c3acd6af
--- /dev/null
+++ b/lib/hipe/test/maps_SUITE_data/maps_redundant_branch_is_key.erl
@@ -0,0 +1,14 @@
+-module(maps_redundant_branch_is_key).
+-export([test/0]).
+
+test() ->
+ ok = thingy(#{a => 1}),
+ ok = thingy(#{a => 2}),
+ ok.
+
+thingy(Map) ->
+ try
+ #{a := _} = Map,
+ ok
+ catch _ -> error
+ end.
diff --git a/lib/hipe/test/maps_SUITE_data/maps_warn_pair_key_overloaded.erl b/lib/hipe/test/maps_SUITE_data/maps_warn_pair_key_overloaded.erl
index 76b2a91f94..cce91530f4 100644
--- a/lib/hipe/test/maps_SUITE_data/maps_warn_pair_key_overloaded.erl
+++ b/lib/hipe/test/maps_SUITE_data/maps_warn_pair_key_overloaded.erl
@@ -14,7 +14,6 @@ test() ->
"hi2" => lists:subtract([1,2],[1]),
"hi3" => +3,
"hi1" => erlang:min(1,2),
- "hi1" => erlang:hash({1,2},35),
"hi1" => erlang:phash({1,2},33),
"hi1" => erlang:phash2({1,2},34),
"hi1" => erlang:integer_to_binary(1337),
diff --git a/lib/hipe/test/opt_verify_SUITE.erl b/lib/hipe/test/opt_verify_SUITE.erl
index 61952e81d7..86083fa02b 100644
--- a/lib/hipe/test/opt_verify_SUITE.erl
+++ b/lib/hipe/test/opt_verify_SUITE.erl
@@ -1,6 +1,9 @@
-module(opt_verify_SUITE).
--compile([export_all]).
+-export([all/0, groups/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_group/2, end_per_group/2,
+ call_elim/0, call_elim/1]).
all() ->
[call_elim].
@@ -23,23 +26,6 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-call_elim_test_file(Config, FileName, Option) ->
- PrivDir = test_server:lookup_config(priv_dir, Config),
- TempOut = test_server:temp_name(filename:join(PrivDir, "call_elim_out")),
- {ok, TestCase} = compile:file(FileName),
- {ok, TestCase} = hipe:c(TestCase, [Option, {pp_range_icode, {file, TempOut}}]),
- {ok, Icode} = file:read_file(TempOut),
- ok = file:delete(TempOut),
- Icode.
-
-substring_count(Icode, Substring) ->
- substring_count(Icode, Substring, 0).
-substring_count(Icode, Substring, N) ->
- case string:str(Icode, Substring) of
- 0 -> N;
- I -> substring_count(lists:nthtail(I, Icode), Substring, N+1)
- end.
-
call_elim() ->
[{doc, "Test that the call elimination optimization pass is ok"}].
call_elim(Config) ->
@@ -60,3 +46,20 @@ call_elim(Config) ->
Icode6 = call_elim_test_file(Config, F3, no_icode_call_elim),
3 = substring_count(binary:bin_to_list(Icode6), "is_key"),
ok.
+
+call_elim_test_file(Config, FileName, Option) ->
+ PrivDir = test_server:lookup_config(priv_dir, Config),
+ TempOut = test_server:temp_name(filename:join(PrivDir, "call_elim_out")),
+ {ok, TestCase} = compile:file(FileName),
+ {ok, TestCase} = hipe:c(TestCase, [Option, {pp_range_icode, {file, TempOut}}]),
+ {ok, Icode} = file:read_file(TempOut),
+ ok = file:delete(TempOut),
+ Icode.
+
+substring_count(Icode, Substring) ->
+ substring_count(Icode, Substring, 0).
+substring_count(Icode, Substring, N) ->
+ case string:str(Icode, Substring) of
+ 0 -> N;
+ I -> substring_count(lists:nthtail(I, Icode), Substring, N+1)
+ end.
diff --git a/lib/hipe/tools/hipe_jit.erl b/lib/hipe/tools/hipe_jit.erl
index ffe0e440e9..5b937a9789 100644
--- a/lib/hipe/tools/hipe_jit.erl
+++ b/lib/hipe/tools/hipe_jit.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2002 by Erik Johansson.
diff --git a/lib/hipe/tools/hipe_profile.erl b/lib/hipe/tools/hipe_profile.erl
index 9b9c0d6aad..f790dc6ebb 100644
--- a/lib/hipe/tools/hipe_profile.erl
+++ b/lib/hipe/tools/hipe_profile.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,12 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
-%% Time-stamp: <2008-04-20 14:53:42 richard>
%% ====================================================================
%% Module : hipe_profile
%% Purpose :
diff --git a/lib/hipe/tools/hipe_timer.erl b/lib/hipe/tools/hipe_timer.erl
index 72aa25d440..13dbeb6f87 100644
--- a/lib/hipe/tools/hipe_timer.erl
+++ b/lib/hipe/tools/hipe_timer.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,12 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
-%% Time-stamp: <2008-04-20 14:53:36 richard>
%% ====================================================================
%% Module : hipe_timer
%% Purpose :
@@ -51,7 +44,7 @@ empty_time() ->
{A,_} = erlang:statistics(runtime),
WTB = erlang:monotonic_time(),
{B,_} = erlang:statistics(runtime),
- {(WTB-WTA)/erlang:convert_time_unit(1, seconds, native),B-A}.
+ {(WTB-WTA)/erlang:convert_time_unit(1, second, native),B-A}.
time(F) ->
WTA = erlang:monotonic_time(),
@@ -59,7 +52,7 @@ time(F) ->
F(),
WTB = erlang:monotonic_time(),
{B,_} = erlang:statistics(runtime),
- {(WTB-WTA)/erlang:convert_time_unit(1, seconds, native),B-A}.
+ {(WTB-WTA)/erlang:convert_time_unit(1, second, native),B-A}.
timer(F) ->
WTA = erlang:monotonic_time(),
@@ -67,7 +60,7 @@ timer(F) ->
R = F(),
WTB = erlang:monotonic_time(),
{B,_} = erlang:statistics(runtime),
- {R,{(WTB-WTA)/erlang:convert_time_unit(1, seconds, native),B-A}}.
+ {R,{(WTB-WTA)/erlang:convert_time_unit(1, second, native),B-A}}.
advanced(_Fun, I) when I < 2 -> false;
advanced(Fun, Iterations) ->
diff --git a/lib/hipe/util/Makefile b/lib/hipe/util/Makefile
index 66e9421c25..20b1c3bf50 100644
--- a/lib/hipe/util/Makefile
+++ b/lib/hipe/util/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2001-2016. All Rights Reserved.
+# Copyright Ericsson AB 2001-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@ HIPE_MODULES = hipe_vectors
else
HIPE_MODULES =
endif
-MODULES = hipe_timing hipe_dot hipe_digraph $(HIPE_MODULES)
+MODULES = hipe_timing hipe_dot hipe_digraph hipe_dsets $(HIPE_MODULES)
HRL_FILES=
ERL_FILES= $(MODULES:%=%.erl)
@@ -113,4 +113,3 @@ release_docs_spec:
$(EBIN)/hipe_timing.beam: ../main/hipe.hrl
-$(EBIN)/hipe_vectors.beam: hipe_vectors.hrl
diff --git a/lib/hipe/util/hipe_digraph.erl b/lib/hipe/util/hipe_digraph.erl
index 7446836926..0976395262 100644
--- a/lib/hipe/util/hipe_digraph.erl
+++ b/lib/hipe/util/hipe_digraph.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%-----------------------------------------------------------------------
%% File : hipe_digraph.erl
%% Author : Tobias Lindahl <[email protected]>
diff --git a/lib/hipe/util/hipe_dot.erl b/lib/hipe/util/hipe_dot.erl
index 53e474db42..22d9c02ba0 100644
--- a/lib/hipe/util/hipe_dot.erl
+++ b/lib/hipe/util/hipe_dot.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_dot.erl
diff --git a/lib/hipe/util/hipe_dsets.erl b/lib/hipe/util/hipe_dsets.erl
new file mode 100644
index 0000000000..9492cab0ff
--- /dev/null
+++ b/lib/hipe/util/hipe_dsets.erl
@@ -0,0 +1,84 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%@doc
+%% IMMUTABLE DISJOINT SETS OF ARBITRARY TERMS
+%%
+%% The disjoint set forests data structure, for elements of arbitrary types.
+%% Note that the find operation mutates the set.
+%%
+%% We could do this more efficiently if we restricted the elements to integers,
+%% and used the (mutable) hipe arrays. For arbitrary terms ETS could be used,
+%% for a persistent interface (which isn't that nice when even accessors return
+%% modified copies), the array module could be used.
+-module(hipe_dsets).
+
+-export([new/1, find/2, union/3, to_map/1, to_rllist/1]).
+-export_type([dsets/1]).
+
+-opaque dsets(X) :: #{X => {node, X} | {root, non_neg_integer()}}.
+
+-spec new([E]) -> dsets(E).
+new(Elems) -> maps:from_list([{E,{root,0}} || E <- Elems]).
+
+-spec find(E, dsets(E)) -> {E, dsets(E)}.
+find(E, DS0) ->
+ case DS0 of
+ #{E := {root,_}} -> {E, DS0};
+ #{E := {node,N}} ->
+ case find(N, DS0) of
+ {N, _}=T -> T;
+ {R, DS1} -> {R, DS1#{E := {node,R}}}
+ end;
+ _ -> error(badarg, [E, DS0])
+ end.
+
+-spec union(E, E, dsets(E)) -> dsets(E).
+union(X, Y, DS0) ->
+ {XRoot, DS1} = find(X, DS0),
+ case find(Y, DS1) of
+ {XRoot, DS2} -> DS2;
+ {YRoot, DS2} ->
+ #{XRoot := {root,XRR}, YRoot := {root,YRR}} = DS2,
+ if XRR < YRR -> DS2#{XRoot := {node,YRoot}};
+ XRR > YRR -> DS2#{YRoot := {node,XRoot}};
+ true -> DS2#{YRoot := {node,XRoot}, XRoot := {root,XRR+1}}
+ end
+ end.
+
+-spec to_map(dsets(E)) -> {#{Elem::E => Root::E}, dsets(E)}.
+to_map(DS) ->
+ to_map(maps:keys(DS), DS, #{}).
+
+to_map([], DS, Acc) -> {Acc, DS};
+to_map([K|Ks], DS0, Acc) ->
+ {KR, DS} = find(K, DS0),
+ to_map(Ks, DS, Acc#{K => KR}).
+
+-spec to_rllist(dsets(E)) -> {[{Root::E, Elems::[E]}], dsets(E)}.
+to_rllist(DS0) ->
+ {Lists, DS} = to_rllist(maps:keys(DS0), #{}, DS0),
+ {maps:to_list(Lists), DS}.
+
+to_rllist([], Acc, DS) -> {Acc, DS};
+to_rllist([E|Es], Acc, DS0) ->
+ {ERoot, DS} = find(E, DS0),
+ to_rllist(Es, map_append(ERoot, E, Acc), DS).
+
+map_append(Key, Elem, Map) ->
+ case Map of
+ #{Key := List} -> Map#{Key := [Elem|List]};
+ #{} -> Map#{Key => [Elem]}
+ end.
diff --git a/lib/hipe/util/hipe_timing.erl b/lib/hipe/util/hipe_timing.erl
index bf8a08dee5..3ebde7b1b5 100644
--- a/lib/hipe/util/hipe_timing.erl
+++ b/lib/hipe/util/hipe_timing.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%====================================================================
%% Note: Uses the process keys:
diff --git a/lib/hipe/util/hipe_vectors.erl b/lib/hipe/util/hipe_vectors.erl
index 7f6c8e91c2..788dacd11b 100644
--- a/lib/hipe/util/hipe_vectors.erl
+++ b/lib/hipe/util/hipe_vectors.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -33,11 +27,25 @@
%% list_to_vector/1,
list/1]).
--include("hipe_vectors.hrl").
+%%-define(USE_TUPLES, true).
+%%-define(USE_GBTREES, true).
+-define(USE_ARRAYS, true).
+
+-type vector() :: vector(_).
+-export_type([vector/0, vector/1]).
+
+-spec new(non_neg_integer(), V) -> vector(E) when V :: E.
+-spec set(vector(E), non_neg_integer(), V :: E) -> vector(E).
+-spec get(vector(E), non_neg_integer()) -> E.
+-spec size(vector(_)) -> non_neg_integer().
+-spec vector_to_list(vector(E)) -> [E].
+%% -spec list_to_vector([E]) -> vector(E).
+-spec list(vector(E)) -> [{non_neg_integer(), E}].
%% ---------------------------------------------------------------------
-ifdef(USE_TUPLES).
+-opaque vector(_) :: tuple().
new(N, V) ->
erlang:make_tuple(N, V).
@@ -68,8 +76,8 @@ get(Vec, Ix) -> element(Ix+1, Vec).
%% ---------------------------------------------------------------------
-ifdef(USE_GBTREES).
+-opaque vector(E) :: gb_trees:tree(non_neg_integer(), E).
--spec new(non_neg_integer(), _) -> hipe_vector().
new(N, V) when is_integer(N), N >= 0 ->
gb_trees:from_orddict(mklist(N, V)).
@@ -81,14 +89,11 @@ mklist(M, N, V) when M < N ->
mklist(_, _, _) ->
[].
--spec size(hipe_vector()) -> non_neg_integer().
size(V) -> gb_trees:size(V).
--spec list(hipe_vector()) -> [{_, _}].
list(Vec) ->
gb_trees:to_list(Vec).
-%% -spec list_to_vector([_]) -> hipe_vector().
%% list_to_vector(Xs) ->
%% gb_trees:from_orddict(index(Xs, 0)).
%%
@@ -97,16 +102,28 @@ list(Vec) ->
%% index([],_) ->
%% [].
--spec vector_to_list(hipe_vector()) -> [_].
vector_to_list(V) ->
gb_trees:values(V).
--spec set(hipe_vector(), non_neg_integer(), _) -> hipe_vector().
set(Vec, Ix, V) ->
gb_trees:update(Ix, V, Vec).
--spec get(hipe_vector(), non_neg_integer()) -> any().
get(Vec, Ix) ->
gb_trees:get(Ix, Vec).
-endif. %% ifdef USE_GBTREES
+
+%% ---------------------------------------------------------------------
+
+-ifdef(USE_ARRAYS).
+-opaque vector(E) :: array:array(E).
+
+new(N, V) -> array:new(N, {default, V}).
+size(V) -> array:size(V).
+list(Vec) -> array:to_orddict(Vec).
+%% list_to_vector(Xs) -> array:from_list(Xs).
+vector_to_list(V) -> array:to_list(V).
+set(Vec, Ix, V) -> array:set(Ix, V, Vec).
+get(Vec, Ix) -> array:get(Ix, Vec).
+
+-endif. %% ifdef USE_ARRAYS
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index e61c1a042c..0ef4aa7f09 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.15.1
+HIPE_VSN = 3.16
diff --git a/lib/hipe/x86/Makefile b/lib/hipe/x86/Makefile
index 93f8b955dd..84edeaebe7 100644
--- a/lib/hipe/x86/Makefile
+++ b/lib/hipe/x86/Makefile
@@ -60,9 +60,9 @@ MODULES=hipe_rtl_to_x86 \
hipe_x86_ra_ls \
hipe_x86_ra_naive \
hipe_x86_ra_postconditions \
- hipe_x86_ra_x87_ls \
hipe_x86_registers \
hipe_x86_spill_restore \
+ hipe_x86_subst \
hipe_x86_x87
HRL_FILES=hipe_x86.hrl
@@ -133,7 +133,6 @@ $(EBIN)/hipe_x86_ra: ../main/hipe.hrl
$(EBIN)/hipe_x86_ra_dummy.beam: ../main/hipe.hrl
$(EBIN)/hipe_x86_ra_ls.beam: ../main/hipe.hrl
$(EBIN)/hipe_x86_ra_postconditions.beam: ../main/hipe.hrl
-$(EBIN)/hipe_x86_ra_x87_ls.beam: ../main/hipe.hrl
$(EBIN)/hipe_x86_registers.beam: ../rtl/hipe_literals.hrl
$(EBIN)/hipe_x86_spill_restore.beam: ../main/hipe.hrl ../flow/cfg.hrl
$(EBIN)/hipe_x86_x87.beam: ../main/hipe.hrl
diff --git a/lib/hipe/x86/NOTES.OPTIM b/lib/hipe/x86/NOTES.OPTIM
index 4c241cacb4..c518ea3481 100644
--- a/lib/hipe/x86/NOTES.OPTIM
+++ b/lib/hipe/x86/NOTES.OPTIM
@@ -1,5 +1,3 @@
-$Id$
-
Partial x86 code optimisation guide
===================================
Priority should be given to P6 and P4, then K7,
diff --git a/lib/hipe/x86/NOTES.RA b/lib/hipe/x86/NOTES.RA
index ce80411642..173eaf229e 100644
--- a/lib/hipe/x86/NOTES.RA
+++ b/lib/hipe/x86/NOTES.RA
@@ -1,5 +1,3 @@
-$Id$
-
Register Allocation
===================
diff --git a/lib/hipe/x86/hipe_rtl_to_x86.erl b/lib/hipe/x86/hipe_rtl_to_x86.erl
index d13f63b1d9..31e4f6e4ac 100644
--- a/lib/hipe/x86/hipe_rtl_to_x86.erl
+++ b/lib/hipe/x86/hipe_rtl_to_x86.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
-%%%
%%%
%%% Translate 3-address RTL code to 2-address pseudo-x86 code.
@@ -85,32 +78,37 @@ conv_insn(I, Map, Data) ->
true ->
conv_shift(Dst, Src1, BinOp, Src2);
false ->
- conv_alu(Dst, Src1, BinOp, Src2, [])
+ conv_alu_nocc(Dst, Src1, BinOp, Src2, [])
end,
{FixSrc1++FixSrc2++I2, Map2, Data};
#alub{} ->
%% dst = src1 op src2; if COND goto label
BinOp = conv_binop(hipe_rtl:alub_op(I)),
- {Dst, Map0} = conv_dst(hipe_rtl:alub_dst(I), Map),
- {FixSrc1, Src1, Map1} = conv_src(hipe_rtl:alub_src1(I), Map0),
- {FixSrc2, Src2, Map2} = conv_src(hipe_rtl:alub_src2(I), Map1),
+ {FixSrc1, Src1, Map0} = conv_src(hipe_rtl:alub_src1(I), Map),
+ {FixSrc2, Src2, Map1} = conv_src(hipe_rtl:alub_src2(I), Map0),
Cc = conv_cond(hipe_rtl:alub_cond(I)),
- I1 = [hipe_x86:mk_pseudo_jcc(Cc,
- hipe_rtl:alub_true_label(I),
- hipe_rtl:alub_false_label(I),
- hipe_rtl:alub_pred(I))],
- I2 = conv_alu(Dst, Src1, BinOp, Src2, I1),
- {FixSrc1++FixSrc2++I2, Map2, Data};
- #branch{} ->
- %% <unused> = src1 - src2; if COND goto label
- {FixSrc1, Src1, Map0} = conv_src(hipe_rtl:branch_src1(I), Map),
- {FixSrc2, Src2, Map1} = conv_src(hipe_rtl:branch_src2(I), Map0),
- Cc = conv_cond(hipe_rtl:branch_cond(I)),
- I2 = conv_branch(Src1, Cc, Src2,
- hipe_rtl:branch_true_label(I),
- hipe_rtl:branch_false_label(I),
- hipe_rtl:branch_pred(I)),
- {FixSrc1++FixSrc2++I2, Map1, Data};
+ BranchOp = conv_branchop(BinOp),
+ HasDst = hipe_rtl:alub_has_dst(I),
+ {I2, Map3} =
+ case (not HasDst) andalso BranchOp =/= none of
+ true ->
+ {conv_branch(Src1, BranchOp, Src2, Cc,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I)), Map1};
+ false ->
+ {Dst, Map2} =
+ case HasDst of
+ false -> {new_untagged_temp(), Map1};
+ true -> conv_dst(hipe_rtl:alub_dst(I), Map1)
+ end,
+ I1 = [hipe_x86:mk_pseudo_jcc(Cc,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I))],
+ {conv_alu(Dst, Src1, BinOp, Src2, I1), Map2}
+ end,
+ {FixSrc1++FixSrc2++I2, Map3, Data};
#call{} ->
%% push <arg1>
%% ...
@@ -126,7 +124,6 @@ conv_insn(I, Map, Data) ->
hipe_rtl:call_continuation(I),
hipe_rtl:call_fail(I),
hipe_rtl:call_type(I)),
- %% XXX Fixme: this ++ is probably inefficient.
{FixArgs++I2, Map2, Data};
#comment{} ->
I2 = [hipe_x86:mk_comment(hipe_rtl:comment_text(I))],
@@ -144,7 +141,7 @@ conv_insn(I, Map, Data) ->
{I2, Map, Data};
#load{} ->
{Dst, Map0} = conv_dst(hipe_rtl:load_dst(I), Map),
- {FixSrc, Src, Map1} = conv_src(hipe_rtl:load_src(I), Map0),
+ {FixSrc, Src, Map1} = conv_src_noimm(hipe_rtl:load_src(I), Map0),
{FixOff, Off, Map2} = conv_src(hipe_rtl:load_offset(I), Map1),
I2 = case {hipe_rtl:load_size(I), hipe_rtl:load_sign(I)} of
{byte, signed} ->
@@ -171,6 +168,7 @@ conv_insn(I, Map, Data) ->
Src = hipe_x86:mk_imm_from_atom(hipe_rtl:load_atom_atom(I)),
I2 = [hipe_x86:mk_move(Src, Dst)],
{I2, Map0, Data};
+ #move{src=Dst, dst=Dst} -> {[], Map, Data};
#move{} ->
{Dst, Map0} = conv_dst(hipe_rtl:move_dst(I), Map),
{FixSrc, Src, Map1} = conv_src(hipe_rtl:move_src(I), Map0),
@@ -182,11 +180,11 @@ conv_insn(I, Map, Data) ->
I2 = move_retvals(Args, [hipe_x86:mk_ret(-1)]),
{FixArgs++I2, Map0, Data};
#store{} ->
- {Ptr, Map0} = conv_dst(hipe_rtl:store_base(I), Map),
+ {FixPtr, Ptr, Map0} = conv_src_noimm(hipe_rtl:store_base(I), Map),
{FixSrc, Src, Map1} = conv_src(hipe_rtl:store_src(I), Map0),
{FixOff, Off, Map2} = conv_src(hipe_rtl:store_offset(I), Map1),
I2 = mk_store(hipe_rtl:store_size(I), Src, Ptr, Off),
- {FixSrc++FixOff++I2, Map2, Data};
+ {FixPtr++FixSrc++FixOff++I2, Map2, Data};
#switch{} -> % this one also updates Data :-(
%% from hipe_rtl2sparc, but we use a hairy addressing mode
%% instead of doing the arithmetic manually
@@ -206,7 +204,7 @@ conv_insn(I, Map, Data) ->
{I2, Map1, NewData};
#fload{} ->
{Dst, Map0} = conv_dst(hipe_rtl:fload_dst(I), Map),
- {[], Src, Map1} = conv_src(hipe_rtl:fload_src(I), Map0),
+ {[], Src, Map1} = conv_src_noimm(hipe_rtl:fload_src(I), Map0),
{[], Off, Map2} = conv_src(hipe_rtl:fload_offset(I), Map1),
I2 = [hipe_x86:mk_fmove(hipe_x86:mk_mem(Src, Off, 'double'),Dst)],
{I2, Map2, Data};
@@ -249,6 +247,34 @@ conv_insn(I, Map, Data) ->
%%% Finalise the conversion of a 3-address ALU operation, taking
%%% care to not introduce more temps and moves than necessary.
+conv_alu_nocc(Dst, Src1, 'add', Src2, Tail) ->
+ case (not same_opnd(Dst, Src1)) andalso (not same_opnd(Dst, Src2))
+ %% We could use orelse instead of xor here to generate lea T1(T2), T3, but
+ %% they seem to move coalesce so well that move+add is better for them.
+ andalso (hipe_x86:is_temp(Src1) xor hipe_x86:is_temp(Src2))
+ of
+ false -> conv_alu(Dst, Src1, 'add', Src2, Tail);
+ true -> % Use LEA
+ Type = typeof_dst(Dst),
+ Mem = case hipe_x86:is_temp(Src1) of
+ true -> hipe_x86:mk_mem(Src1, Src2, Type);
+ false -> hipe_x86:mk_mem(Src2, Src1, Type)
+ end,
+ [hipe_x86:mk_lea(Mem, Dst) | Tail]
+ end;
+conv_alu_nocc(Dst, Src1, 'sub', Src2, Tail) ->
+ case (not same_opnd(Dst, Src1)) andalso hipe_x86:is_temp(Src1)
+ andalso (not hipe_x86:is_temp(Src2))
+ of
+ false -> conv_alu(Dst, Src1, 'sub', Src2, Tail);
+ true -> % Use LEA
+ Imm = hipe_x86:mk_imm(-hipe_x86:imm_value(Src2)),
+ Mem = hipe_x86:mk_mem(Src1, Imm, typeof_dst(Dst)),
+ [hipe_x86:mk_lea(Mem, Dst) | Tail]
+ end;
+conv_alu_nocc(Dst, Src1, BinOp, Src2, Tail) ->
+ conv_alu(Dst, Src1, BinOp, Src2, Tail).
+
conv_alu(Dst, Src1, 'imul', Src2, Tail) ->
mk_imul(Src1, Src2, Dst, Tail);
conv_alu(Dst, Src1, BinOp, Src2, Tail) ->
@@ -343,28 +369,41 @@ conv_shift(Dst, Src1, BinOp, Src2) ->
%%% Finalise the conversion of a conditional branch operation, taking
%%% care to not introduce more temps and moves than necessary.
-conv_branch(Src1, Cc, Src2, TrueLab, FalseLab, Pred) ->
+conv_branchop('sub') -> 'cmp';
+conv_branchop('and') -> 'test';
+conv_branchop(_) -> none.
+
+branchop_commutes('cmp') -> false;
+branchop_commutes('test') -> true.
+
+conv_branch(Src1, Op, Src2, Cc, TrueLab, FalseLab, Pred) ->
case hipe_x86:is_imm(Src1) of
false ->
- mk_branch(Src1, Cc, Src2, TrueLab, FalseLab, Pred);
+ mk_branch(Src1, Op, Src2, Cc, TrueLab, FalseLab, Pred);
true ->
case hipe_x86:is_imm(Src2) of
false ->
- NewCc = commute_cc(Cc),
- mk_branch(Src2, NewCc, Src1, TrueLab, FalseLab, Pred);
+ NewCc = case branchop_commutes(Op) of
+ true -> Cc;
+ false -> commute_cc(Cc)
+ end,
+ mk_branch(Src2, Op, Src1, NewCc, TrueLab, FalseLab, Pred);
true ->
%% two immediates, let the optimiser clean it up
Tmp = new_untagged_temp(),
[hipe_x86:mk_move(Src1, Tmp) |
- mk_branch(Tmp, Cc, Src2, TrueLab, FalseLab, Pred)]
+ mk_branch(Tmp, Op, Src2, Cc, TrueLab, FalseLab, Pred)]
end
end.
-mk_branch(Src1, Cc, Src2, TrueLab, FalseLab, Pred) ->
+mk_branch(Src1, Op, Src2, Cc, TrueLab, FalseLab, Pred) ->
%% PRE: not(is_imm(Src1))
- [hipe_x86:mk_cmp(Src2, Src1),
+ [mk_branchtest(Src1, Op, Src2),
hipe_x86:mk_pseudo_jcc(Cc, TrueLab, FalseLab, Pred)].
+mk_branchtest(Src1, cmp, Src2) -> hipe_x86:mk_cmp(Src2, Src1);
+mk_branchtest(Src1, test, Src2) -> hipe_x86:mk_test(Src2, Src1).
+
%%% Convert an RTL ALU or ALUB binary operator.
conv_binop(BinOp) ->
@@ -572,6 +611,16 @@ conv_fun(Fun, Map) ->
end
end.
+conv_src_noimm(Opnd, Map) ->
+ R={FixSrc0, Src, NewMap} = conv_src(Opnd, Map),
+ case hipe_x86:is_imm(Src) of
+ false -> R;
+ true ->
+ Tmp = new_untagged_temp(),
+ {FixSrc0 ++ [hipe_x86:mk_move(Src, Tmp)],
+ Tmp, NewMap}
+ end.
+
%%% Convert an RTL source operand (imm/var/reg).
conv_src(Opnd, Map) ->
diff --git a/lib/hipe/x86/hipe_x86.erl b/lib/hipe/x86/hipe_x86.erl
index 33d7f77cf1..f514dd1ded 100644
--- a/lib/hipe/x86/hipe_x86.erl
+++ b/lib/hipe/x86/hipe_x86.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% representation of 2-address pseudo-amd64 code
@@ -37,7 +30,7 @@
mk_imm_from_addr/2,
mk_imm_from_atom/1,
is_imm/1,
- %% imm_value/1,
+ imm_value/1,
mk_mem/3,
%% is_mem/1,
@@ -174,6 +167,12 @@
mk_pseudo_spill/1,
+ mk_pseudo_spill_fmove/3,
+ is_pseudo_spill_fmove/1,
+
+ mk_pseudo_spill_move/3,
+ is_pseudo_spill_move/1,
+
mk_pseudo_tailcall/4,
%% is_pseudo_tailcall/1,
pseudo_tailcall_fun/1,
@@ -201,7 +200,7 @@
shift_src/1,
shift_dst/1,
- %% mk_test/2,
+ mk_test/2,
test_src/1,
test_dst/1,
@@ -218,6 +217,10 @@
%% highest_temp/1
]).
+%% Other utilities
+-export([neg_cc/1
+ ]).
+
%%%
%%% Low-level accessors.
%%%
@@ -241,7 +244,7 @@ mk_imm_from_addr(Addr, Type) ->
mk_imm_from_atom(Atom) ->
mk_imm(Atom).
is_imm(X) -> case X of #x86_imm{} -> true; _ -> false end.
-%% imm_value(#x86_imm{value=Value}) -> Value.
+imm_value(#x86_imm{value=Value}) -> Value.
mk_mem(Base, Off, Type) -> #x86_mem{base=Base, off=Off, type=Type}.
%% is_mem(X) -> case X of #x86_mem{} -> true; _ -> false end.
@@ -305,7 +308,7 @@ mk_cmp(Src, Dst) -> #cmp{src=Src, dst=Dst}.
cmp_src(#cmp{src=Src}) -> Src.
cmp_dst(#cmp{dst=Dst}) -> Dst.
-%% mk_test(Src, Dst) -> #test{src=Src, dst=Dst}.
+mk_test(Src, Dst) -> #test{src=Src, dst=Dst}.
test_src(#test{src=Src}) -> Src.
test_dst(#test{dst=Dst}) -> Dst.
@@ -428,6 +431,14 @@ mk_pseudo_jcc_simple(Cc, TrueLabel, FalseLabel, Pred) ->
mk_pseudo_spill(List) ->
#pseudo_spill{args=List}.
+mk_pseudo_spill_fmove(Src, Temp, Dst) ->
+ #pseudo_spill_fmove{src=Src, temp=Temp, dst=Dst}.
+is_pseudo_spill_fmove(I) -> is_record(I, pseudo_spill_fmove).
+
+mk_pseudo_spill_move(Src, Temp, Dst) ->
+ #pseudo_spill_move{src=Src, temp=Temp, dst=Dst}.
+is_pseudo_spill_move(I) -> is_record(I, pseudo_spill_move).
+
mk_pseudo_tailcall(Fun, Arity, StkArgs, Linkage) ->
check_linkage(Linkage),
#pseudo_tailcall{'fun'=Fun, arity=Arity, stkargs=StkArgs, linkage=Linkage}.
diff --git a/lib/hipe/x86/hipe_x86.hrl b/lib/hipe/x86/hipe_x86.hrl
index ef99bf90d9..6cd69905b2 100644
--- a/lib/hipe/x86/hipe_x86.hrl
+++ b/lib/hipe/x86/hipe_x86.hrl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% concrete representation of 2-address pseudo-x86 code
@@ -98,6 +91,8 @@
-record(pseudo_call, {'fun', sdesc, contlab, linkage}).
-record(pseudo_jcc, {cc, true_label, false_label, pred}).
-record(pseudo_spill, {args=[]}).
+-record(pseudo_spill_move, {src, temp, dst}).
+-record(pseudo_spill_fmove, {src, temp, dst}).
-record(pseudo_tailcall, {'fun', arity, stkargs, linkage}).
-record(pseudo_tailcall_prepare, {}).
-record(push, {src}).
diff --git a/lib/hipe/x86/hipe_x86_assemble.erl b/lib/hipe/x86/hipe_x86_assemble.erl
index e21223a5b1..50919bdf4e 100644
--- a/lib/hipe/x86/hipe_x86_assemble.erl
+++ b/lib/hipe/x86/hipe_x86_assemble.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% HiPE/x86 assembler
%%%
@@ -69,7 +63,7 @@ assemble(CompiledCode, Closures, Exports, Options) ->
|| {MFA, Defun} <- CompiledCode],
%%
{ConstAlign,ConstSize,ConstMap,RefsFromConsts} =
- hipe_pack_constants:pack_constants(Code, ?HIPE_X86_REGISTERS:alignment()),
+ hipe_pack_constants:pack_constants(Code),
%%
{CodeSize,CodeBinary,AccRefs,LabelMap,ExportMap} =
encode(translate(Code, ConstMap, Options), Options),
@@ -154,6 +148,8 @@ insn_size(I) ->
translate_insn(I, Context, Options) ->
case I of
+ #alu{aluop='xor', src=#x86_temp{reg=Reg}=Src, dst=#x86_temp{reg=Reg}=Dst} ->
+ [{'xor', {temp_to_reg32(Dst), temp_to_rm32(Src)}, I}];
#alu{} ->
Arg = resolve_alu_args(hipe_x86:alu_src(I), hipe_x86:alu_dst(I), Context),
[{hipe_x86:alu_op(I), Arg, I}];
@@ -234,11 +230,11 @@ translate_insn(I, Context, Options) ->
#move64{} ->
translate_move64(I, Context);
#movsx{} ->
- Arg = resolve_movx_args(hipe_x86:movsx_src(I), hipe_x86:movsx_dst(I)),
- [{movsx, Arg, I}];
+ Src = resolve_movx_src(hipe_x86:movsx_src(I)),
+ [{movsx, {temp_to_regArch(hipe_x86:movsx_dst(I)), Src}, I}];
#movzx{} ->
- Arg = resolve_movx_args(hipe_x86:movzx_src(I), hipe_x86:movzx_dst(I)),
- [{movzx, Arg, I}];
+ Src = resolve_movx_src(hipe_x86:movzx_src(I)),
+ [{movzx, {temp_to_reg32(hipe_x86:movzx_dst(I)), Src}, I}];
%% pseudo_call: eliminated before assembly
%% pseudo_jcc: eliminated before assembly
%% pseudo_tailcall: eliminated before assembly
@@ -599,10 +595,20 @@ temp_to_xmm(#x86_temp{reg=Reg}) ->
{xmm, Reg}.
-ifdef(HIPE_AMD64).
+temp_to_rm8(#x86_temp{reg=Reg}) ->
+ {rm8, ?HIPE_X86_ENCODE:rm_reg(Reg)}.
temp_to_rm64(#x86_temp{reg=Reg}) ->
{rm64, hipe_amd64_encode:rm_reg(Reg)}.
+-else.
+temp_to_rm8(#x86_temp{reg=Reg}) ->
+ true = ?HIPE_X86_ENCODE:reg_has_8bit(Reg),
+ {rm8, ?HIPE_X86_ENCODE:rm_reg(Reg)}.
+temp_to_rm16(#x86_temp{reg=Reg}) ->
+ {rm16, ?HIPE_X86_ENCODE:rm_reg(Reg)}.
-endif.
+temp_to_rm32(#x86_temp{reg=Reg}) ->
+ {rm32, ?HIPE_X86_ENCODE:rm_reg(Reg)}.
temp_to_rmArch(#x86_temp{reg=Reg}) ->
{?RMArch, ?HIPE_X86_ENCODE:rm_reg(Reg)}.
temp_to_rm64fp(#x86_temp{reg=Reg}) ->
@@ -841,16 +847,15 @@ translate_move64(I, _Context) -> exit({?MODULE, I}).
-endif.
%%% mov{s,z}x
-resolve_movx_args(Src=#x86_mem{type=Type}, Dst=#x86_temp{}) ->
- {temp_to_regArch(Dst),
- case Type of
- byte ->
- mem_to_rm8(Src);
- int16 ->
- mem_to_rm16(Src);
- int32 ->
- mem_to_rm32(Src)
- end}.
+resolve_movx_src(Src=#x86_mem{type=Type}) ->
+ case Type of
+ byte ->
+ mem_to_rm8(Src);
+ int16 ->
+ mem_to_rm16(Src);
+ int32 ->
+ mem_to_rm32(Src)
+ end.
%%% alu/cmp (_not_ test)
resolve_alu_args(Src, Dst, Context) ->
@@ -878,15 +883,29 @@ resolve_alu_args(Src, Dst, Context) ->
%%% test
resolve_test_args(Src, Dst, Context) ->
case Src of
- #x86_imm{} -> % imm8 not allowed
- {_ImmSize,ImmValue} = translate_imm(Src, Context, false),
- NewDst =
- case Dst of
- #x86_temp{reg=0} -> ?EAX;
- #x86_temp{} -> temp_to_rmArch(Dst);
- #x86_mem{} -> mem_to_rmArch(Dst)
- end,
- {NewDst, {imm32,ImmValue}};
+ %% Since we're using an 8-bit instruction, the immediate is not sign
+ %% extended. Thus, we can use immediates up to 255.
+ #x86_imm{value=ImmVal}
+ when is_integer(ImmVal), ImmVal >= 0, ImmVal =< 255 ->
+ Imm = {imm8, ImmVal},
+ case Dst of
+ #x86_temp{reg=0} -> {al, Imm};
+ #x86_temp{} -> resolve_test_imm8_reg(Imm, Dst);
+ #x86_mem{} -> {mem_to_rm8(Dst), Imm}
+ end;
+ #x86_imm{value=ImmVal} when is_integer(ImmVal), ImmVal >= 0 ->
+ {case Dst of
+ #x86_temp{reg=0} -> eax;
+ #x86_temp{} -> temp_to_rm32(Dst);
+ #x86_mem{} -> mem_to_rm32(Dst)
+ end, {imm32, ImmVal}};
+ #x86_imm{} -> % Negative ImmVal; use word-sized instr, imm32
+ {_, ImmVal} = translate_imm(Src, Context, false),
+ {case Dst of
+ #x86_temp{reg=0} -> ?EAX;
+ #x86_temp{} -> temp_to_rmArch(Dst);
+ #x86_mem{} -> mem_to_rmArch(Dst)
+ end, {imm32, ImmVal}};
#x86_temp{} ->
NewDst =
case Dst of
@@ -896,6 +915,18 @@ resolve_test_args(Src, Dst, Context) ->
{NewDst, temp_to_regArch(Src)}
end.
+-ifdef(HIPE_AMD64).
+resolve_test_imm8_reg(Imm, Dst) -> {temp_to_rm8(Dst), Imm}.
+-else.
+resolve_test_imm8_reg(Imm = {imm8, ImmVal}, Dst = #x86_temp{reg=Reg}) ->
+ case ?HIPE_X86_ENCODE:reg_has_8bit(Reg) of
+ true -> {temp_to_rm8(Dst), Imm};
+ false ->
+ %% Register does not exist in 8-bit version; use 16-bit instead
+ {temp_to_rm16(Dst), {imm16, ImmVal}}
+ end.
+-endif.
+
%%% shifts
resolve_shift_args(Src, Dst, Context) ->
RM32 =
diff --git a/lib/hipe/x86/hipe_x86_cfg.erl b/lib/hipe/x86/hipe_x86_cfg.erl
index ab40b68580..0a3c0fc9d6 100644
--- a/lib/hipe/x86/hipe_x86_cfg.erl
+++ b/lib/hipe/x86/hipe_x86_cfg.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,24 +11,22 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_x86_cfg).
-export([init/1,
labels/1, start_label/1,
succ/2, pred/2,
- bb/2, bb_add/3]).
+ bb/2, bb_add/3, map_bbs/2, fold_bbs/3]).
-export([postorder/1, reverse_postorder/1]).
--export([linearise/1, params/1, arity/1, redirect_jmp/3]).
+-export([linearise/1, params/1, arity/1, redirect_jmp/3, branch_preds/1]).
%%% these tell cfg.inc what to define (ugly as hell)
-define(PRED_NEEDED,true).
-define(BREADTH_ORDER,true).
-define(PARAMS_NEEDED,true).
-define(START_LABEL_UPDATE_NEEDED,true).
+-define(MAP_FOLD_NEEDED,true).
-include("hipe_x86.hrl").
-include("../flow/cfg.hrl").
@@ -78,6 +72,26 @@ branch_successors(Branch) ->
#ret{} -> []
end.
+branch_preds(Branch) ->
+ case Branch of
+ #jmp_switch{labels=Labels} ->
+ Prob = 1.0/length(Labels),
+ [{L, Prob} || L <- Labels];
+ #pseudo_call{contlab=ContLab, sdesc=#x86_sdesc{exnlab=[]}} ->
+ %% A function can still cause an exception, even if we won't catch it
+ [{ContLab, 1.0-hipe_bb_weights:call_exn_pred()}];
+ #pseudo_call{contlab=ContLab, sdesc=#x86_sdesc{exnlab=ExnLab}} ->
+ CallExnPred = hipe_bb_weights:call_exn_pred(),
+ [{ContLab, 1.0-CallExnPred}, {ExnLab, CallExnPred}];
+ #pseudo_jcc{true_label=TrueLab,false_label=FalseLab,pred=Pred} ->
+ [{FalseLab, 1.0-Pred}, {TrueLab, Pred}];
+ _ ->
+ case branch_successors(Branch) of
+ [] -> [];
+ [Single] -> [{Single, 1.0}]
+ end
+ end.
+
-ifdef(REMOVE_TRIVIAL_BBS_NEEDED).
fails_to(_Instr) -> [].
-endif.
@@ -107,7 +121,7 @@ mk_goto(Label) ->
hipe_x86:mk_jmp_label(Label).
is_label(I) ->
- hipe_x86:is_label(I).
+ case I of #label{} -> true; _ -> false end.
label_name(Label) ->
hipe_x86:label_label(Label).
diff --git a/lib/hipe/x86/hipe_x86_defuse.erl b/lib/hipe/x86/hipe_x86_defuse.erl
index 9cba6cbe4b..2731836dc1 100644
--- a/lib/hipe/x86/hipe_x86_defuse.erl
+++ b/lib/hipe/x86/hipe_x86_defuse.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% compute def/use sets for x86 insns
%%%
@@ -35,7 +29,7 @@
-endif.
-module(?HIPE_X86_DEFUSE).
--export([insn_def/1, insn_use/1]). %% src_use/1]).
+-export([insn_def/1, insn_defs_all/1, insn_use/1]). %% src_use/1]).
-include("../x86/hipe_x86.hrl").
%%%
@@ -57,13 +51,25 @@ insn_def(I) ->
#movzx{dst=Dst} -> dst_def(Dst);
#pseudo_call{} -> call_clobbered();
#pseudo_spill{} -> [];
+ #pseudo_spill_fmove{temp=Temp, dst=Dst} -> [Temp, Dst];
+ #pseudo_spill_move{temp=Temp, dst=Dst} -> [Temp, Dst];
#pseudo_tailcall_prepare{} -> tailcall_clobbered();
#shift{dst=Dst} -> dst_def(Dst);
%% call, cmp, comment, jcc, jmp_fun, jmp_label, jmp_switch, label
- %% pseudo_jcc, pseudo_tailcall, push, ret
+ %% pseudo_jcc, pseudo_tailcall, push, ret, test
_ -> []
end.
+
+%% @doc Answers whether instruction I defines all allocatable registers. Used by
+%% hipe_regalloc_prepass.
+-spec insn_defs_all(_) -> boolean().
+insn_defs_all(I) ->
+ case I of
+ #pseudo_call{} -> true;
+ _ -> false
+ end.
+
dst_def(Dst) ->
case Dst of
#x86_temp{} -> [Dst];
@@ -104,12 +110,15 @@ insn_use(I) ->
#pseudo_call{'fun'=Fun,sdesc=#x86_sdesc{arity=Arity}} ->
addtemp(Fun, arity_use(Arity));
#pseudo_spill{args=Args} -> Args;
+ #pseudo_spill_fmove{src=Src} -> [Src];
+ #pseudo_spill_move{src=Src} -> [Src];
#pseudo_tailcall{'fun'=Fun,arity=Arity,stkargs=StkArgs} ->
addtemp(Fun, addtemps(StkArgs, addtemps(tailcall_clobbered(),
arity_use(Arity))));
#push{src=Src} -> addtemp(Src, []);
#ret{} -> [hipe_x86:mk_temp(?HIPE_X86_REGISTERS:?RV(), 'tagged')];
#shift{src=Src,dst=Dst} -> addtemp(Src, addtemp(Dst, []));
+ #test{src=Src, dst=Dst} -> addtemp(Src, addtemp(Dst, []));
%% comment, jcc, jmp_label, label, pseudo_jcc, pseudo_tailcall_prepare
_ -> []
end.
diff --git a/lib/hipe/x86/hipe_x86_encode.erl b/lib/hipe/x86/hipe_x86_encode.erl
index 3b7be86608..2662f76d0b 100644
--- a/lib/hipe/x86/hipe_x86_encode.erl
+++ b/lib/hipe/x86/hipe_x86_encode.erl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Copyright (C) 2000-2005 Mikael Pettersson
%%%
@@ -65,6 +58,7 @@
cc/1,
% 8-bit registers
%% al/0, cl/0, dl/0, bl/0, ah/0, ch/0, dh/0, bh/0,
+ reg_has_8bit/1,
% 32-bit registers
%% eax/0, ecx/0, edx/0, ebx/0, esp/0, ebp/0, esi/0, edi/0,
% operands
@@ -143,6 +137,8 @@ cc(g) -> ?CC_G.
%% dh() -> ?DH.
%% bh() -> ?BH.
+reg_has_8bit(Reg) -> Reg =< ?BL.
+
%%% 32-bit registers
-define(EAX, 2#000).
@@ -700,8 +696,16 @@ shd_op_sizeof(Opnds) ->
test_encode(Opnds) ->
case Opnds of
+ {al, {imm8,Imm8}} ->
+ [16#A8, Imm8];
+ {ax, {imm16,Imm16}} ->
+ [?PFX_OPND, 16#A9 | le16(Imm16, [])];
{eax, {imm32,Imm32}} ->
[16#A9 | le32(Imm32, [])];
+ {{rm8,RM8}, {imm8,Imm8}} ->
+ [16#F6 | encode_rm(RM8, 2#000, [Imm8])];
+ {{rm16,RM16}, {imm16,Imm16}} ->
+ [?PFX_OPND, 16#F7 | encode_rm(RM16, 2#000, le16(Imm16, []))];
{{rm32,RM32}, {imm32,Imm32}} ->
[16#F7 | encode_rm(RM32, 2#000, le32(Imm32, []))];
{{rm32,RM32}, {reg32,Reg32}} ->
@@ -710,8 +714,16 @@ test_encode(Opnds) ->
test_sizeof(Opnds) ->
case Opnds of
+ {al, {imm8,_}} ->
+ 1 + 1;
+ {ax, {imm16,_}} ->
+ 2 + 2;
{eax, {imm32,_}} ->
1 + 4;
+ {{rm8,RM8}, {imm8,_}} ->
+ 1 + sizeof_rm(RM8) + 1;
+ {{rm16,RM16}, {imm16,_}} ->
+ 2 + sizeof_rm(RM16) + 2;
{{rm32,RM32}, {imm32,_}} ->
1 + sizeof_rm(RM32) + 4;
{{rm32,RM32}, {reg32,_}} ->
@@ -1283,7 +1295,11 @@ dotest1(OS) ->
t(OS,'sub',{RM32,Imm8}),
t(OS,'sub',{RM32,Reg32}),
t(OS,'sub',{Reg32,RM32}),
+ t(OS,'test',{al,Imm8}),
+ t(OS,'test',{ax,Imm16}),
t(OS,'test',{eax,Imm32}),
+ t(OS,'test',{RM8,Imm8}),
+ t(OS,'test',{RM16,Imm16}),
t(OS,'test',{RM32,Imm32}),
t(OS,'test',{RM32,Reg32}),
t(OS,'xor',{eax,Imm32}),
diff --git a/lib/hipe/x86/hipe_x86_encode.txt b/lib/hipe/x86/hipe_x86_encode.txt
index 13746e2a47..eab732fb2d 100644
--- a/lib/hipe/x86/hipe_x86_encode.txt
+++ b/lib/hipe/x86/hipe_x86_encode.txt
@@ -1,5 +1,3 @@
-$Id$
-
hipe_x86_encode USAGE GUIDE
Revision 0.4, 2001-10-09
diff --git a/lib/hipe/x86/hipe_x86_frame.erl b/lib/hipe/x86/hipe_x86_frame.erl
index 8851ead250..558321d0c3 100644
--- a/lib/hipe/x86/hipe_x86_frame.erl
+++ b/lib/hipe/x86/hipe_x86_frame.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% x86 stack frame handling
%%%
@@ -46,15 +40,13 @@
-include("../x86/hipe_x86.hrl").
-include("../rtl/hipe_literals.hrl").
-frame(Defun, _Options) ->
- Formals = fix_formals(hipe_x86:defun_formals(Defun)),
- Temps0 = all_temps(hipe_x86:defun_code(Defun), Formals),
- MinFrame = defun_minframe(Defun),
+frame(CFG0, _Options) ->
+ Formals = fix_formals(hipe_x86_cfg:params(CFG0)),
+ Temps0 = all_temps(CFG0, Formals),
+ MinFrame = defun_minframe(CFG0),
Temps = ensure_minframe(MinFrame, Temps0),
- CFG0 = hipe_x86_cfg:init(Defun),
Liveness = ?HIPE_X86_LIVENESS:analyse(CFG0),
- CFG1 = do_body(CFG0, Liveness, Formals, Temps),
- hipe_x86_cfg:linearise(CFG1).
+ do_body(CFG0, Liveness, Formals, Temps).
fix_formals(Formals) ->
fix_formals(?HIPE_X86_REGISTERS:nr_args(), Formals).
@@ -69,23 +61,14 @@ do_body(CFG0, Liveness, Formals, Temps) ->
do_prologue(CFG1, Context).
do_blocks(CFG, Context) ->
- Labels = hipe_x86_cfg:labels(CFG),
- do_blocks(Labels, CFG, Context).
+ hipe_x86_cfg:map_bbs(fun(Lbl, BB) -> do_block(Lbl, BB, Context) end, CFG).
-do_blocks([Label|Labels], CFG, Context) ->
+do_block(Label, Block, Context) ->
Liveness = context_liveness(Context),
LiveOut = ?HIPE_X86_LIVENESS:liveout(Liveness, Label),
- Block = hipe_x86_cfg:bb(CFG, Label),
Code = hipe_bb:code(Block),
- NewCode = do_block(Code, LiveOut, Context),
- NewBlock = hipe_bb:code_update(Block, NewCode),
- NewCFG = hipe_x86_cfg:bb_add(CFG, Label, NewBlock),
- do_blocks(Labels, NewCFG, Context);
-do_blocks([], CFG, _) ->
- CFG.
-
-do_block(Insns, LiveOut, Context) ->
- do_block(Insns, LiveOut, Context, context_framesize(Context), []).
+ NewCode = do_block(Code, LiveOut, Context, context_framesize(Context), []),
+ hipe_bb:code_update(Block, NewCode).
do_block([I|Insns], LiveOut, Context, FPoff0, RevCode) ->
{NewIs, FPoff1} = do_insn(I, LiveOut, Context, FPoff0),
@@ -112,13 +95,17 @@ do_insn(I, LiveOut, Context, FPoff) ->
#imul{} ->
{[do_imul(I, Context, FPoff)], FPoff};
#move{} ->
- {[do_move(I, Context, FPoff)], FPoff};
+ {do_move(I, Context, FPoff), FPoff};
#movsx{} ->
{[do_movsx(I, Context, FPoff)], FPoff};
#movzx{} ->
{[do_movzx(I, Context, FPoff)], FPoff};
#pseudo_call{} ->
do_pseudo_call(I, LiveOut, Context, FPoff);
+ #pseudo_spill_fmove{} ->
+ {do_pseudo_spill_fmove(I, Context, FPoff), FPoff};
+ #pseudo_spill_move{} ->
+ {do_pseudo_spill_move(I, Context, FPoff), FPoff};
#pseudo_tailcall{} ->
{do_pseudo_tailcall(I, Context), context_framesize(Context)};
#push{} ->
@@ -127,6 +114,8 @@ do_insn(I, LiveOut, Context, FPoff) ->
{do_ret(I, Context, FPoff), context_framesize(Context)};
#shift{} ->
{[do_shift(I, Context, FPoff)], FPoff};
+ #test{} ->
+ {[do_test(I, Context, FPoff)], FPoff};
_ -> % comment, jmp, label, pseudo_jcc, pseudo_tailcall_prepare
{[I], FPoff}
end.
@@ -159,22 +148,50 @@ do_fp_binop(I, Context, FPoff) ->
Dst = conv_opnd(Dst0, FPoff, Context),
[I#fp_binop{src=Src,dst=Dst}].
-do_fmove(I, Context, FPoff) ->
- #fmove{src=Src0,dst=Dst0} = I,
+do_fmove(I0, Context, FPoff) ->
+ #fmove{src=Src0,dst=Dst0} = I0,
Src = conv_opnd(Src0, FPoff, Context),
Dst = conv_opnd(Dst0, FPoff, Context),
- I#fmove{src=Src,dst=Dst}.
+ I = I0#fmove{src=Src,dst=Dst},
+ case Src =:= Dst of
+ true -> []; % omit move-to-self
+ false -> [I]
+ end.
+
+do_pseudo_spill_fmove(I0, Context, FPoff) ->
+ #pseudo_spill_fmove{src=Src0,temp=Temp0,dst=Dst0} = I0,
+ Src = conv_opnd(Src0, FPoff, Context),
+ Temp = conv_opnd(Temp0, FPoff, Context),
+ Dst = conv_opnd(Dst0, FPoff, Context),
+ case Src =:= Dst of
+ true -> []; % omit move-to-self
+ false -> [#fmove{src=Src, dst=Temp}, #fmove{src=Temp, dst=Dst}]
+ end.
do_imul(I, Context, FPoff) ->
#imul{src=Src0} = I,
Src = conv_opnd(Src0, FPoff, Context),
I#imul{src=Src}.
-do_move(I, Context, FPoff) ->
- #move{src=Src0,dst=Dst0} = I,
+do_move(I0, Context, FPoff) ->
+ #move{src=Src0,dst=Dst0} = I0,
Src = conv_opnd(Src0, FPoff, Context),
Dst = conv_opnd(Dst0, FPoff, Context),
- I#move{src=Src,dst=Dst}.
+ I = I0#move{src=Src,dst=Dst},
+ case Src =:= Dst of
+ true -> []; % omit move-to-self
+ false -> [I]
+ end.
+
+do_pseudo_spill_move(I0, Context, FPoff) ->
+ #pseudo_spill_move{src=Src0,temp=Temp0,dst=Dst0} = I0,
+ Src = conv_opnd(Src0, FPoff, Context),
+ Temp = conv_opnd(Temp0, FPoff, Context),
+ Dst = conv_opnd(Dst0, FPoff, Context),
+ case Src =:= Dst of
+ true -> []; % omit move-to-self
+ false -> [#move{src=Src, dst=Temp}, #move{src=Temp, dst=Dst}]
+ end.
do_movsx(I, Context, FPoff) ->
#movsx{src=Src0,dst=Dst0} = I,
@@ -199,6 +216,12 @@ do_shift(I, Context, FPoff) ->
Dst = conv_opnd(Dst0, FPoff, Context),
I#shift{src=Src,dst=Dst}.
+do_test(I, Context, FPoff) ->
+ #test{src=Src0,dst=Dst0} = I,
+ Src = conv_opnd(Src0, FPoff, Context),
+ Dst = conv_opnd(Dst0, FPoff, Context),
+ I#test{src=Src,dst=Dst}.
+
conv_opnd(Opnd, FPoff, Context) ->
case opnd_is_pseudo(Opnd) of
false ->
@@ -609,39 +632,46 @@ temp_is_pseudo(Temp) ->
%%% Build the set of all temps used in a Defun's body.
%%%
-all_temps(Code, Formals) ->
- S0 = find_temps(Code, tset_empty()),
+all_temps(CFG, Formals) ->
+ S0 = fold_insns(fun find_temps/2, tset_empty(), CFG),
S1 = tset_del_list(S0, Formals),
S2 = tset_filter(S1, fun(T) -> temp_is_pseudo(T) end),
S2.
-find_temps([I|Insns], S0) ->
+find_temps(I, S0) ->
S1 = tset_add_list(S0, hipe_x86_defuse:insn_def(I)),
- S2 = tset_add_list(S1, hipe_x86_defuse:insn_use(I)),
- find_temps(Insns, S2);
-find_temps([], S) ->
- S.
+ tset_add_list(S1, hipe_x86_defuse:insn_use(I)).
+
+fold_insns(Fun, InitAcc, CFG) ->
+ hipe_x86_cfg:fold_bbs(
+ fun(_, BB, Acc0) -> lists:foldl(Fun, Acc0, hipe_bb:code(BB)) end,
+ InitAcc, CFG).
+
+-compile({inline, [tset_empty/0, tset_size/1, tset_insert/2,
+ tset_filter/2, tset_to_list/1]}).
tset_empty() ->
- gb_sets:new().
+ #{}.
tset_size(S) ->
- gb_sets:size(S).
+ map_size(S).
tset_insert(S, T) ->
- gb_sets:add_element(T, S).
+ S#{T => []}.
-tset_add_list(S, Ts) ->
- gb_sets:union(S, gb_sets:from_list(Ts)).
+tset_add_list(S, []) -> S;
+tset_add_list(S, [T|Ts]) ->
+ tset_add_list(S#{T => []}, Ts).
-tset_del_list(S, Ts) ->
- gb_sets:subtract(S, gb_sets:from_list(Ts)).
+tset_del_list(S, []) -> S;
+tset_del_list(S, [T|Ts]) ->
+ tset_del_list(maps:remove(T,S), Ts).
tset_filter(S, F) ->
- gb_sets:filter(F, S).
+ maps:filter(fun(K, _V) -> F(K) end, S).
tset_to_list(S) ->
- gb_sets:to_list(S).
+ maps:keys(S).
%%%
%%% Compute minimum permissible frame size, ignoring spilled temps.
@@ -649,16 +679,11 @@ tset_to_list(S) ->
%%% in the middle of a tailcall.
%%%
-defun_minframe(Defun) ->
- MaxTailArity = body_mta(hipe_x86:defun_code(Defun), 0),
- MyArity = length(fix_formals(hipe_x86:defun_formals(Defun))),
+defun_minframe(CFG) ->
+ MaxTailArity = fold_insns(fun insn_mta/2, 0, CFG),
+ MyArity = length(fix_formals(hipe_x86_cfg:params(CFG))),
erlang:max(MaxTailArity - MyArity, 0).
-body_mta([I|Code], MTA) ->
- body_mta(Code, insn_mta(I, MTA));
-body_mta([], MTA) ->
- MTA.
-
insn_mta(I, MTA) ->
case I of
#pseudo_tailcall{arity=Arity} ->
diff --git a/lib/hipe/x86/hipe_x86_liveness.erl b/lib/hipe/x86/hipe_x86_liveness.erl
index ce46ec920e..470501b46d 100644
--- a/lib/hipe/x86/hipe_x86_liveness.erl
+++ b/lib/hipe/x86/hipe_x86_liveness.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% x86_liveness -- compute register liveness for x86 CFGs
diff --git a/lib/hipe/x86/hipe_x86_main.erl b/lib/hipe/x86/hipe_x86_main.erl
index 13b0bb6b28..7e9fd10e62 100644
--- a/lib/hipe/x86/hipe_x86_main.erl
+++ b/lib/hipe/x86/hipe_x86_main.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-ifdef(HIPE_AMD64).
-define(HIPE_X86_MAIN, hipe_amd64_main).
@@ -53,19 +46,23 @@
?RTL_TO_X86(MFA, RTL, Options) ->
Translated = ?option_time(?HIPE_RTL_TO_X86:translate(RTL),
"RTL-to-"?X86STR, Options),
- SpillRest =
+ TransCFG = ?option_time(hipe_x86_cfg:init(Translated),
+ ?X86STR" to cfg", Options),
+ SpillRestCFG =
case proplists:get_bool(caller_save_spill_restore, Options) of
true ->
- ?option_time(?HIPE_X86_SPILL_RESTORE:spill_restore(Translated, Options),
+ ?option_time(?HIPE_X86_SPILL_RESTORE:spill_restore(TransCFG, Options),
?X86STR" spill restore", Options);
false ->
- Translated
+ TransCFG
end,
- Allocated = ?option_time(?HIPE_X86_RA:ra(SpillRest, Options),
- ?X86STR" register allocation", Options),
- Framed = ?option_time(?HIPE_X86_FRAME:frame(Allocated, Options),
- ?X86STR" frame", Options),
- Finalised = ?option_time(hipe_x86_postpass:postpass(Framed, Options),
- ?X86STR" finalise", Options),
+ AllocatedCFG = ?option_time(?HIPE_X86_RA:ra(SpillRestCFG, Options),
+ ?X86STR" register allocation", Options),
+ FramedCFG = ?option_time(?HIPE_X86_FRAME:frame(AllocatedCFG, Options),
+ ?X86STR" frame", Options),
+ Framed = ?option_time(hipe_x86_cfg:linearise(FramedCFG),
+ ?X86STR" linearise", Options),
+ Finalised = ?option_time(hipe_x86_postpass:postpass(Framed, Options),
+ ?X86STR" finalise", Options),
?HIPE_X86_PP:optional_pp(Finalised, MFA, Options),
{native, ?X86TAG, {unprofiled, Finalised}}.
diff --git a/lib/hipe/x86/hipe_x86_postpass.erl b/lib/hipe/x86/hipe_x86_postpass.erl
index 939baeccec..925054dd68 100644
--- a/lib/hipe/x86/hipe_x86_postpass.erl
+++ b/lib/hipe/x86/hipe_x86_postpass.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%----------------------------------------------------------------------
%%% File : hipe_x86_postpass.erl
@@ -63,9 +57,10 @@ postpass(#defun{code=Code0}=Defun, Options) ->
peephole_optimization(Insns) ->
peep(Insns, [], []).
-%% MoveSelf related peep-opts
+
+%% MoveSelf related peep-opts
%% ------------------------------
-peep([#fmove{src=Src, dst=Src} | Insns], Res,Lst) ->
+peep([#fmove{src=Src, dst=Src} | Insns], Res,Lst) ->
peep(Insns, Res, [moveSelf1|Lst]);
peep([I=#fmove{src=Src, dst=Dst},
#fmove{src=Dst, dst=Src} | Insns], Res,Lst) ->
@@ -95,7 +90,8 @@ peep([I=#move{src=#x86_temp{reg=Src}, dst=#x86_temp{reg=Dst}},
%% ElimBinALMDouble
%% ----------------
-peep([Move=#move{src=Src, dst=Dst}, Alu=#alu{src=Src, dst=Dst}|Insns], Res, Lst) ->
+peep([Move=#move{src=Src, dst=Dst}, Alu=#alu{src=Src, dst=Dst}|Insns], Res, Lst)
+ when not is_record(Dst, x86_mem) ->
peep([Alu#alu{src=Dst}|Insns], [Move|Res], [elimBinALMDouble|Lst]);
@@ -119,19 +115,15 @@ peep([#move{src=Src1, dst=Dst},
%% ElimCmp0
%% --------
-peep([C=#cmp{src=Src, dst=Dst},J=#jcc{cc=Cond, label=Lab}|Insns],Res,Lst) ->
- case (((Src =:= #x86_imm{value=0}) or (Dst =:= #x86_imm{value=0})) and
- ((Cond =:= 'eq') or (Cond =:= 'neq'))) of
- true ->
- Src2 = case Src of #x86_imm{value=0} -> Src; _ -> Dst end,
- Cond2 = case Cond of 'eq' -> 'z'; 'neq' -> 'nz' end,
- Test = #test{src=Src2, dst=#x86_imm{value=0}},
- Jump = #jcc{cc=Cond2, label=Lab},
- peep(Insns, [Jump, Test|Res], [elimCmp0|Lst]);
- _ ->
- peep(Insns, [J,C|Res], Lst)
- end;
-
+peep([#cmp{src=#x86_imm{value=0}, dst=Dst=#x86_temp{}}|Insns],Res,Lst) ->
+ %% TEST leaves the adjust flag undefined, whereas CMP sets it properly (in
+ %% this case to 0). However, since HiPE does not use any instructions that
+ %% read the adjust flag, we can do this transform safely.
+ peep(Insns, [#test{src=Dst, dst=Dst} | Res], [elimCmp0_1|Lst]);
+peep([#cmp{src=Src=#x86_temp{}, dst=#x86_imm{value=0}},
+ J=#jcc{cc=Cond}|Insns],Res,Lst)
+ when Cond =:= 'e'; Cond =:= 'ne' -> % We're commuting the comparison
+ peep(Insns, [J, #test{src=Src, dst=Src} | Res], [elimCmp0_2|Lst]);
%% ElimCmpTest
%% -----------
@@ -168,8 +160,7 @@ peep([#jcc{label=Lab}, I=#label{label=Lab}|Insns], Res, Lst) ->
%% ElimSet0
%% --------
-peep([#move{src=#x86_imm{value=0},dst=Dst}|Insns],Res,Lst)
-when (Dst==#x86_temp{}) ->
+peep([#move{src=#x86_imm{value=0},dst=Dst=#x86_temp{}}|Insns],Res,Lst) ->
peep(Insns, [#alu{aluop='xor', src=Dst, dst=Dst}|Res], [elimSet0|Lst]);
%% ElimMDPow2
@@ -186,6 +177,18 @@ peep([B = #alu{aluop=Op,src=#x86_imm{value=Val},dst=Dst}|Insns], Res, Lst) ->
peep(Insns, [B|Res], Lst)
end;
+%% LeaToAdd
+%% This rule transforms lea into add when the destination is the same as one of
+%% the operands. Sound because lea is never used where the condition codes are
+%% live (and would be clobbered by add).
+%% ----------
+peep([#lea{mem=#x86_mem{base=#x86_temp{reg=DstR},off=Src},
+ temp=Dst=#x86_temp{reg=DstR}}|Insns], Res, Lst) ->
+ peep(Insns, [#alu{aluop='add',src=Src,dst=Dst}|Res], [leaToAdd|Lst]);
+peep([#lea{mem=#x86_mem{base=Src,off=#x86_temp{reg=DstR}},
+ temp=Dst=#x86_temp{reg=DstR}}|Insns], Res, Lst) ->
+ peep(Insns, [#alu{aluop='add',src=Src,dst=Dst}|Res], [leaToAdd|Lst]);
+
%% SubToDec
%% This rule turns "subl $1,Dst; jl Lab" into "decl Dst; jl Lab", which
%% changes reduction counter tests to use decl instead of subl.
@@ -208,6 +211,11 @@ trivial_goto_elimination(Insns) -> goto_elim(Insns, []).
goto_elim([#jmp_label{label=Label}, I = #label{label=Label}|Insns], Res) ->
goto_elim([I|Insns], Res);
+goto_elim([#jcc{cc=CC, label=Label} = IJCC,
+ #jmp_label{label=BranchTgt},
+ #label{label=Label} = ILBL|Insns], Res) ->
+ goto_elim([IJCC#jcc{cc=hipe_x86:neg_cc(CC), label=BranchTgt},
+ ILBL|Insns], Res);
goto_elim([I | Insns], Res) ->
goto_elim(Insns, [I|Res]);
goto_elim([], Res) ->
diff --git a/lib/hipe/x86/hipe_x86_pp.erl b/lib/hipe/x86/hipe_x86_pp.erl
index 9352cf5dbf..72d2fa80bf 100644
--- a/lib/hipe/x86/hipe_x86_pp.erl
+++ b/lib/hipe/x86/hipe_x86_pp.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% x86 pretty-printer
@@ -171,7 +165,7 @@ pp_insn(Dev, I, Pre) ->
#pseudo_tailcall{'fun'=Fun, arity=Arity, stkargs=StkArgs, linkage=Linkage} ->
io:format(Dev, "\tpseudo_tailcall ", []),
pp_fun(Dev, Fun),
- io:format(Dev, "~w (", [Arity]),
+ io:format(Dev, " ~w (", [Arity]),
pp_args(Dev, StkArgs),
io:format(Dev, ") ~w\n", [Linkage]);
#pseudo_tailcall_prepare{} ->
@@ -188,6 +182,12 @@ pp_insn(Dev, I, Pre) ->
io:format(Dev, ", ", []),
pp_dst(Dev, Dst),
io:format(Dev, "\n", []);
+ #test{src=Src, dst=Dst} ->
+ io:format(Dev, "\ttest ", []),
+ pp_src(Dev, Src),
+ io:format(Dev, ", ", []),
+ pp_dst(Dev, Dst),
+ io:format(Dev, "\n", []);
#fp_binop{src=Src, dst=Dst, op=Op} ->
io:format(Dev, "\t~s ", [Op]),
pp_dst(Dev, Dst),
diff --git a/lib/hipe/x86/hipe_x86_ra.erl b/lib/hipe/x86/hipe_x86_ra.erl
index f66961a7a7..f358306d49 100644
--- a/lib/hipe/x86/hipe_x86_ra.erl
+++ b/lib/hipe/x86/hipe_x86_ra.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-ifdef(HIPE_AMD64).
-define(HIPE_X86_RA, hipe_amd64_ra).
@@ -41,60 +34,83 @@
%%-define(HIPE_INSTRUMENT_COMPILER, true). %% Turn on instrumentation.
-include("../main/hipe.hrl").
-ra(Defun0, Options) ->
- %% ?HIPE_X86_PP:pp(Defun0),
- {Defun1, Coloring_fp, SpillIndex} = ra_fp(Defun0, Options),
- %% ?HIPE_X86_PP:pp(Defun1),
+-ifdef(HIPE_INSTRUMENT_COMPILER).
+code_size(CFG) ->
+ hipe_x86_cfg:fold_bbs(fun(_, BB, Acc) -> Acc + length(hipe_bb:code(BB)) end,
+ 0, CFG).
+-endif. %% ifdef(HIPE_INSTRUMENT_COMPILER)
+
+ra(CFG0, Options) ->
+ %% hipe_x86_cfg:pp(CFG0),
+ Liveness0 = ?HIPE_X86_SPECIFIC:analyze(CFG0, no_context),
+ {CFG1, Liveness, Coloring_fp, SpillIndex} = ra_fp(CFG0, Liveness0, Options),
+ %% hipe_x86_cfg:pp(CFG1),
?start_ra_instrumentation(Options,
- length(hipe_x86:defun_code(Defun1)),
- element(2,hipe_x86:defun_var_range(Defun1))),
- {Defun2, Coloring}
+ code_size(CFG1),
+ element(2,hipe_gensym:var_range(x86))),
+ {CFG2, _, Coloring}
= case proplists:get_value(regalloc, Options, coalescing) of
coalescing ->
- ra(Defun1, SpillIndex, Options, hipe_coalescing_regalloc);
+ ra(CFG1, Liveness, SpillIndex, Options, hipe_coalescing_regalloc);
optimistic ->
- ra(Defun1, SpillIndex, Options, hipe_optimistic_regalloc);
+ ra(CFG1, Liveness, SpillIndex, Options, hipe_optimistic_regalloc);
graph_color ->
- ra(Defun1, SpillIndex, Options, hipe_graph_coloring_regalloc);
+ ra(CFG1, Liveness, SpillIndex, Options, hipe_graph_coloring_regalloc);
linear_scan ->
- ?HIPE_X86_RA_LS:ra(Defun1, SpillIndex, Options);
+ ?HIPE_X86_RA_LS:ra(CFG1, Liveness, SpillIndex, Options);
naive ->
- ?HIPE_X86_RA_NAIVE:ra(Defun1, Coloring_fp, Options);
+ ?HIPE_X86_RA_NAIVE:ra(CFG1, Liveness, Coloring_fp, Options);
_ ->
exit({unknown_regalloc_compiler_option,
proplists:get_value(regalloc,Options)})
end,
?stop_ra_instrumentation(Options,
- length(hipe_x86:defun_code(Defun2)),
- element(2,hipe_x86:defun_var_range(Defun2))),
- %% ?HIPE_X86_PP:pp(Defun2),
- ?HIPE_X86_RA_FINALISE:finalise(Defun2, Coloring, Coloring_fp, Options).
+ code_size(CFG2),
+ element(2,hipe_gensym:var_range(x86))),
+ %% hipe_x86_cfg:pp(CFG2),
+ ?HIPE_X86_RA_FINALISE:finalise(CFG2, Coloring, Coloring_fp, Options).
-ra(Defun, SpillIndex, Options, RegAllocMod) ->
- hipe_regalloc_loop:ra(Defun, SpillIndex, Options, RegAllocMod, ?HIPE_X86_SPECIFIC).
+ra(CFG, Liveness, SpillIndex, Options, RegAllocMod) ->
+ hipe_regalloc_loop:ra(CFG, Liveness, SpillIndex, Options, RegAllocMod,
+ ?HIPE_X86_SPECIFIC, no_context).
-ifdef(HIPE_AMD64).
-ra_fp(Defun, Options) ->
- case proplists:get_bool(inline_fp, Options) and
- (proplists:get_value(regalloc, Options) =/= naive) of
- true ->
- case proplists:get_bool(x87, Options) of
- true ->
- hipe_amd64_ra_x87_ls:ra(Defun, Options);
- false ->
- hipe_regalloc_loop:ra_fp(Defun, Options,
- hipe_coalescing_regalloc,
- hipe_amd64_specific_sse2)
- end;
- false ->
- {Defun,[],0}
+ra_fp(CFG, Liveness, Options) ->
+ Regalloc0 = proplists:get_value(regalloc, Options),
+ {Regalloc, TargetMod} =
+ case proplists:get_bool(inline_fp, Options) and (Regalloc0 =/= naive) of
+ false -> {naive, undefined};
+ true ->
+ case proplists:get_bool(x87, Options) of
+ true -> {linear_scan, hipe_amd64_specific_x87};
+ false -> {Regalloc0, hipe_amd64_specific_sse2}
+ end
+ end,
+ case Regalloc of
+ coalescing ->
+ ra_fp(CFG, Liveness, Options, hipe_coalescing_regalloc, TargetMod);
+ optimistic ->
+ ra_fp(CFG, Liveness, Options, hipe_optimistic_regalloc, TargetMod);
+ graph_color ->
+ ra_fp(CFG, Liveness, Options, hipe_graph_coloring_regalloc, TargetMod);
+ linear_scan -> hipe_amd64_ra_ls:ra_fp(CFG, Liveness, Options, TargetMod,
+ no_context);
+ naive -> {CFG,Liveness,[],0};
+ _ ->
+ exit({unknown_regalloc_compiler_option,
+ proplists:get_value(regalloc,Options)})
end.
+
+ra_fp(CFG, Liveness, Options, RegAllocMod, TargetMod) ->
+ hipe_regalloc_loop:ra_fp(CFG, Liveness, Options, RegAllocMod, TargetMod,
+ no_context).
-else.
-ra_fp(Defun, Options) ->
+ra_fp(CFG, Liveness, Options) ->
case proplists:get_bool(inline_fp, Options) of
true ->
- hipe_x86_ra_x87_ls:ra(Defun, Options);
+ hipe_x86_ra_ls:ra_fp(CFG, Liveness, Options, hipe_x86_specific_x87,
+ no_context);
false ->
- {Defun,[],0}
+ {CFG,Liveness,[],0}
end.
-endif.
diff --git a/lib/hipe/x86/hipe_x86_ra_finalise.erl b/lib/hipe/x86/hipe_x86_ra_finalise.erl
index 5dd75cb7ae..e8abe78e00 100644
--- a/lib/hipe/x86/hipe_x86_ra_finalise.erl
+++ b/lib/hipe/x86/hipe_x86_ra_finalise.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
-%%%
%%%
%%% - apply temp -> reg/spill map from RA
@@ -25,23 +18,36 @@
-define(HIPE_X86_RA_FINALISE, hipe_amd64_ra_finalise).
-define(HIPE_X86_REGISTERS, hipe_amd64_registers).
-define(HIPE_X86_X87, hipe_amd64_x87).
+-define(HIPE_X86_SSE2, hipe_amd64_sse2).
+-define(IF_HAS_SSE2(Expr), Expr).
-else.
-define(HIPE_X86_RA_FINALISE, hipe_x86_ra_finalise).
-define(HIPE_X86_REGISTERS, hipe_x86_registers).
-define(HIPE_X86_X87, hipe_x86_x87).
+-define(IF_HAS_SSE2(Expr),).
-endif.
-module(?HIPE_X86_RA_FINALISE).
-export([finalise/4]).
-include("../x86/hipe_x86.hrl").
-finalise(Defun, TempMap, FpMap, Options) ->
- Defun1 = finalise_ra(Defun, TempMap, FpMap, Options),
+finalise(CFG0, TempMap, FpMap, Options) ->
+ CFG1 = finalise_ra(CFG0, TempMap, FpMap, Options),
case proplists:get_bool(x87, Options) of
true ->
- ?HIPE_X86_X87:map(Defun1);
+ ?HIPE_X86_X87:map(CFG1);
_ ->
- Defun1
+ case
+ proplists:get_bool(inline_fp, Options)
+ and (proplists:get_value(regalloc, Options) =:= linear_scan)
+ of
+ %% Ugly, but required to avoid Dialyzer complaints about "Unknown
+ %% function" hipe_x86_sse2:map/1
+ ?IF_HAS_SSE2(true ->
+ ?HIPE_X86_SSE2:map(CFG1);)
+ false ->
+ CFG1
+ end
end.
%%%
@@ -50,15 +56,16 @@ finalise(Defun, TempMap, FpMap, Options) ->
%%% but I just want this to work now)
%%%
-finalise_ra(Defun, [], [], _Options) ->
- Defun;
-finalise_ra(Defun, TempMap, FpMap, Options) ->
- Code = hipe_x86:defun_code(Defun),
- {_, SpillLimit} = hipe_x86:defun_var_range(Defun),
+finalise_ra(CFG, [], [], _Options) ->
+ CFG;
+finalise_ra(CFG, TempMap, FpMap, Options) ->
+ {_, SpillLimit} = hipe_gensym:var_range(x86),
Map = mk_ra_map(TempMap, SpillLimit),
FpMap0 = mk_ra_map_fp(FpMap, SpillLimit, Options),
- NewCode = ra_code(Code, Map, FpMap0),
- Defun#defun{code=NewCode}.
+ hipe_x86_cfg:map_bbs(fun(_Lbl, BB) -> ra_bb(BB, Map, FpMap0) end, CFG).
+
+ra_bb(BB, Map, FpMap) ->
+ hipe_bb:code_update(BB, ra_code(hipe_bb:code(BB), Map, FpMap)).
ra_code(Code, Map, FpMap) ->
[ra_insn(I, Map, FpMap) || I <- Code].
@@ -133,6 +140,16 @@ ra_insn(I, Map, FpMap) ->
I#pseudo_call{'fun'=Fun};
#pseudo_jcc{} ->
I;
+ #pseudo_spill_fmove{src=Src0, temp=Temp0, dst=Dst0} ->
+ Src = ra_opnd(Src0, Map, FpMap),
+ Temp = ra_opnd(Temp0, Map, FpMap),
+ Dst = ra_opnd(Dst0, Map, FpMap),
+ I#pseudo_spill_fmove{src=Src, temp=Temp, dst=Dst};
+ #pseudo_spill_move{src=Src0, temp=Temp0, dst=Dst0} ->
+ Src = ra_opnd(Src0, Map),
+ Temp = ra_opnd(Temp0, Map),
+ Dst = ra_opnd(Dst0, Map),
+ I#pseudo_spill_move{src=Src, temp=Temp, dst=Dst};
#pseudo_tailcall{'fun'=Fun0,stkargs=StkArgs0} ->
Fun = ra_opnd(Fun0, Map),
StkArgs = ra_args(StkArgs0, Map),
@@ -148,6 +165,10 @@ ra_insn(I, Map, FpMap) ->
Src = ra_opnd(Src0, Map),
Dst = ra_opnd(Dst0, Map),
I#shift{src=Src,dst=Dst};
+ #test{src=Src0,dst=Dst0} ->
+ Src = ra_opnd(Src0, Map),
+ Dst = ra_opnd(Dst0, Map),
+ I#test{src=Src,dst=Dst};
_ ->
exit({?MODULE,ra_insn,I})
end.
@@ -230,49 +251,27 @@ mk_ra_map(TempMap, SpillLimit) ->
gb_trees:empty(),
TempMap).
-conv_ra_maplet(MapLet = {From,To}, SpillLimit, IsPrecoloured) ->
+conv_ra_maplet({From,To}, SpillLimit, IsPrecoloured)
+ when is_integer(From), From =< SpillLimit ->
%% From should be a pseudo, or a hard reg mapped to itself.
- if is_integer(From), From =< SpillLimit ->
- case ?HIPE_X86_REGISTERS:IsPrecoloured(From) of
- false -> [];
- _ ->
- case To of
- {reg, From} -> [];
- _ -> exit({?MODULE,conv_ra_maplet,MapLet})
- end
- end;
- true -> exit({?MODULE,conv_ra_maplet,MapLet})
+ case ?HIPE_X86_REGISTERS:IsPrecoloured(From) of
+ false -> ok;
+ _ -> To = {reg, From}, ok
end,
%% end of From check
case To of
- {reg, NewReg} ->
+ {reg, NewReg} when is_integer(NewReg) ->
%% NewReg should be a hard reg, or a pseudo mapped
%% to itself (formals are handled this way).
- if is_integer(NewReg) ->
- case ?HIPE_X86_REGISTERS:IsPrecoloured(NewReg) of
- true -> [];
- _ -> if From =:= NewReg -> [];
- true ->
- exit({?MODULE,conv_ra_maplet,MapLet})
- end
- end;
- true -> exit({?MODULE,conv_ra_maplet,MapLet})
- end,
- %% end of NewReg check
+ true = (?HIPE_X86_REGISTERS:IsPrecoloured(NewReg) orelse From =:= NewReg),
{From, NewReg};
- {spill, SpillIndex} ->
- %% SpillIndex should be >= 0.
- if is_integer(SpillIndex), SpillIndex >= 0 -> [];
- true -> exit({?MODULE,conv_ra_maplet,MapLet})
- end,
- %% end of SpillIndex check
+ {spill, SpillIndex} when is_integer(SpillIndex), SpillIndex >= 0 ->
ToTempNum = SpillLimit+SpillIndex+1,
MaxTempNum = hipe_gensym:get_var(x86),
if MaxTempNum >= ToTempNum -> ok;
true -> hipe_gensym:set_var(x86, ToTempNum)
end,
- {From, ToTempNum};
- _ -> exit({?MODULE,conv_ra_maplet,MapLet})
+ {From, ToTempNum}
end.
mk_ra_map_x87(FpMap, SpillLimit) ->
diff --git a/lib/hipe/x86/hipe_x86_ra_ls.erl b/lib/hipe/x86/hipe_x86_ra_ls.erl
index 3e34433111..581abd299d 100644
--- a/lib/hipe/x86/hipe_x86_ra_ls.erl
+++ b/lib/hipe/x86/hipe_x86_ra_ls.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Linear Scan register allocator for x86
@@ -35,41 +29,64 @@
-endif.
-module(?HIPE_X86_RA_LS).
--export([ra/3,regalloc/7]).
+-export([ra/4,ra_fp/5]).
-define(HIPE_INSTRUMENT_COMPILER, true). %% Turn on instrumentation.
-include("../main/hipe.hrl").
-ra(Defun, SpillIndex, Options) ->
- NewDefun = Defun, %% hipe_${ARCH}_ra_rename:rename(Defun,Options),
- CFG = hipe_x86_cfg:init(NewDefun),
-
+ra(CFG, Liveness, SpillIndex, Options) ->
SpillLimit = ?HIPE_X86_SPECIFIC:number_of_temporaries(
- CFG),
+ CFG, no_context),
+ ?inc_counter(bbs_counter, length(hipe_x86_cfg:labels(CFG))),
+ alloc(CFG, Liveness, SpillIndex, SpillLimit, Options).
+
+ra_fp(CFG, Liveness, Options, TargetMod, TargetCtx) ->
+ ?inc_counter(ra_calls_counter,1),
+ %% ?inc_counter(ra_caller_saves_counter,count_caller_saves(CFG)),
+ SpillIndex = 0,
+ SpillLimit = TargetMod:number_of_temporaries(CFG, TargetCtx),
?inc_counter(bbs_counter, length(hipe_x86_cfg:labels(CFG))),
- alloc(NewDefun, SpillIndex, SpillLimit, Options).
+ ?inc_counter(ra_iteration_counter,1),
+ %% ?HIPE_X86_PP:pp(Defun),
+
+ {Coloring,NewSpillIndex} =
+ regalloc(CFG, Liveness,
+ TargetMod:allocatable('linearscan', TargetCtx),
+ [hipe_x86_cfg:start_label(CFG)],
+ SpillIndex, SpillLimit, Options,
+ TargetMod, TargetCtx),
+
+ {NewCFG, _DidSpill} =
+ TargetMod:check_and_rewrite(CFG, Coloring, 'linearscan', TargetCtx),
+ TempMap = hipe_temp_map:cols2tuple(Coloring, TargetMod, TargetCtx),
+ {TempMap2, NewSpillIndex2} =
+ hipe_spillmin:stackalloc(CFG, Liveness, [], SpillIndex, Options,
+ TargetMod, TargetCtx, TempMap),
+ Coloring2 =
+ hipe_spillmin:mapmerge(hipe_temp_map:to_substlist(TempMap), TempMap2),
+ ?add_spills(Options, NewSpillIndex),
+ {NewCFG, Liveness, Coloring2, NewSpillIndex2}.
-alloc(Defun, SpillIndex, SpillLimit, Options) ->
+alloc(CFG, Liveness, SpillIndex, SpillLimit, Options) ->
?inc_counter(ra_iteration_counter,1),
%% ?HIPE_X86_PP:pp(Defun),
- CFG = hipe_x86_cfg:init(Defun),
- {Coloring, NewSpillIndex} =
+ {Coloring, NewSpillIndex} =
regalloc(
- CFG,
+ CFG, Liveness,
?HIPE_X86_REGISTERS:allocatable()--
[?HIPE_X86_REGISTERS:temp1(),
?HIPE_X86_REGISTERS:temp0()],
[hipe_x86_cfg:start_label(CFG)],
SpillIndex, SpillLimit, Options,
- ?HIPE_X86_SPECIFIC),
- {NewDefun, _DidSpill} =
+ ?HIPE_X86_SPECIFIC, no_context),
+ {NewCFG, _DidSpill} =
?HIPE_X86_RA_POSTCONDITIONS:check_and_rewrite(
- Defun, Coloring, 'linearscan'),
+ CFG, Coloring, 'linearscan'),
%% ?HIPE_X86_PP:pp(NewDefun),
- TempMap = hipe_temp_map:cols2tuple(Coloring, ?HIPE_X86_SPECIFIC),
- {TempMap2,NewSpillIndex2} =
- hipe_spillmin:stackalloc(CFG, [], SpillIndex, Options,
- ?HIPE_X86_SPECIFIC, TempMap),
+ TempMap = hipe_temp_map:cols2tuple(Coloring, ?HIPE_X86_SPECIFIC, no_context),
+ {TempMap2,NewSpillIndex2} =
+ hipe_spillmin:stackalloc(CFG, Liveness, [], SpillIndex, Options,
+ ?HIPE_X86_SPECIFIC, no_context, TempMap),
Coloring2 =
hipe_spillmin:mapmerge(hipe_temp_map:to_substlist(TempMap), TempMap2),
case proplists:get_bool(verbose_spills, Options) of
@@ -79,8 +96,9 @@ alloc(Defun, SpillIndex, SpillLimit, Options) ->
ok
end,
?add_spills(Options, NewSpillIndex),
- {NewDefun, Coloring2}.
+ {NewCFG, Liveness, Coloring2}.
-regalloc(CFG,PhysRegs,Entrypoints, SpillIndex, DontSpill, Options, Target) ->
- hipe_ls_regalloc:regalloc(CFG,PhysRegs,Entrypoints, SpillIndex,
- DontSpill, Options, Target).
+regalloc(CFG, Liveness, PhysRegs, Entrypoints, SpillIndex, DontSpill, Options,
+ TgtMod, TgtCtx) ->
+ hipe_ls_regalloc:regalloc(CFG, Liveness, PhysRegs, Entrypoints, SpillIndex,
+ DontSpill, Options, TgtMod, TgtCtx).
diff --git a/lib/hipe/x86/hipe_x86_ra_naive.erl b/lib/hipe/x86/hipe_x86_ra_naive.erl
index 0ef4ef0a04..f96c662d18 100644
--- a/lib/hipe/x86/hipe_x86_ra_naive.erl
+++ b/lib/hipe/x86/hipe_x86_ra_naive.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% simple local x86 regalloc
@@ -33,15 +27,14 @@
-endif.
-module(?HIPE_X86_RA_NAIVE).
--export([ra/3]).
+-export([ra/4]).
-include("../x86/hipe_x86.hrl").
-define(HIPE_INSTRUMENT_COMPILER, true). % enable instrumentation
-include("../main/hipe.hrl").
-ra(X86Defun, Coloring_fp, Options) ->
- #defun{code=Code0} = X86Defun,
- Code1 = do_insns(Code0),
+ra(CFG0, Liveness, Coloring_fp, Options) ->
+ CFG = hipe_x86_cfg:map_bbs(fun do_bb/2, CFG0),
NofSpilledFloats = count_non_float_spills(Coloring_fp),
NofFloats = length(Coloring_fp),
?add_spills(Options, hipe_gensym:get_var(x86) -
@@ -49,15 +42,17 @@ ra(X86Defun, Coloring_fp, Options) ->
NofSpilledFloats -
NofFloats),
TempMap = [],
- {X86Defun#defun{code=Code1,
- var_range={0, hipe_gensym:get_var(x86)}},
+ {CFG, Liveness,
TempMap}.
+do_bb(_Lbl, BB) ->
+ hipe_bb:code_update(BB, do_insns(hipe_bb:code(BB))).
+
count_non_float_spills(Coloring_fp) ->
count_non_float_spills(Coloring_fp, 0).
count_non_float_spills([{_,To}|Tail], Num) ->
- case ?HIPE_X86_SPECIFIC_FP:is_precoloured(To) of
+ case ?HIPE_X86_SPECIFIC_FP:is_precoloured(To, no_context) of
true ->
count_non_float_spills(Tail, Num);
false ->
@@ -99,6 +94,8 @@ do_insn(I) -> % Insn -> Insn list
do_fp_binop(I);
#shift{} ->
do_shift(I);
+ #test{} ->
+ do_test(I);
#label{} ->
[I];
#pseudo_jcc{} ->
@@ -309,6 +306,11 @@ do_shift(I) ->
FixDst ++ [I#shift{dst=Dst}]
end.
+do_test(I) ->
+ #test{src=Src0,dst=Dst0} = I,
+ {FixSrc, Src, FixDst, Dst} = do_binary(Src0, Dst0),
+ FixSrc ++ FixDst ++ [I#test{src=Src,dst=Dst}].
+
%%% Fix the operands of a binary op.
%%% 1. remove pseudos from any explicit memory operands
%%% 2. if both operands are (implicit or explicit) memory operands,
diff --git a/lib/hipe/x86/hipe_x86_ra_postconditions.erl b/lib/hipe/x86/hipe_x86_ra_postconditions.erl
index 0a70bd1d22..db6391d5c1 100644
--- a/lib/hipe/x86/hipe_x86_ra_postconditions.erl
+++ b/lib/hipe/x86/hipe_x86_ra_postconditions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-ifdef(HIPE_AMD64).
-define(HIPE_X86_RA_POSTCONDITIONS, hipe_amd64_ra_postconditions).
@@ -40,14 +33,18 @@
-include("../main/hipe.hrl").
-define(count_temp(T), ?cons_counter(counter_mfa_mem_temps, T)).
-check_and_rewrite(Defun, Coloring, Strategy) ->
+check_and_rewrite(CFG, Coloring, Strategy) ->
%% io:format("Converting\n"),
- TempMap = hipe_temp_map:cols2tuple(Coloring, ?HIPE_X86_SPECIFIC),
+ TempMap = hipe_temp_map:cols2tuple(Coloring, ?HIPE_X86_SPECIFIC, no_context),
%% io:format("Rewriting\n"),
- #defun{code=Code0} = Defun,
- {Code1, DidSpill} = do_insns(Code0, TempMap, Strategy, [], false),
- {Defun#defun{code=Code1,var_range={0,hipe_gensym:get_var(x86)}},
- DidSpill}.
+ do_bbs(hipe_x86_cfg:labels(CFG), TempMap, Strategy, CFG, false).
+
+do_bbs([], _, _, CFG, DidSpill) -> {CFG, DidSpill};
+do_bbs([Lbl|Lbls], TempMap, Strategy, CFG0, DidSpill0) ->
+ Code0 = hipe_bb:code(BB = hipe_x86_cfg:bb(CFG0, Lbl)),
+ {Code, DidSpill} = do_insns(Code0, TempMap, Strategy, [], DidSpill0),
+ CFG = hipe_x86_cfg:bb_add(CFG0, Lbl, hipe_bb:code_update(BB, Code)),
+ do_bbs(Lbls, TempMap, Strategy, CFG, DidSpill).
do_insns([I|Insns], TempMap, Strategy, Accum, DidSpill0) ->
{NewIs, DidSpill1} = do_insn(I, TempMap, Strategy),
@@ -77,8 +74,12 @@ do_insn(I, TempMap, Strategy) -> % Insn -> {Insn list, DidSpill}
do_movx(I, TempMap, Strategy);
#fmove{} ->
do_fmove(I, TempMap, Strategy);
+ #pseudo_spill_move{} ->
+ do_pseudo_spill_move(I, TempMap, Strategy);
#shift{} ->
do_shift(I, TempMap, Strategy);
+ #test{} ->
+ do_test(I, TempMap, Strategy);
_ ->
%% comment, jmp*, label, pseudo_call, pseudo_jcc, pseudo_tailcall,
%% pseudo_tailcall_prepare, push, ret
@@ -169,24 +170,41 @@ do_jmp_switch(I, TempMap, Strategy) ->
%%% Fix a lea op.
do_lea(I, TempMap, Strategy) ->
- #lea{temp=Temp} = I,
- case is_spilled(Temp, TempMap) of
- false ->
- {[I], false};
- true ->
- NewTmp = spill_temp('untagged', Strategy),
- {[I#lea{temp=NewTmp}, hipe_x86:mk_move(NewTmp, Temp)],
- true}
+ #lea{mem=Mem0,temp=Temp0} = I,
+ {FixMem, Mem, DidSpill1} = fix_mem_operand(Mem0, TempMap, temp1(Strategy)),
+ case Mem of
+ #x86_mem{base=Base, off=#x86_imm{value=0}} ->
+ %% We've decayed into a move due to both operands being memory (there's an
+ %% 'add' in FixMem).
+ {FixMem ++ [hipe_x86:mk_move(Base, Temp0)], DidSpill1};
+ #x86_mem{} ->
+ {StoreTemp, Temp, DidSpill2} =
+ case is_mem_opnd(Temp0, TempMap) of
+ false -> {[], Temp0, false};
+ true ->
+ Temp1 = clone2(Temp0, temp0(Strategy)),
+ {[hipe_x86:mk_move(Temp1, Temp0)], Temp1, true}
+ end,
+ {FixMem ++ [I#lea{mem=Mem,temp=Temp} | StoreTemp], DidSpill1 or DidSpill2}
end.
%%% Fix a move op.
do_move(I, TempMap, Strategy) ->
#move{src=Src0,dst=Dst0} = I,
- {FixSrc, Src, FixDst, Dst, DidSpill} =
- do_check_byte_move(Src0, Dst0, TempMap, Strategy),
- {FixSrc ++ FixDst ++ [I#move{src=Src,dst=Dst}],
- DidSpill}.
+ case
+ is_record(Src0, x86_temp) andalso is_record(Dst0, x86_temp)
+ andalso is_spilled(Src0, TempMap) andalso is_spilled(Dst0, TempMap)
+ of
+ true ->
+ Tmp = clone(Src0, Strategy),
+ {[hipe_x86:mk_pseudo_spill_move(Src0, Tmp, Dst0)], true};
+ false ->
+ {FixSrc, Src, FixDst, Dst, DidSpill} =
+ do_check_byte_move(Src0, Dst0, TempMap, Strategy),
+ {FixSrc ++ FixDst ++ [I#move{src=Src,dst=Dst}],
+ DidSpill}
+ end.
-ifdef(HIPE_AMD64).
@@ -280,6 +298,13 @@ do_fmove(I, TempMap, Strategy) ->
{FixSrc ++ FixDst ++ [I#fmove{src=Src,dst=Dst}],
DidSpill1 or DidSpill2}.
+%%% Fix an pseudo_spill_move op.
+
+do_pseudo_spill_move(I = #pseudo_spill_move{temp=Temp}, TempMap, _Strategy) ->
+ %% Temp is above the low water mark and must not have been spilled
+ false = is_spilled(Temp, TempMap),
+ {[I], false}. % nothing to do
+
%%% Fix a shift operation.
%%% 1. remove pseudos from any explicit memory operands
%%% 2. if the source is a register or memory position
@@ -296,6 +321,14 @@ do_shift(I, TempMap, Strategy) ->
{FixDst ++ [I#shift{dst=Dst}], DidSpill}
end.
+%%% Fix a test op.
+
+do_test(I, TempMap, Strategy) ->
+ #test{src=Src0,dst=Dst0} = I,
+ {FixSrc, Src, FixDst, Dst, DidSpill} =
+ do_binary(Src0, Dst0, TempMap, Strategy),
+ {FixSrc ++ FixDst ++ [I#test{src=Src,dst=Dst}], DidSpill}.
+
%%% Fix the operands of a binary op.
%%% 1. remove pseudos from any explicit memory operands
%%% 2. if both operands are (implicit or explicit) memory operands,
@@ -377,19 +410,12 @@ is_mem_opnd(Opnd, TempMap) ->
Reg = hipe_x86:temp_reg(Opnd),
case hipe_x86:temp_is_allocatable(Opnd) of
true ->
- case tuple_size(TempMap) > Reg of
+ case
+ hipe_temp_map:is_spilled(Reg, TempMap) of
true ->
- case
- hipe_temp_map:is_spilled(Reg, TempMap) of
- true ->
- ?count_temp(Reg),
- true;
- false -> false
- end;
- _ ->
- %% impossible, but was true in ls post and false in normal post
- exit({?MODULE,is_mem_opnd,Reg}),
- false
+ ?count_temp(Reg),
+ true;
+ false -> false
end;
false -> true
end;
@@ -404,15 +430,10 @@ is_spilled(Temp, TempMap) ->
case hipe_x86:temp_is_allocatable(Temp) of
true ->
Reg = hipe_x86:temp_reg(Temp),
- case tuple_size(TempMap) > Reg of
+ case hipe_temp_map:is_spilled(Reg, TempMap) of
true ->
- case hipe_temp_map:is_spilled(Reg, TempMap) of
- true ->
- ?count_temp(Reg),
- true;
- false ->
- false
- end;
+ ?count_temp(Reg),
+ true;
false ->
false
end;
@@ -429,14 +450,14 @@ clone(Dst, Strategy) ->
end,
spill_temp(Type, Strategy).
-spill_temp0(Type, 'normal') ->
+spill_temp0(Type, 'normal') when Type =/= double ->
hipe_x86:mk_new_temp(Type);
-spill_temp0(Type, 'linearscan') ->
+spill_temp0(Type, 'linearscan') when Type =/= double ->
hipe_x86:mk_temp(?HIPE_X86_REGISTERS:temp0(), Type).
-spill_temp(Type, 'normal') ->
+spill_temp(Type, 'normal') when Type =/= double ->
hipe_x86:mk_new_temp(Type);
-spill_temp(Type, 'linearscan') ->
+spill_temp(Type, 'linearscan') when Type =/= double ->
hipe_x86:mk_temp(?HIPE_X86_REGISTERS:temp1(), Type).
%%% Make a certain reg into a clone of Dst
@@ -448,6 +469,6 @@ clone2(Dst, RegOpt) ->
#x86_temp{} -> hipe_x86:temp_type(Dst)
end,
case RegOpt of
- [] -> hipe_x86:mk_new_temp(Type);
+ [] when Type =/= double -> hipe_x86:mk_new_temp(Type);
Reg -> hipe_x86:mk_temp(Reg, Type)
end.
diff --git a/lib/hipe/x86/hipe_x86_ra_x87_ls.erl b/lib/hipe/x86/hipe_x86_ra_x87_ls.erl
deleted file mode 100644
index 1ee76e5948..0000000000
--- a/lib/hipe/x86/hipe_x86_ra_x87_ls.erl
+++ /dev/null
@@ -1,64 +0,0 @@
-%% $Id$
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%% Linear Scan register allocator for x87
-
--ifdef(HIPE_AMD64).
--define(HIPE_X86_RA_X87_LS, hipe_amd64_ra_x87_ls).
--define(HIPE_X86_SPECIFIC_X87, hipe_amd64_specific_x87).
--define(HIPE_X86_PP, hipe_amd64_pp).
--define(HIPE_X86_RA_LS, hipe_amd64_ra_ls).
--else.
--define(HIPE_X86_RA_X87_LS, hipe_x86_ra_x87_ls).
--define(HIPE_X86_SPECIFIC_X87, hipe_x86_specific_x87).
--define(HIPE_X86_PP, hipe_x86_pp).
--define(HIPE_X86_RA_LS, hipe_x86_ra_ls).
--endif.
-
--module(?HIPE_X86_RA_X87_LS).
--export([ra/2]).
-
-%%-define(DEBUG,1).
-
--define(HIPE_INSTRUMENT_COMPILER, false). %% Turn off instrumentation.
--include("../main/hipe.hrl").
-
-ra(Defun, Options) ->
- ?inc_counter(ra_calls_counter,1),
- CFG = hipe_x86_cfg:init(Defun),
- %% ?inc_counter(ra_caller_saves_counter,count_caller_saves(CFG)),
- SpillIndex = 0,
- SpillLimit = ?HIPE_X86_SPECIFIC_X87:number_of_temporaries(CFG),
- ?inc_counter(bbs_counter, length(hipe_x86_cfg:labels(CFG))),
-
- ?inc_counter(ra_iteration_counter,1),
- %% ?HIPE_X86_PP:pp(Defun),
- Cfg = hipe_x86_cfg:init(Defun), % XXX: didn't we just compute this above?
-
- {Coloring,NewSpillIndex} =
- ?HIPE_X86_RA_LS:regalloc(Cfg,
- ?HIPE_X86_SPECIFIC_X87:allocatable(),
- [hipe_x86_cfg:start_label(Cfg)],
- SpillIndex, SpillLimit, Options,
- ?HIPE_X86_SPECIFIC_X87),
-
- ?add_spills(Options, NewSpillIndex),
- {Defun, Coloring, NewSpillIndex}.
diff --git a/lib/hipe/x86/hipe_x86_registers.erl b/lib/hipe/x86/hipe_x86_registers.erl
index 179d734501..dbff68ad28 100644
--- a/lib/hipe/x86/hipe_x86_registers.erl
+++ b/lib/hipe/x86/hipe_x86_registers.erl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,9 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
-%%%
%%%
%%% TODO:
%%% - Do we need a pseudo reg for the condition codes?
@@ -224,6 +216,8 @@ ret(N) ->
exit({?MODULE, ret, N})
end.
+%% Note: the fact that (allocatable() UNION allocatable_x87()) is a subset of
+%% call_clobbered() is hard-coded in hipe_x86_defuse:insn_defs_all/1
call_clobbered() ->
[{?EAX,tagged},{?EAX,untagged}, % does the RA strip the type or not?
{?EDX,tagged},{?EDX,untagged},
diff --git a/lib/hipe/x86/hipe_x86_spill_restore.erl b/lib/hipe/x86/hipe_x86_spill_restore.erl
index f17b91f33b..90edef31f3 100644
--- a/lib/hipe/x86/hipe_x86_spill_restore.erl
+++ b/lib/hipe/x86/hipe_x86_spill_restore.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%% ====================================================================
%% Authors : Dogan Yazar and Erdem Aksu (KT2 project of 2008)
%% ====================================================================
@@ -25,13 +19,11 @@
-ifdef(HIPE_AMD64).
-define(HIPE_X86_SPILL_RESTORE, hipe_amd64_spill_restore).
-define(HIPE_X86_LIVENESS, hipe_amd64_liveness).
--define(HIPE_X86_SPECIFIC, hipe_amd64_specific).
-define(HIPE_X86_REGISTERS, hipe_amd64_registers).
-define(X86STR, "amd64").
-else.
-define(HIPE_X86_SPILL_RESTORE, hipe_x86_spill_restore).
-define(HIPE_X86_LIVENESS, hipe_x86_liveness).
--define(HIPE_X86_SPECIFIC, hipe_x86_specific).
-define(HIPE_X86_REGISTERS, hipe_x86_registers).
-define(X86STR, "x86").
-endif.
@@ -51,15 +43,13 @@
-include("../flow/cfg.hrl"). % Added for the definition of #cfg{}
%% Main function
-spill_restore(Defun, Options) ->
- CFG = ?option_time(firstPass(Defun), ?X86STR" First Pass", Options),
- CFGFinal = ?option_time(secondPass(CFG), ?X86STR" Second Pass", Options),
- hipe_x86_cfg:linearise(CFGFinal).
+spill_restore(CFG0, Options) ->
+ CFG1 = ?option_time(firstPass(CFG0), ?X86STR" First Pass", Options),
+ ?option_time(secondPass(CFG1), ?X86STR" Second Pass", Options).
%% Performs the first pass of the algorithm.
%% By working bottom up, introduce the pseudo_spills.
-firstPass(Defun) ->
- CFG0 = ?HIPE_X86_SPECIFIC:defun_to_cfg(Defun),
+firstPass(CFG0) ->
%% get the labels bottom up
Labels = hipe_x86_cfg:postorder(CFG0),
Liveness = ?HIPE_X86_LIVENESS:analyse(CFG0),
diff --git a/lib/hipe/x86/hipe_x86_subst.erl b/lib/hipe/x86/hipe_x86_subst.erl
new file mode 100644
index 0000000000..7db3b23d92
--- /dev/null
+++ b/lib/hipe/x86/hipe_x86_subst.erl
@@ -0,0 +1,112 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+-ifdef(HIPE_AMD64).
+-define(HIPE_X86_SUBST, hipe_amd64_subst).
+-else.
+-define(HIPE_X86_SUBST, hipe_x86_subst).
+-endif.
+
+-module(?HIPE_X86_SUBST).
+-export([insn_temps/2, insn_lbls/2]).
+-include("../x86/hipe_x86.hrl").
+
+%% These should be moved to hipe_x86 and exported
+-type temp() :: #x86_temp{}.
+-type oper() :: temp() | #x86_imm{} | #x86_mem{}.
+-type mfarec() :: #x86_mfa{}.
+-type prim() :: #x86_prim{}.
+-type funv() :: mfarec() | prim() | temp().
+-type label() :: non_neg_integer().
+-type insn() :: tuple(). % for now
+
+-type subst_fun() :: fun((temp()) -> temp()).
+
+%% @doc Maps over the temporaries in an instruction
+-spec insn_temps(subst_fun(), insn()) -> insn().
+insn_temps(SubstTemp, I) ->
+ O = fun(O) -> oper_temps(SubstTemp, O) end,
+ case I of
+ #alu {src=S, dst=D} -> I#alu {src=O(S), dst=O(D)};
+ #cmovcc {src=S, dst=D} -> I#cmovcc {src=O(S), dst=O(D)};
+ #cmp {src=S, dst=D} -> I#cmp {src=O(S), dst=O(D)};
+ #fmove {src=S, dst=D} -> I#fmove {src=O(S), dst=O(D)};
+ #fp_binop{src=S, dst=D} -> I#fp_binop{src=O(S), dst=O(D)};
+ #imul {src=S, temp=T} -> I#imul {src=O(S), temp=O(T)};
+ #lea {mem=M, temp=T} -> I#lea {mem=O(M), temp=O(T)};
+ #move {src=S, dst=D} -> I#move {src=O(S), dst=O(D)};
+ #movsx {src=S, dst=D} -> I#movsx {src=O(S), dst=O(D)};
+ #movzx {src=S, dst=D} -> I#movzx {src=O(S), dst=O(D)};
+ #shift {src=S, dst=D} -> I#shift {src=O(S), dst=O(D)};
+ #test {src=S, dst=D} -> I#test {src=O(S), dst=O(D)};
+ #fp_unop{arg=[]} -> I;
+ #fp_unop{arg=A} -> I#fp_unop{arg=O(A)};
+ #move64 {dst=D} -> I#move64 {dst=O(D)};
+ #push {src=S} -> I#push {src=O(S)};
+ #pop {dst=D} -> I#pop {dst=O(D)};
+ #jmp_switch{temp=T, jtab=J} ->
+ I#jmp_switch{temp=O(T), jtab=jtab_temps(SubstTemp, J)};
+ #pseudo_call{'fun'=F} ->
+ I#pseudo_call{'fun'=funv_temps(SubstTemp, F)};
+ #pseudo_spill_fmove{src=S, temp=T, dst=D} ->
+ I#pseudo_spill_fmove{src=O(S), temp=O(T), dst=O(D)};
+ #pseudo_spill_move{src=S, temp=T, dst=D} ->
+ I#pseudo_spill_move{src=O(S), temp=O(T), dst=O(D)};
+ #pseudo_tailcall{'fun'=F, stkargs=Stk} ->
+ I#pseudo_tailcall{'fun'=funv_temps(SubstTemp, F),
+ stkargs=lists:map(O, Stk)};
+ #comment{} -> I;
+ #jmp_label{} -> I;
+ #pseudo_tailcall_prepare{} -> I;
+ #pseudo_jcc{} -> I;
+ #ret{} -> I
+ end.
+
+-spec oper_temps(subst_fun(), oper()) -> oper().
+oper_temps(_SubstTemp, I=#x86_imm{}) -> I;
+oper_temps(SubstTemp, T=#x86_temp{}) -> SubstTemp(T);
+oper_temps(SubstTemp, M=#x86_mem{base=Base,off=Off}) ->
+ M#x86_mem{base=oper_temps(SubstTemp, Base),
+ off =oper_temps(SubstTemp, Off)}.
+
+-spec funv_temps(subst_fun(), funv()) -> funv().
+funv_temps(_SubstTemp, MFA=#x86_mfa{}) -> MFA;
+funv_temps(_SubstTemp, P=#x86_prim{}) -> P;
+funv_temps(SubstTemp, T=#x86_temp{}) -> SubstTemp(T).
+
+%% TODO: Undo this ifdeffery at the source (make jtab an #x86_imm{} on x86)
+-ifdef(HIPE_AMD64).
+jtab_temps(SubstTemp, T=#x86_temp{}) -> SubstTemp(T).
+-else.
+jtab_temps(_SubstTemp, DataLbl) when is_integer(DataLbl) -> DataLbl.
+-endif.
+
+-type lbl_subst_fun() :: fun((label()) -> label()).
+
+%% @doc Maps over the branch targets in an instruction
+-spec insn_lbls(lbl_subst_fun(), insn()) -> insn().
+insn_lbls(SubstLbl, I) ->
+ case I of
+ #jmp_label{label=Label} ->
+ I#jmp_label{label=SubstLbl(Label)};
+ #pseudo_call{sdesc=Sdesc, contlab=Contlab} ->
+ I#pseudo_call{sdesc=sdesc_lbls(SubstLbl, Sdesc),
+ contlab=SubstLbl(Contlab)};
+ #pseudo_jcc{true_label=T, false_label=F} ->
+ I#pseudo_jcc{true_label=SubstLbl(T), false_label=SubstLbl(F)}
+ end.
+
+sdesc_lbls(_SubstLbl, Sdesc=#x86_sdesc{exnlab=[]}) -> Sdesc;
+sdesc_lbls(SubstLbl, Sdesc=#x86_sdesc{exnlab=Exnlab}) ->
+ Sdesc#x86_sdesc{exnlab=SubstLbl(Exnlab)}.
diff --git a/lib/hipe/x86/hipe_x86_x87.erl b/lib/hipe/x86/hipe_x86_x87.erl
index e874490252..85268ab85a 100644
--- a/lib/hipe/x86/hipe_x86_x87.erl
+++ b/lib/hipe/x86/hipe_x86_x87.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% Floating point handling.
@@ -41,13 +35,12 @@
%%----------------------------------------------------------------------
-map(Defun) ->
- CFG0 = hipe_x86_cfg:init(Defun),
+map(CFG0) ->
%% hipe_x86_cfg:pp(CFG0),
Liveness = ?HIPE_X86_LIVENESS:analyse(CFG0),
StartLabel = hipe_x86_cfg:start_label(CFG0),
{CFG1,_} = do_blocks([], [StartLabel], CFG0, Liveness, [], gb_trees:empty()),
- hipe_x86_cfg:linearise(CFG1).
+ CFG1.
do_blocks(Pred, [Lbl|Lbls], CFG, Liveness, Map, BlockMap) ->
case gb_trees:lookup(Lbl, BlockMap) of
diff --git a/lib/ic/doc/src/Makefile b/lib/ic/doc/src/Makefile
index c9691df7af..19f12ac6b9 100644
--- a/lib/ic/doc/src/Makefile
+++ b/lib/ic/doc/src/Makefile
@@ -225,7 +225,7 @@ release_docs_spec: docs
$(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf"
$(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)"
$(INSTALL_DIR) "$(RELSYSDIR)/doc/html"
- (/bin/cp -rf $(HTMLDIR) "$(RELSYSDIR)/doc")
+ ($(CP) -rf $(HTMLDIR) "$(RELSYSDIR)/doc")
$(INSTALL_DIR) "$(RELEASE_PATH)/man/man3"
$(INSTALL_DATA) $(MAN3_FILES) "$(RELEASE_PATH)/man/man3"
diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml
index 08b02bc4a4..ea8bf758cf 100644
--- a/lib/ic/doc/src/notes.xml
+++ b/lib/ic/doc/src/notes.xml
@@ -31,7 +31,29 @@
<file>notes.xml</file>
</header>
- <section><title>IC 4.4.1</title>
+ <section><title>IC 4.4.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Correct bugs when path to mib or idl spec files
+ contains UTF-8 characters. </p>
+ <p>
+ Own Id: OTP-13718 Aux Id: ERL-179 </p>
+ </item>
+ <item>
+ <p>
+ Update build scripts to not make assumtions about where
+ env, cp and perl are located.</p>
+ <p>
+ Own Id: OTP-13800</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>IC 4.4.1</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/ic/src/ic_codegen.erl b/lib/ic/src/ic_codegen.erl
index adad021da1..a3f141f606 100644
--- a/lib/ic/src/ic_codegen.erl
+++ b/lib/ic/src/ic_codegen.erl
@@ -245,8 +245,8 @@ emit_stub_head(G, F1, Name, java) ->
stub_header(G, Name) ->
["Implementation stub file",
"",
- io_lib:format("Target: ~s", [Name]),
- io_lib:format("Source: ~s", [ic_genobj:idlfile(G)]),
+ io_lib:format("Target: ~ts", [Name]),
+ io_lib:format("Source: ~ts", [ic_genobj:idlfile(G)]),
io_lib:format("IC vsn: ~s", [?COMPILERVSN]),
"",
"This file is automatically generated. DO NOT EDIT IT."].
@@ -298,8 +298,8 @@ emit_hrl_head(G, Fd, Name, c_server) ->
hrl_header(G, Name) ->
["",
- io_lib:format("Target: ~s", [Name]),
- io_lib:format("Source: ~s", [ic_genobj:idlfile(G)]),
+ io_lib:format("Target: ~ts", [Name]),
+ io_lib:format("Source: ~ts", [ic_genobj:idlfile(G)]),
io_lib:format("IC vsn: ~s", [?COMPILERVSN]),
"",
"This file is automatically generated. DO NOT EDIT IT."].
diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
index af189a74f7..b3a18e03d4 100644
--- a/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c
@@ -58,7 +58,7 @@
#include "erl_interface.h"
#include "m_i.h"
-#define HOSTNAMESZ 256
+#define HOSTNAMESZ 255
#define NODENAMESZ 512
#define INBUFSZ 10
@@ -295,7 +295,7 @@ int main(int argc, char **argv)
progname = argv[0];
host[HOSTNAMESZ] = '\0';
- if (gethostname(host, HOSTNAMESZ) < 0) {
+ if (gethostname(host, HOSTNAMESZ + 1) < 0) {
fprintf(stderr, "Can't find own hostname\n");
done(1);
}
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
index b7609d63e5..40c7328f03 100644
--- a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c
@@ -61,7 +61,7 @@
#include "erl_interface.h"
#include "m_i.h"
-#define HOSTNAMESZ 256
+#define HOSTNAMESZ 255
#define NODENAMESZ 512
#define INBUFSZ 10
@@ -298,7 +298,7 @@ int main(int argc, char **argv)
progname = argv[0];
host[HOSTNAMESZ] = '\0';
- if (gethostname(host, HOSTNAMESZ) < 0) {
+ if (gethostname(host, HOSTNAMESZ + 1) < 0) {
fprintf(stderr, "Can't find own hostname\n");
done(1);
}
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
index 23dc089555..33cfe71322 100644
--- a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c
@@ -61,7 +61,7 @@
#include "erl_interface.h"
#include "m_i.h"
-#define HOSTNAMESZ 256
+#define HOSTNAMESZ 255
#define NODENAMESZ 512
#define INBUFSZ 10
@@ -298,7 +298,7 @@ int main(int argc, char **argv)
progname = argv[0];
host[HOSTNAMESZ] = '\0';
- if (gethostname(host, HOSTNAMESZ) < 0) {
+ if (gethostname(host, HOSTNAMESZ + 1) < 0) {
fprintf(stderr, "Can't find own hostname\n");
done(1);
}
diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c
index 53345d561b..f48480e8dc 100644
--- a/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c
+++ b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c
@@ -81,7 +81,7 @@ static void showtime(MyTimeval *start, MyTimeval *stop);
static void usage(void);
static void done(int r);
-#define HOSTNAMESZ 256
+#define HOSTNAMESZ 255
#define NODENAMESZ 512
#define INBUFSZ 10
#define OUTBUFSZ 0
@@ -122,7 +122,7 @@ int main(int argc, char **argv)
progname = argv[0];
host[HOSTNAMESZ] = '\0';
- if (gethostname(host, HOSTNAMESZ) < 0) {
+ if (gethostname(host, HOSTNAMESZ + 1) < 0) {
fprintf(stderr, "Can't find own hostname\n");
done(1);
}
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c
index a18f0e7ba9..e2ba5bd5b6 100644
--- a/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c
@@ -81,7 +81,7 @@ static void showtime(MyTimeval *start, MyTimeval *stop);
static void usage(void);
static void done(int r);
-#define HOSTNAMESZ 256
+#define HOSTNAMESZ 255
#define NODENAMESZ 512
#define INBUFSZ 10
#define OUTBUFSZ 0
@@ -122,7 +122,7 @@ int main(int argc, char **argv)
progname = argv[0];
host[HOSTNAMESZ] = '\0';
- if (gethostname(host, HOSTNAMESZ) < 0) {
+ if (gethostname(host, HOSTNAMESZ + 1) < 0) {
fprintf(stderr, "Can't find own hostname\n");
done(1);
}
diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk
index 7d00ae0170..f0e5e7c266 100644
--- a/lib/ic/vsn.mk
+++ b/lib/ic/vsn.mk
@@ -1 +1 @@
-IC_VSN = 4.4.1
+IC_VSN = 4.4.2
diff --git a/lib/inets/doc/src/http_server.xml b/lib/inets/doc/src/http_server.xml
index aeda961714..65b3dcde95 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>2015</year>
+ <year>2004</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -40,8 +40,8 @@
<item>Secure Sockets Layer (SSL)</item>
<item>Erlang Scripting Interface (ESI)</item>
<item>Common Gateway Interface (CGI)</item>
- <item>User Authentication (using <c>Mnesia</c>,
- <c>Dets</c> or plain text database)</item>
+ <item>User Authentication (using Mnesia,
+ Dets or plain text database)</item>
<item>Common Logfile Format (with or without disk_log(3) support)</item>
<item>URL Aliasing</item>
<item>Action Mappings</item>
@@ -563,7 +563,7 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
<title>mod_auth - User Authentication</title>
<p>The <seealso marker="mod_auth">mod_auth(3)</seealso>
module provides for basic user authentication using
- textual files, <c>Dets</c> databases as well as <c>Mnesia</c> databases.</p>
+ textual files, Dets databases as well as Mnesia databases.</p>
<p>Uses the following Erlang Web Server API interaction data:
</p>
<list type="bulleted">
@@ -580,15 +580,15 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
<section>
<title>Mnesia As Authentication Database</title>
- <p>If <c>Mnesia</c> is used as storage method, <c>Mnesia</c> must be
- started before the HTTP server. The first time <c>Mnesia</c> is
+ <p>If Mnesia is used as storage method, Mnesia must be
+ started before the HTTP server. The first time Mnesia is
started, the schema and the tables must be created before
- <c>Mnesia</c> is started. A simple example of a module with two
- functions that creates and start <c>Mnesia</c> is provided
+ Mnesia is started. A simple example of a module with two
+ functions that creates and start Mnesia is provided
here. Function <c>first_start/0</c> is to be used the first
time. It creates the schema and the tables.
<c>start/0</c> is to be used in consecutive startups.
- <c>start/0</c> starts <c>Mnesia</c> and waits for the tables to
+ <c>start/0</c> starts Mnesia and waits for the tables to
be initiated. This function must only be used when the
schema and the tables are already created.</p>
@@ -616,25 +616,25 @@ start() ->
mnesia:start(),
mnesia:wait_for_tables([httpd_user, httpd_group], 60000). </code>
- <p>To create the <c>Mnesia</c> tables, we use two records defined in
+ <p>To create the Mnesia tables, we use two records defined in
<c>mod_auth.hrl</c>, so that file must be included. <c>first_start/0</c>
creates a schema that specifies on which nodes the database is to reside.
- Then it starts <c>Mnesia</c> and creates the tables. The first argument
+ Then it starts Mnesia and creates the tables. The first argument
is the name of the tables, the second argument is a list of options of
how to create the table, see
- <seealso marker="mnesia:mnesia"><c>mnesia</c></seealso>, documentation for
+ <seealso marker="mnesia:mnesia"><c>mnesia(3)</c></seealso>, documentation for
more information. As the implementation of the <c>mod_auth_mnesia</c>
saves one row for each user, the type must be <c>bag</c>.
When the schema and the tables are created, function
<seealso marker="mnesia:mnesia#start-0">mnesia:start/0</seealso>
- is used to start <c>Mnesia</c> and
- waits for the tables to be loaded. <c>Mnesia</c> uses the
+ is used to start Mnesia and
+ waits for the tables to be loaded. Mnesia uses the
directory specified as <c>mnesia_dir</c> at startup if specified,
- otherwise <c>Mnesia</c> uses the current directory. For security
- reasons, ensure that the <c>Mnesia</c> tables are stored outside
+ otherwise Mnesia uses the current directory. For security
+ reasons, ensure that the Mnesia tables are stored outside
the document tree of the HTTP server. If they are placed in the
directory which it protects, clients can download the tables.
- Only the <c>Dets</c> and <c>Mnesia</c> storage
+ Only the Dets and Mnesia storage
methods allow writing of dynamic user data to disk. <c>plain</c> is
a read only method.</p>
</section>
@@ -669,7 +669,7 @@ start() ->
<section>
<title>mod_disk_log - Logging Using Disk_Log.</title>
<p>Standard logging using the "Common Logfile Format" and
- <seealso marker="kernel:disk_log">kernel:disk_log(3)</seealso>.</p>
+ <seealso marker="kernel:disk_log">disk_log(3)</seealso>.</p>
<p>Uses the following Erlang Web Server API interaction data:
</p>
<list type="bulleted">
diff --git a/lib/inets/doc/src/http_uri.xml b/lib/inets/doc/src/http_uri.xml
index 8e0301c520..20c042c202 100644
--- a/lib/inets/doc/src/http_uri.xml
+++ b/lib/inets/doc/src/http_uri.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2012</year><year>2015</year>
+ <year>2012</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -45,6 +45,7 @@
this module:</p>
<p><c>boolean() = true | false</c></p>
<p><c>string()</c> = list of ASCII characters</p>
+ <p><c>unicode_binary()</c> = binary() with characters encoded in the UTF-8 coding standard</p>
</section>
@@ -53,22 +54,22 @@
<p>Type definitions that are related to URI:</p>
<taglist>
- <tag><c>uri() = string()</c></tag>
+ <tag><c>uri() = string() | unicode:unicode_binary()</c></tag>
<item><p>Syntax according to the URI definition in RFC 3986,
for example, "http://www.erlang.org/"</p></item>
- <tag><c>user_info() = string()</c></tag>
+ <tag><c>user_info() = string() | unicode:unicode_binary()</c></tag>
<item><p></p></item>
<tag><c>scheme() = atom()</c></tag>
<item><p>Example: http, https</p></item>
- <tag><c>host() = string()</c></tag>
+ <tag><c>host() = string() | unicode:unicode_binary()</c></tag>
<item><p></p></item>
<tag><c>port() = pos_integer()</c></tag>
<item><p></p></item>
- <tag><c>path() = string()</c></tag>
+ <tag><c>path() = string() | unicode:unicode_binary()</c></tag>
<item><p>Represents a file path or directory path</p></item>
- <tag><c>query() = string()</c></tag>
+ <tag><c>query() = string() | unicode:unicode_binary()</c></tag>
<item><p></p></item>
- <tag><c>fragment() = string()</c></tag>
+ <tag><c>fragment() = string() | unicode:unicode_binary()</c></tag>
<item><p></p></item>
</taglist>
@@ -83,7 +84,7 @@
<fsummary>Decodes a hexadecimal encoded URI.</fsummary>
<type>
- <v>HexEncodedURI = string() - A possibly hexadecimal encoded URI</v>
+ <v>HexEncodedURI = string() | unicode:unicode_binary() - A possibly hexadecimal encoded URI</v>
<v>URI = uri()</v>
</type>
@@ -98,7 +99,7 @@
<fsummary>Encodes a hexadecimal encoded URI.</fsummary>
<type>
<v>URI = uri()</v>
- <v>HexEncodedURI = string() - Hexadecimal encoded URI</v>
+ <v>HexEncodedURI = string() | unicode:unicode_binary() - Hexadecimal encoded URI</v>
</type>
<desc>
@@ -118,7 +119,7 @@
<v>Option = {ipv6_host_with_brackets, boolean()} |
{scheme_defaults, scheme_defaults()} |
{fragment, boolean()} |
- {schema_validation_fun, fun()}]</v>
+ {scheme_validation_fun, fun()}]</v>
<v>Result = {Scheme, UserInfo, Host, Port, Path, Query} |
{Scheme, UserInfo, Host, Port, Path, Query, Fragment}</v>
<v>UserInfo = user_info()</v>
@@ -145,7 +146,7 @@
<p>Scheme validation fun is to be defined as follows:</p>
<code>
-fun(SchemeStr :: string()) ->
+fun(SchemeStr :: string() | unicode:unicode_binary()) ->
valid | {error, Reason :: term()}.
</code>
diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml
index ca9b268a03..66ec6cabd8 100644
--- a/lib/inets/doc/src/httpc.xml
+++ b/lib/inets/doc/src/httpc.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2015</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -68,11 +68,11 @@
this module:</p>
<p><c>boolean() = true | false</c></p>
<p><c>string()</c> = list of ASCII characters</p>
- <p><c>request_id() = ref()</c></p>
+ <p><c>request_id() = reference()</c></p>
<p><c>profile() = atom()</c></p>
<p><c>path() = string()</c> representing a file path or directory path</p>
<p><c>ip_address()</c> = See the
- <seealso marker="kernel:inet">inet(3)</seealso> manual page in <c>Kernel</c>.</p>
+ <seealso marker="kernel:inet">inet(3)</seealso> manual page in Kernel.</p>
<p><c>socket_opt()</c> = See the options used by
<seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso> <c>gen_tcp(3)</c> and
<seealso marker="ssl:ssl">ssl(3)</seealso> connect(s)</p>
@@ -83,7 +83,7 @@
<title>HTTP DATA TYPES</title>
<p>Type definitions related to HTTP:</p>
- <p><c>method() = head | get | put | post | trace | options | delete</c></p>
+ <p><c>method() = head | get | put | post | trace | options | delete | patch</c></p>
<taglist>
<tag><c>request()</c></tag>
<item><p>= <c>{url(), headers()}</c></p>
@@ -344,7 +344,7 @@
<tag><c><![CDATA[ssl]]></c></tag>
<item>
<p>This is the <c>SSL/TLS</c> connectin configuration option.</p>
- <p>Defaults to <c>[]</c>. See <seealso marker="ssl:ssl">ssl:connect/[2, 3,4]</seealso> for availble options.</p>
+ <p>Defaults to <c>[]</c>. See <seealso marker="ssl:ssl">ssl:connect/[2,3,4]</seealso> for available options.</p>
</item>
<tag><c><![CDATA[autoredirect]]></c></tag>
diff --git a/lib/inets/doc/src/httpd.xml b/lib/inets/doc/src/httpd.xml
index 62b92b8356..d74635fc01 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>2015</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -455,7 +455,7 @@ text/plain asc txt</pre>
directory. Several files can be given, in which case the server
returns the first it finds, for example:</p>
- <code>{directory_index, ["index.hml", "welcome.html"]}</code>
+ <code>{directory_index, ["index.html", "welcome.html"]}</code>
<p>Access to http://your.server.org/docs/ would return
http://your.server.org/docs/index.html or
@@ -711,7 +711,7 @@ text/plain asc txt</pre>
<item>
<p>Sets the type of authentication database that is used for the
directory. The key difference between the different methods is
- that dynamic data can be saved when <c>Mnesia</c> and <c>Dets</c>
+ that dynamic data can be saved when Mnesia and Dets
are used.
This property is called <c>AuthDbType</c> in the Apache-like
configuration files.</p>
@@ -731,10 +731,10 @@ text/plain asc txt</pre>
<code> ragnar:s7Xxv7
edward:wwjau8 </code>
- <p>If the <c>Dets</c> storage method is used, the user database is
- maintained by <c>Dets</c> and must not be edited by hand. Use the
+ <p>If the Dets storage method is used, the user database is
+ maintained by Dets and must not be edited by hand. Use the
API functions in module <c>mod_auth</c> to create/edit the user
- database. This directive is ignored if the <c>Mnesia</c>
+ database. This directive is ignored if the Mnesia
storage method is used. For security reasons, ensure that
<c>auth_user_file</c> is stored outside the document tree of the web
server. If it is placed in the directory that it protects,
@@ -753,10 +753,10 @@ text/plain asc txt</pre>
<code>group1: bob joe ante</code>
- <p>If the <c>Dets</c> storage method is used, the group database is
- maintained by <c>Dets</c> and must not be edited by hand. Use the
+ <p>If the Dets storage method is used, the group database is
+ maintained by Dets and must not be edited by hand. Use the
API for module <c>mod_auth</c> to create/edit the group database.
- This directive is ignored if the <c>Mnesia</c> storage method is used.
+ This directive is ignored if the Mnesia storage method is used.
For security reasons, ensure that the <c>auth_group_file</c> is
stored outside the document tree of the web server. If it is
placed in the directory that it protects, clients
diff --git a/lib/inets/doc/src/mod_auth.xml b/lib/inets/doc/src/mod_auth.xml
index 4b7088b2c5..c4f844622b 100644
--- a/lib/inets/doc/src/mod_auth.xml
+++ b/lib/inets/doc/src/mod_auth.xml
@@ -33,7 +33,7 @@
<modulesummary>User authentication using text files, Dets, or Mnesia database.</modulesummary>
<description>
<p>This module provides for basic user authentication using
- textual files, <c>Dets</c> databases, or <c>Mnesia</c> databases.</p>
+ textual files, Dets databases, or Mnesia databases.</p>
</description>
<funcs>
diff --git a/lib/inets/doc/src/mod_esi.xml b/lib/inets/doc/src/mod_esi.xml
index 8279fdc824..46cc796c8a 100644
--- a/lib/inets/doc/src/mod_esi.xml
+++ b/lib/inets/doc/src/mod_esi.xml
@@ -61,13 +61,13 @@
<tag><c>{server_port, integer()}</c></tag>
<item><p>Servers port number.</p></item>
- <tag><c>{request_method, "GET | "PUT" | "DELETE | "POST" | "PATCH"}</c></tag>
+ <tag><c>{request_method, "GET | "PUT" | "DELETE" | "POST" | "PATCH"}</c></tag>
<item><p>HTTP request method.</p></item>
<tag><c>{remote_adress, inet:ip_address()} </c></tag>
<item><p>The clients ip address.</p></item>
- <tag><c>{peer_cert, undefined | no_peercert | DER:binary()</c></tag>
+ <tag><c>{peer_cert, undefined | no_peercert | DER:binary()}</c></tag>
<item>
<p>For TLS connections where client certificates are used this will
be an ASN.1 DER-encoded X509-certificate as an Erlang binary.
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 5321203511..2f4f20347a 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>2016</year>
+ <year>2002</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -33,7 +33,258 @@
<file>notes.xml</file>
</header>
- <section><title>Inets 6.3</title>
+ <section><title>Inets 6.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ httpd_util:rfc1123_date/1 gracefully handle invalid DST
+ dates by returning the original time in the expected
+ rfc1123 format.</p>
+ <p>
+ Own Id: OTP-14394</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add unicode binary support to http_uri functions</p>
+ <p>
+ Own Id: OTP-14404</p>
+ </item>
+ <item>
+ <p>
+ httpc - Change timeout handling so the redirects cause a
+ new timer to be set. This means that a simple redirected
+ request could return after 2*timeout milliseconds.</p>
+ <p>
+ Own Id: OTP-14429</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.3.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The close of a chunked file reception crashed in a
+ certain timing sequence.</p>
+ <p>
+ Own Id: OTP-14391 Aux Id: seq13306 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.3.8</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Added missing release note for inets-6.3.7</p>
+ <p>
+ Own Id: OTP-14383</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.3.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a bug in ftp that made further operations after a
+ recv_chunk operation impossible.</p>
+ <p>
+ Own Id: OTP-14242</p>
+ </item>
+
+ <item>
+ <p>Make default port, 80 and 443, implicit in automatic redirection.
+ </p>
+ <p> Own Id: OTP-14301
+ </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.3.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Chunk size decoding could fail. The symptom was that
+ chunk decoding sometimes failed depending on timing of
+ the received stream. If chunk size was split into two
+ different packets decoding would fail.</p>
+ <p>
+ Own Id: OTP-13571 Aux Id: ERL-116 </p>
+ </item>
+ <item>
+ <p>
+ Prevent httpc user process to hang if httpc_handler
+ process terminates unexpectedly</p>
+ <p>
+ Own Id: OTP-14091</p>
+ </item>
+ <item>
+ <p>
+ Correct Host header, to include port number, when
+ redirecting requests.</p>
+ <p>
+ Own Id: OTP-14097</p>
+ </item>
+ <item>
+ <p>
+ Shutdown gracefully on connection or TLS handshake errors</p>
+ <p>
+ Own Id: OTP-14173 Aux Id: seq13262 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.3.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Correct misstakes in ftp client introduced in inets-6.3.4</p>
+ <p>
+ Own Id: OTP-14203 Aux Id: OTP-13982 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.3.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixes a bug that makes the ftp client end up in bad state
+ if there is a multi line response from the server and the
+ response number is in the message being sent.</p>
+ <p>
+ Own Id: OTP-13960 Aux Id: PR1196 </p>
+ </item>
+ <item>
+ <p>
+ The ftp client could stop consuming messages when the
+ multiline response handling was corrected.</p>
+ <p>
+ Own Id: OTP-13967</p>
+ </item>
+ <item>
+ <p>
+ Fix keep-alive https through proxy connections so that
+ all requests, following the first one, will run as
+ expected instead of failing.</p>
+ <p>
+ Own Id: OTP-14041</p>
+ </item>
+ <item>
+ <p>
+ Fix bug from commit
+ fdfda2fab0921d409789174556582db28141448e that could make
+ listing of group members in mod_auth callbacks fail.</p>
+ <p>
+ Own Id: OTP-14082</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Update behavior of httpc:request to match RFC-7231</p>
+ <p>
+ Own Id: OTP-13902</p>
+ </item>
+ <item>
+ <p>
+ Fixed dialyzer warnings as well as some white-space
+ issues. Thanks to Kostis.</p>
+ <p>
+ Own Id: OTP-13982 Aux Id: PR-1207 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.3.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The legacy option 'inet6fb4' for inets had stopped
+ working. This bug has now been corrected. Fix by Edwin
+ Fine in bugs.erlang.org ERL-200 and Github PR#1132.</p>
+ <p>
+ Own Id: OTP-13776 Aux Id: ERL-200 PR-1132 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.3.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ PUT and DELETE support has been added to mod_esi</p>
+ <p>
+ Own Id: OTP-13688 Aux Id: seq13149 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A debug message was accidently left enabled in the ftp
+ client.</p>
+ <p>
+ Own Id: OTP-13712 Aux Id: seq13143 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 6.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
@@ -185,6 +436,21 @@
</section>
+ <section><title>Inets 6.1.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Mend ipv6_host_with_brackets option in httpc</p>
+ <p>
+ Own Id: OTP-13417</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
+
<section><title>Inets 6.1.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -591,7 +857,7 @@
<list>
<item>
<p>
- Gracefully handle invalid content-lenght headers instead
+ Gracefully handle invalid content-length headers instead
of crashing in list_to_integer.</p>
<p>
Own Id: OTP-12429</p>
diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl
index bbf25f8e90..e0430654eb 100644
--- a/lib/inets/src/ftp/ftp.erl
+++ b/lib/inets/src/ftp/ftp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -100,14 +100,21 @@
ftp_extension = ?FTP_EXT_DEFAULT
}).
+-record(recv_chunk_closing, {
+ dconn_closed = false,
+ pos_compl_received = false,
+ client_called_us = false
+ }).
+
-type shortage_reason() :: 'etnospc' | 'epnospc'.
-type restriction_reason() :: 'epath' | 'efnamena' | 'elogin' | 'enotbinary'.
-type common_reason() :: 'econn' | 'eclosed' | term().
-type file_write_error_reason() :: term(). % See file:write for more info
-%%-define(DBG(F,A), 'n/a').
--define(DBG(F,A), io:format(F,A)).
+-define(DBG(F,A), 'n/a').
+%%-define(DBG(F,A), io:format(F,A)).
+%%-define(DBG(F,A), ct:pal("~p:~p " ++ if is_list(F) -> F; is_atom(F) -> atom_to_list(F) end, [?MODULE,?LINE|A])).
%%%=========================================================================
%%% API - CLIENT FUNCTIONS
@@ -1095,7 +1102,7 @@ init(Options) ->
erlang:monitor(process, Client),
%% Make sure inet is started
- inet_db:start(),
+ _ = inet_db:start(),
%% Where are we
{ok, Dir} = file:get_cwd(),
@@ -1105,15 +1112,17 @@ init(Options) ->
trace ->
dbg:tracer(),
dbg:p(all, [call]),
- dbg:tpl(ftp, [{'_', [], [{return_trace}]}]),
- dbg:tpl(ftp_response, [{'_', [], [{return_trace}]}]),
- dbg:tpl(ftp_progress, [{'_', [], [{return_trace}]}]);
+ {ok, _} = dbg:tpl(ftp, [{'_', [], [{return_trace}]}]),
+ {ok, _} = dbg:tpl(ftp_response, [{'_', [], [{return_trace}]}]),
+ {ok, _} = dbg:tpl(ftp_progress, [{'_', [], [{return_trace}]}]),
+ ok;
debug ->
dbg:tracer(),
dbg:p(all, [call]),
- dbg:tp(ftp, [{'_', [], [{return_trace}]}]),
- dbg:tp(ftp_response, [{'_', [], [{return_trace}]}]),
- dbg:tp(ftp_progress, [{'_', [], [{return_trace}]}]);
+ {ok, _} = dbg:tp(ftp, [{'_', [], [{return_trace}]}]),
+ {ok, _} = dbg:tp(ftp_response, [{'_', [], [{return_trace}]}]),
+ {ok, _} = dbg:tp(ftp_progress, [{'_', [], [{return_trace}]}]),
+ ok;
_ ->
%% Keep silent
ok
@@ -1295,8 +1304,7 @@ handle_call({_,{rmdir, Dir}}, From, #state{chunk = false} = State) ->
activate_ctrl_connection(State),
{noreply, State#state{client = From}};
-handle_call({_,{type, Type}}, From, #state{chunk = false}
- = State) ->
+handle_call({_,{type, Type}}, From, #state{chunk = false} = State) ->
case Type of
ascii ->
send_ctrl_message(State, mk_cmd("TYPE A", [])),
@@ -1341,6 +1349,25 @@ handle_call({_,{recv_chunk_start, RemoteFile}}, From, #state{chunk = false}
handle_call({_, recv_chunk}, _, #state{chunk = false} = State) ->
{reply, {error, "ftp:recv_chunk_start/2 not called"}, State};
+handle_call({_, recv_chunk}, _From, #state{chunk = true,
+ caller = #recv_chunk_closing{dconn_closed = true,
+ pos_compl_received = true
+ }
+ } = State0) ->
+ %% The ftp:recv_chunk call was the last event we waited for, finnish and clean up
+ ?DBG("recv_chunk_closing ftp:recv_chunk, last event",[]),
+ activate_ctrl_connection(State0),
+ {reply, ok, State0#state{caller = undefined,
+ chunk = false,
+ client = undefined}};
+
+handle_call({_, recv_chunk}, From, #state{chunk = true,
+ caller = #recv_chunk_closing{} = R
+ } = State) ->
+ %% Waiting for more, don't care what
+ ?DBG("recv_chunk_closing ftp:recv_chunk, get more",[]),
+ {noreply, State#state{client = From, caller = R#recv_chunk_closing{client_called_us=true}}};
+
handle_call({_, recv_chunk}, From, #state{chunk = true} = State0) ->
State = activate_data_connection(State0),
{noreply, State#state{client = From, caller = recv_chunk}};
@@ -1454,7 +1481,7 @@ handle_info({Trpt, Socket, Data},
#state{dsock = {Trpt,Socket},
caller = {recv_file, Fd}} = State0) when Trpt==tcp;Trpt==ssl ->
?DBG('L~p --data ~p ----> ~s~p~n',[?LINE,Socket,Data,State0]),
- file_write(binary_to_list(Data), Fd),
+ ok = file_write(binary_to_list(Data), Fd),
progress_report({binary, Data}, State0),
State = activate_data_connection(State0),
{noreply, State};
@@ -1473,24 +1500,29 @@ handle_info({Trpt, Socket, Data}, #state{dsock = {Trpt,Socket}} = State0) when T
Data/binary>>}};
handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket},
- caller = {recv_file, Fd}}
- = State) when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
+ caller = {recv_file, Fd}} = State)
+ when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
file_close(Fd),
progress_report({transfer_size, 0}, State),
activate_ctrl_connection(State),
+ ?DBG("Data channel close",[]),
{noreply, State#state{dsock = undefined, data = <<>>}};
-handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, client = From,
- caller = recv_chunk}
- = State) when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
- gen_server:reply(From, ok),
- {noreply, State#state{dsock = undefined, client = undefined,
- data = <<>>, caller = undefined,
- chunk = false}};
+handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket},
+ client = Client,
+ caller = recv_chunk} = State)
+ when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
+ ?DBG("Data channel close recv_chunk",[]),
+ activate_ctrl_connection(State),
+ {noreply, State#state{dsock = undefined,
+ caller = #recv_chunk_closing{dconn_closed = true,
+ client_called_us = Client =/= undefined}
+ }};
handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, caller = recv_bin,
data = Data} = State)
when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
+ ?DBG("Data channel close",[]),
activate_ctrl_connection(State),
{noreply, State#state{dsock = undefined, data = <<>>,
caller = {recv_bin, Data}}};
@@ -1498,6 +1530,7 @@ handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, caller = recv_bin,
handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, data = Data,
caller = {handle_dir_result, Dir}}
= State) when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
+ ?DBG("Data channel close",[]),
activate_ctrl_connection(State),
{noreply, State#state{dsock = undefined,
caller = {handle_dir_result, Dir, Data},
@@ -1599,13 +1632,13 @@ terminate(normal, State) ->
%% If terminate reason =/= normal the progress reporting process will
%% be killed by the exit signal.
progress_report(stop, State),
- do_termiante({error, econn}, State);
+ do_terminate({error, econn}, State);
terminate(Reason, State) ->
Report = io_lib:format("Ftp connection closed due to: ~p~n", [Reason]),
error_logger:error_report(Report),
- do_termiante({error, eclosed}, State).
+ do_terminate({error, eclosed}, State).
-do_termiante(ErrorMsg, State) ->
+do_terminate(ErrorMsg, State) ->
close_data_connection(State),
close_ctrl_connection(State),
case State#state.client of
@@ -2044,6 +2077,30 @@ handle_ctrl_result({pos_prel, _}, #state{client = From,
end;
%%--------------------------------------------------------------------------
+%% File handling - chunk_transfer complete
+
+handle_ctrl_result({pos_compl, _}, #state{client = From,
+ caller = #recv_chunk_closing{dconn_closed = true,
+ client_called_us = true,
+ pos_compl_received = false
+ }}
+ = State0) when From =/= undefined ->
+ %% The pos_compl was the last event we waited for, finnish and clean up
+ ?DBG("recv_chunk_closing pos_compl, last event",[]),
+ gen_server:reply(From, ok),
+ activate_ctrl_connection(State0),
+ {noreply, State0#state{caller = undefined,
+ chunk = false,
+ client = undefined}};
+
+handle_ctrl_result({pos_compl, _}, #state{caller = #recv_chunk_closing{}=R}
+ = State0) ->
+ %% Waiting for more, don't care what
+ ?DBG("recv_chunk_closing pos_compl, wait more",[]),
+ {noreply, State0#state{caller = R#recv_chunk_closing{pos_compl_received=true}}};
+
+
+%%--------------------------------------------------------------------------
%% File handling - recv_file
handle_ctrl_result({pos_prel, _}, #state{caller = {recv_file, _}} = State0) ->
case accept_data_connection(State0) of
@@ -2099,7 +2156,7 @@ handle_ctrl_result({pos_prel, _}, #state{caller = {transfer_data, Bin}}
%%--------------------------------------------------------------------------
%% Default
-handle_ctrl_result({Status, Lines}, #state{client = From} = State)
+handle_ctrl_result({Status, _Lines}, #state{client = From} = State)
when From =/= undefined ->
ctrl_result_response(Status, State, {error, Status}).
@@ -2220,16 +2277,16 @@ setup_data_connection(#state{mode = active,
{ok, Port} = inet:port(LSock),
case FtpExt of
false ->
- {IP1, IP2, IP3, IP4} = IP,
- {Port1, Port2} = {Port div 256, Port rem 256},
- send_ctrl_message(State,
- mk_cmd("PORT ~w,~w,~w,~w,~w,~w",
- [IP1, IP2, IP3, IP4, Port1, Port2]));
- true ->
- IpAddress = inet_parse:ntoa(IP),
- Cmd = mk_cmd("EPRT |1|~s|~p|", [IpAddress, Port]),
- send_ctrl_message(State, Cmd)
- end,
+ {IP1, IP2, IP3, IP4} = IP,
+ {Port1, Port2} = {Port div 256, Port rem 256},
+ send_ctrl_message(State,
+ mk_cmd("PORT ~w,~w,~w,~w,~w,~w",
+ [IP1, IP2, IP3, IP4, Port1, Port2]));
+ true ->
+ IpAddress = inet_parse:ntoa(IP),
+ Cmd = mk_cmd("EPRT |1|~s|~p|", [IpAddress, Port]),
+ send_ctrl_message(State, Cmd)
+ end,
activate_ctrl_connection(State),
{noreply, State#state{caller = {setup_data_connection,
{LSock, Caller}}}}
@@ -2337,7 +2394,7 @@ accept_data_connection(#state{mode = passive} = State) ->
send_ctrl_message(_S=#state{csock = Socket, verbose = Verbose}, Message) ->
verbose(lists:flatten(Message),Verbose,send),
?DBG('<--ctrl ~p ---- ~s~p~n',[Socket,Message,_S]),
- send_message(Socket, Message).
+ _ = send_message(Socket, Message).
send_data_message(_S=#state{dsock = Socket}, Message) ->
?DBG('<==data ~p ==== ~s~n~p~n',[Socket,Message,_S]),
@@ -2358,24 +2415,34 @@ send_message({tcp, Socket}, Message) ->
send_message({ssl, Socket}, Message) ->
ssl:send(Socket, Message).
-activate_ctrl_connection(#state{csock = Socket, ctrl_data = {<<>>, _, _}}) ->
- activate_connection(Socket);
-activate_ctrl_connection(#state{csock = Socket}) ->
+activate_ctrl_connection(#state{csock = CSock, ctrl_data = {<<>>, _, _}}) ->
+ activate_connection(CSock);
+activate_ctrl_connection(#state{csock = CSock}) ->
+ activate_connection(CSock),
%% We have already received at least part of the next control message,
%% that has been saved in ctrl_data, process this first.
- self() ! {tcp, unwrap_socket(Socket), <<>>}.
-
-unwrap_socket({tcp,Socket}) -> Socket;
-unwrap_socket({ssl,Socket}) -> Socket;
-unwrap_socket(Socket) -> Socket.
-
+ self() ! {socket_type(CSock), unwrap_socket(CSock), <<>>},
+ ok.
-activate_data_connection(#state{dsock = Socket} = State) ->
- activate_connection(Socket),
+activate_data_connection(#state{dsock = DSock} = State) ->
+ activate_connection(DSock),
State.
-activate_connection({tcp, Socket}) -> inet:setopts(Socket, [{active, once}]);
-activate_connection({ssl, Socket}) -> ssl:setopts(Socket, [{active, once}]).
+activate_connection(Socket) ->
+ ignore_return_value(
+ case socket_type(Socket) of
+ tcp -> inet:setopts(unwrap_socket(Socket), [{active, once}]);
+ ssl -> ssl:setopts(unwrap_socket(Socket), [{active, once}])
+ end).
+
+
+ignore_return_value(_) -> ok.
+
+unwrap_socket({tcp,Socket}) -> Socket;
+unwrap_socket({ssl,Socket}) -> Socket.
+
+socket_type({tcp,_Socket}) -> tcp;
+socket_type({ssl,_Socket}) -> ssl.
close_ctrl_connection(#state{csock = undefined}) -> ok;
close_ctrl_connection(#state{csock = Socket}) -> close_connection(Socket).
@@ -2383,16 +2450,16 @@ close_ctrl_connection(#state{csock = Socket}) -> close_connection(Socket).
close_data_connection(#state{dsock = undefined}) -> ok;
close_data_connection(#state{dsock = Socket}) -> close_connection(Socket).
-close_connection({lsock,Socket}) -> gen_tcp:close(Socket);
-close_connection({tcp, Socket}) -> gen_tcp:close(Socket);
-close_connection({ssl, Socket}) -> ssl:close(Socket).
+close_connection({lsock,Socket}) -> ignore_return_value( gen_tcp:close(Socket) );
+close_connection({tcp, Socket}) -> ignore_return_value( gen_tcp:close(Socket) );
+close_connection({ssl, Socket}) -> ignore_return_value( ssl:close(Socket) ).
-%% ------------ FILE HANDELING ----------------------------------------
+%% ------------ FILE HANDLING ----------------------------------------
send_file(#state{tls_upgrading_data_connection = {true, CTRL, _}} = State, Fd) ->
{noreply, State#state{tls_upgrading_data_connection = {true, CTRL, ?MODULE, send_file, Fd}}};
send_file(State, Fd) ->
case file_read(Fd) of
- {ok, N, Bin} when N > 0->
+ {ok, N, Bin} when N > 0 ->
send_data_message(State, Bin),
progress_report({binary, Bin}, State),
send_file(State, Fd);
@@ -2412,7 +2479,7 @@ file_open(File, Option) ->
file:open(File, [raw, binary, Option]).
file_close(Fd) ->
- file:close(Fd).
+ ignore_return_value( file:close(Fd) ).
file_read(Fd) ->
case file:read(Fd, ?FILE_BUFSIZE) of
@@ -2504,7 +2571,7 @@ progress_report(stop, #state{progress = ProgressPid}) ->
ftp_progress:stop(ProgressPid);
progress_report({binary, Data}, #state{progress = ProgressPid}) ->
ftp_progress:report(ProgressPid, {transfer_size, size(Data)});
-progress_report(Report, #state{progress = ProgressPid}) ->
+progress_report(Report, #state{progress = ProgressPid}) ->
ftp_progress:report(ProgressPid, Report).
diff --git a/lib/inets/src/ftp/ftp_progress.erl b/lib/inets/src/ftp/ftp_progress.erl
index 68185a222d..a6263e5cd7 100644
--- a/lib/inets/src/ftp/ftp_progress.erl
+++ b/lib/inets/src/ftp/ftp_progress.erl
@@ -36,11 +36,11 @@
-include_lib("kernel/include/file.hrl").
-record(progress, {
- file, % string()
- cb_module, % atom()
- cb_function, % atom()
- init_progress_term, % term()
- current_progress_term % term()
+ file :: string() | 'undefined',
+ cb_module :: module(),
+ cb_function :: atom(),
+ init_progress_term :: term(),
+ current_progress_term :: term()
}).
%%%=========================================================================
@@ -53,13 +53,15 @@
%% Description: Starts the progress report process unless progress reporting
%% should not be performed.
%%--------------------------------------------------------------------------
+-type options() :: 'ignore' | {module(), atom(), term()}.
+-spec start_link(options()) -> 'ignore' | pid().
start_link(ignore) ->
ignore;
start_link(Options) ->
spawn_link(?MODULE, init, [Options]).
%%--------------------------------------------------------------------------
-%% report_progress(Pid, Report) -> _
+%% report_progress(Pid, Report) -> ok
%% Pid = pid()
%% Report = {local_file, File} | {remote_file, File} |
%% {transfer_size, Size}
@@ -68,17 +70,23 @@ start_link(Options) ->
%% Description: Reports progress to the reporting process that calls the
%% user defined callback function.
%%--------------------------------------------------------------------------
+-type report() :: {'local_file', string()} | {'remote_file', string()}
+ | {'transfer_size', non_neg_integer()}.
+-spec report(pid(), report()) -> 'ok'.
report(Pid, Report) ->
- Pid ! {progress_report, Report}.
+ Pid ! {progress_report, Report},
+ ok.
%%--------------------------------------------------------------------------
-%% stop(Pid) -> _
+%% stop(Pid) -> ok
%% Pid = pid()
%%
%% Description:
%%--------------------------------------------------------------------------
+-spec stop(pid()) -> 'ok'.
stop(Pid) ->
- Pid ! stop.
+ Pid ! stop,
+ ok.
%%%=========================================================================
%%% Internal functions
diff --git a/lib/inets/src/ftp/ftp_response.erl b/lib/inets/src/ftp/ftp_response.erl
index 7533bc4550..d54d97dc91 100644
--- a/lib/inets/src/ftp/ftp_response.erl
+++ b/lib/inets/src/ftp/ftp_response.erl
@@ -90,19 +90,23 @@ parse_lines(<<C1, C2, C3, ?WHITE_SPACE, Bin/binary>>, Lines, start) ->
parse_lines(Bin, [?WHITE_SPACE, C3, C2, C1 | Lines], finish);
%% Last line found
-parse_lines(<<C1, C2, C3, ?WHITE_SPACE, Rest/binary>>, Lines, {C1, C2, C3}) ->
- parse_lines(Rest, [?WHITE_SPACE, C3, C2, C1 | Lines], finish);
+parse_lines(<<?CR, ?LF, C1, C2, C3, ?WHITE_SPACE, Rest/binary>>, Lines, {C1, C2, C3}) ->
+ parse_lines(Rest, [?WHITE_SPACE, C3, C2, C1, ?LF, ?CR | Lines], finish);
%% Potential end found wait for more data
-parse_lines(<<C1, C2, C3>> = Bin, Lines, {C1, C2, C3}) ->
+parse_lines(<<?CR, ?LF, C1, C2, C3>> = Bin, Lines, {C1, C2, C3}) ->
{continue, {Bin, Lines, {C1, C2, C3}}};
%% Intermidate line begining with status code
-parse_lines(<<C1, C2, C3, Rest/binary>>, Lines, {C1, C2, C3}) ->
- parse_lines(Rest, [C3, C2, C1 | Lines], {C1, C2, C3});
+parse_lines(<<?CR, ?LF, C1, C2, C3, Rest/binary>>, Lines, {C1, C2, C3}) ->
+ parse_lines(Rest, [C3, C2, C1, ?LF, ?CR | Lines], {C1, C2, C3});
%% Potential last line wait for more data
-parse_lines(<<C1, C2>> = Data, Lines, {C1, C2, _} = StatusCode) ->
+parse_lines(<<?CR, ?LF, C1, C2>> = Data, Lines, {C1, C2, _} = StatusCode) ->
{continue, {Data, Lines, StatusCode}};
-parse_lines(<<C1>> = Data, Lines, {C1, _, _} = StatusCode) ->
+parse_lines(<<?CR, ?LF, C1>> = Data, Lines, {C1, _, _} = StatusCode) ->
+ {continue, {Data, Lines, StatusCode}};
+parse_lines(<<?CR, ?LF>> = Data, Lines, {_,_,_} = StatusCode) ->
+ {continue, {Data, Lines, StatusCode}};
+parse_lines(<<?LF>> = Data, Lines, {_,_,_} = StatusCode) ->
{continue, {Data, Lines, StatusCode}};
parse_lines(<<>> = Data, Lines, {_,_,_} = StatusCode) ->
{continue, {Data, Lines, StatusCode}};
diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl
index 91d87289a2..bf2da82603 100644
--- a/lib/inets/src/http_client/httpc.erl
+++ b/lib/inets/src/http_client/httpc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -147,6 +147,26 @@ request(Method, Request, HttpOptions, Options) ->
request(Method, Request, HttpOptions, Options, default_profile()).
request(Method,
+ {Url, Headers, ContentType, TupleBody},
+ HTTPOptions, Options, Profile)
+ when ((Method =:= post) orelse (Method =:= patch) orelse (Method =:= put) orelse (Method =:= delete))
+ andalso (is_atom(Profile) orelse is_pid(Profile)) andalso
+ is_list(ContentType) andalso is_tuple(TupleBody)->
+ case check_body_gen(TupleBody) of
+ ok ->
+ do_request(Method, {Url, Headers, ContentType, TupleBody}, HTTPOptions, Options, Profile);
+ Error ->
+ Error
+ end;
+request(Method,
+ {Url, Headers, ContentType, Body},
+ HTTPOptions, Options, Profile)
+ when ((Method =:= post) orelse (Method =:= patch) orelse (Method =:= put) orelse (Method =:= delete))
+ andalso (is_atom(Profile) orelse is_pid(Profile)) andalso
+ is_list(ContentType) andalso (is_list(Body) orelse is_binary(Body)) ->
+ do_request(Method, {Url, Headers, ContentType, Body}, HTTPOptions, Options, Profile);
+
+request(Method,
{Url, Headers},
HTTPOptions, Options, Profile)
when (Method =:= options) orelse
@@ -155,12 +175,6 @@ request(Method,
(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 uri_parse(Url, Options) of
{error, Reason} ->
{error, Reason};
@@ -172,21 +186,9 @@ request(Method,
handle_request(Method, Url, ParsedUrl, Headers, [], [],
HTTPOptions, Options, Profile)
end
- end;
-
-request(Method,
- {Url, Headers, ContentType, Body},
- HTTPOptions, Options, Profile)
- when ((Method =:= post) orelse (Method =:= patch) orelse (Method =:= put) orelse
- (Method =:= delete)) 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}]),
+ end.
+
+do_request(Method, {Url, Headers, ContentType, Body}, HTTPOptions, Options, Profile) ->
case uri_parse(Url, Options) of
{error, Reason} ->
{error, Reason};
@@ -196,7 +198,6 @@ request(Method,
HTTPOptions, Options, Profile)
end.
-
%%--------------------------------------------------------------------------
%% cancel_request(RequestId) -> ok
%% cancel_request(RequestId, Profile) -> ok
@@ -209,7 +210,6 @@ cancel_request(RequestId) ->
cancel_request(RequestId, Profile)
when is_atom(Profile) orelse is_pid(Profile) ->
- ?hcrt("cancel request", [{request_id, RequestId}, {profile, Profile}]),
httpc_manager:cancel_request(RequestId, profile_name(Profile)).
@@ -232,7 +232,6 @@ cancel_request(RequestId, Profile)
set_options(Options) ->
set_options(Options, default_profile()).
set_options(Options, Profile) when is_atom(Profile) orelse is_pid(Profile) ->
- ?hcrt("set options", [{options, Options}, {profile, Profile}]),
case validate_options(Options) of
{ok, Opts} ->
httpc_manager:set_options(Opts, profile_name(Profile));
@@ -272,7 +271,6 @@ get_options(all = _Options, Profile) ->
get_options(Options, Profile)
when (is_list(Options) andalso
(is_atom(Profile) orelse is_pid(Profile))) ->
- ?hcrt("get options", [{options, Options}, {profile, Profile}]),
case Options -- get_options() of
[] ->
try
@@ -314,9 +312,6 @@ store_cookies(SetCookieHeaders, Url) ->
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
%% Since the Address part is not actually used
@@ -353,9 +348,6 @@ cookie_header(Url, Opts) when is_list(Opts) ->
cookie_header(Url, Opts, Profile)
when (is_list(Opts) andalso (is_atom(Profile) orelse is_pid(Profile))) ->
- ?hcrt("cookie header", [{url, Url},
- {opts, Opts},
- {profile, Profile}]),
try
begin
httpc_manager:which_cookies(Url, Opts, profile_name(Profile))
@@ -398,7 +390,6 @@ which_sessions() ->
which_sessions(default_profile()).
which_sessions(Profile) ->
- ?hcrt("which sessions", [{profile, Profile}]),
try
begin
httpc_manager:which_sessions(profile_name(Profile))
@@ -419,7 +410,6 @@ info() ->
info(default_profile()).
info(Profile) ->
- ?hcrt("info", [{profile, Profile}]),
try
begin
httpc_manager:info(profile_name(Profile))
@@ -440,7 +430,6 @@ reset_cookies() ->
reset_cookies(default_profile()).
reset_cookies(Profile) ->
- ?hcrt("reset cookies", [{profile, Profile}]),
try
begin
httpc_manager:reset_cookies(profile_name(Profile))
@@ -458,7 +447,6 @@ reset_cookies(Profile) ->
%% same behavior as active once for sockets.
%%-------------------------------------------------------------------------
stream_next(Pid) ->
- ?hcrt("stream next", [{handler, Pid}]),
httpc_handler:stream_next(Pid).
@@ -466,7 +454,6 @@ stream_next(Pid) ->
%%% Behaviour callbacks
%%%========================================================================
start_standalone(PropList) ->
- ?hcrt("start standalone", [{proplist, PropList}]),
case proplists:get_value(profile, PropList) of
undefined ->
{error, no_profile};
@@ -477,14 +464,11 @@ start_standalone(PropList) ->
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);
@@ -510,7 +494,6 @@ service_info(Pid) ->
%%%========================================================================
%%% Internal functions
%%%========================================================================
-
handle_request(Method, Url,
{Scheme, UserInfo, Host, Port, Path, Query},
Headers0, ContentType, Body0,
@@ -521,9 +504,6 @@ handle_request(Method, Url,
try
begin
- ?hcrt("begin processing", [{started, Started},
- {new_headers, NewHeaders0}]),
-
{NewHeaders, Body} =
case Body0 of
{chunkify, ProcessBody, Acc}
@@ -544,7 +524,7 @@ handle_request(Method, Url,
Options = request_options(Options0),
Sync = proplists:get_value(sync, Options),
Stream = proplists:get_value(stream, Options),
- Host2 = header_host(Scheme, Host, Port),
+ Host2 = http_request:normalize_host(Scheme, Host, Port),
HeadersRecord = header_record(NewHeaders, Host2, HTTPOptions),
Receiver = proplists:get_value(receiver, Options),
SocketOpts = proplists:get_value(socket_opts, Options),
@@ -575,16 +555,13 @@ handle_request(Method, Url,
{ok, RequestId} ->
handle_answer(RequestId, Sync, Options);
{error, Reason} ->
- ?hcrd("request failed", [{reason, Reason}]),
{error, Reason}
end
end
catch
error:{noproc, _} ->
- ?hcrv("noproc", [{profile, Profile}]),
{error, {not_started, Profile}};
throw:Error ->
- ?hcrv("throw", [{error, Error}]),
Error
end.
@@ -620,15 +597,10 @@ handle_answer(RequestId, false, _) ->
handle_answer(RequestId, true, Options) ->
receive
{http, {RequestId, saved_to_file}} ->
- ?hcrt("received saved-to-file", [{request_id, RequestId}]),
{ok, saved_to_file};
{http, {RequestId, {_,_,_} = Result}} ->
- ?hcrt("received answer", [{request_id, RequestId},
- {result, Result}]),
return_answer(Options, Result);
{http, {RequestId, {error, Reason}}} ->
- ?hcrt("received error", [{request_id, RequestId},
- {reason, Reason}]),
{error, Reason}
end.
@@ -1063,14 +1035,6 @@ bad_option(Option, BadValue) ->
throw({error, {bad_option, Option, BadValue}}).
-header_host(https, Host, 443 = _Port) ->
- Host;
-header_host(http, Host, 80 = _Port) ->
- Host;
-header_host(_Scheme, Host, Port) ->
- Host ++ ":" ++ integer_to_list(Port).
-
-
header_record(NewHeaders, Host, #http_options{version = Version}) ->
header_record(NewHeaders, #http_request_h{}, Host, Version).
@@ -1257,18 +1221,14 @@ child_name(Pid, [{Name, Pid} | _]) ->
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.
-
host_address(Host, false) ->
Host;
host_address(Host, true) ->
string:strip(string:strip(Host, right, $]), left, $[).
+
+check_body_gen({Fun, _}) when is_function(Fun) ->
+ ok;
+check_body_gen({chunkify, Fun, _}) when is_function(Fun) ->
+ ok;
+check_body_gen(Gen) ->
+ {error, {bad_body_generator, Gen}}.
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index d1c52dcc78..bd1d2e833a 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,7 +32,6 @@
%% Internal Application API
-export([
start_link/4,
- %% connect_and_send/2,
send/2,
cancel/2,
stream_next/1,
@@ -45,28 +44,30 @@
-record(timers,
{
- request_timers = [], % [ref()]
- queue_timer % ref()
+ request_timers = [] :: [reference()],
+ queue_timer :: reference() | 'undefined'
}).
+-type session_failed() :: {'connect_failed',term()} | {'send_failed',term()}.
+
-record(state,
{
- request, % #request{}
- session, % #session{}
+ request :: request() | 'undefined',
+ session :: session() | session_failed() | 'undefined',
status_line, % {Version, StatusCode, ReasonPharse}
- headers, % #http_response_h{}
- body, % binary()
+ headers :: http_response_h() | 'undefined',
+ body :: binary() | 'undefined',
mfa, % {Module, Function, Args}
- pipeline = queue:new(), % queue:queue()
- keep_alive = queue:new(), % queue:queue()
+ pipeline = queue:new() :: queue:queue(),
+ keep_alive = queue:new() :: queue:queue(),
status, % undefined | new | pipeline | keep_alive | close | {ssl_tunnel, Request}
canceled = [], % [RequestId]
- max_header_size = nolimit, % nolimit | integer()
- max_body_size = nolimit, % nolimit | integer()
- options, % #options{}
- timers = #timers{}, % #timers{}
- profile_name, % atom() - id of httpc_manager process.
- once = inactive % inactive | once
+ max_header_size = nolimit :: nolimit | integer(),
+ max_body_size = nolimit :: nolimit | integer(),
+ options :: options(),
+ timers = #timers{} :: #timers{},
+ profile_name :: atom(), % id of httpc_manager process.
+ once = inactive :: 'inactive' | 'once'
}).
@@ -113,7 +114,7 @@ send(Request, Pid) ->
%%--------------------------------------------------------------------
%% Function: cancel(RequestId, Pid) -> ok
-%% RequestId = ref()
+%% RequestId = reference()
%% Pid = pid() - the pid of the http-request handler process.
%%
%% Description: Cancels a request. Intended to be called by the httpc
@@ -163,14 +164,12 @@ info(Pid) ->
%%--------------------------------------------------------------------
%% Request should not be streamed
stream(BodyPart, #request{stream = none} = Request, _) ->
- ?hcrt("stream - none", []),
{false, BodyPart, Request};
%% Stream to caller
stream(BodyPart, #request{stream = Self} = Request, Code)
when ?IS_STREAMED(Code) andalso
((Self =:= self) orelse (Self =:= {self, once})) ->
- ?hcrt("stream - self", [{stream, Self}, {code, Code}]),
httpc_response:send(Request#request.from,
{Request#request.id, stream, BodyPart}),
{true, <<>>, Request};
@@ -180,10 +179,8 @@ stream(BodyPart, #request{stream = Self} = Request, Code)
%% We keep this for backward compatibillity...
stream(BodyPart, #request{stream = Filename} = Request, Code)
when ?IS_STREAMED(Code) andalso is_list(Filename) ->
- ?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}]),
stream(BodyPart, Request#request{stream = Fd}, 200);
{error, Reason} ->
exit({stream_to_file_failed, Reason})
@@ -192,7 +189,6 @@ stream(BodyPart, #request{stream = Filename} = Request, Code)
%% Stream to file
stream(BodyPart, #request{stream = Fd} = Request, Code)
when ?IS_STREAMED(Code) ->
- ?hcrt("stream to file", [{stream, Fd}, {code, Code}]),
case file:write(Fd, BodyPart) of
ok ->
{true, <<>>, Request};
@@ -201,7 +197,6 @@ stream(BodyPart, #request{stream = Fd} = Request, Code)
end;
stream(BodyPart, Request,_) -> % only 200 and 206 responses can be streamed
- ?hcrt("stream - ignore", [{request, Request}]),
{false, BodyPart, Request}.
@@ -255,22 +250,148 @@ init([Parent, Request, Options, ProfileName]) ->
%% {stop, Reason, State} (terminate/2 is called)
%% Description: Handling call messages
%%--------------------------------------------------------------------
-handle_call(#request{address = Addr} = Request, _,
+handle_call(Request, From, State) ->
+ try do_handle_call(Request, From, State) of
+ Result ->
+ Result
+ catch
+ _:Reason ->
+ {stop, {shutdown, Reason} , State}
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Function: handle_cast(Msg, State) -> {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%% Description: Handling cast messages
+%%--------------------------------------------------------------------
+handle_cast(Msg, State) ->
+ try do_handle_cast(Msg, State) of
+ Result ->
+ Result
+ catch
+ _:Reason ->
+ {stop, {shutdown, Reason} , State}
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: handle_info(Info, State) -> {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%% Description: Handling all non call/cast messages
+%%--------------------------------------------------------------------
+handle_info(Info, State) ->
+ try do_handle_info(Info, State) of
+ Result ->
+ Result
+ catch
+ _:Reason ->
+ {stop, {shutdown, Reason} , State}
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: terminate(Reason, State) -> _ (ignored by gen_server)
+%% Description: Shutdown the httpc_handler
+%%--------------------------------------------------------------------
+
+%% Init error there is no socket to be closed.
+terminate(normal,
+ #state{request = Request,
+ session = {send_failed, _} = Reason} = State) ->
+ maybe_send_answer(Request,
+ httpc_response:error(Request, Reason),
+ State),
+ ok;
+
+terminate(normal,
+ #state{request = Request,
+ session = {connect_failed, _} = Reason} = State) ->
+ maybe_send_answer(Request,
+ httpc_response:error(Request, Reason),
+ State),
+ ok;
+
+terminate(normal, #state{session = undefined}) ->
+ ok;
+
+%% Init error sending, no session information has been setup but
+%% there is a socket that needs closing.
+terminate(normal,
+ #state{session = #session{id = undefined} = Session}) ->
+ close_socket(Session);
+
+%% Socket closed remotely
+terminate(normal,
+ #state{session = #session{socket = {remote_close, Socket},
+ socket_type = SocketType,
+ id = Id},
+ profile_name = ProfileName,
+ request = Request,
+ timers = Timers,
+ pipeline = Pipeline,
+ keep_alive = KeepAlive} = State) ->
+ %% Clobber session
+ (catch httpc_manager:delete_session(Id, ProfileName)),
+
+ maybe_retry_queue(Pipeline, State),
+ maybe_retry_queue(KeepAlive, State),
+
+ %% Cancel timers
+ cancel_timers(Timers),
+
+ %% Maybe deliver answers to requests
+ deliver_answer(Request),
+
+ %% And, just in case, close our side (**really** overkill)
+ http_transport:close(SocketType, Socket);
+
+terminate(_Reason, #state{session = #session{id = Id,
+ socket = Socket,
+ socket_type = SocketType},
+ request = undefined,
+ profile_name = ProfileName,
+ timers = Timers,
+ pipeline = Pipeline,
+ keep_alive = KeepAlive} = State) ->
+
+ %% Clobber session
+ (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),
+ http_transport:close(SocketType, Socket);
+
+terminate(_Reason, #state{request = undefined}) ->
+ ok;
+
+terminate(Reason, #state{request = Request} = State) ->
+ NewState = maybe_send_answer(Request,
+ httpc_response:error(Request, Reason),
+ State),
+ terminate(Reason, NewState#state{request = undefined}).
+
+%%--------------------------------------------------------------------
+%% Func: code_change(_OldVsn, State, Extra) -> {ok, NewState}
+%% Purpose: Convert process state when code is changed
+%%--------------------------------------------------------------------
+
+code_change(_, State, _) ->
+ {ok, State}.
+
+%%%--------------------------------------------------------------------
+%%% Internal functions
+%%%--------------------------------------------------------------------
+do_handle_call(#request{address = Addr} = Request, _,
#state{status = Status,
session = #session{type = pipeline} = Session,
timers = Timers,
options = #options{proxy = Proxy} = _Options,
profile_name = ProfileName} = State0)
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, Session, Request) of
ok ->
@@ -285,9 +406,8 @@ handle_call(#request{address = Addr} = Request, _,
case State0#state.request of
#request{} = OldRequest -> %% Old request not yet finished
- ?hcrd("old request still not finished", []),
%% Make sure to use the new value of timers in state
- NewTimers = State1#state.timers,
+ NewTimers = State1#state.timers,
NewPipeline = queue:in(Request, State1#state.pipeline),
NewSession =
Session#session{queue_length =
@@ -295,7 +415,6 @@ handle_call(#request{address = Addr} = Request, _,
queue:len(NewPipeline) + 1,
client_close = ClientClose},
insert_session(NewSession, ProfileName),
- ?hcrd("session updated", []),
{reply, ok, State1#state{
request = OldRequest,
pipeline = NewPipeline,
@@ -304,7 +423,6 @@ handle_call(#request{address = Addr} = Request, _,
undefined ->
%% 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 =
@@ -312,18 +430,16 @@ handle_call(#request{address = Addr} = Request, _,
client_close = ClientClose},
httpc_manager:insert_session(NewSession, ProfileName),
NewTimers = Timers#timers{queue_timer = undefined},
- ?hcrd("session created", []),
State = init_wait_for_response_state(Request, State1#state{session = NewSession,
timers = NewTimers}),
{reply, ok, State}
end;
{error, Reason} ->
- ?hcri("failed sending request", [{reason, Reason}]),
NewPipeline = queue:in(Request, State0#state.pipeline),
- {stop, shutdown, {pipeline_failed, Reason}, State0#state{pipeline = NewPipeline}}
+ {stop, {shutdown, {pipeline_failed, Reason}}, State0#state{pipeline = NewPipeline}}
end;
-handle_call(#request{address = Addr} = Request, _,
+do_handle_call(#request{address = Addr} = Request, _,
#state{status = Status,
session = #session{type = keep_alive} = Session,
timers = Timers,
@@ -331,17 +447,11 @@ handle_call(#request{address = Addr} = Request, _,
profile_name = ProfileName} = State0)
when Status =/= undefined ->
- ?hcrv("new request on a keep-alive session",
- [{request, Request},
- {profile, ProfileName},
- {status, Status}]),
-
ClientClose = httpc_request:is_client_closing(Request#request.headers),
case State0#state.request of
#request{} -> %% Old request not yet finished
%% Make sure to use the new value of timers in state
- ?hcrd("old request still not finished", []),
NewKeepAlive = queue:in(Request, State0#state.keep_alive),
NewSession =
Session#session{queue_length =
@@ -349,13 +459,11 @@ handle_call(#request{address = Addr} = Request, _,
queue:len(NewKeepAlive) + 1,
client_close = ClientClose},
insert_session(NewSession, ProfileName),
- ?hcrd("session updated", []),
{reply, ok, State0#state{keep_alive = NewKeepAlive,
session = NewSession}};
undefined ->
%% Note: tcp-message receiving has already been
%% activated by handle_pipeline/2.
- ?hcrd("no current request", []),
cancel_timer(Timers#timers.queue_timer,
timeout_queue),
NewTimers = Timers#timers{queue_timer = undefined},
@@ -363,8 +471,6 @@ handle_call(#request{address = Addr} = Request, _,
Address = handle_proxy(Addr, Proxy),
case httpc_request:send(Address, Session, Request) of
ok ->
- ?hcrd("request sent", []),
-
%% Activate the request time out for the new request
State2 =
activate_request_timeout(State1#state{request = Request}),
@@ -375,22 +481,13 @@ handle_call(#request{address = Addr} = Request, _,
State = init_wait_for_response_state(Request, State2#state{session = NewSession}),
{reply, ok, State};
{error, Reason} ->
- ?hcri("failed sending request", [{reason, Reason}]),
- {stop, shutdown, {keepalive_failed, Reason}, State1}
+ {stop, {shutdown, {keepalive_failed, Reason}}, State1}
end
end;
-
-handle_call(info, _, State) ->
+do_handle_call(info, _, State) ->
Info = handler_info(State),
{reply, Info, State}.
-%%--------------------------------------------------------------------
-%% Function: handle_cast(Msg, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%% Description: Handling cast messages
-%%--------------------------------------------------------------------
-
%% When the request in process has been canceled the handler process is
%% stopped and the pipelined requests will be reissued or remaining
%% requests will be sent on a new connection. This is is
@@ -403,145 +500,102 @@ handle_call(info, _, State) ->
%% 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},
+do_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}]),
{stop, normal,
State#state{canceled = [RequestId | Canceled],
request = Request#request{from = answer_sent}}};
-handle_cast({cancel, RequestId},
- #state{profile_name = ProfileName,
- request = #request{id = CurrId},
- canceled = Canceled} = State) ->
- ?hcrv("cancel", [{request_id, RequestId},
- {curr_req_id, CurrId},
- {profile, ProfileName},
- {canceled, Canceled}]),
+do_handle_cast({cancel, RequestId},
+ #state{request = #request{},
+ canceled = Canceled} = State) ->
{noreply, State#state{canceled = [RequestId | Canceled]}};
-handle_cast({cancel, RequestId},
- #state{profile_name = ProfileName,
- request = undefined,
- canceled = Canceled} = State) ->
- ?hcrv("cancel", [{request_id, RequestId},
- {curr_req_id, undefined},
- {profile, ProfileName},
- {canceled, Canceled}]),
+do_handle_cast({cancel, _},
+ #state{request = undefined} = State) ->
{noreply, State};
-
-handle_cast(stream_next, #state{session = Session} = State) ->
+do_handle_cast(stream_next, #state{session = Session} = State) ->
activate_once(Session),
%% Inactivate the #state.once here because we don't want
%% next_body_chunk/1 to activate the socket twice.
{noreply, State#state{once = inactive}}.
-
-%%--------------------------------------------------------------------
-%% Function: handle_info(Info, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State} (terminate/2 is called)
-%% Description: Handling all non call/cast messages
-%%--------------------------------------------------------------------
-handle_info({Proto, _Socket, Data},
+do_handle_info({Proto, _Socket, Data},
#state{mfa = {Module, Function, Args},
- request = #request{method = Method,
- stream = Stream} = Request,
+ request = #request{method = Method} = Request,
session = Session,
status_line = StatusLine} = State)
when (Proto =:= tcp) orelse
(Proto =:= ssl) orelse
(Proto =:= httpc_handler) ->
- ?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", []),
- 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", [{length, Length}]),
- {_, Code, _} = StatusLine,
- {Streamed, 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 Streamed of
- false ->
- Length;
- true ->
- Length - size(Body)
- end,
-
- NewState = next_body_chunk(State, Code),
- NewMFA = {Module, whole_body, [NewBody, NewLength]},
- {noreply, NewState#state{mfa = NewMFA,
- request = NewRequest}};
- {Module, decode_size,
- [TotalChunk, HexList,
- {MaxBodySize, BodySoFar, AccLength, MaxHeaderSize}]}
- when BodySoFar =/= <<>> ->
- ?hcrd("data processed - decode_size", []),
- %% The response body is chunk-encoded. Steal decoded
- %% chunks as much as possible to stream.
- {_, Code, _} = StatusLine,
- {_, NewBody, NewRequest} = stream(BodySoFar, Request, Code),
- NewState = next_body_chunk(State, Code),
- NewMFA = {Module, decode_size,
- [TotalChunk, HexList,
- {MaxBodySize, NewBody, AccLength, MaxHeaderSize}]},
- {noreply, NewState#state{mfa = NewMFA,
- request = NewRequest}};
- {Module, decode_data,
- [ChunkSize, TotalChunk,
+ try Module:Function([Data | Args]) of
+ {ok, Result} ->
+ handle_http_msg(Result, State);
+ {_, whole_body, _} when Method =:= head ->
+ handle_response(State#state{body = <<>>});
+ {Module, whole_body, [Body, Length]} ->
+ {_, Code, _} = StatusLine,
+ {Streamed, 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 Streamed of
+ false ->
+ Length;
+ true ->
+ Length - size(Body)
+ end,
+
+ NewState = next_body_chunk(State, Code),
+ NewMFA = {Module, whole_body, [NewBody, NewLength]},
+ {noreply, NewState#state{mfa = NewMFA,
+ request = NewRequest}};
+ {Module, decode_size,
+ [TotalChunk, HexList, AccHeaderSize,
{MaxBodySize, BodySoFar, AccLength, MaxHeaderSize}]}
- when TotalChunk =/= <<>> orelse BodySoFar =/= <<>> ->
- ?hcrd("data processed - decode_data", []),
- %% The response body is chunk-encoded. Steal decoded
- %% chunks as much as possible to stream.
- ChunkSizeToSteal = min(ChunkSize, byte_size(TotalChunk)),
- <<StolenChunk:ChunkSizeToSteal/binary, NewTotalChunk/binary>> = TotalChunk,
- StolenBody = <<BodySoFar/binary, StolenChunk/binary>>,
- NewChunkSize = ChunkSize - ChunkSizeToSteal,
- {_, Code, _} = StatusLine,
-
- {_, NewBody, NewRequest} = stream(StolenBody, Request, Code),
- NewState = next_body_chunk(State, Code),
- NewMFA = {Module, decode_data,
- [NewChunkSize, NewTotalChunk,
+ when BodySoFar =/= <<>> ->
+ %% The response body is chunk-encoded. Steal decoded
+ %% chunks as much as possible to stream.
+ {_, Code, _} = StatusLine,
+ {_, NewBody, NewRequest} = stream(BodySoFar, Request, Code),
+ NewState = next_body_chunk(State, Code),
+ NewMFA = {Module, decode_size,
+ [TotalChunk, HexList, AccHeaderSize,
{MaxBodySize, NewBody, AccLength, MaxHeaderSize}]},
+ {noreply, NewState#state{mfa = NewMFA,
+ request = NewRequest}};
+ {Module, decode_data,
+ [ChunkSize, TotalChunk,
+ {MaxBodySize, BodySoFar, AccLength, MaxHeaderSize}]}
+ when TotalChunk =/= <<>> orelse BodySoFar =/= <<>> ->
+ %% The response body is chunk-encoded. Steal decoded
+ %% chunks as much as possible to stream.
+ ChunkSizeToSteal = min(ChunkSize, byte_size(TotalChunk)),
+ <<StolenChunk:ChunkSizeToSteal/binary, NewTotalChunk/binary>> = TotalChunk,
+ StolenBody = <<BodySoFar/binary, StolenChunk/binary>>,
+ NewChunkSize = ChunkSize - ChunkSizeToSteal,
+ {_, Code, _} = StatusLine,
+
+ {_, NewBody, NewRequest} = stream(StolenBody, Request, Code),
+ NewState = next_body_chunk(State, Code),
+ NewMFA = {Module, decode_data,
+ [NewChunkSize, NewTotalChunk,
+ {MaxBodySize, NewBody, AccLength, MaxHeaderSize}]},
{noreply, NewState#state{mfa = NewMFA,
request = NewRequest}};
- NewMFA ->
- ?hcrd("data processed - new mfa", []),
- activate_once(Session),
- {noreply, State#state{mfa = NewMFA}}
- catch
- _:_Reason ->
- ?hcrd("data processing exit", [{exit, _Reason}]),
- 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", [{final_result, FinalResult}]),
- FinalResult;
-
+ NewMFA ->
+ activate_once(Session),
+ {noreply, State#state{mfa = NewMFA}}
+ catch
+ _:Reason ->
+ ClientReason = {could_not_parse_as_http, Data},
+ ClientErrMsg = httpc_response:error(Request, ClientReason),
+ NewState = answer_request(Request, ClientErrMsg, State),
+ {stop, {shutdown, Reason}, NewState}
+ end;
-handle_info({Proto, Socket, Data},
+do_handle_info({Proto, Socket, Data},
#state{mfa = MFA,
request = Request,
session = Session,
@@ -566,200 +620,107 @@ handle_info({Proto, Socket, Data},
{noreply, State};
-
%% The Server may close the connection to indicate that the
%% whole body is now sent instead of sending an length
%% indicator.
-handle_info({tcp_closed, _}, State = #state{mfa = {_, whole_body, Args}}) ->
+do_handle_info({tcp_closed, _}, State = #state{mfa = {_, whole_body, Args}}) ->
handle_response(State#state{body = hd(Args)});
-handle_info({ssl_closed, _}, State = #state{mfa = {_, whole_body, Args}}) ->
+do_handle_info({ssl_closed, _}, State = #state{mfa = {_, whole_body, Args}}) ->
handle_response(State#state{body = hd(Args)});
%%% Server closes idle pipeline
-handle_info({tcp_closed, _}, State = #state{request = undefined}) ->
+do_handle_info({tcp_closed, _}, State = #state{request = undefined}) ->
{stop, normal, State};
-handle_info({ssl_closed, _}, State = #state{request = undefined}) ->
+do_handle_info({ssl_closed, _}, State = #state{request = undefined}) ->
{stop, normal, State};
%%% Error cases
-handle_info({tcp_closed, _}, #state{session = Session0} = State) ->
+do_handle_info({tcp_closed, _}, #state{session = Session0} = State) ->
Socket = Session0#session.socket,
Session = Session0#session{socket = {remote_close, Socket}},
%% {stop, session_remotly_closed, State};
{stop, normal, State#state{session = Session}};
-handle_info({ssl_closed, _}, #state{session = Session0} = State) ->
+do_handle_info({ssl_closed, _}, #state{session = Session0} = State) ->
Socket = Session0#session.socket,
Session = Session0#session{socket = {remote_close, Socket}},
%% {stop, session_remotly_closed, State};
{stop, normal, State#state{session = Session}};
-handle_info({tcp_error, _, _} = Reason, State) ->
+do_handle_info({tcp_error, _, _} = Reason, State) ->
{stop, Reason, State};
-handle_info({ssl_error, _, _} = Reason, State) ->
+do_handle_info({ssl_error, _, _} = Reason, State) ->
{stop, Reason, State};
%% Timeouts
%% Internally, to a request handling process, a request timeout is
%% seen as a canceled request.
-handle_info({timeout, RequestId},
+do_handle_info({timeout, RequestId},
#state{request = #request{id = RequestId} = Request,
canceled = Canceled,
profile_name = ProfileName} = State) ->
- ?hcri("timeout of current request", [{id, RequestId}]),
httpc_response:send(Request#request.from,
httpc_response:error(Request, timeout)),
httpc_manager:request_done(RequestId, ProfileName),
- ?hcrv("response (timeout) sent - now terminate", []),
{stop, normal,
State#state{request = Request#request{from = answer_sent},
canceled = [RequestId | Canceled]}};
-handle_info({timeout, RequestId},
+do_handle_info({timeout, RequestId},
#state{canceled = Canceled,
profile_name = ProfileName} = 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
httpc_response:send(From,
httpc_response:error(Request, timeout)),
httpc_manager:request_done(RequestId, ProfileName),
- ?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}}
end;
-handle_info(timeout_queue, State = #state{request = undefined}) ->
+do_handle_info(timeout_queue, State = #state{request = undefined}) ->
{stop, normal, State};
%% Timing was such as the queue_timeout was not canceled!
-handle_info(timeout_queue, #state{timers = Timers} = State) ->
+do_handle_info(timeout_queue, #state{timers = Timers} = State) ->
{noreply, State#state{timers =
Timers#timers{queue_timer = undefined}}};
%% Setting up the connection to the server somehow failed.
-handle_info({init_error, Tag, ClientErrMsg},
+do_handle_info({init_error, Reason, ClientErrMsg},
State = #state{request = Request}) ->
- ?hcrv("init error", [{tag, Tag}, {client_error, ClientErrMsg}]),
NewState = answer_request(Request, ClientErrMsg, State),
- {stop, normal, NewState};
-
+ {stop, {shutdown, Reason}, NewState};
%%% httpc_manager process dies.
-handle_info({'EXIT', _, _}, State = #state{request = undefined}) ->
+do_handle_info({'EXIT', _, _}, State = #state{request = undefined}) ->
{stop, normal, State};
%%Try to finish the current request anyway,
%% there is a fairly high probability that it can be done successfully.
%% Then close the connection, hopefully a new manager is started that
%% can retry requests in the pipeline.
-handle_info({'EXIT', _, _}, State) ->
+do_handle_info({'EXIT', _, _}, State) ->
{noreply, State#state{status = close}}.
-%%--------------------------------------------------------------------
-%% Function: terminate(Reason, State) -> _ (ignored by gen_server)
-%% Description: Shutdown the httpc_handler
-%%--------------------------------------------------------------------
-
-%% Init error there is no socket to be closed.
-terminate(normal,
- #state{request = Request,
- session = {send_failed, AReason} = Reason} = State) ->
- ?hcrd("terminate", [{send_reason, AReason}, {request, Request}]),
- maybe_send_answer(Request,
- httpc_response:error(Request, Reason),
- State),
- ok;
-
-terminate(normal,
- #state{request = Request,
- session = {connect_failed, AReason} = Reason} = State) ->
- ?hcrd("terminate", [{connect_reason, AReason}, {request, Request}]),
- maybe_send_answer(Request,
- httpc_response:error(Request, Reason),
- State),
- ok;
-
-terminate(normal, #state{session = undefined}) ->
- ok;
-
-%% Init error sending, no session information has been setup but
-%% there is a socket that needs closing.
-terminate(normal,
- #state{session = #session{id = undefined} = Session}) ->
- close_socket(Session);
-
-%% Socket closed remotely
-terminate(normal,
- #state{session = #session{socket = {remote_close, Socket},
- socket_type = SocketType,
- id = Id},
- profile_name = ProfileName,
- request = Request,
- timers = Timers,
- pipeline = Pipeline,
- keep_alive = KeepAlive} = State) ->
- ?hcrt("terminate(normal) - remote close",
- [{id, Id}, {profile, ProfileName}]),
-
- %% Clobber session
- (catch httpc_manager:delete_session(Id, ProfileName)),
-
- maybe_retry_queue(Pipeline, State),
- maybe_retry_queue(KeepAlive, State),
-
- %% Cancel timers
- cancel_timers(Timers),
-
- %% Maybe deliver answers to requests
- deliver_answer(Request),
-
- %% And, just in case, close our side (**really** overkill)
- http_transport:close(SocketType, Socket);
-
-terminate(Reason, #state{session = #session{id = Id,
- socket = Socket,
- socket_type = SocketType},
- request = undefined,
- profile_name = ProfileName,
- timers = Timers,
- pipeline = Pipeline,
- keep_alive = KeepAlive} = State) ->
- ?hcrt("terminate",
- [{id, Id}, {profile, ProfileName}, {reason, Reason}]),
-
- %% Clobber session
- (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),
- http_transport:close(SocketType, Socket);
+call(Msg, Pid) ->
+ call(Msg, Pid, infinity).
-terminate(Reason, #state{request = undefined}) ->
- ?hcrt("terminate", [{reason, Reason}]),
- ok;
+call(Msg, Pid, Timeout) ->
+ gen_server:call(Pid, Msg, Timeout).
-terminate(Reason, #state{request = Request} = State) ->
- ?hcrd("terminate", [{reason, Reason}, {request, Request}]),
- NewState = maybe_send_answer(Request,
- httpc_response:error(Request, Reason),
- State),
- terminate(Reason, NewState#state{request = undefined}).
+cast(Msg, Pid) ->
+ gen_server:cast(Pid, Msg).
maybe_retry_queue(Q, State) ->
case queue:is_empty(Q) of
@@ -774,86 +735,13 @@ maybe_send_answer(#request{from = answer_sent}, _Reason, State) ->
maybe_send_answer(Request, Answer, State) ->
answer_request(Request, Answer, State).
-deliver_answer(#request{id = Id, from = From} = Request)
+deliver_answer(#request{from = From} = Request)
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_answer(Request) ->
- ?hcrd("skip deliver answer", [{request, Request}]),
+deliver_answer(_Request) ->
ok.
-
-%%--------------------------------------------------------------------
-%% Func: code_change(_OldVsn, State, Extra) -> {ok, NewState}
-%% Purpose: Convert process state when code is changed
-%%--------------------------------------------------------------------
-
-code_change(_,
- #state{session = OldSession,
- profile_name = ProfileName} = State,
- upgrade_from_pre_5_8_1) ->
- case OldSession of
- {session,
- Id, ClientClose, Scheme, Socket, SocketType, QueueLen, Type} ->
- NewSession = #session{id = Id,
- client_close = ClientClose,
- scheme = Scheme,
- socket = Socket,
- socket_type = SocketType,
- queue_length = QueueLen,
- type = Type},
- insert_session(NewSession, ProfileName),
- {ok, State#state{session = NewSession}};
- _ ->
- {ok, State}
- end;
-
-code_change(_,
- #state{session = OldSession,
- profile_name = ProfileName} = State,
- downgrade_to_pre_5_8_1) ->
- case OldSession of
- #session{id = Id,
- client_close = ClientClose,
- scheme = Scheme,
- socket = Socket,
- socket_type = SocketType,
- queue_length = QueueLen,
- type = Type} ->
- NewSession = {session,
- Id, ClientClose, Scheme, Socket, SocketType,
- QueueLen, Type},
- insert_session(NewSession, ProfileName),
- {ok, State#state{session = NewSession}};
- _ ->
- {ok, State}
- end;
-
-code_change(_, State, _) ->
- {ok, State}.
-
-
-%% new_http_options({http_options, TimeOut, AutoRedirect, SslOpts,
-%% Auth, Relaxed}) ->
-%% {http_options, "HTTP/1.1", TimeOut, AutoRedirect, SslOpts,
-%% Auth, Relaxed}.
-
-%% old_http_options({http_options, _, TimeOut, AutoRedirect,
-%% SslOpts, Auth, Relaxed}) ->
-%% {http_options, TimeOut, AutoRedirect, SslOpts, Auth, Relaxed}.
-
-%% new_queue(Queue, Fun) ->
-%% List = queue:to_list(Queue),
-%% NewList =
-%% lists:map(fun(Request) ->
-%% Settings =
-%% Fun(Request#request.settings),
-%% Request#request{settings = Settings}
-%% end, List),
-%% queue:from_list(NewList).
-
-
%%%--------------------------------------------------------------------
%%% Internal functions
%%%--------------------------------------------------------------------
@@ -911,31 +799,25 @@ connect(SocketType, ToAddress,
connect_and_send_first_request(Address, Request, #state{options = Options} = State) ->
SocketType = socket_type(Request),
ConnTimeout = (Request#request.settings)#http_options.connect_timeout,
- ?hcri("connect",
- [{address, Address}, {request, Request}, {options, Options}]),
case connect(SocketType, Address, Options, ConnTimeout) of
{ok, Socket} ->
ClientClose =
- httpc_request:is_client_closing(
- Request#request.headers),
+ httpc_request:is_client_closing(
+ Request#request.headers),
SessionType = httpc_manager:session_type(Options),
SocketType = socket_type(Request),
Session = #session{id = {Request#request.address, self()},
scheme = Request#request.scheme,
socket = Socket,
- socket_type = SocketType,
- client_close = ClientClose,
- type = SessionType},
- ?hcri("connected - now send first request", [{socket, Socket}]),
-
+ socket_type = SocketType,
+ client_close = ClientClose,
+ type = SessionType},
case httpc_request:send(Address, Session, Request) of
ok ->
- ?hcri("first request sent", []),
TmpState = State#state{request = Request,
session = Session,
mfa = init_mfa(Request, State),
- status_line =
- init_status_line(Request),
+ status_line = init_status_line(Request),
headers = undefined,
body = undefined,
status = new},
@@ -947,8 +829,7 @@ connect_and_send_first_request(Address, Request, #state{options = Options} = Sta
self() ! {init_error, error_sending,
httpc_response:error(Request, Reason)},
{ok, State#state{request = Request,
- session =
- #session{socket = Socket}}}
+ session = #session{socket = Socket}}}
end;
{error, Reason} ->
self() ! {init_error, error_connecting,
@@ -990,12 +871,6 @@ handler_info(#state{request = Request,
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
@@ -1006,8 +881,6 @@ handler_info(#state{request = Request,
[{id, Id}, {started, ReqStarted}]
end,
- ?hcrt("handler info", [{request_info, RequestInfo}]),
-
%% Info about the current session/socket
SessionType = Session#session.type,
QueueLen = case SessionType of
@@ -1020,22 +893,12 @@ handler_info(#state{request = Request,
Socket = Session#session.socket,
SocketType = Session#session.socket_type,
- ?hcrt("handler info", [{session_type, SessionType},
- {queue_length, QueueLen},
- {scheme, Scheme},
- {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},
@@ -1055,7 +918,6 @@ handler_info(#state{request = Request,
handle_http_msg({Version, StatusCode, ReasonPharse, Headers, Body},
State = #state{request = Request}) ->
- ?hcrt("handle_http_msg", [{headers, Headers}]),
case Headers#http_response_h.'content-type' of
"multipart/byteranges" ++ _Param ->
exit({not_yet_implemented, multypart_byteranges});
@@ -1069,15 +931,12 @@ handle_http_msg({Version, StatusCode, ReasonPharse, Headers, Body},
end;
handle_http_msg({ChunkedHeaders, Body},
#state{status_line = {_, Code, _}, headers = Headers} = State) ->
- ?hcrt("handle_http_msg",
- [{chunked_headers, ChunkedHeaders}, {headers, Headers}]),
NewHeaders = http_chunk:handle_headers(Headers, ChunkedHeaders),
{_, NewBody, NewRequest} = stream(Body, State#state.request, Code),
handle_response(State#state{headers = NewHeaders,
body = NewBody,
request = NewRequest});
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}).
@@ -1092,41 +951,28 @@ handle_http_body(_, #state{status = {ssl_tunnel, Request},
{stop, normal, NewState};
handle_http_body(<<>>, #state{status_line = {_,304, _}} = State) ->
- ?hcrt("handle_http_body - 304", []),
handle_response(State#state{body = <<>>});
handle_http_body(<<>>, #state{status_line = {_,204, _}} = State) ->
- ?hcrt("handle_http_body - 204", []),
handle_response(State#state{body = <<>>});
handle_http_body(<<>>, #state{request = #request{method = head}} = State) ->
- ?hcrt("handle_http_body - head", []),
handle_response(State#state{body = <<>>});
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" ->
- ?hcrt("handle_http_body - chunked", []),
try http_chunk:decode(Body, State#state.max_body_size,
State#state.max_header_size) of
{Module, Function, Args} ->
- ?hcrt("handle_http_body - new mfa",
- [{module, Module},
- {function, Function},
- {args, Args}]),
NewState = next_body_chunk(State, Code),
{noreply, NewState#state{mfa =
{Module, Function, Args}}};
{ok, {ChunkedHeaders, NewBody}} ->
- ?hcrt("handle_http_body - new body",
- [{chunked_headers, ChunkedHeaders},
- {new_body, NewBody}]),
NewHeaders = http_chunk:handle_headers(Headers,
ChunkedHeaders),
case Body of
@@ -1148,7 +994,6 @@ handle_http_body(Body, #state{headers = Headers,
{stop, normal, NewState}
end;
Enc when Enc =:= "identity"; Enc =:= undefined ->
- ?hcrt("handle_http_body - identity", []),
Length =
list_to_integer(Headers#http_response_h.'content-length'),
case ((Length =< MaxBodySize) orelse (MaxBodySize =:= nolimit)) of
@@ -1172,7 +1017,6 @@ handle_http_body(Body, #state{headers = Headers,
{stop, normal, NewState}
end;
Encoding when is_list(Encoding) ->
- ?hcrt("handle_http_body - other", [{encoding, Encoding}]),
NewState = answer_request(Request,
httpc_response:error(Request,
unknown_encoding),
@@ -1193,18 +1037,10 @@ handle_response(#state{request = Request,
options = Options,
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,
send_raw(Session, RequestBody),
@@ -1221,7 +1057,6 @@ handle_response(#state{request = Request,
%% 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,
MFA = {httpc_response, parse,
[State#state.max_header_size, Relaxed]},
@@ -1235,23 +1070,17 @@ handle_response(#state{request = Request,
%% 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}]),
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}]),
ok = httpc_manager:retry_request(TimeNewRequest, ProfileName),
handle_queue(State#state{request = undefined}, Data);
{ok, Msg, Data} ->
- ?hcrd("handle response - ok", []),
stream_remaining_body(Body, Request, StatusLine),
end_stream(StatusLine, Request),
NewState = maybe_send_answer(Request, Msg, State),
handle_queue(NewState, Data);
{stop, Msg} ->
- ?hcrd("handle response - stop", [{msg, Msg}]),
end_stream(StatusLine, Request),
NewState = maybe_send_answer(Request, Msg, State),
{stop, normal, NewState}
@@ -1286,28 +1115,19 @@ handle_pipeline(#state{status = pipeline,
profile_name = ProfileName,
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("pipeline queue empty", []),
handle_empty_queue(Session, ProfileName, TimeOut, State);
{{value, NextRequest}, Pipeline} ->
- ?hcrd("pipeline queue non-empty", []),
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},
pipeline = Pipeline}};
false ->
- ?hcrv("next request", [{request, NextRequest}]),
NewSession =
Session#session{queue_length =
%% Queue + current
@@ -1324,25 +1144,16 @@ handle_keep_alive_queue(#state{status = keep_alive,
options = #options{keep_alive_timeout = TimeOut,
proxy = Proxy}} = State,
Data) ->
-
- ?hcrd("handle keep_alive", [{profile, ProfileName},
- {session, Session},
- {timeout, TimeOut}]),
-
case queue:out(State#state.keep_alive) of
{empty, _} ->
- ?hcrd("keep_alive queue empty", []),
handle_empty_queue(Session, ProfileName, TimeOut, State);
{{value, NextRequest}, KeepAlive} ->
- ?hcrd("keep_alive queue non-empty", []),
case lists:member(NextRequest#request.id,
State#state.canceled) of
true ->
- ?hcrv("next request has already been canceled", []),
handle_keep_alive_queue(
State#state{keep_alive = KeepAlive}, Data);
false ->
- ?hcrv("next request", [{request, NextRequest}]),
#request{address = Addr} = NextRequest,
Address = handle_proxy(Addr, Proxy),
case httpc_request:send(Address, Session, NextRequest) of
@@ -1355,7 +1166,6 @@ handle_keep_alive_queue(#state{status = keep_alive,
end
end
end.
-
handle_empty_queue(Session, ProfileName, TimeOut, State) ->
%% The server may choose too terminate an idle pipline| keep_alive session
%% in this case we want to receive the close message
@@ -1365,17 +1175,20 @@ handle_empty_queue(Session, ProfileName, TimeOut, State) ->
%% If a pipline | 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),
- update_session(ProfileName, Session, #session.queue_length, 0),
- %% Note mfa will be initialized when a new request
- %% arrives.
- {noreply,
- NewState#state{request = undefined,
- mfa = undefined,
- status_line = undefined,
- headers = undefined,
- body = undefined
- }
- }.
+ case update_session(ProfileName, Session, #session.queue_length, 0) of
+ {stop, Reason} ->
+ {stop, {shutdown, Reason}, State};
+ _ ->
+ %% Note mfa will be initialized when a new request
+ %% arrives.
+ {noreply,
+ NewState#state{request = undefined,
+ mfa = undefined,
+ status_line = undefined,
+ headers = undefined,
+ body = undefined
+ }}
+ end.
receive_response(Request, Session, Data, State) ->
NewState = init_wait_for_response_state(Request, State),
@@ -1391,7 +1204,6 @@ init_wait_for_response_state(Request, State) ->
status_line = undefined,
headers = undefined,
body = undefined}.
-
gather_data(<<>>, Session, State) ->
activate_once(Session),
{noreply, State};
@@ -1415,29 +1227,29 @@ close_socket(#session{socket = Socket, socket_type = SocketType}) ->
http_transport:close(SocketType, Socket).
activate_request_timeout(
- #state{request = #request{timer = undefined} = Request} = State) ->
+ #state{request = #request{timer = OldRef} = Request} = State) ->
Timeout = (Request#request.settings)#http_options.timeout,
case Timeout of
infinity ->
State;
_ ->
ReqId = Request#request.id,
- ?hcrt("activate request timer",
- [{request_id, ReqId},
- {time_consumed, t() - Request#request.started},
- {timeout, Timeout}]),
Msg = {timeout, ReqId},
+ case OldRef of
+ undefined ->
+ ok;
+ _ ->
+ %% Timer is already running! This is the case for a redirect or retry
+ %% We need to restart the timer because the handler pid has changed
+ cancel_timer(OldRef, Msg)
+ end,
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.
+ end.
activate_queue_timeout(infinity, State) ->
State;
@@ -1468,10 +1280,6 @@ try_to_enable_pipeline_or_keep_alive(
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 ->
@@ -1496,7 +1304,6 @@ answer_request(#request{id = RequestId, from = From} = Request, Msg,
#state{session = Session,
timers = Timers,
profile_name = ProfileName} = State) ->
- ?hcrt("answer request", [{request, Request}, {msg, Msg}]),
httpc_response:send(From, Msg),
RequestTimers = Timers#timers.request_timers,
TimerRef =
@@ -1643,42 +1450,32 @@ socket_type(#request{scheme = http}) ->
ip_comm;
socket_type(#request{scheme = https, settings = Settings}) ->
Settings#http_options.ssl.
-%% socket_type(http) ->
-%% ip_comm;
-%% socket_type(https) ->
-%% {ssl1, []}. %% Dummy value ok for ex setopts that does not use this value
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)
when ?IS_STREAMED(Code) ->
- ?hcrt("start stream - self", [{code, Code}]),
Msg = httpc_response:stream_start(Headers, Request, ignore),
httpc_response:send(Request#request.from, Msg),
{ok, Request};
start_stream({_Version, Code, _ReasonPhrase}, Headers,
#request{stream = {self, once}} = Request)
when ?IS_STREAMED(Code) ->
- ?hcrt("start stream - self:once", [{code, Code}]),
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)
when ?IS_STREAMED(Code) andalso is_list(Filename) ->
- ?hcrt("start stream", [{code, Code}, {filename, Filename}]),
case file:open(Filename, [write, raw, append, delayed_write]) of
{ok, Fd} ->
- ?hcri("start stream - file open ok", [{fd, Fd}]),
{ok, Request#request{stream = Fd}};
{error, Reason} ->
exit({stream_to_file_failed, Reason})
end;
start_stream(_StatusLine, _Headers, Request) ->
- ?hcrt("start stream - no op", []),
{ok, Request}.
stream_remaining_body(<<>>, _, _) ->
@@ -1689,16 +1486,12 @@ stream_remaining_body(Body, Request, {_, Code, _}) ->
%% Note the end stream message is handled by httpc_response and will
%% be sent by answer_request
end_stream(_, #request{stream = none}) ->
- ?hcrt("end stream - none", []),
ok;
end_stream(_, #request{stream = self}) ->
- ?hcrt("end stream - self", []),
ok;
end_stream(_, #request{stream = {self, once}}) ->
- ?hcrt("end stream - self:once", []),
ok;
end_stream({_,200,_}, #request{stream = Fd}) ->
- ?hcrt("end stream - 200", [{stream, Fd}]),
case file:close(Fd) of
ok ->
ok;
@@ -1706,15 +1499,13 @@ end_stream({_,200,_}, #request{stream = Fd}) ->
file:close(Fd)
end;
end_stream({_,206,_}, #request{stream = Fd}) ->
- ?hcrt("end stream - 206", [{stream, Fd}]),
case file:close(Fd) of
ok ->
ok;
{error, enospc} -> % Could be due to delayed_write
file:close(Fd)
end;
-end_stream(SL, R) ->
- ?hcrt("end stream", [{status_line, SL}, {request, R}]),
+end_stream(_, _) ->
ok.
@@ -1743,11 +1534,8 @@ handle_verbose(trace) ->
handle_verbose(_) ->
ok.
-
-
send_raw(#session{socket = Socket, socket_type = SocketType},
{ProcessBody, Acc}) when is_function(ProcessBody, 1) ->
- ?hcrt("send raw", [{acc, Acc}]),
send_raw(SocketType, Socket, ProcessBody, Acc);
send_raw(#session{socket = Socket, socket_type = SocketType}, Body) ->
http_transport:send(SocketType, Socket, Body).
@@ -1758,7 +1546,6 @@ send_raw(SocketType, Socket, ProcessBody, Acc) ->
ok;
{ok, Data, NewAcc} ->
DataBin = iolist_to_binary(Data),
- ?hcrd("send", [{data, DataBin}]),
case http_transport:send(SocketType, Socket, DataBin) of
ok ->
send_raw(SocketType, Socket, ProcessBody, NewAcc);
@@ -1790,14 +1577,16 @@ tls_tunnel(Address, Request, #state{session = #session{socket = Socket,
tls_tunnel_request(#request{headers = Headers,
settings = Options,
+ id = RequestId,
+ from = From,
address = {Host, Port}= Adress,
ipv6_host_with_brackets = IPV6}) ->
URI = Host ++":" ++ integer_to_list(Port),
#request{
- id = make_ref(),
- from = self(),
+ id = RequestId,
+ from = From,
scheme = http, %% Use tcp-first and then upgrade!
address = Adress,
path = URI,
@@ -1887,10 +1676,13 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) ->
httpc_manager:update_session(ProfileName, SessionId, Pos, Value)
end
catch
- error:undef -> % This could happen during code upgrade
+ error:undef -> %% This could happen during code upgrade
Session2 = erlang:setelement(Pos, Session, Value),
insert_session(Session2, ProfileName);
- T:E ->
+ error:badarg ->
+ {stop, normal};
+ T:E ->
+ %% Unexpected this must be an error!
Stacktrace = erlang:get_stacktrace(),
error_logger:error_msg("Failed updating session: "
"~n ProfileName: ~p"
@@ -1908,27 +1700,14 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) ->
Session,
(catch httpc_manager:lookup_session(SessionId, ProfileName)),
T, E]),
- exit({failed_updating_session,
- [{profile, ProfileName},
- {session_id, SessionId},
- {pos, Pos},
- {value, Value},
- {etype, T},
- {error, E},
- {stacktrace, Stacktrace}]})
+ {stop, {failed_updating_session,
+ [{profile, ProfileName},
+ {session_id, SessionId},
+ {pos, Pos},
+ {value, Value},
+ {etype, T},
+ {error, E},
+ {stacktrace, Stacktrace}]}}
end.
-%% ---------------------------------------------------------------------
-
-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).
-
-t() ->
- http_util:timestamp().
diff --git a/lib/inets/src/http_client/httpc_internal.hrl b/lib/inets/src/http_client/httpc_internal.hrl
index f4e69cc1fa..5f8c70f28d 100644
--- a/lib/inets/src/http_client/httpc_internal.hrl
+++ b/lib/inets/src/http_client/httpc_internal.hrl
@@ -43,32 +43,32 @@
%%% HTTP Client per request settings
-record(http_options,
{
- %% string() - "HTTP/1.1" | "HTTP/1.0" | "HTTP/0.9"
- version,
+ %% "HTTP/1.1" | "HTTP/1.0" | "HTTP/0.9"
+ version :: 'undefined' | string(),
- %% integer() | infinity - ms before a request times out
- timeout = ?HTTP_REQUEST_TIMEOUT,
+ %% ms before a request times out
+ timeout = ?HTTP_REQUEST_TIMEOUT :: timeout(),
- %% bool() - true if auto redirect on 30x response
- autoredirect = true,
+ %% true if auto redirect on 30x response
+ autoredirect = true :: boolean(),
%% ssl socket options
- ssl = [],
+ ssl = [],
%% {User, Password} = {string(), string()}
proxy_auth,
- %% bool() - true if not strictly std compliant
- relaxed = false,
+ %% true if not strictly std compliant
+ relaxed = false :: boolean(),
%% integer() - ms before a connect times out
- connect_timeout = ?HTTP_REQUEST_CTIMEOUT,
-
- %% bool() - Use %-encoding rfc 2396
- url_encode
+ connect_timeout = ?HTTP_REQUEST_CTIMEOUT :: timeout(),
+ %% Use %-encoding rfc 2396
+ url_encode :: 'undefined' | boolean()
}
).
+-type http_options() :: #http_options{}.
%%% HTTP Client per profile setting.
-record(options,
@@ -82,18 +82,19 @@
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,
+ verbose = false, % boolean(),
ipfamily = inet, % inet | inet6 | inet6fb4
ip = default, % specify local interface
port = default, % specify local port
socket_opts = [] % other socket options
}
).
+-type options() :: #options{}.
%%% All data associated to a specific HTTP request
-record(request,
{
- id, % ref() - Request Id
+ id :: 'undefined' | reference(), % Request Id
from, % pid() - Caller
redircount = 0,% Number of redirects made for this request
scheme, % http | https
@@ -103,7 +104,7 @@
method, % atom() - HTTP request Method
headers, % #http_request_h{}
content, % {ContentType, Body} - Current HTTP request
- settings, % #http_options{} - User defined settings
+ 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?
@@ -112,20 +113,19 @@
% for testing purposes.
started, % integer() > 0 - When we started processing the
% request
- timer, % undefined | ref()
+ timer :: undefined | reference(),
socket_opts, % undefined | [socket_option()]
ipv6_host_with_brackets % boolean()
}
- ).
-
+ ).
+-type request() :: #request{}.
-record(session,
{
%% {{Host, Port}, HandlerPid}
id,
- %% true | false
- client_close,
+ client_close :: 'undefined' | boolean(),
%% http (HTTP/TCP) | https (HTTP/SSL/TCP)
scheme,
@@ -140,14 +140,13 @@
queue_length = 1,
%% pipeline | keep_alive (wait for response before sending new request)
- type,
+ type :: 'undefined' | 'pipeline' | 'keep_alive',
- %% true | false
%% This will be true, when a response has been received for
%% the first request. See type above.
- available = false
+ available = false :: boolean()
}).
-
+-type session() :: #session{}.
-record(http_cookie,
{
@@ -162,7 +161,7 @@
secure = false,
version = "0"
}).
-
+-type http_cookie() :: #http_cookie{}.
%% -record(parsed_uri,
%% {
diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl
index 4cb6f005ad..a63864493f 100644
--- a/lib/inets/src/http_client/httpc_manager.erl
+++ b/lib/inets/src/http_client/httpc_manager.erl
@@ -137,7 +137,7 @@ redirect_request(Request, ProfileName) ->
%%--------------------------------------------------------------------
%% Function: cancel_request(RequestId, ProfileName) -> ok
-%% RequestId - ref()
+%% RequestId - reference()
%% ProfileName = atom()
%%
%% Description: Cancels the request with <RequestId>.
@@ -148,7 +148,7 @@ cancel_request(RequestId, ProfileName) ->
%%--------------------------------------------------------------------
%% Function: request_done(RequestId, ProfileName) -> ok
-%% RequestId - ref()
+%% RequestId - reference()
%% ProfileName = atom()
%%
%% Description: Inform tha manager that a request has been completed.
diff --git a/lib/inets/src/http_client/httpc_request.erl b/lib/inets/src/http_client/httpc_request.erl
index e8d020c165..89872a3831 100644
--- a/lib/inets/src/http_client/httpc_request.erl
+++ b/lib/inets/src/http_client/httpc_request.erl
@@ -88,9 +88,11 @@ send(SendAddr, Socket, SocketType,
case Address of
SendAddr ->
{TmpHdrs2, Path ++ Query};
- _Proxy ->
+ _Proxy when SocketType == ip_comm ->
TmpHdrs3 = handle_proxy(HttpOptions, TmpHdrs2),
- {TmpHdrs3, AbsUri}
+ {TmpHdrs3, AbsUri};
+ _ ->
+ {TmpHdrs2, Path ++ Query}
end,
FinalHeaders =
diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl
index 91256fa6a2..b3b11b74ab 100644
--- a/lib/inets/src/http_client/httpc_response.erl
+++ b/lib/inets/src/http_client/httpc_response.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -110,27 +110,30 @@ result(Response = {{_, 300, _}, _, _},
redirect(Response, Request);
result(Response = {{_, Code, _}, _, _},
+ Request = #request{settings =
+ #http_options{autoredirect = true},
+ method = post}) when (Code =:= 301) orelse
+ (Code =:= 302) orelse
+ (Code =:= 303) ->
+ redirect(Response, Request#request{method = get});
+result(Response = {{_, Code, _}, _, _},
+ Request = #request{settings =
+ #http_options{autoredirect = true},
+ method = post}) when (Code =:= 307) ->
+ redirect(Response, Request);
+result(Response = {{_, Code, _}, _, _},
Request = #request{settings =
#http_options{autoredirect = true},
- method = head}) when (Code =:= 301) orelse
+ method = Method}) when (Code =:= 301) orelse
(Code =:= 302) orelse
(Code =:= 303) orelse
(Code =:= 307) ->
- redirect(Response, Request);
-result(Response = {{_, Code, _}, _, _},
- Request = #request{settings =
- #http_options{autoredirect = true},
- method = get}) when (Code =:= 301) orelse
- (Code =:= 302) orelse
- (Code =:= 303) orelse
- (Code =:= 307) ->
- redirect(Response, Request);
-result(Response = {{_, 303, _}, _, _},
- Request = #request{settings =
- #http_options{autoredirect = true},
- method = post}) ->
- redirect(Response, Request#request{method = get});
-
+ case lists:member(Method, [get, head, options, trace]) of
+ true ->
+ redirect(Response, Request);
+ false ->
+ transparent(Response, Request)
+ end;
result(Response = {{_,503,_}, _, _}, Request) ->
status_service_unavailable(Response, Request);
@@ -359,8 +362,9 @@ redirect(Response = {StatusLine, Headers, Body}, Request) ->
{ok, error(Request, Reason), Data};
%% Automatic redirection
{ok, {Scheme, _, Host, Port, Path, Query}} ->
+ HostPort = http_request:normalize_host(Scheme, Host, Port),
NewHeaders =
- (Request#request.headers)#http_request_h{host = Host},
+ (Request#request.headers)#http_request_h{host = HostPort},
NewRequest =
Request#request{redircount =
Request#request.redircount+1,
@@ -431,7 +435,7 @@ format_response({StatusLine, Headers, Body}) ->
Length = list_to_integer(Headers#http_response_h.'content-length'),
{NewBody, Data} =
case Length of
- -1 -> % When no lenght indicator is provided
+ -1 -> % When no length indicator is provided
{Body, <<>>};
Length when (Length =< size(Body)) ->
<<BodyThisReq:Length/binary, Next/binary>> = Body,
diff --git a/lib/inets/src/http_lib/http_internal.hrl b/lib/inets/src/http_lib/http_internal.hrl
index ae92b5df8f..ca1dad07cd 100644
--- a/lib/inets/src/http_lib/http_internal.hrl
+++ b/lib/inets/src/http_lib/http_internal.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -71,7 +71,7 @@
'last-modified',
other=[] % list() - Key/Value list with other headers
}).
-
+-type http_response_h() :: #http_response_h{}.
%%% Request headers
-record(http_request_h,{
@@ -118,5 +118,6 @@
'last-modified',
other=[] % list() - Key/Value list with other headers
}).
+-type http_request_h() :: #http_request_h{}.
-endif. % -ifdef(http_internal_hrl).
diff --git a/lib/inets/src/http_lib/http_request.erl b/lib/inets/src/http_lib/http_request.erl
index c77b616f0d..f68b233e10 100644
--- a/lib/inets/src/http_lib/http_request.erl
+++ b/lib/inets/src/http_lib/http_request.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@
-include("http_internal.hrl").
--export([headers/2, http_headers/1, is_absolut_uri/1, key_value/1]).
+-export([headers/2, http_headers/1, is_absolut_uri/1, key_value/1, normalize_host/3]).
key_value(KeyValueStr) ->
@@ -85,6 +85,22 @@ is_absolut_uri("https://" ++ _) ->
is_absolut_uri(_) ->
false.
+%%-------------------------------------------------------------------------
+%% normalize_host(Scheme, Host, Port) -> string()
+%% Scheme - http | https
+%% Host - string()
+%% Port - integer()
+%%
+%% Description: returns a normalized Host header value, with the port
+%% number omitted for well-known ports
+%%-------------------------------------------------------------------------
+normalize_host(https, Host, 443 = _Port) ->
+ Host;
+normalize_host(http, Host, 80 = _Port) ->
+ Host;
+normalize_host(_Scheme, Host, Port) ->
+ Host ++ ":" ++ integer_to_list(Port).
+
%%%========================================================================
%%% Internal functions
%%%========================================================================
diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl
index cb3e107ccf..c4be5abd7c 100644
--- a/lib/inets/src/http_lib/http_uri.erl
+++ b/lib/inets/src/http_lib/http_uri.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -102,16 +102,23 @@ parse(AbsURI, Opts) ->
reserved() ->
sets:from_list([$;, $:, $@, $&, $=, $+, $,, $/, $?,
- $#, $[, $], $<, $>, $\", ${, $}, $|,
+ $#, $[, $], $<, $>, $\", ${, $}, $|, %"
$\\, $', $^, $%, $ ]).
-encode(URI) ->
+encode(URI) when is_list(URI) ->
Reserved = reserved(),
- lists:append([uri_encode(Char, Reserved) || Char <- URI]).
+ lists:append([uri_encode(Char, Reserved) || Char <- URI]);
+encode(URI) when is_binary(URI) ->
+ Reserved = reserved(),
+ << <<(uri_encode_binary(Char, Reserved))/binary>> || <<Char>> <= URI >>.
-decode(String) ->
- do_decode(String).
+decode(String) when is_list(String) ->
+ do_decode(String);
+decode(String) when is_binary(String) ->
+ do_decode_binary(String).
+do_decode([$+|Rest]) ->
+ [$ |do_decode(Rest)];
do_decode([$%,Hex1,Hex2|Rest]) ->
[hex2dec(Hex1)*16+hex2dec(Hex2)|do_decode(Rest)];
do_decode([First|Rest]) ->
@@ -119,6 +126,14 @@ do_decode([First|Rest]) ->
do_decode([]) ->
[].
+do_decode_binary(<<$+, Rest/bits>>) ->
+ <<$ , (do_decode_binary(Rest))/binary>>;
+do_decode_binary(<<$%, Hex:2/binary, Rest/bits>>) ->
+ <<(binary_to_integer(Hex, 16)), (do_decode_binary(Rest))/binary>>;
+do_decode_binary(<<First:1/binary, Rest/bits>>) ->
+ <<First/binary, (do_decode_binary(Rest))/binary>>;
+do_decode_binary(<<>>) ->
+ <<>>.
%%%========================================================================
%%% Internal functions
@@ -162,9 +177,30 @@ extract_scheme(Str, Opts) ->
{error, Error}
end;
_ ->
- {ok, list_to_atom(http_util:to_lower(Str))}
+ {ok, to_atom(http_util:to_lower(Str))}
end.
+to_atom(S) when is_list(S) ->
+ list_to_atom(S);
+to_atom(S) when is_binary(S) ->
+ binary_to_atom(S, unicode).
+
+parse_uri_rest(Scheme, DefaultPort, <<"//", URIPart/binary>>, Opts) ->
+ {Authority, PathQueryFragment} =
+ split_uri(URIPart, "[/?#]", {URIPart, <<"">>}, 1, 0),
+ {RawPath, QueryFragment} =
+ split_uri(PathQueryFragment, "[?#]", {PathQueryFragment, <<"">>}, 1, 0),
+ {Query, Fragment} =
+ split_uri(QueryFragment, "#", {QueryFragment, <<"">>}, 1, 0),
+ {UserInfo, HostPort} = split_uri(Authority, "@", {<<"">>, Authority}, 1, 1),
+ {Host, Port} = parse_host_port(Scheme, DefaultPort, HostPort, Opts),
+ Path = path(RawPath),
+ case lists:keyfind(fragment, 1, Opts) of
+ {fragment, true} ->
+ {ok, {Scheme, UserInfo, Host, Port, Path, Query, Fragment}};
+ _ ->
+ {ok, {Scheme, UserInfo, Host, Port, Path, Query}}
+ end;
parse_uri_rest(Scheme, DefaultPort, "//" ++ URIPart, Opts) ->
{Authority, PathQueryFragment} =
split_uri(URIPart, "[/?#]", {URIPart, ""}, 1, 0),
@@ -185,6 +221,11 @@ parse_uri_rest(Scheme, DefaultPort, "//" ++ URIPart, Opts) ->
%% In this version of the function, we no longer need
%% the Scheme argument, but just in case...
+parse_host_port(_Scheme, DefaultPort, <<"[", HostPort/binary>>, Opts) -> %ipv6
+ {Host, ColonPort} = split_uri(HostPort, "\\]", {HostPort, <<"">>}, 1, 1),
+ Host2 = maybe_ipv6_host_with_brackets(Host, Opts),
+ {_, Port} = split_uri(ColonPort, ":", {<<"">>, DefaultPort}, 0, 1),
+ {Host2, int_port(Port)};
parse_host_port(_Scheme, DefaultPort, "[" ++ HostPort, Opts) -> %ipv6
{Host, ColonPort} = split_uri(HostPort, "\\]", {HostPort, ""}, 1, 1),
Host2 = maybe_ipv6_host_with_brackets(Host, Opts),
@@ -198,12 +239,19 @@ parse_host_port(_Scheme, DefaultPort, HostPort, _Opts) ->
split_uri(UriPart, SplitChar, NoMatchResult, SkipLeft, SkipRight) ->
case re:run(UriPart, SplitChar, [{capture, first}]) of
{match, [{Match, _}]} ->
- {string:substr(UriPart, 1, Match + 1 - SkipLeft),
- string:substr(UriPart, Match + 1 + SkipRight, length(UriPart))};
+ {string:slice(UriPart, 0, Match + 1 - SkipLeft),
+ string:slice(UriPart, Match + SkipRight, string:length(UriPart))};
nomatch ->
NoMatchResult
end.
+maybe_ipv6_host_with_brackets(Host, Opts) when is_binary(Host) ->
+ case lists:keysearch(ipv6_host_with_brackets, 1, Opts) of
+ {value, {ipv6_host_with_brackets, true}} ->
+ <<"[", Host/binary, "]">>;
+ _ ->
+ Host
+ end;
maybe_ipv6_host_with_brackets(Host, Opts) ->
case lists:keysearch(ipv6_host_with_brackets, 1, Opts) of
{value, {ipv6_host_with_brackets, true}} ->
@@ -212,15 +260,18 @@ maybe_ipv6_host_with_brackets(Host, Opts) ->
Host
end.
-
int_port(Port) when is_integer(Port) ->
Port;
+int_port(Port) when is_binary(Port) ->
+ binary_to_integer(Port);
int_port(Port) when is_list(Port) ->
list_to_integer(Port);
%% This is the case where no port was found and there was no default port
int_port(no_default_port) ->
throw({error, no_default_port}).
+path(<<"">>) ->
+ <<"/">>;
path("") ->
"/";
path(Path) ->
@@ -234,6 +285,14 @@ uri_encode(Char, Reserved) ->
[Char]
end.
+uri_encode_binary(Char, Reserved) ->
+ case sets:is_element(Char, Reserved) of
+ true ->
+ << $%, (integer_to_binary(Char, 16))/binary >>;
+ false ->
+ <<Char>>
+ end.
+
hex2dec(X) when (X>=$0) andalso (X=<$9) -> X-$0;
hex2dec(X) when (X>=$A) andalso (X=<$F) -> X-$A+10;
hex2dec(X) when (X>=$a) andalso (X=<$f) -> X-$a+10.
diff --git a/lib/inets/src/http_lib/http_util.erl b/lib/inets/src/http_lib/http_util.erl
index 20c342dd66..487d04f7aa 100644
--- a/lib/inets/src/http_lib/http_util.erl
+++ b/lib/inets/src/http_lib/http_util.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -35,10 +35,10 @@
%%% Internal application API
%%%=========================================================================
to_upper(Str) ->
- string:to_upper(Str).
+ string:uppercase(Str).
to_lower(Str) ->
- string:to_lower(Str).
+ string:lowercase(Str).
%% Example: Mon, 09-Dec-2002 13:46:00 GMT
convert_netscapecookie_date([_D,_A,_Y, $,, $ ,
diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl
index e5182ca23c..9e54f2b2c5 100644
--- a/lib/inets/src/http_server/httpd_conf.erl
+++ b/lib/inets/src/http_server/httpd_conf.erl
@@ -395,7 +395,8 @@ validate_properties(Properties) ->
%% That is, if property A depends on property B.
%% The only sunch preperty at this time is bind_address that depends
%% on ipfamily.
-validate_properties2(Properties) ->
+validate_properties2(Properties0) ->
+ Properties = fix_ipfamily(Properties0),
case proplists:get_value(bind_address, Properties) of
undefined ->
case proplists:get_value(sock_type, Properties, ip_comm) of
@@ -422,6 +423,15 @@ validate_properties2(Properties) ->
end
end.
+fix_ipfamily(Properties) ->
+ case proplists:get_value(ipfamily, Properties) of
+ undefined ->
+ Properties;
+ IpFamily ->
+ NewProps = proplists:delete(ipfamily, Properties),
+ [{ipfamily, validate_ipfamily(IpFamily)} | NewProps]
+ end.
+
add_inet_defaults(Properties) ->
case proplists:get_value(ipfamily, Properties) of
undefined ->
diff --git a/lib/inets/src/http_server/httpd_example.erl b/lib/inets/src/http_server/httpd_example.erl
index 424d269859..c893b10dca 100644
--- a/lib/inets/src/http_server/httpd_example.erl
+++ b/lib/inets/src/http_server/httpd_example.erl
@@ -20,7 +20,7 @@
%%
-module(httpd_example).
-export([print/1]).
--export([get/2, post/2, yahoo/2, test1/2, get_bin/2, peer/2]).
+-export([get/2, put/2, post/2, yahoo/2, test1/2, get_bin/2, peer/2]).
-export([newformat/3]).
%% These are used by the inets test-suite
@@ -59,6 +59,11 @@ get(_Env,[]) ->
get(Env,Input) ->
default(Env,Input).
+put(Env,{Input,_Body}) ->
+ default(Env,Input);
+put(Env,Input) ->
+ default(Env,Input).
+
get_bin(_Env,_Input) ->
[list_to_binary(header()),
list_to_binary(top("GET Example")),
@@ -94,7 +99,7 @@ default(Env,Input) ->
io_lib:format("~p",[httpd:parse_query(Input)]),"\n",
footer()].
-peer(Env, Input) ->
+peer(Env, _Input) ->
Header =
case proplists:get_value(peer_cert, Env) of
undefined ->
@@ -161,7 +166,7 @@ sleep(T) -> receive after T -> ok end.
%% ------------------------------------------------------
-chunk_timeout(SessionID, _, StrInt) ->
+chunk_timeout(SessionID, _, _StrInt) ->
mod_esi:deliver(SessionID, "Tranfer-Encoding:chunked/html\r\n\r\n"),
mod_esi:deliver(SessionID, top("Test chunk encoding timeout")),
timer:sleep(20000),
diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl
index 071fa94ef6..538d52b98d 100644
--- a/lib/inets/src/http_server/httpd_request_handler.erl
+++ b/lib/inets/src/http_server/httpd_request_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -37,18 +37,19 @@
-include("httpd_internal.hrl").
-define(HANDSHAKE_TIMEOUT, 5000).
+
-record(state, {mod, %% #mod{}
manager, %% pid()
status, %% accept | busy | blocked
mfa, %% {Module, Function, Args}
max_keep_alive_request = infinity, %% integer() | infinity
- response_sent = false, %% true | false
- timeout, %% infinity | integer() > 0
- timer, %% ref() - Request timer
- headers, %% #http_request_h{}
+ response_sent = false :: boolean(),
+ timeout, %% infinity | integer() > 0
+ timer :: 'undefined' | reference(), % Request timer
+ headers, %% #http_request_h{}
body, %% binary()
data, %% The total data received in bits, checked after 10s
- byte_limit %% Bit limit per second before kick out
+ byte_limit %% Bit limit per second before kick out
}).
%%====================================================================
@@ -240,9 +241,9 @@ handle_info({tcp_closed, _}, State) ->
handle_info({ssl_closed, _}, State) ->
{stop, normal, State};
handle_info({tcp_error, _, _} = Reason, State) ->
- {stop, Reason, State};
+ {stop, {shutdown, Reason}, State};
handle_info({ssl_error, _, _} = Reason, State) ->
- {stop, Reason, State};
+ {stop, {shutdown, Reason}, State};
%% Timeouts
handle_info(timeout, #state{mfa = {_, parse, _}} = State) ->
diff --git a/lib/inets/src/http_server/httpd_response.erl b/lib/inets/src/http_server/httpd_response.erl
index 1374b7e85e..effa273e92 100644
--- a/lib/inets/src/http_server/httpd_response.erl
+++ b/lib/inets/src/http_server/httpd_response.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/inets/src/http_server/httpd_util.erl b/lib/inets/src/http_server/httpd_util.erl
index a647f04ddc..4a2eff4770 100644
--- a/lib/inets/src/http_server/httpd_util.erl
+++ b/lib/inets/src/http_server/httpd_util.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -333,7 +333,9 @@ rfc1123_date(LocalTime) ->
{{YYYY,MM,DD},{Hour,Min,Sec}} =
case calendar:local_time_to_universal_time_dst(LocalTime) of
[Gmt] -> Gmt;
- [_,Gmt] -> Gmt
+ [_,Gmt] -> Gmt;
+ % Should not happen, but handle the empty list to prevent an error.
+ [] -> LocalTime
end,
DayNumber = calendar:day_of_the_week({YYYY,MM,DD}),
lists:flatten(
diff --git a/lib/inets/src/http_server/mod_auth_server.erl b/lib/inets/src/http_server/mod_auth_server.erl
index 93d8145821..90d9ee34b1 100644
--- a/lib/inets/src/http_server/mod_auth_server.erl
+++ b/lib/inets/src/http_server/mod_auth_server.erl
@@ -128,7 +128,7 @@ list_group_members(Addr, Port, Dir, Group, Password) ->
list_group_members(Addr, Port, ?DEFAULT_PROFILE, Dir, Group, Password).
list_group_members(Addr, Port, Profile, Dir, Group, Password) ->
Name = make_name(Addr, Port, Profile),
- Req = {list_group_members, Addr, Port, Dir, Group, Password},
+ Req = {list_group_members, Addr, Port, Profile, Dir, Group, Password},
call(Name, Req).
delete_group(Addr, Port, Dir, GroupName, Password) ->
diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl
index 2800250727..b21af1418c 100644
--- a/lib/inets/src/http_server/mod_esi.erl
+++ b/lib/inets/src/http_server/mod_esi.erl
@@ -241,7 +241,7 @@ alias_match_str(Alias, eval_script_alias) ->
%%------------------------ Erl mechanism --------------------------------
erl(#mod{method = Method} = ModData, ESIBody, Modules)
- when (Method =:= "GET") orelse (Method =:= "HEAD") ->
+ when (Method =:= "GET") orelse (Method =:= "HEAD") orelse (Method =:= "DELETE") ->
?hdrt("erl", [{method, Method}]),
case httpd_util:split(ESIBody,":|%3A|/",2) of
{ok, [ModuleName, FuncAndInput]} ->
@@ -264,35 +264,32 @@ erl(#mod{method = Method} = ModData, ESIBody, Modules)
{proceed, [{status,{400, none, BadRequest}} | ModData#mod.data]}
end;
-erl(#mod{request_uri = ReqUri,
- method = "PUT",
- http_version = Version,
- data = Data}, _ESIBody, _Modules) ->
- ?hdrt("erl", [{method, put}]),
- {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) ->
- ?hdrt("erl", [{method, delete}]),
- {proceed,[{status,{501,{"DELETE", ReqUri, Version},
- ?NICE("Erl mechanism doesn't support method DELETE")}}|
- Data]};
-
-erl(#mod{request_uri = ReqUri,
- method = "PATCH",
- http_version = Version,
- data = Data}, _ESIBody, _Modules) ->
- ?hdrt("erl", [{method, patch}]),
- {proceed, [{status,{501,{"PATCH", ReqUri, Version},
- ?NICE("Erl mechanism doesn't support method PATCH")}}|
- Data]};
+erl(#mod{method = "PUT", entity_body = Body} = ModData,
+ ESIBody, Modules) ->
+ case httpd_util:split(ESIBody,":|%3A|/",2) of
+ {ok, [ModuleName, FuncAndInput]} ->
+ case httpd_util:split(FuncAndInput,"[\?/]",2) of
+ {ok, [FunctionName, Input]} ->
+ generate_webpage(ModData, ESIBody, Modules,
+ list_to_atom(ModuleName),
+ FunctionName, {Input,Body},
+ [{entity_body, Body} |
+ script_elements(FuncAndInput, Input)]);
+ {ok, [FunctionName]} ->
+ generate_webpage(ModData, ESIBody, Modules,
+ list_to_atom(ModuleName),
+ FunctionName, {undefined,Body},
+ [{entity_body, Body} |
+ script_elements(FuncAndInput, "")]);
+ {ok, BadRequest} ->
+ {proceed,[{status,{400,none, BadRequest}} |
+ ModData#mod.data]}
+ end;
+ {ok, BadRequest} ->
+ {proceed, [{status,{400, none, BadRequest}} | ModData#mod.data]}
+ end;
-erl(#mod{method = "POST",
- entity_body = Body} = ModData, ESIBody, Modules) ->
+erl(#mod{method = "POST", entity_body = Body} = ModData, ESIBody, Modules) ->
?hdrt("erl", [{method, post}]),
case httpd_util:split(ESIBody,":|%3A|/",2) of
{ok,[ModuleName, Function]} ->
@@ -301,7 +298,16 @@ erl(#mod{method = "POST",
Function, Body, [{entity_body, Body}]);
{ok, BadRequest} ->
{proceed,[{status, {400, none, BadRequest}} | ModData#mod.data]}
- end.
+ end;
+
+erl(#mod{request_uri = ReqUri,
+ method = "PATCH",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ ?hdrt("erl", [{method, patch}]),
+ {proceed, [{status,{501,{"PATCH", ReqUri, Version},
+ ?NICE("Erl mechanism doesn't support method PATCH")}}|
+ Data]}.
generate_webpage(ModData, ESIBody, [all], Module, FunctionName,
Input, ScriptElements) ->
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index 3a31daeb20..f9ad8709d9 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -1,7 +1,7 @@
%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,10 +18,14 @@
%% %CopyrightEnd%
{"%VSN%",
[
+ {<<"6.2.4">>, [{load_module, httpd_request_handler,
+ soft_purge, soft_purge, []}]},
{<<"6\\..*">>,[{restart_application, inets}]},
{<<"5\\..*">>,[{restart_application, inets}]}
],
[
+ {<<"6.2.4">>, [{load_module, httpd_request_handler,
+ soft_purge, soft_purge, []}]},
{<<"6\\..*">>,[{restart_application, inets}]},
{<<"5\\..*">>,[{restart_application, inets}]}
]
diff --git a/lib/inets/src/inets_app/inets_lib.erl b/lib/inets/src/inets_app/inets_lib.erl
index 8993be29e4..3fae376a9f 100644
--- a/lib/inets/src/inets_app/inets_lib.erl
+++ b/lib/inets/src/inets_app/inets_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl
index e2dec0c42a..3dfec01ba2 100644
--- a/lib/inets/test/ftp_SUITE.erl
+++ b/lib/inets/test/ftp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -93,8 +93,11 @@ ftp_tests()->
append_chunk,
recv,
recv_3,
- recv_bin,
+ recv_bin,
+ recv_bin_twice,
recv_chunk,
+ recv_chunk_twice,
+ recv_chunk_three_times,
type,
quote,
error_elogin,
@@ -191,9 +194,22 @@ end_per_suite(Config) ->
ok.
%%--------------------------------------------------------------------
-init_per_group(_Group, Config) -> Config.
-
-end_per_group(_Group, Config) -> Config.
+init_per_group(Group, Config) when Group == ftps_active,
+ Group == ftps_passive ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ Config
+ catch
+ _:_ ->
+ {skip, "Crypto did not start"}
+ end;
+
+init_per_group(_Group, Config) ->
+ Config.
+
+end_per_group(_Group, Config) ->
+ Config.
%%--------------------------------------------------------------------
init_per_testcase(Case, Config0) ->
@@ -533,15 +549,19 @@ append_chunk(Config0) ->
recv() ->
[{doc, "Receive a file using recv/2"}].
recv(Config0) ->
- File = "f_dst.txt",
+ File1 = "f_dst1.txt",
+ File2 = "f_dst2.txt",
SrcDir = "a_dir",
- Contents = <<"ftp_SUITE test ...">>,
- Config = set_state([reset, {mkfile,[SrcDir,File],Contents}], Config0),
+ Contents1 = <<"1 ftp_SUITE test ...">>,
+ Contents2 = <<"2 ftp_SUITE test ...">>,
+ Config = set_state([reset, {mkfile,[SrcDir,File1],Contents1}, {mkfile,[SrcDir,File2],Contents2}], Config0),
Pid = proplists:get_value(ftp, Config),
ok = ftp:cd(Pid, id2ftp(SrcDir,Config)),
ok = ftp:lcd(Pid, id2ftp("",Config)),
- ok = ftp:recv(Pid, File),
- chk_file(File, Contents, Config),
+ ok = ftp:recv(Pid, File1),
+ chk_file(File1, Contents1, Config),
+ ok = ftp:recv(Pid, File2),
+ chk_file(File2, Contents2, Config),
{error,epath} = ftp:recv(Pid, "non_existing_file"),
ok.
@@ -572,6 +592,25 @@ recv_bin(Config0) ->
ok.
%%-------------------------------------------------------------------------
+recv_bin_twice() ->
+ [{doc, "Receive two files as a binaries."}].
+recv_bin_twice(Config0) ->
+ File1 = "f_dst1.txt",
+ File2 = "f_dst2.txt",
+ Contents1 = <<"1 ftp_SUITE test ...">>,
+ Contents2 = <<"2 ftp_SUITE test ...">>,
+ Config = set_state([reset, {mkfile,File1,Contents1}, {mkfile,File2,Contents2}], Config0),
+ ct:log("First transfer",[]),
+ Pid = proplists:get_value(ftp, Config),
+ {ok,Received1} = ftp:recv_bin(Pid, id2ftp(File1,Config)),
+ find_diff(Received1, Contents1),
+ ct:log("Second transfer",[]),
+ {ok,Received2} = ftp:recv_bin(Pid, id2ftp(File2,Config)),
+ find_diff(Received2, Contents2),
+ ct:log("Transfers ready!",[]),
+ {error,epath} = ftp:recv_bin(Pid, id2ftp("non_existing_file",Config)),
+ ok.
+%%-------------------------------------------------------------------------
recv_chunk() ->
[{doc, "Receive a file using chunk-wise."}].
recv_chunk(Config0) ->
@@ -584,13 +623,74 @@ recv_chunk(Config0) ->
{ok, ReceivedContents, _Ncunks} = recv_chunk(Pid, <<>>),
find_diff(ReceivedContents, Contents).
+recv_chunk_twice() ->
+ [{doc, "Receive two files using chunk-wise."}].
+recv_chunk_twice(Config0) ->
+ File1 = "big_file1.txt",
+ File2 = "big_file2.txt",
+ Contents1 = list_to_binary( lists:duplicate(1000, lists:seq(0,255)) ),
+ Contents2 = crypto:strong_rand_bytes(1200),
+ Config = set_state([reset, {mkfile,File1,Contents1}, {mkfile,File2,Contents2}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ {{error, "ftp:recv_chunk_start/2 not called"},_} = recv_chunk(Pid, <<>>),
+ ok = ftp:recv_chunk_start(Pid, id2ftp(File1,Config)),
+ {ok, ReceivedContents1, _Ncunks1} = recv_chunk(Pid, <<>>),
+ ok = ftp:recv_chunk_start(Pid, id2ftp(File2,Config)),
+ {ok, ReceivedContents2, _Ncunks2} = recv_chunk(Pid, <<>>),
+ find_diff(ReceivedContents1, Contents1),
+ find_diff(ReceivedContents2, Contents2).
+
+recv_chunk_three_times() ->
+ [{doc, "Receive two files using chunk-wise."},
+ {timetrap,{seconds,120}}].
+recv_chunk_three_times(Config0) ->
+ File1 = "big_file1.txt",
+ File2 = "big_file2.txt",
+ File3 = "big_file3.txt",
+ Contents1 = list_to_binary( lists:duplicate(1000, lists:seq(0,255)) ),
+ Contents2 = crypto:strong_rand_bytes(1200),
+ Contents3 = list_to_binary( lists:duplicate(1000, lists:seq(255,0,-1)) ),
+
+ Config = set_state([reset, {mkfile,File1,Contents1}, {mkfile,File2,Contents2}, {mkfile,File3,Contents3}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ {{error, "ftp:recv_chunk_start/2 not called"},_} = recv_chunk(Pid, <<>>),
+
+ ok = ftp:recv_chunk_start(Pid, id2ftp(File1,Config)),
+ {ok, ReceivedContents1, Nchunks1} = recv_chunk(Pid, <<>>),
+
+ ok = ftp:recv_chunk_start(Pid, id2ftp(File2,Config)),
+ {ok, ReceivedContents2, _Nchunks2} = recv_chunk(Pid, <<>>),
+
+ ok = ftp:recv_chunk_start(Pid, id2ftp(File3,Config)),
+ {ok, ReceivedContents3, _Nchunks3} = recv_chunk(Pid, <<>>, 10000, 0, Nchunks1),
+
+ find_diff(ReceivedContents1, Contents1),
+ find_diff(ReceivedContents2, Contents2),
+ find_diff(ReceivedContents3, Contents3).
+
+
+
recv_chunk(Pid, Acc) ->
- recv_chunk(Pid, Acc, 0).
+ recv_chunk(Pid, Acc, 0, 0, undefined).
+
+
+
+%% ExpectNchunks :: integer() | undefined
+recv_chunk(Pid, Acc, DelayMilliSec, N, ExpectNchunks) when N+1 < ExpectNchunks ->
+ %% for all I in integer(), I < undefined
+ recv_chunk1(Pid, Acc, DelayMilliSec, N, ExpectNchunks);
+
+recv_chunk(Pid, Acc, DelayMilliSec, N, ExpectNchunks) ->
+ %% N >= ExpectNchunks-1
+ timer:sleep(DelayMilliSec),
+ recv_chunk1(Pid, Acc, DelayMilliSec, N, ExpectNchunks).
+
-recv_chunk(Pid, Acc, N) ->
+recv_chunk1(Pid, Acc, DelayMilliSec, N, ExpectNchunks) ->
+ ct:log("Call ftp:recv_chunk",[]),
case ftp:recv_chunk(Pid) of
ok -> {ok, Acc, N};
- {ok, Bin} -> recv_chunk(Pid, <<Acc/binary, Bin/binary>>, N+1);
+ {ok, Bin} -> recv_chunk(Pid, <<Acc/binary, Bin/binary>>, DelayMilliSec, N+1, ExpectNchunks);
Error -> {Error, N}
end.
diff --git a/lib/inets/test/ftp_format_SUITE.erl b/lib/inets/test/ftp_format_SUITE.erl
index a33b31f46f..95d594a44b 100644
--- a/lib/inets/test/ftp_format_SUITE.erl
+++ b/lib/inets/test/ftp_format_SUITE.erl
@@ -38,8 +38,8 @@ all() ->
groups() ->
[{ftp_response, [],
[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_425, ftp_other_status_codes, ftp_multiple_lines_status_in_msg,
+ ftp_multiple_lines, ftp_multipel_ctrl_messages]}].
init_per_suite(Config) ->
Config.
@@ -141,6 +141,15 @@ ftp_425(Config) when is_list(Config) ->
{trans_neg_compl, _} = ftp_response:interpret(Msg),
ok.
+ftp_multiple_lines_status_in_msg() ->
+ [{doc, "check that multiple lines gets parsed correct, even if we have "
+ " the status code within the msg being sent"}].
+ftp_multiple_lines_status_in_msg(Config) when is_list(Config) ->
+ ML = "230-User usr-230 is logged in\r\n" ++
+ "230 OK. Current directory is /\r\n",
+ {ok, ML, <<>>} = ftp_response:parse_lines(list_to_binary(ML), [], start),
+ ok.
+
ftp_multiple_lines() ->
[{doc, "Especially check multiple lines devided in significant places"}].
ftp_multiple_lines(Config) when is_list(Config) ->
diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl
index a2b463e98c..4e10a97f58 100644
--- a/lib/inets/test/http_format_SUITE.erl
+++ b/lib/inets/test/http_format_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 932567ec55..e6dcd2285f 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -88,7 +88,8 @@ real_requests()->
stream_through_mfa,
streaming_error,
inet_opts,
- invalid_headers
+ invalid_headers,
+ invalid_body
].
only_simulated() ->
@@ -107,6 +108,7 @@ only_simulated() ->
tolerate_missing_CR,
userinfo,
bad_response,
+ timeout_redirect,
internal_server_error,
invalid_http,
invalid_chunk_size,
@@ -125,7 +127,9 @@ only_simulated() ->
redirect_see_other,
redirect_temporary_redirect,
port_in_host_header,
- relaxed
+ redirect_port_in_host_header,
+ relaxed,
+ multipart_chunks
].
misc() ->
@@ -160,21 +164,17 @@ init_per_group(misc = Group, Config) ->
ok = httpc:set_options([{ipfamily, Inet}]),
Config;
+
init_per_group(Group, Config0) when Group =:= sim_https; Group =:= https->
- ct:timetrap({seconds, 30}),
- start_apps(Group),
- StartSsl = try ssl:start()
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ct:timetrap({seconds, 30}),
+ start_apps(Group),
+ do_init_per_group(Group, Config0)
catch
- Error:Reason ->
- {skip, lists:flatten(io_lib:format("Failed to start apps for https Error=~p Reason=~p", [Error, Reason]))}
- end,
- case StartSsl of
- {error, {already_started, _}} ->
- do_init_per_group(Group, Config0);
- ok ->
- do_init_per_group(Group, Config0);
- _ ->
- StartSsl
+ _:_ ->
+ {skip, "Crypto did not start"}
end;
init_per_group(Group, Config0) ->
@@ -500,10 +500,11 @@ redirect_multiple_choises(Config) when is_list(Config) ->
httpc:request(get, {URL300, []}, [{autoredirect, false}], []).
%%-------------------------------------------------------------------------
redirect_moved_permanently() ->
- [{doc, "If the 301 status code is received in response to a request other "
- "than GET or HEAD, the user agent MUST NOT automatically redirect the request "
- "unless it can be confirmed by the user, since this might change "
- "the conditions under which the request was issued."}].
+ [{doc, "The server SHOULD generate a Location header field in the response "
+ "containing a preferred URI reference for the new permanent URI. The user "
+ "agent MAY use the Location field value for automatic redirection. The server's "
+ "response payload usually contains a short hypertext note with a "
+ "hyperlink to the new URI(s)."}].
redirect_moved_permanently(Config) when is_list(Config) ->
URL301 = url(group_name(Config), "/301.html", Config),
@@ -514,15 +515,16 @@ redirect_moved_permanently(Config) when is_list(Config) ->
{ok, {{_,200,_}, [_ | _], []}}
= httpc:request(head, {URL301, []}, [], []),
- {ok, {{_,301,_}, [_ | _], [_|_]}}
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
= httpc:request(post, {URL301, [],"text/plain", "foobar"},
[], []).
%%-------------------------------------------------------------------------
redirect_found() ->
- [{doc," If the 302 status code is received in response to a request other "
- "than GET or HEAD, the user agent MUST NOT automatically redirect the "
- "request unless it can be confirmed by the user, since this might change "
- "the conditions under which the request was issued."}].
+ [{doc, "The server SHOULD generate a Location header field in the response "
+ "containing a URI reference for the different URI. The user agent MAY "
+ "use the Location field value for automatic redirection. The server's "
+ "response payload usually contains a short hypertext note with a "
+ "hyperlink to the different URI(s)."}].
redirect_found(Config) when is_list(Config) ->
URL302 = url(group_name(Config), "/302.html", Config),
@@ -533,14 +535,14 @@ redirect_found(Config) when is_list(Config) ->
{ok, {{_,200,_}, [_ | _], []}}
= httpc:request(head, {URL302, []}, [], []),
- {ok, {{_,302,_}, [_ | _], [_|_]}}
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
= httpc:request(post, {URL302, [],"text/plain", "foobar"},
[], []).
%%-------------------------------------------------------------------------
redirect_see_other() ->
[{doc, "The different URI SHOULD be given by the Location field in the response. "
"Unless the request method was HEAD, the entity of the response SHOULD contain a short "
- "hypertext note with a hyperlink to the new URI(s). "}].
+ "hypertext note with a hyperlink to the new URI(s)."}].
redirect_see_other(Config) when is_list(Config) ->
URL303 = url(group_name(Config), "/303.html", Config),
@@ -556,10 +558,11 @@ redirect_see_other(Config) when is_list(Config) ->
[], []).
%%-------------------------------------------------------------------------
redirect_temporary_redirect() ->
- [{doc," If the 307 status code is received in response to a request other "
- "than GET or HEAD, the user agent MUST NOT automatically redirect the request "
- "unless it can be confirmed by the user, since this might change "
- "the conditions under which the request was issued."}].
+ [{doc, "The server SHOULD generate a Location header field in the response "
+ "containing a URI reference for the different URI. The user agent MAY "
+ "use the Location field value for automatic redirection. The server's "
+ "response payload usually contains a short hypertext note with a "
+ "hyperlink to the different URI(s)."}].
redirect_temporary_redirect(Config) when is_list(Config) ->
URL307 = url(group_name(Config), "/307.html", Config),
@@ -570,7 +573,7 @@ redirect_temporary_redirect(Config) when is_list(Config) ->
{ok, {{_,200,_}, [_ | _], []}}
= httpc:request(head, {URL307, []}, [], []),
- {ok, {{_,307,_}, [_ | _], [_|_]}}
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
= httpc:request(post, {URL307, [],"text/plain", "foobar"},
[], []).
@@ -783,6 +786,14 @@ bad_response(Config) when is_list(Config) ->
ct:print("Wrong Statusline: ~p~n", [Reason]).
%%-------------------------------------------------------------------------
+timeout_redirect() ->
+ [{doc, "Test that timeout works for redirects, check ERL-420."}].
+timeout_redirect(Config) when is_list(Config) ->
+ URL = url(group_name(Config), "/redirect_to_missing_crlf.html", Config),
+ {error, timeout} = httpc:request(get, {URL, []}, [{timeout, 400}], []).
+
+%%-------------------------------------------------------------------------
+
internal_server_error(doc) ->
["Test 50X codes"];
internal_server_error(Config) when is_list(Config) ->
@@ -997,10 +1008,25 @@ invalid_headers(Config) ->
Request = {url(group_name(Config), "/dummy.html", Config), [{"cookie", undefined}]},
{error, _} = httpc:request(get, Request, [], []).
+%%-------------------------------------------------------------------------
+
+invalid_body(Config) ->
+ URL = url(group_name(Config), "/dummy.html", Config),
+ try
+ httpc:request(post, {URL, [], <<"text/plain">>, "foobar"},
+ [], []),
+ ct:fail(accepted_invalid_input)
+ catch
+ error:function_clause ->
+ ok
+ end.
+
+%%-------------------------------------------------------------------------
remote_socket_close(Config) when is_list(Config) ->
URL = url(group_name(Config), "/just_close.html", Config),
{error, socket_closed_remotely} = httpc:request(URL).
+
%%-------------------------------------------------------------------------
remote_socket_close_async(Config) when is_list(Config) ->
@@ -1099,8 +1125,21 @@ port_in_host_header(Config) when is_list(Config) ->
Request = {url(group_name(Config), "/ensure_host_header_with_port.html", Config), []},
{ok, {{_, 200, _}, _, Body}} = httpc:request(get, Request, [], []),
inets_test_lib:check_body(Body).
+%%-------------------------------------------------------------------------
+redirect_port_in_host_header(Config) when is_list(Config) ->
+
+ Request = {url(group_name(Config), "/redirect_ensure_host_header_with_port.html", Config), []},
+ {ok, {{_, 200, _}, _, Body}} = httpc:request(get, Request, [], []),
+ inets_test_lib:check_body(Body).
%%-------------------------------------------------------------------------
+multipart_chunks(Config) when is_list(Config) ->
+ Request = {url(group_name(Config), "/multipart_chunks.html", Config), []},
+ {ok, Ref} = httpc:request(get, Request, [], [{sync, false}, {stream, self}]),
+ ok = receive_stream_n(Ref, 10),
+ httpc:cancel_request(Ref).
+
+%%-------------------------------------------------------------------------
timeout_memory_leak() ->
[{doc, "Check OTP-8739"}].
timeout_memory_leak(Config) when is_list(Config) ->
@@ -1395,7 +1434,7 @@ dummy_server(Caller, SocketType, Inet, Extra) ->
end.
dummy_server_init(Caller, ip_comm, Inet, _) ->
- BaseOpts = [binary, {packet, 0}, {reuseaddr,true}, {active, false}],
+ BaseOpts = [binary, {packet, 0}, {reuseaddr,true}, {keepalive, true}, {active, false}],
{ok, ListenSocket} = gen_tcp:listen(0, [Inet | BaseOpts]),
{ok, Port} = inet:port(ListenSocket),
Caller ! {port, Port},
@@ -1677,6 +1716,12 @@ handle_uri(_,"/ensure_host_header_with_port.html",_,Headers,_,_) ->
"HTTP/1.1 500 Internal Server Error\r\n" ++
"Content-Length:" ++ Len ++ "\r\n\r\n" ++ B
end;
+handle_uri(_,"/redirect_ensure_host_header_with_port.html",Port,_,Socket,_) ->
+ NewUri = url_start(Socket) ++
+ integer_to_list(Port) ++ "/ensure_host_header_with_port.html",
+ "HTTP/1.1 302 Found \r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:0\r\n\r\n";
handle_uri(_,"/300.html",Port,_,Socket,_) ->
NewUri = url_start(Socket) ++
@@ -1879,6 +1924,16 @@ handle_uri(_,"/missing_crlf.html",_,_,_,_) ->
"Content-Length:32\r\n" ++
"<HTML><BODY>foobar</BODY></HTML>";
+handle_uri(_,"/redirect_to_missing_crlf.html",Port,_,Socket,_) ->
+ NewUri = url_start(Socket) ++
+ integer_to_list(Port) ++ "/missing_crlf.html",
+ Body = "<HTML><BODY><a href=" ++ NewUri ++
+ ">New place</a></BODY></HTML>",
+ "HTTP/1.1 303 See Other \r\n" ++
+ "Location:" ++ NewUri ++ "\r\n" ++
+ "Content-Length:" ++ integer_to_list(length(Body))
+ ++ "\r\n\r\n" ++ Body;
+
handle_uri(_,"/wrong_statusline.html",_,_,_,_) ->
"ok 200 HTTP/1.1\r\n\r\n" ++
"Content-Length:32\r\n\r\n" ++
@@ -1965,6 +2020,16 @@ handle_uri(_,"/missing_CR.html",_,_,_,_) ->
"Content-Length:32\r\n\n" ++
"<HTML><BODY>foobar</BODY></HTML>";
+handle_uri(_,"/multipart_chunks.html",_,_,Socket,_) ->
+ Head = "HTTP/1.1 200 ok\r\n" ++
+ "Transfer-Encoding:chunked\r\n" ++
+ "Date: " ++ httpd_util:rfc1123_date() ++ "\r\n"
+ "Connection: Keep-Alive\r\n" ++
+ "Content-Type: multipart/x-mixed-replace; boundary=chunk_boundary\r\n" ++
+ "\r\n",
+ send(Socket, Head),
+ send_multipart_chunks(Socket),
+ http_chunk:encode_last();
handle_uri("HEAD",_,_,_,_,_) ->
"HTTP/1.1 200 ok\r\n" ++
"Content-Length:0\r\n\r\n";
@@ -2261,3 +2326,21 @@ otp_8739_dummy_server_main(_Parent, ListenSocket) ->
Error ->
exit(Error)
end.
+
+send_multipart_chunks(Socket) ->
+ send(Socket, http_chunk:encode("--chunk_boundary\r\n")),
+ send(Socket, http_chunk:encode("Content-Type: text/plain\r\nContent-Length: 4\r\n\r\n")),
+ send(Socket, http_chunk:encode("test\r\n")),
+ ct:sleep(500),
+ send_multipart_chunks(Socket).
+
+receive_stream_n(_, 0) ->
+ ok;
+receive_stream_n(Ref, N) ->
+ receive
+ {http, {Ref, stream_start, _}} ->
+ receive_stream_n(Ref, N);
+ {http, {Ref,stream, Data}} ->
+ ct:pal("Data: ~p", [Data]),
+ receive_stream_n(Ref, N-1)
+ end.
diff --git a/lib/inets/test/httpd_1_1.erl b/lib/inets/test/httpd_1_1.erl
index 3755ed117b..ce9f7acc4d 100644
--- a/lib/inets/test/httpd_1_1.erl
+++ b/lib/inets/test/httpd_1_1.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -405,11 +405,11 @@ getRangeSize(Head)->
{multiPart, BoundaryString};
_X1 ->
case re:run(Head, ?CONTENT_RANGE "bytes=.*\r\n", [{capture, first}]) of
- {match, [{Start, Lenght}]} ->
+ {match, [{Start, Length}]} ->
%% Get the range data remove the fieldname and the
%% end of line.
RangeInfo = string:substr(Head, Start + 1 + 20,
- Lenght - (20 +2)),
+ Length - (20 +2)),
rangeSize(string:strip(RangeInfo));
_X2 ->
error
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index 3194b5ad3d..055b847319 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -119,8 +119,10 @@ groups() ->
]},
{htaccess, [], [htaccess_1_1, htaccess_1_0, htaccess_0_9]},
{security, [], [security_1_1, security_1_0]}, %% Skip 0.9 as causes timing issus in test code
- {http_1_1, [], [host, chunked, expect, cgi, cgi_chunked_encoding_test,
- trace, range, if_modified_since, mod_esi_chunk_timeout] ++ http_head() ++ http_get() ++ load()},
+ {http_1_1, [],
+ [host, chunked, expect, cgi, cgi_chunked_encoding_test,
+ trace, range, if_modified_since, mod_esi_chunk_timeout,
+ esi_put] ++ http_head() ++ http_get() ++ load()},
{http_1_0, [], [host, cgi, trace] ++ http_head() ++ http_get() ++ load()},
{http_0_9, [], http_head() ++ http_get() ++ load()}
].
@@ -195,7 +197,14 @@ init_per_group(Group, Config0) when Group == https_basic;
Group == https_security;
Group == https_reload
->
- init_ssl(Group, Config0);
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ init_ssl(Group, Config0)
+ catch
+ _:_ ->
+ {skip, "Crypto did not start"}
+ end;
init_per_group(Group, Config0) when Group == http_basic;
Group == http_limit;
Group == http_custom;
@@ -230,7 +239,14 @@ init_per_group(https_htaccess = Group, Config) ->
Path = proplists:get_value(doc_root, Config),
catch remove_htaccess(Path),
create_htaccess_data(Path, proplists:get_value(address, Config)),
- init_ssl(Group, Config);
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ init_ssl(Group, Config)
+ catch
+ _:_ ->
+ {skip, "Crypto did not start"}
+ end;
init_per_group(auth_api, Config) ->
[{auth_prefix, ""} | Config];
init_per_group(auth_api_dets, Config) ->
@@ -283,20 +299,50 @@ init_per_testcase(Case, Config) when Case == host; Case == trace ->
http_1_1 ->
httpd_1_1
end,
- [{version_cb, Cb} | proplists:delete(version_cb, Config)];
+ dbg(
+ Case,
+ [{version_cb, Cb} | proplists:delete(version_cb, Config)],
+ init);
init_per_testcase(range, Config) ->
ct:timetrap({seconds, 20}),
DocRoot = proplists:get_value(doc_root, Config),
create_range_data(DocRoot),
- Config;
+ dbg(range, Config, init);
-init_per_testcase(_, Config) ->
+init_per_testcase(Case, Config) ->
ct:timetrap({seconds, 20}),
- Config.
-
-end_per_testcase(_Case, _Config) ->
- ok.
+ dbg(Case, Config, init).
+
+end_per_testcase(Case, Config) ->
+ dbg(Case, Config, 'end').
+
+
+dbg(Case, Config, Status) ->
+ Cases = [esi_put],
+ case lists:member(Case, Cases) of
+ true ->
+ case Status of
+ init ->
+ dbg:tracer(),
+ dbg:p(all, c),
+ dbg:tpl(httpd_example, cx),
+ dbg:tpl(mod_esi, generate_webpage, cx),
+ io:format("dbg: started~n"),
+ Config;
+ 'end' ->
+ io:format("dbg: stopped~n"),
+ dbg:stop_clear(),
+ ok
+ end;
+ false ->
+ case Status of
+ init ->
+ Config;
+ 'end' ->
+ ok
+ end
+ end.
%%-------------------------------------------------------------------------
%% Test cases starts here.
@@ -489,6 +535,9 @@ do_auth_api(AuthPrefix, Config) ->
"two", "group1"),
add_group_member(Node, ServerRoot, Port, AuthPrefix,
"secret", "Aladdin", "group2"),
+ {ok, Members} = list_group_members(Node, ServerRoot, Port, AuthPrefix, "secret", "group1"),
+ true = lists:member("one", Members),
+ true = lists:member("two", Members),
ok = auth_status(auth_request("/" ++ AuthPrefix ++ "secret/",
"one", "onePassword", Version, Host),
Config, [{statuscode, 200}]),
@@ -765,6 +814,14 @@ esi(Config) when is_list(Config) ->
ok = http_status("GET /cgi-bin/erl/httpd_example:peer ",
Config, [{statuscode, 200},
{header, "peer-cert-exist", peer(Config)}]).
+
+%%-------------------------------------------------------------------------
+esi_put() ->
+ [{doc, "Test mod_esi PUT"}].
+
+esi_put(Config) when is_list(Config) ->
+ ok = http_status("PUT /cgi-bin/erl/httpd_example/put/123342234123 ",
+ Config, [{statuscode, 200}]).
%%-------------------------------------------------------------------------
mod_esi_chunk_timeout(Config) when is_list(Config) ->
@@ -2115,6 +2172,10 @@ add_group_member(Node, Root, Port, AuthPrefix, Dir, User, Group) ->
Directory = filename:join([Root, "htdocs", AuthPrefix ++ Dir]),
rpc:call(Node, mod_auth, add_group_member, [Group, User, Addr, Port,
Directory]).
+list_group_members(Node, Root, Port, AuthPrefix, Dir, Group) ->
+ Directory = filename:join([Root, "htdocs", AuthPrefix ++ Dir]),
+ rpc:call(Node, mod_auth, list_group_members, [Group, [{port, Port}, {dir, Directory}]]).
+
getaddr() ->
{ok,HostName} = inet:gethostname(),
{ok,{A1,A2,A3,A4}} = inet:getaddr(HostName,inet),
diff --git a/lib/inets/test/httpd_basic_SUITE.erl b/lib/inets/test/httpd_basic_SUITE.erl
index f413248092..931cd076cc 100644
--- a/lib/inets/test/httpd_basic_SUITE.erl
+++ b/lib/inets/test/httpd_basic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -42,7 +42,8 @@ all() ->
escaped_url_in_error_body,
script_timeout,
slowdose,
- keep_alive_timeout
+ keep_alive_timeout,
+ invalid_rfc1123_date
].
groups() ->
@@ -383,6 +384,16 @@ slowdose(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
+
+invalid_rfc1123_date() ->
+ [{doc, "Test that a non-DST date is handled correcly"}].
+invalid_rfc1123_date(Config) when is_list(Config) ->
+ Rfc1123FormattedDate = "Sun, 26 Mar 2017 01:00:00 GMT",
+ NonDSTDateTime = {{2017, 03, 26},{1, 0, 0}},
+ Rfc1123FormattedDate =:= httpd_util:rfc1123_date(NonDSTDateTime).
+
+
+%%-------------------------------------------------------------------------
%% Internal functions
%%-------------------------------------------------------------------------
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
index 3f9fde03b5..3add93cd73 100644
--- a/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
+++ b/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
+# Copyright Ericsson AB 1997-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -128,7 +128,7 @@ SecurityDiskLogSize 200000 10
MaxClients 50
-# KeepAlive set the flag for persistent connections. For peristent connections
+# KeepAlive set the flag for persistent connections. For persistent 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
diff --git a/lib/inets/test/inets_SUITE.erl b/lib/inets/test/inets_SUITE.erl
index 5eaf3a28a0..38b8229389 100644
--- a/lib/inets/test/inets_SUITE.erl
+++ b/lib/inets/test/inets_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -212,11 +212,19 @@ start_httpd(Config) when is_list(Config) ->
Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
true = lists:member(Pid0, Pids0),
[_|_] = inets:services_info(),
-
inets:stop(httpd, Pid0),
ct:sleep(500),
+ Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
+ false = lists:member(Pid0, Pids1),
+ {ok, Pid0b} =
+ inets:start(httpd, [{port, 0}, {ipfamily, inet6fb4} | HttpdConf]),
+ Pids0b = [ServicePid || {_, ServicePid} <- inets:services()],
+ true = lists:member(Pid0b, Pids0b),
+ [_|_] = inets:services_info(),
+ inets:stop(httpd, Pid0b),
+ ct:sleep(500),
Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
- false = lists:member(Pid0, Pids1),
+ false = lists:member(Pid0b, Pids1),
{ok, Pid1} =
inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf],
stand_alone),
diff --git a/lib/inets/test/inets_socketwrap_SUITE.erl b/lib/inets/test/inets_socketwrap_SUITE.erl
index 18df995215..7ea7e08ed1 100644
--- a/lib/inets/test/inets_socketwrap_SUITE.erl
+++ b/lib/inets/test/inets_socketwrap_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/inets/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl
index 5b8b1463c8..1e664337e6 100644
--- a/lib/inets/test/inets_sup_SUITE.erl
+++ b/lib/inets/test/inets_sup_SUITE.erl
@@ -33,7 +33,7 @@ suite() ->
all() ->
[default_tree, ftpc_worker, tftpd_worker,
- httpd_subtree, httpd_subtree_profile,
+ httpd_config, httpd_subtree, httpd_subtree_profile,
httpc_subtree].
groups() ->
@@ -52,9 +52,32 @@ end_per_suite(_) ->
inets:stop(),
ok.
-init_per_testcase(httpd_subtree, Config) ->
+init_per_testcase(httpd_config = TC, Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Dir = filename:join(PrivDir, TC),
+ ok = file:make_dir(Dir),
+
+ FallbackConfig = [{port, 0},
+ {server_name,"www.test"},
+ {modules, [mod_get]},
+ {server_root, Dir},
+ {document_root, Dir},
+ {bind_address, any},
+ {ipfamily, inet6fb4}],
+ try
+ inets:stop(),
+ inets:start(),
+ inets:start(httpd, FallbackConfig),
+ Config
+ catch
+ _:Reason ->
+ inets:stop(),
+ exit({failed_starting_inets, Reason})
+ end;
+
+init_per_testcase(httpd_subtree = TC, Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
- Dir = filename:join(PrivDir, "root"),
+ Dir = filename:join(PrivDir, TC),
ok = file:make_dir(Dir),
SimpleConfig = [{port, 0},
@@ -75,9 +98,9 @@ init_per_testcase(httpd_subtree, Config) ->
exit({failed_starting_inets, Reason})
end;
-init_per_testcase(httpd_subtree_profile, Config) ->
+init_per_testcase(httpd_subtree_profile = TC, Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
- Dir = filename:join(PrivDir, "root"),
+ Dir = filename:join(PrivDir, TC),
ok = file:make_dir(Dir),
SimpleConfig = [{port, 0},
@@ -193,6 +216,11 @@ tftpd_worker(Config) when is_list(Config) ->
[] = supervisor:which_children(tftp_sup),
ok.
+httpd_config() ->
+ [{doc, "Makes sure the httpd config works for inet6fb4."}].
+httpd_config(Config) when is_list(Config) ->
+ do_httpd_subtree(Config, default).
+
httpd_subtree() ->
[{doc, "Makes sure the httpd sub tree is correct."}].
httpd_subtree(Config) when is_list(Config) ->
diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf
index 3f9fde03b5..3add93cd73 100644
--- a/lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
+# Copyright Ericsson AB 1997-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -128,7 +128,7 @@ SecurityDiskLogSize 200000 10
MaxClients 50
-# KeepAlive set the flag for persistent connections. For peristent connections
+# KeepAlive set the flag for persistent connections. For persistent 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
diff --git a/lib/inets/test/uri_SUITE.erl b/lib/inets/test/uri_SUITE.erl
index b26c645821..3e7799141c 100644
--- a/lib/inets/test/uri_SUITE.erl
+++ b/lib/inets/test/uri_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
-module(uri_SUITE).
+-include_lib("eunit/include/eunit.hrl").
-include_lib("common_test/include/ct.hrl").
-include("inets_test_lib.hrl").
@@ -50,7 +51,8 @@ all() ->
fragments,
escaped,
hexed_query,
- scheme_validation
+ scheme_validation,
+ encode_decode
].
%%--------------------------------------------------------------------
@@ -73,7 +75,10 @@ end_per_testcase(_Case, _Config) ->
ipv4(Config) when is_list(Config) ->
{ok, {http,[],"127.0.0.1",80,"/foobar.html",[]}} =
- http_uri:parse("http://127.0.0.1/foobar.html").
+ http_uri:parse("http://127.0.0.1/foobar.html"),
+
+ {ok, {http,<<>>,<<"127.0.0.1">>,80,<<"/foobar.html">>,<<>>}} =
+ http_uri:parse(<<"http://127.0.0.1/foobar.html">>).
ipv6(Config) when is_list(Config) ->
{ok, {http,[],"2010:836B:4179::836B:4179",80,"/foobar.html",[]}} =
@@ -89,24 +94,52 @@ ipv6(Config) when is_list(Config) ->
[{foo, false}]),
{error,
{malformed_url, _, "http://2010:836B:4179::836B:4179/foobar.html"}} =
- http_uri:parse("http://2010:836B:4179::836B:4179/foobar.html").
+ http_uri:parse("http://2010:836B:4179::836B:4179/foobar.html"),
+
+ {ok, {http,<<>>,<<"2010:836B:4179::836B:4179">>,80,<<"/foobar.html">>,<<>>}} =
+ http_uri:parse(<<"http://[2010:836B:4179::836B:4179]/foobar.html">>),
+ {ok, {http,<<>>,<<"[2010:836B:4179::836B:4179]">>,80,<<"/foobar.html">>,<<>>}} =
+ http_uri:parse(<<"http://[2010:836B:4179::836B:4179]/foobar.html">>,
+ [{ipv6_host_with_brackets, true}]),
+ {ok, {http,<<>>,<<"2010:836B:4179::836B:4179">>,80,<<"/foobar.html">>,<<>>}} =
+ http_uri:parse(<<"http://[2010:836B:4179::836B:4179]/foobar.html">>,
+ [{ipv6_host_with_brackets, false}]),
+ {ok, {http,<<>>,<<"2010:836B:4179::836B:4179">>,80,<<"/foobar.html">>,<<>>}} =
+ http_uri:parse(<<"http://[2010:836B:4179::836B:4179]/foobar.html">>,
+ [{foo, false}]),
+ {error,
+ {malformed_url, _, <<"http://2010:836B:4179::836B:4179/foobar.html">>}} =
+ http_uri:parse(<<"http://2010:836B:4179::836B:4179/foobar.html">>).
host(Config) when is_list(Config) ->
{ok, {http,[],"localhost",8888,"/foobar.html",[]}} =
- http_uri:parse("http://localhost:8888/foobar.html").
+ http_uri:parse("http://localhost:8888/foobar.html"),
+
+ {ok, {http,<<>>,<<"localhost">>,8888,<<"/foobar.html">>,<<>>}} =
+ http_uri:parse(<<"http://localhost:8888/foobar.html">>).
userinfo(Config) when is_list(Config) ->
{ok, {http,"nisse:foobar","localhost",8888,"/foobar.html",[]}} =
- http_uri:parse("http://nisse:foobar@localhost:8888/foobar.html").
+ http_uri:parse("http://nisse:foobar@localhost:8888/foobar.html"),
+
+ {ok, {http,<<"nisse:foobar">>,<<"localhost">>,8888,<<"/foobar.html">>,<<>>}} =
+ http_uri:parse(<<"http://nisse:foobar@localhost:8888/foobar.html">>).
scheme(Config) when is_list(Config) ->
{error, no_scheme} = http_uri:parse("localhost/foobar.html"),
{error, {malformed_url, _, _}} =
- http_uri:parse("localhost:8888/foobar.html").
+ http_uri:parse("localhost:8888/foobar.html"),
+
+ {error, no_scheme} = http_uri:parse(<<"localhost/foobar.html">>),
+ {error, {malformed_url, _, _}} =
+ http_uri:parse(<<"localhost:8888/foobar.html">>).
queries(Config) when is_list(Config) ->
{ok, {http,[],"localhost",8888,"/foobar.html","?foo=bar&foobar=42"}} =
- http_uri:parse("http://localhost:8888/foobar.html?foo=bar&foobar=42").
+ http_uri:parse("http://localhost:8888/foobar.html?foo=bar&foobar=42"),
+
+ {ok, {http,<<>>,<<"localhost">>,8888,<<"/foobar.html">>,<<"?foo=bar&foobar=42">>}} =
+ http_uri:parse(<<"http://localhost:8888/foobar.html?foo=bar&foobar=42">>).
fragments(Config) when is_list(Config) ->
{ok, {http,[],"localhost",80,"/",""}} =
@@ -142,6 +175,41 @@ fragments(Config) when is_list(Config) ->
http_uri:parse("http://localhost?query#", [{fragment,true}]),
{ok, {http,[],"localhost",80,"/path","?query","#"}} =
http_uri:parse("http://localhost/path?query#", [{fragment,true}]),
+
+
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/">>,<<"">>}} =
+ http_uri:parse(<<"http://localhost#fragment">>),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/path">>,<<"">>}} =
+ http_uri:parse(<<"http://localhost/path#fragment">>),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/">>,<<"?query">>}} =
+ http_uri:parse(<<"http://localhost?query#fragment">>),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/path">>,<<"?query">>}} =
+ http_uri:parse(<<"http://localhost/path?query#fragment">>),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/">>,<<"">>,<<"#fragment">>}} =
+ http_uri:parse(<<"http://localhost#fragment">>, [{fragment,true}]),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/path">>,<<"">>,<<"#fragment">>}} =
+ http_uri:parse(<<"http://localhost/path#fragment">>, [{fragment,true}]),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/">>,<<"?query">>,<<"#fragment">>}} =
+ http_uri:parse(<<"http://localhost?query#fragment">>, [{fragment,true}]),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/path">>,<<"?query">>,<<"#fragment">>}} =
+ http_uri:parse(<<"http://localhost/path?query#fragment">>,
+ [{fragment,true}]),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/">>,<<"">>,<<"">>}} =
+ http_uri:parse(<<"http://localhost">>, [{fragment,true}]),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/path">>,<<"">>,<<"">>}} =
+ http_uri:parse(<<"http://localhost/path">>, [{fragment,true}]),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/">>,<<"?query">>,<<"">>}} =
+ http_uri:parse(<<"http://localhost?query">>, [{fragment,true}]),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/path">>,<<"?query">>,<<"">>}} =
+ http_uri:parse(<<"http://localhost/path?query">>, [{fragment,true}]),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/">>,<<"">>,<<"#">>}} =
+ http_uri:parse(<<"http://localhost#">>, [{fragment,true}]),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/path">>,<<"">>,<<"#">>}} =
+ http_uri:parse(<<"http://localhost/path#">>, [{fragment,true}]),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/">>,<<"?query">>,<<"#">>}} =
+ http_uri:parse(<<"http://localhost?query#">>, [{fragment,true}]),
+ {ok, {http,<<>>,<<"localhost">>,80,<<"/path">>,<<"?query">>,<<"#">>}} =
+ http_uri:parse(<<"http://localhost/path?query#">>, [{fragment,true}]),
ok.
escaped(Config) when is_list(Config) ->
@@ -152,7 +220,16 @@ escaped(Config) when is_list(Config) ->
{ok, {http,[],"www.somedomain.com",80,"/%25abc",[]}} =
http_uri:parse("http://www.somedomain.com/%25abc"),
{ok, {http,[],"www.somedomain.com",80,"/%25abc", "?foo=bar"}} =
- http_uri:parse("http://www.somedomain.com/%25abc?foo=bar").
+ http_uri:parse("http://www.somedomain.com/%25abc?foo=bar"),
+
+ {ok, {http,<<>>,<<"www.somedomain.com">>,80,<<"/%2Eabc">>,<<>>}} =
+ http_uri:parse(<<"http://www.somedomain.com/%2Eabc">>),
+ {ok, {http,<<>>,<<"www.somedomain.com">>,80,<<"/%252Eabc">>,<<>>}} =
+ http_uri:parse(<<"http://www.somedomain.com/%252Eabc">>),
+ {ok, {http,<<>>,<<"www.somedomain.com">>,80,<<"/%25abc">>,<<>>}} =
+ http_uri:parse(<<"http://www.somedomain.com/%25abc">>),
+ {ok, {http,<<>>,<<"www.somedomain.com">>,80,<<"/%25abc">>, <<"?foo=bar">>}} =
+ http_uri:parse(<<"http://www.somedomain.com/%25abc?foo=bar">>).
hexed_query(doc) ->
[{doc, "Solves OTP-6191"}];
@@ -196,6 +273,17 @@ scheme_validation(Config) when is_list(Config) ->
http_uri:parse("https://localhost#fragment",
[{scheme_validation_fun, none}]).
+encode_decode(Config) when is_list(Config) ->
+ ?assertEqual("foo%20bar", http_uri:encode("foo bar")),
+ ?assertEqual(<<"foo%20bar">>, http_uri:encode(<<"foo bar">>)),
+
+ ?assertEqual("foo bar", http_uri:decode("foo+bar")),
+ ?assertEqual(<<"foo bar">>, http_uri:decode(<<"foo+bar">>)),
+ ?assertEqual("foo bar", http_uri:decode("foo%20bar")),
+ ?assertEqual(<<"foo bar">>, http_uri:decode(<<"foo%20bar">>)),
+ ?assertEqual("foo\r\n", http_uri:decode("foo%0D%0A")),
+ ?assertEqual(<<"foo\r\n">>, http_uri:decode(<<"foo%0D%0A">>)).
+
%%--------------------------------------------------------------------
%% Internal Functions ------------------------------------------------
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index 543e0d44fd..96796f11c0 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2001-2016. All Rights Reserved.
+# Copyright Ericsson AB 2001-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,6 +19,6 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 6.3
+INETS_VSN = 6.4
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
diff --git a/lib/jinterface/doc/src/Makefile b/lib/jinterface/doc/src/Makefile
index cd1e61a795..508c8e01b5 100644
--- a/lib/jinterface/doc/src/Makefile
+++ b/lib/jinterface/doc/src/Makefile
@@ -166,7 +166,7 @@ release_docs_spec: docs
$(INSTALL_DIR) "$(RELSYSDIR)/doc/html"
$(INSTALL_DIR) "$(RELSYSDIR)/doc/html/java/$(JAVA_PKG_PATH)"
$(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)"
- (/bin/cp -rf ../html "$(RELSYSDIR)/doc")
+ ($(CP) -rf ../html "$(RELSYSDIR)/doc")
# $(INSTALL_DATA) $(GIF_FILES) $(EXTRA_FILES) $(HTML_FILES) \
# "$(RELSYSDIR)/doc/html"
diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml
index 3151fc4b5e..b44a04d7cd 100644
--- a/lib/jinterface/doc/src/notes.xml
+++ b/lib/jinterface/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2016</year>
+ <year>2000</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,48 @@
</header>
<p>This document describes the changes made to the Jinterface application.</p>
+<section><title>Jinterface 1.8</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Remove generation of atoms in old latin1 external format
+ in the distribution between erlang nodes,
+ <c>erl_interface</c>, and <c>jinterface</c>. The new utf8
+ format for atoms was introduced in OTP R16. An OTP 20
+ node can therefore not connect to nodes older than R16.</p>
+ <p>
+ Atoms that can be encoded using latin1 are still encoded
+ by <c>term_to_binary()</c> using latin1 encoding. Note
+ that all atoms will by default be encoded using utf8 in a
+ future Erlang/OTP release. For more information see the
+ documentation of <seealso
+ marker="erts:erlang#term_to_binary/2"><c>erlang:term_to_binary/2</c></seealso>.</p>
+ <p>
+ Own Id: OTP-14337</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Jinterface 1.7.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Update build scripts to not make assumtions about where
+ env, cp and perl are located.</p>
+ <p>
+ Own Id: OTP-13800</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Jinterface 1.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
index 7891871e76..0bf3ca2a67 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2000-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ import java.util.Random;
* received from the peer.
*
* <p>
- * This abstract class provides the neccesary methods to maintain the actual
+ * This abstract class provides the necessary methods to maintain the actual
* connection and encode the messages and headers in the proper format according
* to the Erlang distribution protocol. Subclasses can use these methods to
* provide a more or less transparent communication channel as desired.
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java
index 70c9e6db4a..42e178c3f6 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2000-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@ package com.ericsson.otp.erlang;
* <p>
* Mailboxes can be named, either at creation or later. Messages can be sent to
* named mailboxes and named Erlang processes without knowing the
- * {@link OtpErlangPid pid} that identifies the mailbox. This is neccessary in
+ * {@link OtpErlangPid pid} that identifies the mailbox. This is necessary in
* order to set up initial communication between parts of an application. Each
* mailbox can have at most one name.
* </p>
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
index dca2eb7c51..187705a0b5 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpOutputStream.java
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2000-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -403,7 +403,6 @@ public class OtpOutputStream extends ByteArrayOutputStream {
public void write_atom(final String atom) {
String enc_atom;
byte[] bytes;
- boolean isLatin1 = true;
if (atom.codePointCount(0, atom.length()) <= OtpExternal.maxAtomLength) {
enc_atom = atom;
@@ -416,29 +415,15 @@ public class OtpOutputStream extends ByteArrayOutputStream {
OtpExternal.maxAtomLength);
}
- for (int offset = 0; offset < enc_atom.length();) {
- final int cp = enc_atom.codePointAt(offset);
- if ((cp & ~0xFF) != 0) {
- isLatin1 = false;
- break;
- }
- offset += Character.charCount(cp);
- }
try {
- if (isLatin1) {
- bytes = enc_atom.getBytes("ISO-8859-1");
- write1(OtpExternal.atomTag);
- write2BE(bytes.length);
+ bytes = enc_atom.getBytes("UTF-8");
+ final int length = bytes.length;
+ if (length < 256) {
+ write1(OtpExternal.smallAtomUtf8Tag);
+ write1(length);
} else {
- bytes = enc_atom.getBytes("UTF-8");
- final int length = bytes.length;
- if (length < 256) {
- write1(OtpExternal.smallAtomUtf8Tag);
- write1(length);
- } else {
- write1(OtpExternal.atomUtf8Tag);
- write2BE(length);
- }
+ write1(OtpExternal.atomUtf8Tag);
+ write2BE(length);
}
writeN(bytes);
} catch (final java.io.UnsupportedEncodingException e) {
diff --git a/lib/jinterface/test/jinterface_SUITE_data/Maps.java b/lib/jinterface/test/jinterface_SUITE_data/Maps.java
index e8a05245da..c4dfbab5e5 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/Maps.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/Maps.java
@@ -11,7 +11,7 @@ import com.ericsson.otp.erlang.OtpOutputStream;
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2004-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2004-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,19 +40,19 @@ class Maps {
public static void main(final String argv[]) {
runTest(new byte[] { (byte) 131, 116, 0, 0, 0, 0 }, "#{}", 1);
- runTest(new byte[] { (byte) 131, 116, 0, 0, 0, 1, 100, 0, 1, 97, 100,
- 0, 1, 98 }, "#{a => b}", 2);
+ runTest(new byte[] { (byte) 131, 116, 0, 0, 0, 1, 119, 1, 97, 119,
+ 1, 98 }, "#{a => b}", 2);
// make sure keys are sorted here, jinterface doesn't reorder them
runTest(new byte[] { (byte) 131, 116, 0, 0, 0, 2, 97, 2, 106,
- 100, 0, 1, 97, 97, 1 }, "#{2 => [],a => 1}", 3);
+ 119, 1, 97, 97, 1 }, "#{2 => [],a => 1}", 3);
runTest(new byte[] { (byte) 131, 116, 0, 0, 0, 1, 104, 1, 97, 3, 108,
- 0, 0, 0, 1, 100, 0, 1, 114, 106 }, "#{{3} => [r]}", 4);
+ 0, 0, 0, 1, 119, 1, 114, 106 }, "#{{3} => [r]}", 4);
try {
// #{2 => [],a => 1}
final OtpErlangMap map = new OtpErlangMap(new OtpInputStream(
new byte[] { (byte) 131, 116, 0, 0, 0, 2, 97, 2, 106,
- 100, 0, 1, 97, 97, 1 }));
+ 119, 1, 97, 97, 1 }));
if (map.arity() != 2) {
fail(5);
diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk
index 752b34e78c..373e2dab22 100644
--- a/lib/jinterface/vsn.mk
+++ b/lib/jinterface/vsn.mk
@@ -1 +1 @@
-JINTERFACE_VSN = 1.7
+JINTERFACE_VSN = 1.8
diff --git a/lib/kernel/doc/src/app.xml b/lib/kernel/doc/src/app.xml
index 5e0da409a3..d2e9390d7e 100644
--- a/lib/kernel/doc/src/app.xml
+++ b/lib/kernel/doc/src/app.xml
@@ -151,7 +151,7 @@ ApplicationVersion = string()</code>
application is allowed to be started. <c>systools</c> uses
this list to generate correct start scripts. Defaults to
the empty list, but notice that all applications have
- dependencies to (at least) <c>Kernel</c> and <c>STDLIB</c>.</p>
+ dependencies to (at least) Kernel and STDLIB.</p>
</item>
<tag><c>env</c></tag>
<item>
@@ -171,7 +171,7 @@ ApplicationVersion = string()</code>
implemented as a supervision tree, otherwise the application
controller does not know how to start it. <c>mod</c>
can be omitted for applications without processes, typically
- code libraries, for example, <c>STDLIB</c>.</p>
+ code libraries, for example, STDLIB.</p>
</item>
<tag><c>start_phases</c></tag>
<item>
@@ -236,7 +236,7 @@ ApplicationVersion = string()</code>
<section>
<title>See Also</title>
<p><seealso marker="application"><c>application(3)</c></seealso>,
- <seealso marker="sasl:systools"><c>sasl:systools(3)</c></seealso></p>
+ <seealso marker="sasl:systools"><c>systools(3)</c></seealso></p>
</section>
</fileref>
diff --git a/lib/kernel/doc/src/application.xml b/lib/kernel/doc/src/application.xml
index 8d33aa86e7..886286b76d 100644
--- a/lib/kernel/doc/src/application.xml
+++ b/lib/kernel/doc/src/application.xml
@@ -200,7 +200,7 @@
<seealso marker="app"><c>app(4)</c></seealso>.</p>
<p>If <c><anno>Distributed</anno> == {<anno>Application</anno>,[<anno>Time</anno>,]<anno>Nodes</anno>}</c>,
the application becomes distributed. The argument overrides
- the value for the application in the <c>Kernel</c> configuration
+ the value for the application in the Kernel configuration
parameter <c>distributed</c>. <c><anno>Application</anno></c> must be
the application name (same as in the first argument).
If a node crashes and <c><anno>Time</anno></c> is specified,
@@ -221,7 +221,7 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
the application is to be started at <c>cp2@cave</c>
or <c>cp3@cave</c>.</p>
<p>If <c>Distributed == default</c>, the value for
- the application in the <c>Kernel</c> configuration parameter
+ the application in the Kernel configuration parameter
<c>distributed</c> is used.</p>
</desc>
</func>
@@ -267,7 +267,7 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
started, <c>Application</c> is started as well.</p>
<p>By default, all applications are loaded with permission
<c>true</c> on all nodes. The permission can be configured
- using the <c>Kernel</c> configuration parameter <c>permissions</c>.</p>
+ using the Kernel configuration parameter <c>permissions</c>.</p>
</desc>
</func>
<func>
diff --git a/lib/kernel/doc/src/auth.xml b/lib/kernel/doc/src/auth.xml
index 03f983b96d..5901446960 100644
--- a/lib/kernel/doc/src/auth.xml
+++ b/lib/kernel/doc/src/auth.xml
@@ -47,7 +47,7 @@
<desc>
<p>Use
<seealso marker="erts:erlang#erlang:get_cookie/0"><c>erlang:get_cookie()</c></seealso>
- in <c>ERTS</c> instead.</p>
+ in ERTS instead.</p>
</desc>
</func>
<func>
@@ -59,7 +59,7 @@
<desc>
<p>Use
<seealso marker="erts:erlang#erlang:set_cookie/2"><c>erlang:set_cookie(node(), <anno>Cookie</anno>)</c>
- in <c>ERTS</c></seealso> instead.</p>
+ in ERTS</seealso> instead.</p>
</desc>
</func>
<func>
diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml
index d3611d6a03..c94f612c01 100644
--- a/lib/kernel/doc/src/code.xml
+++ b/lib/kernel/doc/src/code.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -86,11 +86,11 @@
an <c>ebin</c> directory are ignored.</p>
<p>All application directories found in the additional directories
appears before the standard OTP applications, except for the
- <c>Kernel</c> and <c>STDLIB</c> applications, which are placed before
+ Kernel and STDLIB applications, which are placed before
any additional applications. In other words, modules found in any
of the additional library directories override modules with
- the same name in OTP, except for modules in <c>Kernel</c> and
- <c>STDLIB</c>.</p>
+ the same name in OTP, except for modules in Kernel and
+ STDLIB.</p>
<p>Environment variable <c>ERL_LIBS</c> (if defined) is to contain
a colon-separated (for Unix-like systems) or semicolon-separated
(for Windows) list of additional libraries.</p>
@@ -151,7 +151,7 @@ zip:create("mnesia-4.4.7.ez",
<c>$OTPROOT/lib/mnesia.ez/mnesia/ebin</c> or
<c>$OTPROOT/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin</c>.</p>
- <p>The code server uses module <c>erl_prim_loader</c> in <c>ERTS</c>
+ <p>The code server uses module <c>erl_prim_loader</c> in ERTS
(possibly through <c>erl_boot_server</c>) to read code files from
archives. However, the functions in <c>erl_prim_loader</c> can also be
used by other applications to read files from archives. For
@@ -258,7 +258,7 @@ zip:create("mnesia-4.4.7.ez",
both strings and atoms, but a future release will probably only allow
the arguments that are documented.</p>
- <p>As from Erlang/OTP R12B, functions in this module generally fail with an
+ <p>Functions in this module generally fail with an
exception if they are passed an incorrect type (for example, an integer or a tuple
where an atom is expected). An error tuple is returned if the argument type
is correct, but there are some other errors (for example, a non-existing directory
@@ -382,9 +382,14 @@ zip:create("mnesia-4.4.7.ez",
<name name="add_pathsa" arity="1"/>
<fsummary>Add directories to the beginning of the code path.</fsummary>
<desc>
- <p>Adds the directories in <c><anno>Dirs</anno></c> to the beginning of
- the code path. If a <c><anno>Dir</anno></c> exists, it is removed
- from the old position in the code path.</p>
+ <p>Traverses <c><anno>Dirs</anno></c> and adds
+ each <c><anno>Dir</anno></c> to the beginning of the code
+ path. This means that the order of <c><anno>Dirs</anno></c>
+ is reversed in the resulting code path. For example, if you
+ add <c>[Dir1,Dir2]</c>, the resulting path will
+ be <c>[Dir2,Dir1|OldCodePath]</c>.</p>
+ <p>If a <c><anno>Dir</anno></c> already exists in the code
+ path, it is removed from the old position.</p>
<p>Always returns <c>ok</c>, regardless of the validity of each
individual <c><anno>Dir</anno></c>.</p>
</desc>
@@ -651,6 +656,11 @@ ok = code:finish_loading(Prepared),
<p>Purges the code for <c><anno>Module</anno></c>, that is, removes code
marked as old. If some processes still linger in the old code,
these processes are killed before the code is removed.</p>
+ <note><p>As of ERTS version 9.0, a process is only considered
+ to be lingering in the code if it has direct references to the code.
+ For more information see documentation of
+ <seealso marker="erts:erlang#check_process_code/3"><c>erlang:check_process_code/3</c></seealso>,
+ which is used in order to determine this.</p></note>
<p>Returns <c>true</c> if successful and any process is needed to
be killed, otherwise <c>false</c>.</p>
</desc>
@@ -661,6 +671,11 @@ ok = code:finish_loading(Prepared),
<desc>
<p>Purges the code for <c><anno>Module</anno></c>, that is, removes code
marked as old, but only if no processes linger in it.</p>
+ <note><p>As of ERTS version 9.0, a process is only considered
+ to be lingering in the code if it has direct references to the code.
+ For more information see documentation of
+ <seealso marker="erts:erlang#check_process_code/3"><c>erlang:check_process_code/3</c></seealso>,
+ which is used in order to determine this.</p></note>
<p>Returns <c>false</c> if the module cannot be purged because
of processes lingering in old code, otherwise <c>true</c>.</p>
</desc>
@@ -678,9 +693,9 @@ ok = code:finish_loading(Prepared),
<p>Normally, <c><anno>Loaded</anno></c> is the absolute filename
<c>Filename</c> from which the code is obtained. If the module
is preloaded (see
- <seealso marker="sasl:script"><c>sasl:script(4)</c></seealso>),
+ <seealso marker="sasl:script"><c>script(4)</c></seealso>),
<c>Loaded==preloaded</c>. If the module is Cover-compiled (see
- <seealso marker="tools:cover"><c>tools:cover(3)</c></seealso>),
+ <seealso marker="tools:cover"><c>cover(3)</c></seealso>),
<c>Loaded==cover_compiled</c>.</p>
</desc>
</func>
@@ -884,6 +899,48 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
</desc>
</func>
<func>
+ <name name="module_status" arity="1"/>
+ <fsummary>Return the status of the module in relation to object file on disk.</fsummary>
+ <desc>
+ <p>Returns:</p>
+ <taglist>
+ <tag><c>not_loaded</c></tag>
+ <item><p>If <c><anno>Module</anno></c> is not currently loaded.</p></item>
+ <tag><c>loaded</c></tag>
+ <item><p>If <c><anno>Module</anno></c> is loaded and the object file
+ exists and contains the same code.</p></item>
+ <tag><c>removed</c></tag>
+ <item><p>If <c><anno>Module</anno></c> is loaded but no
+ corresponding object file can be found in the code path.</p></item>
+ <tag><c>modified</c></tag>
+ <item><p>If <c><anno>Module</anno></c> is loaded but the object file
+ contains code with a different MD5 checksum.</p></item>
+ </taglist>
+ <p>Preloaded modules are always reported as <c>loaded</c>, without
+ inspecting the contents on disk. Cover compiled modules will always
+ be reported as <c>modified</c> if an object file exists, or as
+ <c>removed</c> otherwise. Modules whose load path is an empty string
+ (which is the convention for auto-generated code) will only be
+ reported as <c>loaded</c> or <c>not_loaded</c>.</p>
+ <p>For modules that have native code loaded (see
+ <seealso marker="#is_module_native/1"><c>is_module_native/1</c></seealso>),
+ the MD5 sum of the native code in the object file is used for the
+ comparison, if it exists; the Beam code in the file is ignored.
+ Reversely, for modules that do not currently have native code
+ loaded, any native code in the file will be ignored.</p>
+ <p>See also <seealso marker="#modified_modules/0"><c>modified_modules/0</c></seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="modified_modules" arity="0"/>
+ <fsummary>Return a list of all modules modified on disk.</fsummary>
+ <desc>
+ <p>Returns the list of all currently loaded modules for which
+ <seealso marker="#module_status/1"><c>module_status/1</c></seealso>
+ returns <c>modified</c>. See also <seealso marker="#all_loaded/0"><c>all_loaded/0</c></seealso>.</p>
+ </desc>
+ </func>
+ <func>
<name name="is_module_native" arity="1"/>
<fsummary>Test if a module has native code.</fsummary>
<desc>
diff --git a/lib/kernel/doc/src/config.xml b/lib/kernel/doc/src/config.xml
index c5f37fd036..fdb2d29f63 100644
--- a/lib/kernel/doc/src/config.xml
+++ b/lib/kernel/doc/src/config.xml
@@ -4,7 +4,7 @@
<fileref>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -77,8 +77,8 @@
to update the application configurations.</p>
<p>This means that specifying another <c>.config</c> file, or more
<c>.config</c> files, leads to inconsistent update of application
- configurations. Therefore, in Erlang 5.4/OTP R10B, the syntax of
- <c>sys.config</c> was extended to allow pointing out other
+ configurations. There is, however, a syntax for
+ <c>sys.config</c> that allows pointing out other
<c>.config</c> files:</p>
<code type="none">
[{Application, [{Par, Val}]} | File].</code>
diff --git a/lib/kernel/doc/src/disk_log.xml b/lib/kernel/doc/src/disk_log.xml
index 0b6ee1e6a5..1be28adfb8 100644
--- a/lib/kernel/doc/src/disk_log.xml
+++ b/lib/kernel/doc/src/disk_log.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1997</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -43,7 +43,7 @@
<taglist>
<tag>halt logs</tag>
<item><p>Appends items to a single file, which size can
- be limited by the disk log module.</p></item>
+ be limited by the <c>disk_log</c> module.</p></item>
<tag>wrap logs</tag>
<item><p>Uses a sequence of wrap log files of limited size. As a
wrap log file is filled up, further items are logged on to the next
@@ -62,8 +62,8 @@
An item logged to an internally formatted log must not occupy more
than 4 GB of disk space (the size must fit in 4 bytes).</p></item>
<tag>external format</tag>
- <item><p>Leaves it up to the user to read the logged deep byte lists.
- The disk log module cannot repair externally formatted logs.</p></item>
+ <item><p>Leaves it up to the user to read and interpret the logged data.
+ The <c>disk_log</c> module cannot repair externally formatted logs.</p></item>
</taglist>
<p>For each open disk log, one process handles requests
@@ -109,8 +109,7 @@
These functions log one or more Erlang terms.
By prefixing each of the functions with a <c>b</c> (for "binary"),
we get the corresponding <c>blog()</c> functions for the external format.
- These functions log one or more deep lists of bytes or, alternatively,
- binaries of deep lists of bytes.
+ These functions log one or more chunks of bytes.
For example, to log the string <c>"hello"</c> in ASCII format, you
can use <c>disk_log:blog(Log, "hello")</c>, or
<c>disk_log:blog(Log, list_to_binary("hello"))</c>. The two
@@ -219,9 +218,6 @@
<name name="dlog_head_opt"/>
</datatype>
<datatype>
- <name name="dlog_byte"/>
- </datatype>
- <datatype>
<name name="dlog_mode"/>
</datatype>
<datatype>
@@ -234,9 +230,6 @@
</desc>
</datatype>
<datatype>
- <name name="bytes"/>
- </datatype>
- <datatype>
<name name="invalid_header"/>
</datatype>
<datatype>
@@ -953,7 +946,7 @@
written first on the log file. If the log is a wrap
log, the item <c><anno>Head</anno></c> is written first in each new file.
<c><anno>Head</anno></c> is to be a term if the format is
- <c>internal</c>, otherwise a deep list of bytes (or a binary).
+ <c>internal</c>, otherwise a sequence of bytes.
Defaults to <c>none</c>, which means that
no header is written first on the file.
</p>
@@ -965,7 +958,7 @@
The call <c>M:F(A)</c> is assumed to return <c>{ok, Head}</c>.
The item <c>Head</c> is written first in each file.
<c>Head</c> is to be a term if the format is
- <c>internal</c>, otherwise a deep list of bytes (or a binary).
+ <c>internal</c>, otherwise a sequence of bytes.
</p>
</item>
<tag><c>{mode, <anno>Mode</anno>}</c></tag>
@@ -975,6 +968,12 @@
<c>read_write</c>.
</p>
</item>
+ <tag><c>{quiet, Boolean}</c></tag>
+ <item>
+ <p>Specifies if messages will be sent to
+ <c>error_logger</c> on recoverable errors with
+ the log files. Defaults to <c>true</c>.</p>
+ </item>
</taglist>
<p><c>open/1</c> returns <c>{ok, <anno>Log</anno>}</c> if the
log file is successfully opened. If the file is
diff --git a/lib/kernel/doc/src/erl_boot_server.xml b/lib/kernel/doc/src/erl_boot_server.xml
index 897365f9b9..4109251387 100644
--- a/lib/kernel/doc/src/erl_boot_server.xml
+++ b/lib/kernel/doc/src/erl_boot_server.xml
@@ -38,13 +38,13 @@
command-line flag <c>-loader inet</c>. All hosts specified
with command-line flag <c>-hosts Host</c> must have one
instance of this server running.</p>
- <p>This server can be started with the <c>Kernel</c> configuration
+ <p>This server can be started with the Kernel configuration
parameter <c>start_boot_server</c>.</p>
<p>The <c>erl_boot_server</c> can read regular files and
files in archives. See <seealso marker="code"><c>code(3)</c></seealso>
and
<seealso marker="erts:erl_prim_loader"><c>erl_prim_loader(3)</c></seealso>
- in <c>ERTS</c>.</p>
+ in ERTS.</p>
<warning><p>The support for loading code from archive files is
experimental. It is released before it is ready
to obtain early feedback. The file format, semantics,
diff --git a/lib/kernel/doc/src/erl_ddll.xml b/lib/kernel/doc/src/erl_ddll.xml
index a5ce58ef3e..75114e015c 100644
--- a/lib/kernel/doc/src/erl_ddll.xml
+++ b/lib/kernel/doc/src/erl_ddll.xml
@@ -201,7 +201,7 @@
<desc>
<p>Removes a driver monitor in much the same way as
<seealso marker="erts:erlang#erlang:demonitor/1"><c>erlang:demonitor/1</c></seealso>
- in <c>ERTS</c>
+ in ERTS
does with process monitors. For details about how to create
driver monitors, see
<seealso marker="#monitor/2"><c>monitor/2</c></seealso>,
@@ -431,7 +431,7 @@
<p>Creates a driver monitor and works in many
ways as
<seealso marker="erts:erlang#erlang:monitor/2"><c>erlang:monitor/2</c></seealso>
- in <c>ERTS</c>,
+ in ERTS,
does for processes. When a driver changes state, the monitor
results in a monitor message that is sent to the calling
process. <c><anno>MonitorRef</anno></c> returned by this function is
@@ -745,7 +745,7 @@
<p>This parameter is the name of the driver
to be used in subsequent calls to function
<seealso marker="erts:erlang#open_port/2"><c>erlang:open_port</c></seealso>
- in <c>ERTS</c>.
+ in ERTS.
The name can be specified as an <c>iolist()</c> or
an <c>atom()</c>. The name specified when loading is used
to find the object file (with the help of <c><anno>Path</anno></c>
diff --git a/lib/kernel/doc/src/error_logger.xml b/lib/kernel/doc/src/error_logger.xml
index a8273e59e2..91bf57cb91 100644
--- a/lib/kernel/doc/src/error_logger.xml
+++ b/lib/kernel/doc/src/error_logger.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -33,7 +33,7 @@
<description>
<p>The Erlang <em>error logger</em> is an event manager (see
<seealso marker="doc/design_principles:des_princ">OTP Design Principles</seealso> and
- <seealso marker="stdlib:gen_event"><c>stdlib:gen_event(3)</c></seealso>),
+ <seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso>),
registered as <c>error_logger</c>. Errors, warnings, and info events
are sent to the error logger from the Erlang runtime system and
the different Erlang/OTP applications. The events are, by default,
@@ -44,12 +44,12 @@
executing.</p>
<p>Initially, <c>error_logger</c> has only a primitive event
handler, which buffers and prints the raw event messages. During
- system startup, the <c>Kernel</c> application replaces this with a
+ system startup, the Kernel application replaces this with a
<em>standard event handler</em>, by default one that writes
- nicely formatted output to the terminal. <c>Kernel</c> can also be
+ nicely formatted output to the terminal. Kernel can also be
configured so that events are logged to a file instead, or not logged at all,
see <seealso marker="kernel_app"><c>kernel(6)</c></seealso>.</p>
- <p>Also the <c>SASL</c> application, if started, adds its own event
+ <p>Also the SASL application, if started, adds its own event
handler, which by default writes supervisor, crash, and progress
reports to the terminal. See
<seealso marker="sasl:sasl_app"><c>sasl(6)</c></seealso>.</p>
@@ -58,9 +58,9 @@
User-defined event handlers can be added to handle application-specific
events, see
<seealso marker="#add_report_handler/1"><c>add_report_handler/1,2</c></seealso>.
- Also, a useful event handler is provided in <c>STDLIB</c> for multi-file
+ Also, a useful event handler is provided in STDLIB for multi-file
logging of events, see
- <seealso marker="stdlib:log_mf_h"><c>stdlib:log_mf_h(3)</c></seealso>.</p>
+ <seealso marker="stdlib:log_mf_h"><c>log_mf_h(3)</c></seealso>.</p>
<p>Warning events were introduced in Erlang/OTP R9C and are enabled
by default as from Erlang/OTP 18.0. To retain backwards compatibility
with existing user-defined event handlers, the warning events can be
@@ -82,7 +82,7 @@
<p>Adds a new event handler to the error logger. The event
handler must be implemented as a <c>gen_event</c> callback
module, see
- <seealso marker="stdlib:gen_event"><c>stdlib:gen_event(3)</c></seealso>.</p>
+ <seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso>.</p>
<p><c><anno>Handler</anno></c> is typically the name of the callback module
and <c><anno>Args</anno></c> is an optional term (defaults to []) passed
to the initialization callback function <c><anno>Handler</anno>:init/1</c>.
@@ -97,7 +97,7 @@
<desc>
<p>Deletes an event handler from the error logger by calling
<c>gen_event:delete_handler(error_logger, <anno>Handler</anno>, [])</c>,
- see <seealso marker="stdlib:gen_event"><c>stdlib:gen_event(3)</c></seealso>.</p>
+ see <seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso>.</p>
</desc>
</func>
<func>
@@ -110,7 +110,7 @@
The <c><anno>Format</anno></c> and <c><anno>Data</anno></c> arguments
are the same as the arguments of
<seealso marker="stdlib:io#format/2"><c>io:format/2</c></seealso>
- in <c>STDLIB</c>.
+ in STDLIB.
The event is handled by the standard event handler.</p>
<p><em>Example:</em></p>
<pre>
@@ -126,6 +126,12 @@ ok</pre>
<seealso marker="#error_report/1"><c>error_report/1</c></seealso>
instead.</p>
</warning>
+ <warning>
+ <p>If the Unicode translation modifier (<c>t</c>) is used in
+ the format string, all error handlers must ensure that the
+ formatted output is correctly encoded for the I/O
+ device.</p>
+ </warning>
</desc>
</func>
<func>
@@ -163,6 +169,19 @@ ok</pre>
</desc>
</func>
<func>
+ <name name="get_format_depth" arity="0"/>
+ <fsummary>Get the value of the Kernel application variable
+ <c>error_logger_format_depth</c>.</fsummary>
+ <desc>
+ <p>Returns <c>max(10, Depth)</c>, where <c>Depth</c> is the
+ value of
+ <seealso marker="kernel:kernel_app#error_logger_format_depth">
+ error_logger_format_depth</seealso>
+ in the Kernel application, if Depth is an integer. Otherwise,
+ <c>unlimited</c> is returned.</p>
+ </desc>
+ </func>
+ <func>
<name name="info_msg" arity="1"/>
<name name="info_msg" arity="2"/>
<fsummary>Send a standard information event to the error logger.</fsummary>
@@ -171,7 +190,7 @@ ok</pre>
The <c><anno>Format</anno></c> and <c><anno>Data</anno></c> arguments
are the same as the arguments of
<seealso marker="stdlib:io#format/2"><c>io:format/2</c></seealso>
- in <c>STDLIB</c>. The event is handled by the standard event handler.</p>
+ in STDLIB. The event is handled by the standard event handler.</p>
<p><em>Example:</em></p>
<pre>
1> <input>error_logger:info_msg("Something happened in ~p~n", [a_module]).</input>
@@ -184,6 +203,12 @@ ok</pre>
the standard event handler, meaning no further events are
logged. When in doubt, use <c>info_report/1</c> instead.</p>
</warning>
+ <warning>
+ <p>If the Unicode translation modifier (<c>t</c>) is used in
+ the format string, all error handlers must ensure that the
+ formatted output is correctly encoded for the I/O
+ device.</p>
+ </warning>
</desc>
</func>
<func>
@@ -235,7 +260,7 @@ ok</pre>
<p>Enables or disables printout of standard events to a file.</p>
<p>This is done by adding or deleting the standard event handler
for output to file. Thus, calling this function overrides
- the value of the <c>Kernel</c> <c>error_logger</c> configuration
+ the value of the Kernel <c>error_logger</c> configuration
parameter.</p>
<p>Enabling file logging can be used together with calling
<c>tty(false)</c>, to have a silent system where
@@ -249,7 +274,7 @@ ok</pre>
successful, or <c>{error, allready_have_logfile}</c> if
logging to file is already enabled, or an error tuple if
another error occurred (for example, if <c><anno>Filename</anno></c>
- cannot be opened).</p>
+ cannot be opened). The file is opened with encoding UTF-8.</p>
</item>
<tag><c>close</c></tag>
<item>
@@ -274,7 +299,7 @@ ok</pre>
to the terminal.</p>
<p>This is done by adding or deleting the standard event handler
for output to the terminal. Thus, calling this function overrides
- the value of the <c>Kernel</c> <c>error_logger</c> configuration parameter.</p>
+ the value of the Kernel <c>error_logger</c> configuration parameter.</p>
</desc>
</func>
<func>
@@ -323,7 +348,7 @@ ok</pre>
The <c><anno>Format</anno></c> and <c><anno>Data</anno></c> arguments
are the same as the arguments of
<seealso marker="stdlib:io#format/2"><c>io:format/2</c></seealso>
- in <c>STDLIB</c>.
+ in STDLIB.
The event is handled by the standard event handler. It is tagged
as an error, warning, or info, see
<seealso marker="#warning_map/0"><c>warning_map/0</c></seealso>.</p>
@@ -332,6 +357,12 @@ ok</pre>
the standard event handler, meaning no further events are
logged. When in doubt, use <c>warning_report/1</c> instead.</p>
</warning>
+ <warning>
+ <p>If the Unicode translation modifier (<c>t</c>) is used in
+ the format string, all error handlers must ensure that the
+ formatted output is correctly encoded for the I/O
+ device.</p>
+ </warning>
</desc>
</func>
<func>
@@ -416,8 +447,8 @@ ok</pre>
</section>
<section>
<title>See Also</title>
- <p><seealso marker="stdlib:gen_event"><c>stdlib:gen_event(3)</c></seealso>,
- <seealso marker="stdlib:log_mf_h"><c>stdlib:log_mf_h(3)</c></seealso>
+ <p><seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso>,
+ <seealso marker="stdlib:log_mf_h"><c>log_mf_h(3)</c></seealso>
<seealso marker="kernel_app"><c>kernel(6)</c></seealso>
<seealso marker="sasl:sasl_app"><c>sasl(6)</c></seealso></p>
</section>
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 7d86c3ebcb..b674b3ca93 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -79,7 +79,7 @@
<seealso marker="#list_dir_all"><c>list_dir_all/1</c></seealso> and
<seealso marker="#read_link_all"><c>read_link_all/1</c></seealso>.</p>
- <p>See also section <seealso marker="stdlib:unicode_usage#notes-about-raw-filenames">Notes About Raw Filenames</seealso> in the <c>STDLIB</c> User´s Giude.</p>
+ <p>See also section <seealso marker="stdlib:unicode_usage#notes-about-raw-filenames">Notes About Raw Filenames</seealso> in the STDLIB User's Guide.</p>
</description>
@@ -277,7 +277,7 @@ f.txt: {person, "kalle", 25}.
{ok,[{person,"kalle",25},{person,"pelle",30}]}</pre>
<p>The encoding of <c><anno>Filename</anno></c> can be set
by a comment, as described in
- <seealso marker="stdlib:epp#encoding"><c>stdlib:epp(3)</c></seealso>.</p>
+ <seealso marker="stdlib:epp#encoding"><c>epp(3)</c></seealso>.</p>
</desc>
</func>
<func>
@@ -445,7 +445,7 @@ f.txt: {person, "kalle", 25}.
</taglist>
<p>The encoding of <c><anno>Filename</anno></c> can be set
by a comment, as described in
- <seealso marker="stdlib:epp#encoding"><c>stdlib:epp(3)</c></seealso>.</p>
+ <seealso marker="stdlib:epp#encoding"><c>epp(3)</c></seealso>.</p>
</desc>
</func>
<func>
@@ -455,7 +455,7 @@ f.txt: {person, "kalle", 25}.
<p>The same as <c>eval/1</c>, but the variable bindings
<c><anno>Bindings</anno></c> are used in the evaluation. For information
about the variable bindings, see
- <seealso marker="stdlib:erl_eval"><c>stdlib:erl_eval(3)</c></seealso>.</p>
+ <seealso marker="stdlib:erl_eval"><c>erl_eval(3)</c></seealso>.</p>
</desc>
</func>
<func>
@@ -830,7 +830,7 @@ f.txt: {person, "kalle", 25}.
this module (<c>file</c>) for reading and writing data as the interfaces
provided here work with byte-oriented data. Using other (Unicode)
encodings makes the
- <seealso marker="stdlib:io"><c>stdlib:io(3)</c></seealso> functions
+ <seealso marker="stdlib:io"><c>io(3)</c></seealso> functions
<c>get_chars</c>, <c>get_line</c>, and <c>put_chars</c> more suitable,
as they can work with the full Unicode range.</p>
<p>If data is sent to an <c>io_device()</c> in a format that cannot be
@@ -847,7 +847,7 @@ f.txt: {person, "kalle", 25}.
that is,
<seealso marker="#read/2"><c>read/2</c></seealso> are
returned "as is". If module
- <seealso marker="stdlib:io"><c>stdlib:io(3)</c></seealso> is used for
+ <seealso marker="stdlib:io"><c>io(3)</c></seealso> is used for
writing, the file can only cope with Unicode characters up to code point
255 (the ISO Latin-1 range).</p>
</item>
@@ -861,7 +861,7 @@ f.txt: {person, "kalle", 25}.
the file lies beyond the ISO Latin-1 range (0..255), but failure occurs
if the data contains Unicode code points beyond that range. The file is
best read with the functions in the Unicode aware module
- <seealso marker="stdlib:io"><c>stdlib:io(3)</c></seealso>.</p>
+ <seealso marker="stdlib:io"><c>io(3)</c></seealso>.</p>
<p>Bytes written to the file by any means are translated to UTF-8 encoding
before being stored on the disk file.</p>
</item>
@@ -891,7 +891,7 @@ f.txt: {person, "kalle", 25}.
So a file can be analyzed in latin1 encoding for, for example, a BOM,
positioned beyond the BOM and then be set for the right encoding before
further reading. For functions identifying BOMs, see module
- <seealso marker="stdlib:unicode"><c>stdlib:unicode(3)</c></seealso>. </p>
+ <seealso marker="stdlib:unicode"><c>unicode(3)</c></seealso>. </p>
<p>This option is not allowed on <c>raw</c> files.</p>
</item>
<tag><c>ram</c></tag>
@@ -932,7 +932,7 @@ f.txt: {person, "kalle", 25}.
closed and the process itself is terminated.
An <c><anno>IoDevice</anno></c> returned from this call can be used
as an argument to the I/O functions (see
- <seealso marker="stdlib:io"><c>stdlib:io(3)</c></seealso>).</p>
+ <seealso marker="stdlib:io"><c>io(3)</c></seealso>).</p>
<note>
<p>In previous versions of <c>file</c>, modes were specified
as one of the atoms <c>read</c>, <c>write</c>, or
@@ -1055,7 +1055,7 @@ f.txt: {person, "kalle", 25}.
</taglist>
<p>The encoding of <c><anno>Filename</anno></c> can be set
by a comment as described in
- <seealso marker="stdlib:epp#encoding"><c>stdlib:epp(3)</c></seealso>.</p>
+ <seealso marker="stdlib:epp#encoding"><c>epp(3)</c></seealso>.</p>
</desc>
</func>
<func>
@@ -1128,7 +1128,7 @@ f.txt: {person, "kalle", 25}.
</taglist>
<p>The encoding of <c><anno>Filename</anno></c> can be set
by a comment as described in
- <seealso marker="stdlib:epp#encoding"><c>stdlib:epp(3)</c></seealso>.</p>
+ <seealso marker="stdlib:epp#encoding"><c>epp(3)</c></seealso>.</p>
</desc>
</func>
<func>
@@ -1389,7 +1389,7 @@ f.txt: {person, "kalle", 25}.
<c>{ok, <anno>FileInfo</anno>}</c> if successful, otherwise
<c>{error, <anno>Reason</anno>}</c>. <c><anno>FileInfo</anno></c>
is a record
- <c>file_info</c>, defined in the <c>Kernel</c> include file
+ <c>file_info</c>, defined in the Kernel include file
<c>file.hrl</c>. Include the following directive in the module
from which the function is called:</p>
<code type="none">
@@ -1477,8 +1477,8 @@ f.txt: {person, "kalle", 25}.
<tag><c>16#400</c></tag>
<item><p>set group id on execution</p></item>
</taglist>
- <p>On Unix platforms, the following bits
- can also be set:</p>
+ <p>On Unix platforms, other bits than those listed above
+ may be set.</p>
</item>
<tag><c>links = integer() >= 0</c></tag>
<item>
@@ -1552,7 +1552,7 @@ f.txt: {person, "kalle", 25}.
raw line-oriented reading.</p>
<p>If <c>encoding</c> is set to something else than <c>latin1</c>, the
<c>read_line/1</c> call fails if the data contains characters larger than 255,
- why module <seealso marker="stdlib:io"><c>stdlib:io(3)</c></seealso> is to be
+ why module <seealso marker="stdlib:io"><c>io(3)</c></seealso> is to be
preferred when reading such a file.</p>
<p>The function returns:</p>
<taglist>
@@ -1970,7 +1970,7 @@ f.txt: {person, "kalle", 25}.
<p>Changes file information. Returns <c>ok</c> if successful,
otherwise <c>{error, <anno>Reason</anno>}</c>.
<c><anno>FileInfo</anno></c> is a record
- <c>file_info</c>, defined in the <c>Kernel</c> include file
+ <c>file_info</c>, defined in the Kernel include file
<c>file.hrl</c>. Include the following directive in the module
from which the function is called:</p>
<code type="none">
@@ -2042,8 +2042,8 @@ f.txt: {person, "kalle", 25}.
<tag><c>16#400</c></tag>
<item><p>Set group id on execution</p></item>
</taglist>
- <p>On Unix platforms, the following bits
- can also be set.</p>
+ <p>On Unix platforms, other bits than those listed above
+ may be set.</p>
</item>
<tag><c>uid = integer() >= 0</c></tag>
<item>
diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml
index 83242c2df8..070782e1f3 100644
--- a/lib/kernel/doc/src/gen_tcp.xml
+++ b/lib/kernel/doc/src/gen_tcp.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -140,6 +140,23 @@ do_recv(Sock, Bs) ->
<fsummary>Close a TCP socket.</fsummary>
<desc>
<p>Closes a TCP socket.</p>
+ <p>Note that in most implementations of TCP, doing a <c>close</c> does
+ not guarantee that any data sent is delivered to the recipient before
+ the close is detected at the remote side. If you want to guarantee
+ delivery of the data to the recipient there are two common ways to
+ achieve this.</p>
+ <list type="ordered">
+ <item><p>Use <seealso marker="#shutdown/2">
+ <c>gen_tcp:shutdown(Sock, write)</c></seealso> to signal that
+ no more data is to be sent and wait for the read side of the
+ socket to be closed.</p>
+ </item>
+ <item><p>Use the socket option <seealso marker="inet#packet">
+ <c>{packet, N}</c></seealso> (or something similar) to make
+ it possible for the receiver to close the connection when it
+ knowns it has received all the data.</p>
+ </item>
+ </list>
</desc>
</func>
@@ -216,7 +233,7 @@ do_recv(Sock, Bs) ->
time-out in milliseconds. Defaults to <c>infinity</c>.</p>
<note>
<p>The default values for options specified to <c>connect</c> can
- be affected by the <c>Kernel</c> configuration parameter
+ be affected by the Kernel configuration parameter
<c>inet_default_connect_options</c>. For details, see
<seealso marker="inet"><c>inet(3)</c></seealso>.</p>
</note>
@@ -231,7 +248,11 @@ do_recv(Sock, Bs) ->
<c><anno>Socket</anno></c>. The controlling process is the process
that receives messages from the socket. If called by any other
process than the current controlling process,
- <c>{error, not_owner}</c> is returned.</p>
+ <c>{error, not_owner}</c> is returned. If the process identified
+ by <c><anno>Pid</anno></c> is not an existing local pid,
+ <c>{error, badarg}</c> is returned. <c>{error, badarg}</c> may also
+ be returned in some cases when <c><anno>Socket</anno></c> is closed
+ during the execution of this function.</p>
<p>If the socket is set in active mode, this function
will transfer any messages in the mailbox of the caller
to the new controlling process.
@@ -293,7 +314,7 @@ do_recv(Sock, Bs) ->
<seealso marker="#accept/1"><c>accept/1,2</c></seealso>.</p>
<note>
<p>The default values for options specified to <c>listen</c> can
- be affected by the <c>Kernel</c> configuration parameter
+ be affected by the Kernel configuration parameter
<c>inet_default_listen_options</c>. For details, see
<seealso marker="inet"><c>inet(3)</c></seealso>.</p>
</note>
@@ -307,7 +328,7 @@ do_recv(Sock, Bs) ->
<type_desc variable="HttpPacket">See the description of
<c>HttpPacket</c> in
<seealso marker="erts:erlang#decode_packet/3"><c>erlang:decode_packet/3</c></seealso>
- in <c>ERTS</c>.
+ in ERTS.
</type_desc>
<desc>
<p>Receives a packet from a socket in passive
diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml
index 3f88a0272d..f79566ef71 100644
--- a/lib/kernel/doc/src/gen_udp.xml
+++ b/lib/kernel/doc/src/gen_udp.xml
@@ -68,7 +68,11 @@
<c><anno>Socket</anno></c>. The controlling process is the process
that receives messages from the socket. If called by any other
process than the current controlling process,
- <c>{error, not_owner}</c> is returned.</p>
+ <c>{error, not_owner}</c> is returned. If the process identified
+ by <c><anno>Pid</anno></c> is not an existing local pid,
+ <c>{error, badarg}</c> is returned. <c>{error, badarg}</c> may also
+ be returned in some cases when <c><anno>Socket</anno></c> is closed
+ during the execution of this function.</p>
</desc>
</func>
diff --git a/lib/kernel/doc/src/heart.xml b/lib/kernel/doc/src/heart.xml
index 864f8facac..5b5b71e521 100644
--- a/lib/kernel/doc/src/heart.xml
+++ b/lib/kernel/doc/src/heart.xml
@@ -37,10 +37,7 @@
the <c>heart</c> port program is to check that the Erlang runtime system
it is supervising is still running. If the port program has not
received any heartbeats within <c>HEART_BEAT_TIMEOUT</c> seconds
- (defaults to 60 seconds), the system can be rebooted. Also, if
- the system is equipped with a hardware watchdog timer and is
- running Solaris, the watchdog can be used to supervise the entire
- system.</p>
+ (defaults to 60 seconds), the system can be rebooted.</p>
<p>An Erlang runtime system to be monitored by a heart program
is to be started with command-line flag <c>-heart</c> (see
also <seealso marker="erts:erl"><c>erl(1)</c></seealso>).
@@ -51,17 +48,13 @@
or a terminated Erlang runtime system, environment variable
<c>HEART_COMMAND</c> must be set before the system is started.
If this variable is not set, a warning text is printed but
- the system does not reboot. However, if the hardware watchdog is
- used, it still triggers a reboot <c>HEART_BEAT_BOOT_DELAY</c>
- seconds later (defaults to 60 seconds).</p>
+ the system does not reboot.</p>
<p>To reboot on Windows, <c>HEART_COMMAND</c> can be
set to <c>heart -shutdown</c> (included in the Erlang delivery)
or to any other suitable program that can activate a reboot.</p>
- <p>The hardware watchdog is not started under Solaris if
- environment variable <c>HW_WD_DISABLE</c> is set.</p>
- <p>The environment variables <c>HEART_BEAT_TIMEOUT</c> and
- <c>HEART_BEAT_BOOT_DELAY</c> can be used to configure the heart
- time-outs; they can be set in the operating system shell before Erlang
+ <p>The environment variable <c>HEART_BEAT_TIMEOUT</c>
+ can be used to configure the heart
+ time-outs; it can be set in the operating system shell before Erlang
is started or be specified at the command line:</p>
<pre>
% <input>erl -heart -env HEART_BEAT_TIMEOUT 30 ...</input></pre>
@@ -83,7 +76,7 @@
<c><![CDATA[SIGKILL]]></c>:</p>
<pre>
% <input>erl -heart -env HEART_KILL_SIGNAL SIGABRT ...</input></pre>
- <p> If heart should <b>not</b> kill the Erlang runtime system, this can be indicated
+ <p> If heart should <em>not</em> kill the Erlang runtime system, this can be indicated
using the environment variable <c><![CDATA[HEART_NO_KILL=TRUE]]></c>.
This can be useful if the command executed by heart takes care of this,
for example as part of a specific cleanup sequence.
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index c0dce2f50c..b71e8a1e5d 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -36,7 +36,7 @@
<seealso marker="erts:inet_cfg">ERTS User's Guide:
Inet Configuration</seealso> for more information about how to
configure an Erlang runtime system for IP communication.</p>
- <p>The following two <c>Kernel</c> configuration parameters affect the
+ <p>The following two Kernel configuration parameters affect the
behavior of all sockets opened on an Erlang node:</p>
<list type="bulleted">
<item><p><c>inet_default_connect_options</c> can contain a list of
@@ -48,7 +48,7 @@
<p>When <c>accept</c> is issued, the values of the listening socket options
are inherited. No such application variable is therefore needed for
<c>accept</c>.</p>
- <p>Using the <c>Kernel</c> configuration parameters above, one
+ <p>Using the Kernel configuration parameters above, one
can set default options for all TCP sockets on a node, but use this
with care. Options such as <c>{delay_send,true}</c> can be
specified in this way. The following is an example of starting an Erlang
@@ -75,8 +75,8 @@ Address ip_address()
------- ------------
::1 {0,0,0,0,0,0,0,1}
::192.168.42.2 {0,0,0,0,0,0,(192 bsl 8) bor 168,(42 bsl 8) bor 2}
-FFFF::192.168.42.2
- {16#FFFF,0,0,0,0,0,(192 bsl 8) bor 168,(42 bsl 8) bor 2}
+::FFFF:192.168.42.2
+ {0,0,0,0,0,16#FFFF,(192 bsl 8) bor 168,(42 bsl 8) bor 2}
3ffe:b80:1f8d:2:204:acff:fe17:bf38
{16#3ffe,16#b80,16#1f8d,16#2,16#204,16#acff,16#fe17,16#bf38}
fe80::204:acff:fe17:bf38
@@ -87,15 +87,15 @@ fe80::204:acff:fe17:bf38
<pre>
1> <input>inet:parse_address("192.168.42.2").</input>
{ok,{192,168,42,2}}
-2> <input>inet:parse_address("FFFF::192.168.42.2").</input>
-{ok,{65535,0,0,0,0,0,49320,10754}}</pre>
+2> <input>inet:parse_address("::FFFF:192.168.42.2").</input>
+{ok,{0,0,0,0,0,65535,49320,10754}}</pre>
</description>
<datatypes>
<datatype>
<name name="hostent"/>
<desc>
- <p>The record is defined in the <c>Kernel</c> include file
+ <p>The record is defined in the Kernel include file
<c>"inet.hrl"</c>.</p>
<p>Add the following directive to the module:</p>
<code>
@@ -151,6 +151,12 @@ fe80::204:acff:fe17:bf38
<name name="socket_address"/>
</datatype>
<datatype>
+ <name name="socket_getopt"/>
+ </datatype>
+ <datatype>
+ <name name="socket_setopt"/>
+ </datatype>
+ <datatype>
<name name="returned_non_ip_address"/>
<desc>
<p>
@@ -327,8 +333,6 @@ fe80::204:acff:fe17:bf38
<func>
<name name="getopts" arity="2"/>
<fsummary>Get one or more options for a socket.</fsummary>
- <type name="socket_getopt"/>
- <type name="socket_setopt"/>
<desc>
<p>Gets one or more options for a socket. For a list of available
options, see
@@ -387,7 +391,7 @@ get_tcpi_sacked(Sock) ->
<<_:28/binary,TcpiSacked:32/native,_/binary>> = Info,
TcpiSacked.]]></code>
<p>Preferably, you would check the machine type, the operating system,
- and the <c>Kernel</c> version before executing anything similar to
+ and the Kernel version before executing anything similar to
this code.</p>
</desc>
</func>
@@ -580,7 +584,6 @@ get_tcpi_sacked(Sock) ->
<func>
<name name="setopts" arity="2"/>
<fsummary>Set one or more options for a socket.</fsummary>
- <type name="socket_setopt"/>
<desc>
<p>Sets one or more options for a socket.</p>
<p>The following options are available:</p>
@@ -656,9 +659,10 @@ get_tcpi_sacked(Sock) ->
<tag><c>{buffer, Size}</c></tag>
<item>
<p>The size of the user-level software buffer used by
- the driver. Not to be confused with options <c>sndbuf</c>
+ the driver.
+ Not to be confused with options <c>sndbuf</c>
and <c>recbuf</c>, which correspond to the
- <c>Kernel</c> socket buffers. It is recommended
+ Kernel socket buffers. It is recommended
to have <c>val(buffer) &gt;= max(val(sndbuf),val(recbuf))</c> to
avoid performance issues because of unnecessary copying.
<c>val(buffer)</c> is automatically set to the above
@@ -667,6 +671,9 @@ get_tcpi_sacked(Sock) ->
usually become larger, you are encouraged to use
<seealso marker="#getopts/2"><c>getopts/2</c></seealso>
to analyze the behavior of your operating system.</p>
+ <p>Note that this is also the maximum amount of data that can be
+ received from a single recv call. If you are using higher than
+ normal MTU consider setting buffer higher.</p>
</item>
<tag><c>{delay_send, Boolean}</c></tag>
<item>
@@ -717,7 +724,7 @@ get_tcpi_sacked(Sock) ->
<p>The socket message queue is set to a busy
state when the amount of data on the message
queue reaches this limit. Notice that this limit only
- concerns data that has not yet reached the <c>ERTS</c> internal
+ concerns data that has not yet reached the ERTS internal
socket implementation. Defaults to 8 kB.</p>
<p>Senders of data to the socket are suspended if
either the socket message queue is busy or the socket
@@ -733,7 +740,7 @@ get_tcpi_sacked(Sock) ->
<tag><c>{high_watermark, Size}</c> (TCP/IP sockets)</tag>
<item>
<p>The socket is set to a busy state when the amount
- of data queued internally by the <c>ERTS</c> socket implementation
+ of data queued internally by the ERTS socket implementation
reaches this limit. Defaults to 8 kB.</p>
<p>Senders of data to the socket are suspended if
either the socket message queue is busy or the socket
@@ -813,7 +820,7 @@ get_tcpi_sacked(Sock) ->
socket message queue is set in a not busy state when
the amount of data queued in the message queue falls
below this limit. Notice that this limit only concerns data
- that has not yet reached the <c>ERTS</c> internal socket
+ that has not yet reached the ERTS internal socket
implementation. Defaults to 4 kB.</p>
<p>Senders that are suspended because of either a
busy message queue or a busy socket are resumed
@@ -831,7 +838,7 @@ get_tcpi_sacked(Sock) ->
<item>
<p>If the socket is in a busy state, the socket is
set in a not busy state when the amount of data
- queued internally by the <c>ERTS</c> socket implementation
+ queued internally by the ERTS socket implementation
falls below this limit. Defaults to 4 kB.</p>
<p>Senders that are suspended because of a
busy message queue or a busy socket are resumed
@@ -890,6 +897,32 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp</code>
<seealso marker="file#native_name_encoding/0"><c>file:native_name_encoding/0</c></seealso>.</p></item>
</list>
</item>
+ <tag><c>{bind_to_device, Ifname :: binary()}</c></tag>
+ <item>
+ <p>Binds a socket to a specific network interface. This option
+ must be used in a function call that creates a socket, that is,
+ <seealso marker="gen_tcp#connect/3"><c>gen_tcp:connect/3,4</c></seealso>,
+ <seealso marker="gen_tcp#listen/2"><c>gen_tcp:listen/2</c></seealso>,
+ <seealso marker="gen_udp#open/1"><c>gen_udp:open/1,2</c></seealso>, or
+ <seealso marker="gen_sctp#open/0"><c>gen_sctp:open/0,1,2</c></seealso>.</p>
+ <p>Unlike <seealso marker="#getifaddrs/0"><c>getifaddrs/0</c></seealso>, Ifname
+ is encoded a binary. In the unlikely case that a system is using
+ non-7-bit-ASCII characters in network device names, special care
+ has to be taken when encoding this argument.</p>
+ <p>This option uses the Linux-specific socket option
+ <c>SO_BINDTODEVICE</c>, such as in Linux kernel 2.0.30 or later,
+ and therefore only exists when the runtime system
+ is compiled for such an operating system.</p>
+ <p>Before Linux 3.8, this socket option could be set, but could not retrieved
+ with <seealso marker="#getopts/2"><c>getopts/2</c></seealso>. Since Linux 3.8,
+ it is readable.</p>
+ <p>The virtual machine also needs elevated privileges, either
+ running as superuser or (for Linux) having capability
+ <c>CAP_NET_RAW</c>.</p>
+ <p>The primary use case for this option is to bind sockets into
+ <url href="http://www.kernel.org/doc/Documentation/networking/vrf.txt">Linux VRF instances</url>.
+ </p>
+ </item>
<tag><c>list</c></tag>
<item>
<p>Received <c>Packet</c> is delivered as a list.</p>
@@ -906,7 +939,7 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp</code>
</item>
<tag><c>{packet, PacketType}</c>(TCP/IP sockets)</tag>
<item>
- <p>Defines the type of packets to use for a socket.
+ <p><marker id="packet"/>Defines the type of packets to use for a socket.
Possible values:</p>
<taglist>
<tag><c>raw | 0</c></tag>
@@ -951,7 +984,7 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp</code>
are returned with the format according to <c>HttpPacket</c>
described in
<seealso marker="erts:erlang#decode_packet/3">
- <c>erlang:decode_packet/3</c></seealso> in <c>ERTS</c>.
+ <c>erlang:decode_packet/3</c></seealso> in ERTS.
A socket in passive
mode returns <c>{ok, HttpPacket}</c> from <c>gen_tcp:recv</c>
while an active socket sends messages like
@@ -984,11 +1017,6 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp</code>
<p>Sets the line delimiting character for line-oriented protocols
(<c>line</c>). Defaults to <c>$\n</c>.</p>
</item>
- <tag><c>{priority, Priority}</c></tag>
- <item>
- <p>Sets the protocol-defined priority for all packets to be sent
- on this socket.</p>
- </item>
<tag><c>{raw, Protocol, OptionNum, ValueBin}</c></tag>
<item>
<p>See below.</p>
@@ -1089,6 +1117,15 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp</code>
The option is ignored on platforms where it is not
implemented. Use with caution.</p>
</item>
+ <tag><c>{tclass, Integer}</c></tag>
+ <item>
+ <p>
+ Sets <c>IPV6_TCLASS IP</c> level options on platforms
+ where this is implemented. The behavior and allowed range
+ varies between different systems.
+ The option is ignored on platforms where it is not
+ implemented. Use with caution.</p>
+ </item>
</taglist>
<p>In addition to these options, <em>raw</em>
option specifications can be used. The raw options are
@@ -1127,7 +1164,7 @@ inet:setopts(Sock,[{raw,6,8,<<30:32/native>>}]),]]></code>
can respond differently to this kind of option
manipulation. Use with care.</p>
<p>Notice that the default options for TCP/IP sockets can be
- changed with the <c>Kernel</c> configuration parameters mentioned in
+ changed with the Kernel configuration parameters mentioned in
the beginning of this manual page.</p>
</desc>
</func>
diff --git a/lib/kernel/doc/src/init_stub.xml b/lib/kernel/doc/src/init_stub.xml
index df89b174ca..1297c8264d 100644
--- a/lib/kernel/doc/src/init_stub.xml
+++ b/lib/kernel/doc/src/init_stub.xml
@@ -34,6 +34,6 @@
<modulesummary>Coordination of system startup.</modulesummary>
<description>
<p>This module is moved to the
- <seealso marker="erts:init"><c>ERTS</c></seealso> application.</p>
+ <seealso marker="erts:init">ERTS</seealso> application.</p>
</description>
</erlref>
diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml
index 9e6fb60bb7..e5ac031539 100644
--- a/lib/kernel/doc/src/kernel_app.xml
+++ b/lib/kernel/doc/src/kernel_app.xml
@@ -4,14 +4,14 @@
<appref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>kernel</title>
@@ -31,12 +31,12 @@
<app>kernel</app>
<appsummary>The Kernel application.</appsummary>
<description>
- <p>The <c>Kernel</c> application has all the code necessary to run
+ <p>The Kernel application has all the code necessary to run
the Erlang runtime system: file servers, code servers,
and so on.</p>
- <p>The <c>Kernel</c> application is the first application started. It is
+ <p>The Kernel application is the first application started. It is
mandatory in the sense that the minimal system based on
- Erlang/OTP consists of <c>Kernel</c> and <c>STDLIB</c>. <c>Kernel</c>
+ Erlang/OTP consists of Kernel and STDLIB. Kernel
contains the following functional areas:</p>
<list type="bulleted">
<item>Start, stop, supervision, configuration, and distribution of applications</item>
@@ -53,13 +53,68 @@
<section>
<title>Error Logger Event Handlers</title>
<p>Two standard error logger event handlers are defined in
- the <c>Kernel</c> application. These are described in
+ the Kernel application. These are described in
<seealso marker="error_logger"><c>error_logger(3)</c></seealso>.</p>
</section>
<section>
+ <marker id="erl_signal_server"/>
+ <title>OS Signal Event Handler</title>
+ <p>Asynchronous OS signals may be subscribed to via the Kernel applications event manager
+ (see <seealso marker="doc/design_principles:des_princ">OTP Design Principles</seealso> and
+ <seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso>) registered as <c>erl_signal_server</c>.
+ A default signal handler is installed which handles the following signals:</p>
+ <taglist>
+ <tag><c>sigusr1</c></tag>
+ <item><p>The default handler will halt Erlang and produce a crashdump
+ with slogan "Received SIGUSR1".
+ This is equivalent to calling <c>erlang:halt("Received SIGUSR1")</c>.
+ </p></item>
+
+ <tag><c>sigquit</c></tag>
+ <item><p>The default handler will halt Erlang immediately.
+ This is equivalent to calling <c>erlang:halt()</c>.
+ </p></item>
+
+ <tag><c>sigterm</c></tag>
+ <item><p>The default handler will terminate Erlang normally.
+ This is equivalent to calling <c>init:stop()</c>.
+ </p></item>
+ </taglist>
+
+ <section>
+ <title>Events</title>
+ <p>Any event handler added to <c>erl_signal_server</c> must handle the following events.</p>
+ <taglist>
+ <tag><c>sighup</c></tag>
+ <item><p>Hangup detected on controlling terminal or death of controlling process</p></item>
+ <tag><c>sigquit</c></tag>
+ <item><p>Quit from keyboard</p></item>
+ <tag><c>sigabrt</c></tag>
+ <item><p>Abort signal from abort</p></item>
+ <tag><c>sigalrm</c></tag>
+ <item><p>Timer signal from alarm</p></item>
+ <tag><c>sigterm</c></tag>
+ <item><p>Termination signal</p></item>
+ <tag><c>sigusr1</c></tag>
+ <item><p>User-defined signal 1</p></item>
+ <tag><c>sigusr2</c></tag>
+ <item><p>User-defined signal 2</p></item>
+ <tag><c>sigchld</c></tag>
+ <item><p>Child process stopped or terminated</p></item>
+ <tag><c>sigstop</c></tag>
+ <item><p>Stop process</p></item>
+ <tag><c>sigtstp</c></tag>
+ <item><p>Stop typed at terminal</p></item>
+ </taglist>
+
+ <p>Setting OS signals are described in <seealso marker="os#set_signal/2"><c>os:set_signal/2</c></seealso>.</p>
+ </section>
+ </section>
+
+ <section>
<title>Configuration</title>
- <p>The following configuration parameters are defined for the <c>Kernel</c>
+ <p>The following configuration parameters are defined for the Kernel
application. For more information about configuration parameters,
see file <seealso marker="app"><c>app(4)</c></seealso>.</p>
<taglist>
@@ -131,7 +186,7 @@
<tag><c>{file, FileName}</c></tag>
<item><p>Installs the standard event handler, which prints error
reports to file <c>FileName</c>, where <c>FileName</c>
- is a string.</p></item>
+ is a string. The file is opened with encoding UTF-8.</p></item>
<tag><c>false</c></tag>
<item>
<p>No standard event handler is installed, but
@@ -162,8 +217,8 @@
depth to which terms are printed by the error logger event
handlers included in OTP. This
configuration parameter is used by the two event handlers
- defined by the <c>Kernel</c> application and the two event
- handlers in the <c>SASL</c> application.
+ defined by the Kernel application and the two event
+ handlers in the SASL application.
(If you have implemented your own error handlers, this configuration
parameter has no effect on them.)</p>
@@ -173,7 +228,7 @@
<c>~P</c> and <c>~W</c>, respectively, and <c>Depth</c> is
used as the depth parameter. For details, see
<seealso marker="stdlib:io#format/2"><c>io:format/2</c></seealso>
- in <c>STDLIB</c>.</p>
+ in STDLIB.</p>
<note><p>A reasonable starting value for <c>Depth</c> is
<c>30</c>. We recommend to test crashing various processes in your
@@ -217,12 +272,14 @@
</item>
<tag><c>{inet_dist_listen_options, Opts}</c></tag>
<item>
+ <marker id="inet_dist_listen_options"></marker>
<p>Defines a list of extra socket options to be used when opening the
listening socket for a distributed Erlang node.
See <seealso marker="gen_tcp#listen/2"><c>gen_tcp:listen/2</c></seealso>.</p>
</item>
<tag><c>{inet_dist_connect_options, Opts}</c></tag>
<item>
+ <marker id="inet_dist_connect_options"></marker>
<p>Defines a list of extra socket options to be used when connecting to
other distributed Erlang nodes.
See <seealso marker="gen_tcp#connect/4"><c>gen_tcp:connect/4</c></seealso>.</p>
@@ -239,7 +296,7 @@
<p>The name (string) of an Inet user configuration file. For details,
see section
<seealso marker="erts:inet_cfg"><c>Inet Configuration</c></seealso>
- in the <c>ERTS</c> User's Guide.</p>
+ in the ERTS User's Guide.</p>
</item>
<tag><c>net_setuptime = SetupTime</c></tag>
<item>
@@ -358,11 +415,34 @@ MaxT = TickTime + TickTime / 4</code>
<tag><c>start_timer = true | false</c></tag>
<item>
<p>Starts the <c>timer_server</c> if the parameter is
- <c>true</c> (see <seealso marker="stdlib:timer"><c>stdlib:timer(3)</c></seealso>).
+ <c>true</c> (see <seealso marker="stdlib:timer"><c>timer(3)</c></seealso>).
This parameter is to be set to <c>true</c> in an embedded system
using this service.</p>
<p>Defaults to <c>false</c>.</p>
</item>
+ <tag><c>shell_history = enabled | disabled </c></tag>
+ <item>
+ <p>Specifies whether shell history should be logged to disk
+ between usages of <c>erl</c>.</p>
+ </item>
+ <tag><c>shell_history_drop = [string()]</c></tag>
+ <item>
+ <p>Specific log lines that should not be persisted. For
+ example <c>["q().", "init:stop()."]</c> will allow to
+ ignore commands that shut the node down. Defaults to
+ <c>[]</c>.</p>
+ </item>
+ <tag><c>shell_history_file_bytes = integer()</c></tag>
+ <item>
+ <p>how many bytes the shell should remember. By default, the
+ value is set to 512kb, and the minimal value is 50kb.</p>
+ </item>
+ <tag><c>shell_history_path = string()</c></tag>
+ <item>
+ <p>Specifies where the shell history files will be stored.
+ defaults to the user's cache directory as returned by
+ <c>filename:basedir(user_cache, "erlang-history")</c>.</p>
+ </item>
<tag><c>shutdown_func = {Mod, Func}</c></tag>
<item>
<p>Where:</p>
@@ -377,6 +457,28 @@ MaxT = TickTime + TickTime / 4</code>
return as soon as possible for <c>application_controller</c>
to terminate properly.</p>
</item>
+ <tag><c>source_search_rules = [DirRule] | [SuffixRule] </c></tag>
+ <item>
+ <marker id="source_search_rules"></marker>
+ <p>Where:</p>
+ <list type="bulleted">
+ <item><c>DirRule = {ObjDirSuffix,SrcDirSuffix}</c></item>
+ <item><c>SuffixRule = {ObjSuffix,SrcSuffix,[DirRule]}</c></item>
+ <item><c>ObjDirSuffix = string()</c></item>
+ <item><c>SrcDirSuffix = string()</c></item>
+ <item><c>ObjSuffix = string()</c></item>
+ <item><c>SrcSuffix = string()</c></item>
+ </list>
+ <p>Specifies a list of rules for use by <c>filelib:find_file/2</c> and
+ <c>filelib:find_source/2</c>. If this is set to some other value
+ than the empty list, it replaces the default rules. Rules can be
+ simple pairs of directory suffixes, such as <c>{"ebin",
+ "src"}</c>, which are used by <c>filelib:find_file/2</c>, or
+ triples specifying separate directory suffix rules depending on
+ file name extensions, for example <c>[{".beam", ".erl", [{"ebin",
+ "src"}]}</c>, which are used by <c>filelib:find_source/2</c>. Both
+ kinds of rules can be mixed in the list.</p>
+ </item>
</taglist>
</section>
@@ -403,4 +505,3 @@ MaxT = TickTime + TickTime / 4</code>
<seealso marker="stdlib:timer"><c>timer(3)</c></seealso></p>
</section>
</appref>
-
diff --git a/lib/kernel/doc/src/net_kernel.xml b/lib/kernel/doc/src/net_kernel.xml
index f48a534d4f..0b94fc0fa6 100644
--- a/lib/kernel/doc/src/net_kernel.xml
+++ b/lib/kernel/doc/src/net_kernel.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -55,7 +55,7 @@ $ <input>erl -sname foobar</input></pre>
<seealso marker="erts:erl"><c>erl</c></seealso>.</p>
<p>Normally, connections are established automatically when
another node is referenced. This functionality can be disabled
- by setting <c>Kernel</c> configuration parameter
+ by setting Kernel configuration parameter
<c>dist_auto_connect</c> to <c>false</c>, see
<seealso marker="kernel_app"><c>kernel(6)</c></seealso>. In this case,
connections must be established explicitly by calling
@@ -64,6 +64,19 @@ $ <input>erl -sname foobar</input></pre>
by the magic cookie system, see section
<seealso marker="doc/reference_manual:distributed">Distributed Erlang</seealso>
in the Erlang Reference Manual.</p>
+ <warning>
+ <p>
+ Starting a distributed node without also specifying
+ <seealso marker="erts:erl#proto_dist"><c>-proto_dist inet_tls</c></seealso>
+ will expose the node to attacks that may give the attacker
+ complete access to the node and in extension the cluster.
+ When using un-secure distributed nodes, make sure that the
+ network is configured to keep potential attackers out.
+ See the <seealso marker="ssl:ssl_distribution">
+ Using SSL for Erlang Distribution</seealso> User's Guide
+ for details on how to setup a secure distributed node.
+ </p>
+ </warning>
</description>
<funcs>
@@ -116,6 +129,21 @@ $ <input>erl -sname foobar</input></pre>
</func>
<func>
+ <name name="getopts" arity="2"/>
+ <fsummary>Get distribution socket options.</fsummary>
+ <desc>
+ <p>Get one or more options for the distribution socket
+ connected to <c><anno>Node</anno></c>.</p>
+ <p>If <c><anno>Node</anno></c> is a connected node
+ the return value is the same as from
+ <seealso marker="inet#getopts/2"><c>inet:getopts(Sock, Options)</c></seealso>
+ where <c>Sock</c> is the distribution socket for <c><anno>Node</anno></c>.</p>
+ <p>Returns <c>ignored</c> if the local node is not alive or
+ <c>{error, noconnection}</c> if <c><anno>Node</anno></c> is not connected.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="monitor_nodes" arity="1"/>
<name name="monitor_nodes" arity="2"/>
<fsummary>Subscribe to node status change messages.</fsummary>
@@ -131,7 +159,7 @@ $ <input>erl -sname foobar</input></pre>
are stopped. Two
option lists are considered the same if they contain the same
set of options.</p>
- <p>As from <c>Kernel</c> version 2.11.4, and <c>ERTS</c> version
+ <p>As from Kernel version 2.11.4, and ERTS version
5.5.4, the following is guaranteed:</p>
<list type="bulleted">
<item><p><c>nodeup</c> messages are delivered before delivery
@@ -141,13 +169,13 @@ $ <input>erl -sname foobar</input></pre>
messages from the remote node that have been passed
through the connection have been delivered.</p></item>
</list>
- <p>Notice that this is <em>not</em> guaranteed for <c>Kernel</c>
+ <p>Notice that this is <em>not</em> guaranteed for Kernel
versions before 2.11.4.</p>
- <p>As from <c>Kernel</c> version 2.11.4, subscriptions can also be
+ <p>As from Kernel version 2.11.4, subscriptions can also be
made before the <c>net_kernel</c> server is started, that is,
<c>net_kernel:monitor_nodes/[1,2]</c> does not return
<c>ignored</c>.</p>
- <p>As from <c>Kernel</c> version 2.13, and <c>ERTS</c> version
+ <p>As from Kernel version 2.13, and ERTS version
5.7, the following is guaranteed:</p>
<list type="bulleted">
<item><p><c>nodeup</c> messages are delivered after the
@@ -157,7 +185,7 @@ $ <input>erl -sname foobar</input></pre>
corresponding node has disappeared in results from
<c>erlang:nodes/X</c>.</p></item>
</list>
- <p>Notice that this is <em>not</em> guaranteed for <c>Kernel</c>
+ <p>Notice that this is <em>not</em> guaranteed for Kernel
versions before 2.13.</p>
<p>The format of the node status change messages depends on
<c><anno>Options</anno></c>. If <c><anno>Options</anno></c> is
@@ -289,6 +317,27 @@ $ <input>erl -sname foobar</input></pre>
</func>
<func>
+ <name name="setopts" arity="2"/>
+ <fsummary>Set distribution socket options.</fsummary>
+ <desc>
+ <p>Set one or more options for distribution sockets.
+ Argument <c><anno>Node</anno></c> can be either one node name
+ or the atom <c>new</c> to affect the distribution sockets of all
+ future connected nodes.</p>
+ <p>The return value is the same as from
+ <seealso marker="inet#setopts/2"><c>inet:setopts/2</c></seealso>
+ or <c>{error, noconnection}</c> if <c><anno>Node</anno></c> is not
+ a connected node or <c>new</c>.</p>
+ <p>If <c><anno>Node</anno></c> is <c>new</c> the <c><anno>Options</anno></c>
+ will then also be added to kernel configration parameters
+ <seealso marker="kernel:kernel_app#inet_dist_listen_options">inet_dist_listen_options</seealso>
+ and
+ <seealso marker="kernel:kernel_app#inet_dist_connect_options">inet_dist_connect_options</seealso>.</p>
+ <p>Returns <c>ignored</c> if the local node is not alive.</p>
+ </desc>
+ </func>
+
+ <func>
<name>start([Name]) -> {ok, pid()} | {error, Reason}</name>
<name>start([Name, NameType]) -> {ok, pid()} | {error, Reason}</name>
<name>start([Name, NameType, Ticktime]) -> {ok, pid()} | {error, Reason}</name>
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index f37433110c..e1cf45109d 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,344 @@
</header>
<p>This document describes the changes made to the Kernel application.</p>
+<section><title>Kernel 5.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Function <c>inet:ntoa/1</c> has been fixed to return
+ lowercase letters according to RFC 5935 that has been
+ approved after this function was written. Previously
+ uppercase letters were returned so this may be a
+ backwards incompatible change depending on how the
+ returned address string is used.</p>
+ <p>Function <c>inet:parse_address/1</c> has been fixed to
+ accept %-suffixes on scoped addresses. The addresses does
+ not work yet, but gives no parse errors.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-13006 Aux Id: ERIERL-20, ERL-429 </p>
+ </item>
+ <item>
+ <p>
+ Fix bug where gethostname would incorrectly fail with
+ enametoolong on Linux.</p>
+ <p>
+ Own Id: OTP-14310</p>
+ </item>
+ <item>
+ <p>
+ Fix bug causing <c>code:is_module_native</c> to falsely
+ return true when <c>local</c> call trace is enabled for
+ the module.</p>
+ <p>
+ Own Id: OTP-14390</p>
+ </item>
+ <item>
+ <p>
+ Add early reject of invalid node names from distributed
+ nodes.</p>
+ <p>
+ Own Id: OTP-14426</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Since Unicode is now allowed in atoms an extra check is
+ needed for node names, which are restricted to Latin-1.</p>
+ <p>
+ Own Id: OTP-13805</p>
+ </item>
+ <item>
+ <p>Replaced usage of deprecated symbolic <seealso
+ marker="erts:erlang#type-time_unit"><c>time
+ unit</c></seealso> representations.</p>
+ <p>
+ Own Id: OTP-13831 Aux Id: OTP-13735 </p>
+ </item>
+ <item>
+ <p><c>file:write_file(Name, Data, [raw])</c> would turn
+ <c>Data</c> into a single binary before writing. This
+ meant it could not take advantage of the <c>writev()</c>
+ system call if it was given a list of binaries and told
+ to write with <c>raw</c> mode.</p>
+ <p>
+ Own Id: OTP-13909</p>
+ </item>
+ <item>
+ <p>The performance of the <c>disk_log</c> has been
+ somewhat improved in some corner cases (big items), and
+ the documentation has been clarified. </p>
+ <p>
+ Own Id: OTP-14057 Aux Id: PR-1245 </p>
+ </item>
+ <item>
+ <p>Functions for detecting changed code has been added.
+ <c>code:modified_modules/0</c> returns all currently
+ loaded modules that have changed on disk.
+ <c>code:module_status/1</c> returns the status for a
+ module. In the shell and in <c>c</c> module, <c>mm/0</c>
+ is short for <c>code:modified_modules/0</c>, and
+ <c>lm/0</c> reloads all currently loaded modules that
+ have changed on disk.</p>
+ <p>
+ Own Id: OTP-14059</p>
+ </item>
+ <item>
+ <p>
+ Introduce an event manager in Erlang to handle OS
+ signals. A subset of OS signals may be subscribed to and
+ those are described in the Kernel application.</p>
+ <p>
+ Own Id: OTP-14186</p>
+ </item>
+ <item>
+ <p> Sockets can now be bound to device (SO_BINDTODEVICE)
+ on platforms where it is supported. </p> <p> This has
+ been implemented e.g to support VRF-Lite under Linux; see
+ <url
+ href="https://www.kernel.org/doc/Documentation/networking/vrf.txt">
+ VRF </url>, and GitHub pull request <url
+ href="https://github.com/erlang/otp/pull/1326">#1326</url>.
+ </p>
+ <p>
+ Own Id: OTP-14357 Aux Id: PR-1326 </p>
+ </item>
+ <item>
+ <p>
+ Added option to store shell_history on disk so that the
+ history can be reused between sessions.</p>
+ <p>
+ Own Id: OTP-14409 Aux Id: PR-1420 </p>
+ </item>
+ <item>
+ <p> The size of crash reports created by
+ <c>gen_server</c>, <c>gen_statem</c> and <c>proc_lib</c>
+ is limited with aid of the Kernel application variable
+ <c>error_logger_format_depth</c>. The purpose is to limit
+ the size of the messages sent to the <c>error_logger</c>
+ process when processes with huge message queues or states
+ crash. </p> <p>The crash report generated by
+ <c>proc_lib</c> includes the new tag
+ <c>message_queue_len</c>. The neighbour report also
+ includes the new tag <c>current_stacktrace</c>. Finally,
+ the neighbour report no longer includes the tags
+ <c>messages</c> and <c>dictionary</c>. </p> <p> The new
+ function <c>error_logger:get_format_depth/0</c> can be
+ used to retrieve the value of the Kernel application
+ variable <c>error_logger_format_depth</c>. </p>
+ <p>
+ Own Id: OTP-14417</p>
+ </item>
+ <item>
+ <p> One of the ETS tables used by the <c>global</c>
+ module is created with <c>{read_concurrency, true}</c> in
+ order to reduce contention. </p>
+ <p>
+ Own Id: OTP-14419</p>
+ </item>
+ <item>
+ <p>
+ Warnings have been added to the relevant documentation
+ about not using un-secure distributed nodes in exposed
+ environments.</p>
+ <p>
+ Own Id: OTP-14425</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 5.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix a race during cleanup of os:cmd that would cause
+ os:cmd to hang indefinitely.</p>
+ <p>
+ Own Id: OTP-14232 Aux Id: seq13275 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The functions in the '<c>file</c>' module that take a
+ list of paths (e.g. <c>file:path_consult/2</c>) will now
+ continue to search in the path if the path contains
+ something that is not a directory.</p>
+ <p>
+ Own Id: OTP-14191</p>
+ </item>
+ <item>
+ <p>Two OTP processes that are known to receive many
+ messages are 'rex' (used by 'rpc') and 'error_logger'.
+ Those processes will now store unprocessed messages
+ outside the process heap, which will potentially decrease
+ the cost of garbage collections.</p>
+ <p>
+ Own Id: OTP-14192</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 5.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ <c>code:add_pathsa/1</c> and command line option
+ <c>-pa</c> both revert the given list of directories when
+ adding it at the beginning of the code path. This is now
+ documented.</p>
+ <p>
+ Own Id: OTP-13920 Aux Id: ERL-267 </p>
+ </item>
+ <item>
+ <p>
+ Add lost runtime dependency to erts-8.1. This should have
+ been done in kernel-5.1 (OTP-19.1) as it cannot run
+ without at least erts-8.1 (OTP-19.1).</p>
+ <p>
+ Own Id: OTP-14003</p>
+ </item>
+ <item>
+ <p>
+ Type and doc for gen_{tcp,udp,sctp}:controlling_process/2
+ has been improved.</p>
+ <p>
+ Own Id: OTP-14022 Aux Id: PR-1208 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 5.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix a memory leak when calling
+ seq_trace:get_system_tracer().</p>
+ <p>
+ Own Id: OTP-13742</p>
+ </item>
+ <item>
+ <p>
+ Fix for the problem that when adding the ebin directory
+ of an application to the code path, the
+ <c>code:priv_dir/1</c> function returns an incorrect path
+ to the priv directory of the same application.</p>
+ <p>
+ Own Id: OTP-13758 Aux Id: ERL-195 </p>
+ </item>
+ <item>
+ <p>
+ Fix code_server crash when adding code paths of two
+ levels.</p>
+ <p>
+ Own Id: OTP-13765 Aux Id: ERL-194 </p>
+ </item>
+ <item>
+ <p>
+ Respect -proto_dist switch while connection to EPMD</p>
+ <p>
+ Own Id: OTP-13770 Aux Id: PR-1129 </p>
+ </item>
+ <item>
+ <p>
+ Fixed a bug where init:stop could deadlock if a process
+ with infinite shutdown timeout (e.g. a supervisor)
+ attempted to load code while terminating.</p>
+ <p>
+ Own Id: OTP-13802</p>
+ </item>
+ <item>
+ <p>
+ Close stdin of commands run in os:cmd. This is a
+ backwards compatibility fix that restores the behaviour of
+ pre 19.0 os:cmd.</p>
+ <p>
+ Own Id: OTP-13867 Aux Id: seq13178 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add <c>net_kernel:setopts/2</c> and
+ <c>net_kernel:getopts/2</c> to control options for
+ distribution sockets in runtime.</p>
+ <p>
+ Own Id: OTP-13564</p>
+ </item>
+ <item>
+ <p>
+ Rudimentary support for DSCP has been implemented
+ in the guise of a <c>tclass</c> socket option
+ for IPv6 sockets.</p>
+ <p>
+ Own Id: OTP-13582</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 5.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ When calling os:cmd from a process that has set trap_exit
+ to true an 'EXIT' message would be left in the message
+ queue. This bug was introduced in kernel vsn 5.0.1.</p>
+ <p>
+ Own Id: OTP-13813</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 5.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix a os:cmd bug where creating a background job using
+ &amp; would cause os:cmd to hang until the background job
+ terminated or closed its stdout and stderr file
+ descriptors. This bug has existed from kernel 5.0.</p>
+ <p>
+ Own Id: OTP-13741</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Kernel 5.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -1309,7 +1647,7 @@
dependent, so applications aiming to be portable should
consider using <c>{ipv6_v6only,true}</c> when creating an
<c>inet6</c> listening/destination socket, and if
- neccesary also create an <c>inet</c> socket on the same
+ necessary also create an <c>inet</c> socket on the same
port for IPv4 traffic. See the documentation.</p>
<p>
Own Id: OTP-8928 Aux Id: kunagi-193 [104] </p>
@@ -3447,7 +3785,7 @@
types (for instance, <c>ensure_loaded/1</c> now only
accepts an atom as documented; it used to accept a string
too).</p>
- <p><c>Dialyzer</c> will generally emit warnings for any
+ <p>Dialyzer will generally emit warnings for any
calls that use undocumented argument types. Even if the
call happens to still work in R12B, you should correct
your code. A future release will adhere to the
diff --git a/lib/kernel/doc/src/os.xml b/lib/kernel/doc/src/os.xml
index 739ac35d2a..0e9add4161 100644
--- a/lib/kernel/doc/src/os.xml
+++ b/lib/kernel/doc/src/os.xml
@@ -4,14 +4,14 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>os</title>
@@ -156,6 +156,33 @@ DirOut = os:cmd("dir"), % on Win32 platform</code>
</func>
<func>
+ <name name="set_signal" arity="2"/>
+ <fsummary>Enables or disables handling of OS signals.</fsummary>
+ <desc>
+ <p>Enables or disables OS signals.</p>
+ <p>Each signal my be set to one of the following options:</p>
+ <taglist>
+ <tag><c>ignore</c></tag>
+ <item>
+ This signal will be ignored.
+ </item>
+
+ <tag><c>default</c></tag>
+ <item>
+ This signal will use the default signal handler for the operating system.
+ </item>
+
+ <tag><c>handle</c></tag>
+ <item>
+ This signal will notify
+ <seealso marker="kernel_app#erl_signal_server"><c>erl_signal_server</c></seealso>
+ when it is received by the Erlang runtime system.
+ </item>
+ </taglist>
+ </desc>
+ </func>
+
+ <func>
<name name="system_time" arity="0"/>
<fsummary>Current OS system time.</fsummary>
<desc>
@@ -296,4 +323,3 @@ calendar:now_to_universal_time(TS),
</func>
</funcs>
</erlref>
-
diff --git a/lib/kernel/doc/src/rpc.xml b/lib/kernel/doc/src/rpc.xml
index 8cad9fe4fc..adec2d9520 100644
--- a/lib/kernel/doc/src/rpc.xml
+++ b/lib/kernel/doc/src/rpc.xml
@@ -88,6 +88,12 @@
to retrieve the value of evaluating <c>apply(<anno>Module</anno>,
<anno>Function</anno>, <anno>Args</anno>)</c> on node
<c><anno>Node</anno></c>.</p>
+ <note>
+ <p><seealso marker="#yield/1"><c>yield/1</c></seealso> and
+ <seealso marker="#nb_yield/1"><c>nb_yield/1,2</c></seealso>
+ must be called by the same process from which this function
+ was made otherwise they will never yield correctly.</p>
+ </note>
</desc>
</func>
@@ -299,6 +305,11 @@
the tuple <c>{value, <anno>Val</anno>}</c> when the computation is
finished, or <c>timeout</c> when <c><anno>Timeout</anno></c>
milliseconds has elapsed.</p>
+ <note>
+ <p>This function must be called by the same process from which
+ <seealso marker="#async_call/4"><c>async_call/4</c></seealso>
+ was made otherwise it will only return <c>timeout</c>.</p>
+ </note>
</desc>
</func>
@@ -320,7 +331,7 @@
<fsummary>Information about a process.</fsummary>
<desc>
<p>Location transparent version of the BIF
- <seealso marker="erts:erlang#process_info/1"><c>erlang:process_info/1</c></seealso> in <c>ERTS</c>.</p>
+ <seealso marker="erts:erlang#process_info/1"><c>erlang:process_info/1</c></seealso> in ERTS.</p>
</desc>
</func>
@@ -330,7 +341,7 @@
<fsummary>Information about a process.</fsummary>
<desc>
<p>Location transparent version of the BIF
- <seealso marker="erts:erlang#process_info/2"><c>erlang:process_info/2</c></seealso> in <c>ERTS</c>.</p>
+ <seealso marker="erts:erlang#process_info/2"><c>erlang:process_info/2</c></seealso> in ERTS.</p>
</desc>
</func>
@@ -407,6 +418,11 @@
If the answer is available, it is
returned immediately. Otherwise, the calling process is
suspended until the answer arrives from <c>Node</c>.</p>
+ <note>
+ <p>This function must be called by the same process from which
+ <seealso marker="#async_call/4"><c>async_call/4</c></seealso>
+ was made otherwise it will never return.</p>
+ </note>
</desc>
</func>
</funcs>
diff --git a/lib/kernel/doc/src/seq_trace.xml b/lib/kernel/doc/src/seq_trace.xml
index 5ac199b6a7..197851021f 100644
--- a/lib/kernel/doc/src/seq_trace.xml
+++ b/lib/kernel/doc/src/seq_trace.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1998</year><year>2016</year>
+ <year>1998</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -129,7 +129,7 @@ seq_trace:set_token(OldToken), % activate the trace token again
<seealso marker="erts:time_correction#Erlang_Monotonic_Time">Erlang
monotonic time</seealso> and a monotonically increasing
integer. The time-stamp has the same format and value
- as produced by <c>{erlang:monotonic_time(nano_seconds),
+ as produced by <c>{erlang:monotonic_time(nanosecond),
erlang:unique_integer([monotonic])}</c>.</p>
</item>
<tag><c>set_token(monotonic_timestamp, <anno>Bool</anno>)</c></tag>
@@ -141,7 +141,7 @@ seq_trace:set_token(OldToken), % activate the trace token again
<seealso marker="erts:time_correction#Erlang_Monotonic_Time">Erlang
monotonic time</seealso>. The time-stamp has the same
format and value as produced by
- <c>erlang:monotonic_time(nano_seconds)</c>.</p>
+ <c>erlang:monotonic_time(nanosecond)</c>.</p>
</item>
</taglist>
<p>If multiple timestamp flags are passed, <c>timestamp</c> has
@@ -427,12 +427,6 @@ prev_cnt := tcurr</code>
built with <c>Erl_Interface</c> only maintains one trace token, which
means that the C-node appears as one process from
the sequential tracing point of view.</p>
- <p>To be able to perform sequential tracing between
- distributed Erlang nodes, the distribution protocol has been
- extended (in a backward compatible way). An Erlang node
- supporting sequential tracing can communicate with an older
- (Erlang/OTP R3B) node but messages passed within that node can
- not be traced.</p>
</section>
<section>
diff --git a/lib/kernel/doc/src/zlib_stub.xml b/lib/kernel/doc/src/zlib_stub.xml
index b111581b10..9ab9c4eb62 100644
--- a/lib/kernel/doc/src/zlib_stub.xml
+++ b/lib/kernel/doc/src/zlib_stub.xml
@@ -34,6 +34,6 @@
<modulesummary>Zlib compression interface.</modulesummary>
<description>
<p>This module is moved to the
- <seealso marker="erts:zlib"><c>ERTS</c></seealso> application.</p>
+ <seealso marker="erts:zlib">ERTS</seealso> application.</p>
</description>
</erlref>
diff --git a/lib/kernel/include/dist_util.hrl b/lib/kernel/include/dist_util.hrl
index 43e50d4325..e3d2fe0eb6 100644
--- a/lib/kernel/include/dist_util.hrl
+++ b/lib/kernel/include/dist_util.hrl
@@ -29,7 +29,7 @@
-endif.
-ifdef(dist_trace).
--define(trace(Fmt,Args), io:format("~p ~p:~s",[erlang:now(),node(),lists:flatten(io_lib:format(Fmt, Args))])).
+-define(trace(Fmt,Args), io:format("~p ~p:~s",[erlang:timestamp(),node(),lists:flatten(io_lib:format(Fmt, Args))])).
% Use the one below for config-file (early boot) connection tracing
%-define(trace(Fmt,Args), erlang:display([erlang:now(),node(),lists:flatten(io_lib:format(Fmt, Args))])).
-define(trace_factor,8).
@@ -63,7 +63,7 @@
f_getll, %% Get low level port or pid.
f_address, %% The address of the "socket",
%% generated from Socket,Node
- %% These two are used in the tick loop,
+ %% These three are used in the tick loop,
%% so they are not fun's to avoid holding old code.
mf_tick, %% Takes the socket as parameters and
%% sends a tick, this is no fun, it
@@ -74,7 +74,11 @@
%% {ok, RecvCnt, SendCnt, SendPend} for
%% a given socket. This is a {M,F},
%% returning {error, Reason on failure}
- request_type = normal
+ request_type = normal,
+
+ %% New in kernel-5.1 (OTP 19.1):
+ mf_setopts, %% netkernel:setopts on active connection
+ mf_getopts %% netkernel:getopts on active connection
}).
diff --git a/lib/kernel/include/inet.hrl b/lib/kernel/include/inet.hrl
index b39df8c3f2..daa2e14b46 100644
--- a/lib/kernel/include/inet.hrl
+++ b/lib/kernel/include/inet.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@
-record(hostent,
{
- h_name :: inet:hostname(), %% offical name of host
+ h_name :: inet:hostname(), %% official name of host
h_aliases = [] :: [inet:hostname()], %% alias list
h_addrtype :: 'inet' | 'inet6', %% host address type
h_length :: non_neg_integer(), %% length of address
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index 2b72f78dcf..5946620f0f 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2016. All Rights Reserved.
+# Copyright Ericsson AB 1996-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -71,6 +71,7 @@ MODULES = \
erl_distribution \
erl_epmd \
erl_reply \
+ erl_signal_handler \
erts_debug \
error_handler \
error_logger \
@@ -84,6 +85,7 @@ MODULES = \
global_group \
global_search \
group \
+ group_history \
heart \
hipe_unified_loader \
inet \
diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl
index 0e61153613..3b642f5873 100644
--- a/lib/kernel/src/application_controller.erl
+++ b/lib/kernel/src/application_controller.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1620,7 +1620,7 @@ conv(_) -> [].
make_term(Str) ->
case erl_scan:string(Str) of
{ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens ++ [{dot, 1}]) of
+ case erl_parse:parse_term(Tokens ++ [{dot, erl_anno:new(1)}]) of
{ok, Term} ->
Term;
{error, {_,M,Reason}} ->
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index 8d0a2fbf66..9969021a6c 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -70,7 +70,9 @@
where_is_file/2,
set_primary_archive/4,
clash/0,
- get_mode/0]).
+ module_status/1,
+ modified_modules/0,
+ get_mode/0]).
-deprecated({rehash,0,next_major_release}).
@@ -116,8 +118,8 @@ get_chunk(_, _) ->
is_module_native(_) ->
erlang:nif_error(undef).
--spec make_stub_module(Module, Beam, Info) -> Module when
- Module :: module(),
+-spec make_stub_module(LoaderState, Beam, Info) -> module() when
+ LoaderState :: binary(),
Beam :: binary(),
Info :: {list(), list(), binary()}.
@@ -487,13 +489,13 @@ prepare_check_uniq_1([], [_|_]=Errors) ->
{error,Errors}.
partition_on_load(Prep) ->
- P = fun({_,{Bin,_,_}}) ->
- erlang:has_prepared_code_on_load(Bin)
+ P = fun({_,{PC,_,_}}) ->
+ erlang:has_prepared_code_on_load(PC)
end,
lists:partition(P, Prep).
verify_prepared([{M,{Prep,Name,_Native}}|T])
- when is_atom(M), is_binary(Prep), is_list(Name) ->
+ when is_atom(M), is_list(Name) ->
try erlang:has_prepared_code_on_load(Prep) of
false ->
verify_prepared(T);
@@ -560,10 +562,10 @@ prepare_loading_fun() ->
GetNative = get_native_fun(),
fun(Mod, FullName, Beam) ->
case erlang:prepare_loading(Mod, Beam) of
- Prepared when is_binary(Prepared) ->
- {ok,{Prepared,FullName,GetNative(Beam)}};
{error,_}=Error ->
- Error
+ Error;
+ Prepared ->
+ {ok,{Prepared,FullName,GetNative(Beam)}}
end
end.
@@ -719,38 +721,14 @@ start_get_mode() ->
which(Module) when is_atom(Module) ->
case is_loaded(Module) of
false ->
- which2(Module);
+ which(Module, get_path());
{file, File} ->
File
end.
-which2(Module) ->
- Base = atom_to_list(Module),
- File = filename:basename(Base) ++ objfile_extension(),
- Path = get_path(),
- which(File, filename:dirname(Base), Path).
-
--spec which(file:filename(), file:filename(), [file:filename()]) ->
- 'non_existing' | file:filename().
-
-which(_, _, []) ->
- non_existing;
-which(File, Base, [Directory|Tail]) ->
- Path = if
- Base =:= "." -> Directory;
- true -> filename:join(Directory, Base)
- end,
- case erl_prim_loader:list_dir(Path) of
- {ok,Files} ->
- case lists:member(File,Files) of
- true ->
- filename:append(Path, File);
- false ->
- which(File, Base, Tail)
- end;
- _Error ->
- which(File, Base, Tail)
- end.
+which(Module, Path) when is_atom(Module) ->
+ File = atom_to_list(Module) ++ objfile_extension(),
+ where_is_file(Path, File).
%% Search the code path for a specific file. Try to locate
%% it in the code path cache if possible.
@@ -760,13 +738,33 @@ which(File, Base, [Directory|Tail]) ->
Absname :: file:filename().
where_is_file(File) when is_list(File) ->
Path = get_path(),
- which(File, ".", Path).
+ where_is_file(Path, File).
--spec where_is_file(Path :: file:filename(), Filename :: file:filename()) ->
- file:filename() | 'non_existing'.
+%% To avoid unnecessary work when looking at many modules, this also
+%% accepts pairs of directories and pre-fetched contents in the path
+-spec where_is_file(Path :: [Dir|{Dir,Files}], Filename :: file:filename()) ->
+ 'non_existing' | file:filename() when
+ Dir :: file:filename(), Files :: [file:filename()].
-where_is_file(Path, File) when is_list(Path), is_list(File) ->
- which(File, ".", Path).
+where_is_file([], _) ->
+ non_existing;
+where_is_file([{Path, Files}|Tail], File) ->
+ where_is_file(Tail, File, Path, Files);
+where_is_file([Path|Tail], File) ->
+ case erl_prim_loader:list_dir(Path) of
+ {ok,Files} ->
+ where_is_file(Tail, File, Path, Files);
+ _Error ->
+ where_is_file(Tail, File)
+ end.
+
+where_is_file(Tail, File, Path, Files) ->
+ case lists:member(File, Files) of
+ true ->
+ filename:append(Path, File);
+ false ->
+ where_is_file(Tail, File)
+ end.
-spec set_primary_archive(ArchiveFile :: file:filename(),
ArchiveBin :: binary(),
@@ -899,3 +897,97 @@ load_all_native_1([{Mod,BeamFilename}|T], ChunkTag) ->
load_all_native_1(T, ChunkTag);
load_all_native_1([], _) ->
ok.
+
+%% Returns the status of the module in relation to object file on disk.
+-spec module_status(Module :: module()) -> not_loaded | loaded | modified | removed.
+module_status(Module) ->
+ module_status(Module, code:get_path()).
+
+%% Note that we don't want to go via which/1, since it doesn't look at the
+%% disk contents at all if the module is already loaded.
+module_status(Module, PathFiles) ->
+ case code:is_loaded(Module) of
+ false -> not_loaded;
+ {file, preloaded} -> loaded;
+ {file, cover_compiled} ->
+ %% cover compilation loads directly to memory and does not
+ %% create a beam file, so report 'modified' if a file exists
+ case which(Module, PathFiles) of
+ non_existing -> removed;
+ _File -> modified
+ end;
+ {file, []} -> loaded; % no beam file - generated code
+ {file, OldFile} when is_list(OldFile) ->
+ %% we don't care whether or not the file is in the same location
+ %% as when last loaded, as long as it can be found in the path
+ case which(Module, PathFiles) of
+ non_existing -> removed;
+ Path ->
+ case module_changed_on_disk(Module, Path) of
+ true -> modified;
+ false -> loaded
+ end
+ end
+ end.
+
+%% Detects actual code changes only, e.g. to decide whether a module should
+%% be reloaded; does not care about file timestamps or compilation time
+module_changed_on_disk(Module, Path) ->
+ MD5 = erlang:get_module_info(Module, md5),
+ case erlang:system_info(hipe_architecture) of
+ undefined ->
+ %% straightforward, since native is not supported
+ MD5 =/= beam_file_md5(Path);
+ Architecture ->
+ case code:is_module_native(Module) of
+ true ->
+ %% MD5 is for native code, so we check only the native
+ %% code on disk, ignoring the beam code
+ MD5 =/= beam_file_native_md5(Path, Architecture);
+ _ ->
+ %% MD5 is for beam code, so check only the beam code on
+ %% disk, even if the file contains native code as well
+ MD5 =/= beam_file_md5(Path)
+ end
+ end.
+
+beam_file_md5(Path) ->
+ case beam_lib:md5(Path) of
+ {ok,{_Mod,MD5}} -> MD5;
+ _ -> undefined
+ end.
+
+beam_file_native_md5(Path, Architecture) ->
+ try
+ get_beam_chunk(Path, hipe_unified_loader:chunk_name(Architecture))
+ of
+ NativeCode when is_binary(NativeCode) ->
+ erlang:md5(NativeCode)
+ catch
+ _:_ -> undefined
+ end.
+
+get_beam_chunk(Path, Chunk) ->
+ {ok, {_, [{_, Bin}]}} = beam_lib:chunks(Path, [Chunk]),
+ Bin.
+
+%% Returns a list of all modules modified on disk.
+-spec modified_modules() -> [module()].
+modified_modules() ->
+ PathFiles = path_files(),
+ [M || {M, _} <- code:all_loaded(),
+ module_status(M, PathFiles) =:= modified].
+
+%% prefetch the directory contents of code path directories
+path_files() ->
+ path_files(code:get_path()).
+
+path_files([]) ->
+ [];
+path_files([Path|Tail]) ->
+ case erl_prim_loader:list_dir(Path) of
+ {ok, Files} ->
+ [{Path,Files} | path_files(Tail)];
+ _Error ->
+ path_files(Tail)
+ end.
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index 6174136507..418b0c50e1 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -135,10 +135,14 @@ split_paths([], _S, Path, Paths) ->
-spec call(term()) -> term().
call(Req) ->
+ Ref = erlang:monitor(process, ?MODULE),
?MODULE ! {code_call, self(), Req},
receive
{?MODULE, Reply} ->
- Reply
+ erlang:demonitor(Ref,[flush]),
+ Reply;
+ {'DOWN',Ref,process,_,_} ->
+ exit({'DOWN',code_server,Req})
end.
reply(Pid, Res) ->
@@ -807,7 +811,13 @@ clear_namedb([], _) ->
%% Dir must be a complete pathname (not only a name).
insert_dir(Dir, Db) ->
Splitted = filename:split(Dir),
- Name = get_name_from_splitted(Splitted),
+ case get_name_from_splitted(Splitted) of
+ Name when Name /= "ebin", Name /= "." ->
+ Name;
+ _ ->
+ SplittedAbsName = filename:split(absname(Dir)),
+ Name = get_name_from_splitted(SplittedAbsName)
+ end,
AppDir = filename:join(del_ebin_1(Splitted)),
do_insert_name(Name, AppDir, Db).
@@ -933,15 +943,25 @@ del_ebin(Dir) ->
filename:join(del_ebin_1(filename:split(Dir))).
del_ebin_1([Parent,App,"ebin"]) ->
- Ext = archive_extension(),
- case filename:basename(Parent, Ext) of
- Parent ->
- %% Plain directory.
+ case filename:basename(Parent) of
+ [] ->
+ %% Parent is the root directory
[Parent,App];
- Archive ->
- %% Archive.
- [Archive]
+ _ ->
+ Ext = archive_extension(),
+ case filename:basename(Parent, Ext) of
+ Parent ->
+ %% Plain directory.
+ [Parent,App];
+ Archive ->
+ %% Archive.
+ [Archive]
+ end
end;
+del_ebin_1(Path = [_App,"ebin"]) ->
+ del_ebin_1(filename:split(absname(filename:join(Path))));
+del_ebin_1(["ebin"]) ->
+ del_ebin_1(filename:split(absname("ebin")));
del_ebin_1([H|T]) ->
[H|del_ebin_1(T)];
del_ebin_1([]) ->
@@ -1110,19 +1130,18 @@ try_load_module_2(File, Mod, Bin, From, Architecture,
#state{moddb=Db}=St) ->
case catch hipe_unified_loader:load_native_code(Mod, Bin, Architecture) of
{module,Mod} = Module ->
- ets:insert(Db, [{{native,Mod},true},{Mod,File}]),
+ ets:insert(Db, {Mod,File}),
{reply,Module,St};
no_native ->
try_load_module_3(File, Mod, Bin, From, Architecture, St);
Error ->
error_msg("Native loading of ~ts failed: ~p\n", [File,Error]),
- {reply,ok,St}
+ {reply,{error,Error},St}
end.
-try_load_module_3(File, Mod, Bin, From, Architecture, St0) ->
+try_load_module_3(File, Mod, Bin, From, _Architecture, St0) ->
Action = fun({module,_}=Module, #state{moddb=Db}=S) ->
ets:insert(Db, {Mod,File}),
- post_beam_load([Mod], Architecture, S),
{reply,Module,S};
({error,on_load_failure}=Error, S) ->
{reply,Error,S};
@@ -1133,24 +1152,14 @@ try_load_module_3(File, Mod, Bin, From, Architecture, St0) ->
Res = erlang:load_module(Mod, Bin),
handle_on_load(Res, Action, Mod, From, St0).
-hipe_result_to_status(Result, #state{moddb=Db}) ->
+hipe_result_to_status(Result, #state{}) ->
case Result of
- {module,Mod} ->
- ets:insert(Db, [{{native,Mod},true}]),
+ {module,_} ->
Result;
_ ->
{error,Result}
end.
-post_beam_load(_, undefined, _) ->
- %% HiPE is disabled.
- ok;
-post_beam_load(Mods0, _Architecture, #state{moddb=Db}) ->
- %% post_beam_load/2 can potentially be very expensive because it
- %% blocks multi-scheduling. Therefore, we only want to call
- %% it with modules that are known to have native code loaded.
- Mods = [M || M <- Mods0, ets:member(Db, {native,M})],
- hipe_unified_loader:post_beam_load(Mods).
int_list([H|T]) when is_integer(H) -> int_list(T);
int_list([_|_]) -> false;
@@ -1293,15 +1302,12 @@ abort_if_sticky(L, Db) ->
[_|_] -> {error,Sticky}
end.
-do_finish_loading(Prepared, #state{moddb=Db}=St) ->
+do_finish_loading(Prepared, #state{moddb=Db}) ->
MagicBins = [B || {_,{B,_}} <- Prepared],
case erlang:finish_loading(MagicBins) of
ok ->
MFs = [{M,F} || {M,{_,F}} <- Prepared],
true = ets:insert(Db, MFs),
- Ms = [M || {M,_} <- MFs],
- Architecture = erlang:system_info(hipe_architecture),
- post_beam_load(Ms, Architecture, St),
ok;
{Reason,Ms} ->
{error,[{M,Reason} || M <- Ms]}
@@ -1372,11 +1378,10 @@ finish_on_load(PidRef, OnLoadRes, #state{on_load=OnLoad0}=St0) ->
finish_on_load_1(Mod, OnLoadRes, Waiting, St) ->
Keep = OnLoadRes =:= ok,
- erlang:finish_after_on_load(Mod, Keep),
+ erts_code_purger:finish_after_on_load(Mod, Keep),
Res = case Keep of
false ->
_ = finish_on_load_report(Mod, OnLoadRes),
- _ = erts_code_purger:purge(Mod),
{error,on_load_failure};
true ->
{module,Mod}
@@ -1404,7 +1409,7 @@ finish_on_load_report(Mod, Term) ->
%% from the code_server process.
spawn(fun() ->
F = "The on_load function for module "
- "~s returned ~P\n",
+ "~s returned:~n~P\n",
%% Express the call as an apply to simplify
%% the ext_mod_dep/1 test case.
diff --git a/lib/kernel/src/disk_log.erl b/lib/kernel/src/disk_log.erl
index 9b44021872..70cbf1c87c 100644
--- a/lib/kernel/src/disk_log.erl
+++ b/lib/kernel/src/disk_log.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -67,7 +67,7 @@
%%-define(PROFILE(C), C).
-define(PROFILE(C), void).
--compile({inline,[{log_loop,5},{log_end_sync,2},{replies,2},{rflat,1}]}).
+-compile({inline,[{log_loop,6},{log_end_sync,2},{replies,2},{rflat,1}]}).
%%%----------------------------------------------------------------------
%%% Contract type specifications
@@ -75,8 +75,6 @@
-opaque continuation() :: #continuation{}.
--type bytes() :: binary() | [byte()].
-
-type file_error() :: term(). % XXX: refine
-type invalid_header() :: term(). % XXX: refine
@@ -127,28 +125,28 @@ open(A) ->
Log :: log(),
Term :: term().
log(Log, Term) ->
- req(Log, {log, term_to_binary(Term)}).
+ req(Log, {log, internal, [term_to_binary(Term)]}).
-spec blog(Log, Bytes) -> ok | {error, Reason :: log_error_rsn()} when
Log :: log(),
- Bytes :: bytes().
+ Bytes :: iodata().
blog(Log, Bytes) ->
- req(Log, {blog, check_bytes(Bytes)}).
+ req(Log, {log, external, [ensure_binary(Bytes)]}).
-spec log_terms(Log, TermList) -> ok | {error, Resaon :: log_error_rsn()} when
Log :: log(),
TermList :: [term()].
log_terms(Log, Terms) ->
Bs = terms2bins(Terms),
- req(Log, {log, Bs}).
+ req(Log, {log, internal, Bs}).
-spec blog_terms(Log, BytesList) ->
ok | {error, Reason :: log_error_rsn()} when
Log :: log(),
- BytesList :: [bytes()].
+ BytesList :: [iodata()].
blog_terms(Log, Bytess) ->
- Bs = check_bytes_list(Bytess, Bytess),
- req(Log, {blog, Bs}).
+ Bs = ensure_binary_list(Bytess),
+ req(Log, {log, external, Bs}).
-type notify_ret() :: 'ok' | {'error', 'no_such_log'}.
@@ -156,27 +154,27 @@ blog_terms(Log, Bytess) ->
Log :: log(),
Term :: term().
alog(Log, Term) ->
- notify(Log, {alog, term_to_binary(Term)}).
+ notify(Log, {alog, internal, [term_to_binary(Term)]}).
-spec alog_terms(Log, TermList) -> notify_ret() when
Log :: log(),
TermList :: [term()].
alog_terms(Log, Terms) ->
Bs = terms2bins(Terms),
- notify(Log, {alog, Bs}).
+ notify(Log, {alog, internal, Bs}).
-spec balog(Log, Bytes) -> notify_ret() when
Log :: log(),
- Bytes :: bytes().
+ Bytes :: iodata().
balog(Log, Bytes) ->
- notify(Log, {balog, check_bytes(Bytes)}).
+ notify(Log, {alog, external, [ensure_binary(Bytes)]}).
-spec balog_terms(Log, ByteList) -> notify_ret() when
Log :: log(),
- ByteList :: [bytes()].
+ ByteList :: [iodata()].
balog_terms(Log, Bytess) ->
- Bs = check_bytes_list(Bytess, Bytess),
- notify(Log, {balog, Bs}).
+ Bs = ensure_binary_list(Bytess),
+ notify(Log, {alog, external, Bs}).
-type close_error_rsn() ::'no_such_log' | 'nonode'
| {'file_error', file:filename(), file_error()}.
@@ -219,9 +217,9 @@ truncate(Log, Head) ->
-spec btruncate(Log, BHead) -> 'ok' | {'error', trunc_error_rsn()} when
Log :: log(),
- BHead :: bytes().
+ BHead :: iodata().
btruncate(Log, Head) ->
- req(Log, {truncate, {ok, check_bytes(Head)}, btruncate, 2}).
+ req(Log, {truncate, {ok, ensure_binary(Head)}, btruncate, 2}).
-type reopen_error_rsn() :: no_such_log
| nonode
@@ -248,9 +246,9 @@ reopen(Log, NewFile, NewHead) ->
-spec breopen(Log, File, BHead) -> 'ok' | {'error', reopen_error_rsn()} when
Log :: log(),
File :: file:filename(),
- BHead :: bytes().
+ BHead :: iodata().
breopen(Log, NewFile, NewHead) ->
- req(Log, {reopen, NewFile, {ok, check_bytes(NewHead)}, breopen, 3}).
+ req(Log, {reopen, NewFile, {ok, ensure_binary(NewHead)}, breopen, 3}).
-type inc_wrap_error_rsn() :: 'no_such_log' | 'nonode'
| {'read_only_mode', log()}
@@ -640,6 +638,8 @@ check_arg([{mode, read_only}|Tail], Res) ->
check_arg(Tail, Res#arg{mode = read_only});
check_arg([{mode, read_write}|Tail], Res) ->
check_arg(Tail, Res#arg{mode = read_write});
+check_arg([{quiet, Boolean}|Tail], Res) when is_boolean(Boolean) ->
+ check_arg(Tail, Res#arg{quiet = Boolean});
check_arg(Arg, _) ->
{error, {badarg, Arg}}.
@@ -670,13 +670,12 @@ init(Parent, Server) ->
process_flag(trap_exit, true),
loop(#state{parent = Parent, server = Server}).
-loop(State) when State#state.messages =:= [] ->
+loop(#state{messages = []}=State) ->
receive
Message ->
handle(Message, State)
end;
-loop(State) ->
- [M | Ms] = State#state.messages,
+loop(#state{messages = [M | Ms]}=State) ->
handle(M, State#state{messages = Ms}).
handle({From, write_cache}, S) when From =:= self() ->
@@ -686,106 +685,79 @@ handle({From, write_cache}, S) when From =:= self() ->
Error ->
loop(S#state{cache_error = Error})
end;
-handle({From, {log, B}}, S) ->
+handle({From, {log, Format, B}}=Message, S) ->
case get(log) of
- L when L#log.mode =:= read_only ->
+ #log{mode = read_only}=L ->
reply(From, {error, {read_only_mode, L#log.name}}, S);
- L when L#log.status =:= ok, L#log.format =:= internal ->
- log_loop(S, From, [B], [], iolist_size(B));
- L when L#log.status =:= ok, L#log.format =:= external ->
+ #log{status = ok, format=external}=L when Format =:= internal ->
reply(From, {error, {format_external, L#log.name}}, S);
- L when L#log.status =:= {blocked, false} ->
- reply(From, {error, {blocked_log, L#log.name}}, S);
- L when L#log.blocked_by =:= From ->
- reply(From, {error, {blocked_log, L#log.name}}, S);
- _ ->
- loop(S#state{queue = [{From, {log, B}} | S#state.queue]})
- end;
-handle({From, {blog, B}}, S) ->
- case get(log) of
- L when L#log.mode =:= read_only ->
- reply(From, {error, {read_only_mode, L#log.name}}, S);
- L when L#log.status =:= ok ->
- log_loop(S, From, [B], [], iolist_size(B));
- L when L#log.status =:= {blocked, false} ->
+ #log{status = ok, format=LogFormat} ->
+ log_loop(S, From, [B], [], iolist_size(B), LogFormat);
+ #log{status = {blocked, false}}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
- L when L#log.blocked_by =:= From ->
+ #log{blocked_by = From}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
_ ->
- loop(S#state{queue = [{From, {blog, B}} | S#state.queue]})
+ enqueue(Message, S)
end;
-handle({alog, B}, S) ->
+handle({alog, Format, B}=Message, S) ->
case get(log) of
- L when L#log.mode =:= read_only ->
+ #log{mode = read_only} ->
notify_owners({read_only,B}),
loop(S);
- L when L#log.status =:= ok, L#log.format =:= internal ->
- log_loop(S, [], [B], [], iolist_size(B));
- L when L#log.status =:= ok ->
+ #log{status = ok, format = external} when Format =:= internal ->
notify_owners({format_external, B}),
loop(S);
- L when L#log.status =:= {blocked, false} ->
+ #log{status = ok, format=LogFormat} ->
+ log_loop(S, [], [B], [], iolist_size(B), LogFormat);
+ #log{status = {blocked, false}} ->
notify_owners({blocked_log, B}),
loop(S);
_ ->
- loop(S#state{queue = [{alog, B} | S#state.queue]})
+ enqueue(Message, S)
end;
-handle({balog, B}, S) ->
+handle({From, {block, QueueLogRecs}}=Message, S) ->
case get(log) of
- L when L#log.mode =:= read_only ->
- notify_owners({read_only,B}),
- loop(S);
- L when L#log.status =:= ok ->
- log_loop(S, [], [B], [], iolist_size(B));
- L when L#log.status =:= {blocked, false} ->
- notify_owners({blocked_log, B}),
- loop(S);
- _ ->
- loop(S#state{queue = [{balog, B} | S#state.queue]})
- end;
-handle({From, {block, QueueLogRecs}}, S) ->
- case get(log) of
- L when L#log.status =:= ok ->
+ #log{status = ok}=L ->
do_block(From, QueueLogRecs, L),
reply(From, ok, S);
- L when L#log.status =:= {blocked, false} ->
+ #log{status = {blocked, false}}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
- L when L#log.blocked_by =:= From ->
+ #log{blocked_by = From}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
_ ->
- loop(S#state{queue = [{From, {block, QueueLogRecs}} |
- S#state.queue]})
+ enqueue(Message, S)
end;
handle({From, unblock}, S) ->
case get(log) of
- L when L#log.status =:= ok ->
+ #log{status = ok}=L ->
reply(From, {error, {not_blocked, L#log.name}}, S);
- L when L#log.blocked_by =:= From ->
+ #log{blocked_by = From}=L ->
S2 = do_unblock(L, S),
reply(From, ok, S2);
L ->
reply(From, {error, {not_blocked_by_pid, L#log.name}}, S)
end;
-handle({From, sync}, S) ->
+handle({From, sync}=Message, S) ->
case get(log) of
- L when L#log.mode =:= read_only ->
+ #log{mode = read_only}=L ->
reply(From, {error, {read_only_mode, L#log.name}}, S);
- L when L#log.status =:= ok ->
- sync_loop([From], S);
- L when L#log.status =:= {blocked, false} ->
+ #log{status = ok, format=LogFormat} ->
+ log_loop(S, [], [], [From], 0, LogFormat);
+ #log{status = {blocked, false}}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
- L when L#log.blocked_by =:= From ->
+ #log{blocked_by = From}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
_ ->
- loop(S#state{queue = [{From, sync} | S#state.queue]})
+ enqueue(Message, S)
end;
-handle({From, {truncate, Head, F, A}}, S) ->
+handle({From, {truncate, Head, F, A}}=Message, S) ->
case get(log) of
- L when L#log.mode =:= read_only ->
+ #log{mode = read_only}=L ->
reply(From, {error, {read_only_mode, L#log.name}}, S);
- L when L#log.status =:= ok, S#state.cache_error =/= ok ->
+ #log{status = ok} when S#state.cache_error =/= ok ->
loop(cache_error(S, [From]));
- L when L#log.status =:= ok ->
+ #log{status = ok}=L ->
H = merge_head(Head, L#log.head),
case catch do_trunc(L, H) of
ok ->
@@ -796,48 +768,46 @@ handle({From, {truncate, Head, F, A}}, S) ->
Error ->
do_exit(S, From, Error, ?failure(Error, F, A))
end;
- L when L#log.status =:= {blocked, false} ->
+ #log{status = {blocked, false}}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
- L when L#log.blocked_by =:= From ->
+ #log{blocked_by = From}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
_ ->
- loop(S#state{queue = [{From, {truncate, Head, F, A}}
- | S#state.queue]})
+ enqueue(Message, S)
end;
-handle({From, {chunk, Pos, B, N}}, S) ->
+handle({From, {chunk, Pos, B, N}}=Message, S) ->
case get(log) of
- L when L#log.status =:= ok, S#state.cache_error =/= ok ->
+ #log{status = ok} when S#state.cache_error =/= ok ->
loop(cache_error(S, [From]));
- L when L#log.status =:= ok ->
+ #log{status = ok}=L ->
R = do_chunk(L, Pos, B, N),
reply(From, R, S);
- L when L#log.blocked_by =:= From ->
+ #log{blocked_by = From}=L ->
R = do_chunk(L, Pos, B, N),
reply(From, R, S);
- L when L#log.status =:= {blocked, false} ->
+ #log{status = {blocked, false}}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
_L ->
- loop(S#state{queue = [{From, {chunk, Pos, B, N}} | S#state.queue]})
+ enqueue(Message, S)
end;
-handle({From, {chunk_step, Pos, N}}, S) ->
+handle({From, {chunk_step, Pos, N}}=Message, S) ->
case get(log) of
- L when L#log.status =:= ok, S#state.cache_error =/= ok ->
+ #log{status = ok} when S#state.cache_error =/= ok ->
loop(cache_error(S, [From]));
- L when L#log.status =:= ok ->
+ #log{status = ok}=L ->
R = do_chunk_step(L, Pos, N),
reply(From, R, S);
- L when L#log.blocked_by =:= From ->
+ #log{blocked_by = From}=L ->
R = do_chunk_step(L, Pos, N),
reply(From, R, S);
- L when L#log.status =:= {blocked, false} ->
+ #log{status = {blocked, false}}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
_ ->
- loop(S#state{queue = [{From, {chunk_step, Pos, N}}
- | S#state.queue]})
+ enqueue(Message, S)
end;
-handle({From, {change_notify, Pid, NewNotify}}, S) ->
+handle({From, {change_notify, Pid, NewNotify}}=Message, S) ->
case get(log) of
- L when L#log.status =:= ok ->
+ #log{status = ok}=L ->
case do_change_notify(L, Pid, NewNotify) of
{ok, L1} ->
put(log, L1),
@@ -845,39 +815,37 @@ handle({From, {change_notify, Pid, NewNotify}}, S) ->
Error ->
reply(From, Error, S)
end;
- L when L#log.status =:= {blocked, false} ->
+ #log{status = {blocked, false}}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
- L when L#log.blocked_by =:= From ->
+ #log{blocked_by = From}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
_ ->
- loop(S#state{queue = [{From, {change_notify, Pid, NewNotify}}
- | S#state.queue]})
+ enqueue(Message, S)
end;
-handle({From, {change_header, NewHead}}, S) ->
+handle({From, {change_header, NewHead}}=Message, S) ->
case get(log) of
- L when L#log.mode =:= read_only ->
+ #log{mode = read_only}=L ->
reply(From, {error, {read_only_mode, L#log.name}}, S);
- L when L#log.status =:= ok ->
- case check_head(NewHead, L#log.format) of
+ #log{status = ok, format = Format}=L ->
+ case check_head(NewHead, Format) of
{ok, Head} ->
- put(log, L#log{head = mk_head(Head, L#log.format)}),
+ put(log, L#log{head = mk_head(Head, Format)}),
reply(From, ok, S);
Error ->
reply(From, Error, S)
end;
- L when L#log.status =:= {blocked, false} ->
+ #log{status = {blocked, false}}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
- L when L#log.blocked_by =:= From ->
+ #log{blocked_by = From}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
_ ->
- loop(S#state{queue = [{From, {change_header, NewHead}}
- | S#state.queue]})
+ enqueue(Message, S)
end;
-handle({From, {change_size, NewSize}}, S) ->
+handle({From, {change_size, NewSize}}=Message, S) ->
case get(log) of
- L when L#log.mode =:= read_only ->
+ #log{mode = read_only}=L ->
reply(From, {error, {read_only_mode, L#log.name}}, S);
- L when L#log.status =:= ok ->
+ #log{status = ok}=L ->
case check_size(L#log.type, NewSize) of
ok ->
case catch do_change_size(L, NewSize) of % does the put
@@ -894,23 +862,22 @@ handle({From, {change_size, NewSize}}, S) ->
not_ok ->
reply(From, {error, {badarg, size}}, S)
end;
- L when L#log.status =:= {blocked, false} ->
+ #log{status = {blocked, false}}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
- L when L#log.blocked_by =:= From ->
+ #log{blocked_by = From}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
_ ->
- loop(S#state{queue = [{From, {change_size, NewSize}}
- | S#state.queue]})
+ enqueue(Message, S)
end;
-handle({From, inc_wrap_file}, S) ->
+handle({From, inc_wrap_file}=Message, S) ->
case get(log) of
- L when L#log.mode =:= read_only ->
+ #log{mode = read_only}=L ->
reply(From, {error, {read_only_mode, L#log.name}}, S);
- L when L#log.type =:= halt ->
+ #log{type = halt}=L ->
reply(From, {error, {halt_log, L#log.name}}, S);
- L when L#log.status =:= ok, S#state.cache_error =/= ok ->
+ #log{status = ok} when S#state.cache_error =/= ok ->
loop(cache_error(S, [From]));
- L when L#log.status =:= ok ->
+ #log{status = ok}=L ->
case catch do_inc_wrap_file(L) of
{ok, L2, Lost} ->
put(log, L2),
@@ -920,20 +887,22 @@ handle({From, inc_wrap_file}, S) ->
put(log, L2),
reply(From, Error, state_err(S, Error))
end;
- L when L#log.status =:= {blocked, false} ->
+ #log{status = {blocked, false}}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
- L when L#log.blocked_by =:= From ->
+ #log{blocked_by = From}=L ->
reply(From, {error, {blocked_log, L#log.name}}, S);
_ ->
- loop(S#state{queue = [{From, inc_wrap_file} | S#state.queue]})
+ enqueue(Message, S)
end;
handle({From, {reopen, NewFile, Head, F, A}}, S) ->
case get(log) of
- L when L#log.mode =:= read_only ->
+ #log{mode = read_only}=L ->
reply(From, {error, {read_only_mode, L#log.name}}, S);
- L when L#log.status =:= ok, S#state.cache_error =/= ok ->
+ #log{status = ok} when S#state.cache_error =/= ok ->
loop(cache_error(S, [From]));
- L when L#log.status =:= ok, L#log.filename =/= NewFile ->
+ #log{status = ok, filename = NewFile}=L ->
+ reply(From, {error, {same_file_name, L#log.name}}, S);
+ #log{status = ok}=L ->
case catch close_disk_log2(L) of
closed ->
File = L#log.filename,
@@ -966,8 +935,6 @@ handle({From, {reopen, NewFile, Head, F, A}}, S) ->
Error ->
do_exit(S, From, Error, ?failure(Error, F, A))
end;
- L when L#log.status =:= ok ->
- reply(From, {error, {same_file_name, L#log.name}}, S);
L ->
reply(From, {error, {blocked_log, L#log.name}}, S)
end;
@@ -1005,11 +972,11 @@ handle({From, close}, S) ->
end;
handle({From, info}, S) ->
reply(From, do_info(get(log), S#state.cnt), S);
-handle({'EXIT', From, Reason}, S) when From =:= S#state.parent ->
+handle({'EXIT', From, Reason}, #state{parent=From}=S) ->
%% Parent orders shutdown.
_ = do_stop(S),
exit(Reason);
-handle({'EXIT', From, Reason}, S) when From =:= S#state.server ->
+handle({'EXIT', From, Reason}, #state{server=From}=S) ->
%% The server is gone.
_ = do_stop(S),
exit(Reason);
@@ -1034,57 +1001,59 @@ handle({system, From, Req}, S) ->
handle(_, S) ->
loop(S).
-sync_loop(From, S) ->
- log_loop(S, [], [], From, 0).
+enqueue(Message, #state{queue = Queue}=S) ->
+ loop(S#state{queue = [Message | Queue]}).
+
+%% Collect further log and sync requests already in the mailbox or queued
-define(MAX_LOOK_AHEAD, 64*1024).
%% Inlined.
-log_loop(#state{cache_error = CE}=S, Pids, _Bins, _Sync, _Sz) when CE =/= ok ->
+log_loop(#state{cache_error = CE}=S, Pids, _Bins, _Sync, _Sz, _F) when CE =/= ok ->
loop(cache_error(S, Pids));
-log_loop(#state{}=S, Pids, Bins, Sync, Sz) when Sz > ?MAX_LOOK_AHEAD ->
- loop(log_end(S, Pids, Bins, Sync));
-log_loop(#state{messages = []}=S, Pids, Bins, Sync, Sz) ->
- receive
+log_loop(#state{}=S, Pids, Bins, Sync, Sz, _F) when Sz > ?MAX_LOOK_AHEAD ->
+ loop(log_end(S, Pids, Bins, Sync, Sz));
+log_loop(#state{messages = []}=S, Pids, Bins, Sync, Sz, F) ->
+ receive
Message ->
- log_loop(Message, Pids, Bins, Sync, Sz, S, get(log))
+ log_loop(Message, Pids, Bins, Sync, Sz, F, S)
after 0 ->
- loop(log_end(S, Pids, Bins, Sync))
+ loop(log_end(S, Pids, Bins, Sync, Sz))
end;
-log_loop(#state{messages = [M | Ms]}=S, Pids, Bins, Sync, Sz) ->
+log_loop(#state{messages = [M | Ms]}=S, Pids, Bins, Sync, Sz, F) ->
S1 = S#state{messages = Ms},
- log_loop(M, Pids, Bins, Sync, Sz, S1, get(log)).
+ log_loop(M, Pids, Bins, Sync, Sz, F, S1).
%% Items logged after the last sync request found are sync:ed as well.
-log_loop({alog,B}, Pids, Bins, Sync, Sz, S, #log{format = internal}) ->
- %% {alog, _} allowed for the internal format only.
- log_loop(S, Pids, [B | Bins], Sync, Sz+iolist_size(B));
-log_loop({balog, B}, Pids, Bins, Sync, Sz, S, _L) ->
- log_loop(S, Pids, [B | Bins], Sync, Sz+iolist_size(B));
-log_loop({From, {log, B}}, Pids, Bins, Sync, Sz, S, #log{format = internal}) ->
- %% {log, _} allowed for the internal format only.
- log_loop(S, [From | Pids], [B | Bins], Sync, Sz+iolist_size(B));
-log_loop({From, {blog, B}}, Pids, Bins, Sync, Sz, S, _L) ->
- log_loop(S, [From | Pids], [B | Bins], Sync, Sz+iolist_size(B));
-log_loop({From, sync}, Pids, Bins, Sync, Sz, S, _L) ->
- log_loop(S, Pids, Bins, [From | Sync], Sz);
-log_loop(Message, Pids, Bins, Sync, _Sz, S, _L) ->
- NS = log_end(S, Pids, Bins, Sync),
+log_loop({alog, internal, B}, Pids, Bins, Sync, Sz, internal=F, S) ->
+ %% alog of terms allowed for the internal format only
+ log_loop(S, Pids, [B | Bins], Sync, Sz+iolist_size(B), F);
+log_loop({alog, binary, B}, Pids, Bins, Sync, Sz, F, S) ->
+ log_loop(S, Pids, [B | Bins], Sync, Sz+iolist_size(B), F);
+log_loop({From, {log, internal, B}}, Pids, Bins, Sync, Sz, internal=F, S) ->
+ %% log of terms allowed for the internal format only
+ log_loop(S, [From | Pids], [B | Bins], Sync, Sz+iolist_size(B), F);
+log_loop({From, {log, binary, B}}, Pids, Bins, Sync, Sz, F, S) ->
+ log_loop(S, [From | Pids], [B | Bins], Sync, Sz+iolist_size(B), F);
+log_loop({From, sync}, Pids, Bins, Sync, Sz, F, S) ->
+ log_loop(S, Pids, Bins, [From | Sync], Sz, F);
+log_loop(Message, Pids, Bins, Sync, Sz, _F, S) ->
+ NS = log_end(S, Pids, Bins, Sync, Sz),
handle(Message, NS).
-log_end(S, [], [], Sync) ->
+log_end(S, [], [], Sync, _Sz) ->
log_end_sync(S, Sync);
-log_end(S, Pids, Bins, Sync) ->
- case do_log(get(log), rflat(Bins)) of
+log_end(#state{cnt = Cnt}=S, Pids, Bins, Sync, Sz) ->
+ case do_log(get(log), rflat(Bins), Sz) of
N when is_integer(N) ->
ok = replies(Pids, ok),
- S1 = (state_ok(S))#state{cnt = S#state.cnt+N},
+ S1 = (state_ok(S))#state{cnt = Cnt + N},
log_end_sync(S1, Sync);
{error, {error, {full, _Name}}, N} when Pids =:= [] ->
- log_end_sync(state_ok(S#state{cnt = S#state.cnt + N}), Sync);
+ log_end_sync(state_ok(S#state{cnt = Cnt + N}), Sync);
{error, Error, N} ->
ok = replies(Pids, Error),
- state_err(S#state{cnt = S#state.cnt + N}, Error)
+ state_err(S#state{cnt = Cnt + N}, Error)
end.
%% Inlined.
@@ -1096,12 +1065,9 @@ log_end_sync(S, Sync) ->
state_err(S, Res).
%% Inlined.
-rflat([B]=L) when is_binary(B) -> L;
rflat([B]) -> B;
rflat(B) -> rflat(B, []).
-rflat([B | Bs], L) when is_binary(B) ->
- rflat(Bs, [B | L]);
rflat([B | Bs], L) ->
rflat(Bs, B ++ L);
rflat([], L) -> L.
@@ -1138,17 +1104,17 @@ close_owner(Pid, L, S) ->
S2 = do_unblock(Pid, get(log), S),
unlink(Pid),
do_close2(L1, S2).
-
+
%% -> {stop, S} | {continue, S}
-close_user(Pid, L, S) when L#log.users > 0 ->
- L1 = L#log{users = L#log.users - 1},
+close_user(Pid, #log{users=Users}=L, S) when Users > 0 ->
+ L1 = L#log{users = Users - 1},
put(log, L1),
S2 = do_unblock(Pid, get(log), S),
do_close2(L1, S2);
close_user(_Pid, _L, S) ->
{continue, S}.
-do_close2(L, S) when L#log.users =:= 0, L#log.owners =:= [] ->
+do_close2(#log{users = 0, owners = []}, S) ->
{stop, S};
do_close2(_L, S) ->
{continue, S}.
@@ -1227,14 +1193,14 @@ add_pid(Pid, Notify, L) when is_pid(Pid) ->
add_pid(_NotAPid, _Notify, L) ->
{ok, L#log{users = L#log.users + 1}}.
-unblock_pid(L) when L#log.blocked_by =:= none ->
+unblock_pid(#log{blocked_by = none}) ->
ok;
-unblock_pid(L) ->
- case is_owner(L#log.blocked_by, L) of
+unblock_pid(#log{blocked_by = Pid}=L) ->
+ case is_owner(Pid, L) of
{true, _Notify} ->
ok;
false ->
- unlink(L#log.blocked_by)
+ unlink(Pid)
end.
%% -> true | false
@@ -1312,7 +1278,8 @@ compare_arg(_Attr, _Val, _A) ->
do_open(A) ->
#arg{type = Type, format = Format, name = Name, head = Head0,
file = FName, repair = Repair, size = Size, mode = Mode,
- version = V} = A,
+ quiet = Quiet, version = V} = A,
+ disk_log_1:set_quiet(Quiet),
Head = mk_head(Head0, Format),
case do_open2(Type, Format, Name, FName, Repair, Size, Mode, Head, V) of
{ok, Ret, Extra, FormatType, NoItems} ->
@@ -1326,7 +1293,7 @@ do_open(A) ->
end.
mk_head({head, Term}, internal) -> {ok, term_to_binary(Term)};
-mk_head({head, Bytes}, external) -> {ok, check_bytes(Bytes)};
+mk_head({head, Bytes}, external) -> {ok, ensure_binary(Bytes)};
mk_head(H, _) -> H.
terms2bins([T | Ts]) ->
@@ -1334,30 +1301,29 @@ terms2bins([T | Ts]) ->
terms2bins([]) ->
[].
-check_bytes_list([B | Bs], Bs0) when is_binary(B) ->
- check_bytes_list(Bs, Bs0);
-check_bytes_list([], Bs0) ->
+ensure_binary_list(Bs) ->
+ ensure_binary_list(Bs, Bs).
+
+ensure_binary_list([B | Bs], Bs0) when is_binary(B) ->
+ ensure_binary_list(Bs, Bs0);
+ensure_binary_list([], Bs0) ->
Bs0;
-check_bytes_list(_, Bs0) ->
- check_bytes_list(Bs0).
-
-check_bytes_list([B | Bs]) when is_binary(B) ->
- [B | check_bytes_list(Bs)];
-check_bytes_list([B | Bs]) ->
- [list_to_binary(B) | check_bytes_list(Bs)];
-check_bytes_list([]) ->
+ensure_binary_list(_, Bs0) ->
+ make_binary_list(Bs0).
+
+make_binary_list([B | Bs]) ->
+ [ensure_binary(B) | make_binary_list(Bs)];
+make_binary_list([]) ->
[].
-check_bytes(Binary) when is_binary(Binary) ->
- Binary;
-check_bytes(Bytes) ->
- list_to_binary(Bytes).
+ensure_binary(Bytes) ->
+ iolist_to_binary(Bytes).
%%-----------------------------------------------------------------
%% Change size of the logs in runtime.
%%-----------------------------------------------------------------
%% -> ok | {big, CurSize} | throw(Error)
-do_change_size(L, NewSize) when L#log.type =:= halt ->
+do_change_size(#log{type = halt}=L, NewSize) ->
Halt = L#log.extra,
CurB = Halt#halt.curB,
NewLog = L#log{extra = Halt#halt{size = NewSize}},
@@ -1373,7 +1339,7 @@ do_change_size(L, NewSize) when L#log.type =:= halt ->
true ->
{big, CurB}
end;
-do_change_size(L, NewSize) when L#log.type =:= wrap ->
+do_change_size(#log{type = wrap}=L, NewSize) ->
#log{extra = Extra, version = Version} = L,
{ok, Handle} = disk_log_1:change_size_wrap(Extra, NewSize, Version),
erase(is_full),
@@ -1388,7 +1354,7 @@ check_head({head_func, {M, F, A}}, _Format) when is_atom(M),
is_list(A) ->
{ok, {M, F, A}};
check_head({head, Head}, external) ->
- case catch check_bytes(Head) of
+ case catch ensure_binary(Head) of
{'EXIT', _} ->
{error, {badarg, head}};
_ ->
@@ -1674,7 +1640,7 @@ do_block(Pid, QueueLogRecs, L) ->
link(Pid)
end.
-do_unblock(Pid, L, S) when L#log.blocked_by =:= Pid ->
+do_unblock(Pid, #log{blocked_by = Pid}=L, S) ->
do_unblock(L, S);
do_unblock(_Pid, _L, S) ->
S.
@@ -1692,10 +1658,13 @@ do_unblock(L, S) ->
-spec do_log(#log{}, [binary()]) -> integer() | {'error', _, integer()}.
-do_log(L, B) when L#log.type =:= halt ->
+do_log(L, B) ->
+ do_log(L, B, iolist_size(B)).
+
+do_log(#log{type = halt}=L, B, BSz) ->
#log{format = Format, extra = Halt} = L,
#halt{curB = CurSize, size = Sz} = Halt,
- {Bs, BSize} = bsize(B, Format),
+ {Bs, BSize} = logl(B, Format, BSz),
case get(is_full) of
true ->
{error, {error, {full, L#log.name}}, 0};
@@ -1704,7 +1673,7 @@ do_log(L, B) when L#log.type =:= halt ->
undefined ->
halt_write_full(L, B, Format, 0)
end;
-do_log(L, B) when L#log.format_type =:= wrap_int ->
+do_log(#log{format_type = wrap_int}=L, B, _BSz) ->
case disk_log_1:mf_int_log(L#log.extra, B, L#log.head) of
{ok, Handle, Logged, Lost, Wraps} ->
notify_owners_wrap(Wraps),
@@ -1717,7 +1686,7 @@ do_log(L, B) when L#log.format_type =:= wrap_int ->
put(log, L#log{extra = Handle}),
{error, Error, Logged - Lost}
end;
-do_log(L, B) when L#log.format_type =:= wrap_ext ->
+do_log(#log{format_type = wrap_ext}=L, B, _BSz) ->
case disk_log_1:mf_ext_log(L#log.extra, B, L#log.head) of
{ok, Handle, Logged, Lost, Wraps} ->
notify_owners_wrap(Wraps),
@@ -1731,17 +1700,16 @@ do_log(L, B) when L#log.format_type =:= wrap_ext ->
{error, Error, Logged - Lost}
end.
-bsize(B, external) ->
- {B, xsz(B, 0)};
-bsize(B, internal) ->
+logl(B, external, undefined) ->
+ {B, iolist_size(B)};
+logl(B, external, Sz) ->
+ {B, Sz};
+logl(B, internal, _Sz) ->
disk_log_1:logl(B).
-xsz([B|T], Sz) -> xsz(T, byte_size(B) + Sz);
-xsz([], Sz) -> Sz.
-
halt_write_full(L, [Bin | Bins], Format, N) ->
B = [Bin],
- {Bs, BSize} = bsize(B, Format),
+ {Bs, BSize} = logl(B, Format, undefined),
Halt = L#log.extra,
#halt{curB = CurSize, size = Sz} = Halt,
if
@@ -1793,7 +1761,7 @@ do_sync(#log{type = wrap, extra = Handle} = Log) ->
Reply.
%% -> ok | Error | throw(Error)
-do_trunc(L, Head) when L#log.type =:= halt ->
+do_trunc(#log{type = halt}=L, Head) ->
#log{filename = FName, extra = Halt} = L,
FdC = Halt#halt.fdc,
{Reply1, FdC2} =
@@ -1822,7 +1790,7 @@ do_trunc(L, Head) when L#log.type =:= halt ->
end,
put(log, L#log{extra = NewHalt}),
Reply;
-do_trunc(L, Head) when L#log.type =:= wrap ->
+do_trunc(#log{type = wrap}=L, Head) ->
Handle = L#log.extra,
OldHead = L#log.head,
{MaxB, MaxF} = disk_log_1:get_wrap_size(Handle),
@@ -2016,8 +1984,7 @@ notify_owners(Note) ->
(_) -> ok
end, L#log.owners).
-cache_error(S, Pids) ->
- Error = S#state.cache_error,
+cache_error(#state{cache_error=Error}=S, Pids) ->
ok = replies(Pids, Error),
state_err(S#state{cache_error = ok}, Error).
diff --git a/lib/kernel/src/disk_log.hrl b/lib/kernel/src/disk_log.hrl
index 3262d979ee..a362881f40 100644
--- a/lib/kernel/src/disk_log.hrl
+++ b/lib/kernel/src/disk_log.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@
-define(MAX_FILES, 65000).
-define(MAX_BYTES, ((1 bsl 64) - 1)).
-define(MAX_CHUNK_SIZE, 65536).
+-define(MAX_FWRITE_CACHE, 65536).
%% Object defines
-define(LOGMAGIC, <<1,2,3,4>>).
@@ -54,11 +55,10 @@
%% Types -- alphabetically
%%------------------------------------------------------------------------
--type dlog_byte() :: [dlog_byte()] | byte().
-type dlog_format() :: 'external' | 'internal'.
-type dlog_format_type() :: 'halt_ext' | 'halt_int' | 'wrap_ext' | 'wrap_int'.
-type dlog_head() :: 'none' | {'ok', binary()} | mfa().
--type dlog_head_opt() :: none | term() | binary() | [dlog_byte()].
+-type dlog_head_opt() :: none | term() | iodata().
-type log() :: term(). % XXX: refine
-type dlog_mode() :: 'read_only' | 'read_write'.
-type dlog_name() :: atom() | string().
@@ -69,13 +69,14 @@
| {file, FileName :: file:filename()}
| {linkto, LinkTo :: none | pid()}
| {repair, Repair :: true | false | truncate}
- | {type, Type :: dlog_type}
+ | {type, Type :: dlog_type()}
| {format, Format :: dlog_format()}
| {size, Size :: dlog_size()}
| {distributed, Nodes :: [node()]}
| {notify, boolean()}
| {head, Head :: dlog_head_opt()}
| {head_func, MFA :: {atom(), atom(), list()}}
+ | {quiet, boolean()}
| {mode, Mode :: dlog_mode()}.
-type dlog_options() :: [dlog_option()].
-type dlog_repair() :: 'truncate' | boolean().
@@ -102,6 +103,7 @@
head = none,
mode = read_write :: dlog_mode(),
notify = false :: boolean(),
+ quiet = false :: boolean(),
options = [] :: dlog_options()}).
-record(cache, %% Cache for logged terms (per file descriptor).
diff --git a/lib/kernel/src/disk_log_1.erl b/lib/kernel/src/disk_log_1.erl
index 2e61363aa6..93856aa7b3 100644
--- a/lib/kernel/src/disk_log_1.erl
+++ b/lib/kernel/src/disk_log_1.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -37,6 +37,7 @@
-export([get_wrap_size/1]).
-export([is_head/1]).
-export([position/3, truncate_at/3, fwrite/4, fclose/2]).
+-export([set_quiet/1, is_quiet/0]).
-compile({inline,[{scan_f2,7}]}).
@@ -500,7 +501,10 @@ lh(H, _F) -> % cannot happen
repair(In, File) ->
FSz = file_size(File),
- error_logger:info_msg("disk_log: repairing ~tp ...\n", [File]),
+ case is_quiet() of
+ true -> ok;
+ _ -> error_logger:info_msg("disk_log: repairing ~tp ...\n", [File])
+ end,
Tmp = add_ext(File, "TMP"),
{ok, {_Alloc, Out, {0, _}, _FileSize}} = new_int_file(Tmp, none),
scan_f_read(<<>>, In, Out, File, FSz, Tmp, ?MAX_CHUNK_SIZE, 0, 0).
@@ -769,8 +773,11 @@ mf_int_chunk(Handle, {FileNo, Pos}, Bin, N) ->
NFileNo = inc(FileNo, Handle#handle.maxF),
case catch int_open(FName, true, read_only, any) of
{error, _Reason} ->
- error_logger:info_msg("disk_log: chunk error. File ~tp missing.\n\n",
- [FName]),
+ case is_quiet() of
+ true -> ok;
+ _ -> error_logger:info_msg("disk_log: chunk error. File ~tp missing.\n\n",
+ [FName])
+ end,
mf_int_chunk(Handle, {NFileNo, 0}, [], N);
{ok, {_Alloc, FdC, _HeadSize, _FileSize}} ->
case chunk(FdC, FName, Pos, Bin, N) of
@@ -797,9 +804,12 @@ mf_int_chunk_read_only(Handle, {FileNo, Pos}, Bin, N) ->
NFileNo = inc(FileNo, Handle#handle.maxF),
case catch int_open(FName, true, read_only, any) of
{error, _Reason} ->
- error_logger:info_msg("disk_log: chunk error. File ~tp missing.\n\n",
- [FName]),
- mf_int_chunk_read_only(Handle, {NFileNo, 0}, [], N);
+ case is_quiet() of
+ true -> ok;
+ _ -> error_logger:info_msg("disk_log: chunk error. File ~tp missing.\n\n",
+ [FName])
+ end,
+ mf_int_chunk_read_only(Handle, {NFileNo, 0}, [], N);
{ok, {_Alloc, FdC, _HeadSize, _FileSize}} ->
case do_chunk_read_only(FdC, FName, Pos, Bin, N) of
{NewFdC, eof} ->
@@ -1416,24 +1426,36 @@ open_truncate(FileName) ->
%%% Functions that access files, and throw on error.
--define(MAX, 16384). % bytes
-define(TIMEOUT, 2000). % ms
%% -> {Reply, cache()}; Reply = ok | Error
-fwrite(#cache{c = []} = FdC, _FN, B, Size) ->
+fwrite(FdC, _FN, _B, 0) ->
+ {ok, FdC}; % avoid starting a timer for empty writes
+fwrite(#cache{fd = Fd, c = C, sz = Sz} = FdC, FileName, B, Size) ->
+ Sz1 = Sz + Size,
+ C1 = cache_append(C, B),
+ if Sz1 > ?MAX_FWRITE_CACHE ->
+ write_cache(Fd, FileName, C1);
+ true ->
+ maybe_start_timer(C),
+ {ok, FdC#cache{sz = Sz1, c = C1}}
+ end.
+
+cache_append([], B) -> B;
+cache_append(C, B) -> [C | B].
+
+%% if the cache was empty, start timer (unless it's already running)
+maybe_start_timer([]) ->
case get(write_cache_timer_is_running) of
- true ->
+ true ->
ok;
- _ ->
+ _ ->
put(write_cache_timer_is_running, true),
erlang:send_after(?TIMEOUT, self(), {self(), write_cache}),
ok
- end,
- {ok, FdC#cache{sz = Size, c = B}};
-fwrite(#cache{sz = Sz, c = C} = FdC, _FN, B, Size) when Sz < ?MAX ->
- {ok, FdC#cache{sz = Sz+Size, c = [C | B]}};
-fwrite(#cache{fd = Fd, c = C}, FileName, B, _Size) ->
- write_cache(Fd, FileName, [C | B]).
+ end;
+maybe_start_timer(_C) ->
+ ok.
fwrite_header(Fd, B, Size) ->
{ok, #cache{fd = Fd, sz = Size, c = B}}.
@@ -1537,6 +1559,12 @@ fclose(#cache{fd = Fd, c = C}, FileName) ->
_ = write_cache_close(Fd, FileName, C),
file:close(Fd).
+set_quiet(Bool) ->
+ put(quiet, Bool).
+
+is_quiet() ->
+ get(quiet) =:= true.
+
%% -> {Reply, #cache{}}; Reply = ok | Error
write_cache(Fd, _FileName, []) ->
{ok, #cache{fd = Fd}};
diff --git a/lib/kernel/src/dist_ac.erl b/lib/kernel/src/dist_ac.erl
index 6c2fa0b6b1..2a5cf0ba92 100644
--- a/lib/kernel/src/dist_ac.erl
+++ b/lib/kernel/src/dist_ac.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -123,7 +123,7 @@ load_application(AppName, DistNodes) ->
gen_server:call(?DIST_AC, {load_application, AppName, DistNodes}, infinity).
takeover_application(AppName, RestartType) ->
- case validRestartType(RestartType) of
+ case valid_restart_type(RestartType) of
true ->
wait_for_sync_dacs(),
Nodes = get_nodes(AppName),
@@ -1514,10 +1514,10 @@ dist_del_node(Appls, Node) ->
Appl#appl{run = NRun}
end, Appls).
-validRestartType(permanent) -> true;
-validRestartType(temporary) -> true;
-validRestartType(transient) -> true;
-validRestartType(_RestartType) -> false.
+valid_restart_type(permanent) -> true;
+valid_restart_type(temporary) -> true;
+valid_restart_type(transient) -> true;
+valid_restart_type(_RestartType) -> false.
dist_mismatch(AppName, Node) ->
error_msg("Distribution mismatch for application \"~p\" on nodes ~p and ~p~n",
diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl
index 47d0c1b861..b3507e5d13 100644
--- a/lib/kernel/src/dist_util.erl
+++ b/lib/kernel/src/dist_util.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -131,7 +131,7 @@ handshake_other_started(#hs_data{request_type=ReqType}=HSData0) ->
other_version=Version,
other_node=Node,
other_started=true},
- check_dflag_xnc(HSData),
+ check_dflags(HSData),
is_allowed(HSData),
?debug({"MD5 connection from ~p (V~p)~n",
[Node, HSData#hs_data.other_version]}),
@@ -143,7 +143,11 @@ handshake_other_started(#hs_data{request_type=ReqType}=HSData0) ->
ChallengeB = recv_challenge_reply(HSData, ChallengeA, MyCookie),
send_challenge_ack(HSData, gen_digest(ChallengeB, HisCookie)),
?debug({dist_util, self(), accept_connection, Node}),
- connection(HSData).
+ connection(HSData);
+
+handshake_other_started(OldHsData) when element(1,OldHsData) =:= hs_data ->
+ handshake_other_started(convert_old_hsdata(OldHsData)).
+
%%
%% check if connecting node is allowed to connect
@@ -164,27 +168,24 @@ is_allowed(#hs_data{other_node = Node,
%% Check that both nodes can handle the same types of extended
%% node containers. If they can not, abort the connection.
%%
-check_dflag_xnc(#hs_data{other_node = Node,
- other_flags = OtherFlags,
- other_started = OtherStarted} = HSData) ->
- XRFlg = ?DFLAG_EXTENDED_REFERENCES,
- XPPFlg = case erlang:system_info(compat_rel) of
- R when R >= 10 ->
- ?DFLAG_EXTENDED_PIDS_PORTS;
- _ ->
- 0
- end,
- ReqXncFlags = XRFlg bor XPPFlg,
- case OtherFlags band ReqXncFlags =:= ReqXncFlags of
- true ->
- ok;
- false ->
- What = case {OtherFlags band XRFlg =:= XRFlg,
- OtherFlags band XPPFlg =:= XPPFlg} of
- {false, false} -> "references, pids and ports";
- {true, false} -> "pids and ports";
- {false, true} -> "references"
- end,
+check_dflags(#hs_data{other_node = Node,
+ other_flags = OtherFlags,
+ other_started = OtherStarted} = HSData) ->
+
+ Mandatory = [{?DFLAG_EXTENDED_REFERENCES, "EXTENDED_REFERENCES"},
+ {?DFLAG_EXTENDED_PIDS_PORTS, "EXTENDED_PIDS_PORTS"},
+ {?DFLAG_UTF8_ATOMS, "UTF8_ATOMS"}],
+ Missing = lists:filtermap(fun({Bit, Str}) ->
+ case Bit band OtherFlags of
+ Bit -> false;
+ 0 -> {true, Str}
+ end
+ end,
+ Mandatory),
+ case Missing of
+ [] ->
+ ok;
+ _ ->
case OtherStarted of
true ->
send_status(HSData, not_allowed),
@@ -195,9 +196,9 @@ check_dflag_xnc(#hs_data{other_node = Node,
How = "aborted"
end,
error_msg("** ~w: Connection attempt ~s node ~w ~s "
- "since it cannot handle extended ~s. "
- "**~n", [node(), Dir, Node, How, What]),
- ?shutdown2(Node, {check_dflag_xnc_failed, What})
+ "since it cannot handle ~p."
+ "**~n", [node(), Dir, Node, How, Missing]),
+ ?shutdown2(Node, {check_dflags_failed, Missing})
end.
@@ -323,14 +324,27 @@ handshake_we_started(#hs_data{request_type=ReqType,
NewHSData = HSData#hs_data{this_flags = ThisFlags,
other_flags = OtherFlags,
other_started = false},
- check_dflag_xnc(NewHSData),
+ check_dflags(NewHSData),
MyChallenge = gen_challenge(),
{MyCookie,HisCookie} = get_cookies(Node),
send_challenge_reply(NewHSData,MyChallenge,
gen_digest(ChallengeA,HisCookie)),
reset_timer(NewHSData#hs_data.timer),
recv_challenge_ack(NewHSData, MyChallenge, MyCookie),
- connection(NewHSData).
+ connection(NewHSData);
+
+handshake_we_started(OldHsData) when element(1,OldHsData) =:= hs_data ->
+ handshake_we_started(convert_old_hsdata(OldHsData)).
+
+convert_old_hsdata({hs_data, KP, ON, TN, S, T, TF, A, OV, OF, OS, FS, FR,
+ FS_PRE, FS_POST, FG, FA, MFT, MFG, RT}) ->
+ #hs_data{
+ kernel_pid = KP, other_node = ON, this_node = TN, socket = S, timer = T,
+ this_flags = TF, allowed = A, other_version = OV, other_flags = OF,
+ other_started = OS, f_send = FS, f_recv = FR, f_setopts_pre_nodeup = FS_PRE,
+ f_setopts_post_nodeup = FS_POST, f_getll = FG, f_address = FA,
+ mf_tick = MFT, mf_getstat = MFG, request_type = RT}.
+
%% --------------------------------------------------------------
%% The connection has been established.
@@ -350,15 +364,15 @@ connection(#hs_data{other_node = Node,
mark_nodeup(HSData,Address),
case FPostNodeup(Socket) of
ok ->
- con_loop(HSData#hs_data.kernel_pid,
- Node,
- Socket,
- Address,
- HSData#hs_data.this_node,
- PType,
- #tick{},
- HSData#hs_data.mf_tick,
- HSData#hs_data.mf_getstat);
+ con_loop({HSData#hs_data.kernel_pid,
+ Node,
+ Socket,
+ PType,
+ HSData#hs_data.mf_tick,
+ HSData#hs_data.mf_getstat,
+ HSData#hs_data.mf_setopts,
+ HSData#hs_data.mf_getopts},
+ #tick{});
_ ->
?shutdown2(Node, connection_setup_failed)
end;
@@ -454,8 +468,8 @@ mark_nodeup(#hs_data{kernel_pid = Kernel,
?shutdown(Node)
end.
-con_loop(Kernel, Node, Socket, TcpAddress,
- MyNode, Type, Tick, MFTick, MFGetstat) ->
+con_loop({Kernel, Node, Socket, Type, MFTick, MFGetstat, MFSetOpts, MFGetOpts}=ConData,
+ Tick) ->
receive
{tcp_closed, Socket} ->
?shutdown2(Node, connection_closed);
@@ -468,15 +482,12 @@ con_loop(Kernel, Node, Socket, TcpAddress,
_ ->
ignore_it
end,
- con_loop(Kernel, Node, Socket, TcpAddress, MyNode, Type,
- Tick, MFTick, MFGetstat);
+ con_loop(ConData, Tick);
{Kernel, tick} ->
case send_tick(Socket, Tick, Type,
MFTick, MFGetstat) of
{ok, NewTick} ->
- con_loop(Kernel, Node, Socket, TcpAddress,
- MyNode, Type, NewTick, MFTick,
- MFGetstat);
+ con_loop(ConData, NewTick);
{error, not_responding} ->
error_msg("** Node ~p not responding **~n"
"** Removing (timedout) connection **~n",
@@ -489,13 +500,24 @@ con_loop(Kernel, Node, Socket, TcpAddress,
case MFGetstat(Socket) of
{ok, Read, Write, _} ->
From ! {self(), get_status, {ok, Read, Write}},
- con_loop(Kernel, Node, Socket, TcpAddress,
- MyNode,
- Type, Tick,
- MFTick, MFGetstat);
+ con_loop(ConData, Tick);
_ ->
?shutdown2(Node, get_status_failed)
- end
+ end;
+ {From, Ref, {setopts, Opts}} ->
+ Ret = case MFSetOpts of
+ undefined -> {error, enotsup};
+ _ -> MFSetOpts(Socket, Opts)
+ end,
+ From ! {Ref, Ret},
+ con_loop(ConData, Tick);
+ {From, Ref, {getopts, Opts}} ->
+ Ret = case MFGetOpts of
+ undefined -> {error, enotsup};
+ _ -> MFGetOpts(Socket, Opts)
+ end,
+ From ! {Ref, Ret},
+ con_loop(ConData, Tick)
end.
@@ -550,12 +572,25 @@ recv_name(#hs_data{socket = Socket, f_recv = Recv}) ->
?shutdown(no_node)
end.
-get_name([$n,VersionA, VersionB, Flag1, Flag2, Flag3, Flag4 | OtherNode]) ->
- {?u32(Flag1, Flag2, Flag3, Flag4), list_to_atom(OtherNode),
- ?u16(VersionA,VersionB)};
+get_name([$n,VersionA, VersionB, Flag1, Flag2, Flag3, Flag4 | OtherNode] = Data) ->
+ case is_valid_name(OtherNode) of
+ true ->
+ {?u32(Flag1, Flag2, Flag3, Flag4), list_to_atom(OtherNode),
+ ?u16(VersionA,VersionB)};
+ false ->
+ ?shutdown(Data)
+ end;
get_name(Data) ->
?shutdown(Data).
+is_valid_name(OtherNodeName) ->
+ case string:lexemes(OtherNodeName,"@") of
+ [_OtherNodeName,_OtherNodeHost] ->
+ true;
+ _else ->
+ false
+ end.
+
publish_type(Flags) ->
case Flags band ?DFLAG_PUBLISHED of
0 ->
diff --git a/lib/kernel/src/erl_epmd.erl b/lib/kernel/src/erl_epmd.erl
index f8ef4a475d..7bc9e2ede3 100644
--- a/lib/kernel/src/erl_epmd.erl
+++ b/lib/kernel/src/erl_epmd.erl
@@ -103,6 +103,10 @@ names(EpmdAddr) ->
register_node(Name, PortNo) ->
register_node(Name, PortNo, inet).
+register_node(Name, PortNo, inet_tcp) ->
+ register_node(Name, PortNo, inet);
+register_node(Name, PortNo, inet6_tcp) ->
+ register_node(Name, PortNo, inet6);
register_node(Name, PortNo, Family) ->
gen_server:call(erl_epmd, {register, Name, PortNo, Family}, infinity).
@@ -403,8 +407,6 @@ select_best_version(L1, _H1, _L2, H2) when L1 > H2 ->
0;
select_best_version(_L1, H1, L2, _H2) when L2 > H1 ->
0;
-select_best_version(_L1, H1, L2, _H2) when L2 > H1 ->
- 0;
select_best_version(_L1, H1, _L2, H2) ->
erlang:min(H1, H2).
diff --git a/lib/kernel/src/erl_signal_handler.erl b/lib/kernel/src/erl_signal_handler.erl
new file mode 100644
index 0000000000..22f235d4e4
--- /dev/null
+++ b/lib/kernel/src/erl_signal_handler.erl
@@ -0,0 +1,57 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, 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_signal_handler).
+-behaviour(gen_event).
+-export([init/1, format_status/2,
+ handle_event/2, handle_call/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+-record(state,{}).
+
+init(_Args) ->
+ {ok, #state{}}.
+
+handle_event(sigusr1, S) ->
+ erlang:halt("Received SIGUSR1"),
+ {ok, S};
+handle_event(sigquit, S) ->
+ erlang:halt(),
+ {ok, S};
+handle_event(sigterm, S) ->
+ error_logger:info_msg("SIGTERM received - shutting down~n"),
+ ok = init:stop(),
+ {ok, S};
+handle_event(_SignalMsg, S) ->
+ {ok, S}.
+
+handle_info(_Info, S) ->
+ {ok, S}.
+
+handle_call(_Request, S) ->
+ {ok, ok, S}.
+
+format_status(_Opt, [_Pdict,_S]) ->
+ ok.
+
+code_change(_OldVsn, S, _Extra) ->
+ {ok, S}.
+
+terminate(_Args, _S) ->
+ ok.
diff --git a/lib/kernel/src/error_logger.erl b/lib/kernel/src/error_logger.erl
index 3523f680a3..9bf8547745 100644
--- a/lib/kernel/src/error_logger.erl
+++ b/lib/kernel/src/error_logger.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -31,6 +31,8 @@
handle_event/2, handle_call/2, handle_info/2,
terminate/2]).
+-export([get_format_depth/0, limit_term/1]).
+
-define(buffer_size, 10).
%%-----------------------------------------------------------------
@@ -360,8 +362,12 @@ init(Max) when is_integer(Max) ->
%% go back.
init({go_back, _PostState}) ->
{ok, {?buffer_size, 0, []}};
-init(_) -> %% Start and just relay to other
- {ok, []}. %% node if node(GLeader) =/= node().
+init(_) ->
+ %% The error logger process may receive a huge amount of
+ %% messages. Make sure that they are stored off heap to
+ %% avoid exessive GCs.
+ process_flag(message_queue_data, off_heap),
+ {ok, []}.
-spec handle_event(term(), state()) -> {'ok', state()}.
@@ -514,3 +520,21 @@ string_p1([H|T]) when is_list(H) ->
end;
string_p1([]) -> true;
string_p1(_) -> false.
+
+-spec limit_term(term()) -> term().
+
+limit_term(Term) ->
+ case get_format_depth() of
+ unlimited -> Term;
+ D -> io_lib:limit_term(Term, D)
+ end.
+
+-spec get_format_depth() -> 'unlimited' | pos_integer().
+
+get_format_depth() ->
+ case application:get_env(kernel, error_logger_format_depth) of
+ {ok, Depth} when is_integer(Depth) ->
+ max(10, Depth);
+ undefined ->
+ unlimited
+ end.
diff --git a/lib/kernel/src/erts_debug.erl b/lib/kernel/src/erts_debug.erl
index 7b3f1e313a..ad92aafc2f 100644
--- a/lib/kernel/src/erts_debug.erl
+++ b/lib/kernel/src/erts_debug.erl
@@ -35,7 +35,8 @@
dump_monitors/1, dump_links/1, flat_size/1,
get_internal_state/1, instructions/0, lock_counters/1,
map_info/1, same/2, set_internal_state/2,
- size_shared/1, copy_shared/1]).
+ size_shared/1, copy_shared/1, dirty_cpu/2, dirty_io/2,
+ dirty/3]).
-spec breakpoint(MFA, Flag) -> non_neg_integer() when
MFA :: {Module :: module(),
@@ -182,6 +183,28 @@ same(_, _) ->
set_internal_state(_, _) ->
erlang:nif_error(undef).
+-spec dirty_cpu(Term1, Term2) -> term() when
+ Term1 :: term(),
+ Term2 :: term().
+
+dirty_cpu(_, _) ->
+ erlang:nif_error(undef).
+
+-spec dirty_io(Term1, Term2) -> term() when
+ Term1 :: term(),
+ Term2 :: term().
+
+dirty_io(_, _) ->
+ erlang:nif_error(undef).
+
+-spec dirty(Term1, Term2, Term3) -> term() when
+ Term1 :: term(),
+ Term2 :: term(),
+ Term3 :: term().
+
+dirty(_, _, _) ->
+ erlang:nif_error(undef).
+
%%% End of BIFs
%% size(Term)
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 58b601e456..933f2d5f65 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -397,25 +397,36 @@ write_file(Name, Bin) ->
Modes :: [mode()],
Reason :: posix() | badarg | terminated | system_limit.
-write_file(Name, Bin, ModeList) when is_list(ModeList) ->
- case make_binary(Bin) of
- B when is_binary(B) ->
- case open(Name, [binary, write |
- lists:delete(binary,
- lists:delete(write, ModeList))]) of
- {ok, Handle} ->
- case write(Handle, B) of
- ok ->
- close(Handle);
- E1 ->
- _ = close(Handle),
- E1
- end;
- E2 ->
- E2
- end;
- E3 ->
- E3
+write_file(Name, IOData, ModeList) when is_list(ModeList) ->
+ case lists:member(raw, ModeList) of
+ true ->
+ %% For backwards compatibility of error messages
+ try iolist_size(IOData) of
+ _Size -> do_write_file(Name, IOData, ModeList)
+ catch
+ error:Error -> {error, Error}
+ end;
+ false ->
+ case make_binary(IOData) of
+ Bin when is_binary(Bin) ->
+ do_write_file(Name, Bin, ModeList);
+ Error ->
+ Error
+ end
+ end.
+
+do_write_file(Name, IOData, ModeList) ->
+ case open(Name, [binary, write | ModeList]) of
+ {ok, Handle} ->
+ case write(Handle, IOData) of
+ ok ->
+ close(Handle);
+ E1 ->
+ _ = close(Handle),
+ E1
+ end;
+ E2 ->
+ E2
end.
%% Obsolete, undocumented, local node only, don't use!.
@@ -1413,7 +1424,7 @@ path_open_first([Path|Rest], Name, Mode, LastError) ->
case open(FileName, Mode) of
{ok, Fd} ->
{ok, Fd, FileName};
- {error, enoent} ->
+ {error, Reason} when Reason =:= enoent; Reason =:= enotdir ->
path_open_first(Rest, Name, Mode, LastError);
Error ->
Error
diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl
index b133e6fed4..a6aa0edd15 100644
--- a/lib/kernel/src/gen_sctp.erl
+++ b/lib/kernel/src/gen_sctp.erl
@@ -439,7 +439,7 @@ error_string(X) ->
-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when
Socket :: sctp_socket(),
Pid :: pid(),
- Reason :: closed | not_owner | inet:posix().
+ Reason :: closed | not_owner | badarg | inet:posix().
controlling_process(S, Pid) when is_port(S), is_pid(Pid) ->
inet:udp_controlling_process(S, Pid);
diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl
index 1a21541b7c..ac61dbc792 100644
--- a/lib/kernel/src/gen_tcp.erl
+++ b/lib/kernel/src/gen_tcp.erl
@@ -320,7 +320,7 @@ unrecv(S, Data) when is_port(S) ->
-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when
Socket :: socket(),
Pid :: pid(),
- Reason :: closed | not_owner | inet:posix().
+ Reason :: closed | not_owner | badarg | inet:posix().
controlling_process(S, NewOwner) ->
case inet_db:lookup_socket(S) of
diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl
index 98d2f0bcfb..3121544719 100644
--- a/lib/kernel/src/gen_udp.erl
+++ b/lib/kernel/src/gen_udp.erl
@@ -195,7 +195,7 @@ connect(S, Address, Port) when is_port(S) ->
-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when
Socket :: socket(),
Pid :: pid(),
- Reason :: closed | not_owner | inet:posix().
+ Reason :: closed | not_owner | badarg | inet:posix().
controlling_process(S, NewOwner) ->
inet:udp_controlling_process(S, NewOwner).
diff --git a/lib/kernel/src/global.erl b/lib/kernel/src/global.erl
index 0c73ead7c5..a9e92b28b8 100644
--- a/lib/kernel/src/global.erl
+++ b/lib/kernel/src/global.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -58,14 +58,18 @@
%%% In certain places in the server, calling io:format hangs everything,
%%% so we'd better use erlang:display/1.
%%% my_tracer is used in testsuites
--define(trace(_), ok).
+%% uncomment this if tracing is wanted
+%%-define(DEBUG, true).
+-ifdef(DEBUG).
+-define(trace(T), erlang:display({format, node(), cs(), T})).
+ cs() ->
+ {_Big, Small, Tiny} = erlang:timestamp(),
+ (Small rem 100) * 100 + (Tiny div 10000).
%-define(trace(T), (catch my_tracer ! {node(), {line,?LINE}, T})).
-
-%-define(trace(T), erlang:display({format, node(), cs(), T})).
-%cs() ->
-% {_Big, Small, Tiny} = now(),
-% (Small rem 100) * 100 + (Tiny div 10000).
+-else.
+-define(trace(_), ok).
+-endif.
%% These are the protocol versions:
%% Vsn 1 is the original protocol.
@@ -443,7 +447,8 @@ info() ->
init([]) ->
process_flag(trap_exit, true),
_ = ets:new(global_locks, [set, named_table, protected]),
- _ = ets:new(global_names, [set, named_table, protected]),
+ _ = ets:new(global_names, [set, named_table, protected,
+ {read_concurrency, true}]),
_ = ets:new(global_names_ext, [set, named_table, protected]),
_ = ets:new(global_pid_names, [bag, named_table, protected]),
diff --git a/lib/kernel/src/global_group.erl b/lib/kernel/src/global_group.erl
index 8ac0bd9551..f5ead2a4c5 100644
--- a/lib/kernel/src/global_group.erl
+++ b/lib/kernel/src/global_group.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl
index b5e73117dd..bf785959ff 100644
--- a/lib/kernel/src/group.erl
+++ b/lib/kernel/src/group.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ start(Drv, Shell, Options) ->
server(Drv, Shell, Options) ->
process_flag(trap_exit, true),
edlin:init(),
- put(line_buffer, proplists:get_value(line_buffer, Options, [])),
+ put(line_buffer, proplists:get_value(line_buffer, Options, group_history:load())),
put(read_mode, list),
put(user_drv, Drv),
put(expand_fun,
@@ -783,6 +783,7 @@ save_line_buffer("\n", Lines) ->
save_line_buffer(Line, [Line|_Lines]=Lines) ->
save_line_buffer(Lines);
save_line_buffer(Line, Lines) ->
+ group_history:add(Line),
save_line_buffer([Line|Lines]).
save_line_buffer(Lines) ->
diff --git a/lib/kernel/src/group_history.erl b/lib/kernel/src/group_history.erl
new file mode 100644
index 0000000000..91f3663cc5
--- /dev/null
+++ b/lib/kernel/src/group_history.erl
@@ -0,0 +1,341 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(group_history).
+-export([load/0, add/1]).
+
+%% Make a minimal size that should encompass set of lines and then make
+%% a file rotation for N files of this size.
+-define(DEFAULT_HISTORY_FILE, "erlang-shell-log").
+-define(MAX_HISTORY_FILES, 10).
+-define(DEFAULT_SIZE, 1024*512). % 512 kb total default
+-define(DEFAULT_STATUS, disabled).
+-define(MIN_HISTORY_SIZE, (50*1024)). % 50 kb, in bytes
+-define(DEFAULT_DROP, []).
+-define(DISK_LOG_FORMAT, internal). % since we want repairs
+-define(LOG_NAME, '$#group_history').
+-define(VSN, {0,1,0}).
+
+%%%%%%%%%%%%%%
+%%% PUBLIC %%%
+%%%%%%%%%%%%%%
+
+%% @doc Loads the shell history from memory. This function should only be
+%% called from group:server/3 to inject itself in the previous commands
+%% stack.
+-spec load() -> [string()].
+load() ->
+ wait_for_kernel_safe_sup(),
+ case history_status() of
+ enabled ->
+ case open_log() of
+ {ok, ?LOG_NAME} ->
+ read_full_log(?LOG_NAME);
+ {repaired, ?LOG_NAME, {recovered, Good}, {badbytes, Bad}} ->
+ report_repairs(?LOG_NAME, Good, Bad),
+ read_full_log(?LOG_NAME);
+ {error, {need_repair, _FileName}} ->
+ repair_log(?LOG_NAME);
+ {error, {arg_mismatch, repair, true, false}} ->
+ repair_log(?LOG_NAME);
+ {error, {name_already_open, _}} ->
+ show_rename_warning(),
+ read_full_log(?LOG_NAME);
+ {error, {size_mismatch, Current, New}} ->
+ show_size_warning(Current, New),
+ resize_log(?LOG_NAME, Current, New),
+ load();
+ {error, {invalid_header, {vsn, Version}}} ->
+ upgrade_version(?LOG_NAME, Version),
+ load();
+ {error, Reason} ->
+ handle_open_error(Reason),
+ disable_history(),
+ []
+ end;
+ _ ->
+ []
+ end.
+
+%% @doc adds a log line to the erlang history log, if configured to do so.
+-spec add(iodata()) -> ok.
+add(Line) -> add(Line, history_status()).
+
+add(Line, enabled) ->
+ case lists:member(Line, to_drop()) of
+ false ->
+ case disk_log:log(?LOG_NAME, Line) of
+ ok ->
+ ok;
+ {error, no_such_log} ->
+ _ = open_log(), % a wild attempt we hope works!
+ disk_log:log(?LOG_NAME, Line);
+ {error, _Other} ->
+ % just ignore, we're too late
+ ok
+ end;
+ true ->
+ ok
+ end;
+add(_Line, disabled) ->
+ ok.
+
+%%%%%%%%%%%%%%%
+%%% PRIVATE %%%
+%%%%%%%%%%%%%%%
+
+%% Because loading the shell happens really damn early, processes we depend on
+%% might not be there yet. Luckily, the load function is called from the shell
+%% after a new process has been spawned, so we can block in here
+wait_for_kernel_safe_sup() ->
+ case whereis(kernel_safe_sup) of
+ undefined ->
+ timer:sleep(50),
+ wait_for_kernel_safe_sup();
+ _ ->
+ ok
+ end.
+
+%% Repair the log out of band
+repair_log(Name) ->
+ Opts = lists:keydelete(size, 1, log_options()),
+ case disk_log:open(Opts) of
+ {repaired, ?LOG_NAME, {recovered, Good}, {badbytes, Bad}} ->
+ report_repairs(?LOG_NAME, Good, Bad);
+ _ ->
+ ok
+ end,
+ _ = disk_log:close(Name),
+ load().
+
+%% Return whether the shell history is enabled or not
+-spec history_status() -> enabled | disabled.
+history_status() ->
+ case is_user() orelse application:get_env(kernel, shell_history) of
+ true -> disabled; % don't run for user proc
+ {ok, enabled} -> enabled;
+ undefined -> ?DEFAULT_STATUS;
+ _ -> disabled
+ end.
+
+%% Return whether the user process is running this
+-spec is_user() -> boolean().
+is_user() ->
+ case process_info(self(), registered_name) of
+ {registered_name, user} -> true;
+ _ -> false
+ end.
+
+%% Open a disk_log file while ensuring the required path is there.
+open_log() ->
+ Opts = log_options(),
+ _ = ensure_path(Opts),
+ disk_log:open(Opts).
+
+%% Return logger options
+log_options() ->
+ Path = find_path(),
+ File = filename:join([Path, ?DEFAULT_HISTORY_FILE]),
+ Size = find_wrap_values(),
+ [{name, ?LOG_NAME},
+ {file, File},
+ {repair, true},
+ {format, internal},
+ {type, wrap},
+ {size, Size},
+ {distributed, []},
+ {notify, false},
+ {head, {vsn, ?VSN}},
+ {quiet, true},
+ {mode, read_write}].
+
+-spec ensure_path([{file, string()} | {atom(), _}, ...]) -> ok | {error, term()}.
+ensure_path(Opts) ->
+ {file, Path} = lists:keyfind(file, 1, Opts),
+ filelib:ensure_dir(Path).
+
+%% @private read the logs from an already open file. Treat closed files
+%% as wrong and returns an empty list to avoid crash loops in the shell.
+-spec read_full_log(term()) -> [string()].
+read_full_log(Name) ->
+ case disk_log:chunk(Name, start) of
+ {error, no_such_log} ->
+ show_unexpected_close_warning(),
+ [];
+ eof ->
+ [];
+ {Cont, Logs} ->
+ lists:reverse(maybe_drop_header(Logs) ++ read_full_log(Name, Cont))
+ end.
+
+read_full_log(Name, Cont) ->
+ case disk_log:chunk(Name, Cont) of
+ {error, no_such_log} ->
+ show_unexpected_close_warning(),
+ [];
+ eof ->
+ [];
+ {NextCont, Logs} ->
+ maybe_drop_header(Logs) ++ read_full_log(Name, NextCont)
+ end.
+
+maybe_drop_header([{vsn, _} | Rest]) -> Rest;
+maybe_drop_header(Logs) -> Logs.
+
+-spec handle_open_error(_) -> ok.
+handle_open_error({arg_mismatch, OptName, CurrentVal, NewVal}) ->
+ show('$#erlang-history-arg-mismatch',
+ "Log file argument ~p changed value from ~p to ~p "
+ "and cannot be automatically updated. Please clear the "
+ "history files and try again.~n",
+ [OptName, CurrentVal, NewVal]);
+handle_open_error({not_a_log_file, FileName}) ->
+ show_invalid_file_warning(FileName);
+handle_open_error({invalid_index_file, FileName}) ->
+ show_invalid_file_warning(FileName);
+handle_open_error({invalid_header, Term}) ->
+ show('$#erlang-history-invalid-header',
+ "Shell history expects to be able to use the log files "
+ "which currently have unknown headers (~p) and may belong to "
+ "another mechanism. History logging will be "
+ "disabled.~n",
+ [Term]);
+handle_open_error({file_error, FileName, Reason}) ->
+ show('$#erlang-history-file-error',
+ "Error handling File ~ts. Reason: ~p~n"
+ "History logging will be disabled.~n",
+ [FileName, Reason]);
+handle_open_error(Err) ->
+ show_unexpected_warning({disk_log, open, 1}, Err).
+
+find_wrap_values() ->
+ ConfSize = case application:get_env(kernel, shell_history_file_bytes) of
+ undefined -> ?DEFAULT_SIZE;
+ {ok, S} -> S
+ end,
+ SizePerFile = max(?MIN_HISTORY_SIZE, ConfSize div ?MAX_HISTORY_FILES),
+ FileCount = if SizePerFile > ?MIN_HISTORY_SIZE ->
+ ?MAX_HISTORY_FILES
+ ; SizePerFile =< ?MIN_HISTORY_SIZE ->
+ max(1, ConfSize div SizePerFile)
+ end,
+ {SizePerFile, FileCount}.
+
+report_repairs(_, _, 0) ->
+ %% just a regular close repair
+ ok;
+report_repairs(_, Good, Bad) ->
+ show('$#erlang-history-report-repairs',
+ "The shell history log file was corrupted and was repaired. "
+ "~p bytes were recovered and ~p were lost.~n", [Good, Bad]).
+
+resize_log(Name, _OldSize, NewSize) ->
+ show('$#erlang-history-resize-attempt',
+ "Attempting to resize the log history file to ~p...", [NewSize]),
+ Opts = lists:keydelete(size, 1, log_options()),
+ _ = case disk_log:open(Opts) of
+ {error, {need_repair, _}} ->
+ _ = repair_log(Name),
+ disk_log:open(Opts);
+ _ ->
+ ok
+ end,
+ case disk_log:change_size(Name, NewSize) of
+ ok ->
+ show('$#erlang-history-resize-result',
+ "ok~n", []);
+ {error, {new_size_too_small, _}} ->
+ show('$#erlang-history-resize-result',
+ "failed (new size is too small)~n", []),
+ disable_history();
+ {error, Reason} ->
+ show('$#erlang-history-resize-result',
+ "failed (~p)~n", [Reason]),
+ disable_history()
+ end.
+
+upgrade_version(_Name, Unsupported) ->
+ %% We only know of one version and can't support a newer one
+ show('$#erlang-history-upgrade',
+ "The version for the shell logs found on disk (~p) is "
+ "not supported by the current version (~p)~n",
+ [Unsupported, ?VSN]),
+ disable_history().
+
+disable_history() ->
+ show('$#erlang-history-disable', "Disabling shell history logging.~n", []),
+ application:set_env(kernel, shell_history, force_disabled).
+
+find_path() ->
+ case application:get_env(kernel, shell_history_path) of
+ undefined -> filename:basedir(user_cache, "erlang-history");
+ {ok, Path} -> Path
+ end.
+
+to_drop() ->
+ case application:get_env(kernel, shell_history_drop) of
+ undefined ->
+ application:set_env(kernel, shell_history_drop, ?DEFAULT_DROP),
+ ?DEFAULT_DROP;
+ {ok, V} when is_list(V) -> [Ln++"\n" || Ln <- V];
+ {ok, _} -> ?DEFAULT_DROP
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Output functions %%%
+%%%%%%%%%%%%%%%%%%%%%%%%
+show_rename_warning() ->
+ show('$#erlang-history-rename-warn',
+ "A history file with a different path has already "
+ "been started for the shell of this node. The old "
+ "name will keep being used for this session.~n",
+ []).
+
+show_invalid_file_warning(FileName) ->
+ show('$#erlang-history-invalid-file',
+ "Shell history expects to be able to use the file ~ts "
+ "which currently exists and is not a file usable for "
+ "history logging purposes. History logging will be "
+ "disabled.~n", [FileName]).
+
+show_unexpected_warning({M,F,A}, Term) ->
+ show('$#erlang-history-unexpected-return',
+ "unexpected return value from ~p:~p/~p: ~p~n"
+ "shell history will be disabled for this session.~n",
+ [M,F,A,Term]).
+
+show_unexpected_close_warning() ->
+ show('$#erlang-history-unexpected-close',
+ "The shell log file has mysteriousy closed. Ignoring "
+ "currently unread history.~n", []).
+
+show_size_warning(_Current, _New) ->
+ show('$#erlang-history-size',
+ "The configured log history file size is different from "
+ "the size of the log file on disk.~n", []).
+
+show(Key, Format, Args) ->
+ case get(Key) of
+ undefined ->
+ io:format(standard_error, Format, Args),
+ put(Key, true),
+ ok;
+ true ->
+ ok
+ end.
diff --git a/lib/kernel/src/heart.erl b/lib/kernel/src/heart.erl
index eea78aabdf..8fa48d56fb 100644
--- a/lib/kernel/src/heart.erl
+++ b/lib/kernel/src/heart.erl
@@ -198,16 +198,11 @@ start_portprogram() ->
end.
get_heart_timeouts() ->
- HeartOpts = case os:getenv("HEART_BEAT_TIMEOUT") of
- false -> "";
- H when is_list(H) ->
- "-ht " ++ H
- end,
- HeartOpts ++ case os:getenv("HEART_BEAT_BOOT_DELAY") of
- false -> "";
- W when is_list(W) ->
- " -wt " ++ W
- end.
+ case os:getenv("HEART_BEAT_TIMEOUT") of
+ false -> "";
+ H when is_list(H) ->
+ "-ht " ++ H
+ end.
check_start_heart() ->
case init:get_argument(heart) of
diff --git a/lib/kernel/src/hipe_ext_format.hrl b/lib/kernel/src/hipe_ext_format.hrl
index 102cb49a2b..05c678fdec 100644
--- a/lib/kernel/src/hipe_ext_format.hrl
+++ b/lib/kernel/src/hipe_ext_format.hrl
@@ -1,3 +1,15 @@
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
%% hipe_x86_ext_format.hrl
%% Definitions for unified external object format
%% Currently: sparc, x86, amd64
diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl
index 087cceb5d8..f4c7c277ed 100644
--- a/lib/kernel/src/hipe_unified_loader.erl
+++ b/lib/kernel/src/hipe_unified_loader.erl
@@ -1,4 +1,15 @@
%% -*- erlang-indent-level: 2 -*-
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%% =======================================================================
%% Filename : hipe_unified_loader.erl
%% Module : hipe_unified_loader
@@ -41,10 +52,11 @@
% I think the real solution would be to let BIF erlang:load_module/2 redirect all
% hipe calls to the module and thereby remove post_beam_load.
+% SVERK: Can we remove -compile(no_native) now when post_beam_load is gone?
+
-export([chunk_name/1,
%% Only the code and code_server modules may call the entries below!
load_native_code/3,
- post_beam_load/1,
load_module/4,
load/3]).
@@ -101,15 +113,13 @@ word_size(Architecture) ->
load_native_code(_Mod, _Bin, undefined) ->
no_native;
load_native_code(Mod, Bin, Architecture) when is_atom(Mod), is_binary(Bin) ->
- %% patch_to_emu(Mod),
case code:get_chunk(Bin, chunk_name(Architecture)) of
undefined -> no_native;
NativeCode when is_binary(NativeCode) ->
erlang:system_flag(multi_scheduling, block_normal),
try
- OldReferencesToPatch = patch_to_emu_step1(Mod),
- case load_module(Mod, NativeCode, Bin, OldReferencesToPatch,
- Architecture) of
+ put(hipe_patch_closures, false),
+ case load_common(Mod, NativeCode, Bin, Architecture) of
bad_crc -> no_native;
Result -> Result
end
@@ -120,22 +130,6 @@ load_native_code(Mod, Bin, Architecture) when is_atom(Mod), is_binary(Bin) ->
%%========================================================================
--spec post_beam_load([module()]) -> 'ok'.
-
-post_beam_load([])->
- ok;
-post_beam_load([_|_]=Mods) ->
- erlang:system_flag(multi_scheduling, block_normal),
- try
- _ = [patch_to_emu(Mod) || Mod <- Mods],
- ok
- after
- erlang:system_flag(multi_scheduling, unblock_normal)
- end,
- ok.
-
-%%========================================================================
-
version_check(Version, Mod) when is_atom(Mod) ->
Ver = ?VERSION_STRING(),
case Version < Ver of
@@ -153,19 +147,12 @@ version_check(Version, Mod) when is_atom(Mod) ->
load_module(Mod, Bin, Beam, Architecture) ->
erlang:system_flag(multi_scheduling, block_normal),
try
- load_module_nosmp(Mod, Bin, Beam, Architecture)
+ put(hipe_patch_closures, false),
+ load_common(Mod, Bin, Beam, Architecture)
after
erlang:system_flag(multi_scheduling, unblock_normal)
end.
-load_module_nosmp(Mod, Bin, Beam, Architecture) ->
- load_module(Mod, Bin, Beam, [], Architecture).
-
-load_module(Mod, Bin, Beam, OldReferencesToPatch, Architecture) ->
- ?debug_msg("************ Loading Module ~w ************\n",[Mod]),
- %% Loading a whole module, let the BEAM loader patch closures.
- put(hipe_patch_closures, false),
- load_common(Mod, Bin, Beam, OldReferencesToPatch, Architecture).
%%========================================================================
@@ -175,20 +162,17 @@ load_module(Mod, Bin, Beam, OldReferencesToPatch, Architecture) ->
load(Mod, Bin, Architecture) ->
erlang:system_flag(multi_scheduling, block_normal),
try
- load_nosmp(Mod, Bin, Architecture)
+ ?debug_msg("********* Loading funs in module ~w *********\n",[Mod]),
+ %% Loading just some functions in a module; patch closures separately.
+ put(hipe_patch_closures, true),
+ load_common(Mod, Bin, [], Architecture)
after
erlang:system_flag(multi_scheduling, unblock_normal)
end.
-load_nosmp(Mod, Bin, Architecture) ->
- ?debug_msg("********* Loading funs in module ~w *********\n",[Mod]),
- %% Loading just some functions in a module; patch closures separately.
- put(hipe_patch_closures, true),
- load_common(Mod, Bin, [], [], Architecture).
-
%%------------------------------------------------------------------------
-load_common(Mod, Bin, Beam, OldReferencesToPatch, Architecture) ->
+load_common(Mod, Bin, Beam, Architecture) ->
%% Unpack the binary.
[{Version, CheckSum},
ConstAlign, ConstSize, ConstMap, LabelMap, ExportMap,
@@ -215,29 +199,31 @@ load_common(Mod, Bin, Beam, OldReferencesToPatch, Architecture) ->
put(closures_to_patch, []),
WordSize = word_size(Architecture),
WriteWord = write_word_fun(WordSize),
+ LoaderState = hipe_bifs:alloc_loader_state(Mod),
+ put(hipe_loader_state, LoaderState),
%% Create data segment
{ConstAddr,ConstMap2} =
- create_data_segment(ConstAlign, ConstSize, ConstMap, WriteWord),
+ create_data_segment(ConstAlign, ConstSize, ConstMap, WriteWord,
+ LoaderState),
%% Find callees for which we may need trampolines.
CalleeMFAs = find_callee_mfas(Refs, Architecture),
%% Write the code to memory.
{CodeAddress,Trampolines} =
- enter_code(CodeSize, CodeBinary, CalleeMFAs, Mod, Beam),
+ enter_code(CodeSize, CodeBinary, CalleeMFAs, LoaderState),
%% Construct CalleeMFA-to-trampoline mapping.
TrampolineMap = mk_trampoline_map(CalleeMFAs, Trampolines,
Architecture),
%% Patch references to code labels in data seg.
ok = patch_consts(LabelMap, ConstAddr, CodeAddress, WriteWord),
+
%% Find out which functions are being loaded (and where).
- %% Note: Addresses are sorted descending.
- {MFAs,Addresses} = exports(ExportMap, CodeAddress),
- %% Remove references to old versions of the module.
- ReferencesToPatch = get_refs_from(MFAs, []),
- %% io:format("References to patch: ~w~n", [ReferencesToPatch]),
- ok = remove_refs_from(MFAs),
+ %% Note: FunDefs are sorted descending address order.
+ FunDefs = exports(ExportMap, CodeAddress),
+
%% Patch all dynamic references in the code.
%% Function calls, Atoms, Constants, System calls
- ok = patch(Refs, CodeAddress, ConstMap2, Addresses, TrampolineMap),
+
+ ok = patch(Refs, CodeAddress, ConstMap2, FunDefs, TrampolineMap),
%% Tell the system where the loaded funs are.
%% (patches the BEAM code to redirect to native.)
@@ -250,25 +236,22 @@ load_common(Mod, Bin, Beam, OldReferencesToPatch, Architecture) ->
lists:foreach(fun({FE, DestAddress}) ->
hipe_bifs:set_native_address_in_fe(FE, DestAddress)
end, erase(closures_to_patch)),
- export_funs(Addresses),
+ ok = hipe_bifs:commit_patch_load(LoaderState),
+ set_beam_call_traps(FunDefs),
ok;
BeamBinary when is_binary(BeamBinary) ->
%% Find all closures in the code.
[] = erase(closures_to_patch), %Clean up, assertion.
ClosurePatches = find_closure_patches(Refs),
AddressesOfClosuresToPatch =
- calculate_addresses(ClosurePatches, CodeAddress, Addresses),
- export_funs(Addresses),
- export_funs(Mod, MD5, BeamBinary,
- Addresses, AddressesOfClosuresToPatch)
+ calculate_addresses(ClosurePatches, CodeAddress, FunDefs),
+ export_funs(FunDefs),
+ make_beam_stub(Mod, LoaderState, MD5, BeamBinary, FunDefs,
+ AddressesOfClosuresToPatch)
end,
- %% Redirect references to the old module to the new module's BEAM stub.
- patch_to_emu_step2(OldReferencesToPatch),
- %% Patch referring functions to call the new function
- %% The call to export_funs/1 above updated the native addresses
- %% for the targets, so passing 'Addresses' is not needed.
- redirect(ReferencesToPatch),
+
%% Final clean up.
+ _ = erase(hipe_loader_state),
_ = erase(hipe_patch_closures),
_ = erase(hipe_assert_code_area),
?debug_msg("****************Loader Finished****************\n", []),
@@ -371,31 +354,31 @@ trampoline_map_lookup(Primop, Map) ->
is_exported :: boolean()}).
exports(ExportMap, BaseAddress) ->
- exports(ExportMap, BaseAddress, [], []).
+ exports(ExportMap, BaseAddress, []).
-exports([Offset,M,F,A,IsClosure,IsExported|Rest], BaseAddress, MFAs, Addresses) ->
+exports([Offset,M,F,A,IsClosure,IsExported|Rest], BaseAddress, FunDefs) ->
case IsExported andalso erlang:is_builtin(M, F, A) of
true ->
- exports(Rest, BaseAddress, MFAs, Addresses);
+ exports(Rest, BaseAddress, FunDefs);
_false ->
MFA = {M,F,A},
Address = BaseAddress + Offset,
FunDef = #fundef{address=Address, mfa=MFA, is_closure=IsClosure,
is_exported=IsExported},
- exports(Rest, BaseAddress, [MFA|MFAs], [FunDef|Addresses])
+ exports(Rest, BaseAddress, [FunDef|FunDefs])
end;
-exports([], _, MFAs, Addresses) ->
- {MFAs, Addresses}.
+exports([], _, FunDefs) ->
+ FunDefs.
mod({M,_F,_A}) -> M.
%%------------------------------------------------------------------------
-calculate_addresses(PatchOffsets, Base, Addresses) ->
+calculate_addresses(PatchOffsets, Base, FunDefs) ->
RemoteOrLocal = local, % closure code refs are local
[{Data,
offsets_to_addresses(Offsets, Base),
- get_native_address(DestMFA, Addresses, RemoteOrLocal)} ||
+ get_native_address(DestMFA, FunDefs, RemoteOrLocal)} ||
{{DestMFA,_,_}=Data,Offsets} <- PatchOffsets].
offsets_to_addresses(Os, Base) ->
@@ -424,9 +407,9 @@ find_closure_refs([], Refs) ->
%%------------------------------------------------------------------------
-export_funs([FunDef | Addresses]) ->
+set_beam_call_traps([FunDef | FunDefs]) ->
#fundef{address=Address, mfa=MFA, is_closure=IsClosure,
- is_exported=IsExported} = FunDef,
+ is_exported=_IsExported} = FunDef,
?IF_DEBUG({M,F,A} = MFA, no_debug),
?IF_DEBUG(
case IsClosure of
@@ -437,21 +420,38 @@ export_funs([FunDef | Addresses]) ->
?debug_msg("LINKING: ~w:~w/~w to closure (0x~.16b)\n",
[M,F,A, Address])
end, no_debug),
- hipe_bifs:set_funinfo_native_address(MFA, Address, IsExported),
hipe_bifs:set_native_address(MFA, Address, IsClosure),
- export_funs(Addresses);
+ set_beam_call_traps(FunDefs);
+set_beam_call_traps([]) ->
+ ok.
+
+export_funs([FunDef | FunDefs]) ->
+ #fundef{address=Address, mfa=MFA, is_closure=_IsClosure,
+ is_exported=IsExported} = FunDef,
+ ?IF_DEBUG({M,F,A} = MFA, no_debug),
+ ?IF_DEBUG(
+ case _IsClosure of
+ false ->
+ ?debug_msg("LINKING: ~w:~w/~w to (0x~.16b)\n",
+ [M,F,A, Address]);
+ true ->
+ ?debug_msg("LINKING: ~w:~w/~w to closure (0x~.16b)\n",
+ [M,F,A, Address])
+ end, no_debug),
+ hipe_bifs:set_funinfo_native_address(MFA, Address, IsExported),
+ export_funs(FunDefs);
export_funs([]) ->
ok.
-export_funs(Mod, MD5, Beam, Addresses, ClosuresToPatch) ->
- Fs = [{F,A,Address} || #fundef{address=Address, mfa={_M,F,A}} <- Addresses],
- Mod = code:make_stub_module(Mod, Beam, {Fs,ClosuresToPatch,MD5}),
+make_beam_stub(Mod, LoaderState, MD5, Beam, FunDefs, ClosuresToPatch) ->
+ Fs = [{F,A,Address} || #fundef{address=Address, mfa={_M,F,A}} <- FunDefs],
+ Mod = code:make_stub_module(LoaderState, Beam, {Fs,ClosuresToPatch,MD5}),
ok.
%%========================================================================
%% Patching
%% @spec patch(refs(), BaseAddress::integer(), ConstAndZone::term(),
-%% Addresses::term(), TrampolineMap::term()) -> 'ok'.
+%% FunDefs::term(), TrampolineMap::term()) -> 'ok'.
%% @type refs()=[{RefType::integer(), Reflist::reflist()} | refs()]
%%
%% @type reflist()= [{Data::term(), Offsets::offests()}|reflist()]
@@ -463,39 +463,39 @@ export_funs(Mod, MD5, Beam, Addresses, ClosuresToPatch) ->
%% (we use this to look up the address of a referred function only once).
%%
-patch([{Type,SortedRefs}|Rest], CodeAddress, ConstMap2, Addresses, TrampolineMap) ->
+patch([{Type,SortedRefs}|Rest], CodeAddress, ConstMap2, FunDefs, TrampolineMap) ->
?debug_msg("Patching ~w at [~w+offset] with ~w\n",
[Type,CodeAddress,SortedRefs]),
case ?EXT2PATCH_TYPE(Type) of
call_local ->
- patch_call(SortedRefs, CodeAddress, Addresses, 'local', TrampolineMap);
+ patch_call(SortedRefs, CodeAddress, FunDefs, 'local', TrampolineMap);
call_remote ->
- patch_call(SortedRefs, CodeAddress, Addresses, 'remote', TrampolineMap);
+ patch_call(SortedRefs, CodeAddress, FunDefs, 'remote', TrampolineMap);
Other ->
- patch_all(Other, SortedRefs, CodeAddress, {ConstMap2,CodeAddress}, Addresses)
+ patch_all(Other, SortedRefs, CodeAddress, {ConstMap2,CodeAddress}, FunDefs)
end,
- patch(Rest, CodeAddress, ConstMap2, Addresses, TrampolineMap);
+ patch(Rest, CodeAddress, ConstMap2, FunDefs, TrampolineMap);
patch([], _, _, _, _) -> ok.
%%----------------------------------------------------------------
%% Handle a 'call_local' or 'call_remote' patch.
%%
-patch_call([{DestMFA,Offsets}|SortedRefs], BaseAddress, Addresses, RemoteOrLocal, TrampolineMap) ->
+patch_call([{DestMFA,Offsets}|SortedRefs], BaseAddress, FunDefs, RemoteOrLocal, TrampolineMap) ->
case bif_address(DestMFA) of
false ->
- %% Previous code used mfa_to_address(DestMFA, Addresses)
+ %% Previous code used mfa_to_address(DestMFA, FunDefs)
%% here for local calls. That is wrong because even local
- %% destinations may not be present in Addresses: they may
+ %% destinations may not be present in FunDefs: they may
%% not have been compiled yet, or they may be BEAM-only
%% functions (e.g. module_info).
- DestAddress = get_native_address(DestMFA, Addresses, RemoteOrLocal),
+ DestAddress = get_native_address(DestMFA, FunDefs, RemoteOrLocal),
Trampoline = trampoline_map_get(DestMFA, TrampolineMap),
- patch_mfa_call_list(Offsets, BaseAddress, DestMFA, DestAddress, Addresses, RemoteOrLocal, Trampoline);
+ patch_mfa_call_list(Offsets, BaseAddress, DestMFA, DestAddress, FunDefs, RemoteOrLocal, Trampoline);
BifAddress when is_integer(BifAddress) ->
Trampoline = trampoline_map_lookup(DestMFA, TrampolineMap),
patch_bif_call_list(Offsets, BaseAddress, BifAddress, Trampoline)
end,
- patch_call(SortedRefs, BaseAddress, Addresses, RemoteOrLocal, TrampolineMap);
+ patch_call(SortedRefs, BaseAddress, FunDefs, RemoteOrLocal, TrampolineMap);
patch_call([], _, _, _, _) ->
ok.
@@ -506,49 +506,48 @@ patch_bif_call_list([Offset|Offsets], BaseAddress, BifAddress, Trampoline) ->
patch_bif_call_list(Offsets, BaseAddress, BifAddress, Trampoline);
patch_bif_call_list([], _, _, _) -> ok.
-patch_mfa_call_list([Offset|Offsets], BaseAddress, DestMFA, DestAddress, Addresses, RemoteOrLocal, Trampoline) ->
+patch_mfa_call_list([Offset|Offsets], BaseAddress, DestMFA, DestAddress, FunDefs, RemoteOrLocal, Trampoline) ->
CallAddress = BaseAddress+Offset,
- add_ref(DestMFA, CallAddress, Addresses, 'call', Trampoline, RemoteOrLocal),
+ add_ref(DestMFA, CallAddress, FunDefs, 'call', Trampoline, RemoteOrLocal),
?ASSERT(assert_local_patch(CallAddress)),
patch_call_insn(CallAddress, DestAddress, Trampoline),
- patch_mfa_call_list(Offsets, BaseAddress, DestMFA, DestAddress, Addresses, RemoteOrLocal, Trampoline);
+ patch_mfa_call_list(Offsets, BaseAddress, DestMFA, DestAddress, FunDefs, RemoteOrLocal, Trampoline);
patch_mfa_call_list([], _, _, _, _, _, _) -> ok.
patch_call_insn(CallAddress, DestAddress, Trampoline) ->
- %% This assertion is false when we're called from redirect/2.
- %% ?ASSERT(assert_local_patch(CallAddress)),
+ ?ASSERT(assert_local_patch(CallAddress)),
hipe_bifs:patch_call(CallAddress, DestAddress, Trampoline).
%% ____________________________________________________________________
%%
-patch_all(Type, [{Dest,Offsets}|Rest], BaseAddress, ConstAndZone, Addresses)->
- patch_all_offsets(Type, Dest, Offsets, BaseAddress, ConstAndZone, Addresses),
- patch_all(Type, Rest, BaseAddress, ConstAndZone, Addresses);
+patch_all(Type, [{Dest,Offsets}|Rest], BaseAddress, ConstAndZone, FunDefs)->
+ patch_all_offsets(Type, Dest, Offsets, BaseAddress, ConstAndZone, FunDefs),
+ patch_all(Type, Rest, BaseAddress, ConstAndZone, FunDefs);
patch_all(_, [], _, _, _) -> ok.
patch_all_offsets(Type, Data, [Offset|Offsets], BaseAddress,
- ConstAndZone, Addresses) ->
+ ConstAndZone, FunDefs) ->
?debug_msg("Patching ~w at [~w+~w] with ~w\n",
[Type,BaseAddress,Offset, Data]),
Address = BaseAddress + Offset,
- patch_offset(Type, Data, Address, ConstAndZone, Addresses),
+ patch_offset(Type, Data, Address, ConstAndZone, FunDefs),
?debug_msg("Patching done\n",[]),
- patch_all_offsets(Type, Data, Offsets, BaseAddress, ConstAndZone, Addresses);
+ patch_all_offsets(Type, Data, Offsets, BaseAddress, ConstAndZone, FunDefs);
patch_all_offsets(_, _, [], _, _, _) -> ok.
%%----------------------------------------------------------------
%% Handle any patch type except 'call_local' or 'call_remote'.
%%
-patch_offset(Type, Data, Address, ConstAndZone, Addresses) ->
+patch_offset(Type, Data, Address, ConstAndZone, FunDefs) ->
case Type of
load_address ->
- patch_load_address(Data, Address, ConstAndZone, Addresses);
+ patch_load_address(Data, Address, ConstAndZone, FunDefs);
load_atom ->
Atom = Data,
patch_atom(Address, Atom);
sdesc ->
- patch_sdesc(Data, Address, ConstAndZone, Addresses);
+ patch_sdesc(Data, Address, ConstAndZone, FunDefs);
x86_abs_pcrel ->
patch_instr(Address, Data, x86_abs_pcrel)
%% _ ->
@@ -561,37 +560,38 @@ patch_atom(Address, Atom) ->
patch_instr(Address, hipe_bifs:atom_to_word(Atom), atom).
patch_sdesc(?STACK_DESC(SymExnRA, FSize, Arity, Live),
- Address, {_ConstMap2,CodeAddress}, _Addresses) ->
+ Address, {_ConstMap2,CodeAddress}, FunDefs) ->
ExnRA =
case SymExnRA of
[] -> 0; % No catch
LabelOffset -> CodeAddress + LabelOffset
end,
?ASSERT(assert_local_patch(Address)),
- DBG_MFA = ?IF_DEBUG(address_to_mfa_lth(Address, _Addresses), {undefined,undefined,0}),
- hipe_bifs:enter_sdesc({Address, ExnRA, FSize, Arity, Live, DBG_MFA}).
+ MFA = address_to_mfa_lth(Address, FunDefs),
+ hipe_bifs:enter_sdesc({Address, ExnRA, FSize, Arity, Live, MFA},
+ get(hipe_loader_state)).
%%----------------------------------------------------------------
%% Handle a 'load_address'-type patch.
%%
-patch_load_address(Data, Address, ConstAndZone, Addresses) ->
+patch_load_address(Data, Address, ConstAndZone, FunDefs) ->
case Data of
{local_function,DestMFA} ->
- patch_load_mfa(Address, DestMFA, Addresses, 'local');
+ patch_load_mfa(Address, DestMFA, FunDefs, 'local');
{remote_function,DestMFA} ->
- patch_load_mfa(Address, DestMFA, Addresses, 'remote');
+ patch_load_mfa(Address, DestMFA, FunDefs, 'remote');
{constant,Name} ->
{ConstMap2,_CodeAddress} = ConstAndZone,
ConstAddress = find_const(Name, ConstMap2),
patch_instr(Address, ConstAddress, constant);
{closure,{DestMFA,Uniq,Index}} ->
- patch_closure(DestMFA, Uniq, Index, Address, Addresses);
+ patch_closure(DestMFA, Uniq, Index, Address, FunDefs);
{c_const,CConst} ->
patch_instr(Address, bif_address(CConst), c_const)
end.
-patch_closure(DestMFA, Uniq, Index, Address, Addresses) ->
+patch_closure(DestMFA, Uniq, Index, Address, FunDefs) ->
case get(hipe_patch_closures) of
false ->
[]; % This is taken care of when registering the module.
@@ -602,7 +602,7 @@ patch_closure(DestMFA, Uniq, Index, Address, Addresses) ->
%% address into the fun entry to ensure that the native code cannot
%% be called until it has been completely fixed up.
RemoteOrLocal = local, % closure code refs are local
- DestAddress = get_native_address(DestMFA, Addresses, RemoteOrLocal),
+ DestAddress = get_native_address(DestMFA, FunDefs, RemoteOrLocal),
BEAMAddress = hipe_bifs:fun_to_address(DestMFA),
FE = hipe_bifs:get_fe(mod(DestMFA), {Uniq, Index, BEAMAddress}),
put(closures_to_patch, [{FE,DestAddress}|get(closures_to_patch)]),
@@ -616,17 +616,17 @@ patch_closure(DestMFA, Uniq, Index, Address, Addresses) ->
%% Patch an instruction loading the address of an MFA.
%% RemoteOrLocal ::= 'remote' | 'local'
%%
-patch_load_mfa(CodeAddress, DestMFA, Addresses, RemoteOrLocal) ->
+patch_load_mfa(CodeAddress, DestMFA, FunDefs, RemoteOrLocal) ->
+ ?ASSERT(assert_local_patch(CodeAddress)),
DestAddress =
case bif_address(DestMFA) of
false ->
- NativeAddress = get_native_address(DestMFA, Addresses, RemoteOrLocal),
- add_ref(DestMFA, CodeAddress, Addresses, 'load_mfa', [], RemoteOrLocal),
+ NativeAddress = get_native_address(DestMFA, FunDefs, RemoteOrLocal),
+ add_ref(DestMFA, CodeAddress, FunDefs, 'load_mfa', [], RemoteOrLocal),
NativeAddress;
BifAddress when is_integer(BifAddress) ->
BifAddress
end,
- ?ASSERT(assert_local_patch(CodeAddress)),
patch_instr(CodeAddress, DestAddress, 'load_mfa').
%%----------------------------------------------------------------
@@ -702,9 +702,9 @@ bif_address(Name) when is_atom(Name) ->
%% memory, and produces a ConstMap2 mapping each constant's ConstNo to
%% its runtime address, tagged if the constant is a term.
%%
-create_data_segment(DataAlign, DataSize, DataList, WriteWord) ->
+create_data_segment(DataAlign, DataSize, DataList, WriteWord, LoaderState) ->
%%io:format("create_data_segment: \nDataAlign: ~p\nDataSize: ~p\nDataList: ~p\n",[DataAlign,DataSize,DataList]),
- DataAddress = hipe_bifs:alloc_data(DataAlign, DataSize),
+ DataAddress = hipe_bifs:alloc_data(DataAlign, DataSize, LoaderState),
enter_data(DataList, [], DataAddress, DataSize, WriteWord).
enter_data(List, ConstMap2, DataAddress, DataSize, WriteWord) ->
@@ -772,7 +772,7 @@ find_const(ConstNo, []) ->
%%----------------------------------------------------------------
%% Record that the code at address 'Address' has a reference
%% of type 'RefType' ('call' or 'load_mfa') to 'CalleeMFA'.
-%% 'Addresses' must be an address-descending list from exports/2.
+%% 'FunDefs' must be an address-descending list from exports/2.
%%
%% If 'RefType' is 'call', then 'Trampoline' may be the address
%% of a stub branching to 'CalleeMFA', where the stub is reachable
@@ -781,34 +781,29 @@ find_const(ConstNo, []) ->
%% RemoteOrLocal ::= 'remote' | 'local'.
%%
-%%
-%% -record(ref, {caller_mfa, address, ref_type, trampoline, remote_or_local}).
-%%
+add_ref(CalleeMFA, Address, FunDefs, RefType, Trampoline, RemoteOrLocal) ->
+ CallerMFA = address_to_mfa_lth(Address, FunDefs),
+ case RemoteOrLocal of
+ local ->
+ %% assert that the callee and caller are from the same module
+ {M,_,_} = CalleeMFA,
+ {M,_,_} = CallerMFA,
+ ok;
+ remote ->
+ hipe_bifs:add_ref(CalleeMFA, {CallerMFA,Address,RefType,Trampoline,
+ get(hipe_loader_state)})
+ end.
-add_ref(CalleeMFA, Address, Addresses, RefType, Trampoline, RemoteOrLocal) ->
- CallerMFA = address_to_mfa_lth(Address, Addresses),
- %% just a sanity assertion below
- true = case RemoteOrLocal of
- local ->
- {M1,_,_} = CalleeMFA,
- {M2,_,_} = CallerMFA,
- M1 =:= M2;
- remote ->
- true
- end,
- %% io:format("Adding ref ~w\n",[{CallerMFA, CalleeMFA, Address, RefType}]),
- hipe_bifs:add_ref(CalleeMFA, {CallerMFA,Address,RefType,Trampoline,RemoteOrLocal}).
-
-% For FunDefs sorted from low to high addresses
+%% For FunDefs sorted from low to high addresses
address_to_mfa_lth(Address, FunDefs) ->
- case address_to_mfa_lth(Address, FunDefs, false) of
- false ->
- ?error_msg("Local adddress not found ~w\n",[Address]),
- exit({?MODULE, local_address_not_found});
- MFA ->
- MFA
- end.
-
+ case address_to_mfa_lth(Address, FunDefs, false) of
+ false ->
+ ?error_msg("Local adddress not found ~w\n",[Address]),
+ exit({?MODULE, local_address_not_found});
+ MFA ->
+ MFA
+ end.
+
address_to_mfa_lth(Address, [#fundef{address=Adr, mfa=MFA}|Rest], Prev) ->
if Address < Adr ->
Prev;
@@ -818,107 +813,33 @@ address_to_mfa_lth(Address, [#fundef{address=Adr, mfa=MFA}|Rest], Prev) ->
address_to_mfa_lth(_Address, [], Prev) ->
Prev.
-% For FunDefs sorted from high to low addresses
+%% For FunDefs sorted from high to low addresses
%% address_to_mfa_htl(Address, [#fundef{address=Adr, mfa=MFA}|_Rest]) when Address >= Adr -> MFA;
%% address_to_mfa_htl(Address, [_ | Rest]) -> address_to_mfa_htl(Address, Rest);
%% address_to_mfa_htl(Address, []) ->
%% ?error_msg("Local adddress not found ~w\n",[Address]),
%% exit({?MODULE, local_address_not_found}).
-%%----------------------------------------------------------------
-%% Change callers of the given module to instead trap to BEAM.
-%% load_native_code/3 calls this just before loading native code.
-%%
-patch_to_emu(Mod) ->
- patch_to_emu_step2(patch_to_emu_step1(Mod)).
-
-%% Step 1 must occur before the loading of native code updates
-%% references information or creates a new BEAM stub module.
-patch_to_emu_step1(Mod) ->
- case is_loaded(Mod) of
- true ->
- %% Get exported functions
- MFAs = [{Mod,Fun,Arity} || {Fun,Arity} <- Mod:module_info(exports)],
- %% get_refs_from/2 only finds references from compiled static
- %% call sites to the module, but some native address entries
- %% were added as the result of dynamic apply calls. We must
- %% purge them too, but we have no explicit record of them.
- %% Therefore invalidate all native addresses for the module.
- hipe_bifs:invalidate_funinfo_native_addresses(MFAs),
- %% Find all call sites that call these MFAs. As a side-effect,
- %% create native stubs for any MFAs that are referred.
- ReferencesToPatch = get_refs_from(MFAs, []),
- ok = remove_refs_from(MFAs),
- ReferencesToPatch;
- false ->
- %% The first time we load the module, no redirection needs to be done.
- []
- end.
-
-%% Step 2 must occur after the new BEAM stub module is created.
-patch_to_emu_step2(ReferencesToPatch) ->
- redirect(ReferencesToPatch).
-
--spec is_loaded(Module::atom()) -> boolean().
-%% @doc Checks whether a module is loaded or not.
-is_loaded(M) when is_atom(M) ->
- try hipe_bifs:fun_to_address({M,module_info,0}) of
- I when is_integer(I) -> true
- catch _:_ -> false
- end.
-
-%%--------------------------------------------------------------------
-%% Given a list of MFAs, tag them with their referred_from references.
-%% The resulting {MFA,Refs} list is later passed to redirect/1, once
-%% the MFAs have been bound to (possibly new) native-code addresses.
-%%
-get_refs_from(MFAs, []) ->
- mark_referred_from(MFAs),
- MFAs.
-
-mark_referred_from(MFAs) ->
- lists:foreach(fun(MFA) -> hipe_bifs:mark_referred_from(MFA) end, MFAs).
-
-%%--------------------------------------------------------------------
-%% Given a list of MFAs with referred_from references, update their
-%% callers to refer to their new native-code addresses.
-%%
-%% The {MFA,Refs} list must come from get_refs_from/2.
-%%
-redirect(MFAs) ->
- lists:foreach(fun(MFA) -> hipe_bifs:redirect_referred_from(MFA) end, MFAs).
-
-%%--------------------------------------------------------------------
-%% Given a list of MFAs, remove all referred_from references having
-%% any of them as CallerMFA.
-%%
-%% This is the only place using refers_to. Whenever a reference is
-%% added from CallerMFA to CalleeMFA, CallerMFA is added to CalleeMFA's
-%% referred_from list, and CalleeMFA is added to CallerMFA's refers_to
-%% list. The refers_to list is used here to find the CalleeMFAs whose
-%% referred_from lists should be updated.
-%%
-remove_refs_from(MFAs) ->
- lists:foreach(fun(MFA) -> hipe_bifs:remove_refs_from(MFA) end, MFAs).
%%--------------------------------------------------------------------
%% To find the native code of an MFA we need to look in 3 places:
-%% 1. If it is compiled now look in the Addresses data structure.
+%% 1. If it is compiled now look in the FunDefs data structure.
%% 2. Then look in native_addresses from module info.
%% 3. Then (the function might have been singled compiled) look in
%% hipe_funinfo
%% If all else fails create a native stub for the MFA
-get_native_address(MFA, Addresses, RemoteOrLocal) ->
- case mfa_to_address(MFA, Addresses, RemoteOrLocal) of
+get_native_address(MFA, FunDefs, RemoteOrLocal) ->
+ case mfa_to_address(MFA, FunDefs, RemoteOrLocal) of
Adr when is_integer(Adr) -> Adr;
false ->
- IsRemote =
case RemoteOrLocal of
- remote -> true;
- local -> false
- end,
- hipe_bifs:find_na_or_make_stub(MFA, IsRemote)
+ remote ->
+ hipe_bifs:find_na_or_make_stub(MFA);
+ local ->
+ ?error_msg("Local function ~p not found\n",[MFA]),
+ exit({function_not_found,MFA})
+ end
end.
mfa_to_address(MFA, [#fundef{address=Adr, mfa=MFA,
@@ -958,12 +879,10 @@ assert_local_patch(Address) when is_integer(Address) ->
%% ____________________________________________________________________
%%
-%% Beam: nil() | binary() (used as a flag)
-
-enter_code(CodeSize, CodeBinary, CalleeMFAs, Mod, Beam) ->
+enter_code(CodeSize, CodeBinary, CalleeMFAs, LoaderState) ->
true = byte_size(CodeBinary) =:= CodeSize,
- hipe_bifs:update_code_size(Mod, Beam, CodeSize),
- {CodeAddress,Trampolines} = hipe_bifs:enter_code(CodeBinary, CalleeMFAs),
+ {CodeAddress,Trampolines} = hipe_bifs:enter_code(CodeBinary, CalleeMFAs,
+ LoaderState),
?init_assert_patch(CodeAddress, byte_size(CodeBinary)),
{CodeAddress,Trampolines}.
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index a91a6ed517..6aef5476f1 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -75,6 +75,7 @@
-export_type([address_family/0, hostent/0, hostname/0, ip4_address/0,
ip6_address/0, ip_address/0, port_number/0,
local_address/0, socket_address/0, returned_non_ip_address/0,
+ socket_setopt/0, socket_getopt/0,
posix/0, socket/0, stat_option/0]).
%% imports
-import(lists, [append/1, duplicate/2, filter/2, foldl/3]).
@@ -676,7 +677,7 @@ parse_strict_address(Addr) ->
%% Return a list of available options
options() ->
[
- tos, priority, reuseaddr, keepalive, dontroute, linger,
+ tos, tclass, priority, reuseaddr, keepalive, dontroute, linger,
broadcast, sndbuf, recbuf, nodelay, ipv6_v6only,
buffer, header, active, packet, deliver, mode,
multicast_if, multicast_ttl, multicast_loop,
@@ -697,11 +698,11 @@ stats() ->
%% Available options for tcp:connect
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
connect_options() ->
- [tos, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay,
+ [tos, tclass, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay,
header, active, packet, packet_size, buffer, mode, deliver, line_delimiter,
exit_on_close, high_watermark, low_watermark, high_msgq_watermark,
low_msgq_watermark, send_timeout, send_timeout_close, delay_send, raw,
- show_econnreset].
+ show_econnreset, bind_to_device].
connect_options(Opts, Mod) ->
BaseOpts =
@@ -765,11 +766,11 @@ con_add(Name, Val, #connect_opts{} = R, Opts, AllOpts) ->
%% Available options for tcp:listen
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
listen_options() ->
- [tos, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay,
+ [tos, tclass, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay,
header, active, packet, buffer, mode, deliver, backlog, ipv6_v6only,
exit_on_close, high_watermark, low_watermark, high_msgq_watermark,
low_msgq_watermark, send_timeout, send_timeout_close, delay_send,
- packet_size, raw, show_econnreset].
+ packet_size, raw, show_econnreset, bind_to_device].
listen_options(Opts, Mod) ->
BaseOpts =
@@ -845,11 +846,11 @@ tcp_module_1(Opts, Address) ->
%% Available options for udp:open
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
udp_options() ->
- [tos, priority, reuseaddr, sndbuf, recbuf, header, active, buffer, mode,
+ [tos, tclass, priority, reuseaddr, sndbuf, recbuf, header, active, buffer, mode,
deliver, ipv6_v6only,
broadcast, dontroute, multicast_if, multicast_ttl, multicast_loop,
add_membership, drop_membership, read_packets,raw,
- high_msgq_watermark, low_msgq_watermark].
+ high_msgq_watermark, low_msgq_watermark, bind_to_device].
udp_options(Opts, Mod) ->
@@ -916,8 +917,9 @@ udp_module(Opts) ->
% (*) passing of open FDs ("fdopen") is not supported.
sctp_options() ->
[ % The following are generic inet options supported for SCTP sockets:
- mode, active, buffer, tos, priority, dontroute, reuseaddr, linger, sndbuf,
+ mode, active, buffer, tos, tclass, priority, dontroute, reuseaddr, linger, sndbuf,
recbuf, ipv6_v6only, high_msgq_watermark, low_msgq_watermark,
+ bind_to_device,
% Other options are SCTP-specific (though they may be similar to their
% TCP and UDP counter-parts):
@@ -1054,7 +1056,6 @@ binary2filename(Bin) ->
Bin
end.
-
translate_ip(any, inet) -> {0,0,0,0};
translate_ip(loopback, inet) -> {127,0,0,1};
translate_ip(any, inet6) -> {0,0,0,0,0,0,0,0};
diff --git a/lib/kernel/src/inet6_tcp_dist.erl b/lib/kernel/src/inet6_tcp_dist.erl
index 3aa61973af..9b6c2745d5 100644
--- a/lib/kernel/src/inet6_tcp_dist.erl
+++ b/lib/kernel/src/inet6_tcp_dist.erl
@@ -24,6 +24,7 @@
-export([listen/1, accept/1, accept_connection/5,
setup/5, close/1, select/1, is_node_name/1]).
+-export([setopts/2, getopts/2]).
%% ------------------------------------------------------------
%% Select this protocol based on node name
@@ -72,3 +73,9 @@ close(Socket) ->
is_node_name(Node) when is_atom(Node) ->
inet_tcp_dist:is_node_name(Node).
+
+setopts(S, Opts) ->
+ inet_tcp_dist:setopts(S, Opts).
+
+getopts(S, Opts) ->
+ inet_tcp_dist:getopts(S, Opts).
diff --git a/lib/kernel/src/inet_db.erl b/lib/kernel/src/inet_db.erl
index 465cec1b45..6cbb6ac2da 100644
--- a/lib/kernel/src/inet_db.erl
+++ b/lib/kernel/src/inet_db.erl
@@ -1379,7 +1379,8 @@ cache_rr(_Db, Cache, RR) ->
ets:insert(Cache, RR).
times() ->
- erlang:convert_time_unit(erlang:monotonic_time() - erlang:system_info(start_time),native,seconds).
+ erlang:convert_time_unit(erlang:monotonic_time() - erlang:system_info(start_time),
+ native, second).
%% lookup and remove old entries
diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl
index c8a8962e78..bc5b67f7bf 100644
--- a/lib/kernel/src/inet_int.hrl
+++ b/lib/kernel/src/inet_int.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -153,6 +153,8 @@
-define(INET_LOPT_NETNS, 38).
-define(INET_LOPT_TCP_SHOW_ECONNRESET, 39).
-define(INET_LOPT_LINE_DELIM, 40).
+-define(INET_OPT_TCLASS, 41).
+-define(INET_OPT_BIND_TO_DEVICE, 42).
% Specific SCTP options: separate range:
-define(SCTP_OPT_RTOINFO, 100).
-define(SCTP_OPT_ASSOCINFO, 101).
diff --git a/lib/kernel/src/inet_parse.erl b/lib/kernel/src/inet_parse.erl
index b0a3ee3008..29804dc50b 100644
--- a/lib/kernel/src/inet_parse.erl
+++ b/lib/kernel/src/inet_parse.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -644,8 +644,12 @@ ipv6_addr(Cs) ->
ipv6_addr(hex(Cs), [], 0).
%% Before "::"
+ipv6_addr({Cs0,"%"++Cs1}, A, N) when N == 7 ->
+ ipv6_addr_scope(Cs1, [hex_to_int(Cs0)|A], [], N+1, []);
ipv6_addr({Cs0,[]}, A, N) when N == 7 ->
ipv6_addr_done([hex_to_int(Cs0)|A]);
+ipv6_addr({Cs0,"::%"++Cs1}, A, N) when N =< 6 ->
+ ipv6_addr_scope(Cs1, [hex_to_int(Cs0)|A], [], N+1, []);
ipv6_addr({Cs0,"::"}, A, N) when N =< 6 ->
ipv6_addr_done([hex_to_int(Cs0)|A], [], N+1);
ipv6_addr({Cs0,"::"++Cs1}, A, N) when N =< 5 ->
@@ -658,6 +662,8 @@ ipv6_addr(_, _, _) ->
erlang:error(badarg).
%% After "::"
+ipv6_addr({Cs0,"%"++Cs1}, A, B, N) when N =< 6 ->
+ ipv6_addr_scope(Cs1, A, [hex_to_int(Cs0)|B], N+1, []);
ipv6_addr({Cs0,[]}, A, B, N) when N =< 6 ->
ipv6_addr_done(A, [hex_to_int(Cs0)|B], N+1);
ipv6_addr({Cs0,":"++Cs1}, A, B, N) when N =< 5 ->
@@ -667,6 +673,43 @@ ipv6_addr({Cs0,"."++_=Cs1}, A, B, N) when N =< 5 ->
ipv6_addr(_, _, _, _) ->
erlang:error(badarg).
+%% After "%"
+ipv6_addr_scope([], Ar, Br, N, Sr) ->
+ ScopeId =
+ case lists:reverse(Sr) of
+ %% Empty scope id
+ "" -> 0;
+ %% Scope id starts with 0
+ "0"++S -> dec16(S);
+ _ -> 0
+ end,
+ %% Suggested formats for scope id parsing:
+ %% "" -> "0"
+ %% "0" -> Scope id 0
+ %% "1" - "9", "10" - "99" -> "0"++S
+ %% "0"++DecimalScopeId -> decimal scope id
+ %% "25"++PercentEncoded -> Percent encoded interface name
+ %% S -> Interface name (Unicode?)
+ %% Missing: translation from interface name into integer scope id.
+ %% XXX: scope id is actually 32 bit, but we only have room for
+ %% 16 bit in the second address word - ignore or fix (how)?
+ ipv6_addr_scope(ScopeId, Ar, Br, N);
+ipv6_addr_scope([C|Cs], Ar, Br, N, Sr) ->
+ ipv6_addr_scope(Cs, Ar, Br, N, [C|Sr]).
+%%
+ipv6_addr_scope(ScopeId, [P], Br, N)
+ when N =< 7, P =:= 16#fe80;
+ N =< 7, P =:= 16#ff02 ->
+ %% Optimized special case
+ ipv6_addr_done([ScopeId,P], Br, N+1);
+ipv6_addr_scope(ScopeId, Ar, Br, N) ->
+ case lists:reverse(Br++dup(8-N, 0, Ar)) of
+ [P,0|Xs] when P =:= 16#fe80; P =:= 16#ff02 ->
+ list_to_tuple([P,ScopeId|Xs]);
+ _ ->
+ erlang:error(badarg)
+ end.
+
ipv6_addr_done(Ar, Br, N, {D1,D2,D3,D4}) ->
ipv6_addr_done(Ar, [((D3 bsl 8) bor D4),((D1 bsl 8) bor D2)|Br], N+2).
@@ -690,6 +733,19 @@ hex(Cs, [_|_]=R, _) when is_list(Cs) ->
hex(_, _, _) ->
erlang:error(badarg).
+%% Parse a reverse decimal integer string, empty is 0
+dec16(Cs) -> dec16(Cs, 0).
+%%
+dec16([], I) -> I;
+dec16([C|Cs], I) when C >= $0, C =< $9 ->
+ case 10*I + (C - $0) of
+ J when 16#ffff < J ->
+ erlang:error(badarg);
+ J ->
+ dec16(Cs, J)
+ end;
+dec16(_, _) -> erlang:error(badarg).
+
%% Hex string to integer
hex_to_int(Cs) -> erlang:list_to_integer(Cs, 16).
@@ -701,9 +757,9 @@ dup(N, E, L) when is_integer(N), N >= 1 ->
-%% Convert IPv4 adress to ascii
-%% Convert IPv6 / IPV4 adress to ascii (plain format)
-ntoa({A,B,C,D}) ->
+%% Convert IPv4 address to ascii
+%% Convert IPv6 / IPV4 address to ascii (plain format)
+ntoa({A,B,C,D}) when (A band B band C band D band (bnot 16#ff)) =:= 0 ->
integer_to_list(A) ++ "." ++ integer_to_list(B) ++ "." ++
integer_to_list(C) ++ "." ++ integer_to_list(D);
%% ANY
@@ -711,13 +767,25 @@ ntoa({0,0,0,0,0,0,0,0}) -> "::";
%% LOOPBACK
ntoa({0,0,0,0,0,0,0,1}) -> "::1";
%% IPV4 ipv6 host address
-ntoa({0,0,0,0,0,0,A,B}) -> "::" ++ dig_to_dec(A) ++ "." ++ dig_to_dec(B);
+ntoa({0,0,0,0,0,0,A,B}) when (A band B band (bnot 16#ffff)) =:= 0 ->
+ "::" ++ dig_to_dec(A) ++ "." ++ dig_to_dec(B);
%% IPV4 non ipv6 host address
-ntoa({0,0,0,0,0,16#ffff,A,B}) ->
- "::FFFF:" ++ dig_to_dec(A) ++ "." ++ dig_to_dec(B);
-ntoa({_,_,_,_,_,_,_,_}=T) ->
- %% Find longest sequence of zeros, at least 2, to replace with "::"
- ntoa(tuple_to_list(T), []);
+ntoa({0,0,0,0,0,16#ffff,A,B}) when (A band B band (bnot 16#ffff)) =:= 0 ->
+ "::ffff:" ++ dig_to_dec(A) ++ "." ++ dig_to_dec(B);
+ntoa({A,B,C,D,E,F,G,H})
+ when (A band B band C band D band E band F band G band H band
+ (bnot 16#ffff)) =:= 0 ->
+ if
+ A =:= 16#fe80, B =/= 0;
+ A =:= 16#ff02, B =/= 0 ->
+ %% Find longest sequence of zeros, at least 2,
+ %% to replace with "::"
+ ntoa([A,0,C,D,E,F,G,H], []) ++ "%0" ++ integer_to_list(B);
+ true ->
+ %% Find longest sequence of zeros, at least 2,
+ %% to replace with "::"
+ ntoa([A,B,C,D,E,F,G,H], [])
+ end;
ntoa(_) ->
{error, einval}.
@@ -780,9 +848,19 @@ dig_to_dec(X) ->
integer_to_list((X bsr 8) band 16#ff) ++ "." ++
integer_to_list(X band 16#ff).
-%% Convert a integer to hex string
-dig_to_hex(X) ->
- erlang:integer_to_list(X, 16).
+%% Convert a integer to hex string (lowercase)
+dig_to_hex(0) -> "0";
+dig_to_hex(X) when is_integer(X), 0 < X ->
+ dig_to_hex(X, "").
+%%
+dig_to_hex(0, Acc) -> Acc;
+dig_to_hex(X, Acc) ->
+ dig_to_hex(
+ X bsr 4,
+ [case X band 15 of
+ D when D < 10 -> D + $0;
+ D -> D - 10 + $a
+ end|Acc]).
%%
%% Count number of '.' in a name
diff --git a/lib/kernel/src/inet_tcp_dist.erl b/lib/kernel/src/inet_tcp_dist.erl
index f91d7ef7c3..e3fdb1bb22 100644
--- a/lib/kernel/src/inet_tcp_dist.erl
+++ b/lib/kernel/src/inet_tcp_dist.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,13 +24,16 @@
-export([listen/1, accept/1, accept_connection/5,
setup/5, close/1, select/1, is_node_name/1]).
+%% Optional
+-export([setopts/2, getopts/2]).
+
%% Generalized dist API
-export([gen_listen/2, gen_accept/2, gen_accept_connection/6,
gen_setup/6, gen_select/2]).
%% internal exports
--export([accept_loop/3,do_accept/7,do_setup/7,getstat/1]).
+-export([accept_loop/3,do_accept/7,do_setup/7,getstat/1,tick/2]).
-import(error_logger,[error_msg/2]).
@@ -74,7 +77,7 @@ gen_listen(Driver, Name) ->
TcpAddress = get_tcp_address(Driver, Socket),
{_,Port} = TcpAddress#net_address.address,
ErlEpmd = net_kernel:epmd_module(),
- case ErlEpmd:register_node(Name, Port) of
+ case ErlEpmd:register_node(Name, Port, Driver) of
{ok, Creation} ->
{ok, {Socket, TcpAddress, Creation}};
Error ->
@@ -215,8 +218,10 @@ do_accept(Driver, Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
inet:getll(S)
end,
f_address = fun(S, Node) -> get_remote_id(Driver, S, Node) end,
- mf_tick = fun(S) -> tick(Driver, S) end,
- mf_getstat = fun ?MODULE:getstat/1
+ mf_tick = fun(S) -> ?MODULE:tick(Driver, S) end,
+ mf_getstat = fun ?MODULE:getstat/1,
+ mf_setopts = fun ?MODULE:setopts/2,
+ mf_getopts = fun ?MODULE:getopts/2
},
dist_util:handshake_other_started(HSData);
{false,IP} ->
@@ -320,6 +325,7 @@ do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
{packet, 4},
nodelay()])
end,
+
f_getll = fun inet:getll/1,
f_address =
fun(_,_) ->
@@ -329,9 +335,11 @@ do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
protocol = tcp,
family = AddressFamily}
end,
- mf_tick = fun(S) -> tick(Driver, S) end,
+ mf_tick = fun(S) -> ?MODULE:tick(Driver, S) end,
mf_getstat = fun ?MODULE:getstat/1,
- request_type = Type
+ request_type = Type,
+ mf_setopts = fun ?MODULE:setopts/2,
+ mf_getopts = fun ?MODULE:getopts/2
},
dist_util:handshake_we_started(HSData);
_ ->
@@ -382,14 +390,14 @@ splitnode(Driver, Node, LongOrShortNames) ->
error_msg("** System running to use "
"fully qualified "
"hostnames **~n"
- "** Hostname ~s is illegal **~n",
+ "** Hostname ~ts is illegal **~n",
[Host]),
?shutdown(Node)
end;
L when length(L) > 1, LongOrShortNames =:= shortnames ->
error_msg("** System NOT running to use fully qualified "
"hostnames **~n"
- "** Hostname ~s is illegal **~n",
+ "** Hostname ~ts is illegal **~n",
[Host]),
?shutdown(Node);
_ ->
@@ -492,3 +500,12 @@ split_stat([], R, W, P) ->
{ok, R, W, P}.
+setopts(S, Opts) ->
+ case [Opt || {K,_}=Opt <- Opts,
+ K =:= active orelse K =:= deliver orelse K =:= packet] of
+ [] -> inet:setopts(S,Opts);
+ Opts1 -> {error, {badopts,Opts1}}
+ end.
+
+getopts(S, Opts) ->
+ inet:getopts(S, Opts).
diff --git a/lib/kernel/src/inet_udp.erl b/lib/kernel/src/inet_udp.erl
index 8a8aa8ecca..1e624b9e90 100644
--- a/lib/kernel/src/inet_udp.erl
+++ b/lib/kernel/src/inet_udp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -113,7 +113,7 @@ fdopen(Fd, Opts) ->
%% Here's how:
%% Reverse the list.
%% For each head option go through the tail and remove
-%% all occurences of the same option from the tail.
+%% all occurrences of the same option from the tail.
%% Store that head option and iterate using the new tail.
%% Return the list of stored head options.
optuniquify(List) ->
@@ -122,8 +122,8 @@ optuniquify(List) ->
optuniquify([], Result) ->
Result;
optuniquify([Opt | Tail], Result) ->
- %% Remove all occurences of Opt in Tail,
- %% prepend Opt to Result,
+ %% Remove all occurrences of Opt in Tail,
+ %% prepend Opt to Result,
%% then iterate back here.
optuniquify(Opt, Tail, [], Result).
diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src
index 56d1699656..e150938487 100644
--- a/lib/kernel/src/kernel.app.src
+++ b/lib/kernel/src/kernel.app.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@
erl_boot_server,
erl_distribution,
erl_reply,
+ erl_signal_handler,
error_handler,
error_logger,
file,
@@ -43,6 +44,7 @@
global_group,
global_search,
group,
+ group_history,
heart,
hipe_unified_loader,
inet6_tcp,
@@ -118,6 +120,6 @@
{applications, []},
{env, [{error_logger, tty}]},
{mod, {kernel, []}},
- {runtime_dependencies, ["erts-8.0", "stdlib-3.0", "sasl-3.0"]}
+ {runtime_dependencies, ["erts-9.0", "stdlib-3.0", "sasl-3.0"]}
]
}.
diff --git a/lib/kernel/src/kernel.appup.src b/lib/kernel/src/kernel.appup.src
index d16e200cb3..77085b2064 100644
--- a/lib/kernel/src/kernel.appup.src
+++ b/lib/kernel/src/kernel.appup.src
@@ -1,7 +1,7 @@
%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,9 +18,7 @@
%% %CopyrightEnd%
{"%VSN%",
%% Up from - max one major revision back
- [{<<"5\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-18.*
+ [{<<"5\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-19.*
%% Down to - max one major revision back
- [{<<"5\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-18.*
+ [{<<"5\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-19.*
}.
diff --git a/lib/kernel/src/kernel.erl b/lib/kernel/src/kernel.erl
index 3d0ef81318..cba57088ec 100644
--- a/lib/kernel/src/kernel.erl
+++ b/lib/kernel/src/kernel.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,6 +32,14 @@
start(_, []) ->
case supervisor:start_link({local, kernel_sup}, kernel, []) of
{ok, Pid} ->
+ %% add signal handler
+ case whereis(erl_signal_server) of
+ %% in case of minimal mode
+ undefined -> ok;
+ _ ->
+ ok = gen_event:add_handler(erl_signal_server, erl_signal_handler, [])
+ end,
+ %% add error handler
Type = get_error_logger_type(),
case error_logger:swap_handler(Type) of
ok -> {ok, Pid, []};
@@ -92,60 +100,112 @@ get_error_logger_type() ->
%%%-----------------------------------------------------------------
init([]) ->
- SupFlags = {one_for_all, 0, 1},
-
- Config = {kernel_config,
- {kernel_config, start_link, []},
- permanent, 2000, worker, [kernel_config]},
- Code = {code_server,
- {code, start_link, []},
- permanent, 2000, worker, [code]},
- File = {file_server_2,
- {file_server, start_link, []},
- permanent, 2000, worker,
- [file, file_server, file_io_server, prim_file]},
- StdError = {standard_error,
- {standard_error, start_link, []},
- temporary, 2000, supervisor, [user_sup]},
- User = {user,
- {user_sup, start, []},
- temporary, 2000, supervisor, [user_sup]},
-
+ SupFlags = #{strategy => one_for_all,
+ intensity => 0,
+ period => 1},
+
+ Config = #{id => kernel_config,
+ start => {kernel_config, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [kernel_config]},
+
+ Code = #{id => code_server,
+ start => {code, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [code]},
+
+ File = #{id => file_server_2,
+ start => {file_server, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [file, file_server, file_io_server, prim_file]},
+
+ StdError = #{id => standard_error,
+ start => {standard_error, start_link, []},
+ restart => temporary,
+ shutdown => 2000,
+ type => supervisor,
+ modules => [user_sup]},
+
+ User = #{id => user,
+ start => {user_sup, start, []},
+ restart => temporary,
+ shutdown => 2000,
+ type => supervisor,
+ modules => [user_sup]},
+
+ SafeSup = #{id => kernel_safe_sup,
+ start =>{supervisor, start_link, [{local, kernel_safe_sup}, ?MODULE, safe]},
+ restart => permanent,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [?MODULE]},
+
case init:get_argument(mode) of
- {ok, [["minimal"]]} ->
- SafeSupervisor = {kernel_safe_sup,
- {supervisor, start_link,
- [{local, kernel_safe_sup}, ?MODULE, safe]},
- permanent, infinity, supervisor, [?MODULE]},
- {ok, {SupFlags,
- [Code, File, StdError, User,
- Config, SafeSupervisor]}};
- _ ->
- Rpc = {rex, {rpc, start_link, []},
- permanent, 2000, worker, [rpc]},
- Global = {global_name_server, {global, start_link, []},
- permanent, 2000, worker, [global]},
- Glo_grp = {global_group, {global_group,start_link,[]},
- permanent, 2000, worker, [global_group]},
- InetDb = {inet_db, {inet_db, start_link, []},
- permanent, 2000, worker, [inet_db]},
- NetSup = {net_sup, {erl_distribution, start_link, []},
- permanent, infinity, supervisor,[erl_distribution]},
- DistAC = start_dist_ac(),
-
- Timer = start_timer(),
-
- SafeSupervisor = {kernel_safe_sup,
- {supervisor, start_link,
- [{local, kernel_safe_sup}, ?MODULE, safe]},
- permanent, infinity, supervisor, [?MODULE]},
- {ok, {SupFlags,
- [Code, Rpc, Global, InetDb | DistAC] ++
- [NetSup, Glo_grp, File,
- StdError, User, Config, SafeSupervisor] ++ Timer}}
+ {ok, [["minimal"]]} ->
+ {ok, {SupFlags, [Code, File, StdError, User, Config, SafeSup]}};
+ _ ->
+ Rpc = #{id => rex,
+ start => {rpc, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [rpc]},
+
+ Global = #{id => global_name_server,
+ start => {global, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [global]},
+
+ GlGroup = #{id => global_group,
+ start => {global_group,start_link,[]},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [global_group]},
+
+ InetDb = #{id => inet_db,
+ start => {inet_db, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [inet_db]},
+
+ NetSup = #{id => net_sup,
+ start => {erl_distribution, start_link, []},
+ restart => permanent,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [erl_distribution]},
+
+ SigSrv = #{id => erl_signal_server,
+ start => {gen_event, start_link, [{local, erl_signal_server}]},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => dynamic},
+
+ DistAC = start_dist_ac(),
+
+ Timer = start_timer(),
+
+ {ok, {SupFlags,
+ [Code, Rpc, Global, InetDb | DistAC] ++
+ [NetSup, GlGroup, File, SigSrv,
+ StdError, User, Config, SafeSup] ++ Timer}}
end;
init(safe) ->
- SupFlags = {one_for_one, 4, 3600},
+ SupFlags = #{strategy => one_for_one,
+ intensity => 4,
+ period => 3600},
+
Boot = start_boot_server(),
DiskLog = start_disk_log(),
Pg2 = start_pg2(),
@@ -159,60 +219,85 @@ init(safe) ->
{ok, {SupFlags, Boot ++ DiskLog ++ Pg2}}.
start_dist_ac() ->
- Spec = [{dist_ac,{dist_ac,start_link,[]},permanent,2000,worker,[dist_ac]}],
+ Spec = [#{id => dist_ac,
+ start => {dist_ac,start_link,[]},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [dist_ac]}],
case application:get_env(kernel, start_dist_ac) of
- {ok, true} -> Spec;
- {ok, false} -> [];
- undefined ->
- case application:get_env(kernel, distributed) of
- {ok, _} -> Spec;
- _ -> []
- end
+ {ok, true} -> Spec;
+ {ok, false} -> [];
+ undefined ->
+ case application:get_env(kernel, distributed) of
+ {ok, _} -> Spec;
+ _ -> []
+ end
end.
start_boot_server() ->
case application:get_env(kernel, start_boot_server) of
- {ok, true} ->
- Args = get_boot_args(),
- [{boot_server, {erl_boot_server, start_link, [Args]}, permanent,
- 1000, worker, [erl_boot_server]}];
- _ ->
- []
+ {ok, true} ->
+ Args = get_boot_args(),
+ [#{id => boot_server,
+ start => {erl_boot_server, start_link, [Args]},
+ restart => permanent,
+ shutdown => 1000,
+ type => worker,
+ modules => [erl_boot_server]}];
+ _ ->
+ []
end.
get_boot_args() ->
case application:get_env(kernel, boot_server_slaves) of
- {ok, Slaves} -> Slaves;
- _ -> []
+ {ok, Slaves} -> Slaves;
+ _ -> []
end.
start_disk_log() ->
case application:get_env(kernel, start_disk_log) of
- {ok, true} ->
- [{disk_log_server,
- {disk_log_server, start_link, []},
- permanent, 2000, worker, [disk_log_server]},
- {disk_log_sup, {disk_log_sup, start_link, []}, permanent,
- 1000, supervisor, [disk_log_sup]}];
- _ ->
- []
+ {ok, true} ->
+ [#{id => disk_log_server,
+ start => {disk_log_server, start_link, []},
+ restart => permanent,
+ shutdown => 2000,
+ type => worker,
+ modules => [disk_log_server]},
+ #{id => disk_log_sup,
+ start => {disk_log_sup, start_link, []},
+ restart => permanent,
+ shutdown => 1000,
+ type => supervisor,
+ modules => [disk_log_sup]}];
+ _ ->
+ []
end.
start_pg2() ->
case application:get_env(kernel, start_pg2) of
- {ok, true} ->
- [{pg2, {pg2, start_link, []}, permanent, 1000, worker, [pg2]}];
- _ ->
- []
+ {ok, true} ->
+ [#{id => pg2,
+ start => {pg2, start_link, []},
+ restart => permanent,
+ shutdown => 1000,
+ type => worker,
+ modules => [pg2]}];
+ _ ->
+ []
end.
start_timer() ->
case application:get_env(kernel, start_timer) of
- {ok, true} ->
- [{timer_server, {timer, start_link, []}, permanent, 1000, worker,
- [timer]}];
- _ ->
- []
+ {ok, true} ->
+ [#{id => timer_server,
+ start => {timer, start_link, []},
+ restart => permanent,
+ shutdown => 1000,
+ type => worker,
+ modules => [timer]}];
+ _ ->
+ []
end.
%%-----------------------------------------------------------------
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index ac19f4935b..ddda396713 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -26,15 +26,13 @@
%%-define(dist_debug, true).
-%-define(DBG,erlang:display([?MODULE,?LINE])).
-
-ifdef(dist_debug).
-define(debug(Term), erlang:display(Term)).
-else.
-define(debug(Term), ok).
-endif.
--ifdef(DEBUG).
+-ifdef(dist_debug).
-define(connect_failure(Node,Term),
io:format("Net Kernel 2: Failed connection to node ~p, reason ~p~n",
[Node,Term])).
@@ -59,6 +57,8 @@
connect_node/1,
monitor_nodes/1,
monitor_nodes/2,
+ setopts/2,
+ getopts/2,
start/1,
stop/0]).
@@ -111,7 +111,7 @@
}).
-record(listen, {
- listen, %% listen pid
+ listen, %% listen socket
accept, %% accepting pid
address, %% #net_address
module %% proto module
@@ -384,7 +384,7 @@ init({Name, LongOrShortNames, TickT, CleanHalt}) ->
connections =
ets:new(sys_dist,[named_table,
protected,
- {keypos, 2}]),
+ {keypos, #connection.node}]),
listen = Listeners,
allowed = [],
verbose = 0
@@ -554,6 +554,38 @@ handle_call({new_ticktime,_T,_TP},
#state{tick = #tick_change{time = T}} = State) ->
async_reply({reply, {ongoing_change_to, T}, State}, From);
+handle_call({setopts, new, Opts}, From, State) ->
+ Ret = setopts_new(Opts, State),
+ async_reply({reply, Ret, State}, From);
+
+handle_call({setopts, Node, Opts}, From, State) ->
+ Return =
+ case ets:lookup(sys_dist, Node) of
+ [Conn] when Conn#connection.state =:= up ->
+ case call_owner(Conn#connection.owner, {setopts, Opts}) of
+ {ok, Ret} -> Ret;
+ _ -> {error, noconnection}
+ end;
+
+ _ ->
+ {error, noconnection}
+ end,
+ async_reply({reply, Return, State}, From);
+
+handle_call({getopts, Node, Opts}, From, State) ->
+ Return =
+ case ets:lookup(sys_dist, Node) of
+ [Conn] when Conn#connection.state =:= up ->
+ case call_owner(Conn#connection.owner, {getopts, Opts}) of
+ {ok, Ret} -> Ret;
+ _ -> {error, noconnection}
+ end;
+
+ _ ->
+ {error, noconnection}
+ end,
+ async_reply({reply, Return, State}, From);
+
handle_call(_Msg, _From, State) ->
{noreply, State}.
@@ -1230,11 +1262,22 @@ create_name(Name, LongOrShortNames, Try) ->
{Head,Host1} = create_hostpart(Name, LongOrShortNames),
case Host1 of
{ok,HostPart} ->
- {ok,list_to_atom(Head ++ HostPart)};
+ case valid_name_head(Head) of
+ true ->
+ {ok,list_to_atom(Head ++ HostPart)};
+ false ->
+ error_logger:info_msg("Invalid node name!\n"
+ "Please check your configuration\n"),
+ {error, badarg}
+ end;
{error,long} when Try =:= 1 ->
%% It could be we haven't read domain name from resolv file yet
inet_config:do_load_resolv(os:type(), longnames),
create_name(Name, LongOrShortNames, 0);
+ {error, hostname_not_allowed} ->
+ error_logger:info_msg("Invalid node name!\n"
+ "Please check your configuration\n"),
+ {error, badarg};
{error,Type} ->
error_logger:info_msg(
lists:concat(["Can\'t set ",
@@ -1247,12 +1290,13 @@ create_name(Name, LongOrShortNames, Try) ->
create_hostpart(Name, LongOrShortNames) ->
{Head,Host} = split_node(Name),
Host1 = case {Host,LongOrShortNames} of
- {[$@,_|_],longnames} ->
- {ok,Host};
+ {[$@,_|_] = Host,longnames} ->
+ validate_hostname(Host);
{[$@,_|_],shortnames} ->
case lists:member($.,Host) of
true -> {error,short};
- _ -> {ok,Host}
+ _ ->
+ validate_hostname(Host)
end;
{_,shortnames} ->
case inet_db:gethostname() of
@@ -1272,6 +1316,24 @@ create_hostpart(Name, LongOrShortNames) ->
end,
{Head,Host1}.
+validate_hostname([$@|HostPart] = Host) ->
+ {ok, MP} = re:compile("^[!-ÿ]*$", [unicode]),
+ case re:run(HostPart, MP) of
+ {match, _} ->
+ {ok, Host};
+ nomatch ->
+ {error, hostname_not_allowed}
+ end.
+
+valid_name_head(Head) ->
+ {ok, MP} = re:compile("^[0-9A-Za-z_\\-]*$", [unicode]),
+ case re:run(Head, MP) of
+ {match, _} ->
+ true;
+ nomatch ->
+ false
+ end.
+
split_node(Name) ->
lists:splitwith(fun(C) -> C =/= $@ end, atom_to_list(Name)).
@@ -1608,3 +1670,93 @@ async_gen_server_reply(From, Msg) ->
{'EXIT', _} ->
ok
end.
+
+call_owner(Owner, Msg) ->
+ Mref = monitor(process, Owner),
+ Owner ! {self(), Mref, Msg},
+ receive
+ {Mref, Reply} ->
+ erlang:demonitor(Mref, [flush]),
+ {ok, Reply};
+ {'DOWN', Mref, _, _, _} ->
+ error
+ end.
+
+
+-spec setopts(Node, Options) -> ok | {error, Reason} | ignored when
+ Node :: node() | new,
+ Options :: [inet:socket_setopt()],
+ Reason :: inet:posix() | noconnection.
+
+setopts(Node, Opts) when is_atom(Node), is_list(Opts) ->
+ request({setopts, Node, Opts}).
+
+setopts_new(Opts, State) ->
+ %% First try setopts on listening socket(s)
+ %% Bail out on failure.
+ %% If successful, we are pretty sure Opts are ok
+ %% and we continue with config params and pending connections.
+ case setopts_on_listen(Opts, State#state.listen) of
+ ok ->
+ setopts_new_1(Opts);
+ Fail -> Fail
+ end.
+
+setopts_on_listen(_, []) -> ok;
+setopts_on_listen(Opts, [#listen {listen = LSocket, module = Mod} | T]) ->
+ try Mod:setopts(LSocket, Opts) of
+ ok ->
+ setopts_on_listen(Opts, T);
+ Fail -> Fail
+ catch
+ error:undef -> {error, enotsup}
+ end.
+
+setopts_new_1(Opts) ->
+ ConnectOpts = case application:get_env(kernel, inet_dist_connect_options) of
+ {ok, CO} -> CO;
+ _ -> []
+ end,
+ application:set_env(kernel, inet_dist_connect_options,
+ merge_opts(Opts,ConnectOpts)),
+ ListenOpts = case application:get_env(kernel, inet_dist_listen_options) of
+ {ok, LO} -> LO;
+ _ -> []
+ end,
+ application:set_env(kernel, inet_dist_listen_options,
+ merge_opts(Opts, ListenOpts)),
+ case lists:keyfind(nodelay, 1, Opts) of
+ {nodelay, ND} when is_boolean(ND) ->
+ application:set_env(kernel, dist_nodelay, ND);
+ _ -> ignore
+ end,
+
+ %% Update any pending connections
+ PendingConns = ets:select(sys_dist, [{'_',
+ [{'=/=',{element,#connection.state,'$_'},up}],
+ ['$_']}]),
+ lists:foreach(fun(#connection{state = pending, owner = Owner}) ->
+ call_owner(Owner, {setopts, Opts});
+ (#connection{state = up_pending, pending_owner = Owner}) ->
+ call_owner(Owner, {setopts, Opts});
+ (_) -> ignore
+ end, PendingConns),
+ ok.
+
+merge_opts([], B) ->
+ B;
+merge_opts([H|T], B0) ->
+ {Key, _} = H,
+ B1 = lists:filter(fun({K,_}) -> K =/= Key end, B0),
+ merge_opts(T, [H | B1]).
+
+-spec getopts(Node, Options) ->
+ {'ok', OptionValues} | {'error', Reason} | ignored when
+ Node :: node(),
+ Options :: [inet:socket_getopt()],
+ OptionValues :: [inet:socket_setopt()],
+ Reason :: inet:posix() | noconnection.
+
+getopts(Node, Opts) when is_atom(Node), is_list(Opts) ->
+ request({getopts, Node, Opts}).
+
diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl
index f0ad26b1f2..0250783632 100644
--- a/lib/kernel/src/os.erl
+++ b/lib/kernel/src/os.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@
-export([getenv/0, getenv/1, getenv/2, getpid/0,
perf_counter/0, perf_counter/1,
- putenv/2, system_time/0, system_time/1,
+ putenv/2, set_signal/2, system_time/0, system_time/1,
timestamp/0, unsetenv/1]).
-spec getenv() -> [string()].
@@ -104,6 +104,15 @@ timestamp() ->
unsetenv(_) ->
erlang:nif_error(undef).
+-spec set_signal(Signal, Option) -> 'ok' when
+ Signal :: 'sighup' | 'sigquit' | 'sigabrt' | 'sigalrm' |
+ 'sigterm' | 'sigusr1' | 'sigusr2' | 'sigchld' |
+ 'sigstop' | 'sigtstp',
+ Option :: 'default' | 'handle' | 'ignore'.
+
+set_signal(_Signal, _Option) ->
+ erlang:nif_error(undef).
+
%%% End of BIFs
-spec type() -> {Osfamily, Osname} when
@@ -226,11 +235,13 @@ extensions() ->
Command :: atom() | io_lib:chars().
cmd(Cmd) ->
validate(Cmd),
- {SpawnCmd, SpawnOpts, SpawnInput} = mk_cmd(os:type(), Cmd),
+ {SpawnCmd, SpawnOpts, SpawnInput, Eot} = mk_cmd(os:type(), Cmd),
Port = open_port({spawn, SpawnCmd}, [binary, stderr_to_stdout,
- stream, in, eof, hide | SpawnOpts]),
+ stream, in, hide | SpawnOpts]),
+ MonRef = erlang:monitor(port, Port),
true = port_command(Port, SpawnInput),
- Bytes = get_data(Port, []),
+ Bytes = get_data(Port, MonRef, Eot, []),
+ demonitor(MonRef, [flush]),
String = unicode:characters_to_list(Bytes),
if %% Convert to unicode list if possible otherwise return bytes
is_list(String) -> String;
@@ -243,7 +254,7 @@ mk_cmd({win32,Wtype}, Cmd) ->
{false,_} -> lists:concat(["cmd /c", Cmd]);
{Cspec,_} -> lists:concat([Cspec," /c",Cmd])
end,
- {Command, [], []};
+ {Command, [], [], <<>>};
mk_cmd(OsType,Cmd) when is_atom(Cmd) ->
mk_cmd(OsType, atom_to_list(Cmd));
mk_cmd(_,Cmd) ->
@@ -252,7 +263,20 @@ mk_cmd(_,Cmd) ->
{"/bin/sh -s unix:cmd", [out],
%% We insert a new line after the command, in case the command
%% contains a comment character.
- ["(", unicode:characters_to_binary(Cmd), "\n); exit\n"]}.
+ %%
+ %% The </dev/null closes stdin, which means that programs
+ %% that use a closed stdin as an termination indicator works.
+ %% An example of such a program is 'more'.
+ %%
+ %% The "echo ^D" is used to indicate that the program has executed
+ %% and we should return any output we have gotten. We cannot use
+ %% termination of the child or closing of stdin/stdout as then
+ %% starting background jobs from os:cmd will block os:cmd.
+ %%
+ %% I tried changing this to be "better", but got bombarded with
+ %% backwards incompatibility bug reports, so leave this as it is.
+ ["(", unicode:characters_to_binary(Cmd), "\n) </dev/null; echo \"\^D\"\n"],
+ <<$\^D>>}.
validate(Atom) when is_atom(Atom) ->
ok;
@@ -267,21 +291,50 @@ validate1([List|Rest]) when is_list(List) ->
validate1([]) ->
ok.
-get_data(Port, Sofar) ->
+get_data(Port, MonRef, Eot, Sofar) ->
receive
{Port, {data, Bytes}} ->
- get_data(Port, [Sofar,Bytes]);
- {Port, eof} ->
- Port ! {self(), close},
- receive
- {Port, closed} ->
- true
- end,
- receive
- {'EXIT', Port, _} ->
- ok
- after 1 -> % force context switch
- ok
- end,
+ case eot(Bytes, Eot) of
+ more ->
+ get_data(Port, MonRef, Eot, [Sofar,Bytes]);
+ Last ->
+ catch port_close(Port),
+ flush_until_down(Port, MonRef),
+ iolist_to_binary([Sofar, Last])
+ end;
+ {'DOWN', MonRef, _, _, _} ->
+ flush_exit(Port),
iolist_to_binary(Sofar)
end.
+
+eot(_Bs, <<>>) ->
+ more;
+eot(Bs, Eot) ->
+ case binary:match(Bs, Eot) of
+ nomatch -> more;
+ {Pos, _} ->
+ binary:part(Bs,{0, Pos})
+ end.
+
+%% When port_close returns we know that all the
+%% messages sent have been sent and that the
+%% DOWN message is after them all.
+flush_until_down(Port, MonRef) ->
+ receive
+ {Port, {data, _Bytes}} ->
+ flush_until_down(Port, MonRef);
+ {'DOWN', MonRef, _, _, _} ->
+ flush_exit(Port)
+ end.
+
+%% The exit signal is always delivered before
+%% the down signal, so we can be sure that if there
+%% was an exit message sent, it will be in the
+%% mailbox now.
+flush_exit(Port) ->
+ receive
+ {'EXIT', Port, _} ->
+ ok
+ after 0 ->
+ ok
+ end.
diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl
index 21bff02214..0e0b7dffa3 100644
--- a/lib/kernel/src/rpc.erl
+++ b/lib/kernel/src/rpc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -67,17 +67,27 @@
%%------------------------------------------------------------------------
+
+%% The rex server may receive a huge amount of
+%% messages. Make sure that they are stored off heap to
+%% avoid exessive GCs.
+
+-define(SPAWN_OPTS, [{spawn_opt,[{message_queue_data,off_heap}]}]).
+
%% Remote execution and broadcasting facility
-spec start() -> {'ok', pid()} | 'ignore' | {'error', term()}.
start() ->
- gen_server:start({local,?NAME}, ?MODULE, [], []).
+ gen_server:start({local,?NAME}, ?MODULE, [], ?SPAWN_OPTS).
-spec start_link() -> {'ok', pid()} | 'ignore' | {'error', term()}.
start_link() ->
- gen_server:start_link({local,?NAME}, ?MODULE, [], []).
+ %% The rex server process may receive a huge amount of
+ %% messages. Make sure that they are stored off heap to
+ %% avoid exessive GCs.
+ gen_server:start_link({local,?NAME}, ?MODULE, [], ?SPAWN_OPTS).
-spec stop() -> term().
diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl
index 81407e9d96..866043cfb4 100644
--- a/lib/kernel/test/application_SUITE.erl
+++ b/lib/kernel/test/application_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1498,7 +1498,7 @@ otp_5363(Conf) when is_list(Conf) ->
%% Ticket: OTP-5606
%% Slogan: Problems with starting a distributed application
%%-----------------------------------------------------------------
-%% Test of several processes simultanously starting the same
+%% Test of several processes simultaneously starting the same
%% distributed application.
otp_5606(Conf) when is_list(Conf) ->
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index 8da67c89f8..6f8e949aac 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -36,7 +36,9 @@
code_archive/1, code_archive2/1, on_load/1, on_load_binary/1,
on_load_embedded/1, on_load_errors/1, on_load_update/1,
on_load_purge/1, on_load_self_call/1, on_load_pending/1,
+ on_load_deleted/1,
big_boot_embedded/1,
+ module_status/1,
native_early_modules/1, get_mode/1,
normalized_paths/1]).
@@ -66,6 +68,8 @@ all() ->
bad_erl_libs, code_archive, code_archive2, on_load,
on_load_binary, on_load_embedded, on_load_errors, on_load_update,
on_load_purge, on_load_self_call, on_load_pending,
+ on_load_deleted,
+ module_status,
big_boot_embedded, native_early_modules, get_mode, normalized_paths].
groups() ->
@@ -91,6 +95,11 @@ init_per_suite(Config) ->
end_per_suite(Config) ->
Config.
+-define(TESTMOD, test_dummy).
+-define(TESTMODSTR, "test_dummy").
+-define(TESTMODSRC, ?TESTMODSTR ".erl").
+-define(TESTMODOBJ, ?TESTMODSTR ".beam").
+
init_per_testcase(big_boot_embedded, Config) ->
case catch crypto:start() of
ok ->
@@ -98,16 +107,36 @@ init_per_testcase(big_boot_embedded, Config) ->
_Else ->
{skip, "Needs crypto!"}
end;
+init_per_testcase(on_load_embedded, Config0) ->
+ LibRoot = code:lib_dir(),
+ LinkName = filename:join(LibRoot, "on_load_app-1.0"),
+ Config = [{link_name,LinkName}|Config0],
+ init_per_testcase(Config);
init_per_testcase(_Func, Config) ->
+ init_per_testcase(Config).
+
+init_per_testcase(Config) ->
P = code:get_path(),
[{code_path, P}|Config].
+
+end_per_testcase(module_status, Config) ->
+ code:purge(?TESTMOD),
+ code:delete(?TESTMOD),
+ code:purge(?TESTMOD),
+ file:delete(?TESTMODOBJ),
+ file:delete(?TESTMODSRC),
+ end_per_testcase(Config);
end_per_testcase(TC, Config) when TC == mult_lib_roots;
TC == big_boot_embedded ->
{ok, HostName} = inet:gethostname(),
NodeName = list_to_atom(atom_to_list(TC)++"@"++HostName),
test_server:stop_node(NodeName),
end_per_testcase(Config);
+end_per_testcase(on_load_embedded, Config) ->
+ LinkName = proplists:get_value(link_name, Config),
+ _ = del_link(LinkName),
+ end_per_testcase(Config);
end_per_testcase(_Func, Config) ->
end_per_testcase(Config).
@@ -307,7 +336,7 @@ load_abs(Config) when is_list(Config) ->
{error, nofile} = code:load_abs(TestDir ++ "/duuuumy_mod"),
{error, badfile} = code:load_abs(TestDir ++ "/code_a_test"),
{'EXIT', _} = (catch code:load_abs({})),
- {'EXIT', _} = (catch code:load_abs("Non-latin-имя-файла")),
+ {error, nofile} = code:load_abs("Non-latin-имя-файла"),
{module, code_b_test} = code:load_abs(TestDir ++ "/code_b_test"),
code:stick_dir(TestDir),
{error, sticky_directory} = code:load_abs(TestDir ++ "/code_b_test"),
@@ -481,23 +510,35 @@ load_binary(Config) when is_list(Config) ->
code:delete(code_b_test),
ok.
+
upgrade(Config) ->
DataDir = proplists:get_value(data_dir, Config),
- %%T = [beam, hipe],
- T = [beam],
-
- [upgrade_do(DataDir, Client, U1, U2, O1, O2)
- || Client<-T, U1<-T, U2<-T, O1<-T, O2<-T],
-
+ case erlang:system_info(hipe_architecture) of
+ undefined ->
+ upgrade_do(DataDir, beam, [beam]);
+
+ _ ->
+ T = [beam, hipe],
+ [upgrade_do(DataDir, Client, T) || Client <- T],
+
+ case hipe:llvm_support_available() of
+ false -> ok;
+ true ->
+ T2 = [beam, hipe_llvm],
+ [upgrade_do(DataDir, Client, T2) || Client <- T2]
+ end
+ end,
ok.
-upgrade_do(DataDir, Client, U1, U2, O1, O2) ->
+upgrade_do(DataDir, Client, T) ->
compile_load(upgrade_client, DataDir, undefined, Client),
- upgrade_client:run(DataDir, U1, U2, O1, O2),
+ [upgrade_client:run(DataDir, U1, U2, O1, O2)
+ || U1<-T, U2<-T, O1<-T, O2<-T],
ok.
compile_load(Mod, Dir, Ver, CodeType) ->
+ %%erlang:display({"{{{{{{{{{{{{{{{{Loading",Mod,Ver,CodeType}),
Version = case Ver of
undefined ->
io:format("Compiling '~p' as ~p\n", [Mod, CodeType]),
@@ -509,14 +550,21 @@ compile_load(Mod, Dir, Ver, CodeType) ->
end,
Target = case CodeType of
beam -> [];
- hipe -> [native]
+ hipe -> [native];
+ hipe_llvm -> [native,{hipe,[to_llvm]}]
end,
CompOpts = [binary, report] ++ Target ++ Version,
Src = filename:join(Dir, atom_to_list(Mod) ++ ".erl"),
+ T1 = erlang:now(),
{ok,Mod,Code} = compile:file(Src, CompOpts),
+ T2 = erlang:now(),
ObjFile = filename:basename(Src,".erl") ++ ".beam",
{module,Mod} = code:load_binary(Mod, ObjFile, Code),
+ T3 = erlang:now(),
+ io:format("Compile time ~p ms, Load time ~p ms\n",
+ [timer:now_diff(T2,T1) div 1000, timer:now_diff(T3,T2) div 1000]),
+ %%erlang:display({"}}}}}}}}}}}}}}}Loaded",Mod,Ver,CodeType}),
ok.
dir_req(Config) when is_list(Config) ->
@@ -586,20 +634,28 @@ sticky_compiler(Files, PrivDir) ->
[R || R <- Rets, R =/= ok].
do_sticky_compile(Mod, Dir) ->
- %% Make sure that the module is loaded. A module being sticky
- %% only prevents it from begin reloaded, not from being loaded
- %% from the wrong place to begin with.
- Mod = Mod:module_info(module),
- File = filename:append(Dir, atom_to_list(Mod)),
- Src = io_lib:format("-module(~s).\n"
- "-export([test/1]).\n"
- "test(me) -> fail.\n", [Mod]),
- ok = file:write_file(File++".erl", Src),
- case c:c(File, [{outdir,Dir}]) of
- {ok,Module} ->
- Module:test(me);
- {error,sticky_directory} ->
- ok
+ case code:is_sticky(Mod) of
+ true ->
+ %% Make sure that the module is loaded. A module being sticky
+ %% only prevents it from begin reloaded, not from being loaded
+ %% from the wrong place to begin with.
+ Mod = Mod:module_info(module),
+ File = filename:append(Dir, atom_to_list(Mod)),
+ Src = io_lib:format("-module(~s).\n"
+ "-export([test/1]).\n"
+ "test(me) -> fail.\n", [Mod]),
+ ok = file:write_file(File++".erl", Src),
+ case c:c(File, [{outdir,Dir}]) of
+ {ok,Module} ->
+ Module:test(me);
+ {error,sticky_directory} ->
+ ok
+ end;
+ false ->
+ %% For some reason the module is not sticky
+ %% could be that the .erlang file has
+ %% unstuck it?
+ {Mod, is_not_sticky}
end.
%% Test that the -pa and -pz options work as expected.
@@ -808,8 +864,6 @@ check_funs({'$M_EXPR','$F_EXPR',_},
{code_server,start_link,1}]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',_},
[{erlang,spawn_link,1},{code_server,start_link,1}]) -> 0;
-check_funs({'$M_EXPR',module_info,1},
- [{hipe_unified_loader,patch_to_emu_step1,1} | _]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',2},
[{hipe_unified_loader,write_words,3} | _]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',2},
@@ -821,11 +875,7 @@ check_funs({'$M_EXPR','$F_EXPR',2},
{hipe_unified_loader,sort_and_write,5} | _]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',1},
[{lists,foreach,2},
- {hipe_unified_loader,patch_consts,3} | _]) -> 0;
-check_funs({'$M_EXPR','$F_EXPR',1},
- [{lists,foreach,2},
- {hipe_unified_loader,mark_referred_from,1},
- {hipe_unified_loader,get_refs_from,2}| _]) -> 0;
+ {hipe_unified_loader,patch_consts,4} | _]) -> 0;
check_funs({'$M_EXPR',warning_msg,2},
[{code_server,finish_on_load_report,2} | _]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',1},
@@ -1234,10 +1284,9 @@ on_load_embedded(Config) when is_list(Config) ->
on_load_embedded_1(Config) ->
DataDir = proplists:get_value(data_dir, Config),
+ LinkName = proplists:get_value(link_name, Config),
%% Link the on_load_app application into the lib directory.
- LibRoot = code:lib_dir(),
- LinkName = filename:join(LibRoot, "on_load_app-1.0"),
OnLoadApp = filename:join(DataDir, "on_load_app-1.0"),
del_link(LinkName),
io:format("LinkName :~p, OnLoadApp: ~p~n",[LinkName,OnLoadApp]),
@@ -1271,8 +1320,7 @@ on_load_embedded_1(Config) ->
ok = rpc:call(Node, on_load_embedded, status, []),
%% Clean up.
- stop_node(Node),
- ok = del_link(LinkName).
+ stop_node(Node).
del_link(LinkName) ->
case file:delete(LinkName) of
@@ -1323,9 +1371,8 @@ create_big_boot(Config) ->
%% corresponding beam file (if hipe is not enabled).
filter_app("hipe",_) -> false;
-%% Dialyzer and typer depends on hipe
+%% Dialyzer depends on hipe
filter_app("dialyzer",_) -> false;
-filter_app("typer",_) -> false;
%% Orber requires explicit configuration
filter_app("orber",_) -> false;
@@ -1602,6 +1649,98 @@ on_load_pending(_Config) ->
ok = Mod:t(),
ok.
+on_load_deleted(_Config) ->
+ Mod = ?FUNCTION_NAME,
+
+ R0 = fun() ->
+ Tree = ?Q(["-module('@Mod@').\n",
+ "-on_load(f/0).\n",
+ "f() -> ok.\n"]),
+ merl:print(Tree),
+ {ok,Mod,Code} = merl:compile(Tree),
+ {module,Mod} = code:load_binary(Mod, "", Code)
+ end,
+ delete_before_reload(Mod, R0),
+ delete_before_reload(Mod, R0),
+
+ R1 = fun() ->
+ Tree = ?Q(["-module('@Mod@').\n",
+ "-on_load(f/0).\n",
+ "f() -> fail.\n"]),
+ merl:print(Tree),
+ {ok,Mod,Code} = merl:compile(Tree),
+ {error,on_load_failure} = code:load_binary(Mod, "", Code)
+ end,
+ delete_before_reload(Mod, R1),
+ delete_before_reload(Mod, R1),
+
+ OtherMod = list_to_atom(lists:concat([Mod,"_42"])),
+ OtherTree = ?Q(["-module('@OtherMod@').\n"]),
+ merl:print(OtherTree),
+ {ok,OtherMod,OtherCode} = merl:compile(OtherTree),
+
+ R2 = fun() ->
+ RegName = 'on_load__registered_name',
+ Tree = ?Q(["-module('@Mod@').\n",
+ "-on_load(f/0).\n",
+ "f() ->\n",
+ " register('@RegName@', self()),\n",
+ " receive _ -> ok end.\n"]),
+ merl:print(Tree),
+ {ok,Mod,Code} = merl:compile(Tree),
+ spawn(fun() ->
+ {module,Mod} = code:load_binary(Mod, "", Code)
+ end),
+ receive after 1 -> ok end,
+ {module,OtherMod} = code:load_binary(OtherMod, "",
+ OtherCode),
+ RegName ! stop
+ end,
+ delete_before_reload(Mod, R2),
+
+ ok.
+
+delete_before_reload(Mod, Reload) ->
+ false = check_old_code(Mod),
+
+ Tree1 = ?Q(["-module('@Mod@').\n",
+ "-export([f/1]).\n",
+ "f(Parent) ->\n",
+ " register('@Mod@', self()),\n",
+ " Parent ! started,\n",
+ " receive _ -> ok end.\n"]),
+ merl:print(Tree1),
+ {ok,Mod,Code1} = merl:compile(Tree1),
+
+ Self = self(),
+ spawn(fun() ->
+ {module,Mod} = code:load_binary(Mod, "", Code1),
+ Mod:f(Self)
+ end),
+ receive started -> ok end,
+
+ true = code:delete(Mod),
+ true = check_old_code(Mod),
+
+ Reload(),
+
+ %% When loading the the module with the -on_load() function,
+ %% the reference to the old code would be lost. Make sure that
+ %% the old code is remembered and is still preventing the
+ %% purge.
+ false = code:soft_purge(Mod),
+
+ %% Get rid of the old code.
+ Mod ! stop,
+ receive after 1 -> ok end,
+ true = code:soft_purge(Mod),
+
+ %% Unload the version of the module with the -on_load() function.
+ true = code:delete(Mod),
+ true = code:soft_purge(Mod),
+
+ ok.
+
%% Test that the native code of early loaded modules is loaded.
native_early_modules(Config) when is_list(Config) ->
@@ -1650,6 +1789,185 @@ do_normalized_paths([M|Ms]) ->
do_normalized_paths([]) ->
ok.
+%% Test that module_status/1 behaves as expected
+module_status(_Config) ->
+ case test_server:is_cover() of
+ true ->
+ module_status();
+ false ->
+ %% Make sure that we terminate the cover server.
+ try
+ module_status()
+ after
+ cover:stop()
+ end
+ end.
+
+module_status() ->
+ %% basics
+ not_loaded = code:module_status(fubar), % nonexisting
+ {file, preloaded} = code:is_loaded(erlang),
+ loaded = code:module_status(erlang), % preloaded
+ loaded = code:module_status(?MODULE), % normal known loaded
+
+ non_existing = code:which(?TESTMOD), % verify dummy name not in path
+ code:purge(?TESTMOD), % ensure no previous version in memory
+ code:delete(?TESTMOD),
+ code:purge(?TESTMOD),
+
+ %% generated code is detected as such
+ {ok,?TESTMOD,Bin} = compile:forms(dummy_ast(), []),
+ {module,?TESTMOD} = code:load_binary(?TESTMOD,"",Bin), % no source file
+ ok = ?TESTMOD:f(),
+ "" = code:which(?TESTMOD), % verify empty string for source file
+ loaded = code:module_status(?TESTMOD),
+
+ %% deleting generated code
+ true = code:delete(?TESTMOD),
+ non_existing = code:which(?TESTMOD), % verify still not in path
+ not_loaded = code:module_status(?TESTMOD),
+
+ %% beam file exists but not loaded
+ make_source_file(<<"0">>),
+ compile_beam(0),
+ true = (non_existing =/= code:which(?TESTMOD)), % verify in path
+ not_loaded = code:module_status(?TESTMOD),
+
+ %% loading code from disk makes it loaded
+ load_code(),
+ loaded = code:module_status(?TESTMOD), % loaded
+
+ %% cover compiling a module
+ {ok,?TESTMOD} = cover:compile(?TESTMOD),
+ {file, cover_compiled} = code:is_loaded(?TESTMOD), % verify cover compiled
+ modified = code:module_status(?TESTMOD), % loaded cover code but file exists
+ remove_code(),
+ removed = code:module_status(?TESTMOD), % removed
+ compile_beam(0),
+ modified = code:module_status(?TESTMOD), % recreated
+ load_code(),
+ loaded = code:module_status(?TESTMOD), % loading removes cover status
+ code:purge(?TESTMOD),
+ true = code:delete(?TESTMOD),
+ not_loaded = code:module_status(?TESTMOD), % deleted
+
+ %% recompilation ignores timestamps, only md5 matters
+ load_code(),
+ compile_beam(1100),
+ loaded = code:module_status(?TESTMOD),
+
+ %% modifying module detects different md5
+ make_source_file(<<"1">>),
+ compile_beam(0),
+ modified = code:module_status(?TESTMOD),
+
+ %% loading the modified code from disk makes it loaded
+ load_code(),
+ loaded = code:module_status(?TESTMOD),
+
+ %% removing and recreating a module with same md5
+ remove_code(),
+ removed = code:module_status(?TESTMOD),
+ compile_beam(0),
+ loaded = code:module_status(?TESTMOD),
+
+ case erlang:system_info(hipe_architecture) of
+ undefined ->
+ %% no native support
+ ok;
+ _ ->
+ %% native chunk is ignored if beam code is already loaded
+ load_code(),
+ loaded = code:module_status(?TESTMOD),
+ false = has_native(?TESTMOD),
+ compile_native(0),
+ BeamMD5 = erlang:get_module_info(?TESTMOD, md5),
+ {ok,{?TESTMOD,BeamMD5}} = beam_lib:md5(?TESTMODOBJ), % beam md5 unchanged
+ loaded = code:module_status(?TESTMOD),
+
+ %% native code reported as loaded, though different md5 from beam
+ load_code(),
+ true = has_native(?TESTMOD),
+ NativeMD5 = erlang:get_module_info(?TESTMOD, md5),
+ true = (BeamMD5 =/= NativeMD5),
+ loaded = code:module_status(?TESTMOD),
+
+ %% recompilation ignores timestamps, only md5 matters
+ compile_native(1100), % later timestamp
+ loaded = code:module_status(?TESTMOD),
+
+ %% modifying native module detects different md5
+ make_source_file(<<"2">>),
+ compile_native(0),
+ modified = code:module_status(?TESTMOD),
+
+ %% loading the modified native code from disk makes it loaded
+ load_code(),
+ true = has_native(?TESTMOD),
+ NativeMD5_2 = erlang:get_module_info(?TESTMOD, md5),
+ true = (NativeMD5 =/= NativeMD5_2), % verify native md5 changed
+ {ok,{?TESTMOD,BeamMD5_2}} = beam_lib:md5(?TESTMODOBJ),
+ true = (BeamMD5_2 =/= NativeMD5_2), % verify md5 differs from beam
+ loaded = code:module_status(?TESTMOD),
+
+ %% removing and recreating a native module with same md5
+ remove_code(),
+ removed = code:module_status(?TESTMOD),
+ compile_native(0),
+ loaded = code:module_status(?TESTMOD),
+
+ %% purging/deleting native module
+ code:purge(?TESTMOD),
+ true = code:delete(?TESTMOD),
+ not_loaded = code:module_status(?TESTMOD)
+ end,
+ ok.
+
+compile_beam(Sleep) ->
+ compile(Sleep, []).
+
+compile_native(Sleep) ->
+ compile(Sleep, [native]).
+
+compile(Sleep, Opts) ->
+ timer:sleep(Sleep), % increment compilation timestamp
+ {ok,?TESTMOD} = compile:file(?TESTMODSRC, Opts).
+
+load_code() ->
+ code:purge(?TESTMOD),
+ {module,?TESTMOD} = code:load_file(?TESTMOD).
+
+remove_code() ->
+ ok = file:delete(?TESTMODOBJ).
+
+has_native(Module) ->
+ case erlang:get_module_info(Module, native_addresses) of
+ [] -> false;
+ [_|_] -> true
+ end.
+
+make_source_file(Body) ->
+ ok = file:write_file(?TESTMODSRC, dummy_source(Body)).
+
+dummy_source(Body) ->
+ [<<"-module(" ?TESTMODSTR ").\n"
+ "-export([f/0]).\n"
+ "f() -> ">>, Body, <<".\n">>].
+
+dummy_ast() ->
+ dummy_ast(?TESTMODSTR).
+
+dummy_ast(Mod) when is_atom(Mod) ->
+ dummy_ast(atom_to_list(Mod));
+dummy_ast(ModStr) ->
+ [scan_form("-module(" ++ ModStr ++ ")."),
+ scan_form("-export([f/0])."),
+ scan_form("f() -> ok.")].
+
+scan_form(String) ->
+ {ok,Ts,_} = erl_scan:string(String),
+ {ok,F} = erl_parse:parse_form(Ts),
+ F.
%%-----------------------------------------------------------------
%% error_logger handler.
diff --git a/lib/kernel/test/code_SUITE_data/upgrade_client.erl b/lib/kernel/test/code_SUITE_data/upgrade_client.erl
index bb655e01d3..faa18e1410 100644
--- a/lib/kernel/test/code_SUITE_data/upgrade_client.erl
+++ b/lib/kernel/test/code_SUITE_data/upgrade_client.erl
@@ -9,6 +9,8 @@ run(Dir, Upgradee1, Upgradee2, Other1, Other2) ->
%% Load version 1 of upgradee
code_SUITE:compile_load(upgradee, Dir, 1, Upgradee1),
+ Tracer = start_tracing(),
+
?line 1 = upgradee:exp1(),
?line 1 = upgradee:exp1exp2(),
?line 1 = upgradee:exp1loc2(),
@@ -56,6 +58,15 @@ run(Dir, Upgradee1, Upgradee2, Other1, Other2) ->
?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1),
?line {'EXIT',{undef,_}} = proxy_call(P, other, loc2),
+ Env1 = "Env1",
+ put(loc1_fun, upgradee:get_local_fun(Env1)),
+ ?line {1,Env1} = (get(loc1_fun))(),
+
+ put(exp1exp2_fun, upgradee:get_exp1exp2_fun()),
+ ?line 1 = (get(exp1exp2_fun))(),
+
+ ok = check_tracing(Tracer, 13),
+
%%
%% Load version 1 of other
%%
@@ -78,6 +89,8 @@ run(Dir, Upgradee1, Upgradee2, Other1, Other2) ->
?line {'EXIT',{undef,_}} = proxy_call(P, other, exp2),
?line {'EXIT',{undef,_}} = proxy_call(P, other, loc2),
+ ok = check_tracing(Tracer, 5),
+
%%
%% Load version 2 of upgradee
%%
@@ -130,6 +143,15 @@ run(Dir, Upgradee1, Upgradee2, Other1, Other2) ->
?line {'EXIT',{undef,_}} = proxy_call(P, other, exp2),
?line {'EXIT',{undef,_}} = proxy_call(P, other, loc2),
+ ?line {1,Env1} = (get(loc1_fun))(),
+ Env2 = "Env2",
+ put(loc2_fun, upgradee:get_local_fun(Env2)),
+ ?line {2,Env2} = (get(loc2_fun))(),
+
+ ?line 2 = (get(exp1exp2_fun))(),
+
+ ok = check_tracing(Tracer, 10),
+
%%
%% Load version 2 of other
%%
@@ -182,17 +204,26 @@ run(Dir, Upgradee1, Upgradee2, Other1, Other2) ->
?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1loc2),
?line {'EXIT',{undef,_}} = proxy_call(P, other, loc2),
+ ?line {1,Env1} = (get(loc1_fun))(),
+ ?line {2,Env2} = (get(loc2_fun))(),
+ ?line 2 = (get(exp1exp2_fun))(),
+
+ ok = check_tracing(Tracer, 10),
%%
%% Upgrade proxy to version 2
%%
P ! upgrade_order,
-
%%
- io:format("Delete version 2 of 'upgradee'\n",[]),
+ io:format("Purge version 1 of 'upgradee'\n",[]),
%%
+ put(loc1_fun,undefined),
code:purge(upgradee),
+
+ %%
+ io:format("Delete version 2 of 'upgradee'\n",[]),
+ %%
code:delete(upgradee),
?line {'EXIT',{undef,_}} = (catch upgradee:exp2()),
@@ -239,17 +270,24 @@ run(Dir, Upgradee1, Upgradee2, Other1, Other2) ->
?line {'EXIT',{undef,_}} = proxy_call(P, other, exp1loc2),
?line {'EXIT',{undef,_}} = proxy_call(P, other, loc1loc2),
?line {'EXIT',{undef,_}} = proxy_call(P, other, loc2),
+
+ ?line {'EXIT',{undef,_}} = (catch (get(exp1exp2_fun))()),
+ ok = check_tracing(Tracer, 14),
+
unlink(P),
exit(P, die_please),
io:format("Purge 'upgradee'\n",[]),
+ put(loc2_fun,undefined),
code:purge(upgradee),
io:format("Delete and purge 'other'\n",[]),
code:purge(other),
code:delete(other),
code:purge(other),
+
+ stop_tracing(Tracer),
ok.
proxy_call(Pid, CallType, Func) ->
@@ -257,3 +295,54 @@ proxy_call(Pid, CallType, Func) ->
receive
{Pid, call_result, Func, Ret} -> Ret
end.
+
+
+start_tracing() ->
+ Self = self(),
+ {Tracer,_} = spawn_opt(fun() -> tracer_loop(Self) end, [link,monitor]),
+ ?line 1 = erlang:trace_pattern({error_handler,undefined_function,3},
+ true, [global]),
+ ?line 1 = erlang:trace(Self, true, [call,{tracer,Tracer}]),
+ Tracer.
+
+
+tracer_loop(Receiver) ->
+ receive
+ die_please ->
+ ok;
+ {do_trace_delivered, Tracee} ->
+ _ = erlang:trace_delivered(Tracee),
+ tracer_loop(Receiver);
+
+ Msg ->
+ Receiver ! Msg,
+ tracer_loop(Receiver)
+ end.
+
+check_tracing(Tracer, Expected) ->
+ Tracer ! {do_trace_delivered, self()},
+ case check_tracing_loop(0,[]) of
+ {Expected,_} ->
+ ok;
+ {Got, MsgList} ->
+ io:format("Expected ~p trace msg, got ~p:\n~p\n",
+ [Expected, Got, lists:reverse(MsgList)]),
+ "Trace msg mismatch"
+ end.
+
+check_tracing_loop(N, MsgList) ->
+ Self = self(),
+ receive
+ {trace, _Pid, call, {_M, _F, _Args}} = Msg ->
+ check_tracing_loop(N+1, [Msg | MsgList]);
+ {trace_delivered, Self, _} ->
+ {N, MsgList}
+ end.
+
+
+stop_tracing(Tracer) ->
+ erlang:trace(self(), false, [call]),
+ Tracer ! die_please,
+ receive
+ {'DOWN', _, process, Tracer, _} -> ok
+ end.
diff --git a/lib/kernel/test/code_SUITE_data/upgradee.erl b/lib/kernel/test/code_SUITE_data/upgradee.erl
index 62b1d95e30..8ca660c19c 100644
--- a/lib/kernel/test/code_SUITE_data/upgradee.erl
+++ b/lib/kernel/test/code_SUITE_data/upgradee.erl
@@ -8,6 +8,9 @@
-export([exp1/0]). % only exported in v1
-export([exp1loc2/0]). % exported in v1, local in v2
-export([exp1exp2/0]). % exported in v1 and v2
+-export([get_local_fun/1]).
+-export([get_exp1exp2_fun/0]).
+-export([exp1exp2_fun/0]).
exp1() -> ?VERSION.
loc1() -> ?VERSION.
@@ -20,6 +23,9 @@ loc1() -> ?VERSION.
-export([exp2/0]).
-export([loc1exp2/0]).
-export([exp1exp2/0]).
+-export([get_local_fun/1]).
+-export([get_exp1exp2_fun/0]).
+-export([exp1exp2_fun/0]).
exp2() -> ?VERSION.
loc2() -> ?VERSION.
@@ -31,6 +37,12 @@ exp1loc2() -> ?VERSION.
loc1exp2() -> ?VERSION.
loc1loc2() -> ?VERSION.
+get_local_fun(Env) -> fun() -> {?VERSION,Env} end.
+get_exp1exp2_fun() -> fun ?MODULE:exp1exp2_fun/0.
+
+exp1exp2_fun() ->
+ ?VERSION.
+
dispatch_loop() ->
receive
upgrade_order ->
diff --git a/lib/kernel/test/disk_log_SUITE.erl b/lib/kernel/test/disk_log_SUITE.erl
index f7ad9c0c04..fe2fc778f2 100644
--- a/lib/kernel/test/disk_log_SUITE.erl
+++ b/lib/kernel/test/disk_log_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -421,7 +421,7 @@ halt_ro_alog(Conf) when is_list(Conf) ->
halt_ro_alog_wait_notify(Log, T) ->
Term = term_to_binary(T),
receive
- {disk_log, _, Log,{read_only, Term}} ->
+ {disk_log, _, Log,{read_only, [Term]}} ->
ok;
Other ->
Other
@@ -449,7 +449,7 @@ halt_ro_balog(Conf) when is_list(Conf) ->
halt_ro_balog_wait_notify(Log, T) ->
Term = list_to_binary(T),
receive
- {disk_log, _, Log,{read_only, Term}} ->
+ {disk_log, _, Log,{read_only, [Term]}} ->
ok;
Other ->
Other
@@ -1385,15 +1385,15 @@ blocked_notif(Conf) when is_list(Conf) ->
"The requested operation" ++ _ = format_error(Error1),
ok = disk_log:blog(n, B),
ok = disk_log:alog(n, B),
- rec(1, {disk_log, node(), n, {format_external, term_to_binary(B)}}),
+ rec(1, {disk_log, node(), n, {format_external, [term_to_binary(B)]}}),
ok = disk_log:alog_terms(n, [B,B,B,B]),
rec(1, {disk_log, node(), n, {format_external,
lists:map(fun term_to_binary/1, [B,B,B,B])}}),
ok = disk_log:block(n, false),
ok = disk_log:alog(n, B),
- rec(1, {disk_log, node(), n, {blocked_log, term_to_binary(B)}}),
+ rec(1, {disk_log, node(), n, {blocked_log, [term_to_binary(B)]}}),
ok = disk_log:balog(n, B),
- rec(1, {disk_log, node(), n, {blocked_log, list_to_binary(B)}}),
+ rec(1, {disk_log, node(), n, {blocked_log, [list_to_binary(B)]}}),
ok = disk_log:balog_terms(n, [B,B,B,B]),
disk_log:close(n),
rec(1, {disk_log, node(), n, {blocked_log,
@@ -2493,6 +2493,7 @@ error_repair(Conf) when is_list(Conf) ->
del(File, No),
ok = file:del_dir(Dir),
+ error_logger:add_report_handler(?MODULE, self()),
%% repair a file
P1 = pps(),
{ok, n} = disk_log:open([{name, n}, {file, File}, {type, wrap},
@@ -2509,6 +2510,8 @@ error_repair(Conf) when is_list(Conf) ->
ok = disk_log:close(n),
true = (P1 == pps()),
del(File, No),
+ receive {info_msg, _, "disk_log: repairing" ++ _, _} -> ok
+ after 1000 -> ct:fail(failed) end,
%% yet another repair
P2 = pps(),
@@ -2525,6 +2528,8 @@ error_repair(Conf) when is_list(Conf) ->
ok = disk_log:close(n),
true = (P2 == pps()),
del(File, No),
+ receive {info_msg, _, "disk_log: repairing" ++ _, _} -> ok
+ after 1000 -> ct:fail(failed) end,
%% Repair, large term
Big = term_to_binary(lists:duplicate(66000,$a)),
@@ -2540,6 +2545,8 @@ error_repair(Conf) when is_list(Conf) ->
ok = disk_log:close(n),
Got = Big,
del(File, No),
+ receive {info_msg, _, "disk_log: repairing" ++ _, _} -> ok
+ after 1000 -> ct:fail(failed) end,
%% A term a little smaller than a chunk, then big terms.
BigSmall = mk_bytes(1024*64-8-12),
@@ -2560,6 +2567,8 @@ error_repair(Conf) when is_list(Conf) ->
{type, halt}, {format, internal}]),
ok = disk_log:close(n),
file:delete(File),
+ receive {info_msg, _, "disk_log: repairing" ++ _, _} -> ok
+ after 1000 -> ct:fail(failed) end,
%% The header is recovered.
{ok,n} =
@@ -2573,12 +2582,13 @@ error_repair(Conf) when is_list(Conf) ->
crash(File, 30),
{repaired,n,{recovered,3},{badbytes,16}} =
disk_log:open([{name, n}, {file, File}, {type, halt},
- {format, internal},{repair,true},
+ {format, internal},{repair,true}, {quiet, true},
{head_func, {?MODULE, head_fun, [{ok,"head"}]}}]),
["head",'of',terms] = get_all_terms(n),
ok = disk_log:close(n),
-
+ error_logger:delete_report_handler(?MODULE),
file:delete(File),
+ {messages, []} = process_info(self(), messages),
ok.
@@ -4666,7 +4676,7 @@ other_groups(Conf) when is_list(Conf) ->
ok.
--define(MAX, 16384). % MAX in disk_log_1.erl
+-define(MAX, ?MAX_FWRITE_CACHE). % as in disk_log_1.erl
%% Evil cases such as closed file descriptor port.
evil(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
@@ -4690,7 +4700,7 @@ evil(Conf) when is_list(Conf) ->
{size,?MAX+50},{format,external}]),
[Fd] = erlang:ports() -- Ports0,
{B,_} = x_mk_bytes(30),
- ok = disk_log:blog(Log, <<0:(?MAX+1)/unit:8>>),
+ ok = disk_log:blog(Log, <<0:(?MAX-1)/unit:8>>),
exit(Fd, kill),
{error, {file_error,_,einval}} = disk_log:blog_terms(Log, [B,B]),
ok= disk_log:close(Log),
@@ -5007,6 +5017,9 @@ init(Tester) ->
handle_event({error_report, _GL, {Pid, crash_report, Report}}, Tester) ->
Tester ! {crash_report, Pid, Report},
{ok, Tester};
+handle_event({info_msg, _GL, {Pid, F,A}}, Tester) ->
+ Tester ! {info_msg, Pid, F, A},
+ {ok, Tester};
handle_event(_Event, State) ->
{ok, State}.
diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl
index eb58e92224..bbfaa9d147 100644
--- a/lib/kernel/test/erl_distribution_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,10 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2]).
--export([tick/1, tick_change/1, illegal_nodenames/1, hidden_node/1,
+-export([tick/1, tick_change/1,
+ nodenames/1, hostnames/1,
+ illegal_nodenames/1, hidden_node/1,
+ setopts/1,
table_waste/1, net_setuptime/1,
inet_dist_options_options/1,
@@ -42,6 +45,8 @@
-export([get_socket_priorities/0,
tick_cli_test/1, tick_cli_test1/1,
tick_serv_test/2, tick_serv_test1/1,
+ run_remote_test/1,
+ setopts_do/2,
keep_conn/1, time_ping/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -50,7 +55,6 @@
-export([pinger/1]).
-
-define(DUMMY_NODE,dummy@test01).
%%-----------------------------------------------------------------
@@ -65,7 +69,8 @@ suite() ->
{timetrap,{minutes,4}}].
all() ->
- [tick, tick_change, illegal_nodenames, hidden_node,
+ [tick, tick_change, nodenames, hostnames, illegal_nodenames,
+ hidden_node, setopts,
table_waste, net_setuptime, inet_dist_options_options,
{group, monitor_nodes}].
@@ -175,7 +180,105 @@ table_waste(Config) when is_list(Config) ->
stop_node(N),
ok.
+%% Test that starting nodes with different legal name part works, and that illegal
+%% ones are filtered
+nodenames(Config) when is_list(Config) ->
+ legal("a1@b"),
+ legal("a-1@b"),
+ legal("a_1@b"),
+
+ illegal("cdé@a"),
+ illegal("te欢st@a").
+
+%% Test that starting nodes with different legal host part works, and that illegal
+%% ones are filtered
+hostnames(Config) when is_list(Config) ->
+ Host = gethostname(),
+ legal([$a,$@|atom_to_list(Host)]),
+ legal("1@b1"),
+ legal("b@b1-c"),
+ legal("c@b1_c"),
+ legal("d@b1#c"),
+ legal("f@::1"),
+ legal("g@1:bc3:4e3f:f20:0:1"),
+
+ case file:native_name_encoding() of
+ latin1 -> ignore;
+ _ -> legal("e@b1é")
+ end,
+ long_hostnames(net_kernel:longnames()),
+
+ illegal("h@testالع"),
+ illegal("i@языtest"),
+ illegal("j@te欢st").
+
+long_hostnames(true) ->
+ legal("[email protected]"),
+ legal("[email protected]"),
+ legal("[email protected]_c.d"),
+ legal("[email protected]"),
+ legal("[email protected]");
+long_hostnames(false) ->
+ illegal("[email protected]").
+
+legal(Name) ->
+ case test_node(Name) of
+ started ->
+ ok;
+ not_started ->
+ ct:fail("no ~p node started", [Name])
+ end.
+
+illegal(Name) ->
+ case test_node(Name, true) of
+ not_started ->
+ ok;
+ started ->
+ ct:fail("~p node started with illegal name", [Name])
+ end.
+
+test_node(Name) ->
+ test_node(Name, false).
+test_node(Name, Illigal) ->
+ ProgName = atom_to_list(lib:progname()),
+ Command = ProgName ++ " -noinput " ++ long_or_short() ++ Name ++
+ " -eval \"net_adm:ping('" ++ atom_to_list(node()) ++ "')\"" ++
+ case Illigal of
+ true ->
+ " -eval \"timer:sleep(10000),init:stop().\"";
+ false ->
+ ""
+ end,
+ net_kernel:monitor_nodes(true),
+ BinCommand = unicode:characters_to_binary(Command, utf8),
+ Prt = open_port({spawn, BinCommand}, [stream]),
+ Node = list_to_atom(Name),
+ receive
+ {nodeup, Node} ->
+ net_kernel:monitor_nodes(false),
+ slave:stop(Node),
+ started
+ after 5000 ->
+ net_kernel:monitor_nodes(false),
+ not_started
+ end.
+long_or_short() ->
+ case net_kernel:longnames() of
+ true -> " -name ";
+ false -> " -sname "
+ end.
+
+% get the localhost's name, depending on the using name policy
+gethostname() ->
+ Hostname = case net_kernel:longnames() of
+ true->
+ net_adm:localhost();
+ _->
+ {ok, Name}=inet:gethostname(),
+ Name
+ end,
+ list_to_atom(Hostname).
%% Test that pinging an illegal nodename does not kill the node.
illegal_nodenames(Config) when is_list(Config) ->
@@ -226,10 +329,10 @@ time_ping(Node) ->
T0 = erlang:monotonic_time(),
pang = net_adm:ping(Node),
T1 = erlang:monotonic_time(),
- erlang:convert_time_unit(T1 - T0, native, milli_seconds).
+ erlang:convert_time_unit(T1 - T0, native, millisecond).
%% Keep the connection with the client node up.
-%% This is neccessary as the client node runs with much shorter
+%% This is necessary as the client node runs with much shorter
%% tick time !!
keep_conn(Node) ->
sleep(1),
@@ -270,7 +373,7 @@ tick_cli_test1(Node) ->
receive
{whats_the_result, From} ->
Diff = erlang:convert_time_unit(T2-T1, native,
- milli_seconds),
+ millisecond),
case Diff of
T when T > 8000, T < 16000 ->
From ! {tick_test, T};
@@ -282,6 +385,165 @@ tick_cli_test1(Node) ->
end
end.
+setopts(Config) when is_list(Config) ->
+ register(setopts_regname, self()),
+ [N1,N2,N3,N4] = get_nodenames(4, setopts),
+
+ {_N1F,Port1} = start_node_unconnected(N1, ?MODULE, run_remote_test,
+ ["setopts_do", atom_to_list(node()), "1", "ping"]),
+ 0 = wait_for_port_exit(Port1),
+
+ {_N2F,Port2} = start_node_unconnected(N2, ?MODULE, run_remote_test,
+ ["setopts_do", atom_to_list(node()), "2", "ping"]),
+ 0 = wait_for_port_exit(Port2),
+
+ {ok, LSock} = gen_tcp:listen(0, [{packet,2}, {active,false}]),
+ {ok, LTcpPort} = inet:port(LSock),
+
+ {N3F,Port3} = start_node_unconnected(N3, ?MODULE, run_remote_test,
+ ["setopts_do", atom_to_list(node()),
+ "1", integer_to_list(LTcpPort)]),
+ wait_and_connect(LSock, N3F, Port3),
+ 0 = wait_for_port_exit(Port3),
+
+ {N4F,Port4} = start_node_unconnected(N4, ?MODULE, run_remote_test,
+ ["setopts_do", atom_to_list(node()),
+ "2", integer_to_list(LTcpPort)]),
+ wait_and_connect(LSock, N4F, Port4),
+ 0 = wait_for_port_exit(Port4),
+
+ ok.
+
+wait_and_connect(LSock, NodeName, NodePort) ->
+ {ok, Sock} = gen_tcp:accept(LSock),
+ {ok, "Connect please"} = gen_tcp:recv(Sock, 0),
+ flush_from_port(NodePort),
+ pong = net_adm:ping(NodeName),
+ gen_tcp:send(Sock, "Connect done"),
+ gen_tcp:close(Sock).
+
+
+flush_from_port(Port) ->
+ flush_from_port(Port, 10).
+
+flush_from_port(Port, Timeout) ->
+ receive
+ {Port,{data,String}} ->
+ io:format("~p: ~s\n", [Port, String]),
+ flush_from_port(Port, Timeout)
+ after Timeout ->
+ timeout
+ end.
+
+wait_for_port_exit(Port) ->
+ case (receive M -> M end) of
+ {Port,{exit_status,Status}} ->
+ Status;
+ {Port,{data,String}} ->
+ io:format("~p: ~s\n", [Port, String]),
+ wait_for_port_exit(Port)
+ end.
+
+run_remote_test([FuncStr, TestNodeStr | Args]) ->
+ Status = try
+ io:format("Node ~p started~n", [node()]),
+ TestNode = list_to_atom(TestNodeStr),
+ io:format("Node ~p spawning function ~p~n", [node(), FuncStr]),
+ {Pid,Ref} = spawn_monitor(?MODULE, list_to_atom(FuncStr), [TestNode, Args]),
+ io:format("Node ~p waiting for function ~p~n", [node(), FuncStr]),
+ receive
+ {'DOWN', Ref, process, Pid, normal} ->
+ 0;
+ Other ->
+ io:format("Node ~p got unexpected msg: ~p\n",[node(), Other]),
+ 1
+ end
+ catch
+ C:E ->
+ io:format("Node ~p got EXCEPTION ~p:~p\nat ~p\n",
+ [node(), C, E, erlang:get_stacktrace()]),
+ 2
+ end,
+ io:format("Node ~p doing halt(~p).\n",[node(), Status]),
+ erlang:halt(Status).
+
+% Do the actual test on the remote node
+setopts_do(TestNode, [OptNr, ConnectData]) ->
+ [] = nodes(),
+ {Opt, Val} = opt_from_nr(OptNr),
+ ok = net_kernel:setopts(new, [{Opt, Val}]),
+
+ [] = nodes(),
+ {error, noconnection} = net_kernel:getopts(TestNode, [Opt]),
+
+ case ConnectData of
+ "ping" -> % We connect
+ net_adm:ping(TestNode);
+ TcpPort -> % Other connect
+ {ok, Sock} = gen_tcp:connect("localhost", list_to_integer(TcpPort),
+ [{active,false},{packet,2}]),
+ ok = gen_tcp:send(Sock, "Connect please"),
+ {ok, "Connect done"} = gen_tcp:recv(Sock, 0),
+ gen_tcp:close(Sock)
+ end,
+ [TestNode] = nodes(),
+ {ok, [{Opt,Val}]} = net_kernel:getopts(TestNode, [Opt]),
+ {error, noconnection} = net_kernel:getopts('pixie@fairyland', [Opt]),
+
+ NewVal = change_val(Val),
+ ok = net_kernel:setopts(TestNode, [{Opt, NewVal}]),
+ {ok, [{Opt,NewVal}]} = net_kernel:getopts(TestNode, [Opt]),
+
+ ok = net_kernel:setopts(TestNode, [{Opt, Val}]),
+ {ok, [{Opt,Val}]} = net_kernel:getopts(TestNode, [Opt]),
+
+ ok.
+
+opt_from_nr("1") -> {nodelay, true};
+opt_from_nr("2") -> {nodelay, false}.
+
+change_val(true) -> false;
+change_val(false) -> true.
+
+start_node_unconnected(Name, Mod, Func, Args) ->
+ FullName = full_node_name(Name),
+ CmdLine = mk_node_cmdline(Name,Mod,Func,Args),
+ io:format("Starting node ~p: ~s~n", [FullName, CmdLine]),
+ case open_port({spawn, CmdLine}, [exit_status]) of
+ Port when is_port(Port) ->
+ {FullName, Port};
+ Error ->
+ exit({failed_to_start_node, FullName, Error})
+ end.
+
+full_node_name(PreName) ->
+ HostSuffix = lists:dropwhile(fun ($@) -> false; (_) -> true end,
+ atom_to_list(node())),
+ list_to_atom(atom_to_list(PreName) ++ HostSuffix).
+
+mk_node_cmdline(Name,Mod,Func,Args) ->
+ Static = "-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 ";
+ 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())
+ ++ " -run " ++ atom_to_list(Mod) ++ " " ++ atom_to_list(Func)
+ ++ " " ++ string:join(Args, " ").
+
%% OTP-4255.
tick_change(Config) when is_list(Config) ->
@@ -896,7 +1158,7 @@ monitor_nodes_otp_6481_test(Config, TestType) when is_list(Config) ->
RemotePid = spawn(Node,
fun () ->
receive after 1500 -> ok end,
- %% infinit loop of msgs
+ %% infinite loop of msgs
%% we want an endless stream of messages and the kill
%% the node mercilessly.
%% We then want to ensure that the nodedown message arrives
diff --git a/lib/kernel/test/erl_distribution_wb_SUITE.erl b/lib/kernel/test/erl_distribution_wb_SUITE.erl
index 6a23ad0d11..03aaee56b7 100644
--- a/lib/kernel/test/erl_distribution_wb_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_wb_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@
%% 1)
%%
-%% Connections are now always set up symetrically with respect to
+%% Connections are now always set up symmetrically with respect to
%% publication. If connecting node doesn't send DFLAG_PUBLISHED
%% the other node wont send DFLAG_PUBLISHED. If the connecting
%% node send DFLAG_PUBLISHED but the other node doesn't send
@@ -56,10 +56,14 @@
-define(DFLAG_HIDDEN_ATOM_CACHE,16#40).
-define(DFLAG_NEW_FUN_TAGS,16#80).
-define(DFLAG_EXTENDED_PIDS_PORTS,16#100).
+-define(DFLAG_UTF8_ATOMS, 16#10000).
%% From R9 and forward extended references is compulsory
%% From R10 and forward extended pids and ports are compulsory
--define(COMPULSORY_DFLAGS, (?DFLAG_EXTENDED_REFERENCES bor ?DFLAG_EXTENDED_PIDS_PORTS)).
+%% From R20 and forward UTF8 atoms are compulsory
+-define(COMPULSORY_DFLAGS, (?DFLAG_EXTENDED_REFERENCES bor
+ ?DFLAG_EXTENDED_PIDS_PORTS bor
+ ?DFLAG_UTF8_ATOMS)).
-define(shutdown(X), exit(X)).
diff --git a/lib/kernel/test/error_logger_SUITE.erl b/lib/kernel/test/error_logger_SUITE.erl
index b6e7551741..2d26a7246c 100644
--- a/lib/kernel/test/error_logger_SUITE.erl
+++ b/lib/kernel/test/error_logger_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
+ off_heap/1,
error_report/1, info_report/1, error/1, info/1,
emulator/1, tty/1, logfile/1, add/1, delete/1]).
@@ -45,7 +46,7 @@ suite() ->
{timetrap,{minutes,1}}].
all() ->
- [error_report, info_report, error, info, emulator, tty,
+ [off_heap, error_report, info_report, error, info, emulator, tty,
logfile, add, delete].
groups() ->
@@ -66,6 +67,16 @@ end_per_group(_GroupName, Config) ->
%%-----------------------------------------------------------------
+off_heap(_Config) ->
+ %% The error_logger process may receive a huge amount of
+ %% messages. Make sure that they are stored off heap to
+ %% avoid exessive GCs.
+ MQD = message_queue_data,
+ {MQD,off_heap} = process_info(whereis(error_logger), MQD),
+ ok.
+
+%%-----------------------------------------------------------------
+
error_report(Config) when is_list(Config) ->
error_logger:add_report_handler(?MODULE, self()),
Rep1 = [{tag1,"data1"},{tag2,data2},{tag3,3}],
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index 5f049c6f99..119e1f24bb 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
%% %CopyrightEnd%
%%
-%% This is a developement feature when developing a new file module,
+%% This is a development feature when developing a new file module,
%% ugly but practical.
-ifndef(FILE_MODULE).
-define(FILE_MODULE, file).
@@ -493,22 +493,13 @@ read_write_file(Config) when is_list(Config) ->
%% Try writing and reading back some term
SomeTerm = {"This term",{will,be},[written,$t,$o],1,file,[]},
- ok = ?FILE_MODULE:write_file(Name,term_to_binary(SomeTerm)),
- {ok,Bin1} = ?FILE_MODULE:read_file(Name),
- SomeTerm = binary_to_term(Bin1),
+ Bin1 = term_to_binary(SomeTerm),
+ ok = do_read_write_file(Name, Bin1),
%% Try a "null" term
NullTerm = [],
- ok = ?FILE_MODULE:write_file(Name,term_to_binary(NullTerm)),
- {ok,Bin2} = ?FILE_MODULE:read_file(Name),
- NullTerm = binary_to_term(Bin2),
-
- %% Try some "complicated" types
- BigNum = 123456789012345678901234567890,
- ComplTerm = {self(),make_ref(),BigNum,3.14159},
- ok = ?FILE_MODULE:write_file(Name,term_to_binary(ComplTerm)),
- {ok,Bin3} = ?FILE_MODULE:read_file(Name),
- ComplTerm = binary_to_term(Bin3),
+ Bin2 = term_to_binary(NullTerm),
+ ok = do_read_write_file(Name, Bin2),
%% Try reading a nonexistent file
Name2 = filename:join(RootDir,
@@ -519,25 +510,42 @@ read_write_file(Config) when is_list(Config) ->
{error, enoent} = ?FILE_MODULE:read_file(''),
%% Try writing to a bad filename
- {error, enoent} =
- ?FILE_MODULE:write_file("",term_to_binary(NullTerm)),
+ {error, enoent} = do_read_write_file("", Bin2),
%% Try writing something else than a binary
- {error, badarg} = ?FILE_MODULE:write_file(Name,{1,2,3}),
- {error, badarg} = ?FILE_MODULE:write_file(Name,self()),
+ {error, badarg} = do_read_write_file(Name, {1,2,3}),
+ {error, badarg} = do_read_write_file(Name, self()),
%% Some non-term binaries
- ok = ?FILE_MODULE:write_file(Name,[]),
- {ok,Bin4} = ?FILE_MODULE:read_file(Name),
- 0 = byte_size(Bin4),
+ ok = do_read_write_file(Name, []),
- ok = ?FILE_MODULE:write_file(Name,[Bin1,[],[[Bin2]]]),
- {ok,Bin5} = ?FILE_MODULE:read_file(Name),
- {Bin1,Bin2} = split_binary(Bin5,byte_size(Bin1)),
+ %% Write some iolists
+ ok = do_read_write_file(Name, [Bin1,[],[[Bin2]]]),
+ ok = do_read_write_file(Name, ["string",<<"binary">>]),
+ ok = do_read_write_file(Name, "pure string"),
[] = flush(),
ok.
+do_read_write_file(Name, Data) ->
+ case ?FILE_MODULE:write_file(Name, Data) of
+ ok ->
+ BinData = iolist_to_binary(Data),
+ {ok,BinData} = ?FILE_MODULE:read_file(Name),
+
+ ok = ?FILE_MODULE:write_file(Name, Data, []),
+ {ok,BinData} = ?FILE_MODULE:read_file(Name),
+
+ ok = ?FILE_MODULE:write_file(Name, Data, [raw]),
+ {ok,BinData} = ?FILE_MODULE:read_file(Name),
+
+ ok;
+ {error,_}=Res ->
+ Res = ?FILE_MODULE:write_file(Name, Data, []),
+ Res = ?FILE_MODULE:write_file(Name, Data, [raw]),
+ Res
+ end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -3730,7 +3738,7 @@ response_analysis(Module, Function, Arguments) ->
{Result, Comment}.
micro_ts() ->
- erlang:monotonic_time(micro_seconds).
+ erlang:monotonic_time(microsecond).
response_stat(init, Ts) ->
{0, 0, Ts, 0, 0};
diff --git a/lib/kernel/test/file_SUITE_data/realmen.html b/lib/kernel/test/file_SUITE_data/realmen.html
index c810a5d088..92e13f23b8 100644
--- a/lib/kernel/test/file_SUITE_data/realmen.html
+++ b/lib/kernel/test/file_SUITE_data/realmen.html
@@ -237,7 +237,7 @@ destroy most of the interesting uses for EQUIVALENCE, and make it
impossible to modify the operating system code with negative
subscripts. Worst of all, bounds checking is inefficient.
-<LI> Source code maintainance systems. A Real Programmer keeps his
+<LI> Source code maintenance systems. A Real Programmer keeps his
code locked up in a card file, because it implies that its owner
cannot leave his important programs unguarded [5].
@@ -396,7 +396,7 @@ double stuff Oreos for special occasions.
<LI> Underneath the Oreos is a flow-charting template, left there by
the previous occupant of the office. (Real Programmers write programs,
-not documentation. Leave that to the maintainence people.)
+not documentation. Leave that to the maintenance people.)
</UL> <P>
diff --git a/lib/kernel/test/file_name_SUITE.erl b/lib/kernel/test/file_name_SUITE.erl
index 10b6b105d0..899102c908 100644
--- a/lib/kernel/test/file_name_SUITE.erl
+++ b/lib/kernel/test/file_name_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -383,7 +383,7 @@ check_icky(Mod) ->
ok
end,
- _ = make_icky_dir(Mod, treat_icky(<<"åäö_dir">>)),
+ _ = make_icky_dir(Mod, treat_icky(<<"åäö_dir"/utf8>>)),
if
UniMode and (OS =/= win32) ->
{error,enoent} = Mod:set_cwd("åäö_dir");
diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl
index f836b2aa94..620ab235a0 100644
--- a/lib/kernel/test/gen_sctp_SUITE.erl
+++ b/lib/kernel/test/gen_sctp_SUITE.erl
@@ -117,7 +117,11 @@ xfer_min(Config) when is_list(Config) ->
Stream = 0,
Data = <<"The quick brown fox jumps over a lazy dog 0123456789">>,
Loopback = {127,0,0,1},
+ StatOpts =
+ [recv_avg,recv_cnt,recv_max,recv_oct,
+ send_avg,send_cnt,send_max,send_oct],
{ok,Sb} = gen_sctp:open([{type,seqpacket}]),
+ {ok,SbStat1} = inet:getstat(Sb, StatOpts),
{ok,Pb} = inet:port(Sb),
ok = gen_sctp:listen(Sb, true),
@@ -212,6 +216,8 @@ xfer_min(Config) when is_list(Config) ->
assoc_id=SbAssocId}} =
recv_event(log_ok(gen_sctp:recv(Sb, infinity))),
ok = gen_sctp:close(Sa),
+ {ok,SbStat2} = inet:getstat(Sb, StatOpts),
+ [] = filter_stat_eq(SbStat1, SbStat2),
ok = gen_sctp:close(Sb),
receive
@@ -220,6 +226,18 @@ xfer_min(Config) when is_list(Config) ->
end,
ok.
+filter_stat_eq([], []) ->
+ [];
+filter_stat_eq([{Tag,Val1}=Stat|SbStat1], [{Tag,Val2}|SbStat2]) ->
+ if
+ Val1 == Val2 ->
+ [Stat|filter_stat_eq(SbStat1, SbStat2)];
+ true ->
+ filter_stat_eq(SbStat1, SbStat2)
+ end.
+
+
+
%% Minimal data transfer in active mode.
xfer_active(Config) when is_list(Config) ->
Timeout = 2000,
@@ -383,26 +401,28 @@ def_sndrcvinfo(Config) when is_list(Config) ->
assoc_id=S2AssocId} = S2AssocChange =
log_ok(gen_sctp:connect(S2, Loopback, P1, [])),
?LOGVAR(S2AssocChange),
- case recv_event(log_ok(gen_sctp:recv(S1))) of
- {Loopback,P2,
- #sctp_assoc_change{
- state=comm_up,
- error=0,
- assoc_id=S1AssocId}} ->
- ?LOGVAR(S1AssocId);
- {Loopback,P2,
- #sctp_paddr_change{
- state=addr_confirmed,
- error=0,
- assoc_id=S1AssocId}} ->
- ?LOGVAR(S1AssocId),
+ S1AssocId =
+ case recv_event(log_ok(gen_sctp:recv(S1))) of
{Loopback,P2,
#sctp_assoc_change{
state=comm_up,
error=0,
- assoc_id=S1AssocId}} =
- recv_event(log_ok(gen_sctp:recv(S1)))
- end,
+ assoc_id=AssocId}} ->
+ AssocId;
+ {Loopback,P2,
+ #sctp_paddr_change{
+ state=addr_confirmed,
+ error=0,
+ assoc_id=AssocId}} ->
+ {Loopback,P2,
+ #sctp_assoc_change{
+ state=comm_up,
+ error=0,
+ assoc_id=AssocId}} =
+ recv_event(log_ok(gen_sctp:recv(S1))),
+ AssocId
+ end,
+ ?LOGVAR(S1AssocId),
#sctp_sndrcvinfo{
ppid=17, context=0, timetolive=0} = %, assoc_id=S1AssocId} =
@@ -1055,6 +1075,7 @@ peeloff(Config, SockOpts) when is_list(Config) ->
Addr = {127,0,0,1},
Stream = 0,
Timeout = 333,
+ StartTime = timestamp(),
S1 = socket_open([{ifaddr,Addr}|SockOpts], Timeout),
?LOGVAR(S1),
P1 = socket_call(S1, get_port),
@@ -1077,7 +1098,7 @@ peeloff(Config, SockOpts) when is_list(Config) ->
state=comm_up,
assoc_id=AssocId2}}} -> AssocId2
after Timeout ->
- socket_bailout([S1,S2])
+ socket_bailout([S1,S2], StartTime)
end,
?LOGVAR(S2Ai),
S1Ai =
@@ -1087,7 +1108,7 @@ peeloff(Config, SockOpts) when is_list(Config) ->
state=comm_up,
assoc_id=AssocId1}}} -> AssocId1
after Timeout ->
- socket_bailout([S1,S2])
+ socket_bailout([S1,S2], StartTime)
end,
?LOGVAR(S1Ai),
%%
@@ -1095,13 +1116,13 @@ peeloff(Config, SockOpts) when is_list(Config) ->
receive
{S1,{Addr,P2,S1Ai,Stream,<<"Number one">>}} -> ok
after Timeout ->
- socket_bailout([S1,S2])
+ socket_bailout([S1,S2], StartTime)
end,
socket_call(S2, {send,Socket1,S1Ai,Stream,<<"Number two">>}),
receive
{S2,{Addr,P1,S2Ai,Stream,<<"Number two">>}} -> ok
after Timeout ->
- socket_bailout([S1,S2])
+ socket_bailout([S1,S2], StartTime)
end,
%%
S3 = socket_peeloff(Socket1, S1Ai, SockOpts, Timeout),
@@ -1120,31 +1141,31 @@ peeloff(Config, SockOpts) when is_list(Config) ->
receive
{S2,{Addr,P3,S2Ai,Stream,<<"Number three">>}} -> ok
after Timeout ->
- socket_bailout([S1,S2,S3])
+ socket_bailout([S1,S2,S3], StartTime)
end,
socket_call(S3, {send,Socket2,S2Ai,Stream,<<"Number four">>}),
receive
{S3,{Addr,P2,S3Ai,Stream,<<"Number four">>}} -> ok
after Timeout ->
- socket_bailout([S1,S2,S3])
+ socket_bailout([S1,S2,S3], StartTime)
end,
%%
inet:i(sctp),
- socket_close_verbose(S1),
- socket_close_verbose(S2),
+ socket_close_verbose(S1, StartTime),
+ socket_close_verbose(S2, StartTime),
receive
{S3,{Addr,P2,#sctp_shutdown_event{assoc_id=S3Ai_X}}} ->
match_unless_solaris(S3Ai, S3Ai_X)
after Timeout ->
- socket_bailout([S3])
+ socket_bailout([S3], StartTime)
end,
receive
{S3,{Addr,P2,#sctp_assoc_change{state=shutdown_comp,
assoc_id=S3Ai}}} -> ok
after Timeout ->
- socket_bailout([S3])
+ socket_bailout([S3], StartTime)
end,
- socket_close_verbose(S3),
+ socket_close_verbose(S3, StartTime),
[] = flush(),
ok.
@@ -1156,6 +1177,7 @@ buffers(Config) when is_list(Config) ->
Addr = {127,0,0,1},
Stream = 1,
Timeout = 3333,
+ StartTime = timestamp(),
S1 = socket_open([{ip,Addr}], Timeout),
?LOGVAR(S1),
P1 = socket_call(S1, get_port),
@@ -1174,7 +1196,7 @@ buffers(Config) when is_list(Config) ->
state=comm_up,
assoc_id=AssocId2}}} -> AssocId2
after Timeout ->
- socket_bailout([S1,S2])
+ socket_bailout([S1,S2], StartTime)
end,
S1Ai =
receive
@@ -1183,7 +1205,7 @@ buffers(Config) when is_list(Config) ->
state=comm_up,
assoc_id=AssocId1}}} -> AssocId1
after Timeout ->
- socket_bailout([S1,S2])
+ socket_bailout([S1,S2], StartTime)
end,
%%
socket_call(S1, {setopts,[{recbuf,Limit}]}),
@@ -1197,22 +1219,22 @@ buffers(Config) when is_list(Config) ->
receive
{S1,{Addr,P2,S1Ai,Stream,Data}} -> ok
after Timeout ->
- socket_bailout([S1,S2])
+ socket_bailout([S1,S2], StartTime)
end,
%%
- socket_close_verbose(S1),
+ socket_close_verbose(S1, StartTime),
receive
{S2,{Addr,P1,#sctp_shutdown_event{assoc_id=S2Ai}}} -> ok
after Timeout ->
- socket_bailout([S2])
+ socket_bailout([S2], StartTime)
end,
receive
{S2,{Addr,P1,#sctp_assoc_change{state=shutdown_comp,
assoc_id=S2Ai}}} -> ok
after Timeout ->
- socket_bailout([S2])
+ socket_bailout([S2], StartTime)
end,
- socket_close_verbose(S2),
+ socket_close_verbose(S2, StartTime),
[] = flush(),
ok.
@@ -1521,8 +1543,8 @@ socket_peeloff(Socket, AssocId, SocketOpts, Timeout) ->
end,
s_start(Starter, Timeout).
-socket_close_verbose(S) ->
- History = socket_history(socket_close(S)),
+socket_close_verbose(S, StartTime) ->
+ History = socket_history(socket_close(S), StartTime),
io:format("socket_close ~p:~n ~p.~n", [S,History]),
History.
@@ -1535,19 +1557,19 @@ socket_call(S, Request) ->
%% socket_get(S, Key) ->
%% s_req(S, {get,Key}).
-socket_bailout([S|Ss]) ->
- History = socket_history(socket_close(S)),
+socket_bailout([S|Ss], StartTime) ->
+ History = socket_history(socket_close(S), StartTime),
io:format("bailout ~p:~n ~p.~n", [S,History]),
- socket_bailout(Ss);
-socket_bailout([]) ->
+ socket_bailout(Ss, StartTime);
+socket_bailout([], _) ->
io:format("flush: ~p.~n", [flush()]),
ct:fail(socket_bailout).
-socket_history({State,Flush}) ->
+socket_history({State,Flush}, StartTime) ->
{lists:keysort(
2,
lists:flatten(
- [[{Key,Val} || Val <- Vals]
+ [[{Key,{TS-StartTime,Val}} || {TS,Val} <- Vals]
|| {Key,Vals} <- gb_trees:to_list(State)])),
Flush}.
@@ -1610,14 +1632,12 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
{Parent,Ref,exit} ->
ok = gen_sctp:close(Socket),
Key = exit,
- Val = {now(),Socket},
- NewState = gb_push(Key, Val, State),
+ NewState = gb_push(Key, Socket, State),
Parent ! {self(),Ref,{NewState,flush()}};
{Parent,Ref,{Msg}} ->
Result = Handler(Msg),
Key = req,
- Val = {now(),{Msg,Result}},
- NewState = gb_push(Key, Val, State),
+ NewState = gb_push(Key, {Msg,Result}, State),
Parent ! {self(),Ref,Result},
s_loop(Socket, Timeout, Parent, Handler, NewState);
%% {Parent,Ref,{get,Key}} ->
@@ -1627,16 +1647,15 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
{[#sctp_sndrcvinfo{stream=Stream,assoc_id=AssocId}=SRI],Data}}
when not is_tuple(Data) ->
case gb_get({assoc_change,AssocId}, State) of
- [{_,{Addr,Port,
- #sctp_assoc_change{
- state=comm_up,
- inbound_streams=Is}}}|_]
+ [{Addr,Port,
+ #sctp_assoc_change{
+ state=comm_up,
+ inbound_streams=Is}}|_]
when 0 =< Stream, Stream < Is-> ok;
[] -> ok
end,
Key = {msg,AssocId,Stream},
- Val = {now(),{Addr,Port,SRI,Data}},
- NewState = gb_push(Key, Val, State),
+ NewState = gb_push(Key, {Addr,Port,SRI,Data}, State),
Parent ! {self(),{Addr,Port,AssocId,Stream,Data}},
again(Socket),
s_loop(Socket, Timeout, Parent, Handler, NewState);
@@ -1647,13 +1666,12 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
[] -> ok
end,
Key = {assoc_change,AssocId},
- Val = {now(),{Addr,Port,SAC}},
case {gb_get(Key, State),St} of
{[],_} -> ok;
- {[{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_],_}
+ {[{Addr,Port,#sctp_assoc_change{state=comm_up}}|_],_}
when St =:= comm_lost; St =:= shutdown_comp -> ok
end,
- NewState = gb_push(Key, Val, State),
+ NewState = gb_push(Key, {Addr,Port,SAC}, State),
Parent ! {self(),{Addr,Port,SAC}},
again(Socket),
s_loop(Socket, Timeout, Parent, Handler, NewState);
@@ -1667,14 +1685,13 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
[] -> ok
end,
case {gb_get({assoc_change,AssocId}, State),St} of
- {[{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_],_}
+ {[{Addr,Port,#sctp_assoc_change{state=comm_up}}|_],_}
when St =:= addr_available;
St =:= addr_confirmed -> ok;
{[],addr_confirmed} -> ok
end,
Key = {paddr_change,AssocId},
- Val = {now(),{Addr,Port,SPC}},
- NewState = gb_push(Key, Val, State),
+ NewState = gb_push(Key, {Addr,Port,SPC}, State),
again(Socket),
s_loop(Socket, Timeout, Parent, Handler, NewState);
{sctp,Socket,Addr,Port,
@@ -1684,12 +1701,11 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
[] -> ok
end,
case gb_get({assoc_change,AssocId}, State) of
- [{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_] -> ok;
+ [{Addr,Port,#sctp_assoc_change{state=comm_up}}|_] -> ok;
[] -> ok
end,
Key = {shutdown_event,AssocId},
- Val = {now(),{Addr,Port}},
- NewState = gb_push(Key, Val, State),
+ NewState = gb_push(Key, {Addr,Port}, State),
Parent ! {self(), {Addr,Port,SSE}},
again(Socket),
s_loop(Socket, Timeout, Parent, Handler, NewState);
@@ -1707,11 +1723,12 @@ again(Socket) ->
end.
gb_push(Key, Val, GBT) ->
+ TS = timestamp(),
case gb_trees:lookup(Key, GBT) of
none ->
- gb_trees:insert(Key, [Val], GBT);
+ gb_trees:insert(Key, [{TS,Val}], GBT);
{value,V} ->
- gb_trees:update(Key, [Val|V], GBT)
+ gb_trees:update(Key, [{TS,Val}|V], GBT)
end.
gb_get(Key, GBT) ->
@@ -1719,7 +1736,7 @@ gb_get(Key, GBT) ->
none ->
[];
{value,V} ->
- V
+ [Val || {_TS,Val} <- V]
end.
match_unless_solaris(A, B) ->
@@ -1727,3 +1744,6 @@ match_unless_solaris(A, B) ->
{unix,sunos} -> B;
_ -> A = B
end.
+
+timestamp() ->
+ erlang:monotonic_time().
diff --git a/lib/kernel/test/gen_tcp_api_SUITE.erl b/lib/kernel/test/gen_tcp_api_SUITE.erl
index 77ec89b4f4..12d22519ce 100644
--- a/lib/kernel/test/gen_tcp_api_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_api_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@
t_local_basic/1, t_local_unbound/1, t_local_fdopen/1,
t_local_fdopen_listen/1, t_local_fdopen_listen_unbound/1,
t_local_fdopen_connect/1, t_local_fdopen_connect_unbound/1,
- t_local_abstract/1]).
+ t_local_abstract/1, t_accept_inet6_tclass/1]).
-export([getsockfd/0,closesockfd/1]).
@@ -50,6 +50,7 @@ all() ->
[{group, t_accept}, {group, t_connect}, {group, t_recv},
t_shutdown_write, t_shutdown_both, t_shutdown_error,
t_shutdown_async, t_fdopen, t_fdconnect, t_implicit_inet6,
+ t_accept_inet6_tclass,
{group, t_local}].
groups() ->
@@ -301,9 +302,9 @@ t_implicit_inet6(Config) when is_list(Config) ->
end.
t_implicit_inet6(Host, Addr) ->
- case gen_tcp:listen(0, [inet6]) of
+ Loopback = {0,0,0,0,0,0,0,1},
+ case gen_tcp:listen(0, [inet6, {ip,Loopback}]) of
{ok,S1} ->
- Loopback = {0,0,0,0,0,0,0,1},
io:format("~s ~p~n", ["::1",Loopback]),
implicit_inet6(S1, Loopback),
ok = gen_tcp:close(S1),
@@ -521,6 +522,24 @@ local_handshake(S, SAddr, C, CAddr) ->
SData = ok(gen_tcp:recv(C, length(SData))),
ok.
+t_accept_inet6_tclass(Config) when is_list(Config) ->
+ TClassOpt = {tclass,8#56 bsl 2}, % Expedited forwarding
+ Loopback = {0,0,0,0,0,0,0,1},
+ case gen_tcp:listen(0, [inet6, {ip, Loopback}, TClassOpt]) of
+ {ok,L} ->
+ LPort = ok(inet:port(L)),
+ Sa = ok(gen_tcp:connect(Loopback, LPort, [])),
+ Sb = ok(gen_tcp:accept(L)),
+ [TClassOpt] = ok(inet:getopts(Sb, [tclass])),
+ ok = gen_tcp:close(Sb),
+ ok = gen_tcp:close(Sa),
+ ok = gen_tcp:close(L),
+ ok;
+ {error,_} ->
+ {skip,"IPv6 TCLASS not supported"}
+ end.
+
+
%%% Utilities
%% Calls M:F/length(A), which should return a timeout error, and complete
diff --git a/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c b/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
index 2990ddda41..b91dca61d4 100644
--- a/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
+++ b/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
@@ -17,7 +17,7 @@
*
* %CopyrightEnd%
*/
-#include "erl_nif.h"
+#include <erl_nif.h>
#include <stdio.h>
#include <string.h>
diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl
index 6b64c83fc2..929f66d400 100644
--- a/lib/kernel/test/gen_tcp_misc_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl
@@ -1914,7 +1914,7 @@ so_priority(Config) when is_list(Config) ->
%% Accept test utilities (suites are below)
millis() ->
- erlang:monotonic_time(milli_seconds).
+ erlang:monotonic_time(millisecond).
collect_accepts(0,_) -> [];
collect_accepts(N,Tmo) ->
diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl
index 1029d7ef0a..aa616d43d6 100644
--- a/lib/kernel/test/gen_udp_SUITE.erl
+++ b/lib/kernel/test/gen_udp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -717,9 +717,9 @@ implicit_inet6(Config) when is_list(Config) ->
implicit_inet6(Host, Addr) ->
Active = {active,false},
- case gen_udp:open(0, [inet6,Active]) of
+ Loopback = {0,0,0,0,0,0,0,1},
+ case gen_udp:open(0, [inet6,Active,{ip, Loopback}]) of
{ok,S1} ->
- Loopback = {0,0,0,0,0,0,0,1},
io:format("~s ~p~n", ["::1",Loopback]),
implicit_inet6(S1, Active, Loopback),
ok = gen_udp:close(S1),
diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl
index f60c13d2e3..3b502be8b8 100644
--- a/lib/kernel/test/inet_SUITE.erl
+++ b/lib/kernel/test/inet_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -40,7 +40,8 @@
lookup_bad_search_option/1,
getif/1,
getif_ifr_name_overflow/1,getservbyname_overflow/1, getifaddrs/1,
- parse_strict_address/1, simple_netns/1, simple_netns_open/1]).
+ parse_strict_address/1, simple_netns/1, simple_netns_open/1,
+ simple_bind_to_device/1, simple_bind_to_device_open/1]).
-export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1,
kill_gethost/0, parallell_gethost/0, test_netns/0]).
@@ -58,7 +59,8 @@ all() ->
gethostnative_debug_level, gethostnative_soft_restart,
lookup_bad_search_option,
getif, getif_ifr_name_overflow, getservbyname_overflow,
- getifaddrs, parse_strict_address, simple_netns, simple_netns_open].
+ getifaddrs, parse_strict_address, simple_netns, simple_netns_open,
+ simple_bind_to_device, simple_bind_to_device_open].
groups() ->
[{parse, [], [parse_hosts, parse_address]}].
@@ -445,91 +447,125 @@ parse_hosts(Config) when is_list(Config) ->
inet_parse:resolv(ResolvErr1).
parse_address(Config) when is_list(Config) ->
- V4Strict =
+ V4Reversable =
[{{0,0,0,0},"0.0.0.0"},
- {{1,2,3,4},"1.2.3.4"},
+ {{1,2,3,4},"1.2.3.4"},
{{253,252,251,250},"253.252.251.250"},
{{1,2,255,254},"1.2.255.254"}],
- V6Strict =
+ V6Reversable =
[{{0,0,0,0,0,0,0,0},"::"},
+ {{0,0,0,0,0,0,0,1},"::1"},
+ {{0,0,0,0,0,0,0,2},"::0.0.0.2"},
{{15,0,0,0,0,0,0,2},"f::2"},
- {{15,16#f11,0,0,0,0,256,2},"f:f11::0100:2"},
- {{0,0,0,0,0,0,0,16#17},"::17"},
- {{16#700,0,0,0,0,0,0,0},"0700::"},
- {{0,0,0,0,0,0,2,1},"::2:1"},
+ {{15,16#f11,0,0,0,0,256,2},"f:f11::100:2"},
+ {{16#700,0,0,0,0,0,0,0},"700::"},
+ {{0,0,0,0,0,0,2,1},"::0.2.0.1"},
{{0,0,0,0,0,3,2,1},"::3:2:1"},
{{0,0,0,0,4,3,2,1},"::4:3:2:1"},
{{0,0,0,5,4,3,2,1},"::5:4:3:2:1"},
{{0,0,6,5,4,3,2,1},"::6:5:4:3:2:1"},
- {{0,7,6,5,4,3,2,1},"::7:6:5:4:3:2:1"},
+ {{0,7,6,5,4,3,2,1},"0:7:6:5:4:3:2:1"},
{{7,0,0,0,0,0,0,0},"7::"},
{{7,6,0,0,0,0,0,0},"7:6::"},
{{7,6,5,0,0,0,0,0},"7:6:5::"},
{{7,6,5,4,0,0,0,0},"7:6:5:4::"},
{{7,6,5,4,3,0,0,0},"7:6:5:4:3::"},
{{7,6,5,4,3,2,0,0},"7:6:5:4:3:2::"},
- {{7,6,5,4,3,2,1,0},"7:6:5:4:3:2:1::"},
+ {{7,6,5,4,3,2,1,0},"7:6:5:4:3:2:1:0"},
+ {{0,0,6,5,4,3,0,0},"::6:5:4:3:0:0"},
+ {{0,0,6,5,4,0,0,0},"0:0:6:5:4::"},
+ {{8,0,0,5,4,0,0,1},"8::5:4:0:0:1"},
+ {{8,0,0,5,0,0,0,1},"8:0:0:5::1"},
+ {{0,7,6,5,4,3,2,0},"0:7:6:5:4:3:2:0"},
+ {{0,0,6,5,4,3,0,0},"::6:5:4:3:0:0"},
+ {{0,0,0,5,4,0,0,0},"::5:4:0:0:0"},
+ {{0,0,0,0,4,0,0,0},"::4:0:0:0"},
+ {{0,0,0,5,0,0,0,0},"0:0:0:5::"},
{{16#c11,16#c22,16#5c33,16#c440,16#55c0,16#c66c,16#77,16#88},
- "c11:0c22:5c33:c440:55c0:c66c:77:0088"},
+ "c11:c22:5c33:c440:55c0:c66c:77:88"},
+ {{0,16#c22,16#5c33,16#c440,16#55c0,16#c66c,16#77,16#88},
+ "0:c22:5c33:c440:55c0:c66c:77:88"},
{{16#c11,0,16#5c33,16#c440,16#55c0,16#c66c,16#77,16#88},
- "c11::5c33:c440:55c0:c66c:77:0088"},
+ "c11:0:5c33:c440:55c0:c66c:77:88"},
{{16#c11,16#c22,0,16#c440,16#55c0,16#c66c,16#77,16#88},
- "c11:0c22::c440:55c0:c66c:77:0088"},
+ "c11:c22:0:c440:55c0:c66c:77:88"},
{{16#c11,16#c22,16#5c33,0,16#55c0,16#c66c,16#77,16#88},
- "c11:0c22:5c33::55c0:c66c:77:0088"},
+ "c11:c22:5c33:0:55c0:c66c:77:88"},
{{16#c11,16#c22,16#5c33,16#c440,0,16#c66c,16#77,16#88},
- "c11:0c22:5c33:c440::c66c:77:0088"},
+ "c11:c22:5c33:c440:0:c66c:77:88"},
{{16#c11,16#c22,16#5c33,16#c440,16#55c0,0,16#77,16#88},
- "c11:0c22:5c33:c440:55c0::77:0088"},
+ "c11:c22:5c33:c440:55c0:0:77:88"},
{{16#c11,16#c22,16#5c33,16#c440,16#55c0,16#c66c,0,16#88},
- "c11:0c22:5c33:c440:55c0:c66c::0088"},
+ "c11:c22:5c33:c440:55c0:c66c:0:88"},
+ {{16#c11,16#c22,16#5c33,16#c440,16#55c0,16#c66c,16#77,0},
+ "c11:c22:5c33:c440:55c0:c66c:77:0"},
+ {{0,0,16#5c33,16#c440,16#55c0,16#c66c,16#77,16#88},
+ "::5c33:c440:55c0:c66c:77:88"},
{{16#c11,0,0,16#c440,16#55c0,16#c66c,16#77,16#88},
- "c11::c440:55c0:c66c:77:0088"},
+ "c11::c440:55c0:c66c:77:88"},
{{16#c11,16#c22,0,0,16#55c0,16#c66c,16#77,16#88},
- "c11:0c22::55c0:c66c:77:0088"},
+ "c11:c22::55c0:c66c:77:88"},
{{16#c11,16#c22,16#5c33,0,0,16#c66c,16#77,16#88},
- "c11:0c22:5c33::c66c:77:0088"},
+ "c11:c22:5c33::c66c:77:88"},
{{16#c11,16#c22,16#5c33,16#c440,0,0,16#77,16#88},
- "c11:0c22:5c33:c440::77:0088"},
+ "c11:c22:5c33:c440::77:88"},
{{16#c11,16#c22,16#5c33,16#c440,16#55c0,0,0,16#88},
- "c11:0c22:5c33:c440:55c0::0088"},
+ "c11:c22:5c33:c440:55c0::88"},
+ {{16#c11,16#c22,16#5c33,16#c440,16#55c0,16#c66c,0,0},
+ "c11:c22:5c33:c440:55c0:c66c::"},
+ {{0,0,0,16#c440,16#55c0,16#c66c,16#77,16#88},
+ "::c440:55c0:c66c:77:88"},
{{16#c11,0,0,0,16#55c0,16#c66c,16#77,16#88},
- "c11::55c0:c66c:77:0088"},
+ "c11::55c0:c66c:77:88"},
{{16#c11,16#c22,0,0,0,16#c66c,16#77,16#88},
- "c11:0c22::c66c:77:0088"},
+ "c11:c22::c66c:77:88"},
{{16#c11,16#c22,16#5c33,0,0,0,16#77,16#88},
- "c11:0c22:5c33::77:0088"},
+ "c11:c22:5c33::77:88"},
{{16#c11,16#c22,16#5c33,16#c440,0,0,0,16#88},
- "c11:0c22:5c33:c440::0088"},
+ "c11:c22:5c33:c440::88"},
+ {{16#c11,16#c22,16#5c33,16#c440,16#55c0,0,0,0},
+ "c11:c22:5c33:c440:55c0::"},
+ {{0,0,0,0,16#55c0,16#c66c,16#77,16#88},
+ "::55c0:c66c:77:88"},
{{16#c11,0,0,0,0,16#c66c,16#77,16#88},
- "c11::c66c:77:0088"},
+ "c11::c66c:77:88"},
{{16#c11,16#c22,0,0,0,0,16#77,16#88},
- "c11:0c22::77:0088"},
+ "c11:c22::77:88"},
{{16#c11,16#c22,16#5c33,0,0,0,0,16#88},
- "c11:0c22:5c33::0088"},
+ "c11:c22:5c33::88"},
+ {{16#c11,16#c22,16#5c33,16#c440,0,0,0,0},
+ "c11:c22:5c33:c440::"},
+ {{0,0,0,0,0,16#c66c,16#77,16#88},
+ "::c66c:77:88"},
{{16#c11,0,0,0,0,0,16#77,16#88},
- "c11::77:0088"},
+ "c11::77:88"},
{{16#c11,16#c22,0,0,0,0,0,16#88},
- "c11:0c22::0088"},
- {{0,0,0,0,0,65535,258,65534},"::FFFF:1.2.255.254"},
+ "c11:c22::88"},
+ {{16#c11,16#c22,16#5c33,0,0,0,0,0},
+ "c11:c22:5c33::"},
+ {{0,0,0,0,0,65535,258,65534},"::ffff:1.2.255.254"},
+ {{16#fe80,12345,0,0,0,0,0,16#12},"fe80::12%012345"},
{{16#ffff,16#ffff,16#ffff,16#ffff,16#ffff,16#ffff,16#ffff,16#ffff},
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"}
- |[{{D2,0,0,0,0,P,(D1 bsl 8) bor D2,(D3 bsl 8) bor D4},
- erlang:integer_to_list(D2, 16)++"::"++Q++S}
- || {{D1,D2,D3,D4},S} <- V4Strict,
- {P,Q} <- [{0,""},{16#17,"17:"},{16#ff0,"0ff0:"}]]],
+ |[{list_to_tuple(P++[(D1 bsl 8) bor D2,(D3 bsl 8) bor D4]),
+ Q++S}
+ || {{D1,D2,D3,D4},S} <-
+ tl(V4Reversable),
+ {P,Q} <-
+ [{[0,0,0,0,0,16#ffff],"::ffff:"},
+ {[0,0,0,0,0,0],"::"}]]],
V4Sloppy =
[{{10,1,16#98,16#76},"10.0x019876"},
{{8#12,1,8#130,8#321},"012.01.054321"},
- {{255,255,255,255},"255.255.255.0377"},
- {{255,255,255,255},"0Xff.000000000377.0x0000ff.255"},
- {{255,255,255,255},"255.255.65535"},
- {{255,255,255,255},"255.0xFF.0177777"},
- {{255,255,255,255},"255.16777215"},
- {{255,255,255,255},"00377.0XFFFFFF"},
- {{255,255,255,255},"4294967295"},
- {{255,255,255,255},"0xffffffff"},
- {{255,255,255,255},"00000000000037777777777"},
+ {{252,253,254,255},"252.253.254.0377"},
+ {{252,253,254,255},"0Xfc.000000000375.0x0000fe.255"},
+ {{252,253,254,255},"252.253.65279"},
+ {{252,253,254,255},"252.0xFD.0177377"},
+ {{252,253,254,255},"252.16645887"},
+ {{252,253,254,255},"00374.0XFDFEFF"},
+ {{252,253,254,255},"4244504319"},
+ {{252,253,254,255},"0xfcfdfeff"},
+ {{252,253,254,255},"00000000000037477377377"},
{{16#12,16#34,16#56,16#78},"0x12345678"},
{{16#12,16#34,16#56,16#78},"0x12.0x345678"},
{{16#12,16#34,16#56,16#78},"0x12.0X34.0x5678"},
@@ -541,8 +577,14 @@ parse_address(Config) when is_list(Config) ->
{{0,0,0,0},"0.00.0.0"},
{{0,0,0,0},"0.0.000000000000.0"}],
V6Sloppy =
- [{{0,0,0,0,0,65535,(D1 bsl 8) bor D2,(D3 bsl 8) bor D4},S}
- || {{D1,D2,D3,D4},S} <- V4Strict++V4Sloppy],
+ [{{16#a,16#b,16#c,16#0,16#0,16#d,16#e,16#f},"A:B:C::d:e:f"},
+ {{16#fe80,0,0,0,0,0,0,16#12},"fe80::12%XXXXXXX"}]
+ ++
+ [{{P,0,0,0,0,D2,(D1 bsl 8) bor D2,(D3 bsl 8) bor D4},
+ Q++erlang:integer_to_list(D2, 16)++":"++S}
+ || {{D1,D2,D3,D4},S} <- V4Reversable,
+ {P,Q} <-
+ [{16#2001,"2001::"},{16#177,"177::"},{16#ff0,"Ff0::"}]],
V4Err =
["0.256.0.1",
"1.2.3.4.5",
@@ -586,28 +628,36 @@ parse_address(Config) when is_list(Config) ->
"fec0::fFfF:127.0.0.1."],
t_parse_address
(parse_ipv6_address,
- V6Strict++V6Sloppy++V6Err++V4Err),
+ false,
+ V6Reversable++V6Sloppy++V6Err++V4Err),
t_parse_address
(parse_ipv6strict_address,
- V6Strict++V6Err++V4Err++[S || {_,S} <- V6Sloppy]),
+ true,
+ V6Reversable++V6Err++V4Err),
t_parse_address
(parse_ipv4_address,
- V4Strict++V4Sloppy++V4Err++V6Err++[S || {_,S} <- V6Strict]),
+ false,
+ V4Reversable++V4Sloppy++V4Err++V6Err++[S || {_,S} <- V6Reversable]),
t_parse_address
(parse_ipv4strict_address,
- V4Strict++V4Err++V6Err++[S || {_,S} <- V4Sloppy++V6Strict]).
+ true,
+ V4Reversable++V4Err++V6Err++[S || {_,S} <- V4Sloppy++V6Reversable]).
-t_parse_address(Func, []) ->
+t_parse_address(Func, _Reversable, []) ->
io:format("~p done.~n", [Func]),
ok;
-t_parse_address(Func, [{Addr,String}|L]) ->
+t_parse_address(Func, Reversable, [{Addr,String}|L]) ->
io:format("~p = ~p.~n", [Addr,String]),
{ok,Addr} = inet:Func(String),
- t_parse_address(Func, L);
-t_parse_address(Func, [String|L]) ->
+ case Reversable of
+ true ->String = inet:ntoa(Addr);
+ false -> ok
+ end,
+ t_parse_address(Func, Reversable, L);
+t_parse_address(Func, Reversable, [String|L]) ->
io:format("~p.~n", [String]),
{error,einval} = inet:Func(String),
- t_parse_address(Func, L).
+ t_parse_address(Func, Reversable, L).
parse_strict_address(Config) when is_list(Config) ->
{ok, {127,0,0,1}} =
@@ -1247,3 +1297,67 @@ cmd(CmdString) ->
io:put_chars(["# ",CmdString,io_lib:nl()]),
io:put_chars([os:cmd(CmdString++" ; echo ' =>' $?")]),
ok.
+
+-define(CAP_NET_RAW, 13). %% from /usr/include/linux/capability.h
+
+can_bind_to_device({unix, linux}, {Major, _, _})
+ when Major > 2 ->
+ Status = os:cmd("cat /proc/self/status | grep CapEff"),
+ [_, CapEffStr] = string:tokens(Status, [$\n, $\t]),
+ CapEff = list_to_integer(CapEffStr, 16),
+ if CapEff band (1 bsl ?CAP_NET_RAW) =/= 0 ->
+ ok;
+ true ->
+ {skip,"insufficient capabilities, CAP_NET_RAW not granted"}
+ end;
+can_bind_to_device(_OS, _Version) ->
+ {skip,"socket option bind_to_device not supported on this OS or version"}.
+
+simple_bind_to_device(Config) when is_list(Config) ->
+ case can_bind_to_device(os:type(), os:version()) of
+ ok ->
+ {ok,U} = gen_udp:open(0),
+ jog_bind_to_device_opt(U),
+ ok = gen_udp:close(U),
+ %%
+ {ok,L} = gen_tcp:listen(0, []),
+ jog_bind_to_device_opt(L),
+ ok = gen_tcp:close(L),
+ %%
+ case gen_sctp:open() of
+ {ok,S} ->
+ jog_bind_to_device_opt(S),
+ ok = gen_sctp:close(S);
+ {error,eprotonosupport} ->
+ ok
+ end;
+ Other ->
+ Other
+ end.
+
+%% Smoke test bind_to_device support.
+simple_bind_to_device_open(Config) when is_list(Config) ->
+ case can_bind_to_device(os:type(), os:version()) of
+ ok ->
+ {ok,U} = gen_udp:open(0, [binary,{bind_to_device,<<"lo">>},inet]),
+ ok = gen_udp:close(U),
+ {ok,T} = gen_tcp:listen(0, [binary,{bind_to_device,<<"lo">>},inet]),
+ ok = gen_tcp:close(T),
+
+ case gen_sctp:open(0, [binary,{bind_to_device,<<"lo">>},inet]) of
+ {ok,S} ->
+ ok = gen_sctp:close(S);
+ {error,eprotonosupport} ->
+ ok
+ end;
+ Other ->
+ Other
+ end.
+
+jog_bind_to_device_opt(S) ->
+ %% This is just jogging the option mechanics
+ ok = inet:setopts(S, [{bind_to_device,<<>>}]),
+ {ok,[{bind_to_device,<<>>}]} = inet:getopts(S, [bind_to_device]),
+ ok = inet:setopts(S, [{bind_to_device,<<"lo">>}]),
+ {ok,[{bind_to_device,<<"lo">>}]} = inet:getopts(S, [bind_to_device]),
+ ok.
diff --git a/lib/kernel/test/inet_sockopt_SUITE.erl b/lib/kernel/test/inet_sockopt_SUITE.erl
index 322b9f30fe..ada9c2689c 100644
--- a/lib/kernel/test/inet_sockopt_SUITE.erl
+++ b/lib/kernel/test/inet_sockopt_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -620,7 +620,7 @@ ipv6_v6only_close(Module, Socket) ->
%% Test using socket option ipv6_v6only for UDP.
use_ipv6_v6only_udp(Config) when is_list(Config) ->
- case gen_udp:open(0, [inet6,{ipv6_v6only,true}]) of
+ case gen_udp:open(0, [inet6,{ip,{0,0,0,0,0,0,0,1}}, {ipv6_v6only,true}]) of
{ok,S6} ->
case inet:getopts(S6, [ipv6_v6only]) of
{ok,[{ipv6_v6only,true}]} ->
diff --git a/lib/kernel/test/init_SUITE.erl b/lib/kernel/test/init_SUITE.erl
index 1370e23195..2b59eb2bfe 100644
--- a/lib/kernel/test/init_SUITE.erl
+++ b/lib/kernel/test/init_SUITE.erl
@@ -27,7 +27,8 @@
-export([get_arguments/1, get_argument/1, boot_var/1, restart/1,
many_restarts/0, many_restarts/1,
get_plain_arguments/1,
- reboot/1, stop_status/1, stop/1, get_status/1, script_id/1]).
+ reboot/1, stop_status/1, stop/1, get_status/1, script_id/1,
+ find_system_processes/0]).
-export([boot1/1, boot2/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -355,12 +356,16 @@ wait_for(N,Node,EHPid) ->
restart(Config) when is_list(Config) ->
Args = args(),
+ Pa = " -pa " ++ filename:dirname(code:which(?MODULE)),
+
%% Currently test_server:start_node cannot be used. The restarted
%% node immediately halts due to the implementation of
%% test_server:start_node.
- {ok, Node} = loose_node:start(init_test, Args, ?DEFAULT_TIMEOUT_SEC),
+ {ok, Node} = loose_node:start(init_test, Args ++ Pa, ?DEFAULT_TIMEOUT_SEC),
%% Ok, the node is up, now the real test test begins.
erlang:monitor_node(Node, true),
+ SysProcs0 = rpc:call(Node, ?MODULE, find_system_processes, []),
+ [InitPid, PurgerPid, LitCollectorPid, DirtyCodePid] = SysProcs0,
InitPid = rpc:call(Node, erlang, whereis, [init]),
PurgerPid = rpc:call(Node, erlang, whereis, [erts_code_purger]),
Procs = rpc:call(Node, erlang, processes, []),
@@ -375,6 +380,9 @@ restart(Config) when is_list(Config) ->
end,
ok = wait_restart(30, Node),
+ SysProcs1 = rpc:call(Node, ?MODULE, find_system_processes, []),
+ [InitPid1, PurgerPid1, LitCollectorPid1, DirtyCodePid1] = SysProcs1,
+
%% Still the same init process!
InitPid1 = rpc:call(Node, erlang, whereis, [init]),
InitP = pid_to_list(InitPid),
@@ -385,8 +393,24 @@ restart(Config) when is_list(Config) ->
PurgerP = pid_to_list(PurgerPid),
PurgerP = pid_to_list(PurgerPid1),
+ %% and same literal area collector process!
+ case LitCollectorPid of
+ undefined -> undefined = LitCollectorPid1;
+ _ ->
+ LitCollectorP = pid_to_list(LitCollectorPid),
+ LitCollectorP = pid_to_list(LitCollectorPid1)
+ end,
+
+ %% and same dirty process code checker process!
+ case DirtyCodePid of
+ undefined -> undefined = DirtyCodePid1;
+ _ ->
+ DirtyCodeP = pid_to_list(DirtyCodePid),
+ DirtyCodeP = pid_to_list(DirtyCodePid1)
+ end,
+
NewProcs0 = rpc:call(Node, erlang, processes, []),
- NewProcs = NewProcs0 -- [InitPid1, PurgerPid1],
+ NewProcs = NewProcs0 -- SysProcs1,
case check_processes(NewProcs, MaxPid) of
true ->
ok;
@@ -406,6 +430,37 @@ restart(Config) when is_list(Config) ->
loose_node:stop(Node),
ok.
+-record(sys_procs, {init,
+ code_purger,
+ literal_collector,
+ dirty_proc_checker}).
+
+find_system_processes() ->
+ find_system_procs(processes(), #sys_procs{}).
+
+find_system_procs([], SysProcs) ->
+ [SysProcs#sys_procs.init,
+ SysProcs#sys_procs.code_purger,
+ SysProcs#sys_procs.literal_collector,
+ SysProcs#sys_procs.dirty_proc_checker];
+find_system_procs([P|Ps], SysProcs) ->
+ case process_info(P, initial_call) of
+ {initial_call,{otp_ring0,start,2}} ->
+ undefined = SysProcs#sys_procs.init,
+ find_system_procs(Ps, SysProcs#sys_procs{init = P});
+ {initial_call,{erts_code_purger,start,0}} ->
+ undefined = SysProcs#sys_procs.code_purger,
+ find_system_procs(Ps, SysProcs#sys_procs{code_purger = P});
+ {initial_call,{erts_literal_area_collector,start,0}} ->
+ undefined = SysProcs#sys_procs.literal_collector,
+ find_system_procs(Ps, SysProcs#sys_procs{literal_collector = P});
+ {initial_call,{erts_dirty_process_code_checker,start,0}} ->
+ undefined = SysProcs#sys_procs.dirty_proc_checker,
+ find_system_procs(Ps, SysProcs#sys_procs{dirty_proc_checker = P});
+ _ ->
+ find_system_procs(Ps, SysProcs)
+ end.
+
wait_restart(0, _Node) ->
ct:fail(not_restarted);
wait_restart(N, Node) ->
diff --git a/lib/kernel/test/interactive_shell_SUITE.erl b/lib/kernel/test/interactive_shell_SUITE.erl
index fc3706ba1e..298a364a91 100644
--- a/lib/kernel/test/interactive_shell_SUITE.erl
+++ b/lib/kernel/test/interactive_shell_SUITE.erl
@@ -711,7 +711,7 @@ toerl_loop(Port,Acc) ->
end.
millistamp() ->
- erlang:monotonic_time(milli_seconds).
+ erlang:monotonic_time(millisecond).
get_data_within(Port, X, Acc) when X =< 0 ->
?dbg({get_data_within, X, Acc, ?LINE}),
diff --git a/lib/kernel/test/multi_load_SUITE.erl b/lib/kernel/test/multi_load_SUITE.erl
index 369e25ac64..f3258ea520 100644
--- a/lib/kernel/test/multi_load_SUITE.erl
+++ b/lib/kernel/test/multi_load_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -144,14 +144,14 @@ prep_magic([H|T]) ->
prep_magic(Tuple) when is_tuple(Tuple) ->
L = prep_magic(tuple_to_list(Tuple)),
list_to_tuple(L);
-prep_magic(Bin) when is_binary(Bin) ->
- try erlang:has_prepared_code_on_load(Bin) of
+prep_magic(Ref) when is_reference(Ref) ->
+ try erlang:has_prepared_code_on_load(Ref) of
false ->
- %% Create a different kind of magic binary.
+ %% Create a different kind of magic ref.
ets:match_spec_compile([{'_',[true],['$_']}])
catch
_:_ ->
- Bin
+ Ref
end;
prep_magic(Other) ->
Other.
diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl
index 2a1e5016ec..53a9e168ef 100644
--- a/lib/kernel/test/os_SUITE.erl
+++ b/lib/kernel/test/os_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,8 @@
init_per_testcase/2,end_per_testcase/2]).
-export([space_in_cwd/1, quoting/1, cmd_unicode/1, space_in_name/1, bad_command/1,
find_executable/1, unix_comment_in_command/1, deep_list_command/1,
- large_output_command/1, perf_counter_api/1]).
+ large_output_command/1, background_command/0, background_command/1,
+ message_leak/1, close_stdin/0, close_stdin/1, perf_counter_api/1]).
-include_lib("common_test/include/ct.hrl").
@@ -35,7 +36,8 @@ suite() ->
all() ->
[space_in_cwd, quoting, cmd_unicode, space_in_name, bad_command,
find_executable, unix_comment_in_command, deep_list_command,
- large_output_command, perf_counter_api].
+ large_output_command, background_command, message_leak,
+ close_stdin, perf_counter_api].
groups() ->
[].
@@ -52,6 +54,14 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
+init_per_testcase(TC, Config)
+ when TC =:= background_command; TC =:= close_stdin ->
+ case os:type() of
+ {win32, _} ->
+ {skip,"Should not work on windows"};
+ _ ->
+ Config
+ end;
init_per_testcase(_TC,Config) ->
Config.
@@ -261,44 +271,86 @@ deep_list_command(Config) when is_list(Config) ->
%% FYI: [$e, $c, "ho"] =:= io_lib:format("ec~s", ["ho"])
ok.
-%% Test to take sure that the correct data is
+%% Test to make sure that the correct data is
%% received when doing large commands.
large_output_command(Config) when is_list(Config) ->
%% Maximum allowed on windows is 8192, so we test well below that
AAA = lists:duplicate(7000, $a),
comp(AAA,os:cmd("echo " ++ AAA)).
+%% Test that it is possible on unix to start a background task using os:cmd.
+background_command() ->
+ [{timetrap, {seconds, 5}}].
+background_command(_Config) ->
+ %% This testcase fails when the os:cmd takes
+ %% longer then the 5 second timeout
+ os:cmd("sleep 10&").
+
+%% Test that message does not leak to the calling process
+message_leak(_Config) ->
+ process_flag(trap_exit, true),
+
+ os:cmd("echo hello"),
+ [] = receive_all(),
+
+ case os:type() of
+ {unix, _} ->
+ os:cmd("for i in $(seq 1 100); do echo hello; done&"),
+ [] = receive_all();
+ _ ->
+ ok % Cannot background on non-unix
+ end,
+
+ process_flag(trap_exit, false).
+
+%% Test that os:cmd closes stdin of the program that is executed
+close_stdin() ->
+ [{timetrap, {seconds, 5}}].
+close_stdin(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ Fds = filename:join(DataDir, "my_fds"),
+
+ "-1" = os:cmd(Fds).
+
+
%% Test that the os:perf_counter api works as expected
perf_counter_api(_Config) ->
true = is_integer(os:perf_counter()),
true = os:perf_counter() > 0,
- T1 = os:perf_counter(),
+ Conv = fun(T1, T2) ->
+ erlang:convert_time_unit(T2 - T1, perf_counter, nanosecond)
+ end,
+
+ do_perf_counter_test([], Conv, 120000000, 80000000),
+ do_perf_counter_test([1000], fun(T1, T2) -> T2 - T1 end, 120, 80).
+
+do_perf_counter_test(CntArgs, Conv, Upper, Lower) ->
+ %% We run the test multiple times to try to get a somewhat
+ %% stable value... what does this test? That the
+ %% calculate_perf_counter_unit in sys_time.c works somewhat ok.
+ do_perf_counter_test(CntArgs, Conv, Upper, Lower, 10).
+
+do_perf_counter_test(CntArgs, _Conv, Upper, Lower, 0) ->
+ ct:fail("perf_counter_test ~p ~p ~p",[CntArgs, Upper, Lower]);
+do_perf_counter_test(CntArgs, Conv, Upper, Lower, Iters) ->
+
+ T1 = apply(os, perf_counter, CntArgs),
timer:sleep(100),
- T2 = os:perf_counter(),
- TsDiff = erlang:convert_time_unit(T2 - T1, perf_counter, nano_seconds),
- ct:pal("T1: ~p~n"
+ T2 = apply(os, perf_counter, CntArgs),
+ TsDiff = Conv(T1, T2),
+ ct:log("T1: ~p~n"
"T2: ~p~n"
"TsDiff: ~p~n",
[T1,T2,TsDiff]),
- %% We allow a 15% diff
- true = TsDiff < 115000000,
- true = TsDiff > 85000000,
-
- T1Ms = os:perf_counter(1000),
- timer:sleep(100),
- T2Ms = os:perf_counter(1000),
- MsDiff = T2Ms - T1Ms,
- ct:pal("T1Ms: ~p~n"
- "T2Ms: ~p~n"
- "MsDiff: ~p~n",
- [T1Ms,T2Ms,MsDiff]),
-
- %% We allow a 15% diff
- true = MsDiff < 115,
- true = MsDiff > 85.
+ if
+ TsDiff < Upper, TsDiff > Lower ->
+ ok;
+ true ->
+ do_perf_counter_test(CntArgs, Conv, Upper, Lower, Iters-1)
+ end.
%% Util functions
diff --git a/lib/kernel/test/os_SUITE_data/Makefile.src b/lib/kernel/test/os_SUITE_data/Makefile.src
index 912d0cbcb1..f83f781411 100644
--- a/lib/kernel/test/os_SUITE_data/Makefile.src
+++ b/lib/kernel/test/os_SUITE_data/Makefile.src
@@ -3,7 +3,7 @@ LD = @LD@
CFLAGS = @CFLAGS@ -I@erl_include@ @DEFS@
CROSSLDFLAGS = @CROSSLDFLAGS@
-PROGS = my_echo@exe@
+PROGS = my_echo@exe@ my_fds@exe@
all: $(PROGS)
@@ -12,3 +12,9 @@ my_echo@exe@: my_echo@obj@
my_echo@obj@: my_echo.c
$(CC) -c -o my_echo@obj@ $(CFLAGS) my_echo.c
+
+my_fds@exe@: my_fds@obj@
+ $(LD) $(CROSSLDFLAGS) -o my_fds my_fds@obj@ @LIBS@
+
+my_fds@obj@: my_fds.c
+ $(CC) -c -o my_fds@obj@ $(CFLAGS) my_fds.c
diff --git a/lib/kernel/test/os_SUITE_data/my_fds.c b/lib/kernel/test/os_SUITE_data/my_fds.c
new file mode 100644
index 0000000000..704a4d1e1d
--- /dev/null
+++ b/lib/kernel/test/os_SUITE_data/my_fds.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int
+main(int argc, char** argv)
+{
+ char buff[1];
+ int res = read(stdin, buff, 1);
+ printf("%d", res);
+}
diff --git a/lib/kernel/test/pdict_SUITE.erl b/lib/kernel/test/pdict_SUITE.erl
index 638d99176e..d105952df9 100644
--- a/lib/kernel/test/pdict_SUITE.erl
+++ b/lib/kernel/test/pdict_SUITE.erl
@@ -32,10 +32,13 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
mixed/1,
+ literals/1,
simple/1, complicated/1, heavy/1, simple_all_keys/1, info/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
-export([other_process/2]).
+-export([put_do/2, get_do/1, erase_do/1]).
+
init_per_testcase(_Case, Config) ->
Config.
@@ -48,6 +51,7 @@ suite() ->
all() ->
[simple, complicated, heavy, simple_all_keys, info,
+ literals,
mixed].
groups() ->
@@ -418,3 +422,59 @@ do_mixed([GoalN | _]=Goals, CurrN, Array0, C, Rand0) ->
Array2 = array:resize(CurrN-1, Array1),
do_mixed(Goals, CurrN-1, Array2, C+1, Rand2)
end.
+
+%% Test hash precalculation of literal keys
+literals(_Config) ->
+ %% Put literal -> get variable
+ put(1742, "1742"),
+ "1742" = ?MODULE:get_do(1742),
+ "1742" = ?MODULE:erase_do(1742),
+
+ put(-1742, "-1742"),
+ "-1742" = ?MODULE:get_do(-1742),
+ "-1742" = ?MODULE:erase_do(-1742),
+
+ put([], "NIL"),
+ "NIL" = ?MODULE:get_do([]),
+ "NIL" = ?MODULE:erase_do([]),
+
+ put(<<"binary">>, "binary"),
+ "binary" = ?MODULE:get_do(<<"binary">>),
+ "binary" = ?MODULE:erase_do(<<"binary">>),
+
+ BigBin = <<"A large binary with a lot of bytes to make it go off heap as shared and reference counted">>,
+ put(BigBin, "bigbin"),
+ "bigbin" = ?MODULE:get_do(BigBin),
+ "bigbin" = ?MODULE:erase_do(BigBin),
+
+ %% Put variable -> get literal
+ ?MODULE:put_do(4217, "4217"),
+ "4217" = get(4217),
+ "4217" = erase(4217),
+
+ ?MODULE:put_do(-4217, "-4217"),
+ "-4217" = get(-4217),
+ "-4217" = erase(-4217),
+
+ ?MODULE:put_do([], "NIL"),
+ "NIL" = get([]),
+ "NIL" = erase([]),
+
+ ?MODULE:put_do(<<"bytes">>, "bytes"),
+ "bytes" = get(<<"bytes">>),
+ "bytes" = erase(<<"bytes">>),
+
+ ?MODULE:put_do(BigBin, "BigBin"),
+ "BigBin" = get(BigBin),
+ "BigBin" = erase(BigBin),
+
+ ok.
+
+put_do(K, V) ->
+ put(K, V).
+
+get_do(K) ->
+ get(K).
+
+erase_do(K) ->
+ erase(K).
diff --git a/lib/kernel/test/pg2_SUITE.erl b/lib/kernel/test/pg2_SUITE.erl
index fdc268cb5a..acecd34ead 100644
--- a/lib/kernel/test/pg2_SUITE.erl
+++ b/lib/kernel/test/pg2_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@
-export([
otp_7277/1, otp_8259/1, otp_8653/1,
- compat/1, basic/1]).
+ basic/1]).
-define(TESTCASE, testcase_name).
-define(testcase, proplists:get_value(?TESTCASE, Config)).
@@ -56,7 +56,7 @@ all() ->
groups() ->
[{tickets, [],
- [otp_7277, otp_8259, otp_8653, compat, basic]}].
+ [otp_7277, otp_8259, otp_8653, basic]}].
init_per_suite(Config) ->
Config.
@@ -218,29 +218,6 @@ loop() ->
exit(normal)
end.
-%% OTP-8259. Check that 'exchange' and 'del_member' work.
-compat(Config) when is_list(Config) ->
- case test_server:is_release_available("r13b") of
- true ->
- Pid = spawn(forever()),
- G = a,
- ok = pg2:create(G),
- ok = pg2:join(G, Pid),
- ok = pg2:join(G, Pid),
- {ok, A} = start_node_rel(r13, r13b, slave),
- pong = net_adm:ping(A),
- wait_for_ready_net(Config),
- {ok, _} = rpc:call(A, pg2, start, []),
- ?UNTIL([Pid,Pid] =:= rpc:call(A, pg2, get_members, [a])),
- true = exit(Pid, kill),
- ?UNTIL([] =:= pg2:get_members(a)),
- ?UNTIL([] =:= rpc:call(A, pg2, get_members, [a])),
- test_server:stop_node(A),
- ok;
- false ->
- {skipped, "No support for old node"}
- end.
-
%% OTP-8259. Some basic tests.
basic(Config) when is_list(Config) ->
_ = [pg2:delete(G) || G <- pg2:which_groups()],
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index 8be94f1e57..2f4330c217 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,8 +19,8 @@
%%
-module(prim_file_SUITE).
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2,
- read_write_file/1]).
+ init_per_group/2,end_per_group/2, init_per_testcase/2, end_per_testcase/2,
+ read_write_file/1, free_memory/0]).
-export([cur_dir_0a/1, cur_dir_0b/1,
cur_dir_1a/1, cur_dir_1b/1,
make_del_dir_a/1, make_del_dir_b/1,
@@ -115,6 +115,18 @@ groups() ->
[make_link_a, make_link_b, read_link_info_for_non_link,
symlinks_a, symlinks_b, list_dir_error]}].
+init_per_testcase(large_write, Config) ->
+ {ok, Started} = application:ensure_all_started(os_mon),
+ [{started, Started}|Config];
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(large_write, Config) ->
+ [application:stop(App) || App <- lists:reverse(proplists:get_value(started, Config))],
+ ok;
+end_per_testcase(_, _Config) ->
+ ok.
+
init_per_group(_GroupName, Config) ->
Config.
@@ -2022,11 +2034,13 @@ run_large_file_test(Config, Run, Name) ->
{{unix,sunos},OsVersion} when OsVersion < {5,5,1} ->
{skip,"Only supported on Win32, Unix or SunOS >= 5.5.1"};
{{unix,_},_} ->
- N = unix_free(proplists:get_value(priv_dir, Config)),
- io:format("Free disk: ~w KByte~n", [N]),
- if N < 5 bsl 20 ->
+ DiscFree = unix_free(proplists:get_value(priv_dir, Config)),
+ MemFree = free_memory(),
+ io:format("Free disk: ~w KByte~n", [DiscFree]),
+ io:format("Free mem: ~w MByte~n", [MemFree]),
+ if DiscFree < 5 bsl 20; MemFree < 5 bsl 10 ->
%% Less than 5 GByte free
- {skip,"Less than 5 GByte free disk"};
+ {skip,"Less than 5 GByte free disk/mem"};
true ->
do_run_large_file_test(Config, Run, Name)
end;
@@ -2079,6 +2093,27 @@ zip_data([], Bs) ->
zip_data(As, []) ->
As.
+%% Stolen from emulator -> alloc_SUITE
+free_memory() ->
+ %% Free memory in MB.
+ try
+ SMD = memsup:get_system_memory_data(),
+ {value, {free_memory, Free}} = lists:keysearch(free_memory, 1, SMD),
+ TotFree = (Free +
+ case lists:keysearch(cached_memory, 1, SMD) of
+ {value, {cached_memory, Cached}} -> Cached;
+ false -> 0
+ end +
+ case lists:keysearch(buffered_memory, 1, SMD) of
+ {value, {buffered_memory, Buffed}} -> Buffed;
+ false -> 0
+ end),
+ TotFree div (1024*1024)
+ catch
+ error : undef ->
+ ct:fail({"os_mon not built"})
+ end.
+
%%%-----------------------------------------------------------------
%%% Utilities
rm_rf(Mod,Dir) ->
diff --git a/lib/kernel/test/rpc_SUITE.erl b/lib/kernel/test/rpc_SUITE.erl
index 1c72ddc87f..a89a7600a2 100644
--- a/lib/kernel/test/rpc_SUITE.erl
+++ b/lib/kernel/test/rpc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,7 +21,8 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2]).
--export([call/1, block_call/1, multicall/1, multicall_timeout/1,
+-export([off_heap/1,
+ call/1, block_call/1, multicall/1, multicall_timeout/1,
multicall_dies/1, multicall_node_dies/1,
called_dies/1, called_node_dies/1,
called_throws/1, call_benchmark/1, async_call/1]).
@@ -35,7 +36,7 @@ suite() ->
{timetrap,{minutes,2}}].
all() ->
- [call, block_call, multicall, multicall_timeout,
+ [off_heap, call, block_call, multicall, multicall_timeout,
multicall_dies, multicall_node_dies, called_dies,
called_node_dies, called_throws, call_benchmark,
async_call].
@@ -55,6 +56,13 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
+off_heap(_Config) ->
+ %% The rex server process may receive a huge amount of
+ %% messages. Make sure that they are stored off heap to
+ %% avoid exessive GCs.
+ MQD = message_queue_data,
+ {MQD,off_heap} = process_info(whereis(rex), MQD),
+ ok.
%% Test different rpc calls.
diff --git a/lib/kernel/test/sendfile_SUITE.erl b/lib/kernel/test/sendfile_SUITE.erl
index 2673c38494..bfa564c32c 100644
--- a/lib/kernel/test/sendfile_SUITE.erl
+++ b/lib/kernel/test/sendfile_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -100,13 +100,13 @@ init_per_testcase(TC,Config) when TC == t_sendfile_recvduring;
%% Check if sendfile is supported on this platform
case catch sendfile_send(Send) of
ok ->
- Config;
+ init_per_testcase(t_sendfile, Config);
Error ->
ct:log("Error: ~p",[Error]),
{skip,"Not supported"}
end;
init_per_testcase(_Tc,Config) ->
- Config.
+ Config ++ [{sendfile_opts,[{use_threads,false}]}].
t_sendfile_small(Config) when is_list(Config) ->
diff --git a/lib/kernel/test/zlib_SUITE.erl b/lib/kernel/test/zlib_SUITE.erl
index f8257bd20c..4b67fce9a8 100644
--- a/lib/kernel/test/zlib_SUITE.erl
+++ b/lib/kernel/test/zlib_SUITE.erl
@@ -83,7 +83,7 @@ groups() ->
[api_open_close, api_deflateInit,
api_deflateSetDictionary, api_deflateReset,
api_deflateParams, api_deflate, api_deflateEnd,
- api_inflateInit, api_inflateSetDictionary,
+ api_inflateInit, api_inflateSetDictionary, api_inflateGetDictionary,
api_inflateSync, api_inflateReset, api_inflate, api_inflateChunk,
api_inflateEnd, api_setBufsz, api_getBufsz, api_crc32,
api_adler32, api_getQSize, api_un_compress, api_un_zip,
@@ -288,6 +288,42 @@ api_inflateSetDictionary(Config) when is_list(Config) ->
?m({'EXIT',{stream_error,_}}, zlib:inflateSetDictionary(Z1,Dict)),
?m(ok, zlib:close(Z1)).
+%% Test inflateGetDictionary.
+api_inflateGetDictionary(Config) when is_list(Config) ->
+ Z1 = zlib:open(),
+ IsOperationSupported =
+ case catch zlib:inflateGetDictionary(Z1) of
+ {'EXIT',{einval,_}} -> true;
+ {'EXIT',{enotsup,_}} -> false
+ end,
+ _ = zlib:close(Z1),
+ api_inflateGetDictionary_if_supported(IsOperationSupported).
+
+api_inflateGetDictionary_if_supported(false) ->
+ {skip, "inflateGetDictionary/1 unsupported in current setup"};
+api_inflateGetDictionary_if_supported(true) ->
+ % Compress payload using custom dictionary
+ Z1 = zlib:open(),
+ ?m(ok, zlib:deflateInit(Z1)),
+ Dict = <<"foobar barfoo foo bar far boo">>,
+ ?m(_, zlib:deflateSetDictionary(Z1, Dict)),
+ Payload = <<"foobarbarbar">>,
+ Compressed = zlib:deflate(Z1, Payload, finish),
+ ?m(ok, zlib:close(Z1)),
+
+ % Decompress and test dictionary extraction
+ Z2 = zlib:open(),
+ ?m(ok, zlib:inflateInit(Z2)),
+ ?m(<<>>, iolist_to_binary(zlib:inflateGetDictionary(Z2))),
+ ?m({'EXIT',{stream_error,_}}, zlib:inflateSetDictionary(Z2, Dict)),
+ ?m({'EXIT',{{need_dictionary,_},_}}, zlib:inflate(Z2, Compressed)),
+ ?m(ok, zlib:inflateSetDictionary(Z2, Dict)),
+ ?m(Dict, iolist_to_binary(zlib:inflateGetDictionary(Z2))),
+ ?m(Payload, iolist_to_binary(zlib:inflate(Z2, Compressed))),
+ ?m(ok, zlib:close(Z2)),
+ ?m(?BARG, zlib:inflateSetDictionary(Z2, Dict)),
+ ok.
+
%% Test inflateSync.
api_inflateSync(Config) when is_list(Config) ->
{skip,"inflateSync/1 sucks"}.
diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk
index e7d422d03c..4edecd8969 100644
--- a/lib/kernel/vsn.mk
+++ b/lib/kernel/vsn.mk
@@ -1 +1 @@
-KERNEL_VSN = 5.0
+KERNEL_VSN = 5.3
diff --git a/lib/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml
index a05a339003..068389c0c2 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>2016</year>
+ <year>2000</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -37,7 +37,22 @@
section is the version number of Megaco.</p>
- <section><title>Megaco 3.18.1</title>
+ <section><title>Megaco 3.18.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Typos have been fixed.</p>
+ <p>
+ Own Id: OTP-14387</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Megaco 3.18.1</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/megaco/src/app/megaco.appup.src b/lib/megaco/src/app/megaco.appup.src
index 46da79cfe3..9c73ab8072 100644
--- a/lib/megaco/src/app/megaco.appup.src
+++ b/lib/megaco/src/app/megaco.appup.src
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/megaco/src/text/megaco_text_gen_prev3a.hrl b/lib/megaco/src/text/megaco_text_gen_prev3a.hrl
index ae4a990779..db7507fd27 100644
--- a/lib/megaco/src/text/megaco_text_gen_prev3a.hrl
+++ b/lib/megaco/src/text/megaco_text_gen_prev3a.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -424,7 +424,7 @@ enc_TransactionReply(#'TransactionReply'{transactionId = Tid,
transactionResult = Res,
%% These fields are actually not
%% supported in this implementation,
- %% but because the messanger module
+ %% but because the messenger module
%% cannot see any diff between the
%% various v3 implementations...
segmentNumber = asn1_NOVALUE,
diff --git a/lib/megaco/src/text/megaco_text_gen_prev3b.hrl b/lib/megaco/src/text/megaco_text_gen_prev3b.hrl
index e7fb85d137..d5f29025c8 100644
--- a/lib/megaco/src/text/megaco_text_gen_prev3b.hrl
+++ b/lib/megaco/src/text/megaco_text_gen_prev3b.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -424,7 +424,7 @@ enc_TransactionReply(#'TransactionReply'{transactionId = Tid,
transactionResult = Res,
%% These fields are actually not
%% supported in this implementation,
- %% but because the messanger module
+ %% but because the messenger module
%% cannot see any diff between the
%% various v3 implementations...
segmentNumber = asn1_NOVALUE,
diff --git a/lib/megaco/src/text/megaco_text_gen_prev3c.hrl b/lib/megaco/src/text/megaco_text_gen_prev3c.hrl
index 722e97a743..6452be25d0 100644
--- a/lib/megaco/src/text/megaco_text_gen_prev3c.hrl
+++ b/lib/megaco/src/text/megaco_text_gen_prev3c.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -434,7 +434,7 @@ enc_TransactionReply(#'TransactionReply'{transactionId = Tid,
transactionResult = Res,
%% These fields are actually not
%% supported in this implementation,
- %% but because the messanger module
+ %% but because the messenger module
%% cannot see any diff between the
%% various v3 implementations...
segmentNumber = asn1_NOVALUE,
diff --git a/lib/megaco/test/megaco_app_test.erl b/lib/megaco/test/megaco_app_test.erl
index 346a123c66..981d93f5dd 100644
--- a/lib/megaco/test/megaco_app_test.erl
+++ b/lib/megaco/test/megaco_app_test.erl
@@ -17,8 +17,6 @@
%%
%% %CopyrightEnd%
%%
-
-%%
%%----------------------------------------------------------------------
%% Purpose: Verify the application specifics of the Megaco application
%%----------------------------------------------------------------------
@@ -26,296 +24,26 @@
-compile(export_all).
--include("megaco_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 = Case, Config) ->
- NewConfig = [{tc_timeout, ?MINUTES(10)} | Config],
- megaco_test_lib:init_per_testcase(Case, NewConfig);
-init_per_testcase(Case, Config) ->
- megaco_test_lib:init_per_testcase(Case, Config).
-
-end_per_testcase(Case, Config) ->
- megaco_test_lib:end_per_testcase(Case, Config).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-include_lib("common_test/include/ct.hrl").
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
all() ->
[
- fields,
- modules,
- exportall,
- app_depend,
- undef_funcs
+ app,
+ appup
].
-groups() ->
- [].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-init_per_suite(suite) -> [];
-init_per_suite(doc) -> [];
-init_per_suite(Config) when is_list(Config) ->
- case is_app(megaco) of
- {ok, AppFile} ->
- io:format("AppFile: ~n~p~n", [AppFile]),
- case megaco_flex_scanner:is_enabled() of
- true ->
- case megaco_flex_scanner:is_reentrant_enabled() of
- true ->
- io:format("~nMegaco reentrant flex scanner enabled~n~n", []);
- false ->
- io:format("~nMegaco non-reentrant flex scanner enabled~n~n", [])
- end;
- false ->
- io:format("~nMegaco flex scanner disabled~n~n", [])
- end,
- megaco: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, {LineNo, Mod, Code}} ->
- IoList = lists:concat([File, ":", LineNo, ": ",
- Mod:format_error(Code)]),
- {error, list_to_atom(lists:flatten(IoList))};
- Error ->
- {error, {invalid_format, Error}}
- end.
-
-
-end_per_suite(suite) -> [];
-end_per_suite(doc) -> [];
-end_per_suite(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(megaco),
- 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 = megaco,
- 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.
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+app() ->
+ [{doc, "Test that the megaco app file is ok"}].
+app(Config) when is_list(Config) ->
+ ok = test_server:app_test(megaco).
+%%--------------------------------------------------------------------
+appup() ->
+ [{doc, "Test that the megaco appup file is ok"}].
+appup(Config) when is_list(Config) ->
+ ok = test_server:appup_test(megaco).
diff --git a/lib/megaco/test/megaco_appup_test.erl b/lib/megaco/test/megaco_appup_test.erl
index 325e7a6096..8dc3ad51a0 100644
--- a/lib/megaco/test/megaco_appup_test.erl
+++ b/lib/megaco/test/megaco_appup_test.erl
@@ -17,8 +17,6 @@
%%
%% %CopyrightEnd%
%%
-
-%%
%%----------------------------------------------------------------------
%% Purpose: Verify the application specifics of the Megaco application
%%----------------------------------------------------------------------
@@ -27,26 +25,18 @@
-compile(export_all).
-compile({no_auto_import,[error/1]}).
+-include_lib("common_test/include/ct.hrl").
-include("megaco_test_lib.hrl").
--define(APPLICATION, megaco).
-
-t() -> megaco_test_lib:t(?MODULE).
-t(Case) -> megaco_test_lib:t({?MODULE, Case}).
-
-
-%% Test server callbacks
-init_per_testcase(Case, Config) ->
- megaco_test_lib:init_per_testcase(Case, Config).
-
-end_per_testcase(Case, Config) ->
- megaco_test_lib:end_per_testcase(Case, Config).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
all() ->
- [appup].
+ Cases =
+ [
+ appup_file
+ ],
+ Cases.
groups() ->
[].
@@ -64,16 +54,9 @@ end_per_group(_GroupName, Config) ->
init_per_suite(suite) -> [];
init_per_suite(doc) -> [];
init_per_suite(Config) when is_list(Config) ->
- AppFile = file_name(?APPLICATION, ".app"),
- AppupFile = file_name(?APPLICATION, ".appup"),
- [{app_file, AppFile}, {appup_file, AppupFile}|Config].
+ Config.
-file_name(App, Ext) ->
- LibDir = code:lib_dir(App),
- filename:join([LibDir, "ebin", atom_to_list(App) ++ Ext]).
-
-
end_per_suite(suite) -> [];
end_per_suite(doc) -> [];
end_per_suite(Config) when is_list(Config) ->
@@ -82,468 +65,17 @@ end_per_suite(Config) when is_list(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,megaco,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}]} ->
- 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),
- check_module_subset(UpFrom),
- check_module_subset(DownTo),
- ok.
-
-
-check_depends(_, [], _) ->
- ok;
-check_depends(UpDown, [Dep|Deps], Modules) ->
- check_depend(UpDown, Dep, Modules),
- check_depends(UpDown, Deps, Modules).
-
-
-check_depend(up = UpDown, {add_application, ?APPLICATION} = Instr, Modules) ->
- d("check_instructions(~w) -> entry with"
- "~n Instruction: ~p"
- "~n Modules: ~p", [UpDown, Instr, Modules]),
- ok;
-check_depend(down = UpDown, {remove_application, ?APPLICATION} = Instr,
- Modules) ->
- d("check_instructions(~w) -> entry with"
- "~n Instruction: ~p"
- "~n Modules: ~p", [UpDown, Instr, Modules]),
- ok;
-check_depend(UpDown, {V, Instructions}, Modules) ->
- d("check_instructions(~w) -> entry with"
- "~n V: ~p"
- "~n Modules: ~p", [UpDown, V, 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) ->
- d("check_instructions(~w) -> entry with"
- "~n Instr: ~p", [UpDown,Instr]),
- case (catch check_instruction(UpDown, Instr, AllInstr, Modules)) of
- ok ->
- check_instructions(UpDown, Instrs, AllInstr,
- [Instr|Good], Bad, Modules);
- {error, Reason} ->
- d("check_instructions(~w) -> bad instruction: "
- "~n Reason: ~p", [UpDown,Reason]),
- check_instructions(UpDown, Instrs, AllInstr, Good,
- [{Instr, Reason}|Bad], Modules)
- end.
-
-%% A new module is added
-check_instruction(up, {add_module, Module}, _, Modules)
- when is_atom(Module) ->
- d("check_instruction -> entry when up-add_module instruction with"
- "~n Module: ~p", [Module]),
- check_module(Module, Modules);
-
-%% An old module is re-added
-check_instruction(down, {add_module, Module}, _, Modules)
- when is_atom(Module) ->
- d("check_instruction -> entry when down-add_module instruction with"
- "~n Module: ~p", [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) andalso is_atom(Pre) andalso is_atom(Post) ->
- d("check_instruction -> entry when up-remove instruction with"
- "~n Module: ~p"
- "~n Pre: ~p"
- "~n Post: ~p", [Module, Pre, 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) andalso is_atom(Pre) andalso is_atom(Post) ->
- d("check_instruction -> entry when down-remove instruction with"
- "~n Module: ~p"
- "~n Pre: ~p"
- "~n Post: ~p", [Module, Pre, 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(_, {load_module, Module, Pre, Post, Depend},
- AllInstr, Modules)
- when is_atom(Module) andalso is_atom(Pre) andalso is_atom(Post) andalso is_list(Depend) ->
- d("check_instruction -> entry when load_module instruction with"
- "~n Module: ~p"
- "~n Pre: ~p"
- "~n Post: ~p"
- "~n Depend: ~p", [Module, Pre, Post, Depend]),
- check_module(Module, Modules),
- check_module_depend(Module, Depend, Modules),
- check_module_depend(Module, Depend, updated_modules(AllInstr, [])),
- check_purge(Pre),
- check_purge(Post);
-
-check_instruction(_, {update, Module, Change, Pre, Post, Depend},
- AllInstr, Modules)
- when is_atom(Module) andalso is_atom(Pre) andalso is_atom(Post) andalso is_list(Depend) ->
- d("check_instruction -> entry when update instruction with"
- "~n Module: ~p"
- "~n Change: ~p"
- "~n Pre: ~p"
- "~n Post: ~p"
- "~n Depend: ~p", [Module, Change, Pre, Post, Depend]),
- check_module(Module, Modules),
- check_module_depend(Module, Depend, Modules),
- check_module_depend(Module, Depend, updated_modules(AllInstr, [])),
- check_change(Change),
- check_purge(Pre),
- check_purge(Post);
-
-check_instruction(_, {update, Module, supervisor}, _, Modules)
- when is_atom(Module) ->
- check_module(Module, Modules);
-
-check_instruction(_, {apply, {Module, Function, Args}}, _, Modules)
- when is_atom(Module) andalso is_atom(Function) andalso is_list(Args) ->
- d("check_instruction -> entry when down-apply instruction with"
- "~n Module: ~p"
- "~n Function: ~p"
- "~n Args: ~p", [Module, Function, Args]),
- check_module(Module, Modules),
- check_apply(Module, Function, Args);
-
-check_instruction(_, {restart_application, ?APPLICATION}, _AllInstr, _Modules) ->
- ok;
-
-check_instruction(_, Instr, _AllInstr, _Modules) ->
- d("check_instruction -> entry when unknown instruction with"
- "~n Instr: ~p", [Instr]),
- error({error, {unknown_instruction, Instr}}).
-
-
-%% If Module X depends on Module Y, then module Y must have an update
-%% instruction of some sort (otherwise the depend is faulty).
-updated_modules([], Modules) ->
- d("update_modules -> entry when done with"
- "~n Modules: ~p", [Modules]),
- Modules;
-updated_modules([Instr|Instrs], Modules) ->
- d("update_modules -> entry with"
- "~n Instr: ~p"
- "~n Modules: ~p", [Instr,Modules]),
- Module = instruction_module(Instr),
- d("update_modules -> Module: ~p", [Module]),
- updated_modules(Instrs, [Module|Modules]).
-
-instruction_module({add_module, Module}) ->
- Module;
-instruction_module({remove, {Module, _, _}}) ->
- Module;
-instruction_module({load_module, Module, _, _, _}) ->
- Module;
-instruction_module({update, Module, _, _, _, _}) ->
- Module;
-instruction_module({apply, {Module, _, _}}) ->
- Module;
-instruction_module(Instr) ->
- d("instruction_module -> entry when unknown instruction with"
- "~n Instr: ~p", [Instr]),
- error({error, {unknown_instruction, Instr}}).
-
-
-%% Check that the modules handled in an instruction set for version X
-%% is a subset of the instruction set for version X-1.
-check_module_subset(Instructions) ->
- %% io:format("check_module_subset -> "
- %% "~n Instructions: ~p"
- %% "~n", [Instructions]),
- do_check_module_subset(modules_of(Instructions)).
-
-do_check_module_subset([]) ->
- ok;
-do_check_module_subset([_]) ->
- ok;
-do_check_module_subset([{_V1, Mods1}|T]) ->
- %% io:format("do_check_module_subset -> "
- %% "~n V1: ~p"
- %% "~n Mods1: ~p"
- %% "~n T: ~p"
- %% "~n", [_V1, Mods1, T]),
- {V2, Mods2} = hd(T),
- %% Check that the modules in V1 is a subset of V2
- case do_check_module_subset2(Mods1, Mods2) of
- ok ->
- do_check_module_subset(T);
- {error, Modules} ->
- fail({subset_missing_instructions, V2, Modules})
- end.
-
-do_check_module_subset2(Mods1, Mods2) ->
- do_check_module_subset2(Mods1, Mods2, []).
-
-do_check_module_subset2([], _, []) ->
- ok;
-do_check_module_subset2([], _, Acc) ->
- {error, lists:reverse(Acc)};
-do_check_module_subset2([Mod|Mods], Mods2, Acc) ->
- case lists:member(Mod, Mods2) of
- true ->
- do_check_module_subset2(Mods, Mods2, Acc);
- false ->
- do_check_module_subset2(Mods, Mods2, [Mod|Acc])
- end.
-
-
-modules_of(Instructions) ->
- modules_of(Instructions, []).
-
-modules_of([], Acc) ->
- lists:reverse(Acc);
-modules_of([{V,Instructions}|T], Acc) ->
- %% io:format("modules_of -> "
- %% "~n V: ~p"
- %% "~n Instructions: ~p"
- %% "~n", [V, Instructions]),
- case modules_of2(Instructions, []) of
- Mods when is_list(Mods) ->
- %% io:format("modules_of -> "
- %% "~n Mods: ~p"
- %% "~n", [Mods]),
- modules_of(T, [{V, Mods}|Acc]);
- skip ->
- %% io:format("modules_of -> skip"
- %% "~n", []),
- modules_of(T, Acc)
- end.
-
-modules_of2([], Acc) ->
- lists:reverse(Acc);
-modules_of2([Instr|Instructions], Acc) ->
- case module_of(Instr) of
- {value, Mod} ->
- modules_of2(Instructions, [Mod|Acc]);
- skip ->
- skip;
- false ->
- modules_of2(Instructions, Acc)
- end.
-
-module_of({add_module, Module}) ->
- {value, Module};
-module_of({remove, {Module, _Pre, _Post}}) ->
- {value, Module};
-module_of({load_module, Module, _Pre, _Post, _Depend}) ->
- {value, Module};
-module_of({update, Module, _Change, _Pre, _Post, _Depend}) ->
- {value, Module};
-module_of({restart_application, _App}) ->
- skip;
-module_of(_) ->
- false.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% The version is a string consting of numbers separated by dots: "."
-%% Example: "3.3.3"
-%%
-check_version(V) when is_list(V) ->
- case do_check_version(string:tokens(V, [$.])) of
- ok ->
- ok;
- {error, BadVersionPart} ->
- throw({error, {bad_version, V, BadVersionPart}})
- end;
-check_version(V) ->
- error({bad_version, V}).
-
-do_check_version([]) ->
- ok;
-do_check_version([H|T]) ->
- case (catch list_to_integer(H)) of
- I when is_integer(I) ->
- do_check_version(T);
- _ ->
- {error, H}
- end.
-
-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) ->
- d("check_module_depend -> entry with"
- "~n M: ~p", [M]),
- ok;
-check_module_depend(M, Deps, Modules) when is_atom(M) andalso is_list(Deps) ->
- d("check_module_depend -> entry with"
- "~n M: ~p"
- "~n Deps: ~p"
- "~n Modules: ~p", [M, Deps, Modules]),
- case [Dep || Dep <- Deps, lists:member(Dep, Modules) == false] of
- [] ->
- ok;
- Unknown ->
- error({unknown_depend_modules, Unknown})
- end;
-check_module_depend(_M, D, _Modules) ->
- d("check_module_depend -> entry when bad depend with"
- "~n D: ~p", [D]),
- 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}).
-
-
-check_apply(Module, Function, Args) ->
- case (catch Module:module_info()) of
- Info when is_list(Info) ->
- check_exported(Function, Args, Info);
- {'EXIT', {undef, _}} ->
- error({not_existing_module, Module})
- end.
-
-check_exported(Function, Args, Info) ->
- case lists:keysearch(exports, 1, Info) of
- {value, {exports, FuncList}} ->
- Arity = length(Args),
- Arities = [A || {F, A} <- FuncList, F == Function],
- case lists:member(Arity, Arities) of
- true ->
- ok;
- false ->
- error({not_exported_function, Function, Arity})
- end;
- _ ->
- error({bad_export, Info})
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-error(Reason) ->
- throw({error, Reason}).
-
-fail(Reason) ->
- exit({suite_failed, Reason}).
+%% Test server callbacks
+init_per_testcase(_Case, Config) when is_list(Config) ->
+ Config.
-key1search(Key, L) ->
- case lists:keysearch(Key, 1, L) of
- undefined ->
- fail({not_found, Key, L});
- {value, {Key, Value}} ->
- Value
- end.
+end_per_testcase(_Case, Config) when is_list(Config) ->
+ Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-d(F, A) ->
- d(false, F, A).
+%% Perform a simple check of the appup file
+appup_file(Config) when is_list(Config) ->
+ ok = ?t:appup_test(megaco).
-d(true, F, A) ->
- io:format(F ++ "~n", A);
-d(_, _, _) ->
- ok.
-
-
diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk
index b95cd66a81..9c6ba5bba0 100644
--- a/lib/megaco/vsn.mk
+++ b/lib/megaco/vsn.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2015. All Rights Reserved.
+# Copyright Ericsson AB 1997-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,6 +19,6 @@
# %CopyrightEnd%
APPLICATION = megaco
-MEGACO_VSN = 3.18.1
+MEGACO_VSN = 3.18.2
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)"
diff --git a/lib/mnesia/doc/src/Mnesia_chap1.xml b/lib/mnesia/doc/src/Mnesia_chap1.xml
index 9dfeb5efe4..035e934ed2 100644
--- a/lib/mnesia/doc/src/Mnesia_chap1.xml
+++ b/lib/mnesia/doc/src/Mnesia_chap1.xml
@@ -32,38 +32,38 @@
<rev>C</rev>
<file>Mnesia_chap1.xml</file>
</header>
- <p>The <c>Mnesia</c> application provides a heavy duty real-time
+ <p>The Mnesia application provides a heavy duty real-time
distributed database.</p>
<section>
<title>Scope</title>
<p>This User's Guide describes how to
- build <c>Mnesia</c> database applications, and how to integrate
- and use the <c>Mnesia</c> database management system with
+ build Mnesia database applications, and how to integrate
+ and use the Mnesia database management system with
OTP. Programming constructs are described, and numerous
programming examples are included to illustrate the use of
- <c>Mnesia</c>.</p>
+ Mnesia.</p>
<p>This User's Guide is organized as follows:</p>
<list type="bulleted">
<item><seealso marker="Mnesia_overview">Mnesia</seealso>
provides an introduction to
- <c>Mnesia</c>.
+ Mnesia.
</item>
<item><seealso marker="Mnesia_chap2">Getting Started</seealso>
- introduces <c>Mnesia</c> with an example database. Examples
+ introduces Mnesia with an example database. Examples
are included how to start an Erlang session, specify a
- <c>Mnesia</c> database directory, initialize a database
- schema, start <c>Mnesia</c>, and create tables. Initial
+ Mnesia database directory, initialize a database
+ schema, start Mnesia, and create tables. Initial
prototyping of record definitions is also discussed.
</item>
<item><seealso marker="Mnesia_chap3">Build a Mnesia
Database</seealso> more formally describes the steps
- introduced in the previous section, namely the <c>Mnesia</c>
- functions that define a database schema, start <c>Mnesia</c>,
+ introduced in the previous section, namely the Mnesia
+ functions that define a database schema, start Mnesia,
and create the required tables.
</item>
<item><seealso marker="Mnesia_chap4">Transactions and Other Access Contexts</seealso>
- describes the transactions properties that make <c>Mnesia</c> into
+ describes the transactions properties that make Mnesia into
a fault tolerant, real-time distributed database management
system. This section also describes the concept of locking
to ensure consistency in tables, and "dirty
@@ -76,16 +76,16 @@
features include indexing, checkpoints, distribution and fault
tolerance, disc-less nodes, replication manipulation, local
content tables, concurrency, and object-based programming in
- <c>Mnesia</c>.
+ Mnesia.
</item>
<item><seealso marker="Mnesia_chap7">Mnesia System
Information</seealso> describes the files contained in the
- <c>Mnesia</c> database directory, database configuration data,
+ Mnesia database directory, database configuration data,
core and table dumps, as well as the important subject of
backup, fall-back, and disaster recovery principles.
</item>
<item><seealso marker="Mnesia_chap8">Combine Mnesia with
- SNMP</seealso> is a short section that outlines <c>Mnesia</c>
+ SNMP</seealso> is a short section that outlines Mnesia
integrated with SNMP.
</item>
<item><seealso marker="Mnesia_App_A">Appendix A: Backup
diff --git a/lib/mnesia/doc/src/Mnesia_chap3.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap3.xmlsrc
index 8f1a4366ee..ffda739dfa 100644
--- a/lib/mnesia/doc/src/Mnesia_chap3.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap3.xmlsrc
@@ -348,7 +348,7 @@ skeppet %<input>erl -sname b -mnesia dir '"/ldisc/scratch/Mnesia.company"'</inpu
<p>If the startup procedure fails, the function
<seealso marker="mnesia#start/0">mnesia:start()</seealso>
returns the cryptic tuple
- <c>{error,{shutdown, {mnesia_sup,start,[normal,[]]}}}</c>.
+ <c>{error,{shutdown, {mnesia_sup,start_link,[normal,[]]}}}</c>.
To get more information about the start failure, use
command-line arguments <c>-boot start_sasl</c> as argument to
the <c>erl</c> script.</p>
diff --git a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
index a83d1d77d2..62759c624b 100644
--- a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
@@ -362,11 +362,6 @@ ok
<seealso marker="mnesia_frag_hash">mnesia_frag_hash</seealso>
callback behavior. This property can explicitly be set at
table creation. Default is <c>mnesia_frag_hash</c>.</p>
- <p>Older tables, that were created before the concept of
- user-defined hash modules was introduced, use module
- <c>mnesia_frag_old_hash</c> to be backwards compatible.
- <c>mnesia_frag_old_hash</c> still uses the poor
- deprecated function <c>erlang:hash/1</c>.</p>
</item>
<tag><c>{hash_state, Term}</c></tag>
<item>
diff --git a/lib/mnesia/doc/src/Mnesia_chap8.xml b/lib/mnesia/doc/src/Mnesia_chap8.xml
index f1a469e315..4a2eed84d7 100644
--- a/lib/mnesia/doc/src/Mnesia_chap8.xml
+++ b/lib/mnesia/doc/src/Mnesia_chap8.xml
@@ -51,11 +51,11 @@
</item>
</list>
<p>All these approaches have different advantages and
- disadvantages. <c>Mnesia</c> applications can easily be opened to
+ disadvantages. Mnesia applications can easily be opened to
the SNMP protocol. A direct 1-to-1 mapping can be established
- between <c>Mnesia</c> tables and SNMP tables. This means
- that a <c>Mnesia</c> table can be configured to be <em>both</em>
- a <c>Mnesia</c> table and an SNMP table. A number of functions to
+ between Mnesia tables and SNMP tables. This means
+ that a Mnesia table can be configured to be <em>both</em>
+ a Mnesia table and an SNMP table. A number of functions to
control this behavior are described in the Reference Manual.</p>
</section>
</chapter>
diff --git a/lib/mnesia/doc/src/Mnesia_overview.xml b/lib/mnesia/doc/src/Mnesia_overview.xml
index d2d597b85d..63f2309284 100644
--- a/lib/mnesia/doc/src/Mnesia_overview.xml
+++ b/lib/mnesia/doc/src/Mnesia_overview.xml
@@ -39,14 +39,14 @@
high level of fault tolerance that is required in many nonstop
systems, combined with requirements on the DBMS to run in the same
address space as the application, have led us to implement a new
- DBMS, called <c>Mnesia</c>.</p>
- <p><c>Mnesia</c> is implemented in, and tightly connected to Erlang.
+ DBMS, called Mnesia.</p>
+ <p>Mnesia is implemented in, and tightly connected to Erlang.
It provides the functionality that is necessary for the
implementation of fault tolerant telecommunications systems.</p>
- <p><c>Mnesia</c> is a multiuser distributed DBMS specially made for
+ <p>Mnesia is a multiuser distributed DBMS specially made for
industrial telecommunications applications written in Erlang,
which is also the intended target language.
- <c>Mnesia</c> tries to address all the data
+ Mnesia tries to address all the data
management issues required for typical telecommunications systems.
It has a number of features that are not normally found in traditional
databases.</p>
@@ -54,7 +54,7 @@
from the features provided by traditional DBMSs. The applications now
implemented in Erlang need a mixture of a broad range
of features, which generally are not satisfied by traditional DBMSs.
- <c>Mnesia</c> is designed with requirements like the following in
+ Mnesia is designed with requirements like the following in
mind:</p>
<list type="ordered">
<item>Fast real-time key/value lookup
@@ -71,9 +71,9 @@
<item>Complex objects
</item>
</list>
- <p><c>Mnesia</c> is designed with the typical data management problems
- of telecommunications applications in mind. This sets <c>Mnesia</c>
- apart from most other DBMS. Hence <c>Mnesia</c>
+ <p>Mnesia is designed with the typical data management problems
+ of telecommunications applications in mind. This sets Mnesia
+ apart from most other DBMS. Hence Mnesia
combines many concepts found in traditional databases such as
transactions and queries with concepts found in data management
systems for telecommunications applications, for example:</p>
@@ -86,7 +86,7 @@
suspending it.
</item>
</list>
- <p><c>Mnesia</c> is also interesting because of its tight coupling to
+ <p>Mnesia is also interesting because of its tight coupling to
Erlang, thus almost turning Erlang into a database programming
language. This has many benefits, the foremost is that
the impedance mismatch between the data format used by the DBMS
@@ -97,7 +97,7 @@
<title>Mnesia Database Management System (DBMS)</title>
<section>
<title>Features</title>
- <p><c>Mnesia</c> contains the following features that combine to
+ <p>Mnesia contains the following features that combine to
produce a fault-tolerant, distributed DBMS written in Erlang:
</p>
<list type="bulleted">
@@ -118,7 +118,7 @@
functions can be called within one transaction.
</item>
<item>Several transactions can run concurrently, and their execution
- is fully synchronized by the DBMS. <c>Mnesia</c> ensures that no
+ is fully synchronized by the DBMS. Mnesia ensures that no
two processes manipulate data simultaneously.
</item>
<item>Transactions can be assigned the property of being executed on
@@ -132,29 +132,29 @@
<section>
<title>Add-On Application</title>
- <p>Query List Comprehension (QLC) can be used with <c>Mnesia</c>
+ <p>Query List Comprehension (QLC) can be used with Mnesia
to produce specialized functions that enhance the operational
- ability of <c>Mnesia</c>. QLC has its own documentation as part
+ ability of Mnesia. QLC has its own documentation as part
of the OTP documentation set. The main features of QLC
- when used with <c>Mnesia</c> are as follows:</p>
+ when used with Mnesia are as follows:</p>
<list type="bulleted">
- <item>QLC can optimize the query compiler for the <c>Mnesia</c>
+ <item>QLC can optimize the query compiler for the Mnesia
DBMS, essentially making the DBMS more efficient.
</item>
<item>QLC can be used as a database programming
- language for <c>Mnesia</c>. It includes a notation called "list
+ language for Mnesia. It includes a notation called "list
comprehensions" and can be used to make complex database
queries over a set of tables.
</item>
</list>
<p>For information about QLC, see the
<seealso marker="stdlib:qlc">qlc</seealso> manual page
- in <c>STDLIB</c>.</p>
+ in STDLIB.</p>
</section>
<section>
<title>When to Use Mnesia</title>
- <p>Use <c>Mnesia</c> with the following types of applications:</p>
+ <p>Use Mnesia with the following types of applications:</p>
<list type="bulleted">
<item>Applications that need to replicate data.
</item>
@@ -166,7 +166,7 @@
<item>Applications that use soft real-time characteristics.
</item>
</list>
- <p><c>Mnesia</c> is not as appropriate with the
+ <p>Mnesia is not as appropriate with the
following types of applications:</p>
<list type="bulleted">
<item>Programs that process plain text or binary data files.
@@ -176,14 +176,14 @@
library module <c>dets</c>, which is a disc-based version
of the module <c>ets</c>. For information about <c>dets</c>,
see the <seealso marker="stdlib:dets">dets</seealso>
- manual page in <c>STDLIB</c>.
+ manual page in STDLIB.
</item>
<item>Applications that need disc logging facilities.
Those applications can
use the module <c>disk_log</c> by preference. For
information about <c>disk_log</c>, see the
<seealso marker="kernel:disk_log">disk_log</seealso>
- manual page in <c>Kernel</c>.
+ manual page in Kernel.
</item>
<item>Hard real-time systems.
</item>
diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml
index b35214cde9..621b6047ee 100644
--- a/lib/mnesia/doc/src/mnesia.xml
+++ b/lib/mnesia/doc/src/mnesia.xml
@@ -37,7 +37,7 @@
<description>
<p>The following are some of the most important and attractive
- capabilities provided by <c>Mnesia</c>:</p>
+ capabilities provided by Mnesia:</p>
<list type="bulleted">
<item>A relational/object hybrid data model that is suitable
for telecommunications applications.
@@ -62,15 +62,15 @@
reconfigured at runtime without stopping the system.
</item>
</list>
- <p>This Reference Manual describes the <c>Mnesia</c> API. This
- includes functions that define and manipulate <c>Mnesia</c>
+ <p>This Reference Manual describes the Mnesia API. This
+ includes functions that define and manipulate Mnesia
tables.</p>
<p>All functions in this Reference Manual can be used in any
combination with queries using the list comprehension notation.
For information about the query notation, see the
<seealso marker="stdlib:qlc">qlc</seealso>
- manual page in <c>STDLIB</c>.</p>
- <p>Data in <c>Mnesia</c> is organized as a set of tables. Each table
+ manual page in STDLIB.</p>
+ <p>Data in Mnesia is organized as a set of tables. Each table
has a name that must be an atom. Each table is made up of
Erlang records. The user is responsible for the record
definitions. Each table also has a set of properties. The
@@ -121,14 +121,14 @@
<item>
<p><c>index</c>. This is a list of attribute names, or
integers, which specify the tuple positions on which
- <c>Mnesia</c> is to build and maintain an extra index
+ Mnesia is to build and maintain an extra index
table.</p>
</item>
<item>
<p><c>local_content</c>. When an application requires
tables whose contents are local to each node,
<c>local_content</c> tables can be used. The table name
- is known to all <c>Mnesia</c> nodes, but its content is
+ is known to all Mnesia nodes, but its content is
unique on each node. This means that access to such a table
must be done locally. Set field <c>local_content</c> to
<c>true</c> to enable the <c>local_content</c>
@@ -143,7 +143,7 @@
avoid inconsistencies because of network splits.</p>
</item>
<item>
- <p><c>snmp</c>. Each (set-based) <c>Mnesia</c> table can be
+ <p><c>snmp</c>. Each (set-based) Mnesia table can be
automatically turned into a Simple Network Management
Protocol (SNMP) ordered table as well.
This property specifies the types of the SNMP keys.</p>
@@ -174,7 +174,7 @@
copy of each modified record during the transaction. During
iteration, that is, <c>mnesia:fold[lr]/4</c>,
<c>mnesia:next/2</c>, <c>mnesia:prev/2</c>, and
- <c>mnesia:snmp_get_next_index/2</c>, <c>Mnesia</c>
+ <c>mnesia:snmp_get_next_index/2</c>, Mnesia
compensates for every written or deleted record, which can
reduce the performance.</p>
<p>If possible, avoid writing or deleting records in the same
@@ -188,7 +188,7 @@
<desc>
<p>Makes the transaction silently
return the tuple <c>{aborted, Reason}</c>.
- Termination of a <c>Mnesia</c> transaction means that
+ Termination of a Mnesia transaction means that
an exception is thrown to an enclosing <c>catch</c>.
Thus, the expression <c>catch mnesia:abort(x)</c> does
not terminate the transaction.</p>
@@ -324,7 +324,7 @@
<c>mnesia:ets</c>. Argument <c>AccessMod</c>
is the name of a callback module, which implements the
<c>mnesia_access</c> behavior.</p>
- <p><c>Mnesia</c> forwards calls to the following functions:</p>
+ <p>Mnesia forwards calls to the following functions:</p>
<list type="bulleted">
<item>mnesia:lock/2 (read_lock_table/1, write_lock_table/1)
</item>
@@ -391,15 +391,15 @@
</item>
</list>
<p><c>ActivityId</c> is a record that represents the identity
- of the enclosing <c>Mnesia</c> activity. The first field
+ of the enclosing Mnesia activity. The first field
(obtained with <c>element(1, ActivityId)</c>) contains an
atom, which can be interpreted as the activity type:
<c>ets</c>, <c>async_dirty</c>, <c>sync_dirty</c>, or
<c>tid</c>. <c>tid</c> means that the activity is a
transaction. The structure of the rest of the identity
- record is internal to <c>Mnesia</c>.</p>
+ record is internal to Mnesia.</p>
<p><c>Opaque</c> is an opaque data structure that is internal
- to <c>Mnesia</c>.</p>
+ to Mnesia.</p>
</desc>
</func>
<func>
@@ -458,7 +458,7 @@ mnesia:add_table_index(person, age)</code>
<desc>
<marker id="async_dirty"></marker>
<p>Calls the <c>Fun</c> in a context that is not protected by
- a transaction. The <c>Mnesia</c> function calls performed in
+ a transaction. The Mnesia function calls performed in
the <c>Fun</c> are mapped to the corresponding dirty
functions. This still involves logging, replication, and
subscriptions, but there is no locking, local transaction
@@ -467,7 +467,7 @@ mnesia:add_table_index(person, age)</code>
for normal <c>mnesia:dirty_*</c> operations, the operations
are performed semi-asynchronously. For details, see
<c>mnesia:activity/4</c> and the User's Guide.</p>
- <p>The <c>Mnesia</c> tables can be manipulated without
+ <p>The Mnesia tables can be manipulated without
using transactions. This has some serious disadvantages, but
is considerably faster, as the transaction manager is not
involved and no locks are set. A dirty operation does,
@@ -480,7 +480,7 @@ mnesia:add_table_index(person, age)</code>
read records dirty than within a transaction.</p>
<p>Depending on the application, it can be a good idea to use
the dirty functions for certain operations. Almost all
- <c>Mnesia</c> functions that can be called within
+ Mnesia functions that can be called within
transactions have a dirty equivalent, which is much more
efficient.</p>
<p>However, notice that there is a risk that the database can
@@ -497,7 +497,7 @@ mnesia:add_table_index(person, age)</code>
<fsummary>Backs up all tables in the database.</fsummary>
<desc>
<marker id="backup"></marker>
- <p>Activates a new checkpoint covering all <c>Mnesia</c> tables,
+ <p>Activates a new checkpoint covering all Mnesia tables,
including the schema, with maximum degree of redundancy, and
performs a backup using <c>backup_checkpoint/2/3</c>. The
default value of the backup callback module <c>BackupMod</c>
@@ -529,16 +529,16 @@ mnesia:add_table_index(person, age)</code>
<taglist>
<tag><c>extra_db_nodes</c></tag>
<item>
- <p><c>Value</c> is a list of nodes that <c>Mnesia</c>
+ <p><c>Value</c> is a list of nodes that Mnesia
is to try to connect to. <c>ReturnValue</c> is those
- nodes in <c>Value</c> that <c>Mnesia</c> is connected
+ nodes in <c>Value</c> that Mnesia is connected
to.</p>
<p>Notice that this function must only be used to connect
to newly started RAM nodes (N.D.R.S.N.) with an empty
schema. If, for example, this function is used after
the network has been partitioned, it can lead to
inconsistent tables.</p>
- <p>Notice that <c>Mnesia</c> can be connected to other
+ <p>Notice that Mnesia can be connected to other
nodes than those returned in <c>ReturnValue</c>.</p>
</item>
<tag><c>dc_dump_limit</c></tag>
@@ -548,7 +548,7 @@ mnesia:add_table_index(person, age)</code>
Configuration Parameters</seealso>. <c>ReturnValue</c>
is the new value. Notice that this configuration
parameter is not persistent. It is lost when
- <c>Mnesia</c> has stopped.</p>
+ Mnesia has stopped.</p>
</item>
</taglist>
</desc>
@@ -562,9 +562,9 @@ mnesia:add_table_index(person, age)</code>
<c>read_write</c> but it can also be set to the atom
<c>read_only</c>. If <c>AccessMode</c> is set to
<c>read_only</c>, updates to the table cannot be
- performed. At startup, <c>Mnesia</c> always loads
+ performed. At startup, Mnesia always loads
<c>read_only</c> tables locally regardless of when and if
- <c>Mnesia</c> is terminated on other nodes.</p>
+ Mnesia is terminated on other nodes.</p>
</desc>
</func>
<func>
@@ -620,13 +620,13 @@ mnesia:change_table_copy_type(person, node(), disc_copies)</code>
<desc>
<marker id="create_schema"></marker>
<p>Creates a new database on disc. Various files are
- created in the local <c>Mnesia</c> directory of each node.
+ created in the local Mnesia directory of each node.
Notice that the directory must be unique for each node.
Two nodes must never share the same directory. If possible,
use a local disc device to improve performance.</p>
<p><c>mnesia:create_schema/1</c> fails if any of the
Erlang nodes given as <c>DiscNodes</c> are not alive, if
- <c>Mnesia</c> is running on any of the nodes, or if any
+ Mnesia is running on any of the nodes, or if any
of the nodes already have a schema. Use
<c>mnesia:delete_schema/1</c> to get rid of old faulty
schemas.</p>
@@ -638,10 +638,10 @@ mnesia:change_table_copy_type(person, node(), disc_copies)</code>
</func>
<func>
<name>create_table(Name, TabDef) -> {atomic, ok} | {aborted, Reason}</name>
- <fsummary>Creates a <c>Mnesia</c> table called <c>Name</c>with properties as described by argument <c>TabDef</c>.</fsummary>
+ <fsummary>Creates a Mnesia table called <c>Name</c>with properties as described by argument <c>TabDef</c>.</fsummary>
<desc>
<marker id="create_table"></marker>
- <p>Creates a <c>Mnesia</c> table called
+ <p>Creates a Mnesia table called
<c>Name</c> according to argument <c>TabDef</c>. This
list must be a list of <c>{Item, Value}</c> tuples,
where the following values are allowed:</p>
@@ -652,8 +652,8 @@ mnesia:change_table_copy_type(person, node(), disc_copies)</code>
set to the atom <c>read_only</c>. If <c>AccessMode</c>
is set to <c>read_only</c>, updates to the table
cannot be performed.</p>
- <p>At startup, <c>Mnesia</c> always loads <c>read_only</c>
- table locally regardless of when and if <c>Mnesia</c> is
+ <p>At startup, Mnesia always loads <c>read_only</c>
+ table locally regardless of when and if Mnesia is
terminated on other nodes. This argument returns the
access mode of the table. The access mode can be
<c>read_only</c> or <c>read_write</c>.</p>
@@ -693,7 +693,7 @@ mnesia:change_table_copy_type(person, node(), disc_copies)</code>
<item>
<p><c>{index, Intlist}</c>, where
<c>Intlist</c> is a list of attribute names (atoms) or
- record fields for which <c>Mnesia</c> is to build and
+ record fields for which Mnesia is to build and
maintain an extra index table. The <c>qlc</c> query
compiler <em>may</em> be able to optimize queries
if there are indexes available.</p>
@@ -735,10 +735,10 @@ mnesia:change_table_copy_type(person, node(), disc_copies)</code>
<c>mnesia:create_table/2</c>, the table is immediately
accessible by SNMP. Therefore applications that use
SNMP to manipulate and control the system can be
- designed easily, since <c>Mnesia</c> provides a
+ designed easily, since Mnesia provides a
direct mapping between the logical tables that make up
an SNMP control application and the physical data that
- makes up a <c>Mnesia</c> table.</p>
+ makes up a Mnesia table.</p>
</item>
<item>
<p><c>{storage_properties, [{Backend, Properties}]</c>
@@ -746,7 +746,7 @@ mnesia:change_table_copy_type(person, node(), disc_copies)</code>
<c>Backend</c> can currently be <c>ets</c> or <c>dets</c>.
<c>Properties</c> is a list of options sent to the
back end storage during table creation. <c>Properties</c>
- cannot contain properties already used by <c>Mnesia</c>,
+ cannot contain properties already used by Mnesia,
such as <c>type</c> or <c>named_table</c>.</p>
<p>For example:</p>
<code type="none">
@@ -776,7 +776,7 @@ mnesia:create_table(table, [{ram_copies, [node()]}, {disc_only_copies, nodes()},
mnesia:create_table(person,
[{ram_copies, [N1, N2]},
{attributes, record_info(fields, person)}]).</code>
- <p>If it is required that <c>Mnesia</c> must build and
+ <p>If it is required that Mnesia must build and
maintain an extra index table on attribute <c>address</c>
of all the <c>person</c> records that are inserted in the
table, the following code would be issued:</p>
@@ -819,8 +819,8 @@ mnesia:create_table(person,
When the last replica is deleted with this
function, the table disappears entirely.</p>
<p>This function can also be used to delete a replica of
- the table named <c>schema</c>. The <c>Mnesia</c> node is
- then removed. Notice that <c>Mnesia</c> must be
+ the table named <c>schema</c>. The Mnesia node is
+ then removed. Notice that Mnesia must be
stopped on the node first.</p>
</desc>
</func>
@@ -891,9 +891,9 @@ mnesia:create_table(person,
<c>mnesia:create_schema/1</c>.
<c>mnesia:delete_schema/1</c> fails if any of the Erlang
nodes given as <c>DiscNodes</c> are not alive, or if
- <c>Mnesia</c> is running on any of the nodes.</p>
+ Mnesia is running on any of the nodes.</p>
<p>After the database is deleted, it can still be possible
- to start <c>Mnesia</c> as a disc-less node. This depends
+ to start Mnesia as a disc-less node. This depends
on how configuration parameter <c>schema_location</c> is
set.</p>
<warning>
@@ -1100,7 +1100,7 @@ mnesia:create_table(person,
<name>dirty_update_counter(Tab, Key, Incr) -> NewVal | exit({aborted, Reason})</name>
<fsummary>Dirty update of a counter record.</fsummary>
<desc>
- <p><c>Mnesia</c> has no special counter records. However,
+ <p>Mnesia has no special counter records. However,
records of the form <c>{Tab, Key, Integer}</c> can be used
as (possibly disc-resident) counters when <c>Tab</c> is a
<c>set</c>. This function updates a counter with a positive
@@ -1147,7 +1147,7 @@ mnesia:create_table(person,
<desc>
<marker id="dump_log"></marker>
<p>Performs a user-initiated dump of the local log file.
- This is usually not necessary, as <c>Mnesia</c> by default
+ This is usually not necessary, as Mnesia by default
manages this automatically. See configuration parameters
<seealso marker="#dump_log_time_threshold">dump_log_time_threshold</seealso>
and
@@ -1172,7 +1172,7 @@ mnesia:create_table(person,
<fsummary>Dumps local tables into a text file.</fsummary>
<desc>
<marker id="dump_to_textfile"></marker>
- <p>Dumps all local tables of a <c>Mnesia</c> system into a
+ <p>Dumps all local tables of a Mnesia system into a
text file, which can be edited (by a normal text editor)
and then be reloaded with
<c>mnesia:load_textfile/1</c>. Only use this function for
@@ -1182,10 +1182,10 @@ mnesia:create_table(person,
</func>
<func>
<name>error_description(Error) -> String</name>
- <fsummary>Returns a string describing a particular <c>Mnesia</c> error.</fsummary>
+ <fsummary>Returns a string describing a particular Mnesia error.</fsummary>
<desc>
<marker id="error_description"></marker>
- <p>All <c>Mnesia</c> transactions, including all the schema
+ <p>All Mnesia transactions, including all the schema
update functions, either return value <c>{atomic, Val}</c>
or the tuple <c>{aborted, Reason}</c>. <c>Reason</c> can
be either of the atoms in the following list. The
@@ -1264,8 +1264,8 @@ mnesia:create_table(person,
<desc>
<marker id="ets"></marker>
<p>Calls the <c>Fun</c> in a raw context that is not protected by
- a transaction. The <c>Mnesia</c> function call is performed in
- the <c>Fun</c> and performed directly on the local <c>ets</c>
+ a transaction. The Mnesia function call is performed in
+ the <c>Fun</c> and performed directly on the local ETS
tables on the assumption that the local storage type is
<c>ram_copies</c> and the tables are not replicated to other
nodes. Subscriptions are not triggered and checkpoints are
@@ -1321,13 +1321,13 @@ mnesia:create_table(person,
<fsummary>Forces a table to be loaded into the system.</fsummary>
<desc>
<marker id="force_load_table"></marker>
- <p>The <c>Mnesia</c> algorithm for table load can lead to a
+ <p>The Mnesia algorithm for table load can lead to a
situation where a table cannot be loaded. This situation
- occurs when a node is started and <c>Mnesia</c> concludes, or
+ occurs when a node is started and Mnesia concludes, or
suspects, that another copy of the table was active after
this local copy became inactive because of a system crash.</p>
<p>If this situation is not acceptable, this function can be
- used to override the strategy of the <c>Mnesia</c> table
+ used to override the strategy of the Mnesia table
load algorithm. This can lead to a situation where some
transaction effects are lost with an inconsistent database as
result, but for some applications high availability is more
@@ -1402,9 +1402,9 @@ mnesia:create_table(person,
<desc>
<marker id="info"></marker>
<p>Prints system information on the terminal.
- This function can be used even if <c>Mnesia</c> is not
+ This function can be used even if Mnesia is not
started. However, more information is displayed if
- <c>Mnesia</c> is started.</p>
+ Mnesia is started.</p>
</desc>
</func>
<func>
@@ -1431,7 +1431,7 @@ mnesia:create_table(person,
<p>Installs a backup as fallback. The fallback is used to
restore the database at the next startup. Installation of
fallbacks requires Erlang to be operational on all the
- involved nodes, but it does not matter if <c>Mnesia</c>
+ involved nodes, but it does not matter if Mnesia
is running or not. The installation of the fallback fails
if the local node is not one of the disc-resident nodes
in the backup.</p>
@@ -1465,14 +1465,14 @@ mnesia:create_table(person,
<p><c>{mnesia_dir, AlternateDir}</c>.
This argument is only valid if the scope of the
installation is <c>local</c>. Normally the installation
- of a fallback is targeted to the <c>Mnesia</c> directory,
+ of a fallback is targeted to the Mnesia directory,
as configured with configuration parameter
<c>-mnesia dir</c>. But by explicitly supplying an
<c>AlternateDir</c>, the fallback is installed there
- regardless of the <c>Mnesia</c> directory configuration
+ regardless of the Mnesia directory configuration
parameter setting. After installation of a fallback on
- an alternative <c>Mnesia</c> directory, that directory
- is fully prepared for use as an active <c>Mnesia</c>
+ an alternative Mnesia directory, that directory
+ is fully prepared for use as an active Mnesia
directory.</p>
<p>This is a dangerous feature that must be
used with care. By unintentional mixing of directories,
@@ -1509,7 +1509,7 @@ mnesia:create_table(person,
<marker id="load_textfile"></marker>
<p>Loads a series of definitions and data found in the
text file (generated with <c>mnesia:dump_to_textfile/1</c>)
- into <c>Mnesia</c>. This function also starts <c>Mnesia</c>
+ into Mnesia. This function also starts Mnesia
and possibly creates a new schema. This function is
intended for educational purposes only. It is recommended
to use other functions to deal with real backups.</p>
@@ -1558,7 +1558,7 @@ mnesia:create_table(person,
</taglist>
<p>Conflicting lock requests are automatically queued if there
is no risk of a deadlock. Otherwise the transaction must be
- terminated and executed again. <c>Mnesia</c> does this
+ terminated and executed again. Mnesia does this
automatically as long as the upper limit of the maximum
<c>retries</c> is not reached. For details, see
<c>mnesia:transaction/3</c>.</p>
@@ -1726,19 +1726,19 @@ mnesia:create_table(person,
</func>
<func>
<name>report_event(Event) -> ok</name>
- <fsummary>Reports a user event to the <c>Mnesia</c> event handler.</fsummary>
+ <fsummary>Reports a user event to the Mnesia event handler.</fsummary>
<desc>
<marker id="report_event"></marker>
- <p>When tracing a system of <c>Mnesia</c> applications it is
- useful to be able to interleave <c>Mnesia</c> own events with
+ <p>When tracing a system of Mnesia applications it is
+ useful to be able to interleave Mnesia own events with
application-related events that give information about the
application context.</p>
<p>Whenever the application begins a
- new and demanding <c>Mnesia</c> task, or if it enters a new
+ new and demanding Mnesia task, or if it enters a new
interesting phase in its execution, it can be a good idea to
use <c>mnesia:report_event/1</c>. <c>Event</c> can be
any term and generates a <c>{mnesia_user, Event}</c> event
- for any processes that subscribe to <c>Mnesia</c> system
+ for any processes that subscribe to Mnesia system
events.</p>
</desc>
</func>
@@ -1748,7 +1748,7 @@ mnesia:create_table(person,
<desc>
<marker id="restore"></marker>
<p>With this function, tables can be restored online from a
- backup without restarting <c>Mnesia</c>.
+ backup without restarting Mnesia.
<c>Opaque</c> is forwarded to the backup module.
<c>Args</c> is a list of the following tuples:</p>
<list type="bulleted">
@@ -1873,7 +1873,7 @@ mnesia:create_table(person,
<p>For a complete description of <c>select</c>, see the
<seealso marker="erts:index">ERTS</seealso> User's Guide and the
<seealso marker="stdlib:ets">ets</seealso> manual page in
- <c>STDLIB</c>.</p>
+ STDLIB.</p>
<p>For example, to find the names of all male persons older
than 30 in table <c>Tab</c>:</p>
<code type="none">
@@ -1920,10 +1920,10 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</func>
<func>
<name>set_debug_level(Level) -> OldLevel</name>
- <fsummary>Changes the internal debug level of <c>Mnesia</c>.</fsummary>
+ <fsummary>Changes the internal debug level of Mnesia.</fsummary>
<desc>
<marker id="set_debug_level"></marker>
- <p>Changes the internal debug level of <c>Mnesia</c>.
+ <p>Changes the internal debug level of Mnesia.
For details, see
<seealso marker="#configuration_parameters">Section
Configuration Parameters</seealso>.</p>
@@ -1934,7 +1934,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
<fsummary>Sets the master nodes for all tables.</fsummary>
<desc>
<marker id="set_master_nodes_1"></marker>
- <p>For each table <c>Mnesia</c> determines its replica nodes
+ <p>For each table Mnesia determines its replica nodes
(<c>TabNodes</c>) and starts
<c>mnesia:set_master_nodes(Tab, TabMasterNodes)</c>. where
<c>TabMasterNodes</c> is the intersection of
@@ -1952,16 +1952,16 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
that can have caused an inconsistent database, it can use the
function <c>mnesia:set_master_nodes(Tab, MasterNodes)</c> to
define from which nodes each table is to be loaded.
- At startup, the <c>Mnesia</c> normal table load algorithm is
+ At startup, the Mnesia normal table load algorithm is
bypassed and the table is loaded from one of the master nodes
- defined for the table, regardless of when and if <c>Mnesia</c>
+ defined for the table, regardless of when and if Mnesia
terminated on other nodes. <c>MasterNodes</c> can only
contain nodes where the table has a replica. If the
<c>MasterNodes</c> list is empty, the master node recovery
mechanism for the particular table is reset, and the
normal load mechanism is used at the next restart.</p>
<p>The master node setting is always local. It can be
- changed regardless if <c>Mnesia</c> is started or not.</p>
+ changed regardless if Mnesia is started or not.</p>
<p>The database can also become inconsistent if
configuration parameter <c>max_wait_for_decision</c> is used
or if <c>mnesia:force_load_table/1</c> is used.</p>
@@ -1976,7 +1976,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</func>
<func>
<name>snmp_get_mnesia_key(Tab, RowIndex) -> {ok, Key} | undefined</name>
- <fsummary>Gets the corresponding <c>Mnesia</c> key from an SNMP index.</fsummary>
+ <fsummary>Gets the corresponding Mnesia key from an SNMP index.</fsummary>
<type>
<v>Tab ::= atom()</v>
<v>RowIndex ::= [integer()]</v>
@@ -1984,7 +1984,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
<v>key() ::= integer() | string() | [integer()]</v>
</type>
<desc>
- <p>Transforms an SNMP index to the corresponding <c>Mnesia</c>
+ <p>Transforms an SNMP index to the corresponding Mnesia
key. If the SNMP table has multiple keys, the key is a tuple
of the key columns.</p>
</desc>
@@ -2020,7 +2020,7 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</func>
<func>
<name>snmp_open_table(Tab, SnmpStruct) -> {aborted, R} | {atomic, ok}</name>
- <fsummary>Organizes a <c>Mnesia</c> table as an SNMP table.</fsummary>
+ <fsummary>Organizes a Mnesia table as an SNMP table.</fsummary>
<type>
<v>Tab ::= atom()</v>
<v>SnmpStruct ::= [{key, type()}]</v>
@@ -2029,14 +2029,14 @@ mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),</code>
</type>
<desc>
<p>A direct one-to-one mapping can be established between
- <c>Mnesia</c> tables and SNMP tables. Many telecommunication
+ Mnesia tables and SNMP tables. Many telecommunication
applications are controlled and monitored by the SNMP
- protocol. This connection between <c>Mnesia</c> and SNMP
+ protocol. This connection between Mnesia and SNMP
makes it simple and convenient to achieve this mapping.</p>
<p>Argument <c>SnmpStruct</c> is a list of SNMP
information. Currently, the only information needed is
information about the key types in the table. Multiple
- keys cannot be handled in <c>Mnesia</c>, but many SNMP
+ keys cannot be handled in Mnesia, but many SNMP
tables have multiple keys. Therefore, the following
convention is used: if a table has multiple keys, these must
always be stored as a tuple of the keys. Information about
@@ -2069,39 +2069,39 @@ mnesia:create_table(employee,
<p>When a table is SNMP ordered, modifications are more
expensive than usual, O(logN). Also, more memory is used.</p>
<p>Notice that only the lexicographical SNMP ordering is
- implemented in <c>Mnesia</c>, not the actual SNMP monitoring.</p>
+ implemented in Mnesia, not the actual SNMP monitoring.</p>
</desc>
</func>
<func>
<name>start() -> ok | {error, Reason}</name>
- <fsummary>Starts a local <c>Mnesia</c> system.</fsummary>
+ <fsummary>Starts a local Mnesia system.</fsummary>
<desc>
<marker id="start"></marker>
- <p>The startup procedure for a set of <c>Mnesia</c> nodes is a
- fairly complicated operation. A <c>Mnesia</c> system consists
- of a set of nodes, with <c>Mnesia</c> started locally on all
+ <p>The startup procedure for a set of Mnesia nodes is a
+ fairly complicated operation. A Mnesia system consists
+ of a set of nodes, with Mnesia started locally on all
participating nodes. Normally, each node has a directory where
- all the <c>Mnesia</c> files are written. This directory is
- referred to as the <c>Mnesia</c> directory. <c>Mnesia</c> can
+ all the Mnesia files are written. This directory is
+ referred to as the Mnesia directory. Mnesia can
also be started on disc-less nodes. For more information
about disc-less nodes, see <c>mnesia:create_schema/1</c>
and the User's Guide.</p>
- <p>The set of nodes that makes up a <c>Mnesia</c> system is kept
- in a schema. <c>Mnesia</c> nodes can be added to or removed
+ <p>The set of nodes that makes up a Mnesia system is kept
+ in a schema. Mnesia nodes can be added to or removed
from the schema. The initial schema is normally created on
disc with the function <c>mnesia:create_schema/1</c>. On
disc-less nodes, a tiny default schema is generated each time
- <c>Mnesia</c> is started. During the startup procedure,
- <c>Mnesia</c> exchanges schema information between the nodes
+ Mnesia is started. During the startup procedure,
+ Mnesia exchanges schema information between the nodes
to verify that the table definitions are compatible.</p>
<p>Each schema has a unique cookie, which can be regarded as a
unique schema identifier. The cookie must be the same on all
- nodes where <c>Mnesia</c> is supposed to run. For details,
+ nodes where Mnesia is supposed to run. For details,
see the User's Guide.</p>
- <p>The schema file and all other files that <c>Mnesia</c>
- needs are kept in the <c>Mnesia</c> directory. The
+ <p>The schema file and all other files that Mnesia
+ needs are kept in the Mnesia directory. The
command-line option <c>-mnesia dir Dir</c> can be used to
- specify the location of this directory to the <c>Mnesia</c>
+ specify the location of this directory to the Mnesia
system. If no such command-line option is found, the name
of the directory defaults to <c>Mnesia.Node</c>.</p>
<p><c>application:start(mnesia)</c> can also be used.</p>
@@ -2109,10 +2109,10 @@ mnesia:create_table(employee,
</func>
<func>
<name>stop() -> stopped</name>
- <fsummary>Stops <c>Mnesia</c> locally.</fsummary>
+ <fsummary>Stops Mnesia locally.</fsummary>
<desc>
<marker id="stop"></marker>
- <p>Stops <c>Mnesia</c> locally on the current node.</p>
+ <p>Stops Mnesia locally on the current node.</p>
<p><c>application:stop(mnesia)</c> can also be used.</p>
</desc>
</func>
@@ -2132,7 +2132,7 @@ mnesia:create_table(employee,
<desc>
<marker id="sync_dirty"></marker>
<p>Calls the <c>Fun</c> in a context that is not protected by
- a transaction. The <c>Mnesia</c> function calls performed in
+ a transaction. The Mnesia function calls performed in
the <c>Fun</c> are mapped to the corresponding dirty functions.
It is performed in almost the same context as
<c>mnesia:async_dirty/1,2</c>. The difference is that the
@@ -2167,10 +2167,10 @@ mnesia:create_table(employee,
</func>
<func>
<name>system_info(InfoKey) -> Info | exit({aborted, Reason})</name>
- <fsummary>Returns information about the <c>Mnesia</c> system.</fsummary>
+ <fsummary>Returns information about the Mnesia system.</fsummary>
<desc>
<marker id="system_info"></marker>
- <p>Returns information about the <c>Mnesia</c> system, such as
+ <p>Returns information about the Mnesia system, such as
transaction statistics, <c>db_nodes</c>, and configuration
parameters. The valid keys are as follows:</p>
<list type="bulleted">
@@ -2188,7 +2188,7 @@ mnesia:create_table(employee,
</item>
<item>
<p><c>auto_repair</c>. Returns <c>true</c> or <c>false</c>
- to indicate if <c>Mnesia</c> is configured to start the
+ to indicate if Mnesia is configured to start the
auto-repair facility on corrupted disc files.</p>
</item>
<item>
@@ -2209,20 +2209,20 @@ mnesia:create_table(employee,
in the list of nodes if they explicitly have been added
to the schema, for example, with
<c>mnesia:add_table_copy/3</c>. The function can be
- started even if <c>Mnesia</c> is not yet running.</p>
+ started even if Mnesia is not yet running.</p>
</item>
<item>
<p><c>debug</c>. Returns the current debug level of
- <c>Mnesia</c>.</p>
+ Mnesia.</p>
</item>
<item>
- <p><c>directory</c>. Returns the name of the <c>Mnesia</c>
- directory. It can be called even if <c>Mnesia</c> is
+ <p><c>directory</c>. Returns the name of the Mnesia
+ directory. It can be called even if Mnesia is
not yet running.</p>
</item>
<item>
<p><c>dump_log_load_regulation</c>. Returns a boolean that
- tells if <c>Mnesia</c> is configured to regulate the
+ tells if Mnesia is configured to regulate the
dumper process load.</p>
<p>This feature is temporary and will be removed in future
releases.</p>
@@ -2233,9 +2233,9 @@ mnesia:create_table(employee,
</item>
<item>
<p><c>dump_log_update_in_place</c>. Returns a boolean that
- tells if <c>Mnesia</c> is configured to perform the
- updates in the <c>dets</c> files directly, or if the
- updates are to be performed in a copy of the <c>dets</c>
+ tells if Mnesia is configured to perform the
+ updates in the Dets files directly, or if the
+ updates are to be performed in a copy of the Dets
files.</p>
</item>
<item>
@@ -2253,13 +2253,13 @@ mnesia:create_table(employee,
</item>
<item>
<p><c>held_locks</c>. Returns a list of all
- locks held by the local <c>Mnesia</c> lock manager.</p>
+ locks held by the local Mnesia lock manager.</p>
</item>
<item>
<p><c>is_running</c>. Returns <c>yes</c> or <c>no</c> to
- indicate if <c>Mnesia</c> is running. It can
+ indicate if Mnesia is running. It can
also return <c>starting</c> or <c>stopping</c>. Can be
- called even if <c>Mnesia</c> is not yet running.</p>
+ called even if Mnesia is not yet running.</p>
</item>
<item>
<p><c>local_tables</c>. Returns a list
@@ -2272,7 +2272,7 @@ mnesia:create_table(employee,
</item>
<item>
<p><c>log_version</c>. Returns the version
- number of the <c>Mnesia</c> transaction log format.</p>
+ number of the Mnesia transaction log format.</p>
</item>
<item>
<p><c>master_node_tables</c>. Returns a
@@ -2280,25 +2280,25 @@ mnesia:create_table(employee,
</item>
<item>
<p><c>protocol_version</c>. Returns the version number of
- the <c>Mnesia</c> inter-process communication protocol.</p>
+ the Mnesia inter-process communication protocol.</p>
</item>
<item>
<p><c>running_db_nodes</c>. Returns a list of nodes where
- <c>Mnesia</c> currently is running. This function can be
- called even if <c>Mnesia</c> is not yet running, but it
+ Mnesia currently is running. This function can be
+ called even if Mnesia is not yet running, but it
then has slightly different semantics.</p>
- <p>If <c>Mnesia</c> is down on the local node, the function
+ <p>If Mnesia is down on the local node, the function
returns those other <c>db_nodes</c> and
<c>extra_db_nodes</c> that for the moment are
operational.</p>
- <p>If <c>Mnesia</c> is started, the function returns
- those nodes that <c>Mnesia</c> on the local node is fully
- connected to. Only those nodes that <c>Mnesia</c> has
+ <p>If Mnesia is started, the function returns
+ those nodes that Mnesia on the local node is fully
+ connected to. Only those nodes that Mnesia has
exchanged schema information with are included as
<c>running_db_nodes</c>. After the merge of schemas, the
- local <c>Mnesia</c> system is fully operable and
+ local Mnesia system is fully operable and
applications can perform access of remote replicas.
- Before the schema merge, <c>Mnesia</c> only operates
+ Before the schema merge, Mnesia only operates
locally. Sometimes there are more nodes included in the
<c>running_db_nodes</c> list than all <c>db_nodes</c>
and <c>extra_db_nodes</c> together.</p>
@@ -2322,17 +2322,17 @@ mnesia:create_table(employee,
<item>
<p><c>transaction_failures</c>. Returns a
number that indicates how many transactions have
- failed since <c>Mnesia</c> was started.</p>
+ failed since Mnesia was started.</p>
</item>
<item>
<p><c>transaction_commits</c>. Returns a
number that indicates how many transactions have
- terminated successfully since <c>Mnesia</c> was started.</p>
+ terminated successfully since Mnesia was started.</p>
</item>
<item>
<p><c>transaction_restarts</c>. Returns a
number that indicates how many transactions have been
- restarted since <c>Mnesia</c> was started.</p>
+ restarted since Mnesia was started.</p>
</item>
<item>
<p><c>transaction_log_writes</c>.
@@ -2342,12 +2342,12 @@ mnesia:create_table(employee,
</item>
<item>
<p><c>use_dir</c>. Returns a boolean that indicates if
- the <c>Mnesia</c> directory is used or not. Can be
- started even if <c>Mnesia</c> is not yet running.</p>
+ the Mnesia directory is used or not. Can be
+ started even if Mnesia is not yet running.</p>
</item>
<item>
<p><c>version</c>. Returns the current
- version number of <c>Mnesia</c>.</p>
+ version number of Mnesia.</p>
</item>
</list>
</desc>
@@ -2359,13 +2359,13 @@ mnesia:create_table(employee,
<marker id="table"></marker>
<p>Returns a Query List Comprehension (QLC) query handle,
see the <seealso marker="stdlib:qlc">qlc(3)</seealso>
- manual page in <c>STDLIB</c>. The module <c>qlc</c>
- implements a query language that can use <c>Mnesia</c>
+ manual page in STDLIB. The module <c>qlc</c>
+ implements a query language that can use Mnesia
tables as sources of data. Calling
<c>mnesia:table/1,2</c> is the means to make the
<c>mnesia</c> table <c>Tab</c> usable to QLC.</p>
- <p><c>Option</c> can contain <c>Mnesia</c>
- options or QLC options. <c>Mnesia</c> recognizes the
+ <p><c>Option</c> can contain Mnesia
+ options or QLC options. Mnesia recognizes the
following options (any other option is forwarded to
QLC).</p>
<list type="bulleted">
@@ -2374,7 +2374,7 @@ mnesia:create_table(employee,
</item>
<item><c>{n_objects,Number}</c>, where <c>n_objects</c>
specifies (roughly) the number of objects returned
- from <c>Mnesia</c> to QLC. Queries to remote tables
+ from Mnesia to QLC. Queries to remote tables
can need a larger chunk to reduce network overhead.
By default, <c>100</c> objects at a time are returned.
</item>
@@ -2413,7 +2413,7 @@ mnesia:create_table(employee,
<desc>
<marker id="table_info"></marker>
<p>The <c>table_info/2</c> function takes two arguments.
- The first is the name of a <c>Mnesia</c> table.
+ The first is the name of a Mnesia table.
The second is one of the following keys:</p>
<list type="bulleted">
<item>
@@ -2465,7 +2465,7 @@ mnesia:create_table(employee,
</item>
<item>
<p><c>load_node</c>. Returns the name of
- the node that <c>Mnesia</c> loaded the table from. The
+ the node that Mnesia loaded the table from. The
structure of the returned value is unspecified, but
can be useful for debugging purposes.</p>
</item>
@@ -2476,7 +2476,7 @@ mnesia:create_table(employee,
</item>
<item>
<p><c>load_reason</c>. Returns the
- reason of why <c>Mnesia</c> decided to load the table.
+ reason of why Mnesia decided to load the table.
The structure of the returned value is unspecified, but
can be useful for debugging purposes.</p>
</item>
@@ -2620,7 +2620,7 @@ raise(Name, Amount) ->
several processes running on different nodes can concurrently
execute the function <c>raise/2</c> without interfering
with each other.</p>
- <p>Since <c>Mnesia</c> detects deadlocks, a transaction can be
+ <p>Since Mnesia detects deadlocks, a transaction can be
restarted any number of times. This function attempts a
restart as specified in <c>Retries</c>. <c>Retries</c> must
be an integer greater than 0 or the atom <c>infinity</c>.
@@ -2643,7 +2643,7 @@ raise(Name, Amount) ->
<p><c>NewAttributeList</c> and <c>NewRecordName</c>
specify the attributes and the new record type of the
converted table. Table name always remains unchanged. If
- <c>record_name</c> is changed, only the <c>Mnesia</c>
+ <c>record_name</c> is changed, only the Mnesia
functions that use table identifiers work, for example,
<c>mnesia:write/3</c> works, but not <c>mnesia:write/1</c>.</p>
</desc>
@@ -2706,7 +2706,7 @@ raise(Name, Amount) ->
distributed operation that is either performed on all
nodes with disc resident schema, or none. Uninstallation of
fallbacks requires Erlang to be operational on all
- involved nodes, but it does not matter if <c>Mnesia</c> is
+ involved nodes, but it does not matter if Mnesia is
running or not. Which nodes that are considered as
disc-resident nodes is determined from the schema
information in the local fallback.</p>
@@ -2792,28 +2792,28 @@ raise(Name, Amount) ->
<section>
<title>Configuration Parameters</title>
<marker id="configuration_parameters"></marker>
- <p><c>Mnesia</c> reads the following application configuration
+ <p>Mnesia reads the following application configuration
parameters:</p>
<list type="bulleted">
<item>
<p><c>-mnesia access_module Module</c>. The name of the
- <c>Mnesia</c> activity access callback module. Default is
+ Mnesia activity access callback module. Default is
<c>mnesia</c>.</p>
</item>
<item>
<p><c>-mnesia auto_repair true | false</c>. This flag
- controls if <c>Mnesia</c> automatically tries to repair
+ controls if Mnesia automatically tries to repair
files that have not been properly closed. Default is
<c>true</c>.</p>
</item>
<item>
<p><c>-mnesia backup_module Module</c>. The name of the
- <c>Mnesia</c> backup callback module. Default is
+ Mnesia backup callback module. Default is
<c>mnesia_backup</c>.</p>
</item>
<item>
<p><c>-mnesia debug Level</c>. Controls the debug level
- of <c>Mnesia</c>. The possible values are as follows:</p>
+ of Mnesia. The possible values are as follows:</p>
<taglist>
<tag><c>none</c></tag>
<item>
@@ -2825,7 +2825,7 @@ raise(Name, Amount) ->
events generate <c>{mnesia_info, Format, Args}</c>
system events. Processes can subscribe to these events with
<c>mnesia:subscribe/1</c>. The events are always sent to
- the <c>Mnesia</c> event handler.</p>
+ the Mnesia event handler.</p>
</item>
<tag><c>debug</c></tag>
<item>
@@ -2834,15 +2834,15 @@ raise(Name, Amount) ->
<c>{mnesia_info, Format, Args}</c> system events.
Processes can subscribe to these events with
<c>mnesia:subscribe/1</c>. The events are always sent to
- the <c>Mnesia</c> event handler. On this debug level,
- the <c>Mnesia</c> event handler starts subscribing to
+ the Mnesia event handler. On this debug level,
+ the Mnesia event handler starts subscribing to
updates in the schema table.</p>
</item>
<tag><c>trace</c></tag>
<item>
<p>Activates all events at the debug level. On this
- level, the <c>Mnesia</c> event handler starts subscribing
- to updates on all <c>Mnesia</c> tables. This level is
+ level, the Mnesia event handler starts subscribing
+ to updates on all Mnesia tables. This level is
intended only for debugging small toy systems, as many
large events can be generated.</p>
</item>
@@ -2856,7 +2856,7 @@ raise(Name, Amount) ->
</item>
<item>
<p><c>-mnesia core_dir Directory</c>. The name of the
- directory where <c>Mnesia</c> core files is stored, or
+ directory where Mnesia core files is stored, or
false. Setting it implies that also RAM-only nodes
generate a core file if a crash occurs.</p>
</item>
@@ -2870,9 +2870,9 @@ raise(Name, Amount) ->
</item>
<item>
<p><c>-mnesia dir Directory</c>. The name of the directory
- where all <c>Mnesia</c> data is stored. The directory name
+ where all Mnesia data is stored. The directory name
must be unique for the current node. Two nodes must never
- share the the same <c>Mnesia</c> directory. The results
+ share the the same Mnesia directory. The results
are unpredictable.</p>
</item>
<item>
@@ -2915,44 +2915,44 @@ raise(Name, Amount) ->
</item>
<item>
<p><c>-mnesia event_module Module</c>. The name of the
- <c>Mnesia</c> event handler callback module. Default is
+ Mnesia event handler callback module. Default is
<c>mnesia_event</c>.</p>
</item>
<item>
<p><c>-mnesia extra_db_nodes Nodes</c> specifies a list of
nodes, in addition to the ones found in the schema, with
- which <c>Mnesia</c> is also to establish contact. Default
+ which Mnesia is also to establish contact. Default
is <c>[]</c> (empty list).</p>
</item>
<item>
<p><c>-mnesia fallback_error_function {UserModule, UserFunc}</c>.
Specifies a user-supplied callback function, which is
- called if a fallback is installed and <c>Mnesia</c> goes
- down on another node. <c>Mnesia</c> calls the function
+ called if a fallback is installed and Mnesia goes
+ down on another node. Mnesia calls the function
with one argument, the name of the dying node, for example,
- <c>UserModule:UserFunc(DyingNode)</c>. <c>Mnesia</c> must
+ <c>UserModule:UserFunc(DyingNode)</c>. Mnesia must
be restarted, otherwise the database can be inconsistent.
- The default behavior is to terminate <c>Mnesia</c>.</p>
+ The default behavior is to terminate Mnesia.</p>
</item>
<item>
<p><c>-mnesia max_wait_for_decision Timeout</c>. Specifies
- how long <c>Mnesia</c> waits for other nodes to share their
+ how long Mnesia waits for other nodes to share their
knowledge about the outcome of an unclear transaction. By
default, <c>Timeout</c> is set to the atom <c>infinity</c>.
- This implies that if <c>Mnesia</c> upon startup detects
+ This implies that if Mnesia upon startup detects
a "heavyweight transaction" whose outcome is unclear, the
- local <c>Mnesia</c> waits until <c>Mnesia</c> is started
+ local Mnesia waits until Mnesia is started
on some (in the worst case all) of the other nodes that were
involved in the interrupted transaction. This is a rare
- situation, but if it occurs, <c>Mnesia</c> does not guess if
+ situation, but if it occurs, Mnesia does not guess if
the transaction on the other nodes was committed or
- terminated. <c>Mnesia</c> waits until it knows the outcome
+ terminated. Mnesia waits until it knows the outcome
and then acts accordingly.</p>
<p>If <c>Timeout</c> is set to an integer value in
- milliseconds, <c>Mnesia</c> forces "heavyweight transactions"
+ milliseconds, Mnesia forces "heavyweight transactions"
to be finished, even if the outcome of the transaction for
the moment is unclear. After <c>Timeout</c> milliseconds,
- <c>Mnesia</c> commits or terminates the transaction and
+ Mnesia commits or terminates the transaction and
continues with the startup. This can lead to a situation
where the transaction is committed on some nodes and
terminated on other nodes. If the transaction is a
@@ -2976,14 +2976,14 @@ raise(Name, Amount) ->
</item>
<item>
<p><c>-mnesia schema_location Loc</c>. Controls where
- <c>Mnesia</c> looks for its schema. Parameter
+ Mnesia looks for its schema. Parameter
<c>Loc</c> can be one of the following atoms:</p>
<taglist>
<tag><c>disc</c></tag>
<item>
<p>Mandatory disc. The schema is assumed to be located
- in the <c>Mnesia</c> directory. If the schema cannot
- be found, <c>Mnesia</c> refuses to start. This is the
+ in the Mnesia directory. If the schema cannot
+ be found, Mnesia refuses to start. This is the
old behavior.</p>
</item>
<tag><c>ram</c></tag>
@@ -3001,10 +3001,10 @@ raise(Name, Amount) ->
<tag><c>opt_disc</c></tag>
<item>
<p>Optional disc. The schema can reside on disc or in
- RAM. If the schema is found on disc, <c>Mnesia</c>
+ RAM. If the schema is found on disc, Mnesia
starts as a disc-based node and the storage type of
the schema table is <c>disc_copies</c>. If no schema is
- found on disc, <c>Mnesia</c> starts as a disc-less node
+ found on disc, Mnesia starts as a disc-less node
and the storage type of the schema table is
<c>ram_copies</c>. Default value for the application
parameter is <c>opt_disc</c>.</p>
@@ -3012,7 +3012,7 @@ raise(Name, Amount) ->
</taglist>
</item>
</list>
- <p>First, the <c>SASL</c> application parameters are checked,
+ <p>First, the SASL application parameters are checked,
then the command-line flags are checked, and finally, the
default value is chosen.</p>
</section>
diff --git a/lib/mnesia/doc/src/mnesia_frag_hash.xml b/lib/mnesia/doc/src/mnesia_frag_hash.xml
index 95f5f8aa07..51b32129b6 100644
--- a/lib/mnesia/doc/src/mnesia_frag_hash.xml
+++ b/lib/mnesia/doc/src/mnesia_frag_hash.xml
@@ -87,13 +87,13 @@
the new one.</p>
<p><c>NewState</c> is stored as <c>hash_state</c> among the
other <c>frag_properties</c>.</p>
- <p>As a part of the <c>add_frag</c> procedure, <c>Mnesia</c> iterates
+ <p>As a part of the <c>add_frag</c> procedure, Mnesia iterates
over all fragments corresponding to the <c>IterFrags</c> numbers
and starts <c>key_to_frag_number(NewState,RecordKey)</c> for
each record. If the new fragment differs from the old
fragment, the record is moved to the new fragment.</p>
<p>As the <c>add_frag</c> procedure is a part of a schema
- transaction, <c>Mnesia</c> acquires write locks on the
+ transaction, Mnesia acquires write locks on the
affected tables. That is, both the fragments corresponding
to <c>IterFrags</c> and those corresponding to
<c>AdditionalLockFrags</c>.</p>
@@ -112,7 +112,7 @@
<desc>
<p><c>NewState</c> is stored as <c>hash_state</c> among the
other <c>frag_properties</c>.</p>
- <p>As a part of the <c>del_frag</c> procedure, <c>Mnesia</c> iterates
+ <p>As a part of the <c>del_frag</c> procedure, Mnesia iterates
over all fragments corresponding to the <c>IterFrags</c> numbers
and starts <c>key_to_frag_number(NewState,RecordKey)</c> for
each record. If the new fragment differs from the old
@@ -120,7 +120,7 @@
<p>Notice that all records in the last fragment must be moved to
another fragment, as the entire fragment is deleted.</p>
<p>As the <c>del_frag</c> procedure is a part of a schema
- transaction, <c>Mnesia</c> acquires write locks on the
+ transaction, Mnesia acquires write locks on the
affected tables. That is, both the fragments corresponding
to <c>IterFrags</c> and those corresponding to
<c>AdditionalLockFrags</c>.</p>
@@ -134,7 +134,7 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Starts whenever <c>Mnesia</c> needs to determine
+ <p>Starts whenever Mnesia needs to determine
which fragment a certain record belongs to. It is typically
started at <c>read</c>, <c>write</c>, and <c>delete</c>.</p>
</desc>
@@ -149,7 +149,7 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>This function is called whenever <c>Mnesia</c> needs to determine
+ <p>This function is called whenever Mnesia needs to determine
which fragments that need to be searched for a <c>MatchSpec</c>.
It is typically called by <c>select</c> and
<c>match_object</c>.</p>
diff --git a/lib/mnesia/doc/src/mnesia_registry.xml b/lib/mnesia/doc/src/mnesia_registry.xml
index cd778ae072..a76f716981 100644
--- a/lib/mnesia/doc/src/mnesia_registry.xml
+++ b/lib/mnesia/doc/src/mnesia_registry.xml
@@ -38,20 +38,20 @@
<modulesummary>Dump support for registries in erl_interface.</modulesummary>
<description>
<p>This module is usually part of the <c>erl_interface</c>
- application, but is currently part of the <c>Mnesia</c>
+ application, but is currently part of the Mnesia
application.</p>
<p>This module is mainly intended for internal use within OTP,
but it has two functions that are exported for public use.</p>
<p>On C-nodes, <c>erl_interface</c> has support for registry
tables. These tables reside in RAM on the C-node, but can also
- be dumped into <c>Mnesia</c> tables. By default, the dumping
+ be dumped into Mnesia tables. By default, the dumping
of registry tables through <c>erl_interface</c> causes a
- corresponding <c>Mnesia</c> table to be created with
+ corresponding Mnesia table to be created with
<c>mnesia_registry:create_table/1</c>, if necessary.</p>
<p>Tables that are created with these functions can be
- administered as all other <c>Mnesia</c> tables. They can be
+ administered as all other Mnesia tables. They can be
included in backups, replicas can be added, and so on.
- The tables are normal <c>Mnesia</c> tables owned by the user
+ The tables are normal Mnesia tables owned by the user
of the corresponding <c>erl_interface</c> registries.</p>
</description>
@@ -68,7 +68,7 @@
that is, <c>{ram_copies,[node()]}</c> or
<c>{disc_copies,[node()]}</c>.</p>
<p>This function is used by <c>erl_interface</c> to
- create the <c>Mnesia</c> table if it does not already
+ create the Mnesia table if it does not already
exist.</p>
</desc>
</func>
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index 7d8e8d0c44..3ca4026190 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -39,7 +39,88 @@
thus constitutes one section in this document. The title of each
section is the version number of Mnesia.</p>
- <section><title>Mnesia 4.14</title>
+ <section><title>Mnesia 4.15</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Removed the wrapping of select continuations in extension
+ plugin handling. This might require the user to rewrite
+ user backend plugin if used.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14039</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.14.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed crash in checkpoint handling when table was deleted
+ during backup.</p>
+ <p>
+ Own Id: OTP-14167</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.14.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A continuation returned by mnesia:select/[14] should be
+ reusable in different, non-transactional activities.</p>
+ <p>
+ Own Id: OTP-13944 Aux Id: PR-1184 </p>
+ </item>
+ <item>
+ <p>
+ Fixed crash when calling block_table multiple times.
+ Could happen when having locks for a long time and
+ restarting mnesia.</p>
+ <p>
+ Own Id: OTP-13970 Aux Id: Seq-13198 </p>
+ </item>
+ <item>
+ <p>
+ Change mnesia_tm process to have off-heap messages since
+ mnesia_tm can be the receiver of many non-synchronized
+ message from other nodes.</p>
+ <p>
+ Own Id: OTP-14074</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.14.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Correct some minor documentation issues. </p>
+ <p>
+ Own Id: OTP-13891</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.14</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/mnesia/doc/src/part.xml b/lib/mnesia/doc/src/part.xml
index 101bdb29d4..d3ffe93937 100644
--- a/lib/mnesia/doc/src/part.xml
+++ b/lib/mnesia/doc/src/part.xml
@@ -30,7 +30,7 @@
<file>part.sgml</file>
</header>
<description>
- <p>The <c>Mnesia</c> application is a distributed Database Management
+ <p>The Mnesia application is a distributed Database Management
System (DBMS), appropriate for telecommunications applications and other
Erlang applications, which require continuous operation and exhibit soft
real-time properties.</p>
diff --git a/lib/mnesia/doc/src/ref_man.xml b/lib/mnesia/doc/src/ref_man.xml
index 662f0d61d6..7fb71b9c45 100644
--- a/lib/mnesia/doc/src/ref_man.xml
+++ b/lib/mnesia/doc/src/ref_man.xml
@@ -33,7 +33,7 @@
<file>refman.sgml</file>
</header>
<description>
- <p>The <c>Mnesia</c> application is a distributed Database Management
+ <p>The Mnesia application is a distributed Database Management
System (DBMS), appropriate for telecommunications applications and other
Erlang applications, which require continuous operation and exhibit soft
real-time properties.</p>
diff --git a/lib/mnesia/src/Makefile b/lib/mnesia/src/Makefile
index 08a00e6aba..7d316df263 100644
--- a/lib/mnesia/src/Makefile
+++ b/lib/mnesia/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2016. All Rights Reserved.
+# Copyright Ericsson AB 1996-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/mnesia-$(VSN)
# ----------------------------------------------------
MODULES= \
mnesia \
+ mnesia_app \
mnesia_backend_type \
mnesia_backup \
mnesia_bup \
@@ -54,7 +55,6 @@ MODULES= \
mnesia_ext_sup \
mnesia_frag \
mnesia_frag_hash \
- mnesia_frag_old_hash \
mnesia_index \
mnesia_kernel_sup \
mnesia_late_loader \
@@ -67,7 +67,6 @@ MODULES= \
mnesia_registry \
mnesia_schema\
mnesia_snmp_hook \
- mnesia_snmp_sup \
mnesia_subscr \
mnesia_sup \
mnesia_sp \
diff --git a/lib/mnesia/src/mnesia.app.src b/lib/mnesia/src/mnesia.app.src
index 006ad4bac1..6b49fc6c88 100644
--- a/lib/mnesia/src/mnesia.app.src
+++ b/lib/mnesia/src/mnesia.app.src
@@ -3,6 +3,7 @@
{vsn, "%VSN%"},
{modules, [
mnesia,
+ mnesia_app,
mnesia_backend_type,
mnesia_backup,
mnesia_bup,
@@ -14,7 +15,6 @@
mnesia_ext_sup,
mnesia_frag,
mnesia_frag_hash,
- mnesia_frag_old_hash,
mnesia_index,
mnesia_kernel_sup,
mnesia_late_loader,
@@ -27,7 +27,6 @@
mnesia_registry,
mnesia_schema,
mnesia_snmp_hook,
- mnesia_snmp_sup,
mnesia_subscr,
mnesia_sup,
mnesia_sp,
@@ -49,7 +48,5 @@
mnesia_tm
]},
{applications, [kernel, stdlib]},
- {mod, {mnesia_sup, []}},
+ {mod, {mnesia_app, []}},
{runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-7.0"]}]}.
-
-
diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index 9586adbf93..3b771e8c5b 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -138,6 +138,36 @@
-include("mnesia.hrl").
-import(mnesia_lib, [verbose/2]).
+-type create_option() ::
+ {'access_mode', 'read_write' | 'read_only'} |
+ {'attributes', [atom()]} |
+ {'disc_copies', [node()]} |
+ {'disc_only_copies', [node]} |
+ {'index', [index_attr()]} |
+ {'load_order', non_neg_integer()} |
+ {'majority', boolean()} |
+ {'ram_copies', [node()]} |
+ {'record_name', atom()} |
+ {'snmp', SnmpStruct::term()} |
+ {'storage_properties', [{Backend::module(), [BackendProp::_]}]} |
+ {'type', 'set' | 'ordered_set' | 'bag'} |
+ {'local_content', boolean()}.
+
+-type t_result(Res) :: {'atomic', Res} | {'aborted', Reason::term()}.
+-type activity() :: 'ets' | 'async_dirty' | 'sync_dirty' | 'transaction' | 'sync_transaction' |
+ {'transaction', Retries::non_neg_integer()} |
+ {'sync_transaction', Retries::non_neg_integer()}.
+-type table() :: atom().
+-type storage_type() :: 'ram_copies' | 'disc_copies' | 'disc_only_copies'.
+-type index_attr() :: atom() | non_neg_integer().
+-type write_locks() :: 'write' | 'sticky_write'.
+-type read_locks() :: 'read'.
+-type lock_kind() :: write_locks() | read_locks().
+-type select_continuation() :: term().
+-type snmp_struct() :: [{atom(), snmp_type() | tuple_of(snmp_type())}].
+-type snmp_type() :: 'fix_string' | 'string' | 'integer'.
+-type tuple_of(_T) :: tuple().
+
-define(DEFAULT_ACCESS, ?MODULE).
%% Select
@@ -196,7 +226,7 @@ e_has_var(X, Pos) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Start and stop
-
+-spec start() -> 'ok' | {'error', term()}.
start() ->
start([]).
@@ -216,6 +246,7 @@ start_() ->
{error, R}
end.
+-spec start([{Option::atom(), Value::_}]) -> 'ok' | {'error', term()}.
start(ExtraEnv) when is_list(ExtraEnv) ->
case mnesia_lib:ensure_loaded(?APPLICATION) of
ok ->
@@ -238,6 +269,7 @@ patched_start([Head | _]) ->
patched_start([]) ->
start_().
+-spec stop() -> 'stopped' | {'error', term()}.
stop() ->
case application:stop(?APPLICATION) of
ok -> stopped;
@@ -245,6 +277,7 @@ stop() ->
Other -> Other
end.
+-spec change_config(Config::atom(), Value::_) -> ok | {error, term()}.
change_config(extra_db_nodes, Ns) when is_list(Ns) ->
mnesia_controller:connect_nodes(Ns);
change_config(dc_dump_limit, N) when is_number(N), N > 0 ->
@@ -273,6 +306,7 @@ kill() ->
ms() ->
[
mnesia,
+ mnesia_app,
mnesia_backup,
mnesia_bup,
mnesia_checkpoint,
@@ -282,7 +316,6 @@ ms() ->
mnesia_loader,
mnesia_frag,
mnesia_frag_hash,
- mnesia_frag_old_hash,
mnesia_index,
mnesia_kernel_sup,
mnesia_late_loader,
@@ -311,12 +344,12 @@ ms() ->
%% Activity mgt
-spec abort(_) -> no_return().
-
abort(Reason = {aborted, _}) ->
exit(Reason);
abort(Reason) ->
exit({aborted, Reason}).
+-spec is_transaction() -> boolean().
is_transaction() ->
case get(mnesia_activity_state) of
{_, Tid, _Ts} when element(1,Tid) == tid ->
@@ -325,29 +358,52 @@ is_transaction() ->
false
end.
+-spec transaction(Fun) -> t_result(Res) when
+ Fun :: fun(() -> Res).
transaction(Fun) ->
transaction(get(mnesia_activity_state), Fun, [], infinity, ?DEFAULT_ACCESS, async).
+
+-spec transaction(Fun, Retries) -> t_result(Res) when
+ Fun :: fun(() -> Res),
+ Retries :: non_neg_integer() | 'infinity';
+ (Fun, [Arg::_]) -> t_result(Res) when
+ Fun :: fun((...) -> Res).
transaction(Fun, Retries) when is_integer(Retries), Retries >= 0 ->
transaction(get(mnesia_activity_state), Fun, [], Retries, ?DEFAULT_ACCESS, async);
transaction(Fun, Retries) when Retries == infinity ->
transaction(get(mnesia_activity_state), Fun, [], Retries, ?DEFAULT_ACCESS, async);
transaction(Fun, Args) ->
transaction(get(mnesia_activity_state), Fun, Args, infinity, ?DEFAULT_ACCESS, async).
+
+-spec transaction(Fun, [Arg::_], Retries) -> t_result(Res) when
+ Fun :: fun((...) -> Res),
+ Retries :: non_neg_integer() | 'infinity'.
transaction(Fun, Args, Retries) ->
transaction(get(mnesia_activity_state), Fun, Args, Retries, ?DEFAULT_ACCESS, async).
+-spec sync_transaction(Fun) -> t_result(Res) when
+ Fun :: fun(() -> Res).
sync_transaction(Fun) ->
transaction(get(mnesia_activity_state), Fun, [], infinity, ?DEFAULT_ACCESS, sync).
+
+-spec sync_transaction(Fun, Retries) -> t_result(Res) when
+ Fun :: fun(() -> Res),
+ Retries :: non_neg_integer() | 'infinity';
+ (Fun, [Arg::_]) -> t_result(Res) when
+ Fun :: fun((...) -> Res).
sync_transaction(Fun, Retries) when is_integer(Retries), Retries >= 0 ->
transaction(get(mnesia_activity_state), Fun, [], Retries, ?DEFAULT_ACCESS, sync);
sync_transaction(Fun, Retries) when Retries == infinity ->
transaction(get(mnesia_activity_state), Fun, [], Retries, ?DEFAULT_ACCESS, sync);
sync_transaction(Fun, Args) ->
transaction(get(mnesia_activity_state), Fun, Args, infinity, ?DEFAULT_ACCESS, sync).
+
+-spec sync_transaction(Fun, [Arg::_], Retries) -> t_result(Res) when
+ Fun :: fun((...) -> Res),
+ Retries :: non_neg_integer() | 'infinity'.
sync_transaction(Fun, Args, Retries) ->
transaction(get(mnesia_activity_state), Fun, Args, Retries, ?DEFAULT_ACCESS, sync).
-
transaction(State, Fun, Args, Retries, Mod, Kind)
when is_function(Fun), is_list(Args), Retries == infinity, is_atom(Mod) ->
mnesia_tm:transaction(State, Fun, Args, Retries, Mod, Kind);
@@ -363,28 +419,60 @@ non_transaction(State, Fun, Args, ActivityKind, Mod)
non_transaction(_State, Fun, Args, _ActivityKind, _Mod) ->
{aborted, {badarg, Fun, Args}}.
+-spec async_dirty(Fun) -> Res | no_return() when
+ Fun :: fun(() -> Res).
async_dirty(Fun) ->
async_dirty(Fun, []).
+
+-spec async_dirty(Fun, [Arg::_]) -> Res | no_return() when
+ Fun :: fun((...) -> Res).
async_dirty(Fun, Args) ->
non_transaction(get(mnesia_activity_state), Fun, Args, async_dirty, ?DEFAULT_ACCESS).
+-spec sync_dirty(Fun) -> Res | no_return() when
+ Fun :: fun(() -> Res).
sync_dirty(Fun) ->
sync_dirty(Fun, []).
+
+-spec sync_dirty(Fun, [Arg::_]) -> Res | no_return() when
+ Fun :: fun((...) -> Res).
sync_dirty(Fun, Args) ->
non_transaction(get(mnesia_activity_state), Fun, Args, sync_dirty, ?DEFAULT_ACCESS).
+-spec ets(Fun) -> Res | no_return() when
+ Fun :: fun(() -> Res).
ets(Fun) ->
ets(Fun, []).
+
+-spec ets(Fun, [Arg::_]) -> Res | no_return() when
+ Fun :: fun((...) -> Res).
ets(Fun, Args) ->
non_transaction(get(mnesia_activity_state), Fun, Args, ets, ?DEFAULT_ACCESS).
+-spec activity(Kind, Fun) -> t_result(Res) | Res when
+ Kind :: activity(),
+ Fun :: fun(() -> Res).
activity(Kind, Fun) ->
activity(Kind, Fun, []).
+
+-spec activity(Kind, Fun, [Arg::_]) -> t_result(Res) | Res when
+ Kind :: activity(),
+ Fun :: fun((...) -> Res);
+ (Kind, Fun, Mod) -> t_result(Res) | Res when
+ Kind :: activity(),
+ Fun :: fun(() -> Res),
+ Mod :: atom().
+
activity(Kind, Fun, Args) when is_list(Args) ->
activity(Kind, Fun, Args, mnesia_monitor:get_env(access_module));
activity(Kind, Fun, Mod) ->
activity(Kind, Fun, [], Mod).
+-spec activity(Kind, Fun, [Arg::_], Mod) -> t_result(Res) | Res when
+ Kind :: activity(),
+ Fun :: fun((...) -> Res),
+ Mod :: atom().
+
activity(Kind, Fun, Args, Mod) ->
State = get(mnesia_activity_state),
case Kind of
@@ -414,7 +502,11 @@ wrap_trans(State, Fun, Args, Retries, Mod, Kind) ->
%% Nodes may either be a list of nodes or one node as an atom
%% Mnesia on all Nodes must be connected to each other, but
%% it is not neccessary that they are up and running.
-
+-spec lock(LockItem, LockKind) -> list() | tuple() | no_return() when
+ LockItem :: {'record', table(), Key::term()} |
+ {'table', table()} |
+ {'global', Key::term(), MnesiaNodes::[node()]},
+ LockKind :: lock_kind() | 'load'.
lock(LockItem, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -425,6 +517,9 @@ lock(LockItem, LockKind) ->
abort(no_transaction)
end.
+-spec lock_table(Tab::table(), LockKind) -> [MnesiaNode] | no_return() when
+ MnesiaNode :: node(),
+ LockKind :: lock_kind() | load.
lock_table(Tab, LockKind) ->
lock({table, Tab}, LockKind).
@@ -446,11 +541,13 @@ lock(Tid, Ts, LockItem, LockKind) ->
end.
%% Grab a read lock on a whole table
+-spec read_lock_table(Tab::table()) -> ok.
read_lock_table(Tab) ->
lock({table, Tab}, read),
ok.
%% Grab a write lock on a whole table
+-spec write_lock_table(Tab::table()) -> ok.
write_lock_table(Tab) ->
lock({table, Tab}, write),
ok.
@@ -515,17 +612,19 @@ good_global_nodes(Nodes) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Access within an activity - updates
-
+-spec write(Record::tuple()) -> 'ok'.
write(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
write(Tab, Val, write);
write(Val) ->
abort({bad_type, Val}).
+-spec s_write(Record::tuple()) -> 'ok'.
s_write(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
write(Tab, Val, sticky_write).
+-spec write(Tab::table(), Record::tuple(), LockKind::write_locks()) -> 'ok'.
write(Tab, Val, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -572,16 +671,19 @@ write_to_store(Tab, Store, Oid, Val) ->
end,
ok.
+-spec delete({Tab::table(), Key::_}) -> 'ok'.
delete({Tab, Key}) ->
delete(Tab, Key, write);
delete(Oid) ->
abort({bad_type, Oid}).
+-spec s_delete({Tab::table(), Key::_}) -> 'ok'.
s_delete({Tab, Key}) ->
delete(Tab, Key, sticky_write);
s_delete(Oid) ->
abort({bad_type, Oid}).
+-spec delete(Tab::table(), Key::_, LockKind::write_locks()) -> 'ok'.
delete(Tab, Key, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -618,18 +720,21 @@ delete(Tid, Ts, Tab, Key, LockKind)
delete(_Tid, _Ts, Tab, _Key, _LockKind) ->
abort({bad_type, Tab}).
+-spec delete_object(Rec::tuple()) -> 'ok'.
delete_object(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
delete_object(Tab, Val, write);
delete_object(Val) ->
abort({bad_type, Val}).
+-spec s_delete_object(Rec::tuple()) -> 'ok'.
s_delete_object(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
delete_object(Tab, Val, sticky_write);
s_delete_object(Val) ->
abort({bad_type, Val}).
+-spec delete_object(Tab::table(), Rec::tuple(), LockKind::write_locks()) -> 'ok'.
delete_object(Tab, Val, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -689,19 +794,23 @@ do_delete_object(Tid, Ts, Tab, Val, LockKind) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Access within an activity - read
+-spec read(Tab::table(), Key::_) -> [tuple()].
read(Tab, Key) ->
read(Tab, Key, read).
+-spec read({Tab::table(), Key::_}) -> [tuple()].
read({Tab, Key}) ->
read(Tab, Key, read);
read(Oid) ->
abort({bad_type, Oid}).
+-spec wread({Tab::table(), Key::_}) -> [tuple()].
wread({Tab, Key}) ->
read(Tab, Key, write);
wread(Oid) ->
abort({bad_type, Oid}).
+-spec read(Tab::table(), Key::_, LockKind::lock_kind()) -> [tuple()].
read(Tab, Key, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -738,6 +847,7 @@ read(Tid, Ts, Tab, Key, LockKind)
read(_Tid, _Ts, Tab, _Key, _LockKind) ->
abort({bad_type, Tab}).
+-spec first(Tab::table()) -> Key::term().
first(Tab) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -765,6 +875,7 @@ first(Tid, Ts, Tab)
first(_Tid, _Ts,Tab) ->
abort({bad_type, Tab}).
+-spec last(Tab::table()) -> Key::term().
last(Tab) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -792,6 +903,7 @@ last(Tid, Ts, Tab)
last(_Tid, _Ts,Tab) ->
abort({bad_type, Tab}).
+-spec next(Tab::table(), Key::term()) -> NextKey::term().
next(Tab,Key) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS,Tid,Ts} ->
@@ -818,6 +930,7 @@ next(Tid,Ts,Tab,Key)
next(_Tid, _Ts,Tab,_) ->
abort({bad_type, Tab}).
+-spec prev(Tab::table(), Key::term()) -> PrevKey::term().
prev(Tab,Key) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS,Tid,Ts} ->
@@ -952,6 +1065,8 @@ ts_keys_1([], Acc) ->
%%%%%%%%%%%%%%%%%%%%%
%% Iterators
+-spec foldl(Fun, Acc0, Tab::table()) -> Acc when
+ Fun::fun((Record::tuple(), Acc0) -> Acc).
foldl(Fun, Acc, Tab) ->
foldl(Fun, Acc, Tab, read).
@@ -992,6 +1107,8 @@ do_foldl(A, O, Tab, Key, Fun, Acc, Type, Stored) -> %% Type is set or bag
{_, Tid, Ts} = get(mnesia_activity_state),
do_foldl(Tid, Ts, Tab, dirty_next(Tab, Key), Fun, NewAcc, Type, NewStored).
+-spec foldr(Fun, Acc0, Tab::table()) -> Acc when
+ Fun::fun((Record::tuple(), Acc0) -> Acc).
foldr(Fun, Acc, Tab) ->
foldr(Fun, Acc, Tab, read).
foldr(Fun, Acc, Tab, LockKind) when is_function(Fun) ->
@@ -1105,12 +1222,15 @@ add_written_to_bag([{_, _ , delete} | Tail], _Objs, _Ack) ->
add_written_to_bag([{_, Val, delete_object} | Tail], Objs, Ack) ->
add_written_to_bag(Tail, lists:delete(Val, Objs), lists:delete(Val, Ack)).
+-spec match_object(Pattern::tuple()) -> [Record::tuple()].
match_object(Pat) when is_tuple(Pat), tuple_size(Pat) > 2 ->
Tab = element(1, Pat),
match_object(Tab, Pat, read);
match_object(Pat) ->
abort({bad_type, Pat}).
+-spec match_object(Tab,Pattern,LockKind) -> [Record] when
+ Tab::table(),Pattern::tuple(),LockKind::lock_kind(),Record::tuple().
match_object(Tab, Pat, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -1270,9 +1390,13 @@ deloid(Oid, [H | T]) ->
%%%%%%%%%%%%%%%%%%
% select
-
+-spec select(Tab, Spec) -> [Match] when
+ Tab::table(), Spec::ets:match_spec(), Match::term().
select(Tab, Pat) ->
select(Tab, Pat, read).
+-spec select(Tab, Spec, LockKind) -> [Match] when
+ Tab::table(), Spec::ets:match_spec(),
+ Match::term(),LockKind::lock_kind().
select(Tab, Pat, LockKind)
when is_atom(Tab), Tab /= schema, is_list(Pat) ->
case get(mnesia_activity_state) of
@@ -1331,6 +1455,11 @@ select_lock(Tid,Ts,LockKind,Spec,Tab) ->
end.
%% Breakable Select
+-spec select(Tab, Spec, N, LockKind) -> {[Match], Cont} | '$end_of_table' when
+ Tab::table(), Spec::ets:match_spec(),
+ Match::term(), N::non_neg_integer(),
+ LockKind::lock_kind(),
+ Cont::select_continuation().
select(Tab, Pat, NObjects, LockKind)
when is_atom(Tab), Tab /= schema, is_list(Pat), is_integer(NObjects) ->
case get(mnesia_activity_state) of
@@ -1387,6 +1516,9 @@ fun_select(Tid, Ts, Tab, Spec, LockKind, TabPat, Init, NObjects, Node, Storage)
select_state(Init(Spec),Def)
end.
+-spec select(Cont) -> {[Match], Cont} | '$end_of_table' when
+ Match::term(),
+ Cont::select_continuation().
select(Cont) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -1409,8 +1541,14 @@ select_cont(Tid,_,State=#mnesia_select{tid=Tid,written=[]}) ->
select_state(dirty_sel_cont(State),State);
select_cont(Tid,_Ts,State=#mnesia_select{tid=Tid}) ->
trans_select(dirty_sel_cont(State), State);
-select_cont(_Tid2,_,#mnesia_select{tid=_Tid1}) -> % Missmatching tids
+select_cont(Tid2,_,#mnesia_select{tid=_Tid1})
+ when element(1,Tid2) == tid -> % Mismatching tids
abort(wrong_transaction);
+select_cont(Tid,Ts,State=#mnesia_select{}) ->
+ % Repair mismatching tids in non-transactional contexts
+ RepairedState = State#mnesia_select{tid = Tid, written = [],
+ spec = undefined, type = undefined},
+ select_cont(Tid,Ts,RepairedState);
select_cont(_,_,Cont) ->
abort({badarg, Cont}).
@@ -1430,6 +1568,7 @@ get_record_pattern([]) -> [];
get_record_pattern([{M,C,_B}|R]) ->
[{M,C,['$_']} | get_record_pattern(R)].
+-spec all_keys(Tab::table()) -> [Key::term()].
all_keys(Tab) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -1454,12 +1593,20 @@ all_keys(Tid, Ts, Tab, LockKind)
all_keys(_Tid, _Ts, Tab, _LockKind) ->
abort({bad_type, Tab}).
+-spec index_match_object(Pattern, Attr) -> [Record] when
+ Pattern::tuple(), Attr::index_attr(), Record::tuple().
index_match_object(Pat, Attr) when is_tuple(Pat), tuple_size(Pat) > 2 ->
Tab = element(1, Pat),
index_match_object(Tab, Pat, Attr, read);
index_match_object(Pat, _Attr) ->
abort({bad_type, Pat}).
+-spec index_match_object(Tab, Pattern, Attr, LockKind) -> [Record] when
+ Tab::table(),
+ Pattern::tuple(),
+ Attr::index_attr(),
+ LockKind::lock_kind(),
+ Record::tuple().
index_match_object(Tab, Pat, Attr, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -1496,6 +1643,11 @@ index_match_object(Tid, Ts, Tab, Pat, Attr, LockKind)
index_match_object(_Tid, _Ts, Tab, Pat, _Attr, _LockKind) ->
abort({bad_type, Tab, Pat}).
+-spec index_read(Tab, Key, Attr) -> [Record] when
+ Tab::table(),
+ Key::term(),
+ Attr::index_attr(),
+ Record::tuple().
index_read(Tab, Key, Attr) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -1535,13 +1687,14 @@ index_read(_Tid, _Ts, Tab, _Key, _Attr, _LockKind) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Dirty access regardless of activities - updates
-
+-spec dirty_write(Record::tuple()) -> 'ok'.
dirty_write(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
dirty_write(Tab, Val);
dirty_write(Val) ->
abort({bad_type, Val}).
+-spec dirty_write(Tab::table(), Record::tuple()) -> 'ok'.
dirty_write(Tab, Val) ->
do_dirty_write(async_dirty, Tab, Val).
@@ -1553,11 +1706,13 @@ do_dirty_write(SyncMode, Tab, Val)
do_dirty_write(_SyncMode, Tab, Val) ->
abort({bad_type, Tab, Val}).
+-spec dirty_delete({Tab::table(), Key::_}) -> 'ok'.
dirty_delete({Tab, Key}) ->
dirty_delete(Tab, Key);
dirty_delete(Oid) ->
abort({bad_type, Oid}).
+-spec dirty_delete(Tab::table(), Key::_) -> 'ok'.
dirty_delete(Tab, Key) ->
do_dirty_delete(async_dirty, Tab, Key).
@@ -1567,12 +1722,14 @@ do_dirty_delete(SyncMode, Tab, Key) when is_atom(Tab), Tab /= schema ->
do_dirty_delete(_SyncMode, Tab, _Key) ->
abort({bad_type, Tab}).
+-spec dirty_delete_object(Record::tuple()) -> 'ok'.
dirty_delete_object(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
dirty_delete_object(Tab, Val);
dirty_delete_object(Val) ->
abort({bad_type, Val}).
+-spec dirty_delete_object(Tab::table(), Record::tuple()) -> 'ok'.
dirty_delete_object(Tab, Val) ->
do_dirty_delete_object(async_dirty, Tab, Val).
@@ -1590,12 +1747,15 @@ do_dirty_delete_object(_SyncMode, Tab, Val) ->
abort({bad_type, Tab, Val}).
%% A Counter is an Oid being {CounterTab, CounterName}
-
+-spec dirty_update_counter({Tab::table(), Key::_}, Incr::integer()) ->
+ NewVal::integer().
dirty_update_counter({Tab, Key}, Incr) ->
dirty_update_counter(Tab, Key, Incr);
dirty_update_counter(Counter, _Incr) ->
abort({bad_type, Counter}).
+-spec dirty_update_counter(Tab::table(), Key::_, Incr::integer()) ->
+ NewVal::integer().
dirty_update_counter(Tab, Key, Incr) ->
do_dirty_update_counter(async_dirty, Tab, Key, Incr).
@@ -1614,23 +1774,28 @@ do_dirty_update_counter(_SyncMode, Tab, _Key, Incr) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Dirty access regardless of activities - read
+-spec dirty_read({Tab::table(), Key::_}) -> [tuple()].
dirty_read({Tab, Key}) ->
dirty_read(Tab, Key);
dirty_read(Oid) ->
abort({bad_type, Oid}).
+-spec dirty_read(Tab::table(), Key::_) -> [tuple()].
dirty_read(Tab, Key)
when is_atom(Tab), Tab /= schema ->
dirty_rpc(Tab, mnesia_lib, db_get, [Tab, Key]);
dirty_read(Tab, _Key) ->
abort({bad_type, Tab}).
+-spec dirty_match_object(Pattern::tuple()) -> [Record::tuple()].
dirty_match_object(Pat) when is_tuple(Pat), tuple_size(Pat) > 2 ->
Tab = element(1, Pat),
dirty_match_object(Tab, Pat);
dirty_match_object(Pat) ->
abort({bad_type, Pat}).
+-spec dirty_match_object(Tab,Pattern) -> [Record] when
+ Tab::table(), Pattern::tuple(), Record::tuple().
dirty_match_object(Tab, Pat)
when is_atom(Tab), Tab /= schema, is_tuple(Pat), tuple_size(Pat) > 2 ->
dirty_rpc(Tab, ?MODULE, remote_dirty_match_object, [Tab, Pat]);
@@ -1660,6 +1825,8 @@ remote_dirty_match_object(Tab, Pat, []) ->
remote_dirty_match_object(Tab, Pat, _PosList) ->
abort({bad_type, Tab, Pat}).
+-spec dirty_select(Tab, Spec) -> [Match] when
+ Tab::table(), Spec::ets:match_spec(), Match::term().
dirty_select(Tab, Spec) when is_atom(Tab), Tab /= schema, is_list(Spec) ->
dirty_rpc(Tab, ?MODULE, remote_dirty_select, [Tab, Spec]);
dirty_select(Tab, Spec) ->
@@ -1708,6 +1875,7 @@ dirty_sel_cont(#mnesia_select{cont='$end_of_table'}) -> '$end_of_table';
dirty_sel_cont(#mnesia_select{node=Node,tab=Tab,storage=Type,cont=Cont,orig=Ms}) ->
do_dirty_rpc(Tab,Node,mnesia_lib,db_select_cont,[Type,Cont,Ms]).
+-spec dirty_all_keys(Tab::table()) -> [Key::term()].
dirty_all_keys(Tab) when is_atom(Tab), Tab /= schema ->
case ?catch_val({Tab, wild_pattern}) of
{'EXIT', _} ->
@@ -1723,12 +1891,19 @@ dirty_all_keys(Tab) when is_atom(Tab), Tab /= schema ->
dirty_all_keys(Tab) ->
abort({bad_type, Tab}).
+-spec dirty_index_match_object(Pattern, Attr) -> [Record] when
+ Pattern::tuple(), Attr::index_attr(), Record::tuple().
dirty_index_match_object(Pat, Attr) when is_tuple(Pat), tuple_size(Pat) > 2 ->
Tab = element(1, Pat),
dirty_index_match_object(Tab, Pat, Attr);
dirty_index_match_object(Pat, _Attr) ->
abort({bad_type, Pat}).
+-spec dirty_index_match_object(Tab, Pattern, Attr) -> [Record] when
+ Tab::table(),
+ Pattern::tuple(),
+ Attr::index_attr(),
+ Record::tuple().
dirty_index_match_object(Tab, Pat, Attr)
when is_atom(Tab), Tab /= schema, is_tuple(Pat), tuple_size(Pat) > 2 ->
case mnesia_schema:attr_tab_to_pos(Tab, Attr) of
@@ -1752,6 +1927,11 @@ dirty_index_match_object(Tab, Pat, Attr)
dirty_index_match_object(Tab, Pat, _Attr) ->
abort({bad_type, Tab, Pat}).
+-spec dirty_index_read(Tab, Key, Attr) -> [Record] when
+ Tab::table(),
+ Key::term(),
+ Attr::index_attr(),
+ Record::tuple().
dirty_index_read(Tab, Key, Attr) when is_atom(Tab), Tab /= schema ->
Pos = mnesia_schema:attr_tab_to_pos(Tab, Attr),
case has_var(Key) of
@@ -1763,26 +1943,31 @@ dirty_index_read(Tab, Key, Attr) when is_atom(Tab), Tab /= schema ->
dirty_index_read(Tab, _Key, _Attr) ->
abort({bad_type, Tab}).
+%% do not use only for backwards compatibility
dirty_slot(Tab, Slot) when is_atom(Tab), Tab /= schema, is_integer(Slot) ->
dirty_rpc(Tab, mnesia_lib, db_slot, [Tab, Slot]);
dirty_slot(Tab, Slot) ->
abort({bad_type, Tab, Slot}).
+-spec dirty_first(Tab::table()) -> Key::term().
dirty_first(Tab) when is_atom(Tab), Tab /= schema ->
dirty_rpc(Tab, mnesia_lib, db_first, [Tab]);
dirty_first(Tab) ->
abort({bad_type, Tab}).
+-spec dirty_last(Tab::table()) -> Key::term().
dirty_last(Tab) when is_atom(Tab), Tab /= schema ->
dirty_rpc(Tab, mnesia_lib, db_last, [Tab]);
dirty_last(Tab) ->
abort({bad_type, Tab}).
+-spec dirty_next(Tab::table(), Key::_) -> NextKey::term().
dirty_next(Tab, Key) when is_atom(Tab), Tab /= schema ->
dirty_rpc(Tab, mnesia_lib, db_next_key, [Tab, Key]);
dirty_next(Tab, _Key) ->
abort({bad_type, Tab}).
+-spec dirty_prev(Tab::table(), Key::_) -> PrevKey::term().
dirty_prev(Tab, Key) when is_atom(Tab), Tab /= schema ->
dirty_rpc(Tab, mnesia_lib, db_prev_key, [Tab, Key]);
dirty_prev(Tab, _Key) ->
@@ -1833,7 +2018,7 @@ do_dirty_rpc(Tab, Node, M, F, Args) ->
%% Info
%% Info about one table
--spec table_info(atom(), any()) -> any().
+-spec table_info(Tab::table(), Item::term()) -> Info::term().
table_info(Tab, Item) ->
case get(mnesia_activity_state) of
undefined ->
@@ -1876,9 +2061,10 @@ any_table_info(Tab, Item) when is_atom(Tab) ->
[] ->
abort({no_exists, Tab, Item});
Props ->
- lists:map(fun({setorbag, Type}) -> {type, Type};
- (Prop) -> Prop end,
- Props)
+ Rename = fun ({setorbag, Type}) -> {type, Type};
+ (Prop) -> Prop
+ end,
+ lists:sort(lists:map(Rename, Props))
end;
name ->
Tab;
@@ -1921,16 +2107,20 @@ bad_info_reply(_Tab, memory) -> 0;
bad_info_reply(Tab, Item) -> abort({no_exists, Tab, Item}).
%% Raw info about all tables
+-spec schema() -> ok.
schema() ->
mnesia_schema:info().
%% Raw info about one tables
+-spec schema(Tab::table()) -> ok.
schema(Tab) ->
mnesia_schema:info(Tab).
+-spec error_description(Error::term()) -> string().
error_description(Err) ->
mnesia_lib:error_desc(Err).
+-spec info() -> ok.
info() ->
case mnesia_lib:is_running() of
yes ->
@@ -2056,6 +2246,7 @@ display_tab_info() ->
Rdisp = fun({Rpat, Rtabs}) -> io:format("~p = ~p~n", [Rpat, Rtabs]) end,
lists:foreach(Rdisp, lists:sort(Repl)).
+-spec get_backend_types() -> [BackendType::term()].
get_backend_types() ->
case ?catch_val({schema, user_property, mnesia_backend_types}) of
{'EXIT', _} ->
@@ -2064,6 +2255,7 @@ get_backend_types() ->
lists:sort(Ts)
end.
+-spec get_index_plugins() -> [IndexPlugins::term()].
get_index_plugins() ->
case ?catch_val({schema, user_property, mnesia_index_plugins}) of
{'EXIT', _} ->
@@ -2112,6 +2304,7 @@ storage_count(T, {U, R, D, DO, Ext}) ->
{ext, A, _} -> {U, R, D, DO, orddict:append(A, T, Ext)}
end.
+-spec system_info(Iterm::term()) -> Info::term().
system_info(Item) ->
try system_info2(Item)
catch _:Error -> abort(Error)
@@ -2361,83 +2554,134 @@ load_mnesia_or_abort() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Database mgt
+-spec create_schema(Ns::[node()]) -> 'ok' | {'error', Reason::term()}.
create_schema(Ns) ->
create_schema(Ns, []).
+-spec create_schema(Ns::[node()], [Prop]) -> 'ok' | {'error', Reason::term()} when
+ Prop :: BackendType | IndexPlugin,
+ BackendType :: {backend_types, [{Name::atom(), Module::module()}]},
+ IndexPlugin :: {index_plugins, [{{Name::atom()}, Module::module(), Function::atom()}]}.
create_schema(Ns, Properties) ->
mnesia_bup:create_schema(Ns, Properties).
+-spec delete_schema(Ns::[node()]) -> 'ok' | {'error', Reason::term()}.
delete_schema(Ns) ->
mnesia_schema:delete_schema(Ns).
+-spec add_backend_type(Name::atom(), Module::module()) -> t_result('ok').
add_backend_type(Alias, Module) ->
mnesia_schema:add_backend_type(Alias, Module).
+-spec backup(Dest::term()) -> 'ok' | {'error', Reason::term()}.
backup(Opaque) ->
mnesia_log:backup(Opaque).
+-spec backup(Dest::term(), Mod::module()) ->
+ 'ok' | {'error', Reason::term()}.
backup(Opaque, Mod) ->
mnesia_log:backup(Opaque, Mod).
+-spec traverse_backup(Src::term(), Dest::term(), Fun, Acc) ->
+ {'ok', Acc} | {'error', Reason::term()} when
+ Fun :: fun((Items, Acc) -> {Items,Acc}).
traverse_backup(S, T, Fun, Acc) ->
mnesia_bup:traverse_backup(S, T, Fun, Acc).
+-spec traverse_backup(Src::term(), SrcMod::module(),
+ Dest::term(), DestMod::module(),
+ Fun, Acc) ->
+ {'ok', Acc} | {'error', Reason::term()} when
+ Fun :: fun((Items, Acc) -> {Items,Acc}).
traverse_backup(S, SM, T, TM, F, A) ->
mnesia_bup:traverse_backup(S, SM, T, TM, F, A).
+-spec install_fallback(Src::term()) -> 'ok' | {'error', Reason::term()}.
install_fallback(Opaque) ->
mnesia_bup:install_fallback(Opaque).
+-spec install_fallback(Src::term(), Mod::module()|[Opt]) ->
+ 'ok' | {'error', Reason::term()} when
+ Opt :: Module | Scope | Dir,
+ Module :: {'module', Mod::module()},
+ Scope :: {'scope', 'global' | 'local'},
+ Dir :: {'mnesia_dir', Dir::string()}.
install_fallback(Opaque, Mod) ->
mnesia_bup:install_fallback(Opaque, Mod).
+-spec uninstall_fallback() -> 'ok' | {'error', Reason::term()}.
uninstall_fallback() ->
mnesia_bup:uninstall_fallback().
+-spec uninstall_fallback(Args) -> 'ok' | {'error', Reason::term()} when
+ Args :: [{'mnesia_dir', Dir::string()}].
uninstall_fallback(Args) ->
mnesia_bup:uninstall_fallback(Args).
+-spec activate_checkpoint([Arg]) -> {'ok', Name, [node()]} | {'error', Reason::term()} when
+ Arg :: {'name', Name} | {'max', [table()]} | {'min', [table()]} |
+ {'allow_remote', boolean()} | {'ram_overrides_dump', boolean()}.
activate_checkpoint(Args) ->
mnesia_checkpoint:activate(Args).
+-spec deactivate_checkpoint(Name::_) -> 'ok' | {'error', Reason::term()}.
deactivate_checkpoint(Name) ->
mnesia_checkpoint:deactivate(Name).
+-spec backup_checkpoint(Name::_, Dest::_) -> 'ok' | {'error', Reason::term()}.
backup_checkpoint(Name, Opaque) ->
mnesia_log:backup_checkpoint(Name, Opaque).
+-spec backup_checkpoint(Name::_, Dest::_, Mod::module()) ->
+ 'ok' | {'error', Reason::term()}.
backup_checkpoint(Name, Opaque, Mod) ->
mnesia_log:backup_checkpoint(Name, Opaque, Mod).
+-spec restore(Src::_, [Arg]) -> t_result([table()]) when
+ Op :: 'skip_tables' | 'clear_tables' | 'keep_tables' | 'restore_tables',
+ Arg :: {'module', module()} | {Op, [table()]} | {'default_op', Op}.
restore(Opaque, Args) ->
mnesia_schema:restore(Opaque, Args).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Table mgt
-
+-spec create_table([Arg]) -> t_result('ok') when
+ Arg :: {'name', table()} | create_option().
create_table(Arg) ->
mnesia_schema:create_table(Arg).
+
+-spec create_table(Name::table(), [create_option()]) -> t_result('ok').
create_table(Name, Arg) when is_list(Arg) ->
mnesia_schema:create_table([{name, Name}| Arg]);
create_table(Name, Arg) ->
{aborted, badarg, Name, Arg}.
+-spec delete_table(Tab::table()) -> t_result('ok').
delete_table(Tab) ->
mnesia_schema:delete_table(Tab).
+-spec add_table_copy(Tab::table(), N::node(), ST::storage_type()) -> t_result(ok).
add_table_copy(Tab, N, S) ->
mnesia_schema:add_table_copy(Tab, N, S).
+
+-spec del_table_copy(Tab::table(), N::node()) -> t_result(ok).
del_table_copy(Tab, N) ->
mnesia_schema:del_table_copy(Tab, N).
+-spec move_table_copy(Tab::table(), From::node(), To::node()) -> t_result(ok).
move_table_copy(Tab, From, To) ->
mnesia_schema:move_table(Tab, From, To).
+-spec add_table_index(Tab::table(), I::index_attr()) -> t_result(ok).
add_table_index(Tab, Ix) ->
mnesia_schema:add_table_index(Tab, Ix).
+-spec del_table_index(Tab::table(), I::index_attr()) -> t_result(ok).
del_table_index(Tab, Ix) ->
mnesia_schema:del_table_index(Tab, Ix).
+-spec transform_table(Tab::table(), Fun, [Attr]) -> t_result(ok) when
+ Attr :: atom(),
+ Fun:: fun((Record::tuple()) -> Transformed::tuple()).
transform_table(Tab, Fun, NewA) ->
try val({Tab, record_name}) of
OldRN -> mnesia_schema:transform_table(Tab, Fun, NewA, OldRN)
@@ -2445,12 +2689,18 @@ transform_table(Tab, Fun, NewA) ->
mnesia:abort(Reason)
end.
+-spec transform_table(Tab::table(), Fun, [Attr], RecName) -> t_result(ok) when
+ RecName :: atom(),
+ Attr :: atom(),
+ Fun:: fun((Record::tuple()) -> Transformed::tuple()).
transform_table(Tab, Fun, NewA, NewRN) ->
mnesia_schema:transform_table(Tab, Fun, NewA, NewRN).
+-spec change_table_copy_type(Tab::table(), Node::node(), To::storage_type()) -> t_result(ok).
change_table_copy_type(T, N, S) ->
mnesia_schema:change_table_copy_type(T, N, S).
+-spec clear_table(Tab::table()) -> t_result(ok).
clear_table(Tab) ->
case get(mnesia_activity_state) of
State = {Mod, Tid, _Ts} when element(1, Tid) =/= tid ->
@@ -2480,19 +2730,22 @@ clear_table(Tid, Ts, Tab, Obj) when element(1, Tid) =:= tid ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Table mgt - user properties
-
+-spec read_table_property(Tab::table(), PropKey::term()) -> Res::tuple().
read_table_property(Tab, PropKey) ->
val({Tab, user_property, PropKey}).
+-spec write_table_property(Tab::table(), Prop::tuple()) -> t_result(ok).
write_table_property(Tab, Prop) ->
mnesia_schema:write_table_property(Tab, Prop).
+-spec delete_table_property(Tab::table(), PropKey::term()) -> t_result(ok).
delete_table_property(Tab, PropKey) ->
mnesia_schema:delete_table_property(Tab, PropKey).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Table mgt - user properties
+-spec change_table_frag(Tab::table(), FP::term()) -> t_result(ok).
change_table_frag(Tab, FragProp) ->
mnesia_schema:change_table_frag(Tab, FragProp).
@@ -2500,28 +2753,38 @@ change_table_frag(Tab, FragProp) ->
%% Table mgt - table load
%% Dump a ram table to disc
+-spec dump_tables([Tab::table()]) -> t_result(ok).
dump_tables(Tabs) ->
mnesia_schema:dump_tables(Tabs).
%% allow the user to wait for some tables to be loaded
+-spec wait_for_tables([Tab::table()], TMO::timeout()) ->
+ 'ok' | {'timeout', [table()]} | {'error', Reason::term()}.
wait_for_tables(Tabs, Timeout) ->
mnesia_controller:wait_for_tables(Tabs, Timeout).
+-spec force_load_table(Tab::table()) -> 'yes' | {'error', Reason::term()}.
force_load_table(Tab) ->
case mnesia_controller:force_load_table(Tab) of
ok -> yes; % Backwards compatibility
Other -> Other
end.
+-spec change_table_access_mode(Tab::table(), Mode) -> t_result(ok) when
+ Mode :: 'read_only'|'read_write'.
change_table_access_mode(T, Access) ->
mnesia_schema:change_table_access_mode(T, Access).
+-spec change_table_load_order(Tab::table(), Order) -> t_result(ok) when
+ Order :: non_neg_integer().
change_table_load_order(T, O) ->
mnesia_schema:change_table_load_order(T, O).
+-spec change_table_majority(Tab::table(), M::boolean()) -> t_result(ok).
change_table_majority(T, M) ->
mnesia_schema:change_table_majority(T, M).
+-spec set_master_nodes(Ns::[node()]) -> 'ok' | {'error', Reason::term()}.
set_master_nodes(Nodes) when is_list(Nodes) ->
UseDir = system_info(use_dir),
IsRunning = system_info(is_running),
@@ -2560,6 +2823,8 @@ log_valid_master_nodes(Cstructs, Nodes, UseDir, IsRunning) ->
Args = lists:map(Fun, Cstructs),
mnesia_recover:log_master_nodes(Args, UseDir, IsRunning).
+-spec set_master_nodes(Tab::table(), Ns::[node()]) ->
+ 'ok' | {'error', Reason::term()}.
set_master_nodes(Tab, Nodes) when is_list(Nodes) ->
UseDir = system_info(use_dir),
IsRunning = system_info(is_running),
@@ -2610,31 +2875,39 @@ set_master_nodes(Tab, Nodes) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Misc admin
-
+-spec dump_log() -> 'dumped'.
dump_log() ->
mnesia_controller:sync_dump_log(user).
+-spec sync_log() -> 'ok' | {'error', Reason::term()}.
sync_log() ->
mnesia_monitor:sync_log(latest_log).
+-spec subscribe(What) -> {'ok', node()} | {'error', Reason::term()} when
+ What :: 'system' | 'activity' | {'table', table(), 'simple' | 'detailed'}.
subscribe(What) ->
mnesia_subscr:subscribe(self(), What).
+-spec unsubscribe(What) -> {'ok', node()} | {'error', Reason::term()} when
+ What :: 'system' | 'activity' | {'table', table(), 'simple' | 'detailed'}.
unsubscribe(What) ->
mnesia_subscr:unsubscribe(self(), What).
+-spec report_event(Event::_) -> 'ok'.
report_event(Event) ->
mnesia_lib:report_system_event({mnesia_user, Event}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Snmp
-
+-spec snmp_open_table(Tab::table(), Snmp::snmp_struct()) -> ok.
snmp_open_table(Tab, Us) ->
mnesia_schema:add_snmp(Tab, Us).
+-spec snmp_close_table(Tab::table()) -> ok.
snmp_close_table(Tab) ->
mnesia_schema:del_snmp(Tab).
+-spec snmp_get_row(Tab::table(), [integer()]) -> {'ok', Row::tuple()} | 'undefined'.
snmp_get_row(Tab, RowIndex) when is_atom(Tab), Tab /= schema, is_list(RowIndex) ->
case get(mnesia_activity_state) of
{Mod, Tid, Ts=#tidstore{store=Store}} when element(1, Tid) =:= tid ->
@@ -2670,7 +2943,7 @@ snmp_get_row(Tab, _RowIndex) ->
abort({bad_type, Tab}).
%%%%%%%%%%%%%
-
+-spec snmp_get_next_index(Tab::table(), [integer()]) -> {'ok', [integer()]} | 'endOfTable'.
snmp_get_next_index(Tab, RowIndex) when is_atom(Tab), Tab /= schema, is_list(RowIndex) ->
{Next,OrigKey} = dirty_rpc(Tab, mnesia_snmp_hook, get_next_index, [Tab, RowIndex]),
case get(mnesia_activity_state) of
@@ -2712,7 +2985,7 @@ get_ordered_snmp_key(_, []) ->
endOfTable.
%%%%%%%%%%
-
+-spec snmp_get_mnesia_key(Tab::table(), [integer()]) -> {'ok', Key::term()} | 'undefined'.
snmp_get_mnesia_key(Tab, RowIndex) when is_atom(Tab), Tab /= schema, is_list(RowIndex) ->
case get(mnesia_activity_state) of
{_Mod, Tid, Ts} when element(1, Tid) =:= tid ->
@@ -2776,17 +3049,27 @@ snmp_filter_key(undefined, RowIndex, Tab, Store) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Textfile access
-
+-spec load_textfile(File::file:filename()) -> t_result(ok) | {'error', term()}.
load_textfile(F) ->
mnesia_text:load_textfile(F).
+
+-spec dump_to_textfile(File :: file:filename()) -> 'ok' | 'error' | {'error', term()}.
dump_to_textfile(F) ->
mnesia_text:dump_to_textfile(F).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% QLC Handles
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec table(Tab::table()) -> qlc:query_handle().
table(Tab) ->
table(Tab, []).
+
+-spec table(Tab::table(), Options) -> qlc:query_handle() when
+ Options :: Option | [Option],
+ Option :: MnesiaOpt | QlcOption,
+ MnesiaOpt :: {'traverse', SelectOp} | {lock, lock_kind()} | {n_objects, non_neg_integer()},
+ SelectOp :: 'select' | {'select', ets:match_spec()},
+ QlcOption :: {'key_equality', '==' | '=:='}.
table(Tab,Opts) ->
{[Trav,Lock,NObjects],QlcOptions0} =
qlc_opts(Opts,[{traverse,select},{lock,read},{n_objects,100}]),
diff --git a/lib/mnesia/src/mnesia.hrl b/lib/mnesia/src/mnesia.hrl
index 0716dd87c8..da7e662288 100644
--- a/lib/mnesia/src/mnesia.hrl
+++ b/lib/mnesia/src/mnesia.hrl
@@ -49,12 +49,12 @@
%% It's important that counter is first, since we compare tid's
--record(tid,
+-record(tid,
{counter, %% serial no for tid
pid}). %% owner of tid
--record(tidstore,
+-record(tidstore,
{store, %% current ets table for tid
up_stores = [], %% list of upper layer stores for nested trans
level = 1}). %% transaction level
@@ -128,5 +128,4 @@
mnesia_lib:eval_debug_fun(I, C, ?FILE, ?LINE)).
-else.
-define(eval_debug_fun(I, C), ok).
--endif.
-
+-endif.
diff --git a/lib/percept/src/percept.appup.src b/lib/mnesia/src/mnesia_app.erl
index 3ccdf8db2b..4d89011db2 100644
--- a/lib/percept/src/percept.appup.src
+++ b/lib/mnesia/src/mnesia_app.erl
@@ -1,7 +1,7 @@
-%% -*- erlang -*-
+%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -16,7 +16,26 @@
%% limitations under the License.
%%
%% %CopyrightEnd%
-{"%VSN%",
- [{<<".*">>,[{restart_application, percept}]}],
- [{<<".*">>,[{restart_application, percept}]}]
-}.
+%%
+
+-module(mnesia_app).
+
+-behaviour(application).
+
+-export([start/2, stop/1]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% application callback functions
+
+start(normal, Args) ->
+ case mnesia_sup:start_link(Args) of
+ {ok, Pid} ->
+ {ok, Pid, {normal, Args}};
+ Error ->
+ Error
+ end;
+start(_, _) ->
+ {error, badarg}.
+
+stop(_StartArgs) ->
+ ok.
diff --git a/lib/mnesia/src/mnesia_checkpoint.erl b/lib/mnesia/src/mnesia_checkpoint.erl
index 9eb939e8d3..8659e4622c 100644
--- a/lib/mnesia/src/mnesia_checkpoint.erl
+++ b/lib/mnesia/src/mnesia_checkpoint.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016
+%% Copyright Ericsson AB 1996-2017
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -909,7 +909,7 @@ retainer_loop(Cp = #checkpoint_args{name=Name}) ->
retainer_loop(Cp2);
{From, {iter_end, Iter}} ->
- retainer_fixtable(Iter#iter.oid_tab, false),
+ ?SAFE(retainer_fixtable(Iter#iter.oid_tab, false)),
Iters = Cp#checkpoint_args.iterators -- [Iter],
reply(From, Name, ok),
retainer_loop(Cp#checkpoint_args{iterators = Iters});
@@ -971,7 +971,8 @@ do_stop(Cp) ->
unset({checkpoint, Name}),
lists:foreach(fun deactivate_tab/1, Cp#checkpoint_args.retainers),
Iters = Cp#checkpoint_args.iterators,
- lists:foreach(fun(I) -> retainer_fixtable(I#iter.oid_tab, false) end, Iters).
+ [?SAFE(retainer_fixtable(Tab, false)) || #iter{main_tab=Tab} <- Iters],
+ ok.
deactivate_tab(R) ->
Name = R#retainer.cp_name,
@@ -1151,7 +1152,7 @@ do_change_copy(Cp, Tab, FromType, ToType) ->
Cp#checkpoint_args{retainers = Rs, nodes = writers(Rs)}.
check_iter(From, Iter) when Iter#iter.pid == From ->
- retainer_fixtable(Iter#iter.oid_tab, false),
+ ?SAFE(retainer_fixtable(Iter#iter.oid_tab, false)),
false;
check_iter(_From, _Iter) ->
true.
diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index 4791e2e290..6b93935cb4 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1703,9 +1703,10 @@ add_active_replica(Tab, Node, Cs = #cstruct{}) ->
block_table(Tab) ->
Var = {Tab, where_to_commit},
- Old = val(Var),
- New = {blocked, Old},
- set(Var, New). % where_to_commit
+ case is_tab_blocked(val(Var)) of
+ {true, _} -> ok;
+ {false, W2C} -> set(Var, mark_blocked_tab(true, W2C))
+ end.
unblock_table(Tab) ->
call({unblock_table, Tab}).
@@ -1887,7 +1888,7 @@ info_format(Tab, Size, Mem, Media) ->
StrT = mnesia_lib:pad_name(atom_to_list(Tab), 15, []),
StrS = mnesia_lib:pad_name(integer_to_list(Size), 8, []),
StrM = mnesia_lib:pad_name(integer_to_list(Mem), 8, []),
- io:format("~s: with ~s records occupying ~s ~s~n",
+ io:format("~ts: with ~s records occupying ~s ~s~n",
[StrT, StrS, StrM, Media]).
%% Handle early arrived messages
diff --git a/lib/mnesia/src/mnesia_event.erl b/lib/mnesia/src/mnesia_event.erl
index 7320d381ea..b06043bc61 100644
--- a/lib/mnesia/src/mnesia_event.erl
+++ b/lib/mnesia/src/mnesia_event.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -114,7 +114,8 @@ handle_table_event({Oper, Record, TransId}, State) ->
handle_system_event({mnesia_checkpoint_activated, _Checkpoint}, State) ->
{ok, State};
-handle_system_event({mnesia_checkpoint_deactivated, _Checkpoint}, State) ->
+handle_system_event({mnesia_checkpoint_deactivated, Checkpoint}, State) ->
+ report_error("Checkpoint '~p' has been deactivated, last table copy deleted.\n",[Checkpoint]),
{ok, State};
handle_system_event({mnesia_up, Node}, State) ->
diff --git a/lib/mnesia/src/mnesia_frag.erl b/lib/mnesia/src/mnesia_frag.erl
index c6e812b36d..c39f30e140 100644
--- a/lib/mnesia/src/mnesia_frag.erl
+++ b/lib/mnesia/src/mnesia_frag.erl
@@ -58,9 +58,7 @@
-include("mnesia.hrl").
--define(OLD_HASH_MOD, mnesia_frag_old_hash).
-define(DEFAULT_HASH_MOD, mnesia_frag_hash).
-%%-define(DEFAULT_HASH_MOD, ?OLD_HASH_MOD). %% BUGBUG: New should be default
-record(frag_state,
{foreign_key,
@@ -80,7 +78,7 @@
lock(ActivityId, Opaque, {table , Tab}, LockKind) ->
case frag_names(Tab) of
[Tab] ->
- mnesia:lock(ActivityId, Opaque, {table, Tab}, LockKind);
+ mnesia:lock(ActivityId, Opaque, {table, Tab}, LockKind);
Frags ->
DeepNs = [mnesia:lock(ActivityId, Opaque, {table, F}, LockKind) ||
F <- Frags],
@@ -321,7 +319,7 @@ init_select(Tid,Opaque,Tab,Pat,Limit,LockKind) ->
{'EXIT', _} ->
mnesia:select(Tid, Opaque, Tab, Pat, Limit,LockKind);
FH ->
- FragNumbers = verify_numbers(FH,Pat),
+ FragNumbers = verify_numbers(FH,Pat),
Fun = fun(Num) ->
Name = n_to_frag_name(Tab, Num),
Node = val({Name, where_to_read}),
@@ -336,19 +334,19 @@ init_select(Tid,Opaque,Tab,Pat,Limit,LockKind) ->
end.
select_cont(_Tid,_,{frag_cont, '$end_of_table', [],_}) -> '$end_of_table';
-select_cont(Tid,Ts,{frag_cont, '$end_of_table', [{Tab,Node,Type}|Rest],Args}) ->
+select_cont(Tid,Ts,{frag_cont, '$end_of_table', [{Tab,Node,Type}|Rest],Args}) ->
{Spec,LockKind,Limit} = Args,
InitFun = fun(FixedSpec) -> mnesia:dirty_sel_init(Node,Tab,FixedSpec,Limit,Type) end,
Res = mnesia:fun_select(Tid,Ts,Tab,Spec,LockKind,Tab,InitFun,Limit,Node,Type),
frag_sel_cont(Res, Rest, Args);
-select_cont(Tid,Ts,{frag_cont, Cont, TabL, Args}) ->
+select_cont(Tid,Ts,{frag_cont, Cont, TabL, Args}) ->
frag_sel_cont(mnesia:select_cont(Tid,Ts,Cont),TabL,Args);
select_cont(Tid,Ts,Else) -> %% Not a fragmented table
mnesia:select_cont(Tid,Ts,Else).
frag_sel_cont('$end_of_table', [],_) ->
'$end_of_table';
-frag_sel_cont('$end_of_table', TabL,Args) ->
+frag_sel_cont('$end_of_table', TabL,Args) ->
{[], {frag_cont, '$end_of_table', TabL,Args}};
frag_sel_cont({Recs,Cont}, TabL,Args) ->
{Recs, {frag_cont, Cont, TabL,Args}}.
@@ -358,9 +356,9 @@ do_select(ActivityId, Opaque, Tab, MatchSpec, LockKind) ->
{'EXIT', _} ->
mnesia:select(ActivityId, Opaque, Tab, MatchSpec, LockKind);
FH ->
- FragNumbers = verify_numbers(FH,MatchSpec),
+ FragNumbers = verify_numbers(FH,MatchSpec),
Fun = fun(Num) ->
- Name = n_to_frag_name(Tab, Num),
+ Name = n_to_frag_name(Tab, Num),
Node = val({Name, where_to_read}),
mnesia:lock(ActivityId, Opaque, {table, Name}, LockKind),
{Name, Node}
@@ -398,7 +396,7 @@ do_select(ActivityId, Opaque, Tab, MatchSpec, LockKind) ->
verify_numbers(FH,MatchSpec) ->
HashState = FH#frag_state.hash_state,
- FragNumbers =
+ FragNumbers =
case FH#frag_state.hash_module of
HashMod when HashMod == ?DEFAULT_HASH_MOD ->
?DEFAULT_HASH_MOD:match_spec_to_frag_numbers(HashState, MatchSpec);
@@ -434,7 +432,7 @@ local_select(ReplyTo, Ref, RemoteNameNodes, MatchSpec) ->
end,
unlink(ReplyTo),
exit(normal).
-
+
remote_select(ReplyTo, Ref, NameNodes, MatchSpec) ->
do_remote_select(ReplyTo, Ref, NameNodes, MatchSpec).
@@ -805,22 +803,22 @@ make_deactivate(Tab) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Add a fragment to a fragmented table and fill it with half of
%% the records from one of the old fragments
-
+
make_multi_add_frag(Tab, SortedNs) when is_list(SortedNs) ->
verify_multi(Tab),
Ops = make_add_frag(Tab, SortedNs),
%% Propagate to foreigners
MoreOps = [make_add_frag(T, SortedNs) || T <- lookup_foreigners(Tab)],
- [Ops | MoreOps];
+ [Ops | MoreOps];
make_multi_add_frag(Tab, SortedNs) ->
mnesia:abort({bad_type, Tab, SortedNs}).
verify_multi(Tab) ->
FH = lookup_frag_hash(Tab),
ForeignKey = FH#frag_state.foreign_key,
- mnesia_schema:verify(undefined, ForeignKey,
- {combine_error, Tab,
+ mnesia_schema:verify(undefined, ForeignKey,
+ {combine_error, Tab,
"Op only allowed via foreign table",
{foreign_key, ForeignKey}}).
@@ -839,7 +837,7 @@ make_frag_names_and_acquire_locks(Tab, N, FragIndecies, DoNotLockN) ->
end,
FragNames = erlang:make_tuple(N, undefined),
lists:foldl(Fun, FragNames, FragIndecies).
-
+
make_add_frag(Tab, SortedNs) ->
Cs = mnesia_schema:incr_version(val({Tab, cstruct})),
mnesia_schema:ensure_active(Cs),
@@ -849,8 +847,8 @@ make_add_frag(Tab, SortedNs) ->
FragNames = make_frag_names_and_acquire_locks(Tab, N, WriteIndecies, true),
NewFrag = element(N, FragNames),
- NR = length(Cs#cstruct.ram_copies),
- ND = length(Cs#cstruct.disc_copies),
+ NR = length(Cs#cstruct.ram_copies),
+ ND = length(Cs#cstruct.disc_copies),
NDO = length(Cs#cstruct.disc_only_copies),
NExt = length(Cs#cstruct.external_copies),
NewCs = Cs#cstruct{name = NewFrag,
@@ -859,7 +857,7 @@ make_add_frag(Tab, SortedNs) ->
disc_copies = [],
disc_only_copies = [],
external_copies = []},
-
+
{NewCs2, _, _} = set_frag_nodes(NR, ND, NDO, NExt, NewCs, SortedNs, []),
[NewOp] = mnesia_schema:make_create_table(NewCs2),
@@ -944,7 +942,7 @@ do_split(FH, OldN, FragNames, [Rec | Recs], Ops) ->
Key = element(2, Rec),
NewOid = {NewFrag, Key},
OldOid = {OldFrag, Key},
- Ops2 = [{op, rec, unknown, {NewOid, [Rec], write}},
+ Ops2 = [{op, rec, unknown, {NewOid, [Rec], write}},
{op, rec, unknown, {OldOid, [OldOid], delete}} | Ops],
do_split(FH, OldN, FragNames, Recs, Ops2);
_NewFrag ->
@@ -958,7 +956,7 @@ do_split(_FH, _OldN, _FragNames, [], Ops) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Delete a fragment from a fragmented table
%% and merge its records with another fragment
-
+
make_multi_del_frag(Tab) ->
verify_multi(Tab),
Ops = make_del_frag(Tab),
@@ -1064,7 +1062,7 @@ do_merge(FH, OldN, FragNames, [Rec | Recs], Ops) ->
Key = element(2, Rec),
NewOid = {NewFrag, Key},
OldOid = {OldFrag, Key},
- Ops2 = [{op, rec, unknown, {NewOid, [Rec], write}},
+ Ops2 = [{op, rec, unknown, {NewOid, [Rec], write}},
{op, rec, unknown, {OldOid, [OldOid], delete}} | Ops],
do_merge(FH, OldN, FragNames, Recs, Ops2);
_NewFrag ->
@@ -1077,7 +1075,7 @@ do_merge(FH, OldN, FragNames, [Rec | Recs], Ops) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Add a node to the node pool of a fragmented table
-
+
make_multi_add_node(Tab, Node) ->
verify_multi(Tab),
Ops = make_add_node(Tab, Node),
@@ -1085,7 +1083,7 @@ make_multi_add_node(Tab, Node) ->
%% Propagate to foreigners
MoreOps = [make_add_node(T, Node) || T <- lookup_foreigners(Tab)],
[Ops | MoreOps].
-
+
make_add_node(Tab, Node) when is_atom(Node) ->
Pool = lookup_prop(Tab, node_pool),
case lists:member(Node, Pool) of
@@ -1114,7 +1112,7 @@ make_multi_del_node(Tab, Node) ->
%% Propagate to foreigners
MoreOps = [make_del_node(T, Node) || T <- lookup_foreigners(Tab)],
[Ops | MoreOps].
-
+
make_del_node(Tab, Node) when is_atom(Node) ->
Cs = mnesia_schema:incr_version(val({Tab, cstruct})),
mnesia_schema:ensure_active(Cs),
@@ -1147,8 +1145,8 @@ remove_node(Node, Cs) ->
case lists:member(Node, Pool) of
true ->
Pool2 = Pool -- [Node],
- Props = lists:keyreplace(node_pool, 1,
- Cs#cstruct.frag_properties,
+ Props = lists:keyreplace(node_pool, 1,
+ Cs#cstruct.frag_properties,
{node_pool, Pool2}),
{Cs#cstruct{frag_properties = Props}, true};
false ->
@@ -1180,18 +1178,10 @@ props_to_frag_hash(Tab, Props) ->
T when T == Tab ->
Foreign = mnesia_schema:pick(Tab, foreign_key, Props, must),
N = mnesia_schema:pick(Tab, n_fragments, Props, must),
-
case mnesia_schema:pick(Tab, hash_module, Props, undefined) of
undefined ->
- Split = mnesia_schema:pick(Tab, next_n_to_split, Props, must),
- Doubles = mnesia_schema:pick(Tab, n_doubles, Props, must),
- FH = {frag_hash, Foreign, N, Split, Doubles},
- HashState = ?OLD_HASH_MOD:init_state(Tab, FH),
- #frag_state{foreign_key = Foreign,
- n_fragments = N,
- hash_module = ?OLD_HASH_MOD,
- hash_state = HashState};
- HashMod ->
+ no_hash;
+ HashMod ->
HashState = mnesia_schema:pick(Tab, hash_state, Props, must),
#frag_state{foreign_key = Foreign,
n_fragments = N,
@@ -1216,13 +1206,9 @@ lookup_frag_hash(Tab) ->
case ?catch_val({Tab, frag_hash}) of
FH when is_record(FH, frag_state) ->
FH;
- {frag_hash, K, N, _S, _D} = FH ->
+ {frag_hash, _K, _N, _S, _D} ->
%% Old style. Kept for backwards compatibility.
- HashState = ?OLD_HASH_MOD:init_state(Tab, FH),
- #frag_state{foreign_key = K,
- n_fragments = N,
- hash_module = ?OLD_HASH_MOD,
- hash_state = HashState};
+ mnesia:abort({no_hash, Tab, frag_properties, frag_hash});
{'EXIT', _} ->
mnesia:abort({no_exists, Tab, frag_properties, frag_hash})
end.
@@ -1249,10 +1235,10 @@ key_pos(FH) ->
case FH#frag_state.foreign_key of
undefined ->
2;
- {_ForeignTab, Pos} ->
+ {_ForeignTab, Pos} ->
Pos
end.
-
+
%% Returns name of fragment table
key_to_frag_name({BaseTab, _} = Tab, Key) ->
N = key_to_frag_number(Tab, Key),
diff --git a/lib/mnesia/src/mnesia_frag_old_hash.erl b/lib/mnesia/src/mnesia_frag_old_hash.erl
deleted file mode 100644
index b246c76236..0000000000
--- a/lib/mnesia/src/mnesia_frag_old_hash.erl
+++ /dev/null
@@ -1,133 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%%%----------------------------------------------------------------------
-%%% Purpose : Implements hashing functionality for fragmented tables
-%%%----------------------------------------------------------------------
-
--module(mnesia_frag_old_hash).
-%%-behaviour(mnesia_frag_hash).
-
--compile({nowarn_deprecated_function, {erlang,hash,2}}).
-
-%% Hashing callback functions
--export([
- init_state/2,
- add_frag/1,
- del_frag/1,
- key_to_frag_number/2,
- match_spec_to_frag_numbers/2
- ]).
-
--record(old_hash_state,
- {n_fragments,
- next_n_to_split,
- n_doubles}).
-
-%% Old style. Kept for backwards compatibility.
--record(frag_hash,
- {foreign_key,
- n_fragments,
- next_n_to_split,
- n_doubles}).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-init_state(_Tab, InitialState) when InitialState == undefined ->
- #old_hash_state{n_fragments = 1,
- next_n_to_split = 1,
- n_doubles = 0};
-init_state(_Tab, FH) when is_record(FH, frag_hash) ->
- %% Old style. Kept for backwards compatibility.
- #old_hash_state{n_fragments = FH#frag_hash.n_fragments,
- next_n_to_split = FH#frag_hash.next_n_to_split,
- n_doubles = FH#frag_hash.n_doubles}.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-add_frag(State) when is_record(State, old_hash_state) ->
- SplitN = State#old_hash_state.next_n_to_split,
- P = SplitN + 1,
- L = State#old_hash_state.n_doubles,
- NewN = State#old_hash_state.n_fragments + 1,
- State2 = case trunc(math:pow(2, L)) + 1 of
- P2 when P2 == P ->
- State#old_hash_state{n_fragments = NewN,
- next_n_to_split = 1,
- n_doubles = L + 1};
- _ ->
- State#old_hash_state{n_fragments = NewN,
- next_n_to_split = P}
- end,
- {State2, [SplitN], [NewN]}.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-del_frag(State) when is_record(State, old_hash_state) ->
- P = State#old_hash_state.next_n_to_split - 1,
- L = State#old_hash_state.n_doubles,
- N = State#old_hash_state.n_fragments,
- if
- P < 1 ->
- L2 = L - 1,
- MergeN = trunc(math:pow(2, L2)),
- State2 = State#old_hash_state{n_fragments = N - 1,
- next_n_to_split = MergeN,
- n_doubles = L2},
- {State2, [N], [MergeN]};
- true ->
- MergeN = P,
- State2 = State#old_hash_state{n_fragments = N - 1,
- next_n_to_split = MergeN},
- {State2, [N], [MergeN]}
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-key_to_frag_number(State, Key) when is_record(State, old_hash_state) ->
- L = State#old_hash_state.n_doubles,
- A = erlang:hash(Key, trunc(math:pow(2, L))),
- P = State#old_hash_state.next_n_to_split,
- if
- A < P ->
- erlang:hash(Key, trunc(math:pow(2, L + 1)));
- true ->
- A
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-match_spec_to_frag_numbers(State, MatchSpec) when is_record(State, old_hash_state) ->
- case MatchSpec of
- [{HeadPat, _, _}] when is_tuple(HeadPat), tuple_size(HeadPat) > 2 ->
- KeyPat = element(2, HeadPat),
- case has_var(KeyPat) of
- false ->
- [key_to_frag_number(State, KeyPat)];
- true ->
- lists:seq(1, State#old_hash_state.n_fragments)
- end;
- _ ->
- lists:seq(1, State#old_hash_state.n_fragments)
- end.
-
-has_var(Pat) ->
- mnesia:has_var(Pat).
diff --git a/lib/mnesia/src/mnesia_kernel_sup.erl b/lib/mnesia/src/mnesia_kernel_sup.erl
index c9af5c460a..a761d5eed0 100644
--- a/lib/mnesia/src/mnesia_kernel_sup.erl
+++ b/lib/mnesia/src/mnesia_kernel_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -43,7 +43,6 @@ init([]) ->
worker_spec(mnesia_recover, timer:minutes(3), [gen_server]),
worker_spec(mnesia_tm, timer:seconds(30), ProcLib),
supervisor_spec(mnesia_checkpoint_sup),
- supervisor_spec(mnesia_snmp_sup),
worker_spec(mnesia_controller, timer:seconds(3), [gen_server]),
worker_spec(mnesia_late_loader, timer:seconds(3), ProcLib)
],
diff --git a/lib/mnesia/src/mnesia_lib.erl b/lib/mnesia/src/mnesia_lib.erl
index 10e232c800..1fdc656600 100644
--- a/lib/mnesia/src/mnesia_lib.erl
+++ b/lib/mnesia/src/mnesia_lib.erl
@@ -1192,25 +1192,15 @@ db_select(Storage, Tab, Pat) ->
end.
db_select_init({ext, Alias, Mod}, Tab, Pat, Limit) ->
- case Mod:select(Alias, Tab, Pat, Limit) of
- {Matches, Continuation} when is_list(Matches) ->
- {Matches, {Alias, Continuation}};
- R ->
- R
- end;
+ Mod:select(Alias, Tab, Pat, Limit);
db_select_init(disc_only_copies, Tab, Pat, Limit) ->
dets:select(Tab, Pat, Limit);
db_select_init(_, Tab, Pat, Limit) ->
ets:select(Tab, Pat, Limit).
-db_select_cont({ext, Alias, Mod}, Cont0, Ms) ->
+db_select_cont({ext, _Alias, Mod}, Cont0, Ms) ->
Cont = Mod:repair_continuation(Cont0, Ms),
- case Mod:select(Cont) of
- {Matches, Continuation} when is_list(Matches) ->
- {Matches, {Alias, Continuation}};
- R ->
- R
- end;
+ Mod:select(Cont);
db_select_cont(disc_only_copies, Cont0, Ms) ->
Cont = dets:repair_continuation(Cont0, Ms),
dets:select(Cont);
diff --git a/lib/mnesia/src/mnesia_loader.erl b/lib/mnesia/src/mnesia_loader.erl
index 71e5829c87..c710470a2c 100644
--- a/lib/mnesia/src/mnesia_loader.erl
+++ b/lib/mnesia/src/mnesia_loader.erl
@@ -342,9 +342,12 @@ spawned_receiver(ReplyTo,Tab,Storage,Cs, SenderPid,TabSize,DetsData, Init) ->
Done = do_init_table(Tab,Storage,Cs,
SenderPid,TabSize,DetsData,
ReplyTo, Init),
- ReplyTo ! {self(),Done},
- unlink(ReplyTo),
- unlink(whereis(mnesia_controller)),
+ try
+ ReplyTo ! {self(),Done},
+ unlink(ReplyTo),
+ unlink(whereis(mnesia_controller))
+ catch _:_ -> ok %% avoid error reports when stopping down mnesia
+ end,
exit(normal).
wait_on_load_complete(Pid) ->
@@ -916,9 +919,15 @@ send_packet(_N, _Pid, _Chunk, DataState) ->
finish_copy(Pid, Tab, Storage, RemoteS, NeedLock) ->
RecNode = node(Pid),
DatBin = dat2bin(Tab, Storage, RemoteS),
+ Node = node(Pid),
Trans =
fun() ->
NeedLock andalso mnesia:read_lock_table(Tab),
+ %% Check that receiver is still alive
+ receive {copier_done, Node} ->
+ throw(receiver_died)
+ after 0 -> ok
+ end,
A = val({Tab, access_mode}),
mnesia_controller:sync_and_block_table_whereabouts(Tab, RecNode, RemoteS, A),
cleanup_tab_copier(Pid, Storage, Tab),
@@ -927,7 +936,7 @@ finish_copy(Pid, Tab, Storage, RemoteS, NeedLock) ->
receive
{Pid, no_more} -> % Dont bother about the spurious 'more' message
no_more;
- {copier_done, Node} when Node == node(Pid)->
+ {copier_done, Node} ->
verbose("Tab receiver ~p crashed (more): ~p~n", [Tab, Node]),
receiver_died
end
diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl
index ab78c9b13e..22a24b6dc9 100644
--- a/lib/mnesia/src/mnesia_monitor.erl
+++ b/lib/mnesia/src/mnesia_monitor.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -169,7 +169,7 @@ check_protocol([{Node, {accept, Mon, Version, Protocol}} | Tail], Protocols) ->
verbose("Failed to connect with ~p. ~p protocols rejected. "
"expected version = ~p, expected protocol = ~p~n",
[Node, Protocols, Version, Protocol]),
- unlink(Mon), % Get rid of unneccessary link
+ unlink(Mon), % Get rid of unnecessary link
check_protocol(Tail, Protocols)
end;
check_protocol([{Node, {reject, _Mon, Version, Protocol}} | Tail], Protocols) ->
diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl
index 0e4017e4c3..f71ee26d7c 100644
--- a/lib/mnesia/src/mnesia_schema.erl
+++ b/lib/mnesia/src/mnesia_schema.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -866,18 +866,18 @@ list2cs(List, ExtTypes) when is_list(List) ->
is_list(DetsOpts) orelse mnesia:abort({badarg, Name, {dets, DetsOpts}}),
[CheckProp(Prop, BadDetsOpts) || Prop <- DetsOpts],
- case lists:keymember(mnesia, 1, application:which_applications()) of
- true ->
- Keys = check_keys(Name, List),
- check_duplicates(Name, Keys);
- false ->
+ case whereis(mnesia_controller) of
+ undefined ->
%% check_keys/2 cannot be executed when mnesia is not
%% running, due to it not being possible to read what ext
%% backends are loaded.
- %%% this doesn't work - disabled for now:
- %%%Keys = check_keys(Name, List, record_info(fields, cstruct)),
- %%%check_duplicates(Name, Keys)
- ignore
+ %% this doesn't work - disabled for now:
+ %%Keys = check_keys(Name, List, record_info(fields, cstruct)),
+ %%check_duplicates(Name, Keys)
+ ignore;
+ Pid when is_pid(Pid) ->
+ Keys = check_keys(Name, List),
+ check_duplicates(Name, Keys)
end,
Cs0 = #cstruct{name = Name,
@@ -1941,7 +1941,7 @@ make_change_table_copy_type(Tab, Node, ToS) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% change index functions ....
-%% Pos is allready added by 1 in both of these functions
+%% Pos is already added by 1 in both of these functions
add_table_index(Tab, Pos) ->
schema_transaction(fun() -> do_add_table_index(Tab, Pos) end).
diff --git a/lib/mnesia/src/mnesia_snmp_sup.erl b/lib/mnesia/src/mnesia_snmp_sup.erl
deleted file mode 100644
index ed579d01c5..0000000000
--- a/lib/mnesia/src/mnesia_snmp_sup.erl
+++ /dev/null
@@ -1,43 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
--module(mnesia_snmp_sup).
-
--behaviour(supervisor).
-
--export([start/0, init/1]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% top supervisor callback functions
-
-start() ->
- supervisor:start_link({local, ?MODULE}, ?MODULE, []).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% sub supervisor callback functions
-
-init([]) ->
- Flags = {simple_one_for_one, 0, timer:hours(24)}, % Trust the top supervisor
- MFA = {mnesia_snmp_hook, start, []},
- Modules = [?MODULE, mnesia_snmp_hook, supervisor],
- KillAfter = mnesia_kernel_sup:supervisor_timeout(timer:seconds(3)),
- Workers = [{?MODULE, MFA, transient, KillAfter, worker, Modules}],
- {ok, {Flags, Workers}}.
diff --git a/lib/mnesia/src/mnesia_sup.erl b/lib/mnesia/src/mnesia_sup.erl
index 4aece81308..3e5792900b 100644
--- a/lib/mnesia/src/mnesia_sup.erl
+++ b/lib/mnesia/src/mnesia_sup.erl
@@ -23,39 +23,21 @@
-module(mnesia_sup).
--behaviour(application).
-behaviour(supervisor).
--export([start/0, start/2, init/1, stop/1, start_event/0, kill/0]).
+-export([start_link/1, init/1, start_event/0, kill/0]).
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% application and suprvisor callback functions
-
-start(normal, Args) ->
- SupName = {local,?MODULE},
- case supervisor:start_link(SupName, ?MODULE, [Args]) of
- {ok, Pid} ->
- {ok, Pid, {normal, Args}};
- Error ->
- Error
- end;
-start(_, _) ->
- {error, badarg}.
-
-start() ->
- SupName = {local,?MODULE},
- supervisor:start_link(SupName, ?MODULE, []).
+start_link(Args) ->
+ supervisor:start_link({local,?MODULE}, ?MODULE, [Args]).
-stop(_StartArgs) ->
- ok.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% supervisor callback functions
-init([]) -> % Supervisor
- init();
-init([[]]) -> % Application
+init([[]]) ->
init();
init(BadArg) ->
{error, {badarg, BadArg}}.
-
+
init() ->
Flags = {one_for_all, 0, 3600}, % Should be rest_for_one policy
@@ -124,4 +106,3 @@ ensure_dead(Name) ->
timer:sleep(10),
ensure_dead(Name)
end.
-
diff --git a/lib/mnesia/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl
index b116b48312..305bf14bcf 100644
--- a/lib/mnesia/src/mnesia_tm.erl
+++ b/lib/mnesia/src/mnesia_tm.erl
@@ -80,6 +80,7 @@ start() ->
init(Parent) ->
register(?MODULE, self()),
process_flag(trap_exit, true),
+ process_flag(message_queue_data, off_heap),
%% Initialize the schema
IgnoreFallback = mnesia_monitor:get_env(ignore_fallback_at_startup),
@@ -950,7 +951,7 @@ return_abort(Fun, Args, Reason) ->
if
Level == 1 ->
mnesia_locker:async_release_tid(Nodes, Tid),
- ?MODULE ! {delete_transaction, Tid},
+ ?SAFE(?MODULE ! {delete_transaction, Tid}),
erase(mnesia_activity_state),
flush_downs(),
?SAFE(unlink(whereis(?MODULE))),
diff --git a/lib/mnesia/test/ext_test.erl b/lib/mnesia/test/ext_test.erl
index 45ddb148bc..ad32245a11 100644
--- a/lib/mnesia/test/ext_test.erl
+++ b/lib/mnesia/test/ext_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -233,5 +233,5 @@ select_1({Acc, C}) ->
select(ext_ets, Tab, Ms, Limit) when is_integer(Limit); Limit =:= infinity ->
ets:select(mnesia_lib:val({?MODULE,Tab}), Ms, Limit).
-repair_continuation({Alias, Cont}, Ms) ->
- {Alias, ets:repair_continuation(Cont, Ms)}.
+repair_continuation(Cont, Ms) ->
+ ets:repair_continuation(Cont, Ms).
diff --git a/lib/mnesia/test/mnesia_evil_backup.erl b/lib/mnesia/test/mnesia_evil_backup.erl
index e745ec9b04..0fa72c4305 100644
--- a/lib/mnesia/test/mnesia_evil_backup.erl
+++ b/lib/mnesia/test/mnesia_evil_backup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -723,18 +723,18 @@ bup_records(File, Mod) ->
exit(Reason)
end.
-sops_with_checkpoint(doc) ->
+sops_with_checkpoint(doc) ->
["Test schema operations during a checkpoint"];
sops_with_checkpoint(suite) -> [];
sops_with_checkpoint(Config) when is_list(Config) ->
- Ns = ?acquire_nodes(2, Config),
-
+ Ns = [N1,N2] = ?acquire_nodes(2, Config),
+
?match({ok, cp1, Ns}, mnesia:activate_checkpoint([{name, cp1},{max,mnesia:system_info(tables)}])),
- Tab = tab,
+ Tab = tab,
?match({atomic, ok}, mnesia:create_table(Tab, [{disc_copies,Ns}])),
OldRecs = [{Tab, K, -K} || K <- lists:seq(1, 5)],
[mnesia:dirty_write(R) || R <- OldRecs],
-
+
?match({ok, cp2, Ns}, mnesia:activate_checkpoint([{name, cp2},{max,mnesia:system_info(tables)}])),
File1 = "cp1_delete_me.BUP",
?match(ok, mnesia:dirty_write({Tab,6,-6})),
@@ -742,16 +742,16 @@ sops_with_checkpoint(Config) when is_list(Config) ->
?match(ok, mnesia:dirty_write({Tab,7,-7})),
File2 = "cp2_delete_me.BUP",
?match(ok, mnesia:backup_checkpoint(cp2, File2)),
-
+
?match(ok, mnesia:deactivate_checkpoint(cp1)),
?match(ok, mnesia:backup_checkpoint(cp2, File1)),
?match(ok, mnesia:dirty_write({Tab,8,-8})),
-
+
?match({atomic,ok}, mnesia:delete_table(Tab)),
?match({error,_}, mnesia:backup_checkpoint(cp2, File2)),
?match({'EXIT',_}, mnesia:dirty_write({Tab,9,-9})),
- ?match({atomic,_}, mnesia:restore(File1, [{default_op, recreate_tables}])),
+ ?match({atomic,_}, mnesia:restore(File1, [{default_op, recreate_tables}])),
Test = fun(N) when N > 5 -> ?error("To many records in backup ~p ~n", [N]);
(N) -> case mnesia:dirty_read(Tab,N) of
[{Tab,N,B}] when -B =:= N -> ok;
@@ -759,8 +759,29 @@ sops_with_checkpoint(Config) when is_list(Config) ->
end
end,
[Test(N) || N <- mnesia:dirty_all_keys(Tab)],
- ?match({aborted,enoent}, mnesia:restore(File2, [{default_op, recreate_tables}])),
-
+ ?match({aborted,enoent}, mnesia:restore(File2, [{default_op, recreate_tables}])),
+
+ %% Mnesia crashes when deleting a table during backup
+ ?match([], mnesia_test_lib:stop_mnesia([N2])),
+ Tab2 = ram,
+ ?match({atomic, ok}, mnesia:create_table(Tab2, [{ram_copies,[N1]}])),
+ ?match({ok, cp3, _}, mnesia:activate_checkpoint([{name, cp3},
+ {ram_overrides_dump,true},
+ {min,[Tab2]}])),
+ Write = fun Loop (N) ->
+ case N > 0 of
+ true ->
+ mnesia:dirty_write({Tab2, N+100, N+100}),
+ Loop(N-1);
+ false ->
+ ok
+ end
+ end,
+ ok = Write(100000),
+ spawn_link(fun() -> ?match({atomic, ok},mnesia:delete_table(Tab2)) end),
+
+ %% We don't check result here, depends on timing of above call
+ mnesia:backup_checkpoint(cp3, File2),
file:delete(File1), file:delete(File2),
- ?verify_mnesia(Ns, []).
+ ?verify_mnesia([N1], [N2]).
diff --git a/lib/mnesia/test/mnesia_test_lib.erl b/lib/mnesia/test/mnesia_test_lib.erl
index 6e84a27ec9..0fabdc7929 100644
--- a/lib/mnesia/test/mnesia_test_lib.erl
+++ b/lib/mnesia/test/mnesia_test_lib.erl
@@ -263,6 +263,7 @@ slave_start_link(Host, Name, Retries) ->
Path = code:get_path(),
ok = rpc:call(NewNode, file, set_cwd, [Cwd]),
true = rpc:call(NewNode, code, set_path, [Path]),
+ ok = rpc:call(NewNode, error_logger, tty, [false]),
spawn_link(NewNode, ?MODULE, slave_sup, []),
rpc:multicall([node() | nodes()], global, sync, []),
{ok, NewNode};
diff --git a/lib/mnesia/test/mnesia_trans_access_test.erl b/lib/mnesia/test/mnesia_trans_access_test.erl
index aa50ee4cb1..4ed73ea859 100644
--- a/lib/mnesia/test/mnesia_trans_access_test.erl
+++ b/lib/mnesia/test/mnesia_trans_access_test.erl
@@ -307,6 +307,7 @@ select14(Config) when is_list(Config) ->
%% Some Helpers
Trans = fun(Fun) -> mnesia:transaction(Fun) end,
+ Dirty = fun(Fun) -> mnesia:async_dirty(Fun) end,
LoopHelp = fun('$end_of_table',_) -> [];
({Recs,Cont},Fun) ->
Sel = mnesia:select(Cont),
@@ -334,8 +335,13 @@ select14(Config) when is_list(Config) ->
?match({atomic, [OneRec]}, Trans(fun() -> Loop(Tab, OnePat) end)),
?match({atomic, All}, Trans(fun() -> Loop(Tab, AllPat) end)),
- {atomic,{_, Cont}} = Trans(fun() -> mnesia:select(Tab, OnePat, 1, read) end),
- ?match({aborted, wrong_transaction}, Trans(fun() -> mnesia:select(Cont) end)),
+ {atomic,{_, ContOne}} = Trans(fun() -> mnesia:select(Tab, OnePat, 1, read) end),
+ ?match({aborted, wrong_transaction}, Trans(fun() -> mnesia:select(ContOne) end)),
+ ?match('$end_of_table', Dirty(fun() -> mnesia:select(ContOne) end)),
+
+ {atomic,{_, ContAll}} = Trans(fun() -> mnesia:select(Tab, AllPat, 1, read) end),
+ ?match({aborted, wrong_transaction}, Trans(fun() -> mnesia:select(ContAll) end)),
+ ?match({[_], _}, Dirty(fun() -> mnesia:select(ContAll) end)),
?match({aborted, _}, Trans(fun() -> mnesia:select(Tab, {match, '$1', 2},1,read) end)),
?match({aborted, _}, Trans(fun() -> mnesia:select(Tab, [{'_', [], '$1'}],1,read) end)),
diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk
index fb4200f62d..81b15d65db 100644
--- a/lib/mnesia/vsn.mk
+++ b/lib/mnesia/vsn.mk
@@ -1 +1 @@
-MNESIA_VSN = 4.14
+MNESIA_VSN = 4.15
diff --git a/lib/observer/doc/src/etop.xml b/lib/observer/doc/src/etop.xml
index d70d9d1d23..e7a83d0514 100644
--- a/lib/observer/doc/src/etop.xml
+++ b/lib/observer/doc/src/etop.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2002</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -35,7 +35,7 @@
<file></file>
</header>
<module>etop</module>
- <modulesummary>Erlang Top is a tool for presenting information about Erlang
+ <modulesummary>Erlang Top is a tool for presenting information about Erlang
processes similar to the information presented by "top" in UNIX.</modulesummary>
<description>
@@ -60,11 +60,11 @@
<p>Value: <c>atom()</c></p>
<p>Mandatory</p></item>
<tag><c>setcookie</c></tag>
- <item><p>Cookie to use for the <c>etop</c> node. Must be same as the
+ <item><p>Cookie to use for the <c>etop</c> node. Must be same as the
cookie on the measured node.</p>
<p>Value: <c>atom()</c></p></item>
<tag><c>lines</c></tag>
- <item><p>Number of lines (processes) to display.</p>
+ <item><p>Number of lines (processes) to display.</p>
<p>Value: <c>integer()</c></p>
<p>Default: <c>10</c></p></item>
<tag><c>interval</c></tag>
@@ -92,7 +92,7 @@
<p>Default: <c>on</c></p></item>
</taglist>
- <p>For detalis about Erlang Top, see the
+ <p>For details about Erlang Top, see the
<seealso marker="etop_ug">User's Guide</seealso>.</p>
</description>
diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml
index 505d0dcc89..d329be5d5a 100644
--- a/lib/observer/doc/src/notes.xml
+++ b/lib/observer/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,6 +32,191 @@
<p>This document describes the changes made to the Observer
application.</p>
+<section><title>Observer 2.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ <c>etop</c> had a hardcoded timeout value of 1 second
+ when waiting for data from a remote node. When this
+ expired, which could happen for instance if there were
+ very many processes on the remote node, etop would exit
+ with reason <c>connection_lost</c>. To overcome this
+ problem, the timeout is now changed to be the same as the
+ update interval, which is configurable.</p>
+ <p>
+ Own Id: OTP-14393</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Show dirty-scheduler threads in performance monitor graph
+ and add a column with maximum allocated memory in the
+ Memory Allocators table.</p>
+ <p>
+ Own Id: OTP-14137</p>
+ </item>
+ <item>
+ <p>
+ Keep table and port selection after refresh of tables.
+ Store settings before shutdown and restore when starting
+ application.</p>
+ <p>
+ Own Id: OTP-14270</p>
+ </item>
+ <item>
+ <p> Miscellaneous updates due to atoms containing
+ arbitrary Unicode characters. </p>
+ <p>
+ Own Id: OTP-14285</p>
+ </item>
+ <item>
+ <p>
+ When observing a node older than OTP-19.0, a pop-up will
+ be displayed when trying to access port information.
+ Earlier, observer would crash in this situation.</p>
+ <p>
+ Own Id: OTP-14345 Aux Id: ERL-399 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Observer 2.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ etop erroneously reported the average scheduler
+ utilization since the tool was first started instead of
+ the scheduler utilization since last update. This is now
+ corrected.</p>
+ <p>
+ Own Id: OTP-14090 Aux Id: seq13232 </p>
+ </item>
+ <item>
+ <p>
+ crashdump_viewer crashed when the 'Slogan' had more than
+ one line. This is now corrected.</p>
+ <p>
+ Own Id: OTP-14093 Aux Id: ERL-318 </p>
+ </item>
+ <item>
+ <p>
+ When clicking an HTML-link to a port before the port tab
+ has been opened for the first time, observer would crash
+ since port info is not initiated. This is now corrected.</p>
+ <p>
+ Own Id: OTP-14151 Aux Id: PR-1296 </p>
+ </item>
+ <item>
+ <p>The dialyzer and observer applications will now use a
+ portable way to find the home directory. That means that
+ there is no longer any need to manually set the HOME
+ environment variable on Windows.</p>
+ <p>
+ Own Id: OTP-14249 Aux Id: ERL-161 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Observer 2.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The shell script (priv/bin/cdv) and bat file
+ (priv/bin/cdv.bat) which can be used for starting
+ crashdump_viewer both started a distributed erlang node.
+ This would cause any attempt at starting a second
+ instance of the crashdump_viewer to fail. To solve this
+ problem, cdv and cdv.bat now use non-distributed nodes
+ when starting the crashdump_viewer.</p>
+ <p>
+ Own Id: OTP-14010</p>
+ </item>
+ <item>
+ <p>
+ A bug caused the number of buckets to be shown in the
+ 'Objects' column, and the number of objects to be shown
+ in the 'Memory' column for ets table in crashdump_viewer.
+ This is now corrected.</p>
+ <p>
+ Own Id: OTP-14064</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add option <c>queue_size</c> to ttb:tracer/2. This sets
+ the maximum queue size for the IP trace driver which is
+ used when tracing to shell and/or <c>{local,File}</c>.</p>
+ <p>
+ The default value for <c>queue_size</c> is specified by
+ <c>dbg</c>, and it is now changed from 50 to 200.</p>
+ <p>
+ Own Id: OTP-13829 Aux Id: seq13171 </p>
+ </item>
+ <item>
+ <p>
+ The port information page is updated to show more
+ information per port.</p>
+ <p>
+ Own Id: OTP-13948 Aux Id: ERL-272 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Observer 2.2.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed error handling in observer when mnesia tables was
+ requested and not available.</p>
+ <p>
+ Own Id: OTP-13845 Aux Id: ERL-237 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Observer 2.2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a crash happening when observing another node, who
+ have a different number of schedulers than the current
+ one.</p>
+ <p>
+ Own Id: OTP-13702 Aux Id: ERL-171 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Observer 2.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/observer/doc/src/observer.xml b/lib/observer/doc/src/observer.xml
index 4d43ffe39f..843be26ee1 100644
--- a/lib/observer/doc/src/observer.xml
+++ b/lib/observer/doc/src/observer.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2011</year><year>2016</year>
+ <year>2011</year><year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -43,7 +43,7 @@
<seealso marker="ttb"><c>ttb</c></seealso>.
</p>
- <p>For detalis about how to get started, see the
+ <p>For details about how to get started, see the
<seealso marker="observer_ug"><c>User's Guide</c></seealso>.</p>
</description>
<funcs>
diff --git a/lib/observer/doc/src/observer_ug.xml b/lib/observer/doc/src/observer_ug.xml
index 6eb72f3e58..c9204f2bbe 100644
--- a/lib/observer/doc/src/observer_ug.xml
+++ b/lib/observer/doc/src/observer_ug.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2011</year><year>2016</year>
+ <year>2011</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -107,6 +107,11 @@
see module
<seealso marker="erts:erts_alloc"><c>erts_alloc</c></seealso>
in application ERTS.</p>
+ <p>The <c>Max Carrier size</c> column shows the maximum value seen by observer
+ since the last node change or since the start of the application, i.e. switching
+ nodes will reset the max column. Values are sampled so higher values may have
+ existed than what is shown.
+ </p>
</section>
<section>
diff --git a/lib/observer/doc/src/ttb.xml b/lib/observer/doc/src/ttb.xml
index 94ecef24b4..7cd15e15d3 100644
--- a/lib/observer/doc/src/ttb.xml
+++ b/lib/observer/doc/src/ttb.xml
@@ -114,7 +114,8 @@ ttb:p(all, call).</input></pre>
<v>Opt = {file,Client} | {handler, FormatHandler} | {process_info,PI} |
shell | {shell, ShellSpec} | {timer, TimerSpec} |
{overload_check, {MSec, Module, Function}} |
- {flush, MSec} | resume | {resume, FetchTimeout}</v>
+ {flush, MSec} | resume | {resume, FetchTimeout} |
+ {queue_size, QueueSize}</v>
<v>TimerSpec = MSec | {MSec, StopOpts}</v>
<v>MSec = FetchTimeout = integer()</v>
<v>Module = Function = atom() </v>
@@ -126,6 +127,7 @@ ttb:p(all, call).</input></pre>
<v>FormatHandler = See format/2</v>
<v>PI = true | false </v>
<v>ShellSpec = true | false | only</v>
+ <v>QueueSize = non_neg_integer()</v>
</type>
<desc>
<p>Starts a file trace port on all specified nodes
@@ -147,6 +149,18 @@ ttb:p(all, call).</input></pre>
<c>Client</c> must be <c>{local, File}</c>. All
trace information is then sent to the trace control node where
it is written to file.</p></item>
+ <tag><c>queue_size</c></tag>
+ <item><p>When tracing to shell or <c>{local,File}</c>, an ip
+ trace driver is used internally. The ip trace driver has a
+ queue of maximum <c>QueueSize</c> messages waiting to be
+ delivered. If the driver cannot deliver messages as fast as
+ they are produced, the queue size might be exceeded and
+ messages are dropped. This parameter is optional, and is
+ only useful if many <c>{drop,N}</c> trace messages are
+ received by the trace handler. It has no meaning if shell
+ or <c>{local,File}</c> is not used. See
+ <seealso marker="runtime_tools:dbg#trace_port/2">dbg:trace_port/2</seealso>
+ for more information about the ip trace driver.</p></item>
<tag><c>process_info</c></tag>
<item><p>Indicates if process
information is to be collected. If <c>PI = true</c> (which is
@@ -485,7 +499,7 @@ ttb:p(all, call).</input></pre>
<p>For a description of the <c>match_spec()</c> syntax,
see section
<seealso marker="erts:match_spec"><c>Match Specifications in Erlang</c></seealso>
- in <c>ERTS</c>, which explains the general match specification "language".
+ in ERTS, which explains the general match specification "language".
</p>
<note>
<p>The <em>system tracer</em> for sequential tracing is
diff --git a/lib/observer/priv/bin/cdv b/lib/observer/priv/bin/cdv
index 1c44785ac2..d14fd47e41 100755
--- a/lib/observer/priv/bin/cdv
+++ b/lib/observer/priv/bin/cdv
@@ -1,4 +1,4 @@
#!/bin/sh
-erl -sname cdv -noinput -s crashdump_viewer script_start $@
+erl -noinput -s crashdump_viewer script_start $@
diff --git a/lib/observer/priv/bin/cdv.bat b/lib/observer/priv/bin/cdv.bat
index efa8bf8687..18136a30d6 100644
--- a/lib/observer/priv/bin/cdv.bat
+++ b/lib/observer/priv/bin/cdv.bat
@@ -1,2 +1,2 @@
@ECHO OFF
-CALL werl -sname cdv -s crashdump_viewer script_start %*
+CALL werl -s crashdump_viewer script_start %*
diff --git a/lib/observer/priv/crashdump_viewer.tool b/lib/observer/priv/crashdump_viewer.tool
deleted file mode 100644
index b6bd6bbdef..0000000000
--- a/lib/observer/priv/crashdump_viewer.tool
+++ /dev/null
@@ -1,2 +0,0 @@
-{version,"1.2"}.
-[{config_func,{crashdump_viewer,configData,[]}}].
diff --git a/lib/observer/priv/crashdump_viewer/collapsd.gif b/lib/observer/priv/crashdump_viewer/collapsd.gif
deleted file mode 100644
index 0b90c08a9a..0000000000
--- a/lib/observer/priv/crashdump_viewer/collapsd.gif
+++ /dev/null
Binary files differ
diff --git a/lib/observer/priv/crashdump_viewer/exploded.gif b/lib/observer/priv/crashdump_viewer/exploded.gif
deleted file mode 100644
index e3ab5ca2e9..0000000000
--- a/lib/observer/priv/crashdump_viewer/exploded.gif
+++ /dev/null
Binary files differ
diff --git a/lib/observer/src/Makefile b/lib/observer/src/Makefile
index dd7831fa2b..ff2bcbdb99 100644
--- a/lib/observer/src/Makefile
+++ b/lib/observer/src/Makefile
@@ -92,7 +92,7 @@ EXAMPLE_FILES= multitrace.erl
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
PRIVDIR= ../priv
-WEBTOOLFILES= $(PRIVDIR)/crashdump_viewer.tool $(PRIVDIR)/erlang_observer.png
+PNGFILES= $(PRIVDIR)/erlang_observer.png
BINDIR= $(PRIVDIR)/bin
ifeq ($(findstring win32,$(TARGET)),win32)
WIN32_EXECUTABLES= $(BINDIR)/etop.bat $(BINDIR)/cdv.bat
@@ -103,10 +103,6 @@ EXECUTABLES= \
$(BINDIR)/etop \
$(BINDIR)/cdv \
$(WIN32_EXECUTABLES)
-CDVDIR= $(PRIVDIR)/crashdump_viewer
-GIF_FILES= \
- $(CDVDIR)/collapsd.gif \
- $(CDVDIR)/exploded.gif
APP_FILE= observer.app
@@ -163,9 +159,7 @@ release_spec: opt
$(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin"
$(INSTALL_DIR) "$(RELSYSDIR)/priv/bin"
$(INSTALL_SCRIPT) $(EXECUTABLES) "$(RELSYSDIR)/priv/bin"
- $(INSTALL_DIR) "$(RELSYSDIR)/priv/crashdump_viewer"
- $(INSTALL_DATA) $(WEBTOOLFILES) "$(RELSYSDIR)/priv"
- $(INSTALL_DATA) $(GIF_FILES) "$(RELSYSDIR)/priv/crashdump_viewer"
+ $(INSTALL_DATA) $(PNGFILES) "$(RELSYSDIR)/priv"
release_docs_spec:
diff --git a/lib/observer/src/cdv_bin_cb.erl b/lib/observer/src/cdv_bin_cb.erl
index 0cea1fdcf0..5472d36a6f 100644
--- a/lib/observer/src/cdv_bin_cb.erl
+++ b/lib/observer/src/cdv_bin_cb.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -58,7 +58,7 @@ binary_to_term_fun(Bin) ->
try binary_to_term(Bin) of
Term -> plain_html(io_lib:format("~p",[Term]))
catch error:badarg ->
- Warning = "This binary can not be coverted to an Erlang term",
+ Warning = "This binary can not be converted to an Erlang term",
observer_html_lib:warning(Warning)
end
end.
diff --git a/lib/observer/src/cdv_detail_wx.erl b/lib/observer/src/cdv_detail_wx.erl
index 44f121f359..27057fd27f 100644
--- a/lib/observer/src/cdv_detail_wx.erl
+++ b/lib/observer/src/cdv_detail_wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -55,7 +55,7 @@ init([Id, Data, ParentFrame, Callback, Parent]) ->
end,
{stop,normal};
{info,Info} ->
- observer_lib:display_info_dialog(Info),
+ observer_lib:display_info_dialog(ParentFrame,Info),
{stop,normal}
end.
diff --git a/lib/observer/src/cdv_ets_cb.erl b/lib/observer/src/cdv_ets_cb.erl
index 52a90b093b..a652729ed3 100644
--- a/lib/observer/src/cdv_ets_cb.erl
+++ b/lib/observer/src/cdv_ets_cb.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -30,34 +30,26 @@
-include("crashdump_viewer.hrl").
%% Defines
--define(COL_ID, 0).
--define(COL_NAME, ?COL_ID+1).
--define(COL_SLOT, ?COL_NAME+1).
--define(COL_OWNER, ?COL_SLOT+1).
--define(COL_BUCK, ?COL_OWNER+1).
--define(COL_OBJ, ?COL_BUCK+1).
+-define(COL_NAME, 0).
+-define(COL_IS_NAMED, ?COL_NAME+1).
+-define(COL_OWNER, ?COL_IS_NAMED+1).
+-define(COL_OBJ, ?COL_OWNER+1).
-define(COL_MEM, ?COL_OBJ+1).
--define(COL_TYPE, ?COL_MEM+1).
%% Callbacks for cdv_virtual_list_wx
-col_to_elem(id) -> col_to_elem(?COL_ID);
-col_to_elem(?COL_ID) -> #ets_table.id;
+col_to_elem(id) -> col_to_elem(?COL_NAME);
+col_to_elem(?COL_IS_NAMED) -> #ets_table.is_named;
col_to_elem(?COL_NAME) -> #ets_table.name;
-col_to_elem(?COL_SLOT) -> #ets_table.slot;
col_to_elem(?COL_OWNER) -> #ets_table.pid;
-col_to_elem(?COL_TYPE) -> #ets_table.data_type;
-col_to_elem(?COL_BUCK) -> #ets_table.buckets;
col_to_elem(?COL_OBJ) -> #ets_table.size;
col_to_elem(?COL_MEM) -> #ets_table.memory.
col_spec() ->
- [{"Id", ?wxLIST_FORMAT_LEFT, 200},
- {"Name", ?wxLIST_FORMAT_LEFT, 200},
- {"Slot", ?wxLIST_FORMAT_RIGHT, 50},
+ [{"Name", ?wxLIST_FORMAT_LEFT, 200},
+ {"Is Named", ?wxLIST_FORMAT_CENTRE, 70},
{"Owner", ?wxLIST_FORMAT_CENTRE, 120},
{"Objects", ?wxLIST_FORMAT_RIGHT, 80},
{"Memory", ?wxLIST_FORMAT_RIGHT, 80}
-% {"Type", ?wxLIST_FORMAT_LEFT, 50}
].
get_info(Owner) ->
@@ -73,7 +65,7 @@ get_details(Id, Data) ->
{ok,{"Table:" ++ Id,Proplist,""}}.
get_detail_cols(all) ->
- {[{ets, ?COL_ID}, {process, ?COL_OWNER}],true};
+ {[{ets, ?COL_NAME}, {process, ?COL_OWNER}],true};
get_detail_cols(_W) ->
{[],true}.
diff --git a/lib/observer/src/cdv_mem_cb.erl b/lib/observer/src/cdv_mem_cb.erl
index ba972d6963..abeddc7335 100644
--- a/lib/observer/src/cdv_mem_cb.erl
+++ b/lib/observer/src/cdv_mem_cb.erl
@@ -77,6 +77,10 @@ fix_alloc([{Title,Columns,Data}|Tables]) ->
fix_alloc(Tables)];
fix_alloc([{Title,[{_,V}|_]=Data}|Tables]) ->
fix_alloc([{Title,lists:duplicate(length(V),[]),Data}|Tables]);
+fix_alloc([{"",[]}|Tables]) -> % no name and no data, probably truncated dump
+ fix_alloc(Tables);
+fix_alloc([{Title,[]=Data}|Tables]) -> % no data, probably truncated dump
+ fix_alloc([{Title,[],Data}|Tables]);
fix_alloc([]) ->
[].
diff --git a/lib/observer/src/cdv_wx.erl b/lib/observer/src/cdv_wx.erl
index 2587a6e64e..1e3fb6289e 100644
--- a/lib/observer/src/cdv_wx.erl
+++ b/lib/observer/src/cdv_wx.erl
@@ -17,7 +17,7 @@
%%
%% %CopyrightEnd%
-module(cdv_wx).
--compile(export_all).
+
-behaviour(wx_object).
-export([start/1]).
diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl
index 9268dac180..8d70f5e2c8 100644
--- a/lib/observer/src/crashdump_viewer.erl
+++ b/lib/observer/src/crashdump_viewer.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -90,6 +90,7 @@
%% All possible tags - use macros in order to avoid misspelling in the code
+-define(abort,abort).
-define(allocated_areas,allocated_areas).
-define(allocator,allocator).
-define(atoms,atoms).
@@ -321,8 +322,16 @@ handle_call(general_info,_From,State=#state{file=File}) ->
NumAtoms = GenInfo#general_info.num_atoms,
WS = parse_vsn_str(GenInfo#general_info.system_vsn,4),
TW = case get(truncated) of
- true -> ["WARNING: The crash dump is truncated. "
- "Some information might be missing."];
+ true ->
+ case get(truncated_reason) of
+ undefined ->
+ ["WARNING: The crash dump is truncated. "
+ "Some information might be missing."];
+ Reason ->
+ ["WARNING: The crash dump is truncated "
+ "("++Reason++"). "
+ "Some information might be missing."]
+ end;
false -> []
end,
ets:insert(cdv_reg_proc_table,
@@ -515,8 +524,15 @@ truncated_warning([Tag|Tags]) ->
false -> truncated_warning(Tags)
end.
truncated_warning() ->
- ["WARNING: The crash dump is truncated here. "
- "Some information might be missing."].
+ case get(truncated_reason) of
+ undefined ->
+ ["WARNING: The crash dump is truncated here. "
+ "Some information might be missing."];
+ Reason ->
+ ["WARNING: The crash dump is truncated here "
+ "("++Reason++"). "
+ "Some information might be missing."]
+ end.
truncated_here(Tag) ->
case get(truncated) of
@@ -692,6 +708,7 @@ val(Fd, NoExist) ->
{eof,[]} -> NoExist;
[] -> NoExist;
{eof,Val} -> Val;
+ "=abort:"++_ -> NoExist;
Val -> Val
end.
@@ -787,7 +804,7 @@ do_read_file(File) ->
?erl_crash_dump ->
reset_index_table(),
insert_index(Tag,Id,N1+1),
- put(last_tag,{Tag,""}),
+ put_last_tag(Tag,""),
indexify(Fd,Rest,N1),
end_progress(),
check_if_truncated(),
@@ -831,7 +848,7 @@ indexify(Fd,Bin,N) ->
<<_:Pos/binary,TagAndRest/binary>> = Bin,
{Tag,Id,Rest,N1} = tag(Fd,TagAndRest,N+Pos),
insert_index(Tag,Id,N1+1), % +1 to get past newline
- put(last_tag,{Tag,Id}),
+ put_last_tag(Tag,Id),
indexify(Fd,Rest,N1);
nomatch ->
case progress_read(Fd) of
@@ -911,7 +928,10 @@ general_info(File) ->
WholeLine -> WholeLine
end,
- GI = get_general_info(Fd,#general_info{created=Created}),
+ {Slogan,SysVsn} = get_slogan_and_sysvsn(Fd,[]),
+ GI = get_general_info(Fd,#general_info{created=Created,
+ slogan=Slogan,
+ system_vsn=SysVsn}),
{MemTot,MemMax} =
case lookup_index(?memory) of
@@ -965,12 +985,20 @@ general_info(File) ->
mem_max=MemMax,
instr_info=InstrInfo}.
+get_slogan_and_sysvsn(Fd,Acc) ->
+ case val(Fd,eof) of
+ "Slogan: " ++ SloganPart when Acc==[] ->
+ get_slogan_and_sysvsn(Fd,[SloganPart]);
+ "System version: " ++ SystemVsn ->
+ {lists:append(lists:reverse(Acc)),SystemVsn};
+ eof ->
+ {lists:append(lists:reverse(Acc)),"-1"};
+ SloganPart ->
+ get_slogan_and_sysvsn(Fd,[[$\n|SloganPart]|Acc])
+ end.
+
get_general_info(Fd,GenInfo) ->
case line_head(Fd) of
- "Slogan" ->
- get_general_info(Fd,GenInfo#general_info{slogan=val(Fd)});
- "System version" ->
- get_general_info(Fd,GenInfo#general_info{system_vsn=val(Fd)});
"Compiled" ->
get_general_info(Fd,GenInfo#general_info{compile_time=val(Fd)});
"Taints" ->
@@ -1174,7 +1202,11 @@ parse_link_list("{from,"++Str,Links,Monitors,MonitoredBy) ->
parse_link_list(", "++Rest,Links,Monitors,MonitoredBy) ->
parse_link_list(Rest,Links,Monitors,MonitoredBy);
parse_link_list([],Links,Monitors,MonitoredBy) ->
- {lists:reverse(Links),lists:reverse(Monitors),lists:reverse(MonitoredBy)}.
+ {lists:reverse(Links),lists:reverse(Monitors),lists:reverse(MonitoredBy)};
+parse_link_list(Unexpected,Links,Monitors,MonitoredBy) ->
+ io:format("WARNING: found unexpected data in link list:~n~s~n",[Unexpected]),
+ parse_link_list([],Links,Monitors,MonitoredBy).
+
parse_port(Str) ->
{Port,Rest} = parse_link(Str,[]),
@@ -1523,10 +1555,14 @@ split_pid_list_no_space([],[],Pids) ->
%% Page with external ets tables
get_ets_tables(File,Pid,WS) ->
ParseFun = fun(Fd,Id) ->
- get_etsinfo(Fd,#ets_table{pid=list_to_pid(Id)},WS)
+ ET = get_etsinfo(Fd,#ets_table{pid=list_to_pid(Id)},WS),
+ ET#ets_table{is_named=tab_is_named(ET)}
end,
lookup_and_parse_index(File,{?ets,Pid},ParseFun,"ets").
+tab_is_named(#ets_table{id=Name,name=Name}) -> "yes";
+tab_is_named(#ets_table{}) -> "no".
+
get_etsinfo(Fd,EtsTable = #ets_table{details=Ds},WS) ->
case line_head(Fd) of
"Slot" ->
@@ -1813,16 +1849,16 @@ main_modinfo(_Fd,LM,_LineHead) ->
all_modinfo(Fd,LM,LineHead) ->
case LineHead of
"Current attributes" ->
- Str = hex_to_str(val(Fd)),
+ Str = hex_to_str(val(Fd,"")),
LM#loaded_mod{current_attrib=Str};
"Current compilation info" ->
- Str = hex_to_str(val(Fd)),
+ Str = hex_to_str(val(Fd,"")),
LM#loaded_mod{current_comp_info=Str};
"Old attributes" ->
- Str = hex_to_str(val(Fd)),
+ Str = hex_to_str(val(Fd,"")),
LM#loaded_mod{old_attrib=Str};
"Old compilation info" ->
- Str = hex_to_str(val(Fd)),
+ Str = hex_to_str(val(Fd,"")),
LM#loaded_mod{old_comp_info=Str};
Other ->
unexpected(Fd,Other,"loaded modules info"),
@@ -1848,7 +1884,12 @@ hex_to_term([],Acc) ->
Bin};
Term ->
Term
- end.
+ end;
+hex_to_term(Rest,Acc) ->
+ {"WARNING: The term is probably truncated!",
+ "I can not convert hex to term.",
+ Rest,list_to_binary(lists:reverse(Acc))}.
+
hex_to_dec("F") -> 15;
hex_to_dec("E") -> 14;
@@ -2159,7 +2200,8 @@ sort_allocator_types([{Name,Data}|Allocators],Acc,DoTotal) ->
Type =
case string:tokens(Name,"[]") of
[T,_Id] -> T;
- [Name] -> Name
+ [Name] -> Name;
+ Other -> Other
end,
TypeData = proplists:get_value(Type,Acc,[]),
{NewTypeData,NewDoTotal} = sort_type_data(Type,Data,TypeData,DoTotal),
@@ -2686,6 +2728,7 @@ count_index(Tag) ->
%%-----------------------------------------------------------------
%% Convert tags read from crashdump to atoms used as first part of key
%% in cdv_dump_index_table
+tag_to_atom("abort") -> ?abort;
tag_to_atom("allocated_areas") -> ?allocated_areas;
tag_to_atom("allocator") -> ?allocator;
tag_to_atom("atoms") -> ?atoms;
@@ -2720,6 +2763,14 @@ tag_to_atom(UnknownTag) ->
list_to_atom(UnknownTag).
%%%-----------------------------------------------------------------
+%%% Store last tag for use when truncated, and reason if aborted
+put_last_tag(?abort,Reason) ->
+ %% Don't overwrite the real last tag
+ put(truncated_reason,Reason);
+put_last_tag(Tag,Id) ->
+ put(last_tag,{Tag,Id}).
+
+%%%-----------------------------------------------------------------
%%% Fetch next chunk from crashdump file
lookup_and_parse_index(File,What,ParseFun,Str) when is_list(File) ->
Indices = lookup_index(What),
@@ -2815,7 +2866,16 @@ collect(Pids,Acc) ->
update_progress(),
collect(Pids,Acc);
{'DOWN', _Ref, process, Pid, {pmap_done,Result}} ->
- collect(lists:delete(Pid,Pids),[Result|Acc])
+ collect(lists:delete(Pid,Pids),[Result|Acc]);
+ {'DOWN', _Ref, process, Pid, _Error} ->
+ Warning =
+ "WARNING: an error occured while parsing data.\n" ++
+ case get(truncated) of
+ true -> "This might be because the dump is truncated.\n";
+ false -> ""
+ end,
+ io:format(Warning),
+ collect(lists:delete(Pid,Pids),Acc)
end.
%%%-----------------------------------------------------------------
diff --git a/lib/observer/src/crashdump_viewer.hrl b/lib/observer/src/crashdump_viewer.hrl
index a08659efd6..6a93a089fd 100644
--- a/lib/observer/src/crashdump_viewer.hrl
+++ b/lib/observer/src/crashdump_viewer.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -118,6 +118,7 @@
slot,
id,
name,
+ is_named,
data_type="hash",
buckets="-",
size,
diff --git a/lib/observer/src/etop.erl b/lib/observer/src/etop.erl
index fcb900960b..f0990f1f25 100644
--- a/lib/observer/src/etop.erl
+++ b/lib/observer/src/etop.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@
-export([start/0, start/1, config/2, stop/0, dump/1, help/0]).
%% Internal
-export([update/1]).
--export([loadinfo/1, meminfo/2, getopt/2]).
+-export([loadinfo/2, meminfo/2, getopt/2]).
-include("etop.hrl").
-include("etop_defs.hrl").
@@ -81,7 +81,7 @@ check_runtime_config(accumulate,A) when A=:=true; A=:=false -> ok;
check_runtime_config(_Key,_Value) -> error.
dump(File) ->
- case file:open(File,[write]) of
+ case file:open(File,[write,{encoding,utf8}]) of
{ok,Fd} -> etop_server ! {dump,Fd};
Error -> Error
end.
@@ -161,7 +161,7 @@ data_handler(Reader, Opts) ->
{'EXIT', EPid, Reason} when EPid == Opts#opts.out_proc ->
case Reason of
normal -> ok;
- _ -> io:format("Output server crashed: ~p~n",[Reason])
+ _ -> io:format("Output server crashed: ~tp~n",[Reason])
end,
stop(Opts),
out_proc_stopped;
@@ -180,10 +180,16 @@ stop(Opts) ->
end,
unregister(etop_server).
-update(#opts{store=Store,node=Node,tracing=Tracing}=Opts) ->
+update(#opts{store=Store,node=Node,tracing=Tracing,intv=Interval}=Opts) ->
Pid = spawn_link(Node,observer_backend,etop_collect,[self()]),
Info = receive {Pid,I} -> I
- after 1000 -> exit(connection_lost)
+ after Interval ->
+ %% Took more than the update interval to fetch
+ %% data. Either the connection is lost or the
+ %% fetching took too long...
+ io:format("Timeout when waiting for process info from "
+ "node ~p; exiting~n", [Node]),
+ exit(timeout)
end,
#etop_info{procinfo=ProcInfo} = Info,
ProcInfo1 =
@@ -319,18 +325,18 @@ output(graphical) -> exit({deprecated, "Use observer instead"});
output(text) -> etop_txt.
-loadinfo(SysI) ->
+loadinfo(SysI,Prev) ->
#etop_info{n_procs = Procs,
run_queue = RQ,
now = Now,
wall_clock = WC,
runtime = RT} = SysI,
- Cpu = calculate_cpu_utilization(WC,RT),
+ Cpu = calculate_cpu_utilization(WC,RT,Prev#etop_info.runtime),
Clock = io_lib:format("~2.2.0w:~2.2.0w:~2.2.0w",
tuple_to_list(element(2,calendar:now_to_datetime(Now)))),
{Cpu,Procs,RQ,Clock}.
-calculate_cpu_utilization({_,WC},{_,RT}) ->
+calculate_cpu_utilization({_,WC},{_,RT},_) ->
%% Old version of observer_backend, using statistics(wall_clock)
%% and statistics(runtime)
case {WC,RT} of
@@ -341,15 +347,23 @@ calculate_cpu_utilization({_,WC},{_,RT}) ->
_ ->
round(100*RT/WC)
end;
-calculate_cpu_utilization(_,undefined) ->
+calculate_cpu_utilization(_,undefined,_) ->
%% First time collecting - no cpu utilization has been measured
%% since scheduler_wall_time flag is not yet on
0;
-calculate_cpu_utilization(_,RTInfo) ->
+calculate_cpu_utilization(WC,RTInfo,undefined) ->
+ %% Second time collecting - RTInfo shows scheduler_wall_time since
+ %% flag was set to true. Faking previous values by setting
+ %% everything to zero.
+ ZeroRT = [{Id,0,0} || {Id,_,_} <- RTInfo],
+ calculate_cpu_utilization(WC,RTInfo,ZeroRT);
+calculate_cpu_utilization(_,RTInfo,PrevRTInfo) ->
%% New version of observer_backend, using statistics(scheduler_wall_time)
- Sum = lists:foldl(fun({_,A,T},{AAcc,TAcc}) -> {A+AAcc,T+TAcc} end,
+ Sum = lists:foldl(fun({{_, A0, T0}, {_, A1, T1}},{AAcc,TAcc}) ->
+ {(A1 - A0)+AAcc,(T1 - T0)+TAcc}
+ end,
{0,0},
- RTInfo),
+ lists:zip(PrevRTInfo,RTInfo)),
case Sum of
{0,0} ->
0;
diff --git a/lib/observer/src/etop_txt.erl b/lib/observer/src/etop_txt.erl
index 3b4c176478..183641119a 100644
--- a/lib/observer/src/etop_txt.erl
+++ b/lib/observer/src/etop_txt.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,35 +22,34 @@
%%-compile(export_all).
-export([init/1,stop/1]).
--export([do_update/3]).
+-export([do_update/4]).
-include("etop.hrl").
-include("etop_defs.hrl").
--import(etop,[loadinfo/1,meminfo/2]).
-
--define(PROCFORM,"~-15w~-20s~8w~8w~8w~8w ~-20s~n").
+-import(etop,[loadinfo/2,meminfo/2]).
stop(Pid) -> Pid ! stop.
init(Config) ->
- loop(Config).
+ loop(#etop_info{},Config).
-loop(Config) ->
- Info = do_update(Config),
+loop(Prev,Config) ->
+ Info = do_update(Prev,Config),
receive
stop -> stopped;
- {dump,Fd} -> do_update(Fd,Info,Config), loop(Config);
- {config,_,Config1} -> loop(Config1)
- after Config#opts.intv -> loop(Config)
+ {dump,Fd} -> do_update(Fd,Info,Prev,Config), loop(Info,Config);
+ {config,_,Config1} -> loop(Info,Config1)
+ after Config#opts.intv -> loop(Info,Config)
end.
-do_update(Config) ->
+do_update(Prev,Config) ->
Info = etop:update(Config),
- do_update(standard_io,Info,Config).
+ do_update(standard_io,Info,Prev,Config).
-do_update(Fd,Info,Config) ->
- {Cpu,NProcs,RQ,Clock} = loadinfo(Info),
+do_update(Fd,Info,Prev,Config) ->
+ Encoding = encoding(Fd),
+ {Cpu,NProcs,RQ,Clock} = loadinfo(Info,Prev),
io:nl(Fd),
writedoubleline(Fd),
case Info#etop_info.memi of
@@ -73,7 +72,7 @@ do_update(Fd,Info,Config) ->
io:nl(Fd),
writepinfo_header(Fd),
writesingleline(Fd),
- writepinfo(Fd,Info#etop_info.procinfo),
+ writepinfo(Fd,Info#etop_info.procinfo,Encoding),
writedoubleline(Fd),
io:nl(Fd),
Info.
@@ -93,19 +92,37 @@ writepinfo(Fd,[#etop_proc_info{pid=Pid,
runtime=Time,
cf=MFA,
mq=MQ}
- |T]) ->
- io:fwrite(Fd,?PROCFORM,[Pid,to_list(Name),Time,Reds,Mem,MQ,formatmfa(MFA)]),
- writepinfo(Fd,T);
-writepinfo(_Fd,[]) ->
+ |T],
+ Encoding) ->
+ io:fwrite(Fd,proc_format(Encoding),
+ [Pid,to_list(Name,Encoding),Time,Reds,Mem,MQ,
+ formatmfa(MFA,Encoding)]),
+ writepinfo(Fd,T,Encoding);
+writepinfo(_Fd,[],_) ->
ok.
-formatmfa({M, F, A}) ->
+formatmfa({M, F, A},latin1) ->
io_lib:format("~w:~w/~w",[M, F, A]);
-formatmfa(Other) ->
+formatmfa({M, F, A},_) ->
+ io_lib:format("~w:~tw/~w",[M, F, A]);
+formatmfa(Other,_) ->
%% E.g. when running hipe - the current_function for some
%% processes will be 'undefined'
io_lib:format("~w",[Other]).
-to_list(Name) when is_atom(Name) -> atom_to_list(Name);
-to_list({_M,_F,_A}=MFA) -> formatmfa(MFA).
+to_list(Name,_) when is_atom(Name) -> atom_to_list(Name);
+to_list({_M,_F,_A}=MFA,Encoding) -> formatmfa(MFA,Encoding).
+
+encoding(Device) ->
+ case io:getopts(Device) of
+ List when is_list(List) ->
+ proplists:get_value(encoding,List,latin1);
+ _ ->
+ latin1
+ end.
+
+proc_format(latin1) ->
+ "~-15w~-20s~8w~8w~8w~8w ~-20s~n";
+proc_format(_) ->
+ "~-15w~-20ts~8w~8w~8w~8w ~-20ts~n".
diff --git a/lib/observer/src/observer_alloc_wx.erl b/lib/observer/src/observer_alloc_wx.erl
index 77609b11ce..ef425f0874 100644
--- a/lib/observer/src/observer_alloc_wx.erl
+++ b/lib/observer/src/observer_alloc_wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
%% %CopyrightEnd%
-module(observer_alloc_wx).
--export([start_link/2]).
+-export([start_link/3]).
%% wx_object callbacks
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
@@ -36,6 +36,7 @@
wins,
mem,
samples,
+ max,
panel,
paint,
appmon,
@@ -48,10 +49,10 @@
[make_win/4, setup_graph_drawing/1, refresh_panel/4, interval_dialog/2,
add_data/5, precalc/4]).
-start_link(Notebook, Parent) ->
- wx_object:start_link(?MODULE, [Notebook, Parent], []).
+start_link(Notebook, Parent, Config) ->
+ wx_object:start_link(?MODULE, [Notebook, Parent, Config], []).
-init([Notebook, Parent]) ->
+init([Notebook, Parent, Config]) ->
try
TopP = wxPanel:new(Notebook),
Main = wxBoxSizer:new(?wxVERTICAL),
@@ -74,7 +75,8 @@ init([Notebook, Parent]) ->
wins = Windows,
mem = MemWin,
paint = PaintInfo,
- time = setup_time()
+ time = setup_time(Config),
+ max = #{}
}
}
catch _:Err ->
@@ -82,9 +84,11 @@ init([Notebook, Parent]) ->
{stop, Err}
end.
-setup_time() ->
- Freq = 1,
- #ti{fetch=Freq, disp=?DISP_FREQ/Freq}.
+setup_time(Config) ->
+ Freq = maps:get(fetch, Config, 1),
+ #ti{disp=?DISP_FREQ/Freq,
+ fetch=Freq,
+ secs=maps:get(secs, Config, ?DISP_SECONDS)}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
handle_event(#wx{id=?ID_REFRESH_INTERVAL, event=#wxCommand{type=command_menu_selected}},
@@ -115,6 +119,10 @@ handle_sync_event(#wx{obj=Panel, event = #wxPaint{}},_,
refresh_panel(Active, Win, Ti, Paint),
ok.
%%%%%%%%%%
+handle_call(get_config, _, #state{time=Ti}=State) ->
+ #ti{fetch=Fetch, secs=Range} = Ti,
+ {reply, #{fetch=>Fetch, secs=>Range}, State};
+
handle_call(Event, From, _State) ->
error({unhandled_call, Event, From}).
@@ -126,16 +134,17 @@ handle_info({Key, {promise_reply, {badrpc, _}}}, #state{async=Key} = State) ->
{noreply, State#state{active=false, appmon=undefined}};
handle_info({Key, {promise_reply, SysInfo}},
- #state{async=Key, panel=_Panel, samples=Data, active=Active, wins=Wins0,
- time=#ti{tick=Tick, disp=Disp0}=Ti} = S0) ->
+ #state{async=Key, samples=Data, max=Max0,
+ active=Active, wins=Wins0, time=#ti{tick=Tick, disp=Disp0}=Ti} = S0) ->
Disp = trunc(Disp0),
Next = max(Tick - Disp, 0),
erlang:send_after(1000 div ?DISP_FREQ, self(), {refresh, Next}),
Info = alloc_info(SysInfo),
+ Max = lists:foldl(fun calc_max/2, Max0, Info),
{Wins, Samples} = add_data(Info, Data, Wins0, Ti, Active),
- S1 = S0#state{time=Ti#ti{tick=Next}, wins=Wins, samples=Samples, async=undefined},
+ S1 = S0#state{time=Ti#ti{tick=Next}, wins=Wins, samples=Samples, max=Max, async=undefined},
if Active ->
- update_alloc(S0, Info),
+ update_alloc(S0, Info, Max),
State = precalc(S1),
{noreply, State};
true ->
@@ -185,27 +194,40 @@ code_change(_, _, State) ->
%%%%%%%%%%
restart_fetcher(Node, #state{panel=Panel, wins=Wins0, time=Ti} = State) ->
- SysInfo = observer_wx:try_rpc(Node, observer_backend, sys_info, []),
- Info = alloc_info(SysInfo),
- {Wins, Samples} = add_data(Info, {0, queue:new()}, Wins0, Ti, true),
- erlang:send_after(1000 div ?DISP_FREQ, self(), {refresh, 0}),
- wxWindow:refresh(Panel),
- precalc(State#state{active=true, appmon=Node, time=Ti#ti{tick=0},
- wins=Wins, samples=Samples}).
+ case rpc:call(Node, observer_backend, sys_info, []) of
+ {badrpc, _} -> State;
+ SysInfo ->
+ Info = alloc_info(SysInfo),
+ Max = lists:foldl(fun calc_max/2, #{}, Info),
+ {Wins, Samples} = add_data(Info, {0, queue:new()}, Wins0, Ti, true),
+ erlang:send_after(1000 div ?DISP_FREQ, self(), {refresh, 0}),
+ wxWindow:refresh(Panel),
+ precalc(State#state{active=true, appmon=Node, time=Ti#ti{tick=0},
+ wins=Wins, samples=Samples, max=Max})
+ end.
precalc(#state{samples=Data0, paint=Paint, time=Ti, wins=Wins0}=State) ->
Wins = [precalc(Ti, Data0, Paint, Win) || Win <- Wins0],
State#state{wins=Wins}.
+calc_max({Name, _, Cs}, Max0) ->
+ case maps:get(Name, Max0, 0) of
+ Value when Value < Cs ->
+ Max0#{Name=>Cs};
+ _V ->
+ Max0
+ end.
-update_alloc(#state{mem=Grid}, Fields) ->
+update_alloc(#state{mem=Grid}, Fields, Max) ->
wxWindow:freeze(Grid),
- Max = wxListCtrl:getItemCount(Grid),
+ Last = wxListCtrl:getItemCount(Grid),
Update = fun({Name, BS, CS}, Row) ->
- (Row >= Max) andalso wxListCtrl:insertItem(Grid, Row, ""),
+ (Row >= Last) andalso wxListCtrl:insertItem(Grid, Row, ""),
+ MaxV = maps:get(Name, Max, CS),
wxListCtrl:setItem(Grid, Row, 0, observer_lib:to_str(Name)),
wxListCtrl:setItem(Grid, Row, 1, observer_lib:to_str(BS div 1024)),
wxListCtrl:setItem(Grid, Row, 2, observer_lib:to_str(CS div 1024)),
+ wxListCtrl:setItem(Grid, Row, 3, observer_lib:to_str(MaxV div 1024)),
Row + 1
end,
wx:foldl(Update, 0, Fields),
@@ -269,7 +291,9 @@ create_mem_info(Parent) ->
end,
ListItems = [{"Allocator Type", ?wxLIST_FORMAT_LEFT, 200},
{"Block size (kB)", ?wxLIST_FORMAT_RIGHT, 150},
- {"Carrier size (kB)",?wxLIST_FORMAT_RIGHT, 150}],
+ {"Carrier size (kB)",?wxLIST_FORMAT_RIGHT, 150},
+ {"Max Carrier size (kB)",?wxLIST_FORMAT_RIGHT, 150}
+ ],
lists:foldl(AddListEntry, 0, ListItems),
wxListItem:destroy(Li),
diff --git a/lib/observer/src/observer_app_wx.erl b/lib/observer/src/observer_app_wx.erl
index 936b2783e2..bc4f1fe117 100644
--- a/lib/observer/src/observer_app_wx.erl
+++ b/lib/observer/src/observer_app_wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
%% %CopyrightEnd%
-module(observer_app_wx).
--export([start_link/2]).
+-export([start_link/3]).
%% wx_object callbacks
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
@@ -73,10 +73,10 @@
-define(wxGC, wxGraphicsContext).
-start_link(Notebook, Parent) ->
- wx_object:start_link(?MODULE, [Notebook, Parent], []).
+start_link(Notebook, Parent, Config) ->
+ wx_object:start_link(?MODULE, [Notebook, Parent, Config], []).
-init([Notebook, Parent]) ->
+init([Notebook, Parent, _Config]) ->
Panel = wxPanel:new(Notebook, [{size, wxWindow:getClientSize(Notebook)},
{winid, 1}
]),
@@ -191,8 +191,8 @@ handle_event(#wx{event=#wxMouse{type=Type, x=X0, y=Y0}},
end;
handle_event(#wx{event=#wxCommand{type=command_menu_selected}},
- State = #state{sel=undefined}) ->
- observer_lib:display_info_dialog("Select process first"),
+ State = #state{panel=Panel,sel=undefined}) ->
+ observer_lib:display_info_dialog(Panel,"Select process first"),
{noreply, State};
handle_event(#wx{id=?ID_PROC_INFO, event=#wxCommand{type=command_menu_selected}},
@@ -205,7 +205,7 @@ handle_event(#wx{id=?ID_PROC_MSG, event=#wxCommand{type=command_menu_selected}},
case observer_lib:user_term(Panel, "Enter message", "") of
cancel -> ok;
{ok, Term} -> Pid ! Term;
- {error, Error} -> observer_lib:display_info_dialog(Error)
+ {error, Error} -> observer_lib:display_info_dialog(Panel,Error)
end,
{noreply, State};
@@ -214,7 +214,7 @@ handle_event(#wx{id=?ID_PROC_KILL, event=#wxCommand{type=command_menu_selected}}
case observer_lib:user_term(Panel, "Enter Exit Reason", "kill") of
cancel -> ok;
{ok, Term} -> exit(Pid, Term);
- {error, Error} -> observer_lib:display_info_dialog(Error)
+ {error, Error} -> observer_lib:display_info_dialog(Panel,Error)
end,
{noreply, State};
@@ -258,6 +258,8 @@ handle_sync_event(#wx{event = #wxPaint{}},_,
destroy_gc(GC),
ok.
%%%%%%%%%%
+handle_call(get_config, _, State) ->
+ {reply, #{}, State};
handle_call(Event, From, _State) ->
error({unhandled_call, Event, From}).
diff --git a/lib/observer/src/observer_lib.erl b/lib/observer/src/observer_lib.erl
index 7c1337025f..c7ee294719 100644
--- a/lib/observer/src/observer_lib.erl
+++ b/lib/observer/src/observer_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,12 +20,12 @@
-module(observer_lib).
-export([get_wx_parent/1,
- display_info_dialog/1, display_yes_no_dialog/1,
+ display_info_dialog/2, display_yes_no_dialog/1,
display_progress_dialog/2, destroy_progress_dialog/0,
wait_for_progress/0, report_progress/1,
user_term/3, user_term_multiline/3,
- interval_dialog/4, start_timer/1, stop_timer/1,
- display_info/2, fill_info/2, update_info/2, to_str/1,
+ interval_dialog/4, start_timer/1, start_timer/2, stop_timer/1, timer_config/1,
+ display_info/2, display_info/3, fill_info/2, update_info/2, to_str/1,
create_menus/3, create_menu_item/3,
create_attrs/0,
set_listctrl_col_size/2,
@@ -90,6 +90,12 @@ stop_timer(Timer = {true, _}) -> Timer;
stop_timer(Timer = {_, Intv}) ->
setup_timer(false, Timer),
{true, Intv}.
+
+start_timer(#{interval:=Intv}, _Def) ->
+ setup_timer(true, {false, Intv});
+start_timer(_, Def) ->
+ setup_timer(true, {false, Def}).
+
start_timer(Intv) when is_integer(Intv) ->
setup_timer(true, {true, Intv});
start_timer(Timer) ->
@@ -105,10 +111,15 @@ setup_timer(Bool, {Timer, Old}) ->
timer:cancel(Timer),
setup_timer(Bool, {false, Old}).
-display_info_dialog(Str) ->
- display_info_dialog("",Str).
-display_info_dialog(Title,Str) ->
- Dlg = wxMessageDialog:new(wx:null(), Str, [{caption,Title}]),
+timer_config({_, Interval}) ->
+ #{interval=>Interval};
+timer_config(#{}=Config) ->
+ Config.
+
+display_info_dialog(Parent,Str) ->
+ display_info_dialog(Parent,"",Str).
+display_info_dialog(Parent,Title,Str) ->
+ Dlg = wxMessageDialog:new(Parent, Str, [{caption,Title}]),
wxMessageDialog:showModal(Dlg),
wxMessageDialog:destroy(Dlg),
ok.
@@ -124,6 +135,11 @@ display_info(Frame, Info) ->
Panel = wxPanel:new(Frame),
wxWindow:setBackgroundStyle(Panel, ?wxBG_STYLE_SYSTEM),
Sizer = wxBoxSizer:new(?wxVERTICAL),
+ InfoFs = display_info(Panel, Sizer, Info),
+ wxWindow:setSizerAndFit(Panel, Sizer),
+ {Panel, Sizer, InfoFs}.
+
+display_info(Panel, Sizer, Info) ->
wxSizer:addSpacer(Sizer, 5),
Add = fun(BoxInfo) ->
case create_box(Panel, BoxInfo) of
@@ -136,9 +152,7 @@ display_info(Frame, Info) ->
[]
end
end,
- InfoFs = [Add(I) || I <- Info],
- wxWindow:setSizerAndFit(Panel, Sizer),
- {Panel, Sizer, InfoFs}.
+ [Add(I) || I <- Info].
fill_info([{dynamic, Key}|Rest], Data)
when is_atom(Key); is_function(Key) ->
@@ -159,13 +173,13 @@ fill_info([{Str,Attrib,Key}|Rest], Data) when is_atom(Key); is_function(Key) ->
Value -> [{Str,Attrib,Value} | fill_info(Rest, Data)]
end;
fill_info([{Str, {Format, Key}}|Rest], Data)
- when is_atom(Key); is_function(Key), is_atom(Format) ->
+ when is_atom(Key); is_function(Key) ->
case get_value(Key, Data) of
undefined -> [undefined | fill_info(Rest, Data)];
Value -> [{Str, {Format, Value}} | fill_info(Rest, Data)]
end;
fill_info([{Str, Attrib, {Format, Key}}|Rest], Data)
- when is_atom(Key); is_function(Key), is_atom(Format) ->
+ when is_atom(Key); is_function(Key) ->
case get_value(Key, Data) of
undefined -> [undefined | fill_info(Rest, Data)];
Value -> [{Str, Attrib, {Format, Value}} | fill_info(Rest, Data)]
@@ -238,6 +252,8 @@ to_str({bytes, B}) ->
KB > 0 -> integer_to_list(KB) ++ " kB";
true -> integer_to_list(B) ++ " B"
end;
+to_str({{words,WSz}, Sz}) ->
+ to_str({bytes, WSz*Sz});
to_str({time_ms, MS}) ->
S = MS div 1000,
Min = S div 60,
@@ -254,6 +270,11 @@ to_str({func, {F,A}}) when is_atom(F), is_integer(A) ->
lists:concat([F, "/", A]);
to_str({func, {F,'_'}}) when is_atom(F) ->
atom_to_list(F);
+to_str({inet, Addr}) ->
+ case inet:ntoa(Addr) of
+ {error,einval} -> to_str(Addr);
+ AddrStr -> AddrStr
+ end;
to_str({{format,Fun},Value}) when is_function(Fun) ->
Fun(Value);
to_str({A, B}) when is_atom(A), is_atom(B) ->
@@ -453,14 +474,16 @@ create_box(Parent, Data) ->
link_entry(Panel,Value);
_ ->
Value = to_str(Value0),
- case length(Value) > 100 of
- true ->
- Shown = lists:sublist(Value, 80),
+ case string:sub_word(lists:sublist(Value, 80),1,$\n) of
+ Value ->
+ %% Short string, no newlines - show all
+ wxStaticText:new(Panel, ?wxID_ANY, Value);
+ Shown ->
+ %% Long or with newlines,
+ %% use tooltip to show all
TCtrl = wxStaticText:new(Panel, ?wxID_ANY, [Shown,"..."]),
wxWindow:setToolTip(TCtrl,wxToolTip:new(Value)),
- TCtrl;
- false ->
- wxStaticText:new(Panel, ?wxID_ANY, Value)
+ TCtrl
end
end,
wxSizer:add(Line, 10, 0), % space of size 10 horisontally
@@ -613,12 +636,12 @@ user_term_multiline(Parent, Title, Default) ->
parse_string(Str) ->
try
- Tokens = case erl_scan:string(Str) of
+ Tokens = case erl_scan:string(Str, 1, [text]) of
{ok, Ts, _} -> Ts;
{error, {_SLine, SMod, SError}, _} ->
throw(io_lib:format("~s", [SMod:format_error(SError)]))
end,
- case erl_parse:parse_term(Tokens) of
+ case lib:extended_parse_term(Tokens) of
{error, {_PLine, PMod, PError}} ->
throw(io_lib:format("~s", [PMod:format_error(PError)]));
Res -> Res
@@ -714,7 +737,7 @@ progress_loop(Title,PD,Caller) ->
if is_list(Reason) -> Reason;
true -> file:format_error(Reason)
end,
- display_info_dialog("Crashdump Viewer Error",FailMsg),
+ display_info_dialog(PD,"Crashdump Viewer Error",FailMsg),
Caller ! error,
unregister(?progress_handler),
unlink(Caller);
diff --git a/lib/observer/src/observer_perf_wx.erl b/lib/observer/src/observer_perf_wx.erl
index 1010a6af4c..fcc51310c8 100644
--- a/lib/observer/src/observer_perf_wx.erl
+++ b/lib/observer/src/observer_perf_wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
%% %CopyrightEnd%
-module(observer_perf_wx).
--export([start_link/2]).
+-export([start_link/3]).
%% wx_object callbacks
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
@@ -55,12 +55,12 @@
-define(wxGC, wxGraphicsContext).
--record(paint, {font, small, pen, pen2, pens, usegc = false}).
+-record(paint, {font, small, pen, pen2, pens, dot_pens, usegc = false}).
-start_link(Notebook, Parent) ->
- wx_object:start_link(?MODULE, [Notebook, Parent], []).
+start_link(Notebook, Parent, Config) ->
+ wx_object:start_link(?MODULE, [Notebook, Parent, Config], []).
-init([Notebook, Parent]) ->
+init([Notebook, Parent, Config]) ->
try
Panel = wxPanel:new(Notebook),
Main = wxBoxSizer:new(?wxVERTICAL),
@@ -81,7 +81,9 @@ init([Notebook, Parent]) ->
panel =Panel,
wins = Windows,
paint=PaintInfo,
- samples=reset_data()
+ samples=reset_data(),
+ time=#ti{fetch=maps:get(fetch, Config, ?FETCH_DATA),
+ secs=maps:get(secs, Config, ?DISP_SECONDS)}
},
{Panel, State0}
catch _:Err ->
@@ -124,13 +126,17 @@ setup_graph_drawing(Panels) ->
{F, SF}
end,
BlackPen = wxPen:new({0,0,0}, [{width, 1}]),
- Pens = [wxPen:new(Col, [{width, 1}]) || Col <- tuple_to_list(colors())],
+ Pens = [wxPen:new(Col, [{width, 1}, {style, ?wxSOLID}])
+ || Col <- tuple_to_list(colors())],
+ DotPens = [wxPen:new(Col, [{width, 1}, {style, ?wxDOT}])
+ || Col <- tuple_to_list(colors())],
#paint{usegc = UseGC,
font = Font,
small = SmallFont,
pen = ?wxGREY_PEN,
pen2 = BlackPen,
- pens = list_to_tuple(Pens)
+ pens = list_to_tuple(Pens),
+ dot_pens = list_to_tuple(DotPens)
}.
@@ -173,6 +179,10 @@ refresh_panel(Active, #win{name=_Id, panel=Panel}=Win, Ti, #paint{usegc=UseGC}=P
destroy_gc(GC).
%%%%%%%%%%
+handle_call(get_config, _, #state{time=Ti}=State) ->
+ #ti{fetch=Fetch, secs=Range} = Ti,
+ {reply, #{fetch=>Fetch, secs=>Range}, State};
+
handle_call(Event, From, _State) ->
error({unhandled_call, Event, From}).
@@ -181,17 +191,17 @@ handle_cast(Event, _State) ->
%%%%%%%%%%
handle_info({stats, 1, _, _, _} = Stats,
#state{panel=Panel, samples=Data, active=Active, wins=Wins0,
- time=#ti{tick=Tick, disp=Disp0}=Ti} = State0) ->
+ appmon=Node, time=#ti{tick=Tick, disp=Disp0}=Ti} = State0) ->
if Active ->
Disp = trunc(Disp0),
Next = max(Tick - Disp, 0),
erlang:send_after(1000 div ?DISP_FREQ, self(), {refresh, Next}),
- {Wins, Samples} = add_data(Stats, Data, Wins0, Ti, Active),
+ {Wins, Samples} = add_data(Stats, Data, Wins0, Ti, Active, Node),
State = precalc(State0#state{time=Ti#ti{tick=Next}, wins=Wins, samples=Samples}),
wxWindow:refresh(Panel),
{noreply, State};
true ->
- {Wins1, Samples} = add_data(Stats, Data, Wins0, Ti, Active),
+ {Wins1, Samples} = add_data(Stats, Data, Wins0, Ti, Active, Node),
Wins = [W#win{max=undefined} || W <- Wins1],
{noreply, State0#state{samples=Samples, wins=Wins, time=Ti#ti{tick=0}}}
end;
@@ -206,7 +216,7 @@ handle_info({refresh, Seq}, #state{panel=Panel, time=#ti{tick=Seq, disp=DispF}=T
handle_info({refresh, _}, State) ->
{noreply, State};
-handle_info({active, Node}, #state{parent=Parent, panel=Panel, appmon=Old, time=_Ti} = State) ->
+handle_info({active, Node}, #state{parent=Parent, panel=Panel, appmon=Old} = State) ->
create_menus(Parent, []),
try
Node = node(Old),
@@ -235,39 +245,50 @@ terminate(_Event, #state{appmon=Pid}) ->
code_change(_, _, State) ->
State.
-restart_fetcher(Node, #state{appmon=Old, panel=Panel, time=#ti{fetch=Freq}=Ti}=State) ->
+restart_fetcher(Node, #state{appmon=Old, panel=Panel, time=#ti{fetch=Freq}=Ti, wins=Wins0}=State) ->
catch Old ! exit,
Me = self(),
Pid = spawn_link(Node, observer_backend, fetch_stats, [Me, round(1000/Freq)]),
wxWindow:refresh(Panel),
- precalc(State#state{active=true, appmon=Pid, samples=reset_data(), time=Ti#ti{tick=0}}).
+ Wins = [W#win{state=undefined} || W <- Wins0],
+ precalc(State#state{active=true, appmon=Pid, samples=reset_data(),
+ wins=Wins, time=Ti#ti{tick=0}}).
reset_data() ->
{0, queue:new()}.
-add_data(Stats, {N, Q0}, Wins, #ti{fetch=Fetch, secs=Secs}, Active) when N > (Secs*Fetch+1) ->
+add_data(Stats, Q, Wins, Ti, Active) ->
+ add_data(Stats, Q, Wins, Ti, Active, ignore).
+
+add_data(Stats, {N, Q0}, Wins, #ti{fetch=Fetch, secs=Secs}, Active, Node)
+ when N > (Secs*Fetch+1) ->
{{value, Drop}, Q} = queue:out(Q0),
- add_data_1(Wins, Stats, N, {Drop,Q}, Active);
-add_data(Stats, {N, Q}, Wins, _, Active) ->
- add_data_1(Wins, Stats, N+1, {empty, Q}, Active).
+ add_data_1(Wins, Stats, N, {Drop,Q}, Active, Node);
+add_data(Stats, {N, Q}, Wins, _, Active, Node) ->
+ add_data_1(Wins, Stats, N+1, {empty, Q}, Active, Node).
-add_data_1([#win{state={_,St}}|_]=Wins0, Last, N, {Drop, Q}, Active)
+add_data_1([#win{state={_,St}}|_]=Wins0, Last, N, {Drop, Q}, Active, Node)
when St /= undefined ->
- {Wins, Stat} =
- lists:mapfoldl(fun(Win0, Entry) ->
- {Win1,Stat} = add_data_2(Win0, Last, Entry),
- case Active of
- true ->
- Win = add_data_3(Win1, N, Drop, Stat, Q),
- {Win, Stat};
- false ->
- {Win1, Stat}
- end
- end, #{}, Wins0),
- {Wins, {N,queue:in(Stat#{}, Q)}};
-add_data_1(Wins, Stats, 1, {_, Q}, _) ->
- {[Win#win{state=init_data(Id, Stats),
- info = info(Id, Stats)}
+ try
+ {Wins, Stat} =
+ lists:mapfoldl(fun(Win0, Entry) ->
+ {Win1,Stat} = add_data_2(Win0, Last, Entry),
+ case Active of
+ true ->
+ Win = add_data_3(Win1, N, Drop, Stat, Q),
+ {Win, Stat};
+ false ->
+ {Win1, Stat}
+ end
+ end, #{}, Wins0),
+ {Wins, {N,queue:in(Stat#{}, Q)}}
+ catch no_scheduler_change ->
+ {[Win#win{state=init_data(Id, Last), info=info(Id, Last, Node)}
+ || #win{name=Id}=Win <- Wins0], {0,queue:new()}}
+ end;
+
+add_data_1(Wins, Stats, 1, {_, Q}, _, Node) ->
+ {[Win#win{state=init_data(Id, Stats), info=info(Id, Stats, Node)}
|| #win{name=Id}=Win <- Wins], {0,Q}}.
add_data_2(#win{name=Id, state=S0}=Win, Stats, Map) ->
@@ -373,16 +394,24 @@ lmax(MState, Values, State) ->
init_data(runq, {stats, _, T0, _, _}) -> {mk_max(),lists:sort(T0)};
init_data(io, {stats, _, _, {{_,In0}, {_,Out0}}, _}) -> {mk_max(), {In0,Out0}};
-init_data(memory, _) -> {mk_max(), info(memory, undefined)};
-init_data(alloc, _) -> {mk_max(), ok};
-init_data(utilz, _) -> {mk_max(), ok}.
-
-info(runq, {stats, _, T0, _, _}) -> lists:seq(1, length(T0));
-info(memory, _) -> [total, processes, atom, binary, code, ets];
-info(io, _) -> [input, output];
-info(alloc, First) -> [Type || {Type, _, _} <- First];
-info(utilz, First) -> [Type || {Type, _, _} <- First];
-info(_, []) -> [].
+init_data(memory, _) -> {mk_max(), info(memory, undefined, undefined)};
+init_data(alloc, _) -> {mk_max(), unused};
+init_data(utilz, _) -> {mk_max(), unused}.
+
+info(runq, {stats, _, T0, _, _}, Node) ->
+ Dirty = get_dirty_cpu(Node),
+ {lists:seq(1, length(T0)-Dirty), Dirty};
+info(memory, _, _) -> [total, processes, atom, binary, code, ets];
+info(io, _, _) -> [input, output];
+info(alloc, First, _) -> [Type || {Type, _, _} <- First];
+info(utilz, First, _) -> [Type || {Type, _, _} <- First];
+info(_, [], _) -> [].
+
+get_dirty_cpu(Node) ->
+ case rpc:call(node(Node), erlang, system_info, [dirty_cpu_schedulers]) of
+ {badrpc,_R} -> 0;
+ N -> N
+ end.
collect_data(runq, {stats, _, T0, _, _}, {Max,S0}) ->
S1 = lists:sort(T0),
@@ -401,15 +430,16 @@ collect_data(memory, {stats, _, _, _, MemInfo}, {Max, MemTypes}) ->
collect_data(alloc, MemInfo, Max) ->
Vs = [Carrier || {_Type,_Block,Carrier} <- MemInfo],
Sample = list_to_tuple(Vs),
- {Sample, lmax(Max, Vs, Sample)};
+ {Sample, {lmax(Max, Vs, Sample),unused}};
collect_data(utilz, MemInfo, Max) ->
Vs = [round(100*Block/Carrier) || {_Type,Block,Carrier} <- MemInfo],
Sample = list_to_tuple(Vs),
- {Sample, lmax(Max,Vs,Sample)}.
+ {Sample, {lmax(Max,Vs,Sample),unused}}.
calc_delta([{Id, WN, TN}|Ss], [{Id, WP, TP}|Ps]) ->
[100*(WN-WP) div (TN-TP)|calc_delta(Ss, Ps)];
-calc_delta([], []) -> [].
+calc_delta([], []) -> [];
+calc_delta(_, _) -> throw(no_scheduler_change).
precalc(#state{samples=Data0, paint=Paint, time=Ti, wins=Wins0}=State) ->
Wins = [precalc(Ti, Data0, Paint, Win) || Win <- Wins0],
@@ -461,9 +491,10 @@ window_geom({W,H}, {_, Max, _Unit, MaxUnit},
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-draw_win(DC, #win{no_samples=Samples, geom=#{scale:={WS,HS}}, graphs=Graphs, max={_,Max,_,_}}=Win,
+draw_win(DC, #win{name=Name, no_samples=Samples, geom=#{scale:={WS,HS}},
+ graphs=Graphs, max={_,Max,_,_}, info=Info}=Win,
#ti{tick=Tick, fetch=FetchFreq, secs=Secs, disp=DispFreq}=Ti,
- Paint=#paint{pens=Pens}) when Samples >= 2, Graphs =/= [] ->
+ Paint=#paint{pens=Pens, dot_pens=Dots}) when Samples >= 2, Graphs =/= [] ->
%% Draw graphs
{X0,Y0,DrawBs} = draw_borders(DC, Ti, Win, Paint),
Offset = Tick / DispFreq,
@@ -473,14 +504,23 @@ draw_win(DC, #win{no_samples=Samples, geom=#{scale:={WS,HS}}, graphs=Graphs, max
end,
Start = X0 + (max(Secs*FetchFreq+Full-Samples, 0) - Offset)*WS,
Last = Secs*FetchFreq*WS+X0,
+ Dirty = case {Name, Info} of
+ {runq, {_, DCpu}} -> DCpu;
+ _ -> 0
+ end,
+ NoGraphs = length(Graphs),
+ NoCpu = NoGraphs - Dirty,
Draw = fun(Lines0, N) ->
- setPen(DC, element(1+ ((N-1) rem tuple_size(Pens)), Pens)),
+ case Dirty > 0 andalso N > NoCpu of
+ true -> setPen(DC, element(1+ ((N-NoCpu-1) rem tuple_size(Dots)), Dots));
+ false -> setPen(DC, element(1+ ((N-1) rem tuple_size(Pens)), Pens))
+ end,
Order = lists:reverse(Lines0),
[{_,Y}|Lines] = translate(Order, {Start, Y0}, 0, WS, {X0,Max*HS,Last}, []),
strokeLines(DC, [{Last,Y}|Lines]),
N-1
end,
- lists:foldl(Draw, length(Graphs), Graphs),
+ lists:foldl(Draw, NoGraphs, Graphs),
DrawBs(),
ok;
@@ -645,11 +685,17 @@ draw_borders(DC, #ti{secs=Secs, fetch=FetchFreq},
case Type of
runq ->
+ {TextInfo, DirtyCpus} = Info,
drawText(DC, "Scheduler Utilization (%) ", TopTextX, ?BH),
TN0 = Text(TopTextX, BottomTextY, "Scheduler: ", 0),
- lists:foldl(fun(Id, Pos0) ->
- Text(Pos0, BottomTextY, integer_to_list(Id), Id)
- end, TN0, Info);
+ Id = fun(Id, Pos0) ->
+ Text(Pos0, BottomTextY, integer_to_list(Id), Id)
+ end,
+ TN1 = lists:foldl(Id, TN0, TextInfo),
+ TN2 = Text(TN1, BottomTextY, "Dirty cpu: ", 0),
+ TN3 = lists:foldl(Id, TN2, lists:seq(1, DirtyCpus)),
+ _ = Text(TN3, BottomTextY, "(dotted)", 0),
+ ok;
memory ->
drawText(DC, "Memory Usage " ++ Unit, TopTextX,?BH),
lists:foldl(fun(MType, {PenId, Pos0}) ->
@@ -738,10 +784,10 @@ calc_max1(Max) ->
end.
colors() ->
- {{240, 100, 100}, {100, 240, 100}, {100, 100, 240},
- {220, 220, 80}, {100, 240, 240}, {240, 100, 240},
- {100, 25, 25}, {25, 100, 25}, {25, 25, 100},
- {120, 120, 0}, {25, 100, 100}, {100, 50, 100}
+ {{240, 100, 100}, {0, 128, 0}, {25, 45, 170}, {255, 165, 0},
+ {220, 220, 40}, {100, 240, 240},{240, 100, 240}, {160, 40, 40},
+ {100, 100, 240}, {140, 140, 0}, {25, 200, 100}, {120, 25, 240},
+ {255, 140, 163}, {25, 120, 120}, {120, 25, 120}, {110, 90, 60}
}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/observer/src/observer_port_wx.erl b/lib/observer/src/observer_port_wx.erl
index 3b788642cc..8339267659 100644
--- a/lib/observer/src/observer_port_wx.erl
+++ b/lib/observer/src/observer_port_wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
%% %CopyrightEnd%
-module(observer_port_wx).
--export([start_link/2]).
+-export([start_link/3]).
%% wx_object callbacks
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
@@ -52,7 +52,13 @@
slot,
id_str,
links,
- monitors}).
+ monitors,
+ monitored_by,
+ parallelism,
+ locking,
+ queue_size,
+ memory,
+ inet}).
-record(opt, {sort_key=2,
sort_incr=true
@@ -63,7 +69,7 @@
parent,
grid,
panel,
- node=node(),
+ node={node(),true},
opt=#opt{},
right_clicked_port,
ports,
@@ -71,10 +77,10 @@
open_wins=[]
}).
-start_link(Notebook, Parent) ->
- wx_object:start_link(?MODULE, [Notebook, Parent], []).
+start_link(Notebook, Parent, Config) ->
+ wx_object:start_link(?MODULE, [Notebook, Parent, Config], []).
-init([Notebook, Parent]) ->
+init([Notebook, Parent, Config]) ->
Panel = wxPanel:new(Notebook),
Sizer = wxBoxSizer:new(?wxVERTICAL),
Style = ?wxLC_REPORT bor ?wxLC_HRULES,
@@ -104,12 +110,12 @@ init([Notebook, Parent]) ->
wxListCtrl:connect(Grid, size, [{skip, true}]),
wxWindow:setFocus(Grid),
- {Panel, #state{grid=Grid, parent=Parent, panel=Panel, timer={false, 10}}}.
+ {Panel, #state{grid=Grid, parent=Parent, panel=Panel, timer=Config}}.
handle_event(#wx{id=?ID_REFRESH},
State = #state{node=Node, grid=Grid, opt=Opt}) ->
Ports0 = get_ports(Node),
- Ports = update_grid(Grid, Opt, Ports0),
+ Ports = update_grid(Grid, sel(State), Opt, Ports0),
{noreply, State#state{ports=Ports}};
handle_event(#wx{obj=Obj, event=#wxClose{}}, #state{open_wins=Opened} = State) ->
@@ -128,7 +134,7 @@ handle_event(#wx{event=#wxList{type=command_list_col_click, col=Col}},
NewKey -> Opt0#opt{sort_key=NewKey}
end,
Ports0 = get_ports(Node),
- Ports = update_grid(Grid, Opt, Ports0),
+ Ports = update_grid(Grid, sel(State), Opt, Ports0),
wxWindow:setFocus(Grid),
{noreply, State#state{opt=Opt, ports=Ports}};
@@ -254,6 +260,9 @@ handle_event(Event, _State) ->
handle_sync_event(_Event, _Obj, _State) ->
ok.
+handle_call(get_config, _, #state{timer=Timer}=State) ->
+ {reply, observer_lib:timer_config(Timer), State};
+
handle_call(Event, From, _State) ->
error({unhandled_call, Event, From}).
@@ -261,10 +270,39 @@ handle_cast(Event, _State) ->
error({unhandled_cast, Event}).
handle_info({portinfo_open, PortIdStr},
- State = #state{grid=Grid, ports=Ports, open_wins=Opened}) ->
- Port = lists:keyfind(PortIdStr,#port.id_str,Ports),
- NewOpened = display_port_info(Grid, Port, Opened),
- {noreply, State#state{open_wins = NewOpened}};
+ State = #state{node={ActiveNodeName,ActiveAvailable}, grid=Grid,
+ opt=Opt, open_wins=Opened}) ->
+ NodeName = node(list_to_port(PortIdStr)),
+ Available =
+ case NodeName of
+ ActiveNodeName ->
+ ActiveAvailable;
+ _ ->
+ portinfo_available(NodeName)
+ end,
+ if Available ->
+ Ports0 = get_ports({NodeName,Available}),
+ Port = lists:keyfind(PortIdStr, #port.id_str, Ports0),
+ NewOpened =
+ case Port of
+ false ->
+ self() ! {error,"No such port: " ++ PortIdStr},
+ Opened;
+ _ ->
+ display_port_info(Grid, Port, Opened)
+ end,
+ Ports =
+ case NodeName of
+ ActiveNodeName ->
+ update_grid(Grid, sel(State), Opt, Ports0);
+ _ ->
+ State#state.ports
+ end,
+ {noreply, State#state{ports=Ports, open_wins=NewOpened}};
+ true ->
+ popup_unavailable_info(NodeName),
+ {noreply, State}
+ end;
handle_info(refresh_interval, State = #state{node=Node, grid=Grid, opt=Opt,
ports=OldPorts}) ->
@@ -273,25 +311,35 @@ handle_info(refresh_interval, State = #state{node=Node, grid=Grid, opt=Opt,
%% no change
{noreply, State};
Ports0 ->
- Ports = update_grid(Grid, Opt, Ports0),
+ Ports = update_grid(Grid, sel(State), Opt, Ports0),
{noreply, State#state{ports=Ports}}
end;
-handle_info({active, Node}, State = #state{parent=Parent, grid=Grid, opt=Opt,
- timer=Timer0}) ->
- Ports0 = get_ports(Node),
- Ports = update_grid(Grid, Opt, Ports0),
+handle_info({active, NodeName}, State = #state{parent=Parent, grid=Grid, opt=Opt,
+ timer=Timer0}) ->
+ Available = portinfo_available(NodeName),
+ Available orelse popup_unavailable_info(NodeName),
+ Ports0 = get_ports({NodeName,Available}),
+ Ports = update_grid(Grid, sel(State), Opt, Ports0),
wxWindow:setFocus(Grid),
create_menus(Parent),
- Timer = observer_lib:start_timer(Timer0),
- {noreply, State#state{node=Node, ports=Ports, timer=Timer}};
+ Timer = observer_lib:start_timer(Timer0, 10),
+ {noreply, State#state{node={NodeName,Available}, ports=Ports, timer=Timer}};
handle_info(not_active, State = #state{timer = Timer0}) ->
Timer = observer_lib:stop_timer(Timer0),
{noreply, State#state{timer=Timer}};
-handle_info({error, Error}, State) ->
- handle_error(Error),
+handle_info({info, {port_info_not_available,NodeName}},
+ State = #state{panel=Panel}) ->
+ Str = io_lib:format("Can not fetch port info from ~p.~n"
+ "Too old OTP version.",[NodeName]),
+ observer_lib:display_info_dialog(Panel, Str),
+ {noreply, State};
+
+handle_info({error, Error}, #state{panel=Panel} = State) ->
+ Str = io_lib:format("ERROR: ~s~n",[Error]),
+ observer_lib:display_info_dialog(Panel, Str),
{noreply, State};
handle_info(_Event, State) ->
@@ -322,16 +370,18 @@ create_menus(Parent) ->
],
observer_wx:create_menus(Parent, MenuEntries).
-get_ports(Node) ->
- case get_ports2(Node) of
+get_ports({_NodeName,false}) ->
+ [];
+get_ports({NodeName,true}) ->
+ case get_ports2(NodeName) of
Error = {error, _} ->
self() ! Error,
[];
Res ->
Res
end.
-get_ports2(Node) ->
- case rpc:call(Node, observer_backend, get_port_list, []) of
+get_ports2(NodeName) ->
+ case rpc:call(NodeName, observer_backend, get_port_list, []) of
{badrpc, Error} ->
{error, Error};
Error = {error, _} ->
@@ -358,7 +408,13 @@ list_to_portrec(PL) ->
links = proplists:get_value(links, PL, []),
name = proplists:get_value(registered_name, PL, []),
monitors = proplists:get_value(monitors, PL, []),
- controls = proplists:get_value(name, PL)}.
+ monitored_by = proplists:get_value(monitored_by, PL, []),
+ controls = proplists:get_value(name, PL),
+ parallelism = proplists:get_value(parallelism, PL),
+ locking = proplists:get_value(locking, PL),
+ queue_size = proplists:get_value(queue_size, PL, 0),
+ memory = proplists:get_value(memory, PL, 0),
+ inet = proplists:get_value(inet, PL, [])}.
portrec_to_list(#port{id = Id,
slot = Slot,
@@ -366,14 +422,26 @@ portrec_to_list(#port{id = Id,
links = Links,
name = Name,
monitors = Monitors,
- controls = Controls}) ->
+ monitored_by = MonitoredBy,
+ controls = Controls,
+ parallelism = Parallelism,
+ locking = Locking,
+ queue_size = QueueSize,
+ memory = Memory,
+ inet = Inet}) ->
[{id,Id},
{slot,Slot},
{connected,Connected},
{links,Links},
{name,Name},
{monitors,Monitors},
- {controls,Controls}].
+ {monitored_by,MonitoredBy},
+ {controls,Controls},
+ {parallelism,Parallelism},
+ {locking,Locking},
+ {queue_size,QueueSize},
+ {memory,Memory} |
+ Inet].
display_port_info(Parent, PortRec, Opened) ->
PortIdStr = PortRec#port.id_str,
@@ -391,43 +459,95 @@ do_display_port_info(Parent0, PortRec) ->
Title = "Port Info: " ++ PortRec#port.id_str,
Frame = wxMiniFrame:new(Parent, ?wxID_ANY, Title,
[{style, ?wxSYSTEM_MENU bor ?wxCAPTION
- bor ?wxCLOSE_BOX bor ?wxRESIZE_BORDER}]),
-
+ bor ?wxCLOSE_BOX bor ?wxRESIZE_BORDER},
+ {size,{600,400}}]),
+ ScrolledWin = wxScrolledWindow:new(Frame,[{style,?wxHSCROLL bor ?wxVSCROLL}]),
+ wxScrolledWindow:enableScrolling(ScrolledWin,true,true),
+ wxScrolledWindow:setScrollbars(ScrolledWin,20,20,0,0),
+ Sizer = wxBoxSizer:new(?wxVERTICAL),
+ wxWindow:setSizer(ScrolledWin,Sizer),
Port = portrec_to_list(PortRec),
Fields0 = port_info_fields(Port),
- {_FPanel, _Sizer, _UpFields} = observer_lib:display_info(Frame, Fields0),
+ _UpFields = observer_lib:display_info(ScrolledWin, Sizer, Fields0),
wxFrame:center(Frame),
wxFrame:connect(Frame, close_window, [{skip, true}]),
wxFrame:show(Frame),
Frame.
-port_info_fields(Port) ->
+
+port_info_fields(Port0) ->
+ {InetStruct,Port} = inet_extra_fields(Port0),
Struct =
[{"Overview",
- [{"Name", name},
+ [{"Registered Name", name},
{"Connected", {click,connected}},
{"Slot", slot},
- {"Controls", controls}]},
+ {"Controls", controls},
+ {"Parallelism", parallelism},
+ {"Locking", locking},
+ {"Queue Size", {bytes,queue_size}},
+ {"Memory", {bytes,memory}}]},
{scroll_boxes,
[{"Links",1,{click,links}},
- {"Monitors",1,{click,filter_monitor_info()}}]}],
+ {"Monitors",1,{click,filter_monitor_info()}},
+ {"Monitored by",1,{click,monitored_by}}]} | InetStruct],
observer_lib:fill_info(Struct, Port).
+inet_extra_fields(Port) ->
+ Statistics = proplists:get_value(statistics,Port,[]),
+ Options = proplists:get_value(options,Port,[]),
+ Struct =
+ case proplists:get_value(controls,Port) of
+ Inet when Inet=="tcp_inet"; Inet=="udp_inet"; Inet=="sctp_inet" ->
+ [{"Inet",
+ [{"Local Address", {inet,local_address}},
+ {"Local Port Number", local_port},
+ {"Remote Address", {inet,remote_address}},
+ {"Remote Port Number", remote_port}]},
+ {"Statistics",
+ [stat_name_and_unit(Key) || {Key,_} <- Statistics]},
+ {"Options",
+ [{atom_to_list(Key),Key} || {Key,_} <- Options]}];
+ _ ->
+ []
+ end,
+ Port1 = lists:keydelete(statistics,1,Port),
+ Port2 = lists:keydelete(options,1,Port1),
+ {Struct,Port2 ++ Statistics ++ Options}.
+
+stat_name_and_unit(recv_avg) ->
+ {"Average package size received", {bytes,recv_avg}};
+stat_name_and_unit(recv_cnt) ->
+ {"Number of packets received", recv_cnt};
+stat_name_and_unit(recv_dvi) ->
+ {"Average packet size deviation received", {bytes,recv_dvi}};
+stat_name_and_unit(recv_max) ->
+ {"Largest packet received", {bytes,recv_max}};
+stat_name_and_unit(recv_oct) ->
+ {"Total received", {bytes,recv_oct}};
+stat_name_and_unit(send_avg) ->
+ {"Average packet size sent", {bytes, send_avg}};
+stat_name_and_unit(send_cnt) ->
+ {"Number of packets sent", send_cnt};
+stat_name_and_unit(send_max) ->
+ {"Largest packet sent", {bytes, send_max}};
+stat_name_and_unit(send_oct) ->
+ {"Total sent", {bytes, send_oct}};
+stat_name_and_unit(send_pend) ->
+ {"Data waiting to be sent from driver", {bytes,send_pend}};
+stat_name_and_unit(Key) ->
+ {atom_to_list(Key), Key}.
+
filter_monitor_info() ->
fun(Data) ->
Ms = proplists:get_value(monitors, Data),
[Pid || {process, Pid} <- Ms]
end.
-
-handle_error(Foo) ->
- Str = io_lib:format("ERROR: ~s~n",[Foo]),
- observer_lib:display_info_dialog(Str).
-
-update_grid(Grid, Opt, Ports) ->
- wx:batch(fun() -> update_grid2(Grid, Opt, Ports) end).
-update_grid2(Grid, #opt{sort_key=Sort,sort_incr=Dir}, Ports) ->
+update_grid(Grid, Sel, Opt, Ports) ->
+ wx:batch(fun() -> update_grid2(Grid, Sel, Opt, Ports) end).
+update_grid2(Grid, Sel, #opt{sort_key=Sort,sort_incr=Dir}, Ports) ->
wxListCtrl:deleteAllItems(Grid),
Update =
fun(#port{id = Id,
@@ -447,6 +567,12 @@ update_grid2(Grid, #opt{sort_key=Sort,sort_incr=Dir}, Ports) ->
observer_lib:to_str(Val))
end,
[{0,Id},{1,Connected},{2,Name},{3,Ctrl},{4,Slot}]),
+ case lists:member(Id, Sel) of
+ true ->
+ wxListCtrl:setItemState(Grid, Row, 16#FFFF, ?wxLIST_STATE_SELECTED);
+ false ->
+ wxListCtrl:setItemState(Grid, Row, 0, ?wxLIST_STATE_SELECTED)
+ end,
Row + 1
end,
PortInfo = case Dir of
@@ -456,6 +582,8 @@ update_grid2(Grid, #opt{sort_key=Sort,sort_incr=Dir}, Ports) ->
lists:foldl(Update, 0, PortInfo),
PortInfo.
+sel(#state{grid=Grid, ports=Ports}) ->
+ [Id || #port{id=Id} <- get_selected_items(Grid, Ports)].
get_selected_items(Grid, Data) ->
get_indecies(get_selected_items(Grid, -1, []), Data).
@@ -477,3 +605,15 @@ get_indecies(Rest = [_|_], I, [_|T]) ->
get_indecies(Rest, I+1, T);
get_indecies(_, _, _) ->
[].
+
+portinfo_available(NodeName) ->
+ _ = rpc:call(NodeName, code, ensure_loaded, [observer_backend]),
+ case rpc:call(NodeName, erlang, function_exported,
+ [observer_backend, get_port_list, 0]) of
+ true -> true;
+ false -> false
+ end.
+
+popup_unavailable_info(NodeName) ->
+ self() ! {info, {port_info_not_available, NodeName}},
+ ok.
diff --git a/lib/observer/src/observer_pro_wx.erl b/lib/observer/src/observer_pro_wx.erl
index ee6829b847..3083297f31 100644
--- a/lib/observer/src/observer_pro_wx.erl
+++ b/lib/observer/src/observer_pro_wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
-behaviour(wx_object).
--export([start_link/2]).
+-export([start_link/3]).
%% wx_object callbacks
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
@@ -67,12 +67,14 @@
-record(holder, {parent,
info,
- etop,
+ next=[],
sort=#sort{},
accum=[],
+ next_accum=[],
attrs,
node,
- backend_pid
+ backend_pid,
+ old_backend=false
}).
-record(state, {parent,
@@ -86,18 +88,19 @@
right_clicked_pid,
holder}).
-start_link(Notebook, Parent) ->
- wx_object:start_link(?MODULE, [Notebook, Parent], []).
+start_link(Notebook, Parent, Config) ->
+ wx_object:start_link(?MODULE, [Notebook, Parent, Config], []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-init([Notebook, Parent]) ->
+init([Notebook, Parent, Config]) ->
Attrs = observer_lib:create_attrs(),
Self = self(),
- Holder = spawn_link(fun() -> init_table_holder(Self, Attrs) end),
- {ProPanel, State} = setup(Notebook, Parent, Holder),
+ Acc = maps:get(acc, Config, false),
+ Holder = spawn_link(fun() -> init_table_holder(Self, Acc, Attrs) end),
+ {ProPanel, State} = setup(Notebook, Parent, Holder, Config),
{ProPanel, State#state{holder=Holder}}.
-setup(Notebook, Parent, Holder) ->
+setup(Notebook, Parent, Holder, Config) ->
ProPanel = wxPanel:new(Notebook, []),
Grid = create_list_box(ProPanel, Holder),
@@ -113,7 +116,7 @@ setup(Notebook, Parent, Holder) ->
panel=ProPanel,
parent_notebook=Notebook,
holder=Holder,
- timer={false, 10}
+ timer=Config
},
{ProPanel, State}.
@@ -225,7 +228,7 @@ handle_info({holder_updated, Count}, State0=#state{grid=Grid}) ->
wxListCtrl:setItemCount(Grid, Count),
Count > 0 andalso wxListCtrl:refreshItems(Grid, 0, Count-1),
-
+ observer_wx:set_status(io_lib:format("Number of Processes: ~w", [Count])),
{noreply, State};
handle_info(refresh_interval, #state{holder=Holder}=State) ->
@@ -246,7 +249,7 @@ handle_info({active, Node},
#state{holder=Holder, timer=Timer, parent=Parent}=State) ->
create_pro_menu(Parent, Holder),
Holder ! {change_node, Node},
- {noreply, State#state{timer=observer_lib:start_timer(Timer)}};
+ {noreply, State#state{timer=observer_lib:start_timer(Timer, 10)}};
handle_info(not_active, #state{timer=Timer0}=State) ->
Timer = observer_lib:stop_timer(Timer0),
@@ -264,11 +267,15 @@ terminate(_Reason, #state{holder=Holder}) ->
code_change(_, _, State) ->
{ok, State}.
+handle_call(get_config, _, #state{holder=Holder, timer=Timer}=State) ->
+ Conf = observer_lib:timer_config(Timer),
+ Accum = call(Holder, {get_accum, self()}),
+ {reply, Conf#{acc=>Accum}, State};
+
handle_call(Msg, _From, State) ->
io:format("~p:~p: Unhandled call ~p~n",[?MODULE, ?LINE, Msg]),
{reply, ok, State}.
-
handle_cast(Msg, State) ->
io:format("~p:~p: Unhandled cast ~p~n", [?MODULE, ?LINE, Msg]),
{noreply, State}.
@@ -453,18 +460,23 @@ rm_selected(_, [], [], AccIds, AccPids) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%TABLE HOLDER%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-init_table_holder(Parent, Attrs) ->
- Backend = spawn_link(node(), observer_backend,etop_collect,[self()]),
+init_table_holder(Parent, Accum0, Attrs) ->
+ process_flag(trap_exit, true),
+ Backend = spawn_link(node(), observer_backend, procs_info, [self()]),
+ Accum = case Accum0 of
+ true -> true;
+ false -> []
+ end,
table_holder(#holder{parent=Parent,
- etop=#etop_info{},
info=array:new(),
node=node(),
backend_pid=Backend,
- attrs=Attrs
+ attrs=Attrs,
+ accum=Accum
}).
table_holder(#holder{info=Info, attrs=Attrs,
- node=Node, backend_pid=Backend}=S0) ->
+ node=Node, backend_pid=Backend, old_backend=Old}=S0) ->
receive
{get_row, From, Row, Col} ->
get_row(From, Row, Col, Info),
@@ -472,14 +484,25 @@ table_holder(#holder{info=Info, attrs=Attrs,
{get_attr, From, Row} ->
get_attr(From, Row, Attrs),
table_holder(S0);
+ {procs_info, Backend, Procs} ->
+ State = handle_update(Procs, S0),
+ table_holder(State);
+ {'EXIT', Backend, normal} when Old =:= false ->
+ S1 = update_complete(S0),
+ table_holder(S1#holder{backend_pid=undefined});
{Backend, EtopInfo=#etop_info{}} ->
- State = handle_update(EtopInfo, S0),
+ State = handle_update_old(EtopInfo, S0),
table_holder(State#holder{backend_pid=undefined});
refresh when is_pid(Backend)->
table_holder(S0); %% Already updating
refresh ->
- Pid = spawn_link(Node,observer_backend,etop_collect,[self()]),
- table_holder(S0#holder{backend_pid=Pid});
+ Pid = case Old of
+ true ->
+ spawn_link(Node, observer_backend, etop_collect, [self()]);
+ false ->
+ spawn_link(Node, observer_backend, procs_info, [self()])
+ end,
+ table_holder(S0#holder{backend_pid=Pid});
{change_sort, Col} ->
State = change_sort(Col, S0),
table_holder(State);
@@ -492,7 +515,6 @@ table_holder(#holder{info=Info, attrs=Attrs,
{get_name_or_pid, From, Indices} ->
get_name_or_pid(From, Indices, Info),
table_holder(S0);
-
{get_node, From} ->
From ! {self(), Node},
table_holder(S0);
@@ -501,30 +523,50 @@ table_holder(#holder{info=Info, attrs=Attrs,
true ->
table_holder(S0);
false ->
- self() ! refresh,
- table_holder(S0#holder{node=NewNode})
- end;
+ _ = rpc:call(NewNode, code, ensure_loaded, [observer_backend]),
+ case rpc:call(NewNode, erlang, function_exported,
+ [observer_backend,procs_info, 1]) of
+ true ->
+ self() ! refresh,
+ table_holder(S0#holder{node=NewNode, old_backend=false});
+ false ->
+ self() ! refresh,
+ table_holder(S0#holder{node=NewNode, old_backend=true});
+ _ ->
+ table_holder(S0)
+ end
+ end;
{accum, Bool} ->
table_holder(change_accum(Bool,S0));
{get_accum, From} ->
From ! {self(), S0#holder.accum == true},
table_holder(S0);
{dump, Fd} ->
- EtopInfo = (S0#holder.etop)#etop_info{procinfo=array:to_list(Info)},
- etop_txt:do_update(Fd, EtopInfo, #opts{node=Node}),
- file:close(Fd),
- table_holder(S0);
+ Collector = spawn_link(Node, observer_backend, etop_collect,[self()]),
+ receive
+ {Collector, EtopInfo=#etop_info{}} ->
+ etop_txt:do_update(Fd, EtopInfo, #etop_info{}, #opts{node=Node}),
+ file:close(Fd),
+ table_holder(S0);
+ {'EXIT', Collector, _} ->
+ table_holder(S0)
+ end;
stop ->
ok;
- What ->
- io:format("Table holder got ~p~n",[What]),
+ {'EXIT', Backend, normal} ->
+ table_holder(S0);
+ {'EXIT', Backend, _Reason} ->
+ %% Node crashed will be noticed soon..
+ table_holder(S0#holder{backend_pid=undefined});
+ _What ->
+ %% io:format("~p: Table holder got ~p~n",[?MODULE, _What]),
table_holder(S0)
end.
change_sort(Col, S0=#holder{parent=Parent, info=Data, sort=Sort0}) ->
{Sort, ProcInfo}=sort(Col, Sort0, Data),
Parent ! {holder_updated, array:size(Data)},
- S0#holder{info=ProcInfo, sort=Sort}.
+ S0#holder{info=array:from_list(ProcInfo), sort=Sort}.
change_accum(true, S0) ->
S0#holder{accum=true};
@@ -532,23 +574,45 @@ change_accum(false, S0=#holder{info=Info}) ->
self() ! refresh,
S0#holder{accum=lists:sort(array:to_list(Info))}.
-handle_update(EI=#etop_info{procinfo=ProcInfo0},
- S0=#holder{parent=Parent, sort=Sort=#sort{sort_key=KeyField}}) ->
- {ProcInfo1, S1} = accum(ProcInfo0, S0),
+handle_update_old(#etop_info{procinfo=ProcInfo0},
+ S0=#holder{parent=Parent, sort=Sort=#sort{sort_key=KeyField}}) ->
+ {ProcInfo1, Accum} = accum(ProcInfo0, S0),
{_SO, ProcInfo} = sort(KeyField, Sort#sort{sort_key=undefined}, ProcInfo1),
- Parent ! {holder_updated, array:size(ProcInfo)},
- S1#holder{info=ProcInfo, etop=EI#etop_info{procinfo=[]}}.
+ Info = array:from_list(ProcInfo),
+ Parent ! {holder_updated, array:size(Info)},
+ S0#holder{info=Info, accum=Accum}.
+
+handle_update(ProcInfo0, S0=#holder{next=Next, sort=#sort{sort_key=KeyField}}) ->
+ {ProcInfo1, Accum} = accum(ProcInfo0, S0),
+ Sort = sort_fun(KeyField, true),
+ Merge = merge_fun(KeyField),
+ Merged = Merge(Sort(ProcInfo1), Next),
+ case Accum of
+ true -> S0#holder{next=Merged};
+ _List -> S0#holder{next=Merged, next_accum=Accum}
+ end.
-accum(ProcInfo, State=#holder{accum=true}) ->
- {ProcInfo, State};
-accum(ProcInfo0, State=#holder{accum=Previous}) ->
+update_complete(#holder{parent=Parent, sort=#sort{sort_incr=Incr},
+ next=ProcInfo, accum=Accum, next_accum=NextAccum}=S0) ->
+ Info = case Incr of
+ true -> array:from_list(ProcInfo);
+ false -> array:from_list(lists:reverse(ProcInfo))
+ end,
+ Parent ! {holder_updated, array:size(Info)},
+ S0#holder{info=Info, accum= Accum =:= true orelse NextAccum,
+ next=[], next_accum=[]}.
+
+accum(ProcInfo, #holder{accum=true}) ->
+ {ProcInfo, true};
+accum(ProcInfo0, #holder{accum=Previous, next_accum=Next}) ->
+ Accum = [{Pid, Reds} || #etop_proc_info{pid=Pid, reds=Reds} <- ProcInfo0],
ProcInfo = lists:sort(ProcInfo0),
- {accum2(ProcInfo,Previous,[]), State#holder{accum=ProcInfo}}.
+ {accum2(ProcInfo,Previous,[]), lists:merge(lists:sort(Accum), Next)}.
-accum2([PI=#etop_proc_info{pid=Pid, reds=Reds, runtime=RT}|PIs],
- [#etop_proc_info{pid=Pid, reds=OldReds, runtime=OldRT}|Old], Acc) ->
- accum2(PIs, Old, [PI#etop_proc_info{reds=Reds-OldReds, runtime=RT-OldRT}|Acc]);
-accum2(PIs=[#etop_proc_info{pid=Pid}|_], [#etop_proc_info{pid=OldPid}|Old], Acc)
+accum2([PI=#etop_proc_info{pid=Pid, reds=Reds}|PIs],
+ [{Pid, OldReds}|Old], Acc) ->
+ accum2(PIs, Old, [PI#etop_proc_info{reds=Reds-OldReds}|Acc]);
+accum2(PIs=[#etop_proc_info{pid=Pid}|_], [{OldPid,_}|Old], Acc)
when Pid > OldPid ->
accum2(PIs, Old, Acc);
accum2([PI|PIs], Old, Acc) ->
@@ -559,14 +623,52 @@ sort(Col, Opt, Table)
when not is_list(Table) ->
sort(Col,Opt,array:to_list(Table));
sort(Col, Opt=#sort{sort_key=Col, sort_incr=Bool}, Table) ->
- {Opt#sort{sort_incr=not Bool},
- array:from_list(lists:reverse(Table))};
-sort(Col, S=#sort{sort_incr=true}, Table) ->
- {S#sort{sort_key=Col},
- array:from_list(lists:keysort(col_to_element(Col), Table))};
-sort(Col, S=#sort{sort_incr=false}, Table) ->
- {S#sort{sort_key=Col},
- array:from_list(lists:reverse(lists:keysort(col_to_element(Col), Table)))}.
+ {Opt#sort{sort_incr=not Bool},lists:reverse(Table)};
+sort(Col, S=#sort{sort_incr=Incr}, Table) ->
+ Sort = sort_fun(Col, Incr),
+ {S#sort{sort_key=Col}, Sort(Table)}.
+
+sort_fun(?COL_NAME, true) ->
+ fun(Table) -> lists:sort(fun sort_name/2, Table) end;
+sort_fun(?COL_NAME, false) ->
+ fun(Table) -> lists:sort(fun sort_name_rev/2, Table) end;
+sort_fun(Col, true) ->
+ N = col_to_element(Col),
+ fun(Table) -> lists:keysort(N, Table) end;
+sort_fun(Col, false) ->
+ N = col_to_element(Col),
+ fun(Table) -> lists:reverse(lists:keysort(N, Table)) end.
+
+merge_fun(?COL_NAME) ->
+ fun(A,B) -> lists:merge(fun sort_name/2, A, B) end;
+merge_fun(Col) ->
+ KeyField = col_to_element(Col),
+ fun(A,B) -> lists:keymerge(KeyField, A, B) end.
+
+
+sort_name(#etop_proc_info{name={_,_,_}=A}, #etop_proc_info{name={_,_,_}=B}) ->
+ A =< B;
+sort_name(#etop_proc_info{name=A}, #etop_proc_info{name=B})
+ when is_atom(A), is_atom(B) ->
+ A =< B;
+sort_name(#etop_proc_info{name=Reg}, #etop_proc_info{name={M,_F,_A}})
+ when is_atom(Reg) ->
+ Reg < M;
+sort_name(#etop_proc_info{name={M,_,_}}, #etop_proc_info{name=Reg})
+ when is_atom(Reg) ->
+ M < Reg.
+
+sort_name_rev(#etop_proc_info{name={_,_,_}=A}, #etop_proc_info{name={_,_,_}=B}) ->
+ A >= B;
+sort_name_rev(#etop_proc_info{name=A}, #etop_proc_info{name=B})
+ when is_atom(A), is_atom(B) ->
+ A >= B;
+sort_name_rev(#etop_proc_info{name=Reg}, #etop_proc_info{name={M,_F,_A}})
+ when is_atom(Reg) ->
+ Reg >= M;
+sort_name_rev(#etop_proc_info{name={M,_,_}}, #etop_proc_info{name=Reg})
+ when is_atom(Reg) ->
+ M >= Reg.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/observer/src/observer_procinfo.erl b/lib/observer/src/observer_procinfo.erl
index 620979dcc9..10decd8b62 100644
--- a/lib/observer/src/observer_procinfo.erl
+++ b/lib/observer/src/observer_procinfo.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -92,7 +92,7 @@ init([Pid, ParentFrame, Parent]) ->
observer_wx:return_to_localnode(ParentFrame, node(Pid)),
{stop, badrpc};
process_undefined ->
- observer_lib:display_info_dialog("No such alive process"),
+ observer_lib:display_info_dialog(ParentFrame,"No such alive process"),
{stop, normal}
end.
@@ -198,10 +198,11 @@ code_change(_, _, State) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init_process_page(Panel, Pid) ->
- Fields0 = process_info_fields(Pid),
+ WSz = observer_wx:try_rpc(node(Pid), erlang, system_info,[wordsize]),
+ Fields0 = process_info_fields(Pid, WSz),
{FPanel, _, UpFields} = observer_lib:display_info(Panel, Fields0),
{FPanel, fun() ->
- Fields = process_info_fields(Pid),
+ Fields = process_info_fields(Pid, WSz),
observer_lib:update_info(UpFields, Fields)
end}.
@@ -359,7 +360,7 @@ create_menus(MenuBar) ->
{"View", [#create_menu{id=?REFRESH, text="Refresh\tCtrl-R"}]}],
observer_lib:create_menus(Menus, MenuBar, new_window).
-process_info_fields(Pid) ->
+process_info_fields(Pid, WSz) ->
Struct = [{"Overview",
[{"Initial Call", initial_call},
{"Current Function", current_function},
@@ -383,10 +384,10 @@ process_info_fields(Pid) ->
{"Monitored by", {click, monitored_by}}]},
{"Memory and Garbage Collection", right,
[{"Memory", {bytes, memory}},
- {"Stack and Heaps", {bytes, total_heap_size}},
- {"Heap Size", {bytes, heap_size}},
- {"Stack Size", {bytes, stack_size}},
- {"GC Min Heap Size", {bytes, get_gc_info(min_heap_size)}},
+ {"Stack and Heaps", {{words,WSz}, total_heap_size}},
+ {"Heap Size", {{words,WSz}, heap_size}},
+ {"Stack Size", {{words,WSz}, stack_size}},
+ {"GC Min Heap Size", {{words,WSz}, get_gc_info(min_heap_size)}},
{"GC FullSweep After", get_gc_info(fullsweep_after)}
]}],
case observer_wx:try_rpc(node(Pid), erlang, process_info, [Pid, item_list()]) of
@@ -434,7 +435,7 @@ get_gc_info(Arg) ->
filter_monitor_info() ->
fun(Data) ->
Ms = proplists:get_value(monitors, Data),
- [Pid || {process, Pid} <- Ms]
+ [Id || {_Type, Id} <- Ms] % Type is process or port
end.
stringify_bins(Data) ->
diff --git a/lib/observer/src/observer_sys_wx.erl b/lib/observer/src/observer_sys_wx.erl
index fa824995f7..db86c05bed 100644
--- a/lib/observer/src/observer_sys_wx.erl
+++ b/lib/observer/src/observer_sys_wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
-behaviour(wx_object).
--export([start_link/2]).
+-export([start_link/3]).
%% wx_object callbacks
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
handle_event/2, handle_cast/2]).
@@ -41,12 +41,12 @@
fields,
timer}).
-start_link(Notebook, Parent) ->
- wx_object:start_link(?MODULE, [Notebook, Parent], []).
+start_link(Notebook, Parent, Config) ->
+ wx_object:start_link(?MODULE, [Notebook, Parent, Config], []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-init([Notebook, Parent]) ->
+init([Notebook, Parent, Config]) ->
SysInfo = observer_backend:sys_info(),
{Sys, Mem, Cpu, Stats} = info_fields(),
Panel = wxPanel:new(Notebook),
@@ -69,7 +69,7 @@ init([Notebook, Parent]) ->
wxSizer:add(Sizer, HSizer1, [{flag, ?wxEXPAND bor BorderFlags bor ?wxBOTTOM},
{proportion, 0}, {border, 5}]),
wxPanel:setSizer(Panel, Sizer),
- Timer = observer_lib:start_timer(10),
+ Timer = observer_lib:start_timer(Config, 10),
{Panel, #sys_wx_state{parent=Parent,
parent_notebook=Notebook,
panel=Panel, sizer=Sizer,
@@ -167,6 +167,9 @@ terminate(_Reason, _State) ->
code_change(_, _, State) ->
{ok, State}.
+handle_call(get_config, _, #sys_wx_state{timer=Timer}=State) ->
+ {reply, observer_lib:timer_config(Timer), State};
+
handle_call(Msg, _From, State) ->
io:format("~p~p: Unhandled Call ~p~n",[?MODULE, ?LINE, Msg]),
{reply, ok, State}.
diff --git a/lib/observer/src/observer_trace_wx.erl b/lib/observer/src/observer_trace_wx.erl
index af90e2100c..b960c61ff0 100644
--- a/lib/observer/src/observer_trace_wx.erl
+++ b/lib/observer/src/observer_trace_wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
-module(observer_trace_wx).
--export([start_link/2, add_processes/1, add_ports/1]).
+-export([start_link/3, add_processes/1, add_ports/1]).
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
handle_event/2, handle_cast/2]).
@@ -88,8 +88,8 @@
-record(titem, {id, opts}).
-start_link(Notebook, ParentPid) ->
- wx_object:start_link(?MODULE, [Notebook, ParentPid], []).
+start_link(Notebook, ParentPid, Config) ->
+ wx_object:start_link(?MODULE, [Notebook, ParentPid, Config], []).
add_processes(Pids) when is_list(Pids) ->
wx_object:cast(observer_wx:get_tracer(), {add_processes, Pids}).
@@ -99,10 +99,10 @@ add_ports(Ports) when is_list(Ports) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-init([Notebook, ParentPid]) ->
- wx:batch(fun() -> create_window(Notebook, ParentPid) end).
+init([Notebook, ParentPid, Config]) ->
+ wx:batch(fun() -> create_window(Notebook, ParentPid, Config) end).
-create_window(Notebook, ParentPid) ->
+create_window(Notebook, ParentPid, Config) ->
%% Create the window
Panel = wxPanel:new(Notebook, [{size, wxWindow:getClientSize(Notebook)}]),
Sizer = wxBoxSizer:new(?wxVERTICAL),
@@ -130,11 +130,16 @@ create_window(Notebook, ParentPid) ->
wxSizer:add(Sizer, Buttons, [{flag, ?wxLEFT bor ?wxRIGHT bor ?wxDOWN},
{border, 5}, {proportion,0}]),
wxWindow:setSizer(Panel, Sizer),
+ MS = parse_ms(maps:get(match_specs, Config, []), default_matchspecs()),
{Panel, #state{parent=ParentPid, panel=Panel,
n_view=NodeView, proc_view=ProcessView, port_view=PortView,
m_view=ModView, f_view=FuncView,
toggle_button = ToggleButton,
- match_specs=default_matchspecs()}}.
+ output=maps:get(output, Config, []),
+ def_proc_flags=maps:get(procflags, Config, []),
+ def_port_flags=maps:get(portflags, Config, []),
+ match_specs=MS
+ }}.
default_matchspecs() ->
[{Key,default_matchspecs(Key)} || Key <- [funcs,send,'receive']].
@@ -397,27 +402,19 @@ handle_event(#wx{id=?LOG_SAVE, userData=TCtrl}, #state{panel=Panel} = State) ->
{noreply, State};
handle_event(#wx{id = ?SAVE_TRACEOPTS},
- #state{panel = Panel,
- def_proc_flags = ProcFlags,
- def_port_flags = PortFlags,
- match_specs = MatchSpecs,
- tpatterns = TracePatterns,
- output = Output
- } = State) ->
+ #state{panel = Panel} = State) ->
Dialog = wxFileDialog:new(Panel, [{style, ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT}]),
case wxFileDialog:showModal(Dialog) of
?wxID_OK ->
Path = wxFileDialog:getPath(Dialog),
- write_file(Panel, Path,
- ProcFlags, PortFlags, MatchSpecs, Output,
- dict:to_list(TracePatterns)
- );
+ write_file(Panel, Path, get_config(State));
_ ->
ok
end,
wxDialog:destroy(Dialog),
{noreply, State};
+
handle_event(#wx{id = ?LOAD_TRACEOPTS}, #state{panel = Panel} = State) ->
Dialog = wxFileDialog:new(Panel, [{style, ?wxFD_FILE_MUST_EXIST}]),
State2 = case wxFileDialog:showModal(Dialog) of
@@ -690,6 +687,10 @@ handle_event(#wx{id=ID, event = What}, State) ->
{noreply, State}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+handle_call(get_config, _, State) ->
+ Config0 = get_config(State),
+ Config = lists:keydelete(trace_p, 1, Config0),
+ {reply, maps:from_list(Config), State};
handle_call(Msg, From, _State) ->
error({unhandled_call, Msg, From}).
@@ -1101,26 +1102,38 @@ ftup(Trace, Index, Size) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-write_file(Frame, Filename, ProcFlags, PortFlags, MatchSpecs, Output, TPs) ->
+get_config(#state{def_proc_flags = ProcFlags,
+ def_port_flags = PortFlags,
+ match_specs = MatchSpecs0,
+ tpatterns = TracePatterns,
+ output = Output}) ->
MSToList = fun(#match_spec{name=Id, term=T, func=F}) ->
[{name,Id},{term,T},{func,F}]
end,
- MSTermList = [{ms,Key,[MSToList(MS) || MS <- MSs]} ||
- {Key,MSs} <- MatchSpecs],
+ MatchSpecs = [{ms,Key,[MSToList(MS) || MS <- MSs]} ||
+ {Key,MSs} <- MatchSpecs0],
TPToTuple = fun(#tpattern{fa={F,A}, ms=Ms}) ->
- {F,A,MSToList(Ms)}
+ {F,A,MSToList(Ms)}
end,
ModuleTermList = [{tp, Module, [TPToTuple(FTP) || FTP <- FTPs]} ||
- {Module,FTPs} <- TPs],
-
+ {Module,FTPs} <- dict:to_list(TracePatterns)],
+ [{procflags,ProcFlags},
+ {portflags,PortFlags},
+ {match_specs,MatchSpecs},
+ {output,Output},
+ {trace_p,ModuleTermList}].
+
+write_file(Frame, Filename, Config) ->
Str =
["%%%\n%%% This file is generated by Observer\n",
"%%%\n%%% DO NOT EDIT!\n%%%\n",
- [io_lib:format("~p.~n",[MSTerm]) || MSTerm <- MSTermList],
- io_lib:format("~p.~n",[{procflags,ProcFlags}]),
- io_lib:format("~p.~n",[{portflags,PortFlags}]),
- io_lib:format("~p.~n",[{output,Output}]),
- [io_lib:format("~p.~n",[ModuleTerm]) || ModuleTerm <- ModuleTermList]
+ [io_lib:format("~p.~n",[MSTerm]) ||
+ MSTerm <- proplists:get_value(match_specs, Config)],
+ io_lib:format("~p.~n",[lists:keyfind(procflags, 1, Config)]),
+ io_lib:format("~p.~n",[lists:keyfind(portflags, 1, Config)]),
+ io_lib:format("~p.~n",[lists:keyfind(output, 1, Config)]),
+ [io_lib:format("~p.~n",[ModuleTerm]) ||
+ ModuleTerm <- proplists:get_value(trace_p, Config)]
],
case file:write_file(Filename, list_to_binary(Str)) of
diff --git a/lib/observer/src/observer_tv_table.erl b/lib/observer/src/observer_tv_table.erl
index 75e6919642..789e060cfb 100644
--- a/lib/observer/src/observer_tv_table.erl
+++ b/lib/observer/src/observer_tv_table.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -233,9 +233,22 @@ handle_event(#wx{id=?ID_REFRESH},State = #state{pid=Pid}) ->
{noreply, State};
handle_event(#wx{event=#wxList{type=command_list_col_click, col=Col}},
- State = #state{pid=Pid}) ->
+ State = #state{pid=Pid, grid=Grid, selected=OldSel}) ->
+ SelObj = case OldSel of
+ undefined -> undefined;
+ _ -> get_row(Pid, OldSel, term)
+ end,
Pid ! {sort, Col+1},
- {noreply, State};
+ case SelObj =/= undefined andalso search(Pid, SelObj, -1, true, term) of
+ false when is_integer(OldSel) ->
+ wxListCtrl:setItemState(Grid, OldSel, 0, ?wxLIST_STATE_SELECTED),
+ {noreply, State#state{selected=undefined}};
+ false ->
+ {noreply, State#state{selected=undefined}};
+ Row ->
+ wxListCtrl:setItemState(Grid, Row, 16#FFFF, ?wxLIST_STATE_SELECTED),
+ {noreply, State#state{selected=Row}}
+ end;
handle_event(#wx{event=#wxSize{size={W,_}}}, State=#state{grid=Grid}) ->
observer_lib:set_listctrl_col_size(Grid, W),
@@ -607,6 +620,17 @@ keysort(Col, Table) ->
end,
lists:sort(Sort, Table).
+search([Term, -1, true, term], S=#holder{parent=Parent, table=Table}) ->
+ Search = fun(Idx, [Tuple|_]) ->
+ Tuple =:= Term andalso throw(Idx),
+ Tuple
+ end,
+ try array:map(Search, Table) of
+ _ -> Parent ! {self(), false}
+ catch Index ->
+ Parent ! {self(), Index}
+ end,
+ S;
search([Str, Row, Dir0, CaseSens],
S=#holder{parent=Parent, n=N, table=Table}) ->
Opt = case CaseSens of
@@ -642,6 +666,8 @@ get_row(From, Row, Col, Table) ->
From ! {self(), format(Object)};
[Object|_] when Col =:= all_multiline ->
From ! {self(), io_lib:format("~p", [Object])};
+ [Object|_] when Col =:= term ->
+ From ! {self(), Object};
[Object|_] when tuple_size(Object) >= Col ->
From ! {self(), format(element(Col, Object))};
_ ->
diff --git a/lib/observer/src/observer_tv_wx.erl b/lib/observer/src/observer_tv_wx.erl
index 59f6443551..9564bdfa1c 100644
--- a/lib/observer/src/observer_tv_wx.erl
+++ b/lib/observer/src/observer_tv_wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
%% %CopyrightEnd%
-module(observer_tv_wx).
--export([start_link/2, display_table_info/4]).
+-export([start_link/3, display_table_info/4]).
%% wx_object callbacks
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
@@ -58,10 +58,10 @@
timer
}).
-start_link(Notebook, Parent) ->
- wx_object:start_link(?MODULE, [Notebook, Parent], []).
+start_link(Notebook, Parent, Config) ->
+ wx_object:start_link(?MODULE, [Notebook, Parent, Config], []).
-init([Notebook, Parent]) ->
+init([Notebook, Parent, Config]) ->
Panel = wxPanel:new(Notebook),
Sizer = wxBoxSizer:new(?wxVERTICAL),
Style = ?wxLC_REPORT bor ?wxLC_SINGLE_SEL bor ?wxLC_HRULES,
@@ -78,11 +78,11 @@ init([Notebook, Parent]) ->
Col + 1
end,
ListItems = [{"Table Name", ?wxLIST_FORMAT_LEFT, 200},
- {"Table Id", ?wxLIST_FORMAT_RIGHT, 100},
{"Objects", ?wxLIST_FORMAT_RIGHT, 100},
{"Size (kB)", ?wxLIST_FORMAT_RIGHT, 100},
{"Owner Pid", ?wxLIST_FORMAT_CENTER, 150},
- {"Owner Name", ?wxLIST_FORMAT_LEFT, 200}
+ {"Owner Name", ?wxLIST_FORMAT_LEFT, 200},
+ {"Table Id", ?wxLIST_FORMAT_LEFT, 250}
],
lists:foldl(AddListEntry, 0, ListItems),
wxListItem:destroy(Li),
@@ -94,25 +94,31 @@ init([Notebook, Parent]) ->
wxListCtrl:connect(Grid, size, [{skip, true}]),
wxWindow:setFocus(Grid),
- {Panel, #state{grid=Grid, parent=Parent, panel=Panel, timer={false, 10}}}.
+ {Panel, #state{grid=Grid, parent=Parent, panel=Panel,
+ timer=Config,
+ opt=#opt{type=maps:get(type, Config, ets),
+ sys_hidden=maps:get(sys_hidden, Config, true),
+ unread_hidden=maps:get(unread_hidden, Config, true)}
+ }}.
handle_event(#wx{id=?ID_REFRESH},
State = #state{node=Node, grid=Grid, opt=Opt}) ->
Tables = get_tables(Node, Opt),
- Tabs = update_grid(Grid, Opt, Tables),
- {noreply, State#state{tabs=Tabs}};
+ {Tabs,Sel} = update_grid(Grid, sel(State), Opt, Tables),
+ Sel =/= undefined andalso wxListCtrl:ensureVisible(Grid, Sel),
+ {noreply, State#state{tabs=Tabs, selected=Sel}};
handle_event(#wx{event=#wxList{type=command_list_col_click, col=Col}},
State = #state{node=Node, grid=Grid,
opt=Opt0=#opt{sort_key=Key, sort_incr=Bool}}) ->
- Opt = case Col+2 of
+ Opt = case col2key(Col) of
Key -> Opt0#opt{sort_incr=not Bool};
NewKey -> Opt0#opt{sort_key=NewKey}
end,
Tables = get_tables(Node, Opt),
- Tabs = update_grid(Grid, Opt, Tables),
+ {Tabs,Sel} = update_grid(Grid, sel(State), Opt, Tables),
wxWindow:setFocus(Grid),
- {noreply, State#state{opt=Opt, tabs=Tabs}};
+ {noreply, State#state{opt=Opt, tabs=Tabs, selected=Sel}};
handle_event(#wx{id=Id}, State = #state{node=Node, grid=Grid, opt=Opt0})
when Id >= ?ID_ETS, Id =< ?ID_SYSTEM_TABLES ->
@@ -124,12 +130,14 @@ handle_event(#wx{id=Id}, State = #state{node=Node, grid=Grid, opt=Opt0})
end,
case get_tables2(Node, Opt) of
Error = {error, _} ->
+ Id =:= ?ID_MNESIA andalso
+ wxMenuBar:check(observer_wx:get_menubar(), ?ID_ETS, true),
self() ! Error,
{noreply, State};
Tables ->
- Tabs = update_grid(Grid, Opt, Tables),
+ {Tabs, Sel} = update_grid(Grid, sel(State), Opt, Tables),
wxWindow:setFocus(Grid),
- {noreply, State#state{opt=Opt, tabs=Tabs}}
+ {noreply, State#state{opt=Opt, tabs=Tabs, selected=Sel}}
end;
handle_event(#wx{event=#wxSize{size={W,_}}}, State=#state{grid=Grid}) ->
@@ -200,6 +208,12 @@ handle_event(Event, _State) ->
handle_sync_event(_Event, _Obj, _State) ->
ok.
+handle_call(get_config, _, #state{timer=Timer, opt=Opt}=State) ->
+ #opt{type=Type, sys_hidden=Sys, unread_hidden=Unread} = Opt,
+ Conf0 = observer_lib:timer_config(Timer),
+ Conf = Conf0#{type=>Type, sys_hidden=>Sys, unread_hidden=>Unread},
+ {reply, Conf, State};
+
handle_call(Event, From, _State) ->
error({unhandled_call, Event, From}).
@@ -213,26 +227,38 @@ handle_info(refresh_interval, State = #state{node=Node, grid=Grid, opt=Opt,
%% no change
{noreply, State};
Tables ->
- Tabs = update_grid(Grid, Opt, Tables),
- {noreply, State#state{tabs=Tabs}}
+ {Tabs, Sel} = update_grid(Grid, sel(State), Opt, Tables),
+ Sel =/= undefined andalso wxListCtrl:ensureVisible(Grid, Sel),
+ {noreply, State#state{tabs=Tabs, selected=Sel}}
end;
-handle_info({active, Node}, State = #state{parent=Parent, grid=Grid, opt=Opt,
+handle_info({active, Node}, State = #state{parent=Parent, grid=Grid, opt=Opt0,
timer=Timer0}) ->
- Tables = get_tables(Node, Opt),
- Tabs = update_grid(Grid, Opt, Tables),
+ {Tables, Opt} = case Opt0#opt.type =:= mnesia andalso get_tables2(Node, Opt0) of
+ Ts when is_list(Ts) ->
+ {Ts, Opt0};
+ _ -> % false or error getting mnesia tables
+ Opt1 = Opt0#opt{type=ets},
+ {get_tables(Node, Opt1), Opt1}
+ end,
+ {Tabs,Sel} = update_grid(Grid, sel(State), Opt, Tables),
wxWindow:setFocus(Grid),
create_menus(Parent, Opt),
- Timer = observer_lib:start_timer(Timer0),
- {noreply, State#state{node=Node, tabs=Tabs, timer=Timer}};
+ Timer = observer_lib:start_timer(Timer0, 10),
+ {noreply, State#state{node=Node, tabs=Tabs, timer=Timer, opt=Opt, selected=Sel}};
handle_info(not_active, State = #state{timer = Timer0}) ->
Timer = observer_lib:stop_timer(Timer0),
{noreply, State#state{timer=Timer}};
-handle_info({error, Error}, State) ->
- handle_error(Error),
- {noreply, State};
+handle_info({error, Error}, #state{panel=Panel,opt=Opt}=State) ->
+ Str = io_lib:format("ERROR: ~s~n",[Error]),
+ observer_lib:display_info_dialog(Panel,Str),
+ case Opt#opt.type of
+ mnesia -> wxMenuBar:check(observer_wx:get_menubar(), ?ID_ETS, true);
+ _ -> ok
+ end,
+ {noreply, State#state{opt=Opt#opt{type=ets}}};
handle_info(_Event, State) ->
{noreply, State}.
@@ -283,6 +309,13 @@ get_tables2(Node, #opt{type=Type, sys_hidden=Sys, unread_hidden=Unread}) ->
[list_to_tabrec(Tab) || Tab <- Result]
end.
+col2key(0) -> #tab.name;
+col2key(1) -> #tab.size;
+col2key(2) -> #tab.memory;
+col2key(3) -> #tab.owner;
+col2key(4) -> #tab.reg_name;
+col2key(5) -> #tab.id.
+
list_to_tabrec(PL) ->
#tab{name = proplists:get_value(name, PL),
id = proplists:get_value(id, PL, ignore),
@@ -353,17 +386,15 @@ list_to_strings([A]) -> integer_to_list(A);
list_to_strings([A|B]) ->
integer_to_list(A) ++ " ," ++ list_to_strings(B).
-handle_error(Foo) ->
- Str = io_lib:format("ERROR: ~s~n",[Foo]),
- observer_lib:display_info_dialog(Str).
+update_grid(Grid, Selected, Opt, Tables) ->
+ wx:batch(fun() -> update_grid2(Grid, Selected, Opt, Tables) end).
-update_grid(Grid, Opt, Tables) ->
- wx:batch(fun() -> update_grid2(Grid, Opt, Tables) end).
-update_grid2(Grid, #opt{sort_key=Sort,sort_incr=Dir}, Tables) ->
+update_grid2(Grid, {SelName,SelId}, #opt{sort_key=Sort,sort_incr=Dir}, Tables) ->
wxListCtrl:deleteAllItems(Grid),
Update =
fun(#tab{name = Name, id = Id, owner = Owner, size = Size, memory = Memory,
- protection = Protection, reg_name = RegName}, Row) ->
+ protection = Protection, reg_name = RegName},
+ {Row, Sel}) ->
_Item = wxListCtrl:insertItem(Grid, Row, ""),
if (Row rem 2) =:= 0 ->
wxListCtrl:setItemBackgroundColour(Grid, Row, ?BG_EVEN);
@@ -378,13 +409,26 @@ update_grid2(Grid, #opt{sort_key=Sort,sort_incr=Dir}, Tables) ->
({Col, Val}) ->
wxListCtrl:setItem(Grid, Row, Col, observer_lib:to_str(Val))
end,
- [{0,Name}, {1,Id}, {2,Size}, {3, Memory div 1024},
- {4,Owner}, {5,RegName}]),
- Row + 1
+ [{0,Name}, {1,Size}, {2, Memory div 1024},
+ {3,Owner}, {4,RegName}, {5,Id}]),
+ if SelName =:= Name, SelId =:= Id ->
+ wxListCtrl:setItemState(Grid, Row, 16#FFFF, ?wxLIST_STATE_SELECTED),
+ {Row+1, Row};
+ true ->
+ wxListCtrl:setItemState(Grid, Row, 0, ?wxLIST_STATE_SELECTED),
+ {Row+1, Sel}
+ end
end,
ProcInfo = case Dir of
false -> lists:reverse(lists:keysort(Sort, Tables));
true -> lists:keysort(Sort, Tables)
end,
- lists:foldl(Update, 0, ProcInfo),
- ProcInfo.
+ {_, Sel} = lists:foldl(Update, {0, undefined}, ProcInfo),
+ {ProcInfo, Sel}.
+
+sel(#state{selected=Sel, tabs=Tabs}) ->
+ try lists:nth(Sel+1, Tabs) of
+ #tab{name=Name, id=Id} -> {Name, Id}
+ catch _:_ ->
+ {undefined, undefined}
+ end.
diff --git a/lib/observer/src/observer_wx.erl b/lib/observer/src/observer_wx.erl
index 301bb4b32f..9b9e80f479 100644
--- a/lib/observer/src/observer_wx.erl
+++ b/lib/observer/src/observer_wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@
-behaviour(wx_object).
-export([start/0, stop/0]).
--export([create_menus/2, get_attrib/1, get_tracer/0, get_active_node/0,
+-export([create_menus/2, get_attrib/1, get_tracer/0, get_active_node/0, get_menubar/0,
set_status/1, create_txt_dialog/4, try_rpc/4, return_to_localnode/2]).
-export([init/1, handle_event/2, handle_cast/2, terminate/2, code_change/3,
@@ -54,20 +54,14 @@
status_bar,
notebook,
main_panel,
- pro_panel,
- port_panel,
- tv_panel,
- sys_panel,
- trace_panel,
- app_panel,
- perf_panel,
- allc_panel,
+ panels,
active_tab,
node,
nodes,
prev_node="",
log = false,
- reply_to=false
+ reply_to=false,
+ config
}).
start() ->
@@ -94,6 +88,9 @@ get_tracer() ->
get_active_node() ->
wx_object:call(observer, get_active_node).
+get_menubar() ->
+ wx_object:call(observer, get_menubar).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init(_Args) ->
@@ -115,6 +112,10 @@ init(_Args) ->
setup(#state{frame = Frame} = State) ->
%% Setup Menubar & Menus
+ Config = load_config(),
+ Cnf = fun(Who) ->
+ proplists:get_value(Who, Config, #{})
+ end,
MenuBar = wxMenuBar:new(),
{Nodes, NodeMenus} = get_nodes(),
@@ -128,7 +129,7 @@ setup(#state{frame = Frame} = State) ->
Notebook = wxNotebook:new(Panel, ?ID_NOTEBOOK, [{style, ?wxBK_DEFAULT}]),
%% System Panel
- SysPanel = observer_sys_wx:start_link(Notebook, self()),
+ SysPanel = observer_sys_wx:start_link(Notebook, self(), Cnf(sys_panel)),
wxNotebook:addPage(Notebook, SysPanel, "System", []),
%% Setup sizer create early to get it when window shows
@@ -142,43 +143,45 @@ setup(#state{frame = Frame} = State) ->
wxFrame:setTitle(Frame, atom_to_list(node())),
wxStatusBar:setStatusText(StatusBar, atom_to_list(node())),
- wxNotebook:connect(Notebook, command_notebook_page_changing),
- wxFrame:connect(Frame, close_window, [{skip, true}]),
+ wxNotebook:connect(Notebook, command_notebook_page_changed,
+ [{skip, true}, {id, ?ID_NOTEBOOK}]),
+ wxFrame:connect(Frame, close_window, []),
wxMenu:connect(Frame, command_menu_selected),
wxFrame:show(Frame),
%% Freeze and thaw is buggy currently
- DoFreeze = [?wxMAJOR_VERSION,?wxMINOR_VERSION] < [2,9],
+ DoFreeze = [?wxMAJOR_VERSION,?wxMINOR_VERSION] < [2,9]
+ orelse element(1, os:type()) =:= win32,
DoFreeze andalso wxWindow:freeze(Panel),
%% I postpone the creation of the other tabs so they can query/use
%% the window size
%% Perf Viewer Panel
- PerfPanel = observer_perf_wx:start_link(Notebook, self()),
+ PerfPanel = observer_perf_wx:start_link(Notebook, self(), Cnf(perf_panel)),
wxNotebook:addPage(Notebook, PerfPanel, "Load Charts", []),
%% Memory Allocator Viewer Panel
- AllcPanel = observer_alloc_wx:start_link(Notebook, self()),
+ AllcPanel = observer_alloc_wx:start_link(Notebook, self(), Cnf(allc_panel)),
wxNotebook:addPage(Notebook, AllcPanel, ?ALLOC_STR, []),
%% App Viewer Panel
- AppPanel = observer_app_wx:start_link(Notebook, self()),
+ AppPanel = observer_app_wx:start_link(Notebook, self(), Cnf(app_panel)),
wxNotebook:addPage(Notebook, AppPanel, "Applications", []),
%% Process Panel
- ProPanel = observer_pro_wx:start_link(Notebook, self()),
+ ProPanel = observer_pro_wx:start_link(Notebook, self(), Cnf(pro_panel)),
wxNotebook:addPage(Notebook, ProPanel, "Processes", []),
%% Port Panel
- PortPanel = observer_port_wx:start_link(Notebook, self()),
+ PortPanel = observer_port_wx:start_link(Notebook, self(), Cnf(port_panel)),
wxNotebook:addPage(Notebook, PortPanel, "Ports", []),
%% Table Viewer Panel
- TVPanel = observer_tv_wx:start_link(Notebook, self()),
+ TVPanel = observer_tv_wx:start_link(Notebook, self(), Cnf(tv_panel)),
wxNotebook:addPage(Notebook, TVPanel, "Table Viewer", []),
%% Trace Viewer Panel
- TracePanel = observer_trace_wx:start_link(Notebook, self()),
+ TracePanel = observer_trace_wx:start_link(Notebook, self(), Cnf(trace_panel)),
wxNotebook:addPage(Notebook, TracePanel, ?TRACE_STR, []),
%% Force redraw (windows needs it)
@@ -190,19 +193,21 @@ setup(#state{frame = Frame} = State) ->
SysPid = wx_object:get_pid(SysPanel),
SysPid ! {active, node()},
+ Panels = [{sys_panel, SysPanel, "System"}, %% In order
+ {perf_panel, PerfPanel, "Load Charts"},
+ {allc_panel, AllcPanel, ?ALLOC_STR},
+ {app_panel, AppPanel, "Applications"},
+ {pro_panel, ProPanel, "Processes"},
+ {port_panel, PortPanel, "Ports"},
+ {tv_panel, TVPanel, "Table Viewer"},
+ {trace_panel, TracePanel, ?TRACE_STR}],
+
UpdState = State#state{main_panel = Panel,
notebook = Notebook,
menubar = MenuBar,
status_bar = StatusBar,
- sys_panel = SysPanel,
- pro_panel = ProPanel,
- port_panel = PortPanel,
- tv_panel = TVPanel,
- trace_panel = TracePanel,
- app_panel = AppPanel,
- perf_panel = PerfPanel,
- allc_panel = AllcPanel,
active_tab = SysPid,
+ panels = Panels,
node = node(),
nodes = Nodes
},
@@ -225,11 +230,14 @@ setup(#state{frame = Frame} = State) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%Callbacks
-handle_event(#wx{event=#wxNotebook{type=command_notebook_page_changing}},
- #state{active_tab=Previous, node=Node} = State) ->
- case get_active_pid(State) of
- Previous -> {noreply, State};
+handle_event(#wx{event=#wxNotebook{type=command_notebook_page_changed, nSel=Next}},
+ #state{active_tab=Previous, node=Node, panels=Panels, status_bar=SB} = State) ->
+ {_, Obj, _} = lists:nth(Next+1, Panels),
+ case wx_object:get_pid(Obj) of
+ Previous ->
+ {noreply, State};
Pid ->
+ wxStatusBar:setStatusText(SB, ""),
Previous ! not_active,
Pid ! {active, Node},
{noreply, State#state{active_tab=Pid}}
@@ -359,8 +367,7 @@ handle_event(#wx{id = Id, event = #wxCommand{type = command_menu_selected}},
end,
{noreply, change_node_view(Node, LState)};
-handle_event(Event, State) ->
- Pid = get_active_pid(State),
+handle_event(Event, #state{active_tab=Pid} = State) ->
Pid ! Event,
{noreply, State}.
@@ -385,12 +392,16 @@ handle_call({create_menus, TabMenus}, _From,
handle_call({get_attrib, Attrib}, _From, State) ->
{reply, get(Attrib), State};
-handle_call(get_tracer, _From, State=#state{trace_panel=TraceP}) ->
+handle_call(get_tracer, _From, State=#state{panels=Panels}) ->
+ {_, TraceP, _} = lists:keyfind(trace_panel, 1, Panels),
{reply, TraceP, State};
handle_call(get_active_node, _From, State=#state{node=Node}) ->
{reply, Node, State};
+handle_call(get_menubar, _From, State=#state{menubar=MenuBar}) ->
+ {reply, MenuBar, State};
+
handle_call(stop, From, State) ->
stop_servers(State),
{noreply, State#state{reply_to=From}};
@@ -418,9 +429,7 @@ handle_info({nodedown, Node},
create_txt_dialog(Frame, Msg, "Node down", ?wxICON_EXCLAMATION),
{noreply, State3};
-handle_info({open_link, Id0}, State = #state{pro_panel=ProcViewer,
- port_panel=PortViewer,
- frame=Frame}) ->
+handle_info({open_link, Id0}, State = #state{panels=Panels,frame=Frame}) ->
Id = case Id0 of
[_|_] -> try list_to_pid(Id0) catch _:_ -> Id0 end;
_ -> Id0
@@ -428,8 +437,10 @@ handle_info({open_link, Id0}, State = #state{pro_panel=ProcViewer,
%% Forward to process tab
case Id of
Pid when is_pid(Pid) ->
+ {pro_panel, ProcViewer, _} = lists:keyfind(pro_panel, 1, Panels),
wx_object:get_pid(ProcViewer) ! {procinfo_open, Pid};
"#Port" ++ _ = Port ->
+ {port_panel, PortViewer, _} = lists:keyfind(port_panel, 1, Panels),
wx_object:get_pid(PortViewer) ! {portinfo_open, Port};
_ ->
Msg = io_lib:format("Information about ~p is not available or implemented",[Id]),
@@ -459,15 +470,13 @@ handle_info({stop, Me}, State) when Me =:= self() ->
handle_info(_Info, State) ->
{noreply, State}.
-stop_servers(#state{node=Node, log=LogOn, sys_panel=Sys, pro_panel=Procs, tv_panel=TVs,
- trace_panel=Trace, app_panel=Apps, perf_panel=Perfs,
- allc_panel=Alloc} = _State) ->
+stop_servers(#state{node=Node, log=LogOn, panels=Panels} = _State) ->
LogOn andalso rpc:block_call(Node, rb, stop, []),
Me = self(),
- Tabs = [Sys, Procs, TVs, Trace, Apps, Perfs, Alloc],
+ save_config(Panels),
Stop = fun() ->
try
- _ = [wx_object:stop(Panel) || Panel <- Tabs],
+ _ = [wx_object:stop(Panel) || {_, Panel, _} <- Panels],
ok
catch _:_ -> ok
end,
@@ -484,6 +493,27 @@ terminate(_Reason, #state{frame = Frame, reply_to=From}) ->
end,
ok.
+load_config() ->
+ case file:consult(config_file()) of
+ {ok, Config} -> Config;
+ _ -> []
+ end.
+
+save_config(Panels) ->
+ Configs = [{Name, wx_object:call(Panel, get_config)} || {Name, Panel, _} <- Panels],
+ File = config_file(),
+ case filelib:ensure_dir(File) of
+ ok ->
+ Format = [io_lib:format("~p.~n",[Conf]) || Conf <- Configs],
+ _ = file:write_file(File, Format);
+ _ ->
+ ignore
+ end.
+
+config_file() ->
+ Dir = filename:basedir(user_config, "erl_observer"),
+ filename:join(Dir, "config.txt").
+
code_change(_, _, State) ->
{ok, State}.
@@ -543,8 +573,7 @@ connect2(NodeName, Opts, Cookie) ->
{error, net_kernel, Reason}
end.
-change_node_view(Node, State) ->
- Tab = get_active_pid(State),
+change_node_view(Node, #state{active_tab=Tab} = State) ->
Tab ! not_active,
Tab ! {active, Node},
StatusText = ["Observer - " | atom_to_list(Node)],
@@ -556,37 +585,13 @@ check_page_title(Notebook) ->
Selection = wxNotebook:getSelection(Notebook),
wxNotebook:getPageText(Notebook, Selection).
-get_active_pid(#state{notebook=Notebook, pro_panel=Pro, sys_panel=Sys,
- tv_panel=Tv, trace_panel=Trace, app_panel=App,
- perf_panel=Perf, allc_panel=Alloc, port_panel=Port
- }) ->
- Panel = case check_page_title(Notebook) of
- "Processes" -> Pro;
- "Ports" -> Port;
- "System" -> Sys;
- "Table Viewer" -> Tv;
- ?TRACE_STR -> Trace;
- "Load Charts" -> Perf;
- "Applications" -> App;
- ?ALLOC_STR -> Alloc
- end,
- wx_object:get_pid(Panel).
-
-pid2panel(Pid, #state{pro_panel=Pro, sys_panel=Sys,
- tv_panel=Tv, trace_panel=Trace, app_panel=App,
- perf_panel=Perf, allc_panel=Alloc}) ->
- case Pid of
- Pro -> "Processes";
- Sys -> "System";
- Tv -> "Table Viewer" ;
- Trace -> ?TRACE_STR;
- Perf -> "Load Charts";
- App -> "Applications";
- Alloc -> ?ALLOC_STR;
- _ -> "unknown"
+pid2panel(Pid, #state{panels=Panels}) ->
+ PanelPids = [{Name, wx_object:get_pid(Obj)} || {Name, Obj, _} <- Panels],
+ case lists:keyfind(Pid, 2, PanelPids) of
+ false -> "unknown";
+ {Name,_} -> Name
end.
-
create_connect_dialog(ping, #state{frame = Frame, prev_node=Prev}) ->
Dialog = wxTextEntryDialog:new(Frame, "Connect to node", [{value, Prev}]),
case wxDialog:showModal(Dialog) of
@@ -629,7 +634,8 @@ create_connect_dialog(connect, #state{frame = Frame}) ->
wxWindow:setSizerAndFit(Dialog, VSizer),
wxSizer:setSizeHints(VSizer, Dialog),
- CookiePath = filename:join(os:getenv("HOME"), ".erlang.cookie"),
+ {ok,[[HomeDir]]} = init:get_argument(home),
+ CookiePath = filename:join(HomeDir, ".erlang.cookie"),
DefaultCookie = case filelib:is_file(CookiePath) of
true ->
{ok, Bin} = file:read_file(CookiePath),
diff --git a/lib/observer/src/ttb.erl b/lib/observer/src/ttb.erl
index ac6c4572eb..09b0bc6710 100644
--- a/lib/observer/src/ttb.erl
+++ b/lib/observer/src/ttb.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -78,6 +78,11 @@ do_tracer(Nodes0,PI,Client,Traci) ->
do_tracer(Clients,PI,Traci) ->
Shell = proplists:get_value(shell, Traci, false),
+ IpPortSpec =
+ case proplists:get_value(queue_size, Traci) of
+ undefined -> 0;
+ QS -> {0,QS}
+ end,
DefShell = fun(Trace) -> dbg:dhandler(Trace, standard_io) end,
{ClientSucc,Succ} =
lists:foldl(
@@ -98,7 +103,7 @@ do_tracer(Clients,PI,Traci) ->
[_,H] = string:tokens(atom_to_list(N),"@"),
H
end,
- case catch dbg:tracer(N,port,dbg:trace_port(ip,0)) of
+ case catch dbg:tracer(N,port,dbg:trace_port(ip,IpPortSpec)) of
{ok,N} ->
{ok,Port} = dbg:trace_port_control(N,get_listen_port),
{ok,T} = dbg:get_tracer(N),
@@ -160,6 +165,8 @@ opt([{resume,MSec}|O],{PI,Client,Traci}) ->
opt(O,{PI,Client,[{resume, {true, MSec}}|Traci]});
opt([{flush,MSec}|O],{PI,Client,Traci}) ->
opt(O,{PI,Client,[{flush, MSec}|Traci]});
+opt([{queue_size,QueueSize}|O],{PI,Client,Traci}) ->
+ opt(O,{PI,Client,[{queue_size,QueueSize}|Traci]});
opt([],Opt) ->
ensure_opt(Opt).
@@ -384,16 +391,16 @@ run_config(ConfigFile,N) ->
print_func(M,F,A) ->
Args = arg_list(A,[]),
- io:format("~w:~w(~s) ->~n",[M,F,Args]).
+ io:format("~w:~tw(~ts) ->~n",[M,F,Args]).
print_result(R) ->
- io:format("~p~n~n",[R]).
+ io:format("~tp~n~n",[R]).
arg_list([],[]) ->
"";
arg_list([A1],Acc) ->
- Acc++io_lib:format("~w",[A1]);
+ Acc++io_lib:format("~tw",[A1]);
arg_list([A1|A],Acc) ->
- arg_list(A,Acc++io_lib:format("~w,",[A1])).
+ arg_list(A,Acc++io_lib:format("~tw,",[A1])).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1110,7 +1117,7 @@ get_fd(Out) ->
Out;
_file ->
file:delete(Out),
- case file:open(Out,[append]) of
+ case file:open(Out,[append,{encoding,utf8}]) of
{ok,Fd} -> Fd;
Error -> exit(Error)
end
diff --git a/lib/observer/test/crashdump_helper.erl b/lib/observer/test/crashdump_helper.erl
index 4239a3d0d1..f37d9057cb 100644
--- a/lib/observer/test/crashdump_helper.erl
+++ b/lib/observer/test/crashdump_helper.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
-module(crashdump_helper).
-export([n1_proc/2,remote_proc/2]).
--compile(r13).
+-compile(r18).
-include_lib("common_test/include/ct.hrl").
n1_proc(N2,Creator) ->
@@ -44,7 +44,7 @@ n1_proc(Creator,_N2,Pid2,Port2,_L) ->
Ref = make_ref(),
Pid = self(),
Bin = list_to_binary(lists:seq(1, 255)),
- SubBin = element(1, split_binary(element(2, split_binary(Bin, 8)), 17)),
+ <<_:2,SubBin:17/binary,_/bits>> = Bin,
register(named_port,Port),
diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl
index 73ed890802..1fd94ffb3c 100644
--- a/lib/observer/test/crashdump_viewer_SUITE.erl
+++ b/lib/observer/test/crashdump_viewer_SUITE.erl
@@ -101,7 +101,10 @@ end_per_group(_GroupName, Config) ->
init_per_suite(Config) when is_list(Config) ->
delete_saved(Config),
DataDir = ?config(data_dir,Config),
- Rels = [R || R <- ['17','18'], ?t:is_release_available(R)] ++ [current],
+ CurrVsn = list_to_integer(erlang:system_info(otp_release)),
+ OldRels = [R || R <- [CurrVsn-2,CurrVsn-1],
+ ?t:is_release_available(list_to_atom(integer_to_list(R)))],
+ Rels = OldRels ++ [current],
io:format("Creating crash dumps for the following releases: ~p", [Rels]),
AllDumps = create_dumps(DataDir,Rels),
[{dumps,AllDumps}|Config].
@@ -420,6 +423,10 @@ special(File,Procs) ->
%% ".trunc" ->
%% %% ????
%% ok;
+ ".trunc.bytes" ->
+ {ok,_,[TW]} = crashdump_viewer:general_info(),
+ {match,_} = re:run(TW,"CRASH DUMP SIZE LIMIT REACHED"),
+ ok;
_ ->
ok
end,
@@ -481,7 +488,11 @@ do_create_dumps(DataDir,Rel) ->
current ->
CD3 = dump_with_args(DataDir,Rel,"instr","+Mim true"),
CD4 = dump_with_strange_module_name(DataDir,Rel,"strangemodname"),
- {[CD1,CD2,CD3,CD4], DosDump};
+ Bytes = rand:uniform(300000) + 100,
+ CD5 = dump_with_args(DataDir,Rel,"trunc.bytes",
+ "-env ERL_CRASH_DUMP_BYTES " ++
+ integer_to_list(Bytes)),
+ {[CD1,CD2,CD3,CD4,CD5], DosDump};
_ ->
{[CD1,CD2], DosDump}
end.
@@ -604,23 +615,17 @@ dos_dump(DataDir,Rel,Dump) ->
[]
end.
+rel_opt(current) ->
+ [];
rel_opt(Rel) ->
- case Rel of
- '17' -> [{erl,[{release,"17_latest"}]}];
- '18' -> [{erl,[{release,"18_latest"}]}];
- current -> []
- end.
+ [{erl,[{release,lists:concat([Rel,"_latest"])}]}].
+dump_prefix(current) ->
+ dump_prefix(erlang:system_info(otp_release));
dump_prefix(Rel) ->
- case Rel of
- '17' -> "r17_dump.";
- '18' -> "r18_dump.";
- current -> "r19_dump."
- end.
+ lists:concat(["r",Rel,"_dump."]).
+compat_rel(current) ->
+ "";
compat_rel(Rel) ->
- case Rel of
- '17' -> "+R17 ";
- '18' -> "+R18 ";
- current -> ""
- end.
+ lists:concat(["+R",Rel," "]).
diff --git a/lib/observer/test/observer_SUITE.erl b/lib/observer/test/observer_SUITE.erl
index 4c882ad951..41726b1521 100644
--- a/lib/observer/test/observer_SUITE.erl
+++ b/lib/observer/test/observer_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -34,7 +34,8 @@
%% Test cases
-export([app_file/1, appup_file/1,
- basic/1, process_win/1, table_win/1
+ basic/1, process_win/1, table_win/1,
+ port_win_when_tab_not_initiated/1
]).
%% Default timetrap timeout (set in init_per_testcase)
@@ -49,7 +50,8 @@ groups() ->
[{gui, [],
[basic,
process_win,
- table_win
+ table_win,
+ port_win_when_tab_not_initiated
]
}].
@@ -299,6 +301,17 @@ table_win(Config) when is_list(Config) ->
observer:stop(),
ok.
+%% Test PR-1296/OTP-14151
+%% Clicking a link to a port before the port tab has been activated the
+%% first time crashes observer.
+port_win_when_tab_not_initiated(Config) ->
+ {ok,Port} = gen_tcp:listen(0,[]),
+ ok = observer:start(),
+ Notebook = setup_whitebox_testing(),
+ observer ! {open_link,erlang:port_to_list(Port)},
+ timer:sleep(1000),
+ observer:stop(),
+ ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk
index f214810199..21edfcd184 100644
--- a/lib/observer/vsn.mk
+++ b/lib/observer/vsn.mk
@@ -1 +1 @@
-OBSERVER_VSN = 2.2
+OBSERVER_VSN = 2.4
diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in
index cb2b23d534..2dec6e5abf 100644
--- a/lib/odbc/configure.in
+++ b/lib/odbc/configure.in
@@ -65,7 +65,7 @@ dnl ---------------------------------------------------------------------
dnl Special windows stuff regarding CFLAGS and details in the environment...
dnl ---------------------------------------------------------------------
LM_WINDOWS_ENVIRONMENT
-
+
AC_PROG_MAKE_SET
AC_CHECK_PROGS(LD, ld.sh)
@@ -136,8 +136,8 @@ AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_addr], [], [],
dnl Checks for library functions.
AC_CHECK_FUNCS([memset socket])
-
-# ODBC
+
+# ODBC
$RM -f "$ERL_TOP/lib/odbc/SKIP"
LM_CHECK_THR_LIB
@@ -146,24 +146,24 @@ AC_SUBST(THR_LIBS)
odbc_lib_link_success=no
AC_SUBST(TARGET_FLAGS)
- case $host_os in
- darwin1[[0-4]].*|darwin[[0-9]].*)
+ case $host_os in
+ darwin1[[0-9]].*)
TARGET_FLAGS="-DUNIX"
if test ! -d "$with_odbc" || test "$with_odbc" = "yes"; then
- ODBC_LIB= -L"/usr/lib"
- ODBC_INCLUDE="-I/usr/lib/include"
+ ODBC_LIB= -L"/usr/local/lib"
+ ODBC_INCLUDE="-I/usr/local/include"
else
ODBC_LIB=-L"$with_odbc/lib"
ODBC_INCLUDE="-I$with_odbc/include"
fi
-
- AC_CHECK_LIB(iodbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -liodbc"; odbc_lib_link_success=yes])
+
+ AC_CHECK_LIB(iodbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -lodbc"; odbc_lib_link_success=yes])
;;
win32|cygwin)
TARGET_FLAGS="-DWIN32"
AC_CHECK_LIB(ws2_32, main)
if test ! -d "$with_odbc" || test "$with_odbc" = "yes"; then
- ODBC_LIB=""
+ ODBC_LIB=""
ODBC_INCLUDE=""
else
ODBC_LIB=-L"$with_odbc/lib"
@@ -196,7 +196,7 @@ AC_SUBST(TARGET_FLAGS)
elif test -d "${libdir}/64/."; then
libdir="${libdir}/64"
fi
- fi
+ fi
ODBC_LIB="-L$libdir"
ODBC_INCLUDE="-I$erl_xcomp_isysroot$rdir/include"
break
@@ -207,7 +207,7 @@ AC_SUBST(TARGET_FLAGS)
echo "No odbc library found" > "$ERL_TOP/lib/odbc/SKIP"
else
AC_MSG_RESULT($ODBC_LIB)
- AC_CHECK_LIB(odbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -lodbc"; odbc_lib_link_success=yes])
+ AC_CHECK_LIB(odbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -lodbc"; odbc_lib_link_success=yes])
fi
;;
diff --git a/lib/odbc/doc/src/notes.xml b/lib/odbc/doc/src/notes.xml
index d3dd39616f..cc25a21c74 100644
--- a/lib/odbc/doc/src/notes.xml
+++ b/lib/odbc/doc/src/notes.xml
@@ -32,7 +32,44 @@
<p>This document describes the changes made to the odbc application.
</p>
- <section><title>ODBC 2.11.2</title>
+ <section><title>ODBC 2.12</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Change configure to skip odbc for old MACs, the change in
+ PR-1227 is not backwards compatible with old MACs, and we
+ do not see a need to continue support for such old
+ versions. However it is still possible to make it work on
+ such machines using the --with-odbc configure option.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14083</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>ODBC 2.11.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ ODBC build configure has been updated to accept Mac OS X
+ El Capitan. Fixed by Lee Bannard.</p>
+ <p>
+ Own Id: OTP-13781</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>ODBC 2.11.2</title>
<section><title>Improvements and New Features</title>
<list>
@@ -585,7 +622,7 @@
also been extended. </item><item> The <c>configure</c>
scripts of <c>erl_interface</c> and <c>odbc</c> now
search for thread libraries and thread library quirks the
- same way as <c>erts</c> do. </item><item> The
+ same way as ERTS do. </item><item> The
<c>configure</c> script of the <c>odbc</c> application
now also looks for odbc libraries in <c>lib64</c> and
<c>lib/64</c> directories when building on a 64-bit
diff --git a/lib/odbc/test/odbc_connect_SUITE.erl b/lib/odbc/test/odbc_connect_SUITE.erl
index 5727c1ca50..261dfc6f20 100644
--- a/lib/odbc/test/odbc_connect_SUITE.erl
+++ b/lib/odbc/test/odbc_connect_SUITE.erl
@@ -89,6 +89,7 @@ init_per_suite(Config) when is_list(Config) ->
[{auto_commit, off}] ++ odbc_test_lib:platform_options()) of
{ok, Ref} ->
odbc:disconnect(Ref),
+ ct:timetrap(?default_timeout),
[{tableName, odbc_test_lib:unique_table_name()} | Config];
_ ->
{skip, "ODBC is not properly setup"}
@@ -129,11 +130,8 @@ init_per_testcase(_TestCase, Config) ->
init_per_testcase_common(Config).
init_per_testcase_common(Config) ->
- test_server:format("ODBCINI = ~p~n", [os:getenv("ODBCINI")]),
- Dog = test_server:timetrap(?default_timeout),
- Temp = lists:keydelete(connection_ref, 1, Config),
- NewConfig = lists:keydelete(watchdog, 1, Temp),
- [{watchdog, Dog} | NewConfig].
+ ct:pal("ODBCINI = ~p~n", [os:getenv("ODBCINI")]),
+ lists:keydelete(connection_ref, 1, Config).
%%--------------------------------------------------------------------
%% Function: end_per_testcase(Case, Config) -> _
@@ -153,25 +151,22 @@ end_per_testcase(_TestCase, Config) ->
end_per_testcase_common(Config).
end_per_testcase_common(Config) ->
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
{ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
Result = odbc:sql_query(Ref, "DROP TABLE " ++ Table),
io:format("Drop table: ~p ~p~n", [Table, Result]),
- odbc:disconnect(Ref),
- Dog = ?config(watchdog, Config),
- test_server:timetrap_cancel(Dog).
+ odbc:disconnect(Ref).
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-commit(doc)->
- ["Test the use of explicit commit"];
-commit(suite) -> [];
+commit()->
+ [{doc,"Test the use of explicit commit"}].
commit(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
[{auto_commit, off}] ++ odbc_test_lib:platform_options()),
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
TransStr = transaction_support_str(?RDBMS),
{updated, _} =
@@ -205,14 +200,13 @@ commit(Config) ->
ok = odbc:disconnect(Ref).
%%-------------------------------------------------------------------------
-rollback(doc)->
- ["Test the use of explicit rollback"];
-rollback(suite) -> [];
+rollback()->
+ [{doc,"Test the use of explicit rollback"}].
rollback(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
[{auto_commit, off}] ++ odbc_test_lib:platform_options()),
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
TransStr = transaction_support_str(?RDBMS),
@@ -245,9 +239,8 @@ rollback(Config) ->
ok = odbc:disconnect(Ref).
%%-------------------------------------------------------------------------
-not_explicit_commit(doc) ->
- ["Test what happens if you try using commit on a auto_commit connection."];
-not_explicit_commit(suite) -> [];
+not_explicit_commit() ->
+ [{doc,"Test what happens if you try using commit on a auto_commit connection."}].
not_explicit_commit(_Config) ->
{ok, Ref} =
odbc:connect(?RDBMS:connection_string(), [{auto_commit, on}] ++
@@ -256,19 +249,17 @@ not_explicit_commit(_Config) ->
ok = odbc:disconnect(Ref).
%%-------------------------------------------------------------------------
-not_exist_db(doc) ->
- ["Tests valid data format but invalid data in the connection parameters."];
-not_exist_db(suite) -> [];
+not_exist_db() ->
+ [{doc,"Tests valid data format but invalid data in the connection parameters."}].
not_exist_db(_Config) ->
{error, _} = odbc:connect("DSN=foo;UID=bar;PWD=foobar",
odbc_test_lib:platform_options()),
%% So that the odbc control server can be stoped "in the correct way"
- test_server:sleep(100).
+ ct:sleep(100).
%%-------------------------------------------------------------------------
-no_c_executable(doc) ->
- "Test what happens if the port-program can not be found";
-no_c_executable(suite) -> [];
+no_c_executable() ->
+ [{doc,"Test what happens if the port-program can not be found"}].
no_c_executable(_Config) ->
process_flag(trap_exit, true),
Dir = filename:nativename(filename:join(code:priv_dir(odbc),
@@ -293,9 +284,8 @@ no_c_executable(_Config) ->
end.
%%------------------------------------------------------------------------
-port_dies(doc) ->
- "Tests what happens if the port program dies";
-port_dies(suite) -> [];
+port_dies() ->
+ [{doc,"Tests what happens if the port program dies"}].
port_dies(_Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
{status, _} = process_info(Ref, status),
@@ -307,7 +297,7 @@ port_dies(_Config) ->
%% Wait for exit_status from port 5000 ms (will not get a exit
%% status in this case), then wait a little longer to make sure
%% the port and the controlprocess has had time to terminate.
- test_server:sleep(10000),
+ ct:sleep(10000),
undefined = process_info(Ref, status);
[] ->
ct:fail([erlang:port_info(P, name) || P <- erlang:ports()])
@@ -315,9 +305,8 @@ port_dies(_Config) ->
%%-------------------------------------------------------------------------
-control_process_dies(doc) ->
- "Tests what happens if the Erlang control process dies";
-control_process_dies(suite) -> [];
+control_process_dies() ->
+ [{doc,"Tests what happens if the Erlang control process dies"}].
control_process_dies(_Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
process_flag(trap_exit, true),
@@ -326,7 +315,7 @@ control_process_dies(_Config) ->
[Port] ->
{connected, Ref} = erlang:port_info(Port, connected),
exit(Ref, kill),
- test_server:sleep(500),
+ ct:sleep(500),
undefined = erlang:port_info(Port, connected);
%% Check for c-program still running, how?
[] ->
@@ -334,9 +323,8 @@ control_process_dies(_Config) ->
end.
%%-------------------------------------------------------------------------
-client_dies_normal(doc) ->
- ["Client dies with reason normal."];
-client_dies_normal(suite) -> [];
+client_dies_normal() ->
+ [{doc,"Client dies with reason normal."}].
client_dies_normal(Config) when is_list(Config) ->
Pid = spawn(?MODULE, client_normal, [self()]),
@@ -352,7 +340,7 @@ client_dies_normal(Config) when is_list(Config) ->
{'DOWN', MonitorReference, _Type, _Object, _Info} ->
ok
after 5000 ->
- test_server:fail(control_process_not_stopped)
+ ct:fail(control_process_not_stopped)
end.
client_normal(Pid) ->
@@ -366,9 +354,8 @@ client_normal(Pid) ->
%%-------------------------------------------------------------------------
-client_dies_timeout(doc) ->
- ["Client dies with reason timeout."];
-client_dies_timeout(suite) -> [];
+client_dies_timeout() ->
+ [{doc,"Client dies with reason timeout."}].
client_dies_timeout(Config) when is_list(Config) ->
Pid = spawn(?MODULE, client_timeout, [self()]),
@@ -384,7 +371,7 @@ client_dies_timeout(Config) when is_list(Config) ->
{'DOWN', MonitorReference, _Type, _Object, _Info} ->
ok
after 5000 ->
- test_server:fail(control_process_not_stopped)
+ ct:fail(control_process_not_stopped)
end.
client_timeout(Pid) ->
@@ -398,9 +385,8 @@ client_timeout(Pid) ->
%%-------------------------------------------------------------------------
-client_dies_error(doc) ->
- ["Client dies with reason error."];
-client_dies_error(suite) -> [];
+client_dies_error() ->
+ [{doc,"Client dies with reason error."}].
client_dies_error(Config) when is_list(Config) ->
Pid = spawn(?MODULE, client_error, [self()]),
@@ -416,7 +402,7 @@ client_dies_error(Config) when is_list(Config) ->
{'DOWN', MonitorReference, _Type, _Object, _Info} ->
ok
after 5000 ->
- test_server:fail(control_process_not_stopped)
+ ct:fail(control_process_not_stopped)
end.
client_error(Pid) ->
@@ -430,9 +416,8 @@ client_error(Pid) ->
%%-------------------------------------------------------------------------
-connect_timeout(doc) ->
- ["Test the timeout for the connect function."];
-connect_timeout(suite) -> [];
+connect_timeout() ->
+ [{doc,"Test the timeout for the connect function."}].
connect_timeout(Config) when is_list(Config) ->
{'EXIT',timeout} = (catch odbc:connect(?RDBMS:connection_string(),
[{timeout, 0}] ++
@@ -442,10 +427,9 @@ connect_timeout(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-connect_port_timeout(doc) ->
- ["Test the timeout for the port program to connect back to the odbc "
- "application within the connect function."];
-connect_port_timeout(suite) -> [];
+connect_port_timeout() ->
+ [{"Test the timeout for the port program to connect back to the odbc "
+ "application within the connect function."}].
connect_port_timeout(Config) when is_list(Config) ->
%% Application environment var 'port_timeout' has been set to 0 by
%% init_per_testcase/2.
@@ -453,15 +437,14 @@ connect_port_timeout(Config) when is_list(Config) ->
odbc_test_lib:platform_options()).
%%-------------------------------------------------------------------------
-timeout(doc) ->
- ["Test that timeouts don't cause unwanted behavior sush as receiving"
- " an anwser to a previously tiemed out query."];
-timeout(suite) -> [];
+timeout() ->
+ [{"Test that timeouts don't cause unwanted behavior sush as receiving"
+ " an anwser to a previously tiemed out query."}].
timeout(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
[{auto_commit, off}]),
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
TransStr = transaction_support_str(?RDBMS),
@@ -512,7 +495,7 @@ update_table_timeout(Table, TimeOut, Pid) ->
{'EXIT', timeout} ->
Pid ! timout_occurred;
{updated, 1} ->
- test_server:fail(database_locker_failed)
+ ct:fail(database_locker_failed)
end,
receive
@@ -537,15 +520,14 @@ update_table_timeout(Table, TimeOut, Pid) ->
ok = odbc:disconnect(Ref).
%%-------------------------------------------------------------------------
-many_timeouts(doc) ->
- ["Tests that many consecutive timeouts lead to that the connection "
- "is shutdown."];
-many_timeouts(suite) -> [];
+many_timeouts() ->
+ [{doc, "Tests that many consecutive timeouts lead to that the connection "
+ "is shutdown."}].
many_timeouts(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
[{auto_commit, off}] ++ odbc_test_lib:platform_options()),
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
TransStr = transaction_support_str(?RDBMS),
{updated, _} =
@@ -592,19 +574,18 @@ loop_many_timouts(Ref, UpdateQuery, TimeOut) ->
{'EXIT',timeout} ->
loop_many_timouts(Ref, UpdateQuery, TimeOut);
{updated, 1} ->
- test_server:fail(database_locker_failed);
+ ct:fail(database_locker_failed);
{error, connection_closed} ->
ok
end.
%%-------------------------------------------------------------------------
-timeout_reset(doc) ->
- ["Check that the number of consecutive timouts is reset to 0 when "
- "a successful call to the database is made."];
-timeout_reset(suite) -> [];
+timeout_reset() ->
+ [{doc, "Check that the number of consecutive timouts is reset to 0 when "
+ "a successful call to the database is made."}].
timeout_reset(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
[{auto_commit, off}] ++ odbc_test_lib:platform_options()),
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
TransStr = transaction_support_str(?RDBMS),
{updated, _} =
@@ -688,21 +669,20 @@ loop_timout_reset(Ref, UpdateQuery, TimeOut, NumTimeouts) ->
loop_timout_reset(Ref, UpdateQuery,
TimeOut, NumTimeouts - 1);
{updated, 1} ->
- test_server:fail(database_locker_failed);
+ ct:fail(database_locker_failed);
{error, connection_closed} ->
- test_server:fail(connection_closed_premature)
+ ct:fail(connection_closed_premature)
end.
%%-------------------------------------------------------------------------
-disconnect_on_timeout(doc) ->
- ["Check that disconnect after a time out works properly"];
-disconnect_on_timeout(suite) -> [];
+disconnect_on_timeout() ->
+ [{doc,"Check that disconnect after a time out works properly"}].
disconnect_on_timeout(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
[{auto_commit, off}] ++ odbc_test_lib:platform_options()),
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
TransStr = transaction_support_str(?RDBMS),
{updated, _} =
@@ -726,7 +706,7 @@ disconnect_on_timeout(Config) when is_list(Config) ->
ok ->
ok = odbc:commit(Ref, commit);
nok ->
- test_server:fail(database_locker_failed)
+ ct:fail(database_locker_failed)
end.
update_table_disconnect_on_timeout(Table, TimeOut, Pid) ->
@@ -744,14 +724,13 @@ update_table_disconnect_on_timeout(Table, TimeOut, Pid) ->
end.
%%-------------------------------------------------------------------------
-connection_closed(doc) ->
- ["Checks that you get an appropriate error message if you try to"
- " use a connection that has been closed"];
-connection_closed(suite) -> [];
+connection_closed() ->
+ [{doc, "Checks that you get an appropriate error message if you try to"
+ " use a connection that has been closed"}].
connection_closed(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
@@ -771,14 +750,13 @@ connection_closed(Config) when is_list(Config) ->
{error, connection_closed} = odbc:commit(Ref, commit).
%%-------------------------------------------------------------------------
-disable_scrollable_cursors(doc) ->
- ["Test disabling of scrollable cursors."];
-disable_scrollable_cursors(suite) -> [];
+disable_scrollable_cursors() ->
+ [{doc,"Test disabling of scrollable cursors."}].
disable_scrollable_cursors(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
[{scrollable_cursors, off}]),
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -792,10 +770,10 @@ disable_scrollable_cursors(Config) when is_list(Config) ->
NextResult = ?RDBMS:selected_ID(1, next),
- test_server:format("Expected: ~p~n", [NextResult]),
+ ct:pal("Expected: ~p~n", [NextResult]),
Result = odbc:next(Ref),
- test_server:format("Got: ~p~n", [Result]),
+ ct:pal("Got: ~p~n", [Result]),
NextResult = Result,
{error, scrollable_cursors_disabled} = odbc:first(Ref),
@@ -809,15 +787,14 @@ disable_scrollable_cursors(Config) when is_list(Config) ->
{selected, _ColNames,[]} = odbc:select(Ref, next, 1).
%%-------------------------------------------------------------------------
-return_rows_as_lists(doc)->
- ["Test the option that a row may be returned as a list instead "
- "of a tuple. Too be somewhat backward compatible."];
-return_rows_as_lists(suite) -> [];
+return_rows_as_lists()->
+ [{doc,"Test the option that a row may be returned as a list instead "
+ "of a tuple. Too be somewhat backward compatible."}].
return_rows_as_lists(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
[{tuple_row, off}] ++ odbc_test_lib:platform_options()),
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -854,29 +831,28 @@ return_rows_as_lists(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-api_missuse(doc)->
- ["Test that behaviour of the control process if the api is abused"];
-api_missuse(suite) -> [];
+api_missuse()->
+ [{doc,"Test that behaviour of the control process if the api is abused"}].
api_missuse(Config) when is_list(Config)->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
%% Serious programming fault, connetion will be shut down
gen_server:call(Ref, {self(), foobar, 10}, infinity),
- test_server:sleep(10),
+ ct:sleep(10),
undefined = process_info(Ref, status),
{ok, Ref2} = odbc:connect(?RDBMS:connection_string(),
odbc_test_lib:platform_options()),
%% Serious programming fault, connetion will be shut down
gen_server:cast(Ref2, {self(), foobar, 10}),
- test_server:sleep(10),
+ ct:sleep(10),
undefined = process_info(Ref2, status),
{ok, Ref3} = odbc:connect(?RDBMS:connection_string(),
odbc_test_lib:platform_options()),
%% Could be an innocent misstake the connection lives.
Ref3 ! foobar,
- test_server:sleep(10),
+ ct:sleep(10),
{status, _} = process_info(Ref3, status).
transaction_support_str(mysql) ->
@@ -886,13 +862,13 @@ transaction_support_str(_) ->
%%-------------------------------------------------------------------------
-extended_errors(doc)->
- ["Test the extended errors connection option: When off; the old behaviour of just an error "
- "string is returned on error. When on, the error string is replaced by a 3 element tuple "
- "that also exposes underlying ODBC provider error codes."];
-extended_errors(suite) -> [];
+extended_errors()->
+ [{doc,
+ "Test the extended errors connection option: When off; the old behaviour of just an error "
+ "string is returned on error. When on, the error string is replaced by a 3 element tuple "
+ "that also exposes underlying ODBC provider error codes."}].
extended_errors(Config) when is_list(Config)->
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
{ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
{updated, _} = odbc:sql_query(Ref, "create table " ++ Table ++" ( id integer, data varchar(10))"),
diff --git a/lib/odbc/test/odbc_data_type_SUITE.erl b/lib/odbc/test/odbc_data_type_SUITE.erl
index c88c00725e..a3a4bc78eb 100644
--- a/lib/odbc/test/odbc_data_type_SUITE.erl
+++ b/lib/odbc/test/odbc_data_type_SUITE.erl
@@ -120,6 +120,7 @@ init_per_suite(Config) when is_list(Config) ->
false ->
case (catch odbc:start()) of
ok ->
+ ct:timetrap(?default_timeout),
[{tableName, odbc_test_lib:unique_table_name()}| Config];
_ ->
{skip, "ODBC not startable"}
@@ -191,23 +192,22 @@ init_per_testcase(Case, Config) ->
common_init_per_testcase(Case, Config) ->
PlatformOptions = odbc_test_lib:platform_options(),
- case atom_to_list(Case) of
- "binary" ++ _ ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{binary_strings, on}] ++ PlatformOptions);
- LCase when LCase == "utf8";
- LCase == "nchar";
- LCase == "nvarchar" ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{binary_strings, on}] ++ PlatformOptions);
- _ ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), PlatformOptions)
- end,
+ {ok, Ref} =
+ case atom_to_list(Case) of
+ "binary" ++ _ ->
+ odbc:connect(?RDBMS:connection_string(),
+ [{binary_strings, on}] ++ PlatformOptions);
+ LCase when LCase == "utf8";
+ LCase == "nchar";
+ LCase == "nvarchar" ->
+ odbc:connect(?RDBMS:connection_string(),
+ [{binary_strings, on}] ++ PlatformOptions);
+ _ ->
+ odbc:connect(?RDBMS:connection_string(), PlatformOptions)
+ end,
odbc_test_lib:strict(Ref, ?RDBMS),
- Dog = test_server:timetrap(?default_timeout),
- Temp = lists:keydelete(connection_ref, 1, Config),
- NewConfig = lists:keydelete(watchdog, 1, Temp),
- [{watchdog, Dog}, {connection_ref, Ref} | NewConfig].
+ NewConfig = lists:keydelete(connection_ref, 1, Config),
+ [{connection_ref, Ref} | NewConfig].
is_fixed_upper_limit(mysql) ->
false;
@@ -231,28 +231,23 @@ is_supported_bit(_) ->
%% Description: Cleanup after each test case
%%--------------------------------------------------------------------
end_per_testcase(_TestCase, Config) ->
- Ref = ?config(connection_ref, Config),
+ Ref = proplists:get_value(connection_ref, Config),
ok = odbc:disconnect(Ref),
%% Clean up if needed
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
{ok, NewRef} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
odbc:sql_query(NewRef, "DROP TABLE " ++ Table),
- odbc:disconnect(NewRef),
- Dog = ?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
- ok.
+ odbc:disconnect(NewRef).
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-char_fixed_lower_limit(doc) ->
- ["Tests fixed length char data type lower boundaries."];
-char_fixed_lower_limit(suite) ->
- [];
+char_fixed_lower_limit() ->
+ [{doc,"Tests fixed length char data type lower boundaries."}].
char_fixed_lower_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
%% Below limit
{error, _} =
@@ -287,18 +282,16 @@ char_fixed_lower_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-char_fixed_upper_limit(doc) ->
- ["Tests fixed length char data type upper boundaries."];
-char_fixed_upper_limit(suite) ->
- [];
+char_fixed_upper_limit() ->
+ [{doc,"Tests fixed length char data type upper boundaries."}].
char_fixed_upper_limit(Config) when is_list(Config) ->
case ?RDBMS of
postgres ->
{skip, "Limit unknown"};
_ ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
%% Upper limit
{updated, _} = % Value == 0 || -1 driver dependent!
@@ -337,14 +330,12 @@ char_fixed_upper_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-char_fixed_padding(doc) ->
- ["Tests that data that is shorter than the given size is padded "
- "with blanks."];
-char_fixed_padding(suite) ->
- [];
+char_fixed_padding() ->
+ [{doc, "Tests that data that is shorter than the given size is padded "
+ "with blanks."}].
char_fixed_padding(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
%% Data should be padded with blanks
{updated, _} = % Value == 0 || -1 driver dependent!
@@ -365,13 +356,11 @@ char_fixed_padding(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-varchar_lower_limit(doc) ->
- ["Tests variable length char data type lower boundaries."];
-varchar_lower_limit(suite) ->
- [];
+varchar_lower_limit() ->
+ [{doc,"Tests variable length char data type lower boundaries."}].
varchar_lower_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
%% Below limit
{error, _} =
@@ -405,13 +394,11 @@ varchar_lower_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-varchar_upper_limit(doc) ->
- ["Tests variable length char data type upper boundaries."];
-varchar_upper_limit(suite) ->
- [];
+varchar_upper_limit() ->
+ [{doc,"Tests variable length char data type upper boundaries."}].
varchar_upper_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
case ?RDBMS of
oracle ->
@@ -455,14 +442,12 @@ varchar_upper_limit(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
-varchar_no_padding(doc) ->
- ["Tests that data that is shorter than the given max size is not padded "
- "with blanks."];
-varchar_no_padding(suite) ->
- [];
+varchar_no_padding() ->
+ [{doc, "Tests that data that is shorter than the given max size is not padded "
+ "with blanks."}].
varchar_no_padding(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
%% Data should NOT be padded with blanks
{updated, _} = % Value == 0 || -1 driver dependent!
@@ -481,13 +466,11 @@ varchar_no_padding(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-text_lower_limit(doc) ->
- ["Tests 'long' char data type lower boundaries."];
-text_lower_limit(suite) ->
- [];
+text_lower_limit() ->
+ [{doc,"Tests 'long' char data type lower boundaries."}].
text_lower_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -504,15 +487,13 @@ text_lower_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-text_upper_limit(doc) ->
- [];
-text_upper_limit(suite) ->
- [];
+text_upper_limit() ->
+ [{doc,"Tests 'text' char data type upper boundaries."}].
text_upper_limit(Config) when is_list(Config) ->
{skip,"Consumes too much resources" }.
-%% Ref = ?config(connection_ref, Config),
-%% Table = ?config(tableName, Config),
+%% Ref = proplists:get_value(connection_ref, Config),
+%% Table = proplists:get_value(tableName, Config),
%% {updated, _} = % Value == 0 || -1 driver dependent!
%% odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -534,13 +515,11 @@ text_upper_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-binary_char_fixed_lower_limit(doc) ->
- ["Tests fixed length char data type lower boundaries."];
-binary_char_fixed_lower_limit(suite) ->
- [];
+binary_char_fixed_lower_limit() ->
+ [{doc,"Tests fixed length char data type lower boundaries."}].
binary_char_fixed_lower_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
%% Below limit
{error, _} =
@@ -579,18 +558,16 @@ binary_char_fixed_lower_limit(Config) when is_list(Config) ->
++ "')").
%%-------------------------------------------------------------------------
-binary_char_fixed_upper_limit(doc) ->
- ["Tests fixed length char data type upper boundaries."];
-binary_char_fixed_upper_limit(suite) ->
- [];
+binary_char_fixed_upper_limit() ->
+ [{doc,"Tests fixed length char data type upper boundaries."}].
binary_char_fixed_upper_limit(Config) when is_list(Config) ->
case ?RDBMS of
postgres ->
{skip, "Limit unknown"};
_ ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
%% Upper limit
{updated, _} = % Value == 0 || -1 driver dependent!
@@ -630,14 +607,12 @@ binary_char_fixed_upper_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-binary_char_fixed_padding(doc) ->
- ["Tests that data that is shorter than the given size is padded "
- "with blanks."];
-binary_char_fixed_padding(suite) ->
- [];
+binary_char_fixed_padding() ->
+ [{doc, "Tests that data that is shorter than the given size is padded "
+ "with blanks."}].
binary_char_fixed_padding(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
%% Data should be padded with blanks
{updated, _} = % Value == 0 || -1 driver dependent!
@@ -658,13 +633,11 @@ binary_char_fixed_padding(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-binary_varchar_lower_limit(doc) ->
- ["Tests variable length char data type lower boundaries."];
-binary_varchar_lower_limit(suite) ->
- [];
+binary_varchar_lower_limit() ->
+ [{doc,"Tests variable length char data type lower boundaries."}].
binary_varchar_lower_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
%% Below limit
{error, _} =
@@ -701,13 +674,11 @@ binary_varchar_lower_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-binary_varchar_upper_limit(doc) ->
- ["Tests variable length char data type upper boundaries."];
-binary_varchar_upper_limit(suite) ->
- [];
+binary_varchar_upper_limit() ->
+ [{doc,"Tests variable length char data type upper boundaries."}].
binary_varchar_upper_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
case ?RDBMS of
oracle ->
@@ -750,14 +721,12 @@ binary_varchar_upper_limit(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
-binary_varchar_no_padding(doc) ->
- ["Tests that data that is shorter than the given max size is not padded "
- "with blanks."];
-binary_varchar_no_padding(suite) ->
- [];
+binary_varchar_no_padding() ->
+ [{doc,"Tests that data that is shorter than the given max size is not padded "
+ "with blanks."}].
binary_varchar_no_padding(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
%% Data should NOT be padded with blanks
{updated, _} = % Value == 0 || -1 driver dependent!
@@ -776,13 +745,11 @@ binary_varchar_no_padding(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-binary_text_lower_limit(doc) ->
- ["Tests 'long' char data type lower boundaries."];
-binary_text_lower_limit(suite) ->
- [];
+binary_text_lower_limit() ->
+ [{doc,"Tests 'long' char data type lower boundaries."}].
binary_text_lower_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -799,15 +766,13 @@ binary_text_lower_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-binary_text_upper_limit(doc) ->
- [];
-binary_text_upper_limit(suite) ->
- [];
+binary_text_upper_limit() ->
+ [{doc,"Tests text char data type upper boundaries."}].
binary_text_upper_limit(Config) when is_list(Config) ->
{skip,"Consumes too much resources" }.
-%% Ref = ?config(connection_ref, Config),
-%% Table = ?config(tableName, Config),
+%% Ref = proplists:get_value(connection_ref, Config),
+%% Table = proplists:get_value(tableName, Config),
%% {updated, _} = % Value == 0 || -1 driver dependent!
%% odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -830,17 +795,15 @@ binary_text_upper_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-tiny_int_lower_limit(doc) ->
- ["Tests integer of type tinyint."];
-tiny_int_lower_limit(suite) ->
- [];
+tiny_int_lower_limit() ->
+ [{doc,"Tests integer of type tinyint."}].
tiny_int_lower_limit(Config) when is_list(Config) ->
case ?RDBMS of
postgres ->
{skip, "Type tiniyint not supported"};
_ ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -864,17 +827,15 @@ tiny_int_lower_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-tiny_int_upper_limit(doc) ->
- ["Tests integer of type tinyint."];
-tiny_int_upper_limit(suite) ->
- [];
+tiny_int_upper_limit() ->
+ [{doc,"Tests integer of type tinyint."}].
tiny_int_upper_limit(Config) when is_list(Config) ->
case ?RDBMS of
postgres ->
{skip, "Type tiniyint not supported"};
_ ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -898,13 +859,11 @@ tiny_int_upper_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-small_int_lower_limit(doc) ->
- ["Tests integer of type smallint."];
-small_int_lower_limit(suite) ->
- [];
+small_int_lower_limit() ->
+ [{doc,"Tests integer of type smallint."}].
small_int_lower_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -927,13 +886,11 @@ small_int_lower_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-small_int_upper_limit(doc) ->
- ["Tests integer of type smallint."];
-small_int_upper_limit(suite) ->
- [];
+small_int_upper_limit() ->
+ [{doc,"Tests integer of type smallint."}].
small_int_upper_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -955,13 +912,11 @@ small_int_upper_limit(Config) when is_list(Config) ->
++ "')").
%%-------------------------------------------------------------------------
-int_lower_limit(doc) ->
- ["Tests integer of type int."];
-int_lower_limit(suite) ->
- [];
+int_lower_limit() ->
+ [{doc,"Tests integer of type int."}].
int_lower_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -983,13 +938,11 @@ int_lower_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-int_upper_limit(doc) ->
- ["Tests integer of type int."];
-int_upper_limit(suite) ->
- [];
+int_upper_limit() ->
+ [{doc,"Tests integer of type int."}].
int_upper_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1011,13 +964,11 @@ int_upper_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-big_int_lower_limit(doc) ->
- ["Tests integer of type bigint"];
-big_int_lower_limit(suite) ->
- [];
+big_int_lower_limit() ->
+ [{doc,"Tests integer of type bigint"}].
big_int_lower_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1040,13 +991,11 @@ big_int_lower_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-big_int_upper_limit(doc) ->
- ["Tests integer of type bigint."];
-big_int_upper_limit(suite) ->
- [];
+big_int_upper_limit() ->
+ [{doc,"Tests integer of type bigint."}].
big_int_upper_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1068,17 +1017,13 @@ big_int_upper_limit(Config) when is_list(Config) ->
++ "')").
%%-------------------------------------------------------------------------
-bit_false(doc) ->
- [""];
-bit_false(suite) ->
- [];
bit_false(Config) when is_list(Config) ->
case ?RDBMS of
oracle ->
{skip, "Not supported by driver"};
_ ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1102,17 +1047,13 @@ bit_false(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-bit_true(doc) ->
- [""];
-bit_true(suite) ->
- [];
bit_true(Config) when is_list(Config) ->
case ?RDBMS of
oracle ->
{skip, "Not supported by driver"};
_ ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
@@ -1136,14 +1077,11 @@ bit_true(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
-float_lower_limit(doc) ->
- [""];
-float_lower_limit(suite) ->
- [];
+
float_lower_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
case ?RDBMS of
mysql ->
@@ -1186,13 +1124,10 @@ float_lower_limit(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
-float_upper_limit(doc) ->
- [""];
-float_upper_limit(suite) ->
- [];
+
float_upper_limit(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
case ?RDBMS of
mysql ->
@@ -1218,13 +1153,11 @@ float_upper_limit(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
-float_zero(doc) ->
- ["Test the float value zero."];
-float_zero(suite) ->
- [];
+float_zero() ->
+ [{doc,"Test the float value zero."}].
float_zero(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1237,13 +1170,11 @@ float_zero(Config) when is_list(Config) ->
SelectResult =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table).
%%-------------------------------------------------------------------------
-real_zero(doc) ->
- ["Test the real value zero."];
-real_zero(suite) ->
- [];
+real_zero() ->
+ [{doc,"Test the real value zero."}].
real_zero(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
case ?RDBMS of
oracle ->
@@ -1262,13 +1193,11 @@ real_zero(Config) when is_list(Config) ->
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table)
end.
%%------------------------------------------------------------------------
-dec_long(doc) ->
- [""];
dec_long(suit) ->
[];
dec_long(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1281,13 +1210,11 @@ dec_long(Config) when is_list(Config) ->
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
["FIELD"] = odbc_test_lib:to_upper(Fields).
%%------------------------------------------------------------------------
-dec_double(doc) ->
- [""];
dec_double(suit) ->
[];
dec_double(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1329,13 +1256,11 @@ dec_double(Config) when is_list(Config) ->
["FIELD"] = odbc_test_lib:to_upper(Fields2).
%%------------------------------------------------------------------------
-dec_bignum(doc) ->
- [""];
dec_bignum(suit) ->
[];
dec_bignum(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1361,13 +1286,11 @@ dec_bignum(Config) when is_list(Config) ->
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
["FIELD"] = odbc_test_lib:to_upper(Fields1).
%%------------------------------------------------------------------------
-num_long(doc) ->
- [""];
num_long(suit) ->
[];
num_long(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1380,13 +1303,11 @@ num_long(Config) when is_list(Config) ->
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
["FIELD"] = odbc_test_lib:to_upper(Fields).
%%------------------------------------------------------------------------
-num_double(doc) ->
- [""];
num_double(suit) ->
[];
num_double(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1426,13 +1347,11 @@ num_double(Config) when is_list(Config) ->
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
["FIELD"] = odbc_test_lib:to_upper(Fields2).
%%------------------------------------------------------------------------
-num_bignum(doc) ->
- [""];
num_bignum(suit) ->
[];
num_bignum(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1459,13 +1378,13 @@ num_bignum(Config) when is_list(Config) ->
["FIELD"] = odbc_test_lib:to_upper(Fields1).
%%------------------------------------------------------------------------
-utf8(doc) ->
- ["Test unicode support"];
+utf8() ->
+ [{doc,"Test unicode support"}].
utf8(suit) ->
[];
utf8(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ "(FIELD text)"),
@@ -1487,30 +1406,30 @@ utf8(Config) when is_list(Config) ->
end,
Latin1Data),
- test_server:format("UnicodeIn: ~p ~n",[UnicodeIn]),
+ ct:pal("UnicodeIn: ~p ~n",[UnicodeIn]),
{updated, _} = odbc:param_query(Ref,"INSERT INTO " ++ Table ++ "(FIELD) values(?)",
[{{sql_varchar,50}, UnicodeIn}]),
{selected,_,UnicodeOut} = odbc:sql_query(Ref,"SELECT * FROM " ++ Table),
- test_server:format("UnicodeOut: ~p~n", [UnicodeOut]),
+ ct:pal("UnicodeOut: ~p~n", [UnicodeOut]),
Result = lists:map(fun({Char}) ->
unicode:characters_to_list(Char,utf8)
end, UnicodeOut),
- test_server:format("Result: ~p ~n", [Result]),
+ ct:pal("Result: ~p ~n", [Result]),
Latin1Data = Result.
%%------------------------------------------------------------------------
-nchar(doc) ->
- ["Test unicode nchar support in sqlserver"];
+nchar() ->
+ [{doc,"Test unicode nchar support in sqlserver"}].
nchar(suit) ->
[];
nchar(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1520,13 +1439,13 @@ nchar(Config) when is_list(Config) ->
%%------------------------------------------------------------------------
-nvarchar(doc) ->
- ["Test 'unicode' nvarchar support"];
+nvarchar() ->
+ [{doc,"Test 'unicode' nvarchar support"}].
nvarchar(suit) ->
[];
nvarchar(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1535,13 +1454,11 @@ nvarchar(Config) when is_list(Config) ->
w_char_support(Ref, Table, sql_wlongvarchar, 50).
%%------------------------------------------------------------------------
-timestamp(doc) ->
- [""];
timestamp(suit) ->
[];
timestamp(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1582,21 +1499,21 @@ w_char_support(Ref, Table, CharType, Size) ->
end,
Latin1Data),
- test_server:format("UnicodeIn (utf 16): ~p ~n",[UnicodeIn]),
+ ct:pal("UnicodeIn (utf 16): ~p ~n",[UnicodeIn]),
{updated, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ "(FIELD) values(?)",
[{{CharType, Size},UnicodeIn}]),
{selected,_,UnicodeOut} = odbc:sql_query(Ref,"SELECT * FROM " ++ Table),
- test_server:format("UnicodeOut: ~p~n", [UnicodeOut]),
+ ct:pal("UnicodeOut: ~p~n", [UnicodeOut]),
PadResult = lists:map(fun({Unicode}) ->
unicode:characters_to_list(Unicode,{utf16,little})
end,
UnicodeOut),
- test_server:format("Result: ~p~n", [PadResult]),
+ ct:pal("Result: ~p~n", [PadResult]),
Result = lists:map(fun(Str) -> string:strip(Str) end, PadResult),
diff --git a/lib/odbc/test/odbc_query_SUITE.erl b/lib/odbc/test/odbc_query_SUITE.erl
index 5f719b7287..c283872965 100644
--- a/lib/odbc/test/odbc_query_SUITE.erl
+++ b/lib/odbc/test/odbc_query_SUITE.erl
@@ -113,6 +113,7 @@ init_per_suite(Config) when is_list(Config) ->
false ->
case (catch odbc:start()) of
ok ->
+ ct:timetrap(?default_timeout),
[{tableName, odbc_test_lib:unique_table_name()}| Config];
_ ->
{skip, "ODBC not startable"}
@@ -144,10 +145,10 @@ end_per_suite(_Config) ->
init_per_testcase(_Case, Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
odbc_test_lib:strict(Ref, ?RDBMS),
- Dog = test_server:timetrap(?default_timeout),
- Temp = lists:keydelete(connection_ref, 1, Config),
- NewConfig = lists:keydelete(watchdog, 1, Temp),
- [{watchdog, Dog}, {connection_ref, Ref} | NewConfig].
+
+ NewConfig = lists:keydelete(connection_ref, 1, Config),
+
+ [{connection_ref, Ref} | NewConfig].
%%--------------------------------------------------------------------
%% Function: end_per_testcase(Case, Config) -> _
@@ -158,27 +159,23 @@ init_per_testcase(_Case, Config) ->
%% Description: Cleanup after each test case
%%--------------------------------------------------------------------
end_per_testcase(_Case, Config) ->
- Ref = ?config(connection_ref, Config),
+ Ref = proplists:get_value(connection_ref, Config),
ok = odbc:disconnect(Ref),
%% Clean up if needed
- Table = ?config(tableName, Config),
+ Table = proplists:get_value(tableName, Config),
{ok, NewRef} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
odbc:sql_query(NewRef, "DROP TABLE " ++ Table),
- odbc:disconnect(NewRef),
- Dog = ?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
- ok.
+ odbc:disconnect(NewRef).
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-stored_proc(doc)->
- ["Test stored proc with OUT param"];
-stored_proc(suite) -> [];
+stored_proc()->
+ [{doc, "Test stored proc with OUT param"}].
stored_proc(Config) when is_list(Config) ->
case ?RDBMS of
X when X == oracle; X == postgres->
- Ref = ?config(connection_ref, Config),
+ Ref = proplists:get_value(connection_ref, Config),
{updated, _} =
odbc:sql_query(Ref,
?RDBMS:stored_proc_integer_out()),
@@ -192,12 +189,11 @@ stored_proc(Config) when is_list(Config) ->
{skip, "stored proc not yet supported"}
end.
-sql_query(doc)->
- ["Test the common cases"];
-sql_query(suite) -> [];
+sql_query()->
+ [{doc, "Test the common cases"}].
sql_query(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -235,14 +231,14 @@ sql_query(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-select_count(doc) ->
- ["Tests select_count/[2,3]'s timeout, "
- " select_count's functionality will be better tested by other tests "
- " such as first."];
+select_count() ->
+ [{doc, "Tests select_count/[2,3]'s timeout, "
+ " select_count's functionality will be better tested by other tests "
+ " such as first."}].
select_count(sute) -> [];
select_count(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
@@ -257,12 +253,11 @@ select_count(Config) when is_list(Config) ->
(catch odbc:select_count(Ref, "SELECT * FROM ", -1)),
ok.
%%-------------------------------------------------------------------------
-first(doc) ->
- ["Tests first/[1,2]"];
-first(suite) -> [];
+first() ->
+ [doc, {"Tests first/[1,2]"}].
first(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
@@ -284,12 +279,11 @@ first(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-last(doc) ->
- ["Tests last/[1,2]"];
-last(suite) -> [];
+last() ->
+ [{doc, "Tests last/[1,2]"}].
last(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
@@ -311,12 +305,11 @@ last(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-next(doc) ->
- ["Tests next/[1,2]"];
-next(suite) -> [];
+next() ->
+ [{doc, "Tests next/[1,2]"}].
next(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
@@ -337,12 +330,11 @@ next(Config) when is_list(Config) ->
{'EXIT', {function_clause, _}} = (catch odbc:next(Ref, -1)),
ok.
%%-------------------------------------------------------------------------
-prev(doc) ->
- ["Tests prev/[1,2]"];
-prev(suite) -> [];
+prev() ->
+ [{doc, "Tests prev/[1,2]"}].
prev(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
@@ -366,12 +358,12 @@ prev(Config) when is_list(Config) ->
{'EXIT', {function_clause, _}} = (catch odbc:prev(Ref, -1)),
ok.
%%-------------------------------------------------------------------------
-select_next(doc) ->
- ["Tests select/[4,5] with CursorRelation = next "];
+select_next() ->
+ [{doc, "Tests select/[4,5] with CursorRelation = next "}].
select_next(suit) -> [];
select_next(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
@@ -407,12 +399,12 @@ select_next(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-select_relative(doc) ->
- ["Tests select/[4,5] with CursorRelation = relative "];
+select_relative() ->
+ [{doc, "Tests select/[4,5] with CursorRelation = relative "}].
select_relative(suit) -> [];
select_relative(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
@@ -448,12 +440,12 @@ select_relative(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-select_absolute(doc) ->
- ["Tests select/[4,5] with CursorRelation = absolute "];
+select_absolute() ->
+ [{doc, "Tests select/[4,5] with CursorRelation = absolute "}].
select_absolute(suit) -> [];
select_absolute(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
@@ -482,12 +474,11 @@ select_absolute(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-create_table_twice(doc) ->
- ["Test what happens if you try to create the same table twice."];
-create_table_twice(suite) -> [];
+create_table_twice() ->
+ [{doc, "Test what happens if you try to create the same table twice."}].
create_table_twice(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -501,12 +492,11 @@ create_table_twice(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-delete_table_twice(doc) ->
- ["Test what happens if you try to delete the same table twice."];
-delete_table_twice(suite) -> [];
+delete_table_twice() ->
+ [{doc, "Test what happens if you try to delete the same table twice."}].
delete_table_twice(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -518,12 +508,12 @@ delete_table_twice(Config) when is_list(Config) ->
ok.
%-------------------------------------------------------------------------
-duplicate_key(doc) ->
- ["Test what happens if you try to use the same key twice"];
+duplicate_key() ->
+ [{doc, "Test what happens if you try to use the same key twice"}].
duplicate_key(suit) -> [];
duplicate_key(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -539,13 +529,12 @@ duplicate_key(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-not_connection_owner(doc) ->
- ["Test what happens if a process that did not start the connection"
- " tries to acess it."];
-not_connection_owner(suite) -> [];
+not_connection_owner() ->
+ [{doc, "Test what happens if a process that did not start the connection"
+ " tries to acess it."}].
not_connection_owner(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
spawn_link(?MODULE, not_owner, [self(), Ref, Table]),
@@ -564,12 +553,11 @@ not_owner(Pid, Ref, Table) ->
Pid ! continue.
%%-------------------------------------------------------------------------
-no_result_set(doc) ->
- ["Tests what happens if you try to use a function that needs an "
- "associated result set when there is none."];
-no_result_set(suite) -> [];
+no_result_set() ->
+ [{doc, "Tests what happens if you try to use a function that needs an "
+ "associated result set when there is none."}].
no_result_set(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
+ Ref = proplists:get_value(connection_ref, Config),
{error, result_set_does_not_exist} = odbc:first(Ref),
{error, result_set_does_not_exist} = odbc:last(Ref),
@@ -582,13 +570,11 @@ no_result_set(Config) when is_list(Config) ->
odbc:select(Ref, {relative, 2}, 1),
ok.
%%-------------------------------------------------------------------------
-query_error(doc) ->
- ["Test what happens if there is an error in the query."];
-query_error(suite) ->
- [];
+query_error() ->
+ [{doc, "Test what happens if there is an error in the query."}].
query_error(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -605,15 +591,13 @@ query_error(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-multiple_select_result_sets(doc) ->
- ["Test what happens if you have a batch of select queries."];
-multiple_select_result_sets(suite) ->
- [];
+multiple_select_result_sets() ->
+ [{doc, "Test what happens if you have a batch of select queries."}].
multiple_select_result_sets(Config) when is_list(Config) ->
case ?RDBMS of
sqlserver ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -640,16 +624,14 @@ multiple_select_result_sets(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
-multiple_mix_result_sets(doc) ->
- ["Test what happens if you have a batch of select and other type of"
- " queries."];
-multiple_mix_result_sets(suite) ->
- [];
+multiple_mix_result_sets() ->
+ [{doc, "Test what happens if you have a batch of select and other type of"
+ " queries."}].
multiple_mix_result_sets(Config) when is_list(Config) ->
case ?RDBMS of
sqlserver ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -674,15 +656,13 @@ multiple_mix_result_sets(Config) when is_list(Config) ->
{skip, "multiple result_set not supported"}
end.
%%-------------------------------------------------------------------------
-multiple_result_sets_error(doc) ->
- ["Test what happens if one of the batched queries fails."];
-multiple_result_sets_error(suite) ->
- [];
+multiple_result_sets_error() ->
+ [{doc, "Test what happens if one of the batched queries fails."}].
multiple_result_sets_error(Config) when is_list(Config) ->
case ?RDBMS of
sqlserver ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -709,15 +689,13 @@ multiple_result_sets_error(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
-param_insert_tiny_int(doc)->
- ["Test insertion of tiny ints by parameterized queries."];
-param_insert_tiny_int(suite) ->
- [];
+param_insert_tiny_int()->
+ [{doc,"Test insertion of tiny ints by parameterized queries."}].
param_insert_tiny_int(Config) when is_list(Config) ->
case ?RDBMS of
sqlserver ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -746,13 +724,11 @@ param_insert_tiny_int(Config) when is_list(Config) ->
{skip, "Type tiniyint not supported"}
end.
%%-------------------------------------------------------------------------
-param_insert_small_int(doc)->
- ["Test insertion of small ints by parameterized queries."];
-param_insert_small_int(suite) ->
- [];
+param_insert_small_int()->
+ [{doc,"Test insertion of small ints by parameterized queries."}].
param_insert_small_int(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -778,13 +754,11 @@ param_insert_small_int(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_insert_int(doc)->
- ["Test insertion of ints by parameterized queries."];
-param_insert_int(suite) ->
- [];
+param_insert_int()->
+ [{doc,"Test insertion of ints by parameterized queries."}].
param_insert_int(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -810,13 +784,11 @@ param_insert_int(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_insert_integer(doc)->
- ["Test insertion of integers by parameterized queries."];
-param_insert_integer(suite) ->
- [];
+param_insert_integer()->
+ [{doc,"Test insertion of integers by parameterized queries."}].
param_insert_integer(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -842,13 +814,11 @@ param_insert_integer(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_insert_decimal(doc)->
- ["Test insertion of decimal numbers by parameterized queries."];
-param_insert_decimal(suite) ->
- [];
+param_insert_decimal()->
+ [{doc,"Test insertion of decimal numbers by parameterized queries."}].
param_insert_decimal(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -893,13 +863,11 @@ param_insert_decimal(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_insert_numeric(doc)->
- ["Test insertion of numeric numbers by parameterized queries."];
-param_insert_numeric(suite) ->
- [];
+param_insert_numeric()->
+ [{doc,"Test insertion of numeric numbers by parameterized queries."}].
param_insert_numeric(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -944,13 +912,11 @@ param_insert_numeric(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_insert_char(doc)->
- ["Test insertion of fixed length string by parameterized queries."];
-param_insert_char(suite) ->
- [];
+param_insert_char()->
+ [{doc,"Test insertion of fixed length string by parameterized queries."}].
param_insert_char(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -980,13 +946,11 @@ param_insert_char(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_insert_character(doc)->
- ["Test insertion of fixed length string by parameterized queries."];
-param_insert_character(suite) ->
- [];
+param_insert_character()->
+ [{doc,"Test insertion of fixed length string by parameterized queries."}].
param_insert_character(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1017,13 +981,11 @@ param_insert_character(Config) when is_list(Config) ->
ok.
%%------------------------------------------------------------------------
-param_insert_char_varying(doc)->
- ["Test insertion of variable length strings by parameterized queries."];
-param_insert_char_varying(suite) ->
- [];
+param_insert_char_varying()->
+ [{doc,"Test insertion of variable length strings by parameterized queries."}].
param_insert_char_varying(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1054,13 +1016,11 @@ param_insert_char_varying(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_insert_character_varying(doc)->
- ["Test insertion of variable length strings by parameterized queries."];
-param_insert_character_varying(suite) ->
- [];
+param_insert_character_varying()->
+ [{doc,"Test insertion of variable length strings by parameterized queries."}].
param_insert_character_varying(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1091,13 +1051,11 @@ param_insert_character_varying(Config) when is_list(Config) ->
[{{sql_varchar, 10}, ["1", 2]}])),
ok.
%%-------------------------------------------------------------------------
-param_insert_float(doc)->
- ["Test insertion of floats by parameterized queries."];
-param_insert_float(suite) ->
- [];
+param_insert_float()->
+ [{doc,"Test insertion of floats by parameterized queries."}].
param_insert_float(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1120,7 +1078,7 @@ param_insert_float(Config) when is_list(Config) ->
true ->
ok;
false ->
- test_server:fail(float_numbers_do_not_match)
+ ct:fail(float_numbers_do_not_match)
end,
{'EXIT',{badarg,odbc,param_query,'Params'}} =
@@ -1130,13 +1088,11 @@ param_insert_float(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_insert_real(doc)->
- ["Test insertion of real numbers by parameterized queries."];
-param_insert_real(suite) ->
- [];
+param_insert_real()->
+ [{doc,"Test insertion of real numbers by parameterized queries."}].
param_insert_real(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1161,7 +1117,7 @@ param_insert_real(Config) when is_list(Config) ->
true ->
ok;
false ->
- test_server:fail(real_numbers_do_not_match)
+ ct:fail(real_numbers_do_not_match)
end,
{'EXIT',{badarg,odbc,param_query,'Params'}} =
@@ -1171,13 +1127,11 @@ param_insert_real(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_insert_double(doc)->
- ["Test insertion of doubles by parameterized queries."];
-param_insert_double(suite) ->
- [];
+param_insert_double()->
+ [{doc,"Test insertion of doubles by parameterized queries."}].
param_insert_double(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1200,7 +1154,7 @@ param_insert_double(Config) when is_list(Config) ->
true ->
ok;
false ->
- test_server:fail(double_numbers_do_not_match)
+ ct:fail(double_numbers_do_not_match)
end,
{'EXIT',{badarg,odbc,param_query,'Params'}} =
@@ -1210,13 +1164,11 @@ param_insert_double(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_insert_mix(doc)->
- ["Test insertion of a mixture of datatypes by parameterized queries."];
-param_insert_mix(suite) ->
- [];
+param_insert_mix()->
+ [{doc,"Test insertion of a mixture of datatypes by parameterized queries."}].
param_insert_mix(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1237,13 +1189,11 @@ param_insert_mix(Config) when is_list(Config) ->
odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
ok.
%%-------------------------------------------------------------------------
-param_update(doc)->
- ["Test parameterized update query."];
-param_update(suite) ->
- [];
+param_update()->
+ [{doc,"Test parameterized update query."}].
param_update(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1272,12 +1222,12 @@ param_update(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-delete_nonexisting_row(doc) -> % OTP-5759
- ["Make a delete...where with false conditions (0 rows deleted). ",
- "This used to give an error message (see ticket OTP-5759)."];
+delete_nonexisting_row() -> % OTP-5759
+ [{doc, "Make a delete...where with false conditions (0 rows deleted). ",
+ "This used to give an error message (see ticket OTP-5759)."}].
delete_nonexisting_row(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref, "CREATE TABLE " ++ Table
@@ -1301,13 +1251,11 @@ delete_nonexisting_row(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_delete(doc) ->
- ["Test parameterized delete query."];
-param_delete(suite) ->
- [];
+param_delete() ->
+ [{doc,"Test parameterized delete query."}].
param_delete(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1336,13 +1284,11 @@ param_delete(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-param_select(doc) ->
- ["Test parameterized select query."];
-param_select(suite) ->
- [];
+param_select() ->
+ [{doc,"Test parameterized select query."}].
param_select(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1366,13 +1312,11 @@ param_select(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_select_empty_params(doc) ->
- ["Test parameterized select query with no parameters."];
-param_select_empty_params(suite) ->
- [];
+param_select_empty_params() ->
+ [{doc,"Test parameterized select query with no parameters."}].
param_select_empty_params(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1396,13 +1340,11 @@ param_select_empty_params(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-param_delete_empty_params(doc) ->
- ["Test parameterized delete query with no parameters."];
-param_delete_empty_params(suite) ->
- [];
+param_delete_empty_params() ->
+ [{doc,"Test parameterized delete query with no parameters."}].
param_delete_empty_params(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1430,13 +1372,11 @@ param_delete_empty_params(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-describe_integer(doc) ->
- ["Test describe_table/[2,3] for integer columns."];
-describe_integer(suite) ->
- [];
+describe_integer() ->
+ [{doc,"Test describe_table/[2,3] for integer columns."}].
describe_integer(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1449,13 +1389,11 @@ describe_integer(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-describe_string(doc) ->
- ["Test describe_table/[2,3] for string columns."];
-describe_string(suite) ->
- [];
+describe_string() ->
+ [{doc,"Test describe_table/[2,3] for string columns."}].
describe_string(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1470,13 +1408,11 @@ describe_string(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-describe_floating(doc) ->
- ["Test describe_table/[2,3] for floting columns."];
-describe_floating(suite) ->
- [];
+describe_floating() ->
+ [{doc,"Test describe_table/[2,3] for floting columns."}].
describe_floating(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1490,14 +1426,12 @@ describe_floating(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-describe_dec_num(doc) ->
- ["Test describe_table/[2,3] for decimal and numerical columns"];
-describe_dec_num(suite) ->
- [];
+describe_dec_num() ->
+ [{doc,"Test describe_table/[2,3] for decimal and numerical columns"}].
describe_dec_num(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} =
odbc:sql_query(Ref,
@@ -1511,14 +1445,12 @@ describe_dec_num(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-describe_timestamp(doc) ->
- ["Test describe_table/[2,3] for tinmestap columns"];
-describe_timestamp(suite) ->
- [];
+describe_timestamp() ->
+ [{doc,"Test describe_table/[2,3] for tinmestap columns"}].
describe_timestamp(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
@@ -1530,14 +1462,12 @@ describe_timestamp(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-describe_no_such_table(doc) ->
- ["Test what happens if you try to describe a table that does not exist."];
-describe_no_such_table(suite) ->
- [];
+describe_no_such_table() ->
+ [{doc,"Test what happens if you try to describe a table that does not exist."}].
describe_no_such_table(Config) when is_list(Config) ->
- Ref = ?config(connection_ref, Config),
- Table = ?config(tableName, Config),
+ Ref = proplists:get_value(connection_ref, Config),
+ Table = proplists:get_value(tableName, Config),
{error, _ } = odbc:describe_table(Ref, Table),
ok.
@@ -1549,10 +1479,10 @@ describe_no_such_table(Config) when is_list(Config) ->
is_driver_error(Error) ->
case is_list(Error) of
true ->
- test_server:format("Driver error ~p~n", [Error]),
+ ct:pal("Driver error ~p~n", [Error]),
ok;
false ->
- test_server:fail(Error)
+ ct:fail(Error)
end.
is_supported_multiple_resultsets(sqlserver) ->
true;
diff --git a/lib/odbc/test/odbc_start_SUITE.erl b/lib/odbc/test/odbc_start_SUITE.erl
index f055eeb60e..310b92ca29 100644
--- a/lib/odbc/test/odbc_start_SUITE.erl
+++ b/lib/odbc/test/odbc_start_SUITE.erl
@@ -49,6 +49,7 @@ init_per_suite(Config) ->
_ ->
%% Make sure odbc is not already started
odbc:stop(),
+ ct:timetrap(?TIMEOUT),
[{tableName, odbc_test_lib:unique_table_name()} | Config]
end
end.
@@ -74,11 +75,9 @@ end_per_suite(_Config) ->
%% variable, but should NOT alter/remove any existing entries.
%% Description: Initialization before each test case
%%--------------------------------------------------------------------
-init_per_testcase(_TestCase, Config0) ->
- test_server:format("ODBCINI = ~p~n", [os:getenv("ODBCINI")]),
- Config = lists:keydelete(watchdog, 1, Config0),
- Dog = test_server:timetrap(?TIMEOUT),
- [{watchdog, Dog} | Config].
+init_per_testcase(_TestCase, Config) ->
+ ct:pal("ODBCINI = ~p~n", [os:getenv("ODBCINI")]),
+ Config.
%%--------------------------------------------------------------------
%% Function: end_per_testcase(TestCase, Config) -> _
@@ -88,15 +87,8 @@ init_per_testcase(_TestCase, Config0) ->
%% 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.
-
+end_per_testcase(_TestCase, _Config) ->
+ ok.
%%--------------------------------------------------------------------
%% Function: all(Clause) -> TestCases
%% Clause - atom() - suite | doc
@@ -135,10 +127,8 @@ app(Config) when is_list(Config) ->
appup(Config) when is_list(Config) ->
ok = ?t:appup_test(odbc).
-start(doc) ->
- ["Test start/stop of odbc"];
-start(suite) ->
- [];
+start() ->
+ [{doc,"Test start/stop of odbc"}].
start(Config) when is_list(Config) ->
PlatformOptions = odbc_test_lib:platform_options(),
{error,odbc_not_started} = odbc:connect(?RDBMS:connection_string(),
@@ -153,9 +143,9 @@ start(Config) when is_list(Config) ->
start_odbc(transient),
start_odbc(permanent);
{error, odbc_not_started} ->
- test_server:fail(start_failed);
+ ct:fail(start_failed);
Error ->
- test_server:format("Connection failed: ~p~n", [Error]),
+ ct:pal("Connection failed: ~p~n", [Error]),
{skip, "ODBC is not properly setup"}
end.
@@ -166,13 +156,12 @@ start_odbc(Type) ->
ok = odbc:disconnect(Ref),
odbc:stop();
{error, odbc_not_started} ->
- test_server:fail(start_failed)
+ ct:fail(start_failed)
end.
-long_connection_line(doc)->
- ["Test a connection line longer than 127 characters"];
-long_connection_line(suite) -> [];
+long_connection_line()->
+ [{doc,"Test a connection line longer than 127 characters"}].
long_connection_line(_Config) ->
odbc:start(),
String133 = "unknown_odbc_parameter=01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789",
diff --git a/lib/odbc/test/odbc_test_lib.erl b/lib/odbc/test/odbc_test_lib.erl
index 37c2249303..cf82d4d32a 100644
--- a/lib/odbc/test/odbc_test_lib.erl
+++ b/lib/odbc/test/odbc_test_lib.erl
@@ -61,13 +61,13 @@ odbc_check() ->
end.
check_row_count(Count, Count) ->
- test_server:format("Correct row count Count: ~p~n", [Count]),
+ ct:pal("Correct row count Count: ~p~n", [Count]),
true;
check_row_count(_, undefined) ->
- test_server:format("Undefined row count ~n", []),
+ ct:pal("Undefined row count ~n", []),
true;
check_row_count(Expected, Count) ->
- test_server:format("Incorrect row count Expected ~p Got ~p~n",
+ ct:pal("Incorrect row count Expected ~p Got ~p~n",
[Expected, Count]),
false.
diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk
index 957c6b42eb..2e313570e1 100644
--- a/lib/odbc/vsn.mk
+++ b/lib/odbc/vsn.mk
@@ -1 +1 @@
-ODBC_VSN = 2.11.2
+ODBC_VSN = 2.12
diff --git a/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl b/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl
index 545be62852..88049a509f 100644
--- a/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl
+++ b/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -610,11 +610,16 @@ convert_list([{N, T, _O}|Rest], HowMany, Counter, Acc) ->
%% Returns :
%%----------------------------------------------------------------------
destroy(OE_THIS, OE_State) ->
- case corba:get_subobject_key(OE_THIS) of
- <<131,100,0,9,117,110,100,101,102,105,110,101,100>> ->
- %% undefined binary.
- corba:raise(#'NO_PERMISSION'{completion_status=?COMPLETED_NO});
- SubobjKey ->
+ SubobjKey = corba:get_subobject_key(OE_THIS),
+ try begin
+ true = (byte_size(SubobjKey) < 20),
+ undefined = binary_to_term(SubobjKey)
+ end
+ of
+ _ ->
+ corba:raise(#'NO_PERMISSION'{completion_status=?COMPLETED_NO})
+ catch
+ error:_ -> %% Not atom 'undefined', carry on...
_DF =
fun() ->
case mnesia:wread({orber_CosNaming, SubobjKey}) of
@@ -624,12 +629,7 @@ destroy(OE_THIS, OE_State) ->
orber:dbg("[~p] ~p:destroy(~p);~n"
"DB access returned ~p",
[?LINE, ?MODULE, SubobjKey, Other], ?DEBUG_LEVEL),
- {'EXCEPTION', #'CosNaming_NamingContext_NotEmpty'{}};
- Other ->
- orber:dbg("[~p] ~p:destroy(~p);~n"
- "DB access returned ~p",
- [?LINE, ?MODULE, SubobjKey, Other], ?DEBUG_LEVEL),
- {'EXCEPTION', #'INTERNAL'{completion_status=?COMPLETED_NO}}
+ {'EXCEPTION', #'CosNaming_NamingContext_NotEmpty'{}}
end
end,
case mnesia:transaction(_DF) of
diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml
index 89f258e5e9..5a82270b28 100644
--- a/lib/orber/doc/src/notes.xml
+++ b/lib/orber/doc/src/notes.xml
@@ -33,6 +33,20 @@
<file>notes.xml</file>
</header>
+ <section><title>Orber 3.8.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Fix some dialyzer warnings</p>
+ <p>
+ Own Id: OTP-14006</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
<section><title>Orber 3.8.2</title>
diff --git a/lib/orber/src/cdr_encode.erl b/lib/orber/src/cdr_encode.erl
index f922b330a0..2c42d5bd7e 100644
--- a/lib/orber/src/cdr_encode.erl
+++ b/lib/orber/src/cdr_encode.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -683,7 +683,7 @@ enc_fixed(_Env, Digits, Scale, Fixed, _Bytes, _Len) ->
orber:dbg("[~p] cdr_encode:enc_fixed(~p, ~p, ~p)~n"
"The supplied fixed type incorrect. Check that the 'digits' and 'scale' field~n"
"match the definition in the IDL-specification. The value field must be~n"
- "a list of Digits lenght.",
+ "a list of Digits length.",
[?LINE, Digits, Scale, Fixed], ?DEBUG_LEVEL),
corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}).
diff --git a/lib/orber/src/corba.erl b/lib/orber/src/corba.erl
index faebbc4059..23ce01ffc3 100644
--- a/lib/orber/src/corba.erl
+++ b/lib/orber/src/corba.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -2115,7 +2115,7 @@ call_RQprotected(Module, Obj, Func, Args, GroupID, RQCtx) ->
sticky_write),
Reply;
% retransmitted request
- #ft_reply_retention{reply = Reply} ->
+ [#ft_reply_retention{reply = Reply}] ->
Reply
end.
diff --git a/lib/orber/src/orber_ifr_contained.erl b/lib/orber/src/orber_ifr_contained.erl
index d5f41fbe72..2a67fa98fd 100644
--- a/lib/orber/src/orber_ifr_contained.erl
+++ b/lib/orber/src/orber_ifr_contained.erl
@@ -232,7 +232,7 @@ move(true, Contained_objref, New_container, New_name, New_version) ->
lists:filter(fun(X) -> X /= Contained_objref
end, select(Old_container_obj,
contents))),
- New_container_obj = mnesia:read(New_container),
+ [New_container_obj] = mnesia:read(New_container),
Contents = orber_ifr_container:contents(New_container, dk_All,
true),
New_new_container_obj =
diff --git a/lib/orber/src/orber_iiop.hrl b/lib/orber/src/orber_iiop.hrl
index 6bc82fb6d6..ec502b6f09 100644
--- a/lib/orber/src/orber_iiop.hrl
+++ b/lib/orber/src/orber_iiop.hrl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -279,8 +279,8 @@
%%----------------------------------------------------------------------
%% Profile Body
%%
-%% iiop_version: describes the version of IIOP that the agent at the
-%% specified adress is prepared to receive.
+%% iiop_version: describes the version of IIOP that the agent at the
+%% specified address is prepared to receive.
%% host: identifies the internet host to which the GIOP messages
%% for the specified object may be sent.
%% port: contains the TCP?IP port number where the target agnet is listening
diff --git a/lib/orber/src/orber_initial_references.erl b/lib/orber/src/orber_initial_references.erl
index 738d702088..9140563881 100644
--- a/lib/orber/src/orber_initial_references.erl
+++ b/lib/orber/src/orber_initial_references.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -89,7 +89,7 @@ install(Timeout, Options) ->
end,
Wait = mnesia:wait_for_tables([orber_references], Timeout),
- %% Check if any error has occured yet. If there are errors, return them.
+ %% Check if any error has occurred yet. If there are errors, return them.
if
DB_Result == {atomic, ok},
Wait == ok ->
diff --git a/lib/orber/src/orber_objectkeys.erl b/lib/orber/src/orber_objectkeys.erl
index 1233e4e721..12ed1a2f85 100644
--- a/lib/orber/src/orber_objectkeys.erl
+++ b/lib/orber/src/orber_objectkeys.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -344,7 +344,7 @@ install(Timeout, Options) ->
end,
Wait = mnesia:wait_for_tables([orber_objkeys], Timeout),
- %% Check if any error has occured yet. If there are errors, return them.
+ %% Check if any error has occurred yet. If there are errors, return them.
if
DB_Result == {atomic, ok},
Wait == ok ->
diff --git a/lib/orber/test/multi_ORB_SUITE.erl b/lib/orber/test/multi_ORB_SUITE.erl
index d739e47cc1..3c5bb0b5e5 100644
--- a/lib/orber/test/multi_ORB_SUITE.erl
+++ b/lib/orber/test/multi_ORB_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -135,13 +135,12 @@ cases() ->
setup_multi_connection_timeout_api,
setup_multi_connection_timeout_attempts_api,
setup_multi_connection_timeout_random_api,
- ssl_1_multi_orber_api,
ssl_1_multi_orber_generation_3_api,
- ssl_2_multi_orber_api,
ssl_2_multi_orber_generation_3_api,
- ssl_reconfigure_api,
ssl_reconfigure_generation_3_api].
+% ssl_1_multi_orber_api,ssl_2_multi_orber_api,ssl_reconfigure_api,
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
diff --git a/lib/orber/test/orber_test_lib.erl b/lib/orber/test/orber_test_lib.erl
index 95ab26cd30..9b19c4bc4e 100644
--- a/lib/orber/test/orber_test_lib.erl
+++ b/lib/orber/test/orber_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -356,11 +356,17 @@ get_options(ssl, Role, Level) ->
get_options(ssl, Role, 2, Options) ->
Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
- [{depth, 2},
- {verify, 2},
- {keyfile, filename:join([Dir, Role, "key.pem"])},
- {cacertfile, filename:join([Dir, Role, "cacerts.pem"])},
- {certfile, filename:join([Dir, Role, "cert.pem"])} |Options];
+ Options1 = [{depth, 2},
+ {verify, 2},
+ {keyfile, filename:join([Dir, Role, "key.pem"])},
+ {cacertfile, filename:join([Dir, Role, "cacerts.pem"])},
+ {certfile, filename:join([Dir, Role, "cert.pem"])} |Options],
+ case Role of
+ client ->
+ [{server_name_indication, disable} |Options1];
+ server ->
+ Options1
+ end;
get_options(iiop_ssl, _Role, 2, Options) ->
Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
[{ssl_server_options, [{depth, 2},
@@ -369,10 +375,11 @@ get_options(iiop_ssl, _Role, 2, Options) ->
{cacertfile, filename:join([Dir, "server", "cacerts.pem"])},
{keyfile, filename:join([Dir, "server", "key.pem"])}]},
{ssl_client_options, [{depth, 2},
- {verify, 2},
- {certfile, filename:join([Dir, "client", "cert.pem"])},
- {cacertfile, filename:join([Dir, "client", "cacerts.pem"])},
- {keyfile, filename:join([Dir, "client", "key.pem"])}]},
+ {verify, 2},
+ {server_name_indication, disable},
+ {certfile, filename:join([Dir, "client", "cert.pem"])},
+ {cacertfile, filename:join([Dir, "client", "cacerts.pem"])},
+ {keyfile, filename:join([Dir, "client", "key.pem"])}]},
{secure, ssl} |Options];
get_options(iiop_ssl, _Role, 1, Options) ->
Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
@@ -382,10 +389,11 @@ get_options(iiop_ssl, _Role, 1, Options) ->
{cacertfile, filename:join([Dir, "server", "cacerts.pem"])},
{keyfile, filename:join([Dir, "server", "key.pem"])}]},
{ssl_client_options, [{depth, 1},
- {verify, 0},
- {certfile, filename:join([Dir, "client", "cert.pem"])},
- {cacertfile, filename:join([Dir, "client", "cacerts.pem"])},
- {keyfile, filename:join([Dir, "client", "key.pem"])}]},
+ {verify, 0},
+ {server_name_indication, disable},
+ {certfile, filename:join([Dir, "client", "cert.pem"])},
+ {cacertfile, filename:join([Dir, "client", "cacerts.pem"])},
+ {keyfile, filename:join([Dir, "client", "key.pem"])}]},
{secure, ssl} |Options].
create_paths() ->
diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk
index dcb2c985a3..595e686cb7 100644
--- a/lib/orber/vsn.mk
+++ b/lib/orber/vsn.mk
@@ -1 +1 @@
-ORBER_VSN = 3.8.2
+ORBER_VSN = 3.8.3
diff --git a/lib/os_mon/doc/src/notes.xml b/lib/os_mon/doc/src/notes.xml
index e6e80b046d..df4151147c 100644
--- a/lib/os_mon/doc/src/notes.xml
+++ b/lib/os_mon/doc/src/notes.xml
@@ -31,6 +31,21 @@
</header>
<p>This document describes the changes made to the OS_Mon application.</p>
+<section><title>Os_Mon 2.4.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Support s390x in os_mon.</p>
+ <p>
+ Own Id: OTP-14161 Aux Id: PR-1309 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Os_Mon 2.4.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/os_mon/src/Makefile b/lib/os_mon/src/Makefile
index 3ff63204c6..fc2eb22393 100644
--- a/lib/os_mon/src/Makefile
+++ b/lib/os_mon/src/Makefile
@@ -60,7 +60,7 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_obsolete_guard -I$(INCLUDE) -Werror
+ERL_COMPILE_FLAGS += -I$(INCLUDE) -Werror
# ----------------------------------------------------
# Targets
diff --git a/lib/os_mon/src/memsup.erl b/lib/os_mon/src/memsup.erl
index 4729d090f8..0a9a883390 100644
--- a/lib/os_mon/src/memsup.erl
+++ b/lib/os_mon/src/memsup.erl
@@ -701,6 +701,7 @@ get_os_wordsize_with_uname() ->
"sparc64" -> 64;
"amd64" -> 64;
"ppc64" -> 64;
+ "s390x" -> 64;
_ -> 32
end.
diff --git a/lib/os_mon/vsn.mk b/lib/os_mon/vsn.mk
index 1ac0fb1d27..59a3d9dee4 100644
--- a/lib/os_mon/vsn.mk
+++ b/lib/os_mon/vsn.mk
@@ -1 +1 @@
-OS_MON_VSN = 2.4.1
+OS_MON_VSN = 2.4.2
diff --git a/lib/otp_mibs/src/Makefile b/lib/otp_mibs/src/Makefile
index 4023f50d48..5c7af39c3f 100644
--- a/lib/otp_mibs/src/Makefile
+++ b/lib/otp_mibs/src/Makefile
@@ -64,7 +64,7 @@ TARGETS = $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += -I$(INCLUDE) +warn_obsolete_guard
+ERL_COMPILE_FLAGS += -I$(INCLUDE)
# ----------------------------------------------------
# Targets
diff --git a/lib/parsetools/doc/src/leex.xml b/lib/parsetools/doc/src/leex.xml
index 29d546105f..1227625287 100644
--- a/lib/parsetools/doc/src/leex.xml
+++ b/lib/parsetools/doc/src/leex.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2009</year><year>2016</year>
+ <year>2009</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -446,7 +446,8 @@ D = [0-9]
</item>
</taglist>
- <p>The following examples define Erlang data types:</p>
+ <p>The following examples define simplified versions of a few
+ Erlang data types:</p>
<code>
Atoms [a-z][0-9a-zA-Z_]*
diff --git a/lib/parsetools/doc/src/notes.xml b/lib/parsetools/doc/src/notes.xml
index b826b4d03a..3fa7169f50 100644
--- a/lib/parsetools/doc/src/notes.xml
+++ b/lib/parsetools/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,69 @@
</header>
<p>This document describes the changes made to the Parsetools application.</p>
+<section><title>Parsetools 2.1.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Minor documentation fixes</p>
+ <p>
+ Own Id: OTP-14276 Aux Id: PR-1357 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Miscellaneous updates due to atoms containing
+ arbitrary Unicode characters. </p>
+ <p>
+ Own Id: OTP-14285</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Parsetools 2.1.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Correct counting of newlines when rules with newlines
+ are used in Leex. </p>
+ <p>
+ Own Id: OTP-13916 Aux Id: ERL-263 </p>
+ </item>
+ <item>
+ <p> Correct handling of Unicode in Leex. </p>
+ <p>
+ Own Id: OTP-13919</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Parsetools 2.1.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Yecc generates Dialyzer suppressions to avoid
+ warnings when operator precedence declarations are used.
+ </p>
+ <p>
+ Own Id: OTP-13681</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Parsetools 2.1.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/parsetools/doc/src/yecc.xml b/lib/parsetools/doc/src/yecc.xml
index 6ec9fb5f0e..5f95b5c150 100644
--- a/lib/parsetools/doc/src/yecc.xml
+++ b/lib/parsetools/doc/src/yecc.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -201,13 +201,13 @@
<p>The grammar starts with an optional <c>header</c> section. The
header is put first in the generated file, before the module
declaration. The purpose of the header is to provide a means to
- make the documentation generated by <c>EDoc</c> look nicer. Each
+ make the documentation generated by EDoc look nicer. Each
header line should be enclosed in double quotes, and newlines
will be inserted between the lines. For example:</p>
<code>
Header "%% Copyright (C)"
"%% @private"
-"%% @Author John"</code>
+"%% @Author John".</code>
<p>Next comes a declaration of the <c>nonterminal categories</c>
to be used in the rules. For example:</p>
<code type="none">
diff --git a/lib/parsetools/include/leexinc.hrl b/lib/parsetools/include/leexinc.hrl
index 2657fdcfaa..b4449607cb 100644
--- a/lib/parsetools/include/leexinc.hrl
+++ b/lib/parsetools/include/leexinc.hrl
@@ -36,8 +36,10 @@ string(Ics0, L0, Tcs, Ts) ->
string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts);
{reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state
{error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1};
- {A,Alen,_Tlen,_Ics1,_L1,_S1} ->
- string_cont(yysuf(Tcs, Alen), L0, yyaction(A, Alen, Tcs, L0), Ts)
+ {A,Alen,Tlen,_Ics1,L1,_S1} ->
+ Tcs1 = yysuf(Tcs, Alen),
+ L2 = adjust_line(Tlen, Alen, Tcs1, L1),
+ string_cont(Tcs1, L2, yyaction(A, Alen, Tcs, L0), Ts)
end.
%% string_cont(RestChars, Line, Token, Tokens)
@@ -107,8 +109,10 @@ token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) ->
{reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match
Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},
{done,{error,Error,L1},Ics1};
- {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> % Use last accept match
- token_cont(yysuf(Tcs, Alen1), L0, yyaction(A1, Alen1, Tcs, Tline))
+ {A1,Alen1,Tlen1,_Ics1,L1,_S1} -> % Use last accept match
+ Tcs1 = yysuf(Tcs, Alen1),
+ L2 = adjust_line(Tlen1, Alen1, Tcs1, L1),
+ token_cont(Tcs1, L2, yyaction(A1, Alen1, Tcs, Tline))
end.
%% token_cont(RestChars, Line, Token)
@@ -181,9 +185,11 @@ tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) ->
%% Skip rest of tokens.
Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}},
skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error);
- {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} ->
+ {A1,Alen1,Tlen1,_Ics1,L1,_S1} ->
Token = yyaction(A1, Alen1, Tcs, Tline),
- tokens_cont(yysuf(Tcs, Alen1), L0, Token, Ts)
+ Tcs1 = yysuf(Tcs, Alen1),
+ L2 = adjust_line(Tlen1, Alen1, Tcs1, L1),
+ tokens_cont(Tcs1, L2, Token, Ts)
end.
%% tokens_cont(RestChars, Line, Token, Tokens)
@@ -235,9 +241,11 @@ skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) ->
{done,{error,Error,L1},eof};
{reject,_Alen1,Tlen1,_Ics1,L1,_S1} ->
skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error);
- {A1,Alen1,_Tlen1,_Ics1,L1,_S1} ->
+ {A1,Alen1,Tlen1,_Ics1,L1,_S1} ->
Token = yyaction(A1, Alen1, Tcs, Tline),
- skip_cont(yysuf(Tcs, Alen1), L1, Token, Error)
+ Tcs1 = yysuf(Tcs, Alen1),
+ L2 = adjust_line(Tlen1, Alen1, Tcs1, L1),
+ skip_cont(Tcs1, L2, Token, Error)
end.
%% skip_cont(RestChars, Line, Token, Error)
@@ -269,6 +277,17 @@ yyrev(List, Tail) -> lists:reverse(List, Tail).
yypre(List, N) -> lists:sublist(List, N).
yysuf(List, N) -> lists:nthtail(N, List).
+%% adjust_line(TokenLength, AcceptLength, Chars, Line) -> NewLine
+%% Make sure that newlines in Chars are not counted twice.
+%% Line has been updated with respect to newlines in the prefix of
+%% Chars consisting of (TokenLength - AcceptLength) characters.
+
+adjust_line(N, N, _Cs, L) -> L;
+adjust_line(T, A, [$\n|Cs], L) ->
+ adjust_line(T-1, A, Cs, L-1);
+adjust_line(T, A, [_|Cs], L) ->
+ adjust_line(T-1, A, Cs, L).
+
%% yystate() -> InitialState.
%% yystate(State, InChars, Line, CurrTokLen, AcceptAction, AcceptLen) ->
%% {Action, AcceptLen, RestChars, Line} |
diff --git a/lib/parsetools/include/yeccpre.hrl b/lib/parsetools/include/yeccpre.hrl
index fe958e9738..91d6cd49a6 100644
--- a/lib/parsetools/include/yeccpre.hrl
+++ b/lib/parsetools/include/yeccpre.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -151,21 +151,20 @@ yecctoken_location(Token) ->
end.
-compile({nowarn_unused_function, yecctoken2string/1}).
-yecctoken2string({atom, _, A}) -> io_lib:write(A);
+yecctoken2string({atom, _, A}) -> io_lib:write_atom(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:write(A);
-yecctoken2string({_Cat, _, Val}) -> io_lib:format("~p",[Val]);
+yecctoken2string({_Cat, _, Val}) -> io_lib:format("~tp", [Val]);
yecctoken2string({dot, _}) -> "'.'";
-yecctoken2string({'$end', _}) ->
- [];
+yecctoken2string({'$end', _}) -> [];
yecctoken2string({Other, _}) when is_atom(Other) ->
- io_lib:write(Other);
+ io_lib:write_atom(Other);
yecctoken2string(Other) ->
- io_lib:write(Other).
+ io_lib:format("~tp", [Other]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/parsetools/src/Makefile b/lib/parsetools/src/Makefile
index dea29bee4c..ba206904ec 100644
--- a/lib/parsetools/src/Makefile
+++ b/lib/parsetools/src/Makefile
@@ -59,7 +59,7 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_obsolete_guard -I$(ERL_TOP)/lib/stdlib/include \
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/stdlib/include \
-Werror
# ----------------------------------------------------
diff --git a/lib/parsetools/src/leex.erl b/lib/parsetools/src/leex.erl
index 15d42a4d9c..e2e7d7359f 100644
--- a/lib/parsetools/src/leex.erl
+++ b/lib/parsetools/src/leex.erl
@@ -1264,7 +1264,7 @@ pack_dfa([], _, Rs, PDFA) -> {PDFA,Rs}.
%% {Action, AcceptLength, CurrTokLen, RestChars, Line, State}.
%% The return CurrTokLen is always the current number of characters
-%% scanned in the current token. The returns have the follwoing
+%% scanned in the current token. The returns have the following
%% meanings:
%% {Action, AcceptLength, RestChars, Line} -
%% The scanner has reached an accepting end-state, for example after
@@ -1281,7 +1281,7 @@ pack_dfa([], _, Rs, PDFA) -> {PDFA,Rs}.
%%
%% {reject, AcceptLength, CurrTokLen, RestChars, Line, State} -
%% {Action, AcceptLength, CurrTokLen, RestChars, Line, State} -
-%% The scanner has reached a non-accepting transistion state. If
+%% The scanner has reached a non-accepting transition state. If
%% RestChars == [] we need to get more characters to continue.
%% Otherwise if 'reject' then no accepting state has been reached it
%% is an error. If we have an Action and AcceptLength then these are
@@ -1548,22 +1548,23 @@ out_action_code(File, XrlFile, {_A,Code,_Vars,Name,Args,ArgsChars}) ->
L = erl_scan:line(hd(Code)),
output_file_directive(File, XrlFile, L-2),
io:fwrite(File, "~s(~s) ->~n", [Name, ArgsChars]),
- io:fwrite(File, " ~s\n", [pp_tokens(Code, L)]).
+ io:fwrite(File, " ~ts\n", [pp_tokens(Code, L, File)]).
-%% pp_tokens(Tokens, Line) -> [char()].
+%% pp_tokens(Tokens, Line, File) -> [char()].
%% Prints the tokens keeping the line breaks of the original code.
-pp_tokens(Tokens, Line0) -> pp_tokens(Tokens, Line0, none).
+pp_tokens(Tokens, Line0, File) -> pp_tokens(Tokens, Line0, File, none).
-pp_tokens([], _Line0, _) -> [];
-pp_tokens([T | Ts], Line0, Prev) ->
+pp_tokens([], _Line0, _, _) -> [];
+pp_tokens([T | Ts], Line0, File, Prev) ->
Line = erl_scan:line(T),
- [pp_sep(Line, Line0, Prev, T), pp_symbol(T) | pp_tokens(Ts, Line, T)].
+ [pp_sep(Line, Line0, Prev, T),
+ pp_symbol(T, File) | pp_tokens(Ts, Line, File, T)].
-pp_symbol({var,_,Var}) -> atom_to_list(Var);
-pp_symbol({_,_,Symbol}) -> io_lib:fwrite("~p", [Symbol]);
-pp_symbol({dot, _}) -> ".";
-pp_symbol({Symbol, _}) -> atom_to_list(Symbol).
+pp_symbol({var,_,Var}, _) -> atom_to_list(Var);
+pp_symbol({_,_,Symbol}, File) -> format_symbol(Symbol, File);
+pp_symbol({dot, _}, _) -> ".";
+pp_symbol({Symbol, _}, _) -> atom_to_list(Symbol).
pp_sep(Line, Line0, Prev, T) when Line > Line0 ->
["\n " | pp_sep(Line - 1, Line0, Prev, T)];
@@ -1586,6 +1587,8 @@ out_dfa_graph(St, DFA, DF) ->
case file:open(St#leex.gfile, [write]) of
{ok,Gfile} ->
try
+ %% Set the same encoding as infile:
+ set_encoding(St, Gfile),
io:fwrite(Gfile, "digraph DFA {~n", []),
out_dfa_states(Gfile, DFA, DF),
out_dfa_edges(Gfile, DFA),
@@ -1620,17 +1623,17 @@ out_dfa_edges(File, DFA) ->
end, orddict:new(), Pt),
foreach(fun (T) ->
Crs = orddict:fetch(T, Tdict),
- Edgelab = dfa_edgelabel(Crs),
- io:fwrite(File, " ~b -> ~b [label=\"~s\"];~n",
+ Edgelab = dfa_edgelabel(Crs, File),
+ io:fwrite(File, " ~b -> ~b [label=\"~ts\"];~n",
[S,T,Edgelab])
end, sort(orddict:fetch_keys(Tdict)))
end, DFA).
-dfa_edgelabel([C]) when is_integer(C) -> quote(C);
-dfa_edgelabel(Cranges) ->
+dfa_edgelabel([C], File) when is_integer(C) -> quote(C, File);
+dfa_edgelabel(Cranges, File) ->
%% io:fwrite("el: ~p\n", [Cranges]),
- "[" ++ map(fun ({A,B}) -> [quote(A), "-", quote(B)];
- (C) -> [quote(C)]
+ "[" ++ map(fun ({A,B}) -> [quote(A, File), "-", quote(B, File)];
+ (C) -> [quote(C, File)]
end, Cranges) ++ "]".
set_encoding(#leex{encoding = none}, File) ->
@@ -1649,33 +1652,50 @@ output_file_directive(File, Filename, Line) ->
format_filename(Filename0, File) ->
Filename = filename:flatten(Filename0),
+ case enc(File) of
+ unicode -> io_lib:write_string(Filename);
+ latin1 -> io_lib:write_string_as_latin1(Filename)
+ end.
+
+format_symbol(Symbol, File) ->
+ Format = case enc(File) of
+ latin1 -> "~p";
+ unicode -> "~tp"
+ end,
+ io_lib:fwrite(Format, [Symbol]).
+
+enc(File) ->
case lists:keyfind(encoding, 1, io:getopts(File)) of
- {encoding, unicode} -> io_lib:write_string(Filename);
- _ -> io_lib:write_string_as_latin1(Filename)
+ false -> latin1; % should never happen
+ {encoding, Enc} -> Enc
end.
-quote($^) -> "\\^";
-quote($.) -> "\\.";
-quote($$) -> "\\$";
-quote($-) -> "\\-";
-quote($[) -> "\\[";
-quote($]) -> "\\]";
-quote($\s) -> "\\\\s";
-quote($\") -> "\\\"";
-quote($\b) -> "\\\\b";
-quote($\f) -> "\\\\f";
-quote($\n) -> "\\\\n";
-quote($\r) -> "\\\\r";
-quote($\t) -> "\\\\t";
-quote($\e) -> "\\\\e";
-quote($\v) -> "\\\\v";
-quote($\d) -> "\\\\d";
-quote($\\) -> "\\\\";
-quote(C) when is_integer(C) ->
+quote($^, _File) -> "\\^";
+quote($., _File) -> "\\.";
+quote($$, _File) -> "\\$";
+quote($-, _File) -> "\\-";
+quote($[, _File) -> "\\[";
+quote($], _File) -> "\\]";
+quote($\s, _File) -> "\\\\s";
+quote($\", _File) -> "\\\"";
+quote($\b, _File) -> "\\\\b";
+quote($\f, _File) -> "\\\\f";
+quote($\n, _File) -> "\\\\n";
+quote($\r, _File) -> "\\\\r";
+quote($\t, _File) -> "\\\\t";
+quote($\e, _File) -> "\\\\e";
+quote($\v, _File) -> "\\\\v";
+quote($\d, _File) -> "\\\\d";
+quote($\\, _File) -> "\\\\";
+quote(C, File) when is_integer(C) ->
%% Must remove the $ and get the \'s right.
- case io_lib:write_char(C) of
+ S = case enc(File) of
+ unicode -> io_lib:write_char(C);
+ latin1 -> io_lib:write_char_as_latin1(C)
+ end,
+ case S of
[$$,$\\|Cs] -> "\\\\" ++ Cs;
[$$|Cs] -> Cs
end;
-quote(maxchar) ->
+quote(maxchar, _File) ->
"MAXCHAR".
diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl
index 1b426141a1..36e33b52a4 100644
--- a/lib/parsetools/src/yecc.erl
+++ b/lib/parsetools/src/yecc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -81,7 +81,7 @@
-record(rule, {
n, % rule n in the grammar file
- line,
+ anno,
symbols, % the names of symbols
tokens,
is_guard, % the action is a guard (not used)
@@ -105,7 +105,7 @@
-record(user_code, {state, terminal, funname, action}).
--record(symbol, {line = none, name}).
+-record(symbol, {anno = none, name}).
%% ACCEPT is neither an atom nor a non-terminal.
-define(ACCEPT, {}).
@@ -154,13 +154,13 @@ compile(Input0, Output0,
format_error(bad_declaration) ->
io_lib:fwrite("unknown or bad declaration, ignored", []);
format_error({bad_expect, SymName}) ->
- io_lib:fwrite("argument ~s of Expect is not an integer",
+ io_lib:fwrite("argument ~ts of Expect is not an integer",
[format_symbol(SymName)]);
format_error({bad_rootsymbol, SymName}) ->
- io_lib:fwrite("rootsymbol ~s is not a nonterminal",
+ io_lib:fwrite("rootsymbol ~ts is not a nonterminal",
[format_symbol(SymName)]);
format_error({bad_states, SymName}) ->
- io_lib:fwrite("argument ~s of States is not an integer",
+ io_lib:fwrite("argument ~ts of States is not an integer",
[format_symbol(SymName)]);
format_error({conflict, Conflict}) ->
format_conflict(Conflict);
@@ -169,19 +169,19 @@ format_error({conflicts, SR, RR}) ->
format_error({duplicate_declaration, Tag}) ->
io_lib:fwrite("duplicate declaration of ~s", [atom_to_list(Tag)]);
format_error({duplicate_nonterminal, Nonterminal}) ->
- io_lib:fwrite("duplicate non-terminals ~s",
+ io_lib:fwrite("duplicate non-terminals ~ts",
[format_symbol(Nonterminal)]);
format_error({duplicate_precedence, Op}) ->
- io_lib:fwrite("duplicate precedence operator ~s",
+ io_lib:fwrite("duplicate precedence operator ~ts",
[format_symbol(Op)]);
format_error({duplicate_terminal, Terminal}) ->
- io_lib:fwrite("duplicate terminal ~s",
+ io_lib:fwrite("duplicate terminal ~ts",
[format_symbol(Terminal)]);
format_error({endsymbol_is_nonterminal, Symbol}) ->
- io_lib:fwrite("endsymbol ~s is a nonterminal",
+ io_lib:fwrite("endsymbol ~ts is a nonterminal",
[format_symbol(Symbol)]);
format_error({endsymbol_is_terminal, Symbol}) ->
- io_lib:fwrite("endsymbol ~s is a terminal",
+ io_lib:fwrite("endsymbol ~ts is a terminal",
[format_symbol(Symbol)]);
format_error({error, Module, Error}) ->
Module:format_error(Error);
@@ -192,7 +192,7 @@ format_error(illegal_empty) ->
format_error({internal_error, Error}) ->
io_lib:fwrite("internal yecc error: ~w", [Error]);
format_error({missing_syntax_rule, Nonterminal}) ->
- io_lib:fwrite("no syntax rule for non-terminal symbol ~s",
+ io_lib:fwrite("no syntax rule for non-terminal symbol ~ts",
[format_symbol(Nonterminal)]);
format_error({n_states, Exp, N}) ->
io_lib:fwrite("expected ~w states, but got ~p states", [Exp, N]);
@@ -201,31 +201,31 @@ format_error(no_grammar_rules) ->
format_error(nonterminals_missing) ->
io_lib:fwrite("Nonterminals is missing", []);
format_error({precedence_op_is_endsymbol, SymName}) ->
- io_lib:fwrite("precedence operator ~s is endsymbol",
+ io_lib:fwrite("precedence operator ~ts is endsymbol",
[format_symbol(SymName)]);
format_error({precedence_op_is_unknown, SymName}) ->
- io_lib:fwrite("unknown precedence operator ~s",
+ io_lib:fwrite("unknown precedence operator ~ts",
[format_symbol(SymName)]);
format_error({reserved, N}) ->
io_lib:fwrite("the use of ~w should be avoided", [N]);
format_error({symbol_terminal_and_nonterminal, SymName}) ->
- io_lib:fwrite("symbol ~s is both a terminal and nonterminal",
+ io_lib:fwrite("symbol ~ts is both a terminal and nonterminal",
[format_symbol(SymName)]);
format_error(rootsymbol_missing) ->
io_lib:fwrite("Rootsymbol is missing", []);
format_error(terminals_missing) ->
io_lib:fwrite("Terminals is missing", []);
format_error({undefined_nonterminal, Symbol}) ->
- io_lib:fwrite("undefined nonterminal: ~s", [format_symbol(Symbol)]);
+ io_lib:fwrite("undefined nonterminal: ~ts", [format_symbol(Symbol)]);
format_error({undefined_pseudo_variable, Atom}) ->
io_lib:fwrite("undefined pseudo variable ~w", [Atom]);
format_error({undefined_symbol, SymName}) ->
- io_lib:fwrite("undefined rhs symbol ~s", [format_symbol(SymName)]);
+ io_lib:fwrite("undefined rhs symbol ~ts", [format_symbol(SymName)]);
format_error({unused_nonterminal, Nonterminal}) ->
- io_lib:fwrite("non-terminal symbol ~s not used",
+ io_lib:fwrite("non-terminal symbol ~ts not used",
[format_symbol(Nonterminal)]);
format_error({unused_terminal, Terminal}) ->
- io_lib:fwrite("terminal symbol ~s not used",
+ io_lib:fwrite("terminal symbol ~ts not used",
[format_symbol(Terminal)]);
format_error({bad_symbol, String}) ->
io_lib:fwrite("bad symbol ~ts", [String]);
@@ -517,7 +517,7 @@ parse_grammar(Grammar, Inport, NextLine, St0) ->
parse_grammar(Inport, NextLine, St).
parse_grammar({error,ErrorLine,Error}, St) ->
- add_error(ErrorLine, Error, St);
+ add_error(erl_anno:new(ErrorLine), Error, St);
parse_grammar({rule, Rule, Tokens}, St0) ->
NmbrOfDaughters = case Rule of
[_, #symbol{name = '$empty'}] -> 0;
@@ -534,15 +534,15 @@ parse_grammar({rule, Rule, Tokens}, St0) ->
St#yecc{rules_list = [RuleDef | St#yecc.rules_list]};
parse_grammar({prec, Prec}, St) ->
St#yecc{prec = Prec ++ St#yecc.prec};
-parse_grammar({#symbol{}, [{string,Line,String}]}, St) ->
- add_error(Line, {bad_symbol, String}, St);
-parse_grammar({#symbol{line = Line, name = Name}, Symbols}, St) ->
+parse_grammar({#symbol{}, [{string,Anno,String}]}, St) ->
+ add_error(Anno, {bad_symbol, String}, St);
+parse_grammar({#symbol{anno = Anno, name = Name}, Symbols}, St) ->
CF = fun(I) ->
case element(I, St) of
[] ->
setelement(I, St, Symbols);
_ ->
- add_error(Line, {duplicate_declaration, Name}, St)
+ add_error(Anno, {duplicate_declaration, Name}, St)
end
end,
OneSymbol = length(Symbols) =:= 1,
@@ -553,7 +553,7 @@ parse_grammar({#symbol{line = Line, name = Name}, Symbols}, St) ->
'Endsymbol' when OneSymbol -> CF(#yecc.endsymbol);
'Expect' when OneSymbol -> CF(#yecc.expect_shift_reduce);
'States' when OneSymbol -> CF(#yecc.expect_n_states); % undocumented
- _ -> add_warning(Line, bad_declaration, St)
+ _ -> add_warning(Anno, bad_declaration, St)
end.
read_grammar(Inport, St, Line) ->
@@ -599,7 +599,7 @@ precedence(_) -> unknown.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
check_grammar(St0) ->
- Empty = #symbol{line = none, name = '$empty'},
+ Empty = #symbol{anno = none, name = '$empty'},
AllSymbols = St0#yecc.nonterminals ++ St0#yecc.terminals ++ [Empty],
St1 = St0#yecc{all_symbols = AllSymbols},
Cs = [fun check_nonterminals/1, fun check_terminals/1,
@@ -640,12 +640,12 @@ check_rootsymbol(St) ->
case St#yecc.rootsymbol of
[] ->
add_error(rootsymbol_missing, St);
- [#symbol{line = Line, name = SymName}] ->
+ [#symbol{anno = Anno, name = SymName}] ->
case kind_of_symbol(St, SymName) of
nonterminal ->
St#yecc{rootsymbol = SymName};
_ ->
- add_error(Line, {bad_rootsymbol, SymName}, St)
+ add_error(Anno, {bad_rootsymbol, SymName}, St)
end
end.
@@ -653,12 +653,12 @@ check_endsymbol(St) ->
case St#yecc.endsymbol of
[] ->
St#yecc{endsymbol = '$end'};
- [#symbol{line = Line, name = SymName}] ->
+ [#symbol{anno = Anno, name = SymName}] ->
case kind_of_symbol(St, SymName) of
nonterminal ->
- add_error(Line, {endsymbol_is_nonterminal, SymName}, St);
+ add_error(Anno, {endsymbol_is_nonterminal, SymName}, St);
terminal ->
- add_error(Line, {endsymbol_is_terminal, SymName}, St);
+ add_error(Anno, {endsymbol_is_terminal, SymName}, St);
_ ->
St#yecc{endsymbol = SymName}
end
@@ -670,8 +670,8 @@ check_expect(St0) ->
St0#yecc{expect_shift_reduce = 0};
[#symbol{name = Expect}] when is_integer(Expect) ->
St0#yecc{expect_shift_reduce = Expect};
- [#symbol{line = Line, name = Name}] ->
- St1 = add_error(Line, {bad_expect, Name}, St0),
+ [#symbol{anno = Anno, name = Name}] ->
+ St1 = add_error(Anno, {bad_expect, Name}, St0),
St1#yecc{expect_shift_reduce = 0}
end.
@@ -681,27 +681,27 @@ check_states(St) ->
St;
[#symbol{name = NStates}] when is_integer(NStates) ->
St#yecc{expect_n_states = NStates};
- [#symbol{line = Line, name = Name}] ->
- add_error(Line, {bad_states, Name}, St)
+ [#symbol{anno = Anno, name = Name}] ->
+ add_error(Anno, {bad_states, Name}, St)
end.
check_precedences(St0) ->
{St1, _} =
- foldr(fun({#symbol{line = Line, name = Op},_I,_A}, {St,Ps}) ->
+ foldr(fun({#symbol{anno = Anno, name = Op},_I,_A}, {St,Ps}) ->
case member(Op, Ps) of
true ->
- {add_error(Line, {duplicate_precedence,Op}, St),
+ {add_error(Anno, {duplicate_precedence,Op}, St),
Ps};
false ->
{St, [Op | Ps]}
end
end, {St0,[]}, St0#yecc.prec),
- foldl(fun({#symbol{line = Line, name = Op},I,A}, St) ->
+ foldl(fun({#symbol{anno = Anno, name = Op},I,A}, St) ->
case kind_of_symbol(St, Op) of
endsymbol ->
- add_error(Line,{precedence_op_is_endsymbol,Op}, St);
+ add_error(Anno,{precedence_op_is_endsymbol,Op}, St);
unknown ->
- add_error(Line, {precedence_op_is_unknown, Op}, St);
+ add_error(Anno, {precedence_op_is_unknown, Op}, St);
_ ->
St#yecc{prec = [{Op,I,A} | St#yecc.prec]}
end
@@ -709,13 +709,13 @@ check_precedences(St0) ->
check_rule(Rule0, {St0,Rules}) ->
Symbols = Rule0#rule.symbols,
- #symbol{line = HeadLine, name = Head} = hd(Symbols),
+ #symbol{anno = HeadAnno, name = Head} = hd(Symbols),
case member(Head, St0#yecc.nonterminals) of
false ->
- {add_error(HeadLine, {undefined_nonterminal, Head}, St0), Rules};
+ {add_error(HeadAnno, {undefined_nonterminal, Head}, St0), Rules};
true ->
St = check_rhs(tl(Symbols), St0),
- Rule = Rule0#rule{line = HeadLine, symbols = names(Symbols)},
+ Rule = Rule0#rule{anno = HeadAnno, symbols = names(Symbols)},
{St, [Rule | Rules]}
end.
@@ -725,7 +725,7 @@ check_rules(St0) ->
[] ->
add_error(no_grammar_rules, St);
_ ->
- Rule = #rule{line = none,
+ Rule = #rule{anno = none,
symbols = [?ACCEPT, St#yecc.rootsymbol],
tokens = []},
Rules1 = [Rule | Rules0],
@@ -740,9 +740,9 @@ duplicates(List) ->
names(Symbols) ->
map(fun(Symbol) -> Symbol#symbol.name end, Symbols).
-symbol_line(Name, St) ->
- #symbol{line = Line} = symbol_find(Name, St#yecc.all_symbols),
- Line.
+symbol_anno(Name, St) ->
+ #symbol{anno = Anno} = symbol_find(Name, St#yecc.all_symbols),
+ Anno.
symbol_member(Symbol, Symbols) ->
symbol_find(Symbol#symbol.name, Symbols) =/= false.
@@ -894,31 +894,33 @@ report_warnings(St) ->
add_error(E, St) ->
add_error(none, E, St).
-add_error(Line, E, St) ->
- add_error(St#yecc.infile, Line, E, St).
+add_error(Anno, E, St) ->
+ add_error(St#yecc.infile, Anno, E, St).
-add_error(File, Line, E, St) ->
- St#yecc{errors = [{File,{Line,?MODULE,E}}|St#yecc.errors]}.
+add_error(File, Anno, E, St) ->
+ Loc = location(Anno),
+ St#yecc{errors = [{File,{Loc,?MODULE,E}}|St#yecc.errors]}.
add_errors(SymNames, E0, St0) ->
foldl(fun(SymName, St) ->
- add_error(symbol_line(SymName, St), {E0, SymName}, St)
+ add_error(symbol_anno(SymName, St), {E0, SymName}, St)
end, St0, SymNames).
-add_warning(Line, W, St) ->
- St#yecc{warnings = [{St#yecc.infile,{Line,?MODULE,W}}|St#yecc.warnings]}.
+add_warning(Anno, W, St) ->
+ Loc = location(Anno),
+ St#yecc{warnings = [{St#yecc.infile,{Loc,?MODULE,W}}|St#yecc.warnings]}.
add_warnings(SymNames, W0, St0) ->
foldl(fun(SymName, St) ->
- add_warning(symbol_line(SymName, St), {W0, SymName}, St)
+ add_warning(symbol_anno(SymName, St), {W0, SymName}, St)
end, St0, SymNames).
check_rhs([#symbol{name = '$empty'}], St) ->
St;
check_rhs(Rhs, St0) ->
case symbol_find('$empty', Rhs) of
- #symbol{line = Line} ->
- add_error(Line, illegal_empty, St0);
+ #symbol{anno = Anno} ->
+ add_error(Anno, illegal_empty, St0);
false ->
foldl(fun(Sym, St) ->
case symbol_member(Sym, St#yecc.all_symbols) of
@@ -926,13 +928,13 @@ check_rhs(Rhs, St0) ->
St;
false ->
E = {undefined_symbol,Sym#symbol.name},
- add_error(Sym#symbol.line, E, St)
+ add_error(Sym#symbol.anno, E, St)
end
end, St0, Rhs)
end.
check_action(Tokens) ->
- case erl_parse:parse_exprs(add_roberts_dot(Tokens, 0)) of
+ case erl_parse:parse_exprs(add_roberts_dot(Tokens, erl_anno:new(0))) of
{error, _Error} ->
{false, false};
{ok, [Expr | Exprs]} ->
@@ -940,10 +942,10 @@ check_action(Tokens) ->
{IsGuard, true}
end.
-add_roberts_dot([], Line) ->
- [{'dot', Line}];
-add_roberts_dot([{'dot', Line} | _], _) ->
- [{'dot', Line}];
+add_roberts_dot([], Anno) ->
+ [{'dot', Anno}];
+add_roberts_dot([{'dot', Anno} | _], _) ->
+ [{'dot', Anno}];
add_roberts_dot([Token | Tokens], _) ->
[Token | add_roberts_dot(Tokens, element(2, Token))].
@@ -953,21 +955,22 @@ subst_pseudo_vars([H0 | T0], NmbrOfDaughters, St0) ->
{H, St1} = subst_pseudo_vars(H0, NmbrOfDaughters, St0),
{T, St} = subst_pseudo_vars(T0, NmbrOfDaughters, St1),
{[H | T], St};
-subst_pseudo_vars({atom, Line, Atom}, NmbrOfDaughters, St0) ->
+subst_pseudo_vars({atom, Anno, Atom}, NmbrOfDaughters, St0) ->
case atom_to_list(Atom) of
[$$ | Rest] ->
try list_to_integer(Rest) of
N when N > 0, N =< NmbrOfDaughters ->
- {{var, Line, list_to_atom(append("__", Rest))}, St0};
+ {{var, Anno, list_to_atom(append("__", Rest))}, St0};
_ ->
- St = add_error(Line, {undefined_pseudo_variable, Atom},
+ St = add_error(Anno,
+ {undefined_pseudo_variable, Atom},
St0),
- {{atom, Line, '$undefined'}, St}
+ {{atom, Anno, '$undefined'}, St}
catch
- error: _ -> {{atom, Line, Atom}, St0}
+ error: _ -> {{atom, Anno, Atom}, St0}
end;
_ ->
- {{atom, Line, Atom}, St0}
+ {{atom, Anno, Atom}, St0}
end;
subst_pseudo_vars(Tuple, NmbrOfDaughters, St0) when is_tuple(Tuple) ->
{L, St} = subst_pseudo_vars(tuple_to_list(Tuple), NmbrOfDaughters, St0),
@@ -1806,9 +1809,9 @@ report_conflict(Conflict, St, ActionName, How) ->
Formated = format_symbol(ActionName),
case How of
prec ->
- io:fwrite(<<"Resolved in favor of ~s.\n\n">>, [Formated]);
+ io:fwrite(<<"Resolved in favor of ~ts.\n\n">>, [Formated]);
default ->
- io:fwrite(<<"Conflict resolved in favor of ~s.\n\n">>,
+ io:fwrite(<<"Conflict resolved in favor of ~ts.\n\n">>,
[Formated])
end;
true ->
@@ -1853,7 +1856,7 @@ format_conflict({Symbol, N, _, {one_level_up,
{L1, RuleN1, {P1, Ass1}},
{L2, RuleN2, {P2, Ass2}}}}) ->
S1 = io_lib:fwrite(<<"Conflicting precedences of symbols when "
- "scanning ~s in state ~w:\n">>,
+ "scanning ~ts in state ~w:\n">>,
[format_symbol(Symbol), N]),
S2 = io_lib:fwrite(<<" ~s ~w (rule ~w at line ~w)\n"
" vs.\n">>,
@@ -1863,26 +1866,26 @@ format_conflict({Symbol, N, _, {one_level_up,
[S1, S2, S3];
format_conflict({Symbol, N, Reduce, Confl}) ->
S1 = io_lib:fwrite(<<"Parse action conflict scanning symbol "
- "~s in state ~w:\n">>, [format_symbol(Symbol), N]),
+ "~ts in state ~w:\n">>, [format_symbol(Symbol), N]),
S2 = case Reduce of
{[HR | TR], RuleNmbr, RuleLine} ->
- io_lib:fwrite(<<" Reduce to ~s from ~s (rule ~w at "
+ io_lib:fwrite(<<" Reduce to ~ts from ~ts (rule ~w at "
"line ~w)\n vs.\n">>,
[format_symbol(HR), format_symbols(TR),
RuleNmbr, RuleLine])
end,
S3 = case Confl of
{reduce, [HR2|TR2], RuleNmbr2, RuleLine2} ->
- io_lib:fwrite(<<" reduce to ~s from ~s "
+ io_lib:fwrite(<<" reduce to ~ts from ~ts "
"(rule ~w at line ~w).">>,
[format_symbol(HR2), format_symbols(TR2),
RuleNmbr2, RuleLine2]);
{shift, NewState, Sym} ->
io_lib:fwrite(<<" shift to state ~w, adding right "
- "sisters to ~s.">>,
+ "sisters to ~ts.">>,
[NewState, format_symbol(Sym)]);
{accept, Rootsymbol} ->
- io_lib:fwrite(<<" reduce to rootsymbol ~s.">>,
+ io_lib:fwrite(<<" reduce to rootsymbol ~ts.">>,
[format_symbol(Rootsymbol)])
end,
[S1, S2, S3].
@@ -1923,8 +1926,9 @@ format_conflict({Symbol, N, Reduce, Confl}) ->
-define(CODE_VERSION, "1.4").
-define(YECC_BUG(M, A),
- iolist_to_binary([" erlang:error({yecc_bug,\"",?CODE_VERSION,"\",",
- io_lib:fwrite(M, A), "}).\n\n"])).
+ unicode:characters_to_binary(
+ [" erlang:error({yecc_bug,\"",?CODE_VERSION,"\",",
+ io_lib:fwrite(M, A), "}).\n\n"])).
%% Returns number of newlines in included files.
output_prelude(Outport, Inport, St0) when St0#yecc.includefile =:= [] ->
@@ -1977,8 +1981,9 @@ output_header(St0) ->
output_goto(St, [{_Nonterminal, []} | Go], StateInfo) ->
output_goto(St, Go, StateInfo);
output_goto(St0, [{Nonterminal, List} | Go], StateInfo) ->
- F = function_name(yeccgoto, Nonterminal),
- St10 = output_goto1(St0, List, F, StateInfo, true),
+ F = function_name(St0, yeccgoto, Nonterminal),
+ St05 = fwrite(St0, <<"-dialyzer({nowarn_function, ~w/7}).\n">>, [F]),
+ St10 = output_goto1(St05, List, F, StateInfo, true),
St = output_goto_fini(F, Nonterminal, St10),
output_goto(St, Go, StateInfo);
output_goto(St, [], _StateInfo) ->
@@ -2014,7 +2019,8 @@ output_goto_fini(F, NT, #yecc{includefile_version = {1,1}}=St0) ->
St = fwrite(St10, <<"~w(State, _Cat, _Ss, _Stack, _T, _Ts, _Tzr) ->\n">>,
[F]),
fwrite(St,
- ?YECC_BUG(<<"{~w, State, missing_in_goto_table}">>, [NT]),
+ ?YECC_BUG(<<"{~ts, State, missing_in_goto_table}">>,
+ [quoted_atom(St0, NT)]),
[]);
output_goto_fini(_F, _NT, St) ->
fwrite(St, <<".\n\n">>, []).
@@ -2023,7 +2029,7 @@ output_goto_fini(_F, _NT, St) ->
find_user_code(ParseActions, St) ->
[#user_code{state = State,
terminal = Terminal,
- funname = inlined_function_name(State, Terminal),
+ funname = inlined_function_name(St, State, Terminal),
action = Action} ||
{State, La_actions} <- ParseActions,
{Action, Terminals, RuleNmbr, NmbrOfDaughters}
@@ -2144,14 +2150,14 @@ output_action(St, State, Terminal, #reduce{}=Action, IsFirst, SI) ->
output_reduce(St, State, Terminal, Action, IsFirst, SI);
output_action(St0, State, Terminal, #shift{state = NewState}, IsFirst, _SI) ->
St10 = delim(St0, IsFirst),
- St = fwrite(St10, <<"yeccpars2_~w(S, ~s, Ss, Stack, T, Ts, Tzr) ->\n">>,
- [State, quoted_atom(Terminal)]),
+ St = fwrite(St10, <<"yeccpars2_~w(S, ~ts, Ss, Stack, T, Ts, Tzr) ->\n">>,
+ [State, quoted_atom(St10, Terminal)]),
output_call_to_includefile(NewState, St);
output_action(St0, State, Terminal, accept, IsFirst, _SI) ->
St10 = delim(St0, IsFirst),
St = fwrite(St10,
- <<"yeccpars2_~w(_S, ~s, _Ss, Stack, _T, _Ts, _Tzr) ->\n">>,
- [State, quoted_atom(Terminal)]),
+ <<"yeccpars2_~w(_S, ~ts, _Ss, Stack, _T, _Ts, _Tzr) ->\n">>,
+ [State, quoted_atom(St10, Terminal)]),
fwrite(St, <<" {ok, hd(Stack)}">>, []);
output_action(St, _State, _Terminal, nonassoc, _IsFirst, _SI) ->
St.
@@ -2170,19 +2176,19 @@ output_state_actions_fini(State, IsFirst, St0) ->
St = fwrite(St10, <<"yeccpars2_~w(_, _, _, _, T, _, _) ->\n">>, [State]),
fwrite(St, <<" yeccerror(T).\n\n">>, []).
-output_reduce(St0, State, Terminal0,
+output_reduce(St0, State, Terminal,
#reduce{rule_nmbr = RuleNmbr,
head = Head,
nmbr_of_daughters = NmbrOfDaughters},
IsFirst, StateInfo) ->
St10 = delim(St0, IsFirst),
- Terminal = if
- is_atom(Terminal0) -> quoted_atom(Terminal0);
- true -> Terminal0
- end,
+ QuotedTerminal = if
+ is_atom(Terminal) -> quoted_atom(St10, Terminal);
+ true -> Terminal
+ end,
St20 = fwrite(St10,
- <<"yeccpars2_~w(_S, ~s, Ss, Stack, T, Ts, Tzr) ->\n">>,
- [State, Terminal]),
+ <<"yeccpars2_~w(_S, ~ts, Ss, Stack, T, Ts, Tzr) ->\n">>,
+ [State, QuotedTerminal]),
St30 =
if
NmbrOfDaughters < 2 ->
@@ -2201,7 +2207,7 @@ output_reduce(St0, State, Terminal0,
_ ->
NewStack = "NewStack",
fwrite(St30, <<" NewStack = ~w(Stack),\n">>,
- [inlined_function_name(State, Terminal0)])
+ [inlined_function_name(St30, State, Terminal)])
end,
if
NmbrOfDaughters =:= 0 ->
@@ -2217,13 +2223,13 @@ output_reduce(St0, State, Terminal0,
St = fwrite(St40, <<"~s">>, [C]),
%% Short-circuit call to yeccpars2:
fwrite(St,
- <<" yeccpars2_~w(~s, ~s, [~w | Ss], ~s, T, Ts, Tzr)">>,
- [Repr, NextS, Terminal, State, NewStack]);
+ <<" yeccpars2_~w(~s, ~ts, [~w | Ss], ~s, T, Ts, Tzr)">>,
+ [Repr, NextS, QuotedTerminal, State, NewStack]);
true ->
fwrite(St40,
- <<" ~w(hd(~s), ~s, ~s, ~s, T, Ts, Tzr)">>,
- [function_name(yeccgoto, Head), Ns,
- Terminal, Ns, NewStack])
+ <<" ~w(hd(~s), ~ts, ~s, ~s, T, Ts, Tzr)">>,
+ [function_name(St40, yeccgoto, Head), Ns,
+ QuotedTerminal, Ns, NewStack])
end.
delim(St, true) ->
@@ -2231,8 +2237,10 @@ delim(St, true) ->
delim(St, false) ->
fwrite(St, <<";\n">>, []).
-quoted_atom(Atom) ->
- io_lib:fwrite(<<"~w">>, [Atom]).
+quoted_atom(#yecc{encoding = latin1}, Atom) when is_atom(Atom) ->
+ io_lib:write_atom_as_latin1(Atom);
+quoted_atom(_St, Atomic) ->
+ io_lib:write(Atomic).
output_inlined(St, UserCodeActions, Infile) ->
foldl(fun(#user_code{funname = InlinedFunctionName,
@@ -2284,19 +2292,21 @@ output_inlined(St0, FunctionName, Reduce, Infile) ->
fwrite(St, <<" [begin\n ~ts\n end | ~s].\n\n">>,
[pp_tokens(Tokens, Line0, St#yecc.encoding), Stack]).
-inlined_function_name(State, "Cat") ->
- inlined_function_name(State, "");
-inlined_function_name(State, Terminal) ->
- list_to_atom(concat([yeccpars2_, State, '_', Terminal])).
+inlined_function_name(St, State, Terminal) ->
+ End = case Terminal of
+ "Cat" -> [];
+ _ -> [quoted_atom(St, Terminal)]
+ end,
+ list_to_atom(concat([yeccpars2_, State, '_'] ++ End)).
--compile({nowarn_unused_function,function_name/2}).
-function_name(Name, Suf) ->
- list_to_atom(concat([Name, '_' | quoted_atom(Suf)])).
+-compile({nowarn_unused_function,function_name/3}).
+function_name(St, Name, Suf) ->
+ list_to_atom(concat([Name, '_'] ++ [quoted_atom(St, Suf)])).
rule(RulePointer, St) ->
- #rule{n = N, line = Line, symbols = Symbols} =
+ #rule{n = N, anno = Anno, symbols = Symbols} =
dict:fetch(RulePointer, St#yecc.rule_pointer2rule),
- {Symbols, Line, N}.
+ {Symbols, Anno, N}.
get_rule(RuleNmbr, St) ->
dict:fetch(RuleNmbr, St#yecc.rule_pointer2rule).
@@ -2462,7 +2472,7 @@ include(St, File, Outport) ->
include1(eof, _, _, _File, L, _St) ->
L;
include1({error, _}=_Error, _Inport, _Outport, File, L, St) ->
- throw(add_error(File, L, cannot_parse, St));
+ throw(add_error(File, erl_anno:new(L), cannot_parse, St));
include1(Line, Inport, Outport, File, L, St) ->
Incr = case member($\n, Line) of
true -> 1;
@@ -2487,7 +2497,7 @@ includefile_version(Includefile) ->
parse_file(Epp) ->
case epp:parse_erl_form(Epp) of
- {ok, {function,_Line,yeccpars1,7,_Clauses}} ->
+ {ok, {function,_Anno,yeccpars1,7,_Clauses}} ->
{1,4};
{eof,_Line} ->
{1,1};
@@ -2502,7 +2512,7 @@ pp_tokens(Tokens, Line0, Enc) ->
pp_tokens1([], _Line0, _Enc, _T0) ->
[];
pp_tokens1([T | Ts], Line0, Enc, T0) ->
- Line = element(2, T),
+ Line = location(anno(T)),
[pp_sep(Line, Line0, T0), pp_symbol(T, Enc)|pp_tokens1(Ts, Line, Enc, T)].
pp_symbol({var,_,Var}, _Enc) -> Var;
@@ -2537,10 +2547,17 @@ output_file_directive(St, _Filename, _Line) ->
St.
first_line(Tokens) ->
- element(2, hd(Tokens)).
+ location(anno(hd(Tokens))).
last_line(Tokens) ->
- element(2, lists:last(Tokens)).
+ location(anno(lists:last(Tokens))).
+
+location(none) -> none;
+location(Anno) ->
+ erl_anno:line(Anno).
+
+anno(Token) ->
+ element(2, Token).
%% Keep track of the current line in the generated file.
fwrite(#yecc{outport = Outport, line = Line}=St, Format, Args) ->
@@ -2580,18 +2597,18 @@ format_symbol(Symbol) ->
String = concat([Symbol]),
case erl_scan:string(String) of
{ok, [{atom, _, _}], _} ->
- io_lib:fwrite(<<"~w">>, [Symbol]);
+ io_lib:fwrite(<<"~tw">>, [Symbol]);
{ok, [{Word, _}], _} when Word =/= ':', Word =/= '->' ->
case erl_scan:reserved_word(Word) of
true ->
String;
false ->
- io_lib:fwrite(<<"~w">>, [Symbol])
+ io_lib:fwrite(<<"~tw">>, [Symbol])
end;
{ok, [{var, _, _}], _} ->
String;
_ ->
- io_lib:fwrite(<<"~w">>, [Symbol])
+ io_lib:fwrite(<<"~tw">>, [Symbol])
end.
inverse(L) ->
diff --git a/lib/parsetools/src/yeccgramm.yrl b/lib/parsetools/src/yeccgramm.yrl
index c7b2ef6a86..40aa85a43e 100644
--- a/lib/parsetools/src/yeccgramm.yrl
+++ b/lib/parsetools/src/yeccgramm.yrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -39,43 +39,38 @@ rule -> head '->' symbols attached_code dot: {rule, ['$1' | '$3'], '$4'}.
head -> symbol : '$1'.
symbols -> symbol : ['$1'].
symbols -> symbol symbols : ['$1' | '$2'].
-strings -> string : [string('$1')].
-strings -> string strings : [string('$1') | '$2'].
+strings -> string : ['$1'].
+strings -> string strings : ['$1' | '$2'].
attached_code -> ':' tokens : {erlang_code, '$2'}.
-attached_code -> '$empty' : {erlang_code, [{atom, 0, '$undefined'}]}.
+attached_code -> '$empty' : {erlang_code,
+ [{atom, erl_anno:new(0), '$undefined'}]}.
tokens -> token : ['$1'].
tokens -> token tokens : ['$1' | '$2'].
symbol -> var : symbol('$1').
symbol -> atom : symbol('$1').
symbol -> integer : symbol('$1').
symbol -> reserved_word : symbol('$1').
-token -> var : token('$1').
-token -> atom : token('$1').
-token -> float : token('$1').
-token -> integer : token('$1').
-token -> string : token('$1').
-token -> char : token('$1').
-token -> reserved_symbol : {value_of('$1'), line_of('$1')}.
-token -> reserved_word : {value_of('$1'), line_of('$1')}.
-token -> '->' : {'->', line_of('$1')}. % Have to be treated in this
-token -> ':' : {':', line_of('$1')}. % manner, because they are also
- % special symbols of the metagrammar
+token -> var : '$1'.
+token -> atom : '$1'.
+token -> float : '$1'.
+token -> integer : '$1'.
+token -> string : '$1'.
+token -> char : '$1'.
+token -> reserved_symbol : {value_of('$1'), anno_of('$1')}.
+token -> reserved_word : {value_of('$1'), anno_of('$1')}.
+token -> '->' : {'->', anno_of('$1')}. % Have to be treated in this
+token -> ':' : {':', anno_of('$1')}. % manner, because they are also
+ % special symbols of the metagrammar
Erlang code.
--record(symbol, {line, name}).
+-record(symbol, {anno, name}).
symbol(Symbol) ->
- #symbol{line = line_of(Symbol), name = value_of(Symbol)}.
-
-token(Token) ->
- setelement(2, Token, line_of(Token)).
-
-string(Token) ->
- setelement(2, Token, line_of(Token)).
+ #symbol{anno = anno_of(Symbol), name = value_of(Symbol)}.
value_of(Token) ->
element(3, Token).
-line_of(Token) ->
- erl_anno:line(element(2, Token)).
+anno_of(Token) ->
+ element(2, Token).
diff --git a/lib/parsetools/src/yeccparser.erl b/lib/parsetools/src/yeccparser.erl
index 0025284ccf..6f6f66d56c 100644
--- a/lib/parsetools/src/yeccparser.erl
+++ b/lib/parsetools/src/yeccparser.erl
@@ -1,29 +1,23 @@
-module(yeccparser).
-export([parse/1, parse_and_scan/1, format_error/1]).
--file("yeccgramm.yrl", 63).
+-file("yeccgramm.yrl", 65).
--record(symbol, {line, name}).
+-record(symbol, {anno, name}).
symbol(Symbol) ->
- #symbol{line = line_of(Symbol), name = value_of(Symbol)}.
-
-token(Token) ->
- setelement(2, Token, line_of(Token)).
-
-string(Token) ->
- setelement(2, Token, line_of(Token)).
+ #symbol{anno = anno_of(Symbol), name = value_of(Symbol)}.
value_of(Token) ->
element(3, Token).
-line_of(Token) ->
- erl_anno:line(element(2, Token)).
+anno_of(Token) ->
+ element(2, Token).
--file("lib/parsetools/include/yeccpre.hrl", 0).
+-file("/ldisk/hasse/otp/lib/parsetools/include/yeccpre.hrl", 0).
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -147,21 +141,10 @@ yecc_end(Line) ->
{'$end', Line}.
yecctoken_end_location(Token) ->
- try
- Str = erl_scan:text(Token),
- Line = erl_scan:line(Token),
- Parts = re:split(Str, "\n"),
- Dline = length(Parts) - 1,
- Yline = Line + Dline,
- case erl_scan:column(Token) of
- Column when is_integer(Column) ->
- Col = byte_size(lists:last(Parts)),
- {Yline, Col + if Dline =:= 0 -> Column; true -> 1 end};
- undefined ->
- Yline
- end
- catch _:_ ->
- yecctoken_location(Token)
+ try erl_anno:end_location(element(2, Token)) of
+ undefined -> yecctoken_location(Token);
+ Loc -> Loc
+ catch _:_ -> yecctoken_location(Token)
end.
-compile({nowarn_unused_function, yeccerror/1}).
@@ -172,15 +155,15 @@ yeccerror(Token) ->
-compile({nowarn_unused_function, yecctoken_to_string/1}).
yecctoken_to_string(Token) ->
- case catch erl_scan:text(Token) of
- Txt when is_list(Txt) -> Txt;
- _ -> yecctoken2string(Token)
+ try erl_scan:text(Token) of
+ undefined -> yecctoken2string(Token);
+ Txt -> Txt
+ catch _:_ -> yecctoken2string(Token)
end.
yecctoken_location(Token) ->
- case catch erl_scan:location(Token) of
- Loc when Loc =/= undefined -> Loc;
- _ -> element(2, Token)
+ try erl_scan:location(Token)
+ catch _:_ -> element(2, Token)
end.
-compile({nowarn_unused_function, yecctoken2string/1}).
@@ -204,8 +187,9 @@ yecctoken2string(Other) ->
--file("yeccgramm.erl", 207).
+-file("yeccgramm.erl", 190).
+-dialyzer({nowarn_function, yeccpars2/7}).
yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(1=S, Cat, Ss, Stack, T, Ts, Tzr) ->
@@ -281,6 +265,7 @@ yeccpars2(35=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2(Other, _, _, _, _, _, _) ->
erlang:error({yecc_bug,"1.4",{missing_state_in_action_table, Other}}).
+-dialyzer({nowarn_function, yeccpars2_0/7}).
yeccpars2_0(S, atom, Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 6, Ss, Stack, T, Ts, Tzr);
yeccpars2_0(S, integer, Ss, Stack, T, Ts, Tzr) ->
@@ -308,11 +293,13 @@ yeccpars2_1(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_2(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_grammar(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccpars2_3/7}).
yeccpars2_3(S, '->', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr);
yeccpars2_3(_, _, _, _, T, _, _) ->
yeccerror(T).
+-dialyzer({nowarn_function, yeccpars2_4/7}).
yeccpars2_4(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) ->
{ok, hd(Stack)};
yeccpars2_4(_, _, _, _, T, _, _) ->
@@ -362,11 +349,13 @@ yeccpars2_13(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_13_(Stack),
yeccgoto_symbols(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccpars2_14/7}).
yeccpars2_14(S, dot, Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 29, Ss, Stack, T, Ts, Tzr);
yeccpars2_14(_, _, _, _, T, _, _) ->
yeccerror(T).
+-dialyzer({nowarn_function, yeccpars2_15/7}).
yeccpars2_15(S, '->', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 18, Ss, Stack, T, Ts, Tzr);
yeccpars2_15(S, ':', Ss, Stack, T, Ts, Tzr) ->
@@ -428,20 +417,16 @@ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_20(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_20_(Stack),
- yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_21_(Stack),
- yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_22_(Stack),
- yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_23_(Stack),
- yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_24_(Stack),
@@ -452,12 +437,10 @@ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_26_(Stack),
- yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_27(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_27_(Stack),
- yeccgoto_token(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_token(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_28(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -469,11 +452,13 @@ yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_29_(Stack),
yeccgoto_rule(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccpars2_30/7}).
yeccpars2_30(S, dot, Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr);
yeccpars2_30(_, _, _, _, T, _, _) ->
yeccerror(T).
+-dialyzer({nowarn_function, yeccpars2_31/7}).
yeccpars2_31(S, dot, Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
yeccpars2_31(_, _, _, _, T, _, _) ->
@@ -500,26 +485,33 @@ yeccpars2_35(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_35_(Stack),
yeccgoto_declaration(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccgoto_attached_code/7}).
yeccgoto_attached_code(11, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_14(14, Cat, Ss, Stack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccgoto_declaration/7}).
yeccgoto_declaration(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccgoto_grammar/7}).
yeccgoto_grammar(0, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_4(4, Cat, Ss, Stack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccgoto_head/7}).
yeccgoto_head(0, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_3(3, Cat, Ss, Stack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccgoto_rule/7}).
yeccgoto_rule(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_2(_S, Cat, Ss, Stack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccgoto_strings/7}).
yeccgoto_strings(1, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_31(31, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_strings(32=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccgoto_symbol/7}).
yeccgoto_symbol(0, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_1(1, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_symbol(1, Cat, Ss, Stack, T, Ts, Tzr) ->
@@ -529,6 +521,7 @@ yeccgoto_symbol(10, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_symbol(12, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_12(12, Cat, Ss, Stack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccgoto_symbols/7}).
yeccgoto_symbols(1, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_symbols(10, Cat, Ss, Stack, T, Ts, Tzr) ->
@@ -536,18 +529,20 @@ yeccgoto_symbols(10, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_symbols(12=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_13(_S, Cat, Ss, Stack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccgoto_token/7}).
yeccgoto_token(15, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_token(17, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr).
+-dialyzer({nowarn_function, yeccgoto_tokens/7}).
yeccgoto_tokens(15=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_tokens(17=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_28(_S, Cat, Ss, Stack, T, Ts, Tzr).
-compile({inline,yeccpars2_6_/1}).
--file("yeccgramm.yrl", 44).
+-file("yeccgramm.yrl", 46).
yeccpars2_6_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
@@ -555,7 +550,7 @@ yeccpars2_6_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_7_/1}).
--file("yeccgramm.yrl", 45).
+-file("yeccgramm.yrl", 47).
yeccpars2_7_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
@@ -563,7 +558,7 @@ yeccpars2_7_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_8_/1}).
--file("yeccgramm.yrl", 46).
+-file("yeccgramm.yrl", 48).
yeccpars2_8_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
@@ -571,7 +566,7 @@ yeccpars2_8_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_9_/1}).
--file("yeccgramm.yrl", 43).
+-file("yeccgramm.yrl", 45).
yeccpars2_9_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
@@ -579,14 +574,15 @@ yeccpars2_9_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_11_/1}).
--file("yeccgramm.yrl", 40).
+-file("yeccgramm.yrl", 41).
yeccpars2_11_(__Stack0) ->
[begin
- { erlang_code , [ { atom , 0 , '$undefined' } ] }
+ { erlang_code ,
+ [ { atom , erl_anno : new ( 0 ) , '$undefined' } ] }
end | __Stack0].
-compile({inline,yeccpars2_12_/1}).
--file("yeccgramm.yrl", 35).
+-file("yeccgramm.yrl", 36).
yeccpars2_12_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
@@ -594,7 +590,7 @@ yeccpars2_12_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_13_/1}).
--file("yeccgramm.yrl", 36).
+-file("yeccgramm.yrl", 37).
yeccpars2_13_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
@@ -602,7 +598,7 @@ yeccpars2_13_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_16_/1}).
--file("yeccgramm.yrl", 39).
+-file("yeccgramm.yrl", 40).
yeccpars2_16_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
@@ -610,7 +606,7 @@ yeccpars2_16_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_17_/1}).
--file("yeccgramm.yrl", 41).
+-file("yeccgramm.yrl", 43).
yeccpars2_17_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
@@ -618,87 +614,39 @@ yeccpars2_17_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_18_/1}).
--file("yeccgramm.yrl", 55).
+-file("yeccgramm.yrl", 57).
yeccpars2_18_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
- { '->' , line_of ( __1 ) }
+ { '->' , anno_of ( __1 ) }
end | __Stack].
-compile({inline,yeccpars2_19_/1}).
--file("yeccgramm.yrl", 56).
+-file("yeccgramm.yrl", 58).
yeccpars2_19_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
- { ':' , line_of ( __1 ) }
- end | __Stack].
-
--compile({inline,yeccpars2_20_/1}).
--file("yeccgramm.yrl", 48).
-yeccpars2_20_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
- [begin
- token ( __1 )
- end | __Stack].
-
--compile({inline,yeccpars2_21_/1}).
--file("yeccgramm.yrl", 52).
-yeccpars2_21_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
- [begin
- token ( __1 )
- end | __Stack].
-
--compile({inline,yeccpars2_22_/1}).
--file("yeccgramm.yrl", 49).
-yeccpars2_22_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
- [begin
- token ( __1 )
- end | __Stack].
-
--compile({inline,yeccpars2_23_/1}).
--file("yeccgramm.yrl", 50).
-yeccpars2_23_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
- [begin
- token ( __1 )
+ { ':' , anno_of ( __1 ) }
end | __Stack].
-compile({inline,yeccpars2_24_/1}).
--file("yeccgramm.yrl", 53).
+-file("yeccgramm.yrl", 55).
yeccpars2_24_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
- { value_of ( __1 ) , line_of ( __1 ) }
+ { value_of ( __1 ) , anno_of ( __1 ) }
end | __Stack].
-compile({inline,yeccpars2_25_/1}).
--file("yeccgramm.yrl", 54).
+-file("yeccgramm.yrl", 56).
yeccpars2_25_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
- { value_of ( __1 ) , line_of ( __1 ) }
- end | __Stack].
-
--compile({inline,yeccpars2_26_/1}).
--file("yeccgramm.yrl", 51).
-yeccpars2_26_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
- [begin
- token ( __1 )
- end | __Stack].
-
--compile({inline,yeccpars2_27_/1}).
--file("yeccgramm.yrl", 47).
-yeccpars2_27_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
- [begin
- token ( __1 )
+ { value_of ( __1 ) , anno_of ( __1 ) }
end | __Stack].
-compile({inline,yeccpars2_28_/1}).
--file("yeccgramm.yrl", 42).
+-file("yeccgramm.yrl", 44).
yeccpars2_28_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
@@ -706,7 +654,7 @@ yeccpars2_28_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_29_/1}).
--file("yeccgramm.yrl", 33).
+-file("yeccgramm.yrl", 34).
yeccpars2_29_(__Stack0) ->
[__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
@@ -714,23 +662,23 @@ yeccpars2_29_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_32_/1}).
--file("yeccgramm.yrl", 37).
+-file("yeccgramm.yrl", 38).
yeccpars2_32_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
- [ string ( __1 ) ]
+ [ __1 ]
end | __Stack].
-compile({inline,yeccpars2_33_/1}).
--file("yeccgramm.yrl", 38).
+-file("yeccgramm.yrl", 39).
yeccpars2_33_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
- [ string ( __1 ) | __2 ]
+ [ __1 | __2 ]
end | __Stack].
-compile({inline,yeccpars2_34_/1}).
--file("yeccgramm.yrl", 32).
+-file("yeccgramm.yrl", 33).
yeccpars2_34_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
@@ -738,7 +686,7 @@ yeccpars2_34_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_35_/1}).
--file("yeccgramm.yrl", 31).
+-file("yeccgramm.yrl", 32).
yeccpars2_35_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
@@ -746,4 +694,4 @@ yeccpars2_35_(__Stack0) ->
end | __Stack].
--file("yeccgramm.yrl", 82).
+-file("yeccgramm.yrl", 77).
diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl
index 949ef3c36e..3f5d9fee3e 100644
--- a/lib/parsetools/test/leex_SUITE.erl
+++ b/lib/parsetools/test/leex_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -45,7 +45,7 @@
pt/1, man/1, ex/1, ex2/1, not_yet/1,
line_wrap/1,
- otp_10302/1, otp_11286/1, unicode/1]).
+ otp_10302/1, otp_11286/1, unicode/1, otp_13916/1, otp_14285/1]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -62,12 +62,12 @@ end_per_testcase(_Case, Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [{group, checks}, {group, examples}, {group, bugs}].
+ [{group, checks}, {group, examples}, {group, tickets}, {group, bugs}].
groups() ->
[{checks, [], [file, compile, syntax]},
{examples, [], [pt, man, ex, ex2, not_yet, unicode]},
- {tickets, [], [otp_10302, otp_11286]},
+ {tickets, [], [otp_10302, otp_11286, otp_13916, otp_14285]},
{bugs, [], [line_wrap]}].
init_per_suite(Config) ->
@@ -408,12 +408,12 @@ unicode(Config) when is_list(Config) ->
Ts = [{unicode_1,
<<"%% -*- coding: utf-8 -*-\n"
"Definitions.\n"
- "RTLarrow = (←)\n"
+ "RTLarrow = (←)\n"
"Rules.\n"
- "{RTLarrow} : {token,{'<-',TokenLine}}.\n"
+ "{RTLarrow} : {token,{\"←\",TokenLine}}.\n"
"Erlang code.\n"
"-export([t/0]).\n"
- "t() -> {ok, [{'<-', 1}], 1} = string(\"←\"), ok.">>,
+ "t() -> {ok, [{\"←\", 1}], 1} = string(\"←\"), ok.">>,
default,
ok}],
@@ -1052,7 +1052,7 @@ otp_11286(Config) when is_list(Config) ->
Dir = ?privdir,
UName = [1024] ++ "u",
UDir = filename:join(Dir, UName),
- ok = rpc:call(Node, file, make_dir, [UDir]),
+ _ = rpc:call(Node, file, make_dir, [UDir]),
%% Note: Cannot use UName as filename since the filename is used
%% as module name. To be fixed in R18.
@@ -1095,6 +1095,81 @@ otp_11286(Config) when is_list(Config) ->
true = test_server:stop_node(Node),
ok.
+otp_13916(doc) ->
+ "OTP-13916. Leex rules with newlines result in bad line numbers";
+otp_13916(suite) -> [];
+otp_13916(Config) when is_list(Config) ->
+ Ts = [{otp_13916_1,
+ <<"Definitions.\n"
+ "W = [a-zA-Z0-9]\n"
+ "S = [\\s\\t]\n"
+ "B = [\\n\\r]\n"
+ "Rules.\n"
+ "%% mark line break(s) and empty lines by token 'break'\n"
+ "%% in order to use as delimiters\n"
+ "{B}({S}*{B})+ : {token, {break, TokenLine}}.\n"
+ "{B} : {token, {break, TokenLine}}.\n"
+ "{S}+ : {token, {blank, TokenLine, TokenChars}}.\n"
+ "{W}+ : {token, {word, TokenLine, TokenChars}}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,[{break,1},{blank,4,\" \"},{word,4,\"breaks\"}],4} =\n"
+ " string(\"\\n\\n \\n breaks\"),\n"
+ " {ok,[{break,1},{word,4,\"works\"}],4} =\n"
+ " string(\"\\n\\n \\nworks\"),\n"
+ " {ok,[{break,1},{word,4,\"L4\"},{break,4},\n"
+ " {word,5,\"L5\"},{break,5},{word,7,\"L7\"}], 7} =\n"
+ " string(\"\\n\\n \\nL4\\nL5\\n\\nL7\"),\n"
+ " {ok,[{break,1},{blank,4,\" \"},{word,4,\"L4\"},\n"
+ " {break,4},{blank,5,\" \"},{word,5,\"L5\"},\n"
+ " {break,5},{blank,7,\" \"},{word,7,\"L7\"}], 7} =\n"
+ " string(\"\\n\\n \\n L4\\n L5\\n\\n L7\"),\n"
+ " ok.\n">>,
+ default,
+ ok}],
+ ?line run(Config, Ts),
+ ok.
+
+otp_14285(Config) ->
+ Dir = ?privdir,
+ Filename = filename:join(Dir, "file.xrl"),
+
+ Ts = [{otp_14285_1,
+ <<"%% encoding: latin-1\n"
+ "Definitions.\n"
+ "A = a\n"
+ "Z = z\n"
+ "L = [{A}-{Z}]\n"
+ "U = [\\x{400}]\n"
+ "Rules.\n"
+ "{L}+ : {token,l}.\n"
+ "{U}+ : {token,'\\x{400}'}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,['\\x{400}'],1} = string(\"\\x{400}\"), ok.\n">>,
+ default,
+ ok},
+ {otp_14285_2,
+ <<"%% encoding: UTF-8\n"
+ "Definitions.\n"
+ "A = a\n"
+ "Z = z\n"
+ "L = [{A}-{Z}]\n"
+ "U = [\x{400}]\n"
+ "Rules.\n"
+ "{L}+ : {token,l}.\n"
+ "{U}+ : {token,'\x{400}'}.\n"
+ "Erlang code.\n"
+ "-export([t/0]).\n"
+ "t() ->\n"
+ " {ok,['\x{400}'],1} = string(\"\x{400}\"), ok.\n">>,
+ default,
+ ok}],
+ run(Config, Ts),
+ ok.
+
start_node(Name, Args) ->
[_,Host] = string:tokens(atom_to_list(node()), "@"),
ct:log("Trying to start ~w@~s~n", [Name,Host]),
@@ -1137,7 +1212,7 @@ run_test(Config, Def, Pre) ->
XrlFile = filename:join(DataDir, DefFile),
ErlFile = filename:join(DataDir, Filename),
Opts = [return, warn_unused_vars,{outdir,DataDir}],
- ok = file:write_file(XrlFile, Def, [{encoding, unicode}]),
+ ok = file:write_file(XrlFile, Def),
LOpts = [return, {report, false} |
case Pre of
default ->
diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl
index 3710569aba..a7166b91ed 100644
--- a/lib/parsetools/test/yecc_SUITE.erl
+++ b/lib/parsetools/test/yecc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -50,7 +50,7 @@
otp_5369/1, otp_6362/1, otp_7945/1, otp_8483/1, otp_8486/1,
otp_7292/1, otp_7969/1, otp_8919/1, otp_10302/1, otp_11269/1,
- otp_11286/1]).
+ otp_11286/1, otp_14285/1]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -78,7 +78,7 @@ groups() ->
{bugs, [],
[otp_5369, otp_6362, otp_7945, otp_8483, otp_8486]},
{improvements, [], [otp_7292, otp_7969, otp_8919, otp_10302,
- otp_11269, otp_11286]}].
+ otp_11269, otp_11286, otp_14285]}].
init_per_suite(Config) ->
Config.
@@ -342,7 +342,7 @@ syntax(Config) when is_list(Config) ->
{L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
[]} = compile:file(Parserfile1, [basic_validation,return]),
?line L1 = 31 + SzYeccPre,
- ?line L2 = 38 + SzYeccPre
+ ?line L2 = 39 + SzYeccPre
end(),
%% Bad macro in action. OTP-7224.
@@ -360,7 +360,7 @@ syntax(Config) when is_list(Config) ->
{L2,_,{bad_inline,{yeccpars2_2_,1}}}]}],
[]} = compile:file(Parserfile1, [basic_validation,return]),
?line L1 = 31 + SzYeccPre,
- ?line L2 = 38 + SzYeccPre
+ ?line L2 = 39 + SzYeccPre
end(),
%% Check line numbers. OTP-7224.
@@ -1524,7 +1524,7 @@ otp_7945(suite) -> [];
otp_7945(Config) when is_list(Config) ->
A2 = erl_anno:new(2),
A3 = erl_anno:new(3),
- {error,_} = erl_parse:parse([{atom,3,foo},{'.',A2,9,9}]),
+ {error,_} = erl_parse:parse([{atom,A3,foo},{'.',A2,9,9}]),
ok.
otp_8483(doc) ->
@@ -1623,7 +1623,7 @@ otp_7292(Config) when is_list(Config) ->
[{_,[{16,_,{unused_function,{foo,0}}}]}]} =
compile:file(Parserfile1, [basic_validation, return]),
L1 = 41 + SzYeccPre,
- L2 = 48 + SzYeccPre
+ L2 = 49 + SzYeccPre
end(),
YeccPre = filename:join(Dir, "yeccpre.hrl"),
@@ -1641,7 +1641,7 @@ otp_7292(Config) when is_list(Config) ->
[{_,[{16,_,{unused_function,{foo,0}}}]}]} =
compile:file(Parserfile1, [basic_validation, return]),
?line L1 = 40 + SzYeccPre,
- ?line L2 = 47 + SzYeccPre
+ ?line L2 = 48 + SzYeccPre
end(),
file:delete(YeccPre),
@@ -2009,7 +2009,7 @@ otp_11286(Config) when is_list(Config) ->
Dir = ?privdir,
UName = [1024] ++ "u",
UDir = filename:join(Dir, UName),
- ok = rpc:call(Node, file, make_dir, [UDir]),
+ _ = rpc:call(Node, file, make_dir, [UDir]),
%% Note: Cannot use UName as filename since the filename is used
%% as module name. To be fixed in R18.
@@ -2048,6 +2048,90 @@ otp_11286(Config) when is_list(Config) ->
true = test_server:stop_node(Node),
ok.
+otp_14285(Config) ->
+ Dir = ?privdir,
+ YeccPre = filename:join(Dir, "yeccpre.hrl"),
+ ?line ok = file:write_file(YeccPre,
+ [<<"-export([t/0]).\n">>,my_yeccpre()]),
+
+ T0 = <<"
+ Nonterminals '\\x{400}'.
+ Terminals t.
+ Rootsymbol '\\x{400}'.
+ '\\x{400}' -> t : '$1'.
+ Erlang code.
+ t() ->
+ L = [{t, 1}],
+ {ok, R} = parse(L),
+ {t, 1} = R,
+ ok.">>,
+ Ts0 = [{otp_14285_1,
+ [<<"%% coding: Latin-1\n">>,T0],YeccPre,ok},
+ {otp_14285_2,
+ [<<"%% coding: coding: UTF-8\n">>,T0],YeccPre,ok}],
+ run(Config, Ts0),
+ file:delete(YeccPre),
+
+ T1 = <<"
+ Nonterminals '1\\x{400}' list 'unused\\x{400}'.
+ Terminals '2\\x{400}'.
+ Rootsymbol '1\\x{400}'.
+
+ '1\\x{400}' -> list : '$1'.
+
+ list -> '2\\x{400}' : '$1'.
+ list -> list '2\\x{400}' : {foo,'\\x{400}'}.
+
+ Erlang code.
+
+ -export([t/0]).
+
+ t() ->
+ L = [{'2\\x{400}', 1}, {'2\\x{400}',2}],
+ {ok, R} = parse(L),
+ {foo,A} = R,
+ '\\x{400}' = A,
+ [1024] = atom_to_list(A),
+ ok.">>,
+
+ Ts1 = [{otp_14285_3,
+ [<<"%% coding: Latin-1\n">>,T1],default,ok},
+ {otp_14285_4,
+ [<<"%% coding: UTF-8\n">>,T1],default,ok}],
+ run(Config, Ts1),
+
+ T2 = <<"
+ Nonterminals E.
+ Terminals '-' '+' '=' id.
+ Rootsymbol E.
+ Endsymbol '\\x{400}'.
+
+ 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},
+ {'\\x{400}',1}]),
+ ok.">>,
+
+ Ts2 = [{otp_14285_5,
+ [<<"%% coding: Latin-1\n">>,T2],default,ok},
+ {otp_14285_6,
+ [<<"%% coding: UTF-8\n">>,T2],default,ok}],
+ run(Config, Ts2),
+
+ ok.
+
start_node(Name, Args) ->
[_,Host] = string:tokens(atom_to_list(node()), "@"),
ct:log("Trying to start ~w@~s~n", [Name,Host]),
diff --git a/lib/parsetools/vsn.mk b/lib/parsetools/vsn.mk
index befdd82d6e..502ca00a47 100644
--- a/lib/parsetools/vsn.mk
+++ b/lib/parsetools/vsn.mk
@@ -1 +1 @@
-PARSETOOLS_VSN = 2.1.2
+PARSETOOLS_VSN = 2.1.5
diff --git a/lib/percept/AUTHORS b/lib/percept/AUTHORS
deleted file mode 100644
index f6c040ae76..0000000000
--- a/lib/percept/AUTHORS
+++ /dev/null
@@ -1,4 +0,0 @@
-Original Authors and Contributors:
-
-Bj�rn-Egil Dahlberg
-Magnus Tho�ng
diff --git a/lib/percept/Makefile b/lib/percept/Makefile
deleted file mode 100644
index 1f51bd2fef..0000000000
--- a/lib/percept/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2007-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-
-# ----------------------------------------------------
-# Common Macros
-# ----------------------------------------------------
-
-SUB_DIRECTORIES = src priv doc/src
-
-SPECIAL_TARGETS =
-
-# ----------------------------------------------------
-# Default Subdir Targets
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_subdir.mk
diff --git a/lib/percept/c_src/.gitignore b/lib/percept/c_src/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/percept/c_src/.gitignore
+++ /dev/null
diff --git a/lib/percept/doc/html/.gitignore b/lib/percept/doc/html/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/percept/doc/html/.gitignore
+++ /dev/null
diff --git a/lib/percept/doc/man3/.gitignore b/lib/percept/doc/man3/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/percept/doc/man3/.gitignore
+++ /dev/null
diff --git a/lib/percept/doc/pdf/.gitignore b/lib/percept/doc/pdf/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/percept/doc/pdf/.gitignore
+++ /dev/null
diff --git a/lib/percept/doc/src/Makefile b/lib/percept/doc/src/Makefile
deleted file mode 100644
index 2f84d61cbc..0000000000
--- a/lib/percept/doc/src/Makefile
+++ /dev/null
@@ -1,190 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2007-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include ../../vsn.mk
-VSN=$(PERCEPT_VSN)
-APPLICATION=percept
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
-
-# ----------------------------------------------------
-# Help application directory specification
-# ----------------------------------------------------
-
-EDOC_DIR = $(ERL_TOP)/lib/edoc
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-PERCEPT_DIR = $(ERL_TOP)/lib/$(APPLICATION)/src
-RUNTIME_TOOLS_DIR = $(ERL_TOP)/lib/runtime_tools/src
-
-PERCEPT_MODULES = \
- egd\
- percept
-
-RUNTIME_TOOLS_MODULES = \
- percept_profile
-
-XML_APPLICATION_FILES = \
- ref_man.xml
-
-PERCEPT_XML_FILES = $(PERCEPT_MODULES:=.xml)
-
-RUNTIME_TOOLS_XML_FILES = $(RUNTIME_TOOLS_MODULES:=.xml)
-
-MODULE_XML_FILES = $(PERCEPT_XML_FILES) $(RUNTIME_TOOLS_XML_FILES)
-
-XML_REF_MAN = \
- ref_man.xml
-
-XML_REF3_FILES = $(MODULE_XML_FILES)
-
-XML_PART_FILES = \
- part.xml \
- part_notes.xml
-
-XML_REF6_FILES =
-
-XML_CHAPTER_FILES = \
- notes.xml \
- egd_ug.xml \
- percept_ug.xml
-
-GEN_XML = \
- egd_ug.xml \
- percept_ug.xml
-
-BOOK_FILES = book.xml
-
-XML_FILES = \
- $(BOOK_FILES) $(XML_CHAPTER_FILES) \
- $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_REF_MAN)
-
-HTML_EXAMPLE_FILES = \
- percept_examples.html
-
-HTML_STYLESHEET_FILES = \
- ../stylesheet.css
-
-
-GIF_FILES = \
- test1.gif \
- test2.gif \
- test3.gif \
- test4.gif \
- percept_overview.gif \
- percept_processes.gif \
- percept_processinfo.gif \
- percept_compare.gif \
- img_esi_result.gif
-
-# ----------------------------------------------------
-INFO_FILE = ../../info
-
-HTML_FILES = \
- $(XML_REF_MAN:%.xml=$(HTMLDIR)/%.html) \
- $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
-
-MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3)
-MAN6_FILES = $(XML_REF6_FILES:%_app.xml=$(MAN6DIR)/%.6)
-
-
-HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
-
-TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
-
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-XML_FLAGS +=
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-$(HTMLDIR)/%.gif: %.gif
- $(INSTALL_DATA) $< $@
-
-docs: pdf html man
-
-$(TOP_PDF_FILE): $(XML_FILES)
-
-pdf: $(TOP_PDF_FILE)
-
-html: gifs $(HTML_REF_MAN_FILE)
-
-clean clean_docs:
- rm -f $(MODULE_XML_FILES) $(GEN_XML)
- rm -rf $(HTMLDIR)/*
- rm -f $(MAN3DIR)/*
- rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
- rm -f errs core *~
-
-man: $(MAN3_FILES) $(MAN6_FILES)
-
-gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
-
-xml: $(MODULE_XML_FILES)
-
-$(PERCEPT_XML_FILES):
- escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(PERCEPT_DIR)/$(@:%.xml=%.erl)
-
-$(RUNTIME_TOOLS_XML_FILES):
- escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(RUNTIME_TOOLS_DIR)/$(@:%.xml=%.erl)
-
-info:
- @echo "XML_PART_FILES: $(XML_PART_FILES)"
- @echo "XML_APPLICATION_FILES: $(XML_APPLICATION_FILES)"
- @echo "PERCEPT_XML_FILES: $(MODULE_XML_FILES)"
- @echo "PERCEPT_MODULES: $(PERCEPT_MODULES)"
- @echo "HTML_FILES: $(HTML_FILES)"
- @echo "HTMLDIR: $(HTMLDIR)"
-
-
-debug opt:
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-release_docs_spec: docs
- $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf"
- $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf"
- $(INSTALL_DIR) "$(RELSYSDIR)/doc/html"
- $(INSTALL_DATA) $(HTML_EXAMPLE_FILES) $(HTML_STYLESHEET_FILES) \
- $(HTMLDIR)/* \
- "$(RELSYSDIR)/doc/html"
- $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)"
- $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3"
- $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3"
-
-release_spec:
-
diff --git a/lib/percept/doc/src/book.xml b/lib/percept/doc/src/book.xml
deleted file mode 100644
index 5acba1f214..0000000000
--- a/lib/percept/doc/src/book.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE book SYSTEM "book.dtd">
-
-<book xmlns:xi="http://www.w3.org/2001/XInclude">
- <header titlestyle="normal">
- <copyright>
- <year>2007</year>
- <year>2016</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Percept</title>
- <prepared>Björn-Egil Dahlberg</prepared>
- <docno></docno>
- <date>2007-11-02</date>
- <rev>0.5.0</rev>
- <file>book.xml</file>
- </header>
- <insidecover>
- </insidecover>
- <pagetext>Percept</pagetext>
- <preamble>
- <contents level="2"></contents>
- </preamble>
- <parts lift="no">
- <xi:include href="part.xml"/>
- </parts>
- <applications>
- <xi:include href="ref_man.xml"/>
- </applications>
- <releasenotes>
- <xi:include href="notes.xml"/>
- </releasenotes>
- <listofterms></listofterms>
- <index></index>
-</book>
-
diff --git a/lib/percept/doc/src/egd_ug.xmlsrc b/lib/percept/doc/src/egd_ug.xmlsrc
deleted file mode 100644
index 85d41ada79..0000000000
--- a/lib/percept/doc/src/egd_ug.xmlsrc
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2007</year>
- <year>2016</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>egd</title>
- <prepared>Björn-Egil Dahlberg</prepared>
- <docno></docno>
- <date>2007-11-03</date>
- <rev>A</rev>
- <file>egd_ug.xml</file>
- </header>
- <section>
- <title>Introduction</title>
- <p>
- The egd module is an interface for 2d-image rendering and is used by
- Percept to generate dynamic graphs to its web pages. All code is pure
- erlang, no drivers needed.
- </p>
- <p>
- The library is intended for small to medium image sizes with low
- complexity for optimal performance. The library handles horizontal
- lines better then vertical lines.
- </p>
- <p>
- The foremost purpose for this module is to enable users to
- generate images from erlang code and/or datasets and to
- send these images to either files or web servers.
- </p>
- </section>
- <section>
- <title>File example</title>
- <p>Drawing examples:</p>
- <codeinclude file="img.erl" tag="" type="none"></codeinclude>
- <p> First save. </p>
- <image file="test1.gif">
- <icaption>test1.png</icaption>
- </image>
-
- <p> Second save. </p>
- <image file="test2.gif">
- <icaption>test2.png</icaption>
- </image>
-
- <p> Third save. </p>
- <image file="test3.gif">
- <icaption>test3.png</icaption>
- </image>
-
- <p> Fourth save. </p>
- <image file="test4.gif">
- <icaption>test4.png</icaption>
- </image>
- </section>
- <section>
- <title>ESI example</title>
- <p>Using egd with inets ESI to generate images on the fly:</p>
- <codeinclude file="img_esi.erl" tag="" type="none"></codeinclude>
- <image file="img_esi_result.gif">
- <icaption>Example of result.</icaption>
- </image>
- <p>
- For more information regarding ESI, please see inets application
- <seealso marker="inets:mod_esi">mod_esi</seealso>.
- </p>
- </section>
-</chapter>
-
-
diff --git a/lib/percept/doc/src/fascicules.xml b/lib/percept/doc/src/fascicules.xml
deleted file mode 100644
index 37feca543f..0000000000
--- a/lib/percept/doc/src/fascicules.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
-
-<fascicules>
- <fascicule file="part" href="part_frame.html" entry="no">
- User's Guide
- </fascicule>
- <fascicule file="ref_man" href="ref_man_frame.html" entry="yes">
- Reference Manual
- </fascicule>
- <fascicule file="part_notes" href="part_notes_frame.html" entry="no">
- Release Notes
- </fascicule>
- <fascicule file="" href="../../../../doc/print.html" entry="no">
- Off-Print
- </fascicule>
-</fascicules>
-
diff --git a/lib/percept/doc/src/img.erl b/lib/percept/doc/src/img.erl
deleted file mode 100644
index 8f3bd3839f..0000000000
--- a/lib/percept/doc/src/img.erl
+++ /dev/null
@@ -1,50 +0,0 @@
--module(img).
-
--export([do/0]).
-
-do() ->
- Im = egd:create(200,200),
- Red = egd:color({255,0,0}),
- Green = egd:color({0,255,0}),
- Blue = egd:color({0,0,255}),
- Black = egd:color({0,0,0}),
- Yellow = egd:color({255,255,0}),
-
- % Line and fillRectangle
-
- egd:filledRectangle(Im, {20,20}, {180,180}, Red),
- egd:line(Im, {0,0}, {200,200}, Black),
-
- egd:save(egd:render(Im, png), "/home/egil/test1.png"),
-
- egd:filledEllipse(Im, {45, 60}, {55, 70}, Yellow),
- egd:filledEllipse(Im, {145, 60}, {155, 70}, Blue),
-
- egd:save(egd:render(Im, png), "/home/egil/test2.png"),
-
- R = 80,
- X0 = 99,
- Y0 = 99,
-
- Pts = [ { X0 + trunc(R*math:cos(A*math:pi()*2/360)),
- Y0 + trunc(R*math:sin(A*math:pi()*2/360))
- } || A <- lists:seq(0,359,5)],
- lists:map(
- fun({X,Y}) ->
- egd:rectangle(Im, {X-5, Y-5}, {X+5,Y+5}, Green)
- end, Pts),
-
- egd:save(egd:render(Im, png), "/home/egil/test3.png"),
-
- % Text
- Filename = filename:join([code:priv_dir(percept), "fonts", "6x11_latin1.wingsfont"]),
- Font = egd_font:load(Filename),
- {W,H} = egd_font:size(Font),
- String = "egd says hello",
- Length = length(String),
-
- egd:text(Im, {round(100 - W*Length/2), 200 - H - 5}, Font, String, Black),
-
- egd:save(egd:render(Im, png), "/home/egil/test4.png"),
-
- egd:destroy(Im).
diff --git a/lib/percept/doc/src/img_esi.erl b/lib/percept/doc/src/img_esi.erl
deleted file mode 100644
index e9796819c0..0000000000
--- a/lib/percept/doc/src/img_esi.erl
+++ /dev/null
@@ -1,25 +0,0 @@
--module(img_esi).
-
--export([image/3]).
-
-image(SessionID, _Env, _Input) ->
- mod_esi:deliver(SessionID, header()),
- Binary = my_image(),
- mod_esi:deliver(SessionID, binary_to_list(Binary)).
-
-my_image() ->
- Im = egd:create(300,20),
- Black = egd:color({0,0,0}),
- Red = egd:color({255,0,0}),
- egd:filledRectangle(Im, {30,14}, {270,19}, Red),
- egd:rectangle(Im, {30,14}, {270,19}, Black),
-
- Filename = filename:join([code:priv_dir(percept), "fonts", "6x11_latin1.wingsfont"]),
- Font = egd_font:load(Filename),
- egd:text(Im, {30, 0}, Font, "egd with esi callback", Black),
- Bin = egd:render(Im, png),
- egd:destroy(Im),
- Bin.
-
-header() ->
- "Content-Type: image/png\r\n\r\n".
diff --git a/lib/percept/doc/src/img_esi_result.gif b/lib/percept/doc/src/img_esi_result.gif
deleted file mode 100644
index 6973392998..0000000000
--- a/lib/percept/doc/src/img_esi_result.gif
+++ /dev/null
Binary files differ
diff --git a/lib/percept/doc/src/ipc_tree.erl b/lib/percept/doc/src/ipc_tree.erl
deleted file mode 100644
index 89360379c6..0000000000
--- a/lib/percept/doc/src/ipc_tree.erl
+++ /dev/null
@@ -1,30 +0,0 @@
--module(ipc_tree).
--export([go/1, init/2]).
-
-go(N) ->
- start(N, self()),
- receive {_,stop} -> ok end.
-
-start(Depth, ParentPid) ->
- spawn(?MODULE, init, [Depth, ParentPid]).
-
-init(0, ParentPid) ->
- workload(5000),
- ParentPid ! {self(),stop},
- ok;
-init(Depth, ParentPid) ->
- Pid1 = spawn(?MODULE, init, [Depth - 1, self()]),
- Pid2 = spawn(?MODULE, init, [Depth - 1, self()]),
- main([Pid1,Pid2], ParentPid).
-
-main(Pids, ParentPid) ->
- workload(5000),
- gather(Pids),
- ParentPid ! {self(),stop},
- ok.
-
-gather([]) -> ok;
-gather([Pid|Pids]) -> receive {Pid,stop} -> gather(Pids) end.
-
-workload(0) -> ok;
-workload(N) -> math:sin(2), workload(N - 1).
diff --git a/lib/percept/doc/src/notes.xml b/lib/percept/doc/src/notes.xml
deleted file mode 100644
index c9d5d3ae29..0000000000
--- a/lib/percept/doc/src/notes.xml
+++ /dev/null
@@ -1,495 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2007</year>
- <year>2016</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Percept Release Notes</title>
- <prepared>otp_appnotes</prepared>
- <docno>nil</docno>
- <date>nil</date>
- <rev>nil</rev>
- <file>notes.xml</file>
- </header>
- <p>This document describes the changes made to the Percept application.</p>
-
-<section><title>Percept 0.9</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Remove deprecated <c>erlang:now/0</c> calls</p>
- <p>
- Own Id: OTP-13422</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Improve line implementation</p>
- <p>
- Add capabilities for line thickness and anti-aliasing.</p>
- <p>
- Own Id: OTP-13598</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.11</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fix http server configuration</p>
- <p>
- Own Id: OTP-12662</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.10</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Make sure to install .hrl files when needed</p>
- <p>
- Own Id: OTP-12197</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.9</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Application upgrade (appup) files are corrected for the
- following applications: </p>
- <p>
- <c>asn1, common_test, compiler, crypto, debugger,
- dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe,
- inets, observer, odbc, os_mon, otp_mibs, parsetools,
- percept, public_key, reltool, runtime_tools, ssh,
- syntax_tools, test_server, tools, typer, webtool, wx,
- xmerl</c></p>
- <p>
- A new test utility for testing appup files is added to
- test_server. This is now used by most applications in
- OTP.</p>
- <p>
- (Thanks to Tobias Schlager)</p>
- <p>
- Own Id: OTP-11744</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.8.2</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- The encoding of the <c>notes.xml</c> file has been
- changed from latin1 to utf-8 to avoid future merge
- problems.</p>
- <p>
- Own Id: OTP-11310</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.8.1</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p> Postscript files no longer needed for the generation
- of PDF files have been removed. </p>
- <p>
- Own Id: OTP-11016</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.8</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Misc build updates</p>
- <p>
- Own Id: OTP-10784</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.7</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Add missing modules in app-file</p>
- <p>
- Own Id: OTP-10439</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.6.1</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Miscellaneous documentation build updates</p>
- <p>
- Own Id: OTP-9813</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.6</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fix message handling in select requests</p>
- <p>
- percept_db used to send results in untagged messages, and
- use a non selective receive to extract them. When percept
- is used from the shell process, this can confuse other
- messages with the actual result.</p>
- <p>
- Add a tag to the message to be {result, Result}. Add
- demonitor to avoid keeping DOWN message in the queue fix
- one spec in do_start/0</p>
- <p>
- (Thanks to Ahmed Omar)</p>
- <p>
- Own Id: OTP-9490</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.5</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p> Fixes a race condition found in percept_db start/1
- function. (Thanks to Ahmed Omar) </p>
- <p>
- Own Id: OTP-9012</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.4</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fix egd_render transparent to use float constants.</p>
- <p>
- The render engine has float guards to enhance beam code
- generation. However, the default case used integers which
- caused the engine to crash. This is now fixed.</p>
- <p>
- Own Id: OTP-8425</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>The documentation is now possible to build in an open
- source environment after a number of bugs are fixed and
- some features are added in the documentation build
- process. </p>
- <p>- The arity calculation is updated.</p>
- <p>- The module prefix used in the function names for
- bif's are removed in the generated links so the links
- will look like
- "http://www.erlang.org/doc/man/erlang.html#append_element-2"
- instead of
- "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p>
- <p>- Enhanced the menu positioning in the html
- documentation when a new page is loaded.</p>
- <p>- A number of corrections in the generation of man
- pages (thanks to Sergei Golovan)</p>
- <p>- The legal notice is taken from the xml book file so
- OTP's build process can be used for non OTP
- applications.</p>
- <p>
- Own Id: OTP-8343</p>
- </item>
- <item>
- <p>
- Cleanups suggested by tidier and modernization of types
- and specs.</p>
- <p>
- Own Id: OTP-8455</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.3</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- The documentation is now built with open source tools
- (xsltproc and fop) that exists on most platforms. One
- visible change is that the frames are removed.</p>
- <p>
- Own Id: OTP-8201</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.2</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Extensions to <c>egd:color/1</c> for using atoms as color
- definition in addition to rgb triplets.</p>
- <p>
- Own Id: OTP-7975</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.8.1</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p><c>egd</c> now supports encapsulated postscript output
- format.</p>
- <p>
- Own Id: OTP-7923</p>
- </item>
- </list>
- </section>
-
-</section>
-
- <section><title>Percept 0.8</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>A problem with options list to percept causing some
- options to be disregarded unintentionally. This has now
- been fixed.</p> <p>An error in <c>percept_analyzer</c>
- caused calculation of standard deviation to be incorrect.
- This has now been corrected.</p>
- <p>
- Own Id: OTP-7693</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>Updated css for percept server for enhanced
- viewing.</p> <p>Increased performance of egd render.</p>
- <p>Several graph errors could occur when compacting data
- to decrease graph rendering time causing incorrect
- scalability numbers. These errors have now been
- fixed.</p> <p>Increased viewing width for graphs. The
- viewing width is now dependent on client screen
- resolution.</p>
- <p>
- Own Id: OTP-7696</p>
- </item>
- </list>
- </section>
-
-</section>
-<section><title>Percept 0.7.3</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>External pids caused the webserver to crash. This has
- now been fixed.</p>
- <p>
- Own Id: OTP-7515 Aux Id: seq11004 </p>
- </item>
- <item>
- <p>Fixed a timestamp problem where some events could be
- sent out of order. Minor fixes to presentation of
- data.</p>
- <p>
- Own Id: OTP-7544 Aux Id: otp-7442 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>Performance enhancement for the egd render engine
- (Thanks to Magnus Thoäng).</p>
- <p>
- Own Id: OTP-7616</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.7.2</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>Calling <c>egd:destroy/1</c> did not properly remove
- the process holding the image.</p>
- <p>Synchronous calls done via the egd interface could
- erroneous receive messages not intended for egd. Messages
- are now tagged in such a way so this should not
- occur.</p>
- <p>
- Own Id: OTP-7336</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.7.1</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Fixed out of bounds rendering problem in egd which could
- cause the rendering process to crash.</p>
- <p>
- Own Id: OTP-7215</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.7</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>Percept no longer depends on external c-libraries. The
- graphical rendering is now done via erlang code.</p>
- <p>
- Own Id: OTP-7162</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>Percept 0.6.2</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- A new module, percept_profile, can now be used to collect
- profiling data even if the percept application is not
- installed. This should help profiling erlang application
- on target machines without libgd installed.</p>
- <p>
- Own Id: OTP-7126</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section>
- <title>Percept 0.5.0</title>
- <section><title>First Release</title>
- <list>
- <item>
- <p>
- First Release.
- </p>
- <p>Own Id: OTP-6783</p>
- </item>
- </list>
- </section>
- </section>
-</chapter>
-
diff --git a/lib/percept/doc/src/part.xml b/lib/percept/doc/src/part.xml
deleted file mode 100644
index 277d89d45c..0000000000
--- a/lib/percept/doc/src/part.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>2007</year>
- <year>2016</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Percept User's Guide</title>
- <prepared>Björn-Egil Dahlberg</prepared>
- <docno></docno>
- <date>2007-11-02</date>
- <rev>0.5.0</rev>
- <file>part.xml</file>
- </header>
- <description>
- <p>
- <em>Percept</em> is an acronym for <em>P</em>ercept - <em>er</em>lang
- <em>c</em>oncurr<em>e</em>ncy <em>p</em>rofiling <em>t</em>ool.
- </p>
- <p>
- It is a tool to visualize application level concurrency and
- identify concurrency bottlenecks.
- </p>
- </description>
- <xi:include href="percept_ug.xml"/>
- <xi:include href="egd_ug.xml"/>
-</part>
-
diff --git a/lib/percept/doc/src/part_notes.xml b/lib/percept/doc/src/part_notes.xml
deleted file mode 100644
index f428b4fd81..0000000000
--- a/lib/percept/doc/src/part_notes.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>2007</year>
- <year>2016</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Percept Release Notes</title>
- <prepared>Björn-Egil Dahlberg</prepared>
- <docno></docno>
- <date>>2007-11-02</date>
- <rev></rev>
- <file>part_notes.xml</file>
- </header>
- <description>
- <p>
- The <em>Percept</em> application.
- </p>
- </description>
- <xi:include href="notes.xml"/>
-</part>
-
diff --git a/lib/percept/doc/src/percept_compare.gif b/lib/percept/doc/src/percept_compare.gif
deleted file mode 100644
index 1c8ccf0186..0000000000
--- a/lib/percept/doc/src/percept_compare.gif
+++ /dev/null
Binary files differ
diff --git a/lib/percept/doc/src/percept_examples.html b/lib/percept/doc/src/percept_examples.html
deleted file mode 100644
index df2f52bdfd..0000000000
--- a/lib/percept/doc/src/percept_examples.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<meta http-equiv="Context-Type" content="text/html; charset=iso-8859-1">
-<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
-<html xmlns="http://www.w3.org/1999/xhtml" ><head>
-<title>Customization functions</title>
-<link rel="stylesheet" type="text/css" href="stylesheet.css">
-</head>
-<body>
-<h1>Customization functions</h1>
-</body>
-</html>
diff --git a/lib/percept/doc/src/percept_overview.gif b/lib/percept/doc/src/percept_overview.gif
deleted file mode 100644
index 12ac172472..0000000000
--- a/lib/percept/doc/src/percept_overview.gif
+++ /dev/null
Binary files differ
diff --git a/lib/percept/doc/src/percept_processes.gif b/lib/percept/doc/src/percept_processes.gif
deleted file mode 100644
index 640ff50ee2..0000000000
--- a/lib/percept/doc/src/percept_processes.gif
+++ /dev/null
Binary files differ
diff --git a/lib/percept/doc/src/percept_processinfo.gif b/lib/percept/doc/src/percept_processinfo.gif
deleted file mode 100644
index 00cc05f5c9..0000000000
--- a/lib/percept/doc/src/percept_processinfo.gif
+++ /dev/null
Binary files differ
diff --git a/lib/percept/doc/src/percept_ug.xmlsrc b/lib/percept/doc/src/percept_ug.xmlsrc
deleted file mode 100644
index 0d243cdabe..0000000000
--- a/lib/percept/doc/src/percept_ug.xmlsrc
+++ /dev/null
@@ -1,223 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2007</year>
- <year>2016</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Percept</title>
- <prepared>Björn-Egil Dahlberg</prepared>
- <docno></docno>
- <date>2007-11-02</date>
- <rev>A</rev>
- <file>percept_ug.xml</file>
- </header>
- <p>
- Percept, or Percept - Erlang Concurrency Profiling Tool, utilizes trace
- informations and profiler events to form a picture of the processes's and
- ports runnability.
- </p>
-
- <section>
- <title>Introduction</title>
- <p>
- Percept uses <c>erlang:trace/3</c> and <c>erlang:system_profile/2</c> to monitor events from
- process states. Such states are,</p>
- <list>
- <item>waiting</item>
- <item>running</item>
- <item>runnable</item>
- <item>free</item>
- <item>exiting</item>
- </list>
- <p>
- There are some other states too, <c>suspended</c>, <c>hibernating</c>, and
- garbage collecting (<c>gc</c>). The only ignored state is <c>gc</c> and a process is considered to have
- its previous state through out the entire garbage collecting phase. The main reason for this, is that our
- model considers the <c>gc</c> as a third state neither active nor inactive.
- </p>
- <p>
- A waiting or suspended process is considered an inactive process and a running or
- runnable process is considered an active process.
- </p>
- <p>
- Events are collected and stored to a file. The file can be moved and
- analyzed on a different machine than the target machine.
- </p>
- <p>
- Note, even if percept is not installed on your target machine, profiling
- can still be done via the module <seealso marker="percept_profile">percept_profile</seealso>
- located in runtime_tools.
- </p>
- </section>
- <section>
- <title>Getting started</title>
- <section>
- <title>Profiling</title>
- <p>
- There are a few ways to start the profiling of a specific code. The
- command <c>percept:profile/3</c> is a preferred way.
- </p>
- <p>
- The command takes a filename for the data destination file as first
- argument, a callback entry-point as second argument and a
- list of specific profiler options, for instance <c>procs</c>, as third
- argument.
- </p>
- <p>
- Let's say we have a module called example that initializes our
- profiling-test and let it run under some defined manner designed by ourself.
- The module needs a start function, let's call it go and it takes zero arguments.
- The start arguments would look like:
- </p>
- <p><c>percept:profile("test.dat", {test, go, []}, [procs]).</c></p>
- <p>
- For a semi-real example we start a tree of processes that does sorting
- of random numbers. In our model below we use a controller process that
- distributes work to different client processes.
- </p>
- <codeinclude file="sorter.erl" tag="" type="none"></codeinclude>
- <p>We can now start our test using percept:</p>
- <pre>
-Erlang (BEAM) emulator version 5.6 [async-threads:0] [kernel-poll:false]
-
-Eshell V5.6 (abort with ^G)
-1> percept:profile("test.dat", {sorter, go, [5, 2000, 15]}, [procs]).
-Starting profiling.
-ok
- </pre>
- <p>
- Percept sets up the trace and profiling facilities to listen for process
- specific events. It then stores these events to the <c>test.dat</c>
- file. The profiling will go on for the whole duration until
- <c>sorter:go/3</c> returns and the profiling has concluded.
- </p>
- </section>
- <section>
- <title>Data viewing</title>
- <p>
- To analyze this file, use <c>percept:analyze("test.dat")</c>. We can do
- this on any machine with Percept installed. The command will parse the
- data file and insert all events in a RAM database, <c>percept_db</c>. The
- initial command will only prompt how many processes were involved in the
- profile.
- </p>
- <pre>
-2> percept:analyze("test.dat").
-Parsing: "test.dat"
-Parsed 428 entries in 3.81310e-2 s.
- 17 created processes.
- 0 opened ports.
-ok
- </pre>
- <p>
- To view the data we start the web-server using
- <c>percept:start_webserver/1</c>. The command will return the hostname
- and the a port where we should direct our favorite web browser.
- </p>
- <pre>
-3> percept:start_webserver(8888).
-{started,"durin",8888}
-4>
- </pre>
- <section>
- <title>Overview selection</title>
- <p>
- Now we can view our data. The database has its content from
- <c>percept:analyze/1</c> command and the webserver is started.
- </p>
- <p>
- When we click on the <c>overview</c> button in the menu percept will
- generate a graph of the concurrency and send it to our web browser. In this
- view we get no details but rather the big picture. We can see if
- our processes behave in an inefficient manner. Dips in the graph represents
- low concurrency in the erlang system.
- </p>
- <p>
- We can zoom in on different areas of the graph either using the mouse
- to select an area or by specifying min and max ranges in the edit boxes.
- </p>
- <note>
- <p>Measured time is presented in seconds if nothing else is stated.</p>
- </note>
- <image file="percept_overview.gif">
- <icaption>Overview selection</icaption>
- </image>
- </section>
- <section>
- <title>Processes selection</title>
- <p>
- To get a more detailed description we can select the process view by
- clicking the <c>processes</c> button in the menu.
- </p>
- <p>
- The table shows process id's that are click-able and direct you to
- the process information page, a lifetime bar that presents a rough estimate
- in green color about when the process was alive during profiling, an
- entry-point, its registered name if it had one and the process's
- parent id.
- </p>
- <p>
- We can select which processes we want to compare and then hit the
- <c>compare</c> button on the top right of the screen.
- </p>
- <image file="percept_processes.gif">
- <icaption>Processes selection</icaption>
- </image>
- </section>
- <section>
- <title>Compare selection</title>
- <p>
- The activity bar under the concurrency graph shows each process's
- runnability. The color green shows when a process is active (which is
- running or runnable) and the white color represents time when a
- process is inactive (waiting in a receive or is suspended).
- </p>
- <p>
- To inspect a certain process click on the process id button, this will
- direct you to a process information page for that specific process.
- </p>
- <image file="percept_compare.gif">
- <icaption>Processes compare selection</icaption>
- </image>
- </section>
- <section>
- <title>Process information selection</title>
- <p>
- Here we can some general information for the process. Parent and
- children processes, spawn and exit times, entry-point and start arguments.
- </p>
- <p>
- We can also see the process' inactive times. How many times it has
- been waiting, statistical information and most importantly in which
- function.
- </p>
- <p>
- The time percentages presented in process information are of time spent in waiting, not total run time.
- </p>
- <image file="percept_processinfo.gif">
- <icaption>Process information selection</icaption>
- </image>
- </section>
- </section>
- </section>
-</chapter>
diff --git a/lib/percept/doc/src/ref_man.xml b/lib/percept/doc/src/ref_man.xml
deleted file mode 100644
index 143312489b..0000000000
--- a/lib/percept/doc/src/ref_man.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE application SYSTEM "application.dtd">
-
-<application xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>2007</year>
- <year>2016</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Percept Reference Manual</title>
- <prepared>Edoc</prepared>
- <docno></docno>
- <date>2007-11-02</date>
- <rev>1.0</rev>
- <file>ref_man.xml</file>
- </header>
- <description>
- <p>
- <em>Percept</em> is an acronym for <em>P</em>ercept - <em>er</em>lang
- <em>c</em>oncurr<em>e</em>ncy <em>p</em>rofiling <em>t</em>ool.
- </p>
- <p>
- It is a tool to visualize application level concurrency and
- identify concurrency bottlenecks.
- </p>
- </description>
- <xi:include href="egd.xml"/>
- <xi:include href="percept.xml"/>
- <xi:include href="percept_profile.xml"/>
-</application>
-
diff --git a/lib/percept/doc/src/sorter.erl b/lib/percept/doc/src/sorter.erl
deleted file mode 100644
index 8d5f2c715c..0000000000
--- a/lib/percept/doc/src/sorter.erl
+++ /dev/null
@@ -1,41 +0,0 @@
--module(sorter).
--export([go/3,loop/0,main/4]).
-
-go(I,N,M) ->
- spawn(?MODULE, main, [I,N,M,self()]),
- receive done -> ok end.
-
-main(I,N,M,Parent) ->
- Pids = lists:foldl(
- fun(_,Ps) ->
- [ spawn(?MODULE,loop, []) | Ps]
- end, [], lists:seq(1,M)),
-
- lists:foreach(
- fun(_) ->
- send_work(N,Pids),
- gather(Pids)
- end, lists:seq(1,I)),
-
- lists:foreach(
- fun(Pid) ->
- Pid ! {self(), quit}
- end, Pids),
-
- gather(Pids), Parent ! done.
-
-send_work(_,[]) -> ok;
-send_work(N,[Pid|Pids]) ->
- Pid ! {self(),sort,N},
- send_work(round(N*1.2),Pids).
-
-loop() ->
- receive
- {Pid, sort, N} -> dummy_sort(N),Pid ! {self(), done},loop();
- {Pid, quit} -> Pid ! {self(), done}
- end.
-
-dummy_sort(N) -> lists:sort([ random:uniform(N) || _ <- lists:seq(1,N)]).
-
-gather([]) -> ok;
-gather([Pid|Pids]) -> receive {Pid, done} -> gather(Pids) end.
diff --git a/lib/percept/doc/src/test1.gif b/lib/percept/doc/src/test1.gif
deleted file mode 100644
index 70a519d8e3..0000000000
--- a/lib/percept/doc/src/test1.gif
+++ /dev/null
Binary files differ
diff --git a/lib/percept/doc/src/test2.gif b/lib/percept/doc/src/test2.gif
deleted file mode 100644
index f18e1f9e58..0000000000
--- a/lib/percept/doc/src/test2.gif
+++ /dev/null
Binary files differ
diff --git a/lib/percept/doc/src/test3.gif b/lib/percept/doc/src/test3.gif
deleted file mode 100644
index c7581f19aa..0000000000
--- a/lib/percept/doc/src/test3.gif
+++ /dev/null
Binary files differ
diff --git a/lib/percept/doc/src/test4.gif b/lib/percept/doc/src/test4.gif
deleted file mode 100644
index e7d52c08a3..0000000000
--- a/lib/percept/doc/src/test4.gif
+++ /dev/null
Binary files differ
diff --git a/lib/percept/doc/stylesheet.css b/lib/percept/doc/stylesheet.css
deleted file mode 100644
index 24d8a02145..0000000000
--- a/lib/percept/doc/stylesheet.css
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2007-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-BODY {color: #000000;
- background-color: #ffffff;
- margin-left: .4in}
-H1 {margin-left: -.4in}
-H2 {margin-left: -.4in}
-H3 {margin-left: -.2in}
-.logo{float:right;}
-.toc UL {
- list-style-type: none;
- border: solid;
- border-width: thin;
- padding-left: 10px;
- padding-right: 10px;
- padding-top: 5px;
- padding-bottom: 5px;
- background: #f0f0f0;
- letter-spacing: 2px;
- line-height: 20px;
-}
diff --git a/lib/percept/ebin/.gitignore b/lib/percept/ebin/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/percept/ebin/.gitignore
+++ /dev/null
diff --git a/lib/percept/include/.gitignore b/lib/percept/include/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/percept/include/.gitignore
+++ /dev/null
diff --git a/lib/percept/info b/lib/percept/info
deleted file mode 100644
index 07d58d28ae..0000000000
--- a/lib/percept/info
+++ /dev/null
@@ -1,2 +0,0 @@
-group: tools
-short: A concurrency profiler tool.
diff --git a/lib/percept/priv/Makefile b/lib/percept/priv/Makefile
deleted file mode 100644
index a1912edfc0..0000000000
--- a/lib/percept/priv/Makefile
+++ /dev/null
@@ -1,97 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2007-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include ../vsn.mk
-VSN=$(PERCEPT_VSN)
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/percept-$(VSN)
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-CONF_FILES = \
- server_root/conf/mime.types
-
-HTDOCS_FILES = \
- server_root/htdocs/index.html
-
-IMAGE_FILES = \
- server_root/images/nav.png \
- server_root/images/white.png
-
-SCRIPT_FILES = \
- server_root/scripts/percept_area_select.js \
- server_root/scripts/percept_error_handler.js \
- server_root/scripts/percept_select_all.js
-
-CSS_FILES = \
- server_root/css/percept.css
-
-FONT_FILES = \
- fonts/6x11_latin1.wingsfont
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-ERL_COMPILE_FLAGS +=
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-debug opt:
-
-clean:
-
-docs:
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-release_spec: opt
- # Finished
- $(INSTALL_DIR) "$(RELSYSDIR)/priv/logs"
- $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root"
- $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root/htdocs"
- $(INSTALL_DATA) $(HTDOCS_FILES) "$(RELSYSDIR)/priv/server_root/htdocs"
- $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root/conf"
- $(INSTALL_DATA) $(CONF_FILES) "$(RELSYSDIR)/priv/server_root/conf"
- $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root/scripts"
- $(INSTALL_DATA) $(SCRIPT_FILES) "$(RELSYSDIR)/priv/server_root/scripts"
- $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root/css"
- $(INSTALL_DATA) $(CSS_FILES) "$(RELSYSDIR)/priv/server_root/css"
- $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root/images"
- $(INSTALL_DATA) $(IMAGE_FILES) "$(RELSYSDIR)/priv/server_root/images"
- $(INSTALL_DIR) "$(RELSYSDIR)/priv/fonts"
- $(INSTALL_DATA) $(FONT_FILES) "$(RELSYSDIR)/priv/fonts"
-
-release_docs_spec:
-
diff --git a/lib/percept/priv/fonts/6x11_latin1.wingsfont b/lib/percept/priv/fonts/6x11_latin1.wingsfont
deleted file mode 100644
index d1e1c42eef..0000000000
--- a/lib/percept/priv/fonts/6x11_latin1.wingsfont
+++ /dev/null
Binary files differ
diff --git a/lib/percept/priv/logs/.gitignore b/lib/percept/priv/logs/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/percept/priv/logs/.gitignore
+++ /dev/null
diff --git a/lib/percept/priv/obj/.gitignore b/lib/percept/priv/obj/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/percept/priv/obj/.gitignore
+++ /dev/null
diff --git a/lib/percept/priv/server_root/cgi-bin/.gitignore b/lib/percept/priv/server_root/cgi-bin/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/percept/priv/server_root/cgi-bin/.gitignore
+++ /dev/null
diff --git a/lib/percept/priv/server_root/conf/mime.types b/lib/percept/priv/server_root/conf/mime.types
deleted file mode 100644
index 6245efdbd9..0000000000
--- a/lib/percept/priv/server_root/conf/mime.types
+++ /dev/null
@@ -1,462 +0,0 @@
-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/percept/priv/server_root/css/percept.css b/lib/percept/priv/server_root/css/percept.css
deleted file mode 100644
index 2d0734b6b6..0000000000
--- a/lib/percept/priv/server_root/css/percept.css
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2007-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-/* Globals */
-html, body {
- margin: 0;
- padding: 0;
- font: 12px Verdana;
- background: #7a83a2;
-}
-
-table {
- border-collapse: collapse;
- /*width: 100%;*/
-}
-
-tr.even {
- background-color: #ffffff; color: black;
-}
-
-tr.odd {
- background-color: #def2ef; color: black;
-}
-
-td {
- text-valign: top;
- text-align: right;
- font: 14px Verdana;
-}
-
-th {
- letter-spacing: 2px;
- text-align: right;
- padding: 4px 4px 4px 8px;
-}
-
-a {
- color: yellow;
- text-decoration: none;
-}
-
-a:hover {
- text-decoration: underline;
-}
-
-td a {
- color: #101010;
-}
-
-img {
- border: 0;
-}
-
-
-/* Header and footer stuff */
-
-#header {
- font: bold 24px Verdana;
- padding-left: 156px;
- padding-right: 156px;
- padding-top: 10px;
- padding-bottom: 10px;
- height: 74px;
- text-align: right;
- background: #7a83a2;
-}
-
-#footer {
- font: 12px Verdana;
- position: relative;
- padding: 5px;
- border-top: 1px solid black;
- clear:left;
-}
-
-
-/* Content stuff */
-
-#content {
- background: #fefefe;
- position: relative;
- padding: 5px 25px 5px 25px;
- margin: 0px 60px 0px 60px;
- border-top: 1px solid #383a32;
- border-left: 1px solid #383a32;
- border-right: 1px solid #383a32;
- border-bottom: 1px solid #383a32;
-}
-
-.table_header {
- font-decoration: underline;
- width: 100%;
-}
-
-/* Menu */
-
-#menu {
- margin: 0px 60px 0px 60px;
- height: 30px;
- padding-right: 0px;
- background-image: url('../images/nav.png');
- background-repeat: repeat-x;
- padding-top: 0px;
- border-top: 1px solid #383a32;
- border-left: 1px solid #383a32;
- border-right: 1px solid #383a32;
-}
-
-.menu_tabs {
- overflow: hidden;
-}
-
-.menu_tabs ul {
- margin: 0;
- padding: 0;
- font: bold 12px Verdana;
- list-style-type: none;
-}
-
-.menu_tabs li {
- display: inline;
- margin: 0;
- background-repeat: repeat-x;
-}
-
-.menu_tabs li a {
- float: right;
- display: block;
- text-decoration: none;
- margin: 0;
- padding: 8px; 7px 8px; 3px;
- border-left: 1px solid #777487;
-}
-
-.menu_tabs li a:visited {
- color: black;
-}
-
-.menu_tabs li a:hover {
- background: #cae8ea;
-}
-
-.menu_tabs li a:selected .menu_tabs li a:active {
- background: yellow;
-}
diff --git a/lib/percept/priv/server_root/htdocs/index.html b/lib/percept/priv/server_root/htdocs/index.html
deleted file mode 100644
index f7322cba89..0000000000
--- a/lib/percept/priv/server_root/htdocs/index.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
- %CopyrightBegin%
-
- Copyright Ericsson AB 2007-2016. All Rights Reserved.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- %CopyrightEnd%
--->
-<html>
-<head>
- <title>percept</title>
- <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" />
- <link href="/css/percept.css" rel="stylesheet" type="text/css">
-</head>
-
-<body>
- <div id="header"><a href=/index.html>percept</a></div>
- <div id="menu" class="menu_tabs">
- <ul>
- <li><a href=/cgi-bin/percept_html/databases_page>databases</a></li>
- <li><a href=/cgi-bin/percept_html/processes_page>processes</a></li>
- <li><a href=/cgi-bin/percept_html/page>overview</a></li>
- </ul>
- </div>
- <div id="content">
- <p>Percept - Erlang Concurrency Profiling Tool</p>
- </div>
-</body>
-</html>
-
diff --git a/lib/percept/priv/server_root/images/nav.png b/lib/percept/priv/server_root/images/nav.png
deleted file mode 100644
index d136e806b1..0000000000
--- a/lib/percept/priv/server_root/images/nav.png
+++ /dev/null
Binary files differ
diff --git a/lib/percept/priv/server_root/images/white.png b/lib/percept/priv/server_root/images/white.png
deleted file mode 100644
index 94381b429d..0000000000
--- a/lib/percept/priv/server_root/images/white.png
+++ /dev/null
Binary files differ
diff --git a/lib/percept/priv/server_root/scripts/percept_area_select.js b/lib/percept/priv/server_root/scripts/percept_area_select.js
deleted file mode 100644
index 83fbb02c92..0000000000
--- a/lib/percept/priv/server_root/scripts/percept_area_select.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2007-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-function size_image(img, src) {
- percept_content = document.getElementById("content");
- var width = percept_content.offsetWidth - 120;
- var imgfile = "/cgi-bin/percept_graph/" + src + "&width=" + width;
- img.src = imgfile;
- img.onload = '';
-}
-
-function load_image() {
- var percept_graph = document.getElementById("percept_graph");
- if (percept_graph) {
- percept_content = document.getElementById("content");
- var width = percept_content.offsetWidth - 50;
- var height = max(screen.height - 550, 600);
- var rmin = document.form_area.data_min.value;
- var rmax = document.form_area.data_max.value;
-
- percept_graph.style.backgroundImage = "url('/cgi-bin/percept_graph/graph" +
- "?range_min=" + rmin +
- "&range_max=" + rmax +
- "&width=" + width +
- "&height=" + height + "')";
- percept_graph.style.width = width;
- percept_graph.style.height = height;
- }
-}
-
-function select_image() {
- var Graph = document.getElementById("percept_graph");
- if (Graph) {
- var GraphIndex = document.form_area.graph_select.selectedIndex;
- var GraphSelectValue = document.form_area.graph_select.options[GraphIndex].value;
- Graph.style.backgroundImage = "url('" + GraphSelectValue +"')";
- }
-}
-
-function select_down(event) {
- var Graf = document.getElementById("percept_graph");
- var Area = document.getElementById("percept_areaselect");
- var x = event.offsetX?(event.offsetX):event.pageX-Graf.offsetLeft;
- x = x - 60;
-
- var width = Graf.offsetWidth;
- var height = Graf.offsetHeight;
- var margin = 20;
-
- var Xmin = document.form_area.data_min.value;
- var Xmax = document.form_area.data_max.value;
-
- // Trim edges
-
- if ( x < margin ) {
- x = margin;
- }
-
- if ( x > width - margin ) {
- x = width - margin;
- }
-
- Area.style.left = x;
- Area.style.top = height - margin;
- Area.style.width = 1;
- Area.style.height = margin;
- Area.moving = true;
- Area.bgcolor = "#00ff00";
- Area.style.visibility = "visible";
- Area.style.borderRight = "1px solid #000"
- Area.style.borderLeft = "1px solid #000"
- Area.style.opacity = 0.65;
- Area.style.filter = 'alpha(opacity=65)';
- var RangeMin = convert_image2graph(x, Xmin, Xmax, margin, width - margin);
- if (RangeMin == 0) document.form_area.range_min.value = 0.0;
- else document.form_area.range_min.value = RangeMin;
-}
-
- function select_move(event) {
- var Graf = document.getElementById("percept_graph");
- var Area = document.getElementById("percept_areaselect");
- var x = event.offsetX?(event.offsetX):event.pageX-Graf.offsetLeft;
- x = x - 60;
- if (Area.moving == true) {
-
- var width = Graf.offsetWidth;
- var height = Graf.offsetHeight;
- var margin = 20;
- var Xmin = document.form_area.data_min.value;
- var Xmax = document.form_area.data_max.value;
-
- // Trim edges
-
- if ( x < margin ) {
- x = margin;
- }
-
- if ( x > width - margin ) {
- x = width - margin;
- }
-
- var x0 = min(x, Area.offsetLeft);
- var x1 = max(x, Area.offsetLeft);
- var w = (x1 - x0);
- Area.style.left = x0;
- Area.style.width = w;
- var RangeMin = convert_image2graph(x0, Xmin, Xmax, margin, width - margin);
- var RangeMax = convert_image2graph(x1, Xmin, Xmax, margin, width - margin);
- Area.style.visibility = "visible";
-
- if (RangeMin == 0) document.form_area.range_min.value = 0.0;
- else document.form_area.range_min.value = RangeMin;
- if (RangeMax == 0) document.form_area.range_max.value = 0.0;
- else document.form_area.range_max.value = RangeMax;
- }
-}
-
-function select_up(event) {
- var Graf = document.getElementById("percept_graph");
- var Area = document.getElementById("percept_areaselect");
- var x = event.offsetX?(event.offsetX):event.pageX-Graf.offsetLeft;
-
- x = x - 60;
- var width = Graf.offsetWidth;
- var height = Graf.offsetHeight;
- var margin = 20;
- var Xmin = document.form_area.data_min.value;
- var Xmax = document.form_area.data_max.value;
-
- // Trim edges
-
- if ( x < margin ) {
- x = margin;
- }
-
- if ( x > width - margin ) {
- x = width - margin;
- }
-
- var w = (x - Area.style.offsetLeft);
-
- Area.moving = false;
- Area.style.width = w;
- var RangeMax = convert_image2graph(x, Xmin, Xmax, margin, width - margin);
- if (RangeMax == 0) document.form_area.range_max.value = 0.0;
- else document.form_area.range_max.value = RangeMax;
-}
-
-function min(A, B) {
- if (A > B) return B;
- else return A;
-}
-
-function max(A,B) {
- if (A > B) return A;
- else return B;
-}
-
-function convert_image2graph(X, Xmin, Xmax, X0, X1) {
- var ImageWidth = X1 - X0;
- var RangeWidth = Xmax - Xmin;
- var DX = RangeWidth/ImageWidth;
- var Xprime = (X - X0)*DX + Xmin*1.0;
- return Xprime;
-}
diff --git a/lib/percept/priv/server_root/scripts/percept_error_handler.js b/lib/percept/priv/server_root/scripts/percept_error_handler.js
deleted file mode 100644
index dad8f2b566..0000000000
--- a/lib/percept/priv/server_root/scripts/percept_error_handler.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2007-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-var onerror=handleErr;
-
-function handleErr(msg,url,l) {
- var txt = "Error: " + msg + "\nURL: " + url + "\nCode line: " + l;
- alert(txt);
-}
diff --git a/lib/percept/priv/server_root/scripts/percept_select_all.js b/lib/percept/priv/server_root/scripts/percept_select_all.js
deleted file mode 100644
index c8eb966059..0000000000
--- a/lib/percept/priv/server_root/scripts/percept_select_all.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2007-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-function selectall() {
- for (var i = 0; i < document.process_select.elements.length; i++) {
- var e = document.process_select.elements[i];
- if ((e.name != 'select_all') && (e.type == 'checkbox')) {
- e.checked = document.process_select.select_all.checked;
- }
- }
-}
diff --git a/lib/percept/src/Makefile b/lib/percept/src/Makefile
deleted file mode 100644
index b2ec87d08c..0000000000
--- a/lib/percept/src/Makefile
+++ /dev/null
@@ -1,108 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2007-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include ../vsn.mk
-VSN=$(PERCEPT_VSN)
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/percept-$(VSN)
-
-# ----------------------------------------------------
-# Common Macros
-# ----------------------------------------------------
-
-MODULES= \
- egd \
- egd_png \
- egd_font \
- egd_render \
- egd_primitives \
- percept \
- percept_db \
- percept_html \
- percept_image \
- percept_graph \
- percept_analyzer
-
-
-#HRL_FILES= ../include/
-
-INTERNAL_HRL_FILES= egd.hrl percept.hrl
-
-ERL_FILES= $(MODULES:%=%.erl)
-
-TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
-
-APP_FILE= percept.app
-
-APP_SRC= $(APP_FILE).src
-APP_TARGET= $(EBIN)/$(APP_FILE)
-
-APPUP_FILE= percept.appup
-
-APPUP_SRC= $(APPUP_FILE).src
-APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_unused_vars -I../include
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-debug opt: $(TARGET_FILES)
-
-clean:
- rm -f $(TARGET_FILES)
- rm -f errs core *~
-
-$(APP_TARGET): $(APP_SRC) ../vsn.mk
- $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
-
-$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
-
-docs:
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-release_spec: opt
- $(INSTALL_DIR) "$(RELSYSDIR)/src"
- $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src"
- $(INSTALL_DATA) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src"
-# $(INSTALL_DIR) "$(RELSYSDIR)/include"
-# $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include"
- $(INSTALL_DIR) "$(RELSYSDIR)/ebin"
- $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin"
-
-release_docs_spec:
-
diff --git a/lib/percept/src/egd.erl b/lib/percept/src/egd.erl
deleted file mode 100644
index fe52da71f1..0000000000
--- a/lib/percept/src/egd.erl
+++ /dev/null
@@ -1,275 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-
-%%
-%% @doc egd - erlang graphical drawer
-%%
-%%
-
--module(egd).
-
--export([create/2, destroy/1, information/1]).
--export([text/5, line/4, color/1, color/2]).
--export([rectangle/4, filledRectangle/4, filledEllipse/4]).
--export([arc/4, arc/5]).
--export([render/1, render/2, render/3]).
-
--export([filledTriangle/5, polygon/3]).
-
--export([save/2]).
-
--include("egd.hrl").
-
-%%==========================================================================
-%% Type definitions
-%%==========================================================================
-
-%% @type egd_image()
-%% @type font()
-%% @type point() = {integer(), integer()}
-%% @type color()
-%% @type render_option() = {render_engine, opaque} | {render_engine, alpha}
-
--type egd_image() :: pid().
--type point() :: {non_neg_integer(), non_neg_integer()}.
--type render_option() :: {'render_engine', 'opaque'} | {'render_engine', 'alpha'}.
--type color() :: {float(), float(), float(), float()}.
-
-%%==========================================================================
-%% Interface functions
-%%==========================================================================
-
-%% @spec create(integer(), integer()) -> egd_image()
-%% @doc Creates an image area and returns its reference.
-
--spec create(Width :: integer(), Height :: integer()) -> egd_image().
-
-create(Width,Height) ->
- spawn_link(fun() -> init(trunc(Width),trunc(Height)) end).
-
-
-%% @spec destroy(egd_image()) -> ok
-%% @doc Destroys the image.
-
--spec destroy(Image :: egd_image()) -> ok.
-
-destroy(Image) ->
- cast(Image, destroy).
-
-
-%% @spec render(egd_image()) -> binary()
-%% @equiv render(Image, png, [{render_engine, opaque}])
-
--spec render(Image :: egd_image()) -> binary().
-
-render(Image) ->
- render(Image, png, [{render_engine, opaque}]).
-
-%% @spec render(egd_image(), png | raw_bitmap) -> binary()
-%% @equiv render(Image, Type, [{render_engine, opaque}])
-
-render(Image, Type) ->
- render(Image, Type, [{render_engine, opaque}]).
-
-%% @spec render(egd_image(), png | raw_bitmap, [render_option()]) -> binary()
-%% @doc Renders a binary from the primitives specified by egd_image(). The
-%% binary can either be a raw bitmap with rgb tripplets or a binary in png
-%% format.
-
--spec render(
- Image :: egd_image(),
- Type :: 'png' | 'raw_bitmap' | 'eps',
- Options :: [render_option()]) -> binary().
-
-render(Image, Type, Options) ->
- {render_engine, RenderType} = proplists:lookup(render_engine, Options),
- call(Image, {render, Type, RenderType}).
-
-
-%% @spec information(egd_image()) -> ok
-%% @hidden
-%% @doc Writes out information about the image. This is a debug feature
-%% mainly.
-
-information(Pid) ->
- cast(Pid, information).
-
-%% @spec line(egd_image(), point(), point(), color()) -> ok
-%% @doc Creates a line object from P1 to P2 in the image.
-
--spec line(
- Image :: egd_image(),
- P1 :: point(),
- P2 :: point(),
- Color :: color()) -> 'ok'.
-
-line(Image, P1, P2, Color) ->
- cast(Image, {line, P1, P2, Color}).
-
-%% @spec color( Value | Name ) -> color()
-%% where
-%% Value = {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()}
-%% Name = black | silver | gray | white | maroon | red | purple | fuchia | green | lime | olive | yellow | navy | blue | teal | aqua
-%% @doc Creates a color reference.
-
--spec color(Value :: {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} | atom()) ->
- color().
-
-color(Color) ->
- egd_primitives:color(Color).
-
-%% @spec color(egd_image(), {byte(), byte(), byte()}) -> color()
-%% @doc Creates a color reference.
-%% @hidden
-
-color(_Image, Color) ->
- egd_primitives:color(Color).
-
-%% @spec text(egd_image(), point(), font(), string(), color()) -> ok
-%% @doc Creates a text object.
-
-text(Image, P, Font, Text, Color) ->
- cast(Image, {text, P, Font, Text, Color}).
-
-%% @spec rectangle(egd_image(), point(), point(), color()) -> ok
-%% @doc Creates a rectangle object.
-
-rectangle(Image, P1, P2, Color) ->
- cast(Image, {rectangle, P1, P2, Color}).
-
-%% @spec filledRectangle(egd_image(), point(), point(), color()) -> ok
-%% @doc Creates a filled rectangle object.
-
-filledRectangle(Image, P1, P2, Color) ->
- cast(Image, {filled_rectangle, P1, P2, Color}).
-
-%% @spec filledEllipse(egd_image(), point(), point(), color()) -> ok
-%% @doc Creates a filled ellipse object.
-
-filledEllipse(Image, P1, P2, Color) ->
- cast(Image, {filled_ellipse, P1, P2, Color}).
-
-%% @spec filledTriangle(egd_image(), point(), point(), point(), color()) -> ok
-%% @hidden
-%% @doc Creates a filled triangle object.
-
-filledTriangle(Image, P1, P2, P3, Color) ->
- cast(Image, {filled_triangle, P1, P2, P3, Color}).
-
-%% @spec polygon(egd_image(), [point()], color()) -> ok
-%% @hidden
-%% @doc Creates a filled filled polygon object.
-
-polygon(Image, Pts, Color) ->
- cast(Image, {polygon, Pts, Color}).
-
-%% @spec arc(egd_image(), point(), point(), color()) -> ok
-%% @hidden
-%% @doc Creates an arc with radius of bbx corner.
-
-arc(Image, P1, P2, Color) ->
- cast(Image, {arc, P1, P2, Color}).
-
-%% @spec arc(egd_image(), point(), point(), integer(), color()) -> ok
-%% @hidden
-%% @doc Creates an arc.
-
-arc(Image, P1, P2, D, Color) ->
- cast(Image, {arc, P1, P2, D, Color}).
-
-%% @spec save(binary(), string()) -> ok
-%% @doc Saves the binary to file.
-
-save(Binary, Filename) when is_binary(Binary) ->
- ok = file:write_file(Filename, Binary),
- ok.
-% ---------------------------------
-% Aux functions
-% ---------------------------------
-
-cast(Pid, Command) ->
- Pid ! {egd, self(), Command},
- ok.
-
-call(Pid, Command) ->
- Pid ! {egd, self(), Command},
- receive {egd, Pid, Result} -> Result end.
-
-% ---------------------------------
-% Server loop
-% ---------------------------------
-
-init(W,H) ->
- Image = egd_primitives:create(W,H),
- loop(Image).
-
-loop(Image) ->
- receive
- % Quitting
- {egd, _Pid, destroy} -> ok;
-
- % Rendering
- {egd, Pid, {render, BinaryType, RenderType}} ->
- case BinaryType of
- raw_bitmap ->
- Bitmap = egd_render:binary(Image, RenderType),
- Pid ! {egd, self(), Bitmap},
- loop(Image);
- eps ->
- Eps = egd_render:eps(Image),
- Pid ! {egd, self(), Eps},
- loop(Image);
- png ->
- Bitmap = egd_render:binary(Image, RenderType),
- Png = egd_png:binary(
- Image#image.width,
- Image#image.height,
- Bitmap),
- Pid ! {egd, self(), Png},
- loop(Image);
- Unhandled ->
- Pid ! {egd, self(), {error, {format, Unhandled}}},
- loop(Image)
- end;
-
- % Drawing primitives
- {egd, _Pid, {line, P1, P2, C}} ->
- loop(egd_primitives:line(Image, P1, P2, C));
- {egd, _Pid, {text, P, Font, Text, C}} ->
- loop(egd_primitives:text(Image, P, Font, Text, C));
- {egd, _Pid, {filled_ellipse, P1, P2, C}} ->
- loop(egd_primitives:filledEllipse(Image, P1, P2, C));
- {egd, _Pid, {filled_rectangle, P1, P2, C}} ->
- loop(egd_primitives:filledRectangle(Image, P1, P2, C));
- {egd, _Pid, {filled_triangle, P1, P2, P3, C}} ->
- loop(egd_primitives:filledTriangle(Image, P1, P2, P3, C));
- {egd, _Pid, {polygon, Pts, C}} ->
- loop(egd_primitives:polygon(Image, Pts, C));
- {egd, _Pid, {arc, P1, P2, C}} ->
- loop(egd_primitives:arc(Image, P1, P2, C));
- {egd, _Pid, {arc, P1, P2, D, C}} ->
- loop(egd_primitives:arc(Image, P1, P2, D, C));
- {egd, _Pid, {rectangle, P1, P2, C}} ->
- loop(egd_primitives:rectangle(Image, P1, P2, C));
- {egd, _Pid, information} ->
- egd_primitives:info(Image),
- loop(Image);
- _ ->
- loop(Image)
- end.
diff --git a/lib/percept/src/egd.hrl b/lib/percept/src/egd.hrl
deleted file mode 100644
index fc0a7e10ee..0000000000
--- a/lib/percept/src/egd.hrl
+++ /dev/null
@@ -1,45 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-
--type rgba_float() :: {float(), float(), float(), float()}.
--type rgba_byte() :: {byte(), byte(), byte(), byte()}.
--type rgb() :: {byte(), byte(), byte()}.
-
--record(image_object, {
- type,
- points = [],
- span,
- internals,
- intervals,
- color}). % RGBA in float values
-
--record(image, {
- width,
- height,
- objects = [],
- background = {1.0,1.0,1.0,1.0},
- image}).
-
--define(debug, void).
-
--ifdef(debug).
--define(dbg(X), io:format("DEBUG: ~p:~p~n",[?MODULE, X])).
--else.
--define(dbg(X), ok).
--endif.
diff --git a/lib/percept/src/egd_font.erl b/lib/percept/src/egd_font.erl
deleted file mode 100644
index ef1cc434df..0000000000
--- a/lib/percept/src/egd_font.erl
+++ /dev/null
@@ -1,173 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-
-%%
-%% @doc egd_font
-%%
-
--module(egd_font).
-
--export([load/1, size/1, glyph/2]).
--include("egd.hrl").
-
-%% Font represenatation in ets table
-%% egd_font_table
-%%
-%% Information:
-%% {Key, Description, Size}
-%% Key :: {Font :: atom(), information}
-%% Description :: any(), Description header from font file
-%% Size :: {W :: integer(), H :: integer()}
-%%
-%% Glyphs:
-%% {Key, Translation LSs} where
-%% Key :: {Font :: atom(), Code :: integer()}, Code = glyph char code
-%% Translation :: {
-%% W :: integer(), % BBx width
-%% H :: integer(), % BBx height
-%% X0 :: integer(), % X start
-%% Y0 :: integer(), % Y start
-%% Xm :: integer(), % Glyph X move when drawing
-%% }
-%% LSs :: [[{Xl :: integer(), Xr :: integer()}]]
-%% The first list is height (top to bottom), the inner list is the list
-%% of line spans for the glyphs horizontal pixels.
-%%
-
-%%==========================================================================
-%% Interface functions
-%%==========================================================================
-
-size(Font) ->
- [{_Key, _Description, Size}] = ets:lookup(egd_font_table,{Font,information}),
- Size.
-
-glyph(Font, Code) ->
- [{_Key, Translation, LSs}] = ets:lookup(egd_font_table,{Font,Code}),
- {Translation, LSs}.
-
-load(Filename) ->
- {ok, Bin} = file:read_file(Filename),
- Font = erlang:binary_to_term(Bin),
- load_font_header(Font).
-
-%%==========================================================================
-%% Internal functions
-%%==========================================================================
-
-%% ETS handler functions
-
-initialize_table() ->
- egd_font_table = ets:new(egd_font_table, [named_table, ordered_set, public]),
- ok.
-
-glyph_insert(Font, Code, Translation, LSs) ->
- Element = {{Font, Code}, Translation, LSs},
- ets:insert(egd_font_table, Element).
-
-font_insert(Font, Description, Dimensions) ->
- Element = {{Font, information}, Description, Dimensions},
- ets:insert(egd_font_table, Element).
-
-%% Font loader functions
-
-is_font_loaded(Font) ->
- try
- case ets:lookup(egd_font_table, {Font, information}) of
- [] -> false;
- _ -> true
- end
- catch
- error:_ ->
- initialize_table(),
- false
- end.
-
-
-load_font_header({_Type, _Version, Font}) ->
- load_font_body(Font).
-
-load_font_body({Key,Desc,W,H,Glyphs,Bitmaps}) ->
- case is_font_loaded(Key) of
- true -> Key;
- false ->
- % insert dimensions
- font_insert(Key, Desc, {W,H}),
- parse_glyphs(Glyphs, Bitmaps, Key),
- Key
- end.
-
-parse_glyphs([], _ , _Key) -> ok;
-parse_glyphs([Glyph|Glyphs], Bs, Key) ->
- {Code, Translation, LSs} = parse_glyph(Glyph, Bs),
- glyph_insert(Key, Code, Translation, LSs),
- parse_glyphs(Glyphs, Bs, Key).
-
-parse_glyph({Code,W,H,X0,Y0,Xm,Offset}, Bitmasks) ->
- BytesPerLine = ((W+7) div 8),
- NumBytes = BytesPerLine*H,
- <<_:Offset/binary,Bitmask:NumBytes/binary,_/binary>> = Bitmasks,
- LSs = render_glyph(W,H,X0,Y0,Xm,Bitmask),
- {Code, {W,H,X0,Y0,Xm}, LSs}.
-
-render_glyph(W, H, X0, Y0, Xm, Bitmask) ->
- render_glyph(W,{0,H},X0,Y0,Xm,Bitmask, []).
-render_glyph(_W, {H,H}, _X0, _Y0, _Xm, _Bitmask, Out) -> Out;
-render_glyph(W, {Hi,H}, X0, Y0,Xm, Bitmask , LSs) ->
- N = ((W+7) div 8),
- O = N*Hi,
- <<_:O/binary, Submask/binary>> = Bitmask,
- LS = render_glyph_horizontal(
- Submask, % line glyph bitmask
- {down, W - 1}, % loop state
- W - 1, % Width
- []), % Linespans
- render_glyph(W,{Hi+1,H},X0,Y0,Xm, Bitmask, [LS|LSs]).
-
-render_glyph_horizontal(Value, {Pr, Px}, 0, Spans) ->
- Cr = bit_spin(Value, 0),
- case {Pr,Cr} of
- {up , up } -> % closure of interval since its last
- [{0, Px}|Spans];
- {up , down} -> % closure of interval
- [{1, Px}|Spans];
- {down, up } -> % beginning of interval
- [{0, 0}|Spans];
- {down, down} -> % no change in interval
- Spans
- end;
-render_glyph_horizontal(Value, {Pr, Px}, Cx, Spans) ->
- Cr = bit_spin(Value, Cx),
- case {Pr,Cr} of
- {up , up } -> % no change in interval
- render_glyph_horizontal(Value, {Cr, Px}, Cx - 1, Spans);
- {up , down} -> % closure of interval
- render_glyph_horizontal(Value, {Cr, Cx}, Cx - 1, [{Cx+1,Px}|Spans]);
- {down, up } -> % beginning of interval
- render_glyph_horizontal(Value, {Cr, Cx}, Cx - 1, Spans);
- {down, down} -> % no change in interval
- render_glyph_horizontal(Value, {Cr, Px}, Cx - 1, Spans)
- end.
-
-bit_spin(Value, Cx) ->
- <<_:Cx, Bit:1, _/bits>> = Value,
- case Bit of
- 1 -> up;
- 0 -> down
- end.
diff --git a/lib/percept/src/egd_png.erl b/lib/percept/src/egd_png.erl
deleted file mode 100644
index fe660513b4..0000000000
--- a/lib/percept/src/egd_png.erl
+++ /dev/null
@@ -1,105 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-
-
-%% This code was originally written by Dan Gudmundsson for png-handling in
-%% wings3d (e3d__png).
-%%
-%% @doc egd
-%%
-
--module(egd_png).
-
--export([binary/3]).
-
--include("egd.hrl").
-
--define(MAGIC, 137,$P,$N,$G,$\r,$\n,26,$\n).
-
--define(GREYSCALE, 0).
--define(TRUECOLOUR, 2).
--define(INDEXED, 3).
--define(GREYSCALE_A, 4).
--define(TRUECOLOUR_A,6).
-
--define(MAX_WBITS,15).
-
--define(CHUNK, 240).
-
--define(get4p1(Idx),((Idx) bsr 4)).
--define(get4p2(Idx),((Idx) band 16#0F)).
--define(get2p1(Idx),((Idx) bsr 6)).
--define(get2p2(Idx),(((Idx) bsr 4) band 3)).
--define(get2p3(Idx),(((Idx) bsr 2) band 3)).
--define(get2p4(Idx),((Idx) band 3)).
--define(get1p1(Idx),((Idx) bsr 7)).
--define(get1p2(Idx),(((Idx) bsr 6) band 1)).
--define(get1p3(Idx),(((Idx) bsr 5) band 1)).
--define(get1p4(Idx),(((Idx) bsr 4) band 1)).
--define(get1p5(Idx),(((Idx) bsr 3) band 1)).
--define(get1p6(Idx),(((Idx) bsr 2) band 1)).
--define(get1p7(Idx),(((Idx) bsr 1) band 1)).
--define(get1p8(Idx),((Idx) band 1)).
-
-binary(W, H, Bitmap) when is_binary(Bitmap) ->
- Z = zlib:open(),
- Binary = bitmap2png(W, H, Bitmap, Z),
- zlib:close(Z),
- Binary.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-% Begin Tainted
-
-bitmap2png(W, H, Bitmap,Z) ->
- HDR = create_chunk(<<"IHDR",W:32,H:32,8:8,(png_type(r8g8b8)):8,0:8,0:8,0:8>>,Z),
- DATA = create_chunk(["IDAT",compress_image(0,3*W,Bitmap,[])],Z),
- END = create_chunk(<<"IEND">>,Z),
- list_to_binary([?MAGIC,HDR,DATA,END]).
-
-compress_image(I,RowLen, Bin, Acc) ->
- Pos = I*RowLen,
- case Bin of
- <<_:Pos/binary,Row:RowLen/binary,_/binary>> ->
- Filtered = filter_row(Row,RowLen),
- compress_image(I+1,RowLen,Bin,[Filtered|Acc]);
- _ when Pos == size(Bin) ->
- Filtered = list_to_binary(lists:reverse(Acc)),
- Compressed = zlib:compress(Filtered),
- Compressed
- end.
-
-filter_row(Row,_RowLen) ->
- [0,Row].
-
-% dialyzer warnings
-%png_type(g8) -> ?GREYSCALE;
-%png_type(a8) -> ?GREYSCALE;
-%png_type(r8g8b8a8) -> ?TRUECOLOUR_A;
-png_type(r8g8b8) -> ?TRUECOLOUR.
-
-create_chunk(Bin,Z) when is_list(Bin) ->
- create_chunk(list_to_binary(Bin),Z);
-create_chunk(Bin,Z) when is_binary(Bin) ->
- Sz = size(Bin)-4,
- Crc = zlib:crc32(Z,Bin),
- <<Sz:32,Bin/binary,Crc:32>>.
-
-% End tainted
diff --git a/lib/percept/src/egd_primitives.erl b/lib/percept/src/egd_primitives.erl
deleted file mode 100644
index b64189c552..0000000000
--- a/lib/percept/src/egd_primitives.erl
+++ /dev/null
@@ -1,412 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-
-%%
-%% @doc egd_primitives
-%%
-
-
--module(egd_primitives).
--export([create/2,
- color/1,
- pixel/3,
- polygon/3,
- line/4,
- line/5,
- arc/4,
- arc/5,
- rectangle/4,
- filledRectangle/4,
- filledEllipse/4,
- filledTriangle/5,
- text/5]).
-
--export([info/1,
- object_info/1,
- rgb_float2byte/1]).
-
--export([arc_to_edges/3,
- convex_hull/1,
- edges/1]).
-
--include("egd.hrl").
-
-%% API info
-info(I) ->
- W = I#image.width, H = I#image.height,
- io:format("Dimensions: ~p x ~p~n", [W,H]),
- io:format("Number of image objects: ~p~n", [length(I#image.objects)]),
- TotalPoints = info_objects(I#image.objects,0),
- io:format("Total points: ~p [~p %]~n", [TotalPoints, 100*TotalPoints/(W*H)]),
- ok.
-
-info_objects([],N) -> N;
-info_objects([O | Os],N) ->
- Points = length(O#image_object.points),
-info_objects(Os,N+Points).
-
-object_info(O) ->
- io:format("Object information: ~p~n", [O#image_object.type]),
- io:format("- Number of points: ~p~n", [length(O#image_object.points)]),
- io:format("- Bounding box: ~p~n", [O#image_object.span]),
- io:format("- Color: ~p~n", [O#image_object.color]),
- ok.
-
-%% interface functions
-
-line(#image{objects=Os}=I, Sp, Ep, Color) ->
- line(#image{objects=Os}=I, Sp, Ep, 1, Color).
-
-line(#image{objects=Os}=I, Sp, Ep, Wd, Color) ->
- I#image{objects=[#image_object{
- internals = Wd,
- type = line,
- points = [Sp, Ep],
- span = span([Sp, Ep]),
- color = Color}|Os]}.
-
-arc(I, {Sx,Sy} = Sp, {Ex,Ey} = Ep, Color) ->
- X = Ex - Sx,
- Y = Ey - Sy,
- R = math:sqrt(X*X + Y*Y)/2,
- arc(I, Sp, Ep, R, Color).
-
-arc(#image{objects=Os}=I, Sp, Ep, D, Color) ->
- SpanPts = lists:flatten([
- [{X + D, Y + D},
- {X + D, Y - D},
- {X - D, Y + D},
- {X - D, Y - D}] || {X,Y} <- [Sp,Ep]]),
-
- I#image{objects=[#image_object{
- internals = D,
- type = arc,
- points = [Sp, Ep],
- span = span(SpanPts),
- color = Color}|Os]}.
-
-pixel(#image{objects=Os}=I, Point, Color) ->
- I#image{objects=[#image_object{
- type = pixel,
- points = [Point],
- span = span([Point]),
- color = Color}|Os]}.
-
-rectangle(#image{objects=Os}=I, Sp, Ep, Color) ->
- I#image{objects=[#image_object{
- type = rectangle,
- points = [Sp, Ep],
- span = span([Sp, Ep]),
- color = Color}|Os]}.
-
-filledRectangle(#image{objects=Os}=I, Sp, Ep, Color) ->
- I#image{objects=[#image_object{
- type = filled_rectangle,
- points = [Sp, Ep],
- span = span([Sp, Ep]),
- color = Color}|Os]}.
-
-filledEllipse(#image{objects=Os}=I, Sp, Ep, Color) ->
- {X0,Y0,X1,Y1} = Span = span([Sp, Ep]),
- Xr = (X1 - X0)/2,
- Yr = (Y1 - Y0)/2,
- Xp = - X0 - Xr,
- Yp = - Y0 - Yr,
- I#image{objects=[#image_object{
- internals = {Xp,Yp, Xr*Xr,Yr*Yr},
- type = filled_ellipse,
- points = [Sp, Ep],
- span = Span,
- color = Color}|Os]}.
-
-filledTriangle(#image{objects=Os}=I, P1, P2, P3, Color) ->
- I#image{objects=[#image_object{
- type = filled_triangle,
- points = [P1,P2,P3],
- span = span([P1,P2,P3]),
- color = Color}|Os]}.
-
-polygon(#image{objects=Os}=I, Points, Color) ->
- I#image{objects=[#image_object{
- type = polygon,
- points = Points,
- span = span(Points),
- color = Color}|Os]}.
-
-text(#image{objects=Os}=I, {Xs,Ys}=Sp, Font, Text, Color) ->
- {FW,FH} = egd_font:size(Font),
- Length = length(Text),
- Ep = {Xs + Length*FW, Ys + FH + 5},
- I#image{objects=[#image_object{
- internals = {Font, Text},
- type = text_horizontal,
- points = [Sp],
- span = span([Sp,Ep]),
- color = Color}|Os]}.
-
-create(W, H) ->
- #image{width = W, height = H}.
-
-color(Color) when is_atom(Color) -> rgba_byte2float(name_to_color(Color, 255));
-color({Color, A}) when is_atom(Color) -> rgba_byte2float(name_to_color(Color, A));
-color({R,G,B}) -> rgba_byte2float({R,G,B, 255});
-color(C) -> rgba_byte2float(C).
-
-name_to_color(Color, A) ->
- case Color of
- %% HTML default colors
- black -> { 0, 0, 0, A};
- silver -> {192, 192, 192, A};
- gray -> {128, 128, 128, A};
- white -> {128, 0, 0, A};
- maroon -> {255, 0, 0, A};
- red -> {128, 0, 128, A};
- purple -> {128, 0, 128, A};
- fuchia -> {255, 0, 255, A};
- green -> { 0, 128, 0, A};
- lime -> { 0, 255, 0, A};
- olive -> {128, 128, 0, A};
- yellow -> {255, 255, 0, A};
- navy -> { 0, 0, 128, A};
- blue -> { 0, 0, 255, A};
- teal -> { 0, 128, 0, A};
- aqua -> { 0, 255, 155, A};
-
- %% HTML color extensions
- steelblue -> { 70, 130, 180, A};
- royalblue -> { 4, 22, 144, A};
- cornflowerblue -> {100, 149, 237, A};
- lightsteelblue -> {176, 196, 222, A};
- mediumslateblue -> {123, 104, 238, A};
- slateblue -> {106, 90, 205, A};
- darkslateblue -> { 72, 61, 139, A};
- midnightblue -> { 25, 25, 112, A};
- darkblue -> { 0, 0, 139, A};
- mediumblue -> { 0, 0, 205, A};
- dodgerblue -> { 30, 144, 255, A};
- deepskyblue -> { 0, 191, 255, A};
- lightskyblue -> {135, 206, 250, A};
- skyblue -> {135, 206, 235, A};
- lightblue -> {173, 216, 230, A};
- powderblue -> {176, 224, 230, A};
- azure -> {240, 255, 255, A};
- lightcyan -> {224, 255, 255, A};
- paleturquoise -> {175, 238, 238, A};
- mediumturquoise -> { 72, 209, 204, A};
- lightseagreen -> { 32, 178, 170, A};
- darkcyan -> { 0, 139, 139, A};
- cadetblue -> { 95, 158, 160, A};
- darkturquoise -> { 0, 206, 209, A};
- cyan -> { 0, 255, 255, A};
- turquoise -> { 64, 224, 208, A};
- aquamarine -> {127, 255, 212, A};
- mediumaquamarine -> {102, 205, 170, A};
- darkseagreen -> {143, 188, 143, A};
- mediumseagreen -> { 60, 179, 113, A};
- seagreen -> { 46, 139, 87, A};
- darkgreen -> { 0, 100, 0, A};
- forestgreen -> { 34, 139, 34, A};
- limegreen -> { 50, 205, 50, A};
- chartreuse -> {127, 255, 0, A};
- lawngreen -> {124, 252, 0, A};
- greenyellow -> {173, 255, 47, A};
- yellowgreen -> {154, 205, 50, A};
- palegreen -> {152, 251, 152, A};
- lightgreen -> {144, 238, 144, A};
- springgreen -> { 0, 255, 127, A};
- darkolivegreen -> { 85, 107, 47, A};
- olivedrab -> {107, 142, 35, A};
- darkkhaki -> {189, 183, 107, A};
- darkgoldenrod -> {184, 134, 11, A};
- goldenrod -> {218, 165, 32, A};
- gold -> {255, 215, 0, A};
- khaki -> {240, 230, 140, A};
- palegoldenrod -> {238, 232, 170, A};
- blanchedalmond -> {255, 235, 205, A};
- moccasin -> {255, 228, 181, A};
- wheat -> {245, 222, 179, A};
- navajowhite -> {255, 222, 173, A};
- burlywood -> {222, 184, 135, A};
- tan -> {210, 180, 140, A};
- rosybrown -> {188, 143, 143, A};
- sienna -> {160, 82, 45, A};
- saddlebrown -> {139, 69, 19, A};
- chocolate -> {210, 105, 30, A};
- peru -> {205, 133, 63, A};
- sandybrown -> {244, 164, 96, A};
- darkred -> {139, 0, 0, A};
- brown -> {165, 42, 42, A};
- firebrick -> {178, 34, 34, A};
- indianred -> {205, 92, 92, A};
- lightcoral -> {240, 128, 128, A};
- salmon -> {250, 128, 114, A};
- darksalmon -> {233, 150, 122, A};
- lightsalmon -> {255, 160, 122, A};
- coral -> {255, 127, 80, A};
- tomato -> {255, 99, 71, A};
- darkorange -> {255, 140, 0, A};
- orange -> {255, 165, 0, A};
- orangered -> {255, 69, 0, A};
- crimson -> {220, 20, 60, A};
- deeppink -> {255, 20, 147, A};
- fuchsia -> {255, 0, 255, A};
- magenta -> {255, 0, 255, A};
- hotpink -> {255, 105, 180, A};
- lightpink -> {255, 182, 193, A};
- pink -> {255, 192, 203, A};
- palevioletred -> {219, 112, 147, A};
- mediumvioletred -> {199, 21, 133, A};
- darkmagenta -> {139, 0, 139, A};
- mediumpurple -> {147, 112, 219, A};
- blueviolet -> {138, 43, 226, A};
- indigo -> { 75, 0, 130, A};
- darkviolet -> {148, 0, 211, A};
- darkorchid -> {153, 50, 204, A};
- mediumorchid -> {186, 85, 211, A};
- orchid -> {218, 112, 214, A};
- violet -> {238, 130, 238, A};
- plum -> {221, 160, 221, A};
- thistle -> {216, 191, 216, A};
- lavender -> {230, 230, 250, A};
- ghostwhite -> {248, 248, 255, A};
- aliceblue -> {240, 248, 255, A};
- mintcream -> {245, 255, 250, A};
- honeydew -> {240, 255, 240, A};
- lemonchiffon -> {255, 250, 205, A};
- cornsilk -> {255, 248, 220, A};
- lightyellow -> {255, 255, 224, A};
- ivory -> {255, 255, 240, A};
- floralwhite -> {255, 250, 240, A};
- linen -> {250, 240, 230, A};
- oldlace -> {253, 245, 230, A};
- antiquewhite -> {250, 235, 215, A};
- bisque -> {255, 228, 196, A};
- peachpuff -> {255, 218, 185, A};
- papayawhip -> {255, 239, 213, A};
- beige -> {245, 245, 220, A};
- seashell -> {255, 245, 238, A};
- lavenderblush -> {255, 240, 245, A};
- mistyrose -> {255, 228, 225, A};
- snow -> {255, 250, 250, A};
- whitesmoke -> {245, 245, 245, A};
- gainsboro -> {220, 220, 220, A};
- lightgrey -> {211, 211, 211, A};
- darkgray -> {169, 169, 169, A};
- lightslategray -> {119, 136, 153, A};
- slategray -> {112, 128, 144, A};
- dimgray -> {105, 105, 105, A};
- darkslategray -> { 47, 79, 79, A};
- mediumspringgreen -> { 0, 250, 154, A};
- lightgoldenrodyellow -> {250, 250, 210, A}
- end.
-
-
-%%% Generic transformations
-
-%% arc_to_edges
-%% In:
-%% P1 :: point(),
-%% P2 :: point(),
-%% D :: float(),
-%% Out:
-%% Res :: [edges()]
-
-arc_to_edges(P0, P1, D) when abs(D) < 0.5 -> [{P0,P1}];
-arc_to_edges({X0,Y0}, {X1,Y1}, D) ->
- Vx = X1 - X0,
- Vy = Y1 - Y0,
-
- Mx = X0 + 0.5 * Vx,
- My = Y0 + 0.5 * Vy,
-
- % Scale V by Rs
- L = math:sqrt(Vx*Vx + Vy*Vy),
- Sx = D*Vx/L,
- Sy = D*Vy/L,
-
- Bx = trunc(Mx - Sy),
- By = trunc(My + Sx),
-
- arc_to_edges({X0,Y0}, {Bx,By}, D/4) ++ arc_to_edges({Bx,By}, {X1,Y1}, D/4).
-
-%% edges
-%% In:
-%% Pts :: [point()]
-%% Out:
-%% Edges :: [{point(),point()}]
-
-edges([]) -> [];
-edges([P0|_] = Pts) -> edges(Pts, P0,[]).
-edges([P1], P0, Out) -> [{P1,P0}|Out];
-edges([P1,P2|Pts],P0,Out) -> edges([P2|Pts],P0,[{P1,P2}|Out]).
-
-%% convex_hull
-%% In:
-%% Ps :: [point()]
-%% Out:
-%% Res :: [point()]
-
-convex_hull(Ps) ->
- P0 = lower_right(Ps),
- [P1|Ps1] = lists:sort(fun
- (P2,P1) ->
- case point_side({P1,P0},P2) of
- left -> true;
- _ -> false
- end
- end, Ps -- [P0]),
- convex_hull(Ps1, [P1,P0]).
-
-convex_hull([], W) -> W;
-convex_hull([P|Pts], [P1,P2|W]) ->
- case point_side({P2,P1},P) of
- left -> convex_hull(Pts, [P,P1,P2|W]);
- _ -> convex_hull([P|Pts], [P2|W])
- end.
-
-lower_right([P|Pts]) -> lower_right(P, Pts).
-lower_right(P, []) -> P;
-lower_right({X0,Y0}, [{_,Y}|Pts]) when Y < Y0 -> lower_right({X0,Y0}, Pts);
-lower_right({X0,Y0}, [{X,Y}|Pts]) when X < X0, Y < Y0 -> lower_right({X0,Y0}, Pts);
-lower_right(_,[P|Pts]) -> lower_right(P, Pts).
-
-point_side({{X0,Y0}, {X1, Y1}}, {X2, Y2}) -> point_side((X1 - X0)*(Y2 - Y0) - (X2 - X0)*(Y1 - Y0)).
-point_side(D) when D > 0 -> left;
-point_side(D) when D < 0 -> right;
-point_side(_) -> on_line.
-
-%% AUX
-
-span([{X0,Y0}|Points]) ->
- span(Points,X0,Y0,X0,Y0).
-span([{X0,Y0}|Points],Xmin,Ymin,Xmax,Ymax) ->
- span(Points,erlang:min(Xmin,X0),
- erlang:min(Ymin,Y0),
- erlang:max(Xmax,X0),
- erlang:max(Ymax,Y0));
-span([],Xmin,Ymin,Xmax,Ymax) ->
- {Xmin,Ymin,Xmax,Ymax}.
-
-
-rgb_float2byte({R,G,B}) -> rgb_float2byte({R,G,B,1.0});
-rgb_float2byte({R,G,B,A}) ->
- {trunc(R*255), trunc(G*255), trunc(B*255), trunc(A*255)}.
-
-rgba_byte2float({R,G,B,A}) ->
- {R/255,G/255,B/255,A/255}.
diff --git a/lib/percept/src/egd_render.erl b/lib/percept/src/egd_render.erl
deleted file mode 100644
index 6c708e3e86..0000000000
--- a/lib/percept/src/egd_render.erl
+++ /dev/null
@@ -1,664 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-
-%%
-%% @doc egd_render
-%%
-
--module(egd_render).
-
--export([binary/1, binary/2]).
--export([eps/1]).
--compile(inline).
-
--export([line_to_linespans/3]).
-
--include("egd.hrl").
--define('DummyC',0).
-
-binary(Image) ->
- binary(Image, opaque).
-
-binary(Image, Type) ->
- parallel_binary(precompile(Image),Type).
-
-parallel_binary(Image = #image{ height = Height },Type) ->
- case erlang:min(erlang:system_info(schedulers), Height) of
- 1 ->
- % if the height or the number of schedulers is 1
- % do the scanlines in this process.
- W = Image#image.width,
- Bg = Image#image.background,
- Os = Image#image.objects,
- erlang:list_to_binary([scanline(Y, Os, {0,0,W - 1, Bg}, Type)
- || Y <- lists:seq(1, Height)]);
- Np ->
- Pids = start_workers(Np, Type),
- Handler = handle_workers(Height, Pids),
- init_workers(Image, Handler, Pids),
- Res = receive_binaries(Height),
- finish_workers(Pids),
- Res
- end.
-
-start_workers(Np, Type) ->
- start_workers(Np, Type, []).
-
-start_workers( 0, _, Pids) -> Pids;
-start_workers(Np, Type, Pids) when Np > 0 ->
- start_workers(Np - 1, Type, [spawn_link(fun() -> worker(Type) end)|Pids]).
-
-worker(Type) ->
- receive
- {Pid, data, #image{ objects = Os, width = W, background = Bg }} ->
- worker(Os, W, Bg, Type, Pid)
- end.
-
-worker(Objects, Width, Bg, Type, Collector) ->
- receive
- {Pid, scan, {Ys, Ye}} ->
- lists:foreach(fun
- (Y) ->
- Bin = erlang:list_to_binary(scanline(Y, Objects, {0,0,Width - 1, Bg}, Type)),
- Collector ! {scan, Y, Bin}
- end, lists:seq(Ys,Ye)),
- Pid ! {self(), scan_complete},
- worker(Objects, Width, Bg, Type, Collector);
- {Pid, scan, Y} ->
- Bin = erlang:list_to_binary(scanline(Y, Objects, {0,0,Width - 1, Bg}, Type)),
- Collector ! {scan, Y, Bin},
- Pid ! {self(), scan_complete},
- worker(Objects, Width, Bg, Type, Collector);
- {_, done} ->
- ok
- end.
-
-init_workers(_Image, _Handler, []) -> ok;
-init_workers(Image, Handler, [Pid|Pids]) ->
- Pid ! {self(), data, Image},
- Handler ! {Pid, scan_complete},
- init_workers(Image, Handler, Pids).
-
-handle_workers(H, Pids) ->
- spawn_link(fun() -> handle_workers(H, H, length(Pids)) end).
-
-handle_workers(_, 0, _) -> ok;
-handle_workers(H, Hi, Np) when H > 0 ->
- N = trunc(Hi/(2*Np)),
- receive
- {Pid, scan_complete} ->
- if N < 2 ->
- Pid ! {self(), scan, Hi},
- handle_workers(H, Hi - 1, Np);
- true ->
- Pid ! {self(), scan, {Hi - N, Hi}},
- handle_workers(H, Hi - 1 - N, Np)
- end
- end.
-
-finish_workers([]) -> ok;
-finish_workers([Pid|Pids]) ->
- Pid ! {self(), done},
- finish_workers(Pids).
-
-receive_binaries(H) ->
- receive_binaries(H, []).
-
-receive_binaries(0, Bins) -> erlang:list_to_binary(Bins);
-receive_binaries(H, Bins) when H > 0 ->
- receive
- {scan, H, Bin} ->
- receive_binaries(H - 1, [Bin|Bins])
- end.
-
-scanline(Y, Os, {_,_,Width,_}=LSB, Type) ->
- OLSs = parse_objects_on_line(Y-1, Width, Os),
- RLSs = resulting_line_spans([LSB|OLSs],Type),
- [ lists:duplicate(Xr - Xl + 1, <<(trunc(R*255)):8,(trunc(G*255)):8,(trunc(B*255)):8>>) || {_,Xl, Xr, {R,G,B,_}} <- RLSs ].
-
-resulting_line_spans(LSs,Type) ->
- %% Build a list of "transitions" from left to right.
- Trans = line_spans_to_trans(LSs),
- %% Convert list of "transitions" to linespans.
- trans_to_line_spans(Trans,Type).
-
-line_spans_to_trans(LSs) ->
- line_spans_to_trans(LSs,[],0).
-
-line_spans_to_trans([],Db,_) ->
- lists:sort(Db);
-line_spans_to_trans([{_,L,R,C}|LSs],Db,Z) ->
- line_spans_to_trans(LSs,[{{L,Z,start},C},{{R+1,Z,stop},C}|Db],Z+1).
-
-trans_to_line_spans(Trans,Type) ->
- trans_to_line_spans(simplify_trans(Trans,Type,[],{0.0,0.0,0.0,0.0},[])).
-
-trans_to_line_spans(SimpleTrans) ->
- trans_to_line_spans1(SimpleTrans,[]).
-
-trans_to_line_spans1([],Spans) ->
- Spans;
-trans_to_line_spans1([_],Spans) ->
- Spans;
-trans_to_line_spans1([{L1,_},{L2,C2}|SimpleTrans],Spans) ->
- %% We are going backwards now...
- trans_to_line_spans1([{L2,C2}|SimpleTrans],[{?DummyC,L2,L1-1,C2}|Spans]).
-
-simplify_trans([],_,_,_,Acc) ->
- Acc;
-simplify_trans([{{L,_,_},_}|_] = Trans,Type,Layers,OldC,Acc) ->
- {NextTrans,RestTrans} =
- lists:splitwith(fun({{L1,_,_},_}) when L1 == L ->
- true;
- (_) ->
- false
- end, Trans),
- {C,NewLayers} = color(NextTrans,Layers,Type,OldC),
- case OldC of
- C -> %% No change in color, so transition unnecessary.
- simplify_trans(RestTrans,Type,NewLayers,OldC,Acc);
- _ ->
- simplify_trans(RestTrans,Type,NewLayers,C,[{L,C}|Acc])
- end.
-
-color(Trans,Layers,Type,OldC) ->
- case modify_layers(Layers,Trans) of
- Layers ->
- {OldC,Layers};
- NewLayers ->
- {color(NewLayers,Type),NewLayers}
- end.
-
-color([],_) -> {0.0,0.0,0.0,0.0};
-color([{_,C}|_],opaque) -> C;
-color(Layers,alpha) -> color1({0.0,0.0,0.0,0.0},Layers).
-
-color1(Color,[]) -> Color;
-color1(Color,[{_,C}|Layers]) -> color1(alpha_blend(Color,C),Layers).
-
-modify_layers(Layers,[]) -> Layers;
-modify_layers(Layers,[{{_,Z,start},C}|Trans]) ->
- modify_layers(add_layer(Layers, Z, C), Trans);
-modify_layers(Layers,[{{_,Z,stop },C}|Trans]) ->
- modify_layers(remove_layer(Layers, Z, C), Trans).
-
-add_layer([{Z1,_}=H|Layers],Z,C) when Z1 > Z ->
- [H|add_layer(Layers,Z,C)];
-add_layer(Layers,Z,C) ->
- [{Z,C}|Layers].
-
-remove_layer(Layers,Z,C) ->
- Layers -- [{Z,C}].
-
-alpha_blend({R1,G1,B1,A1}, {R2,G2,B2,A2}) when is_float(A1), is_float(A2)->
- Beta = A2*(1.0 - A1),
- A = A1 + Beta,
- R = R1*A1 + R2*Beta,
- G = G1*A1 + G2*Beta,
- B = B1*A1 + B2*Beta,
- {R,G,B,A}.
-
-parse_objects_on_line(Y, Width, Objects) ->
- parse_objects_on_line(Y, 1, Width, Objects, []).
-parse_objects_on_line(_Y, _Z, _, [], Out) -> lists:flatten(Out);
-parse_objects_on_line(Y, Z, Width, [O|Os], Out) ->
- case is_object_on_line(O, Y) of
- false ->
- parse_objects_on_line(Y, Z + 1, Width, Os, Out);
- true ->
- OLs = object_line_data(O,Y,Z),
- TOLs = trim_object_line_data(OLs, Width),
- parse_objects_on_line(Y, Z + 1, Width, Os, [TOLs|Out])
- end.
-
-trim_object_line_data(OLs, Width) ->
- trim_object_line_data(OLs, Width, []).
-trim_object_line_data([], _, Out) -> Out;
-
-trim_object_line_data([{_, Xl, _, _}|OLs], Width, Out) when Xl > Width ->
- trim_object_line_data(OLs, Width, Out);
-trim_object_line_data([{_, _, Xr, _}|OLs], Width, Out) when Xr < 0 ->
- trim_object_line_data(OLs, Width, Out);
-trim_object_line_data([{Z, Xl, Xr, C}|OLs], Width, Out) ->
- trim_object_line_data(OLs, Width, [{Z, erlang:max(0,Xl), erlang:min(Xr,Width), C}|Out]).
-
-% object_line_data
-% In:
-% Object :: image_object()
-% Y :: index of height
-% Z :: index of depth
-% Out:
-% OLs = [{Z, Xl, Xr, Color}]
-% Z = index of height
-% Xl = left X index
-% Xr = right X index
-% Purpose:
-% Calculate the length (start and finish index) of an objects horizontal
-% line given the height index.
-
-object_line_data(#image_object{type=rectangle,
- span={X0,Y0,X1,Y1}, color=C}, Y, Z) ->
- if
- Y0 =:= Y ; Y1 =:= Y ->
- [{Z, X0, X1, C}];
- true ->
- [{Z, X0, X0, C},
- {Z, X1, X1, C}]
- end;
-
-object_line_data(#image_object{type=filled_rectangle,
- span={X0, _, X1, _}, color=C}, _Y, Z) ->
- [{Z, X0, X1, C}];
-
-object_line_data(#image_object{type=filled_ellipse,
- internals={Xr,Yr,Yr2}, span={X0,Y0,X1,Y1}, color=C}, Y, Z) ->
- if
- X1 - X0 =:= 0; Y1 - Y0 =:= 0 ->
- [{Z, X0, X1, C}];
- true ->
- Yo = trunc(Y - Y0 - Yr),
- Yo2 = Yo*Yo,
- Xo = math:sqrt((1 - Yo2/Yr2))*Xr,
- [{Z, round(X0 - Xo + Xr), round(X0 + Xo + Xr), C}]
- end;
-
-object_line_data(#image_object{type=filled_triangle,
- intervals=Is, color=C}, Y, Z) ->
- case lists:keyfind(Y, 1, Is) of
- {Y, Xl, Xr} -> [{Z, Xl, Xr, C}];
- false -> []
- end;
-
-object_line_data(#image_object{type=line,
- intervals=M, color={R,G,B,_}}, Y, Z) ->
- case M of
- #{Y := Ls} -> [{Z, Xl, Xr, {R,G,B,1.0-C/255}}||{Xl,Xr,C} <- Ls];
- _ -> []
- end;
-
-object_line_data(#image_object{type=polygon,
- color=C, intervals=Is}, Y, Z) ->
- [{Z, Xl, Xr, C} || {Yp, Xl, Xr} <- Is, Yp =:= Y];
-
-object_line_data(#image_object{type=text_horizontal,
- color=C, intervals=Is}, Y, Z) ->
- [{Z, Xl, Xr, C} || {Yg, Xl, Xr} <- Is, Yg =:= Y];
-
-object_line_data(#image_object{type=pixel,
- span={X0,_,X1,_}, color=C}, _, Z) ->
- [{Z, X0, X1, C}].
-
-is_object_on_line(#image_object{span={_,Y0,_,Y1}}, Y) ->
- if Y < Y0; Y > Y1 -> false;
- true -> true
- end.
-
-%%% primitives to line_spans
-
-%% compile objects to linespans
-
-precompile(#image{objects = Os}=I) ->
- I#image{objects = precompile_objects(Os)}.
-
-precompile_objects([]) -> [];
-precompile_objects([#image_object{type=line, internals=W, points=[P0,P1]}=O|Os]) ->
- [O#image_object{intervals = linespans_to_map(line_to_linespans(P0,P1,W))}|precompile_objects(Os)];
-precompile_objects([#image_object{type=filled_triangle, points=[P0,P1,P2]}=O|Os]) ->
- [O#image_object{intervals = triangle_ls(P0,P1,P2)}|precompile_objects(Os)];
-precompile_objects([#image_object{type=polygon, points=Pts}=O|Os]) ->
- [O#image_object{intervals = polygon_ls(Pts)}|precompile_objects(Os)];
-precompile_objects([#image_object{type=filled_ellipse, span={X0,Y0,X1,Y1}}=O|Os]) ->
- Xr = (X1 - X0)/2,
- Yr = (Y1 - Y0)/2,
- Yr2 = Yr*Yr,
- [O#image_object{internals={Xr,Yr,Yr2}}|precompile_objects(Os)];
-precompile_objects([#image_object{type=arc, points=[P0,P1], internals=D}=O|Os]) ->
- Es = egd_primitives:arc_to_edges(P0, P1, D),
- Ls = lists:foldl(fun ({Ep0,Ep1},M) ->
- linespans_to_map(line_to_linespans(Ep0,Ep1,1),M)
- end, #{}, Es),
- [O#image_object{type=line, intervals=Ls}|precompile_objects(Os)];
-precompile_objects([#image_object{type=text_horizontal,
- points=[P0], internals={Font,Text}}=O|Os]) ->
- [O#image_object{intervals=text_horizontal_ls(P0,Font,Text)}|precompile_objects(Os)];
-precompile_objects([O|Os]) ->
- [O|precompile_objects(Os)].
-
-% triangle
-
-triangle_ls(P1,P2,P3) ->
- % Find top point (or left most top point),
- % From that point, two lines will be drawn to the
- % other points.
- % For each Y step,
- % bresenham_line_interval for each of the two lines
- % Find the left most and the right most for those lines
- % At an end point, a new line to the point already being drawn
- % repeat same procedure as above
- [Sp1, Sp2, Sp3] = tri_pt_ysort([P1,P2,P3]),
- triangle_ls_lp(tri_ls_ysort(line_to_linespans(Sp1,Sp2,1)), Sp2,
- tri_ls_ysort(line_to_linespans(Sp1,Sp3,1)), Sp3, []).
-
-% There will be Y mismatches between the two lists since bresenham is not perfect.
-% I can be remedied with checking intervals this could however be costly and
-% it may not be necessary, depending on how exact we need the points to be.
-% It should at most differ by one and endpoints should be fine.
-
-triangle_ls_lp([],_,[],_,Out) -> Out;
-triangle_ls_lp(LSs1, P1, [], P2, Out) ->
- SLSs = tri_ls_ysort(line_to_linespans(P2,P1,1)),
- N2 = length(SLSs),
- N1 = length(LSs1),
- if
- N1 > N2 ->
- [_|ILSs] = LSs1,
- triangle_ls_lp(ILSs, SLSs, Out);
- N2 > N1 ->
- [_|ILSs] = SLSs,
- triangle_ls_lp(LSs1, ILSs, Out);
- true ->
- triangle_ls_lp(LSs1, SLSs, Out)
- end;
-triangle_ls_lp([], P1, LSs2, P2, Out) ->
- SLSs = tri_ls_ysort(line_to_linespans(P1,P2,1)),
- N1 = length(SLSs),
- N2 = length(LSs2),
- if
- N1 > N2 ->
- [_|ILSs] = SLSs,
- triangle_ls_lp(ILSs, LSs2, Out);
- N2 > N1 ->
- [_|ILSs] = LSs2,
- triangle_ls_lp(SLSs, ILSs, Out);
- true ->
- triangle_ls_lp(SLSs, LSs2, Out)
- end;
-triangle_ls_lp([LS1|LSs1],P1,[LS2|LSs2],P2, Out) ->
- {Y, Xl1, Xr1,_Ca1} = LS1,
- {_, Xl2, Xr2,_Ca2} = LS2,
- Xr = lists:max([Xl1,Xr1,Xl2,Xr2]),
- Xl = lists:min([Xl1,Xr1,Xl2,Xr2]),
- triangle_ls_lp(LSs1,P1,LSs2,P2,[{Y,Xl,Xr}|Out]).
-
-triangle_ls_lp([],[],Out) -> Out;
-triangle_ls_lp([],_,Out) -> Out;
-triangle_ls_lp(_,[],Out) -> Out;
-triangle_ls_lp([LS1|LSs1], [LS2|LSs2], Out) ->
- {Y, Xl1, Xr1, _Ca1} = LS1,
- {_, Xl2, Xr2, _Ca2} = LS2,
- Xr = lists:max([Xl1,Xr1,Xl2,Xr2]),
- Xl = lists:min([Xl1,Xr1,Xl2,Xr2]),
- triangle_ls_lp(LSs1,LSs2,[{Y,Xl,Xr}|Out]).
-
-tri_pt_ysort(Pts) ->
- % {X,Y}
- lists:sort(
- fun ({_,Y1},{_,Y2}) ->
- if Y1 > Y2 -> false; true -> true end
- end, Pts).
-
-tri_ls_ysort(LSs) ->
- % {Y, Xl, Xr, Ca}
- lists:sort(
- fun ({Y1,_,_,_},{Y2,_,_,_}) ->
- if Y1 > Y2 -> false; true -> true end
- end, LSs).
-
-% polygon_ls
-% In:
-% Pts :: [{X,Y}]
-% Out:
-% LSs :: [{Y,Xl,Xr}]
-% Purpose:
-% Make polygon line spans
-% Algorithm:
-% 1. Find the left most (lm) point
-% 2. Find the two points adjacent to that point
-% The tripplet will make a triangle
-% 3. Ensure no points lies within the triangle
-% 4a.No points within triangle,
-% make triangle,
-% remove lm point
-% 1.
-% 4b.point(s) within triangle,
-%
-
-
-polygon_ls(Pts) ->
- % Make triangles
- Tris = polygon_tri(Pts),
- % interval triangles
- lists:flatten(polygon_tri_ls(Tris, [])).
-
-polygon_tri_ls([], Out) -> Out;
-polygon_tri_ls([{P1,P2,P3}|Tris], Out) ->
- polygon_tri_ls(Tris, [triangle_ls(P1,P2,P3)|Out]).
-
-polygon_tri(Pts) ->
- polygon_tri(polygon_lm_pt(Pts), []).
-
-
-polygon_tri([P1,P2,P3],Tris) -> [{P1,P2,P3}|Tris];
-polygon_tri([P2,P1,P3|Pts], Tris) ->
- case polygon_tri_test(P1,P2,P3,Pts) of
- false -> polygon_tri(polygon_lm_pt([P2,P3|Pts]), [{P1,P2,P3}|Tris]);
- [LmPt|Ptsn] -> polygon_tri([P2,P1,LmPt,P3|Ptsn], Tris)
- end.
-
-polygon_tri_test(P1,P2,P3, Pts) ->
- polygon_tri_test(P1,P2,P3, Pts, []).
-
-polygon_tri_test(_,_,_, [], _) -> false;
-polygon_tri_test(P1,P2,P3,[Pt|Pts], Ptsr) ->
- case point_inside_triangle(Pt, P1,P2,P3) of
- false -> polygon_tri_test(P1,P2,P3, Pts, [Pt|Ptsr]);
- true -> [Pt|Pts] ++ lists:reverse(Ptsr)
- end.
-
-% polygon_lm_pt
-% In:
-% Pts :: [{X,Y}]
-% Out
-% LmPts = [{X0,Y0},{Xmin,Y0},{X1,Y1},...]
-% Purpose:
-% The order of the list is important
-% rotate the elements until Xmin is first
-% This is not extremly fast.
-
-polygon_lm_pt(Pts) ->
- Xs = [X||{X,_}<-Pts],
- polygon_lm_pt(Pts, lists:min(Xs), []).
-
-polygon_lm_pt([Pt0,{X,_}=Ptm | Pts], Xmin, Ptsr) when X > Xmin ->
- polygon_lm_pt([Ptm|Pts], Xmin, [Pt0|Ptsr]);
-polygon_lm_pt(Pts, _, Ptsr) ->
- Pts ++ lists:reverse(Ptsr).
-
-
-% return true if P is inside triangle (p1,p2,p3),
-% otherwise false.
-
-points_same_side({P1x,P1y}, {P2x,P2y}, {L1x,L1y}, {L2x,L2y}) ->
- ((P1x - L1x)*(L2y - L1y) - (L2x - L1x)*(P1y - L1y) *
- (P2x - L1x)*(L2y - L1y) - (L2x - L1x)*(P2y - L1y)) >= 0.
-
-point_inside_triangle(P, P1, P2, P3) ->
- points_same_side(P, P1, P2, P3) and
- points_same_side(P, P2, P1, P3) and
- points_same_side(P, P3, P1, P2).
-
-%% [{Y, Xl, Xr}] -> #{Y := [{Xl,Xr}]}
-%% Reorganize linspans to a map with Y as key.
-
-linespans_to_map(Ls) ->
- linespans_to_map(Ls,#{}).
-linespans_to_map([{Y,Xl,Xr,C}|Ls], M) ->
- case M of
- #{Y := Spans} -> linespans_to_map(Ls, M#{Y := [{Xl,Xr,C}|Spans]});
- _ -> linespans_to_map(Ls, M#{Y => [{Xl,Xr,C}]})
- end;
-linespans_to_map([], M) ->
- M.
-
-
-%% line_to_linespans
-%% Anti-aliased thick line
-%% Do it CPS style
-%% In:
-%% P1 :: point()
-%% P2 :: point()
-%% Out:
-%% [{Y,Xl,Xr}]
-%%
-line_to_linespans({X0,Y0},{X1,Y1},Wd) ->
- Dx = abs(X1-X0),
- Dy = abs(Y1-Y0),
- Sx = if X0 < X1 -> 1; true -> -1 end,
- Sy = if Y0 < Y1 -> 1; true -> -1 end,
- E0 = Dx - Dy,
- Ed = if Dx + Dy =:= 0 -> 1; true -> math:sqrt(Dx*Dx + Dy*Dy) end,
- line_to_ls(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E0,Ed,(Wd+1)/2,[]).
-
-line_to_ls(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0) ->
- C = max(0, 255*(abs(E - Dx+Dy)/Ed - Wd + 1)),
- Ls1 = [{Y0,X0,X0,C}|Ls0],
- line_to_ls_sx(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls1,E).
-
-line_to_ls_sx(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2) when 2*E2 > -Dx ->
- line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2+Dy,Y0);
-line_to_ls_sx(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2) ->
- line_to_ls_sy(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2,X0).
-
-line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,E2,Y) when E2 < Ed*Wd andalso
- (Y1 =/= Y orelse Dx > Dy) ->
- Y2 = Y + Sy,
- C = max(0,255*(abs(E2)/Ed-Wd+1)),
- Ls = [{Y2,X0,X0,C}|Ls0],
- line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2+Dx,Y2);
-line_to_ls_sx_do(X0,_Y0,X1,_Y1,_Dx,_Dy,_Sx,_Sy,_E,_Ed,_Wd,Ls,_E2,_Y) when X0 =:= X1 ->
- Ls;
-line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,_E2,_Y) ->
- line_to_ls_sy(X0+Sx,Y0,X1,Y1,Dx,Dy,Sx,Sy,E-Dy,Ed,Wd,Ls,E,X0).
-
-line_to_ls_sy(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,E2,X) when 2*E2 =< Dy ->
- line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,Dx-E2,X);
-line_to_ls_sy(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,_E2,_X) ->
- line_to_ls(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0).
-
-line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,E2,X) when E2 < Ed*Wd andalso
- (X1 =/= X orelse Dx < Dy) ->
- X2 = X + Sx,
- C = max(0,255*(abs(E2)/Ed-Wd+1)),
- Ls = [{Y0,X2,X2,C}|Ls0],
- line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2+Dy,X2);
-line_to_ls_sy_do(_X0,Y0,_X1,Y1,_Dx,_Dy,_Sx,_Sy,_E,_Ed,_Wd,Ls,_E2,_X) when Y0 =:= Y1 ->
- Ls;
-line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,_E2,_X) ->
- line_to_ls(X0,Y0+Sy,X1,Y1,Dx,Dy,Sx,Sy,E+Dx,Ed,Wd,Ls0).
-
-% Text
-
-text_horizontal_ls(Point, Font, Chars) ->
- {_Fw,Fh} = egd_font:size(Font),
- text_intervals(Point, Fh, Font, Chars, []).
-
-% This is stupid. The starting point is the top left (Ptl) but the font
-% offsets is relative to the bottom right origin,
-% {Xtl,Ytl} -------------------------
-% | |
-% | Glyph BoundingBox |
-% | -------- |
-% | |Bitmap| Gh |
-% FH |-Gx0-|Data | |
-% | -------- |
-% | | |
-% | Gy0 |
-% | | |
-% Glyph (0,0)------------------------- Gxm (Glyph X move)
-% FW
-% Therefore, we need Yo, which is Yo = FH - Gy0 - Gh,
-% Font height minus Glyph Y offset minus Glyph bitmap data boundingbox
-% height.
-
-text_intervals( _, _, _, [], Out) -> lists:flatten(Out);
-text_intervals({Xtl,Ytl}, Fh, Font, [Code|Chars], Out) ->
- {{_Gw, Gh, Gx0, Gy0, Gxm}, LSs} = egd_font:glyph(Font, Code),
- % Set offset points from translation matrix to point in TeInVe.
- Yo = Fh - Gh + Gy0,
- GLSs = text_intervals_vertical({Xtl+Gx0,Ytl+Yo},LSs, []),
- text_intervals({Xtl+Gxm,Ytl}, Fh, Font, Chars, [GLSs|Out]).
-
-text_intervals_vertical( _, [], Out) -> Out;
-text_intervals_vertical({Xtl, Ytl}, [LS|LSs], Out) ->
- H = lists:foldl(
- fun ({Xl,Xr}, RLSs) ->
- [{Ytl, Xl + Xtl, Xr + Xtl}|RLSs]
- end, [], LS),
- text_intervals_vertical({Xtl, Ytl+1}, LSs, [H|Out]).
-
-
-%%% E. PostScript implementation
-
-eps(#image{ objects = Os, width = W, height = H}) ->
- list_to_binary([eps_header(W,H),eps_objects(H,Os),eps_footer()]).
-
-eps_objects(H,Os) -> eps_objects(H,Os, []).
-eps_objects(_,[], Out) -> lists:flatten(Out);
-eps_objects(H,[O|Os], Out) -> eps_objects(H,Os, [eps_object(H,O)|Out]).
-
-eps_object(H,#image_object{ type = text_horizontal, internals = {_Font,Text}, points = [{X,Y}], color={R,G,B,_}}) ->
- s("/Times-Roman findfont\n14 scalefont\nsetfont\n~.4f ~.4f ~.4f setrgbcolor\nnewpath\n~p ~p moveto\n(~s) show~n",
- [R,G,B,X,H-(Y + 10), Text]);
-eps_object(H,#image_object{ type = filled_ellipse, points = [{X1,Y1p},{X2,Y2p}], color={R,G,B,_}}) ->
- Y1 = H - Y1p,
- Y2 = H - Y2p,
- Xr = trunc((X2-X1)/2),
- Yr = trunc((Y2-Y1)/2),
- Cx = X1 + Xr,
- Cy = Y1 + Yr,
- s("~.4f ~.4f ~.4f setrgbcolor\nnewpath\n~p ~p ~p ~p 0 360 ellipse fill\n",
- [R,G,B,Cx,Cy,Xr,Yr]);
-eps_object(H,#image_object{ type = arc, points = [P0, P1], internals = D, color={R,G,B,_}}) ->
- Es = egd_primitives:arc_to_edges(P0, P1, D),
- [s("~.4f ~.4f ~.4f setrgbcolor\n", [R,G,B])|lists:foldl(fun
- ({{X1,Y1},{X2,Y2}}, Eps) ->
- [s("newpath\n~p ~p moveto\n~p ~p lineto\n1 setlinewidth\nstroke\n", [X1,H-Y1,X2,H-Y2])|Eps]
- end, [], Es)];
-
-eps_object(H,#image_object{ type = line, points = [{X1,Y1}, {X2,Y2}], color={R,G,B,_}}) ->
- s("~.4f ~.4f ~.4f setrgbcolor\nnewpath\n~p ~p moveto\n~p ~p lineto\n1 setlinewidth\nstroke\n",
- [R,G,B,X1,H-Y1,X2,H-Y2]);
-eps_object(H,#image_object{ type = rectangle, points = [{X1,Y1}, {X2,Y2}], color={R,G,B,_}}) ->
- s("~.4f ~.4f ~.4f setrgbcolor\nnewpath\n~p ~p moveto\n~p ~p lineto\n~p ~p lineto\n~p ~p lineto\n~p ~p lineto\n1 setlinewidth\nstroke\n",
- [R,G,B,X1,H-Y1,X2,H-Y1,X2,H-Y2,X1,H-Y2,X1,H-Y1]);
-eps_object(H,#image_object{ type = filled_rectangle, points = [{X1,Y1}, {X2,Y2}], color={R,G,B,_}}) ->
- s("~.4f ~.4f ~.4f setrgbcolor\nnewpath\n~p ~p moveto\n~p ~p lineto\n~p ~p lineto\n~p ~p lineto\n~p ~p lineto\nclosepath\nfill\n",
- [R,G,B,X1,H-Y1,X2,H-Y1,X2,H-Y2,X1,H-Y2,X1,H-Y1]);
-eps_object(_,_) -> "".
-
-s(Format, Terms) -> lists:flatten(io_lib:format(Format, Terms)).
-
-eps_header(W,H) ->
- s("%!PS-Adobe-3.0 EPSF-3.0\n%%Creator: Created by egd\n%%BoundingBox: 0 0 ~p ~p\n%%LanguageLevel: 2\n%%Pages: 1\n%%DocumentData: Clean7Bit\n",[W,H]) ++
- "%%BeginProlog\n/ellipse {7 dict begin\n/endangle exch def\n/startangle exch def\n/yradius exch def\n/xradius exch def\n/yC exch def\n/xC exch def\n"
- "/savematrix matrix currentmatrix def\nxC yC translate\nxradius yradius scale\n0 0 1 startangle endangle arc\nsavematrix setmatrix\nend\n} def\n"
- "%%EndProlog\n".
-
-eps_footer() ->
- "%%EOF\n".
diff --git a/lib/percept/src/percept.app.src b/lib/percept/src/percept.app.src
deleted file mode 100644
index 1749730f97..0000000000
--- a/lib/percept/src/percept.app.src
+++ /dev/null
@@ -1,45 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-{application,percept, [
- {description, "PERCEPT Erlang Concurrency Profiling Tool"},
- {vsn, "%VSN%"},
- {modules, [
- egd,
- egd_font,
- egd_png,
- egd_primitives,
- egd_render,
- percept,
- percept_analyzer,
- percept_db,
- percept_graph,
- percept_html,
- percept_image
- ]},
- {registered, [percept_db,percept_port]},
- {applications, [kernel,stdlib]},
- {env,[]},
- {runtime_dependencies, ["stdlib-2.0","runtime_tools-1.8.14","kernel-3.0",
- "inets-5.10","erts-6.0"]}
-]}.
-
-
-%% vim: syntax=erlang
diff --git a/lib/percept/src/percept.erl b/lib/percept/src/percept.erl
deleted file mode 100644
index 046e0b7518..0000000000
--- a/lib/percept/src/percept.erl
+++ /dev/null
@@ -1,337 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% @doc Percept - Erlang Concurrency Profiling Tool
-%%
-%% This module provides the user interface for the application.
-%%
-
--module(percept).
--behaviour(application).
--export([profile/1,
- profile/2,
- profile/3,
- stop_profile/0,
- start_webserver/0,
- start_webserver/1,
- stop_webserver/0,
- stop_webserver/1,
- analyze/1,
- % Application behaviour
- start/2,
- stop/1]).
-
-
--include("percept.hrl").
-
-%%==========================================================================
-%% Type definitions
-%%==========================================================================
-
-%% @type percept_option() = procs | ports | exclusive
-
--type percept_option() :: 'procs' | 'ports' | 'exclusive' | 'scheduler'.
-
-%%==========================================================================
-%% Application callback functions
-%%==========================================================================
-
-%% @spec start(Type, Args) -> {started, Hostname, Port} | {error, Reason}
-%% @doc none
-%% @hidden
-
-start(_Type, _Args) ->
- %% start web browser service
- start_webserver(0).
-
-%% @spec stop(State) -> ok
-%% @doc none
-%% @hidden
-
-stop(_State) ->
- %% stop web browser service
- stop_webserver(0).
-
-%%==========================================================================
-%% Interface functions
-%%==========================================================================
-
-%% @spec profile(Filename::string()) -> {ok, Port} | {already_started, Port}
-%% @see percept_profile
-
-%% profiling
-
--spec profile(Filename :: file:filename()) ->
- {'ok', port()} | {'already_started', port()}.
-
-profile(Filename) ->
- percept_profile:start(Filename, [procs]).
-
-%% @spec profile(Filename::string(), [percept_option()]) -> {ok, Port} | {already_started, Port}
-%% @see percept_profile
-
--spec profile(Filename :: file:filename(),
- Options :: [percept_option()]) ->
- {'ok', port()} | {'already_started', port()}.
-
-profile(Filename, Options) ->
- percept_profile:start(Filename, Options).
-
-%% @spec profile(Filename::string(), MFA::mfa(), [percept_option()]) -> ok | {already_started, Port} | {error, not_started}
-%% @see percept_profile
-
--spec profile(Filename :: file:filename(),
- Entry :: {atom(), atom(), list()},
- Options :: [percept_option()]) ->
- 'ok' | {'already_started', port()} | {'error', 'not_started'}.
-
-profile(Filename, MFA, Options) ->
- percept_profile:start(Filename, MFA, Options).
-
--spec stop_profile() -> 'ok' | {'error', 'not_started'}.
-
-%% @spec stop_profile() -> ok | {'error', 'not_started'}
-%% @see percept_profile
-
-stop_profile() ->
- percept_profile:stop().
-
-%% @spec analyze(string()) -> ok | {error, Reason}
-%% @doc Analyze file.
-
--spec analyze(Filename :: file:filename()) ->
- 'ok' | {'error', any()}.
-
-analyze(Filename) ->
- case percept_db:start() of
- {started, DB} ->
- parse_and_insert(Filename,DB);
- {restarted, DB} ->
- parse_and_insert(Filename,DB)
- end.
-
-%% @spec start_webserver() -> {started, Hostname, Port} | {error, Reason}
-%% Hostname = string()
-%% Port = integer()
-%% Reason = term()
-%% @doc Starts webserver.
-
--spec start_webserver() ->
- {'started', string(), pos_integer()} | {'error', any()}.
-
-start_webserver() ->
- start_webserver(0).
-
-%% @spec start_webserver(integer()) -> {started, Hostname, AssignedPort} | {error, Reason}
-%% Hostname = string()
-%% AssignedPort = integer()
-%% Reason = term()
-%% @doc Starts webserver. If port number is 0, an available port number will
-%% be assigned by inets.
-
--spec start_webserver(Port :: non_neg_integer()) ->
- {'started', string(), pos_integer()} | {'error', any()}.
-
-start_webserver(Port) when is_integer(Port) ->
- ok = ensure_loaded(percept),
- case whereis(percept_httpd) of
- undefined ->
- {ok, Config} = get_webserver_config("percept", Port),
- ok = application:ensure_started(inets),
- case inets:start(httpd, Config) of
- {ok, Pid} ->
- AssignedPort = find_service_port_from_pid(inets:services_info(), Pid),
- {ok, Host} = inet:gethostname(),
- %% workaround until inets can get me a service from a name.
- Mem = spawn(fun() -> service_memory({Pid,AssignedPort,Host}) end),
- register(percept_httpd, Mem),
- {started, Host, AssignedPort};
- {error, Reason} ->
- {error, {inets, Reason}}
- end;
- _ ->
- {error, already_started}
- end.
-
-%% @spec stop_webserver() -> ok | {error, not_started}
-%% @doc Stops webserver.
-
-stop_webserver() ->
- case whereis(percept_httpd) of
- undefined ->
- {error, not_started};
- Pid ->
- do_stop([], Pid)
- end.
-
-do_stop([], Pid)->
- Pid ! {self(), get_port},
- Port = receive P -> P end,
- do_stop(Port, Pid);
-do_stop(Port, [])->
- case whereis(percept_httpd) of
- undefined ->
- {error, not_started};
- Pid ->
- do_stop(Port, Pid)
- end;
-do_stop(Port, Pid)->
- case find_service_pid_from_port(inets:services_info(), Port) of
- undefined ->
- {error, not_started};
- Pid2 ->
- Pid ! quit,
- inets:stop(httpd, Pid2)
- end.
-
-%% @spec stop_webserver(integer()) -> ok | {error, not_started}
-%% @doc Stops webserver of the given port.
-%% @hidden
-
-stop_webserver(Port) ->
- do_stop(Port,[]).
-
-%%==========================================================================
-%% Auxiliary functions
-%%==========================================================================
-
-%% parse_and_insert
-
-parse_and_insert(Filename, DB) ->
- io:format("Parsing: ~p ~n", [Filename]),
- T0 = erlang:monotonic_time(milli_seconds),
- Pid = dbg:trace_client(file, Filename, mk_trace_parser(self())),
- Ref = erlang:monitor(process, Pid),
- parse_and_insert_loop(Filename, Pid, Ref, DB, T0).
-
-parse_and_insert_loop(Filename, Pid, Ref, DB, T0) ->
- receive
- {'DOWN',Ref,process, Pid, noproc} ->
- io:format("Incorrect file or malformed trace file: ~p~n", [Filename]),
- {error, file};
- {parse_complete, {Pid, Count}} ->
- receive {'DOWN', Ref, process, Pid, normal} -> ok after 0 -> ok end,
- DB ! {action, consolidate},
- T1 = erlang:monotonic_time(milli_seconds),
- io:format("Parsed ~w entries in ~w ms.~n", [Count, T1 - T0]),
- io:format(" ~p created processes.~n", [length(percept_db:select({information, procs}))]),
- io:format(" ~p opened ports.~n", [length(percept_db:select({information, ports}))]),
- ok;
- {'DOWN',Ref, process, Pid, normal} -> parse_and_insert_loop(Filename, Pid, Ref, DB, T0);
- {'DOWN',Ref, process, Pid, Reason} -> {error, Reason}
- end.
-
-mk_trace_parser(Pid) ->
- {fun trace_parser/2, {0, Pid}}.
-
-trace_parser(end_of_trace, {Count, Pid}) ->
- Pid ! {parse_complete, {self(),Count}},
- receive
- {ack, Pid} ->
- ok
- end;
-trace_parser(Trace, {Count, Pid}) ->
- percept_db:insert(Trace),
- {Count + 1, Pid}.
-
-find_service_pid_from_port([], _) ->
- undefined;
-find_service_pid_from_port([{_, Pid, Options} | Services], Port) ->
- case lists:keyfind(port, 1, Options) of
- false ->
- find_service_pid_from_port(Services, Port);
- {port, Port} ->
- Pid
- end.
-
-find_service_port_from_pid([], _) ->
- undefined;
-find_service_port_from_pid([{_, Pid, Options} | _], Pid) ->
- case lists:keyfind(port, 1, Options) of
- false ->
- undefined;
- {port, Port} ->
- Port
- end;
-find_service_port_from_pid([{_, _, _} | Services], Pid) ->
- find_service_port_from_pid(Services, Pid).
-
-%% service memory
-
-service_memory({Pid, Port, Host}) ->
- receive
- quit ->
- ok;
- {Reply, get_port} ->
- Reply ! Port,
- service_memory({Pid, Port, Host});
- {Reply, get_host} ->
- Reply ! Host,
- service_memory({Pid, Port, Host});
- {Reply, get_pid} ->
- Reply ! Pid,
- service_memory({Pid, Port, Host})
- end.
-
-% Create config data for the webserver
-
-get_webserver_config(Servername, Port) when is_list(Servername), is_integer(Port) ->
- Path = code:priv_dir(percept),
- Root = filename:join([Path, "server_root"]),
- MimeTypesFile = filename:join([Root,"conf","mime.types"]),
- {ok, MimeTypes} = httpd_conf:load_mime_types(MimeTypesFile),
- Config = [
- % Roots
- {server_root, Root},
- {document_root,filename:join([Root, "htdocs"])},
-
- % Aliases
- {eval_script_alias,{"/eval",[io]}},
- {erl_script_alias,{"/cgi-bin",[percept_graph,percept_html,io]}},
- {script_alias,{"/cgi-bin/", filename:join([Root, "cgi-bin"])}},
- {alias,{"/javascript/",filename:join([Root, "scripts"]) ++ "/"}},
- {alias,{"/images/", filename:join([Root, "images"]) ++ "/"}},
- {alias,{"/css/", filename:join([Root, "css"]) ++ "/"}},
-
- % Configs
- {default_type,"text/plain"},
- {directory_index,["index.html"]},
- {mime_types, MimeTypes},
- {modules,[mod_alias,
- mod_esi,
- mod_actions,
- mod_cgi,
- mod_dir,
- mod_get,
- mod_head
- ]},
- {com_type,ip_comm},
- {server_name, Servername},
- {bind_address, any},
- {port, Port}],
- {ok, Config}.
-
-ensure_loaded(App) ->
- case application:load(App) of
- ok -> ok;
- {error,{already_loaded,App}} -> ok;
- Error -> Error
- end.
diff --git a/lib/percept/src/percept.hrl b/lib/percept/src/percept.hrl
deleted file mode 100644
index 58926cd1b4..0000000000
--- a/lib/percept/src/percept.hrl
+++ /dev/null
@@ -1,53 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
--define(seconds(EndTs,StartTs), timer:now_diff(EndTs, StartTs)/1000000).
-
-%%% ------------------- %%%
-%%% Type definitions %%%
-%%% ------------------- %%%
-
--type timestamp() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
--type true_mfa() :: {atom(), atom(), byte() | list()}.
--type state() :: 'active' | 'inactive'.
--type scheduler_id() :: {'scheduler_id', non_neg_integer()}.
-
-%%% ------------------- %%%
-%%% Records %%%
-%%% ------------------- %%%
-
--record(activity, {
- timestamp ,%:: timestamp() ,
- id ,%:: pid() | port() | scheduler_id(),
- state = undefined ,%:: state() | 'undefined',
- where = undefined ,%:: true_mfa() | 'undefined',
- runnable_count = 0 %:: non_neg_integer()
- }).
-
--record(information, {
- id ,%:: pid() | port(),
- name = undefined ,%:: atom() | string() | 'undefined',
- entry = undefined ,%:: true_mfa() | 'undefined',
- start = undefined ,%:: timestamp() | 'undefined',
- stop = undefined ,%:: timestamp() | 'undefined',
- parent = undefined ,%:: pid() | 'undefined',
- children = [] %:: [pid()]
- }).
-
diff --git a/lib/percept/src/percept_analyzer.erl b/lib/percept/src/percept_analyzer.erl
deleted file mode 100644
index f38d026905..0000000000
--- a/lib/percept/src/percept_analyzer.erl
+++ /dev/null
@@ -1,368 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-
-%% @doc Utility functions to operate on percept data. These functions should
-%% be considered experimental. Behaviour may change in future releases.
-
--module(percept_analyzer).
--export([
- minmax/1,
- waiting_activities/1,
- activities2count/2,
- activities2count/3,
- activities2count2/2,
- analyze_activities/2,
- runnable_count/1,
- runnable_count/2,
- seconds2ts/2,
- minmax_activities/2,
- mean/1
- ]).
-
--include("percept.hrl").
-
-%%==========================================================================
-%%
-%% Interface functions
-%%
-%%==========================================================================
-
-
-%% @spec minmax([{X, Y}]) -> {MinX, MinY, MaxX, MaxY}
-%% X = number()
-%% Y = number()
-%% MinX = number()
-%% MinY = number()
-%% MaxX = number()
-%% MaxY = number()
-%% @doc Returns the min and max of a set of 2-dimensional numbers.
-
-minmax(Data) ->
- Xs = [ X || {X,_Y} <- Data],
- Ys = [ Y || {_X, Y} <- Data],
- {lists:min(Xs), lists:min(Ys), lists:max(Xs), lists:max(Ys)}.
-
-%% @spec mean([number()]) -> {Mean, StdDev, N}
-%% Mean = float()
-%% StdDev = float()
-%% N = integer()
-%% @doc Calculates the mean and the standard deviation of a set of
-%% numbers.
-
-mean([]) -> {0, 0, 0};
-mean([Value]) -> {Value, 0, 1};
-mean(List) -> mean(List, {0, 0, 0}).
-
-mean([], {Sum, SumSquare, N}) ->
- Mean = Sum / N,
- StdDev = math:sqrt((SumSquare - Sum*Sum/N)/(N - 1)),
- {Mean, StdDev, N};
-mean([Value | List], {Sum, SumSquare, N}) ->
- mean(List, {Sum + Value, SumSquare + Value*Value, N + 1}).
-
-
-
-activities2count2(Acts, StartTs) ->
- Start = inactive_start_states(Acts),
- activities2count2(Acts, StartTs, Start, []).
-
-activities2count2([], _, _, Out) -> lists:reverse(Out);
-activities2count2([#activity{ id = Id, timestamp = Ts, state = active} | Acts], StartTs, {Proc,Port}, Out) when is_pid(Id) ->
- activities2count2(Acts, StartTs, {Proc + 1, Port}, [{?seconds(Ts, StartTs), Proc + 1, Port}|Out]);
-activities2count2([#activity{ id = Id, timestamp = Ts, state = inactive} | Acts], StartTs, {Proc,Port}, Out) when is_pid(Id) ->
- activities2count2(Acts, StartTs, {Proc - 1, Port}, [{?seconds(Ts, StartTs), Proc - 1, Port}|Out]);
-activities2count2([#activity{ id = Id, timestamp = Ts, state = active} | Acts], StartTs, {Proc,Port}, Out) when is_port(Id) ->
- activities2count2(Acts, StartTs, {Proc, Port + 1}, [{?seconds(Ts, StartTs), Proc, Port + 1}|Out]);
-activities2count2([#activity{ id = Id, timestamp = Ts, state = inactive} | Acts], StartTs, {Proc,Port}, Out) when is_port(Id) ->
- activities2count2(Acts, StartTs, {Proc, Port - 1}, [{?seconds(Ts, StartTs), Proc, Port - 1}|Out]).
-
-
-inactive_start_states(Acts) ->
- D = activity_start_states(Acts, dict:new()),
- dict:fold(fun
- (K, inactive, {Procs, Ports}) when is_pid(K) -> {Procs + 1, Ports};
- (K, inactive, {Procs, Ports}) when is_port(K) -> {Procs, Ports + 1};
- (_, _, {Procs, Ports}) -> {Procs, Ports}
- end, {0,0}, D).
-activity_start_states([], D) -> D;
-activity_start_states([#activity{id = Id, state = State}|Acts], D) ->
- case dict:is_key(Id, D) of
- true -> activity_start_states(Acts, D);
- false -> activity_start_states(Acts, dict:store(Id, State, D))
- end.
-
-
-
-
-%% @spec activities2count(#activity{}, timestamp()) -> Result
-%% Result = [{Time, ProcessCount, PortCount}]
-%% Time = float()
-%% ProcessCount = integer()
-%% PortCount = integer()
-%% @doc Calculate the resulting active processes and ports during
-%% the activity interval.
-%% Also checks active/inactive consistency.
-%% A task will always begin with an active state and end with an inactive state.
-
-activities2count(Acts, StartTs) when is_list(Acts) -> activities2count(Acts, StartTs, separated).
-
-activities2count(Acts, StartTs, Type) when is_list(Acts) -> activities2count_loop(Acts, {StartTs, {0,0}}, Type, []).
-
-activities2count_loop([], _, _, Out) -> lists:reverse(Out);
-activities2count_loop(
- [#activity{ timestamp = Ts, id = Id, runnable_count = Rc} | Acts],
- {StartTs, {Procs, Ports}}, separated, Out) ->
-
- Time = ?seconds(Ts, StartTs),
- case Id of
- Id when is_port(Id) ->
- Entry = {Time, Procs, Rc},
- activities2count_loop(Acts, {StartTs, {Procs, Rc}}, separated, [Entry | Out]);
- Id when is_pid(Id) ->
- Entry = {Time, Rc, Ports},
- activities2count_loop(Acts, {StartTs, {Rc, Ports}}, separated, [Entry | Out]);
- _ ->
- activities2count_loop(Acts, {StartTs,{Procs, Ports}}, separated, Out)
- end;
-activities2count_loop(
- [#activity{ timestamp = Ts, id = Id, runnable_count = Rc} | Acts],
- {StartTs, {Procs, Ports}}, summated, Out) ->
-
- Time = ?seconds(Ts, StartTs),
- case Id of
- Id when is_port(Id) ->
- Entry = {Time, Procs + Rc},
- activities2count_loop(Acts, {StartTs, {Procs, Rc}}, summated, [Entry | Out]);
- Id when is_pid(Id) ->
- Entry = {Time, Rc + Ports},
- activities2count_loop(Acts, {StartTs, {Rc, Ports}}, summated, [Entry | Out])
- end.
-
-%% @spec waiting_activities([#activity{}]) -> FunctionList
-%% FunctionList = [{Seconds, Mfa, {Mean, StdDev, N}}]
-%% Seconds = float()
-%% Mfa = mfa()
-%% Mean = float()
-%% StdDev = float()
-%% N = integer()
-%% @doc Calculates the time, both average and total, that a process has spent
-%% in a receive state at specific function. However, if there are multiple receives
-%% in a function it cannot differentiate between them.
-
-waiting_activities(Activities) ->
- ListedMfas = waiting_activities_mfa_list(Activities, []),
- Unsorted = lists:foldl(
- fun (Mfa, MfaList) ->
- {Total, WaitingTimes} = get({waiting_mfa, Mfa}),
-
- % cleanup
- erlang:erase({waiting_mfa, Mfa}),
-
- % statistics of receive waiting places
- Stats = mean(WaitingTimes),
-
- [{Total, Mfa, Stats} | MfaList]
- end, [], ListedMfas),
- lists:sort(fun ({A,_,_},{B,_,_}) ->
- if
- A > B -> true;
- true -> false
- end
- end, Unsorted).
-
-
-%% Generate lists of receive waiting times per mfa
-%% Out:
-%% ListedMfas = [mfa()]
-%% Intrisnic:
-%% get({waiting, mfa()}) ->
-%% [{waiting, mfa()}, {Total, [WaitingTime]})
-%% WaitingTime = float()
-
-waiting_activities_mfa_list([], ListedMfas) -> ListedMfas;
-waiting_activities_mfa_list([Activity|Activities], ListedMfas) ->
- #activity{id = Pid, state = Act, timestamp = Time, where = MFA} = Activity,
- case Act of
- active ->
- waiting_activities_mfa_list(Activities, ListedMfas);
- inactive ->
- % Want to know how long the wait is in a receive,
- % it is given via the next activity
- case Activities of
- [] ->
- [Info] = percept_db:select(information, Pid),
- case Info#information.stop of
- undefined ->
- % get profile end time
- Waited = ?seconds(
- percept_db:select({system,stop_ts}),
- Time);
- Time2 ->
- Waited = ?seconds(Time2, Time)
- end,
- case get({waiting_mfa, MFA}) of
- undefined ->
- put({waiting_mfa, MFA}, {Waited, [Waited]}),
- [MFA | ListedMfas];
- {Total, TimedMfa} ->
- put({waiting_mfa, MFA}, {Total + Waited, [Waited | TimedMfa]}),
- ListedMfas
- end;
- [#activity{timestamp=Time2, id = Pid, state = active} | _ ] ->
- % Calculate waiting time
- Waited = ?seconds(Time2, Time),
- % Get previous entry
-
- case get({waiting_mfa, MFA}) of
- undefined ->
- % add entry to list
- put({waiting_mfa, MFA}, {Waited, [Waited]}),
- waiting_activities_mfa_list(Activities, [MFA|ListedMfas]);
- {Total, TimedMfa} ->
- put({waiting_mfa, MFA}, {Total + Waited, [Waited | TimedMfa]}),
- waiting_activities_mfa_list(Activities, ListedMfas)
- end;
- _ -> error
- end
- end.
-
-%% seconds2ts(Seconds, StartTs) -> TS
-%% In:
-%% Seconds = float()
-%% StartTs = timestamp()
-%% Out:
-%% TS = timestamp()
-
-%% @spec seconds2ts(float(), StartTs::{integer(),integer(),integer()}) -> timestamp()
-%% @doc Calculates a timestamp given a duration in seconds and a starting timestamp.
-
-seconds2ts(Seconds, {Ms, S, Us}) ->
- % Calculate mega seconds integer
- MsInteger = trunc(Seconds) div 1000000 ,
-
- % Calculate the reminder for seconds
- SInteger = trunc(Seconds),
-
- % Calculate the reminder for micro seconds
- UsInteger = trunc((Seconds - SInteger) * 1000000),
-
- % Wrap overflows
-
- UsOut = (UsInteger + Us) rem 1000000,
- SOut = ((SInteger + S) + (UsInteger + Us) div 1000000) rem 1000000,
- MsOut = (MsInteger+ Ms) + ((SInteger + S) + (UsInteger + Us) div 1000000) div 1000000,
-
- {MsOut, SOut, UsOut}.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% Analyze interval for concurrency
-%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% @spec analyze_activities(integer(), [#activity{}]) -> [{integer(),#activity{}}]
-%% @hidden
-
-analyze_activities(Threshold, Activities) ->
- RunnableCount = runnable_count(Activities, 0),
- analyze_runnable_activities(Threshold, RunnableCount).
-
-
-%% runnable_count(Activities, StartValue) -> RunnableCount
-%% In:
-%% Activities = [activity()]
-%% StartValue = integer()
-%% Out:
-%% RunnableCount = [{integer(), activity()}]
-%% Purpose:
-%% Calculate the runnable count of a given interval of generic
-%% activities.
-
-%% @spec runnable_count([#activity{}]) -> [{integer(),#activity{}}]
-%% @hidden
-
-runnable_count(Activities) ->
- Threshold = runnable_count_threshold(Activities),
- runnable_count(Activities, Threshold, []).
-
-runnable_count_threshold(Activities) ->
- CountedActs = runnable_count(Activities, 0),
- Counts = [C || {C, _} <- CountedActs],
- Min = lists:min(Counts),
- 0 - Min.
-%% @spec runnable_count([#activity{}],integer()) -> [{integer(),#activity{}}]
-%% @hidden
-
-runnable_count(Activities, StartCount) when is_integer(StartCount) ->
- runnable_count(Activities, StartCount, []).
-runnable_count([], _ , Out) ->
- lists:reverse(Out);
-runnable_count([A | As], PrevCount, Out) ->
- case A#activity.state of
- active ->
- runnable_count(As, PrevCount + 1, [{PrevCount + 1, A} | Out]);
- inactive ->
- runnable_count(As, PrevCount - 1, [{PrevCount - 1, A} | Out])
- end.
-
-%% In:
-%% Threshold = integer(),
-%% RunnableActivities = [{Rc, activity()}]
-%% Rc = integer()
-
-analyze_runnable_activities(Threshold, RunnableActivities) ->
- analyze_runnable_activities(Threshold, RunnableActivities, []).
-
-analyze_runnable_activities( _z, [], Out) ->
- lists:reverse(Out);
-analyze_runnable_activities(Threshold, [{Rc, Act} | RunnableActs], Out) ->
- if
- Rc =< Threshold ->
- analyze_runnable_activities(Threshold, RunnableActs, [{Rc,Act} | Out]);
- true ->
- analyze_runnable_activities(Threshold, RunnableActs, Out)
- end.
-
-%% minmax_activity(Activities, Count) -> {Min, Max}
-%% In:
-%% Activities = [activity()]
-%% InitialCount = non_neg_integer()
-%% Out:
-%% {Min, Max}
-%% Min = non_neg_integer()
-%% Max = non_neg_integer()
-%% Purpose:
-%% Minimal and maximal activity during an activity interval.
-%% Initial activity count needs to be supplied.
-
-%% @spec minmax_activities([#activity{}], integer()) -> {integer(), integer()}
-%% @doc Calculates the minimum and maximum of runnable activites (processes
-% and ports) during the interval of reffered by the activity list.
-
-minmax_activities(Activities, Count) ->
- minmax_activities(Activities, Count, {Count, Count}).
-minmax_activities([], _, Out) ->
- Out;
-minmax_activities([A|Acts], Count, {Min, Max}) ->
- case A#activity.state of
- active ->
- minmax_activities(Acts, Count + 1, {Min, lists:max([Count + 1, Max])});
- inactive ->
- minmax_activities(Acts, Count - 1, {lists:min([Count - 1, Min]), Max})
- end.
diff --git a/lib/percept/src/percept_db.erl b/lib/percept/src/percept_db.erl
deleted file mode 100644
index 6cbe3ce022..0000000000
--- a/lib/percept/src/percept_db.erl
+++ /dev/null
@@ -1,780 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-
-%%
-%% @doc Percept database.
-%%
-%%
-
--module(percept_db).
-
--export([start/0,
- stop/0,
- insert/1,
- select/2,
- select/1,
- consolidate/0]).
-
--include("percept.hrl").
--define(STOP_TIMEOUT, 1000).
-%%==========================================================================
-%% Type definitions
-%%==========================================================================
-
-%% @type activity_option() =
-%% {ts_min, timestamp()} |
-%% {ts_max, timestamp()} |
-%% {ts_exact, bool()} |
-%% {mfa, {atom(), atom(), byte()}} |
-%% {state, active | inactive} |
-%% {id, all | procs | ports | pid() | port()}
-
-%% @type scheduler_option() =
-%% {ts_min, timestamp()} |
-%% {ts_max, timestamp()} |
-%% {ts_exact, bool()} |
-%% {id, scheduler_id()}
-
-%% @type system_option() = start_ts | stop_ts
-
-%% @type information_option() =
-%% all | procs | ports | pid() | port()
-
-
-
-
-%%==========================================================================
-%% Interface functions
-%%==========================================================================
-
-%% @spec start() -> ok | {started, Pid} | {restarted, Pid}
-%% Pid = pid()
-%% @doc Starts or restarts the percept database.
-
--spec start() -> {'started', pid()} | {'restarted', pid()}.
-
-start() ->
- case erlang:whereis(percept_db) of
- undefined ->
- {started, do_start()};
- PerceptDB ->
- {restarted, restart(PerceptDB)}
- end.
-
-%% @spec restart(pid()) -> pid()
-%% @private
-%% @doc restarts the percept database.
-
--spec restart(pid())-> pid().
-
-restart(PerceptDB)->
- stop_sync(PerceptDB),
- do_start().
-
-%% @spec do_start() -> pid()
-%% @private
-%% @doc starts the percept database.
-
--spec do_start()-> pid().
-
-do_start()->
- Pid = spawn(fun() -> init_percept_db() end),
- erlang:register(percept_db, Pid),
- Pid.
-
-%% @spec stop() -> not_started | {stopped, Pid}
-%% Pid = pid()
-%% @doc Stops the percept database.
-
--spec stop() -> 'not_started' | {'stopped', pid()}.
-
-stop() ->
- case erlang:whereis(percept_db) of
- undefined ->
- not_started;
- Pid ->
- Pid ! {action, stop},
- {stopped, Pid}
- end.
-
-%% @spec stop_sync(pid()) -> true
-%% @private
-%% @doc Stops the percept database, with a synchronous call.
-
--spec stop_sync(pid()) -> true.
-
-stop_sync(Pid) ->
- MonitorRef = erlang:monitor(process, Pid),
- _ = stop(),
- receive
- {'DOWN', MonitorRef, _Type, Pid, _Info}->
- true
- after ?STOP_TIMEOUT->
- erlang:demonitor(MonitorRef, [flush]),
- exit(Pid, kill)
- end.
-
-%% @spec insert(tuple()) -> ok
-%% @doc Inserts a trace or profile message to the database.
-
-insert(Trace) ->
- percept_db ! {insert, Trace},
- ok.
-
-
-%% @spec select({atom(), Options}) -> Result
-%% @doc Synchronous call. Selects information based on a query.
-%%
-%% <p>Queries:</p>
-%% <pre>
-%% {system, Option}
-%% Option = system_option()
-%% Result = timestamp()
-%% {information, Options}
-%% Options = [information_option()]
-%% Result = [#information{}]
-%% {scheduler, Options}
-%% Options = [sceduler_option()]
-%% Result = [#activity{}]
-%% {activity, Options}
-%% Options = [activity_option()]
-%% Result = [#activity{}]
-%% </pre>
-%% <p>
-%% Note: selection of Id's are always OR all other options are considered AND.
-%% </p>
-
-select(Query) ->
- percept_db ! {select, self(), Query},
- receive {result, Match} -> Match end.
-
-%% @spec select(atom(), list()) -> Result
-%% @equiv select({Table,Options})
-
-select(Table, Options) ->
- percept_db ! {select, self(), {Table, Options}},
- receive {result, Match} -> Match end.
-
-%% @spec consolidate() -> Result
-%% @doc Checks timestamp and state-flow inconsistencies in the
-%% the database.
-
-consolidate() ->
- percept_db ! {action, consolidate},
- ok.
-
-%%==========================================================================
-%% Database loop
-%%==========================================================================
-
-init_percept_db() ->
- % Proc and Port information
- pdb_info = ets:new(pdb_info, [named_table, private, {keypos, #information.id}, set]),
-
- % Scheduler runnability
- pdb_scheduler = ets:new(pdb_scheduler, [named_table, private, {keypos, #activity.timestamp}, ordered_set]),
-
- % Process and Port runnability
- pdb_activity = ets:new(pdb_activity, [named_table, private, {keypos, #activity.timestamp}, ordered_set]),
-
- % System status
- pdb_system = ets:new(pdb_system, [named_table, private, {keypos, 1}, set]),
-
- % System warnings
- pdb_warnings = ets:new(pdb_warnings, [named_table, private, {keypos, 1}, ordered_set]),
- put(debug, 0),
- loop_percept_db().
-
-loop_percept_db() ->
- receive
- {insert, Trace} ->
- insert_trace(clean_trace(Trace)),
- loop_percept_db();
- {select, Pid, Query} ->
- Pid ! {result, select_query(Query)},
- loop_percept_db();
- {action, stop} ->
- stopped;
- {action, consolidate} ->
- consolidate_db(),
- loop_percept_db();
- {operate, Pid, {Table, {Fun, Start}}} ->
- Result = ets:foldl(Fun, Start, Table),
- Pid ! {result, Result},
- loop_percept_db();
- Unhandled ->
- io:format("loop_percept_db, unhandled query: ~p~n", [Unhandled]),
- loop_percept_db()
- end.
-
-%%==========================================================================
-%% Auxiliary functions
-%%==========================================================================
-
-%% cleans trace messages from external pids
-
-clean_trace(Trace) when is_tuple(Trace) -> list_to_tuple(clean_trace(tuple_to_list(Trace)));
-clean_trace(Trace) when is_list(Trace) -> clean_list(Trace, []);
-clean_trace(Trace) when is_pid(Trace) ->
- PidStr = pid_to_list(Trace),
- [_,P2,P3p] = string:tokens(PidStr,"."),
- P3 = lists:sublist(P3p, 1, length(P3p) - 1),
- erlang:list_to_pid("<0." ++ P2 ++ "." ++ P3 ++ ">");
-clean_trace(Trace) -> Trace.
-
-clean_list([], Out) -> lists:reverse(Out);
-clean_list([Element|Trace], Out) ->
- clean_list(Trace, [clean_trace(Element)|Out]).
-
-
-insert_trace(Trace) ->
- case Trace of
- {profile_start, Ts} ->
- update_system_start_ts(Ts),
- ok;
- {profile_stop, Ts} ->
- update_system_stop_ts(Ts),
- ok;
- %%% erlang:system_profile, option: runnable_procs
- %%% ---------------------------------------------
- {profile, Id, State, Mfa, TS} when is_pid(Id) ->
- % Update runnable count in activity and db
-
- case check_activity_consistency(Id, State) of
- invalid_state ->
- ignored;
- ok ->
- Rc = get_runnable_count(procs, State),
- % Update registered procs
- % insert proc activity
- update_activity(#activity{
- id = Id,
- state = State,
- timestamp = TS,
- runnable_count = Rc,
- where = Mfa}),
- ok
- end;
- %%% erlang:system_profile, option: runnable_ports
- %%% ---------------------------------------------
- {profile, Id, State, Mfa, TS} when is_port(Id) ->
- case check_activity_consistency(Id, State) of
- invalid_state ->
- ignored;
- ok ->
- % Update runnable count in activity and db
- Rc = get_runnable_count(ports, State),
-
- % Update registered ports
- % insert port activity
- update_activity(#activity{
- id = Id,
- state = State,
- timestamp = TS,
- runnable_count = Rc,
- where = Mfa}),
-
- ok
- end;
- %%% erlang:system_profile, option: scheduler
- {profile, scheduler, Id, State, Scheds, Ts} ->
- % insert scheduler activity
- update_scheduler(#activity{
- id = {scheduler, Id},
- state = State,
- timestamp = Ts,
- where = Scheds}),
- ok;
-
- %%% erlang:trace, option: procs
- %%% ---------------------------
- {trace_ts, Parent, spawn, Pid, Mfa, TS} ->
- InformativeMfa = mfa2informative(Mfa),
- % Update id_information
- update_information(#information{id = Pid, start = TS, parent = Parent, entry = InformativeMfa}),
- update_information_child(Parent, Pid),
- ok;
- {trace_ts, Pid, exit, _Reason, TS} ->
- % Update registered procs
-
- % Update id_information
- update_information(#information{id = Pid, stop = TS}),
-
- ok;
- {trace_ts, Pid, register, Name, _Ts} when is_pid(Pid) ->
- % Update id_information
- update_information(#information{id = Pid, name = Name}),
- ok;
- {trace_ts, Pid, register, Name, _Ts} when is_pid(Pid) ->
- % Update id_information
- update_information(#information{id = Pid, name = Name}),
- ok;
- {trace_ts, _Pid, unregister, _Name, _Ts} ->
- % Not implemented
- ok;
- {trace_ts, Pid, getting_unlinked, _Id, _Ts} when is_pid(Pid) ->
- % Update id_information
- ok;
- {trace_ts, Pid, getting_linked, _Id, _Ts} when is_pid(Pid)->
- % Update id_information
- ok;
- {trace_ts, Pid, link, _Id, _Ts} when is_pid(Pid)->
- % Update id_information
- ok;
- {trace_ts, Pid, unlink, _Id, _Ts} when is_pid(Pid) ->
- % Update id_information
- ok;
-
- %%% erlang:trace, option: ports
- %%% ----------------------------
- {trace_ts, Caller, open, Port, Driver, TS} ->
- % Update id_information
- update_information(#information{
- id = Port, entry = Driver, start = TS, parent = Caller}),
- ok;
- {trace_ts, Port, closed, _Reason, Ts} ->
- % Update id_information
- update_information(#information{id = Port, stop = Ts}),
- ok;
-
- Unhandled ->
- io:format("insert_trace, unhandled: ~p~n", [Unhandled])
- end.
-
-mfa2informative({erlang, apply, [M, F, Args]}) -> mfa2informative({M, F,Args});
-mfa2informative({erlang, apply, [Fun, Args]}) ->
- FunInfo = erlang:fun_info(Fun),
- M = case proplists:get_value(module, FunInfo, undefined) of
- [] -> undefined_fun_module;
- undefined -> undefined_fun_module;
- Module -> Module
- end,
- F = case proplists:get_value(name, FunInfo, undefined) of
- [] -> undefined_fun_function;
- undefined -> undefined_fun_function;
- Function -> Function
- end,
- mfa2informative({M, F, Args});
-mfa2informative(Mfa) -> Mfa.
-
-%% consolidate_db() -> bool()
-%% Purpose:
-%% Check start/stop time
-%% Activity consistency
-
-consolidate_db() ->
- io:format("Consolidating...~n"),
- % Check start/stop timestamps
- case select_query({system, start_ts}) of
- undefined ->
- Min = lists:min(list_all_ts()),
- update_system_start_ts(Min);
- _ -> ok
- end,
- case select_query({system, stop_ts}) of
- undefined ->
- Max = lists:max(list_all_ts()),
- update_system_stop_ts(Max);
- _ -> ok
- end,
- consolidate_runnability(),
- ok.
-
-consolidate_runnability() ->
- put({runnable, procs}, undefined),
- put({runnable, ports}, undefined),
- consolidate_runnability_loop(ets:first(pdb_activity)).
-
-consolidate_runnability_loop('$end_of_table') -> ok;
-consolidate_runnability_loop(Key) ->
- case ets:lookup(pdb_activity, Key) of
- [#activity{id = Id, state = State } = A] when is_pid(Id) ->
- Rc = get_runnable_count(procs, State),
- ets:insert(pdb_activity, A#activity{ runnable_count = Rc});
- [#activity{id = Id, state = State } = A] when is_port(Id) ->
- Rc = get_runnable_count(ports, State),
- ets:insert(pdb_activity, A#activity{ runnable_count = Rc});
- _ -> throw(consolidate)
- end,
- consolidate_runnability_loop(ets:next(pdb_activity, Key)).
-
-list_all_ts() ->
- ATs = [Act#activity.timestamp || Act <- select_query({activity, []})],
- STs = [Act#activity.timestamp || Act <- select_query({scheduler, []})],
- ITs = lists:flatten([
- [I#information.start,
- I#information.stop] ||
- I <- select_query({information, all})]),
- %% Filter out all undefined (non ts)
- [Elem || Elem = {_,_,_} <- ATs ++ STs ++ ITs].
-
-%% get_runnable_count(Type, State) -> RunnableCount
-%% In:
-%% Type = procs | ports
-%% State = active | inactive
-%% Out:
-%% RunnableCount = integer()
-%% Purpose:
-%% Keep track of the number of runnable ports and processes
-%% during the profile duration.
-
-get_runnable_count(Type, State) ->
- case {get({runnable, Type}), State} of
- {undefined, active} ->
- put({runnable, Type}, 1),
- 1;
- {N, active} ->
- put({runnable, Type}, N + 1),
- N + 1;
- {N, inactive} ->
- put({runnable, Type}, N - 1),
- N - 1;
- Unhandled ->
- io:format("get_runnable_count, unhandled ~p~n", [Unhandled]),
- Unhandled
- end.
-
-check_activity_consistency(Id, State) ->
- case get({previous_state, Id}) of
- State ->
- io:format("check_activity_consistency, state flow invalid.~n"),
- invalid_state;
- undefined when State == inactive ->
- invalid_state;
- _ ->
- put({previous_state, Id}, State),
- ok
- end.
-%%%
-%%% select_query
-%%% In:
-%%% Query = {Table, Option}
-%%% Table = system | activity | scheduler | information
-
-
-select_query(Query) ->
- case Query of
- {system, _ } ->
- select_query_system(Query);
- {activity, _ } ->
- select_query_activity(Query);
- {scheduler, _} ->
- select_query_scheduler(Query);
- {information, _ } ->
- select_query_information(Query);
- Unhandled ->
- io:format("select_query, unhandled: ~p~n", [Unhandled]),
- []
- end.
-
-%%% select_query_information
-
-select_query_information(Query) ->
- case Query of
- {information, all} ->
- ets:select(pdb_info, [{
- #information{ _ = '_'},
- [],
- ['$_']
- }]);
- {information, procs} ->
- ets:select(pdb_info, [{
- #information{ id = '$1', _ = '_'},
- [{is_pid, '$1'}],
- ['$_']
- }]);
- {information, ports} ->
- ets:select(pdb_info, [{
- #information{ id = '$1', _ = '_'},
- [{is_port, '$1'}],
- ['$_']
- }]);
- {information, Id} when is_port(Id) ; is_pid(Id) ->
- ets:select(pdb_info, [{
- #information{ id = Id, _ = '_'},
- [],
- ['$_']
- }]);
- Unhandled ->
- io:format("select_query_information, unhandled: ~p~n", [Unhandled]),
- []
- end.
-
-%%% select_query_scheduler
-
-select_query_scheduler(Query) ->
- case Query of
- {scheduler, Options} when is_list(Options) ->
- Head = #activity{
- timestamp = '$1',
- id = '$2',
- state = '$3',
- where = '$4',
- _ = '_'},
- Body = ['$_'],
- % We don't need id's
- {Constraints, _ } = activity_ms_and(Head, Options, [], []),
- ets:select(pdb_scheduler, [{Head, Constraints, Body}]);
- Unhandled ->
- io:format("select_query_scheduler, unhandled: ~p~n", [Unhandled]),
- []
- end.
-
-%%% select_query_system
-
-select_query_system(Query) ->
- case Query of
- {system, start_ts} ->
- case ets:lookup(pdb_system, {system, start_ts}) of
- [] -> undefined;
- [{{system, start_ts}, StartTS}] -> StartTS
- end;
- {system, stop_ts} ->
- case ets:lookup(pdb_system, {system, stop_ts}) of
- [] -> undefined;
- [{{system, stop_ts}, StopTS}] -> StopTS
- end;
- Unhandled ->
- io:format("select_query_system, unhandled: ~p~n", [Unhandled]),
- []
- end.
-
-%%% select_query_activity
-
-select_query_activity(Query) ->
- case Query of
- {activity, Options} when is_list(Options) ->
- case lists:member({ts_exact, true},Options) of
- true ->
- case catch select_query_activity_exact_ts(Options) of
- {'EXIT', Reason} ->
- io:format(" - select_query_activity [ catch! ]: ~p~n", [Reason]),
- [];
- Match ->
- Match
- end;
- false ->
- MS = activity_ms(Options),
- case catch ets:select(pdb_activity, MS) of
- {'EXIT', Reason} ->
- io:format(" - select_query_activity [ catch! ]: ~p~n", [Reason]),
- [];
- Match ->
- Match
- end
- end;
- Unhandled ->
- io:format("select_query_activity, unhandled: ~p~n", [Unhandled]),
- []
- end.
-
-select_query_activity_exact_ts(Options) ->
- case { proplists:get_value(ts_min, Options, undefined), proplists:get_value(ts_max, Options, undefined) } of
- {undefined, undefined} -> [];
- {undefined, _ } -> [];
- {_ , undefined} -> [];
- {TsMin , TsMax } ->
- % Remove unwanted options
- Opts = lists_filter([ts_exact], Options),
- Ms = activity_ms(Opts),
- case ets:select(pdb_activity, Ms) of
- % no entries within interval
- [] ->
- Opts2 = lists_filter([ts_max, ts_min], Opts) ++ [{ts_min, TsMax}],
- Ms2 = activity_ms(Opts2),
- case ets:select(pdb_activity, Ms2, 1) of
- '$end_of_table' -> [];
- {[E], _} ->
- [PrevAct] = ets:lookup(pdb_activity, ets:prev(pdb_activity, E#activity.timestamp)),
- [PrevAct#activity{ timestamp = TsMin} , E]
- end;
- Acts ->
- [Head| _] = Acts,
- if
- Head#activity.timestamp == TsMin -> Acts;
- true ->
- PrevTs = ets:prev(pdb_activity, Head#activity.timestamp),
- case ets:lookup(pdb_activity, PrevTs) of
- [] -> Acts;
- [PrevAct] -> [PrevAct#activity{timestamp = TsMin}|Acts]
- end
- end
- end
- end.
-
-lists_filter([], Options) -> Options;
-lists_filter([D|Ds], Options) ->
- lists_filter(Ds, lists:filter(
- fun ({Pred, _}) ->
- if
- Pred == D -> false;
- true -> true
- end
- end, Options)).
-
-% Options:
-% {ts_min, timestamp()}
-% {ts_max, timestamp()}
-% {mfa, mfa()}
-% {state, active | inactive}
-% {id, all | procs | ports | pid() | port()}
-%
-% All options are regarded as AND expect id which are regarded as OR
-% For example: [{ts_min, TS1}, {ts_max, TS2}, {id, PID1}, {id, PORT1}] would be
-% ({ts_min, TS1} and {ts_max, TS2} and {id, PID1}) or
-% ({ts_min, TS1} and {ts_max, TS2} and {id, PORT1}).
-
-activity_ms(Opts) ->
- % {activity, Timestamp, State, Mfa}
- Head = #activity{
- timestamp = '$1',
- id = '$2',
- state = '$3',
- where = '$4',
- _ = '_'},
-
- {Conditions, IDs} = activity_ms_and(Head, Opts, [], []),
- Body = ['$_'],
-
- lists:foldl(
- fun (Option, MS) ->
- case Option of
- {id, ports} ->
- [{Head, [{is_port, Head#activity.id} | Conditions], Body} | MS];
- {id, procs} ->
- [{Head,[{is_pid, Head#activity.id} | Conditions], Body} | MS];
- {id, ID} when is_pid(ID) ; is_port(ID) ->
- [{Head,[{'==', Head#activity.id, ID} | Conditions], Body} | MS];
- {id, all} ->
- [{Head, Conditions,Body} | MS];
- _ ->
- io:format("activity_ms id dropped ~p~n", [Option]),
- MS
- end
- end, [], IDs).
-
-activity_ms_and(_, [], Constraints, []) ->
- {Constraints, [{id, all}]};
-activity_ms_and(_, [], Constraints, IDs) ->
- {Constraints, IDs};
-activity_ms_and(Head, [Opt|Opts], Constraints, IDs) ->
- case Opt of
- {ts_min, Min} ->
- activity_ms_and(Head, Opts,
- [{'>=', Head#activity.timestamp, {Min}} | Constraints], IDs);
- {ts_max, Max} ->
- activity_ms_and(Head, Opts,
- [{'=<', Head#activity.timestamp, {Max}} | Constraints], IDs);
- {id, ID} ->
- activity_ms_and(Head, Opts,
- Constraints, [{id, ID} | IDs]);
- {state, State} ->
- activity_ms_and(Head, Opts,
- [{'==', Head#activity.state, State} | Constraints], IDs);
- {mfa, Mfa} ->
- activity_ms_and(Head, Opts,
- [{'==', Head#activity.where, {Mfa}}| Constraints], IDs);
- _ ->
- io:format("activity_ms_and option dropped ~p~n", [Opt]),
- activity_ms_and(Head, Opts, Constraints, IDs)
- end.
-
-% Information = information()
-
-%%%
-%%% update_information
-%%%
-
-
-update_information(#information{id = Id} = NewInfo) ->
- case ets:lookup(pdb_info, Id) of
- [] ->
- ets:insert(pdb_info, NewInfo),
- ok;
- [Info] ->
- % Remake NewInfo and Info to lists then substitute
- % old values for new values that are not undefined or empty lists.
-
- {_, Result} = lists:foldl(
- fun (InfoElem, {[NewInfoElem | Tail], Out}) ->
- case NewInfoElem of
- undefined ->
- {Tail, [InfoElem | Out]};
- [] ->
- {Tail, [InfoElem | Out]};
- NewInfoElem ->
- {Tail, [NewInfoElem | Out]}
- end
- end, {tuple_to_list(NewInfo), []}, tuple_to_list(Info)),
- ets:insert(pdb_info, list_to_tuple(lists:reverse(Result))),
- ok
- end.
-
-update_information_child(Id, Child) ->
- case ets:lookup(pdb_info, Id) of
- [] ->
- ets:insert(pdb_info,#information{
- id = Id,
- children = [Child]}),
- ok;
- [I] ->
- ets:insert(pdb_info,I#information{children = [Child | I#information.children]}),
- ok
- end.
-
-%%%
-%%% update_activity
-%%%
-update_scheduler(Activity) ->
- ets:insert(pdb_scheduler, Activity).
-
-update_activity(Activity) ->
- ets:insert(pdb_activity, Activity).
-
-%%%
-%%% update_system_ts
-%%%
-
-update_system_start_ts(TS) ->
- case ets:lookup(pdb_system, {system, start_ts}) of
- [] ->
- ets:insert(pdb_system, {{system, start_ts}, TS});
- [{{system, start_ts}, StartTS}] ->
- DT = ?seconds(StartTS, TS),
- if
- DT > 0.0 -> ets:insert(pdb_system, {{system, start_ts}, TS});
- true -> ok
- end;
- Unhandled ->
- io:format("update_system_start_ts, unhandled ~p ~n", [Unhandled])
- end.
-
-update_system_stop_ts(TS) ->
- case ets:lookup(pdb_system, {system, stop_ts}) of
- [] ->
- ets:insert(pdb_system, {{system, stop_ts}, TS});
- [{{system, stop_ts}, StopTS}] ->
- DT = ?seconds(StopTS, TS),
- if
- DT < 0.0 -> ets:insert(pdb_system, {{system, stop_ts}, TS});
- true -> ok
- end;
- Unhandled ->
- io:format("update_system_stop_ts, unhandled ~p ~n", [Unhandled])
- end.
diff --git a/lib/percept/src/percept_graph.erl b/lib/percept/src/percept_graph.erl
deleted file mode 100644
index e5bbaca2b4..0000000000
--- a/lib/percept/src/percept_graph.erl
+++ /dev/null
@@ -1,134 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-
-%% @doc Interface for CGI request on graphs used by percept. The module exports two functions that are implementations for ESI callbacks used by the httpd server. See http://www.erlang.org//doc/apps/inets/index.html.
-
--module(percept_graph).
--export([proc_lifetime/3, graph/3, scheduler_graph/3, activity/3, percentage/3]).
-
--include("percept.hrl").
--include_lib("kernel/include/file.hrl").
-
-%% API
-
-%% graph
-%% @spec graph(SessionID, Env, Input) -> term()
-%% @doc An ESI callback implementation used by the httpd server.
-%%
-
-graph(SessionID, Env, Input) ->
- ok = mod_esi:deliver(SessionID, header()),
- ok = mod_esi:deliver(SessionID, binary_to_list(graph(Env, Input))).
-
-%% activity
-%% @spec activity(SessionID, Env, Input) -> term()
-%% @doc An ESI callback implementation used by the httpd server.
-
-activity(SessionID, Env, Input) ->
- ok = mod_esi:deliver(SessionID, header()),
- ok = mod_esi:deliver(SessionID, binary_to_list(activity_bar(Env, Input))).
-
-proc_lifetime(SessionID, Env, Input) ->
- ok = mod_esi:deliver(SessionID, header()),
- ok = mod_esi:deliver(SessionID, binary_to_list(proc_lifetime(Env, Input))).
-
-percentage(SessionID, Env, Input) ->
- ok = mod_esi:deliver(SessionID, header()),
- ok = mod_esi:deliver(SessionID, binary_to_list(percentage(Env,Input))).
-
-scheduler_graph(SessionID, Env, Input) ->
- ok = mod_esi:deliver(SessionID, header()),
- ok = mod_esi:deliver(SessionID, binary_to_list(scheduler_graph(Env, Input))).
-
-graph(_Env, Input) ->
- Query = httpd:parse_query(Input),
- RangeMin = percept_html:get_option_value("range_min", Query),
- RangeMax = percept_html:get_option_value("range_max", Query),
- Pids = percept_html:get_option_value("pids", Query),
- Width = percept_html:get_option_value("width", Query),
- Height = percept_html:get_option_value("height", Query),
-
- % Convert Pids to id option list
- IDs = [ {id, ID} || ID <- Pids],
-
- % seconds2ts
- StartTs = percept_db:select({system, start_ts}),
- TsMin = percept_analyzer:seconds2ts(RangeMin, StartTs),
- TsMax = percept_analyzer:seconds2ts(RangeMax, StartTs),
-
- Options = [{ts_min, TsMin},{ts_max, TsMax} | IDs],
-
- Acts = percept_db:select({activity, Options}),
- Counts = case IDs of
- [] -> percept_analyzer:activities2count(Acts, StartTs);
- _ -> percept_analyzer:activities2count2(Acts, StartTs)
- end,
-
- percept_image:graph(Width, Height,Counts).
-
-scheduler_graph(_Env, Input) ->
- Query = httpd:parse_query(Input),
- RangeMin = percept_html:get_option_value("range_min", Query),
- RangeMax = percept_html:get_option_value("range_max", Query),
- Width = percept_html:get_option_value("width", Query),
- Height = percept_html:get_option_value("height", Query),
-
- StartTs = percept_db:select({system, start_ts}),
- TsMin = percept_analyzer:seconds2ts(RangeMin, StartTs),
- TsMax = percept_analyzer:seconds2ts(RangeMax, StartTs),
-
-
- Acts = percept_db:select({scheduler, [{ts_min, TsMin}, {ts_max,TsMax}]}),
-
- Counts = [{?seconds(Ts, StartTs), Scheds, 0} || #activity{where = Scheds, timestamp = Ts} <- Acts],
-
- percept_image:graph(Width, Height, Counts).
-
-activity_bar(_Env, Input) ->
- Query = httpd:parse_query(Input),
- Pid = percept_html:get_option_value("pid", Query),
- Min = percept_html:get_option_value("range_min", Query),
- Max = percept_html:get_option_value("range_max", Query),
- Width = percept_html:get_option_value("width", Query),
- Height = percept_html:get_option_value("height", Query),
-
- Data = percept_db:select({activity, [{id, Pid}]}),
- StartTs = percept_db:select({system, start_ts}),
- Activities = [{?seconds(Ts, StartTs), State} || #activity{timestamp = Ts, state = State} <- Data],
-
- percept_image:activities(Width, Height, {Min,Max},Activities).
-
-proc_lifetime(_Env, Input) ->
- Query = httpd:parse_query(Input),
- ProfileTime = percept_html:get_option_value("profiletime", Query),
- Start = percept_html:get_option_value("start", Query),
- End = percept_html:get_option_value("end", Query),
- Width = percept_html:get_option_value("width", Query),
- Height = percept_html:get_option_value("height", Query),
- percept_image:proc_lifetime(round(Width), round(Height), float(Start), float(End), float(ProfileTime)).
-
-percentage(_Env, Input) ->
- Query = httpd:parse_query(Input),
- Width = percept_html:get_option_value("width", Query),
- Height = percept_html:get_option_value("height", Query),
- Percentage = percept_html:get_option_value("percentage", Query),
- percept_image:percentage(round(Width), round(Height), float(Percentage)).
-
-header() ->
- "Content-Type: image/png\r\n\r\n".
diff --git a/lib/percept/src/percept_html.erl b/lib/percept/src/percept_html.erl
deleted file mode 100644
index a675227584..0000000000
--- a/lib/percept/src/percept_html.erl
+++ /dev/null
@@ -1,707 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-
--module(percept_html).
--export([page/3,
- codelocation_page/3,
- databases_page/3,
- load_database_page/3,
- processes_page/3,
- concurrency_page/3,
- process_info_page/3]).
-
--export([value2pid/1,
- pid2value/1,
- get_option_value/2,
- join_strings_with/2]).
-
--include("percept.hrl").
--include_lib("kernel/include/file.hrl").
-
-
-%% API
-
-page(SessionID, Env, Input) ->
- ok = mod_esi:deliver(SessionID, header()),
- ok = mod_esi:deliver(SessionID, menu()),
- ok = mod_esi:deliver(SessionID, overview_content(Env, Input)),
- ok = mod_esi:deliver(SessionID, footer()).
-
-processes_page(SessionID, _, _) ->
- ok = mod_esi:deliver(SessionID, header()),
- ok = mod_esi:deliver(SessionID, menu()),
- ok = mod_esi:deliver(SessionID, processes_content()),
- ok = mod_esi:deliver(SessionID, footer()).
-
-concurrency_page(SessionID, Env, Input) ->
- ok = mod_esi:deliver(SessionID, header()),
- ok = mod_esi:deliver(SessionID, menu()),
- ok = mod_esi:deliver(SessionID, concurrency_content(Env, Input)),
- ok = mod_esi:deliver(SessionID, footer()).
-
-databases_page(SessionID, _, _) ->
- ok = mod_esi:deliver(SessionID, header()),
- ok = mod_esi:deliver(SessionID, menu()),
- ok = mod_esi:deliver(SessionID, databases_content()),
- ok = mod_esi:deliver(SessionID, footer()).
-
-codelocation_page(SessionID, Env, Input) ->
- ok = mod_esi:deliver(SessionID, header()),
- ok = mod_esi:deliver(SessionID, menu()),
- ok = mod_esi:deliver(SessionID, codelocation_content(Env, Input)),
- ok = mod_esi:deliver(SessionID, footer()).
-
-process_info_page(SessionID, Env, Input) ->
- ok = mod_esi:deliver(SessionID, header()),
- ok = mod_esi:deliver(SessionID, menu()),
- ok = mod_esi:deliver(SessionID, process_info_content(Env, Input)),
- ok = mod_esi:deliver(SessionID, footer()).
-
-load_database_page(SessionID, Env, Input) ->
- ok = mod_esi:deliver(SessionID, header()),
-
- % Very dynamic page, handled differently
- load_database_content(SessionID, Env, Input),
- ok = mod_esi:deliver(SessionID, footer()).
-
-
-%%% --------------------------- %%%
-%%% Content pages %%%
-%%% --------------------------- %%%
-
-overview_content(_Env, Input) ->
- Query = httpd:parse_query(Input),
- Min = get_option_value("range_min", Query),
- Max = get_option_value("range_max", Query),
- Width = 1200,
- Height = 600,
- TotalProfileTime = ?seconds( percept_db:select({system, stop_ts}),
- percept_db:select({system, start_ts})),
- RegisteredProcs = length(percept_db:select({information, procs})),
- RegisteredPorts = length(percept_db:select({information, ports})),
-
- InformationTable =
- "<table>" ++
- table_line(["Profile time:", TotalProfileTime]) ++
- table_line(["Processes:", RegisteredProcs]) ++
- table_line(["Ports:", RegisteredPorts]) ++
- table_line(["Min. range:", Min]) ++
- table_line(["Max. range:", Max]) ++
- "</table>",
-
- Header = "
- <div id=\"content\">
- <div>" ++ InformationTable ++ "</div>\n
- <form name=form_area method=POST action=/cgi-bin/percept_html/page>
- <input name=data_min type=hidden value=" ++ term2html(float(Min)) ++ ">
- <input name=data_max type=hidden value=" ++ term2html(float(Max)) ++ ">\n",
-
-
- RangeTable =
- "<table>"++
- table_line([
- "Min:",
- "<input name=range_min value=" ++ term2html(float(Min)) ++">",
- "<select name=\"graph_select\" onChange=\"select_image()\">
- <option disabled=true value=\""++ url_graph(Width, Height, Min, Max, []) ++"\" />Ports
- <option disabled=true value=\""++ url_graph(Width, Height, Min, Max, []) ++"\" />Processes
- <option value=\""++ url_graph(Width, Height, Min, Max, []) ++"\" />Ports & Processes
- </select>",
- "<input type=submit value=Update>"
- ]) ++
- table_line([
- "Max:",
- "<input name=range_max value=" ++ term2html(float(Max)) ++">",
- "",
- "<a href=/cgi-bin/percept_html/codelocation_page?range_min=" ++
- term2html(Min) ++ "&range_max=" ++ term2html(Max) ++ ">Code location</a>"
- ]) ++
- "</table>",
-
-
- MainTable =
- "<table>" ++
- table_line([div_tag_graph()]) ++
- table_line([RangeTable]) ++
- "</table>",
-
- Footer = "</div></form>",
-
- Header ++ MainTable ++ Footer.
-
-div_tag_graph() ->
- %background:url('/images/loader.gif') no-repeat center;
- "<div id=\"percept_graph\"
- onMouseDown=\"select_down(event)\"
- onMouseMove=\"select_move(event)\"
- onMouseUp=\"select_up(event)\"
-
- style=\"
- background-size: 100%;
- background-origin: content;
- width: 100%;
- position:relative;
- \">
-
- <div id=\"percept_areaselect\"
- style=\"background-color:#ef0909;
- position:relative;
- visibility:hidden;
- border-left: 1px solid #101010;
- border-right: 1px solid #101010;
- z-index:2;
- width:40px;
- height:40px;\"></div></div>".
-
--spec url_graph(
- Widht :: non_neg_integer(),
- Height :: non_neg_integer(),
- Min :: float(),
- Max :: float(),
- Pids :: [pid()]) -> string().
-
-url_graph(W, H, Min, Max, []) ->
- "/cgi-bin/percept_graph/graph?range_min=" ++ term2html(float(Min))
- ++ "&range_max=" ++ term2html(float(Max))
- ++ "&width=" ++ term2html(float(W))
- ++ "&height=" ++ term2html(float(H)).
-
-%%% process_info_content
-
-process_info_content(_Env, Input) ->
- Query = httpd:parse_query(Input),
- Pid = get_option_value("pid", Query),
-
-
- [I] = percept_db:select({information, Pid}),
- ArgumentString = case I#information.entry of
- {_, _, Arguments} -> lists:flatten( [term2html(Arg) ++ "<br>" || Arg <- Arguments]);
- _ -> ""
- end,
-
- TimeTable = html_table([
- [{th, ""},
- {th, "Timestamp"},
- {th, "Profile Time"}],
- [{td, "Start"},
- term2html(I#information.start),
- term2html(procstarttime(I#information.start))],
- [{td, "Stop"},
- term2html(I#information.stop),
- term2html(procstoptime(I#information.stop))]
- ]),
-
- InfoTable = html_table([
- [{th, "Pid"}, term2html(I#information.id)],
- [{th, "Name"}, term2html(I#information.name)],
- [{th, "Entrypoint"}, mfa2html(I#information.entry)],
- [{th, "Arguments"}, ArgumentString],
- [{th, "Timetable"}, TimeTable],
- [{th, "Parent"}, pid2html(I#information.parent)],
- [{th, "Children"}, lists:flatten(lists:map(fun(Child) -> pid2html(Child) ++ " " end, I#information.children))]
- ]),
-
- PidActivities = percept_db:select({activity, [{id, Pid}]}),
- WaitingMfas = percept_analyzer:waiting_activities(PidActivities),
-
- TotalWaitTime = lists:sum( [T || {T, _, _} <- WaitingMfas] ),
-
- MfaTable = html_table([
- [{th, "percentage"},
- {th, "total"},
- {th, "mean"},
- {th, "stddev"},
- {th, "#recv"},
- {th, "module:function/arity"}]] ++ [
- [{td, image_string(percentage, [{width, 100}, {height, 10}, {percentage, Time/TotalWaitTime}])},
- {td, term2html(Time)},
- {td, term2html(Mean)},
- {td, term2html(StdDev)},
- {td, term2html(N)},
- {td, mfa2html(MFA)} ] || {Time, MFA, {Mean, StdDev, N}} <- WaitingMfas]),
-
- "<div id=\"content\">" ++
- InfoTable ++ "<br>" ++
- MfaTable ++
- "</div>".
-
-%%% concurrency content
-concurrency_content(_Env, Input) ->
- %% Get query
- Query = httpd:parse_query(Input),
-
- %% Collect selected pids and generate id tags
- Pids = [value2pid(PidValue) || {PidValue, Case} <- Query, Case == "on", PidValue /= "select_all"],
- IDs = [{id, Pid} || Pid <- Pids],
-
- % FIXME: A lot of extra work here, redo
-
- %% Analyze activities and calculate area bounds
- Activities = percept_db:select({activity, IDs}),
- StartTs = percept_db:select({system, start_ts}),
- Counts = [{Time, Y1 + Y2} || {Time, Y1, Y2} <- percept_analyzer:activities2count2(Activities, StartTs)],
- {T0,_,T1,_} = percept_analyzer:minmax(Counts),
-
- % FIXME: End
-
- PidValues = [pid2value(Pid) || Pid <- Pids],
-
- %% Generate activity bar requests
- ActivityBarTable = lists:foldl(
- fun(Pid, Out) ->
- ValueString = pid2value(Pid),
- Out ++
- table_line([
- pid2html(Pid),
- "<img onload=\"size_image(this, '" ++
- image_string_head("activity", [{"pid", ValueString}, {range_min, T0},{range_max, T1},{height, 10}], []) ++
- "')\" src=/images/white.png border=0 />"
- ])
- end, [], Pids),
-
- %% Make pids request string
- PidsRequest = join_strings_with(PidValues, ":"),
-
- "<div id=\"content\">
- <table cellspacing=0 cellpadding=0 border=0>" ++
- table_line([
- "",
- "<img onload=\"size_image(this, '" ++
- image_string_head("graph", [{"pids", PidsRequest},{range_min, T0}, {range_max, T1}, {height, 400}], []) ++
- "')\" src=/images/white.png border=0 />"
- ]) ++
- ActivityBarTable ++
- "</table></div>\n".
-
-processes_content() ->
- Ports = percept_db:select({information, ports}),
- UnsortedProcesses = percept_db:select({information, procs}),
- SystemStartTS = percept_db:select({system, start_ts}),
- SystemStopTS = percept_db:select({system, stop_ts}),
- ProfileTime = ?seconds( SystemStopTS,
- SystemStartTS),
- Processes = lists:sort(
- fun (A, B) ->
- if
- A#information.id > B#information.id -> true;
- true -> false
- end
- end, UnsortedProcesses),
-
- ProcsHtml = lists:foldl(
- fun (I, Out) ->
- StartTime = procstarttime(I#information.start),
- EndTime = procstoptime(I#information.stop),
- Prepare =
- table_line([
- "<input type=checkbox name=" ++ pid2value(I#information.id) ++ ">",
- pid2html(I#information.id),
- image_string(proc_lifetime, [
- {profiletime, ProfileTime},
- {start, StartTime},
- {"end", term2html(float(EndTime))},
- {width, 100},
- {height, 10}]),
- mfa2html(I#information.entry),
- term2html(I#information.name),
- pid2html(I#information.parent)
- ]),
- [Prepare|Out]
- end, [], Processes),
-
- PortsHtml = lists:foldl(
- fun (I, Out) ->
- StartTime = procstarttime(I#information.start),
- EndTime = procstoptime(I#information.stop),
- Prepare =
- table_line([
- "",
- pid2html(I#information.id),
- image_string(proc_lifetime, [
- {profiletime, ProfileTime},
- {start, StartTime},
- {"end", term2html(float(EndTime))},
- {width, 100},
- {height, 10}]),
- mfa2html(I#information.entry),
- term2html(I#information.name),
- pid2html(I#information.parent)
- ]),
- [Prepare|Out]
- end, [], Ports),
-
- Selector = "<table>" ++
- table_line([
- "<input onClick='selectall()' type=checkbox name=select_all>Select all"]) ++
- table_line([
- "<input type=submit value=Compare>"]) ++
- "</table>",
-
- if
- length(ProcsHtml) > 0 ->
- ProcsHtmlResult =
- "<tr><td><b>Processes</b></td></tr>
- <tr><td>
- <table width=700 cellspacing=0 border=0>
- <tr>
- <td align=middle width=40><b>Select</b></td>
- <td align=middle width=40><b>Pid</b></td>
- <td><b>Lifetime</b></td>
- <td><b>Entrypoint</b></td>
- <td><b>Name</b></td>
- <td><b>Parent</b></td>
- </tr>" ++
- lists:flatten(ProcsHtml) ++
- "</table>
- </td></tr>";
- true ->
- ProcsHtmlResult = ""
- end,
- if
- length(PortsHtml) > 0 ->
- PortsHtmlResult = "
- <tr><td><b>Ports</b></td></tr>
- <tr><td>
- <table width=700 cellspacing=0 border=0>
- <tr>
- <td align=middle width=40><b>Select</b></td>
- <td align=left width=40><b>Pid</b></td>
- <td><b>Lifetime</b></td>
- <td><b>Entrypoint</b></td>
- <td><b>Name</b></td>
- <td><b>Parent</b></td>
- </tr>" ++
- lists:flatten(PortsHtml) ++
- "</table>
- </td></tr>";
- true ->
- PortsHtmlResult = ""
- end,
-
- Right = "<div>"
- ++ Selector ++
- "</div>\n",
-
- Middle = "<div id=\"content\">
- <table>" ++
- ProcsHtmlResult ++
- PortsHtmlResult ++
- "</table>" ++
- Right ++
- "</div>\n",
-
- "<form name=process_select method=POST action=/cgi-bin/percept_html/concurrency_page>" ++
- Middle ++
- "</form>".
-
-procstarttime(TS) ->
- case TS of
- undefined -> 0.0;
- TS -> ?seconds(TS,percept_db:select({system, start_ts}))
- end.
-
-procstoptime(TS) ->
- case TS of
- undefined -> ?seconds( percept_db:select({system, stop_ts}),
- percept_db:select({system, start_ts}));
- TS -> ?seconds(TS, percept_db:select({system, start_ts}))
- end.
-
-databases_content() ->
- "<div id=\"content\">
- <form name=load_percept_file method=post action=/cgi-bin/percept_html/load_database_page>
- <center>
- <table>
- <tr><td>Enter file to analyse:</td><td><input type=hidden name=path /></td></tr>
- <tr><td><input type=file name=file size=40 /></td><td><input type=submit value=Load onClick=\"path.value = file.value;\" /></td></tr>
- </table>
- </center>
- </form>
- </div>".
-
-load_database_content(SessionId, _Env, Input) ->
- Query = httpd:parse_query(Input),
- {_,{_,Path}} = lists:keysearch("file", 1, Query),
- {_,{_,File}} = lists:keysearch("path", 1, Query),
- Filename = filename:join(Path, File),
- % Check path/file/filename
-
- ok = mod_esi:deliver(SessionId, "<div id=\"content\">"),
- case file:read_file_info(Filename) of
- {ok, _} ->
- Content = "<center>
- Parsing: " ++ Filename ++ "<br>
- </center>",
- ok = mod_esi:deliver(SessionId, Content),
- case percept:analyze(Filename) of
- {error, Reason} ->
- ok = mod_esi:deliver(SessionId, error_msg("Analyze" ++ term2html(Reason)));
- _ ->
- Complete = "<center><a href=\"/cgi-bin/percept_html/page\">View</a></center>",
- ok = mod_esi:deliver(SessionId, Complete)
- end;
- {error, Reason} ->
- ok = mod_esi:deliver(SessionId, error_msg("File" ++ term2html(Reason)))
- end,
- ok = mod_esi:deliver(SessionId, "</div>").
-
-codelocation_content(_Env, Input) ->
- Query = httpd:parse_query(Input),
- Min = get_option_value("range_min", Query),
- Max = get_option_value("range_max", Query),
- StartTs = percept_db:select({system, start_ts}),
- TsMin = percept_analyzer:seconds2ts(Min, StartTs),
- TsMax = percept_analyzer:seconds2ts(Max, StartTs),
- Acts = percept_db:select({activity, [{ts_min, TsMin}, {ts_max, TsMax}]}),
-
- Secs = [timer:now_diff(A#activity.timestamp,StartTs)/1000 || A <- Acts],
- Delta = cl_deltas(Secs),
- Zip = lists:zip(Acts, Delta),
- Table = html_table([
- [{th, "delta [ms]"},
- {th, "time [ms]"},
- {th, " pid "},
- {th, "activity"},
- {th, "module:function/arity"},
- {th, "#runnables"}]] ++ [
- [{td, term2html(D)},
- {td, term2html(timer:now_diff(A#activity.timestamp,StartTs)/1000)},
- {td, pid2html(A#activity.id)},
- {td, term2html(A#activity.state)},
- {td, mfa2html(A#activity.where)},
- {td, term2html(A#activity.runnable_count)}] || {A, D} <- Zip ]),
-
- "<div id=\"content\">" ++
- Table ++
- "</div>".
-
-cl_deltas([]) -> [];
-cl_deltas(List) -> cl_deltas(List, [0.0]).
-cl_deltas([_], Out) -> lists:reverse(Out);
-cl_deltas([A,B|Ls], Out) -> cl_deltas([B|Ls], [B - A | Out]).
-
-%%% --------------------------- %%%
-%%% Utility functions %%%
-%%% --------------------------- %%%
-
-%% Should be in string stdlib?
-
-join_strings(Strings) ->
- lists:flatten(Strings).
-
--spec join_strings_with(Strings :: [string()], Separator :: string()) -> string().
-
-join_strings_with([S1, S2 | R], S) ->
- join_strings_with([join_strings_with(S1,S2,S) | R], S);
-join_strings_with([S], _) ->
- S.
-join_strings_with(S1, S2, S) ->
- join_strings([S1,S,S2]).
-
-%%% Generic erlang2html
-
--spec html_table(Rows :: [[string() | {'td' | 'th', string()}]]) -> string().
-
-html_table(Rows) -> "<table>" ++ html_table_row(Rows) ++ "</table>".
-
-html_table_row(Rows) -> html_table_row(Rows, odd).
-html_table_row([], _) -> "";
-html_table_row([Row|Rows], odd ) -> "<tr class=\"odd\">" ++ html_table_data(Row) ++ "</tr>" ++ html_table_row(Rows, even);
-html_table_row([Row|Rows], even) -> "<tr class=\"even\">" ++ html_table_data(Row) ++ "</tr>" ++ html_table_row(Rows, odd ).
-
-html_table_data([]) -> "";
-html_table_data([{td, Data}|Row]) -> "<td>" ++ Data ++ "</td>" ++ html_table_data(Row);
-html_table_data([{th, Data}|Row]) -> "<th>" ++ Data ++ "</th>" ++ html_table_data(Row);
-html_table_data([Data|Row]) -> "<td>" ++ Data ++ "</td>" ++ html_table_data(Row).
-
-
-
-
--spec table_line(Table :: [any()]) -> string().
-
-table_line(List) -> table_line(List, ["<tr>"]).
-table_line([], Out) -> lists:flatten(lists:reverse(["</tr>\n"|Out]));
-table_line([Element | Elements], Out) when is_list(Element) ->
- table_line(Elements, ["<td>" ++ Element ++ "</td>" |Out]);
-table_line([Element | Elements], Out) ->
- table_line(Elements, ["<td>" ++ term2html(Element) ++ "</td>"|Out]).
-
--spec term2html(any()) -> string().
-
-term2html(Term) when is_float(Term) -> lists:flatten(io_lib:format("~.4f", [Term]));
-term2html(Term) -> lists:flatten(io_lib:format("~p", [Term])).
-
--spec mfa2html(MFA :: {atom(), atom(), list() | integer()}) -> string().
-
-mfa2html({Module, Function, Arguments}) when is_list(Arguments) ->
- lists:flatten(io_lib:format("~p:~p/~p", [Module, Function, length(Arguments)]));
-mfa2html({Module, Function, Arity}) when is_integer(Arity) ->
- lists:flatten(io_lib:format("~p:~p/~p", [Module, Function, Arity]));
-mfa2html(_) ->
- "undefined".
-
--spec pid2html(Pid :: pid() | port()) -> string().
-
-pid2html(Pid) when is_pid(Pid) ->
- PidString = term2html(Pid),
- PidValue = pid2value(Pid),
- "<a href=\"/cgi-bin/percept_html/process_info_page?pid="++PidValue++"\">"++PidString++"</a>";
-pid2html(Pid) when is_port(Pid) ->
- term2html(Pid);
-pid2html(_) ->
- "undefined".
-
--spec image_string(Request :: string()) -> string().
-
-image_string(Request) ->
- "<img border=0 src=\"/cgi-bin/percept_graph/" ++
- Request ++
- " \">".
-
--spec image_string(atom() | string(), list()) -> string().
-
-image_string(Request, Options) when is_atom(Request), is_list(Options) ->
- image_string(image_string_head(erlang:atom_to_list(Request), Options, []));
-image_string(Request, Options) when is_list(Options) ->
- image_string(image_string_head(Request, Options, [])).
-
-image_string_head(Request, [{Type, Value} | Opts], Out) when is_atom(Type), is_number(Value) ->
- Opt = join_strings(["?",term2html(Type),"=",term2html(Value)]),
- image_string_tail(Request, Opts, [Opt|Out]);
-image_string_head(Request, [{Type, Value} | Opts], Out) ->
- Opt = join_strings(["?",Type,"=",Value]),
- image_string_tail(Request, Opts, [Opt|Out]).
-
-image_string_tail(Request, [], Out) ->
- join_strings([Request | lists:reverse(Out)]);
-image_string_tail(Request, [{Type, Value} | Opts], Out) when is_atom(Type), is_number(Value) ->
- Opt = join_strings(["&",term2html(Type),"=",term2html(Value)]),
- image_string_tail(Request, Opts, [Opt|Out]);
-image_string_tail(Request, [{Type, Value} | Opts], Out) ->
- Opt = join_strings(["&",Type,"=",Value]),
- image_string_tail(Request, Opts, [Opt|Out]).
-
-
-%%% percept conversions
-
--spec pid2value(Pid :: pid()) -> string().
-
-pid2value(Pid) ->
- String = lists:flatten(io_lib:format("~p", [Pid])),
- lists:sublist(String, 2, erlang:length(String)-2).
-
--spec value2pid(Value :: string()) -> pid().
-
-value2pid(Value) ->
- String = lists:flatten("<" ++ Value ++ ">"),
- erlang:list_to_pid(String).
-
-
-%%% get value
-
--spec get_option_value(Option :: string(), Options :: [{string(),any()}]) ->
- {'error', any()} | boolean() | pid() | [pid()] | number().
-
-get_option_value(Option, Options) ->
- case catch get_option_value0(Option, Options) of
- {'EXIT', Reason} -> {error, Reason};
- Value -> Value
- end.
-
-get_option_value0(Option, Options) ->
- case lists:keysearch(Option, 1, Options) of
- false -> get_default_option_value(Option);
- {value, {Option, _Value}} when Option == "fillcolor" -> true;
- {value, {Option, Value}} when Option == "pid" -> value2pid(Value);
- {value, {Option, Value}} when Option == "pids" ->
- [value2pid(PidValue) || PidValue <- string:tokens(Value,":")];
- {value, {Option, Value}} -> get_number_value(Value);
- _ -> {error, undefined}
- end.
-
-get_default_option_value(Option) ->
- case Option of
- "fillcolor" -> false;
- "range_min" -> float(0.0);
- "pids" -> [];
- "range_max" ->
- Acts = percept_db:select({activity, []}),
- #activity{ timestamp = Start } = hd(Acts),
- #activity{ timestamp = Stop } = hd(lists:reverse(Acts)),
- ?seconds(Stop,Start);
- "width" -> 700;
- "height" -> 400;
- _ -> {error, {undefined_default_option, Option}}
- end.
-
--spec get_number_value(string()) -> number() | {'error', 'illegal_number'}.
-
-get_number_value(Value) ->
- % Try float
- case string:to_float(Value) of
- {error, no_float} ->
- % Try integer
- case string:to_integer(Value) of
- {error, _} -> {error, illegal_number};
- {Integer, _} -> Integer
- end;
- {error, _} -> {error, illegal_number};
- {Float, _} -> Float
- end.
-
-%%% --------------------------- %%%
-%%% html prime functions %%%
-%%% --------------------------- %%%
-
-header() -> header([]).
-header(HeaderData) ->
- "Content-Type: text/html\r\n\r\n" ++
- "<html>
- <head>
- <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">
- <title>percept</title>
- <link href=\"/css/percept.css\" rel=\"stylesheet\" type=\"text/css\">
- <script type=\"text/javascript\" src=\"/javascript/percept_error_handler.js\"></script>
- <script type=\"text/javascript\" src=\"/javascript/percept_select_all.js\"></script>
- <script type=\"text/javascript\" src=\"/javascript/percept_area_select.js\"></script>
- " ++ HeaderData ++"
- </head>
- <body onLoad=\"load_image()\">
- <div id=\"header\"><a href=/index.html>percept</a></div>\n".
-
-footer() ->
- "</body>
- </html>\n".
-
-menu() ->
- "<div id=\"menu\" class=\"menu_tabs\">
- <ul>
- <li><a href=/cgi-bin/percept_html/databases_page>databases</a></li>
- <li><a href=/cgi-bin/percept_html/processes_page>processes</a></li>
- <li><a href=/cgi-bin/percept_html/page>overview</a></li>
- </ul></div>\n".
-
--spec error_msg(Error :: string()) -> string().
-
-error_msg(Error) ->
- "<table width=300>
- <tr height=5><td></td> <td></td></tr>
- <tr><td width=150 align=right><b>Error: </b></td> <td align=left>"++ Error ++ "</td></tr>
- <tr height=5><td></td> <td></td></tr>
- </table>\n".
diff --git a/lib/percept/src/percept_image.erl b/lib/percept/src/percept_image.erl
deleted file mode 100644
index e819938027..0000000000
--- a/lib/percept/src/percept_image.erl
+++ /dev/null
@@ -1,316 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-
--module(percept_image).
--export([ proc_lifetime/5,
- percentage/3,
- graph/3,
- graph/4,
- activities/3,
- activities/4]).
--record(graph_area, {x = 0, y = 0, width, height}).
--compile(inline).
-
-%%% -------------------------------------
-%%% GRAF
-%%% -------------------------------------
-
-%% graph(Widht, Height, Range, Data)
-
-graph(Width, Height, {RXmin, RYmin, RXmax, RYmax}, Data) ->
- Data2 = [{X, Y1 + Y2} || {X, Y1, Y2} <- Data],
- MinMax = percept_analyzer:minmax(Data2),
- {Xmin, Ymin, Xmax, Ymax} = MinMax,
- graf1(Width, Height,{ lists:min([RXmin, Xmin]),
- lists:min([RYmin, Ymin]),
- lists:max([RXmax, Xmax]),
- lists:max([RYmax, Ymax])}, Data).
-
-%% graph(Widht, Height, Data) = Image
-%% In:
-%% Width = integer(),
-%% Height = integer(),
-%% Data = [{Time, Procs, Ports}]
-%% Time = float()
-%% Procs = integer()
-%% Ports = integer()
-%% Out:
-%% Image = binary()
-
-graph(Width, Height, Data) ->
- Data2 = [{X, Y1 + Y2} || {X, Y1, Y2} <- Data],
- Bounds = percept_analyzer:minmax(Data2),
- graf1(Width, Height, Bounds, Data).
-
-graf1(Width, Height, {Xmin, Ymin, Xmax, Ymax}, Data) ->
- % Calculate areas
- HO = 20,
- GrafArea = #graph_area{x = HO, y = 4, width = Width - 2*HO, height = Height - 17},
- XticksArea = #graph_area{x = HO, y = Height - 13, width = Width - 2*HO, height = 13},
- YticksArea = #graph_area{x = 1, y = 4, width = HO, height = Height - 17},
-
- %% Initiate Image
-
- Image = egd:create(Width, Height),
-
- %% Set colors
-
- Black = egd:color(Image, {0, 0, 0}),
- ProcColor = egd:color(Image, {0, 255, 0}),
- PortColor = egd:color(Image, {255, 0, 0}),
-
- %% Draw graf, xticks and yticks
- draw_graf(Image, Data, {Black, ProcColor, PortColor}, GrafArea, {Xmin, Ymin, Xmax, Ymax}),
- draw_xticks(Image, Black, XticksArea, {Xmin, Xmax}, Data),
- draw_yticks(Image, Black, YticksArea, {Ymin, Ymax}),
-
- %% Kill image and return binaries
- Binary = egd:render(Image, png),
- egd:destroy(Image),
- Binary.
-
-%% draw_graf(Image, Data, Color, GraphArea, DataBounds)
-%% Image, port to Image
-%% Data, list of three tuple data, (X, Y1, Y2)
-%% Color, {ForegroundColor, ProcFillColor, PortFillColor}
-%% DataBounds, {Xmin, Ymin, Xmax, Ymax}
-
-draw_graf(Im, Data, Colors, GA = #graph_area{x = X0, y = Y0, width = Width, height = Height}, {Xmin, _Ymin, Xmax, Ymax}) ->
- Dx = (Width)/(Xmax - Xmin),
- Dy = (Height)/(Ymax),
- Plotdata = [{trunc(X0 + X*Dx - Xmin*Dx), trunc(Y0 + Height - Y1*Dy), trunc(Y0 + Height - (Y1 + Y2)*Dy)} || {X, Y1, Y2} <- Data],
- draw_graf(Im, Plotdata, Colors, GA).
-
-draw_graf(Im, [{X1, Yproc1, Yport1}, {X2, Yproc2, Yport2}|Data], C, GA) when X2 - X1 < 1 ->
- draw_graf(Im, [{X1, [{Yproc2, Yport2},{Yproc1, Yport1}]}|Data], C, GA);
-
-draw_graf(Im, [{X1, Ys1}, {X2, Yproc2, Yport2}|Data], C, GA) when X2 - X1 < 1, is_list(Ys1) ->
- draw_graf(Im, [{X1, [{Yproc2, Yport2}|Ys1]}|Data], C, GA);
-
-draw_graf(Im, [{X1, Yproc1, Yport1}, {X2, Yproc2, Yport2}|Data], C = {B, PrC, PoC}, GA = #graph_area{y = Y0, height = H}) ->
- GyZero = trunc(Y0 + H),
- egd:filledRectangle(Im, {X1, GyZero}, {X2, Yproc1}, PrC),
- egd:filledRectangle(Im, {X1, Yproc1}, {X2, Yport1}, PoC),
- egd:line(Im, {X1, Yport1}, {X2, Yport1}, B), % top line
- egd:line(Im, {X1, Yport2}, {X1, Yport1}, B), % right line
- egd:line(Im, {X2, Yport1}, {X2, Yport2}, B), % right line
- draw_graf(Im, [{X2, Yproc2, Yport2}|Data], C, GA);
-
-draw_graf(Im, [{X1, Ys1 = [{Yproc1,Yport1}|_]}, {X2, Yproc2, Yport2}|Data], C = {B, PrC, PoC}, GA = #graph_area{y = Y0, height = H}) ->
- GyZero = trunc(Y0 + H),
- Yprocs = [Yp || {Yp, _} <- Ys1],
- Yports = [Yp || {_, Yp} <- Ys1],
-
- YprMin = lists:min(Yprocs),
- YprMax = lists:max(Yprocs),
- YpoMax = lists:max(Yports),
- egd:filledRectangle(Im, {X1, GyZero}, {X2, Yproc1}, PrC),
- egd:filledRectangle(Im, {X1, Yproc1}, {X2, Yport1}, PoC),
- egd:filledRectangle(Im, {X1, Yport1}, {X2, Yport1}, B), % top line
- egd:filledRectangle(Im, {X2, Yport1}, {X2, Yport2}, B), % right line
-
- egd:filledRectangle(Im, {X1, GyZero}, {X1, YprMin}, PrC), % left proc green line
- egd:filledRectangle(Im, {X1, YprMax}, {X1, YpoMax}, PoC), % left port line
- egd:filledRectangle(Im, {X1, YprMax}, {X1, YprMin}, B),
-
- draw_graf(Im, [{X2, Yproc2, Yport2}|Data], C, GA);
-draw_graf(_, _, _, _) -> ok.
-
-draw_xticks(Image, Color, XticksArea, {Xmin, Xmax}, Data) ->
- #graph_area{x = X0, y = Y0, width = Width} = XticksArea,
-
- DX = Width/(Xmax - Xmin),
- Offset = X0 - Xmin*DX,
- Y = trunc(Y0),
- Font = load_font(),
- {FontW, _FontH} = egd_font:size(Font),
- egd:filledRectangle(Image, {trunc(X0), Y}, {trunc(X0 + Width), Y}, Color),
- lists:foldl(
- fun ({X,_,_}, PX) ->
- X1 = trunc(Offset + X*DX),
-
- % Optimization:
- % if offset has past half the previous text
- % start checking this text
-
- if
- X1 > PX ->
- Text = lists:flatten(io_lib:format("~.3f", [float(X)])),
- TextLength = length(Text),
- TextWidth = TextLength*FontW,
- Spacing = 2,
- if
- X1 > PX + round(TextWidth/2) + Spacing ->
- egd:line(Image, {X1, Y - 3}, {X1, Y + 3}, Color),
- text(Image, {X1 - round(TextWidth/2), Y + 2}, Font, Text, Color),
- X1 + round(TextWidth/2) + Spacing;
- true ->
- PX
- end;
- true ->
- PX
- end
- end, 0, Data).
-
-draw_yticks(Im, Color, TickArea, {_,Ymax}) ->
- #graph_area{x = X0, y = Y0, width = Width, height = Height} = TickArea,
- Font = load_font(),
- X = trunc(X0 + Width),
- Dy = (Height)/(Ymax),
- Yts = if
- Height/(Ymax*12) < 1.0 -> round(1 + Ymax*15/Height);
- true -> 1
- end,
- egd:filledRectangle(Im, {X, trunc(0 + Y0)}, {X, trunc(Y0 + Height)}, Color),
- draw_yticks0(Im, Font, Color, 0, Yts, Ymax, {X, Height, Dy}).
-
-draw_yticks0(Im, Font, Color, Yi, Yts, Ymax, Area) when Yi < Ymax ->
- {X, Height, Dy} = Area,
- Y = round(Height - (Yi*Dy) + 3),
-
- egd:filledRectangle(Im, {X - 3, Y}, {X + 3, Y}, Color),
- Text = lists:flatten(io_lib:format("~p", [Yi])),
- text(Im, {0, Y - 4}, Font, Text, Color),
- draw_yticks0(Im, Font, Color, Yi + Yts, Yts, Ymax, Area);
-draw_yticks0(_, _, _, _, _, _, _) -> ok.
-
-%%% -------------------------------------
-%%% ACTIVITIES
-%%% -------------------------------------
-
-%% activities(Width, Height, Range, Activities) -> Binary
-%% In:
-%% Width = integer()
-%% Height = integer()
-%% Range = {float(), float()}
-%% Activities = [{float(), active | inactive}]
-%% Out:
-%% Binary = binary()
-
-activities(Width, Height, {UXmin, UXmax}, Activities) ->
- Xs = [ X || {X,_} <- Activities],
- Xmin = lists:min(Xs),
- Xmax = lists:max(Xs),
- activities0(Width, Height, {lists:min([Xmin, UXmin]), lists:max([UXmax, Xmax])}, Activities).
-
-activities(Width, Height, Activities) ->
- Xs = [ X || {X,_} <- Activities],
- Xmin = lists:min(Xs),
- Xmax = lists:max(Xs),
- activities0(Width, Height, {Xmin, Xmax}, Activities).
-
-activities0(Width, Height, {Xmin, Xmax}, Activities) ->
- Image = egd:create(Width, Height),
- Grey = egd:color(Image, {200, 200, 200}),
- HO = 20,
- ActivityArea = #graph_area{x = HO, y = 0, width = Width - 2*HO, height = Height},
- egd:filledRectangle(Image, {0, 0}, {Width, Height}, Grey),
- draw_activity(Image, {Xmin, Xmax}, ActivityArea, Activities),
- Binary = egd:render(Image, png),
- egd:destroy(Image),
- Binary.
-
-draw_activity(Image, {Xmin, Xmax}, Area = #graph_area{ width = Width }, Acts) ->
- White = egd:color({255, 255, 255}),
- Green = egd:color({0,250, 0}),
- Black = egd:color({0, 0, 0}),
-
- Dx = Width/(Xmax - Xmin),
-
- draw_activity(Image, {Xmin, Xmax}, Area, {White, Green, Black}, Dx, Acts).
-
-draw_activity(_, _, _, _, _, [_]) -> ok;
-draw_activity(Image, {Xmin, Xmax}, Area = #graph_area{ height = Height, x = X0 }, {Cw, Cg, Cb}, Dx, [{Xa1, State}, {Xa2, Act2} | Acts]) ->
- X1 = erlang:trunc(X0 + Dx*Xa1 - Xmin*Dx),
- X2 = erlang:trunc(X0 + Dx*Xa2 - Xmin*Dx),
-
- case State of
- inactive ->
- egd:filledRectangle(Image, {X1, 0}, {X2, Height - 1}, Cw),
- egd:rectangle(Image, {X1, 0}, {X2, Height - 1}, Cb);
- active ->
- egd:filledRectangle(Image, {X1, 0}, {X2, Height - 1}, Cg),
- egd:rectangle(Image, {X1, 0}, {X2, Height - 1}, Cb)
- end,
- draw_activity(Image, {Xmin, Xmax}, Area, {Cw, Cg, Cb}, Dx, [{Xa2, Act2} | Acts]).
-
-
-
-%%% -------------------------------------
-%%% Process lifetime
-%%% Used by processes page
-%%% -------------------------------------
-
-proc_lifetime(Width, Height, Start, End, ProfileTime) ->
- Im = egd:create(round(Width), round(Height)),
- Black = egd:color(Im, {0, 0, 0}),
- Green = egd:color(Im, {0, 255, 0}),
-
- % Ratio and coordinates
-
- DX = (Width-1)/ProfileTime,
- X1 = round(DX*Start),
- X2 = round(DX*End),
-
- % Paint
- egd:filledRectangle(Im, {X1, 0}, {X2, Height - 1}, Green),
- egd:rectangle(Im, {X1, 0}, {X2, Height - 1}, Black),
-
- Binary = egd:render(Im, png),
- egd:destroy(Im),
- Binary.
-
-%%% -------------------------------------
-%%% Percentage
-%%% Used by process_info page
-%%% Percentage should be 0.0 -> 1.0
-%%% -------------------------------------
-percentage(Width, Height, Percentage) ->
- Im = egd:create(round(Width), round(Height)),
- Font = load_font(),
- Black = egd:color(Im, {0, 0, 0}),
- Green = egd:color(Im, {0, 255, 0}),
-
- % Ratio and coordinates
-
- X = round(Width - 1 - Percentage*(Width - 1)),
-
- % Paint
- egd:filledRectangle(Im, {X, 0}, {Width - 1, Height - 1}, Green),
- {FontW, _} = egd_font:size(Font),
- String = lists:flatten(io_lib:format("~.10B %", [round(100*Percentage)])),
-
- text( Im,
- {round(Width/2 - (FontW*length(String)/2)), 0},
- Font,
- String,
- Black),
- egd:rectangle(Im, {X, 0}, {Width - 1, Height - 1}, Black),
-
- Binary = egd:render(Im, png),
- egd:destroy(Im),
- Binary.
-
-
-load_font() ->
- Filename = filename:join([code:priv_dir(percept),"fonts", "6x11_latin1.wingsfont"]),
- egd_font:load(Filename).
-
-text(Image, {X,Y}, Font, Text, Color) ->
- egd:text(Image, {X,Y-2}, Font, Text, Color).
diff --git a/lib/percept/test/Makefile b/lib/percept/test/Makefile
deleted file mode 100644
index 87fde49410..0000000000
--- a/lib/percept/test/Makefile
+++ /dev/null
@@ -1,91 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2007-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-include $(ERL_TOP)/make/target.mk
-
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-
-MODULES= \
- ipc_tree \
- percept_SUITE \
- egd_SUITE
-
-EBIN = .
-
-HRL_FILES=
-
-ERL_FILES= $(MODULES:%=%.erl)
-
-TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
-
-SOURCE = $(ERL_FILES) $(HRL_FILES)
-
-EMAKEFILE=Emakefile
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/percept_test
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-ERL_MAKE_FLAGS +=
-ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/percept/include
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-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) percept.spec percept.cover $(EMAKEFILE) $(SOURCE) "$(RELSYSDIR)"
- chmod -R u+w "$(RELSYSDIR)"
- @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
-
-release_docs_spec:
-
-
diff --git a/lib/percept/test/egd_SUITE.erl b/lib/percept/test/egd_SUITE.erl
deleted file mode 100644
index 401695dddd..0000000000
--- a/lib/percept/test/egd_SUITE.erl
+++ /dev/null
@@ -1,389 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
--module(egd_SUITE).
--include_lib("common_test/include/ct.hrl").
-
-%% Test server specific exports
--export([all/0, suite/0]).
--export([init_per_suite/1, end_per_suite/1]).
--export([init_per_testcase/2, end_per_testcase/2]).
-
-%% Test cases
--export([image_create_and_destroy/1,
- image_shape/1,
- image_primitives/1,
- image_colors/1,
- image_font/1,
- image_fans/1,
- image_png_compliant/1]).
-
-suite() ->
- [{ct_hooks,[ts_install_cth]},
- {timetrap, {minutes, 1}}].
-
-all() ->
- [image_create_and_destroy, image_shape,
- image_primitives, image_colors, image_font,
- image_fans,
- image_png_compliant].
-
-
-init_per_suite(Config) when is_list(Config) ->
- rand:seed(exsplus),
- Config.
-
-end_per_suite(Config) when is_list(Config) ->
- Config.
-
-init_per_testcase(_Case, Config) ->
- [{max_size, 800}|Config].
-
-end_per_testcase(_Case, _Config) ->
- ok.
-
-%%----------------------------------------------------------------------
-%% Tests
-%%----------------------------------------------------------------------
-
-%% Image creation and destroy test.
-image_create_and_destroy(Config) when is_list(Config) ->
- {W,H} = get_size(proplists:get_value(max_size, Config)),
- Image = egd:create(W, H),
- ok = egd:destroy(Image),
- ok.
-
-%% Image color test.
-image_colors(Config) when is_list(Config) ->
- {W,H} = get_size(proplists:get_value(max_size, Config)),
- Dir = proplists:get_value(priv_dir, Config),
- Image = egd:create(W, H),
- put(image_size, {W,H}),
-
- RGB = get_rgb(),
- Black = egd:color({0,0,0}),
- Red = egd:color({255,0,0}),
- Green = egd:color({0,255,0}),
- Blue = egd:color({0,0,255}),
- Random = egd:color(Image, RGB),
-
- ok = egd:line(Image, get_point(), get_point(), Random),
- ok = egd:line(Image, get_point(), get_point(), Red),
- ok = egd:line(Image, get_point(), get_point(), Green),
- ok = egd:line(Image, get_point(), get_point(), Black),
- ok = egd:line(Image, get_point(), get_point(), Blue),
-
- HtmlDefaultNames = [black,silver,gray,white,maroon,red,
- purple,fuchia,green,lime,olive,yellow,navy,blue,teal,
- aqua],
-
- lists:foreach(fun (ColorName) ->
- Color = egd:color(ColorName),
- ok = egd:line(Image, get_point(), get_point(), Color)
- end, HtmlDefaultNames),
-
- Png1 = <<_/binary>> = egd:render(Image,png,[{render_engine, alpha}]),
- File1 = filename:join(Dir,"image_colors_alpha.png"),
- ok = egd:save(Png1,File1),
- ct:log("<p>Image alpha:</p><img src=\"~s\" />~n", [File1]),
- Png2 = <<_/binary>> = egd:render(Image,png,[{render_engine, opaque}]),
- File2 = filename:join(Dir,"image_colors_opaque.png"),
- ok = egd:save(Png2,File2),
- ct:log("<p>Image opaque:</p><img src=\"~s\" />~n", [File2]),
-
- ok = egd:destroy(Image),
- erase(image_size),
- ok.
-
-%% Image shape API test.
-image_shape(Config) when is_list(Config) ->
- {W,H} = get_size(proplists:get_value(max_size, Config)),
- Dir = proplists:get_value(priv_dir, Config),
- put(image_size, {W,H}),
- Im = egd:create(W, H),
-
- Fgc = egd:color({255,0,0}),
-
- ok = egd:line(Im, get_point(), get_point(), Fgc),
- ok = egd:rectangle(Im, get_point(), get_point(), Fgc),
- ok = egd:filledEllipse(Im, get_point(), get_point(), Fgc),
- ok = egd:arc(Im, get_point(), get_point(), Fgc),
- ok = egd:arc(Im, get_point(), get_point(), 100, Fgc),
-
- Pt1 = get_point(),
- Pt2 = get_point(),
-
- ok = egd:filledRectangle(Im, Pt1, Pt2, Fgc),
-
- Bitmap = egd:render(Im, raw_bitmap),
-
- ok = bitmap_point_has_color(Bitmap, {W,H}, Pt2, Fgc),
- ok = bitmap_point_has_color(Bitmap, {W,H}, Pt1, Fgc),
-
- Bin = <<_/binary>> = egd:render(Im, raw_bitmap, [{render_engine, alpha}]),
- Png = egd_png:binary(W,H,Bin),
- File = filename:join(Dir,"image_shape.png"),
- ok = egd:save(Png,File),
- ct:log("<p>Image:</p><img src=\"~s\" />~n", [File]),
-
- ok = egd:destroy(Im),
-
- erase(image_size),
- ok.
-
-%% Image shape API test.
-image_primitives(Config) when is_list(Config) ->
- {W,H} = get_size(proplists:get_value(max_size, Config)),
- Dir = proplists:get_value(priv_dir, Config),
- put(image_size, {W,H}),
-
- Im0 = egd_primitives:create(W, H),
- Fgc = egd:color({25,25,255}),
- Bgc = egd:color({0,250,25}),
-
- Im1 = lists:foldl(fun ({Function, Arguments}, Im) ->
- erlang:apply(egd_primitives, Function, [Im|Arguments])
- end, Im0,
- [{Fs, [get_point(), get_point(), Bgc]} || Fs <- [line, rectangle, filledEllipse, arc]] ++
- [{pixel, [get_point(), Bgc]},
- {filledTriangle, [get_point(), get_point(), get_point(), Bgc]}]),
-
- Pt1 = get_point(),
- Pt2 = get_point(),
-
- Im2 = egd_primitives:filledRectangle(Im1, Pt1, Pt2, Fgc),
-
- Bitmap = egd_render:binary(Im2, opaque),
-
- ok = bitmap_point_has_color(Bitmap, {W,H}, Pt2, Fgc),
- ok = bitmap_point_has_color(Bitmap, {W,H}, Pt1, Fgc),
-
- Bin = <<_/binary>> = egd_render:binary(Im2, alpha),
- Png = egd_png:binary(W,H,Bin),
- File = filename:join(Dir,"image_primitives.png"),
- ok = egd:save(Png,File),
- ct:log("<p>Image:</p><img src=\"~s\" />~n", [File]),
-
- erase(image_size),
- ok.
-
-%% Image font test.
-image_font(Config) when is_list(Config) ->
- {W,H} = get_size(proplists:get_value(max_size, Config)),
- Dir = proplists:get_value(priv_dir, Config),
- put(image_size, {W,H}),
- Im = egd:create(W, H),
- Fgc = egd:color({0,130,0}),
-
- Filename = filename:join([code:priv_dir(percept),"fonts","6x11_latin1.wingsfont"]),
- Font = egd_font:load(Filename),
-
- % simple text
- ok = egd:text(Im, get_point(), Font, "Hello World", Fgc),
- <<_/binary>> = egd:render(Im, png),
-
- GlyphStr1 = " !\"#$%&'()*+,-./", % Codes 32 -> 47
- NumericStr = "0123456789", % Codes 48 -> 57
- GlyphStr2 = ":;<=>?@", % Codes 58 -> 64
- AlphaBigStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", % Codes 65 -> 90
- GlyphStr3 = "[\\]^_`", % Codes 91 -> 96
- AlphaSmStr = "abcdefghijklmnopqrstuvwxyz", % Codes 97 -> 122
- GlyphStr4 = "{|}~", % Codes 123 -> 126
-
- ok = egd:text(Im, get_point(), Font, GlyphStr1, Fgc),
- Png1 = <<_/binary>> = egd:render(Im, png),
- File1 = filename:join(Dir,"text1.png"),
- ok = egd:save(Png1,File1),
- ct:log("<p>Image:</p><img src=\"~s\" />~n", [File1]),
-
- ok = egd:text(Im, get_point(), Font, NumericStr, Fgc),
- Png2 = <<_/binary>> = egd:render(Im, png),
- File2 = filename:join(Dir,"text2.png"),
- ok = egd:save(Png2,File2),
- ct:log("<p>Image:</p><img src=\"~s\" />~n", [File2]),
-
- ok = egd:text(Im, get_point(), Font, GlyphStr2, Fgc),
- Png3 = <<_/binary>> = egd:render(Im, png),
- File3 = filename:join(Dir,"text3.png"),
- ok = egd:save(Png3,File3),
- ct:log("<p>Image:</p><img src=\"~s\" />~n", [File3]),
-
- ok = egd:text(Im, get_point(), Font, AlphaBigStr, Fgc),
- Png4 = <<_/binary>> = egd:render(Im, png),
- File4 = filename:join(Dir,"text4.png"),
- ok = egd:save(Png4,File4),
- ct:log("<p>Image:</p><img src=\"~s\" />~n", [File4]),
-
- ok = egd:text(Im, get_point(), Font, GlyphStr3, Fgc),
- Png5 = <<_/binary>> = egd:render(Im, png),
- File5 = filename:join(Dir,"text5.png"),
- ok = egd:save(Png5,File5),
- ct:log("<p>Image:</p><img src=\"~s\" />~n", [File5]),
-
- ok = egd:text(Im, get_point(), Font, AlphaSmStr, Fgc),
- Png6 = <<_/binary>> = egd:render(Im, png),
- File6 = filename:join(Dir,"text6.png"),
- ok = egd:save(Png6,File6),
- ct:log("<p>Image:</p><img src=\"~s\" />~n", [File6]),
-
- ok = egd:text(Im, get_point(), Font, GlyphStr4, Fgc),
- Png7 = <<_/binary>> = egd:render(Im, png),
- File7 = filename:join(Dir,"text7.png"),
- ok = egd:save(Png7,File7),
- ct:log("<p>Image:</p><img src=\"~s\" />~n", [File7]),
-
- ok = egd:destroy(Im),
- erase(image_size),
- ok.
-
-%% Image png compliant test.
-image_png_compliant(Config) when is_list(Config) ->
- {W,H} = get_size(proplists:get_value(max_size, Config)),
- put(image_size, {W,H}),
- Im = egd:create(W, H),
- Fgc = egd:color({0,0,0}),
- ok = egd:filledRectangle(Im, get_point(), get_point(), Fgc),
-
- Bin = egd:render(Im, png),
- true = binary_is_png_compliant(Bin),
-
- ok = egd:destroy(Im),
- erase(image_size),
- ok.
-
-image_fans(Config) when is_list(Config) ->
- W = 1024,
- H = 800,
- Dir = proplists:get_value(priv_dir, Config),
-
- Fun = fun({F,Args},Im) ->
- erlang:apply(egd_primitives,F,[Im|Args])
- end,
-
- %% fan1
- Ops1 = gen_vertical_fan(1,{0,400},egd:color(red),1024,800,-15),
- Ops2 = gen_horizontal_fan(1,{512,800},egd:color(green),1024,0,-15),
-
- Im0 = egd_primitives:create(W,H),
- Im1 = lists:foldl(Fun, Im0, Ops1 ++ Ops2),
- Bin1 = egd_render:binary(Im1, opaque),
- Png1 = egd_png:binary(W,H,Bin1),
-
- File1 = filename:join(Dir,"fan1_opaque.png"),
- ok = egd:save(Png1,File1),
- ct:log("<p>Image opaque width 1:</p><img src=\"~s\" />~n", [File1]),
-
- Bin2 = egd_render:binary(Im1, alpha),
- Png2 = egd_png:binary(W,H,Bin2),
-
- File2 = filename:join(Dir,"fan1_alpha.png"),
- ok = egd:save(Png2,File2),
- ct:log("<p>Image alpha width 1:</p><img src=\"~s\" />~n", [File2]),
-
-
- %% fan2
- Ops3 = gen_vertical_fan(7,{0,400},egd:color(red),1024,800,-15),
- Ops4 = gen_horizontal_fan(7,{512,800},egd:color(green),1024,0,-15),
-
- Im2 = lists:foldl(Fun, Im0, Ops3 ++ Ops4),
- Bin3 = egd_render:binary(Im2, opaque),
- Png3 = egd_png:binary(W,H,Bin3),
-
- File3 = filename:join(Dir,"fan2_opaque.png"),
- ok = egd:save(Png3,File3),
- ct:log("<p>Image opaque width 7:</p><img src=\"~s\" />~n", [File3]),
-
- Bin4 = egd_render:binary(Im2, alpha),
- Png4 = egd_png:binary(W,H,Bin4),
-
- File4 = filename:join(Dir,"fan2_alpha.png"),
- ok = egd:save(Png4,File4),
- ct:log("<p>Image alpha width 7:</p><img src=\"~s\" />~n", [File4]),
- ok.
-
-gen_vertical_fan(Wd,Pt,C,X,Y,Step) when Y > 0 ->
- [{line,[Pt,{X,Y},Wd,C]}|gen_vertical_fan(Wd,Pt,C,X,Y + Step,Step)];
-gen_vertical_fan(_,_,_,_,_,_) -> [].
-
-gen_horizontal_fan(Wd,Pt,C,X,Y,Step) when X > 0 ->
- [{line,[Pt,{X,Y},Wd,C]}|gen_horizontal_fan(Wd,Pt,C,X + Step,Y,Step)];
-gen_horizontal_fan(_,_,_,_,_,_) -> [].
-
-
-%%----------------------------------------------------------------------
-%% Auxiliary tests
-%%----------------------------------------------------------------------
-
-bitmap_point_has_color(Bitmap, {W,_}, {X,Y}, C) ->
- {CR,CG,CB,_} = egd_primitives:rgb_float2byte(C),
- N = W*Y*3 + X*3,
- << _:N/binary, R,G,B, _/binary>> = Bitmap,
- case {R,G,B} of
- {CR,CG,CB} -> ok;
- Other ->
- io:format("bitmap_point_has_color: error color was ~p, should be ~p~n", [Other, {CR,CG,CB}]),
- {error, {Other,{CR,CG,CB}}}
- end.
-
-binary_is_png_compliant(PngBin) ->
- {Bin, _} = split_binary(PngBin, 10),
- List = binary_to_list(Bin),
- case lists:sublist(List, 2,3) of
- "PNG" -> true;
- Other ->
- io:format("img -> ~p~n", [Other]),
- false
- end.
-
-%%----------------------------------------------------------------------
-%% Auxiliary
-%%----------------------------------------------------------------------
-
-
-get_rgb() ->
- R = random(255),
- G = random(255),
- B = random(255),
- {R,G,B}.
-
-get_angle() ->
- random(359).
-
-get_point() ->
- get_point(get(image_size)).
-get_point({W,H}) ->
- X = random(W - 1),
- Y = random(H - 1),
- {X,Y}.
-
-get_size(Max) ->
- W = trunc(random(Max/2) + Max/2 + 1),
- H = trunc(random(Max/2) + Max/2 + 1),
- io:format("Image size will be ~p x ~p~n", [W,H]),
- {W,H}.
-
-get_points(N) ->
- get_points(N, []).
-get_points(0, Out) ->
- Out;
-get_points(N, Out) ->
- get_points(N - 1, [get_point() | Out]).
-
-random(N) -> trunc(rand:uniform(trunc(N + 1)) - 1).
diff --git a/lib/percept/test/ipc_tree.erl b/lib/percept/test/ipc_tree.erl
deleted file mode 100644
index 29da20e83f..0000000000
--- a/lib/percept/test/ipc_tree.erl
+++ /dev/null
@@ -1,49 +0,0 @@
-%% ``Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% 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(ipc_tree).
--export([go/1, init/2]).
-
-go(N) ->
- start(N, self()),
- receive stop -> ok end.
-
-start(Depth, ParentPid) ->
- spawn(?MODULE, init, [Depth, ParentPid]).
-
-init(0, ParentPid) ->
- workload(5000),
- ParentPid ! stop,
- ok;
-init(Depth, ParentPid) ->
- Pid1 = spawn(?MODULE, init, [Depth - 1, self()]),
- Pid2 = spawn(?MODULE, init, [Depth - 1, self()]),
- main([Pid1,Pid2], ParentPid).
-
-main(Pids, ParentPid) ->
- workload(5000),
- gather(Pids),
- ParentPid ! stop,
- ok.
-
-gather([]) -> ok;
-gather([_|Pids]) -> receive _ -> gather(Pids) end.
-
-workload(0) -> ok;
-workload(N) -> _ = math:sin(2), workload(N - 1).
diff --git a/lib/percept/test/percept.cover b/lib/percept/test/percept.cover
deleted file mode 100644
index 8a5ad0a55e..0000000000
--- a/lib/percept/test/percept.cover
+++ /dev/null
@@ -1,2 +0,0 @@
-{incl_app,percept,details}.
-
diff --git a/lib/percept/test/percept.spec b/lib/percept/test/percept.spec
deleted file mode 100644
index f3ef76bd60..0000000000
--- a/lib/percept/test/percept.spec
+++ /dev/null
@@ -1 +0,0 @@
-{suites,"../percept_test",all}.
diff --git a/lib/percept/test/percept_SUITE.erl b/lib/percept/test/percept_SUITE.erl
deleted file mode 100644
index fbc77302ae..0000000000
--- a/lib/percept/test/percept_SUITE.erl
+++ /dev/null
@@ -1,126 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
--module(percept_SUITE).
--include_lib("common_test/include/ct.hrl").
-
-%% Test server specific exports
--export([all/0, suite/0]).
-
-%% Test cases
--export([app/1,
- appup/1,
- profile/1,
- analyze/1,
- analyze_dist/1,
- webserver/1]).
-
-suite() ->
- [{ct_hooks,[ts_install_cth]},
- {timetrap, {minutes, 2}}].
-
-all() ->
- [app, appup, webserver, profile,
- analyze, analyze_dist].
-
-
-%%----------------------------------------------------------------------
-%% Tests
-%%----------------------------------------------------------------------
-
-%% Test that the percept app file is ok
-app(Config) when is_list(Config) ->
- ok = test_server:app_test(percept).
-
-%% Test that the percept appup file is ok
-appup(Config) when is_list(Config) ->
- ok = test_server:appup_test(percept).
-
-%% Percept webserver test.
-webserver(Config) when is_list(Config) ->
- % Explicit start inets?
- {started, _, Port} = percept:start_webserver(),
- ok = percept:stop_webserver(Port),
- {started, _, _} = percept:start_webserver(),
- ok = percept:stop_webserver(),
- {started, _, NewPort} = percept:start_webserver(),
- ok = percept:stop_webserver(NewPort),
- application:stop(inets),
- ok.
-
-%% Percept profile test.
-profile(Config) when is_list(Config) ->
- Path = proplists:get_value(data_dir, Config),
- File = filename:join([Path,"profile_test.dat"]),
- {ok, _} = percept:profile(File, [procs]),
- ipc_tree:go(7),
- ok = percept:stop_profile(),
- ok.
-
-%% Percept analyze test.
-analyze(Config) when is_list(Config) ->
- Begin = processes(),
- Path = proplists:get_value(data_dir, Config),
- File = filename:join([Path,"profile_test.dat"]),
- T0 = erlang:monotonic_time(milli_seconds),
- ok = percept:analyze(File),
- T1 = erlang:monotonic_time(milli_seconds),
- io:format("percept:analyze/1 took ~w ms.~n", [T1 - T0]),
- {stopped, _} = percept_db:stop(),
- print_remainers(remainers(Begin, processes())),
- ok.
-
-%% Percept analyze distribution test.
-analyze_dist(Config) when is_list(Config) ->
- Begin = processes(),
- Path = proplists:get_value(data_dir, Config),
- File = filename:join([Path,"ipc-dist.dat"]),
- T0 = erlang:monotonic_time(milli_seconds),
- ok = percept:analyze(File),
- T1 = erlang:monotonic_time(milli_seconds),
- io:format("percept:analyze/1 took ~w ms.~n", [T1 - T0]),
- {stopped, _} = percept_db:stop(),
- print_remainers(remainers(Begin, processes())),
- ok.
-
-%%----------------------------------------------------------------------
-%% Auxiliary tests
-%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Auxiliary
-%%----------------------------------------------------------------------
-
-print_remainers([]) -> ok;
-print_remainers([Pid|Pids]) ->
- io:format("[Pid ~p] [Entry ~p] [Name ~p]~n", [
- Pid,
- erlang:process_info(Pid, initial_call),
- erlang:process_info(Pid, registered_name)
- ]),
- print_remainers(Pids).
-
-remainers(Begin, End) -> remainers(Begin, End, []).
-remainers(_, [], Out) -> lists:reverse(Out);
-remainers(Begin, [Pid|End], Out) ->
- case lists:member(Pid, Begin) of
- true -> remainers(Begin, End, Out);
- false -> remainers(Begin, End, [Pid|Out])
- end.
diff --git a/lib/percept/test/percept_SUITE_data/ipc-dist.dat b/lib/percept/test/percept_SUITE_data/ipc-dist.dat
deleted file mode 100644
index 14ab6c0c5d..0000000000
--- a/lib/percept/test/percept_SUITE_data/ipc-dist.dat
+++ /dev/null
Binary files differ
diff --git a/lib/percept/test/percept_db_SUITE.erl b/lib/percept/test/percept_db_SUITE.erl
deleted file mode 100644
index b2827e0e42..0000000000
--- a/lib/percept/test/percept_db_SUITE.erl
+++ /dev/null
@@ -1,55 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
--module(percept_db_SUITE).
--include_lib("common_test/include/ct.hrl").
-
-%% Test server specific exports
--export([all/0, suite/0]).
-
-%% Test cases
--export([start/1]).
-
-%% Default timetrap timeout (set in init_per_testcase)
--define(restarts, 10).
--define(alive_timeout, 500).
-
-suite() ->
- [{timetrap, {minutes, 2}}].
-
-all() ->
- [start].
-
-%%----------------------------------------------------------------------
-%% Tests
-%%----------------------------------------------------------------------
-
-%% Percept_db start and restart test.
-start(Config) when is_list(Config) ->
- ok = restart(?restarts),
- {stopped, _DB} = percept_db:stop(),
- ok.
-
-restart(0)-> ok;
-restart(N)->
- {_, DB} = percept_db:start(),
- timer:sleep(?alive_timeout),
- true = erlang:is_process_alive(DB),
- restart(N-1).
diff --git a/lib/percept/vsn.mk b/lib/percept/vsn.mk
deleted file mode 100644
index 614cee8645..0000000000
--- a/lib/percept/vsn.mk
+++ /dev/null
@@ -1 +0,0 @@
-PERCEPT_VSN = 0.9
diff --git a/lib/public_key/asn1/PKCS-8.asn1 b/lib/public_key/asn1/PKCS-8.asn1
index 8412345b68..292a7b2029 100644
--- a/lib/public_key/asn1/PKCS-8.asn1
+++ b/lib/public_key/asn1/PKCS-8.asn1
@@ -26,7 +26,7 @@ BEGIN
-- This import is really unnecessary since ALGORITHM-IDENTIFIER is defined as a
-- TYPE-IDENTIFIER
--- Renome this import and replace all occurences of ALGORITHM-IDENTIFIER with
+-- Rename this import and replace all occurrences of ALGORITHM-IDENTIFIER with
-- TYPE-IDENTIFIER as a workaround for weaknesses in the ASN.1 compiler
--AlgorithmIdentifier, ALGORITHM-IDENTIFIER
-- FROM PKCS5v2-0 {iso(1) member-body(2) us(840) rsadsi(113549)
diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml
index c4d930c01f..64592a6d87 100644
--- a/lib/public_key/doc/src/notes.xml
+++ b/lib/public_key/doc/src/notes.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -35,6 +35,86 @@
<file>notes.xml</file>
</header>
+<section><title>Public_Key 1.4.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Bug for <c>public_key:generate_key({namedCurve,OID})</c>
+ fixed.</p>
+ <p>
+ Own Id: OTP-14258</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Modernized internal representation used for crl
+ validation by use of maps.</p>
+ <p>
+ Own Id: OTP-14111</p>
+ </item>
+ <item>
+ <p>
+ Support EC key in pkix_sign/2</p>
+ <p>
+ Own Id: OTP-14294</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Public_Key 1.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ New function <c>pkix_verify_hostname/2,3</c> Implements
+ certificate hostname checking. See the manual and RFC
+ 6125.</p>
+ <p>
+ Own Id: OTP-13009</p>
+ </item>
+ <item>
+ <p>
+ The ssh host key fingerprint generation now also takes a
+ list of algorithms and returns a list of corresponding
+ fingerprints. See
+ <c>public_key:ssh_hostkey_fingerprint/2</c> and the
+ option <c>silently_accept_hosts</c> in
+ <c>ssh:connect</c>.</p>
+ <p>
+ Own Id: OTP-14223</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Public_Key 1.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ New function
+ <c>public_key:ssh_hostkey_fingerprint/1,2</c> to
+ calculate the SSH host key fingerprint string.</p>
+ <p>
+ Own Id: OTP-13888 Aux Id: OTP-13887 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Public_Key 1.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index 385604677c..04966ffb9c 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2015</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -331,13 +331,17 @@
</func>
<func>
- <name>generate_key(Params) -> {Public::binary(), Private::binary()} | #'ECPrivateKey'{} </name>
+ <name>generate_key(Params) -> {Public::binary(), Private::binary()} | #'ECPrivateKey'{} | #'RSAPrivateKey'{}</name>
<fsummary>Generates a new keypair.</fsummary>
<type>
- <v>Params = #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{}</v>
+ <v>Params = #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{}
+ | {rsa, Size::integer(), PubExp::integer} </v>
</type>
<desc>
- <p>Generates a new keypair.</p>
+ <p>Generates a new keypair. Note that except for Diffie-Hellman
+ the public key is included in the private key structure. See also
+ <seealso marker="crypto:crypto#generate_key/2">crypto:generate_key/2</seealso>
+ </p>
</desc>
</func>
@@ -757,6 +761,39 @@ fun(#'DistributionPoint'{}, #'CertificateList'{},
</func>
<func>
+ <name>pkix_verify_hostname(Cert, ReferenceIDs) -> boolean()</name>
+ <name>pkix_verify_hostname(Cert, ReferenceIDs, Opts) -> boolean()</name>
+ <fsummary>Verifies that a PKIX x.509 certificate <i>presented identifier</i> (e.g hostname) is
+ an expected one.</fsummary>
+ <type>
+ <v>Cert = der_encoded() | #'OTPCertificate'{} </v>
+ <v>ReferenceIDs = [ RefID ]</v>
+ <v>RefID = {IdType,string()}</v>
+ <v>IdType = dns_id | srv_id | uri_id</v>
+ <v>Opts = [ PvhOpt() ]</v>
+ <v>PvhOpt = [MatchOpt | FailCallBackOpt | FqdnExtractOpt]</v>
+ <v>MatchOpt = {fun(RefId | FQDN::string(), PresentedID) -> boolean() | default}</v>
+ <v>PresentedID = {dNSName,string()} | {uniformResourceIdentifier,string()}</v>
+ <v>FailCallBackOpt = {fail_callback, fun(#'OTPCertificate'{}) -> boolean()}</v>
+ <v>FqdnExtractOpt = {fqdn_fun, fun(RefID) -> FQDN::string() | default | undefined}</v>
+ </type>
+ <desc>
+ <p>This function checks that the <i>Presented Identifier</i> (e.g hostname) in a peer certificate
+ conforms with the Expected Identifier that the client wants to connect to.
+ This functions is intended to be added as an extra client check to the peer certificate when performing
+ <seealso marker="public_key:public_key#pkix_path_validation-3">public_key:pkix_path_validation/3</seealso>
+ </p>
+ <p>See <url href="https://tools.ietf.org/html/rfc6125">RFC 6125</url>
+ for detailed information about hostname verification.
+ The <seealso marker="using_public_key#verify_hostname">User's Manual</seealso>
+ and
+ <seealso marker="using_public_key#verify_hostname_examples">code examples</seealso>
+ describes this function more detailed.
+ </p>
+ </desc>
+ </func>
+
+ <func>
<name>sign(Msg, DigestType, Key) -> binary()</name>
<fsummary>Creates a digital signature.</fsummary>
<type>
@@ -822,6 +859,41 @@ fun(#'DistributionPoint'{}, #'CertificateList'{},
</func>
<func>
+ <name>ssh_hostkey_fingerprint(HostKey) -> string()</name>
+ <name>ssh_hostkey_fingerprint(DigestType, HostKey) -> string()</name>
+ <name>ssh_hostkey_fingerprint([DigestType], HostKey) -> [string()]</name>
+ <fsummary>Calculates a ssh fingerprint for a hostkey.</fsummary>
+ <type>
+ <v>Key = public_key()</v>
+ <v>DigestType = digest_type()</v>
+ </type>
+ <desc>
+ <p>Calculates a ssh fingerprint from a public host key as openssh does.</p>
+ <p>The algorithm in <c>ssh_hostkey_fingerprint/1</c> is md5 to be compatible with older
+ ssh-keygen commands. The string from the second variant is prepended by the algorithm name
+ in uppercase as in newer ssh-keygen commands.</p>
+ <p>Examples:</p>
+ <code>
+ 2> public_key:ssh_hostkey_fingerprint(Key).
+ "f5:64:a6:c1:5a:cb:9f:0a:10:46:a2:5c:3e:2f:57:84"
+
+ 3> public_key:ssh_hostkey_fingerprint(md5,Key).
+ "MD5:f5:64:a6:c1:5a:cb:9f:0a:10:46:a2:5c:3e:2f:57:84"
+
+ 4> public_key:ssh_hostkey_fingerprint(sha,Key).
+ "SHA1:bSLY/C4QXLDL/Iwmhyg0PGW9UbY"
+
+ 5> public_key:ssh_hostkey_fingerprint(sha256,Key).
+ "SHA256:aZGXhabfbf4oxglxltItWeHU7ub3Dc31NcNw2cMJePQ"
+
+ 6> public_key:ssh_hostkey_fingerprint([sha,sha256],Key).
+ ["SHA1:bSLY/C4QXLDL/Iwmhyg0PGW9UbY",
+ "SHA256:aZGXhabfbf4oxglxltItWeHU7ub3Dc31NcNw2cMJePQ"]
+ </code>
+ </desc>
+ </func>
+
+ <func>
<name>verify(Msg, DigestType, Signature, Key) -> boolean()</name>
<fsummary>Verifies a digital signature.</fsummary>
<type>
diff --git a/lib/public_key/doc/src/public_key_app.xml b/lib/public_key/doc/src/public_key_app.xml
index 1f87932b6c..923a9f1dfb 100644
--- a/lib/public_key/doc/src/public_key_app.xml
+++ b/lib/public_key/doc/src/public_key_app.xml
@@ -61,7 +61,7 @@
<section>
<title>DEPENDENCIES</title>
<p>The <c>public_key</c> application uses the
- Crypto application to preform cryptographic operations and the
+ Crypto application to perform cryptographic operations and the
ASN-1 application to handle PKIX-ASN-1 specifications, hence
these applications must be loaded for the <c>public_key</c> application to work.
In an embedded environment this means they must be started with
@@ -72,7 +72,7 @@
<section>
<title>ERROR LOGGER AND EVENT HANDLERS</title>
<p> The <c>public_key</c> application is a library application
- and does not use the error logger. The functions will either sucssed
+ and does not use the error logger. The functions will either succeed
or fail with a runtime error.
</p>
</section>
diff --git a/lib/public_key/doc/src/using_public_key.xml b/lib/public_key/doc/src/using_public_key.xml
index e3a1eed4be..417d479da3 100644
--- a/lib/public_key/doc/src/using_public_key.xml
+++ b/lib/public_key/doc/src/using_public_key.xml
@@ -417,6 +417,259 @@ true = public_key:verify(Digest, none, Signature, PublicKey),</code>
</section>
+ <section>
+ <marker id="verify_hostname"></marker>
+ <title>Verifying a certificate hostname</title>
+ <section>
+ <title>Background</title>
+ <p>When a client checks a server certificate there are a number of checks available like
+ checks that the certificate is not revoked, not forged or not out-of-date.
+ </p>
+ <p>There are however attacks that are not detected by those checks. Suppose a bad guy has
+ succeded with a DNS infection. Then the client could belive it is connecting to one host but
+ ends up at another but evil one. Though it is evil, it could have a perfectly legal
+ certificate! The certificate has a valid signature, it is not revoked, the certificate chain
+ is not faked and has a trusted root and so on.
+ </p>
+ <p>To detect that the server is not the intended one, the client must additionaly perform
+ a <i>hostname verification</i>. This procedure is described in
+ <url href="https://tools.ietf.org/html/rfc6125">RFC 6125</url>. The idea is that the certificate
+ lists the hostnames it could be fetched from. This is checked by the certificate issuer when
+ the certificate is signed. So if the certificate is issued by a trusted root the client
+ could trust the host names signed in it.
+ </p>
+ <p>There is a default hostname matching procedure defined in
+ <url href="https://tools.ietf.org/html/rfc6125#section-6">RFC 6125, section 6</url>
+ as well as protocol dependent variations defined in
+ <url href="https://tools.ietf.org/html/rfc6125#appendix-B">RFC 6125 appendix B</url>.
+ The default procedure is implemented in
+ <seealso marker="public_key:public_key#pkix_verify_hostname-2">public_key:pkix_verify_hostname/2,3</seealso>.
+ It is possible for a client to hook in modified rules using the options list.
+ </p>
+ <p>Some terminology is needed: the certificate presents hostname(s) on which it is valid.
+ Those are called <i>Presented IDs</i>. The hostname(s) the client belives it connects to
+ are called <i>Reference IDs</i>. The matching rules aims to verify that there is at least
+ one of the Reference IDs that matches one of the Presented IDs. If not, the verification fails.
+ </p>
+ <p>The IDs contains normal fully qualified domain names like e.g <c>foo.example.com</c>,
+ but IP addresses are not recommended. The rfc describes why this is not recommended as well
+ as security considerations about how to aquire the Reference IDs.
+ </p>
+ <p>Internationalized domain names are not supported.
+ </p>
+ </section>
+ <section>
+ <title>The verification process</title>
+ <p>Traditionally the Presented IDs were found in the <c>Subject</c> certificate field as <c>CN</c>
+ names. This is still quite common. When printing a certificate they show up as:
+ </p>
+ <code>
+ $ openssl x509 -text &lt; cert.pem
+ ...
+ Subject: C=SE, CN=example.com, CN=*.example.com, O=erlang.org
+ ...
+ </code>
+ <p>The example <c>Subject</c> field has one C, two CN and one O part. It is only the
+ CN (Common Name) that is used by hostname verification. The two other (C and O) is not used
+ here even when they contain a domain name like the O part. The C and O parts are defined
+ elsewhere and meaningful only for other functions.
+ </p>
+ <p>In the example the Presented IDs are <c>example.com</c> as well as hostnames matching
+ <c>*.example.com</c>. For example <c>foo.example.com</c> and <c>bar.example.com</c> both
+ matches but not <c>foo.bar.example.com</c>. The name <c>erlang.org</c> matches neither
+ since it is not a CN.
+ </p>
+ <p>In case where the Presented IDs are fetched from the <c>Subject</c> certificate field, the
+ names may contain wildcard characters. The function handles this as defined in
+ <url href="https://tools.ietf.org/html/rfc6125#section-6.4.3">chapter 6.4.3 in RFC 6125</url>.
+ </p>
+ <p>There may only be one wildcard character and that is in the first label, for example:
+ <c>*.example.com</c>. This matches <c>foo.example.com</c> but neither <c>example.com</c> nor
+ <c>foo.bar.example.com</c>.
+ </p>
+ <p>There may be label characters before or/and after the wildcard. For example:
+ <c>a*d.example.com</c> matches <c>abcd.example.com</c> and <c>ad.example.com</c>,
+ but not <c>ab.cd.example.com</c>.
+ </p>
+ <p>In the previous example there is no indication of which protocols are expected. So a client
+ has no indication of whether it is a web server, an ldap server or maybe a sip server it is
+ connected to.
+ There are fields in the certificate that can indicate this. To be more exact, the rfc
+ introduces the usage of the <c>X509v3 Subject Alternative Name</c> in the <c>X509v3 extensions</c>
+ field:
+ </p>
+ <code>
+ $ openssl x509 -text &lt; cert.pem
+ ...
+ X509v3 extensions:
+ X509v3 Subject Alternative Name:
+ DNS:kb.example.org, URI:https://www.example.org
+ ...
+ </code>
+ <p>Here <c>kb.example.org</c> serves any protocol while <c>www.example.org</c> presents a secure
+ web server.
+ </p>
+
+ <p>The next example has both <c>Subject</c> and <c>Subject Alternate Name</c> present:</p>
+ <code>
+ $ openssl x509 -text &lt; cert.pem
+ ...
+ Subject: C=SE, CN=example.com, CN=*.example.com, O=erlang.org
+ ...
+ X509v3 extensions:
+ X509v3 Subject Alternative Name:
+ DNS:kb.example.org, URI:https://www.example.org
+ ...
+ </code>
+ <p>The RFC states that if a certificate defines Reference IDs in a <c>Subject Alternate Name</c>
+ field, the <c>Subject</c> field MUST NOT be used for host name checking, even if it contains
+ valid CN names.
+ Therefore only <c>kb.example.org</c> and <c>https://www.example.org</c> matches. The match fails
+ both for <c>example.com</c> and <c>foo.example.com</c> becuase they are in the <c>Subject</c>
+ field which is not checked because the <c>Subject Alternate Name</c> field is present.
+ </p>
+ </section>
+
+ <section>
+ <marker id="verify_hostname_examples"></marker>
+ <title>Function call examples</title>
+ <note>
+ <p>Other applications like ssl/tls or https might have options that are passed
+ down to the <c>public_key:pkix_verify_hostname</c>. You will probably not
+ have to call it directly</p>
+ </note>
+ <p>Suppose our client expects to connect to the web server https://www.example.net. This
+ URI is therefore the Reference IDs of the client.
+ The call will be:
+ </p>
+ <code>
+ public_key:pkix_verify_hostname(CertFromHost,
+ [{uri_id, "https://www.example.net"}
+ ]).
+ </code>
+ <p>The call will return <c>true</c> or <c>false</c> depending on the check. The caller
+ do not need to handle the matching rules in the rfc. The matching will proceed as:
+ </p>
+ <list>
+ <item>If there is a <c>Subject Alternate Name</c> field, the <c>{uri_id,string()}</c> in the
+ function call will be compared to any
+ <c>{uniformResourceIdentifier,string()}</c> in the Certificate field.
+ If the two <c>strings()</c> are equal (case insensitive), there is a match.
+ The same applies for any <c>{dns_id,string()}</c> in the call which is compared
+ with all <c>{dNSName,string()}</c> in the Certificate field.
+ </item>
+ <item>If there is NO <c>Subject Alternate Name</c> field, the <c>Subject</c> field will be
+ checked. All <c>CN</c> names will be compared to all hostnames <i>extracted</i> from
+ <c>{uri_id,string()}</c> and from <c>{dns_id,string()}</c>.
+ </item>
+ </list>
+ </section>
+ <section>
+ <title>Extending the search mechanism</title>
+ <p>The caller can use own extraction and matching rules. This is done with the two options
+ <c>fqdn_fun</c> and <c>match_fun</c>.
+ </p>
+ <section>
+ <title>Hostname extraction</title>
+ <p>The <c>fqdn_fun</c> extracts hostnames (Fully Qualified Domain Names) from uri_id
+ or other ReferenceIDs that are not pre-defined in the public_key function.
+ Suppose you have some URI with a very special protocol-part:
+ <c>myspecial://example.com"</c>. Since this a non-standard URI there will be no hostname
+ extracted for matching CN-names in the <c>Subject</c>.</p>
+ <p>To "teach" the function how to extract, you can give a fun which replaces the default
+ extraction function.
+ The <c>fqdn_fun</c> takes one argument and returns
+ either a <c>string()</c> to be matched to each CN-name or the atom <c>default</c> which will invoke
+ the default fqdn extraction function. The return value <c>undefined</c> removes the current
+ URI from the fqdn extraction.
+ </p>
+ <code>
+ ...
+ Extract = fun({uri_id, "myspecial://"++HostName}) -> HostName;
+ (_Else) -> default
+ end,
+ ...
+ public_key:pkix_verify_hostname(CertFromHost, RefIDs,
+ [{fqdn_fun, Extract}])
+ ...
+ </code>
+ </section>
+ <section>
+ <title>Re-defining the match operations</title>
+ <p>The default matching handles dns_id and uri_id. In an uri_id the value is tested for
+ equality with a value from the <c>Subject Alternate Name</c>. If som other kind of matching
+ is needed, use the <c>match_fun</c> option.
+ </p>
+ <p>The <c>match_fun</c> takes two arguments and returns either <c>true</c>,
+ <c>false</c> or <c>default</c>. The value <c>default</c> will invoke the default
+ match function.
+ </p>
+ <code>
+ ...
+ Match = fun({uri_id,"myspecial://"++A},
+ {uniformResourceIdentifier,"myspecial://"++B}) ->
+ my_match(A,B);
+ (_RefID, _PresentedID) ->
+ default
+ end,
+ ...
+ public_key:pkix_verify_hostname(CertFromHost, RefIDs,
+ [{match_fun, Match}]),
+ ...
+ </code>
+ <p>In case of a match operation between a ReferenceID and a CN value from the <c>Subject</c>
+ field, the first argument to the fun is the extracted hostname from the ReferenceID, and the
+ second argument is the tuple <c>{cn, string()}</c> taken from the <c>Subject</c> field. That
+ makes it possible to have separate matching rules for Presented IDs from the <c>Subject</c>
+ field and from the <c>Subject Alternate Name</c> field.
+ </p>
+ <p>The default matching transformes the ascii values in strings to lowercase before comparing.
+ The <c>match_fun</c> is however called without any transfomation applied to the strings. The
+ reason is to enable the user to do unforseen handling of the strings where the original format
+ is needed.
+ </p>
+ </section>
+ </section>
+ <section>
+ <title>"Pinning" a Certificate</title>
+ <p>The <url href="https://tools.ietf.org/html/rfc6125">RFC 6125</url> defines <i>pinning</i>
+ as:</p>
+ <quote>
+ <p>"The act of establishing a cached name association between
+ the application service's certificate and one of the client's
+ reference identifiers, despite the fact that none of the presented
+ identifiers matches the given reference identifier. ..."
+ </p>
+ </quote>
+ <p>The purpose is to have a mechanism for a human to accept an otherwise faulty Certificate.
+ In for example a web browser, you could get a question like </p>
+ <quote>
+ <p>Warning: you wanted to visit the site www.example.com,
+ but the certificate is for shop.example.com. Accept anyway (yes/no)?"
+ </p>
+ </quote>
+ <p>This could be accomplished with the option <c>fail_callback</c> which will
+ be called if the hostname verification fails:
+ </p>
+ <code>
+ -include_lib("public_key/include/public_key.hrl"). % Record def
+ ...
+ Fail = fun(#'OTPCertificate'{}=C) ->
+ case in_my_cache(C) orelse my_accept(C) of
+ true ->
+ enter_my_cache(C),
+ true;
+ false ->
+ false
+ end,
+ ...
+ public_key:pkix_verify_hostname(CertFromHost, RefIDs,
+ [{fail_callback, Fail}]),
+ ...
+ </code>
+ </section>
+ </section>
+
<section>
<title>SSH Files</title>
diff --git a/lib/public_key/src/pubkey_ssh.erl b/lib/public_key/src/pubkey_ssh.erl
index 90726b1eb3..9bda76d670 100644
--- a/lib/public_key/src/pubkey_ssh.erl
+++ b/lib/public_key/src/pubkey_ssh.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -44,11 +44,6 @@
%%====================================================================
%%--------------------------------------------------------------------
--spec decode(binary(), public_key | public_key:ssh_file()) ->
- [{public_key:public_key(), Attributes::list()}]
- ; (binary(), ssh2_pubkey) -> public_key:public_key()
- .
-%%
%% Description: Decodes a ssh file-binary.
%%--------------------------------------------------------------------
decode(Bin, public_key)->
@@ -66,11 +61,6 @@ decode(Bin, Type) ->
openssh_decode(Bin, Type).
%%--------------------------------------------------------------------
--spec encode([{public_key:public_key(), Attributes::list()}], public_key:ssh_file()) ->
- binary()
- ; (public_key:public_key(), ssh2_pubkey) -> binary()
- .
-%%
%% Description: Encodes a list of ssh file entries.
%%--------------------------------------------------------------------
encode(Bin, ssh2_pubkey) ->
@@ -81,10 +71,6 @@ encode(Entries, Type) ->
end, Entries)).
%%--------------------------------------------------------------------
--spec dh_gex_group(integer(), integer(), integer(),
- undefined | [{integer(),[{integer(),integer()}]}]) ->
- {ok,{integer(),{integer(),integer()}}} | {error,any()} .
-%%
%% Description: Returns Generator and Modulus given MinSize, WantedSize
%% and MaxSize
%%--------------------------------------------------------------------
@@ -421,14 +407,22 @@ comma_list_encode([Option | Rest], []) ->
comma_list_encode([Option | Rest], Acc) ->
comma_list_encode(Rest, Acc ++ "," ++ Option).
+
ssh2_pubkey_encode(#'RSAPublicKey'{modulus = N, publicExponent = E}) ->
- TypeStr = <<"ssh-rsa">>,
- StrLen = size(TypeStr),
+ ssh2_pubkey_encode({#'RSAPublicKey'{modulus = N, publicExponent = E}, 'ssh-rsa'});
+
+ssh2_pubkey_encode({Key, 'rsa-sha2-256'}) -> ssh2_pubkey_encode({Key, 'ssh-rsa'});
+ssh2_pubkey_encode({Key, 'rsa-sha2-512'}) -> ssh2_pubkey_encode({Key, 'ssh-rsa'});
+ssh2_pubkey_encode({#'RSAPublicKey'{modulus = N, publicExponent = E}, SignAlg}) ->
+ SignAlgName = list_to_binary(atom_to_list(SignAlg)),
+ StrLen = size(SignAlgName),
EBin = mpint(E),
NBin = mpint(N),
- <<?UINT32(StrLen), TypeStr:StrLen/binary,
+ <<?UINT32(StrLen), SignAlgName:StrLen/binary,
EBin/binary,
NBin/binary>>;
+ssh2_pubkey_encode({{_,#'Dss-Parms'{}}=Key, _}) ->
+ ssh2_pubkey_encode(Key);
ssh2_pubkey_encode({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) ->
TypeStr = <<"ssh-dss">>,
StrLen = size(TypeStr),
@@ -441,6 +435,8 @@ ssh2_pubkey_encode({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) ->
QBin/binary,
GBin/binary,
YBin/binary>>;
+ssh2_pubkey_encode({{#'ECPoint'{},_}=Key, _}) ->
+ ssh2_pubkey_encode(Key);
ssh2_pubkey_encode(Key={#'ECPoint'{point = Q}, {namedCurve,OID}}) ->
TypeStr = key_type(Key),
StrLen = size(TypeStr),
@@ -453,6 +449,8 @@ ssh2_pubkey_encode(Key={#'ECPoint'{point = Q}, {namedCurve,OID}}) ->
ssh2_pubkey_decode(Bin = <<?UINT32(Len), Type:Len/binary, _/binary>>) ->
ssh2_pubkey_decode(Type, Bin).
+ssh2_pubkey_decode(<<"rsa-sha2-256">>, Bin) -> ssh2_pubkey_decode(<<"ssh-rsa">>, Bin);
+ssh2_pubkey_decode(<<"rsa-sha2-512">>, Bin) -> ssh2_pubkey_decode(<<"ssh-rsa">>, Bin);
ssh2_pubkey_decode(<<"ssh-rsa">>,
<<?UINT32(Len), _:Len/binary,
?UINT32(SizeE), E:SizeE/binary,
@@ -470,6 +468,7 @@ ssh2_pubkey_decode(<<"ssh-dss">>,
#'Dss-Parms'{p = erlint(SizeP, P),
q = erlint(SizeQ, Q),
g = erlint(SizeG, G)}};
+
ssh2_pubkey_decode(<<"ecdsa-sha2-",Id/binary>>,
<<?UINT32(Len), ECDSA_SHA2_etc:Len/binary,
?UINT32(SizeId), Id:SizeId/binary,
diff --git a/lib/public_key/src/public_key.app.src b/lib/public_key/src/public_key.app.src
index 88ef07c5a6..dbd732c384 100644
--- a/lib/public_key/src/public_key.app.src
+++ b/lib/public_key/src/public_key.app.src
@@ -14,7 +14,7 @@
{applications, [asn1, crypto, kernel, stdlib]},
{registered, []},
{env, []},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0","crypto-3.3",
+ {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0","crypto-3.8",
"asn1-3.0"]}
]
}.
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index d23abfe256..6651e9510e 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -48,7 +48,9 @@
pkix_issuer_id/2,
pkix_normalize_name/1,
pkix_path_validation/3,
+ pkix_verify_hostname/2, pkix_verify_hostname/3,
ssh_decode/2, ssh_encode/2,
+ ssh_hostkey_fingerprint/1, ssh_hostkey_fingerprint/2,
ssh_curvename2oid/1, oid2ssh_curvename/1,
pkix_crls_validate/3,
pkix_dist_point/1,
@@ -91,7 +93,8 @@
-type public_crypt_options() :: [{rsa_pad, rsa_padding()}].
-type rsa_digest_type() :: 'md5' | 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'.
-type dss_digest_type() :: 'none' | 'sha'. %% None is for backwards compatibility
--type ecdsa_digest_type() :: 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'.
+-type ecdsa_digest_type() :: 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'.
+-type digest_type() :: rsa_digest_type() | dss_digest_type() | ecdsa_digest_type().
-type crl_reason() :: unspecified | keyCompromise | cACompromise | affiliationChanged | superseded
| cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise.
-type oid() :: tuple().
@@ -392,9 +395,15 @@ dh_gex_group(Min, N, Max, Groups) ->
pubkey_ssh:dh_gex_group(Min, N, Max, Groups).
%%--------------------------------------------------------------------
--spec generate_key(#'DHParameter'{} | {namedCurve, Name ::oid()} |
- #'ECParameters'{}) -> {Public::binary(), Private::binary()} |
- #'ECPrivateKey'{}.
+-spec generate_key(#'DHParameter'{}) ->
+ {Public::binary(), Private::binary()};
+ ({namedCurve, Name ::oid()}) ->
+ #'ECPrivateKey'{};
+ (#'ECParameters'{}) ->
+ #'ECPrivateKey'{};
+ ({rsa, Size::pos_integer(), PubExp::pos_integer()}) ->
+ #'RSAPrivateKey'{}.
+
%% Description: Generates a new keypair
%%--------------------------------------------------------------------
generate_key(#'DHParameter'{prime = P, base = G}) ->
@@ -402,7 +411,43 @@ generate_key(#'DHParameter'{prime = P, base = G}) ->
generate_key({namedCurve, _} = Params) ->
ec_generate_key(Params);
generate_key(#'ECParameters'{} = Params) ->
- ec_generate_key(Params).
+ ec_generate_key(Params);
+generate_key({rsa, ModulusSize, PublicExponent}) ->
+ case crypto:generate_key(rsa, {ModulusSize,PublicExponent}) of
+ {[E, N], [E, N, D, P, Q, D_mod_P_1, D_mod_Q_1, InvQ_mod_P]} ->
+ Nint = crypto:bytes_to_integer(N),
+ Eint = crypto:bytes_to_integer(E),
+ #'RSAPrivateKey'{version = 0, % Two-factor (I guess since otherPrimeInfos is not given)
+ modulus = Nint,
+ publicExponent = Eint,
+ privateExponent = crypto:bytes_to_integer(D),
+ prime1 = crypto:bytes_to_integer(P),
+ prime2 = crypto:bytes_to_integer(Q),
+ exponent1 = crypto:bytes_to_integer(D_mod_P_1),
+ exponent2 = crypto:bytes_to_integer(D_mod_Q_1),
+ coefficient = crypto:bytes_to_integer(InvQ_mod_P)};
+
+ {[E, N], [E, N, D]} -> % FIXME: what to set the other fields in #'RSAPrivateKey'?
+ % Answer: Miller [Mil76]
+ % G.L. Miller. Riemann's hypothesis and tests for primality.
+ % Journal of Computer and Systems Sciences,
+ % 13(3):300-307,
+ % 1976.
+ Nint = crypto:bytes_to_integer(N),
+ Eint = crypto:bytes_to_integer(E),
+ #'RSAPrivateKey'{version = 0, % Two-factor (I guess since otherPrimeInfos is not given)
+ modulus = Nint,
+ publicExponent = Eint,
+ privateExponent = crypto:bytes_to_integer(D),
+ prime1 = '?',
+ prime2 = '?',
+ exponent1 = '?',
+ exponent2 = '?',
+ coefficient = '?'};
+
+ Other ->
+ Other
+ end.
%%--------------------------------------------------------------------
-spec compute_key(#'ECPoint'{} , #'ECPrivateKey'{}) -> binary().
@@ -559,7 +604,7 @@ pkix_match_dist_point(#'CertificateList'{
%%--------------------------------------------------------------------
-spec pkix_sign(#'OTPTBSCertificate'{},
- rsa_private_key() | dsa_private_key()) -> Der::binary().
+ rsa_private_key() | dsa_private_key() | ec_private_key()) -> Der::binary().
%%
%% Description: Sign a pkix x.509 certificate. Returns the corresponding
%% der encoded 'Certificate'{}
@@ -761,6 +806,76 @@ pkix_crls_validate(OtpCert, DPAndCRLs0, Options) ->
pkix_crls_validate(OtpCert, DPAndCRLs, DPAndCRLs,
Options, pubkey_crl:init_revokation_state()).
+%--------------------------------------------------------------------
+-spec pkix_verify_hostname(Cert :: #'OTPCertificate'{} | binary(),
+ ReferenceIDs :: [{uri_id | dns_id | oid(), string()}]) -> boolean().
+
+-spec pkix_verify_hostname(Cert :: #'OTPCertificate'{} | binary(),
+ ReferenceIDs :: [{uri_id | dns_id | oid(), string()}],
+ Options :: proplists:proplist()) -> boolean().
+
+%% Description: Validates a hostname to RFC 6125
+%%--------------------------------------------------------------------
+pkix_verify_hostname(Cert, ReferenceIDs) ->
+ pkix_verify_hostname(Cert, ReferenceIDs, []).
+
+pkix_verify_hostname(BinCert, ReferenceIDs, Options) when is_binary(BinCert) ->
+ pkix_verify_hostname(pkix_decode_cert(BinCert,otp), ReferenceIDs, Options);
+
+pkix_verify_hostname(Cert = #'OTPCertificate'{tbsCertificate = TbsCert}, ReferenceIDs0, Opts) ->
+ MatchFun = proplists:get_value(match_fun, Opts, undefined),
+ FailCB = proplists:get_value(fail_callback, Opts, fun(_Cert) -> false end),
+ FqdnFun = proplists:get_value(fqdn_fun, Opts, fun verify_hostname_extract_fqdn_default/1),
+
+ ReferenceIDs = [{T,to_string(V)} || {T,V} <- ReferenceIDs0],
+ PresentedIDs =
+ try lists:keyfind(?'id-ce-subjectAltName',
+ #'Extension'.extnID,
+ TbsCert#'OTPTBSCertificate'.extensions)
+ of
+ #'Extension'{extnValue = ExtVals} ->
+ [{T,to_string(V)} || {T,V} <- ExtVals];
+ false ->
+ []
+ catch
+ _:_ -> []
+ end,
+ %% PresentedIDs example: [{dNSName,"ewstest.ericsson.com"}, {dNSName,"www.ericsson.com"}]}
+ case PresentedIDs of
+ [] ->
+ %% Fallback to CN-ids [rfc6125, ch6]
+ case TbsCert#'OTPTBSCertificate'.subject of
+ {rdnSequence,RDNseq} ->
+ PresentedCNs =
+ [{cn, to_string(V)}
+ || ATVs <- RDNseq, % RDNseq is list-of-lists
+ #'AttributeTypeAndValue'{type = ?'id-at-commonName',
+ value = {_T,V}} <- ATVs
+ % _T = kind of string (teletexString etc)
+ ],
+ %% Example of PresentedCNs: [{cn,"www.ericsson.se"}]
+ %% match ReferenceIDs to PresentedCNs
+ verify_hostname_match_loop(verify_hostname_fqnds(ReferenceIDs, FqdnFun),
+ PresentedCNs,
+ MatchFun, FailCB, Cert);
+
+ _ ->
+ false
+ end;
+ _ ->
+ %% match ReferenceIDs to PresentedIDs
+ case verify_hostname_match_loop(ReferenceIDs, PresentedIDs,
+ MatchFun, FailCB, Cert) of
+ false ->
+ %% Try to extract DNS-IDs from URIs etc
+ DNS_ReferenceIDs =
+ [{dns_id,X} || X <- verify_hostname_fqnds(ReferenceIDs, FqdnFun)],
+ verify_hostname_match_loop(DNS_ReferenceIDs, PresentedIDs,
+ MatchFun, FailCB, Cert);
+ true ->
+ true
+ end
+ end.
%%--------------------------------------------------------------------
-spec ssh_decode(binary(), public_key | ssh_file()) -> [{public_key(), Attributes::list()}]
@@ -785,6 +900,7 @@ ssh_decode(SshBin, Type) when is_binary(SshBin),
%%--------------------------------------------------------------------
-spec ssh_encode([{public_key(), Attributes::list()}], ssh_file()) -> binary()
; (public_key(), ssh2_pubkey) -> binary()
+ ; ({public_key(),atom()}, ssh2_pubkey) -> binary()
.
%%
%% Description: Encodes a list of ssh file entries (public keys and
@@ -819,6 +935,51 @@ oid2ssh_curvename(?'secp384r1') -> <<"nistp384">>;
oid2ssh_curvename(?'secp521r1') -> <<"nistp521">>.
%%--------------------------------------------------------------------
+-spec ssh_hostkey_fingerprint(public_key()) -> string().
+-spec ssh_hostkey_fingerprint( digest_type(), public_key()) -> string()
+ ; ([digest_type()], public_key()) -> [string()]
+ .
+
+ssh_hostkey_fingerprint(Key) ->
+ sshfp_string(md5, public_key:ssh_encode(Key,ssh2_pubkey) ).
+
+ssh_hostkey_fingerprint(HashAlgs, Key) when is_list(HashAlgs) ->
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ [sshfp_full_string(HashAlg,EncKey) || HashAlg <- HashAlgs];
+ssh_hostkey_fingerprint(HashAlg, Key) when is_atom(HashAlg) ->
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ sshfp_full_string(HashAlg, EncKey).
+
+
+sshfp_string(HashAlg, EncodedKey) ->
+ %% Other HashAlgs than md5 will be printed with
+ %% other formats than hextstr by
+ %% ssh-keygen -E <alg> -lf <file>
+ fp_fmt(sshfp_fmt(HashAlg), crypto:hash(HashAlg, EncodedKey)).
+
+sshfp_full_string(HashAlg, EncKey) ->
+ lists:concat([sshfp_alg_name(HashAlg),
+ [$: | sshfp_string(HashAlg, EncKey)]
+ ]).
+
+sshfp_alg_name(sha) -> "SHA1";
+sshfp_alg_name(Alg) -> string:to_upper(atom_to_list(Alg)).
+
+sshfp_fmt(md5) -> hexstr;
+sshfp_fmt(_) -> b64.
+
+fp_fmt(hexstr, Bin) ->
+ lists:flatten(string:join([io_lib:format("~2.16.0b",[C1]) || <<C1>> <= Bin], ":"));
+fp_fmt(b64, Bin) ->
+ %% This function clause *seems* to be
+ %% [C || C<-base64:encode_to_string(Bin), C =/= $=]
+ %% but I am not sure. Must be checked.
+ B64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
+ BitsInLast = 8*size(Bin) rem 6,
+ Padding = (6-BitsInLast) rem 6, % Want BitsInLast = [1:5] to map to padding [5:1] and 0 -> 0
+ [lists:nth(C+1,B64Chars) || <<C:6>> <= <<Bin/binary,0:Padding>> ].
+
+%%--------------------------------------------------------------------
-spec short_name_hash({rdnSequence, [#'AttributeTypeAndValue'{}]}) ->
string().
@@ -992,19 +1153,16 @@ do_pkix_crls_validate(OtpCert, [{DP, CRL, DeltaCRL} | Rest], All, Options, Revo
end.
sort_dp_crls(DpsAndCrls, FreshCB) ->
- Sorted = do_sort_dp_crls(DpsAndCrls, dict:new()),
- sort_crls(Sorted, FreshCB, []).
-
-do_sort_dp_crls([], Dict) ->
- dict:to_list(Dict);
-do_sort_dp_crls([{DP, CRL} | Rest], Dict0) ->
- Dict = try dict:fetch(DP, Dict0) of
- _ ->
- dict:append(DP, CRL, Dict0)
- catch _:_ ->
- dict:store(DP, [CRL], Dict0)
- end,
- do_sort_dp_crls(Rest, Dict).
+ sort_crls(maps:to_list(lists:foldl(fun group_dp_crls/2,
+ #{},
+ DpsAndCrls)),
+ FreshCB, []).
+
+group_dp_crls({DP,CRL}, M) ->
+ case M of
+ #{DP := CRLs} -> M#{DP := [CRL|CRLs]};
+ _ -> M#{DP => [CRL]}
+ end.
sort_crls([], _, Acc) ->
Acc;
@@ -1083,8 +1241,11 @@ ec_curve_spec( #'ECParameters'{fieldID = FieldId, curve = PCurve, base = Base, o
FieldId#'FieldID'.parameters},
Curve = {PCurve#'Curve'.a, PCurve#'Curve'.b, none},
{Field, Curve, Base, Order, CoFactor};
-ec_curve_spec({namedCurve, OID}) ->
- pubkey_cert_records:namedCurves(OID).
+ec_curve_spec({namedCurve, OID}) when is_tuple(OID), is_integer(element(1,OID)) ->
+ ec_curve_spec({namedCurve, pubkey_cert_records:namedCurves(OID)});
+ec_curve_spec({namedCurve, Name}) when is_atom(Name) ->
+ crypto:ec_curve(Name).
+
ec_key({PubKey, PrivateKey}, Params) ->
#'ECPrivateKey'{version = 1,
@@ -1163,3 +1324,96 @@ ascii_to_lower(String) ->
end)>>
||
<<C>> <= iolist_to_binary(String) >>.
+
+%%%----------------------------------------------------------------
+%%% pkix_verify_hostname help functions
+verify_hostname_extract_fqdn_default({dns_id,S}) ->
+ S;
+verify_hostname_extract_fqdn_default({uri_id,URI}) ->
+ {ok,{https,_,Host,_,_,_}} = http_uri:parse(URI),
+ Host.
+
+
+verify_hostname_fqnds(L, FqdnFun) ->
+ [E || E0 <- L,
+ E <- [try case FqdnFun(E0) of
+ default -> verify_hostname_extract_fqdn_default(E0);
+ undefined -> undefined; % will make the "is_list(E)" test fail
+ Other -> Other
+ end
+ catch _:_-> undefined % will make the "is_list(E)" test fail
+ end],
+ is_list(E),
+ E =/= "",
+ {error,einval} == inet:parse_address(E)
+ ].
+
+
+-define(srvName_OID, {1,3,6,1,4,1,434,2,2,1,37,0}).
+
+verify_hostname_match_default(Ref, Pres) ->
+ verify_hostname_match_default0(to_lower_ascii(Ref), to_lower_ascii(Pres)).
+
+verify_hostname_match_default0(FQDN=[_|_], {cn,FQDN}) ->
+ not lists:member($*, FQDN);
+verify_hostname_match_default0(FQDN=[_|_], {cn,Name=[_|_]}) ->
+ [F1|Fs] = string:tokens(FQDN, "."),
+ [N1|Ns] = string:tokens(Name, "."),
+ match_wild(F1,N1) andalso Fs==Ns;
+verify_hostname_match_default0({dns_id,R}, {dNSName,P}) ->
+ R==P;
+verify_hostname_match_default0({uri_id,R}, {uniformResourceIdentifier,P}) ->
+ R==P;
+verify_hostname_match_default0({srv_id,R}, {T,P}) when T == srvName ;
+ T == ?srvName_OID ->
+ R==P;
+verify_hostname_match_default0(_, _) ->
+ false.
+
+
+match_wild(A, [$*|B]) -> match_wild_suffixes(A, B);
+match_wild([C|A], [ C|B]) -> match_wild(A, B);
+match_wild([], []) -> true;
+match_wild(_, _) -> false.
+
+%% Match the parts after the only wildcard by comparing them from the end
+match_wild_suffixes(A, B) -> match_wild_sfx(lists:reverse(A), lists:reverse(B)).
+
+match_wild_sfx([$*|_], _) -> false; % Bad name (no wildcards alowed)
+match_wild_sfx(_, [$*|_]) -> false; % Bad pattern (no more wildcards alowed)
+match_wild_sfx([A|Ar], [A|Br]) -> match_wild_sfx(Ar, Br);
+match_wild_sfx(Ar, []) -> not lists:member($*, Ar); % Chk for bad name (= wildcards)
+match_wild_sfx(_, _) -> false.
+
+
+verify_hostname_match_loop(Refs0, Pres0, undefined, FailCB, Cert) ->
+ Pres = lists:map(fun to_lower_ascii/1, Pres0),
+ Refs = lists:map(fun to_lower_ascii/1, Refs0),
+ lists:any(
+ fun(R) ->
+ lists:any(fun(P) ->
+ verify_hostname_match_default(R,P) orelse FailCB(Cert)
+ end, Pres)
+ end, Refs);
+verify_hostname_match_loop(Refs, Pres, MatchFun, FailCB, Cert) ->
+ lists:any(
+ fun(R) ->
+ lists:any(fun(P) ->
+ (case MatchFun(R,P) of
+ default -> verify_hostname_match_default(R,P);
+ Bool -> Bool
+ end) orelse FailCB(Cert)
+ end,
+ Pres)
+ end,
+ Refs).
+
+
+to_lower_ascii(S) when is_list(S) -> lists:map(fun to_lower_ascii/1, S);
+to_lower_ascii({T,S}) -> {T, to_lower_ascii(S)};
+to_lower_ascii(C) when $A =< C,C =< $Z -> C + ($a-$A);
+to_lower_ascii(C) -> C.
+
+to_string(S) when is_list(S) -> S;
+to_string(B) when is_binary(B) -> binary_to_list(B).
+
diff --git a/lib/public_key/test/erl_make_certs.erl b/lib/public_key/test/erl_make_certs.erl
index 3dab70784c..e4118bab0d 100644
--- a/lib/public_key/test/erl_make_certs.erl
+++ b/lib/public_key/test/erl_make_certs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -346,10 +346,22 @@ make_key(ec, _Opts) ->
%% RSA key generation (OBS: for testing only)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+gen_rsa2(Size) ->
+ try
+ %% The numbers 2048,17 is choosen to not cause the cryptolib on
+ %% FIPS-enabled test machines be mad at us.
+ public_key:generate_key({rsa, 2048, 17})
+ catch
+ error:notsup ->
+ %% Disabled dirty_schedulers => crypto:generate_key not working
+ weak_gen_rsa2(Size)
+ end.
+
+
-define(SMALL_PRIMES, [65537,97,89,83,79,73,71,67,61,59,53,
47,43,41,37,31,29,23,19,17,13,11,7,5,3]).
-gen_rsa2(Size) ->
+weak_gen_rsa2(Size) ->
P = prime(Size),
Q = prime(Size),
N = P*Q,
diff --git a/lib/public_key/test/pbe_SUITE.erl b/lib/public_key/test/pbe_SUITE.erl
index 004eaefc27..44caf479e5 100644
--- a/lib/public_key/test/pbe_SUITE.erl
+++ b/lib/public_key/test/pbe_SUITE.erl
@@ -219,7 +219,12 @@ pbes2() ->
pbes2(Config) when is_list(Config) ->
decode_encode_key_file("pbes2_des_cbc_enc_key.pem", "password", "DES-CBC", Config),
decode_encode_key_file("pbes2_des_ede3_cbc_enc_key.pem", "password", "DES-EDE3-CBC", Config),
- decode_encode_key_file("pbes2_rc2_cbc_enc_key.pem", "password", "RC2-CBC", Config).
+ case lists:member(rc2_cbc, proplists:get_value(ciphers, crypto:supports())) of
+ true ->
+ decode_encode_key_file("pbes2_rc2_cbc_enc_key.pem", "password", "RC2-CBC", Config);
+ false ->
+ ok
+ end.
check_key_info(#'PrivateKeyInfo'{privateKeyAlgorithm =
#'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = ?rsaEncryption},
diff --git a/lib/public_key/test/public_key.cover b/lib/public_key/test/public_key.cover
index ec00814578..6c46492bec 100644
--- a/lib/public_key/test/public_key.cover
+++ b/lib/public_key/test/public_key.cover
@@ -1,4 +1,4 @@
{incl_app,public_key,details}.
-{excl_mods, public_key, ['OTP-PUB-KEY']}.
+{excl_mods, public_key, ['OTP-PUB-KEY', 'PKCS-FRAME']}.
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index b22b69a0f2..80895ce97c 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -45,7 +45,18 @@ all() ->
{group, sign_verify},
pkix, pkix_countryname, pkix_emailaddress, pkix_path_validation,
pkix_iso_rsa_oid, pkix_iso_dsa_oid, pkix_crl, general_name,
- short_cert_issuer_hash, short_crl_issuer_hash].
+ pkix_verify_hostname_cn,
+ pkix_verify_hostname_subjAltName,
+ pkix_verify_hostname_options,
+ short_cert_issuer_hash, short_crl_issuer_hash,
+ ssh_hostkey_fingerprint_md5_implicit,
+ ssh_hostkey_fingerprint_md5,
+ ssh_hostkey_fingerprint_sha,
+ ssh_hostkey_fingerprint_sha256,
+ ssh_hostkey_fingerprint_sha384,
+ ssh_hostkey_fingerprint_sha512,
+ ssh_hostkey_fingerprint_list
+ ].
groups() ->
[{pem_decode_encode, [], [dsa_pem, rsa_pem, ec_pem, encrypted_pem,
@@ -81,7 +92,26 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
%%-------------------------------------------------------------------
-init_per_testcase(_TestCase, Config0) ->
+init_per_testcase(TestCase, Config) ->
+ case TestCase of
+ ssh_hostkey_fingerprint_md5_implicit -> init_fingerprint_testcase([md5], Config);
+ ssh_hostkey_fingerprint_md5 -> init_fingerprint_testcase([md5], Config);
+ ssh_hostkey_fingerprint_sha -> init_fingerprint_testcase([sha], Config);
+ ssh_hostkey_fingerprint_sha256 -> init_fingerprint_testcase([sha256], Config);
+ ssh_hostkey_fingerprint_sha384 -> init_fingerprint_testcase([sha384], Config);
+ ssh_hostkey_fingerprint_sha512 -> init_fingerprint_testcase([sha512], Config);
+ ssh_hostkey_fingerprint_list -> init_fingerprint_testcase([sha,md5], Config);
+ _ -> init_common_per_testcase(Config)
+ end.
+
+init_fingerprint_testcase(Algs, Config) ->
+ Hashs = proplists:get_value(hashs, crypto:supports(), []),
+ case Algs -- Hashs of
+ [] -> init_common_per_testcase(Config);
+ UnsupportedAlgs -> {skip,{UnsupportedAlgs,not_supported}}
+ end.
+
+init_common_per_testcase(Config0) ->
Config = lists:keydelete(watchdog, 1, Config0),
Dog = ct:timetrap(?TIMEOUT),
[{watchdog, Dog} | Config].
@@ -89,6 +119,7 @@ init_per_testcase(_TestCase, Config0) ->
end_per_testcase(_TestCase, _Config) ->
ok.
+
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
@@ -529,6 +560,56 @@ ssh_openssh_public_key_long_header(Config) when is_list(Config) ->
Decoded = public_key:ssh_decode(Encoded, rfc4716_public_key).
%%--------------------------------------------------------------------
+%% Check of different host keys left to later
+ssh_hostkey_fingerprint_md5_implicit(_Config) ->
+ Expected = "4b:0b:63:de:0f:a7:3a:ab:2c:cc:2d:d1:21:37:1d:3a",
+ Expected = public_key:ssh_hostkey_fingerprint(ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
+%% Check of different host keys left to later
+ssh_hostkey_fingerprint_md5(_Config) ->
+ Expected = "MD5:4b:0b:63:de:0f:a7:3a:ab:2c:cc:2d:d1:21:37:1d:3a",
+ Expected = public_key:ssh_hostkey_fingerprint(md5, ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
+%% Since this kind of fingerprint is not available yet on standard
+%% distros, we do like this instead. The Expected is generated with:
+%% $ openssh-7.3p1/ssh-keygen -E sha1 -lf <file>
+%% 2048 SHA1:Soammnaqg06jrm2jivMSnzQGlmk [email protected] (RSA)
+ssh_hostkey_fingerprint_sha(_Config) ->
+ Expected = "SHA1:Soammnaqg06jrm2jivMSnzQGlmk",
+ Expected = public_key:ssh_hostkey_fingerprint(sha, ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
+%% Since this kind of fingerprint is not available yet on standard
+%% distros, we do like this instead.
+ssh_hostkey_fingerprint_sha256(_Config) ->
+ Expected = "SHA256:T7F1BahkJWR7iJO8+rpzWOPbp7LZP4MlNrDExdNYOvY",
+ Expected = public_key:ssh_hostkey_fingerprint(sha256, ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
+%% Since this kind of fingerprint is not available yet on standard
+%% distros, we do like this instead.
+ssh_hostkey_fingerprint_sha384(_Config) ->
+ Expected = "SHA384:QhkLoGNI4KXdPvC//HxxSCP3uTQVADqxdajbgm+Gkx9zqz8N94HyP1JmH8C4/aEl",
+ Expected = public_key:ssh_hostkey_fingerprint(sha384, ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
+%% Since this kind of fingerprint is not available yet on standard
+%% distros, we do like this instead.
+ssh_hostkey_fingerprint_sha512(_Config) ->
+ Expected = "SHA512:ezUismvm3ADQQb6Nm0c1DwQ6ydInlJNfsnSQejFkXNmABg1Aenk9oi45CXeBOoTnlfTsGG8nFDm0smP10PBEeA",
+ Expected = public_key:ssh_hostkey_fingerprint(sha512, ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
+%% Since this kind of fingerprint is not available yet on standard
+%% distros, we do like this instead.
+ssh_hostkey_fingerprint_list(_Config) ->
+ Expected = ["SHA1:Soammnaqg06jrm2jivMSnzQGlmk",
+ "MD5:4b:0b:63:de:0f:a7:3a:ab:2c:cc:2d:d1:21:37:1d:3a"],
+ Expected = public_key:ssh_hostkey_fingerprint([sha,md5], ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
encrypt_decrypt() ->
[{doc, "Test public_key:encrypt_private and public_key:decrypt_public"}].
encrypt_decrypt(Config) when is_list(Config) ->
@@ -746,6 +827,114 @@ pkix_path_validation(Config) when is_list(Config) ->
ok.
%%--------------------------------------------------------------------
+%% To generate the PEM file contents:
+%%
+%% openssl req -x509 -nodes -newkey rsa:1024 -keyout /dev/null -subj '/C=SE/CN=example.com/CN=*.foo.example.com/CN=a*b.bar.example.com/O=erlang.org' > public_key_SUITE_data/pkix_verify_hostname_cn.pem
+%%
+%% Note that the same pem-file is used in pkix_verify_hostname_options/1
+%%
+%% Subject: C=SE, CN=example.com, CN=*.foo.example.com, CN=a*b.bar.example.com, O=erlang.org
+%% extensions = no subjAltName
+
+pkix_verify_hostname_cn(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ {ok,Bin} = file:read_file(filename:join(DataDir,"pkix_verify_hostname_cn.pem")),
+ Cert = public_key:pkix_decode_cert(element(2,hd(public_key:pem_decode(Bin))), otp),
+
+ %% Check that 1) only CNs are checked,
+ %% 2) an empty label does not match a wildcard and
+ %% 3) a wildcard does not match more than one label
+ false = public_key:pkix_verify_hostname(Cert, [{dns_id,"erlang.org"},
+ {dns_id,"foo.EXAMPLE.com"},
+ {dns_id,"b.a.foo.EXAMPLE.com"}]),
+
+ %% Check that a hostname is extracted from a https-uri and used for checking:
+ true = public_key:pkix_verify_hostname(Cert, [{uri_id,"HTTPS://EXAMPLE.com"}]),
+
+ %% Check wildcard matching one label:
+ true = public_key:pkix_verify_hostname(Cert, [{dns_id,"a.foo.EXAMPLE.com"}]),
+
+ %% Check wildcard with surrounding chars matches one label:
+ true = public_key:pkix_verify_hostname(Cert, [{dns_id,"accb.bar.EXAMPLE.com"}]),
+
+ %% Check that a wildcard with surrounding chars matches an empty string:
+ true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://ab.bar.EXAMPLE.com"}]).
+
+%%--------------------------------------------------------------------
+%% To generate the PEM file contents:
+%%
+%% openssl req -x509 -nodes -newkey rsa:1024 -keyout /dev/null -extensions SAN -config public_key_SUITE_data/verify_hostname.conf 2>/dev/null > public_key_SUITE_data/pkix_verify_hostname_subjAltName.pem
+%%
+%% Subject: C=SE, CN=example.com
+%% Subject Alternative Name: DNS:kb.example.org, URI:http://www.example.org, URI:https://wws.example.org
+
+pkix_verify_hostname_subjAltName(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ {ok,Bin} = file:read_file(filename:join(DataDir,"pkix_verify_hostname_subjAltName.pem")),
+ Cert = public_key:pkix_decode_cert(element(2,hd(public_key:pem_decode(Bin))), otp),
+
+ %% Check that neither a uri nor dns hostname matches a CN if subjAltName is present:
+ false = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://example.com"},
+ {dns_id,"example.com"}]),
+
+ %% Check that a uri_id matches a URI subjAltName:
+ true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://wws.example.org"}]),
+
+ %% Check that a dns_id does not match a URI subjAltName:
+ false = public_key:pkix_verify_hostname(Cert, [{dns_id,"www.example.org"},
+ {dns_id,"wws.example.org"}]),
+
+ %% Check that a dns_id matches a DNS subjAltName:
+ true = public_key:pkix_verify_hostname(Cert, [{dns_id,"kb.example.org"}]).
+
+%%--------------------------------------------------------------------
+%% Uses the pem-file for pkix_verify_hostname_cn
+%% Subject: C=SE, CN=example.com, CN=*.foo.example.com, CN=a*b.bar.example.com, O=erlang.org
+pkix_verify_hostname_options(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ {ok,Bin} = file:read_file(filename:join(DataDir,"pkix_verify_hostname_cn.pem")),
+ Cert = public_key:pkix_decode_cert(element(2,hd(public_key:pem_decode(Bin))), otp),
+
+ %% Check that the fail_callback is called and is presented the correct certificate:
+ true = public_key:pkix_verify_hostname(Cert, [{dns_id,"erlang.org"}],
+ [{fail_callback,
+ fun(#'OTPCertificate'{}=C) when C==Cert ->
+ true; % To test the return value matters
+ (#'OTPCertificate'{}=C) ->
+ ct:log("~p:~p: Wrong cert:~n~p~nExpect~n~p",
+ [?MODULE, ?LINE, C, Cert]),
+ ct:fail("Wrong cert, see log");
+ (C) ->
+ ct:log("~p:~p: Bad cert: ~p",[?MODULE,?LINE,C]),
+ ct:fail("Bad cert, see log")
+ end}]),
+
+ %% Check the callback for user-provided match functions:
+ true = public_key:pkix_verify_hostname(Cert, [{dns_id,"very.wrong.domain"}],
+ [{match_fun,
+ fun("very.wrong.domain", {cn,"example.com"}) ->
+ true;
+ (_, _) ->
+ false
+ end}]),
+ false = public_key:pkix_verify_hostname(Cert, [{dns_id,"not.example.com"}],
+ [{match_fun, fun(_, _) -> default end}]),
+ true = public_key:pkix_verify_hostname(Cert, [{dns_id,"example.com"}],
+ [{match_fun, fun(_, _) -> default end}]),
+
+ %% Check the callback for user-provided fqdn extraction:
+ true = public_key:pkix_verify_hostname(Cert, [{uri_id,"some://very.wrong.domain"}],
+ [{fqdn_fun,
+ fun({uri_id, "some://very.wrong.domain"}) ->
+ "example.com";
+ (_) ->
+ ""
+ end}]),
+ true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://example.com"}],
+ [{fqdn_fun, fun(_) -> default end}]),
+ false = public_key:pkix_verify_hostname(Cert, [{uri_id,"some://very.wrong.domain"}]).
+
+%%--------------------------------------------------------------------
pkix_iso_rsa_oid() ->
[{doc, "Test workaround for supporting certs that use ISO oids"
" 1.3.14.3.2.29 instead of PKIX/PKCS oid"}].
@@ -929,3 +1118,13 @@ incorrect_countryname_pkix_cert() ->
incorrect_emailaddress_pkix_cert() ->
<<48,130,3,74,48,130,2,50,2,9,0,133,49,203,25,198,156,252,230,48,13,6,9,42,134, 72,134,247,13,1,1,5,5,0,48,103,49,11,48,9,6,3,85,4,6,19,2,65,85,49,19,48,17, 6,3,85,4,8,12,10,83,111,109,101,45,83,116,97,116,101,49,33,48,31,6,3,85,4,10, 12,24,73,110,116,101,114,110,101,116,32,87,105,100,103,105,116,115,32,80,116, 121,32,76,116,100,49,32,48,30,6,9,42,134,72,134,247,13,1,9,1,12,17,105,110, 118,97,108,105,100,64,101,109,97,105,108,46,99,111,109,48,30,23,13,49,51,49, 49,48,55,50,48,53,54,49,56,90,23,13,49,52,49,49,48,55,50,48,53,54,49,56,90, 48,103,49,11,48,9,6,3,85,4,6,19,2,65,85,49,19,48,17,6,3,85,4,8,12,10,83,111, 109,101,45,83,116,97,116,101,49,33,48,31,6,3,85,4,10,12,24,73,110,116,101, 114,110,101,116,32,87,105,100,103,105,116,115,32,80,116,121,32,76,116,100,49, 32,48,30,6,9,42,134,72,134,247,13,1,9,1,12,17,105,110,118,97,108,105,100,64, 101,109,97,105,108,46,99,111,109,48,130,1,34,48,13,6,9,42,134,72,134,247,13, 1,1,1,5,0,3,130,1,15,0,48,130,1,10,2,130,1,1,0,190,243,49,213,219,60,232,105, 1,127,126,9,130,15,60,190,78,100,148,235,246,223,21,91,238,200,251,84,55,212, 78,32,120,61,85,172,0,144,248,5,165,29,143,79,64,178,51,153,203,76,115,238, 192,49,173,37,121,203,89,62,157,13,181,166,30,112,154,40,202,140,104,211,157, 73,244,9,78,236,70,153,195,158,233,141,42,238,2,143,160,225,249,27,30,140, 151,176,43,211,87,114,164,108,69,47,39,195,123,185,179,219,28,218,122,53,83, 77,48,81,184,14,91,243,12,62,146,86,210,248,228,171,146,225,87,51,146,155, 116,112,238,212,36,111,58,41,67,27,6,61,61,3,84,150,126,214,121,57,38,12,87, 121,67,244,37,45,145,234,131,115,134,58,194,5,36,166,52,59,229,32,47,152,80, 237,190,58,182,248,98,7,165,198,211,5,31,231,152,116,31,108,71,218,64,188, 178,143,27,167,79,15,112,196,103,116,212,65,197,94,37,4,132,103,91,217,73, 223,207,185,7,153,221,240,232,31,44,102,108,82,83,56,242,210,214,74,71,246, 177,217,148,227,220,230,4,176,226,74,194,37,2,3,1,0,1,48,13,6,9,42,134,72, 134,247,13,1,1,5,5,0,3,130,1,1,0,89,247,141,154,173,123,123,203,143,85,28,79, 73,37,164,6,17,89,171,224,149,22,134,17,198,146,158,192,241,41,253,58,230, 133,71,189,43,66,123,88,15,242,119,227,249,99,137,61,200,54,161,0,177,167, 169,114,80,148,90,22,97,78,162,181,75,93,209,116,245,46,81,232,64,157,93,136, 52,57,229,113,197,218,113,93,42,161,213,104,205,137,30,144,183,58,10,98,47, 227,177,96,40,233,98,150,209,217,68,22,221,133,27,161,152,237,46,36,179,59, 172,97,134,194,205,101,137,71,192,57,153,20,114,27,173,233,166,45,56,0,61, 205,45,202,139,7,132,103,248,193,157,184,123,43,62,172,236,110,49,62,209,78, 249,83,219,133,1,213,143,73,174,16,113,143,189,41,84,60,128,222,30,177,104, 134,220,52,239,171,76,59,176,36,113,176,214,118,16,44,235,21,167,199,216,200, 76,219,142,248,13,70,145,205,216,230,226,148,97,223,216,179,68,209,222,63, 140,137,24,164,192,149,194,79,119,247,75,159,49,116,70,241,70,116,11,40,119, 176,157,36,160,102,140,255,34,248,25,231,136,59>>.
+
+
+
+ssh_hostkey(rsa) ->
+ [{PKdecoded,_}] =
+ public_key:ssh_decode(
+ <<"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDYXcYmsyJBstl4EfFYzfQJmSiUE162zvSGSoMYybShYOI6rnnyvvihfw8Aml+2gZ716F2tqG48FQ/yPZEGWNPMrCejPpJctaPWhpNdNMJ8KFXSEgr5bY2mEpa19DHmuDeXKzeJJ+X7s3fVdYc4FMk5731KIW6Huf019ZnTxbx0VKG6b1KAJBg3vpNsDxEMwQ4LFMB0JHVklOTzbxmpaeULuIxvl65A+eGeFVeo2Q+YI9UnwY1vSgmc9Azwy8Ie9Z0HpQBN5I7Uc5xnknT8V6xDhgNfXEfzsgsRdDfZLECt1WO/1gP9wkosvAGZWt5oG8pbNQWiQdFq536ck8WQD9WD [email protected]">>,
+ public_key),
+ PKdecoded.
+
diff --git a/lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_cn.pem b/lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_cn.pem
new file mode 100644
index 0000000000..9f7b428f9a
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_cn.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICsjCCAhugAwIBAgIJAMCGx1ezaJFRMA0GCSqGSIb3DQEBCwUAMHIxCzAJBgNV
+BAYTAlNFMRQwEgYDVQQDDAtleGFtcGxlLmNvbTEaMBgGA1UEAwwRKi5mb28uZXhh
+bXBsZS5jb20xHDAaBgNVBAMME2EqYi5iYXIuZXhhbXBsZS5jb20xEzARBgNVBAoM
+CmVybGFuZy5vcmcwHhcNMTYxMjIwMTUwNDUyWhcNMTcwMTE5MTUwNDUyWjByMQsw
+CQYDVQQGEwJTRTEUMBIGA1UEAwwLZXhhbXBsZS5jb20xGjAYBgNVBAMMESouZm9v
+LmV4YW1wbGUuY29tMRwwGgYDVQQDDBNhKmIuYmFyLmV4YW1wbGUuY29tMRMwEQYD
+VQQKDAplcmxhbmcub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVGJgZ
+defGucvMXf0RrEm6Hb18IfVUo9IV6swSP/kwAu/608ZIZdzlfp2pxC0e72a4E3WN
+4vrGxAr2wMMQOiyoy4qlAeLX27THJ6Q4Vl82fc6QuOJbScKIydSZ4KoB+luGlBu5
+b6xYh2pBbneKFpsecmK5rsWtTactjD4n1tKjUwIDAQABo1AwTjAdBgNVHQ4EFgQU
+OCtzidUeaDva7qp12T0CQrgfLW4wHwYDVR0jBBgwFoAUOCtzidUeaDva7qp12T0C
+QrgfLW4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQCAz+ComCMo9Qbu
+PHxG7pv3mQvoxrMFva/Asg4o9mW2mDyrk0DwI4zU8vMHbSRKSBYGm4TATXsQkDQT
+gJw/bxhISnhZZtPC7Yup8kJCkJ6S6EDLYrlzgsRqfeU6jWim3nbfaLyMi9dHFDMk
+HULnyNNW3qxTEKi8Wo2sCMej4l7KFg==
+-----END CERTIFICATE-----
diff --git a/lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_subjAltName.pem b/lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_subjAltName.pem
new file mode 100644
index 0000000000..83e1ad37b3
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/pkix_verify_hostname_subjAltName.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICEjCCAXugAwIBAgIJANwliLph5EiAMA0GCSqGSIb3DQEBCwUAMCMxCzAJBgNV
+BAYTAlNFMRQwEgYDVQQDEwtleGFtcGxlLmNvbTAeFw0xNjEyMjAxNTEyMjRaFw0x
+NzAxMTkxNTEyMjRaMCMxCzAJBgNVBAYTAlNFMRQwEgYDVQQDEwtleGFtcGxlLmNv
+bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAydstIN157w8QxkVaOl3wm81j
+fgZ8gqO3BXkECPF6bw5ewLlmePL6Qs4RypsaRe7cKJ9rHFlwhpdcYkxWSWEt2N7Z
+Ry3N4SjuU04ohWbYgy3ijTt7bJg7jOV1Dh56BnI4hwhQj0oNFizNZOeRRfEzdMnS
++uk03t/Qre2NS7KbwnUCAwEAAaNOMEwwSgYDVR0RBEMwQYIOa2IuZXhhbXBsZS5v
+cmeGFmh0dHA6Ly93d3cuZXhhbXBsZS5vcmeGF2h0dHBzOi8vd3dzLmV4YW1wbGUu
+b3JnMA0GCSqGSIb3DQEBCwUAA4GBAKqFqW5gCso422bXriCBJoygokOTTOw1Rzpq
+K8Mm0B8W9rrW9OTkoLEcjekllZcUCZFin2HovHC5HlHZz+mQvBI1M6sN2HVQbSzS
+EgL66U9gwJVnn9/U1hXhJ0LO28aGbyE29DxnewNR741dWN3oFxCdlNaO6eMWaEsO
+gduJ5sDl
+-----END CERTIFICATE-----
diff --git a/lib/public_key/test/public_key_SUITE_data/verify_hostname.conf b/lib/public_key/test/public_key_SUITE_data/verify_hostname.conf
new file mode 100644
index 0000000000..a28864dc78
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/verify_hostname.conf
@@ -0,0 +1,16 @@
+[req]
+prompt = no
+distinguished_name = DN
+
+[DN]
+C=SE
+CN=example.com
+
+[SAN]
+subjectAltName = @alt_names
+
+[alt_names]
+DNS = kb.example.org
+URI.1 = http://www.example.org
+URI.2 = https://wws.example.org
+
diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk
index 84f6a659b5..83a77d2a28 100644
--- a/lib/public_key/vsn.mk
+++ b/lib/public_key/vsn.mk
@@ -1 +1 @@
-PUBLIC_KEY_VSN = 1.2
+PUBLIC_KEY_VSN = 1.4.1
diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml
index 6df4924d0a..8593a1017f 100644
--- a/lib/reltool/doc/src/notes.xml
+++ b/lib/reltool/doc/src/notes.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2009</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -38,7 +38,69 @@
thus constitutes one section in this document. The title of each
section is the version number of Reltool.</p>
- <section><title>Reltool 0.7.1</title>
+ <section><title>Reltool 0.7.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> The User's Guide examples are updated after removal
+ of support for Dets files created with Erlang/OTP R7 and
+ earlier. </p>
+ <p>
+ Own Id: OTP-14422 Aux Id: OTP-13830 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Reltool 0.7.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed xml issues in old release notes</p>
+ <p>
+ Own Id: OTP-14269</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Reltool 0.7.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Dependencies specified in .app files would earlier only
+ be followed for applications that are included in a 'rel'
+ spec in the reltool config. For other applications, only
+ xref would decide the dependencies.</p>
+ <p>
+ Some dependency chains would even be missed for
+ applications that are included in a 'rel' spec in the
+ reltool config. E.g.</p>
+
+ <list> <item>Application x has y as included application,
+ and y in turn has z as included application. Then z is
+ not included. </item> <item>Application x has y in its
+ 'applications' tag in the .app file, and y in turn has z
+ as included application. Then z is not included.</item>
+ </list>
+ <p>
+ These bugs are now corrected.</p>
+ <p>
+ Own Id: OTP-11993</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Reltool 0.7.1</title>
<section><title>Improvements and New Features</title>
<list>
@@ -546,8 +608,8 @@
<p>The handling of applications included in releases has
been improved. Applications that are required to be
started before other applications in a release are now
- automatically included in the release. The <c>kernel</c>
- and <c>stdlib</c> applications are always included as
+ automatically included in the release. The Kernel
+ and STDLIB applications are always included as
they are mandatory.</p>
<p>Applications that are (explicitly or implicitly)
included in a release are now automatically included as
diff --git a/lib/reltool/doc/src/part.xml b/lib/reltool/doc/src/part.xml
index 5904084879..e608d548ea 100644
--- a/lib/reltool/doc/src/part.xml
+++ b/lib/reltool/doc/src/part.xml
@@ -31,7 +31,7 @@
<rev>%VSN%</rev>
</header>
<description>
- <p><c>Reltool</c> is a release management tool. It analyses a given
+ <p>Reltool is a release management tool. It analyses a given
Erlang/OTP installation and determines various dependencies
between applications. The <c>graphical</c> frontend depicts the
dependencies and enables interactive customization of a
diff --git a/lib/reltool/doc/src/ref_man.xml b/lib/reltool/doc/src/ref_man.xml
index 38f270b79a..1684f075ff 100644
--- a/lib/reltool/doc/src/ref_man.xml
+++ b/lib/reltool/doc/src/ref_man.xml
@@ -31,7 +31,7 @@
<rev>%VSN%</rev>
</header>
<description>
- <p><c>Reltool</c> is a release management tool. It analyses a given
+ <p>Reltool is a release management tool. It analyses a given
Erlang/OTP installation and determines various dependencies
between applications. The <c>graphical</c> frontend depicts the
dependencies and enables interactive customization of a
diff --git a/lib/reltool/doc/src/reltool.xml b/lib/reltool/doc/src/reltool.xml
index 38448e7961..5bfbee966b 100644
--- a/lib/reltool/doc/src/reltool.xml
+++ b/lib/reltool/doc/src/reltool.xml
@@ -47,7 +47,7 @@
<p>The tool uses an installed Erlang/OTP system as input.
<c>root_dir</c> is the root directory of the analysed system and
- it defaults to the system executing <c>reltool</c>. Applications
+ it defaults to the system executing Reltool. Applications
may also be located outside <c>root_dir</c>. <c>lib_dirs</c>
defines library directories where additional applications
may reside and it defaults to the directories
@@ -56,7 +56,7 @@
<p>An application directory <c>AppDir</c> under a library
directory is recognized by the existence of an <c>AppDir/ebin</c>
- directory. If this does not exist, <c>reltool</c> will not
+ directory. If this does not exist, Reltool will not
consider <c>AppDir</c> at all when looking for applications.</p>
<p>It is recommended that application directories are named as the
@@ -81,14 +81,14 @@
<tag><c>config</c></tag>
<item>
<p>This is the main option and it controls the configuration
- of <c>reltool</c>. It can either be a <c>sys</c> tuple or
+ of Reltool. It can either be a <c>sys</c> tuple or
a name of a <c>file</c> containing a sys tuple.</p>
</item>
<tag><c>trap_exit</c></tag>
<item>
<p>This option controls the error handling behavior of
- <c>reltool</c>. By default the window processes traps
+ Reltool. By default the window processes traps
exit, but this behavior can altered by setting
<c>trap_exit</c> to <c>false</c>.</p>
</item>
diff --git a/lib/reltool/doc/src/reltool_examples.xml b/lib/reltool/doc/src/reltool_examples.xml
index f735d914ea..30cb3c13b6 100644
--- a/lib/reltool/doc/src/reltool_examples.xml
+++ b/lib/reltool/doc/src/reltool_examples.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2009</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -41,30 +41,31 @@
<p>The main process in Reltool is the server. It can be used as it
is or be used via the GUI frontend process. When the GUI is
started, a server process will automatically be started. The GUI
- process is started with <c>reltool:start/0</c>,
- <c>reltool:start/1</c> or <c>reltool:start_link/1</c>. The pid of
- its server can be obtained with <c>reltool:get_server/1</c></p>
+ process is started with
+ <seealso marker="reltool#start-0"><c>reltool:start/0</c></seealso>,
+ <seealso marker="reltool#start-1"><c>reltool:start/1</c></seealso> or
+ <seealso marker="reltool#start_link-1"><c>reltool:start_link/1</c></seealso>.
+ The pid of its server can be obtained with
+ <seealso marker="reltool#start_link-1"><c>reltool:get_server/1</c></seealso>
+ </p>
<pre>
-Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4]
- [async-threads:0] [kernel-poll:false]
-
-Eshell V5.7.3 (abort with ^G)
+Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
+[hipe] [kernel-poll:false]
+Eshell V9.0 (abort with ^G)
+1&gt;
1&gt; {ok, Win} = reltool:start([]).
{ok,&lt;0.36.01&gt;}
-2&gt; {ok, Server} = reltool:get_server([]).
+2&gt; {ok, Server} = reltool:get_server(Win).
{ok,&lt;0.37.01&gt;}
3&gt; reltool:get_config(Server).
{ok,{sys,[]}}
-4&gt; reltool:stop(Win).
-ok
-
-
-5&gt; {ok, Server2} = reltool:start_server([]).
+4&gt;
+4&gt; {ok, Server2} = reltool:start_server([]).
{ok,&lt;0.6535.01&gt;}
-6&gt; reltool:get_config(Server2).
+5&gt; reltool:get_config(Server2).
{ok,{sys,[]}}
-7&gt; reltool:stop(Server2).
+6&gt; reltool:stop(Server2).
ok
</pre>
@@ -74,13 +75,11 @@ ok
<title>Inspecting the configuration</title>
<pre>
-Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4]
- [async-threads:0] [kernel-poll:false]
-
-Eshell V5.7.3 (abort with ^G)
-1&gt; Config = {sys, [{escript,
- "examples/display_args",
- [{incl_cond, include}]},
+Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
+[hipe] [kernel-poll:false]
+Eshell V9.0 (abort with ^G)
+1&gt;
+1&gt; Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]},
{app, inets, [{incl_cond, include}]},
{app, mnesia, [{incl_cond, exclude}]},
{app, ssl, [{incl_cond, exclude}]},
@@ -92,88 +91,105 @@ Eshell V5.7.3 (abort with ^G)
{app,ssl,[{incl_cond,exclude}]},
{app,runtime_tools,[{incl_cond,exclude}]},
{app,syntax_tools,[{incl_cond,exclude}]}]}
-
-
-
+2&gt;
2&gt; {ok, Server} = reltool:start_server([Config]).
-{ok,&lt;0.35.0&gt;}
+{ok,&lt;0.66.0&gt;}
+3&gt;
3&gt; reltool:get_config(Server).
-{ok,{sys,[{escript,"/clearcase/otp/tools/reltool/examples/display_args",
- [{incl_cond,include}]}]}}
+{ok,{sys,[{escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
+ [{incl_cond,include}]},
+ {app,inets,[{incl_cond,include}]},
+ {app,mnesia,[{incl_cond,exclude}]},
+ {app,runtime_tools,[{incl_cond,exclude}]},
+ {app,ssl,[{incl_cond,exclude}]},
+ {app,syntax_tools,[{incl_cond,exclude}]}]}}
+4&gt;
4&gt; reltool:get_config(Server, false, false).
-{ok,{sys,[{escript,"/clearcase/otp/tools/reltool/examples/display_args",
- [{incl_cond,include}]}]}}
-
-
-
+{ok,{sys,[{escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
+ [{incl_cond,include}]},
+ {app,inets,[{incl_cond,include}]},
+ {app,mnesia,[{incl_cond,exclude}]},
+ {app,runtime_tools,[{incl_cond,exclude}]},
+ {app,ssl,[{incl_cond,exclude}]},
+ {app,syntax_tools,[{incl_cond,exclude}]}]}}
+5&gt;
5&gt; reltool:get_config(Server, true, false).
-{ok,{sys,[{root_dir,"/ldisk/hakan/otp_test"},
+{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
{lib_dirs,[]},
- {escript,"/clearcase/otp/tools/reltool/examples/display_args",
+ {escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
[{incl_cond,include}]},
{mod_cond,all},
{incl_cond,derived},
+ {app,inets,
+ [{incl_cond,include},{vsn,undefined},{lib_dir,undefined}]},
+ {app,mnesia,[{incl_cond,exclude}]},
+ {app,runtime_tools,[{incl_cond,exclude}]},
+ {app,ssl,[{incl_cond,exclude}]},
+ {app,syntax_tools,[{incl_cond,exclude}]},
{boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[sasl]},
{emu_name,"beam"},
{relocatable,true},
{profile,development},
- {incl_sys_files,[".*"]},
- {excl_sys_files,[]},
- {incl_app_files,[".*"]},
- {excl_app_files,[]},
- {incl_archive_dirs,[".*"]},
- {excl_archive_dirs,["^include$","^priv$"]},
+ {incl_sys_filters,[".*"]},
+ {excl_sys_filters,[]},
+ {incl_app_filters,[".*"]},
+ {excl_app_filters,[]},
+ {incl_archive_filters,[".*"]},
+ {excl_archive_filters,[[...]|...]},
{archive_opts,[]},
- {app_type,permanent},
- {app_file,keep},
- {debug_info,keep}]}}
-
-
-
+ {rel_app_type,...},
+ {...}|...]}}
+6&gt;
6&gt; reltool:get_config(Server, true, true).
-{ok,{sys,[{root_dir,"/ldisk/hakan/otp_test"},
+{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
{lib_dirs,[]},
- {escript,"/clearcase/otp/tools/reltool/examples/display_args",
+ {escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
[{incl_cond,include}]},
{mod_cond,all},
{incl_cond,derived},
- {erts,[{vsn,"5.7.3"},
- {mod,erl_prim_loader,[]},
- {mod,erlang,[]},
- {mod,init,[]},
- {mod,otp_ring0,[]},
- {mod,prim_file,[]},
- {mod,prim_inet,[]},
- {mod,prim_zip,[]},
- {mod,zlib,[]}]},
+ {erts,[{app,erts,
+ [{vsn,"9.0"},
+ {lib_dir,"/usr/local/lib/erlang/lib/erts-9.0"},
+ {mod,erl_prim_loader,[]},
+ {mod,erl_tracer,[]},
+ {mod,erlang,[]},
+ {mod,erts_code_purger,[]},
+ {mod,erts_dirty_process_code_checker,[]},
+ {mod,erts_internal,[]},
+ {mod,erts_literal_area_collector,[]},
+ {mod,init,[]},
+ {mod,otp_ring0,...},
+ {mod,...},
+ {...}|...]}]},
{app,compiler,
- [{vsn,"4.6.3"},
+ [{vsn,"7.0.4"},
+ {lib_dir,"/usr/local/lib/erlang/lib/compiler-7.0.4"},
+ {mod,beam_a,[]},
{mod,beam_asm,[]},
{mod,beam_block,[]},
- {mod,beam_bool,[]},
+ {mod,beam_bs,[]},
{mod,beam_bsm,[]},
{mod,beam_clean,[]},
{mod,beam_dead,[]},
{mod,beam_dict,[]},
{mod,beam_disasm,[]},
- {mod,beam_flatten,[]},
- {mod,beam_jump,[]},
- {mod,beam_listing,[]},
- {mod,beam_opcodes,...},
+ {mod,beam_except,[]},
+ {mod,beam_flatten,...},
{mod,...},
{...}|...]},
{app,crypto,
- [{vsn,"1.6.1"},
+ [{vsn,"3.7.4"},
+ {lib_dir,"/usr/local/lib/erlang/lib/crypto-3.7.4"},
{mod,crypto,[]},
- {mod,crypto_app,[]},
- {mod,crypto_server,[]},
- {mod,crypto_sup,[]}]},
+ {mod,crypto_ec_curves,[]}]},
{app,hipe,
- [{vsn,"3.7.3"},
+ [{vsn,"3.15.4"},
+ {lib_dir,"/usr/local/lib/erlang/lib/hipe-3.15.4"},
{mod,cerl_cconv,[]},
{mod,cerl_closurean,[]},
{mod,cerl_hipeify,[]},
- {mod,cerl_hybrid_transform,[]},
{mod,cerl_lib,[]},
{mod,cerl_messagean,[]},
{mod,cerl_pmatch,[]},
@@ -182,65 +198,110 @@ Eshell V5.7.3 (abort with ^G)
{mod,cerl_typean,...},
{mod,...},
{...}|...]},
+ {app,inets,
+ [{incl_cond,include},
+ {vsn,"6.3.9"},
+ {lib_dir,"/usr/local/lib/erlang/lib/inets-6.3.9"},
+ {mod,ftp,[]},
+ {mod,ftp_progress,[]},
+ {mod,ftp_response,[]},
+ {mod,ftp_sup,[]},
+ {mod,http_chunk,[]},
+ {mod,http_request,[]},
+ {mod,http_response,...},
+ {mod,...},
+ {...}|...]},
{app,kernel,
- [{vsn,"2.13.3"},
+ [{vsn,"5.2"},
+ {lib_dir,"/usr/local/lib/erlang/lib/kernel-5.2"},
{mod,application,[]},
{mod,application_controller,[]},
{mod,application_master,[]},
{mod,application_starter,[]},
{mod,auth,[]},
{mod,code,[]},
- {mod,code_server,[]},
- {mod,disk_log,[]},
- {mod,disk_log_1,...},
+ {mod,code_server,...},
+ {mod,...},
+ {...}|...]},
+ {app,mnesia,[{incl_cond,exclude}]},
+ {app,runtime_tools,[{incl_cond,exclude}]},
+ {app,sasl,
+ [{vsn,"3.0.3"},
+ {lib_dir,"/usr/local/lib/erlang/lib/sasl-3.0.3"},
+ {mod,alarm_handler,[]},
+ {mod,erlsrv,[]},
+ {mod,format_lib_supp,[]},
+ {mod,misc_supp,...},
{mod,...},
{...}|...]},
+ {app,ssl,[{incl_cond,exclude}]},
{app,stdlib,
- [{vsn,"1.16.3"},
+ [{vsn,"3.3"},
+ {lib_dir,"/usr/local/lib/erlang/lib/stdlib-3.3"},
{mod,array,[]},
- {mod,base64,[]},
- {mod,beam_lib,[]},
- {mod,c,[]},
- {mod,calendar,[]},
- {mod,dets,[]},
- {mod,dets_server,[]},
- {mod,dets_sup,...},
+ {mod,base64,...},
{mod,...},
{...}|...]},
+ {app,syntax_tools,[{incl_cond,exclude}]},
+ {app,tools,
+ [{vsn,"2.9.1"},{lib_dir,[...]},{mod,...},{...}|...]},
{boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[...]},
{emu_name,"beam"},
{relocatable,true},
- {profile,development},
- {incl_sys_files,[".*"]},
- {excl_sys_files,[]},
- {incl_app_files,[".*"]},
- {excl_app_files,[]},
- {incl_archive_dirs,[".*"]},
- {excl_archive_dirs,["^include$",[...]]},
- {archive_opts,[]},
- {app_type,permanent},
- {app_file,...},
- {...}]}}
-
-
-
-7&gt; reltool:get_config([{sys,[{profile, embedded}]}]).
-{ok,{sys,[{profile,embedded},
+ {profile,...},
+ {...}|...]}}
+7&gt;
+7&gt; reltool:get_config([{sys, [{profile, embedded}]}], true, false).
+{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
+ {lib_dirs,[]},
+ {mod_cond,all},
+ {incl_cond,derived},
+ {boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[sasl]},
+ {emu_name,"beam"},
+ {relocatable,true},
+ {profile,embedded},
{incl_sys_filters,["^bin","^erts","^lib","^releases"]},
{excl_sys_filters,["^bin/(erlc|dialyzer|typer)(|\\.exe)$",
"^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$",
"^erts.*/bin/.*(debug|pdb)"]},
- {incl_app_filters,["^ebin","^include","^priv"]}]}}
-8&gt; reltool:get_config([{sys,[{profile, standalone}]}]).
-{ok,{sys,[{profile,standalone},
+ {incl_app_filters,["^ebin","^include","^priv"]},
+ {excl_app_filters,[]},
+ {incl_archive_filters,[".*"]},
+ {excl_archive_filters,["^include$","^priv$"]},
+ {archive_opts,[]},
+ {rel_app_type,permanent},
+ {embedded_app_type,load},
+ {app_file,keep},
+ {debug_info,keep}]}}
+8&gt;
+8&gt; reltool:get_config([{sys, [{profile, standalone}]}], true, false).
+{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
+ {lib_dirs,[]},
+ {mod_cond,all},
+ {incl_cond,derived},
+ {boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[sasl]},
+ {emu_name,"beam"},
+ {relocatable,true},
+ {profile,standalone},
{incl_sys_filters,["^bin/(erl|epmd)(|\\.exe|\\.ini)$",
"^bin/start(|_clean).boot$","^erts.*/bin","^lib$"]},
{excl_sys_filters,["^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$",
"^erts.*/bin/(start|escript|to_erl|run_erl)(|\\.exe)$",
"^erts.*/bin/.*(debug|pdb)"]},
{incl_app_filters,["^ebin","^priv"]},
- {excl_app_filters,["^ebin/.*\\.appup$"]}]}}
-
+ {excl_app_filters,["^ebin/.*\\.appup$"]},
+ {incl_archive_filters,[".*"]},
+ {excl_archive_filters,["^include$","^priv$"]},
+ {archive_opts,[]},
+ {rel_app_type,permanent},
+ {app_file,keep},
+ {debug_info,keep}]}}
</pre>
</section>
@@ -248,43 +309,51 @@ Eshell V5.7.3 (abort with ^G)
<section>
<title>Generate release and script files</title>
<pre>
-5&gt; {ok, Server} = reltool:start_server([{config, {sys, [{boot_rel, "NAME"},
+Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
+[hipe] [kernel-poll:false]
+Eshell V9.0 (abort with ^G)
+1&gt;
+1&gt; {ok, Server} = reltool:start_server([{config, {sys, [{boot_rel, "NAME"},
{rel, "NAME", "VSN",
[sasl]}]}}]).
{ok,&lt;0.1288.0&gt;}
-6&gt; reltool:get_config(Server).
+2&gt;
+2&gt; reltool:get_config(Server).
{ok,{sys,[{boot_rel,"NAME"},
{rel,"NAME","VSN",[sasl]}]}}
-7&gt; reltool:get_rel(Server, "NAME").
+3&gt;
+3&gt; reltool:get_rel(Server, "NAME").
{ok,{release,{"NAME","VSN"},
- {erts,"5.7"},
- [{kernel,"2.13"},{stdlib,"1.16"},{sasl,"2.1.6"}]}}
-8&gt; reltool:get_script(Server, "NAME").
+ {erts,"9.0"},
+ [{kernel,"5.2"},{stdlib,"3.3"},{sasl,"3.0.3"}]}}
+4&gt;
+4&gt; reltool:get_script(Server, "NAME").
{ok,{script,{"NAME","VSN"},
- [{preLoaded,[erl_prim_loader,erlang,init,otp_ring0,
- prim_eval,prim_file,prim_inet,prim_zip,
- zlib]},
+ [{preLoaded,[erl_prim_loader,erl_tracer,erlang,
+ erts_code_purger,erts_dirty_process_code_checker,
+ erts_internal,erts_literal_area_collector,init,otp_ring0,
+ prim_eval,prim_file,prim_inet,prim_zip,zlib]},
{progress,preloaded},
- {path,["$ROOT/lib/kernel-2.13/ebin",
- "$ROOT/lib/stdlib-1.16/ebin"]},
+ {path,["$ROOT/lib/kernel-5.2/ebin",
+ "$ROOT/lib/stdlib-3.3/ebin"]},
{primLoad,[error_handler]},
{kernel_load_completed},
{progress,kernel_load_completed},
- {path,["$ROOT/lib/kernel-2.13/ebin"]},
+ {path,["$ROOT/lib/kernel-5.2/ebin"]},
{primLoad,[application,application_controller,
application_master,application_starter,auth,code,
code_server,disk_log,disk_log_1,disk_log_server,
disk_log_sup,dist_ac,dist_util,erl_boot_server|...]},
- {path,["$ROOT/lib/stdlib-1.16/ebin"]},
- {primLoad,[array,base64,beam_lib,c,calendar,dets,
- dets_server,dets_sup,dets_utils,dets_v8,dets_v9,dict|...]},
- {path,["$ROOT/lib/sasl-2.1.6/ebin"]},
+ {path,["$ROOT/lib/stdlib-3.3/ebin"]},
+ {primLoad,[array,base64,beam_lib,binary,c,calendar,dets,
+ dets_server,dets_sup,dets_utils,dets_v9,dict|...]},
+ {path,["$ROOT/lib/sasl-3.0.3/ebin"]},
{primLoad,[alarm_handler,erlsrv,format_lib_supp,misc_supp,
- overload,rb,rb_format_supp,release_handler,
- release_handler_1,sasl|...]},
+ rb,rb_format_supp,release_handler,release_handler_1,sasl,
+ sasl_report|...]},
{progress,modules_loaded},
- {path,["$ROOT/lib/kernel-2.13/ebin",
- "$ROOT/lib/stdlib-1.16/ebin","$ROOT/lib/sasl-2.1.6/ebin"]},
+ {path,["$ROOT/lib/kernel-5.2/ebin",
+ "$ROOT/lib/stdlib-3.3/ebin","$ROOT/lib/sasl-3.0.3/ebin"]},
{kernelProcess,heart,{heart,start,[]}},
{kernelProcess,error_logger,{error_logger,start_link,[]}},
{kernelProcess,application_controller,
@@ -296,7 +365,8 @@ Eshell V5.7.3 (abort with ^G)
{apply,{...}},
{apply,...},
{...}|...]}}
-9&gt; reltool:stop(Server).
+5&gt;
+5&gt; reltool:stop(Server).
ok
</pre>
</section>
@@ -304,13 +374,11 @@ ok
<section>
<title>Create a target system</title>
<pre>
-Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4]
- [async-threads:0] [kernel-poll:false]
-
-Eshell V5.7.3 (abort with ^G)
-1&gt; Config = {sys, [{escript,
- "examples/display_args",
- [{incl_cond, include}]},
+Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
+[hipe] [kernel-poll:false]
+Eshell V9.0 (abort with ^G)
+1&gt;
+1&gt; Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]},
{app, inets, [{incl_cond, include}]},
{app, mnesia, [{incl_cond, exclude}]},
{app, ssl, [{incl_cond, exclude}]},
@@ -322,156 +390,183 @@ Eshell V5.7.3 (abort with ^G)
{app,ssl,[{incl_cond,exclude}]},
{app,runtime_tools,[{incl_cond,exclude}]},
{app,syntax_tools,[{incl_cond,exclude}]}]}
-
-
-
+2&gt;
2&gt; {ok, Spec} = reltool:get_target_spec([Config]).
{ok,[{create_dir,"releases",
- [{write_file,"start_erl.data","5.7.3 1.0"},
- {create_dir,"1.0",
- [{write_file,"start_clean.rel",
- [37,37,32,114,101,108,32,103,101,110,101|...]},
- {write_file,"start_clean.script",
- [37,37,32,115,99,114,105,112,116,32|...]},
- {write_file,"start_clean.boot",
- &lt;&lt;131,104,3,100,0,6,115,99,114,...&gt;&gt;},
- {write_file,"start_sasl.rel",
- [37,37,32,114,101,108,32,103,101,110,101|...]},
- {write_file,"start_sasl.script",
- [37,37,32,115,99,114,105,112,116,32|...]},
- {write_file,"start_sasl.boot",
- &lt;&lt;131,104,3,100,0,6,115,99,114,...&gt;&gt;}]}]},
+ [{write_file,"start_erl.data","9.0 1.0\n"},
+ {create_dir,"1.0",
+ [{write_file,"start_clean.rel",
+ [37,37,32,114,101,108,32,103,101,110,101,114,97,116|...]},
+ {write_file,"start_clean.script",
+ [37,37,32,115,99,114,105,112,116,32,103,101,110|...]},
+ {write_file,"start_clean.boot",
+ &lt;&lt;131,104,3,119,6,115,99,114,105,112,116,104,...&gt;&gt;},
+ {write_file,"start_sasl.rel",
+ [37,37,32,114,101,108,32,103,101,110,101|...]},
+ {write_file,"start_sasl.script",
+ [37,37,32,115,99,114,105,112,116,32|...]},
+ {write_file,"start_sasl.boot",
+ &lt;&lt;131,104,3,119,6,115,99,114,105,...&gt;&gt;}]}]},
{create_dir,"bin",
- [{copy_file,"display_args.escript",
- "/clearcase/otp/tools/reltool/examples/display_args"},
- {copy_file,"display_args","erts-5.7.3/bin/escript"},
- {copy_file,"start","erts-5.7.3/bin/start"},
- {copy_file,"erl","erts-5.7.3/bin/dyn_erl"},
- {copy_file,"epmd","erts-5.7.3/bin/epmd"},
- {copy_file,"to_erl","erts-5.7.3/bin/to_erl"},
- {copy_file,"run_erl","erts-5.7.3/bin/run_erl"},
- {copy_file,"escript","erts-5.7.3/bin/escript"},
- {copy_file,"erlc","erts-5.7.3/bin/erlc"},
- {copy_file,"dialyzer","erts-5.7.3/bin/dialyzer"},
- {copy_file,"typer","erts-5.7.3/bin/typer"},
- {write_file,"start_clean.boot",
- &lt;&lt;131,104,3,100,0,6,115,...&gt;&gt;},
- {write_file,"start_sasl.boot",&lt;&lt;131,104,3,100,0,6,...&gt;&gt;},
- {write_file,"start.boot",&lt;&lt;131,104,3,100,0,...&gt;&gt;}]},
- {create_dir,"misc",
- [{copy_file,"makewhatis"},{copy_file,"format_man_pages"}]},
+ [{copy_file,"display_args.escript",
+ "/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args"},
+ {copy_file,"display_args","erts-9.0/bin/escript"},
+ {copy_file,"start","erts-9.0/bin/start"},
+ {copy_file,"ct_run","erts-9.0/bin/ct_run"},
+ {copy_file,"dialyzer","erts-9.0/bin/dialyzer"},
+ {copy_file,"run_erl","erts-9.0/bin/run_erl"},
+ {copy_file,"erl","erts-9.0/bin/dyn_erl"},
+ {copy_file,"to_erl","erts-9.0/bin/to_erl"},
+ {copy_file,"epmd","erts-9.0/bin/epmd"},
+ {copy_file,"erlc","erts-9.0/bin/erlc"},
+ {copy_file,"typer","erts-9.0/bin/typer"},
+ {copy_file,"escript","erts-9.0/bin/escript"},
+ {write_file,"start_clean.boot",&lt;&lt;131,104,3,119,6,115,...&gt;&gt;},
+ {write_file,"start_sasl.boot",&lt;&lt;131,104,3,119,6,...&gt;&gt;},
+ {write_file,"start.boot",&lt;&lt;131,104,3,119,...&gt;&gt;}]},
{copy_file,"Install"},
+ {create_dir,"misc",
+ [{copy_file,"makewhatis"},{copy_file,"format_man_pages"}]},
{create_dir,"usr",
- [{create_dir,"lib",
- [{copy_file,"liberts_r.a"},{copy_file,"liberts.a"}]},
- {create_dir,"include",
- [{copy_file,"erl_fixed_size_int_types.h"},
- {copy_file,"erl_int_sizes_config.h"},
- {copy_file,"erl_memory_trace_parser.h"},
- {create_dir,"obsolete",[{copy_file,"driver.h"}]},
- {copy_file,"driver_int.h"},
- {copy_file,"erl_driver.h"}]}]},
- {create_dir,"erts-5.7.3",
- [{create_dir,"lib",
- [{create_dir,"internal",
- [{copy_file,"liberts_internal_r.a"},
- {copy_file,"liberts_internal.a"},
- {copy_file,"libethread.a"},
- {copy_file,"README"}]},
- {copy_file,"liberts_r.a"},
- {copy_file,"liberts.a"}]},
- {create_dir,"bin",
- [{copy_file,"start"},
- {copy_file,"erl","erts-5.7.3/bin/dyn_erl"},
- {copy_file,"epmd"},
- {copy_file,"to_erl"},
- {copy_file,"run_erl"},
- {copy_file,"escript"},
- {copy_file,"erlc"},
- {copy_file,"dialyzer"},
- {copy_file,"typer"},
- {copy_file,"erlexec"},
- {copy_file,[...]},
- {copy_file,...},
- {...}|...]},
- {create_dir,"doc",[]},
- {create_dir,"man",[]},
- {create_dir,"include",
- [{create_dir,"internal",
- [{create_dir,"tile",[{copy_file,...},{...}]},
- {create_dir,"sparc64",[{...}]},
- {create_dir,"sparc32",[...]},
- {create_dir,[...],...},
- {create_dir,...},
- {...}|...]},
- {copy_file,"erl_fixed_size_int_types.h"},
- {copy_file,"erl_int_sizes_config.h"},
- {copy_file,"erl_memory_trace_parser.h"},
- {copy_file,"driver_int.h"},
- {copy_file,"erl_driver.h"}]},
- {create_dir,"src",[{copy_file,"setuid_socket_wrap.c"}]}]},
+ [{create_dir,"lib",
+ [{copy_file,"liberts.a"},
+ {copy_file,"liberl_interface_st.a"},
+ {copy_file,"liberts_r.a"},
+ {copy_file,"libic.a"},
+ {copy_file,"liberl_interface.a"},
+ {copy_file,"libei_st.a"},
+ {copy_file,"libei.a"}]},
+ {create_dir,"include",
+ [{copy_file,"erl_memory_trace_parser.h"},
+ {copy_file,"driver_int.h"},
+ {copy_file,"ei_connect.h"},
+ {copy_file,"ei.h"},
+ {copy_file,"erl_nif_api_funcs.h"},
+ {copy_file,"erl_fixed_size_int_types.h"},
+ {copy_file,"erl_int_sizes_config.h"},
+ {copy_file,"erl_interface.h"},
+ {copy_file,"eicode.h"},
+ {copy_file,"erl_driver.h"},
+ {copy_file,"erlang.idl"},
+ {copy_file,[...]},
+ {copy_file,...},
+ {...}]}]},
+ {create_dir,"erts-9.0",
+ [{create_dir,"bin",
+ [{copy_file,"start"},
+ {copy_file,"ct_run"},
+ {copy_file,"erlexec"},
+ {copy_file,"dialyzer"},
+ {copy_file,"beam.smp"},
+ {copy_file,"run_erl"},
+ {copy_file,"erl","erts-9.0/bin/dyn_erl"},
+ {copy_file,"to_erl"},
+ {copy_file,"epmd"},
+ {copy_file,"erl_child_setup"},
+ {copy_file,"heart"},
+ {copy_file,[...]},
+ {copy_file,...},
+ {...}|...]},
+ {create_dir,"lib",
+ [{create_dir,"internal",
+ [{copy_file,"liberts_internal.a"},
+ {copy_file,"liberts_internal_r.a"},
+ {copy_file,"libethread.a"},
+ {copy_file,"README"}]},
+ {copy_file,"liberts.a"},
+ {copy_file,"liberts_r.a"}]},
+ {create_dir,"src",[{copy_file,"setuid_socket_wrap.c"}]},
+ {create_dir,"doc",[]},
+ {create_dir,"man",[]},
+ {create_dir,"include",
+ [{create_dir,"internal",
+ [{create_dir,"i386",[{...}|...]},
+ {copy_file,"erl_errno.h"},
+ {copy_file,[...]},
+ {copy_file,...},
+ {...}|...]},
+ {copy_file,"erl_memory_trace_parser.h"},
+ {copy_file,"driver_int.h"},
+ {copy_file,"erl_nif_api_funcs.h"},
+ {copy_file,"erl_fixed_size_int_types.h"},
+ {copy_file,"erl_int_sizes_config.h"},
+ {copy_file,[...]},
+ {copy_file,...},
+ {...}]}]},
{create_dir,"lib",
- [{archive,"compiler-4.6.3.ez",[],
- [{create_dir,"compiler-4.6.3",
- [{create_dir,"ebin",
- [{copy_file,"compiler.appup"},
- {copy_file,[...]},
- {copy_file,...},
- {...}|...]},
- {create_dir,"src",
- [{copy_file,[...]},
- {copy_file,...},{...}|...]}]}]},
- {archive,"crypto-1.6.1.ez",[],
- [{create_dir,"crypto-1.6.1",
- [{create_dir,"ebin",
- [{copy_file,[...]},
- {copy_file,...},{...}|...]},
- {create_dir,"src",[{copy_file,...},{...}|...]}]}]},
- {create_dir,"crypto-1.6.1",
- [{create_dir,"priv",
- [{create_dir,"lib",[{copy_file,[...]}]},
- {create_dir,"obj",[{copy_file,...},{...}]}]}]},
- {archive,"erts-5.7.3.ez",[],
- [{create_dir,"erts-5.7.3",
- [{create_dir,"ebin",[{...}|...]},
- {create_dir,"src",[...]}]}]},
- {archive,"hipe-3.7.3.ez",[],
- [{create_dir,"hipe-3.7.3",
- [{create_dir,"util",[...]},
- {create_dir,[...],...},
- {create_dir,...},
- {...}|...]}]},
- {archive,"kernel-2.13.3.ez",[],
- [{create_dir,"kernel-2.13.3",
- [{create_dir,[...],...},{create_dir,...},{...}]}]},
- {create_dir,"kernel-2.13.3",
- [{create_dir,"include",
- [{copy_file,[...]},{copy_file,...},{...}]}]},
- {archive,"stdlib-1.16.3.ez",[],
- [{create_dir,"stdlib-1.16.3",[{...}|...]}]},
- {create_dir,"stdlib-1.16.3",
- [{create_dir,"include",[{...}|...]}]}]}]}
-
-
-
-3&gt; TargetDir = "my_target_dir".
-"my_target_dir"
+ [{archive,"compiler-7.0.4.ez",[],
+ [{create_dir,"compiler-7.0.4",
+ [{create_dir,"src",
+ [{copy_file,"beam_flatten.erl"},
+ {copy_file,[...]},
+ {copy_file,...},
+ {...}|...]},
+ {create_dir,"ebin",
+ [{copy_file,[...]},{copy_file,...},{...}|...]}]}]},
+ {archive,"crypto-3.7.4.ez",[],
+ [{create_dir,"crypto-3.7.4",
+ [{create_dir,"src",[{copy_file,[...]},{copy_file,...}]},
+ {create_dir,"ebin",[{copy_file,...},{...}|...]}]}]},
+ {create_dir,"crypto-3.7.4",
+ [{create_dir,"priv",
+ [{create_dir,"lib",[{copy_file,[...]},{copy_file,...}]},
+ {create_dir,"obj",[{copy_file,...},{...}|...]}]}]},
+ {archive,"erts-9.0.ez",[],
+ [{create_dir,"erts-9.0",
+ [{create_dir,"src",[{...}|...]},
+ {create_dir,"ebin",[...]}]}]},
+ {archive,"hipe-3.15.4.ez",[],
+ [{create_dir,"hipe-3.15.4",
+ [{create_dir,"flow",[...]},
+ {copy_file,[...]},
+ {create_dir,...},
+ {...}|...]}]},
+ {archive,"inets-6.3.9.ez",[],
+ [{create_dir,"inets-6.3.9",
+ [{create_dir,[...],...},{create_dir,...},{...}]}]},
+ {create_dir,"inets-6.3.9",
+ [{create_dir,"priv",[{create_dir,[...],...}]},
+ {create_dir,"include",[{copy_file,...},{...}]}]},
+ {archive,"kernel-5.2.ez",[],
+ [{create_dir,"kernel-5.2",[{...}|...]}]},
+ {create_dir,"kernel-5.2",
+ [{create_dir,"include",[{...}|...]}]},
+ {archive,"sasl-3.0.3.ez",[],[{create_dir,[...],...}]},
+ {archive,"stdlib-3.3.ez",[],[{create_dir,...}]},
+ {create_dir,"stdlib-3.3",[{create_dir,...}]},
+ {archive,"tools-2.9.1.ez",[],[...]}]}]}
+3&gt;
+3&gt; TargetDir = "/tmp/my_target_dir".
+"/tmp/my_target_dir"
+4&gt;
4&gt; reltool:eval_target_spec(Spec, code:root_dir(), TargetDir).
-{error,"/clearcase/otp/tools/reltool/my_target_dir: no such file or directory"}
-5&gt; file:make_dir("my_target_dir").
+{error,"/tmp/my_target_dir: no such file or directory"}
+5&gt;
+5&gt; file:make_dir(TargetDir).
ok
+6&gt;
6&gt; reltool:eval_target_spec(Spec, code:root_dir(), TargetDir).
ok
+7&gt;
7&gt; file:list_dir(TargetDir).
-{ok,["lib","erts-5.7.3","usr","Install","misc","bin","releases"]}
+{ok,["bin","Install","lib","misc","usr","erts-9.0",
+ "releases"]}
+8&gt;
8&gt; file:list_dir(filename:join([TargetDir,"lib"])).
-{ok,["stdlib-1.16.3","stdlib-1.16.3.ez","kernel-2.13.3",
- "kernel-2.13.3.ez","hipe-3.7.3.ez","erts-5.7.3.ez",
- "crypto-1.6.1","crypto-1.6.1.ez","compiler-4.6.3.ez"]}
-9&gt; file:make_dir("yet_another_target_dir").
+{ok,["tools-2.9.1.ez","kernel-5.2.ez","inets-6.3.9.ez",
+ "kernel-5.2","sasl-3.0.3.ez","hipe-3.15.4.ez","inets-6.3.9",
+ "crypto-3.7.4","crypto-3.7.4.ez","stdlib-3.3.ez",
+ "erts-9.0.ez","stdlib-3.3","compiler-7.0.4.ez"]}
+9&gt;
+9&gt; file:make_dir("/tmp/yet_another_target_dir").
ok
-10&gt; reltool:create_target(Config, "yet_another_target_dir").
+10&gt;
+10&gt; reltool:create_target([Config], "/tmp/yet_another_target_dir").
ok
+11&gt;
+11&gt; file:list_dir("/tmp/yet_another_target_dir").
+{ok,["bin","Install","lib","misc","usr","erts-9.0",
+ "releases"]}
</pre>
</section>
diff --git a/lib/reltool/doc/src/reltool_intro.xml b/lib/reltool/doc/src/reltool_intro.xml
index 8e232b8838..2980ad7977 100644
--- a/lib/reltool/doc/src/reltool_intro.xml
+++ b/lib/reltool/doc/src/reltool_intro.xml
@@ -34,7 +34,7 @@
<rev>%VSN%</rev>
<file>reltool_intro.xml</file>
</header>
- <p><c>Reltool</c> is a release management tool. It analyses a given
+ <p>Reltool is a release management tool. It analyses a given
Erlang/OTP installation and determines various dependencies between
applications. The <c>graphical</c> frontend depicts the dependencies and
enables interactive customization of a target system. The backend provides a
@@ -82,7 +82,7 @@
and about the Erlang/OTP development system:</p>
<list type="bulleted">
<item>
- <p>the Reference Manual of <c>Reltool</c></p>
+ <p>the Reference Manual of Reltool</p>
</item>
<item>
<p>the Erlang/OTP <c>System Principles</c></p>
diff --git a/lib/reltool/src/reltool.hrl b/lib/reltool/src/reltool.hrl
index 9ac22b9450..8b4898570b 100644
--- a/lib/reltool/src/reltool.hrl
+++ b/lib/reltool/src/reltool.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -154,19 +154,19 @@
-record(app_info,
{
- description = "" :: string(),
- id = "" :: string(),
- vsn = "" :: app_vsn(),
- modules = [] :: [mod_name()],
- maxP = infinity :: integer() | infinity,
- maxT = infinity :: integer() | infinity,
- registered = [] :: [atom()],
- incl_apps = [] :: [app_name()],
- applications = [] :: [app_name()],
- env = [] :: [{atom(), term()}],
- mod = undefined :: {mod_name(), [term()]} | undefined,
- start_phases = undefined :: [{atom(), term()}] | undefined,
- runtime_dependencies = [] :: [string()]
+ description = "" :: '_' | string(),
+ id = "" :: '_' | string(),
+ vsn = "" :: '_' | app_vsn(),
+ modules = [] :: '_' | [mod_name()],
+ maxP = infinity :: '_' | integer() | infinity,
+ maxT = infinity :: '_' | integer() | infinity,
+ registered = [] :: '_' | [atom()],
+ incl_apps = [] :: '_' | '$3' | [app_name()],
+ applications = [] :: '_' | '$2' | [app_name()],
+ env = [] :: '_' | [{atom(), term()}],
+ mod = undefined :: '_' | {mod_name(), [term()]} | undefined,
+ start_phases = undefined :: '_' | [{atom(), term()}] | undefined,
+ runtime_dependencies = [] :: '_' | [string()]
}).
-record(regexp, {source, compiled}).
diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl
index 21a4485f94..89e90670cf 100644
--- a/lib/reltool/src/reltool_server.erl
+++ b/lib/reltool/src/reltool_server.erl
@@ -530,9 +530,14 @@ analyse(#state{sys=Sys} = S, Apps, Status) ->
%% Write all #app to app_tab and all #mod to mod_tab.
Status2 = apps_init_is_included(S, Apps, RelApps, Status),
+ %% For each application that is not (directly or indirectly) part
+ %% of a release, but still has #app.is_included==true, propagate
+ %% is_included to the dependencies specified in the .app files.
+ app_propagate_is_included(S),
+
%% For each module that has #mod.is_included==true, propagate
%% is_included to the modules it uses.
- propagate_is_included(S),
+ mod_propagate_is_included(S),
%% Insert reverse dependencies - i.e. for each
%% #mod{name=Mod, uses_mods=[UsedMod]},
@@ -565,31 +570,34 @@ apps_in_rels(Rels, Apps) ->
apps_in_rel(#rel{name = RelName, rel_apps = RelApps}, Apps) ->
Mandatory = [{RelName, kernel}, {RelName, stdlib}],
- Other =
+ Explicit0 = [{RelName, AppName} || #rel_app{name=AppName} <- RelApps],
+ Explicit = Mandatory ++ Explicit0,
+ Deps =
[{RelName, AppName} ||
RA <- RelApps,
- AppName <- [RA#rel_app.name |
+ AppName <-
+ case lists:keyfind(RA#rel_app.name,
+ #app.name,
+ Apps) of
+ App=#app{info = #app_info{applications = AA}} ->
%% Included applications in rel shall overwrite included
%% applications in .app. I.e. included applications in
%% .app shall only be used if it is not defined in rel.
- case RA#rel_app.incl_apps of
- undefined ->
- case lists:keyfind(RA#rel_app.name,
- #app.name,
- Apps) of
- #app{info = #app_info{incl_apps = IA}} ->
- IA;
- false ->
- reltool_utils:throw_error(
- "Release ~tp uses non existing "
- "application ~w",
- [RelName,RA#rel_app.name])
- end;
- IA ->
- IA
- end],
- not lists:keymember(AppName, 2, Mandatory)],
- more_apps_in_rels(Mandatory ++ Other, Apps, []).
+ IA = case RA#rel_app.incl_apps of
+ undefined ->
+ (App#app.info)#app_info.incl_apps;
+ RelIA ->
+ RelIA
+ end,
+ AA ++ IA;
+ false ->
+ reltool_utils:throw_error(
+ "Release ~tp uses non existing "
+ "application ~w",
+ [RelName,RA#rel_app.name])
+ end,
+ not lists:keymember(AppName, 2, Explicit)],
+ more_apps_in_rels(Deps, Apps, Explicit).
more_apps_in_rels([{RelName, AppName} = RA | RelApps], Apps, Acc) ->
case lists:member(RA, Acc) of
@@ -597,8 +605,8 @@ more_apps_in_rels([{RelName, AppName} = RA | RelApps], Apps, Acc) ->
more_apps_in_rels(RelApps, Apps, Acc);
false ->
case lists:keyfind(AppName, #app.name, Apps) of
- #app{info = #app_info{applications = InfoApps}} ->
- Extra = [{RelName, N} || N <- InfoApps],
+ #app{info = #app_info{applications = AA, incl_apps=IA}} ->
+ Extra = [{RelName, N} || N <- AA++IA],
Acc2 = more_apps_in_rels(Extra, Apps, [RA | Acc]),
more_apps_in_rels(RelApps, Apps, Acc2);
false ->
@@ -610,7 +618,6 @@ more_apps_in_rels([{RelName, AppName} = RA | RelApps], Apps, Acc) ->
more_apps_in_rels([], _Apps, Acc) ->
Acc.
-
apps_init_is_included(S, Apps, RelApps, Status) ->
lists:foldl(fun(App, AccStatus) ->
app_init_is_included(S, App, RelApps, AccStatus)
@@ -745,6 +752,100 @@ false_to_undefined(Bool) ->
_ -> Bool
end.
+get_no_rel_apps_and_dependencies(S) ->
+ ets:select(S#state.app_tab, [{#app{name='$1',
+ is_included=true,
+ info=#app_info{applications='$2',
+ incl_apps='$3',
+ _='_'},
+ rels=[],
+ _='_'},
+ [],
+ [{{'$1','$2','$3'}}]}]).
+
+app_propagate_is_included(S) ->
+ lists:foreach(
+ fun({AppName,DepNames1,DepNames2}) ->
+ app_mark_is_included(S,AppName,DepNames1++DepNames2)
+ end,
+ get_no_rel_apps_and_dependencies(S)).
+
+app_mark_is_included(#state{app_tab=AppTab, mod_tab=ModTab, sys=Sys}=S,UsedByName,[AppName|AppNames]) ->
+ case ets:lookup(AppTab, AppName) of
+ [A] ->
+ case A#app.is_included of
+ undefined ->
+ %% Not yet marked => mark and propagate
+ A2 =
+ case A#app.incl_cond of
+ include ->
+ A#app{is_pre_included = true,
+ is_included = true};
+ exclude ->
+ A#app{is_pre_included = false,
+ is_included = false};
+ AppInclCond when AppInclCond==undefined;
+ AppInclCond==derived ->
+ A#app{is_included = true}
+ end,
+ ets:insert(AppTab, A2),
+
+ ModCond =
+ case A#app.mod_cond of
+ undefined -> Sys#sys.mod_cond;
+ _ -> A#app.mod_cond
+ end,
+ Filter =
+ fun(M) ->
+ case ModCond of
+ all -> true;
+ app -> M#mod.is_app_mod;
+ ebin -> M#mod.is_ebin_mod;
+ derived -> false;
+ none -> false
+ end
+ end,
+ Mods = lists:filter(Filter, A#app.mods),
+ %% Mark the modules of this app, but no need to go
+ %% recursive on modules since this is done in
+ %% mod_mark_is_included.
+ [case M#mod.is_included of
+ undefined ->
+ M2 =
+ case M#mod.incl_cond of
+ include ->
+ M#mod{is_pre_included = true,
+ is_included = true};
+ exclude ->
+ M#mod{is_pre_included = false,
+ is_included = false};
+ ModInclCond when ModInclCond==undefined;
+ ModInclCond==derived ->
+ M#mod{is_included = true}
+ end,
+ ets:insert(ModTab, M2);
+ _ ->
+ ok
+ end || M <- Mods],
+
+ %% Go recursive on dependencies
+ #app{info=#app_info{applications=DepNames1,
+ incl_apps=DepNames2}} = A,
+ app_mark_is_included(S,AppName,DepNames1++DepNames2);
+ _ ->
+ %% Already marked
+ ok
+ end;
+ [] ->
+ %% Missing app
+ reltool_utils:throw_error(
+ "Application ~tp uses non existing application ~w",
+ [UsedByName,AppName])
+ end,
+ app_mark_is_included(S, UsedByName, AppNames);
+app_mark_is_included(_S, _UsedByName, []) ->
+ ok.
+
%% Return the list for {ModName, UsesModNames} for all modules where
%% #mod.is_included==true.
get_all_mods_and_dependencies(S) ->
@@ -755,7 +856,7 @@ get_all_mods_and_dependencies(S) ->
[],
[{{'$1','$2'}}]}]).
-propagate_is_included(S) ->
+mod_propagate_is_included(S) ->
case lists:flatmap(
fun({ModName,UsesModNames}) ->
mod_mark_is_included(S,ModName,UsesModNames,[])
diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl
index e9bd46fb27..e8dfea94da 100644
--- a/lib/reltool/test/reltool_server_SUITE.erl
+++ b/lib/reltool/test/reltool_server_SUITE.erl
@@ -142,6 +142,7 @@ all() ->
save_config,
dependencies,
mod_incl_cond_derived,
+ dep_in_app_not_xref,
use_selected_vsn,
use_selected_vsn_relative_path,
non_standard_vsn_id,
@@ -408,7 +409,6 @@ create_release_sort(Config) ->
{app,tools,[{mod_cond,app},{incl_cond,include}]}
]},
%% Generate release
-
?msym({ok, {release, {RelName1, RelVsn},
{erts, _},
[{kernel, _},
@@ -2304,6 +2304,7 @@ dependencies(Config) ->
ok.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Test that incl_cond on mod level overwrites mod_cond on app level
%% Uses same test applications as dependencies/1 above
mod_incl_cond_derived(Config) ->
@@ -2346,6 +2347,40 @@ mod_incl_cond_derived(Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% ERL-167, OTP-11993: For applications that are not included in a
+%% release spec ('rel'), dependencies in the .app files are not
+%% considered - only those found with xref.
+dep_in_app_not_xref(Config) ->
+ RelName = "Just testing...",
+ RelVsn = "1.0",
+ Sys =
+ {sys,
+ [
+ {lib_dirs,[filename:join(datadir(Config),"dep_in_app_not_xref")]},
+ {incl_cond,exclude},
+ {incl_archive_filters,[]},
+ {erts,[{incl_cond,exclude}]},
+ {boot_rel, RelName},
+ {rel, RelName, RelVsn, [kernel, stdlib]},
+ {app,kernel,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]},
+ {app,x,[{incl_cond,include}]},
+ {app,y,[{incl_cond,derived}]},
+ {app,z,[{incl_cond,derived}]}
+ ]},
+
+ TargetDir = filename:join([?WORK_DIR, "target_dep_in_app_not_xref"]),
+ ?m(ok, reltool_utils:recursive_delete(TargetDir)),
+ ?m(ok, file:make_dir(TargetDir)),
+ ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Sys}])]),
+ ok = ?m(ok, reltool:create_target([{config, Sys}], TargetDir)),
+ ?log("~p~n",[file:list_dir(filename:join([TargetDir,"lib"]))]),
+
+ ?m(true, filelib:is_dir(filename:join([TargetDir,"lib","y-1.0"]))),
+ ?m(true, filelib:is_dir(filename:join([TargetDir,"lib","z-1.0"]))),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
use_selected_vsn(Config) ->
LibDir1 = filename:join(datadir(Config),"use_selected_vsn"),
B1Dir = filename:join(LibDir1,"b-1.0"),
diff --git a/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/x-1.0/ebin/x.app b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/x-1.0/ebin/x.app
new file mode 100644
index 0000000000..fe922e3a41
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/x-1.0/ebin/x.app
@@ -0,0 +1,7 @@
+% -*-erlang-*-
+{application, x,
+ [{description, "Main application in reltool dependency test"},
+ {vsn, "1.0"},
+ {modules, [x1]},
+ {registered, []},
+ {applications, [kernel, stdlib, y]}]}.
diff --git a/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/x-1.0/src/x1.erl b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/x-1.0/src/x1.erl
new file mode 100644
index 0000000000..bf1e7f9279
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/x-1.0/src/x1.erl
@@ -0,0 +1,5 @@
+-module(x1).
+-compile(export_all).
+
+f() ->
+ ok.
diff --git a/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/y-1.0/ebin/y.app b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/y-1.0/ebin/y.app
new file mode 100644
index 0000000000..a21cfe6c21
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/y-1.0/ebin/y.app
@@ -0,0 +1,8 @@
+% -*-erlang-*-
+{application, y,
+ [{description, "Library application in reltool dependency test"},
+ {vsn, "1.0"},
+ {modules, [y1]},
+ {registered, []},
+ {applications, [kernel, stdlib]},
+ {included_applications, [z]}]}.
diff --git a/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/y-1.0/src/y1.erl b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/y-1.0/src/y1.erl
new file mode 100644
index 0000000000..902a7e21f3
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/y-1.0/src/y1.erl
@@ -0,0 +1,5 @@
+-module(y1).
+-compile(export_all).
+
+f() ->
+ ok.
diff --git a/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/z-1.0/ebin/z.app b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/z-1.0/ebin/z.app
new file mode 100644
index 0000000000..437a0968e9
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/z-1.0/ebin/z.app
@@ -0,0 +1,7 @@
+% -*-erlang-*-
+{application, z,
+ [{description, "Library application in reltool dependency test"},
+ {vsn, "1.0"},
+ {modules, [z1]},
+ {registered, []},
+ {applications, [kernel, stdlib]}]}.
diff --git a/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/z-1.0/src/z1.erl b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/z-1.0/src/z1.erl
new file mode 100644
index 0000000000..97ef90b87f
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE_data/dep_in_app_not_xref/z-1.0/src/z1.erl
@@ -0,0 +1,5 @@
+-module(z1).
+-compile(export_all).
+
+f() ->
+ ok.
diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk
index 76f69fd294..3617f6e0d9 100644
--- a/lib/reltool/vsn.mk
+++ b/lib/reltool/vsn.mk
@@ -1 +1 @@
-RELTOOL_VSN = 0.7.1
+RELTOOL_VSN = 0.7.4
diff --git a/lib/runtime_tools/c_src/dyntrace.c b/lib/runtime_tools/c_src/dyntrace.c
index 3d2de9c21c..b589f5ef07 100644
--- a/lib/runtime_tools/c_src/dyntrace.c
+++ b/lib/runtime_tools/c_src/dyntrace.c
@@ -24,7 +24,7 @@
-#include "erl_nif.h"
+#include <erl_nif.h>
#include "config.h"
#include "sys.h"
#include "dtrace-wrapper.h"
diff --git a/lib/runtime_tools/doc/src/LTTng.xml b/lib/runtime_tools/doc/src/LTTng.xml
index 82a4c79379..392d54857c 100644
--- a/lib/runtime_tools/doc/src/LTTng.xml
+++ b/lib/runtime_tools/doc/src/LTTng.xml
@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="utf8" ?>
+<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
- <year>2016</year><year>2016</year>
+ <year>2016</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/runtime_tools/doc/src/dbg.xml b/lib/runtime_tools/doc/src/dbg.xml
index 14a81b2293..95f74d4607 100644
--- a/lib/runtime_tools/doc/src/dbg.xml
+++ b/lib/runtime_tools/doc/src/dbg.xml
@@ -78,7 +78,7 @@
<p>Pseudo function that by means of a <c>parse_transform</c>
translates the <em>literal</em><c>fun()</c> typed as parameter in
the function call to a match specification as described in
- the <c>match_spec</c> manual of <c>ERTS</c> users guide.
+ the <c>match_spec</c> manual of ERTS users guide.
(with literal I mean that the <c>fun()</c> needs to
textually be written as the parameter of the function, it
cannot be held in a variable which in turn is passed to the
@@ -954,7 +954,7 @@ Error: fun containing local erlang function calls ('is_atomm' called in guard)\
as the tuple <c>{drop, N}</c> where <c>N</c> is the number of consecutive messages
dropped. In case of heavy tracing, drop's are likely to occur,
and they surely occur if no client is reading the trace
- messages.</p>
+ messages. The default value of <c>QueSize</c> is 200.</p>
</desc>
</func>
<func>
diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml
index 6bec7cb9ca..2bfc174cae 100644
--- a/lib/runtime_tools/doc/src/notes.xml
+++ b/lib/runtime_tools/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,6 +32,106 @@
<p>This document describes the changes made to the Runtime_Tools
application.</p>
+<section><title>Runtime_Tools 1.12</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add compile option <c>-compile(no_native)</c> in modules
+ with <c>on_load</c> directive which is not yet supported
+ by HiPE.</p>
+ <p>
+ Own Id: OTP-14316 Aux Id: PR-1390 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Miscellaneous updates due to atoms containing
+ arbitrary Unicode characters. </p>
+ <p>
+ Own Id: OTP-14285</p>
+ </item>
+ <item>
+ <p> Sockets can now be bound to device (SO_BINDTODEVICE)
+ on platforms where it is supported. </p> <p> This has
+ been implemented e.g to support VRF-Lite under Linux; see
+ <url
+ href="https://www.kernel.org/doc/Documentation/networking/vrf.txt">
+ VRF </url>, and GitHub pull request <url
+ href="https://github.com/erlang/otp/pull/1326">#1326</url>.
+ </p>
+ <p>
+ Own Id: OTP-14357 Aux Id: PR-1326 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Runtime_Tools 1.11.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ etop erroneously reported the average scheduler
+ utilization since the tool was first started instead of
+ the scheduler utilization since last update. This is now
+ corrected.</p>
+ <p>
+ Own Id: OTP-14090 Aux Id: seq13232 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Runtime_Tools 1.11</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add option <c>queue_size</c> to ttb:tracer/2. This sets
+ the maximum queue size for the IP trace driver which is
+ used when tracing to shell and/or <c>{local,File}</c>.</p>
+ <p>
+ The default value for <c>queue_size</c> is specified by
+ <c>dbg</c>, and it is now changed from 50 to 200.</p>
+ <p>
+ Own Id: OTP-13829 Aux Id: seq13171 </p>
+ </item>
+ <item>
+ <p>
+ The port information page is updated to show more
+ information per port.</p>
+ <p>
+ Own Id: OTP-13948 Aux Id: ERL-272 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Runtime_Tools 1.10.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Correct some minor documentation issues. </p>
+ <p>
+ Own Id: OTP-13891</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Runtime_Tools 1.10</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -668,7 +768,7 @@
also been extended. </item><item> The <c>configure</c>
scripts of <c>erl_interface</c> and <c>odbc</c> now
search for thread libraries and thread library quirks the
- same way as <c>erts</c> do. </item><item> The
+ same way as ERTS do. </item><item> The
<c>configure</c> script of the <c>odbc</c> application
now also looks for odbc libraries in <c>lib64</c> and
<c>lib/64</c> directories when building on a 64-bit
diff --git a/lib/runtime_tools/src/Makefile b/lib/runtime_tools/src/Makefile
index 2c902952a1..5a99c6e240 100644
--- a/lib/runtime_tools/src/Makefile
+++ b/lib/runtime_tools/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2016. All Rights Reserved.
+# Copyright Ericsson AB 1999-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -42,7 +42,6 @@ MODULES= \
runtime_tools_sup \
dbg \
dyntrace \
- percept_profile \
system_information \
observer_backend \
ttb_autostart\
diff --git a/lib/runtime_tools/src/dbg.erl b/lib/runtime_tools/src/dbg.erl
index c0d4665bda..e82f27896d 100644
--- a/lib/runtime_tools/src/dbg.erl
+++ b/lib/runtime_tools/src/dbg.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -50,7 +50,8 @@ fun2ms(ShellFun) when is_function(ShellFun) ->
case ms_transform:transform_from_shell(
?MODULE,Clauses,ImportList) of
{error,[{_,[{_,_,Code}|_]}|_],_} ->
- io:format("Error: ~s~n",
+ Modifier = modifier(),
+ io:format("Error: ~"++Modifier++"s~n",
[ms_transform:format_error(Code)]),
{error,transform_error};
Else ->
@@ -233,8 +234,10 @@ ctpe(Event) when Event =:= send;
%% List saved and built-in trace patterns.
%%
ltp() ->
+ Modifier = modifier(),
+ Format = "~p: ~"++Modifier++"p~n",
pt_doforall(fun({X, El},_Ignore) ->
- io:format("~p: ~p~n", [X,El])
+ io:format(Format, [X,El])
end,[]).
%%
@@ -261,12 +264,13 @@ dtp(_) ->
%%
%% Actually write the built-in trace patterns too.
wtp(FileName) ->
- case file:open(FileName,[write]) of
+ case file:open(FileName,[write,{encoding,utf8}]) of
{error, Reason} ->
{error, Reason};
{ok, File} ->
+ io:put_chars(File, "%% coding: utf8\n"),
pt_doforall(fun ({_, Val}, _) when is_list(Val) ->
- io:format(File, "~p.~n", [Val]);
+ io:format(File, "~tp.~n", [Val]);
({_, _}, _) ->
ok
end,
@@ -427,7 +431,7 @@ trace_port(file, Filename) ->
trace_port1(file, Filename, nowrap);
trace_port(ip, Portno) when is_integer(Portno) ->
- trace_port(ip,{Portno,50});
+ trace_port(ip,{Portno,200});
trace_port(ip, {Portno, Qsiz}) when is_integer(Portno), is_integer(Qsiz) ->
fun() ->
@@ -667,7 +671,9 @@ init(Parent) ->
loop({C,T}=SurviveLinks, Table) ->
receive
{From,i} ->
- reply(From, display_info(lists:map(fun({N,_}) -> N end,get()))),
+ Modifier = modifier(),
+ Reply = display_info(lists:map(fun({N,_}) -> N end,get()), Modifier),
+ reply(From, Reply),
loop(SurviveLinks, Table);
{From,{p,Pid,Flags}} ->
reply(From, trace_process(Pid, Flags)),
@@ -773,7 +779,10 @@ loop({C,T}=SurviveLinks, Table) ->
C ->
case lists:delete(Pid,T) of
T ->
- io:format(user,"** dbg got EXIT - terminating: ~p~n",
+ Modifier = modifier(user),
+ io:format(user,
+ "** dbg got EXIT - terminating: ~"++
+ Modifier++"p~n",
[Reason]),
exit(done);
NewT ->
@@ -784,7 +793,8 @@ loop({C,T}=SurviveLinks, Table) ->
loop({NewC,T}, Table)
end;
Other ->
- io:format(user,"** dbg got garbage: ~p~n",
+ Modifier = modifier(user),
+ io:format(user,"** dbg got garbage: ~"++Modifier++"p~n",
[{Other,SurviveLinks,Table}]),
loop(SurviveLinks, Table)
end.
@@ -836,7 +846,9 @@ recv_all_traces(Suspended0, Traces, Timeout) ->
{done, Suspended0, Traces};
Other ->
%%% Is this really a good idea?
- io:format(user,"** tracer received garbage: ~p~n", [Other]),
+ Modifier = modifier(user),
+ io:format(user,"** tracer received garbage: ~"++Modifier++"p~n",
+ [Other]),
recv_all_traces(Suspended0, Traces, Timeout)
after Timeout ->
{loop, Suspended0, Traces}
@@ -962,165 +974,224 @@ do_relay_1(RelP) ->
RelP ! TraceInfo,
do_relay_1(RelP);
Other ->
- io:format(user,"** relay got garbage: ~p~n", [Other]),
+ Modifier = modifier(user),
+ io:format(user,"** relay got garbage: ~"++Modifier++"p~n", [Other]),
do_relay_1(RelP)
end.
dhandler(end_of_trace, Out) ->
Out;
dhandler(Trace, Out) when element(1, Trace) == trace, tuple_size(Trace) >= 3 ->
- dhandler1(Trace, tuple_size(Trace), Out);
+ dhandler1(Trace, tuple_size(Trace), out(Out));
dhandler(Trace, Out) when element(1, Trace) == trace_ts, tuple_size(Trace) >= 4 ->
- dhandler1(Trace, tuple_size(Trace)-1, element(tuple_size(Trace),Trace), Out);
+ dhandler1(Trace, tuple_size(Trace)-1, element(tuple_size(Trace),Trace)
+ , out(Out));
dhandler(Trace, Out) when element(1, Trace) == drop, tuple_size(Trace) =:= 2 ->
- io:format(Out, "*** Dropped ~p messages.~n", [element(2,Trace)]),
- Out;
-dhandler(Trace, Out) when element(1, Trace) == seq_trace, tuple_size(Trace) >= 3 ->
+ {Device,Modifier} = out(Out),
+ io:format(Device, "*** Dropped ~p messages.~n", [element(2,Trace)]),
+ {Device,Modifier};
+dhandler(Trace, Out) when element(1, Trace) == seq_trace,
+ tuple_size(Trace) >= 3 ->
+ {Device,Modifier} = out(Out),
SeqTraceInfo = case Trace of
{seq_trace, Lbl, STI, TS} ->
- io:format(Out, "SeqTrace ~p [~p]: ",
+ io:format(Device, "SeqTrace ~p [~p]: ",
[TS, Lbl]),
STI;
{seq_trace, Lbl, STI} ->
- io:format(Out, "SeqTrace [~p]: ",
+ io:format(Device, "SeqTrace [~p]: ",
[Lbl]),
STI
end,
case SeqTraceInfo of
{send, Ser, Fr, To, Mes} ->
- io:format(Out, "(~p) ~p ! ~p [Serial: ~p]~n",
+ io:format(Device, "(~p) ~p ! ~"++Modifier++"p [Serial: ~p]~n",
[Fr, To, Mes, Ser]);
{'receive', Ser, Fr, To, Mes} ->
- io:format(Out, "(~p) << ~p [Serial: ~p, From: ~p]~n",
+ io:format(Device, "(~p) << ~"++Modifier++"p [Serial: ~p, From: ~p]~n",
[To, Mes, Ser, Fr]);
{print, Ser, Fr, _, Info} ->
- io:format(Out, "-> ~p [Serial: ~p, From: ~p]~n",
+ io:format(Device, "-> ~"++Modifier++"p [Serial: ~p, From: ~p]~n",
[Info, Ser, Fr]);
Else ->
- io:format(Out, "~p~n", [Else])
+ io:format(Device, "~"++Modifier++"p~n", [Else])
end,
- Out;
+ {Device,Modifier};
dhandler(_Trace, Out) ->
Out.
-dhandler1(Trace, Size, Out) ->
+dhandler1(Trace, Size, {Device,Modifier}) ->
From = element(2, Trace),
case element(3, Trace) of
'receive' ->
case element(4, Trace) of
{dbg,ok} -> ok;
Message ->
- io:format(Out, "(~p) << ~p~n", [From,Message])
+ io:format(Device, "(~p) << ~"++Modifier++"p~n",
+ [From,Message])
end;
'send' ->
Message = element(4, Trace),
To = element(5, Trace),
- io:format(Out, "(~p) ~p ! ~p~n", [From,To,Message]);
+ io:format(Device, "(~p) ~p ! ~"++Modifier++"p~n", [From,To,Message]);
call ->
case element(4, Trace) of
MFA when Size == 5 ->
Message = element(5, Trace),
- io:format(Out, "(~p) call ~s (~p)~n", [From,ffunc(MFA),Message]);
+ io:format(Device,
+ "(~p) call ~"++Modifier++"s (~"++Modifier++"p)~n",
+ [From,ffunc(MFA,Modifier),Message]);
MFA ->
- io:format(Out, "(~p) call ~s~n", [From,ffunc(MFA)])
+ io:format(Device, "(~p) call ~"++Modifier++"s~n",
+ [From,ffunc(MFA,Modifier)])
end;
return -> %% To be deleted...
case element(4, Trace) of
MFA when Size == 5 ->
Ret = element(5, Trace),
- io:format(Out, "(~p) old_ret ~s -> ~p~n", [From,ffunc(MFA),Ret]);
+ io:format(Device,
+ "(~p) old_ret ~"++Modifier++"s -> ~"++Modifier++
+ "p~n",
+ [From,ffunc(MFA,Modifier),Ret]);
MFA ->
- io:format(Out, "(~p) old_ret ~s~n", [From,ffunc(MFA)])
+ io:format(Device, "(~p) old_ret ~"++Modifier++"s~n",
+ [From,ffunc(MFA,Modifier)])
end;
return_from ->
MFA = element(4, Trace),
Ret = element(5, Trace),
- io:format(Out, "(~p) returned from ~s -> ~p~n", [From,ffunc(MFA),Ret]);
+ io:format(Device,
+ "(~p) returned from ~"++Modifier++"s -> ~"++Modifier++"p~n",
+ [From,ffunc(MFA,Modifier),Ret]);
return_to ->
MFA = element(4, Trace),
- io:format(Out, "(~p) returning to ~s~n", [From,ffunc(MFA)]);
+ io:format(Device, "(~p) returning to ~"++Modifier++"s~n",
+ [From,ffunc(MFA,Modifier)]);
spawn when Size == 5 ->
Pid = element(4, Trace),
MFA = element(5, Trace),
- io:format(Out, "(~p) spawn ~p as ~s~n", [From,Pid,ffunc(MFA)]);
+ io:format(Device, "(~p) spawn ~p as ~"++Modifier++"s~n",
+ [From,Pid,ffunc(MFA,Modifier)]);
Op ->
- io:format(Out, "(~p) ~p ~s~n", [From,Op,ftup(Trace,4,Size)])
+ io:format(Device, "(~p) ~p ~"++Modifier++"s~n",
+ [From,Op,ftup(Trace,4,Size,Modifier)])
end,
- Out.
+ {Device,Modifier}.
-dhandler1(Trace, Size, TS, Out) ->
+dhandler1(Trace, Size, TS, {Device,Modifier}) ->
From = element(2, Trace),
case element(3, Trace) of
'receive' ->
case element(4, Trace) of
{dbg,ok} -> ok;
Message ->
- io:format(Out, "(~p) << ~p (Timestamp: ~p)~n", [From,Message,TS])
+ io:format(Device,
+ "(~p) << ~"++Modifier++"p (Timestamp: ~p)~n",
+ [From,Message,TS])
end;
'send' ->
Message = element(4, Trace),
To = element(5, Trace),
- io:format(Out, "(~p) ~p ! ~p (Timestamp: ~p)~n", [From,To,Message,TS]);
+ io:format(Device, "(~p) ~p ! ~"++Modifier++"p (Timestamp: ~p)~n",
+ [From,To,Message,TS]);
call ->
case element(4, Trace) of
MFA when Size == 5 ->
Message = element(5, Trace),
- io:format(Out, "(~p) call ~s (~p) (Timestamp: ~p)~n", [From,ffunc(MFA),Message,TS]);
+ io:format(Device,
+ "(~p) call ~"++Modifier++"s (~"++Modifier++
+ "p) (Timestamp: ~p)~n",
+ [From,ffunc(MFA,Modifier),Message,TS]);
MFA ->
- io:format(Out, "(~p) call ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS])
+ io:format(Device,
+ "(~p) call ~"++Modifier++"s (Timestamp: ~p)~n",
+ [From,ffunc(MFA,Modifier),TS])
end;
return -> %% To be deleted...
case element(4, Trace) of
MFA when Size == 5 ->
Ret = element(5, Trace),
- io:format(Out, "(~p) old_ret ~s -> ~p (Timestamp: ~p)~n", [From,ffunc(MFA),Ret,TS]);
+ io:format(Device,
+ "(~p) old_ret ~"++Modifier++"s -> ~"++Modifier++
+ "p (Timestamp: ~p)~n",
+ [From,ffunc(MFA,Modifier),Ret,TS]);
MFA ->
- io:format(Out, "(~p) old_ret ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS])
+ io:format(Device,
+ "(~p) old_ret ~"++Modifier++"s (Timestamp: ~p)~n",
+ [From,ffunc(MFA,Modifier),TS])
end;
return_from ->
MFA = element(4, Trace),
Ret = element(5, Trace),
- io:format(Out, "(~p) returned from ~s -> ~p (Timestamp: ~p)~n", [From,ffunc(MFA),Ret,TS]);
+ io:format(Device,
+ "(~p) returned from ~"++Modifier++"s -> ~"++Modifier++
+ "p (Timestamp: ~p)~n",
+ [From,ffunc(MFA,Modifier),Ret,TS]);
return_to ->
MFA = element(4, Trace),
- io:format(Out, "(~p) returning to ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS]);
+ io:format(Device,
+ "(~p) returning to ~"++Modifier++"s (Timestamp: ~p)~n",
+ [From,ffunc(MFA,Modifier),TS]);
spawn when Size == 5 ->
Pid = element(4, Trace),
MFA = element(5, Trace),
- io:format(Out, "(~p) spawn ~p as ~s (Timestamp: ~p)~n", [From,Pid,ffunc(MFA),TS]);
+ io:format(Device,
+ "(~p) spawn ~p as ~"++Modifier++"s (Timestamp: ~p)~n",
+ [From,Pid,ffunc(MFA,Modifier),TS]);
Op ->
- io:format(Out, "(~p) ~p ~s (Timestamp: ~p)~n", [From,Op,ftup(Trace,4,Size),TS])
+ io:format(Device, "(~p) ~p ~"++Modifier++"s (Timestamp: ~p)~n",
+ [From,Op,ftup(Trace,4,Size,Modifier),TS])
end,
- Out.
-
-
+ {Device,Modifier}.
%%% These f* functions returns non-flat strings
%% {M,F,[A1, A2, ..., AN]} -> "M:F(A1, A2, ..., AN)"
%% {M,F,A} -> "M:F/A"
-ffunc({M,F,Argl}) when is_list(Argl) ->
- io_lib:format("~p:~p(~s)", [M, F, fargs(Argl)]);
-ffunc({M,F,Arity}) ->
- io_lib:format("~p:~p/~p", [M,F,Arity]);
-ffunc(X) -> io_lib:format("~p", [X]).
+ffunc({M,F,Argl},Modifier) when is_list(Argl) ->
+ io_lib:format("~p:~"++Modifier++"p(~"++Modifier++"s)",
+ [M, F, fargs(Argl,Modifier)]);
+ffunc({M,F,Arity},Modifier) ->
+ io_lib:format("~p:~"++Modifier++"p/~p", [M,F,Arity]);
+ffunc(X,Modifier) -> io_lib:format("~"++Modifier++"p", [X]).
%% Integer -> "Integer"
%% [A1, A2, ..., AN] -> "A1, A2, ..., AN"
-fargs(Arity) when is_integer(Arity) -> integer_to_list(Arity);
-fargs([]) -> [];
-fargs([A]) -> io_lib:format("~p", [A]); %% last arg
-fargs([A|Args]) -> [io_lib:format("~p,", [A]) | fargs(Args)];
-fargs(A) -> io_lib:format("~p", [A]). % last or only arg
+fargs(Arity,_) when is_integer(Arity) -> integer_to_list(Arity);
+fargs([],_) -> [];
+fargs([A],Modifier) ->
+ io_lib:format("~"++Modifier++"p", [A]); %% last arg
+fargs([A|Args],Modifier) ->
+ [io_lib:format("~"++Modifier++"p,", [A]) | fargs(Args,Modifier)];
+fargs(A,Modifier) ->
+ io_lib:format("~"++Modifier++"p", [A]). % last or only arg
%% {A_1, A_2, ..., A_N} -> "A_Index A_Index+1 ... A_Size"
-ftup(Trace, Index, Index) ->
- io_lib:format("~p", [element(Index, Trace)]);
-ftup(Trace, Index, Size) ->
- [io_lib:format("~p ", [element(Index, Trace)])
- | ftup(Trace, Index+1, Size)].
-
+ftup(Trace, Index, Index, Modifier) ->
+ io_lib:format("~"++Modifier++"p", [element(Index, Trace)]);
+ftup(Trace, Index, Size, Modifier) ->
+ [io_lib:format("~"++Modifier++"p ", [element(Index, Trace)])
+ | ftup(Trace, Index+1, Size, Modifier)].
+out({_,_}=Out) ->
+ Out;
+out(Device) ->
+ {Device,modifier(Device)}.
+
+modifier() ->
+ modifier(group_leader()).
+modifier(Device) ->
+ Encoding =
+ case io:getopts(Device) of
+ List when is_list(List) ->
+ proplists:get_value(encoding,List,latin1);
+ _ ->
+ latin1
+ end,
+ encoding_to_modifier(Encoding).
+
+encoding_to_modifier(latin1) -> "";
+encoding_to_modifier(_) -> "t".
trace_process(Pid, [clear]) ->
trac(Pid, false, all());
@@ -1157,22 +1228,22 @@ all() ->
timestamp,monotonic_timestamp,strict_monotonic_timestamp,
arity,return_to,silent,running_procs,running_ports,exiting].
-display_info([Node|Nodes]) ->
+display_info([Node|Nodes],Modifier) ->
io:format("~nNode ~w:~n",[Node]),
io:format("~-12s ~-21s Trace ~n", ["Pid", "Initial call"]),
List = rpc:call(Node,?MODULE,get_info,[]),
- display_info1(List),
- display_info(Nodes);
-display_info([]) ->
+ display_info1(List,Modifier),
+ display_info(Nodes,Modifier);
+display_info([],_) ->
ok.
-display_info1([{Pid,Call,Flags}|T]) ->
- io:format("~-12s ~-21s ~s~n",
+display_info1([{Pid,Call,Flags}|T],Modifier) ->
+ io:format("~-12s ~-21"++Modifier++"s ~s~n",
[io_lib:format("~w",[Pid]),
- io_lib:format("~p", [Call]),
+ io_lib:format("~"++Modifier++"p", [Call]),
format_trace(Flags)]),
- display_info1(T);
-display_info1([]) ->
+ display_info1(T,Modifier);
+display_info1([],_) ->
ok.
get_info() ->
@@ -1304,7 +1375,8 @@ tc_loop([], Handler, HData) ->
tc_loop(Reader, Handler, HData) when is_function(Reader) ->
tc_loop(Reader(), Handler, HData);
tc_loop(Other, _Handler, _HData) ->
- io:format("~p:tc_loop ~p~n", [?MODULE, Other]),
+ Modifier = modifier(),
+ io:format("~p:tc_loop ~"++Modifier++"p~n", [?MODULE, Other]),
exit({unknown_term_from_reader, Other}).
diff --git a/lib/runtime_tools/src/dyntrace.erl b/lib/runtime_tools/src/dyntrace.erl
index 58c5a773c3..5fe62a46f6 100644
--- a/lib/runtime_tools/src/dyntrace.erl
+++ b/lib/runtime_tools/src/dyntrace.erl
@@ -61,8 +61,8 @@
enabled_garbage_collection/3,
enabled/3]).
-
-export([user_trace_i4s4/9]). % Know what you're doing!
+-compile(no_native).
-on_load(on_load/0).
-type probe_arg() :: integer() | iolist().
diff --git a/lib/runtime_tools/src/msacc.erl b/lib/runtime_tools/src/msacc.erl
index 4db5dbec91..0d9b2690e5 100644
--- a/lib/runtime_tools/src/msacc.erl
+++ b/lib/runtime_tools/src/msacc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2014-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/runtime_tools/src/observer_backend.erl b/lib/runtime_tools/src/observer_backend.erl
index cedb677178..d36af257ce 100644
--- a/lib/runtime_tools/src/observer_backend.erl
+++ b/lib/runtime_tools/src/observer_backend.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@
-export([vsn/0]).
%% observer stuff
--export([sys_info/0, get_port_list/0,
+-export([sys_info/0, get_port_list/0, procs_info/1,
get_table/3, get_table_list/2, fetch_stats/2]).
%% etop stuff
@@ -141,14 +141,59 @@ get_mnesia_loop(Parent, {Match, Cont}) ->
get_mnesia_loop(Parent, mnesia:select(Cont)).
get_port_list() ->
+ ExtraItems = [monitors,monitored_by,parallelism,locking,queue_size,memory],
[begin
[{port_id,P}|erlang:port_info(P)] ++
- case erlang:port_info(P,monitors) of
- undefined -> [];
- Monitors -> [Monitors]
- end
+ port_info(P,ExtraItems) ++
+ inet_port_extra(erlang:port_info(P, name), P)
end || P <- erlang:ports()].
+port_info(P,[Item|Items]) ->
+ case erlang:port_info(P,Item) of
+ undefined -> port_info(P,Items);
+ Value -> [Value|port_info(P,Items)]
+ end;
+port_info(_,[]) ->
+ [].
+
+inet_port_extra({_,Type},Port) when Type =:= "udp_inet";
+ Type =:= "tcp_inet";
+ Type =:= "sctp_inet" ->
+ Data =
+ case inet:getstat(Port) of
+ {ok, Stats} -> [{statistics, Stats}];
+ _ -> []
+ end ++
+ case inet:peername(Port) of
+ {ok, {RAddr,RPort}} when is_tuple(RAddr), is_integer(RPort) ->
+ [{remote_address,RAddr},{remote_port,RPort}];
+ {ok, RAddr} ->
+ [{remote_address,RAddr}];
+ {error, _} -> []
+ end ++
+ case inet:sockname(Port) of
+ {ok, {LAddr,LPort}} when is_tuple(LAddr), is_integer(LPort) ->
+ [{local_address,LAddr},{local_port,LPort}];
+ {ok, LAddr} ->
+ [{local_address,LAddr}];
+ {error, _} -> []
+ end ++
+ case inet:getopts(Port,
+ [active, broadcast, buffer, bind_to_device,
+ delay_send, deliver, dontroute, exit_on_close,
+ header, high_msgq_watermark, high_watermark,
+ ipv6_v6only, keepalive, linger, low_msgq_watermark,
+ low_watermark, mode, netns, nodelay, packet,
+ packet_size, priority, read_packets, recbuf,
+ reuseaddr, send_timeout, send_timeout_close,
+ show_econnreset, sndbuf, tos, tclass]) of
+ {ok, Opts} -> [{options, Opts}];
+ {error, _} -> []
+ end,
+ [{inet,Data}];
+inet_port_extra(_,_) ->
+ [].
+
get_table_list(ets, Opts) ->
HideUnread = proplists:get_value(unread_hidden, Opts, true),
HideSys = proplists:get_value(sys_hidden, Opts, true),
@@ -248,6 +293,23 @@ fetch_stats_loop(Parent, Time) ->
try erlang:memory() catch _:_ -> [] end},
fetch_stats_loop(Parent, Time)
end.
+
+%%
+%% Chunk sending process info to etop/observer
+%%
+procs_info(Collector) ->
+ All = processes(),
+ Send = fun Send (Pids) ->
+ try lists:split(10000, Pids) of
+ {First, Rest} ->
+ Collector ! {procs_info, self(), etop_collect(First, [])},
+ Send(Rest)
+ catch _:_ ->
+ Collector ! {procs_info, self(), etop_collect(Pids, [])}
+ end
+ end,
+ Send(All).
+
%%
%% etop backend
%%
@@ -269,13 +331,12 @@ etop_collect(Collector) ->
case SchedulerWallTime of
undefined ->
- spawn(fun() -> flag_holder_proc(Collector) end),
+ erlang:system_flag(scheduler_wall_time,true),
+ spawn(fun() -> flag_holder_proc(Collector) end),
ok;
_ ->
ok
- end,
-
- erlang:system_flag(scheduler_wall_time,true).
+ end.
flag_holder_proc(Collector) ->
Ref = erlang:monitor(process,Collector),
diff --git a/lib/runtime_tools/src/percept_profile.erl b/lib/runtime_tools/src/percept_profile.erl
deleted file mode 100644
index 1e8e913b80..0000000000
--- a/lib/runtime_tools/src/percept_profile.erl
+++ /dev/null
@@ -1,195 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-%% @doc Percept Collector
-%%
-%% This module provides the user interface for the percept data
-% collection (profiling).
-%%
-
--module(percept_profile).
--export([
- start/1,
- start/2,
- start/3,
- stop/0
- ]).
-
-
-%%==========================================================================
-%%
-%% Type definitions
-%%
-%%==========================================================================
-
-%% @type percept_option() = procs | ports | exclusive
-
--type percept_option() :: 'procs' | 'ports' | 'exclusive' | 'scheduler'.
-
-%%==========================================================================
-%%
-%% Interface functions
-%%
-%%==========================================================================
-
-%% @spec start(Filename::string()) -> {ok, Port} | {already_started, Port}
-%% @equiv start(Filename, [procs])
-
--spec start(Filename :: file:filename()) ->
- {'ok', port()} | {'already_started', port()}.
-
-start(Filename) ->
- profile_to_file(Filename, [procs]).
-
-%% @spec start(Filename::string(), [percept_option()]) -> {ok, Port} | {already_started, Port}
-%% Port = port()
-%% @doc Starts profiling with supplied options.
-%% All events are stored in the file given by Filename.
-%% An explicit call to stop/0 is needed to stop profiling.
-
--spec start(Filename :: file:filename(),
- Options :: [percept_option()]) ->
- {'ok', port()} | {'already_started', port()}.
-
-start(Filename, Options) ->
- profile_to_file(Filename, Options).
-
-%% @spec start(string(), MFA::mfa(), [percept_option()]) -> ok | {already_started, Port} | {error, not_started}
-%% Port = port()
-%% @doc Starts profiling at the entrypoint specified by the MFA. All events are collected,
-%% this means that processes outside the scope of the entry-point are also profiled.
-%% No explicit call to stop/0 is needed, the profiling stops when
-%% the entry function returns.
-
--spec start(Filename :: file:filename(),
- Entry :: {atom(), atom(), list()},
- Options :: [percept_option()]) ->
- 'ok' | {'already_started', port()} | {'error', 'not_started'}.
-
-start(Filename, {Module, Function, Args}, Options) ->
- case whereis(percept_port) of
- undefined ->
- {ok, _} = profile_to_file(Filename, Options),
- erlang:apply(Module, Function, Args),
- stop();
- Port ->
- {already_started, Port}
- end.
-
-deliver_all_trace() ->
- Tracee = self(),
- Tracer = spawn(fun() ->
- receive {Tracee, start} -> ok end,
- Ref = erlang:trace_delivered(Tracee),
- receive {trace_delivered, Tracee, Ref} -> Tracee ! {self(), ok} end
- end),
- erlang:trace(Tracee, true, [procs, {tracer, Tracer}]),
- Tracer ! {Tracee, start},
- receive {Tracer, ok} -> ok end,
- erlang:trace(Tracee, false, [procs]),
- ok.
-
-%% @spec stop() -> ok | {'error', 'not_started'}
-%% @doc Stops profiling.
-
--spec stop() -> 'ok' | {'error', 'not_started'}.
-
-stop() ->
- _ = erlang:system_profile(undefined, [runnable_ports, runnable_procs]),
- erlang:trace(all, false, [procs, ports, timestamp]),
- deliver_all_trace(),
- case whereis(percept_port) of
- undefined ->
- {error, not_started};
- Port ->
- erlang:port_command(Port, erlang:term_to_binary({profile_stop, erlang:timestamp()})),
- %% trace delivered?
- erlang:port_close(Port),
- ok
- end.
-
-%%==========================================================================
-%%
-%% Auxiliary functions
-%%
-%%==========================================================================
-
-profile_to_file(Filename, Opts) ->
- case whereis(percept_port) of
- undefined ->
- io:format("Starting profiling.~n", []),
-
- erlang:system_flag(multi_scheduling, block),
- Port = (dbg:trace_port(file, Filename))(),
- % Send start time
- erlang:port_command(Port, erlang:term_to_binary({profile_start, erlang:timestamp()})),
- erlang:system_flag(multi_scheduling, unblock),
-
- %% Register Port
- erlang:register(percept_port, Port),
- set_tracer(Port, Opts),
- {ok, Port};
- Port ->
- io:format("Profiling already started at port ~p.~n", [Port]),
- {already_started, Port}
- end.
-
-%% set_tracer
-
-set_tracer(Port, Opts) ->
- {TOpts, POpts} = parse_profile_options(Opts),
- % Setup profiling and tracing
- erlang:trace(all, true, [{tracer, Port}, timestamp | TOpts]),
- _ = erlang:system_profile(Port, POpts),
- ok.
-
-%% parse_profile_options
-
-parse_profile_options(Opts) ->
- parse_profile_options(Opts, {[],[]}).
-
-parse_profile_options([], Out) ->
- Out;
-parse_profile_options([Opt|Opts], {TOpts, POpts}) ->
- case Opt of
- procs ->
- parse_profile_options(Opts, {
- [procs | TOpts],
- [runnable_procs | POpts]
- });
- ports ->
- parse_profile_options(Opts, {
- [ports | TOpts],
- [runnable_ports | POpts]
- });
- scheduler ->
- parse_profile_options(Opts, {
- TOpts,
- [scheduler | POpts]
- });
- exclusive ->
- parse_profile_options(Opts, {
- TOpts,
- [exclusive | POpts]
- });
- _ ->
- parse_profile_options(Opts, {TOpts, POpts})
- end.
diff --git a/lib/runtime_tools/src/runtime_tools.app.src b/lib/runtime_tools/src/runtime_tools.app.src
index 690c61a4c3..449532e5c4 100644
--- a/lib/runtime_tools/src/runtime_tools.app.src
+++ b/lib/runtime_tools/src/runtime_tools.app.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,8 +20,8 @@
{application, runtime_tools,
[{description, "RUNTIME_TOOLS"},
{vsn, "%VSN%"},
- {modules, [appmon_info, dbg,observer_backend,percept_profile,
- runtime_tools,runtime_tools_sup,erts_alloc_config,
+ {modules, [appmon_info, dbg,observer_backend,runtime_tools,
+ runtime_tools_sup,erts_alloc_config,
ttb_autostart,dyntrace,system_information,
msacc]},
{registered, [runtime_tools_sup]},
@@ -30,5 +30,3 @@
{mod, {runtime_tools, []}},
{runtime_dependencies, ["stdlib-3.0","mnesia-4.12","kernel-5.0",
"erts-8.0"]}]}.
-
-
diff --git a/lib/runtime_tools/test/dbg_SUITE_data/dbg_SUITE.c b/lib/runtime_tools/test/dbg_SUITE_data/dbg_SUITE.c
index ecdee7e3a2..e402791607 100644
--- a/lib/runtime_tools/test/dbg_SUITE_data/dbg_SUITE.c
+++ b/lib/runtime_tools/test/dbg_SUITE_data/dbg_SUITE.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2009-2014. All Rights Reserved.
+ * Copyright Ericsson AB 2009-2016. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
* %CopyrightEnd%
*/
-#include "erl_nif.h"
+#include <erl_nif.h>
#include <stdio.h>
#include <string.h>
diff --git a/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat b/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat
index bdc510e838..a0e3806981 100644
--- a/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat
+++ b/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat
@@ -447,11 +447,6 @@
{native,false},
{compiler,"4.9.1"},
{md5,"a64e0220f855e6e97d53a9bc4f0a111b"}]},
- {dets_v8,
- [{loaded,false},
- {native,false},
- {compiler,"4.9.1"},
- {md5,"ebf2c94f62d180c3159b663ba2094189"}]},
{dets_v9,
[{loaded,false},
{native,false},
diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk
index b33f6f4721..5ee39a25fe 100644
--- a/lib/runtime_tools/vsn.mk
+++ b/lib/runtime_tools/vsn.mk
@@ -1 +1 @@
-RUNTIME_TOOLS_VSN = 1.10
+RUNTIME_TOOLS_VSN = 1.12
diff --git a/lib/sasl/doc/src/alarm_handler.xml b/lib/sasl/doc/src/alarm_handler.xml
index 8550a88b28..4160757164 100644
--- a/lib/sasl/doc/src/alarm_handler.xml
+++ b/lib/sasl/doc/src/alarm_handler.xml
@@ -54,7 +54,7 @@
format is defined by the user. For example, an event handler
for SNMP can be defined, together with an alarm Management
Information Base (MIB).</p>
- <p>The alarm handler is part of the <c>SASL</c> application.</p>
+ <p>The alarm handler is part of the SASL application.</p>
<p>When writing new event handlers for the alarm handler, the
following events must be handled:</p>
<taglist>
@@ -76,7 +76,7 @@
{NewHandler, Args})</c>. <c>NewHandler:init({Args, {alarm_handler,
Alarms}})</c> is called. For more details, see
<seealso marker="stdlib:gen_event"><c>gen_event(3)</c></seealso>
- in <c>STDLIB</c>.</p>
+ in STDLIB.</p>
</description>
<funcs>
diff --git a/lib/sasl/doc/src/appup.xml b/lib/sasl/doc/src/appup.xml
index 6fbdcb9f5b..a43a966dcb 100644
--- a/lib/sasl/doc/src/appup.xml
+++ b/lib/sasl/doc/src/appup.xml
@@ -362,12 +362,12 @@ point_of_no_return</pre>
system is restarted.</p>
<pre>
restart_new_emulator</pre>
- <p>This instruction is used when the application <c>ERTS</c>,
- <c>Kernel</c>, <c>STDLIB</c>, or <c>SASL</c> is
+ <p>This instruction is used when the application ERTS,
+ Kernel, STDLIB, or SASL is
upgraded. It shuts down the current emulator and starts a new
one. All processes are terminated gracefully, and the new
- version of <c>ERTS</c>, <c>Kernel</c>, <c>STDLIB</c>, and
- <c>SASL</c> are used when the emulator restarts.
+ version of ERTS, Kernel, STDLIB, and
+ SASL are used when the emulator restarts.
Only one <c>restart_new_emulator</c> instruction is allowed
in the <c>relup</c> file, and it must be placed first.
<seealso marker="systools#make_relup/3"><c>systools:make_relup/3,4</c></seealso>
@@ -385,7 +385,7 @@ restart_new_emulator</pre>
<warning>
<p>As stated earlier, instruction <c>restart_new_emulator</c>
causes the emulator to be restarted with new versions of
- <c>ERTS</c>, <c>Kernel</c>, <c>STDLIB</c>, and <c>SASL</c>.
+ ERTS>, Kernel, STDLIB, and SASL.
However, all other applications do at startup run their old
versions in this new emulator. This is usually no problem,
but every now and then incompatible changes occur to the
diff --git a/lib/sasl/doc/src/error_logging.xml b/lib/sasl/doc/src/error_logging.xml
index 8464a41ff9..4b2c960bbb 100644
--- a/lib/sasl/doc/src/error_logging.xml
+++ b/lib/sasl/doc/src/error_logging.xml
@@ -32,20 +32,20 @@
<rev>B</rev>
<file>error_logging.xml</file>
</header>
- <p>The <c>SASL</c> application introduces three types of reports:</p>
+ <p>The SASL application introduces three types of reports:</p>
<list type="bulleted">
<item>Supervisor report</item>
<item>Progress report</item>
<item>Crash report</item>
</list>
- <p>When the <c>SASL</c> application is started, it adds a handler that
+ <p>When the SASL application is started, it adds a handler that
formats and writes these reports, as specified in the configuration
- parameters for <c>SASL</c>, that is, the environment variables
- in the <c>SASL</c> application specification, which is found in the
- <c>.app</c> file of <c>SASL</c>. For details, see the
+ parameters for SASL, that is, the environment variables
+ in the SASL application specification, which is found in the
+ <c>.app</c> file of SASL. For details, see the
<seealso marker="sasl_app"><c>sasl(6)</c></seealso> application in the
Reference Manual and the <seealso marker="kernel:app"><c>app(4)</c></seealso>
- file in the <c>Kernel</c> Reference Manual.</p>
+ file in the Kernel Reference Manual.</p>
<section>
<title>Supervisor Report</title>
@@ -180,14 +180,14 @@
<p>The report browser is used to browse and format error reports
written by the error logger handler
<seealso marker="stdlib:log_mf_h"><c>log_mf_h</c></seealso>
- defined in <c>STDLIB</c>.</p>
+ defined in STDLIB.</p>
<p>The <c>log_mf_h</c> handler writes all reports to a
report logging directory, which is specified when
- configuring the <c>SASL</c> application.</p>
+ configuring the SASL application.</p>
<p>If the report browser is
used offline, the reports can be copied to another directory
specified when starting the browser. If no such directory
- is specified, the browser reads reports from the <c>SASL</c>
+ is specified, the browser reads reports from the SASL
<c>error_logger_mf_dir</c>.</p>
<section>
diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml
index dae73f8b23..bc35939d7e 100644
--- a/lib/sasl/doc/src/notes.xml
+++ b/lib/sasl/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,128 @@
</header>
<p>This document describes the changes made to the SASL application.</p>
+<section><title>SASL 3.0.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Documented default values for the 'mod' and
+ 'start_phases' fields in .app files were not allowed as
+ actual values in a .app file. This is now corrected.</p>
+ <p>
+ Own Id: OTP-14029</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Miscellaneous updates due to atoms containing
+ arbitrary Unicode characters. </p>
+ <p>
+ Own Id: OTP-14285</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SASL 3.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ When both options 'warnings_as_errors' and 'silent' were
+ given to systools:make_script or systools:make_relup, no
+ error reason would be returned if warnings occurred.
+ Instead only the atom 'error' was returned. This is now
+ corrected.</p>
+ <p>
+ Options 'warnings_as_errors' and 'no_warn_sasl' are now
+ also allowed for systools:make_tar.</p>
+ <p>
+ Own Id: OTP-14170</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SASL 3.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ <c>code:add_pathsa/1</c> and command line option
+ <c>-pa</c> both revert the given list of directories when
+ adding it at the beginning of the code path. This is now
+ documented.</p>
+ <p>
+ Own Id: OTP-13920 Aux Id: ERL-267 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SASL 3.0.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improved dirty scheduler support. A purge of a module can
+ now be performed without having to wait for completion of
+ all ongoing dirty NIF calls.</p>
+ <p>
+ Note that when enabling support for dirty schedulers, a
+ new purge strategy will as of ERTS version 8.1 be
+ enabled. This new strategy is not fully backwards
+ compatible with the strategy used by default. For more
+ information see the documentation of <seealso
+ marker="erts:erlang#check_process_code/3"><c>erlang:check_process_code/3</c></seealso>.</p>
+ <p>
+ Own Id: OTP-13808 Aux Id: OTP-13833 </p>
+ </item>
+ <item>
+ <p>
+ A new purge strategy has been introduced. The new
+ strategy will by default be disabled during the OTP 19
+ release, but will be the only strategy available as of
+ the OTP 20 release.</p>
+ <p>
+ The new strategy is slightly incompatible with the
+ strategy being used by default in OTP 19. Using the
+ default strategy, processes holding <c>fun</c>s that
+ refer to the module being purged either fail a soft
+ purge, or will be killed during a hard purge. The new
+ strategy completely ignores <c>fun</c>s. If <c>fun</c>s
+ referring to the code being purged exist, and are used
+ after a purge, an exception will be raised upon usage.
+ That is, the behavior will be exactly the same as the
+ case when a <c>fun</c> is received by a process after the
+ purge.</p>
+ <p>
+ The new strategy can optionally be enabled when building
+ OTP during OTP 19, and will automatically be enabled if
+ the runtime system is built with support for dirty
+ schedulers.</p>
+ <p>
+ For more information see the documentation of <seealso
+ marker="erts:erlang#check_process_code/3"><c>erlang:check_process_code/3</c></seealso>.</p>
+ <p>
+ Own Id: OTP-13833</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SASL 3.0</title>
<section><title>Improvements and New Features</title>
@@ -824,7 +946,7 @@
<list>
<item>
<p>Use an infinity timeout in all calls to
- <c>gen_server:call()</c> in the <c>sasl</c>
+ <c>gen_server:call()</c> in the SASL
application.</p>
<p>
Own Id: OTP-8506 Aux Id: seq11509 </p>
diff --git a/lib/sasl/doc/src/part.xml b/lib/sasl/doc/src/part.xml
index f531ed2dea..659710487e 100644
--- a/lib/sasl/doc/src/part.xml
+++ b/lib/sasl/doc/src/part.xml
@@ -30,7 +30,7 @@
<file>part.xml</file>
</header>
<description>
- <p>The System Architecture Support Libraries <c>SASL</c> application
+ <p>The System Architecture Support Libraries SASL application
provides support for alarm handling, release handling, and
related functions.</p>
</description>
diff --git a/lib/sasl/doc/src/rb.xml b/lib/sasl/doc/src/rb.xml
index 1ce19046eb..d5df4fd345 100644
--- a/lib/sasl/doc/src/rb.xml
+++ b/lib/sasl/doc/src/rb.xml
@@ -38,7 +38,7 @@
<p>The Report Browser (RB) tool is used to browse and
format error reports written by the error logger handler
<seealso marker="stdlib:log_mf_h"><c>log_mf_h</c></seealso>
- in <c>STDLIB</c>.</p>
+ in STDLIB.</p>
</description>
<funcs>
@@ -62,7 +62,7 @@
reports that match that filter.</p>
<p>The reports are matched using the
<seealso marker="stdlib:proplists"><c>proplists</c></seealso>
- module in <c>STDLIB</c>. The report must be a proplist
+ module in STDLIB. The report must be a proplist
to be matched against any of the filters.</p>
<p>If the filter has the form <c>{Key, RegExp, re}</c>, the
report must contain an element with key equal to <c>Key</c> and
@@ -102,7 +102,7 @@
</list>
<p>For a definition of valid regular expressions and options, see
the <seealso marker="stdlib:re"><c>re</c></seealso> module in
- <c>STDLIB</c> and in particular function <c>re:run/3</c>.</p>
+ STDLIB and in particular function <c>re:run/3</c>.</p>
<p>For details about data type <c>mp()</c>, see
<seealso marker="stdlib:re#type-mp"><c>re:mp()</c></seealso>.</p>
</desc>
diff --git a/lib/sasl/doc/src/ref_man.xml b/lib/sasl/doc/src/ref_man.xml
index 42045df5ec..78cf1eb26e 100644
--- a/lib/sasl/doc/src/ref_man.xml
+++ b/lib/sasl/doc/src/ref_man.xml
@@ -30,7 +30,7 @@
<file>application.xml</file>
</header>
<description>
- <p>The <c>SASL</c> application provides support for alarm handling,
+ <p>The SASL application provides support for alarm handling,
release handling, and related functions.</p>
</description>
<xi:include href="sasl_app.xml"/>
diff --git a/lib/sasl/doc/src/rel.xml b/lib/sasl/doc/src/rel.xml
index d6558c06b4..9356b2cd47 100644
--- a/lib/sasl/doc/src/rel.xml
+++ b/lib/sasl/doc/src/rel.xml
@@ -59,7 +59,7 @@
<tag><c>Vsn = string()</c></tag>
<item><p>Release version.</p></item>
<tag><c>EVsn = string()</c></tag>
- <item><p><c>ERTS</c> version the release is intended for.</p></item>
+ <item><p>ERTS version the release is intended for.</p></item>
<tag><c>Application = atom()</c></tag>
<item><p>Name of an application included in the release.</p></item>
<tag><c>AppVsn = string()</c></tag>
@@ -82,8 +82,8 @@
to the same value as in the application resource file.</p></item>
</taglist>
<note>
- <p>The list of applications must contain the <c>Kernel</c> and
- <c>STDLIB</c> applications.</p>
+ <p>The list of applications must contain the Kernel and
+ STDLIB applications.</p>
</note>
</section>
diff --git a/lib/sasl/doc/src/release_handler.xml b/lib/sasl/doc/src/release_handler.xml
index bcbc5f5339..8f073807fb 100644
--- a/lib/sasl/doc/src/release_handler.xml
+++ b/lib/sasl/doc/src/release_handler.xml
@@ -31,7 +31,7 @@
<module>release_handler</module>
<modulesummary>Unpacking and Installation of Release Packages</modulesummary>
<description>
- <p>The <em>release handler</em> process belongs to the <c>SASL</c>
+ <p>The <em>release handler</em> process belongs to the SASL
application, which is responsible for <em>release handling</em>,
that is, unpacking, installation, and removal of release packages.</p>
<p>An introduction to release handling and an example is provided in
@@ -44,7 +44,7 @@
directory of the previous version of the release, where
<c>$ROOT</c> is the installation root directory,
<seealso marker="kernel:code#root_dir/0"><c>code:root_dir()</c></seealso>.
- Another <c>releases</c> directory can be specified using the <c>SASL</c>
+ Another <c>releases</c> directory can be specified using the SASL
configuration parameter <c>releases_dir</c> or the OS environment
variable <c>RELDIR</c>. The release handler must have write access
to this directory to install the new release.
@@ -56,7 +56,7 @@
<item>A boot script, <c>Name.boot</c></item>
</list>
<p>The <c>.rel</c> file contains information about the release: its name,
- version, and which <c>ERTS</c> and application versions it uses.</p>
+ version, and which ERTS and application versions it uses.</p>
<p>A release package can also contain:</p>
<list type="bulleted">
<item>A release upgrade file, <c>relup</c></item>
@@ -115,7 +115,7 @@
<em>System Documentation</em>. In this case, the system
configuration file <c>sys.config</c> is mandatory.</p>
<p>The installation of a new release can restart the system. Which
- program to use is specified by the <c>SASL</c> configuration
+ program to use is specified by the SASL configuration
parameter <c>start_prg</c>, which defaults
to <c>$ROOT/bin/start</c>.</p>
<p>The emulator restart on Windows NT expects that the system is
@@ -132,7 +132,7 @@
is made permanent.</p>
<p>The release handler at a node running on a diskless machine,
or with a read-only file system, must be configured accordingly
- using the following <c>SASL</c> configuration parameters (for
+ using the following SASL configuration parameters (for
details, see <seealso marker="sasl_app">sasl(6)</seealso>):</p>
<taglist>
<tag><c>masters</c></tag>
@@ -287,7 +287,7 @@
returned, the emulator is restarted
before the upgrade instructions are executed. This
occurs if the emulator or any of the applications
- <c>Kernel</c>, <c>STDLIB</c>, or <c>SASL</c>
+ Kernel, STDLIB, or SASL
are updated. The new emulator version
and these core applications execute after the restart.
For all other applications the old versions are
@@ -310,13 +310,13 @@
<tag><c>code_change_timeout</c></tag>
<item><p>Defines the time-out
for all calls to
- <seealso marker="stdlib:sys#change_code/4"><c>stdlib:sys:change_code</c></seealso>.
+ <seealso marker="stdlib:sys#change_code/4"><c>sys:change_code</c></seealso>.
If no value is specified or <c>default</c> is specified, the
default value defined in <c>sys</c> is used.</p></item>
<tag><c>suspend_timeout</c></tag>
<item><p>Defines the time-out for
all calls to
- <seealso marker="stdlib:sys#suspend/1"><c>stdlib:sys:suspend</c></seealso>.
+ <seealso marker="stdlib:sys#suspend/1"><c>sys:suspend</c></seealso>.
If no value is specified, the values defined by the <c>Timeout</c>
parameter of the <c>upgrade</c> or <c>suspend</c> instructions are used.
If <c>default</c> is specified, the default value defined in
@@ -342,7 +342,7 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
=> {ok,NewVsn}</code>
<p>If <c>NewVsn</c> is installed with option
<c>{update_paths,true}</c>, then
- <seealso marker="kernel:code#lib_dir/1"><c>kernel:code:lib_dir(myapp)</c></seealso>
+ <seealso marker="kernel:code#lib_dir/1"><c>code:lib_dir(myapp)</c></seealso>
returns <c>/home/user/myapp-1.0</c>.</p></item>
</taglist>
<note>
@@ -801,7 +801,7 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
is an atom named from the Posix error codes, such as
<c>enoent</c>, <c>eacces</c>, or <c>eisdir</c>. See
<seealso marker="kernel:file"><c>file(3)</c></seealso>
- in <c>Kernel</c>.</p></item>
+ in Kernel.</p></item>
<tag><c>Posix</c></tag>
<item><p>Some file operation failed, as for the previous item in
the list.</p></item>
diff --git a/lib/sasl/doc/src/sasl_app.xml b/lib/sasl/doc/src/sasl_app.xml
index 52f449c2a8..0576397f9b 100644
--- a/lib/sasl/doc/src/sasl_app.xml
+++ b/lib/sasl/doc/src/sasl_app.xml
@@ -31,17 +31,17 @@
<app>sasl</app>
<appsummary>The SASL application</appsummary>
<description>
- <p>The <c>SASL</c> application provides the following services:</p>
+ <p>The SASL application provides the following services:</p>
<list type="bulleted">
<item><c>alarm_handler</c></item>
<item><c>rb</c></item>
<item><c>release_handler</c></item>
<item><c>systools</c></item>
</list>
- <p>The <c>SASL</c> application also includes <c>error_logger</c> event
- handlers for formatting <c>SASL</c> error and crash reports.</p>
+ <p>The SASL application also includes <c>error_logger</c> event
+ handlers for formatting SASL error and crash reports.</p>
<note>
- <p>The <c>SASL</c> application in OTP has nothing to do with
+ <p>The SASL application in OTP has nothing to do with
"Simple Authentication and Security Layer" (RFC 4422).</p>
</note>
</description>
@@ -49,7 +49,7 @@
<section>
<title>Error Logger Event Handlers</title>
<p>The following error logger event handlers are used by
- the <c>SASL</c> application.</p>
+ the SASL application.</p>
<taglist>
<tag><c>sasl_report_tty_h</c></tag>
<item>
@@ -57,7 +57,7 @@
reports</em>, and <em>progress reports</em> to <c>stdio</c>.
This error logger event handler uses
<seealso marker="kernel:kernel_app#error_logger_format_depth">error_logger_format_depth</seealso>
- in the <c>Kernel</c> application to limit how much detail is
+ in the Kernel application to limit how much detail is
printed in crash and supervisor reports.</p>
</item>
<tag><c>sasl_report_file_h</c></tag>
@@ -66,7 +66,7 @@
report</em>, and <em>progress report</em> to a single file.
This error logger event handler uses
<seealso marker="kernel:kernel_app#error_logger_format_depth">error_logger_format_depth</seealso>
- in the <c>Kernel</c> application to limit the details
+ in the Kernel application to limit the details
printed in crash and supervisor reports.</p>
</item>
<tag><c>log_mf_h</c></tag>
@@ -75,9 +75,9 @@
error logger to disk. Multiple files and log rotation are
used. For efficiency reasons, each event is written as a
binary. For more information about this handler,
- see <seealso marker="stdlib:log_mf_h">the <c>STDLIB</c> Reference
+ see <seealso marker="stdlib:log_mf_h">the STDLIB Reference
Manual</seealso>.</p>
- <p>To activate this event handler, three <c>SASL</c>
+ <p>To activate this event handler, three SASL
configuration parameters must be set,
<c>error_logger_mf_dir</c>, <c>error_logger_mf_maxbytes</c>,
and <c>error_logger_mf_maxfiles</c>. The next section provides
@@ -88,9 +88,9 @@
<section>
<title>Configuration</title>
- <p>The following configuration parameters are defined for the <c>SASL</c>
+ <p>The following configuration parameters are defined for the SASL
application. For more information about configuration parameters, see
- <seealso marker="kernel:app"><c>app(4)</c></seealso> in <c>Kernel</c>.</p>
+ <seealso marker="kernel:app"><c>app(4)</c></seealso> in Kernel.</p>
<p>All configuration parameters are optional.</p>
<taglist>
<tag><c><![CDATA[sasl_error_logger = Value ]]></c></tag>
@@ -112,7 +112,7 @@
Use <c>[append]</c> to have the <c>FileName</c> open in append mode.
<c>FileName</c> is a string.</p></item>
<tag><c>false</c></tag>
- <item><p>No <c>SASL</c> error logger handler is installed.</p></item>
+ <item><p>No SASL error logger handler is installed.</p></item>
</taglist>
</item>
<tag><c><![CDATA[errlog_type = error | progress | all ]]></c></tag>
diff --git a/lib/sasl/doc/src/sasl_intro.xml b/lib/sasl/doc/src/sasl_intro.xml
index b71dafb192..f74a7c1db8 100644
--- a/lib/sasl/doc/src/sasl_intro.xml
+++ b/lib/sasl/doc/src/sasl_intro.xml
@@ -32,7 +32,7 @@
<section>
<title>Scope</title>
- <p>The <c>SASL</c> application provides support for:</p>
+ <p>The SASL application provides support for:</p>
<list type="bulleted">
<item>Error logging</item>
<item>Alarm handling</item>
diff --git a/lib/sasl/doc/src/script.xml b/lib/sasl/doc/src/script.xml
index 8ed132354d..b40ff28179 100644
--- a/lib/sasl/doc/src/script.xml
+++ b/lib/sasl/doc/src/script.xml
@@ -88,7 +88,7 @@
follows:</p>
<list type="bulleted">
<item><c>-pa Dir1 Dir2 ... DirN</c> adds the directories
- <c>Dir1, Dir2, ..., DirN</c> to the front of the initial
+ <c>DirN, DirN-1, ..., Dir2, Dir1</c> to the front of the initial
load path.</item>
<item><c>-pz Dir1 Dir2 ... DirN</c> adds the directories
<c>Dir1, Dir2, ..., DirN</c> to the end of the initial
diff --git a/lib/sasl/doc/src/systools.xml b/lib/sasl/doc/src/systools.xml
index 7446762de4..e7c3c499da 100644
--- a/lib/sasl/doc/src/systools.xml
+++ b/lib/sasl/doc/src/systools.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1996</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -85,7 +85,7 @@
</item>
<item>
<p>If the emulator needs to be restarted after upgrading or
- downgrading, that is, if the <c>ERTS</c> version differs
+ downgrading, that is, if the ERTS version differs
between <c>Name.rel</c> and <c>Name2.rel</c></p>
</item>
</list>
@@ -201,10 +201,10 @@
between the applications. Where there are no dependencies,
the order in the <c>.rel</c> file is kept.</p>
<p>The function fails if the mandatory
- applications <c>Kernel</c> and <c>STDLIB</c> are not
+ applications Kernel and STDLIB are not
included in the <c>.rel</c> file and have start
type <c>permanent</c> (which is default).</p>
- <p>If <c>SASL</c> is not included as an application in
+ <p>If SASL is not included as an application in
the <c>.rel</c> file, a warning is issued because such a
release cannot be used in an upgrade. To turn off this
warning, add option <c>no_warn_sasl</c>.</p>
@@ -268,7 +268,7 @@
<fsummary>Creates a release package.</fsummary>
<type>
<v>Name = string()</v>
- <v>Opt = {dirs,[IncDir]} | {path,[Dir]} | {variables,[Var]} | {var_tar,VarTar} | {erts,Dir} | src_tests | exref | {exref,[App]} | silent | {outdir,Dir}</v>
+ <v>Opt = {dirs,[IncDir]} | {path,[Dir]} | {variables,[Var]} | {var_tar,VarTar} | {erts,Dir} | src_tests | exref | {exref,[App]} | silent | {outdir,Dir} | | no_warn_sasl | warnings_as_errors</v>
<v>&nbsp;Dir = string()</v>
<v>&nbsp;IncDir = src | include | atom()</v>
<v>&nbsp;Var = {VarName,PreFix}</v>
@@ -297,6 +297,10 @@
directory unless <c>Name</c> contains a path. If option
<c>{outdir,Dir}</c> is specified, it is located in <c>Dir</c>
instead.</p>
+ <p>If SASL is not included as an application in
+ the <c>.rel</c> file, a warning is issued because such a
+ release cannot be used in an upgrade. To turn off this
+ warning, add option <c>no_warn_sasl</c>.</p>
<p>By default, the release package contains the directories
<c>lib/App-Vsn/ebin</c> and <c>lib/App-Vsn/priv</c> for each
included application. If more directories are to be included,
diff --git a/lib/sasl/src/format_lib_supp.erl b/lib/sasl/src/format_lib_supp.erl
index 0b474a0232..80dcdc91da 100644
--- a/lib/sasl/src/format_lib_supp.erl
+++ b/lib/sasl/src/format_lib_supp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,15 +25,12 @@
%%% tools.
%%% The main parts are:
%%% 1) print_info. Prints information tagged by 'header', 'data',
-%%% 'table', 'items' and 'newline'.
+%%% 'items' and 'newline'.
%%%---------------------------------------------------------------------
%% intermodule exports
-export([print_info/2, print_info/3]).
-%% exports for use within module
--export([maxcol/2]).
-
%%---------------------------------------------------------------------
%% Format is an ordered list of:
%% {header, HeaderString}
@@ -42,10 +39,6 @@
%% (if possible); 'Key: Value'.
%% Elements in the list may also be single terms, which are
%% printed as they are.
-%% {table, {TableName, ColumnNames, Columns}}
-%% ColumnNames is a tuple of names for the columns, and
-%% Columns is a list, where each element is a tuple of
-%% data for that column.
%% {items, {Name, Items}}
%% Items is a list of KeyValue_tuples. Will be printed as:
%% 'Name:
@@ -77,9 +70,6 @@ print_format(Device, _Line, []) ->
print_format(Device, Line, [{data, Data}|T]) ->
print_data(Device, Line, Data),
print_format(Device, Line, T);
-print_format(Device, Line, [{table, Table}|T]) ->
- _ = print_table(Device, Line, Table),
- print_format(Device, Line, T);
print_format(Device, Line, [{items, Items}|T]) ->
print_items(Device, Line, Items),
print_format(Device, Line, T);
@@ -94,51 +84,49 @@ print_data(Device, Line, [{Key, Value}|T]) ->
print_one_line(Device, Line, Key, Value),
print_data(Device, Line, T);
print_data(Device, Line, [Value|T]) ->
- io:format(Device, "~p~n", [Value]),
+ Modifier = misc_supp:modifier(Device),
+ io:format(Device, "~"++Modifier++"p~n", [Value]),
print_data(Device, Line, T).
+
print_items(Device, Line, {Name, Items}) ->
print_items(Device, Line, Name, Items).
-print_table(Device, Line, {TableName, ColumnNames, Columns}) ->
- print_table(Device, Line, TableName, ColumnNames, Columns).
-
print_newlines(_Device, 0) -> ok;
print_newlines(Device, N) when N > 0 ->
io:format(Device, '~n', []),
print_newlines(Device, N-1).
print_one_line(Device, Line, Key, Value) ->
- StrKey = term_to_string(Key),
+ Modifier = misc_supp:modifier(Device),
+ StrKey = term_to_string(Key,Modifier),
KeyLen = lists:min([length(StrKey), Line]),
ValueLen = Line - KeyLen,
- Format1 = lists:concat(["~-", KeyLen, s]),
- Format2 = lists:concat(["~", ValueLen, "s~n"]),
+ Format1 = lists:concat(["~-", KeyLen, Modifier, "s"]),
+ Format2 = lists:concat(["~", ValueLen, Modifier, "s~n"]),
io:format(Device, Format1, [StrKey]),
- Try = term_to_string(Value),
+ Try = term_to_string(Value,Modifier),
Length = length(Try),
if
Length < ValueLen ->
io:format(Device, Format2, [Try]);
true ->
io:format(Device, "~n ", []),
- Format3 = lists:concat(["~", Line, ".9p~n"]),
+ Format3 = lists:concat(["~", Line, ".9", Modifier, "p~n"]),
io:format(Device, Format3, [Value])
end.
-term_to_string(Value) ->
- lists:flatten(io_lib:format(get_format(Value), [Value])).
+term_to_string(Value,Modifier) ->
+ lists:flatten(io_lib:format(get_format(Value,Modifier), [Value])).
-get_format(Value) ->
- case misc_supp:is_string(Value) of
- true -> "~s";
- false -> "~p"
+get_format([],_) ->
+ "~p";
+get_format(Value,Modifier) ->
+ case io_lib:printable_list(Value) of
+ true -> "~"++Modifier++"s";
+ false -> "~"++Modifier++"p"
end.
-make_list(0, _Elem) -> [];
-make_list(N, Elem) -> [Elem|make_list(N-1, Elem)].
-
-
%%-----------------------------------------------------------------
%% Items
%%-----------------------------------------------------------------
@@ -150,76 +138,3 @@ print_item_elements(_Device, _Line, []) -> ok;
print_item_elements(Device, Line, [{Key, Value}|T]) ->
print_one_line(Device, Line, lists:concat([" ", Key]), Value),
print_item_elements(Device, Line, T).
-
-%%-----------------------------------------------------------------
-%% Table handling
-%%-----------------------------------------------------------------
-extra_space_between_columns() -> 3.
-
-find_max_col([Row | T], ColumnSizes) ->
- find_max_col(T, misc_supp:multi_map({format_lib_supp, maxcol},
- [Row, ColumnSizes]));
-
-find_max_col([], ColumnSizes) -> ColumnSizes.
-
-maxcol(Term, OldMax) ->
- lists:max([length(term_to_string(Term)), OldMax]).
-
-make_column_format(With) ->
- lists:concat(["~", With + extra_space_between_columns(), s]).
-
-is_correct_column_length(_Length, []) -> true;
-is_correct_column_length(Length, [Tuple|T]) ->
- case size(Tuple) of
- Length -> is_correct_column_length(Length, T);
- _ -> false
- end;
-is_correct_column_length(_, _) -> false.
-
-print_table(Device, Line, TableName, _TupleOfColumnNames, []) ->
- print_one_line(Device, Line, TableName, "<empty table>"),
- io:format(Device, "~n", []);
-
-print_table(Device, Line, TableName, TupleOfColumnNames, ListOfTuples)
- when is_list(ListOfTuples), is_tuple(TupleOfColumnNames) ->
- case is_correct_column_length(size(TupleOfColumnNames),
- ListOfTuples) of
- true ->
- print_one_line(Device, Line, TableName, " "),
- ListOfColumnNames = tuple_to_list(TupleOfColumnNames),
- ListOfLists = lists:map(fun(Tuple) ->
- tuple_to_list(Tuple)
- end,
- ListOfTuples),
- ColWidths = find_max_col([ListOfColumnNames |
- ListOfLists],
- make_list(length(ListOfColumnNames),0)),
- Format = lists:flatten([lists:map(fun(CW) ->
- make_column_format(CW)
- end,
- ColWidths), "~n"]),
- io:format(Device, Format, ListOfColumnNames),
- io:format(Device,
- lists:concat(['~', extra_space_between_columns(),
- 'c', '~', lists:sum(ColWidths)
- + (length(ColWidths) - 1)
- * extra_space_between_columns(),
- 'c~n']), [$ , $-]),
- lists:foreach(fun(List) ->
- print_row(List, Device, Format)
- end,
- ListOfLists),
- io:format(Device, '~n', []),
- true;
- false ->
- {error, {'a tuple has wrong size',
- {TableName, TupleOfColumnNames, ListOfTuples}}}
- end.
-
-%%--------------------------------------------------
-%% Device MUST be 2nd arg because of extraarg ni foreach...
-%%--------------------------------------------------
-print_row(Row, Device, Format) ->
- io:format(Device, Format,
- lists:map(fun(Term) -> term_to_string(Term) end,
- Row)).
diff --git a/lib/sasl/src/misc_supp.erl b/lib/sasl/src/misc_supp.erl
index 093b337a2c..cbbcba0def 100644
--- a/lib/sasl/src/misc_supp.erl
+++ b/lib/sasl/src/misc_supp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@
%%%---------------------------------------------------------------------
-export([format_pdict/3, format_tuples/2, assq/2, passq/2, is_string/1,
- multi_map/2]).
+ multi_map/2, modifier/1]).
%%-----------------------------------------------------------------
%% Uses format_tuples to format the data in process dictionary.
@@ -105,3 +105,19 @@ multi_map(Func, ListOfLists) ->
[apply(Func, lists:map(fun(List) -> hd(List) end, ListOfLists)) |
multi_map(Func,
lists:map(fun(List) -> tl(List) end, ListOfLists))].
+
+%%%-----------------------------------------------------------------
+%%% Check encoding of the given device and return "t" if this format
+%%% modifier should be used.
+modifier(Device) ->
+ Encoding =
+ case io:getopts(Device) of
+ List when is_list(List) ->
+ proplists:get_value(encoding,List,latin1);
+ _ ->
+ latin1
+ end,
+ encoding_to_modifier(Encoding).
+
+encoding_to_modifier(latin1) -> "";
+encoding_to_modifier(_) -> "t".
diff --git a/lib/sasl/src/rb.erl b/lib/sasl/src/rb.erl
index 79df150b41..6595d29a9c 100644
--- a/lib/sasl/src/rb.erl
+++ b/lib/sasl/src/rb.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -273,7 +273,7 @@ code_change(_OldVsn, State, _Extra) ->
open_log_file(standard_io) -> standard_io;
open_log_file(Fd) when is_atom(Fd),Fd=/=standard_error ->
case whereis(Fd) of
- undefined -> io:format("rb: Registered name not found '~s'.~n",
+ undefined -> io:format("rb: Registered name not found '~ts'.~n",
[Fd]),
io:format("rb: Using standard_io~n"),
open_log_file(standard_io);
@@ -281,10 +281,10 @@ open_log_file(Fd) when is_atom(Fd),Fd=/=standard_error ->
end;
open_log_file(Fd) when is_pid(Fd)-> Fd;
open_log_file(FileName) when is_list(FileName) ->
- case file:open(FileName, [write,append]) of
+ case file:open(FileName, [write,append,{encoding,utf8}]) of
{ok, Fd} -> Fd;
Error ->
- io:format("rb: Cannot open file '~s' (~w).~n",
+ io:format("rb: Cannot open file '~ts' (~w).~n",
[FileName, Error]),
io:format("rb: Using standard_io~n"),
standard_io
@@ -419,8 +419,8 @@ read_reports(No, Fd, Fname, Max, Type) ->
add_report_data(NewRes, No, Fname);
{error, [Problem | Res]} ->
_ = file:close(Fd),
- io:format("Error: ~p~n",[Problem]),
- io:format("Salvaged ~p entries from corrupt report file ~s...~n",
+ io:format("Error: ~tp~n",[Problem]),
+ io:format("Salvaged ~p entries from corrupt report file ~ts...~n",
[length(Res),Fname]),
NewRes =
if
@@ -431,7 +431,7 @@ read_reports(No, Fd, Fname, Max, Type) ->
end,
add_report_data(NewRes, No, Fname);
Else ->
- io:format("err ~p~n", [Else]),
+ io:format("err ~tp~n", [Else]),
[{No, unknown, "Can't read reports from file " ++ Fname,
"???", Fname, 0}]
end.
@@ -530,21 +530,18 @@ get_short_descr({{Date, Time}, {error_report, Pid, {_, crash_report, Rep}}}) ->
{value, {_Key, N}} -> N;
_ -> Pid
end,
- NameStr = lists:flatten(io_lib:format("~w", [Name])),
- {NameStr, date_str(Date, Time)};
+ {Name, date_str(Date, Time)};
get_short_descr({{Date, Time}, {error_report, Pid, {_, supervisor_report,Rep}}}) ->
Name =
case lists:keysearch(supervisor, 1, Rep) of
{value, {_Key, N}} when is_atom(N) -> N;
_ -> Pid
end,
- NameStr = lists:flatten(io_lib:format("~w", [Name])),
- {NameStr, date_str(Date,Time)};
+ {Name, date_str(Date,Time)};
get_short_descr({{Date, Time}, {_Type, Pid, _}}) ->
- NameStr = lists:flatten(io_lib:format("~w", [Pid])),
- {NameStr, date_str(Date,Time)};
+ {Pid, date_str(Date,Time)};
get_short_descr(_) ->
- {"???", "???"}.
+ {'???', "???"}.
date_str({Y,Mo,D}=Date,{H,Mi,S}=Time) ->
case application:get_env(sasl,utc_log) of
@@ -571,53 +568,57 @@ local_time_to_universal_time({Date,Time}) ->
end.
-print_list(Fd, Data, Type) ->
+print_list(Fd, Data0, Type) ->
+ Modifier = misc_supp:modifier(Fd),
Header = {"No", "Type", "Process", "Date Time"},
- Width = find_width([Header | Data], 0)+1,
- DateWidth = find_date_width([Header | Data], 0) +1,
- Format = lists:concat(["~4s~20s ~", Width, "s~20s~n"]),
+ {DescrWidth,DateWidth,Data} = find_widths(Data0, Modifier, 7, 13, []),
+ Format = lists:concat(["~4s~20s ~", DescrWidth, "s~20s~n"]),
io:format(Fd, Format, tuple_to_list(Header)),
io:format(Fd, Format, ["==", "====", "=======", "==== ===="]),
- print_list(Fd, Data, Type, Width, DateWidth).
-print_list(_, [], _, _, _) -> true;
-print_list(Fd, [H|T], Type, Width, DateWidth) ->
- print_one_report(Fd, H, Type, Width, DateWidth),
- print_list(Fd, T, Type, Width, DateWidth).
-
-find_width([], Width) -> Width;
-find_width([H|T], Width) ->
- Try = length(element(3, H)),
- if
- Try > Width -> find_width(T, Try);
- true -> find_width(T, Width)
- end.
-find_date_width([], Width) -> Width;
-find_date_width([H|T], Width) ->
- Try = length(element(4, H)),
- if
- Try > Width -> find_date_width(T, Try);
- true -> find_date_width(T, Width)
- end.
+ print_list(Fd, Data, Type, DescrWidth, DateWidth, Modifier).
+print_list(_, [], _, _, _, _) -> true;
+print_list(Fd, [H|T], Type, Width, DateWidth, Modifier) ->
+ print_one_report(Fd, H, Type, Width, DateWidth, Modifier),
+ print_list(Fd, T, Type, Width, DateWidth, Modifier).
+
+
+find_widths([], _Modifier, DescrWidth, DateWidth, Data) ->
+ {DescrWidth+1, DateWidth+1, lists:reverse(Data)};
+find_widths([H|T], Modifier, DescrWidth, DateWidth, Data) ->
+ DescrTerm = element(3,H),
+ Descr = lists:flatten(io_lib:format("~"++Modifier++"w", [DescrTerm])),
+ DescrTry = length(Descr),
+ NewDescrWidth =
+ if
+ DescrTry > DescrWidth -> DescrTry;
+ true -> DescrWidth
+ end,
+ DateTry = length(element(4, H)),
+ NewDateWitdh =
+ if
+ DateTry > DateWidth -> DateTry;
+ true -> DateWidth
+ end,
+ NewH = setelement(3,H,Descr),
+ find_widths(T, Modifier, NewDescrWidth, NewDateWitdh, [NewH|Data]).
print_one_report(Fd, {No, RealType, ShortDescr, Date, _Fname, _FilePos},
WantedType,
- Width, DateWidth) ->
+ Width, DateWidth, Modifier) ->
if
WantedType == all ->
print_short_descr(Fd, No, RealType, ShortDescr, Date, Width,
- DateWidth);
+ DateWidth, Modifier);
WantedType == RealType ->
print_short_descr(Fd, No, RealType, ShortDescr, Date, Width,
- DateWidth);
+ DateWidth, Modifier);
true -> ok
end.
-print_short_descr(Fd, No, Type, ShortDescr, Date, Width, DateWidth) ->
- Format = lists:concat(["~4w~20w ~", Width, "s~", DateWidth,"s~n"]),
- io:format(Fd, Format, [No,
- Type,
- io_lib:format("~s", [ShortDescr]),
- Date]).
+print_short_descr(Fd, No, Type, ShortDescr, Date, Width, DateWidth, Modifier) ->
+ Format = lists:concat(["~4w~20", Modifier, "w ~", Width, Modifier, "s~",
+ DateWidth, "s~n"]),
+ io:format(Fd, Format, [No, Type, ShortDescr, Date]).
print_report_by_num(Dir, Data, Number, Device, Abort, Log) ->
{_,Device1} = print_report(Dir, Data, Number, Device, Abort, Log),
@@ -658,7 +659,7 @@ print_report(Dir, Data, Number, Device, Abort, Log) ->
{ok, Fd} ->
read_rep(Fd, FilePosition, Device, Abort, Log);
_ ->
- io:format("rb: can't open file ~p~n", [Fname]),
+ io:format("rb: can't open file ~tp~n", [Fname]),
{proceed,Device}
end;
no_report ->
@@ -691,14 +692,14 @@ print_grep_report(Dir, Data, Number, Device, RegExp, Abort, Log) ->
{ok, Fd} when is_pid(Fd) ->
check_rep(Fd, FilePosition, Device, RegExp, Number, Abort, Log);
_ ->
- io:format("rb: can't open file ~p~n", [Fname]),
+ io:format("rb: can't open file ~tp~n", [Fname]),
{proceed,Device}
end.
check_rep(Fd, FilePosition, Device, RegExp, Number, Abort, Log) ->
case read_rep_msg(Fd, FilePosition) of
{Date, Msg} ->
- MsgStr = lists:flatten(io_lib:format("~p",[Msg])),
+ MsgStr = lists:flatten(io_lib:format("~tp",[Msg])),
case run_re(MsgStr, RegExp) of
match ->
io:format("Found match in report number ~w~n", [Number]),
@@ -722,7 +723,7 @@ run_re(Subject, Regexp) ->
run_re(Subject, Regexp, []).
run_re(Subject, Regexp, Options) ->
- case re:run(Subject, Regexp, Options) of
+ case re:run(Subject, Regexp, [unicode|Options--[unicode]]) of
nomatch ->
nomatch;
_ ->
@@ -748,7 +749,7 @@ filter_report(Dir, Data, Filters, Number, Device, Abort, Log) ->
{ok, Fd} ->
filter_rep(Filters, Fd, FilePosition, Device, Abort, Log);
_ ->
- io:format("rb: can't open file ~p~n", [Fname]),
+ io:format("rb: can't open file ~tp~n", [Fname]),
{proceed,Device}
end;
no_report ->
@@ -800,7 +801,7 @@ filter_report([{Key, RegExp, re}|T], Msg) ->
undefined ->
false;
Value ->
- Subject = lists:flatten(io_lib:format("~p",[Value])),
+ Subject = lists:flatten(io_lib:format("~tp",[Value])),
case run_re(Subject, RegExp) of
match ->
filter_report(T, Msg);
@@ -812,7 +813,7 @@ filter_report([{Key, RegExp, re, no}|T], Msg) ->
undefined ->
true;
Value ->
- Subject = lists:flatten(io_lib:format("~p",[Value])),
+ Subject = lists:flatten(io_lib:format("~tp",[Value])),
case run_re(Subject, RegExp) of
match -> false;
_ -> filter_report(T, Msg)
@@ -890,7 +891,7 @@ read_rep(Fd, FilePosition, Device, Abort, Log) ->
handle_bad_form(Date, Msg, Device, Abort, Log) ->
io:format("rb: ERROR! A report on bad form was encountered. " ++
"It can not be printed to the log.~n~n"),
- io:format("Details:~n~p ~p~n~n", [Date,Msg]),
+ io:format("Details:~n~p ~tp~n~n", [Date,Msg]),
case {Abort,Device,open_log_file(Log)} of
{true,standard_io,standard_io} ->
io:format("rb: Logging aborted.~n"),
@@ -899,7 +900,7 @@ handle_bad_form(Date, Msg, Device, Abort, Log) ->
io:format("rb: Logging resumed...~n~n"),
{proceed,Device};
{_,_,standard_io} ->
- io:format("rb: Can not reopen ~p. Logging aborted.~n", [Log]),
+ io:format("rb: Can not reopen ~tp. Logging aborted.~n", [Log]),
{abort,Device};
{true,_,NewDevice} ->
io:format(NewDevice,
diff --git a/lib/sasl/src/rb_format_supp.erl b/lib/sasl/src/rb_format_supp.erl
index 0004d85af4..1eda43dae4 100644
--- a/lib/sasl/src/rb_format_supp.erl
+++ b/lib/sasl/src/rb_format_supp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -94,13 +94,15 @@ print(Date, Report, Device) ->
[{header, Header}]),
io:format(Device, Format, Args);
{Type, _GL, TypeReport} ->
- io:format(Device, "~nInfo type <~w> ~s~n",
+ Modifier = misc_supp:modifier(Device),
+ io:format(Device, "~nInfo type <~"++Modifier++"w> ~s~n",
[Type, Date]),
- io:format(Device, "~p", [TypeReport]);
+ io:format(Device, "~"++Modifier++"p", [TypeReport]);
_ ->
+ Modifier = misc_supp:modifier(Device),
io:format("~nPrinting info of unknown type... ~s~n",
[Date]),
- io:format(Device, "~p", [Report])
+ io:format(Device, "~"++Modifier++"p", [Report])
% end
end.
diff --git a/lib/sasl/src/release_handler.erl b/lib/sasl/src/release_handler.erl
index 1fcc9a0288..1f3c6877d5 100644
--- a/lib/sasl/src/release_handler.erl
+++ b/lib/sasl/src/release_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -640,8 +640,8 @@ handle_call({install_release, Vsn, ErrorAction, Opts}, From, S) ->
{noreply, NS};
{'EXIT', Reason} ->
io:format("release_handler:"
- "install_release(Vsn=~p Opts=~p) failed, "
- "Reason=~p~n", [Vsn, Opts, Reason]),
+ "install_release(Vsn=~tp Opts=~tp) failed, "
+ "Reason=~tp~n", [Vsn, Opts, Reason]),
gen_server:reply(From, {error, Reason}),
case ErrorAction of
restart ->
@@ -831,7 +831,7 @@ do_unpack_release(Root, RelDir, ReleaseName, Releases) ->
Tar = filename:join(RelDir, ReleaseName ++ ".tar.gz"),
do_check_file(Tar, regular),
Rel = ReleaseName ++ ".rel",
- extract_rel_file(filename:join("releases", Rel), Tar, Root),
+ _ = extract_rel_file(filename:join("releases", Rel), Tar, Root),
RelFile = filename:join(RelDir, Rel),
Release = check_rel(Root, RelFile, false),
#release{vsn = Vsn} = Release,
@@ -1124,7 +1124,7 @@ new_emulator_make_hybrid_config(CurrentVsn,ToVsn,TmpVsn,RelDir,Masters) ->
{ok,[FC]} ->
FC;
{error,Error1} ->
- io:format("Warning: ~w can not read ~p: ~p~n",
+ io:format("Warning: ~w can not read ~tp: ~tp~n",
[?MODULE,FromFile,Error1]),
[]
end,
@@ -1134,7 +1134,7 @@ new_emulator_make_hybrid_config(CurrentVsn,ToVsn,TmpVsn,RelDir,Masters) ->
{ok,[ToConfig]} ->
[lists:keyfind(App,1,ToConfig) || App <- [kernel,stdlib,sasl]];
{error,Error2} ->
- io:format("Warning: ~w can not read ~p: ~p~n",
+ io:format("Warning: ~w can not read ~tp: ~tp~n",
[?MODULE,ToFile,Error2]),
[false,false,false]
end,
@@ -1807,7 +1807,7 @@ check_opt_file(FileName, Type, Masters) ->
ok ->
true;
_Error ->
- io:format("Warning: ~p missing (optional)~n", [FileName]),
+ io:format("Warning: ~tp missing (optional)~n", [FileName]),
false
end.
@@ -1841,14 +1841,12 @@ do_check_file(Master, FileName, Type) ->
%% by the user in another way, i.e. ignore this here.
%%-----------------------------------------------------------------
extract_rel_file(Rel, Tar, Root) ->
- erl_tar:extract(Tar, [{files, [Rel]}, {cwd, Root}, compressed]).
+ _ = erl_tar:extract(Tar, [{files, [Rel]}, {cwd, Root}, compressed]).
extract_tar(Root, Tar) ->
case erl_tar:extract(Tar, [keep_old_files, {cwd, Root}, compressed]) of
ok ->
ok;
- {error, Reason, Name} -> % Old erl_tar.
- throw({error, {cannot_extract_file, Name, Reason}});
{error, {Name, Reason}} -> % New erl_tar (R3A).
throw({error, {cannot_extract_file, Name, Reason}})
end.
diff --git a/lib/sasl/src/sasl.app.src b/lib/sasl/src/sasl.app.src
index 4ee8a7d6c8..633cdfa070 100644
--- a/lib/sasl/src/sasl.app.src
+++ b/lib/sasl/src/sasl.app.src
@@ -46,5 +46,5 @@
{errlog_type, all}]},
{mod, {sasl, []}},
{runtime_dependencies, ["tools-2.6.14","stdlib-3.0","kernel-5.0",
- "erts-8.0"]}]}.
+ "erts-8.1"]}]}.
diff --git a/lib/sasl/src/sasl.appup.src b/lib/sasl/src/sasl.appup.src
index ecd320c1ea..7f866507a0 100644
--- a/lib/sasl/src/sasl.appup.src
+++ b/lib/sasl/src/sasl.appup.src
@@ -18,9 +18,7 @@
%% %CopyrightEnd%
{"%VSN%",
%% Up from - max one major revision back
- [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-18.*
+ [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-19.*
%% Down to - max one major revision back
- [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-18.*
+ [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-19.*
}.
diff --git a/lib/sasl/src/sasl_report.erl b/lib/sasl/src/sasl_report.erl
index 14702b0ad2..eb454155d5 100644
--- a/lib/sasl/src/sasl_report.erl
+++ b/lib/sasl/src/sasl_report.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -68,12 +68,12 @@ write_report2(IO, Fd, Head, progress, Report) ->
Format = format_key_val(Report),
write_report_action(IO, Fd, Head, "~s", [Format]);
write_report2(IO, Fd, Head, crash_report, Report) ->
- Depth = get_depth(),
+ Depth = error_logger:get_format_depth(),
Format = proc_lib:format(Report, latin1, Depth),
write_report_action(IO, Fd, Head, "~s", [Format]).
supervisor_format(Args0) ->
- case get_depth() of
+ case error_logger:get_format_depth() of
unlimited ->
{" Supervisor: ~p~n"
" Context: ~p~n"
@@ -102,14 +102,6 @@ format_key_val([{Tag,Data}|Rep]) ->
format_key_val(_) ->
[].
-get_depth() ->
- case application:get_env(kernel, error_logger_format_depth) of
- {ok, Depth} when is_integer(Depth) ->
- max(10, Depth);
- undefined ->
- unlimited
- end.
-
sup_get(Tag, Report) ->
case lists:keysearch(Tag, 1, Report) of
{value, {_, Value}} ->
diff --git a/lib/sasl/src/systools_make.erl b/lib/sasl/src/systools_make.erl
index 352e4984df..b1523dcbb7 100644
--- a/lib/sasl/src/systools_make.erl
+++ b/lib/sasl/src/systools_make.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -94,7 +94,11 @@ make_script(RelName, Output, Flags) when is_list(RelName),
Warnings = wsasl(Flags, Warnings0),
case systools_lib:werror(Flags, Warnings) of
true ->
- return(ok,Warnings,Flags);
+ Warnings1 = [W || {warning,W}<-Warnings],
+ return({error,?MODULE,
+ {warnings_treated_as_errors,Warnings1}},
+ Warnings,
+ Flags);
false ->
case generate_script(Output,Release,Appls,Flags) of
ok ->
@@ -115,7 +119,6 @@ make_script(RelName, _Output, Flags) when is_list(Flags) ->
make_script(RelName, _Output, Flags) ->
badarg(Flags,[RelName, Flags]).
-
wsasl(Options, Warnings) ->
case lists:member(no_warn_sasl,Options) of
true -> lists:delete({warning,missing_sasl},Warnings);
@@ -148,21 +151,10 @@ get_outdir(Flags) ->
return(ok,Warnings,Flags) ->
case member(silent,Flags) of
true ->
- case systools_lib:werror(Flags, Warnings) of
- true ->
- error;
- false ->
- {ok,?MODULE,Warnings}
- end;
+ {ok,?MODULE,Warnings};
_ ->
- case member(warnings_as_errors,Flags) of
- true ->
- io:format("~ts",[format_warning(Warnings, true)]),
- error;
- false ->
- io:format("~ts",[format_warning(Warnings)]),
- ok
- end
+ io:format("~ts",[format_warning(Warnings)]),
+ ok
end;
return({error,Mod,Error},_,Flags) ->
case member(silent,Flags) of
@@ -300,6 +292,8 @@ add_apply_upgrade(Script,Args) ->
%% {variables,[{Name,AbsString}]}
%% {machine, jam | beam | vee}
%% {var_tar, include | ownfile | omit}
+%% no_warn_sasl
+%% warnings_as_errors
%%
%% The tar file contains:
%% lib/App-Vsn/ebin
@@ -332,13 +326,23 @@ make_tar(RelName, Flags) when is_list(RelName), is_list(Flags) ->
Path = make_set(Path1 ++ code:get_path()),
ModTestP = {member(src_tests, Flags),xref_p(Flags)},
case get_release(RelName, Path, ModTestP, machine(Flags)) of
- {ok, Release, Appls, Warnings} ->
- case catch mk_tar(RelName, Release, Appls, Flags, Path1) of
- ok ->
- return(ok,Warnings,Flags);
- Error ->
- return(Error,Warnings,Flags)
- end;
+ {ok, Release, Appls, Warnings0} ->
+ Warnings = wsasl(Flags, Warnings0),
+ case systools_lib:werror(Flags, Warnings) of
+ true ->
+ Warnings1 = [W || {warning,W}<-Warnings],
+ return({error,?MODULE,
+ {warnings_treated_as_errors,Warnings1}},
+ Warnings,
+ Flags);
+ false ->
+ case catch mk_tar(RelName, Release, Appls, Flags, Path1) of
+ ok ->
+ return(ok,Warnings,Flags);
+ Error ->
+ return(Error,Warnings,Flags)
+ end
+ end;
Error ->
return(Error,[],Flags)
end;
@@ -643,6 +647,8 @@ get_items([], _Dict) ->
check_item({_,{mod,{M,A}}},_) when is_atom(M) ->
{M,A};
+check_item({_,{mod,[]}},_) -> % default mod is [], so accept as entry
+ [];
check_item({_,{vsn,Vsn}},I) ->
case string_p(Vsn) of
true -> Vsn;
@@ -678,6 +684,8 @@ check_item({_,{modules,Mods}},I) ->
true -> Mods;
_ -> throw({bad_param, I})
end;
+check_item({_,{start_phases,undefined}},_) -> % default start_phase is undefined,
+ undefined; % so accept as entry
check_item({_,{start_phases,Phase}},I) ->
case t_list_p(Phase) of
true -> Phase;
@@ -1491,8 +1499,9 @@ mandatory_modules() ->
preloaded() ->
%% Sorted
[erl_prim_loader,erl_tracer,erlang,
- erts_code_purger,
- erts_internal,init,otp_ring0,prim_eval,prim_file,
+ erts_code_purger,erts_dirty_process_code_checker,
+ erts_internal,erts_literal_area_collector,
+ init,otp_ring0,prim_eval,prim_file,
prim_inet,prim_zip,zlib].
%%______________________________________________________________________
@@ -1899,8 +1908,10 @@ del_tar(Tar, TarName) ->
file:delete(TarName).
add_to_tar(Tar, FromFile, ToFile) ->
- case erl_tar:add(Tar, FromFile, ToFile, [compressed, dereference]) of
+ case catch erl_tar:add(Tar, FromFile, ToFile, [compressed, dereference]) of
ok -> ok;
+ {'EXIT', Reason} ->
+ throw({error, {tar_error, {add, FromFile, Reason}}});
{error, Error} ->
throw({error, {tar_error, {add, FromFile, Error}}})
end.
@@ -2108,90 +2119,80 @@ cas([Y | Args], X) ->
%% Check Options for make_tar
check_args_tar(Args) ->
- cat(Args, {undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, []}).
+ cat(Args, []).
-cat([], {_Path,_Sil,_Dirs,_Erts,_Test,_Var,_VarTar,_Mach,_Xref,_XrefApps, X}) ->
+cat([], X) ->
X;
%%% path ---------------------------------------------------------------
-cat([{path, P} | Args], {Path, Sil, Dirs, Erts, Test,
- Var, VarTar, Mach, Xref, XrefApps, X}) when is_list(P) ->
+cat([{path, P} | Args], X) when is_list(P) ->
case check_path(P) of
ok ->
- cat(Args, {P, Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X});
+ cat(Args, X);
error ->
- cat(Args, {Path, Sil, Dirs, Erts, Test,
- Var, VarTar, Mach, Xref, XrefApps, X++[{path,P}]})
+ cat(Args, X++[{path,P}])
end;
%%% silent -------------------------------------------------------------
-cat([silent | Args], {Path, _Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X}) ->
- cat(Args, {Path, silent, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X});
+cat([silent | Args], X) ->
+ cat(Args, X);
%%% dirs ---------------------------------------------------------------
-cat([{dirs, D} | Args], {Path, Sil, Dirs, Erts, Test,
- Var, VarTar, Mach, Xref, XrefApps, X}) ->
+cat([{dirs, D} | Args], X) ->
case check_dirs(D) of
ok ->
- cat(Args, {Path, Sil, D, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X});
+ cat(Args, X);
error ->
- cat(Args, {Path, Sil, Dirs, Erts, Test,
- Var, VarTar, Mach, Xref, XrefApps, X++[{dirs, D}]})
+ cat(Args, X++[{dirs, D}])
end;
%%% erts ---------------------------------------------------------------
-cat([{erts, E} | Args], {Path, Sil, Dirs, _Erts, Test,
- Var, VarTar, Mach, Xref, XrefApps, X}) when is_list(E)->
- cat(Args, {Path, Sil, Dirs, E, Test, Var, VarTar, Mach, Xref, XrefApps, X});
+cat([{erts, E} | Args], X) when is_list(E)->
+ cat(Args, X);
%%% src_tests ----------------------------------------------------
-cat([src_tests | Args], {Path, Sil, Dirs, Erts, _Test, Var, VarTar, Mach, Xref, XrefApps, X}) ->
- cat(Args, {Path, Sil, Dirs, Erts, src_tests, Var, VarTar, Mach,
- Xref, XrefApps, X});
+cat([src_tests | Args], X) ->
+ cat(Args, X);
%%% variables ----------------------------------------------------------
-cat([{variables, V} | Args], {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X}) when is_list(V) ->
+cat([{variables, V} | Args], X) when is_list(V) ->
case check_vars(V) of
ok ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, V, VarTar, Mach, Xref, XrefApps, X});
+ cat(Args, X);
error ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach,
- Xref, XrefApps, X++[{variables, V}]})
+ cat(Args, X++[{variables, V}])
end;
%%% var_tar ------------------------------------------------------------
-cat([{var_tar, VT} | Args], {Path, Sil, Dirs, Erts, Test,
- Var, _VarTar, Mach, Xref, XrefApps, X}) when VT == include ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, include, Mach, Xref, XrefApps, X});
-cat([{var_tar, VT} | Args], {Path, Sil, Dirs, Erts, Test,
- Var, _VarTar, Mach, Xref, XrefApps, X}) when VT == ownfile ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, ownfile, Mach, Xref, XrefApps, X});
-cat([{var_tar, VT} | Args], {Path, Sil, Dirs, Erts, Test,
- Var, _VarTar, Mach, Xref, XrefApps, X}) when VT == omit ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, omit, Mach, Xref, XrefApps, X});
+cat([{var_tar, VT} | Args], X) when VT == include;
+ VT == ownfile;
+ VT == omit ->
+ cat(Args, X);
%%% machine ------------------------------------------------------------
-cat([{machine, M} | Args], {Path, Sil, Dirs, Erts, Test,
- Var, VarTar, Mach, Xref, XrefApps, X}) when is_atom(M) ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X});
+cat([{machine, M} | Args], X) when is_atom(M) ->
+ cat(Args, X);
%%% exref --------------------------------------------------------------
-cat([exref | Args], {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, _Xref, XrefApps, X}) ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, exref, XrefApps, X});
+cat([exref | Args], X) ->
+ cat(Args, X);
%%% exref Apps ---------------------------------------------------------
-cat([{exref, Apps} | Args], {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X}) when is_list(Apps) ->
+cat([{exref, Apps} | Args], X) when is_list(Apps) ->
case check_apps(Apps) of
ok ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach,
- Xref, Apps, X});
+ cat(Args, X);
error ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach,
- Xref, XrefApps, X++[{exref, Apps}]})
+ cat(Args, X++[{exref, Apps}])
end;
%%% outdir Dir ---------------------------------------------------------
-cat([{outdir, Dir} | Args], {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X}) when is_list(Dir) ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach,
- Xref, XrefApps, X});
+cat([{outdir, Dir} | Args], X) when is_list(Dir) ->
+ cat(Args, X);
%%% otp_build (secret, not documented) ---------------------------------
-cat([otp_build | Args], {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X}) ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X});
+cat([otp_build | Args], X) ->
+ cat(Args, X);
+%%% warnings_as_errors ----
+cat([warnings_as_errors | Args], X) ->
+ cat(Args, X);
+%%% no_warn_sasl ----
+cat([no_warn_sasl | Args], X) ->
+ cat(Args, X);
%%% no_module_tests (kept for backwards compatibility, but ignored) ----
-cat([no_module_tests | Args], {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X}) ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X});
+cat([no_module_tests | Args], X) ->
+ cat(Args, X);
%%% ERROR --------------------------------------------------------------
-cat([Y | Args], {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X}) ->
- cat(Args, {Path, Sil, Dirs, Erts, Test, Var, VarTar, Mach, Xref, XrefApps, X++[Y]}).
+cat([Y | Args], X) ->
+ cat(Args, X++[Y]).
check_path([]) ->
ok;
@@ -2233,9 +2234,9 @@ check_apps(_) ->
format_error(badly_formatted_release) ->
io_lib:format("Syntax error in the release file~n",[]);
format_error({illegal_name, Name}) ->
- io_lib:format("Illegal name (~p) in the release file~n",[Name]);
+ io_lib:format("Illegal name (~tp) in the release file~n",[Name]);
format_error({illegal_form, Form}) ->
- io_lib:format("Illegal tag in the release file: ~p~n",[Form]);
+ io_lib:format("Illegal tag in the release file: ~tp~n",[Form]);
format_error({missing_parameter,Par}) ->
io_lib:format("Missing parameter (~p) in the release file~n",[Par]);
format_error({illegal_applications,Names}) ->
@@ -2250,7 +2251,7 @@ format_error({mandatory_app,Name,Type}) ->
format_error({duplicate_register,Dups}) ->
io_lib:format("Duplicated register names: ~n~ts",
[map(fun({{Reg,App1,_,_},{Reg,App2,_,_}}) ->
- io_lib:format("\t~w registered in ~w and ~w~n",
+ io_lib:format("\t~tw registered in ~w and ~w~n",
[Reg,App1,App2])
end, Dups)]);
format_error({undefined_applications,Apps}) ->
@@ -2274,26 +2275,29 @@ format_error({modules,ModErrs}) ->
format_error({circular_dependencies,Apps}) ->
io_lib:format("Circular dependencies among applications: ~p~n",[Apps]);
format_error({not_found,File}) ->
- io_lib:format("File not found: ~p~n",[File]);
+ io_lib:format("File not found: ~tp~n",[File]);
format_error({parse,File,{Line,Mod,What}}) ->
Str = Mod:format_error(What),
io_lib:format("~ts:~w: ~ts\n",[File, Line, Str]);
format_error({read,File}) ->
- io_lib:format("Cannot read ~p~n",[File]);
+ io_lib:format("Cannot read ~tp~n",[File]);
format_error({open,File,Error}) ->
- io_lib:format("Cannot open ~p - ~ts~n",
+ io_lib:format("Cannot open ~tp - ~ts~n",
[File,file:format_error(Error)]);
format_error({close,File,Error}) ->
- io_lib:format("Cannot close ~p - ~ts~n",
+ io_lib:format("Cannot close ~tp - ~ts~n",
[File,file:format_error(Error)]);
format_error({delete,File,Error}) ->
- io_lib:format("Cannot delete ~p - ~ts~n",
+ io_lib:format("Cannot delete ~tp - ~ts~n",
[File,file:format_error(Error)]);
format_error({tar_error,What}) ->
form_tar_err(What);
+format_error({warnings_treated_as_errors,Warnings}) ->
+ io_lib:format("Warnings being treated as errors:~n~ts",
+ [map(fun(W) -> form_warn("",W) end, Warnings)]);
format_error(ListOfErrors) when is_list(ListOfErrors) ->
format_errors(ListOfErrors);
-format_error(E) -> io_lib:format("~p~n",[E]).
+format_error(E) -> io_lib:format("~tp~n",[E]).
format_errors(ListOfErrors) ->
map(fun({error,E}) -> form_err(E);
@@ -2309,19 +2313,19 @@ form_err({module_not_found,App,Mod}) ->
form_err({error_add_appl, {Name, {tar_error, What}}}) ->
io_lib:format("~p: ~ts~n",[Name,form_tar_err(What)]);
form_err(E) ->
- io_lib:format("~p~n",[E]).
+ io_lib:format("~tp~n",[E]).
form_reading({not_found,File}) ->
- io_lib:format("File not found: ~p~n",[File]);
+ io_lib:format("File not found: ~tp~n",[File]);
form_reading({application_vsn, {Name,Vsn}}) ->
- io_lib:format("Application ~ts with version ~p not found~n",[Name, Vsn]);
+ io_lib:format("Application ~ts with version ~tp not found~n",[Name, Vsn]);
form_reading({parse,File,{Line,Mod,What}}) ->
Str = Mod:format_error(What),
io_lib:format("~ts:~w: ~ts\n",[File, Line, Str]);
form_reading({read,File}) ->
- io_lib:format("Cannot read ~p~n",[File]);
+ io_lib:format("Cannot read ~tp~n",[File]);
form_reading({{bad_param, P},_}) ->
- io_lib:format("Bad parameter in .app file: ~p~n",[P]);
+ io_lib:format("Bad parameter in .app file: ~tp~n",[P]);
form_reading({{missing_param,P},_}) ->
io_lib:format("Missing parameter in .app file: ~p~n",[P]);
form_reading({badly_formatted_application,_}) ->
@@ -2330,12 +2334,12 @@ form_reading({override_include,Apps}) ->
io_lib:format("Tried to include not (in .app file) specified applications: ~p~n",
[Apps]);
form_reading({no_valid_version, {{_, SVsn}, {_, File, FVsn}}}) ->
- io_lib:format("No valid version (~p) of .app file found. Found file ~p with version ~p~n",
+ io_lib:format("No valid version (~tp) of .app file found. Found file ~tp with version ~tp~n",
[SVsn, File, FVsn]);
form_reading({parse_error, {File, Line, Error}}) ->
- io_lib:format("Parse error in file: ~p. Line: ~w Error: ~p; ~n", [File, Line, Error]);
+ io_lib:format("Parse error in file: ~tp. Line: ~w Error: ~tp; ~n", [File, Line, Error]);
form_reading(W) ->
- io_lib:format("~p~n",[W]).
+ io_lib:format("~tp~n",[W]).
form_tar_err({open, File, Error}) ->
io_lib:format("Cannot open tar file ~ts - ~ts~n",
@@ -2347,35 +2351,26 @@ form_tar_err({add, File, Error}) ->
%% Format warning
format_warning(Warnings) ->
- format_warning(Warnings, false).
-
-format_warning(Warnings, Werror) ->
- Prefix = case Werror of
- true ->
- "";
- false ->
- "*WARNING* "
- end,
- map(fun({warning,W}) -> form_warn(Prefix, W) end, Warnings).
-
-form_warn(Prefix, {source_not_found,{Mod,_,App,_,_}}) ->
+ map(fun({warning,W}) -> form_warn("*WARNING* ", W) end, Warnings).
+
+form_warn(Prefix, {source_not_found,{Mod,App,_}}) ->
io_lib:format("~ts~w: Source code not found: ~w.erl~n",
[Prefix,App,Mod]);
form_warn(Prefix, {{parse_error, File},{_,_,App,_,_}}) ->
- io_lib:format("~ts~w: Parse error: ~p~n",
+ io_lib:format("~ts~w: Parse error: ~tp~n",
[Prefix,App,File]);
-form_warn(Prefix, {obj_out_of_date,{Mod,_,App,_,_}}) ->
+form_warn(Prefix, {obj_out_of_date,{Mod,App,_}}) ->
io_lib:format("~ts~w: Object code (~w) out of date~n",
[Prefix,App,Mod]);
form_warn(Prefix, {exref_undef, Undef}) ->
F = fun({M,F,A}) ->
- io_lib:format("~tsUndefined function ~w:~w/~w~n",
+ io_lib:format("~tsUndefined function ~w:~tw/~w~n",
[Prefix,M,F,A])
end,
map(F, Undef);
form_warn(Prefix, missing_sasl) ->
- io_lib:format("~ts: Missing application sasl. "
+ io_lib:format("~tsMissing application sasl. "
"Can not upgrade with this release~n",
[Prefix]);
form_warn(Prefix, What) ->
- io_lib:format("~ts ~p~n", [Prefix,What]).
+ io_lib:format("~ts~tp~n", [Prefix,What]).
diff --git a/lib/sasl/src/systools_rc.erl b/lib/sasl/src/systools_rc.erl
index 7722cef57b..c570ed00ab 100644
--- a/lib/sasl/src/systools_rc.erl
+++ b/lib/sasl/src/systools_rc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -942,41 +942,41 @@ format_error(too_many_point_of_no_return) ->
io_lib:format("Too many point_of_no_return~n", []);
format_error({bad_instruction, X}) ->
- io_lib:format("Bad instruction: ~p~n", [X]);
+ io_lib:format("Bad instruction: ~tp~n", [X]);
format_error({bad_module, X}) ->
- io_lib:format("Bad module: ~p(should be atom())~n", [X]);
+ io_lib:format("Bad module: ~tp(should be atom())~n", [X]);
format_error({bad_code_change, X}) ->
- io_lib:format("Bad code_change: ~p(should be {Mod, Extra})~n", [X]);
+ io_lib:format("Bad code_change: ~tp(should be {Mod, Extra})~n", [X]);
format_error({bad_change, X}) ->
- io_lib:format("Bad change spec: ~p(should be soft | {advanced, E})~n", [X]);
+ io_lib:format("Bad change spec: ~tp(should be soft | {advanced, E})~n", [X]);
format_error({bad_mod_type, X}) ->
- io_lib:format("Bad module type: ~p(should be static | dynamic)~n", [X]);
+ io_lib:format("Bad module type: ~tp(should be static | dynamic)~n", [X]);
format_error({bad_purge_method, X}) ->
- io_lib:format("Bad purge method: ~p(should be soft_purge | brutal_purge)~n",
+ io_lib:format("Bad purge method: ~tp(should be soft_purge | brutal_purge)~n",
[X]);
format_error({bad_list, X}) ->
- io_lib:format("Bad list: ~p~n", [X]);
+ io_lib:format("Bad list: ~tp~n", [X]);
format_error({bad_args_list, X}) ->
- io_lib:format("Bad argument list: ~p~n", [X]);
+ io_lib:format("Bad argument list: ~tp~n", [X]);
format_error({bad_node, X}) ->
- io_lib:format("Bad node: ~p(should be atom())~n", [X]);
+ io_lib:format("Bad node: ~tp(should be atom())~n", [X]);
format_error({bad_application, X}) ->
- io_lib:format("Bad application: ~p(should be atom())~n", [X]);
+ io_lib:format("Bad application: ~tp(should be atom())~n", [X]);
format_error({bad_func, X}) ->
- io_lib:format("Bad function: ~p(should be atom())~n", [X]);
+ io_lib:format("Bad function: ~tp(should be atom())~n", [X]);
format_error({bad_lib, X}) ->
- io_lib:format("Bad library: ~p(should be atom())~n", [X]);
+ io_lib:format("Bad library: ~tp(should be atom())~n", [X]);
format_error({bad_lib_vsn, X}) ->
- io_lib:format("Bad library version: ~p(should be string())~n", [X]);
+ io_lib:format("Bad library version: ~tp(should be string())~n", [X]);
format_error({bad_timeout, X}) ->
- io_lib:format("Bad timeout: ~p(should be infinity | int() > 0)~n", [X]);
+ io_lib:format("Bad timeout: ~tp(should be infinity | int() > 0)~n", [X]);
format_error({undef_module, Mod}) ->
io_lib:format("Undefined module: ~p~n", [Mod]);
format_error({muldef_module, Mod}) ->
io_lib:format("Multiply defined module: ~p~n", [Mod]);
format_error(E) ->
- io_lib:format("~p~n",[E]).
+ io_lib:format("~tp~n",[E]).
%%-----------------------------------------------------------------
diff --git a/lib/sasl/src/systools_relup.erl b/lib/sasl/src/systools_relup.erl
index 28534dc0c8..706ae7d631 100644
--- a/lib/sasl/src/systools_relup.erl
+++ b/lib/sasl/src/systools_relup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -155,36 +155,12 @@ mk_relup(TopRelFile, BaseUpRelDcs, BaseDnRelDcs) ->
mk_relup(TopRelFile, BaseUpRelDcs, BaseDnRelDcs, Opts) ->
case check_opts(Opts) of
[] ->
- R = (catch do_mk_relup(TopRelFile,BaseUpRelDcs,BaseDnRelDcs,
- add_code_path(Opts), Opts)),
- case {get_opt(silent, Opts), get_opt(noexec, Opts)} of
- {false, false} ->
- case R of
- {ok, _Res, _Mod, Ws} ->
- print_warnings(Ws, Opts),
- case systools_lib:werror(Opts, Ws) of
- true ->
- error;
- false ->
- ok
- end;
- Other ->
- print_error(Other),
- error
- end;
- _ ->
- case R of
- {ok, _Res, _Mod, Ws} ->
- case systools_lib:werror(Opts, Ws) of
- true ->
- error;
- false ->
- R
- end;
- R ->
- R
- end
- end;
+ R = try do_mk_relup(TopRelFile,BaseUpRelDcs,BaseDnRelDcs,
+ add_code_path(Opts), Opts)
+ catch throw:Error ->
+ Error
+ end,
+ done_mk_relup(Opts, R);
BadArg ->
erlang:error({badarg, BadArg})
end.
@@ -224,17 +200,45 @@ do_mk_relup(TopRelFile, BaseUpRelDcs, BaseDnRelDcs, Path, Opts) ->
{Dn, Ws2} = foreach_baserel_dn(TopRel, TopApps, BaseDnRelDcs,
Path, Opts, Ws1),
Relup = {TopRel#release.vsn, Up, Dn},
- case systools_lib:werror(Opts, Ws2) of
- true ->
- ok;
- false ->
- write_relup_file(Relup, Opts)
- end,
- {ok, Relup, ?MODULE, Ws2};
+
+ {ok, Relup, Ws2};
Other ->
- throw(Other)
+ Other
end.
+done_mk_relup(Opts, {ok,Relup,Ws}) ->
+ WAE = get_opt(warnings_as_errors,Opts),
+ Silent = get_opt(silent,Opts),
+ Noexec = get_opt(noexec,Opts),
+
+ if WAE andalso Ws=/=[] ->
+ return_error(Silent,
+ {error,?MODULE,{warnings_treated_as_errors, Ws}});
+ not Noexec ->
+ case write_relup_file(Relup,Opts) of
+ ok ->
+ return_ok(Silent,Relup,Ws);
+ Error ->
+ return_error(Silent,Error)
+ end;
+ true -> % noexec
+ return_ok(true,Relup,Ws)
+ end;
+done_mk_relup(Opts, Error) ->
+ return_error(get_opt(silent,Opts) orelse get_opt(noexec,Opts), Error).
+
+return_error(true, Error) ->
+ Error;
+return_error(false, Error) ->
+ print_error(Error),
+ error.
+
+return_ok(true,Relup,Ws) ->
+ {ok,Relup,?MODULE,Ws};
+return_ok(false,_Relup,Ws) ->
+ print_warnings(Ws),
+ ok.
+
%%-----------------------------------------------------------------
%% foreach_baserel_up(Rel, TopApps, BaseRelDcs, Path, Opts, Ws) -> Ret
%% foreach_baserel_dn(Rel, TopApps, BaseRelDcs, Path, Opts, Ws) -> Ret
@@ -529,33 +533,18 @@ to_list(X) when is_list(X) -> X.
%% Writes a relup file.
%%
write_relup_file(Relup, Opts) ->
- case get_opt(noexec, Opts) of
- true ->
- ok;
- _ ->
- Filename = case get_opt(outdir, Opts) of
- OutDir when is_list(OutDir) ->
- filename:join(filename:absname(OutDir),
- "relup");
- false ->
- "relup";
- Badarg ->
- throw({error, ?MODULE, {badarg, {outdir,Badarg}}})
- end,
-
- case file:open(Filename, [write]) of
- {ok, Fd} ->
- io:format(Fd, "~p.~n", [Relup]),
- case file:close(Fd) of
- ok -> ok;
- {error,Reason} ->
- throw({error, ?MODULE,
- {file_problem, {"relup", {close,Reason}}}})
- end;
- {error, Reason} ->
- throw({error, ?MODULE,
- {file_problem, {"relup", {open, Reason}}}})
- end
+ Filename = filename:join(filename:absname(get_opt(outdir,Opts)),
+ "relup"),
+ case file:open(Filename, [write]) of
+ {ok, Fd} ->
+ io:format(Fd, "~p.~n", [Relup]),
+ case file:close(Fd) of
+ ok -> ok;
+ {error,Reason} ->
+ {error, ?MODULE, {file_problem, {"relup", {close,Reason}}}}
+ end;
+ {error, Reason} ->
+ {error, ?MODULE, {file_problem, {"relup", {open, Reason}}}}
end.
add_code_path(Opts) ->
@@ -593,15 +582,14 @@ default(path) -> false;
default(noexec) -> false;
default(silent) -> false;
default(restart_emulator) -> false;
-default(outdir) -> false.
+default(outdir) -> ".";
+default(warnings_as_errors) -> false.
-print_error({'EXIT', Err}) ->
- print_error(Err);
print_error({error, Mod, Error}) ->
S = apply(Mod, format_error, [Error]),
io:format(S, []);
print_error(Other) ->
- io:format("Error: ~p~n", [Other]).
+ io:format("Error: ~tp~n", [Other]).
format_error({file_problem, {File, What}}) ->
io_lib:format("Could not ~w file ~ts~n", [get_reason(What), File]);
@@ -614,33 +602,31 @@ format_error({missing_sasl,Release}) ->
io_lib:format("No sasl application in release ~ts, ~ts. "
"Can not be upgraded.",
[Release#release.name, Release#release.vsn]);
+format_error({warnings_treated_as_errors, Warnings}) ->
+ io_lib:format("Warnings being treated as errors:~n~ts",
+ [[format_warning("",W) || W <- Warnings]]);
format_error(Error) ->
- io:format("~p~n", [Error]).
+ io_lib:format("~tp~n", [Error]).
-print_warnings(Ws, Opts) when is_list(Ws) ->
- lists:foreach(fun(W) -> print_warning(W, Opts) end, Ws);
-print_warnings(W, Opts) ->
- print_warning(W, Opts).
+print_warnings(Ws) when is_list(Ws) ->
+ lists:foreach(fun(W) -> print_warning(W) end, Ws);
+print_warnings(W) ->
+ print_warning(W).
-print_warning(W, Opts) ->
- Prefix = case lists:member(warnings_as_errors, Opts) of
- true ->
- "";
- false ->
- "*WARNING* "
- end,
- S = format_warning(Prefix, W),
- io:format("~ts", [S]).
+print_warning(W) ->
+ io:format("~ts", [format_warning(W)]).
format_warning(W) ->
format_warning("*WARNING* ", W).
format_warning(Prefix, {erts_vsn_changed, {Rel1, Rel2}}) ->
- io_lib:format("~tsThe ERTS version changed between ~p and ~p~n",
+ io_lib:format("~tsThe ERTS version changed between ~tp and ~tp~n",
[Prefix, Rel1, Rel2]);
+format_warning(Prefix, pre_R15_emulator_upgrade) ->
+ io_lib:format("~tsUpgrade from an OTP version earlier than R15. New code should be compiled with the old emulator.~n",[Prefix]);
format_warning(Prefix, What) ->
- io_lib:format("~ts~p~n",[Prefix, What]).
+ io_lib:format("~ts~tp~n",[Prefix, What]).
get_reason({error, {open, _, _}}) -> open;
diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl
index ad58bb6b7b..7093158502 100644
--- a/lib/sasl/test/release_handler_SUITE.erl
+++ b/lib/sasl/test/release_handler_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1063,6 +1063,12 @@ otp_9395_check_and_purge(cleanup,_Conf) ->
%% OTP-9395 - performance problems when there are MANY processes
%% Upgrade which updates many modules (brutal_purge)
otp_9395_update_many_mods(Conf) when is_list(Conf) ->
+
+ %% "nain" is very slow - it fails this test quite often due to a
+ %% long sys call
+ %% /proc/cpuinfo: "clock: 1249MHz"
+ inet:gethostname() == {ok,"nain"} andalso throw({skip,"slow test host"}),
+
%% Set some paths
PrivDir = priv_dir(Conf),
Dir = filename:join(PrivDir,"otp_9395_update_many_mods"),
@@ -1162,6 +1168,12 @@ otp_9395_update_many_mods(cleanup,_Conf) ->
%% OTP-9395 - performance problems when there are MANY processes
%% Upgrade which removes many modules (brutal_purge)
otp_9395_rm_many_mods(Conf) when is_list(Conf) ->
+
+ %% "nain" is very slow - it fails this test quite often due to a
+ %% long sys call
+ %% /proc/cpuinfo: "clock: 1249MHz"
+ inet:gethostname() == {ok,"nain"} andalso throw({skip,"slow test host"}),
+
%% Set some paths
PrivDir = priv_dir(Conf),
Dir = filename:join(PrivDir,"otp_9395_rm_many_mods"),
@@ -1920,7 +1932,7 @@ wait_nodes_up(Nodes, Tag) ->
wait_nodes_up(Nodes0, Tag, Apps) ->
?t:format("wait_nodes_up(~p, ~p, ~p):",[Nodes0, Tag, Apps]),
Nodes = fix_nodes(Nodes0),
- wait_nodes_up(Nodes, Tag, lists:umerge(Apps,[kernel,stdlib,sasl]), 30).
+ wait_nodes_up(Nodes, Tag, lists:umerge(Apps,[kernel,stdlib,sasl]), 60).
fix_nodes([{Node,InitPid}|Nodes]) ->
[{Node,InitPid} | fix_nodes(Nodes)];
@@ -1962,7 +1974,7 @@ wait_nodes_up(Nodes, Tag, Apps, N) ->
?t:format("",[]),
ok;
_ ->
- timer:sleep(1000),
+ timer:sleep(2000),
wait_nodes_up(Pang, Tag, Apps, N-1)
end.
diff --git a/lib/sasl/test/release_handler_SUITE_data/start b/lib/sasl/test/release_handler_SUITE_data/start
index 87275045b1..eab2b77aed 100755
--- a/lib/sasl/test/release_handler_SUITE_data/start
+++ b/lib/sasl/test/release_handler_SUITE_data/start
@@ -21,8 +21,7 @@ then
fi
HEART_COMMAND=$ROOTDIR/bin/start
-HW_WD_DISABLE=true
-export HW_WD_DISABLE HEART_COMMAND
+export HEART_COMMAND
START_ERL_DATA=${1:-$RELDIR/start_erl.data}
diff --git a/lib/sasl/test/release_handler_SUITE_data/start_client b/lib/sasl/test/release_handler_SUITE_data/start_client
index 5ea94d6f7c..05d744f06e 100755
--- a/lib/sasl/test/release_handler_SUITE_data/start_client
+++ b/lib/sasl/test/release_handler_SUITE_data/start_client
@@ -24,8 +24,7 @@ RELDIR=$CLIENTDIR/releases
# Note that this scripts is modified an copied to $CLIENTDIR/bin/start
# in release_handler_SUITE:copy_client - therefore HEART_COMMAND is as follows:
HEART_COMMAND=$CLIENTDIR/bin/start
-HW_WD_DISABLE=true
-export HW_WD_DISABLE HEART_COMMAND
+export HEART_COMMAND
START_ERL_DATA=${1:-$RELDIR/start_erl.data}
diff --git a/lib/sasl/test/rh_test_lib.erl b/lib/sasl/test/rh_test_lib.erl
index 11935496d8..dacd8b6b9f 100644
--- a/lib/sasl/test/rh_test_lib.erl
+++ b/lib/sasl/test/rh_test_lib.erl
@@ -18,7 +18,7 @@ cmd(Cmd,Args,Env) ->
case open_port({spawn_executable, Cmd}, [{args,Args},{env,Env}]) of
Port when is_port(Port) ->
unlink(Port),
- erlang:port_close(Port),
+ catch erlang:port_close(Port), % migth already be closed, so catching
ok;
Error ->
Error
diff --git a/lib/sasl/test/sasl_report_SUITE.erl b/lib/sasl/test/sasl_report_SUITE.erl
index aa229726ae..53fb614921 100644
--- a/lib/sasl/test/sasl_report_SUITE.erl
+++ b/lib/sasl/test/sasl_report_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -79,7 +79,7 @@ do_gen_server_crash(Config) ->
error_logger:logfile(close),
check_file(KernelLog, 70000, 150000),
- check_file(SaslLog, 50000, 100000),
+ check_file(SaslLog, 100000, 150000),
ok.
diff --git a/lib/sasl/test/systools_SUITE.erl b/lib/sasl/test/systools_SUITE.erl
index bf95ceb70c..07748d975f 100644
--- a/lib/sasl/test/systools_SUITE.erl
+++ b/lib/sasl/test/systools_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,6 +29,8 @@
-module(systools_SUITE).
+-compile(export_all).
+
%%-define(debug, true).
-include_lib("common_test/include/ct.hrl").
@@ -39,31 +41,6 @@
-include_lib("kernel/include/file.hrl").
--export([all/0,suite/0,groups/0,init_per_group/2,end_per_group/2]).
-
--export([script_options/1, normal_script/1, unicode_script/1,
- unicode_script/2, no_mod_vsn_script/1,
- wildcard_script/1, variable_script/1, no_sasl_script/1,
- no_dot_erlang_script/1,
- abnormal_script/1, src_tests_script/1, crazy_script/1,
- included_script/1, included_override_script/1,
- included_fail_script/1, included_bug_script/1, exref_script/1,
- duplicate_modules_script/1,
- otp_3065_circular_dependenies/1, included_and_used_sort_script/1]).
--export([tar_options/1, normal_tar/1, no_mod_vsn_tar/1, system_files_tar/1,
- system_files_tar/2, invalid_system_files_tar/1,
- invalid_system_files_tar/2, variable_tar/1,
- src_tests_tar/1, var_tar/1, exref_tar/1, link_tar/1,
- otp_9507_path_ebin/1]).
--export([normal_relup/1, restart_relup/1, abnormal_relup/1, no_sasl_relup/1,
- no_appup_relup/1, bad_appup_relup/1, app_start_type_relup/1,
- regexp_relup/1]).
--export([normal_hybrid/1,hybrid_no_old_sasl/1,hybrid_no_new_sasl/1]).
--export([otp_6226_outdir/1]).
--export([init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, end_per_testcase/2]).
--export([delete_tree/1]).
-
-import(lists, [foldl/3]).
-define(default_timeout, ?t:minutes(20)).
@@ -91,13 +68,14 @@ groups() ->
{tar, [],
[tar_options, normal_tar, no_mod_vsn_tar, system_files_tar,
invalid_system_files_tar, variable_tar,
- src_tests_tar, var_tar, exref_tar, link_tar, otp_9507_path_ebin]},
+ src_tests_tar, var_tar, exref_tar, link_tar, no_sasl_tar,
+ otp_9507_path_ebin]},
{relup, [],
[normal_relup, restart_relup, abnormal_relup, no_sasl_relup,
no_appup_relup, bad_appup_relup, app_start_type_relup, regexp_relup
]},
{hybrid, [], [normal_hybrid,hybrid_no_old_sasl,hybrid_no_new_sasl]},
- {options, [], [otp_6226_outdir]}].
+ {options, [], [otp_6226_outdir,app_file_defaults]}].
init_per_group(_GroupName, Config) ->
Config.
@@ -109,25 +87,25 @@ end_per_group(_GroupName, Config) ->
init_per_suite(Config) when is_list(Config) ->
+ %% To use in end_per_testcase
+ Path = code:get_path(),
+ {ok,Cwd} = file:get_cwd(),
+
%% Make of copy of the data directory.
DataDir = ?datadir,
PrivDir = ?privdir,
CopyDir = fname(PrivDir, "datacopy"),
+ ok = file:make_dir(CopyDir),
TarFile = fname(PrivDir, "datacopy.tgz"),
- {ok, Tar} = erl_tar:open(TarFile, [write, compressed]),
- ok = erl_tar:add(Tar, DataDir, CopyDir, [compressed]),
- ok = erl_tar:close(Tar),
- ok = erl_tar:extract(TarFile, [compressed]),
+ ok = file:set_cwd(DataDir),
+ ok = erl_tar:create(TarFile, ["."], [compressed]),
+ ok = erl_tar:extract(TarFile, [compressed, {cwd,CopyDir}]),
ok = file:delete(TarFile),
%% Compile source files in the copy directory.
Sources = filelib:wildcard(fname([CopyDir,'*','*','*','*','*.erl'])),
lists:foreach(fun compile_source/1, Sources),
- %% To use in end_per_testcase
- Path = code:get_path(),
- {ok,Cwd} = file:get_cwd(),
-
[{copy_dir, CopyDir}, {cwd,Cwd}, {path,Path} | Config].
compile_source(File) ->
@@ -238,6 +216,7 @@ normal_script(Config) when is_list(Config) ->
%% Check the same but w. silent flag
{ok, _, []} = systools:make_script(LatestName, [silent]),
+ {ok, _, []} = systools:make_script(LatestName, [silent,warnings_as_errors]),
%% Use the local option
ok = systools:make_script(LatestName, [local]),
@@ -456,9 +435,16 @@ no_sasl_script(Config) when is_list(Config) ->
{ok, _ , [{warning,missing_sasl}]} =
systools:make_script(LatestName,[{path, P},silent]),
+ {error, systools_make, {warnings_treated_as_errors,[missing_sasl]}} =
+ systools:make_script(LatestName,[{path, P},silent,warnings_as_errors]),
+
{ok, _ , []} =
systools:make_script(LatestName,[{path, P},silent, no_warn_sasl]),
+ {ok, _ , []} =
+ systools:make_script(LatestName,[{path, P},silent, no_warn_sasl,
+ warnings_as_errors]),
+
ok = file:set_cwd(OldDir),
ok.
@@ -525,7 +511,9 @@ src_tests_script(Config) when is_list(Config) ->
ok = file:delete(BootFile),
false = filelib:is_regular(BootFile),
%% With warnings_as_errors and src_tests option, an error should be issued
- error =
+ {error, systools_make,
+ {warnings_treated_as_errors, [{obj_out_of_date,_},
+ {source_not_found,_}]}} =
systools:make_script(LatestName, [silent, {path, N}, src_tests,
warnings_as_errors]),
error =
@@ -745,7 +733,7 @@ exref_script(Config) when is_list(Config) ->
ok = file:set_cwd(LatestDir),
- {ok, _, _} = systools:make_script(LatestName, [{path,P}, silent]),
+ {ok, _, []} = systools:make_script(LatestName, [{path,P}, silent]),
%% Complete exref
{ok, _, W1} =
@@ -894,10 +882,10 @@ normal_tar(Config) when is_list(Config) ->
ok = file:set_cwd(LatestDir),
- {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]),
+ {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}]),
ok = systools:make_tar(LatestName, [{path, P}]),
ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName),
- {ok, _, _} = systools:make_tar(LatestName, [{path, P}, silent]),
+ {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent]),
ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName),
ok = file:set_cwd(OldDir),
@@ -918,10 +906,10 @@ no_mod_vsn_tar(Config) when is_list(Config) ->
ok = file:set_cwd(LatestDir),
- {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]),
+ {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}]),
ok = systools:make_tar(LatestName, [{path, P}]),
ok = check_tar(fname([lib,'db-3.1',ebin,'db.app']), LatestName),
- {ok, _, _} = systools:make_tar(LatestName, [{path, P}, silent]),
+ {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent]),
ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName),
ok = file:set_cwd(OldDir),
@@ -945,11 +933,11 @@ system_files_tar(Config) ->
ok = file:write_file("sys.config","[].\n"),
ok = file:write_file("relup","{\"LATEST\",[],[]}.\n"),
- {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]),
+ {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}]),
ok = systools:make_tar(LatestName, [{path, P}]),
ok = check_tar(fname(["releases","LATEST","sys.config"]), LatestName),
ok = check_tar(fname(["releases","LATEST","relup"]), LatestName),
- {ok, _, _} = systools:make_tar(LatestName, [{path, P}, silent]),
+ {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent]),
ok = check_tar(fname(["releases","LATEST","sys.config"]), LatestName),
ok = check_tar(fname(["releases","LATEST","relup"]), LatestName),
@@ -978,7 +966,7 @@ invalid_system_files_tar(Config) ->
ok = file:set_cwd(LatestDir),
- {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]),
+ {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}]),
%% Add dummy relup and sys.config - faulty sys.config
ok = file:write_file("sys.config","[]\n"), %!!! syntax error - missing '.'
@@ -1036,7 +1024,7 @@ variable_tar(Config) when is_list(Config) ->
ok = file:set_cwd(LatestDir),
- {ok, _, _} = systools:make_script(LatestName,
+ {ok, _, []} = systools:make_script(LatestName,
[silent,
{path, P},
{variables,[{"TEST", LibDir}]}]),
@@ -1045,7 +1033,7 @@ variable_tar(Config) when is_list(Config) ->
{variables,[{"TEST", LibDir}]}]),
ok = check_var_tar("TEST", LatestName),
- {ok, _, _} = systools:make_tar(LatestName,
+ {ok, _, []} = systools:make_tar(LatestName,
[{path, P}, silent,
{variables,[{"TEST", LibDir}]}]),
ok = check_var_tar("TEST", LatestName),
@@ -1174,7 +1162,7 @@ var_tar(Config) when is_list(Config) ->
ok = file:set_cwd(LatestDir),
- {ok, _, _} = systools:make_script(LatestName,
+ {ok, _, []} = systools:make_script(LatestName,
[silent,
{path, P},
{variables,[{"TEST", LibDir}]}]),
@@ -1218,7 +1206,7 @@ exref_tar(Config) when is_list(Config) ->
ok = file:set_cwd(LatestDir),
- {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]),
+ {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}]),
%% Complete exref
{ok, _, W1} =
@@ -1248,7 +1236,41 @@ exref_tar(Config) when is_list(Config) ->
ok = file:set_cwd(OldDir),
ok.
+%% make_tar: Create tar without sasl appl. Check warning.
+no_sasl_tar(Config) when is_list(Config) ->
+ {ok, OldDir} = file:get_cwd(),
+
+ {LatestDir, LatestName} = create_script(latest1_no_sasl,Config),
+
+ DataDir = filename:absname(?copydir),
+ LibDir = fname([DataDir, d_normal, lib]),
+ P = [fname([LibDir, '*', ebin]),
+ fname([DataDir, lib, kernel, ebin]),
+ fname([DataDir, lib, stdlib, ebin]),
+ fname([DataDir, lib, sasl, ebin])],
+ ok = file:set_cwd(LatestDir),
+
+ {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]),
+ ok = systools:make_tar(LatestName, [{path, P}]),
+ {ok, _, [{warning,missing_sasl}]} =
+ systools:make_tar(LatestName, [{path, P}, silent]),
+ {ok, _, []} =
+ systools:make_tar(LatestName, [{path, P}, silent, no_warn_sasl]),
+ {ok, _, []} =
+ systools:make_tar(LatestName, [{path, P}, silent, no_warn_sasl,
+ warnings_as_errors]),
+ TarFile = LatestName ++ ".tar.gz",
+ true = filelib:is_regular(TarFile),
+ ok = file:delete(TarFile),
+ {error, systools_make, {warnings_treated_as_errors,[missing_sasl]}} =
+ systools:make_tar(LatestName, [{path, P}, silent, warnings_as_errors]),
+ error =
+ systools:make_tar(LatestName, [{path, P}, warnings_as_errors]),
+ false = filelib:is_regular(TarFile),
+
+ ok = file:set_cwd(OldDir),
+ ok.
%% make_tar: OTP-9507 - make_tar failed when path given as just 'ebin'.
otp_9507_path_ebin(Config) when is_list(Config) ->
@@ -1268,7 +1290,7 @@ otp_9507_path_ebin(Config) when is_list(Config) ->
fname([DataDir, lib, kernel, ebin]),
fname([DataDir, lib, stdlib, ebin]),
fname([DataDir, lib, sasl, ebin])],
- {ok, _, _} = systools:make_script(RelName, [silent, {path, P1}]),
+ {ok, _, []} = systools:make_script(RelName, [silent, {path, P1}]),
ok = systools:make_tar(RelName, [{path, P1}]),
Content1 = tar_contents(RelName),
@@ -1309,7 +1331,7 @@ normal_relup(Config) when is_list(Config) ->
ok = systools:make_relup(LatestName, [LatestName1], [LatestName1],
[{path, P}]),
ok = check_relup([{db, "2.1"}], [{db, "1.0"}]),
- {ok, _, _, []} =
+ {ok, Relup, _, []} =
systools:make_relup(LatestName, [LatestName1], [LatestName1],
[{path, P}, silent]),
ok = check_relup([{db, "2.1"}], [{db, "1.0"}]),
@@ -1322,7 +1344,9 @@ normal_relup(Config) when is_list(Config) ->
error =
systools:make_relup(LatestName, [LatestName2], [LatestName1],
[{path, P}, warnings_as_errors]),
- error =
+ {error, systools_relup,
+ {warnings_treated_as_errors,[pre_R15_emulator_upgrade,
+ {erts_vsn_changed, _}]}} =
systools:make_relup(LatestName, [LatestName2], [LatestName1],
[{path, P}, silent, warnings_as_errors]),
@@ -1341,6 +1365,14 @@ normal_relup(Config) when is_list(Config) ->
%% relup file should exist now
true = filelib:is_regular("relup"),
+ %% file should not be written if noexec option is used.
+ %% delete before running tests.
+ ok = file:delete("relup"),
+ {ok,Relup,_,[]} =
+ systools:make_relup(LatestName, [LatestName1], [LatestName1],
+ [{path, P}, noexec]),
+ false = filelib:is_regular("relup"),
+
ok = file:set_cwd(OldDir),
ok.
@@ -2014,6 +2046,37 @@ otp_6226_outdir(Config) when is_list(Config) ->
ok.
+%% Test that all default values can be used as values in the .app file
+app_file_defaults(Config) ->
+ PrivDir = ?config(priv_dir,Config),
+ Name = app1,
+ NameStr = atom_to_list(Name),
+ Vsn = "1.0",
+ AppSpec = app_spec(Name,#{vsn=>"1.0"}),
+ ok = file:write_file(filename:join(PrivDir,NameStr ++ ".app"),
+ io_lib:format("~p.~n",[AppSpec])),
+ {ok,_} = systools_make:read_application(NameStr,Vsn,[PrivDir],[]),
+ ok.
+
+app_spec(Name,New) ->
+ {application,Name,app_spec(New)}.
+
+app_spec(New) ->
+ Default = #{description => "",
+ id => "",
+ vsn => "",
+ modules => [],
+ maxP => infinity,
+ maxT => infinity,
+ registered => [],
+ included_applications => [],
+ applications => [],
+ env => [],
+ mod => [],
+ start_phases => undefined,
+ runtime_dependencies => []},
+ maps:to_list(maps:merge(Default,New)).
+
%%%%%%
%%%%%% Utilities
%%%%%%
diff --git a/lib/sasl/test/test_lib.hrl b/lib/sasl/test/test_lib.hrl
index 2d897e9903..9a54937f96 100644
--- a/lib/sasl/test/test_lib.hrl
+++ b/lib/sasl/test/test_lib.hrl
@@ -1,3 +1,3 @@
-define(ertsvsn,"4.4").
--define(kernelvsn,"4.0").
--define(stdlibvsn,"2.5").
+-define(kernelvsn,"5.0").
+-define(stdlibvsn,"3.0").
diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk
index fd0fc9b8b5..2608ca5e00 100644
--- a/lib/sasl/vsn.mk
+++ b/lib/sasl/vsn.mk
@@ -1 +1 @@
-SASL_VSN = 3.0
+SASL_VSN = 3.0.4
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 0f5c35b300..b902e421ca 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -34,7 +34,72 @@
</header>
- <section><title>SNMP 5.2.3</title>
+ <section><title>SNMP 5.2.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Internal code change: Calls to <c>catch</c> followed
+ by a call to <c>erlang:get_stacktrace/0</c> has been
+ rewritten to use <c>try</c> instead of <c>catch</c> to
+ make the code future-proof.</p>
+ <p>
+ Own Id: OTP-14400</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SNMP 5.2.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The SNMP MIB compiler has been fixed to compile MIBS with
+ refinements on user types such as in RFC 4669
+ RADIUS-AUTH-SERVER-MIB.mib. Problem reported and
+ researched by Kenneth Lakin and Daniel Goertzen.</p>
+ <p>
+ See also: https://bugs.erlang.org/browse/ERL-325</p>
+ <p>
+ Own Id: OTP-14145 Aux Id: ERL-325 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SNMP 5.2.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Correct bugs when path to mib or idl spec files
+ contains UTF-8 characters. </p>
+ <p>
+ Own Id: OTP-13718 Aux Id: ERL-179 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Solves snmp config string handling as reported by ERL-164
+ and solved by PR-1100</p>
+ <p>
+ Own Id: OTP-13706</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SNMP 5.2.3</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/snmp/src/agent/snmp_generic.erl b/lib/snmp/src/agent/snmp_generic.erl
index fc23e16ef1..e67a1b3c80 100644
--- a/lib/snmp/src/agent/snmp_generic.erl
+++ b/lib/snmp/src/agent/snmp_generic.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -413,20 +413,21 @@ table_check_status(NameDb, Col, ?'RowStatus_createAndGo', RowIndex, Cols) ->
false ->
% it's ok to use snmpa_local_db:table_construct_row since it's
% side effect free and we only use the result temporary.
- case catch snmpa_local_db:table_construct_row(
+ try snmpa_local_db:table_construct_row(
NameDb, RowIndex, ?'RowStatus_createAndGo', Cols) of
- {'EXIT', _Reason} ->
- ?vtrace(
- "failed construct row (createAndGo): "
- " n Reason: ~p"
- " n Stack: ~p",
- [_Reason, erlang:get_stacktrace()]),
- {noCreation, Col}; % Bad RowIndex
Row ->
case lists:member(noinit, tuple_to_list(Row)) of
false -> {noError, 0};
_Found -> {inconsistentValue, Col}
end
+ catch
+ _:_Reason ->
+ ?vtrace(
+ "failed construct row (createAndGo): "
+ " n Reason: ~p"
+ " n Stack: ~p",
+ [_Reason, erlang:get_stacktrace()]),
+ {noCreation, Col} % Bad RowIndex
end;
true -> {inconsistentValue, Col}
end;
@@ -435,17 +436,18 @@ table_check_status(NameDb, Col, ?'RowStatus_createAndGo', RowIndex, Cols) ->
table_check_status(NameDb, Col, ?'RowStatus_createAndWait', RowIndex, Cols) ->
case table_row_exists(NameDb, RowIndex) of
false ->
- case catch snmpa_local_db:table_construct_row(
+ try snmpa_local_db:table_construct_row(
NameDb, RowIndex, ?'RowStatus_createAndGo', Cols) of
- {'EXIT', _Reason} ->
+ _Row ->
+ {noError, 0}
+ catch
+ _:_Reason ->
?vtrace(
"failed construct row (createAndWait): "
" n Reason: ~p"
" n Stack: ~p",
[_Reason, erlang:get_stacktrace()]),
- {noCreation, Col}; % Bad RowIndex
- _Row ->
- {noError, 0}
+ {noCreation, Col} % Bad RowIndex
end;
true -> {inconsistentValue, Col}
end;
diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl
index 94325a8ed6..fc5116dac9 100644
--- a/lib/snmp/src/agent/snmpa_conf.erl
+++ b/lib/snmp/src/agent/snmpa_conf.erl
@@ -154,7 +154,7 @@ do_write_agent_conf(Fd, {intAgentMaxPacketSize = Tag, Val} ) ->
do_write_agent_conf(Fd, {snmpEngineMaxMessageSize = Tag, Val} ) ->
io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
do_write_agent_conf(Fd, {snmpEngineID = Tag, Val} ) ->
- io:format(Fd, "{~w, \"~s\"}.~n", [Tag, Val]);
+ io:format(Fd, "{~w, ~p}.~n", [Tag, Val]);
do_write_agent_conf(_Fd, Crap) ->
error({bad_agent_config, Crap}).
@@ -758,9 +758,9 @@ do_write_usm_conf(
PrivP, PrivKeyC, OwnPrivKeyC,
Public, AuthKey, PrivKey}) ->
io:format(Fd, "{", []),
- io:format(Fd, "\"~s\", ", [EngineID]),
- io:format(Fd, "\"~s\", ", [UserName]),
- io:format(Fd, "\"~s\", ", [SecName]),
+ io:format(Fd, "~p, ", [EngineID]),
+ io:format(Fd, "~p, ", [UserName]),
+ io:format(Fd, "~p, ", [SecName]),
io:format(Fd, "~w, ", [Clone]),
io:format(Fd, "~w, ", [AuthP]),
do_write_usm2(Fd, AuthKeyC, ", "),
@@ -859,15 +859,15 @@ do_write_vacm_conf(
{vacmSecurityToGroup,
SecModel, SecName, GroupName}) ->
io:format(
- Fd, "{vacmSecurityToGroup, ~w, \"~s\", \"~s\"}.~n",
+ Fd, "{vacmSecurityToGroup, ~w, ~p, ~p}.~n",
[SecModel, SecName, GroupName]);
do_write_vacm_conf(
Fd,
{vacmAccess,
GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV}) ->
io:format(
- Fd, "{vacmAccess, \"~s\", \"~s\", ~w, ~w, ~w, "
- "\"~s\", \"~s\", \"~s\"}.~n",
+ Fd, "{vacmAccess, ~p, ~p, ~w, ~w, ~w, "
+ "~p, ~p, ~p}.~n",
[GroupName, Prefix, SecModel, SecLevel,
Match, RV, WV, NV]);
do_write_vacm_conf(
@@ -875,7 +875,7 @@ do_write_vacm_conf(
{vacmViewTreeFamily,
ViewIndex, ViewSubtree, ViewStatus, ViewMask}) ->
io:format(
- Fd, "{vacmViewTreeFamily, \"~s\", ~w, ~w, ~w}.~n",
+ Fd, "{vacmViewTreeFamily, ~p, ~w, ~w, ~w}.~n",
[ViewIndex, ViewSubtree, ViewStatus, ViewMask]);
do_write_vacm_conf(_Fd, Crap) ->
error({bad_vacm_config, Crap}).
diff --git a/lib/snmp/src/app/snmp.app.src b/lib/snmp/src/app/snmp.app.src
index b593e9ea84..d4bf0de61a 100644
--- a/lib/snmp/src/app/snmp.app.src
+++ b/lib/snmp/src/app/snmp.app.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -23,12 +23,12 @@
{vsn, "%VSN%"},
{modules, [
%% Compiler modules (not in the runtime part of the app)
-% snmpc,
-% snmpc_lib,
-% snmpc_mib_gram,
-% snmpc_mib_to_hrl,
-% snmpc_misc,
-% snmpc_tok,
+ snmpc,
+ snmpc_lib,
+ snmpc_mib_gram,
+ snmpc_mib_to_hrl,
+ snmpc_misc,
+ snmpc_tok,
%% Application modules
snmp,
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index ca61782639..db09ec3dc5 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -8,6 +8,10 @@
%% {update, snmpa_local_db, soft, soft_purge, soft_purge, []}
%% {add_module, snmpm_net_if_mt}
[
+ {<<"5\\.2\\.4">>,
+ [{load_module, snmp, soft_purge, soft_purge, []},
+ {load_module, snmpc_lib, soft_purge, soft_purge, []},
+ {load_module, snmpc_mib_gram, soft_purge, soft_purge, []}]},
{<<"5\\..*">>, [{restart_application, snmp}]},
{<<"4\\..*">>, [{restart_application, snmp}]}
],
@@ -17,6 +21,10 @@
%% {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
[
+ {<<"5\\.2\\.4">>,
+ [{load_module, snmp, soft_purge, soft_purge, []},
+ {load_module, snmpc_lib, soft_purge, soft_purge, []},
+ {load_module, snmpc_mib_gram, soft_purge, soft_purge, []}]},
{<<"5\\..*">>, [{restart_application, snmp}]},
{<<"4\\..*">>, [{restart_application, snmp}]}
]
diff --git a/lib/snmp/src/app/snmp.erl b/lib/snmp/src/app/snmp.erl
index df3933ea01..8a736f688b 100644
--- a/lib/snmp/src/app/snmp.erl
+++ b/lib/snmp/src/app/snmp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -573,9 +573,16 @@ print_mod_info(Prefix, {Module, Info}) ->
CompDate =
case key1search(compile_time, Info) of
{value, {Year, Month, Day, Hour, Min, Sec}} ->
- lists:flatten(
- io_lib:format("~w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w",
- [Year, Month, Day, Hour, Min, Sec]));
+ io_lib:format(
+ "~w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w",
+ [Year, Month, Day, Hour, Min, Sec]);
+ _ ->
+ "Not found"
+ end,
+ Digest =
+ case key1search(md5, Info) of
+ {value, MD5} when is_binary(MD5) ->
+ [io_lib:format("~2.16.0b", [Byte]) || <<Byte>> <= MD5];
_ ->
"Not found"
end,
@@ -583,12 +590,14 @@ print_mod_info(Prefix, {Module, Info}) ->
"~s Vsn: ~s~n"
"~s App vsn: ~s~n"
"~s Compiler ver: ~s~n"
- "~s Compile time: ~s~n",
+ "~s Compile time: ~s~n"
+ "~s MD5 digest: ~s~n",
[Prefix, Module,
Prefix, Vsn,
Prefix, AppVsn,
- Prefix, CompVer,
- Prefix, CompDate]),
+ Prefix, CompVer,
+ Prefix, CompDate,
+ Prefix, Digest]),
ok.
key1search(Key, Vals) ->
@@ -617,7 +626,7 @@ versions1() ->
Error ->
Error
end.
-
+
versions2() ->
case ms2() of
{ok, Mods} ->
@@ -625,25 +634,56 @@ versions2() ->
Error ->
Error
end.
-
+
version_info(Mods) ->
SysInfo = sys_info(),
OsInfo = os_info(),
ModInfo = [mod_version_info(Mod) || Mod <- Mods],
[{sys_info, SysInfo}, {os_info, OsInfo}, {mod_info, ModInfo}].
-
+
mod_version_info(Mod) ->
Info = Mod:module_info(),
- {value, {attributes, Attr}} = lists:keysearch(attributes, 1, Info),
- {value, {vsn, [Vsn]}} = lists:keysearch(vsn, 1, Attr),
- {value, {app_vsn, AppVsn}} = lists:keysearch(app_vsn, 1, Attr),
- {value, {compile, Comp}} = lists:keysearch(compile, 1, Info),
- {value, {version, Ver}} = lists:keysearch(version, 1, Comp),
- {value, {time, Time}} = lists:keysearch(time, 1, Comp),
- {Mod, [{vsn, Vsn},
- {app_vsn, AppVsn},
- {compiler_version, Ver},
- {compile_time, Time}]}.
+ {Mod,
+ case key1search(attributes, Info) of
+ {value, Attr} ->
+ case key1search(vsn, Attr) of
+ {value, [Vsn]} ->
+ [{vsn, Vsn}];
+ not_found ->
+ []
+ end ++
+ case key1search(app_vsn, Attr) of
+ {value, AppVsn} ->
+ [{app_vsn, AppVsn}];
+ not_found ->
+ []
+ end;
+ not_found ->
+ []
+ end ++
+ case key1search(compile, Info) of
+ {value, Comp} ->
+ case key1search(version, Comp) of
+ {value, Ver} ->
+ [{compiler_version, Ver}];
+ not_found ->
+ []
+ end ++
+ case key1search(time, Comp) of
+ {value, Ver} ->
+ [{compile_time, Ver}];
+ not_found ->
+ []
+ end;
+ not_found ->
+ []
+ end ++
+ case key1search(md5, Info) of
+ {value, Bin} ->
+ [{md5, Bin}];
+ not_found ->
+ []
+ end}.
sys_info() ->
SysArch = string:strip(erlang:system_info(system_architecture),right,$\n),
diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl
index db1f9ee61b..416353508e 100644
--- a/lib/snmp/src/compile/snmpc.erl
+++ b/lib/snmp/src/compile/snmpc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -64,7 +64,7 @@ compile(Input, _Output, Options) ->
{ok, _} ->
ok;
{error, Reason} ->
- io:format("~p", [Reason]),
+ io:format("~tp", [Reason]),
error
end.
@@ -126,7 +126,14 @@ compile(FileName) ->
%%----------------------------------------------------------------------
compile(FileName, Options) when is_list(FileName) ->
- true = snmpc_misc:is_string(FileName),
+ case snmpc_misc:check_file(FileName) of
+ true ->
+ compile_1(FileName, Options);
+ false ->
+ {error, {invalid_file, FileName}}
+ end.
+
+compile_1(FileName, Options) ->
DefOpts = [{deprecated, true},
{group_check, true},
{i, ["./"]},
diff --git a/lib/snmp/src/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl
index 51690b6e7e..33ddd78308 100644
--- a/lib/snmp/src/compile/snmpc_lib.erl
+++ b/lib/snmp/src/compile/snmpc_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -99,7 +99,7 @@ make_ASN1type({{type_with_size,Type,{range,Lo,Hi}},Line}) ->
print_error("Undefined type '~w'",[Type],Line),
guess_string_type()
end;
-make_ASN1type({{integer_with_enum,Type,Enums},Line}) ->
+make_ASN1type({{type_with_enum,Type,Enums},Line}) ->
case lookup_vartype(Type) of
{value,ASN1type} -> ASN1type#asn1_type{assocList = [{enums, Enums}]};
false ->
diff --git a/lib/snmp/src/compile/snmpc_mib_gram.yrl b/lib/snmp/src/compile/snmpc_mib_gram.yrl
index 743c3a6550..14a668127e 100644
--- a/lib/snmp/src/compile/snmpc_mib_gram.yrl
+++ b/lib/snmp/src/compile/snmpc_mib_gram.yrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -387,10 +387,12 @@ syntax -> type : {{type, cat('$1')},line_of('$1')}.
syntax -> type size : {{type_with_size, cat('$1'), '$2'},line_of('$1')}.
syntax -> usertype size : {{type_with_size,val('$1'), '$2'},line_of('$1')}.
syntax -> 'INTEGER' '{' namedbits '}' :
- {{integer_with_enum, 'INTEGER', '$3'}, line_of('$1')}.
+ {{type_with_enum, 'INTEGER', '$3'}, line_of('$1')}.
syntax -> 'BITS' '{' namedbits '}' :
ensure_ver(2,'$1'),
{{bits, '$3'}, line_of('$1')}.
+syntax -> usertype '{' namedbits '}' :
+ {{type_with_enum, 'INTEGER', '$3'}, line_of('$1')}.
syntax -> 'SEQUENCE' 'OF' usertype :
{{sequence_of,val('$3')},line_of('$1')}.
diff --git a/lib/snmp/src/compile/snmpc_misc.erl b/lib/snmp/src/compile/snmpc_misc.erl
index 933d629746..312074f2e7 100644
--- a/lib/snmp/src/compile/snmpc_misc.erl
+++ b/lib/snmp/src/compile/snmpc_misc.erl
@@ -29,7 +29,7 @@
bits_to_int/2,
ensure_trailing_dir_delimiter/1,
foreach/3,
- is_string/1,
+ check_file/1,
read_mib/1,
read_noexit/2,
strip_extension_from_filename/2,
@@ -86,21 +86,21 @@ to_upper([C|Cs]) -> [C|to_upper(Cs)];
to_upper([]) -> [].
-is_string([]) -> true;
-is_string([Tkn | Str])
- when is_integer(Tkn) andalso (Tkn >= 0) andalso (Tkn =< 255) ->
- is_string(Str);
-is_string(_) -> false.
-
-
+check_file(FileName) ->
+ case filename:extension(FileName) of
+ ".mib" ->
+ filelib:is_regular(FileName);
+ _ ->
+ filelib:is_regular(FileName ++ ".mib")
+ end.
+
+
foreach(Function, ExtraArgs, [H | T]) ->
apply(Function, [H | ExtraArgs]),
foreach(Function, ExtraArgs, T);
foreach(_Function, _ExtraArgs, []) ->
true.
-
-
%%----------------------------------------------------------------------
%% Returns: {ok, Mib}|{error, Reason}
%% The reason for having the function if this module is:
diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk
index 87539f88f7..0f54e67c65 100644
--- a/lib/snmp/test/modules.mk
+++ b/lib/snmp/test/modules.mk
@@ -31,6 +31,7 @@ SUITE_MODULES = \
snmp_agent_mibs_test \
snmp_agent_nfilter_test \
snmp_agent_test \
+ snmp_agent_conf_test \
snmp_agent_test_lib \
snmp_manager_config_test \
snmp_manager_user \
diff --git a/lib/snmp/test/snmp_SUITE.erl b/lib/snmp/test/snmp_SUITE.erl
index 3b9219739b..05bd86253b 100644
--- a/lib/snmp/test/snmp_SUITE.erl
+++ b/lib/snmp/test/snmp_SUITE.erl
@@ -81,7 +81,8 @@ groups() ->
{group, note_store_test}]},
{agent, [], [{group, mibs_test},
{group, nfilter_test},
- {group, agent_test},
+ {group, agent_test},
+ {group, agent_conf_test},
{group, snmpnet_test}]},
{manager, [], [{group, manager_config_test},
{group, manager_user_test},
@@ -97,6 +98,7 @@ groups() ->
{mibs_test, [], [{snmp_agent_mibs_test, all}]},
{nfilter_test, [], [{snmp_agent_nfilter_test, all}]},
{agent_test, [], [{snmp_agent_test, all}]},
+ {agent_conf_test, [], [{snmp_agent_conf_test, all}]},
{snmpnet_test, [], [{snmp_to_snmpnet_SUITE, all}]},
{manager_config_test, [], [{snmp_manager_config_test, all}]},
{manager_user_test, [], [{snmp_manager_user_test, all}]},
diff --git a/lib/snmp/test/snmp_agent_conf_test.erl b/lib/snmp/test/snmp_agent_conf_test.erl
new file mode 100644
index 0000000000..0a22bd47d1
--- /dev/null
+++ b/lib/snmp/test/snmp_agent_conf_test.erl
@@ -0,0 +1,210 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(snmp_agent_conf_test).
+
+%%----------------------------------------------------------------------
+%% Include files
+%%----------------------------------------------------------------------
+
+%-include_lib("test_server/include/test_server.hrl").
+%-include("snmp_test_lib.hrl").
+-include_lib("common_test/include/ct.hrl").
+
+-export([
+ all/0,
+ groups/0,
+ init_per_suite/1,
+ end_per_suite/1,
+
+ check_agent/1,
+ check_usm/1,
+ check_vacm/1
+ ]).
+
+
+all() -> [
+ check_agent,
+ check_usm,
+ check_vacm
+ ].
+
+
+groups() ->
+ [].
+
+
+init_per_suite(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ PrivSubdir = filename:join(PrivDir, "snmp_agent_conf_test"),
+ ok = filelib:ensure_dir(filename:join(PrivSubdir, "dummy")),
+ [{priv_subdir, PrivSubdir} | Config].
+
+end_per_suite(_Config) ->
+ ok.
+
+%%======================================================================
+%% Test data
+%%======================================================================
+
+engine_ids() -> [
+ "plain eid",
+ "here\"eid",
+ "comes\neid",
+ "trouble\0eid",
+ binary_to_list(<<"中国引擎标识符"/utf8>>)
+].
+
+snmp_admin_strings() -> [
+ "plain string",
+ "heres\"eid",
+ "trouble\neid",
+ binary_to_list(<<"中国引擎标识符"/utf8>>)
+].
+
+
+%%======================================================================
+%% Test functions
+%%======================================================================
+
+
+check_agent(Config) ->
+ Dir = ?config(priv_subdir, Config),
+ lists:foreach(
+ fun(EngineId) -> check_agent_by_engineid(Dir, EngineId) end,
+ engine_ids()
+ ),
+ ok.
+
+check_agent_by_engineid(Dir, EngineId) ->
+ WEntries = [
+ snmpa_conf:agent_entry(intAgentIpAddress, {0,0,0,0}),
+ snmpa_conf:agent_entry(intAgentUDPPort, 161),
+ snmpa_conf:agent_entry(snmpEngineMaxMessageSize, 484),
+ snmpa_conf:agent_entry(snmpEngineID, EngineId)
+ ],
+
+ ok = snmpa_conf:write_agent_config(Dir, WEntries),
+ {ok, REntries} = snmpa_conf:read_agent_config(Dir),
+
+ true = is_subset(WEntries, REntries),
+ ok.
+
+%%======================================================================
+
+check_usm(Config) ->
+ Dir = ?config(priv_subdir, Config),
+ EngineId = hd(engine_ids()),
+ UserName = hd(snmp_admin_strings()),
+ SecName = hd(snmp_admin_strings()),
+
+ %% vary engine id
+ lists:foreach(
+ fun(EngineId_) -> check_usm_by_params(Dir, EngineId_, UserName, SecName) end,
+ engine_ids()
+ ),
+
+ %% vary user name
+ lists:foreach(
+ fun(UserName_) -> check_usm_by_params(Dir, EngineId, UserName_, SecName) end,
+ snmp_admin_strings()
+ ),
+
+ %% vary sec name
+ lists:foreach(
+ fun(SecName_) -> check_usm_by_params(Dir, EngineId, UserName, SecName_) end,
+ snmp_admin_strings()
+ ),
+
+ ok.
+
+check_usm_by_params(Dir, EngineId, UserName, SecName) ->
+ WEntries = [
+ snmpa_conf:usm_entry(
+ EngineId,
+ UserName,
+ SecName,
+ zeroDotZero,
+ usmNoAuthProtocol, % authproto
+ "", "",
+ usmNoPrivProtocol, % privproto
+ "", "", "",
+ [], %AuthKey
+ []) %PrivKey
+ ],
+
+ ok = snmpa_conf:write_usm_config(Dir, WEntries),
+ {ok, REntries} = snmpa_conf:read_usm_config(Dir),
+
+ true = is_subset(WEntries, REntries),
+ ok.
+
+%%======================================================================
+
+check_vacm(Config) ->
+ Dir = ?config(priv_subdir, Config),
+
+ %% vary sec name
+ lists:foreach(
+ fun(SecName_) -> check_vacm_by_params(Dir, SecName_) end,
+ snmp_admin_strings()
+ ),
+
+ ok.
+
+
+check_vacm_by_params(Dir, SecName) ->
+ WEntries = [
+ %% SecModel, SecName, GroupName
+ snmpa_conf:vacm_s2g_entry(usm, SecName, SecName),
+ %% GroupName,Prefix,SecModel,SecLevel,Match,ReadView,WriteView,NotifyView
+ snmpa_conf:vacm_acc_entry(SecName, "", any, noAuthNoPriv, exact, "all", "all", "all")
+ ],
+
+ ok = snmpa_conf:write_vacm_config(Dir, WEntries),
+ {ok, REntries} = snmpa_conf:read_vacm_config(Dir),
+
+ true = is_subset(WEntries, REntries),
+ ok.
+
+
+
+%%======================================================================
+
+
+%% additional tests needed:
+% check_context()
+% check_community()
+% check_standard()
+% check_target_addr()
+% check_target_params()
+% check_notify()
+
+
+%%======================================================================
+%% Local utility functions
+%%======================================================================
+
+is_subset(List1, List2) ->
+ io:format("Check ~p is subset of ~p\n", [List1, List2]),
+ sets:is_subset(
+ sets:from_list(List1),
+ sets:from_list(List2)
+ ).
diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl
index 8ae495bb1b..3c1a6f2afd 100644
--- a/lib/snmp/test/snmp_agent_test.erl
+++ b/lib/snmp/test/snmp_agent_test.erl
@@ -647,22 +647,22 @@ init_per_group(GroupName, Config) ->
snmp_test_lib:init_group_top_dir(GroupName, Config).
init_per_group_ipv6(GroupName, Config, Init) ->
+ {ok, Hostname0} = inet:gethostname(),
case ct:require(ipv6_hosts) of
ok ->
- case gen_udp:open(0, [inet6]) of
- {ok, S} ->
- ok = gen_udp:close(S),
- Init(
- snmp_test_lib:init_group_top_dir(
- GroupName,
- [{ipfamily, inet6},
- {ip, ?LOCALHOST(inet6)}
- | lists:keydelete(ip, 1, Config)]));
- {error, _} ->
- {skip, "Host seems to not support IPv6"}
- end;
+ case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts)) of
+ true ->
+ Init(
+ snmp_test_lib:init_group_top_dir(
+ GroupName,
+ [{ipfamily, inet6},
+ {ip, ?LOCALHOST(inet6)}
+ | lists:keydelete(ip, 1, Config)]));
+ false ->
+ {skip, "Host does not support IPV6"}
+ end;
_ ->
- {skip, "Host does not support IPV6"}
+ {skip, "Test config ipv6_hosts is missing"}
end.
end_per_group(all_tcs, Config) ->
diff --git a/lib/snmp/test/snmp_app_test.erl b/lib/snmp/test/snmp_app_test.erl
index 6e7e85d3b4..5e69866f9a 100644
--- a/lib/snmp/test/snmp_app_test.erl
+++ b/lib/snmp/test/snmp_app_test.erl
@@ -23,366 +23,29 @@
%%----------------------------------------------------------------------
-module(snmp_app_test).
--export([
- all/0, groups/0,
- init_per_group/2, end_per_group/2,
- init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, end_per_testcase/2,
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
- fields/1,
- modules/1,
- exportall/1,
- app_depend/1,
-
- start_and_stop_empty/1,
- start_and_stop_with_agent/1,
- start_and_stop_with_manager/1,
- start_and_stop_with_agent_and_manager/1,
- start_epmty_and_then_agent_and_manager_and_stop/1,
- start_with_agent_and_then_manager_and_stop/1,
- start_with_manager_and_then_agent_and_stop/1
- ]).
-
-
--include_lib("kernel/include/file.hrl").
-include_lib("common_test/include/ct.hrl").
--include("snmp_test_lib.hrl").
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
all() ->
- Cases =
- [
- fields,
- modules,
- exportall,
- app_depend,
- {group, start_and_stop}
- ],
- Cases.
-
-groups() ->
- [{start_and_stop, [],
- [start_and_stop_empty,
- start_and_stop_with_agent,
- start_and_stop_with_manager,
- start_and_stop_with_agent_and_manager,
- start_epmty_and_then_agent_and_manager_and_stop,
- start_with_agent_and_then_manager_and_stop,
- start_with_manager_and_then_agent_and_stop]}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-init_per_suite(Config) when is_list(Config) ->
- ?DISPLAY_SUITE_INFO(),
-
- %% Note that part of this stuff (the suite top dir creation)
- %% may already be done (if we run the entire snmp suite).
-
- PrivDir = ?config(priv_dir, Config),
- TopDir = filename:join(PrivDir, app),
- case file:make_dir(TopDir) of
- ok ->
- ok;
- {error, eexist} ->
- ok;
- Error ->
- fail({failed_creating_subsuite_top_dir, Error})
- end,
- AppFile =
- case is_app() of
- {ok, File} ->
- io:format("File: ~n~p~n", [File]),
- snmp:print_version_info(),
- File;
- {error, Reason} ->
- fail(Reason)
- end,
- [{app_topdir, TopDir}, {app_file, AppFile} | Config].
-
-
-is_app() ->
- is_app(?APPLICATION).
-
-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.
-
-end_per_suite(suite) -> [];
-end_per_suite(doc) -> [];
-end_per_suite(Config) when is_list(Config) ->
- Config.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% Test server callbacks
-init_per_testcase(_Case, Config) ->
- Config.
-
-end_per_testcase(_Case, 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(snmp),
- case missing_modules(Mods, EbinList, []) of
- [] ->
- ok;
- Missing ->
- fail({missing_modules, Missing})
- end,
- Allowed = [snmpc,
- snmpc_lib,
- snmpc_misc,
- snmpc_mib_gram,
- snmpc_mib_to_hrl,
- snmpc_tok],
- case extra_modules(Mods, EbinList, Allowed, []) of
- [] ->
- ok;
- Extra ->
- fail({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, [], Allowed, Extra) ->
- Extra--Allowed;
-extra_modules(Mods, [Mod|Ebins], Allowed, Extra) ->
- case lists:member(Mod, Mods) of
- true ->
- extra_modules(Mods, Ebins, Allowed, Extra);
- false ->
- io:format("superfluous module: ~p~n", [Mod]),
- extra_modules(Mods, Ebins, Allowed, [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 ->
- fail({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.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-start_and_stop_empty(suite) ->
- [];
-start_and_stop_empty(doc) ->
- ["Start and stop the application empty (no configured components)"];
-start_and_stop_empty(Config) when is_list(Config) ->
- ?line false = ?IS_SNMP_RUNNING(),
-
- ?line ok = snmp:start(),
-
- ?line true = ?IS_SNMP_RUNNING(),
-
- ?line ok = snmp:stop(),
-
- ?line false = ?IS_SNMP_RUNNING(),
-
- ok.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-start_and_stop_with_agent(suite) ->
- [];
-start_and_stop_with_agent(doc) ->
- ["Start and stop the application with the agent pre-configured"];
-start_and_stop_with_agent(Config) when is_list(Config) ->
- ?SKIP(not_implemented_yet).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-start_and_stop_with_manager(suite) ->
- [];
-start_and_stop_with_manager(doc) ->
- ["Start and stop the application with the manager pre-configured"];
-start_and_stop_with_manager(Config) when is_list(Config) ->
- ?SKIP(not_implemented_yet).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-start_and_stop_with_agent_and_manager(suite) ->
- [];
-start_and_stop_with_agent_and_manager(doc) ->
- ["Start and stop the application with both the agent "
- "and the manager pre-configured"];
-start_and_stop_with_agent_and_manager(Config) when is_list(Config) ->
- ?SKIP(not_implemented_yet).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-start_epmty_and_then_agent_and_manager_and_stop(suite) ->
- [];
-start_epmty_and_then_agent_and_manager_and_stop(doc) ->
- ["Start the application empty, then start the agent and then "
- "the manager and then stop the application"];
-start_epmty_and_then_agent_and_manager_and_stop(Config) when is_list(Config) ->
- ?SKIP(not_implemented_yet).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-start_with_agent_and_then_manager_and_stop(suite) ->
- [];
-start_with_agent_and_then_manager_and_stop(doc) ->
- ["Start the application with the agent pre-configured, "
- "then start the manager and then stop the application"];
-start_with_agent_and_then_manager_and_stop(Config) when is_list(Config) ->
- ?SKIP(not_implemented_yet).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-start_with_manager_and_then_agent_and_stop(suite) ->
- [];
-start_with_manager_and_then_agent_and_stop(doc) ->
- ["Start the application with the manager pre-configured, "
- "then start the agent and then stop the application"];
-start_with_manager_and_then_agent_and_stop(Config) when is_list(Config) ->
- ?SKIP(not_implemented_yet).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-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.
+ [
+ app,
+ appup
+ ].
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+app() ->
+ [{doc, "Test that the snmp app file is ok"}].
+app(Config) when is_list(Config) ->
+ ok = test_server:app_test(snmp).
+%%--------------------------------------------------------------------
+appup() ->
+ [{doc, "Test that the snmp appup file is ok"}].
+appup(Config) when is_list(Config) ->
+ ok = test_server:appup_test(snmp).
diff --git a/lib/snmp/test/snmp_compiler_test.erl b/lib/snmp/test/snmp_compiler_test.erl
index 2c8851c2a7..9b3c2bfd2c 100644
--- a/lib/snmp/test/snmp_compiler_test.erl
+++ b/lib/snmp/test/snmp_compiler_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -56,7 +56,8 @@
otp_8574/1,
otp_8595/1,
otp_10799/1,
- otp_10808/1
+ otp_10808/1,
+ otp_14145/1
]).
@@ -135,7 +136,8 @@ all() ->
].
groups() ->
- [{tickets, [], [otp_6150, otp_8574, otp_8595, otp_10799, otp_10808]}].
+ [{tickets, [],
+ [otp_6150, otp_8574, otp_8595, otp_10799, otp_10808, otp_14145]}].
init_per_group(_GroupName, Config) ->
Config.
@@ -431,6 +433,30 @@ otp_10808(Config) when is_list(Config) ->
%%======================================================================
+otp_14145(suite) ->
+ [];
+otp_14145(Config) when is_list(Config) ->
+ put(tname, otp10808),
+ p("starting with Config: ~p~n", [Config]),
+
+ Dir = ?config(case_top_dir, Config),
+ MibDir = ?config(mib_dir, Config),
+ MibName = "OTP14145-MIB",
+ MibFile = join(MibDir, MibName++".mib"),
+ ?line {ok, MibBin} =
+ snmpc:compile(MibFile, [{outdir, Dir},
+ {verbosity, trace},
+ {group_check, false},
+ module_compliance]),
+ p("Mib: ~n~p~n", [MibBin]),
+ MIB = read_mib(MibBin),
+ Oid = [1,3,6,1,2,1,67,4],
+ check_mib(MIB#mib.mes, Oid, undefined),
+ ok.
+
+
+%%======================================================================
+
augments_extra_info(suite) ->
[];
augments_extra_info(Config) when is_list(Config) ->
diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl
index d17882e765..4bfeb0f8d1 100644
--- a/lib/snmp/test/snmp_manager_test.erl
+++ b/lib/snmp/test/snmp_manager_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -583,38 +583,38 @@ init_per_group(event_tests_mt = GroupName, Config) ->
GroupName,
[{manager_net_if_module, snmpm_net_if_mt} | Config]);
init_per_group(ipv6_mt = GroupName, Config) ->
+ {ok, Hostname0} = inet:gethostname(),
case ct:require(ipv6_hosts) of
ok ->
- case gen_udp:open(0, [inet6]) of
- {ok, S} ->
- ok = gen_udp:close(S),
+ case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts)) of
+ true ->
ipv6_init(
snmp_test_lib:init_group_top_dir(
GroupName,
[{manager_net_if_module, snmpm_net_if_mt}
| Config]));
- {error, _} ->
- {skip, "Host seems to not support IPv6"}
+ false ->
+ {skip, "Host does not support IPv6"}
end;
_ ->
- {skip, "Host does not support IPV6"}
+ {skip, "Test config ipv6_hosts is missing"}
end;
init_per_group(ipv6 = GroupName, Config) ->
+ {ok, Hostname0} = inet:gethostname(),
case ct:require(ipv6_hosts) of
ok ->
- case gen_udp:open(0, [inet6]) of
- {ok, S} ->
- ok = gen_udp:close(S),
+ case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts)) of
+ true ->
ipv6_init(snmp_test_lib:init_group_top_dir(GroupName, Config));
- {error, _} ->
- {skip, "Host seems to not support IPv6"}
+ false ->
+ {skip, "Host does not support IPv6"}
end;
_ ->
- {skip, "Host does not support IPV6"}
+ {skip, "Test config ipv6_hosts is missing"}
end;
init_per_group(GroupName, Config) ->
snmp_test_lib:init_group_top_dir(GroupName, Config).
-
+
end_per_group(_GroupName, Config) ->
%% Do we really need to do this?
lists:keydelete(snmp_group_top_dir, 1, Config).
@@ -1760,7 +1760,7 @@ do_simple_sync_get2(Node, TargetName, Oids, Get, PostVerify)
"~n Rem: ~w", [Reply, _Rem]),
%% verify that the operation actually worked:
- %% The order should be the same, so no need to seach
+ %% The order should be the same, so no need to search
?line ok = case Reply of
{noError, 0, [#varbind{oid = ?sysObjectID_instance,
value = SysObjectID},
@@ -2709,7 +2709,7 @@ do_simple_set2(Node, TargetName, VAVs, Set, PostVerify) ->
"~n Rem: ~w", [Reply, _Rem]),
%% verify that the operation actually worked:
- %% The order should be the same, so no need to seach
+ %% The order should be the same, so no need to search
%% The value we get should be exactly the same as we sent
?line ok = case Reply of
{noError, 0, [#varbind{oid = ?sysName_instance,
@@ -5118,10 +5118,10 @@ inform_swarm_collector(N) ->
%% Note that we need to deal with re-transmissions!
%% That is, the agent did not receive the ack in time,
-%% and therefor did a re-transmit. This means that we
-%% expect to receive more inform's then we actually
-%% sent. So for sucess we assume:
-%%
+%% and therefor did a re-transmit. This means that we
+%% expect to receive more inform's then we actually
+%% sent. So for success we assume:
+%%
%% SentAckCnt = N
%% RespCnt = N
%% RecvCnt >= N
diff --git a/lib/snmp/test/snmp_test_data/OTP14145-MIB.mib b/lib/snmp/test/snmp_test_data/OTP14145-MIB.mib
new file mode 100644
index 0000000000..f29c65c4c2
--- /dev/null
+++ b/lib/snmp/test/snmp_test_data/OTP14145-MIB.mib
@@ -0,0 +1,44 @@
+OTP14145-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+ MODULE-IDENTITY, OBJECT-TYPE,
+ mib-2 FROM SNMPv2-SMI
+ InetAddressType, InetAddress FROM INET-ADDRESS-MIB
+ MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF;
+
+testMibId MODULE-IDENTITY
+ LAST-UPDATED "200608210000Z" -- 21 August 2006
+ ORGANIZATION "a"
+ CONTACT-INFO "a"
+ DESCRIPTION "a"
+ REVISION "200608210000Z" -- 21 August 2006
+ DESCRIPTION "a"
+ ::= { mib-2 67 }
+
+testObj OBJECT-TYPE
+ SYNTAX InetAddressType
+ -- SYNTAX InetAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "a"
+ ::= { testMibId 2 }
+
+testObjId OBJECT IDENTIFIER ::= { testMibId 3 }
+
+testMibCompliance MODULE-COMPLIANCE
+ STATUS current
+ DESCRIPTION "a"
+ MODULE
+ OBJECT testObj
+ SYNTAX InetAddressType { ipv4(1), ipv6(2) }
+ -- SYNTAX InetAddress ( SIZE(4|16) )
+ DESCRIPTION "a"
+ ::= { testMibId 4 }
+
+testObjGroup OBJECT-GROUP
+ OBJECTS { testObj }
+ STATUS current
+ DESCRIPTION "a"
+ ::= { testObjId 1 }
+
+END
diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
index ac9e37bc8b..24c14d86ea 100644
--- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
+++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
@@ -121,14 +121,14 @@ init_per_group(_, Config) ->
Config.
init_per_group_ipv6(Families, Config) ->
+ {ok, Hostname0} = inet:gethostname(),
case ct:require(ipv6_hosts) of
ok ->
- case gen_udp:open(0, [inet6]) of
- {ok, S} ->
- ok = gen_udp:close(S),
+ case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts)) of
+ true ->
init_per_group_ip(Families, Config);
- {error, _} ->
- {skip, "Host seems to not support IPv6"}
+ false ->
+ {skip, "Host does not support IPv6"}
end;
_ ->
{skip, "Test config ipv6_hosts is missing"}
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index f95b428290..d41b1999cc 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
+# Copyright Ericsson AB 1997-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,6 +19,6 @@
# %CopyrightEnd%
APPLICATION = snmp
-SNMP_VSN = 5.2.3
+SNMP_VSN = 5.2.6
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)"
diff --git a/lib/ssh/doc/src/introduction.xml b/lib/ssh/doc/src/introduction.xml
index ca84528f3d..b7a73e2597 100644
--- a/lib/ssh/doc/src/introduction.xml
+++ b/lib/ssh/doc/src/introduction.xml
@@ -195,8 +195,6 @@
Transport Layer Protocol</item>
<item><url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url> -
Connection Protocol</item>
- <item><url href="http://www.ietf.org/rfc/rfc4255.txt">RFC 4255</url> -
- Key Fingerprints</item>
<item><url href="http://www.ietf.org/rfc/rfc4344.txt">RFC 4344</url> -
Transport Layer Encryption Modes</item>
<item><url href="http://www.ietf.org/rfc/rfc4716.txt">RFC 4716</url> -
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index fd15c334a3..f93753f1d2 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>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -30,6 +30,468 @@
<file>notes.xml</file>
</header>
+<section><title>Ssh 4.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The internal handling of SSH options is re-written.</p>
+ <p>
+ Previously there were no checks if a client option was
+ given to a daemon or vice versa. This is corrected now.
+ If your code has e.g. a client-only option in a call to
+ start a daemon, the call will fail.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12872</p>
+ </item>
+ <item>
+ <p>
+ Modernization of key exchange algorithms. See
+ draft-ietf-curdle-ssh-kex-sha2 for a discussion.</p>
+ <p>
+ Removed an outdated weak algorithm and added stronger
+ replacements to keep interoperability with other modern
+ ssh clients and servers. The default ordering of the
+ algorithms is also adjusted.</p>
+ <p>
+ Retired: The nowadays unsecure key-exchange
+ <c>diffie-hellman-group1-sha1</c> is not enabled by
+ default, but can be enabled with the option
+ <c>preferred-algorithms</c>.</p>
+ <p>
+ Added: The new stronger key-exchange
+ <c>diffie-hellman-group16-sha512</c>,
+ <c>diffie-hellman-group18-sha512</c> and
+ <c>diffie-hellman-group14-sha256</c> are added and
+ enabled by default.</p>
+ <p>
+ The questionable [RFC 6194] sha1-based algorithms
+ <c>diffie-hellman-group-exchange-sha1</c> and
+ <c>diffie-hellman-group14-sha1</c> are however still kept
+ enabled by default for compatibility with ancient clients
+ and servers that lack modern key-exchange alternatives.
+ When the draft-ietf-curdle-ssh-kex-sha2 becomes an rfc,
+ those sha1-based algorithms and
+ <c>diffie-hellman-group1-sha1</c> will be deprecated by
+ IETF. They might then be removed from the default list in
+ Erlang/OTP.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14110</p>
+ </item>
+ <item>
+ <p>
+ Modernized internal representation of sftp by use of
+ maps.</p>
+ <p>
+ Own Id: OTP-14117</p>
+ </item>
+ <item>
+ <p>
+ The Extension Negotiation Mechanism and the extension
+ <c>server-sig-algs</c> in
+ draft-ietf-curdle-ssh-ext-info-05 are implemented.</p>
+ <p>
+ The related draft-ietf-curdle-rsa-sha2-05 is implemented
+ and introduces the signature algorithms
+ <c>rsa-sha2-256</c> and <c>rsa-sha2-512</c>.</p>
+ <p>
+ Own Id: OTP-14193</p>
+ </item>
+ <item>
+ <p>
+ The 'timeout' and 'connect_timeout' handling in
+ ssh_sftp:start_channel documentation is clarified.</p>
+ <p>
+ Own Id: OTP-14216</p>
+ </item>
+ <item>
+ <p>
+ The functions <c>ssh:connect</c>, <c>ssh:shell</c> and
+ <c>ssh:start_channel</c> now accept an IP-tuple as Host
+ destination argument.</p>
+ <p>
+ Own Id: OTP-14243</p>
+ </item>
+ <item>
+ <p>
+ The function <c>ssh:daemon_info/1</c> now returns Host
+ and Profile as well as the Port info in the property
+ list.</p>
+ <p>
+ Own Id: OTP-14259</p>
+ </item>
+ <item>
+ <p>
+ Removed the option <c>public_key_alg</c> which was
+ deprecated in 18.2. Use <c>pref_public_key_algs</c>
+ instead.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14263</p>
+ </item>
+ <item>
+ <p>
+ The SSH application is refactored regarding daemon
+ starting. The resolution of contradicting <c>Host</c>
+ argument and <c>ip</c> option were not described. There
+ were also strange corner cases when the <c>'any'</c>
+ value was used in <c>Host</c> argument or <c>ip</c>
+ option. This is (hopefully) resolved now, but it may
+ cause incompatibilities for code using both <c>Host</c>
+ and the <c>ip</c> option. The value 'loopback' has been
+ added for a correct way of naming those addresses.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14264</p>
+ </item>
+ <item>
+ <p>
+ The supervisor code is refactored. The naming of
+ listening IP-Port-Profile triples are slightly changed to
+ improve consistency in strange corner cases as resolved
+ by OTP-14264</p>
+ <p>
+ Own Id: OTP-14267 Aux Id: OTP-14266 </p>
+ </item>
+ <item>
+ <p>
+ The <c>idle_time</c> option can now be used in daemons.</p>
+ <p>
+ Own Id: OTP-14312</p>
+ </item>
+ <item>
+ <p>
+ Added test cases for IETF-CURDLE Extension Negotiation
+ (ext-info)</p>
+ <p>
+ Own Id: OTP-14361</p>
+ </item>
+ <item>
+ <p>
+ Testcases for IETF-CURDLE extension
+ <c>server-sig-algs</c> including <c>rsa-sha2-*</c></p>
+ <p>
+ Own Id: OTP-14362 Aux Id: OTP-14361 </p>
+ </item>
+ <item>
+ <p>
+ The option <c>auth_methods</c> can now also be used in
+ clients to select which authentication options that are
+ used and in which order.</p>
+ <p>
+ Own Id: OTP-14399</p>
+ </item>
+ <item>
+ <p>
+ Checks that a ECDSA public key (<c>ecdsa-sha2-nistp*</c>)
+ stored in a file has the correct size.</p>
+ <p>
+ Own Id: OTP-14410</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.4.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ ssh:daemon_info/1 crashed if the listening IP was not
+ 'any'</p>
+ <p>
+ Own Id: OTP-14298 Aux Id: seq13294 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.4.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix bug when opening connections. If the tcp setup
+ failed, that would in some cases not result in an error
+ return value.</p>
+ <p>
+ Own Id: OTP-14108</p>
+ </item>
+ <item>
+ <p>
+ Reduce information leakage in case of decryption errors.</p>
+ <p>
+ Own Id: OTP-14109</p>
+ </item>
+ <item>
+ <p>
+ The key exchange algorithm
+ diffie-hellman-group-exchange-sha* has a server-option
+ <c>{dh_gex_limits,{Min,Max}}</c>. There was a hostkey
+ signature validation error on the client side if the
+ option was used and the <c>Min</c> or the <c>Max</c>
+ differed from the corresponding values obtained from the
+ client.</p>
+ <p>
+ This bug is now corrected.</p>
+ <p>
+ Own Id: OTP-14166</p>
+ </item>
+ <item>
+ <p>
+ The sftpd server now correctly uses <c>root_dir</c> and
+ <c>cwd</c> when resolving file paths if both are
+ provided. The <c>cwd</c> handling is also corrected.</p>
+ <p>
+ Thanks to kape1395!</p>
+ <p>
+ Own Id: OTP-14225 Aux Id: PR-1331, PR-1335 </p>
+ </item>
+ <item>
+ <p>
+ Ssh_cli used a function that does not handle non-utf8
+ unicode correctly.</p>
+ <p>
+ Own Id: OTP-14230 Aux Id: ERL-364 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The implementation of the key exchange algorithms
+ diffie-hellman-group-exchange-sha* are optimized, up to a
+ factor of 11 for the slowest ( = biggest and safest)
+ group size.</p>
+ <p>
+ Own Id: OTP-14169 Aux Id: seq-13261 </p>
+ </item>
+ <item>
+ <p>
+ The ssh host key fingerprint generation now also takes a
+ list of algorithms and returns a list of corresponding
+ fingerprints. See
+ <c>public_key:ssh_hostkey_fingerprint/2</c> and the
+ option <c>silently_accept_hosts</c> in
+ <c>ssh:connect</c>.</p>
+ <p>
+ Own Id: OTP-14223</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A file read with an sftp client could loose data if the
+ packet_size is set to larger than 64k. This is corrected
+ now in such a way that the packet_size is silently
+ lowered if there is a risk for data loss.</p>
+ <p>
+ Own Id: OTP-13857 Aux Id: ERL-238, OTP-13858 </p>
+ </item>
+ <item>
+ <p>
+ When user defined SSH shell REPL process exits with
+ reason normal, the SSH channel callback module should
+ report successful exit status to the SSH client. This
+ provides simple way for SSH clients to check for
+ successful completion of executed commands. (Thanks to
+ isvilen)</p>
+ <p>
+ Own Id: OTP-13905 Aux Id: PR-1173 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Extended the option <c>silently_accept_hosts</c> for
+ <c>ssh:connect</c> to make it possible for the client to
+ check the SSH host key fingerprint string. Se the
+ reference manual for SSH.</p>
+ <p>
+ Own Id: OTP-13887 Aux Id: OTP-13888 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.3.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Re-negotiation problems with OpenSSH client solved.</p>
+ <p>
+ Own Id: OTP-13972</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.3.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ If a client illegaly sends an info-line and then
+ immediatly closes the TCP-connection, a badmatch
+ exception was raised.</p>
+ <p>
+ Own Id: OTP-13966</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.3.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Intermittent ssh ERROR REPORT mentioning
+ nonblocking_sender</p>
+ <p>
+ Own Id: OTP-13953 Aux Id: seq13199 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.3.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Handle all possible exit values that should be
+ interpreted as {error, closed}. Failing to do so could
+ lead to unexpected crashes for users of the ssh
+ application.</p>
+ <p>
+ Own Id: OTP-13932 Aux Id: seq13189 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.3.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Upgrade of an established client connection could crash
+ because the ssh client supervisors children had wrong
+ type. This is fixed now.</p>
+ <p>
+ Own Id: OTP-13782 Aux Id: seq13158 </p>
+ </item>
+ <item>
+ <p>
+ Partly checks the public key early in public key
+ authorization</p>
+ <p>
+ Own Id: OTP-13847 Aux Id:
+ defensics-ssh3.1.0-190243,205277,219318 </p>
+ </item>
+ <item>
+ <p>
+ Corrected handling of SHA for ECDSA (Elliptic curve
+ public keys)</p>
+ <p>
+ Own Id: OTP-13850 Aux Id: defensics-ssh3.1.0-214168 </p>
+ </item>
+ <item>
+ <p>
+ Problems found by test suites as well as by
+ Codenomicon/Defensics fixed: - reduce max random padding
+ to 15 bytes (Codenomicon/Defensics) - inclomplete pdu
+ handling (Codenomicon/Defensics) - badmatch in test suite
+ - non-blocking send fixes deadlock in
+ ssh_connection_SUITE:interrupted_send</p>
+ <p>
+ Own Id: OTP-13854</p>
+ </item>
+ <item>
+ <p>
+ Caller is now notified when a tcp close is received.</p>
+ <p>
+ Own Id: OTP-13859 Aux Id: seq13177 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Use application:ensure_all_started/2 instead of
+ hard-coding deps</p>
+ <p>
+ Own Id: OTP-13843 Aux Id: PR-1147 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ SSH client does not any longer retry a bad password given
+ as option to ssh:connect et al.</p>
+ <p>
+ Own Id: OTP-13674 Aux Id: TR-HU92273 </p>
+ </item>
+ <item>
+ <p>
+ Removed possible hanging risk for a certain timing
+ sequence when communicating client and server executes on
+ the same node.</p>
+ <p>
+ Own Id: OTP-13715</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ssh 4.3</title>
<section><title>Improvements and New Features</title>
@@ -108,6 +570,22 @@
</section>
+<section><title>Ssh 4.2.2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ SSH client does not any longer retry a bad password given
+ as option to ssh:connect et al.</p>
+ <p>
+ Own Id: OTP-13674 Aux Id: TR-HU92273 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ssh 4.2.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index e6c54d27bf..ea7e975ef5 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2015</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -153,7 +153,7 @@
<item>
<p>IP version to use.</p>
</item>
- <tag><c><![CDATA[{user_dir, string()}]]></c></tag>
+ <tag><marker id="opt_user_dir"></marker><c><![CDATA[{user_dir, string()}]]></c></tag>
<item>
<p>Sets the user directory, that is, the directory containing
<c>ssh</c> configuration files for the user, such as
@@ -175,12 +175,48 @@
supplied with this option.
</p>
</item>
- <tag><c><![CDATA[{silently_accept_hosts, boolean()}]]></c></tag>
+ <tag>
+ <c><![CDATA[{silently_accept_hosts, boolean()}]]></c> <br/>
+ <c><![CDATA[{silently_accept_hosts, CallbackFun}]]></c> <br/>
+ <c><![CDATA[{silently_accept_hosts, {HashAlgoSpec, CallbackFun} }]]></c> <br/>
+ <br/>
+ <c><![CDATA[HashAlgoSpec = crypto:digest_type() | [ crypto:digest_type() ] ]]></c><br/>
+ <c><![CDATA[CallbackFun = fun(PeerName, FingerPrint) -> boolean()]]></c><br/>
+ <c><![CDATA[PeerName = string()]]></c><br/>
+ <c><![CDATA[FingerPrint = string() | [ string() ] ]]></c>
+ </tag>
<item>
- <p>When <c>true</c>, hosts are added to the
- file <c><![CDATA[known_hosts]]></c> without asking the user.
- Defaults to <c>false</c>.
- </p>
+ <p>This option guides the <c>connect</c> function how to act when the connected server presents a Host
+ Key that the client has not seen before. The default is to ask the user with a question on stdio of whether to
+ accept or reject the new Host Key.
+ See also the option <seealso marker="#opt_user_dir"><c>user_dir</c></seealso>
+ for the path to the file <c>known_hosts</c> where previously accepted Host Keys are recorded.
+ </p>
+ <p>The option can be given in three different forms as seen above:</p>
+ <list>
+ <item>The value is a <c>boolean()</c>. The value <c>true</c> will make the client accept any unknown
+ Host Key without any user interaction. The value <c>false</c> keeps the default behaviour of asking the
+ the user on stdio.
+ </item>
+ <item>A <c>CallbackFun</c> will be called and the boolean return value <c>true</c> will make the client
+ accept the Host Key. A return value of <c>false</c> will make the client to reject the Host Key and therefore
+ also the connection will be closed. The arguments to the fun are:
+ <list type="bulleted">
+ <item><c>PeerName</c> - a string with the name or address of the remote host.</item>
+ <item><c>FingerPrint</c> - the fingerprint of the Host Key as
+ <seealso marker="public_key:public_key#ssh_hostkey_fingerprint-1">public_key:ssh_hostkey_fingerprint/1</seealso>
+ calculates it.
+ </item>
+ </list>
+ </item>
+ <item>A tuple <c>{HashAlgoSpec, CallbackFun}</c>. The <c>HashAlgoSpec</c> specifies which hash algorithm
+ shall be used to calculate the fingerprint used in the call of the <c>CallbackFun</c>. The <c>HashALgoSpec</c>
+ is either an atom or a list of atoms as the first argument in
+ <seealso marker="public_key:public_key#ssh_hostkey_fingerprint-2">public_key:ssh_hostkey_fingerprint/2</seealso>.
+ If it is a list of hash algorithm names, the <c>FingerPrint</c> argument in the <c>CallbackFun</c> will be
+ a list of fingerprints in the same order as the corresponding name in the <c>HashAlgoSpec</c> list.
+ </item>
+ </list>
</item>
<tag><c><![CDATA[{user_interaction, boolean()}]]></c></tag>
<item>
@@ -190,7 +226,7 @@
supplying a password. Defaults to <c>true</c>.
Even if user interaction is allowed it can be
suppressed by other options, such as <c>silently_accept_hosts</c>
- and <c>password</c>. However, those optins are not always desirable
+ and <c>password</c>. However, those options are not always desirable
to use from a security point of view.</p>
</item>
@@ -207,28 +243,15 @@
<p><c>Peer</c> is in the format of <c>{Host,Port}</c>.</p>
</item>
- <tag><c><![CDATA[{public_key_alg, 'ssh-rsa' | 'ssh-dss'}]]></c></tag>
- <item>
- <note>
- <p>This option will be removed in OTP 20, but is kept for compatibility. It is ignored if
- the preferred <c>pref_public_key_algs</c> option is used.</p>
- </note>
- <p>Sets the preferred public key algorithm to use for user
- authentication. If the preferred algorithm fails,
- the other algorithm is tried. If <c>{public_key_alg, 'ssh-rsa'}</c> is set, it is translated
- to <c>{pref_public_key_algs, ['ssh-rsa','ssh-dss']}</c>. If it is
- <c>{public_key_alg, 'ssh-dss'}</c>, it is translated
- to <c>{pref_public_key_algs, ['ssh-dss','ssh-rsa']}</c>.
- </p>
- </item>
-
<tag><c><![CDATA[{pref_public_key_algs, list()}]]></c></tag>
<item>
<p>List of user (client) public key algorithms to try to use.</p>
- <p>The default value is
- <c><![CDATA[['ssh-rsa','ssh-dss','ecdsa-sha2-nistp256','ecdsa-sha2-nistp384','ecdsa-sha2-nistp521'] ]]></c>
+ <p>The default value is the <c>public_key</c> entry in
+ <seealso marker="#default_algorithms/0">ssh:default_algorithms/0</seealso>.
+ </p>
+ <p>If there is no public key of a specified type available, the corresponding entry is ignored.
+ Note that the available set is dependent on the underlying cryptolib and current user's public keys.
</p>
- <p>If there is no public key of a specified type available, the corresponding entry is ignored.</p>
</item>
<tag><c><![CDATA[{preferred_algorithms, algs_list()}]]></c></tag>
@@ -272,6 +295,15 @@
connection. For <c>gen_tcp</c> the time is in milli-seconds and the default value is
<c>infinity</c>.</p>
</item>
+
+ <tag><c><![CDATA[{auth_methods, string()}]]></c></tag>
+ <item>
+ <p>Comma-separated string that determines which
+ authentication methods that the client shall support and
+ in which order they are tried. Defaults to
+ <c><![CDATA["publickey,keyboard-interactive,password"]]></c></p>
+ </item>
+
<tag><c><![CDATA[{user, string()}]]></c></tag>
<item>
<p>Provides a username. If this option is not given, <c>ssh</c>
@@ -279,6 +311,7 @@
<c><![CDATA[USER]]></c> on UNIX,
<c><![CDATA[USERNAME]]></c> on Windows).</p>
</item>
+
<tag><c><![CDATA[{password, string()}]]></c></tag>
<item>
<p>Provides a password for password authentication.
@@ -286,6 +319,30 @@
password, if the password authentication method is
attempted.</p>
</item>
+
+ <!--tag><c><![CDATA[{send_ext_info, boolean()}]]></c></tag>
+ <item>
+ <p>Send a list of extensions to the server if the server has asked for it. See
+ <url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-ext-info">Draft-ietf-curdle-ssh-ext-info (work in progress)</url> for details.
+ </p>
+ <p>Currently the client do not react on any extensions.
+ </p>
+ <p>Default value is <c>true</c>.
+ </p>
+ </item-->
+
+ <tag><c><![CDATA[{recv_ext_info, boolean()}]]></c></tag>
+ <item>
+ <p>Tell the server that the client accepts extension negotiation. See
+ <url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-ext-info">Draft-ietf-curdle-ssh-ext-info (work in progress)</url> for details.
+ </p>
+ <p>Currently implemented extension is <c>server-sig-algs</c> which is the list of the server's preferred
+ user's public key algorithms.
+ </p>
+ <p>Default value is <c>true</c>.
+ </p>
+ </item>
+
<tag><c><![CDATA[{key_cb, key_cb()}]]></c></tag>
<item>
<p>Module implementing the behaviour <seealso
@@ -295,6 +352,7 @@
module via the options passed to it under the key 'key_cb_private'.
</p>
</item>
+
<tag><c><![CDATA[{quiet_mode, atom() = boolean()}]]></c></tag>
<item>
<p>If <c>true</c>, the client does not print anything on authorization.</p>
@@ -358,7 +416,7 @@
on the given port.</fsummary>
<type>
<v>Port = integer()</v>
- <v>HostAddress = ip_address() | any</v>
+ <v>HostAddress = ip_address() | any | loopback</v>
<v>Options = [{Option, Value}]</v>
<v>Option = atom()</v>
<v>Value = term()</v>
@@ -369,6 +427,26 @@
<p>Starts a server listening for SSH connections on the given
port. If the <c>Port</c> is 0, a random free port is selected. See
<seealso marker="#daemon_info/1">daemon_info/1</seealso> about how to find the selected port number.</p>
+
+ <p>Please note that by historical reasons both the <c>HostAddress</c> argument and the inet socket option
+ <c>ip</c> set the listening address. This is a source of possible inconsistent settings.</p>
+
+ <p>The rules for handling the two address passing options are:</p>
+ <list>
+ <item>if <c>HostAddress</c> is an IP-address, that IP-address is the listening address.
+ An 'ip'-option will be discarded if present.</item>
+
+ <item>if <c>HostAddress</c> is <c>loopback</c>, the listening address
+ is <c>loopback</c> and an loopback address will be choosen by the underlying layers.
+ An 'ip'-option will be discarded if present.</item>
+
+ <item>if <c>HostAddress</c> is <c>any</c> and no 'ip'-option is present, the listening address is
+ <c>any</c> and the socket will listen to all addresses</item>
+
+ <item>if <c>HostAddress</c> is <c>any</c> and an 'ip'-option is present, the listening address is
+ set to the value of the 'ip'-option</item>
+ </list>
+
<p>Options:</p>
<taglist>
<tag><c><![CDATA[{inet, inet | inet6}]]></c></tag>
@@ -425,6 +503,7 @@
authentication methods that the server is to support and
in what order they are tried. Defaults to
<c><![CDATA["publickey,keyboard-interactive,password"]]></c></p>
+ <p>Note that the client is free to use any order and to exclude methods.</p>
</item>
<tag><c><![CDATA[{auth_method_kb_interactive_data, PromptTexts}]]></c>
@@ -629,6 +708,27 @@
</p>
</item>
+ <tag><c><![CDATA[{send_ext_info, boolean()}]]></c></tag>
+ <item>
+ <p>Send a list of extensions to the client if the client has asked for it. See
+ <url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-ext-info">Draft-ietf-curdle-ssh-ext-info (work in progress)</url> for details.
+ </p>
+ <p>Currently implemented extension is sending <c>server-sig-algs</c> which is the list of the server's preferred
+ user's public key algorithms.
+ </p>
+ <p>Default value is <c>true</c>.
+ </p>
+ </item>
+
+ <!--tag><c><![CDATA[{recv_ext_info, boolean()}]]></c></tag>
+ <item>
+ <p>Tell the client that the server accepts extension negotiation. See
+ <url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-ext-info">Draft-ietf-curdle-ssh-ext-info (work in progress)</url> for details.
+ </p>
+ <p>Default value is <c>true</c>.
+ </p>
+ </item-->
+
<tag><c><![CDATA[{key_cb, key_cb()}]]></c></tag>
<item>
<p>Module implementing the behaviour <seealso
@@ -678,6 +778,12 @@
<p><c>Peer</c> is in the format of <c>{Host,Port}</c>.</p>
</item>
+ <tag><c><![CDATA[{idle_time, integer()}]]></c></tag>
+ <item>
+ <p>Sets a time-out on a connection when no channels are active.
+ Defaults to <c>infinity</c>.</p>
+ </item>
+
<tag><c><![CDATA[{ssh_msg_debug_fun, fun(ConnectionRef::ssh_connection_ref(), AlwaysDisplay::boolean(), Msg::binary(), LanguageTag::binary()) -> _}]]></c></tag>
<item>
<p>Provide a fun to implement your own logging of the SSH message SSH_MSG_DEBUG. The last three parameters are from the message, see RFC4253, section 11.3. The <c>ConnectionRef</c> is the reference to the connection on which the message arrived. The return value from the fun is not checked.</p>
@@ -690,9 +796,10 @@
</func>
<func>
- <name>daemon_info(Daemon) -> {ok, [{port,Port}]} | {error,Error}</name>
+ <name>daemon_info(Daemon) -> {ok, [DaemonInfo]} | {error,Error}</name>
<fsummary>Get info about a daemon</fsummary>
<type>
+ <v>DaemonInfo = {port,Port::pos_integer()} | {listen_address, any|ip_address()} | {profile,atom()}</v>
<v>Port = integer()</v>
<v>Error = bad_daemon_ref</v>
</type>
@@ -756,7 +863,7 @@
<p>Utility function that starts the applications <c>crypto</c>, <c>public_key</c>,
and <c>ssh</c>. Default type is <c>temporary</c>.
For more information, see the <seealso marker="kernel:application">application(3)</seealso>
- manual page in <c>kernel</c>.</p>
+ manual page in Kernel.</p>
</desc>
</func>
@@ -769,7 +876,7 @@
<desc>
<p>Stops the <c>ssh</c> application.
For more information, see the <seealso marker="kernel:application">application(3)</seealso>
- manual page in <c>kernel</c>.</p>
+ manual page in Kernel.</p>
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_app.xml b/lib/ssh/doc/src/ssh_app.xml
index f6ce44c015..33ec7aaee0 100644
--- a/lib/ssh/doc/src/ssh_app.xml
+++ b/lib/ssh/doc/src/ssh_app.xml
@@ -4,7 +4,7 @@
<appref>
<header>
<copyright>
- <year>2012</year><year>2015</year>
+ <year>2012</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -109,7 +109,7 @@
</section>
<section>
<title>Host Keys</title>
- <p>RSA and DSA host keys are supported and are
+ <p>RSA, DSA and ECDSA host keys are supported and are
expected to be found in files named <c>ssh_host_rsa_key</c>,
<c>ssh_host_dsa_key</c> and <c>ssh_host_ecdsa_key</c>.
</p>
@@ -146,7 +146,10 @@
<item>diffie-hellman-group-exchange-sha1</item>
<item>diffie-hellman-group-exchange-sha256</item>
<item>diffie-hellman-group14-sha1</item>
- <item>diffie-hellman-group1-sha1</item>
+ <item>diffie-hellman-group14-sha256</item>
+ <item>diffie-hellman-group16-sha512</item>
+ <item>diffie-hellman-group18-sha512</item>
+ <item>(diffie-hellman-group1-sha1, retired: can be enabled with the <c>preferred_algorithms</c> option)</item>
</list>
</item>
@@ -158,6 +161,8 @@
<item>ecdsa-sha2-nistp521</item>
<item>ssh-rsa</item>
<item>ssh-dss</item>
+ <item>rsa-sha2-256</item>
+ <item>rsa-sha2-512</item>
</list>
</item>
@@ -173,21 +178,23 @@
<tag>Encryption algorithms (ciphers)</tag>
<item>
<list type="bulleted">
- <item>[email protected] (AEAD_AES_128_GCM)</item>
- <item>[email protected] (AEAD_AES_256_GCM)</item>
+ <item>[email protected]</item>
+ <item>[email protected]</item>
<item>aes128-ctr</item>
<item>aes192-ctr</item>
<item>aes256-ctr</item>
<item>aes128-cbc</item>
<item>3des-cbc</item>
+ <item>(AEAD_AES_128_GCM, not enabled per default)</item>
+ <item>(AEAD_AES_256_GCM, not enabled per default)</item>
</list>
+ <p>See the text at the description of <seealso marker="#rfc5647_note">the rfc 5647 further down</seealso>
+ for more information regarding AEAD_AES_*_GCM.
+ </p>
<p>Following the internet de-facto standard, the cipher and mac algorithm AEAD_AES_128_GCM is selected when the
cipher [email protected] is negotiated. The cipher and mac algorithm AEAD_AES_256_GCM is selected when the
cipher [email protected] is negotiated.
</p>
- <p>See the text at the description of <seealso marker="#rfc5647_note">the rfc 5647 further down</seealso>
- for more information.
- </p>
</item>
<tag>Compression algorithms</tag>
@@ -203,7 +210,7 @@
<section>
<title>Unicode support</title>
<p>Unicode filenames are supported if the emulator and the underlaying OS support it. See section DESCRIPTION in the
- <seealso marker="kernel:file">file</seealso> manual page in <c>kernel</c> for information about this subject.
+ <seealso marker="kernel:file">file</seealso> manual page in Kernel for information about this subject.
</p>
<p>The shell and the cli both support unicode.
</p>
@@ -232,7 +239,11 @@
</item>
<item><url href="https://tools.ietf.org/html/rfc4253">RFC 4253</url>, The Secure Shell (SSH) Transport Layer Protocol.
- <p></p>
+ <p>Except</p>
+ <list type="bulleted">
+ <item>8.1. diffie-hellman-group1-sha1. Disabled by default, can be enabled with the <c>preferred_algorithms</c> option.</item>
+ </list>
+ <p/>
</item>
<item><url href="https://tools.ietf.org/html/rfc4254">RFC 4254</url>, The Secure Shell (SSH) Connection Protocol.
@@ -306,6 +317,30 @@
<p>Comment: Defines hmac-sha2-256 and hmac-sha2-512
</p>
</item>
+
+ <item><url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-kex-sha2">Draft-ietf-curdle-ssh-kex-sha2 (work in progress)</url>, Key Exchange (KEX) Method Updates and Recommendations for Secure Shell (SSH).
+ <p>Deviations:</p>
+ <list type="bulleted">
+ <item>The <c>diffie-hellman-group1-sha1</c> is not enabled by default, but is still supported and can be enabled
+ with the option <c>preferred-algorithms</c></item>
+ <item>The questionable sha1-based algorithms <c>diffie-hellman-group-exchange-sha1</c> and
+ <c>diffie-hellman-group14-sha1</c> are still enabled by default for compatibility with ancient clients and servers.
+ They can be disabled with the option <c>preferred-algorithms</c></item>
+ </list>
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/draft-ietf-curdle-rsa-sha2">Draft-ietf-curdle-rsa-sha2 (work in progress)</url>, Use of RSA Keys with SHA-2 256 and 512 in Secure Shell (SSH).
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-ext-info">Draft-ietf-curdle-ssh-ext-info (work in progress)</url>, Extension Negotiation in Secure Shell (SSH).
+ <p>Implemented are:</p>
+ <list type="bulleted">
+ <item>The Extension Negotiation Mechanism</item>
+ <item>The extension <c>server-sig-algs</c></item>
+ </list>
+ <p/>
+ </item>
</list>
diff --git a/lib/ssh/doc/src/ssh_channel.xml b/lib/ssh/doc/src/ssh_channel.xml
index 907b0b3bec..7b598494f7 100644
--- a/lib/ssh/doc/src/ssh_channel.xml
+++ b/lib/ssh/doc/src/ssh_channel.xml
@@ -139,7 +139,7 @@
enters the <c>ssh_channel</c> process receive loop and become an
<c>ssh_channel process</c>. The process must have been started using
one of the start functions in <c>proc_lib</c>, see the <seealso
- marker="stdlib:proc_lib">proc_lib(3)</seealso> manual page in <c>stdlib</c>.
+ marker="stdlib:proc_lib">proc_lib(3)</seealso> manual page in STDLIB.
The user is responsible for any initialization of the process
and must call <seealso marker = "#init-1">ssh_channel:init/1</seealso>.
</p>
diff --git a/lib/ssh/doc/src/ssh_protocol.xml b/lib/ssh/doc/src/ssh_protocol.xml
index 7288266cf7..a0032ab449 100644
--- a/lib/ssh/doc/src/ssh_protocol.xml
+++ b/lib/ssh/doc/src/ssh_protocol.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2013</year><year>2013</year>
+ <year>2013</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -138,8 +138,6 @@
Transport Layer Protocol.</item>
<item><url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url> -
Connection Protocol.</item>
- <item><url href="http://www.ietf.org/rfc/rfc4255.txt">RFC 4255</url> -
- Key Fingerprints.</item>
<item><url href="http://www.ietf.org/rfc/rfc4344.txt">RFC 4344</url> -
Transport Layer Encryption Modes.</item>
<item><url href="http://www.ietf.org/rfc/rfc4716.txt">RFC 4716</url> -
diff --git a/lib/ssh/doc/src/ssh_sftp.xml b/lib/ssh/doc/src/ssh_sftp.xml
index eb6f43d417..ed7fbf9cf3 100644
--- a/lib/ssh/doc/src/ssh_sftp.xml
+++ b/lib/ssh/doc/src/ssh_sftp.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2005</year><year>2016</year>
+ <year>2005</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -558,8 +558,14 @@
<taglist>
<tag><c><![CDATA[{timeout, timeout()}]]></c></tag>
<item>
- <p>The time-out is passed to the <c>ssh_channel</c> start function,
- and defaults to <c>infinity</c>.</p>
+ <p>There are two ways to set a timeout for the underlying ssh connection:</p>
+ <list>
+ <item>If the connection timeout option <c>connect_timeout</c> is set, that value
+ is used also for the negotiation timeout and this option (<c>timeout</c>) is ignored.</item>
+ <item>Otherwise, this option (<c>timeout</c>) is used as the negotiation timeout
+ only and there is no connection timeout set</item>
+ </list>
+ <p>The value defaults to <c>infinity</c>.</p>
</item>
<tag>
<c><![CDATA[{sftp_vsn, integer()}]]></c>
diff --git a/lib/ssh/doc/src/using_ssh.xml b/lib/ssh/doc/src/using_ssh.xml
index 0861c641c7..ab307624e6 100644
--- a/lib/ssh/doc/src/using_ssh.xml
+++ b/lib/ssh/doc/src/using_ssh.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2012</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -305,7 +305,7 @@ ok = erl_tar:close(HandleRead),
<code type="erl" >
-module(ssh_echo_server).
--behaviour(ssh_subsystem).
+-behaviour(ssh_daemon_channel).
-record(state, {
n,
id,
diff --git a/lib/ssh/src/Makefile b/lib/ssh/src/Makefile
index 69d5a47f83..9e8d80c71f 100644
--- a/lib/ssh/src/Makefile
+++ b/lib/ssh/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2016. All Rights Reserved.
+# Copyright Ericsson AB 2004-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -51,6 +51,7 @@ MODULES= \
ssh_sup \
sshc_sup \
sshd_sup \
+ ssh_options \
ssh_connection_sup \
ssh_connection \
ssh_connection_handler \
@@ -96,7 +97,7 @@ APP_TARGET= $(EBIN)/$(APP_FILE)
APPUP_SRC= $(APPUP_FILE).src
APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
-INTERNAL_HRL_FILES = ssh_auth.hrl ssh_connect.hrl ssh_transport.hrl ssh.hrl ssh_userauth.hrl ssh_xfer.hrl
+INTERNAL_HRL_FILES = ssh_auth.hrl ssh_connect.hrl ssh_transport.hrl ssh.hrl ssh_userauth.hrl ssh_xfer.hrl ssh_dbg.hrl
# ----------------------------------------------------
# FLAGS
diff --git a/lib/ssh/src/ssh.app.src b/lib/ssh/src/ssh.app.src
index 3245ba5197..974292fde1 100644
--- a/lib/ssh/src/ssh.app.src
+++ b/lib/ssh/src/ssh.app.src
@@ -7,6 +7,7 @@
ssh_app,
ssh_acceptor,
ssh_acceptor_sup,
+ ssh_options,
ssh_auth,
ssh_message,
ssh_bits,
@@ -41,11 +42,10 @@
{env, []},
{mod, {ssh_app, []}},
{runtime_dependencies, [
- "crypto-3.3",
+ "crypto-3.7.3",
"erts-6.0",
"kernel-3.0",
- "public_key-1.1",
- "stdlib-3.0"
+ "public_key-1.4",
+ "stdlib-3.3"
]}]}.
-
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index e38cecf226..2540720c41 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -1,7 +1,7 @@
%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,9 +20,13 @@
{"%VSN%",
[
+ {<<"4.3.2">>, [{load_module, ssh_channel, soft_purge, soft_purge, []}
+ ]},
{<<".*">>, [{restart_application, ssh}]}
],
[
+ {<<"4.3.2">>, [{load_module, ssh_channel, soft_purge, soft_purge, []}
+ ]},
{<<".*">>, [{restart_application, ssh}]}
]
}.
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 0570853a9b..5ebab43c30 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -1,7 +1,7 @@
%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
-include("ssh_connect.hrl").
-include_lib("public_key/include/public_key.hrl").
-include_lib("kernel/include/file.hrl").
+-include_lib("kernel/include/inet.hrl").
-export([start/0, start/1, stop/0,
connect/2, connect/3, connect/4,
@@ -40,10 +41,24 @@
]).
%%% Type exports
--export_type([connection_ref/0,
- channel_id/0
+-export_type([ssh_daemon_ref/0,
+ ssh_connection_ref/0,
+ ssh_channel_id/0,
+ role/0,
+ subsystem_spec/0,
+ subsystem_name/0,
+ channel_callback/0,
+ channel_init_args/0,
+ algs_list/0,
+ alg_entry/0,
+ simple_algs/0,
+ double_algs/0
]).
+-opaque ssh_daemon_ref() :: daemon_ref() .
+-opaque ssh_connection_ref() :: connection_ref() .
+-opaque ssh_channel_id() :: channel_id().
+
%%--------------------------------------------------------------------
-spec start() -> ok | {error, term()}.
-spec start(permanent | transient | temporary) -> ok | {error, term()}.
@@ -52,16 +67,15 @@
%% is temporary. see application(3)
%%--------------------------------------------------------------------
start() ->
- application:start(crypto),
- application:start(asn1),
- application:start(public_key),
- application:start(ssh).
+ start(temporary).
start(Type) ->
- application:start(crypto, Type),
- application:start(asn1),
- application:start(public_key, Type),
- application:start(ssh, Type).
+ case application:ensure_all_started(ssh, Type) of
+ {ok, _} ->
+ ok;
+ Other ->
+ Other
+ end.
%%--------------------------------------------------------------------
-spec stop() -> ok | {error, term()}.
@@ -72,55 +86,63 @@ stop() ->
application:stop(ssh).
%%--------------------------------------------------------------------
--spec connect(port(), proplists:proplist()) -> {ok, pid()} | {error, term()}.
+-spec connect(inet:socket(), proplists:proplist()) -> ok_error(connection_ref()).
+
+-spec connect(inet:socket(), proplists:proplist(), timeout()) -> ok_error(connection_ref())
+ ; (string(), inet:port_number(), proplists:proplist()) -> ok_error(connection_ref()).
--spec connect(port(), proplists:proplist(), timeout()) -> {ok, pid()} | {error, term()}
- ; (string(), integer(), proplists:proplist()) -> {ok, pid()} | {error, term()}.
+-spec connect(string(), inet:port_number(), proplists:proplist(), timeout()) -> ok_error(connection_ref()).
--spec connect(string(), integer(), proplists:proplist(), timeout()) -> {ok, pid()} | {error, term()}.
%%
%% Description: Starts an ssh connection.
%%--------------------------------------------------------------------
-connect(Socket, Options) ->
- connect(Socket, Options, infinity).
+connect(Socket, UserOptions) when is_port(Socket),
+ is_list(UserOptions) ->
+ connect(Socket, UserOptions, infinity).
-connect(Socket, Options, Timeout) when is_port(Socket) ->
- case handle_options(Options) of
+connect(Socket, UserOptions, Timeout) when is_port(Socket),
+ is_list(UserOptions) ->
+ case ssh_options:handle_options(client, UserOptions) of
{error, Error} ->
{error, Error};
- {_SocketOptions, SshOptions} ->
- case valid_socket_to_use(Socket, Options) of
- ok ->
+ Options ->
+ case valid_socket_to_use(Socket, ?GET_OPT(transport,Options)) of
+ ok ->
{ok, {Host,_Port}} = inet:sockname(Socket),
- Opts = [{user_pid,self()}, {host,fmt_host(Host)} | SshOptions],
+ Opts = ?PUT_INTERNAL_OPT([{user_pid,self()}, {host,Host}], Options),
ssh_connection_handler:start_connection(client, Socket, Opts, Timeout);
{error,SockError} ->
{error,SockError}
end
end;
-connect(Host, Port, Options) when is_integer(Port), Port>0 ->
- connect(Host, Port, Options, infinity).
+connect(Host, Port, UserOptions) when is_integer(Port),
+ Port>0,
+ is_list(UserOptions) ->
+ connect(Host, Port, UserOptions, infinity).
-connect(Host, Port, Options, Timeout) ->
- case handle_options(Options) of
+connect(Host0, Port, UserOptions, Timeout) when is_integer(Port),
+ Port>0,
+ is_list(UserOptions) ->
+ case ssh_options:handle_options(client, UserOptions) of
{error, _Reason} = Error ->
Error;
- {SocketOptions, SshOptions} ->
- {_, Transport, _} = TransportOpts =
- proplists:get_value(transport, Options, {tcp, gen_tcp, tcp_closed}),
- ConnectionTimeout = proplists:get_value(connect_timeout, Options, infinity),
- try Transport:connect(Host, Port, [ {active, false} | SocketOptions], ConnectionTimeout) of
+ Options ->
+ {_, Transport, _} = TransportOpts = ?GET_OPT(transport, Options),
+ ConnectionTimeout = ?GET_OPT(connect_timeout, Options),
+ SocketOpts = [{active,false} | ?GET_OPT(socket_options,Options)],
+ Host = mangle_connect_address(Host0, SocketOpts),
+ try Transport:connect(Host, Port, SocketOpts, ConnectionTimeout) of
{ok, Socket} ->
- Opts = [{user_pid,self()}, {host,Host} | SshOptions],
+ Opts = ?PUT_INTERNAL_OPT([{user_pid,self()}, {host,Host}], Options),
ssh_connection_handler:start_connection(client, Socket, Opts, Timeout);
{error, Reason} ->
{error, Reason}
catch
- exit:{function_clause, _} ->
+ exit:{function_clause, _F} ->
{error, {options, {transport, TransportOpts}}};
exit:badarg ->
- {error, {options, {socket_options, SocketOptions}}}
+ {error, {options, {socket_options, SocketOpts}}}
end
end.
@@ -128,93 +150,191 @@ connect(Host, Port, Options, Timeout) ->
-spec close(pid()) -> ok.
%%
%% Description: Closes an ssh connection.
-%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
close(ConnectionRef) ->
ssh_connection_handler:stop(ConnectionRef).
%%--------------------------------------------------------------------
-spec connection_info(pid(), [atom()]) -> [{atom(), term()}].
%%
-%% Description: Retrieves information about a connection.
-%%--------------------------------------------------------------------
+%% Description: Retrieves information about a connection.
+%%--------------------------------------------------------------------
connection_info(ConnectionRef, Options) ->
ssh_connection_handler:connection_info(ConnectionRef, Options).
%%--------------------------------------------------------------------
-spec channel_info(pid(), channel_id(), [atom()]) -> [{atom(), term()}].
%%
-%% Description: Retrieves information about a connection.
-%%--------------------------------------------------------------------
+%% Description: Retrieves information about a connection.
+%%--------------------------------------------------------------------
channel_info(ConnectionRef, ChannelId, Options) ->
ssh_connection_handler:channel_info(ConnectionRef, ChannelId, Options).
%%--------------------------------------------------------------------
--spec daemon(integer()) -> {ok, pid()} | {error, term()}.
--spec daemon(integer()|port(), proplists:proplist()) -> {ok, pid()} | {error, term()}.
--spec daemon(any | inet:ip_address(), integer(), proplists:proplist()) -> {ok, pid()} | {error, term()}.
+-spec daemon(inet:port_number()) -> ok_error(daemon_ref()).
+-spec daemon(inet:port_number()|inet:socket(), proplists:proplist()) -> ok_error(daemon_ref()).
+-spec daemon(any | inet:ip_address(), inet:port_number(), proplists:proplist()) -> ok_error(daemon_ref())
+ ;(socket, inet:socket(), proplists:proplist()) -> ok_error(daemon_ref())
+ .
-%% Description: Starts a server listening for SSH connections
+%% Description: Starts a server listening for SSH connections
%% on the given port.
-%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
daemon(Port) ->
daemon(Port, []).
-daemon(Port, Options) when is_integer(Port) ->
- daemon(any, Port, Options);
-daemon(Socket, Options0) when is_port(Socket) ->
- Options = daemon_shell_opt(Options0),
- start_daemon(Socket, Options).
+daemon(Socket, UserOptions) when is_port(Socket) ->
+ try
+ #{} = Options = ssh_options:handle_options(server, UserOptions),
+ case valid_socket_to_use(Socket, ?GET_OPT(transport,Options)) of
+ ok ->
+ {ok, {IP,Port}} = inet:sockname(Socket),
+ finalize_start(IP, Port, ?GET_OPT(profile, Options),
+ ?PUT_INTERNAL_OPT({connected_socket, Socket}, Options),
+ fun(Opts, DefaultResult) ->
+ try ssh_acceptor:handle_established_connection(
+ IP, Port, Opts, Socket)
+ of
+ {error,Error} ->
+ {error,Error};
+ _ ->
+ DefaultResult
+ catch
+ C:R ->
+ {error,{could_not_start_connection,{C,R}}}
+ end
+ end);
+ {error,SockError} ->
+ {error,SockError}
+ end
+ catch
+ throw:bad_fd ->
+ {error,bad_fd};
+ throw:bad_socket ->
+ {error,bad_socket};
+ error:{badmatch,{error,Error}} ->
+ {error,Error};
+ error:Error ->
+ {error,Error};
+ _C:_E ->
+ {error,{cannot_start_daemon,_C,_E}}
+ end;
+
+daemon(Port, UserOptions) when 0 =< Port, Port =< 65535 ->
+ daemon(any, Port, UserOptions).
+
+
+daemon(Host0, Port0, UserOptions0) when 0 =< Port0, Port0 =< 65535,
+ Host0 == any ; Host0 == loopback ; is_tuple(Host0) ->
+ try
+ {Host1, UserOptions} = handle_daemon_args(Host0, UserOptions0),
+ #{} = Options0 = ssh_options:handle_options(server, UserOptions),
+
+ {{Host,Port}, ListenSocket} =
+ open_listen_socket(Host1, Port0, Options0),
+
+ %% Now Host,Port is what to use for the supervisor to register its name,
+ %% and ListenSocket is for listening on connections. But it is still owned
+ %% by self()...
+
+ finalize_start(Host, Port, ?GET_OPT(profile, Options0),
+ ?PUT_INTERNAL_OPT({lsocket,{ListenSocket,self()}}, Options0),
+ fun(Opts, Result) ->
+ {_, Callback, _} = ?GET_OPT(transport, Opts),
+ receive
+ {request_control, ListenSocket, ReqPid} ->
+ ok = Callback:controlling_process(ListenSocket, ReqPid),
+ ReqPid ! {its_yours,ListenSocket},
+ Result
+ end
+ end)
+ catch
+ throw:bad_fd ->
+ {error,bad_fd};
+ throw:bad_socket ->
+ {error,bad_socket};
+ error:{badmatch,{error,Error}} ->
+ {error,Error};
+ error:Error ->
+ {error,Error};
+ _C:_E ->
+ {error,{cannot_start_daemon,_C,_E}}
+ end;
+
+daemon(_, _, _) ->
+ {error, badarg}.
+
-daemon(HostAddr, Port, Options0) ->
- Options1 = daemon_shell_opt(Options0),
- {Host, Inet, Options} = daemon_host_inet_opt(HostAddr, Options1),
- start_daemon(Host, Port, Options, Inet).
%%--------------------------------------------------------------------
+-spec daemon_info(daemon_ref()) -> ok_error( [{atom(), term()}] ).
+
daemon_info(Pid) ->
case catch ssh_system_sup:acceptor_supervisor(Pid) of
AsupPid when is_pid(AsupPid) ->
- [Port] =
- [Prt || {{ssh_acceptor_sup,any,Prt,default},
- _WorkerPid,worker,[ssh_acceptor]} <- supervisor:which_children(AsupPid)],
- {ok, [{port,Port}]};
-
+ [{IP,Port,Profile}] =
+ [{IP,Prt,Prf}
+ || {{ssh_acceptor_sup,Hst,Prt,Prf},_Pid,worker,[ssh_acceptor]}
+ <- supervisor:which_children(AsupPid),
+ IP <- [case inet:parse_strict_address(Hst) of
+ {ok,IP} -> IP;
+ _ -> Hst
+ end]
+ ],
+ {ok, [{port,Port},
+ {ip,IP},
+ {profile,Profile}
+ ]};
_ ->
{error,bad_daemon_ref}
end.
%%--------------------------------------------------------------------
--spec stop_listener(pid()) -> ok.
--spec stop_listener(inet:ip_address(), integer()) -> ok.
+-spec stop_listener(daemon_ref()) -> ok.
+-spec stop_listener(inet:ip_address(), inet:port_number()) -> ok.
%%
-%% Description: Stops the listener, but leaves
+%% Description: Stops the listener, but leaves
%% existing connections started by the listener up and running.
-%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
stop_listener(SysSup) ->
ssh_system_sup:stop_listener(SysSup).
stop_listener(Address, Port) ->
stop_listener(Address, Port, ?DEFAULT_PROFILE).
+stop_listener(any, Port, Profile) ->
+ map_ip(fun(IP) ->
+ ssh_system_sup:stop_listener(IP, Port, Profile)
+ end, [{0,0,0,0},{0,0,0,0,0,0,0,0}]);
stop_listener(Address, Port, Profile) ->
- ssh_system_sup:stop_listener(Address, Port, Profile).
+ map_ip(fun(IP) ->
+ ssh_system_sup:stop_listener(IP, Port, Profile)
+ end, {address,Address}).
%%--------------------------------------------------------------------
--spec stop_daemon(pid()) -> ok.
--spec stop_daemon(inet:ip_address(), integer()) -> ok.
+-spec stop_daemon(daemon_ref()) -> ok.
+-spec stop_daemon(inet:ip_address(), inet:port_number()) -> ok.
+-spec stop_daemon(inet:ip_address(), inet:port_number(), atom()) -> ok.
%%
-%% Description: Stops the listener and all connections started by
+%% Description: Stops the listener and all connections started by
%% the listener.
-%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
stop_daemon(SysSup) ->
ssh_system_sup:stop_system(SysSup).
stop_daemon(Address, Port) ->
- ssh_system_sup:stop_system(Address, Port, ?DEFAULT_PROFILE).
+ stop_daemon(Address, Port, ?DEFAULT_PROFILE).
+stop_daemon(any, Port, Profile) ->
+ map_ip(fun(IP) ->
+ ssh_system_sup:stop_system(IP, Port, Profile)
+ end, [{0,0,0,0},{0,0,0,0,0,0,0,0}]);
stop_daemon(Address, Port, Profile) ->
- ssh_system_sup:stop_system(Address, Port, Profile).
+ map_ip(fun(IP) ->
+ ssh_system_sup:stop_system(IP, Port, Profile)
+ end, {address,Address}).
+
%%--------------------------------------------------------------------
--spec shell(port() | string()) -> _.
--spec shell(port() | string(), proplists:proplist()) -> _.
--spec shell(string(), integer(), proplists:proplist()) -> _.
+-spec shell(inet:socket() | string()) -> _.
+-spec shell(inet:socket() | string(), proplists:proplist()) -> _.
+-spec shell(string(), inet:port_number(), proplists:proplist()) -> _.
%% Host = string()
%% Port = integer()
@@ -243,7 +363,7 @@ start_shell({ok, ConnectionRef}) ->
case ssh_connection:session_channel(ConnectionRef, infinity) of
{ok,ChannelId} ->
success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId, []),
- Args = [{channel_cb, ssh_shell},
+ Args = [{channel_cb, ssh_shell},
{init_args,[ConnectionRef, ChannelId]},
{cm, ConnectionRef}, {channel_id, ChannelId}],
{ok, State} = ssh_channel:init([Args]),
@@ -255,715 +375,111 @@ start_shell(Error) ->
Error.
%%--------------------------------------------------------------------
+-spec default_algorithms() -> algs_list() .
%%--------------------------------------------------------------------
-default_algorithms() ->
+default_algorithms() ->
ssh_transport:default_algorithms().
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-valid_socket_to_use(Socket, Options) ->
- case proplists:get_value(transport, Options, {tcp, gen_tcp, tcp_closed}) of
- {tcp,_,_} ->
- %% Is this tcp-socket a valid socket?
- case {is_tcp_socket(Socket),
- {ok,[{active,false}]} == inet:getopts(Socket, [active])
- }
- of
- {true, true} ->
- ok;
- {true, false} ->
- {error, not_passive_mode};
- _ ->
- {error, not_tcp_socket}
- end;
- {L4,_,_} ->
- {error, {unsupported,L4}}
- end.
-
-is_tcp_socket(Socket) -> {ok,[]} =/= inet:getopts(Socket, [delay_send]).
-
-
-
-daemon_shell_opt(Options) ->
- case proplists:get_value(shell, Options) of
- undefined ->
- [{shell, {shell, start, []}} | Options];
- _ ->
- Options
- end.
-
-daemon_host_inet_opt(HostAddr, Options1) ->
- case HostAddr of
- any ->
- {ok, Host0} = inet:gethostname(),
- {Host0, proplists:get_value(inet, Options1, inet), Options1};
- {_,_,_,_} ->
- {HostAddr, inet,
- [{ip, HostAddr} | Options1]};
- {_,_,_,_,_,_,_,_} ->
- {HostAddr, inet6,
- [{ip, HostAddr} | Options1]}
- end.
-
-
-start_daemon(Socket, Options) ->
- case handle_options(Options) of
- {error, Error} ->
- {error, Error};
- {SocketOptions, SshOptions} ->
- case valid_socket_to_use(Socket, Options) of
- ok ->
- try
- do_start_daemon(Socket, [{role,server}|SshOptions], SocketOptions)
- catch
- throw:bad_fd -> {error,bad_fd};
- _C:_E -> {error,{cannot_start_daemon,_C,_E}}
- end;
- {error,SockError} ->
- {error,SockError}
- end
- end.
-
-start_daemon(Host, Port, Options, Inet) ->
- case handle_options(Options) of
- {error, _Reason} = Error ->
- Error;
- {SocketOptions, SshOptions}->
- try
- do_start_daemon(Host, Port, [{role,server}|SshOptions] , [Inet|SocketOptions])
- catch
- throw:bad_fd -> {error,bad_fd};
- _C:_E -> {error,{cannot_start_daemon,_C,_E}}
- end
- end.
-
-do_start_daemon(Socket, SshOptions, SocketOptions) ->
- {ok, {IP,Port}} =
- try {ok,_} = inet:sockname(Socket)
- catch
- _:_ -> throw(bad_socket)
- end,
- Host = fmt_host(IP),
- Profile = proplists:get_value(profile, SshOptions, ?DEFAULT_PROFILE),
- Opts = [{asocket, Socket},
- {asock_owner,self()},
- {address, Host},
- {port, Port},
- {role, server},
- {socket_opts, SocketOptions},
- {ssh_opts, SshOptions}],
- {_, Callback, _} = proplists:get_value(transport, SshOptions, {tcp, gen_tcp, tcp_closed}),
- case ssh_system_sup:system_supervisor(Host, Port, Profile) of
- undefined ->
- %% It would proably make more sense to call the
- %% address option host but that is a too big change at the
- %% monent. The name is a legacy name!
- try sshd_sup:start_child(Opts) of
- {error, {already_started, _}} ->
- {error, eaddrinuse};
- Result = {ok,_} ->
- ssh_acceptor:handle_connection(Callback, Host, Port, Opts, Socket),
- Result;
- Result = {error, _} ->
- Result
- catch
- exit:{noproc, _} ->
- {error, ssh_not_started}
- end;
- Sup ->
- AccPid = ssh_system_sup:acceptor_supervisor(Sup),
- case ssh_acceptor_sup:start_child(AccPid, Opts) of
- {error, {already_started, _}} ->
- {error, eaddrinuse};
- {ok, _} ->
- ssh_acceptor:handle_connection(Callback, Host, Port, Opts, Socket),
- {ok, Sup};
- Other ->
- Other
- end
- end.
+%% The handle_daemon_args/2 function basically only sets the ip-option in Opts
+%% so that it is correctly set when opening the listening socket.
-do_start_daemon(Host0, Port0, SshOptions, SocketOptions) ->
- {Host,Port1} =
- try
- case proplists:get_value(fd, SocketOptions) of
- undefined ->
- {Host0,Port0};
- Fd when Port0==0 ->
- find_hostport(Fd);
- _ ->
- {Host0,Port0}
- end
- catch
- _:_ -> throw(bad_fd)
- end,
- Profile = proplists:get_value(profile, SshOptions, ?DEFAULT_PROFILE),
- {Port, WaitRequestControl, Opts0} =
- case Port1 of
- 0 -> %% Allocate the socket here to get the port number...
- {_, Callback, _} =
- proplists:get_value(transport, SshOptions, {tcp, gen_tcp, tcp_closed}),
- {ok,LSock} = ssh_acceptor:callback_listen(Callback, 0, SocketOptions),
- {ok,{_,LPort}} = inet:sockname(LSock),
- {LPort,
- {LSock,Callback},
- [{lsocket,LSock},{lsock_owner,self()}]
- };
- _ ->
- {Port1, false, []}
- end,
- Opts = [{address, Host},
- {port, Port},
- {role, server},
- {socket_opts, SocketOptions},
- {ssh_opts, SshOptions} | Opts0],
- case ssh_system_sup:system_supervisor(Host, Port, Profile) of
- undefined ->
- %% It would proably make more sense to call the
- %% address option host but that is a too big change at the
- %% monent. The name is a legacy name!
- try sshd_sup:start_child(Opts) of
- {error, {already_started, _}} ->
- {error, eaddrinuse};
- Result = {ok,_} ->
- sync_request_control(WaitRequestControl),
- Result;
- Result = {error, _} ->
- Result
- catch
- exit:{noproc, _} ->
- {error, ssh_not_started}
- end;
- Sup ->
- AccPid = ssh_system_sup:acceptor_supervisor(Sup),
- case ssh_acceptor_sup:start_child(AccPid, Opts) of
- {error, {already_started, _}} ->
- {error, eaddrinuse};
- {ok, _} ->
- sync_request_control(WaitRequestControl),
- {ok, Sup};
- Other ->
- Other
- end
- end.
+handle_daemon_args(any, Opts) ->
+ case proplists:get_value(ip, Opts) of
+ undefined -> {any, Opts};
+ IP -> {IP, Opts}
+ end;
-sync_request_control(false) ->
- ok;
-sync_request_control({LSock,Callback}) ->
- receive
- {request_control,LSock,ReqPid} ->
- ok = Callback:controlling_process(LSock, ReqPid),
- ReqPid ! {its_yours,LSock},
- ok
+handle_daemon_args(IPaddr, Opts) when is_tuple(IPaddr) ; IPaddr == loopback ->
+ case proplists:get_value(ip, Opts) of
+ undefined -> {IPaddr, [{ip,IPaddr}|Opts]};
+ IPaddr -> {IPaddr, Opts};
+ IP -> {IPaddr, [{ip,IPaddr}|Opts--[{ip,IP}]]} %% Backward compatibility
end.
-find_hostport(Fd) ->
- %% Using internal functions inet:open/8 and inet:close/0.
- %% Don't try this at home unless you know what you are doing!
- {ok,S} = inet:open(Fd, {0,0,0,0}, 0, [], tcp, inet, stream, inet_tcp),
- {ok, HostPort} = inet:sockname(S),
- ok = inet:close(S),
- HostPort.
-
-
-handle_options(Opts) ->
- try handle_option(algs_compatibility(proplists:unfold(Opts)), [], []) of
- {Inet, Ssh} ->
- {handle_ip(Inet), Ssh}
+%%%----------------------------------------------------------------
+valid_socket_to_use(Socket, {tcp,_,_}) ->
+ %% Is this tcp-socket a valid socket?
+ try {is_tcp_socket(Socket),
+ {ok,[{active,false}]} == inet:getopts(Socket, [active])
+ }
+ of
+ {true, true} -> ok;
+ {true, false} -> {error, not_passive_mode};
+ _ -> {error, not_tcp_socket}
catch
- throw:Error ->
- Error
- end.
-
+ _:_ -> {error, bad_socket}
+ end;
-algs_compatibility(Os0) ->
- %% Take care of old options 'public_key_alg' and 'pref_public_key_algs'
- case proplists:get_value(public_key_alg, Os0) of
- undefined ->
- Os0;
- A when is_atom(A) ->
- %% Skip public_key_alg if pref_public_key_algs is defined:
- Os = lists:keydelete(public_key_alg, 1, Os0),
- case proplists:get_value(pref_public_key_algs,Os) of
- undefined when A == 'ssh-rsa' ; A==ssh_rsa ->
- [{pref_public_key_algs,['ssh-rsa','ssh-dss']} | Os];
- undefined when A == 'ssh-dss' ; A==ssh_dsa ->
- [{pref_public_key_algs,['ssh-dss','ssh-rsa']} | Os];
- undefined ->
- throw({error, {eoptions, {public_key_alg,A} }});
- _ ->
- Os
- end;
- V ->
- throw({error, {eoptions, {public_key_alg,V} }})
- end.
+valid_socket_to_use(_, {L4,_,_}) ->
+ {error, {unsupported,L4}}.
-handle_option([], SocketOptions, SshOptions) ->
- {SocketOptions, SshOptions};
-handle_option([{system_dir, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{user_dir, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{user_dir_fun, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{silently_accept_hosts, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{user_interaction, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{connect_timeout, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{user, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{dsa_pass_phrase, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{rsa_pass_phrase, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{password, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{user_passwords, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{pwdfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{key_cb, {Module, Options}} | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option({key_cb, Module}),
- handle_ssh_priv_option({key_cb_private, Options}) |
- SshOptions]);
-handle_option([{key_cb, Module} | Rest], SocketOptions, SshOptions) ->
- handle_option([{key_cb, {Module, []}} | Rest], SocketOptions, SshOptions);
-handle_option([{keyboard_interact_fun, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-%%Backwards compatibility
-handle_option([{allow_user_interaction, Value} | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option({user_interaction, Value}) | SshOptions]);
-handle_option([{infofun, _} = Opt | Rest],SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{connectfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{disconnectfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{unexpectedfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{failfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{ssh_msg_debug_fun, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-%%Backwards compatibility should not be underscore between ip and v6 in API
-handle_option([{ip_v6_disabled, Value} | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option({ipv6_disabled, Value}) | SshOptions]);
-handle_option([{ipv6_disabled, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{transport, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{subsystems, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{ssh_cli, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{shell, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{exec, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{auth_methods, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{auth_method_kb_interactive_data, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{pref_public_key_algs, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{preferred_algorithms,_} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{dh_gex_groups,_} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{dh_gex_limits,_} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{quiet_mode, _} = Opt|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{idle_time, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{rekey_limit, _} = Opt|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{max_sessions, _} = Opt|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{max_channels, _} = Opt|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{negotiation_timeout, _} = Opt|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{parallel_login, _} = Opt|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-%% (Is handled by proplists:unfold above:)
-%% handle_option([parallel_login|Rest], SocketOptions, SshOptions) ->
-%% handle_option(Rest, SocketOptions, [handle_ssh_option({parallel_login,true}) | SshOptions]);
-handle_option([{minimal_remote_max_packet_size, _} = Opt|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{id_string, _ID} = Opt|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{profile, _ID} = Opt|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{max_random_length_padding, _Bool} = Opt|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{tstflg, _} = Opt|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, [handle_inet_option(Opt) | SocketOptions], SshOptions).
-
-
-handle_ssh_option({tstflg,_F} = Opt) -> Opt;
-handle_ssh_option({minimal_remote_max_packet_size, Value} = Opt) when is_integer(Value), Value >=0 ->
- Opt;
-handle_ssh_option({system_dir, Value} = Opt) when is_list(Value) ->
- check_dir(Opt);
-handle_ssh_option({user_dir, Value} = Opt) when is_list(Value) ->
- check_dir(Opt);
-handle_ssh_option({user_dir_fun, Value} = Opt) when is_function(Value) ->
- Opt;
-handle_ssh_option({silently_accept_hosts, Value} = Opt) when is_boolean(Value) ->
- Opt;
-handle_ssh_option({user_interaction, Value} = Opt) when is_boolean(Value) ->
- Opt;
-handle_ssh_option({preferred_algorithms,[_|_]} = Opt) ->
- handle_pref_algs(Opt);
-
-handle_ssh_option({dh_gex_groups,L0}) when is_list(L0) ->
- {dh_gex_groups,
- collect_per_size(
- lists:foldl(
- fun({N,G,P}, Acc) when is_integer(N),N>0,
- is_integer(G),G>0,
- is_integer(P),P>0 ->
- [{N,{G,P}} | Acc];
- ({N,{G,P}}, Acc) when is_integer(N),N>0,
- is_integer(G),G>0,
- is_integer(P),P>0 ->
- [{N,{G,P}} | Acc];
- ({N,GPs}, Acc) when is_list(GPs) ->
- lists:foldr(fun({Gi,Pi}, Acci) when is_integer(Gi),Gi>0,
- is_integer(Pi),Pi>0 ->
- [{N,{Gi,Pi}} | Acci]
- end, Acc, GPs)
- end, [], L0))};
-
-handle_ssh_option({dh_gex_groups,{Tag,File=[C|_]}}=Opt) when is_integer(C), C>0,
- Tag == file ;
- Tag == ssh_moduli_file ->
- {ok,GroupDefs} =
- case Tag of
- file ->
- file:consult(File);
- ssh_moduli_file ->
- case file:open(File,[read]) of
- {ok,D} ->
- try
- {ok,Moduli} = read_moduli_file(D, 1, []),
- file:close(D),
- {ok, Moduli}
- catch
- _:_ ->
- throw({error, {{eoptions, Opt}, "Bad format in file "++File}})
- end;
- {error,enoent} ->
- throw({error, {{eoptions, Opt}, "File not found:"++File}});
- {error,Error} ->
- throw({error, {{eoptions, Opt}, io_lib:format("Error reading file ~s: ~p",[File,Error])}})
- end
- end,
+is_tcp_socket(Socket) ->
+ case inet:getopts(Socket, [delay_send]) of
+ {ok,[_]} -> true;
+ _ -> false
+ end.
+%%%----------------------------------------------------------------
+open_listen_socket(_Host0, Port0, Options0) ->
+ {ok,LSock} =
+ case ?GET_SOCKET_OPT(fd, Options0) of
+ undefined ->
+ ssh_acceptor:listen(Port0, Options0);
+ Fd when is_integer(Fd) ->
+ %% Do gen_tcp:listen with the option {fd,Fd}:
+ ssh_acceptor:listen(0, Options0)
+ end,
+ {ok,{LHost,LPort}} = inet:sockname(LSock),
+ {{LHost,LPort}, LSock}.
+
+%%%----------------------------------------------------------------
+finalize_start(Host, Port, Profile, Options0, F) ->
try
- handle_ssh_option({dh_gex_groups,GroupDefs})
+ sshd_sup:start_child(Host, Port, Profile, Options0)
+ of
+ {error, {already_started, _}} ->
+ {error, eaddrinuse};
+ {error, Error} ->
+ {error, Error};
+ Result = {ok,_} ->
+ F(Options0, Result)
catch
- _:_ ->
- throw({error, {{eoptions, Opt}, "Bad format in file: "++File}})
- end;
-
-
-handle_ssh_option({dh_gex_limits,{Min,Max}} = Opt) when is_integer(Min), Min>0,
- is_integer(Max), Max>=Min ->
- %% Server
- Opt;
-handle_ssh_option({dh_gex_limits,{Min,I,Max}} = Opt) when is_integer(Min), Min>0,
- is_integer(I), I>=Min,
- is_integer(Max), Max>=I ->
- %% Client
- Opt;
-handle_ssh_option({pref_public_key_algs, Value} = Opt) when is_list(Value), length(Value) >= 1 ->
- case handle_user_pref_pubkey_algs(Value, []) of
- {true, NewOpts} ->
- {pref_public_key_algs, NewOpts};
- _ ->
- throw({error, {eoptions, Opt}})
- end;
-handle_ssh_option({connect_timeout, Value} = Opt) when is_integer(Value); Value == infinity ->
- Opt;
-handle_ssh_option({max_sessions, Value} = Opt) when is_integer(Value), Value>0 ->
- Opt;
-handle_ssh_option({max_channels, Value} = Opt) when is_integer(Value), Value>0 ->
- Opt;
-handle_ssh_option({negotiation_timeout, Value} = Opt) when is_integer(Value); Value == infinity ->
- Opt;
-handle_ssh_option({parallel_login, Value} = Opt) when Value==true ; Value==false ->
- Opt;
-handle_ssh_option({user, Value} = Opt) when is_list(Value) ->
- Opt;
-handle_ssh_option({dsa_pass_phrase, Value} = Opt) when is_list(Value) ->
- Opt;
-handle_ssh_option({rsa_pass_phrase, Value} = Opt) when is_list(Value) ->
- Opt;
-handle_ssh_option({password, Value} = Opt) when is_list(Value) ->
- Opt;
-handle_ssh_option({user_passwords, Value} = Opt) when is_list(Value)->
- Opt;
-handle_ssh_option({pwdfun, Value} = Opt) when is_function(Value,2) ->
- Opt;
-handle_ssh_option({pwdfun, Value} = Opt) when is_function(Value,4) ->
- Opt;
-handle_ssh_option({key_cb, Value} = Opt) when is_atom(Value) ->
- Opt;
-handle_ssh_option({key_cb, {CallbackMod, CallbackOptions}} = Opt) when is_atom(CallbackMod),
- is_list(CallbackOptions) ->
- Opt;
-handle_ssh_option({keyboard_interact_fun, Value} = Opt) when is_function(Value,3) ->
- Opt;
-handle_ssh_option({compression, Value} = Opt) when is_atom(Value) ->
- Opt;
-handle_ssh_option({exec, {Module, Function, _}} = Opt) when is_atom(Module),
- is_atom(Function) ->
- Opt;
-handle_ssh_option({exec, Function} = Opt) when is_function(Function) ->
- Opt;
-handle_ssh_option({auth_methods, Value} = Opt) when is_list(Value) ->
- Opt;
-handle_ssh_option({auth_method_kb_interactive_data, {Name,Instruction,Prompt,Echo}} = Opt) when is_list(Name),
- is_list(Instruction),
- is_list(Prompt),
- is_boolean(Echo) ->
- Opt;
-handle_ssh_option({auth_method_kb_interactive_data, F} = Opt) when is_function(F,3) ->
- Opt;
-handle_ssh_option({infofun, Value} = Opt) when is_function(Value) ->
- Opt;
-handle_ssh_option({connectfun, Value} = Opt) when is_function(Value) ->
- Opt;
-handle_ssh_option({disconnectfun, Value} = Opt) when is_function(Value) ->
- Opt;
-handle_ssh_option({unexpectedfun, Value} = Opt) when is_function(Value,2) ->
- Opt;
-handle_ssh_option({failfun, Value} = Opt) when is_function(Value) ->
- Opt;
-handle_ssh_option({ssh_msg_debug_fun, Value} = Opt) when is_function(Value,4) ->
- Opt;
-
-handle_ssh_option({ipv6_disabled, Value} = Opt) when is_boolean(Value) ->
- throw({error, {{ipv6_disabled, Opt}, option_no_longer_valid_use_inet_option_instead}});
-handle_ssh_option({transport, {Protocol, Cb, ClosTag}} = Opt) when is_atom(Protocol),
- is_atom(Cb),
- is_atom(ClosTag) ->
- Opt;
-handle_ssh_option({subsystems, Value} = Opt) when is_list(Value) ->
- Opt;
-handle_ssh_option({ssh_cli, {Cb, _}}= Opt) when is_atom(Cb) ->
- Opt;
-handle_ssh_option({ssh_cli, no_cli} = Opt) ->
- Opt;
-handle_ssh_option({shell, {Module, Function, _}} = Opt) when is_atom(Module),
- is_atom(Function) ->
- Opt;
-handle_ssh_option({shell, Value} = Opt) when is_function(Value) ->
- Opt;
-handle_ssh_option({quiet_mode, Value} = Opt) when is_boolean(Value) ->
- Opt;
-handle_ssh_option({idle_time, Value} = Opt) when is_integer(Value), Value > 0 ->
- Opt;
-handle_ssh_option({rekey_limit, Value} = Opt) when is_integer(Value) ->
- Opt;
-handle_ssh_option({id_string, random}) ->
- {id_string, {random,2,5}}; %% 2 - 5 random characters
-handle_ssh_option({id_string, ID} = Opt) when is_list(ID) ->
- Opt;
-handle_ssh_option({max_random_length_padding, Value} = Opt) when is_integer(Value),
- Value =< 255 ->
- Opt;
-handle_ssh_option({profile, Value} = Opt) when is_atom(Value) ->
- Opt;
-handle_ssh_option(Opt) ->
- throw({error, {eoptions, Opt}}).
-
-handle_ssh_priv_option({key_cb_private, Value} = Opt) when is_list(Value) ->
- Opt.
-
-handle_inet_option({active, _} = Opt) ->
- throw({error, {{eoptions, Opt}, "SSH has built in flow control, "
- "and active is handled internally, user is not allowed"
- "to specify this option"}});
-
-handle_inet_option({inet, Value}) when (Value == inet) or (Value == inet6) ->
- Value;
-handle_inet_option({reuseaddr, _} = Opt) ->
- throw({error, {{eoptions, Opt},"Is set internally, user is not allowed"
- "to specify this option"}});
-%% Option verified by inet
-handle_inet_option(Opt) ->
- Opt.
-
-
-%% Check preferred algs
-
-handle_pref_algs({preferred_algorithms,Algs}) ->
- try alg_duplicates(Algs, [], []) of
- [] ->
- {preferred_algorithms,
- [try ssh_transport:supported_algorithms(Key)
- of
- DefAlgs -> handle_pref_alg(Key,Vals,DefAlgs)
- catch
- _:_ -> throw({error, {{eoptions, {preferred_algorithms,Key}},
- "Bad preferred_algorithms key"}})
- end || {Key,Vals} <- Algs]
- };
-
- Dups ->
- throw({error, {{eoptions, {preferred_algorithms,Dups}}, "Duplicates found"}})
- catch
- _:_ ->
- throw({error, {{eoptions, preferred_algorithms}, "Malformed"}})
- end.
-
-alg_duplicates([{K,V}|KVs], Ks, Dups0) ->
- Dups =
- case lists:member(K,Ks) of
- true ->
- [K|Dups0];
- false ->
- Dups0
- end,
- case V--lists:usort(V) of
- [] ->
- alg_duplicates(KVs, [K|Ks], Dups);
- Ds ->
- alg_duplicates(KVs, [K|Ks], Dups++Ds)
- end;
-alg_duplicates([], _Ks, Dups) ->
- Dups.
-
-handle_pref_alg(Key,
- Vs=[{client2server,C2Ss=[_|_]},{server2client,S2Cs=[_|_]}],
- [{client2server,Sup_C2Ss},{server2client,Sup_S2Cs}]
- ) ->
- chk_alg_vs(Key, C2Ss, Sup_C2Ss),
- chk_alg_vs(Key, S2Cs, Sup_S2Cs),
- {Key, Vs};
-
-handle_pref_alg(Key,
- Vs=[{server2client,[_|_]},{client2server,[_|_]}],
- Sup=[{client2server,_},{server2client,_}]
- ) ->
- handle_pref_alg(Key, lists:reverse(Vs), Sup);
-
-handle_pref_alg(Key,
- Vs=[V|_],
- Sup=[{client2server,_},{server2client,_}]
- ) when is_atom(V) ->
- handle_pref_alg(Key, [{client2server,Vs},{server2client,Vs}], Sup);
-
-handle_pref_alg(Key,
- Vs=[V|_],
- Sup=[S|_]
- ) when is_atom(V), is_atom(S) ->
- chk_alg_vs(Key, Vs, Sup),
- {Key, Vs};
-
-handle_pref_alg(Key, Vs, _) ->
- throw({error, {{eoptions, {preferred_algorithms,[{Key,Vs}]}}, "Badly formed list"}}).
-
-chk_alg_vs(OptKey, Values, SupportedValues) ->
- case (Values -- SupportedValues) of
- [] -> Values;
- Bad -> throw({error, {{eoptions, {OptKey,Bad}}, "Unsupported value(s) found"}})
- end.
-
-handle_ip(Inet) -> %% Default to ipv4
- case lists:member(inet, Inet) of
- true ->
- Inet;
- false ->
- case lists:member(inet6, Inet) of
- true ->
- Inet;
- false ->
- [inet | Inet]
- end
- end.
-
-check_dir({_,Dir} = Opt) ->
- case directory_exist_readable(Dir) of
- ok ->
- Opt;
- {error,Error} ->
- throw({error, {eoptions,{Opt,Error}}})
+ exit:{noproc, _} ->
+ {error, ssh_not_started}
end.
-directory_exist_readable(Dir) ->
- case file:read_file_info(Dir) of
- {ok, #file_info{type = directory,
- access = Access}} ->
- case Access of
- read -> ok;
- read_write -> ok;
- _ -> {error, eacces}
- end;
-
- {ok, #file_info{}}->
- {error, enotdir};
-
- {error, Error} ->
- {error, Error}
+%%%----------------------------------------------------------------
+map_ip(Fun, {address,IP}) when is_tuple(IP) ->
+ Fun(IP);
+map_ip(Fun, {address,Address}) ->
+ IPs = try {ok,#hostent{h_addr_list=IP0s}} = inet:gethostbyname(Address),
+ IP0s
+ catch
+ _:_ -> []
+ end,
+ map_ip(Fun, IPs);
+map_ip(Fun, IPs) ->
+ lists:map(Fun, IPs).
+
+%%%----------------------------------------------------------------
+mangle_connect_address(A, SockOpts) ->
+ mangle_connect_address1(A, proplists:get_value(inet6,SockOpts,false)).
+
+loopback(true) -> {0,0,0,0,0,0,0,1};
+loopback(false) -> {127,0,0,1}.
+
+mangle_connect_address1( loopback, V6flg) -> loopback(V6flg);
+mangle_connect_address1( any, V6flg) -> loopback(V6flg);
+mangle_connect_address1({0,0,0,0}, _) -> loopback(false);
+mangle_connect_address1({0,0,0,0,0,0,0,0}, _) -> loopback(true);
+mangle_connect_address1( IP, _) when is_tuple(IP) -> IP;
+mangle_connect_address1(A, _) ->
+ case catch inet:parse_address(A) of
+ {ok, {0,0,0,0}} -> loopback(false);
+ {ok, {0,0,0,0,0,0,0,0}} -> loopback(true);
+ _ -> A
end.
-
-
-
-collect_per_size(L) ->
- lists:foldr(
- fun({Sz,GP}, [{Sz,GPs}|Acc]) -> [{Sz,[GP|GPs]}|Acc];
- ({Sz,GP}, Acc) -> [{Sz,[GP]}|Acc]
- end, [], lists:sort(L)).
-
-read_moduli_file(D, I, Acc) ->
- case io:get_line(D,"") of
- {error,Error} ->
- {error,Error};
- eof ->
- {ok, Acc};
- "#" ++ _ -> read_moduli_file(D, I+1, Acc);
- <<"#",_/binary>> -> read_moduli_file(D, I+1, Acc);
- Data ->
- Line = if is_binary(Data) -> binary_to_list(Data);
- is_list(Data) -> Data
- end,
- try
- [_Time,_Type,_Tests,_Tries,Size,G,P] = string:tokens(Line," \r\n"),
- M = {list_to_integer(Size),
- {list_to_integer(G), list_to_integer(P,16)}
- },
- read_moduli_file(D, I+1, [M|Acc])
- catch
- _:_ ->
- read_moduli_file(D, I+1, Acc)
- end
- end.
-
-handle_user_pref_pubkey_algs([], Acc) ->
- {true, lists:reverse(Acc)};
-handle_user_pref_pubkey_algs([H|T], Acc) ->
- case lists:member(H, ?SUPPORTED_USER_KEYS) of
- true ->
- handle_user_pref_pubkey_algs(T, [H| Acc]);
-
- false when H==ssh_dsa -> handle_user_pref_pubkey_algs(T, ['ssh-dss'| Acc]);
- false when H==ssh_rsa -> handle_user_pref_pubkey_algs(T, ['ssh-rsa'| Acc]);
-
- false ->
- false
- end.
-
-fmt_host({A,B,C,D}) ->
- lists:concat([A,".",B,".",C,".",D]);
-fmt_host(T={_,_,_,_,_,_,_,_}) ->
- lists:flatten(string:join([io_lib:format("~.16B",[A]) || A <- tuple_to_list(T)], ":")).
diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl
index 868f3a9181..d6d412db43 100644
--- a/lib/ssh/src/ssh.hrl
+++ b/lib/ssh/src/ssh.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,8 +33,11 @@
-define(REKEY_DATA_TIMOUT, 60000).
-define(DEFAULT_PROFILE, default).
+-define(DEFAULT_TRANSPORT, {tcp, gen_tcp, tcp_closed} ).
+
+-define(MAX_RND_PADDING_LEN, 15).
+
-define(SUPPORTED_AUTH_METHODS, "publickey,keyboard-interactive,password").
--define(SUPPORTED_USER_KEYS, ['ssh-rsa','ssh-dss','ecdsa-sha2-nistp256','ecdsa-sha2-nistp384','ecdsa-sha2-nistp521']).
-define(FALSE, 0).
-define(TRUE, 1).
@@ -64,14 +67,73 @@
-define(string_utf8(X), << ?STRING(unicode:characters_to_binary(X)) >> ).
-define(binary(X), << ?STRING(X) >>).
+%% Cipher details
-define(SSH_CIPHER_NONE, 0).
-define(SSH_CIPHER_3DES, 3).
-define(SSH_CIPHER_AUTHFILE, ?SSH_CIPHER_3DES).
+%% Option access macros
+-define(do_get_opt(C,K,O), ssh_options:get_value(C,K,O, ?MODULE,?LINE)).
+-define(do_get_opt(C,K,O,D), ssh_options:get_value(C,K,O,?LAZY(D),?MODULE,?LINE)).
+
+-define(LAZY(D), fun()-> D end).
+
+-define(GET_OPT(Key,Opts), ?do_get_opt(user_options, Key,Opts ) ).
+-define(GET_OPT(Key,Opts,Def), ?do_get_opt(user_options, Key,Opts,Def) ).
+-define(GET_INTERNAL_OPT(Key,Opts), ?do_get_opt(internal_options,Key,Opts ) ).
+-define(GET_INTERNAL_OPT(Key,Opts,Def), ?do_get_opt(internal_options,Key,Opts,Def) ).
+-define(GET_SOCKET_OPT(Key,Opts), ?do_get_opt(socket_options, Key,Opts ) ).
+-define(GET_SOCKET_OPT(Key,Opts,Def), ?do_get_opt(socket_options, Key,Opts,Def) ).
+
+-define(do_put_opt(C,KV,O), ssh_options:put_value(C,KV,O, ?MODULE,?LINE)).
+
+-define(PUT_OPT(KeyVal,Opts), ?do_put_opt(user_options, KeyVal,Opts) ).
+-define(PUT_INTERNAL_OPT(KeyVal,Opts), ?do_put_opt(internal_options,KeyVal,Opts) ).
+-define(PUT_SOCKET_OPT(KeyVal,Opts), ?do_put_opt(socket_options, KeyVal,Opts) ).
+
+-define(do_del_opt(C,K,O), ssh_options:delete_key(C,K,O, ?MODULE,?LINE)).
+-define(DELETE_INTERNAL_OPT(Key,Opts), ?do_del_opt(internal_options,Key,Opts) ).
+
+
+%% Types
+-type role() :: client | server .
+-type ok_error(SuccessType) :: {ok, SuccessType} | {error, any()} .
+-type daemon_ref() :: pid() .
+
+-type subsystem_spec() :: {subsystem_name(), {channel_callback(), channel_init_args()}} .
+-type subsystem_name() :: string() .
+-type channel_callback() :: atom() .
+-type channel_init_args() :: list() .
+
+-type algs_list() :: list( alg_entry() ).
+-type alg_entry() :: {kex, simple_algs()}
+ | {public_key, simple_algs()}
+ | {cipher, double_algs()}
+ | {mac, double_algs()}
+ | {compression, double_algs()} .
+-type simple_algs() :: list( atom() ) .
+-type double_algs() :: list( {client2serverlist,simple_algs()} | {server2client,simple_algs()} )
+ | simple_algs() .
+
+-type options() :: #{socket_options := socket_options(),
+ internal_options := internal_options(),
+ option_key() => any()
+ }.
+
+-type socket_options() :: proplists:proplist().
+-type internal_options() :: #{option_key() => any()}.
+
+-type option_key() :: atom().
+
+
+
+%% Records
-record(ssh,
{
- role, %% client | server
- peer, %% string version of peer address
+ role :: client | role(),
+ peer :: undefined |
+ {inet:hostname(),
+ {inet:ip_address(),inet:port_number()}}, %% string version of peer address
c_vsn, %% client version {Major,Minor}
s_vsn, %% server version {Major,Minor}
@@ -82,6 +144,9 @@
c_keyinit, %% binary payload of kexinit packet
s_keyinit, %% binary payload of kexinit packet
+ send_ext_info, %% May send ext-info to peer
+ recv_ext_info, %% Expect ext-info from peer
+
algorithms, %% #alg{}
kex, %% key exchange algorithm
@@ -127,7 +192,7 @@
recv_sequence = 0,
keyex_key,
keyex_info,
- random_length_padding = 255, % From RFC 4253 section 6.
+ random_length_padding = ?MAX_RND_PADDING_LEN, % From RFC 4253 section 6.
%% User auth
user,
@@ -135,6 +200,7 @@
userauth_quiet_mode, % boolean()
userauth_methods, % list( string() ) eg ["keyboard-interactive", "password"]
userauth_supported_methods, % string() eg "keyboard-interactive,password"
+ userauth_pubkeys,
kb_tries_left = 0, % integer(), num tries left for "keyboard-interactive"
userauth_preference,
available_host_keys,
@@ -153,7 +219,9 @@
compress,
decompress,
c_lng,
- s_lng
+ s_lng,
+ send_ext_info,
+ recv_ext_info
}).
-record(ssh_key,
diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl
index 9f3e60bd62..d66a34c58a 100644
--- a/lib/ssh/src/ssh_acceptor.erl
+++ b/lib/ssh/src/ssh_acceptor.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,84 +25,86 @@
-include("ssh.hrl").
%% Internal application API
--export([start_link/5,
+-export([start_link/4,
number_of_connections/1,
- callback_listen/3,
- handle_connection/5]).
+ listen/2,
+ handle_established_connection/4]).
%% spawn export
--export([acceptor_init/6, acceptor_loop/6]).
+-export([acceptor_init/5, acceptor_loop/6]).
-define(SLEEP_TIME, 200).
%%====================================================================
%% Internal application API
%%====================================================================
-start_link(Port, Address, SockOpts, Opts, AcceptTimeout) ->
- Args = [self(), Port, Address, SockOpts, Opts, AcceptTimeout],
+start_link(Port, Address, Options, AcceptTimeout) ->
+ Args = [self(), Port, Address, Options, AcceptTimeout],
proc_lib:start_link(?MODULE, acceptor_init, Args).
+%%%----------------------------------------------------------------
+number_of_connections(SystemSup) ->
+ length([X ||
+ {R,X,supervisor,[ssh_subsystem_sup]} <- supervisor:which_children(SystemSup),
+ is_pid(X),
+ is_reference(R)
+ ]).
+
+%%%----------------------------------------------------------------
+listen(Port, Options) ->
+ {_, Callback, _} = ?GET_OPT(transport, Options),
+ SockOpts = [{active, false}, {reuseaddr,true} | ?GET_OPT(socket_options, Options)],
+ case Callback:listen(Port, SockOpts) of
+ {error, nxdomain} ->
+ Callback:listen(Port, lists:delete(inet6, SockOpts));
+ {error, enetunreach} ->
+ Callback:listen(Port, lists:delete(inet6, SockOpts));
+ {error, eafnosupport} ->
+ Callback:listen(Port, lists:delete(inet6, SockOpts));
+ Other ->
+ Other
+ end.
+
+%%%----------------------------------------------------------------
+handle_established_connection(Address, Port, Options, Socket) ->
+ {_, Callback, _} = ?GET_OPT(transport, Options),
+ handle_connection(Callback, Address, Port, Options, Socket).
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-acceptor_init(Parent, Port, Address, SockOpts, Opts, AcceptTimeout) ->
- {_, Callback, _} =
- proplists:get_value(transport, Opts, {tcp, gen_tcp, tcp_closed}),
-
- SockOwner = proplists:get_value(lsock_owner, Opts),
- LSock = proplists:get_value(lsocket, Opts),
- UseExistingSocket =
- case catch inet:sockname(LSock) of
- {ok,{_,Port}} -> is_pid(SockOwner);
- _ -> false
- end,
-
- case UseExistingSocket of
- true ->
- proc_lib:init_ack(Parent, {ok, self()}),
- request_ownership(LSock, SockOwner),
- acceptor_loop(Callback, Port, Address, Opts, LSock, AcceptTimeout);
-
- false ->
- case (catch do_socket_listen(Callback, Port, SockOpts)) of
- {ok, ListenSocket} ->
- proc_lib:init_ack(Parent, {ok, self()}),
- acceptor_loop(Callback,
- Port, Address, Opts, ListenSocket, AcceptTimeout);
- Error ->
- proc_lib:init_ack(Parent, Error),
- error
- end
+acceptor_init(Parent, Port, Address, Opts, AcceptTimeout) ->
+ try
+ ?GET_INTERNAL_OPT(lsocket, Opts)
+ of
+ {LSock, SockOwner} ->
+ case inet:sockname(LSock) of
+ {ok,{_,Port}} -> % A usable, open LSock
+ proc_lib:init_ack(Parent, {ok, self()}),
+ request_ownership(LSock, SockOwner),
+ {_, Callback, _} = ?GET_OPT(transport, Opts),
+ acceptor_loop(Callback, Port, Address, Opts, LSock, AcceptTimeout);
+
+ {error,_} -> % Not open, a restart
+ {ok,NewLSock} = listen(Port, Opts),
+ proc_lib:init_ack(Parent, {ok, self()}),
+ Opts1 = ?DELETE_INTERNAL_OPT(lsocket, Opts),
+ {_, Callback, _} = ?GET_OPT(transport, Opts1),
+ acceptor_loop(Callback, Port, Address, Opts1, NewLSock, AcceptTimeout)
+ end
+ catch
+ _:_ ->
+ {error,use_existing_socket_failed}
end.
+
request_ownership(LSock, SockOwner) ->
SockOwner ! {request_control,LSock,self()},
receive
{its_yours,LSock} -> ok
end.
-
-do_socket_listen(Callback, Port0, Opts) ->
- Port =
- case proplists:get_value(fd, Opts) of
- undefined -> Port0;
- _ -> 0
- end,
- callback_listen(Callback, Port, Opts).
-
-callback_listen(Callback, Port, Opts0) ->
- Opts = [{active, false}, {reuseaddr,true} | Opts0],
- case Callback:listen(Port, Opts) of
- {error, nxdomain} ->
- Callback:listen(Port, lists:delete(inet6, Opts));
- {error, enetunreach} ->
- Callback:listen(Port, lists:delete(inet6, Opts));
- {error, eafnosupport} ->
- Callback:listen(Port, lists:delete(inet6, Opts));
- Other ->
- Other
- end.
-
+%%%----------------------------------------------------------------
acceptor_loop(Callback, Port, Address, Opts, ListenSocket, AcceptTimeout) ->
case (catch Callback:accept(ListenSocket, AcceptTimeout)) of
{ok, Socket} ->
@@ -119,22 +121,24 @@ acceptor_loop(Callback, Port, Address, Opts, ListenSocket, AcceptTimeout) ->
ListenSocket, AcceptTimeout)
end.
+%%%----------------------------------------------------------------
handle_connection(Callback, Address, Port, Options, Socket) ->
- SSHopts = proplists:get_value(ssh_opts, Options, []),
- Profile = proplists:get_value(profile, SSHopts, ?DEFAULT_PROFILE),
+ Profile = ?GET_OPT(profile, Options),
SystemSup = ssh_system_sup:system_supervisor(Address, Port, Profile),
- MaxSessions = proplists:get_value(max_sessions,SSHopts,infinity),
+ MaxSessions = ?GET_OPT(max_sessions, Options),
case number_of_connections(SystemSup) < MaxSessions of
true ->
- {ok, SubSysSup} = ssh_system_sup:start_subsystem(SystemSup, Options),
+ {ok, SubSysSup} =
+ ssh_system_sup:start_subsystem(SystemSup, server, Address, Port, Profile, Options),
ConnectionSup = ssh_subsystem_sup:connection_supervisor(SubSysSup),
- Timeout = proplists:get_value(negotiation_timeout, SSHopts, 2*60*1000),
+ NegTimeout = ?GET_OPT(negotiation_timeout, Options),
ssh_connection_handler:start_connection(server, Socket,
- [{supervisors, [{system_sup, SystemSup},
- {subsystem_sup, SubSysSup},
- {connection_sup, ConnectionSup}]}
- | Options], Timeout);
+ ?PUT_INTERNAL_OPT(
+ {supervisors, [{system_sup, SystemSup},
+ {subsystem_sup, SubSysSup},
+ {connection_sup, ConnectionSup}]},
+ Options), NegTimeout);
false ->
Callback:close(Socket),
IPstr = if is_tuple(Address) -> inet:ntoa(Address);
@@ -150,7 +154,7 @@ handle_connection(Callback, Address, Port, Options, Socket) ->
{error,max_sessions}
end.
-
+%%%----------------------------------------------------------------
handle_error(timeout) ->
ok;
@@ -177,10 +181,3 @@ handle_error(Reason) ->
error_logger:error_report(String),
exit({accept_failed, String}).
-
-number_of_connections(SystemSup) ->
- length([X ||
- {R,X,supervisor,[ssh_subsystem_sup]} <- supervisor:which_children(SystemSup),
- is_pid(X),
- is_reference(R)
- ]).
diff --git a/lib/ssh/src/ssh_acceptor_sup.erl b/lib/ssh/src/ssh_acceptor_sup.erl
index 129f85a3e0..a24664793b 100644
--- a/lib/ssh/src/ssh_acceptor_sup.erl
+++ b/lib/ssh/src/ssh_acceptor_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@
-include("ssh.hrl").
--export([start_link/1, start_child/2, stop_child/4]).
+-export([start_link/4, start_child/5, stop_child/4]).
%% Supervisor callback
-export([init/1]).
@@ -41,20 +41,19 @@
%%%=========================================================================
%%% API
%%%=========================================================================
-start_link(Servers) ->
- supervisor:start_link(?MODULE, [Servers]).
+start_link(Address, Port, Profile, Options) ->
+ supervisor:start_link(?MODULE, [Address, Port, Profile, Options]).
-start_child(AccSup, ServerOpts) ->
- Spec = child_spec(ServerOpts),
+start_child(AccSup, Address, Port, Profile, Options) ->
+ Spec = child_spec(Address, Port, Profile, Options),
case supervisor:start_child(AccSup, Spec) of
{error, already_present} ->
- Address = proplists:get_value(address, ServerOpts),
- Port = proplists:get_value(port, ServerOpts),
- Profile = proplists:get_value(profile,
- proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ %% Is this ever called?
stop_child(AccSup, Address, Port, Profile),
supervisor:start_child(AccSup, Spec);
Reply ->
+ %% Reply = {ok,SystemSupPid} when the user calls ssh:daemon
+ %% after having called ssh:stop_listening
Reply
end.
@@ -70,35 +69,29 @@ stop_child(AccSup, Address, Port, Profile) ->
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
-init([ServerOpts]) ->
- RestartStrategy = one_for_one,
- MaxR = 10,
- MaxT = 3600,
- Children = [child_spec(ServerOpts)],
- {ok, {{RestartStrategy, MaxR, MaxT}, Children}}.
+init([Address, Port, Profile, Options]) ->
+ %% Initial start of ssh_acceptor_sup for this port or new start after
+ %% ssh:stop_daemon
+ SupFlags = #{strategy => one_for_one,
+ intensity => 10,
+ period => 3600
+ },
+ ChildSpecs = [child_spec(Address, Port, Profile, Options)],
+ {ok, {SupFlags,ChildSpecs}}.
%%%=========================================================================
%%% Internal functions
%%%=========================================================================
-child_spec(ServerOpts) ->
- Address = proplists:get_value(address, ServerOpts),
- Port = proplists:get_value(port, ServerOpts),
- Timeout = proplists:get_value(timeout, ServerOpts, ?DEFAULT_TIMEOUT),
- Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
- Name = id(Address, Port, Profile),
- SocketOpts = proplists:get_value(socket_opts, ServerOpts),
- StartFunc = {ssh_acceptor, start_link, [Port, Address, SocketOpts, ServerOpts, Timeout]},
- Restart = transient,
- Shutdown = brutal_kill,
- Modules = [ssh_acceptor],
- Type = worker,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+child_spec(Address, Port, Profile, Options) ->
+ Timeout = ?GET_INTERNAL_OPT(timeout, Options, ?DEFAULT_TIMEOUT),
+ #{id => id(Address, Port, Profile),
+ start => {ssh_acceptor, start_link, [Port, Address, Options, Timeout]},
+ restart => transient,
+ shutdown => 5500, %brutal_kill,
+ type => worker,
+ modules => [ssh_acceptor]
+ }.
id(Address, Port, Profile) ->
- case is_list(Address) of
- true ->
- {ssh_acceptor_sup, any, Port, Profile};
- false ->
- {ssh_acceptor_sup, Address, Port, Profile}
- end.
+ {ssh_acceptor_sup, Address, Port, Profile}.
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl
index 49eec8072f..ac64a7bf14 100644
--- a/lib/ssh/src/ssh_auth.erl
+++ b/lib/ssh/src/ssh_auth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -28,57 +28,87 @@
-include("ssh_auth.hrl").
-include("ssh_transport.hrl").
--export([publickey_msg/1, password_msg/1, keyboard_interactive_msg/1,
+-export([get_public_key/2,
+ publickey_msg/1, password_msg/1, keyboard_interactive_msg/1,
service_request_msg/1, init_userauth_request_msg/1,
userauth_request_msg/1, handle_userauth_request/3,
- handle_userauth_info_request/3, handle_userauth_info_response/2
+ handle_userauth_info_request/2, handle_userauth_info_response/2
]).
%%--------------------------------------------------------------------
%%% Internal application API
%%--------------------------------------------------------------------
-publickey_msg([Alg, #ssh{user = User,
- session_id = SessionId,
- service = Service,
- opts = Opts} = Ssh]) ->
- Hash = sha, %% Maybe option?!
- KeyCb = proplists:get_value(key_cb, Opts, ssh_file),
- case KeyCb:user_key(Alg, Opts) of
- {ok, PrivKey} ->
- StrAlgo = atom_to_list(Alg),
- case encode_public_key(StrAlgo, ssh_transport:extract_public_key(PrivKey)) of
- not_ok ->
- not_ok;
- PubKeyBlob ->
- SigData = build_sig_data(SessionId,
- User, Service, PubKeyBlob, StrAlgo),
- Sig = ssh_transport:sign(SigData, Hash, PrivKey),
- SigBlob = list_to_binary([?string(StrAlgo), ?binary(Sig)]),
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_request{user = User,
- service = Service,
- method = "publickey",
- data = [?TRUE,
- ?string(StrAlgo),
- ?binary(PubKeyBlob),
- ?binary(SigBlob)]},
- Ssh)
- end;
- _Error ->
- not_ok
+%%%----------------------------------------------------------------
+userauth_request_msg(#ssh{userauth_methods = ServerMethods,
+ userauth_supported_methods = UserPrefMethods, % Note: this is not documented as supported for clients
+ userauth_preference = ClientMethods0
+ } = Ssh0) ->
+ case sort_select_mthds(ClientMethods0, UserPrefMethods, ServerMethods) of
+ [] ->
+ Msg = #ssh_msg_disconnect{code = ?SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
+ description = "Unable to connect using the available authentication methods",
+ language = "en"},
+ {disconnect, Msg, ssh_transport:ssh_packet(Msg, Ssh0)};
+
+ [{Pref,Module,Function,Args} | Prefs] ->
+ Ssh = case Pref of
+ "keyboard-interactive" -> Ssh0;
+ _ -> Ssh0#ssh{userauth_preference = Prefs}
+ end,
+ case Module:Function(Args ++ [Ssh]) of
+ {not_ok, Ssh1} ->
+ userauth_request_msg(Ssh1#ssh{userauth_preference = Prefs});
+ Result ->
+ {Pref,Result}
+ end
end.
+
+
+sort_select_mthds(Clients, undefined, Servers) ->
+ %% User has not expressed an opinion via option "auth_methods", use the server's prefs
+ sort_select_mthds1(Clients, Servers, string:tokens(?SUPPORTED_AUTH_METHODS,","));
+
+sort_select_mthds(Clients, Users0, Servers0) ->
+ %% The User has an opinion, use the intersection of that and the Servers whishes but
+ %% in the Users order
+ sort_select_mthds1(Clients, string:tokens(Users0,","), Servers0).
+
+
+sort_select_mthds1(Clients, Users0, Servers0) ->
+ Servers = unique(Servers0),
+ Users = unique(Users0),
+ [C || Key <- Users,
+ lists:member(Key, Servers),
+ C <- Clients,
+ element(1,C) == Key].
+
+unique(L) ->
+ lists:reverse(
+ lists:foldl(fun(E,Acc) ->
+ case lists:member(E,Acc) of
+ true -> Acc;
+ false -> [E|Acc]
+ end
+ end, [], L)).
+
+
+%%%---- userauth_request_msg "callbacks"
password_msg([#ssh{opts = Opts, io_cb = IoCb,
- user = User, service = Service} = Ssh]) ->
- Password = case proplists:get_value(password, Opts) of
- undefined ->
- user_interaction(IoCb, Ssh);
- PW ->
- PW
- end,
+ user = User, service = Service} = Ssh0]) ->
+ {Password,Ssh} =
+ case ?GET_OPT(password, Opts) of
+ undefined when IoCb == ssh_no_io ->
+ {not_ok, Ssh0};
+ undefined ->
+ {IoCb:read_password("ssh password: ",Opts), Ssh0};
+ PW ->
+ %% If "password" option is given it should not be tried again
+ {PW, Ssh0#ssh{opts = ?PUT_OPT({password,not_ok}, Opts)}}
+ end,
case Password of
not_ok ->
- not_ok;
+ {not_ok, Ssh};
_ ->
ssh_transport:ssh_packet(
#ssh_msg_userauth_request{user = User,
@@ -90,84 +120,100 @@ password_msg([#ssh{opts = Opts, io_cb = IoCb,
Ssh)
end.
-user_interaction(ssh_no_io, _) ->
- not_ok;
-user_interaction(IoCb, Ssh) ->
- IoCb:read_password("ssh password: ", Ssh).
-
-
%% See RFC 4256 for info on keyboard-interactive
keyboard_interactive_msg([#ssh{user = User,
+ opts = Opts,
service = Service} = Ssh]) ->
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_request{user = User,
- service = Service,
- method = "keyboard-interactive",
- data = << ?STRING(<<"">>),
- ?STRING(<<>>) >> },
- Ssh).
+ case ?GET_OPT(password, Opts) of
+ not_ok ->
+ {not_ok,Ssh}; % No need to use a failed pwd once more
+ _ ->
+ ssh_transport:ssh_packet(
+ #ssh_msg_userauth_request{user = User,
+ service = Service,
+ method = "keyboard-interactive",
+ data = << ?STRING(<<"">>),
+ ?STRING(<<>>) >> },
+ Ssh)
+ end.
+
+get_public_key(SigAlg, #ssh{opts = Opts}) ->
+ KeyAlg = key_alg(SigAlg),
+ {KeyCb,KeyCbOpts} = ?GET_OPT(key_cb, Opts),
+ UserOpts = ?GET_OPT(user_options, Opts),
+ case KeyCb:user_key(KeyAlg, [{key_cb_private,KeyCbOpts}|UserOpts]) of
+ {ok, PrivKey} ->
+ try
+ Key = ssh_transport:extract_public_key(PrivKey),
+ public_key:ssh_encode(Key, ssh2_pubkey)
+ of
+ PubKeyBlob -> {ok,{PrivKey,PubKeyBlob}}
+ catch
+ _:_ ->
+ not_ok
+ end;
+ _Error ->
+ not_ok
+ end.
+
+
+publickey_msg([SigAlg, #ssh{user = User,
+ session_id = SessionId,
+ service = Service} = Ssh]) ->
+ case get_public_key(SigAlg, Ssh) of
+ {ok, {PrivKey,PubKeyBlob}} ->
+ SigAlgStr = atom_to_list(SigAlg),
+ SigData = build_sig_data(SessionId, User, Service,
+ PubKeyBlob, SigAlgStr),
+ Hash = ssh_transport:sha(SigAlg),
+ Sig = ssh_transport:sign(SigData, Hash, PrivKey),
+ SigBlob = list_to_binary([?string(SigAlgStr),
+ ?binary(Sig)]),
+ ssh_transport:ssh_packet(
+ #ssh_msg_userauth_request{user = User,
+ service = Service,
+ method = "publickey",
+ data = [?TRUE,
+ ?string(SigAlgStr),
+ ?binary(PubKeyBlob),
+ ?binary(SigBlob)]},
+ Ssh);
+ _ ->
+ {not_ok, Ssh}
+ end.
+
+%%%----------------------------------------------------------------
service_request_msg(Ssh) ->
ssh_transport:ssh_packet(#ssh_msg_service_request{name = "ssh-userauth"},
Ssh#ssh{service = "ssh-userauth"}).
+%%%----------------------------------------------------------------
init_userauth_request_msg(#ssh{opts = Opts} = Ssh) ->
- case user_name(Opts) of
- {ok, User} ->
- Msg = #ssh_msg_userauth_request{user = User,
- service = "ssh-connection",
- method = "none",
- data = <<>>},
- Algs0 = proplists:get_value(pref_public_key_algs, Opts, ?SUPPORTED_USER_KEYS),
- %% The following line is not strictly correct. The call returns the
- %% supported HOST key types while we are interested in USER keys. However,
- %% they "happens" to be the same (for now). This could change....
- %% There is no danger as long as the set of user keys is a subset of the set
- %% of host keys.
- CryptoSupported = ssh_transport:supported_algorithms(public_key),
- Algs = [A || A <- Algs0,
- lists:member(A, CryptoSupported)],
-
- Prefs = method_preference(Algs),
- ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
- userauth_preference = Prefs,
- userauth_methods = none,
- service = "ssh-connection"});
- {error, no_user} ->
+ %% Client side
+ case ?GET_OPT(user, Opts) of
+ undefined ->
ErrStr = "Could not determine the users name",
ssh_connection_handler:disconnect(
#ssh_msg_disconnect{code = ?SSH_DISCONNECT_ILLEGAL_USER_NAME,
- description = ErrStr})
- end.
-
-userauth_request_msg(#ssh{userauth_preference = []} = Ssh) ->
- Msg = #ssh_msg_disconnect{code =
- ?SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
- description = "Unable to connect using the available"
- " authentication methods",
- language = "en"},
- {disconnect, Msg, ssh_transport:ssh_packet(Msg, Ssh)};
-
-userauth_request_msg(#ssh{userauth_methods = Methods,
- userauth_preference = [{Pref, Module,
- Function, Args} | Prefs]}
- = Ssh0) ->
- Ssh = Ssh0#ssh{userauth_preference = Prefs},
- case lists:member(Pref, Methods) of
- true ->
- case Module:Function(Args ++ [Ssh]) of
- not_ok ->
- userauth_request_msg(Ssh);
- Result ->
- {Pref,Result}
- end;
- false ->
- userauth_request_msg(Ssh)
+ description = ErrStr});
+
+ User ->
+ ssh_transport:ssh_packet(
+ #ssh_msg_userauth_request{user = User,
+ service = "ssh-connection",
+ method = "none",
+ data = <<>>},
+ Ssh#ssh{user = User,
+ userauth_preference = method_preference(Ssh#ssh.userauth_pubkeys),
+ userauth_methods = none,
+ service = "ssh-connection"}
+ )
end.
-
-handle_userauth_request(#ssh_msg_service_request{name =
- Name = "ssh-userauth"},
+%%%----------------------------------------------------------------
+%%% called by server
+handle_userauth_request(#ssh_msg_service_request{name = Name = "ssh-userauth"},
_, Ssh) ->
{ok, ssh_transport:ssh_packet(#ssh_msg_service_accept{name = Name},
Ssh#ssh{service = "ssh-connection"})};
@@ -223,32 +269,52 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
method = "publickey",
- data = Data},
- SessionId,
+ data = <<?BYTE(?FALSE),
+ ?UINT32(ALen), BAlg:ALen/binary,
+ ?UINT32(KLen), KeyBlob:KLen/binary,
+ _/binary
+ >>
+ },
+ _SessionId,
#ssh{opts = Opts,
userauth_supported_methods = Methods} = Ssh) ->
- <<?BYTE(HaveSig), ?UINT32(ALen), BAlg:ALen/binary,
- ?UINT32(KLen), KeyBlob:KLen/binary, SigWLen/binary>> = Data,
- Alg = binary_to_list(BAlg),
- case HaveSig of
- ?TRUE ->
- case verify_sig(SessionId, User, "ssh-connection", Alg,
- KeyBlob, SigWLen, Opts) of
- true ->
- {authorized, User,
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_success{}, Ssh)};
- false ->
- {not_authorized, {User, undefined},
- ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = Methods,
- partial_success = false}, Ssh)}
- end;
- ?FALSE ->
+
+ case pre_verify_sig(User, KeyBlob, Opts) of
+ true ->
{not_authorized, {User, undefined},
ssh_transport:ssh_packet(
- #ssh_msg_userauth_pk_ok{algorithm_name = Alg,
- key_blob = KeyBlob}, Ssh)}
+ #ssh_msg_userauth_pk_ok{algorithm_name = binary_to_list(BAlg),
+ key_blob = KeyBlob}, Ssh)};
+ false ->
+ {not_authorized, {User, undefined},
+ ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
+ authentications = Methods,
+ partial_success = false}, Ssh)}
+ end;
+
+handle_userauth_request(#ssh_msg_userauth_request{user = User,
+ service = "ssh-connection",
+ method = "publickey",
+ data = <<?BYTE(?TRUE),
+ ?UINT32(ALen), BAlg:ALen/binary,
+ ?UINT32(KLen), KeyBlob:KLen/binary,
+ SigWLen/binary>>
+ },
+ SessionId,
+ #ssh{opts = Opts,
+ userauth_supported_methods = Methods} = Ssh) ->
+
+ case verify_sig(SessionId, User, "ssh-connection",
+ BAlg, KeyBlob, SigWLen, Opts) of
+ true ->
+ {authorized, User,
+ ssh_transport:ssh_packet(
+ #ssh_msg_userauth_success{}, Ssh)};
+ false ->
+ {not_authorized, {User, undefined},
+ ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
+ authentications = Methods,
+ partial_success = false}, Ssh)}
end;
handle_userauth_request(#ssh_msg_userauth_request{user = User,
@@ -283,7 +349,7 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
false},
{Name, Instruction, Prompt, Echo} =
- case proplists:get_value(auth_method_kb_interactive_data, Opts) of
+ case ?GET_OPT(auth_method_kb_interactive_data, Opts) of
undefined ->
Default;
{_,_,_,_}=V ->
@@ -319,31 +385,54 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
partial_success = false}, Ssh)}.
-
-handle_userauth_info_request(
- #ssh_msg_userauth_info_request{name = Name,
- instruction = Instr,
- num_prompts = NumPrompts,
- data = Data}, IoCb,
- #ssh{opts = Opts} = Ssh) ->
+%%%----------------------------------------------------------------
+%%% keyboard-interactive client
+handle_userauth_info_request(#ssh_msg_userauth_info_request{name = Name,
+ instruction = Instr,
+ num_prompts = NumPrompts,
+ data = Data},
+ #ssh{opts = Opts,
+ io_cb = IoCb
+ } = Ssh) ->
PromptInfos = decode_keyboard_interactive_prompts(NumPrompts,Data),
- Responses = keyboard_interact_get_responses(IoCb, Opts,
- Name, Instr, PromptInfos),
- {ok,
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_info_response{num_responses = NumPrompts,
- data = Responses}, Ssh)}.
+ case keyboard_interact_get_responses(IoCb, Opts, Name, Instr, PromptInfos) of
+ not_ok ->
+ not_ok;
+ Responses ->
+ {ok,
+ ssh_transport:ssh_packet(
+ #ssh_msg_userauth_info_response{num_responses = NumPrompts,
+ data = Responses}, Ssh)}
+ end.
+%%%----------------------------------------------------------------
+%%% keyboard-interactive server
handle_userauth_info_response(#ssh_msg_userauth_info_response{num_responses = 1,
data = <<?UINT32(Sz), Password:Sz/binary>>},
#ssh{opts = Opts,
kb_tries_left = KbTriesLeft,
user = User,
userauth_supported_methods = Methods} = Ssh) ->
+ SendOneEmpty =
+ (?GET_OPT(tstflg,Opts) == one_empty)
+ orelse
+ proplists:get_value(one_empty, ?GET_OPT(tstflg,Opts), false),
+
case check_password(User, unicode:characters_to_list(Password), Opts, Ssh) of
+ {true,Ssh1} when SendOneEmpty==true ->
+ Msg = #ssh_msg_userauth_info_request{name = "",
+ instruction = "",
+ language_tag = "",
+ num_prompts = 0,
+ data = <<?BOOLEAN(?FALSE)>>
+ },
+ {authorized_but_one_more, User,
+ ssh_transport:ssh_packet(Msg, Ssh1)};
+
{true,Ssh1} ->
{authorized, User,
ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh1)};
+
{false,Ssh1} ->
{not_authorized, {User, {error,"Bad user or password"}},
ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
@@ -353,6 +442,11 @@ handle_userauth_info_response(#ssh_msg_userauth_info_response{num_responses = 1,
)}
end;
+handle_userauth_info_response({extra,#ssh_msg_userauth_info_response{}},
+ #ssh{user = User} = Ssh) ->
+ {authorized, User,
+ ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh)};
+
handle_userauth_info_response(#ssh_msg_userauth_info_response{},
_Auth) ->
ssh_connection_handler:disconnect(
@@ -364,41 +458,17 @@ handle_userauth_info_response(#ssh_msg_userauth_info_response{},
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-method_preference(Algs) ->
- lists:foldr(fun(A, Acc) ->
- [{"publickey", ?MODULE, publickey_msg, [A]} | Acc]
- end,
- [{"password", ?MODULE, password_msg, []},
- {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
- {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
- {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
- {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
- {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
- {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}
- ],
- Algs).
-
-user_name(Opts) ->
- Env = case os:type() of
- {win32, _} ->
- "USERNAME";
- {unix, _} ->
- "LOGNAME"
- end,
- case proplists:get_value(user, Opts, os:getenv(Env)) of
- false ->
- case os:getenv("USER") of
- false ->
- {error, no_user};
- User ->
- {ok, User}
- end;
- User ->
- {ok, User}
- end.
+method_preference(SigKeyAlgs) ->
+ %% PubKeyAlgs: List of user (client) public key algorithms to try to use.
+ %% All of the acceptable algorithms is the default values.
+ PubKeyDefs = [{"publickey", ?MODULE, publickey_msg, [A]} || A <- SigKeyAlgs],
+ NonPKmethods = [{"password", ?MODULE, password_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}
+ ],
+ PubKeyDefs ++ NonPKmethods.
check_password(User, Password, Opts, Ssh) ->
- case proplists:get_value(pwdfun, Opts) of
+ case ?GET_OPT(pwdfun, Opts) of
undefined ->
Static = get_password_option(Opts, User),
{Password == Static, Ssh};
@@ -428,25 +498,37 @@ check_password(User, Password, Opts, Ssh) ->
end.
get_password_option(Opts, User) ->
- Passwords = proplists:get_value(user_passwords, Opts, []),
+ Passwords = ?GET_OPT(user_passwords, Opts),
case lists:keysearch(User, 1, Passwords) of
{value, {User, Pw}} -> Pw;
- false -> proplists:get_value(password, Opts, false)
+ false -> ?GET_OPT(password, Opts)
end.
-verify_sig(SessionId, User, Service, Alg, KeyBlob, SigWLen, Opts) ->
- {ok, Key} = decode_public_key_v2(KeyBlob, Alg),
- KeyCb = proplists:get_value(key_cb, Opts, ssh_file),
+pre_verify_sig(User, KeyBlob, Opts) ->
+ try
+ Key = public_key:ssh_decode(KeyBlob, ssh2_pubkey), % or exception
+ {KeyCb,KeyCbOpts} = ?GET_OPT(key_cb, Opts),
+ UserOpts = ?GET_OPT(user_options, Opts),
+ KeyCb:is_auth_key(Key, User, [{key_cb_private,KeyCbOpts}|UserOpts])
+ catch
+ _:_ ->
+ false
+ end.
- case KeyCb:is_auth_key(Key, User, Opts) of
- true ->
- PlainText = build_sig_data(SessionId, User,
- Service, KeyBlob, Alg),
- <<?UINT32(AlgSigLen), AlgSig:AlgSigLen/binary>> = SigWLen,
- <<?UINT32(AlgLen), _Alg:AlgLen/binary,
- ?UINT32(SigLen), Sig:SigLen/binary>> = AlgSig,
- ssh_transport:verify(PlainText, sha, Sig, Key);
- false ->
+verify_sig(SessionId, User, Service, AlgBin, KeyBlob, SigWLen, Opts) ->
+ try
+ Alg = binary_to_list(AlgBin),
+ {KeyCb,KeyCbOpts} = ?GET_OPT(key_cb, Opts),
+ UserOpts = ?GET_OPT(user_options, Opts),
+ Key = public_key:ssh_decode(KeyBlob, ssh2_pubkey), % or exception
+ true = KeyCb:is_auth_key(Key, User, [{key_cb_private,KeyCbOpts}|UserOpts]),
+ PlainText = build_sig_data(SessionId, User, Service, KeyBlob, Alg),
+ <<?UINT32(AlgSigLen), AlgSig:AlgSigLen/binary>> = SigWLen,
+ <<?UINT32(AlgLen), _Alg:AlgLen/binary,
+ ?UINT32(SigLen), Sig:SigLen/binary>> = AlgSig,
+ ssh_transport:verify(PlainText, ssh_transport:sha(Alg), Sig, Key)
+ catch
+ _:_ ->
false
end.
@@ -468,11 +550,14 @@ decode_keyboard_interactive_prompts(_NumPrompts, Data) ->
keyboard_interact_get_responses(IoCb, Opts, Name, Instr, PromptInfos) ->
NumPrompts = length(PromptInfos),
- keyboard_interact_get_responses(proplists:get_value(user_interaction, Opts, true),
- proplists:get_value(keyboard_interact_fun, Opts),
- proplists:get_value(password, Opts, undefined), IoCb, Name,
+ keyboard_interact_get_responses(?GET_OPT(user_interaction, Opts),
+ ?GET_OPT(keyboard_interact_fun, Opts),
+ ?GET_OPT(password, Opts), IoCb, Name,
Instr, PromptInfos, Opts, NumPrompts).
+
+keyboard_interact_get_responses(_, _, not_ok, _, _, _, _, _, _) ->
+ not_ok;
keyboard_interact_get_responses(_, undefined, Password, _, _, _, _, _,
1) when Password =/= undefined ->
[Password]; %% Password auth implemented with keyboard-interaction and passwd is known
@@ -486,17 +571,18 @@ keyboard_interact_get_responses(true, Fun, _Pwd, _IoCb, Name, Instr, PromptInfos
keyboard_interact_fun(Fun, Name, Instr, PromptInfos, NumPrompts).
keyboard_interact(IoCb, Name, Instr, Prompts, Opts) ->
- if Name /= "" -> IoCb:format("~s~n", [Name]);
- true -> ok
- end,
- if Instr /= "" -> IoCb:format("~s~n", [Instr]);
- true -> ok
- end,
+ write_if_nonempty(IoCb, Name),
+ write_if_nonempty(IoCb, Instr),
lists:map(fun({Prompt, true}) -> IoCb:read_line(Prompt, Opts);
({Prompt, false}) -> IoCb:read_password(Prompt, Opts)
end,
Prompts).
+write_if_nonempty(_, "") -> ok;
+write_if_nonempty(_, <<>>) -> ok;
+write_if_nonempty(IoCb, Text) -> IoCb:format("~s~n",[Text]).
+
+
keyboard_interact_fun(KbdInteractFun, Name, Instr, PromptInfos, NumPrompts) ->
Prompts = lists:map(fun({Prompt, _Echo}) -> Prompt end,
PromptInfos),
@@ -512,18 +598,7 @@ keyboard_interact_fun(KbdInteractFun, Name, Instr, PromptInfos, NumPrompts) ->
language = "en"}})
end.
-decode_public_key_v2(Bin, _Type) ->
- try
- public_key:ssh_decode(Bin, ssh2_pubkey)
- of
- Key -> {ok, Key}
- catch
- _:_ -> {error, bad_format}
- end.
-encode_public_key(_Alg, Key) ->
- try
- public_key:ssh_encode(Key, ssh2_pubkey)
- catch
- _:_ -> not_ok
- end.
+key_alg('rsa-sha2-256') -> 'ssh-rsa';
+key_alg('rsa-sha2-512') -> 'ssh-rsa';
+key_alg(Alg) -> Alg.
diff --git a/lib/ssh/src/ssh_bits.erl b/lib/ssh/src/ssh_bits.erl
index 8bedaaf0c5..3ce7758447 100644
--- a/lib/ssh/src/ssh_bits.erl
+++ b/lib/ssh/src/ssh_bits.erl
@@ -30,39 +30,31 @@
-export([random/1]).
%%%----------------------------------------------------------------
-name_list([Name]) -> to_bin(Name);
-name_list([Name|Ns]) -> <<(to_bin(Name))/binary, ",", (name_list(Ns))/binary>>;
-name_list([]) -> <<>>.
-
-to_bin(A) when is_atom(A) -> list_to_binary(atom_to_list(A));
-to_bin(S) when is_list(S) -> list_to_binary(S);
-to_bin(B) when is_binary(B) -> B.
+name_list(NamesList) -> list_to_binary(lists:join($,, NamesList)).
%%%----------------------------------------------------------------
%%% Multi Precision Integer encoding
mpint(-1) -> <<0,0,0,1,16#ff>>;
mpint(0) -> <<0,0,0,0>>;
-mpint(X) when X < 0 -> mpint_neg(X,0,[]);
-mpint(X) -> mpint_pos(X,0,[]).
-
-mpint_neg(-1,I,Ds=[MSB|_]) ->
- if MSB band 16#80 =/= 16#80 ->
- <<?UINT32((I+1)), (list_to_binary([255|Ds]))/binary>>;
- true ->
- <<?UINT32(I), (list_to_binary(Ds))/binary>>
- end;
-mpint_neg(X,I,Ds) ->
- mpint_neg(X bsr 8,I+1,[(X band 255)|Ds]).
-
-mpint_pos(0,I,Ds=[MSB|_]) ->
- if MSB band 16#80 == 16#80 ->
- <<?UINT32((I+1)), (list_to_binary([0|Ds]))/binary>>;
- true ->
- <<?UINT32(I), (list_to_binary(Ds))/binary>>
+mpint(I) when I>0 ->
+ <<B1,V/binary>> = binary:encode_unsigned(I),
+ case B1 band 16#80 of
+ 16#80 ->
+ <<(size(V)+2):32/unsigned-big-integer, 0,B1,V/binary >>;
+ _ ->
+ <<(size(V)+1):32/unsigned-big-integer, B1,V/binary >>
end;
-mpint_pos(X,I,Ds) ->
- mpint_pos(X bsr 8,I+1,[(X band 255)|Ds]).
-
+mpint(N) when N<0 ->
+ Sxn = 8*size(binary:encode_unsigned(-N)),
+ Sxn1 = Sxn+8,
+ <<W:Sxn1>> = <<1, 0:Sxn>>,
+ <<B1,V/binary>> = binary:encode_unsigned(W+N),
+ case B1 band 16#80 of
+ 16#80 ->
+ <<(size(V)+1):32/unsigned-big-integer, B1,V/binary >>;
+ _ ->
+ <<(size(V)+2):32/unsigned-big-integer, 255,B1,V/binary >>
+ end.
%%%----------------------------------------------------------------
%% random/1
diff --git a/lib/ssh/src/ssh_channel.erl b/lib/ssh/src/ssh_channel.erl
index a8e6ebde16..85b31f3669 100644
--- a/lib/ssh/src/ssh_channel.erl
+++ b/lib/ssh/src/ssh_channel.erl
@@ -93,11 +93,16 @@ call(ChannelPid, Msg, TimeOute) ->
catch
exit:{noproc, _} ->
{error, closed};
+ exit:{normal, _} ->
+ {error, closed};
+ exit:{shutdown, _} ->
+ {error, closed};
+ exit:{{shutdown, _}, _} ->
+ {error, closed};
exit:{timeout, _} ->
{error, timeout}
end.
-
cast(ChannelPid, Msg) ->
gen_server:cast(ChannelPid, Msg).
@@ -256,7 +261,7 @@ handle_info({ssh_cm, _, _} = Msg, #state{cm = ConnectionManager,
adjust_window(Msg),
{noreply, State#state{channel_state = ChannelState}, Timeout};
{stop, ChannelId, ChannelState} ->
- ssh_connection:close(ConnectionManager, ChannelId),
+ catch ssh_connection:close(ConnectionManager, ChannelId),
{stop, normal, State#state{close_sent = true,
channel_state = ChannelState}}
end;
diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl
index 74cd2e081a..62854346b0 100644
--- a/lib/ssh/src/ssh_cli.erl
+++ b/lib/ssh/src/ssh_cli.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -208,8 +208,15 @@ handle_msg({Group, Req}, #state{group = Group, buf = Buf, pty = Pty,
write_chars(ConnectionHandler, ChannelId, Chars),
{ok, State#state{buf = NewBuf}};
-handle_msg({'EXIT', Group, _Reason}, #state{group = Group,
- channel = ChannelId} = State) ->
+handle_msg({'EXIT', Group, Reason}, #state{group = Group,
+ cm = ConnectionHandler,
+ channel = ChannelId} = State) ->
+ Status = case Reason of
+ normal -> 0;
+ _ -> -1
+ end,
+ ssh_connection:exit_status(ConnectionHandler, ChannelId, Status),
+ ssh_connection:send_eof(ConnectionHandler, ChannelId),
{stop, ChannelId, State};
handle_msg(_, State) ->
@@ -446,14 +453,20 @@ move_cursor(From, To, #ssh_pty{width=Width, term=Type}) ->
%% %%% make sure that there is data to send
%% %%% before calling ssh_connection:send
write_chars(ConnectionHandler, ChannelId, Chars) ->
- case erlang:iolist_size(Chars) of
- 0 ->
- ok;
- _ ->
- ssh_connection:send(ConnectionHandler, ChannelId,
- ?SSH_EXTENDED_DATA_DEFAULT, Chars)
+ case has_chars(Chars) of
+ false -> ok;
+ true -> ssh_connection:send(ConnectionHandler,
+ ChannelId,
+ ?SSH_EXTENDED_DATA_DEFAULT,
+ Chars)
end.
+has_chars([C|_]) when is_integer(C) -> true;
+has_chars([H|T]) when is_list(H) ; is_binary(H) -> has_chars(H) orelse has_chars(T);
+has_chars(<<_:8,_/binary>>) -> true;
+has_chars(_) -> false.
+
+
%%% tail, works with empty lists
tl1([_|A]) -> A;
tl1(_) -> [].
@@ -486,14 +499,12 @@ start_shell(ConnectionHandler, State) ->
[peer, user]),
ShellFun = case is_function(Shell) of
true ->
- User =
- proplists:get_value(user, ConnectionInfo),
+ User = proplists:get_value(user, ConnectionInfo),
case erlang:fun_info(Shell, arity) of
{arity, 1} ->
fun() -> Shell(User) end;
{arity, 2} ->
- {_, PeerAddr} =
- proplists:get_value(peer, ConnectionInfo),
+ {_, PeerAddr} = proplists:get_value(peer, ConnectionInfo),
fun() -> Shell(User, PeerAddr) end;
_ ->
Shell
@@ -512,8 +523,7 @@ start_shell(ConnectionHandler, Cmd, #state{exec=Shell} = State) when is_function
ConnectionInfo = ssh_connection_handler:connection_info(ConnectionHandler,
[peer, user]),
- User =
- proplists:get_value(user, ConnectionInfo),
+ User = proplists:get_value(user, ConnectionInfo),
ShellFun =
case erlang:fun_info(Shell, arity) of
{arity, 1} ->
@@ -521,8 +531,7 @@ start_shell(ConnectionHandler, Cmd, #state{exec=Shell} = State) when is_function
{arity, 2} ->
fun() -> Shell(Cmd, User) end;
{arity, 3} ->
- {_, PeerAddr} =
- proplists:get_value(peer, ConnectionInfo),
+ {_, PeerAddr} = proplists:get_value(peer, ConnectionInfo),
fun() -> Shell(Cmd, User, PeerAddr) end;
_ ->
Shell
diff --git a/lib/ssh/src/ssh_connect.hrl b/lib/ssh/src/ssh_connect.hrl
index 4fb6bc39f3..a8de5f9a2f 100644
--- a/lib/ssh/src/ssh_connect.hrl
+++ b/lib/ssh/src/ssh_connect.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,9 +22,9 @@
%%% Description : SSH connection protocol
--type role() :: client | server .
--type connection_ref() :: pid().
-type channel_id() :: pos_integer().
+-type connection_ref() :: pid().
+
-define(DEFAULT_PACKET_SIZE, 65536).
-define(DEFAULT_WINDOW_SIZE, 10*?DEFAULT_PACKET_SIZE).
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl
index d0f2d54c06..7e9ee78fd2 100644
--- a/lib/ssh/src/ssh_connection.erl
+++ b/lib/ssh/src/ssh_connection.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -56,8 +56,8 @@
%%--------------------------------------------------------------------
%%--------------------------------------------------------------------
--spec session_channel(pid(), timeout()) -> {ok, channel_id()} | {error, timeout | closed}.
--spec session_channel(pid(), integer(), integer(), timeout()) -> {ok, channel_id()} | {error, timeout | closed}.
+-spec session_channel(connection_ref(), timeout()) -> {ok, channel_id()} | {error, timeout | closed}.
+-spec session_channel(connection_ref(), integer(), integer(), timeout()) -> {ok, channel_id()} | {error, timeout | closed}.
%% Description: Opens a channel for a ssh session. A session is a
%% remote execution of a program. The program may be a shell, an
@@ -81,7 +81,7 @@ session_channel(ConnectionHandler, InitialWindowSize,
end.
%%--------------------------------------------------------------------
--spec exec(pid(), channel_id(), string(), timeout()) ->
+-spec exec(connection_ref(), channel_id(), string(), timeout()) ->
success | failure | {error, timeout | closed}.
%% Description: Will request that the server start the
@@ -92,7 +92,7 @@ exec(ConnectionHandler, ChannelId, Command, TimeOut) ->
true, [?string(Command)], TimeOut).
%%--------------------------------------------------------------------
--spec shell(pid(), channel_id()) -> _.
+-spec shell(connection_ref(), channel_id()) -> _.
%% Description: Will request that the user's default shell (typically
%% defined in /etc/passwd in UNIX systems) be started at the other
@@ -102,7 +102,7 @@ shell(ConnectionHandler, ChannelId) ->
ssh_connection_handler:request(ConnectionHandler, self(), ChannelId,
"shell", false, <<>>, 0).
%%--------------------------------------------------------------------
--spec subsystem(pid(), channel_id(), string(), timeout()) ->
+-spec subsystem(connection_ref(), channel_id(), string(), timeout()) ->
success | failure | {error, timeout | closed}.
%%
%% Description: Executes a predefined subsystem.
@@ -112,11 +112,11 @@ subsystem(ConnectionHandler, ChannelId, SubSystem, TimeOut) ->
ChannelId, "subsystem",
true, [?string(SubSystem)], TimeOut).
%%--------------------------------------------------------------------
--spec send(pid(), channel_id(), iodata()) ->
+-spec send(connection_ref(), channel_id(), iodata()) ->
ok | {error, closed}.
--spec send(pid(), channel_id(), integer()| iodata(), timeout() | iodata()) ->
+-spec send(connection_ref(), channel_id(), integer()| iodata(), timeout() | iodata()) ->
ok | {error, timeout} | {error, closed}.
--spec send(pid(), channel_id(), integer(), iodata(), timeout()) ->
+-spec send(connection_ref(), channel_id(), integer(), iodata(), timeout()) ->
ok | {error, timeout} | {error, closed}.
%%
%%
@@ -134,7 +134,7 @@ send(ConnectionHandler, ChannelId, Type, Data, TimeOut) ->
ssh_connection_handler:send(ConnectionHandler, ChannelId,
Type, Data, TimeOut).
%%--------------------------------------------------------------------
--spec send_eof(pid(), channel_id()) -> ok | {error, closed}.
+-spec send_eof(connection_ref(), channel_id()) -> ok | {error, closed}.
%%
%%
%% Description: Sends eof on the channel <ChannelId>.
@@ -143,7 +143,7 @@ send_eof(ConnectionHandler, Channel) ->
ssh_connection_handler:send_eof(ConnectionHandler, Channel).
%%--------------------------------------------------------------------
--spec adjust_window(pid(), channel_id(), integer()) -> ok | {error, closed}.
+-spec adjust_window(connection_ref(), channel_id(), integer()) -> ok | {error, closed}.
%%
%%
%% Description: Adjusts the ssh flowcontrol window.
@@ -152,7 +152,7 @@ adjust_window(ConnectionHandler, Channel, Bytes) ->
ssh_connection_handler:adjust_window(ConnectionHandler, Channel, Bytes).
%%--------------------------------------------------------------------
--spec setenv(pid(), channel_id(), string(), string(), timeout()) ->
+-spec setenv(connection_ref(), channel_id(), string(), string(), timeout()) ->
success | failure | {error, timeout | closed}.
%%
%%
@@ -165,7 +165,7 @@ setenv(ConnectionHandler, ChannelId, Var, Value, TimeOut) ->
%%--------------------------------------------------------------------
--spec close(pid(), channel_id()) -> ok.
+-spec close(connection_ref(), channel_id()) -> ok.
%%
%%
%% Description: Sends a close message on the channel <ChannelId>.
@@ -174,7 +174,7 @@ close(ConnectionHandler, ChannelId) ->
ssh_connection_handler:close(ConnectionHandler, ChannelId).
%%--------------------------------------------------------------------
--spec reply_request(pid(), boolean(), success | failure, channel_id()) -> ok.
+-spec reply_request(connection_ref(), boolean(), success | failure, channel_id()) -> ok.
%%
%%
%% Description: Send status replies to requests that want such replies.
@@ -185,9 +185,9 @@ reply_request(_,false, _, _) ->
ok.
%%--------------------------------------------------------------------
--spec ptty_alloc(pid(), channel_id(), proplists:proplist()) ->
+-spec ptty_alloc(connection_ref(), channel_id(), proplists:proplist()) ->
success | failiure | {error, closed}.
--spec ptty_alloc(pid(), channel_id(), proplists:proplist(), timeout()) ->
+-spec ptty_alloc(connection_ref(), channel_id(), proplists:proplist(), timeout()) ->
success | failiure | {error, timeout} | {error, closed}.
%%
@@ -197,16 +197,16 @@ reply_request(_,false, _, _) ->
ptty_alloc(ConnectionHandler, Channel, Options) ->
ptty_alloc(ConnectionHandler, Channel, Options, infinity).
ptty_alloc(ConnectionHandler, Channel, Options0, TimeOut) ->
- Options = backwards_compatible(Options0, []),
- {Width, PixWidth} = pty_default_dimensions(width, Options),
- {Height, PixHeight} = pty_default_dimensions(height, Options),
+ TermData = backwards_compatible(Options0, []), % FIXME
+ {Width, PixWidth} = pty_default_dimensions(width, TermData),
+ {Height, PixHeight} = pty_default_dimensions(height, TermData),
pty_req(ConnectionHandler, Channel,
- proplists:get_value(term, Options, os:getenv("TERM", ?DEFAULT_TERMINAL)),
- proplists:get_value(width, Options, Width),
- proplists:get_value(height, Options, Height),
- proplists:get_value(pixel_widh, Options, PixWidth),
- proplists:get_value(pixel_height, Options, PixHeight),
- proplists:get_value(pty_opts, Options, []), TimeOut
+ proplists:get_value(term, TermData, os:getenv("TERM", ?DEFAULT_TERMINAL)),
+ proplists:get_value(width, TermData, Width),
+ proplists:get_value(height, TermData, Height),
+ proplists:get_value(pixel_widh, TermData, PixWidth),
+ proplists:get_value(pixel_height, TermData, PixHeight),
+ proplists:get_value(pty_opts, TermData, []), TimeOut
).
%%--------------------------------------------------------------------
%% Not yet officialy supported! The following functions are part of the
@@ -287,6 +287,9 @@ handle_msg(#ssh_msg_channel_open_confirmation{recipient_channel = ChannelId,
ssh_channel:cache_update(Cache, Channel#channel{
remote_id = RemoteId,
+ recv_packet_size = max(32768, % rfc4254/5.2
+ min(PacketSz, Channel#channel.recv_packet_size)
+ ),
send_window_size = WindowSz,
send_packet_size = PacketSz}),
{Reply, Connection} = reply_msg(Channel, Connection0, {open, ChannelId}),
@@ -414,7 +417,8 @@ handle_msg(#ssh_msg_channel_open{channel_type = "session" = Type,
maximum_packet_size = PacketSz},
#connection{options = SSHopts} = Connection0,
server) ->
- MinAcceptedPackSz = proplists:get_value(minimal_remote_max_packet_size, SSHopts, 0),
+ MinAcceptedPackSz =
+ ?GET_OPT(minimal_remote_max_packet_size, SSHopts),
if
MinAcceptedPackSz =< PacketSz ->
@@ -571,7 +575,6 @@ handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId,
PixWidth, PixHeight, decode_pty_opts(Modes)},
Channel = ssh_channel:cache_lookup(Cache, ChannelId),
-
handle_cli_msg(Connection, Channel,
{pty, ChannelId, WantReply, PtyRequest});
@@ -688,7 +691,6 @@ handle_cli_msg(#connection{channel_cache = Cache} = Connection,
#channel{user = undefined,
remote_id = RemoteId,
local_id = ChannelId} = Channel0, Reply0) ->
-
case (catch start_cli(Connection, ChannelId)) of
{ok, Pid} ->
erlang:monitor(process, Pid),
@@ -816,7 +818,7 @@ start_channel(Cb, Id, Args, SubSysSup, Exec, Opts) ->
ssh_channel_sup:start_child(ChannelSup, ChildSpec).
assert_limit_num_channels_not_exceeded(ChannelSup, Opts) ->
- MaxNumChannels = proplists:get_value(max_channels, Opts, infinity),
+ MaxNumChannels = ?GET_OPT(max_channels, Opts),
NumChannels = length([x || {_,_,worker,[ssh_channel]} <-
supervisor:which_children(ChannelSup)]),
if
@@ -855,8 +857,8 @@ setup_session(#connection{channel_cache = Cache
check_subsystem("sftp"= SsName, Options) ->
- case proplists:get_value(subsystems, Options, no_subsys) of
- no_subsys ->
+ case ?GET_OPT(subsystems, Options) of
+ no_subsys -> % FIXME: Can 'no_subsys' ever be matched?
{SsName, {Cb, Opts}} = ssh_sftpd:subsystem_spec([]),
{Cb, Opts};
SubSystems ->
@@ -864,7 +866,7 @@ check_subsystem("sftp"= SsName, Options) ->
end;
check_subsystem(SsName, Options) ->
- Subsystems = proplists:get_value(subsystems, Options, []),
+ Subsystems = ?GET_OPT(subsystems, Options),
case proplists:get_value(SsName, Subsystems, {none, []}) of
Fun when is_function(Fun) ->
{Fun, []};
@@ -1019,12 +1021,13 @@ pty_req(ConnectionHandler, Channel, Term, Width, Height,
?uint32(PixWidth),?uint32(PixHeight),
encode_pty_opts(PtyOpts)], TimeOut).
-pty_default_dimensions(Dimension, Options) ->
- case proplists:get_value(Dimension, Options, 0) of
+pty_default_dimensions(Dimension, TermData) ->
+ case proplists:get_value(Dimension, TermData, 0) of
N when is_integer(N), N > 0 ->
{N, 0};
_ ->
- case proplists:get_value(list_to_atom("pixel_" ++ atom_to_list(Dimension)), Options, 0) of
+ PixelDim = list_to_atom("pixel_" ++ atom_to_list(Dimension)),
+ case proplists:get_value(PixelDim, TermData, 0) of
N when is_integer(N), N > 0 ->
{0, N};
_ ->
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index e952a333ff..8d3ddb09a4 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -60,7 +60,8 @@
]).
%%% Behaviour callbacks
--export([handle_event/4, terminate/3, format_status/2, code_change/4]).
+-export([init/1, callback_mode/0, handle_event/4, terminate/3,
+ format_status/2, code_change/4]).
%%% Exports not intended to be used :). They are used for spawning and tests
-export([init_connection_handler/3, % proc_lib:spawn needs this
@@ -75,11 +76,15 @@
%%--------------------------------------------------------------------
-spec start_link(role(),
inet:socket(),
- proplists:proplist()
+ ssh_options:options()
) -> {ok, pid()}.
%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
start_link(Role, Socket, Options) ->
- {ok, proc_lib:spawn_link(?MODULE, init_connection_handler, [Role, Socket, Options])}.
+ {ok, proc_lib:spawn_opt(?MODULE,
+ init_connection_handler,
+ [Role, Socket, Options],
+ [link, {message_queue_data,off_heap}]
+ )}.
%%--------------------------------------------------------------------
@@ -98,12 +103,10 @@ stop(ConnectionHandler)->
%% Internal application API
%%====================================================================
--define(DefaultTransport, {tcp, gen_tcp, tcp_closed} ).
-
%%--------------------------------------------------------------------
-spec start_connection(role(),
inet:socket(),
- proplists:proplist(),
+ ssh_options:options(),
timeout()
) -> {ok, connection_ref()} | {error, term()}.
%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
@@ -120,9 +123,8 @@ start_connection(client = Role, Socket, Options, Timeout) ->
end;
start_connection(server = Role, Socket, Options, Timeout) ->
- SSH_Opts = proplists:get_value(ssh_opts, Options, []),
try
- case proplists:get_value(parallel_login, SSH_Opts, false) of
+ case ?GET_OPT(parallel_login, Options) of
true ->
HandshakerPid =
spawn_link(fun() ->
@@ -335,8 +337,7 @@ renegotiate_data(ConnectionHandler) ->
transport_protocol :: atom(), % ex: tcp
transport_cb :: atom(), % ex: gen_tcp
transport_close_tag :: atom(), % ex: tcp_closed
- ssh_params :: #ssh{}
- | undefined,
+ ssh_params :: #ssh{},
socket :: inet:socket(),
decrypted_data_buffer = <<>> :: binary(),
encrypted_data_buffer = <<>> :: binary(),
@@ -345,7 +346,7 @@ renegotiate_data(ConnectionHandler) ->
| undefined,
last_size_rekey = 0 :: non_neg_integer(),
event_queue = [] :: list(),
- opts :: proplists:proplist(),
+% opts :: ssh_options:options(),
inet_initial_recbuf_size :: pos_integer()
| undefined
}).
@@ -356,107 +357,121 @@ renegotiate_data(ConnectionHandler) ->
%%--------------------------------------------------------------------
-spec init_connection_handler(role(),
inet:socket(),
- proplists:proplist()
+ ssh_options:options()
) -> no_return().
%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
init_connection_handler(Role, Socket, Opts) ->
- process_flag(trap_exit, true),
- S0 = init_process_state(Role, Socket, Opts),
- try
- {Protocol, Callback, CloseTag} =
- proplists:get_value(transport, Opts, ?DefaultTransport),
- S0#data{ssh_params = init_ssh_record(Role, Socket, Opts),
- transport_protocol = Protocol,
- transport_cb = Callback,
- transport_close_tag = CloseTag
- }
- of
- S ->
- gen_statem:enter_loop(?MODULE,
- [], %%[{debug,[trace,log,statistics,debug]} || Role==server],
- handle_event_function,
- {hello,Role},
- S)
- catch
- _:Error ->
- gen_statem:enter_loop(?MODULE,
- [],
- handle_event_function,
- {init_error,Error},
- S0)
+ case init([Role, Socket, Opts]) of
+ {ok, StartState, D} ->
+ process_flag(trap_exit, true),
+ gen_statem:enter_loop(?MODULE,
+ [], %%[{debug,[trace,log,statistics,debug]} ], %% []
+ StartState,
+ D);
+
+ {stop, enotconn} ->
+ %% Handles the abnormal sequence:
+ %% SYN->
+ %% <-SYNACK
+ %% ACK->
+ %% RST->
+ exit({shutdown, "TCP connection to server was prematurely closed by the client"});
+
+ {stop, OtherError} ->
+ exit({shutdown, {init,OtherError}})
end.
-init_process_state(Role, Socket, Opts) ->
- D = #data{connection_state =
- C = #connection{channel_cache = ssh_channel:cache_create(),
- channel_id_seed = 0,
- port_bindings = [],
- requests = [],
- options = Opts},
- starter = proplists:get_value(user_pid, Opts),
- socket = Socket,
- opts = Opts
- },
- case Role of
- client ->
- %% Start the renegotiation timers
- timer:apply_after(?REKEY_TIMOUT, gen_statem, cast, [self(), renegotiate]),
- timer:apply_after(?REKEY_DATA_TIMOUT, gen_statem, cast, [self(), data_size]),
- cache_init_idle_timer(D);
- server ->
- D#data{connection_state = init_connection(Role, C, Opts)}
+
+init([Role,Socket,Opts]) ->
+ case inet:peername(Socket) of
+ {ok, PeerAddr} ->
+ {Protocol, Callback, CloseTag} = ?GET_OPT(transport, Opts),
+ C = #connection{channel_cache = ssh_channel:cache_create(),
+ channel_id_seed = 0,
+ port_bindings = [],
+ requests = [],
+ options = Opts},
+ D0 = #data{starter = ?GET_INTERNAL_OPT(user_pid, Opts),
+ connection_state = C,
+ socket = Socket,
+ transport_protocol = Protocol,
+ transport_cb = Callback,
+ transport_close_tag = CloseTag,
+ ssh_params = init_ssh_record(Role, Socket, PeerAddr, Opts)
+ },
+ D = case Role of
+ client ->
+ %% Start the renegotiation timers
+ timer:apply_after(?REKEY_TIMOUT, gen_statem, cast, [self(), renegotiate]),
+ timer:apply_after(?REKEY_DATA_TIMOUT, gen_statem, cast, [self(), data_size]),
+ cache_init_idle_timer(D0);
+ server ->
+ Sups = ?GET_INTERNAL_OPT(supervisors, Opts),
+ cache_init_idle_timer(
+ D0#data{connection_state =
+ C#connection{cli_spec = ?GET_OPT(ssh_cli, Opts, {ssh_cli,[?GET_OPT(shell, Opts)]}),
+ exec = ?GET_OPT(exec, Opts),
+ system_supervisor = proplists:get_value(system_sup, Sups),
+ sub_system_supervisor = proplists:get_value(subsystem_sup, Sups),
+ connection_supervisor = proplists:get_value(connection_sup, Sups)
+ }})
+ end,
+ {ok, {hello,Role}, D};
+
+ {error,Error} ->
+ {stop, Error}
end.
-init_connection(server, C = #connection{}, Opts) ->
- Sups = proplists:get_value(supervisors, Opts),
- SystemSup = proplists:get_value(system_sup, Sups),
- SubSystemSup = proplists:get_value(subsystem_sup, Sups),
- ConnectionSup = proplists:get_value(connection_sup, Sups),
- Shell = proplists:get_value(shell, Opts),
- Exec = proplists:get_value(exec, Opts),
- CliSpec = proplists:get_value(ssh_cli, Opts, {ssh_cli, [Shell]}),
- C#connection{cli_spec = CliSpec,
- exec = Exec,
- system_supervisor = SystemSup,
- sub_system_supervisor = SubSystemSup,
- connection_supervisor = ConnectionSup
- }.
-
init_ssh_record(Role, Socket, Opts) ->
- {ok, PeerAddr} = inet:peername(Socket),
- KeyCb = proplists:get_value(key_cb, Opts, ssh_file),
- AuthMethods = proplists:get_value(auth_methods, Opts, ?SUPPORTED_AUTH_METHODS),
+ %% Export of this internal function is
+ %% intended for low-level protocol test suites
+ {ok,PeerAddr} = inet:peername(Socket),
+ init_ssh_record(Role, Socket, PeerAddr, Opts).
+
+init_ssh_record(Role, _Socket, PeerAddr, Opts) ->
+ KeyCb = ?GET_OPT(key_cb, Opts),
+ AuthMethods = ?GET_OPT(auth_methods, Opts),
S0 = #ssh{role = Role,
key_cb = KeyCb,
opts = Opts,
userauth_supported_methods = AuthMethods,
available_host_keys = supported_host_keys(Role, KeyCb, Opts),
- random_length_padding = proplists:get_value(max_random_length_padding,
- Opts,
- (#ssh{})#ssh.random_length_padding)
+ random_length_padding = ?GET_OPT(max_random_length_padding, Opts)
},
{Vsn, Version} = ssh_transport:versions(Role, Opts),
case Role of
client ->
- PeerName = proplists:get_value(host, Opts),
- S0#ssh{c_vsn = Vsn,
- c_version = Version,
- io_cb = case proplists:get_value(user_interaction, Opts, true) of
- true -> ssh_io;
- false -> ssh_no_io
- end,
- userauth_quiet_mode = proplists:get_value(quiet_mode, Opts, false),
- peer = {PeerName, PeerAddr}
- };
+ PeerName = case ?GET_INTERNAL_OPT(host, Opts) of
+ PeerIP when is_tuple(PeerIP) ->
+ inet_parse:ntoa(PeerIP);
+ PeerName0 when is_atom(PeerName0) ->
+ atom_to_list(PeerName0);
+ PeerName0 when is_list(PeerName0) ->
+ PeerName0
+ end,
+ S1 =
+ S0#ssh{c_vsn = Vsn,
+ c_version = Version,
+ io_cb = case ?GET_OPT(user_interaction, Opts) of
+ true -> ssh_io;
+ false -> ssh_no_io
+ end,
+ userauth_quiet_mode = ?GET_OPT(quiet_mode, Opts),
+ peer = {PeerName, PeerAddr}
+ },
+ S1#ssh{userauth_pubkeys = [K || K <- ?GET_OPT(pref_public_key_algs, Opts),
+ is_usable_user_pubkey(K, S1)
+ ]
+ };
server ->
S0#ssh{s_vsn = Vsn,
s_version = Version,
- io_cb = proplists:get_value(io_cb, Opts, ssh_io),
+ io_cb = ?GET_INTERNAL_OPT(io_cb, Opts, ssh_io),
userauth_methods = string:tokens(AuthMethods, ","),
kb_tries_left = 3,
peer = {undefined, PeerAddr}
@@ -474,51 +489,53 @@ init_ssh_record(Role, Socket, Opts) ->
-type renegotiate_flag() :: init | renegotiate.
-type state_name() ::
- {init_error,any()}
- | {hello, role()}
- | {kexinit, role(), renegotiate_flag()}
- | {key_exchange, role(), renegotiate_flag()}
- | {key_exchange_dh_gex_init, server, renegotiate_flag()}
+ {hello, role() }
+ | {kexinit, role(), renegotiate_flag()}
+ | {key_exchange, role(), renegotiate_flag()}
+ | {key_exchange_dh_gex_init, server, renegotiate_flag()}
| {key_exchange_dh_gex_reply, client, renegotiate_flag()}
- | {new_keys, role()}
- | {service_request, role()}
- | {userauth, role()}
- | {userauth_keyboard_interactive, role()}
- | {connected, role()}
+ | {new_keys, role(), renegotiate_flag()}
+ | {ext_info, role(), renegotiate_flag()}
+ | {service_request, role() }
+ | {userauth, role() }
+ | {userauth_keyboard_interactive, role() }
+ | {userauth_keyboard_interactive_extra, server }
+ | {userauth_keyboard_interactive_info_response, client }
+ | {connected, role() }
.
--type handle_event_result() :: gen_statem:handle_event_result().
+%% The state names must fulfill some rules regarding
+%% where the role() and the renegotiate_flag() is placed:
+
+-spec role(state_name()) -> role().
+role({_,Role}) -> Role;
+role({_,Role,_}) -> Role.
+
+-spec renegotiation(state_name()) -> boolean().
+renegotiation({_,_,ReNeg}) -> ReNeg == renegotiation;
+renegotiation(_) -> false.
+
+
+-define(CONNECTED(StateName),
+ (element(1,StateName) == connected orelse
+ element(1,StateName) == ext_info ) ).
-spec handle_event(gen_statem:event_type(),
event_content(),
state_name(),
#data{}
- ) -> handle_event_result().
+ ) -> gen_statem:event_handler_result(state_name()) .
%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-%%% ######## Error in the initialisation ####
-
-handle_event(_, _Event, {init_error,Error}, _) ->
- case Error of
- {badmatch,{error,enotconn}} ->
- %% Handles the abnormal sequence:
- %% SYN->
- %% <-SYNACK
- %% ACK->
- %% RST->
- {stop, {shutdown,"TCP connenction to server was prematurely closed by the client"}};
-
- OtherError ->
- {stop, {shutdown,{init,OtherError}}}
- end;
-
+callback_mode() ->
+ handle_event_function.
%%% ######## {hello, client|server} ####
%% The very first event that is sent when the we are set as controlling process of Socket
handle_event(_, socket_control, {hello,_}, D) ->
VsnMsg = ssh_transport:hello_version_msg(string_version(D#data.ssh_params)),
- ok = send_bytes(VsnMsg, D),
+ send_bytes(VsnMsg, D),
case inet:getopts(Socket=D#data.socket, [recbuf]) of
{ok, [{recbuf,Size}]} ->
%% Set the socket to the hello text line handling mode:
@@ -538,12 +555,13 @@ handle_event(_, {info_line,_Line}, {hello,Role}, D) ->
case Role of
client ->
%% The server may send info lines to the client before the version_exchange
+ %% RFC4253/4.2
inet:setopts(D#data.socket, [{active, once}]),
keep_state_and_data;
server ->
%% But the client may NOT send them to the server. Openssh answers with cleartext,
%% and so do we
- ok = send_bytes("Protocol mismatch.", D),
+ send_bytes("Protocol mismatch.", D),
{stop, {shutdown,"Protocol mismatch in version exchange. Client sent info lines."}}
end;
@@ -558,7 +576,7 @@ handle_event(_, {version_exchange,Version}, {hello,Role}, D) ->
{active, once},
{recbuf, D#data.inet_initial_recbuf_size}]),
{KeyInitMsg, SshPacket, Ssh} = ssh_transport:key_exchange_init_msg(Ssh1),
- ok = send_bytes(SshPacket, D),
+ send_bytes(SshPacket, D),
{next_state, {kexinit,Role,init}, D#data{ssh_params = Ssh,
key_exchange_init_msg = KeyInitMsg}};
not_supported ->
@@ -576,7 +594,7 @@ handle_event(_, {#ssh_msg_kexinit{}=Kex, Payload}, {kexinit,Role,ReNeg},
Ssh1 = ssh_transport:key_init(peer_role(Role), D#data.ssh_params, Payload),
Ssh = case ssh_transport:handle_kexinit_msg(Kex, OwnKex, Ssh1) of
{ok, NextKexMsg, Ssh2} when Role==client ->
- ok = send_bytes(NextKexMsg, D),
+ send_bytes(NextKexMsg, D),
Ssh2;
{ok, Ssh2} when Role==server ->
Ssh2
@@ -589,43 +607,53 @@ handle_event(_, {#ssh_msg_kexinit{}=Kex, Payload}, {kexinit,Role,ReNeg},
%%%---- diffie-hellman
handle_event(_, #ssh_msg_kexdh_init{} = Msg, {key_exchange,server,ReNeg}, D) ->
{ok, KexdhReply, Ssh1} = ssh_transport:handle_kexdh_init(Msg, D#data.ssh_params),
- ok = send_bytes(KexdhReply, D),
- {ok, NewKeys, Ssh} = ssh_transport:new_keys_message(Ssh1),
- ok = send_bytes(NewKeys, D),
+ send_bytes(KexdhReply, D),
+ {ok, NewKeys, Ssh2} = ssh_transport:new_keys_message(Ssh1),
+ send_bytes(NewKeys, D),
+ {ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh2),
+ send_bytes(ExtInfo, D),
{next_state, {new_keys,server,ReNeg}, D#data{ssh_params=Ssh}};
handle_event(_, #ssh_msg_kexdh_reply{} = Msg, {key_exchange,client,ReNeg}, D) ->
- {ok, NewKeys, Ssh} = ssh_transport:handle_kexdh_reply(Msg, D#data.ssh_params),
- ok = send_bytes(NewKeys, D),
+ {ok, NewKeys, Ssh1} = ssh_transport:handle_kexdh_reply(Msg, D#data.ssh_params),
+ send_bytes(NewKeys, D),
+ {ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh1),
+ send_bytes(ExtInfo, D),
{next_state, {new_keys,client,ReNeg}, D#data{ssh_params=Ssh}};
%%%---- diffie-hellman group exchange
handle_event(_, #ssh_msg_kex_dh_gex_request{} = Msg, {key_exchange,server,ReNeg}, D) ->
- {ok, GexGroup, Ssh} = ssh_transport:handle_kex_dh_gex_request(Msg, D#data.ssh_params),
- ok = send_bytes(GexGroup, D),
+ {ok, GexGroup, Ssh1} = ssh_transport:handle_kex_dh_gex_request(Msg, D#data.ssh_params),
+ send_bytes(GexGroup, D),
+ Ssh = ssh_transport:parallell_gen_key(Ssh1),
{next_state, {key_exchange_dh_gex_init,server,ReNeg}, D#data{ssh_params=Ssh}};
handle_event(_, #ssh_msg_kex_dh_gex_request_old{} = Msg, {key_exchange,server,ReNeg}, D) ->
- {ok, GexGroup, Ssh} = ssh_transport:handle_kex_dh_gex_request(Msg, D#data.ssh_params),
- ok = send_bytes(GexGroup, D),
+ {ok, GexGroup, Ssh1} = ssh_transport:handle_kex_dh_gex_request(Msg, D#data.ssh_params),
+ send_bytes(GexGroup, D),
+ Ssh = ssh_transport:parallell_gen_key(Ssh1),
{next_state, {key_exchange_dh_gex_init,server,ReNeg}, D#data{ssh_params=Ssh}};
handle_event(_, #ssh_msg_kex_dh_gex_group{} = Msg, {key_exchange,client,ReNeg}, D) ->
{ok, KexGexInit, Ssh} = ssh_transport:handle_kex_dh_gex_group(Msg, D#data.ssh_params),
- ok = send_bytes(KexGexInit, D),
+ send_bytes(KexGexInit, D),
{next_state, {key_exchange_dh_gex_reply,client,ReNeg}, D#data{ssh_params=Ssh}};
%%%---- elliptic curve diffie-hellman
handle_event(_, #ssh_msg_kex_ecdh_init{} = Msg, {key_exchange,server,ReNeg}, D) ->
{ok, KexEcdhReply, Ssh1} = ssh_transport:handle_kex_ecdh_init(Msg, D#data.ssh_params),
- ok = send_bytes(KexEcdhReply, D),
- {ok, NewKeys, Ssh} = ssh_transport:new_keys_message(Ssh1),
- ok = send_bytes(NewKeys, D),
+ send_bytes(KexEcdhReply, D),
+ {ok, NewKeys, Ssh2} = ssh_transport:new_keys_message(Ssh1),
+ send_bytes(NewKeys, D),
+ {ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh2),
+ send_bytes(ExtInfo, D),
{next_state, {new_keys,server,ReNeg}, D#data{ssh_params=Ssh}};
handle_event(_, #ssh_msg_kex_ecdh_reply{} = Msg, {key_exchange,client,ReNeg}, D) ->
- {ok, NewKeys, Ssh} = ssh_transport:handle_kex_ecdh_reply(Msg, D#data.ssh_params),
- ok = send_bytes(NewKeys, D),
+ {ok, NewKeys, Ssh1} = ssh_transport:handle_kex_ecdh_reply(Msg, D#data.ssh_params),
+ send_bytes(NewKeys, D),
+ {ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh1),
+ send_bytes(ExtInfo, D),
{next_state, {new_keys,client,ReNeg}, D#data{ssh_params=Ssh}};
@@ -633,9 +661,11 @@ handle_event(_, #ssh_msg_kex_ecdh_reply{} = Msg, {key_exchange,client,ReNeg}, D)
handle_event(_, #ssh_msg_kex_dh_gex_init{} = Msg, {key_exchange_dh_gex_init,server,ReNeg}, D) ->
{ok, KexGexReply, Ssh1} = ssh_transport:handle_kex_dh_gex_init(Msg, D#data.ssh_params),
- ok = send_bytes(KexGexReply, D),
- {ok, NewKeys, Ssh} = ssh_transport:new_keys_message(Ssh1),
- ok = send_bytes(NewKeys, D),
+ send_bytes(KexGexReply, D),
+ {ok, NewKeys, Ssh2} = ssh_transport:new_keys_message(Ssh1),
+ send_bytes(NewKeys, D),
+ {ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh2),
+ send_bytes(ExtInfo, D),
{next_state, {new_keys,server,ReNeg}, D#data{ssh_params=Ssh}};
@@ -643,37 +673,68 @@ handle_event(_, #ssh_msg_kex_dh_gex_init{} = Msg, {key_exchange_dh_gex_init,serv
handle_event(_, #ssh_msg_kex_dh_gex_reply{} = Msg, {key_exchange_dh_gex_reply,client,ReNeg}, D) ->
{ok, NewKeys, Ssh1} = ssh_transport:handle_kex_dh_gex_reply(Msg, D#data.ssh_params),
- ok = send_bytes(NewKeys, D),
- {next_state, {new_keys,client,ReNeg}, D#data{ssh_params=Ssh1}};
+ send_bytes(NewKeys, D),
+ {ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh1),
+ send_bytes(ExtInfo, D),
+ {next_state, {new_keys,client,ReNeg}, D#data{ssh_params=Ssh}};
%%% ######## {new_keys, client|server} ####
%% First key exchange round:
-handle_event(_, #ssh_msg_newkeys{} = Msg, {new_keys,Role,init}, D) ->
+handle_event(_, #ssh_msg_newkeys{} = Msg, {new_keys,client,init}, D) ->
{ok, Ssh1} = ssh_transport:handle_new_keys(Msg, D#data.ssh_params),
- Ssh = case Role of
- client ->
- {MsgReq, Ssh2} = ssh_auth:service_request_msg(Ssh1),
- ok = send_bytes(MsgReq, D),
- Ssh2;
- server ->
- Ssh1
- end,
- {next_state, {service_request,Role}, D#data{ssh_params=Ssh}};
+ %% {ok, ExtInfo, Ssh2} = ssh_transport:ext_info_message(Ssh1),
+ %% send_bytes(ExtInfo, D),
+ {MsgReq, Ssh} = ssh_auth:service_request_msg(Ssh1),
+ send_bytes(MsgReq, D),
+ {next_state, {ext_info,client,init}, D#data{ssh_params=Ssh}};
+
+handle_event(_, #ssh_msg_newkeys{} = Msg, {new_keys,server,init}, D) ->
+ {ok, Ssh} = ssh_transport:handle_new_keys(Msg, D#data.ssh_params),
+ %% {ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh1),
+ %% send_bytes(ExtInfo, D),
+ {next_state, {ext_info,server,init}, D#data{ssh_params=Ssh}};
%% Subsequent key exchange rounds (renegotiation):
-handle_event(_, #ssh_msg_newkeys{}, {new_keys,Role,renegotiate}, D) ->
+handle_event(_, #ssh_msg_newkeys{} = Msg, {new_keys,Role,renegotiate}, D) ->
+ {ok, Ssh} = ssh_transport:handle_new_keys(Msg, D#data.ssh_params),
+ %% {ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh1),
+ %% send_bytes(ExtInfo, D),
+ {next_state, {ext_info,Role,renegotiate}, D#data{ssh_params=Ssh}};
+
+
+%%% ######## {ext_info, client|server, init|renegotiate} ####
+
+handle_event(_, #ssh_msg_ext_info{}=Msg, {ext_info,Role,init}, D0) ->
+ D = handle_ssh_msg_ext_info(Msg, D0),
+ {next_state, {service_request,Role}, D};
+
+handle_event(_, #ssh_msg_ext_info{}=Msg, {ext_info,Role,renegotiate}, D0) ->
+ D = handle_ssh_msg_ext_info(Msg, D0),
{next_state, {connected,Role}, D};
-%%% ######## {service_request, client|server}
+handle_event(_, #ssh_msg_newkeys{}=Msg, {ext_info,_Role,renegotiate}, D) ->
+ {ok, Ssh} = ssh_transport:handle_new_keys(Msg, D#data.ssh_params),
+ {keep_state, D#data{ssh_params = Ssh}};
+
+
+handle_event(internal, Msg, {ext_info,Role,init}, D) when is_tuple(Msg) ->
+ %% If something else arrives, goto next state and handle the event in that one
+ {next_state, {service_request,Role}, D, [postpone]};
+
+handle_event(internal, Msg, {ext_info,Role,_ReNegFlag}, D) when is_tuple(Msg) ->
+ %% If something else arrives, goto next state and handle the event in that one
+ {next_state, {connected,Role}, D, [postpone]};
+
+%%% ######## {service_request, client|server} ####
handle_event(_, Msg = #ssh_msg_service_request{name=ServiceName}, StateName = {service_request,server}, D) ->
case ServiceName of
"ssh-userauth" ->
Ssh0 = #ssh{session_id=SessionId} = D#data.ssh_params,
{ok, {Reply, Ssh}} = ssh_auth:handle_userauth_request(Msg, SessionId, Ssh0),
- ok = send_bytes(Reply, D),
+ send_bytes(Reply, D),
{next_state, {userauth,server}, D#data{ssh_params = Ssh}};
_ ->
@@ -685,7 +746,7 @@ handle_event(_, Msg = #ssh_msg_service_request{name=ServiceName}, StateName = {s
handle_event(_, #ssh_msg_service_accept{name = "ssh-userauth"}, {service_request,client},
#data{ssh_params = #ssh{service="ssh-userauth"} = Ssh0} = State) ->
{Msg, Ssh} = ssh_auth:init_userauth_request_msg(Ssh0),
- ok = send_bytes(Msg, State),
+ send_bytes(Msg, State),
{next_state, {userauth,client}, State#data{auth_user = Ssh#ssh.user, ssh_params = Ssh}};
@@ -702,7 +763,7 @@ handle_event(_,
%% Probably the very first userauth_request but we deny unauthorized login
{not_authorized, _, {Reply,Ssh}} =
ssh_auth:handle_userauth_request(Msg, Ssh0#ssh.session_id, Ssh0),
- ok = send_bytes(Reply, D),
+ send_bytes(Reply, D),
{keep_state, D#data{ssh_params = Ssh}};
{"ssh-connection", "ssh-connection", Method} ->
@@ -712,7 +773,7 @@ handle_event(_,
%% Yepp! we support this method
case ssh_auth:handle_userauth_request(Msg, Ssh0#ssh.session_id, Ssh0) of
{authorized, User, {Reply, Ssh}} ->
- ok = send_bytes(Reply, D),
+ send_bytes(Reply, D),
D#data.starter ! ssh_connected,
connected_fun(User, Method, D),
{next_state, {connected,server},
@@ -720,11 +781,11 @@ handle_event(_,
ssh_params = Ssh#ssh{authenticated = true}}};
{not_authorized, {User, Reason}, {Reply, Ssh}} when Method == "keyboard-interactive" ->
retry_fun(User, Reason, D),
- ok = send_bytes(Reply, D),
+ send_bytes(Reply, D),
{next_state, {userauth_keyboard_interactive,server}, D#data{ssh_params = Ssh}};
{not_authorized, {User, Reason}, {Reply, Ssh}} ->
retry_fun(User, Reason, D),
- ok = send_bytes(Reply, D),
+ send_bytes(Reply, D),
{keep_state, D#data{ssh_params = Ssh}}
end;
false ->
@@ -745,6 +806,11 @@ handle_event(_,
end;
%%---- userauth success to client
+handle_event(_, #ssh_msg_ext_info{}=Msg, {userauth,client}, D0) ->
+ %% FIXME: need new state to receive this msg!
+ D = handle_ssh_msg_ext_info(Msg, D0),
+ {keep_state, D};
+
handle_event(_, #ssh_msg_userauth_success{}, {userauth,client}, D=#data{ssh_params = Ssh}) ->
D#data.starter ! ssh_connected,
{next_state, {connected,client}, D#data{ssh_params=Ssh#ssh{authenticated = true}}};
@@ -794,9 +860,13 @@ handle_event(_, #ssh_msg_userauth_banner{message = Msg}, {userauth,client}, D) -
handle_event(_, #ssh_msg_userauth_info_request{} = Msg, {userauth_keyboard_interactive, client},
#data{ssh_params = Ssh0} = D) ->
- {ok, {Reply, Ssh}} = ssh_auth:handle_userauth_info_request(Msg, Ssh0#ssh.io_cb, Ssh0),
- send_bytes(Reply, D),
- {next_state, {userauth_keyboard_interactive_info_response,client}, D#data{ssh_params = Ssh}};
+ case ssh_auth:handle_userauth_info_request(Msg, Ssh0) of
+ {ok, {Reply, Ssh}} ->
+ send_bytes(Reply, D),
+ {next_state, {userauth_keyboard_interactive_info_response,client}, D#data{ssh_params = Ssh}};
+ not_ok ->
+ {next_state, {userauth,client}, D, [postpone]}
+ end;
handle_event(_, #ssh_msg_userauth_info_response{} = Msg, {userauth_keyboard_interactive, server}, D) ->
case ssh_auth:handle_userauth_info_response(Msg, D#data.ssh_params) of
@@ -809,34 +879,60 @@ handle_event(_, #ssh_msg_userauth_info_response{} = Msg, {userauth_keyboard_inte
{not_authorized, {User, Reason}, {Reply, Ssh}} ->
retry_fun(User, Reason, D),
send_bytes(Reply, D),
- {next_state, {userauth,server}, D#data{ssh_params = Ssh}}
+ {next_state, {userauth,server}, D#data{ssh_params = Ssh}};
+
+ {authorized_but_one_more, _User, {Reply, Ssh}} ->
+ send_bytes(Reply, D),
+ {next_state, {userauth_keyboard_interactive_extra,server}, D#data{ssh_params = Ssh}}
end;
-handle_event(_, Msg = #ssh_msg_userauth_failure{}, {userauth_keyboard_interactive, client},
+handle_event(_, #ssh_msg_userauth_info_response{} = Msg, {userauth_keyboard_interactive_extra, server}, D) ->
+ {authorized, User, {Reply, Ssh}} = ssh_auth:handle_userauth_info_response({extra,Msg}, D#data.ssh_params),
+ send_bytes(Reply, D),
+ D#data.starter ! ssh_connected,
+ connected_fun(User, "keyboard-interactive", D),
+ {next_state, {connected,server}, D#data{auth_user = User,
+ ssh_params = Ssh#ssh{authenticated = true}}};
+
+handle_event(_, #ssh_msg_userauth_failure{}, {userauth_keyboard_interactive, client},
#data{ssh_params = Ssh0} = D0) ->
Prefs = [{Method,M,F,A} || {Method,M,F,A} <- Ssh0#ssh.userauth_preference,
Method =/= "keyboard-interactive"],
D = D0#data{ssh_params = Ssh0#ssh{userauth_preference=Prefs}},
- {next_state, {userauth,client}, D, [{next_event, internal, Msg}]};
+ {next_state, {userauth,client}, D, [postpone]};
+
+handle_event(_, #ssh_msg_userauth_failure{}, {userauth_keyboard_interactive_info_response, client},
+ #data{ssh_params = Ssh0} = D0) ->
+ Opts = Ssh0#ssh.opts,
+ D = case ?GET_OPT(password, Opts) of
+ undefined ->
+ D0;
+ _ ->
+ D0#data{ssh_params =
+ Ssh0#ssh{opts = ?PUT_OPT({password,not_ok}, Opts)}} % FIXME:intermodule dependency
+ end,
+ {next_state, {userauth,client}, D, [postpone]};
-handle_event(_, Msg=#ssh_msg_userauth_failure{}, {userauth_keyboard_interactive_info_response, client}, D) ->
- {next_state, {userauth,client}, D, [{next_event, internal, Msg}]};
+handle_event(_, #ssh_msg_ext_info{}=Msg, {userauth_keyboard_interactive_info_response, client}, D0) ->
+ %% FIXME: need new state to receive this msg!
+ D = handle_ssh_msg_ext_info(Msg, D0),
+ {keep_state, D};
-handle_event(_, Msg=#ssh_msg_userauth_success{}, {userauth_keyboard_interactive_info_response, client}, D) ->
- {next_state, {userauth,client}, D, [{next_event, internal, Msg}]};
+handle_event(_, #ssh_msg_userauth_success{}, {userauth_keyboard_interactive_info_response, client}, D) ->
+ {next_state, {userauth,client}, D, [postpone]};
-handle_event(_, Msg=#ssh_msg_userauth_info_request{}, {userauth_keyboard_interactive_info_response, client}, D) ->
- {next_state, {userauth_keyboard_interactive,client}, D, [{next_event, internal, Msg}]};
+handle_event(_, #ssh_msg_userauth_info_request{}, {userauth_keyboard_interactive_info_response, client}, D) ->
+ {next_state, {userauth_keyboard_interactive,client}, D, [postpone]};
%%% ######## {connected, client|server} ####
-handle_event(_, {#ssh_msg_kexinit{},_} = Event, {connected,Role}, D0) ->
+handle_event(_, {#ssh_msg_kexinit{},_}, {connected,Role}, D0) ->
{KeyInitMsg, SshPacket, Ssh} = ssh_transport:key_exchange_init_msg(D0#data.ssh_params),
D = D0#data{ssh_params = Ssh,
key_exchange_init_msg = KeyInitMsg},
send_bytes(SshPacket, D),
- {next_state, {kexinit,Role,renegotiate}, D, [{next_event, internal, Event}]};
+ {next_state, {kexinit,Role,renegotiate}, D, [postpone]};
handle_event(_, #ssh_msg_disconnect{description=Desc} = Msg, StateName, D0) ->
{disconnect, _, {{replies,Replies}, _}} =
@@ -885,6 +981,9 @@ handle_event(internal, Msg=#ssh_msg_channel_extended_data{}, StateName, D) -
handle_event(internal, Msg=#ssh_msg_channel_eof{}, StateName, D) ->
handle_connection_msg(Msg, StateName, D);
+handle_event(internal, Msg=#ssh_msg_channel_close{}, {connected,server} = StateName, D) ->
+ handle_connection_msg(Msg, StateName, cache_request_idle_timer_check(D));
+
handle_event(internal, Msg=#ssh_msg_channel_close{}, StateName, D) ->
handle_connection_msg(Msg, StateName, D);
@@ -892,6 +991,7 @@ handle_event(internal, Msg=#ssh_msg_channel_request{}, StateName, D) -
handle_connection_msg(Msg, StateName, D);
handle_event(internal, Msg=#ssh_msg_channel_success{}, StateName, D) ->
+ update_inet_buffers(D#data.socket),
handle_connection_msg(Msg, StateName, D);
handle_event(internal, Msg=#ssh_msg_channel_failure{}, StateName, D) ->
@@ -915,7 +1015,7 @@ handle_event(cast, renegotiate, _, _) ->
handle_event(cast, data_size, {connected,Role}, D) ->
{ok, [{send_oct,Sent0}]} = inet:getstat(D#data.socket, [send_oct]),
Sent = Sent0 - D#data.last_size_rekey,
- MaxSent = proplists:get_value(rekey_limit, D#data.opts, 1024000000),
+ MaxSent = ?GET_OPT(rekey_limit, (D#data.ssh_params)#ssh.opts),
timer:apply_after(?REKEY_DATA_TIMOUT, gen_statem, cast, [self(), data_size]),
case Sent >= MaxSent of
true ->
@@ -936,12 +1036,10 @@ handle_event(cast, data_size, _, _) ->
-handle_event(cast, _, StateName, _) when StateName /= {connected,server},
- StateName /= {connected,client} ->
+handle_event(cast, _, StateName, _) when not ?CONNECTED(StateName) ->
{keep_state_and_data, [postpone]};
-
-handle_event(cast, {adjust_window,ChannelId,Bytes}, {connected,_}, D) ->
+handle_event(cast, {adjust_window,ChannelId,Bytes}, StateName, D) when ?CONNECTED(StateName) ->
case ssh_channel:cache_lookup(cache(D), ChannelId) of
#channel{recv_window_size = WinSize,
recv_window_pending = Pending,
@@ -967,23 +1065,24 @@ handle_event(cast, {adjust_window,ChannelId,Bytes}, {connected,_}, D) ->
keep_state_and_data
end;
-handle_event(cast, {reply_request,success,ChannelId}, {connected,_}, D) ->
+handle_event(cast, {reply_request,success,ChannelId}, StateName, D) when ?CONNECTED(StateName) ->
case ssh_channel:cache_lookup(cache(D), ChannelId) of
#channel{remote_id = RemoteId} ->
Msg = ssh_connection:channel_success_msg(RemoteId),
+ update_inet_buffers(D#data.socket),
{keep_state, send_msg(Msg,D)};
undefined ->
keep_state_and_data
end;
-handle_event(cast, {request,ChannelPid, ChannelId, Type, Data}, {connected,_}, D) ->
+handle_event(cast, {request,ChannelPid, ChannelId, Type, Data}, StateName, D) when ?CONNECTED(StateName) ->
{keep_state, handle_request(ChannelPid, ChannelId, Type, Data, false, none, D)};
-handle_event(cast, {request,ChannelId,Type,Data}, {connected,_}, D) ->
+handle_event(cast, {request,ChannelId,Type,Data}, StateName, D) when ?CONNECTED(StateName) ->
{keep_state, handle_request(ChannelId, Type, Data, false, none, D)};
-handle_event(cast, {unknown,Data}, {connected,_}, D) ->
+handle_event(cast, {unknown,Data}, StateName, D) when ?CONNECTED(StateName) ->
Msg = #ssh_msg_unimplemented{sequence = Data},
{keep_state, send_msg(Msg,D)};
@@ -1006,13 +1105,13 @@ handle_event({call,From}, get_print_info, StateName, D) ->
{keep_state_and_data, [{reply,From,Reply}]};
handle_event({call,From}, {connection_info, Options}, _, D) ->
- Info = ssh_info(Options, D, []),
+ Info = fold_keys(Options, fun conn_info/2, D),
{keep_state_and_data, [{reply,From,Info}]};
handle_event({call,From}, {channel_info,ChannelId,Options}, _, D) ->
case ssh_channel:cache_lookup(cache(D), ChannelId) of
#channel{} = Channel ->
- Info = ssh_channel_info(Options, Channel, []),
+ Info = fold_keys(Options, fun chann_info/2, Channel),
{keep_state_and_data, [{reply,From,Info}]};
undefined ->
{keep_state_and_data, [{reply,From,[]}]}
@@ -1044,30 +1143,34 @@ handle_event({call,From}, stop, StateName, D0) ->
{Repls,D} = send_replies(Replies, D0),
{stop_and_reply, normal, [{reply,From,ok}|Repls], D#data{connection_state=Connection}};
-handle_event({call,_}, _, StateName, _) when StateName /= {connected,server},
- StateName /= {connected,client} ->
+
+handle_event({call,_}, _, StateName, _) when not ?CONNECTED(StateName) ->
{keep_state_and_data, [postpone]};
-handle_event({call,From}, {request, ChannelPid, ChannelId, Type, Data, Timeout}, {connected,_}, D0) ->
+handle_event({call,From}, {request, ChannelPid, ChannelId, Type, Data, Timeout}, StateName, D0)
+ when ?CONNECTED(StateName) ->
D = handle_request(ChannelPid, ChannelId, Type, Data, true, From, D0),
%% Note reply to channel will happen later when reply is recived from peer on the socket
start_channel_request_timer(ChannelId, From, Timeout),
{keep_state, cache_request_idle_timer_check(D)};
-handle_event({call,From}, {request, ChannelId, Type, Data, Timeout}, {connected,_}, D0) ->
+handle_event({call,From}, {request, ChannelId, Type, Data, Timeout}, StateName, D0)
+ when ?CONNECTED(StateName) ->
D = handle_request(ChannelId, Type, Data, true, From, D0),
%% Note reply to channel will happen later when reply is recived from peer on the socket
start_channel_request_timer(ChannelId, From, Timeout),
{keep_state, cache_request_idle_timer_check(D)};
-handle_event({call,From}, {data, ChannelId, Type, Data, Timeout}, {connected,_}, D0) ->
+handle_event({call,From}, {data, ChannelId, Type, Data, Timeout}, StateName, D0)
+ when ?CONNECTED(StateName) ->
{{replies, Replies}, Connection} =
ssh_connection:channel_data(ChannelId, Type, Data, D0#data.connection_state, From),
{Repls,D} = send_replies(Replies, D0#data{connection_state = Connection}),
start_channel_request_timer(ChannelId, From, Timeout), % FIXME: No message exchange so why?
{keep_state, D, Repls};
-handle_event({call,From}, {eof, ChannelId}, {connected,_}, D0) ->
+handle_event({call,From}, {eof, ChannelId}, StateName, D0)
+ when ?CONNECTED(StateName) ->
case ssh_channel:cache_lookup(cache(D0), ChannelId) of
#channel{remote_id = Id, sent_close = false} ->
D = send_msg(ssh_connection:channel_eof_msg(Id), D0),
@@ -1078,8 +1181,8 @@ handle_event({call,From}, {eof, ChannelId}, {connected,_}, D0) ->
handle_event({call,From},
{open, ChannelPid, Type, InitialWindowSize, MaxPacketSize, Data, Timeout},
- {connected,_},
- D0) ->
+ StateName,
+ D0) when ?CONNECTED(StateName) ->
erlang:monitor(process, ChannelPid),
{ChannelId, D1} = new_channel_id(D0),
D2 = send_msg(ssh_connection:channel_open_msg(Type, ChannelId,
@@ -1099,7 +1202,8 @@ handle_event({call,From},
start_channel_request_timer(ChannelId, From, Timeout),
{keep_state, cache_cancel_idle_timer(D)};
-handle_event({call,From}, {send_window, ChannelId}, {connected,_}, D) ->
+handle_event({call,From}, {send_window, ChannelId}, StateName, D)
+ when ?CONNECTED(StateName) ->
Reply = case ssh_channel:cache_lookup(cache(D), ChannelId) of
#channel{send_window_size = WinSize,
send_packet_size = Packsize} ->
@@ -1109,7 +1213,8 @@ handle_event({call,From}, {send_window, ChannelId}, {connected,_}, D) ->
end,
{keep_state_and_data, [{reply,From,Reply}]};
-handle_event({call,From}, {recv_window, ChannelId}, {connected,_}, D) ->
+handle_event({call,From}, {recv_window, ChannelId}, StateName, D)
+ when ?CONNECTED(StateName) ->
Reply = case ssh_channel:cache_lookup(cache(D), ChannelId) of
#channel{recv_window_size = WinSize,
recv_packet_size = Packsize} ->
@@ -1119,7 +1224,8 @@ handle_event({call,From}, {recv_window, ChannelId}, {connected,_}, D) ->
end,
{keep_state_and_data, [{reply,From,Reply}]};
-handle_event({call,From}, {close, ChannelId}, {connected,_}, D0) ->
+handle_event({call,From}, {close, ChannelId}, StateName, D0)
+ when ?CONNECTED(StateName) ->
case ssh_channel:cache_lookup(cache(D0), ChannelId) of
#channel{remote_id = Id} = Channel ->
D1 = send_msg(ssh_connection:channel_close_msg(Id), D0),
@@ -1158,17 +1264,17 @@ handle_event(info, {Proto, Sock, NewData}, StateName, D0 = #data{socket = Sock,
ssh_message:decode(set_kex_overload_prefix(DecryptedBytes,D))
of
Msg = #ssh_msg_kexinit{} ->
- {keep_state, D, [{next_event, internal, {Msg,DecryptedBytes}},
- {next_event, internal, prepare_next_packet}
+ {keep_state, D, [{next_event, internal, prepare_next_packet},
+ {next_event, internal, {Msg,DecryptedBytes}}
]};
Msg ->
- {keep_state, D, [{next_event, internal, Msg},
- {next_event, internal, prepare_next_packet}
+ {keep_state, D, [{next_event, internal, prepare_next_packet},
+ {next_event, internal, Msg}
]}
catch
_C:_E ->
disconnect(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Encountered unexpected input"},
+ description = "Bad packet"},
StateName, D)
end;
@@ -1183,13 +1289,12 @@ handle_event(info, {Proto, Sock, NewData}, StateName, D0 = #data{socket = Sock,
{bad_mac, Ssh1} ->
disconnect(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad mac"},
+ description = "Bad packet"},
StateName, D0#data{ssh_params=Ssh1});
- {error, {exceeds_max_size,PacketLen}} ->
+ {error, {exceeds_max_size,_PacketLen}} ->
disconnect(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad packet length "
- ++ integer_to_list(PacketLen)},
+ description = "Bad packet"},
StateName, D0)
catch
_C:_E ->
@@ -1206,16 +1311,20 @@ handle_event(internal, prepare_next_packet, _, D) ->
Sz when Sz >= Enough ->
self() ! {D#data.transport_protocol, D#data.socket, <<>>};
_ ->
- inet:setopts(D#data.socket, [{active, once}])
+ ok
end,
+ inet:setopts(D#data.socket, [{active, once}]),
keep_state_and_data;
handle_event(info, {CloseTag,Socket}, StateName,
D = #data{socket = Socket,
transport_close_tag = CloseTag}) ->
- disconnect(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
- description = "Connection closed"},
- StateName, D);
+ %% Simulate a disconnect from the peer
+ handle_event(info,
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
+ description = "Connection closed"},
+ StateName,
+ D);
handle_event(info, {timeout, {_, From} = Request}, _,
#data{connection_state = #connection{requests = Requests} = C0} = D) ->
@@ -1251,11 +1360,12 @@ handle_event(info, UnexpectedMessage, StateName, D = #data{ssh_params = Ssh}) ->
"Unexpected message '~p' received in state '~p'\n"
"Role: ~p\n"
"Peer: ~p\n"
- "Local Address: ~p\n", [UnexpectedMessage,
- StateName,
- Ssh#ssh.role,
- Ssh#ssh.peer,
- proplists:get_value(address, Ssh#ssh.opts)])),
+ "Local Address: ~p\n",
+ [UnexpectedMessage,
+ StateName,
+ Ssh#ssh.role,
+ Ssh#ssh.peer,
+ ?GET_INTERNAL_OPT(address, Ssh#ssh.opts)])),
error_logger:info_report(Msg),
keep_state_and_data;
@@ -1269,11 +1379,12 @@ handle_event(info, UnexpectedMessage, StateName, D = #data{ssh_params = Ssh}) ->
"Message: ~p\n"
"Role: ~p\n"
"Peer: ~p\n"
- "Local Address: ~p\n", [Other,
- UnexpectedMessage,
- Ssh#ssh.role,
- element(2,Ssh#ssh.peer),
- proplists:get_value(address, Ssh#ssh.opts)]
+ "Local Address: ~p\n",
+ [Other,
+ UnexpectedMessage,
+ Ssh#ssh.role,
+ element(2,Ssh#ssh.peer),
+ ?GET_INTERNAL_OPT(address, Ssh#ssh.opts)]
)),
error_logger:error_report(Msg),
keep_state_and_data
@@ -1282,11 +1393,16 @@ handle_event(info, UnexpectedMessage, StateName, D = #data{ssh_params = Ssh}) ->
handle_event(internal, {disconnect,Msg,_Reason}, StateName, D) ->
disconnect(Msg, StateName, D);
+handle_event(_Type, _Msg, {ext_info,Role,_ReNegFlag}, D) ->
+ %% If something else arrives, goto next state and handle the event in that one
+ {next_state, {connected,Role}, D, [postpone]};
+
handle_event(Type, Ev, StateName, D) ->
Descr =
case catch atom_to_list(element(1,Ev)) of
"ssh_msg_" ++_ when Type==internal ->
- "Message in wrong state";
+%% "Message in wrong state";
+ lists:flatten(io_lib:format("Message ~p in wrong state (~p)", [element(1,Ev), StateName]));
_ ->
"Internal error"
end,
@@ -1315,12 +1431,10 @@ terminate(shutdown, StateName, State0) ->
State = send_msg(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
description = "Application shutdown"},
State0),
-timer:sleep(400), %% FIXME!!! gen_tcp:shutdown instead
finalize_termination(StateName, State);
%% terminate({shutdown,Msg}, StateName, State0) when is_record(Msg,ssh_msg_disconnect)->
%% State = send_msg(Msg, State0),
-%% timer:sleep(400), %% FIXME!!! gen_tcp:shutdown instead
%% finalize_termination(StateName, Msg, State);
terminate({shutdown,_R}, StateName, State) ->
@@ -1382,12 +1496,12 @@ fmt_stat_rec(FieldNames, Rec, Exclude) ->
state_name(),
#data{},
term()
- ) -> {gen_statem:callback_mode(), state_name(), #data{}}.
+ ) -> {ok, state_name(), #data{}}.
%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
code_change(_OldVsn, StateName, State, _Extra) ->
- {handle_event_function, StateName, State}.
+ {ok, StateName, State}.
%%====================================================================
@@ -1397,11 +1511,11 @@ code_change(_OldVsn, StateName, State, _Extra) ->
%%--------------------------------------------------------------------
%% Starting
-start_the_connection_child(UserPid, Role, Socket, Options) ->
- Sups = proplists:get_value(supervisors, Options),
+start_the_connection_child(UserPid, Role, Socket, Options0) ->
+ Sups = ?GET_INTERNAL_OPT(supervisors, Options0),
ConnectionSup = proplists:get_value(connection_sup, Sups),
- Opts = [{supervisors, Sups}, {user_pid, UserPid} | proplists:get_value(ssh_opts, Options, [])],
- {ok, Pid} = ssh_connection_sup:start_child(ConnectionSup, [Role, Socket, Opts]),
+ Options = ?PUT_INTERNAL_OPT({user_pid,UserPid}, Options0),
+ {ok, Pid} = ssh_connection_sup:start_child(ConnectionSup, [Role, Socket, Options]),
ok = socket_control(Socket, Pid, Options),
Pid.
@@ -1428,46 +1542,45 @@ peer_role(client) -> server;
peer_role(server) -> client.
%%--------------------------------------------------------------------
-%% StateName to Role
-role({_,Role}) -> Role;
-role({_,Role,_}) -> Role.
-
-%%--------------------------------------------------------------------
-%% Check the StateName to see if we are in the renegotiation phase
-renegotiation({_,_,ReNeg}) -> ReNeg == renegotiation;
-renegotiation(_) -> false.
-
-%%--------------------------------------------------------------------
supported_host_keys(client, _, Options) ->
try
- case proplists:get_value(public_key,
- proplists:get_value(preferred_algorithms,Options,[])
- ) of
- undefined ->
- ssh_transport:default_algorithms(public_key);
- L ->
- L -- (L--ssh_transport:default_algorithms(public_key))
- end
+ find_sup_hkeys(Options)
of
[] ->
- {stop, {shutdown, "No public key algs"}};
+ error({shutdown, "No public key algs"});
Algs ->
[atom_to_list(A) || A<-Algs]
catch
exit:Reason ->
- {stop, {shutdown, Reason}}
+ error({shutdown, Reason})
end;
supported_host_keys(server, KeyCb, Options) ->
- [atom_to_list(A) || A <- proplists:get_value(public_key,
- proplists:get_value(preferred_algorithms,Options,[]),
- ssh_transport:default_algorithms(public_key)
- ),
+ [atom_to_list(A) || A <- find_sup_hkeys(Options),
available_host_key(KeyCb, A, Options)
].
+
+find_sup_hkeys(Options) ->
+ case proplists:get_value(public_key,
+ ?GET_OPT(preferred_algorithms,Options)
+ )
+ of
+ undefined ->
+ ssh_transport:default_algorithms(public_key);
+ L ->
+ NonSupported = L--ssh_transport:supported_algorithms(public_key),
+ L -- NonSupported
+ end.
+
+
+
%% Alg :: atom()
-available_host_key(KeyCb, Alg, Opts) ->
- element(1, catch KeyCb:host_key(Alg, Opts)) == ok.
+available_host_key({KeyCb,KeyCbOpts}, Alg, Opts) ->
+ UserOpts = ?GET_OPT(user_options, Opts),
+ case KeyCb:host_key(Alg, [{key_cb_private,KeyCbOpts}|UserOpts]) of
+ {ok,_} -> true;
+ _ -> false
+ end.
send_msg(Msg, State=#data{ssh_params=Ssh0}) when is_tuple(Msg) ->
@@ -1475,8 +1588,11 @@ send_msg(Msg, State=#data{ssh_params=Ssh0}) when is_tuple(Msg) ->
send_bytes(Bytes, State),
State#data{ssh_params=Ssh}.
+send_bytes("", _D) ->
+ ok;
send_bytes(Bytes, #data{socket = Socket, transport_cb = Transport}) ->
- Transport:send(Socket, Bytes).
+ _ = Transport:send(Socket, Bytes),
+ ok.
handle_version({2, 0} = NumVsn, StrVsn, Ssh0) ->
Ssh = counterpart_versions(NumVsn, StrVsn, Ssh0),
@@ -1580,6 +1696,57 @@ cache(#data{connection_state=C}) -> C#connection.channel_cache.
%%%----------------------------------------------------------------
+handle_ssh_msg_ext_info(#ssh_msg_ext_info{}, D=#data{ssh_params = #ssh{recv_ext_info=false}} ) ->
+ % The peer sent this although we didn't allow it!
+ D;
+
+handle_ssh_msg_ext_info(#ssh_msg_ext_info{data=Data}, D0) ->
+ lists:foldl(fun ext_info/2, D0, Data).
+
+
+ext_info({"server-sig-algs",SigAlgsStr},
+ D0 = #data{ssh_params=#ssh{role=client,
+ userauth_pubkeys=ClientSigAlgs}=Ssh0}) ->
+ %% ClientSigAlgs are the pub_key algortithms that:
+ %% 1) is usable, that is, the user has such a public key and
+ %% 2) is either the default list or set by the caller
+ %% with the client option 'pref_public_key_algs'
+ %%
+ %% The list is already checked for duplicates.
+
+ SigAlgs = [A || Astr <- string:tokens(SigAlgsStr, ","),
+ A <- try [list_to_existing_atom(Astr)]
+ %% list_to_existing_atom will fail for unknown algorithms
+ catch _:_ -> []
+ end],
+
+ CommonAlgs = [A || A <- SigAlgs,
+ lists:member(A, ClientSigAlgs)],
+
+ %% Re-arrange the client supported public-key algorithms so that the server
+ %% preferred ones are tried first.
+ %% Trying algorithms not mentioned by the server is ok, since the server can't know
+ %% if the client supports 'server-sig-algs' or not.
+
+ D0#data{
+ ssh_params =
+ Ssh0#ssh{
+ userauth_pubkeys =
+ CommonAlgs ++ (ClientSigAlgs -- CommonAlgs)
+ }};
+
+ext_info(_, D0) ->
+ %% Not implemented
+ D0.
+
+%%%----------------------------------------------------------------
+is_usable_user_pubkey(A, Ssh) ->
+ case ssh_auth:get_public_key(A, Ssh) of
+ {ok,_} -> true;
+ _ -> false
+ end.
+
+%%%----------------------------------------------------------------
handle_request(ChannelPid, ChannelId, Type, Data, WantReply, From, D) ->
case ssh_channel:cache_lookup(cache(D), ChannelId) of
#channel{remote_id = Id} = Channel ->
@@ -1635,7 +1802,6 @@ new_channel_id(#data{connection_state = #connection{channel_id_seed = Id} =
disconnect(Msg=#ssh_msg_disconnect{description=Description}, _StateName, State0) ->
State = send_msg(Msg, State0),
disconnect_fun(Description, State),
-timer:sleep(400),
{stop, {shutdown,Description}, State}.
%%%----------------------------------------------------------------
@@ -1644,43 +1810,43 @@ counterpart_versions(NumVsn, StrVsn, #ssh{role = server} = Ssh) ->
counterpart_versions(NumVsn, StrVsn, #ssh{role = client} = Ssh) ->
Ssh#ssh{s_vsn = NumVsn , s_version = StrVsn}.
-ssh_info([], _State, Acc) ->
- Acc;
-ssh_info([client_version | Rest], #data{ssh_params = #ssh{c_vsn = IntVsn,
- c_version = StringVsn}} = State, Acc) ->
- ssh_info(Rest, State, [{client_version, {IntVsn, StringVsn}} | Acc]);
-
-ssh_info([server_version | Rest], #data{ssh_params =#ssh{s_vsn = IntVsn,
- s_version = StringVsn}} = State, Acc) ->
- ssh_info(Rest, State, [{server_version, {IntVsn, StringVsn}} | Acc]);
-ssh_info([peer | Rest], #data{ssh_params = #ssh{peer = Peer}} = State, Acc) ->
- ssh_info(Rest, State, [{peer, Peer} | Acc]);
-ssh_info([sockname | Rest], #data{socket = Socket} = State, Acc) ->
- {ok, SockName} = inet:sockname(Socket),
- ssh_info(Rest, State, [{sockname, SockName}|Acc]);
-ssh_info([user | Rest], #data{auth_user = User} = State, Acc) ->
- ssh_info(Rest, State, [{user, User}|Acc]);
-ssh_info([ _ | Rest], State, Acc) ->
- ssh_info(Rest, State, Acc).
-
-
-ssh_channel_info([], _, Acc) ->
- Acc;
+%%%----------------------------------------------------------------
+conn_info(client_version, #data{ssh_params=S}) -> {S#ssh.c_vsn, S#ssh.c_version};
+conn_info(server_version, #data{ssh_params=S}) -> {S#ssh.s_vsn, S#ssh.s_version};
+conn_info(peer, #data{ssh_params=S}) -> S#ssh.peer;
+conn_info(user, D) -> D#data.auth_user;
+conn_info(sockname, D) -> {ok, SockName} = inet:sockname(D#data.socket),
+ SockName;
+%% dbg options ( = not documented):
+conn_info(socket, D) -> D#data.socket;
+conn_info(chan_ids, D) ->
+ ssh_channel:cache_foldl(fun(#channel{local_id=Id}, Acc) ->
+ [Id | Acc]
+ end, [], cache(D)).
-ssh_channel_info([recv_window | Rest], #channel{recv_window_size = WinSize,
- recv_packet_size = Packsize
- } = Channel, Acc) ->
- ssh_channel_info(Rest, Channel, [{recv_window, {{win_size, WinSize},
- {packet_size, Packsize}}} | Acc]);
-ssh_channel_info([send_window | Rest], #channel{send_window_size = WinSize,
- send_packet_size = Packsize
- } = Channel, Acc) ->
- ssh_channel_info(Rest, Channel, [{send_window, {{win_size, WinSize},
- {packet_size, Packsize}}} | Acc]);
-ssh_channel_info([ _ | Rest], Channel, Acc) ->
- ssh_channel_info(Rest, Channel, Acc).
+%%%----------------------------------------------------------------
+chann_info(recv_window, C) ->
+ {{win_size, C#channel.recv_window_size},
+ {packet_size, C#channel.recv_packet_size}};
+chann_info(send_window, C) ->
+ {{win_size, C#channel.send_window_size},
+ {packet_size, C#channel.send_packet_size}};
+%% dbg options ( = not documented):
+chann_info(pid, C) ->
+ C#channel.user.
+%%%----------------------------------------------------------------
+%% Assisting meta function for the *_info functions
+fold_keys(Keys, Fun, Extra) ->
+ lists:foldr(fun(Key, Acc) ->
+ try Fun(Key, Extra) of
+ Value -> [{Key,Value}|Acc]
+ catch
+ _:_ -> Acc
+ end
+ end, [], Keys).
+%%%----------------------------------------------------------------
log_error(Reason) ->
Report = io_lib:format("Erlang ssh connection handler failed with reason:~n"
" ~p~n"
@@ -1689,7 +1855,6 @@ log_error(Reason) ->
[Reason, erlang:get_stacktrace()]),
error_logger:error_report(Report).
-
%%%----------------------------------------------------------------
not_connected_filter({connection_reply, _Data}) -> true;
not_connected_filter(_) -> false.
@@ -1701,6 +1866,11 @@ send_replies(Repls, State) ->
Repls).
get_repl({connection_reply,Msg}, {CallRepls,S}) ->
+ if is_record(Msg, ssh_msg_channel_success) ->
+ update_inet_buffers(S#data.socket);
+ true ->
+ ok
+ end,
{CallRepls, send_msg(Msg,S)};
get_repl({channel_data,undefined,_Data}, Acc) ->
Acc;
@@ -1720,47 +1890,24 @@ get_repl(X, Acc) ->
exit({get_repl,X,Acc}).
%%%----------------------------------------------------------------
-disconnect_fun({disconnect,Msg}, D) ->
- disconnect_fun(Msg, D);
-disconnect_fun(Reason, #data{opts=Opts}) ->
- case proplists:get_value(disconnectfun, Opts) of
- undefined ->
- ok;
- Fun ->
- catch Fun(Reason)
- end.
-
-unexpected_fun(UnexpectedMessage, #data{opts = Opts,
- ssh_params = #ssh{peer = {_,Peer} }
- } ) ->
- case proplists:get_value(unexpectedfun, Opts) of
- undefined ->
- report;
- Fun ->
- catch Fun(UnexpectedMessage, Peer)
- end.
+-define(CALL_FUN(Key,D), catch (?GET_OPT(Key, (D#data.ssh_params)#ssh.opts)) ).
+
+disconnect_fun({disconnect,Msg}, D) -> ?CALL_FUN(disconnectfun,D)(Msg);
+disconnect_fun(Reason, D) -> ?CALL_FUN(disconnectfun,D)(Reason).
+unexpected_fun(UnexpectedMessage, #data{ssh_params = #ssh{peer = {_,Peer} }} = D) ->
+ ?CALL_FUN(unexpectedfun,D)(UnexpectedMessage, Peer).
debug_fun(#ssh_msg_debug{always_display = Display,
message = DbgMsg,
language = Lang},
- #data{opts = Opts}) ->
- case proplists:get_value(ssh_msg_debug_fun, Opts) of
- undefined ->
- ok;
- Fun ->
- catch Fun(self(), Display, DbgMsg, Lang)
- end.
+ D) ->
+ ?CALL_FUN(ssh_msg_debug_fun,D)(self(), Display, DbgMsg, Lang).
-connected_fun(User, Method, #data{ssh_params = #ssh{peer = {_,Peer}},
- opts = Opts}) ->
- case proplists:get_value(connectfun, Opts) of
- undefined ->
- ok;
- Fun ->
- catch Fun(User, Peer, Method)
- end.
+connected_fun(User, Method, #data{ssh_params = #ssh{peer = {_,Peer}}} = D) ->
+ ?CALL_FUN(connectfun,D)(User, Peer, Method).
+
retry_fun(_, undefined, _) ->
ok;
@@ -1774,7 +1921,7 @@ retry_fun(User, Reason, #data{ssh_params = #ssh{opts = Opts,
_ ->
{infofun, Reason}
end,
- Fun = proplists:get_value(Tag, Opts, fun(_,_)-> ok end),
+ Fun = ?GET_OPT(Tag, Opts),
try erlang:fun_info(Fun, arity)
of
{arity, 2} -> %% Backwards compatible
@@ -1793,7 +1940,7 @@ retry_fun(User, Reason, #data{ssh_params = #ssh{opts = Opts,
%%% channels open for a while.
cache_init_idle_timer(D) ->
- case proplists:get_value(idle_time, D#data.opts, infinity) of
+ case ?GET_OPT(idle_time, (D#data.ssh_params)#ssh.opts) of
infinity ->
D#data{idle_timer_value = infinity,
idle_timer_ref = infinity % A flag used later...
@@ -1856,9 +2003,8 @@ start_channel_request_timer(Channel, From, Time) ->
%%% Connection start and initalization helpers
socket_control(Socket, Pid, Options) ->
- {_, TransportCallback, _} = % For example {_,gen_tcp,_}
- proplists:get_value(transport, Options, ?DefaultTransport),
- case TransportCallback:controlling_process(Socket, Pid) of
+ {_, Callback, _} = ?GET_OPT(transport, Options),
+ case Callback:controlling_process(Socket, Pid) of
ok ->
gen_statem:cast(Pid, socket_control);
{error, Reason} ->
@@ -1889,3 +2035,15 @@ handshake(Pid, Ref, Timeout) ->
{error, timeout}
end.
+update_inet_buffers(Socket) ->
+ try
+ {ok, BufSzs0} = inet:getopts(Socket, [sndbuf,recbuf]),
+ MinVal = 655360,
+ [{Tag,MinVal} || {Tag,Val} <- BufSzs0,
+ Val < MinVal]
+ of
+ [] -> ok;
+ NewOpts -> inet:setopts(Socket, NewOpts)
+ catch
+ _:_ -> ok
+ end.
diff --git a/lib/ssh/src/ssh_connection_sup.erl b/lib/ssh/src/ssh_connection_sup.erl
index 0f54053f52..60ee8b7c73 100644
--- a/lib/ssh/src/ssh_connection_sup.erl
+++ b/lib/ssh/src/ssh_connection_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -45,19 +45,17 @@ start_child(Sup, Args) ->
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
--spec init( [term()] ) -> {ok,{supervisor:sup_flags(),[supervisor:child_spec()]}} | ignore .
-
init(_) ->
- RestartStrategy = simple_one_for_one,
- MaxR = 0,
- MaxT = 3600,
-
- Name = undefined, % As simple_one_for_one is used.
- StartFunc = {ssh_connection_handler, start_link, []},
- Restart = temporary, % E.g. should not be restarted
- Shutdown = 4000,
- Modules = [ssh_connection_handler],
- Type = worker,
-
- ChildSpec = {Name, StartFunc, Restart, Shutdown, Type, Modules},
- {ok, {{RestartStrategy, MaxR, MaxT}, [ChildSpec]}}.
+ SupFlags = #{strategy => simple_one_for_one,
+ intensity => 0,
+ period => 3600
+ },
+ ChildSpecs = [#{id => undefined, % As simple_one_for_one is used.
+ start => {ssh_connection_handler, start_link, []},
+ restart => temporary,
+ shutdown => 4000,
+ type => worker,
+ modules => [ssh_connection_handler]
+ }
+ ],
+ {ok, {SupFlags,ChildSpecs}}.
diff --git a/lib/ssh/src/ssh_dbg.erl b/lib/ssh/src/ssh_dbg.erl
index 480795cfc7..3f742ad9b6 100644
--- a/lib/ssh/src/ssh_dbg.erl
+++ b/lib/ssh/src/ssh_dbg.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,79 +22,216 @@
-module(ssh_dbg).
--export([messages/0,
- messages/1,
+-export([messages/0, messages/1, messages/2, messages/3,
+ auth/0, auth/1, auth/2, auth/3,
stop/0
]).
+-export([shrink_bin/1,
+ wr_record/3]).
+
-include("ssh.hrl").
-include("ssh_transport.hrl").
-include("ssh_connect.hrl").
-include("ssh_auth.hrl").
--record(data, {
- writer,
- acc = []}).
%%%================================================================
-messages() -> messages(fun(String,_D) -> io:format(String) end).
-%% messages() -> messages(fun(String,Acc) -> [String|Acc] end)
+messages() -> start(msg).
+messages(F) -> start(msg,F).
+messages(F,X) -> start(msg,F,X).
+messages(F,M,I) -> start(msg,F,M,I).
-messages(Write) when is_function(Write,2) ->
- catch dbg:start(),
- setup_tracer(Write),
- dbg:p(new,c),
- dbg_ssh_messages().
+auth() -> start(auth).
+auth(F) -> start(auth,F).
+auth(F,X) -> start(auth,F,X).
+auth(F,M,I) -> start(auth,F,M,I).
-dbg_ssh_messages() ->
- dbg:tp(ssh_message,encode,1, x),
- dbg:tp(ssh_message,decode,1, x),
- dbg:tpl(ssh_transport,select_algorithm,3, x).
+stop() -> dbg:stop().
%%%----------------------------------------------------------------
-stop() ->
- dbg:stop().
+start(Type) -> start(Type, fun io:format/2).
+
+start(Type, F) when is_function(F,2) -> start(Type, fmt_fun(F));
+start(Type, F) when is_function(F,3) -> start(Type, F, id_fun()).
+
+start(Type, WriteFun, MangleArgFun) when is_function(WriteFun, 3),
+ is_function(MangleArgFun, 1) ->
+ start(Type, WriteFun, MangleArgFun, []);
+start(Type, WriteFun, InitValue) ->
+ start(Type, WriteFun, id_fun(), InitValue).
+
+start(Type, WriteFun, MangleArgFun, InitValue) when is_function(WriteFun, 3),
+ is_function(MangleArgFun, 1) ->
+ cond_start(Type, WriteFun, MangleArgFun, InitValue),
+ dbg_ssh(Type).
+
+%%%----------------------------------------------------------------
+fmt_fun(F) -> fun(Fmt,Args,Data) -> F(Fmt,Args), Data end.
+
+id_fun() -> fun(X) -> X end.
+%%%----------------------------------------------------------------
+dbg_ssh(msg) ->
+ dbg_ssh(auth),
+ dbg:tp(ssh_message,encode,1, x),
+ dbg:tp(ssh_message,decode,1, x),
+ dbg:tpl(ssh_transport,select_algorithm,4, x),
+ dbg:tp(ssh_transport,hello_version_msg,1, x),
+ dbg:tp(ssh_transport,handle_hello_version,1, x),
+ dbg:tpl(ssh_connection_handler,ext_info,2, x);
+
+dbg_ssh(auth) ->
+ dbg:tp(ssh_transport,hello_version_msg,1, x),
+ dbg:tp(ssh_transport,handle_hello_version,1, x),
+ dbg:tp(ssh_message,encode,1, x),
+ dbg:tpl(ssh_transport,select_algorithm,4, x),
+ dbg:tpl(ssh_connection_handler,ext_info,2, x),
+ lists:foreach(fun(F) -> dbg:tp(ssh_auth, F, x) end,
+ [publickey_msg, password_msg, keyboard_interactive_msg]).
+
%%%================================================================
-msg_formater({trace,Pid,call,{ssh_message,encode,[Msg]}}, D) ->
- fmt("~nSEND ~p ~s~n", [Pid,wr_record(shrink_bin(Msg))], D);
-msg_formater({trace,_Pid,return_from,{ssh_message,encode,1},_Res}, D) ->
+cond_start(Type, WriteFun, MangleArgFun, Init) ->
+ try
+ dbg:start(),
+ setup_tracer(Type, WriteFun, MangleArgFun, Init),
+ dbg:p(new,[c,timestamp])
+ catch
+ _:_ -> ok
+ end.
+
+
+msg_formater(msg, {trace_ts,Pid,call,{ssh_message,encode,[Msg]},TS}, D) ->
+ fmt("~n~s SEND ~p ~s~n", [ts(TS),Pid,wr_record(shrink_bin(Msg))], D);
+msg_formater(msg, {trace_ts,_Pid,return_from,{ssh_message,encode,1},_Res,_TS}, D) ->
D;
-msg_formater({trace,_Pid,call,{ssh_message,decode,_}}, D) ->
+msg_formater(msg, {trace_ts,_Pid,call,{ssh_message,decode,_},_TS}, D) ->
D;
-msg_formater({trace,Pid,return_from,{ssh_message,decode,1},Msg}, D) ->
- fmt("~nRECV ~p ~s~n", [Pid,wr_record(shrink_bin(Msg))], D);
+msg_formater(msg, {trace_ts,Pid,return_from,{ssh_message,decode,1},Msg,TS}, D) ->
+ fmt("~n~s ~p RECV ~s~n", [ts(TS),Pid,wr_record(shrink_bin(Msg))], D);
+
+msg_formater(auth, {trace_ts,Pid,return_from,{ssh_message,decode,1},#ssh_msg_userauth_failure{authentications=As},TS}, D) ->
+ fmt("~n~s ~p Client login FAILURE. Try ~s~n", [ts(TS),Pid,As], D);
+
+msg_formater(auth, {trace_ts,Pid,return_from,{ssh_message,decode,1},#ssh_msg_userauth_success{},TS}, D) ->
+ fmt("~n~s ~p Client login SUCCESS~n", [ts(TS),Pid], D);
+
-msg_formater({trace,_Pid,call,{ssh_transport,select_algorithm,_}}, D) ->
+msg_formater(_, {trace_ts,_Pid,call,{ssh_transport,select_algorithm,_},_TS}, D) ->
+ D;
+msg_formater(_, {trace_ts,Pid,return_from,{ssh_transport,select_algorithm,_},{ok,Alg},TS}, D) ->
+ fmt("~n~s ~p ALGORITHMS~n~s~n", [ts(TS),Pid, wr_record(Alg)], D);
+
+msg_formater(_, {trace_ts,_Pid,call,{ssh_transport,hello_version_msg,_},_TS}, D) ->
+ D;
+msg_formater(_, {trace_ts,Pid,return_from,{ssh_transport,hello_version_msg,1},Hello,TS}, D) ->
+ fmt("~n~s ~p TCP SEND HELLO~n ~p~n", [ts(TS),Pid,lists:flatten(Hello)], D);
+
+msg_formater(_, {trace_ts,Pid,call,{ssh_transport,handle_hello_version,[Hello]},TS}, D) ->
+ fmt("~n~s ~p RECV HELLO~n ~p~n", [ts(TS),Pid,lists:flatten(Hello)], D);
+msg_formater(_, {trace_ts,_Pid,return_from,{ssh_transport,handle_hello_version,1},_,_TS}, D) ->
D;
-msg_formater({trace,Pid,return_from,{ssh_transport,select_algorithm,3},{ok,Alg}}, D) ->
- fmt("~nALGORITHMS ~p~n~s~n", [Pid, wr_record(Alg)], D);
-msg_formater({trace,Pid,send,ErlangMsg,Dest}, D) ->
- fmt("~nERL MSG ~p SEND TO ~p~n ~p~n", [Pid,Dest, shrink_bin(ErlangMsg)], D);
+msg_formater(_, {trace_ts,Pid,call,{ssh_connection_handler,ext_info,[{"server-sig-algs",SigAlgs},State]},TS}, D) ->
+ try lists:keyfind(ssh, 1, tuple_to_list(State)) of
+ false ->
+ D;
+ #ssh{userauth_pubkeys = PKs} ->
+ fmt("~n~s ~p Client got suggestion to use user public key sig-algs~n ~p~n and can use~n ~p~n",
+ [ts(TS),Pid,string:tokens(SigAlgs,","),PKs], D)
+ catch
+ _:_ ->
+ D
+ end;
+
+msg_formater(_, {trace_ts,Pid,return_from,{ssh_connection_handler,ext_info,2},State,TS}, D) ->
+ try lists:keyfind(ssh, 1, tuple_to_list(State)) of
+ false ->
+ D;
+ #ssh{userauth_pubkeys = PKs} ->
+ fmt("~n~s ~p Client will try user public key sig-algs~n ~p~n", [ts(TS),Pid,PKs], D)
+ catch
+ _:_ ->
+ D
+ end;
+
+msg_formater(_, {trace_ts,Pid,call,{ssh_auth,publickey_msg,[[SigAlg,#ssh{user=User}]]},TS}, D) ->
+ fmt("~n~s ~p Client will try to login user ~p with public key algorithm ~p~n", [ts(TS),Pid,User,SigAlg], D);
+msg_formater(_, {trace_ts,Pid,return_from,{ssh_auth,publickey_msg,1},{not_ok,#ssh{user=User}},TS}, D) ->
+ fmt("~s ~p User ~p can't login with that kind of public key~n", [ts(TS),Pid,User], D);
+
+msg_formater(_, {trace_ts,Pid,call,{ssh_auth,password_msg,[[#ssh{user=User}]]},TS}, D) ->
+ fmt("~n~s ~p Client will try to login user ~p with password~n", [ts(TS),Pid,User], D);
+msg_formater(_, {trace_ts,Pid,return_from,{ssh_auth,password_msg,1},{not_ok,#ssh{user=User}},TS}, D) ->
+ fmt("~s ~p User ~p can't login with password~n", [ts(TS),Pid,User], D);
+
+msg_formater(_, {trace_ts,Pid,call,{ssh_auth,keyboard_interactive_msg,[[#ssh{user=User}]]},TS}, D) ->
+ fmt("~n~s ~p Client will try to login user ~p with password~n", [ts(TS),Pid,User], D);
+msg_formater(_, {trace_ts,Pid,return_from,{ssh_auth,keyboard_interactive_msg,1},{not_ok,#ssh{user=User}},TS}, D) ->
+ fmt("~s ~p User ~p can't login with keyboard_interactive password~n", [ts(TS),Pid,User], D);
-msg_formater({trace,Pid,'receive',ErlangMsg}, D) ->
- fmt("~nERL MSG ~p RECIEVE~n ~p~n", [Pid,shrink_bin(ErlangMsg)], D);
+msg_formater(msg, {trace_ts,Pid,send,{tcp,Sock,Bytes},Pid,TS}, D) ->
+ fmt("~n~s ~p TCP SEND on ~p~n ~p~n", [ts(TS),Pid,Sock, shrink_bin(Bytes)], D);
-msg_formater(M, D) ->
- fmt("~nDBG ~n~p~n", [shrink_bin(M)], D).
+msg_formater(msg, {trace_ts,Pid,send,{tcp,Sock,Bytes},Dest,TS}, D) ->
+ fmt("~n~s ~p TCP SEND from ~p TO ~p~n ~p~n", [ts(TS),Pid,Sock,Dest, shrink_bin(Bytes)], D);
-%% msg_formater(_, D) ->
-%% D.
+msg_formater(msg, {trace_ts,Pid,send,ErlangMsg,Dest,TS}, D) ->
+ fmt("~n~s ~p ERL MSG SEND TO ~p~n ~p~n", [ts(TS),Pid,Dest, shrink_bin(ErlangMsg)], D);
-fmt(Fmt, Args, D=#data{writer=Write,acc=Acc}) ->
- D#data{acc = Write(io_lib:format(Fmt, Args), Acc)}.
+msg_formater(msg, {trace_ts,Pid,'receive',{tcp,Sock,Bytes},TS}, D) ->
+ fmt("~n~s ~p TCP RECEIVE on ~p~n ~p~n", [ts(TS),Pid,Sock,shrink_bin(Bytes)], D);
+
+msg_formater(msg, {trace_ts,Pid,'receive',ErlangMsg,TS}, D) ->
+ fmt("~n~s ~p ERL MSG RECEIVE~n ~p~n", [ts(TS),Pid,shrink_bin(ErlangMsg)], D);
+
+
+%% msg_formater(_, {trace_ts,_Pid,return_from,MFA,_Ret,_TS}=M, D) ->
+%% case lists:member(MFA, [{ssh_auth,keyboard_interactive_msg,1},
+%% {ssh_auth,password_msg,1},
+%% {ssh_auth,publickey_msg,1}]) of
+%% true ->
+%% D;
+%% false ->
+%% fmt("~nDBG ~n~p~n", [shrink_bin(M)], D)
+%% end;
+
+%% msg_formater(_, M, D) ->
+%% fmt("~nDBG ~n~p~n", [shrink_bin(M)], D).
+
+msg_formater(_, _, D) ->
+ D.
%%%----------------------------------------------------------------
-setup_tracer(Write) ->
- Handler = fun msg_formater/2,
- InitialData = #data{writer = Write},
+-record(data, {writer,
+ acc}).
+
+fmt(Fmt, Args, D=#data{writer=Write, acc=Acc}) ->
+ D#data{acc = Write(Fmt,Args,Acc)}.
+
+ts({_,_,Usec}=Now) ->
+ {_Date,{HH,MM,SS}} = calendar:now_to_local_time(Now),
+ io_lib:format("~.2.0w:~.2.0w:~.2.0w.~.6.0w",[HH,MM,SS,Usec]);
+ts(_) ->
+ "-".
+
+setup_tracer(Type, WriteFun, MangleArgFun, Init) ->
+ Handler = fun(Arg, D) ->
+ msg_formater(Type, MangleArgFun(Arg), D)
+ end,
+ InitialData = #data{writer = WriteFun,
+ acc = Init},
{ok,_} = dbg:tracer(process, {Handler, InitialData}),
ok.
%%%----------------------------------------------------------------
-shrink_bin(B) when is_binary(B), size(B)>100 -> {'*** SHRINKED BIN',size(B),element(1,split_binary(B,20)),'***'};
+shrink_bin(B) when is_binary(B), size(B)>256 -> {'*** SHRINKED BIN',
+ size(B),
+ element(1,split_binary(B,64)),
+ '...',
+ element(2,split_binary(B,size(B)-64))
+ };
shrink_bin(L) when is_list(L) -> lists:map(fun shrink_bin/1, L);
shrink_bin(T) when is_tuple(T) -> list_to_tuple(shrink_bin(tuple_to_list(T)));
shrink_bin(X) -> X.
@@ -117,6 +254,7 @@ shrink_bin(X) -> X.
?wr_record(ssh_msg_kexdh_init);
?wr_record(ssh_msg_kexdh_reply);
?wr_record(ssh_msg_newkeys);
+?wr_record(ssh_msg_ext_info);
?wr_record(ssh_msg_kex_dh_gex_request);
?wr_record(ssh_msg_kex_dh_gex_request_old);
?wr_record(ssh_msg_kex_dh_gex_group);
diff --git a/lib/hipe/amd64/hipe_amd64_ra_x87_ls.erl b/lib/ssh/src/ssh_dbg.hrl
index 6da3f44cd3..e94664737b 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_x87_ls.erl
+++ b/lib/ssh/src/ssh_dbg.hrl
@@ -1,8 +1,8 @@
%%
%% %CopyrightBegin%
-%%
+%%
%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
+%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +14,14 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
+%%
%% %CopyrightEnd%
%%
--include("../x86/hipe_x86_ra_x87_ls.erl").
+-ifndef(SSH_DBG_HRL).
+-define(SSH_DBG_HRL, 1).
+
+-define(formatrec(RecName,R),
+ ssh_dbg:wr_record(R, record_info(fields,RecName), [])).
+
+-endif. % SSH_DBG_HRL defined
diff --git a/lib/ssh/src/ssh_file.erl b/lib/ssh/src/ssh_file.erl
index 216f65f33a..33792da38f 100644
--- a/lib/ssh/src/ssh_file.erl
+++ b/lib/ssh/src/ssh_file.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -75,17 +75,9 @@ host_key(Algorithm, Opts) ->
Password = proplists:get_value(identity_pass_phrase(Algorithm), Opts, ignore),
case decode(File, Password) of
{ok,Key} ->
- case {Key,Algorithm} of
- {#'RSAPrivateKey'{}, 'ssh-rsa'} -> {ok,Key};
- {#'DSAPrivateKey'{}, 'ssh-dss'} -> {ok,Key};
- {#'ECPrivateKey'{parameters = {namedCurve, ?'secp256r1'}}, 'ecdsa-sha2-nistp256'} -> {ok,Key};
- {#'ECPrivateKey'{parameters = {namedCurve, ?'secp384r1'}}, 'ecdsa-sha2-nistp384'} -> {ok,Key};
- {#'ECPrivateKey'{parameters = {namedCurve, ?'secp521r1'}}, 'ecdsa-sha2-nistp521'} -> {ok,Key};
- _ ->
- {error,bad_keytype_in_file}
- end;
- Other ->
- Other
+ check_key_type(Key, Algorithm);
+ {error,DecodeError} ->
+ {error,DecodeError}
end.
is_auth_key(Key, User,Opts) ->
@@ -109,12 +101,25 @@ is_host_key(Key, PeerName, Algorithm, Opts) ->
user_key(Algorithm, Opts) ->
File = file_name(user, identity_key_filename(Algorithm), Opts),
Password = proplists:get_value(identity_pass_phrase(Algorithm), Opts, ignore),
- decode(File, Password).
+ case decode(File, Password) of
+ {ok, Key} ->
+ check_key_type(Key, Algorithm);
+ Error ->
+ Error
+ end.
%% Internal functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+check_key_type(Key, Algorithm) ->
+ case ssh_transport:valid_key_sha_alg(Key,Algorithm) of
+ true -> {ok,Key};
+ false -> {error,bad_keytype_in_file}
+ end.
file_base_name('ssh-rsa' ) -> "ssh_host_rsa_key";
+file_base_name('rsa-sha2-256' ) -> "ssh_host_rsa_key";
+file_base_name('rsa-sha2-384' ) -> "ssh_host_rsa_key";
+file_base_name('rsa-sha2-512' ) -> "ssh_host_rsa_key";
file_base_name('ssh-dss' ) -> "ssh_host_dsa_key";
file_base_name('ecdsa-sha2-nistp256') -> "ssh_host_ecdsa_key";
file_base_name('ecdsa-sha2-nistp384') -> "ssh_host_ecdsa_key";
@@ -192,8 +197,8 @@ lookup_user_key(Key, User, Opts) ->
ssh_dir({remoteuser, User}, Opts) ->
case proplists:get_value(user_dir_fun, Opts) of
undefined ->
- case proplists:get_value(user_dir, Opts) of
- undefined ->
+ case proplists:get_value(user_dir, Opts, false) of
+ false ->
default_user_dir();
Dir ->
Dir
@@ -221,6 +226,8 @@ file_name(Type, Name, Opts) ->
%% in: "host" out: "host,1.2.3.4.
+add_ip(IP) when is_tuple(IP) ->
+ ssh_connection:encode_ip(IP);
add_ip(Host) ->
case inet:getaddr(Host, inet) of
{ok, Addr} ->
@@ -251,12 +258,18 @@ do_lookup_host_key(KeyToMatch, Host, Alg, Opts) ->
identity_key_filename('ssh-dss' ) -> "id_dsa";
identity_key_filename('ssh-rsa' ) -> "id_rsa";
+identity_key_filename('rsa-sha2-256' ) -> "id_rsa";
+identity_key_filename('rsa-sha2-384' ) -> "id_rsa";
+identity_key_filename('rsa-sha2-512' ) -> "id_rsa";
identity_key_filename('ecdsa-sha2-nistp256') -> "id_ecdsa";
identity_key_filename('ecdsa-sha2-nistp384') -> "id_ecdsa";
identity_key_filename('ecdsa-sha2-nistp521') -> "id_ecdsa".
identity_pass_phrase("ssh-dss" ) -> dsa_pass_phrase;
identity_pass_phrase("ssh-rsa" ) -> rsa_pass_phrase;
+identity_pass_phrase("rsa-sha2-256" ) -> rsa_pass_phrase;
+identity_pass_phrase("rsa-sha2-384" ) -> rsa_pass_phrase;
+identity_pass_phrase("rsa-sha2-512" ) -> rsa_pass_phrase;
identity_pass_phrase("ecdsa-sha2-"++_) -> ecdsa_pass_phrase;
identity_pass_phrase(P) when is_atom(P) ->
identity_pass_phrase(atom_to_list(P)).
diff --git a/lib/ssh/src/ssh_info.erl b/lib/ssh/src/ssh_info.erl
index 0c24c09887..d464def6fa 100644
--- a/lib/ssh/src/ssh_info.erl
+++ b/lib/ssh/src/ssh_info.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/ssh/src/ssh_io.erl b/lib/ssh/src/ssh_io.erl
index 026d0f6151..8ba759ad60 100644
--- a/lib/ssh/src/ssh_io.erl
+++ b/lib/ssh/src/ssh_io.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,60 +27,57 @@
-export([yes_no/2, read_password/2, read_line/2, format/2]).
-include("ssh.hrl").
-read_line(Prompt, Ssh) ->
+read_line(Prompt, Opts) ->
format("~s", [listify(Prompt)]),
- proplists:get_value(user_pid, Ssh) ! {self(), question},
+ ?GET_INTERNAL_OPT(user_pid, Opts) ! {self(), question},
receive
- Answer ->
+ Answer when is_list(Answer) ->
Answer
end.
-yes_no(Prompt, Ssh) ->
- io:format("~s [y/n]?", [Prompt]),
- proplists:get_value(user_pid, Ssh#ssh.opts) ! {self(), question},
+yes_no(Prompt, Opts) ->
+ format("~s [y/n]?", [Prompt]),
+ ?GET_INTERNAL_OPT(user_pid, Opts) ! {self(), question},
receive
- Answer ->
+ %% I can't see that the atoms y and n are ever received, but it must
+ %% be investigated before removing
+ y -> yes;
+ n -> no;
+
+ Answer when is_list(Answer) ->
case trim(Answer) of
"y" -> yes;
"n" -> no;
"Y" -> yes;
"N" -> no;
- y -> yes;
- n -> no;
_ ->
- io:format("please answer y or n\n"),
- yes_no(Prompt, Ssh)
+ format("please answer y or n\n",[]),
+ yes_no(Prompt, Opts)
end
end.
-
-read_password(Prompt, Ssh) ->
+read_password(Prompt, Opts) ->
format("~s", [listify(Prompt)]),
- case is_list(Ssh) of
- false ->
- proplists:get_value(user_pid, Ssh#ssh.opts) ! {self(), user_password};
- _ ->
- proplists:get_value(user_pid, Ssh) ! {self(), user_password}
- end,
+ ?GET_INTERNAL_OPT(user_pid, Opts) ! {self(), user_password},
receive
- Answer ->
- case Answer of
- "" ->
- read_password(Prompt, Ssh);
- Pass -> Pass
- end
+ Answer when is_list(Answer) ->
+ case trim(Answer) of
+ "" ->
+ read_password(Prompt, Opts);
+ Pwd ->
+ Pwd
+ end
end.
-listify(A) when is_atom(A) ->
- atom_to_list(A);
-listify(L) when is_list(L) ->
- L;
-listify(B) when is_binary(B) ->
- binary_to_list(B).
format(Fmt, Args) ->
io:format(Fmt, Args).
+%%%================================================================
+listify(A) when is_atom(A) -> atom_to_list(A);
+listify(L) when is_list(L) -> L;
+listify(B) when is_binary(B) -> binary_to_list(B).
+
trim(Line) when is_list(Line) ->
lists:reverse(trim1(lists:reverse(trim1(Line))));
@@ -93,6 +90,3 @@ trim1([$\r|Cs]) -> trim(Cs);
trim1([$\n|Cs]) -> trim(Cs);
trim1([$\t|Cs]) -> trim(Cs);
trim1(Cs) -> Cs.
-
-
-
diff --git a/lib/ssh/src/ssh_message.erl b/lib/ssh/src/ssh_message.erl
index 562f040477..b1fc05ae33 100644
--- a/lib/ssh/src/ssh_message.erl
+++ b/lib/ssh/src/ssh_message.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -215,6 +215,16 @@ encode(#ssh_msg_service_accept{
}) ->
<<?Ebyte(?SSH_MSG_SERVICE_ACCEPT), ?Estring_utf8(Service)>>;
+encode(#ssh_msg_ext_info{
+ nr_extensions = N,
+ data = Data
+ }) ->
+ lists:foldl(fun({ExtName,ExtVal}, Acc) ->
+ <<Acc/binary, ?Estring(ExtName), ?Estring(ExtVal)>>
+ end,
+ <<?Ebyte(?SSH_MSG_EXT_INFO), ?Euint32(N)>>,
+ Data);
+
encode(#ssh_msg_newkeys{}) ->
<<?Ebyte(?SSH_MSG_NEWKEYS)>>;
@@ -435,6 +445,18 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_RESPONSE), ?UINT32(Num), Data/binary>>) ->
num_responses = Num,
data = Data};
+decode(<<?BYTE(?SSH_MSG_EXT_INFO), ?UINT32(N), BinData/binary>>) ->
+ Data = bin_foldr(
+ fun(Bin,Acc) when length(Acc) == N ->
+ {Bin,Acc};
+ (<<?DEC_BIN(V0,__0), ?DEC_BIN(V1,__1), Rest/binary>>, Acc) ->
+ {Rest,[{binary_to_list(V0),binary_to_list(V1)}|Acc]}
+ end, [], BinData),
+ #ssh_msg_ext_info{
+ nr_extensions = N,
+ data = Data
+ };
+
%%% Keyexchange messages
decode(<<?BYTE(?SSH_MSG_KEXINIT), Cookie:128, Data/binary>>) ->
decode_kex_init(Data, [Cookie, ssh_msg_kexinit], 10);
@@ -537,17 +559,28 @@ decode(<<?BYTE(?SSH_MSG_DEBUG), ?BYTE(Bool), ?DEC_BIN(Msg,__0), ?DEC_BIN(Lang,__
%%% Helper functions
%%%
+bin_foldr(Fun, Acc, Bin) ->
+ lists:reverse(bin_foldl(Fun, Acc, Bin)).
+
+bin_foldl(_, Acc, <<>>) -> Acc;
+bin_foldl(Fun, Acc0, Bin0) ->
+ {Bin,Acc} = Fun(Bin0,Acc0),
+ bin_foldl(Fun, Acc, Bin).
+
+%%%----------------------------------------------------------------
decode_keyboard_interactive_prompts(<<>>, Acc) ->
lists:reverse(Acc);
decode_keyboard_interactive_prompts(<<?DEC_BIN(Prompt,__0), ?BYTE(Bool), Bin/binary>>,
Acc) ->
decode_keyboard_interactive_prompts(Bin, [{Prompt, erl_boolean(Bool)} | Acc]).
+%%%----------------------------------------------------------------
erl_boolean(0) ->
false;
erl_boolean(1) ->
true.
+%%%----------------------------------------------------------------
decode_kex_init(<<?BYTE(Bool), ?UINT32(X)>>, Acc, 0) ->
list_to_tuple(lists:reverse([X, erl_boolean(Bool) | Acc]));
decode_kex_init(<<?BYTE(Bool)>>, Acc, 0) ->
@@ -565,15 +598,16 @@ decode_kex_init(<<?DEC_BIN(Data,__0), Rest/binary>>, Acc, N) ->
%%% Signature decode/encode
%%%
-decode_signature(<<?DEC_BIN(_Alg,__0), ?UINT32(_), Signature/binary>>) ->
- Signature.
+decode_signature(<<?DEC_BIN(Alg,__0), ?UINT32(_), Signature/binary>>) ->
+ {binary_to_list(Alg), Signature}.
-encode_signature(#'RSAPublicKey'{}, Signature) ->
- <<?Ebinary(<<"ssh-rsa">>), ?Ebinary(Signature)>>;
-encode_signature({_, #'Dss-Parms'{}}, Signature) ->
+encode_signature({#'RSAPublicKey'{},Sign}, Signature) ->
+ SignName = list_to_binary(atom_to_list(Sign)),
+ <<?Ebinary(SignName), ?Ebinary(Signature)>>;
+encode_signature({{_, #'Dss-Parms'{}},_}, Signature) ->
<<?Ebinary(<<"ssh-dss">>), ?Ebinary(Signature)>>;
-encode_signature({#'ECPoint'{}, {namedCurve,OID}}, Signature) ->
+encode_signature({{#'ECPoint'{}, {namedCurve,OID}},_}, Signature) ->
CurveName = public_key:oid2ssh_curvename(OID),
<<?Ebinary(<<"ecdsa-sha2-",CurveName/binary>>), ?Ebinary(Signature)>>.
diff --git a/lib/ssh/src/ssh_options.erl b/lib/ssh/src/ssh_options.erl
new file mode 100644
index 0000000000..7eeed70739
--- /dev/null
+++ b/lib/ssh/src/ssh_options.erl
@@ -0,0 +1,904 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssh_options).
+
+-include("ssh.hrl").
+-include_lib("kernel/include/file.hrl").
+
+-export([default/1,
+ get_value/5, get_value/6,
+ put_value/5,
+ delete_key/5,
+ handle_options/2
+ ]).
+
+-export_type([options/0
+ ]).
+
+%%%================================================================
+%%% Types
+
+-type option_in() :: proplists:property() | proplists:proplist() .
+
+-type option_class() :: internal_options | socket_options | user_options .
+
+-type option_declaration() :: #{class := user_options,
+ chk := fun((any) -> boolean() | {true,any()}),
+ default => any()
+ }.
+
+-type option_declarations() :: #{ {option_key(),def} := option_declaration() }.
+
+-type error() :: {error,{eoptions,any()}} .
+
+%%%================================================================
+%%%
+%%% Get an option
+%%%
+
+-spec get_value(option_class(), option_key(), options(),
+ atom(), non_neg_integer()) -> any() | no_return().
+
+get_value(Class, Key, Opts, _CallerMod, _CallerLine) when is_map(Opts) ->
+ case Class of
+ internal_options -> maps:get(Key, maps:get(internal_options,Opts));
+ socket_options -> proplists:get_value(Key, maps:get(socket_options,Opts));
+ user_options -> maps:get(Key, Opts)
+ end;
+get_value(Class, Key, Opts, _CallerMod, _CallerLine) ->
+ error({bad_options,Class, Key, Opts, _CallerMod, _CallerLine}).
+
+
+-spec get_value(option_class(), option_key(), options(), fun(() -> any()),
+ atom(), non_neg_integer()) -> any() | no_return().
+
+get_value(socket_options, Key, Opts, DefFun, _CallerMod, _CallerLine) when is_map(Opts) ->
+ proplists:get_value(Key, maps:get(socket_options,Opts), DefFun);
+get_value(Class, Key, Opts, DefFun, CallerMod, CallerLine) when is_map(Opts) ->
+ try get_value(Class, Key, Opts, CallerMod, CallerLine)
+ of
+ undefined -> DefFun();
+ Value -> Value
+ catch
+ error:{badkey,Key} -> DefFun()
+ end;
+get_value(Class, Key, Opts, _DefFun, _CallerMod, _CallerLine) ->
+ error({bad_options,Class, Key, Opts, _CallerMod, _CallerLine}).
+
+
+%%%================================================================
+%%%
+%%% Put an option
+%%%
+
+-spec put_value(option_class(), option_in(), options(),
+ atom(), non_neg_integer()) -> options().
+
+put_value(user_options, KeyVal, Opts, _CallerMod, _CallerLine) when is_map(Opts) ->
+ put_user_value(KeyVal, Opts);
+
+put_value(internal_options, KeyVal, Opts, _CallerMod, _CallerLine) when is_map(Opts) ->
+ InternalOpts = maps:get(internal_options,Opts),
+ Opts#{internal_options := put_internal_value(KeyVal, InternalOpts)};
+
+put_value(socket_options, KeyVal, Opts, _CallerMod, _CallerLine) when is_map(Opts) ->
+ SocketOpts = maps:get(socket_options,Opts),
+ Opts#{socket_options := put_socket_value(KeyVal, SocketOpts)}.
+
+
+%%%----------------
+put_user_value(L, Opts) when is_list(L) ->
+ lists:foldl(fun put_user_value/2, Opts, L);
+put_user_value({Key,Value}, Opts) ->
+ Opts#{Key := Value}.
+
+%%%----------------
+put_internal_value(L, IntOpts) when is_list(L) ->
+ lists:foldl(fun put_internal_value/2, IntOpts, L);
+put_internal_value({Key,Value}, IntOpts) ->
+ IntOpts#{Key => Value}.
+
+%%%----------------
+put_socket_value(L, SockOpts) when is_list(L) ->
+ L ++ SockOpts;
+put_socket_value({Key,Value}, SockOpts) ->
+ [{Key,Value} | SockOpts];
+put_socket_value(A, SockOpts) when is_atom(A) ->
+ [A | SockOpts].
+
+%%%================================================================
+%%%
+%%% Delete an option
+%%%
+
+-spec delete_key(option_class(), option_key(), options(),
+ atom(), non_neg_integer()) -> options().
+
+delete_key(internal_options, Key, Opts, _CallerMod, _CallerLine) when is_map(Opts) ->
+ InternalOpts = maps:get(internal_options,Opts),
+ Opts#{internal_options := maps:remove(Key, InternalOpts)}.
+
+
+%%%================================================================
+%%%
+%%% Initialize the options
+%%%
+
+-spec handle_options(role(), proplists:proplist()) -> options() | error() .
+
+-spec handle_options(role(), proplists:proplist(), options()) -> options() | error() .
+
+handle_options(Role, PropList0) ->
+ handle_options(Role, PropList0, #{socket_options => [],
+ internal_options => #{},
+ user_options => []
+ }).
+
+handle_options(Role, PropList0, Opts0) when is_map(Opts0),
+ is_list(PropList0) ->
+ PropList1 = proplists:unfold(PropList0),
+ try
+ OptionDefinitions = default(Role),
+ InitialMap =
+ maps:fold(
+ fun({K,def}, #{default:=V}, M) -> M#{K=>V};
+ (_,_,M) -> M
+ end,
+ Opts0#{user_options =>
+ maps:get(user_options,Opts0) ++ PropList1
+ },
+ OptionDefinitions),
+ %% Enter the user's values into the map; unknown keys are
+ %% treated as socket options
+ lists:foldl(fun(KV, Vals) ->
+ save(KV, OptionDefinitions, Vals)
+ end, InitialMap, PropList1)
+ catch
+ error:{eoptions, KV, undefined} ->
+ {error, {eoptions,KV}};
+
+ error:{eoptions, KV, Txt} when is_list(Txt) ->
+ {error, {eoptions,{KV,lists:flatten(Txt)}}};
+
+ error:{eoptions, KV, Extra} ->
+ {error, {eoptions,{KV,Extra}}}
+ end.
+
+
+check_fun(Key, Defs) ->
+ #{chk := Fun} = maps:get({Key,def}, Defs),
+ Fun.
+
+%%%================================================================
+%%%
+%%% Check and save one option
+%%%
+
+
+%%% First some prohibited inet options:
+save({K,V}, _, _) when K == reuseaddr ;
+ K == active
+ ->
+ forbidden_option(K, V);
+
+%%% then compatibility conversions:
+save({allow_user_interaction,V}, Opts, Vals) ->
+ save({user_interaction,V}, Opts, Vals);
+
+%% Special case for socket options 'inet' and 'inet6'
+save(Inet, Defs, OptMap) when Inet==inet ; Inet==inet6 ->
+ save({inet,Inet}, Defs, OptMap);
+
+%% Two clauses to prepare for a proplists:unfold
+save({Inet,true}, Defs, OptMap) when Inet==inet ; Inet==inet6 -> save({inet,Inet}, Defs, OptMap);
+save({Inet,false}, _Defs, OptMap) when Inet==inet ; Inet==inet6 -> OptMap;
+
+%% and finaly the 'real stuff':
+save({Key,Value}, Defs, OptMap) when is_map(OptMap) ->
+ try (check_fun(Key,Defs))(Value)
+ of
+ true ->
+ OptMap#{Key := Value};
+ {true, ModifiedValue} ->
+ OptMap#{Key := ModifiedValue};
+ false ->
+ error({eoptions, {Key,Value}, "Bad value"})
+ catch
+ %% An unknown Key (= not in the definition map) is
+ %% regarded as an inet option:
+ error:{badkey,{inet,def}} ->
+ %% atomic (= non-tuple) options 'inet' and 'inet6':
+ OptMap#{socket_options := [Value | maps:get(socket_options,OptMap)]};
+ error:{badkey,{Key,def}} ->
+ OptMap#{socket_options := [{Key,Value} | maps:get(socket_options,OptMap)]};
+
+ %% But a Key that is known but the value does not validate
+ %% by the check fun will give an error exception:
+ error:{check,{BadValue,Extra}} ->
+ error({eoptions, {Key,BadValue}, Extra})
+ end.
+
+%%%================================================================
+%%%
+%%% Default options
+%%%
+
+-spec default(role() | common) -> option_declarations() .
+
+default(server) ->
+ (default(common))
+ #{
+ {subsystems, def} =>
+ #{default => [ssh_sftpd:subsystem_spec([])],
+ chk => fun(L) ->
+ is_list(L) andalso
+ lists:all(fun({Name,{CB,Args}}) ->
+ check_string(Name) andalso
+ is_atom(CB) andalso
+ is_list(Args);
+ (_) ->
+ false
+ end, L)
+ end,
+ class => user_options
+ },
+
+ {shell, def} =>
+ #{default => {shell, start, []},
+ chk => fun({M,F,A}) -> is_atom(M) andalso is_atom(F) andalso is_list(A);
+ (V) -> check_function1(V) orelse check_function2(V)
+ end,
+ class => user_options
+ },
+
+ {exec, def} => % FIXME: need some archeology....
+ #{default => undefined,
+ chk => fun({M,F,_}) -> is_atom(M) andalso is_atom(F);
+ (V) -> is_function(V)
+ end,
+ class => user_options
+ },
+
+ {ssh_cli, def} =>
+ #{default => undefined,
+ chk => fun({Cb, As}) -> is_atom(Cb) andalso is_list(As);
+ (V) -> V == no_cli
+ end,
+ class => user_options
+ },
+
+ {system_dir, def} =>
+ #{default => "/etc/ssh",
+ chk => fun(V) -> check_string(V) andalso check_dir(V) end,
+ class => user_options
+ },
+
+ {auth_method_kb_interactive_data, def} =>
+ #{default => undefined, % Default value can be constructed when User is known
+ chk => fun({S1,S2,S3,B}) ->
+ check_string(S1) andalso
+ check_string(S2) andalso
+ check_string(S3) andalso
+ is_boolean(B);
+ (F) ->
+ check_function3(F)
+ end,
+ class => user_options
+ },
+
+ {user_passwords, def} =>
+ #{default => [],
+ chk => fun(V) ->
+ is_list(V) andalso
+ lists:all(fun({S1,S2}) ->
+ check_string(S1) andalso
+ check_string(S2)
+ end, V)
+ end,
+ class => user_options
+ },
+
+ {password, def} =>
+ #{default => undefined,
+ chk => fun check_string/1,
+ class => user_options
+ },
+
+ {dh_gex_groups, def} =>
+ #{default => undefined,
+ chk => fun check_dh_gex_groups/1,
+ class => user_options
+ },
+
+ {dh_gex_limits, def} =>
+ #{default => {0, infinity},
+ chk => fun({I1,I2}) ->
+ check_pos_integer(I1) andalso
+ check_pos_integer(I2) andalso
+ I1 < I2;
+ (_) ->
+ false
+ end,
+ class => user_options
+ },
+
+ {pwdfun, def} =>
+ #{default => undefined,
+ chk => fun(V) -> check_function4(V) orelse check_function2(V) end,
+ class => user_options
+ },
+
+ {negotiation_timeout, def} =>
+ #{default => 2*60*1000,
+ chk => fun check_timeout/1,
+ class => user_options
+ },
+
+ {max_sessions, def} =>
+ #{default => infinity,
+ chk => fun check_pos_integer/1,
+ class => user_options
+ },
+
+ {max_channels, def} =>
+ #{default => infinity,
+ chk => fun check_pos_integer/1,
+ class => user_options
+ },
+
+ {parallel_login, def} =>
+ #{default => false,
+ chk => fun erlang:is_boolean/1,
+ class => user_options
+ },
+
+ {minimal_remote_max_packet_size, def} =>
+ #{default => 0,
+ chk => fun check_pos_integer/1,
+ class => user_options
+ },
+
+ {failfun, def} =>
+ #{default => fun(_,_,_) -> void end,
+ chk => fun(V) -> check_function3(V) orelse
+ check_function2(V) % Backwards compatibility
+ end,
+ class => user_options
+ },
+
+ {connectfun, def} =>
+ #{default => fun(_,_,_) -> void end,
+ chk => fun check_function3/1,
+ class => user_options
+ },
+
+%%%%% Undocumented
+ {infofun, def} =>
+ #{default => fun(_,_,_) -> void end,
+ chk => fun(V) -> check_function3(V) orelse
+ check_function2(V) % Backwards compatibility
+ end,
+ class => user_options
+ }
+ };
+
+default(client) ->
+ (default(common))
+ #{
+ {dsa_pass_phrase, def} =>
+ #{default => undefined,
+ chk => fun check_string/1,
+ class => user_options
+ },
+
+ {rsa_pass_phrase, def} =>
+ #{default => undefined,
+ chk => fun check_string/1,
+ class => user_options
+ },
+
+ {silently_accept_hosts, def} =>
+ #{default => false,
+ chk => fun check_silently_accept_hosts/1,
+ class => user_options
+ },
+
+ {user_interaction, def} =>
+ #{default => true,
+ chk => fun erlang:is_boolean/1,
+ class => user_options
+ },
+
+ {pref_public_key_algs, def} =>
+ #{default => ssh_transport:default_algorithms(public_key),
+ chk => fun check_pref_public_key_algs/1,
+ class => user_options
+ },
+
+ {dh_gex_limits, def} =>
+ #{default => {1024, 6144, 8192}, % FIXME: Is this true nowadays?
+ chk => fun({Min,I,Max}) ->
+ lists:all(fun check_pos_integer/1,
+ [Min,I,Max]);
+ (_) -> false
+ end,
+ class => user_options
+ },
+
+ {connect_timeout, def} =>
+ #{default => infinity,
+ chk => fun check_timeout/1,
+ class => user_options
+ },
+
+ {user, def} =>
+ #{default =>
+ begin
+ Env = case os:type() of
+ {win32, _} -> "USERNAME";
+ {unix, _} -> "LOGNAME"
+ end,
+ case os:getenv(Env) of
+ false ->
+ case os:getenv("USER") of
+ false -> undefined;
+ User -> User
+ end;
+ User ->
+ User
+ end
+ end,
+ chk => fun check_string/1,
+ class => user_options
+ },
+
+ {password, def} =>
+ #{default => undefined,
+ chk => fun check_string/1,
+ class => user_options
+ },
+
+ {quiet_mode, def} =>
+ #{default => false,
+ chk => fun erlang:is_boolean/1,
+ class => user_options
+ },
+
+%%%%% Undocumented
+ {keyboard_interact_fun, def} =>
+ #{default => undefined,
+ chk => fun check_function3/1,
+ class => user_options
+ }
+ };
+
+default(common) ->
+ #{
+ {user_dir, def} =>
+ #{default => false, % FIXME: TBD ~/.ssh at time of call when user is known
+ chk => fun(V) -> check_string(V) andalso check_dir(V) end,
+ class => user_options
+ },
+
+ {preferred_algorithms, def} =>
+ #{default => ssh:default_algorithms(),
+ chk => fun check_preferred_algorithms/1,
+ class => user_options
+ },
+
+ {id_string, def} =>
+ #{default => undefined, % FIXME: see ssh_transport:ssh_vsn/0
+ chk => fun(random) ->
+ {true, {random,2,5}}; % 2 - 5 random characters
+ ({random,I1,I2}) ->
+ %% Undocumented
+ check_pos_integer(I1) andalso
+ check_pos_integer(I2) andalso
+ I1=<I2;
+ (V) ->
+ check_string(V)
+ end,
+ class => user_options
+ },
+
+ {key_cb, def} =>
+ #{default => {ssh_file, []},
+ chk => fun({Mod,Opts}) -> is_atom(Mod) andalso is_list(Opts);
+ (Mod) when is_atom(Mod) -> {true, {Mod,[]}};
+ (_) -> false
+ end,
+ class => user_options
+ },
+
+ {profile, def} =>
+ #{default => ?DEFAULT_PROFILE,
+ chk => fun erlang:is_atom/1,
+ class => user_options
+ },
+
+ {idle_time, def} =>
+ #{default => infinity,
+ chk => fun check_timeout/1,
+ class => user_options
+ },
+
+ %% This is a "SocketOption"...
+ %% {fd, def} =>
+ %% #{default => undefined,
+ %% chk => fun erlang:is_integer/1,
+ %% class => user_options
+ %% },
+
+ {disconnectfun, def} =>
+ #{default => fun(_) -> void end,
+ chk => fun check_function1/1,
+ class => user_options
+ },
+
+ {unexpectedfun, def} =>
+ #{default => fun(_,_) -> report end,
+ chk => fun check_function2/1,
+ class => user_options
+ },
+
+ {ssh_msg_debug_fun, def} =>
+ #{default => fun(_,_,_,_) -> void end,
+ chk => fun check_function4/1,
+ class => user_options
+ },
+
+ {rekey_limit, def} => % FIXME: Why not common?
+ #{default => 1024000000,
+ chk => fun check_non_neg_integer/1,
+ class => user_options
+ },
+
+ {auth_methods, def} =>
+ #{default => ?SUPPORTED_AUTH_METHODS,
+ chk => fun(As) ->
+ try
+ Sup = string:tokens(?SUPPORTED_AUTH_METHODS, ","),
+ New = string:tokens(As, ","),
+ [] == [X || X <- New,
+ not lists:member(X,Sup)]
+ catch
+ _:_ -> false
+ end
+ end,
+ class => user_options
+ },
+
+%%%%% Undocumented
+ {transport, def} =>
+ #{default => ?DEFAULT_TRANSPORT,
+ chk => fun({A,B,C}) ->
+ is_atom(A) andalso is_atom(B) andalso is_atom(C)
+ end,
+ class => user_options
+ },
+
+ {vsn, def} =>
+ #{default => {2,0},
+ chk => fun({Maj,Min}) -> check_non_neg_integer(Maj) andalso check_non_neg_integer(Min);
+ (_) -> false
+ end,
+ class => user_options
+ },
+
+ {tstflg, def} =>
+ #{default => [],
+ chk => fun erlang:is_list/1,
+ class => user_options
+ },
+
+ {user_dir_fun, def} =>
+ #{default => undefined,
+ chk => fun check_function1/1,
+ class => user_options
+ },
+
+ {max_random_length_padding, def} =>
+ #{default => ?MAX_RND_PADDING_LEN,
+ chk => fun check_non_neg_integer/1,
+ class => user_options
+ },
+
+ {send_ext_info, def} =>
+ #{default => true,
+ chk => fun erlang:is_boolean/1,
+ class => user_options
+ },
+
+ {recv_ext_info, def} =>
+ #{default => true,
+ chk => fun erlang:is_boolean/1,
+ class => user_options
+ }
+ }.
+
+
+%%%================================================================
+%%%================================================================
+%%%================================================================
+
+%%%
+%%% check_*/1 -> true | false | error({check,Spec})
+%%% See error_in_check/2,3
+%%%
+
+%%% error_in_check(BadValue) -> error_in_check(BadValue, undefined).
+
+error_in_check(BadValue, Extra) -> error({check,{BadValue,Extra}}).
+
+
+%%%----------------------------------------------------------------
+check_timeout(infinity) -> true;
+check_timeout(I) -> check_pos_integer(I).
+
+%%%----------------------------------------------------------------
+check_pos_integer(I) -> is_integer(I) andalso I>0.
+
+%%%----------------------------------------------------------------
+check_non_neg_integer(I) -> is_integer(I) andalso I>=0.
+
+%%%----------------------------------------------------------------
+check_function1(F) -> is_function(F,1).
+check_function2(F) -> is_function(F,2).
+check_function3(F) -> is_function(F,3).
+check_function4(F) -> is_function(F,4).
+
+%%%----------------------------------------------------------------
+check_pref_public_key_algs(V) ->
+ %% Get the dynamically supported keys, that is, thoose
+ %% that are stored
+ PKs = ssh_transport:supported_algorithms(public_key),
+ CHK = fun(A, Ack) ->
+ case lists:member(A, PKs) of
+ true ->
+ case lists:member(A,Ack) of
+ false -> [A|Ack];
+ true -> Ack % Remove duplicates
+ end;
+ false -> error_in_check(A, "Not supported public key")
+ end
+ end,
+ case lists:foldr(
+ fun(ssh_dsa, Ack) -> CHK('ssh-dss', Ack); % compatibility
+ (ssh_rsa, Ack) -> CHK('ssh-rsa', Ack); % compatibility
+ (X, Ack) -> CHK(X, Ack)
+ end, [], V)
+ of
+ V -> true;
+ [] -> false;
+ V1 -> {true,V1}
+ end.
+
+
+%%%----------------------------------------------------------------
+%% Check that it is a directory and is readable
+check_dir(Dir) ->
+ case file:read_file_info(Dir) of
+ {ok, #file_info{type = directory,
+ access = Access}} ->
+ case Access of
+ read -> true;
+ read_write -> true;
+ _ -> error_in_check(Dir, eacces)
+ end;
+
+ {ok, #file_info{}}->
+ error_in_check(Dir, enotdir);
+
+ {error, Error} ->
+ error_in_check(Dir, Error)
+ end.
+
+%%%----------------------------------------------------------------
+check_string(S) -> is_list(S). % FIXME: stub
+
+%%%----------------------------------------------------------------
+check_dh_gex_groups({file,File}) when is_list(File) ->
+ case file:consult(File) of
+ {ok, GroupDefs} ->
+ check_dh_gex_groups(GroupDefs);
+ {error, Error} ->
+ error_in_check({file,File},Error)
+ end;
+
+check_dh_gex_groups({ssh_moduli_file,File}) when is_list(File) ->
+ case file:open(File,[read]) of
+ {ok,D} ->
+ try
+ read_moduli_file(D, 1, [])
+ of
+ {ok,Moduli} ->
+ check_dh_gex_groups(Moduli);
+ {error,Error} ->
+ error_in_check({ssh_moduli_file,File}, Error)
+ catch
+ _:_ ->
+ error_in_check({ssh_moduli_file,File}, "Bad format in file "++File)
+ after
+ file:close(D)
+ end;
+
+ {error, Error} ->
+ error_in_check({ssh_moduli_file,File}, Error)
+ end;
+
+check_dh_gex_groups(L0) when is_list(L0), is_tuple(hd(L0)) ->
+ {true,
+ collect_per_size(
+ lists:foldl(
+ fun({N,G,P}, Acc) when is_integer(N),N>0,
+ is_integer(G),G>0,
+ is_integer(P),P>0 ->
+ [{N,{G,P}} | Acc];
+ ({N,{G,P}}, Acc) when is_integer(N),N>0,
+ is_integer(G),G>0,
+ is_integer(P),P>0 ->
+ [{N,{G,P}} | Acc];
+ ({N,GPs}, Acc) when is_list(GPs) ->
+ lists:foldr(fun({Gi,Pi}, Acci) when is_integer(Gi),Gi>0,
+ is_integer(Pi),Pi>0 ->
+ [{N,{Gi,Pi}} | Acci]
+ end, Acc, GPs)
+ end, [], L0))};
+
+check_dh_gex_groups(_) ->
+ false.
+
+
+
+collect_per_size(L) ->
+ lists:foldr(
+ fun({Sz,GP}, [{Sz,GPs}|Acc]) -> [{Sz,[GP|GPs]}|Acc];
+ ({Sz,GP}, Acc) -> [{Sz,[GP]}|Acc]
+ end, [], lists:sort(L)).
+
+read_moduli_file(D, I, Acc) ->
+ case io:get_line(D,"") of
+ {error,Error} ->
+ {error,Error};
+ eof ->
+ {ok, Acc};
+ "#" ++ _ -> read_moduli_file(D, I+1, Acc);
+ <<"#",_/binary>> -> read_moduli_file(D, I+1, Acc);
+ Data ->
+ Line = if is_binary(Data) -> binary_to_list(Data);
+ is_list(Data) -> Data
+ end,
+ try
+ [_Time,_Class,_Tests,_Tries,Size,G,P] = string:tokens(Line," \r\n"),
+ M = {list_to_integer(Size),
+ {list_to_integer(G), list_to_integer(P,16)}
+ },
+ read_moduli_file(D, I+1, [M|Acc])
+ catch
+ _:_ ->
+ read_moduli_file(D, I+1, Acc)
+ end
+ end.
+
+%%%----------------------------------------------------------------
+-define(SHAs, [md5, sha, sha224, sha256, sha384, sha512]).
+
+check_silently_accept_hosts(B) when is_boolean(B) -> true;
+check_silently_accept_hosts(F) when is_function(F,2) -> true;
+check_silently_accept_hosts({false,S}) when is_atom(S) -> valid_hash(S);
+check_silently_accept_hosts({S,F}) when is_function(F,2) -> valid_hash(S);
+check_silently_accept_hosts(_) -> false.
+
+
+valid_hash(S) -> valid_hash(S, proplists:get_value(hashs,crypto:supports())).
+
+valid_hash(S, Ss) when is_atom(S) -> lists:member(S, ?SHAs) andalso lists:member(S, Ss);
+valid_hash(L, Ss) when is_list(L) -> lists:all(fun(S) -> valid_hash(S,Ss) end, L);
+valid_hash(X, _) -> error_in_check(X, "Expect atom or list in fingerprint spec").
+
+%%%----------------------------------------------------------------
+check_preferred_algorithms(Algs) ->
+ [error_in_check(K,"Bad preferred_algorithms key")
+ || {K,_} <- Algs,
+ not lists:keymember(K,1,ssh:default_algorithms())],
+
+ try alg_duplicates(Algs, [], [])
+ of
+ [] ->
+ {true,
+ [case proplists:get_value(Key, Algs) of
+ undefined ->
+ {Key,DefAlgs};
+ Vals ->
+ handle_pref_alg(Key,Vals,SupAlgs)
+ end
+ || {{Key,DefAlgs}, {Key,SupAlgs}} <- lists:zip(ssh:default_algorithms(),
+ ssh_transport:supported_algorithms())
+ ]
+ };
+
+ Dups ->
+ error_in_check(Dups, "Duplicates")
+ catch
+ _:_ ->
+ false
+ end.
+
+alg_duplicates([{K,V}|KVs], Ks, Dups0) ->
+ Dups =
+ case lists:member(K,Ks) of
+ true -> [K|Dups0];
+ false -> Dups0
+ end,
+ case V--lists:usort(V) of
+ [] -> alg_duplicates(KVs, [K|Ks], Dups);
+ Ds -> alg_duplicates(KVs, [K|Ks], Dups++Ds)
+ end;
+alg_duplicates([], _Ks, Dups) ->
+ Dups.
+
+handle_pref_alg(Key,
+ Vs=[{client2server,C2Ss=[_|_]},{server2client,S2Cs=[_|_]}],
+ [{client2server,Sup_C2Ss},{server2client,Sup_S2Cs}]
+ ) ->
+ chk_alg_vs(Key, C2Ss, Sup_C2Ss),
+ chk_alg_vs(Key, S2Cs, Sup_S2Cs),
+ {Key, Vs};
+
+handle_pref_alg(Key,
+ Vs=[{server2client,[_|_]},{client2server,[_|_]}],
+ Sup=[{client2server,_},{server2client,_}]
+ ) ->
+ handle_pref_alg(Key, lists:reverse(Vs), Sup);
+
+handle_pref_alg(Key,
+ Vs=[V|_],
+ Sup=[{client2server,_},{server2client,_}]
+ ) when is_atom(V) ->
+ handle_pref_alg(Key, [{client2server,Vs},{server2client,Vs}], Sup);
+
+handle_pref_alg(Key,
+ Vs=[V|_],
+ Sup=[S|_]
+ ) when is_atom(V), is_atom(S) ->
+ chk_alg_vs(Key, Vs, Sup),
+ {Key, Vs};
+
+handle_pref_alg(Key, Vs, _) ->
+ error_in_check({Key,Vs}, "Badly formed list").
+
+chk_alg_vs(OptKey, Values, SupportedValues) ->
+ case (Values -- SupportedValues) of
+ [] -> Values;
+ [none] -> [none]; % for testing only
+ Bad -> error_in_check({OptKey,Bad}, "Unsupported value(s) found")
+ end.
+
+%%%----------------------------------------------------------------
+forbidden_option(K,V) ->
+ Txt = io_lib:format("The option '~s' is used internally. The "
+ "user is not allowed to specify this option.",
+ [K]),
+ error({eoptions, {K,V}, Txt}).
+
+%%%----------------------------------------------------------------
diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl
index afc2fb88ff..c1558a19b1 100644
--- a/lib/ssh/src/ssh_sftp.erl
+++ b/lib/ssh/src/ssh_sftp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@
-export([open/3, open_tar/3, opendir/2, close/2, readdir/2, pread/4, read/3,
open/4, open_tar/4, opendir/3, close/3, readdir/3, pread/5, read/4,
apread/4, aread/3, pwrite/4, write/3, apwrite/4, awrite/3,
- pwrite/5, write/4,
+ pwrite/5, write/4,
position/3, real_path/2, read_file_info/2, get_file_info/2,
position/4, real_path/3, read_file_info/3, get_file_info/3,
write_file_info/3, read_link_info/2, read_link/2, make_symlink/3,
@@ -52,7 +52,7 @@
%% TODO: Should be placed elsewhere ssh_sftpd should not call functions in ssh_sftp!
-export([info_to_attr/1, attr_to_info/1]).
--record(state,
+-record(state,
{
xf,
rep_buf = <<>>,
@@ -64,7 +64,7 @@
-record(fileinf,
{
- handle,
+ handle,
offset,
size,
mode
@@ -81,7 +81,7 @@
enc_text_buf = <<>>, % Encrypted text
plain_text_buf = <<>> % Decrypted text
}).
-
+
-define(FILEOP_TIMEOUT, infinity).
-define(NEXT_REQID(S),
@@ -98,20 +98,16 @@ start_channel(Cm) when is_pid(Cm) ->
start_channel(Socket) when is_port(Socket) ->
start_channel(Socket, []);
start_channel(Host) when is_list(Host) ->
- start_channel(Host, []).
-
-start_channel(Socket, Options) when is_port(Socket) ->
- Timeout =
- %% A mixture of ssh:connect and ssh_sftp:start_channel:
- case proplists:get_value(connect_timeout, Options, undefined) of
- undefined ->
- proplists:get_value(timeout, Options, infinity);
- TO ->
- TO
- end,
- case ssh:connect(Socket, Options, Timeout) of
- {ok,Cm} ->
- case start_channel(Cm, Options) of
+ start_channel(Host, []).
+
+start_channel(Socket, UserOptions) when is_port(Socket) ->
+ {SshOpts, _ChanOpts, SftpOpts} = handle_options(UserOptions),
+ Timeout = % A mixture of ssh:connect and ssh_sftp:start_channel:
+ proplists:get_value(connect_timeout, SshOpts,
+ proplists:get_value(timeout, SftpOpts, infinity)),
+ case ssh:connect(Socket, SshOpts, Timeout) of
+ {ok,Cm} ->
+ case start_channel(Cm, UserOptions) of
{ok, Pid} ->
{ok, Pid, Cm};
Error ->
@@ -120,17 +116,17 @@ start_channel(Socket, Options) when is_port(Socket) ->
Error ->
Error
end;
-start_channel(Cm, Opts) when is_pid(Cm) ->
- Timeout = proplists:get_value(timeout, Opts, infinity),
- {_, ChanOpts, SftpOpts} = handle_options(Opts, [], [], []),
+start_channel(Cm, UserOptions) when is_pid(Cm) ->
+ Timeout = proplists:get_value(timeout, UserOptions, infinity),
+ {_SshOpts, ChanOpts, SftpOpts} = handle_options(UserOptions),
case ssh_xfer:attach(Cm, [], ChanOpts) of
- {ok, ChannelId, Cm} ->
- case ssh_channel:start(Cm, ChannelId,
+ {ok, ChannelId, Cm} ->
+ case ssh_channel:start(Cm, ChannelId,
?MODULE, [Cm, ChannelId, SftpOpts]) of
{ok, Pid} ->
case wait_for_version_negotiation(Pid, Timeout) of
ok ->
- {ok, Pid};
+ {ok, Pid};
TimeOut ->
TimeOut
end;
@@ -143,15 +139,17 @@ start_channel(Cm, Opts) when is_pid(Cm) ->
Error
end;
-start_channel(Host, Opts) ->
- start_channel(Host, 22, Opts).
-start_channel(Host, Port, Opts) ->
- {SshOpts, ChanOpts, SftpOpts} = handle_options(Opts, [], [], []),
- Timeout = proplists:get_value(timeout, SftpOpts, infinity),
+start_channel(Host, UserOptions) ->
+ start_channel(Host, 22, UserOptions).
+
+start_channel(Host, Port, UserOptions) ->
+ {SshOpts, ChanOpts, SftpOpts} = handle_options(UserOptions),
+ Timeout = % A mixture of ssh:connect and ssh_sftp:start_channel:
+ proplists:get_value(connect_timeout, SshOpts,
+ proplists:get_value(timeout, SftpOpts, infinity)),
case ssh_xfer:connect(Host, Port, SshOpts, ChanOpts, Timeout) of
{ok, ChannelId, Cm} ->
- case ssh_channel:start(Cm, ChannelId, ?MODULE, [Cm,
- ChannelId, SftpOpts]) of
+ case ssh_channel:start(Cm, ChannelId, ?MODULE, [Cm,ChannelId,SftpOpts]) of
{ok, Pid} ->
case wait_for_version_negotiation(Pid, Timeout) of
ok ->
@@ -165,7 +163,7 @@ start_channel(Host, Port, Opts) ->
{error, ignore}
end;
Error ->
- Error
+ Error
end.
stop_channel(Pid) ->
@@ -174,12 +172,12 @@ stop_channel(Pid) ->
OldValue = process_flag(trap_exit, true),
link(Pid),
exit(Pid, ssh_sftp_stop_channel),
- receive
+ receive
{'EXIT', Pid, normal} ->
ok
after 5000 ->
exit(Pid, kill),
- receive
+ receive
{'EXIT', Pid, killed} ->
ok
end
@@ -209,9 +207,9 @@ open_tar(Pid, File, Mode, FileOpTimeout) ->
erl_tar:init(Pid, write,
fun(write, {_,Data}) ->
write_to_remote_tar(Pid, Handle, to_bin(Data), FileOpTimeout);
- (position, {_,Pos}) ->
+ (position, {_,Pos}) ->
position(Pid, Handle, Pos, FileOpTimeout);
- (close, _) ->
+ (close, _) ->
close(Pid, Handle, FileOpTimeout)
end);
{true,false,[{crypto,{CryptoInitFun,CryptoEncryptFun,CryptoEndFun}}]} ->
@@ -245,9 +243,9 @@ open_tar(Pid, File, Mode, FileOpTimeout) ->
erl_tar:init(Pid, read,
fun(read2, {_,Len}) ->
read_repeat(Pid, Handle, Len, FileOpTimeout);
- (position, {_,Pos}) ->
+ (position, {_,Pos}) ->
position(Pid, Handle, Pos, FileOpTimeout);
- (close, _) ->
+ (close, _) ->
close(Pid, Handle, FileOpTimeout)
end);
{false,true,[{crypto,{CryptoInitFun,CryptoDecryptFun}}]} ->
@@ -258,9 +256,9 @@ open_tar(Pid, File, Mode, FileOpTimeout) ->
erl_tar:init(Pid, read,
fun(read2, {_,Len}) ->
read_buf(Pid, SftpHandle, BufHandle, Len, FileOpTimeout);
- (position, {_,Pos}) ->
+ (position, {_,Pos}) ->
position_buf(Pid, SftpHandle, BufHandle, Pos, FileOpTimeout);
- (close, _) ->
+ (close, _) ->
call(Pid, {erase_bufinf,BufHandle}, FileOpTimeout),
close(Pid, SftpHandle, FileOpTimeout)
end);
@@ -292,16 +290,16 @@ pread(Pid, Handle, Offset, Len, FileOpTimeout) ->
read(Pid, Handle, Len) ->
read(Pid, Handle, Len, ?FILEOP_TIMEOUT).
read(Pid, Handle, Len, FileOpTimeout) ->
- call(Pid, {read,false,Handle, Len}, FileOpTimeout).
+ call(Pid, {read,false,Handle, Len}, FileOpTimeout).
-%% TODO this ought to be a cast! Is so in all practial meaning
+%% TODO this ought to be a cast! Is so in all practical meaning
%% even if it is obscure!
apread(Pid, Handle, Offset, Len) ->
call(Pid, {pread,true,Handle, Offset, Len}, infinity).
%% TODO this ought to be a cast!
aread(Pid, Handle, Len) ->
- call(Pid, {read,true,Handle, Len}, infinity).
+ call(Pid, {read,true,Handle, Len}, infinity).
pwrite(Pid, Handle, Offset, Data) ->
pwrite(Pid, Handle, Offset, Data, ?FILEOP_TIMEOUT).
@@ -313,12 +311,12 @@ write(Pid, Handle, Data) ->
write(Pid, Handle, Data, FileOpTimeout) ->
call(Pid, {write,false,Handle,Data}, FileOpTimeout).
-%% TODO this ought to be a cast! Is so in all practial meaning
+%% TODO this ought to be a cast! Is so in all practical meaning
%% even if it is obscure!
apwrite(Pid, Handle, Offset, Data) ->
call(Pid, {pwrite,true,Handle,Offset,Data}, infinity).
-%% TODO this ought to be a cast! Is so in all practial meaning
+%% TODO this ought to be a cast! Is so in all practical meaning
%% even if it is obscure!
awrite(Pid, Handle, Data) ->
call(Pid, {write,true,Handle,Data}, infinity).
@@ -367,7 +365,7 @@ make_symlink(Pid, Name, Target) ->
make_symlink(Pid, Name, Target, ?FILEOP_TIMEOUT).
make_symlink(Pid, Name, Target, FileOpTimeout) ->
call(Pid, {make_symlink,false, Name, Target}, FileOpTimeout).
-
+
rename(Pid, FromFile, ToFile) ->
rename(Pid, FromFile, ToFile, ?FILEOP_TIMEOUT).
rename(Pid, FromFile, ToFile, FileOpTimeout) ->
@@ -411,8 +409,8 @@ list_dir(Pid, Name, FileOpTimeout) ->
close(Pid, Handle, FileOpTimeout),
case Res of
{ok, List} ->
- NList = lists:foldl(fun({Nm, _Info},Acc) ->
- [Nm|Acc] end,
+ NList = lists:foldl(fun({Nm, _Info},Acc) ->
+ [Nm|Acc] end,
[], List),
{ok,NList};
Error -> Error
@@ -482,7 +480,7 @@ write_file_loop(Pid, Handle, Pos, Bin, Remain, PacketSz, FileOpTimeout) ->
<<_:Pos/binary, Data:PacketSz/binary, _/binary>> = Bin,
case write(Pid, Handle, Data, FileOpTimeout) of
ok ->
- write_file_loop(Pid, Handle,
+ write_file_loop(Pid, Handle,
Pos+PacketSz, Bin, Remain-PacketSz,
PacketSz, FileOpTimeout);
Error ->
@@ -510,7 +508,7 @@ init([Cm, ChannelId, Options]) ->
Xf = #ssh_xfer{cm = Cm,
channel = ChannelId},
{ok, #state{xf = Xf,
- req_id = 0,
+ req_id = 0,
rep_buf = <<>>,
inf = new_inf(),
opts = Options}};
@@ -519,7 +517,7 @@ init([Cm, ChannelId, Options]) ->
Error ->
{stop, {shutdown, Error}}
end.
-
+
%%--------------------------------------------------------------------
%% Function: handle_call/3
%% Description: Handling call messages
@@ -541,7 +539,7 @@ handle_call({{timeout, Timeout}, wait_for_version_negotiation}, From,
handle_call({_, wait_for_version_negotiation}, _, State) ->
{reply, ok, State};
-
+
handle_call({{timeout, infinity}, Msg}, From, State) ->
do_handle_call(Msg, From, State);
handle_call({{timeout, Timeout}, Msg}, From, #state{req_id = Id} = State) ->
@@ -555,13 +553,13 @@ code_change(_OldVsn, State, _Extra) ->
{ok, State}.
do_handle_call({get_bufinf,BufHandle}, _From, S=#state{inf=I0}) ->
- {reply, dict:find(BufHandle,I0), S};
+ {reply, maps:find(BufHandle,I0), S};
do_handle_call({put_bufinf,BufHandle,B}, _From, S=#state{inf=I0}) ->
- {reply, ok, S#state{inf=dict:store(BufHandle,B,I0)}};
+ {reply, ok, S#state{inf=maps:put(BufHandle,B,I0)}};
do_handle_call({erase_bufinf,BufHandle}, _From, S=#state{inf=I0}) ->
- {reply, ok, S#state{inf=dict:erase(BufHandle,I0)}};
+ {reply, ok, S#state{inf=maps:remove(BufHandle,I0)}};
do_handle_call({open, Async,FileName,Mode}, From, #state{xf = XF} = State) ->
{Access,Flags,Attrs} = open_mode(XF#ssh_xfer.vsn, Mode),
@@ -636,7 +634,7 @@ do_handle_call({pread,Async,Handle,At,Length}, From, State) ->
binary -> {{ok,Data}, State2};
text -> {{ok,binary_to_list(Data)}, State2}
end;
- (Rep, State2) ->
+ (Rep, State2) ->
{Rep, State2}
end);
Error ->
@@ -777,7 +775,7 @@ do_handle_call(recv_window, _From, State) ->
do_handle_call(stop, _From, State) ->
{stop, shutdown, ok, State};
-do_handle_call(Call, _From, State) ->
+do_handle_call(Call, _From, State) ->
{reply, {error, bad_call, Call, State}, State}.
%%--------------------------------------------------------------------
@@ -785,13 +783,13 @@ do_handle_call(Call, _From, State) ->
%%
%% Description: Handles channel messages
%%--------------------------------------------------------------------
-handle_ssh_msg({ssh_cm, _ConnectionManager,
- {data, _ChannelId, 0, Data}}, #state{rep_buf = Data0} =
+handle_ssh_msg({ssh_cm, _ConnectionManager,
+ {data, _ChannelId, 0, Data}}, #state{rep_buf = Data0} =
State0) ->
State = handle_reply(State0, <<Data0/binary,Data/binary>>),
{ok, State};
-handle_ssh_msg({ssh_cm, _ConnectionManager,
+handle_ssh_msg({ssh_cm, _ConnectionManager,
{data, _ChannelId, 1, Data}}, State) ->
error_logger:format("ssh: STDERR: ~s\n", [binary_to_list(Data)]),
{ok, State};
@@ -803,7 +801,7 @@ handle_ssh_msg({ssh_cm, _, {signal, _, _}}, State) ->
%% Ignore signals according to RFC 4254 section 6.9.
{ok, State};
-handle_ssh_msg({ssh_cm, _, {exit_signal, ChannelId, _, Error, _}},
+handle_ssh_msg({ssh_cm, _, {exit_signal, ChannelId, _, Error, _}},
State0) ->
State = reply_all(State0, {error, Error}),
{stop, ChannelId, State};
@@ -823,7 +821,7 @@ handle_msg({ssh_channel_up, _, _}, #state{opts = Options, xf = Xf} = State) ->
{ok, State};
%% Version negotiation timed out
-handle_msg({timeout, undefined, From},
+handle_msg({timeout, undefined, From},
#state{xf = #ssh_xfer{channel = ChannelId}} = State) ->
ssh_channel:reply(From, {error, timeout}),
{stop, ChannelId, State};
@@ -839,12 +837,12 @@ handle_msg({timeout, Id, From}, #state{req_list = ReqList0} = State) ->
end;
%% Connection manager goes down
-handle_msg({'DOWN', _Ref, _Type, _Process, _},
+handle_msg({'DOWN', _Ref, _Type, _Process, _},
#state{xf = #ssh_xfer{channel = ChannelId}} = State) ->
{stop, ChannelId, State};
-
+
%% Stopped by user
-handle_msg({'EXIT', _, ssh_sftp_stop_channel},
+handle_msg({'EXIT', _, ssh_sftp_stop_channel},
#state{xf = #ssh_xfer{channel = ChannelId}} = State) ->
{stop, ChannelId, State};
@@ -865,6 +863,9 @@ terminate(_Reason, State) ->
%%====================================================================
%% Internal functions
%%====================================================================
+handle_options(UserOptions) ->
+ handle_options(UserOptions, [], [], []).
+
handle_options([], Sftp, Chan, Ssh) ->
{Ssh, Chan, Sftp};
handle_options([{timeout, _} = Opt | Rest], Sftp, Chan, Ssh) ->
@@ -883,10 +884,10 @@ call(Pid, Msg, TimeOut) ->
handle_reply(State, <<?UINT32(Len),Reply:Len/binary,Rest/binary>>) ->
do_handle_reply(State, Reply, Rest);
-handle_reply(State, Data) ->
+handle_reply(State, Data) ->
State#state{rep_buf = Data}.
-do_handle_reply(#state{xf = Xf} = State,
+do_handle_reply(#state{xf = Xf} = State,
<<?SSH_FXP_VERSION, ?UINT32(Version), BinExt/binary>>, Rest) ->
Ext = ssh_xfer:decode_ext(BinExt),
case Xf#ssh_xfer.vsn of
@@ -899,7 +900,7 @@ do_handle_reply(#state{xf = Xf} = State,
ok
end,
ssh_channel:reply(From, ok)
- end,
+ end,
State#state{xf = Xf#ssh_xfer{vsn = Version, ext = Ext}, rep_buf = Rest};
do_handle_reply(State0, Data, Rest) ->
@@ -919,9 +920,9 @@ handle_req_reply(State0, {_, ReqID, _} = XfReply) ->
List = lists:keydelete(ReqID, 1, State0#state.req_list),
State1 = State0#state { req_list = List },
case catch Fun(xreply(XfReply),State1) of
- {'EXIT', _} ->
+ {'EXIT', _} ->
State1;
- State ->
+ State ->
State
end
end.
@@ -998,15 +999,15 @@ reply_all(State, Reply) ->
make_reply(ReqID, true, From, State) ->
{reply, {async, ReqID},
update_request_info(ReqID, State,
- fun(Reply,State1) ->
+ fun(Reply,State1) ->
async_reply(ReqID,Reply,From,State1)
end)};
make_reply(ReqID, false, From, State) ->
{noreply,
update_request_info(ReqID, State,
- fun(Reply,State1) ->
- sync_reply(Reply, From, State1)
+ fun(Reply,State1) ->
+ sync_reply(Reply, From, State1)
end)}.
make_reply_post(ReqID, true, From, State, PostFun) ->
@@ -1062,25 +1063,16 @@ attr_to_info(A) when is_record(A, ssh_xfer_attr) ->
gid = A#ssh_xfer_attr.group}.
-%% Added workaround for sftp timestam problem. (Timestamps should be
-%% in UTC but they where not) . The workaround uses a deprecated
-%% function i calandar. This will work as expected most of the time
-%% but has problems for the same reason as
-%% calendar:local_time_to_universal_time/1. We consider it better that
-%% the timestamps work as expected most of the time instead of none of
-%% the time. Hopfully the file-api will be updated so that we can
-%% solve this problem in a better way in the future.
-
unix_to_datetime(undefined) ->
undefined;
unix_to_datetime(UTCSecs) ->
- UTCDateTime =
+ UTCDateTime =
calendar:gregorian_seconds_to_datetime(UTCSecs + 62167219200),
erlang:universaltime_to_localtime(UTCDateTime).
datetime_to_unix(undefined) ->
undefined;
-datetime_to_unix(LocalDateTime) ->
+datetime_to_unix(LocalDateTime) ->
UTCDateTime = erlang:localtime_to_universaltime(LocalDateTime),
calendar:datetime_to_gregorian_seconds(UTCDateTime) - 62167219200.
@@ -1128,11 +1120,11 @@ open_mode3(Modes) ->
end,
{[], Fl, A}.
-%% accessors for inf dict
-new_inf() -> dict:new().
+%% accessors for inf map
+new_inf() -> #{}.
add_new_handle(Handle, FileMode, Inf) ->
- dict:store(Handle, #fileinf{offset=0, size=0, mode=FileMode}, Inf).
+ maps:put(Handle, #fileinf{offset=0, size=0, mode=FileMode}, Inf).
update_size(Handle, NewSize, State) ->
OldSize = get_size(Handle, State),
@@ -1152,27 +1144,24 @@ update_offset(Handle, NewOffset, State0) ->
%% access size and offset for handle
put_size(Handle, Size, State) ->
Inf0 = State#state.inf,
- case dict:find(Handle, Inf0) of
+ case maps:find(Handle, Inf0) of
{ok, FI} ->
- State#state{inf=dict:store(Handle, FI#fileinf{size=Size}, Inf0)};
+ State#state{inf=maps:put(Handle, FI#fileinf{size=Size}, Inf0)};
_ ->
- State#state{inf=dict:store(Handle, #fileinf{size=Size,offset=0},
- Inf0)}
+ State#state{inf=maps:put(Handle, #fileinf{size=Size,offset=0}, Inf0)}
end.
put_offset(Handle, Offset, State) ->
Inf0 = State#state.inf,
- case dict:find(Handle, Inf0) of
+ case maps:find(Handle, Inf0) of
{ok, FI} ->
- State#state{inf=dict:store(Handle, FI#fileinf{offset=Offset},
- Inf0)};
+ State#state{inf=maps:put(Handle, FI#fileinf{offset=Offset}, Inf0)};
_ ->
- State#state{inf=dict:store(Handle, #fileinf{size=Offset,
- offset=Offset}, Inf0)}
+ State#state{inf=maps:put(Handle, #fileinf{size=Offset, offset=Offset}, Inf0)}
end.
get_size(Handle, State) ->
- case dict:find(Handle, State#state.inf) of
+ case maps:find(Handle, State#state.inf) of
{ok, FI} ->
FI#fileinf.size;
_ ->
@@ -1180,11 +1169,11 @@ get_size(Handle, State) ->
end.
%% get_offset(Handle, State) ->
-%% {ok, FI} = dict:find(Handle, State#state.inf),
+%% {ok, FI} = maps:find(Handle, State#state.inf),
%% FI#fileinf.offset.
get_mode(Handle, State) ->
- case dict:find(Handle, State#state.inf) of
+ case maps:find(Handle, State#state.inf) of
{ok, FI} ->
FI#fileinf.mode;
_ ->
@@ -1192,14 +1181,14 @@ get_mode(Handle, State) ->
end.
erase_handle(Handle, State) ->
- FI = dict:erase(Handle, State#state.inf),
+ FI = maps:remove(Handle, State#state.inf),
State#state{inf = FI}.
%%
%% Caluclate a integer offset
%%
lseek_position(Handle, Pos, State) ->
- case dict:find(Handle, State#state.inf) of
+ case maps:find(Handle, State#state.inf) of
{ok, #fileinf{offset=O, size=S}} ->
lseek_pos(Pos, O, S);
_ ->
@@ -1229,7 +1218,7 @@ lseek_pos({cur, Offset}, CurOffset, _CurSize)
true ->
{ok, NewOffset}
end;
-lseek_pos({eof, Offset}, _CurOffset, CurSize)
+lseek_pos({eof, Offset}, _CurOffset, CurSize)
when is_integer(Offset) andalso -(?SSH_FILEXFER_LARGEFILESIZE) =< Offset andalso
Offset < ?SSH_FILEXFER_LARGEFILESIZE ->
NewOffset = CurSize + Offset,
@@ -1239,7 +1228,7 @@ lseek_pos({eof, Offset}, _CurOffset, CurSize)
{ok, NewOffset}
end;
lseek_pos(_, _, _) ->
- {error, einval}.
+ {error, einval}.
%%%================================================================
%%%
@@ -1277,13 +1266,13 @@ position_buf(Pid, SftpHandle, BufHandle, Pos, FileOpTimeout) ->
case Pos of
{cur,0} when Mode==write ->
{ok,Size+size(Buf0)};
-
+
{cur,0} when Mode==read ->
{ok,Size};
-
+
_ when Mode==read, is_integer(Pos) ->
Skip = Pos-Size,
- if
+ if
Skip < 0 ->
{error, cannot_rewind};
Skip == 0 ->
@@ -1318,7 +1307,7 @@ read_buf(Pid, SftpHandle, BufHandle, WantedLen, FileOpTimeout) ->
eof
end.
-do_the_read_buf(_Pid, _SftpHandle, WantedLen, _Packet, _FileOpTimeout,
+do_the_read_buf(_Pid, _SftpHandle, WantedLen, _Packet, _FileOpTimeout,
B=#bufinf{plain_text_buf=PlainBuf0,
size = Size})
when size(PlainBuf0) >= WantedLen ->
@@ -1327,7 +1316,7 @@ do_the_read_buf(_Pid, _SftpHandle, WantedLen, _Packet, _FileOpTimeout,
{ok,ResultBin,B#bufinf{plain_text_buf=PlainBuf,
size = Size + WantedLen}};
-do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
+do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
B0=#bufinf{plain_text_buf = PlainBuf0,
enc_text_buf = EncBuf0,
chunksize = undefined
@@ -1335,12 +1324,12 @@ do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
when size(EncBuf0) > 0 ->
%% We have (at least) one decodable byte waiting for decodeing.
{ok,DecodedBin,B} = apply_crypto(EncBuf0, B0),
- do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
+ do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
B#bufinf{plain_text_buf = <<PlainBuf0/binary, DecodedBin/binary>>,
enc_text_buf = <<>>
});
-
-do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
+
+do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
B0=#bufinf{plain_text_buf = PlainBuf0,
enc_text_buf = EncBuf0,
chunksize = ChunkSize0
@@ -1349,11 +1338,11 @@ do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
%% We have (at least) one chunk of decodable bytes waiting for decodeing.
<<ToDecode:ChunkSize0/binary, EncBuf/binary>> = EncBuf0,
{ok,DecodedBin,B} = apply_crypto(ToDecode, B0),
- do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
+ do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout,
B#bufinf{plain_text_buf = <<PlainBuf0/binary, DecodedBin/binary>>,
enc_text_buf = EncBuf
});
-
+
do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout, B=#bufinf{enc_text_buf = EncBuf0}) ->
%% We must read more bytes and append to the buffer of encoded bytes.
case read(Pid, SftpHandle, Packet, FileOpTimeout) of
@@ -1370,7 +1359,7 @@ do_the_read_buf(Pid, SftpHandle, WantedLen, Packet, FileOpTimeout, B=#bufinf{enc
write_buf(Pid, SftpHandle, BufHandle, PlainBin, FileOpTimeout) ->
{ok,{_Window,Packet}} = send_window(Pid, FileOpTimeout),
{ok,B0=#bufinf{plain_text_buf=PTB}} = call(Pid, {get_bufinf,BufHandle}, FileOpTimeout),
- case do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout,
+ case do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout,
B0#bufinf{plain_text_buf = <<PTB/binary,PlainBin/binary>>}) of
{ok, B} ->
call(Pid, {put_bufinf,BufHandle,B}, FileOpTimeout),
@@ -1379,7 +1368,7 @@ write_buf(Pid, SftpHandle, BufHandle, PlainBin, FileOpTimeout) ->
{error,Error}
end.
-do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout,
+do_the_write_buf(Pid, SftpHandle, Packet, FileOpTimeout,
B=#bufinf{enc_text_buf = EncBuf0,
size = Size})
when size(EncBuf0) >= Packet ->
@@ -1421,9 +1410,9 @@ do_the_write_buf(_Pid, _SftpHandle, _Packet, _FileOpTimeout, B) ->
apply_crypto(In, B=#bufinf{crypto_state = CState0,
crypto_fun = F}) ->
case F(In,CState0) of
- {ok,EncodedBin,CState} ->
+ {ok,EncodedBin,CState} ->
{ok, EncodedBin, B#bufinf{crypto_state=CState}};
- {ok,EncodedBin,CState,ChunkSize} ->
+ {ok,EncodedBin,CState,ChunkSize} ->
{ok, EncodedBin, B#bufinf{crypto_state=CState,
chunksize=ChunkSize}}
end.
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index dca018f20f..427edf01ab 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -34,8 +34,7 @@
%%--------------------------------------------------------------------
%% External exports
--export([subsystem_spec/1,
- listen/1, listen/2, listen/3, stop/1]).
+-export([subsystem_spec/1]).
-export([init/1, handle_ssh_msg/2, handle_msg/2, terminate/2]).
@@ -76,29 +75,6 @@
subsystem_spec(Options) ->
{"sftp", {?MODULE, Options}}.
-%%% DEPRECATED START %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%%--------------------------------------------------------------------
-%% Function: listen() -> Pid | {error,Error}
-%% Description: Starts the server
-%%--------------------------------------------------------------------
-listen(Port) ->
- listen(any, Port, []).
-listen(Port, Options) ->
- listen(any, Port, Options).
-listen(Addr, Port, Options) ->
- SubSystems = [subsystem_spec(Options)],
- ssh:daemon(Addr, Port, [{subsystems, SubSystems} |Options]).
-
-%%--------------------------------------------------------------------
-%% Function: stop(Pid) -> ok
-%% Description: Stops the listener
-%%--------------------------------------------------------------------
-stop(Pid) ->
- ssh:stop_listener(Pid).
-
-
-%%% DEPRECATED END %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%====================================================================
%% subsystem callbacks
@@ -664,29 +640,25 @@ open(Vsn, ReqId, Data, State) when Vsn >= 4 ->
do_open(ReqId, State, Path, Flags).
do_open(ReqId, State0, Path, Flags) ->
- #state{file_handler = FileMod, file_state = FS0, root = Root, xf = #ssh_xfer{vsn = Vsn}} = State0,
- XF = State0#state.xf,
- F = [binary | Flags],
- {IsDir, _FS1} = FileMod:is_dir(Path, FS0),
+ #state{file_handler = FileMod, file_state = FS0, xf = #ssh_xfer{vsn = Vsn}} = State0,
+ AbsPath = relate_file_name(Path, State0),
+ {IsDir, _FS1} = FileMod:is_dir(AbsPath, FS0),
case IsDir of
true when Vsn > 5 ->
ssh_xfer:xf_send_status(State0#state.xf, ReqId,
- ?SSH_FX_FILE_IS_A_DIRECTORY, "File is a directory");
+ ?SSH_FX_FILE_IS_A_DIRECTORY, "File is a directory"),
+ State0;
true ->
ssh_xfer:xf_send_status(State0#state.xf, ReqId,
- ?SSH_FX_FAILURE, "File is a directory");
+ ?SSH_FX_FAILURE, "File is a directory"),
+ State0;
false ->
- AbsPath = case Root of
- "" ->
- Path;
- _ ->
- relate_file_name(Path, State0)
- end,
- {Res, FS1} = FileMod:open(AbsPath, F, FS0),
+ OpenFlags = [binary | Flags],
+ {Res, FS1} = FileMod:open(AbsPath, OpenFlags, FS0),
State1 = State0#state{file_state = FS1},
case Res of
{ok, IoDevice} ->
- add_handle(State1, XF, ReqId, file, {Path,IoDevice});
+ add_handle(State1, State0#state.xf, ReqId, file, {Path,IoDevice});
{error, Error} ->
ssh_xfer:xf_send_status(State1#state.xf, ReqId,
ssh_xfer:encode_erlang_status(Error)),
@@ -742,6 +714,10 @@ resolve_symlinks_2([], State, _LinkCnt, AccPath) ->
{{ok, AccPath}, State}.
+%% The File argument is always in a user visible file system, i.e.
+%% is under Root and is relative to CWD or Root, if starts with "/".
+%% The result of the function is always an absolute path in a
+%% "backend" file system.
relate_file_name(File, State) ->
relate_file_name(File, State, _Canonicalize=true).
@@ -749,19 +725,20 @@ relate_file_name(File, State, Canonicalize) when is_binary(File) ->
relate_file_name(unicode:characters_to_list(File), State, Canonicalize);
relate_file_name(File, #state{cwd = CWD, root = ""}, Canonicalize) ->
relate_filename_to_path(File, CWD, Canonicalize);
-relate_file_name(File, #state{root = Root}, Canonicalize) ->
- case is_within_root(Root, File) of
- true ->
- File;
- false ->
- RelFile = make_relative_filename(File),
- NewFile = relate_filename_to_path(RelFile, Root, Canonicalize),
- case is_within_root(Root, NewFile) of
- true ->
- NewFile;
- false ->
- Root
- end
+relate_file_name(File, #state{cwd = CWD, root = Root}, Canonicalize) ->
+ CWD1 = case is_within_root(Root, CWD) of
+ true -> CWD;
+ false -> Root
+ end,
+ AbsFile = case make_relative_filename(File) of
+ File ->
+ relate_filename_to_path(File, CWD1, Canonicalize);
+ RelFile ->
+ relate_filename_to_path(RelFile, Root, Canonicalize)
+ end,
+ case is_within_root(Root, AbsFile) of
+ true -> AbsFile;
+ false -> Root
end.
is_within_root(Root, File) ->
diff --git a/lib/ssh/src/ssh_sftpd_file_api.erl b/lib/ssh/src/ssh_sftpd_file_api.erl
index 78f452df67..81f181f1fc 100644
--- a/lib/ssh/src/ssh_sftpd_file_api.erl
+++ b/lib/ssh/src/ssh_sftpd_file_api.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@
-callback list_dir(file:name(), State::term()) ->
{{ok, Filenames::term()}, State::term()} | {{error, Reason::term()}, State::term()}.
-callback make_dir(Dir::term(), State::term()) ->
- {{ok, State::term()},State::term()} | {{error, Reason::term()}, State::term()}.
+ {ok, State::term()} | {{error, Reason::term()}, State::term()}.
-callback make_symlink(Path2::term(), Path::term(), State::term()) ->
{ok, State::term()} | {{error, Reason::term()}, State::term()}.
-callback open(Path::term(), Flags::term(), State::term()) ->
diff --git a/lib/ssh/src/ssh_subsystem_sup.erl b/lib/ssh/src/ssh_subsystem_sup.erl
index 637f5f398f..8db051095c 100644
--- a/lib/ssh/src/ssh_subsystem_sup.erl
+++ b/lib/ssh/src/ssh_subsystem_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -26,7 +26,9 @@
-behaviour(supervisor).
--export([start_link/1,
+-include("ssh.hrl").
+
+-export([start_link/5,
connection_supervisor/1,
channel_supervisor/1
]).
@@ -37,8 +39,8 @@
%%%=========================================================================
%%% API
%%%=========================================================================
-start_link(Opts) ->
- supervisor:start_link(?MODULE, [Opts]).
+start_link(Role, Address, Port, Profile, Options) ->
+ supervisor:start_link(?MODULE, [Role, Address, Port, Profile, Options]).
connection_supervisor(SupPid) ->
Children = supervisor:which_children(SupPid),
@@ -51,49 +53,40 @@ channel_supervisor(SupPid) ->
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
--spec init( [term()] ) -> {ok,{supervisor:sup_flags(),[supervisor:child_spec()]}} | ignore .
-
-init([Opts]) ->
- RestartStrategy = one_for_all,
- MaxR = 0,
- MaxT = 3600,
- Children = child_specs(Opts),
- {ok, {{RestartStrategy, MaxR, MaxT}, Children}}.
+init([Role, Address, Port, Profile, Options]) ->
+ SupFlags = #{strategy => one_for_all,
+ intensity => 0,
+ period => 3600
+ },
+ ChildSpecs = child_specs(Role, Address, Port, Profile, Options),
+ {ok, {SupFlags,ChildSpecs}}.
%%%=========================================================================
%%% Internal functions
%%%=========================================================================
-child_specs(Opts) ->
- case proplists:get_value(role, Opts) of
- client ->
- [];
- server ->
- [ssh_channel_child_spec(Opts), ssh_connectinon_child_spec(Opts)]
- end.
+child_specs(client, _Address, _Port, _Profile, _Options) ->
+ [];
+child_specs(server, Address, Port, Profile, Options) ->
+ [ssh_channel_child_spec(server, Address, Port, Profile, Options),
+ ssh_connection_child_spec(server, Address, Port, Profile, Options)].
-ssh_connectinon_child_spec(Opts) ->
- Address = proplists:get_value(address, Opts),
- Port = proplists:get_value(port, Opts),
- Role = proplists:get_value(role, Opts),
- Name = id(Role, ssh_connection_sup, Address, Port),
- StartFunc = {ssh_connection_sup, start_link, [Opts]},
- Restart = temporary,
- Shutdown = 5000,
- Modules = [ssh_connection_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
-ssh_channel_child_spec(Opts) ->
- Address = proplists:get_value(address, Opts),
- Port = proplists:get_value(port, Opts),
- Role = proplists:get_value(role, Opts),
- Name = id(Role, ssh_channel_sup, Address, Port),
- StartFunc = {ssh_channel_sup, start_link, [Opts]},
- Restart = temporary,
- Shutdown = infinity,
- Modules = [ssh_channel_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+ssh_connection_child_spec(Role, Address, Port, _Profile, Options) ->
+ #{id => id(Role, ssh_connection_sup, Address, Port),
+ start => {ssh_connection_sup, start_link, [Options]},
+ restart => temporary,
+ shutdown => 5000,
+ type => supervisor,
+ modules => [ssh_connection_sup]
+ }.
+
+ssh_channel_child_spec(Role, Address, Port, _Profile, Options) ->
+ #{id => id(Role, ssh_channel_sup, Address, Port),
+ start => {ssh_channel_sup, start_link, [Options]},
+ restart => temporary,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [ssh_channel_sup]
+ }.
id(Role, Sup, Address, Port) ->
{Role, Sup, Address, Port}.
diff --git a/lib/ssh/src/ssh_sup.erl b/lib/ssh/src/ssh_sup.erl
index 8b57387589..eaec7a54e4 100644
--- a/lib/ssh/src/ssh_sup.erl
+++ b/lib/ssh/src/ssh_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -31,63 +31,20 @@
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
--spec init( [term()] ) -> {ok,{supervisor:sup_flags(),[supervisor:child_spec()]}} | ignore .
-
-init([]) ->
- SupFlags = {one_for_one, 10, 3600},
- Children = children(),
- {ok, {SupFlags, Children}}.
-
-%%%=========================================================================
-%%% Internal functions
-%%%=========================================================================
-get_services() ->
- case (catch application:get_env(ssh, services)) of
- {ok, Services} ->
- Services;
- _ ->
- []
- end.
-
-children() ->
- Services = get_services(),
- Clients = [Service || Service <- Services, is_client(Service)],
- Servers = [Service || Service <- Services, is_server(Service)],
-
- [server_child_spec(Servers), client_child_spec(Clients)].
-
-server_child_spec(Servers) ->
- Name = sshd_sup,
- StartFunc = {sshd_sup, start_link, [Servers]},
- Restart = permanent,
- Shutdown = infinity,
- Modules = [sshd_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
-client_child_spec(Clients) ->
- Name = sshc_sup,
- StartFunc = {sshc_sup, start_link, [Clients]},
- Restart = permanent,
- Shutdown = infinity,
- Modules = [sshc_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
-is_server({sftpd, _}) ->
- true;
-is_server({shelld, _}) ->
- true;
-is_server(_) ->
- false.
-
-is_client({sftpc, _}) ->
- true;
-is_client({shellc, _}) ->
- true;
-is_client(_) ->
- false.
-
-
-
+init(_) ->
+ SupFlags = #{strategy => one_for_one,
+ intensity => 10,
+ period => 3600
+ },
+ ChildSpecs = [#{id => Module,
+ start => {Module, start_link, []},
+ restart => permanent,
+ shutdown => 4000, %brutal_kill,
+ type => supervisor,
+ modules => [Module]
+ }
+ || Module <- [sshd_sup,
+ sshc_sup]
+ ],
+ {ok, {SupFlags,ChildSpecs}}.
diff --git a/lib/ssh/src/ssh_system_sup.erl b/lib/ssh/src/ssh_system_sup.erl
index e97ac7b01a..e70abf59c2 100644
--- a/lib/ssh/src/ssh_system_sup.erl
+++ b/lib/ssh/src/ssh_system_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@
%%
%%----------------------------------------------------------------------
%% Purpose: The ssh server instance supervisor, an instans of this supervisor
-%% exists for every ip-address and port combination, hangs under
+%% exists for every ip-address and port combination, hangs under
%% sshd_sup.
%%----------------------------------------------------------------------
@@ -31,64 +31,103 @@
-include("ssh.hrl").
--export([start_link/1, stop_listener/1,
+-export([start_link/4, stop_listener/1,
stop_listener/3, stop_system/1,
stop_system/3, system_supervisor/3,
- subsystem_supervisor/1, channel_supervisor/1,
- connection_supervisor/1,
- acceptor_supervisor/1, start_subsystem/2, restart_subsystem/3,
- restart_acceptor/3, stop_subsystem/2]).
+ subsystem_supervisor/1, channel_supervisor/1,
+ connection_supervisor/1,
+ acceptor_supervisor/1, start_subsystem/6,
+ stop_subsystem/2]).
%% Supervisor callback
-export([init/1]).
%%%=========================================================================
-%%% Internal API
+%%% API
%%%=========================================================================
-start_link(ServerOpts) ->
- Address = proplists:get_value(address, ServerOpts),
- Port = proplists:get_value(port, ServerOpts),
- Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+start_link(Address, Port, Profile, Options) ->
Name = make_name(Address, Port, Profile),
- supervisor:start_link({local, Name}, ?MODULE, [ServerOpts]).
+ supervisor:start_link({local, Name}, ?MODULE, [Address, Port, Profile, Options]).
-stop_listener(SysSup) ->
- stop_acceptor(SysSup).
+%%%=========================================================================
+%%% Supervisor callback
+%%%=========================================================================
+init([Address, Port, Profile, Options]) ->
+ SupFlags = #{strategy => one_for_one,
+ intensity => 0,
+ period => 3600
+ },
+ ChildSpecs =
+ case ?GET_INTERNAL_OPT(connected_socket,Options,undefined) of
+ undefined ->
+ [#{id => id(ssh_acceptor_sup, Address, Port, Profile),
+ start => {ssh_acceptor_sup, start_link, [Address, Port, Profile, Options]},
+ restart => transient,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [ssh_acceptor_sup]
+ }];
+ _ ->
+ []
+ end,
+ {ok, {SupFlags,ChildSpecs}}.
+
+%%%=========================================================================
+%%% Service API
+%%%=========================================================================
+stop_listener(SystemSup) ->
+ {Name, AcceptorSup, _, _} = lookup(ssh_acceptor_sup, SystemSup),
+ case supervisor:terminate_child(AcceptorSup, Name) of
+ ok ->
+ supervisor:delete_child(AcceptorSup, Name);
+ Error ->
+ Error
+ end.
stop_listener(Address, Port, Profile) ->
- Name = make_name(Address, Port, Profile),
- stop_acceptor(whereis(Name)).
-
+ stop_listener(
+ system_supervisor(Address, Port, Profile)).
+
+
stop_system(SysSup) ->
- Name = sshd_sup:system_name(SysSup),
- spawn(fun() -> sshd_sup:stop_child(Name) end),
+ spawn(fun() -> sshd_sup:stop_child(SysSup) end),
ok.
-stop_system(Address, Port, Profile) ->
+stop_system(Address, Port, Profile) ->
spawn(fun() -> sshd_sup:stop_child(Address, Port, Profile) end),
ok.
+
system_supervisor(Address, Port, Profile) ->
Name = make_name(Address, Port, Profile),
whereis(Name).
subsystem_supervisor(SystemSup) ->
- ssh_subsystem_sup(supervisor:which_children(SystemSup)).
+ {_, Child, _, _} = lookup(ssh_subsystem_sup, SystemSup),
+ Child.
channel_supervisor(SystemSup) ->
- SubSysSup = ssh_subsystem_sup(supervisor:which_children(SystemSup)),
- ssh_subsystem_sup:channel_supervisor(SubSysSup).
+ ssh_subsystem_sup:channel_supervisor(
+ subsystem_supervisor(SystemSup)).
connection_supervisor(SystemSup) ->
- SubSysSup = ssh_subsystem_sup(supervisor:which_children(SystemSup)),
- ssh_subsystem_sup:connection_supervisor(SubSysSup).
+ ssh_subsystem_sup:connection_supervisor(
+ subsystem_supervisor(SystemSup)).
acceptor_supervisor(SystemSup) ->
- ssh_acceptor_sup(supervisor:which_children(SystemSup)).
+ {_, Child, _, _} = lookup(ssh_acceptor_sup, SystemSup),
+ Child.
-start_subsystem(SystemSup, Options) ->
- Spec = ssh_subsystem_child_spec(Options),
- supervisor:start_child(SystemSup, Spec).
+
+start_subsystem(SystemSup, Role, Address, Port, Profile, Options) ->
+ SubsystemSpec =
+ #{id => make_ref(),
+ start => {ssh_subsystem_sup, start_link, [Role, Address, Port, Profile, Options]},
+ restart => temporary,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [ssh_subsystem_sup]},
+ supervisor:start_child(SystemSup, SubsystemSpec).
stop_subsystem(SystemSup, SubSys) ->
case catch lists:keyfind(SubSys, 2, supervisor:which_children(SystemSup)) of
@@ -106,100 +145,21 @@ stop_subsystem(SystemSup, SubSys) ->
ok
end.
-
-restart_subsystem(Address, Port, Profile) ->
- SysSupName = make_name(Address, Port, Profile),
- SubSysName = id(ssh_subsystem_sup, Address, Port, Profile),
- case supervisor:terminate_child(SysSupName, SubSysName) of
- ok ->
- supervisor:restart_child(SysSupName, SubSysName);
- Error ->
- Error
- end.
-
-restart_acceptor(Address, Port, Profile) ->
- SysSupName = make_name(Address, Port, Profile),
- AcceptorName = id(ssh_acceptor_sup, Address, Port, Profile),
- supervisor:restart_child(SysSupName, AcceptorName).
-
-%%%=========================================================================
-%%% Supervisor callback
-%%%=========================================================================
--spec init( [term()] ) -> {ok,{supervisor:sup_flags(),[supervisor:child_spec()]}} | ignore .
-
-init([ServerOpts]) ->
- RestartStrategy = one_for_one,
- MaxR = 0,
- MaxT = 3600,
- Children = case proplists:get_value(asocket,ServerOpts) of
- undefined -> child_specs(ServerOpts);
- _ -> []
- end,
- {ok, {{RestartStrategy, MaxR, MaxT}, Children}}.
-
%%%=========================================================================
%%% Internal functions
%%%=========================================================================
-child_specs(ServerOpts) ->
- [ssh_acceptor_child_spec(ServerOpts)].
-
-ssh_acceptor_child_spec(ServerOpts) ->
- Address = proplists:get_value(address, ServerOpts),
- Port = proplists:get_value(port, ServerOpts),
- Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
- Name = id(ssh_acceptor_sup, Address, Port, Profile),
- StartFunc = {ssh_acceptor_sup, start_link, [ServerOpts]},
- Restart = transient,
- Shutdown = infinity,
- Modules = [ssh_acceptor_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
-ssh_subsystem_child_spec(ServerOpts) ->
- Name = make_ref(),
- StartFunc = {ssh_subsystem_sup, start_link, [ServerOpts]},
- Restart = temporary,
- Shutdown = infinity,
- Modules = [ssh_subsystem_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
-
id(Sup, Address, Port, Profile) ->
- case is_list(Address) of
- true ->
- {Sup, any, Port, Profile};
- false ->
- {Sup, Address, Port, Profile}
- end.
+ {Sup, Address, Port, Profile}.
make_name(Address, Port, Profile) ->
- case is_list(Address) of
- true ->
- list_to_atom(lists:flatten(io_lib:format("ssh_system_~p_~p_~p_sup",
- [any, Port, Profile])));
- false ->
- list_to_atom(lists:flatten(io_lib:format("ssh_system_~p_~p_~p_sup",
- [Address, Port, Profile])))
- end.
+ list_to_atom(lists:flatten(io_lib:format("ssh_system_~s_~p_~p_sup", [fmt_host(Address), Port, Profile]))).
-ssh_subsystem_sup([{_, Child, _, [ssh_subsystem_sup]} | _]) ->
- Child;
-ssh_subsystem_sup([_ | Rest]) ->
- ssh_subsystem_sup(Rest).
+fmt_host(IP) when is_tuple(IP) -> inet:ntoa(IP);
+fmt_host(A) when is_atom(A) -> A;
+fmt_host(S) when is_list(S) -> S.
-ssh_acceptor_sup([{_, Child, _, [ssh_acceptor_sup]} | _]) ->
- Child;
-ssh_acceptor_sup([_ | Rest]) ->
- ssh_acceptor_sup(Rest).
-stop_acceptor(Sup) ->
- [{Name, AcceptorSup}] =
- [{SupName, ASup} || {SupName, ASup, _, [ssh_acceptor_sup]} <-
- supervisor:which_children(Sup)],
- case supervisor:terminate_child(AcceptorSup, Name) of
- ok ->
- supervisor:delete_child(AcceptorSup, Name);
- Error ->
- Error
- end.
+lookup(SupModule, SystemSup) ->
+ lists:keyfind([SupModule], 4,
+ supervisor:which_children(SystemSup)).
+
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 7cb3b75ac0..412f5de9de 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -38,15 +38,18 @@
handle_hello_version/1,
key_exchange_init_msg/1,
key_init/3, new_keys_message/1,
+ ext_info_message/1,
handle_kexinit_msg/3, handle_kexdh_init/2,
handle_kex_dh_gex_group/2, handle_kex_dh_gex_init/2, handle_kex_dh_gex_reply/2,
handle_new_keys/2, handle_kex_dh_gex_request/2,
handle_kexdh_reply/2,
handle_kex_ecdh_init/2,
handle_kex_ecdh_reply/2,
+ parallell_gen_key/1,
extract_public_key/1,
ssh_packet/2, pack/2,
- sign/3, verify/4]).
+ valid_key_sha_alg/2,
+ sha/1, sign/3, verify/4]).
%%% For test suites
-export([pack/3]).
@@ -78,6 +81,10 @@ default_algorithms() -> [{K,default_algorithms(K)} || K <- algo_classes()].
algo_classes() -> [kex, public_key, cipher, mac, compression].
+default_algorithms(kex) ->
+ supported_algorithms(kex, [
+ 'diffie-hellman-group1-sha1' % Gone in OpenSSH 7.3.p1
+ ]);
default_algorithms(cipher) ->
supported_algorithms(cipher, same(['AEAD_AES_128_GCM',
@@ -85,6 +92,7 @@ default_algorithms(cipher) ->
default_algorithms(mac) ->
supported_algorithms(mac, same(['AEAD_AES_128_GCM',
'AEAD_AES_256_GCM']));
+
default_algorithms(Alg) ->
supported_algorithms(Alg, []).
@@ -94,34 +102,41 @@ supported_algorithms() -> [{K,supported_algorithms(K)} || K <- algo_classes()].
supported_algorithms(kex) ->
select_crypto_supported(
[
- {'ecdh-sha2-nistp256', [{public_keys,ecdh}, {ec_curve,secp256r1}, {hashs,sha256}]},
{'ecdh-sha2-nistp384', [{public_keys,ecdh}, {ec_curve,secp384r1}, {hashs,sha384}]},
- {'diffie-hellman-group14-sha1', [{public_keys,dh}, {hashs,sha}]},
+ {'ecdh-sha2-nistp521', [{public_keys,ecdh}, {ec_curve,secp521r1}, {hashs,sha512}]},
+ {'ecdh-sha2-nistp256', [{public_keys,ecdh}, {ec_curve,secp256r1}, {hashs,sha256}]},
{'diffie-hellman-group-exchange-sha256', [{public_keys,dh}, {hashs,sha256}]},
+ {'diffie-hellman-group16-sha512', [{public_keys,dh}, {hashs,sha512}]}, % In OpenSSH 7.3.p1
+ {'diffie-hellman-group18-sha512', [{public_keys,dh}, {hashs,sha512}]}, % In OpenSSH 7.3.p1
+ {'diffie-hellman-group14-sha256', [{public_keys,dh}, {hashs,sha256}]}, % In OpenSSH 7.3.p1
+ {'diffie-hellman-group14-sha1', [{public_keys,dh}, {hashs,sha}]},
{'diffie-hellman-group-exchange-sha1', [{public_keys,dh}, {hashs,sha}]},
- {'ecdh-sha2-nistp521', [{public_keys,ecdh}, {ec_curve,secp521r1}, {hashs,sha512}]},
{'diffie-hellman-group1-sha1', [{public_keys,dh}, {hashs,sha}]}
]);
supported_algorithms(public_key) ->
select_crypto_supported(
- [{'ecdsa-sha2-nistp256', [{public_keys,ecdsa}, {hashs,sha256}, {ec_curve,secp256r1}]},
+ [
{'ecdsa-sha2-nistp384', [{public_keys,ecdsa}, {hashs,sha384}, {ec_curve,secp384r1}]},
{'ecdsa-sha2-nistp521', [{public_keys,ecdsa}, {hashs,sha512}, {ec_curve,secp521r1}]},
+ {'ecdsa-sha2-nistp256', [{public_keys,ecdsa}, {hashs,sha256}, {ec_curve,secp256r1}]},
{'ssh-rsa', [{public_keys,rsa}, {hashs,sha} ]},
- {'ssh-dss', [{public_keys,dss}, {hashs,sha} ]}
+ {'rsa-sha2-256', [{public_keys,rsa}, {hashs,sha256} ]},
+ {'rsa-sha2-512', [{public_keys,rsa}, {hashs,sha512} ]},
+ {'ssh-dss', [{public_keys,dss}, {hashs,sha} ]} % Gone in OpenSSH 7.3.p1
]);
supported_algorithms(cipher) ->
same(
select_crypto_supported(
- [{'aes256-ctr', [{ciphers,{aes_ctr,256}}]},
- {'aes192-ctr', [{ciphers,{aes_ctr,192}}]},
- {'aes128-ctr', [{ciphers,{aes_ctr,128}}]},
- {'aes128-cbc', [{ciphers,aes_cbc128}]},
+ [
+ {'[email protected]', [{ciphers,{aes_gcm,256}}]},
+ {'aes256-ctr', [{ciphers,{aes_ctr,256}}]},
+ {'aes192-ctr', [{ciphers,{aes_ctr,192}}]},
{'[email protected]', [{ciphers,{aes_gcm,128}}]},
- {'[email protected]', [{ciphers,{aes_gcm,256}}]},
- {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
+ {'aes128-ctr', [{ciphers,{aes_ctr,128}}]},
{'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]},
+ {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
+ {'aes128-cbc', [{ciphers,aes_cbc128}]},
{'3des-cbc', [{ciphers,des3_cbc}]}
]
));
@@ -143,14 +158,14 @@ supported_algorithms(compression) ->
%%%----------------------------------------------------------------------------
versions(client, Options)->
- Vsn = proplists:get_value(vsn, Options, ?DEFAULT_CLIENT_VERSION),
+ Vsn = ?GET_INTERNAL_OPT(vsn, Options, ?DEFAULT_CLIENT_VERSION),
{Vsn, format_version(Vsn, software_version(Options))};
versions(server, Options) ->
- Vsn = proplists:get_value(vsn, Options, ?DEFAULT_SERVER_VERSION),
+ Vsn = ?GET_INTERNAL_OPT(vsn, Options, ?DEFAULT_SERVER_VERSION),
{Vsn, format_version(Vsn, software_version(Options))}.
software_version(Options) ->
- case proplists:get_value(id_string, Options) of
+ case ?GET_OPT(id_string, Options) of
undefined ->
"Erlang"++ssh_vsn();
{random,Nlo,Nup} ->
@@ -161,7 +176,7 @@ software_version(Options) ->
ssh_vsn() ->
try {ok,L} = application:get_all_key(ssh),
- proplists:get_value(vsn,L,"")
+ proplists:get_value(vsn, L, "")
of
"" -> "";
VSN when is_list(VSN) -> "/" ++ VSN;
@@ -171,7 +186,7 @@ ssh_vsn() ->
end.
random_id(Nlo, Nup) ->
- [crypto:rand_uniform($a,$z+1) || _<- lists:duplicate(crypto:rand_uniform(Nlo,Nup+1),x) ].
+ [$a + rand:uniform($z-$a+1) - 1 || _<- lists:duplicate(Nlo + rand:uniform(Nup-Nlo+1) - 1, x)].
hello_version_msg(Data) ->
[Data,"\r\n"].
@@ -190,9 +205,6 @@ is_valid_mac(Mac, Data, #ssh{recv_mac = Algorithm,
recv_mac_key = Key, recv_sequence = SeqNum}) ->
Mac == mac(Algorithm, Key, SeqNum, Data).
-yes_no(Ssh, Prompt) ->
- (Ssh#ssh.io_cb):yes_no(Prompt, Ssh).
-
format_version({Major,Minor}, SoftwareVersion) ->
"SSH-" ++ integer_to_list(Major) ++ "." ++
integer_to_list(Minor) ++ "-" ++ SoftwareVersion.
@@ -222,14 +234,8 @@ key_exchange_init_msg(Ssh0) ->
kex_init(#ssh{role = Role, opts = Opts, available_host_keys = HostKeyAlgs}) ->
Random = ssh_bits:random(16),
- PrefAlgs =
- case proplists:get_value(preferred_algorithms,Opts) of
- undefined ->
- default_algorithms();
- Algs0 ->
- Algs0
- end,
- kexinit_message(Role, Random, PrefAlgs, HostKeyAlgs).
+ PrefAlgs = ?GET_OPT(preferred_algorithms, Opts),
+ kexinit_message(Role, Random, PrefAlgs, HostKeyAlgs, Opts).
key_init(client, Ssh, Value) ->
Ssh#ssh{c_keyinit = Value};
@@ -237,10 +243,11 @@ key_init(server, Ssh, Value) ->
Ssh#ssh{s_keyinit = Value}.
-kexinit_message(_Role, Random, Algs, HostKeyAlgs) ->
+kexinit_message(Role, Random, Algs, HostKeyAlgs, Opts) ->
#ssh_msg_kexinit{
cookie = Random,
- kex_algorithms = to_strings( get_algs(kex,Algs) ),
+ kex_algorithms = to_strings( get_algs(kex,Algs) )
+ ++ kex_ext_info(Role,Opts),
server_host_key_algorithms = HostKeyAlgs,
encryption_algorithms_client_to_server = c2s(cipher,Algs),
encryption_algorithms_server_to_client = s2c(cipher,Algs),
@@ -262,71 +269,92 @@ get_algs(Key, Algs) -> proplists:get_value(Key, Algs, default_algorithms(Key)).
to_strings(L) -> lists:map(fun erlang:atom_to_list/1, L).
new_keys_message(Ssh0) ->
- {SshPacket, Ssh} =
- ssh_packet(#ssh_msg_newkeys{}, Ssh0),
+ {SshPacket, Ssh1} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
+ Ssh = install_alg(snd, Ssh1),
{ok, SshPacket, Ssh}.
handle_kexinit_msg(#ssh_msg_kexinit{} = CounterPart, #ssh_msg_kexinit{} = Own,
- #ssh{role = client} = Ssh0) ->
- {ok, Algoritms} = select_algorithm(client, Own, CounterPart),
- case verify_algorithm(Algoritms) of
- true ->
- key_exchange_first_msg(Algoritms#alg.kex,
- Ssh0#ssh{algorithms = Algoritms});
- _ ->
- %% TODO: Correct code?
- ssh_connection_handler:disconnect(
- #ssh_msg_disconnect{code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- description = "Selection of key exchange algorithm failed"
- })
+ #ssh{role = client} = Ssh) ->
+ try
+ {ok, Algorithms} = select_algorithm(client, Own, CounterPart, Ssh#ssh.opts),
+ true = verify_algorithm(Algorithms),
+ Algorithms
+ of
+ Algos ->
+ key_exchange_first_msg(Algos#alg.kex,
+ Ssh#ssh{algorithms = Algos})
+ catch
+ _:_ ->
+ ssh_connection_handler:disconnect(
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Selection of key exchange algorithm failed"})
end;
handle_kexinit_msg(#ssh_msg_kexinit{} = CounterPart, #ssh_msg_kexinit{} = Own,
- #ssh{role = server} = Ssh) ->
- {ok, Algoritms} = select_algorithm(server, CounterPart, Own),
- case verify_algorithm(Algoritms) of
- true ->
- {ok, Ssh#ssh{algorithms = Algoritms}};
- _ ->
- ssh_connection_handler:disconnect(
- #ssh_msg_disconnect{code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- description = "Selection of key exchange algorithm failed"
- })
+ #ssh{role = server} = Ssh) ->
+ try
+ {ok, Algorithms} = select_algorithm(server, CounterPart, Own, Ssh#ssh.opts),
+ true = verify_algorithm(Algorithms),
+ Algorithms
+ of
+ Algos ->
+ {ok, Ssh#ssh{algorithms = Algos}}
+ catch
+ _:_ ->
+ ssh_connection_handler:disconnect(
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Selection of key exchange algorithm failed"})
end.
-%% TODO: diffie-hellman-group14-sha1 should also be supported.
-%% Maybe check more things ...
-
-verify_algorithm(#alg{kex = undefined}) -> false;
-verify_algorithm(#alg{hkey = undefined}) -> false;
-verify_algorithm(#alg{send_mac = undefined}) -> false;
-verify_algorithm(#alg{recv_mac = undefined}) -> false;
-verify_algorithm(#alg{encrypt = undefined}) -> false;
-verify_algorithm(#alg{decrypt = undefined}) -> false;
-verify_algorithm(#alg{compress = undefined}) -> false;
-verify_algorithm(#alg{decompress = undefined}) -> false;
-verify_algorithm(#alg{kex = Kex}) -> lists:member(Kex, supported_algorithms(kex)).
+verify_algorithm(#alg{kex = undefined}) -> {false, "kex"};
+verify_algorithm(#alg{hkey = undefined}) -> {false, "hkey"};
+verify_algorithm(#alg{send_mac = undefined}) -> {false, "send_mac"};
+verify_algorithm(#alg{recv_mac = undefined}) -> {false, "recv_mac"};
+verify_algorithm(#alg{encrypt = undefined}) -> {false, "encrypt"};
+verify_algorithm(#alg{decrypt = undefined}) -> {false, "decrypt"};
+verify_algorithm(#alg{compress = undefined}) -> {false, "compress"};
+verify_algorithm(#alg{decompress = undefined}) -> {false, "decompress"};
+verify_algorithm(#alg{kex = Kex}) ->
+ %% This also catches the error if 'ext-info-s' or 'ext-info-c' is selected.
+ %% (draft-ietf-curdle-ssh-ext-info-04 2.2)
+ case lists:member(Kex, supported_algorithms(kex)) of
+ true -> true;
+ false -> {false, "kex"}
+ end.
%%%----------------------------------------------------------------
%%%
%%% Key exchange initialization
%%%
key_exchange_first_msg(Kex, Ssh0) when Kex == 'diffie-hellman-group1-sha1' ;
- Kex == 'diffie-hellman-group14-sha1' ->
+ Kex == 'diffie-hellman-group14-sha1' ;
+ Kex == 'diffie-hellman-group14-sha256' ;
+ Kex == 'diffie-hellman-group16-sha512' ;
+ Kex == 'diffie-hellman-group18-sha512'
+ ->
{G, P} = dh_group(Kex),
- {Public, Private} = generate_key(dh, [P,G]),
+ Sz = dh_bits(Ssh0#ssh.algorithms),
+ {Public, Private} = generate_key(dh, [P,G,2*Sz]),
{SshPacket, Ssh1} = ssh_packet(#ssh_msg_kexdh_init{e = Public}, Ssh0),
{ok, SshPacket,
Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}}}};
key_exchange_first_msg(Kex, Ssh0=#ssh{opts=Opts}) when Kex == 'diffie-hellman-group-exchange-sha1' ;
Kex == 'diffie-hellman-group-exchange-sha256' ->
- {Min,NBits,Max} =
- proplists:get_value(dh_gex_limits, Opts, {?DEFAULT_DH_GROUP_MIN,
- ?DEFAULT_DH_GROUP_NBITS,
- ?DEFAULT_DH_GROUP_MAX}),
+ {Min,NBits0,Max} = ?GET_OPT(dh_gex_limits, Opts),
+ DhBits = dh_bits(Ssh0#ssh.algorithms),
+ NBits1 =
+ %% NIST Special Publication 800-57 Part 1 Revision 4: Recommendation for Key Management
+ if
+ DhBits =< 112 -> 2048;
+ DhBits =< 128 -> 3072;
+ DhBits =< 192 -> 7680;
+ true -> 8192
+ end,
+ NBits = min(max(max(NBits0,NBits1),Min), Max),
+
{SshPacket, Ssh1} =
ssh_packet(#ssh_msg_kex_dh_gex_request{min = Min,
n = NBits,
@@ -348,26 +376,31 @@ key_exchange_first_msg(Kex, Ssh0) when Kex == 'ecdh-sha2-nistp256' ;
%%%
%%% diffie-hellman-group1-sha1
%%% diffie-hellman-group14-sha1
+%%% diffie-hellman-group14-sha256
+%%% diffie-hellman-group16-sha512
+%%% diffie-hellman-group18-sha512
%%%
handle_kexdh_init(#ssh_msg_kexdh_init{e = E},
- Ssh0 = #ssh{algorithms = #alg{kex=Kex}}) ->
+ Ssh0 = #ssh{algorithms = #alg{kex=Kex,
+ hkey=SignAlg} = Algs}) ->
%% server
{G, P} = dh_group(Kex),
if
1=<E, E=<(P-1) ->
- {Public, Private} = generate_key(dh, [P,G]),
+ Sz = dh_bits(Algs),
+ {Public, Private} = generate_key(dh, [P,G,2*Sz]),
K = compute_key(dh, E, Private, [P,G]),
- MyPrivHostKey = get_host_key(Ssh0),
+ MyPrivHostKey = get_host_key(Ssh0, SignAlg),
MyPubHostKey = extract_public_key(MyPrivHostKey),
- H = kex_h(Ssh0, MyPubHostKey, E, Public, K),
- H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
+ H = kex_hash(Ssh0, MyPubHostKey, SignAlg, sha(Kex), {E,Public,K}),
+ H_SIG = sign(H, sha(SignAlg), MyPrivHostKey),
{SshPacket, Ssh1} =
- ssh_packet(#ssh_msg_kexdh_reply{public_host_key = MyPubHostKey,
+ ssh_packet(#ssh_msg_kexdh_reply{public_host_key = {MyPubHostKey,SignAlg},
f = Public,
h_sig = H_SIG
}, Ssh0),
{ok, SshPacket, Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}},
- shared_secret = K,
+ shared_secret = ssh_bits:mpint(K),
exchanged_hash = H,
session_id = sid(Ssh1, H)}};
@@ -383,19 +416,20 @@ handle_kexdh_init(#ssh_msg_kexdh_init{e = E},
handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = PeerPubHostKey,
f = F,
h_sig = H_SIG},
- #ssh{keyex_key = {{Private, Public}, {G, P}}} = Ssh0) ->
+ #ssh{keyex_key = {{Private, Public}, {G, P}},
+ algorithms = #alg{kex=Kex,
+ hkey=SignAlg}} = Ssh0) ->
%% client
if
1=<F, F=<(P-1)->
K = compute_key(dh, F, Private, [P,G]),
- H = kex_h(Ssh0, PeerPubHostKey, Public, F, K),
-
+ H = kex_hash(Ssh0, PeerPubHostKey, SignAlg, sha(Kex), {Public,F,K}),
case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
ok ->
{SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
- {ok, SshPacket, Ssh#ssh{shared_secret = K,
- exchanged_hash = H,
- session_id = sid(Ssh, H)}};
+ {ok, SshPacket, install_alg(snd, Ssh#ssh{shared_secret = ssh_bits:mpint(K),
+ exchanged_hash = H,
+ session_id = sid(Ssh, H)})};
Error ->
ssh_connection_handler:disconnect(
#ssh_msg_disconnect{
@@ -425,14 +459,13 @@ handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = Min0,
%% server
{Min, Max} = adjust_gex_min_max(Min0, Max0, Opts),
case public_key:dh_gex_group(Min, NBits, Max,
- proplists:get_value(dh_gex_groups,Opts)) of
- {ok, {_Sz, {G,P}}} ->
- {Public, Private} = generate_key(dh, [P,G]),
+ ?GET_OPT(dh_gex_groups,Opts)) of
+ {ok, {_, {G,P}}} ->
{SshPacket, Ssh} =
ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
{ok, SshPacket,
- Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
- keyex_info = {Min, Max, NBits}
+ Ssh#ssh{keyex_key = {x, {G, P}},
+ keyex_info = {Min0, Max0, NBits}
}};
{error,_} ->
ssh_connection_handler:disconnect(
@@ -449,7 +482,7 @@ handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request_old{n = NBits},
%% This message was in the draft-00 of rfc4419
%% (https://tools.ietf.org/html/draft-ietf-secsh-dh-group-exchange-00)
%% In later drafts and the rfc is "is used for backward compatibility".
- %% Unfortunatly the rfc does not specify how to treat the parameter n
+ %% Unfortunately the rfc does not specify how to treat the parameter n
%% if there is no group of that modulus length :(
%% The draft-00 however specifies that n is the "... number of bits
%% the subgroup should have at least".
@@ -460,14 +493,13 @@ handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request_old{n = NBits},
Max0 = 8192,
{Min, Max} = adjust_gex_min_max(Min0, Max0, Opts),
case public_key:dh_gex_group(Min, NBits, Max,
- proplists:get_value(dh_gex_groups,Opts)) of
- {ok, {_Sz, {G,P}}} ->
- {Public, Private} = generate_key(dh, [P,G]),
+ ?GET_OPT(dh_gex_groups,Opts)) of
+ {ok, {_, {G,P}}} ->
{SshPacket, Ssh} =
ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
{ok, SshPacket,
- Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
- keyex_info = {-1, -1, NBits} % flag for kex_h hash calc
+ Ssh#ssh{keyex_key = {x, {G, P}},
+ keyex_info = {-1, -1, NBits} % flag for kex_hash calc
}};
{error,_} ->
ssh_connection_handler:disconnect(
@@ -486,28 +518,25 @@ handle_kex_dh_gex_request(_, _) ->
adjust_gex_min_max(Min0, Max0, Opts) ->
- case proplists:get_value(dh_gex_limits, Opts) of
- undefined ->
- {Min0, Max0};
- {Min1, Max1} ->
- Min2 = max(Min0, Min1),
- Max2 = min(Max0, Max1),
- if
- Min2 =< Max2 ->
- {Min2, Max2};
- Max2 < Min2 ->
- ssh_connection_handler:disconnect(
- #ssh_msg_disconnect{
- code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "No possible diffie-hellman-group-exchange group possible"
- })
- end
+ {Min1, Max1} = ?GET_OPT(dh_gex_limits, Opts),
+ Min2 = max(Min0, Min1),
+ Max2 = min(Max0, Max1),
+ if
+ Min2 =< Max2 ->
+ {Min2, Max2};
+ Max2 < Min2 ->
+ ssh_connection_handler:disconnect(
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group possible"
+ })
end.
handle_kex_dh_gex_group(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0) ->
%% client
- {Public, Private} = generate_key(dh, [P,G]),
+ Sz = dh_bits(Ssh0#ssh.algorithms),
+ {Public, Private} = generate_key(dh, [P,G,2*Sz]),
{SshPacket, Ssh1} =
ssh_packet(#ssh_msg_kex_dh_gex_init{e = Public}, Ssh0), % Pub = G^Priv mod P (def)
@@ -516,23 +545,24 @@ handle_kex_dh_gex_group(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0) ->
handle_kex_dh_gex_init(#ssh_msg_kex_dh_gex_init{e = E},
#ssh{keyex_key = {{Private, Public}, {G, P}},
- keyex_info = {Min, Max, NBits}} =
- Ssh0) ->
+ keyex_info = {Min, Max, NBits},
+ algorithms = #alg{kex=Kex,
+ hkey=SignAlg}} = Ssh0) ->
%% server
if
1=<E, E=<(P-1) ->
K = compute_key(dh, E, Private, [P,G]),
if
1<K, K<(P-1) ->
- MyPrivHostKey = get_host_key(Ssh0),
+ MyPrivHostKey = get_host_key(Ssh0, SignAlg),
MyPubHostKey = extract_public_key(MyPrivHostKey),
- H = kex_h(Ssh0, MyPubHostKey, Min, NBits, Max, P, G, E, Public, K),
- H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
+ H = kex_hash(Ssh0, MyPubHostKey, SignAlg, sha(Kex), {Min,NBits,Max,P,G,E,Public,K}),
+ H_SIG = sign(H, sha(SignAlg), MyPrivHostKey),
{SshPacket, Ssh} =
- ssh_packet(#ssh_msg_kex_dh_gex_reply{public_host_key = MyPubHostKey,
+ ssh_packet(#ssh_msg_kex_dh_gex_reply{public_host_key = {MyPubHostKey,SignAlg},
f = Public,
h_sig = H_SIG}, Ssh0),
- {ok, SshPacket, Ssh#ssh{shared_secret = K,
+ {ok, SshPacket, Ssh#ssh{shared_secret = ssh_bits:mpint(K),
exchanged_hash = H,
session_id = sid(Ssh, H)
}};
@@ -555,7 +585,9 @@ handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = PeerPubHostK
f = F,
h_sig = H_SIG},
#ssh{keyex_key = {{Private, Public}, {G, P}},
- keyex_info = {Min, Max, NBits}} =
+ keyex_info = {Min, Max, NBits},
+ algorithms = #alg{kex=Kex,
+ hkey=SignAlg}} =
Ssh0) ->
%% client
if
@@ -563,14 +595,13 @@ handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = PeerPubHostK
K = compute_key(dh, F, Private, [P,G]),
if
1<K, K<(P-1) ->
- H = kex_h(Ssh0, PeerPubHostKey, Min, NBits, Max, P, G, Public, F, K),
-
+ H = kex_hash(Ssh0, PeerPubHostKey, SignAlg, sha(Kex), {Min,NBits,Max,P,G,Public,F,K}),
case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
ok ->
{SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
- {ok, SshPacket, Ssh#ssh{shared_secret = K,
- exchanged_hash = H,
- session_id = sid(Ssh, H)}};
+ {ok, SshPacket, install_alg(snd, Ssh#ssh{shared_secret = ssh_bits:mpint(K),
+ exchanged_hash = H,
+ session_id = sid(Ssh, H)})};
_Error ->
ssh_connection_handler:disconnect(
#ssh_msg_disconnect{
@@ -600,7 +631,8 @@ handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = PeerPubHostK
%%% diffie-hellman-ecdh-sha2-*
%%%
handle_kex_ecdh_init(#ssh_msg_kex_ecdh_init{q_c = PeerPublic},
- Ssh0 = #ssh{algorithms = #alg{kex=Kex}}) ->
+ Ssh0 = #ssh{algorithms = #alg{kex=Kex,
+ hkey=SignAlg}}) ->
%% at server
Curve = ecdh_curve(Kex),
{MyPublic, MyPrivate} = generate_key(ecdh, Curve),
@@ -608,17 +640,17 @@ handle_kex_ecdh_init(#ssh_msg_kex_ecdh_init{q_c = PeerPublic},
compute_key(ecdh, PeerPublic, MyPrivate, Curve)
of
K ->
- MyPrivHostKey = get_host_key(Ssh0),
+ MyPrivHostKey = get_host_key(Ssh0, SignAlg),
MyPubHostKey = extract_public_key(MyPrivHostKey),
- H = kex_h(Ssh0, Curve, MyPubHostKey, PeerPublic, MyPublic, K),
- H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
+ H = kex_hash(Ssh0, MyPubHostKey, SignAlg, sha(Curve), {PeerPublic, MyPublic, K}),
+ H_SIG = sign(H, sha(SignAlg), MyPrivHostKey),
{SshPacket, Ssh1} =
- ssh_packet(#ssh_msg_kex_ecdh_reply{public_host_key = MyPubHostKey,
+ ssh_packet(#ssh_msg_kex_ecdh_reply{public_host_key = {MyPubHostKey,SignAlg},
q_s = MyPublic,
h_sig = H_SIG},
Ssh0),
{ok, SshPacket, Ssh1#ssh{keyex_key = {{MyPublic,MyPrivate},Curve},
- shared_secret = K,
+ shared_secret = ssh_bits:mpint(K),
exchanged_hash = H,
session_id = sid(Ssh1, H)}}
catch
@@ -633,20 +665,21 @@ handle_kex_ecdh_init(#ssh_msg_kex_ecdh_init{q_c = PeerPublic},
handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = PeerPubHostKey,
q_s = PeerPublic,
h_sig = H_SIG},
- #ssh{keyex_key = {{MyPublic,MyPrivate}, Curve}} = Ssh0
+ #ssh{keyex_key = {{MyPublic,MyPrivate}, Curve},
+ algorithms = #alg{hkey=SignAlg}} = Ssh0
) ->
%% at client
try
compute_key(ecdh, PeerPublic, MyPrivate, Curve)
of
K ->
- H = kex_h(Ssh0, Curve, PeerPubHostKey, MyPublic, PeerPublic, K),
+ H = kex_hash(Ssh0, PeerPubHostKey, SignAlg, sha(Curve), {MyPublic,PeerPublic,K}),
case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
ok ->
{SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
- {ok, SshPacket, Ssh#ssh{shared_secret = K,
- exchanged_hash = H,
- session_id = sid(Ssh, H)}};
+ {ok, SshPacket, install_alg(snd, Ssh#ssh{shared_secret = ssh_bits:mpint(K),
+ exchanged_hash = H,
+ session_id = sid(Ssh, H)})};
Error ->
ssh_connection_handler:disconnect(
#ssh_msg_disconnect{
@@ -666,7 +699,7 @@ handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = PeerPubHostKey,
%%%----------------------------------------------------------------
handle_new_keys(#ssh_msg_newkeys{}, Ssh0) ->
- try install_alg(Ssh0) of
+ try install_alg(rcv, Ssh0) of
#ssh{} = Ssh ->
{ok, Ssh}
catch
@@ -677,34 +710,63 @@ handle_new_keys(#ssh_msg_newkeys{}, Ssh0) ->
})
end.
+
+%%%----------------------------------------------------------------
+kex_ext_info(Role, Opts) ->
+ case ?GET_OPT(recv_ext_info,Opts) of
+ true when Role==client -> ["ext-info-c"];
+ true when Role==server -> ["ext-info-s"];
+ false -> []
+ end.
+
+ext_info_message(#ssh{role=client,
+ send_ext_info=true,
+ opts=Opts} = Ssh0) ->
+ %% Since no extension sent by the client is implemented, we add a fake one
+ %% to be able to test the framework.
+ %% Remove this when there is one and update ssh_protocol_SUITE whare it is used.
+ case proplists:get_value(ext_info_client, ?GET_OPT(tstflg,Opts)) of
+ true ->
+ Msg = #ssh_msg_ext_info{nr_extensions = 1,
+ data = [{"[email protected]", "Testing,PleaseIgnore"}]
+ },
+ {SshPacket, Ssh} = ssh_packet(Msg, Ssh0),
+ {ok, SshPacket, Ssh};
+ _ ->
+ {ok, "", Ssh0}
+ end;
+
+ext_info_message(#ssh{role=server,
+ send_ext_info=true,
+ opts = Opts} = Ssh0) ->
+ AlgsList = lists:map(fun erlang:atom_to_list/1,
+ proplists:get_value(public_key,
+ ?GET_OPT(preferred_algorithms, Opts))),
+ Msg = #ssh_msg_ext_info{nr_extensions = 1,
+ data = [{"server-sig-algs", string:join(AlgsList,",")}]
+ },
+ {SshPacket, Ssh} = ssh_packet(Msg, Ssh0),
+ {ok, SshPacket, Ssh};
+
+ext_info_message(Ssh0) ->
+ {ok, "", Ssh0}. % "" means: 'do not send'
+
+%%%----------------------------------------------------------------
%% select session id
-sid(#ssh{session_id = undefined}, H) ->
- H;
-sid(#ssh{session_id = Id}, _) ->
- Id.
+sid(#ssh{session_id = undefined}, H) -> H;
+sid(#ssh{session_id = Id}, _) -> Id.
%%
%% The host key should be read from storage
%%
-get_host_key(SSH) ->
- #ssh{key_cb = Mod, opts = Opts, algorithms = ALG} = SSH,
-
- case Mod:host_key(ALG#alg.hkey, Opts) of
- {ok, #'RSAPrivateKey'{} = Key} -> Key;
- {ok, #'DSAPrivateKey'{} = Key} -> Key;
- {ok, #'ECPrivateKey'{} = Key} -> Key;
- Result ->
- exit({error, {Result, unsupported_key_type}})
+get_host_key(SSH, SignAlg) ->
+ #ssh{key_cb = {KeyCb,KeyCbOpts}, opts = Opts} = SSH,
+ UserOpts = ?GET_OPT(user_options, Opts),
+ case KeyCb:host_key(SignAlg, [{key_cb_private,KeyCbOpts}|UserOpts]) of
+ {ok, PrivHostKey} -> PrivHostKey;
+ Result -> exit({error, {Result, unsupported_key_type}})
end.
-sign_host_key(_Ssh, PrivateKey, H) ->
- sign(H, sign_host_key_sha(PrivateKey), PrivateKey).
-
-sign_host_key_sha(#'ECPrivateKey'{parameters = {namedCurve,OID}}) -> sha(OID);
-sign_host_key_sha(#'RSAPrivateKey'{}) -> sha;
-sign_host_key_sha(#'DSAPrivateKey'{}) -> sha.
-
-
extract_public_key(#'RSAPrivateKey'{modulus = N, publicExponent = E}) ->
#'RSAPublicKey'{modulus = N, publicExponent = E};
extract_public_key(#'DSAPrivateKey'{y = Y, p = P, q = Q, g = G}) ->
@@ -714,45 +776,71 @@ extract_public_key(#'ECPrivateKey'{parameters = {namedCurve,OID},
{#'ECPoint'{point=Q}, {namedCurve,OID}}.
-verify_host_key(SSH, PublicKey, Digest, Signature) ->
- case verify(Digest, host_key_sha(PublicKey), Signature, PublicKey) of
- false ->
- {error, bad_signature};
- true ->
- known_host_key(SSH, PublicKey, public_algo(PublicKey))
+verify_host_key(#ssh{algorithms=Alg}=SSH, PublicKey, Digest, {AlgStr,Signature}) ->
+ case atom_to_list(Alg#alg.hkey) of
+ AlgStr ->
+ case verify(Digest, sha(Alg#alg.hkey), Signature, PublicKey) of
+ false ->
+ {error, bad_signature};
+ true ->
+ known_host_key(SSH, PublicKey, public_algo(PublicKey))
+ end;
+ _ ->
+ {error, bad_signature_name}
end.
-host_key_sha(#'RSAPublicKey'{}) -> sha;
-host_key_sha({_, #'Dss-Parms'{}}) -> sha;
-host_key_sha({#'ECPoint'{},{namedCurve,OID}}) -> sha(OID).
+accepted_host(Ssh, PeerName, Public, Opts) ->
+ case ?GET_OPT(silently_accept_hosts, Opts) of
+
+ %% Original option values; User question and no host key fingerprints known.
+ %% Keep the original question unchanged:
+ false -> yes == yes_no(Ssh, "New host " ++ PeerName ++ " accept");
+ true -> true;
+
+ %% Variant: User question but with host key fingerprint in the question:
+ {false,Alg} ->
+ HostKeyAlg = (Ssh#ssh.algorithms)#alg.hkey,
+ Prompt = io_lib:format("The authenticity of the host can't be established.~n"
+ "~s host key fingerprint is ~s.~n"
+ "New host ~p accept",
+ [fmt_hostkey(HostKeyAlg),
+ public_key:ssh_hostkey_fingerprint(Alg,Public),
+ PeerName]),
+ yes == yes_no(Ssh, Prompt);
+
+ %% Call-back alternatives: A user provided fun is called for the decision:
+ F when is_function(F,2) ->
+ true == (catch F(PeerName, public_key:ssh_hostkey_fingerprint(Public)));
+
+ {DigestAlg,F} when is_function(F,2) ->
+ true == (catch F(PeerName, public_key:ssh_hostkey_fingerprint(DigestAlg,Public)))
+
+ end.
-public_algo(#'RSAPublicKey'{}) -> 'ssh-rsa';
-public_algo({_, #'Dss-Parms'{}}) -> 'ssh-dss';
-public_algo({#'ECPoint'{},{namedCurve,OID}}) ->
- Curve = public_key:oid2ssh_curvename(OID),
- list_to_atom("ecdsa-sha2-" ++ binary_to_list(Curve)).
+yes_no(Ssh, Prompt) ->
+ (Ssh#ssh.io_cb):yes_no(Prompt, Ssh#ssh.opts).
-accepted_host(Ssh, PeerName, Opts) ->
- case proplists:get_value(silently_accept_hosts, Opts, false) of
- true ->
- yes;
- false ->
- yes_no(Ssh, "New host " ++ PeerName ++ " accept")
- end.
-known_host_key(#ssh{opts = Opts, key_cb = Mod, peer = Peer} = Ssh,
+fmt_hostkey('ssh-rsa') -> "RSA";
+fmt_hostkey('ssh-dss') -> "DSA";
+fmt_hostkey(A) when is_atom(A) -> fmt_hostkey(atom_to_list(A));
+fmt_hostkey("ecdsa"++_) -> "ECDSA";
+fmt_hostkey(X) -> X.
+
+
+known_host_key(#ssh{opts = Opts, key_cb = {KeyCb,KeyCbOpts}, peer = {PeerName,_}} = Ssh,
Public, Alg) ->
- PeerName = peer_name(Peer),
- case Mod:is_host_key(Public, PeerName, Alg, Opts) of
+ UserOpts = ?GET_OPT(user_options, Opts),
+ case KeyCb:is_host_key(Public, PeerName, Alg, [{key_cb_private,KeyCbOpts}|UserOpts]) of
true ->
ok;
false ->
- case accepted_host(Ssh, PeerName, Opts) of
- yes ->
- Mod:add_host_key(PeerName, Public, Opts);
- no ->
+ case accepted_host(Ssh, PeerName, Public, Opts) of
+ true ->
+ KeyCb:add_host_key(PeerName, Public, [{key_cb_private,KeyCbOpts}|UserOpts]);
+ false ->
{error, rejected}
end
end.
@@ -764,7 +852,7 @@ known_host_key(#ssh{opts = Opts, key_cb = Mod, peer = Peer} = Ssh,
%%
%% The first algorithm in each list MUST be the preferred (guessed)
%% algorithm. Each string MUST contain at least one algorithm name.
-select_algorithm(Role, Client, Server) ->
+select_algorithm(Role, Client, Server, Opts) ->
{Encrypt0, Decrypt0} = select_encrypt_decrypt(Role, Client, Server),
{SendMac0, RecvMac0} = select_send_recv_mac(Role, Client, Server),
@@ -789,17 +877,34 @@ select_algorithm(Role, Client, Server) ->
Kex = select(Client#ssh_msg_kexinit.kex_algorithms,
Server#ssh_msg_kexinit.kex_algorithms),
- Alg = #alg{kex = Kex,
- hkey = HK,
- encrypt = Encrypt,
- decrypt = Decrypt,
- send_mac = SendMac,
- recv_mac = RecvMac,
- compress = Compression,
- decompress = Decompression,
- c_lng = C_Lng,
- s_lng = S_Lng},
- {ok, Alg}.
+ SendExtInfo =
+ %% To send we must have that option enabled and ...
+ ?GET_OPT(send_ext_info,Opts) andalso
+ %% ... the peer must have told us to send:
+ case Role of
+ server -> lists:member("ext-info-c", Client#ssh_msg_kexinit.kex_algorithms);
+ client -> lists:member("ext-info-s", Server#ssh_msg_kexinit.kex_algorithms)
+ end,
+
+ RecvExtInfo =
+ %% The peer should not send unless told so by us (which is
+ %% guided by an option).
+ %% (However a malicious peer could send anyway, so we must be prepared)
+ ?GET_OPT(recv_ext_info,Opts),
+
+ {ok, #alg{kex = Kex,
+ hkey = HK,
+ encrypt = Encrypt,
+ decrypt = Decrypt,
+ send_mac = SendMac,
+ recv_mac = RecvMac,
+ compress = Compression,
+ decompress = Decompression,
+ c_lng = C_Lng,
+ s_lng = S_Lng,
+ send_ext_info = SendExtInfo,
+ recv_ext_info = RecvExtInfo
+ }}.
%%% It is an agreed problem with RFC 5674 that if the selection is
@@ -880,45 +985,66 @@ select_compression_decompression(server, Client, Server) ->
Server#ssh_msg_kexinit.compression_algorithms_server_to_client),
{Compression, Decompression}.
-install_alg(SSH) ->
- SSH1 = alg_final(SSH),
- SSH2 = alg_setup(SSH1),
- alg_init(SSH2).
+%% DIr = rcv | snd
+install_alg(Dir, SSH) ->
+ SSH1 = alg_final(Dir, SSH),
+ SSH2 = alg_setup(Dir, SSH1),
+ alg_init(Dir, SSH2).
-alg_setup(SSH) ->
+alg_setup(snd, SSH) ->
ALG = SSH#ssh.algorithms,
SSH#ssh{kex = ALG#alg.kex,
hkey = ALG#alg.hkey,
encrypt = ALG#alg.encrypt,
- decrypt = ALG#alg.decrypt,
send_mac = ALG#alg.send_mac,
send_mac_size = mac_digest_size(ALG#alg.send_mac),
+ compress = ALG#alg.compress,
+ c_lng = ALG#alg.c_lng,
+ s_lng = ALG#alg.s_lng,
+ send_ext_info = ALG#alg.send_ext_info,
+ recv_ext_info = ALG#alg.recv_ext_info
+ };
+
+alg_setup(rcv, SSH) ->
+ ALG = SSH#ssh.algorithms,
+ SSH#ssh{kex = ALG#alg.kex,
+ hkey = ALG#alg.hkey,
+ decrypt = ALG#alg.decrypt,
recv_mac = ALG#alg.recv_mac,
recv_mac_size = mac_digest_size(ALG#alg.recv_mac),
- compress = ALG#alg.compress,
decompress = ALG#alg.decompress,
c_lng = ALG#alg.c_lng,
s_lng = ALG#alg.s_lng,
- algorithms = undefined
+ send_ext_info = ALG#alg.send_ext_info,
+ recv_ext_info = ALG#alg.recv_ext_info
}.
-alg_init(SSH0) ->
+
+alg_init(snd, SSH0) ->
{ok,SSH1} = send_mac_init(SSH0),
- {ok,SSH2} = recv_mac_init(SSH1),
- {ok,SSH3} = encrypt_init(SSH2),
- {ok,SSH4} = decrypt_init(SSH3),
- {ok,SSH5} = compress_init(SSH4),
- {ok,SSH6} = decompress_init(SSH5),
- SSH6.
-
-alg_final(SSH0) ->
+ {ok,SSH2} = encrypt_init(SSH1),
+ {ok,SSH3} = compress_init(SSH2),
+ SSH3;
+
+alg_init(rcv, SSH0) ->
+ {ok,SSH1} = recv_mac_init(SSH0),
+ {ok,SSH2} = decrypt_init(SSH1),
+ {ok,SSH3} = decompress_init(SSH2),
+ SSH3.
+
+
+alg_final(snd, SSH0) ->
{ok,SSH1} = send_mac_final(SSH0),
- {ok,SSH2} = recv_mac_final(SSH1),
- {ok,SSH3} = encrypt_final(SSH2),
- {ok,SSH4} = decrypt_final(SSH3),
- {ok,SSH5} = compress_final(SSH4),
- {ok,SSH6} = decompress_final(SSH5),
- SSH6.
+ {ok,SSH2} = encrypt_final(SSH1),
+ {ok,SSH3} = compress_final(SSH2),
+ SSH3;
+
+alg_final(rcv, SSH0) ->
+ {ok,SSH1} = recv_mac_final(SSH0),
+ {ok,SSH2} = decrypt_final(SSH1),
+ {ok,SSH3} = decompress_final(SSH2),
+ SSH3.
+
select_all(CL, SL) when length(CL) + length(SL) < ?MAX_NUM_ALGORITHMS ->
A = CL -- SL, %% algortihms only used by client
@@ -993,7 +1119,7 @@ padding_length(Size, #ssh{encrypt_block_size = BlockSize,
end,
PadBlockSize = max(BlockSize,4),
MaxExtraBlocks = (max(RandomLengthPadding,MinPaddingLen) - MinPaddingLen) div PadBlockSize,
- ExtraPaddingLen = try crypto:rand_uniform(0,MaxExtraBlocks)*PadBlockSize
+ ExtraPaddingLen = try (rand:uniform(MaxExtraBlocks+1) - 1) * PadBlockSize
catch _:_ -> 0
end,
MinPaddingLen + ExtraPaddingLen.
@@ -1082,29 +1208,37 @@ payload(<<PacketLen:32, PaddingLen:8, PayloadAndPadding/binary>>) ->
<<Payload:PayloadLen/binary, _/binary>> = PayloadAndPadding,
Payload.
-sign(SigData, Hash, #'DSAPrivateKey'{} = Key) ->
- DerSignature = public_key:sign(SigData, Hash, Key),
+sign(SigData, HashAlg, #'DSAPrivateKey'{} = Key) ->
+ DerSignature = public_key:sign(SigData, HashAlg, Key),
#'Dss-Sig-Value'{r = R, s = S} = public_key:der_decode('Dss-Sig-Value', DerSignature),
<<R:160/big-unsigned-integer, S:160/big-unsigned-integer>>;
-sign(SigData, Hash, Key = #'ECPrivateKey'{}) ->
- DerEncodedSign = public_key:sign(SigData, Hash, Key),
+sign(SigData, HashAlg, Key = #'ECPrivateKey'{}) ->
+ DerEncodedSign = public_key:sign(SigData, HashAlg, Key),
#'ECDSA-Sig-Value'{r=R, s=S} = public_key:der_decode('ECDSA-Sig-Value', DerEncodedSign),
<<?Empint(R),?Empint(S)>>;
-sign(SigData, Hash, Key) ->
- public_key:sign(SigData, Hash, Key).
-
-verify(PlainText, Hash, Sig, {_, #'Dss-Parms'{}} = Key) ->
- <<R:160/big-unsigned-integer, S:160/big-unsigned-integer>> = Sig,
- Signature = public_key:der_encode('Dss-Sig-Value', #'Dss-Sig-Value'{r = R, s = S}),
- public_key:verify(PlainText, Hash, Signature, Key);
-verify(PlainText, Hash, Sig, {#'ECPoint'{},_} = Key) ->
- <<?UINT32(Rlen),R:Rlen/big-signed-integer-unit:8,
- ?UINT32(Slen),S:Slen/big-signed-integer-unit:8>> = Sig,
- Sval = #'ECDSA-Sig-Value'{r=R, s=S},
- DerEncodedSig = public_key:der_encode('ECDSA-Sig-Value',Sval),
- public_key:verify(PlainText, Hash, DerEncodedSig, Key);
-verify(PlainText, Hash, Sig, Key) ->
- public_key:verify(PlainText, Hash, Sig, Key).
+sign(SigData, HashAlg, Key) ->
+ public_key:sign(SigData, HashAlg, Key).
+
+verify(PlainText, HashAlg, Sig, {_, #'Dss-Parms'{}} = Key) ->
+ case Sig of
+ <<R:160/big-unsigned-integer, S:160/big-unsigned-integer>> ->
+ Signature = public_key:der_encode('Dss-Sig-Value', #'Dss-Sig-Value'{r = R, s = S}),
+ public_key:verify(PlainText, HashAlg, Signature, Key);
+ _ ->
+ false
+ end;
+verify(PlainText, HashAlg, Sig, {#'ECPoint'{},_} = Key) ->
+ case Sig of
+ <<?UINT32(Rlen),R:Rlen/big-signed-integer-unit:8,
+ ?UINT32(Slen),S:Slen/big-signed-integer-unit:8>> ->
+ Sval = #'ECDSA-Sig-Value'{r=R, s=S},
+ DerEncodedSig = public_key:der_encode('ECDSA-Sig-Value',Sval),
+ public_key:verify(PlainText, HashAlg, DerEncodedSig, Key);
+ _ ->
+ false
+ end;
+verify(PlainText, HashAlg, Sig, Key) ->
+ public_key:verify(PlainText, HashAlg, Sig, Key).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1113,6 +1247,51 @@ verify(PlainText, Hash, Sig, Key) ->
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Unit: bytes
+
+-record(cipher_data, {
+ key_bytes,
+ iv_bytes,
+ block_bytes
+ }).
+
+%%% Start of a more parameterized crypto handling.
+cipher('AEAD_AES_128_GCM') ->
+ #cipher_data{key_bytes = 16,
+ iv_bytes = 12,
+ block_bytes = 16};
+
+cipher('AEAD_AES_256_GCM') ->
+ #cipher_data{key_bytes = 32,
+ iv_bytes = 12,
+ block_bytes = 16};
+
+cipher('3des-cbc') ->
+ #cipher_data{key_bytes = 24,
+ iv_bytes = 8,
+ block_bytes = 8};
+
+cipher('aes128-cbc') ->
+ #cipher_data{key_bytes = 16,
+ iv_bytes = 16,
+ block_bytes = 16};
+
+cipher('aes128-ctr') ->
+ #cipher_data{key_bytes = 16,
+ iv_bytes = 16,
+ block_bytes = 16};
+
+cipher('aes192-ctr') ->
+ #cipher_data{key_bytes = 24,
+ iv_bytes = 16,
+ block_bytes = 16};
+
+cipher('aes256-ctr') ->
+ #cipher_data{key_bytes = 32,
+ iv_bytes = 16,
+ block_bytes = 16}.
+
+
encrypt_init(#ssh{encrypt = none} = Ssh) ->
{ok, Ssh};
encrypt_init(#ssh{encrypt = 'AEAD_AES_128_GCM', role = client} = Ssh) ->
@@ -1493,11 +1672,11 @@ send_mac_init(SSH) ->
common ->
case SSH#ssh.role of
client ->
- KeySize = mac_key_size(SSH#ssh.send_mac),
+ KeySize = 8*mac_key_bytes(SSH#ssh.send_mac),
Key = hash(SSH, "E", KeySize),
{ok, SSH#ssh { send_mac_key = Key }};
server ->
- KeySize = mac_key_size(SSH#ssh.send_mac),
+ KeySize = 8*mac_key_bytes(SSH#ssh.send_mac),
Key = hash(SSH, "F", KeySize),
{ok, SSH#ssh { send_mac_key = Key }}
end;
@@ -1516,10 +1695,10 @@ recv_mac_init(SSH) ->
common ->
case SSH#ssh.role of
client ->
- Key = hash(SSH, "F", mac_key_size(SSH#ssh.recv_mac)),
+ Key = hash(SSH, "F", 8*mac_key_bytes(SSH#ssh.recv_mac)),
{ok, SSH#ssh { recv_mac_key = Key }};
server ->
- Key = hash(SSH, "E", mac_key_size(SSH#ssh.recv_mac)),
+ Key = hash(SSH, "E", 8*mac_key_bytes(SSH#ssh.recv_mac)),
{ok, SSH#ssh { recv_mac_key = Key }}
end;
aead ->
@@ -1545,99 +1724,116 @@ mac('hmac-sha2-256', Key, SeqNum, Data) ->
mac('hmac-sha2-512', Key, SeqNum, Data) ->
crypto:hmac(sha512, Key, [<<?UINT32(SeqNum)>>, Data]).
-%% return N hash bytes (HASH)
-hash(SSH, Char, Bits) ->
- HASH =
- case SSH#ssh.kex of
- 'diffie-hellman-group1-sha1' ->
- fun(Data) -> crypto:hash(sha, Data) end;
- 'diffie-hellman-group14-sha1' ->
- fun(Data) -> crypto:hash(sha, Data) end;
-
- 'diffie-hellman-group-exchange-sha1' ->
- fun(Data) -> crypto:hash(sha, Data) end;
- 'diffie-hellman-group-exchange-sha256' ->
- fun(Data) -> crypto:hash(sha256, Data) end;
-
- 'ecdh-sha2-nistp256' ->
- fun(Data) -> crypto:hash(sha256,Data) end;
- 'ecdh-sha2-nistp384' ->
- fun(Data) -> crypto:hash(sha384,Data) end;
- 'ecdh-sha2-nistp521' ->
- fun(Data) -> crypto:hash(sha512,Data) end;
- _ ->
- exit({bad_algorithm,SSH#ssh.kex})
- end,
- hash(SSH, Char, Bits, HASH).
-hash(_SSH, _Char, 0, _HASH) ->
+%%%----------------------------------------------------------------
+%% return N hash bytes (HASH)
+hash(_SSH, _Char, 0) ->
<<>>;
-hash(SSH, Char, N, HASH) ->
- K = ssh_bits:mpint(SSH#ssh.shared_secret),
+hash(SSH, Char, N) ->
+ HashAlg = sha(SSH#ssh.kex),
+ K = SSH#ssh.shared_secret,
H = SSH#ssh.exchanged_hash,
- SessionID = SSH#ssh.session_id,
- K1 = HASH([K, H, Char, SessionID]),
+ K1 = crypto:hash(HashAlg, [K, H, Char, SSH#ssh.session_id]),
Sz = N div 8,
- <<Key:Sz/binary, _/binary>> = hash(K, H, K1, N-128, HASH),
+ <<Key:Sz/binary, _/binary>> = hash(K, H, K1, N-128, HashAlg),
Key.
-hash(_K, _H, Ki, N, _HASH) when N =< 0 ->
+hash(_K, _H, Ki, N, _HashAlg) when N =< 0 ->
Ki;
-hash(K, H, Ki, N, HASH) ->
- Kj = HASH([K, H, Ki]),
- hash(K, H, <<Ki/binary, Kj/binary>>, N-128, HASH).
-
-kex_h(SSH, Key, E, F, K) ->
- KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
- L = <<?Estring(SSH#ssh.c_version), ?Estring(SSH#ssh.s_version),
- ?Ebinary(SSH#ssh.c_keyinit), ?Ebinary(SSH#ssh.s_keyinit), ?Ebinary(KeyBin),
- ?Empint(E), ?Empint(F), ?Empint(K)>>,
- crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).
-
-kex_h(SSH, Curve, Key, Q_c, Q_s, K) ->
- KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
- L = <<?Estring(SSH#ssh.c_version), ?Estring(SSH#ssh.s_version),
- ?Ebinary(SSH#ssh.c_keyinit), ?Ebinary(SSH#ssh.s_keyinit), ?Ebinary(KeyBin),
- ?Empint(Q_c), ?Empint(Q_s), ?Empint(K)>>,
- crypto:hash(sha(Curve), L).
-
-kex_h(SSH, Key, Min, NBits, Max, Prime, Gen, E, F, K) ->
- KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
- L = if Min==-1; Max==-1 ->
- %% flag from 'ssh_msg_kex_dh_gex_request_old'
- %% It was like this before that message was supported,
- %% why?
- <<?Estring(SSH#ssh.c_version), ?Estring(SSH#ssh.s_version),
- ?Ebinary(SSH#ssh.c_keyinit), ?Ebinary(SSH#ssh.s_keyinit), ?Ebinary(KeyBin),
- ?Empint(E), ?Empint(F), ?Empint(K)>>;
- true ->
- <<?Estring(SSH#ssh.c_version), ?Estring(SSH#ssh.s_version),
- ?Ebinary(SSH#ssh.c_keyinit), ?Ebinary(SSH#ssh.s_keyinit), ?Ebinary(KeyBin),
- ?Euint32(Min), ?Euint32(NBits), ?Euint32(Max),
- ?Empint(Prime), ?Empint(Gen), ?Empint(E), ?Empint(F), ?Empint(K)>>
- end,
- crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).
-
+hash(K, H, Ki, N, HashAlg) ->
+ Kj = crypto:hash(HashAlg, [K, H, Ki]),
+ hash(K, H, <<Ki/binary, Kj/binary>>, N-128, HashAlg).
+
+%%%----------------------------------------------------------------
+kex_hash(SSH, Key, SignAlg, HashAlg, Args) ->
+ crypto:hash(HashAlg, kex_plaintext(SSH,Key,SignAlg,Args)).
+
+kex_plaintext(SSH, Key, SignAlg, Args) ->
+ EncodedKey = public_key:ssh_encode({Key,SignAlg}, ssh2_pubkey),
+ <<?Estring(SSH#ssh.c_version), ?Estring(SSH#ssh.s_version),
+ ?Ebinary(SSH#ssh.c_keyinit), ?Ebinary(SSH#ssh.s_keyinit),
+ ?Ebinary(EncodedKey),
+ (kex_alg_dependent(Args))/binary>>.
+
+kex_alg_dependent({E, F, K}) ->
+ %% diffie-hellman and ec diffie-hellman (with E = Q_c, F = Q_s)
+ <<?Empint(E), ?Empint(F), ?Empint(K)>>;
+
+kex_alg_dependent({-1, _, -1, _, _, E, F, K}) ->
+ %% ssh_msg_kex_dh_gex_request_old
+ <<?Empint(E), ?Empint(F), ?Empint(K)>>;
+
+kex_alg_dependent({Min, NBits, Max, Prime, Gen, E, F, K}) ->
+ %% diffie-hellman group exchange
+ <<?Euint32(Min), ?Euint32(NBits), ?Euint32(Max),
+ ?Empint(Prime), ?Empint(Gen), ?Empint(E), ?Empint(F), ?Empint(K)>>.
+
+%%%----------------------------------------------------------------
+
+valid_key_sha_alg(#'RSAPublicKey'{}, 'rsa-sha2-512') -> true;
+valid_key_sha_alg(#'RSAPublicKey'{}, 'rsa-sha2-384') -> true;
+valid_key_sha_alg(#'RSAPublicKey'{}, 'rsa-sha2-256') -> true;
+valid_key_sha_alg(#'RSAPublicKey'{}, 'ssh-rsa' ) -> true;
+
+valid_key_sha_alg(#'RSAPrivateKey'{}, 'rsa-sha2-512') -> true;
+valid_key_sha_alg(#'RSAPrivateKey'{}, 'rsa-sha2-384') -> true;
+valid_key_sha_alg(#'RSAPrivateKey'{}, 'rsa-sha2-256') -> true;
+valid_key_sha_alg(#'RSAPrivateKey'{}, 'ssh-rsa' ) -> true;
+
+valid_key_sha_alg({_, #'Dss-Parms'{}}, 'ssh-dss') -> true;
+valid_key_sha_alg(#'DSAPrivateKey'{}, 'ssh-dss') -> true;
+
+valid_key_sha_alg({#'ECPoint'{},{namedCurve,OID}}, Alg) -> sha(OID) == sha(Alg);
+valid_key_sha_alg(#'ECPrivateKey'{parameters = {namedCurve,OID}}, Alg) -> sha(OID) == sha(Alg);
+valid_key_sha_alg(_, _) -> false.
+
+
+public_algo(#'RSAPublicKey'{}) -> 'ssh-rsa'; % FIXME: Not right with draft-curdle-rsa-sha2
+public_algo({_, #'Dss-Parms'{}}) -> 'ssh-dss';
+public_algo({#'ECPoint'{},{namedCurve,OID}}) ->
+ Curve = public_key:oid2ssh_curvename(OID),
+ list_to_atom("ecdsa-sha2-" ++ binary_to_list(Curve)).
+
+
+
+
+sha('ssh-rsa') -> sha;
+sha('rsa-sha2-256') -> sha256;
+sha('rsa-sha2-384') -> sha384;
+sha('rsa-sha2-512') -> sha512;
+sha('ssh-dss') -> sha;
+sha('ecdsa-sha2-nistp256') -> sha(secp256r1);
+sha('ecdsa-sha2-nistp384') -> sha(secp384r1);
+sha('ecdsa-sha2-nistp521') -> sha(secp521r1);
sha(secp256r1) -> sha256;
sha(secp384r1) -> sha384;
sha(secp521r1) -> sha512;
sha('diffie-hellman-group1-sha1') -> sha;
sha('diffie-hellman-group14-sha1') -> sha;
+sha('diffie-hellman-group14-sha256') -> sha256;
+sha('diffie-hellman-group16-sha512') -> sha512;
+sha('diffie-hellman-group18-sha512') -> sha512;
sha('diffie-hellman-group-exchange-sha1') -> sha;
sha('diffie-hellman-group-exchange-sha256') -> sha256;
sha(?'secp256r1') -> sha(secp256r1);
sha(?'secp384r1') -> sha(secp384r1);
-sha(?'secp521r1') -> sha(secp521r1).
-
-
-mac_key_size('hmac-sha1') -> 20*8;
-mac_key_size('hmac-sha1-96') -> 20*8;
-mac_key_size('hmac-md5') -> 16*8;
-mac_key_size('hmac-md5-96') -> 16*8;
-mac_key_size('hmac-sha2-256')-> 32*8;
-mac_key_size('hmac-sha2-512')-> 512;
-mac_key_size(none) -> 0.
+sha(?'secp521r1') -> sha(secp521r1);
+sha('ecdh-sha2-nistp256') -> sha(secp256r1);
+sha('ecdh-sha2-nistp384') -> sha(secp384r1);
+sha('ecdh-sha2-nistp521') -> sha(secp521r1);
+sha(Str) when is_list(Str), length(Str)<50 -> sha(list_to_atom(Str)).
+
+
+mac_key_bytes('hmac-sha1') -> 20;
+mac_key_bytes('hmac-sha1-96') -> 20;
+mac_key_bytes('hmac-md5') -> 16;
+mac_key_bytes('hmac-md5-96') -> 16;
+mac_key_bytes('hmac-sha2-256')-> 32;
+mac_key_bytes('hmac-sha2-512')-> 64;
+mac_key_bytes('AEAD_AES_128_GCM') -> 0;
+mac_key_bytes('AEAD_AES_256_GCM') -> 0;
+mac_key_bytes(none) -> 0.
mac_digest_size('hmac-sha1') -> 20;
mac_digest_size('hmac-sha1-96') -> 12;
@@ -1649,9 +1845,6 @@ mac_digest_size('AEAD_AES_128_GCM') -> 16;
mac_digest_size('AEAD_AES_256_GCM') -> 16;
mac_digest_size(none) -> 0.
-peer_name({Host, _}) ->
- Host.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Diffie-Hellman utils
@@ -1659,9 +1852,19 @@ peer_name({Host, _}) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
dh_group('diffie-hellman-group1-sha1') -> ?dh_group1;
-dh_group('diffie-hellman-group14-sha1') -> ?dh_group14.
+dh_group('diffie-hellman-group14-sha1') -> ?dh_group14;
+dh_group('diffie-hellman-group14-sha256') -> ?dh_group14;
+dh_group('diffie-hellman-group16-sha512') -> ?dh_group16;
+dh_group('diffie-hellman-group18-sha512') -> ?dh_group18.
%%%----------------------------------------------------------------
+parallell_gen_key(Ssh = #ssh{keyex_key = {x, {G, P}},
+ algorithms = Algs}) ->
+ Sz = dh_bits(Algs),
+ {Public, Private} = generate_key(dh, [P,G,2*Sz]),
+ Ssh#ssh{keyex_key = {{Private, Public}, {G, P}}}.
+
+
generate_key(Algorithm, Args) ->
{Public,Private} = crypto:generate_key(Algorithm, Args),
{crypto:bytes_to_integer(Public), crypto:bytes_to_integer(Private)}.
@@ -1672,6 +1875,15 @@ compute_key(Algorithm, OthersPublic, MyPrivate, Args) ->
crypto:bytes_to_integer(Shared).
+dh_bits(#alg{encrypt = Encrypt,
+ send_mac = SendMac}) ->
+ C = cipher(Encrypt),
+ 8 * lists:max([C#cipher_data.key_bytes,
+ C#cipher_data.block_bytes,
+ C#cipher_data.iv_bytes,
+ mac_key_bytes(SendMac)
+ ]).
+
ecdh_curve('ecdh-sha2-nistp256') -> secp256r1;
ecdh_curve('ecdh-sha2-nistp384') -> secp384r1;
ecdh_curve('ecdh-sha2-nistp521') -> secp521r1.
@@ -1734,10 +1946,6 @@ len_supported(Name, Len) ->
same(Algs) -> [{client2server,Algs}, {server2client,Algs}].
-
-%% default_algorithms(kex) -> % Example of how to disable an algorithm
-%% supported_algorithms(kex, ['ecdh-sha2-nistp521']);
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Other utils
diff --git a/lib/ssh/src/ssh_transport.hrl b/lib/ssh/src/ssh_transport.hrl
index f91cb1dd63..87c3719514 100644
--- a/lib/ssh/src/ssh_transport.hrl
+++ b/lib/ssh/src/ssh_transport.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -48,6 +48,7 @@
-define(SSH_MSG_DEBUG, 4).
-define(SSH_MSG_SERVICE_REQUEST, 5).
-define(SSH_MSG_SERVICE_ACCEPT, 6).
+-define(SSH_MSG_EXT_INFO, 7).
-define(SSH_MSG_KEXINIT, 20).
-define(SSH_MSG_NEWKEYS, 21).
@@ -88,6 +89,20 @@
name %% string
}).
+-record(ssh_msg_ext_info,
+ {
+ nr_extensions, %% uint32
+
+ %% repeat the following 2 fields "nr-extensions" times:
+ %% string extension-name
+ %% string extension-value
+
+ data %% [{extension-name, %% string
+ %% extension-value}, %% string
+ %% ...
+ %% ]
+ }).
+
-record(ssh_msg_kexinit,
{
cookie, %% random(16)
@@ -112,7 +127,7 @@
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% diffie-hellman-group1-sha1 | diffie-hellman-group14-sha1
+%% diffie-hellman-group*-sha*
-define(SSH_MSG_KEXDH_INIT, 30).
-define(SSH_MSG_KEXDH_REPLY, 31).
@@ -238,4 +253,15 @@
-define(dh_group14,
{2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF}).
+%%% rfc 3526, ch5
+%%% Size 4096-bit
+-define(dh_group16,
+ {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF}).
+
+%%% rfc 3526, ch7
+%%% Size 8192-bit
+-define(dh_group18,
+ {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF}).
+
+
-endif. % -ifdef(ssh_transport).
diff --git a/lib/ssh/src/sshc_sup.erl b/lib/ssh/src/sshc_sup.erl
index 15858f36e1..133b2c6450 100644
--- a/lib/ssh/src/sshc_sup.erl
+++ b/lib/ssh/src/sshc_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,23 +27,25 @@
-behaviour(supervisor).
--export([start_link/1, start_child/1, stop_child/1]).
+-export([start_link/0, start_child/1, stop_child/1]).
%% Supervisor callback
-export([init/1]).
+-define(SSHC_SUP, ?MODULE).
+
%%%=========================================================================
%%% API
%%%=========================================================================
-start_link(Args) ->
- supervisor:start_link({local, ?MODULE}, ?MODULE, [Args]).
+start_link() ->
+ supervisor:start_link({local,?SSHC_SUP}, ?MODULE, []).
start_child(Args) ->
supervisor:start_child(?MODULE, Args).
stop_child(Client) ->
spawn(fun() ->
- ClientSup = whereis(?MODULE),
+ ClientSup = whereis(?SSHC_SUP),
supervisor:terminate_child(ClientSup, Client)
end),
ok.
@@ -51,22 +53,17 @@ stop_child(Client) ->
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
--spec init( [term()] ) -> {ok,{supervisor:sup_flags(),[supervisor:child_spec()]}} | ignore .
-
-init(Args) ->
- RestartStrategy = simple_one_for_one,
- MaxR = 0,
- MaxT = 3600,
- {ok, {{RestartStrategy, MaxR, MaxT}, [child_spec(Args)]}}.
-
-%%%=========================================================================
-%%% Internal functions
-%%%=========================================================================
-child_spec(_) ->
- Name = undefined, % As simple_one_for_one is used.
- StartFunc = {ssh_connection_handler, start_link, []},
- Restart = temporary,
- Shutdown = 4000,
- Modules = [ssh_connection_handler],
- Type = worker,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+init(_) ->
+ SupFlags = #{strategy => simple_one_for_one,
+ intensity => 0,
+ period => 3600
+ },
+ ChildSpecs = [#{id => undefined, % As simple_one_for_one is used.
+ start => {ssh_connection_handler, start_link, []},
+ restart => temporary,
+ shutdown => 4000,
+ type => worker,
+ modules => [ssh_connection_handler]
+ }
+ ],
+ {ok, {SupFlags,ChildSpecs}}.
diff --git a/lib/ssh/src/sshd_sup.erl b/lib/ssh/src/sshd_sup.erl
index 04d2df30f7..c23e65d955 100644
--- a/lib/ssh/src/sshd_sup.erl
+++ b/lib/ssh/src/sshd_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
%%
%%
%%----------------------------------------------------------------------
-%% Purpose: The top supervisor for ssh servers hangs under
+%% Purpose: The top supervisor for ssh servers hangs under
%% ssh_sup.
%%----------------------------------------------------------------------
@@ -29,90 +29,79 @@
-include("ssh.hrl").
--export([start_link/1, start_child/1, stop_child/1,
- stop_child/3, system_name/1]).
+-export([start_link/0,
+ start_child/4,
+ stop_child/1,
+ stop_child/3
+]).
%% Supervisor callback
-export([init/1]).
+-define(SSHD_SUP, ?MODULE).
+
%%%=========================================================================
%%% API
%%%=========================================================================
-start_link(Servers) ->
- supervisor:start_link({local, ?MODULE}, ?MODULE, [Servers]).
+start_link() ->
+ %% No children are start now. We wait until the user calls ssh:daemon
+ %% and uses start_child/4 to create the children
+ supervisor:start_link({local,?SSHD_SUP}, ?MODULE, []).
-start_child(ServerOpts) ->
- Address = proplists:get_value(address, ServerOpts),
- Port = proplists:get_value(port, ServerOpts),
- Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+start_child(Address, Port, Profile, Options) ->
case ssh_system_sup:system_supervisor(Address, Port, Profile) of
undefined ->
- Spec = child_spec(Address, Port, ServerOpts),
- case supervisor:start_child(?MODULE, Spec) of
- {error, already_present} ->
- Name = id(Address, Port, Profile),
- supervisor:delete_child(?MODULE, Name),
- supervisor:start_child(?MODULE, Spec);
- Reply ->
- Reply
- end;
+ %% Here we start listening on a new Host/Port/Profile
+ Spec = child_spec(Address, Port, Profile, Options),
+ supervisor:start_child(?SSHD_SUP, Spec);
Pid ->
+ %% Here we resume listening on a new Host/Port/Profile after
+ %% haveing stopped listening to he same with ssh:stop_listen(Pid)
AccPid = ssh_system_sup:acceptor_supervisor(Pid),
- ssh_acceptor_sup:start_child(AccPid, ServerOpts)
+ ssh_acceptor_sup:start_child(AccPid, Address, Port, Profile, Options),
+ {ok,Pid}
end.
-stop_child(Name) ->
- supervisor:terminate_child(?MODULE, Name).
+stop_child(ChildId) when is_tuple(ChildId) ->
+ supervisor:terminate_child(?SSHD_SUP, ChildId);
+stop_child(ChildPid) when is_pid(ChildPid)->
+ stop_child(system_name(ChildPid)).
-stop_child(Address, Port, Profile) ->
- Name = id(Address, Port, Profile),
- stop_child(Name).
-system_name(SysSup) ->
- Children = supervisor:which_children(sshd_sup),
- system_name(SysSup, Children).
+stop_child(Address, Port, Profile) ->
+ Id = id(Address, Port, Profile),
+ stop_child(Id).
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
--spec init( [term()] ) -> {ok,{supervisor:sup_flags(),[supervisor:child_spec()]}} | ignore .
-
-init([Servers]) ->
- RestartStrategy = one_for_one,
- MaxR = 10,
- MaxT = 3600,
- Fun = fun(ServerOpts) ->
- Address = proplists:get_value(address, ServerOpts),
- Port = proplists:get_value(port, ServerOpts),
- child_spec(Address, Port, ServerOpts)
- end,
- Children = lists:map(Fun, Servers),
- {ok, {{RestartStrategy, MaxR, MaxT}, Children}}.
+init(_) ->
+ SupFlags = #{strategy => one_for_one,
+ intensity => 10,
+ period => 3600
+ },
+ ChildSpecs = [
+ ],
+ {ok, {SupFlags,ChildSpecs}}.
%%%=========================================================================
%%% Internal functions
%%%=========================================================================
-child_spec(Address, Port, ServerOpts) ->
- Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
- Name = id(Address, Port,Profile),
- StartFunc = {ssh_system_sup, start_link, [ServerOpts]},
- Restart = temporary,
- Shutdown = infinity,
- Modules = [ssh_system_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+child_spec(Address, Port, Profile, Options) ->
+ #{id => id(Address, Port, Profile),
+ start => {ssh_system_sup, start_link, [Address, Port, Profile, Options]},
+ restart => temporary,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [ssh_system_sup]
+ }.
id(Address, Port, Profile) ->
- case is_list(Address) of
- true ->
- {server, ssh_system_sup, any, Port, Profile};
- false ->
- {server, ssh_system_sup, Address, Port, Profile}
+ {server, ssh_system_sup, Address, Port, Profile}.
+
+system_name(SysSup) ->
+ case lists:keyfind(SysSup, 2, supervisor:which_children(?SSHD_SUP)) of
+ {Name, SysSup, _, _} -> Name;
+ false -> undefind
end.
-system_name([], _ ) ->
- undefined;
-system_name(SysSup, [{Name, SysSup, _, _} | _]) ->
- Name;
-system_name(SysSup, [_ | Rest]) ->
- system_name(SysSup, Rest).
diff --git a/lib/ssh/test/Makefile b/lib/ssh/test/Makefile
index 6ce6d6f537..32e76cf077 100644
--- a/lib/ssh/test/Makefile
+++ b/lib/ssh/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2016. All Rights Reserved.
+# Copyright Ericsson AB 2004-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@ MODULES= \
ssh_options_SUITE \
ssh_renegotiate_SUITE \
ssh_basic_SUITE \
- ssh_benchmark_SUITE \
+ ssh_bench_SUITE \
ssh_connection_SUITE \
ssh_protocol_SUITE \
ssh_sftp_SUITE \
@@ -50,9 +50,11 @@ MODULES= \
ssh_key_cb_options \
ssh_trpt_test_lib \
ssh_echo_server \
+ ssh_bench_dev_null \
ssh_peername_sockname_server \
ssh_test_cli \
- ssh_relay
+ ssh_relay \
+ ssh_eqc_event_handler
HRL_FILES_NEEDED_IN_TEST= \
$(ERL_TOP)/lib/ssh/test/ssh_test_lib.hrl \
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_info_timing.erl b/lib/ssh/test/property_test/ssh_eqc_client_info_timing.erl
new file mode 100644
index 0000000000..c07140dc43
--- /dev/null
+++ b/lib/ssh/test/property_test/ssh_eqc_client_info_timing.erl
@@ -0,0 +1,92 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ssh_eqc_client_info_timing).
+
+-compile(export_all).
+
+-proptest(eqc).
+-proptest([triq,proper]).
+
+-ifndef(EQC).
+-ifndef(PROPER).
+-ifndef(TRIQ).
+-define(EQC,true).
+%%-define(PROPER,true).
+%%-define(TRIQ,true).
+-endif.
+-endif.
+-endif.
+
+-ifdef(EQC).
+-include_lib("eqc/include/eqc.hrl").
+-define(MOD_eqc,eqc).
+
+-else.
+-ifdef(PROPER).
+-include_lib("proper/include/proper.hrl").
+-define(MOD_eqc,proper).
+
+-else.
+-ifdef(TRIQ).
+-define(MOD_eqc,triq).
+-include_lib("triq/include/triq.hrl").
+
+-endif.
+-endif.
+-endif.
+
+
+%%% Properties:
+
+prop_seq(_Config) ->
+ {ok,Pid} = ssh_eqc_event_handler:add_report_handler(),
+ {_, _, Port} = init_daemon(),
+ numtests(1000,
+ ?FORALL(Delay, choose(0,100),%% Micro seconds
+ try
+ send_bad_sequence(Port, Delay, Pid),
+ not any_relevant_error_report(Pid)
+ catch
+ C:E -> io:format('~p:~p~n',[C,E]),
+ false
+ end
+ )).
+
+send_bad_sequence(Port, Delay, Pid) ->
+ {ok,S} = gen_tcp:connect("localhost",Port,[]),
+ gen_tcp:send(S,"Illegal info-string\r\n"),
+ ssh_test_lib:sleep_microsec(Delay),
+ gen_tcp:close(S).
+
+any_relevant_error_report(Pid) ->
+ {ok, Reports} = ssh_eqc_event_handler:get_reports(Pid),
+ lists:any(fun({error_report,_,{_,supervisor_report,L}}) when is_list(L) ->
+ lists:member({reason,{badmatch,{error,closed}}}, L);
+ (_) ->
+ false
+ end, Reports).
+
+%%%================================================================
+init_daemon() ->
+ ok = begin ssh:stop(), ssh:start() end,
+ ssh_test_lib:daemon([]).
+
diff --git a/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
index dc3b7dc7e6..165274241c 100644
--- a/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
+++ b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -54,15 +54,18 @@
-endif.
-endif.
+%% Public key records:
+-include_lib("public_key/include/public_key.hrl").
%%% Properties:
prop_ssh_decode() ->
- ?FORALL(Msg, ssh_msg(),
- try ssh_message:decode(Msg)
+ ?FORALL({Msg,KexFam}, ?LET(KF, kex_family(), {ssh_msg(KF),KF} ),
+ try ssh_message:decode(decode_state(Msg,KexFam))
of
_ -> true
catch
+
C:E -> io:format('~p:~p~n',[C,E]),
false
end
@@ -71,122 +74,101 @@ prop_ssh_decode() ->
%%% This fails because ssh_message is not symmetric in encode and decode regarding data types
prop_ssh_decode_encode() ->
- ?FORALL(Msg, ssh_msg(),
- Msg == ssh_message:encode(ssh_message:decode(Msg))
+ ?FORALL({Msg,KexFam}, ?LET(KF, kex_family(), {ssh_msg(KF),KF} ),
+ Msg == ssh_message:encode(
+ fix_asym(
+ ssh_message:decode(decode_state(Msg,KexFam))))
).
%%%================================================================
%%%
-%%% Scripts to generate message generators
-%%%
-
-%% awk '/^( |\t)+byte( |\t)+SSH/,/^( |\t)*$/{print}' rfc425?.txt | sed 's/^\( \|\\t\)*//' > msgs.txt
-
-%% awk '/^byte( |\t)+SSH/{print $2","}' < msgs.txt
-
-%% awk 'BEGIN{print "%%%---- BEGIN GENERATED";prev=0} END{print " >>.\n%%%---- END GENERATED"} /^byte( |\t)+SSH/{if (prev==1) print " >>.\n"; prev=1; printf "%c%s%c",39,$2,39; print "()->\n <<?"$2;next} /^string( |\t)+\"/{print " ,"$2;next} /^string( |\t)+.*address/{print " ,(ssh_string_address())/binary %%",$2,$3,$4,$5,$6;next}/^string( |\t)+.*US-ASCII/{print " ,(ssh_string_US_ASCII())/binary %%",$2,$3,$4,$5,$6;next} /^string( |\t)+.*UTF-8/{print " ,(ssh_string_UTF_8())/binary %% ",$2,$3,$4,$5,$6;next} /^[a-z0-9]+( |\t)/{print " ,(ssh_"$1"())/binary %%",$2,$3,$4,$5,$6;next} /^byte\[16\]( |\t)+/{print" ,(ssh_byte_16())/binary %%",$2,$3,$4,$5,$6;next} /^name-list( |\t)+/{print" ,(ssh_name_list())/binary %%",$2,$3,$4,$5,$6;next} /./{print "?? %%",$0}' < msgs.txt > gen.txt
-
-%%%================================================================
-%%%
%%% Generators
%%%
-ssh_msg() -> ?LET(M,oneof(
-[[msg_code('SSH_MSG_CHANNEL_CLOSE'),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_DATA'),gen_uint32(),gen_string( )],
- [msg_code('SSH_MSG_CHANNEL_EOF'),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_EXTENDED_DATA'),gen_uint32(),gen_uint32(),gen_string( )],
- [msg_code('SSH_MSG_CHANNEL_FAILURE'),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("direct-tcpip"),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( ),gen_uint32(),gen_string( ),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("forwarded-tcpip"),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( ),gen_uint32(),gen_string( ),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("session"),gen_uint32(),gen_uint32(),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("x11"),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( ),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string( ),gen_uint32(),gen_uint32(),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_OPEN_CONFIRMATION'),gen_uint32(),gen_uint32(),gen_uint32(),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_OPEN_FAILURE'),gen_uint32(),gen_uint32(),gen_string( ),gen_string( )],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("env"),gen_boolean(),gen_string( ),gen_string( )],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("exec"),gen_boolean(),gen_string( )],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("exit-signal"),0,gen_string( ),gen_boolean(),gen_string( ),gen_string( )],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("exit-status"),0,gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("pty-req"),gen_boolean(),gen_string( ),gen_uint32(),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( )],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("shell"),gen_boolean()],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("signal"),0,gen_string( )],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("subsystem"),gen_boolean(),gen_string( )],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("window-change"),0,gen_uint32(),gen_uint32(),gen_uint32(),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("x11-req"),gen_boolean(),gen_boolean(),gen_string( ),gen_string( ),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("xon-xoff"),0,gen_boolean()],
- [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string( ),gen_boolean()],
- [msg_code('SSH_MSG_CHANNEL_SUCCESS'),gen_uint32()],
- [msg_code('SSH_MSG_CHANNEL_WINDOW_ADJUST'),gen_uint32(),gen_uint32()],
-%%Assym [msg_code('SSH_MSG_DEBUG'),gen_boolean(),gen_string( ),gen_string( )],
- [msg_code('SSH_MSG_DISCONNECT'),gen_uint32(),gen_string( ),gen_string( )],
-%%Assym [msg_code('SSH_MSG_GLOBAL_REQUEST'),gen_string("cancel-tcpip-forward"),gen_boolean(),gen_string( ),gen_uint32()],
-%%Assym [msg_code('SSH_MSG_GLOBAL_REQUEST'),gen_string("tcpip-forward"),gen_boolean(),gen_string( ),gen_uint32()],
-%%Assym [msg_code('SSH_MSG_GLOBAL_REQUEST'),gen_string( ),gen_boolean()],
- [msg_code('SSH_MSG_IGNORE'),gen_string( )],
- %% [msg_code('SSH_MSG_KEXDH_INIT'),gen_mpint()],
- %% [msg_code('SSH_MSG_KEXDH_REPLY'),gen_string( ),gen_mpint(),gen_string( )],
- %% [msg_code('SSH_MSG_KEXINIT'),gen_byte(16),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_boolean(),gen_uint32()],
- [msg_code('SSH_MSG_KEX_DH_GEX_GROUP'),gen_mpint(),gen_mpint()],
- [msg_code('SSH_MSG_NEWKEYS')],
- [msg_code('SSH_MSG_REQUEST_FAILURE')],
- [msg_code('SSH_MSG_REQUEST_SUCCESS')],
- [msg_code('SSH_MSG_REQUEST_SUCCESS'),gen_uint32()],
- [msg_code('SSH_MSG_SERVICE_ACCEPT'),gen_string( )],
- [msg_code('SSH_MSG_SERVICE_REQUEST'),gen_string( )],
- [msg_code('SSH_MSG_UNIMPLEMENTED'),gen_uint32()],
- [msg_code('SSH_MSG_USERAUTH_BANNER'),gen_string( ),gen_string( )],
- [msg_code('SSH_MSG_USERAUTH_FAILURE'),gen_name_list(),gen_boolean()],
- [msg_code('SSH_MSG_USERAUTH_PASSWD_CHANGEREQ'),gen_string( ),gen_string( )],
- [msg_code('SSH_MSG_USERAUTH_PK_OK'),gen_string( ),gen_string( )],
- [msg_code('SSH_MSG_USERAUTH_SUCCESS')]
-]
-
-), list_to_binary(M)).
-
-
-%%%================================================================
-%%%
-%%% Generator
-%%%
-
-do() ->
- io_lib:format('[~s~n]',
- [write_gen(
- files(["rfc4254.txt",
- "rfc4253.txt",
- "rfc4419.txt",
- "rfc4252.txt",
- "rfc4256.txt"]))]).
-
-
-write_gen(L) when is_list(L) ->
- string:join(lists:map(fun write_gen/1, L), ",\n ");
-write_gen({MsgName,Args}) ->
- lists:flatten(["[",generate_args([MsgName|Args]),"]"]).
-
-generate_args(As) -> string:join([generate_arg(A) || A <- As], ",").
-
-generate_arg({<<"string">>, <<"\"",B/binary>>}) ->
- S = get_string($",B),
- ["gen_string(\"",S,"\")"];
-generate_arg({<<"string">>, _}) -> "gen_string( )";
-generate_arg({<<"byte[",B/binary>>, _}) ->
- io_lib:format("gen_byte(~p)",[list_to_integer(get_string($],B))]);
-generate_arg({<<"byte">> ,_}) -> "gen_byte()";
-generate_arg({<<"uint16">>,_}) -> "gen_uint16()";
-generate_arg({<<"uint32">>,_}) -> "gen_uint32()";
-generate_arg({<<"uint64">>,_}) -> "gen_uint64()";
-generate_arg({<<"mpint">>,_}) -> "gen_mpint()";
-generate_arg({<<"name-list">>,_}) -> "gen_name_list()";
-generate_arg({<<"boolean">>,<<"FALSE">>}) -> "0";
-generate_arg({<<"boolean">>,<<"TRUE">>}) -> "1";
-generate_arg({<<"boolean">>,_}) -> "gen_boolean()";
-generate_arg({<<"....">>,_}) -> ""; %% FIXME
-generate_arg(Name) when is_binary(Name) ->
- lists:flatten(["msg_code('",binary_to_list(Name),"')"]).
-
+ssh_msg(<<"dh">>) ->
+ ?LET(M,oneof(
+ [
+ [msg_code('SSH_MSG_KEXDH_INIT'),gen_mpint()], % 30
+ [msg_code('SSH_MSG_KEXDH_REPLY'),gen_pubkey_string(rsa),gen_mpint(),gen_signature_string(rsa)] % 31
+ | rest_ssh_msgs()
+ ]),
+ list_to_binary(M));
+
+ssh_msg(<<"dh_gex">>) ->
+ ?LET(M,oneof(
+ [
+ [msg_code('SSH_MSG_KEX_DH_GEX_REQUEST_OLD'),gen_uint32()], % 30
+ [msg_code('SSH_MSG_KEX_DH_GEX_GROUP'),gen_mpint(),gen_mpint()] % 31
+ | rest_ssh_msgs()
+ ]),
+ list_to_binary(M));
+
+ ssh_msg(<<"ecdh">>) ->
+ ?LET(M,oneof(
+ [
+ [msg_code('SSH_MSG_KEX_ECDH_INIT'),gen_mpint()], % 30
+ [msg_code('SSH_MSG_KEX_ECDH_REPLY'),gen_pubkey_string(ecdsa),gen_mpint(),gen_signature_string(ecdsa)] % 31
+ | rest_ssh_msgs()
+ ]),
+ list_to_binary(M)).
+
+
+rest_ssh_msgs() ->
+ [%% SSH_MSG_USERAUTH_INFO_RESPONSE
+ %% hard args SSH_MSG_USERAUTH_INFO_REQUEST
+ %% rfc4252 p12 error SSH_MSG_USERAUTH_REQUEST
+ [msg_code('SSH_MSG_KEX_DH_GEX_REQUEST'),gen_uint32(),gen_uint32(),gen_uint32()],
+ [msg_code('SSH_MSG_KEX_DH_GEX_INIT'),gen_mpint()],
+ [msg_code('SSH_MSG_KEX_DH_GEX_REPLY'),gen_pubkey_string(rsa),gen_mpint(),gen_signature_string(rsa)],
+ [msg_code('SSH_MSG_CHANNEL_CLOSE'),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_DATA'),gen_uint32(),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_EOF'),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_EXTENDED_DATA'),gen_uint32(),gen_uint32(),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_FAILURE'),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("direct-tcpip"),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( ),gen_uint32(),gen_string( ),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("forwarded-tcpip"),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( ),gen_uint32(),gen_string( ),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("session"),gen_uint32(),gen_uint32(),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string("x11"),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( ),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN'),gen_string( ),gen_uint32(),gen_uint32(),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN_CONFIRMATION'),gen_uint32(),gen_uint32(),gen_uint32(),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_OPEN_FAILURE'),gen_uint32(),gen_uint32(),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("env"),gen_boolean(),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("exec"),gen_boolean(),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("exit-signal"),0,gen_string( ),gen_boolean(),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("exit-status"),0,gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("pty-req"),gen_boolean(),gen_string( ),gen_uint32(),gen_uint32(),gen_uint32(),gen_uint32(),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("shell"),gen_boolean()],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("signal"),0,gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("subsystem"),gen_boolean(),gen_string( )],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("window-change"),0,gen_uint32(),gen_uint32(),gen_uint32(),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("x11-req"),gen_boolean(),gen_boolean(),gen_string( ),gen_string( ),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string("xon-xoff"),0,gen_boolean()],
+ [msg_code('SSH_MSG_CHANNEL_REQUEST'),gen_uint32(),gen_string( ),gen_boolean()],
+ [msg_code('SSH_MSG_CHANNEL_SUCCESS'),gen_uint32()],
+ [msg_code('SSH_MSG_CHANNEL_WINDOW_ADJUST'),gen_uint32(),gen_uint32()],
+ [msg_code('SSH_MSG_DEBUG'),gen_boolean(),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_DISCONNECT'),gen_uint32(),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_GLOBAL_REQUEST'),gen_string("cancel-tcpip-forward"),gen_boolean(),gen_string( ),gen_uint32()],
+ [msg_code('SSH_MSG_GLOBAL_REQUEST'),gen_string("tcpip-forward"),gen_boolean(),gen_string( ),gen_uint32()],
+ [msg_code('SSH_MSG_GLOBAL_REQUEST'),gen_string( ),gen_boolean()],
+ [msg_code('SSH_MSG_IGNORE'),gen_string( )],
+ [msg_code('SSH_MSG_KEXINIT'),gen_byte(16),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_name_list(),gen_boolean(),gen_uint32()],
+ [msg_code('SSH_MSG_NEWKEYS')],
+ [msg_code('SSH_MSG_REQUEST_FAILURE')],
+ [msg_code('SSH_MSG_REQUEST_SUCCESS')],
+ [msg_code('SSH_MSG_REQUEST_SUCCESS'),gen_uint32()],
+ [msg_code('SSH_MSG_SERVICE_ACCEPT'),gen_string( )],
+ [msg_code('SSH_MSG_SERVICE_REQUEST'),gen_string( )],
+ [msg_code('SSH_MSG_UNIMPLEMENTED'),gen_uint32()],
+ [msg_code('SSH_MSG_USERAUTH_BANNER'),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_USERAUTH_FAILURE'),gen_name_list(),gen_boolean()],
+ [msg_code('SSH_MSG_USERAUTH_PASSWD_CHANGEREQ'),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_USERAUTH_PK_OK'),gen_string( ),gen_string( )],
+ [msg_code('SSH_MSG_USERAUTH_SUCCESS')]
+ ].
+
+kex_family() -> oneof([<<"dh">>, <<"dh_gex">>, <<"ecdh">>]).
gen_boolean() -> choose(0,1).
@@ -202,10 +184,7 @@ gen_byte(N) when N>0 -> [gen_byte() || _ <- lists:seq(1,N)].
gen_char() -> choose($a,$z).
-gen_mpint() -> ?LET(Size, choose(1,20),
- ?LET(Str, vector(Size, gen_byte()),
- gen_string( strip_0s(Str) )
- )).
+gen_mpint() -> ?LET(I, largeint(), ssh_bits:mpint(I)).
strip_0s([0|T]) -> strip_0s(T);
strip_0s(X) -> X.
@@ -230,13 +209,22 @@ gen_name() -> gen_string().
uint32_to_list(I) -> binary_to_list(<<I:32/unsigned-big-integer>>).
-%%%----
-get_string(Delim, B) ->
- binary_to_list( element(1, split_binary(B, count_string_chars(Delim,B,0))) ).
-
-count_string_chars(Delim, <<Delim,_/binary>>, Acc) -> Acc;
-count_string_chars(Delim, <<_,B/binary>>, Acc) -> count_string_chars(Delim, B, Acc+1).
+gen_pubkey_string(Type) ->
+ PubKey = case Type of
+ rsa -> #'RSAPublicKey'{modulus = 12345,publicExponent = 2};
+ ecdsa -> {#'ECPoint'{point=[1,2,3,4,5]},
+ {namedCurve,{1,2,840,10045,3,1,7}}} % 'secp256r1' nistp256
+ end,
+ gen_string(public_key:ssh_encode(PubKey, ssh2_pubkey)).
+
+gen_signature_string(Type) ->
+ Signature = <<"hejhopp">>,
+ Id = case Type of
+ rsa -> "ssh-rsa";
+ ecdsa -> "ecdsa-sha2-nistp256"
+ end,
+ gen_string(gen_string(Id) ++ gen_string(Signature)).
-define(MSG_CODE(Name,Num),
msg_code(Name) -> Num;
@@ -273,124 +261,44 @@ msg_code(Num) -> Name
?MSG_CODE('SSH_MSG_CHANNEL_FAILURE', 100);
?MSG_CODE('SSH_MSG_USERAUTH_INFO_REQUEST', 60);
?MSG_CODE('SSH_MSG_USERAUTH_INFO_RESPONSE', 61);
+?MSG_CODE('SSH_MSG_KEXDH_INIT', 30);
+?MSG_CODE('SSH_MSG_KEXDH_REPLY', 31);
?MSG_CODE('SSH_MSG_KEX_DH_GEX_REQUEST_OLD', 30);
?MSG_CODE('SSH_MSG_KEX_DH_GEX_REQUEST', 34);
?MSG_CODE('SSH_MSG_KEX_DH_GEX_GROUP', 31);
?MSG_CODE('SSH_MSG_KEX_DH_GEX_INIT', 32);
-?MSG_CODE('SSH_MSG_KEX_DH_GEX_REPLY', 33).
-
-%%%=============================================================================
-%%%=============================================================================
-%%%=============================================================================
-
-files(Fs) ->
- Defs = lists:usort(lists:flatten(lists:map(fun file/1, Fs))),
- DefinedIDs = lists:usort([binary_to_list(element(1,D)) || D <- Defs]),
- WantedIDs = lists:usort(wanted_messages()),
- Missing = WantedIDs -- DefinedIDs,
- case Missing of
- [] -> ok;
- _ -> io:format('%% Warning: missing ~p~n', [Missing])
- end,
- Defs.
-
-
-file(F) ->
- {ok,B} = file:read_file(F),
- hunt_msg_def(B).
-
-
-hunt_msg_def(<<"\n",B/binary>>) -> some_hope(skip_blanks(B));
-hunt_msg_def(<<_, B/binary>>) -> hunt_msg_def(B);
-hunt_msg_def(<<>>) -> [].
-
-some_hope(<<"byte ", B/binary>>) -> try_message(skip_blanks(B));
-some_hope(B) -> hunt_msg_def(B).
-
-try_message(B = <<"SSH_MSG_",_/binary>>) ->
- {ID,Rest} = get_id(B),
- case lists:member(binary_to_list(ID), wanted_messages()) of
- true ->
- {Lines,More} = get_def_lines(skip_blanks(Rest), []),
- [{ID,lists:reverse(Lines)} | hunt_msg_def(More)];
- false ->
- hunt_msg_def(Rest)
- end;
-try_message(B) -> hunt_msg_def(B).
-
+?MSG_CODE('SSH_MSG_KEX_DH_GEX_REPLY', 33);
+?MSG_CODE('SSH_MSG_KEX_ECDH_INIT', 30);
+?MSG_CODE('SSH_MSG_KEX_ECDH_REPLY', 31).
+
+%%%====================================================
+%%%=== WARNING: Knowledge of the test object ahead! ===
+%%%====================================================
+
+%% SSH message records:
+-include_lib("ssh/src/ssh_connect.hrl").
+-include_lib("ssh/src/ssh_transport.hrl").
+
+%%% Encoding and decodeing is asymetric so out=binary in=string. Sometimes. :(
+-define(fix_asym_Xdh_reply(S),
+ fix_asym(#S{public_host_key = Key, h_sig = {Alg,Sig}} = M) ->
+ M#S{public_host_key = {Key, list_to_atom(Alg)}, h_sig = Sig}
+).
-skip_blanks(<<32, B/binary>>) -> skip_blanks(B);
-skip_blanks(<< 9, B/binary>>) -> skip_blanks(B);
-skip_blanks(B) -> B.
-
-get_def_lines(B0 = <<"\n",B/binary>>, Acc) ->
- {ID,Rest} = get_id(skip_blanks(B)),
- case {size(ID), skip_blanks(Rest)} of
- {0,<<"....",More/binary>>} ->
- {Text,LineEnd} = get_to_eol(skip_blanks(More)),
- get_def_lines(LineEnd, [{<<"....">>,Text}|Acc]);
- {0,_} ->
- {Acc,B0};
- {_,Rest1} ->
- {Text,LineEnd} = get_to_eol(Rest1),
- get_def_lines(LineEnd, [{ID,Text}|Acc])
- end;
-get_def_lines(B, Acc) ->
- {Acc,B}.
-
-get_to_eol(B) -> split_binary(B, count_to_eol(B,0)).
+fix_asym(#ssh_msg_global_request{name=N} = M) -> M#ssh_msg_global_request{name = binary_to_list(N)};
+fix_asym(#ssh_msg_debug{message=D,language=L} = M) -> M#ssh_msg_debug{message = binary_to_list(D),
+ language = binary_to_list(L)};
+fix_asym(#ssh_msg_kexinit{cookie=C} = M) -> M#ssh_msg_kexinit{cookie = <<C:128>>};
+?fix_asym_Xdh_reply(ssh_msg_kexdh_reply);
+?fix_asym_Xdh_reply(ssh_msg_kex_dh_gex_reply);
+?fix_asym_Xdh_reply(ssh_msg_kex_ecdh_reply);
+fix_asym(M) -> M.
-count_to_eol(<<"\n",_/binary>>, Acc) -> Acc;
-count_to_eol(<<>>, Acc) -> Acc;
-count_to_eol(<<_,B/binary>>, Acc) -> count_to_eol(B,Acc+1).
-
-get_id(B) -> split_binary(B, count_id_chars(B,0)).
-
-count_id_chars(<<C,B/binary>>, Acc) when $A=<C,C=<$Z -> count_id_chars(B,Acc+1);
-count_id_chars(<<C,B/binary>>, Acc) when $a=<C,C=<$z -> count_id_chars(B,Acc+1);
-count_id_chars(<<C,B/binary>>, Acc) when $0=<C,C=<$9 -> count_id_chars(B,Acc+1);
-count_id_chars(<<"_",B/binary>>, Acc) -> count_id_chars(B,Acc+1);
-count_id_chars(<<"-",B/binary>>, Acc) -> count_id_chars(B,Acc+1); %% e.g name-list
-count_id_chars(<<"[",B/binary>>, Acc) -> count_id_chars(B,Acc+1); %% e.g byte[16]
-count_id_chars(<<"]",B/binary>>, Acc) -> count_id_chars(B,Acc+1); %% e.g byte[16]
-count_id_chars(_, Acc) -> Acc.
-
-wanted_messages() ->
- ["SSH_MSG_CHANNEL_CLOSE",
- "SSH_MSG_CHANNEL_DATA",
- "SSH_MSG_CHANNEL_EOF",
- "SSH_MSG_CHANNEL_EXTENDED_DATA",
- "SSH_MSG_CHANNEL_FAILURE",
- "SSH_MSG_CHANNEL_OPEN",
- "SSH_MSG_CHANNEL_OPEN_CONFIRMATION",
- "SSH_MSG_CHANNEL_OPEN_FAILURE",
- "SSH_MSG_CHANNEL_REQUEST",
- "SSH_MSG_CHANNEL_SUCCESS",
- "SSH_MSG_CHANNEL_WINDOW_ADJUST",
- "SSH_MSG_DEBUG",
- "SSH_MSG_DISCONNECT",
- "SSH_MSG_GLOBAL_REQUEST",
- "SSH_MSG_IGNORE",
- "SSH_MSG_KEXDH_INIT",
- "SSH_MSG_KEXDH_REPLY",
- "SSH_MSG_KEXINIT",
- "SSH_MSG_KEX_DH_GEX_GROUP",
- "SSH_MSG_KEX_DH_GEX_REQUEST",
- "SSH_MSG_KEX_DH_GEX_REQUEST_OLD",
- "SSH_MSG_NEWKEYS",
- "SSH_MSG_REQUEST_FAILURE",
- "SSH_MSG_REQUEST_SUCCESS",
- "SSH_MSG_SERVICE_ACCEPT",
- "SSH_MSG_SERVICE_REQUEST",
- "SSH_MSG_UNIMPLEMENTED",
- "SSH_MSG_USERAUTH_BANNER",
- "SSH_MSG_USERAUTH_FAILURE",
-%% hard args "SSH_MSG_USERAUTH_INFO_REQUEST",
-%% "SSH_MSG_USERAUTH_INFO_RESPONSE",
- "SSH_MSG_USERAUTH_PASSWD_CHANGEREQ",
- "SSH_MSG_USERAUTH_PK_OK",
-%%rfc4252 p12 error "SSH_MSG_USERAUTH_REQUEST",
- "SSH_MSG_USERAUTH_SUCCESS"].
+%%% Message codes 30 and 31 are overloaded depending on kex family so arrange the decoder
+%%% input as the test object does
+decode_state(<<30,_/binary>>=Msg, KexFam) -> <<KexFam/binary, Msg/binary>>;
+decode_state(<<31,_/binary>>=Msg, KexFam) -> <<KexFam/binary, Msg/binary>>;
+decode_state(Msg, _) -> Msg.
diff --git a/lib/ssh/test/ssh.cover b/lib/ssh/test/ssh.cover
index a4221fbbbe..69d2a1c4f8 100644
--- a/lib/ssh/test/ssh.cover
+++ b/lib/ssh/test/ssh.cover
@@ -1,2 +1,3 @@
{incl_app,ssh,details}.
+{excl_mods, ssh, [ssh_dbg, ssh_info, ssh_server_key_api, ssh_sftpd_file_api]}. \ No newline at end of file
diff --git a/lib/ssh/test/ssh.spec b/lib/ssh/test/ssh.spec
index 0076fc275e..b4e3d36072 100644
--- a/lib/ssh/test/ssh.spec
+++ b/lib/ssh/test/ssh.spec
@@ -1,6 +1,8 @@
{suites,"../ssh_test",all}.
-{skip_suites, "../ssh_test", [ssh_benchmark_SUITE],
+{skip_suites, "../ssh_test", [ssh_bench_SUITE,
+ ssh_upgrade_SUITE
+ ],
"Benchmarks run separately"}.
diff --git a/lib/ssh/test/ssh_algorithms_SUITE.erl b/lib/ssh/test/ssh_algorithms_SUITE.erl
index 0f68130a05..98964a2c8a 100644
--- a/lib/ssh/test/ssh_algorithms_SUITE.erl
+++ b/lib/ssh/test/ssh_algorithms_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -58,15 +58,17 @@ groups() ->
|| {Tag,Algs} <- ErlAlgos,
lists:member(Tag,tags())
],
+
+ TypeSSH = ssh_test_lib:ssh_type(),
AlgoTcSet =
- [{Alg, [parallel], specific_test_cases(Tag,Alg,SshcAlgos,SshdAlgos)}
+ [{Alg, [parallel], specific_test_cases(Tag,Alg,SshcAlgos,SshdAlgos,TypeSSH)}
|| {Tag,Algs} <- ErlAlgos ++ DoubleAlgos,
Alg <- Algs],
TagGroupSet ++ AlgoTcSet.
-tags() -> [kex,cipher,mac,compression].
+tags() -> [kex,cipher,mac,compression,public_key].
two_way_tags() -> [cipher,mac,compression].
%%--------------------------------------------------------------------
@@ -121,20 +123,40 @@ init_per_group(Group, Config) ->
Tag = proplists:get_value(name,
hd(proplists:get_value(tc_group_path, Config))),
Alg = Group,
- PA =
- case split(Alg) of
- [_] ->
- [Alg];
- [A1,A2] ->
- [{client2server,[A1]},
- {server2client,[A2]}]
- end,
- ct:log("Init tests for tag=~p alg=~p",[Tag,PA]),
- PrefAlgs = {preferred_algorithms,[{Tag,PA}]},
- start_std_daemon([PrefAlgs],
- [{pref_algs,PrefAlgs} | Config])
+ init_per_group(Tag, Alg, Config)
end.
+
+init_per_group(public_key=Tag, Alg, Config) ->
+ ct:log("Init tests for public_key ~p",[Alg]),
+ PrefAlgs = {preferred_algorithms,[{Tag,[Alg]}]},
+ %% Daemon started later in init_per_testcase
+ try
+ setup_pubkey(Alg,
+ [{pref_algs,PrefAlgs},
+ {tag_alg,{Tag,Alg}}
+ | Config])
+ catch
+ _:_ -> {skip, io_lib:format("Unsupported: ~p",[Alg])}
+ end;
+
+init_per_group(Tag, Alg, Config) ->
+ PA =
+ case split(Alg) of
+ [_] ->
+ [Alg];
+ [A1,A2] ->
+ [{client2server,[A1]},
+ {server2client,[A2]}]
+ end,
+ ct:log("Init tests for tag=~p alg=~p",[Tag,PA]),
+ PrefAlgs = {preferred_algorithms,[{Tag,PA}]},
+ start_std_daemon([PrefAlgs],
+ [{pref_algs,PrefAlgs},
+ {tag_alg,{Tag,Alg}}
+ | Config]).
+
+
end_per_group(_Alg, Config) ->
case proplists:get_value(srvr_pid,Config) of
Pid when is_pid(Pid) ->
@@ -146,22 +168,55 @@ end_per_group(_Alg, Config) ->
-init_per_testcase(sshc_simple_exec_os_cmd, Config) ->
- start_pubkey_daemon([proplists:get_value(pref_algs,Config)], Config);
-init_per_testcase(_TC, Config) ->
+init_per_testcase(TC, Config) ->
+ init_per_testcase(TC, proplists:get_value(tag_alg,Config), Config).
+
+
+init_per_testcase(TC, {public_key,Alg}, Config) ->
+ ExtraOpts = case TC of
+ simple_connect ->
+ [{user_dir, proplists:get_value(priv_dir,Config)}];
+ _ ->
+ []
+ end,
+ Opts = pubkey_opts(Config) ++ ExtraOpts,
+ case {ssh_file:user_key(Alg,Opts), ssh_file:host_key(Alg,Opts)} of
+ {{ok,_}, {ok,_}} ->
+ start_pubkey_daemon([proplists:get_value(pref_algs,Config)
+ | ExtraOpts],
+ [{extra_daemon,true}|Config]);
+ {{ok,_}, {error,Err}} ->
+ {skip, io_lib:format("No host key: ~p",[Err])};
+
+ {{error,Err}, {ok,_}} ->
+ {skip, io_lib:format("No user key: ~p",[Err])};
+
+ _ ->
+ {skip, "Neither host nor user key"}
+ end;
+
+init_per_testcase(sshc_simple_exec_os_cmd, _, Config) ->
+ start_pubkey_daemon([proplists:get_value(pref_algs,Config)],
+ [{extra_daemon,true}|Config]);
+
+init_per_testcase(_, _, Config) ->
Config.
-end_per_testcase(sshc_simple_exec_os_cmd, Config) ->
- case proplists:get_value(srvr_pid,Config) of
- Pid when is_pid(Pid) ->
- ssh:stop_daemon(Pid),
- ct:log("stopped ~p",[proplists:get_value(srvr_addr,Config)]);
- _ ->
- ok
- end;
end_per_testcase(_TC, Config) ->
- Config.
+ case proplists:get_value(extra_daemon, Config, false) of
+ true ->
+ case proplists:get_value(srvr_pid,Config) of
+ Pid when is_pid(Pid) ->
+ ssh:stop_daemon(Pid),
+ ct:log("stopped ~p",[proplists:get_value(srvr_addr,Config)]),
+ Config;
+ _ ->
+ Config
+ end;
+ _ ->
+ Config
+ end.
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
@@ -178,40 +233,50 @@ simple_exec(Config) ->
ssh_test_lib:std_simple_exec(Host, Port, Config).
%%--------------------------------------------------------------------
+%% A simple exec call
+simple_connect(Config) ->
+ {Host,Port} = proplists:get_value(srvr_addr, Config),
+ Opts =
+ case proplists:get_value(tag_alg, Config) of
+ {public_key,Alg} -> [{pref_public_key_algs,[Alg]}];
+ _ -> []
+ end,
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, Opts),
+ ct:log("~p:~p connected! ~p",[?MODULE,?LINE,ConnectionRef]),
+ ssh:close(ConnectionRef).
+
+%%--------------------------------------------------------------------
%% Testing if no group matches
simple_exec_groups_no_match_too_small(Config) ->
- try simple_exec_group({400,500,600}, Config)
- of
- _ -> ct:fail("Exec though no group available")
- catch
- error:{badmatch,{error,"No possible diffie-hellman-group-exchange group found"}} ->
- ok
- end.
+ try_exec_simple_group({400,500,600}, Config).
simple_exec_groups_no_match_too_large(Config) ->
- try simple_exec_group({9200,9500,9700}, Config)
+ try_exec_simple_group({9200,9500,9700}, Config).
+
+
+try_exec_simple_group(Group, Config) ->
+ try simple_exec_group(Group, Config)
of
_ -> ct:fail("Exec though no group available")
catch
- error:{badmatch,{error,"No possible diffie-hellman-group-exchange group found"}} ->
- ok
+ error:{badmatch,{error,"No possible diffie-hellman-group-exchange group found"}} -> ok;
+ error:{badmatch,{error,"Connection closed"}} -> ok
end.
%%--------------------------------------------------------------------
%% Testing all default groups
-simple_exec_groups() -> [{timetrap,{minutes,5}}].
-
+simple_exec_groups() ->
+ [{timetrap,{seconds,120}}].
+
simple_exec_groups(Config) ->
Sizes = interpolate( public_key:dh_gex_group_sizes() ),
lists:foreach(
fun(Sz) ->
ct:log("Try size ~p",[Sz]),
ct:comment(Sz),
- case simple_exec_group(Sz, Config) of
- expected -> ct:log("Size ~p ok",[Sz]);
- _ -> ct:log("Size ~p not ok",[Sz])
- end
+ simple_exec_group(Sz, Config),
+ ct:log("Size ~p ok",[Sz])
end, Sizes),
ct:comment("~p",[lists:map(fun({_,I,_}) -> I;
(I) -> I
@@ -236,13 +301,12 @@ sshc_simple_exec_os_cmd(Config) ->
Parent = self(),
Client = spawn(
fun() ->
- Cmd = lists:concat(["ssh -p ",Port,
- " -C"
- " -o UserKnownHostsFile=",KnownHosts,
- " -o StrictHostKeyChecking=no"
- " ",Host," 1+1."]),
- Result = os:cmd(Cmd),
- ct:log("~p~n = ~p",[Cmd, Result]),
+ Result = ssh_test_lib:open_sshc(Host, Port,
+ [" -C"
+ " -o UserKnownHostsFile=",KnownHosts,
+ " -o StrictHostKeyChecking=no"
+ ],
+ " 1+1."),
Parent ! {result, self(), Result, "2"}
end),
receive
@@ -262,9 +326,16 @@ sshc_simple_exec_os_cmd(Config) ->
%%--------------------------------------------------------------------
%% Connect to the ssh server of the OS
-sshd_simple_exec(_Config) ->
+sshd_simple_exec(Config) ->
+ ClientPubKeyOpts =
+ case proplists:get_value(tag_alg,Config) of
+ {public_key,Alg} -> [{pref_public_key_algs,[Alg]}];
+ _ -> []
+ end,
ConnectionRef = ssh_test_lib:connect(22, [{silently_accept_hosts, true},
- {user_interaction, false}]),
+ proplists:get_value(pref_algs,Config),
+ {user_interaction, false}
+ | ClientPubKeyOpts]),
{ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity),
success = ssh_connection:exec(ConnectionRef, ChannelId0,
"echo testing", infinity),
@@ -319,35 +390,33 @@ concat(A1, A2) -> list_to_atom(lists:concat([A1," + ",A2])).
split(Alg) -> ssh_test_lib:to_atoms(string:tokens(atom_to_list(Alg), " + ")).
-specific_test_cases(Tag, Alg, SshcAlgos, SshdAlgos) ->
- [simple_exec, simple_sftp] ++
- case supports(Tag, Alg, SshcAlgos) of
- true ->
- case ssh_test_lib:ssh_type() of
- openSSH ->
- [sshc_simple_exec_os_cmd];
- _ ->
- []
- end;
- false ->
- []
- end ++
- case supports(Tag, Alg, SshdAlgos) of
- true ->
- [sshd_simple_exec];
- _ ->
- []
- end ++
- case {Tag,Alg} of
- {kex,_} when Alg == 'diffie-hellman-group-exchange-sha1' ;
- Alg == 'diffie-hellman-group-exchange-sha256' ->
- [simple_exec_groups,
- simple_exec_groups_no_match_too_large,
- simple_exec_groups_no_match_too_small
- ];
- _ ->
- []
- end.
+specific_test_cases(Tag, Alg, SshcAlgos, SshdAlgos, TypeSSH) ->
+ case Tag of
+ public_key -> [simple_connect];
+ _ -> [simple_connect, simple_exec, simple_sftp]
+ end
+ ++ case supports(Tag, Alg, SshcAlgos) of
+ true when TypeSSH == openSSH ->
+ [sshc_simple_exec_os_cmd];
+ _ ->
+ []
+ end ++
+ case supports(Tag, Alg, SshdAlgos) of
+ true ->
+ [sshd_simple_exec];
+ _ ->
+ []
+ end ++
+ case {Tag,Alg} of
+ {kex,_} when Alg == 'diffie-hellman-group-exchange-sha1' ;
+ Alg == 'diffie-hellman-group-exchange-sha256' ->
+ [simple_exec_groups,
+ simple_exec_groups_no_match_too_large,
+ simple_exec_groups_no_match_too_small
+ ];
+ _ ->
+ []
+ end.
supports(Tag, Alg, Algos) ->
lists:all(fun(A) ->
@@ -377,19 +446,46 @@ start_std_daemon(Opts, Config) ->
ct:log("started ~p:~p ~p",[Host,Port,Opts]),
[{srvr_pid,Pid},{srvr_addr,{Host,Port}} | Config].
+
start_pubkey_daemon(Opts0, Config) ->
- Opts = [{auth_methods,"publickey"}|Opts0],
- {Pid, Host, Port} = ssh_test_lib:std_daemon1(Config, Opts),
- ct:log("started pubkey_daemon ~p:~p ~p",[Host,Port,Opts]),
+ ct:log("starting pubkey_daemon",[]),
+ Opts = pubkey_opts(Config) ++ Opts0,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{failfun, fun ssh_test_lib:failfun/2}
+ | Opts]),
+ ct:log("started ~p:~p ~p",[Host,Port,Opts]),
[{srvr_pid,Pid},{srvr_addr,{Host,Port}} | Config].
+pubkey_opts(Config) ->
+ SystemDir = filename:join(proplists:get_value(priv_dir,Config), "system"),
+ [{auth_methods,"publickey"},
+ {system_dir, SystemDir}].
+
+
setup_pubkey(Config) ->
DataDir = proplists:get_value(data_dir, Config),
UserDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_dsa(DataDir, UserDir),
- ssh_test_lib:setup_rsa(DataDir, UserDir),
- ssh_test_lib:setup_ecdsa("256", DataDir, UserDir),
+ Keys =
+ [ssh_test_lib:setup_dsa(DataDir, UserDir),
+ ssh_test_lib:setup_rsa(DataDir, UserDir),
+ ssh_test_lib:setup_ecdsa("256", DataDir, UserDir)
+ ],
+ ssh_test_lib:write_auth_keys(Keys, UserDir), % 'authorized_keys' shall contain ALL pub keys
+ Config.
+
+setup_pubkey(Alg, Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ UserDir = proplists:get_value(priv_dir, Config),
+ ct:log("Setup keys for ~p",[Alg]),
+ case Alg of
+ 'ssh-dss' -> ssh_test_lib:setup_dsa(DataDir, UserDir);
+ 'ssh-rsa' -> ssh_test_lib:setup_rsa(DataDir, UserDir);
+ 'rsa-sha2-256' -> ssh_test_lib:setup_rsa(DataDir, UserDir);
+ 'rsa-sha2-512' -> ssh_test_lib:setup_rsa(DataDir, UserDir);
+ 'ecdsa-sha2-nistp256' -> ssh_test_lib:setup_ecdsa("256", DataDir, UserDir);
+ 'ecdsa-sha2-nistp384' -> ssh_test_lib:setup_ecdsa("384", DataDir, UserDir);
+ 'ecdsa-sha2-nistp521' -> ssh_test_lib:setup_ecdsa("521", DataDir, UserDir)
+ end,
Config.
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384
new file mode 100644
index 0000000000..4c39e916e9
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDAughXu55DNyhxe6x+MNjv4oZKWUDh7bhi4CqjvxhCp9KMpsybltcq+
+lsuKTarzTdKgBwYFK4EEACKhZANiAASu1vvDL0SQoXGtzlltaPHPyDfEVMG/sKLA
+pqv8vfRN5Wcs7+yaRKw92nYEKGXfZLbhVX8ArFPMtXPWHcRHCntvL1Acn2kJQ8Gc
+7iL4NAr8JhTIUBv4YMhHDa9Pv/CH2zk=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384.pub
new file mode 100644
index 0000000000..caa9604c84
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBK7W+8MvRJChca3OWW1o8c/IN8RUwb+wosCmq/y99E3lZyzv7JpErD3adgQoZd9ktuFVfwCsU8y1c9YdxEcKe28vUByfaQlDwZzuIvg0CvwmFMhQG/hgyEcNr0+/8IfbOQ== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521
new file mode 100644
index 0000000000..1e16fcbd57
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEEWXGoVLiNwQVUwAGZWxOu6uxtU8ntxyZNlcWU4Z8pze9kq3eK7a9XH
+l/wxL75Vk1QdOiR/rE3s/L/zOuChp44o1aAHBgUrgQQAI6GBiQOBhgAEAfCrtwjO
+kQYKr4/F3uanS7Eby1+SYDdRl1ABuDFhNC3CivVBFt4CnRneV+Mf0viDAxD+HEpd
+/GaE2CdsFoVpglN5AVG+fEePY2PiCLHmjc4/pBuR+tWhErzcWAd0KLBCBuc4OAvl
+aLLYV1NAJI6COnnfGTCVvYYE5nKMG4LLX0zaWtWl
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521.pub
new file mode 100644
index 0000000000..069683eba7
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHwq7cIzpEGCq+Pxd7mp0uxG8tfkmA3UZdQAbgxYTQtwor1QRbeAp0Z3lfjH9L4gwMQ/hxKXfxmhNgnbBaFaYJTeQFRvnxHj2Nj4gix5o3OP6QbkfrVoRK83FgHdCiwQgbnODgL5Wiy2FdTQCSOgjp53xkwlb2GBOZyjBuCy19M2lrVpQ== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..5835bcd74c
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDB+l0+SMLYgQ3ZRzg2Pn5u+1ZwKbEnJzXsTKTJM9QSJbKkbA7uCnjdS
+CvEW+66CoHqgBwYFK4EEACKhZANiAAT6awCCIrcCr9H4wq0bJ/rQou3tpLHyyf33
+c8D6FPn48/hNqinpx7b0le/0D+Rrhdl9edIplAf6oki7yoFFGl4yuzWtv7rag9jB
+vv6w1508ChOmyQ094rFt/xj4KVBhEHI=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..714fc4eb89
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPprAIIitwKv0fjCrRsn+tCi7e2ksfLJ/fdzwPoU+fjz+E2qKenHtvSV7/QP5GuF2X150imUB/qiSLvKgUUaXjK7Na2/utqD2MG+/rDXnTwKE6bJDT3isW3/GPgpUGEQcg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..81aa8df39f
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEHHxgYEfDclsu5bW+pZfg+bkaqWpgEpXtuzLVm++FFPjhAPhMkurSRj
+WQ+CuI2TxgYkBbYFNjn9JqgdMF7FzaiojKAHBgUrgQQAI6GBiQOBhgAEAFTM8TKG
+xexxmfAGuyl/Tpk4wytB/OyuVfkF+Q3H1v17HLcpMacA5xUFr80+D5XnjxGttBsS
++X0uexR7QbPbhhPqADgQzFqvTsB1mUNAZnJBD6QNCZkfWwRRwFYQWSmisb43H6G3
+iUTKqiCXMXO8drKLA+Wi+L7VyfoI1CvatBBlDHbV
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..17b9a1d834
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBABUzPEyhsXscZnwBrspf06ZOMMrQfzsrlX5BfkNx9b9exy3KTGnAOcVBa/NPg+V548RrbQbEvl9LnsUe0Gz24YT6gA4EMxar07AdZlDQGZyQQ+kDQmZH1sEUcBWEFkporG+Nx+ht4lEyqoglzFzvHayiwPlovi+1cn6CNQr2rQQZQx21Q== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index 733414e23a..62e2a585e4 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -46,11 +46,17 @@
exec_key_differs2/1,
exec_key_differs3/1,
exec_key_differs_fail/1,
- idle_time/1,
+ idle_time_client/1,
+ idle_time_server/1,
inet6_option/1,
inet_option/1,
internal_error/1,
- known_hosts/1,
+ known_hosts/1,
+ login_bad_pwd_no_retry1/1,
+ login_bad_pwd_no_retry2/1,
+ login_bad_pwd_no_retry3/1,
+ login_bad_pwd_no_retry4/1,
+ login_bad_pwd_no_retry5/1,
misc_ssh_options/1,
openssh_zlib_basic_test/1,
packet_size_zero/1,
@@ -62,7 +68,8 @@
shell_unicode_string/1,
ssh_info_print/1,
key_callback/1,
- key_callback_options/1
+ key_callback_options/1,
+ shell_exit_status/1
]).
%%% Common test callbacks
@@ -100,7 +107,9 @@ all() ->
daemon_opt_fd,
multi_daemon_opt_fd,
packet_size_zero,
- ssh_info_print
+ ssh_info_print,
+ {group, login_bad_pwd_no_retry},
+ shell_exit_status
].
groups() ->
@@ -116,7 +125,13 @@ groups() ->
{dsa_pass_key, [], [pass_phrase]},
{rsa_pass_key, [], [pass_phrase]},
{key_cb, [], [key_callback, key_callback_options]},
- {internal_error, [], [internal_error]}
+ {internal_error, [], [internal_error]},
+ {login_bad_pwd_no_retry, [], [login_bad_pwd_no_retry1,
+ login_bad_pwd_no_retry2,
+ login_bad_pwd_no_retry3,
+ login_bad_pwd_no_retry4,
+ login_bad_pwd_no_retry5
+ ]}
].
@@ -125,7 +140,7 @@ basic_tests() ->
exec, exec_compressed,
shell, shell_no_unicode, shell_unicode_string,
cli, known_hosts,
- idle_time, openssh_zlib_basic_test,
+ idle_time_client, idle_time_server, openssh_zlib_basic_test,
misc_ssh_options, inet_option, inet6_option].
@@ -138,15 +153,27 @@ end_per_suite(_Config) ->
%%--------------------------------------------------------------------
init_per_group(dsa_key, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_dsa(DataDir, PrivDir),
- Config;
+ case lists:member('ssh-dss',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
init_per_group(rsa_key, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_rsa(DataDir, PrivDir),
- Config;
+ case lists:member('ssh-rsa',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ ssh_test_lib:setup_rsa(DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
init_per_group(ecdsa_sha2_nistp256_key, Config) ->
case lists:member('ecdsa-sha2-nistp256',
ssh_transport:default_algorithms(public_key)) of
@@ -181,15 +208,27 @@ init_per_group(ecdsa_sha2_nistp521_key, Config) ->
{skip, unsupported_pub_key}
end;
init_per_group(rsa_pass_key, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_rsa_pass_pharse(DataDir, PrivDir, "Password"),
- [{pass_phrase, {rsa_pass_phrase, "Password"}}| Config];
+ case lists:member('ssh-rsa',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ ssh_test_lib:setup_rsa_pass_pharse(DataDir, PrivDir, "Password"),
+ [{pass_phrase, {rsa_pass_phrase, "Password"}}| Config];
+ false ->
+ {skip, unsupported_pub_key}
+ end;
init_per_group(dsa_pass_key, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_dsa_pass_pharse(DataDir, PrivDir, "Password"),
- [{pass_phrase, {dsa_pass_phrase, "Password"}}| Config];
+ case lists:member('ssh-dss',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ ssh_test_lib:setup_dsa_pass_pharse(DataDir, PrivDir, "Password"),
+ [{pass_phrase, {dsa_pass_phrase, "Password"}}| Config];
+ false ->
+ {skip, unsupported_pub_key}
+ end;
init_per_group(host_user_key_differs, Config) ->
Data = proplists:get_value(data_dir, Config),
Sys = filename:join(proplists:get_value(priv_dir, Config), system_rsa),
@@ -206,10 +245,16 @@ init_per_group(host_user_key_differs, Config) ->
ssh_test_lib:setup_rsa_known_host(Sys, Usr),
Config;
init_per_group(key_cb, Config) ->
- DataDir = proplists:get_value(data_dir, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_dsa(DataDir, PrivDir),
- Config;
+ case lists:member('ssh-rsa',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ ssh_test_lib:setup_rsa(DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
init_per_group(internal_error, Config) ->
DataDir = proplists:get_value(data_dir, Config),
PrivDir = proplists:get_value(priv_dir, Config),
@@ -279,7 +324,7 @@ end_per_group(rsa_pass_key, Config) ->
Config;
end_per_group(key_cb, Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:clean_dsa(PrivDir),
+ ssh_test_lib:clean_rsa(PrivDir),
Config;
end_per_group(internal_error, Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
@@ -301,9 +346,9 @@ init_per_testcase(TC, Config) when TC==shell_no_unicode ;
{user_passwords, [{"foo", "bar"}]}]),
ct:sleep(500),
IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir,
- [{silently_accept_hosts, true},
- {user,"foo"},{password,"bar"}]),
+ Shell = ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir},
+ {silently_accept_hosts, true},
+ {user,"foo"},{password,"bar"}]),
ct:log("IO=~p, Shell=~p, self()=~p",[IO,Shell,self()]),
ct:log("file:native_name_encoding() = ~p,~nio:getopts() = ~p",
[file:native_name_encoding(),io:getopts()]),
@@ -329,14 +374,15 @@ end_per_testcase(TC, Config) when TC==shell_no_unicode ;
TC==shell_unicode_string ->
case proplists:get_value(sftpd, Config) of
{Pid, _, _} ->
- ssh:stop_daemon(Pid),
- ssh:stop();
+ catch ssh:stop_daemon(Pid);
_ ->
- ssh:stop()
- end;
+ ok
+ end,
+ end_per_testcase(Config);
end_per_testcase(_TestCase, Config) ->
end_per_testcase(Config).
-end_per_testcase(_Config) ->
+
+end_per_testcase(_Config) ->
ssh:stop(),
ok.
@@ -477,8 +523,8 @@ exec_compressed(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-%%% Idle timeout test
-idle_time(Config) ->
+%%% Idle timeout test, client
+idle_time_client(Config) ->
SystemDir = filename:join(proplists:get_value(priv_dir, Config), system),
UserDir = proplists:get_value(priv_dir, Config),
@@ -499,6 +545,28 @@ idle_time(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
+%%% Idle timeout test, server
+idle_time_server(Config) ->
+ SystemDir = filename:join(proplists:get_value(priv_dir, Config), system),
+ UserDir = proplists:get_value(priv_dir, Config),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {idle_time, 2000},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ {ok, Id} = ssh_connection:session_channel(ConnectionRef, 1000),
+ ssh_connection:close(ConnectionRef, Id),
+ receive
+ after 10000 ->
+ {error, closed} = ssh_connection:session_channel(ConnectionRef, 1000)
+ end,
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
%%% Test that ssh:shell/2 works
shell(Config) when is_list(Config) ->
process_flag(trap_exit, true),
@@ -510,7 +578,7 @@ shell(Config) when is_list(Config) ->
ct:sleep(500),
IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir),
+ Shell = ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir}]),
receive
{'EXIT', _, _} ->
ct:fail(no_ssh_connection);
@@ -544,14 +612,14 @@ exec_key_differs(Config, UserPKAlgs) ->
{_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
{user_dir, SystemUserDir},
{preferred_algorithms,
- [{public_key,['ssh-rsa']}]}]),
+ [{public_key,['ssh-rsa'|UserPKAlgs]}]}]),
ct:sleep(500),
IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir,
- [{preferred_algorithms,[{public_key,['ssh-rsa']}]},
- {pref_public_key_algs,UserPKAlgs}
- ]),
+ Shell = ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir},
+ {preferred_algorithms,[{public_key,['ssh-rsa']}]},
+ {pref_public_key_algs,UserPKAlgs}
+ ]),
receive
@@ -582,9 +650,10 @@ exec_key_differs_fail(Config) when is_list(Config) ->
ct:sleep(500),
IO = ssh_test_lib:start_io_server(),
- ssh_test_lib:start_shell(Port, IO, UserDir,
- [{preferred_algorithms,[{public_key,['ssh-rsa']}]},
- {pref_public_key_algs,['ssh-dss']}]),
+ ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir},
+ {recv_ext_info, false},
+ {preferred_algorithms,[{public_key,['ssh-rsa']}]},
+ {pref_public_key_algs,['ssh-dss']}]),
receive
{'EXIT', _, _} ->
ok;
@@ -674,7 +743,8 @@ known_hosts(Config) when is_list(Config) ->
Lines = string:tokens(binary_to_list(Binary), "\n"),
[Line] = Lines,
[HostAndIp, Alg, _KeyData] = string:tokens(Line, " "),
- [Host, _Ip] = string:tokens(HostAndIp, ","),
+ [StoredHost, _Ip] = string:tokens(HostAndIp, ","),
+ true = ssh_test_lib:match_ip(StoredHost, Host),
"ssh-" ++ _ = Alg,
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
@@ -735,7 +805,7 @@ key_callback_options(Config) when is_list(Config) ->
{user_dir, UserDir},
{failfun, fun ssh_test_lib:failfun/2}]),
- {ok, PrivKey} = file:read_file(filename:join(UserDir, "id_dsa")),
+ {ok, PrivKey} = file:read_file(filename:join(UserDir, "id_rsa")),
ConnectOpts = [{silently_accept_hosts, true},
{user_dir, NoPubKeyDir},
@@ -1090,6 +1160,96 @@ ssh_info_print(Config) ->
%%--------------------------------------------------------------------
+%% Check that a basd pwd is not tried more times. Could cause lock-out
+%% on server
+
+login_bad_pwd_no_retry1(Config) ->
+ login_bad_pwd_no_retry(Config, "keyboard-interactive,password").
+
+login_bad_pwd_no_retry2(Config) ->
+ login_bad_pwd_no_retry(Config, "password,keyboard-interactive").
+
+login_bad_pwd_no_retry3(Config) ->
+ login_bad_pwd_no_retry(Config, "password,publickey,keyboard-interactive").
+
+login_bad_pwd_no_retry4(Config) ->
+ login_bad_pwd_no_retry(Config, "password,keyboard-interactive").
+
+login_bad_pwd_no_retry5(Config) ->
+ login_bad_pwd_no_retry(Config, "password,keyboard-interactive,password,password").
+
+
+login_bad_pwd_no_retry(Config, AuthMethods) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = proplists:get_value(data_dir, Config),
+
+ Parent = self(),
+ PwdFun = fun(_, _, _, undefined) -> {false, 1};
+ (_, _, _, _) -> Parent ! retry_bad_pwd,
+ false
+ end,
+
+ {DaemonRef, _Host, Port} =
+ ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {auth_methods, AuthMethods},
+ {user_passwords, [{"foo","somepwd"}]},
+ {pwdfun, PwdFun}
+ ]),
+
+ ConnRes = ssh:connect("localhost", Port,
+ [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "badpwd"},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+
+ receive
+ retry_bad_pwd ->
+ ssh:stop_daemon(DaemonRef),
+ {fail, "Retry bad password"}
+ after 0 ->
+ case ConnRes of
+ {error,"Unable to connect using the available authentication methods"} ->
+ ssh:stop_daemon(DaemonRef),
+ ok;
+ {ok,Conn} ->
+ ssh:close(Conn),
+ ssh:stop_daemon(DaemonRef),
+ {fail, "Connect erroneosly succeded"}
+ end
+ end.
+
+
+%%----------------------------------------------------------------------------
+%%% Test that when shell REPL exit with reason normal client receives status 0
+shell_exit_status(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = proplists:get_value(data_dir, Config),
+ UserDir = proplists:get_value(priv_dir, Config),
+
+ ShellFun = fun (_User) -> spawn(fun() -> ok end) end,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {user_passwords, [{"vego", "morot"}]},
+ {shell, ShellFun},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user, "vego"},
+ {password, "morot"},
+ {user_interaction, false}]),
+
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ ok = ssh_connection:shell(ConnectionRef, ChannelId),
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
%% Due to timing the error message may or may not be delivered to
@@ -1098,7 +1258,7 @@ check_error("Invalid state") ->
ok;
check_error("Connection closed") ->
ok;
-check_error("Selection of key exchange algorithm failed") ->
+check_error("Selection of key exchange algorithm failed"++_) ->
ok;
check_error(Error) ->
ct:fail(Error).
@@ -1204,13 +1364,25 @@ new_do_shell(IO, N, Ops=[{Order,Arg}|More]) ->
ct:log("Skip newline ~p",[_X]),
new_do_shell(IO, N, Ops);
- <<Pfx:PfxSize/binary,P1,"> ">> when (P1-$0)==N ->
+ <<P1,"> ">> when (P1-$0)==N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+ <<"(",Pfx:PfxSize/binary,")",P1,"> ">> when (P1-$0)==N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+ <<"('",Pfx:PfxSize/binary,"')",P1,"> ">> when (P1-$0)==N ->
new_do_shell_prompt(IO, N, Order, Arg, More);
- <<Pfx:PfxSize/binary,P1,P2,"> ">> when (P1-$0)*10 + (P2-$0) == N ->
+ <<P1,P2,"> ">> when (P1-$0)*10 + (P2-$0) == N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+ <<"(",Pfx:PfxSize/binary,")",P1,P2,"> ">> when (P1-$0)*10 + (P2-$0) == N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+ <<"('",Pfx:PfxSize/binary,"')",P1,P2,"> ">> when (P1-$0)*10 + (P2-$0) == N ->
new_do_shell_prompt(IO, N, Order, Arg, More);
- <<Pfx:PfxSize/binary,P1,P2,P3,"> ">> when (P1-$0)*100 + (P2-$0)*10 + (P3-$0) == N ->
+ <<P1,P2,P3,"> ">> when (P1-$0)*100 + (P2-$0)*10 + (P3-$0) == N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+ <<"(",Pfx:PfxSize/binary,")",P1,P2,P3,"> ">> when (P1-$0)*100 + (P2-$0)*10 + (P3-$0) == N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+ <<"('",Pfx:PfxSize/binary,"')",P1,P2,P3,"> ">> when (P1-$0)*100 + (P2-$0)*10 + (P3-$0) == N ->
new_do_shell_prompt(IO, N, Order, Arg, More);
Err when element(1,Err)==error ->
@@ -1246,7 +1418,7 @@ prompt_prefix() ->
case node() of
nonode@nohost -> <<>>;
Node -> list_to_binary(
- lists:concat(["(",Node,")"]))
+ atom_to_list(Node))
end.
diff --git a/lib/ssh/test/ssh_bench.spec b/lib/ssh/test/ssh_bench.spec
index 029f0bd074..b0b64713cf 100644
--- a/lib/ssh/test/ssh_bench.spec
+++ b/lib/ssh/test/ssh_bench.spec
@@ -1 +1,2 @@
-{suites,"../ssh_test",[ssh_benchmark_SUITE]}.
+{suites,"../ssh_test",[ssh_bench_SUITE
+ ]}.
diff --git a/lib/ssh/test/ssh_bench_SUITE.erl b/lib/ssh/test/ssh_bench_SUITE.erl
new file mode 100644
index 0000000000..2c0cd8fc8e
--- /dev/null
+++ b/lib/ssh/test/ssh_bench_SUITE.erl
@@ -0,0 +1,252 @@
+%%%-------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(ssh_bench_SUITE).
+-compile(export_all).
+
+-include_lib("common_test/include/ct_event.hrl").
+-include_lib("common_test/include/ct.hrl").
+
+-include_lib("ssh/src/ssh.hrl").
+-include_lib("ssh/src/ssh_transport.hrl").
+-include_lib("ssh/src/ssh_connect.hrl").
+-include_lib("ssh/src/ssh_userauth.hrl").
+
+%%%================================================================
+%%%
+%%% Suite declarations
+%%%
+
+suite() -> [{ct_hooks,[{ts_install_cth,[{nodenames,2}]}]},
+ {timetrap,{minutes,1}}
+ ].
+all() -> [connect,
+ transfer_text
+ ].
+
+-define(UID, "foo").
+-define(PWD, "bar").
+-define(Nruns, 8).
+
+%%%================================================================
+%%%
+%%% Init per suite
+%%%
+
+init_per_suite(Config) ->
+ catch ssh:stop(),
+ try
+ ok = ssh:start()
+ of
+ ok ->
+ DataSize = 1000000,
+ SystemDir = proplists:get_value(data_dir, Config),
+ Algs = insert_none(ssh:default_algorithms()),
+ {_ServerPid, _Host, Port} =
+ ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_passwords, [{?UID,?PWD}]},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {preferred_algorithms, Algs},
+ {max_random_length_padding, 0},
+ {subsystems, [{"/dev/null", {ssh_bench_dev_null,[DataSize]}}]}
+ ]),
+ [{host,"localhost"}, {port,Port}, {uid,?UID}, {pwd,?PWD}, {data_size,DataSize} | Config]
+ catch
+ C:E ->
+ {skip, io_lib:format("Couldn't start ~p:~p",[C,E])}
+ end.
+
+end_per_suite(_Config) ->
+ catch ssh:stop(),
+ ok.
+
+%%%================================================================
+%%%
+%%% Init per testcase
+%%%
+
+init_per_testcase(_Func, Conf) ->
+ Conf.
+
+end_per_testcase(_Func, _Conf) ->
+ ok.
+
+%%%================================================================
+%%%
+%%% Testcases
+%%%
+
+%%%----------------------------------------------------------------
+%%% Measure the time for an Erlang client to connect to an Erlang
+%%% server on the localhost
+
+connect(Config) ->
+ KexAlgs = proplists:get_value(kex, ssh:default_algorithms()),
+ ct:log("KexAlgs = ~p",[KexAlgs]),
+ lists:foreach(
+ fun(KexAlg) ->
+ PrefAlgs = preferred_algorithms(KexAlg),
+ report([{value, measure_connect(Config,
+ [{preferred_algorithms,PrefAlgs}])},
+ {suite, ?MODULE},
+ {name, mk_name(["Connect erlc erld ",KexAlg," [µs]"])}
+ ])
+ end, KexAlgs).
+
+
+measure_connect(Config, Opts) ->
+ Port = proplists:get_value(port, Config),
+ ConnectOptions = [{user, proplists:get_value(uid, Config)},
+ {password, proplists:get_value(pwd, Config)},
+ {user_dir, proplists:get_value(priv_dir, Config)},
+ {silently_accept_hosts, true},
+ {user_interaction, false},
+ {max_random_length_padding, 0}
+ ] ++ Opts,
+ median(
+ [begin
+ {Time, {ok,Pid}} = timer:tc(ssh,connect,["localhost", Port, ConnectOptions]),
+ ssh:close(Pid),
+ Time
+ end || _ <- lists:seq(1,?Nruns)]).
+
+%%%----------------------------------------------------------------
+%%% Measure the time to transfer a set of data with
+%%% and without crypto
+
+transfer_text(Config) ->
+ Port = proplists:get_value(port, Config),
+ Options = [{user, proplists:get_value(uid, Config)},
+ {password, proplists:get_value(pwd, Config)},
+ {user_dir, proplists:get_value(priv_dir, Config)},
+ {silently_accept_hosts, true},
+ {user_interaction, false},
+ {max_random_length_padding, 0}
+ ],
+ Data = gen_data(proplists:get_value(data_size,Config)),
+
+ [connect_measure(Port, Crypto, Mac, Data, Options)
+ || {Crypto,Mac} <- [{ none, none},
+ {'aes128-ctr', 'hmac-sha1'},
+ {'aes256-ctr', 'hmac-sha1'},
+%% {'[email protected]', 'hmac-sha1'},
+ {'aes128-cbc', 'hmac-sha1'},
+ {'3des-cbc', 'hmac-sha1'},
+ {'aes128-ctr', 'hmac-sha2-256'},
+ {'aes128-ctr', 'hmac-sha2-512'}
+ ],
+ crypto_mac_supported(Crypto,Mac)].
+
+
+crypto_mac_supported(none, none) ->
+ true;
+crypto_mac_supported(C, M) ->
+ Algs = ssh:default_algorithms(),
+ [{_,Cs},_] = proplists:get_value(cipher, Algs),
+ [{_,Ms},_] = proplists:get_value(mac, Algs),
+ lists:member(C,Cs) andalso lists:member(M,Ms).
+
+
+gen_data(DataSz) ->
+ Data0 = << <<C>> || _ <- lists:seq(1,DataSz div 256),
+ C <- lists:seq(0,255) >>,
+ Data1 = << <<C>> || C <- lists:seq(0,(DataSz rem 256) - 1) >>,
+ <<Data0/binary, Data1/binary>>.
+
+
+%% connect_measure(Port, Cipher, Mac, Data, Options) ->
+%% report([{value, 1},
+%% {suite, ?MODULE},
+%% {name, mk_name(["Transfer 1M bytes ",Cipher,"/",Mac," [µs]"])}]);
+connect_measure(Port, Cipher, Mac, Data, Options) ->
+ Times =
+ [begin
+ {ok,C} = ssh:connect("localhost", Port, [{preferred_algorithms, [{cipher,[Cipher]},
+ {mac,[Mac]}]}
+ |Options]),
+ {ok,Ch} = ssh_connection:session_channel(C, 10000),
+ success = ssh_connection:subsystem(C, Ch, "/dev/null", 10000),
+ {Time,ok} = timer:tc(?MODULE, send_wait_acc, [C, Ch, Data]),
+ ok = ssh_connection:send_eof(C, Ch),
+ ssh:close(C),
+ Time
+ end || _ <- lists:seq(1,?Nruns)],
+
+ report([{value, median(Times)},
+ {suite, ?MODULE},
+ {name, mk_name(["Transfer 1M bytes ",Cipher,"/",Mac," [µs]"])}]).
+
+send_wait_acc(C, Ch, Data) ->
+ ssh_connection:send(C, Ch, Data),
+ receive
+ {ssh_cm, C, {data, Ch, 0, <<"READY">>}} -> ok
+ end.
+
+
+%%%================================================================
+%%%
+%%% Private
+%%%
+
+%%%----------------------------------------------------------------
+insert_none(L) ->
+ lists:foldl(fun insert_none/2, [], L).
+
+insert_none({T,L}, Acc) when T==cipher ;
+ T==mac ->
+ [{T, [{T1,L1++[none]} || {T1,L1} <- L]} | Acc];
+insert_none(_, Acc) ->
+ Acc.
+
+%%%----------------------------------------------------------------
+mk_name(Name) -> [char(C) || C <- lists:concat(Name)].
+
+char($-) -> $_;
+char(C) -> C.
+
+%%%----------------------------------------------------------------
+preferred_algorithms(KexAlg) ->
+ [{kex, [KexAlg]},
+ {public_key, ['ssh-rsa']},
+ {cipher, ['aes128-ctr']},
+ {mac, ['hmac-sha1']},
+ {compression, [none]}
+ ].
+
+%%%----------------------------------------------------------------
+median(Data) when is_list(Data) ->
+ SortedData = lists:sort(Data),
+ N = length(Data),
+ Median =
+ case N rem 2 of
+ 0 ->
+ MeanOfMiddle = (lists:nth(N div 2, SortedData) +
+ lists:nth(N div 2 + 1, SortedData)) / 2,
+ round(MeanOfMiddle);
+ 1 ->
+ lists:nth(N div 2 + 1, SortedData)
+ end,
+ ct:log("median(~p) = ~p",[SortedData,Median]),
+ Median.
+
+
+report(Data) ->
+ ct:log("EventData = ~p",[Data]),
+ ct_event:notify(#event{name = benchmark_data,
+ data = Data}).
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_dsa b/lib/ssh/test/ssh_bench_SUITE_data/id_dsa
index d306f8b26e..d306f8b26e 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/id_dsa
+++ b/lib/ssh/test/ssh_bench_SUITE_data/id_dsa
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa256
index 4b1eb12eaa..4b1eb12eaa 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256
+++ b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa256
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa256.pub
index a0147e60fa..a0147e60fa 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256.pub
+++ b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa256.pub
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa384
index 4e8aa40959..4e8aa40959 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384
+++ b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa384
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa384.pub
index 41e722e545..41e722e545 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384.pub
+++ b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa384.pub
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa521
index 7196f46e97..7196f46e97 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521
+++ b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa521
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa521.pub
index 8f059120bc..8f059120bc 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521.pub
+++ b/lib/ssh/test/ssh_bench_SUITE_data/id_ecdsa521.pub
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_rsa b/lib/ssh/test/ssh_bench_SUITE_data/id_rsa
index 9d7e0dd5fb..9d7e0dd5fb 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/id_rsa
+++ b/lib/ssh/test/ssh_bench_SUITE_data/id_rsa
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_dsa_key
index 51ab6fbd88..51ab6fbd88 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key
+++ b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_dsa_key
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_dsa_key.pub
index 4dbb1305b0..4dbb1305b0 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key.pub
+++ b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_dsa_key.pub
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key256
index 2979ea88ed..2979ea88ed 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256
+++ b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key256
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key256.pub
index 85dc419345..85dc419345 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256.pub
+++ b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key256.pub
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key384
index fb1a862ded..fb1a862ded 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384
+++ b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key384
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key384.pub
index 428d5fb7d7..428d5fb7d7 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384.pub
+++ b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key384.pub
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key521
index 3e51ec2ecd..3e51ec2ecd 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521
+++ b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key521
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key521.pub
index 017a29f4da..017a29f4da 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521.pub
+++ b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_ecdsa_key521.pub
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_rsa_key
index 79968bdd7d..79968bdd7d 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key
+++ b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_rsa_key
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_rsa_key.pub
index 75d2025c71..75d2025c71 100644
--- a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key.pub
+++ b/lib/ssh/test/ssh_bench_SUITE_data/ssh_host_rsa_key.pub
diff --git a/lib/ssh/test/ssh_bench_dev_null.erl b/lib/ssh/test/ssh_bench_dev_null.erl
new file mode 100644
index 0000000000..5166247714
--- /dev/null
+++ b/lib/ssh/test/ssh_bench_dev_null.erl
@@ -0,0 +1,58 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+%%% Description: Example ssh server
+-module(ssh_bench_dev_null).
+-behaviour(ssh_daemon_channel).
+
+-record(state, {
+ cm,
+ chid,
+ n,
+ sum = 0
+ }).
+
+-export([init/1, handle_msg/2, handle_ssh_msg/2, terminate/2]).
+
+init([N]) -> {ok, #state{n=N}}.
+
+handle_msg({ssh_channel_up, ChId, CM}, S) ->
+ {ok, S#state{cm = CM,
+ chid = ChId}}.
+
+
+
+handle_ssh_msg({ssh_cm, CM, {data,ChId,0,Data}}, #state{n=N, sum=Sum0, cm=CM, chid=ChId} = S) ->
+ Sum = Sum0 + size(Data),
+ if Sum == N ->
+ %% Got all
+ ssh_connection:send(CM, ChId, <<"READY">>),
+ {ok, S#state{sum=Sum}};
+ Sum < N ->
+ %% Expects more
+ {ok, S#state{sum=Sum}}
+ end;
+handle_ssh_msg({ssh_cm, _, {exit_signal,ChId,_,_,_}}, S) -> {stop, ChId, S};
+handle_ssh_msg({ssh_cm, _, {exit_status,ChId,_} }, S) -> {stop, ChId, S};
+handle_ssh_msg({ssh_cm, _, _ }, S) -> {ok, S}.
+
+terminate(_, _) -> ok.
diff --git a/lib/ssh/test/ssh_benchmark_SUITE.erl b/lib/ssh/test/ssh_benchmark_SUITE.erl
deleted file mode 100644
index c2bfc48449..0000000000
--- a/lib/ssh/test/ssh_benchmark_SUITE.erl
+++ /dev/null
@@ -1,563 +0,0 @@
-%%%-------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(ssh_benchmark_SUITE).
--compile(export_all).
-
--include_lib("common_test/include/ct_event.hrl").
--include_lib("common_test/include/ct.hrl").
-
--include_lib("ssh/src/ssh.hrl").
--include_lib("ssh/src/ssh_transport.hrl").
--include_lib("ssh/src/ssh_connect.hrl").
--include_lib("ssh/src/ssh_userauth.hrl").
-
-
-suite() -> [{ct_hooks,[{ts_install_cth,[{nodenames,2}]}]},
- {timetrap,{minutes,3}}
- ].
-%%suite() -> [{ct_hooks,[ts_install_cth]}].
-
-all() -> [{group, opensshc_erld}
-%% {group, erlc_opensshd}
- ].
-
-groups() ->
- [{opensshc_erld, [{repeat, 3}], [openssh_client_shell,
- openssh_client_sftp]}
- ].
-
-
-init_per_suite(Config) ->
- catch ssh:stop(),
- try
- report_client_algorithms(),
- ok = ssh:start(),
- {ok,TracerPid} = erlang_trace(),
- [{tracer_pid,TracerPid} | init_sftp_dirs(Config)]
- catch
- C:E ->
- {skip, io_lib:format("Couldn't start ~p:~p",[C,E])}
- end.
-
-end_per_suite(_Config) ->
- catch ssh:stop(),
- ok.
-
-
-
-init_per_group(opensshc_erld, Config) ->
- case ssh_test_lib:ssh_type() of
- openSSH ->
- DataDir = proplists:get_value(data_dir, Config),
- UserDir = proplists:get_value(priv_dir, Config),
- ssh_test_lib:setup_dsa(DataDir, UserDir),
- ssh_test_lib:setup_rsa(DataDir, UserDir),
- ssh_test_lib:setup_ecdsa("256", DataDir, UserDir),
- Common = ssh_test_lib:intersect_bi_dir(
- ssh_test_lib:intersection(ssh:default_algorithms(),
- ssh_test_lib:default_algorithms(sshc))),
- [{c_kexs, ssh_test_lib:sshc(kex)},
- {c_ciphers, ssh_test_lib:sshc(cipher)},
- {common_algs, Common}
- | Config];
- _ ->
- {skip, "No OpenSsh client found"}
- end;
-
-init_per_group(erlc_opensshd, _) ->
- {skip, "Group erlc_opensshd not implemented"};
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, _Config) ->
- ok.
-
-
-init_per_testcase(_Func, Conf) ->
- Conf.
-
-end_per_testcase(_Func, _Conf) ->
- ok.
-
-
-init_sftp_dirs(Config) ->
- UserDir = proplists:get_value(priv_dir, Config),
- SrcDir = filename:join(UserDir, "sftp_src"),
- ok = file:make_dir(SrcDir),
- SrcFile = "big_data",
- DstDir = filename:join(UserDir, "sftp_dst"),
- ok = file:make_dir(DstDir),
- N = 100 * 1024*1024,
- ok = file:write_file(filename:join(SrcDir,SrcFile), crypto:strong_rand_bytes(N)),
- [{sftp_src_dir,SrcDir}, {sftp_dst_dir,DstDir}, {src_file,SrcFile}, {sftp_size,N}
- | Config].
-
-%%%================================================================
-openssh_client_shell(Config) ->
- lists:foreach(
- fun(PrefAlgs=[{kex,[Kex]}]) when Kex == 'diffie-hellman-group-exchange-sha256' ->
- lists:foreach(
- fun(Grp) ->
- openssh_client_shell(Config,
- [{preferred_algorithms, PrefAlgs},
- {dh_gex_groups, [Grp]}
- ])
- end, moduli());
- (PrefAlgs) ->
- openssh_client_shell(Config,
- [{preferred_algorithms, PrefAlgs}])
- end, variants(kex,Config) ++ variants(cipher,Config)
- ).
-
-
-openssh_client_shell(Config, Options) ->
- SystemDir = proplists:get_value(data_dir, Config),
- UserDir = proplists:get_value(priv_dir, Config),
- KnownHosts = filename:join(UserDir, "known_hosts"),
-
- {ok, TracerPid} = erlang_trace(),
- {ServerPid, _Host, Port} =
- ssh_test_lib:daemon([{system_dir, SystemDir},
- {public_key_alg, ssh_dsa},
- {failfun, fun ssh_test_lib:failfun/2} |
- Options]),
- ct:sleep(500),
-
- Data = lists:duplicate(100000, $a),
- Cmd = lists:concat(["ssh -p ",Port,
- " -o UserKnownHostsFile=", KnownHosts,
- " -o \"StrictHostKeyChecking no\"",
- " localhost '\"",Data,"\"'."]),
-%% ct:pal("Cmd ="++Cmd),
-
- Parent = self(),
- SlavePid = spawn(fun() ->
- Parent ! {self(),os:cmd(Cmd)}
- end),
- receive
- {SlavePid, _ClientResponse} ->
-%% ct:pal("ClientResponse = ~p",[_ClientResponse]),
- {ok, List} = get_trace_list(TracerPid),
- Times = find_times(List, [accept_to_hello, kex, kex_to_auth, auth, to_prompt]),
- Algs = find_algs(List),
- ct:pal("Algorithms = ~p~n~nTimes = ~p",[Algs,Times]),
- lists:foreach(
- fun({Tag,Value,Unit}) ->
- EventData =
- case Tag of
- {A,B} when A==encrypt ; A==decrypt ->
- [{value, Value},
- {suite, ?MODULE},
- {name, mk_name(["Cipher ",A," ",B," [",Unit,"]"])}
- ];
- kex ->
- KexAlgStr = fmt_alg(Algs#alg.kex, List),
- [{value, Value},
- {suite, ?MODULE},
- {name, mk_name(["Erl server kex ",KexAlgStr," [",Unit,"]"])}
- ];
- _ when is_atom(Tag) ->
- [{value, Value},
- {suite, ?MODULE},
- {name, mk_name(["Erl server ",Tag," [",Unit,"]"])}
- ]
- end,
- ct:pal("ct_event:notify ~p",[EventData]),
- ct_event:notify(#event{name = benchmark_data,
- data = EventData})
- end, Times),
- ssh:stop_daemon(ServerPid),
- ok
- after 60*1000 ->
- ssh:stop_daemon(ServerPid),
- exit(SlavePid, kill),
- {fail, timeout}
- end.
-
-
-%%%================================================================
-openssh_client_sftp(Config) ->
- lists:foreach(
- fun(PrefAlgs) ->
- openssh_client_sftp(Config, [{preferred_algorithms,PrefAlgs}])
- end, variants(cipher,Config)).
-
-
-openssh_client_sftp(Config, Options) ->
- SystemDir = proplists:get_value(data_dir, Config),
- UserDir = proplists:get_value(priv_dir, Config),
- SftpSrcDir = proplists:get_value(sftp_src_dir, Config),
- SrcFile = proplists:get_value(src_file, Config),
- SrcSize = proplists:get_value(sftp_size, Config),
- KnownHosts = filename:join(UserDir, "known_hosts"),
-
- {ok, TracerPid} = erlang_trace(),
- {ServerPid, _Host, Port} =
- ssh_test_lib:daemon([{system_dir, SystemDir},
- {public_key_alg, ssh_dsa},
- {subsystems,[ssh_sftpd:subsystem_spec([%{cwd, SftpSrcDir},
- {root, SftpSrcDir}])]},
- {failfun, fun ssh_test_lib:failfun/2}
- | Options]),
- ct:pal("ServerPid = ~p",[ServerPid]),
- ct:sleep(500),
- Cmd = lists:concat(["sftp",
- " -b -",
- " -P ",Port,
- " -o UserKnownHostsFile=", KnownHosts,
- " -o \"StrictHostKeyChecking no\"",
- " localhost:",SrcFile
- ]),
-%% ct:pal("Cmd = ~p",[Cmd]),
-
- Parent = self(),
- SlavePid = spawn(fun() ->
- Parent ! {self(),os:cmd(Cmd)}
- end),
- receive
- {SlavePid, _ClientResponse} ->
- ct:pal("ClientResponse = ~p~nServerPid = ~p",[_ClientResponse,ServerPid]),
- {ok, List} = get_trace_list(TracerPid),
-%%ct:pal("List=~p",[List]),
- Times = find_times(List, [channel_open_close]),
- Algs = find_algs(List),
- ct:pal("Algorithms = ~p~n~nTimes = ~p",[Algs,Times]),
- lists:foreach(
- fun({{A,B},Value,Unit}) when A==encrypt ; A==decrypt ->
- Data = [{value, Value},
- {suite, ?MODULE},
- {name, mk_name(["Sftp Cipher ",A," ",B," [",Unit,"]"])}
- ],
- ct:pal("sftp ct_event:notify ~p",[Data]),
- ct_event:notify(#event{name = benchmark_data,
- data = Data});
- ({channel_open_close,Value,Unit}) ->
- Cipher = fmt_alg(Algs#alg.encrypt, List),
- Data = [{value, round( (1024*Value) / SrcSize )},
- {suite, ?MODULE},
- {name, mk_name(["Sftp transfer ",Cipher," [",Unit," per kbyte]"])}
- ],
- ct:pal("sftp ct_event:notify ~p",[Data]),
- ct_event:notify(#event{name = benchmark_data,
- data = Data});
- (_) ->
- skip
- end, Times),
- ssh:stop_daemon(ServerPid),
- ok
- after 2*60*1000 ->
- ssh:stop_daemon(ServerPid),
- exit(SlavePid, kill),
- {fail, timeout}
- end.
-
-%%%================================================================
-variants(Tag, Config) ->
- TagType =
- case proplists:get_value(Tag, ssh:default_algorithms()) of
- [{_,_}|_] -> one_way;
- [A|_] when is_atom(A) -> two_way
- end,
- [ [{Tag,tag_value(TagType,Alg)}]
- || Alg <- proplists:get_value(Tag, proplists:get_value(common_algs,Config))
- ].
-
-tag_value(two_way, Alg) -> [Alg];
-tag_value(one_way, Alg) -> [{client2server,[Alg]},
- {server2client,[Alg]}].
-
-%%%----------------------------------------------------------------
-fmt_alg(Alg, List) when is_atom(Alg) ->
- fmt_alg(atom_to_list(Alg), List);
-fmt_alg(Alg = "diffie-hellman-group-exchange-sha" ++ _, List) ->
- try
- integer_to_list(find_gex_size_string(List))
- of
- GexSize -> lists:concat([Alg," ",GexSize])
- catch
- _:_ -> Alg
- end;
-fmt_alg(Alg, _List) ->
- Alg.
-
-%%%----------------------------------------------------------------
-mk_name(Name) -> [char(C) || C <- lists:concat(Name)].
-
-char($-) -> $_;
-char(C) -> C.
-
-%%%----------------------------------------------------------------
-find_times(L, Xs) ->
- [find_time(X,L) || X <- Xs] ++
- function_algs_times_sizes([{ssh_transport,encrypt,2},
- {ssh_transport,decrypt,2},
- {ssh_message,decode,1},
- {ssh_message,encode,1}], L).
-
--record(call, {
- mfa,
- pid,
- t_call,
- t_return,
- args,
- result
- }).
-
-%%%----------------
--define(send(M), fun(C=#call{mfa = {ssh_message,encode,1},
- args = [M]}) ->
- C#call.t_return
- end).
-
--define(recv(M), fun(C=#call{mfa = {ssh_message,decode,1},
- result = M}) ->
- C#call.t_call
- end).
-
-find_time(accept_to_hello, L) ->
- [T0,T1] = find([fun(C=#call{mfa = {ssh_acceptor,handle_connection,5}}) ->
- C#call.t_call
- end,
- ?LINE,
- fun(C=#call{mfa = {ssh_connection_handler,handle_event,4},
- args = [_, {version_exchange,_}, {hello,_}, _]}) ->
- C#call.t_call
- end,
- ?LINE
- ], L, []),
- {accept_to_hello, now2micro_sec(now_diff(T1,T0)), microsec};
-find_time(kex, L) ->
- [T0,T1] = find([fun(C=#call{mfa = {ssh_connection_handler,handle_event,4},
- args = [_, {version_exchange,_}, {hello,_}, _]}) ->
- C#call.t_call
- end,
- ?LINE,
- ?send(#ssh_msg_newkeys{}),
- ?LINE
- ], L, []),
- {kex, now2micro_sec(now_diff(T1,T0)), microsec};
-find_time(kex_to_auth, L) ->
- [T0,T1] = find([?send(#ssh_msg_newkeys{}),
- ?LINE,
- ?recv(#ssh_msg_userauth_request{}),
- ?LINE
- ], L, []),
- {kex_to_auth, now2micro_sec(now_diff(T1,T0)), microsec};
-find_time(auth, L) ->
- [T0,T1] = find([?recv(#ssh_msg_userauth_request{}),
- ?LINE,
- ?send(#ssh_msg_userauth_success{}),
- ?LINE
- ], L, []),
- {auth, now2micro_sec(now_diff(T1,T0)), microsec};
-find_time(to_prompt, L) ->
- [T0,T1] = find([fun(C=#call{mfa = {ssh_acceptor,handle_connection,5}}) ->
- C#call.t_call
- end,
- ?LINE,
- ?recv(#ssh_msg_channel_request{request_type="env"}),
- ?LINE
- ], L, []),
- {to_prompt, now2micro_sec(now_diff(T1,T0)), microsec};
-find_time(channel_open_close, L) ->
- [T0,T1] = find([?recv(#ssh_msg_channel_request{request_type="subsystem"}),
- ?LINE,
- ?send(#ssh_msg_channel_close{}),
- ?LINE
- ], L, []),
- {channel_open_close, now2micro_sec(now_diff(T1,T0)), microsec}.
-
-
-
-find([F,Id|Fs], [C|Cs], Acc) when is_function(F,1) ->
- try
- F(C)
- of
- T -> find(Fs, Cs, [T|Acc])
- catch
- _:_ -> find([F,Id|Fs], Cs, Acc)
- end;
-find([], _, Acc) ->
- lists:reverse(Acc).
-
-
-find_algs(L) ->
- {value, #call{result={ok,Algs}}} =
- lists:keysearch({ssh_transport,select_algorithm,3}, #call.mfa, L),
- Algs.
-
-find_gex_size_string(L) ->
- %% server
- {value, #call{result={ok,{Size, _}}}} =
- lists:keysearch({public_key,dh_gex_group,4}, #call.mfa, L),
- Size.
-
-%%%----------------
-function_algs_times_sizes(EncDecs, L) ->
- Raw = [begin
- {Tag,Size} = function_ats_result(EncDec, C),
- {Tag, Size, now2micro_sec(now_diff(T1,T0))}
- end
- || EncDec <- EncDecs,
- C = #call{mfa = ED,
- % args = Args, %%[S,Data],
- t_call = T0,
- t_return = T1} <- L,
- ED == EncDec
- ],
- [{Alg, round(1024*Time/Size), "microsec per kbyte"} % Microseconds per 1k bytes.
- || {Alg,Size,Time} <- lists:foldl(fun increment/2, [], Raw)].
-
-function_ats_result({ssh_transport,encrypt,2}, #call{args=[S,Data]}) ->
- {{encrypt,S#ssh.encrypt}, size(Data)};
-function_ats_result({ssh_transport,decrypt,2}, #call{args=[S,Data]}) ->
- {{decrypt,S#ssh.decrypt}, size(Data)};
-function_ats_result({ssh_message,encode,1}, #call{result=Data}) ->
- {encode, size(Data)};
-function_ats_result({ssh_message,decode,1}, #call{args=[Data]}) ->
- {decode, size(Data)}.
-
-
-increment({Alg,Sz,T}, [{Alg,SumSz,SumT}|Acc]) ->
- [{Alg,SumSz+Sz,SumT+T} | Acc];
-increment(Spec, [X|Acc]) ->
- [X | increment(Spec,Acc)]; % Not so many Alg, 2 or 3
-increment({Alg,Sz,T},[]) ->
- [{Alg,Sz,T}].
-
-%%%----------------------------------------------------------------
-%%%
-%%% API for the traceing
-%%%
-get_trace_list(TracerPid) ->
- MonRef = monitor(process, TracerPid),
- TracerPid ! {get_trace_list,self()},
- receive
- {trace_list,L} ->
- demonitor(MonRef),
- {ok, pair_events(lists:reverse(L))};
- {'DOWN', MonRef, process, TracerPid, Info} ->
- {error, {tracer_down,Info}}
-
- after 3*60*1000 ->
- demonitor(MonRef),
- {error,no_reply}
- end.
-
-erlang_trace() ->
- TracerPid = spawn(fun trace_loop/0),
- 0 = erlang:trace(new, true, [call,timestamp,{tracer,TracerPid}]),
- [init_trace(MFA, tp(MFA))
- || MFA <- [{ssh_acceptor,handle_connection,5},
-%% {ssh_connection_handler,hello,2},
- {ssh_message,encode,1},
- {ssh_message,decode,1},
- {ssh_transport,select_algorithm,3},
- {ssh_transport,encrypt,2},
- {ssh_transport,decrypt,2},
- {ssh_message,encode,1},
- {ssh_message,decode,1},
- {public_key,dh_gex_group,4} % To find dh_gex group size
- ]],
- init_trace({ssh_connection_handler,handle_event,4},
- [{['_', {version_exchange,'_'}, {hello,'_'}, '_'],
- [],
- [return_trace]}]),
- {ok, TracerPid}.
-
-tp({_M,_F,Arity}) ->
- [{lists:duplicate(Arity,'_'), [], [{return_trace}]}].
-
-%%%----------------------------------------------------------------
-init_trace(MFA = {Module,_,_}, TP) ->
- case code:is_loaded(Module) of
- false -> code:load_file(Module);
- _ -> ok
- end,
- erlang:trace_pattern(MFA, TP, [local]).
-
-
-trace_loop() ->
- trace_loop([]).
-
-trace_loop(L) ->
- receive
- {get_trace_list, From} ->
- From ! {trace_list, L},
- trace_loop(L);
- Ev ->
- trace_loop([Ev|L])
- end.
-
-pair_events(L) ->
- pair_events(L, []).
-
-pair_events([{trace_ts,Pid,call,{M,F,Args},TS0} | L], Acc) ->
- Arity = length(Args),
- {ReturnValue,TS1} = find_return(Pid, {M,F,Arity}, L),
- pair_events(L, [#call{mfa = {M,F,Arity},
- pid = Pid,
- t_call = TS0,
- t_return = TS1,
- args = Args,
- result = ReturnValue} | Acc]);
-pair_events([_|L], Acc) ->
- pair_events(L, Acc);
-pair_events([], Acc) ->
- lists:reverse(Acc).
-
-
-find_return(Pid, MFA,
- [{trace_ts, Pid, return_from, MFA, ReturnValue, TS}|_]) ->
- {ReturnValue, TS};
-find_return(Pid, MFA, [_|L]) ->
- find_return(Pid, MFA, L);
-find_return(_, _, []) ->
- {undefined, undefined}.
-
-%%%----------------------------------------------------------------
-report_client_algorithms() ->
- try
- ssh_test_lib:extract_algos( ssh_test_lib:default_algorithms(sshc) )
- of
- ClientAlgs ->
- ct:pal("The client supports:~n~p",[ClientAlgs])
- catch
- Cls:Err ->
- ct:pal("Testing client about algorithms failed:~n~p ~p",[Cls,Err])
- end.
-
-%%%----------------------------------------------------------------
-
-
-now2sec({A,B,C}) -> A*1000000 + B + C/1000000.
-
-now2micro_sec({A,B,C}) -> (A*1000000 + B)*1000000 + C.
-
-now_diff({A1,B1,C1}, {A0,B0,C0}) -> {A1-A0, B1-B0, C1-C0}.
-
-%%%================================================================
-moduli() ->
- [{1023, 5, 16#CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D182EB7},
- {2047, 5, 16#F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE5E381EF},
- {4095, 2, 16#C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BA7321EB},
- {6143, 5, 16#FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23C3BEB637},
- {8191, 2, 16#DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE37347869A3}].
diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl
index bcf3b01824..9bbd9da817 100644
--- a/lib/ssh/test/ssh_connection_SUITE.erl
+++ b/lib/ssh/test/ssh_connection_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -89,7 +89,7 @@ end_per_suite(Config) ->
%%--------------------------------------------------------------------
init_per_group(openssh, Config) ->
- case gen_tcp:connect("localhost", 22, []) of
+ case ssh_test_lib:gen_tcp_connect("localhost", 22, []) of
{error,econnrefused} ->
{skip,"No openssh deamon"};
{ok, Socket} ->
@@ -126,7 +126,7 @@ simple_exec(Config) when is_list(Config) ->
simple_exec_sock(_Config) ->
- {ok, Sock} = gen_tcp:connect("localhost", ?SSH_DEFAULT_PORT, [{active,false}]),
+ {ok, Sock} = ssh_test_lib:gen_tcp_connect("localhost", ?SSH_DEFAULT_PORT, [{active,false}]),
{ok, ConnectionRef} = ssh:connect(Sock, [{silently_accept_hosts, true},
{user_interaction, false}]),
do_simple_exec(ConnectionRef).
@@ -179,13 +179,13 @@ daemon_sock_not_tcp(_Config) ->
%%--------------------------------------------------------------------
connect_sock_not_passive(_Config) ->
- {ok,Sock} = gen_tcp:connect("localhost", ?SSH_DEFAULT_PORT, []),
+ {ok,Sock} = ssh_test_lib:gen_tcp_connect("localhost", ?SSH_DEFAULT_PORT, []),
{error, not_passive_mode} = ssh:connect(Sock, []),
gen_tcp:close(Sock).
%%--------------------------------------------------------------------
daemon_sock_not_passive(_Config) ->
- {ok,Sock} = gen_tcp:connect("localhost", ?SSH_DEFAULT_PORT, []),
+ {ok,Sock} = ssh_test_lib:gen_tcp_connect("localhost", ?SSH_DEFAULT_PORT, []),
{error, not_passive_mode} = ssh:daemon(Sock),
gen_tcp:close(Sock).
@@ -381,13 +381,13 @@ do_interrupted_send(Config, SendSize, EchoSize) ->
{password, "morot"},
{subsystems, [{"echo_n",EchoSS_spec}]}]),
- ct:log("connect", []),
+ ct:log("~p:~p connect", [?MODULE,?LINE]),
ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
{user, "foo"},
{password, "morot"},
{user_interaction, false},
{user_dir, UserDir}]),
- ct:log("connected", []),
+ ct:log("~p:~p connected", [?MODULE,?LINE]),
%% build big binary
Data = << <<X:32>> || X <- lists:seq(1,SendSize div 4)>>,
@@ -399,58 +399,80 @@ do_interrupted_send(Config, SendSize, EchoSize) ->
Parent = self(),
ResultPid = spawn(
fun() ->
- ct:log("open channel",[]),
+ ct:log("~p:~p open channel",[?MODULE,?LINE]),
{ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
- ct:log("start subsystem", []),
+ ct:log("~p:~p start subsystem", [?MODULE,?LINE]),
case ssh_connection:subsystem(ConnectionRef, ChannelId, "echo_n", infinity) of
success ->
Parent ! {self(), channelId, ChannelId},
Result =
- try collect_data(ConnectionRef, ChannelId)
+ try collect_data(ConnectionRef, ChannelId, EchoSize)
of
ExpectedData ->
+ ct:log("~p:~p got expected data",[?MODULE,?LINE]),
ok;
- _ ->
- {fail,"unexpected result"}
+ Other ->
+ ct:log("~p:~p unexpect: ~p", [?MODULE,?LINE,Other]),
+ {fail,"unexpected result in listener"}
catch
Class:Exception ->
- {fail, io_lib:format("Exception ~p:~p",[Class,Exception])}
+ {fail, io_lib:format("Listener exception ~p:~p",[Class,Exception])}
end,
- Parent ! {self(), Result};
+ Parent ! {self(), result, Result};
Other ->
Parent ! {self(), channelId, error, Other}
end
end),
receive
+ {ResultPid, channelId, error, Other} ->
+ ct:log("~p:~p channelId error ~p", [?MODULE,?LINE,Other]),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid),
+ {fail, "ssh_connection:subsystem"};
+
{ResultPid, channelId, ChannelId} ->
- %% pre-adjust receive window so the other end doesn't block
- ct:log("adjust window", []),
- ssh_connection:adjust_window(ConnectionRef, ChannelId, size(ExpectedData) + 1),
-
- ct:log("going to send ~p bytes", [size(Data)]),
- case ssh_connection:send(ConnectionRef, ChannelId, Data, 30000) of
- {error, closed} ->
- ct:log("{error,closed} - That's what we expect :)", []),
- ok;
- Msg ->
- ct:log("Got ~p - that's bad, very bad indeed",[Msg]),
- ct:fail({expected,{error,closed}, got, Msg})
- end,
- ct:log("going to check the result (if it is available)", []),
+ ct:log("~p:~p ~p going to send ~p bytes", [?MODULE,?LINE,self(),size(Data)]),
+ SenderPid = spawn(fun() ->
+ Parent ! {self(), ssh_connection:send(ConnectionRef, ChannelId, Data, 30000)}
+ end),
receive
- {ResultPid, Result} ->
- ct:log("Got result: ~p", [Result]),
+ {ResultPid, result, {fail, Fail}} ->
+ ct:log("~p:~p Listener failed: ~p", [?MODULE,?LINE,Fail]),
+ {fail, Fail};
+
+ {ResultPid, result, Result} ->
+ ct:log("~p:~p Got result: ~p", [?MODULE,?LINE,Result]),
ssh:close(ConnectionRef),
ssh:stop_daemon(Pid),
- Result
- end;
+ ct:log("~p:~p Check sender", [?MODULE,?LINE]),
+ receive
+ {SenderPid, {error, closed}} ->
+ ct:log("~p:~p {error,closed} - That's what we expect :)",[?MODULE,?LINE]),
+ ok;
+ Msg ->
+ ct:log("~p:~p Not expected send result: ~p",[?MODULE,?LINE,Msg]),
+ {fail, "Not expected msg"}
+ end;
+
+ {SenderPid, {error, closed}} ->
+ ct:log("~p:~p {error,closed} - That's what we expect, but client channel handler has not reported yet",[?MODULE,?LINE]),
+ receive
+ {ResultPid, result, Result} ->
+ ct:log("~p:~p Now got the result: ~p", [?MODULE,?LINE,Result]),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid),
+ ok;
+ Msg ->
+ ct:log("~p:~p Got an unexpected msg ~p",[?MODULE,?LINE,Msg]),
+ {fail, "Un-expected msg"}
+ end;
- {ResultPid, channelId, error, Other} ->
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid),
- {fail, io_lib:format("ssh_connection:subsystem: ~p",[Other])}
+ Msg ->
+ ct:log("~p:~p Got unexpected ~p",[?MODULE,?LINE,Msg]),
+ {fail, "Unexpected msg"}
+ end
end.
%%--------------------------------------------------------------------
@@ -563,12 +585,13 @@ start_shell_sock_exec_fun(Config) when is_list(Config) ->
UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
file:make_dir(UserDir),
SysDir = proplists:get_value(data_dir, Config),
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "morot"},
- {exec, fun ssh_exec/1}]),
+ {Pid, HostD, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {exec, fun ssh_exec/1}]),
+ Host = ssh_test_lib:ntoa(ssh_test_lib:mangle_connect_address(HostD)),
- {ok, Sock} = gen_tcp:connect(Host, Port, [{active,false}]),
+ {ok, Sock} = ssh_test_lib:gen_tcp_connect(Host, Port, [{active,false}]),
{ok,ConnectionRef} = ssh:connect(Sock, [{silently_accept_hosts, true},
{user, "foo"},
{password, "morot"},
@@ -601,7 +624,7 @@ start_shell_sock_daemon_exec(Config) ->
{ok,{_IP,Port}} = inet:sockname(Sl), % _IP is likely to be {0,0,0,0}. Win don't like...
spawn_link(fun() ->
- {ok,Ss} = gen_tcp:connect("localhost", Port, [{active,false}]),
+ {ok,Ss} = ssh_test_lib:gen_tcp_connect("localhost", Port, [{active,false}]),
{ok, _Pid} = ssh:daemon(Ss, [{system_dir, SysDir},
{user_dir, UserDir},
{password, "morot"},
@@ -636,10 +659,10 @@ gracefull_invalid_version(Config) when is_list(Config) ->
SysDir = proplists:get_value(data_dir, Config),
{_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "morot"}]),
+ {user_dir, UserDir},
+ {password, "morot"}]),
- {ok, S} = gen_tcp:connect(Host, Port, []),
+ {ok, S} = ssh_test_lib:gen_tcp_connect(Host, Port, []),
ok = gen_tcp:send(S, ["SSH-8.-1","\r\n"]),
receive
Verstring ->
@@ -658,10 +681,10 @@ gracefull_invalid_start(Config) when is_list(Config) ->
file:make_dir(UserDir),
SysDir = proplists:get_value(data_dir, Config),
{_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "morot"}]),
+ {user_dir, UserDir},
+ {password, "morot"}]),
- {ok, S} = gen_tcp:connect(Host, Port, []),
+ {ok, S} = ssh_test_lib:gen_tcp_connect(Host, Port, []),
ok = gen_tcp:send(S, ["foobar","\r\n"]),
receive
Verstring ->
@@ -680,10 +703,10 @@ gracefull_invalid_long_start(Config) when is_list(Config) ->
file:make_dir(UserDir),
SysDir = proplists:get_value(data_dir, Config),
{_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "morot"}]),
+ {user_dir, UserDir},
+ {password, "morot"}]),
- {ok, S} = gen_tcp:connect(Host, Port, []),
+ {ok, S} = ssh_test_lib:gen_tcp_connect(Host, Port, []),
ok = gen_tcp:send(S, [lists:duplicate(257, $a), "\r\n"]),
receive
Verstring ->
@@ -703,10 +726,10 @@ gracefull_invalid_long_start_no_nl(Config) when is_list(Config) ->
file:make_dir(UserDir),
SysDir = proplists:get_value(data_dir, Config),
{_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "morot"}]),
+ {user_dir, UserDir},
+ {password, "morot"}]),
- {ok, S} = gen_tcp:connect(Host, Port, []),
+ {ok, S} = ssh_test_lib:gen_tcp_connect(Host, Port, []),
ok = gen_tcp:send(S, [lists:duplicate(257, $a), "\r\n"]),
receive
Verstring ->
@@ -757,22 +780,21 @@ stop_listener(Config) when is_list(Config) ->
ct:fail("Exec Timeout")
end,
- {ok, HostAddr} = inet:getaddr(Host, inet),
- case ssh_test_lib:daemon(HostAddr, Port, [{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "potatis"},
- {exec, fun ssh_exec/1}]) of
- {Pid1, HostAddr, Port} ->
+ case ssh_test_lib:daemon(Port, [{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "potatis"},
+ {exec, fun ssh_exec/1}]) of
+ {Pid1, Host, Port} ->
ConnectionRef1 = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
{user, "foo"},
{password, "potatis"},
{user_interaction, true},
{user_dir, UserDir}]),
{error, _} = ssh:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_interaction, true},
- {user_dir, UserDir}]),
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, true},
+ {user_dir, UserDir}]),
ssh:close(ConnectionRef0),
ssh:close(ConnectionRef1),
ssh:stop_daemon(Pid0),
@@ -909,36 +931,46 @@ big_cat_rx(ConnectionRef, ChannelId, Acc) ->
timeout
end.
-collect_data(ConnectionRef, ChannelId) ->
- ct:log("Listener ~p running! ConnectionRef=~p, ChannelId=~p",[self(),ConnectionRef,ChannelId]),
- collect_data(ConnectionRef, ChannelId, [], 0).
+collect_data(ConnectionRef, ChannelId, EchoSize) ->
+ ct:log("~p:~p Listener ~p running! ConnectionRef=~p, ChannelId=~p",[?MODULE,?LINE,self(),ConnectionRef,ChannelId]),
+ collect_data(ConnectionRef, ChannelId, EchoSize, [], 0).
-collect_data(ConnectionRef, ChannelId, Acc, Sum) ->
+collect_data(ConnectionRef, ChannelId, EchoSize, Acc, Sum) ->
TO = 5000,
receive
{ssh_cm, ConnectionRef, {data, ChannelId, 0, Data}} when is_binary(Data) ->
- ct:log("collect_data: received ~p bytes. total ~p bytes",[size(Data),Sum+size(Data)]),
- collect_data(ConnectionRef, ChannelId, [Data | Acc], Sum+size(Data));
- {ssh_cm, ConnectionRef, {eof, ChannelId}} ->
- try
- iolist_to_binary(lists:reverse(Acc))
- of
- Bin ->
- ct:log("collect_data: received eof.~nGot in total ~p bytes",[size(Bin)]),
- Bin
- catch
- C:E ->
- ct:log("collect_data: received eof.~nAcc is strange...~nException=~p:~p~nAcc=~p",
- [C,E,Acc]),
- {error,{C,E}}
- end;
+ ct:log("~p:~p collect_data: received ~p bytes. total ~p bytes, want ~p more",
+ [?MODULE,?LINE,size(Data),Sum+size(Data),EchoSize-Sum]),
+ ssh_connection:adjust_window(ConnectionRef, ChannelId, size(Data)),
+ collect_data(ConnectionRef, ChannelId, EchoSize, [Data | Acc], Sum+size(Data));
+ {ssh_cm, ConnectionRef, Msg={eof, ChannelId}} ->
+ collect_data_report_end(Acc, Msg, EchoSize);
+
+ {ssh_cm, ConnectionRef, Msg={closed,ChannelId}} ->
+ collect_data_report_end(Acc, Msg, EchoSize);
+
Msg ->
- ct:log("collect_data: ***** unexpected message *****~n~p",[Msg]),
- collect_data(ConnectionRef, ChannelId, Acc, Sum)
+ ct:log("~p:~p collect_data: ***** unexpected message *****~n~p",[?MODULE,?LINE,Msg]),
+ collect_data(ConnectionRef, ChannelId, EchoSize, Acc, Sum)
after TO ->
- ct:log("collect_data: ----- Nothing received for ~p seconds -----~n",[]),
- collect_data(ConnectionRef, ChannelId, Acc, Sum)
+ ct:log("~p:~p collect_data: ----- Nothing received for ~p seconds -----~n",[?MODULE,?LINE,TO]),
+ collect_data(ConnectionRef, ChannelId, EchoSize, Acc, Sum)
+ end.
+
+collect_data_report_end(Acc, Msg, EchoSize) ->
+ try
+ iolist_to_binary(lists:reverse(Acc))
+ of
+ Bin ->
+ ct:log("~p:~p collect_data: received ~p.~nGot in total ~p bytes, want ~p more",
+ [?MODULE,?LINE,Msg,size(Bin),EchoSize,size(Bin)]),
+ Bin
+ catch
+ C:E ->
+ ct:log("~p:~p collect_data: received ~p.~nAcc is strange...~nException=~p:~p~nAcc=~p",
+ [?MODULE,?LINE,Msg,C,E,Acc]),
+ {error,{C,E}}
end.
%%%-------------------------------------------------------------------
diff --git a/lib/ssh/test/ssh_eqc_event_handler.erl b/lib/ssh/test/ssh_eqc_event_handler.erl
new file mode 100644
index 0000000000..233965012a
--- /dev/null
+++ b/lib/ssh/test/ssh_eqc_event_handler.erl
@@ -0,0 +1,43 @@
+-module(ssh_eqc_event_handler).
+
+-compile(export_all).
+
+-behaviour(gen_event).
+
+add_report_handler() ->
+ error_logger:add_report_handler(?MODULE, [self(),Ref=make_ref()]),
+ receive
+ {event_handler_started,HandlerPid,Ref} ->
+ {ok,HandlerPid}
+ end.
+
+get_reports(Pid) ->
+ Pid ! {get_reports,self(),Ref=make_ref()},
+ receive
+ {reports,Reports,Ref} ->
+ {ok,Reports}
+ end.
+
+%%%================================================================
+
+-record(state, {
+ reports = []
+ }).
+
+%% error_logger:add_report_handler(ssh_eqc_event_handler, [self()]).
+
+init([CallerPid,Ref]) ->
+ CallerPid ! {event_handler_started,self(),Ref},
+ {ok, #state{}}.
+
+handle_event(Event, State) ->
+ {ok, State#state{reports = [Event|State#state.reports]}}.
+
+handle_info({get_reports,From,Ref}, State) ->
+ From ! {reports, lists:reverse(State#state.reports), Ref},
+ {ok, State#state{reports=[]}}.
+
+handle_call(_Request, State) -> {ok,reply,State}.
+terminate(_Arg, _State) -> stop.
+
+code_change(_OldVsn, State, _Extra) -> {ok, State}.
diff --git a/lib/ssh/test/ssh_key_cb.erl b/lib/ssh/test/ssh_key_cb.erl
index 388ec2ecc1..5564b9d873 100644
--- a/lib/ssh/test/ssh_key_cb.erl
+++ b/lib/ssh/test/ssh_key_cb.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,9 +33,9 @@ add_host_key(_, _, _) ->
is_host_key(_, _, _, _) ->
true.
-user_key('ssh-dss', Opts) ->
+user_key('ssh-rsa', Opts) ->
UserDir = proplists:get_value(user_dir, Opts),
- KeyFile = filename:join(filename:dirname(UserDir), "id_dsa"),
+ KeyFile = filename:join(filename:dirname(UserDir), "id_rsa"),
{ok, KeyBin} = file:read_file(KeyFile),
[Entry] = public_key:pem_decode(KeyBin),
Key = public_key:pem_entry_decode(Entry),
diff --git a/lib/ssh/test/ssh_key_cb_options.erl b/lib/ssh/test/ssh_key_cb_options.erl
index afccb34f0f..c104a2f129 100644
--- a/lib/ssh/test/ssh_key_cb_options.erl
+++ b/lib/ssh/test/ssh_key_cb_options.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ add_host_key(_, _, _) ->
is_host_key(_, _, _, _) ->
true.
-user_key('ssh-dss', Opts) ->
+user_key('ssh-rsa', Opts) ->
KeyCbOpts = proplists:get_value(key_cb_private, Opts),
KeyBin = proplists:get_value(priv_key, KeyCbOpts),
[Entry] = public_key:pem_decode(KeyBin),
diff --git a/lib/ssh/test/ssh_options_SUITE.erl b/lib/ssh/test/ssh_options_SUITE.erl
index 61883c0647..8b454ffe5d 100644
--- a/lib/ssh/test/ssh_options_SUITE.erl
+++ b/lib/ssh/test/ssh_options_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -61,7 +61,14 @@
unexpectedfun_option_client/1,
unexpectedfun_option_server/1,
user_dir_option/1,
- connectfun_disconnectfun_server/1
+ connectfun_disconnectfun_server/1,
+ hostkey_fingerprint_check/1,
+ hostkey_fingerprint_check_md5/1,
+ hostkey_fingerprint_check_sha/1,
+ hostkey_fingerprint_check_sha256/1,
+ hostkey_fingerprint_check_sha384/1,
+ hostkey_fingerprint_check_sha512/1,
+ hostkey_fingerprint_check_list/1
]).
%%% Common test callbacks
@@ -100,6 +107,13 @@ all() ->
disconnectfun_option_client,
unexpectedfun_option_server,
unexpectedfun_option_client,
+ hostkey_fingerprint_check,
+ hostkey_fingerprint_check_md5,
+ hostkey_fingerprint_check_sha,
+ hostkey_fingerprint_check_sha256,
+ hostkey_fingerprint_check_sha384,
+ hostkey_fingerprint_check_sha512,
+ hostkey_fingerprint_check_list,
id_string_no_opt_client,
id_string_own_string_client,
id_string_random_client,
@@ -136,6 +150,7 @@ init_per_group(hardening_tests, Config) ->
DataDir = proplists:get_value(data_dir, Config),
PrivDir = proplists:get_value(priv_dir, Config),
ssh_test_lib:setup_dsa(DataDir, PrivDir),
+ ssh_test_lib:setup_rsa(DataDir, PrivDir),
Config;
init_per_group(dir_options, Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
@@ -540,10 +555,18 @@ connectfun_disconnectfun_server(Config) ->
{disconnect,Ref,R} ->
ct:log("Disconnect result: ~p",[R]),
ssh:stop_daemon(Pid)
- after 2000 ->
+ after 10000 ->
+ receive
+ X -> ct:log("received ~p",[X])
+ after 0 -> ok
+ end,
{fail, "No disconnectfun action"}
end
- after 2000 ->
+ after 10000 ->
+ receive
+ X -> ct:log("received ~p",[X])
+ after 0 -> ok
+ end,
{fail, "No connectfun action"}
end.
@@ -649,7 +672,7 @@ disconnectfun_option_server(Config) ->
ct:log("Server detected disconnect: ~p",[Reason]),
ssh:stop_daemon(Pid),
ok
- after 3000 ->
+ after 5000 ->
receive
X -> ct:log("received ~p",[X])
after 0 -> ok
@@ -774,6 +797,106 @@ unexpectedfun_option_client(Config) ->
end.
%%--------------------------------------------------------------------
+hostkey_fingerprint_check(Config) ->
+ do_hostkey_fingerprint_check(Config, old).
+
+hostkey_fingerprint_check_md5(Config) ->
+ do_hostkey_fingerprint_check(Config, md5).
+
+hostkey_fingerprint_check_sha(Config) ->
+ do_hostkey_fingerprint_check(Config, sha).
+
+hostkey_fingerprint_check_sha256(Config) ->
+ do_hostkey_fingerprint_check(Config, sha256).
+
+hostkey_fingerprint_check_sha384(Config) ->
+ do_hostkey_fingerprint_check(Config, sha384).
+
+hostkey_fingerprint_check_sha512(Config) ->
+ do_hostkey_fingerprint_check(Config, sha512).
+
+hostkey_fingerprint_check_list(Config) ->
+ do_hostkey_fingerprint_check(Config, [sha,md5,sha256]).
+
+%%%----
+do_hostkey_fingerprint_check(Config, HashAlg) ->
+ case supported_hash(HashAlg) of
+ true ->
+ really_do_hostkey_fingerprint_check(Config, HashAlg);
+ false ->
+ {skip,{unsupported_hash,HashAlg}}
+ end.
+
+supported_hash(old) -> true;
+supported_hash(HashAlg) ->
+ Hs = if is_atom(HashAlg) -> [HashAlg];
+ is_list(HashAlg) -> HashAlg
+ end,
+ [] == (Hs -- proplists:get_value(hashs, crypto:supports(), [])).
+
+
+really_do_hostkey_fingerprint_check(Config, HashAlg) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ UserDirServer = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDirServer),
+ SysDir = proplists:get_value(data_dir, Config),
+
+ UserDirClient =
+ ssh_test_lib:create_random_dir(Config), % Ensure no 'known_hosts' disturbs
+
+ %% All host key fingerprints. Trust that public_key has checked the ssh_hostkey_fingerprint
+ %% function since that function is used by the ssh client...
+ FPs0 = [case HashAlg of
+ old -> public_key:ssh_hostkey_fingerprint(Key);
+ _ -> public_key:ssh_hostkey_fingerprint(HashAlg, Key)
+ end
+ || FileCandidate <- begin
+ {ok,KeyFileCands} = file:list_dir(SysDir),
+ KeyFileCands
+ end,
+ nomatch =/= re:run(FileCandidate, ".*\\.pub", []),
+ {Key,_Cmnts} <- begin
+ {ok,Bin} = file:read_file(filename:join(SysDir, FileCandidate)),
+ try public_key:ssh_decode(Bin, public_key)
+ catch
+ _:_ -> []
+ end
+ end],
+ FPs = if is_atom(HashAlg) -> FPs0;
+ is_list(HashAlg) -> lists:concat(FPs0)
+ end,
+ ct:log("Fingerprints(~p) = ~p",[HashAlg,FPs]),
+
+ %% Start daemon with the public keys that we got fingerprints from
+ {Pid, Host0, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDirServer},
+ {password, "morot"}]),
+ Host = ssh_test_lib:ntoa(Host0),
+ FP_check_fun = fun(PeerName, FP) ->
+ ct:log("PeerName = ~p, FP = ~p",[PeerName,FP]),
+ HostCheck = ssh_test_lib:match_ip(Host, PeerName),
+ FPCheck =
+ if is_atom(HashAlg) -> lists:member(FP, FPs);
+ is_list(HashAlg) -> lists:all(fun(FP1) -> lists:member(FP1,FPs) end,
+ FP)
+ end,
+ ct:log("check ~p == ~p (~p) and ~n~p~n in ~p (~p)~n",
+ [PeerName,Host,HostCheck,FP,FPs,FPCheck]),
+ HostCheck and FPCheck
+ end,
+
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts,
+ case HashAlg of
+ old -> FP_check_fun;
+ _ -> {HashAlg, FP_check_fun}
+ end},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDirClient},
+ {user_interaction, false}]),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
%%% Test connect_timeout option in ssh:connect/4
ssh_connect_timeout(_Config) ->
ConnTimeout = 2000,
@@ -929,20 +1052,20 @@ id_string_random_client(Config) ->
%%--------------------------------------------------------------------
id_string_no_opt_server(Config) ->
{_Server, Host, Port} = ssh_test_lib:std_daemon(Config, []),
- {ok,S1}=gen_tcp:connect(Host,Port,[{active,false},{packet,line}]),
+ {ok,S1}=ssh_test_lib:gen_tcp_connect(Host,Port,[{active,false},{packet,line}]),
{ok,"SSH-2.0-Erlang/"++Vsn} = gen_tcp:recv(S1, 0, 2000),
true = expected_ssh_vsn(Vsn).
%%--------------------------------------------------------------------
id_string_own_string_server(Config) ->
{_Server, Host, Port} = ssh_test_lib:std_daemon(Config, [{id_string,"Olle"}]),
- {ok,S1}=gen_tcp:connect(Host,Port,[{active,false},{packet,line}]),
+ {ok,S1}=ssh_test_lib:gen_tcp_connect(Host,Port,[{active,false},{packet,line}]),
{ok,"SSH-2.0-Olle\r\n"} = gen_tcp:recv(S1, 0, 2000).
%%--------------------------------------------------------------------
id_string_random_server(Config) ->
{_Server, Host, Port} = ssh_test_lib:std_daemon(Config, [{id_string,random}]),
- {ok,S1}=gen_tcp:connect(Host,Port,[{active,false},{packet,line}]),
+ {ok,S1}=ssh_test_lib:gen_tcp_connect(Host,Port,[{active,false},{packet,line}]),
{ok,"SSH-2.0-"++Rnd} = gen_tcp:recv(S1, 0, 2000),
case Rnd of
"Erlang"++_ -> ct:log("Id=~p",[Rnd]),
@@ -963,18 +1086,25 @@ ssh_connect_negtimeout(Config, Parallel) ->
ct:log("Parallel: ~p",[Parallel]),
{_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
- {parallel_login, Parallel},
- {negotiation_timeout, NegTimeOut},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
- {ok,Socket} = gen_tcp:connect(Host, Port, []),
+ {parallel_login, Parallel},
+ {negotiation_timeout, NegTimeOut},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ {ok,Socket} = ssh_test_lib:gen_tcp_connect(Host, Port, []),
Factor = 2,
ct:log("And now sleeping ~p*NegTimeOut (~p ms)...", [Factor, round(Factor * NegTimeOut)]),
ct:sleep(round(Factor * NegTimeOut)),
case inet:sockname(Socket) of
- {ok,_} -> ct:fail("Socket not closed");
+ {ok,_} ->
+ %% Give it another chance...
+ ct:log("Sleep more...",[]),
+ ct:sleep(round(Factor * NegTimeOut)),
+ case inet:sockname(Socket) of
+ {ok,_} -> ct:fail("Socket not closed");
+ {error,_} -> ok
+ end;
{error,_} -> ok
end.
@@ -1003,7 +1133,7 @@ ssh_connect_nonegtimeout_connected(Config, Parallel) ->
ct:sleep(500),
IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir),
+ Shell = ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir}]),
receive
Error = {'EXIT', _, _} ->
ct:log("~p",[Error]),
diff --git a/lib/ssh/test/ssh_property_test_SUITE.erl b/lib/ssh/test/ssh_property_test_SUITE.erl
index c8aabcedb7..3318b86d39 100644
--- a/lib/ssh/test/ssh_property_test_SUITE.erl
+++ b/lib/ssh/test/ssh_property_test_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@
-include_lib("common_test/include/ct.hrl").
all() -> [{group, messages},
+ client_sends_info_timing,
{group, client_server}
].
@@ -54,6 +55,9 @@ groups() ->
init_per_suite(Config) ->
ct_property_test:init_per_suite(Config).
+end_per_suite(Config) ->
+ Config.
+
%%% One group in this suite happens to support only QuickCheck, so skip it
%%% if we run proper.
init_per_group(client_server, Config) ->
@@ -67,9 +71,6 @@ init_per_group(_, Config) ->
end_per_group(_, Config) ->
Config.
-%%% Always skip the testcase that is not quite in phase with the
-%%% ssh_message.erl code
-init_per_testcase(decode_encode, _) -> {skip, "Fails - testcase is not ok"};
init_per_testcase(_TestCase, Config) -> Config.
end_per_testcase(_TestCase, Config) -> Config.
@@ -106,3 +107,9 @@ client_server_parallel_multi(Config) ->
ssh_eqc_client_server:prop_parallel_multi(Config),
Config
).
+
+client_sends_info_timing(Config) ->
+ ct_property_test:quickcheck(
+ ssh_eqc_client_info_timing:prop_seq(Config),
+ Config
+ ).
diff --git a/lib/ssh/test/ssh_protocol_SUITE.erl b/lib/ssh/test/ssh_protocol_SUITE.erl
index 4fac1f718a..0837fe7eaf 100644
--- a/lib/ssh/test/ssh_protocol_SUITE.erl
+++ b/lib/ssh/test/ssh_protocol_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -34,6 +34,12 @@
-define(NEWLINE, <<"\r\n">>).
-define(REKEY_DATA_TMO, 65000).
+%%-define(DEFAULT_KEX, 'diffie-hellman-group1-sha1').
+-define(DEFAULT_KEX, 'diffie-hellman-group14-sha256').
+
+-define(CIPHERS, ['aes256-ctr','aes192-ctr','aes128-ctr','aes128-cbc','3des-cbc']).
+-define(DEFAULT_CIPHERS, [{client2server,?CIPHERS}, {server2client,?CIPHERS}]).
+
-define(v(Key, Config), proplists:get_value(Key, Config)).
-define(v(Key, Config, Default), proplists:get_value(Key, Config, Default)).
@@ -48,11 +54,13 @@ suite() ->
all() ->
[{group,tool_tests},
+ client_info_line,
{group,kex},
{group,service_requests},
{group,authentication},
{group,packet_size_error},
- {group,field_size_error}
+ {group,field_size_error},
+ {group,ext_info}
].
groups() ->
@@ -83,7 +91,12 @@ groups() ->
bad_service_name_then_correct
]},
{authentication, [], [client_handles_keyboard_interactive_0_pwds
- ]}
+ ]},
+ {ext_info, [], [no_ext_info_s1,
+ no_ext_info_s2,
+ ext_info_s,
+ ext_info_c
+ ]}
].
@@ -96,7 +109,9 @@ end_per_suite(Config) ->
init_per_testcase(no_common_alg_server_disconnects, Config) ->
- start_std_daemon(Config, [{preferred_algorithms,[{public_key,['ssh-rsa']}]}]);
+ start_std_daemon(Config, [{preferred_algorithms,[{public_key,['ssh-rsa']},
+ {cipher,?DEFAULT_CIPHERS}
+ ]}]);
init_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
TC == gex_client_init_option_groups_moduli_file ;
@@ -106,7 +121,10 @@ init_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
TC == gex_client_old_request_noexact ->
Opts = case TC of
gex_client_init_option_groups ->
- [{dh_gex_groups, [{2345, 3, 41}]}];
+ [{dh_gex_groups,
+ [{1023, 5,
+ 16#D9277DAA27DB131C03B108D41A76B4DA8ACEECCCAE73D2E48CEDAAA70B09EF9F04FB020DCF36C51B8E485B26FABE0337E24232BE4F4E693548310244937433FB1A5758195DC73B84ADEF8237472C46747D79DC0A2CF8A57CE8DBD8F466A20F8551E7B1B824B2E4987A8816D9BC0741C2798F3EBAD3ADEBCC78FCE6A770E2EC9F
+ }]}];
gex_client_init_option_groups_file ->
DataDir = proplists:get_value(data_dir, Config),
F = filename:join(DataDir, "dh_group_test"),
@@ -118,16 +136,19 @@ init_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
_ when TC == gex_server_gex_limit ;
TC == gex_client_old_request_exact ;
TC == gex_client_old_request_noexact ->
- [{dh_gex_groups, [{ 500, 3, 17},
- {1000, 7, 91},
- {3000, 5, 61}]},
- {dh_gex_limits,{500,1500}}
+ [{dh_gex_groups,
+ [{1023, 2, 16#D9277DAA27DB131C03B108D41A76B4DA8ACEECCCAE73D2E48CEDAAA70B09EF9F04FB020DCF36C51B8E485B26FABE0337E24232BE4F4E693548310244937433FB1A5758195DC73B84ADEF8237472C46747D79DC0A2CF8A57CE8DBD8F466A20F8551E7B1B824B2E4987A8816D9BC0741C2798F3EBAD3ADEBCC78FCE6A771225323},
+ {1535, 5, 16#D1391174233D315398FE2830AC6B2B66BCCD01B0A634899F339B7879F1DB85712E9DC4E4B1C6C8355570C1D2DCB53493DF18175A9C53D1128B592B4C72D97136F5542FEB981CBFE8012FDD30361F288A42BD5EBB08BAB0A5640E1AC48763B2ABD1945FEE36B2D55E1D50A1C86CED9DD141C4E7BE2D32D9B562A0F8E2E927020E91F58B57EB9ACDDA106A59302D7E92AD5F6E851A45FA1CFE86029A0F727F65A8F475F33572E2FDAB6073F0C21B8B54C3823DB2EF068927E5D747498F96E1E827},
+ {3071, 2, 16#DFAA35D35531E0F524F0099877A482D2AC8D589F374394A262A8E81A8A4FB2F65FADBAB395E05D147B29D486DFAA41F41597A256DA82A8B6F76401AED53D0253F956CEC610D417E42E3B287F7938FC24D8821B40BFA218A956EB7401BED6C96C68C7FD64F8170A8A76B953DD2F05420118F6B144D8FE48060A2BCB85056B478EDEF96DBC70427053ECD2958C074169E9550DD877779A3CF17C5AC850598C7586BEEA9DCFE9DD2A5FB62DF5F33EA7BC00CDA31B9D2DD721F979EA85B6E63F0C4E30BDDCD3A335522F9004C4ED50B15DC537F55324DD4FA119FB3F101467C6D7E1699DE4B3E3C478A8679B8EB3FA5C9B826B44530FD3BE9AD3063B240B0C853EBDDBD68DD940332D98F148D5D9E1DC977D60A0D23D0CA1198637FEAE4E7FAAC173AF2B84313A666CFB4EE6972811921D0AD867CE57F3BBC8D6CB057E3B66757BB46C9F72662624D44E14528327E3A7100E81A12C43C4E236118318CD90C8AA185BBB0C764826DAEAEE8DD245C5B451B4944E6122CC522D1C335C2EEF9429825A2B}
+ ]},
+ {dh_gex_limits, {1023,2000}}
];
_ ->
[]
end,
start_std_daemon(Config,
- [{preferred_algorithms, ssh:default_algorithms()}
+ [{preferred_algorithms,[{cipher,?DEFAULT_CIPHERS}
+ ]}
| Opts]);
init_per_testcase(_TestCase, Config) ->
check_std_daemon_works(Config, ?LINE).
@@ -236,7 +257,10 @@ lib_works_as_server(Config) ->
%% and finally connect to it with a regular Erlang SSH client:
{ok,_} = std_connect(HostPort, Config,
- [{preferred_algorithms,[{kex,['diffie-hellman-group1-sha1']}]}]
+ [{preferred_algorithms,[{kex,[?DEFAULT_KEX]},
+ {cipher,?DEFAULT_CIPHERS}
+ ]}
+ ]
).
%%--------------------------------------------------------------------
@@ -276,7 +300,9 @@ no_common_alg_server_disconnects(Config) ->
[{silently_accept_hosts, true},
{user_dir, user_dir(Config)},
{user_interaction, false},
- {preferred_algorithms,[{public_key,['ssh-dss']}]}
+ {preferred_algorithms,[{public_key,['ssh-dss']},
+ {cipher,?DEFAULT_CIPHERS}
+ ]}
]},
receive_hello,
{send, hello},
@@ -310,7 +336,7 @@ no_common_alg_client_disconnects(Config) ->
{match, #ssh_msg_kexinit{_='_'}, receive_msg},
{send, #ssh_msg_kexinit{ % with unsupported "SOME-UNSUPPORTED"
cookie = <<80,158,95,51,174,35,73,130,246,141,200,49,180,190,82,234>>,
- kex_algorithms = ["diffie-hellman-group1-sha1"],
+ kex_algorithms = [atom_to_list(?DEFAULT_KEX)],
server_host_key_algorithms = ["SOME-UNSUPPORTED"], % SIC!
encryption_algorithms_client_to_server = ["aes128-ctr"],
encryption_algorithms_server_to_client = ["aes128-ctr"],
@@ -331,7 +357,9 @@ no_common_alg_client_disconnects(Config) ->
%% and finally connect to it with a regular Erlang SSH client
%% which of course does not support SOME-UNSUPPORTED as pub key algo:
- Result = std_connect(HostPort, Config, [{preferred_algorithms,[{public_key,['ssh-dss']}]}]),
+ Result = std_connect(HostPort, Config, [{preferred_algorithms,[{public_key,['ssh-dss']},
+ {cipher,?DEFAULT_CIPHERS}
+ ]}]),
ct:log("Result of connect is ~p",[Result]),
receive
@@ -350,20 +378,25 @@ no_common_alg_client_disconnects(Config) ->
%%%--------------------------------------------------------------------
gex_client_init_option_groups(Config) ->
- do_gex_client_init(Config, {2000, 2048, 4000},
- {3,41}).
+ do_gex_client_init(Config, {512, 2048, 4000},
+ {5,16#D9277DAA27DB131C03B108D41A76B4DA8ACEECCCAE73D2E48CEDAAA70B09EF9F04FB020DCF36C51B8E485B26FABE0337E24232BE4F4E693548310244937433FB1A5758195DC73B84ADEF8237472C46747D79DC0A2CF8A57CE8DBD8F466A20F8551E7B1B824B2E4987A8816D9BC0741C2798F3EBAD3ADEBCC78FCE6A770E2EC9F}
+ ).
gex_client_init_option_groups_file(Config) ->
do_gex_client_init(Config, {2000, 2048, 4000},
- {5,61}).
+ {5, 16#DFAA35D35531E0F524F0099877A482D2AC8D589F374394A262A8E81A8A4FB2F65FADBAB395E05D147B29D486DFAA41F41597A256DA82A8B6F76401AED53D0253F956CEC610D417E42E3B287F7938FC24D8821B40BFA218A956EB7401BED6C96C68C7FD64F8170A8A76B953DD2F05420118F6B144D8FE48060A2BCB85056B478EDEF96DBC70427053ECD2958C074169E9550DD877779A3CF17C5AC850598C7586BEEA9DCFE9DD2A5FB62DF5F33EA7BC00CDA31B9D2DD721F979EA85B6E63F0C4E30BDDCD3A335522F9004C4ED50B15DC537F55324DD4FA119FB3F101467C6D7E1699DE4B3E3C478A8679B8EB3FA5C9B826B44530FD3BE9AD3063B240B0C853EBDDBD68DD940332D98F148D5D9E1DC977D60A0D23D0CA1198637FEAE4E7FAAC173AF2B84313A666CFB4EE6972811921D0AD867CE57F3BBC8D6CB057E3B66757BB46C9F72662624D44E14528327E3A7100E81A12C43C4E236118318CD90C8AA185BBB0C764826DAEAEE8DD245C5B451B4944E6122CC522D1C335C2EEF9424273F1F}
+ ).
gex_client_init_option_groups_moduli_file(Config) ->
do_gex_client_init(Config, {2000, 2048, 4000},
- {5,16#B7}).
+ {5, 16#DD2047CBDBB6F8E919BC63DE885B34D0FD6E3DB2887D8B46FE249886ACED6B46DFCD5553168185FD376122171CD8927E60120FA8D01F01D03E58281FEA9A1ABE97631C828E41815F34FDCDF787419FE13A3137649AA93D2584230DF5F24B5C00C88B7D7DE4367693428C730376F218A53E853B0851BAB7C53C15DA7839CBE1285DB63F6FA45C1BB59FE1C5BB918F0F8459D7EF60ACFF5C0FA0F3FCAD1C5F4CE4416D4F4B36B05CDCEBE4FB879E95847EFBC6449CD190248843BC7EDB145FBFC4EDBB1A3C959298F08F3BA2CFBE231BBE204BE6F906209D28BD4820AB3E7BE96C26AE8A809ADD8D1A5A0B008E9570FA4C4697E116B8119892C604293683A9635F}
+ ).
gex_server_gex_limit(Config) ->
do_gex_client_init(Config, {1000, 3000, 4000},
- {7,91}).
+ %% {7,91}).
+ {5, 16#D1391174233D315398FE2830AC6B2B66BCCD01B0A634899F339B7879F1DB85712E9DC4E4B1C6C8355570C1D2DCB53493DF18175A9C53D1128B592B4C72D97136F5542FEB981CBFE8012FDD30361F288A42BD5EBB08BAB0A5640E1AC48763B2ABD1945FEE36B2D55E1D50A1C86CED9DD141C4E7BE2D32D9B562A0F8E2E927020E91F58B57EB9ACDDA106A59302D7E92AD5F6E851A45FA1CFE86029A0F727F65A8F475F33572E2FDAB6073F0C21B8B54C3823DB2EF068927E5D747498F96E1E827}
+ ).
do_gex_client_init(Config, {Min,N,Max}, {G,P}) ->
@@ -375,7 +408,9 @@ do_gex_client_init(Config, {Min,N,Max}, {G,P}) ->
[{silently_accept_hosts, true},
{user_dir, user_dir(Config)},
{user_interaction, false},
- {preferred_algorithms,[{kex,['diffie-hellman-group-exchange-sha1']}]}
+ {preferred_algorithms,[{kex,['diffie-hellman-group-exchange-sha1']},
+ {cipher,?DEFAULT_CIPHERS}
+ ]}
]},
receive_hello,
{send, hello},
@@ -389,8 +424,15 @@ do_gex_client_init(Config, {Min,N,Max}, {G,P}) ->
).
%%%--------------------------------------------------------------------
-gex_client_old_request_exact(Config) -> do_gex_client_init_old(Config, 500, {3,17}).
-gex_client_old_request_noexact(Config) -> do_gex_client_init_old(Config, 800, {7,91}).
+gex_client_old_request_exact(Config) ->
+ do_gex_client_init_old(Config, 1023,
+ {2, 16#D9277DAA27DB131C03B108D41A76B4DA8ACEECCCAE73D2E48CEDAAA70B09EF9F04FB020DCF36C51B8E485B26FABE0337E24232BE4F4E693548310244937433FB1A5758195DC73B84ADEF8237472C46747D79DC0A2CF8A57CE8DBD8F466A20F8551E7B1B824B2E4987A8816D9BC0741C2798F3EBAD3ADEBCC78FCE6A771225323}
+ ).
+
+gex_client_old_request_noexact(Config) ->
+ do_gex_client_init_old(Config, 1400,
+ {5, 16#D1391174233D315398FE2830AC6B2B66BCCD01B0A634899F339B7879F1DB85712E9DC4E4B1C6C8355570C1D2DCB53493DF18175A9C53D1128B592B4C72D97136F5542FEB981CBFE8012FDD30361F288A42BD5EBB08BAB0A5640E1AC48763B2ABD1945FEE36B2D55E1D50A1C86CED9DD141C4E7BE2D32D9B562A0F8E2E927020E91F58B57EB9ACDDA106A59302D7E92AD5F6E851A45FA1CFE86029A0F727F65A8F475F33572E2FDAB6073F0C21B8B54C3823DB2EF068927E5D747498F96E1E827}
+ ).
do_gex_client_init_old(Config, N, {G,P}) ->
{ok,_} =
@@ -401,7 +443,9 @@ do_gex_client_init_old(Config, N, {G,P}) ->
[{silently_accept_hosts, true},
{user_dir, user_dir(Config)},
{user_interaction, false},
- {preferred_algorithms,[{kex,['diffie-hellman-group-exchange-sha1']}]}
+ {preferred_algorithms,[{kex,['diffie-hellman-group-exchange-sha1']},
+ {cipher,?DEFAULT_CIPHERS}
+ ]}
]},
receive_hello,
{send, hello},
@@ -422,7 +466,7 @@ bad_long_service_name(Config) ->
bad_very_long_service_name(Config) ->
bad_service_name(Config,
- lists:duplicate(4*?SSH_MAX_PACKET_SIZE, $a)).
+ lists:duplicate(?SSH_MAX_PACKET_SIZE+5, $a)).
empty_service_name(Config) ->
bad_service_name(Config, "").
@@ -571,10 +615,148 @@ client_handles_keyboard_interactive_0_pwds(Config) ->
%% and finally connect to it with a regular Erlang SSH client:
{ok,_} = std_connect(HostPort, Config,
- [{preferred_algorithms,[{kex,['diffie-hellman-group1-sha1']}]}]
+ [{preferred_algorithms,[{kex,[?DEFAULT_KEX]},
+ {cipher,?DEFAULT_CIPHERS}
+ ]}]
).
+
+%%%--------------------------------------------------------------------
+client_info_line(_Config) ->
+ %% A client must not send an info-line. If it does, the server should handle
+ %% handle this gracefully
+ {ok,Pid} = ssh_eqc_event_handler:add_report_handler(),
+ {_, _, Port} = ssh_test_lib:daemon([]),
+
+ %% Fake client:
+ {ok,S} = gen_tcp:connect("localhost",Port,[]),
+ gen_tcp:send(S,"An illegal info-string\r\n"),
+ gen_tcp:close(S),
+
+ %% wait for server to react:
+ timer:sleep(1000),
+
+ %% check if a badmatch was received:
+ {ok, Reports} = ssh_eqc_event_handler:get_reports(Pid),
+ case lists:any(fun({error_report,_,{_,supervisor_report,L}}) when is_list(L) ->
+ lists:member({reason,{badmatch,{error,closed}}}, L);
+ (_) ->
+ false
+ end, Reports) of
+ true ->
+ ct:fail("Bad error report on info_line from client");
+ false ->
+ ok
+ end.
+
+%%%--------------------------------------------------------------------
+%%% The server does not send the extension because
+%%% the client does not tell the server to send it
+no_ext_info_s1(Config) ->
+ %% Start the dameon
+ Server = {Pid,_,_} = ssh_test_lib:daemon([{send_ext_info,true},
+ {system_dir, system_dir(Config)}]),
+ {ok,AfterKexState} = connect_and_kex([{server,Server}|Config]),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{send, #ssh_msg_service_request{name = "ssh-userauth"}},
+ {match, #ssh_msg_service_accept{name = "ssh-userauth"}, receive_msg}
+ ], AfterKexState),
+ ssh:stop_daemon(Pid).
+
+%%%--------------------------------------------------------------------
+%%% The server does not send the extension because
+%%% the server is not configured to send it
+no_ext_info_s2(Config) ->
+ %% Start the dameon
+ Server = {Pid,_,_} = ssh_test_lib:daemon([{send_ext_info,false},
+ {system_dir, system_dir(Config)}]),
+ {ok,AfterKexState} = connect_and_kex([{extra_options,[{recv_ext_info,true}]},
+ {server,Server}
+ | Config]),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{send, #ssh_msg_service_request{name = "ssh-userauth"}},
+ {match, #ssh_msg_service_accept{name = "ssh-userauth"}, receive_msg}
+ ], AfterKexState),
+ ssh:stop_daemon(Pid).
+
+%%%--------------------------------------------------------------------
+%%% The server sends the extension
+ext_info_s(Config) ->
+ %% Start the dameon
+ Server = {Pid,_,_} = ssh_test_lib:daemon([{send_ext_info,true},
+ {system_dir, system_dir(Config)}]),
+ {ok,AfterKexState} = connect_and_kex([{extra_options,[{recv_ext_info,true}]},
+ {server,Server}
+ | Config]),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{match, #ssh_msg_ext_info{_='_'}, receive_msg}
+ ],
+ AfterKexState),
+ ssh:stop_daemon(Pid).
+
+%%%--------------------------------------------------------------------
+%%% The client sends the extension
+ext_info_c(Config) ->
+ {User,_Pwd} = server_user_password(Config),
+
+ %% Create a listening socket as server socket:
+ {ok,InitialState} = ssh_trpt_test_lib:exec(listen),
+ HostPort = ssh_trpt_test_lib:server_host_port(InitialState),
+
+ Parent = self(),
+ %% Start a process handling one connection on the server side:
+ Pid =
+ spawn_link(
+ fun() ->
+ Result =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_messages]},
+ {accept, [{system_dir, system_dir(Config)},
+ {user_dir, user_dir(Config)},
+ {recv_ext_info, true}
+ ]},
+ receive_hello,
+ {send, hello},
+
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+
+ {match, #ssh_msg_kexdh_init{_='_'}, receive_msg},
+ {send, ssh_msg_kexdh_reply},
+
+ {send, #ssh_msg_newkeys{}},
+ {match, #ssh_msg_newkeys{_='_'}, receive_msg},
+
+ {match, #ssh_msg_ext_info{_='_'}, receive_msg},
+
+ close_socket,
+ print_state
+ ],
+ InitialState),
+ Parent ! {result,self(),Result}
+ end),
+
+ %% connect to it with a regular Erlang SSH client
+ %% (expect error due to the close_socket in daemon):
+ {error,_} = std_connect(HostPort, Config,
+ [{preferred_algorithms,[{kex,[?DEFAULT_KEX]},
+ {cipher,?DEFAULT_CIPHERS}
+ ]},
+ {tstflg, [{ext_info_client,true}]},
+ {send_ext_info, true}
+ ]
+ ),
+
+ %% Check that the daemon got expected result:
+ receive
+ {result, Pid, {ok,_}} -> ok;
+ {result, Pid, Error} -> ct:fail("Error: ~p",[Error])
+ end.
+
%%%================================================================
%%%==== Internal functions ========================================
%%%================================================================
@@ -592,6 +774,7 @@ stop_apps(_Config) ->
setup_dirs(Config) ->
DataDir = proplists:get_value(data_dir, Config),
PrivDir = proplists:get_value(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, PrivDir),
ssh_test_lib:setup_rsa(DataDir, PrivDir),
Config.
@@ -677,10 +860,15 @@ connect_and_kex(Config, InitialState) ->
ssh_trpt_test_lib:exec(
[{connect,
server_host(Config),server_port(Config),
- [{preferred_algorithms,[{kex,['diffie-hellman-group1-sha1']}]},
- {silently_accept_hosts, true},
+ [{preferred_algorithms,[{kex,[?DEFAULT_KEX]},
+ {cipher,?DEFAULT_CIPHERS}
+ ]},
+ {silently_accept_hosts, true},
+ {recv_ext_info, false},
{user_dir, user_dir(Config)},
- {user_interaction, false}]},
+ {user_interaction, false}
+ | proplists:get_value(extra_options,Config,[])
+ ]},
receive_hello,
{send, hello},
{send, ssh_msg_kexinit},
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test
index 2887bb4b60..87c4b4afc8 100644
--- a/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test
@@ -1,3 +1,3 @@
-{2222, 5, 61}.
-{1111, 7, 91}.
+{1023, 5, 16#D9277DAA27DB131C03B108D41A76B4DA8ACEECCCAE73D2E48CEDAAA70B09EF9F04FB020DCF36C51B8E485B26FABE0337E24232BE4F4E693548310244937433FB1A5758195DC73B84ADEF8237472C46747D79DC0A2CF8A57CE8DBD8F466A20F8551E7B1B824B2E4987A8816D9BC0741C2798F3EBAD3ADEBCC78FCE6A770E2EC9F}.
+{3071, 5, 16#DFAA35D35531E0F524F0099877A482D2AC8D589F374394A262A8E81A8A4FB2F65FADBAB395E05D147B29D486DFAA41F41597A256DA82A8B6F76401AED53D0253F956CEC610D417E42E3B287F7938FC24D8821B40BFA218A956EB7401BED6C96C68C7FD64F8170A8A76B953DD2F05420118F6B144D8FE48060A2BCB85056B478EDEF96DBC70427053ECD2958C074169E9550DD877779A3CF17C5AC850598C7586BEEA9DCFE9DD2A5FB62DF5F33EA7BC00CDA31B9D2DD721F979EA85B6E63F0C4E30BDDCD3A335522F9004C4ED50B15DC537F55324DD4FA119FB3F101467C6D7E1699DE4B3E3C478A8679B8EB3FA5C9B826B44530FD3BE9AD3063B240B0C853EBDDBD68DD940332D98F148D5D9E1DC977D60A0D23D0CA1198637FEAE4E7FAAC173AF2B84313A666CFB4EE6972811921D0AD867CE57F3BBC8D6CB057E3B66757BB46C9F72662624D44E14528327E3A7100E81A12C43C4E236118318CD90C8AA185BBB0C764826DAEAEE8DD245C5B451B4944E6122CC522D1C335C2EEF9424273F1F}.
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli
index f6995ba4c9..6d2b4bcb59 100644
--- a/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli
@@ -1,3 +1,2 @@
-20151021104105 2 6 100 2222 5 B7
-20151021104106 2 6 100 1111 5 4F
-
+20120821044046 2 6 100 1023 2 D9277DAA27DB131C03B108D41A76B4DA8ACEECCCAE73D2E48CEDAAA70B09EF9F04FB020DCF36C51B8E485B26FABE0337E24232BE4F4E693548310244937433FB1A5758195DC73B84ADEF8237472C46747D79DC0A2CF8A57CE8DBD8F466A20F8551E7B1B824B2E4987A8816D9BC0741C2798F3EBAD3ADEBCC78FCE6A7711F2C6B
+20120821050554 2 6 100 2047 5 DD2047CBDBB6F8E919BC63DE885B34D0FD6E3DB2887D8B46FE249886ACED6B46DFCD5553168185FD376122171CD8927E60120FA8D01F01D03E58281FEA9A1ABE97631C828E41815F34FDCDF787419FE13A3137649AA93D2584230DF5F24B5C00C88B7D7DE4367693428C730376F218A53E853B0851BAB7C53C15DA7839CBE1285DB63F6FA45C1BB59FE1C5BB918F0F8459D7EF60ACFF5C0FA0F3FCAD1C5F4CE4416D4F4B36B05CDCEBE4FB879E95847EFBC6449CD190248843BC7EDB145FBFC4EDBB1A3C959298F08F3BA2CFBE231BBE204BE6F906209D28BD4820AB3E7BE96C26AE8A809ADD8D1A5A0B008E9570FA4C4697E116B8119892C604293683A9635F
diff --git a/lib/ssh/test/ssh_relay.erl b/lib/ssh/test/ssh_relay.erl
index 28000fbb97..763130358b 100644
--- a/lib/ssh/test/ssh_relay.erl
+++ b/lib/ssh/test/ssh_relay.erl
@@ -131,7 +131,8 @@ init([ListenAddr, ListenPort, PeerAddr, PeerPort | _Options]) ->
S = #state{local_addr = ListenAddr,
local_port = ListenPort,
lpid = LPid,
- peer_addr = PeerAddr,
+ peer_addr = ssh_test_lib:ntoa(
+ ssh_test_lib:mangle_connect_address(PeerAddr)),
peer_port = PeerPort
},
{ok, S};
@@ -241,11 +242,11 @@ handle_info(stop, State) ->
{stop, normal, State};
handle_info({'DOWN', _Ref, _process, LPid, Reason}, S) when S#state.lpid == LPid ->
- io:format("Acceptor has finished: ~p~n", [Reason]),
+ io:format("Acceptor in ~p has finished: ~p~n", [?MODULE,Reason]),
{noreply, S};
handle_info(_Info, State) ->
- io:format("Unhandled info: ~p~n", [_Info]),
+ io:format("~p:~p Unhandled info: ~p~n", [?MODULE,?LINE,_Info]),
{noreply, State}.
%%--------------------------------------------------------------------
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE.erl b/lib/ssh/test/ssh_renegotiate_SUITE.erl
index b10ec3707f..74bbc291b2 100644
--- a/lib/ssh/test/ssh_renegotiate_SUITE.erl
+++ b/lib/ssh/test/ssh_renegotiate_SUITE.erl
@@ -92,11 +92,11 @@ rekey(Config) ->
ConnectionRef =
ssh_test_lib:std_connect(Config, Host, Port,
[{rekey_limit, 0}]),
- Kex1 = get_kex_init(ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
receive
after ?REKEY_DATA_TMO ->
%%By this time rekeying would have been done
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
false = (Kex2 == Kex1),
ssh:close(ConnectionRef),
ssh:stop_daemon(Pid)
@@ -120,31 +120,31 @@ rekey_limit(Config) ->
{max_random_length_padding,0}]),
{ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
- Kex1 = get_kex_init(ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
timer:sleep(?REKEY_DATA_TMO),
- Kex1 = get_kex_init(ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
Data = lists:duplicate(159000,1),
ok = ssh_sftp:write_file(SftpPid, DataFile, Data),
timer:sleep(?REKEY_DATA_TMO),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
false = (Kex2 == Kex1),
timer:sleep(?REKEY_DATA_TMO),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
ok = ssh_sftp:write_file(SftpPid, DataFile, "hi\n"),
timer:sleep(?REKEY_DATA_TMO),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
false = (Kex2 == Kex1),
timer:sleep(?REKEY_DATA_TMO),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
ssh_sftp:stop_channel(SftpPid),
ssh:close(ConnectionRef),
@@ -169,7 +169,7 @@ renegotiate1(Config) ->
ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
{ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
- Kex1 = get_kex_init(ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
{ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
@@ -181,7 +181,7 @@ renegotiate1(Config) ->
timer:sleep(2000),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
false = (Kex2 == Kex1),
@@ -208,7 +208,7 @@ renegotiate2(Config) ->
ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
{ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
- Kex1 = get_kex_init(ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
{ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
@@ -223,7 +223,7 @@ renegotiate2(Config) ->
timer:sleep(2000),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
false = (Kex2 == Kex1),
@@ -235,19 +235,3 @@ renegotiate2(Config) ->
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
-%% get_kex_init - helper function to get key_exchange_init_msg
-get_kex_init(Conn) ->
- %% First, validate the key exchange is complete (StateName == connected)
- {{connected,_},S} = sys:get_state(Conn),
- %% Next, walk through the elements of the #state record looking
- %% for the #ssh_msg_kexinit record. This method is robust against
- %% changes to either record. The KEXINIT message contains a cookie
- %% unique to each invocation of the key exchange procedure (RFC4253)
- SL = tuple_to_list(S),
- case lists:keyfind(ssh_msg_kexinit, 1, SL) of
- false ->
- throw(not_found);
- KexInit ->
- KexInit
- end.
-
diff --git a/lib/ssh/test/ssh_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl
index 19ad81e7da..680a8ef52e 100644
--- a/lib/ssh/test/ssh_sftp_SUITE.erl
+++ b/lib/ssh/test/ssh_sftp_SUITE.erl
@@ -1,7 +1,7 @@
%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -60,12 +60,16 @@ end_per_suite(_onfig) ->
groups() ->
[{not_unicode, [], [{group,erlang_server},
{group,openssh_server},
+ {group,big_recvpkt_size},
sftp_nonexistent_subsystem]},
{unicode, [], [{group,erlang_server},
{group,openssh_server},
sftp_nonexistent_subsystem]},
+ {big_recvpkt_size, [], [{group,erlang_server},
+ {group,openssh_server}]},
+
{erlang_server, [], [{group,write_read_tests},
version_option,
{group,remote_tar}]},
@@ -149,6 +153,9 @@ init_per_group(unicode, Config) ->
{skip, "Not unicode file encoding"}
end;
+init_per_group(big_recvpkt_size, Config) ->
+ [{pkt_sz,123456} | Config];
+
init_per_group(erlang_server, Config) ->
ct:comment("Begin ~p",[grps(Config)]),
PrivDir = proplists:get_value(priv_dir, Config),
@@ -257,7 +264,10 @@ init_per_testcase(Case, Config00) ->
Dog = ct:timetrap(2 * ?default_timeout),
User = proplists:get_value(user, Config0),
Passwd = proplists:get_value(passwd, Config0),
-
+ PktSzOpt = case proplists:get_value(pkt_sz, Config0) of
+ undefined -> [];
+ Sz -> [{packet_size,Sz}]
+ end,
Config =
case proplists:get_value(group,Config2) of
erlang_server ->
@@ -267,7 +277,9 @@ init_per_testcase(Case, Config00) ->
[{user, User},
{password, Passwd},
{user_interaction, false},
- {silently_accept_hosts, true}]
+ {silently_accept_hosts, true}
+ | PktSzOpt
+ ]
),
Sftp = {ChannelPid, Connection},
[{sftp, Sftp}, {watchdog, Dog} | Config2];
@@ -278,7 +290,9 @@ init_per_testcase(Case, Config00) ->
{ok, ChannelPid, Connection} =
ssh_sftp:start_channel(Host,
[{user_interaction, false},
- {silently_accept_hosts, true}]),
+ {silently_accept_hosts, true}
+ | PktSzOpt
+ ]),
Sftp = {ChannelPid, Connection},
[{sftp, Sftp}, {watchdog, Dog} | Config2]
end,
@@ -646,7 +660,7 @@ start_channel_sock(Config) ->
{Host,Port} = proplists:get_value(peer, Config),
%% Get a tcp socket
- {ok, Sock} = gen_tcp:connect(Host, Port, [{active,false}]),
+ {ok, Sock} = ssh_test_lib:gen_tcp_connect(Host, Port, [{active,false}]),
%% and open one channel on one new Connection
{ok, ChPid1, Conn} = ssh_sftp:start_channel(Sock, Opts),
@@ -1024,7 +1038,7 @@ oldprep(Config) ->
prepare(Config0) ->
PrivDir = proplists:get_value(priv_dir, Config0),
- Dir = filename:join(PrivDir, random_chars(10)),
+ Dir = filename:join(PrivDir, ssh_test_lib:random_chars(10)),
file:make_dir(Dir),
Keys = [filename,
testfile,
@@ -1044,8 +1058,6 @@ prepare(Config0) ->
[{sftp_priv_dir,Dir} | Config2].
-random_chars(N) -> [crypto:rand_uniform($a,$z) || _<-lists:duplicate(N,x)].
-
foldl_keydelete(Keys, L) ->
lists:foldl(fun(K,E) -> lists:keydelete(K,1,E) end,
L,
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_sftp_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_sftp_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_sftpd_SUITE.erl b/lib/ssh/test/ssh_sftpd_SUITE.erl
index 52a26110c4..763649a12f 100644
--- a/lib/ssh/test/ssh_sftpd_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -65,7 +65,12 @@ all() ->
ver3_open_flags,
relpath,
sshd_read_file,
- ver6_basic].
+ ver6_basic,
+ access_outside_root,
+ root_with_cwd,
+ relative_path,
+ open_file_dir_v5,
+ open_file_dir_v6].
groups() ->
[].
@@ -117,19 +122,43 @@ init_per_testcase(TestCase, Config) ->
ver6_basic ->
SubSystems = [ssh_sftpd:subsystem_spec([{sftpd_vsn, 6}])],
ssh:daemon(0, [{subsystems, SubSystems}|Options]);
+ access_outside_root ->
+ %% Build RootDir/access_outside_root/a/b and set Root and CWD
+ BaseDir = filename:join(PrivDir, access_outside_root),
+ RootDir = filename:join(BaseDir, a),
+ CWD = filename:join(RootDir, b),
+ %% Make the directory chain:
+ ok = filelib:ensure_dir(filename:join(CWD, tmp)),
+ SubSystems = [ssh_sftpd:subsystem_spec([{root, RootDir},
+ {cwd, CWD}])],
+ ssh:daemon(0, [{subsystems, SubSystems}|Options]);
+ root_with_cwd ->
+ RootDir = filename:join(PrivDir, root_with_cwd),
+ CWD = filename:join(RootDir, home),
+ SubSystems = [ssh_sftpd:subsystem_spec([{root, RootDir}, {cwd, CWD}])],
+ ssh:daemon(0, [{subsystems, SubSystems}|Options]);
+ relative_path ->
+ SubSystems = [ssh_sftpd:subsystem_spec([{cwd, PrivDir}])],
+ ssh:daemon(0, [{subsystems, SubSystems}|Options]);
+ open_file_dir_v5 ->
+ SubSystems = [ssh_sftpd:subsystem_spec([{cwd, PrivDir}])],
+ ssh:daemon(0, [{subsystems, SubSystems}|Options]);
+ open_file_dir_v6 ->
+ SubSystems = [ssh_sftpd:subsystem_spec([{cwd, PrivDir},
+ {sftpd_vsn, 6}])],
+ ssh:daemon(0, [{subsystems, SubSystems}|Options]);
_ ->
SubSystems = [ssh_sftpd:subsystem_spec([])],
ssh:daemon(0, [{subsystems, SubSystems}|Options])
end,
- {ok,Dinf} = ssh:daemon_info(Sftpd),
- Port = proplists:get_value(port, Dinf),
+
+ Port = ssh_test_lib:daemon_port(Sftpd),
Cm = ssh_test_lib:connect(Port,
[{user_dir, ClientUserDir},
{user, ?USER}, {password, ?PASSWD},
{user_interaction, false},
- {silently_accept_hosts, true},
- {pwdfun, fun(_,_) -> true end}]),
+ {silently_accept_hosts, true}]),
{ok, Channel} =
ssh_connection:session_channel(Cm, ?XFER_WINDOW_SIZE,
?XFER_PACKET_SIZE, ?TIMEOUT),
@@ -158,7 +187,7 @@ init_per_testcase(TestCase, Config) ->
[{sftp, {Cm, Channel}}, {sftpd, Sftpd }| Config].
end_per_testcase(_TestCase, Config) ->
- ssh_sftpd:stop(proplists:get_value(sftpd, Config)),
+ catch ssh:stop_daemon(proplists:get_value(sftpd, Config)),
{Cm, Channel} = proplists:get_value(sftp, Config),
ssh_connection:close(Cm, Channel),
ssh:close(Cm),
@@ -646,6 +675,133 @@ ver6_basic(Config) when is_list(Config) ->
open_file(PrivDir, Cm, Channel, ReqId,
?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES,
?SSH_FXF_OPEN_EXISTING).
+
+%%--------------------------------------------------------------------
+access_outside_root() ->
+ [{doc, "Try access files outside the tree below RootDir"}].
+access_outside_root(Config) when is_list(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ BaseDir = filename:join(PrivDir, access_outside_root),
+ %% A file outside the tree below RootDir which is BaseDir/a
+ %% Make the file BaseDir/bad :
+ BadFilePath = filename:join([BaseDir, bad]),
+ ok = file:write_file(BadFilePath, <<>>),
+ {Cm, Channel} = proplists:get_value(sftp, Config),
+ %% Try to access a file parallell to the RootDir:
+ try_access("/../bad", Cm, Channel, 0),
+ %% Try to access the same file via the CWD which is /b relative to the RootDir:
+ try_access("../../bad", Cm, Channel, 1).
+
+
+try_access(Path, Cm, Channel, ReqId) ->
+ Return =
+ open_file(Path, Cm, Channel, ReqId,
+ ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES,
+ ?SSH_FXF_OPEN_EXISTING),
+ ct:log("Try open ~p -> ~p",[Path,Return]),
+ case Return of
+ {ok, <<?SSH_FXP_HANDLE, ?UINT32(ReqId), _Handle0/binary>>, _} ->
+ ct:fail("Could open a file outside the root tree!");
+ {ok, <<?SSH_FXP_STATUS, ?UINT32(ReqId), ?UINT32(Code), Rest/binary>>, <<>>} ->
+ case Code of
+ ?SSH_FX_FILE_IS_A_DIRECTORY ->
+ ct:log("Got the expected SSH_FX_FILE_IS_A_DIRECTORY status",[]),
+ ok;
+ ?SSH_FX_FAILURE ->
+ ct:log("Got the expected SSH_FX_FAILURE status",[]),
+ ok;
+ _ ->
+ case Rest of
+ <<?UINT32(Len), Txt:Len/binary, _/binary>> ->
+ ct:fail("Got unexpected SSH_FX_code: ~p (~p)",[Code,Txt]);
+ _ ->
+ ct:fail("Got unexpected SSH_FX_code: ~p",[Code])
+ end
+ end;
+ _ ->
+ ct:fail("Completly unexpected return: ~p", [Return])
+ end.
+
+%%--------------------------------------------------------------------
+root_with_cwd() ->
+ [{doc, "Check if files are found, if the CWD and Root are specified"}].
+root_with_cwd(Config) when is_list(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ RootDir = filename:join(PrivDir, root_with_cwd),
+ CWD = filename:join(RootDir, home),
+ FileName = "root_with_cwd.txt",
+ FilePath = filename:join(CWD, FileName),
+ ok = filelib:ensure_dir(FilePath),
+ ok = file:write_file(FilePath ++ "0", <<>>),
+ ok = file:write_file(FilePath ++ "1", <<>>),
+ ok = file:write_file(FilePath ++ "2", <<>>),
+ {Cm, Channel} = proplists:get_value(sftp, Config),
+ ReqId0 = 0,
+ {ok, <<?SSH_FXP_HANDLE, ?UINT32(ReqId0), _Handle0/binary>>, _} =
+ open_file(FileName ++ "0", Cm, Channel, ReqId0,
+ ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES,
+ ?SSH_FXF_OPEN_EXISTING),
+ ReqId1 = 1,
+ {ok, <<?SSH_FXP_HANDLE, ?UINT32(ReqId1), _Handle1/binary>>, _} =
+ open_file("./" ++ FileName ++ "1", Cm, Channel, ReqId1,
+ ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES,
+ ?SSH_FXF_OPEN_EXISTING),
+ ReqId2 = 2,
+ {ok, <<?SSH_FXP_HANDLE, ?UINT32(ReqId2), _Handle2/binary>>, _} =
+ open_file("/home/" ++ FileName ++ "2", Cm, Channel, ReqId2,
+ ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES,
+ ?SSH_FXF_OPEN_EXISTING).
+
+%%--------------------------------------------------------------------
+relative_path() ->
+ [{doc, "Test paths relative to CWD when opening a file handle."}].
+relative_path(Config) when is_list(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ FileName = "test_relative_path.txt",
+ FilePath = filename:join(PrivDir, FileName),
+ ok = filelib:ensure_dir(FilePath),
+ ok = file:write_file(FilePath, <<>>),
+ {Cm, Channel} = proplists:get_value(sftp, Config),
+ ReqId = 0,
+ {ok, <<?SSH_FXP_HANDLE, ?UINT32(ReqId), _Handle/binary>>, _} =
+ open_file(FileName, Cm, Channel, ReqId,
+ ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES,
+ ?SSH_FXF_OPEN_EXISTING).
+
+%%--------------------------------------------------------------------
+open_file_dir_v5() ->
+ [{doc, "Test if open_file fails when opening existing directory."}].
+open_file_dir_v5(Config) when is_list(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ FileName = "open_file_dir_v5",
+ FilePath = filename:join(PrivDir, FileName),
+ ok = filelib:ensure_dir(FilePath),
+ ok = file:make_dir(FilePath),
+ {Cm, Channel} = proplists:get_value(sftp, Config),
+ ReqId = 0,
+ {ok, <<?SSH_FXP_STATUS, ?UINT32(ReqId),
+ ?UINT32(?SSH_FX_FAILURE), _/binary>>, _} =
+ open_file(FileName, Cm, Channel, ReqId,
+ ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES,
+ ?SSH_FXF_OPEN_EXISTING).
+
+%%--------------------------------------------------------------------
+open_file_dir_v6() ->
+ [{doc, "Test if open_file fails when opening existing directory."}].
+open_file_dir_v6(Config) when is_list(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ FileName = "open_file_dir_v6",
+ FilePath = filename:join(PrivDir, FileName),
+ ok = filelib:ensure_dir(FilePath),
+ ok = file:make_dir(FilePath),
+ {Cm, Channel} = proplists:get_value(sftp, Config),
+ ReqId = 0,
+ {ok, <<?SSH_FXP_STATUS, ?UINT32(ReqId),
+ ?UINT32(?SSH_FX_FILE_IS_A_DIRECTORY), _/binary>>, _} =
+ open_file(FileName, Cm, Channel, ReqId,
+ ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES,
+ ?SSH_FXF_OPEN_EXISTING).
+
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
@@ -688,9 +844,7 @@ reply(Cm, Channel, RBuf) ->
30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
-
open_file(File, Cm, Channel, ReqId, Access, Flags) ->
-
Data = list_to_binary([?uint32(ReqId),
?binary(list_to_binary(File)),
?uint32(Access),
diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
index 56a33d6349..417b5c4f16 100644
--- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -65,6 +65,7 @@ init_per_suite(Config) ->
{ok, FileInfo} = file:read_file_info(FileName),
ok = file:write_file_info(FileName,
FileInfo#file_info{mode = 8#400}),
+ ssh_test_lib:setup_rsa(DataDir, PrivDir),
ssh_test_lib:setup_dsa(DataDir, PrivDir),
Config
end).
@@ -73,6 +74,7 @@ end_per_suite(Config) ->
UserDir = filename:join(proplists:get_value(priv_dir, Config), nopubkey),
file:del_dir(UserDir),
SysDir = proplists:get_value(priv_dir, Config),
+ ssh_test_lib:clean_rsa(SysDir),
ssh_test_lib:clean_dsa(SysDir),
ok.
@@ -136,7 +138,7 @@ init_per_testcase(TestCase, Config) ->
[{port, Port}, {sftp, {ChannelPid, Connection}}, {sftpd, Sftpd} | NewConfig].
end_per_testcase(_TestCase, Config) ->
- catch ssh_sftpd:stop(proplists:get_value(sftpd, Config)),
+ catch ssh:stop_daemon(proplists:get_value(sftpd, Config)),
{Sftp, Connection} = proplists:get_value(sftp, Config),
catch ssh_sftp:stop_channel(Sftp),
catch ssh:close(Connection),
@@ -187,7 +189,6 @@ quit(Config) when is_list(Config) ->
timer:sleep(5000),
{ok, NewSftp, _Conn} = ssh_sftp:start_channel(Host, Port,
[{silently_accept_hosts, true},
- {pwdfun, fun(_,_) -> true end},
{user_dir, UserDir},
{user, ?USER}, {password, ?PASSWD}]),
diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/id_rsa b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_sup_SUITE.erl b/lib/ssh/test/ssh_sup_SUITE.erl
index ff53e1c4c6..3920a1c592 100644
--- a/lib/ssh/test/ssh_sup_SUITE.erl
+++ b/lib/ssh/test/ssh_sup_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -41,7 +41,8 @@ suite() ->
{timetrap,{seconds,100}}].
all() ->
- [default_tree, sshc_subtree, sshd_subtree, sshd_subtree_profile].
+ [default_tree, sshc_subtree, sshd_subtree, sshd_subtree_profile,
+ killed_acceptor_restarts].
groups() ->
[].
@@ -100,6 +101,7 @@ default_tree(Config) when is_list(Config) ->
?wait_match([], supervisor:which_children(sshc_sup)),
?wait_match([], supervisor:which_children(sshd_sup)).
+%%-------------------------------------------------------------------------
sshc_subtree() ->
[{doc, "Make sure the sshc subtree is correct"}].
sshc_subtree(Config) when is_list(Config) ->
@@ -128,27 +130,31 @@ sshc_subtree(Config) when is_list(Config) ->
ssh:close(Pid2),
?wait_match([], supervisor:which_children(sshc_sup)).
+%%-------------------------------------------------------------------------
sshd_subtree() ->
[{doc, "Make sure the sshd subtree is correct"}].
sshd_subtree(Config) when is_list(Config) ->
HostIP = proplists:get_value(host_ip, Config),
Port = proplists:get_value(port, Config),
SystemDir = proplists:get_value(data_dir, Config),
- ssh:daemon(HostIP, Port, [{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2},
- {user_passwords,
- [{?USER, ?PASSWD}]}]),
+ {ok,Daemon} = ssh:daemon(HostIP, Port, [{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {user_passwords,
+ [{?USER, ?PASSWD}]}]),
- ?wait_match([{{server,ssh_system_sup, HostIP, Port, ?DEFAULT_PROFILE},
+ ct:log("Expect HostIP=~p, Port=~p, Daemon=~p",[HostIP,Port,Daemon]),
+ ?wait_match([{{server,ssh_system_sup, ListenIP, Port, ?DEFAULT_PROFILE},
Daemon, supervisor,
[ssh_system_sup]}],
supervisor:which_children(sshd_sup),
- Daemon),
+ [ListenIP,Daemon]),
+ true = ssh_test_lib:match_ip(HostIP, ListenIP),
check_sshd_system_tree(Daemon, Config),
ssh:stop_daemon(HostIP, Port),
ct:sleep(?WAIT_FOR_SHUTDOWN),
?wait_match([], supervisor:which_children(sshd_sup)).
+%%-------------------------------------------------------------------------
sshd_subtree_profile() ->
[{doc, "Make sure the sshd subtree using profile option is correct"}].
sshd_subtree_profile(Config) when is_list(Config) ->
@@ -157,34 +163,105 @@ sshd_subtree_profile(Config) when is_list(Config) ->
Profile = proplists:get_value(profile, Config),
SystemDir = proplists:get_value(data_dir, Config),
- {ok, _} = ssh:daemon(HostIP, Port, [{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2},
- {user_passwords,
- [{?USER, ?PASSWD}]},
- {profile, Profile}]),
- ?wait_match([{{server,ssh_system_sup, HostIP,Port,Profile},
+ {ok, Daemon} = ssh:daemon(HostIP, Port, [{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {user_passwords,
+ [{?USER, ?PASSWD}]},
+ {profile, Profile}]),
+ ct:log("Expect HostIP=~p, Port=~p, Profile=~p, Daemon=~p",[HostIP,Port,Profile,Daemon]),
+ ?wait_match([{{server,ssh_system_sup, ListenIP,Port,Profile},
Daemon, supervisor,
[ssh_system_sup]}],
supervisor:which_children(sshd_sup),
- Daemon),
+ [ListenIP,Daemon]),
+ true = ssh_test_lib:match_ip(HostIP, ListenIP),
check_sshd_system_tree(Daemon, Config),
ssh:stop_daemon(HostIP, Port, Profile),
ct:sleep(?WAIT_FOR_SHUTDOWN),
?wait_match([], supervisor:which_children(sshd_sup)).
+%%-------------------------------------------------------------------------
+killed_acceptor_restarts(Config) ->
+ Profile = proplists:get_value(profile, Config),
+ SystemDir = proplists:get_value(data_dir, Config),
+ UserDir = proplists:get_value(userdir, Config),
+ {ok, DaemonPid} = ssh:daemon(0, [{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {user_passwords, [{?USER, ?PASSWD}]},
+ {profile, Profile}]),
+
+ {ok, DaemonPid2} = ssh:daemon(0, [{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {user_passwords, [{?USER, ?PASSWD}]},
+ {profile, Profile}]),
+
+ Port = ssh_test_lib:daemon_port(DaemonPid),
+ Port2 = ssh_test_lib:daemon_port(DaemonPid2),
+ true = (Port /= Port2),
+
+ ct:pal("~s",[lists:flatten(ssh_info:string())]),
+
+ {ok,[{AccPid,ListenAddr,Port}]} = acceptor_pid(DaemonPid),
+ {ok,[{AccPid2,ListenAddr,Port2}]} = acceptor_pid(DaemonPid2),
+
+ true = (AccPid /= AccPid2),
+
+ %% Connect first client and check it is alive:
+ {ok,C1} = ssh:connect("localhost", Port, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {user, ?USER},
+ {password, ?PASSWD},
+ {user_dir, UserDir}]),
+ [{client_version,_}] = ssh:connection_info(C1,[client_version]),
+
+ %% Make acceptor restart:
+ exit(AccPid, kill),
+ %% Check it is a new acceptor:
+ {ok,[{AccPid1,ListenAddr,Port}]} = acceptor_pid(DaemonPid),
+ true = (AccPid /= AccPid1),
+ true = (AccPid2 /= AccPid1),
+
+ %% Connect second client and check it is alive:
+ {ok,C2} = ssh:connect("localhost", Port, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {user, ?USER},
+ {password, ?PASSWD},
+ {user_dir, UserDir}]),
+ [{client_version,_}] = ssh:connection_info(C2,[client_version]),
+
+ ct:pal("~s",[lists:flatten(ssh_info:string())]),
+
+ %% Check first client is still alive:
+ [{client_version,_}] = ssh:connection_info(C1,[client_version]),
+
+ ok = ssh:stop_daemon(DaemonPid2),
+ timer:sleep(15000),
+ [{client_version,_}] = ssh:connection_info(C1,[client_version]),
+ [{client_version,_}] = ssh:connection_info(C2,[client_version]),
+
+ ok = ssh:stop_daemon(DaemonPid),
+ timer:sleep(15000),
+ {error,closed} = ssh:connection_info(C1,[client_version]),
+ {error,closed} = ssh:connection_info(C2,[client_version]).
+
+%%-------------------------------------------------------------------------
+%% Help functions
+%%-------------------------------------------------------------------------
check_sshd_system_tree(Daemon, Config) ->
Host = proplists:get_value(host, Config),
Port = proplists:get_value(port, Config),
UserDir = proplists:get_value(userdir, Config),
{ok, Client} = ssh:connect(Host, Port, [{silently_accept_hosts, true},
- {user_interaction, false},
- {user, ?USER}, {password, ?PASSWD},{user_dir, UserDir}]),
+ {user_interaction, false},
+ {user, ?USER},
+ {password, ?PASSWD},
+ {user_dir, UserDir}]),
?wait_match([{_,SubSysSup, supervisor,[ssh_subsystem_sup]},
{{ssh_acceptor_sup,_,_,_}, AccSup, supervisor,[ssh_acceptor_sup]}],
supervisor:which_children(Daemon),
- [SubSysSup,AccSup]),
+ [SubSysSup,AccSup]),
?wait_match([{{server,ssh_connection_sup, _,_},
ConnectionSup, supervisor,
@@ -208,4 +285,33 @@ check_sshd_system_tree(Daemon, Config) ->
?wait_match([{_, _,worker,[ssh_channel]}],
supervisor:which_children(ChannelSup)),
ssh:close(Client).
-
+
+acceptor_pid(DaemonPid) ->
+ Parent = self(),
+ Pid = spawn(fun() ->
+ Parent ! {self(), supsearch,
+ [{AccPid,ListenAddr,Port}
+
+ || {{server,ssh_system_sup,ListenAddr,Port,NS},
+ DPid,supervisor,
+ [ssh_system_sup]} <- supervisor:which_children(sshd_sup),
+ DPid == DaemonPid,
+
+ {{ssh_acceptor_sup,L1,P1,NS1},
+ AccSupPid,supervisor,
+ [ssh_acceptor_sup]} <- supervisor:which_children(DaemonPid),
+ L1 == ListenAddr,
+ P1 == Port,
+ NS1 == NS1,
+
+ {{ssh_acceptor_sup,L2,P2,NS2},
+ AccPid,worker,
+ [ssh_acceptor]} <- supervisor:which_children(AccSupPid),
+ L2 == ListenAddr,
+ P2 == Port,
+ NS2 == NS]}
+ end),
+ receive {Pid, supsearch, L} -> {ok,L}
+ after 2000 -> timeout
+ end.
+
diff --git a/lib/ssh/test/ssh_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl
index 6233680dce..7b273fecef 100644
--- a/lib/ssh/test/ssh_test_lib.erl
+++ b/lib/ssh/test/ssh_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,15 +32,19 @@
-define(TIMEOUT, 50000).
+%%%----------------------------------------------------------------
connect(Port, Options) when is_integer(Port) ->
connect(hostname(), Port, Options).
connect(any, Port, Options) ->
connect(hostname(), Port, Options);
connect(Host, Port, Options) ->
- {ok, ConnectionRef} = ssh:connect(Host, Port, Options),
+ R = ssh:connect(Host, Port, Options),
+ ct:log("~p:~p ssh:connect(~p, ~p, ~p)~n -> ~p",[?MODULE,?LINE,Host, Port, Options, R]),
+ {ok, ConnectionRef} = R,
ConnectionRef.
+%%%----------------------------------------------------------------
daemon(Options) ->
daemon(any, 0, Options).
@@ -53,23 +57,57 @@ daemon(Host, Options) ->
daemon(Host, Port, Options) ->
ct:log("~p:~p Calling ssh:daemon(~p, ~p, ~p)",[?MODULE,?LINE,Host,Port,Options]),
case ssh:daemon(Host, Port, Options) of
- {ok, Pid} when Host == any ->
- ct:log("ssh:daemon ok (1)",[]),
- {Pid, hostname(), daemon_port(Port,Pid)};
{ok, Pid} ->
- ct:log("ssh:daemon ok (2)",[]),
- {Pid, Host, daemon_port(Port,Pid)};
+ {ok,L} = ssh:daemon_info(Pid),
+ ListenPort = proplists:get_value(port, L),
+ ListenIP = proplists:get_value(ip, L),
+ {Pid, ListenIP, ListenPort};
Error ->
ct:log("ssh:daemon error ~p",[Error]),
Error
end.
+%%%----------------------------------------------------------------
+daemon_port(Pid) -> daemon_port(0, Pid).
+
+
daemon_port(0, Pid) -> {ok,Dinf} = ssh:daemon_info(Pid),
proplists:get_value(port, Dinf);
daemon_port(Port, _) -> Port.
-
+%%%----------------------------------------------------------------
+gen_tcp_connect(Host0, Port, Options) ->
+ Host = ssh_test_lib:ntoa(ssh_test_lib:mangle_connect_address(Host0)),
+ ct:log("~p:~p gen_tcp:connect(~p, ~p, ~p)~nHost0 = ~p",
+ [?MODULE,?LINE, Host, Port, Options, Host0]),
+ Result = gen_tcp:connect(Host, Port, Options),
+ ct:log("~p:~p Result = ~p", [?MODULE,?LINE, Result]),
+ Result.
+
+%%%----------------------------------------------------------------
+open_sshc(Host0, Port, OptStr) ->
+ open_sshc(Host0, Port, OptStr, "").
+
+open_sshc(Host0, Port, OptStr, ExecStr) ->
+ Cmd = open_sshc_cmd(Host0, Port, OptStr, ExecStr),
+ Result = os:cmd(Cmd),
+ ct:log("~p:~p Result = ~p", [?MODULE,?LINE, Result]),
+ Result.
+
+
+open_sshc_cmd(Host, Port, OptStr) ->
+ open_sshc_cmd(Host, Port, OptStr, "").
+open_sshc_cmd(Host0, Port, OptStr, ExecStr) ->
+ Host = ssh_test_lib:ntoa(ssh_test_lib:mangle_connect_address(Host0)),
+ Cmd = lists:flatten(["ssh -p ", integer_to_list(Port),
+ " ", OptStr,
+ " ", Host,
+ " ", ExecStr]),
+ ct:log("~p:~p OpenSSH Cmd = ~p", [?MODULE,?LINE, Cmd]),
+ Cmd.
+
+%%%----------------------------------------------------------------
std_daemon(Config, ExtraOpts) ->
PrivDir = proplists:get_value(priv_dir, Config),
UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
@@ -85,6 +123,7 @@ std_daemon1(Config, ExtraOpts) ->
{failfun, fun ssh_test_lib:failfun/2}
| ExtraOpts]).
+%%%----------------------------------------------------------------
std_connect(Config, Host, Port, ExtraOpts) ->
UserDir = proplists:get_value(priv_dir, Config),
_ConnectionRef =
@@ -95,6 +134,7 @@ std_connect(Config, Host, Port, ExtraOpts) ->
{user_interaction, false}
| ExtraOpts]).
+%%%----------------------------------------------------------------
std_simple_sftp(Host, Port, Config) ->
std_simple_sftp(Host, Port, Config, []).
@@ -109,43 +149,49 @@ std_simple_sftp(Host, Port, Config, Opts) ->
ok = ssh:close(ConnectionRef),
Data == ReadData.
+%%%----------------------------------------------------------------
std_simple_exec(Host, Port, Config) ->
std_simple_exec(Host, Port, Config, []).
std_simple_exec(Host, Port, Config, Opts) ->
+ ct:log("~p:~p std_simple_exec",[?MODULE,?LINE]),
ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, Opts),
+ ct:log("~p:~p connected! ~p",[?MODULE,?LINE,ConnectionRef]),
{ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
- success = ssh_connection:exec(ConnectionRef, ChannelId, "23+21-2.", infinity),
- Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"42\n">>}},
- case ssh_test_lib:receive_exec_result(Data) of
- expected ->
- ok;
- Other ->
- ct:fail(Other)
- end,
- ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
- ssh:close(ConnectionRef).
-
-
-start_shell(Port, IOServer, UserDir) ->
- start_shell(Port, IOServer, UserDir, []).
-
-start_shell(Port, IOServer, UserDir, Options) ->
- spawn_link(?MODULE, init_shell, [Port, IOServer, [{user_dir, UserDir}|Options]]).
+ ct:log("~p:~p session_channel ok ~p",[?MODULE,?LINE,ChannelId]),
+ ExecResult = ssh_connection:exec(ConnectionRef, ChannelId, "23+21-2.", infinity),
+ ct:log("~p:~p exec ~p",[?MODULE,?LINE,ExecResult]),
+ case ExecResult of
+ success ->
+ Expected = {ssh_cm, ConnectionRef, {data,ChannelId,0,<<"42\n">>}},
+ case receive_exec_result(Expected) of
+ expected ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end,
+ receive_exec_end(ConnectionRef, ChannelId),
+ ssh:close(ConnectionRef);
+ _ ->
+ ct:fail(ExecResult)
+ end.
+%%%----------------------------------------------------------------
start_shell(Port, IOServer) ->
- spawn_link(?MODULE, init_shell, [Port, IOServer, []]).
+ start_shell(Port, IOServer, []).
-init_shell(Port, IOServer, UserDir) ->
- Host = hostname(),
- Options = [{user_interaction, false}, {silently_accept_hosts,
- true}] ++ UserDir,
- group_leader(IOServer, self()),
- loop_shell(Host, Port, Options).
+start_shell(Port, IOServer, ExtraOptions) ->
+ spawn_link(
+ fun() ->
+ Host = hostname(),
+ Options = [{user_interaction, false},
+ {silently_accept_hosts,true} | ExtraOptions],
+ group_leader(IOServer, self()),
+ ssh:shell(Host, Port, Options)
+ end).
-loop_shell(Host, Port, Options) ->
- ssh:shell(Host, Port, Options).
+%%%----------------------------------------------------------------
start_io_server() ->
spawn_link(?MODULE, init_io_server, [self()]).
@@ -204,10 +250,19 @@ reply(TestCase, Result) ->
%%ct:log("reply ~p sending ~p ! ~p",[self(), TestCase, Result]),
TestCase ! Result.
-
-
+%%%----------------------------------------------------------------
rcv_expected(Expect, SshPort, Timeout) ->
receive
+ {SshPort, Recvd} when is_function(Expect) ->
+ case Expect(Recvd) of
+ true ->
+ ct:log("Got expected ~p from ~p",[Recvd,SshPort]),
+ catch port_close(SshPort),
+ rcv_lingering(50);
+ false ->
+ ct:log("Got UNEXPECTED ~p~n",[Recvd]),
+ rcv_expected(Expect, SshPort, Timeout)
+ end;
{SshPort, Expect} ->
ct:log("Got expected ~p from ~p",[Expect,SshPort]),
catch port_close(SshPort),
@@ -445,8 +500,12 @@ setup_ecdsa_auth_keys(_Size, Dir, UserDir) ->
setup_auth_keys(Keys, Dir) ->
AuthKeys = public_key:ssh_encode(Keys, auth_keys),
AuthKeysFile = filename:join(Dir, "authorized_keys"),
- file:write_file(AuthKeysFile, AuthKeys).
+ ok = file:write_file(AuthKeysFile, AuthKeys),
+ AuthKeys.
+write_auth_keys(Keys, Dir) ->
+ AuthKeysFile = filename:join(Dir, "authorized_keys"),
+ file:write_file(AuthKeysFile, Keys).
del_dirs(Dir) ->
case file:list_dir(Dir) of
@@ -677,13 +736,16 @@ ssh_type() ->
ssh_type1() ->
try
+ ct:log("~p:~p os:find_executable(\"ssh\")",[?MODULE,?LINE]),
case os:find_executable("ssh") of
false ->
ct:log("~p:~p Executable \"ssh\" not found",[?MODULE,?LINE]),
not_found;
- _ ->
+ Path ->
+ ct:log("~p:~p Found \"ssh\" at ~p",[?MODULE,?LINE,Path]),
case os:cmd("ssh -V") of
- "OpenSSH" ++ _ ->
+ Version = "OpenSSH" ++ _ ->
+ ct:log("~p:~p Found OpenSSH ~p",[?MODULE,?LINE,Version]),
openSSH;
Str ->
ct:log("ssh client ~p is unknown",[Str]),
@@ -767,3 +829,157 @@ open_port(Arg1, ExtraOpts) ->
use_stdio,
overlapped_io, hide %only affects windows
| ExtraOpts]).
+
+%%%----------------------------------------------------------------
+%%% Sleeping
+
+%%% Milli sec
+sleep_millisec(Nms) -> receive after Nms -> ok end.
+
+%%% Micro sec
+sleep_microsec(Nus) ->
+ busy_wait(Nus, erlang:system_time(microsecond)).
+
+busy_wait(Nus, T0) ->
+ T = erlang:system_time(microsecond) - T0,
+ Tleft = Nus - T,
+ if
+ Tleft > 2000 ->
+ sleep_millisec((Tleft-1500) div 1000), % μs -> ms
+ busy_wait(Nus,T0);
+ Tleft > 1 ->
+ busy_wait(Nus, T0);
+ true ->
+ T
+ end.
+
+%%%----------------------------------------------------------------
+%% get_kex_init - helper function to get key_exchange_init_msg
+
+get_kex_init(Conn) ->
+ Ref = make_ref(),
+ {ok,TRef} = timer:send_after(15000, {reneg_timeout,Ref}),
+ get_kex_init(Conn, Ref, TRef).
+
+get_kex_init(Conn, Ref, TRef) ->
+ %% First, validate the key exchange is complete (StateName == connected)
+ {State, S} = sys:get_state(Conn),
+ case expected_state(State) of
+ true ->
+ timer:cancel(TRef),
+ %% Next, walk through the elements of the #state record looking
+ %% for the #ssh_msg_kexinit record. This method is robust against
+ %% changes to either record. The KEXINIT message contains a cookie
+ %% unique to each invocation of the key exchange procedure (RFC4253)
+ SL = tuple_to_list(S),
+ case lists:keyfind(ssh_msg_kexinit, 1, SL) of
+ false ->
+ throw(not_found);
+ KexInit ->
+ KexInit
+ end;
+
+ false ->
+ ct:log("Not in 'connected' state: ~p",[State]),
+ receive
+ {reneg_timeout,Ref} ->
+ ct:log("S = ~p", [S]),
+ ct:fail(reneg_timeout)
+ after 0 ->
+ timer:sleep(100), % If renegotiation is complete we do not
+ % want to exit on the reneg_timeout
+ get_kex_init(Conn, Ref, TRef)
+ end
+ end.
+
+expected_state({ext_info,_,_}) -> true;
+expected_state({connected,_}) -> true;
+expected_state(_) -> false.
+
+%%%----------------------------------------------------------------
+%%% Return a string with N random characters
+%%%
+random_chars(N) -> [crypto:rand_uniform($a,$z) || _<-lists:duplicate(N,x)].
+
+
+create_random_dir(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Name = filename:join(PrivDir, random_chars(15)),
+ case file:make_dir(Name) of
+ ok ->
+ Name;
+ {error,eexist} ->
+ %% The Name already denotes an existing file system object, try again.
+ %% The likelyhood of always generating an existing file name is low
+ create_random_dir(Config)
+ end.
+
+%%%----------------------------------------------------------------
+match_ip(A, B) ->
+ R = match_ip0(A,B) orelse match_ip0(B,A),
+ ct:log("match_ip(~p, ~p) -> ~p",[A, B, R]),
+ R.
+
+match_ip0(A, A) ->
+ true;
+match_ip0(any, _) ->
+ true;
+match_ip0(A, B) ->
+ case match_ip1(A, B) of
+ true ->
+ true;
+ false when is_list(A) ->
+ case inet:parse_address(A) of
+ {ok,IPa} -> match_ip0(IPa, B);
+ _ -> false
+ end;
+ false when is_list(B) ->
+ case inet:parse_address(B) of
+ {ok,IPb} -> match_ip0(A, IPb);
+ _ -> false
+ end;
+ false ->
+ false
+ end.
+
+match_ip1(any, _) -> true;
+match_ip1(loopback, {127,_,_,_}) -> true;
+match_ip1({0,0,0,0}, {127,_,_,_}) -> true;
+match_ip1(loopback, {0,0,0,0,0,0,0,1}) -> true;
+match_ip1({0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,1}) -> true;
+match_ip1(_, _) -> false.
+
+%%%----------------------------------------------------------------
+mangle_connect_address(A) ->
+ mangle_connect_address(A, []).
+
+mangle_connect_address(A, SockOpts) ->
+ mangle_connect_address1(A, proplists:get_value(inet6,SockOpts,false)).
+
+loopback(true) -> {0,0,0,0,0,0,0,1};
+loopback(false) -> {127,0,0,1}.
+
+mangle_connect_address1( loopback, V6flg) -> loopback(V6flg);
+mangle_connect_address1( any, V6flg) -> loopback(V6flg);
+mangle_connect_address1({0,0,0,0}, _) -> loopback(false);
+mangle_connect_address1({0,0,0,0,0,0,0,0}, _) -> loopback(true);
+mangle_connect_address1( IP, _) when is_tuple(IP) -> IP;
+mangle_connect_address1(A, _) ->
+ case catch inet:parse_address(A) of
+ {ok, {0,0,0,0}} -> loopback(false);
+ {ok, {0,0,0,0,0,0,0,0}} -> loopback(true);
+ _ -> A
+ end.
+
+%%%----------------------------------------------------------------
+ntoa(A) ->
+ try inet:ntoa(A)
+ of
+ {error,_} when is_atom(A) -> atom_to_list(A);
+ {error,_} when is_list(A) -> A;
+ S when is_list(S) -> S
+ catch
+ _:_ when is_atom(A) -> atom_to_list(A);
+ _:_ when is_list(A) -> A
+ end.
+
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl
index a914938c41..4d6aa93d4e 100644
--- a/lib/ssh/test/ssh_to_openssh_SUITE.erl
+++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,13 +29,14 @@
-define(TIMEOUT, 50000).
-define(SSH_DEFAULT_PORT, 22).
+-define(REKEY_DATA_TMO, 65000).
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
suite() ->
- [{timetrap,{seconds,20}}].
+ [{timetrap,{seconds,60}}].
all() ->
case os:find_executable("ssh") of
@@ -55,10 +56,12 @@ groups() ->
erlang_client_openssh_server_publickey_rsa,
erlang_client_openssh_server_password,
erlang_client_openssh_server_kexs,
- erlang_client_openssh_server_nonexistent_subsystem
+ erlang_client_openssh_server_nonexistent_subsystem,
+ erlang_client_openssh_server_renegotiate
]},
{erlang_server, [], [erlang_server_openssh_client_public_key_dsa,
- erlang_server_openssh_client_public_key_rsa
+ erlang_server_openssh_client_public_key_rsa,
+ erlang_server_openssh_client_renegotiate
]}
].
@@ -104,6 +107,14 @@ init_per_testcase(erlang_server_openssh_client_public_key_rsa, Config) ->
chk_key(sshc, 'ssh-rsa', ".ssh/id_rsa", Config);
init_per_testcase(erlang_client_openssh_server_publickey_dsa, Config) ->
chk_key(sshd, 'ssh-dss', ".ssh/id_dsa", Config);
+init_per_testcase(erlang_client_openssh_server_publickey_rsa, Config) ->
+ chk_key(sshd, 'ssh-rsa', ".ssh/id_rsa", Config);
+
+init_per_testcase(erlang_server_openssh_client_renegotiate, Config) ->
+ case os:type() of
+ {unix,_} -> ssh:start(), Config;
+ Type -> {skip, io_lib:format("Unsupported test on ~p",[Type])}
+ end;
init_per_testcase(_TestCase, Config) ->
ssh:start(),
Config.
@@ -145,7 +156,7 @@ erlang_shell_client_openssh_server(Config) when is_list(Config) ->
IO = ssh_test_lib:start_io_server(),
Shell = ssh_test_lib:start_shell(?SSH_DEFAULT_PORT, IO),
IO ! {input, self(), "echo Hej\n"},
- receive_hej(),
+ receive_data("Hej", undefined),
IO ! {input, self(), "exit\n"},
receive_logout(),
receive_normal_exit(Shell).
@@ -314,78 +325,162 @@ erlang_client_openssh_server_setenv(Config) when is_list(Config) ->
%% setenv not meaningfull on erlang ssh daemon!
%%--------------------------------------------------------------------
-erlang_client_openssh_server_publickey_rsa() ->
- [{doc, "Validate using rsa publickey."}].
-erlang_client_openssh_server_publickey_rsa(Config) when is_list(Config) ->
- {ok,[[Home]]} = init:get_argument(home),
- KeyFile = filename:join(Home, ".ssh/id_rsa"),
- case file:read_file(KeyFile) of
- {ok, Pem} ->
- case public_key:pem_decode(Pem) of
- [{_,_, not_encrypted}] ->
- ConnectionRef =
- ssh_test_lib:connect(?SSH_DEFAULT_PORT,
- [{public_key_alg, ssh_rsa},
- {user_interaction, false},
- silently_accept_hosts]),
- {ok, Channel} =
- ssh_connection:session_channel(ConnectionRef, infinity),
- ok = ssh_connection:close(ConnectionRef, Channel),
- ok = ssh:close(ConnectionRef);
- _ ->
- {skip, {error, "Has pass phrase can not be used by automated test case"}}
- end;
- _ ->
- {skip, "no ~/.ssh/id_rsa"}
- end.
-
+erlang_client_openssh_server_publickey_rsa(Config) ->
+ erlang_client_openssh_server_publickey_X(Config, 'ssh-rsa').
+
+erlang_client_openssh_server_publickey_dsa(Config) ->
+ erlang_client_openssh_server_publickey_X(Config, 'ssh-dss').
-%%--------------------------------------------------------------------
-erlang_client_openssh_server_publickey_dsa() ->
- [{doc, "Validate using dsa publickey."}].
-erlang_client_openssh_server_publickey_dsa(Config) when is_list(Config) ->
+
+erlang_client_openssh_server_publickey_X(Config, Alg) ->
ConnectionRef =
- ssh_test_lib:connect(?SSH_DEFAULT_PORT,
- [{public_key_alg, ssh_dsa},
- {user_interaction, false},
- silently_accept_hosts]),
+ ssh_test_lib:connect(?SSH_DEFAULT_PORT,
+ [{pref_public_key_algs, [Alg]},
+ {user_interaction, false},
+ {auth_methods, "publickey"},
+ silently_accept_hosts]),
{ok, Channel} =
- ssh_connection:session_channel(ConnectionRef, infinity),
+ ssh_connection:session_channel(ConnectionRef, infinity),
ok = ssh_connection:close(ConnectionRef, Channel),
ok = ssh:close(ConnectionRef).
%%--------------------------------------------------------------------
erlang_server_openssh_client_public_key_dsa() ->
- [{timetrap, {seconds,(?TIMEOUT div 1000)+10}},
- {doc, "Validate using dsa publickey."}].
+ [{timetrap, {seconds,(?TIMEOUT div 1000)+10}}].
erlang_server_openssh_client_public_key_dsa(Config) when is_list(Config) ->
- erlang_server_openssh_client_public_key_X(Config, ssh_dsa).
+ erlang_server_openssh_client_public_key_X(Config, 'ssh-dss').
-erlang_server_openssh_client_public_key_rsa() ->
- [{timetrap, {seconds,(?TIMEOUT div 1000)+10}},
- {doc, "Validate using rsa publickey."}].
+erlang_server_openssh_client_public_key_rsa() ->
+ [{timetrap, {seconds,(?TIMEOUT div 1000)+10}}].
erlang_server_openssh_client_public_key_rsa(Config) when is_list(Config) ->
- erlang_server_openssh_client_public_key_X(Config, ssh_rsa).
+ erlang_server_openssh_client_public_key_X(Config, 'ssh-rsa').
-erlang_server_openssh_client_public_key_X(Config, PubKeyAlg) ->
+erlang_server_openssh_client_public_key_X(Config, Alg) ->
SystemDir = proplists:get_value(data_dir, Config),
PrivDir = proplists:get_value(priv_dir, Config),
KnownHosts = filename:join(PrivDir, "known_hosts"),
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {public_key_alg, PubKeyAlg},
+ {preferred_algorithms,[{public_key, [Alg]}]},
+ {auth_methods, "publickey"},
{failfun, fun ssh_test_lib:failfun/2}]),
-
ct:sleep(500),
- Cmd = "ssh -p " ++ integer_to_list(Port) ++
- " -o UserKnownHostsFile=" ++ KnownHosts ++
- " " ++ Host ++ " 1+1.",
+ Cmd = ssh_test_lib:open_sshc_cmd(Host, Port,
+ [" -o UserKnownHostsFile=", KnownHosts,
+ " -o StrictHostKeyChecking=no"],
+ "1+1."),
OpenSsh = ssh_test_lib:open_port({spawn, Cmd}),
ssh_test_lib:rcv_expected({data,<<"2\n">>}, OpenSsh, ?TIMEOUT),
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
+%% Test that the Erlang/OTP server can renegotiate with openSSH
+erlang_server_openssh_client_renegotiate(Config) ->
+ _PubKeyAlg = ssh_rsa,
+ SystemDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ KnownHosts = filename:join(PrivDir, "known_hosts"),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ct:sleep(500),
+
+ RenegLimitK = 3,
+ DataFile = filename:join(PrivDir, "renegotiate_openssh_client.data"),
+ Data = lists:duplicate(trunc(1.1*RenegLimitK*1024), $a),
+ ok = file:write_file(DataFile, Data),
+
+ Cmd = ssh_test_lib:open_sshc_cmd(Host, Port,
+ [" -o UserKnownHostsFile=", KnownHosts,
+ " -o StrictHostKeyChecking=no",
+ " -o RekeyLimit=",integer_to_list(RenegLimitK),"K"]),
+
+
+ OpenSsh = ssh_test_lib:open_port({spawn, Cmd++" < "++DataFile}),
+
+ Expect = fun({data,R}) ->
+ try
+ NonAlphaChars = [C || C<-lists:seq(1,255),
+ not lists:member(C,lists:seq($a,$z)),
+ not lists:member(C,lists:seq($A,$Z))
+ ],
+ Lines = string:tokens(binary_to_list(R), NonAlphaChars),
+ lists:any(fun(L) -> length(L)>1 andalso lists:prefix(L, Data) end,
+ Lines)
+ catch
+ _:_ -> false
+ end;
+
+ ({exit_status,E}) when E=/=0 ->
+ ct:log("exit_status ~p",[E]),
+ throw({skip,"exit status"});
+
+ (_) ->
+ false
+ end,
+
+ try
+ ssh_test_lib:rcv_expected(Expect, OpenSsh, ?TIMEOUT)
+ of
+ _ ->
+ %% Unfortunately we can't check that there has been a renegotiation, just trust OpenSSH.
+ ssh:stop_daemon(Pid)
+ catch
+ throw:{skip,R} -> {skip,R}
+ end.
+
+%%--------------------------------------------------------------------
+erlang_client_openssh_server_renegotiate(_Config) ->
+ process_flag(trap_exit, true),
+ IO = ssh_test_lib:start_io_server(),
+ Ref = make_ref(),
+ Parent = self(),
+
+ Shell =
+ spawn_link(
+ fun() ->
+ Host = ssh_test_lib:hostname(),
+ Options = [{user_interaction, false},
+ {silently_accept_hosts,true}],
+ group_leader(IO, self()),
+ {ok, ConnRef} = ssh:connect(Host, ?SSH_DEFAULT_PORT, Options),
+ ct:log("Parent = ~p, IO = ~p, Shell = ~p, ConnRef = ~p~n",[Parent, IO, self(), ConnRef]),
+ case ssh_connection:session_channel(ConnRef, infinity) of
+ {ok,ChannelId} ->
+ success = ssh_connection:ptty_alloc(ConnRef, ChannelId, []),
+ Args = [{channel_cb, ssh_shell},
+ {init_args,[ConnRef, ChannelId]},
+ {cm, ConnRef}, {channel_id, ChannelId}],
+ {ok, State} = ssh_channel:init([Args]),
+ Parent ! {ok, Ref, ConnRef},
+ ssh_channel:enter_loop(State);
+ Error ->
+ Parent ! {error, Ref, Error}
+ end,
+ receive
+ nothing -> ok
+ end
+ end),
+
+ receive
+ {error, Ref, Error} ->
+ ct:fail("Error=~p",[Error]);
+ {ok, Ref, ConnectionRef} ->
+ IO ! {input, self(), "echo Hej1\n"},
+ receive_data("Hej1", ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
+ ssh_connection_handler:renegotiate(ConnectionRef),
+ IO ! {input, self(), "echo Hej2\n"},
+ receive_data("Hej2", ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
+ IO ! {input, self(), "exit\n"},
+ receive_logout(),
+ receive_normal_exit(Shell),
+ true = (Kex1 =/= Kex2)
+ end.
+
+%%--------------------------------------------------------------------
erlang_client_openssh_server_password() ->
[{doc, "Test client password option"}].
erlang_client_openssh_server_password(Config) when is_list(Config) ->
@@ -440,27 +535,30 @@ erlang_client_openssh_server_nonexistent_subsystem(Config) when is_list(Config)
%%--------------------------------------------------------------------
%%% Internal functions -----------------------------------------------
%%--------------------------------------------------------------------
-receive_hej() ->
+receive_data(Data, Conn) ->
receive
- <<"Hej", _binary>> = Hej ->
- ct:log("Expected result: ~p~n", [Hej]);
- <<"Hej\n", _binary>> = Hej ->
- ct:log("Expected result: ~p~n", [Hej]);
- <<"Hej\r\n", _/binary>> = Hej ->
- ct:log("Expected result: ~p~n", [Hej]);
- Info ->
- Lines = binary:split(Info, [<<"\r\n">>], [global]),
- case lists:member(<<"Hej">>, Lines) of
+ Info when is_binary(Info) ->
+ Lines = string:tokens(binary_to_list(Info), "\r\n "),
+ case lists:member(Data, Lines) of
true ->
- ct:log("Expected result found in lines: ~p~n", [Lines]),
+ ct:log("Expected result ~p found in lines: ~p~n", [Data,Lines]),
ok;
false ->
ct:log("Extra info: ~p~n", [Info]),
- receive_hej()
- end
- after
- 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
- end.
+ receive_data(Data, Conn)
+ end;
+ Other ->
+ ct:log("Unexpected: ~p",[Other]),
+ receive_data(Data, Conn)
+ after
+ 30000 ->
+ {State, _} = case Conn of
+ undefined -> {'??','??'};
+ _ -> sys:get_state(Conn)
+ end,
+ ct:log("timeout ~p:~p~nExpect ~p~nState = ~p",[?MODULE,?LINE,Data,State]),
+ ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
receive_logout() ->
receive
diff --git a/lib/ssh/test/ssh_trpt_test_lib.erl b/lib/ssh/test/ssh_trpt_test_lib.erl
index e34071af99..8de550af15 100644
--- a/lib/ssh/test/ssh_trpt_test_lib.erl
+++ b/lib/ssh/test/ssh_trpt_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -85,15 +85,18 @@ exec(Op, S0=#s{}) ->
throw:Term ->
report_trace(throw, Term, S1),
- throw(Term);
+ throw({Term,Op});
error:Error ->
report_trace(error, Error, S1),
- error(Error);
+ error({Error,Op});
exit:Exit ->
report_trace(exit, Exit, S1),
- exit(Exit)
+ exit({Exit,Op});
+ Cls:Err ->
+ ct:pal("Class=~p, Error=~p", [Cls,Err]),
+ error({"fooooooO",Op})
end;
exec(Op, {ok,S=#s{}}) -> exec(Op, S);
exec(_, Error) -> Error.
@@ -111,20 +114,20 @@ op({accept,Opts}, S) when ?role(S) == server ->
{ok,Socket} = gen_tcp:accept(S#s.listen_socket, S#s.timeout),
{Host,_Port} = ok(inet:sockname(Socket)),
S#s{socket = Socket,
- ssh = init_ssh(server,Socket,[{host,host(Host)}|Opts]),
+ ssh = init_ssh(server, Socket, host(Host), Opts),
return_value = ok};
%%%---- Client ops
op({connect,Host,Port,Opts}, S) when ?role(S) == undefined ->
Socket = ok(gen_tcp:connect(host(Host), Port, mangle_opts([]))),
S#s{socket = Socket,
- ssh = init_ssh(client, Socket, [{host,host(Host)}|Opts]),
+ ssh = init_ssh(client, Socket, host(Host), Opts),
return_value = ok};
%%%---- ops for both client and server
op(close_socket, S) ->
- catch tcp_gen:close(S#s.socket),
- catch tcp_gen:close(S#s.listen_socket),
+ catch gen_tcp:close(S#s.socket),
+ catch gen_tcp:close(S#s.listen_socket),
S#s{socket = undefined,
listen_socket = undefined,
return_value = ok};
@@ -293,12 +296,14 @@ instantiate(X, _S) ->
%%%================================================================
%%%
-init_ssh(Role, Socket, Options0) ->
- Options = [{user_interaction, false},
- {vsn, {2,0}},
- {id_string, "ErlangTestLib"}
- | Options0],
- ssh_connection_handler:init_ssh_record(Role, Socket, Options).
+init_ssh(Role, Socket, Host, UserOptions0) ->
+ UserOptions = [{user_interaction, false},
+ {vsn, {2,0}},
+ {id_string, "ErlangTestLib"}
+ | UserOptions0],
+ Opts = ?PUT_INTERNAL_OPT({host,Host},
+ ssh_options:handle_options(Role, UserOptions)),
+ ssh_connection_handler:init_ssh_record(Role, Socket, Opts).
mangle_opts(Options) ->
SysOpts = [{reuseaddr, true},
@@ -309,8 +314,7 @@ mangle_opts(Options) ->
lists:keydelete(K,1,Opts)
end, Options, SysOpts).
-host({0,0,0,0}) -> "localhost";
-host(H) -> H.
+host(H) -> ssh_test_lib:ntoa(ssh_test_lib:mangle_connect_address(H)).
%%%----------------------------------------------------------------
send(S=#s{ssh=C}, hello) ->
@@ -393,6 +397,12 @@ send(S0, {special,Msg,PacketFun}) when is_tuple(Msg),
send_bytes(Packet, S#s{ssh = C, %%inc_send_seq_num(C),
return_value = Msg});
+send(S0, #ssh_msg_newkeys{} = Msg) ->
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Send~n~s~n",[format_msg(Msg)]} end),
+ {ok, Packet, C} = ssh_transport:new_keys_message(S#s.ssh),
+ send_bytes(Packet, S#s{ssh = C});
+
send(S0, Msg) when is_tuple(Msg) ->
S = opt(print_messages, S0,
fun(X) when X==true;X==detail -> {"Send~n~s~n",[format_msg(Msg)]} end),
@@ -451,7 +461,10 @@ recv(S0 = #s{}) ->
};
#ssh_msg_kexdh_reply{} ->
{ok, _NewKeys, C} = ssh_transport:handle_kexdh_reply(PeerMsg, S#s.ssh),
- S#s{ssh=C#ssh{send_sequence=S#s.ssh#ssh.send_sequence}}; % Back the number
+ S#s{ssh = (S#s.ssh)#ssh{shared_secret = C#ssh.shared_secret,
+ exchanged_hash = C#ssh.exchanged_hash,
+ session_id = C#ssh.session_id}};
+ %%%S#s{ssh=C#ssh{send_sequence=S#s.ssh#ssh.send_sequence}}; % Back the number
#ssh_msg_newkeys{} ->
{ok, C} = ssh_transport:handle_new_keys(PeerMsg, S#s.ssh),
S#s{ssh=C};
diff --git a/lib/ssh/test/ssh_upgrade_SUITE.erl b/lib/ssh/test/ssh_upgrade_SUITE.erl
index b5b27c369a..7b9b109fa1 100644
--- a/lib/ssh/test/ssh_upgrade_SUITE.erl
+++ b/lib/ssh/test/ssh_upgrade_SUITE.erl
@@ -199,6 +199,4 @@ close(#state{server = Server,
connection = undefined}.
-random_contents() -> list_to_binary( random_chars(3) ).
-
-random_chars(N) -> [crypto:rand_uniform($a,$z) || _<-lists:duplicate(N,x)].
+random_contents() -> list_to_binary( ssh_test_lib:random_chars(3) ).
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index b165928877..7208baca6e 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,5 +1,5 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 4.3
+SSH_VSN = 4.5
APP_VSN = "ssh-$(SSH_VSN)"
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index 3b6f988a2d..5a39cac9bc 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2016</year>
+ <year>1999</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -28,6 +28,346 @@
<p>This document describes the changes made to the SSL application.</p>
+<section><title>SSL 8.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ ECDH-ECDSA key exchange supported, was accidently
+ dismissed in earlier versions.</p>
+ <p>
+ Own Id: OTP-14421</p>
+ </item>
+ <item>
+ <p>
+ Correct close semantics for active once connections. This
+ was a timing dependent bug the resulted in the close
+ message not always reaching the ssl user process.</p>
+ <p>
+ Own Id: OTP-14443</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ TLS-1.2 clients will now always send hello messages on
+ its own format, as opposed to earlier versions that will
+ send the hello on the lowest supported version, this is a
+ change supported by the latest RFC.</p>
+ <p>
+ This will make interoperability with some newer servers
+ smoother. Potentially, but unlikely, this could cause a
+ problem with older servers if they do not adhere to the
+ RFC and ignore unknown extensions.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-13820</p>
+ </item>
+ <item>
+ <p>
+ Allow Erlang/OTP to use OpenSSL in FIPS-140 mode, in
+ order to satisfy specific security requirements (mostly
+ by different parts of the US federal government). </p>
+ <p>
+ See the new crypto users guide "FIPS mode" chapter about
+ building and using the FIPS support which is disabled by
+ default.</p>
+ <p>
+ (Thanks to dszoboszlay and legoscia)</p>
+ <p>
+ Own Id: OTP-13921 Aux Id: PR-1180 </p>
+ </item>
+ <item>
+ <p>
+ Implemented DTLS cookie generation, required by spec,
+ instead of using a hardcoded value.</p>
+ <p>
+ Own Id: OTP-14076</p>
+ </item>
+ <item>
+ <p>
+ Implement sliding window replay protection of DTLS
+ records.</p>
+ <p>
+ Own Id: OTP-14077</p>
+ </item>
+ <item>
+ <p>
+ TLS client processes will by default call
+ public_key:pkix_verify_hostname/2 to verify the hostname
+ of the connection with the server certificates specified
+ hostname during certificate path validation. The user may
+ explicitly disables it. Also if the hostname can not be
+ derived from the first argument to connect or is not
+ supplied by the server name indication option, the check
+ will not be performed.</p>
+ <p>
+ Own Id: OTP-14197</p>
+ </item>
+ <item>
+ <p>
+ Extend connection_information/[1,2] . The values
+ session_id, master_secret, client_random and
+ server_random can no be accessed by
+ connection_information/2. Note only session_id will be
+ added to connection_information/1. The rational is that
+ values concerning the connection security should have to
+ be explicitly requested.</p>
+ <p>
+ Own Id: OTP-14291</p>
+ </item>
+ <item>
+ <p>
+ Chacha cipher suites are currently not tested enough to
+ be most preferred ones</p>
+ <p>
+ Own Id: OTP-14382</p>
+ </item>
+ <item>
+ <p>
+ Basic support for DTLS that been tested together with
+ OpenSSL.</p>
+ <p>
+ Test by providing the option {protocol, dtls} to the ssl
+ API functions connect and listen.</p>
+ <p>
+ Own Id: OTP-14388</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 8.1.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Remove debug printout</p>
+ <p>
+ Own Id: OTP-14396</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 8.1.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Correct active once emulation, for TLS. Now all data
+ received by the connection process will be delivered
+ through active once, even when the active once arrives
+ after that the gen_tcp socket is closed by the peer.</p>
+ <p>
+ Own Id: OTP-14300</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 8.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Corrected termination behavior, that caused a PEM cache
+ bug and sometimes resulted in connection failures.</p>
+ <p>
+ Own Id: OTP-14100</p>
+ </item>
+ <item>
+ <p>
+ Fix bug that could hang ssl connection processes when
+ failing to require more data for very large handshake
+ packages. Add option max_handshake_size to mitigate DoS
+ attacks.</p>
+ <p>
+ Own Id: OTP-14138</p>
+ </item>
+ <item>
+ <p>
+ Improved support for CRL handling that could fail to work
+ as intended when an id-ce-extKeyUsage was present in the
+ certificate. Also improvements where needed to
+ distributionpoint handling so that all revocations
+ actually are found and not deemed to be not determinable.</p>
+ <p>
+ Own Id: OTP-14141</p>
+ </item>
+ <item>
+ <p>
+ A TLS handshake might accidentally match old sslv2 format
+ and ssl application would incorrectly aborted TLS
+ handshake with ssl_v2_client_hello_no_supported. Parsing
+ was altered to avoid this problem.</p>
+ <p>
+ Own Id: OTP-14222</p>
+ </item>
+ <item>
+ <p>
+ Correct default cipher list to prefer AES 128 before 3DES</p>
+ <p>
+ Own Id: OTP-14235</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Move PEM cache to a dedicated process, to avoid making
+ the SSL manager process a bottleneck. This improves
+ scalability of TLS connections.</p>
+ <p>
+ Own Id: OTP-13874</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 8.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ List of possible anonymous suites, never supported by
+ default, where incorrect for some TLS versions.</p>
+ <p>
+ Own Id: OTP-13926</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Experimental version of DTLS. It is runnable but not
+ complete and cannot be considered reliable for production
+ usage.</p>
+ <p>
+ Own Id: OTP-12982</p>
+ </item>
+ <item>
+ <p>
+ Add API options to handle ECC curve selection.</p>
+ <p>
+ Own Id: OTP-13959</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 8.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A timing related bug in event handling could cause
+ interoperability problems between an erlang TLS server
+ and some TLS clients, especially noticed with Firefox as
+ TLS client.</p>
+ <p>
+ Own Id: OTP-13917</p>
+ </item>
+ <item>
+ <p>
+ Correct ECC curve selection, the error could cause the
+ default to always be selected.</p>
+ <p>
+ Own Id: OTP-13918</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 8.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Correctly formed handshake messages received out of order
+ will now correctly fail the connection with unexpected
+ message.</p>
+ <p>
+ Own Id: OTP-13853</p>
+ </item>
+
+ <item>
+ <p>Correct handling of signature algorithm selection</p>
+ <p>
+ Own Id: OTP-13711</p>
+ </item>
+
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ ssl application now behaves gracefully also on partially
+ incorrect input from peer.</p>
+ <p>
+ Own Id: OTP-13834</p>
+ </item>
+ <item>
+ <p>
+ Add application environment configuration
+ bypass_pem_cache. This can be used as a workaround for
+ the current implementation of the PEM-cache that has
+ proven to be a bottleneck.</p>
+ <p>
+ Own Id: OTP-13883</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 8.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The TLS/SSL protocol version selection for the SSL server
+ has been corrected to follow RFC 5246 Appendix E.1
+ especially in case where the list of supported versions
+ has gaps. Now the server selects the highest protocol
+ version it supports that is not higher than what the
+ client supports.</p>
+ <p>
+ Own Id: OTP-13753 Aux Id: seq13150 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SSL 8.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index abba5aaf59..ca2dcbb761 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1999</year><year>2016</year>
+ <year>1999</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -127,7 +127,7 @@
<item><p><c>hostname() | ipaddress()</c></p></item>
<tag><c>hostname() =</c></tag>
- <item><p><c>string()</c></p></item>
+ <item><p><c>string() - DNS hostname</c></p></item>
<tag><c>ip_address() =</c></tag>
<item><p><c>{N1,N2,N3,N4} % IPv4 | {K1,K2,K3,K4,K5,K6,K7,K8} % IPv6
@@ -155,7 +155,7 @@
<tag><c>cipher() =</c></tag>
<item><p><c>rc4_128 | des_cbc | '3des_ede_cbc'
- | aes_128_cbc | aes_256_cbc | aes_128_gcm | aes_256_gcm</c></p></item>
+ | aes_128_cbc | aes_256_cbc | aes_128_gcm | aes_256_gcm | chacha20_poly1305</c></p></item>
<tag><c>hash() =</c></tag>
<item><p><c>md5 | sha | sha224 | sha256 | sha348 | sha512</c></p></item>
@@ -170,6 +170,14 @@
<tag><c>SNIfun::fun()</c></tag>
<item><p><c>= fun(ServerName :: string()) -> [ssl_option()]</c></p></item>
+ <tag><c>named_curve() =</c></tag>
+ <item><p><c>sect571r1 | sect571k1 | secp521r1 | brainpoolP512r1
+ | sect409k1 | sect409r1 | brainpoolP384r1 | secp384r1
+ | sect283k1 | sect283r1 | brainpoolP256r1 | secp256k1 | secp256r1
+ | sect239k1 | sect233k1 | sect233r1 | secp224k1 | secp224r1
+ | sect193r1 | sect193r2 | secp192k1 | secp192r1 | sect163k1
+ | sect163r1 | sect163r2 | secp160k1 | secp160r1 | secp160r2</c></p></item>
+
</taglist>
</section>
@@ -181,6 +189,11 @@
<taglist>
+ <tag><c>{protocol, tls | dtls}</c></tag>
+ <item><p>Choose TLS or DTLS protocol for the transport layer security.
+ Defaults to <c>tls</c> Introduced in OTP 20, DTLS support is considered
+ experimental in this release. DTLS over other transports than UDP are not yet supported.</p></item>
+
<tag><c>{cert, public_key:der_encoded()}</c></tag>
<item><p>The DER-encoded users certificate. If this option
is supplied, it overrides option <c>certfile</c>.</p></item>
@@ -217,6 +230,11 @@
Anonymous cipher suites are supported for testing purposes
only and are not be used when security matters.</p></item>
+ <tag><c>{eccs, [named_curve()]}</c></tag>
+ <item><p> Allows to specify the order of preference for named curves
+ and to restrict their usage when using a cipher suite supporting them.
+ </p></item>
+
<tag><c>{secure_renegotiate, boolean()}</c></tag>
<item><p>Specifies if to reject renegotiation attempt that does
not live up to
@@ -236,7 +254,7 @@
be PEER, CA, ROOT-CA; if 2 the path can be PEER, CA, CA,
ROOT-CA, and so on. The default value is 1.</p></item>
- <tag><c>{verify_fun, {Verifyfun :: fun(), InitialUserState ::
+ <tag><marker id="verify_fun"/><c>{verify_fun, {Verifyfun :: fun(), InitialUserState ::
term()}}</c></tag>
<item><p>The verification fun is to be defined as follows:</p>
@@ -411,6 +429,14 @@ marker="public_key:public_key#pkix_path_validation-3">public_key:pkix_path_valid
</taglist>
</item>
+
+ <tag><c>max_handshake_size</c></tag>
+ <item>
+ <p>Integer (24 bits unsigned). Used to limit the size of
+ valid TLS handshake packets to avoid DoS attacks.
+ Defaults to 256*1024.</p>
+ </item>
+
</taglist>
</item>
@@ -561,15 +587,23 @@ fun(srp, Username :: string(), UserState :: term()) ->
<item><p>Specifies the username and password to use to authenticate
to the server.</p></item>
- <tag><c>{server_name_indication, hostname()}</c></tag>
- <item><p>Can be specified when upgrading a TCP socket to a TLS
- socket to use the TLS Server Name Indication extension.</p></item>
+ <tag><c>{server_name_indication, HostName :: hostname()}</c></tag>
+ <item><p>Specify the hostname to be used in TLS Server Name Indication extension.
+ Is usefull when upgrading a TCP socket to a TLS socket or if the hostname can not be
+ derived from the Host argument to <seealso marker="ssl#connect-3">ssl:connect/3</seealso>.
+ Will also cause the client to preform host name verification of the peer certificate
+ <seealso marker="public_key:public_key#pkix_verify_hostname-2">public_key:pkix_verify_hostname(PeerCert, [{dns_id, HostName}])</seealso>
+ </p> during the x509-path validation. If the check fails the error {bad_cert, hostname_check_failiure} will be
+ propagated to the path validation fun <seealso marker="#verify_fun">verify_fun</seealso>
+ </item>
<tag><c>{server_name_indication, disable}</c></tag>
<item>
<p>When starting a TLS connection without upgrade, the Server Name
- Indication extension is sent if possible. This option can be
- used to disable that behavior.</p>
+ Indication extension is sent if possible that is can be derived from the Host argument
+ to <seealso marker="ssl#connect-3">ssl:connect/3</seealso>.
+ This option can be used to disable that behavior.</p>
+ <note><p> Note that this also disables the default host name verification check of the peer certificate.</p></note>
</item>
<tag><c>{fallback, boolean()}</c></tag>
<item>
@@ -751,6 +785,11 @@ fun(srp, Username :: string(), UserState :: term()) ->
(the default), use the client's preference.
</item>
+ <tag><c>{honor_ecc_order, boolean()}</c></tag>
+ <item>If true, use the server's preference for ECC curve selection. If false
+ (the default), use the client's preference.
+ </item>
+
<tag><c>{signature_algs, [{hash(), ecdsa | rsa | dsa}]}</c></tag>
<item><p> The algorithms specified by
this option will be the ones accepted by the server in a signature algorithm
@@ -804,6 +843,17 @@ fun(srp, Username :: string(), UserState :: term()) ->
</func>
<func>
+ <name>eccs() -></name>
+ <name>eccs(protocol()) -> [named_curve()]</name>
+ <fsummary>Returns a list of supported ECCs.</fsummary>
+
+ <desc><p>Returns a list of supported ECCs. <c>eccs()</c>
+ is equivalent to calling <c>eccs(Protocol)</c> with all
+ supported protocols and then deduplicating the output.</p>
+ </desc>
+ </func>
+
+ <func>
<name>clear_pem_cache() -> ok </name>
<fsummary> Clears the pem cache</fsummary>
@@ -898,13 +948,14 @@ fun(srp, Username :: string(), UserState :: term()) ->
<fsummary>Returns all the connection information.
</fsummary>
<type>
- <v>Item = protocol | cipher_suite | sni_hostname | atom()</v>
+ <v>Item = protocol | cipher_suite | sni_hostname | ecc | session_id | atom()</v>
<d>Meaningful atoms, not specified above, are the ssl option names.</d>
<v>Result = [{Item::atom(), Value::term()}]</v>
<v>Reason = term()</v>
</type>
- <desc><p>Returns all relevant information about the connection, ssl options that
- are undefined will be filtered out.</p>
+ <desc><p>Returns the most relevant information about the connection, ssl options that
+ are undefined will be filtered out. Note that values that affect the security of the
+ connection will only be returned if explicitly requested by connection_information/2.</p>
</desc>
</func>
@@ -915,8 +966,10 @@ fun(srp, Username :: string(), UserState :: term()) ->
</fsummary>
<type>
<v>Items = [Item]</v>
- <v>Item = protocol | cipher_suite | sni_hostname | atom()</v>
- <d>Meaningful atoms, not specified above, are the ssl option names.</d>
+ <v>Item = protocol | cipher_suite | sni_hostname | ecc | session_id | client_random
+ | server_random | master_secret | atom()</v>
+ <d>Note that client_random, server_random and master_secret are values
+ that affect the security of connection. Meaningful atoms, not specified above, are the ssl option names.</d>
<v>Result = [{Item::atom(), Value::term()}]</v>
<v>Reason = term()</v>
</type>
diff --git a/lib/ssl/doc/src/ssl_app.xml b/lib/ssl/doc/src/ssl_app.xml
index a66e947bc1..f317dfded4 100644
--- a/lib/ssl/doc/src/ssl_app.xml
+++ b/lib/ssl/doc/src/ssl_app.xml
@@ -141,6 +141,16 @@
marker="ssl#clear_pem_cache-0">ssl:clear_pem_cache/0</seealso>
</item>
+
+ <tag><c><![CDATA[bypass_pem_cache = boolean() <optional>]]></c></tag>
+ <item>
+ <p>Introduced in ssl-8.0.2. Disables the PEM-cache.
+ The PEM cache has proven to be a bottleneck, until the
+ implementation has been improved this can be used as
+ a workaround. Defaults to false.
+ </p>
+ </item>
+
<tag><c><![CDATA[alert_timeout = integer() <optional>]]></c></tag>
<item>
<p>
diff --git a/lib/ssl/doc/src/ssl_crl_cache_api.xml b/lib/ssl/doc/src/ssl_crl_cache_api.xml
index 7440b6ef04..c6774b4df6 100644
--- a/lib/ssl/doc/src/ssl_crl_cache_api.xml
+++ b/lib/ssl/doc/src/ssl_crl_cache_api.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2015</year><year>2015</year>
+ <year>2015</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/ssl/doc/src/ssl_distribution.xml b/lib/ssl/doc/src/ssl_distribution.xml
index 4bd5f67202..61f88e3860 100644
--- a/lib/ssl/doc/src/ssl_distribution.xml
+++ b/lib/ssl/doc/src/ssl_distribution.xml
@@ -43,7 +43,7 @@
Erlang node distributed, <c>net_kernel</c> uses this module to
set up listen ports and connections.</p>
- <p>In the SSL application, an exra distribution
+ <p>In the SSL application, an extra distribution
module, <c>inet_tls_dist</c>, can be used as an
alternative. All distribution connections will use SSL and
all participating Erlang nodes in a distributed system must use
@@ -71,8 +71,8 @@
<section>
<title>Building Boot Scripts Including the ssl Application</title>
<p>Boot scripts are built using the <c>systools</c> utility in the
- <c>sasl</c> application. For more information on <c>systools</c>,
- see the <c>sasl</c> documentation. This is only an example of
+ SASL application. For more information on <c>systools</c>,
+ see the SASL documentation. This is only an example of
what can be done.</p>
<p>The simplest boot script possible includes only the Kernel
diff --git a/lib/ssl/doc/src/ssl_session_cache_api.xml b/lib/ssl/doc/src/ssl_session_cache_api.xml
index b85d8fb284..a84a3dfce9 100644
--- a/lib/ssl/doc/src/ssl_session_cache_api.xml
+++ b/lib/ssl/doc/src/ssl_session_cache_api.xml
@@ -4,14 +4,14 @@
<erlref>
<header>
<copyright>
- <year>1999</year><year>2015</year>
+ <year>1999</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -62,8 +62,8 @@
</taglist>
</section>
-
- <funcs>
+
+ <funcs>
<func>
<name>delete(Cache, Key) -> _</name>
@@ -134,7 +134,7 @@
</p>
</desc>
</func>
-
+
<func>
<name>select_session(Cache, PartialKey) -> [session()]</name>
<fsummary>Selects sessions that can be reused.</fsummary>
@@ -151,6 +151,21 @@
</func>
<func>
+ <name>size(Cache) -> integer()</name>
+ <fsummary>Returns the number of sessions in the cache.</fsummary>
+ <type>
+ <v>Cache = cache_ref()</v>
+ </type>
+ <desc>
+ <p>Returns the number of sessions in the cache. If size
+ exceeds the maximum number of sessions, the current cache
+ entries will be invalidated regardless of their remaining
+ lifetime. Is to be callable from any process.
+ </p>
+ </desc>
+ </func>
+
+ <func>
<name>terminate(Cache) -> _</name>
<fsummary>Called by the process that handles the cache when it
is about to terminate.</fsummary>
@@ -178,7 +193,7 @@
</p>
</desc>
</func>
-
- </funcs>
-
+
+ </funcs>
+
</erlref>
diff --git a/lib/ssl/src/Makefile b/lib/ssl/src/Makefile
index b625db0656..2e7df9792e 100644
--- a/lib/ssl/src/Makefile
+++ b/lib/ssl/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2015. All Rights Reserved.
+# Copyright Ericsson AB 1999-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -48,8 +48,17 @@ MODULES= \
dtls \
ssl_alert \
ssl_app \
- ssl_dist_sup\
ssl_sup \
+ ssl_admin_sup\
+ tls_connection_sup \
+ ssl_connection_sup \
+ ssl_listen_tracker_sup\
+ dtls_connection_sup \
+ dtls_udp_listener\
+ dtls_udp_sup \
+ ssl_dist_sup\
+ ssl_dist_admin_sup\
+ ssl_dist_connection_sup\
inet_tls_dist \
inet6_tls_dist \
ssl_certificate\
@@ -60,19 +69,18 @@ MODULES= \
dtls_connection \
ssl_config \
ssl_connection \
- tls_connection_sup \
- dtls_connection_sup \
tls_handshake \
dtls_handshake\
ssl_handshake\
ssl_manager \
ssl_session \
ssl_session_cache \
+ ssl_pem_cache \
ssl_crl\
ssl_crl_cache \
ssl_crl_hash_dir \
- ssl_socket \
- ssl_listen_tracker_sup \
+ tls_socket \
+ dtls_socket \
tls_record \
dtls_record \
ssl_record \
diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl
index b8be686b99..e8cfbbe2e3 100644
--- a/lib/ssl/src/dtls_connection.erl
+++ b/lib/ssl/src/dtls_connection.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -39,35 +39,28 @@
-export([start_fsm/8, start_link/7, init/1]).
%% State transition handling
--export([next_record/1, next_event/3]).
+-export([next_record/1, next_event/3, next_event/4]).
%% Handshake handling
--export([%%renegotiate/2,
- send_handshake/2, queue_handshake/2, queue_change_cipher/2]).
+-export([renegotiate/2,
+ reinit_handshake_data/1,
+ send_handshake/2, queue_handshake/2, queue_change_cipher/2,
+ select_sni_extension/1]).
%% Alert and close handling
--export([%%send_alert/2, handle_own_alert/4, handle_close_alert/3,
- handle_normal_shutdown/3 %%, close/5
- %%alert_user/6, alert_user/9
- ]).
+-export([encode_alert/3,send_alert/2, close/5]).
%% Data handling
--export([%%write_application_data/3,
- read_application_data/2,
- passive_receive/2, next_record_if_active/1%,
- %%handle_common_event/4,
- %handle_packet/3
- ]).
+-export([encode_data/3, passive_receive/2, next_record_if_active/1, handle_common_event/4,
+ send/3, socket/5, setopts/3, getopts/3]).
%% gen_statem state functions
-export([init/3, error/3, downgrade/3, %% Initiation and take down states
hello/3, certify/3, cipher/3, abbreviated/3, %% Handshake states
connection/3]).
%% gen_statem callbacks
--export([terminate/3, code_change/4, format_status/2]).
-
--define(GEN_STATEM_CB_MODE, state_functions).
+-export([callback_mode/0, terminate/3, code_change/4, format_status/2]).
%%====================================================================
%% Internal application API
@@ -84,70 +77,144 @@ start_fsm(Role, Host, Port, Socket, {#ssl_options{erl_dist = false},_, Tracker}
catch
error:{badmatch, {error, _} = Error} ->
Error
- end;
-
-start_fsm(Role, Host, Port, Socket, {#ssl_options{erl_dist = true},_, Tracker} = Opts,
- User, {CbModule, _,_, _} = CbInfo,
- Timeout) ->
- try
- {ok, Pid} = dtls_connection_sup:start_child_dist([Role, Host, Port, Socket,
- Opts, User, CbInfo]),
- {ok, SslSocket} = ssl_connection:socket_control(?MODULE, Socket, Pid, CbModule, Tracker),
- ok = ssl_connection:handshake(SslSocket, Timeout),
- {ok, SslSocket}
- catch
- error:{badmatch, {error, _} = Error} ->
- Error
end.
-send_handshake(Handshake, State) ->
- send_handshake_flight(queue_handshake(Handshake, State)).
-
-queue_flight_buffer(Msg, #state{negotiated_version = Version,
- connection_states = #connection_states{
- current_write =
- #connection_state{epoch = Epoch}},
- flight_buffer = Flight} = State) ->
- State#state{flight_buffer = Flight ++ [{Version, Epoch, Msg}]}.
+send_handshake(Handshake, #state{connection_states = ConnectionStates} = States) ->
+ #{epoch := Epoch} = ssl_record:current_connection_state(ConnectionStates, write),
+ send_handshake_flight(queue_handshake(Handshake, States), Epoch).
+
+queue_handshake(Handshake0, #state{tls_handshake_history = Hist0,
+ negotiated_version = Version,
+ flight_buffer = #{handshakes := HsBuffer0,
+ change_cipher_spec := undefined,
+ next_sequence := Seq} = Flight0} = State) ->
+ Handshake = dtls_handshake:encode_handshake(Handshake0, Version, Seq),
+ Hist = update_handshake_history(Handshake0, Handshake, Hist0),
+ State#state{flight_buffer = Flight0#{handshakes => [Handshake | HsBuffer0],
+ next_sequence => Seq +1},
+ tls_handshake_history = Hist};
+
+queue_handshake(Handshake0, #state{tls_handshake_history = Hist0,
+ negotiated_version = Version,
+ flight_buffer = #{handshakes_after_change_cipher_spec := Buffer0,
+ next_sequence := Seq} = Flight0} = State) ->
+ Handshake = dtls_handshake:encode_handshake(Handshake0, Version, Seq),
+ Hist = update_handshake_history(Handshake0, Handshake, Hist0),
+ State#state{flight_buffer = Flight0#{handshakes_after_change_cipher_spec => [Handshake | Buffer0],
+ next_sequence => Seq +1},
+ tls_handshake_history = Hist}.
-queue_handshake(Handshake, #state{negotiated_version = Version,
- tls_handshake_history = Hist0,
- connection_states = ConnectionStates0} = State0) ->
- {Frag, ConnectionStates, Hist} =
- encode_handshake(Handshake, Version, ConnectionStates0, Hist0),
- queue_flight_buffer(Frag, State0#state{connection_states = ConnectionStates,
- tls_handshake_history = Hist}).
send_handshake_flight(#state{socket = Socket,
transport_cb = Transport,
- flight_buffer = Flight,
- connection_states = ConnectionStates0} = State0) ->
-
+ flight_buffer = #{handshakes := Flight,
+ change_cipher_spec := undefined},
+ negotiated_version = Version,
+ connection_states = ConnectionStates0} = State0, Epoch) ->
+ %% TODO remove hardcoded Max size
{Encoded, ConnectionStates} =
- encode_handshake_flight(Flight, ConnectionStates0),
+ encode_handshake_flight(lists:reverse(Flight), Version, 1400, Epoch, ConnectionStates0),
+ send(Transport, Socket, Encoded),
+ {State0#state{connection_states = ConnectionStates}, []};
+
+send_handshake_flight(#state{socket = Socket,
+ transport_cb = Transport,
+ flight_buffer = #{handshakes := [_|_] = Flight0,
+ change_cipher_spec := ChangeCipher,
+ handshakes_after_change_cipher_spec := []},
+ negotiated_version = Version,
+ connection_states = ConnectionStates0} = State0, Epoch) ->
+ {HsBefore, ConnectionStates1} =
+ encode_handshake_flight(lists:reverse(Flight0), Version, 1400, Epoch, ConnectionStates0),
+ {EncChangeCipher, ConnectionStates} = encode_change_cipher(ChangeCipher, Version, Epoch, ConnectionStates1),
+
+ send(Transport, Socket, [HsBefore, EncChangeCipher]),
+ {State0#state{connection_states = ConnectionStates}, []};
- Transport:send(Socket, Encoded),
- State0#state{flight_buffer = [], connection_states = ConnectionStates}.
+send_handshake_flight(#state{socket = Socket,
+ transport_cb = Transport,
+ flight_buffer = #{handshakes := [_|_] = Flight0,
+ change_cipher_spec := ChangeCipher,
+ handshakes_after_change_cipher_spec := Flight1},
+ negotiated_version = Version,
+ connection_states = ConnectionStates0} = State0, Epoch) ->
+ {HsBefore, ConnectionStates1} =
+ encode_handshake_flight(lists:reverse(Flight0), Version, 1400, Epoch-1, ConnectionStates0),
+ {EncChangeCipher, ConnectionStates2} =
+ encode_change_cipher(ChangeCipher, Version, Epoch-1, ConnectionStates1),
+ {HsAfter, ConnectionStates} =
+ encode_handshake_flight(lists:reverse(Flight1), Version, 1400, Epoch, ConnectionStates2),
+ send(Transport, Socket, [HsBefore, EncChangeCipher, HsAfter]),
+ {State0#state{connection_states = ConnectionStates}, []};
-queue_change_cipher(Msg, State) ->
- queue_flight_buffer(Msg, State).
+send_handshake_flight(#state{socket = Socket,
+ transport_cb = Transport,
+ flight_buffer = #{handshakes := [],
+ change_cipher_spec := ChangeCipher,
+ handshakes_after_change_cipher_spec := Flight1},
+ negotiated_version = Version,
+ connection_states = ConnectionStates0} = State0, Epoch) ->
+ {EncChangeCipher, ConnectionStates1} =
+ encode_change_cipher(ChangeCipher, Version, Epoch-1, ConnectionStates0),
+ {HsAfter, ConnectionStates} =
+ encode_handshake_flight(lists:reverse(Flight1), Version, 1400, Epoch, ConnectionStates1),
+ send(Transport, Socket, [EncChangeCipher, HsAfter]),
+ {State0#state{connection_states = ConnectionStates}, []}.
+
+queue_change_cipher(ChangeCipher, #state{flight_buffer = Flight,
+ connection_states = ConnectionStates0} = State) ->
+ ConnectionStates =
+ dtls_record:next_epoch(ConnectionStates0, write),
+ State#state{flight_buffer = Flight#{change_cipher_spec => ChangeCipher},
+ connection_states = ConnectionStates}.
send_alert(Alert, #state{negotiated_version = Version,
socket = Socket,
transport_cb = Transport,
connection_states = ConnectionStates0} = State0) ->
{BinMsg, ConnectionStates} =
- ssl_alert:encode(Alert, Version, ConnectionStates0),
- Transport:send(Socket, BinMsg),
+ encode_alert(Alert, Version, ConnectionStates0),
+ send(Transport, Socket, BinMsg),
State0#state{connection_states = ConnectionStates}.
+close(downgrade, _,_,_,_) ->
+ ok;
+%% Other
+close(_, Socket, Transport, _,_) ->
+ dtls_socket:close(Transport,Socket).
+
+reinit_handshake_data(#state{protocol_buffers = Buffers} = State) ->
+ State#state{premaster_secret = undefined,
+ public_key_info = undefined,
+ tls_handshake_history = ssl_handshake:init_handshake_history(),
+ flight_state = {retransmit, ?INITIAL_RETRANSMIT_TIMEOUT},
+ protocol_buffers =
+ Buffers#protocol_buffers{
+ dtls_handshake_next_seq = 0,
+ dtls_handshake_next_fragments = [],
+ dtls_handshake_later_fragments = []
+ }}.
+
+select_sni_extension(#client_hello{extensions = HelloExtensions}) ->
+ HelloExtensions#hello_extensions.sni;
+select_sni_extension(_) ->
+ undefined.
+
+socket(Pid, Transport, Socket, Connection, _) ->
+ dtls_socket:socket(Pid, Transport, Socket, Connection).
+
+setopts(Transport, Socket, Other) ->
+ dtls_socket:setopts(Transport, Socket, Other).
+getopts(Transport, Socket, Tag) ->
+ dtls_socket:getopts(Transport, Socket, Tag).
+
%%====================================================================
%% tls_connection_sup API
%%====================================================================
%%--------------------------------------------------------------------
-spec start_link(atom(), host(), inet:port_number(), port(), list(), pid(), tuple()) ->
- {ok, pid()} | ignore | {error, reason()}.
+ {ok, pid()} | ignore | {error, reason()}.
%%
%% Description: Creates a gen_fsm process which calls Module:init/1 to
%% initialize. To ensure a synchronized start-up procedure, this function
@@ -161,21 +228,25 @@ init([Role, Host, Port, Socket, Options, User, CbInfo]) ->
State0 = initial_state(Role, Host, Port, Socket, Options, User, CbInfo),
try
State = ssl_connection:ssl_config(State0#state.ssl_options, Role, State0),
- gen_statem:enter_loop(?MODULE, [], ?GEN_STATEM_CB_MODE, init, State)
+ gen_statem:enter_loop(?MODULE, [], init, State)
catch
throw:Error ->
- gen_statem:enter_loop(?MODULE, [], ?GEN_STATEM_CB_MODE, error, {Error,State0})
+ gen_statem:enter_loop(?MODULE, [], error, {Error,State0})
end.
+callback_mode() ->
+ [state_functions, state_enter].
+
%%--------------------------------------------------------------------
-%% State functionsconnection/2
+%% State functions
%%--------------------------------------------------------------------
+init(enter, _, State) ->
+ {keep_state, State};
init({call, From}, {start, Timeout},
#state{host = Host, port = Port, role = client,
ssl_options = SslOpts,
session = #session{own_certificate = Cert} = Session0,
- transport_cb = Transport, socket = Socket,
connection_states = ConnectionStates0,
renegotiation = {Renegotiation, _},
session_cache = Cache,
@@ -183,26 +254,38 @@ init({call, From}, {start, Timeout},
} = State0) ->
Timer = ssl_connection:start_or_recv_cancel_timer(Timeout, From),
Hello = dtls_handshake:client_hello(Host, Port, ConnectionStates0, SslOpts,
- Cache, CacheCb, Renegotiation, Cert),
-
+ Cache, CacheCb, Renegotiation, Cert),
+
Version = Hello#client_hello.client_version,
- HelloVersion = dtls_record:lowest_protocol_version(SslOpts#ssl_options.versions),
- Handshake0 = ssl_handshake:init_handshake_history(),
- {BinMsg, ConnectionStates, Handshake} =
- encode_handshake(Hello, HelloVersion, ConnectionStates0, Handshake0),
- Transport:send(Socket, BinMsg),
- State1 = State0#state{connection_states = ConnectionStates,
- negotiated_version = Version, %% Requested version
+ HelloVersion = dtls_record:hello_version(Version, SslOpts#ssl_options.versions),
+ State1 = prepare_flight(State0#state{negotiated_version = Version}),
+ {State2, Actions} = send_handshake(Hello, State1#state{negotiated_version = HelloVersion}),
+ State3 = State2#state{negotiated_version = Version, %% Requested version
session =
Session0#session{session_id = Hello#client_hello.session_id},
- tls_handshake_history = Handshake,
start_or_recv_from = From,
- timer = Timer},
- {Record, State} = next_record(State1),
- next_event(hello, Record, State);
+ timer = Timer,
+ flight_state = {retransmit, ?INITIAL_RETRANSMIT_TIMEOUT}
+ },
+ {Record, State} = next_record(State3),
+ next_event(hello, Record, State, Actions);
+init({call, _} = Type, Event, #state{role = server, transport_cb = gen_udp} = State) ->
+ Result = ssl_connection:init(Type, Event,
+ State#state{flight_state = {retransmit, ?INITIAL_RETRANSMIT_TIMEOUT},
+ protocol_specific = #{current_cookie_secret => dtls_v1:cookie_secret(),
+ previous_cookie_secret => <<>>}},
+ ?MODULE),
+ erlang:send_after(dtls_v1:cookie_timeout(), self(), new_cookie_secret),
+ Result;
+
+init({call, _} = Type, Event, #state{role = server} = State) ->
+ %% I.E. DTLS over sctp
+ ssl_connection:init(Type, Event, State#state{flight_state = reliable}, ?MODULE);
init(Type, Event, State) ->
ssl_connection:init(Type, Event, State, ?MODULE).
+error(enter, _, State) ->
+ {keep_state, State};
error({call, From}, {start, _Timeout}, {Error, State}) ->
{stop_and_reply, normal, {reply, From, {error, Error}}, State};
error({call, From}, Msg, State) ->
@@ -216,37 +299,70 @@ error(_, _, _) ->
#state{}) ->
gen_statem:state_function_result().
%%--------------------------------------------------------------------
-hello(internal, #client_hello{client_version = ClientVersion,
- extensions = #hello_extensions{ec_point_formats = EcPointFormats,
- elliptic_curves = EllipticCurves}} = Hello,
- State = #state{connection_states = ConnectionStates0,
- port = Port, session = #session{own_certificate = Cert} = Session0,
- renegotiation = {Renegotiation, _},
- session_cache = Cache,
- session_cache_cb = CacheCb,
- negotiated_protocol = CurrentProtocol,
- key_algorithm = KeyExAlg,
- ssl_options = SslOpts}) ->
-
- case dtls_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb,
- ConnectionStates0, Cert, KeyExAlg}, Renegotiation) of
- #alert{} = Alert ->
- handle_own_alert(Alert, ClientVersion, hello, State);
- {Version, {Type, Session},
- ConnectionStates, Protocol0, ServerHelloExt, HashSign} ->
- Protocol = case Protocol0 of
- undefined -> CurrentProtocol;
- _ -> Protocol0
- end,
-
- ssl_connection:hello(internal, {common_client_hello, Type, ServerHelloExt},
- State#state{connection_states = ConnectionStates,
- negotiated_version = Version,
- hashsign_algorithm = HashSign,
- session = Session,
- client_ecc = {EllipticCurves, EcPointFormats},
- negotiated_protocol = Protocol}, ?MODULE)
+hello(enter, _, #state{role = server} = State) ->
+ {keep_state, State};
+hello(enter, _, #state{role = client} = State0) ->
+ {State, Actions} = handle_flight_timer(State0),
+ {keep_state, State, Actions};
+hello(internal, #client_hello{cookie = <<>>,
+ client_version = Version} = Hello, #state{role = server,
+ transport_cb = Transport,
+ socket = Socket,
+ protocol_specific = #{current_cookie_secret := Secret}} = State0) ->
+ {ok, {IP, Port}} = dtls_socket:peername(Transport, Socket),
+ Cookie = dtls_handshake:cookie(Secret, IP, Port, Hello),
+ %% FROM RFC 6347 regarding HelloVerifyRequest message:
+ %% The server_version field has the same syntax as in TLS. However, in
+ %% order to avoid the requirement to do version negotiation in the
+ %% initial handshake, DTLS 1.2 server implementations SHOULD use DTLS
+ %% version 1.0 regardless of the version of TLS that is expected to be
+ %% negotiated.
+ VerifyRequest = dtls_handshake:hello_verify_request(Cookie, ?HELLO_VERIFY_REQUEST_VERSION),
+ State1 = prepare_flight(State0#state{negotiated_version = Version}),
+ {State2, Actions} = send_handshake(VerifyRequest, State1),
+ {Record, State} = next_record(State2),
+ next_event(hello, Record, State#state{tls_handshake_history = ssl_handshake:init_handshake_history()}, Actions);
+hello(internal, #client_hello{cookie = Cookie} = Hello, #state{role = server,
+ transport_cb = Transport,
+ socket = Socket,
+ protocol_specific = #{current_cookie_secret := Secret,
+ previous_cookie_secret := PSecret}} = State0) ->
+ {ok, {IP, Port}} = dtls_socket:peername(Transport, Socket),
+ case dtls_handshake:cookie(Secret, IP, Port, Hello) of
+ Cookie ->
+ handle_client_hello(Hello, State0);
+ _ ->
+ case dtls_handshake:cookie(PSecret, IP, Port, Hello) of
+ Cookie ->
+ handle_client_hello(Hello, State0);
+ _ ->
+ %% Handle bad cookie as new cookie request RFC 6347 4.1.2
+ hello(internal, Hello#client_hello{cookie = <<>>}, State0)
+ end
end;
+hello(internal, #hello_verify_request{cookie = Cookie}, #state{role = client,
+ host = Host, port = Port,
+ ssl_options = SslOpts,
+ session = #session{own_certificate = OwnCert}
+ = Session0,
+ connection_states = ConnectionStates0,
+ renegotiation = {Renegotiation, _},
+ session_cache = Cache,
+ session_cache_cb = CacheCb
+ } = State0) ->
+ State1 = prepare_flight(State0#state{tls_handshake_history = ssl_handshake:init_handshake_history()}),
+ Hello = dtls_handshake:client_hello(Host, Port, Cookie, ConnectionStates0,
+ SslOpts,
+ Cache, CacheCb, Renegotiation, OwnCert),
+ Version = Hello#client_hello.client_version,
+ HelloVersion = dtls_record:lowest_protocol_version(SslOpts#ssl_options.versions),
+ {State2, Actions} = send_handshake(Hello, State1#state{negotiated_version = HelloVersion}),
+ State3 = State2#state{negotiated_version = Version, %% Requested version
+ session =
+ Session0#session{session_id =
+ Hello#client_hello.session_id}},
+ {Record, State} = next_record(State3),
+ next_event(hello, Record, State, Actions);
hello(internal, #server_hello{} = Hello,
#state{connection_states = ConnectionStates0,
negotiated_version = ReqVersion,
@@ -255,32 +371,78 @@ hello(internal, #server_hello{} = Hello,
ssl_options = SslOptions} = State) ->
case dtls_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of
#alert{} = Alert ->
- handle_own_alert(Alert, ReqVersion, hello, State);
+ ssl_connection:handle_own_alert(Alert, ReqVersion, hello, State);
{Version, NewId, ConnectionStates, ProtoExt, Protocol} ->
ssl_connection:handle_session(Hello,
Version, NewId, ConnectionStates, ProtoExt, Protocol, State)
end;
+hello(internal, {handshake, {#client_hello{cookie = <<>>} = Handshake, _}}, State) ->
+ %% Initial hello should not be in handshake history
+ {next_state, hello, State, [{next_event, internal, Handshake}]};
+hello(internal, {handshake, {#hello_verify_request{} = Handshake, _}}, State) ->
+ %% hello_verify should not be in handshake history
+ {next_state, hello, State, [{next_event, internal, Handshake}]};
hello(info, Event, State) ->
handle_info(Event, hello, State);
-
+hello(state_timeout, Event, State) ->
+ handle_state_timeout(Event, hello, State);
hello(Type, Event, State) ->
ssl_connection:hello(Type, Event, State, ?MODULE).
+abbreviated(enter, _, State0) ->
+ {State, Actions} = handle_flight_timer(State0),
+ {keep_state, State, Actions};
abbreviated(info, Event, State) ->
handle_info(Event, abbreviated, State);
+abbreviated(internal = Type,
+ #change_cipher_spec{type = <<1>>} = Event,
+ #state{connection_states = ConnectionStates0} = State) ->
+ ConnectionStates1 = dtls_record:save_current_connection_state(ConnectionStates0, read),
+ ConnectionStates = dtls_record:next_epoch(ConnectionStates1, read),
+ ssl_connection:abbreviated(Type, Event, State#state{connection_states = ConnectionStates}, ?MODULE);
+abbreviated(internal = Type, #finished{} = Event, #state{connection_states = ConnectionStates} = State) ->
+ ssl_connection:abbreviated(Type, Event,
+ prepare_flight(State#state{connection_states = ConnectionStates,
+ flight_state = connection}), ?MODULE);
+abbreviated(state_timeout, Event, State) ->
+ handle_state_timeout(Event, abbreviated, State);
abbreviated(Type, Event, State) ->
ssl_connection:abbreviated(Type, Event, State, ?MODULE).
+certify(enter, _, State0) ->
+ {State, Actions} = handle_flight_timer(State0),
+ {keep_state, State, Actions};
certify(info, Event, State) ->
handle_info(Event, certify, State);
+certify(internal = Type, #server_hello_done{} = Event, State) ->
+ ssl_connection:certify(Type, Event, prepare_flight(State), ?MODULE);
+certify(state_timeout, Event, State) ->
+ handle_state_timeout(Event, certify, State);
certify(Type, Event, State) ->
ssl_connection:certify(Type, Event, State, ?MODULE).
+cipher(enter, _, State0) ->
+ {State, Actions} = handle_flight_timer(State0),
+ {keep_state, State, Actions};
cipher(info, Event, State) ->
handle_info(Event, cipher, State);
+cipher(internal = Type, #change_cipher_spec{type = <<1>>} = Event,
+ #state{connection_states = ConnectionStates0} = State) ->
+ ConnectionStates1 = dtls_record:save_current_connection_state(ConnectionStates0, read),
+ ConnectionStates = dtls_record:next_epoch(ConnectionStates1, read),
+ ssl_connection:cipher(Type, Event, State#state{connection_states = ConnectionStates}, ?MODULE);
+cipher(internal = Type, #finished{} = Event, #state{connection_states = ConnectionStates} = State) ->
+ ssl_connection:cipher(Type, Event,
+ prepare_flight(State#state{connection_states = ConnectionStates,
+ flight_state = connection}),
+ ?MODULE);
+cipher(state_timeout, Event, State) ->
+ handle_state_timeout(Event, cipher, State);
cipher(Type, Event, State) ->
ssl_connection:cipher(Type, Event, State, ?MODULE).
+connection(enter, _, State) ->
+ {keep_state, State};
connection(info, Event, State) ->
handle_info(Event, connection, State);
connection(internal, #hello_request{}, #state{host = Host, port = Port,
@@ -291,13 +453,12 @@ connection(internal, #hello_request{}, #state{host = Host, port = Port,
renegotiation = {Renegotiation, _}} = State0) ->
Hello = dtls_handshake:client_hello(Host, Port, ConnectionStates0, SslOpts,
Cache, CacheCb, Renegotiation, Cert),
- State1 = send_handshake(Hello, State0),
+ {State1, Actions} = send_handshake(Hello, State0),
{Record, State} =
next_record(
State1#state{session = Session0#session{session_id
= Hello#client_hello.session_id}}),
- next_event(hello, Record, State);
-
+ next_event(hello, Record, State, Actions);
connection(internal, #client_hello{} = Hello, #state{role = server, allow_renegotiate = true} = State) ->
%% Mitigate Computational DoS attack
%% http://www.educatedguesswork.org/2011/10/ssltls_and_computational_dos.html
@@ -306,21 +467,20 @@ connection(internal, #client_hello{} = Hello, #state{role = server, allow_renego
%% renegotiations immediately after each other.
erlang:send_after(?WAIT_TO_ALLOW_RENEGOTIATION, self(), allow_renegotiate),
{next_state, hello, State#state{allow_renegotiate = false}, [{next_event, internal, Hello}]};
-
-
connection(internal, #client_hello{}, #state{role = server, allow_renegotiate = false} = State0) ->
Alert = ?ALERT_REC(?WARNING, ?NO_RENEGOTIATION),
State1 = send_alert(Alert, State0),
{Record, State} = ssl_connection:prepare_connection(State1, ?MODULE),
next_event(connection, Record, State);
-
connection(Type, Event, State) ->
ssl_connection:connection(Type, Event, State, ?MODULE).
+%%TODO does this make sense for DTLS ?
+downgrade(enter, _, State) ->
+ {keep_state, State};
downgrade(Type, Event, State) ->
ssl_connection:downgrade(Type, Event, State, ?MODULE).
-
%%--------------------------------------------------------------------
%% Description: This function is called by a gen_fsm when it receives any
%% other message than a synchronous or asynchronous event
@@ -328,40 +488,112 @@ downgrade(Type, Event, State) ->
%%--------------------------------------------------------------------
%% raw data from socket, unpack records
-handle_info({Protocol, _, Data}, StateName,
+handle_info({Protocol, _, _, _, Data}, StateName,
#state{data_tag = Protocol} = State0) ->
- case next_tls_record(Data, State0) of
+ case next_dtls_record(Data, State0) of
{Record, State} ->
next_event(StateName, Record, State);
#alert{} = Alert ->
- handle_normal_shutdown(Alert, StateName, State0),
+ ssl_connection:handle_normal_shutdown(Alert, StateName, State0),
{stop, {shutdown, own_alert}}
- end;
+ end;
handle_info({CloseTag, Socket}, StateName,
- #state{socket = Socket, close_tag = CloseTag,
+ #state{socket = Socket,
+ socket_options = #socket_options{active = Active},
+ protocol_buffers = #protocol_buffers{dtls_cipher_texts = CTs},
+ close_tag = CloseTag,
negotiated_version = Version} = State) ->
%% Note that as of DTLS 1.2 (TLS 1.1),
%% failure to properly close a connection no longer requires that a
%% session not be resumed. This is a change from DTLS 1.0 to conform
%% with widespread implementation practice.
- case Version of
- {254, N} when N =< 253 ->
- ok;
- _ ->
- %% As invalidate_sessions here causes performance issues,
- %% we will conform to the widespread implementation
- %% practice and go aginst the spec
- %%invalidate_session(Role, Host, Port, Session)
- ok
- end,
- handle_normal_shutdown(?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), StateName, State),
- {stop, {shutdown, transport_closed}};
+ case (Active == false) andalso (CTs =/= []) of
+ false ->
+ case Version of
+ {254, N} when N =< 253 ->
+ ok;
+ _ ->
+ %% As invalidate_sessions here causes performance issues,
+ %% we will conform to the widespread implementation
+ %% practice and go aginst the spec
+ %%invalidate_session(Role, Host, Port, Session)
+ ok
+ end,
+ ssl_connection:handle_normal_shutdown(?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), StateName, State),
+ {stop, {shutdown, transport_closed}};
+ true ->
+ %% Fixes non-delivery of final DTLS record in {active, once}.
+ %% Basically allows the application the opportunity to set {active, once} again
+ %% and then receive the final message.
+ next_event(StateName, no_record, State)
+ end;
+
+handle_info(new_cookie_secret, StateName,
+ #state{protocol_specific = #{current_cookie_secret := Secret} = CookieInfo} = State) ->
+ erlang:send_after(dtls_v1:cookie_timeout(), self(), new_cookie_secret),
+ {next_state, StateName, State#state{protocol_specific =
+ CookieInfo#{current_cookie_secret => dtls_v1:cookie_secret(),
+ previous_cookie_secret => Secret}}};
handle_info(Msg, StateName, State) ->
ssl_connection:handle_info(Msg, StateName, State).
+
handle_call(Event, From, StateName, State) ->
ssl_connection:handle_call(Event, From, StateName, State, ?MODULE).
+handle_common_event(internal, #alert{} = Alert, StateName,
+ #state{negotiated_version = Version} = State) ->
+ ssl_connection:handle_own_alert(Alert, Version, StateName, State);
+%%% DTLS record protocol level handshake messages
+handle_common_event(internal, #ssl_tls{type = ?HANDSHAKE,
+ fragment = Data},
+ StateName,
+ #state{protocol_buffers = Buffers0,
+ negotiated_version = Version} = State0) ->
+ try
+ case dtls_handshake:get_dtls_handshake(Version, Data, Buffers0) of
+ {[], Buffers} ->
+ {Record, State} = next_record(State0#state{protocol_buffers = Buffers}),
+ next_event(StateName, Record, State);
+ {Packets, Buffers} ->
+ State = State0#state{protocol_buffers = Buffers},
+ Events = dtls_handshake_events(Packets),
+ {next_state, StateName,
+ State#state{unprocessed_handshake_events = unprocessed_events(Events)}, Events}
+ end
+ catch throw:#alert{} = Alert ->
+ ssl_connection:handle_own_alert(Alert, Version, StateName, State0)
+ end;
+%%% DTLS record protocol level application data messages
+handle_common_event(internal, #ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, StateName, State) ->
+ {next_state, StateName, State, [{next_event, internal, {application_data, Data}}]};
+%%% DTLS record protocol level change cipher messages
+handle_common_event(internal, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = Data}, StateName, State) ->
+ {next_state, StateName, State, [{next_event, internal, #change_cipher_spec{type = Data}}]};
+%%% DTLS record protocol level Alert messages
+handle_common_event(internal, #ssl_tls{type = ?ALERT, fragment = EncAlerts}, StateName,
+ #state{negotiated_version = Version} = State) ->
+ case decode_alerts(EncAlerts) of
+ Alerts = [_|_] ->
+ handle_alerts(Alerts, {next_state, StateName, State});
+ #alert{} = Alert ->
+ ssl_connection:handle_own_alert(Alert, Version, StateName, State)
+ end;
+%% Ignore unknown TLS record level protocol messages
+handle_common_event(internal, #ssl_tls{type = _Unknown}, StateName, State) ->
+ {next_state, StateName, State}.
+
+handle_state_timeout(flight_retransmission_timeout, StateName,
+ #state{flight_state = {retransmit, NextTimeout}} = State0) ->
+ {State1, Actions} = send_handshake_flight(State0#state{flight_state = {retransmit, NextTimeout}},
+ retransmit_epoch(StateName, State0)),
+ {Record, State} = next_record(State1),
+ next_event(StateName, Record, State, Actions).
+
+send(Transport, {_, {{_,_}, _} = Socket}, Data) ->
+ send(Transport, Socket, Data);
+send(Transport, Socket, Data) ->
+ dtls_socket:send(Transport, Socket, Data).
%%--------------------------------------------------------------------
%% Description:This function is called by a gen_fsm when it is about
%% to terminate. It should be the opposite of Module:init/1 and do any
@@ -376,7 +608,7 @@ terminate(Reason, StateName, State) ->
%% Description: Convert process state when code is changed
%%--------------------------------------------------------------------
code_change(_OldVsn, StateName, State, _Extra) ->
- {?GEN_STATEM_CB_MODE, StateName, State}.
+ {ok, StateName, State}.
format_status(Type, Data) ->
ssl_connection:format_status(Type, Data).
@@ -384,88 +616,59 @@ format_status(Type, Data) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-encode_handshake(Handshake, Version, ConnectionStates0, Hist0) ->
- {Seq, ConnectionStates} = sequence(ConnectionStates0),
- {EncHandshake, Frag} = dtls_handshake:encode_handshake(Handshake, Version, Seq),
- Hist = ssl_handshake:update_handshake_history(Hist0, EncHandshake),
- {Frag, ConnectionStates, Hist}.
+handle_client_hello(#client_hello{client_version = ClientVersion} = Hello,
+ #state{connection_states = ConnectionStates0,
+ port = Port, session = #session{own_certificate = Cert} = Session0,
+ renegotiation = {Renegotiation, _},
+ session_cache = Cache,
+ session_cache_cb = CacheCb,
+ negotiated_protocol = CurrentProtocol,
+ key_algorithm = KeyExAlg,
+ ssl_options = SslOpts} = State0) ->
+
+ case dtls_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb,
+ ConnectionStates0, Cert, KeyExAlg}, Renegotiation) of
+ #alert{} = Alert ->
+ ssl_connection:handle_own_alert(Alert, ClientVersion, hello, State0);
+ {Version, {Type, Session},
+ ConnectionStates, Protocol0, ServerHelloExt, HashSign} ->
+ Protocol = case Protocol0 of
+ undefined -> CurrentProtocol;
+ _ -> Protocol0
+ end,
-encode_change_cipher(#change_cipher_spec{}, Version, ConnectionStates) ->
- dtls_record:encode_change_cipher_spec(Version, ConnectionStates).
+ State = prepare_flight(State0#state{connection_states = ConnectionStates,
+ negotiated_version = Version,
+ hashsign_algorithm = HashSign,
+ session = Session,
+ negotiated_protocol = Protocol}),
+
+ ssl_connection:hello(internal, {common_client_hello, Type, ServerHelloExt},
+ State, ?MODULE)
+ end.
-encode_handshake_flight(Flight, ConnectionStates) ->
- MSS = 1400,
- encode_handshake_records(Flight, ConnectionStates, MSS, init_pack_records()).
+encode_handshake_flight(Flight, Version, MaxFragmentSize, Epoch, ConnectionStates) ->
+ Fragments = lists:map(fun(Handshake) ->
+ dtls_handshake:fragment_handshake(Handshake, MaxFragmentSize)
+ end, Flight),
+ dtls_record:encode_handshake(Fragments, Version, Epoch, ConnectionStates).
-encode_handshake_records([], CS, _MSS, Recs) ->
- {finish_pack_records(Recs), CS};
+encode_change_cipher(#change_cipher_spec{}, Version, Epoch, ConnectionStates) ->
+ dtls_record:encode_change_cipher_spec(Version, Epoch, ConnectionStates).
-encode_handshake_records([{Version, _Epoch, Frag = #change_cipher_spec{}}|Tail], ConnectionStates0, MSS, Recs0) ->
- {Encoded, ConnectionStates} =
- encode_change_cipher(Frag, Version, ConnectionStates0),
- Recs = append_pack_records([Encoded], MSS, Recs0),
- encode_handshake_records(Tail, ConnectionStates, MSS, Recs);
-
-encode_handshake_records([{Version, Epoch, {MsgType, MsgSeq, Bin}}|Tail], CS0, MSS, Recs0 = {Buf0, _}) ->
- Space = MSS - iolist_size(Buf0),
- Len = byte_size(Bin),
- {Encoded, CS} =
- encode_handshake_record(Version, Epoch, Space, MsgType, MsgSeq, Len, Bin, 0, MSS, [], CS0),
- Recs = append_pack_records(Encoded, MSS, Recs0),
- encode_handshake_records(Tail, CS, MSS, Recs).
-
-%% TODO: move to dtls_handshake????
-encode_handshake_record(_Version, _Epoch, _Space, _MsgType, _MsgSeq, _Len, <<>>, _Offset, _MRS, Encoded, CS)
- when length(Encoded) > 0 ->
- %% make sure we encode at least one segment (for empty messages like Server Hello Done
- {lists:reverse(Encoded), CS};
-
-encode_handshake_record(Version, Epoch, Space, MsgType, MsgSeq, Len, Bin,
- Offset, MRS, Encoded0, CS0) ->
- MaxFragmentLen = Space - 25,
- case Bin of
- <<BinFragment:MaxFragmentLen/bytes, Rest/binary>> ->
- ok;
- _ ->
- BinFragment = Bin,
- Rest = <<>>
- end,
- FragLength = byte_size(BinFragment),
- Frag = [MsgType, ?uint24(Len), ?uint16(MsgSeq), ?uint24(Offset), ?uint24(FragLength), BinFragment],
- %% TODO Real solution, now avoid dialyzer error {Encoded, CS} = ssl_record:encode_handshake({Epoch, Frag}, Version, CS0),
- {Encoded, CS} = ssl_record:encode_handshake(Frag, Version, CS0),
- encode_handshake_record(Version, Epoch, MRS, MsgType, MsgSeq, Len, Rest, Offset + FragLength, MRS, [Encoded|Encoded0], CS).
-
-init_pack_records() ->
- {[], []}.
-
-append_pack_records([], MSS, Recs = {Buf0, Acc0}) ->
- Remaining = MSS - iolist_size(Buf0),
- if Remaining < 12 ->
- {[], [lists:reverse(Buf0)|Acc0]};
- true ->
- Recs
- end;
-append_pack_records([Head|Tail], MSS, {Buf0, Acc0}) ->
- TotLen = iolist_size(Buf0) + iolist_size(Head),
- if TotLen > MSS ->
- append_pack_records(Tail, MSS, {[Head], [lists:reverse(Buf0)|Acc0]});
- true ->
- append_pack_records(Tail, MSS, {[Head|Buf0], Acc0})
- end.
+encode_data(Data, Version, ConnectionStates0)->
+ dtls_record:encode_data(Data, Version, ConnectionStates0).
-finish_pack_records({[], Acc}) ->
- lists:reverse(Acc);
-finish_pack_records({Buf, Acc}) ->
- lists:reverse([lists:reverse(Buf)|Acc]).
+encode_alert(#alert{} = Alert, Version, ConnectionStates) ->
+ dtls_record:encode_alert_record(Alert, Version, ConnectionStates).
-%% decode_alerts(Bin) ->
-%% ssl_alert:decode(Bin).
+decode_alerts(Bin) ->
+ ssl_alert:decode(Bin).
-initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User,
+initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions, _}, User,
{CbModule, DataTag, CloseTag, ErrorTag}) ->
#ssl_options{beast_mitigation = BeastMitigation} = SSLOptions,
- ConnectionStates = ssl_record:init_connection_states(Role, BeastMitigation),
+ ConnectionStates = dtls_record:init_connection_states(Role, BeastMitigation),
SessionCacheCb = case application:get_env(ssl, session_cb) of
{ok, Cb} when is_atom(Cb) ->
@@ -497,10 +700,12 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User,
renegotiation = {false, first},
allow_renegotiate = SSLOptions#ssl_options.client_renegotiation,
start_or_recv_from = undefined,
- protocol_cb = ?MODULE
+ protocol_cb = ?MODULE,
+ flight_buffer = new_flight(),
+ flight_state = {retransmit, ?INITIAL_RETRANSMIT_TIMEOUT}
}.
-next_tls_record(Data, #state{protocol_buffers = #protocol_buffers{
+next_dtls_record(Data, #state{protocol_buffers = #protocol_buffers{
dtls_record_buffer = Buf0,
dtls_cipher_texts = CT0} = Buffers} = State0) ->
case dtls_record:get_dtls_records(Data, Buf0) of
@@ -509,27 +714,53 @@ next_tls_record(Data, #state{protocol_buffers = #protocol_buffers{
next_record(State0#state{protocol_buffers =
Buffers#protocol_buffers{dtls_record_buffer = Buf1,
dtls_cipher_texts = CT1}});
-
#alert{} = Alert ->
Alert
- end.
+ end.
-next_record(#state{%%flight = #flight{state = finished},
- protocol_buffers =
- #protocol_buffers{dtls_packets = [], dtls_cipher_texts = [CT | Rest]}
+next_record(#state{unprocessed_handshake_events = N} = State) when N > 0 ->
+ {no_record, State#state{unprocessed_handshake_events = N-1}};
+
+next_record(#state{protocol_buffers =
+ #protocol_buffers{dtls_cipher_texts = [#ssl_tls{epoch = Epoch} = CT | Rest]}
= Buffers,
- connection_states = ConnStates0} = State) ->
- case dtls_record:decode_cipher_text(CT, ConnStates0) of
- {Plain, ConnStates} ->
- {Plain, State#state{protocol_buffers =
- Buffers#protocol_buffers{dtls_cipher_texts = Rest},
- connection_states = ConnStates}};
- #alert{} = Alert ->
- {Alert, State}
+ connection_states = #{current_read := #{epoch := Epoch}} = ConnectionStates} = State) ->
+ CurrentRead = dtls_record:get_connection_state_by_epoch(Epoch, ConnectionStates, read),
+ case dtls_record:replay_detect(CT, CurrentRead) of
+ false ->
+ decode_cipher_text(State#state{connection_states = ConnectionStates}) ;
+ true ->
+ %% Ignore replayed record
+ next_record(State#state{protocol_buffers =
+ Buffers#protocol_buffers{dtls_cipher_texts = Rest},
+ connection_states = ConnectionStates})
end;
-next_record(#state{socket = Socket,
- transport_cb = Transport} = State) -> %% when FlightState =/= finished
- ssl_socket:setopts(Transport, Socket, [{active,once}]),
+next_record(#state{protocol_buffers =
+ #protocol_buffers{dtls_cipher_texts = [#ssl_tls{epoch = Epoch} | Rest]}
+ = Buffers,
+ connection_states = #{current_read := #{epoch := CurrentEpoch}} = ConnectionStates} = State)
+ when Epoch > CurrentEpoch ->
+ %% TODO Buffer later Epoch message, drop it for now
+ next_record(State#state{protocol_buffers =
+ Buffers#protocol_buffers{dtls_cipher_texts = Rest},
+ connection_states = ConnectionStates});
+next_record(#state{protocol_buffers =
+ #protocol_buffers{dtls_cipher_texts = [ _ | Rest]}
+ = Buffers,
+ connection_states = ConnectionStates} = State) ->
+ %% Drop old epoch message
+ next_record(State#state{protocol_buffers =
+ Buffers#protocol_buffers{dtls_cipher_texts = Rest},
+ connection_states = ConnectionStates});
+next_record(#state{role = server,
+ socket = {Listener, {Client, _}},
+ transport_cb = gen_udp} = State) ->
+ dtls_udp_listener:active_once(Listener, Client, self()),
+ {no_record, State};
+next_record(#state{role = client,
+ socket = {_Server, Socket},
+ transport_cb = Transport} = State) ->
+ dtls_socket:setopts(Transport, Socket, [{active,once}]),
{no_record, State};
next_record(State) ->
{no_record, State}.
@@ -548,88 +779,188 @@ passive_receive(State0 = #state{user_data_buffer = Buffer}, StateName) ->
{Record, State} = next_record(State0),
next_event(StateName, Record, State);
_ ->
- {Record, State} = read_application_data(<<>>, State0),
+ {Record, State} = ssl_connection:read_application_data(<<>>, State0),
next_event(StateName, Record, State)
end.
next_event(StateName, Record, State) ->
next_event(StateName, Record, State, []).
-next_event(connection = StateName, no_record, State0, Actions) ->
+next_event(connection = StateName, no_record,
+ #state{connection_states = #{current_read := #{epoch := CurrentEpoch}}} = State0, Actions) ->
case next_record_if_active(State0) of
{no_record, State} ->
- ssl_connection:hibernate_after(StateName, State, Actions);
- {#ssl_tls{} = Record, State} ->
- {next_state, StateName, State, [{next_event, internal, {dtls_record, Record}} | Actions]};
+ ssl_connection:hibernate_after(StateName, State, Actions);
+ {#ssl_tls{epoch = CurrentEpoch} = Record, State} ->
+ {next_state, StateName, State, [{next_event, internal, {protocol_record, Record}} | Actions]};
+ {#ssl_tls{epoch = Epoch,
+ type = ?HANDSHAKE,
+ version = _Version}, State1} = _Record when Epoch == CurrentEpoch-1 ->
+ {State2, MoreActions} = send_handshake_flight(State1, CurrentEpoch),
+ {NextRecord, State} = next_record(State2),
+ next_event(StateName, NextRecord, State, Actions ++ MoreActions);
+ %% From FLIGHT perspective CHANGE_CIPHER_SPEC is treated as a handshake
+ {#ssl_tls{epoch = Epoch,
+ type = ?CHANGE_CIPHER_SPEC,
+ version = _Version}, State1} = _Record when Epoch == CurrentEpoch-1 ->
+ {State2, MoreActions} = send_handshake_flight(State1, CurrentEpoch),
+ {NextRecord, State} = next_record(State2),
+ next_event(StateName, NextRecord, State, Actions ++ MoreActions);
+ {#ssl_tls{epoch = _Epoch,
+ version = _Version}, State1} ->
+ %% TODO maybe buffer later epoch
+ {Record, State} = next_record(State1),
+ next_event(StateName, Record, State, Actions);
{#alert{} = Alert, State} ->
{next_state, StateName, State, [{next_event, internal, Alert} | Actions]}
end;
-next_event(StateName, Record, State, Actions) ->
+next_event(connection = StateName, Record,
+ #state{connection_states = #{current_read := #{epoch := CurrentEpoch}}} = State0, Actions) ->
+ case Record of
+ #ssl_tls{epoch = CurrentEpoch} ->
+ {next_state, StateName, State0, [{next_event, internal, {protocol_record, Record}} | Actions]};
+ #ssl_tls{epoch = Epoch,
+ type = ?HANDSHAKE,
+ version = _Version} when Epoch == CurrentEpoch-1 ->
+ {State1, MoreActions} = send_handshake_flight(State0, CurrentEpoch),
+ {NextRecord, State} = next_record(State1),
+ next_event(StateName, NextRecord, State, Actions ++ MoreActions);
+ %% From FLIGHT perspective CHANGE_CIPHER_SPEC is treated as a handshake
+ #ssl_tls{epoch = Epoch,
+ type = ?CHANGE_CIPHER_SPEC,
+ version = _Version} when Epoch == CurrentEpoch-1 ->
+ {State1, MoreActions} = send_handshake_flight(State0, CurrentEpoch),
+ {NextRecord, State} = next_record(State1),
+ next_event(StateName, NextRecord, State, Actions ++ MoreActions);
+ _ ->
+ next_event(StateName, no_record, State0, Actions)
+ end;
+next_event(StateName, Record,
+ #state{connection_states = #{current_read := #{epoch := CurrentEpoch}}} = State0, Actions) ->
case Record of
no_record ->
- {next_state, StateName, State, Actions};
- #ssl_tls{} = Record ->
- {next_state, StateName, State, [{next_event, internal, {dtls_record, Record}} | Actions]};
+ {next_state, StateName, State0, Actions};
+ #ssl_tls{epoch = CurrentEpoch,
+ version = Version} = Record ->
+ {next_state, StateName,
+ dtls_version(StateName, Version, State0),
+ [{next_event, internal, {protocol_record, Record}} | Actions]};
+ #ssl_tls{epoch = _Epoch,
+ version = _Version} = _Record ->
+ %% TODO maybe buffer later epoch
+ {Record, State} = next_record(State0),
+ next_event(StateName, Record, State, Actions);
#alert{} = Alert ->
- {next_state, StateName, State, [{next_event, internal, Alert} | Actions]}
+ {next_state, StateName, State0, [{next_event, internal, Alert} | Actions]}
+ end.
+
+decode_cipher_text(#state{protocol_buffers = #protocol_buffers{dtls_cipher_texts = [ CT | Rest]} = Buffers,
+ connection_states = ConnStates0} = State) ->
+ case dtls_record:decode_cipher_text(CT, ConnStates0) of
+ {Plain, ConnStates} ->
+ {Plain, State#state{protocol_buffers =
+ Buffers#protocol_buffers{dtls_cipher_texts = Rest},
+ connection_states = ConnStates}};
+ #alert{} = Alert ->
+ {Alert, State}
end.
-read_application_data(_,State) ->
- {#ssl_tls{fragment = <<"place holder">>}, State}.
-
-handle_own_alert(_,_,_, State) -> %% Place holder
- {stop, {shutdown, own_alert}, State}.
-
-handle_normal_shutdown(_, _, _State) -> %% Place holder
- ok.
-
-%% TODO This generates dialyzer warnings, has to be handled differently.
-%% handle_packet(Address, Port, Packet) ->
-%% try dtls_record:get_dtls_records(Packet, <<>>) of
-%% %% expect client hello
-%% {[#ssl_tls{type = ?HANDSHAKE, version = {254, _}} = Record], <<>>} ->
-%% handle_dtls_client_hello(Address, Port, Record);
-%% _Other ->
-%% {error, not_dtls}
-%% catch
-%% _Class:_Error ->
-%% {error, not_dtls}
-%% end.
-
-%% handle_dtls_client_hello(Address, Port,
-%% #ssl_tls{epoch = Epoch, sequence_number = Seq,
-%% version = Version} = Record) ->
-%% {[{Hello, _}], _} =
-%% dtls_handshake:get_dtls_handshake(Record,
-%% dtls_handshake:dtls_handshake_new_flight(undefined)),
-%% #client_hello{client_version = {Major, Minor},
-%% random = Random,
-%% session_id = SessionId,
-%% cipher_suites = CipherSuites,
-%% compression_methods = CompressionMethods} = Hello,
-%% CookieData = [address_to_bin(Address, Port),
-%% <<?BYTE(Major), ?BYTE(Minor)>>,
-%% Random, SessionId, CipherSuites, CompressionMethods],
-%% Cookie = crypto:hmac(sha, <<"secret">>, CookieData),
-
-%% case Hello of
-%% #client_hello{cookie = Cookie} ->
-%% accept;
-
-%% _ ->
-%% %% generate HelloVerifyRequest
-%% {RequestFragment, _} = dtls_handshake:encode_handshake(
-%% dtls_handshake:hello_verify_request(Cookie),
-%% Version, 0),
-%% HelloVerifyRequest =
-%% dtls_record:encode_tls_cipher_text(?HANDSHAKE, Version, Epoch, Seq, RequestFragment),
-%% {reply, HelloVerifyRequest}
-%% end.
-
-%% address_to_bin({A,B,C,D}, Port) ->
-%% <<0:80,16#ffff:16,A,B,C,D,Port:16>>;
-%% address_to_bin({A,B,C,D,E,F,G,H}, Port) ->
-%% <<A:16,B:16,C:16,D:16,E:16,F:16,G:16,H:16,Port:16>>.
-
-sequence(#connection_states{dtls_write_msg_seq = Seq} = CS) ->
- {Seq, CS#connection_states{dtls_write_msg_seq = Seq + 1}}.
+dtls_version(hello, Version, #state{role = server} = State) ->
+ State#state{negotiated_version = Version}; %%Inital version
+dtls_version(_,_, State) ->
+ State.
+
+prepare_flight(#state{flight_buffer = Flight,
+ connection_states = ConnectionStates0,
+ protocol_buffers =
+ #protocol_buffers{} = Buffers} = State) ->
+ ConnectionStates = dtls_record:save_current_connection_state(ConnectionStates0, write),
+ State#state{flight_buffer = next_flight(Flight),
+ connection_states = ConnectionStates,
+ protocol_buffers = Buffers#protocol_buffers{
+ dtls_handshake_next_fragments = [],
+ dtls_handshake_later_fragments = []}}.
+new_flight() ->
+ #{next_sequence => 0,
+ handshakes => [],
+ change_cipher_spec => undefined,
+ handshakes_after_change_cipher_spec => []}.
+
+next_flight(Flight) ->
+ Flight#{handshakes => [],
+ change_cipher_spec => undefined,
+ handshakes_after_change_cipher_spec => []}.
+
+handle_flight_timer(#state{transport_cb = gen_udp,
+ flight_state = {retransmit, Timeout}} = State) ->
+ start_retransmision_timer(Timeout, State);
+handle_flight_timer(#state{transport_cb = gen_udp,
+ flight_state = connection} = State) ->
+ {State, []};
+handle_flight_timer(State) ->
+ %% No retransmision needed i.e DTLS over SCTP
+ {State#state{flight_state = reliable}, []}.
+
+start_retransmision_timer(Timeout, State) ->
+ {State#state{flight_state = {retransmit, new_timeout(Timeout)}},
+ [{state_timeout, Timeout, flight_retransmission_timeout}]}.
+
+new_timeout(N) when N =< 30 ->
+ N * 2;
+new_timeout(_) ->
+ 60.
+
+dtls_handshake_events(Packets) ->
+ lists:map(fun(Packet) ->
+ {next_event, internal, {handshake, Packet}}
+ end, Packets).
+
+renegotiate(#state{role = client} = State, Actions) ->
+ %% Handle same way as if server requested
+ %% the renegotiation
+ Hs0 = ssl_handshake:init_handshake_history(),
+ {next_state, connection, State#state{tls_handshake_history = Hs0,
+ protocol_buffers = #protocol_buffers{}},
+ [{next_event, internal, #hello_request{}} | Actions]};
+
+renegotiate(#state{role = server,
+ connection_states = CS0} = State0, Actions) ->
+ HelloRequest = ssl_handshake:hello_request(),
+ CS = CS0#{write_msg_seq => 0},
+ {State1, MoreActions} = send_handshake(HelloRequest,
+ State0#state{connection_states =
+ CS}),
+ Hs0 = ssl_handshake:init_handshake_history(),
+ {Record, State} = next_record(State1#state{tls_handshake_history = Hs0,
+ protocol_buffers = #protocol_buffers{}}),
+ next_event(hello, Record, State, Actions ++ MoreActions).
+
+handle_alerts([], Result) ->
+ Result;
+handle_alerts(_, {stop,_} = Stop) ->
+ Stop;
+handle_alerts([Alert | Alerts], {next_state, StateName, State}) ->
+ handle_alerts(Alerts, ssl_connection:handle_alert(Alert, StateName, State));
+handle_alerts([Alert | Alerts], {next_state, StateName, State, _Actions}) ->
+ handle_alerts(Alerts, ssl_connection:handle_alert(Alert, StateName, State)).
+
+retransmit_epoch(_StateName, #state{connection_states = ConnectionStates}) ->
+ #{epoch := Epoch} =
+ ssl_record:current_connection_state(ConnectionStates, write),
+ Epoch.
+
+
+update_handshake_history(#hello_verify_request{}, _, Hist) ->
+ Hist;
+update_handshake_history(_, Handshake, Hist) ->
+ %% DTLS never needs option "v2_hello_compatible" to be true
+ ssl_handshake:update_handshake_history(Hist, iolist_to_binary(Handshake), false).
+
+unprocessed_events(Events) ->
+ %% The first handshake event will be processed immediately
+ %% as it is entered first in the event queue and
+ %% when it is processed there will be length(Events)-1
+ %% handshake events left to process before we should
+ %% process more TLS-records received on the socket.
+ erlang:length(Events)-1.
+
diff --git a/lib/ssl/src/dtls_connection.hrl b/lib/ssl/src/dtls_connection.hrl
index ee3daa3c14..3dd78235d0 100644
--- a/lib/ssl/src/dtls_connection.hrl
+++ b/lib/ssl/src/dtls_connection.hrl
@@ -29,20 +29,14 @@
-include("ssl_connection.hrl").
-record(protocol_buffers, {
- dtls_packets = [], %%::[binary()], % Not yet handled decode ssl/tls packets.
- dtls_record_buffer = <<>>, %%:: binary(), % Buffer of incomplete records
- dtls_fragment_state, %%:: [], % DTLS fragments
- dtls_handshake_buffer = <<>>, %%:: binary(), % Buffer of incomplete handshakes
- dtls_cipher_texts = [], %%:: [binary()],
- dtls_cipher_texts_next %%:: [binary()] % Received for Epoch not yet active
+ dtls_record_buffer = <<>>, %% Buffer of incomplete records
+ dtls_handshake_next_seq = 0,
+ dtls_flight_last,
+ dtls_handshake_next_fragments = [], %% Fragments of the next handshake message
+ dtls_handshake_later_fragments = [], %% Fragments of handsake messages come after the one in next buffer
+ dtls_cipher_texts = [] %%:: [binary()],
}).
--record(flight, {
- last_retransmit,
- last_read_seq,
- msl_timer,
- state,
- buffer % buffer of not yet ACKed TLS records
- }).
+-define(INITIAL_RETRANSMIT_TIMEOUT, 1000). %1 sec
-endif. % -ifdef(dtls_connection).
diff --git a/lib/ssl/src/dtls_connection_sup.erl b/lib/ssl/src/dtls_connection_sup.erl
index dc7601a684..7d7be5743d 100644
--- a/lib/ssl/src/dtls_connection_sup.erl
+++ b/lib/ssl/src/dtls_connection_sup.erl
@@ -60,7 +60,7 @@ init(_O) ->
StartFunc = {dtls_connection, start_link, []},
Restart = temporary, % E.g. should not be restarted
Shutdown = 4000,
- Modules = [dtls_connection],
+ Modules = [dtls_connection, ssl_connection],
Type = worker,
ChildSpec = {Name, StartFunc, Restart, Shutdown, Type, Modules},
diff --git a/lib/ssl/src/dtls_handshake.erl b/lib/ssl/src/dtls_handshake.erl
index 5a799cf441..37a46b862e 100644
--- a/lib/ssl/src/dtls_handshake.erl
+++ b/lib/ssl/src/dtls_handshake.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,15 +18,15 @@
%% %CopyrightEnd%
-module(dtls_handshake).
+-include("dtls_connection.hrl").
-include("dtls_handshake.hrl").
-include("dtls_record.hrl").
-include("ssl_internal.hrl").
-include("ssl_alert.hrl").
--export([client_hello/8, client_hello/9, hello/4,
- hello_verify_request/1, get_dtls_handshake/2,
- dtls_handshake_new_flight/1, dtls_handshake_new_epoch/1,
- encode_handshake/3]).
+-export([client_hello/8, client_hello/9, cookie/4, hello/4,
+ hello_verify_request/2, get_dtls_handshake/3, fragment_handshake/2,
+ handshake_bin/2, encode_handshake/3]).
-type dtls_handshake() :: #client_hello{} | #hello_verify_request{} |
ssl_handshake:ssl_handshake().
@@ -35,7 +35,7 @@
%% Internal application API
%%====================================================================
%%--------------------------------------------------------------------
--spec client_hello(host(), inet:port_number(), #connection_states{},
+-spec client_hello(host(), inet:port_number(), ssl_record:connection_states(),
#ssl_options{}, integer(), atom(), boolean(), der_cert()) ->
#client_hello{}.
%%
@@ -48,7 +48,7 @@ client_hello(Host, Port, ConnectionStates, SslOpts,
Cache, CacheCb, Renegotiation, OwnCert).
%%--------------------------------------------------------------------
--spec client_hello(host(), inet:port_number(), term(), #connection_states{},
+-spec client_hello(host(), inet:port_number(), term(), ssl_record:connection_states(),
#ssl_options{}, integer(), atom(), boolean(), der_cert()) ->
#client_hello{}.
%%
@@ -61,12 +61,12 @@ client_hello(Host, Port, Cookie, ConnectionStates,
Cache, CacheCb, Renegotiation, OwnCert) ->
Version = dtls_record:highest_protocol_version(Versions),
Pending = ssl_record:pending_connection_state(ConnectionStates, read),
- SecParams = Pending#connection_state.security_parameters,
- CipherSuites = ssl_handshake:available_suites(UserSuites, Version),
-
- Extensions = ssl_handshake:client_hello_extensions(Host, dtls_v1:corresponding_tls_version(Version), CipherSuites,
- SslOpts, ConnectionStates, Renegotiation),
+ SecParams = maps:get(security_parameters, Pending),
+ TLSVersion = dtls_v1:corresponding_tls_version(Version),
+ CipherSuites = ssl_handshake:available_suites(UserSuites, TLSVersion),
+ Extensions = ssl_handshake:client_hello_extensions(TLSVersion, CipherSuites,
+ SslOpts, ConnectionStates, Renegotiation),
Id = ssl_session:client_id({Host, Port, SslOpts}, Cache, CacheCb, OwnCert),
#client_hello{session_id = Id,
@@ -96,72 +96,53 @@ hello(#client_hello{client_version = ClientVersion} = Hello,
#ssl_options{versions = Versions} = SslOpts,
Info, Renegotiation) ->
Version = ssl_handshake:select_version(dtls_record, ClientVersion, Versions),
- %%
- %% TODO: handle Cipher Fallback
- %%
handle_client_hello(Version, Hello, SslOpts, Info, Renegotiation).
--spec hello_verify_request(binary()) -> #hello_verify_request{}.
+cookie(Key, Address, Port, #client_hello{client_version = {Major, Minor},
+ random = Random,
+ session_id = SessionId,
+ cipher_suites = CipherSuites,
+ compression_methods = CompressionMethods}) ->
+ CookieData = [address_to_bin(Address, Port),
+ <<?BYTE(Major), ?BYTE(Minor)>>,
+ Random, SessionId, CipherSuites, CompressionMethods],
+ crypto:hmac(sha, Key, CookieData).
+
+-spec hello_verify_request(binary(), dtls_record:dtls_version()) -> #hello_verify_request{}.
%%
%% Description: Creates a hello verify request message sent by server to
%% verify client
%%--------------------------------------------------------------------
-hello_verify_request(Cookie) ->
- %% TODO: DTLS Versions?????
- #hello_verify_request{protocol_version = {254, 255}, cookie = Cookie}.
+hello_verify_request(Cookie, Version) ->
+ #hello_verify_request{protocol_version = Version, cookie = Cookie}.
%%--------------------------------------------------------------------
-%% %%--------------------------------------------------------------------
-encode_handshake(Handshake, Version, MsgSeq) ->
+encode_handshake(Handshake, Version, Seq) ->
{MsgType, Bin} = enc_handshake(Handshake, Version),
Len = byte_size(Bin),
- Enc = [MsgType, ?uint24(Len), ?uint16(MsgSeq), ?uint24(0), ?uint24(Len), Bin],
- Frag = {MsgType, MsgSeq, Bin},
- {Enc, Frag}.
+ [MsgType, ?uint24(Len), ?uint16(Seq), ?uint24(0), ?uint24(Len), Bin].
-%%--------------------------------------------------------------------
--spec get_dtls_handshake(#ssl_tls{}, #dtls_hs_state{} | undefined) ->
- {[dtls_handshake()], #dtls_hs_state{}} | {retransmit, #dtls_hs_state{}}.
-%%
-%% Description: Given a DTLS state and new data from ssl_record, collects
-%% and returns it as a list of handshake messages, also returns a new
-%% DTLS state
-%%--------------------------------------------------------------------
-get_dtls_handshake(Records, undefined) ->
- HsState = #dtls_hs_state{highest_record_seq = 0,
- starting_read_seq = 0,
- fragments = gb_trees:empty(),
- completed = []},
- get_dtls_handshake(Records, HsState);
-get_dtls_handshake(Records, HsState0) when is_list(Records) ->
- HsState1 = lists:foldr(fun get_dtls_handshake_aux/2, HsState0, Records),
- get_dtls_handshake_completed(HsState1);
-get_dtls_handshake(Record, HsState0) when is_record(Record, ssl_tls) ->
- HsState1 = get_dtls_handshake_aux(Record, HsState0),
- get_dtls_handshake_completed(HsState1).
+fragment_handshake(Bin, _) when is_binary(Bin)->
+ %% This is the change_cipher_spec not a "real handshake" but part of the flight
+ Bin;
+fragment_handshake([MsgType, Len, Seq, _, Len, Bin], Size) ->
+ Bins = bin_fragments(Bin, Size),
+ handshake_fragments(MsgType, Seq, Len, Bins, []).
+handshake_bin([Type, Length, Data], Seq) ->
+ handshake_bin(Type, Length, Seq, Data).
+
%%--------------------------------------------------------------------
--spec dtls_handshake_new_epoch(#dtls_hs_state{}) -> #dtls_hs_state{}.
+-spec get_dtls_handshake(dtls_record:dtls_version(), binary(), #protocol_buffers{}) ->
+ {[dtls_handshake()], #protocol_buffers{}}.
%%
-%% Description: Reset the DTLS decoder state for a new Epoch
+%% Description: Given buffered and new data from dtls_record, collects
+%% and returns it as a list of handshake messages, also returns
+%% possible leftover data in the new "protocol_buffers".
%%--------------------------------------------------------------------
-%% dtls_handshake_new_epoch(<<>>) ->
-%% dtls_hs_state_init();
-dtls_handshake_new_epoch(HsState) ->
- HsState#dtls_hs_state{highest_record_seq = 0,
- starting_read_seq = HsState#dtls_hs_state.current_read_seq,
- fragments = gb_trees:empty(), completed = []}.
-
-%--------------------------------------------------------------------
--spec dtls_handshake_new_flight(integer() | undefined) -> #dtls_hs_state{}.
-%
-% Description: Init the DTLS decoder state for a new Flight
-dtls_handshake_new_flight(ExpectedReadReq) ->
- #dtls_hs_state{current_read_seq = ExpectedReadReq,
- highest_record_seq = 0,
- starting_read_seq = 0,
- fragments = gb_trees:empty(), completed = []}.
+get_dtls_handshake(Version, Fragment, ProtocolBuffers) ->
+ handle_fragments(Version, Fragment, ProtocolBuffers, []).
%%--------------------------------------------------------------------
%%% Internal functions
@@ -170,27 +151,29 @@ handle_client_hello(Version, #client_hello{session_id = SugesstedId,
cipher_suites = CipherSuites,
compression_methods = Compressions,
random = Random,
- extensions = #hello_extensions{elliptic_curves = Curves,
- signature_algs = ClientHashSigns} = HelloExt},
+ extensions =
+ #hello_extensions{elliptic_curves = Curves,
+ signature_algs = ClientHashSigns} = HelloExt},
#ssl_options{versions = Versions,
signature_algs = SupportedHashSigns} = SslOpts,
{Port, Session0, Cache, CacheCb, ConnectionStates0, Cert, _}, Renegotiation) ->
case dtls_record:is_acceptable_version(Version, Versions) of
true ->
+ TLSVersion = dtls_v1:corresponding_tls_version(Version),
AvailableHashSigns = ssl_handshake:available_signature_algs(
- ClientHashSigns, SupportedHashSigns, Cert,
- dtls_v1:corresponding_tls_version(Version)),
- ECCCurve = ssl_handshake:select_curve(Curves, ssl_handshake:supported_ecc(Version)),
+ ClientHashSigns, SupportedHashSigns, Cert,TLSVersion),
+ ECCCurve = ssl_handshake:select_curve(Curves, ssl_handshake:supported_ecc(TLSVersion)),
{Type, #session{cipher_suite = CipherSuite} = Session1}
= ssl_handshake:select_session(SugesstedId, CipherSuites, AvailableHashSigns, Compressions,
- Port, Session0#session{ecc = ECCCurve}, Version,
+ Port, Session0#session{ecc = ECCCurve}, TLSVersion,
SslOpts, Cache, CacheCb, Cert),
case CipherSuite of
no_suite ->
?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY);
_ ->
{KeyExAlg,_,_,_} = ssl_cipher:suite_definition(CipherSuite),
- case ssl_handshake:select_hashsign(ClientHashSigns, Cert, KeyExAlg, SupportedHashSigns, Version) of
+ case ssl_handshake:select_hashsign(ClientHashSigns, Cert, KeyExAlg,
+ SupportedHashSigns, TLSVersion) of
#alert{} = Alert ->
Alert;
HashSign ->
@@ -228,214 +211,15 @@ handle_server_hello_extensions(Version, SessionId, Random, CipherSuite,
{Version, SessionId, ConnectionStates, ProtoExt, Protocol}
end.
-get_dtls_handshake_completed(HsState = #dtls_hs_state{completed = Completed}) ->
- {lists:reverse(Completed), HsState#dtls_hs_state{completed = []}}.
-
-get_dtls_handshake_aux(#ssl_tls{version = Version,
- sequence_number = SeqNo,
- fragment = Data}, HsState) ->
- get_dtls_handshake_aux(Version, SeqNo, Data, HsState).
-
-get_dtls_handshake_aux(Version, SeqNo,
- <<?BYTE(Type), ?UINT24(Length),
- ?UINT16(MessageSeq),
- ?UINT24(FragmentOffset), ?UINT24(FragmentLength),
- Body:FragmentLength/binary, Rest/binary>>,
- HsState0) ->
- case reassemble_dtls_fragment(SeqNo, Type, Length, MessageSeq,
- FragmentOffset, FragmentLength,
- Body, HsState0) of
- {HsState1, HighestSeqNo, MsgBody} ->
- HsState2 = dec_dtls_fragment(Version, HighestSeqNo, Type, Length, MessageSeq, MsgBody, HsState1),
- HsState3 = process_dtls_fragments(Version, HsState2),
- get_dtls_handshake_aux(Version, SeqNo, Rest, HsState3);
-
- HsState2 ->
- HsState3 = process_dtls_fragments(Version, HsState2),
- get_dtls_handshake_aux(Version, SeqNo, Rest, HsState3)
- end;
-
-get_dtls_handshake_aux(_Version, _SeqNo, <<>>, HsState) ->
- HsState.
-
-dec_dtls_fragment(Version, SeqNo, Type, Length, MessageSeq, MsgBody,
- HsState = #dtls_hs_state{highest_record_seq = HighestSeqNo, completed = Acc}) ->
- Raw = <<?BYTE(Type), ?UINT24(Length), ?UINT16(MessageSeq), ?UINT24(0), ?UINT24(Length), MsgBody/binary>>,
- H = decode_handshake(Version, Type, MsgBody),
- HsState#dtls_hs_state{completed = [{H,Raw}|Acc], highest_record_seq = erlang:max(HighestSeqNo, SeqNo)}.
-
-process_dtls_fragments(Version,
- HsState0 = #dtls_hs_state{current_read_seq = CurrentReadSeq,
- fragments = Fragments0}) ->
- case gb_trees:is_empty(Fragments0) of
- true ->
- HsState0;
- _ ->
- case gb_trees:smallest(Fragments0) of
- {CurrentReadSeq, {SeqNo, Type, Length, CurrentReadSeq, {Length, [{0, Length}], MsgBody}}} ->
- HsState1 = dtls_hs_state_process_seq(HsState0),
- HsState2 = dec_dtls_fragment(Version, SeqNo, Type, Length, CurrentReadSeq, MsgBody, HsState1),
- process_dtls_fragments(Version, HsState2);
- _ ->
- HsState0
- end
- end.
-
-dtls_hs_state_process_seq(HsState0 = #dtls_hs_state{current_read_seq = CurrentReadSeq,
- fragments = Fragments0}) ->
- Fragments1 = gb_trees:delete_any(CurrentReadSeq, Fragments0),
- HsState0#dtls_hs_state{current_read_seq = CurrentReadSeq + 1,
- fragments = Fragments1}.
-
-dtls_hs_state_add_fragment(MessageSeq, Fragment, HsState0 = #dtls_hs_state{fragments = Fragments0}) ->
- Fragments1 = gb_trees:enter(MessageSeq, Fragment, Fragments0),
- HsState0#dtls_hs_state{fragments = Fragments1}.
-
-reassemble_dtls_fragment(SeqNo, Type, Length, MessageSeq, 0, Length,
- Body, HsState0 = #dtls_hs_state{current_read_seq = undefined})
- when Type == ?CLIENT_HELLO;
- Type == ?SERVER_HELLO;
- Type == ?HELLO_VERIFY_REQUEST ->
- %% First message, should be client hello
- %% return the current message and set the next expected Sequence
- %%
- %% Note: this could (should?) be restricted further, ClientHello and
- %% HelloVerifyRequest have to have message_seq = 0, ServerHello
- %% can have a message_seq of 0 or 1
- %%
- {HsState0#dtls_hs_state{current_read_seq = MessageSeq + 1}, SeqNo, Body};
-
-reassemble_dtls_fragment(_SeqNo, _Type, Length, _MessageSeq, _, Length,
- _Body, HsState = #dtls_hs_state{current_read_seq = undefined}) ->
- %% not what we expected, drop it
- HsState;
-
-reassemble_dtls_fragment(SeqNo, _Type, Length, MessageSeq, 0, Length,
- Body, HsState0 =
- #dtls_hs_state{starting_read_seq = StartingReadSeq})
- when MessageSeq < StartingReadSeq ->
- %% this has to be the start of a new flight, let it through
- %%
- %% Note: this could (should?) be restricted further, the first message of a
- %% new flight has to have message_seq = 0
- %%
- HsState = dtls_hs_state_process_seq(HsState0),
- {HsState, SeqNo, Body};
-
-reassemble_dtls_fragment(_SeqNo, _Type, Length, MessageSeq, 0, Length,
- _Body, HsState = #dtls_hs_state{current_read_seq = CurrentReadSeq})
- when MessageSeq < CurrentReadSeq ->
- HsState;
-
-reassemble_dtls_fragment(SeqNo, _Type, Length, MessageSeq, 0, Length,
- Body, HsState0 = #dtls_hs_state{current_read_seq = MessageSeq}) ->
- %% Message fully contained and it's the current seq
- HsState1 = dtls_hs_state_process_seq(HsState0),
- {HsState1, SeqNo, Body};
-
-reassemble_dtls_fragment(SeqNo, Type, Length, MessageSeq, 0, Length,
- Body, HsState) ->
- %% Message fully contained and it's the NOT the current seq -> buffer
- Fragment = {SeqNo, Type, Length, MessageSeq,
- dtls_fragment_init(Length, 0, Length, Body)},
- dtls_hs_state_add_fragment(MessageSeq, Fragment, HsState);
-
-reassemble_dtls_fragment(_SeqNo, _Type, Length, MessageSeq, FragmentOffset, FragmentLength,
- _Body,
- HsState = #dtls_hs_state{current_read_seq = CurrentReadSeq})
- when FragmentOffset + FragmentLength == Length andalso MessageSeq == (CurrentReadSeq - 1) ->
- {retransmit, HsState};
-
-reassemble_dtls_fragment(_SeqNo, _Type, _Length, MessageSeq, _FragmentOffset, _FragmentLength,
- _Body,
- HsState = #dtls_hs_state{current_read_seq = CurrentReadSeq})
- when MessageSeq < CurrentReadSeq ->
- HsState;
-
-reassemble_dtls_fragment(SeqNo, Type, Length, MessageSeq,
- FragmentOffset, FragmentLength,
- Body,
- HsState = #dtls_hs_state{fragments = Fragments0}) ->
- case gb_trees:lookup(MessageSeq, Fragments0) of
- {value, Fragment} ->
- dtls_fragment_reassemble(SeqNo, Type, Length, MessageSeq,
- FragmentOffset, FragmentLength,
- Body, Fragment, HsState);
- none ->
- dtls_fragment_start(SeqNo, Type, Length, MessageSeq,
- FragmentOffset, FragmentLength,
- Body, HsState)
- end.
-dtls_fragment_start(SeqNo, Type, Length, MessageSeq,
- FragmentOffset, FragmentLength,
- Body, HsState = #dtls_hs_state{fragments = Fragments0}) ->
- Fragment = {SeqNo, Type, Length, MessageSeq,
- dtls_fragment_init(Length, FragmentOffset, FragmentLength, Body)},
- Fragments1 = gb_trees:insert(MessageSeq, Fragment, Fragments0),
- HsState#dtls_hs_state{fragments = Fragments1}.
-
-dtls_fragment_reassemble(SeqNo, Type, Length, MessageSeq,
- FragmentOffset, FragmentLength,
- Body,
- {LastSeqNo, Type, Length, MessageSeq, FragBuffer0},
- HsState = #dtls_hs_state{fragments = Fragments0}) ->
- FragBuffer1 = dtls_fragment_add(FragBuffer0, FragmentOffset, FragmentLength, Body),
- Fragment = {erlang:max(SeqNo, LastSeqNo), Type, Length, MessageSeq, FragBuffer1},
- Fragments1 = gb_trees:enter(MessageSeq, Fragment, Fragments0),
- HsState#dtls_hs_state{fragments = Fragments1};
-
-%% Type, Length or Seq mismatch, drop everything...
-%% Note: the RFC is not clear on how to handle this...
-dtls_fragment_reassemble(_SeqNo, _Type, _Length, MessageSeq,
- _FragmentOffset, _FragmentLength, _Body, _Fragment,
- HsState = #dtls_hs_state{fragments = Fragments0}) ->
- Fragments1 = gb_trees:delete_any(MessageSeq, Fragments0),
- HsState#dtls_hs_state{fragments = Fragments1}.
-
-dtls_fragment_add({Length, FragmentList0, Bin0}, FragmentOffset, FragmentLength, Body) ->
- Bin1 = dtls_fragment_bin_add(FragmentOffset, FragmentLength, Body, Bin0),
- FragmentList1 = add_fragment(FragmentList0, {FragmentOffset, FragmentLength}),
- {Length, FragmentList1, Bin1}.
-
-dtls_fragment_init(Length, 0, Length, Body) ->
- {Length, [{0, Length}], Body};
-dtls_fragment_init(Length, FragmentOffset, FragmentLength, Body) ->
- Bin = dtls_fragment_bin_add(FragmentOffset, FragmentLength, Body, <<0:(Length*8)>>),
- {Length, [{FragmentOffset, FragmentOffset + FragmentLength}], Bin}.
-
-dtls_fragment_bin_add(FragmentOffset, FragmentLength, Add, Buffer) ->
- <<First:FragmentOffset/bytes, _:FragmentLength/bytes, Rest/binary>> = Buffer,
- <<First/binary, Add/binary, Rest/binary>>.
-
-merge_fragment_list([], Fragment, Acc) ->
- lists:reverse([Fragment|Acc]);
-
-merge_fragment_list([H = {_, HEnd}|Rest], Frag = {FStart, _}, Acc)
- when FStart > HEnd ->
- merge_fragment_list(Rest, Frag, [H|Acc]);
-
-merge_fragment_list(Rest = [{HStart, _HEnd}|_], Frag = {_FStart, FEnd}, Acc)
- when FEnd < HStart ->
- lists:reverse(Acc) ++ [Frag|Rest];
-
-merge_fragment_list([{HStart, HEnd}|Rest], _Frag = {FStart, FEnd}, Acc)
- when
- FStart =< HEnd orelse FEnd >= HStart ->
- Start = erlang:min(HStart, FStart),
- End = erlang:max(HEnd, FEnd),
- NewFrag = {Start, End},
- merge_fragment_list(Rest, NewFrag, Acc).
-
-add_fragment(List, {FragmentOffset, FragmentLength}) ->
- merge_fragment_list(List, {FragmentOffset, FragmentOffset + FragmentLength}, []).
+%%%%%%% Encodeing %%%%%%%%%%%%%
enc_handshake(#hello_verify_request{protocol_version = {Major, Minor},
cookie = Cookie}, _Version) ->
- CookieLength = byte_size(Cookie),
+ CookieLength = byte_size(Cookie),
{?HELLO_VERIFY_REQUEST, <<?BYTE(Major), ?BYTE(Minor),
?BYTE(CookieLength),
- Cookie/binary>>};
+ Cookie:CookieLength/binary>>};
enc_handshake(#hello_request{}, _Version) ->
{?HELLO_REQUEST, <<>>};
@@ -445,58 +229,274 @@ enc_handshake(#client_hello{client_version = {Major, Minor},
cookie = Cookie,
cipher_suites = CipherSuites,
compression_methods = CompMethods,
- extensions = HelloExtensions}, Version) ->
+ extensions = HelloExtensions}, _Version) ->
SIDLength = byte_size(SessionID),
- BinCookie = enc_client_hello_cookie(Version, Cookie),
+ CookieLength = byte_size(Cookie),
BinCompMethods = list_to_binary(CompMethods),
CmLength = byte_size(BinCompMethods),
BinCipherSuites = list_to_binary(CipherSuites),
CsLength = byte_size(BinCipherSuites),
ExtensionsBin = ssl_handshake:encode_hello_extensions(HelloExtensions),
-
+
{?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SIDLength), SessionID/binary,
- BinCookie/binary,
+ ?BYTE(CookieLength), Cookie/binary,
?UINT16(CsLength), BinCipherSuites/binary,
?BYTE(CmLength), BinCompMethods/binary, ExtensionsBin/binary>>};
+
+enc_handshake(#server_hello{} = HandshakeMsg, Version) ->
+ {Type, <<?BYTE(Major), ?BYTE(Minor), Rest/binary>>} =
+ ssl_handshake:encode_handshake(HandshakeMsg, Version),
+ {DTLSMajor, DTLSMinor} = dtls_v1:corresponding_dtls_version({Major, Minor}),
+ {Type, <<?BYTE(DTLSMajor), ?BYTE(DTLSMinor), Rest/binary>>};
+
enc_handshake(HandshakeMsg, Version) ->
- ssl_handshake:encode_handshake(HandshakeMsg, Version).
+ ssl_handshake:encode_handshake(HandshakeMsg, dtls_v1:corresponding_tls_version(Version)).
-enc_client_hello_cookie(_, <<>>) ->
- <<>>;
-enc_client_hello_cookie(_, Cookie) ->
- CookieLength = byte_size(Cookie),
- <<?BYTE(CookieLength), Cookie/binary>>.
+bin_fragments(Bin, Size) ->
+ bin_fragments(Bin, size(Bin), Size, 0, []).
+
+bin_fragments(Bin, BinSize, FragSize, Offset, Fragments) ->
+ case (BinSize - Offset - FragSize) > 0 of
+ true ->
+ Frag = binary:part(Bin, {Offset, FragSize}),
+ bin_fragments(Bin, BinSize, FragSize, Offset + FragSize, [{Frag, Offset} | Fragments]);
+ false ->
+ Frag = binary:part(Bin, {Offset, BinSize-Offset}),
+ lists:reverse([{Frag, Offset} | Fragments])
+ end.
-decode_handshake(_Version, ?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
+handshake_fragments(_, _, _, [], Acc) ->
+ lists:reverse(Acc);
+handshake_fragments(MsgType, Seq, Len, [{Bin, Offset} | Bins], Acc) ->
+ FragLen = size(Bin),
+ handshake_fragments(MsgType, Seq, Len, Bins,
+ [<<?BYTE(MsgType), Len/binary, Seq/binary, ?UINT24(Offset),
+ ?UINT24(FragLen), Bin/binary>> | Acc]).
+
+address_to_bin({A,B,C,D}, Port) ->
+ <<0:80,16#ffff:16,A,B,C,D,Port:16>>;
+address_to_bin({A,B,C,D,E,F,G,H}, Port) ->
+ <<A:16,B:16,C:16,D:16,E:16,F:16,G:16,H:16,Port:16>>.
+
+%%%%%%% Decodeing %%%%%%%%%%%%%
+
+handle_fragments(Version, FragmentData, Buffers0, Acc) ->
+ Fragments = decode_handshake_fragments(FragmentData),
+ do_handle_fragments(Version, Fragments, Buffers0, Acc).
+
+do_handle_fragments(_, [], Buffers, Acc) ->
+ {lists:reverse(Acc), Buffers};
+do_handle_fragments(Version, [Fragment | Fragments], Buffers0, Acc) ->
+ case reassemble(Version, Fragment, Buffers0) of
+ {more_data, Buffers} when Fragments == [] ->
+ {lists:reverse(Acc), Buffers};
+ {more_data, Buffers} ->
+ do_handle_fragments(Version, Fragments, Buffers, Acc);
+ {HsPacket, Buffers} ->
+ do_handle_fragments(Version, Fragments, Buffers, [HsPacket | Acc])
+ end.
+
+decode_handshake(Version, <<?BYTE(Type), Bin/binary>>) ->
+ decode_handshake(Version, Type, Bin).
+
+decode_handshake(_, ?HELLO_REQUEST, <<>>) ->
+ #hello_request{};
+decode_handshake(_Version, ?CLIENT_HELLO, <<?UINT24(_), ?UINT16(_),
+ ?UINT24(_), ?UINT24(_),
+ ?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SID_length), Session_ID:SID_length/binary,
- ?BYTE(Cookie_length), Cookie:Cookie_length/binary,
+ ?BYTE(CookieLength), Cookie:CookieLength/binary,
?UINT16(Cs_length), CipherSuites:Cs_length/binary,
?BYTE(Cm_length), Comp_methods:Cm_length/binary,
Extensions/binary>>) ->
- DecodedExtensions = ssl_handshake:decode_hello_extensions(Extensions),
-
+ DecodedExtensions = ssl_handshake:decode_hello_extensions({client, Extensions}),
+
#client_hello{
client_version = {Major,Minor},
random = Random,
- session_id = Session_ID,
cookie = Cookie,
+ session_id = Session_ID,
cipher_suites = ssl_handshake:decode_suites('2_bytes', CipherSuites),
compression_methods = Comp_methods,
extensions = DecodedExtensions
- };
+ };
+
+decode_handshake(_Version, ?HELLO_VERIFY_REQUEST, <<?UINT24(_), ?UINT16(_),
+ ?UINT24(_), ?UINT24(_),
+ ?BYTE(Major), ?BYTE(Minor),
+ ?BYTE(CookieLength),
+ Cookie:CookieLength/binary>>) ->
+ #hello_verify_request{protocol_version = {Major, Minor},
+ cookie = Cookie};
+
+decode_handshake(Version, Tag, <<?UINT24(_), ?UINT16(_),
+ ?UINT24(_), ?UINT24(_), Msg/binary>>) ->
+ %% DTLS specifics stripped
+ decode_tls_thandshake(Version, Tag, Msg).
+
+decode_tls_thandshake(Version, Tag, Msg) ->
+ TLSVersion = dtls_v1:corresponding_tls_version(Version),
+ ssl_handshake:decode_handshake(TLSVersion, Tag, Msg).
+
+decode_handshake_fragments(<<>>) ->
+ [<<>>];
+decode_handshake_fragments(<<?BYTE(Type), ?UINT24(Length),
+ ?UINT16(MessageSeq),
+ ?UINT24(FragmentOffset), ?UINT24(FragmentLength),
+ Fragment:FragmentLength/binary, Rest/binary>>) ->
+ [#handshake_fragment{type = Type,
+ length = Length,
+ message_seq = MessageSeq,
+ fragment_offset = FragmentOffset,
+ fragment_length = FragmentLength,
+ fragment = Fragment} | decode_handshake_fragments(Rest)].
+
+reassemble(Version, #handshake_fragment{message_seq = Seq} = Fragment,
+ #protocol_buffers{dtls_handshake_next_seq = Seq,
+ dtls_handshake_next_fragments = Fragments0,
+ dtls_handshake_later_fragments = LaterFragments0} =
+ Buffers0)->
+ case reassemble_fragments(Fragment, Fragments0) of
+ {more_data, Fragments} ->
+ {more_data, Buffers0#protocol_buffers{dtls_handshake_next_fragments = Fragments}};
+ {raw, RawHandshake} ->
+ Handshake = decode_handshake(Version, RawHandshake),
+ {NextFragments, LaterFragments} = next_fragments(LaterFragments0),
+ {{Handshake, RawHandshake}, Buffers0#protocol_buffers{dtls_handshake_next_seq = Seq + 1,
+ dtls_handshake_next_fragments = NextFragments,
+ dtls_handshake_later_fragments = LaterFragments}}
+ end;
+reassemble(_, #handshake_fragment{message_seq = FragSeq} = Fragment,
+ #protocol_buffers{dtls_handshake_next_seq = Seq,
+ dtls_handshake_later_fragments = LaterFragments} = Buffers0) when FragSeq > Seq->
+ {more_data,
+ Buffers0#protocol_buffers{dtls_handshake_later_fragments = [Fragment | LaterFragments]}};
+reassemble(_, _, Buffers) ->
+ %% Disregard fragments FragSeq < Seq
+ {more_data, Buffers}.
+
+reassemble_fragments(Current, Fragments0) ->
+ [Frag1 | Frags] = lists:keysort(#handshake_fragment.fragment_offset, [Current | Fragments0]),
+ [Fragment | _] = Fragments = merge_fragment(Frag1, Frags),
+ case is_complete_handshake(Fragment) of
+ true ->
+ {raw, handshake_bin(Fragment)};
+ false ->
+ {more_data, Fragments}
+ end.
-decode_handshake(_Version, ?HELLO_VERIFY_REQUEST, <<?BYTE(Major), ?BYTE(Minor),
- ?BYTE(CookieLength), Cookie:CookieLength/binary>>) ->
+merge_fragment(Frag0, []) ->
+ [Frag0];
+merge_fragment(Frag0, [Frag1 | Rest]) ->
+ case merge_fragments(Frag0, Frag1) of
+ [_|_] = Frags ->
+ Frags ++ Rest;
+ Frag ->
+ merge_fragment(Frag, Rest)
+ end.
- #hello_verify_request{
- protocol_version = {Major,Minor},
- cookie = Cookie};
-decode_handshake(Version, Tag, Msg) ->
- ssl_handshake:decode_handshake(Version, Tag, Msg).
+is_complete_handshake(#handshake_fragment{length = Length, fragment_length = Length}) ->
+ true;
+is_complete_handshake(_) ->
+ false.
+
+next_fragments(LaterFragments) ->
+ case lists:keysort(#handshake_fragment.message_seq, LaterFragments) of
+ [] ->
+ {[], []};
+ [#handshake_fragment{message_seq = Seq} | _] = Fragments ->
+ split_frags(Fragments, Seq, [])
+ end.
-%% address_to_bin({A,B,C,D}, Port) ->
-%% <<0:80,16#ffff:16,A,B,C,D,Port:16>>;
-%% address_to_bin({A,B,C,D,E,F,G,H}, Port) ->
-%% <<A:16,B:16,C:16,D:16,E:16,F:16,G:16,H:16,Port:16>>.
+split_frags([#handshake_fragment{message_seq = Seq} = Frag | Rest], Seq, Acc) ->
+ split_frags(Rest, Seq, [Frag | Acc]);
+split_frags(Frags, _, Acc) ->
+ {lists:reverse(Acc), Frags}.
+
+
+%% Duplicate
+merge_fragments(#handshake_fragment{
+ fragment_offset = PreviousOffSet,
+ fragment_length = PreviousLen,
+ fragment = PreviousData
+ } = Previous,
+ #handshake_fragment{
+ fragment_offset = PreviousOffSet,
+ fragment_length = PreviousLen,
+ fragment = PreviousData}) ->
+ Previous;
+
+%% Lager fragment save new data
+merge_fragments(#handshake_fragment{
+ fragment_offset = PreviousOffSet,
+ fragment_length = PreviousLen,
+ fragment = PreviousData
+ } = Previous,
+ #handshake_fragment{
+ fragment_offset = PreviousOffSet,
+ fragment_length = CurrentLen,
+ fragment = CurrentData}) when CurrentLen > PreviousLen ->
+ NewLength = CurrentLen - PreviousLen,
+ <<_:PreviousLen/binary, NewData/binary>> = CurrentData,
+ Previous#handshake_fragment{
+ fragment_length = PreviousLen + NewLength,
+ fragment = <<PreviousData/binary, NewData/binary>>
+ };
+
+%% Smaller fragment
+merge_fragments(#handshake_fragment{
+ fragment_offset = PreviousOffSet,
+ fragment_length = PreviousLen
+ } = Previous,
+ #handshake_fragment{
+ fragment_offset = PreviousOffSet,
+ fragment_length = CurrentLen}) when CurrentLen < PreviousLen ->
+ Previous;
+%% Next fragment, might be overlapping
+merge_fragments(#handshake_fragment{
+ fragment_offset = PreviousOffSet,
+ fragment_length = PreviousLen,
+ fragment = PreviousData
+ } = Previous,
+ #handshake_fragment{
+ fragment_offset = CurrentOffSet,
+ fragment_length = CurrentLen,
+ fragment = CurrentData})
+ when PreviousOffSet + PreviousLen >= CurrentOffSet andalso
+ PreviousOffSet + PreviousLen < CurrentOffSet + CurrentLen ->
+ CurrentStart = PreviousOffSet + PreviousLen - CurrentOffSet,
+ <<_:CurrentStart/bytes, Data/binary>> = CurrentData,
+ Previous#handshake_fragment{
+ fragment_length = PreviousLen + CurrentLen - CurrentStart,
+ fragment = <<PreviousData/binary, Data/binary>>};
+%% already fully contained fragment
+merge_fragments(#handshake_fragment{
+ fragment_offset = PreviousOffSet,
+ fragment_length = PreviousLen
+ } = Previous,
+ #handshake_fragment{
+ fragment_offset = CurrentOffSet,
+ fragment_length = CurrentLen})
+ when PreviousOffSet + PreviousLen >= CurrentOffSet andalso
+ PreviousOffSet + PreviousLen >= CurrentOffSet + CurrentLen ->
+ Previous;
+
+%% No merge there is a gap
+merge_fragments(Previous, Current) ->
+ [Previous, Current].
+
+handshake_bin(#handshake_fragment{
+ type = Type,
+ length = Len,
+ message_seq = Seq,
+ fragment_length = Len,
+ fragment_offset = 0,
+ fragment = Fragment}) ->
+ handshake_bin(Type, Len, Seq, Fragment).
+
+handshake_bin(Type, Length, Seq, FragmentData) ->
+ <<?BYTE(Type), ?UINT24(Length),
+ ?UINT16(Seq), ?UINT24(0), ?UINT24(Length),
+ FragmentData:Length/binary>>.
diff --git a/lib/ssl/src/dtls_handshake.hrl b/lib/ssl/src/dtls_handshake.hrl
index 0298fd3105..50e92027d2 100644
--- a/lib/ssl/src/dtls_handshake.hrl
+++ b/lib/ssl/src/dtls_handshake.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@
-include("ssl_handshake.hrl"). %% Common TLS and DTLS records and Constantes
-define(HELLO_VERIFY_REQUEST, 3).
+-define(HELLO_VERIFY_REQUEST_VERSION, {254, 255}).
-record(client_hello, {
client_version,
@@ -46,12 +47,13 @@
cookie
}).
--record(dtls_hs_state,
- {current_read_seq,
- starting_read_seq,
- highest_record_seq,
- fragments,
- completed
- }).
+-record(handshake_fragment, {
+ type,
+ length,
+ message_seq,
+ fragment_offset,
+ fragment_length,
+ fragment
+ }).
-endif. % -ifdef(dtls_handshake).
diff --git a/lib/ssl/src/dtls_record.erl b/lib/ssl/src/dtls_record.erl
index 5387fcafa8..8a7f8c1d0a 100644
--- a/lib/ssl/src/dtls_record.erl
+++ b/lib/ssl/src/dtls_record.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -30,34 +30,107 @@
-include("ssl_cipher.hrl").
%% Handling of incoming data
--export([get_dtls_records/2]).
+-export([get_dtls_records/2, init_connection_states/2]).
%% Decoding
-export([decode_cipher_text/2]).
%% Encoding
--export([encode_plain_text/4, encode_tls_cipher_text/5, encode_change_cipher_spec/2]).
+-export([encode_handshake/4, encode_alert_record/3,
+ encode_change_cipher_spec/3, encode_data/3]).
+-export([encode_plain_text/5]).
%% Protocol version handling
-export([protocol_version/1, lowest_protocol_version/1, lowest_protocol_version/2,
highest_protocol_version/1, highest_protocol_version/2,
is_higher/2, supported_protocol_versions/0,
- is_acceptable_version/2]).
+ is_acceptable_version/2, hello_version/2]).
-%% DTLS Epoch handling
--export([init_connection_state_seq/2, current_connection_state_epoch/2,
- set_connection_state_by_epoch/3, connection_state_by_epoch/3]).
+-export([save_current_connection_state/2, next_epoch/2, get_connection_state_by_epoch/3, replay_detect/2]).
+
+-export([init_connection_state_seq/2, current_connection_state_epoch/2]).
-export_type([dtls_version/0, dtls_atom_version/0]).
-type dtls_version() :: ssl_record:ssl_version().
-type dtls_atom_version() :: dtlsv1 | 'dtlsv1.2'.
+-define(REPLAY_WINDOW_SIZE, 64).
+
-compile(inline).
%%====================================================================
%% Internal application API
%%====================================================================
+%%--------------------------------------------------------------------
+-spec init_connection_states(client | server, one_n_minus_one | zero_n | disabled) ->
+ ssl_record:connection_states().
+%% %
+ %
+%% Description: Creates a connection_states record with appropriate
+%% values for the initial SSL connection setup.
+%%--------------------------------------------------------------------
+init_connection_states(Role, BeastMitigation) ->
+ ConnectionEnd = ssl_record:record_protocol_role(Role),
+ Initial = initial_connection_state(ConnectionEnd, BeastMitigation),
+ Current = Initial#{epoch := 0},
+ InitialPending = ssl_record:empty_connection_state(ConnectionEnd, BeastMitigation),
+ Pending = InitialPending#{epoch => undefined, replay_window => init_replay_window(?REPLAY_WINDOW_SIZE)},
+ #{saved_read => Current,
+ current_read => Current,
+ pending_read => Pending,
+ saved_write => Current,
+ current_write => Current,
+ pending_write => Pending}.
+
+%%--------------------------------------------------------------------
+-spec save_current_connection_state(ssl_record:connection_states(), read | write) ->
+ ssl_record:connection_states().
+%%
+%% Description: Returns the instance of the connection_state map
+%% where the current read|write state has been copied to the save state.
+%%--------------------------------------------------------------------
+save_current_connection_state(#{current_read := Current} = States, read) ->
+ States#{saved_read := Current};
+
+save_current_connection_state(#{current_write := Current} = States, write) ->
+ States#{saved_write := Current}.
+
+next_epoch(#{pending_read := Pending,
+ current_read := #{epoch := Epoch}} = States, read) ->
+ States#{pending_read := Pending#{epoch := Epoch + 1,
+ replay_window := init_replay_window(?REPLAY_WINDOW_SIZE)}};
+
+next_epoch(#{pending_write := Pending,
+ current_write := #{epoch := Epoch}} = States, write) ->
+ States#{pending_write := Pending#{epoch := Epoch + 1,
+ replay_window := init_replay_window(?REPLAY_WINDOW_SIZE)}}.
+
+get_connection_state_by_epoch(Epoch, #{current_write := #{epoch := Epoch} = Current},
+ write) ->
+ Current;
+get_connection_state_by_epoch(Epoch, #{saved_write := #{epoch := Epoch} = Saved},
+ write) ->
+ Saved;
+get_connection_state_by_epoch(Epoch, #{current_read := #{epoch := Epoch} = Current},
+ read) ->
+ Current;
+get_connection_state_by_epoch(Epoch, #{saved_read := #{epoch := Epoch} = Saved},
+ read) ->
+ Saved.
+
+set_connection_state_by_epoch(WriteState, Epoch, #{current_write := #{epoch := Epoch}} = States,
+ write) ->
+ States#{current_write := WriteState};
+set_connection_state_by_epoch(WriteState, Epoch, #{saved_write := #{epoch := Epoch}} = States,
+ write) ->
+ States#{saved_write := WriteState};
+set_connection_state_by_epoch(ReadState, Epoch, #{current_read := #{epoch := Epoch}} = States,
+ read) ->
+ States#{current_read := ReadState};
+set_connection_state_by_epoch(ReadState, Epoch, #{saved_read := #{epoch := Epoch}} = States,
+ read) ->
+ States#{saved_read := ReadState}.
%%--------------------------------------------------------------------
-spec get_dtls_records(binary(), binary()) -> {[binary()], binary()} | #alert{}.
@@ -121,103 +194,57 @@ get_dtls_records_aux(Data, Acc) ->
?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE)
end.
-encode_plain_text(Type, Version, Data,
- #connection_states{current_write =
- #connection_state{
- epoch = Epoch,
- sequence_number = Seq,
- compression_state=CompS0,
- security_parameters=
- #security_parameters{
- cipher_type = ?AEAD,
- compression_algorithm=CompAlg}
- }= WriteState0} = ConnectionStates) ->
- {Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0),
- WriteState1 = WriteState0#connection_state{compression_state = CompS1},
- AAD = calc_aad(Type, Version, Epoch, Seq),
- {CipherFragment, WriteState} = ssl_record:cipher_aead(dtls_v1:corresponding_tls_version(Version),
- Comp, WriteState1, AAD),
- CipherText = encode_tls_cipher_text(Type, Version, Epoch, Seq, CipherFragment),
- {CipherText, ConnectionStates#connection_states{current_write =
- WriteState#connection_state{sequence_number = Seq +1}}};
-
-encode_plain_text(Type, Version, Data,
- #connection_states{current_write=#connection_state{
- epoch = Epoch,
- sequence_number = Seq,
- compression_state=CompS0,
- security_parameters=
- #security_parameters{compression_algorithm=CompAlg}
- }= WriteState0} = ConnectionStates) ->
- {Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0),
- WriteState1 = WriteState0#connection_state{compression_state = CompS1},
- MacHash = calc_mac_hash(WriteState1, Type, Version, Epoch, Seq, Comp),
- {CipherFragment, WriteState} = ssl_record:cipher(dtls_v1:corresponding_tls_version(Version),
- Comp, WriteState1, MacHash),
- CipherText = encode_tls_cipher_text(Type, Version, Epoch, Seq, CipherFragment),
- {CipherText, ConnectionStates#connection_states{current_write =
- WriteState#connection_state{sequence_number = Seq +1}}}.
+%%--------------------------------------------------------------------
+-spec encode_handshake(iolist(), dtls_version(), integer(), ssl_record:connection_states()) ->
+ {iolist(), ssl_record:connection_states()}.
+%
+%% Description: Encodes a handshake message to send on the ssl-socket.
+%%--------------------------------------------------------------------
+encode_handshake(Frag, Version, Epoch, ConnectionStates) ->
+ encode_plain_text(?HANDSHAKE, Version, Epoch, Frag, ConnectionStates).
-decode_cipher_text(#ssl_tls{type = Type, version = Version,
- epoch = Epoch,
- sequence_number = Seq,
- fragment = CipherFragment} = CipherText,
- #connection_states{current_read =
- #connection_state{
- compression_state = CompressionS0,
- security_parameters=
- #security_parameters{
- cipher_type = ?AEAD,
- compression_algorithm=CompAlg}
- } = ReadState0}= ConnnectionStates0) ->
- AAD = calc_aad(Type, Version, Epoch, Seq),
- case ssl_record:decipher_aead(dtls_v1:corresponding_tls_version(Version),
- CipherFragment, ReadState0, AAD) of
- {PlainFragment, ReadState1} ->
- {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
- PlainFragment, CompressionS0),
- ConnnectionStates = ConnnectionStates0#connection_states{
- current_read = ReadState1#connection_state{
- compression_state = CompressionS1}},
- {CipherText#ssl_tls{fragment = Plain}, ConnnectionStates};
- #alert{} = Alert ->
- Alert
- end;
-decode_cipher_text(#ssl_tls{type = Type, version = Version,
- epoch = Epoch,
- sequence_number = Seq,
- fragment = CipherFragment} = CipherText,
- #connection_states{current_read =
- #connection_state{
- compression_state = CompressionS0,
- security_parameters=
- #security_parameters{
- compression_algorithm=CompAlg}
- } = ReadState0}= ConnnectionStates0) ->
- {PlainFragment, Mac, ReadState1} = ssl_record:decipher(dtls_v1:corresponding_tls_version(Version),
- CipherFragment, ReadState0, true),
- MacHash = calc_mac_hash(ReadState1, Type, Version, Epoch, Seq, PlainFragment),
- case ssl_record:is_correct_mac(Mac, MacHash) of
- true ->
- {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
- PlainFragment, CompressionS0),
- ConnnectionStates = ConnnectionStates0#connection_states{
- current_read = ReadState1#connection_state{
- compression_state = CompressionS1}},
- {CipherText#ssl_tls{fragment = Plain}, ConnnectionStates};
- false ->
- ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
- end.
+%%--------------------------------------------------------------------
+-spec encode_alert_record(#alert{}, dtls_version(), ssl_record:connection_states()) ->
+ {iolist(), ssl_record:connection_states()}.
+%%
+%% Description: Encodes an alert message to send on the ssl-socket.
+%%--------------------------------------------------------------------
+encode_alert_record(#alert{level = Level, description = Description},
+ Version, ConnectionStates) ->
+ #{epoch := Epoch} = ssl_record:current_connection_state(ConnectionStates, write),
+ encode_plain_text(?ALERT, Version, Epoch, <<?BYTE(Level), ?BYTE(Description)>>,
+ ConnectionStates).
%%--------------------------------------------------------------------
--spec encode_change_cipher_spec(dtls_version(), #connection_states{}) ->
- {iolist(), #connection_states{}}.
+-spec encode_change_cipher_spec(dtls_version(), integer(), ssl_record:connection_states()) ->
+ {iolist(), ssl_record:connection_states()}.
%%
%% Description: Encodes a change_cipher_spec-message to send on the ssl socket.
%%--------------------------------------------------------------------
-encode_change_cipher_spec(Version, ConnectionStates) ->
- encode_plain_text(?CHANGE_CIPHER_SPEC, Version, <<1:8>>, ConnectionStates).
+encode_change_cipher_spec(Version, Epoch, ConnectionStates) ->
+ encode_plain_text(?CHANGE_CIPHER_SPEC, Version, Epoch, ?byte(?CHANGE_CIPHER_SPEC_PROTO), ConnectionStates).
+
+%%--------------------------------------------------------------------
+-spec encode_data(binary(), dtls_version(), ssl_record:connection_states()) ->
+ {iolist(),ssl_record:connection_states()}.
+%%
+%% Description: Encodes data to send on the ssl-socket.
+%%--------------------------------------------------------------------
+encode_data(Data, Version, ConnectionStates) ->
+ #{epoch := Epoch} = ssl_record:current_connection_state(ConnectionStates, write),
+ encode_plain_text(?APPLICATION_DATA, Version, Epoch, Data, ConnectionStates).
+
+encode_plain_text(Type, Version, Epoch, Data, ConnectionStates) ->
+ Write0 = get_connection_state_by_epoch(Epoch, ConnectionStates, write),
+ {CipherFragment, Write1} = encode_plain_text(Type, Version, Data, Write0),
+ {CipherText, Write} = encode_dtls_cipher_text(Type, Version, CipherFragment, Write1),
+ {CipherText, set_connection_state_by_epoch(Write, Epoch, ConnectionStates, write)}.
+
+
+decode_cipher_text(#ssl_tls{epoch = Epoch} = CipherText, ConnnectionStates0) ->
+ ReadState = get_connection_state_by_epoch(Epoch, ConnnectionStates0, read),
+ decode_cipher_text(CipherText, ReadState, ConnnectionStates0).
%%--------------------------------------------------------------------
-spec protocol_version(dtls_atom_version() | dtls_version()) ->
@@ -352,92 +379,60 @@ is_acceptable_version(Version, Versions) ->
%%--------------------------------------------------------------------
--spec init_connection_state_seq(dtls_version(), #connection_states{}) ->
- #connection_state{}.
+-spec init_connection_state_seq(dtls_version(), ssl_record:connection_states()) ->
+ ssl_record:connection_state().
%%
%% Description: Copy the read sequence number to the write sequence number
%% This is only valid for DTLS in the first client_hello
%%--------------------------------------------------------------------
init_connection_state_seq({254, _},
- #connection_states{
- current_read = Read = #connection_state{epoch = 0},
- current_write = Write = #connection_state{epoch = 0}} = CS0) ->
- CS0#connection_states{current_write =
- Write#connection_state{
- sequence_number = Read#connection_state.sequence_number}};
-init_connection_state_seq(_, CS) ->
- CS.
+ #{current_read := #{epoch := 0, sequence_number := Seq},
+ current_write := #{epoch := 0} = Write} = ConnnectionStates0) ->
+ ConnnectionStates0#{current_write => Write#{sequence_number => Seq}};
+init_connection_state_seq(_, ConnnectionStates) ->
+ ConnnectionStates.
%%--------------------------------------------------------
--spec current_connection_state_epoch(#connection_states{}, read | write) ->
+-spec current_connection_state_epoch(ssl_record:connection_states(), read | write) ->
integer().
%%
%% Description: Returns the epoch the connection_state record
-%% that is currently defined as the current conection state.
+%% that is currently defined as the current connection state.
%%--------------------------------------------------------------------
-current_connection_state_epoch(#connection_states{current_read = Current},
+current_connection_state_epoch(#{current_read := #{epoch := Epoch}},
read) ->
- Current#connection_state.epoch;
-current_connection_state_epoch(#connection_states{current_write = Current},
+ Epoch;
+current_connection_state_epoch(#{current_write := #{epoch := Epoch}},
write) ->
- Current#connection_state.epoch.
+ Epoch.
+
+-spec hello_version(dtls_version(), [dtls_version()]) -> dtls_version().
+hello_version(Version, Versions) ->
+ case dtls_v1:corresponding_tls_version(Version) of
+ TLSVersion when TLSVersion >= {3, 3} ->
+ Version;
+ _ ->
+ lowest_protocol_version(Versions)
+ end.
-%%--------------------------------------------------------------------
-
--spec connection_state_by_epoch(#connection_states{}, integer(), read | write) ->
- #connection_state{}.
-%%
-%% Description: Returns the instance of the connection_state record
-%% that is defined by the Epoch.
-%%--------------------------------------------------------------------
-connection_state_by_epoch(#connection_states{current_read = CS}, Epoch, read)
- when CS#connection_state.epoch == Epoch ->
- CS;
-connection_state_by_epoch(#connection_states{pending_read = CS}, Epoch, read)
- when CS#connection_state.epoch == Epoch ->
- CS;
-connection_state_by_epoch(#connection_states{current_write = CS}, Epoch, write)
- when CS#connection_state.epoch == Epoch ->
- CS;
-connection_state_by_epoch(#connection_states{pending_write = CS}, Epoch, write)
- when CS#connection_state.epoch == Epoch ->
- CS.
-%%--------------------------------------------------------------------
--spec set_connection_state_by_epoch(#connection_states{},
- #connection_state{}, read | write)
- -> #connection_states{}.
-%%
-%% Description: Returns the instance of the connection_state record
-%% that is defined by the Epoch.
-%%--------------------------------------------------------------------
-set_connection_state_by_epoch(ConnectionStates0 =
- #connection_states{current_read = CS},
- NewCS = #connection_state{epoch = Epoch}, read)
- when CS#connection_state.epoch == Epoch ->
- ConnectionStates0#connection_states{current_read = NewCS};
-
-set_connection_state_by_epoch(ConnectionStates0 =
- #connection_states{pending_read = CS},
- NewCS = #connection_state{epoch = Epoch}, read)
- when CS#connection_state.epoch == Epoch ->
- ConnectionStates0#connection_states{pending_read = NewCS};
-
-set_connection_state_by_epoch(ConnectionStates0 =
- #connection_states{current_write = CS},
- NewCS = #connection_state{epoch = Epoch}, write)
- when CS#connection_state.epoch == Epoch ->
- ConnectionStates0#connection_states{current_write = NewCS};
-
-set_connection_state_by_epoch(ConnectionStates0 =
- #connection_states{pending_write = CS},
- NewCS = #connection_state{epoch = Epoch}, write)
- when CS#connection_state.epoch == Epoch ->
- ConnectionStates0#connection_states{pending_write = NewCS}.
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-
+initial_connection_state(ConnectionEnd, BeastMitigation) ->
+ #{security_parameters =>
+ ssl_record:initial_security_params(ConnectionEnd),
+ epoch => undefined,
+ sequence_number => 0,
+ replay_window => init_replay_window(?REPLAY_WINDOW_SIZE),
+ beast_mitigation => BeastMitigation,
+ compression_state => undefined,
+ cipher_state => undefined,
+ mac_secret => undefined,
+ secure_renegotiation => undefined,
+ client_verify_data => undefined,
+ server_verify_data => undefined
+ }.
lowest_list_protocol_version(Ver, []) ->
Ver;
@@ -449,17 +444,105 @@ highest_list_protocol_version(Ver, []) ->
highest_list_protocol_version(Ver1, [Ver2 | Rest]) ->
highest_list_protocol_version(highest_protocol_version(Ver1, Ver2), Rest).
-encode_tls_cipher_text(Type, {MajVer, MinVer}, Epoch, Seq, Fragment) ->
+encode_dtls_cipher_text(Type, {MajVer, MinVer}, Fragment,
+ #{epoch := Epoch, sequence_number := Seq} = WriteState) ->
Length = erlang:iolist_size(Fragment),
- [<<?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer), ?UINT16(Epoch),
- ?UINT48(Seq), ?UINT16(Length)>>, Fragment].
+ {[<<?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer), ?UINT16(Epoch),
+ ?UINT48(Seq), ?UINT16(Length)>>, Fragment],
+ WriteState#{sequence_number => Seq + 1}}.
+
+encode_plain_text(Type, Version, Data, #{compression_state := CompS0,
+ epoch := Epoch,
+ sequence_number := Seq,
+ cipher_state := CipherS0,
+ security_parameters :=
+ #security_parameters{
+ cipher_type = ?AEAD,
+ bulk_cipher_algorithm =
+ BulkCipherAlgo,
+ compression_algorithm = CompAlg}
+ } = WriteState0) ->
+ {Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0),
+ AAD = calc_aad(Type, Version, Epoch, Seq),
+ TLSVersion = dtls_v1:corresponding_tls_version(Version),
+ {CipherFragment, CipherS1} =
+ ssl_cipher:cipher_aead(BulkCipherAlgo, CipherS0, Seq, AAD, Comp, TLSVersion),
+ {CipherFragment, WriteState0#{compression_state => CompS1,
+ cipher_state => CipherS1}};
+encode_plain_text(Type, Version, Fragment, #{compression_state := CompS0,
+ epoch := Epoch,
+ sequence_number := Seq,
+ cipher_state := CipherS0,
+ security_parameters :=
+ #security_parameters{compression_algorithm = CompAlg,
+ bulk_cipher_algorithm =
+ BulkCipherAlgo}
+ }= WriteState0) ->
+ {Comp, CompS1} = ssl_record:compress(CompAlg, Fragment, CompS0),
+ WriteState1 = WriteState0#{compression_state => CompS1},
+ MAC = calc_mac_hash(Type, Version, WriteState1, Epoch, Seq, Comp),
+ TLSVersion = dtls_v1:corresponding_tls_version(Version),
+ {CipherFragment, CipherS1} =
+ ssl_cipher:cipher(BulkCipherAlgo, CipherS0, MAC, Fragment, TLSVersion),
+ {CipherFragment, WriteState0#{cipher_state => CipherS1}}.
+
+decode_cipher_text(#ssl_tls{type = Type, version = Version,
+ epoch = Epoch,
+ sequence_number = Seq,
+ fragment = CipherFragment} = CipherText,
+ #{compression_state := CompressionS0,
+ cipher_state := CipherS0,
+ security_parameters :=
+ #security_parameters{
+ cipher_type = ?AEAD,
+ bulk_cipher_algorithm =
+ BulkCipherAlgo,
+ compression_algorithm = CompAlg}} = ReadState0,
+ ConnnectionStates0) ->
+ AAD = calc_aad(Type, Version, Epoch, Seq),
+ TLSVersion = dtls_v1:corresponding_tls_version(Version),
+ case ssl_cipher:decipher_aead(BulkCipherAlgo, CipherS0, Seq, AAD, CipherFragment, TLSVersion) of
+ {PlainFragment, CipherState} ->
+ {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
+ PlainFragment, CompressionS0),
+ ReadState0 = ReadState0#{compression_state => CompressionS1,
+ cipher_state => CipherState},
+ ReadState = update_replay_window(Seq, ReadState0),
+ ConnnectionStates = set_connection_state_by_epoch(ReadState, Epoch, ConnnectionStates0, read),
+ {CipherText#ssl_tls{fragment = Plain}, ConnnectionStates};
+ #alert{} = Alert ->
+ Alert
+ end;
+decode_cipher_text(#ssl_tls{type = Type, version = Version,
+ epoch = Epoch,
+ sequence_number = Seq,
+ fragment = CipherFragment} = CipherText,
+ #{compression_state := CompressionS0,
+ security_parameters :=
+ #security_parameters{
+ compression_algorithm = CompAlg}} = ReadState0,
+ ConnnectionStates0) ->
+ {PlainFragment, Mac, ReadState1} = ssl_record:decipher(dtls_v1:corresponding_tls_version(Version),
+ CipherFragment, ReadState0, true),
+ MacHash = calc_mac_hash(Type, Version, ReadState1, Epoch, Seq, PlainFragment),
+ case ssl_record:is_correct_mac(Mac, MacHash) of
+ true ->
+ {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
+ PlainFragment, CompressionS0),
+
+ ReadState2 = ReadState1#{compression_state => CompressionS1},
+ ReadState = update_replay_window(Seq, ReadState2),
+ ConnnectionStates = set_connection_state_by_epoch(ReadState, Epoch, ConnnectionStates0, read),
+ {CipherText#ssl_tls{fragment = Plain}, ConnnectionStates};
+ false ->
+ ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
+ end.
-calc_mac_hash(#connection_state{mac_secret = MacSecret,
- security_parameters = #security_parameters{mac_algorithm = MacAlg}},
- Type, Version, Epoch, SeqNo, Fragment) ->
+calc_mac_hash(Type, Version, #{mac_secret := MacSecret,
+ security_parameters := #security_parameters{mac_algorithm = MacAlg}},
+ Epoch, SeqNo, Fragment) ->
Length = erlang:iolist_size(Fragment),
- NewSeq = (Epoch bsl 48) + SeqNo,
- mac_hash(Version, MacAlg, MacSecret, NewSeq, Type,
+ mac_hash(Version, MacAlg, MacSecret, Epoch, SeqNo, Type,
Length, Fragment).
highest_protocol_version() ->
@@ -472,10 +555,46 @@ sufficient_dtlsv1_2_crypto_support() ->
CryptoSupport = crypto:supports(),
proplists:get_bool(sha256, proplists:get_value(hashs, CryptoSupport)).
-mac_hash(Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) ->
- dtls_v1:mac_hash(Version, MacAlg, MacSecret, SeqNo, Type,
- Length, Fragment).
-
+mac_hash({Major, Minor}, MacAlg, MacSecret, Epoch, SeqNo, Type, Length, Fragment) ->
+ Value = [<<?UINT16(Epoch), ?UINT48(SeqNo), ?BYTE(Type),
+ ?BYTE(Major), ?BYTE(Minor), ?UINT16(Length)>>,
+ Fragment],
+ dtls_v1:hmac_hash(MacAlg, MacSecret, Value).
+
calc_aad(Type, {MajVer, MinVer}, Epoch, SeqNo) ->
- NewSeq = (Epoch bsl 48) + SeqNo,
- <<NewSeq:64/integer, ?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer)>>.
+ <<?UINT16(Epoch), ?UINT48(SeqNo), ?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer)>>.
+
+init_replay_window(Size) ->
+ #{size => Size,
+ top => Size,
+ bottom => 0,
+ mask => 0 bsl 64
+ }.
+
+replay_detect(#ssl_tls{sequence_number = SequenceNumber}, #{replay_window := Window}) ->
+ is_replay(SequenceNumber, Window).
+
+
+is_replay(SequenceNumber, #{bottom := Bottom}) when SequenceNumber < Bottom ->
+ true;
+is_replay(SequenceNumber, #{size := Size,
+ top := Top,
+ bottom := Bottom,
+ mask := Mask}) when (SequenceNumber >= Bottom) andalso (SequenceNumber =< Top) ->
+ Index = (SequenceNumber rem Size),
+ (Index band Mask) == 1;
+
+is_replay(_, _) ->
+ false.
+
+update_replay_window(SequenceNumber, #{replay_window := #{size := Size,
+ top := Top,
+ bottom := Bottom,
+ mask := Mask0} = Window0} = ConnectionStates) ->
+ NoNewBits = SequenceNumber - Top,
+ Index = SequenceNumber rem Size,
+ Mask = (Mask0 bsl NoNewBits) bor Index,
+ Window = Window0#{top => SequenceNumber,
+ bottom => Bottom + NoNewBits,
+ mask => Mask},
+ ConnectionStates#{replay_window := Window}.
diff --git a/lib/ssl/src/dtls_record.hrl b/lib/ssl/src/dtls_record.hrl
index b9f84cbe7f..373481c3f8 100644
--- a/lib/ssl/src/dtls_record.hrl
+++ b/lib/ssl/src/dtls_record.hrl
@@ -34,11 +34,10 @@
-record(ssl_tls, {
type,
version,
- epoch,
- sequence_number,
- offset,
- length,
- fragment
+ %%length,
+ fragment,
+ epoch,
+ sequence_number
}).
-endif. % -ifdef(dtls_record).
diff --git a/lib/ssl/src/dtls_socket.erl b/lib/ssl/src/dtls_socket.erl
new file mode 100644
index 0000000000..fbbd479428
--- /dev/null
+++ b/lib/ssl/src/dtls_socket.erl
@@ -0,0 +1,156 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2016-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(dtls_socket).
+
+-include("ssl_internal.hrl").
+-include("ssl_api.hrl").
+
+-export([send/3, listen/3, accept/3, connect/4, socket/4, setopts/3, getopts/3, getstat/3,
+ peername/2, sockname/2, port/2, close/2]).
+-export([emulated_options/0, internal_inet_values/0, default_inet_values/0, default_cb_info/0]).
+
+send(Transport, {{IP,Port},Socket}, Data) ->
+ Transport:send(Socket, IP, Port, Data).
+
+listen(gen_udp = Transport, Port, #config{transport_info = {Transport, _, _, _},
+ ssl = SslOpts,
+ emulated = EmOpts,
+ inet_user = Options} = Config) ->
+
+
+ case dtls_udp_sup:start_child([Port, emulated_socket_options(EmOpts, #socket_options{}),
+ Options ++ internal_inet_values(), SslOpts]) of
+ {ok, Pid} ->
+ {ok, #sslsocket{pid = {udp, Config#config{udp_handler = {Pid, Port}}}}};
+ Err = {error, _} ->
+ Err
+ end.
+
+accept(udp, #config{transport_info = {Transport = gen_udp,_,_,_},
+ connection_cb = ConnectionCb,
+ udp_handler = {Listner, _}}, _Timeout) ->
+ case dtls_udp_listener:accept(Listner, self()) of
+ {ok, Pid, Socket} ->
+ {ok, socket(Pid, Transport, {Listner, Socket}, ConnectionCb)};
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+connect(Address, Port, #config{transport_info = {Transport, _, _, _} = CbInfo,
+ connection_cb = ConnectionCb,
+ ssl = SslOpts,
+ emulated = EmOpts,
+ inet_ssl = SocketOpts}, Timeout) ->
+ case Transport:open(0, SocketOpts ++ internal_inet_values()) of
+ {ok, Socket} ->
+ ssl_connection:connect(ConnectionCb, Address, Port, {{Address, Port},Socket},
+ {SslOpts,
+ emulated_socket_options(EmOpts, #socket_options{}), undefined},
+ self(), CbInfo, Timeout);
+ {error, _} = Error->
+ Error
+ end.
+
+close(gen_udp, {_Client, _Socket}) ->
+ ok.
+
+socket(Pid, gen_udp = Transport, {{_, _}, Socket}, ConnectionCb) ->
+ #sslsocket{pid = Pid,
+ %% "The name "fd" is keept for backwards compatibility
+ fd = {Transport, Socket, ConnectionCb}};
+socket(Pid, Transport, Socket, ConnectionCb) ->
+ #sslsocket{pid = Pid,
+ %% "The name "fd" is keept for backwards compatibility
+ fd = {Transport, Socket, ConnectionCb}}.
+setopts(_, #sslsocket{pid = {udp, #config{udp_handler = {ListenPid, _}}}}, Options) ->
+ SplitOpts = tls_socket:split_options(Options),
+ dtls_udp_listener:set_sock_opts(ListenPid, SplitOpts);
+%%% Following clauses will not be called for emulated options, they are handled in the connection process
+setopts(gen_udp, Socket, Options) ->
+ inet:setopts(Socket, Options);
+setopts(Transport, Socket, Options) ->
+ Transport:setopts(Socket, Options).
+
+getopts(_, #sslsocket{pid = {udp, #config{udp_handler = {ListenPid, _}}}}, Options) ->
+ SplitOpts = tls_socket:split_options(Options),
+ dtls_udp_listener:get_sock_opts(ListenPid, SplitOpts);
+getopts(gen_udp, #sslsocket{pid = {Socket, #config{emulated = EmOpts}}}, Options) ->
+ {SockOptNames, EmulatedOptNames} = tls_socket:split_options(Options),
+ EmulatedOpts = get_emulated_opts(EmOpts, EmulatedOptNames),
+ SocketOpts = tls_socket:get_socket_opts(Socket, SockOptNames, inet),
+ {ok, EmulatedOpts ++ SocketOpts};
+getopts(_Transport, #sslsocket{pid = {Socket, #config{emulated = EmOpts}}}, Options) ->
+ {SockOptNames, EmulatedOptNames} = tls_socket:split_options(Options),
+ EmulatedOpts = get_emulated_opts(EmOpts, EmulatedOptNames),
+ SocketOpts = tls_socket:get_socket_opts(Socket, SockOptNames, inet),
+ {ok, EmulatedOpts ++ SocketOpts};
+%%% Following clauses will not be called for emulated options, they are handled in the connection process
+getopts(gen_udp, {_,{{_, _},Socket}}, Options) ->
+ inet:getopts(Socket, Options);
+getopts(gen_udp, {_,Socket}, Options) ->
+ inet:getopts(Socket, Options);
+getopts(Transport, Socket, Options) ->
+ Transport:getopts(Socket, Options).
+getstat(gen_udp, {_,Socket}, Options) ->
+ inet:getstat(Socket, Options);
+getstat(Transport, Socket, Options) ->
+ Transport:getstat(Socket, Options).
+peername(udp, _) ->
+ {error, enotconn};
+peername(gen_udp, {_, {Client, _Socket}}) ->
+ {ok, Client};
+peername(Transport, Socket) ->
+ Transport:peername(Socket).
+sockname(gen_udp, {_, {_,Socket}}) ->
+ inet:sockname(Socket);
+sockname(gen_udp, Socket) ->
+ inet:sockname(Socket);
+sockname(Transport, Socket) ->
+ Transport:sockname(Socket).
+
+port(gen_udp, {_,Socket}) ->
+ inet:port(Socket);
+port(Transport, Socket) ->
+ Transport:port(Socket).
+
+emulated_options() ->
+ [mode, active, packet, packet_size].
+
+internal_inet_values() ->
+ [{active, false}, {mode,binary}].
+
+default_inet_values() ->
+ [{active, true}, {mode, list}].
+
+default_cb_info() ->
+ {gen_udp, udp, udp_closed, udp_error}.
+
+get_emulated_opts(EmOpts, EmOptNames) ->
+ lists:map(fun(Name) -> {value, Value} = lists:keysearch(Name, 1, EmOpts),
+ Value end,
+ EmOptNames).
+
+emulated_socket_options(InetValues, #socket_options{
+ mode = Mode,
+ active = Active}) ->
+ #socket_options{
+ mode = proplists:get_value(mode, InetValues, Mode),
+ active = proplists:get_value(active, InetValues, Active)
+ }.
diff --git a/lib/ssl/src/dtls_udp_listener.erl b/lib/ssl/src/dtls_udp_listener.erl
new file mode 100644
index 0000000000..c789a32087
--- /dev/null
+++ b/lib/ssl/src/dtls_udp_listener.erl
@@ -0,0 +1,304 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2016-2017. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, 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(dtls_udp_listener).
+
+-behaviour(gen_server).
+
+-include("ssl_internal.hrl").
+
+%% API
+-export([start_link/4, active_once/3, accept/2, sockname/1, close/1,
+ get_all_opts/1, get_sock_opts/2, set_sock_opts/2]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+-record(state,
+ {port,
+ listner,
+ dtls_options,
+ emulated_options,
+ dtls_msq_queues = kv_new(),
+ clients = set_new(),
+ dtls_processes = kv_new(),
+ accepters = queue:new(),
+ first,
+ close
+ }).
+
+%%%===================================================================
+%%% API
+%%%===================================================================
+
+start_link(Port, EmOpts, InetOptions, DTLSOptions) ->
+ gen_server:start_link(?MODULE, [Port, EmOpts, InetOptions, DTLSOptions], []).
+
+active_once(UDPConnection, Client, Pid) ->
+ gen_server:cast(UDPConnection, {active_once, Client, Pid}).
+
+accept(UDPConnection, Accepter) ->
+ call(UDPConnection, {accept, Accepter}).
+
+sockname(UDPConnection) ->
+ call(UDPConnection, sockname).
+close(UDPConnection) ->
+ call(UDPConnection, close).
+get_sock_opts(UDPConnection, SplitSockOpts) ->
+ call(UDPConnection, {get_sock_opts, SplitSockOpts}).
+get_all_opts(UDPConnection) ->
+ call(UDPConnection, get_all_opts).
+set_sock_opts(UDPConnection, Opts) ->
+ call(UDPConnection, {set_sock_opts, Opts}).
+
+%%%===================================================================
+%%% gen_server callbacks
+%%%===================================================================
+
+init([Port, EmOpts, InetOptions, DTLSOptions]) ->
+ try
+ {ok, Socket} = gen_udp:open(Port, InetOptions),
+ {ok, #state{port = Port,
+ first = true,
+ dtls_options = DTLSOptions,
+ emulated_options = EmOpts,
+ listner = Socket,
+ close = false}}
+ catch _:_ ->
+ {error, closed}
+ end.
+handle_call({accept, _}, _, #state{close = true} = State) ->
+ {reply, {error, closed}, State};
+
+handle_call({accept, Accepter}, From, #state{first = true,
+ accepters = Accepters,
+ listner = Socket} = State0) ->
+ next_datagram(Socket),
+ State = State0#state{first = false,
+ accepters = queue:in({Accepter, From}, Accepters)},
+ {noreply, State};
+
+handle_call({accept, Accepter}, From, #state{accepters = Accepters} = State0) ->
+ State = State0#state{accepters = queue:in({Accepter, From}, Accepters)},
+ {noreply, State};
+handle_call(sockname, _, #state{listner = Socket} = State) ->
+ Reply = inet:sockname(Socket),
+ {reply, Reply, State};
+handle_call(close, _, #state{dtls_processes = Processes,
+ accepters = Accepters} = State) ->
+ case kv_empty(Processes) of
+ true ->
+ {stop, normal, ok, State#state{close=true}};
+ false ->
+ lists:foreach(fun({_, From}) ->
+ gen_server:reply(From, {error, closed})
+ end, queue:to_list(Accepters)),
+ {reply, ok, State#state{close = true, accepters = queue:new()}}
+ end;
+handle_call({get_sock_opts, {SocketOptNames, EmOptNames}}, _, #state{listner = Socket,
+ emulated_options = EmOpts} = State) ->
+ case get_socket_opts(Socket, SocketOptNames) of
+ {ok, Opts} ->
+ {reply, {ok, emulated_opts_list(EmOpts, EmOptNames, []) ++ Opts}, State};
+ {error, Reason} ->
+ {reply, {error, Reason}, State}
+ end;
+handle_call(get_all_opts, _, #state{dtls_options = DTLSOptions,
+ emulated_options = EmOpts} = State) ->
+ {reply, {ok, EmOpts, DTLSOptions}, State};
+handle_call({set_sock_opts, {SocketOpts, NewEmOpts}}, _, #state{listner = Socket, emulated_options = EmOpts0} = State) ->
+ set_socket_opts(Socket, SocketOpts),
+ EmOpts = do_set_emulated_opts(NewEmOpts, EmOpts0),
+ {reply, ok, State#state{emulated_options = EmOpts}}.
+
+handle_cast({active_once, Client, Pid}, State0) ->
+ State = handle_active_once(Client, Pid, State0),
+ {noreply, State}.
+
+handle_info({udp, Socket, IP, InPortNo, _} = Msg, #state{listner = Socket} = State0) ->
+ State = handle_datagram({IP, InPortNo}, Msg, State0),
+ next_datagram(Socket),
+ {noreply, State};
+
+%% UDP socket does not have a connection and should not receive an econnreset
+%% This does however happens on on some windows versions. Just ignoring it
+%% appears to make things work as expected!
+handle_info({udp_error, Socket, econnreset = Error}, #state{listner = Socket} = State) ->
+ Report = io_lib:format("Ignore SSL UDP Listener: Socket error: ~p ~n", [Error]),
+ error_logger:info_report(Report),
+ {noreply, State};
+handle_info({udp_error, Socket, Error}, #state{listner = Socket} = State) ->
+ Report = io_lib:format("SSL UDP Listener shutdown: Socket error: ~p ~n", [Error]),
+ error_logger:info_report(Report),
+ {noreply, State#state{close=true}};
+
+handle_info({'DOWN', _, process, Pid, _}, #state{clients = Clients,
+ dtls_processes = Processes0,
+ close = ListenClosed} = State) ->
+ Client = kv_get(Pid, Processes0),
+ Processes = kv_delete(Pid, Processes0),
+ case ListenClosed andalso kv_empty(Processes) of
+ true ->
+ {stop, normal, State};
+ false ->
+ {noreply, State#state{clients = set_delete(Client, Clients),
+ dtls_processes = Processes}}
+ end.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%%===================================================================
+%%% Internal functions
+%%%===================================================================
+handle_datagram(Client, Msg, #state{clients = Clients,
+ accepters = AcceptorsQueue0} = State) ->
+ case set_is_member(Client, Clients) of
+ false ->
+ case queue:out(AcceptorsQueue0) of
+ {{value, {UserPid, From}}, AcceptorsQueue} ->
+ setup_new_connection(UserPid, From, Client, Msg,
+ State#state{accepters = AcceptorsQueue});
+ {empty, _} ->
+ %% Drop packet client will resend
+ State
+ end;
+ true ->
+ dispatch(Client, Msg, State)
+ end.
+
+dispatch(Client, Msg, #state{dtls_msq_queues = MsgQueues} = State) ->
+ case kv_lookup(Client, MsgQueues) of
+ {value, Queue0} ->
+ case queue:out(Queue0) of
+ {{value, Pid}, Queue} when is_pid(Pid) ->
+ Pid ! Msg,
+ State#state{dtls_msq_queues =
+ kv_update(Client, Queue, MsgQueues)};
+ {{value, _}, Queue} ->
+ State#state{dtls_msq_queues =
+ kv_update(Client, queue:in(Msg, Queue), MsgQueues)};
+ {empty, Queue} ->
+ State#state{dtls_msq_queues =
+ kv_update(Client, queue:in(Msg, Queue), MsgQueues)}
+ end
+ end.
+next_datagram(Socket) ->
+ inet:setopts(Socket, [{active, once}]).
+
+handle_active_once(Client, Pid, #state{dtls_msq_queues = MsgQueues} = State0) ->
+ Queue0 = kv_get(Client, MsgQueues),
+ case queue:out(Queue0) of
+ {{value, Pid}, _} when is_pid(Pid) ->
+ State0;
+ {{value, Msg}, Queue} ->
+ Pid ! Msg,
+ State0#state{dtls_msq_queues = kv_update(Client, Queue, MsgQueues)};
+ {empty, Queue0} ->
+ State0#state{dtls_msq_queues = kv_update(Client, queue:in(Pid, Queue0), MsgQueues)}
+ end.
+
+setup_new_connection(User, From, Client, Msg, #state{dtls_processes = Processes,
+ clients = Clients,
+ dtls_msq_queues = MsgQueues,
+ dtls_options = DTLSOpts,
+ port = Port,
+ listner = Socket,
+ emulated_options = EmOpts} = State) ->
+ ConnArgs = [server, "localhost", Port, {self(), {Client, Socket}},
+ {DTLSOpts, EmOpts, udp_listner}, User, dtls_socket:default_cb_info()],
+ case dtls_connection_sup:start_child(ConnArgs) of
+ {ok, Pid} ->
+ erlang:monitor(process, Pid),
+ gen_server:reply(From, {ok, Pid, {Client, Socket}}),
+ Pid ! Msg,
+ State#state{clients = set_insert(Client, Clients),
+ dtls_msq_queues = kv_insert(Client, queue:new(), MsgQueues),
+ dtls_processes = kv_insert(Pid, Client, Processes)};
+ {error, Reason} ->
+ gen_server:reply(From, {error, Reason}),
+ State
+ end.
+
+kv_update(Key, Value, Store) ->
+ gb_trees:update(Key, Value, Store).
+kv_lookup(Key, Store) ->
+ gb_trees:lookup(Key, Store).
+kv_insert(Key, Value, Store) ->
+ gb_trees:insert(Key, Value, Store).
+kv_get(Key, Store) ->
+ gb_trees:get(Key, Store).
+kv_delete(Key, Store) ->
+ gb_trees:delete(Key, Store).
+kv_new() ->
+ gb_trees:empty().
+kv_empty(Store) ->
+ gb_trees:is_empty(Store).
+
+set_new() ->
+ gb_sets:empty().
+set_insert(Item, Set) ->
+ gb_sets:insert(Item, Set).
+set_delete(Item, Set) ->
+ gb_sets:delete(Item, Set).
+set_is_member(Item, Set) ->
+ gb_sets:is_member(Item, Set).
+
+call(Server, Msg) ->
+ try
+ gen_server:call(Server, Msg, infinity)
+ catch
+ exit:{noproc, _} ->
+ {error, closed};
+ exit:{normal, _} ->
+ {error, closed};
+ exit:{{shutdown, _},_} ->
+ {error, closed}
+ end.
+
+set_socket_opts(_, []) ->
+ ok;
+set_socket_opts(Socket, SocketOpts) ->
+ inet:setopts(Socket, SocketOpts).
+
+get_socket_opts(_, []) ->
+ {ok, []};
+get_socket_opts(Socket, SocketOpts) ->
+ inet:getopts(Socket, SocketOpts).
+
+do_set_emulated_opts([], Opts) ->
+ Opts;
+do_set_emulated_opts([{mode, Value} | Rest], Opts) ->
+ do_set_emulated_opts(Rest, Opts#socket_options{mode = Value});
+do_set_emulated_opts([{active, Value} | Rest], Opts) ->
+ do_set_emulated_opts(Rest, Opts#socket_options{active = Value}).
+
+emulated_opts_list(_,[], Acc) ->
+ Acc;
+emulated_opts_list( Opts, [mode | Rest], Acc) ->
+ emulated_opts_list(Opts, Rest, [{mode, Opts#socket_options.mode} | Acc]);
+emulated_opts_list(Opts, [active | Rest], Acc) ->
+ emulated_opts_list(Opts, Rest, [{active, Opts#socket_options.active} | Acc]).
+
diff --git a/lib/ssl/src/dtls_udp_sup.erl b/lib/ssl/src/dtls_udp_sup.erl
new file mode 100644
index 0000000000..197882e92f
--- /dev/null
+++ b/lib/ssl/src/dtls_udp_sup.erl
@@ -0,0 +1,62 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2016-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Supervisor for a procsses dispatching upd datagrams to
+%% correct DTLS handler
+%%----------------------------------------------------------------------
+-module(dtls_udp_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+-export([start_child/1]).
+
+%% Supervisor callback
+-export([init/1]).
+
+%%%=========================================================================
+%%% API
+%%%=========================================================================
+start_link() ->
+ supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+
+start_child(Args) ->
+ supervisor:start_child(?MODULE, Args).
+
+%%%=========================================================================
+%%% Supervisor callback
+%%%=========================================================================
+init(_O) ->
+ RestartStrategy = simple_one_for_one,
+ MaxR = 0,
+ MaxT = 3600,
+
+ Name = undefined, % As simple_one_for_one is used.
+ StartFunc = {dtls_udp_listener, start_link, []},
+ Restart = temporary, % E.g. should not be restarted
+ Shutdown = 4000,
+ Modules = [dtls_udp_listener],
+ Type = worker,
+
+ ChildSpec = {Name, StartFunc, Restart, Shutdown, Type, Modules},
+ {ok, {{RestartStrategy, MaxR, MaxT}, [ChildSpec]}}.
diff --git a/lib/ssl/src/dtls_v1.erl b/lib/ssl/src/dtls_v1.erl
index 8c03bda513..51ee8ec047 100644
--- a/lib/ssl/src/dtls_v1.erl
+++ b/lib/ssl/src/dtls_v1.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,16 +21,27 @@
-include("ssl_cipher.hrl").
--export([suites/1, mac_hash/7, ecc_curves/1, corresponding_tls_version/1]).
+-export([suites/1, all_suites/1, hmac_hash/3, ecc_curves/1,
+ corresponding_tls_version/1, corresponding_dtls_version/1,
+ cookie_secret/0, cookie_timeout/0]).
+
+-define(COOKIE_BASE_TIMEOUT, 30000).
-spec suites(Minor:: 253|255) -> [ssl_cipher:cipher_suite()].
suites(Minor) ->
- tls_v1:suites(corresponding_minor_tls_version(Minor)).
+ lists:filter(fun(Cipher) ->
+ is_acceptable_cipher(ssl_cipher:suite_definition(Cipher))
+ end,
+ tls_v1:suites(corresponding_minor_tls_version(Minor))).
+all_suites(Version) ->
+ lists:filter(fun(Cipher) ->
+ is_acceptable_cipher(ssl_cipher:suite_definition(Cipher))
+ end,
+ ssl_cipher:all_suites(corresponding_tls_version(Version))).
-mac_hash(Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) ->
- tls_v1:mac_hash(MacAlg, MacSecret, SeqNo, Type, corresponding_tls_version(Version),
- Length, Fragment).
+hmac_hash(MacAlg, MacSecret, Value) ->
+ tls_v1:hmac_hash(MacAlg, MacSecret, Value).
ecc_curves({_Major, Minor}) ->
tls_v1:ecc_curves(corresponding_minor_tls_version(Minor)).
@@ -38,7 +49,24 @@ ecc_curves({_Major, Minor}) ->
corresponding_tls_version({254, Minor}) ->
{3, corresponding_minor_tls_version(Minor)}.
+cookie_secret() ->
+ crypto:strong_rand_bytes(32).
+
+cookie_timeout() ->
+ %% Cookie will live for two timeouts periods
+ round(rand:uniform() * ?COOKIE_BASE_TIMEOUT/2).
+
corresponding_minor_tls_version(255) ->
2;
corresponding_minor_tls_version(253) ->
3.
+
+corresponding_dtls_version({3, Minor}) ->
+ {254, corresponding_minor_dtls_version(Minor)}.
+
+corresponding_minor_dtls_version(2) ->
+ 255;
+corresponding_minor_dtls_version(3) ->
+ 253.
+is_acceptable_cipher(Suite) ->
+ not ssl_cipher:is_stream_ciphersuite(Suite).
diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src
index b26efbd88f..064dcd6892 100644
--- a/lib/ssl/src/ssl.app.src
+++ b/lib/ssl/src/ssl.app.src
@@ -6,14 +6,20 @@
tls_connection,
tls_handshake,
tls_record,
+ tls_socket,
tls_v1,
ssl_v3,
ssl_v2,
+ tls_connection_sup,
%% DTLS
dtls_connection,
dtls_handshake,
dtls_record,
+ dtls_socket,
dtls_v1,
+ dtls_connection_sup,
+ dtls_udp_listener,
+ dtls_udp_sup,
%% API
ssl, %% Main API
tls, %% TLS specific
@@ -27,17 +33,19 @@
ssl_cipher,
ssl_srp_primes,
ssl_alert,
- ssl_socket,
- ssl_listen_tracker_sup,
+ ssl_listen_tracker_sup, %% may be used by DTLS over SCTP
%% Erlang Distribution over SSL/TLS
inet_tls_dist,
inet6_tls_dist,
ssl_tls_dist_proxy,
ssl_dist_sup,
- %% SSL/TLS session handling
+ ssl_dist_connection_sup,
+ ssl_dist_admin_sup,
+ %% SSL/TLS session and cert handling
ssl_session,
ssl_session_cache,
ssl_manager,
+ ssl_pem_cache,
ssl_pkix_db,
ssl_certificate,
%% CRL handling
@@ -48,14 +56,14 @@
%% App structure
ssl_app,
ssl_sup,
- tls_connection_sup,
- dtls_connection_sup
+ ssl_admin_sup,
+ ssl_connection_sup
]},
{registered, [ssl_sup, ssl_manager]},
{applications, [crypto, public_key, kernel, stdlib]},
{env, []},
{mod, {ssl_app, []}},
- {runtime_dependencies, ["stdlib-3.0","public_key-1.2","kernel-3.0",
+ {runtime_dependencies, ["stdlib-3.2","public_key-1.2","kernel-3.0",
"erts-7.0","crypto-3.3", "inets-5.10.7"]}]}.
diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src
index 11728128c4..bfdd0c205b 100644
--- a/lib/ssl/src/ssl.appup.src
+++ b/lib/ssl/src/ssl.appup.src
@@ -1,6 +1,7 @@
%% -*- erlang -*-
{"%VSN%",
[
+ {<<"8\\..*">>, [{restart_application, ssl}]},
{<<"7\\..*">>, [{restart_application, ssl}]},
{<<"6\\..*">>, [{restart_application, ssl}]},
{<<"5\\..*">>, [{restart_application, ssl}]},
@@ -8,6 +9,7 @@
{<<"3\\..*">>, [{restart_application, ssl}]}
],
[
+ {<<"8\\..*">>, [{restart_application, ssl}]},
{<<"7\\..*">>, [{restart_application, ssl}]},
{<<"6\\..*">>, [{restart_application, ssl}]},
{<<"5\\..*">>, [{restart_application, ssl}]},
@@ -15,4 +17,3 @@
{<<"3\\..*">>, [{restart_application, ssl}]}
]
}.
-
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index d2aeb3258f..75eb308ba5 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -38,15 +38,12 @@
getopts/2, setopts/2, getstat/1, getstat/2
]).
%% SSL/TLS protocol handling
--export([cipher_suites/0, cipher_suites/1,
- connection_info/1, versions/0, session_info/1, format_error/1,
- renegotiate/1, prf/5, negotiated_protocol/1, negotiated_next_protocol/1,
+
+-export([cipher_suites/0, cipher_suites/1, eccs/0, eccs/1, versions/0,
+ format_error/1, renegotiate/1, prf/5, negotiated_protocol/1,
connection_information/1, connection_information/2]).
%% Misc
--export([handle_options/2]).
-
--deprecated({negotiated_next_protocol, 1, next_major_release}).
--deprecated({connection_info, 1, next_major_release}).
+-export([handle_options/2, tls_version/1]).
-include("ssl_api.hrl").
-include("ssl_internal.hrl").
@@ -101,33 +98,27 @@ connect(Socket, SslOptions0, Timeout) when is_port(Socket),
(is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
{Transport,_,_,_} = proplists:get_value(cb_info, SslOptions0,
{gen_tcp, tcp, tcp_closed, tcp_error}),
- EmulatedOptions = ssl_socket:emulated_options(),
- {ok, SocketValues} = ssl_socket:getopts(Transport, Socket, EmulatedOptions),
+ EmulatedOptions = tls_socket:emulated_options(),
+ {ok, SocketValues} = tls_socket:getopts(Transport, Socket, EmulatedOptions),
try handle_options(SslOptions0 ++ SocketValues, client) of
- {ok, #config{transport_info = CbInfo, ssl = SslOptions, emulated = EmOpts,
- connection_cb = ConnectionCb}} ->
-
- ok = ssl_socket:setopts(Transport, Socket, ssl_socket:internal_inet_values()),
- case ssl_socket:peername(Transport, Socket) of
- {ok, {Address, Port}} ->
- ssl_connection:connect(ConnectionCb, Address, Port, Socket,
- {SslOptions, emulated_socket_options(EmOpts, #socket_options{}), undefined},
- self(), CbInfo, Timeout);
- {error, Error} ->
- {error, Error}
- end
+ {ok, Config} ->
+ tls_socket:upgrade(Socket, Config, Timeout)
catch
_:{error, Reason} ->
{error, Reason}
end;
-
connect(Host, Port, Options) ->
connect(Host, Port, Options, infinity).
connect(Host, Port, Options, Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
- try handle_options(Options, client) of
- {ok, Config} ->
- do_connect(Host,Port,Config,Timeout)
+ try
+ {ok, Config} = handle_options(Options, client, Host),
+ case Config#config.connection_cb of
+ tls_connection ->
+ tls_socket:connect(Host,Port,Config,Timeout);
+ dtls_connection ->
+ dtls_socket:connect(Host,Port,Config,Timeout)
+ end
catch
throw:Error ->
Error
@@ -144,17 +135,7 @@ listen(_Port, []) ->
listen(Port, Options0) ->
try
{ok, Config} = handle_options(Options0, server),
- ConnectionCb = connection_cb(Options0),
- #config{transport_info = {Transport, _, _, _}, inet_user = Options, connection_cb = ConnectionCb,
- ssl = SslOpts, emulated = EmOpts} = Config,
- case Transport:listen(Port, Options) of
- {ok, ListenSocket} ->
- ok = ssl_socket:setopts(Transport, ListenSocket, ssl_socket:internal_inet_values()),
- {ok, Tracker} = ssl_socket:inherit_tracker(ListenSocket, EmOpts, SslOpts),
- {ok, #sslsocket{pid = {ListenSocket, Config#config{emulated = Tracker}}}};
- Err = {error, _} ->
- Err
- end
+ do_listen(Port, Config, connection_cb(Options0))
catch
Error = {error, _} ->
Error
@@ -171,27 +152,15 @@ transport_accept(ListenSocket) ->
transport_accept(ListenSocket, infinity).
transport_accept(#sslsocket{pid = {ListenSocket,
- #config{transport_info = {Transport,_,_, _} =CbInfo,
- connection_cb = ConnectionCb,
- ssl = SslOpts,
- emulated = Tracker}}}, Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
- case Transport:accept(ListenSocket, Timeout) of
- {ok, Socket} ->
- {ok, EmOpts} = ssl_socket:get_emulated_opts(Tracker),
- {ok, Port} = ssl_socket:port(Transport, Socket),
- ConnArgs = [server, "localhost", Port, Socket,
- {SslOpts, emulated_socket_options(EmOpts, #socket_options{}), Tracker}, self(), CbInfo],
- ConnectionSup = connection_sup(ConnectionCb),
- case ConnectionSup:start_child(ConnArgs) of
- {ok, Pid} ->
- ssl_connection:socket_control(ConnectionCb, Socket, Pid, Transport, Tracker);
- {error, Reason} ->
- {error, Reason}
- end;
- {error, Reason} ->
- {error, Reason}
+ #config{connection_cb = ConnectionCb} = Config}}, Timeout)
+ when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
+ case ConnectionCb of
+ tls_connection ->
+ tls_socket:accept(ListenSocket, Config, Timeout);
+ dtls_connection ->
+ dtls_socket:accept(ListenSocket, Config, Timeout)
end.
-
+
%%--------------------------------------------------------------------
-spec ssl_accept(#sslsocket{}) -> ok | {error, reason()}.
-spec ssl_accept(#sslsocket{} | port(), timeout()| [ssl_option()
@@ -214,13 +183,22 @@ ssl_accept(ListenSocket, SslOptions) when is_port(ListenSocket) ->
ssl_accept(ListenSocket, SslOptions, infinity).
ssl_accept(#sslsocket{} = Socket, [], Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity)->
- ssl_accept(#sslsocket{} = Socket, Timeout);
-ssl_accept(#sslsocket{fd = {_, _, _, Tracker}} = Socket, SslOpts0, Timeout) when
+ ssl_accept(Socket, Timeout);
+ssl_accept(#sslsocket{fd = {_, _, _, Tracker}} = Socket, SslOpts, Timeout) when
+ (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity)->
+ try
+ {ok, EmOpts, _} = tls_socket:get_all_opts(Tracker),
+ ssl_connection:handshake(Socket, {SslOpts,
+ tls_socket:emulated_socket_options(EmOpts, #socket_options{})}, Timeout)
+ catch
+ Error = {error, _Reason} -> Error
+ end;
+ssl_accept(#sslsocket{pid = Pid, fd = {_, _, _}} = Socket, SslOpts, Timeout) when
(is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity)->
try
- {ok, EmOpts, InheritedSslOpts} = ssl_socket:get_all_opts(Tracker),
- SslOpts = handle_options(SslOpts0, InheritedSslOpts),
- ssl_connection:handshake(Socket, {SslOpts, emulated_socket_options(EmOpts, #socket_options{})}, Timeout)
+ {ok, EmOpts, _} = dtls_udp_listener:get_all_opts(Pid),
+ ssl_connection:handshake(Socket, {SslOpts,
+ tls_socket:emulated_socket_options(EmOpts, #socket_options{})}, Timeout)
catch
Error = {error, _Reason} -> Error
end;
@@ -228,20 +206,20 @@ ssl_accept(Socket, SslOptions, Timeout) when is_port(Socket),
(is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) ->
{Transport,_,_,_} =
proplists:get_value(cb_info, SslOptions, {gen_tcp, tcp, tcp_closed, tcp_error}),
- EmulatedOptions = ssl_socket:emulated_options(),
- {ok, SocketValues} = ssl_socket:getopts(Transport, Socket, EmulatedOptions),
+ EmulatedOptions = tls_socket:emulated_options(),
+ {ok, SocketValues} = tls_socket:getopts(Transport, Socket, EmulatedOptions),
ConnetionCb = connection_cb(SslOptions),
try handle_options(SslOptions ++ SocketValues, server) of
{ok, #config{transport_info = CbInfo, ssl = SslOpts, emulated = EmOpts}} ->
- ok = ssl_socket:setopts(Transport, Socket, ssl_socket:internal_inet_values()),
- {ok, Port} = ssl_socket:port(Transport, Socket),
+ ok = tls_socket:setopts(Transport, Socket, tls_socket:internal_inet_values()),
+ {ok, Port} = tls_socket:port(Transport, Socket),
ssl_connection:ssl_accept(ConnetionCb, Port, Socket,
- {SslOpts, emulated_socket_options(EmOpts, #socket_options{}), undefined},
+ {SslOpts,
+ tls_socket:emulated_socket_options(EmOpts, #socket_options{}), undefined},
self(), CbInfo, Timeout)
catch
Error = {error, _Reason} -> Error
end.
-
%%--------------------------------------------------------------------
-spec close(#sslsocket{}) -> term().
%%
@@ -249,6 +227,8 @@ ssl_accept(Socket, SslOptions, Timeout) when is_port(Socket),
%%--------------------------------------------------------------------
close(#sslsocket{pid = Pid}) when is_pid(Pid) ->
ssl_connection:close(Pid, {close, ?DEFAULT_TIMEOUT});
+close(#sslsocket{pid = {udp, #config{udp_handler = {Pid, _}}}}) ->
+ dtls_udp_listener:close(Pid);
close(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport,_, _, _}}}}) ->
Transport:close(ListenSocket).
@@ -275,6 +255,10 @@ close(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport,_, _, _}
%%--------------------------------------------------------------------
send(#sslsocket{pid = Pid}, Data) when is_pid(Pid) ->
ssl_connection:send(Pid, Data);
+send(#sslsocket{pid = {_, #config{transport_info={gen_udp, _, _, _}}}}, _) ->
+ {error,enotconn}; %% Emulate connection behaviour
+send(#sslsocket{pid = {udp,_}}, _) ->
+ {error,enotconn};
send(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport, _, _, _}}}}, Data) ->
Transport:send(ListenSocket, Data). %% {error,enotconn}
@@ -289,6 +273,8 @@ recv(Socket, Length) ->
recv(#sslsocket{pid = Pid}, Length, Timeout) when is_pid(Pid),
(is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity)->
ssl_connection:recv(Pid, Length, Timeout);
+recv(#sslsocket{pid = {udp,_}}, _, _) ->
+ {error,enotconn};
recv(#sslsocket{pid = {Listen,
#config{transport_info = {Transport, _, _, _}}}}, _,_) when is_port(Listen)->
Transport:recv(Listen, 0). %% {error,enotconn}
@@ -301,10 +287,14 @@ recv(#sslsocket{pid = {Listen,
%%--------------------------------------------------------------------
controlling_process(#sslsocket{pid = Pid}, NewOwner) when is_pid(Pid), is_pid(NewOwner) ->
ssl_connection:new_user(Pid, NewOwner);
+controlling_process(#sslsocket{pid = {udp, _}},
+ NewOwner) when is_pid(NewOwner) ->
+ ok; %% Meaningless but let it be allowed to conform with TLS
controlling_process(#sslsocket{pid = {Listen,
#config{transport_info = {Transport, _, _, _}}}},
NewOwner) when is_port(Listen),
is_pid(NewOwner) ->
+ %% Meaningless but let it be allowed to conform with normal sockets
Transport:controlling_process(Listen, NewOwner).
@@ -314,22 +304,24 @@ controlling_process(#sslsocket{pid = {Listen,
%% Description: Return SSL information for the connection
%%--------------------------------------------------------------------
connection_information(#sslsocket{pid = Pid}) when is_pid(Pid) ->
- case ssl_connection:connection_information(Pid) of
+ case ssl_connection:connection_information(Pid, false) of
{ok, Info} ->
{ok, [Item || Item = {_Key, Value} <- Info, Value =/= undefined]};
Error ->
Error
end;
connection_information(#sslsocket{pid = {Listen, _}}) when is_port(Listen) ->
- {error, enotconn}.
+ {error, enotconn};
+connection_information(#sslsocket{pid = {udp,_}}) ->
+ {error,enotconn}.
%%--------------------------------------------------------------------
-spec connection_information(#sslsocket{}, [atom()]) -> {ok, list()} | {error, reason()}.
%%
%% Description: Return SSL information for the connection
%%--------------------------------------------------------------------
-connection_information(#sslsocket{} = SSLSocket, Items) ->
- case connection_information(SSLSocket) of
+connection_information(#sslsocket{pid = Pid}, Items) when is_pid(Pid) ->
+ case ssl_connection:connection_information(Pid, include_security_info(Items)) of
{ok, Info} ->
{ok, [Item || Item = {Key, Value} <- Info, lists:member(Key, Items),
Value =/= undefined]};
@@ -338,29 +330,22 @@ connection_information(#sslsocket{} = SSLSocket, Items) ->
end.
%%--------------------------------------------------------------------
-%% Deprecated
--spec connection_info(#sslsocket{}) -> {ok, {tls_record:tls_atom_version(), ssl_cipher:erl_cipher_suite()}} |
- {error, reason()}.
-%%
-%% Description: Returns ssl protocol and cipher used for the connection
-%%--------------------------------------------------------------------
-connection_info(#sslsocket{} = SSLSocket) ->
- case connection_information(SSLSocket) of
- {ok, Result} ->
- {ok, {proplists:get_value(protocol, Result), proplists:get_value(cipher_suite, Result)}};
- Error ->
- Error
- end.
-
-%%--------------------------------------------------------------------
-spec peername(#sslsocket{}) -> {ok, {inet:ip_address(), inet:port_number()}} | {error, reason()}.
%%
%% Description: same as inet:peername/1.
%%--------------------------------------------------------------------
+peername(#sslsocket{pid = Pid, fd = {Transport, Socket, _}}) when is_pid(Pid)->
+ dtls_socket:peername(Transport, Socket);
peername(#sslsocket{pid = Pid, fd = {Transport, Socket, _, _}}) when is_pid(Pid)->
- ssl_socket:peername(Transport, Socket);
+ tls_socket:peername(Transport, Socket);
+peername(#sslsocket{pid = {udp = Transport, #config{udp_handler = {_Pid, _}}}}) ->
+ dtls_socket:peername(Transport, undefined);
+peername(#sslsocket{pid = Pid, fd = {gen_udp= Transport, Socket, _, _}}) when is_pid(Pid) ->
+ dtls_socket:peername(Transport, Socket);
peername(#sslsocket{pid = {ListenSocket, #config{transport_info = {Transport,_,_,_}}}}) ->
- ssl_socket:peername(Transport, ListenSocket). %% Will return {error, enotconn}
+ tls_socket:peername(Transport, ListenSocket); %% Will return {error, enotconn}
+peername(#sslsocket{pid = {udp,_}}) ->
+ {error,enotconn}.
%%--------------------------------------------------------------------
-spec peercert(#sslsocket{}) ->{ok, DerCert::binary()} | {error, reason()}.
@@ -374,6 +359,8 @@ peercert(#sslsocket{pid = Pid}) when is_pid(Pid) ->
Result ->
Result
end;
+peercert(#sslsocket{pid = {udp, _}}) ->
+ {error, enotconn};
peercert(#sslsocket{pid = {Listen, _}}) when is_port(Listen) ->
{error, enotconn}.
@@ -387,20 +374,6 @@ negotiated_protocol(#sslsocket{pid = Pid}) ->
ssl_connection:negotiated_protocol(Pid).
%%--------------------------------------------------------------------
--spec negotiated_next_protocol(#sslsocket{}) -> {ok, binary()} | {error, reason()}.
-%%
-%% Description: Returns the next protocol that has been negotiated. If no
-%% protocol has been negotiated will return {error, next_protocol_not_negotiated}
-%%--------------------------------------------------------------------
-negotiated_next_protocol(Socket) ->
- case negotiated_protocol(Socket) of
- {error, protocol_not_negotiated} ->
- {error, next_protocol_not_negotiated};
- Res ->
- Res
- end.
-
-%%--------------------------------------------------------------------
-spec cipher_suites() -> [ssl_cipher:erl_cipher_suite()] | [string()].
%%--------------------------------------------------------------------
cipher_suites() ->
@@ -420,6 +393,33 @@ cipher_suites(all) ->
[ssl_cipher:erl_suite_definition(Suite) || Suite <- available_suites(all)].
%%--------------------------------------------------------------------
+-spec eccs() -> tls_v1:curves().
+%% Description: returns all supported curves across all versions
+%%--------------------------------------------------------------------
+eccs() ->
+ Curves = tls_v1:ecc_curves(all), % only tls_v1 has named curves right now
+ eccs_filter_supported(Curves).
+
+%%--------------------------------------------------------------------
+-spec eccs(tls_record:tls_version() | tls_record:tls_atom_version()) ->
+ tls_v1:curves().
+%% Description: returns the curves supported for a given version of
+%% ssl/tls.
+%%--------------------------------------------------------------------
+eccs({3,0}) ->
+ [];
+eccs({3,_}) ->
+ Curves = tls_v1:ecc_curves(all),
+ eccs_filter_supported(Curves);
+eccs(AtomVersion) when is_atom(AtomVersion) ->
+ eccs(tls_record:protocol_version(AtomVersion)).
+
+eccs_filter_supported(Curves) ->
+ CryptoCurves = crypto:ec_curves(),
+ lists:filter(fun(Curve) -> proplists:get_bool(Curve, CryptoCurves) end,
+ Curves).
+
+%%--------------------------------------------------------------------
-spec getopts(#sslsocket{}, [gen_tcp:option_name()]) ->
{ok, [gen_tcp:option()]} | {error, reason()}.
%%
@@ -427,9 +427,19 @@ cipher_suites(all) ->
%%--------------------------------------------------------------------
getopts(#sslsocket{pid = Pid}, OptionTags) when is_pid(Pid), is_list(OptionTags) ->
ssl_connection:get_opts(Pid, OptionTags);
+getopts(#sslsocket{pid = {udp, #config{transport_info = {Transport,_,_,_}}}} = ListenSocket, OptionTags) when is_list(OptionTags) ->
+ try dtls_socket:getopts(Transport, ListenSocket, OptionTags) of
+ {ok, _} = Result ->
+ Result;
+ {error, InetError} ->
+ {error, {options, {socket_options, OptionTags, InetError}}}
+ catch
+ _:Error ->
+ {error, {options, {socket_options, OptionTags, Error}}}
+ end;
getopts(#sslsocket{pid = {_, #config{transport_info = {Transport,_,_,_}}}} = ListenSocket,
OptionTags) when is_list(OptionTags) ->
- try ssl_socket:getopts(Transport, ListenSocket, OptionTags) of
+ try tls_socket:getopts(Transport, ListenSocket, OptionTags) of
{ok, _} = Result ->
Result;
{error, InetError} ->
@@ -455,9 +465,18 @@ setopts(#sslsocket{pid = Pid}, Options0) when is_pid(Pid), is_list(Options0) ->
_:_ ->
{error, {options, {not_a_proplist, Options0}}}
end;
-
+setopts(#sslsocket{pid = {udp, #config{transport_info = {Transport,_,_,_}}}} = ListenSocket, Options) when is_list(Options) ->
+ try dtls_socket:setopts(Transport, ListenSocket, Options) of
+ ok ->
+ ok;
+ {error, InetError} ->
+ {error, {options, {socket_options, Options, InetError}}}
+ catch
+ _:Error ->
+ {error, {options, {socket_options, Options, Error}}}
+ end;
setopts(#sslsocket{pid = {_, #config{transport_info = {Transport,_,_,_}}}} = ListenSocket, Options) when is_list(Options) ->
- try ssl_socket:setopts(Transport, ListenSocket, Options) of
+ try tls_socket:setopts(Transport, ListenSocket, Options) of
ok ->
ok;
{error, InetError} ->
@@ -490,10 +509,10 @@ getstat(Socket) ->
%% Description: Get one or more statistic options for a socket.
%%--------------------------------------------------------------------
getstat(#sslsocket{pid = {Listen, #config{transport_info = {Transport, _, _, _}}}}, Options) when is_port(Listen), is_list(Options) ->
- ssl_socket:getstat(Transport, Listen, Options);
+ tls_socket:getstat(Transport, Listen, Options);
getstat(#sslsocket{pid = Pid, fd = {Transport, Socket, _, _}}, Options) when is_pid(Pid), is_list(Options) ->
- ssl_socket:getstat(Transport, Socket, Options).
+ tls_socket:getstat(Transport, Socket, Options).
%%---------------------------------------------------------------
-spec shutdown(#sslsocket{}, read | write | read_write) -> ok | {error, reason()}.
@@ -503,6 +522,8 @@ getstat(#sslsocket{pid = Pid, fd = {Transport, Socket, _, _}}, Options) when is_
shutdown(#sslsocket{pid = {Listen, #config{transport_info = {Transport,_, _, _}}}},
How) when is_port(Listen) ->
Transport:shutdown(Listen, How);
+shutdown(#sslsocket{pid = {udp,_}},_) ->
+ {error, enotconn};
shutdown(#sslsocket{pid = Pid}, How) ->
ssl_connection:shutdown(Pid, How).
@@ -512,21 +533,13 @@ shutdown(#sslsocket{pid = Pid}, How) ->
%% Description: Same as inet:sockname/1
%%--------------------------------------------------------------------
sockname(#sslsocket{pid = {Listen, #config{transport_info = {Transport, _, _, _}}}}) when is_port(Listen) ->
- ssl_socket:sockname(Transport, Listen);
-
+ tls_socket:sockname(Transport, Listen);
+sockname(#sslsocket{pid = {udp, #config{udp_handler = {Pid, _}}}}) ->
+ dtls_udp_listener:sockname(Pid);
+sockname(#sslsocket{pid = Pid, fd = {Transport, Socket, _}}) when is_pid(Pid) ->
+ dtls_socket:sockname(Transport, Socket);
sockname(#sslsocket{pid = Pid, fd = {Transport, Socket, _, _}}) when is_pid(Pid) ->
- ssl_socket:sockname(Transport, Socket).
-
-%%---------------------------------------------------------------
--spec session_info(#sslsocket{}) -> {ok, list()} | {error, reason()}.
-%%
-%% Description: Returns list of session info currently [{session_id, session_id(),
-%% {cipher_suite, cipher_suite()}]
-%%--------------------------------------------------------------------
-session_info(#sslsocket{pid = Pid}) when is_pid(Pid) ->
- ssl_connection:session_info(Pid);
-session_info(#sslsocket{pid = {Listen,_}}) when is_port(Listen) ->
- {error, enotconn}.
+ tls_socket:sockname(Transport, Socket).
%%---------------------------------------------------------------
-spec versions() -> [{ssl_app, string()} | {supported, [tls_record:tls_atom_version()]} |
@@ -549,6 +562,8 @@ versions() ->
%%--------------------------------------------------------------------
renegotiate(#sslsocket{pid = Pid}) when is_pid(Pid) ->
ssl_connection:renegotiation(Pid);
+renegotiate(#sslsocket{pid = {udp,_}}) ->
+ {error, enotconn};
renegotiate(#sslsocket{pid = {Listen,_}}) when is_port(Listen) ->
{error, enotconn}.
@@ -562,6 +577,8 @@ renegotiate(#sslsocket{pid = {Listen,_}}) when is_port(Listen) ->
prf(#sslsocket{pid = Pid},
Secret, Label, Seed, WantedLength) when is_pid(Pid) ->
ssl_connection:prf(Pid, Secret, Label, Seed, WantedLength);
+prf(#sslsocket{pid = {udp,_}}, _,_,_,_) ->
+ {error, enotconn};
prf(#sslsocket{pid = {Listen,_}}, _,_,_,_) when is_port(Listen) ->
{error, enotconn}.
@@ -571,7 +588,7 @@ prf(#sslsocket{pid = {Listen,_}}, _,_,_,_) when is_port(Listen) ->
%% Description: Clear the PEM cache
%%--------------------------------------------------------------------
clear_pem_cache() ->
- ssl_manager:clear_pem_cache().
+ ssl_pem_cache:clear().
%%---------------------------------------------------------------
-spec format_error({error, term()}) -> list().
@@ -607,6 +624,11 @@ format_error(Error) ->
Other
end.
+tls_version({3, _} = Version) ->
+ Version;
+tls_version({254, _} = Version) ->
+ dtls_v1:corresponding_tls_version(Version).
+
%%%--------------------------------------------------------------
%%% Internal functions
%%%--------------------------------------------------------------------
@@ -620,30 +642,21 @@ available_suites(all) ->
Version = tls_record:highest_protocol_version([]),
ssl_cipher:filter_suites(ssl_cipher:all_suites(Version)).
-do_connect(Address, Port,
- #config{transport_info = CbInfo, inet_user = UserOpts, ssl = SslOpts,
- emulated = EmOpts, inet_ssl = SocketOpts, connection_cb = ConnetionCb},
- Timeout) ->
- {Transport, _, _, _} = CbInfo,
- try Transport:connect(Address, Port, SocketOpts, Timeout) of
- {ok, Socket} ->
- ssl_connection:connect(ConnetionCb, Address, Port, Socket,
- {SslOpts, emulated_socket_options(EmOpts, #socket_options{}), undefined},
- self(), CbInfo, Timeout);
- {error, Reason} ->
- {error, Reason}
- catch
- exit:{function_clause, _} ->
- {error, {options, {cb_info, CbInfo}}};
- exit:badarg ->
- {error, {options, {socket_options, UserOpts}}};
- exit:{badarg, _} ->
- {error, {options, {socket_options, UserOpts}}}
- end.
+do_listen(Port, #config{transport_info = {Transport, _, _, _}} = Config, tls_connection) ->
+ tls_socket:listen(Transport, Port, Config);
+do_listen(Port, #config{transport_info = {Transport, _, _, _}} = Config, dtls_connection) ->
+ dtls_socket:listen(Transport, Port, Config).
+
%% Handle extra ssl options given to ssl_accept
+-spec handle_options([any()], #ssl_options{}) -> #ssl_options{}
+ ; ([any()], client | server) -> {ok, #config{}}.
+handle_options(Opts, Role) ->
+ handle_options(Opts, Role, undefined).
+
+
handle_options(Opts0, #ssl_options{protocol = Protocol, cacerts = CaCerts0,
- cacertfile = CaCertFile0} = InheritedSslOpts) ->
+ cacertfile = CaCertFile0} = InheritedSslOpts, _) ->
RecordCB = record_cb(Protocol),
CaCerts = handle_option(cacerts, Opts0, CaCerts0),
{Verify, FailIfNoPeerCert, CaCertDefault, VerifyFun, PartialChainHanlder,
@@ -676,7 +689,7 @@ handle_options(Opts0, #ssl_options{protocol = Protocol, cacerts = CaCerts0,
end;
%% Handle all options in listen and connect
-handle_options(Opts0, Role) ->
+handle_options(Opts0, Role, Host) ->
Opts = proplists:expand([{binary, [{mode, binary}]},
{list, [{mode, list}]}], Opts0),
assert_proplist(Opts),
@@ -698,6 +711,8 @@ handle_options(Opts0, Role) ->
[RecordCb:protocol_version(Vsn) || Vsn <- Vsns]
end,
+ Protocol = handle_option(protocol, Opts, tls),
+
SSLOptions = #ssl_options{
versions = Versions,
verify = validate_option(verify, Verify),
@@ -720,10 +735,12 @@ handle_options(Opts0, Role) ->
srp_identity = handle_option(srp_identity, Opts, undefined),
ciphers = handle_cipher_option(proplists:get_value(ciphers, Opts, []),
RecordCb:highest_protocol_version(Versions)),
+ eccs = handle_eccs_option(proplists:get_value(eccs, Opts, eccs()),
+ RecordCb:highest_protocol_version(Versions)),
signature_algs = handle_hashsigns_option(proplists:get_value(signature_algs, Opts,
default_option_role(server,
tls_v1:default_signature_algs(Versions), Role)),
- RecordCb:highest_protocol_version(Versions)),
+ tls_version(RecordCb:highest_protocol_version(Versions))),
%% Server side option
reuse_session = handle_option(reuse_session, Opts, ReuseSessionFun),
reuse_sessions = handle_option(reuse_sessions, Opts, true),
@@ -744,13 +761,18 @@ handle_options(Opts0, Role) ->
make_next_protocol_selector(
handle_option(client_preferred_next_protocols, Opts, undefined)),
log_alert = handle_option(log_alert, Opts, true),
- server_name_indication = handle_option(server_name_indication, Opts, undefined),
+ server_name_indication = handle_option(server_name_indication, Opts,
+ default_option_role(client,
+ server_name_indication_default(Host), Role)),
sni_hosts = handle_option(sni_hosts, Opts, []),
sni_fun = handle_option(sni_fun, Opts, undefined),
honor_cipher_order = handle_option(honor_cipher_order, Opts,
default_option_role(server, false, Role),
server, Role),
- protocol = proplists:get_value(protocol, Opts, tls),
+ honor_ecc_order = handle_option(honor_ecc_order, Opts,
+ default_option_role(server, false, Role),
+ server, Role),
+ protocol = Protocol,
padding_check = proplists:get_value(padding_check, Opts, true),
beast_mitigation = handle_option(beast_mitigation, Opts, one_n_minus_one),
fallback = handle_option(fallback, Opts,
@@ -760,10 +782,11 @@ handle_options(Opts0, Role) ->
client, Role),
crl_check = handle_option(crl_check, Opts, false),
crl_cache = handle_option(crl_cache, Opts, {ssl_crl_cache, {internal, []}}),
- v2_hello_compatible = handle_option(v2_hello_compatible, Opts, false)
+ v2_hello_compatible = handle_option(v2_hello_compatible, Opts, false),
+ max_handshake_size = handle_option(max_handshake_size, Opts, ?DEFAULT_MAX_HANDSHAKE_SIZE)
},
- CbInfo = proplists:get_value(cb_info, Opts, {gen_tcp, tcp, tcp_closed, tcp_error}),
+ CbInfo = proplists:get_value(cb_info, Opts, default_cb_info(Protocol)),
SslOptions = [protocol, versions, verify, verify_fun, partial_chain,
fail_if_no_peer_cert, verify_client_once,
depth, cert, certfile, key, keyfile,
@@ -775,13 +798,14 @@ handle_options(Opts0, Role) ->
alpn_preferred_protocols, next_protocols_advertised,
client_preferred_next_protocols, log_alert,
server_name_indication, honor_cipher_order, padding_check, crl_check, crl_cache,
- fallback, signature_algs, beast_mitigation, v2_hello_compatible],
+ fallback, signature_algs, eccs, honor_ecc_order, beast_mitigation, v2_hello_compatible,
+ max_handshake_size],
SockOpts = lists:foldl(fun(Key, PropList) ->
proplists:delete(Key, PropList)
end, Opts, SslOptions),
- {Sock, Emulated} = emulated_options(SockOpts),
+ {Sock, Emulated} = emulated_options(Protocol, SockOpts),
ConnetionCb = connection_cb(Opts),
{ok, #config{ssl = SSLOptions, emulated = Emulated, inet_ssl = Sock,
@@ -983,12 +1007,20 @@ validate_option(next_protocols_advertised = Opt, Value) when is_list(Value) ->
validate_option(next_protocols_advertised, undefined) ->
undefined;
-validate_option(server_name_indication, Value) when is_list(Value) ->
+validate_option(server_name_indication = Opt, Value) when is_list(Value) ->
+ %% RFC 6066, Section 3: Currently, the only server names supported are
+ %% DNS hostnames
+ case inet_parse:domain(Value) of
+ false ->
+ throw({error, {options, {{Opt, Value}}}});
+ true ->
+ Value
+ end;
+validate_option(server_name_indication, undefined = Value) ->
Value;
validate_option(server_name_indication, disable) ->
- disable;
-validate_option(server_name_indication, undefined) ->
undefined;
+
validate_option(sni_hosts, []) ->
[];
validate_option(sni_hosts, [{Hostname, SSLOptions} | Tail]) when is_list(Hostname) ->
@@ -1005,6 +1037,8 @@ validate_option(sni_fun, Fun) when is_function(Fun) ->
Fun;
validate_option(honor_cipher_order, Value) when is_boolean(Value) ->
Value;
+validate_option(honor_ecc_order, Value) when is_boolean(Value) ->
+ Value;
validate_option(padding_check, Value) when is_boolean(Value) ->
Value;
validate_option(fallback, Value) when is_boolean(Value) ->
@@ -1021,18 +1055,24 @@ validate_option(beast_mitigation, Value) when Value == one_n_minus_one orelse
Value;
validate_option(v2_hello_compatible, Value) when is_boolean(Value) ->
Value;
+validate_option(max_handshake_size, Value) when is_integer(Value) andalso Value =< ?MAX_UNIT24 ->
+ Value;
+validate_option(protocol, Value = tls) ->
+ Value;
+validate_option(protocol, Value = dtls) ->
+ Value;
validate_option(Opt, Value) ->
throw({error, {options, {Opt, Value}}}).
-handle_hashsigns_option(Value, {Major, Minor} = Version) when is_list(Value)
- andalso Major >= 3 andalso Minor >= 3->
+handle_hashsigns_option(Value, Version) when is_list(Value)
+ andalso Version >= {3, 3} ->
case tls_v1:signature_algs(Version, Value) of
[] ->
throw({error, {options, no_supported_algorithms, {signature_algs, Value}}});
_ ->
Value
end;
-handle_hashsigns_option(_, {Major, Minor} = Version) when Major >= 3 andalso Minor >= 3->
+handle_hashsigns_option(_, Version) when Version >= {3, 3} ->
handle_hashsigns_option(tls_v1:default_signature_algs(Version), Version);
handle_hashsigns_option(_, _Version) ->
undefined.
@@ -1058,17 +1098,37 @@ validate_binary_list(Opt, List) ->
(Bin) ->
throw({error, {options, {Opt, {invalid_protocol, Bin}}}})
end, List).
-
validate_versions([], Versions) ->
Versions;
validate_versions([Version | Rest], Versions) when Version == 'tlsv1.2';
Version == 'tlsv1.1';
Version == tlsv1;
Version == sslv3 ->
- validate_versions(Rest, Versions);
+ tls_validate_versions(Rest, Versions);
+validate_versions([Version | Rest], Versions) when Version == 'dtlsv1';
+ Version == 'dtlsv1.2'->
+ dtls_validate_versions(Rest, Versions);
validate_versions([Ver| _], Versions) ->
throw({error, {options, {Ver, {versions, Versions}}}}).
+tls_validate_versions([], Versions) ->
+ Versions;
+tls_validate_versions([Version | Rest], Versions) when Version == 'tlsv1.2';
+ Version == 'tlsv1.1';
+ Version == tlsv1;
+ Version == sslv3 ->
+ tls_validate_versions(Rest, Versions);
+tls_validate_versions([Ver| _], Versions) ->
+ throw({error, {options, {Ver, {versions, Versions}}}}).
+
+dtls_validate_versions([], Versions) ->
+ Versions;
+dtls_validate_versions([Version | Rest], Versions) when Version == 'dtlsv1';
+ Version == 'dtlsv1.2'->
+ dtls_validate_versions(Rest, Versions);
+dtls_validate_versions([Ver| _], Versions) ->
+ throw({error, {options, {Ver, {versions, Versions}}}}).
+
validate_inet_option(mode, Value)
when Value =/= list, Value =/= binary ->
throw({error, {options, {mode,Value}}});
@@ -1098,8 +1158,13 @@ ca_cert_default(verify_peer, {Fun,_}, _) when is_function(Fun) ->
%% some trusted certs.
ca_cert_default(verify_peer, undefined, _) ->
"".
-emulated_options(Opts) ->
- emulated_options(Opts, ssl_socket:internal_inet_values(), ssl_socket:default_inet_values()).
+emulated_options(Protocol, Opts) ->
+ case Protocol of
+ tls ->
+ emulated_options(Opts, tls_socket:internal_inet_values(), tls_socket:default_inet_values());
+ dtls ->
+ emulated_options(Opts, dtls_socket:internal_inet_values(), dtls_socket:default_inet_values())
+ end.
emulated_options([{mode, Value} = Opt |Opts], Inet, Emulated) ->
validate_inet_option(mode, Value),
@@ -1135,18 +1200,18 @@ handle_cipher_option(Value, Version) when is_list(Value) ->
binary_cipher_suites(Version, []) ->
%% Defaults to all supported suites that does
%% not require explicit configuration
- ssl_cipher:filter_suites(ssl_cipher:suites(Version));
+ ssl_cipher:filter_suites(ssl_cipher:suites(tls_version(Version)));
binary_cipher_suites(Version, [Tuple|_] = Ciphers0) when is_tuple(Tuple) ->
Ciphers = [ssl_cipher:suite(C) || C <- Ciphers0],
binary_cipher_suites(Version, Ciphers);
binary_cipher_suites(Version, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) ->
- All = ssl_cipher:all_suites(Version),
+ All = ssl_cipher:all_suites(tls_version(Version)),
case [Cipher || Cipher <- Ciphers0, lists:member(Cipher, All)] of
[] ->
%% Defaults to all supported suites that does
%% not require explicit configuration
- ssl_cipher:filter_suites(ssl_cipher:suites(Version));
+ ssl_cipher:filter_suites(ssl_cipher:suites(tls_version(Version)));
Ciphers ->
Ciphers
end;
@@ -1159,6 +1224,15 @@ binary_cipher_suites(Version, Ciphers0) ->
Ciphers = [ssl_cipher:openssl_suite(C) || C <- string:tokens(Ciphers0, ":")],
binary_cipher_suites(Version, Ciphers).
+handle_eccs_option(Value, Version) when is_list(Value) ->
+ {_Major, Minor} = tls_version(Version),
+ try tls_v1:ecc_curves(Minor, Value) of
+ Curves -> #elliptic_curves{elliptic_curve_list = Curves}
+ catch
+ exit:_ -> throw({error, {options, {eccs, Value}}});
+ error:_ -> throw({error, {options, {eccs, Value}}})
+ end.
+
unexpected_format(Error) ->
lists:flatten(io_lib:format("Unexpected error: ~p", [Error])).
@@ -1232,11 +1306,6 @@ record_cb(dtls) ->
record_cb(Opts) ->
record_cb(proplists:get_value(protocol, Opts, tls)).
-connection_sup(tls_connection) ->
- tls_connection_sup;
-connection_sup(dtls_connection) ->
- dtls_connection_sup.
-
binary_filename(FileName) ->
Enc = file:native_name_encoding(),
unicode:characters_to_binary(FileName, unicode, Enc).
@@ -1255,20 +1324,6 @@ assert_proplist([inet6 | Rest]) ->
assert_proplist([Value | _]) ->
throw({option_not_a_key_value_tuple, Value}).
-emulated_socket_options(InetValues, #socket_options{
- mode = Mode,
- header = Header,
- active = Active,
- packet = Packet,
- packet_size = Size}) ->
- #socket_options{
- mode = proplists:get_value(mode, InetValues, Mode),
- header = proplists:get_value(header, InetValues, Header),
- active = proplists:get_value(active, InetValues, Active),
- packet = proplists:get_value(packet, InetValues, Packet),
- packet_size = proplists:get_value(packet_size, InetValues, Size)
- }.
-
new_ssl_options([], #ssl_options{} = Opts, _) ->
Opts;
new_ssl_options([{verify_client_once, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
@@ -1329,13 +1384,24 @@ new_ssl_options([{server_name_indication, Value} | Rest], #ssl_options{} = Opts,
new_ssl_options(Rest, Opts#ssl_options{server_name_indication = validate_option(server_name_indication, Value)}, RecordCB);
new_ssl_options([{honor_cipher_order, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
new_ssl_options(Rest, Opts#ssl_options{honor_cipher_order = validate_option(honor_cipher_order, Value)}, RecordCB);
+new_ssl_options([{honor_ecc_order, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
+ new_ssl_options(Rest, Opts#ssl_options{honor_ecc_order = validate_option(honor_ecc_order, Value)}, RecordCB);
+new_ssl_options([{eccs, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
+ new_ssl_options(Rest,
+ Opts#ssl_options{eccs =
+ handle_eccs_option(Value, RecordCB:highest_protocol_version())
+ },
+ RecordCB);
new_ssl_options([{signature_algs, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
new_ssl_options(Rest,
Opts#ssl_options{signature_algs =
handle_hashsigns_option(Value,
- RecordCB:highest_protocol_version())},
+ tls_version(RecordCB:highest_protocol_version()))},
RecordCB);
-
+new_ssl_options([{protocol, dtls = Value} | Rest], #ssl_options{} = Opts, dtls_record = RecordCB) ->
+ new_ssl_options(Rest, Opts#ssl_options{protocol = Value}, RecordCB);
+new_ssl_options([{protocol, tls = Value} | Rest], #ssl_options{} = Opts, tls_record = RecordCB) ->
+ new_ssl_options(Rest, Opts#ssl_options{protocol = Value}, RecordCB);
new_ssl_options([{Key, Value} | _Rest], #ssl_options{}, _) ->
throw({error, {options, {Key, Value}}}).
@@ -1397,3 +1463,23 @@ default_option_role(Role, Value, Role) ->
Value;
default_option_role(_,_,_) ->
undefined.
+
+default_cb_info(tls) ->
+ {gen_tcp, tcp, tcp_closed, tcp_error};
+default_cb_info(dtls) ->
+ {gen_udp, udp, udp_closed, udp_error}.
+
+include_security_info([]) ->
+ false;
+include_security_info([Item | Items]) ->
+ case lists:member(Item, [client_random, server_random, master_secret]) of
+ true ->
+ true;
+ false ->
+ include_security_info(Items)
+ end.
+
+server_name_indication_default(Host) when is_list(Host) ->
+ Host;
+server_name_indication_default(_) ->
+ undefined.
diff --git a/lib/ssl/src/ssl_admin_sup.erl b/lib/ssl/src/ssl_admin_sup.erl
new file mode 100644
index 0000000000..9c96435753
--- /dev/null
+++ b/lib/ssl/src/ssl_admin_sup.erl
@@ -0,0 +1,95 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_admin_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0, manager_opts/0]).
+
+%% Supervisor callback
+-export([init/1]).
+
+%%%=========================================================================
+%%% API
+%%%=========================================================================
+
+-spec start_link() -> {ok, pid()} | ignore | {error, term()}.
+
+start_link() ->
+ supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+
+%%%=========================================================================
+%%% Supervisor callback
+%%%=========================================================================
+
+init([]) ->
+ PEMCache = pem_cache_child_spec(),
+ SessionCertManager = session_and_cert_manager_child_spec(),
+ {ok, {{rest_for_one, 10, 3600}, [PEMCache, SessionCertManager]}}.
+
+manager_opts() ->
+ CbOpts = case application:get_env(ssl, session_cb) of
+ {ok, Cb} when is_atom(Cb) ->
+ InitArgs = session_cb_init_args(),
+ [{session_cb, Cb}, {session_cb_init_args, InitArgs}];
+ _ ->
+ []
+ end,
+ case application:get_env(ssl, session_lifetime) of
+ {ok, Time} when is_integer(Time) ->
+ [{session_lifetime, Time}| CbOpts];
+ _ ->
+ CbOpts
+ end.
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+pem_cache_child_spec() ->
+ Name = ssl_pem_cache,
+ StartFunc = {ssl_pem_cache, start_link, [[]]},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [ssl_pem_cache],
+ Type = worker,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+
+session_and_cert_manager_child_spec() ->
+ Opts = manager_opts(),
+ Name = ssl_manager,
+ StartFunc = {ssl_manager, start_link, [Opts]},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [ssl_manager],
+ Type = worker,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+
+session_cb_init_args() ->
+ case application:get_env(ssl, session_cb_init_args) of
+ {ok, Args} when is_list(Args) ->
+ Args;
+ _ ->
+ []
+ end.
diff --git a/lib/ssl/src/ssl_alert.erl b/lib/ssl/src/ssl_alert.erl
index db71b16d80..696a55e4b9 100644
--- a/lib/ssl/src/ssl_alert.erl
+++ b/lib/ssl/src/ssl_alert.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,22 +32,13 @@
-include("ssl_record.hrl").
-include("ssl_internal.hrl").
--export([encode/3, decode/1, alert_txt/1, reason_code/2]).
+-export([decode/1, alert_txt/1, reason_code/2]).
%%====================================================================
%% Internal application API
%%====================================================================
%%--------------------------------------------------------------------
--spec encode(#alert{}, ssl_record:ssl_version(), #connection_states{}) ->
- {iolist(), #connection_states{}}.
-%%
-%% Description: Encodes an alert
-%%--------------------------------------------------------------------
-encode(#alert{} = Alert, Version, ConnectionStates) ->
- ssl_record:encode_alert_record(Alert, Version, ConnectionStates).
-
-%%--------------------------------------------------------------------
-spec decode(binary()) -> [#alert{}] | #alert{}.
%%
%% Description: Decode alert(s), will return a singel own alert if peer
diff --git a/lib/ssl/src/ssl_alert.hrl b/lib/ssl/src/ssl_alert.hrl
index 38facb964f..f3743ba0f0 100644
--- a/lib/ssl/src/ssl_alert.hrl
+++ b/lib/ssl/src/ssl_alert.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl
index 3ec3f50e05..0dd5e5c5cf 100644
--- a/lib/ssl/src/ssl_certificate.erl
+++ b/lib/ssl/src/ssl_certificate.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016 All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017 All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -64,7 +64,7 @@ trusted_cert_and_path(CertChain, CertDbHandle, CertDbRef, PartialChainHandler) -
{ok, IssuerId} = public_key:pkix_issuer_id(OtpCert, self),
{self, IssuerId};
false ->
- other_issuer(OtpCert, BinCert, CertDbHandle)
+ other_issuer(OtpCert, BinCert, CertDbHandle, CertDbRef)
end,
case SignedAndIssuerID of
@@ -125,21 +125,28 @@ file_to_crls(File, DbHandle) ->
%% Description: Validates ssl/tls specific extensions
%%--------------------------------------------------------------------
validate(_,{extension, #'Extension'{extnID = ?'id-ce-extKeyUsage',
- extnValue = KeyUse}}, {Role, _,_, _, _}) ->
+ extnValue = KeyUse}}, UserState = {Role, _,_, _, _, _}) ->
case is_valid_extkey_usage(KeyUse, Role) of
true ->
- {valid, Role};
+ {valid, UserState};
false ->
{fail, {bad_cert, invalid_ext_key_usage}}
end;
-validate(_, {extension, _}, Role) ->
- {unknown, Role};
+validate(_, {extension, _}, UserState) ->
+ {unknown, UserState};
validate(_, {bad_cert, _} = Reason, _) ->
{fail, Reason};
-validate(_, valid, Role) ->
- {valid, Role};
-validate(_, valid_peer, Role) ->
- {valid, Role}.
+validate(_, valid, UserState) ->
+ {valid, UserState};
+validate(Cert, valid_peer, UserState = {client, _,_, Hostname, _, _}) when Hostname =/= undefined ->
+ case public_key:pkix_verify_hostname(Cert, [{dns_id, Hostname}]) of
+ true ->
+ {valid, UserState};
+ false ->
+ {fail, {bad_cert, hostname_check_failed}}
+ end;
+validate(_, valid_peer, UserState) ->
+ {valid, UserState}.
%%--------------------------------------------------------------------
-spec is_valid_key_usage(list(), term()) -> boolean().
@@ -200,7 +207,7 @@ certificate_chain(OtpCert, BinCert, CertDbHandle, CertsDbRef, Chain) ->
{_, true = SelfSigned} ->
certificate_chain(CertDbHandle, CertsDbRef, Chain, ignore, ignore, SelfSigned);
{{error, issuer_not_found}, SelfSigned} ->
- case find_issuer(OtpCert, BinCert, CertDbHandle) of
+ case find_issuer(OtpCert, BinCert, CertDbHandle, CertsDbRef) of
{ok, {SerialNr, Issuer}} ->
certificate_chain(CertDbHandle, CertsDbRef, Chain,
SerialNr, Issuer, SelfSigned);
@@ -232,7 +239,7 @@ certificate_chain(CertDbHandle, CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned
{ok, undefined, lists:reverse(Chain)}
end.
-find_issuer(OtpCert, BinCert, CertDbHandle) ->
+find_issuer(OtpCert, BinCert, CertDbHandle, CertsDbRef) ->
IsIssuerFun =
fun({_Key, {_Der, #'OTPCertificate'{} = ErlCertCandidate}}, Acc) ->
case public_key:pkix_is_issuer(OtpCert, ErlCertCandidate) of
@@ -250,12 +257,24 @@ find_issuer(OtpCert, BinCert, CertDbHandle) ->
Acc
end,
- try ssl_pkix_db:foldl(IsIssuerFun, issuer_not_found, CertDbHandle) of
- issuer_not_found ->
- {error, issuer_not_found}
- catch
- {ok, _IssuerId} = Return ->
- Return
+ if is_reference(CertsDbRef) -> % actual DB exists
+ try ssl_pkix_db:foldl(IsIssuerFun, issuer_not_found, CertDbHandle) of
+ issuer_not_found ->
+ {error, issuer_not_found}
+ catch
+ {ok, _IssuerId} = Return ->
+ Return
+ end;
+ is_tuple(CertsDbRef), element(1,CertsDbRef) =:= extracted -> % cache bypass byproduct
+ {extracted, CertsData} = CertsDbRef,
+ DB = [Entry || {decoded, Entry} <- CertsData],
+ try lists:foldl(IsIssuerFun, issuer_not_found, DB) of
+ issuer_not_found ->
+ {error, issuer_not_found}
+ catch
+ {ok, _IssuerId} = Return ->
+ Return
+ end
end.
is_valid_extkey_usage(KeyUse, client) ->
@@ -281,12 +300,12 @@ public_key(#'OTPSubjectPublicKeyInfo'{algorithm = #'PublicKeyAlgorithm'{algorith
subjectPublicKey = Key}) ->
{Key, Params}.
-other_issuer(OtpCert, BinCert, CertDbHandle) ->
+other_issuer(OtpCert, BinCert, CertDbHandle, CertDbRef) ->
case public_key:pkix_issuer_id(OtpCert, other) of
{ok, IssuerId} ->
{other, IssuerId};
{error, issuer_not_found} ->
- case find_issuer(OtpCert, BinCert, CertDbHandle) of
+ case find_issuer(OtpCert, BinCert, CertDbHandle, CertDbRef) of
{ok, IssuerId} ->
{other, IssuerId};
Other ->
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index e935c033c7..bd60197c88 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -1,7 +1,7 @@
%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -40,15 +40,16 @@
ec_keyed_suites/0, anonymous_suites/1, psk_suites/1, srp_suites/0,
rc4_suites/1, des_suites/1, openssl_suite/1, openssl_suite_name/1, filter/2, filter_suites/1,
hash_algorithm/1, sign_algorithm/1, is_acceptable_hash/2, is_fallback/1,
- random_bytes/1]).
+ random_bytes/1, calc_mac_hash/4,
+ is_stream_ciphersuite/1]).
-export_type([cipher_suite/0,
erl_cipher_suite/0, openssl_cipher_suite/0,
hash/0, key_algo/0, sign_algo/0]).
--type cipher() :: null |rc4_128 | idea_cbc | des40_cbc | des_cbc | '3des_ede_cbc'
+-type cipher() :: null |rc4_128 | des_cbc | '3des_ede_cbc'
| aes_128_cbc | aes_256_cbc | aes_128_gcm | aes_256_gcm | chacha20_poly1305.
--type hash() :: null | sha | md5 | sha224 | sha256 | sha384 | sha512.
+-type hash() :: null | md5 | sha | sha224 | sha256 | sha384 | sha512.
-type sign_algo() :: rsa | dsa | ecdsa.
-type key_algo() :: null | rsa | dhe_rsa | dhe_dss | ecdhe_ecdsa| ecdh_ecdsa | ecdh_rsa| srp_rsa| srp_dss |
psk | dhe_psk | rsa_psk | dh_anon | ecdh_anon | srp_anon.
@@ -156,7 +157,7 @@ cipher_aead(?CHACHA20_POLY1305, CipherState, SeqNo, AAD, Fragment, Version) ->
aead_cipher(chacha20_poly1305, #cipher_state{key=Key} = CipherState, SeqNo, AAD0, Fragment, _Version) ->
CipherLen = erlang:iolist_size(Fragment),
AAD = <<AAD0/binary, ?UINT16(CipherLen)>>,
- Nonce = <<SeqNo:64/integer>>,
+ Nonce = ?uint64(SeqNo),
{Content, CipherTag} = crypto:block_encrypt(chacha20_poly1305, Key, Nonce, {AAD, Fragment}),
{<<Content/binary, CipherTag/binary>>, CipherState};
aead_cipher(Type, #cipher_state{key=Key, iv = IV0, nonce = Nonce} = CipherState, _SeqNo, AAD0, Fragment, _Version) ->
@@ -279,7 +280,7 @@ aead_ciphertext_to_state(chacha20_poly1305, SeqNo, _IV, AAD0, Fragment, _Version
CipherLen = size(Fragment) - 16,
<<CipherText:CipherLen/bytes, CipherTag:16/bytes>> = Fragment,
AAD = <<AAD0/binary, ?UINT16(CipherLen)>>,
- Nonce = <<SeqNo:64/integer>>,
+ Nonce = ?uint64(SeqNo),
{Nonce, AAD, CipherText, CipherTag};
aead_ciphertext_to_state(_, _SeqNo, <<Salt:4/bytes, _/binary>>, AAD0, Fragment, _Version) ->
CipherLen = size(Fragment) - 24,
@@ -310,16 +311,21 @@ aead_decipher(Type, #cipher_state{key = Key, iv = IV} = CipherState,
%%--------------------------------------------------------------------
suites({3, 0}) ->
ssl_v3:suites();
-suites({3, N}) ->
- tls_v1:suites(N).
+suites({3, Minor}) ->
+ tls_v1:suites(Minor);
+suites({_, Minor}) ->
+ dtls_v1:suites(Minor).
-all_suites(Version) ->
+all_suites({3, _} = Version) ->
suites(Version)
++ anonymous_suites(Version)
++ psk_suites(Version)
++ srp_suites()
++ rc4_suites(Version)
- ++ des_suites(Version).
+ ++ des_suites(Version);
+all_suites(Version) ->
+ dtls_v1:all_suites(Version).
+
%%--------------------------------------------------------------------
-spec anonymous_suites(ssl_record:ssl_version() | integer()) -> [cipher_suite()].
%%
@@ -333,21 +339,27 @@ anonymous_suites({3, N}) ->
anonymous_suites(N)
when N >= 3 ->
[?TLS_DH_anon_WITH_AES_128_GCM_SHA256,
- ?TLS_DH_anon_WITH_AES_256_GCM_SHA384
- ] ++ anonymous_suites(0);
-
-anonymous_suites(_) ->
- [?TLS_DH_anon_WITH_RC4_128_MD5,
- ?TLS_DH_anon_WITH_DES_CBC_SHA,
- ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
- ?TLS_DH_anon_WITH_AES_128_CBC_SHA,
- ?TLS_DH_anon_WITH_AES_256_CBC_SHA,
+ ?TLS_DH_anon_WITH_AES_256_GCM_SHA384,
?TLS_DH_anon_WITH_AES_128_CBC_SHA256,
?TLS_DH_anon_WITH_AES_256_CBC_SHA256,
- ?TLS_ECDH_anon_WITH_RC4_128_SHA,
- ?TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
?TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
- ?TLS_ECDH_anon_WITH_AES_256_CBC_SHA].
+ ?TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
+ ?TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DH_anon_WITH_RC4_128_MD5];
+
+anonymous_suites(2) ->
+ [?TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
+ ?TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
+ ?TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DH_anon_WITH_DES_CBC_SHA,
+ ?TLS_DH_anon_WITH_RC4_128_MD5];
+
+anonymous_suites(N) when N == 0;
+ N == 1 ->
+ [?TLS_DH_anon_WITH_RC4_128_MD5,
+ ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DH_anon_WITH_DES_CBC_SHA
+ ].
%%--------------------------------------------------------------------
-spec psk_suites(ssl_record:ssl_version() | integer()) -> [cipher_suite()].
@@ -1441,25 +1453,60 @@ filter_suites(Suites) ->
is_acceptable_prf(Prf, Hashs)
end, Suites).
-is_acceptable_keyexchange(KeyExchange, Algos)
- when KeyExchange == ecdh_ecdsa;
- KeyExchange == ecdhe_ecdsa;
- KeyExchange == ecdh_rsa;
- KeyExchange == ecdhe_rsa;
- KeyExchange == ecdh_anon ->
+is_acceptable_keyexchange(KeyExchange, _Algos) when KeyExchange == psk;
+ KeyExchange == null ->
+ true;
+is_acceptable_keyexchange(KeyExchange, Algos) when KeyExchange == dh_anon;
+ KeyExchange == dhe_psk ->
+ proplists:get_bool(dh, Algos);
+is_acceptable_keyexchange(dhe_dss, Algos) ->
+ proplists:get_bool(dh, Algos) andalso
+ proplists:get_bool(dss, Algos);
+is_acceptable_keyexchange(dhe_rsa, Algos) ->
+ proplists:get_bool(dh, Algos) andalso
+ proplists:get_bool(rsa, Algos);
+is_acceptable_keyexchange(ecdh_anon, Algos) ->
proplists:get_bool(ecdh, Algos);
-is_acceptable_keyexchange(_, _) ->
- true.
-
+is_acceptable_keyexchange(KeyExchange, Algos) when KeyExchange == ecdh_ecdsa;
+ KeyExchange == ecdhe_ecdsa ->
+ proplists:get_bool(ecdh, Algos) andalso
+ proplists:get_bool(ecdsa, Algos);
+is_acceptable_keyexchange(KeyExchange, Algos) when KeyExchange == ecdh_rsa;
+ KeyExchange == ecdhe_rsa ->
+ proplists:get_bool(ecdh, Algos) andalso
+ proplists:get_bool(rsa, Algos);
+is_acceptable_keyexchange(KeyExchange, Algos) when KeyExchange == rsa;
+ KeyExchange == rsa_psk ->
+ proplists:get_bool(rsa, Algos);
+is_acceptable_keyexchange(srp_anon, Algos) ->
+ proplists:get_bool(srp, Algos);
+is_acceptable_keyexchange(srp_dss, Algos) ->
+ proplists:get_bool(srp, Algos) andalso
+ proplists:get_bool(dss, Algos);
+is_acceptable_keyexchange(srp_rsa, Algos) ->
+ proplists:get_bool(srp, Algos) andalso
+ proplists:get_bool(rsa, Algos);
+is_acceptable_keyexchange(_KeyExchange, _Algos) ->
+ false.
+
+is_acceptable_cipher(null, _Algos) ->
+ true;
+is_acceptable_cipher(rc4_128, Algos) ->
+ proplists:get_bool(rc4, Algos);
+is_acceptable_cipher(des_cbc, Algos) ->
+ proplists:get_bool(des_cbc, Algos);
+is_acceptable_cipher('3des_ede_cbc', Algos) ->
+ proplists:get_bool(des3_cbc, Algos);
+is_acceptable_cipher(aes_128_cbc, Algos) ->
+ proplists:get_bool(aes_cbc128, Algos);
+is_acceptable_cipher(aes_256_cbc, Algos) ->
+ proplists:get_bool(aes_cbc256, Algos);
is_acceptable_cipher(Cipher, Algos)
when Cipher == aes_128_gcm;
Cipher == aes_256_gcm ->
proplists:get_bool(aes_gcm, Algos);
-is_acceptable_cipher(Cipher, Algos)
- when Cipher == chacha20_poly1305 ->
- proplists:get_bool(Cipher, Algos);
-is_acceptable_cipher(_, _) ->
- true.
+is_acceptable_cipher(Cipher, Algos) ->
+ proplists:get_bool(Cipher, Algos).
is_acceptable_hash(null, _Algos) ->
true;
@@ -1484,9 +1531,32 @@ is_fallback(CipherSuites)->
random_bytes(N) ->
crypto:strong_rand_bytes(N).
+calc_mac_hash(Type, Version,
+ PlainFragment, #{sequence_number := SeqNo,
+ mac_secret := MacSecret,
+ security_parameters:=
+ SecPars}) ->
+ Length = erlang:iolist_size(PlainFragment),
+ mac_hash(Version, SecPars#security_parameters.mac_algorithm,
+ MacSecret, SeqNo, Type,
+ Length, PlainFragment).
+
+is_stream_ciphersuite({_, rc4_128, _, _}) ->
+ true;
+is_stream_ciphersuite(_) ->
+ false.
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+mac_hash({_,_}, ?NULL, _MacSecret, _SeqNo, _Type,
+ _Length, _Fragment) ->
+ <<>>;
+mac_hash({3, 0}, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) ->
+ ssl_v3:mac_hash(MacAlg, MacSecret, SeqNo, Type, Length, Fragment);
+mac_hash({3, N} = Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment)
+ when N =:= 1; N =:= 2; N =:= 3 ->
+ tls_v1:mac_hash(MacAlg, MacSecret, SeqNo, Type, Version,
+ Length, Fragment).
bulk_cipher_algorithm(null) ->
?NULL;
diff --git a/lib/ssl/src/ssl_config.erl b/lib/ssl/src/ssl_config.erl
index 0652d029c3..e4611995ec 100644
--- a/lib/ssl/src/ssl_config.erl
+++ b/lib/ssl/src/ssl_config.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,18 +32,20 @@ init(SslOpts, Role) ->
init_manager_name(SslOpts#ssl_options.erl_dist),
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CRLDbHandle, OwnCert}
+ {ok, #{pem_cache := PemCache} = Config}
= init_certificates(SslOpts, Role),
PrivateKey =
- init_private_key(PemCacheHandle, SslOpts#ssl_options.key, SslOpts#ssl_options.keyfile,
+ init_private_key(PemCache, SslOpts#ssl_options.key, SslOpts#ssl_options.keyfile,
SslOpts#ssl_options.password, Role),
- DHParams = init_diffie_hellman(PemCacheHandle, SslOpts#ssl_options.dh, SslOpts#ssl_options.dhfile, Role),
- {ok, CertDbRef, CertDbHandle, FileRefHandle, CacheHandle, CRLDbHandle, OwnCert, PrivateKey, DHParams}.
+ DHParams = init_diffie_hellman(PemCache, SslOpts#ssl_options.dh, SslOpts#ssl_options.dhfile, Role),
+ {ok, Config#{private_key => PrivateKey, dh_params => DHParams}}.
init_manager_name(false) ->
- put(ssl_manager, ssl_manager:manager_name(normal));
+ put(ssl_manager, ssl_manager:name(normal)),
+ put(ssl_pem_cache, ssl_pem_cache:name(normal));
init_manager_name(true) ->
- put(ssl_manager, ssl_manager:manager_name(dist)).
+ put(ssl_manager, ssl_manager:name(dist)),
+ put(ssl_pem_cache, ssl_pem_cache:name(dist)).
init_certificates(#ssl_options{cacerts = CaCerts,
cacertfile = CACertFile,
@@ -51,7 +53,7 @@ init_certificates(#ssl_options{cacerts = CaCerts,
cert = Cert,
crl_cache = CRLCache
}, Role) ->
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CRLDbInfo} =
+ {ok, Config} =
try
Certs = case CaCerts of
undefined ->
@@ -59,41 +61,37 @@ init_certificates(#ssl_options{cacerts = CaCerts,
_ ->
{der, CaCerts}
end,
- {ok, _, _, _, _, _, _} = ssl_manager:connection_init(Certs, Role, CRLCache)
+ {ok,_} = ssl_manager:connection_init(Certs, Role, CRLCache)
catch
_:Reason ->
file_error(CACertFile, {cacertfile, Reason})
end,
- init_certificates(Cert, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle,
- CacheHandle, CRLDbInfo, CertFile, Role).
+ init_certificates(Cert, Config, CertFile, Role).
-init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle,
- CRLDbInfo, <<>>, _) ->
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CRLDbInfo, undefined};
+init_certificates(undefined, Config, <<>>, _) ->
+ {ok, Config#{own_certificate => undefined}};
-init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle,
- CacheHandle, CRLDbInfo, CertFile, client) ->
+init_certificates(undefined, #{pem_cache := PemCache} = Config, CertFile, client) ->
try
%% Ignoring potential proxy-certificates see:
%% http://dev.globus.org/wiki/Security/ProxyFileFormat
- [OwnCert|_] = ssl_certificate:file_to_certificats(CertFile, PemCacheHandle),
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CRLDbInfo, OwnCert}
+ [OwnCert|_] = ssl_certificate:file_to_certificats(CertFile, PemCache),
+ {ok, Config#{own_certificate => OwnCert}}
catch _Error:_Reason ->
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CRLDbInfo, undefined}
- end;
+ {ok, Config#{own_certificate => undefined}}
+ end;
-init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle,
- PemCacheHandle, CacheRef, CRLDbInfo, CertFile, server) ->
+init_certificates(undefined, #{pem_cache := PemCache} = Config, CertFile, server) ->
try
- [OwnCert|_] = ssl_certificate:file_to_certificats(CertFile, PemCacheHandle),
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, CRLDbInfo, OwnCert}
+ [OwnCert|_] = ssl_certificate:file_to_certificats(CertFile, PemCache),
+ {ok, Config#{own_certificate => OwnCert}}
catch
_:Reason ->
file_error(CertFile, {certfile, Reason})
end;
-init_certificates(Cert, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, CRLDbInfo, _, _) ->
- {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, CRLDbInfo, Cert}.
-
+init_certificates(Cert, Config, _, _) ->
+ {ok, Config#{own_certificate => Cert}}.
+
init_private_key(_, undefined, <<>>, _Password, _Client) ->
undefined;
init_private_key(DbHandle, undefined, KeyFile, Password, _) ->
@@ -135,6 +133,8 @@ file_error(File, Throw) ->
case Throw of
{Opt,{badmatch, {error, {badmatch, Error}}}} ->
throw({options, {Opt, binary_to_list(File), Error}});
+ {Opt, {badmatch, Error}} ->
+ throw({options, {Opt, binary_to_list(File), Error}});
_ ->
throw(Throw)
end.
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 53282998d0..fb87662c7b 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -42,9 +42,9 @@
%% User Events
-export([send/2, recv/3, close/2, shutdown/2,
- new_user/2, get_opts/2, set_opts/2, session_info/1,
+ new_user/2, get_opts/2, set_opts/2,
peer_certificate/1, renegotiation/1, negotiated_protocol/1, prf/5,
- connection_information/1
+ connection_information/2, handle_common_event/5
]).
%% General gen_statem state functions with extra callback argument
@@ -58,13 +58,21 @@
-export([handle_info/3, handle_call/5, handle_session/7, ssl_config/3,
prepare_connection/2, hibernate_after/3]).
+%% Alert and close handling
+-export([handle_own_alert/4,handle_alert/3,
+ handle_normal_shutdown/3
+ ]).
+
+%% Data handling
+-export([write_application_data/3, read_application_data/2]).
%%====================================================================
%% Internal application API
%%====================================================================
%%--------------------------------------------------------------------
-spec connect(tls_connection | dtls_connection,
- host(), inet:port_number(), port(),
+ host(), inet:port_number(),
+ port() | {tuple(), port()}, %% TLS | DTLS
{#ssl_options{}, #socket_options{},
%% Tracker only needed on server side
undefined},
@@ -138,14 +146,24 @@ socket_control(Connection, Socket, Pid, Transport) ->
-spec socket_control(tls_connection | dtls_connection, port(), pid(), atom(), pid()| undefined) ->
{ok, #sslsocket{}} | {error, reason()}.
%%--------------------------------------------------------------------
-socket_control(Connection, Socket, Pid, Transport, ListenTracker) ->
+socket_control(Connection, Socket, Pid, Transport, udp_listner) ->
+ %% dtls listner process must have the socket control
+ {ok, Connection:socket(Pid, Transport, Socket, Connection, undefined)};
+
+socket_control(tls_connection = Connection, Socket, Pid, Transport, ListenTracker) ->
+ case Transport:controlling_process(Socket, Pid) of
+ ok ->
+ {ok, Connection:socket(Pid, Transport, Socket, Connection, ListenTracker)};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+socket_control(dtls_connection = Connection, {_, Socket}, Pid, Transport, ListenTracker) ->
case Transport:controlling_process(Socket, Pid) of
ok ->
- {ok, ssl_socket:socket(Pid, Transport, Socket, Connection, ListenTracker)};
+ {ok, Connection:socket(Pid, Transport, Socket, Connection, ListenTracker)};
{error, Reason} ->
{error, Reason}
end.
-
%%--------------------------------------------------------------------
-spec send(pid(), iodata()) -> ok | {error, reason()}.
%%
@@ -167,12 +185,12 @@ recv(Pid, Length, Timeout) ->
call(Pid, {recv, Length, Timeout}).
%%--------------------------------------------------------------------
--spec connection_information(pid()) -> {ok, list()} | {error, reason()}.
+-spec connection_information(pid(), boolean()) -> {ok, list()} | {error, reason()}.
%%
%% Description: Get the SNI hostname
%%--------------------------------------------------------------------
-connection_information(Pid) when is_pid(Pid) ->
- call(Pid, connection_information).
+connection_information(Pid, IncludeSecrityInfo) when is_pid(Pid) ->
+ call(Pid, {connection_information, IncludeSecrityInfo}).
%%--------------------------------------------------------------------
-spec close(pid(), {close, Timeout::integer() |
@@ -229,14 +247,6 @@ set_opts(ConnectionPid, Options) ->
call(ConnectionPid, {set_opts, Options}).
%%--------------------------------------------------------------------
--spec session_info(pid()) -> {ok, list()} | {error, reason()}.
-%%
-%% Description: Returns info about the ssl session
-%%--------------------------------------------------------------------
-session_info(ConnectionPid) ->
- call(ConnectionPid, session_info).
-
-%%--------------------------------------------------------------------
-spec peer_certificate(pid()) -> {ok, binary()| undefined} | {error, reason()}.
%%
%% Description: Returns the peer cert
@@ -264,7 +274,7 @@ prf(ConnectionPid, Secret, Label, Seed, WantedLength) ->
%%--------------------------------------------------------------------
-spec handle_session(#server_hello{}, ssl_record:ssl_version(),
- binary(), #connection_states{}, _,_, #state{}) ->
+ binary(), ssl_record:connection_states(), _,_, #state{}) ->
gen_statem:state_function_result().
%%--------------------------------------------------------------------
handle_session(#server_hello{cipher_suite = CipherSuite,
@@ -272,19 +282,21 @@ handle_session(#server_hello{cipher_suite = CipherSuite,
Version, NewId, ConnectionStates, ProtoExt, Protocol0,
#state{session = #session{session_id = OldId},
negotiated_version = ReqVersion,
- negotiated_protocol = CurrentProtocol} = State0) ->
+ negotiated_protocol = CurrentProtocol} = State0) ->
{KeyAlgorithm, _, _, _} =
ssl_cipher:suite_definition(CipherSuite),
PremasterSecret = make_premaster_secret(ReqVersion, KeyAlgorithm),
- {ExpectNPN, Protocol} = case Protocol0 of
- undefined -> {false, CurrentProtocol};
- _ -> {ProtoExt =:= npn, Protocol0}
- end,
+ {ExpectNPN, Protocol} = case Protocol0 of
+ undefined ->
+ {false, CurrentProtocol};
+ _ ->
+ {ProtoExt =:= npn, Protocol0}
+ end,
State = State0#state{key_algorithm = KeyAlgorithm,
- negotiated_version = Version,
+ negotiated_version = Version,
connection_states = ConnectionStates,
premaster_secret = PremasterSecret,
expecting_next_protocol_negotiation = ExpectNPN,
@@ -303,8 +315,14 @@ handle_session(#server_hello{cipher_suite = CipherSuite,
-spec ssl_config(#ssl_options{}, client | server, #state{}) -> #state{}.
%%--------------------------------------------------------------------
ssl_config(Opts, Role, State) ->
- {ok, Ref, CertDbHandle, FileRefHandle, CacheHandle, CRLDbInfo,
- OwnCert, Key, DHParams} =
+ {ok, #{cert_db_ref := Ref,
+ cert_db_handle := CertDbHandle,
+ fileref_db_handle := FileRefHandle,
+ session_cache := CacheHandle,
+ crl_db_info := CRLDbHandle,
+ private_key := Key,
+ dh_params := DHParams,
+ own_certificate := OwnCert}} =
ssl_config:init(Opts, Role),
Handshake = ssl_handshake:init_handshake_history(),
TimeStamp = erlang:monotonic_time(),
@@ -315,7 +333,7 @@ ssl_config(Opts, Role, State) ->
file_ref_db = FileRefHandle,
cert_db_ref = Ref,
cert_db = CertDbHandle,
- crl_db = CRLDbInfo,
+ crl_db = CRLDbHandle,
session_cache = CacheHandle,
private_key = Key,
diffie_hellman_params = DHParams,
@@ -337,11 +355,13 @@ init({call, From}, {start, Timeout}, State0, Connection) ->
timer = Timer}),
Connection:next_event(hello, Record, State);
init({call, From}, {start, {Opts, EmOpts}, Timeout},
- #state{role = Role} = State0, Connection) ->
+ #state{role = Role, ssl_options = OrigSSLOptions,
+ socket_options = SockOpts} = State0, Connection) ->
try
- State = ssl_config(Opts, Role, State0),
+ SslOpts = ssl:handle_options(Opts, OrigSSLOptions),
+ State = ssl_config(SslOpts, Role, State0),
init({call, From}, {start, Timeout},
- State#state{ssl_options = Opts, socket_options = EmOpts}, Connection)
+ State#state{ssl_options = SslOpts, socket_options = new_emulated(EmOpts, SockOpts)}, Connection)
catch throw:Error ->
{stop_and_reply, normal, {reply, From, {error, Error}}}
end;
@@ -382,7 +402,7 @@ abbreviated(internal, #finished{verify_data = Data} = Finished,
session = #session{master_secret = MasterSecret},
connection_states = ConnectionStates0} =
State0, Connection) ->
- case ssl_handshake:verify_connection(Version, Finished, client,
+ case ssl_handshake:verify_connection(ssl:tls_version(Version), Finished, client,
get_current_prf(ConnectionStates0, write),
MasterSecret, Handshake) of
verified ->
@@ -392,7 +412,7 @@ abbreviated(internal, #finished{verify_data = Data} = Finished,
expecting_finished = false}, Connection),
Connection:next_event(connection, Record, State);
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, abbreviated, State0)
+ handle_own_alert(Alert, Version, abbreviated, State0)
end;
abbreviated(internal, #finished{verify_data = Data} = Finished,
@@ -400,19 +420,19 @@ abbreviated(internal, #finished{verify_data = Data} = Finished,
session = #session{master_secret = MasterSecret},
negotiated_version = Version,
connection_states = ConnectionStates0} = State0, Connection) ->
- case ssl_handshake:verify_connection(Version, Finished, server,
+ case ssl_handshake:verify_connection(ssl:tls_version(Version), Finished, server,
get_pending_prf(ConnectionStates0, write),
MasterSecret, Handshake0) of
verified ->
ConnectionStates1 =
ssl_record:set_server_verify_data(current_read, Data, ConnectionStates0),
- State1 =
+ {State1, Actions} =
finalize_handshake(State0#state{connection_states = ConnectionStates1},
abbreviated, Connection),
{Record, State} = prepare_connection(State1#state{expecting_finished = false}, Connection),
- Connection:next_event(connection, Record, State);
+ Connection:next_event(connection, Record, State, Actions);
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, abbreviated, State0)
+ handle_own_alert(Alert, Version, abbreviated, State0)
end;
%% only allowed to send next_protocol message after change cipher spec
@@ -452,9 +472,9 @@ certify(internal, #certificate{asn1_certificates = []},
#state{role = server, negotiated_version = Version,
ssl_options = #ssl_options{verify = verify_peer,
fail_if_no_peer_cert = true}} =
- State, Connection) ->
+ State, _) ->
Alert = ?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE),
- Connection:handle_own_alert(Alert, Version, certify, State);
+ handle_own_alert(Alert, Version, certify, State);
certify(internal, #certificate{asn1_certificates = []},
#state{role = server,
@@ -469,9 +489,9 @@ certify(internal, #certificate{},
#state{role = server,
negotiated_version = Version,
ssl_options = #ssl_options{verify = verify_none}} =
- State, Connection) ->
+ State, _) ->
Alert = ?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE, unrequested_certificate),
- Connection:handle_own_alert(Alert, Version, certify, State);
+ handle_own_alert(Alert, Version, certify, State);
certify(internal, #certificate{} = Cert,
#state{negotiated_version = Version,
@@ -481,18 +501,12 @@ certify(internal, #certificate{} = Cert,
crl_db = CRLDbInfo,
ssl_options = Opts} = State, Connection) ->
case ssl_handshake:certify(Cert, CertDbHandle, CertDbRef,
- Opts#ssl_options.depth,
- Opts#ssl_options.verify,
- Opts#ssl_options.verify_fun,
- Opts#ssl_options.partial_chain,
- Opts#ssl_options.crl_check,
- CRLDbInfo,
- Role) of
+ Opts, CRLDbInfo, Role) of
{PeerCert, PublicKeyInfo} ->
handle_peer_cert(Role, PeerCert, PublicKeyInfo,
State#state{client_certificate_requested = false}, Connection);
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, certify, State)
+ handle_own_alert(Alert, Version, certify, State)
end;
certify(internal, #server_key_exchange{exchange_keys = Keys},
@@ -506,10 +520,10 @@ certify(internal, #server_key_exchange{exchange_keys = Keys},
Alg == psk; Alg == dhe_psk; Alg == rsa_psk;
Alg == srp_dss; Alg == srp_rsa; Alg == srp_anon ->
- Params = ssl_handshake:decode_server_key(Keys, Alg, Version),
+ Params = ssl_handshake:decode_server_key(Keys, Alg, ssl:tls_version(Version)),
%% Use negotiated value if TLS-1.2 otherwhise return default
- HashSign = negotiated_hashsign(Params#server_key_params.hashsign, Alg, PubKeyInfo, Version),
+ HashSign = negotiated_hashsign(Params#server_key_params.hashsign, Alg, PubKeyInfo, ssl:tls_version(Version)),
case is_anonymous(Alg) of
true ->
@@ -517,26 +531,25 @@ certify(internal, #server_key_exchange{exchange_keys = Keys},
State#state{hashsign_algorithm = HashSign}, Connection);
false ->
case ssl_handshake:verify_server_key(Params, HashSign,
- ConnectionStates, Version, PubKeyInfo) of
+ ConnectionStates, ssl:tls_version(Version), PubKeyInfo) of
true ->
calculate_secret(Params#server_key_params.params,
State#state{hashsign_algorithm = HashSign},
Connection);
false ->
- Connection:handle_own_alert(?ALERT_REC(?FATAL, ?DECRYPT_ERROR),
+ handle_own_alert(?ALERT_REC(?FATAL, ?DECRYPT_ERROR),
Version, certify, State)
end
end;
-certify(internal, #certificate_request{hashsign_algorithms = HashSigns},
+certify(internal, #certificate_request{} = CertRequest,
#state{session = #session{own_certificate = Cert},
- key_algorithm = KeyExAlg,
+ role = client,
ssl_options = #ssl_options{signature_algs = SupportedHashSigns},
negotiated_version = Version} = State0, Connection) ->
-
- case ssl_handshake:select_hashsign(HashSigns, Cert, KeyExAlg, SupportedHashSigns, Version) of
+ case ssl_handshake:select_hashsign(CertRequest, Cert, SupportedHashSigns, ssl:tls_version(Version)) of
#alert {} = Alert ->
- Connection:handle_own_alert(Alert, Version, certify, State0);
+ handle_own_alert(Alert, Version, certify, State0);
NegotiatedHashSign ->
{Record, State} = Connection:next_record(State0#state{client_certificate_requested = true}),
Connection:next_event(certify, Record,
@@ -555,7 +568,7 @@ certify(internal, #server_hello_done{},
when Alg == psk ->
case ssl_handshake:premaster_secret({Alg, PSKIdentity}, PSKLookup) of
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, certify, State0);
+ handle_own_alert(Alert, Version, certify, State0);
PremasterSecret ->
State = master_secret(PremasterSecret,
State0#state{premaster_secret = PremasterSecret}),
@@ -576,7 +589,7 @@ certify(internal, #server_hello_done{},
case ssl_handshake:premaster_secret({Alg, PSKIdentity}, PSKLookup,
RSAPremasterSecret) of
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, certify, State0);
+ handle_own_alert(Alert, Version, certify, State0);
PremasterSecret ->
State = master_secret(PremasterSecret,
State0#state{premaster_secret = RSAPremasterSecret}),
@@ -590,13 +603,13 @@ certify(internal, #server_hello_done{},
negotiated_version = Version,
premaster_secret = undefined,
role = client} = State0, Connection) ->
- case ssl_handshake:master_secret(record_cb(Connection), Version, Session,
+ case ssl_handshake:master_secret(ssl:tls_version(Version), Session,
ConnectionStates0, client) of
{MasterSecret, ConnectionStates} ->
State = State0#state{connection_states = ConnectionStates},
client_certify_and_key_exchange(State, Connection);
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, certify, State0)
+ handle_own_alert(Alert, Version, certify, State0)
end;
%% Master secret is calculated from premaster_secret
@@ -606,7 +619,7 @@ certify(internal, #server_hello_done{},
negotiated_version = Version,
premaster_secret = PremasterSecret,
role = client} = State0, Connection) ->
- case ssl_handshake:master_secret(record_cb(Connection), Version, PremasterSecret,
+ case ssl_handshake:master_secret(ssl:tls_version(Version), PremasterSecret,
ConnectionStates0, client) of
{MasterSecret, ConnectionStates} ->
Session = Session0#session{master_secret = MasterSecret},
@@ -614,7 +627,7 @@ certify(internal, #server_hello_done{},
session = Session},
client_certify_and_key_exchange(State, Connection);
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, certify, State0)
+ handle_own_alert(Alert, Version, certify, State0)
end;
certify(internal = Type, #client_key_exchange{} = Msg,
@@ -628,11 +641,11 @@ certify(internal = Type, #client_key_exchange{} = Msg,
certify(internal, #client_key_exchange{exchange_keys = Keys},
State = #state{key_algorithm = KeyAlg, negotiated_version = Version}, Connection) ->
try
- certify_client_key_exchange(ssl_handshake:decode_client_key(Keys, KeyAlg, Version),
+ certify_client_key_exchange(ssl_handshake:decode_client_key(Keys, KeyAlg, ssl:tls_version(Version)),
State, Connection)
catch
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, certify, State)
+ handle_own_alert(Alert, Version, certify, State)
end;
certify(Type, Msg, State, Connection) ->
@@ -663,21 +676,21 @@ cipher(internal, #certificate_verify{signature = Signature,
%% Use negotiated value if TLS-1.2 otherwhise return default
HashSign = negotiated_hashsign(CertHashSign, KexAlg, PublicKeyInfo, Version),
case ssl_handshake:certificate_verify(Signature, PublicKeyInfo,
- Version, HashSign, MasterSecret, Handshake) of
+ ssl:tls_version(Version), HashSign, MasterSecret, Handshake) of
valid ->
{Record, State} = Connection:next_record(State0),
Connection:next_event(cipher, Record,
State#state{cert_hashsign_algorithm = HashSign});
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, cipher, State0)
+ handle_own_alert(Alert, Version, cipher, State0)
end;
%% client must send a next protocol message if we are expecting it
cipher(internal, #finished{},
#state{role = server, expecting_next_protocol_negotiation = true,
negotiated_protocol = undefined, negotiated_version = Version} = State0,
- Connection) ->
- Connection:handle_own_alert(?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE), Version, cipher, State0);
+ _Connection) ->
+ handle_own_alert(?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE), Version, cipher, State0);
cipher(internal, #finished{verify_data = Data} = Finished,
#state{negotiated_version = Version,
@@ -689,7 +702,7 @@ cipher(internal, #finished{verify_data = Data} = Finished,
= Session0,
connection_states = ConnectionStates0,
tls_handshake_history = Handshake0} = State, Connection) ->
- case ssl_handshake:verify_connection(Version, Finished,
+ case ssl_handshake:verify_connection(ssl:tls_version(Version), Finished,
opposite_role(Role),
get_current_prf(ConnectionStates0, read),
MasterSecret, Handshake0) of
@@ -698,7 +711,7 @@ cipher(internal, #finished{verify_data = Data} = Finished,
cipher_role(Role, Data, Session,
State#state{expecting_finished = false}, Connection);
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, cipher, State)
+ handle_own_alert(Alert, Version, cipher, State)
end;
%% only allowed to send next_protocol message after change cipher spec
@@ -731,7 +744,7 @@ connection({call, From}, {application_data, Data},
%% parallize send and receive decoding and not block the receiver
%% if sending is overloading the socket.
try
- Connection:write_application_data(Data, From, State)
+ write_application_data(Data, From, State)
catch throw:Error ->
hibernate_after(connection, State, [{reply, From, Error}])
end;
@@ -748,14 +761,12 @@ connection({call, From}, renegotiate, #state{protocol_cb = Connection} = State,
connection({call, From}, peer_certificate,
#state{session = #session{peer_certificate = Cert}} = State, _) ->
hibernate_after(connection, State, [{reply, From, {ok, Cert}}]);
-connection({call, From}, connection_information, State, _) ->
+connection({call, From}, {connection_information, true}, State, _) ->
+ Info = connection_info(State) ++ security_info(State),
+ hibernate_after(connection, State, [{reply, From, {ok, Info}}]);
+connection({call, From}, {connection_information, false}, State, _) ->
Info = connection_info(State),
hibernate_after(connection, State, [{reply, From, {ok, Info}}]);
-connection({call, From}, session_info, #state{session = #session{session_id = Id,
- cipher_suite = Suite}} = State, _) ->
- SessionInfo = [{session_id, Id},
- {cipher_suite, ssl_cipher:erl_suite_definition(Suite)}],
- hibernate_after(connection, State, [{reply, From, SessionInfo}]);
connection({call, From}, negotiated_protocol,
#state{negotiated_protocol = undefined} = State, _) ->
hibernate_after(connection, State, [{reply, From, {error, protocol_not_negotiated}}]);
@@ -780,7 +791,7 @@ connection(Type, Msg, State, Connection) ->
downgrade(internal, #alert{description = ?CLOSE_NOTIFY},
#state{transport_cb = Transport, socket = Socket,
downgrade = {Pid, From}} = State, _) ->
- ssl_socket:setopts(Transport, Socket, [{active, false}, {packet, 0}, {mode, binary}]),
+ tls_socket:setopts(Transport, Socket, [{active, false}, {packet, 0}, {mode, binary}]),
Transport:controlling_process(Socket, Pid),
gen_statem:reply(From, {ok, Socket}),
{stop, normal, State};
@@ -802,35 +813,37 @@ handle_common_event(internal, {handshake, {#hello_request{}, _}}, StateName, #st
when StateName =/= connection ->
{keep_state_and_data};
handle_common_event(internal, {handshake, {Handshake, Raw}}, StateName,
- #state{tls_handshake_history = Hs0} = State0, Connection) ->
+ #state{tls_handshake_history = Hs0,
+ ssl_options = #ssl_options{v2_hello_compatible = V2HComp}} = State0,
+ Connection) ->
+
+ PossibleSNI = Connection:select_sni_extension(Handshake),
%% This function handles client SNI hello extension when Handshake is
%% a client_hello, which needs to be determined by the connection callback.
%% In other cases this is a noop
- State = Connection:handle_sni_extension(Handshake, State0),
- HsHist = ssl_handshake:update_handshake_history(Hs0, Raw),
+ State = handle_sni_extension(PossibleSNI, State0),
+ HsHist = ssl_handshake:update_handshake_history(Hs0, iolist_to_binary(Raw), V2HComp),
{next_state, StateName, State#state{tls_handshake_history = HsHist},
[{next_event, internal, Handshake}]};
-handle_common_event(internal, {tls_record, TLSRecord}, StateName, State, Connection) ->
- Connection:handle_common_event(internal, TLSRecord, StateName, State);
+handle_common_event(internal, {protocol_record, TLSorDTLSRecord}, StateName, State, Connection) ->
+ Connection:handle_common_event(internal, TLSorDTLSRecord, StateName, State);
handle_common_event(timeout, hibernate, _, _, _) ->
{keep_state_and_data, [hibernate]};
handle_common_event(internal, {application_data, Data}, StateName, State0, Connection) ->
- case Connection:read_application_data(Data, State0) of
+ case read_application_data(Data, State0) of
{stop, Reason, State} ->
{stop, Reason, State};
{Record, State} ->
Connection:next_event(StateName, Record, State)
end;
handle_common_event(internal, #change_cipher_spec{type = <<1>>}, StateName,
- #state{negotiated_version = Version} = State, Connection) ->
- Connection:handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), Version,
+ #state{negotiated_version = Version} = State, _) ->
+ handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), Version,
StateName, State);
-handle_common_event(internal, _, _, _, _) ->
- {keep_state_and_data, [postpone]};
handle_common_event(_Type, Msg, StateName, #state{negotiated_version = Version} = State,
- Connection) ->
+ _) ->
Alert = ?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE),
- Connection:handle_own_alert(Alert, Version, {StateName, Msg}, State).
+ handle_own_alert(Alert, Version, {StateName, Msg}, State).
handle_call({application_data, _Data}, _, _, _, _) ->
%% In renegotiation priorities handshake, send data when handshake is finished
@@ -843,24 +856,24 @@ handle_call({close, {Pid, Timeout}}, From, StateName, State0, Connection) when i
%% When downgrading an TLS connection to a transport connection
%% we must recive the close alert from the peer before releasing the
%% transport socket.
- {next_state, downgrade, State, [{timeout, Timeout, downgrade}]};
+ {next_state, downgrade, State#state{terminated = true}, [{timeout, Timeout, downgrade}]};
handle_call({close, _} = Close, From, StateName, State, Connection) ->
%% Run terminate before returning so that the reuseaddr
- %% inet-option
- Result = Connection:terminate(Close, StateName, State),
+ %% inet-option works properly
+ Result = Connection:terminate(Close, StateName, State#state{terminated = true}),
{stop_and_reply, {shutdown, normal},
{reply, From, Result}, State};
handle_call({shutdown, How0}, From, _,
#state{transport_cb = Transport,
negotiated_version = Version,
connection_states = ConnectionStates,
- socket = Socket}, _) ->
+ socket = Socket}, Connection) ->
case How0 of
How when How == write; How == both ->
Alert = ?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
{BinMsg, _} =
- ssl_alert:encode(Alert, Version, ConnectionStates),
- Transport:send(Socket, BinMsg);
+ Connection:encode_alert(Alert, Version, ConnectionStates),
+ Connection:send(Transport, Socket, BinMsg);
_ ->
ok
end,
@@ -892,14 +905,14 @@ handle_call({new_user, User}, From, StateName,
handle_call({get_opts, OptTags}, From, _,
#state{socket = Socket,
transport_cb = Transport,
- socket_options = SockOpts}, _) ->
- OptsReply = get_socket_opts(Transport, Socket, OptTags, SockOpts, []),
+ socket_options = SockOpts}, Connection) ->
+ OptsReply = get_socket_opts(Connection, Transport, Socket, OptTags, SockOpts, []),
{keep_state_and_data, [{reply, From, OptsReply}]};
handle_call({set_opts, Opts0}, From, StateName,
#state{socket_options = Opts1,
socket = Socket,
- transport_cb = Transport} = State0, _) ->
- {Reply, Opts} = set_socket_opts(Transport, Socket, Opts0, Opts1, []),
+ transport_cb = Transport} = State0, Connection) ->
+ {Reply, Opts} = set_socket_opts(Connection, Transport, Socket, Opts0, Opts1, []),
State = State0#state{socket_options = Opts},
handle_active_option(Opts#socket_options.active, StateName, From, Reply, State);
@@ -908,9 +921,8 @@ handle_call(renegotiate, From, StateName, _, _) when StateName =/= connection ->
handle_call({prf, Secret, Label, Seed, WantedLength}, From, _,
#state{connection_states = ConnectionStates,
negotiated_version = Version}, _) ->
- ConnectionState =
+ #{security_parameters := SecParams} =
ssl_record:current_connection_state(ConnectionStates, read),
- SecParams = ConnectionState#connection_state.security_parameters,
#security_parameters{master_secret = MasterSecret,
client_random = ClientRandom,
server_random = ServerRandom,
@@ -925,7 +937,7 @@ handle_call({prf, Secret, Label, Seed, WantedLength}, From, _,
(client_random, Acc) -> [ClientRandom|Acc];
(server_random, Acc) -> [ServerRandom|Acc]
end, [], Seed)),
- ssl_handshake:prf(Version, PRFAlgorithm, SecretToUse, Label, SeedToUse, WantedLength)
+ ssl_handshake:prf(ssl:tls_version(Version), PRFAlgorithm, SecretToUse, Label, SeedToUse, WantedLength)
catch
exit:_ -> {error, badarg};
error:Reason -> {error, Reason}
@@ -936,20 +948,19 @@ handle_call(_,_,_,_,_) ->
handle_info({ErrorTag, Socket, econnaborted}, StateName,
#state{socket = Socket, transport_cb = Transport,
- start_or_recv_from = StartFrom, role = Role,
protocol_cb = Connection,
+ start_or_recv_from = StartFrom, role = Role,
error_tag = ErrorTag,
tracker = Tracker} = State) when StateName =/= connection ->
- Connection:alert_user(Transport, Tracker,Socket,
- StartFrom, ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), Role),
+ alert_user(Transport, Tracker,Socket,
+ StartFrom, ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), Role, Connection),
{stop, normal, State};
handle_info({ErrorTag, Socket, Reason}, StateName, #state{socket = Socket,
- protocol_cb = Connection,
error_tag = ErrorTag} = State) ->
Report = io_lib:format("SSL: Socket error: ~p ~n", [Reason]),
error_logger:info_report(Report),
- Connection:handle_normal_shutdown(?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), StateName, State),
+ handle_normal_shutdown(?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), StateName, State),
{stop, normal, State};
handle_info({'DOWN', MonitorRef, _, _, _}, _,
@@ -991,7 +1002,10 @@ handle_info(Msg, StateName, #state{socket = Socket, error_tag = Tag} = State) ->
terminate(_, _, #state{terminated = true}) ->
%% Happens when user closes the connection using ssl:close/1
%% we want to guarantee that Transport:close has been called
- %% when ssl:close/1 returns.
+ %% when ssl:close/1 returns unless it is a downgrade where
+ %% we want to guarantee that close alert is received before
+ %% returning. In both cases terminate has been run manually
+ %% before run by gen_statem which will end up here
ok;
terminate({shutdown, transport_closed} = Reason,
@@ -1017,8 +1031,8 @@ terminate(Reason, connection, #state{negotiated_version = Version,
transport_cb = Transport, socket = Socket
} = State) ->
handle_trusted_certs_db(State),
- {BinAlert, ConnectionStates} = terminate_alert(Reason, Version, ConnectionStates0),
- Transport:send(Socket, BinAlert),
+ {BinAlert, ConnectionStates} = terminate_alert(Reason, Version, ConnectionStates0, Connection),
+ Connection:send(Transport, Socket, BinAlert),
Connection:close(Reason, Socket, Transport, ConnectionStates, Check);
terminate(Reason, _StateName, #state{transport_cb = Transport, protocol_cb = Connection,
@@ -1052,15 +1066,145 @@ format_status(terminate, [_, StateName, State]) ->
ssl_options = NewOptions,
flight_buffer = ?SECRET_PRINTOUT}
}}]}].
+
+%%--------------------------------------------------------------------
+%%%
+%%--------------------------------------------------------------------
+write_application_data(Data0, From,
+ #state{socket = Socket,
+ negotiated_version = Version,
+ protocol_cb = Connection,
+ transport_cb = Transport,
+ connection_states = ConnectionStates0,
+ socket_options = SockOpts,
+ ssl_options = #ssl_options{renegotiate_at = RenegotiateAt}} = State) ->
+ Data = encode_packet(Data0, SockOpts),
+
+ case time_to_renegotiate(Data, ConnectionStates0, RenegotiateAt) of
+ true ->
+ Connection:renegotiate(State#state{renegotiation = {true, internal}},
+ [{next_event, {call, From}, {application_data, Data0}}]);
+ false ->
+ {Msgs, ConnectionStates} = Connection:encode_data(Data, Version, ConnectionStates0),
+ Result = Connection:send(Transport, Socket, Msgs),
+ ssl_connection:hibernate_after(connection, State#state{connection_states = ConnectionStates},
+ [{reply, From, Result}])
+ end.
+
+read_application_data(Data, #state{user_application = {_Mon, Pid},
+ socket = Socket,
+ protocol_cb = Connection,
+ transport_cb = Transport,
+ socket_options = SOpts,
+ bytes_to_read = BytesToRead,
+ start_or_recv_from = RecvFrom,
+ timer = Timer,
+ user_data_buffer = Buffer0,
+ tracker = Tracker} = State0) ->
+ Buffer1 = if
+ Buffer0 =:= <<>> -> Data;
+ Data =:= <<>> -> Buffer0;
+ true -> <<Buffer0/binary, Data/binary>>
+ end,
+ case get_data(SOpts, BytesToRead, Buffer1) of
+ {ok, ClientData, Buffer} -> % Send data
+ SocketOpt = deliver_app_data(Transport, Socket, SOpts,
+ ClientData, Pid, RecvFrom, Tracker, Connection),
+ cancel_timer(Timer),
+ State = State0#state{user_data_buffer = Buffer,
+ start_or_recv_from = undefined,
+ timer = undefined,
+ bytes_to_read = undefined,
+ socket_options = SocketOpt
+ },
+ if
+ SocketOpt#socket_options.active =:= false; Buffer =:= <<>> ->
+ %% Passive mode, wait for active once or recv
+ %% Active and empty, get more data
+ Connection:next_record_if_active(State);
+ true -> %% We have more data
+ read_application_data(<<>>, State)
+ end;
+ {more, Buffer} -> % no reply, we need more data
+ Connection:next_record(State0#state{user_data_buffer = Buffer});
+ {passive, Buffer} ->
+ Connection:next_record_if_active(State0#state{user_data_buffer = Buffer});
+ {error,_Reason} -> %% Invalid packet in packet mode
+ deliver_packet_error(Transport, Socket, SOpts, Buffer1, Pid, RecvFrom, Tracker, Connection),
+ {stop, normal, State0}
+ end.
+%%--------------------------------------------------------------------
+%%%
+%%--------------------------------------------------------------------
+handle_alert(#alert{level = ?FATAL} = Alert, StateName,
+ #state{socket = Socket, transport_cb = Transport,
+ protocol_cb = Connection,
+ ssl_options = SslOpts, start_or_recv_from = From, host = Host,
+ port = Port, session = Session, user_application = {_Mon, Pid},
+ role = Role, socket_options = Opts, tracker = Tracker}) ->
+ invalidate_session(Role, Host, Port, Session),
+ log_alert(SslOpts#ssl_options.log_alert, StateName, Alert),
+ alert_user(Transport, Tracker, Socket, StateName, Opts, Pid, From, Alert, Role, Connection),
+ {stop, normal};
+
+handle_alert(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert,
+ StateName, State) ->
+ handle_normal_shutdown(Alert, StateName, State),
+ {stop, {shutdown, peer_close}};
+
+handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName,
+ #state{ssl_options = SslOpts, renegotiation = {true, internal}} = State) ->
+ log_alert(SslOpts#ssl_options.log_alert, StateName, Alert),
+ handle_normal_shutdown(Alert, StateName, State),
+ {stop, {shutdown, peer_close}};
+
+handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName,
+ #state{ssl_options = SslOpts, renegotiation = {true, From},
+ protocol_cb = Connection} = State0) ->
+ log_alert(SslOpts#ssl_options.log_alert, StateName, Alert),
+ gen_statem:reply(From, {error, renegotiation_rejected}),
+ {Record, State} = Connection:next_record(State0),
+ %% Go back to connection!
+ Connection:next_event(connection, Record, State);
+
+%% Gracefully log and ignore all other warning alerts
+handle_alert(#alert{level = ?WARNING} = Alert, StateName,
+ #state{ssl_options = SslOpts, protocol_cb = Connection} = State0) ->
+ log_alert(SslOpts#ssl_options.log_alert, StateName, Alert),
+ {Record, State} = Connection:next_record(State0),
+ Connection:next_event(StateName, Record, State).
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
connection_info(#state{sni_hostname = SNIHostname,
- session = #session{cipher_suite = CipherSuite},
- negotiated_version = Version, ssl_options = Opts}) ->
- [{protocol, tls_record:protocol_version(Version)},
- {cipher_suite, ssl_cipher:erl_suite_definition(CipherSuite)},
- {sni_hostname, SNIHostname}] ++ ssl_options_list(Opts).
+ session = #session{session_id = SessionId,
+ cipher_suite = CipherSuite, ecc = ECCCurve},
+ protocol_cb = Connection,
+ negotiated_version = {_,_} = Version,
+ ssl_options = Opts}) ->
+ RecordCB = record_cb(Connection),
+ CipherSuiteDef = ssl_cipher:erl_suite_definition(CipherSuite),
+ IsNamedCurveSuite = lists:member(element(1,CipherSuiteDef),
+ [ecdh_ecdsa, ecdhe_ecdsa, ecdh_anon]),
+ CurveInfo = case ECCCurve of
+ {namedCurve, Curve} when IsNamedCurveSuite ->
+ [{ecc, {named_curve, pubkey_cert_records:namedCurves(Curve)}}];
+ _ ->
+ []
+ end,
+ [{protocol, RecordCB:protocol_version(Version)},
+ {session_id, SessionId},
+ {cipher_suite, CipherSuiteDef},
+ {sni_hostname, SNIHostname} | CurveInfo] ++ ssl_options_list(Opts).
+
+security_info(#state{connection_states = ConnectionStates}) ->
+ #{security_parameters :=
+ #security_parameters{client_random = ClientRand,
+ server_random = ServerRand,
+ master_secret = MasterSecret}} =
+ ssl_record:current_connection_state(ConnectionStates, read),
+ [{client_random, ClientRand}, {server_random, ServerRand}, {master_secret, MasterSecret}].
do_server_hello(Type, #hello_extensions{next_protocol_negotiation = NextProtocols} =
ServerHelloExt,
@@ -1070,7 +1214,7 @@ do_server_hello(Type, #hello_extensions{next_protocol_negotiation = NextProtocol
= State0, Connection) when is_atom(Type) ->
ServerHello =
- ssl_handshake:server_hello(SessId, Version, ConnectionStates0, ServerHelloExt),
+ ssl_handshake:server_hello(SessId, ssl:tls_version(Version), ConnectionStates0, ServerHelloExt),
State = server_hello(ServerHello,
State0#state{expecting_next_protocol_negotiation =
NextProtocols =/= undefined}, Connection),
@@ -1088,33 +1232,33 @@ new_server_hello(#server_hello{cipher_suite = CipherSuite,
negotiated_version = Version} = State0, Connection) ->
try server_certify_and_key_exchange(State0, Connection) of
#state{} = State1 ->
- State2 = server_hello_done(State1, Connection),
+ {State2, Actions} = server_hello_done(State1, Connection),
Session =
Session0#session{session_id = SessionId,
cipher_suite = CipherSuite,
compression_method = Compression},
{Record, State} = Connection:next_record(State2#state{session = Session}),
- Connection:next_event(certify, Record, State)
+ Connection:next_event(certify, Record, State, Actions)
catch
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, hello, State0)
+ handle_own_alert(Alert, Version, hello, State0)
end.
resumed_server_hello(#state{session = Session,
connection_states = ConnectionStates0,
negotiated_version = Version} = State0, Connection) ->
- case ssl_handshake:master_secret(record_cb(Connection), Version, Session,
+ case ssl_handshake:master_secret(ssl:tls_version(Version), Session,
ConnectionStates0, server) of
{_, ConnectionStates1} ->
State1 = State0#state{connection_states = ConnectionStates1,
session = Session},
- State2 =
+ {State2, Actions} =
finalize_handshake(State1, abbreviated, Connection),
{Record, State} = Connection:next_record(State2),
- Connection:next_event(abbreviated, Record, State);
+ Connection:next_event(abbreviated, Record, State, Actions);
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, hello, State0)
+ handle_own_alert(Alert, Version, hello, State0)
end.
server_hello(ServerHello, State0, Connection) ->
@@ -1180,7 +1324,7 @@ verify_client_cert(#state{client_certificate_requested = true, role = client,
tls_handshake_history = Handshake0} = State, Connection) ->
case ssl_handshake:client_certificate_verify(OwnCert, MasterSecret,
- Version, HashSign, PrivateKey, Handshake0) of
+ ssl:tls_version(Version), HashSign, PrivateKey, Handshake0) of
#certificate_verify{} = Verified ->
Connection:queue_handshake(Verified, State);
ignore ->
@@ -1195,15 +1339,15 @@ client_certify_and_key_exchange(#state{negotiated_version = Version} =
State0, Connection) ->
try do_client_certify_and_key_exchange(State0, Connection) of
State1 = #state{} ->
- State2 = finalize_handshake(State1, certify, Connection),
+ {State2, Actions} = finalize_handshake(State1, certify, Connection),
State3 = State2#state{
%% Reinitialize
client_certificate_requested = false},
{Record, State} = Connection:next_record(State3),
- Connection:next_event(cipher, Record, State)
+ Connection:next_event(cipher, Record, State, Actions)
catch
throw:#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, certify, State0)
+ handle_own_alert(Alert, Version, certify, State0)
end.
do_client_certify_and_key_exchange(State0, Connection) ->
@@ -1294,12 +1438,11 @@ key_exchange(#state{role = server, key_algorithm = Algo,
Algo == dhe_rsa;
Algo == dh_anon ->
DHKeys = public_key:generate_key(Params),
- ConnectionState =
+ #{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates0, read),
- SecParams = ConnectionState#connection_state.security_parameters,
#security_parameters{client_random = ClientRandom,
server_random = ServerRandom} = SecParams,
- Msg = ssl_handshake:key_exchange(server, Version, {dh, DHKeys, Params,
+ Msg = ssl_handshake:key_exchange(server, ssl:tls_version(Version), {dh, DHKeys, Params,
HashSignAlgo, ClientRandom,
ServerRandom,
PrivateKey}),
@@ -1312,22 +1455,23 @@ key_exchange(#state{role = server, private_key = Key, key_algorithm = Algo} = St
key_exchange(#state{role = server, key_algorithm = Algo,
hashsign_algorithm = HashSignAlgo,
private_key = PrivateKey,
+ session = #session{ecc = ECCCurve},
connection_states = ConnectionStates0,
negotiated_version = Version
} = State0, Connection)
when Algo == ecdhe_ecdsa; Algo == ecdhe_rsa;
Algo == ecdh_anon ->
- ECDHKeys = public_key:generate_key(select_curve(State0)),
- ConnectionState =
+ ECDHKeys = public_key:generate_key(ECCCurve),
+ #{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates0, read),
- SecParams = ConnectionState#connection_state.security_parameters,
#security_parameters{client_random = ClientRandom,
server_random = ServerRandom} = SecParams,
- Msg = ssl_handshake:key_exchange(server, Version, {ecdh, ECDHKeys,
- HashSignAlgo, ClientRandom,
- ServerRandom,
- PrivateKey}),
+ Msg = ssl_handshake:key_exchange(server, ssl:tls_version(Version),
+ {ecdh, ECDHKeys,
+ HashSignAlgo, ClientRandom,
+ ServerRandom,
+ PrivateKey}),
State = Connection:queue_handshake(Msg, State0),
State#state{diffie_hellman_keys = ECDHKeys};
@@ -1341,14 +1485,14 @@ key_exchange(#state{role = server, key_algorithm = psk,
connection_states = ConnectionStates0,
negotiated_version = Version
} = State0, Connection) ->
- ConnectionState =
+ #{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates0, read),
- SecParams = ConnectionState#connection_state.security_parameters,
#security_parameters{client_random = ClientRandom,
server_random = ServerRandom} = SecParams,
- Msg = ssl_handshake:key_exchange(server, Version, {psk, PskIdentityHint,
- HashSignAlgo, ClientRandom,
- ServerRandom,
+ Msg = ssl_handshake:key_exchange(server, ssl:tls_version(Version),
+ {psk, PskIdentityHint,
+ HashSignAlgo, ClientRandom,
+ ServerRandom,
PrivateKey}),
Connection:queue_handshake(Msg, State0);
@@ -1361,16 +1505,16 @@ key_exchange(#state{role = server, key_algorithm = dhe_psk,
negotiated_version = Version
} = State0, Connection) ->
DHKeys = public_key:generate_key(Params),
- ConnectionState =
+ #{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates0, read),
- SecParams = ConnectionState#connection_state.security_parameters,
#security_parameters{client_random = ClientRandom,
server_random = ServerRandom} = SecParams,
- Msg = ssl_handshake:key_exchange(server, Version, {dhe_psk,
- PskIdentityHint, DHKeys, Params,
- HashSignAlgo, ClientRandom,
- ServerRandom,
- PrivateKey}),
+ Msg = ssl_handshake:key_exchange(server, ssl:tls_version(Version),
+ {dhe_psk,
+ PskIdentityHint, DHKeys, Params,
+ HashSignAlgo, ClientRandom,
+ ServerRandom,
+ PrivateKey}),
State = Connection:queue_handshake(Msg, State0),
State#state{diffie_hellman_keys = DHKeys};
@@ -1384,15 +1528,15 @@ key_exchange(#state{role = server, key_algorithm = rsa_psk,
connection_states = ConnectionStates0,
negotiated_version = Version
} = State0, Connection) ->
- ConnectionState =
+ #{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates0, read),
- SecParams = ConnectionState#connection_state.security_parameters,
#security_parameters{client_random = ClientRandom,
server_random = ServerRandom} = SecParams,
- Msg = ssl_handshake:key_exchange(server, Version, {psk, PskIdentityHint,
- HashSignAlgo, ClientRandom,
- ServerRandom,
- PrivateKey}),
+ Msg = ssl_handshake:key_exchange(server, ssl:tls_version(Version),
+ {psk, PskIdentityHint,
+ HashSignAlgo, ClientRandom,
+ ServerRandom,
+ PrivateKey}),
Connection:queue_handshake(Msg, State0);
key_exchange(#state{role = server, key_algorithm = Algo,
@@ -1413,15 +1557,15 @@ key_exchange(#state{role = server, key_algorithm = Algo,
Keys0 = {_,_} ->
Keys0
end,
- ConnectionState =
+ #{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates0, read),
- SecParams = ConnectionState#connection_state.security_parameters,
#security_parameters{client_random = ClientRandom,
server_random = ServerRandom} = SecParams,
- Msg = ssl_handshake:key_exchange(server, Version, {srp, Keys, SrpParams,
- HashSignAlgo, ClientRandom,
- ServerRandom,
- PrivateKey}),
+ Msg = ssl_handshake:key_exchange(server, ssl:tls_version(Version),
+ {srp, Keys, SrpParams,
+ HashSignAlgo, ClientRandom,
+ ServerRandom,
+ PrivateKey}),
State = Connection:queue_handshake(Msg, State0),
State#state{srp_params = SrpParams,
srp_keys = Keys};
@@ -1431,7 +1575,7 @@ key_exchange(#state{role = client,
public_key_info = PublicKeyInfo,
negotiated_version = Version,
premaster_secret = PremasterSecret} = State0, Connection) ->
- Msg = rsa_key_exchange(Version, PremasterSecret, PublicKeyInfo),
+ Msg = rsa_key_exchange(ssl:tls_version(Version), PremasterSecret, PublicKeyInfo),
Connection:queue_handshake(Msg, State0);
key_exchange(#state{role = client,
@@ -1442,7 +1586,7 @@ key_exchange(#state{role = client,
when Algorithm == dhe_dss;
Algorithm == dhe_rsa;
Algorithm == dh_anon ->
- Msg = ssl_handshake:key_exchange(client, Version, {dh, DhPubKey}),
+ Msg = ssl_handshake:key_exchange(client, ssl:tls_version(Version), {dh, DhPubKey}),
Connection:queue_handshake(Msg, State0);
key_exchange(#state{role = client,
@@ -1452,14 +1596,14 @@ key_exchange(#state{role = client,
when Algorithm == ecdhe_ecdsa; Algorithm == ecdhe_rsa;
Algorithm == ecdh_ecdsa; Algorithm == ecdh_rsa;
Algorithm == ecdh_anon ->
- Msg = ssl_handshake:key_exchange(client, Version, {ecdh, Keys}),
+ Msg = ssl_handshake:key_exchange(client, ssl:tls_version(Version), {ecdh, Keys}),
Connection:queue_handshake(Msg, State0);
key_exchange(#state{role = client,
ssl_options = SslOpts,
key_algorithm = psk,
negotiated_version = Version} = State0, Connection) ->
- Msg = ssl_handshake:key_exchange(client, Version,
+ Msg = ssl_handshake:key_exchange(client, ssl:tls_version(Version),
{psk, SslOpts#ssl_options.psk_identity}),
Connection:queue_handshake(Msg, State0);
@@ -1468,7 +1612,7 @@ key_exchange(#state{role = client,
key_algorithm = dhe_psk,
negotiated_version = Version,
diffie_hellman_keys = {DhPubKey, _}} = State0, Connection) ->
- Msg = ssl_handshake:key_exchange(client, Version,
+ Msg = ssl_handshake:key_exchange(client, ssl:tls_version(Version),
{dhe_psk,
SslOpts#ssl_options.psk_identity, DhPubKey}),
Connection:queue_handshake(Msg, State0);
@@ -1479,7 +1623,7 @@ key_exchange(#state{role = client,
negotiated_version = Version,
premaster_secret = PremasterSecret}
= State0, Connection) ->
- Msg = rsa_psk_key_exchange(Version, SslOpts#ssl_options.psk_identity,
+ Msg = rsa_psk_key_exchange(ssl:tls_version(Version), SslOpts#ssl_options.psk_identity,
PremasterSecret, PublicKeyInfo),
Connection:queue_handshake(Msg, State0);
@@ -1491,7 +1635,7 @@ key_exchange(#state{role = client,
when Algorithm == srp_dss;
Algorithm == srp_rsa;
Algorithm == srp_anon ->
- Msg = ssl_handshake:key_exchange(client, Version, {srp, ClientPubKey}),
+ Msg = ssl_handshake:key_exchange(client, ssl:tls_version(Version), {srp, ClientPubKey}),
Connection:queue_handshake(Msg, State0).
rsa_key_exchange(Version, PremasterSecret, PublicKeyInfo = {Algorithm, _, _})
@@ -1504,7 +1648,7 @@ rsa_key_exchange(Version, PremasterSecret, PublicKeyInfo = {Algorithm, _, _})
Algorithm == ?sha384WithRSAEncryption;
Algorithm == ?sha512WithRSAEncryption
->
- ssl_handshake:key_exchange(client, Version,
+ ssl_handshake:key_exchange(client, ssl:tls_version(Version),
{premaster_secret, PremasterSecret,
PublicKeyInfo});
rsa_key_exchange(_, _, _) ->
@@ -1521,7 +1665,7 @@ rsa_psk_key_exchange(Version, PskIdentity, PremasterSecret,
Algorithm == ?sha384WithRSAEncryption;
Algorithm == ?sha512WithRSAEncryption
->
- ssl_handshake:key_exchange(client, Version,
+ ssl_handshake:key_exchange(client, ssl:tls_version(Version),
{psk_premaster_secret, PskIdentity, PremasterSecret,
PublicKeyInfo});
rsa_psk_key_exchange(_, _, _, _) ->
@@ -1533,12 +1677,14 @@ request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer,
cert_db = CertDbHandle,
cert_db_ref = CertDbRef,
negotiated_version = Version} = State0, Connection) ->
- #connection_state{security_parameters =
- #security_parameters{cipher_suite = CipherSuite}} =
+ #{security_parameters :=
+ #security_parameters{cipher_suite = CipherSuite}} =
ssl_record:pending_connection_state(ConnectionStates0, read),
- HashSigns = ssl_handshake:available_signature_algs(SupportedHashSigns, Version, [Version]),
+ TLSVersion = ssl:tls_version(Version),
+ HashSigns = ssl_handshake:available_signature_algs(SupportedHashSigns,
+ TLSVersion),
Msg = ssl_handshake:certificate_request(CipherSuite, CertDbHandle, CertDbRef,
- HashSigns, Version),
+ HashSigns, TLSVersion),
State = Connection:queue_handshake(Msg, State0),
State#state{client_certificate_requested = true};
@@ -1551,7 +1697,7 @@ calculate_master_secret(PremasterSecret,
connection_states = ConnectionStates0,
session = Session0} = State0, Connection,
_Current, Next) ->
- case ssl_handshake:master_secret(record_cb(Connection), Version, PremasterSecret,
+ case ssl_handshake:master_secret(ssl:tls_version(Version), PremasterSecret,
ConnectionStates0, server) of
{MasterSecret, ConnectionStates} ->
Session = Session0#session{master_secret = MasterSecret},
@@ -1560,7 +1706,7 @@ calculate_master_secret(PremasterSecret,
{Record, State} = Connection:next_record(State1),
Connection:next_event(Next, Record, State);
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, certify, State0)
+ handle_own_alert(Alert, Version, certify, State0)
end.
finalize_handshake(State0, StateName, Connection) ->
@@ -1593,7 +1739,7 @@ finished(#state{role = Role, negotiated_version = Version,
connection_states = ConnectionStates0,
tls_handshake_history = Handshake0} = State0, StateName, Connection) ->
MasterSecret = Session#session.master_secret,
- Finished = ssl_handshake:finished(Version, Role,
+ Finished = ssl_handshake:finished(ssl:tls_version(Version), Role,
get_current_prf(ConnectionStates0, write),
MasterSecret, Handshake0),
ConnectionStates = save_verify_data(Role, Finished, ConnectionStates0, StateName),
@@ -1620,12 +1766,13 @@ calculate_secret(#server_dh_params{dh_p = Prime, dh_g = Base,
Connection, certify, certify);
calculate_secret(#server_ecdh_params{curve = ECCurve, public = ECServerPubKey},
- State, Connection) ->
+ State=#state{session=Session}, Connection) ->
ECDHKeys = public_key:generate_key(ECCurve),
PremasterSecret =
ssl_handshake:premaster_secret(#'ECPoint'{point = ECServerPubKey}, ECDHKeys),
calculate_master_secret(PremasterSecret,
- State#state{diffie_hellman_keys = ECDHKeys},
+ State#state{diffie_hellman_keys = ECDHKeys,
+ session = Session#session{ecc = ECCurve}},
Connection, certify, certify);
calculate_secret(#server_psk_params{
@@ -1658,7 +1805,7 @@ master_secret(#alert{} = Alert, _) ->
master_secret(PremasterSecret, #state{session = Session,
negotiated_version = Version, role = Role,
connection_states = ConnectionStates0} = State) ->
- case ssl_handshake:master_secret(tls_record, Version, PremasterSecret,
+ case ssl_handshake:master_secret(ssl:tls_version(Version), PremasterSecret,
ConnectionStates0, Role) of
{MasterSecret, ConnectionStates} ->
State#state{
@@ -1719,16 +1866,11 @@ cipher_role(server, Data, Session, #state{connection_states = ConnectionStates0
Connection) ->
ConnectionStates1 = ssl_record:set_client_verify_data(current_read, Data,
ConnectionStates0),
- State1 =
+ {State1, Actions} =
finalize_handshake(State0#state{connection_states = ConnectionStates1,
session = Session}, cipher, Connection),
{Record, State} = prepare_connection(State1, Connection),
- Connection:next_event(connection, Record, State).
-
-select_curve(#state{client_ecc = {[Curve|_], _}}) ->
- {namedCurve, Curve};
-select_curve(_) ->
- {namedCurve, ?secp256r1}.
+ Connection:next_event(connection, Record, State, Actions).
is_anonymous(Algo) when Algo == dh_anon;
Algo == ecdh_anon;
@@ -1741,11 +1883,11 @@ is_anonymous(_) ->
false.
get_current_prf(CStates, Direction) ->
- CS = ssl_record:current_connection_state(CStates, Direction),
- CS#connection_state.security_parameters#security_parameters.prf_algorithm.
+ #{security_parameters := SecParams} = ssl_record:current_connection_state(CStates, Direction),
+ SecParams#security_parameters.prf_algorithm.
get_pending_prf(CStates, Direction) ->
- CS = ssl_record:pending_connection_state(CStates, Direction),
- CS#connection_state.security_parameters#security_parameters.prf_algorithm.
+ #{security_parameters := SecParams} = ssl_record:pending_connection_state(CStates, Direction),
+ SecParams#security_parameters.prf_algorithm.
opposite_role(client) ->
server;
@@ -1768,42 +1910,39 @@ call(FsmPid, Event) ->
{error, closed}
end.
-get_socket_opts(_,_,[], _, Acc) ->
+get_socket_opts(_, _,_,[], _, Acc) ->
{ok, Acc};
-get_socket_opts(Transport, Socket, [mode | Tags], SockOpts, Acc) ->
- get_socket_opts(Transport, Socket, Tags, SockOpts,
+get_socket_opts(Connection, Transport, Socket, [mode | Tags], SockOpts, Acc) ->
+ get_socket_opts(Connection, Transport, Socket, Tags, SockOpts,
[{mode, SockOpts#socket_options.mode} | Acc]);
-get_socket_opts(Transport, Socket, [packet | Tags], SockOpts, Acc) ->
+get_socket_opts(Connection, Transport, Socket, [packet | Tags], SockOpts, Acc) ->
case SockOpts#socket_options.packet of
{Type, headers} ->
- get_socket_opts(Transport, Socket, Tags, SockOpts, [{packet, Type} | Acc]);
+ get_socket_opts(Connection, Transport, Socket, Tags, SockOpts, [{packet, Type} | Acc]);
Type ->
- get_socket_opts(Transport, Socket, Tags, SockOpts, [{packet, Type} | Acc])
+ get_socket_opts(Connection, Transport, Socket, Tags, SockOpts, [{packet, Type} | Acc])
end;
-get_socket_opts(Transport, Socket, [header | Tags], SockOpts, Acc) ->
- get_socket_opts(Transport, Socket, Tags, SockOpts,
+get_socket_opts(Connection, Transport, Socket, [header | Tags], SockOpts, Acc) ->
+ get_socket_opts(Connection, Transport, Socket, Tags, SockOpts,
[{header, SockOpts#socket_options.header} | Acc]);
-get_socket_opts(Transport, Socket, [active | Tags], SockOpts, Acc) ->
- get_socket_opts(Transport, Socket, Tags, SockOpts,
+get_socket_opts(Connection, Transport, Socket, [active | Tags], SockOpts, Acc) ->
+ get_socket_opts(Connection, Transport, Socket, Tags, SockOpts,
[{active, SockOpts#socket_options.active} | Acc]);
-get_socket_opts(Transport, Socket, [Tag | Tags], SockOpts, Acc) ->
- try ssl_socket:getopts(Transport, Socket, [Tag]) of
- {ok, [Opt]} ->
- get_socket_opts(Transport, Socket, Tags, SockOpts, [Opt | Acc]);
- {error, Error} ->
- {error, {options, {socket_options, Tag, Error}}}
- catch
- %% So that inet behavior does not crash our process
- _:Error -> {error, {options, {socket_options, Tag, Error}}}
+get_socket_opts(Connection, Transport, Socket, [Tag | Tags], SockOpts, Acc) ->
+ case Connection:getopts(Transport, Socket, [Tag]) of
+ {ok, [Opt]} ->
+ get_socket_opts(Connection, Transport, Socket, Tags, SockOpts, [Opt | Acc]);
+ {error, Reason} ->
+ {error, {options, {socket_options, Tag, Reason}}}
end;
-get_socket_opts(_, _,Opts, _,_) ->
+get_socket_opts(_,_, _,Opts, _,_) ->
{error, {options, {socket_options, Opts, function_clause}}}.
-set_socket_opts(_,_, [], SockOpts, []) ->
+set_socket_opts(_,_,_, [], SockOpts, []) ->
{ok, SockOpts};
-set_socket_opts(Transport, Socket, [], SockOpts, Other) ->
+set_socket_opts(ConnectionCb, Transport, Socket, [], SockOpts, Other) ->
%% Set non emulated options
- try ssl_socket:setopts(Transport, Socket, Other) of
+ try ConnectionCb:setopts(Transport, Socket, Other) of
ok ->
{ok, SockOpts};
{error, InetError} ->
@@ -1814,13 +1953,13 @@ set_socket_opts(Transport, Socket, [], SockOpts, Other) ->
{{error, {options, {socket_options, Other, Error}}}, SockOpts}
end;
-set_socket_opts(Transport,Socket, [{mode, Mode}| Opts], SockOpts, Other)
+set_socket_opts(ConnectionCb, Transport,Socket, [{mode, Mode}| Opts], SockOpts, Other)
when Mode == list; Mode == binary ->
- set_socket_opts(Transport, Socket, Opts,
+ set_socket_opts(ConnectionCb, Transport, Socket, Opts,
SockOpts#socket_options{mode = Mode}, Other);
-set_socket_opts(_, _, [{mode, _} = Opt| _], SockOpts, _) ->
+set_socket_opts(_, _, _, [{mode, _} = Opt| _], SockOpts, _) ->
{{error, {options, {socket_options, Opt}}}, SockOpts};
-set_socket_opts(Transport,Socket, [{packet, Packet}| Opts], SockOpts, Other)
+set_socket_opts(ConnectionCb, Transport,Socket, [{packet, Packet}| Opts], SockOpts, Other)
when Packet == raw;
Packet == 0;
Packet == 1;
@@ -1836,26 +1975,26 @@ set_socket_opts(Transport,Socket, [{packet, Packet}| Opts], SockOpts, Other)
Packet == httph;
Packet == http_bin;
Packet == httph_bin ->
- set_socket_opts(Transport, Socket, Opts,
+ set_socket_opts(ConnectionCb, Transport, Socket, Opts,
SockOpts#socket_options{packet = Packet}, Other);
-set_socket_opts(_, _, [{packet, _} = Opt| _], SockOpts, _) ->
+set_socket_opts(_, _, _, [{packet, _} = Opt| _], SockOpts, _) ->
{{error, {options, {socket_options, Opt}}}, SockOpts};
-set_socket_opts(Transport, Socket, [{header, Header}| Opts], SockOpts, Other)
+set_socket_opts(ConnectionCb, Transport, Socket, [{header, Header}| Opts], SockOpts, Other)
when is_integer(Header) ->
- set_socket_opts(Transport, Socket, Opts,
+ set_socket_opts(ConnectionCb, Transport, Socket, Opts,
SockOpts#socket_options{header = Header}, Other);
-set_socket_opts(_, _, [{header, _} = Opt| _], SockOpts, _) ->
+set_socket_opts(_, _, _, [{header, _} = Opt| _], SockOpts, _) ->
{{error,{options, {socket_options, Opt}}}, SockOpts};
-set_socket_opts(Transport, Socket, [{active, Active}| Opts], SockOpts, Other)
+set_socket_opts(ConnectionCb, Transport, Socket, [{active, Active}| Opts], SockOpts, Other)
when Active == once;
Active == true;
Active == false ->
- set_socket_opts(Transport, Socket, Opts,
+ set_socket_opts(ConnectionCb, Transport, Socket, Opts,
SockOpts#socket_options{active = Active}, Other);
-set_socket_opts(_, _, [{active, _} = Opt| _], SockOpts, _) ->
+set_socket_opts(_,_, _, [{active, _} = Opt| _], SockOpts, _) ->
{{error, {options, {socket_options, Opt}} }, SockOpts};
-set_socket_opts(Transport, Socket, [Opt | Opts], SockOpts, Other) ->
- set_socket_opts(Transport, Socket, Opts, SockOpts, [Opt | Other]).
+set_socket_opts(ConnectionCb, Transport, Socket, [Opt | Opts], SockOpts, Other) ->
+ set_socket_opts(ConnectionCb, Transport, Socket, Opts, SockOpts, [Opt | Other]).
start_or_recv_cancel_timer(infinity, _RecvFrom) ->
undefined;
@@ -1869,17 +2008,17 @@ hibernate_after(connection = StateName,
hibernate_after(StateName, State, Actions) ->
{next_state, StateName, State, Actions}.
-terminate_alert(normal, Version, ConnectionStates) ->
- ssl_alert:encode(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
+terminate_alert(normal, Version, ConnectionStates, Connection) ->
+ Connection:encode_alert(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
Version, ConnectionStates);
-terminate_alert({Reason, _}, Version, ConnectionStates) when Reason == close;
- Reason == shutdown ->
- ssl_alert:encode(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
+terminate_alert({Reason, _}, Version, ConnectionStates, Connection) when Reason == close;
+ Reason == shutdown ->
+ Connection:encode_alert(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
Version, ConnectionStates);
-terminate_alert(_, Version, ConnectionStates) ->
- {BinAlert, _} = ssl_alert:encode(?ALERT_REC(?FATAL, ?INTERNAL_ERROR),
- Version, ConnectionStates),
+terminate_alert(_, Version, ConnectionStates, Connection) ->
+ {BinAlert, _} = Connection:encode_alert(?ALERT_REC(?FATAL, ?INTERNAL_ERROR),
+ Version, ConnectionStates),
BinAlert.
handle_trusted_certs_db(#state{ssl_options =
@@ -1967,7 +2106,7 @@ handle_resumed_session(SessId, #state{connection_states = ConnectionStates0,
session_cache = Cache,
session_cache_cb = CacheCb} = State0) ->
Session = CacheCb:lookup(Cache, {{Host, Port}, SessId}),
- case ssl_handshake:master_secret(tls_record, Version, Session,
+ case ssl_handshake:master_secret(ssl:tls_version(Version), Session,
ConnectionStates0, client) of
{_, ConnectionStates} ->
{Record, State} =
@@ -1976,7 +2115,7 @@ handle_resumed_session(SessId, #state{connection_states = ConnectionStates0,
session = Session}),
Connection:next_event(abbreviated, Record, State);
#alert{} = Alert ->
- Connection:handle_own_alert(Alert, Version, hello, State0)
+ handle_own_alert(Alert, Version, hello, State0)
end.
make_premaster_secret({MajVer, MinVer}, rsa) ->
@@ -2043,7 +2182,7 @@ handle_active_option(_, StateName, To, Reply, #state{user_data_buffer = <<>>} =
%% user_data_buffer =/= <<>>
handle_active_option(_, StateName0, To, Reply, #state{protocol_cb = Connection} = State0) ->
- case Connection:read_application_data(<<>>, State0) of
+ case read_application_data(<<>>, State0) of
{stop, Reason, State} ->
{stop, Reason, State};
{Record, State1} ->
@@ -2057,3 +2196,277 @@ handle_active_option(_, StateName0, To, Reply, #state{protocol_cb = Connection}
Stop
end
end.
+
+encode_packet(Data, #socket_options{packet=Packet}) ->
+ case Packet of
+ 1 -> encode_size_packet(Data, 8, (1 bsl 8) - 1);
+ 2 -> encode_size_packet(Data, 16, (1 bsl 16) - 1);
+ 4 -> encode_size_packet(Data, 32, (1 bsl 32) - 1);
+ _ -> Data
+ end.
+
+encode_size_packet(Bin, Size, Max) ->
+ Len = erlang:byte_size(Bin),
+ case Len > Max of
+ true -> throw({error, {badarg, {packet_to_large, Len, Max}}});
+ false -> <<Len:Size, Bin/binary>>
+ end.
+
+time_to_renegotiate(_Data,
+ #{current_write := #{sequence_number := Num}},
+ RenegotiateAt) ->
+
+ %% We could do test:
+ %% is_time_to_renegotiate((erlang:byte_size(_Data) div ?MAX_PLAIN_TEXT_LENGTH) + 1, RenegotiateAt),
+ %% but we chose to have a some what lower renegotiateAt and a much cheaper test
+ is_time_to_renegotiate(Num, RenegotiateAt).
+
+is_time_to_renegotiate(N, M) when N < M->
+ false;
+is_time_to_renegotiate(_,_) ->
+ true.
+
+
+%% Picks ClientData
+get_data(_, _, <<>>) ->
+ {more, <<>>};
+%% Recv timed out save buffer data until next recv
+get_data(#socket_options{active=false}, undefined, Buffer) ->
+ {passive, Buffer};
+get_data(#socket_options{active=Active, packet=Raw}, BytesToRead, Buffer)
+ when Raw =:= raw; Raw =:= 0 -> %% Raw Mode
+ if
+ Active =/= false orelse BytesToRead =:= 0 ->
+ %% Active true or once, or passive mode recv(0)
+ {ok, Buffer, <<>>};
+ byte_size(Buffer) >= BytesToRead ->
+ %% Passive Mode, recv(Bytes)
+ <<Data:BytesToRead/binary, Rest/binary>> = Buffer,
+ {ok, Data, Rest};
+ true ->
+ %% Passive Mode not enough data
+ {more, Buffer}
+ end;
+get_data(#socket_options{packet=Type, packet_size=Size}, _, Buffer) ->
+ PacketOpts = [{packet_size, Size}],
+ case decode_packet(Type, Buffer, PacketOpts) of
+ {more, _} ->
+ {more, Buffer};
+ Decoded ->
+ Decoded
+ end.
+
+decode_packet({http, headers}, Buffer, PacketOpts) ->
+ decode_packet(httph, Buffer, PacketOpts);
+decode_packet({http_bin, headers}, Buffer, PacketOpts) ->
+ decode_packet(httph_bin, Buffer, PacketOpts);
+decode_packet(Type, Buffer, PacketOpts) ->
+ erlang:decode_packet(Type, Buffer, PacketOpts).
+
+%% Just like with gen_tcp sockets, an ssl socket that has been configured with
+%% {packet, http} (or {packet, http_bin}) will automatically switch to expect
+%% HTTP headers after it sees a HTTP Request or HTTP Response line. We
+%% represent the current state as follows:
+%% #socket_options.packet =:= http: Expect a HTTP Request/Response line
+%% #socket_options.packet =:= {http, headers}: Expect HTTP Headers
+%% Note that if the user has explicitly configured the socket to expect
+%% HTTP headers using the {packet, httph} option, we don't do any automatic
+%% switching of states.
+deliver_app_data(Transport, Socket, SOpts = #socket_options{active=Active, packet=Type},
+ Data, Pid, From, Tracker, Connection) ->
+ send_or_reply(Active, Pid, From, format_reply(Transport, Socket, SOpts, Data, Tracker, Connection)),
+ SO = case Data of
+ {P, _, _, _} when ((P =:= http_request) or (P =:= http_response)),
+ ((Type =:= http) or (Type =:= http_bin)) ->
+ SOpts#socket_options{packet={Type, headers}};
+ http_eoh when tuple_size(Type) =:= 2 ->
+ % End of headers - expect another Request/Response line
+ {Type1, headers} = Type,
+ SOpts#socket_options{packet=Type1};
+ _ ->
+ SOpts
+ end,
+ case Active of
+ once ->
+ SO#socket_options{active=false};
+ _ ->
+ SO
+ end.
+
+format_reply(_, _,#socket_options{active = false, mode = Mode, packet = Packet,
+ header = Header}, Data, _, _) ->
+ {ok, do_format_reply(Mode, Packet, Header, Data)};
+format_reply(Transport, Socket, #socket_options{active = _, mode = Mode, packet = Packet,
+ header = Header}, Data, Tracker, Connection) ->
+ {ssl, Connection:socket(self(), Transport, Socket, Connection, Tracker),
+ do_format_reply(Mode, Packet, Header, Data)}.
+
+deliver_packet_error(Transport, Socket, SO= #socket_options{active = Active}, Data, Pid, From, Tracker, Connection) ->
+ send_or_reply(Active, Pid, From, format_packet_error(Transport, Socket, SO, Data, Tracker, Connection)).
+
+format_packet_error(_, _,#socket_options{active = false, mode = Mode}, Data, _, _) ->
+ {error, {invalid_packet, do_format_reply(Mode, raw, 0, Data)}};
+format_packet_error(Transport, Socket, #socket_options{active = _, mode = Mode}, Data, Tracker, Connection) ->
+ {ssl_error, Connection:socket(self(), Transport, Socket, Connection, Tracker),
+ {invalid_packet, do_format_reply(Mode, raw, 0, Data)}}.
+
+do_format_reply(binary, _, N, Data) when N > 0 -> % Header mode
+ header(N, Data);
+do_format_reply(binary, _, _, Data) ->
+ Data;
+do_format_reply(list, Packet, _, Data)
+ when Packet == http; Packet == {http, headers};
+ Packet == http_bin; Packet == {http_bin, headers};
+ Packet == httph; Packet == httph_bin ->
+ Data;
+do_format_reply(list, _,_, Data) ->
+ binary_to_list(Data).
+
+header(0, <<>>) ->
+ <<>>;
+header(_, <<>>) ->
+ [];
+header(0, Binary) ->
+ Binary;
+header(N, Binary) ->
+ <<?BYTE(ByteN), NewBinary/binary>> = Binary,
+ [ByteN | header(N-1, NewBinary)].
+
+send_or_reply(false, _Pid, From, Data) when From =/= undefined ->
+ gen_statem:reply(From, Data);
+%% Can happen when handling own alert or tcp error/close and there is
+%% no outstanding gen_fsm sync events
+send_or_reply(false, no_pid, _, _) ->
+ ok;
+send_or_reply(_, Pid, _From, Data) ->
+ send_user(Pid, Data).
+
+send_user(Pid, Msg) ->
+ Pid ! Msg.
+
+alert_user(Transport, Tracker, Socket, connection, Opts, Pid, From, Alert, Role, Connection) ->
+ alert_user(Transport, Tracker, Socket, Opts#socket_options.active, Pid, From, Alert, Role, Connection);
+alert_user(Transport, Tracker, Socket,_, _, _, From, Alert, Role, Connection) ->
+ alert_user(Transport, Tracker, Socket, From, Alert, Role, Connection).
+
+alert_user(Transport, Tracker, Socket, From, Alert, Role, Connection) ->
+ alert_user(Transport, Tracker, Socket, false, no_pid, From, Alert, Role, Connection).
+
+alert_user(_, _, _, false = Active, Pid, From, Alert, Role, _) when From =/= undefined ->
+ %% If there is an outstanding ssl_accept | recv
+ %% From will be defined and send_or_reply will
+ %% send the appropriate error message.
+ ReasonCode = ssl_alert:reason_code(Alert, Role),
+ send_or_reply(Active, Pid, From, {error, ReasonCode});
+alert_user(Transport, Tracker, Socket, Active, Pid, From, Alert, Role, Connection) ->
+ case ssl_alert:reason_code(Alert, Role) of
+ closed ->
+ send_or_reply(Active, Pid, From,
+ {ssl_closed, Connection:socket(self(),
+ Transport, Socket, Connection, Tracker)});
+ ReasonCode ->
+ send_or_reply(Active, Pid, From,
+ {ssl_error, Connection:socket(self(),
+ Transport, Socket, Connection, Tracker), ReasonCode})
+ end.
+
+log_alert(true, Info, Alert) ->
+ Txt = ssl_alert:alert_txt(Alert),
+ error_logger:format("SSL: ~p: ~s\n", [Info, Txt]);
+log_alert(false, _, _) ->
+ ok.
+
+handle_own_alert(Alert, Version, StateName,
+ #state{transport_cb = Transport,
+ socket = Socket,
+ protocol_cb = Connection,
+ connection_states = ConnectionStates,
+ ssl_options = SslOpts} = State) ->
+ try %% Try to tell the other side
+ {BinMsg, _} =
+ Connection:encode_alert(Alert, Version, ConnectionStates),
+ Connection:send(Transport, Socket, BinMsg)
+ catch _:_ -> %% Can crash if we are in a uninitialized state
+ ignore
+ end,
+ try %% Try to tell the local user
+ log_alert(SslOpts#ssl_options.log_alert, StateName, Alert),
+ handle_normal_shutdown(Alert,StateName, State)
+ catch _:_ ->
+ ok
+ end,
+ {stop, {shutdown, own_alert}}.
+
+handle_normal_shutdown(Alert, _, #state{socket = Socket,
+ transport_cb = Transport,
+ protocol_cb = Connection,
+ start_or_recv_from = StartFrom,
+ tracker = Tracker,
+ role = Role, renegotiation = {false, first}}) ->
+ alert_user(Transport, Tracker,Socket, StartFrom, Alert, Role, Connection);
+
+handle_normal_shutdown(Alert, StateName, #state{socket = Socket,
+ socket_options = Opts,
+ transport_cb = Transport,
+ protocol_cb = Connection,
+ user_application = {_Mon, Pid},
+ tracker = Tracker,
+ start_or_recv_from = RecvFrom, role = Role}) ->
+ alert_user(Transport, Tracker, Socket, StateName, Opts, Pid, RecvFrom, Alert, Role, Connection).
+
+invalidate_session(client, Host, Port, Session) ->
+ ssl_manager:invalidate_session(Host, Port, Session);
+invalidate_session(server, _, Port, Session) ->
+ ssl_manager:invalidate_session(Port, Session).
+
+handle_sni_extension(undefined, State) ->
+ State;
+handle_sni_extension(#sni{hostname = Hostname}, State0) ->
+ NewOptions = update_ssl_options_from_sni(State0#state.ssl_options, Hostname),
+ case NewOptions of
+ undefined ->
+ State0;
+ _ ->
+ {ok, #{cert_db_ref := Ref,
+ cert_db_handle := CertDbHandle,
+ fileref_db_handle := FileRefHandle,
+ session_cache := CacheHandle,
+ crl_db_info := CRLDbHandle,
+ private_key := Key,
+ dh_params := DHParams,
+ own_certificate := OwnCert}} =
+ ssl_config:init(NewOptions, State0#state.role),
+ State0#state{
+ session = State0#state.session#session{own_certificate = OwnCert},
+ file_ref_db = FileRefHandle,
+ cert_db_ref = Ref,
+ cert_db = CertDbHandle,
+ crl_db = CRLDbHandle,
+ session_cache = CacheHandle,
+ private_key = Key,
+ diffie_hellman_params = DHParams,
+ ssl_options = NewOptions,
+ sni_hostname = Hostname
+ }
+ end.
+
+update_ssl_options_from_sni(OrigSSLOptions, SNIHostname) ->
+ SSLOption =
+ case OrigSSLOptions#ssl_options.sni_fun of
+ undefined ->
+ proplists:get_value(SNIHostname,
+ OrigSSLOptions#ssl_options.sni_hosts);
+ SNIFun ->
+ SNIFun(SNIHostname)
+ end,
+ case SSLOption of
+ undefined ->
+ undefined;
+ _ ->
+ ssl:handle_options(SSLOption, OrigSSLOptions)
+ end.
+
+new_emulated([], EmOpts) ->
+ EmOpts;
+new_emulated(NewEmOpts, _) ->
+ NewEmOpts.
diff --git a/lib/ssl/src/ssl_connection.hrl b/lib/ssl/src/ssl_connection.hrl
index 4b54943ddf..3e26f67de1 100644
--- a/lib/ssl/src/ssl_connection.hrl
+++ b/lib/ssl/src/ssl_connection.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -43,11 +43,12 @@
error_tag :: atom(), % ex tcp_error
host :: string() | inet:ip_address(),
port :: integer(),
- socket :: port(),
+ socket :: port() | tuple(), %% TODO: dtls socket
ssl_options :: #ssl_options{},
socket_options :: #socket_options{},
- connection_states :: #connection_states{} | secret_printout(),
+ connection_states :: ssl_record:connection_states() | secret_printout(),
protocol_buffers :: term() | secret_printout() , %% #protocol_buffers{} from tls_record.hrl or dtls_recor.hrl
+ unprocessed_handshake_events = 0 :: integer(),
tls_handshake_history :: ssl_handshake:ssl_handshake_history() | secret_printout()
| 'undefined',
cert_db :: reference() | 'undefined',
@@ -80,18 +81,19 @@
allow_renegotiate = true ::boolean(),
expecting_next_protocol_negotiation = false ::boolean(),
expecting_finished = false ::boolean(),
- negotiated_protocol = undefined :: undefined | binary(),
- client_ecc, % {Curves, PointFmt}
+ next_protocol = undefined :: undefined | binary(),
+ negotiated_protocol,
tracker :: pid() | 'undefined', %% Tracker process for listen socket
sni_hostname = undefined,
downgrade,
- flight_buffer = [] :: list() %% Buffer of TLS/DTLS records, used during the TLS handshake
- %% to when possible pack more than on TLS record into the
- %% underlaying packet format. Introduced by DTLS - RFC 4347.
- %% The mecahnism is also usefull in TLS although we do not
- %% need to worry about packet loss in TLS.
+ flight_buffer = [] :: list() | map(), %% Buffer of TLS/DTLS records, used during the TLS handshake
+ %% to when possible pack more than on TLS record into the
+ %% underlaying packet format. Introduced by DTLS - RFC 4347.
+ %% The mecahnism is also usefull in TLS although we do not
+ %% need to worry about packet loss in TLS. In DTLS we need to track DTLS handshake seqnr
+ flight_state = reliable, %% reliable | {retransmit, integer()}| {waiting, ref(), integer()} - last two is used in DTLS over udp.
+ protocol_specific = #{} :: map()
}).
-
-define(DEFAULT_DIFFIE_HELLMAN_PARAMS,
#'DHParameter'{prime = ?DEFAULT_DIFFIE_HELLMAN_PRIME,
base = ?DEFAULT_DIFFIE_HELLMAN_GENERATOR}).
diff --git a/lib/ssl/src/ssl_connection_sup.erl b/lib/ssl/src/ssl_connection_sup.erl
new file mode 100644
index 0000000000..1a1f43e683
--- /dev/null
+++ b/lib/ssl/src/ssl_connection_sup.erl
@@ -0,0 +1,101 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_connection_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+
+%% Supervisor callback
+-export([init/1]).
+
+%%%=========================================================================
+%%% API
+%%%=========================================================================
+
+-spec start_link() -> {ok, pid()} | ignore | {error, term()}.
+
+start_link() ->
+ supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+
+%%%=========================================================================
+%%% Supervisor callback
+%%%=========================================================================
+
+init([]) ->
+
+ TLSConnetionManager = tls_connection_manager_child_spec(),
+ %% Handles emulated options so that they inherited by the accept
+ %% socket, even when setopts is performed on the listen socket
+ ListenOptionsTracker = listen_options_tracker_child_spec(),
+
+ DTLSConnetionManager = dtls_connection_manager_child_spec(),
+ DTLSUdpListeners = dtls_udp_listeners_spec(),
+
+ {ok, {{one_for_one, 10, 3600}, [TLSConnetionManager,
+ ListenOptionsTracker,
+ DTLSConnetionManager,
+ DTLSUdpListeners
+ ]}}.
+
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+tls_connection_manager_child_spec() ->
+ Name = tls_connection,
+ StartFunc = {tls_connection_sup, start_link, []},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [tls_connection_sup],
+ Type = supervisor,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+
+dtls_connection_manager_child_spec() ->
+ Name = dtls_connection,
+ StartFunc = {dtls_connection_sup, start_link, []},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [dtls_connection_sup],
+ Type = supervisor,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+
+listen_options_tracker_child_spec() ->
+ Name = tls_socket,
+ StartFunc = {ssl_listen_tracker_sup, start_link, []},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [tls_socket],
+ Type = supervisor,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+
+dtls_udp_listeners_spec() ->
+ Name = dtls_udp_listener,
+ StartFunc = {dtls_udp_sup, start_link, []},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [],
+ Type = supervisor,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
diff --git a/lib/ssl/src/ssl_crl.erl b/lib/ssl/src/ssl_crl.erl
index d9f21e04ac..888a75bfd6 100644
--- a/lib/ssl/src/ssl_crl.erl
+++ b/lib/ssl/src/ssl_crl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@
-export([trusted_cert_and_path/3]).
-trusted_cert_and_path(CRL, {SerialNumber, Issuer},{Db, DbRef} = DbHandle) ->
+trusted_cert_and_path(CRL, {SerialNumber, Issuer},{_, {Db, DbRef}} = DbHandle) ->
case ssl_pkix_db:lookup_trusted_cert(Db, DbRef, SerialNumber, Issuer) of
undefined ->
trusted_cert_and_path(CRL, issuer_not_found, DbHandle);
@@ -37,17 +37,34 @@ trusted_cert_and_path(CRL, {SerialNumber, Issuer},{Db, DbRef} = DbHandle) ->
{ok, Root, Chain} = ssl_certificate:certificate_chain(OtpCert, Db, DbRef),
{ok, Root, lists:reverse(Chain)}
end;
-
-trusted_cert_and_path(CRL, issuer_not_found, {Db, DbRef} = DbHandle) ->
- case find_issuer(CRL, DbHandle) of
+trusted_cert_and_path(CRL, issuer_not_found, {CertPath, {Db, DbRef}}) ->
+ case find_issuer(CRL, {certpath,
+ [{Der, public_key:pkix_decode_cert(Der,otp)} || Der <- CertPath]}) of
{ok, OtpCert} ->
{ok, Root, Chain} = ssl_certificate:certificate_chain(OtpCert, Db, DbRef),
{ok, Root, lists:reverse(Chain)};
{error, issuer_not_found} ->
- {ok, unknown_crl_ca, []}
- end.
+ trusted_cert_and_path(CRL, issuer_not_found, {Db, DbRef})
+ end;
+trusted_cert_and_path(CRL, issuer_not_found, {Db, DbRef} = DbInfo) ->
+ case find_issuer(CRL, DbInfo) of
+ {ok, OtpCert} ->
+ {ok, Root, Chain} = ssl_certificate:certificate_chain(OtpCert, Db, DbRef),
+ {ok, Root, lists:reverse(Chain)};
+ {error, issuer_not_found} ->
+ {error, unknown_ca}
+ end.
-find_issuer(CRL, {Db,_}) ->
+find_issuer(CRL, {certpath = Db, DbRef}) ->
+ Issuer = public_key:pkix_normalize_name(public_key:pkix_crl_issuer(CRL)),
+ IsIssuerFun =
+ fun({_Der,ErlCertCandidate}, Acc) ->
+ verify_crl_issuer(CRL, ErlCertCandidate, Issuer, Acc);
+ (_, Acc) ->
+ Acc
+ end,
+ find_issuer(IsIssuerFun, Db, DbRef);
+find_issuer(CRL, {Db, DbRef}) ->
Issuer = public_key:pkix_normalize_name(public_key:pkix_crl_issuer(CRL)),
IsIssuerFun =
fun({_Key, {_Der,ErlCertCandidate}}, Acc) ->
@@ -55,13 +72,32 @@ find_issuer(CRL, {Db,_}) ->
(_, Acc) ->
Acc
end,
-
+ find_issuer(IsIssuerFun, Db, DbRef).
+
+find_issuer(IsIssuerFun, certpath, Certs) ->
+ try lists:foldl(IsIssuerFun, issuer_not_found, Certs) of
+ issuer_not_found ->
+ {error, issuer_not_found}
+ catch
+ {ok, _} = Result ->
+ Result
+ end;
+find_issuer(IsIssuerFun, extracted, CertsData) ->
+ Certs = [Entry || {decoded, Entry} <- CertsData],
+ try lists:foldl(IsIssuerFun, issuer_not_found, Certs) of
+ issuer_not_found ->
+ {error, issuer_not_found}
+ catch
+ {ok, _} = Result ->
+ Result
+ end;
+find_issuer(IsIssuerFun, Db, _) ->
try ssl_pkix_db:foldl(IsIssuerFun, issuer_not_found, Db) of
- issuer_not_found ->
- {error, issuer_not_found}
- catch
- {ok, _} = Result ->
- Result
+ issuer_not_found ->
+ {error, issuer_not_found}
+ catch
+ {ok, _} = Result ->
+ Result
end.
verify_crl_issuer(CRL, ErlCertCandidate, Issuer, NotIssuer) ->
diff --git a/lib/ssl/src/ssl_crl_cache.erl b/lib/ssl/src/ssl_crl_cache.erl
index 647e0465fe..86c0207515 100644
--- a/lib/ssl/src/ssl_crl_cache.erl
+++ b/lib/ssl/src/ssl_crl_cache.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/ssl/src/ssl_crl_cache_api.erl b/lib/ssl/src/ssl_crl_cache_api.erl
index c3a57e2f49..d5380583e7 100644
--- a/lib/ssl/src/ssl_crl_cache_api.erl
+++ b/lib/ssl/src/ssl_crl_cache_api.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/ssl/src/ssl_dist_admin_sup.erl b/lib/ssl/src/ssl_dist_admin_sup.erl
new file mode 100644
index 0000000000..f60806c4cb
--- /dev/null
+++ b/lib/ssl/src/ssl_dist_admin_sup.erl
@@ -0,0 +1,74 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2016-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_dist_admin_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+
+%% Supervisor callback
+-export([init/1]).
+
+%%%=========================================================================
+%%% API
+%%%=========================================================================
+
+-spec start_link() -> {ok, pid()} | ignore | {error, term()}.
+
+start_link() ->
+ supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+
+%%%=========================================================================
+%%% Supervisor callback
+%%%=========================================================================
+
+init([]) ->
+ PEMCache = pem_cache_child_spec(),
+ SessionCertManager = session_and_cert_manager_child_spec(),
+ {ok, {{rest_for_one, 10, 3600}, [PEMCache, SessionCertManager]}}.
+
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+pem_cache_child_spec() ->
+ Name = ssl_pem_cache_dist,
+ StartFunc = {ssl_pem_cache, start_link_dist, [[]]},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [ssl_pem_cache],
+ Type = worker,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+
+session_and_cert_manager_child_spec() ->
+ Opts = ssl_admin_sup:manager_opts(),
+ Name = ssl_dist_manager,
+ StartFunc = {ssl_manager, start_link_dist, [Opts]},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [ssl_manager],
+ Type = worker,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+
diff --git a/lib/ssl/src/ssl_dist_connection_sup.erl b/lib/ssl/src/ssl_dist_connection_sup.erl
new file mode 100644
index 0000000000..e5842c866e
--- /dev/null
+++ b/lib/ssl/src/ssl_dist_connection_sup.erl
@@ -0,0 +1,79 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_dist_connection_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+
+%% Supervisor callback
+-export([init/1]).
+
+%%%=========================================================================
+%%% API
+%%%=========================================================================
+
+-spec start_link() -> {ok, pid()} | ignore | {error, term()}.
+
+start_link() ->
+ supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+
+%%%=========================================================================
+%%% Supervisor callback
+%%%=========================================================================
+
+init([]) ->
+
+ TLSConnetionManager = tls_connection_manager_child_spec(),
+ %% Handles emulated options so that they inherited by the accept
+ %% socket, even when setopts is performed on the listen socket
+ ListenOptionsTracker = listen_options_tracker_child_spec(),
+
+ {ok, {{one_for_one, 10, 3600}, [TLSConnetionManager,
+ ListenOptionsTracker
+ ]}}.
+
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+tls_connection_manager_child_spec() ->
+ Name = dist_tls_connection,
+ StartFunc = {tls_connection_sup, start_link_dist, []},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [tls_connection_sup],
+ Type = supervisor,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+
+listen_options_tracker_child_spec() ->
+ Name = dist_tls_socket,
+ StartFunc = {ssl_listen_tracker_sup, start_link_dist, []},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [tls_socket],
+ Type = supervisor,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+
diff --git a/lib/ssl/src/ssl_dist_sup.erl b/lib/ssl/src/ssl_dist_sup.erl
index a6eb1be1f6..690b896919 100644
--- a/lib/ssl/src/ssl_dist_sup.erl
+++ b/lib/ssl/src/ssl_dist_sup.erl
@@ -44,34 +44,29 @@ start_link() ->
%%%=========================================================================
init([]) ->
- SessionCertManager = session_and_cert_manager_child_spec(),
- ConnetionManager = connection_manager_child_spec(),
- ListenOptionsTracker = listen_options_tracker_child_spec(),
+ AdminSup = ssl_admin_child_spec(),
+ ConnectionSup = ssl_connection_sup(),
ProxyServer = proxy_server_child_spec(),
-
- {ok, {{one_for_all, 10, 3600}, [SessionCertManager, ConnetionManager,
- ListenOptionsTracker,
- ProxyServer]}}.
+ {ok, {{one_for_all, 10, 3600}, [AdminSup, ProxyServer, ConnectionSup]}}.
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-session_and_cert_manager_child_spec() ->
- Opts = ssl_sup:manager_opts(),
- Name = ssl_manager_dist,
- StartFunc = {ssl_manager, start_link_dist, [Opts]},
+ssl_admin_child_spec() ->
+ Name = ssl_dist_admin_sup,
+ StartFunc = {ssl_dist_admin_sup, start_link , []},
Restart = permanent,
Shutdown = 4000,
- Modules = [ssl_manager],
- Type = worker,
+ Modules = [ssl_admin_sup],
+ Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-connection_manager_child_spec() ->
- Name = ssl_connection_dist,
- StartFunc = {tls_connection_sup, start_link_dist, []},
- Restart = permanent,
- Shutdown = infinity,
- Modules = [tls_connection_sup],
+ssl_connection_sup() ->
+ Name = ssl_dist_connection_sup,
+ StartFunc = {ssl_dist_connection_sup, start_link, []},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [ssl_connection_sup],
Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
@@ -83,12 +78,3 @@ proxy_server_child_spec() ->
Modules = [ssl_tls_dist_proxy],
Type = worker,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
-listen_options_tracker_child_spec() ->
- Name = ssl_socket_dist,
- StartFunc = {ssl_listen_tracker_sup, start_link_dist, []},
- Restart = permanent,
- Shutdown = 4000,
- Modules = [ssl_socket],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 9c3fe9d73b..3cf466e78f 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -50,9 +50,9 @@
finished/5, next_protocol/1]).
%% Handle handshake messages
--export([certify/10, client_certificate_verify/6, certificate_verify/6, verify_signature/5,
- master_secret/5, server_key_exchange_hash/2, verify_connection/6,
- init_handshake_history/0, update_handshake_history/2, verify_server_key/5
+-export([certify/6, client_certificate_verify/6, certificate_verify/6, verify_signature/5,
+ master_secret/4, server_key_exchange_hash/2, verify_connection/6,
+ init_handshake_history/0, update_handshake_history/3, verify_server_key/5
]).
%% Encode/Decode
@@ -64,17 +64,17 @@
]).
%% Cipher suites handling
--export([available_suites/2, available_signature_algs/3, cipher_suites/2,
+-export([available_suites/2, available_signature_algs/2, cipher_suites/2,
select_session/11, supported_ecc/1, available_signature_algs/4]).
%% Extensions handling
--export([client_hello_extensions/6,
+-export([client_hello_extensions/5,
handle_client_hello_extensions/9, %% Returns server hello extensions
- handle_server_hello_extensions/9, select_curve/2
+ handle_server_hello_extensions/9, select_curve/2, select_curve/3
]).
%% MISC
--export([select_version/3, prf/6, select_hashsign/5,
+-export([select_version/3, prf/6, select_hashsign/4, select_hashsign/5,
select_hashsign_algs/3,
premaster_secret/2, premaster_secret/3, premaster_secret/4]).
@@ -94,15 +94,14 @@ hello_request() ->
#hello_request{}.
%%--------------------------------------------------------------------
--spec server_hello(#session{}, ssl_record:ssl_version(), #connection_states{},
+-spec server_hello(#session{}, ssl_record:ssl_version(), ssl_record:connection_states(),
#hello_extensions{}) -> #server_hello{}.
%%
%% Description: Creates a server hello message.
%%--------------------------------------------------------------------
server_hello(SessionId, Version, ConnectionStates, Extensions) ->
- Pending = ssl_record:pending_connection_state(ConnectionStates, read),
- SecParams = Pending#connection_state.security_parameters,
-
+ #{security_parameters := SecParams} =
+ ssl_record:pending_connection_state(ConnectionStates, read),
#server_hello{server_version = Version,
cipher_suite = SecParams#security_parameters.cipher_suite,
compression_method =
@@ -120,12 +119,13 @@ server_hello(SessionId, Version, ConnectionStates, Extensions) ->
server_hello_done() ->
#server_hello_done{}.
-client_hello_extensions(Host, Version, CipherSuites,
- #ssl_options{signature_algs = SupportedHashSigns, versions = AllVersions} = SslOpts, ConnectionStates, Renegotiation) ->
+client_hello_extensions(Version, CipherSuites,
+ #ssl_options{signature_algs = SupportedHashSigns,
+ eccs = SupportedECCs} = SslOpts, ConnectionStates, Renegotiation) ->
{EcPointFormats, EllipticCurves} =
case advertises_ec_ciphers(lists:map(fun ssl_cipher:suite_definition/1, CipherSuites)) of
true ->
- client_ecc_extensions(tls_v1, Version);
+ client_ecc_extensions(SupportedECCs);
false ->
{undefined, undefined}
end,
@@ -135,14 +135,14 @@ client_hello_extensions(Host, Version, CipherSuites,
renegotiation_info = renegotiation_info(tls_record, client,
ConnectionStates, Renegotiation),
srp = SRP,
- signature_algs = available_signature_algs(SupportedHashSigns, Version, AllVersions),
+ signature_algs = available_signature_algs(SupportedHashSigns, Version),
ec_point_formats = EcPointFormats,
elliptic_curves = EllipticCurves,
alpn = encode_alpn(SslOpts#ssl_options.alpn_advertised_protocols, Renegotiation),
next_protocol_negotiation =
encode_client_protocol_negotiation(SslOpts#ssl_options.next_protocol_selector,
Renegotiation),
- sni = sni(Host, SslOpts#ssl_options.server_name_indication)}.
+ sni = sni(SslOpts#ssl_options.server_name_indication)}.
%%--------------------------------------------------------------------
-spec certificate(der_cert(), db_handle(), certdb_ref(), client | server) -> #certificate{} | #alert{}.
@@ -335,9 +335,8 @@ verify_server_key(#server_key_params{params_bin = EncParams,
signature = Signature},
HashSign = {HashAlgo, _},
ConnectionStates, Version, PubKeyInfo) ->
- ConnectionState =
+ #{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates, read),
- SecParams = ConnectionState#connection_state.security_parameters,
#security_parameters{client_random = ClientRandom,
server_random = ServerRandom} = SecParams,
Hash = server_key_exchange_hash(HashAlgo,
@@ -389,25 +388,26 @@ verify_signature(_, Hash, {HashAlgo, _SignAlg}, Signature,
%%--------------------------------------------------------------------
--spec certify(#certificate{}, db_handle(), certdb_ref(), integer() | nolimit,
- verify_peer | verify_none, {fun(), term}, fun(), term(), term(),
+-spec certify(#certificate{}, db_handle(), certdb_ref(), #ssl_options{}, term(),
client | server) -> {der_cert(), public_key_info()} | #alert{}.
%%
%% Description: Handles a certificate handshake message
%%--------------------------------------------------------------------
certify(#certificate{asn1_certificates = ASN1Certs}, CertDbHandle, CertDbRef,
- MaxPathLen, _Verify, ValidationFunAndState0, PartialChain, CRLCheck, CRLDbHandle, Role) ->
- [PeerCert | _] = ASN1Certs,
-
- ValidationFunAndState = validation_fun_and_state(ValidationFunAndState0, Role,
- CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle),
+ Opts, CRLDbHandle, Role) ->
+ [PeerCert | _] = ASN1Certs,
try
{TrustedCert, CertPath} =
- ssl_certificate:trusted_cert_and_path(ASN1Certs, CertDbHandle, CertDbRef, PartialChain),
+ ssl_certificate:trusted_cert_and_path(ASN1Certs, CertDbHandle, CertDbRef,
+ Opts#ssl_options.partial_chain),
+ ValidationFunAndState = validation_fun_and_state(Opts#ssl_options.verify_fun, Role,
+ CertDbHandle, CertDbRef,
+ Opts#ssl_options.server_name_indication,
+ Opts#ssl_options.crl_check, CRLDbHandle, CertPath),
case public_key:pkix_path_validation(TrustedCert,
CertPath,
- [{max_path_length, MaxPathLen},
+ [{max_path_length, Opts#ssl_options.depth},
{verify_fun, ValidationFunAndState}]) of
{ok, {PublicKeyInfo,_}} ->
{PeerCert, PublicKeyInfo};
@@ -447,7 +447,7 @@ init_handshake_history() ->
{[], []}.
%%--------------------------------------------------------------------
--spec update_handshake_history(ssl_handshake:ssl_handshake_history(), Data ::term()) ->
+-spec update_handshake_history(ssl_handshake:ssl_handshake_history(), Data ::term(), boolean()) ->
ssl_handshake:ssl_handshake_history().
%%
%% Description: Update the handshake history buffer with Data.
@@ -457,14 +457,14 @@ update_handshake_history(Handshake, % special-case SSL2 client hello
?UINT16(CSLength), ?UINT16(0),
?UINT16(CDLength),
CipherSuites:CSLength/binary,
- ChallengeData:CDLength/binary>>) ->
+ ChallengeData:CDLength/binary>>, true) ->
update_handshake_history(Handshake,
<<?CLIENT_HELLO, ?BYTE(Major), ?BYTE(Minor),
?UINT16(CSLength), ?UINT16(0),
?UINT16(CDLength),
CipherSuites:CSLength/binary,
- ChallengeData:CDLength/binary>>);
-update_handshake_history({Handshake0, _Prev}, Data) ->
+ ChallengeData:CDLength/binary>>, true);
+update_handshake_history({Handshake0, _Prev}, Data, _) ->
{[Data|Handshake0], Handshake0}.
%% %%--------------------------------------------------------------------
@@ -581,7 +581,7 @@ prf({3,_N}, PRFAlgo, Secret, Label, Seed, WantedLength) ->
{atom(), atom()} | undefined | #alert{}.
%%
-%% Description: Handles signature_algorithms extension
+%% Description: Handles signature_algorithms hello extension (server)
%%--------------------------------------------------------------------
select_hashsign(_, undefined, _, _, _Version) ->
{null, anon};
@@ -593,14 +593,17 @@ select_hashsign(HashSigns, Cert, KeyExAlgo,
select_hashsign(#hash_sign_algos{hash_sign_algos = HashSigns}, Cert, KeyExAlgo, SupportedHashSigns,
{Major, Minor}) when Major >= 3 andalso Minor >= 3 ->
#'OTPCertificate'{tbsCertificate = TBSCert} = public_key:pkix_decode_cert(Cert, otp),
- #'OTPSubjectPublicKeyInfo'{algorithm = {_,Algo, _}} = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
- Sign = cert_sign(Algo),
- case lists:filter(fun({sha, dsa = S}) when S == Sign ->
- true;
- ({_, dsa}) ->
- false;
- ({_, _} = Algos) ->
- is_acceptable_hash_sign(Algos, Sign, KeyExAlgo, SupportedHashSigns);
+ #'OTPCertificate'{tbsCertificate = TBSCert,
+ signatureAlgorithm = {_,SignAlgo, _}} = public_key:pkix_decode_cert(Cert, otp),
+ #'OTPSubjectPublicKeyInfo'{algorithm = {_, SubjAlgo, _}} =
+ TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
+
+ Sign = sign_algo(SignAlgo),
+ SubSing = sign_algo(SubjAlgo),
+
+ case lists:filter(fun({_, S} = Algos) when S == Sign ->
+ is_acceptable_hash_sign(Algos, Sign,
+ SubSing, KeyExAlgo, SupportedHashSigns);
(_) ->
false
end, HashSigns) of
@@ -613,6 +616,49 @@ select_hashsign(_, Cert, _, _, Version) ->
#'OTPCertificate'{tbsCertificate = TBSCert} = public_key:pkix_decode_cert(Cert, otp),
#'OTPSubjectPublicKeyInfo'{algorithm = {_,Algo, _}} = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
select_hashsign_algs(undefined, Algo, Version).
+%%--------------------------------------------------------------------
+-spec select_hashsign(#certificate_request{}, binary(),
+ [atom()], ssl_record:ssl_version()) ->
+ {atom(), atom()} | #alert{}.
+
+%%
+%% Description: Handles signature algorithms selection for certificate requests (client)
+%%--------------------------------------------------------------------
+select_hashsign(#certificate_request{}, undefined, _, {Major, Minor}) when Major >= 3 andalso Minor >= 3->
+ %% There client does not have a certificate and will send an empty reply, the server may fail
+ %% or accept the connection by its own preference. No signature algorihms needed as there is
+ %% no certificate to verify.
+ {undefined, undefined};
+
+select_hashsign(#certificate_request{hashsign_algorithms = #hash_sign_algos{hash_sign_algos = HashSigns},
+ certificate_types = Types}, Cert, SupportedHashSigns,
+ {Major, Minor}) when Major >= 3 andalso Minor >= 3->
+ #'OTPCertificate'{tbsCertificate = TBSCert} = public_key:pkix_decode_cert(Cert, otp),
+ #'OTPCertificate'{tbsCertificate = TBSCert,
+ signatureAlgorithm = {_,SignAlgo, _}} = public_key:pkix_decode_cert(Cert, otp),
+ #'OTPSubjectPublicKeyInfo'{algorithm = {_, SubjAlgo, _}} =
+ TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
+
+ Sign = sign_algo(SignAlgo),
+ SubSign = sign_algo(SubjAlgo),
+
+ case is_acceptable_cert_type(SubSign, HashSigns, Types) andalso is_supported_sign(Sign, HashSigns) of
+ true ->
+ case lists:filter(fun({_, S} = Algos) when S == SubSign ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+ (_) ->
+ false
+ end, HashSigns) of
+ [] ->
+ ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY, no_suitable_signature_algorithm);
+ [HashSign | _] ->
+ HashSign
+ end;
+ false ->
+ ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY, no_suitable_signature_algorithm)
+ end;
+select_hashsign(#certificate_request{}, Cert, _, Version) ->
+ select_hashsign(undefined, Cert, undefined, [], Version).
%%--------------------------------------------------------------------
-spec select_hashsign_algs({atom(), atom()}| undefined, oid(), ssl_record:ssl_version()) ->
@@ -648,34 +694,34 @@ select_hashsign_algs(undefined, ?rsaEncryption, _) ->
select_hashsign_algs(undefined, ?'id-dsa', _) ->
{sha, dsa}.
+
%%--------------------------------------------------------------------
--spec master_secret(atom(), ssl_record:ssl_version(), #session{} | binary(), #connection_states{},
- client | server) -> {binary(), #connection_states{}} | #alert{}.
+-spec master_secret(ssl_record:ssl_version(), #session{} | binary(), ssl_record:connection_states(),
+ client | server) -> {binary(), ssl_record:connection_states()} | #alert{}.
%%
%% Description: Sets or calculates the master secret and calculate keys,
%% updating the pending connection states. The Mastersecret and the update
%% connection states are returned or an alert if the calculation fails.
%%-------------------------------------------------------------------
-master_secret(RecordCB, Version, #session{master_secret = Mastersecret},
+master_secret(Version, #session{master_secret = Mastersecret},
ConnectionStates, Role) ->
- ConnectionState =
+ #{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates, read),
- SecParams = ConnectionState#connection_state.security_parameters,
- try master_secret(RecordCB, Version, Mastersecret, SecParams,
+ try master_secret(Version, Mastersecret, SecParams,
ConnectionStates, Role)
catch
exit:_ ->
?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, key_calculation_failure)
end;
-master_secret(RecordCB, Version, PremasterSecret, ConnectionStates, Role) ->
- ConnectionState =
+master_secret(Version, PremasterSecret, ConnectionStates, Role) ->
+ #{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates, read),
- SecParams = ConnectionState#connection_state.security_parameters,
+
#security_parameters{prf_algorithm = PrfAlgo,
client_random = ClientRandom,
server_random = ServerRandom} = SecParams,
- try master_secret(RecordCB, Version,
+ try master_secret(Version,
calc_master_secret(Version,PrfAlgo,PremasterSecret,
ClientRandom, ServerRandom),
SecParams, ConnectionStates, Role)
@@ -1125,8 +1171,9 @@ select_session(SuggestedSessionId, CipherSuites, HashSigns, Compressions, Port,
{resumed, Resumed}
end.
-supported_ecc({Major, Minor} = Version) when ((Major == 3) and (Minor >= 1)) orelse (Major > 3) ->
- Curves = tls_v1:ecc_curves(Version),
+%% Deprecated?
+supported_ecc({Major, Minor}) when ((Major == 3) and (Minor >= 1)) orelse (Major > 3) ->
+ Curves = tls_v1:ecc_curves(Minor),
#elliptic_curves{elliptic_curve_list = Curves};
supported_ecc(_) ->
#elliptic_curves{elliptic_curve_list = []}.
@@ -1143,11 +1190,13 @@ certificate_types(_, {N, M}) when N >= 3 andalso M >= 3 ->
end;
certificate_types({KeyExchange, _, _, _}, _) when KeyExchange == rsa;
+ KeyExchange == dh_rsa;
KeyExchange == dhe_rsa;
KeyExchange == ecdhe_rsa ->
<<?BYTE(?RSA_SIGN)>>;
-certificate_types({KeyExchange, _, _, _}, _) when KeyExchange == dhe_dss;
+certificate_types({KeyExchange, _, _, _}, _) when KeyExchange == dh_dss;
+ KeyExchange == dhe_dss;
KeyExchange == srp_dss ->
<<?BYTE(?DSS_SIGN)>>;
@@ -1170,13 +1219,18 @@ certificate_authorities(CertDbHandle, CertDbRef) ->
end,
list_to_binary([Enc(Cert) || {_, Cert} <- Authorities]).
-certificate_authorities_from_db(CertDbHandle, CertDbRef) ->
+certificate_authorities_from_db(CertDbHandle, CertDbRef) when is_reference(CertDbRef) ->
ConnectionCerts = fun({{Ref, _, _}, Cert}, Acc) when Ref == CertDbRef ->
[Cert | Acc];
(_, Acc) ->
Acc
end,
- ssl_pkix_db:foldl(ConnectionCerts, [], CertDbHandle).
+ ssl_pkix_db:foldl(ConnectionCerts, [], CertDbHandle);
+certificate_authorities_from_db(_CertDbHandle, {extracted, CertDbData}) ->
+ %% Cache disabled, Ref contains data
+ lists:foldl(fun({decoded, {_Key,Cert}}, Acc) -> [Cert | Acc] end,
+ [], CertDbData).
+
%%-------------Extension handling --------------------------------
@@ -1256,35 +1310,67 @@ handle_server_hello_extensions(RecordCB, Random, CipherSuite, Compression,
end.
select_version(RecordCB, ClientVersion, Versions) ->
- ServerVersion = RecordCB:highest_protocol_version(Versions),
- RecordCB:lowest_protocol_version(ClientVersion, ServerVersion).
+ do_select_version(RecordCB, ClientVersion, Versions).
+
+do_select_version(_, ClientVersion, []) ->
+ ClientVersion;
+do_select_version(RecordCB, ClientVersion, [Version | Versions]) ->
+ case RecordCB:is_higher(Version, ClientVersion) of
+ true ->
+ %% Version too high for client - keep looking
+ do_select_version(RecordCB, ClientVersion, Versions);
+ false ->
+ %% Version ok for client - look for a higher
+ do_select_version(RecordCB, ClientVersion, Versions, Version)
+ end.
+%%
+do_select_version(_, _, [], GoodVersion) ->
+ GoodVersion;
+do_select_version(
+ RecordCB, ClientVersion, [Version | Versions], GoodVersion) ->
+ BetterVersion =
+ case RecordCB:is_higher(Version, ClientVersion) of
+ true ->
+ %% Version too high for client
+ GoodVersion;
+ false ->
+ %% Version ok for client
+ case RecordCB:is_higher(Version, GoodVersion) of
+ true ->
+ %% Use higher version
+ Version;
+ false ->
+ GoodVersion
+ end
+ end,
+ do_select_version(RecordCB, ClientVersion, Versions, BetterVersion).
renegotiation_info(_, client, _, false) ->
#renegotiation_info{renegotiated_connection = undefined};
renegotiation_info(_RecordCB, server, ConnectionStates, false) ->
- CS = ssl_record:current_connection_state(ConnectionStates, read),
- case CS#connection_state.secure_renegotiation of
+ ConnectionState = ssl_record:current_connection_state(ConnectionStates, read),
+ case maps:get(secure_renegotiation, ConnectionState) of
true ->
#renegotiation_info{renegotiated_connection = ?byte(0)};
false ->
#renegotiation_info{renegotiated_connection = undefined}
end;
renegotiation_info(_RecordCB, client, ConnectionStates, true) ->
- CS = ssl_record:current_connection_state(ConnectionStates, read),
- case CS#connection_state.secure_renegotiation of
+ ConnectionState = ssl_record:current_connection_state(ConnectionStates, read),
+ case maps:get(secure_renegotiation, ConnectionState) of
true ->
- Data = CS#connection_state.client_verify_data,
+ Data = maps:get(client_verify_data, ConnectionState),
#renegotiation_info{renegotiated_connection = Data};
false ->
#renegotiation_info{renegotiated_connection = undefined}
end;
renegotiation_info(_RecordCB, server, ConnectionStates, true) ->
- CS = ssl_record:current_connection_state(ConnectionStates, read),
- case CS#connection_state.secure_renegotiation of
+ ConnectionState = ssl_record:current_connection_state(ConnectionStates, read),
+ case maps:get(secure_renegotiation, ConnectionState) of
true ->
- CData = CS#connection_state.client_verify_data,
- SData =CS#connection_state.server_verify_data,
+ CData = maps:get(client_verify_data, ConnectionState),
+ SData = maps:get(server_verify_data, ConnectionState),
#renegotiation_info{renegotiated_connection = <<CData/binary, SData/binary>>};
false ->
#renegotiation_info{renegotiated_connection = undefined}
@@ -1307,9 +1393,9 @@ handle_renegotiation_info(_RecordCB, _, undefined, ConnectionStates, false, _, _
handle_renegotiation_info(_RecordCB, client, #renegotiation_info{renegotiated_connection = ClientServerVerify},
ConnectionStates, true, _, _) ->
- CS = ssl_record:current_connection_state(ConnectionStates, read),
- CData = CS#connection_state.client_verify_data,
- SData = CS#connection_state.server_verify_data,
+ ConnectionState = ssl_record:current_connection_state(ConnectionStates, read),
+ CData = maps:get(client_verify_data, ConnectionState),
+ SData = maps:get(server_verify_data, ConnectionState),
case <<CData/binary, SData/binary>> == ClientServerVerify of
true ->
{ok, ConnectionStates};
@@ -1323,8 +1409,8 @@ handle_renegotiation_info(_RecordCB, server, #renegotiation_info{renegotiated_co
true ->
?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, {server_renegotiation, empty_renegotiation_info_scsv});
false ->
- CS = ssl_record:current_connection_state(ConnectionStates, read),
- Data = CS#connection_state.client_verify_data,
+ ConnectionState = ssl_record:current_connection_state(ConnectionStates, read),
+ Data = maps:get(client_verify_data, ConnectionState),
case Data == ClientVerify of
true ->
{ok, ConnectionStates};
@@ -1345,8 +1431,8 @@ handle_renegotiation_info(RecordCB, server, undefined, ConnectionStates, true, S
end.
handle_renegotiation_info(_RecordCB, ConnectionStates, SecureRenegotation) ->
- CS = ssl_record:current_connection_state(ConnectionStates, read),
- case {SecureRenegotation, CS#connection_state.secure_renegotiation} of
+ ConnectionState = ssl_record:current_connection_state(ConnectionStates, read),
+ case {SecureRenegotation, maps:get(secure_renegotiation, ConnectionState)} of
{_, true} ->
?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, already_secure);
{true, false} ->
@@ -1371,12 +1457,12 @@ srp_user(#ssl_options{srp_identity = {UserName, _}}) ->
srp_user(_) ->
undefined.
-client_ecc_extensions(Module, Version) ->
+client_ecc_extensions(SupportedECCs) ->
CryptoSupport = proplists:get_value(public_keys, crypto:supports()),
case proplists:get_bool(ecdh, CryptoSupport) of
true ->
EcPointFormats = #ec_point_formats{ec_point_format_list = [?ECPOINT_UNCOMPRESSED]},
- EllipticCurves = #elliptic_curves{elliptic_curve_list = Module:ecc_curves(Version)},
+ EllipticCurves = SupportedECCs,
{EcPointFormats, EllipticCurves};
_ ->
{undefined, undefined}
@@ -1410,40 +1496,44 @@ advertises_ec_ciphers([{ecdh_anon, _,_,_} | _]) ->
true;
advertises_ec_ciphers([_| Rest]) ->
advertises_ec_ciphers(Rest).
-select_curve(#elliptic_curves{elliptic_curve_list = ClientCurves},
- #elliptic_curves{elliptic_curve_list = ServerCurves}) ->
- select_curve(ClientCurves, ServerCurves);
-select_curve(undefined, _) ->
+
+select_curve(Client, Server) ->
+ select_curve(Client, Server, false).
+
+select_curve(#elliptic_curves{elliptic_curve_list = ClientCurves},
+ #elliptic_curves{elliptic_curve_list = ServerCurves},
+ ServerOrder) ->
+ case ServerOrder of
+ false ->
+ select_shared_curve(ClientCurves, ServerCurves);
+ true ->
+ select_shared_curve(ServerCurves, ClientCurves)
+ end;
+select_curve(undefined, _, _) ->
%% Client did not send ECC extension use default curve if
%% ECC cipher is negotiated
- {namedCurve, ?secp256r1};
-select_curve(_, []) ->
+ {namedCurve, ?secp256r1}.
+
+select_shared_curve([], _) ->
no_curve;
-select_curve(Curves, [Curve| Rest]) ->
+select_shared_curve([Curve | Rest], Curves) ->
case lists:member(Curve, Curves) of
true ->
{namedCurve, Curve};
false ->
- select_curve(Curves, Rest)
+ select_shared_curve(Rest, Curves)
end.
-%% RFC 6066, Section 3: Currently, the only server names supported are
-%% DNS hostnames
-sni(_, disable) ->
+
+sni(undefined) ->
undefined;
-sni(Host, undefined) ->
- sni1(Host);
-sni(_Host, SNIOption) ->
- sni1(SNIOption).
-
-sni1(Hostname) ->
- case inet_parse:domain(Hostname) of
- false -> undefined;
- true -> #sni{hostname = Hostname}
- end.
+sni(Hostname) ->
+ #sni{hostname = Hostname}.
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-validation_fun_and_state({Fun, UserState0}, Role, CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle) ->
+validation_fun_and_state({Fun, UserState0}, Role, CertDbHandle, CertDbRef,
+ ServerNameIndication, CRLCheck, CRLDbHandle, CertPath) ->
{fun(OtpCert, {extension, _} = Extension, {SslState, UserState}) ->
case ssl_certificate:validate(OtpCert,
Extension,
@@ -1452,24 +1542,29 @@ validation_fun_and_state({Fun, UserState0}, Role, CertDbHandle, CertDbRef, CRLC
{valid, {NewSslState, UserState}};
{fail, Reason} ->
apply_user_fun(Fun, OtpCert, Reason, UserState,
- SslState);
+ SslState, CertPath);
{unknown, _} ->
apply_user_fun(Fun, OtpCert,
- Extension, UserState, SslState)
+ Extension, UserState, SslState, CertPath)
end;
(OtpCert, VerifyResult, {SslState, UserState}) ->
apply_user_fun(Fun, OtpCert, VerifyResult, UserState,
- SslState)
- end, {{Role, CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle}, UserState0}};
-validation_fun_and_state(undefined, Role, CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle) ->
+ SslState, CertPath)
+ end, {{Role, CertDbHandle, CertDbRef, ServerNameIndication, CRLCheck, CRLDbHandle}, UserState0}};
+validation_fun_and_state(undefined, Role, CertDbHandle, CertDbRef,
+ ServerNameIndication, CRLCheck, CRLDbHandle, CertPath) ->
{fun(OtpCert, {extension, _} = Extension, SslState) ->
ssl_certificate:validate(OtpCert,
Extension,
SslState);
- (OtpCert, VerifyResult, SslState) when (VerifyResult == valid) or (VerifyResult == valid_peer) ->
- case crl_check(OtpCert, CRLCheck, CertDbHandle, CertDbRef, CRLDbHandle, VerifyResult) of
- valid ->
- {VerifyResult, SslState};
+ (OtpCert, VerifyResult, SslState) when (VerifyResult == valid) or
+ (VerifyResult == valid_peer) ->
+ case crl_check(OtpCert, CRLCheck, CertDbHandle, CertDbRef,
+ CRLDbHandle, VerifyResult, CertPath) of
+ valid ->
+ ssl_certificate:validate(OtpCert,
+ VerifyResult,
+ SslState);
Reason ->
{fail, Reason}
end;
@@ -1477,23 +1572,24 @@ validation_fun_and_state(undefined, Role, CertDbHandle, CertDbRef, CRLCheck, CRL
ssl_certificate:validate(OtpCert,
VerifyResult,
SslState)
- end, {Role, CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle}}.
+ end, {Role, CertDbHandle, CertDbRef, ServerNameIndication, CRLCheck, CRLDbHandle}}.
apply_user_fun(Fun, OtpCert, VerifyResult, UserState0,
- {_, CertDbHandle, CertDbRef, CRLCheck, CRLDbHandle} = SslState) when
+ {_, CertDbHandle, CertDbRef, _, CRLCheck, CRLDbHandle} = SslState, CertPath) when
(VerifyResult == valid) or (VerifyResult == valid_peer) ->
case Fun(OtpCert, VerifyResult, UserState0) of
{Valid, UserState} when (Valid == valid) or (Valid == valid_peer) ->
- case crl_check(OtpCert, CRLCheck, CertDbHandle, CertDbRef, CRLDbHandle, VerifyResult) of
+ case crl_check(OtpCert, CRLCheck, CertDbHandle, CertDbRef,
+ CRLDbHandle, VerifyResult, CertPath) of
valid ->
{Valid, {SslState, UserState}};
Result ->
- apply_user_fun(Fun, OtpCert, Result, UserState, SslState)
+ apply_user_fun(Fun, OtpCert, Result, UserState, SslState, CertPath)
end;
{fail, _} = Fail ->
Fail
end;
-apply_user_fun(Fun, OtpCert, ExtensionOrError, UserState0, SslState) ->
+apply_user_fun(Fun, OtpCert, ExtensionOrError, UserState0, SslState, _CertPath) ->
case Fun(OtpCert, ExtensionOrError, UserState0) of
{Valid, UserState} when (Valid == valid) or (Valid == valid_peer)->
{Valid, {SslState, UserState}};
@@ -1564,7 +1660,7 @@ calc_finished({3, 0}, Role, _PrfAlgo, MasterSecret, Handshake) ->
calc_finished({3, N}, Role, PrfAlgo, MasterSecret, Handshake) ->
tls_v1:finished(Role, N, PrfAlgo, MasterSecret, lists:reverse(Handshake)).
-master_secret(_RecordCB, Version, MasterSecret,
+master_secret(Version, MasterSecret,
#security_parameters{
bulk_cipher_algorithm = BCA,
client_random = ClientRandom,
@@ -1647,18 +1743,16 @@ hello_pending_connection_states(_RecordCB, Role, Version, CipherSuite, Random, C
NewWriteSecParams,
ConnectionStates).
-hello_security_parameters(client, Version, ConnectionState, CipherSuite, Random,
+hello_security_parameters(client, Version, #{security_parameters := SecParams}, CipherSuite, Random,
Compression) ->
- SecParams = ConnectionState#connection_state.security_parameters,
NewSecParams = ssl_cipher:security_parameters(Version, CipherSuite, SecParams),
NewSecParams#security_parameters{
server_random = Random,
compression_algorithm = Compression
};
-hello_security_parameters(server, Version, ConnectionState, CipherSuite, Random,
+hello_security_parameters(server, Version, #{security_parameters := SecParams}, CipherSuite, Random,
Compression) ->
- SecParams = ConnectionState#connection_state.security_parameters,
NewSecParams = ssl_cipher:security_parameters(Version, CipherSuite, SecParams),
NewSecParams#security_parameters{
client_random = Random,
@@ -2050,16 +2144,11 @@ is_member(Suite, SupportedSuites) ->
select_compression(_CompressionMetodes) ->
?NULL.
-available_signature_algs(undefined, _, _) ->
+available_signature_algs(undefined, _) ->
undefined;
-available_signature_algs(SupportedHashSigns, {Major, Minor}, AllVersions) when Major >= 3 andalso Minor >= 3 ->
- case tls_record:lowest_protocol_version(AllVersions) of
- {3, 3} ->
- #hash_sign_algos{hash_sign_algos = SupportedHashSigns};
- _ ->
- undefined
- end;
-available_signature_algs(_, _, _) ->
+available_signature_algs(SupportedHashSigns, Version) when Version >= {3, 3} ->
+ #hash_sign_algos{hash_sign_algos = SupportedHashSigns};
+available_signature_algs(_, _) ->
undefined.
psk_secret(PSKIdentity, PSKLookup) ->
@@ -2091,13 +2180,14 @@ handle_psk_identity(_PSKIdentity, LookupFun)
handle_psk_identity(PSKIdentity, {Fun, UserState}) ->
Fun(psk, PSKIdentity, UserState).
-crl_check(_, false, _,_,_, _) ->
+crl_check(_, false, _,_,_, _, _) ->
valid;
-crl_check(_, peer, _, _,_, valid) -> %% Do not check CAs with this option.
+crl_check(_, peer, _, _,_, valid, _) -> %% Do not check CAs with this option.
valid;
-crl_check(OtpCert, Check, CertDbHandle, CertDbRef, {Callback, CRLDbHandle}, _) ->
+crl_check(OtpCert, Check, CertDbHandle, CertDbRef, {Callback, CRLDbHandle}, _, CertPath) ->
Options = [{issuer_fun, {fun(_DP, CRL, Issuer, DBInfo) ->
- ssl_crl:trusted_cert_and_path(CRL, Issuer, DBInfo)
+ ssl_crl:trusted_cert_and_path(CRL, Issuer, {CertPath,
+ DBInfo})
end, {CertDbHandle, CertDbRef}}},
{update_crl, fun(DP, CRL) -> Callback:fresh_crl(DP, CRL) end}
],
@@ -2133,7 +2223,8 @@ dps_and_crls(OtpCert, Callback, CRLDbHandle, ext) ->
no_dps;
DistPoints ->
Issuer = OtpCert#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.issuer,
- distpoints_lookup(DistPoints, Issuer, Callback, CRLDbHandle)
+ CRLs = distpoints_lookup(DistPoints, Issuer, Callback, CRLDbHandle),
+ dps_and_crls(DistPoints, CRLs, [])
end;
dps_and_crls(OtpCert, Callback, CRLDbHandle, same_issuer) ->
@@ -2146,7 +2237,13 @@ dps_and_crls(OtpCert, Callback, CRLDbHandle, same_issuer) ->
end, GenNames),
[{DP, {CRL, public_key:der_decode('CertificateList', CRL)}} || CRL <- CRLs].
-distpoints_lookup([], _, _, _) ->
+dps_and_crls([], _, Acc) ->
+ Acc;
+dps_and_crls([DP | Rest], CRLs, Acc) ->
+ DpCRL = [{DP, {CRL, public_key:der_decode('CertificateList', CRL)}} || CRL <- CRLs],
+ dps_and_crls(Rest, CRLs, DpCRL ++ Acc).
+
+distpoints_lookup([],_, _, _) ->
[];
distpoints_lookup([DistPoint | Rest], Issuer, Callback, CRLDbHandle) ->
Result =
@@ -2161,30 +2258,78 @@ distpoints_lookup([DistPoint | Rest], Issuer, Callback, CRLDbHandle) ->
not_available ->
distpoints_lookup(Rest, Issuer, Callback, CRLDbHandle);
CRLs ->
- [{DistPoint, {CRL, public_key:der_decode('CertificateList', CRL)}} || CRL <- CRLs]
+ CRLs
end.
-cert_sign(?rsaEncryption) ->
+sign_algo(?rsaEncryption) ->
rsa;
-cert_sign(?'id-ecPublicKey') ->
+sign_algo(?'id-ecPublicKey') ->
ecdsa;
-cert_sign(?'id-dsa') ->
+sign_algo(?'id-dsa') ->
dsa;
-cert_sign(Alg) ->
+sign_algo(Alg) ->
{_, Sign} =public_key:pkix_sign_types(Alg),
Sign.
-is_acceptable_hash_sign({_, Sign} = Algos, Sign, _, SupportedHashSigns) ->
- is_acceptable_hash_sign(Algos, SupportedHashSigns);
-is_acceptable_hash_sign(Algos,_, KeyExAlgo, SupportedHashSigns) when KeyExAlgo == dh_ecdsa;
- KeyExAlgo == ecdh_rsa;
- KeyExAlgo == ecdh_ecdsa ->
+is_acceptable_hash_sign(Algos, _, _, KeyExAlgo, SupportedHashSigns) when
+ KeyExAlgo == dh_dss;
+ KeyExAlgo == dh_rsa;
+ KeyExAlgo == dh_ecdsa ->
+ %% dh_* could be called only dh in TLS-1.2
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign(Algos, rsa, ecdsa, ecdh_rsa, SupportedHashSigns) ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign({_, rsa} = Algos, rsa, _, dhe_rsa, SupportedHashSigns) ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign({_, rsa} = Algos, rsa, rsa, ecdhe_rsa, SupportedHashSigns) ->
is_acceptable_hash_sign(Algos, SupportedHashSigns);
-is_acceptable_hash_sign(_,_,_,_) ->
- false.
+is_acceptable_hash_sign({_, rsa} = Algos, rsa, rsa, rsa, SupportedHashSigns) ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign({_, rsa} = Algos, rsa, _, srp_rsa, SupportedHashSigns) ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign({_, rsa} = Algos, rsa, _, rsa_psk, SupportedHashSigns) ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign({_, dsa} = Algos, dsa, _, dhe_dss, SupportedHashSigns) ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign({_, dsa} = Algos, dsa, _, srp_dss, SupportedHashSigns) ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign({_, ecdsa} = Algos, ecdsa, _, dhe_ecdsa, SupportedHashSigns) ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign({_, ecdsa} = Algos, ecdsa, ecdsa, ecdh_ecdsa, SupportedHashSigns) ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign({_, ecdsa} = Algos, ecdsa, ecdsa, ecdhe_ecdsa, SupportedHashSigns) ->
+ is_acceptable_hash_sign(Algos, SupportedHashSigns);
+is_acceptable_hash_sign(_, _, _, KeyExAlgo, _) when
+ KeyExAlgo == psk;
+ KeyExAlgo == dhe_psk;
+ KeyExAlgo == srp_anon;
+ KeyExAlgo == dh_anon;
+ KeyExAlgo == ecdhe_anon
+ ->
+ true;
+is_acceptable_hash_sign(_,_, _,_,_) ->
+ false.
+
is_acceptable_hash_sign(Algos, SupportedHashSigns) ->
lists:member(Algos, SupportedHashSigns).
+is_acceptable_cert_type(Sign, _HashSigns, Types) ->
+ lists:member(sign_type(Sign), binary_to_list(Types)).
+
+is_supported_sign(Sign, HashSigns) ->
+ [] =/= lists:dropwhile(fun({_, S}) when S =/= Sign ->
+ true;
+ (_)->
+ false
+ end, HashSigns).
+sign_type(rsa) ->
+ ?RSA_SIGN;
+sign_type(dsa) ->
+ ?DSS_SIGN;
+sign_type(ecdsa) ->
+ ?ECDSA_SIGN.
+
+
bad_key(#'DSAPrivateKey'{}) ->
unacceptable_dsa_key;
bad_key(#'RSAPrivateKey'{}) ->
@@ -2192,11 +2337,11 @@ bad_key(#'RSAPrivateKey'{}) ->
bad_key(#'ECPrivateKey'{}) ->
unacceptable_ecdsa_key.
-available_signature_algs(undefined, SupportedHashSigns, _, {Major, Minor}) when
- (Major >= 3) andalso (Minor >= 3) ->
+available_signature_algs(undefined, SupportedHashSigns, _, Version) when
+ Version >= {3,3} ->
SupportedHashSigns;
available_signature_algs(#hash_sign_algos{hash_sign_algos = ClientHashSigns}, SupportedHashSigns,
- _, {Major, Minor}) when (Major >= 3) andalso (Minor >= 3) ->
+ _, Version) when Version >= {3,3} ->
sets:to_list(sets:intersection(sets:from_list(ClientHashSigns),
sets:from_list(SupportedHashSigns)));
available_signature_algs(_, _, _, _) ->
diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl
index fde92035a2..324b7dbde3 100644
--- a/lib/ssl/src/ssl_handshake.hrl
+++ b/lib/ssl/src/ssl_handshake.hrl
@@ -80,6 +80,9 @@
-define(CLIENT_KEY_EXCHANGE, 16).
-define(FINISHED, 20).
+-define(MAX_UNIT24, 8388607).
+-define(DEFAULT_MAX_HANDSHAKE_SIZE, (256*1024)).
+
-record(random, {
gmt_unix_time, % uint32
random_bytes % opaque random_bytes[28]
diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index c19c1787ff..24ac34653e 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -76,7 +76,7 @@
-define(ALL_SUPPORTED_VERSIONS, ['tlsv1.2', 'tlsv1.1', tlsv1]).
-define(MIN_SUPPORTED_VERSIONS, ['tlsv1.1', tlsv1]).
-define(ALL_DATAGRAM_SUPPORTED_VERSIONS, ['dtlsv1.2', dtlsv1]).
--define(MIN_DATAGRAM_SUPPORTED_VERSIONS, ['dtlsv1.2', dtlsv1]).
+-define(MIN_DATAGRAM_SUPPORTED_VERSIONS, [dtlsv1]).
-define('24H_in_msec', 86400000).
-define('24H_in_sec', 86400).
@@ -140,8 +140,11 @@
crl_check :: boolean() | peer | best_effort,
crl_cache,
signature_algs,
- v2_hello_compatible :: boolean()
- }).
+ eccs,
+ honor_ecc_order :: boolean(),
+ v2_hello_compatible :: boolean(),
+ max_handshake_size :: integer()
+ }).
-record(socket_options,
{
@@ -154,7 +157,8 @@
-record(config, {ssl, %% SSL parameters
inet_user, %% User set inet options
- emulated, %% Emulated option list or "inherit_tracker" pid
+ emulated, %% Emulated option list or "inherit_tracker" pid
+ udp_handler,
inet_ssl, %% inet options for internal ssl socket
transport_info, %% Callback info
connection_cb
diff --git a/lib/ssl/src/ssl_listen_tracker_sup.erl b/lib/ssl/src/ssl_listen_tracker_sup.erl
index 7f685a2ead..f7e97bcb76 100644
--- a/lib/ssl/src/ssl_listen_tracker_sup.erl
+++ b/lib/ssl/src/ssl_listen_tracker_sup.erl
@@ -57,10 +57,10 @@ init(_O) ->
MaxT = 3600,
Name = undefined, % As simple_one_for_one is used.
- StartFunc = {ssl_socket, start_link, []},
+ StartFunc = {tls_socket, start_link, []},
Restart = temporary, % E.g. should not be restarted
Shutdown = 4000,
- Modules = [ssl_socket],
+ Modules = [tls_socket],
Type = worker,
ChildSpec = {Name, StartFunc, Restart, Shutdown, Type, Modules},
diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index c7dcbaabe9..ca9aaf4660 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,10 +32,9 @@
new_session_id/1, clean_cert_db/2,
register_session/2, register_session/3, invalidate_session/2,
insert_crls/2, insert_crls/3, delete_crls/1, delete_crls/2,
- invalidate_session/3, invalidate_pem/1, clear_pem_cache/0, manager_name/1]).
+ invalidate_session/3, name/1]).
-% Spawn export
--export([init_session_validator/1, init_pem_cache_validator/1]).
+-export([init_session_validator/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@@ -52,9 +51,7 @@
session_lifetime :: integer(),
certificate_db :: db_handle(),
session_validation_timer :: reference(),
- last_delay_timer = {undefined, undefined},%% Keep for testing purposes
- last_pem_check :: erlang:timestamp(),
- clear_pem_cache :: integer(),
+ last_delay_timer = {undefined, undefined},%% Keep for testing purposes
session_cache_client_max :: integer(),
session_cache_server_max :: integer(),
session_server_invalidator :: undefined | pid(),
@@ -63,7 +60,6 @@
-define(GEN_UNIQUE_ID_MAX_TRIES, 10).
-define(SESSION_VALIDATION_INTERVAL, 60000).
--define(CLEAR_PEM_CACHE, 120000).
-define(CLEAN_SESSION_DB, 60000).
-define(CLEAN_CERT_DB, 500).
-define(DEFAULT_MAX_SESSION_CACHE, 1000).
@@ -74,14 +70,14 @@
%%====================================================================
%%--------------------------------------------------------------------
--spec manager_name(normal | dist) -> atom().
+-spec name(normal | dist) -> atom().
%%
%% Description: Returns the registered name of the ssl manager process
%% in the operation modes 'normal' and 'dist'.
%%--------------------------------------------------------------------
-manager_name(normal) ->
+name(normal) ->
?MODULE;
-manager_name(dist) ->
+name(dist) ->
list_to_atom(atom_to_list(?MODULE) ++ "dist").
%%--------------------------------------------------------------------
@@ -91,9 +87,10 @@ manager_name(dist) ->
%% and certificate caching.
%%--------------------------------------------------------------------
start_link(Opts) ->
- DistMangerName = manager_name(normal),
- gen_server:start_link({local, DistMangerName},
- ?MODULE, [DistMangerName, Opts], []).
+ MangerName = name(normal),
+ CacheName = ssl_pem_cache:name(normal),
+ gen_server:start_link({local, MangerName},
+ ?MODULE, [MangerName, CacheName, Opts], []).
%%--------------------------------------------------------------------
-spec start_link_dist(list()) -> {ok, pid()} | ignore | {error, term()}.
@@ -102,24 +99,21 @@ start_link(Opts) ->
%% be used by the erlang distribution. Note disables soft upgrade!
%%--------------------------------------------------------------------
start_link_dist(Opts) ->
- DistMangerName = manager_name(dist),
+ DistMangerName = name(dist),
+ DistCacheName = ssl_pem_cache:name(dist),
gen_server:start_link({local, DistMangerName},
- ?MODULE, [DistMangerName, Opts], []).
+ ?MODULE, [DistMangerName, DistCacheName, Opts], []).
%%--------------------------------------------------------------------
-spec connection_init(binary()| {der, list()}, client | server,
{Cb :: atom(), Handle:: term()}) ->
- {ok, certdb_ref(), db_handle(), db_handle(),
- db_handle(), db_handle(), CRLInfo::term()}.
+ {ok, map()}.
%%
%% Description: Do necessary initializations for a new connection.
%%--------------------------------------------------------------------
connection_init({der, _} = Trustedcerts, Role, CRLCache) ->
- call({connection_init, Trustedcerts, Role, CRLCache});
-
-connection_init(<<>> = Trustedcerts, Role, CRLCache) ->
- call({connection_init, Trustedcerts, Role, CRLCache});
-
+ {ok, Extracted} = ssl_pkix_db:extract_trusted_certs(Trustedcerts),
+ call({connection_init, Extracted, Role, CRLCache});
connection_init(Trustedcerts, Role, CRLCache) ->
call({connection_init, Trustedcerts, Role, CRLCache}).
@@ -129,26 +123,14 @@ connection_init(Trustedcerts, Role, CRLCache) ->
%% Description: Cache a pem file and return its content.
%%--------------------------------------------------------------------
cache_pem_file(File, DbHandle) ->
- case ssl_pkix_db:lookup_cached_pem(DbHandle, File) of
- [{Content,_}] ->
- {ok, Content};
- [Content] ->
+ case ssl_pkix_db:lookup(File, DbHandle) of
+ [Content] ->
{ok, Content};
undefined ->
- call({cache_pem, File})
+ ssl_pem_cache:insert(File)
end.
%%--------------------------------------------------------------------
--spec clear_pem_cache() -> ok.
-%%
-%% Description: Clear the PEM cache
-%%--------------------------------------------------------------------
-clear_pem_cache() ->
- %% Not supported for distribution at the moement, should it be?
- put(ssl_manager, manager_name(normal)),
- call(unconditionally_clear_pem_cache).
-
-%%--------------------------------------------------------------------
-spec lookup_trusted_cert(term(), reference(), serialnumber(), issuer()) ->
undefined |
{ok, {der_cert(), #'OTPCertificate'{}}}.
@@ -205,26 +187,22 @@ invalidate_session(Port, Session) ->
load_mitigation(),
cast({invalidate_session, Port, Session}).
--spec invalidate_pem(File::binary()) -> ok.
-invalidate_pem(File) ->
- cast({invalidate_pem, File}).
-
insert_crls(Path, CRLs)->
insert_crls(Path, CRLs, normal).
insert_crls(?NO_DIST_POINT_PATH = Path, CRLs, ManagerType)->
- put(ssl_manager, manager_name(ManagerType)),
+ put(ssl_manager, name(ManagerType)),
cast({insert_crls, Path, CRLs});
insert_crls(Path, CRLs, ManagerType)->
- put(ssl_manager, manager_name(ManagerType)),
+ put(ssl_manager, name(ManagerType)),
call({insert_crls, Path, CRLs}).
delete_crls(Path)->
delete_crls(Path, normal).
delete_crls(?NO_DIST_POINT_PATH = Path, ManagerType)->
- put(ssl_manager, manager_name(ManagerType)),
+ put(ssl_manager, name(ManagerType)),
cast({delete_crls, Path});
delete_crls(Path, ManagerType)->
- put(ssl_manager, manager_name(ManagerType)),
+ put(ssl_manager, name(ManagerType)),
call({delete_crls, Path}).
%%====================================================================
@@ -238,13 +216,14 @@ delete_crls(Path, ManagerType)->
%%
%% Description: Initiates the server
%%--------------------------------------------------------------------
-init([Name, Opts]) ->
- put(ssl_manager, Name),
+init([ManagerName, PemCacheName, Opts]) ->
+ put(ssl_manager, ManagerName),
+ put(ssl_pem_cache, PemCacheName),
process_flag(trap_exit, true),
CacheCb = proplists:get_value(session_cb, Opts, ssl_session_cache),
SessionLifeTime =
proplists:get_value(session_lifetime, Opts, ?'24H_in_sec'),
- CertDb = ssl_pkix_db:create(),
+ CertDb = ssl_pkix_db:create(PemCacheName),
ClientSessionCache =
CacheCb:init([{role, client} |
proplists:get_value(session_cb_init_args, Opts, [])]),
@@ -253,16 +232,12 @@ init([Name, Opts]) ->
proplists:get_value(session_cb_init_args, Opts, [])]),
Timer = erlang:send_after(SessionLifeTime * 1000 + 5000,
self(), validate_sessions),
- Interval = pem_check_interval(),
- erlang:send_after(Interval, self(), clear_pem_cache),
{ok, #state{certificate_db = CertDb,
session_cache_client = ClientSessionCache,
session_cache_server = ServerSessionCache,
session_cache_cb = CacheCb,
session_lifetime = SessionLifeTime,
session_validation_timer = Timer,
- last_pem_check = os:timestamp(),
- clear_pem_cache = Interval,
session_cache_client_max =
max_session_cache_size(session_cache_client_max),
session_cache_server_max =
@@ -285,18 +260,25 @@ init([Name, Opts]) ->
handle_call({{connection_init, <<>>, Role, {CRLCb, UserCRLDb}}, _Pid}, _From,
#state{certificate_db = [CertDb, FileRefDb, PemChace | _] = Db} = State) ->
Ref = make_ref(),
- Result = {ok, Ref, CertDb, FileRefDb, PemChace,
- session_cache(Role, State), {CRLCb, crl_db_info(Db, UserCRLDb)}},
- {reply, Result, State#state{certificate_db = Db}};
+ {reply, {ok, #{cert_db_ref => Ref,
+ cert_db_handle => CertDb,
+ fileref_db_handle => FileRefDb,
+ pem_cache => PemChace,
+ session_cache => session_cache(Role, State),
+ crl_db_info => {CRLCb, crl_db_info(Db, UserCRLDb)}}}, State};
handle_call({{connection_init, Trustedcerts, Role, {CRLCb, UserCRLDb}}, Pid}, _From,
#state{certificate_db = [CertDb, FileRefDb, PemChace | _] = Db} = State) ->
case add_trusted_certs(Pid, Trustedcerts, Db) of
{ok, Ref} ->
- {reply, {ok, Ref, CertDb, FileRefDb, PemChace, session_cache(Role, State),
- {CRLCb, crl_db_info(Db, UserCRLDb)}}, State};
- {error, _} = Error ->
- {reply, Error, State}
+ {reply, {ok, #{cert_db_ref => Ref,
+ cert_db_handle => CertDb,
+ fileref_db_handle => FileRefDb,
+ pem_cache => PemChace,
+ session_cache => session_cache(Role, State),
+ crl_db_info => {CRLCb, crl_db_info(Db, UserCRLDb)}}}, State};
+ {error, _} = Error ->
+ {reply, Error, State}
end;
handle_call({{insert_crls, Path, CRLs}, _}, _From,
@@ -313,21 +295,7 @@ handle_call({{new_session_id, Port}, _},
_, #state{session_cache_cb = CacheCb,
session_cache_server = Cache} = State) ->
Id = new_id(Port, ?GEN_UNIQUE_ID_MAX_TRIES, Cache, CacheCb),
- {reply, Id, State};
-
-handle_call({{cache_pem,File}, _Pid}, _,
- #state{certificate_db = Db} = State) ->
- try ssl_pkix_db:cache_pem_file(File, Db) of
- Result ->
- {reply, Result, State}
- catch
- _:Reason ->
- {reply, {error, Reason}, State}
- end;
-handle_call({unconditionally_clear_pem_cache, _},_,
- #state{certificate_db = [_,_,PemChace | _]} = State) ->
- ssl_pkix_db:clear(PemChace),
- {reply, ok, State}.
+ {reply, Id, State}.
%%--------------------------------------------------------------------
-spec handle_cast(msg(), #state{}) -> {noreply, #state{}}.
@@ -365,11 +333,6 @@ handle_cast({insert_crls, Path, CRLs},
handle_cast({delete_crls, CRLsOrPath},
#state{certificate_db = Db} = State) ->
ssl_pkix_db:remove_crls(Db, CRLsOrPath),
- {noreply, State};
-
-handle_cast({invalidate_pem, File},
- #state{certificate_db = [_, _, PemCache | _]} = State) ->
- ssl_pkix_db:remove(File, PemCache),
{noreply, State}.
%%--------------------------------------------------------------------
@@ -401,22 +364,14 @@ handle_info({delayed_clean_session, Key, Cache}, #state{session_cache_cb = Cache
CacheCb:delete(Cache, Key),
{noreply, State};
-handle_info(clear_pem_cache, #state{certificate_db = [_,_,PemChace | _],
- clear_pem_cache = Interval,
- last_pem_check = CheckPoint} = State) ->
- NewCheckPoint = os:timestamp(),
- start_pem_cache_validator(PemChace, CheckPoint),
- erlang:send_after(Interval, self(), clear_pem_cache),
- {noreply, State#state{last_pem_check = NewCheckPoint}};
-
handle_info({clean_cert_db, Ref, File},
- #state{certificate_db = [CertDb,RefDb, PemCache | _]} = State) ->
+ #state{certificate_db = [CertDb, {RefDb, FileMapDb} | _]} = State) ->
case ssl_pkix_db:lookup(Ref, RefDb) of
undefined -> %% Alredy cleaned
ok;
_ ->
- clean_cert_db(Ref, CertDb, RefDb, PemCache, File)
+ clean_cert_db(Ref, CertDb, RefDb, FileMapDb, File)
end,
{noreply, State};
@@ -569,16 +524,11 @@ new_id(Port, Tries, Cache, CacheCb) ->
new_id(Port, Tries - 1, Cache, CacheCb)
end.
-clean_cert_db(Ref, CertDb, RefDb, PemCache, File) ->
+clean_cert_db(Ref, CertDb, RefDb, FileMapDb, File) ->
case ssl_pkix_db:ref_count(Ref, RefDb, 0) of
0 ->
- case ssl_pkix_db:lookup_cached_pem(PemCache, File) of
- [{Content, Ref}] ->
- ssl_pkix_db:insert(File, Content, PemCache);
- _ ->
- ok
- end,
ssl_pkix_db:remove(Ref, RefDb),
+ ssl_pkix_db:remove(File, FileMapDb),
ssl_pkix_db:remove_trusted_certs(Ref, CertDb);
_ ->
ok
@@ -662,42 +612,6 @@ exists_equivalent(#session{
exists_equivalent(Session, [ _ | Rest]) ->
exists_equivalent(Session, Rest).
-start_pem_cache_validator(PemCache, CheckPoint) ->
- spawn_link(?MODULE, init_pem_cache_validator,
- [[get(ssl_manager), PemCache, CheckPoint]]).
-
-init_pem_cache_validator([SslManagerName, PemCache, CheckPoint]) ->
- put(ssl_manager, SslManagerName),
- ssl_pkix_db:foldl(fun pem_cache_validate/2,
- CheckPoint, PemCache).
-
-pem_cache_validate({File, _}, CheckPoint) ->
- case file:read_file_info(File, []) of
- {ok, #file_info{mtime = Time}} ->
- case is_before_checkpoint(Time, CheckPoint) of
- true ->
- ok;
- false ->
- invalidate_pem(File)
- end;
- _ ->
- invalidate_pem(File)
- end,
- CheckPoint.
-
-pem_check_interval() ->
- case application:get_env(ssl, ssl_pem_cache_clean) of
- {ok, Interval} when is_integer(Interval) ->
- Interval;
- _ ->
- ?CLEAR_PEM_CACHE
- end.
-
-is_before_checkpoint(Time, CheckPoint) ->
- calendar:datetime_to_gregorian_seconds(
- calendar:now_to_datetime(CheckPoint)) -
- calendar:datetime_to_gregorian_seconds(Time) > 0.
-
add_trusted_certs(Pid, Trustedcerts, Db) ->
try
ssl_pkix_db:add_trusted_certs(Pid, Trustedcerts, Db)
diff --git a/lib/ssl/src/ssl_pem_cache.erl b/lib/ssl/src/ssl_pem_cache.erl
new file mode 100644
index 0000000000..6cc0729208
--- /dev/null
+++ b/lib/ssl/src/ssl_pem_cache.erl
@@ -0,0 +1,266 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 20016-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%----------------------------------------------------------------------
+%% Purpose: Manages ssl sessions and trusted certifacates
+%%----------------------------------------------------------------------
+
+-module(ssl_pem_cache).
+-behaviour(gen_server).
+
+%% Internal application API
+-export([start_link/1,
+ start_link_dist/1,
+ name/1,
+ insert/1,
+ clear/0]).
+
+% Spawn export
+-export([init_pem_cache_validator/1]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+-include("ssl_handshake.hrl").
+-include("ssl_internal.hrl").
+-include_lib("kernel/include/file.hrl").
+
+-record(state, {
+ pem_cache,
+ last_pem_check :: erlang:timestamp(),
+ clear :: integer()
+ }).
+
+-define(CLEAR_PEM_CACHE, 120000).
+-define(DEFAULT_MAX_SESSION_CACHE, 1000).
+
+%%====================================================================
+%% API
+%%====================================================================
+
+%%--------------------------------------------------------------------
+-spec name(normal | dist) -> atom().
+%%
+%% Description: Returns the registered name of the ssl cache process
+%% in the operation modes 'normal' and 'dist'.
+%%--------------------------------------------------------------------
+name(normal) ->
+ ?MODULE;
+name(dist) ->
+ list_to_atom(atom_to_list(?MODULE) ++ "dist").
+
+%%--------------------------------------------------------------------
+-spec start_link(list()) -> {ok, pid()} | ignore | {error, term()}.
+%%
+%% Description: Starts the ssl pem cache handler
+%%--------------------------------------------------------------------
+start_link(_) ->
+ CacheName = name(normal),
+ gen_server:start_link({local, CacheName},
+ ?MODULE, [CacheName], []).
+
+%%--------------------------------------------------------------------
+-spec start_link_dist(list()) -> {ok, pid()} | ignore | {error, term()}.
+%%
+%% Description: Starts a special instance of the ssl manager to
+%% be used by the erlang distribution. Note disables soft upgrade!
+%%--------------------------------------------------------------------
+start_link_dist(_) ->
+ DistCacheName = name(dist),
+ gen_server:start_link({local, DistCacheName},
+ ?MODULE, [DistCacheName], []).
+
+
+%%--------------------------------------------------------------------
+-spec insert(binary()) -> {ok, term()} | {error, reason()}.
+%%
+%% Description: Cache a pem file and return its content.
+%%--------------------------------------------------------------------
+insert(File) ->
+ {ok, PemBin} = file:read_file(File),
+ Content = public_key:pem_decode(PemBin),
+ case bypass_cache() of
+ true ->
+ {ok, Content};
+ false ->
+ cast({cache_pem, File, Content}),
+ {ok, Content}
+ end.
+
+%%--------------------------------------------------------------------
+-spec clear() -> ok.
+%%
+%% Description: Clear the PEM cache
+%%--------------------------------------------------------------------
+clear() ->
+ %% Not supported for distribution at the moement, should it be?
+ put(ssl_pem_cache, name(normal)),
+ call(unconditionally_clear_pem_cache).
+
+-spec invalidate_pem(File::binary()) -> ok.
+invalidate_pem(File) ->
+ cast({invalidate_pem, File}).
+
+%%====================================================================
+%% gen_server callbacks
+%%====================================================================
+
+%%--------------------------------------------------------------------
+-spec init(list()) -> {ok, #state{}}.
+%% Possible return values not used now.
+%% | {ok, #state{}, timeout()} | ignore | {stop, term()}.
+%%
+%% Description: Initiates the server
+%%--------------------------------------------------------------------
+init([Name]) ->
+ put(ssl_pem_cache, Name),
+ process_flag(trap_exit, true),
+ PemCache = ssl_pkix_db:create_pem_cache(Name),
+ Interval = pem_check_interval(),
+ erlang:send_after(Interval, self(), clear_pem_cache),
+ {ok, #state{pem_cache = PemCache,
+ last_pem_check = os:timestamp(),
+ clear = Interval
+ }}.
+
+%%--------------------------------------------------------------------
+-spec handle_call(msg(), from(), #state{}) -> {reply, reply(), #state{}}.
+%% Possible return values not used now.
+%% {reply, reply(), #state{}, timeout()} |
+%% {noreply, #state{}} |
+%% {noreply, #state{}, timeout()} |
+%% {stop, reason(), reply(), #state{}} |
+%% {stop, reason(), #state{}}.
+%%
+%% Description: Handling call messages
+%%--------------------------------------------------------------------
+handle_call({unconditionally_clear_pem_cache, _},_,
+ #state{pem_cache = PemCache} = State) ->
+ ssl_pkix_db:clear(PemCache),
+ {reply, ok, State}.
+
+%%--------------------------------------------------------------------
+-spec handle_cast(msg(), #state{}) -> {noreply, #state{}}.
+%% Possible return values not used now.
+%% | {noreply, #state{}, timeout()} |
+%% {stop, reason(), #state{}}.
+%%
+%% Description: Handling cast messages
+%%--------------------------------------------------------------------
+handle_cast({cache_pem, File, Content}, #state{pem_cache = Db} = State) ->
+ ssl_pkix_db:insert(File, Content, Db),
+ {noreply, State};
+
+handle_cast({invalidate_pem, File}, #state{pem_cache = Db} = State) ->
+ ssl_pkix_db:remove(File, Db),
+ {noreply, State}.
+
+
+%%--------------------------------------------------------------------
+-spec handle_info(msg(), #state{}) -> {noreply, #state{}}.
+%% Possible return values not used now.
+%% |{noreply, #state{}, timeout()} |
+%% {stop, reason(), #state{}}.
+%%
+%% Description: Handling all non call/cast messages
+%%-------------------------------------------------------------------
+handle_info(clear_pem_cache, #state{pem_cache = PemCache,
+ clear = Interval,
+ last_pem_check = CheckPoint} = State) ->
+ NewCheckPoint = os:timestamp(),
+ start_pem_cache_validator(PemCache, CheckPoint),
+ erlang:send_after(Interval, self(), clear_pem_cache),
+ {noreply, State#state{last_pem_check = NewCheckPoint}};
+
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+%%--------------------------------------------------------------------
+-spec terminate(reason(), #state{}) -> ok.
+%%
+%% Description: This function is called by a gen_server when it is about to
+%% terminate. It should be the opposite of Module:init/1 and do any necessary
+%% cleaning up. When it returns, the gen_server terminates with Reason.
+%% The return value is ignored.
+%%--------------------------------------------------------------------
+terminate(_Reason, #state{}) ->
+ ok.
+
+%%--------------------------------------------------------------------
+-spec code_change(term(), #state{}, list()) -> {ok, #state{}}.
+%%
+%% Description: Convert process state when code is changed
+%%--------------------------------------------------------------------
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+call(Msg) ->
+ gen_server:call(get(ssl_pem_cache), {Msg, self()}, infinity).
+
+cast(Msg) ->
+ gen_server:cast(get(ssl_pem_cache), Msg).
+
+start_pem_cache_validator(PemCache, CheckPoint) ->
+ spawn_link(?MODULE, init_pem_cache_validator,
+ [[get(ssl_pem_cache), PemCache, CheckPoint]]).
+
+init_pem_cache_validator([CacheName, PemCache, CheckPoint]) ->
+ put(ssl_pem_cache, CacheName),
+ ssl_pkix_db:foldl(fun pem_cache_validate/2,
+ CheckPoint, PemCache).
+
+pem_cache_validate({File, _}, CheckPoint) ->
+ case file:read_file_info(File, []) of
+ {ok, #file_info{mtime = Time}} ->
+ case is_before_checkpoint(Time, CheckPoint) of
+ true ->
+ ok;
+ false ->
+ invalidate_pem(File)
+ end;
+ _ ->
+ invalidate_pem(File)
+ end,
+ CheckPoint.
+
+is_before_checkpoint(Time, CheckPoint) ->
+ calendar:datetime_to_gregorian_seconds(
+ calendar:now_to_datetime(CheckPoint)) -
+ calendar:datetime_to_gregorian_seconds(Time) > 0.
+
+pem_check_interval() ->
+ case application:get_env(ssl, ssl_pem_cache_clean) of
+ {ok, Interval} when is_integer(Interval) ->
+ Interval;
+ _ ->
+ ?CLEAR_PEM_CACHE
+ end.
+
+bypass_cache() ->
+ case application:get_env(ssl, bypass_pem_cache) of
+ {ok, Bool} when is_boolean(Bool) ->
+ Bool;
+ _ ->
+ false
+ end.
diff --git a/lib/ssl/src/ssl_pkix_db.erl b/lib/ssl/src/ssl_pkix_db.erl
index b16903d7c7..b28636569d 100644
--- a/lib/ssl/src/ssl_pkix_db.erl
+++ b/lib/ssl/src/ssl_pkix_db.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -28,36 +28,43 @@
-include_lib("public_key/include/public_key.hrl").
-include_lib("kernel/include/file.hrl").
--export([create/0, add_crls/3, remove_crls/2, remove/1, add_trusted_certs/3,
+-export([create/1, create_pem_cache/1,
+ add_crls/3, remove_crls/2, remove/1, add_trusted_certs/3,
+ extract_trusted_certs/1,
remove_trusted_certs/2, insert/3, remove/2, clear/1, db_size/1,
ref_count/3, lookup_trusted_cert/4, foldl/3, select_cert_by_issuer/2,
- lookup_cached_pem/2, cache_pem_file/2, cache_pem_file/3,
- lookup/2]).
+ decode_pem_file/1, lookup/2]).
%%====================================================================
%% Internal application API
%%====================================================================
%%--------------------------------------------------------------------
--spec create() -> [db_handle(),...].
+-spec create(atom()) -> [db_handle(),...].
%%
%% Description: Creates a new certificate db.
%% Note: lookup_trusted_cert/4 may be called from any process but only
%% the process that called create may call the other functions.
%%--------------------------------------------------------------------
-create() ->
+create(PEMCacheName) ->
[%% Let connection process delete trusted certs
%% that can only belong to one connection. (Supplied directly
%% on DER format to ssl:connect/listen.)
ets:new(ssl_otp_cacertificate_db, [set, public]),
%% Let connection processes call ref_count/3 directly
- ets:new(ssl_otp_ca_file_ref, [set, public]),
- ets:new(ssl_otp_pem_cache, [set, protected]),
+ {ets:new(ssl_otp_ca_file_ref, [set, public]),
+ ets:new(ssl_otp_ca_ref_file_mapping, [set, protected])
+ },
+ %% Lookups in named table owned by ssl_pem_cache process
+ PEMCacheName,
%% Default cache
{ets:new(ssl_otp_crl_cache, [set, protected]),
ets:new(ssl_otp_crl_issuer_mapping, [bag, protected])}
].
+create_pem_cache(Name) ->
+ ets:new(Name, [named_table, set, protected]).
+
%%--------------------------------------------------------------------
-spec remove([db_handle()]) -> ok.
%%
@@ -69,6 +76,10 @@ remove(Dbs) ->
true = ets:delete(Db1);
(undefined) ->
ok;
+ (ssl_pem_cache) ->
+ ok;
+ (ssl_pem_cache_dist) ->
+ ok;
(Db) ->
true = ets:delete(Db)
end, Dbs).
@@ -82,19 +93,24 @@ remove(Dbs) ->
%% <SerialNumber, Issuer>. Ref is used as it is specified
%% for each connection which certificates are trusted.
%%--------------------------------------------------------------------
-lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer) ->
+lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer) when is_reference(Ref) ->
case lookup({Ref, SerialNumber, Issuer}, DbHandle) of
undefined ->
undefined;
[Certs] ->
{ok, Certs}
+ end;
+lookup_trusted_cert(_DbHandle, {extracted,Certs}, SerialNumber, Issuer) ->
+ try
+ [throw(Cert)
+ || {decoded, {{_Ref,CertSerial,CertIssuer}, Cert}} <- Certs,
+ CertSerial =:= SerialNumber, CertIssuer =:= Issuer],
+ undefined
+ catch
+ Cert ->
+ {ok, Cert}
end.
-lookup_cached_pem([_, _, PemChache | _], File) ->
- lookup_cached_pem(PemChache, File);
-lookup_cached_pem(PemChache, File) ->
- lookup(File, PemChache).
-
%%--------------------------------------------------------------------
-spec add_trusted_certs(pid(), {erlang:timestamp(), string()} |
{der, list()}, [db_handle()]) -> {ok, [db_handle()]}.
@@ -103,43 +119,48 @@ lookup_cached_pem(PemChache, File) ->
%% runtime database. Returns Ref that should be handed to lookup_trusted_cert
%% together with the cert serialnumber and issuer.
%%--------------------------------------------------------------------
+add_trusted_certs(_Pid, {extracted, _} = Certs, _) ->
+ {ok, Certs};
+
add_trusted_certs(_Pid, {der, DerList}, [CertDb, _,_ | _]) ->
NewRef = make_ref(),
add_certs_from_der(DerList, NewRef, CertDb),
{ok, NewRef};
-add_trusted_certs(_Pid, File, [CertsDb, RefDb, PemChache | _] = Db) ->
- case lookup_cached_pem(Db, File) of
- [{_Content, Ref}] ->
+add_trusted_certs(_Pid, File, [ _, {RefDb, FileMapDb} | _] = Db) ->
+ case lookup(File, FileMapDb) of
+ [Ref] ->
ref_count(Ref, RefDb, 1),
{ok, Ref};
- [Content] ->
- Ref = make_ref(),
- update_counter(Ref, 1, RefDb),
- insert(File, {Content, Ref}, PemChache),
- add_certs_from_pem(Content, Ref, CertsDb),
- {ok, Ref};
undefined ->
new_trusted_cert_entry(File, Db)
end.
-%%--------------------------------------------------------------------
-%%
-%% Description: Cache file as binary in DB
-%%--------------------------------------------------------------------
--spec cache_pem_file(binary(), [db_handle()]) -> {ok, term()}.
-cache_pem_file(File, [_CertsDb, _RefDb, PemChache | _]) ->
- {ok, PemBin} = file:read_file(File),
- Content = public_key:pem_decode(PemBin),
- insert(File, Content, PemChache),
- {ok, Content}.
+extract_trusted_certs({der, DerList}) ->
+ {ok, {extracted, certs_from_der(DerList)}};
+extract_trusted_certs(File) ->
+ case file:read_file(File) of
+ {ok, PemBin} ->
+ Content = public_key:pem_decode(PemBin),
+ DerList = [Cert || {'Certificate', Cert, not_encrypted} <- Content],
+ {ok, {extracted, certs_from_der(DerList)}};
+ Error ->
+ %% Have to simulate a failure happening in a server for
+ %% external handlers.
+ {error, {badmatch, Error}}
+ end.
--spec cache_pem_file(reference(), binary(), [db_handle()]) -> {ok, term()}.
-cache_pem_file(Ref, File, [_CertsDb, _RefDb, PemChache| _]) ->
- {ok, PemBin} = file:read_file(File),
- Content = public_key:pem_decode(PemBin),
- insert(File, {Content, Ref}, PemChache),
- {ok, Content}.
+-spec decode_pem_file(binary()) -> {ok, term()}.
+decode_pem_file(File) ->
+ case file:read_file(File) of
+ {ok, PemBin} ->
+ Content = public_key:pem_decode(PemBin),
+ {ok, Content};
+ Error ->
+ %% Have to simulate a failure happening in a server for
+ %% external handlers.
+ {error, {badmatch, Error}}
+ end.
%%--------------------------------------------------------------------
-spec remove_trusted_certs(reference(), db_handle()) -> ok.
@@ -203,6 +224,10 @@ select_cert_by_issuer(Cache, Issuer) ->
%%
%% Description: Updates a reference counter in a <Db>.
%%--------------------------------------------------------------------
+ref_count({extracted, _}, _Db, _N) ->
+ not_cached;
+ref_count(Key, {Db, _}, N) ->
+ ref_count(Key, Db, N);
ref_count(Key, Db, N) ->
ets:update_counter(Db,Key,N).
@@ -235,9 +260,9 @@ insert(Key, Data, Db) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-update_counter(Key, Count, Db) ->
- true = ets:insert(Db, {Key, Count}),
- ok.
+init_ref_db(Ref, File, {RefDb, FileMapDb}) ->
+ true = ets:insert(RefDb, {Ref, 1}),
+ true = ets:insert(FileMapDb, {File, Ref}).
remove_certs(Ref, CertsDb) ->
true = ets:match_delete(CertsDb, {{Ref, '_', '_'}, '_'}),
@@ -248,29 +273,45 @@ add_certs_from_der(DerList, Ref, CertsDb) ->
[Add(Cert) || Cert <- DerList],
ok.
+certs_from_der(DerList) ->
+ Ref = make_ref(),
+ [Decoded || Cert <- DerList,
+ Decoded <- [decode_certs(Ref, Cert)],
+ Decoded =/= undefined].
+
add_certs_from_pem(PemEntries, Ref, CertsDb) ->
Add = fun(Cert) -> add_certs(Cert, Ref, CertsDb) end,
[Add(Cert) || {'Certificate', Cert, not_encrypted} <- PemEntries],
ok.
add_certs(Cert, Ref, CertsDb) ->
+ try
+ {decoded, {Key, Val}} = decode_certs(Ref, Cert),
+ insert(Key, Val, CertsDb)
+ catch
+ error:_ ->
+ ok
+ end.
+
+decode_certs(Ref, Cert) ->
try ErlCert = public_key:pkix_decode_cert(Cert, otp),
TBSCertificate = ErlCert#'OTPCertificate'.tbsCertificate,
SerialNumber = TBSCertificate#'OTPTBSCertificate'.serialNumber,
Issuer = public_key:pkix_normalize_name(
TBSCertificate#'OTPTBSCertificate'.issuer),
- insert({Ref, SerialNumber, Issuer}, {Cert,ErlCert}, CertsDb)
+ {decoded, {{Ref, SerialNumber, Issuer}, {Cert, ErlCert}}}
catch
error:_ ->
Report = io_lib:format("SSL WARNING: Ignoring a CA cert as "
"it could not be correctly decoded.~n", []),
- error_logger:info_report(Report)
+ error_logger:info_report(Report),
+ undefined
end.
-new_trusted_cert_entry(File, [CertsDb, RefDb, _ | _] = Db) ->
+new_trusted_cert_entry(File, [CertsDb, RefsDb, _ | _]) ->
Ref = make_ref(),
- update_counter(Ref, 1, RefDb),
- {ok, Content} = cache_pem_file(Ref, File, Db),
+ init_ref_db(Ref, File, RefsDb),
+ {ok, Content} = ssl_pem_cache:insert(File),
add_certs_from_pem(Content, Ref, CertsDb),
{ok, Ref}.
diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl
index 5bb1c92c2d..62c2ffce8b 100644
--- a/lib/ssl/src/ssl_record.erl
+++ b/lib/ssl/src/ssl_record.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -30,8 +30,7 @@
-include("ssl_alert.hrl").
%% Connection state handling
--export([init_connection_states/2,
- current_connection_state/2, pending_connection_state/2,
+-export([initial_security_params/1, current_connection_state/2, pending_connection_state/2,
activate_pending_connection_state/2,
set_security_params/3,
set_mac_secret/4,
@@ -39,135 +38,101 @@
set_pending_cipher_state/4,
set_renegotiation_flag/2,
set_client_verify_data/3,
- set_server_verify_data/3]).
-
-%% Encoding records
--export([encode_handshake/3, encode_alert_record/3,
- encode_change_cipher_spec/2, encode_data/3]).
+ set_server_verify_data/3,
+ empty_connection_state/2, initial_connection_state/2, record_protocol_role/1]).
%% Compression
-export([compress/3, uncompress/3, compressions/0]).
%% Payload encryption/decryption
--export([cipher/4, decipher/4, is_correct_mac/2,
- cipher_aead/4, decipher_aead/4]).
+-export([cipher/4, decipher/4, cipher_aead/4, is_correct_mac/2]).
--export_type([ssl_version/0, ssl_atom_version/0]).
+-export_type([ssl_version/0, ssl_atom_version/0, connection_states/0, connection_state/0]).
-type ssl_version() :: {integer(), integer()}.
-type ssl_atom_version() :: tls_record:tls_atom_version().
-
+-type connection_states() :: term(). %% Map
+-type connection_state() :: term(). %% Map
%%====================================================================
%% Internal application API
%%====================================================================
-%%--------------------------------------------------------------------
--spec init_connection_states(client | server, one_n_minus_one | zero_n | disabled ) ->
- #connection_states{}.
-%%
-%% Description: Creates a connection_states record with appropriate
-%% values for the initial SSL connection setup.
-%%--------------------------------------------------------------------
-init_connection_states(Role, BeastMitigation) ->
- ConnectionEnd = record_protocol_role(Role),
- Current = initial_connection_state(ConnectionEnd, BeastMitigation),
- Pending = empty_connection_state(ConnectionEnd, BeastMitigation),
- #connection_states{dtls_write_msg_seq = 1, % only used by dtls
- current_read = Current,
- pending_read = Pending,
- current_write = Current,
- pending_write = Pending
- }.
%%--------------------------------------------------------------------
--spec current_connection_state(#connection_states{}, read | write) ->
- #connection_state{}.
+-spec current_connection_state(connection_states(), read | write) ->
+ connection_state().
%%
-%% Description: Returns the instance of the connection_state record
-%% that is currently defined as the current conection state.
+%% Description: Returns the instance of the connection_state map
+%% that is currently defined as the current connection state.
%%--------------------------------------------------------------------
-current_connection_state(#connection_states{current_read = Current},
- read) ->
- Current;
-current_connection_state(#connection_states{current_write = Current},
- write) ->
- Current.
+current_connection_state(ConnectionStates, read) ->
+ maps:get(current_read, ConnectionStates);
+current_connection_state(ConnectionStates, write) ->
+ maps:get(current_write, ConnectionStates).
%%--------------------------------------------------------------------
--spec pending_connection_state(#connection_states{}, read | write) ->
- term().
+-spec pending_connection_state(connection_states(), read | write) ->
+ connection_state().
%%
-%% Description: Returns the instance of the connection_state record
-%% that is currently defined as the pending conection state.
+%% Description: Returns the instance of the connection_state map
+%% that is pendingly defined as the pending connection state.
%%--------------------------------------------------------------------
-pending_connection_state(#connection_states{pending_read = Pending},
- read) ->
- Pending;
-pending_connection_state(#connection_states{pending_write = Pending},
- write) ->
- Pending.
-
+pending_connection_state(ConnectionStates, read) ->
+ maps:get(pending_read, ConnectionStates);
+pending_connection_state(ConnectionStates, write) ->
+ maps:get(pending_write, ConnectionStates).
%%--------------------------------------------------------------------
--spec activate_pending_connection_state(#connection_states{}, read | write) ->
- #connection_states{}.
+-spec activate_pending_connection_state(connection_states(), read | write) ->
+ connection_states().
%%
%% Description: Creates a new instance of the connection_states record
%% where the pending state of <Type> has been activated.
%%--------------------------------------------------------------------
-activate_pending_connection_state(States =
- #connection_states{current_read = Current,
- pending_read = Pending},
+activate_pending_connection_state(#{current_read := Current,
+ pending_read := Pending} = States,
read) ->
- NewCurrent = Pending#connection_state{epoch = dtls_next_epoch(Current),
- sequence_number = 0},
- BeastMitigation = Pending#connection_state.beast_mitigation,
- SecParams = Pending#connection_state.security_parameters,
+ #{secure_renegotiation := SecureRenegotation} = Current,
+ #{beast_mitigation := BeastMitigation,
+ security_parameters := SecParams} = Pending,
+ NewCurrent = Pending#{sequence_number => 0},
ConnectionEnd = SecParams#security_parameters.connection_end,
EmptyPending = empty_connection_state(ConnectionEnd, BeastMitigation),
- SecureRenegotation = NewCurrent#connection_state.secure_renegotiation,
- NewPending = EmptyPending#connection_state{secure_renegotiation = SecureRenegotation},
- States#connection_states{current_read = NewCurrent,
- pending_read = NewPending
- };
-
-activate_pending_connection_state(States =
- #connection_states{current_write = Current,
- pending_write = Pending},
+ NewPending = EmptyPending#{secure_renegotiation => SecureRenegotation},
+ States#{current_read => NewCurrent,
+ pending_read => NewPending
+ };
+
+activate_pending_connection_state(#{current_write := Current,
+ pending_write := Pending} = States,
write) ->
- NewCurrent = Pending#connection_state{epoch = dtls_next_epoch(Current),
- sequence_number = 0},
- BeastMitigation = Pending#connection_state.beast_mitigation,
- SecParams = Pending#connection_state.security_parameters,
+ NewCurrent = Pending#{sequence_number => 0},
+ #{secure_renegotiation := SecureRenegotation} = Current,
+ #{beast_mitigation := BeastMitigation,
+ security_parameters := SecParams} = Pending,
ConnectionEnd = SecParams#security_parameters.connection_end,
EmptyPending = empty_connection_state(ConnectionEnd, BeastMitigation),
- SecureRenegotation = NewCurrent#connection_state.secure_renegotiation,
- NewPending = EmptyPending#connection_state{secure_renegotiation = SecureRenegotation},
- States#connection_states{current_write = NewCurrent,
- pending_write = NewPending
- }.
-
+ NewPending = EmptyPending#{secure_renegotiation => SecureRenegotation},
+ States#{current_write => NewCurrent,
+ pending_write => NewPending
+ }.
%%--------------------------------------------------------------------
-spec set_security_params(#security_parameters{}, #security_parameters{},
- #connection_states{}) -> #connection_states{}.
+ connection_states()) -> connection_states().
%%
%% Description: Creates a new instance of the connection_states record
%% where the pending states gets its security parameters updated.
%%--------------------------------------------------------------------
-set_security_params(ReadParams, WriteParams, States =
- #connection_states{pending_read = Read,
- pending_write = Write}) ->
- States#connection_states{pending_read =
- Read#connection_state{security_parameters =
- ReadParams},
- pending_write =
- Write#connection_state{security_parameters =
- WriteParams}
- }.
+set_security_params(ReadParams, WriteParams,
+ #{pending_read := Read,
+ pending_write := Write} = States) ->
+ States#{pending_read => Read#{security_parameters => ReadParams},
+ pending_write => Write#{security_parameters => WriteParams}
+ }.
%%--------------------------------------------------------------------
-spec set_mac_secret(binary(), binary(), client | server,
- #connection_states{}) -> #connection_states{}.
+ connection_states()) -> connection_states().
%%
%% Description: update the mac_secret field in pending connection states
%%--------------------------------------------------------------------
@@ -177,204 +142,132 @@ set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, server, States) ->
set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, States).
set_mac_secret(ReadMacSecret, WriteMacSecret,
- States = #connection_states{pending_read = Read,
- pending_write = Write}) ->
- States#connection_states{
- pending_read = Read#connection_state{mac_secret = ReadMacSecret},
- pending_write = Write#connection_state{mac_secret = WriteMacSecret}
+ States = #{pending_read := Read,
+ pending_write := Write}) ->
+ States#{pending_read => Read#{mac_secret => ReadMacSecret},
+ pending_write => Write#{mac_secret => WriteMacSecret}
}.
%%--------------------------------------------------------------------
--spec set_master_secret(binary(), #connection_states{}) -> #connection_states{}.
+-spec set_master_secret(binary(), connection_states()) -> connection_states().
%%
%% Description: Set master_secret in pending connection states
%%--------------------------------------------------------------------
set_master_secret(MasterSecret,
- States = #connection_states{pending_read = Read,
- pending_write = Write}) ->
- ReadSecPar = Read#connection_state.security_parameters,
- Read1 = Read#connection_state{
- security_parameters = ReadSecPar#security_parameters{
- master_secret = MasterSecret}},
- WriteSecPar = Write#connection_state.security_parameters,
- Write1 = Write#connection_state{
- security_parameters = WriteSecPar#security_parameters{
- master_secret = MasterSecret}},
- States#connection_states{pending_read = Read1, pending_write = Write1}.
+ States = #{pending_read := Read = #{security_parameters := ReadSecPar},
+ pending_write := Write = #{security_parameters := WriteSecPar}}) ->
+ Read1 = Read#{security_parameters => ReadSecPar#security_parameters{
+ master_secret = MasterSecret}},
+ Write1 = Write#{security_parameters => WriteSecPar#security_parameters{
+ master_secret = MasterSecret}},
+ States#{pending_read => Read1, pending_write => Write1}.
%%--------------------------------------------------------------------
--spec set_renegotiation_flag(boolean(), #connection_states{}) -> #connection_states{}.
+-spec set_renegotiation_flag(boolean(), connection_states()) -> connection_states().
%%
%% Description: Set secure_renegotiation in pending connection states
%%--------------------------------------------------------------------
-set_renegotiation_flag(Flag, #connection_states{
- current_read = CurrentRead0,
- current_write = CurrentWrite0,
- pending_read = PendingRead0,
- pending_write = PendingWrite0}
+set_renegotiation_flag(Flag, #{current_read := CurrentRead0,
+ current_write := CurrentWrite0,
+ pending_read := PendingRead0,
+ pending_write := PendingWrite0}
= ConnectionStates) ->
- CurrentRead = CurrentRead0#connection_state{secure_renegotiation = Flag},
- CurrentWrite = CurrentWrite0#connection_state{secure_renegotiation = Flag},
- PendingRead = PendingRead0#connection_state{secure_renegotiation = Flag},
- PendingWrite = PendingWrite0#connection_state{secure_renegotiation = Flag},
- ConnectionStates#connection_states{current_read = CurrentRead,
- current_write = CurrentWrite,
- pending_read = PendingRead,
- pending_write = PendingWrite}.
+ CurrentRead = CurrentRead0#{secure_renegotiation => Flag},
+ CurrentWrite = CurrentWrite0#{secure_renegotiation => Flag},
+ PendingRead = PendingRead0#{secure_renegotiation => Flag},
+ PendingWrite = PendingWrite0#{secure_renegotiation => Flag},
+ ConnectionStates#{current_read => CurrentRead,
+ current_write => CurrentWrite,
+ pending_read => PendingRead,
+ pending_write => PendingWrite}.
%%--------------------------------------------------------------------
-spec set_client_verify_data(current_read | current_write | current_both,
- binary(), #connection_states{})->
- #connection_states{}.
+ binary(), connection_states())->
+ connection_states().
%%
%% Description: Set verify data in connection states.
%%--------------------------------------------------------------------
set_client_verify_data(current_read, Data,
- #connection_states{current_read = CurrentRead0,
- pending_write = PendingWrite0}
+ #{current_read := CurrentRead0,
+ pending_write := PendingWrite0}
= ConnectionStates) ->
- CurrentRead = CurrentRead0#connection_state{client_verify_data = Data},
- PendingWrite = PendingWrite0#connection_state{client_verify_data = Data},
- ConnectionStates#connection_states{current_read = CurrentRead,
- pending_write = PendingWrite};
+ CurrentRead = CurrentRead0#{client_verify_data => Data},
+ PendingWrite = PendingWrite0#{client_verify_data => Data},
+ ConnectionStates#{current_read => CurrentRead,
+ pending_write => PendingWrite};
set_client_verify_data(current_write, Data,
- #connection_states{pending_read = PendingRead0,
- current_write = CurrentWrite0}
+ #{pending_read := PendingRead0,
+ current_write := CurrentWrite0}
= ConnectionStates) ->
- PendingRead = PendingRead0#connection_state{client_verify_data = Data},
- CurrentWrite = CurrentWrite0#connection_state{client_verify_data = Data},
- ConnectionStates#connection_states{pending_read = PendingRead,
- current_write = CurrentWrite};
+ PendingRead = PendingRead0#{client_verify_data => Data},
+ CurrentWrite = CurrentWrite0#{client_verify_data => Data},
+ ConnectionStates#{pending_read => PendingRead,
+ current_write => CurrentWrite};
set_client_verify_data(current_both, Data,
- #connection_states{current_read = CurrentRead0,
- current_write = CurrentWrite0}
+ #{current_read := CurrentRead0,
+ current_write := CurrentWrite0}
= ConnectionStates) ->
- CurrentRead = CurrentRead0#connection_state{client_verify_data = Data},
- CurrentWrite = CurrentWrite0#connection_state{client_verify_data = Data},
- ConnectionStates#connection_states{current_read = CurrentRead,
- current_write = CurrentWrite}.
+ CurrentRead = CurrentRead0#{client_verify_data => Data},
+ CurrentWrite = CurrentWrite0#{client_verify_data => Data},
+ ConnectionStates#{current_read => CurrentRead,
+ current_write => CurrentWrite}.
%%--------------------------------------------------------------------
-spec set_server_verify_data(current_read | current_write | current_both,
- binary(), #connection_states{})->
- #connection_states{}.
+ binary(), connection_states())->
+ connection_states().
%%
%% Description: Set verify data in pending connection states.
%%--------------------------------------------------------------------
set_server_verify_data(current_write, Data,
- #connection_states{pending_read = PendingRead0,
- current_write = CurrentWrite0}
+ #{pending_read := PendingRead0,
+ current_write := CurrentWrite0}
= ConnectionStates) ->
- PendingRead = PendingRead0#connection_state{server_verify_data = Data},
- CurrentWrite = CurrentWrite0#connection_state{server_verify_data = Data},
- ConnectionStates#connection_states{pending_read = PendingRead,
- current_write = CurrentWrite};
+ PendingRead = PendingRead0#{server_verify_data => Data},
+ CurrentWrite = CurrentWrite0#{server_verify_data => Data},
+ ConnectionStates#{pending_read => PendingRead,
+ current_write => CurrentWrite};
set_server_verify_data(current_read, Data,
- #connection_states{current_read = CurrentRead0,
- pending_write = PendingWrite0}
+ #{current_read := CurrentRead0,
+ pending_write := PendingWrite0}
= ConnectionStates) ->
- CurrentRead = CurrentRead0#connection_state{server_verify_data = Data},
- PendingWrite = PendingWrite0#connection_state{server_verify_data = Data},
- ConnectionStates#connection_states{current_read = CurrentRead,
- pending_write = PendingWrite};
+ CurrentRead = CurrentRead0#{server_verify_data => Data},
+ PendingWrite = PendingWrite0#{server_verify_data => Data},
+ ConnectionStates#{current_read => CurrentRead,
+ pending_write => PendingWrite};
set_server_verify_data(current_both, Data,
- #connection_states{current_read = CurrentRead0,
- current_write = CurrentWrite0}
+ #{current_read := CurrentRead0,
+ current_write := CurrentWrite0}
= ConnectionStates) ->
- CurrentRead = CurrentRead0#connection_state{server_verify_data = Data},
- CurrentWrite = CurrentWrite0#connection_state{server_verify_data = Data},
- ConnectionStates#connection_states{current_read = CurrentRead,
- current_write = CurrentWrite}.
+ CurrentRead = CurrentRead0#{server_verify_data => Data},
+ CurrentWrite = CurrentWrite0#{server_verify_data => Data},
+ ConnectionStates#{current_read => CurrentRead,
+ current_write => CurrentWrite}.
%%--------------------------------------------------------------------
--spec set_pending_cipher_state(#connection_states{}, #cipher_state{},
+-spec set_pending_cipher_state(connection_states(), #cipher_state{},
#cipher_state{}, client | server) ->
- #connection_states{}.
+ connection_states().
%%
%% Description: Set the cipher state in the specified pending connection state.
%%--------------------------------------------------------------------
-set_pending_cipher_state(#connection_states{pending_read = Read,
- pending_write = Write} = States,
+set_pending_cipher_state(#{pending_read := Read,
+ pending_write := Write} = States,
ClientState, ServerState, server) ->
- States#connection_states{
- pending_read = Read#connection_state{cipher_state = ClientState},
- pending_write = Write#connection_state{cipher_state = ServerState}};
+ States#{
+ pending_read => Read#{cipher_state => ClientState},
+ pending_write => Write#{cipher_state => ServerState}};
-set_pending_cipher_state(#connection_states{pending_read = Read,
- pending_write = Write} = States,
+set_pending_cipher_state(#{pending_read := Read,
+ pending_write := Write} = States,
ClientState, ServerState, client) ->
- States#connection_states{
- pending_read = Read#connection_state{cipher_state = ServerState},
- pending_write = Write#connection_state{cipher_state = ClientState}}.
+ States#{
+ pending_read => Read#{cipher_state => ServerState},
+ pending_write => Write#{cipher_state => ClientState}}.
-%%--------------------------------------------------------------------
--spec encode_handshake(iolist(), ssl_version(), #connection_states{}) ->
- {iolist(), #connection_states{}}.
-%%
-%% Description: Encodes a handshake message to send on the ssl-socket.
-%%--------------------------------------------------------------------
-encode_handshake(Frag, Version,
- #connection_states{current_write =
- #connection_state{
- beast_mitigation = BeastMitigation,
- security_parameters =
- #security_parameters{bulk_cipher_algorithm = BCA}}} =
- ConnectionStates)
-when is_list(Frag) ->
- case iolist_size(Frag) of
- N when N > ?MAX_PLAIN_TEXT_LENGTH ->
- Data = split_bin(iolist_to_binary(Frag), ?MAX_PLAIN_TEXT_LENGTH, Version, BCA, BeastMitigation),
- encode_iolist(?HANDSHAKE, Data, Version, ConnectionStates);
- _ ->
- encode_plain_text(?HANDSHAKE, Version, Frag, ConnectionStates)
- end;
-%% TODO: this is a workarround for DTLS
-%%
-%% DTLS need to select the connection write state based on Epoch it wants to
-%% send this fragment in. That Epoch does not nessarily has to be the same
-%% as the current_write epoch.
-%% The right solution might be to pass the WriteState instead of the ConnectionStates,
-%% however, this will require substantion API changes.
-encode_handshake(Frag, Version, ConnectionStates) ->
- encode_plain_text(?HANDSHAKE, Version, Frag, ConnectionStates).
-
-%%--------------------------------------------------------------------
--spec encode_alert_record(#alert{}, ssl_version(), #connection_states{}) ->
- {iolist(), #connection_states{}}.
-%%
-%% Description: Encodes an alert message to send on the ssl-socket.
-%%--------------------------------------------------------------------
-encode_alert_record(#alert{level = Level, description = Description},
- Version, ConnectionStates) ->
- encode_plain_text(?ALERT, Version, <<?BYTE(Level), ?BYTE(Description)>>,
- ConnectionStates).
-
-%%--------------------------------------------------------------------
--spec encode_change_cipher_spec(ssl_version(), #connection_states{}) ->
- {iolist(), #connection_states{}}.
-%%
-%% Description: Encodes a change_cipher_spec-message to send on the ssl socket.
-%%--------------------------------------------------------------------
-encode_change_cipher_spec(Version, ConnectionStates) ->
- encode_plain_text(?CHANGE_CIPHER_SPEC, Version, <<1:8>>, ConnectionStates).
-
-%%--------------------------------------------------------------------
--spec encode_data(binary(), ssl_version(), #connection_states{}) ->
- {iolist(), #connection_states{}}.
-%%
-%% Description: Encodes data to send on the ssl-socket.
-%%--------------------------------------------------------------------
-encode_data(Frag, Version,
- #connection_states{current_write = #connection_state{
- beast_mitigation = BeastMitigation,
- security_parameters =
- #security_parameters{bulk_cipher_algorithm = BCA}}} =
- ConnectionStates) ->
- Data = split_bin(Frag, ?MAX_PLAIN_TEXT_LENGTH, Version, BCA, BeastMitigation),
- encode_iolist(?APPLICATION_DATA, Data, Version, ConnectionStates).
-
uncompress(?NULL, Data, CS) ->
{Data, CS}.
@@ -390,84 +283,74 @@ compressions() ->
[?byte(?NULL)].
%%--------------------------------------------------------------------
--spec cipher(ssl_version(), iodata(), #connection_state{}, MacHash::binary()) ->
- {CipherFragment::binary(), #connection_state{}}.
+-spec cipher(ssl_version(), iodata(), connection_state(), MacHash::binary()) ->
+ {CipherFragment::binary(), connection_state()}.
%%
%% Description: Payload encryption
%%--------------------------------------------------------------------
cipher(Version, Fragment,
- #connection_state{cipher_state = CipherS0,
- security_parameters=
- #security_parameters{bulk_cipher_algorithm =
- BulkCipherAlgo}
- } = WriteState0, MacHash) ->
-
+ #{cipher_state := CipherS0,
+ security_parameters :=
+ #security_parameters{bulk_cipher_algorithm =
+ BulkCipherAlgo}
+ } = WriteState0, MacHash) ->
+
{CipherFragment, CipherS1} =
ssl_cipher:cipher(BulkCipherAlgo, CipherS0, MacHash, Fragment, Version),
- {CipherFragment, WriteState0#connection_state{cipher_state = CipherS1}}.
-%%--------------------------------------------------------------------
--spec cipher_aead(ssl_version(), iodata(), #connection_state{}, MacHash::binary()) ->
- {CipherFragment::binary(), #connection_state{}}.
-%%
-%% Description: Payload encryption
-%%--------------------------------------------------------------------
+ {CipherFragment, WriteState0#{cipher_state => CipherS1}}.
+%% %%--------------------------------------------------------------------
+%% -spec cipher_aead(ssl_version(), iodata(), connection_state(), MacHash::binary()) ->
+%% {CipherFragment::binary(), connection_state()}.
+%% %%
+%% %% Description: Payload encryption
+%% %%--------------------------------------------------------------------
cipher_aead(Version, Fragment,
- #connection_state{cipher_state = CipherS0,
- sequence_number = SeqNo,
- security_parameters=
- #security_parameters{bulk_cipher_algorithm =
- BulkCipherAlgo}
- } = WriteState0, AAD) ->
-
+ #{cipher_state := CipherS0,
+ sequence_number := SeqNo,
+ security_parameters :=
+ #security_parameters{bulk_cipher_algorithm =
+ BulkCipherAlgo}
+ } = WriteState0, AAD) ->
+
{CipherFragment, CipherS1} =
ssl_cipher:cipher_aead(BulkCipherAlgo, CipherS0, SeqNo, AAD, Fragment, Version),
- {CipherFragment, WriteState0#connection_state{cipher_state = CipherS1}}.
+ {CipherFragment, WriteState0#{cipher_state => CipherS1}}.
%%--------------------------------------------------------------------
--spec decipher(ssl_version(), binary(), #connection_state{}, boolean()) -> {binary(), binary(), #connection_state{}} | #alert{}.
+-spec decipher(ssl_version(), binary(), connection_state(), boolean()) ->
+ {binary(), binary(), connection_state} | #alert{}.
%%
%% Description: Payload decryption
%%--------------------------------------------------------------------
decipher(Version, CipherFragment,
- #connection_state{security_parameters =
- #security_parameters{bulk_cipher_algorithm =
- BulkCipherAlgo,
- hash_size = HashSz},
- cipher_state = CipherS0
- } = ReadState, PaddingCheck) ->
+ #{security_parameters :=
+ #security_parameters{bulk_cipher_algorithm =
+ BulkCipherAlgo,
+ hash_size = HashSz},
+ cipher_state := CipherS0
+ } = ReadState, PaddingCheck) ->
case ssl_cipher:decipher(BulkCipherAlgo, HashSz, CipherS0, CipherFragment, Version, PaddingCheck) of
{PlainFragment, Mac, CipherS1} ->
- CS1 = ReadState#connection_state{cipher_state = CipherS1},
+ CS1 = ReadState#{cipher_state => CipherS1},
{PlainFragment, Mac, CS1};
#alert{} = Alert ->
Alert
end.
-%%--------------------------------------------------------------------
--spec decipher_aead(ssl_version(), binary(), #connection_state{}, binary()) -> {binary(), binary(), #connection_state{}} | #alert{}.
-%%
-%% Description: Payload decryption
-%%--------------------------------------------------------------------
-decipher_aead(Version, CipherFragment,
- #connection_state{sequence_number = SeqNo,
- security_parameters =
- #security_parameters{bulk_cipher_algorithm =
- BulkCipherAlgo},
- cipher_state = CipherS0
- } = ReadState, AAD) ->
- case ssl_cipher:decipher_aead(BulkCipherAlgo, CipherS0, SeqNo, AAD, CipherFragment, Version) of
- {PlainFragment, CipherS1} ->
- CS1 = ReadState#connection_state{cipher_state = CipherS1},
- {PlainFragment, CS1};
- #alert{} = Alert ->
- Alert
- end.
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
empty_connection_state(ConnectionEnd, BeastMitigation) ->
SecParams = empty_security_params(ConnectionEnd),
- #connection_state{security_parameters = SecParams,
- beast_mitigation = BeastMitigation}.
+ #{security_parameters => SecParams,
+ beast_mitigation => BeastMitigation,
+ compression_state => undefined,
+ cipher_state => undefined,
+ mac_secret => undefined,
+ secure_renegotiation => undefined,
+ client_verify_data => undefined,
+ server_verify_data => undefined
+ }.
empty_security_params(ConnectionEnd = ?CLIENT) ->
#security_parameters{connection_end = ConnectionEnd,
@@ -481,11 +364,6 @@ random() ->
Random_28_bytes = ssl_cipher:random_bytes(28),
<<?UINT32(Secs_since_1970), Random_28_bytes/binary>>.
-dtls_next_epoch(#connection_state{epoch = undefined}) -> %% SSL/TLS
- undefined;
-dtls_next_epoch(#connection_state{epoch = Epoch}) -> %% DTLS
- Epoch + 1.
-
is_correct_mac(Mac, Mac) ->
true;
is_correct_mac(_M,_H) ->
@@ -497,58 +375,20 @@ record_protocol_role(server) ->
?SERVER.
initial_connection_state(ConnectionEnd, BeastMitigation) ->
- #connection_state{security_parameters =
- initial_security_params(ConnectionEnd),
- sequence_number = 0,
- beast_mitigation = BeastMitigation
- }.
+ #{security_parameters =>
+ initial_security_params(ConnectionEnd),
+ sequence_number => 0,
+ beast_mitigation => BeastMitigation,
+ compression_state => undefined,
+ cipher_state => undefined,
+ mac_secret => undefined,
+ secure_renegotiation => undefined,
+ client_verify_data => undefined,
+ server_verify_data => undefined
+ }.
initial_security_params(ConnectionEnd) ->
SecParams = #security_parameters{connection_end = ConnectionEnd,
compression_algorithm = ?NULL},
ssl_cipher:security_parameters(?TLS_NULL_WITH_NULL_NULL, SecParams).
-
-encode_plain_text(Type, Version, Data, ConnectionStates) ->
- RecordCB = protocol_module(Version),
- RecordCB:encode_plain_text(Type, Version, Data, ConnectionStates).
-
-encode_iolist(Type, Data, Version, ConnectionStates0) ->
- RecordCB = protocol_module(Version),
- {ConnectionStates, EncodedMsg} =
- lists:foldl(fun(Text, {CS0, Encoded}) ->
- {Enc, CS1} =
- RecordCB:encode_plain_text(Type, Version, Text, CS0),
- {CS1, [Enc | Encoded]}
- end, {ConnectionStates0, []}, Data),
- {lists:reverse(EncodedMsg), ConnectionStates}.
-
-%% 1/n-1 splitting countermeasure Rizzo/Duong-Beast, RC4 chiphers are
-%% not vulnerable to this attack.
-split_bin(<<FirstByte:8, Rest/binary>>, ChunkSize, Version, BCA, one_n_minus_one) when
- BCA =/= ?RC4 andalso ({3, 1} == Version orelse
- {3, 0} == Version) ->
- do_split_bin(Rest, ChunkSize, [[FirstByte]]);
-%% 0/n splitting countermeasure for clients that are incompatible with 1/n-1
-%% splitting.
-split_bin(Bin, ChunkSize, Version, BCA, zero_n) when
- BCA =/= ?RC4 andalso ({3, 1} == Version orelse
- {3, 0} == Version) ->
- do_split_bin(Bin, ChunkSize, [[<<>>]]);
-split_bin(Bin, ChunkSize, _, _, _) ->
- do_split_bin(Bin, ChunkSize, []).
-
-do_split_bin(<<>>, _, Acc) ->
- lists:reverse(Acc);
-do_split_bin(Bin, ChunkSize, Acc) ->
- case Bin of
- <<Chunk:ChunkSize/binary, Rest/binary>> ->
- do_split_bin(Rest, ChunkSize, [Chunk | Acc]);
- _ ->
- lists:reverse(Acc, [Bin])
- end.
-
-protocol_module({3, _}) ->
- tls_record;
-protocol_module({254, _}) ->
- dtls_record.
diff --git a/lib/ssl/src/ssl_record.hrl b/lib/ssl/src/ssl_record.hrl
index a41264ff9b..ed007f58d7 100644
--- a/lib/ssl/src/ssl_record.hrl
+++ b/lib/ssl/src/ssl_record.hrl
@@ -30,29 +30,27 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Connection states - RFC 4346 section 6.1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--record(connection_state, {
- security_parameters,
- compression_state,
- cipher_state,
- mac_secret,
- epoch, %% Only used by DTLS
- sequence_number,
- %% RFC 5746
- secure_renegotiation,
- client_verify_data,
- server_verify_data,
- %% How to do BEAST mitigation?
- beast_mitigation
- }).
-
--record(connection_states, {
- dtls_write_msg_seq, %% Only used by DTLS
+%% For documentation purposes are now maps in implementation
+%% -record(connection_state, {
+%% security_parameters,
+%% compression_state,
+%% cipher_state,
+%% mac_secret,
+%% sequence_number,
+%% %% RFC 5746
+%% secure_renegotiation,
+%% client_verify_data,
+%% server_verify_data,
+%% %% How to do BEAST mitigation?
+%% beast_mitigation
+%% }).
- current_read,
- pending_read,
- current_write,
- pending_write
- }).
+%% -record(connection_states, {
+%% current_read,
+%% pending_read,
+%% current_write,
+%% pending_write,
+%% }).
-record(security_parameters, {
cipher_suite,
diff --git a/lib/ssl/src/ssl_sup.erl b/lib/ssl/src/ssl_sup.erl
index 7fa1f7dc9e..05a7aaaa82 100644
--- a/lib/ssl/src/ssl_sup.erl
+++ b/lib/ssl/src/ssl_sup.erl
@@ -25,7 +25,7 @@
-behaviour(supervisor).
%% API
--export([start_link/0, manager_opts/0]).
+-export([start_link/0]).
%% Supervisor callback
-export([init/1]).
@@ -44,78 +44,28 @@ start_link() ->
%%%=========================================================================
init([]) ->
- SessionCertManager = session_and_cert_manager_child_spec(),
- TLSConnetionManager = tls_connection_manager_child_spec(),
- %% Not supported yet
- %%DTLSConnetionManager = tls_connection_manager_child_spec(),
- %% Handles emulated options so that they inherited by the accept socket, even when setopts is performed on
- %% the listen socket
- ListenOptionsTracker = listen_options_tracker_child_spec(),
- {ok, {{one_for_all, 10, 3600}, [SessionCertManager, TLSConnetionManager, ListenOptionsTracker]}}.
+ {ok, {{rest_for_one, 10, 3600}, [ssl_admin_child_spec(),
+ ssl_connection_sup()
+ ]}}.
-
-manager_opts() ->
- CbOpts = case application:get_env(ssl, session_cb) of
- {ok, Cb} when is_atom(Cb) ->
- InitArgs = session_cb_init_args(),
- [{session_cb, Cb}, {session_cb_init_args, InitArgs}];
- _ ->
- []
- end,
- case application:get_env(ssl, session_lifetime) of
- {ok, Time} when is_integer(Time) ->
- [{session_lifetime, Time}| CbOpts];
- _ ->
- CbOpts
- end.
-
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-
-session_and_cert_manager_child_spec() ->
- Opts = manager_opts(),
- Name = ssl_manager,
- StartFunc = {ssl_manager, start_link, [Opts]},
- Restart = permanent,
- Shutdown = 4000,
- Modules = [ssl_manager],
- Type = worker,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
-tls_connection_manager_child_spec() ->
- Name = tls_connection,
- StartFunc = {tls_connection_sup, start_link, []},
+ssl_admin_child_spec() ->
+ Name = ssl_admin_sup,
+ StartFunc = {ssl_admin_sup, start_link, []},
Restart = permanent,
Shutdown = 4000,
- Modules = [tls_connection_sup],
+ Modules = [ssl_admin_sup],
Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-%% dtls_connection_manager_child_spec() ->
-%% Name = dtls_connection,
-%% StartFunc = {dtls_connection_sup, start_link, []},
-%% Restart = permanent,
-%% Shutdown = 4000,
-%% Modules = [dtls_connection, ssl_connection],
-%% Type = supervisor,
-%% {Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
-
-listen_options_tracker_child_spec() ->
- Name = ssl_socket,
- StartFunc = {ssl_listen_tracker_sup, start_link, []},
- Restart = permanent,
+ssl_connection_sup() ->
+ Name = ssl_connection_sup,
+ StartFunc = {ssl_connection_sup, start_link, []},
+ Restart = permanent,
Shutdown = 4000,
- Modules = [ssl_socket],
+ Modules = [ssl_connection_sup],
Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
-session_cb_init_args() ->
- case application:get_env(ssl, session_cb_init_args) of
- {ok, Args} when is_list(Args) ->
- Args;
- _ ->
- []
- end.
diff --git a/lib/ssl/src/ssl_tls_dist_proxy.erl b/lib/ssl/src/ssl_tls_dist_proxy.erl
index a920f54ed2..08947f24dd 100644
--- a/lib/ssl/src/ssl_tls_dist_proxy.erl
+++ b/lib/ssl/src/ssl_tls_dist_proxy.erl
@@ -117,7 +117,7 @@ handle_call({listen, Driver, Name}, _From, State) ->
{ok, WorldTcpAddress} = get_tcp_address(World),
{_,Port} = WorldTcpAddress#net_address.address,
ErlEpmd = net_kernel:epmd_module(),
- case ErlEpmd:register_node(Name, Port) of
+ case ErlEpmd:register_node(Name, Port, Driver) of
{ok, Creation} ->
{reply, {ok, {Socket, TcpAddress, Creation}},
State#state{listen={Socket, World}}};
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 9880befa94..352874c77d 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -45,33 +45,30 @@
%% Setup
-export([start_fsm/8, start_link/7, init/1]).
+-export([encode_data/3, encode_alert/3]).
+
%% State transition handling
--export([next_record/1, next_event/3]).
+-export([next_record/1, next_event/3, next_event/4]).
%% Handshake handling
-export([renegotiate/2, send_handshake/2,
queue_handshake/2, queue_change_cipher/2,
- reinit_handshake_data/1, handle_sni_extension/2]).
+ reinit_handshake_data/1, select_sni_extension/1]).
%% Alert and close handling
--export([send_alert/2, handle_own_alert/4, handle_close_alert/3,
- handle_normal_shutdown/3,
- close/5, alert_user/6, alert_user/9
- ]).
+-export([send_alert/2, close/5]).
%% Data handling
--export([write_application_data/3, read_application_data/2,
- passive_receive/2, next_record_if_active/1, handle_common_event/4]).
+-export([passive_receive/2, next_record_if_active/1, handle_common_event/4, send/3,
+ socket/5, setopts/3, getopts/3]).
%% gen_statem state functions
-export([init/3, error/3, downgrade/3, %% Initiation and take down states
hello/3, certify/3, cipher/3, abbreviated/3, %% Handshake states
connection/3]).
%% gen_statem callbacks
--export([terminate/3, code_change/4, format_status/2]).
+-export([callback_mode/0, terminate/3, code_change/4, format_status/2]).
--define(GEN_STATEM_CB_MODE, state_functions).
-
%%====================================================================
%% Internal application API
%%====================================================================
@@ -109,9 +106,10 @@ send_handshake(Handshake, State) ->
queue_handshake(Handshake, #state{negotiated_version = Version,
tls_handshake_history = Hist0,
flight_buffer = Flight0,
+ ssl_options = #ssl_options{v2_hello_compatible = V2HComp},
connection_states = ConnectionStates0} = State0) ->
{BinHandshake, ConnectionStates, Hist} =
- encode_handshake(Handshake, Version, ConnectionStates0, Hist0),
+ encode_handshake(Handshake, Version, ConnectionStates0, Hist0, V2HComp),
State0#state{connection_states = ConnectionStates,
tls_handshake_history = Hist,
flight_buffer = Flight0 ++ [BinHandshake]}.
@@ -119,8 +117,8 @@ queue_handshake(Handshake, #state{negotiated_version = Version,
send_handshake_flight(#state{socket = Socket,
transport_cb = Transport,
flight_buffer = Flight} = State0) ->
- Transport:send(Socket, Flight),
- State0#state{flight_buffer = []}.
+ send(Transport, Socket, Flight),
+ {State0#state{flight_buffer = []}, []}.
queue_change_cipher(Msg, #state{negotiated_version = Version,
flight_buffer = Flight0,
@@ -135,8 +133,8 @@ send_alert(Alert, #state{negotiated_version = Version,
transport_cb = Transport,
connection_states = ConnectionStates0} = State0) ->
{BinMsg, ConnectionStates} =
- ssl_alert:encode(Alert, Version, ConnectionStates0),
- Transport:send(Socket, BinMsg),
+ encode_alert(Alert, Version, ConnectionStates0),
+ send(Transport, Socket, BinMsg),
State0#state{connection_states = ConnectionStates}.
reinit_handshake_data(State) ->
@@ -149,6 +147,23 @@ reinit_handshake_data(State) ->
tls_handshake_history = ssl_handshake:init_handshake_history()
}.
+select_sni_extension(#client_hello{extensions = HelloExtensions}) ->
+ HelloExtensions#hello_extensions.sni;
+select_sni_extension(_) ->
+ undefined.
+
+encode_data(Data, Version, ConnectionStates0)->
+ tls_record:encode_data(Data, Version, ConnectionStates0).
+
+%%--------------------------------------------------------------------
+-spec encode_alert(#alert{}, ssl_record:ssl_version(), ssl_record:connection_states()) ->
+ {iolist(), ssl_record:connection_states()}.
+%%
+%% Description: Encodes an alert
+%%--------------------------------------------------------------------
+encode_alert(#alert{} = Alert, Version, ConnectionStates) ->
+ tls_record:encode_alert_record(Alert, Version, ConnectionStates).
+
%%====================================================================
%% tls_connection_sup API
%%====================================================================
@@ -169,11 +184,22 @@ init([Role, Host, Port, Socket, Options, User, CbInfo]) ->
State0 = initial_state(Role, Host, Port, Socket, Options, User, CbInfo),
try
State = ssl_connection:ssl_config(State0#state.ssl_options, Role, State0),
- gen_statem:enter_loop(?MODULE, [], ?GEN_STATEM_CB_MODE, init, State)
+ gen_statem:enter_loop(?MODULE, [], init, State)
catch throw:Error ->
- gen_statem:enter_loop(?MODULE, [], ?GEN_STATEM_CB_MODE, error, {Error, State0})
+ gen_statem:enter_loop(?MODULE, [], error, {Error, State0})
end.
+callback_mode() ->
+ state_functions.
+
+socket(Pid, Transport, Socket, Connection, Tracker) ->
+ tls_socket:socket(Pid, Transport, Socket, Connection, Tracker).
+
+setopts(Transport, Socket, Other) ->
+ tls_socket:setopts(Transport, Socket, Other).
+getopts(Transport, Socket, Tag) ->
+ tls_socket:getopts(Transport, Socket, Tag).
+
%%--------------------------------------------------------------------
%% State functions
%%--------------------------------------------------------------------
@@ -185,7 +211,7 @@ init([Role, Host, Port, Socket, Options, User, CbInfo]) ->
init({call, From}, {start, Timeout},
#state{host = Host, port = Port, role = client,
- ssl_options = SslOpts,
+ ssl_options = #ssl_options{v2_hello_compatible = V2HComp} = SslOpts,
session = #session{own_certificate = Cert} = Session0,
transport_cb = Transport, socket = Socket,
connection_states = ConnectionStates0,
@@ -198,11 +224,11 @@ init({call, From}, {start, Timeout},
Cache, CacheCb, Renegotiation, Cert),
Version = Hello#client_hello.client_version,
- HelloVersion = tls_record:lowest_protocol_version(SslOpts#ssl_options.versions),
+ HelloVersion = tls_record:hello_version(Version, SslOpts#ssl_options.versions),
Handshake0 = ssl_handshake:init_handshake_history(),
{BinMsg, ConnectionStates, Handshake} =
- encode_handshake(Hello, HelloVersion, ConnectionStates0, Handshake0),
- Transport:send(Socket, BinMsg),
+ encode_handshake(Hello, HelloVersion, ConnectionStates0, Handshake0, V2HComp),
+ send(Transport, Socket, BinMsg),
State1 = State0#state{connection_states = ConnectionStates,
negotiated_version = Version, %% Requested version
session =
@@ -213,7 +239,7 @@ init({call, From}, {start, Timeout},
{Record, State} = next_record(State1),
next_event(hello, Record, State);
init(Type, Event, State) ->
- ssl_connection:init(Type, Event, State, ?MODULE).
+ gen_handshake(ssl_connection, init, Type, Event, State).
%%--------------------------------------------------------------------
-spec error(gen_statem:event_type(),
@@ -234,9 +260,7 @@ error(_, _, _) ->
#state{}) ->
gen_statem:state_function_result().
%%--------------------------------------------------------------------
-hello(internal, #client_hello{client_version = ClientVersion,
- extensions = #hello_extensions{ec_point_formats = EcPointFormats,
- elliptic_curves = EllipticCurves}} = Hello,
+hello(internal, #client_hello{client_version = ClientVersion} = Hello,
#state{connection_states = ConnectionStates0,
port = Port, session = #session{own_certificate = Cert} = Session0,
renegotiation = {Renegotiation, _},
@@ -249,7 +273,7 @@ hello(internal, #client_hello{client_version = ClientVersion,
case tls_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb,
ConnectionStates0, Cert, KeyExAlg}, Renegotiation) of
#alert{} = Alert ->
- handle_own_alert(Alert, ClientVersion, hello, State);
+ ssl_connection:handle_own_alert(Alert, ClientVersion, hello, State);
{Version, {Type, Session},
ConnectionStates, Protocol0, ServerHelloExt, HashSign} ->
Protocol = case Protocol0 of
@@ -257,13 +281,12 @@ hello(internal, #client_hello{client_version = ClientVersion,
_ -> Protocol0
end,
- ssl_connection:hello(internal, {common_client_hello, Type, ServerHelloExt},
+ gen_handshake(ssl_connection, hello, internal, {common_client_hello, Type, ServerHelloExt},
State#state{connection_states = ConnectionStates,
negotiated_version = Version,
hashsign_algorithm = HashSign,
session = Session,
- client_ecc = {EllipticCurves, EcPointFormats},
- negotiated_protocol = Protocol}, ?MODULE)
+ negotiated_protocol = Protocol})
end;
hello(internal, #server_hello{} = Hello,
#state{connection_states = ConnectionStates0,
@@ -273,42 +296,42 @@ hello(internal, #server_hello{} = Hello,
ssl_options = SslOptions} = State) ->
case tls_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of
#alert{} = Alert ->
- handle_own_alert(Alert, ReqVersion, hello, State);
+ ssl_connection:handle_own_alert(Alert, ReqVersion, hello, State);
{Version, NewId, ConnectionStates, ProtoExt, Protocol} ->
ssl_connection:handle_session(Hello,
Version, NewId, ConnectionStates, ProtoExt, Protocol, State)
end;
hello(info, Event, State) ->
- handle_info(Event, hello, State);
+ gen_info(Event, hello, State);
hello(Type, Event, State) ->
- ssl_connection:hello(Type, Event, State, ?MODULE).
+ gen_handshake(ssl_connection, hello, Type, Event, State).
%%--------------------------------------------------------------------
-spec abbreviated(gen_statem:event_type(), term(), #state{}) ->
gen_statem:state_function_result().
%%--------------------------------------------------------------------
abbreviated(info, Event, State) ->
- handle_info(Event, abbreviated, State);
+ gen_info(Event, abbreviated, State);
abbreviated(Type, Event, State) ->
- ssl_connection:abbreviated(Type, Event, State, ?MODULE).
+ gen_handshake(ssl_connection, abbreviated, Type, Event, State).
%%--------------------------------------------------------------------
-spec certify(gen_statem:event_type(), term(), #state{}) ->
gen_statem:state_function_result().
%%--------------------------------------------------------------------
certify(info, Event, State) ->
- handle_info(Event, certify, State);
+ gen_info(Event, certify, State);
certify(Type, Event, State) ->
- ssl_connection:certify(Type, Event, State, ?MODULE).
+ gen_handshake(ssl_connection, certify, Type, Event, State).
%%--------------------------------------------------------------------
-spec cipher(gen_statem:event_type(), term(), #state{}) ->
gen_statem:state_function_result().
%%--------------------------------------------------------------------
cipher(info, Event, State) ->
- handle_info(Event, cipher, State);
+ gen_info(Event, cipher, State);
cipher(Type, Event, State) ->
- ssl_connection:cipher(Type, Event, State, ?MODULE).
+ gen_handshake(ssl_connection, cipher, Type, Event, State).
%%--------------------------------------------------------------------
-spec connection(gen_statem:event_type(),
@@ -316,7 +339,7 @@ cipher(Type, Event, State) ->
gen_statem:state_function_result().
%%--------------------------------------------------------------------
connection(info, Event, State) ->
- handle_info(Event, connection, State);
+ gen_info(Event, connection, State);
connection(internal, #hello_request{},
#state{role = client, host = Host, port = Port,
session = #session{own_certificate = Cert} = Session0,
@@ -326,12 +349,12 @@ connection(internal, #hello_request{},
renegotiation = {Renegotiation, _}} = State0) ->
Hello = tls_handshake:client_hello(Host, Port, ConnectionStates0, SslOpts,
Cache, CacheCb, Renegotiation, Cert),
- State1 = send_handshake(Hello, State0),
+ {State1, Actions} = send_handshake(Hello, State0),
{Record, State} =
next_record(
State1#state{session = Session0#session{session_id
= Hello#client_hello.session_id}}),
- next_event(hello, Record, State);
+ next_event(hello, Record, State, Actions);
connection(internal, #client_hello{} = Hello,
#state{role = server, allow_renegotiate = true} = State0) ->
%% Mitigate Computational DoS attack
@@ -373,34 +396,47 @@ handle_info({Protocol, _, Data}, StateName,
{Record, State} ->
next_event(StateName, Record, State);
#alert{} = Alert ->
- handle_normal_shutdown(Alert, StateName, State0),
+ ssl_connection:handle_normal_shutdown(Alert, StateName, State0),
{stop, {shutdown, own_alert}}
end;
handle_info({CloseTag, Socket}, StateName,
#state{socket = Socket, close_tag = CloseTag,
+ socket_options = #socket_options{active = Active},
+ protocol_buffers = #protocol_buffers{tls_cipher_texts = CTs},
negotiated_version = Version} = State) ->
+
%% Note that as of TLS 1.1,
%% failure to properly close a connection no longer requires that a
%% session not be resumed. This is a change from TLS 1.0 to conform
%% with widespread implementation practice.
- case Version of
- {1, N} when N >= 1 ->
- ok;
- _ ->
- %% As invalidate_sessions here causes performance issues,
- %% we will conform to the widespread implementation
- %% practice and go aginst the spec
- %%invalidate_session(Role, Host, Port, Session)
- ok
- end,
- handle_normal_shutdown(?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), StateName, State),
- {stop, {shutdown, transport_closed}};
+
+ case (Active == false) andalso (CTs =/= []) of
+ false ->
+ case Version of
+ {1, N} when N >= 1 ->
+ ok;
+ _ ->
+ %% As invalidate_sessions here causes performance issues,
+ %% we will conform to the widespread implementation
+ %% practice and go aginst the spec
+ %%invalidate_session(Role, Host, Port, Session)
+ ok
+ end,
+
+ ssl_connection:handle_normal_shutdown(?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), StateName, State),
+ {stop, {shutdown, transport_closed}};
+ true ->
+ %% Fixes non-delivery of final TLS record in {active, once}.
+ %% Basically allows the application the opportunity to set {active, once} again
+ %% and then receive the final message.
+ next_event(StateName, no_record, State)
+ end;
handle_info(Msg, StateName, State) ->
ssl_connection:handle_info(Msg, StateName, State).
handle_common_event(internal, #alert{} = Alert, StateName,
#state{negotiated_version = Version} = State) ->
- handle_own_alert(Alert, Version, StateName, State);
+ ssl_connection:handle_own_alert(Alert, Version, StateName, State);
%%% TLS record protocol level handshake messages
handle_common_event(internal, #ssl_tls{type = ?HANDSHAKE, fragment = Data},
@@ -410,18 +446,26 @@ handle_common_event(internal, #ssl_tls{type = ?HANDSHAKE, fragment = Data},
ssl_options = Options} = State0) ->
try
{Packets, Buf} = tls_handshake:get_tls_handshake(Version,Data,Buf0, Options),
- State =
+ State1 =
State0#state{protocol_buffers =
Buffers#protocol_buffers{tls_handshake_buffer = Buf}},
- Events = tls_handshake_events(Packets),
- case StateName of
- connection ->
- ssl_connection:hibernate_after(StateName, State, Events);
- _ ->
- {next_state, StateName, State, Events}
- end
+ case Packets of
+ [] ->
+ assert_buffer_sanity(Buf, Options),
+ {Record, State} = next_record(State1),
+ next_event(StateName, Record, State);
+ _ ->
+ Events = tls_handshake_events(Packets),
+ case StateName of
+ connection ->
+ ssl_connection:hibernate_after(StateName, State1, Events);
+ _ ->
+ {next_state, StateName,
+ State1#state{unprocessed_handshake_events = unprocessed_events(Events)}, Events}
+ end
+ end
catch throw:#alert{} = Alert ->
- handle_own_alert(Alert, Version, StateName, State0)
+ ssl_connection:handle_own_alert(Alert, Version, StateName, State0)
end;
%%% TLS record protocol level application data messages
handle_common_event(internal, #ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, StateName, State) ->
@@ -432,16 +476,27 @@ handle_common_event(internal, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = Da
%%% TLS record protocol level Alert messages
handle_common_event(internal, #ssl_tls{type = ?ALERT, fragment = EncAlerts}, StateName,
#state{negotiated_version = Version} = State) ->
- case decode_alerts(EncAlerts) of
+ try decode_alerts(EncAlerts) of
Alerts = [_|_] ->
handle_alerts(Alerts, {next_state, StateName, State});
+ [] ->
+ ssl_connection:handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, empty_alert),
+ Version, StateName, State);
#alert{} = Alert ->
- handle_own_alert(Alert, Version, StateName, State)
+ ssl_connection:handle_own_alert(Alert, Version, StateName, State)
+ catch
+ _:_ ->
+ ssl_connection:handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, alert_decode_error),
+ Version, StateName, State)
+
end;
%% Ignore unknown TLS record level protocol messages
handle_common_event(internal, #ssl_tls{type = _Unknown}, StateName, State) ->
{next_state, StateName, State}.
+send(Transport, Socket, Data) ->
+ tls_socket:send(Transport, Socket, Data).
+
%%--------------------------------------------------------------------
%% gen_statem callbacks
%%--------------------------------------------------------------------
@@ -457,22 +512,22 @@ format_status(Type, Data) ->
%%--------------------------------------------------------------------
code_change(_OldVsn, StateName, State0, {Direction, From, To}) ->
State = convert_state(State0, Direction, From, To),
- {?GEN_STATEM_CB_MODE, StateName, State};
+ {ok, StateName, State};
code_change(_OldVsn, StateName, State, _) ->
- {?GEN_STATEM_CB_MODE, StateName, State}.
+ {ok, StateName, State}.
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-encode_handshake(Handshake, Version, ConnectionStates0, Hist0) ->
+encode_handshake(Handshake, Version, ConnectionStates0, Hist0, V2HComp) ->
Frag = tls_handshake:encode_handshake(Handshake, Version),
- Hist = ssl_handshake:update_handshake_history(Hist0, Frag),
+ Hist = ssl_handshake:update_handshake_history(Hist0, Frag, V2HComp),
{Encoded, ConnectionStates} =
- ssl_record:encode_handshake(Frag, Version, ConnectionStates0),
+ tls_record:encode_handshake(Frag, Version, ConnectionStates0),
{Encoded, ConnectionStates, Hist}.
encode_change_cipher(#change_cipher_spec{}, Version, ConnectionStates) ->
- ssl_record:encode_change_cipher_spec(Version, ConnectionStates).
+ tls_record:encode_change_cipher_spec(Version, ConnectionStates).
decode_alerts(Bin) ->
ssl_alert:decode(Bin).
@@ -480,7 +535,7 @@ decode_alerts(Bin) ->
initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions, Tracker}, User,
{CbModule, DataTag, CloseTag, ErrorTag}) ->
#ssl_options{beast_mitigation = BeastMitigation} = SSLOptions,
- ConnectionStates = ssl_record:init_connection_states(Role, BeastMitigation),
+ ConnectionStates = tls_record:init_connection_states(Role, BeastMitigation),
SessionCacheCb = case application:get_env(ssl, session_cb) of
{ok, Cb} when is_atom(Cb) ->
@@ -515,23 +570,6 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions, Tracker}, Us
flight_buffer = []
}.
-
-update_ssl_options_from_sni(OrigSSLOptions, SNIHostname) ->
- SSLOption =
- case OrigSSLOptions#ssl_options.sni_fun of
- undefined ->
- proplists:get_value(SNIHostname,
- OrigSSLOptions#ssl_options.sni_hosts);
- SNIFun ->
- SNIFun(SNIHostname)
- end,
- case SSLOption of
- undefined ->
- undefined;
- _ ->
- ssl:handle_options(SSLOption, OrigSSLOptions)
- end.
-
next_tls_record(Data, #state{protocol_buffers = #protocol_buffers{tls_record_buffer = Buf0,
tls_cipher_texts = CT0} = Buffers} = State0) ->
case tls_record:get_tls_records(Data, Buf0) of
@@ -543,7 +581,9 @@ next_tls_record(Data, #state{protocol_buffers = #protocol_buffers{tls_record_buf
#alert{} = Alert ->
Alert
end.
-
+next_record(#state{unprocessed_handshake_events = N} = State) when N > 0 ->
+ {no_record, State#state{unprocessed_handshake_events = N-1}};
+
next_record(#state{protocol_buffers =
#protocol_buffers{tls_packets = [], tls_cipher_texts = [CT | Rest]}
= Buffers,
@@ -560,8 +600,12 @@ next_record(#state{protocol_buffers =
next_record(#state{protocol_buffers = #protocol_buffers{tls_packets = [], tls_cipher_texts = []},
socket = Socket,
transport_cb = Transport} = State) ->
- ssl_socket:setopts(Transport, Socket, [{active,once}]),
- {no_record, State};
+ case tls_socket:setopts(Transport, Socket, [{active,once}]) of
+ ok ->
+ {no_record, State};
+ _ ->
+ {socket_closed, State}
+ end;
next_record(State) ->
{no_record, State}.
@@ -579,19 +623,24 @@ passive_receive(State0 = #state{user_data_buffer = Buffer}, StateName) ->
{Record, State} = next_record(State0),
next_event(StateName, Record, State);
_ ->
- {Record, State} = read_application_data(<<>>, State0),
+ {Record, State} = ssl_connection:read_application_data(<<>>, State0),
next_event(StateName, Record, State)
end.
next_event(StateName, Record, State) ->
next_event(StateName, Record, State, []).
+next_event(StateName, socket_closed, State, _) ->
+ ssl_connection:handle_normal_shutdown(?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), StateName, State),
+ {stop, {shutdown, transport_closed}, State};
next_event(connection = StateName, no_record, State0, Actions) ->
case next_record_if_active(State0) of
{no_record, State} ->
ssl_connection:hibernate_after(StateName, State, Actions);
+ {socket_closed, State} ->
+ next_event(StateName, socket_closed, State, Actions);
{#ssl_tls{} = Record, State} ->
- {next_state, StateName, State, [{next_event, internal, {tls_record, Record}} | Actions]};
+ {next_state, StateName, State, [{next_event, internal, {protocol_record, Record}} | Actions]};
{#alert{} = Alert, State} ->
{next_state, StateName, State, [{next_event, internal, Alert} | Actions]}
end;
@@ -600,225 +649,17 @@ next_event(StateName, Record, State, Actions) ->
no_record ->
{next_state, StateName, State, Actions};
#ssl_tls{} = Record ->
- {next_state, StateName, State, [{next_event, internal, {tls_record, Record}} | Actions]};
+ {next_state, StateName, State, [{next_event, internal, {protocol_record, Record}} | Actions]};
#alert{} = Alert ->
{next_state, StateName, State, [{next_event, internal, Alert} | Actions]}
end.
-read_application_data(Data, #state{user_application = {_Mon, Pid},
- socket = Socket,
- transport_cb = Transport,
- socket_options = SOpts,
- bytes_to_read = BytesToRead,
- start_or_recv_from = RecvFrom,
- timer = Timer,
- user_data_buffer = Buffer0,
- tracker = Tracker} = State0) ->
- Buffer1 = if
- Buffer0 =:= <<>> -> Data;
- Data =:= <<>> -> Buffer0;
- true -> <<Buffer0/binary, Data/binary>>
- end,
- case get_data(SOpts, BytesToRead, Buffer1) of
- {ok, ClientData, Buffer} -> % Send data
- SocketOpt = deliver_app_data(Transport, Socket, SOpts, ClientData, Pid, RecvFrom, Tracker),
- cancel_timer(Timer),
- State = State0#state{user_data_buffer = Buffer,
- start_or_recv_from = undefined,
- timer = undefined,
- bytes_to_read = undefined,
- socket_options = SocketOpt
- },
- if
- SocketOpt#socket_options.active =:= false; Buffer =:= <<>> ->
- %% Passive mode, wait for active once or recv
- %% Active and empty, get more data
- next_record_if_active(State);
- true -> %% We have more data
- read_application_data(<<>>, State)
- end;
- {more, Buffer} -> % no reply, we need more data
- next_record(State0#state{user_data_buffer = Buffer});
- {passive, Buffer} ->
- next_record_if_active(State0#state{user_data_buffer = Buffer});
- {error,_Reason} -> %% Invalid packet in packet mode
- deliver_packet_error(Transport, Socket, SOpts, Buffer1, Pid, RecvFrom, Tracker),
- {stop, normal, State0}
- end.
-
-%% Picks ClientData
-get_data(_, _, <<>>) ->
- {more, <<>>};
-%% Recv timed out save buffer data until next recv
-get_data(#socket_options{active=false}, undefined, Buffer) ->
- {passive, Buffer};
-get_data(#socket_options{active=Active, packet=Raw}, BytesToRead, Buffer)
- when Raw =:= raw; Raw =:= 0 -> %% Raw Mode
- if
- Active =/= false orelse BytesToRead =:= 0 ->
- %% Active true or once, or passive mode recv(0)
- {ok, Buffer, <<>>};
- byte_size(Buffer) >= BytesToRead ->
- %% Passive Mode, recv(Bytes)
- <<Data:BytesToRead/binary, Rest/binary>> = Buffer,
- {ok, Data, Rest};
- true ->
- %% Passive Mode not enough data
- {more, Buffer}
- end;
-get_data(#socket_options{packet=Type, packet_size=Size}, _, Buffer) ->
- PacketOpts = [{packet_size, Size}],
- case decode_packet(Type, Buffer, PacketOpts) of
- {more, _} ->
- {more, Buffer};
- Decoded ->
- Decoded
- end.
-
-decode_packet({http, headers}, Buffer, PacketOpts) ->
- decode_packet(httph, Buffer, PacketOpts);
-decode_packet({http_bin, headers}, Buffer, PacketOpts) ->
- decode_packet(httph_bin, Buffer, PacketOpts);
-decode_packet(Type, Buffer, PacketOpts) ->
- erlang:decode_packet(Type, Buffer, PacketOpts).
-
-%% Just like with gen_tcp sockets, an ssl socket that has been configured with
-%% {packet, http} (or {packet, http_bin}) will automatically switch to expect
-%% HTTP headers after it sees a HTTP Request or HTTP Response line. We
-%% represent the current state as follows:
-%% #socket_options.packet =:= http: Expect a HTTP Request/Response line
-%% #socket_options.packet =:= {http, headers}: Expect HTTP Headers
-%% Note that if the user has explicitly configured the socket to expect
-%% HTTP headers using the {packet, httph} option, we don't do any automatic
-%% switching of states.
-deliver_app_data(Transport, Socket, SOpts = #socket_options{active=Active, packet=Type},
- Data, Pid, From, Tracker) ->
- send_or_reply(Active, Pid, From, format_reply(Transport, Socket, SOpts, Data, Tracker)),
- SO = case Data of
- {P, _, _, _} when ((P =:= http_request) or (P =:= http_response)),
- ((Type =:= http) or (Type =:= http_bin)) ->
- SOpts#socket_options{packet={Type, headers}};
- http_eoh when tuple_size(Type) =:= 2 ->
- % End of headers - expect another Request/Response line
- {Type1, headers} = Type,
- SOpts#socket_options{packet=Type1};
- _ ->
- SOpts
- end,
- case Active of
- once ->
- SO#socket_options{active=false};
- _ ->
- SO
- end.
-
-format_reply(_, _,#socket_options{active = false, mode = Mode, packet = Packet,
- header = Header}, Data, _) ->
- {ok, do_format_reply(Mode, Packet, Header, Data)};
-format_reply(Transport, Socket, #socket_options{active = _, mode = Mode, packet = Packet,
- header = Header}, Data, Tracker) ->
- {ssl, ssl_socket:socket(self(), Transport, Socket, ?MODULE, Tracker),
- do_format_reply(Mode, Packet, Header, Data)}.
-
-deliver_packet_error(Transport, Socket, SO= #socket_options{active = Active}, Data, Pid, From, Tracker) ->
- send_or_reply(Active, Pid, From, format_packet_error(Transport, Socket, SO, Data, Tracker)).
-
-format_packet_error(_, _,#socket_options{active = false, mode = Mode}, Data, _) ->
- {error, {invalid_packet, do_format_reply(Mode, raw, 0, Data)}};
-format_packet_error(Transport, Socket, #socket_options{active = _, mode = Mode}, Data, Tracker) ->
- {ssl_error, ssl_socket:socket(self(), Transport, Socket, ?MODULE, Tracker),
- {invalid_packet, do_format_reply(Mode, raw, 0, Data)}}.
-
-do_format_reply(binary, _, N, Data) when N > 0 -> % Header mode
- header(N, Data);
-do_format_reply(binary, _, _, Data) ->
- Data;
-do_format_reply(list, Packet, _, Data)
- when Packet == http; Packet == {http, headers};
- Packet == http_bin; Packet == {http_bin, headers};
- Packet == httph; Packet == httph_bin ->
- Data;
-do_format_reply(list, _,_, Data) ->
- binary_to_list(Data).
-
-header(0, <<>>) ->
- <<>>;
-header(_, <<>>) ->
- [];
-header(0, Binary) ->
- Binary;
-header(N, Binary) ->
- <<?BYTE(ByteN), NewBinary/binary>> = Binary,
- [ByteN | header(N-1, NewBinary)].
-
-send_or_reply(false, _Pid, From, Data) when From =/= undefined ->
- gen_statem:reply(From, Data);
-%% Can happen when handling own alert or tcp error/close and there is
-%% no outstanding gen_fsm sync events
-send_or_reply(false, no_pid, _, _) ->
- ok;
-send_or_reply(_, Pid, _From, Data) ->
- send_user(Pid, Data).
-
-send_user(Pid, Msg) ->
- Pid ! Msg.
-
-tls_handshake_events([]) ->
- throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, malformed_handshake));
tls_handshake_events(Packets) ->
lists:map(fun(Packet) ->
{next_event, internal, {handshake, Packet}}
end, Packets).
-write_application_data(Data0, From,
- #state{socket = Socket,
- negotiated_version = Version,
- transport_cb = Transport,
- connection_states = ConnectionStates0,
- socket_options = SockOpts,
- ssl_options = #ssl_options{renegotiate_at = RenegotiateAt}} = State) ->
- Data = encode_packet(Data0, SockOpts),
-
- case time_to_renegotiate(Data, ConnectionStates0, RenegotiateAt) of
- true ->
- renegotiate(State#state{renegotiation = {true, internal}},
- [{next_event, {call, From}, {application_data, Data0}}]);
- false ->
- {Msgs, ConnectionStates} = ssl_record:encode_data(Data, Version, ConnectionStates0),
- Result = Transport:send(Socket, Msgs),
- ssl_connection:hibernate_after(connection, State#state{connection_states = ConnectionStates},
- [{reply, From, Result}])
- end.
-
-encode_packet(Data, #socket_options{packet=Packet}) ->
- case Packet of
- 1 -> encode_size_packet(Data, 8, (1 bsl 8) - 1);
- 2 -> encode_size_packet(Data, 16, (1 bsl 16) - 1);
- 4 -> encode_size_packet(Data, 32, (1 bsl 32) - 1);
- _ -> Data
- end.
-encode_size_packet(Bin, Size, Max) ->
- Len = erlang:byte_size(Bin),
- case Len > Max of
- true -> throw({error, {badarg, {packet_to_large, Len, Max}}});
- false -> <<Len:Size, Bin/binary>>
- end.
-
-time_to_renegotiate(_Data,
- #connection_states{current_write =
- #connection_state{sequence_number = Num}},
- RenegotiateAt) ->
-
- %% We could do test:
- %% is_time_to_renegotiate((erlang:byte_size(_Data) div ?MAX_PLAIN_TEXT_LENGTH) + 1, RenegotiateAt),
- %% but we chose to have a some what lower renegotiateAt and a much cheaper test
- is_time_to_renegotiate(Num, RenegotiateAt).
-
-is_time_to_renegotiate(N, M) when N < M->
- false;
-is_time_to_renegotiate(_,_) ->
- true.
renegotiate(#state{role = client} = State, Actions) ->
%% Handle same way as if server requested
%% the renegotiation
@@ -835,8 +676,8 @@ renegotiate(#state{role = server,
Frag = tls_handshake:encode_handshake(HelloRequest, Version),
Hs0 = ssl_handshake:init_handshake_history(),
{BinMsg, ConnectionStates} =
- ssl_record:encode_handshake(Frag, Version, ConnectionStates0),
- Transport:send(Socket, BinMsg),
+ tls_record:encode_handshake(Frag, Version, ConnectionStates0),
+ send(Transport, Socket, BinMsg),
State1 = State0#state{connection_states =
ConnectionStates,
tls_handshake_history = Hs0},
@@ -848,135 +689,14 @@ handle_alerts([], Result) ->
handle_alerts(_, {stop,_} = Stop) ->
Stop;
handle_alerts([Alert | Alerts], {next_state, StateName, State}) ->
- handle_alerts(Alerts, handle_alert(Alert, StateName, State));
+ handle_alerts(Alerts, ssl_connection:handle_alert(Alert, StateName, State));
handle_alerts([Alert | Alerts], {next_state, StateName, State, _Actions}) ->
- handle_alerts(Alerts, handle_alert(Alert, StateName, State)).
-handle_alert(#alert{level = ?FATAL} = Alert, StateName,
- #state{socket = Socket, transport_cb = Transport,
- ssl_options = SslOpts, start_or_recv_from = From, host = Host,
- port = Port, session = Session, user_application = {_Mon, Pid},
- role = Role, socket_options = Opts, tracker = Tracker}) ->
- invalidate_session(Role, Host, Port, Session),
- log_alert(SslOpts#ssl_options.log_alert, StateName, Alert),
- alert_user(Transport, Tracker, Socket, StateName, Opts, Pid, From, Alert, Role),
- {stop, normal};
-
-handle_alert(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert,
- StateName, State) ->
- handle_normal_shutdown(Alert, StateName, State),
- {stop, {shutdown, peer_close}};
-
-handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName,
- #state{ssl_options = SslOpts, renegotiation = {true, internal}} = State) ->
- log_alert(SslOpts#ssl_options.log_alert, StateName, Alert),
- handle_normal_shutdown(Alert, StateName, State),
- {stop, {shutdown, peer_close}};
-
-handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName,
- #state{ssl_options = SslOpts, renegotiation = {true, From}} = State0) ->
- log_alert(SslOpts#ssl_options.log_alert, StateName, Alert),
- gen_statem:reply(From, {error, renegotiation_rejected}),
- {Record, State} = next_record(State0),
- %% Go back to connection!
- next_event(connection, Record, State);
+ handle_alerts(Alerts, ssl_connection:handle_alert(Alert, StateName, State)).
-%% Gracefully log and ignore all other warning alerts
-handle_alert(#alert{level = ?WARNING} = Alert, StateName,
- #state{ssl_options = SslOpts} = State0) ->
- log_alert(SslOpts#ssl_options.log_alert, StateName, Alert),
- {Record, State} = next_record(State0),
- next_event(StateName, Record, State).
-
-alert_user(Transport, Tracker, Socket, connection, Opts, Pid, From, Alert, Role) ->
- alert_user(Transport, Tracker, Socket, Opts#socket_options.active, Pid, From, Alert, Role);
-alert_user(Transport, Tracker, Socket,_, _, _, From, Alert, Role) ->
- alert_user(Transport, Tracker, Socket, From, Alert, Role).
-
-alert_user(Transport, Tracker, Socket, From, Alert, Role) ->
- alert_user(Transport, Tracker, Socket, false, no_pid, From, Alert, Role).
-
-alert_user(_, _, _, false = Active, Pid, From, Alert, Role) when From =/= undefined ->
- %% If there is an outstanding ssl_accept | recv
- %% From will be defined and send_or_reply will
- %% send the appropriate error message.
- ReasonCode = ssl_alert:reason_code(Alert, Role),
- send_or_reply(Active, Pid, From, {error, ReasonCode});
-alert_user(Transport, Tracker, Socket, Active, Pid, From, Alert, Role) ->
- case ssl_alert:reason_code(Alert, Role) of
- closed ->
- send_or_reply(Active, Pid, From,
- {ssl_closed, ssl_socket:socket(self(),
- Transport, Socket, ?MODULE, Tracker)});
- ReasonCode ->
- send_or_reply(Active, Pid, From,
- {ssl_error, ssl_socket:socket(self(),
- Transport, Socket, ?MODULE, Tracker), ReasonCode})
- end.
-
-log_alert(true, Info, Alert) ->
- Txt = ssl_alert:alert_txt(Alert),
- error_logger:format("SSL: ~p: ~s\n", [Info, Txt]);
-log_alert(false, _, _) ->
- ok.
-
-handle_own_alert(Alert, Version, StateName,
- #state{transport_cb = Transport,
- socket = Socket,
- connection_states = ConnectionStates,
- ssl_options = SslOpts} = State) ->
- try %% Try to tell the other side
- {BinMsg, _} =
- ssl_alert:encode(Alert, Version, ConnectionStates),
- Transport:send(Socket, BinMsg)
- catch _:_ -> %% Can crash if we are in a uninitialized state
- ignore
- end,
- try %% Try to tell the local user
- log_alert(SslOpts#ssl_options.log_alert, StateName, Alert),
- handle_normal_shutdown(Alert,StateName, State)
- catch _:_ ->
- ok
- end,
- {stop, {shutdown, own_alert}}.
-
-handle_normal_shutdown(Alert, _, #state{socket = Socket,
- transport_cb = Transport,
- start_or_recv_from = StartFrom,
- tracker = Tracker,
- role = Role, renegotiation = {false, first}}) ->
- alert_user(Transport, Tracker,Socket, StartFrom, Alert, Role);
-
-handle_normal_shutdown(Alert, StateName, #state{socket = Socket,
- socket_options = Opts,
- transport_cb = Transport,
- user_application = {_Mon, Pid},
- tracker = Tracker,
- start_or_recv_from = RecvFrom, role = Role}) ->
- alert_user(Transport, Tracker, Socket, StateName, Opts, Pid, RecvFrom, Alert, Role).
-
-handle_close_alert(Data, StateName, State0) ->
- case next_tls_record(Data, State0) of
- {#ssl_tls{type = ?ALERT, fragment = EncAlerts}, State} ->
- [Alert|_] = decode_alerts(EncAlerts),
- handle_normal_shutdown(Alert, StateName, State);
- _ ->
- ok
- end.
-
-cancel_timer(undefined) ->
- ok;
-cancel_timer(Timer) ->
- erlang:cancel_timer(Timer),
- ok.
-
-invalidate_session(client, Host, Port, Session) ->
- ssl_manager:invalidate_session(Host, Port, Session);
-invalidate_session(server, _, Port, Session) ->
- ssl_manager:invalidate_session(Port, Session).
%% User closes or recursive call!
close({close, Timeout}, Socket, Transport = gen_tcp, _,_) ->
- ssl_socket:setopts(Transport, Socket, [{active, false}]),
+ tls_socket:setopts(Transport, Socket, [{active, false}]),
Transport:shutdown(Socket, write),
_ = Transport:recv(Socket, 0, Timeout),
ok;
@@ -1011,31 +731,66 @@ convert_options_partial_chain(Options, up) ->
convert_options_partial_chain(Options, down) ->
list_to_tuple(proplists:delete(partial_chain, tuple_to_list(Options))).
-handle_sni_extension(#client_hello{extensions = HelloExtensions}, State0) ->
- case HelloExtensions#hello_extensions.sni of
- undefined ->
- State0;
- #sni{hostname = Hostname} ->
- NewOptions = update_ssl_options_from_sni(State0#state.ssl_options, Hostname),
- case NewOptions of
- undefined ->
- State0;
- _ ->
- {ok, Ref, CertDbHandle, FileRefHandle, CacheHandle, CRLDbHandle, OwnCert, Key, DHParams} =
- ssl_config:init(NewOptions, State0#state.role),
- State0#state{
- session = State0#state.session#session{own_certificate = OwnCert},
- file_ref_db = FileRefHandle,
- cert_db_ref = Ref,
- cert_db = CertDbHandle,
- crl_db = CRLDbHandle,
- session_cache = CacheHandle,
- private_key = Key,
- diffie_hellman_params = DHParams,
- ssl_options = NewOptions,
- sni_hostname = Hostname
- }
- end
+gen_handshake(GenConnection, StateName, Type, Event,
+ #state{negotiated_version = Version} = State) ->
+ try GenConnection:StateName(Type, Event, State, ?MODULE) of
+ Result ->
+ Result
+ catch
+ _:_ ->
+ ssl_connection:handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
+ malformed_handshake_data),
+ Version, StateName, State)
+ end.
+
+gen_info(Event, connection = StateName, #state{negotiated_version = Version} = State) ->
+ try handle_info(Event, StateName, State) of
+ Result ->
+ Result
+ catch
+ _:_ ->
+ ssl_connection:handle_own_alert(?ALERT_REC(?FATAL, ?INTERNAL_ERROR,
+ malformed_data),
+ Version, StateName, State)
end;
-handle_sni_extension(_, State) ->
- State.
+
+gen_info(Event, StateName, #state{negotiated_version = Version} = State) ->
+ try handle_info(Event, StateName, State) of
+ Result ->
+ Result
+ catch
+ _:_ ->
+ ssl_connection:handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
+ malformed_handshake_data),
+ Version, StateName, State)
+ end.
+
+unprocessed_events(Events) ->
+ %% The first handshake event will be processed immediately
+ %% as it is entered first in the event queue and
+ %% when it is processed there will be length(Events)-1
+ %% handshake events left to process before we should
+ %% process more TLS-records received on the socket.
+ erlang:length(Events)-1.
+
+
+assert_buffer_sanity(<<?BYTE(_Type), ?UINT24(Length), Rest/binary>>, #ssl_options{max_handshake_size = Max}) when
+ Length =< Max ->
+ case size(Rest) of
+ N when N < Length ->
+ true;
+ N when N > Length ->
+ throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
+ too_big_handshake_data));
+ _ ->
+ throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
+ malformed_handshake_data))
+ end;
+assert_buffer_sanity(Bin, _) ->
+ case size(Bin) of
+ N when N < 3 ->
+ true;
+ _ ->
+ throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
+ malformed_handshake_data))
+ end.
diff --git a/lib/ssl/src/tls_handshake.erl b/lib/ssl/src/tls_handshake.erl
index 566b7db332..b54540393a 100644
--- a/lib/ssl/src/tls_handshake.erl
+++ b/lib/ssl/src/tls_handshake.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -41,7 +41,7 @@
%% Internal application API
%%====================================================================
%%--------------------------------------------------------------------
--spec client_hello(host(), inet:port_number(), #connection_states{},
+-spec client_hello(host(), inet:port_number(), ssl_record:connection_states(),
#ssl_options{}, integer(), atom(), boolean(), der_cert()) ->
#client_hello{}.
%%
@@ -54,10 +54,9 @@ client_hello(Host, Port, ConnectionStates,
} = SslOpts,
Cache, CacheCb, Renegotiation, OwnCert) ->
Version = tls_record:highest_protocol_version(Versions),
- Pending = ssl_record:pending_connection_state(ConnectionStates, read),
- SecParams = Pending#connection_state.security_parameters,
+ #{security_parameters := SecParams} = ssl_record:pending_connection_state(ConnectionStates, read),
AvailableCipherSuites = ssl_handshake:available_suites(UserSuites, Version),
- Extensions = ssl_handshake:client_hello_extensions(Host, Version,
+ Extensions = ssl_handshake:client_hello_extensions(Version,
AvailableCipherSuites,
SslOpts, ConnectionStates, Renegotiation),
CipherSuites =
@@ -78,18 +77,18 @@ client_hello(Host, Port, ConnectionStates,
%%--------------------------------------------------------------------
-spec hello(#server_hello{} | #client_hello{}, #ssl_options{},
- #connection_states{} | {inet:port_number(), #session{}, db_handle(),
- atom(), #connection_states{},
+ ssl_record:connection_states() | {inet:port_number(), #session{}, db_handle(),
+ atom(), ssl_record:connection_states(),
binary() | undefined, ssl_cipher:key_algo()},
boolean()) ->
{tls_record:tls_version(), session_id(),
- #connection_states{}, alpn | npn, binary() | undefined}|
+ ssl_record:connection_states(), alpn | npn, binary() | undefined}|
{tls_record:tls_version(), {resumed | new, #session{}},
- #connection_states{}, binary() | undefined,
+ ssl_record:connection_states(), binary() | undefined,
#hello_extensions{}, {ssl_cipher:hash(), ssl_cipher:sign_algo()} | undefined} |
#alert{}.
%%
-%% Description: Handles a recieved hello message
+%% Description: Handles a received hello message
%%--------------------------------------------------------------------
hello(#server_hello{server_version = Version, random = Random,
cipher_suite = CipherSuite,
@@ -109,19 +108,25 @@ hello(#client_hello{client_version = ClientVersion,
cipher_suites = CipherSuites} = Hello,
#ssl_options{versions = Versions} = SslOpts,
Info, Renegotiation) ->
- Version = ssl_handshake:select_version(tls_record, ClientVersion, Versions),
- case ssl_cipher:is_fallback(CipherSuites) of
+ try
+ Version = ssl_handshake:select_version(tls_record, ClientVersion, Versions),
+ case ssl_cipher:is_fallback(CipherSuites) of
true ->
- Highest = tls_record:highest_protocol_version(Versions),
- case tls_record:is_higher(Highest, Version) of
- true ->
- ?ALERT_REC(?FATAL, ?INAPPROPRIATE_FALLBACK);
- false ->
- handle_client_hello(Version, Hello, SslOpts, Info, Renegotiation)
- end;
- false ->
- handle_client_hello(Version, Hello, SslOpts, Info, Renegotiation)
- end.
+ Highest = tls_record:highest_protocol_version(Versions),
+ case tls_record:is_higher(Highest, Version) of
+ true ->
+ ?ALERT_REC(?FATAL, ?INAPPROPRIATE_FALLBACK);
+ false ->
+ handle_client_hello(Version, Hello, SslOpts, Info, Renegotiation)
+ end;
+ false ->
+ handle_client_hello(Version, Hello, SslOpts, Info, Renegotiation)
+ end
+ catch
+ _:_ ->
+ ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, malformed_handshake_data)
+ end.
+
%%--------------------------------------------------------------------
-spec encode_handshake(tls_handshake(), tls_record:tls_version()) -> iolist().
%%
@@ -155,13 +160,15 @@ handle_client_hello(Version, #client_hello{session_id = SugesstedId,
extensions = #hello_extensions{elliptic_curves = Curves,
signature_algs = ClientHashSigns} = HelloExt},
#ssl_options{versions = Versions,
- signature_algs = SupportedHashSigns} = SslOpts,
+ signature_algs = SupportedHashSigns,
+ eccs = SupportedECCs,
+ honor_ecc_order = ECCOrder} = SslOpts,
{Port, Session0, Cache, CacheCb, ConnectionStates0, Cert, _}, Renegotiation) ->
case tls_record:is_acceptable_version(Version, Versions) of
true ->
AvailableHashSigns = ssl_handshake:available_signature_algs(
ClientHashSigns, SupportedHashSigns, Cert, Version),
- ECCCurve = ssl_handshake:select_curve(Curves, ssl_handshake:supported_ecc(Version)),
+ ECCCurve = ssl_handshake:select_curve(Curves, SupportedECCs, ECCOrder),
{Type, #session{cipher_suite = CipherSuite} = Session1}
= ssl_handshake:select_session(SugesstedId, CipherSuites, AvailableHashSigns, Compressions,
Port, Session0#session{ecc = ECCCurve}, Version,
@@ -185,37 +192,33 @@ handle_client_hello(Version, #client_hello{session_id = SugesstedId,
end.
get_tls_handshake_aux(Version, <<?BYTE(Type), ?UINT24(Length),
- Body:Length/binary,Rest/binary>>, #ssl_options{v2_hello_compatible = V2Hello} = Opts, Acc) ->
+ Body:Length/binary,Rest/binary>>,
+ #ssl_options{v2_hello_compatible = V2Hello} = Opts, Acc) ->
Raw = <<?BYTE(Type), ?UINT24(Length), Body/binary>>,
- Handshake = decode_handshake(Version, Type, Body, V2Hello),
- get_tls_handshake_aux(Version, Rest, Opts, [{Handshake,Raw} | Acc]);
+ try decode_handshake(Version, Type, Body, V2Hello) of
+ Handshake ->
+ get_tls_handshake_aux(Version, Rest, Opts, [{Handshake,Raw} | Acc])
+ catch
+ _:_ ->
+ throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, handshake_decode_error))
+ end;
get_tls_handshake_aux(_Version, Data, _, Acc) ->
{lists:reverse(Acc), Data}.
decode_handshake(_, ?HELLO_REQUEST, <<>>, _) ->
#hello_request{};
-%% Client hello v2.
-%% The server must be able to receive such messages, from clients that
-%% are willing to use ssl v3 or higher, but have ssl v2 compatibility.
-decode_handshake(_Version, ?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor),
- ?UINT16(CSLength), ?UINT16(0),
- ?UINT16(CDLength),
- CipherSuites:CSLength/binary,
- ChallengeData:CDLength/binary>>, true) ->
- #client_hello{client_version = {Major, Minor},
- random = ssl_v2:client_random(ChallengeData, CDLength),
- session_id = 0,
- cipher_suites = ssl_handshake:decode_suites('3_bytes', CipherSuites),
- compression_methods = [?NULL],
- extensions = #hello_extensions{}
- };
-decode_handshake(_Version, ?CLIENT_HELLO, <<?BYTE(_), ?BYTE(_),
- ?UINT16(CSLength), ?UINT16(0),
- ?UINT16(CDLength),
- _CipherSuites:CSLength/binary,
- _ChallengeData:CDLength/binary>>, false) ->
- throw(?ALERT_REC(?FATAL, ?PROTOCOL_VERSION, ssl_v2_client_hello_no_supported));
+decode_handshake(_Version, ?CLIENT_HELLO, Bin, true) ->
+ try decode_hello(Bin) of
+ Hello ->
+ Hello
+ catch
+ _:_ ->
+ decode_v2_hello(Bin)
+ end;
+decode_handshake(_Version, ?CLIENT_HELLO, Bin, false) ->
+ decode_hello(Bin);
+
decode_handshake(_Version, ?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SID_length), Session_ID:SID_length/binary,
?UINT16(Cs_length), CipherSuites:Cs_length/binary,
@@ -232,10 +235,40 @@ decode_handshake(_Version, ?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:3
compression_methods = Comp_methods,
extensions = DecodedExtensions
};
-
decode_handshake(Version, Tag, Msg, _) ->
ssl_handshake:decode_handshake(Version, Tag, Msg).
+
+decode_hello(<<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
+ ?BYTE(SID_length), Session_ID:SID_length/binary,
+ ?UINT16(Cs_length), CipherSuites:Cs_length/binary,
+ ?BYTE(Cm_length), Comp_methods:Cm_length/binary,
+ Extensions/binary>>) ->
+ DecodedExtensions = ssl_handshake:decode_hello_extensions({client, Extensions}),
+
+ #client_hello{
+ client_version = {Major,Minor},
+ random = Random,
+ session_id = Session_ID,
+ cipher_suites = ssl_handshake:decode_suites('2_bytes', CipherSuites),
+ compression_methods = Comp_methods,
+ extensions = DecodedExtensions
+ }.
+%% The server must be able to receive such messages, from clients that
+%% are willing to use ssl v3 or higher, but have ssl v2 compatibility.
+decode_v2_hello(<<?BYTE(Major), ?BYTE(Minor),
+ ?UINT16(CSLength), ?UINT16(0),
+ ?UINT16(CDLength),
+ CipherSuites:CSLength/binary,
+ ChallengeData:CDLength/binary>>) ->
+ #client_hello{client_version = {Major, Minor},
+ random = ssl_v2:client_random(ChallengeData, CDLength),
+ session_id = 0,
+ cipher_suites = ssl_handshake:decode_suites('3_bytes', CipherSuites),
+ compression_methods = [?NULL],
+ extensions = #hello_extensions{}
+ }.
+
enc_handshake(#hello_request{}, _Version) ->
{?HELLO_REQUEST, <<>>};
enc_handshake(#client_hello{client_version = {Major, Minor},
diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl
index 9348c8bbdd..4ac6cdc6b5 100644
--- a/lib/ssl/src/tls_record.erl
+++ b/lib/ssl/src/tls_record.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,19 +32,21 @@
-include("ssl_cipher.hrl").
%% Handling of incoming data
--export([get_tls_records/2]).
+-export([get_tls_records/2, init_connection_states/2]).
-%% Decoding
--export([decode_cipher_text/3]).
-
-%% Encoding
+%% Encoding TLS records
+-export([encode_handshake/3, encode_alert_record/3,
+ encode_change_cipher_spec/2, encode_data/3]).
-export([encode_plain_text/4]).
%% Protocol version handling
-export([protocol_version/1, lowest_protocol_version/1, lowest_protocol_version/2,
highest_protocol_version/1, highest_protocol_version/2,
is_higher/2, supported_protocol_versions/0,
- is_acceptable_version/1, is_acceptable_version/2]).
+ is_acceptable_version/1, is_acceptable_version/2, hello_version/2]).
+
+%% Decoding
+-export([decode_cipher_text/3]).
-export_type([tls_version/0, tls_atom_version/0]).
@@ -56,12 +58,28 @@
%%====================================================================
%% Internal application API
%%====================================================================
+%%--------------------------------------------------------------------
+-spec init_connection_states(client | server, one_n_minus_one | zero_n | disabled) ->
+ ssl_record:connection_states().
+%% %
+ %
+%% Description: Creates a connection_states record with appropriate
+%% values for the initial SSL connection setup.
+%%--------------------------------------------------------------------
+init_connection_states(Role, BeastMitigation) ->
+ ConnectionEnd = ssl_record:record_protocol_role(Role),
+ Current = initial_connection_state(ConnectionEnd, BeastMitigation),
+ Pending = ssl_record:empty_connection_state(ConnectionEnd, BeastMitigation),
+ #{current_read => Current,
+ pending_read => Pending,
+ current_write => Current,
+ pending_write => Pending}.
%%--------------------------------------------------------------------
-spec get_tls_records(binary(), binary()) -> {[binary()], binary()} | #alert{}.
%%
-%% Description: Given old buffer and new data from TCP, packs up a records
%% and returns it as a list of tls_compressed binaries also returns leftover
+%% Description: Given old buffer and new data from TCP, packs up a records
%% data
%%--------------------------------------------------------------------
get_tls_records(Data, <<>>) ->
@@ -69,155 +87,61 @@ get_tls_records(Data, <<>>) ->
get_tls_records(Data, Buffer) ->
get_tls_records_aux(list_to_binary([Buffer, Data]), []).
-get_tls_records_aux(<<?BYTE(?APPLICATION_DATA),?BYTE(MajVer),?BYTE(MinVer),
- ?UINT16(Length), Data:Length/binary, Rest/binary>>,
- Acc) ->
- get_tls_records_aux(Rest, [#ssl_tls{type = ?APPLICATION_DATA,
- version = {MajVer, MinVer},
- fragment = Data} | Acc]);
-get_tls_records_aux(<<?BYTE(?HANDSHAKE),?BYTE(MajVer),?BYTE(MinVer),
- ?UINT16(Length),
- Data:Length/binary, Rest/binary>>, Acc) ->
- get_tls_records_aux(Rest, [#ssl_tls{type = ?HANDSHAKE,
- version = {MajVer, MinVer},
- fragment = Data} | Acc]);
-get_tls_records_aux(<<?BYTE(?ALERT),?BYTE(MajVer),?BYTE(MinVer),
- ?UINT16(Length), Data:Length/binary,
- Rest/binary>>, Acc) ->
- get_tls_records_aux(Rest, [#ssl_tls{type = ?ALERT,
- version = {MajVer, MinVer},
- fragment = Data} | Acc]);
-get_tls_records_aux(<<?BYTE(?CHANGE_CIPHER_SPEC),?BYTE(MajVer),?BYTE(MinVer),
- ?UINT16(Length), Data:Length/binary, Rest/binary>>,
- Acc) ->
- get_tls_records_aux(Rest, [#ssl_tls{type = ?CHANGE_CIPHER_SPEC,
- version = {MajVer, MinVer},
- fragment = Data} | Acc]);
-%% Matches an ssl v2 client hello message.
-%% The server must be able to receive such messages, from clients that
-%% are willing to use ssl v3 or higher, but have ssl v2 compatibility.
-get_tls_records_aux(<<1:1, Length0:15, Data0:Length0/binary, Rest/binary>>,
- Acc) ->
- case Data0 of
- <<?BYTE(?CLIENT_HELLO), ?BYTE(MajVer), ?BYTE(MinVer), _/binary>> ->
- Length = Length0-1,
- <<?BYTE(_), Data1:Length/binary>> = Data0,
- Data = <<?BYTE(?CLIENT_HELLO), ?UINT24(Length), Data1/binary>>,
- get_tls_records_aux(Rest, [#ssl_tls{type = ?HANDSHAKE,
- version = {MajVer, MinVer},
- fragment = Data} | Acc]);
- _ ->
- ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)
-
- end;
-
-get_tls_records_aux(<<0:1, _CT:7, ?BYTE(_MajVer), ?BYTE(_MinVer),
- ?UINT16(Length), _/binary>>,
- _Acc) when Length > ?MAX_CIPHER_TEXT_LENGTH ->
- ?ALERT_REC(?FATAL, ?RECORD_OVERFLOW);
-
-get_tls_records_aux(<<1:1, Length0:15, _/binary>>,_Acc)
- when Length0 > ?MAX_CIPHER_TEXT_LENGTH ->
- ?ALERT_REC(?FATAL, ?RECORD_OVERFLOW);
+%%--------------------------------------------------------------------
+-spec encode_handshake(iolist(), tls_version(), ssl_record:connection_states()) ->
+ {iolist(), ssl_record:connection_states()}.
+%
+%% Description: Encodes a handshake message to send on the ssl-socket.
+%%--------------------------------------------------------------------
+encode_handshake(Frag, Version,
+ #{current_write :=
+ #{beast_mitigation := BeastMitigation,
+ security_parameters :=
+ #security_parameters{bulk_cipher_algorithm = BCA}}} =
+ ConnectionStates) ->
+ case iolist_size(Frag) of
+ N when N > ?MAX_PLAIN_TEXT_LENGTH ->
+ Data = split_bin(iolist_to_binary(Frag), ?MAX_PLAIN_TEXT_LENGTH, Version, BCA, BeastMitigation),
+ encode_iolist(?HANDSHAKE, Data, Version, ConnectionStates);
+ _ ->
+ encode_plain_text(?HANDSHAKE, Version, Frag, ConnectionStates)
+ end.
-get_tls_records_aux(Data, Acc) ->
- case size(Data) =< ?MAX_CIPHER_TEXT_LENGTH + ?INITIAL_BYTES of
- true ->
- {lists:reverse(Acc), Data};
- false ->
- ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE)
- end.
+%%--------------------------------------------------------------------
+-spec encode_alert_record(#alert{}, tls_version(), ssl_record:connection_states()) ->
+ {iolist(), ssl_record:connection_states()}.
+%%
+%% Description: Encodes an alert message to send on the ssl-socket.
+%%--------------------------------------------------------------------
+encode_alert_record(#alert{level = Level, description = Description},
+ Version, ConnectionStates) ->
+ encode_plain_text(?ALERT, Version, <<?BYTE(Level), ?BYTE(Description)>>,
+ ConnectionStates).
-encode_plain_text(Type, Version, Data,
- #connection_states{current_write =
- #connection_state{
- sequence_number = Seq,
- compression_state=CompS0,
- security_parameters=
- #security_parameters{
- cipher_type = ?AEAD,
- compression_algorithm=CompAlg}
- }= WriteState0} = ConnectionStates) ->
- {Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0),
- WriteState1 = WriteState0#connection_state{compression_state = CompS1},
- AAD = calc_aad(Type, Version, WriteState1),
- {CipherFragment, WriteState} = ssl_record:cipher_aead(Version, Comp, WriteState1, AAD),
- CipherText = encode_tls_cipher_text(Type, Version, CipherFragment),
- {CipherText, ConnectionStates#connection_states{current_write = WriteState#connection_state{sequence_number = Seq +1}}};
-
-encode_plain_text(Type, Version, Data,
- #connection_states{current_write =
- #connection_state{
- sequence_number = Seq,
- compression_state=CompS0,
- security_parameters=
- #security_parameters{compression_algorithm=CompAlg}
- }= WriteState0} = ConnectionStates) ->
- {Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0),
- WriteState1 = WriteState0#connection_state{compression_state = CompS1},
- MacHash = calc_mac_hash(Type, Version, Comp, WriteState1),
- {CipherFragment, WriteState} = ssl_record:cipher(Version, Comp, WriteState1, MacHash),
- CipherText = encode_tls_cipher_text(Type, Version, CipherFragment),
- {CipherText, ConnectionStates#connection_states{current_write = WriteState#connection_state{sequence_number = Seq +1}}}.
+%%--------------------------------------------------------------------
+-spec encode_change_cipher_spec(tls_version(), ssl_record:connection_states()) ->
+ {iolist(), ssl_record:connection_states()}.
+%%
+%% Description: Encodes a change_cipher_spec-message to send on the ssl socket.
+%%--------------------------------------------------------------------
+encode_change_cipher_spec(Version, ConnectionStates) ->
+ encode_plain_text(?CHANGE_CIPHER_SPEC, Version, ?byte(?CHANGE_CIPHER_SPEC_PROTO), ConnectionStates).
%%--------------------------------------------------------------------
--spec decode_cipher_text(#ssl_tls{}, #connection_states{}, boolean()) ->
- {#ssl_tls{}, #connection_states{}}| #alert{}.
+-spec encode_data(binary(), tls_version(), ssl_record:connection_states()) ->
+ {iolist(), ssl_record:connection_states()}.
%%
-%% Description: Decode cipher text
+%% Description: Encodes data to send on the ssl-socket.
%%--------------------------------------------------------------------
-decode_cipher_text(#ssl_tls{type = Type, version = Version,
- fragment = CipherFragment} = CipherText,
- #connection_states{current_read =
- #connection_state{
- compression_state = CompressionS0,
- sequence_number = Seq,
- security_parameters=
- #security_parameters{
- cipher_type = ?AEAD,
- compression_algorithm=CompAlg}
- } = ReadState0} = ConnnectionStates0, _) ->
- AAD = calc_aad(Type, Version, ReadState0),
- case ssl_record:decipher_aead(Version, CipherFragment, ReadState0, AAD) of
- {PlainFragment, ReadState1} ->
- {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
- PlainFragment, CompressionS0),
- ConnnectionStates = ConnnectionStates0#connection_states{
- current_read = ReadState1#connection_state{
- sequence_number = Seq + 1,
- compression_state = CompressionS1}},
- {CipherText#ssl_tls{fragment = Plain}, ConnnectionStates};
- #alert{} = Alert ->
- Alert
- end;
+encode_data(Frag, Version,
+ #{current_write := #{beast_mitigation := BeastMitigation,
+ security_parameters :=
+ #security_parameters{bulk_cipher_algorithm = BCA}}} =
+ ConnectionStates) ->
+ Data = split_bin(Frag, ?MAX_PLAIN_TEXT_LENGTH, Version, BCA, BeastMitigation),
+ encode_iolist(?APPLICATION_DATA, Data, Version, ConnectionStates).
+
-decode_cipher_text(#ssl_tls{type = Type, version = Version,
- fragment = CipherFragment} = CipherText,
- #connection_states{current_read =
- #connection_state{
- compression_state = CompressionS0,
- sequence_number = Seq,
- security_parameters=
- #security_parameters{compression_algorithm=CompAlg}
- } = ReadState0} = ConnnectionStates0, PaddingCheck) ->
- case ssl_record:decipher(Version, CipherFragment, ReadState0, PaddingCheck) of
- {PlainFragment, Mac, ReadState1} ->
- MacHash = calc_mac_hash(Type, Version, PlainFragment, ReadState1),
- case ssl_record:is_correct_mac(Mac, MacHash) of
- true ->
- {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
- PlainFragment, CompressionS0),
- ConnnectionStates = ConnnectionStates0#connection_states{
- current_read = ReadState1#connection_state{
- sequence_number = Seq + 1,
- compression_state = CompressionS1}},
- {CipherText#ssl_tls{fragment = Plain}, ConnnectionStates};
- false ->
- ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
- end;
- #alert{} = Alert ->
- Alert
- end.
%%--------------------------------------------------------------------
-spec protocol_version(tls_atom_version() | tls_version()) ->
tls_version() | tls_atom_version().
@@ -353,6 +277,7 @@ supported_protocol_versions([_|_] = Vsns) ->
NewVsns
end
end.
+
%%--------------------------------------------------------------------
%%
%% Description: ssl version 2 is not acceptable security risks are too big.
@@ -372,9 +297,90 @@ is_acceptable_version({N,_} = Version, Versions)
is_acceptable_version(_,_) ->
false.
+-spec hello_version(tls_version(), [tls_version()]) -> tls_version().
+hello_version(Version, _) when Version >= {3, 3} ->
+ Version;
+hello_version(_, Versions) ->
+ lowest_protocol_version(Versions).
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+initial_connection_state(ConnectionEnd, BeastMitigation) ->
+ #{security_parameters =>
+ ssl_record:initial_security_params(ConnectionEnd),
+ sequence_number => 0,
+ beast_mitigation => BeastMitigation,
+ compression_state => undefined,
+ cipher_state => undefined,
+ mac_secret => undefined,
+ secure_renegotiation => undefined,
+ client_verify_data => undefined,
+ server_verify_data => undefined
+ }.
+
+get_tls_records_aux(<<?BYTE(?APPLICATION_DATA),?BYTE(MajVer),?BYTE(MinVer),
+ ?UINT16(Length), Data:Length/binary, Rest/binary>>,
+ Acc) ->
+ get_tls_records_aux(Rest, [#ssl_tls{type = ?APPLICATION_DATA,
+ version = {MajVer, MinVer},
+ fragment = Data} | Acc]);
+get_tls_records_aux(<<?BYTE(?HANDSHAKE),?BYTE(MajVer),?BYTE(MinVer),
+ ?UINT16(Length),
+ Data:Length/binary, Rest/binary>>, Acc) ->
+ get_tls_records_aux(Rest, [#ssl_tls{type = ?HANDSHAKE,
+ version = {MajVer, MinVer},
+ fragment = Data} | Acc]);
+get_tls_records_aux(<<?BYTE(?ALERT),?BYTE(MajVer),?BYTE(MinVer),
+ ?UINT16(Length), Data:Length/binary,
+ Rest/binary>>, Acc) ->
+ get_tls_records_aux(Rest, [#ssl_tls{type = ?ALERT,
+ version = {MajVer, MinVer},
+ fragment = Data} | Acc]);
+get_tls_records_aux(<<?BYTE(?CHANGE_CIPHER_SPEC),?BYTE(MajVer),?BYTE(MinVer),
+ ?UINT16(Length), Data:Length/binary, Rest/binary>>,
+ Acc) ->
+ get_tls_records_aux(Rest, [#ssl_tls{type = ?CHANGE_CIPHER_SPEC,
+ version = {MajVer, MinVer},
+ fragment = Data} | Acc]);
+%% Matches an ssl v2 client hello message.
+%% The server must be able to receive such messages, from clients that
+%% are willing to use ssl v3 or higher, but have ssl v2 compatibility.
+get_tls_records_aux(<<1:1, Length0:15, Data0:Length0/binary, Rest/binary>>,
+ Acc) ->
+ case Data0 of
+ <<?BYTE(?CLIENT_HELLO), ?BYTE(MajVer), ?BYTE(MinVer), _/binary>> ->
+ Length = Length0-1,
+ <<?BYTE(_), Data1:Length/binary>> = Data0,
+ Data = <<?BYTE(?CLIENT_HELLO), ?UINT24(Length), Data1/binary>>,
+ get_tls_records_aux(Rest, [#ssl_tls{type = ?HANDSHAKE,
+ version = {MajVer, MinVer},
+ fragment = Data} | Acc]);
+ _ ->
+ ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)
+
+ end;
+
+get_tls_records_aux(<<0:1, _CT:7, ?BYTE(_MajVer), ?BYTE(_MinVer),
+ ?UINT16(Length), _/binary>>,
+ _Acc) when Length > ?MAX_CIPHER_TEXT_LENGTH ->
+ ?ALERT_REC(?FATAL, ?RECORD_OVERFLOW);
+
+get_tls_records_aux(<<1:1, Length0:15, _/binary>>,_Acc)
+ when Length0 > ?MAX_CIPHER_TEXT_LENGTH ->
+ ?ALERT_REC(?FATAL, ?RECORD_OVERFLOW);
+
+get_tls_records_aux(Data, Acc) ->
+ case size(Data) =< ?MAX_CIPHER_TEXT_LENGTH + ?INITIAL_BYTES of
+ true ->
+ {lists:reverse(Acc), Data};
+ false ->
+ ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE)
+ end.
+
+encode_plain_text(Type, Version, Data, #{current_write := Write0} = ConnectionStates) ->
+ {CipherFragment, Write1} = do_encode_plain_text(Type, Version, Data, Write0),
+ {CipherText, Write} = encode_tls_cipher_text(Type, Version, CipherFragment, Write1),
+ {CipherText, ConnectionStates#{current_write => Write}}.
lowest_list_protocol_version(Ver, []) ->
Ver;
@@ -386,20 +392,10 @@ highest_list_protocol_version(Ver, []) ->
highest_list_protocol_version(Ver1, [Ver2 | Rest]) ->
highest_list_protocol_version(highest_protocol_version(Ver1, Ver2), Rest).
-encode_tls_cipher_text(Type, {MajVer, MinVer}, Fragment) ->
+encode_tls_cipher_text(Type, {MajVer, MinVer}, Fragment, #{sequence_number := Seq} = Write) ->
Length = erlang:iolist_size(Fragment),
- [<<?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer), ?UINT16(Length)>>, Fragment].
-
-
-mac_hash({_,_}, ?NULL, _MacSecret, _SeqNo, _Type,
- _Length, _Fragment) ->
- <<>>;
-mac_hash({3, 0}, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) ->
- ssl_v3:mac_hash(MacAlg, MacSecret, SeqNo, Type, Length, Fragment);
-mac_hash({3, N} = Version, MacAlg, MacSecret, SeqNo, Type, Length, Fragment)
- when N =:= 1; N =:= 2; N =:= 3 ->
- tls_v1:mac_hash(MacAlg, MacSecret, SeqNo, Type, Version,
- Length, Fragment).
+ {[<<?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer), ?UINT16(Length)>>, Fragment],
+ Write#{sequence_number => Seq +1}}.
highest_protocol_version() ->
highest_protocol_version(supported_protocol_versions()).
@@ -407,21 +403,126 @@ highest_protocol_version() ->
lowest_protocol_version() ->
lowest_protocol_version(supported_protocol_versions()).
-
sufficient_tlsv1_2_crypto_support() ->
CryptoSupport = crypto:supports(),
proplists:get_bool(sha256, proplists:get_value(hashs, CryptoSupport)).
-calc_mac_hash(Type, Version,
- PlainFragment, #connection_state{sequence_number = SeqNo,
- mac_secret = MacSecret,
- security_parameters =
- SecPars}) ->
- Length = erlang:iolist_size(PlainFragment),
- mac_hash(Version, SecPars#security_parameters.mac_algorithm,
- MacSecret, SeqNo, Type,
- Length, PlainFragment).
+encode_iolist(Type, Data, Version, ConnectionStates0) ->
+ {ConnectionStates, EncodedMsg} =
+ lists:foldl(fun(Text, {CS0, Encoded}) ->
+ {Enc, CS1} =
+ encode_plain_text(Type, Version, Text, CS0),
+ {CS1, [Enc | Encoded]}
+ end, {ConnectionStates0, []}, Data),
+ {lists:reverse(EncodedMsg), ConnectionStates}.
+
+%% 1/n-1 splitting countermeasure Rizzo/Duong-Beast, RC4 chiphers are
+%% not vulnerable to this attack.
+split_bin(<<FirstByte:8, Rest/binary>>, ChunkSize, Version, BCA, one_n_minus_one) when
+ BCA =/= ?RC4 andalso ({3, 1} == Version orelse
+ {3, 0} == Version) ->
+ do_split_bin(Rest, ChunkSize, [[FirstByte]]);
+%% 0/n splitting countermeasure for clients that are incompatible with 1/n-1
+%% splitting.
+split_bin(Bin, ChunkSize, Version, BCA, zero_n) when
+ BCA =/= ?RC4 andalso ({3, 1} == Version orelse
+ {3, 0} == Version) ->
+ do_split_bin(Bin, ChunkSize, [[<<>>]]);
+split_bin(Bin, ChunkSize, _, _, _) ->
+ do_split_bin(Bin, ChunkSize, []).
+
+do_split_bin(<<>>, _, Acc) ->
+ lists:reverse(Acc);
+do_split_bin(Bin, ChunkSize, Acc) ->
+ case Bin of
+ <<Chunk:ChunkSize/binary, Rest/binary>> ->
+ do_split_bin(Rest, ChunkSize, [Chunk | Acc]);
+ _ ->
+ lists:reverse(Acc, [Bin])
+ end.
+
+%%--------------------------------------------------------------------
+-spec decode_cipher_text(#ssl_tls{}, ssl_record:connection_states(), boolean()) ->
+ {#ssl_tls{}, ssl_record:connection_states()}| #alert{}.
+%%
+%% Description: Decode cipher text
+%%--------------------------------------------------------------------
+decode_cipher_text(#ssl_tls{type = Type, version = Version,
+ fragment = CipherFragment} = CipherText,
+ #{current_read :=
+ #{compression_state := CompressionS0,
+ sequence_number := Seq,
+ cipher_state := CipherS0,
+ security_parameters :=
+ #security_parameters{
+ cipher_type = ?AEAD,
+ bulk_cipher_algorithm =
+ BulkCipherAlgo,
+ compression_algorithm = CompAlg}
+ } = ReadState0} = ConnnectionStates0, _) ->
+ AAD = calc_aad(Type, Version, ReadState0),
+ case ssl_cipher:decipher_aead(BulkCipherAlgo, CipherS0, Seq, AAD, CipherFragment, Version) of
+ {PlainFragment, CipherS1} ->
+ {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
+ PlainFragment, CompressionS0),
+ ConnnectionStates = ConnnectionStates0#{
+ current_read => ReadState0#{
+ cipher_state => CipherS1,
+ sequence_number => Seq + 1,
+ compression_state => CompressionS1}},
+ {CipherText#ssl_tls{fragment = Plain}, ConnnectionStates};
+ #alert{} = Alert ->
+ Alert
+ end;
+
+decode_cipher_text(#ssl_tls{type = Type, version = Version,
+ fragment = CipherFragment} = CipherText,
+ #{current_read :=
+ #{compression_state := CompressionS0,
+ sequence_number := Seq,
+ security_parameters :=
+ #security_parameters{compression_algorithm = CompAlg}
+ } = ReadState0} = ConnnectionStates0, PaddingCheck) ->
+ case ssl_record:decipher(Version, CipherFragment, ReadState0, PaddingCheck) of
+ {PlainFragment, Mac, ReadState1} ->
+ MacHash = ssl_cipher:calc_mac_hash(Type, Version, PlainFragment, ReadState1),
+ case ssl_record:is_correct_mac(Mac, MacHash) of
+ true ->
+ {Plain, CompressionS1} = ssl_record:uncompress(CompAlg,
+ PlainFragment, CompressionS0),
+ ConnnectionStates = ConnnectionStates0#{
+ current_read => ReadState1#{
+ sequence_number => Seq + 1,
+ compression_state => CompressionS1}},
+ {CipherText#ssl_tls{fragment = Plain}, ConnnectionStates};
+ false ->
+ ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
+ end;
+ #alert{} = Alert ->
+ Alert
+ end.
+
+do_encode_plain_text(Type, Version, Data, #{compression_state := CompS0,
+ security_parameters :=
+ #security_parameters{
+ cipher_type = ?AEAD,
+ compression_algorithm = CompAlg}
+ } = WriteState0) ->
+ {Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0),
+ WriteState1 = WriteState0#{compression_state => CompS1},
+ AAD = calc_aad(Type, Version, WriteState1),
+ ssl_record:cipher_aead(Version, Comp, WriteState1, AAD);
+do_encode_plain_text(Type, Version, Data, #{compression_state := CompS0,
+ security_parameters :=
+ #security_parameters{compression_algorithm = CompAlg}
+ }= WriteState0) ->
+ {Comp, CompS1} = ssl_record:compress(CompAlg, Data, CompS0),
+ WriteState1 = WriteState0#{compression_state => CompS1},
+ MacHash = ssl_cipher:calc_mac_hash(Type, Version, Comp, WriteState1),
+ ssl_record:cipher(Version, Comp, WriteState1, MacHash);
+do_encode_plain_text(_,_,_,CS) ->
+ exit({cs, CS}).
calc_aad(Type, {MajVer, MinVer},
- #connection_state{sequence_number = SeqNo}) ->
- <<SeqNo:64/integer, ?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer)>>.
+ #{sequence_number := SeqNo}) ->
+ <<?UINT64(SeqNo), ?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer)>>.
diff --git a/lib/ssl/src/ssl_socket.erl b/lib/ssl/src/tls_socket.erl
index b2aea2ba9c..e76d9c100a 100644
--- a/lib/ssl/src/ssl_socket.erl
+++ b/lib/ssl/src/tls_socket.erl
@@ -17,16 +17,19 @@
%%
%% %CopyrightEnd%
%%
--module(ssl_socket).
+-module(tls_socket).
-behaviour(gen_server).
-include("ssl_internal.hrl").
-include("ssl_api.hrl").
--export([socket/5, setopts/3, getopts/3, getstat/3, peername/2, sockname/2, port/2]).
+-export([send/3, listen/3, accept/3, socket/5, connect/4, upgrade/3,
+ setopts/3, getopts/3, getstat/3, peername/2, sockname/2, port/2]).
+-export([split_options/1, get_socket_opts/3]).
-export([emulated_options/0, internal_inet_values/0, default_inet_values/0,
- init/1, start_link/3, terminate/2, inherit_tracker/3, get_emulated_opts/1,
+ init/1, start_link/3, terminate/2, inherit_tracker/3,
+ emulated_socket_options/2, get_emulated_opts/1,
set_emulated_opts/2, get_all_opts/1, handle_call/3, handle_cast/2,
handle_info/2, code_change/3]).
@@ -39,6 +42,76 @@
%%--------------------------------------------------------------------
%%% Internal API
%%--------------------------------------------------------------------
+send(Transport, Socket, Data) ->
+ Transport:send(Socket, Data).
+
+listen(Transport, Port, #config{transport_info = {Transport, _, _, _},
+ inet_user = Options,
+ ssl = SslOpts, emulated = EmOpts} = Config) ->
+ case Transport:listen(Port, Options ++ internal_inet_values()) of
+ {ok, ListenSocket} ->
+ {ok, Tracker} = inherit_tracker(ListenSocket, EmOpts, SslOpts),
+ {ok, #sslsocket{pid = {ListenSocket, Config#config{emulated = Tracker}}}};
+ Err = {error, _} ->
+ Err
+ end.
+
+accept(ListenSocket, #config{transport_info = {Transport,_,_,_} = CbInfo,
+ connection_cb = ConnectionCb,
+ ssl = SslOpts,
+ emulated = Tracker}, Timeout) ->
+ case Transport:accept(ListenSocket, Timeout) of
+ {ok, Socket} ->
+ {ok, EmOpts} = get_emulated_opts(Tracker),
+ {ok, Port} = tls_socket:port(Transport, Socket),
+ ConnArgs = [server, "localhost", Port, Socket,
+ {SslOpts, emulated_socket_options(EmOpts, #socket_options{}), Tracker}, self(), CbInfo],
+ case tls_connection_sup:start_child(ConnArgs) of
+ {ok, Pid} ->
+ ssl_connection:socket_control(ConnectionCb, Socket, Pid, Transport, Tracker);
+ {error, Reason} ->
+ {error, Reason}
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+upgrade(Socket, #config{transport_info = {Transport,_,_,_}= CbInfo,
+ ssl = SslOptions,
+ emulated = EmOpts, connection_cb = ConnectionCb}, Timeout) ->
+ ok = setopts(Transport, Socket, tls_socket:internal_inet_values()),
+ case peername(Transport, Socket) of
+ {ok, {Address, Port}} ->
+ ssl_connection:connect(ConnectionCb, Address, Port, Socket,
+ {SslOptions,
+ emulated_socket_options(EmOpts, #socket_options{}), undefined},
+ self(), CbInfo, Timeout);
+ {error, Error} ->
+ {error, Error}
+ end.
+
+connect(Address, Port,
+ #config{transport_info = CbInfo, inet_user = UserOpts, ssl = SslOpts,
+ emulated = EmOpts, inet_ssl = SocketOpts, connection_cb = ConnetionCb},
+ Timeout) ->
+ {Transport, _, _, _} = CbInfo,
+ try Transport:connect(Address, Port, SocketOpts, Timeout) of
+ {ok, Socket} ->
+ ssl_connection:connect(ConnetionCb, Address, Port, Socket,
+ {SslOpts,
+ emulated_socket_options(EmOpts, #socket_options{}), undefined},
+ self(), CbInfo, Timeout);
+ {error, Reason} ->
+ {error, Reason}
+ catch
+ exit:{function_clause, _} ->
+ {error, {options, {cb_info, CbInfo}}};
+ exit:badarg ->
+ {error, {options, {socket_options, UserOpts}}};
+ exit:{badarg, _} ->
+ {error, {options, {socket_options, UserOpts}}}
+ end.
+
socket(Pid, Transport, Socket, ConnectionCb, Tracker) ->
#sslsocket{pid = Pid,
%% "The name "fd" is keept for backwards compatibility
@@ -241,3 +314,17 @@ get_emulated_opts(TrackerPid, EmOptNames) ->
lists:map(fun(Name) -> {value, Value} = lists:keysearch(Name, 1, EmOpts),
Value end,
EmOptNames).
+
+emulated_socket_options(InetValues, #socket_options{
+ mode = Mode,
+ header = Header,
+ active = Active,
+ packet = Packet,
+ packet_size = Size}) ->
+ #socket_options{
+ mode = proplists:get_value(mode, InetValues, Mode),
+ header = proplists:get_value(header, InetValues, Header),
+ active = proplists:get_value(active, InetValues, Active),
+ packet = proplists:get_value(packet, InetValues, Packet),
+ packet_size = proplists:get_value(packet_size, InetValues, Size)
+ }.
diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl
index 711db77708..a8fe119bf8 100644
--- a/lib/ssl/src/tls_v1.erl
+++ b/lib/ssl/src/tls_v1.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,11 +29,20 @@
-include("ssl_internal.hrl").
-include("ssl_record.hrl").
--export([master_secret/4, finished/5, certificate_verify/3, mac_hash/7,
+-export([master_secret/4, finished/5, certificate_verify/3, mac_hash/7, hmac_hash/3,
setup_keys/8, suites/1, prf/5,
- ecc_curves/1, oid_to_enum/1, enum_to_oid/1,
+ ecc_curves/1, ecc_curves/2, oid_to_enum/1, enum_to_oid/1,
default_signature_algs/1, signature_algs/2]).
+-type named_curve() :: sect571r1 | sect571k1 | secp521r1 | brainpoolP512r1 |
+ sect409k1 | sect409r1 | brainpoolP384r1 | secp384r1 |
+ sect283k1 | sect283r1 | brainpoolP256r1 | secp256k1 | secp256r1 |
+ sect239k1 | sect233k1 | sect233r1 | secp224k1 | secp224r1 |
+ sect193r1 | sect193r2 | secp192k1 | secp192r1 | sect163k1 |
+ sect163r1 | sect163r2 | secp160k1 | secp160r1 | secp160r2.
+-type curves() :: [named_curve()].
+-export_type([curves/0, named_curve/0]).
+
%%====================================================================
%% Internal application API
%%====================================================================
@@ -195,28 +204,24 @@ suites(Minor) when Minor == 1; Minor == 2 ->
?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
?TLS_RSA_WITH_AES_256_CBC_SHA,
- ?TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
- ?TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
- ?TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
- ?TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
- ?TLS_RSA_WITH_3DES_EDE_CBC_SHA,
-
?TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
?TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
?TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
?TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
- ?TLS_RSA_WITH_AES_128_CBC_SHA
+ ?TLS_RSA_WITH_AES_128_CBC_SHA,
+
+ ?TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_RSA_WITH_3DES_EDE_CBC_SHA
];
suites(3) ->
- [
- ?TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
- ?TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
-
- ?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ [?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
?TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
@@ -225,7 +230,10 @@ suites(3) ->
?TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
+ ?TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+ ?TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
?TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+
?TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
?TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,
?TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
@@ -398,14 +406,21 @@ is_pair(Hash, rsa, Hashs) ->
AtLeastMd5 = Hashs -- [md2,md4],
lists:member(Hash, AtLeastMd5).
-%% list ECC curves in prefered order
-ecc_curves(_Minor) ->
- TLSCurves = [sect571r1,sect571k1,secp521r1,brainpoolP512r1,
- sect409k1,sect409r1,brainpoolP384r1,secp384r1,
- sect283k1,sect283r1,brainpoolP256r1,secp256k1,secp256r1,
- sect239k1,sect233k1,sect233r1,secp224k1,secp224r1,
- sect193r1,sect193r2,secp192k1,secp192r1,sect163k1,
- sect163r1,sect163r2,secp160k1,secp160r1,secp160r2],
+%% list ECC curves in preferred order
+-spec ecc_curves(1..3 | all) -> [named_curve()].
+ecc_curves(all) ->
+ [sect571r1,sect571k1,secp521r1,brainpoolP512r1,
+ sect409k1,sect409r1,brainpoolP384r1,secp384r1,
+ sect283k1,sect283r1,brainpoolP256r1,secp256k1,secp256r1,
+ sect239k1,sect233k1,sect233r1,secp224k1,secp224r1,
+ sect193r1,sect193r2,secp192k1,secp192r1,sect163k1,
+ sect163r1,sect163r2,secp160k1,secp160r1,secp160r2];
+ecc_curves(Minor) ->
+ TLSCurves = ecc_curves(all),
+ ecc_curves(Minor, TLSCurves).
+
+-spec ecc_curves(1..3, [named_curve()]) -> [named_curve()].
+ecc_curves(_Minor, TLSCurves) ->
CryptoCurves = crypto:ec_curves(),
lists:foldr(fun(Curve, Curves) ->
case proplists:get_bool(Curve, CryptoCurves) of
@@ -414,6 +429,7 @@ ecc_curves(_Minor) ->
end
end, [], TLSCurves).
+
%% ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005)
oid_to_enum(?sect163k1) -> 1;
oid_to_enum(?sect163r1) -> 2;
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
index a2eb4ce449..558be6d642 100644
--- a/lib/ssl/test/Makefile
+++ b/lib/ssl/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2016. All Rights Reserved.
+# Copyright Ericsson AB 1999-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -56,7 +56,8 @@ MODULES = \
ssl_upgrade_SUITE\
ssl_sni_SUITE \
make_certs\
- erl_make_certs
+ erl_make_certs\
+ x509_test
ERL_FILES = $(MODULES:%=%.erl)
diff --git a/lib/ssl/test/erl_make_certs.erl b/lib/ssl/test/erl_make_certs.erl
index a6657be995..3ab6222780 100644
--- a/lib/ssl/test/erl_make_certs.erl
+++ b/lib/ssl/test/erl_make_certs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -179,7 +179,7 @@ make_tbs(SubjectKey, Opts) ->
subject(proplists:get_value(subject, Opts),false)
end,
- {#'OTPTBSCertificate'{serialNumber = trunc(random:uniform()*100000000)*10000 + 1,
+ {#'OTPTBSCertificate'{serialNumber = trunc(rand:uniform()*100000000)*10000 + 1,
signature = SignAlgo,
issuer = Issuer,
validity = validity(Opts),
diff --git a/lib/ssl/test/make_certs.erl b/lib/ssl/test/make_certs.erl
index 009bcd81ad..ecbacc1590 100644
--- a/lib/ssl/test/make_certs.erl
+++ b/lib/ssl/test/make_certs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -172,8 +172,8 @@ revoke(Root, CA, User, C) ->
gencrl(Root, CA, C).
gencrl(Root, CA, C) ->
- %% By default, the CRL is valid for 24 hours from now.
- gencrl(Root, CA, C, 24).
+ %% By default, the CRL is valid for a week from now.
+ gencrl(Root, CA, C, 24*7).
gencrl(Root, CA, C, CrlHours) ->
CACnfFile = filename:join([Root, CA, "ca.cnf"]),
@@ -385,6 +385,7 @@ req_cnf(Root, C) ->
"subjectAltName = email:copy\n"].
ca_cnf(Root, C = #config{issuing_distribution_point = true}) ->
+ Hostname = net_adm:localhost(),
["# Purpose: Configuration for CAs.\n"
"\n"
"ROOTDIR = " ++ Root ++ "\n"
@@ -434,7 +435,7 @@ ca_cnf(Root, C = #config{issuing_distribution_point = true}) ->
"keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
"subjectKeyIdentifier = hash\n"
"authorityKeyIdentifier = keyid,issuer:always\n"
- "subjectAltName = email:copy\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
"issuerAltName = issuer:copy\n"
"crlDistributionPoints=@crl_section\n"
@@ -449,7 +450,7 @@ ca_cnf(Root, C = #config{issuing_distribution_point = true}) ->
"keyUsage = digitalSignature\n"
"subjectKeyIdentifier = hash\n"
"authorityKeyIdentifier = keyid,issuer:always\n"
- "subjectAltName = email:copy\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
"issuerAltName = issuer:copy\n"
"\n"
@@ -458,12 +459,13 @@ ca_cnf(Root, C = #config{issuing_distribution_point = true}) ->
"keyUsage = cRLSign, keyCertSign\n"
"subjectKeyIdentifier = hash\n"
"authorityKeyIdentifier = keyid:always,issuer:always\n"
- "subjectAltName = email:copy\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
"issuerAltName = issuer:copy\n"
"crlDistributionPoints=@crl_section\n"
];
ca_cnf(Root, C = #config{issuing_distribution_point = false}) ->
+ Hostname = net_adm:localhost(),
["# Purpose: Configuration for CAs.\n"
"\n"
"ROOTDIR = " ++ Root ++ "\n"
@@ -513,7 +515,7 @@ ca_cnf(Root, C = #config{issuing_distribution_point = false}) ->
"keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
"subjectKeyIdentifier = hash\n"
"authorityKeyIdentifier = keyid,issuer:always\n"
- "subjectAltName = email:copy\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
"issuerAltName = issuer:copy\n"
%"crlDistributionPoints=@crl_section\n"
@@ -528,7 +530,7 @@ ca_cnf(Root, C = #config{issuing_distribution_point = false}) ->
"keyUsage = digitalSignature\n"
"subjectKeyIdentifier = hash\n"
"authorityKeyIdentifier = keyid,issuer:always\n"
- "subjectAltName = email:copy\n"
+ "subjectAltName = DNS.1:" ++ Hostname ++ "\n"
"issuerAltName = issuer:copy\n"
"\n"
diff --git a/lib/ssl/test/ssl.spec b/lib/ssl/test/ssl.spec
index 86e14c033e..0ad94e22bc 100644
--- a/lib/ssl/test/ssl.spec
+++ b/lib/ssl/test/ssl.spec
@@ -1,4 +1,5 @@
{suites,"../ssl_test",all}.
{skip_cases, "../ssl_test",
- ssl_bench_SUITE, [setup_sequential, setup_concurrent, payload_simple],
+ ssl_bench_SUITE, [setup_sequential, setup_concurrent, payload_simple,
+ use_pem_cache, bypass_pem_cache],
"Benchmarks run separately"}.
diff --git a/lib/ssl/test/ssl_ECC_SUITE.erl b/lib/ssl/test/ssl_ECC_SUITE.erl
index b8a03f578d..0fbb0bb79a 100644
--- a/lib/ssl/test/ssl_ECC_SUITE.erl
+++ b/lib/ssl/test/ssl_ECC_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -44,41 +44,101 @@ groups() ->
{'tlsv1.2', [], all_versions_groups()},
{'tlsv1.1', [], all_versions_groups()},
{'tlsv1', [], all_versions_groups()},
- {'erlang_server', [], key_cert_combinations()},
- {'erlang_client', [], key_cert_combinations()},
- {'erlang', [], key_cert_combinations() ++ misc()}
+ {'erlang_server', [], openssl_key_cert_combinations()},
+ %%{'erlang_client', [], openssl_key_cert_combinations()},
+ {'erlang', [], key_cert_combinations() ++ misc()
+ ++ ecc_negotiation()}
].
all_versions_groups ()->
[{group, 'erlang_server'},
- {group, 'erlang_client'},
+ %%{group, 'erlang_client'},
{group, 'erlang'}
].
+
+openssl_key_cert_combinations() ->
+ ECDH_RSA = case ssl_test_lib:openssl_filter("ECDH-RSA") of
+ [] ->
+ [];
+ _ ->
+ server_ecdh_rsa()
+ end,
+
+ ECDHE_RSA = case ssl_test_lib:openssl_filter("ECDHE-RSA") of
+ [] ->
+ [];
+ _ ->
+ server_ecdhe_rsa()
+ end,
+ ECDH_ECDSA = case ssl_test_lib:openssl_filter("ECDH-ECDSA") of
+ [] ->
+ [];
+ _ ->
+ server_ecdhe_ecdsa()
+ end,
+
+ ECDHE_ECDSA = case ssl_test_lib:openssl_filter("ECDHE-ECDSA") of
+ [] ->
+ [];
+ _ ->
+ server_ecdhe_ecdsa()
+ end,
+ ECDH_RSA ++ ECDHE_RSA ++ ECDH_ECDSA ++ ECDHE_ECDSA.
+
key_cert_combinations() ->
- [client_ecdh_server_ecdh,
- client_rsa_server_ecdh,
- client_ecdh_server_rsa,
- client_rsa_server_rsa,
- client_ecdsa_server_ecdsa,
- client_ecdsa_server_rsa,
- client_rsa_server_ecdsa
- ].
+ server_ecdh_rsa() ++
+ server_ecdhe_rsa() ++
+ server_ecdh_ecdsa() ++
+ server_ecdhe_ecdsa().
+
+server_ecdh_rsa() ->
+ [client_ecdh_rsa_server_ecdh_rsa,
+ client_ecdhe_rsa_server_ecdh_rsa,
+ client_ecdhe_ecdsa_server_ecdh_rsa].
+
+server_ecdhe_rsa() ->
+ [client_ecdh_rsa_server_ecdhe_rsa,
+ client_ecdhe_rsa_server_ecdhe_rsa,
+ client_ecdhe_ecdsa_server_ecdhe_rsa].
+
+server_ecdh_ecdsa() ->
+ [client_ecdh_ecdsa_server_ecdh_ecdsa,
+ client_ecdhe_rsa_server_ecdh_ecdsa,
+ client_ecdhe_ecdsa_server_ecdh_ecdsa].
+
+server_ecdhe_ecdsa() ->
+ [client_ecdh_rsa_server_ecdhe_ecdsa,
+ client_ecdh_ecdsa_server_ecdhe_ecdsa,
+ client_ecdhe_ecdsa_server_ecdhe_ecdsa].
+
misc()->
[client_ecdsa_server_ecdsa_with_raw_key].
+ecc_negotiation() ->
+ [ecc_default_order,
+ ecc_default_order_custom_curves,
+ ecc_client_order,
+ ecc_client_order_custom_curves,
+ ecc_unknown_curve,
+ client_ecdh_rsa_server_ecdhe_ecdsa_server_custom,
+ client_ecdh_rsa_server_ecdhe_rsa_server_custom,
+ client_ecdhe_rsa_server_ecdhe_ecdsa_server_custom,
+ client_ecdhe_rsa_server_ecdhe_rsa_server_custom,
+ client_ecdhe_rsa_server_ecdh_rsa_server_custom,
+ client_ecdhe_ecdsa_server_ecdhe_ecdsa_server_custom,
+ client_ecdhe_ecdsa_server_ecdhe_rsa_server_custom,
+ client_ecdhe_ecdsa_server_ecdhe_ecdsa_client_custom,
+ client_ecdhe_rsa_server_ecdhe_ecdsa_client_custom
+ ].
+
%%--------------------------------------------------------------------
init_per_suite(Config0) ->
end_per_suite(Config0),
try crypto:start() of
ok ->
- %% make rsa certs using oppenssl
- {ok, _} = make_certs:all(proplists:get_value(data_dir, Config0),
- proplists:get_value(priv_dir, Config0)),
- Config1 = ssl_test_lib:make_ecdsa_cert(Config0),
- Config2 = ssl_test_lib:make_ecdh_rsa_cert(Config1),
- ssl_test_lib:cert_options(Config2)
+ Config0
catch _:_ ->
{skip, "Crypto did not start"}
end.
@@ -145,7 +205,7 @@ init_per_testcase(TestCase, Config) ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
ct:log("Ciphers: ~p~n ", [ ssl:cipher_suites()]),
end_per_testcase(TestCase, Config),
- ssl:start(),
+ ssl_test_lib:clean_start(),
ct:timetrap({seconds, 15}),
Config.
@@ -157,150 +217,314 @@ end_per_testcase(_TestCase, Config) ->
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-client_ecdh_server_ecdh(Config) when is_list(Config) ->
- COpts = proplists:get_value(client_ecdh_rsa_opts, Config),
- SOpts = proplists:get_value(server_ecdh_rsa_verify_opts, Config),
- basic_test(COpts, SOpts, Config).
-
-client_ecdh_server_rsa(Config) when is_list(Config) ->
- COpts = proplists:get_value(client_ecdh_rsa_opts, Config),
- SOpts = proplists:get_value(server_ecdh_rsa_verify_opts, Config),
- basic_test(COpts, SOpts, Config).
-
-client_rsa_server_ecdh(Config) when is_list(Config) ->
- COpts = proplists:get_value(client_ecdh_rsa_opts, Config),
- SOpts = proplists:get_value(server_ecdh_rsa_verify_opts, Config),
- basic_test(COpts, SOpts, Config).
+%% Test diffrent certificate chain types, note that it is the servers
+%% chain that affect what cipher suit that will be choosen
+
+%% ECDH_RSA
+client_ecdh_rsa_server_ecdh_rsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],
+ ecdh_rsa, ecdh_rsa, Config),
+ basic_test(COpts, SOpts, [{check_keyex, ecdh_rsa} | proplists:delete(check_keyex, Config)]).
+client_ecdhe_rsa_server_ecdh_rsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_rsa, ecdh_rsa, Config),
+ basic_test(COpts, SOpts, [{check_keyex, ecdh_rsa} | proplists:delete(check_keyex, Config)]).
+client_ecdhe_ecdsa_server_ecdh_rsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdh_rsa, Config),
+ basic_test(COpts, SOpts, [{check_keyex, ecdh_rsa} | proplists:delete(check_keyex, Config)]).
+
+%% ECDHE_RSA
+client_ecdh_rsa_server_ecdhe_rsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdh_rsa, ecdhe_rsa, Config),
+ basic_test(COpts, SOpts, [{check_keyex, ecdhe_rsa} | proplists:delete(check_keyex, Config)]).
+client_ecdhe_rsa_server_ecdhe_rsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_rsa, ecdhe_rsa, Config),
+ basic_test(COpts, SOpts, [{check_keyex, ecdhe_rsa} | proplists:delete(check_keyex, Config)]).
+client_ecdhe_ecdsa_server_ecdhe_rsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdh_ecdsa, ecdhe_rsa, Config),
+ basic_test(COpts, SOpts, [{check_keyex, ecdhe_rsa} | proplists:delete(check_keyex, Config)]).
-client_rsa_server_rsa(Config) when is_list(Config) ->
- COpts = proplists:get_value(client_verification_opts, Config),
- SOpts = proplists:get_value(server_verification_opts, Config),
- basic_test(COpts, SOpts, Config).
-
-client_ecdsa_server_ecdsa(Config) when is_list(Config) ->
- COpts = proplists:get_value(client_ecdsa_opts, Config),
- SOpts = proplists:get_value(server_ecdsa_verify_opts, Config),
- basic_test(COpts, SOpts, Config).
-
-client_ecdsa_server_rsa(Config) when is_list(Config) ->
- COpts = proplists:get_value(client_ecdsa_opts, Config),
- SOpts = proplists:get_value(server_ecdsa_verify_opts, Config),
- basic_test(COpts, SOpts, Config).
-
-client_rsa_server_ecdsa(Config) when is_list(Config) ->
- COpts = proplists:get_value(client_ecdsa_opts, Config),
- SOpts = proplists:get_value(server_ecdsa_verify_opts, Config),
- basic_test(COpts, SOpts, Config).
+%% ECDH_ECDSA
+client_ecdh_ecdsa_server_ecdh_ecdsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_peer_opts,
+ [{extensions, [{key_usage, [keyEncipherment]
+ }]}]}],
+ ecdh_ecdsa, ecdh_ecdsa, Config),
+ basic_test(COpts, SOpts,
+ [{check_keyex, ecdh_ecdsa} | proplists:delete(check_keyex, Config)]).
+client_ecdhe_rsa_server_ecdh_ecdsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_peer_opts,
+ [{extensions, [{key_usage, [keyEncipherment]
+ }]}]}],
+ ecdhe_rsa, ecdh_ecdsa, Config),
+ basic_test(COpts, SOpts, [{check_keyex, ecdh_ecdsa} | proplists:delete(check_keyex, Config)]).
+
+client_ecdhe_ecdsa_server_ecdh_ecdsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_peer_opts,
+ [{extensions, [{key_usage, [keyEncipherment]
+ }]}]}],
+ ecdhe_ecdsa, ecdh_ecdsa, Config),
+ basic_test(COpts, SOpts,
+ [{check_keyex, ecdh_ecdsa} | proplists:delete(check_keyex, Config)]).
+
+%% ECDHE_ECDSA
+client_ecdh_rsa_server_ecdhe_ecdsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdh_rsa, ecdhe_ecdsa, Config),
+ basic_test(COpts, SOpts, [{check_keyex, ecdhe_ecdsa} | proplists:delete(check_keyex, Config)]).
+client_ecdh_ecdsa_server_ecdhe_ecdsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdh_ecdsa, ecdhe_ecdsa, Config),
+ basic_test(COpts, SOpts, [{check_keyex, ecdhe_ecdsa} | proplists:delete(check_keyex, Config)]).
+client_ecdhe_ecdsa_server_ecdhe_ecdsa(Config) when is_list(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ basic_test(COpts, SOpts, [{check_keyex, ecdhe_ecdsa} | proplists:delete(check_keyex, Config)]).
client_ecdsa_server_ecdsa_with_raw_key(Config) when is_list(Config) ->
- COpts = proplists:get_value(client_ecdsa_opts, Config),
- SOpts = proplists:get_value(server_ecdsa_verify_opts, Config),
- ServerCert = proplists:get_value(certfile, SOpts),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_ecdsa, ecdhe_ecdsa, Config),
ServerKeyFile = proplists:get_value(keyfile, SOpts),
{ok, PemBin} = file:read_file(ServerKeyFile),
PemEntries = public_key:pem_decode(PemBin),
{'ECPrivateKey', Key, not_encrypted} = proplists:lookup('ECPrivateKey', PemEntries),
ServerKey = {'ECPrivateKey', Key},
- ServerCA = proplists:get_value(cacertfile, SOpts),
- ClientCert = proplists:get_value(certfile, COpts),
- ClientKey = proplists:get_value(keyfile, COpts),
- ClientCA = proplists:get_value(cacertfile, COpts),
SType = proplists:get_value(server_type, Config),
CType = proplists:get_value(client_type, Config),
{Server, Port} = start_server_with_raw_key(SType,
- ClientCA, ServerCA,
- ServerCert,
- ServerKey,
- Config),
- Client = start_client(CType, Port, ServerCA, ClientCA,
- ClientCert,
- ClientKey, Config),
+ [{key, ServerKey} | proplists:delete(keyfile, SOpts)],
+ Config),
+ Client = start_client(CType, Port, COpts, Config),
check_result(Server, SType, Client, CType),
close(Server, Client).
+ecc_default_order(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ ECCOpts = [],
+ case supported_eccs([{eccs, [sect571r1]}]) of
+ true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+ecc_default_order_custom_curves(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ ECCOpts = [{eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+ecc_client_order(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ ECCOpts = [{honor_ecc_order, false}],
+ case supported_eccs([{eccs, [sect571r1]}]) of
+ true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+ecc_client_order_custom_curves(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ ECCOpts = [{honor_ecc_order, false}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+ecc_unknown_curve(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ ECCOpts = [{eccs, ['123_fake_curve']}],
+ ecc_test_error(COpts, SOpts, [], ECCOpts, Config).
+
+client_ecdh_rsa_server_ecdhe_ecdsa_server_custom(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdh_rsa, ecdhe_ecdsa, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_ecdh_rsa_server_ecdhe_rsa_server_custom(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdh_rsa, ecdhe_rsa, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_ecdhe_rsa_server_ecdhe_ecdsa_server_custom(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_rsa, ecdhe_ecdsa, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_ecdhe_rsa_server_ecdhe_rsa_server_custom(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_rsa, ecdhe_rsa, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+client_ecdhe_rsa_server_ecdh_rsa_server_custom(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_peer_opts,
+ [{extensions, [{key_usage, [keyEncipherment]
+ }]}]}], ecdhe_rsa, ecdh_rsa, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_ecdhe_ecdsa_server_ecdhe_ecdsa_server_custom(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_ecdhe_ecdsa_server_ecdhe_rsa_server_custom(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_rsa, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_ecdhe_ecdsa_server_ecdhe_ecdsa_client_custom(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ ECCOpts = [{eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(secp256r1, COpts, SOpts, ECCOpts, [], Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_ecdhe_rsa_server_ecdhe_ecdsa_client_custom(Config) ->
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_rsa, ecdhe_ecdsa, Config),
+ ECCOpts = [{eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(secp256r1, COpts, SOpts, ECCOpts, [], Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
basic_test(COpts, SOpts, Config) ->
- basic_test(proplists:get_value(certfile, COpts),
- proplists:get_value(keyfile, COpts),
- proplists:get_value(cacertfile, COpts),
- proplists:get_value(certfile, SOpts),
- proplists:get_value(keyfile, SOpts),
- proplists:get_value(cacertfile, SOpts),
- Config).
-
-basic_test(ClientCert, ClientKey, ClientCA, ServerCert, ServerKey, ServerCA, Config) ->
SType = proplists:get_value(server_type, Config),
CType = proplists:get_value(client_type, Config),
- {Server, Port} = start_server(SType,
- ClientCA, ServerCA,
- ServerCert,
- ServerKey,
- Config),
- Client = start_client(CType, Port, ServerCA, ClientCA,
- ClientCert,
- ClientKey, Config),
+ {Server, Port} = start_server(SType, SOpts, Config),
+ Client = start_client(CType, Port, COpts, Config),
check_result(Server, SType, Client, CType),
close(Server, Client).
-start_client(openssl, Port, CA, OwnCa, Cert, Key, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- NewCA = new_ca(filename:join(PrivDir, "new_ca.pem"), CA, OwnCa),
+
+ecc_test(Expect, COpts, SOpts, CECCOpts, SECCOpts, Config) ->
+ {Server, Port} = start_server_ecc(erlang, SOpts, Expect, SECCOpts, Config),
+ Client = start_client_ecc(erlang, Port, COpts, Expect, CECCOpts, Config),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ close(Server, Client).
+
+ecc_test_error(COpts, SOpts, CECCOpts, SECCOpts, Config) ->
+ {Server, Port} = start_server_ecc_error(erlang, SOpts, SECCOpts, Config),
+ Client = start_client_ecc_error(erlang, Port, COpts, CECCOpts, Config),
+ Error = {error, {tls_alert, "insufficient security"}},
+ ssl_test_lib:check_result(Server, Error, Client, Error).
+
+
+start_client(openssl, Port, ClientOpts, _Config) ->
+ Cert = proplists:get_value(certfile, ClientOpts),
+ Key = proplists:get_value(keyfile, ClientOpts),
+ CA = proplists:get_value(cacertfile, ClientOpts),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
Exe = "openssl",
Args = ["s_client", "-verify", "2", "-port", integer_to_list(Port),
ssl_test_lib:version_flag(Version),
- "-cert", Cert, "-CAfile", NewCA,
+ "-cert", Cert, "-CAfile", CA,
"-key", Key, "-host","localhost", "-msg", "-debug"],
OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, "Hello world"),
OpenSslPort;
-start_client(erlang, Port, CA, _, Cert, Key, Config) ->
+
+start_client(erlang, Port, ClientOpts, Config) ->
{ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+ KeyEx = proplists:get_value(check_keyex, Config, false),
ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
- {mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, [{verify, verify_peer},
- {cacertfile, CA},
- {certfile, Cert}, {keyfile, Key}]}]).
+ {mfa, {ssl_test_lib, check_key_exchange_send_active, [KeyEx]}},
+ {options, [{verify, verify_peer} | ClientOpts]}]).
-start_server(openssl, CA, OwnCa, Cert, Key, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- NewCA = new_ca(filename:join(PrivDir, "new_ca.pem"), CA, OwnCa),
+start_client_ecc(erlang, Port, ClientOpts, Expect, ECCOpts, Config) ->
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, check_ecc, [client, Expect]}},
+ {options,
+ ECCOpts ++
+ [{verify, verify_peer} | ClientOpts]}]).
+
+start_client_ecc_error(erlang, Port, ClientOpts, ECCOpts, Config) ->
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options,
+ ECCOpts ++
+ [{verify, verify_peer} | ClientOpts]}]).
+
+
+start_server(openssl, ServerOpts, _Config) ->
+ Cert = proplists:get_value(certfile, ServerOpts),
+ Key = proplists:get_value(keyfile, ServerOpts),
+ CA = proplists:get_value(cacertfile, ServerOpts),
Port = ssl_test_lib:inet_port(node()),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
Exe = "openssl",
Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-verify", "2", "-cert", Cert, "-CAfile", NewCA,
+ "-verify", "2", "-cert", Cert, "-CAfile", CA,
"-key", Key, "-msg", "-debug"],
OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
true = port_command(OpenSslPort, "Hello world"),
{OpenSslPort, Port};
-start_server(erlang, CA, _, Cert, Key, Config) ->
+start_server(erlang, ServerOpts, Config) ->
{_, ServerNode, _} = ssl_test_lib:run_where(Config),
+ KeyEx = proplists:get_value(check_keyex, Config, false),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- send_recv_result_active,
- []}},
- {options,
- [{verify, verify_peer}, {cacertfile, CA},
- {certfile, Cert}, {keyfile, Key}]}]),
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ check_key_exchange_send_active,
+ [KeyEx]}},
+ {options, [{verify, verify_peer} | ServerOpts]}]),
{Server, ssl_test_lib:inet_port(Server)}.
-start_server_with_raw_key(erlang, CA, _, Cert, Key, Config) ->
+
+start_server_with_raw_key(erlang, ServerOpts, Config) ->
{_, ServerNode, _} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- send_recv_result_active,
- []}},
- {options,
- [{verify, verify_peer}, {cacertfile, CA},
- {certfile, Cert}, {key, Key}]}]),
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ send_recv_result_active,
+ []}},
+ {options,
+ [{verify, verify_peer} | ServerOpts]}]),
+ {Server, ssl_test_lib:inet_port(Server)}.
+
+start_server_ecc(erlang, ServerOpts, Expect, ECCOpts, Config) ->
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, check_ecc, [server, Expect]}},
+ {options,
+ ECCOpts ++
+ [{verify, verify_peer} | ServerOpts]}]),
+ {Server, ssl_test_lib:inet_port(Server)}.
+
+start_server_ecc_error(erlang, ServerOpts, ECCOpts, Config) ->
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options,
+ ECCOpts ++
+ [{verify, verify_peer} | ServerOpts]}]),
{Server, ssl_test_lib:inet_port(Server)}.
check_result(Server, erlang, Client, erlang) ->
@@ -336,19 +560,16 @@ close(Client, Server) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-%% Work around OpenSSL bug, apparently the same bug as we had fixed in
-%% 11629690ba61f8e0c93ef9b2b6102fd279825977
-new_ca(FileName, CA, OwnCa) ->
- {ok, P1} = file:read_file(CA),
- E1 = public_key:pem_decode(P1),
- {ok, P2} = file:read_file(OwnCa),
- E2 = public_key:pem_decode(P2),
- case os:cmd("openssl version") of
- "OpenSSL 1.0.1p-freebsd" ++ _ ->
- Pem = public_key:pem_encode(E1 ++E2),
- file:write_file(FileName, Pem);
- _ ->
- Pem = public_key:pem_encode(E2 ++E1),
- file:write_file(FileName, Pem)
- end,
- FileName.
+supported_eccs(Opts) ->
+ ToCheck = proplists:get_value(eccs, Opts, []),
+ Supported = ssl:eccs(),
+ lists:all(fun(Curve) -> lists:member(Curve, Supported) end, ToCheck).
+
+check_ecc(SSL, Role, Expect) ->
+ {ok, Data} = ssl:connection_information(SSL),
+ case lists:keyfind(ecc, 1, Data) of
+ {ecc, {named_curve, Expect}} -> ok;
+ false when Expect =:= undefined -> ok;
+ Other -> {error, Role, Expect, Other}
+ end.
+
diff --git a/lib/ssl/test/ssl_alpn_handshake_SUITE.erl b/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
index da181faf64..158b3524ac 100644
--- a/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_alpn_handshake_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -71,7 +71,7 @@ init_per_suite(Config) ->
catch crypto:stop(),
try crypto:start() of
ok ->
- ssl:start(),
+ ssl_test_lib:clean_start(),
{ok, _} = make_certs:all(proplists:get_value(data_dir, Config),
proplists:get_value(priv_dir, Config)),
ssl_test_lib:cert_options(Config)
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index efa5faa218..407152aa75 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -40,6 +40,7 @@
-define(SLEEP, 500).
-define(RENEGOTIATION_DISABLE_TIME, 12000).
-define(CLEAN_SESSION_DB, 60000).
+-define(SEC_RENEGOTIATION_TIMEOUT, 30).
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
@@ -51,8 +52,9 @@ all() ->
{group, options},
{group, options_tls},
{group, session},
- %%{group, 'dtlsv1.2'},
- %%{group, 'dtlsv1'},
+ {group, 'dtlsv1.2'},
+ %% {group, 'dtlsv1'}, Breaks dtls in cert_verify_SUITE enable later when
+ %% problem is identified and fixed
{group, 'tlsv1.2'},
{group, 'tlsv1.1'},
{group, 'tlsv1'},
@@ -64,14 +66,15 @@ groups() ->
{basic_tls, [], basic_tests_tls()},
{options, [], options_tests()},
{options_tls, [], options_tests_tls()},
- %%{'dtlsv1.2', [], all_versions_groups()},
- %%{'dtlsv1', [], all_versions_groups()},
+ {'dtlsv1.2', [], all_versions_groups()},
+ {'dtlsv1', [], all_versions_groups()},
{'tlsv1.2', [], all_versions_groups() ++ tls_versions_groups() ++ [conf_signature_algs, no_common_signature_algs]},
{'tlsv1.1', [], all_versions_groups() ++ tls_versions_groups()},
{'tlsv1', [], all_versions_groups() ++ tls_versions_groups() ++ rizzo_tests()},
{'sslv3', [], all_versions_groups() ++ tls_versions_groups() ++ rizzo_tests() ++ [tls_ciphersuite_vs_version]},
{api,[], api_tests()},
{api_tls,[], api_tests_tls()},
+ {tls_ciphers,[], tls_cipher_tests()},
{session, [], session_tests()},
{renegotiate, [], renegotiate_tests()},
{ciphers, [], cipher_tests()},
@@ -81,12 +84,13 @@ groups() ->
].
tls_versions_groups ()->
- [{group, api_tls},
+ [{group, renegotiate}, %% Should be in all_versions_groups not fixed for DTLS yet
+ {group, api_tls},
+ {group, tls_ciphers},
{group, error_handling_tests_tls}].
all_versions_groups ()->
[{group, api},
- {group, renegotiate},
{group, ciphers},
{group, ciphers_ec},
{group, error_handling_tests}].
@@ -115,7 +119,6 @@ options_tests() ->
[der_input,
ssl_options_not_proplist,
raw_ssl_option,
- socket_options,
invalid_inet_get_option,
invalid_inet_get_option_not_list,
invalid_inet_get_option_improper_list,
@@ -134,7 +137,8 @@ options_tests() ->
honor_server_cipher_order,
honor_client_cipher_order,
unordered_protocol_versions_server,
- unordered_protocol_versions_client
+ unordered_protocol_versions_client,
+ max_handshake_size
].
options_tests_tls() ->
@@ -143,12 +147,12 @@ options_tests_tls() ->
api_tests() ->
[connection_info,
+ secret_connection_info,
connection_information,
- peername,
peercert,
peercert_with_client_cert,
- sockname,
versions,
+ eccs,
controlling_process,
getstat,
close_with_timeout,
@@ -158,8 +162,8 @@ api_tests() ->
ssl_recv_timeout,
server_name_indication_option,
accept_pool,
- new_options_in_accept,
- prf
+ prf,
+ socket_options
].
api_tests_tls() ->
@@ -171,7 +175,11 @@ api_tests_tls() ->
tls_shutdown,
tls_shutdown_write,
tls_shutdown_both,
- tls_shutdown_error
+ tls_shutdown_error,
+ peername,
+ sockname,
+ tls_socket_options,
+ new_options_in_accept
].
session_tests() ->
@@ -193,6 +201,11 @@ renegotiate_tests() ->
renegotiate_dos_mitigate_passive,
renegotiate_dos_mitigate_absolute].
+tls_cipher_tests() ->
+ [rc4_rsa_cipher_suites,
+ rc4_ecdh_rsa_cipher_suites,
+ rc4_ecdsa_cipher_suites].
+
cipher_tests() ->
[cipher_suites,
cipher_suites_mix,
@@ -208,9 +221,6 @@ cipher_tests() ->
srp_cipher_suites,
srp_anon_cipher_suites,
srp_dsa_cipher_suites,
- rc4_rsa_cipher_suites,
- rc4_ecdh_rsa_cipher_suites,
- rc4_ecdsa_cipher_suites,
des_rsa_cipher_suites,
des_ecdh_rsa_cipher_suites,
default_reject_anonymous].
@@ -222,15 +232,16 @@ cipher_tests_ec() ->
ciphers_ecdh_rsa_signed_certs_openssl_names].
error_handling_tests()->
- [controller_dies,
- close_transport_accept,
+ [close_transport_accept,
recv_active,
recv_active_once,
recv_error_handling
].
error_handling_tests_tls()->
- [tls_client_closes_socket,
+ [controller_dies,
+ tls_client_closes_socket,
+ tls_closed_in_active_once,
tls_tcp_error_propagation_in_active_mode,
tls_tcp_connect,
tls_tcp_connect_big,
@@ -249,7 +260,7 @@ init_per_suite(Config0) ->
catch crypto:stop(),
try crypto:start() of
ok ->
- ssl:start(),
+ ssl_test_lib:clean_start(),
%% make rsa certs using oppenssl
{ok, _} = make_certs:all(proplists:get_value(data_dir, Config0),
proplists:get_value(priv_dir, Config0)),
@@ -306,6 +317,7 @@ init_per_testcase(protocol_versions, Config) ->
init_per_testcase(reuse_session_expired, Config) ->
ssl:stop(),
application:load(ssl),
+ ssl_test_lib:clean_env(),
application:set_env(ssl, session_lifetime, ?EXPIRE),
application:set_env(ssl, session_delay_cleanup_time, 500),
ssl:start(),
@@ -315,6 +327,7 @@ init_per_testcase(reuse_session_expired, Config) ->
init_per_testcase(empty_protocol_versions, Config) ->
ssl:stop(),
application:load(ssl),
+ ssl_test_lib:clean_env(),
application:set_env(ssl, protocol_version, []),
ssl:start(),
ct:timetrap({seconds, 5}),
@@ -340,7 +353,7 @@ init_per_testcase(TestCase, Config) when TestCase == client_renegotiate;
TestCase == renegotiate_dos_mitigate_passive;
TestCase == renegotiate_dos_mitigate_absolute ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
- ct:timetrap({seconds, 30}),
+ ct:timetrap({seconds, ?SEC_RENEGOTIATION_TIMEOUT + 5}),
Config;
init_per_testcase(TestCase, Config) when TestCase == psk_cipher_suites;
@@ -350,12 +363,27 @@ init_per_testcase(TestCase, Config) when TestCase == psk_cipher_suites;
TestCase == ciphers_dsa_signed_certs;
TestCase == ciphers_dsa_signed_certs_openssl_names;
TestCase == anonymous_cipher_suites;
+ TestCase == ciphers_ecdsa_signed_certs;
+ TestCase == ciphers_ecdsa_signed_certs_openssl_names;
+ TestCase == anonymous_cipher_suites;
+ TestCase == psk_anon_cipher_suites;
+ TestCase == psk_anon_with_hint_cipher_suites;
TestCase == versions_option,
TestCase == tls_tcp_connect_big ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
ct:timetrap({seconds, 60}),
Config;
+init_per_testcase(version_option, Config) ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 10}),
+ Config;
+
+init_per_testcase(reuse_session, Config) ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 10}),
+ Config;
+
init_per_testcase(rizzo, Config) ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
ct:timetrap({seconds, 40}),
@@ -404,12 +432,18 @@ init_per_testcase(prf, Config) ->
init_per_testcase(TestCase, Config) when TestCase == tls_ssl_accept_timeout;
TestCase == tls_client_closes_socket;
+ TestCase == tls_closed_in_active_once;
TestCase == tls_downgrade ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
ct:timetrap({seconds, 15}),
Config;
-init_per_testcase(clear_pem_cache, Config) ->
+init_per_testcase(TestCase, Config) when TestCase == clear_pem_cache;
+ TestCase == der_input;
+ TestCase == defaults ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ %% White box test need clean start
+ ssl:stop(),
+ ssl:start(),
ct:timetrap({seconds, 20}),
Config;
init_per_testcase(raw_ssl_option, Config) ->
@@ -430,7 +464,18 @@ init_per_testcase(accept_pool, Config) ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
Config
end;
-
+init_per_testcase(controller_dies, Config) ->
+ ct:timetrap({seconds, 10}),
+ Config;
+init_per_testcase(eccs, Config) ->
+ case ssl:eccs() of
+ [] ->
+ {skip, "named curves not supported"};
+ [_|_] ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 5}),
+ Config
+ end;
init_per_testcase(_TestCase, Config) ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
ct:timetrap({seconds, 5}),
@@ -441,6 +486,11 @@ end_per_testcase(reuse_session_expired, Config) ->
application:unset_env(ssl, session_delay_cleanup_time),
end_per_testcase(default_action, Config);
+end_per_testcase(Case, Config) when Case == protocol_versions;
+ Case == empty_protocol_versions->
+ application:unset_env(ssl, protocol_versions),
+ end_per_testcase(default_action, Config);
+
end_per_testcase(_TestCase, Config) ->
Config.
@@ -565,10 +615,10 @@ prf(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
connection_info() ->
- [{doc,"Test the API function ssl:connection_information/1"}].
+ [{doc,"Test the API function ssl:connection_information/2"}].
connection_info(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
@@ -599,6 +649,38 @@ connection_info(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
+secret_connection_info() ->
+ [{doc,"Test the API function ssl:connection_information/2"}].
+secret_connection_info(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(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, secret_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, secret_connection_info_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ Version = ssl_test_lib:protocol_version(Config),
+
+ ssl_test_lib:check_result(Server, true, Client, true),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+
connection_information() ->
[{doc,"Test the API function ssl:connection_information/1"}].
connection_information(Config) when is_list(Config) ->
@@ -801,8 +883,7 @@ controller_dies(Config) when is_list(Config) ->
Server ! listen,
Tester = self(),
Connect = fun(Pid) ->
- {ok, Socket} = ssl:connect(Hostname, Port,
- [{reuseaddr,true},{ssl_imp,new}]),
+ {ok, Socket} = ssl:connect(Hostname, Port, ClientOpts),
%% Make sure server finishes and verification
%% and is in coonection state before
%% killing client
@@ -883,6 +964,48 @@ tls_client_closes_socket(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, {error,closed}).
%%--------------------------------------------------------------------
+tls_closed_in_active_once() ->
+ [{doc, "Test that ssl_closed is delivered in active once with non-empty buffer, check ERL-420."}].
+
+tls_closed_in_active_once(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ {_ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+ Port = ssl_test_lib:inet_port(node()),
+ Server = fun() ->
+ {ok, Listen} = gen_tcp:listen(Port, TcpOpts),
+ {ok, TcpServerSocket} = gen_tcp:accept(Listen),
+ {ok, ServerSocket} = ssl:ssl_accept(TcpServerSocket, ServerOpts),
+ lists:foreach(
+ fun(_) ->
+ ssl:send(ServerSocket, "some random message\r\n")
+ end, lists:seq(1, 20)),
+ %% Close TCP instead of SSL socket to trigger the bug:
+ gen_tcp:close(TcpServerSocket),
+ gen_tcp:close(Listen)
+ end,
+ spawn_link(Server),
+ {ok, Socket} = ssl:connect(Hostname, Port, [{active, false} | ClientOpts]),
+ Result = tls_closed_in_active_once_loop(Socket),
+ ssl:close(Socket),
+ case Result of
+ ok -> ok;
+ _ -> ct:fail(Result)
+ end.
+
+tls_closed_in_active_once_loop(Socket) ->
+ ssl:setopts(Socket, [{active, once}]),
+ receive
+ {ssl, Socket, _} ->
+ tls_closed_in_active_once_loop(Socket);
+ {ssl_closed, Socket} ->
+ ok
+ after 5000 ->
+ no_ssl_closed_received
+ end.
+
+%%--------------------------------------------------------------------
connect_dist() ->
[{doc,"Test a simple connect as is used by distribution"}].
@@ -919,9 +1042,9 @@ clear_pem_cache(Config) when is_list(Config) ->
{status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
[_, _,_, _, Prop] = StatusInfo,
State = ssl_test_lib:state(Prop),
- [_,FilRefDb |_] = element(6, State),
+ [_,{FilRefDb, _} |_] = element(6, State),
{Server, Client} = basic_verify_test_no_close(Config),
- CountReferencedFiles = fun({_,-1}, Acc) ->
+ CountReferencedFiles = fun({_, -1}, Acc) ->
Acc;
({_, N}, Acc) ->
N + Acc
@@ -1144,8 +1267,8 @@ cipher_suites_mix() ->
cipher_suites_mix(Config) when is_list(Config) ->
CipherSuites = [{ecdh_rsa,aes_128_cbc,sha256,sha256}, {rsa,aes_128_cbc,sha}],
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -1164,10 +1287,10 @@ cipher_suites_mix(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
-socket_options() ->
+tls_socket_options() ->
[{doc,"Test API function getopts/2 and setopts/2"}].
-socket_options(Config) when is_list(Config) ->
+tls_socket_options(Config) when is_list(Config) ->
ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -1182,14 +1305,14 @@ socket_options(Config) when is_list(Config) ->
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, socket_options_result,
+ {mfa, {?MODULE, tls_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,
+ {mfa, {?MODULE, tls_socket_options_result,
[Options, Values, NewOptions, NewValues]}},
{options, ClientOpts}]),
@@ -1204,7 +1327,7 @@ socket_options(Config) when is_list(Config) ->
{ok,[{recbuf, _}]} = ssl:getopts(Listen, [recbuf]),
ssl:close(Listen).
-socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
+tls_socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
%% Test get/set emulated opts
{ok, DefaultValues} = ssl:getopts(Socket, Options),
ssl:setopts(Socket, NewValues),
@@ -1219,6 +1342,59 @@ socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
%%--------------------------------------------------------------------
+socket_options() ->
+ [{doc,"Test API function getopts/2 and setopts/2"}].
+
+socket_options(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Values = [{mode, list}, {active, true}],
+ %% Shall be the reverse order of Values!
+ Options = [active, 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),
+
+ {ok, Listen} = ssl:listen(0, ServerOpts),
+ {ok,[{mode,list}]} = ssl:getopts(Listen, [mode]),
+ ok = ssl:setopts(Listen, [{mode, binary}]),
+ {ok,[{mode, binary}]} = ssl:getopts(Listen, [mode]),
+ {ok,[{recbuf, _}]} = ssl:getopts(Listen, [recbuf]),
+ ssl:close(Listen).
+
+
+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,[{reuseaddr, _}]} = ssl:getopts(Socket, [reuseaddr]),
+ {ok, All} = ssl:getopts(Socket, []),
+ ct:log("All opts ~p~n", [All]),
+ ok.
+
+
+%%--------------------------------------------------------------------
invalid_inet_get_option() ->
[{doc,"Test handling of invalid inet options in getopts"}].
@@ -1474,6 +1650,25 @@ versions(Config) when is_list(Config) ->
[_|_] = Versions = ssl:versions(),
ct:log("~p~n", [Versions]).
+
+%%--------------------------------------------------------------------
+eccs() ->
+ [{doc, "Test API functions eccs/0 and eccs/1"}].
+
+eccs(Config) when is_list(Config) ->
+ [_|_] = All = ssl:eccs(),
+ [] = SSL3 = ssl:eccs({3,0}),
+ [_|_] = Tls = ssl:eccs({3,1}),
+ [_|_] = Tls1 = ssl:eccs({3,2}),
+ [_|_] = Tls2 = ssl:eccs({3,3}),
+ [] = SSL3 = ssl:eccs(sslv3),
+ [_|_] = Tls = ssl:eccs(tlsv1),
+ [_|_] = Tls1 = ssl:eccs('tlsv1.1'),
+ [_|_] = Tls2 = ssl:eccs('tlsv1.2'),
+ %% ordering is currently unverified by the test
+ true = lists:sort(All) =:= lists:usort(SSL3 ++ Tls ++ Tls1 ++ Tls2),
+ ok.
+
%%--------------------------------------------------------------------
send_recv() ->
[{doc,""}].
@@ -2133,8 +2328,9 @@ ciphers_dsa_signed_certs() ->
[{doc,"Test all dsa ssl cipher suites in highest support ssl/tls version"}].
ciphers_dsa_signed_certs(Config) when is_list(Config) ->
+ NVersion = ssl_test_lib:protocol_version(Config, tuple),
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:dsa_suites(),
+ Ciphers = ssl_test_lib:dsa_suites(NVersion),
ct:log("~p erlang cipher suites ~p~n", [Version, Ciphers]),
run_suites(Ciphers, Version, Config, dsa).
%%-------------------------------------------------------------------
@@ -2151,35 +2347,39 @@ anonymous_cipher_suites()->
[{doc,"Test the anonymous ciphersuites"}].
anonymous_cipher_suites(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:anonymous_suites(),
+ Ciphers = ssl_test_lib:anonymous_suites(Version),
run_suites(Ciphers, Version, Config, anonymous).
%%-------------------------------------------------------------------
psk_cipher_suites() ->
[{doc, "Test the PSK ciphersuites WITHOUT server supplied identity hint"}].
psk_cipher_suites(Config) when is_list(Config) ->
+ NVersion = tls_record:highest_protocol_version([]),
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:psk_suites(),
+ Ciphers = ssl_test_lib:psk_suites(NVersion),
run_suites(Ciphers, Version, Config, psk).
%%-------------------------------------------------------------------
psk_with_hint_cipher_suites()->
[{doc, "Test the PSK ciphersuites WITH server supplied identity hint"}].
psk_with_hint_cipher_suites(Config) when is_list(Config) ->
+ NVersion = tls_record:highest_protocol_version([]),
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:psk_suites(),
+ Ciphers = ssl_test_lib:psk_suites(NVersion),
run_suites(Ciphers, Version, Config, psk_with_hint).
%%-------------------------------------------------------------------
psk_anon_cipher_suites() ->
[{doc, "Test the anonymous PSK ciphersuites WITHOUT server supplied identity hint"}].
psk_anon_cipher_suites(Config) when is_list(Config) ->
+ NVersion = tls_record:highest_protocol_version([]),
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:psk_anon_suites(),
+ Ciphers = ssl_test_lib:psk_anon_suites(NVersion),
run_suites(Ciphers, Version, Config, psk_anon).
%%-------------------------------------------------------------------
psk_anon_with_hint_cipher_suites()->
[{doc, "Test the anonymous PSK ciphersuites WITH server supplied identity hint"}].
psk_anon_with_hint_cipher_suites(Config) when is_list(Config) ->
+ NVersion = tls_record:highest_protocol_version([]),
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:psk_anon_suites(),
+ Ciphers = ssl_test_lib:psk_anon_suites(NVersion),
run_suites(Ciphers, Version, Config, psk_anon_with_hint).
%%-------------------------------------------------------------------
srp_cipher_suites()->
@@ -2230,18 +2430,17 @@ rc4_ecdsa_cipher_suites(Config) when is_list(Config) ->
%%-------------------------------------------------------------------
des_rsa_cipher_suites()->
- [{doc, "Test the RC4 ciphersuites"}].
+ [{doc, "Test the des_rsa ciphersuites"}].
des_rsa_cipher_suites(Config) when is_list(Config) ->
- NVersion = tls_record:highest_protocol_version([]),
- Version = tls_record:protocol_version(NVersion),
- Ciphers = ssl_test_lib:des_suites(NVersion),
+ Version = ssl_test_lib:protocol_version(Config),
+ Ciphers = ssl_test_lib:des_suites(Config),
run_suites(Ciphers, Version, Config, des_rsa).
%-------------------------------------------------------------------
des_ecdh_rsa_cipher_suites()->
- [{doc, "Test the RC4 ciphersuites"}].
+ [{doc, "Test ECDH rsa signed ciphersuites"}].
des_ecdh_rsa_cipher_suites(Config) when is_list(Config) ->
- NVersion = tls_record:highest_protocol_version([]),
- Version = tls_record:protocol_version(NVersion),
+ NVersion = ssl_test_lib:protocol_version(Config, tuple),
+ Version = ssl_test_lib:protocol_version(Config),
Ciphers = ssl_test_lib:des_suites(NVersion),
run_suites(Ciphers, Version, Config, des_dhe_rsa).
@@ -2252,9 +2451,11 @@ default_reject_anonymous(Config) when is_list(Config) ->
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
-
- [Cipher | _] = ssl_test_lib:anonymous_suites(),
-
+ Version = ssl_test_lib:protocol_version(Config),
+ TLSVersion = ssl_test_lib:tls_version(Version),
+
+ [CipherSuite | _] = ssl_test_lib:anonymous_suites(TLSVersion),
+
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
{options, ServerOpts}]),
@@ -2263,7 +2464,7 @@ default_reject_anonymous(Config) when is_list(Config) ->
{host, Hostname},
{from, self()},
{options,
- [{ciphers,[Cipher]} |
+ [{ciphers,[CipherSuite]} |
ClientOpts]}]),
ssl_test_lib:check_result(Server, {error, {tls_alert, "insufficient security"}},
@@ -2274,8 +2475,9 @@ ciphers_ecdsa_signed_certs() ->
[{doc, "Test all ecdsa ssl cipher suites in highest support ssl/tls version"}].
ciphers_ecdsa_signed_certs(Config) when is_list(Config) ->
+ NVersion = ssl_test_lib:protocol_version(Config, tuple),
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:ecdsa_suites(),
+ Ciphers = ssl_test_lib:ecdsa_suites(NVersion),
ct:log("~p erlang cipher suites ~p~n", [Version, Ciphers]),
run_suites(Ciphers, Version, Config, ecdsa).
%%--------------------------------------------------------------------
@@ -2292,8 +2494,9 @@ ciphers_ecdh_rsa_signed_certs() ->
[{doc, "Test all ecdh_rsa ssl cipher suites in highest support ssl/tls version"}].
ciphers_ecdh_rsa_signed_certs(Config) when is_list(Config) ->
+ NVersion = ssl_test_lib:protocol_version(Config, tuple),
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:ecdh_rsa_suites(),
+ Ciphers = ssl_test_lib:ecdh_rsa_suites(NVersion),
ct:log("~p erlang cipher suites ~p~n", [Version, Ciphers]),
run_suites(Ciphers, Version, Config, ecdh_rsa).
%%--------------------------------------------------------------------
@@ -2775,10 +2978,10 @@ der_input(Config) when is_list(Config) ->
Size = ets:info(CADb, size),
- SeverVerifyOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ SeverVerifyOpts = ssl_test_lib:ssl_options(server_opts, Config),
{ServerCert, ServerKey, ServerCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} |
SeverVerifyOpts]),
- ClientVerifyOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
+ ClientVerifyOpts = ssl_test_lib:ssl_options(client_opts, Config),
{ClientCert, ClientKey, ClientCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} |
ClientVerifyOpts]),
ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true},
@@ -3265,11 +3468,11 @@ hibernate(Config) ->
process_info(Pid, current_function),
ssl_test_lib:check_result(Server, ok, Client, ok),
- timer:sleep(1100),
-
+
+ timer:sleep(1500),
{current_function, {erlang, hibernate, 3}} =
process_info(Pid, current_function),
-
+
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
@@ -3302,13 +3505,12 @@ hibernate_right_away(Config) ->
[{port, Port1}, {options, [{hibernate_after, 0}|ClientOpts]}]),
ssl_test_lib:check_result(Server1, ok, Client1, ok),
-
- {current_function, {erlang, hibernate, 3}} =
+
+ {current_function, {erlang, hibernate, 3}} =
process_info(Pid1, current_function),
-
ssl_test_lib:close(Server1),
ssl_test_lib:close(Client1),
-
+
Server2 = ssl_test_lib:start_server(StartServerOpts),
Port2 = ssl_test_lib:inet_port(Server2),
{Client2, #sslsocket{pid = Pid2}} = ssl_test_lib:start_client(StartClientOpts ++
@@ -3316,8 +3518,8 @@ hibernate_right_away(Config) ->
ssl_test_lib:check_result(Server2, ok, Client2, ok),
- ct:sleep(100), %% Schedule out
-
+ ct:sleep(1000), %% Schedule out
+
{current_function, {erlang, hibernate, 3}} =
process_info(Pid2, current_function),
@@ -3343,7 +3545,6 @@ listen_socket(Config) ->
{error, enotconn} = ssl:connection_information(ListenSocket),
{error, enotconn} = ssl:peername(ListenSocket),
{error, enotconn} = ssl:peercert(ListenSocket),
- {error, enotconn} = ssl:session_info(ListenSocket),
{error, enotconn} = ssl:renegotiate(ListenSocket),
{error, enotconn} = ssl:prf(ListenSocket, 'master_secret', <<"Label">>, client_random, 256),
{error, enotconn} = ssl:shutdown(ListenSocket, read_write),
@@ -3604,9 +3805,10 @@ no_rizzo_rc4() ->
[{doc,"Test that there is no 1/n-1-split for RC4 as it is not vunrable to Rizzo/Dungon attack"}].
no_rizzo_rc4(Config) when is_list(Config) ->
- Ciphers = [X || X ={_,Y,_} <- ssl:cipher_suites(),Y == rc4_128],
Prop = proplists:get_value(tc_group_properties, Config),
Version = proplists:get_value(name, Prop),
+ Ciphers = [ssl_cipher:erl_suite_definition(Suite) ||
+ Suite <- ssl_test_lib:rc4_suites(tls_record:protocol_version(Version))],
run_send_recv_rizzo(Ciphers, Config, Version,
{?MODULE, send_recv_result_active_no_rizzo, []}).
@@ -3614,9 +3816,10 @@ rizzo_one_n_minus_one() ->
[{doc,"Test that the 1/n-1-split mitigation of Rizzo/Dungon attack can be explicitly selected"}].
rizzo_one_n_minus_one(Config) when is_list(Config) ->
- Ciphers = [X || X ={_,Y,_} <- ssl:cipher_suites(), Y =/= rc4_128],
Prop = proplists:get_value(tc_group_properties, Config),
Version = proplists:get_value(name, Prop),
+ AllSuites = ssl_test_lib:available_suites(tls_record:protocol_version(Version)),
+ Ciphers = [X || X ={_,Y,_} <- AllSuites, Y =/= rc4_128],
run_send_recv_rizzo(Ciphers, Config, Version,
{?MODULE, send_recv_result_active_rizzo, []}).
@@ -3624,9 +3827,10 @@ rizzo_zero_n() ->
[{doc,"Test that the 0/n-split mitigation of Rizzo/Dungon attack can be explicitly selected"}].
rizzo_zero_n(Config) when is_list(Config) ->
- Ciphers = [X || X ={_,Y,_} <- ssl:cipher_suites(), Y =/= rc4_128],
Prop = proplists:get_value(tc_group_properties, Config),
Version = proplists:get_value(name, Prop),
+ AllSuites = ssl_test_lib:available_suites(tls_record:protocol_version(Version)),
+ Ciphers = [X || X ={_,Y,_} <- AllSuites, Y =/= rc4_128],
run_send_recv_rizzo(Ciphers, Config, Version,
{?MODULE, send_recv_result_active_no_rizzo, []}).
@@ -3797,6 +4001,29 @@ unordered_protocol_versions_client(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg).
%%--------------------------------------------------------------------
+max_handshake_size() ->
+ [{doc,"Test that we can set max_handshake_size to max value."}].
+
+max_handshake_size(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(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, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{max_handshake_size, 8388607} |ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{max_handshake_size, 8388607} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok).
+
+%%--------------------------------------------------------------------
server_name_indication_option() ->
[{doc,"Test API server_name_indication option to connect."}].
@@ -3943,11 +4170,11 @@ prf_create_plan(TlsVersions, PRFs, Results) ->
prf_ciphers_and_expected(TlsVer, PRFs, Results) ->
case TlsVer of
TlsVer when TlsVer == sslv3 orelse TlsVer == tlsv1
- orelse TlsVer == 'tlsv1.1' ->
+ orelse TlsVer == 'tlsv1.1' orelse TlsVer == 'dtlsv1' ->
Ciphers = ssl:cipher_suites(),
{_, Expected} = lists:keyfind(md5sha, 1, Results),
[[{tls_ver, TlsVer}, {ciphers, Ciphers}, {expected, Expected}, {prf, md5sha}]];
- 'tlsv1.2' ->
+ TlsVer when TlsVer == 'tlsv1.2' orelse TlsVer == 'dtlsv1.2'->
lists:foldl(
fun(PRF, Acc) ->
Ciphers = prf_get_ciphers(TlsVer, PRF),
@@ -3962,21 +4189,20 @@ prf_ciphers_and_expected(TlsVer, PRFs, Results) ->
end
end, [], PRFs)
end.
-prf_get_ciphers(TlsVer, PRF) ->
- case TlsVer of
- 'tlsv1.2' ->
- lists:filter(
- fun(C) when tuple_size(C) == 4 andalso
- element(4, C) == PRF ->
- true;
- (_) -> false
- end, ssl:cipher_suites())
- end.
+prf_get_ciphers(_, PRF) ->
+ lists:filter(
+ fun(C) when tuple_size(C) == 4 andalso
+ element(4, C) == PRF ->
+ true;
+ (_) ->
+ false
+ end,
+ ssl:cipher_suites()).
prf_run_test(_, TlsVer, [], _, Prf) ->
ct:fail({error, cipher_list_empty, TlsVer, Prf});
prf_run_test(Config, TlsVer, Ciphers, Expected, Prf) ->
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- BaseOpts = [{active, true}, {versions, [TlsVer]}, {ciphers, Ciphers}],
+ BaseOpts = [{active, true}, {versions, [TlsVer]}, {ciphers, Ciphers}, {protocol, tls_or_dtls(TlsVer)}],
ServerOpts = BaseOpts ++ proplists:get_value(server_opts, Config),
ClientOpts = BaseOpts ++ proplists:get_value(client_opts, Config),
Server = ssl_test_lib:start_server(
@@ -4288,7 +4514,7 @@ erlang_ssl_receive(Socket, Data) ->
erlang_ssl_receive(Socket, tl(Data));
Other ->
ct:fail({unexpected_message, Other})
- after ?SLEEP * 3 * test_server:timetrap_scale_factor() ->
+ after timer:seconds(?SEC_RENEGOTIATION_TIMEOUT) * test_server:timetrap_scale_factor() ->
ct:fail({did_not_get, Data})
end.
@@ -4377,7 +4603,7 @@ rizzo_test(Cipher, Config, Version, Mfa) ->
{host, Hostname},
{from, self()},
{mfa, Mfa},
- {options, [{active, true} | ClientOpts]}]),
+ {options, [{active, true}, {ciphers, [Cipher]}| ClientOpts]}]),
Result = ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
@@ -4409,27 +4635,32 @@ run_suites(Ciphers, Version, Config, Type) ->
{ClientOpts, ServerOpts} =
case Type of
rsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
- ssl_test_lib:ssl_options(server_opts, Config)};
+ {ssl_test_lib:ssl_options(client_verification_opts, Config),
+ ssl_test_lib:ssl_options(server_verification_opts, Config)};
dsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
+ {ssl_test_lib:ssl_options(client_verification_opts, Config),
ssl_test_lib:ssl_options(server_dsa_opts, Config)};
anonymous ->
%% No certs in opts!
- {ssl_test_lib:ssl_options(client_opts, Config),
- ssl_test_lib:ssl_options(server_anon, Config)};
+ {ssl_test_lib:ssl_options(client_verification_opts, Config),
+ [{reuseaddr, true}, {ciphers, ssl_test_lib:anonymous_suites(Version)}]};
psk ->
{ssl_test_lib:ssl_options(client_psk, Config),
- ssl_test_lib:ssl_options(server_psk, Config)};
+ [{ciphers, ssl_test_lib:psk_suites(Version)} |
+ ssl_test_lib:ssl_options(server_psk, Config)]};
psk_with_hint ->
{ssl_test_lib:ssl_options(client_psk, Config),
- ssl_test_lib:ssl_options(server_psk_hint, Config)};
+ [{ciphers, ssl_test_lib:psk_suites(Version)} |
+ ssl_test_lib:ssl_options(server_psk_hint, Config)
+ ]};
psk_anon ->
{ssl_test_lib:ssl_options(client_psk, Config),
- ssl_test_lib:ssl_options(server_psk_anon, Config)};
+ [{ciphers, ssl_test_lib:psk_anon_suites(Version)} |
+ ssl_test_lib:ssl_options(server_psk_anon, Config)]};
psk_anon_with_hint ->
{ssl_test_lib:ssl_options(client_psk, Config),
- ssl_test_lib:ssl_options(server_psk_anon_hint, Config)};
+ [{ciphers, ssl_test_lib:psk_anon_suites(Version)} |
+ ssl_test_lib:ssl_options(server_psk_anon_hint, Config)]};
srp ->
{ssl_test_lib:ssl_options(client_srp, Config),
ssl_test_lib:ssl_options(server_srp, Config)};
@@ -4440,36 +4671,36 @@ run_suites(Ciphers, Version, Config, Type) ->
{ssl_test_lib:ssl_options(client_srp_dsa, Config),
ssl_test_lib:ssl_options(server_srp_dsa, Config)};
ecdsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
+ {ssl_test_lib:ssl_options(client_verification_opts, Config),
ssl_test_lib:ssl_options(server_ecdsa_opts, Config)};
ecdh_rsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
+ {ssl_test_lib:ssl_options(client_verification_opts, Config),
ssl_test_lib:ssl_options(server_ecdh_rsa_opts, Config)};
rc4_rsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
+ {ssl_test_lib:ssl_options(client_verification_opts, Config),
[{ciphers, Ciphers} |
- ssl_test_lib:ssl_options(server_opts, Config)]};
+ ssl_test_lib:ssl_options(server_verification_opts, Config)]};
rc4_ecdh_rsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
+ {ssl_test_lib:ssl_options(client_verification_opts, Config),
[{ciphers, Ciphers} |
ssl_test_lib:ssl_options(server_ecdh_rsa_opts, Config)]};
rc4_ecdsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
+ {ssl_test_lib:ssl_options(client_verification_opts, Config),
[{ciphers, Ciphers} |
ssl_test_lib:ssl_options(server_ecdsa_opts, Config)]};
des_dhe_rsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
+ {ssl_test_lib:ssl_options(client_verification_opts, Config),
[{ciphers, Ciphers} |
- ssl_test_lib:ssl_options(server_opts, Config)]};
+ ssl_test_lib:ssl_options(server_verification_opts, Config)]};
des_rsa ->
- {ssl_test_lib:ssl_options(client_opts, Config),
+ {ssl_test_lib:ssl_options(client_verification_opts, Config),
[{ciphers, Ciphers} |
- ssl_test_lib:ssl_options(server_opts, Config)]}
+ ssl_test_lib:ssl_options(server_verification_opts, Config)]}
end,
Result = lists:map(fun(Cipher) ->
cipher(Cipher, Version, Config, ClientOpts, ServerOpts) end,
- ssl_test_lib:filter_suites(Ciphers)),
+ ssl_test_lib:filter_suites(Ciphers, Version)),
case lists:flatten(Result) of
[] ->
ok;
@@ -4537,6 +4768,11 @@ version_info_result(Socket) ->
{ok, [{version, Version}]} = ssl:connection_information(Socket, [version]),
{ok, Version}.
+secret_connection_info_result(Socket) ->
+ {ok, [{client_random, ClientRand}, {server_random, ServerRand}, {master_secret, MasterSecret}]}
+ = ssl:connection_information(Socket, [client_random, server_random, master_secret]),
+ is_binary(ClientRand) andalso is_binary(ServerRand) andalso is_binary(MasterSecret).
+
connect_dist_s(S) ->
Msg = term_to_binary({erlang,term}),
ok = ssl:send(S, Msg).
@@ -4668,3 +4904,10 @@ first_rsa_suite([_ | Rest]) ->
wait_for_send(Socket) ->
%% Make sure TLS process processed send message event
_ = ssl:connection_information(Socket).
+
+tls_or_dtls('dtlsv1') ->
+ dtls;
+tls_or_dtls('dtlsv1.2') ->
+ dtls;
+tls_or_dtls(_) ->
+ tls.
diff --git a/lib/ssl/test/ssl_bench_SUITE.erl b/lib/ssl/test/ssl_bench_SUITE.erl
index ed439a425f..ae2928b1c3 100644
--- a/lib/ssl/test/ssl_bench_SUITE.erl
+++ b/lib/ssl/test/ssl_bench_SUITE.erl
@@ -1,7 +1,7 @@
%%%-------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2014-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,11 +25,12 @@
suite() -> [{ct_hooks,[{ts_install_cth,[{nodenames,2}]}]}].
-all() -> [{group, setup}, {group, payload}].
+all() -> [{group, setup}, {group, payload}, {group, pem_cache}].
groups() ->
[{setup, [{repeat, 3}], [setup_sequential, setup_concurrent]},
- {payload, [{repeat, 3}], [payload_simple]}
+ {payload, [{repeat, 3}], [payload_simple]},
+ {pem_cache, [{repeat, 3}], [use_pem_cache, bypass_pem_cache]}
].
init_per_group(_GroupName, Config) ->
@@ -49,9 +50,33 @@ init_per_suite(Config) ->
end_per_suite(_Config) ->
ok.
+init_per_testcase(use_pem_cache, Conf) ->
+ case bypass_pem_cache_supported() of
+ false -> {skipped, "PEM cache bypass support required"};
+ true ->
+ application:set_env(ssl, bypass_pem_cache, false),
+ Conf
+ end;
+init_per_testcase(bypass_pem_cache, Conf) ->
+ case bypass_pem_cache_supported() of
+ false -> {skipped, "PEM cache bypass support required"};
+ true ->
+ application:set_env(ssl, bypass_pem_cache, true),
+ Conf
+ end;
init_per_testcase(_Func, Conf) ->
Conf.
+end_per_testcase(use_pem_cache, _Config) ->
+ case bypass_pem_cache_supported() of
+ false -> ok;
+ true -> application:set_env(ssl, bypass_pem_cache, false)
+ end;
+end_per_testcase(bypass_pem_cache, _Config) ->
+ case bypass_pem_cache_supported() of
+ false -> ok;
+ true -> application:set_env(ssl, bypass_pem_cache, false)
+ end;
end_per_testcase(_Func, _Conf) ->
ok.
@@ -63,7 +88,6 @@ end_per_testcase(_Func, _Conf) ->
-define(FPROF_SERVER, false).
-define(EPROF_CLIENT, false).
-define(EPROF_SERVER, false).
--define(PERCEPT_SERVER, false).
%% Current numbers gives roughly a testcase per minute on todays hardware..
@@ -94,6 +118,18 @@ payload_simple(Config) ->
{suite, "ssl"}, {name, "Payload simple"}]}),
ok.
+use_pem_cache(_Config) ->
+ {ok, Result} = do_test(ssl, pem_cache, 100, 500, node()),
+ ct_event:notify(#event{name = benchmark_data,
+ data=[{value, Result},
+ {suite, "ssl"}, {name, "Use PEM cache"}]}).
+
+bypass_pem_cache(_Config) ->
+ {ok, Result} = do_test(ssl, pem_cache, 100, 500, node()),
+ ct_event:notify(#event{name = benchmark_data,
+ data=[{value, Result},
+ {suite, "ssl"}, {name, "Bypass PEM cache"}]}).
+
ssl() ->
test(ssl, ?COUNT, node()).
@@ -153,7 +189,6 @@ server_init(ssl, setup_connection, _, _, Server) ->
?FPROF_SERVER andalso start_profile(fprof, [whereis(ssl_manager), new]),
%%?EPROF_SERVER andalso start_profile(eprof, [ssl_connection_sup, ssl_manager]),
?EPROF_SERVER andalso start_profile(eprof, [ssl_manager]),
- ?PERCEPT_SERVER andalso percept:profile("/tmp/ssl_server.percept"),
Server ! {self(), {init, Host, Port}},
Test = fun(TSocket) ->
ok = ssl:ssl_accept(TSocket),
@@ -172,6 +207,18 @@ server_init(ssl, payload, Loop, _, Server) ->
ssl:close(TSocket)
end,
setup_server_connection(Socket, Test);
+server_init(ssl, pem_cache, Loop, _, Server) ->
+ {ok, Socket} = ssl:listen(0, ssl_opts(listen_der)),
+ {ok, {_Host, Port}} = ssl:sockname(Socket),
+ {ok, Host} = inet:gethostname(),
+ Server ! {self(), {init, Host, Port}},
+ Test = fun(TSocket) ->
+ ok = ssl:ssl_accept(TSocket),
+ Size = byte_size(msg()),
+ server_echo(TSocket, Size, Loop),
+ ssl:close(TSocket)
+ end,
+ setup_server_connection(Socket, Test);
server_init(Type, Tc, _, _, Server) ->
io:format("No server init code for ~p ~p~n",[Type, Tc]),
@@ -185,6 +232,11 @@ client_init(Master, ssl, payload, Host, Port) ->
Master ! {self(), init},
Size = byte_size(msg()),
{Sock, Size};
+client_init(Master, ssl, pem_cache, Host, Port) ->
+ {ok, Sock} = ssl:connect(Host, Port, ssl_opts(connect_der)),
+ Master ! {self(), init},
+ Size = byte_size(msg()),
+ {Sock, Size};
client_init(_Me, Type, Tc, Host, Port) ->
io:format("No client init code for ~p ~p~n",[Type, Tc]),
{Host, Port}.
@@ -193,7 +245,6 @@ setup_server_connection(LSocket, Test) ->
receive quit ->
?FPROF_SERVER andalso stop_profile(fprof, "test_server_res.fprof"),
?EPROF_SERVER andalso stop_profile(eprof, "test_server_res.eprof"),
- ?PERCEPT_SERVER andalso stop_profile(percept, "/tmp/ssl_server.percept"),
ok
after 0 ->
case ssl:transport_accept(LSocket, 2000) of
@@ -228,6 +279,13 @@ payload(Loop, ssl, D = {Socket, Size}) when Loop > 0 ->
payload(_, _, {Socket, _}) ->
ssl:close(Socket).
+pem_cache(N, ssl, Data = {Socket, Size}) when N > 0 ->
+ ok = ssl:send(Socket, msg()),
+ {ok, _} = ssl:recv(Socket, Size),
+ pem_cache(N-1, ssl, Data);
+pem_cache(_, _, {Socket, _}) ->
+ ssl:close(Socket).
+
msg() ->
<<"Hello",
0:(512*8),
@@ -327,13 +385,6 @@ start_profile(fprof, Procs) ->
fprof:trace([start, {procs, Procs}]),
io:format("(F)Profiling ...",[]).
-stop_profile(percept, File) ->
- percept:stop_profile(),
- percept:analyze(File),
- {started, _Host, Port} = percept:start_webserver(),
- wx:new(),
- wx_misc:launchDefaultBrowser("http://" ++ net_adm:localhost() ++ ":" ++ integer_to_list(Port)),
- ok;
stop_profile(eprof, File) ->
profiling_stopped = eprof:stop_profiling(),
eprof:log(File),
@@ -352,16 +403,49 @@ stop_profile(fprof, File) ->
ssl_opts(listen) ->
[{backlog, 500} | ssl_opts("server")];
ssl_opts(connect) ->
- [{verify, verify_peer}
- | ssl_opts("client")];
+ [{verify, verify_peer} | ssl_opts("client")];
+ssl_opts(listen_der) ->
+ [{backlog, 500} | ssl_opts("server_der")];
+ssl_opts(connect_der) ->
+ [{verify, verify_peer} | ssl_opts("client_der")];
ssl_opts(Role) ->
+ CertData = cert_data(Role),
+ Opts = [{active, false},
+ {depth, 2},
+ {reuseaddr, true},
+ {mode,binary},
+ {nodelay, true},
+ {ciphers, [{dhe_rsa,aes_256_cbc,sha}]}
+ |CertData],
+ case Role of
+ "client" ++ _ ->
+ [{server_name_indication, disable} | Opts];
+ "server" ++ _ ->
+ Opts
+ end.
+
+cert_data(Der) when Der =:= "server_der"; Der =:= "client_der" ->
+ [Role,_] = string:tokens(Der, "_"),
Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
- [{active, false},
- {depth, 2},
- {reuseaddr, true},
- {mode,binary},
- {nodelay, true},
- {ciphers, [{dhe_rsa,aes_256_cbc,sha}]},
- {cacertfile, filename:join([Dir, Role, "cacerts.pem"])},
+ {ok, CaCert0} = file:read_file(filename:join([Dir, Role, "cacerts.pem"])),
+ {ok, Cert0} = file:read_file(filename:join([Dir, Role, "cert.pem"])),
+ {ok, Key0} = file:read_file(filename:join([Dir, Role, "key.pem"])),
+ [{_, Cert, _}] = public_key:pem_decode(Cert0),
+ CaCert1 = public_key:pem_decode(CaCert0),
+ CaCert = [CCert || {_, CCert, _} <- CaCert1],
+ [{KeyType, Key, _}] = public_key:pem_decode(Key0),
+ [{cert, Cert},
+ {cacerts, CaCert},
+ {key, {KeyType, Key}}];
+cert_data(Role) ->
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ [{cacertfile, filename:join([Dir, Role, "cacerts.pem"])},
{certfile, filename:join([Dir, Role, "cert.pem"])},
{keyfile, filename:join([Dir, Role, "key.pem"])}].
+
+bypass_pem_cache_supported() ->
+ %% This function is currently critical to support cache bypass
+ %% and did not exist in prior versions.
+ catch ssl_pkix_db:module_info(), % ensure module is loaded
+ erlang:function_exported(ssl_pkix_db, extract_trusted_certs, 1).
+
diff --git a/lib/ssl/test/ssl_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
index 20165c70f0..6221cffdc1 100644
--- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl
+++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -39,17 +39,26 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
all() ->
- [{group, active},
- {group, passive},
- {group, active_once},
- {group, error_handling}].
-
+ [
+ {group, tls},
+ {group, dtls}
+ ].
groups() ->
- [{active, [], tests()},
+ [
+ {tls, [], all_protocol_groups()},
+ {dtls, [], all_protocol_groups()},
+ {active, [], tests()},
{active_once, [], tests()},
{passive, [], tests()},
- {error_handling, [],error_handling_tests()}].
+ {error_handling, [],error_handling_tests()}
+ ].
+
+all_protocol_groups() ->
+ [{group, active},
+ {group, passive},
+ {group, active_once},
+ {group, error_handling}].
tests() ->
[verify_peer,
@@ -65,9 +74,10 @@ tests() ->
cert_expired,
invalid_signature_client,
invalid_signature_server,
- extended_key_usage_verify_peer,
- extended_key_usage_verify_none,
- critical_extension_verify_peer,
+ extended_key_usage_verify_both,
+ extended_key_usage_verify_server,
+ critical_extension_verify_client,
+ critical_extension_verify_server,
critical_extension_verify_none].
error_handling_tests()->
@@ -78,18 +88,14 @@ error_handling_tests()->
unknown_server_ca_accept_verify_peer,
unknown_server_ca_accept_backwardscompatibility,
no_authority_key_identifier,
- no_authority_key_identifier_and_nonstandard_encoding].
+ no_authority_key_identifier_keyEncipherment].
-init_per_suite(Config0) ->
+init_per_suite(Config) ->
catch crypto:stop(),
try crypto:start() of
ok ->
- ssl:start(),
- %% make rsa certs using oppenssl
- {ok, _} = make_certs:all(proplists:get_value(data_dir, Config0),
- proplists:get_value(priv_dir, Config0)),
- Config = ssl_test_lib:make_dsa_cert(Config0),
- ssl_test_lib:cert_options(Config)
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config)
catch _:_ ->
{skip, "Crypto did not start"}
end.
@@ -98,32 +104,44 @@ end_per_suite(_Config) ->
ssl:stop(),
application:stop(crypto).
+init_per_group(tls, Config0) ->
+ Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, protocol_version, Version),
+ ssl:start(),
+ Config = proplists:delete(protocol, Config0),
+ [{protocol, tls}, {version, tls_record:protocol_version(Version)} | Config];
+
+init_per_group(dtls, Config0) ->
+ Version = dtls_record:protocol_version(dtls_record:highest_protocol_version([])),
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, protocol_version, Version),
+ ssl:start(),
+ Config = proplists:delete(protocol_opts, proplists:delete(protocol, Config0)),
+ [{protocol, dtls}, {protocol_opts, [{protocol, dtls}]}, {version, dtls_record:protocol_version(Version)} | Config];
+
init_per_group(active, Config) ->
- [{active, true}, {receive_function, send_recv_result_active} | Config];
+ [{active, true}, {receive_function, send_recv_result_active} | Config];
init_per_group(active_once, Config) ->
- [{active, once}, {receive_function, send_recv_result_active_once} | Config];
+ [{active, once}, {receive_function, send_recv_result_active_once} | Config];
init_per_group(passive, Config) ->
- [{active, false}, {receive_function, send_recv_result} | Config];
+ [{active, false}, {receive_function, send_recv_result} | Config];
+init_per_group(error_handling, Config) ->
+ [{active, false}, {receive_function, send_recv_result} | Config];
+
init_per_group(_, Config) ->
Config.
end_per_group(_GroupName, Config) ->
Config.
-init_per_testcase(TestCase, Config) when TestCase == cert_expired;
- TestCase == invalid_signature_client;
- TestCase == invalid_signature_server;
- TestCase == extended_key_usage_verify_none;
- TestCase == extended_key_usage_verify_peer;
- TestCase == critical_extension_verify_none;
- TestCase == critical_extension_verify_peer;
- TestCase == no_authority_key_identifier;
- TestCase == no_authority_key_identifier_and_nonstandard_encoding->
- ssl:clear_pem_cache(),
- init_per_testcase(common, Config);
init_per_testcase(_TestCase, Config) ->
+ ssl:stop(),
+ ssl:start(),
ssl_test_lib:ct_log_supported_protocol_versions(Config),
- ct:timetrap({seconds, 5}),
+ ct:timetrap({seconds, 10}),
Config.
end_per_testcase(_TestCase, Config) ->
@@ -136,23 +154,23 @@ end_per_testcase(_TestCase, Config) ->
verify_peer() ->
[{doc,"Test option verify_peer"}].
verify_peer(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
Active = proplists:get_value(active, Config),
ReceiveFunction = proplists:get_value(receive_function, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active}, {verify, verify_peer}
- | ServerOpts]}]),
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{active, Active}, {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, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active} | ClientOpts]}]),
-
+ {from, self()},
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{active, Active}, {verify, verify_peer} | ClientOpts]}]),
+
ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
@@ -162,23 +180,24 @@ verify_none() ->
[{doc,"Test option verify_none"}].
verify_none(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
Active = proplists:get_value(active, Config),
ReceiveFunction = proplists:get_value(receive_function, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active}, {verify, verify_none}
- | ServerOpts]}]),
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{active, Active}, {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, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active} | ClientOpts]}]),
+ {from, self()},
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{active, Active},
+ {verify, verify_none} | ClientOpts]}]),
ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
@@ -190,8 +209,8 @@ server_verify_client_once() ->
[{doc,"Test server option verify_client_once"}].
server_verify_client_once(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, []),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
Active = proplists:get_value(active, Config),
ReceiveFunction = proplists:get_value(receive_function, Config),
@@ -207,7 +226,7 @@ server_verify_client_once(Config) when is_list(Config) ->
{host, Hostname},
{from, self()},
{mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{active, Active} | ClientOpts]}]),
+ {options, [{active, Active} | ClientOpts]}]),
ssl_test_lib:check_result(Server, ok, Client0, ok),
Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
@@ -229,8 +248,8 @@ server_require_peer_cert_ok() ->
server_require_peer_cert_ok(Config) when is_list(Config) ->
ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_verification_opts, Config)],
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
+ | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
Active = proplists:get_value(active, Config),
ReceiveFunction = proplists:get_value(receive_function, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -258,20 +277,21 @@ server_require_peer_cert_fail() ->
server_require_peer_cert_fail(Config) when is_list(Config) ->
ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_verification_opts, Config)],
- BadClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
+ BadClientOpts = ssl_test_lib:ssl_options(empty_client_opts, Config),
+ Active = proplists:get_value(active, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
- {options, [{active, false} | ServerOpts]}]),
+ {options, [{active, Active} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
- {options, [{active, false} | BadClientOpts]}]),
+ {options, [{active, Active} | BadClientOpts]}]),
receive
{Server, {error, {tls_alert, "handshake failure"}}} ->
receive
@@ -289,24 +309,25 @@ server_require_peer_cert_partial_chain() ->
server_require_peer_cert_partial_chain(Config) when is_list(Config) ->
ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_verification_opts, Config)],
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
+ | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ Active = proplists:get_value(active, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
{ok, ClientCAs} = file:read_file(proplists:get_value(cacertfile, ClientOpts)),
- [{_,RootCA,_}, {_, _, _}] = public_key:pem_decode(ClientCAs),
+ [{_,RootCA,_} | _] = public_key:pem_decode(ClientCAs),
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
{mfa, {ssl_test_lib, no_result, []}},
- {options, [{active, false} | ServerOpts]}]),
+ {options, [{active, Active} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
{mfa, {ssl_test_lib, no_result, []}},
- {options, [{active, false},
+ {options, [{active, Active},
{cacerts, [RootCA]} |
proplists:delete(cacertfile, ClientOpts)]}]),
receive
@@ -324,14 +345,14 @@ server_require_peer_cert_allow_partial_chain() ->
server_require_peer_cert_allow_partial_chain(Config) when is_list(Config) ->
ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_verification_opts, Config)],
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
+ | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Active = proplists:get_value(active, Config),
ReceiveFunction = proplists:get_value(receive_function, Config),
- {ok, ServerCAs} = file:read_file(proplists:get_value(cacertfile, ServerOpts)),
- [{_,_,_}, {_, IntermidiateCA, _}] = public_key:pem_decode(ServerCAs),
+ {ok, ClientCAs} = file:read_file(proplists:get_value(cacertfile, ClientOpts)),
+ [{_,_,_}, {_, IntermidiateCA, _} | _] = public_key:pem_decode(ClientCAs),
PartialChain = fun(CertChain) ->
case lists:member(IntermidiateCA, CertChain) of
@@ -366,12 +387,12 @@ server_require_peer_cert_do_not_allow_partial_chain() ->
server_require_peer_cert_do_not_allow_partial_chain(Config) when is_list(Config) ->
ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_verification_opts, Config)],
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
+ | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
{ok, ServerCAs} = file:read_file(proplists:get_value(cacertfile, ServerOpts)),
- [{_,_,_}, {_, IntermidiateCA, _}] = public_key:pem_decode(ServerCAs),
+ [{_,_,_}, {_, IntermidiateCA, _} | _] = public_key:pem_decode(ServerCAs),
PartialChain = fun(_CertChain) ->
unknown_ca
@@ -407,12 +428,12 @@ server_require_peer_cert_partial_chain_fun_fail() ->
server_require_peer_cert_partial_chain_fun_fail(Config) when is_list(Config) ->
ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}
- | ssl_test_lib:ssl_options(server_verification_opts, Config)],
- ClientOpts = proplists:get_value(client_verification_opts, Config),
+ | ssl_test_lib:ssl_options(server_rsa_opts, Config)],
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
{ok, ServerCAs} = file:read_file(proplists:get_value(cacertfile, ServerOpts)),
- [{_,_,_}, {_, IntermidiateCA, _}] = public_key:pem_decode(ServerCAs),
+ [{_,_,_}, {_, IntermidiateCA, _} | _] = public_key:pem_decode(ServerCAs),
PartialChain = fun(_CertChain) ->
ture = false %% crash on purpose
@@ -447,8 +468,8 @@ verify_fun_always_run_client() ->
[{doc,"Verify that user verify_fun is always run (for valid and valid_peer not only unknown_extension)"}].
verify_fun_always_run_client(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
@@ -492,8 +513,8 @@ verify_fun_always_run_client(Config) when is_list(Config) ->
verify_fun_always_run_server() ->
[{doc,"Verify that user verify_fun is always run (for valid and valid_peer not only unknown_extension)"}].
verify_fun_always_run_server(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
%% If user verify fun is called correctly we fail the connection.
@@ -524,9 +545,7 @@ verify_fun_always_run_server(Config) when is_list(Config) ->
{from, self()},
{mfa, {ssl_test_lib,
no_result, []}},
- {options,
- [{verify, verify_peer}
- | ClientOpts]}]),
+ {options, ClientOpts}]),
%% Client error may be {tls_alert, "handshake failure" } or closed depending on timing
%% this is not a bug it is a circumstance of how tcp works!
@@ -543,63 +562,28 @@ cert_expired() ->
[{doc,"Test server with expired certificate"}].
cert_expired(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
-
- KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
- [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
-
- ServerCertFile = proplists:get_value(certfile, ServerOpts),
- NewServerCertFile = filename:join(PrivDir, "server/expired_cert.pem"),
- [{'Certificate', DerCert, _}] = ssl_test_lib:pem_to_der(ServerCertFile),
- OTPCert = public_key:pkix_decode_cert(DerCert, otp),
- OTPTbsCert = OTPCert#'OTPCertificate'.tbsCertificate,
-
{Year, Month, Day} = date(),
- {Hours, Min, Sec} = time(),
- NotBeforeStr = lists:flatten(io_lib:format("~p~s~s~s~s~sZ",[Year-2,
- two_digits_str(Month),
- two_digits_str(Day),
- two_digits_str(Hours),
- two_digits_str(Min),
- two_digits_str(Sec)])),
- NotAfterStr = lists:flatten(io_lib:format("~p~s~s~s~s~sZ",[Year-1,
- two_digits_str(Month),
- two_digits_str(Day),
- two_digits_str(Hours),
- two_digits_str(Min),
- two_digits_str(Sec)])),
- NewValidity = {'Validity', {generalTime, NotBeforeStr}, {generalTime, NotAfterStr}},
-
- ct:log("Validity: ~p ~n NewValidity: ~p ~n",
- [OTPTbsCert#'OTPTBSCertificate'.validity, NewValidity]),
-
- NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{validity = NewValidity},
- NewServerDerCert = public_key:pkix_sign(NewOTPTbsCert, Key),
- ssl_test_lib:der_to_pem(NewServerCertFile, [{'Certificate', NewServerDerCert, not_encrypted}]),
- NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
-
+ Active = proplists:get_value(active, Config),
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_ca_0,
+ [{validity, {{Year-2, Month, Day},
+ {Year-1, Month, Day}}}]}],
+ Config, "_expired"),
+ ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
+ ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
+
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
- {options, NewServerOpts}]),
+ {options, [{active, Active}| ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
- {options, [{verify, verify_peer} | ClientOpts]}]),
- receive
- {Client, {error, {tls_alert, "certificate expired"}}} ->
- receive
- {Server, {error, {tls_alert, "certificate expired"}}} ->
- ok;
- {Server, {error, closed}} ->
- ok
- end
- end.
+ {options, [{verify, verify_peer}, {active, Active} | ClientOpts]}]),
+
+ tcp_delivery_workaround(Server, {error, {tls_alert, "certificate expired"}},
+ Client, {error, {tls_alert, "certificate expired"}}).
two_digits_str(N) when N < 10 ->
lists:flatten(io_lib:format("0~p", [N]));
@@ -607,61 +591,33 @@ two_digits_str(N) ->
lists:flatten(io_lib:format("~p", [N])).
%%--------------------------------------------------------------------
-extended_key_usage_verify_peer() ->
- [{doc,"Test cert that has a critical extended_key_usage extension in verify_peer mode"}].
-
-extended_key_usage_verify_peer(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
+extended_key_usage_verify_server() ->
+ [{doc,"Test cert that has a critical extended_key_usage extension in server cert"}].
+
+extended_key_usage_verify_server(Config) when is_list(Config) ->
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_peer_opts,
+ [{extensions,
+ [{?'id-ce-extKeyUsage',
+ [?'id-kp-serverAuth'], true}]
+ }]}], Config, "_keyusage_server"),
+ ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
+ ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
Active = proplists:get_value(active, Config),
ReceiveFunction = proplists:get_value(receive_function, Config),
- KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
- [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
-
- ServerCertFile = proplists:get_value(certfile, ServerOpts),
- NewServerCertFile = filename:join(PrivDir, "server/new_cert.pem"),
- [{'Certificate', ServerDerCert, _}] = ssl_test_lib:pem_to_der(ServerCertFile),
- ServerOTPCert = public_key:pkix_decode_cert(ServerDerCert, otp),
- ServerExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-serverAuth']},
- ServerOTPTbsCert = ServerOTPCert#'OTPCertificate'.tbsCertificate,
- ServerExtensions = ServerOTPTbsCert#'OTPTBSCertificate'.extensions,
- NewServerOTPTbsCert = ServerOTPTbsCert#'OTPTBSCertificate'{extensions =
- [ServerExtKeyUsageExt |
- ServerExtensions]},
- NewServerDerCert = public_key:pkix_sign(NewServerOTPTbsCert, Key),
- ssl_test_lib:der_to_pem(NewServerCertFile, [{'Certificate', NewServerDerCert, not_encrypted}]),
- NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
-
- ClientCertFile = proplists:get_value(certfile, ClientOpts),
- NewClientCertFile = filename:join(PrivDir, "client/new_cert.pem"),
- [{'Certificate', ClientDerCert, _}] = ssl_test_lib:pem_to_der(ClientCertFile),
- ClientOTPCert = public_key:pkix_decode_cert(ClientDerCert, otp),
- ClientExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-clientAuth']},
- ClientOTPTbsCert = ClientOTPCert#'OTPCertificate'.tbsCertificate,
- ClientExtensions = ClientOTPTbsCert#'OTPTBSCertificate'.extensions,
- NewClientOTPTbsCert = ClientOTPTbsCert#'OTPTBSCertificate'{extensions =
- [ClientExtKeyUsageExt |
- ClientExtensions]},
- NewClientDerCert = public_key:pkix_sign(NewClientOTPTbsCert, Key),
- ssl_test_lib:der_to_pem(NewClientCertFile, [{'Certificate', NewClientDerCert, not_encrypted}]),
- NewClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts)],
-
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
{mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{verify, verify_peer}, {active, Active} | NewServerOpts]}]),
+ {options, [{verify, verify_none}, {active, Active} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
{mfa, {ssl_test_lib, ReceiveFunction, []}},
{options, [{verify, verify_peer}, {active, Active} |
- NewClientOpts]}]),
+ ClientOpts]}]),
ssl_test_lib:check_result(Server, ok, Client, ok),
@@ -669,60 +625,35 @@ extended_key_usage_verify_peer(Config) when is_list(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
-extended_key_usage_verify_none() ->
- [{doc,"Test cert that has a critical extended_key_usage extension in verify_none mode"}].
-
-extended_key_usage_verify_none(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
+extended_key_usage_verify_both() ->
+ [{doc,"Test cert that has a critical extended_key_usage extension in client verify_peer mode"}].
+
+extended_key_usage_verify_both(Config) when is_list(Config) ->
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_peer_opts,
+ [{extensions, [{?'id-ce-extKeyUsage',
+ [?'id-kp-serverAuth'], true}]
+ }]},
+ {client_peer_opts,
+ [{extensions, [{?'id-ce-extKeyUsage',
+ [?'id-kp-clientAuth'], true}]
+ }]}], Config, "_keyusage_both"),
+ ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
+ ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
Active = proplists:get_value(active, Config),
ReceiveFunction = proplists:get_value(receive_function, Config),
- KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
- [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
-
- ServerCertFile = proplists:get_value(certfile, ServerOpts),
- NewServerCertFile = filename:join(PrivDir, "server/new_cert.pem"),
- [{'Certificate', ServerDerCert, _}] = ssl_test_lib:pem_to_der(ServerCertFile),
- ServerOTPCert = public_key:pkix_decode_cert(ServerDerCert, otp),
- ServerExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-serverAuth']},
- ServerOTPTbsCert = ServerOTPCert#'OTPCertificate'.tbsCertificate,
- ServerExtensions = ServerOTPTbsCert#'OTPTBSCertificate'.extensions,
- NewServerOTPTbsCert = ServerOTPTbsCert#'OTPTBSCertificate'{extensions =
- [ServerExtKeyUsageExt |
- ServerExtensions]},
- NewServerDerCert = public_key:pkix_sign(NewServerOTPTbsCert, Key),
- ssl_test_lib:der_to_pem(NewServerCertFile, [{'Certificate', NewServerDerCert, not_encrypted}]),
- NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
-
- ClientCertFile = proplists:get_value(certfile, ClientOpts),
- NewClientCertFile = filename:join(PrivDir, "client/new_cert.pem"),
- [{'Certificate', ClientDerCert, _}] = ssl_test_lib:pem_to_der(ClientCertFile),
- ClientOTPCert = public_key:pkix_decode_cert(ClientDerCert, otp),
- ClientExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-clientAuth']},
- ClientOTPTbsCert = ClientOTPCert#'OTPCertificate'.tbsCertificate,
- ClientExtensions = ClientOTPTbsCert#'OTPTBSCertificate'.extensions,
- NewClientOTPTbsCert = ClientOTPTbsCert#'OTPTBSCertificate'{extensions =
- [ClientExtKeyUsageExt |
- ClientExtensions]},
- NewClientDerCert = public_key:pkix_sign(NewClientOTPTbsCert, Key),
- ssl_test_lib:der_to_pem(NewClientCertFile, [{'Certificate', NewClientDerCert, not_encrypted}]),
- NewClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts)],
-
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
{mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{verify, verify_none}, {active, Active} | NewServerOpts]}]),
+ {options, [{verify, verify_peer}, {active, Active} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
{mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{verify, verify_none}, {active, Active} | NewClientOpts]}]),
+ {options, [{verify, verify_peer}, {active, Active} | ClientOpts]}]),
ssl_test_lib:check_result(Server, ok, Client, ok),
@@ -730,28 +661,55 @@ extended_key_usage_verify_none(Config) when is_list(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
-critical_extension_verify_peer() ->
+critical_extension_verify_server() ->
[{doc,"Test cert that has a critical unknown extension in verify_peer mode"}].
-critical_extension_verify_peer(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
+critical_extension_verify_server(Config) when is_list(Config) ->
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{client_peer_opts,
+ [{extensions, [{{2,16,840,1,113730,1,1},
+ <<3,2,6,192>>, true}]
+ }]}], Config, "_client_unknown_extension"),
+ ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
+ ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
Active = proplists:get_value(active, Config),
ReceiveFunction = proplists:get_value(receive_function, Config),
- KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
- NewCertName = integer_to_list(erlang:unique_integer()) ++ ".pem",
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- ServerCertFile = proplists:get_value(certfile, ServerOpts),
- NewServerCertFile = filename:join([PrivDir, "server", NewCertName]),
- add_critical_netscape_cert_type(ServerCertFile, NewServerCertFile, KeyFile),
- NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
+ Server = ssl_test_lib:start_server_error(
+ [{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{verify, verify_peer}, {active, Active} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error(
+ [{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, ReceiveFunction, []}},
+ {options, [{verify, verify_none}, {active, Active} | ClientOpts]}]),
- ClientCertFile = proplists:get_value(certfile, ClientOpts),
- NewClientCertFile = filename:join([PrivDir, "client", NewCertName]),
- add_critical_netscape_cert_type(ClientCertFile, NewClientCertFile, KeyFile),
- NewClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts)],
+ %% This certificate has a critical extension that we don't
+ %% understand. Therefore, verification should fail.
+
+ tcp_delivery_workaround(Server, {error, {tls_alert, "unsupported certificate"}},
+ Client, {error, {tls_alert, "unsupported certificate"}}),
+
+ ssl_test_lib:close(Server).
+%%--------------------------------------------------------------------
+
+critical_extension_verify_client() ->
+ [{doc,"Test cert that has a critical unknown extension in verify_peer mode"}].
+
+critical_extension_verify_client(Config) when is_list(Config) ->
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_peer_opts,
+ [{extensions, [{{2,16,840,1,113730,1,1},
+ <<3,2,6,192>>, true}]
+ }]}], Config, "_server_unknown_extensions"),
+ ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
+ ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
+ Active = proplists:get_value(active, Config),
+ ReceiveFunction = proplists:get_value(receive_function, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -759,61 +717,51 @@ critical_extension_verify_peer(Config) when is_list(Config) ->
[{node, ServerNode}, {port, 0},
{from, self()},
{mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{verify, verify_peer}, {active, Active} | NewServerOpts]}]),
+ {options, [{verify, verify_none}, {active, Active} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client_error(
[{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
{mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{verify, verify_peer}, {active, Active} | NewClientOpts]}]),
+ {options, [{verify, verify_peer}, {active, Active} | ClientOpts]}]),
%% This certificate has a critical extension that we don't
%% understand. Therefore, verification should fail.
- tcp_delivery_workaround(Server, {error, {tls_alert, "unsupported certificate"}},
- Client, {error, {tls_alert, "unsupported certificate"}}),
+ ssl_test_lib:check_result(Server, {error, {tls_alert, "unsupported certificate"}},
+ Client, {error, {tls_alert, "unsupported certificate"}}),
- ssl_test_lib:close(Server),
- ok.
+ ssl_test_lib:close(Server).
%%--------------------------------------------------------------------
critical_extension_verify_none() ->
[{doc,"Test cert that has a critical unknown extension in verify_none mode"}].
critical_extension_verify_none(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{client_peer_opts,
+ [{extensions,
+ [{{2,16,840,1,113730,1,1},
+ <<3,2,6,192>>, true}]
+ }]}], Config, "_unknown_extensions"),
+ ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
+ ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
Active = proplists:get_value(active, Config),
ReceiveFunction = proplists:get_value(receive_function, Config),
- KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
- NewCertName = integer_to_list(erlang:unique_integer()) ++ ".pem",
-
- ServerCertFile = proplists:get_value(certfile, ServerOpts),
- NewServerCertFile = filename:join([PrivDir, "server", NewCertName]),
- add_critical_netscape_cert_type(ServerCertFile, NewServerCertFile, KeyFile),
- NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
-
- ClientCertFile = proplists:get_value(certfile, ClientOpts),
- NewClientCertFile = filename:join([PrivDir, "client", NewCertName]),
- add_critical_netscape_cert_type(ClientCertFile, NewClientCertFile, KeyFile),
- NewClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts)],
-
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server(
[{node, ServerNode}, {port, 0},
{from, self()},
{mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{verify, verify_none}, {active, Active} | NewServerOpts]}]),
+ {options, [{verify, verify_none}, {active, Active} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client(
[{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
{mfa, {ssl_test_lib, ReceiveFunction, []}},
- {options, [{verify, verify_none}, {active, Active} | NewClientOpts]}]),
+ {options, [{verify, verify_none}, {active, Active} | ClientOpts]}]),
%% This certificate has a critical extension that we don't
%% understand. But we're using `verify_none', so verification
@@ -821,28 +769,7 @@ critical_extension_verify_none(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- ok.
-
-add_critical_netscape_cert_type(CertFile, NewCertFile, KeyFile) ->
- [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
-
- [{'Certificate', DerCert, _}] = ssl_test_lib:pem_to_der(CertFile),
- OTPCert = public_key:pkix_decode_cert(DerCert, otp),
- %% This is the "Netscape Cert Type" extension, telling us that the
- %% certificate can be used for SSL clients and SSL servers.
- NetscapeCertTypeExt = #'Extension'{
- extnID = {2,16,840,1,113730,1,1},
- critical = true,
- extnValue = <<3,2,6,192>>},
- OTPTbsCert = OTPCert#'OTPCertificate'.tbsCertificate,
- Extensions = OTPTbsCert#'OTPTBSCertificate'.extensions,
- NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{
- extensions = [NetscapeCertTypeExt] ++ Extensions},
- NewDerCert = public_key:pkix_sign(NewOTPTbsCert, Key),
- ssl_test_lib:der_to_pem(NewCertFile, [{'Certificate', NewDerCert, not_encrypted}]),
- ok.
+ ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
no_authority_key_identifier() ->
@@ -850,35 +777,21 @@ no_authority_key_identifier() ->
" but are present in trusted certs db."}].
no_authority_key_identifier(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
-
- KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
- [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
-
- CertFile = proplists:get_value(certfile, ServerOpts),
- NewCertFile = filename:join(PrivDir, "server/new_cert.pem"),
- [{'Certificate', DerCert, _}] = ssl_test_lib:pem_to_der(CertFile),
- OTPCert = public_key:pkix_decode_cert(DerCert, otp),
- OTPTbsCert = OTPCert#'OTPCertificate'.tbsCertificate,
- Extensions = OTPTbsCert#'OTPTBSCertificate'.extensions,
- NewExtensions = delete_authority_key_extension(Extensions, []),
- NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{extensions = NewExtensions},
-
- ct:log("Extensions ~p~n, NewExtensions: ~p~n", [Extensions, NewExtensions]),
-
- NewDerCert = public_key:pkix_sign(NewOTPTbsCert, Key),
- ssl_test_lib:der_to_pem(NewCertFile, [{'Certificate', NewDerCert, not_encrypted}]),
- NewServerOpts = [{certfile, NewCertFile} | proplists:delete(certfile, ServerOpts)],
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_peer_opts,
+ [{extensions, [{auth_key_id, undefined}]
+ }]},
+ {client_peer_opts,
+ [{extensions, [{auth_key_id, undefined}]
+ }]}], Config, "_peer_no_auth_key_id"),
+ ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
+ ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
{mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, NewServerOpts}]),
+ {options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -894,53 +807,35 @@ no_authority_key_identifier(Config) when is_list(Config) ->
delete_authority_key_extension([], Acc) ->
lists:reverse(Acc);
delete_authority_key_extension([#'Extension'{extnID = ?'id-ce-authorityKeyIdentifier'} | Rest],
- Acc) ->
+ Acc) ->
delete_authority_key_extension(Rest, Acc);
delete_authority_key_extension([Head | Rest], Acc) ->
delete_authority_key_extension(Rest, [Head | Acc]).
%%--------------------------------------------------------------------
-no_authority_key_identifier_and_nonstandard_encoding() ->
- [{doc, "Test cert with nonstandard encoding that does not have"
- " authorityKeyIdentifier extension but are present in trusted certs db."}].
-
-no_authority_key_identifier_and_nonstandard_encoding(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
- PrivDir = proplists:get_value(priv_dir, Config),
-
- KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
- [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
- Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
-
- CertFile = proplists:get_value(certfile, ServerOpts),
- NewCertFile = filename:join(PrivDir, "server/new_cert.pem"),
- [{'Certificate', DerCert, _}] = ssl_test_lib:pem_to_der(CertFile),
- ServerCert = public_key:pkix_decode_cert(DerCert, plain),
- ServerTbsCert = ServerCert#'Certificate'.tbsCertificate,
- Extensions0 = ServerTbsCert#'TBSCertificate'.extensions,
- %% need to remove authorityKeyIdentifier extension to cause DB lookup by signature
- Extensions = delete_authority_key_extension(Extensions0, []),
- NewExtensions = replace_key_usage_extension(Extensions, []),
- NewServerTbsCert = ServerTbsCert#'TBSCertificate'{extensions = NewExtensions},
-
- ct:log("Extensions ~p~n, NewExtensions: ~p~n", [Extensions, NewExtensions]),
-
- TbsDer = public_key:pkix_encode('TBSCertificate', NewServerTbsCert, plain),
- Sig = public_key:sign(TbsDer, md5, Key),
- NewServerCert = ServerCert#'Certificate'{tbsCertificate = NewServerTbsCert, signature = Sig},
- NewDerCert = public_key:pkix_encode('Certificate', NewServerCert, plain),
- ssl_test_lib:der_to_pem(NewCertFile, [{'Certificate', NewDerCert, not_encrypted}]),
- NewServerOpts = [{certfile, NewCertFile} | proplists:delete(certfile, ServerOpts)],
-
+no_authority_key_identifier_keyEncipherment() ->
+ [{doc, "Test cert with keyEncipherment key_usage an no"
+ " authorityKeyIdentifier extension, but are present in trusted certs db."}].
+
+no_authority_key_identifier_keyEncipherment(Config) when is_list(Config) ->
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_peer_opts,
+ [{extensions, [{auth_key_id, undefined},
+ {key_usage, [digitalSignature,
+ keyEncipherment]}]
+ }]},
+ {client_peer_opts,
+ [{extensions, [{auth_key_id, undefined}]
+ }]}], Config, "_peer_keyEncipherment"),
+ ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
+ ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
{mfa, {ssl_test_lib,
send_recv_result_active, []}},
- {options, [{active, true} | NewServerOpts]}]),
+ {options, [{active, true} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -952,14 +847,6 @@ no_authority_key_identifier_and_nonstandard_encoding(Config) when is_list(Config
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-replace_key_usage_extension([], Acc) ->
- lists:reverse(Acc);
-replace_key_usage_extension([#'Extension'{extnID = ?'id-ce-keyUsage'} = E | Rest], Acc) ->
- %% A nonstandard DER encoding of [digitalSignature, keyEncipherment]
- Val = <<3, 2, 0, 16#A0>>,
- replace_key_usage_extension(Rest, [E#'Extension'{extnValue = Val} | Acc]);
-replace_key_usage_extension([Head | Rest], Acc) ->
- replace_key_usage_extension(Rest, [Head | Acc]).
%%--------------------------------------------------------------------
@@ -967,16 +854,16 @@ invalid_signature_server() ->
[{doc,"Test client with invalid signature"}].
invalid_signature_server(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
PrivDir = proplists:get_value(priv_dir, Config),
- KeyFile = filename:join(PrivDir, "server/key.pem"),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
[KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
ServerCertFile = proplists:get_value(certfile, ServerOpts),
- NewServerCertFile = filename:join(PrivDir, "server/invalid_cert.pem"),
+ NewServerCertFile = filename:join(PrivDir, "server_invalid_cert.pem"),
[{'Certificate', ServerDerCert, _}] = ssl_test_lib:pem_to_der(ServerCertFile),
ServerOTPCert = public_key:pkix_decode_cert(ServerDerCert, otp),
ServerOTPTbsCert = ServerOTPCert#'OTPCertificate'.tbsCertificate,
@@ -995,8 +882,8 @@ invalid_signature_server(Config) when is_list(Config) ->
{from, self()},
{options, [{verify, verify_peer} | ClientOpts]}]),
- tcp_delivery_workaround(Server, {error, {tls_alert, "bad certificate"}},
- Client, {error, {tls_alert, "bad certificate"}}).
+ tcp_delivery_workaround(Server, {error, {tls_alert, "unknown ca"}},
+ Client, {error, {tls_alert, "unknown ca"}}).
%%--------------------------------------------------------------------
@@ -1004,16 +891,16 @@ invalid_signature_client() ->
[{doc,"Test server with invalid signature"}].
invalid_signature_client(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
PrivDir = proplists:get_value(priv_dir, Config),
- KeyFile = filename:join(PrivDir, "client/key.pem"),
+ KeyFile = proplists:get_value(keyfile, ClientOpts),
[KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
Key = ssl_test_lib:public_key(public_key:pem_entry_decode(KeyEntry)),
ClientCertFile = proplists:get_value(certfile, ClientOpts),
- NewClientCertFile = filename:join(PrivDir, "client/invalid_cert.pem"),
+ NewClientCertFile = filename:join(PrivDir, "client_invalid_cert.pem"),
[{'Certificate', ClientDerCert, _}] = ssl_test_lib:pem_to_der(ClientCertFile),
ClientOTPCert = public_key:pkix_decode_cert(ClientDerCert, otp),
ClientOTPTbsCert = ClientOTPCert#'OTPCertificate'.tbsCertificate,
@@ -1032,8 +919,8 @@ invalid_signature_client(Config) when is_list(Config) ->
{from, self()},
{options, NewClientOpts}]),
- tcp_delivery_workaround(Server, {error, {tls_alert, "bad certificate"}},
- Client, {error, {tls_alert, "bad certificate"}}).
+ tcp_delivery_workaround(Server, {error, {tls_alert, "unknown ca"}},
+ Client, {error, {tls_alert, "unknown ca"}}).
%%--------------------------------------------------------------------
@@ -1042,15 +929,23 @@ client_with_cert_cipher_suites_handshake() ->
[{doc, "Test that client with a certificate without keyEncipherment usage "
" extension can connect to a server with restricted cipher suites "}].
client_with_cert_cipher_suites_handshake(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_verification_opts_digital_signature_only, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{client_peer_opts,
+ [{extensions,
+ [{key_usage, [digitalSignature]}]
+ }]}], Config, "_sign_only_extensions"),
+
+
+ ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
+ ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
+
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
{mfa, {ssl_test_lib,
send_recv_result_active, []}},
{options, [{active, true},
- {ciphers, ssl_test_lib:rsa_non_signed_suites()}
+ {ciphers,
+ ssl_test_lib:rsa_non_signed_suites(proplists:get_value(version, Config))}
| ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
@@ -1070,7 +965,7 @@ client_with_cert_cipher_suites_handshake(Config) when is_list(Config) ->
server_verify_no_cacerts() ->
[{doc,"Test server must have cacerts if it wants to verify client"}].
server_verify_no_cacerts(Config) when is_list(Config) ->
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ ServerOpts = proplists:delete(cacertfile, ssl_test_lib:ssl_options(server_rsa_opts, Config)),
{_, ServerNode, _} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
@@ -1084,8 +979,8 @@ server_verify_no_cacerts(Config) when is_list(Config) ->
unknown_server_ca_fail() ->
[{doc,"Test that the client fails if the ca is unknown in verify_peer mode"}].
unknown_server_ca_fail(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(empty_client_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
@@ -1128,8 +1023,8 @@ unknown_server_ca_fail(Config) when is_list(Config) ->
unknown_server_ca_accept_verify_none() ->
[{doc,"Test that the client succeds if the ca is unknown in verify_none mode"}].
unknown_server_ca_accept_verify_none(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(empty_client_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
@@ -1153,8 +1048,8 @@ unknown_server_ca_accept_verify_peer() ->
[{doc, "Test that the client succeds if the ca is unknown in verify_peer mode"
" with a verify_fun that accepts the unknown ca error"}].
unknown_server_ca_accept_verify_peer(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(empty_client_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
@@ -1192,8 +1087,8 @@ unknown_server_ca_accept_verify_peer(Config) when is_list(Config) ->
unknown_server_ca_accept_backwardscompatibility() ->
[{doc,"Test that old style verify_funs will work"}].
unknown_server_ca_accept_backwardscompatibility(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_verification_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(empty_client_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
diff --git a/lib/ssl/test/ssl_crl_SUITE.erl b/lib/ssl/test/ssl_crl_SUITE.erl
index 00636e5660..e293d183f7 100644
--- a/lib/ssl/test/ssl_crl_SUITE.erl
+++ b/lib/ssl/test/ssl_crl_SUITE.erl
@@ -72,7 +72,7 @@ init_per_suite(Config) ->
false ->
{skip, io_lib:format("Bad openssl version: ~p",[OpenSSL_version])};
_ ->
- catch crypto:stop(),
+ end_per_suite(Config),
try crypto:start() of
ok ->
{ok, Hostname0} = inet:gethostname(),
@@ -99,32 +99,37 @@ init_per_group(check_peer, Config) ->
init_per_group(check_best_effort, Config) ->
[{crl_check, best_effort} | Config];
init_per_group(Group, Config0) ->
- case is_idp(Group) of
- true ->
- [{idp_crl, true} | Config0];
- false ->
- DataDir = proplists:get_value(data_dir, Config0),
- CertDir = filename:join(proplists:get_value(priv_dir, Config0), Group),
- {CertOpts, Config} = init_certs(CertDir, Group, Config0),
- {ok, _} = make_certs:all(DataDir, CertDir, CertOpts),
- case Group of
- crl_hash_dir ->
- CrlDir = filename:join(CertDir, "crls"),
- %% Copy CRLs to their hashed filenames.
- %% Find the hashes with 'openssl crl -noout -hash -in crl.pem'.
- populate_crl_hash_dir(CertDir, CrlDir,
- [{"erlangCA", "d6134ed3"},
- {"otpCA", "d4c8d7e5"}],
- replace),
- CrlCacheOpts = [{crl_cache,
- {ssl_crl_hash_dir,
- {internal, [{dir, CrlDir}]}}}];
- _ ->
- CrlCacheOpts = []
- end,
- [{crl_cache_opts, CrlCacheOpts},
- {cert_dir, CertDir},
- {idp_crl, false} | Config]
+ try
+ case is_idp(Group) of
+ true ->
+ [{idp_crl, true} | Config0];
+ false ->
+ DataDir = proplists:get_value(data_dir, Config0),
+ CertDir = filename:join(proplists:get_value(priv_dir, Config0), Group),
+ {CertOpts, Config} = init_certs(CertDir, Group, Config0),
+ {ok, _} = make_certs:all(DataDir, CertDir, CertOpts),
+ CrlCacheOpts = case Group of
+ crl_hash_dir ->
+ CrlDir = filename:join(CertDir, "crls"),
+ %% Copy CRLs to their hashed filenames.
+ %% Find the hashes with 'openssl crl -noout -hash -in crl.pem'.
+ populate_crl_hash_dir(CertDir, CrlDir,
+ [{"erlangCA", "d6134ed3"},
+ {"otpCA", "d4c8d7e5"}],
+ replace),
+ [{crl_cache,
+ {ssl_crl_hash_dir,
+ {internal, [{dir, CrlDir}]}}}];
+ _ ->
+ []
+ end,
+ [{crl_cache_opts, CrlCacheOpts},
+ {cert_dir, CertDir},
+ {idp_crl, false} | Config]
+ end
+ catch
+ _:_ ->
+ {skip, "Unable to create crls"}
end.
end_per_group(_GroupName, Config) ->
@@ -136,7 +141,7 @@ init_per_testcase(Case, Config0) ->
true ->
end_per_testcase(Case, Config0),
inets:start(),
- ssl:start(),
+ ssl_test_lib:clean_start(),
ServerRoot = make_dir_path([proplists:get_value(priv_dir, Config0), idp_crl, tmp]),
%% start a HTTP server to serve the CRLs
{ok, Httpd} = inets:start(httpd, [{ipfamily, proplists:get_value(ipfamily, Config0)},
@@ -155,7 +160,7 @@ init_per_testcase(Case, Config0) ->
[{cert_dir, CertDir} | Config];
false ->
end_per_testcase(Case, Config0),
- ssl:start(),
+ ssl_test_lib:clean_start(),
Config0
end.
@@ -187,7 +192,7 @@ crl_verify_valid(Config) when is_list(Config) ->
{crl_cache, {ssl_crl_cache, {internal, [{http, 5000}]}}},
{verify, verify_peer}];
false ->
- ?config(crl_cache_opts, Config) ++
+ proplists:get_value(crl_cache_opts, Config) ++
[{cacertfile, filename:join([PrivDir, "server", "cacerts.pem"])},
{crl_check, Check},
{verify, verify_peer}]
@@ -220,7 +225,7 @@ crl_verify_revoked(Config) when is_list(Config) ->
{crl_check, Check},
{verify, verify_peer}];
false ->
- ?config(crl_cache_opts, Config) ++
+ proplists:get_value(crl_cache_opts, Config) ++
[{cacertfile, filename:join([PrivDir, "revoked", "cacerts.pem"])},
{crl_check, Check},
{verify, verify_peer}]
@@ -279,8 +284,8 @@ crl_verify_no_crl(Config) when is_list(Config) ->
crl_hash_dir_collision() ->
[{doc,"Verify ssl_crl_hash_dir behaviour with hash collisions"}].
crl_hash_dir_collision(Config) when is_list(Config) ->
- PrivDir = ?config(cert_dir, Config),
- Check = ?config(crl_check, Config),
+ PrivDir = proplists:get_value(cert_dir, Config),
+ Check = proplists:get_value(crl_check, Config),
%% Create two CAs whose names hash to the same value
CA1 = "hash-collision-0000000000",
@@ -307,13 +312,17 @@ crl_hash_dir_collision(Config) when is_list(Config) ->
{CA2, "b68fc624"}],
replace),
- ClientOpts = ?config(crl_cache_opts, Config) ++
- [{cacertfile, filename:join([PrivDir, "erlangCA", "cacerts.pem"])},
+ NewCA = new_ca(filename:join([PrivDir, "new_ca"]),
+ filename:join([PrivDir, "erlangCA", "cacerts.pem"]),
+ filename:join([PrivDir, "server", "cacerts.pem"])),
+
+ ClientOpts = proplists:get_value(crl_cache_opts, Config) ++
+ [{cacertfile, NewCA},
{crl_check, Check},
{verify, verify_peer}],
-
+
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
-
+
%% Neither certificate revoked; both succeed.
crl_verify_valid(Hostname, ServerNode, ServerOpts1, ClientNode, ClientOpts),
crl_verify_valid(Hostname, ServerNode, ServerOpts2, ClientNode, ClientOpts),
@@ -346,8 +355,8 @@ crl_hash_dir_collision(Config) when is_list(Config) ->
crl_hash_dir_expired() ->
[{doc,"Verify ssl_crl_hash_dir behaviour with expired CRLs"}].
crl_hash_dir_expired(Config) when is_list(Config) ->
- PrivDir = ?config(cert_dir, Config),
- Check = ?config(crl_check, Config),
+ PrivDir = proplists:get_value(cert_dir, Config),
+ Check = proplists:get_value(crl_check, Config),
CA = "CRL-maybe-expired-CA",
%% Add "issuing distribution point", to ensure that verification
@@ -362,7 +371,7 @@ crl_hash_dir_expired(Config) when is_list(Config) ->
ServerOpts = [{keyfile, filename:join([PrivDir, EndUser, "key.pem"])},
{certfile, filename:join([PrivDir, EndUser, "cert.pem"])},
{cacertfile, filename:join([PrivDir, EndUser, "cacerts.pem"])}],
- ClientOpts = ?config(crl_cache_opts, Config) ++
+ ClientOpts = proplists:get_value(crl_cache_opts, Config) ++
[{cacertfile, filename:join([PrivDir, CA, "cacerts.pem"])},
{crl_check, Check},
{verify, verify_peer}],
@@ -492,3 +501,12 @@ find_free_name(CrlDir, Hash, N) ->
false ->
Name
end.
+
+new_ca(FileName, CA1, CA2) ->
+ {ok, P1} = file:read_file(CA1),
+ E1 = public_key:pem_decode(P1),
+ {ok, P2} = file:read_file(CA2),
+ E2 = public_key:pem_decode(P2),
+ Pem = public_key:pem_encode(E1 ++E2),
+ file:write_file(FileName, Pem),
+ FileName.
diff --git a/lib/ssl/test/ssl_dist_SUITE.erl b/lib/ssl/test/ssl_dist_SUITE.erl
index 5ebf9bb2de..8740e8c8f0 100644
--- a/lib/ssl/test/ssl_dist_SUITE.erl
+++ b/lib/ssl/test/ssl_dist_SUITE.erl
@@ -109,11 +109,11 @@ common_end(_, _Config) ->
basic() ->
[{doc,"Test that two nodes can connect via ssl distribution"}].
basic(Config) when is_list(Config) ->
- NH1 = start_ssl_node(Config),
+ gen_dist_test(basic_test, Config).
+
+basic_test(NH1, NH2, _) ->
Node1 = NH1#node_handle.nodename,
- NH2 = start_ssl_node(Config),
Node2 = NH2#node_handle.nodename,
-
pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
[Node2] = apply_on_ssl_node(NH1, fun () -> nodes() end),
@@ -161,18 +161,16 @@ basic(Config) when is_list(Config) ->
ok
end
end)
- end,
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
+ end.
%%--------------------------------------------------------------------
payload() ->
[{doc,"Test that send a lot of data between the ssl distributed noes"}].
payload(Config) when is_list(Config) ->
- NH1 = start_ssl_node(Config),
+ gen_dist_test(payload_test, Config).
+
+payload_test(NH1, NH2, _) ->
Node1 = NH1#node_handle.nodename,
- NH2 = start_ssl_node(Config),
Node2 = NH2#node_handle.nodename,
pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
@@ -204,10 +202,8 @@ payload(Config) when is_list(Config) ->
ok
end
end)
- end,
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
+ end.
+
%%--------------------------------------------------------------------
plain_options() ->
[{doc,"Test specifying additional options"}].
@@ -218,20 +214,17 @@ plain_options(Config) when is_list(Config) ->
"client_verify verify_none server_verify verify_none "
"server_depth 1 client_depth 1 "
"server_hibernate_after 500 client_hibernate_after 500",
+ gen_dist_test(plain_options_test, [{additional_dist_opts, DistOpts} | Config]).
- NH1 = start_ssl_node([{additional_dist_opts, DistOpts} | Config]),
+plain_options_test(NH1, NH2, _) ->
Node1 = NH1#node_handle.nodename,
- NH2 = start_ssl_node([{additional_dist_opts, DistOpts} | Config]),
Node2 = NH2#node_handle.nodename,
pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
[Node2] = apply_on_ssl_node(NH1, fun () -> nodes() end),
- [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end),
+ [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end).
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
%%--------------------------------------------------------------------
plain_verify_options() ->
[{doc,"Test specifying additional options"}].
@@ -240,20 +233,18 @@ plain_verify_options(Config) when is_list(Config) ->
"client_secure_renegotiate true "
"server_reuse_sessions true client_reuse_sessions true "
"server_hibernate_after 500 client_hibernate_after 500",
+ gen_dist_test(plain_verify_options_test, [{additional_dist_opts, DistOpts} | Config]).
- NH1 = start_ssl_node([{additional_dist_opts, DistOpts} | Config]),
+plain_verify_options_test(NH1, NH2, _) ->
Node1 = NH1#node_handle.nodename,
- NH2 = start_ssl_node([{additional_dist_opts, DistOpts} | Config]),
Node2 = NH2#node_handle.nodename,
-
+
pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
-
+
[Node2] = apply_on_ssl_node(NH1, fun () -> nodes() end),
- [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end),
+ [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end).
+
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
%%--------------------------------------------------------------------
nodelay_option() ->
[{doc,"Test specifying dist_nodelay option"}].
@@ -265,6 +256,7 @@ nodelay_option(Config) ->
after
application:unset_env(kernel, dist_nodelay)
end.
+%%--------------------------------------------------------------------
listen_port_options() ->
[{doc, "Test specifying listening ports"}].
@@ -285,32 +277,39 @@ listen_port_options(Config) when is_list(Config) ->
#node_handle{} ->
%% If the node was able to start, it didn't take the port
%% option into account.
+ stop_ssl_node(NH1),
exit(unexpected_success)
catch
exit:{accept_failed, timeout} ->
%% The node failed to start, as expected.
ok
end,
-
+
%% Try again, now specifying a high max port.
PortOpt2 = "-kernel inet_dist_listen_min " ++ integer_to_list(Port1) ++
- " inet_dist_listen_max 65535",
+ " inet_dist_listen_max 65535",
NH2 = start_ssl_node([{additional_dist_opts, PortOpt2} | Config]),
- Node2 = NH2#node_handle.nodename,
- Name2 = lists:takewhile(fun(C) -> C =/= $@ end, atom_to_list(Node2)),
- {ok, NodesPorts2} = apply_on_ssl_node(NH2, fun net_adm:names/0),
- {Name2, Port2} = lists:keyfind(Name2, 1, NodesPorts2),
-
- %% The new port should be higher:
- if Port2 > Port1 ->
- ok;
- true ->
- error({port, Port2, not_higher_than, Port1})
+
+ try
+ Node2 = NH2#node_handle.nodename,
+ Name2 = lists:takewhile(fun(C) -> C =/= $@ end, atom_to_list(Node2)),
+ {ok, NodesPorts2} = apply_on_ssl_node(NH2, fun net_adm:names/0),
+ {Name2, Port2} = lists:keyfind(Name2, 1, NodesPorts2),
+
+ %% The new port should be higher:
+ if Port2 > Port1 ->
+ ok;
+ true ->
+ error({port, Port2, not_higher_than, Port1})
+ end
+ catch
+ _:Reason ->
+ stop_ssl_node(NH2),
+ ct:fail(Reason)
end,
-
- stop_ssl_node(NH1),
stop_ssl_node(NH2),
success(Config).
+
%%--------------------------------------------------------------------
listen_options() ->
[{doc, "Test inet_dist_listen_options"}].
@@ -329,28 +328,25 @@ do_listen_options(Prio, Config) ->
end,
Options = "-kernel inet_dist_listen_options " ++ PriorityString,
-
- NH1 = start_ssl_node([{additional_dist_opts, Options} | Config]),
- NH2 = start_ssl_node([{additional_dist_opts, Options} | Config]),
- Node2 = NH2#node_handle.nodename,
-
+ gen_dist_test(listen_options_test, [{prio, Prio}, {additional_dist_opts, Options} | Config]).
+
+listen_options_test(NH1, NH2, Config) ->
+ Prio = proplists:get_value(prio, Config),
+ Node2 = NH2#node_handle.nodename,
pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
PrioritiesNode1 =
apply_on_ssl_node(NH1, fun get_socket_priorities/0),
PrioritiesNode2 =
apply_on_ssl_node(NH2, fun get_socket_priorities/0),
-
+
Elevated1 = [P || P <- PrioritiesNode1, P =:= Prio],
- ?t:format("Elevated1: ~p~n", [Elevated1]),
+ ct:pal("Elevated1: ~p~n", [Elevated1]),
Elevated2 = [P || P <- PrioritiesNode2, P =:= Prio],
- ?t:format("Elevated2: ~p~n", [Elevated2]),
+ ct:pal("Elevated2: ~p~n", [Elevated2]),
[_|_] = Elevated1,
- [_|_] = Elevated2,
+ [_|_] = Elevated2.
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
%%--------------------------------------------------------------------
connect_options() ->
[{doc, "Test inet_dist_connect_options"}].
@@ -369,9 +365,11 @@ do_connect_options(Prio, Config) ->
end,
Options = "-kernel inet_dist_connect_options " ++ PriorityString,
+ gen_dist_test(connect_options_test,
+ [{prio, Prio}, {additional_dist_opts, Options} | Config]).
- NH1 = start_ssl_node([{additional_dist_opts, Options} | Config]),
- NH2 = start_ssl_node([{additional_dist_opts, Options} | Config]),
+connect_options_test(NH1, NH2, Config) ->
+ Prio = proplists:get_value(prio, Config),
Node2 = NH2#node_handle.nodename,
pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
@@ -382,17 +380,14 @@ do_connect_options(Prio, Config) ->
apply_on_ssl_node(NH2, fun get_socket_priorities/0),
Elevated1 = [P || P <- PrioritiesNode1, P =:= Prio],
- ?t:format("Elevated1: ~p~n", [Elevated1]),
+ ct:pal("Elevated1: ~p~n", [Elevated1]),
Elevated2 = [P || P <- PrioritiesNode2, P =:= Prio],
- ?t:format("Elevated2: ~p~n", [Elevated2]),
+ ct:pal("Elevated2: ~p~n", [Elevated2]),
%% Node 1 will have a socket with elevated priority.
[_|_] = Elevated1,
%% Node 2 will not, since it only applies to outbound connections.
- [] = Elevated2,
+ [] = Elevated2.
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
%%--------------------------------------------------------------------
use_interface() ->
[{doc, "Test inet_dist_use_interface"}].
@@ -403,22 +398,28 @@ use_interface(Config) when is_list(Config) ->
%% Start a node, and get the port number it's listening on.
NH1 = start_ssl_node([{additional_dist_opts, Options} | Config]),
- Node1 = NH1#node_handle.nodename,
- Name = lists:takewhile(fun(C) -> C =/= $@ end, atom_to_list(Node1)),
- {ok, NodesPorts} = apply_on_ssl_node(NH1, fun net_adm:names/0),
- {Name, Port} = lists:keyfind(Name, 1, NodesPorts),
-
- %% Now find the socket listening on that port, and check its sockname.
- Sockets = apply_on_ssl_node(
- NH1,
- fun() ->
- [inet:sockname(P) ||
- P <- inet_ports(),
- {ok, Port} =:= (catch inet:port(P))]
- end),
- %% And check that it's actually listening on localhost.
- [{ok,{{127,0,0,1},Port}}] = Sockets,
-
+
+ try
+ Node1 = NH1#node_handle.nodename,
+ Name = lists:takewhile(fun(C) -> C =/= $@ end, atom_to_list(Node1)),
+ {ok, NodesPorts} = apply_on_ssl_node(NH1, fun net_adm:names/0),
+ {Name, Port} = lists:keyfind(Name, 1, NodesPorts),
+
+ %% Now find the socket listening on that port, and check its sockname.
+ Sockets = apply_on_ssl_node(
+ NH1,
+ fun() ->
+ [inet:sockname(P) ||
+ P <- inet_ports(),
+ {ok, Port} =:= (catch inet:port(P))]
+ end),
+ %% And check that it's actually listening on localhost.
+ [{ok,{{127,0,0,1},Port}}] = Sockets
+ catch
+ _:Reason ->
+ stop_ssl_node(NH1),
+ ct:fail(Reason)
+ end,
stop_ssl_node(NH1),
success(Config).
%%--------------------------------------------------------------------
@@ -430,11 +431,11 @@ verify_fun_fail(Config) when is_list(Config) ->
"\"{ssl_dist_SUITE,verify_fail_always,{}}\" "
"client_verify verify_peer client_verify_fun "
"\"{ssl_dist_SUITE,verify_fail_always,{}}\" ",
+ gen_dist_test(verify_fun_fail_test, [{additional_dist_opts, DistOpts} | Config]).
- NH1 = start_ssl_node([{additional_dist_opts, DistOpts} | Config]),
- NH2 = start_ssl_node([{additional_dist_opts, DistOpts} | Config]),
+verify_fun_fail_test(NH1, NH2, _) ->
Node2 = NH2#node_handle.nodename,
-
+
pang = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
[] = apply_on_ssl_node(NH1, fun () -> nodes() end),
@@ -446,25 +447,9 @@ verify_fun_fail(Config) when is_list(Config) ->
%% On the server node, it wouldn't run, because the server didn't
%% request a certificate from the client.
undefined =
- apply_on_ssl_node(NH2, fun () -> ets:info(verify_fun_ran) end),
+ apply_on_ssl_node(NH2, fun () -> ets:info(verify_fun_ran) end).
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
-verify_fail_always(_Certificate, _Event, _State) ->
- %% Create an ETS table, to record the fact that the verify function ran.
- %% Spawn a new process, to avoid the ETS table disappearing.
- Parent = self(),
- spawn(
- fun() ->
- ets:new(verify_fun_ran, [public, named_table]),
- ets:insert(verify_fun_ran, {verify_fail_always_ran, true}),
- Parent ! go_ahead,
- timer:sleep(infinity)
- end),
- receive go_ahead -> ok end,
- {fail, bad_certificate}.
%%--------------------------------------------------------------------
verify_fun_pass() ->
@@ -476,10 +461,10 @@ verify_fun_pass(Config) when is_list(Config) ->
"server_fail_if_no_peer_cert true "
"client_verify verify_peer client_verify_fun "
"\"{ssl_dist_SUITE,verify_pass_always,{}}\" ",
+ gen_dist_test(verify_fun_pass_test, [{additional_dist_opts, DistOpts} | Config]).
- NH1 = start_ssl_node([{additional_dist_opts, DistOpts} | Config]),
+verify_fun_pass_test(NH1, NH2, _) ->
Node1 = NH1#node_handle.nodename,
- NH2 = start_ssl_node([{additional_dist_opts, DistOpts} | Config]),
Node2 = NH2#node_handle.nodename,
pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
@@ -494,25 +479,8 @@ verify_fun_pass(Config) when is_list(Config) ->
%% requested and verified the client's certificate because we
%% passed fail_if_no_peer_cert.
[{verify_pass_always_ran, true}] =
- apply_on_ssl_node(NH2, fun () -> ets:tab2list(verify_fun_ran) end),
+ apply_on_ssl_node(NH2, fun () -> ets:tab2list(verify_fun_ran) end).
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
-
-verify_pass_always(_Certificate, _Event, State) ->
- %% Create an ETS table, to record the fact that the verify function ran.
- %% Spawn a new process, to avoid the ETS table disappearing.
- Parent = self(),
- spawn(
- fun() ->
- ets:new(verify_fun_ran, [public, named_table]),
- ets:insert(verify_fun_ran, {verify_pass_always_ran, true}),
- Parent ! go_ahead,
- timer:sleep(infinity)
- end),
- receive go_ahead -> ok end,
- {valid, State}.
%%--------------------------------------------------------------------
crl_check_pass() ->
[{doc,"Test crl_check with non-revoked certificate"}].
@@ -520,10 +488,10 @@ crl_check_pass(Config) when is_list(Config) ->
DistOpts = "-ssl_dist_opt client_crl_check true",
NewConfig =
[{many_verify_opts, true}, {additional_dist_opts, DistOpts}] ++ Config,
+ gen_dist_test(crl_check_pass_test, NewConfig).
- NH1 = start_ssl_node(NewConfig),
+crl_check_pass_test(NH1, NH2, Config) ->
Node1 = NH1#node_handle.nodename,
- NH2 = start_ssl_node(NewConfig),
Node2 = NH2#node_handle.nodename,
PrivDir = ?config(priv_dir, Config),
@@ -533,11 +501,7 @@ crl_check_pass(Config) when is_list(Config) ->
pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
[Node2] = apply_on_ssl_node(NH1, fun () -> nodes() end),
- [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end),
-
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
+ [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end).
%%--------------------------------------------------------------------
crl_check_fail() ->
@@ -549,10 +513,9 @@ crl_check_fail(Config) when is_list(Config) ->
%% The server uses a revoked certificate.
{server_cert_dir, "revoked"},
{additional_dist_opts, DistOpts}] ++ Config,
+ gen_dist_test(crl_check_fail_test, NewConfig).
- NH1 = start_ssl_node(NewConfig),
- %%Node1 = NH1#node_handle.nodename,
- NH2 = start_ssl_node(NewConfig),
+crl_check_fail_test(NH1, NH2, Config) ->
Node2 = NH2#node_handle.nodename,
PrivDir = ?config(priv_dir, Config),
@@ -562,11 +525,7 @@ crl_check_fail(Config) when is_list(Config) ->
pang = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
[] = apply_on_ssl_node(NH1, fun () -> nodes() end),
- [] = apply_on_ssl_node(NH2, fun () -> nodes() end),
-
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
+ [] = apply_on_ssl_node(NH2, fun () -> nodes() end).
%%--------------------------------------------------------------------
crl_check_best_effort() ->
@@ -576,22 +535,18 @@ crl_check_best_effort(Config) when is_list(Config) ->
"server_verify verify_peer server_crl_check best_effort",
NewConfig =
[{many_verify_opts, true}, {additional_dist_opts, DistOpts}] ++ Config,
+ gen_dist_test(crl_check_best_effort_test, NewConfig).
+crl_check_best_effort_test(NH1, NH2, _Config) ->
%% We don't have the correct CRL at hand, but since crl_check is
%% best_effort, we accept it anyway.
- NH1 = start_ssl_node(NewConfig),
Node1 = NH1#node_handle.nodename,
- NH2 = start_ssl_node(NewConfig),
Node2 = NH2#node_handle.nodename,
pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
[Node2] = apply_on_ssl_node(NH1, fun () -> nodes() end),
- [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end),
-
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
+ [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end).
%%--------------------------------------------------------------------
crl_cache_check_pass() ->
@@ -605,20 +560,16 @@ crl_cache_check_pass(Config) when is_list(Config) ->
"\"{ssl_dist_SUITE,{\\\"" ++ NodeDir ++ "\\\",[]}}\"",
NewConfig =
[{many_verify_opts, true}, {additional_dist_opts, DistOpts}] ++ Config,
+ gen_dist_test(crl_cache_check_pass_test, NewConfig).
- NH1 = start_ssl_node(NewConfig),
+crl_cache_check_pass_test(NH1, NH2, _) ->
Node1 = NH1#node_handle.nodename,
- NH2 = start_ssl_node(NewConfig),
Node2 = NH2#node_handle.nodename,
pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
[Node2] = apply_on_ssl_node(NH1, fun () -> nodes() end),
- [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end),
-
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
+ [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end).
%%--------------------------------------------------------------------
crl_cache_check_fail() ->
@@ -636,44 +587,31 @@ crl_cache_check_fail(Config) when is_list(Config) ->
{server_cert_dir, "revoked"},
{additional_dist_opts, DistOpts}] ++ Config,
- NH1 = start_ssl_node(NewConfig),
- NH2 = start_ssl_node(NewConfig),
- Node2 = NH2#node_handle.nodename,
+ gen_dist_test(crl_cache_check_fail_test, NewConfig).
+crl_cache_check_fail_test(NH1, NH2, _) ->
+ Node2 = NH2#node_handle.nodename,
pang = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
[] = apply_on_ssl_node(NH1, fun () -> nodes() end),
- [] = apply_on_ssl_node(NH2, fun () -> nodes() end),
-
- stop_ssl_node(NH1),
- stop_ssl_node(NH2),
- success(Config).
-
-%% ssl_crl_cache_api callbacks
-lookup(_DistributionPoint, _DbHandle) ->
- not_available.
-
-select({rdnSequence, NameParts}, {NodeDir, _}) ->
- %% Extract the CN from the issuer name...
- [CN] = [CN ||
- [#'AttributeTypeAndValue'{
- type = ?'id-at-commonName',
- value = <<_, _, CN/binary>>}] <- NameParts],
- %% ...and use that as the directory name to find the CRL.
- error_logger:info_report([{found_cn, CN}]),
- CRLFile = filename:join([NodeDir, CN, "crl.pem"]),
- {ok, PemBin} = file:read_file(CRLFile),
- PemEntries = public_key:pem_decode(PemBin),
- CRLs = [ CRL || {'CertificateList', CRL, not_encrypted}
- <- PemEntries],
- CRLs.
-
-fresh_crl(_DistributionPoint, CRL) ->
- CRL.
-
+ [] = apply_on_ssl_node(NH2, fun () -> nodes() end).
%%--------------------------------------------------------------------
%%% Internal functions -----------------------------------------------
%%--------------------------------------------------------------------
+gen_dist_test(Test, Config) ->
+ NH1 = start_ssl_node(Config),
+ NH2 = start_ssl_node(Config),
+ try
+ ?MODULE:Test(NH1, NH2, Config)
+ catch
+ _:Reason ->
+ stop_ssl_node(NH1),
+ stop_ssl_node(NH2),
+ ct:fail(Reason)
+ end,
+ stop_ssl_node(NH1),
+ stop_ssl_node(NH2),
+ success(Config).
%% ssl_node side api
%%
@@ -742,13 +680,15 @@ stop_ssl_node(#node_handle{connection_handler = Handler,
receive
{'DOWN', Mon, process, Handler, Reason} ->
case Reason of
- normal -> ok;
- _ -> exit(Reason)
+ normal ->
+ ok;
+ _ ->
+ ct:pal("Down ~p ~n", [Reason])
end
end;
Error ->
erlang:demonitor(Mon, [flush]),
- exit(Error)
+ ct:pal("Warning ~p ~n", [Error])
end.
start_ssl_node(Config) ->
@@ -1226,3 +1166,53 @@ vsn(App) ->
after
application:stop(ssl)
end.
+
+verify_fail_always(_Certificate, _Event, _State) ->
+ %% Create an ETS table, to record the fact that the verify function ran.
+ %% Spawn a new process, to avoid the ETS table disappearing.
+ Parent = self(),
+ spawn(
+ fun() ->
+ ets:new(verify_fun_ran, [public, named_table]),
+ ets:insert(verify_fun_ran, {verify_fail_always_ran, true}),
+ Parent ! go_ahead,
+ timer:sleep(infinity)
+ end),
+ receive go_ahead -> ok end,
+ {fail, bad_certificate}.
+
+verify_pass_always(_Certificate, _Event, State) ->
+ %% Create an ETS table, to record the fact that the verify function ran.
+ %% Spawn a new process, to avoid the ETS table disappearing.
+ Parent = self(),
+ spawn(
+ fun() ->
+ ets:new(verify_fun_ran, [public, named_table]),
+ ets:insert(verify_fun_ran, {verify_pass_always_ran, true}),
+ Parent ! go_ahead,
+ timer:sleep(infinity)
+ end),
+ receive go_ahead -> ok end,
+ {valid, State}.
+
+%% ssl_crl_cache_api callbacks
+lookup(_DistributionPoint, _DbHandle) ->
+ not_available.
+
+select({rdnSequence, NameParts}, {NodeDir, _}) ->
+ %% Extract the CN from the issuer name...
+ [CN] = [CN ||
+ [#'AttributeTypeAndValue'{
+ type = ?'id-at-commonName',
+ value = <<_, _, CN/binary>>}] <- NameParts],
+ %% ...and use that as the directory name to find the CRL.
+ error_logger:info_report([{found_cn, CN}]),
+ CRLFile = filename:join([NodeDir, CN, "crl.pem"]),
+ {ok, PemBin} = file:read_file(CRLFile),
+ PemEntries = public_key:pem_decode(PemBin),
+ CRLs = [ CRL || {'CertificateList', CRL, not_encrypted}
+ <- PemEntries],
+ CRLs.
+
+fresh_crl(_DistributionPoint, CRL) ->
+ CRL.
diff --git a/lib/ssl/test/ssl_handshake_SUITE.erl b/lib/ssl/test/ssl_handshake_SUITE.erl
index a671e3e307..9658cb5f56 100644
--- a/lib/ssl/test/ssl_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_handshake_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,6 +33,7 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
all() -> [decode_hello_handshake,
+ decode_hello_handshake_version_confusion,
decode_single_hello_extension_correctly,
decode_supported_elliptic_curves_hello_extension_correctly,
decode_unknown_hello_extension_correctly,
@@ -60,7 +61,7 @@ init_per_testcase(ignore_hassign_extension_pre_tls_1_2, Config0) ->
ok ->
case is_supported(sha512) of
true ->
- ssl:start(),
+ ssl_test_lib:clean_start(),
%% make rsa certs using oppenssl
{ok, _} = make_certs:all(proplists:get_value(data_dir, Config0),
proplists:get_value(priv_dir, Config0)),
@@ -106,6 +107,14 @@ decode_hello_handshake(_Config) ->
#renegotiation_info{renegotiated_connection = <<0>>}
= (Hello#server_hello.extensions)#hello_extensions.renegotiation_info.
+
+decode_hello_handshake_version_confusion(_) ->
+ HelloPacket = <<3,3,0,0,0,0,0,63,210,235,149,6,244,140,108,13,177,74,16,218,33,108,219,41,73,228,3,82,132,123,73,144,118,100,0,0,32,192,4,0,10,192,45,192,38,0,47,192,18,0,163,0,22,0,165,192,29,192,18,192,30,0,103,0,57,192,48,0,47,1,0>>,
+ Version = {3,3},
+ ClientHello = 1,
+ Hello = tls_handshake:decode_handshake({3,3}, ClientHello, HelloPacket, false),
+ Hello = tls_handshake:decode_handshake({3,3}, ClientHello, HelloPacket, true).
+
decode_single_hello_extension_correctly(_Config) ->
Renegotiation = <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(1), 0>>,
Extensions = ssl_handshake:decode_hello_extensions(Renegotiation),
diff --git a/lib/ssl/test/ssl_npn_handshake_SUITE.erl b/lib/ssl/test/ssl_npn_handshake_SUITE.erl
index c55fa73cfb..a02881f1ae 100644
--- a/lib/ssl/test/ssl_npn_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_npn_handshake_SUITE.erl
@@ -68,7 +68,7 @@ init_per_suite(Config) ->
catch crypto:stop(),
try crypto:start() of
ok ->
- ssl:start(),
+ ssl_test_lib:clean_start(),
{ok, _} = make_certs:all(proplists:get_value(data_dir, Config),
proplists:get_value(priv_dir, Config)),
ssl_test_lib:cert_options(Config)
diff --git a/lib/ssl/test/ssl_npn_hello_SUITE.erl b/lib/ssl/test/ssl_npn_hello_SUITE.erl
index 00eb9fee4f..35af666e9e 100644
--- a/lib/ssl/test/ssl_npn_hello_SUITE.erl
+++ b/lib/ssl/test/ssl_npn_hello_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -41,6 +41,19 @@ all() ->
create_server_hello_with_advertised_protocols_test,
create_server_hello_with_no_advertised_protocols_test].
+init_per_suite(Config) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ Config
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ %% This function is required since init_per_suite/1 exists.
+ ok.
+
init_per_testcase(_TestCase, Config) ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
ct:timetrap({seconds, 5}),
@@ -126,15 +139,12 @@ create_server_handshake(Npn) ->
}, Vsn).
create_connection_states() ->
- #connection_states{
- pending_read = #connection_state{
- security_parameters = #security_parameters{
+ #{pending_read => #{security_parameters => #security_parameters{
server_random = <<1:256>>,
compression_algorithm = 1,
cipher_suite = ?TLS_DHE_DSS_WITH_DES_CBC_SHA
}
- },
- current_read = #connection_state {
- secure_renegotiation = false
- }
- }.
+ },
+ current_read => #{secure_renegotiation => false
+ }
+ }.
diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl
index e49d432c21..7281425461 100644
--- a/lib/ssl/test/ssl_packet_SUITE.erl
+++ b/lib/ssl/test/ssl_packet_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -41,9 +41,9 @@
-define(MANY, 1000).
-define(SOME, 50).
--define(BASE_TIMEOUT_SECONDS, 15).
--define(SOME_SCALE, 20).
--define(MANY_SCALE, 20).
+-define(BASE_TIMEOUT_SECONDS, 5).
+-define(SOME_SCALE, 2).
+-define(MANY_SCALE, 3).
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
@@ -140,7 +140,7 @@ init_per_suite(Config) ->
catch crypto:stop(),
try crypto:start() of
ok ->
- ssl:start(),
+ ssl_test_lib:clean_start(),
{ok, _} = make_certs:all(proplists:get_value(data_dir, Config),
proplists:get_value(priv_dir, Config)),
ssl_test_lib:cert_options(Config)
@@ -162,6 +162,7 @@ init_per_group(GroupName, Config) ->
{skip, "Missing crypto support"}
end;
_ ->
+ ssl:stop(),
ssl:start(),
Config
end.
@@ -276,6 +277,7 @@ packet_raw_active_once_many_small() ->
[{doc,"Test packet option {packet, raw} in active once mode."}].
packet_raw_active_once_many_small(Config) when is_list(Config) ->
+ ct:timetrap({seconds, ?BASE_TIMEOUT_SECONDS * ?MANY_SCALE}),
Data = "Packet option is {packet, raw}",
packet(Config, Data, send_raw, active_once_raw, ?MANY, raw, once).
@@ -392,6 +394,7 @@ packet_0_active_some_big() ->
[{doc,"Test packet option {packet, 0} in active mode."}].
packet_0_active_some_big(Config) when is_list(Config) ->
+ ct:timetrap({seconds, ?BASE_TIMEOUT_SECONDS * ?SOME_SCALE}),
Data = lists:append(lists:duplicate(100, "1234567890")),
packet(Config, Data, send, active_raw, ?SOME, 0, true).
@@ -427,6 +430,7 @@ packet_2_active_some_big() ->
[{doc,"Test packet option {packet, 2} in active mode"}].
packet_2_active_some_big(Config) when is_list(Config) ->
+ ct:timetrap({seconds, ?BASE_TIMEOUT_SECONDS * ?SOME_SCALE}),
Data = lists:append(lists:duplicate(100, "1234567890")),
packet(Config, Data, send, active_packet, ?SOME, 2, true).
@@ -1900,6 +1904,31 @@ header_decode_two_bytes_one_sent_passive(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
+
+packet(Config, Data, Send, Recv, Quantity, Packet, Active) when Packet == 0;
+ Packet == raw ->
+ ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(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, Send ,[Data, Quantity]}},
+ {options, [{nodelay, true},{packet, Packet} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, Recv, [Data, Quantity]}},
+ {options, [{active, Active}, {nodelay, true},
+ {packet, Packet} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client);
+
packet(Config, Data, Send, Recv, Quantity, Packet, Active) ->
ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
@@ -1944,14 +1973,14 @@ passive_recv_packet(Socket, _, 0) ->
{error, timeout} = ssl:recv(Socket, 0, 500),
ok;
Other ->
- {other, Other, ssl:session_info(Socket), 0}
+ {other, Other, ssl:connection_information(Socket, [session_id, cipher_suite]), 0}
end;
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}
+ {other, Other, ssl:connection_information(Socket, [session_id, cipher_suite]), N}
end.
send(Socket,_, 0) ->
@@ -1982,26 +2011,19 @@ active_once_raw(Socket, Data, N) ->
active_once_raw(_, _, 0, _) ->
ok;
-active_once_raw(Socket, Data, N, Acc) ->
- receive
- {ssl, Socket, Byte} when length(Byte) == 1 ->
- ssl:setopts(Socket, [{active, once}]),
+active_once_raw(Socket, Data, N, Acc0) ->
+ case lists:prefix(Data, Acc0) of
+ true ->
+ DLen = length(Data),
+ Start = DLen + 1,
+ Len = length(Acc0) - DLen,
+ Acc = string:substr(Acc0, Start, Len),
+ active_once_raw(Socket, Data, N-1, Acc);
+ false ->
receive
- {ssl, Socket, _} ->
- ssl:setopts(Socket, [{active, once}]),
- active_once_raw(Socket, Data, N-1, [])
- end;
- {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, Socket, Info} ->
ssl:setopts(Socket, [{active, once}]),
- active_once_raw(Socket, Data, N, NewAcc)
+ active_once_raw(Socket, Data, N, Acc0 ++ Info)
end
end.
@@ -2010,7 +2032,7 @@ active_once_packet(Socket,_, 0) ->
{ssl, Socket, []} ->
ok;
{ssl, Socket, Other} ->
- {other, Other, ssl:session_info(Socket), 0}
+ {other, Other, ssl:connection_information(Socket, [session_id, cipher_suite]), 0}
end;
active_once_packet(Socket, Data, N) ->
receive
@@ -2055,7 +2077,7 @@ active_packet(Socket, _, 0) ->
{ssl, Socket, []} ->
ok;
Other ->
- {other, Other, ssl:session_info(Socket), 0}
+ {other, Other, ssl:connection_information(Socket, [session_id, cipher_suite]), 0}
end;
active_packet(Socket, Data, N) ->
receive
@@ -2067,7 +2089,7 @@ active_packet(Socket, Data, N) ->
{ssl, Socket, Data} ->
active_packet(Socket, Data, N -1);
Other ->
- {other, Other, ssl:session_info(Socket),N}
+ {other, Other, ssl:connection_information(Socket, [session_id, cipher_suite]),N}
end.
assert_packet_opt(Socket, Type) ->
diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl
index cb0571d0a7..cb1957327a 100644
--- a/lib/ssl/test/ssl_payload_SUITE.erl
+++ b/lib/ssl/test/ssl_payload_SUITE.erl
@@ -70,7 +70,7 @@ init_per_suite(Config) ->
catch crypto:stop(),
try crypto:start() of
ok ->
- ssl:start(),
+ ssl_test_lib:clean_start(),
{ok, _} = make_certs:all(proplists:get_value(data_dir, Config), proplists:get_value(priv_dir, Config)),
ssl_test_lib:cert_options(Config)
catch _:_ ->
@@ -104,8 +104,13 @@ init_per_testcase(TestCase, Config) when TestCase == server_echos_passive_huge;
TestCase == client_echos_passive_huge;
TestCase == client_echos_active_once_huge;
TestCase == client_echos_active_huge ->
- ct:timetrap({seconds, 90}),
- Config;
+ case erlang:system_info(system_architecture) of
+ "sparc-sun-solaris2.10" ->
+ {skip,"Will take to long time on an old Sparc"};
+ _ ->
+ ct:timetrap({seconds, 90}),
+ Config
+ end;
init_per_testcase(TestCase, Config) when TestCase == server_echos_passive_big;
TestCase == server_echos_active_once_big;
diff --git a/lib/ssl/test/ssl_pem_cache_SUITE.erl b/lib/ssl/test/ssl_pem_cache_SUITE.erl
index 13b0ce8ed9..96b15d9b51 100644
--- a/lib/ssl/test/ssl_pem_cache_SUITE.erl
+++ b/lib/ssl/test/ssl_pem_cache_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@ init_per_suite(Config0) ->
catch crypto:stop(),
try crypto:start() of
ok ->
- ssl:start(),
+ ssl_test_lib:clean_start(),
%% make rsa certs using oppenssl
{ok, _} = make_certs:all(proplists:get_value(data_dir, Config0),
proplists:get_value(priv_dir, Config0)),
@@ -63,14 +63,15 @@ end_per_group(_GroupName, Config) ->
Config.
init_per_testcase(pem_cleanup = Case, Config) ->
- end_per_testcase(Case, Config) ,
application:load(ssl),
+ end_per_testcase(Case, Config) ,
application:set_env(ssl, ssl_pem_cache_clean, ?CLEANUP_INTERVAL),
ssl:start(),
ct:timetrap({minutes, 1}),
Config.
end_per_testcase(_TestCase, Config) ->
+ ssl_test_lib:clean_env(),
ssl:stop(),
Config.
@@ -81,8 +82,8 @@ pem_cleanup() ->
[{doc, "Test pem cache invalidate mechanism"}].
pem_cleanup(Config)when is_list(Config) ->
process_flag(trap_exit, true),
- ClientOpts = proplists:get_value(client_opts, Config),
- ServerOpts = proplists:get_value(server_opts, Config),
+ ClientOpts = proplists:get_value(client_verification_opts, Config),
+ ServerOpts = proplists:get_value(server_verification_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server =
diff --git a/lib/ssl/test/ssl_session_cache_SUITE.erl b/lib/ssl/test/ssl_session_cache_SUITE.erl
index b352844ba0..9862b3ce64 100644
--- a/lib/ssl/test/ssl_session_cache_SUITE.erl
+++ b/lib/ssl/test/ssl_session_cache_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -58,7 +58,7 @@ init_per_suite(Config0) ->
catch crypto:stop(),
try crypto:start() of
ok ->
- ssl:start(),
+ ssl_test_lib:clean_start(),
%% make rsa certs using
{ok, _} = make_certs:all(proplists:get_value(data_dir, Config0),
proplists:get_value(priv_dir, Config0)),
diff --git a/lib/ssl/test/ssl_sni_SUITE.erl b/lib/ssl/test/ssl_sni_SUITE.erl
index 34ef2e6af9..4e916a7f03 100644
--- a/lib/ssl/test/ssl_sni_SUITE.erl
+++ b/lib/ssl/test/ssl_sni_SUITE.erl
@@ -41,7 +41,7 @@ init_per_suite(Config0) ->
catch crypto:stop(),
try crypto:start() of
ok ->
- ssl:start(),
+ ssl_test_lib:clean_start(),
{ok, _} = make_certs:all(proplists:get_value(data_dir, Config0),
proplists:get_value(priv_dir, Config0)),
ssl_test_lib:cert_options(Config0)
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 27c670cdc2..77c21d9b57 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -34,13 +34,13 @@
run_where(_) ->
ClientNode = node(),
ServerNode = node(),
- {ok, Host} = rpc:call(ServerNode, inet, gethostname, []),
+ Host = rpc:call(ServerNode, net_adm, localhost, []),
{ClientNode, ServerNode, Host}.
run_where(_, ipv6) ->
ClientNode = node(),
ServerNode = node(),
- {ok, Host} = rpc:call(ServerNode, inet, gethostname, []),
+ Host = rpc:call(ServerNode, net_adm, localhost, []),
{ClientNode, ServerNode, Host}.
node_to_hostip(Node) ->
@@ -278,8 +278,11 @@ check_result(Server, ServerMsg, Client, ClientMsg) ->
check_result(Server, ServerMsg);
{Port, {data,Debug}} when is_port(Port) ->
- ct:log("~p:~p~nopenssl ~s~n",[?MODULE,?LINE, Debug]),
+ ct:log("~p:~p~n Openssl ~s~n",[?MODULE,?LINE, Debug]),
check_result(Server, ServerMsg, Client, ClientMsg);
+ {Port,closed} when is_port(Port) ->
+ ct:log("~p:~p~n Openssl port ~n",[?MODULE,?LINE]),
+ check_result(Server, ServerMsg, Client, ClientMsg);
Unexpected ->
Reason = {{expected, {Client, ClientMsg}},
{expected, {Server, ServerMsg}}, {got, Unexpected}},
@@ -291,11 +294,11 @@ check_result(Pid, Msg) ->
{Pid, Msg} ->
ok;
{Port, {data,Debug}} when is_port(Port) ->
- ct:log("~p:~p~nopenssl ~s~n",[?MODULE,?LINE, Debug]),
+ ct:log("~p:~p~n Openssl ~s~n",[?MODULE,?LINE, Debug]),
check_result(Pid,Msg);
- %% {Port, {exit_status, Status}} when is_port(Port) ->
- %% ct:log("~p:~p Exit status: ~p~n",[?MODULE,?LINE, Status]),
- %% check_result(Pid, Msg);
+ {Port,closed} when is_port(Port)->
+ ct:log("~p:~p Openssl port closed ~n",[?MODULE,?LINE]),
+ check_result(Pid, Msg);
Unexpected ->
Reason = {{expected, {Pid, Msg}},
{got, Unexpected}},
@@ -385,7 +388,9 @@ cert_options(Config) ->
SNIServerAKeyFile = filename:join([proplists:get_value(priv_dir, Config), "a.server", "key.pem"]),
SNIServerBCertFile = filename:join([proplists:get_value(priv_dir, Config), "b.server", "cert.pem"]),
SNIServerBKeyFile = filename:join([proplists:get_value(priv_dir, Config), "b.server", "key.pem"]),
- [{client_opts, []},
+ [{client_opts, [{cacertfile, ClientCaCertFile},
+ {certfile, ClientCertFile},
+ {keyfile, ClientKeyFile}]},
{client_verification_opts, [{cacertfile, ServerCaCertFile},
{certfile, ClientCertFile},
{keyfile, ClientKeyFile},
@@ -394,29 +399,24 @@ cert_options(Config) ->
{certfile, ClientCertFileDigitalSignatureOnly},
{keyfile, ClientKeyFile},
{ssl_imp, new}]},
- {server_opts, [{ssl_imp, new},{reuseaddr, true},
+ {server_opts, [{ssl_imp, new},{reuseaddr, true}, {cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
- {server_anon, [{ssl_imp, new},{reuseaddr, true}, {ciphers, anonymous_suites()}]},
- {client_psk, [{ssl_imp, new},{reuseaddr, true},
+ {client_psk, [{ssl_imp, new},
{psk_identity, "Test-User"},
{user_lookup_fun, {fun user_lookup/3, PskSharedSecret}}]},
{server_psk, [{ssl_imp, new},{reuseaddr, true},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile},
- {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}},
- {ciphers, psk_suites()}]},
+ {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}}]},
{server_psk_hint, [{ssl_imp, new},{reuseaddr, true},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile},
{psk_identity, "HINT"},
- {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}},
- {ciphers, psk_suites()}]},
+ {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}}]},
{server_psk_anon, [{ssl_imp, new},{reuseaddr, true},
- {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}},
- {ciphers, psk_anon_suites()}]},
+ {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}}]},
{server_psk_anon_hint, [{ssl_imp, new},{reuseaddr, true},
{psk_identity, "HINT"},
- {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}},
- {ciphers, psk_anon_suites()}]},
- {client_srp, [{ssl_imp, new},{reuseaddr, true},
+ {user_lookup_fun, {fun user_lookup/3, PskSharedSecret}}]},
+ {client_srp, [{ssl_imp, new},
{srp_identity, {"Test-User", "secret"}}]},
{server_srp, [{ssl_imp, new},{reuseaddr, true},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile},
@@ -460,9 +460,10 @@ cert_options(Config) ->
make_dsa_cert(Config) ->
-
- {ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_cert_files("server", Config, dsa, dsa, ""),
- {ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_cert_files("client", Config, dsa, dsa, ""),
+ {ServerCaCertFile, ServerCertFile, ServerKeyFile} =
+ make_cert_files("server", Config, dsa, dsa, "", []),
+ {ClientCaCertFile, ClientCertFile, ClientKeyFile} =
+ make_cert_files("client", Config, dsa, dsa, "", []),
[{server_dsa_opts, [{ssl_imp, new},{reuseaddr, true},
{cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
@@ -470,7 +471,7 @@ make_dsa_cert(Config) ->
{cacertfile, ClientCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile},
{verify, verify_peer}]},
- {client_dsa_opts, [{ssl_imp, new},{reuseaddr, true},
+ {client_dsa_opts, [{ssl_imp, new},
{cacertfile, ClientCaCertFile},
{certfile, ClientCertFile}, {keyfile, ClientKeyFile}]},
{server_srp_dsa, [{ssl_imp, new},{reuseaddr, true},
@@ -478,32 +479,128 @@ make_dsa_cert(Config) ->
{certfile, ServerCertFile}, {keyfile, ServerKeyFile},
{user_lookup_fun, {fun user_lookup/3, undefined}},
{ciphers, srp_dss_suites()}]},
- {client_srp_dsa, [{ssl_imp, new},{reuseaddr, true},
+ {client_srp_dsa, [{ssl_imp, new},
{srp_identity, {"Test-User", "secret"}},
{cacertfile, ClientCaCertFile},
{certfile, ClientCertFile}, {keyfile, ClientKeyFile}]}
| Config].
+make_rsa_cert_chains(ChainConf, Config, Suffix) ->
+ CryptoSupport = crypto:supports(),
+ KeyGenSpec = key_gen_info(rsa, rsa),
+ ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa" ++ Suffix]),
+ ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa" ++ Suffix]),
+ GenCertData = x509_test:gen_test_certs([{digest, appropriate_sha(CryptoSupport)} | KeyGenSpec] ++ ChainConf),
+ [{server_config, ServerConf},
+ {client_config, ClientConf}] =
+ x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
+ {[{verify, verify_peer} | ClientConf],
+ [{reuseaddr, true}, {verify, verify_peer} | ServerConf]
+ }.
+
+make_ec_cert_chains(ChainConf, ClientChainType, ServerChainType, Config) ->
+ CryptoSupport = crypto:supports(),
+ KeyGenSpec = key_gen_info(ClientChainType, ServerChainType),
+ ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(ClientChainType)]),
+ ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(ServerChainType)]),
+ GenCertData = x509_test:gen_test_certs([{digest, appropriate_sha(CryptoSupport)} | KeyGenSpec] ++ ChainConf),
+ [{server_config, ServerConf},
+ {client_config, ClientConf}] =
+ x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
+ {[{verify, verify_peer} | ClientConf],
+ [{reuseaddr, true}, {verify, verify_peer} | ServerConf]
+ }.
+
+key_gen_info(ClientChainType, ServerChainType) ->
+ key_gen_spec("client", ClientChainType) ++ key_gen_spec("server", ServerChainType).
+
+key_gen_spec(Role, ecdh_rsa) ->
+ CurveOid = hd(tls_v1:ecc_curves(0)),
+ [{list_to_atom(Role ++ "_key_gen"), {namedCurve, CurveOid}},
+ {list_to_atom(Role ++ "_key_gen_chain"), [hardcode_rsa_key(1),
+ {namedCurve, CurveOid}]}
+ ];
+key_gen_spec(Role, ecdhe_ecdsa) ->
+ CurveOid = hd(tls_v1:ecc_curves(0)),
+ [{list_to_atom(Role ++ "_key_gen"), {namedCurve, CurveOid}},
+ {list_to_atom(Role ++ "_key_gen_chain"), [{namedCurve, CurveOid},
+ {namedCurve, CurveOid}]}
+ ];
+key_gen_spec(Role, ecdh_ecdsa) ->
+ CurveOid = hd(tls_v1:ecc_curves(0)),
+ [{list_to_atom(Role ++ "_key_gen"), {namedCurve, CurveOid}},
+ {list_to_atom(Role ++ "_key_gen_chain"), [{namedCurve, CurveOid},
+ {namedCurve, CurveOid}]}
+ ];
+key_gen_spec(Role, ecdhe_rsa) ->
+ [{list_to_atom(Role ++ "_key_gen"), hardcode_rsa_key(1)},
+ {list_to_atom(Role ++ "_key_gen_chain"), [hardcode_rsa_key(2),
+ hardcode_rsa_key(3)]}
+ ];
+key_gen_spec(Role, rsa) ->
+ [{list_to_atom(Role ++ "_key_gen"), hardcode_rsa_key(1)},
+ {list_to_atom(Role ++ "_key_gen_chain"), [hardcode_rsa_key(2),
+ hardcode_rsa_key(3)]}
+ ].
make_ecdsa_cert(Config) ->
CryptoSupport = crypto:supports(),
case proplists:get_bool(ecdsa, proplists:get_value(public_keys, CryptoSupport)) of
- true ->
- {ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_cert_files("server", Config, ec, ec, ""),
- {ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_cert_files("client", Config, ec, ec, ""),
- [{server_ecdsa_opts, [{ssl_imp, new},{reuseaddr, true},
- {cacertfile, ServerCaCertFile},
- {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
- {server_ecdsa_verify_opts, [{ssl_imp, new},{reuseaddr, true},
- {cacertfile, ServerCaCertFile},
- {certfile, ServerCertFile}, {keyfile, ServerKeyFile},
- {verify, verify_peer}]},
- {client_ecdsa_opts, [{ssl_imp, new},{reuseaddr, true},
- {cacertfile, ClientCaCertFile},
- {certfile, ClientCertFile}, {keyfile, ClientKeyFile}]}
+ true ->
+ ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdsa"]),
+ ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdsa"]),
+ CurveOid = hd(tls_v1:ecc_curves(0)),
+ GenCertData = x509_test:gen_test_certs([{server_key_gen, {namedCurve, CurveOid}},
+ {client_key_gen, {namedCurve, CurveOid}},
+ {server_key_gen_chain, [{namedCurve, CurveOid},
+ {namedCurve, CurveOid}]},
+ {client_key_gen_chain, [{namedCurve, CurveOid},
+ {namedCurve, CurveOid}]},
+ {digest, appropriate_sha(CryptoSupport)}]),
+ [{server_config, ServerConf},
+ {client_config, ClientConf}] =
+ x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
+ [{server_ecdsa_opts, [{ssl_imp, new},{reuseaddr, true} | ServerConf]},
+
+ {server_ecdsa_verify_opts, [{ssl_imp, new}, {reuseaddr, true},
+ {verify, verify_peer} | ServerConf]},
+ {client_ecdsa_opts, ClientConf}
| Config];
- _ ->
+ false ->
Config
end.
+make_rsa_cert(Config) ->
+ CryptoSupport = crypto:supports(),
+ case proplists:get_bool(rsa, proplists:get_value(public_keys, CryptoSupport)) of
+ true ->
+ ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa"]),
+ ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa"]),
+ GenCertData = x509_test:gen_test_certs([{server_key_gen, hardcode_rsa_key(1)},
+ {client_key_gen, hardcode_rsa_key(2)},
+ {server_key_gen_chain, [hardcode_rsa_key(3),
+ hardcode_rsa_key(4)]},
+ {client_key_gen_chain, [hardcode_rsa_key(5),
+ hardcode_rsa_key(6)]},
+ {digest, appropriate_sha(CryptoSupport)}]),
+ [{server_config, ServerConf},
+ {client_config, ClientConf}] =
+ x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
+ [{server_rsa_opts, [{ssl_imp, new},{reuseaddr, true} | ServerConf]},
+
+ {server_rsa_verify_opts, [{ssl_imp, new}, {reuseaddr, true},
+ {verify, verify_peer} | ServerConf]},
+ {client_rsa_opts, ClientConf},
+ {client_rsa_verify_opts, [{verify, verify_peer} |ClientConf]}
+ | Config];
+ false ->
+ Config
+ end.
+appropriate_sha(CryptoSupport) ->
+ case proplists:get_bool(sha256, CryptoSupport) of
+ true ->
+ sha256;
+ false ->
+ sha1
+ end.
%% RFC 4492, Sect. 2.3. ECDH_RSA
%%
@@ -513,28 +610,39 @@ make_ecdh_rsa_cert(Config) ->
CryptoSupport = crypto:supports(),
case proplists:get_bool(ecdh, proplists:get_value(public_keys, CryptoSupport)) of
true ->
- {ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_cert_files("server", Config, rsa, ec, "rsa_"),
- {ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_cert_files("client", Config, rsa, ec, "rsa_"),
- [{server_ecdh_rsa_opts, [{ssl_imp, new},{reuseaddr, true},
- {cacertfile, ServerCaCertFile},
- {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
- {server_ecdh_rsa_verify_opts, [{ssl_imp, new},{reuseaddr, true},
- {cacertfile, ServerCaCertFile},
- {certfile, ServerCertFile}, {keyfile, ServerKeyFile},
- {verify, verify_peer}]},
- {client_ecdh_rsa_opts, [{ssl_imp, new},{reuseaddr, true},
- {cacertfile, ClientCaCertFile},
- {certfile, ClientCertFile}, {keyfile, ClientKeyFile}]}
- | Config];
+ ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdh_rsa"]),
+ ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdh_rsa"]),
+ CurveOid = hd(tls_v1:ecc_curves(0)),
+ GenCertData = x509_test:gen_test_certs([{server_key_gen, {namedCurve, CurveOid}},
+ {client_key_gen, {namedCurve, CurveOid}},
+ {server_key_gen_chain, [hardcode_rsa_key(1),
+ {namedCurve, CurveOid}
+ ]},
+ {client_key_gen_chain, [hardcode_rsa_key(2),
+ {namedCurve, CurveOid}
+ ]},
+ {digest, appropriate_sha(CryptoSupport)}]),
+ [{server_config, ServerConf},
+ {client_config, ClientConf}] =
+ x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
+
+ [{server_ecdh_rsa_opts, [{ssl_imp, new},{reuseaddr, true} | ServerConf]},
+
+ {server_ecdh_rsa_verify_opts, [{ssl_imp, new},{reuseaddr, true},
+ {verify, verify_peer} | ServerConf]},
+
+ {client_ecdh_rsa_opts, ClientConf}
+
+ | Config];
_ ->
Config
end.
make_mix_cert(Config) ->
{ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_cert_files("server", Config, dsa,
- rsa, "mix"),
+ rsa, "mix", []),
{ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_cert_files("client", Config, dsa,
- rsa, "mix"),
+ rsa, "mix", []),
[{server_mix_opts, [{ssl_imp, new},{reuseaddr, true},
{cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
@@ -542,16 +650,16 @@ make_mix_cert(Config) ->
{cacertfile, ClientCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile},
{verify, verify_peer}]},
- {client_mix_opts, [{ssl_imp, new},{reuseaddr, true},
+ {client_mix_opts, [{ssl_imp, new},
{cacertfile, ClientCaCertFile},
{certfile, ClientCertFile}, {keyfile, ClientKeyFile}]}
| Config].
-make_cert_files(RoleStr, Config, Alg1, Alg2, Prefix) ->
+make_cert_files(RoleStr, Config, Alg1, Alg2, Prefix, Opts) ->
Alg1Str = atom_to_list(Alg1),
Alg2Str = atom_to_list(Alg2),
- CaInfo = {CaCert, _} = erl_make_certs:make_cert([{key, Alg1}]),
- {Cert, CertKey} = erl_make_certs:make_cert([{key, Alg2}, {issuer, CaInfo}]),
+ CaInfo = {CaCert, _} = erl_make_certs:make_cert([{key, Alg1}| Opts]),
+ {Cert, CertKey} = erl_make_certs:make_cert([{key, Alg2}, {issuer, CaInfo} | Opts]),
CaCertFile = filename:join([proplists:get_value(priv_dir, Config),
RoleStr, Prefix ++ Alg1Str ++ "_cacerts.pem"]),
CertFile = filename:join([proplists:get_value(priv_dir, Config),
@@ -769,18 +877,18 @@ no_result(_) ->
no_result_msg.
trigger_renegotiate(Socket, [ErlData, N]) ->
- [{session_id, Id} | _ ] = ssl:session_info(Socket),
+ {ok, [{session_id, Id}]} = ssl:connection_information(Socket, [session_id]),
trigger_renegotiate(Socket, ErlData, N, Id).
trigger_renegotiate(Socket, _, 0, Id) ->
ct:sleep(1000),
- case ssl:session_info(Socket) of
- [{session_id, Id} | _ ] ->
+ case ssl:connection_information(Socket, [session_id]) of
+ {ok, [{session_id, Id}]} ->
fail_session_not_renegotiated;
%% Tests that uses this function will not reuse
%% sessions so if we get a new session id the
%% renegotiation has succeeded.
- [{session_id, _} | _ ] ->
+ {ok, [{session_id, _}]} ->
ok;
{error, closed} ->
fail_session_fatal_alert_during_renegotiation;
@@ -805,16 +913,24 @@ send_selected_port(_,_,_) ->
rsa_suites(CounterPart) ->
ECC = is_sane_ecc(CounterPart),
FIPS = is_fips(CounterPart),
+ CryptoSupport = crypto:supports(),
+ Ciphers = proplists:get_value(ciphers, CryptoSupport),
lists:filter(fun({rsa, des_cbc, sha}) when FIPS == true ->
false;
({dhe_rsa, des_cbc, sha}) when FIPS == true ->
false;
- ({rsa, _, _}) ->
- true;
- ({dhe_rsa, _, _}) ->
- true;
- ({ecdhe_rsa, _, _}) when ECC == true ->
- true;
+ ({rsa, Cipher, _}) ->
+ lists:member(cipher_atom(Cipher), Ciphers);
+ ({dhe_rsa, Cipher, _}) ->
+ lists:member(cipher_atom(Cipher), Ciphers);
+ ({ecdhe_rsa, Cipher, _}) when ECC == true ->
+ lists:member(cipher_atom(Cipher), Ciphers);
+ ({rsa, Cipher, _, _}) ->
+ lists:member(cipher_atom(Cipher), Ciphers);
+ ({dhe_rsa, Cipher, _,_}) ->
+ lists:member(cipher_atom(Cipher), Ciphers);
+ ({ecdhe_rsa, Cipher, _,_}) when ECC == true ->
+ lists:member(cipher_atom(Cipher), Ciphers);
(_) ->
false
end,
@@ -830,37 +946,42 @@ common_ciphers(openssl) ->
lists:member(ssl_cipher:openssl_suite_name(S), OpenSslSuites)
].
-rsa_non_signed_suites() ->
+available_suites(Version) ->
+ [ssl_cipher:erl_suite_definition(Suite) ||
+ Suite <- ssl_cipher:filter_suites(ssl_cipher:suites(Version))].
+
+
+rsa_non_signed_suites(Version) ->
lists:filter(fun({rsa, _, _}) ->
- true;
+ false;
(_) ->
- false
+ true
end,
- ssl:cipher_suites()).
+ available_suites(Version)).
-dsa_suites() ->
+dsa_suites(Version) ->
lists:filter(fun({dhe_dss, _, _}) ->
true;
(_) ->
false
end,
- ssl:cipher_suites()).
+ available_suites(Version)).
-ecdsa_suites() ->
+ecdsa_suites(Version) ->
lists:filter(fun({ecdhe_ecdsa, _, _}) ->
true;
(_) ->
false
end,
- ssl:cipher_suites()).
+ available_suites(Version)).
-ecdh_rsa_suites() ->
+ecdh_rsa_suites(Version) ->
lists:filter(fun({ecdh_rsa, _, _}) ->
true;
(_) ->
false
end,
- ssl:cipher_suites()).
+ available_suites(Version)).
openssl_rsa_suites(CounterPart) ->
Ciphers = ssl:cipher_suites(openssl),
@@ -888,6 +1009,12 @@ openssl_ecdh_rsa_suites() ->
lists:filter(fun(Str) -> string_regex_filter(Str, "ECDH-RSA")
end, Ciphers).
+openssl_filter(FilterStr) ->
+ Ciphers = string:tokens(os:cmd("openssl ciphers"), ":"),
+ lists:filter(fun(Str) -> string_regex_filter(Str, FilterStr)
+ end, Ciphers).
+
+
string_regex_filter(Str, Search) when is_list(Str) ->
case re:run(Str, Search, []) of
nomatch ->
@@ -898,59 +1025,16 @@ string_regex_filter(Str, Search) when is_list(Str) ->
string_regex_filter(_Str, _Search) ->
false.
-anonymous_suites() ->
- Suites =
- [{dh_anon, rc4_128, md5},
- {dh_anon, des_cbc, sha},
- {dh_anon, '3des_ede_cbc', sha},
- {dh_anon, aes_128_cbc, sha},
- {dh_anon, aes_256_cbc, sha},
- {dh_anon, aes_128_gcm, null, sha256},
- {dh_anon, aes_256_gcm, null, sha384},
- {ecdh_anon,rc4_128,sha},
- {ecdh_anon,'3des_ede_cbc',sha},
- {ecdh_anon,aes_128_cbc,sha},
- {ecdh_anon,aes_256_cbc,sha}],
+anonymous_suites(Version) ->
+ Suites = ssl_cipher:anonymous_suites(Version),
ssl_cipher:filter_suites(Suites).
-psk_suites() ->
- Suites =
- [{psk, rc4_128, sha},
- {psk, '3des_ede_cbc', sha},
- {psk, aes_128_cbc, sha},
- {psk, aes_256_cbc, sha},
- {psk, aes_128_cbc, sha256},
- {psk, aes_256_cbc, sha384},
- {dhe_psk, rc4_128, sha},
- {dhe_psk, '3des_ede_cbc', sha},
- {dhe_psk, aes_128_cbc, sha},
- {dhe_psk, aes_256_cbc, sha},
- {dhe_psk, aes_128_cbc, sha256},
- {dhe_psk, aes_256_cbc, sha384},
- {rsa_psk, rc4_128, sha},
- {rsa_psk, '3des_ede_cbc', sha},
- {rsa_psk, aes_128_cbc, sha},
- {rsa_psk, aes_256_cbc, sha},
- {rsa_psk, aes_128_cbc, sha256},
- {rsa_psk, aes_256_cbc, sha384},
- {psk, aes_128_gcm, null, sha256},
- {psk, aes_256_gcm, null, sha384},
- {dhe_psk, aes_128_gcm, null, sha256},
- {dhe_psk, aes_256_gcm, null, sha384},
- {rsa_psk, aes_128_gcm, null, sha256},
- {rsa_psk, aes_256_gcm, null, sha384}],
+psk_suites(Version) ->
+ Suites = ssl_cipher:psk_suites(Version),
ssl_cipher:filter_suites(Suites).
-psk_anon_suites() ->
- Suites =
- [{psk, rc4_128, sha},
- {psk, '3des_ede_cbc', sha},
- {psk, aes_128_cbc, sha},
- {psk, aes_256_cbc, sha},
- {dhe_psk, rc4_128, sha},
- {dhe_psk, '3des_ede_cbc', sha},
- {dhe_psk, aes_128_cbc, sha},
- {dhe_psk, aes_256_cbc, sha}],
+psk_anon_suites(Version) ->
+ Suites = [Suite || Suite <- psk_suites(Version), is_psk_anon_suite(Suite)],
ssl_cipher:filter_suites(Suites).
srp_suites() ->
@@ -1015,8 +1099,8 @@ cipher_result(Socket, Result) ->
end.
session_info_result(Socket) ->
- ssl:session_info(Socket).
-
+ {ok, Info} = ssl:connection_information(Socket, [session_id, cipher_suite]),
+ Info.
public_key(#'PrivateKeyInfo'{privateKeyAlgorithm =
#'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = ?rsaEncryption},
@@ -1072,14 +1156,16 @@ init_tls_version(Version, Config)
application:load(ssl),
application:set_env(ssl, dtls_protocol_version, Version),
ssl:start(),
- [{protocol, dtls}, {protocol_opts, [{protocol, dtls}]}|Config];
+ NewConfig = proplists:delete(protocol_opts, proplists:delete(protocol, Config)),
+ [{protocol, dtls}, {protocol_opts, [{protocol, dtls}]} | NewConfig];
init_tls_version(Version, Config) ->
ssl:stop(),
application:load(ssl),
application:set_env(ssl, protocol_version, Version),
ssl:start(),
- [{protocol, tls}|Config].
+ NewConfig = proplists:delete(protocol_opts, proplists:delete(protocol, Config)),
+ [{protocol, tls} | NewConfig].
sufficient_crypto_support(Version)
when Version == 'tlsv1.2'; Version == 'dtlsv1.2' ->
@@ -1094,6 +1180,21 @@ sufficient_crypto_support(Group) when Group == ciphers_ec; %% From ssl_basic
sufficient_crypto_support(_) ->
true.
+check_key_exchange_send_active(Socket, false) ->
+ send_recv_result_active(Socket);
+check_key_exchange_send_active(Socket, KeyEx) ->
+ {ok, [{cipher_suite, Suite}]} = ssl:connection_information(Socket, [cipher_suite]),
+ true = check_key_exchange(Suite, KeyEx),
+ send_recv_result_active(Socket).
+
+check_key_exchange({KeyEx,_, _}, KeyEx) ->
+ true;
+check_key_exchange({KeyEx,_,_,_}, KeyEx) ->
+ true;
+check_key_exchange(KeyEx1, KeyEx2) ->
+ ct:pal("Negotiated ~p Expected ~p", [KeyEx1, KeyEx2]),
+ false.
+
send_recv_result_active(Socket) ->
ssl:send(Socket, "Hello world"),
receive
@@ -1175,14 +1276,15 @@ is_fips(_) ->
false.
cipher_restriction(Config0) ->
+ Version = tls_record:protocol_version(protocol_version(Config0)),
case is_sane_ecc(openssl) of
false ->
Opts = proplists:get_value(server_opts, Config0),
Config1 = proplists:delete(server_opts, Config0),
VerOpts = proplists:get_value(server_verification_opts, Config1),
Config = proplists:delete(server_verification_opts, Config1),
- Restricted0 = ssl:cipher_suites() -- ecdsa_suites(),
- Restricted = Restricted0 -- ecdh_rsa_suites(),
+ Restricted0 = ssl:cipher_suites() -- ecdsa_suites(Version),
+ Restricted = Restricted0 -- ecdh_rsa_suites(Version),
[{server_opts, [{ciphers, Restricted} | Opts]}, {server_verification_opts, [{ciphers, Restricted} | VerOpts] } | Config];
true ->
Config0
@@ -1204,6 +1306,10 @@ check_sane_openssl_version(Version) ->
false;
{'tlsv1.1', "OpenSSL 0" ++ _} ->
false;
+ {'dtlsv1', "OpenSSL 0" ++ _} ->
+ false;
+ {'dtlsv1.2', "OpenSSL 0" ++ _} ->
+ false;
{_, _} ->
true
end;
@@ -1213,19 +1319,37 @@ check_sane_openssl_version(Version) ->
enough_openssl_crl_support("OpenSSL 0." ++ _) -> false;
enough_openssl_crl_support(_) -> true.
-wait_for_openssl_server(Port) ->
- wait_for_openssl_server(Port, 10).
-wait_for_openssl_server(_, 0) ->
+wait_for_openssl_server(Port, tls) ->
+ do_wait_for_openssl_tls_server(Port, 10);
+wait_for_openssl_server(Port, dtls) ->
+ do_wait_for_openssl_dtls_server(Port, 10).
+
+do_wait_for_openssl_tls_server(_, 0) ->
exit(failed_to_connect_to_openssl);
-wait_for_openssl_server(Port, N) ->
+do_wait_for_openssl_tls_server(Port, N) ->
case gen_tcp:connect("localhost", Port, []) of
{ok, S} ->
gen_tcp:close(S);
_ ->
ct:sleep(?SLEEP),
- wait_for_openssl_server(Port, N-1)
+ do_wait_for_openssl_tls_server(Port, N-1)
end.
+do_wait_for_openssl_dtls_server(_, 0) ->
+ %%exit(failed_to_connect_to_openssl);
+ ok;
+do_wait_for_openssl_dtls_server(Port, N) ->
+ %% case gen_udp:open(0) of
+ %% {ok, S} ->
+ %% gen_udp:connect(S, "localhost", Port),
+ %% gen_udp:close(S);
+ %% _ ->
+ %% ct:sleep(?SLEEP),
+ %% do_wait_for_openssl_dtls_server(Port, N-1)
+ %% end.
+ ct:sleep(500),
+ do_wait_for_openssl_dtls_server(Port, N-1).
+
version_flag(tlsv1) ->
"-tls1";
version_flag('tlsv1.1') ->
@@ -1235,10 +1359,14 @@ version_flag('tlsv1.2') ->
version_flag(sslv3) ->
"-ssl3";
version_flag(sslv2) ->
- "-ssl2".
-
-filter_suites(Ciphers0) ->
- Version = tls_record:highest_protocol_version([]),
+ "-ssl2";
+version_flag('dtlsv1.2') ->
+ "-dtls1_2";
+version_flag('dtlsv1') ->
+ "-dtls1".
+
+filter_suites(Ciphers0, AtomVersion) ->
+ Version = tls_version(AtomVersion),
Supported0 = ssl_cipher:suites(Version)
++ ssl_cipher:anonymous_suites(Version)
++ ssl_cipher:psk_suites(Version)
@@ -1287,6 +1415,18 @@ portable_open_port(Exe, Args) ->
open_port({spawn_executable, AbsPath},
[{args, Args}, stderr_to_stdout]).
+supports_ssl_tls_version(sslv2 = Version) ->
+ case os:cmd("openssl version") of
+ "OpenSSL 1" ++ _ ->
+ false;
+ _ ->
+ VersionFlag = version_flag(Version),
+ Exe = "openssl",
+ Args = ["s_client", VersionFlag],
+ Port = ssl_test_lib:portable_open_port(Exe, Args),
+ do_supports_ssl_tls_version(Port)
+ end;
+
supports_ssl_tls_version(Version) ->
VersionFlag = version_flag(Version),
Exe = "openssl",
@@ -1296,6 +1436,8 @@ supports_ssl_tls_version(Version) ->
do_supports_ssl_tls_version(Port) ->
receive
+ {Port, {data, "u"}} ->
+ false;
{Port, {data, "unknown option" ++ _}} ->
false;
{Port, {data, Data}} ->
@@ -1305,14 +1447,17 @@ do_supports_ssl_tls_version(Port) ->
false ->
do_supports_ssl_tls_version(Port)
end
- after 500 ->
+ after 1000 ->
true
end.
-ssl_options(Option, Config) ->
+ssl_options(Option, Config) when is_atom(Option) ->
ProtocolOpts = proplists:get_value(protocol_opts, Config, []),
Opts = proplists:get_value(Option, Config, []),
- Opts ++ ProtocolOpts.
+ Opts ++ ProtocolOpts;
+ssl_options(Options, Config) ->
+ ProtocolOpts = proplists:get_value(protocol_opts, Config, []),
+ Options ++ ProtocolOpts.
protocol_version(Config) ->
protocol_version(Config, atom).
@@ -1320,7 +1465,7 @@ protocol_version(Config) ->
protocol_version(Config, tuple) ->
case proplists:get_value(protocol, Config) of
dtls ->
- dtls_record:protocol_version(dtls_record:highest_protocol_version([]));
+ dtls_record:highest_protocol_version(dtls_record:supported_protocol_versions());
_ ->
tls_record:highest_protocol_version(tls_record:supported_protocol_versions())
end;
@@ -1345,3 +1490,192 @@ ct_log_supported_protocol_versions(Config) ->
_ ->
ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()])
end.
+
+clean_env() ->
+ application:unset_env(ssl, protocol_version),
+ application:unset_env(ssl, session_lifetime),
+ application:unset_env(ssl, session_cb),
+ application:unset_env(ssl, session_cb_init_args),
+ application:unset_env(ssl, session_cache_client_max),
+ application:unset_env(ssl, session_cache_server_max),
+ application:unset_env(ssl, ssl_pem_cache_clean),
+ application:unset_env(ssl, bypass_pem_cache),
+ application:unset_env(ssl, alert_timeout).
+
+clean_start() ->
+ ssl:stop(),
+ application:load(ssl),
+ clean_env(),
+ ssl:start().
+
+is_psk_anon_suite({psk, _,_}) ->
+ true;
+is_psk_anon_suite({dhe_psk,_,_}) ->
+ true;
+is_psk_anon_suite({psk, _,_,_}) ->
+ true;
+is_psk_anon_suite({dhe_psk, _,_,_}) ->
+ true;
+is_psk_anon_suite(_) ->
+ false.
+
+cipher_atom(aes_256_cbc) ->
+ aes_cbc256;
+cipher_atom(aes_128_cbc) ->
+ aes_cbc128;
+cipher_atom('3des_ede_cbc') ->
+ des_ede3;
+cipher_atom(Atom) ->
+ Atom.
+tls_version('dtlsv1' = Atom) ->
+ dtls_v1:corresponding_tls_version(dtls_record:protocol_version(Atom));
+tls_version('dtlsv1.2' = Atom) ->
+ dtls_v1:corresponding_tls_version(dtls_record:protocol_version(Atom));
+tls_version(Atom) ->
+ tls_record:protocol_version(Atom).
+
+hardcode_rsa_key(1) ->
+ {'RSAPrivateKey',0,
+ 23995666614853919027835084074500048897452890537492185072956789802729257783422306095699263934587064480357348855732149402060270996295002843755712064937715826848741191927820899197493902093529581182351132392364214171173881547273475904587683433713767834856230531387991145055273426806331200574039205571401702219159773947658558490957010003143162250693492642996408861265758000254664396313741422909188635443907373976005987612936763564996605457102336549804831742940035613780926178523017685712710473543251580072875247250504243621640157403744718833162626193206685233710319205099867303242759099560438381385658382486042995679707669,
+ 17,
+ 11292078406990079542510627799764728892919007311761028269626724613049062486316379339152594792746853873109340637991599718616598115903530750002688030558925094987642913848386305504703012749896273497577003478759630198199473669305165131570674557041773098755873191241407597673069847908861741446606684974777271632545629600685952292605647052193819136445675100211504432575554351515262198132231537860917084269870590492135731720141577986787033006338680118008484613510063003323516659048210893001173583018220214626635609151105287049126443102976056146630518124476470236027123782297108342869049542023328584384300970694412006494684657,
+ 169371138592582642967021557955633494538845517070305333860805485424261447791289944610138334410987654265476540480228705481960508520379619587635662291973699651583489223555422528867090299996446070521801757353675026048850480903160224210802452555900007597342687137394192939372218903554801584969667104937092080815197,
+ 141675062317286527042995673340952251894209529891636708844197799307963834958115010129693036021381525952081167155681637592199810112261679449166276939178032066869788822014115556349519329537177920752776047051833616197615329017439297361972726138285974555338480581117881706656603857310337984049152655480389797687577,
+ 119556097830058336212015217380447172615655659108450823901745048534772786676204666783627059584226579481512852103690850928442711896738555003036938088452023283470698275450886490965004917644550167427154181661417665446247398284583687678213495921811770068712485038160606780733330990744565824684470897602653233516609,
+ 41669135975672507953822256864985956439473391144599032012999352737636422046504414744027363535700448809435637398729893409470532385959317485048904982111185902020526124121798693043976273393287623750816484427009887116945685005129205106462566511260580751570141347387612266663707016855981760014456663376585234613993,
+ 76837684977089699359024365285678488693966186052769523357232308621548155587515525857011429902602352279058920284048929101483304120686557782043616693940283344235057989514310975192908256494992960578961614059245280827077951132083993754797053182279229469590276271658395444955906108899267024101096069475145863928441,
+ asn1_NOVALUE};
+
+hardcode_rsa_key(2) ->
+{'RSAPrivateKey',0,
+ 21343679768589700771839799834197557895311746244621307033143551583788179817796325695589283169969489517156931770973490560582341832744966317712674900833543896521418422508485833901274928542544381247956820115082240721897193055368570146764204557110415281995205343662628196075590438954399631753508888358737971039058298703003743872818150364935790613286541190842600031570570099801682794056444451081563070538409720109449780410837763602317050353477918147758267825417201591905091231778937606362076129350476690460157227101296599527319242747999737801698427160817755293383890373574621116766934110792127739174475029121017282777887777,
+ 17,
+ 18832658619343853622211588088997845201745658451136447382185486691577805721584993260814073385267196632785528033211903435807948675951440868570007265441362261636545666919252206383477878125774454042314841278013741813438699754736973658909592256273895837054592950290554290654932740253882028017801960316533503857992358685308186680144968293076156011747178275038098868263178095174694099811498968993700538293188879611375604635940554394589807673542938082281934965292051746326331046224291377703201248790910007232374006151098976879987912446997911775904329728563222485791845480864283470332826504617837402078265424772379987120023773,
+ 146807662748886761089048448970170315054939768171908279335181627815919052012991509112344782731265837727551849787333310044397991034789843793140419387740928103541736452627413492093463231242466386868459637115999163097726153692593711599245170083315894262154838974616739452594203727376460632750934355508361223110419,
+ 145385325050081892763917667176962991350872697916072592966410309213561884732628046256782356731057378829876640317801978404203665761131810712267778698468684631707642938779964806354584156202882543264893826268426566901882487709510744074274965029453915224310656287149777603803201831202222853023280023478269485417083,
+ 51814469205489445090252393754177758254684624060673510353593515699736136004585238510239335081623236845018299924941168250963996835808180162284853901555621683602965806809675350150634081614988136541809283687999704622726877773856604093851236499993845033701707873394143336209718962603456693912094478414715725803677,
+ 51312467664734785681382706062457526359131540440966797517556579722433606376221663384746714140373192528191755406283051201483646739222992016094510128871300458249756331334105225772206172777487956446433115153562317730076172132768497908567634716277852432109643395464627389577600646306666889302334125933506877206029,
+ 30504662229874176232343608562807118278893368758027179776313787938167236952567905398252901545019583024374163153775359371298239336609182249464886717948407152570850677549297935773605431024166978281486607154204888016179709037883348099374995148481968169438302456074511782717758301581202874062062542434218011141540,
+ asn1_NOVALUE};
+
+hardcode_rsa_key(3) ->
+{'RSAPrivateKey',0,
+ 25089040456112869869472694987833070928503703615633809313972554887193090845137746668197820419383804666271752525807484521370419854590682661809972833718476098189250708650325307850184923546875260207894844301992963978994451844985784504212035958130279304082438876764367292331581532569155681984449177635856426023931875082020262146075451989132180409962870105455517050416234175675478291534563995772675388370042873175344937421148321291640477650173765084699931690748536036544188863178325887393475703801759010864779559318631816411493486934507417755306337476945299570726975433250753415110141783026008347194577506976486290259135429,
+ 17,
+ 8854955455098659953931539407470495621824836570223697404931489960185796768872145882893348383311931058684147950284994536954265831032005645344696294253579799360912014817761873358888796545955974191021709753644575521998041827642041589721895044045980930852625485916835514940558187965584358347452650930302268008446431977397918214293502821599497633970075862760001650736520566952260001423171553461362588848929781360590057040212831994258783694027013289053834376791974167294527043946669963760259975273650548116897900664646809242902841107022557239712438496384819445301703021164043324282687280801738470244471443835900160721870265,
+ 171641816401041100605063917111691927706183918906535463031548413586331728772311589438043965564336865070070922328258143588739626712299625805650832695450270566547004154065267940032684307994238248203186986569945677705100224518137694769557564475390859269797990555863306972197736879644001860925483629009305104925823,
+ 146170909759497809922264016492088453282310383272504533061020897155289106805616042710009332510822455269704884883705830985184223718261139908416790475825625309815234508695722132706422885088219618698987115562577878897003573425367881351537506046253616435685549396767356003663417208105346307649599145759863108910523,
+ 60579464612132153154728441333538327425711971378777222246428851853999433684345266860486105493295364142377972586444050678378691780811632637288529186629507258781295583787741625893888579292084087601124818789392592131211843947578009918667375697196773859928702549128225990187436545756706539150170692591519448797349,
+ 137572620950115585809189662580789132500998007785886619351549079675566218169991569609420548245479957900898715184664311515467504676010484619686391036071176762179044243478326713135456833024206699951987873470661533079532774988581535389682358631768109586527575902839864474036157372334443583670210960715165278974609,
+ 15068630434698373319269196003209754243798959461311186548759287649485250508074064775263867418602372588394608558985183294561315208336731894947137343239541687540387209051236354318837334154993136528453613256169847839789803932725339395739618592522865156272771578671216082079933457043120923342632744996962853951612,
+ asn1_NOVALUE};
+hardcode_rsa_key(4) ->
+{'RSAPrivateKey',0,
+ 28617237755030755643854803617273584643843067580642149032833640135949799721163782522787597288521902619948688786051081993247908700824196122780349730169173433743054172191054872553484065655968335396052034378669869864779940355219732200954630251223541048434478476115391643898092650304645086338265930608997389611376417609043761464100338332976874588396803891301015812818307951159858145399281035705713082131199940309445719678087542976246147777388465712394062188801177717719764254900022006288880246925156931391594131839991579403409541227225173269459173129377291869028712271737734702830877034334838181789916127814298794576266389,
+ 17,
+ 26933870828264240605980991639786903194205240075898493207372837775011576208154148256741268036255908348187001210401018346586267012540419880263858569570986761169933338532757527109161473558558433313931326474042230460969355628442100895016122589386862163232450330461545076609969553227901257730132640573174013751883368376011370428995523268034111482031427024082719896108094847702954695363285832195666458915142143884210891427766607838346722974883433132513540317964796373298134261669479023445911856492129270184781873446960437310543998533283339488055776892320162032014809906169940882070478200435536171854883284366514852906334641,
+ 177342190816702392178883147766999616783253285436834252111702533617098994535049411784501174309695427674025956656849179054202187436663487378682303508229883753383891163725167367039879190685255046547908384208614573353917213168937832054054779266431207529839577747601879940934691505396807977946728204814969824442867,
+ 161367340863680900415977542864139121629424927689088951345472941851682581254789586032968359551717004797621579428672968948552429138154521719743297455351687337112710712475376510559020211584326773715482918387500187602625572442687231345855402020688502483137168684570635690059254866684191216155909970061793538842967,
+ 62591361464718491357252875682470452982324688977706206627659717747211409835899792394529826226951327414362102349476180842659595565881230839534930649963488383547255704844176717778780890830090016428673547367746320007264898765507470136725216211681602657590439205035957626212244060728285168687080542875871702744541,
+ 28476589564178982426348978152495139111074987239250991413906989738532220221433456358759122273832412611344984605059935696803369847909621479954699550944415412431654831613301737157474154985469430655673456186029444871051571607533040825739188591886206320553618003159523945304574388238386685203984112363845918619347,
+ 34340318160575773065401929915821192439103777558577109939078671096408836197675640654693301707202885840826672396546056002756167635035389371579540325327619480512374920136684787633921441576901246290213545161954865184290700344352088099063404416346968182170720521708773285279884132629954461545103181082503707725012,
+ asn1_NOVALUE};
+hardcode_rsa_key(5) ->
+{'RSAPrivateKey',0,
+ 26363170152814518327068346871197765236382539835597898797762992537312221863402655353436079974302838986536256364057947538018476963115004626096654613827403121905035011992899481598437933532388248462251770039307078647864188314916665766359828262009578648593031111569685489178543405615478739906285223620987558499488359880003693226535420421293716164794046859453204135383236667988765227190694994861629971618548127529849059769249520775574008363789050621665120207265361610436965088511042779948238320901918522125988916609088415989475825860046571847719492980547438560049874493788767083330042728150253120940100665370844282489982633,
+ 17,
+ 10855423004100095781734025182257903332628104638187370093196526338893267826106975733767797636477639582691399679317978398007608161282648963686857782164224814902073240232370374775827384395689278778574258251479385325591136364965685903795223402003944149420659869469870495544106108194608892902588033255700759382142132115013969680562678811046675523365751498355532768935784747314021422035957153013494814430893022253205880275287307995039363642554998244274484818208792520243113824379110193356010059999642946040953102866271737127640405568982049887176990990501963784502429481034227543991366980671390566584211881030995602076468001,
+ 163564135568104310461344551909369650951960301778977149705601170951529791054750122905880591964737953456660497440730575925978769763154927541340839715938951226089095007207042122512586007411328664679011914120351043948122025612160733403945093961374276707993674792189646478659304624413958625254578122842556295400709,
+ 161179405627326572739107057023381254841260287988433675196680483761672455172873134522398837271764104320975746111042211695289319249471386600030523328069395763313848583139553961129874895374324504709512019736703349829576024049432816885712623938437949550266365056310544300920756181033500610331519029869549723159637,
+ 115457036871603042678596154288966812436677860079277988027483179495197499568058910286503947269226790675289762899339230065396778656344654735064122152427494983121714122734382674714766593466820233891067233496718383963380253373289929461608301619793607087995535147427985749641862087821617853120878674947686796753441,
+ 142217122612346975946270932667689342506994371754500301644129838613240401623123353990351915239791856753802128921507833848784693455415929352968108818884760967629866396887841730408713142977345151214275311532385308673155315337734838428569962298621720191411498579097539089047726042088382891468987379296661520434973,
+ 40624877259097915043489529504071755460170951428490878553842519165800720914888257733191322215286203357356050737713125202129282154441426952501134581314792133018830748896123382106683994268028624341502298766844710276939303555637478596035491641473828661569958212421472263269629366559343208764012473880251174832392,
+ asn1_NOVALUE};
+hardcode_rsa_key(6) ->
+{'RSAPrivateKey',0,
+ 22748888494866396715768692484866595111939200209856056370972713870125588774286266397044592487895293134537316190976192161177144143633669641697309689280475257429554879273045671863645233402796222694405634510241820106743648116753479926387434021380537483429927516962909367257212902212159798399531316965145618774905828756510318897899298783143203190245236381440043169622358239226123652592179006905016804587837199618842875361941208299410035232803124113612082221121192550063791073372276763648926636149384299189072950588522522800393261949880796214514243704858378436010975184294077063518776479282353562934591448646412389762167039,
+ 17,
+ 6690849557313646092873144848490175032923294179369428344403739373566349639495960705013115437616262686628622409110644753287395336362844012263914614494257428655751435080307550548130951000822418439531068973600535325512837681398082331290421770994275730420566916753796872722709677121223470117509210872101652580854566448661533030419787125312956120661097410038933324613372774190658239039998357548275441758790939430824924502690997433186652165055694361752689819209062683281242276039100201318203707142383491769671330743466041394101421674581185260900666085723130684175548215193875544802254923825103844262661010117443222587769713,
+ 164748737139489923768181260808494855987398781964531448608652166632780898215212977127034263859971474195908846263894581556691971503119888726148555271179103885786024920582830105413607436718060544856016793981261118694063993837665813285582095833772675610567592660039821387740255651489996976698808018635344299728063,
+ 138082323967104548254375818343885141517788525705334488282154811252858957969378263753268344088034079842223206527922445018725900110643394926788280539200323021781309918753249061620424428562366627334409266756720941754364262467100514166396917565961434203543659974860389803369482625510495464845206228470088664021953,
+ 19382204369351755737433089506881747763223386113474288071606137250915399790025056132592266336467232258342217207517009594904937823896457497193947678962247515974826461245038835931012639613889475865413740468383661022831058098548919210068481862796785365949128548239978986792971253116470232552800943368864035262125,
+ 48734937870742781736838524121371226418043009072470995864289933383361985165662916618800592031070851709019955245149098241903258862580021738866451955011878713569874088971734962924855680669070574353320917678842685325069739694270769705787147376221682660074232932303666989424523279591939575827719845342384234360689,
+ 81173034184183681160439870161505779100040258708276674532866007896310418779840630960490793104541748007902477778658270784073595697910785917474138815202903114440800310078464142273778315781957021015333260021813037604142367434117205299831740956310682461174553260184078272196958146289378701001596552915990080834227,
+ asn1_NOVALUE}.
+
+
+dtls_hello() ->
+ [1,
+ <<0,1,4>>,
+ <<0,0>>,
+ <<0,0,0>>,
+ <<0,1,4>>,
+ <<254,253,88,
+ 156,129,61,
+ 131,216,15,
+ 131,194,242,
+ 46,154,190,
+ 20,228,234,
+ 234,150,44,
+ 62,96,96,103,
+ 127,95,103,
+ 23,24,42,138,
+ 13,142,32,57,
+ 230,177,32,
+ 210,154,152,
+ 188,121,134,
+ 136,53,105,
+ 118,96,106,
+ 103,231,223,
+ 133,10,165,
+ 50,32,211,
+ 227,193,14,
+ 181,143,48,
+ 66,0,0,100,0,
+ 255,192,44,
+ 192,48,192,
+ 36,192,40,
+ 192,46,192,
+ 50,192,38,
+ 192,42,0,159,
+ 0,163,0,107,
+ 0,106,0,157,
+ 0,61,192,43,
+ 192,47,192,
+ 35,192,39,
+ 192,45,192,
+ 49,192,37,
+ 192,41,0,158,
+ 0,162,0,103,
+ 0,64,0,156,0,
+ 60,192,10,
+ 192,20,0,57,
+ 0,56,192,5,
+ 192,15,0,53,
+ 192,8,192,18,
+ 0,22,0,19,
+ 192,3,192,13,
+ 0,10,192,9,
+ 192,19,0,51,
+ 0,50,192,4,
+ 192,14,0,47,
+ 1,0,0,86,0,0,
+ 0,14,0,12,0,
+ 0,9,108,111,
+ 99,97,108,
+ 104,111,115,
+ 116,0,10,0,
+ 58,0,56,0,14,
+ 0,13,0,25,0,
+ 28,0,11,0,12,
+ 0,27,0,24,0,
+ 9,0,10,0,26,
+ 0,22,0,23,0,
+ 8,0,6,0,7,0,
+ 20,0,21,0,4,
+ 0,5,0,18,0,
+ 19,0,1,0,2,0,
+ 3,0,15,0,16,
+ 0,17,0,11,0,
+ 2,1,0>>].
+
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
index b3109b5de9..5093ef3728 100644
--- a/lib/ssl/test/ssl_to_openssl_SUITE.erl
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -42,7 +42,9 @@ all() ->
{group, 'tlsv1.2'},
{group, 'tlsv1.1'},
{group, 'tlsv1'},
- {group, 'sslv3'}
+ {group, 'sslv3'},
+ {group, 'dtlsv1.2'},
+ {group, 'dtlsv1'}
].
groups() ->
@@ -50,12 +52,17 @@ groups() ->
{'tlsv1.2', [], all_versions_tests() ++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
{'tlsv1.1', [], all_versions_tests() ++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
{'tlsv1', [], all_versions_tests()++ alpn_tests() ++ npn_tests() ++ sni_server_tests()},
- {'sslv3', [], all_versions_tests()}].
+ {'sslv3', [], all_versions_tests()},
+ {'dtlsv1.2', [], dtls_all_versions_tests()},
+ {'dtlsv1', [], dtls_all_versions_tests()}
+ ].
basic_tests() ->
[basic_erlang_client_openssl_server,
basic_erlang_server_openssl_client,
- expired_session].
+ expired_session,
+ ssl2_erlang_server_openssl_client_comp
+ ].
all_versions_tests() ->
[
@@ -74,7 +81,26 @@ all_versions_tests() ->
ciphers_dsa_signed_certs,
erlang_client_bad_openssl_server,
expired_session,
- ssl2_erlang_server_openssl_client].
+ ssl2_erlang_server_openssl_client
+ ].
+dtls_all_versions_tests() ->
+ [
+ %%erlang_client_openssl_server,
+ erlang_server_openssl_client,
+ %%erlang_client_openssl_server_dsa_cert,
+ erlang_server_openssl_client_dsa_cert,
+ erlang_server_openssl_client_reuse_session
+ %%erlang_client_openssl_server_renegotiate,
+ %%erlang_client_openssl_server_nowrap_seqnum,
+ %%erlang_server_openssl_client_nowrap_seqnum,
+ %%erlang_client_openssl_server_no_server_ca_cert,
+ %%erlang_client_openssl_server_client_cert,
+ %%erlang_server_openssl_client_client_cert
+ %%ciphers_rsa_signed_certs,
+ %%ciphers_dsa_signed_certs,
+ %%erlang_client_bad_openssl_server,
+ %%expired_session
+ ].
alpn_tests() ->
[erlang_client_alpn_openssl_server_alpn,
@@ -116,7 +142,7 @@ init_per_suite(Config0) ->
catch crypto:stop(),
try crypto:start() of
ok ->
- ssl:start(),
+ ssl_test_lib:clean_start(),
{ok, _} = make_certs:all(proplists:get_value(data_dir, Config0),
proplists:get_value(priv_dir, Config0)),
Config1 = ssl_test_lib:make_dsa_cert(Config0),
@@ -141,13 +167,18 @@ init_per_group(basic, Config) ->
init_per_group(GroupName, Config) ->
case ssl_test_lib:is_tls_version(GroupName) of
true ->
- case ssl_test_lib:check_sane_openssl_version(GroupName) of
- true ->
- ssl_test_lib:init_tls_version(GroupName, Config);
- false ->
- {skip, openssl_does_not_support_version}
- end;
- _ ->
+ case ssl_test_lib:supports_ssl_tls_version(GroupName) of
+ true ->
+ case ssl_test_lib:check_sane_openssl_version(GroupName) of
+ true ->
+ ssl_test_lib:init_tls_version(GroupName, Config);
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ false ->
+ {skip, openssl_does_not_support_version}
+ end;
+ _ ->
ssl:start(),
Config
end.
@@ -180,7 +211,8 @@ special_init(TestCase, Config)
{ok, Version} = application:get_env(ssl, protocol_version),
check_sane_openssl_renegotaite(Config, Version);
-special_init(ssl2_erlang_server_openssl_client, Config) ->
+special_init(Case, Config) when Case == ssl2_erlang_server_openssl_client;
+ Case == ssl2_erlang_server_openssl_client_comp ->
case ssl_test_lib:supports_ssl_tls_version(sslv2) of
true ->
Config;
@@ -280,7 +312,8 @@ basic_erlang_client_openssl_server(Config) when is_list(Config) ->
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+
+ ssl_test_lib:wait_for_openssl_server(Port, tls),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -353,7 +386,7 @@ erlang_client_openssl_server(Config) when is_list(Config) ->
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -427,7 +460,7 @@ erlang_client_openssl_server_dsa_cert(Config) when is_list(Config) ->
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -547,7 +580,7 @@ erlang_client_openssl_server_renegotiate(Config) when is_list(Config) ->
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -596,7 +629,7 @@ erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) ->
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -677,7 +710,7 @@ erlang_client_openssl_server_no_server_ca_cert(Config) when is_list(Config) ->
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -720,7 +753,7 @@ erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -830,7 +863,7 @@ ciphers_dsa_signed_certs() ->
[{doc,"Test cipher suites that uses dsa certs"}].
ciphers_dsa_signed_certs(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:dsa_suites(),
+ Ciphers = ssl_test_lib:dsa_suites(tls_record:protocol_version(Version)),
run_suites(Ciphers, Version, Config, dsa).
%%--------------------------------------------------------------------
@@ -852,7 +885,7 @@ erlang_client_bad_openssl_server(Config) when is_list(Config) ->
"-cert", CertFile, "-key", KeyFile],
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -907,7 +940,7 @@ expired_session(Config) when is_list(Config) ->
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, tls),
Client0 =
ssl_test_lib:start_client([{node, ClientNode},
@@ -951,11 +984,39 @@ ssl2_erlang_server_openssl_client(Config) when is_list(Config) ->
{_, ServerNode, _} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Exe = "openssl",
+ Args = ["s_client", "-connect", "localhost:" ++ integer_to_list(Port),
+ "-ssl2", "-msg"],
+
+ OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ct:log("Ports ~p~n", [[erlang:port_info(P) || P <- erlang:ports()]]),
+ consume_port_exit(OpenSslPort),
+ ssl_test_lib:check_result(Server, {error, {tls_alert, "handshake failure"}}),
+ process_flag(trap_exit, false).
+%%--------------------------------------------------------------------
+ssl2_erlang_server_openssl_client_comp() ->
+ [{doc,"Test that ssl v2 clients are rejected"}].
+
+ssl2_erlang_server_openssl_client_comp(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ V2Compat = proplists:get_value(v2_hello_compatible, Config),
+
+ ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
Data = "From openssl to erlang",
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
- {options, ServerOpts}]),
+ {options, [{v2_hello_compatible, V2Compat} | ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Exe = "openssl",
@@ -966,20 +1027,7 @@ ssl2_erlang_server_openssl_client(Config) when is_list(Config) ->
true = port_command(OpenSslPort, Data),
ct:log("Ports ~p~n", [[erlang:port_info(P) || P <- erlang:ports()]]),
- receive
- {'EXIT', OpenSslPort, _} = Exit ->
- ct:log("Received: ~p ~n", [Exit]),
- ok
- end,
- receive
- {'EXIT', _, _} = UnkownExit ->
- Msg = lists:flatten(io_lib:format("Received: ~p ~n", [UnkownExit])),
- ct:log(Msg),
- ct:comment(Msg),
- ok
- after 0 ->
- ok
- end,
+ consume_port_exit(OpenSslPort),
ssl_test_lib:check_result(Server, {error, {tls_alert, "protocol version"}}),
process_flag(trap_exit, false).
@@ -1264,7 +1312,7 @@ client_check_result(Port, DataExpected, DataReceived) ->
_ ->
client_check_result(Port, DataExpected, NewData)
end
- after 3000 ->
+ after 20000 ->
ct:fail({"Time out on openSSL Client", {expected, DataExpected},
{got, DataReceived}})
end.
@@ -1351,7 +1399,7 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
OpenSslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
ConnectionInfo = {ok, {Version, CipherSuite}},
@@ -1421,7 +1469,7 @@ start_erlang_client_and_openssl_server_with_opts(Config, ErlangClientOpts, Opens
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -1457,7 +1505,7 @@ start_erlang_client_and_openssl_server_for_alpn_negotiation(Config, Data, Callba
Args = ["s_server", "-msg", "-alpn", "http/1.1,spdy/2", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
"-cert", CertFile, "-key", KeyFile],
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -1526,7 +1574,7 @@ start_erlang_client_and_openssl_server_for_alpn_npn_negotiation(Config, Data, Ca
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -1591,7 +1639,7 @@ start_erlang_client_and_openssl_server_for_npn_negotiation(Config, Data, Callbac
"-cert", CertFile, "-key", KeyFile],
OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
- ssl_test_lib:wait_for_openssl_server(Port),
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
@@ -1800,3 +1848,9 @@ openssl_client_args(false, Hostname, Port, ServerName) ->
openssl_client_args(true, Hostname, Port, ServerName) ->
["s_client", "-no_ssl2", "-connect", Hostname ++ ":" ++
integer_to_list(Port), "-servername", ServerName].
+
+consume_port_exit(OpenSSLPort) ->
+ receive
+ {'EXIT', OpenSSLPort, _} ->
+ ok
+ end.
diff --git a/lib/ssl/test/ssl_upgrade_SUITE.erl b/lib/ssl/test/ssl_upgrade_SUITE.erl
index 113b3b4158..875399db76 100644
--- a/lib/ssl/test/ssl_upgrade_SUITE.erl
+++ b/lib/ssl/test/ssl_upgrade_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2014-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,7 +29,8 @@
server,
client,
soft,
- result_proxy
+ result_proxy,
+ skip
}).
all() ->
@@ -73,8 +74,15 @@ major_upgrade(Config) when is_list(Config) ->
minor_upgrade(Config) when is_list(Config) ->
ct_release_test:upgrade(ssl, minor,{?MODULE, #state{config = Config}}, Config).
-upgrade_init(CTData, #state{config = Config} = State) ->
- {ok, {_, _, Up, _Down}} = ct_release_test:get_appup(CTData, ssl),
+upgrade_init(CtData, State) ->
+ {ok,{FromVsn,ToVsn}} = ct_release_test:get_app_vsns(CtData, ssl),
+ upgrade_init(FromVsn, ToVsn, CtData, State).
+
+upgrade_init(_, "8.0.2", _, State) ->
+ %% Requires stdlib upgrade so it will be a node upgrade!
+ State#state{skip = true};
+upgrade_init(_, _, CtData, #state{config = Config} = State) ->
+ {ok, {_, _, Up, _Down}} = ct_release_test:get_appup(CtData, ssl),
ct:pal("Up: ~p", [Up]),
Soft = is_soft(Up), %% It is symmetrical, if upgrade is soft so is downgrade
Pid = spawn(?MODULE, result_proxy_init, [[]]),
@@ -88,6 +96,8 @@ upgrade_init(CTData, #state{config = Config} = State) ->
State#state{soft = Soft, result_proxy = Pid}
end.
+upgrade_upgraded(_, #state{skip = true} = State) ->
+ State;
upgrade_upgraded(_, #state{soft = false, config = Config, result_proxy = Pid} = State) ->
ct:pal("Restart upgrade ~n", []),
{Server, Client} = restart_start_connection(Config, Pid),
@@ -96,7 +106,6 @@ upgrade_upgraded(_, #state{soft = false, config = Config, result_proxy = Pid} =
ssl_test_lib:close(Client),
ok = Result,
State;
-
upgrade_upgraded(_, #state{server = Server0, client = Client0,
config = Config, soft = true,
result_proxy = Pid} = State) ->
@@ -110,6 +119,8 @@ upgrade_upgraded(_, #state{server = Server0, client = Client0,
{Server, Client} = soft_start_connection(Config, Pid),
State#state{server = Server, client = Client}.
+upgrade_downgraded(_, #state{skip = true} = State) ->
+ State;
upgrade_downgraded(_, #state{soft = false, config = Config, result_proxy = Pid} = State) ->
ct:pal("Restart downgrade: ~n", []),
{Server, Client} = restart_start_connection(Config, Pid),
@@ -119,7 +130,6 @@ upgrade_downgraded(_, #state{soft = false, config = Config, result_proxy = Pid}
Pid ! stop,
ok = Result,
State;
-
upgrade_downgraded(_, #state{server = Server, client = Client, soft = true, result_proxy = Pid} = State) ->
ct:pal("Soft downgrade: ~n", []),
Server ! changed_version,
diff --git a/lib/ssl/test/x509_test.erl b/lib/ssl/test/x509_test.erl
new file mode 100644
index 0000000000..4da1537ef6
--- /dev/null
+++ b/lib/ssl/test/x509_test.erl
@@ -0,0 +1,352 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+ -module(x509_test).
+
+ -include_lib("public_key/include/public_key.hrl").
+
+ -export([gen_test_certs/1, gen_pem_config_files/3]).
+
+ gen_test_certs(Opts) ->
+ SRootKey = gen_key(proplists:get_value(server_key_gen, Opts)),
+ CRootKey = gen_key(proplists:get_value(client_key_gen, Opts)),
+ ServerRoot = root_cert("server", SRootKey, Opts),
+ ClientRoot = root_cert("client", CRootKey, Opts),
+ [{ServerCert, ServerKey} | ServerCAsKeys] = config(server, ServerRoot, SRootKey, Opts),
+ [{ClientCert, ClientKey} | ClientCAsKeys] = config(client, ClientRoot, CRootKey, Opts),
+ ServerCAs = ca_config(ClientRoot, ServerCAsKeys),
+ ClientCAs = ca_config(ServerRoot, ClientCAsKeys),
+ [{server_config, [{cert, ServerCert}, {key, ServerKey}, {cacerts, ServerCAs}]},
+ {client_config, [{cert, ClientCert}, {key, ClientKey}, {cacerts, ClientCAs}]}].
+
+gen_pem_config_files(GenCertData, ClientBase, ServerBase) ->
+ ServerConf = proplists:get_value(server_config, GenCertData),
+ ClientConf = proplists:get_value(client_config, GenCertData),
+
+ ServerCaCertFile = ServerBase ++ "_server_cacerts.pem",
+ ServerCertFile = ServerBase ++ "_server_cert.pem",
+ ServerKeyFile = ServerBase ++ "_server_key.pem",
+
+ ClientCaCertFile = ClientBase ++ "_client_cacerts.pem",
+ ClientCertFile = ClientBase ++ "_client_cert.pem",
+ ClientKeyFile = ClientBase ++ "_client_key.pem",
+
+ do_gen_pem_config_files(ServerConf,
+ ServerCertFile,
+ ServerKeyFile,
+ ServerCaCertFile),
+ do_gen_pem_config_files(ClientConf,
+ ClientCertFile,
+ ClientKeyFile,
+ ClientCaCertFile),
+ [{server_config, [{certfile, ServerCertFile},
+ {keyfile, ServerKeyFile}, {cacertfile, ServerCaCertFile}]},
+ {client_config, [{certfile, ClientCertFile},
+ {keyfile, ClientKeyFile}, {cacertfile, ClientCaCertFile}]}].
+
+
+ do_gen_pem_config_files(Config, CertFile, KeyFile, CAFile) ->
+ CAs = proplists:get_value(cacerts, Config),
+ Cert = proplists:get_value(cert, Config),
+ Key = proplists:get_value(key, Config),
+ der_to_pem(CertFile, [cert_entry(Cert)]),
+ der_to_pem(KeyFile, [key_entry(Key)]),
+ der_to_pem(CAFile, ca_entries(CAs)).
+
+ cert_entry(Cert) ->
+ {'Certificate', Cert, not_encrypted}.
+
+ key_entry(Key = #'RSAPrivateKey'{}) ->
+ Der = public_key:der_encode('RSAPrivateKey', Key),
+ {'RSAPrivateKey', Der, not_encrypted};
+ key_entry(Key = #'DSAPrivateKey'{}) ->
+ Der = public_key:der_encode('DSAPrivateKey', Key),
+ {'DSAPrivateKey', Der, not_encrypted};
+ key_entry(Key = #'ECPrivateKey'{}) ->
+ Der = public_key:der_encode('ECPrivateKey', Key),
+ {'ECPrivateKey', Der, not_encrypted}.
+
+ ca_entries(CAs) ->
+ [{'Certificate', CACert, not_encrypted} || CACert <- CAs].
+
+ gen_key(KeyGen) ->
+ case is_key(KeyGen) of
+ true ->
+ KeyGen;
+ false ->
+ public_key:generate_key(KeyGen)
+ end.
+
+root_cert(Role, PrivKey, Opts) ->
+ TBS = cert_template(),
+ Issuer = issuer("root", Role, " ROOT CA"),
+ OTPTBS = TBS#'OTPTBSCertificate'{
+ signature = sign_algorithm(PrivKey, Opts),
+ issuer = Issuer,
+ validity = validity(Opts),
+ subject = Issuer,
+ subjectPublicKeyInfo = public_key(PrivKey),
+ extensions = extensions(Role, ca, Opts)
+ },
+ public_key:pkix_sign(OTPTBS, PrivKey).
+
+config(Role, Root, Key, Opts) ->
+ KeyGenOpt = list_to_atom(atom_to_list(Role) ++ "_key_gen_chain"),
+ KeyGens = proplists:get_value(KeyGenOpt, Opts, default_key_gen()),
+ Keys = lists:map(fun gen_key/1, KeyGens),
+ cert_chain(Role, Root, Key, Opts, Keys).
+
+cert_template() ->
+ #'OTPTBSCertificate'{
+ version = v3,
+ serialNumber = trunc(rand:uniform()*100000000)*10000 + 1,
+ issuerUniqueID = asn1_NOVALUE,
+ subjectUniqueID = asn1_NOVALUE
+ }.
+
+issuer(Contact, Role, Name) ->
+ subject(Contact, Role ++ Name).
+
+subject(Contact, Name) ->
+ Opts = [{email, Contact ++ "@erlang.org"},
+ {name, Name},
+ {city, "Stockholm"},
+ {country, "SE"},
+ {org, "erlang"},
+ {org_unit, "automated testing"}],
+ subject(Opts).
+
+subject(SubjectOpts) when is_list(SubjectOpts) ->
+ Encode = fun(Opt) ->
+ {Type,Value} = subject_enc(Opt),
+ [#'AttributeTypeAndValue'{type=Type, value=Value}]
+ end,
+ {rdnSequence, [Encode(Opt) || Opt <- SubjectOpts]}.
+
+subject_enc({name, Name}) ->
+ {?'id-at-commonName', {printableString, Name}};
+subject_enc({email, Email}) ->
+ {?'id-emailAddress', Email};
+subject_enc({city, City}) ->
+ {?'id-at-localityName', {printableString, City}};
+subject_enc({state, State}) ->
+ {?'id-at-stateOrProvinceName', {printableString, State}};
+subject_enc({org, Org}) ->
+ {?'id-at-organizationName', {printableString, Org}};
+subject_enc({org_unit, OrgUnit}) ->
+ {?'id-at-organizationalUnitName', {printableString, OrgUnit}};
+subject_enc({country, Country}) ->
+ {?'id-at-countryName', Country};
+subject_enc({serial, Serial}) ->
+ {?'id-at-serialNumber', Serial};
+subject_enc({title, Title}) ->
+ {?'id-at-title', {printableString, Title}};
+subject_enc({dnQualifer, DnQ}) ->
+ {?'id-at-dnQualifier', DnQ};
+subject_enc(Other) ->
+ Other.
+
+validity(Opts) ->
+ DefFrom0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())-1),
+ DefTo0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())+7),
+ {DefFrom, DefTo} = proplists:get_value(validity, Opts, {DefFrom0, DefTo0}),
+ Format = fun({Y,M,D}) ->
+ lists:flatten(io_lib:format("~w~2..0w~2..0w000000Z",[Y,M,D]))
+ end,
+ #'Validity'{notBefore={generalTime, Format(DefFrom)},
+ notAfter ={generalTime, Format(DefTo)}}.
+
+extensions(Role, Type, Opts) ->
+ Exts = proplists:get_value(extensions, Opts, []),
+ lists:flatten([extension(Ext) || Ext <- default_extensions(Role, Type, Exts)]).
+
+%% Common extension: name_constraints, policy_constraints, ext_key_usage, inhibit_any,
+%% auth_key_id, subject_key_id, policy_mapping,
+
+default_extensions(_, ca, Exts) ->
+ Def = [{key_usage, [keyCertSign, cRLSign]},
+ {basic_constraints, default}],
+ add_default_extensions(Def, Exts);
+
+default_extensions(server, peer, Exts) ->
+ Hostname = net_adm:localhost(),
+ Def = [{key_usage, [digitalSignature, keyAgreement]},
+ {subject_alt, Hostname}],
+ add_default_extensions(Def, Exts);
+
+default_extensions(_, peer, Exts) ->
+ Exts.
+
+add_default_extensions(Def, Exts) ->
+ Filter = fun({Key, _}, D) ->
+ lists:keydelete(Key, 1, D);
+ ({Key, _, _}, D) ->
+ lists:keydelete(Key, 1, D)
+ end,
+ Exts ++ lists:foldl(Filter, Def, Exts).
+
+extension({_, undefined}) ->
+ [];
+extension({basic_constraints, Data}) ->
+ case Data of
+ default ->
+ #'Extension'{extnID = ?'id-ce-basicConstraints',
+ extnValue = #'BasicConstraints'{cA=true},
+ critical=true};
+ false ->
+ [];
+ Len when is_integer(Len) ->
+ #'Extension'{extnID = ?'id-ce-basicConstraints',
+ extnValue = #'BasicConstraints'{cA=true, pathLenConstraint = Len},
+ critical = true};
+ _ ->
+ #'Extension'{extnID = ?'id-ce-basicConstraints',
+ extnValue = Data}
+ end;
+extension({auth_key_id, {Oid, Issuer, SNr}}) ->
+ #'Extension'{extnID = ?'id-ce-authorityKeyIdentifier',
+ extnValue = #'AuthorityKeyIdentifier'{
+ keyIdentifier = Oid,
+ authorityCertIssuer = Issuer,
+ authorityCertSerialNumber = SNr},
+ critical = false};
+extension({key_usage, Value}) ->
+ #'Extension'{extnID = ?'id-ce-keyUsage',
+ extnValue = Value,
+ critical = false};
+extension({subject_alt, Hostname}) ->
+ #'Extension'{extnID = ?'id-ce-subjectAltName',
+ extnValue = [{dNSName, Hostname}],
+ critical = false};
+extension({Id, Data, Critical}) ->
+ #'Extension'{extnID = Id, extnValue = Data, critical = Critical}.
+
+public_key(#'RSAPrivateKey'{modulus=N, publicExponent=E}) ->
+ Public = #'RSAPublicKey'{modulus=N, publicExponent=E},
+ Algo = #'PublicKeyAlgorithm'{algorithm= ?rsaEncryption, parameters='NULL'},
+ #'OTPSubjectPublicKeyInfo'{algorithm = Algo,
+ subjectPublicKey = Public};
+public_key(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) ->
+ Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-dsa',
+ parameters={params, #'Dss-Parms'{p=P, q=Q, g=G}}},
+ #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y};
+public_key(#'ECPrivateKey'{version = _Version,
+ privateKey = _PrivKey,
+ parameters = Params,
+ publicKey = PubKey}) ->
+ Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-ecPublicKey', parameters=Params},
+ #'OTPSubjectPublicKeyInfo'{algorithm = Algo,
+ subjectPublicKey = #'ECPoint'{point = PubKey}}.
+
+sign_algorithm(#'RSAPrivateKey'{}, Opts) ->
+ Type = rsa_digest_oid(proplists:get_value(digest, Opts, sha1)),
+ #'SignatureAlgorithm'{algorithm = Type,
+ parameters = 'NULL'};
+sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) ->
+ #'SignatureAlgorithm'{algorithm = ?'id-dsa-with-sha1',
+ parameters = {params,#'Dss-Parms'{p=P, q=Q, g=G}}};
+sign_algorithm(#'ECPrivateKey'{parameters = Parms}, Opts) ->
+ Type = ecdsa_digest_oid(proplists:get_value(digest, Opts, sha1)),
+ #'SignatureAlgorithm'{algorithm = Type,
+ parameters = Parms}.
+
+rsa_digest_oid(sha1) ->
+ ?'sha1WithRSAEncryption';
+rsa_digest_oid(sha512) ->
+ ?'sha512WithRSAEncryption';
+rsa_digest_oid(sha384) ->
+ ?'sha384WithRSAEncryption';
+rsa_digest_oid(sha256) ->
+ ?'sha256WithRSAEncryption';
+rsa_digest_oid(md5) ->
+ ?'md5WithRSAEncryption'.
+
+ecdsa_digest_oid(sha1) ->
+ ?'ecdsa-with-SHA1';
+ecdsa_digest_oid(sha512) ->
+ ?'ecdsa-with-SHA512';
+ecdsa_digest_oid(sha384) ->
+ ?'ecdsa-with-SHA384';
+ecdsa_digest_oid(sha256) ->
+ ?'ecdsa-with-SHA256'.
+
+ca_config(Root, CAsKeys) ->
+ [Root | [CA || {CA, _} <- CAsKeys]].
+
+cert_chain(Role, Root, RootKey, Opts, Keys) ->
+ cert_chain(Role, Root, RootKey, Opts, Keys, 0, []).
+
+cert_chain(Role, IssuerCert, IssuerKey, Opts, [Key], _, Acc) ->
+ PeerOpts = list_to_atom(atom_to_list(Role) ++ "_peer_opts"),
+ Cert = cert(Role, public_key:pkix_decode_cert(IssuerCert, otp),
+ IssuerKey, Key, "admin", " Peer cert", Opts, PeerOpts, peer),
+ [{Cert, Key}, {IssuerCert, IssuerKey} | Acc];
+cert_chain(Role, IssuerCert, IssuerKey, Opts, [Key | Keys], N, Acc) ->
+ CAOpts = list_to_atom(atom_to_list(Role) ++ "_ca_" ++ integer_to_list(N)),
+ Cert = cert(Role, public_key:pkix_decode_cert(IssuerCert, otp), IssuerKey, Key, "webadmin",
+ " Intermidiate CA " ++ integer_to_list(N), Opts, CAOpts, ca),
+ cert_chain(Role, Cert, Key, Opts, Keys, N+1, [{IssuerCert, IssuerKey} | Acc]).
+
+cert(Role, #'OTPCertificate'{tbsCertificate = #'OTPTBSCertificate'{subject = Issuer,
+ serialNumber = SNr
+ }},
+ PrivKey, Key, Contact, Name, Opts, CertOptsName, Type) ->
+ CertOpts = proplists:get_value(CertOptsName, Opts, []),
+ TBS = cert_template(),
+ OTPTBS = TBS#'OTPTBSCertificate'{
+ signature = sign_algorithm(PrivKey, Opts),
+ issuer = Issuer,
+ validity = validity(CertOpts),
+ subject = subject(Contact, atom_to_list(Role) ++ Name),
+ subjectPublicKeyInfo = public_key(Key),
+ extensions = extensions(Role, Type,
+ add_default_extensions([{auth_key_id, {auth_key_oid(Role), Issuer, SNr}}],
+ CertOpts))
+ },
+ public_key:pkix_sign(OTPTBS, PrivKey).
+
+is_key(#'DSAPrivateKey'{}) ->
+ true;
+is_key(#'RSAPrivateKey'{}) ->
+ true;
+is_key(#'ECPrivateKey'{}) ->
+ true;
+is_key(_) ->
+ false.
+
+der_to_pem(File, Entries) ->
+ PemBin = public_key:pem_encode(Entries),
+ file:write_file(File, PemBin).
+
+default_key_gen() ->
+ case tls_v1:ecc_curves(0) of
+ [] ->
+ [{rsa, 2048, 17}, {rsa, 2048, 17}];
+ [_|_] ->
+ [{namedCurve, hd(tls_v1:ecc_curves(0))},
+ {namedCurve, hd(tls_v1:ecc_curves(0))}]
+ end.
+
+auth_key_oid(server) ->
+ ?'id-kp-serverAuth';
+auth_key_oid(client) ->
+ ?'id-kp-clientAuth'.
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index 3b51fa8c6b..25b2a2bec0 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1 +1 @@
-SSL_VSN = 8.0
+SSL_VSN = 8.2
diff --git a/lib/stdlib/doc/src/assert_hrl.xml b/lib/stdlib/doc/src/assert_hrl.xml
index e2dfc2ab9b..ea23cca2ee 100644
--- a/lib/stdlib/doc/src/assert_hrl.xml
+++ b/lib/stdlib/doc/src/assert_hrl.xml
@@ -4,7 +4,7 @@
<fileref>
<header>
<copyright>
- <year>2012</year><year>2015</year>
+ <year>2012</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -28,7 +28,7 @@
<date></date>
<rev></rev>
</header>
- <file>assert.hrl.xml</file>
+ <file>assert.hrl</file>
<filesummary>Assert macros.</filesummary>
<description>
<p>The include file <c>assert.hrl</c> provides macros for inserting
@@ -49,25 +49,33 @@
entries in the <c>Info</c> list are optional; do not rely programatically
on any of them being present.</p>
+ <p>Each assert macro has a corresponding version with an extra argument,
+ for adding comments to assertions. These can for example be printed as
+ part of error reports, to clarify the meaning of the check that
+ failed. For example, <c>?assertEqual(0, fib(0), "Fibonacci is defined
+ for zero")</c>. The comment text can be any character data (string,
+ UTF8-binary, or deep list of such data), and will be included in the
+ error term as <c>{comment, Text}</c>.</p>
+
<p>If the macro <c>NOASSERT</c> is defined when <c>assert.hrl</c> is read
by the compiler, the macros are defined as equivalent to the atom
- <c>ok</c>. The test is not performed and there is no cost at runtime.</p>
+ <c>ok</c>. The test will not be performed and there is no cost at runtime.</p>
<p>For example, using <c>erlc</c> to compile your modules, the following
- disable all assertions:</p>
+ disables all assertions:</p>
<code type="none">
erlc -DNOASSERT=true *.erl</code>
- <p>The value of <c>NOASSERT</c> does not matter, only the fact that it is
- defined.</p>
+ <p>(The value of <c>NOASSERT</c> does not matter, only the fact that it is
+ defined.)</p>
<p>A few other macros also have effect on the enabling or disabling of
assertions:</p>
<list type="bulleted">
- <item><p>If <c>NODEBUG</c> is defined, it implies <c>NOASSERT</c>, unless
- <c>DEBUG</c> is also defined, which is assumed to take precedence.</p>
+ <item><p>If <c>NODEBUG</c> is defined, it implies <c>NOASSERT</c> (unless
+ <c>DEBUG</c> is also defined, which overrides <c>NODEBUG</c>).</p>
</item>
<item><p>If <c>ASSERT</c> is defined, it overrides <c>NOASSERT</c>, that
is, the assertions remain enabled.</p></item>
@@ -84,16 +92,22 @@ erlc -DNOASSERT=true *.erl</code>
<title>Macros</title>
<taglist>
<tag><c>assert(BoolExpr)</c></tag>
+ <item></item>
+ <tag><c>URKAassert(BoolExpr, Comment)</c></tag>
<item>
<p>Tests that <c>BoolExpr</c> completes normally returning
<c>true</c>.</p>
</item>
<tag><c>assertNot(BoolExpr)</c></tag>
+ <item></item>
+ <tag><c>assertNot(BoolExpr, Comment)</c></tag>
<item>
<p>Tests that <c>BoolExpr</c> completes normally returning
<c>false</c>.</p>
</item>
<tag><c>assertMatch(GuardedPattern, Expr)</c></tag>
+ <item></item>
+ <tag><c>assertMatch(GuardedPattern, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> completes normally yielding a value that
matches <c>GuardedPattern</c>, for example:</p>
@@ -104,6 +118,8 @@ erlc -DNOASSERT=true *.erl</code>
?assertMatch({bork, X} when X > 0, f())</code>
</item>
<tag><c>assertNotMatch(GuardedPattern, Expr)</c></tag>
+ <item></item>
+ <tag><c>assertNotMatch(GuardedPattern, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> completes normally yielding a value that does
not match <c>GuardedPattern</c>.</p>
@@ -111,16 +127,22 @@ erlc -DNOASSERT=true *.erl</code>
<c>when</c> part.</p>
</item>
<tag><c>assertEqual(ExpectedValue, Expr)</c></tag>
+ <item></item>
+ <tag><c>assertEqual(ExpectedValue, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> completes normally yielding a value that is
exactly equal to <c>ExpectedValue</c>.</p>
</item>
<tag><c>assertNotEqual(ExpectedValue, Expr)</c></tag>
+ <item></item>
+ <tag><c>assertNotEqual(ExpectedValue, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> completes normally yielding a value that is
not exactly equal to <c>ExpectedValue</c>.</p>
</item>
<tag><c>assertException(Class, Term, Expr)</c></tag>
+ <item></item>
+ <tag><c>assertException(Class, Term, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> completes abnormally with an exception of type
<c>Class</c> and with the associated <c>Term</c>. The assertion fails
@@ -130,6 +152,8 @@ erlc -DNOASSERT=true *.erl</code>
patterns, as in <c>assertMatch</c>.</p>
</item>
<tag><c>assertNotException(Class, Term, Expr)</c></tag>
+ <item></item>
+ <tag><c>assertNotException(Class, Term, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> does not evaluate abnormally with an
exception of type <c>Class</c> and with the associated <c>Term</c>.
@@ -139,14 +163,20 @@ erlc -DNOASSERT=true *.erl</code>
be guarded patterns.</p>
</item>
<tag><c>assertError(Term, Expr)</c></tag>
+ <item></item>
+ <tag><c>assertError(Term, Expr, Comment)</c></tag>
<item>
<p>Equivalent to <c>assertException(error, Term, Expr)</c></p>
</item>
<tag><c>assertExit(Term, Expr)</c></tag>
+ <item></item>
+ <tag><c>assertExit(Term, Expr, Comment)</c></tag>
<item>
<p>Equivalent to <c>assertException(exit, Term, Expr)</c></p>
</item>
<tag><c>assertThrow(Term, Expr)</c></tag>
+ <item></item>
+ <tag><c>assertThrow(Term, Expr, Comment)</c></tag>
<item>
<p>Equivalent to <c>assertException(throw, Term, Expr)</c></p>
</item>
diff --git a/lib/stdlib/doc/src/beam_lib.xml b/lib/stdlib/doc/src/beam_lib.xml
index d5ec90b060..26d0724aaf 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>2016</year>
+ <year>2000</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -42,10 +42,10 @@
and the corresponding identifiers are as follows:</p>
<list type="bulleted">
- <item><c>abstract_code ("Abst")</c></item>
<item><c>atoms ("Atom")</c></item>
<item><c>attributes ("Attr")</c></item>
<item><c>compile_info ("CInf")</c></item>
+ <item><c>debug_info ("Dbgi")</c></item>
<item><c>exports ("ExpT")</c></item>
<item><c>imports ("ImpT")</c></item>
<item><c>indexed_imports ("ImpT")</c></item>
@@ -60,9 +60,8 @@
<title>Debug Information/Abstract Code</title>
<p>Option <c>debug_info</c> can be specified to the Compiler (see
<seealso marker="compiler:compile#debug_info"><c>compile(3)</c></seealso>)
- to have debug information in the form of abstract code (see section
- <seealso marker="erts:absform">The Abstract Format</seealso> in the
- ERTS User's Guide) stored in the <c>abstract_code</c> chunk.
+ to have debug information, such as <seealso marker="erts:absform">Erlang
+ Abstract Format</seealso>, stored in the <c>debug_info</c> chunk.
Tools such as Debugger and Xref require the debug information to
be included.</p>
@@ -79,7 +78,7 @@
<section>
<title>Reconstruct Source Code</title>
- <p>The following example shows how to reconstruct source code from
+ <p>The following example shows how to reconstruct Erlang source code from
the debug information in a BEAM file <c>Beam</c>:</p>
<code type="none">
@@ -117,7 +116,7 @@ io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).</code>
<list type="ordered">
<item>
- <p>Use Compiler option <c>{debug_info,Key}</c>, see
+ <p>Use Compiler option <c>{debug_info_key,Key}</c>, see
<seealso marker="compiler:compile#debug_info_key"><c>compile(3)</c></seealso>
and function
<seealso marker="#crypto_key_fun/1"><c>crypto_key_fun/1</c></seealso>
@@ -198,18 +197,40 @@ io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).</code>
<datatype>
<name name="chunkid"/>
<desc>
- <p>"Abst" | "Attr" | "CInf" | "ExpT" | "ImpT" | "LocT" | "Atom"</p>
+ <p>"Attr" | "CInf" | "Dbgi" | "ExpT" | "ImpT" | "LocT" | "AtU8"</p>
</desc>
</datatype>
<datatype>
<name name="dataB"/>
</datatype>
<datatype>
+ <name name="debug_info"/>
+ <desc>
+ <p>The format stored in the <c>debug_info</c> chunk.
+ To retrieve particular code representation from the backend,
+ <c>Backend:debug_info(Format, Module, Data, Opts)</c> must be
+ invoked. <c>Format</c> is an atom, such as <c>erlang_v1</c> for
+ the Erlang Abstract Format or <c>core_v1</c> for Core Erlang.
+ <c>Module</c> is the module represented by the beam file and
+ <c>Data</c> is the value stored in the debug info chunk.
+ <c>Opts</c> is any list of values supported by the <c>Backend</c>.
+ <c>Backend:debug_info/4</c> must return <c>{ok, Code}</c> or
+ <c>{error, Term}</c>.</p>
+
+ <p>Developers must always invoke the <c>debug_info/4</c> function
+ and never rely on the <c>Data</c> stored in the <c>debug_info</c>
+ chunk, as it is opaque and may change at any moment. <c>no_debug_info</c>
+ means that chunk <c>"Dbgi"</c> is present, but empty.</p>
+ </desc>
+ </datatype>
+ <datatype>
<name name="abst_code"/>
<desc>
<p>It is not checked that the forms conform to the abstract format
indicated by <c><anno>AbstVersion</anno></c>. <c>no_abstract_code</c>
means that chunk <c>"Abst"</c> is present, but empty.</p>
+ <p>For modules compiled with OTP 20 onwards, the <c>abst_code</c> chunk
+ is automatically computed from the <c>debug_info</c> chunk.</p>
</desc>
</datatype>
<datatype>
@@ -346,7 +367,7 @@ io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).</code>
<desc>
<p>Registers an unary fun
that is called if <c>beam_lib</c> must read an
- <c>abstract_code</c> chunk that has been encrypted. The fun
+ <c>debug_info</c> chunk that has been encrypted. The fun
is held in a process that is started by the function.</p>
<p>If a fun is already registered when attempting to
register a fun, <c>{error, exists}</c> is returned.</p>
@@ -443,7 +464,8 @@ CryptoKeyFun(clear) -> term()</code>
<desc>
<p>Removes all chunks from a BEAM
file except those needed by the loader. In particular,
- the debug information (chunk <c>abstract_code</c>) is removed.</p>
+ the debug information (chunk <c>debug_info</c> and <c>abstract_code</c>)
+ is removed.</p>
</desc>
</func>
@@ -454,9 +476,9 @@ CryptoKeyFun(clear) -> term()</code>
<desc>
<p>Removes all chunks except
those needed by the loader from BEAM files. In particular,
- the debug information (chunk <c>abstract_code</c>) is removed.
- The returned list contains one element for each specified filename,
- in the same order as in <c>Files</c>.</p>
+ the debug information (chunk <c>debug_info</c> and <c>abstract_code</c>)
+ is removed. The returned list contains one element for each
+ specified filename, in the same order as in <c>Files</c>.</p>
</desc>
</func>
diff --git a/lib/stdlib/doc/src/c.xml b/lib/stdlib/doc/src/c.xml
index 92ab59c6b0..7666699183 100644
--- a/lib/stdlib/doc/src/c.xml
+++ b/lib/stdlib/doc/src/c.xml
@@ -52,13 +52,27 @@
<func>
<name name="c" arity="1"/>
<name name="c" arity="2"/>
- <fsummary>Compile and load code in a file.</fsummary>
+ <name name="c" arity="3"/>
+ <fsummary>Compile and load a file or module.</fsummary>
<desc>
- <p>Compiles and then purges and loads the code for a file.
- <c><anno>Options</anno></c> defaults to <c>[]</c>. Compilation is
- equivalent to:</p>
- <code type="none">
-compile:file(<anno>File</anno>, <anno>Options</anno> ++ [report_errors, report_warnings])</code>
+ <p>Compiles and then purges and loads the code for a module.
+ <c><anno>Module</anno></c> can be either a module name or a source
+ file path, with or without <c>.erl</c> extension.
+ <c><anno>Options</anno></c> defaults to <c>[]</c>.</p>
+ <p>If <c><anno>Module</anno></c> is an atom and is not the path of a
+ source file, then the code path is searched to locate the object
+ file for the module and extract its original compiler options and
+ source path. If the source file is not found in the original
+ location, <seealso
+ marker="filelib#find_source/1"><c>filelib:find_source/1</c></seealso>
+ is used to search for it relative to the directory of the object
+ file.</p>
+ <p>The source file is compiled with the the original
+ options appended to the given <c><anno>Options</anno></c>, the
+ output replacing the old object file if and only if compilation
+ succeeds. A function <c><anno>Filter</anno></c> can be specified
+ for removing elements from from the original compiler options
+ before the new options are added.</p>
<p>Notice that purging the code means that any processes
lingering in old code for the module are killed without
warning. For more information, see <c>code/3</c>.</p>
@@ -148,6 +162,15 @@ compile:file(<anno>File</anno>, <anno>Options</anno> ++ [report_errors, report_w
</func>
<func>
+ <name name="lm" arity="0"/>
+ <fsummary>Loads all modified modules.</fsummary>
+ <desc>
+ <p>Reloads all currently loaded modules that have changed on disk (see <c>mm()</c>).
+ Returns the list of results from calling <c>l(M)</c> for each such <c>M</c>.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="ls" arity="0"/>
<fsummary>List files in the current directory.</fsummary>
<desc>
@@ -182,6 +205,15 @@ compile:file(<anno>File</anno>, <anno>Options</anno> ++ [report_errors, report_w
</func>
<func>
+ <name name="mm" arity="0"/>
+ <fsummary>Lists all modified modules.</fsummary>
+ <desc>
+ <p>Lists all modified modules. Shorthand for
+ <seealso marker="kernel:code#modified_modules/0"><c>code:modified_modules/0</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="memory" arity="0"/>
<fsummary>Memory allocation information.</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/dets.xml b/lib/stdlib/doc/src/dets.xml
index 3b134d00b7..eb6e32aecf 100644
--- a/lib/stdlib/doc/src/dets.xml
+++ b/lib/stdlib/doc/src/dets.xml
@@ -100,18 +100,12 @@
provided by Dets, neither is the limited support for
concurrent updates that makes a sequence of <c>first</c> and
<c>next</c> calls safe to use on fixed ETS tables. Both these
- features will be provided by Dets in a future release of
+ features may be provided by Dets in a future release of
Erlang/OTP. Until then, the Mnesia application (or some
user-implemented method for locking) must be used to implement safe
concurrency. Currently, no Erlang/OTP library has support for
ordered disk-based term storage.</p>
- <p>Two versions of the format used for storing objects on file are
- supported by Dets. The first version, 8, is the format always used
- for tables created by Erlang/OTP R7 and earlier. The second version, 9,
- is the default version of tables created by Erlang/OTP R8 (and later
- releases). Erlang/OTP R8 can create version 8 tables, and convert version
- 8 tables to version 9, and conversely, upon request.</p>
<p>All Dets functions return <c>{error, Reason}</c> if an error
occurs (<seealso marker="#first/1"><c>first/1</c></seealso> and
<seealso marker="#next/2"><c>next/2</c></seealso> are exceptions, they
@@ -190,9 +184,6 @@
<datatype>
<name name="type"/>
</datatype>
- <datatype>
- <name name="version"/>
- </datatype>
</datatypes>
<funcs>
@@ -385,19 +376,14 @@
<p><c>{bchunk_format, binary()}</c> - An opaque binary
describing the format of the objects returned by
<c>bchunk/2</c>. The binary can be used as argument to
- <c>is_compatible_chunk_format/2</c>. Only available for
- version 9 tables.</p>
+ <c>is_compatible_chunk_format/2</c>.</p>
</item>
<item>
<p><c>{hash, Hash}</c> - Describes which BIF is
used to calculate the hash values of the objects stored in the
- <c>dets</c> table. Possible values of <c>Hash</c>:</p>
+ Dets table. Possible values of <c>Hash</c>:</p>
<list>
<item>
- <p><c>hash</c> - Implies that the <c>erlang:hash/2</c> BIF
- is used.</p>
- </item>
- <item>
<p><c>phash</c> - Implies that the <c>erlang:phash/2</c> BIF
is used.</p>
</item>
@@ -413,8 +399,7 @@
</item>
<item>
<p><c>{no_keys, integer >= 0()}</c> - The number of different
- keys stored in the table. Only available for version 9
- tables.</p>
+ keys stored in the table.</p>
</item>
<item>
<p><c>{no_objects, integer >= 0()}</c> - The number of objects
@@ -424,8 +409,7 @@
<p><c>{no_slots, {Min, Used, Max}}</c> - The
number of slots of the table. <c>Min</c> is the minimum number of
slots, <c>Used</c> is the number of currently used slots,
- and <c>Max</c> is the maximum number of slots. Only
- available for version 9 tables.</p>
+ and <c>Max</c> is the maximum number of slots.</p>
</item>
<item>
<p><c>{owner, pid()}</c> - The pid of the process that
@@ -466,10 +450,6 @@
time warp safe</seealso>. Time warp safe code must use
<c>safe_fixed_monotonic_time</c> instead.</p>
</item>
- <item>
- <p><c>{version, integer()}</c> - The version of the format of
- the table.</p>
- </item>
</list>
</desc>
</func>
@@ -662,8 +642,8 @@ ok
objects at a time, until at least one object matches or the
end of the table is reached. The default, indicated by
giving <c><anno>N</anno></c> the value <c>default</c>, is to let
- the number of objects vary depending on the sizes of the objects. If
- <c><anno>Name</anno></c> is a version 9 table, all objects with the
+ the number of objects vary depending on the sizes of the objects.
+ All objects with the
same key are always matched at the same time, which implies that
more than <anno>N</anno> objects can sometimes be matched.</p>
<p>The table is always to be protected using
@@ -743,9 +723,9 @@ ok
end of the table is reached. The default, indicated by
giving <c><anno>N</anno></c> the value <c>default</c>,
is to let the number
- of objects vary depending on the sizes of the objects. If
- <c><anno>Name</anno></c> is a version 9 table, all matching objects
- with the same key are always returned in the same reply, which implies
+ of objects vary depending on the sizes of the objects. All
+ matching objects with the same key are always returned
+ in the same reply, which implies
that more than <anno>N</anno> objects can sometimes be returned.</p>
<p>The table is always to be protected using
<seealso marker="#safe_fixtable/2"><c>safe_fixtable/2</c></seealso>
@@ -842,8 +822,7 @@ ok
maximal value. Notice that a higher value can
increase the table fragmentation, and
a smaller value can decrease the fragmentation, at
- the expense of execution time. Only available for version
- 9 tables.</p>
+ the expense of execution time.</p>
</item>
<item>
<p><c>{min_no_slots, </c><seealso marker="#type-no_slots">
@@ -880,12 +859,7 @@ ok
FileName}}</c> is returned if the table must be repaired.</p>
<p>Value <c>force</c> means that a reparation
is made even if the table is properly closed.
- This is how to convert tables created by older versions of
- STDLIB. An example is tables hashed with the deprecated
- <c>erlang:hash/2</c> BIF. Tables created with Dets from
- STDLIB version 1.8.2 or later use function
- <c>erlang:phash/2</c> or function <c>erlang:phash2/1</c>,
- which is preferred.</p>
+ This is a seldom needed option.</p>
<p>Option <c>repair</c> is ignored if the table is already open.</p>
</item>
<item>
@@ -893,15 +867,6 @@ ok
<c>type()</c></seealso><c>}</c> - The table type. Defaults to
<c>set</c>.</p>
</item>
- <item>
- <p><c>{version, </c><seealso marker="#type-version">
- <c>version()</c></seealso><c>}</c> - The version of the format
- used for the table. Defaults to <c>9</c>. Tables on the format
- used before Erlang/OTP R8 can be created by specifying value
- <c>8</c>. A version 8 table can be converted to a version 9
- table by specifying options <c>{version,9}</c>
- and <c>{repair,force}</c>.</p>
- </item>
</list>
</desc>
</func>
@@ -1041,8 +1006,8 @@ ok
a time, until at least one object matches or the end of the
table is reached. The default, indicated by giving
<c><anno>N</anno></c> the value <c>default</c>, is to let the number
- of objects vary depending on the sizes of the objects. If
- <c><anno>Name</anno></c> is a version 9 table, all objects with the
+ of objects vary depending on the sizes of the objects. All
+ objects with the
same key are always handled at the same time, which implies that the
match specification can be applied to more than <anno>N</anno>
objects.</p>
diff --git a/lib/stdlib/doc/src/dict.xml b/lib/stdlib/doc/src/dict.xml
index c926ff1b5b..c229a18721 100644
--- a/lib/stdlib/doc/src/dict.xml
+++ b/lib/stdlib/doc/src/dict.xml
@@ -106,6 +106,16 @@
</func>
<func>
+ <name name="take" arity="2"/>
+ <fsummary>Return value and new dictionary without element with this value.</fsummary>
+ <desc>
+ <p>This function returns value from dictionary and a
+ new dictionary without this value.
+ Returns <c>error</c> if the key is not present in the dictionary.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="filter" arity="2"/>
<fsummary>Select elements that satisfy a predicate.</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/erl_expand_records.xml b/lib/stdlib/doc/src/erl_expand_records.xml
index 7e4aa2db37..b6aa75ed03 100644
--- a/lib/stdlib/doc/src/erl_expand_records.xml
+++ b/lib/stdlib/doc/src/erl_expand_records.xml
@@ -45,8 +45,10 @@
<name name="module" arity="2"/>
<fsummary>Expand all records in a module.</fsummary>
<desc>
- <p>Expands all records in a module. The returned module has no
- references to records, attributes, or code.</p>
+ <p>Expands all records in a module to use explicit tuple
+ operations and adds explicit module names to calls to BIFs and
+ imported functions. The returned module has no references to
+ records, attributes, or code.</p>
</desc>
</func>
</funcs>
diff --git a/lib/stdlib/doc/src/erl_internal.xml b/lib/stdlib/doc/src/erl_internal.xml
index cf49df0972..17cd0fb240 100644
--- a/lib/stdlib/doc/src/erl_internal.xml
+++ b/lib/stdlib/doc/src/erl_internal.xml
@@ -44,6 +44,16 @@
<funcs>
<func>
+ <name name="add_predefined_functions" arity="1"/>
+ <fsummary>Add code for pre-defined functions.</fsummary>
+ <desc>
+ <p>Adds to <c><anno>Forms</anno></c> the code for the standard
+ pre-defined functions (such as <c>module_info/0</c>) that are
+ to be included in every module.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="arith_op" arity="2"/>
<fsummary>Test for an arithmetic operator.</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/erl_tar.xml b/lib/stdlib/doc/src/erl_tar.xml
index 24e7b64b9e..337028568a 100644
--- a/lib/stdlib/doc/src/erl_tar.xml
+++ b/lib/stdlib/doc/src/erl_tar.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2003</year><year>2016</year>
+ <year>2003</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -37,12 +37,13 @@
</modulesummary>
<description>
<p>This module archives and extract files to and from
- a tar file. This module supports the <c>ustar</c> format
- (IEEE Std 1003.1 and ISO/IEC&nbsp;9945-1). All modern <c>tar</c>
- programs (including GNU tar) can read this format. To ensure that
- that GNU tar produces a tar file that <c>erl_tar</c> can read,
- specify option <c>--format=ustar</c> to GNU tar.</p>
-
+ a tar file. This module supports reading most common tar formats,
+ namely v7, STAR, USTAR, and PAX, as well as some of GNU tar's extensions
+ to the USTAR format (sparse files most notably). It produces tar archives
+ in USTAR format, unless the files being archived require PAX format due to
+ restrictions in USTAR (such as unicode metadata, filename length, and more).
+ As such, <c>erl_tar</c> supports tar archives produced by most all modern
+ tar utilities, and produces tarballs which should be similarly portable.</p>
<p>By convention, the name of a tar file is to end in "<c>.tar</c>".
To abide to the convention, add "<c>.tar</c>" to the name.</p>
@@ -83,6 +84,8 @@
<p>If <seealso marker="kernel:file#native_name_encoding/0">
<c>file:native_name_encoding/0</c></seealso>
returns <c>latin1</c>, no translation of path names is done.</p>
+
+ <p>Unicode metadata stored in PAX headers is preserved</p>
</section>
<section>
@@ -104,21 +107,20 @@
<title>Limitations</title>
<list type="bulleted">
<item>
- <p>For maximum compatibility, it is safe to archive files with names
- up to 100 characters in length. Such tar files can generally be
- extracted by any <c>tar</c> program.</p>
- </item>
- <item>
- <p>For filenames exceeding 100 characters in length, the resulting tar
- file can only be correctly extracted by a POSIX-compatible <c>tar</c>
- program (such as Solaris <c>tar</c> or a modern GNU <c>tar</c>).</p>
- </item>
- <item>
- <p>Files with longer names than 256 bytes cannot be stored.</p>
+ <p>If you must remain compatible with the USTAR tar format, you must ensure file paths being
+ stored are less than 255 bytes in total, with a maximum filename component
+ length of 100 bytes. USTAR uses a header field (prefix) in addition to the name field, and
+ splits file paths longer than 100 bytes into two parts. This split is done on a directory boundary,
+ and is done in such a way to make the best use of the space available in those two fields, but in practice
+ this will often mean that you have less than 255 bytes for a path. <c>erl_tar</c> will
+ automatically upgrade the format to PAX to handle longer filenames, so this is only an issue if you
+ need to extract the archive with an older implementation of <c>erl_tar</c> or <c>tar</c> which does
+ not support PAX. In this case, the PAX headers will be extracted as regular files, and you will need to
+ apply them manually.</p>
</item>
<item>
- <p>The file name a symbolic link points is always limited
- to 100 characters.</p>
+ <p>Like the above, if you must remain USTAR compatible, you must also ensure than paths for
+ symbolic/hard links are no more than 100 bytes, otherwise PAX headers will be used.</p>
</item>
</list>
</section>
@@ -129,7 +131,9 @@
<fsummary>Add a file to an open tar file.</fsummary>
<type>
<v>TarDescriptor = term()</v>
- <v>Filename = filename()</v>
+ <v>FilenameOrBin = filename()|binary()</v>
+ <v>NameInArchive = filename()</v>
+ <v>Filename = filename()|{NameInArchive,FilenameOrBin}</v>
<v>Options = [Option]</v>
<v>Option = dereference|verbose|{chunks,ChunkSize}</v>
<v>ChunkSize = positive_integer()</v>
@@ -139,6 +143,9 @@
<desc>
<p>Adds a file to a tar file that has been opened for writing by
<seealso marker="#open/2"><c>open/1</c></seealso>.</p>
+ <p><c>NameInArchive</c> is the name under which the file becomes
+ stored in the tar file. The file gets this name when it is
+ extracted from the tar file.</p>
<p>Options:</p>
<taglist>
<tag><c>dereference</c></tag>
@@ -183,9 +190,6 @@
<seealso marker="#open/2"><c>open/2</c></seealso>. This function
accepts the same options as
<seealso marker="#add/3"><c>add/3</c></seealso>.</p>
- <p><c>NameInArchive</c> is the name under which the file becomes
- stored in the tar file. The file gets this name when it is
- extracted from the tar file.</p>
</desc>
</func>
@@ -206,8 +210,8 @@
<fsummary>Create a tar archive.</fsummary>
<type>
<v>Name = filename()</v>
- <v>FileList = [Filename|{NameInArchive, binary()},{NameInArchive,
- Filename}]</v>
+ <v>FileList = [Filename|{NameInArchive, FilenameOrBin}]</v>
+ <v>FilenameOrBin = filename()|binary()</v>
<v>Filename = filename()</v>
<v>NameInArchive = filename()</v>
<v>RetValue = ok|{error,{Name,Reason}}</v>
@@ -225,8 +229,8 @@
<fsummary>Create a tar archive with options.</fsummary>
<type>
<v>Name = filename()</v>
- <v>FileList = [Filename|{NameInArchive, binary()},{NameInArchive,
- Filename}]</v>
+ <v>FileList = [Filename|{NameInArchive, FilenameOrBin}]</v>
+ <v>FilenameOrBin = filename()|binary()</v>
<v>Filename = filename()</v>
<v>NameInArchive = filename()</v>
<v>OptionList = [Option]</v>
@@ -275,7 +279,8 @@
<name>extract(Name) -> RetValue</name>
<fsummary>Extract all files from a tar file.</fsummary>
<type>
- <v>Name = filename()</v>
+ <v>Name = filename() | {binary,binary()} | {file,Fd}</v>
+ <v>Fd = file_descriptor()</v>
<v>RetValue = ok|{error,{Name,Reason}}</v>
<v>Reason = term()</v>
</type>
@@ -287,6 +292,10 @@
<c>Fd</c> is assumed to be a file descriptor returned from function
<c>file:open/2</c>.</p>
<p>Otherwise, <c>Name</c> is to be a filename.</p>
+ <note><p>Leading slashes in tar member names will be removed before
+ writing the file. That is, absolute paths will be turned into
+ relative paths. There will be an info message written to the error
+ logger when paths are changed in this way.</p></note>
</desc>
</func>
@@ -294,8 +303,7 @@
<name>extract(Name, OptionList)</name>
<fsummary>Extract files from a tar file.</fsummary>
<type>
- <v>Name = filename() | {binary,Binary} | {file,Fd}</v>
- <v>Binary = binary()</v>
+ <v>Name = filename() | {binary,binary()} | {file,Fd}</v>
<v>Fd = file_descriptor()</v>
<v>OptionList = [Option]</v>
<v>Option = {cwd,Cwd}|{files,FileList}|keep_old_files|verbose|memory</v>
@@ -521,7 +529,7 @@ erl_tar:close(TarDesc)</code>
<name>table(Name) -> RetValue</name>
<fsummary>Retrieve the name of all files in a tar file.</fsummary>
<type>
- <v>Name = filename()</v>
+ <v>Name = filename()|{binary,binary()}|{file,file_descriptor()}</v>
<v>RetValue = {ok,[string()]}|{error,{Name,Reason}}</v>
<v>Reason = term()</v>
</type>
@@ -535,7 +543,7 @@ erl_tar:close(TarDesc)</code>
<fsummary>Retrieve name and information of all files in a tar file.
</fsummary>
<type>
- <v>Name = filename()</v>
+ <v>Name = filename()|{binary,binary()}|{file,file_descriptor()}</v>
</type>
<desc>
<p>Retrieves the names of all files in the tar file <c>Name</c>.</p>
@@ -546,7 +554,7 @@ erl_tar:close(TarDesc)</code>
<name>t(Name)</name>
<fsummary>Print the name of each file in a tar file.</fsummary>
<type>
- <v>Name = filename()</v>
+ <v>Name = filename()|{binary,binary()}|{file,file_descriptor()}</v>
</type>
<desc>
<p>Prints the names of all files in the tar file <c>Name</c> to the
@@ -559,7 +567,7 @@ erl_tar:close(TarDesc)</code>
<fsummary>Print name and information for each file in a tar file.
</fsummary>
<type>
- <v>Name = filename()</v>
+ <v>Name = filename()|{binary,binary()}|{file,file_descriptor()}</v>
</type>
<desc>
<p>Prints names and information about all files in the tar file
diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml
index b8e262208d..f6f3d18d6a 100644
--- a/lib/stdlib/doc/src/ets.xml
+++ b/lib/stdlib/doc/src/ets.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -49,13 +49,22 @@
associated with each key. A <c>bag</c> or <c>duplicate_bag</c> table can
have many objects associated with each key.</p>
- <p>The number of tables stored at one Erlang node is limited.
- The current default limit is about 1400 tables. The upper
- limit can be increased by setting environment variable
- <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang runtime
- system (that is, with option <c>-env</c> to
- <c>erl</c>/<c>werl</c>). The actual limit can be slightly higher
- than the one specified, but never lower.</p>
+ <note>
+ <p>
+ The number of tables stored at one Erlang node <em>used</em> to
+ be limited. This is no longer the case (except by memory usage).
+ The previous default limit was about 1400 tables and
+ could be increased by setting the environment variable
+ <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang runtime
+ system. This hard limit has been removed, but it is currently
+ useful to set the <c>ERL_MAX_ETS_TABLES</c> anyway. It should be
+ set to an approximate of the maximum amount of tables used. This since
+ an internal table for named tables is sized using this value. If
+ large amounts of named tables are used and <c>ERL_MAX_ETS_TABLES</c>
+ hasn't been increased, the performance of named table lookup will
+ degrade.
+ </p>
+ </note>
<p>Notice that there is no automatic garbage collection for tables.
Even if there are no references to a table from any process, it
@@ -369,7 +378,7 @@
variable that in turn is passed to the function.</p>
<p>The parse transform is provided in the <c>ms_transform</c>
module and the source <em>must</em> include
- file <c>ms_transform.hrl</c> in <c>STDLIB</c> for this
+ file <c>ms_transform.hrl</c> in STDLIB for this
pseudo function to work. Failing to include the hrl file in
the source results in a runtime error, not a compile
time error. The include file is easiest included by adding line
@@ -541,10 +550,6 @@ Error: fun containing local Erlang function calls
<c><anno>Tab</anno></c> is
not of the correct type, or if <c><anno>Item</anno></c> is not
one of the allowed values, a <c>badarg</c> exception is raised.</p>
- <warning>
- <p>In Erlang/OTP R11B and earlier, this function would not fail but
- return <c>undefined</c> for invalid values for <c>Item</c>.</p>
- </warning>
<p>In addition to the <c>{<anno>Item</anno>,<anno>Value</anno>}</c>
pairs defined for <seealso marker="#info/1"><c>info/1</c></seealso>,
the following items are allowed:</p>
@@ -1458,7 +1463,7 @@ is_integer(X), is_integer(Y), X + Y < 4711]]></code>
specification returned <c>true</c>.</fsummary>
<desc>
<p>Matches the objects in table <c><anno>Tab</anno></c> using a
- <seealso marker="#match_spec">match specificationc</seealso>. If the
+ <seealso marker="#match_spec">match specification</seealso>. If the
match specification returns <c>true</c> for an object, that object
considered a match and is counted. For any other result from
the match specification the object is not considered a match and is
@@ -1495,6 +1500,45 @@ is_integer(X), is_integer(Y), X + Y < 4711]]></code>
</func>
<func>
+ <name name="select_replace" arity="2"/>
+ <fsummary>Match and replace objects atomically in an ETS table</fsummary>
+ <desc>
+ <p>Matches the objects in the table <c><anno>Tab</anno></c> using a
+ <seealso marker="#match_spec">match specification</seealso>. For each
+ matched object, the existing object is replaced with
+ the match specification result.</p>
+ <p>The match-and-replace operation for each individual object is guaranteed to be
+ <seealso marker="#concurrency">atomic and isolated</seealso>. The
+ <c>select_replace</c> table iteration as a whole, like all other select functions,
+ does not give such guarantees.</p>
+ <p>The match specifiction must be guaranteed to <em>retain the key</em>
+ of any matched object. If not, <c>select_replace</c> will fail with <c>badarg</c>
+ without updating any objects.</p>
+ <p>For the moment, due to performance and semantic constraints,
+ tables of type <c>bag</c> are not yet supported.</p>
+ <p>The function returns the total number of replaced objects.</p>
+ <p><em>Example</em></p>
+ <p>For all 2-tuples with a list in second position, add atom <c>'marker'</c> first in the list:</p>
+ <pre>
+1> <input>T = ets:new(x,[]), ets:insert(T, {key, [1, 2, 3]}).</input>
+true
+2> <input>MS = ets:fun2ms(fun({K, L}) when is_list(L) -> {K, [marker | L]} end).</input>
+[{{'$1','$2'},[{is_list,'$2'}],[{{'$1',[marker|'$2']}}]}]
+3> <input>ets:select_replace(T, MS).</input>
+1
+4> <input>ets:tab2list(T).</input>
+[{key,[marker,1,2,3]}]
+ </pre>
+ <p>A generic single object compare-and-swap operation:</p>
+ <pre>
+[Old] = ets:lookup(T, Key),
+New = update_object(Old),
+Success = (1 =:= ets:select_replace(T, [{Old, [], [{const, New}]}])),
+ </pre>
+ </desc>
+ </func>
+
+ <func>
<name name="select_reverse" arity="1"/>
<fsummary>Continue matching objects in an ETS table.</fsummary>
<desc>
@@ -1644,7 +1688,7 @@ is_integer(X), is_integer(Y), X + Y < 4711]]></code>
</taglist>
<p>Whenever option <c>extended_info</c> is used, it
results in a file not readable by versions of ETS before
- that in <c>STDLIB</c> 1.15.1</p>
+ that in STDLIB 1.15.1</p>
<p>If option <c>sync</c> is set to <c>true</c>, it ensures that
the content of the file is written to the disk before
<c>tab2file</c> returns. Defaults to <c>{sync, false}</c>.</p>
@@ -1725,7 +1769,7 @@ is_integer(X), is_integer(Y), X + Y < 4711]]></code>
<p>A tuple <c>{<anno>Major</anno>,<anno>Minor</anno>}</c>
containing the major and
minor version of the file format for ETS table dumps. This
- version field was added beginning with <c>STDLIB</c> 1.5.1.
+ version field was added beginning with STDLIB 1.5.1.
Files dumped with older versions return <c>{0,0}</c> in this
field.</p>
</item>
diff --git a/lib/stdlib/doc/src/filelib.xml b/lib/stdlib/doc/src/filelib.xml
index 7c6380ce28..80c4acffdb 100644
--- a/lib/stdlib/doc/src/filelib.xml
+++ b/lib/stdlib/doc/src/filelib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2003</year><year>2016</year>
+ <year>2003</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -60,6 +60,12 @@
<datatype>
<name name="filename_all"/>
</datatype>
+ <datatype>
+ <name name="find_file_rule"/>
+ </datatype>
+ <datatype>
+ <name name="find_source_rule"/>
+ </datatype>
</datatypes>
<funcs>
@@ -226,7 +232,51 @@ filelib:wildcard("lib/**/*.{erl,hrl}")</code>
directory.</p>
</desc>
</func>
+
+ <func>
+ <name name="find_file" arity="2"/>
+ <name name="find_file" arity="3"/>
+ <fsummary>Find a file relative to a given directory.</fsummary>
+ <desc>
+ <p>Looks for a file of the given name by applying suffix rules to
+ the given directory path. For example, a rule <c>{"ebin", "src"}</c>
+ means that if the directory path ends with <c>"ebin"</c>, the
+ corresponding path ending in <c>"src"</c> should be searched.</p>
+ <p>If <c><anno>Rules</anno></c> is left out or is an empty list, the
+ default system rules are used. See also the Kernel application
+ parameter <seealso
+ marker="kernel:kernel_app#source_search_rules"><c>source_search_rules</c></seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="find_source" arity="1"/>
+ <fsummary>Find the source file for a given object file.</fsummary>
+ <desc>
+ <p>Equivalent to <c>find_source(Base, Dir)</c>, where <c>Dir</c> is
+ <c>filename:dirname(<anno>FilePath</anno>)</c> and <c>Base</c> is
+ <c>filename:basename(<anno>FilePath</anno>)</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="find_source" arity="2"/>
+ <name name="find_source" arity="3"/>
+ <fsummary>Find a source file relative to a given directory.</fsummary>
+ <desc>
+ <p>Applies file extension specific rules to find the source file for
+ a given object file relative to the object directory. For example,
+ for a file with the extension <c>.beam</c>, the default rule is to
+ look for a file with a corresponding extension <c>.erl</c> by
+ replacing the suffix <c>"ebin"</c> of the object directory path with
+ <c>"src"</c>.
+ The file search is done through <seealso
+ marker="#find_file/3"><c>find_file/3</c></seealso>. The directory of
+ the object file is always tried before any other directory specified
+ by the rules.</p>
+ <p>If <c><anno>Rules</anno></c> is left out or is an empty list, the
+ default system rules are used. See also the Kernel application
+ parameter <seealso
+ marker="kernel:kernel_app#source_search_rules"><c>source_search_rules</c></seealso>.</p>
+ </desc>
+ </func>
</funcs>
</erlref>
-
-
diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml
index 2a413835d0..14fd5ef787 100644
--- a/lib/stdlib/doc/src/filename.xml
+++ b/lib/stdlib/doc/src/filename.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -356,10 +356,12 @@ true
<p>Finds the source filename and compiler options for a module.
The result can be fed to <seealso marker="compiler:compile#file/2">
<c>compile:file/2</c></seealso> to compile the file again.</p>
- <warning><p>It is not recommended to use this function. If possible,
- use the <seealso marker="beam_lib"><c>beam_lib(3)</c></seealso>
- module to extract the abstract code format from the Beam file and
- compile that instead.</p></warning>
+ <warning>
+ <p>This function is deprecated. Use <seealso marker="filelib#find_source/1">
+ <c>filelib:find_source/1</c></seealso> instead for finding source files.</p>
+ <p>If possible, use the <seealso marker="beam_lib"><c>beam_lib(3)</c></seealso>
+ module to extract the compiler options and the abstract code
+ format from the Beam file and compile that instead.</p></warning>
<p>Argument <c><anno>Beam</anno></c>, which can be a string or an atom,
specifies either the module name or the path to the source
code, with or without extension <c>".erl"</c>. In either
@@ -511,6 +513,33 @@ true
</func>
<func>
+ <name name="safe_relative_path" arity="1"/>
+ <fsummary>Sanitize a relative path to avoid directory traversal attacks.</fsummary>
+ <desc>
+ <p>Sanitizes the relative path by eliminating ".." and "."
+ components to protect against directory traversal attacks.
+ Either returns the sanitized path name, or the atom
+ <c>unsafe</c> if the path is unsafe.
+ The path is considered unsafe in the following circumstances:</p>
+ <list type="bulleted">
+ <item><p>The path is not relative.</p></item>
+ <item><p>A ".." component would climb up above the root of
+ the relative path.</p></item>
+ </list>
+ <p><em>Examples:</em></p>
+ <pre>
+1> <input>filename:safe_relative_path("dir/sub_dir/..").</input>
+"dir"
+2> <input>filename:safe_relative_path("dir/..").</input>
+[]
+3> <input>filename:safe_relative_path("dir/../..").</input>
+unsafe
+4> <input>filename:safe_relative_path("/abs/path").</input>
+unsafe</pre>
+ </desc>
+ </func>
+
+ <func>
<name name="split" arity="1"/>
<fsummary>Split a filename into its path components.</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/gb_sets.xml b/lib/stdlib/doc/src/gb_sets.xml
index d677dd6f83..7bfe477a11 100644
--- a/lib/stdlib/doc/src/gb_sets.xml
+++ b/lib/stdlib/doc/src/gb_sets.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2001</year><year>2015</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/stdlib/doc/src/gb_trees.xml b/lib/stdlib/doc/src/gb_trees.xml
index 9a49d66820..5cfff021c1 100644
--- a/lib/stdlib/doc/src/gb_trees.xml
+++ b/lib/stdlib/doc/src/gb_trees.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2001</year><year>2015</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -109,6 +109,28 @@
</func>
<func>
+ <name name="take" arity="2"/>
+ <fsummary>Returns a value and new tree without node with key <c>Key</c>.</fsummary>
+ <desc>
+ <p>Returns a value <c><anno>Value</anno></c> from node with key <c><anno>Key</anno></c>
+ and new <c><anno>Tree2</anno></c> without the node with this value.
+ Assumes that the node with key is present in the tree,
+ crashes otherwise.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="take_any" arity="2"/>
+ <fsummary>Returns a value and new tree without node with key <c>Key</c>.</fsummary>
+ <desc>
+ <p>Returns a value <c><anno>Value</anno></c> from node with key <c><anno>Key</anno></c>
+ and new <c><anno>Tree2</anno></c> without the node with this value.
+ Returns <c>error</c> if the node with the key is not present in
+ the tree.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="empty" arity="0"/>
<fsummary>Return an empty tree.</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/gen_event.xml b/lib/stdlib/doc/src/gen_event.xml
index c24542002a..012737c390 100644
--- a/lib/stdlib/doc/src/gen_event.xml
+++ b/lib/stdlib/doc/src/gen_event.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -350,13 +350,18 @@ gen_event:stop -----> Module:terminate/2
<func>
<name>start() -> Result</name>
- <name>start(EventMgrName) -> Result</name>
+ <name>start(EventMgrName | Options) -> Result</name>
+ <name>start(EventMgrName, Options) -> Result</name>
<fsummary>Create a stand-alone event manager process.</fsummary>
<type>
- <v>EventMgrName = {local,Name} | {global,GlobalName}
- | {via,Module,ViaName}</v>
+ <v>EventMgrName = {local,Name} | {global,GlobalName} | {via,Module,ViaName}</v>
<v>&nbsp;Name = atom()</v>
<v>&nbsp;GlobalName = ViaName = term()</v>
+ <v>Options = [Option]</v>
+ <v>&nbsp;Option = {debug,Dbgs} | {timeout,Time} | {hibernate_after,HibernateAfterTimeout} | {spawn_opt,SOpts}</v>
+ <v>&nbsp;&nbsp;Dbgs = [Dbg]</v>
+ <v>&nbsp;&nbsp;&nbsp;Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}</v>
+ <v>&nbsp;&nbsp;SOpts = [term()]</v>
<v>Result = {ok,Pid} | {error,{already_started,Pid}}</v>
<v>&nbsp;Pid = pid()</v>
</type>
@@ -371,14 +376,19 @@ gen_event:stop -----> Module:terminate/2
<func>
<name>start_link() -> Result</name>
- <name>start_link(EventMgrName) -> Result</name>
+ <name>start_link(EventMgrName | Options) -> Result</name>
+ <name>start_link(EventMgrName, Options) -> Result</name>
<fsummary>Create a generic event manager process in a supervision tree.
</fsummary>
<type>
- <v>EventMgrName = {local,Name} | {global,GlobalName}
- | {via,Module,ViaName}</v>
+ <v>EventMgrName = {local,Name} | {global,GlobalName} | {via,Module,ViaName}</v>
<v>&nbsp;Name = atom()</v>
<v>&nbsp;GlobalName = ViaName = term()</v>
+ <v>Options = [Option]</v>
+ <v>&nbsp;Option = {debug,Dbgs} | {timeout,Time} | {hibernate_after,HibernateAfterTimeout} | {spawn_opt,SOpts}</v>
+ <v>&nbsp;&nbsp;Dbgs = [Dbg]</v>
+ <v>&nbsp;&nbsp;&nbsp;Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}</v>
+ <v>&nbsp;&nbsp;SOpts = [term()]</v>
<v>Result = {ok,Pid} | {error,{already_started,Pid}}</v>
<v>&nbsp;Pid = pid()</v>
</type>
@@ -409,6 +419,12 @@ gen_event:stop -----> Module:terminate/2
<seealso marker="kernel:global"><c>global</c></seealso>.
Thus, <c>{via,global,GlobalName}</c> is a valid reference.</p>
</item>
+ <item>
+ <p>If option <c>{hibernate_after,HibernateAfterTimeout}</c> is present, the <c>gen_event</c>
+ process awaits any message for <c>HibernateAfterTimeout</c> milliseconds and
+ if no message is received, the process goes into hibernation automatically
+ (by calling <seealso marker="proc_lib#hibernate/3"><c>proc_lib:hibernate/3</c></seealso>).</p>
+ </item>
</list>
<p>If the event manager is successfully created, the function
returns <c>{ok,Pid}</c>, where <c>Pid</c> is the pid of
@@ -569,6 +585,13 @@ gen_event:stop -----> Module:terminate/2
<v>Extra = term()</v>
</type>
<desc>
+ <note>
+ <p>This callback is optional, so callback modules need not export it.
+ If a release upgrade/downgrade with <c>Change={advanced,Extra}</c>
+ specified in the <c>.appup</c> file is made when <c>code_change/3</c>
+ isn't implemented the event handler will crash with an <c>undef</c> error
+ reason.</p>
+ </note>
<p>This function is called for an installed event handler that
is to update its internal state during a release
upgrade/downgrade, that is, when the instruction
@@ -749,6 +772,12 @@ gen_event:stop -----> Module:terminate/2
<v>&nbsp;&nbsp;Id = term()</v>
</type>
<desc>
+ <note>
+ <p>This callback is optional, so callback modules need not
+ export it. The <c>gen_event</c> module provides a default
+ implementation of this function that logs about the unexpected
+ <c>Info</c> message, drops it and returns <c>{noreply, State}</c>.</p>
+ </note>
<p>This function is called for each installed event handler when
an event manager receives any other message than an event or
a synchronous request (or a system message).</p>
@@ -805,6 +834,11 @@ gen_event:stop -----> Module:terminate/2
<v>&nbsp;Args = Reason = Term = term()</v>
</type>
<desc>
+ <note>
+ <p>This callback is optional, so callback modules need not
+ export it. The <c>gen_event</c> module provides a default
+ implementation without cleanup.</p>
+ </note>
<p>Whenever an event handler is deleted from an event manager,
this function is called. It is to be the opposite of
<seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
diff --git a/lib/stdlib/doc/src/gen_fsm.xml b/lib/stdlib/doc/src/gen_fsm.xml
index de06987d38..7187630b43 100644
--- a/lib/stdlib/doc/src/gen_fsm.xml
+++ b/lib/stdlib/doc/src/gen_fsm.xml
@@ -4,14 +4,14 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996-2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -29,931 +29,176 @@
<rev></rev>
</header>
<module>gen_fsm</module>
- <modulesummary>Generic finite state machine behavior.</modulesummary>
- <description>
- <note>
- <p>
- There is a new behaviour
- <seealso marker="gen_statem"><c>gen_statem</c></seealso>
- that is intended to replace <c>gen_fsm</c> for new code.
- <c>gen_fsm</c> will not be removed for the foreseeable future
- to keep old state machine implementations running.
- </p>
- </note>
- <p>This behavior module provides a finite state machine.
- A generic finite state machine process (<c>gen_fsm</c>) implemented
- using this module has a standard set of interface functions
- and includes functionality for tracing and error reporting. It
- also fits into an OTP supervision tree. For more information, see
- <seealso marker="doc/design_principles:fsm">OTP Design Principles</seealso>.
- </p>
-
- <p>A <c>gen_fsm</c> process assumes all specific parts to be located in a
- callback module exporting a predefined set of functions. The relationship
- between the behavior functions and the callback functions is as
- follows:</p>
-
- <pre>
-gen_fsm module Callback module
--------------- ---------------
-gen_fsm:start
-gen_fsm:start_link -----> Module:init/1
-
-gen_fsm:stop -----> Module:terminate/3
-
-gen_fsm:send_event -----> Module:StateName/2
-
-gen_fsm:send_all_state_event -----> Module:handle_event/3
-
-gen_fsm:sync_send_event -----> Module:StateName/3
-
-gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
-
-- -----> Module:handle_info/3
-
-- -----> Module:terminate/3
+ <modulesummary>Deprecated and replaced by gen_statem </modulesummary>
-- -----> Module:code_change/4</pre>
-
- <p>If a callback function fails or returns a bad value, the <c>gen_fsm</c>
- process terminates.</p>
-
- <p>A <c>gen_fsm</c> process handles system messages as described in
- <seealso marker="sys"><c>sys(3)</c></seealso>. The <c>sys</c> module
- can be used for debugging a <c>gen_fsm</c> process.</p>
-
- <p>Notice that a <c>gen_fsm</c> process does not trap exit signals
- automatically, this must be explicitly initiated in the callback
- module.</p>
-
- <p>Unless otherwise stated, all functions in this module fail if
- the specified <c>gen_fsm</c> process does not exist or if bad arguments
- are specified.</p>
-
- <p>The <c>gen_fsm</c> process can go into hibernation
- (see <seealso marker="erts:erlang#hibernate/3">
- <c>erlang:hibernate/3</c></seealso>) if a callback function
- specifies <c>'hibernate'</c> instead of a time-out value. This
- can be useful if the server is expected to be idle for a long
- time. However, use this feature with care, as hibernation
- implies at least two garbage collections (when hibernating and
- shortly after waking up) and is not something you want to do
- between each call to a busy state machine.</p>
+ <description>
+ <p> Deprecated and replaced by <seealso marker="gen_statem"><c>gen_statem</c></seealso> </p>
</description>
-
- <funcs>
- <func>
- <name>cancel_timer(Ref) -> RemainingTime | false</name>
- <fsummary>Cancel an internal timer in a generic FSM.</fsummary>
- <type>
- <v>Ref = reference()</v>
- <v>RemainingTime = integer()</v>
- </type>
- <desc>
- <p>Cancels an internal timer referred by <c>Ref</c> in the
- <c>gen_fsm</c> process that calls this function.</p>
- <p><c>Ref</c> is a reference returned from
- <seealso marker="#send_event_after/2">
- <c>send_event_after/2</c></seealso> or
- <seealso marker="#start_timer/2"><c>start_timer/2</c></seealso>.</p>
- <p>If the timer has already timed out, but the event not yet
- been delivered, it is cancelled as if it had <em>not</em>
- timed out, so there is no false timer event after
- returning from this function.</p>
- <p>Returns the remaining time in milliseconds until the timer would
- have expired if <c>Ref</c> referred to an active timer, otherwise
- <c>false</c>.</p>
- </desc>
- </func>
-
- <func>
- <name>enter_loop(Module, Options, StateName, StateData)</name>
- <name>enter_loop(Module, Options, StateName, StateData, FsmName)</name>
- <name>enter_loop(Module, Options, StateName, StateData, Timeout)</name>
- <name>enter_loop(Module, Options, StateName, StateData, FsmName, Timeout)</name>
- <fsummary>Enter the <c>gen_fsm</c> receive loop.</fsummary>
- <type>
- <v>Module = atom()</v>
- <v>Options = [Option]</v>
- <v>&nbsp;Option = {debug,Dbgs}</v>
- <v>&nbsp;&nbsp;Dbgs = [Dbg]</v>
- <v>&nbsp;&nbsp;&nbsp;Dbg = trace | log | statistics</v>
- <v>&nbsp;&nbsp;&nbsp;&nbsp;| {log_to_file,FileName} | {install,{Func,FuncState}}</v>
- <v>StateName = atom()</v>
- <v>StateData = term()</v>
- <v>FsmName = {local,Name} | {global,GlobalName}</v>
- <v>&nbsp;&nbsp;| {via,Module,ViaName}</v>
- <v>&nbsp;Name = atom()</v>
- <v>&nbsp;GlobalName = ViaName = term()</v>
- <v>Timeout = int() | infinity</v>
- </type>
- <desc>
- <p>Makes an existing process into a <c>gen_fsm</c> process.
- Does not return,
- instead the calling process enters the <c>gen_fsm</c> receive
- loop and becomes a <c>gen_fsm</c> process. The process <em>must</em>
- have been started using one of the start functions in
- <seealso marker="proc_lib"><c>proc_lib(3)</c></seealso>. The user is
- responsible for any initialization of the process, including
- registering a name for it.</p>
- <p>This function is useful when a more complex initialization
- procedure is needed than the <c>gen_fsm</c> behavior provides.</p>
- <p><c>Module</c>, <c>Options</c>, and <c>FsmName</c> have
- the same meanings as when calling
- <seealso marker="#start_link/3"><c>start[_link]/3,4</c></seealso>.
- However, if <c>FsmName</c> is specified, the process must have
- been registered accordingly <em>before</em> this function is
- called.</p>
- <p><c>StateName</c>, <c>StateData</c>, and <c>Timeout</c> have
- the same meanings as in the return value of
- <seealso marker="#Moduleinit"><c>Module:init/1</c></seealso>.
- The callback module <c>Module</c> does not need to
- export an <c>init/1</c> function.</p>
- <p>The function fails if the calling process was not started by a
- <c>proc_lib</c> start function, or if it is not registered
- according to <c>FsmName</c>.</p>
- </desc>
- </func>
-
- <func>
- <name>reply(Caller, Reply) -> Result</name>
- <fsummary>Send a reply to a caller.</fsummary>
- <type>
- <v>Caller - see below</v>
- <v>Reply = term()</v>
- <v>Result = term()</v>
- </type>
- <desc>
- <p>This function can be used by a <c>gen_fsm</c> process to
- explicitly send a reply to a client process that called
- <seealso marker="#sync_send_event/2">
- <c>sync_send_event/2,3</c></seealso> or
- <seealso marker="#sync_send_all_state_event/2">
- <c>sync_send_all_state_event/2,3</c></seealso>
- when the reply cannot be defined in the return value of
- <seealso marker="#Module:StateName/3">
- <c>Module:StateName/3</c></seealso> or
- <seealso marker="#Module:handle_sync_event/4">
- <c>Module:handle_sync_event/4</c></seealso>.</p>
- <p><c>Caller</c> must be the <c>From</c> argument provided to
- the callback function. <c>Reply</c> is any term
- given back to the client as the return value of
- <c>sync_send_event/2,3</c> or
- <c>sync_send_all_state_event/2,3</c>.</p>
- <p>Return value <c>Result</c> is not further defined, and
- is always to be ignored.</p>
- </desc>
- </func>
-
- <func>
- <name>send_all_state_event(FsmRef, Event) -> ok</name>
- <fsummary>Send an event asynchronously to a generic FSM.</fsummary>
- <type>
- <v>FsmRef = Name | {Name,Node} | {global,GlobalName}</v>
- <v>&nbsp;&nbsp;| {via,Module,ViaName} | pid()</v>
- <v>&nbsp;Name = Node = atom()</v>
- <v>&nbsp;GlobalName = ViaName = term()</v>
- <v>Event = term()</v>
- </type>
- <desc>
- <p>Sends an event asynchronously to the <c>FsmRef</c> of the
- <c>gen_fsm</c> process and returns <c>ok</c> immediately.
- The <c>gen_fsm</c> process calls
- <seealso marker="#Module:handle_event/3">
- <c>Module:handle_event/3</c></seealso> to handle the event.</p>
- <p>For a description of the arguments, see
- <seealso marker="#send_event/2"><c>send_event/2</c></seealso>.</p>
- <p>The difference between <c>send_event/2</c> and
- <c>send_all_state_event/2</c> is which callback function is
- used to handle the event. This function is useful when
- sending events that are handled the same way in every state,
- as only one <c>handle_event</c> clause is needed to handle
- the event instead of one clause in each state name function.</p>
- </desc>
- </func>
-
- <func>
- <name>send_event(FsmRef, Event) -> ok</name>
- <fsummary>Send an event asynchronously to a generic FSM.</fsummary>
- <type>
- <v>FsmRef = Name | {Name,Node} | {global,GlobalName}</v>
- <v>&nbsp;&nbsp;| {via,Module,ViaName} | pid()</v>
- <v>&nbsp;Name = Node = atom()</v>
- <v>&nbsp;GlobalName = ViaName = term()</v>
- <v>Event = term()</v>
- </type>
- <desc>
- <p>Sends an event asynchronously to the <c>FsmRef</c> of the
- <c>gen_fsm</c> process
- and returns <c>ok</c> immediately. The <c>gen_fsm</c> process calls
- <seealso marker="#Module:StateName/2">
- <c>Module:StateName/2</c></seealso> to handle the event, where
- <c>StateName</c> is the name of the current state of
- the <c>gen_fsm</c> process.</p>
- <p><c>FsmRef</c> can be any of the following:</p>
- <list type="bulleted">
- <item>The pid</item>
- <item><c>Name</c>, if the <c>gen_fsm</c> process is locally
- registered</item>
- <item><c>{Name,Node}</c>, if the <c>gen_fsm</c> process is locally
- registered at another node</item>
- <item><c>{global,GlobalName}</c>, if the <c>gen_fsm</c> process is
- globally registered</item>
- <item><c>{via,Module,ViaName}</c>, if the <c>gen_fsm</c> process is
- registered through an alternative process registry</item>
- </list>
- <p><c>Event</c> is any term that is passed as one of
- the arguments to <c>Module:StateName/2</c>.</p>
- </desc>
- </func>
-
- <func>
- <name>send_event_after(Time, Event) -> Ref</name>
- <fsummary>Send a delayed event internally in a generic FSM.</fsummary>
- <type>
- <v>Time = integer()</v>
- <v>Event = term()</v>
- <v>Ref = reference()</v>
- </type>
- <desc>
- <p>Sends a delayed event internally in the <c>gen_fsm</c> process
- that calls this function after <c>Time</c> milliseconds.
- Returns immediately a
- reference that can be used to cancel the delayed send using
- <seealso marker="#cancel_timer/1"><c>cancel_timer/1</c></seealso>.</p>
- <p>The <c>gen_fsm</c> process calls
- <seealso marker="#Module:StateName/2">
- <c>Module:StateName/2</c></seealso> to handle
- the event, where <c>StateName</c> is the name of the current
- state of the <c>gen_fsm</c> process at the time the delayed event is
- delivered.</p>
- <p><c>Event</c> is any term that is passed as one of
- the arguments to <c>Module:StateName/2</c>.</p>
- </desc>
- </func>
-
- <func>
- <name>start(Module, Args, Options) -> Result</name>
- <name>start(FsmName, Module, Args, Options) -> Result</name>
- <fsummary>Create a standalone <c>gen_fsm</c> process.</fsummary>
- <type>
- <v>FsmName = {local,Name} | {global,GlobalName}</v>
- <v>&nbsp;&nbsp;| {via,Module,ViaName}</v>
- <v>&nbsp;Name = atom()</v>
- <v>&nbsp;GlobalName = ViaName = term()</v>
- <v>Module = atom()</v>
- <v>Args = term()</v>
- <v>Options = [Option]</v>
- <v>&nbsp;Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}</v>
- <v>&nbsp;&nbsp;Dbgs = [Dbg]</v>
- <v>&nbsp;&nbsp;&nbsp;Dbg = trace | log | statistics</v>
- <v>&nbsp;&nbsp;&nbsp;&nbsp;| {log_to_file,FileName} | {install,{Func,FuncState}}</v>
- <v>&nbsp;&nbsp;SOpts = [term()]</v>
- <v>Result = {ok,Pid} | ignore | {error,Error}</v>
- <v>&nbsp;Pid = pid()</v>
- <v>&nbsp;Error = {already_started,Pid} | term()</v>
- </type>
- <desc>
- <p>Creates a standalone <c>gen_fsm</c> process, that is, a process that
- is not part of a supervision tree and thus has no supervisor.</p>
- <p>For a description of arguments and return values, see
- <seealso marker="#start_link/3"><c>start_link/3,4</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>start_link(Module, Args, Options) -> Result</name>
- <name>start_link(FsmName, Module, Args, Options) -> Result</name>
- <fsummary>Create a <c>gen_fsm</c> process in a supervision tree.
- </fsummary>
- <type>
- <v>FsmName = {local,Name} | {global,GlobalName}</v>
- <v>&nbsp;&nbsp;| {via,Module,ViaName}</v>
- <v>&nbsp;Name = atom()</v>
- <v>&nbsp;GlobalName = ViaName = term()</v>
- <v>Module = atom()</v>
- <v>Args = term()</v>
- <v>Options = [Option]</v>
- <v>&nbsp;Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}</v>
- <v>&nbsp;&nbsp;Dbgs = [Dbg]</v>
- <v>&nbsp;&nbsp;&nbsp;Dbg = trace | log | statistics</v>
- <v>&nbsp;&nbsp;&nbsp;&nbsp;| {log_to_file,FileName} | {install,{Func,FuncState}}</v>
- <v>&nbsp;&nbsp;SOpts = [SOpt]</v>
- <v>&nbsp;&nbsp;&nbsp;SOpt - see erlang:spawn_opt/2,3,4,5</v>
- <v>Result = {ok,Pid} | ignore | {error,Error}</v>
- <v>&nbsp;Pid = pid()</v>
- <v>&nbsp;Error = {already_started,Pid} | term()</v>
- </type>
- <desc>
- <p>Creates a <c>gen_fsm</c> process as part of a supervision tree.
- The function is to be called, directly or indirectly, by
- the supervisor. For example, it ensures that
- the <c>gen_fsm</c> process is linked to the supervisor.</p>
- <p>The <c>gen_fsm</c> process calls
- <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> to
- initialize. To ensure a synchronized startup procedure,
- <c>start_link/3,4</c> does not return until
- <c>Module:init/1</c> has returned.</p>
- <list type="bulleted">
- <item>
- <p>If <c>FsmName={local,Name}</c>, the <c>gen_fsm</c> process is
- registered locally as <c>Name</c> using <c>register/2</c>.</p>
- </item>
- <item>
- <p>If <c>FsmName={global,GlobalName}</c>, the <c>gen_fsm</c> process
- is registered globally as <c>GlobalName</c> using
- <seealso marker="kernel:global#register_name/2">
- <c>global:register_name/2</c></seealso>.</p>
- </item>
- <item>
- <p>If <c>FsmName={via,Module,ViaName}</c>, the <c>gen_fsm</c>
- process registers with the registry represented by <c>Module</c>.
- The <c>Module</c> callback is to export the functions
- <c>register_name/2</c>, <c>unregister_name/1</c>,
- <c>whereis_name/1</c>, and <c>send/2</c>, which are to behave
- like the corresponding functions in
- <seealso marker="kernel:global"><c>global</c></seealso>.
- Thus, <c>{via,global,GlobalName}</c> is a valid reference.</p>
- </item>
- </list>
- <p>If no name is provided, the <c>gen_fsm</c> process is not
- registered.</p>
- <p><c>Module</c> is the name of the callback module.</p>
- <p><c>Args</c> is any term that is passed as
- the argument to <c>Module:init/1</c>.</p>
- <p>If option <c>{timeout,Time}</c> is present, the <c>gen_fsm</c>
- process is allowed to spend <c>Time</c> milliseconds initializing
- or it terminates and the start function returns
- <c>{error,timeout}</c>.</p>
- <p>If option <c>{debug,Dbgs}</c> is present, the corresponding
- <c>sys</c> function is called for each item in <c>Dbgs</c>; see
- <seealso marker="sys"><c>sys(3)</c></seealso>.</p>
- <p>If option <c>{spawn_opt,SOpts}</c> is present, <c>SOpts</c> is
- passed as option list to the <c>spawn_opt</c> BIF that is used to
- spawn the <c>gen_fsm</c> process; see
- <seealso marker="erts:erlang#spawn_opt/2">
- <c>spawn_opt/2</c></seealso>.</p>
- <note>
- <p>Using spawn option <c>monitor</c> is not
- allowed, it causes the function to fail with reason
- <c>badarg</c>.</p>
- </note>
- <p>If the <c>gen_fsm</c> process is successfully created and
- initialized, the function returns <c>{ok,Pid}</c>, where <c>Pid</c>
- is the pid of the <c>gen_fsm</c> process. If a process with the
- specified <c>FsmName</c> exists already, the function returns
- <c>{error,{already_started,Pid}}</c>, where <c>Pid</c> is
- the pid of that process.</p>
- <p>If <c>Module:init/1</c> fails with <c>Reason</c>,
- the function returns <c>{error,Reason}</c>. If
- <c>Module:init/1</c> returns <c>{stop,Reason}</c> or
- <c>ignore</c>, the process is terminated and the function
- returns <c>{error,Reason}</c> or <c>ignore</c>, respectively.</p>
- </desc>
- </func>
-
- <func>
- <name>start_timer(Time, Msg) -> Ref</name>
- <fsummary>Send a time-out event internally in a generic FSM.</fsummary>
- <type>
- <v>Time = integer()</v>
- <v>Msg = term()</v>
- <v>Ref = reference()</v>
- </type>
- <desc>
- <p>Sends a time-out event internally in the <c>gen_fsm</c>
- process that calls this function after <c>Time</c> milliseconds.
- Returns immediately a
- reference that can be used to cancel the timer using
- <seealso marker="#cancel_timer/1"><c>cancel_timer/1</c></seealso>.</p>
- <p>The <c>gen_fsm</c> process calls
- <seealso marker="#Module:StateName/2">
- <c>Module:StateName/2</c></seealso> to handle
- the event, where <c>StateName</c> is the name of the current
- state of the <c>gen_fsm</c> process at the time the time-out
- message is delivered.</p>
- <p><c>Msg</c> is any term that is passed in the
- time-out message, <c>{timeout, Ref, Msg}</c>, as one of
- the arguments to <c>Module:StateName/2</c>.</p>
- </desc>
- </func>
-
- <func>
- <name>stop(FsmRef) -> ok</name>
- <name>stop(FsmRef, Reason, Timeout) -> ok</name>
- <fsummary>Synchronously stop a generic FSM.</fsummary>
- <type>
- <v>FsmRef = Name | {Name,Node} | {global,GlobalName}</v>
- <v>&nbsp;&nbsp;| {via,Module,ViaName} | pid()</v>
- <v>&nbsp;Node = atom()</v>
- <v>&nbsp;GlobalName = ViaName = term()</v>
- <v>Reason = term()</v>
- <v>Timeout = int()>0 | infinity</v>
- </type>
- <desc>
- <p>Orders a generic finite state machine to exit with the specified
- <c>Reason</c> and waits for it to terminate. The <c>gen_fsm</c>
- process calls <seealso marker="#Module:terminate/3">
- <c>Module:terminate/3</c></seealso> before exiting.</p>
- <p>The function returns <c>ok</c> if the generic finite state machine
- terminates with the expected reason. Any other reason than
- <c>normal</c>, <c>shutdown</c>, or <c>{shutdown,Term}</c> causes an
- error report to be issued using
- <seealso marker="kernel:error_logger#format/2">
- <c>error_logger:format/2</c></seealso>.
- The default <c>Reason</c> is <c>normal</c>.</p>
- <p><c>Timeout</c> is an integer greater than zero that
- specifies how many milliseconds to wait for the generic FSM
- to terminate, or the atom <c>infinity</c> to wait
- indefinitely. The default value is <c>infinity</c>. If the
- generic finite state machine has not terminated within the specified
- time, a <c>timeout</c> exception is raised.</p>
- <p>If the process does not exist, a <c>noproc</c> exception
- is raised.</p>
- </desc>
- </func>
-
- <func>
- <name>sync_send_all_state_event(FsmRef, Event) -> Reply</name>
- <name>sync_send_all_state_event(FsmRef, Event, Timeout) -> Reply</name>
- <fsummary>Send an event synchronously to a generic FSM.</fsummary>
- <type>
- <v>FsmRef = Name | {Name,Node} | {global,GlobalName}</v>
- <v>&nbsp;&nbsp;| {via,Module,ViaName} | pid()</v>
- <v>&nbsp;Name = Node = atom()</v>
- <v>&nbsp;GlobalName = ViaName = term()</v>
- <v>Event = term()</v>
- <v>Timeout = int()>0 | infinity</v>
- <v>Reply = term()</v>
- </type>
- <desc>
- <p>Sends an event to the <c>FsmRef</c> of the <c>gen_fsm</c>
- process and waits until a reply arrives or a time-out occurs.
- The <c>gen_fsm</c> process calls
- <seealso marker="#Module:handle_sync_event/4">
- <c>Module:handle_sync_event/4</c></seealso> to handle the event.</p>
- <p>For a description of <c>FsmRef</c> and <c>Event</c>, see
- <seealso marker="#send_event/2">send_event/2</seealso>.
- For a description of <c>Timeout</c> and <c>Reply</c>, see
- <seealso marker="#sync_send_event/3">
- <c>sync_send_event/3</c></seealso>.</p>
- <p>For a discussion about the difference between
- <c>sync_send_event</c> and <c>sync_send_all_state_event</c>, see
- <seealso marker="#send_all_state_event/2">
- <c>send_all_state_event/2</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>sync_send_event(FsmRef, Event) -> Reply</name>
- <name>sync_send_event(FsmRef, Event, Timeout) -> Reply</name>
- <fsummary>Send an event synchronously to a generic FSM.</fsummary>
- <type>
- <v>FsmRef = Name | {Name,Node} | {global,GlobalName}</v>
- <v>&nbsp;&nbsp;| {via,Module,ViaName} | pid()</v>
- <v>&nbsp;Name = Node = atom()</v>
- <v>&nbsp;GlobalName = ViaName = term()</v>
- <v>Event = term()</v>
- <v>Timeout = int()>0 | infinity</v>
- <v>Reply = term()</v>
- </type>
- <desc>
- <p>Sends an event to the <c>FsmRef</c> of the <c>gen_fsm</c>
- process and waits until a reply arrives or a time-out occurs.
- <c>The gen_fsm</c> process calls
- <seealso marker="#Module:StateName/3">
- <c>Module:StateName/3</c></seealso> to handle the event, where
- <c>StateName</c> is the name of the current state of
- the <c>gen_fsm</c> process.</p>
- <p>For a description of <c>FsmRef</c> and <c>Event</c>, see
- <seealso marker="#send_event/2"><c>send_event/2</c></seealso>.</p>
- <p><c>Timeout</c> is an integer greater than zero that
- specifies how many milliseconds to wait for a reply, or
- the atom <c>infinity</c> to wait indefinitely. Defaults
- to 5000. If no reply is received within the specified time,
- the function call fails.</p>
- <p>Return value <c>Reply</c> is defined in the return value
- of <c>Module:StateName/3</c>.</p>
- <note>
- <p>The ancient behavior of sometimes consuming the server
- exit message if the server died during the call while
- linked to the client was removed in Erlang 5.6/OTP R12B.</p>
- </note>
- </desc>
- </func>
- </funcs>
-
- <section>
- <title>Callback Functions</title>
- <p>The following functions are to be exported from a <c>gen_fsm</c>
- callback module.</p>
-
- <p><em>state name</em> denotes a state of the state machine.</p>
-
- <p><em>state data</em> denotes the internal state of the Erlang process
- that implements the state machine.</p>
- </section>
-
- <funcs>
- <func>
- <name>Module:code_change(OldVsn, StateName, StateData, Extra) -> {ok, NextStateName, NewStateData}</name>
- <fsummary>Update the internal state data during upgrade/downgrade.
- </fsummary>
- <type>
- <v>OldVsn = Vsn | {down, Vsn}</v>
- <v>&nbsp;&nbsp;Vsn = term()</v>
- <v>StateName = NextStateName = atom()</v>
- <v>StateData = NewStateData = term()</v>
- <v>Extra = term()</v>
- </type>
- <desc>
- <p>This function is called by a <c>gen_fsm</c> process when it is to
- update its internal state data during a release upgrade/downgrade,
- that is, when instruction <c>{update,Module,Change,...}</c>,
- where <c>Change={advanced,Extra}</c>, is given in
- the <c>appup</c> file; see section
- <seealso marker="doc/design_principles:release_handling#instr">
- Release Handling Instructions</seealso> in OTP Design Principles.</p>
- <p>For an upgrade, <c>OldVsn</c> is <c>Vsn</c>, and for a downgrade,
- <c>OldVsn</c> is <c>{down,Vsn}</c>. <c>Vsn</c> is defined by the
- <c>vsn</c> attribute(s) of the old version of the callback module
- <c>Module</c>. If no such attribute is defined, the version is
- the checksum of the Beam file.</p>
- <p><c>StateName</c> is the current state name and <c>StateData</c> the
- internal state data of the <c>gen_fsm</c> process.</p>
- <p><c>Extra</c> is passed "as is" from the <c>{advanced,Extra}</c>
- part of the update instruction.</p>
- <p>The function is to return the new current state name and
- updated internal data.</p>
- </desc>
- </func>
-
- <func>
- <name>Module:format_status(Opt, [PDict, StateData]) -> Status</name>
- <fsummary>Optional function for providing a term describing the
- current <c>gen_fsm</c> process status.</fsummary>
- <type>
- <v>Opt = normal | terminate</v>
- <v>PDict = [{Key, Value}]</v>
- <v>StateData = term()</v>
- <v>Status = term()</v>
- </type>
- <desc>
- <note>
- <p>This callback is optional, so callback modules need not
- export it. The <c>gen_fsm</c> module provides a default
- implementation of this function that returns the callback
- module state data.</p>
- </note>
- <p>This function is called by a <c>gen_fsm</c> process in the
- following situations:</p>
- <list type="bulleted">
- <item>One of <seealso marker="sys#get_status/1">
- <c>sys:get_status/1,2</c></seealso>
- is invoked to get the <c>gen_fsm</c> status. <c>Opt</c> is set to
- the atom <c>normal</c> for this case.</item>
- <item>The <c>gen_fsm</c> process terminates abnormally and logs an
- error. <c>Opt</c> is set to the atom <c>terminate</c> for
- this case.</item>
- </list>
- <p>This function is useful for changing the form and
- appearance of the <c>gen_fsm</c> status for these cases. A callback
- module wishing to change the <c>sys:get_status/1,2</c>
- return value as well as how its status appears in
- termination error logs, exports an instance
- of <c>format_status/2</c> that returns a term describing the
- current status of the <c>gen_fsm</c> process.</p>
- <p><c>PDict</c> is the current value of the process dictionary of the
- <c>gen_fsm</c> process.</p>
- <p><c>StateData</c> is the internal state data of the
- <c>gen_fsm</c> process.</p>
- <p>The function is to return <c>Status</c>, a term that
- change the details of the current state and status of
- the <c>gen_fsm</c> process. There are no restrictions on the
- form <c>Status</c> can take, but for
- the <c>sys:get_status/1,2</c> case (when <c>Opt</c>
- is <c>normal</c>), the recommended form for
- the <c>Status</c> value is <c>[{data, [{"StateData",
- Term}]}]</c>, where <c>Term</c> provides relevant details of
- the <c>gen_fsm</c> state data. Following this recommendation is not
- required, but it makes the callback module status
- consistent with the rest of the <c>sys:get_status/1,2</c>
- return value.</p>
- <p>One use for this function is to return compact alternative
- state data representations to avoid that large state terms
- are printed in log files.</p>
- </desc>
- </func>
-
- <func>
- <name>Module:handle_event(Event, StateName, StateData) -> Result</name>
- <fsummary>Handle an asynchronous event.</fsummary>
- <type>
- <v>Event = term()</v>
- <v>StateName = atom()</v>
- <v>StateData = term()</v>
- <v>Result = {next_state,NextStateName,NewStateData}</v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,Timeout}</v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,hibernate}</v>
- <v>&nbsp;&nbsp;| {stop,Reason,NewStateData}</v>
- <v>&nbsp;NextStateName = atom()</v>
- <v>&nbsp;NewStateData = term()</v>
- <v>&nbsp;Timeout = int()>0 | infinity</v>
- <v>&nbsp;Reason = term()</v>
- </type>
- <desc>
- <p>Whenever a <c>gen_fsm</c> process receives an event sent using
- <seealso marker="#send_all_state_event/2">
- <c>send_all_state_event/2</c></seealso>,
- this function is called to handle the event.</p>
- <p><c>StateName</c> is the current state name of the <c>gen_fsm</c>
- process.</p>
- <p>For a description of the other arguments and possible return values,
- see <seealso marker="#Module:StateName/2">
- <c>Module:StateName/2</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>Module:handle_info(Info, StateName, StateData) -> Result</name>
- <fsummary>Handle an incoming message.</fsummary>
- <type>
- <v>Info = term()</v>
- <v>StateName = atom()</v>
- <v>StateData = term()</v>
- <v>Result = {next_state,NextStateName,NewStateData}</v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,Timeout}</v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,hibernate}</v>
- <v>&nbsp;&nbsp;| {stop,Reason,NewStateData}</v>
- <v>&nbsp;NextStateName = atom()</v>
- <v>&nbsp;NewStateData = term()</v>
- <v>&nbsp;Timeout = int()>0 | infinity</v>
- <v>&nbsp;Reason = normal | term()</v>
- </type>
- <desc>
- <p>This function is called by a <c>gen_fsm</c> process when it receives
- any other message than a synchronous or asynchronous event (or a
- system message).</p>
- <p><c>Info</c> is the received message.</p>
- <p>For a description of the other arguments and possible return values,
- see <seealso marker="#Module:StateName/2">
- <c>Module:StateName/2</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>Module:handle_sync_event(Event, From, StateName, StateData) -> Result</name>
- <fsummary>Handle a synchronous event.</fsummary>
- <type>
- <v>Event = term()</v>
- <v>From = {pid(),Tag}</v>
- <v>StateName = atom()</v>
- <v>StateData = term()</v>
- <v>Result = {reply,Reply,NextStateName,NewStateData}</v>
- <v>&nbsp;&nbsp;| {reply,Reply,NextStateName,NewStateData,Timeout}</v>
- <v>&nbsp;&nbsp;| {reply,Reply,NextStateName,NewStateData,hibernate}</v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData}</v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,Timeout}</v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,hibernate}</v>
- <v>&nbsp;&nbsp;| {stop,Reason,Reply,NewStateData} | {stop,Reason,NewStateData}</v>
- <v>&nbsp;Reply = term()</v>
- <v>&nbsp;NextStateName = atom()</v>
- <v>&nbsp;NewStateData = term()</v>
- <v>&nbsp;Timeout = int()>0 | infinity</v>
- <v>&nbsp;Reason = term()</v>
- </type>
- <desc>
- <p>Whenever a <c>gen_fsm</c> process receives an event sent using
- <seealso marker="#sync_send_all_state_event/2">
- <c>sync_send_all_state_event/2,3</c></seealso>,
- this function is called to handle the event.</p>
- <p><c>StateName</c> is the current state name of the <c>gen_fsm</c>
- process.</p>
- <p>For a description of the other arguments and possible return values,
- see <seealso marker="#Module:StateName/3">
- <c>Module:StateName/3</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>Module:init(Args) -> Result</name>
- <fsummary>Initialize process and internal state name and state data.
- </fsummary>
- <type>
- <v>Args = term()</v>
- <v>Result = {ok,StateName,StateData} | {ok,StateName,StateData,Timeout}</v>
- <v>&nbsp;&nbsp;| {ok,StateName,StateData,hibernate}</v>
- <v>&nbsp;&nbsp;| {stop,Reason} | ignore</v>
- <v>&nbsp;StateName = atom()</v>
- <v>&nbsp;StateData = term()</v>
- <v>&nbsp;Timeout = int()>0 | infinity</v>
- <v>&nbsp;Reason = term()</v>
- </type>
- <desc>
- <marker id="Moduleinit"></marker>
- <p>Whenever a <c>gen_fsm</c> process is started using
- <seealso marker="#start/3"><c>start/3,4</c></seealso> or
- <seealso marker="#start_link/3"><c>start_link/3,4</c></seealso>,
- this function is called by the new process to initialize.</p>
- <p><c>Args</c> is the <c>Args</c> argument provided to the start
- function.</p>
- <p>If initialization is successful, the function is to return
- <c>{ok,StateName,StateData}</c>,
- <c>{ok,StateName,StateData,Timeout}</c>, or
- <c>{ok,StateName,StateData,hibernate}</c>, where <c>StateName</c>
- is the initial state name and <c>StateData</c> the initial
- state data of the <c>gen_fsm</c> process.</p>
- <p>If an integer time-out value is provided, a time-out occurs
- unless an event or a message is received within <c>Timeout</c>
- milliseconds. A time-out is represented by the atom
- <c>timeout</c> and is to be handled by the
- <seealso marker="#Module:StateName/2">
- <c>Module:StateName/2</c></seealso> callback functions. The atom
- <c>infinity</c> can be used to wait indefinitely, this is
- the default value.</p>
- <p>If <c>hibernate</c> is specified instead of a time-out value, the
- process goes into hibernation when waiting for the next message
- to arrive (by calling <seealso marker="proc_lib#hibernate/3">
- <c>proc_lib:hibernate/3</c></seealso>).</p>
- <p>If the initialization fails, the function returns
- <c>{stop,Reason}</c>, where <c>Reason</c> is any term,
- or <c>ignore</c>.</p>
- </desc>
- </func>
-
- <func>
- <name>Module:StateName(Event, StateData) -> Result</name>
- <fsummary>Handle an asynchronous event.</fsummary>
- <type>
- <v>Event = timeout | term()</v>
- <v>StateData = term()</v>
- <v>Result = {next_state,NextStateName,NewStateData} </v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,Timeout}</v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,hibernate}</v>
- <v>&nbsp;&nbsp;| {stop,Reason,NewStateData}</v>
- <v>&nbsp;NextStateName = atom()</v>
- <v>&nbsp;NewStateData = term()</v>
- <v>&nbsp;Timeout = int()>0 | infinity</v>
- <v>&nbsp;Reason = term()</v>
- </type>
- <desc>
- <p>There is to be one instance of this function for each
- possible state name. Whenever a <c>gen_fsm</c> process receives
- an event sent using
- <seealso marker="#send_event/2"><c>send_event/2</c></seealso>,
- the instance of this function with the same name as
- the current state name <c>StateName</c> is called to handle
- the event. It is also called if a time-out occurs.</p>
- <p><c>Event</c> is either the atom <c>timeout</c>, if a time-out
- has occurred, or the <c>Event</c> argument provided to
- <c>send_event/2</c>.</p>
- <p><c>StateData</c> is the state data of the <c>gen_fsm</c> process.</p>
- <p>If the function returns
- <c>{next_state,NextStateName,NewStateData}</c>,
- <c>{next_state,NextStateName,NewStateData,Timeout}</c>, or
- <c>{next_state,NextStateName,NewStateData,hibernate}</c>, the
- <c>gen_fsm</c> process continues executing with the current state
- name set to <c>NextStateName</c> and with the possibly
- updated state data <c>NewStateData</c>. For a description of
- <c>Timeout</c> and <c>hibernate</c>, see
- <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>.</p>
- <p>If the function returns <c>{stop,Reason,NewStateData}</c>,
- the <c>gen_fsm</c> process calls
- <c>Module:terminate(Reason,StateName,NewStateData)</c> and
- terminates.</p>
- </desc>
- </func>
-
- <func>
- <name>Module:StateName(Event, From, StateData) -> Result</name>
- <fsummary>Handle a synchronous event.</fsummary>
- <type>
- <v>Event = term()</v>
- <v>From = {pid(),Tag}</v>
- <v>StateData = term()</v>
- <v>Result = {reply,Reply,NextStateName,NewStateData}</v>
- <v>&nbsp;&nbsp;| {reply,Reply,NextStateName,NewStateData,Timeout}</v>
- <v>&nbsp;&nbsp;| {reply,Reply,NextStateName,NewStateData,hibernate}</v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData}</v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,Timeout}</v>
- <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,hibernate}</v>
- <v>&nbsp;&nbsp;| {stop,Reason,Reply,NewStateData} | {stop,Reason,NewStateData}</v>
- <v>&nbsp;Reply = term()</v>
- <v>&nbsp;NextStateName = atom()</v>
- <v>&nbsp;NewStateData = term()</v>
- <v>&nbsp;Timeout = int()>0 | infinity</v>
- <v>&nbsp;Reason = normal | term()</v>
- </type>
- <desc>
- <p>There is to be one instance of this function for each
- possible state name. Whenever a <c>gen_fsm</c> process receives an
- event sent using <seealso marker="#sync_send_event/2">
- <c>sync_send_event/2,3</c></seealso>,
- the instance of this function with the same name as
- the current state name <c>StateName</c> is called to handle
- the event.</p>
- <p><c>Event</c> is the <c>Event</c> argument provided to
- <c>sync_send_event/2,3</c>.</p>
- <p><c>From</c> is a tuple <c>{Pid,Tag}</c> where <c>Pid</c> is
- the pid of the process that called <c>sync_send_event/2,3</c>
- and <c>Tag</c> is a unique tag.</p>
- <p><c>StateData</c> is the state data of the <c>gen_fsm</c> process.</p>
- <list type="bulleted">
- <item>
- <p>If <c>{reply,Reply,NextStateName,NewStateData}</c>,
- <c>{reply,Reply,NextStateName,NewStateData,Timeout}</c>, or
- <c>{reply,Reply,NextStateName,NewStateData,hibernate}</c> is
- returned, <c>Reply</c> is given back to <c>From</c> as the return
- value of <c>sync_send_event/2,3</c>. The <c>gen_fsm</c> process
- then continues executing with the current state name set to
- <c>NextStateName</c> and with the possibly updated state data
- <c>NewStateData</c>. For a description of <c>Timeout</c> and
- <c>hibernate</c>, see
- <seealso marker="#Module:init/1">
- <c>Module:init/1</c></seealso>.</p>
- </item>
- <item>
- <p>If <c>{next_state,NextStateName,NewStateData}</c>,
- <c>{next_state,NextStateName,NewStateData,Timeout}</c>, or
- <c>{next_state,NextStateName,NewStateData,hibernate}</c> is
- returned, the <c>gen_fsm</c> process continues executing in
- <c>NextStateName</c> with <c>NewStateData</c>.
- Any reply to <c>From</c> must be specified explicitly using
- <seealso marker="#reply/2"><c>reply/2</c></seealso>.</p>
- </item>
- <item>
- <p>If the function returns
- <c>{stop,Reason,Reply,NewStateData}</c>, <c>Reply</c> is
- given back to <c>From</c>. If the function returns
- <c>{stop,Reason,NewStateData}</c>, any reply to <c>From</c>
- must be specified explicitly using <c>reply/2</c>.
- The <c>gen_fsm</c> process then calls
- <c>Module:terminate(Reason,StateName,NewStateData)</c> and
- terminates.</p>
- </item>
- </list>
- </desc>
- </func>
-
- <func>
- <name>Module:terminate(Reason, StateName, StateData)</name>
- <fsummary>Clean up before termination.</fsummary>
- <type>
- <v>Reason = normal | shutdown | {shutdown,term()} | term()</v>
- <v>StateName = atom()</v>
- <v>StateData = term()</v>
- </type>
- <desc>
- <p>This function is called by a <c>gen_fsm</c> process when it is about
- to terminate. It is to be the opposite of
- <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
- and do any necessary cleaning up. When it returns, the <c>gen_fsm</c>
- process terminates with <c>Reason</c>. The return value is ignored.
- </p>
- <p><c>Reason</c> is a term denoting the stop reason,
- <c>StateName</c> is the current state name, and
- <c>StateData</c> is the state data of the <c>gen_fsm</c> process.</p>
- <p><c>Reason</c> depends on why the <c>gen_fsm</c> process is
- terminating. If
- it is because another callback function has returned a stop
- tuple <c>{stop,..}</c>, <c>Reason</c> has the value
- specified in that tuple. If it is because of a failure,
- <c>Reason</c> is the error reason.</p>
- <p>If the <c>gen_fsm</c> process is part of a supervision tree and is
- ordered by its supervisor to terminate, this function is called
- with <c>Reason=shutdown</c> if the following conditions apply:</p>
- <list type="bulleted">
- <item>
- <p>The <c>gen_fsm</c> process has been set to trap exit signals.</p>
- </item>
- <item>
- <p>The shutdown strategy as defined in the child specification of
- the supervisor is an integer time-out value, not
- <c>brutal_kill</c>.</p>
- </item>
- </list>
- <p>Even if the <c>gen_fsm</c> process is <em>not</em> part of a
- supervision tree,
- this function is called if it receives an <c>'EXIT'</c>
- message from its parent. <c>Reason</c> is the same as in
- the <c>'EXIT'</c> message.</p>
- <p>Otherwise, the <c>gen_fsm</c> process terminates immediately.</p>
- <p>Notice that for any other reason than <c>normal</c>,
- <c>shutdown</c>, or <c>{shutdown,Term}</c> the <c>gen_fsm</c> process
- is assumed to terminate because of an error and an error report is
- issued using <seealso marker="kernel:error_logger#format/2">
- <c>error_logger:format/2</c></seealso>.</p>
- </desc>
- </func>
- </funcs>
-
<section>
- <title>See Also</title>
- <p><seealso marker="gen_event"><c>gen_event(3)</c></seealso>,
- <seealso marker="gen_server"><c>gen_server(3)</c></seealso>,
- <seealso marker="gen_statem"><c>gen_statem(3)</c></seealso>,
- <seealso marker="proc_lib"><c>proc_lib(3)</c></seealso>,
- <seealso marker="supervisor"><c>supervisor(3)</c></seealso>,
- <seealso marker="sys"><c>sys(3)</c></seealso></p>
+ <marker id="Migration to gen_statem"/>
+ <title>Migration to gen_statem</title>
+
+ <p>Here follows a simple example of turning a gen_fsm into
+ a <seealso marker="gen_statem"><c>gen_statem</c></seealso>. The example comes
+ from the previous Users Guide for <c>gen_fsm</c> </p>
+
+ <code type="erl">
+-module(code_lock).
+-define(NAME, code_lock).
+%-define(BEFORE_REWRITE, true).
+
+-ifdef(BEFORE_REWRITE).
+-behaviour(gen_fsm).
+-else.
+-behaviour(gen_statem).
+-endif.
+
+-export([start_link/1, button/1, stop/0]).
+
+-ifdef(BEFORE_REWRITE).
+-export([init/1, locked/2, open/2, handle_sync_event/4, handle_event/3,
+ handle_info/3, terminate/3, code_change/4]).
+-else.
+-export([init/1, callback_mode/0, locked/3, open/3, terminate/3, code_change/4]).
+%% Add callback__mode/0
+%% Change arity of the state functions
+%% Remove handle_info/3
+-endif.
+
+-ifdef(BEFORE_REWRITE).
+start_link(Code) ->
+ gen_fsm:start_link({local, ?NAME}, ?MODULE, Code, []).
+-else.
+start_link(Code) ->
+ gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).
+-endif.
+
+-ifdef(BEFORE_REWRITE).
+button(Digit) ->
+ gen_fsm:send_event(?NAME, {button, Digit}).
+-else.
+button(Digit) ->
+ gen_statem:cast(?NAME, {button,Digit}).
+ %% send_event is asynchronous and becomes a cast
+-endif.
+
+-ifdef(BEFORE_REWRITE).
+stop() ->
+ gen_fsm:sync_send_all_state_event(?NAME, stop).
+-else.
+stop() ->
+ gen_statem:call(?NAME, stop).
+ %% sync_send is synchronous and becomes call
+ %% all_state is handled by callback code in gen_statem
+-endif.
+
+init(Code) ->
+ do_lock(),
+ Data = #{code => Code, remaining => Code},
+ {ok, locked, Data}.
+
+-ifdef(BEFORE_REWRITE).
+-else.
+callback_mode() ->
+ state_functions.
+%% state_functions mode is the mode most similar to
+%% gen_fsm. There is also handle_event mode which is
+%% a fairly different concept.
+-endif.
+
+-ifdef(BEFORE_REWRITE).
+locked({button, Digit}, Data0) ->
+ case analyze_lock(Digit, Data0) of
+ {open = StateName, Data} ->
+ {next_state, StateName, Data, 10000};
+ {StateName, Data} ->
+ {next_state, StateName, Data}
+ end.
+-else.
+locked(cast, {button,Digit}, Data0) ->
+ case analyze_lock(Digit, Data0) of
+ {open = StateName, Data} ->
+ {next_state, StateName, Data, 10000};
+ {StateName, Data} ->
+ {next_state, StateName, Data}
+ end;
+locked({call, From}, Msg, Data) ->
+ handle_call(From, Msg, Data);
+locked({info, Msg}, StateName, Data) ->
+ handle_info(Msg, StateName, Data).
+%% Arity differs
+%% All state events are dispatched to handle_call and handle_info help
+%% functions. If you want to handle a call or cast event specifically
+%% for this state you would add a special clause for it above.
+-endif.
+
+-ifdef(BEFORE_REWRITE).
+open(timeout, State) ->
+ do_lock(),
+ {next_state, locked, State};
+open({button,_}, Data) ->
+ {next_state, locked, Data}.
+-else.
+open(timeout, _, Data) ->
+ do_lock(),
+ {next_state, locked, Data};
+open(cast, {button,_}, Data) ->
+ {next_state, locked, Data};
+open({call, From}, Msg, Data) ->
+ handle_call(From, Msg, Data);
+open(info, Msg, Data) ->
+ handle_info(Msg, open, Data).
+%% Arity differs
+%% All state events are dispatched to handle_call and handle_info help
+%% functions. If you want to handle a call or cast event specifically
+%% for this state you would add a special clause for it above.
+-endif.
+
+-ifdef(BEFORE_REWRITE).
+handle_sync_event(stop, _From, _StateName, Data) ->
+ {stop, normal, ok, Data}.
+
+handle_event(Event, StateName, Data) ->
+ {stop, {shutdown, {unexpected, Event, StateName}}, Data}.
+
+handle_info(Info, StateName, Data) ->
+ {stop, {shutdown, {unexpected, Info, StateName}}, StateName, Data}.
+-else.
+-endif.
+
+terminate(_Reason, State, _Data) ->
+ State =/= locked andalso do_lock(),
+ ok.
+code_change(_Vsn, State, Data, _Extra) ->
+ {ok, State, Data}.
+
+%% Internal functions
+-ifdef(BEFORE_REWRITE).
+-else.
+handle_call(From, stop, Data) ->
+ {stop_and_reply, normal, {reply, From, ok}, Data}.
+
+handle_info(Info, StateName, Data) ->
+ {stop, {shutdown, {unexpected, Info, StateName}}, StateName, Data}.
+%% These are internal functions for handling all state events
+%% and not behaviour callbacks as in gen_fsm
+-endif.
+
+analyze_lock(Digit, #{code := Code, remaining := Remaining} = Data) ->
+ case Remaining of
+ [Digit] ->
+ do_unlock(),
+ {open, Data#{remaining := Code}};
+ [Digit|Rest] -> % Incomplete
+ {locked, Data#{remaining := Rest}};
+ _Wrong ->
+ {locked, Data#{remaining := Code}}
+ end.
+
+do_lock() ->
+ io:format("Lock~n", []).
+do_unlock() ->
+ io:format("Unlock~n", []).
+ </code>
</section>
</erlref>
diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml
index 4a7dd60858..7d137fc772 100644
--- a/lib/stdlib/doc/src/gen_server.xml
+++ b/lib/stdlib/doc/src/gen_server.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -162,11 +162,6 @@ gen_server:abcast -----> Module:handle_cast/2
of <c>Module:handle_call/3</c>.</p>
<p>The call can fail for many reasons, including time-out and the
called <c>gen_server</c> process dying before or during the call.</p>
- <note>
- <p>The ancient behavior of sometimes consuming the server
- exit message if the server died during the call while
- linked to the client was removed in Erlang 5.6/OTP R12B.</p>
- </note>
</desc>
</func>
@@ -204,7 +199,7 @@ gen_server:abcast -----> Module:handle_cast/2
<type>
<v>Module = atom()</v>
<v>Options = [Option]</v>
- <v>&nbsp;Option = {debug,Dbgs}</v>
+ <v>&nbsp;Option = {debug,Dbgs} | {hibernate_after,HibernateAfterTimeout}</v>
<v>&nbsp;&nbsp;Dbgs = [Dbg]</v>
<v>&nbsp;&nbsp;&nbsp;Dbg = trace | log | statistics</v>
<v>&nbsp;&nbsp;&nbsp;&nbsp;| {log_to_file,FileName} | {install,{Func,FuncState}}</v>
@@ -339,7 +334,7 @@ gen_server:abcast -----> Module:handle_cast/2
<v>Module = atom()</v>
<v>Args = term()</v>
<v>Options = [Option]</v>
- <v>&nbsp;Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}</v>
+ <v>&nbsp;Option = {debug,Dbgs} | {timeout,Time} | {hibernate_after,HibernateAfterTimeout} | {spawn_opt,SOpts}</v>
<v>&nbsp;&nbsp;Dbgs = [Dbg]</v>
<v>&nbsp;&nbsp;&nbsp;Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}</v>
<v>&nbsp;&nbsp;SOpts = [term()]</v>
@@ -369,7 +364,7 @@ gen_server:abcast -----> Module:handle_cast/2
<v>Module = atom()</v>
<v>Args = term()</v>
<v>Options = [Option]</v>
- <v>&nbsp;Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}</v>
+ <v>&nbsp;Option = {debug,Dbgs} | {timeout,Time} | {hibernate_after,HibernateAfterTimeout} | {spawn_opt,SOpts}</v>
<v>&nbsp;&nbsp;Dbgs = [Dbg]</v>
<v>&nbsp;&nbsp;&nbsp;Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}</v>
<v>&nbsp;&nbsp;SOpts = [term()]</v>
@@ -422,6 +417,12 @@ gen_server:abcast -----> Module:handle_cast/2
returns <c>{error,timeout}</c>.</p>
</item>
<item>
+ <p>If option <c>{hibernate_after,HibernateAfterTimeout}</c> is present, the <c>gen_server</c>
+ process awaits any message for <c>HibernateAfterTimeout</c> milliseconds and
+ if no message is received, the process goes into hibernation automatically
+ (by calling <seealso marker="proc_lib#hibernate/3"><c>proc_lib:hibernate/3</c></seealso>).</p>
+ </item>
+ <item>
<p>If option <c>{debug,Dbgs}</c> is present,
the corresponding <c>sys</c> function is called for each
item in <c>Dbgs</c>; see
@@ -509,6 +510,13 @@ gen_server:abcast -----> Module:handle_cast/2
<v>Reason = term()</v>
</type>
<desc>
+ <note>
+ <p>This callback is optional, so callback modules need not export it.
+ If a release upgrade/downgrade with <c>Change={advanced,Extra}</c>
+ specified in the <c>appup</c> file is made when <c>code_change/3</c>
+ isn't implemented the process will crash with an <c>undef</c> exit
+ reason.</p>
+ </note>
<p>This function is called by a <c>gen_server</c> process when it is
to update its internal state during a release upgrade/downgrade,
that is, when the instruction <c>{update,Module,Change,...}</c>,
@@ -695,6 +703,12 @@ gen_server:abcast -----> Module:handle_cast/2
<v>&nbsp;Reason = normal | term()</v>
</type>
<desc>
+ <note>
+ <p>This callback is optional, so callback modules need not
+ export it. The <c>gen_server</c> module provides a default
+ implementation of this function that logs about the unexpected
+ <c>Info</c> message, drops it and returns <c>{noreply, State}</c>.</p>
+ </note>
<p>This function is called by a <c>gen_server</c> process when a
time-out occurs or when it receives any other message than a
synchronous or asynchronous request (or a system message).</p>
@@ -755,6 +769,11 @@ gen_server:abcast -----> Module:handle_cast/2
<v>State = term()</v>
</type>
<desc>
+ <note>
+ <p>This callback is optional, so callback modules need not
+ export it. The <c>gen_server</c> module provides a default
+ implementation without cleanup.</p>
+ </note>
<p>This function is called by a <c>gen_server</c> process when it is
about to terminate. It is to be the opposite of
<seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
@@ -801,7 +820,6 @@ gen_server:abcast -----> Module:handle_cast/2
<section>
<title>See Also</title>
<p><seealso marker="gen_event"><c>gen_event(3)</c></seealso>,
- <seealso marker="gen_fsm"><c>gen_fsm(3)</c></seealso>,
<seealso marker="gen_statem"><c>gen_statem(3)</c></seealso>,
<seealso marker="proc_lib"><c>proc_lib(3)</c></seealso>,
<seealso marker="supervisor"><c>supervisor(3)</c></seealso>,
diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml
index c57a31fa21..a7caa71dcb 100644
--- a/lib/stdlib/doc/src/gen_statem.xml
+++ b/lib/stdlib/doc/src/gen_statem.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2016</year>
+ <year>2016</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -54,30 +54,37 @@
<p>
This is a new behavior in Erlang/OTP 19.0.
It has been thoroughly reviewed, is stable enough
- to be used by at least two heavy OTP applications, and is here to stay.
+ to be used by at least two heavy OTP applications,
+ and is here to stay.
Depending on user feedback, we do not expect
but can find it necessary to make minor
not backward compatible changes into Erlang/OTP 20.0.
</p>
</note>
<p>
- The <c>gen_statem</c> behavior is intended to replace
- <seealso marker="gen_fsm"><c>gen_fsm</c></seealso> for new code.
+ The <c>gen_statem</c> behavior replaces
+ <seealso marker="gen_fsm"><c>gen_fsm</c> </seealso> in Erlang/OTP 20.0.
It has the same features and adds some really useful:
</p>
<list type="bulleted">
- <item>State code is gathered.</item>
- <item>The state can be any term.</item>
- <item>Events can be postponed.</item>
- <item>Events can be self-generated.</item>
- <item>A reply can be sent from a later state.</item>
- <item>There can be multiple <c>sys</c> traceable replies.</item>
+ <item>Gathered state code.</item>
+ <item>Arbitrary term state.</item>
+ <item>Event postponing.</item>
+ <item>Self-generated events.</item>
+ <item>State time-out.</item>
+ <item>Multiple generic named time-outs.</item>
+ <item>Absolute time-out time.</item>
+ <item>Automatic state enter calls.</item>
+ <item>Reply from other state than the request.</item>
+ <item>Multiple <c>sys</c> traceable replies.</item>
</list>
<p>
The callback model(s) for <c>gen_statem</c> differs from
the one for <seealso marker="gen_fsm"><c>gen_fsm</c></seealso>,
- but it is still fairly easy to rewrite
- from <c>gen_fsm</c> to <c>gen_statem</c>.
+ but it is still fairly easy to
+ <seealso marker="gen_fsm#Migration to gen_statem">
+ rewrite from
+ </seealso> <c>gen_fsm</c> to <c>gen_statem</c>.
</p>
<p>
A generic state machine process (<c>gen_statem</c>) implemented
@@ -97,6 +104,9 @@ gen_statem module Callback module
gen_statem:start
gen_statem:start_link -----> Module:init/1
+Server start or code change
+ -----> Module:callback_mode/0
+
gen_statem:stop -----> Module:terminate/3
gen_statem:call
@@ -116,37 +126,40 @@ erlang:'!' -----> Module:StateName/3
</p>
<p>
If a callback function fails or returns a bad value,
- the <c>gen_statem</c> terminates. However, an exception of class
+ the <c>gen_statem</c> terminates, unless otherwise stated.
+ However, an exception of class
<seealso marker="erts:erlang#throw/1"><c>throw</c></seealso>
- is not regarded as an error but as a valid return.
+ is not regarded as an error but as a valid return
+ from all callback functions.
</p>
- <marker id="state_function"/>
+ <marker id="state callback"/>
<p>
- The "<em>state function</em>" for a specific
+ The "<em>state callback</em>" for a specific
<seealso marker="#type-state">state</seealso>
in a <c>gen_statem</c> is the callback function that is called
for all events in this state. It is selected depending on which
<seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
- that the implementation specifies when the server starts.
+ that the callback module defines with the callback function
+ <seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>.
</p>
<p>
When the
<seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
is <c>state_functions</c>, the state must be an atom and
- is used as the state function name; see
+ is used as the state callback name; see
<seealso marker="#Module:StateName/3"><c>Module:StateName/3</c></seealso>.
This gathers all code for a specific state
in one function as the <c>gen_statem</c> engine
branches depending on state name.
- Notice that in this mode the mandatory callback function
+ Note the fact that the callback function
<seealso marker="#Module:terminate/3"><c>Module:terminate/3</c></seealso>
- makes the state name <c>terminate</c> unusable.
+ makes the state name <c>terminate</c> unusable in this mode.
</p>
<p>
When the
<seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
is <c>handle_event_function</c>, the state can be any term
- and the state function name is
+ and the state callback name is
<seealso marker="#Module:handle_event/4"><c>Module:handle_event/4</c></seealso>.
This makes it easy to branch depending on state or event as you desire.
Be careful about which events you handle in which
@@ -156,8 +169,8 @@ erlang:'!' -----> Module:StateName/3
<p>
The <c>gen_statem</c> enqueues incoming events in order of arrival
and presents these to the
- <seealso marker="#state_function">state function</seealso>
- in that order. The state function can postpone an event
+ <seealso marker="#state callback">state callback</seealso>
+ in that order. The state callback can postpone an event
so it is not retried in the current state.
After a state change the queue restarts with the postponed events.
</p>
@@ -169,12 +182,12 @@ erlang:'!' -----> Module:StateName/3
to entering a new receive statement.
</p>
<p>
- The <seealso marker="#state_function">state function</seealso>
+ The <seealso marker="#state callback">state callback</seealso>
can insert events using the
<seealso marker="#type-action"><c>action()</c></seealso>
<c>next_event</c>
and such an event is inserted as the next to present
- to the state function. That is, as if it is
+ to the state callback. That is, as if it is
the oldest incoming event. A dedicated
<seealso marker="#type-event_type"><c>event_type()</c></seealso>
<c>internal</c> can be used for such events making them impossible
@@ -187,9 +200,19 @@ erlang:'!' -----> Module:StateName/3
<seealso marker="gen_fsm"><c>gen_fsm</c></seealso>
to force processing an inserted event before others.
</p>
+ <p>
+ The <c>gen_statem</c> engine can automatically
+ make a specialized call to the
+ <seealso marker="#state callback">state callback</seealso>
+ whenever a new state is entered; see
+ <seealso marker="#type-state_enter"><c>state_enter()</c></seealso>.
+ This is for writing code common to all state entries.
+ Another way to do it is to insert events at state transitions,
+ but you have to do so everywhere it is needed.
+ </p>
<note>
<p>If you in <c>gen_statem</c>, for example, postpone
- an event in one state and then call another state function
+ an event in one state and then call another state callback
of yours, you have not changed states and hence the postponed event
is not retried, which is logical but can be confusing.
</p>
@@ -218,7 +241,7 @@ erlang:'!' -----> Module:StateName/3
The <c>gen_statem</c> process can go into hibernation; see
<seealso marker="proc_lib#hibernate/3"><c>proc_lib:hibernate/3</c></seealso>.
It is done when a
- <seealso marker="#state_function">state function</seealso> or
+ <seealso marker="#state callback">state callback</seealso> or
<seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
specifies <c>hibernate</c> in the returned
<seealso marker="#type-action"><c>Actions</c></seealso>
@@ -249,11 +272,10 @@ erlang:'!' -----> Module:StateName/3
-behaviour(gen_statem).
-export([start/0,push/0,get_count/0,stop/0]).
--export([terminate/3,code_change/4,init/1]).
+-export([terminate/3,code_change/4,init/1,callback_mode/0]).
-export([on/3,off/3]).
name() -> pushbutton_statem. % The registered server name
-callback_mode() -> state_functions.
%% API. This example uses a registered name name()
%% and does not link to the caller.
@@ -270,15 +292,14 @@ stop() ->
terminate(_Reason, _State, _Data) ->
void.
code_change(_Vsn, State, Data, _Extra) ->
- {callback_mode(),State,Data}.
+ {ok,State,Data}.
init([]) ->
- %% Set the callback mode and initial state + data.
- %% Data is used only as a counter.
+ %% Set the initial state + data. Data is used only as a counter.
State = off, Data = 0,
- {callback_mode(),State,Data}.
-
+ {ok,State,Data}.
+callback_mode() -> state_functions.
-%%% State functions
+%%% state callback(s)
off({call,From}, push, Data) ->
%% Go to 'on', increment count and reply
@@ -325,19 +346,14 @@ ok
<p>
To compare styles, here follows the same example using
<seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
- <c>state_functions</c>, or rather the code to replace
- from function <c>init/1</c> of the <c>pushbutton.erl</c>
+ <c>handle_event_function</c>, or rather the code to replace
+ after function <c>init/1</c> of the <c>pushbutton.erl</c>
example file above:
</p>
<code type="erl">
-init([]) ->
- %% Set the callback mode and initial state + data.
- %% Data is used only as a counter.
- State = off, Data = 0,
- {handle_event_function,State,Data}.
-
+callback_mode() -> handle_event_function.
-%%% Event handling
+%%% state callback(s)
handle_event({call,From}, push, off, Data) ->
%% Go to 'on', increment count and reply
@@ -426,8 +442,8 @@ handle_event(_, _, State, Data) ->
<desc>
<p>
Debug option that can be used when starting
- a <c>gen_statem</c> server through, for example,
- <seealso marker="#enter_loop/5"><c>enter_loop/5</c></seealso>.
+ a <c>gen_statem</c> server through,
+ <seealso marker="#enter_loop/4"><c>enter_loop/4-6</c></seealso>.
</p>
<p>
For every entry in <c><anno>Dbgs</anno></c>,
@@ -437,6 +453,21 @@ handle_event(_, _, State, Data) ->
</desc>
</datatype>
<datatype>
+ <name name="hibernate_after_opt"/>
+ <desc>
+ <p>
+ hibernate_after option that can be used when starting
+ a <c>gen_statem</c> server through,
+ <seealso marker="#enter_loop/4"><c>enter_loop/4-6</c></seealso>.
+ </p>
+ <p>If option<seealso marker="#type-hibernate_after_opt"><c>{hibernate_after,HibernateAfterTimeout}</c></seealso> is present, the <c>gen_statem</c>
+ process awaits any message for <c>HibernateAfterTimeout</c> milliseconds and
+ if no message is received, the process goes into hibernation automatically
+ (by calling <seealso marker="proc_lib#hibernate/3"><c>proc_lib:hibernate/3</c></seealso>).
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
<name name="start_opt"/>
<desc>
<p>
@@ -471,6 +502,10 @@ handle_event(_, _, State, Data) ->
<name name="state"/>
<desc>
<p>
+ If the
+ <seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
+ is <c>handle_event_function</c>,
+ the state can be any term.
After a state change (<c>NextState =/= State</c>),
all postponed events are retried.
</p>
@@ -484,6 +519,8 @@ handle_event(_, _, State, Data) ->
<seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
is <c>state_functions</c>,
the state must be of this type.
+ After a state change (<c>NextState =/= State</c>),
+ all postponed events are retried.
</p>
</desc>
</datatype>
@@ -514,9 +551,26 @@ handle_event(_, _, State, Data) ->
originate from the corresponding API functions.
For calls, the event contains whom to reply to.
Type <c>info</c> originates from regular process messages sent
- to the <c>gen_statem</c>. Also, the state machine
- implementation can generate events of types
- <c>timeout</c> and <c>internal</c> to itself.
+ to the <c>gen_statem</c>. The state machine
+ implementation can, in addition to the above,
+ generate
+ <seealso marker="#type-event_type"><c>events of types</c></seealso>
+ <c>timeout</c>, <c>{timeout,<anno>Name</anno>}</c>,
+ <c>state_timeout</c>, and <c>internal</c> to itself.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="callback_mode_result"/>
+ <desc>
+ <p>
+ This is the return type from
+ <seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>
+ and selects
+ <seealso marker="#type-callback_mode">callback mode</seealso>
+ and whether to do
+ <seealso marker="#type-state_enter">state enter calls</seealso>,
+ or not.
</p>
</desc>
</datatype>
@@ -525,12 +579,9 @@ handle_event(_, _, State, Data) ->
<desc>
<p>
The <em>callback mode</em> is selected when starting the
- <c>gen_statem</c> using the return value from
- <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
- or when calling
- <seealso marker="#enter_loop/5"><c>enter_loop/5,6,7</c></seealso>,
- and with the return value from
- <seealso marker="#Module:code_change/4"><c>Module:code_change/4</c></seealso>.
+ <c>gen_statem</c> and after code change
+ using the return value from
+ <seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>.
</p>
<taglist>
<tag><c>state_functions</c></tag>
@@ -555,16 +606,93 @@ handle_event(_, _, State, Data) ->
</desc>
</datatype>
<datatype>
+ <name name="state_enter"/>
+ <desc>
+ <p>
+ Whether the state machine should use <em>state enter calls</em>
+ or not is selected when starting the <c>gen_statem</c>
+ and after code change using the return value from
+ <seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>.
+ </p>
+ <p>
+ If
+ <seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>
+ returns a list containing <c>state_enter</c>,
+ the <c>gen_statem</c> engine will, at every state change,
+ call the
+ <seealso marker="#state callback">state callback</seealso>
+ with arguments <c>(enter, OldState, Data)</c>.
+ This may look like an event but is really a call
+ performed after the previous state callback returned
+ and before any event is delivered to the new state callback.
+ See
+ <seealso marker="#Module:StateName/3"><c>Module:StateName/3</c></seealso>
+ and
+ <seealso marker="#Module:handle_event/4"><c>Module:handle_event/4</c></seealso>.
+ Such a call can be repeated by returning a
+ <seealso marker="#type-state_callback_result">
+ <c>repeat_state</c>
+ </seealso>
+ or
+ <seealso marker="#type-state_callback_result">
+ <c>repeat_state_and_data</c>
+ </seealso>
+ tuple from the state callback.
+ </p>
+ <p>
+ If
+ <seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>
+ does not return such a list, no state enter calls are done.
+ </p>
+ <p>
+ If
+ <seealso marker="#Module:code_change/4"><c>Module:code_change/4</c></seealso>
+ should transform the state to a state with a different
+ name it is still regarded as the same state so this
+ does not cause a state enter call.
+ </p>
+ <p>
+ Note that a state enter call <em>will</em> be done
+ right before entering the initial state even though this
+ formally is not a state change.
+ In this case <c>OldState</c> will be the same as <c>State</c>,
+ which can not happen for a subsequent state change,
+ but will happen when repeating the state enter call.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
<name name="transition_option"/>
<desc>
<p>
Transition options can be set by
<seealso marker="#type-action">actions</seealso>
- and they modify the following in how
- the state transition is done:
+ and they modify how the state transition is done:
</p>
<list type="ordered">
<item>
+ <p>
+ If the state changes, is the initial state,
+ <seealso marker="#type-state_callback_result">
+ <c>repeat_state</c>
+ </seealso>
+ or
+ <seealso marker="#type-state_callback_result">
+ <c>repeat_state_and_data</c>
+ </seealso>
+ is used, and also
+ <seealso marker="#type-state_enter"><em>state enter calls</em></seealso>
+ are used, the <c>gen_statem</c> calls
+ the new state callback with arguments
+ <seealso marker="#type-state_enter">(enter, OldState, Data)</seealso>.
+ Any
+ <seealso marker="#type-enter_action"><c>actions</c></seealso>
+ returned from this call are handled as if they were
+ appended to the actions
+ returned by the state callback that changed states.
+ </p>
+ </item>
+ <item>
<p>
All
<seealso marker="#type-action">actions</seealso>
@@ -590,27 +718,47 @@ handle_event(_, _, State, Data) ->
All events stored with
<seealso marker="#type-action"><c>action()</c></seealso>
<c>next_event</c>
- are inserted in the queue to be processed before
- all other events.
+ are inserted to be processed before the other queued events.
</p>
</item>
<item>
<p>
- If an
+ Time-out timers
+ <seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso>,
+ <seealso marker="#type-generic_timeout"><c>generic_timeout()</c></seealso>
+ and
+ <seealso marker="#type-state_timeout"><c>state_timeout()</c></seealso>
+ are handled. Time-outs with zero time are guaranteed to be
+ delivered to the state machine before any external
+ not yet received event so if there is such a time-out requested,
+ the corresponding time-out zero event is enqueued as
+ the newest event.
+ </p>
+ <p>
+ Any event cancels an
<seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso>
- is set through
- <seealso marker="#type-action"><c>action()</c></seealso>
- <c>timeout</c>,
- an event timer can be started or a time-out zero event
- can be enqueued.
+ so a zero time event time-out is only generated
+ if the event queue is empty.
+ </p>
+ <p>
+ A state change cancels a
+ <seealso marker="#type-state_timeout"><c>state_timeout()</c></seealso>
+ and any new transition option of this type
+ belongs to the new state.
+ </p>
+ </item>
+ <item>
+ <p>
+ If there are enqueued events the
+ <seealso marker="#state callback">state callback</seealso>
+ for the possibly new state
+ is called with the oldest enqueued event,
+ and we start again from the top of this list.
</p>
</item>
<item>
<p>
- The (possibly new)
- <seealso marker="#state_function">state function</seealso>
- is called with the oldest enqueued event if there is any,
- otherwise the <c>gen_statem</c> goes into <c>receive</c>
+ Otherwise the <c>gen_statem</c> goes into <c>receive</c>
or hibernation
(if
<seealso marker="#type-hibernate"><c>hibernate()</c></seealso>
@@ -618,8 +766,11 @@ handle_event(_, _, State, Data) ->
to wait for the next message. In hibernation the next
non-system event awakens the <c>gen_statem</c>, or rather
the next incoming message awakens the <c>gen_statem</c>,
- but if it is a system event
- it goes right back into hibernation.
+ but if it is a system event it goes right back into hibernation.
+ When a new message arrives the
+ <seealso marker="#state callback">state callback</seealso>
+ is called with the corresponding event,
+ and we start again from the top of this list.
</p>
</item>
</list>
@@ -657,41 +808,140 @@ handle_event(_, _, State, Data) ->
<name name="event_timeout"/>
<desc>
<p>
- Generates an event of
+ Starts a timer set by
+ <seealso marker="#type-enter_action"><c>enter_action()</c></seealso>
+ <c>timeout</c>.
+ When the timer expires an event of
<seealso marker="#type-event_type"><c>event_type()</c></seealso>
- <c>timeout</c>
- after this time (in milliseconds) unless another
- event arrives in which case this time-out is cancelled.
- Notice that a retried or inserted event
- counts like a new in this respect.
+ <c>timeout</c> will be generated.
+ See
+ <seealso marker="erts:erlang#start_timer/4"><c>erlang:start_timer/4</c></seealso>
+ for how <c>Time</c> and
+ <seealso marker="#type-timeout_option"><c>Options</c></seealso>
+ are interpreted. Future <c>erlang:start_timer/4</c> <c>Options</c>
+ will not necessarily be supported.
</p>
<p>
- If the value is <c>infinity</c>, no timer is started, as
- it never triggers anyway.
+ Any event that arrives cancels this time-out.
+ Note that a retried or inserted event counts as arrived.
+ So does a state time-out zero event, if it was generated
+ before this time-out is requested.
</p>
<p>
- If the value is <c>0</c>, the time-out event is immediately enqueued
- unless there already are enqueued events, as the
- time-out is then immediately cancelled.
- This is a feature ensuring that a time-out <c>0</c> event
- is processed before any not yet received external event.
+ If <c>Time</c> is <c>infinity</c>,
+ no timer is started, as it never would expire anyway.
</p>
<p>
- Notice that it is not possible or needed to cancel this time-out,
+ If <c>Time</c> is relative and <c>0</c>
+ no timer is actually started,
+ instead the the time-out event is enqueued to ensure
+ that it gets processed before any not yet
+ received external event.
+ </p>
+ <p>
+ Note that it is not possible nor needed to cancel this time-out,
as it is cancelled automatically by any other event.
</p>
</desc>
</datatype>
<datatype>
+ <name name="generic_timeout"/>
+ <desc>
+ <p>
+ Starts a timer set by
+ <seealso marker="#type-enter_action"><c>enter_action()</c></seealso>
+ <c>{timeout,Name}</c>.
+ When the timer expires an event of
+ <seealso marker="#type-event_type"><c>event_type()</c></seealso>
+ <c>{timeout,Name}</c> will be generated.
+ See
+ <seealso marker="erts:erlang#start_timer/4"><c>erlang:start_timer/4</c></seealso>
+ for how <c>Time</c> and
+ <seealso marker="#type-timeout_option"><c>Options</c></seealso>
+ are interpreted. Future <c>erlang:start_timer/4</c> <c>Options</c>
+ will not necessarily be supported.
+ </p>
+ <p>
+ If <c>Time</c> is <c>infinity</c>,
+ no timer is started, as it never would expire anyway.
+ </p>
+ <p>
+ If <c>Time</c> is relative and <c>0</c>
+ no timer is actually started,
+ instead the the time-out event is enqueued to ensure
+ that it gets processed before any not yet
+ received external event.
+ </p>
+ <p>
+ Setting a timer with the same <c>Name</c> while it is running
+ will restart it with the new time-out value.
+ Therefore it is possible to cancel
+ a specific time-out by setting it to <c>infinity</c>.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="state_timeout"/>
+ <desc>
+ <p>
+ Starts a timer set by
+ <seealso marker="#type-enter_action"><c>enter_action()</c></seealso>
+ <c>state_timeout</c>.
+ When the timer expires an event of
+ <seealso marker="#type-event_type"><c>event_type()</c></seealso>
+ <c>state_timeout</c> will be generated.
+ See
+ <seealso marker="erts:erlang#start_timer/4"><c>erlang:start_timer/4</c></seealso>
+ for how <c>Time</c> and
+ <seealso marker="#type-timeout_option"><c>Options</c></seealso>
+ are interpreted. Future <c>erlang:start_timer/4</c> <c>Options</c>
+ will not necessarily be supported.
+ </p>
+ <p>
+ If <c>Time</c> is <c>infinity</c>,
+ no timer is started, as it never would expire anyway.
+ </p>
+ <p>
+ If <c>Time</c> is relative and <c>0</c>
+ no timer is actually started,
+ instead the the time-out event is enqueued to ensure
+ that it gets processed before any not yet
+ received external event.
+ </p>
+ <p>
+ Setting this timer while it is running will restart it with
+ the new time-out value. Therefore it is possible to cancel
+ this time-out by setting it to <c>infinity</c>.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="timeout_option"/>
+ <desc>
+ <p>
+ If <c>Abs</c> is <c>true</c> an absolute timer is started,
+ and if it is <c>false</c> a relative, which is the default.
+ See
+ <seealso marker="erts:erlang#start_timer/4"><c>erlang:start_timer/4</c></seealso>
+ for details.
+ </p>
+ <p>
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
<name name="action"/>
<desc>
<p>
These state transition actions can be invoked by
returning them from the
- <seealso marker="#state_function">state function</seealso>, from
+ <seealso marker="#state callback">state callback</seealso>
+ when it is called with an
+ <seealso marker="#type-event_type">event</seealso>,
+ from
<seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
or by giving them to
- <seealso marker="#enter_loop/6"><c>enter_loop/6,7</c></seealso>.
+ <seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso>.
</p>
<p>
Actions are executed in the containing list order.
@@ -702,8 +952,8 @@ handle_event(_, _, State, Data) ->
override any previous of the same type,
so the last in the containing list wins.
For example, the last
- <seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso>
- overrides any other <c>event_timeout()</c> in the list.
+ <seealso marker="#type-postpone"><c>postpone()</c></seealso>
+ overrides any previous <c>postpone()</c> in the list.
</p>
<taglist>
<tag><c>postpone</c></tag>
@@ -720,6 +970,53 @@ handle_event(_, _, State, Data) ->
as there is no event to postpone in those cases.
</p>
</item>
+ <tag><c>next_event</c></tag>
+ <item>
+ <p>
+ Stores the specified <c><anno>EventType</anno></c>
+ and <c><anno>EventContent</anno></c> for insertion after all
+ actions have been executed.
+ </p>
+ <p>
+ The stored events are inserted in the queue as the next to process
+ before any already queued events. The order of these stored events
+ is preserved, so the first <c>next_event</c> in the containing
+ list becomes the first to process.
+ </p>
+ <p>
+ An event of type
+ <seealso marker="#type-event_type"><c>internal</c></seealso>
+ is to be used when you want to reliably distinguish
+ an event inserted this way from any external event.
+ </p>
+ </item>
+ </taglist>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="enter_action"/>
+ <desc>
+ <p>
+ These state transition actions can be invoked by
+ returning them from the
+ <seealso marker="#state callback">state callback</seealso>, from
+ <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
+ or by giving them to
+ <seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso>.
+ </p>
+ <p>
+ Actions are executed in the containing list order.
+ </p>
+ <p>
+ Actions that set
+ <seealso marker="#type-transition_option">transition options</seealso>
+ override any previous of the same type,
+ so the last in the containing list wins.
+ For example, the last
+ <seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso>
+ overrides any previous <c>event_timeout()</c> in the list.
+ </p>
+ <taglist>
<tag><c>hibernate</c></tag>
<item>
<p>
@@ -735,10 +1032,9 @@ handle_event(_, _, State, Data) ->
Short for <c>{timeout,Timeout,Timeout}</c>, that is,
the time-out message is the time-out time.
This form exists to make the
- <seealso marker="#state_function">state function</seealso>
+ <seealso marker="#state callback">state callback</seealso>
return value <c>{next_state,NextState,NewData,Timeout}</c>
allowed like for <c>gen_fsm</c>'s
- <seealso marker="gen_fsm#Module:StateName/2"><c>Module:StateName/2</c></seealso>.
</p>
</item>
<tag><c>timeout</c></tag>
@@ -747,33 +1043,32 @@ handle_event(_, _, State, Data) ->
Sets the
<seealso marker="#type-transition_option"><c>transition_option()</c></seealso>
<seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso>
- to <c><anno>Time</anno></c> with <c><anno>EventContent</anno></c>.
+ to <c><anno>Time</anno></c> with <c><anno>EventContent</anno></c>
+ and time-out options
+ <seealso marker="#type-timeout_option"><c><anno>Options</anno></c></seealso>.
</p>
</item>
- <tag><c>reply_action()</c></tag>
+ <tag><c>{timeout,<anno>Name</anno>}</c></tag>
<item>
<p>
- Replies to a caller.
+ Sets the
+ <seealso marker="#type-transition_option"><c>transition_option()</c></seealso>
+ <seealso marker="#type-generic_timeout"><c>generic_timeout()</c></seealso>
+ to <c><anno>Time</anno></c> for <c><anno>Name</anno></c>
+ with <c><anno>EventContent</anno></c>
+ and time-out options
+ <seealso marker="#type-timeout_option"><c><anno>Options</anno></c></seealso>.
</p>
- </item>
- <tag><c>next_event</c></tag>
+ </item>
+ <tag><c>state_timeout</c></tag>
<item>
<p>
- Stores the specified <c><anno>EventType</anno></c>
- and <c><anno>EventContent</anno></c> for insertion after all
- actions have been executed.
- </p>
- <p>
- The stored events are inserted in the queue as the next to process
- before any already queued events. The order of these stored events
- is preserved, so the first <c>next_event</c> in the containing
- list becomes the first to process.
- </p>
- <p>
- An event of type
- <seealso marker="#type-event_type"><c>internal</c></seealso>
- is to be used when you want to reliably distinguish
- an event inserted this way from any external event.
+ Sets the
+ <seealso marker="#type-transition_option"><c>transition_option()</c></seealso>
+ <seealso marker="#type-state_timeout"><c>state_timeout()</c></seealso>
+ to <c><anno>Time</anno></c> with <c><anno>EventContent</anno></c>
+ and time-out options
+ <seealso marker="#type-timeout_option"><c><anno>Options</anno></c></seealso>.
</p>
</item>
</taglist>
@@ -783,39 +1078,97 @@ handle_event(_, _, State, Data) ->
<name name="reply_action"/>
<desc>
<p>
- Replies to a caller waiting for a reply in
+ This state transition action can be invoked by
+ returning it from the
+ <seealso marker="#state callback">state callback</seealso>, from
+ <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
+ or by giving it to
+ <seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso>.
+ </p>
+ <p>
+ It replies to a caller waiting for a reply in
<seealso marker="#call/2"><c>call/2</c></seealso>.
<c><anno>From</anno></c> must be the term from argument
<seealso marker="#type-event_type"><c>{call,<anno>From</anno>}</c></seealso>
- to the
- <seealso marker="#state_function">state function</seealso>.
+ in a call to a
+ <seealso marker="#state callback">state callback</seealso>.
+ </p>
+ <p>
+ Note that using this action from
+ <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
+ or
+ <seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso>
+ would be weird on the border of witchcraft
+ since there has been no earlier call to a
+ <seealso marker="#state callback">state callback</seealso>
+ in this server.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="init_result"/>
+ <desc>
+ <p>
+ For a succesful initialization,
+ <c><anno>State</anno></c> is the initial
+ <seealso marker="#type-state"><c>state()</c></seealso>
+ and <c><anno>Data</anno></c> the initial server
+ <seealso marker="#type-data"><c>data()</c></seealso>
+ of the <c>gen_statem</c>.
+ </p>
+ <p>
+ The <seealso marker="#type-action"><c>Actions</c></seealso>
+ are executed when entering the first
+ <seealso marker="#type-state">state</seealso> just as for a
+ <seealso marker="#state callback">state callback</seealso>,
+ except that the action <c>postpone</c> is forced to
+ <c>false</c> since there is no event to postpone.
+ </p>
+ <p>
+ For an unsuccesful initialization,
+ <c>{stop,<anno>Reason</anno>}</c>
+ or <c>ignore</c> should be used; see
+ <seealso marker="#start_link/3"><c>start_link/3,4</c></seealso>.
</p>
</desc>
</datatype>
<datatype>
- <name name="state_function_result"/>
+ <name name="state_enter_result"/>
<desc>
+ <p>
+ <c><anno>State</anno></c> is the current state
+ and it can not be changed since the state callback
+ was called with a
+ <seealso marker="#type-state_enter"><em>state enter call</em></seealso>.
+ </p>
<taglist>
<tag><c>next_state</c></tag>
<item>
<p>
The <c>gen_statem</c> does a state transition to
- <c><anno>NextStateName</anno></c>
- (which can be the same as the current state),
+ <c><anno>State</anno></c>, which has to be
+ the current state,
sets <c><anno>NewData</anno></c>,
and executes all <c><anno>Actions</anno></c>.
</p>
</item>
</taglist>
- <p>
- All these terms are tuples or atoms and this property
- will hold in any future version of <c>gen_statem</c>.
- </p>
</desc>
</datatype>
<datatype>
- <name name="handle_event_result"/>
+ <name name="event_handler_result"/>
<desc>
+ <p>
+ <c><anno>StateType</anno></c> is
+ <seealso marker="#type-state_name"><c>state_name()</c></seealso>
+ if
+ <seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
+ is <c>state_functions</c>, or
+ <seealso marker="#type-state"><c>state()</c></seealso>
+ if
+ <seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
+ is <c>handle_event_function</c>.
+ </p>
<taglist>
<tag><c>next_state</c></tag>
<item>
@@ -828,55 +1181,91 @@ handle_event(_, _, State, Data) ->
</p>
</item>
</taglist>
- <p>
- All these terms are tuples or atoms and this property
- will hold in any future version of <c>gen_statem</c>.
- </p>
</desc>
</datatype>
<datatype>
- <name name="common_state_callback_result"/>
+ <name name="state_callback_result"/>
<desc>
+ <p>
+ <c><anno>ActionType</anno></c> is
+ <seealso marker="#type-enter_action"><c>enter_action()</c></seealso>
+ if the state callback was called with a
+ <seealso marker="#type-state_enter"><em>state enter call</em></seealso>
+ and
+ <seealso marker="#type-action"><c>action()</c></seealso>
+ if the state callback was called with an event.
+ </p>
<taglist>
- <tag><c>stop</c></tag>
+ <tag><c>keep_state</c></tag>
<item>
<p>
- Terminates the <c>gen_statem</c> by calling
- <seealso marker="#Module:terminate/3"><c>Module:terminate/3</c></seealso>
- with <c>Reason</c> and
- <c><anno>NewData</anno></c>, if specified.
+ The <c>gen_statem</c> keeps the current state, or
+ does a state transition to the current state if you like,
+ sets <c><anno>NewData</anno></c>,
+ and executes all <c><anno>Actions</anno></c>.
+ This is the same as
+ <c>{next_state,CurrentState,<anno>NewData</anno>,<anno>Actions</anno>}</c>.
</p>
</item>
- <tag><c>stop_and_reply</c></tag>
+ <tag><c>keep_state_and_data</c></tag>
<item>
<p>
- Sends all <c><anno>Replies</anno></c>,
- then terminates the <c>gen_statem</c> by calling
- <seealso marker="#Module:terminate/3"><c>Module:terminate/3</c></seealso>
- with <c>Reason</c> and
- <c><anno>NewData</anno></c>, if specified.
+ The <c>gen_statem</c> keeps the current state or
+ does a state transition to the current state if you like,
+ keeps the current server data,
+ and executes all <c><anno>Actions</anno></c>.
+ This is the same as
+ <c>{next_state,CurrentState,CurrentData,<anno>Actions</anno>}</c>.
</p>
</item>
- <tag><c>keep_state</c></tag>
+ <tag><c>repeat_state</c></tag>
<item>
<p>
The <c>gen_statem</c> keeps the current state, or
does a state transition to the current state if you like,
sets <c><anno>NewData</anno></c>,
and executes all <c><anno>Actions</anno></c>.
- This is the same as
- <c>{next_state,CurrentState,<anno>NewData</anno>,<anno>Actions</anno>}</c>.
+ If the <c>gen_statem</c> runs with
+ <seealso marker="#type-state_enter"><em>state enter calls</em></seealso>,
+ the state enter call is repeated, see type
+ <seealso marker="#type-transition_option"><c>transition_option()</c></seealso>,
+ otherwise <c>repeat_state</c> is the same as
+ <c>keep_state</c>.
</p>
</item>
- <tag><c>keep_state_and_data</c></tag>
+ <tag><c>repeat_state_and_data</c></tag>
<item>
<p>
- The <c>gen_statem</c> keeps the current state or
+ The <c>gen_statem</c> keeps the current state and data, or
does a state transition to the current state if you like,
- keeps the current server data,
and executes all <c><anno>Actions</anno></c>.
This is the same as
- <c>{next_state,CurrentState,CurrentData,<anno>Actions</anno>}</c>.
+ <c>{repeat_state,CurrentData,<anno>Actions</anno>}</c>.
+ If the <c>gen_statem</c> runs with
+ <seealso marker="#type-state_enter"><em>state enter calls</em></seealso>,
+ the state enter call is repeated, see type
+ <seealso marker="#type-transition_option"><c>transition_option()</c></seealso>,
+ otherwise <c>repeat_state_and_data</c> is the same as
+ <c>keep_state_and_data</c>.
+ </p>
+ </item>
+ <tag><c>stop</c></tag>
+ <item>
+ <p>
+ Terminates the <c>gen_statem</c> by calling
+ <seealso marker="#Module:terminate/3"><c>Module:terminate/3</c></seealso>
+ with <c>Reason</c> and
+ <c><anno>NewData</anno></c>, if specified.
+ </p>
+ </item>
+ <tag><c>stop_and_reply</c></tag>
+ <item>
+ <p>
+ Sends all <c><anno>Replies</anno></c>,
+ then terminates the <c>gen_statem</c> by calling
+ <seealso marker="#Module:terminate/3"><c>Module:terminate/3</c></seealso>
+ with <c>Reason</c> and
+ <c><anno>NewData</anno></c>, if specified.
</p>
</item>
</taglist>
@@ -900,14 +1289,14 @@ handle_event(_, _, State, Data) ->
by sending a request
and waiting until its reply arrives.
The <c>gen_statem</c> calls the
- <seealso marker="#state_function">state function</seealso> with
+ <seealso marker="#state callback">state callback</seealso> with
<seealso marker="#type-event_type"><c>event_type()</c></seealso>
<c>{call,From}</c> and event content
<c><anno>Request</anno></c>.
</p>
<p>
A <c><anno>Reply</anno></c> is generated when a
- <seealso marker="#state_function">state function</seealso>
+ <seealso marker="#state callback">state callback</seealso>
returns with
<c>{reply,From,<anno>Reply</anno>}</c> as one
<seealso marker="#type-action"><c>action()</c></seealso>,
@@ -923,17 +1312,40 @@ handle_event(_, _, State, Data) ->
</p>
<note>
<p>
- To avoid getting a late reply in the caller's
- inbox, this function spawns a proxy process that
+ For <c><anno>Timeout</anno> &lt; infinity</c>,
+ to avoid getting a late reply in the caller's
+ inbox if the caller should catch exceptions,
+ this function spawns a proxy process that
does the call. A late reply gets delivered to the
dead proxy process, hence gets discarded. This is
less efficient than using
- <c><anno>Timeout</anno> =:= infinity</c>.
+ <c><anno>Timeout</anno> == infinity</c>.
+ </p>
+ </note>
+ <p>
+ <c><anno>Timeout</anno></c> can also be a tuple
+ <c>{clean_timeout,<anno>T</anno>}</c> or
+ <c>{dirty_timeout,<anno>T</anno>}</c>, where
+ <c><anno>T</anno></c> is the time-out time.
+ <c>{clean_timeout,<anno>T</anno>}</c> works like
+ just <c>T</c> described in the note above
+ and uses a proxy process for <c>T &lt; infinity</c>,
+ while <c>{dirty_timeout,<anno>T</anno>}</c>
+ bypasses the proxy process which is more lightweight.
+ </p>
+ <note>
+ <p>
+ If you combine catching exceptions from this function
+ with <c>{dirty_timeout,<anno>T</anno>}</c>
+ to avoid that the calling process dies when the call
+ times out, you will have to be prepared to handle
+ a late reply.
+ So why not just let the calling process die?
</p>
</note>
<p>
- The call can fail, for example, if the <c>gen_statem</c> dies
- before or during this function call.
+ The call can also fail, for example, if the <c>gen_statem</c>
+ dies before or during this function call.
</p>
</desc>
</func>
@@ -949,7 +1361,7 @@ handle_event(_, _, State, Data) ->
ignoring if the destination node or <c>gen_statem</c>
does not exist.
The <c>gen_statem</c> calls the
- <seealso marker="#state_function">state function</seealso> with
+ <seealso marker="#state callback">state callback</seealso> with
<seealso marker="#type-event_type"><c>event_type()</c></seealso>
<c>cast</c> and event content
<c><anno>Msg</anno></c>.
@@ -958,35 +1370,36 @@ handle_event(_, _, State, Data) ->
</func>
<func>
- <name name="enter_loop" arity="5"/>
+ <name name="enter_loop" arity="4"/>
<fsummary>Enter the <c>gen_statem</c> receive loop.</fsummary>
<desc>
<p>
The same as
- <seealso marker="#enter_loop/7"><c>enter_loop/7</c></seealso>
- except that no
+ <seealso marker="#enter_loop/6"><c>enter_loop/6</c></seealso>
+ with <c>Actions = []</c> except that no
<seealso marker="#type-server_name"><c>server_name()</c></seealso>
- must have been registered.
+ must have been registered. This creates an anonymous server.
</p>
</desc>
</func>
<func>
- <name name="enter_loop" arity="6"/>
+ <name name="enter_loop" arity="5"/>
<fsummary>Enter the <c>gen_statem</c> receive loop.</fsummary>
<desc>
<p>
If <c><anno>Server_or_Actions</anno></c> is a <c>list()</c>,
the same as
- <seealso marker="#enter_loop/7"><c>enter_loop/7</c></seealso>
+ <seealso marker="#enter_loop/6"><c>enter_loop/6</c></seealso>
except that no
<seealso marker="#type-server_name"><c>server_name()</c></seealso>
must have been registered and
<c>Actions = <anno>Server_or_Actions</anno></c>.
+ This creates an anonymous server.
</p>
<p>
Otherwise the same as
- <seealso marker="#enter_loop/7"><c>enter_loop/7</c></seealso>
+ <seealso marker="#enter_loop/6"><c>enter_loop/6</c></seealso>
with
<c>Server = <anno>Server_or_Actions</anno></c> and
<c>Actions = []</c>.
@@ -995,7 +1408,7 @@ handle_event(_, _, State, Data) ->
</func>
<func>
- <name name="enter_loop" arity="7"/>
+ <name name="enter_loop" arity="6"/>
<fsummary>Enter the <c>gen_statem</c> receive loop.</fsummary>
<desc>
<p>
@@ -1015,21 +1428,31 @@ handle_event(_, _, State, Data) ->
the <c>gen_statem</c> behavior provides.
</p>
<p>
- <c><anno>Module</anno></c>, <c><anno>Opts</anno></c>, and
- <c><anno>Server</anno></c> have the same meanings
- as when calling
+ <c><anno>Module</anno></c>, <c><anno>Opts</anno></c>
+ have the same meaning as when calling
<seealso marker="#start_link/3"><c>start[_link]/3,4</c></seealso>.
+ </p>
+ <p>
+ If <c><anno>Server</anno></c> is <c>self()</c> an anonymous
+ server is created just as when using
+ <seealso marker="#start_link/3"><c>start[_link]/3</c></seealso>.
+ If <c><anno>Server</anno></c> is a
+ <seealso marker="#type-server_name"><c>server_name()</c></seealso>
+ a named server is created just as when using
+ <seealso marker="#start_link/4"><c>start[_link]/4</c></seealso>.
However, the
<seealso marker="#type-server_name"><c>server_name()</c></seealso>
name must have been registered accordingly
- <em>before</em> this function is called.</p>
+ <em>before</em> this function is called.
+ </p>
<p>
- <c><anno>CallbackMode</anno></c>, <c><anno>State</anno></c>,
- <c><anno>Data</anno></c>, and <c><anno>Actions</anno></c>
+ <c><anno>State</anno></c>, <c><anno>Data</anno></c>,
+ and <c><anno>Actions</anno></c>
have the same meanings as in the return value of
<seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>.
- Also, the callback module <c><anno>Module</anno></c>
- does not need to export an <c>init/1</c> function.
+ Also, the callback module does not need to export a
+ <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
+ function.
</p>
<p>
The function fails if the calling process was not started by a
@@ -1052,17 +1475,18 @@ handle_event(_, _, State, Data) ->
<seealso marker="#call/2"><c>call/2</c></seealso>
when the reply cannot be defined in
the return value of a
- <seealso marker="#state_function">state function</seealso>.
+ <seealso marker="#state callback">state callback</seealso>.
</p>
<p>
<c><anno>From</anno></c> must be the term from argument
<seealso marker="#type-event_type"><c>{call,<anno>From</anno>}</c></seealso>
to the
- <seealso marker="#state_function">state function</seealso>.
- <c><anno>From</anno></c> and <c><anno>Reply</anno></c>
- can also be specified using a
- <seealso marker="#type-reply_action"><c>reply_action()</c></seealso>
- and multiple replies with a list of them.
+ <seealso marker="#state callback">state callback</seealso>.
+ A reply or multiple replies canalso be sent
+ using one or several
+ <seealso marker="#type-reply_action"><c>reply_action()</c></seealso>s
+ from a
+ <seealso marker="#state callback">state callback</seealso>.
</p>
<note>
<p>
@@ -1142,6 +1566,13 @@ handle_event(_, _, State, Data) ->
</p>
</item>
<item>
+ <p>If option<seealso marker="#type-hibernate_after_opt"><c>{hibernate_after,HibernateAfterTimeout}</c></seealso> is present, the <c>gen_statem</c>
+ process awaits any message for <c>HibernateAfterTimeout</c> milliseconds and
+ if no message is received, the process goes into hibernation automatically
+ (by calling <seealso marker="proc_lib#hibernate/3"><c>proc_lib:hibernate/3</c></seealso>).
+ </p>
+ </item>
+ <item>
<p>
If option
<seealso marker="#type-debug_opt"><c>{debug,Dbgs}</c></seealso>
@@ -1253,6 +1684,57 @@ handle_event(_, _, State, Data) ->
<funcs>
<func>
+ <name>Module:callback_mode() -> CallbackMode</name>
+ <fsummary>Update the internal state during upgrade/downgrade.</fsummary>
+ <type>
+ <v>
+ CallbackMode =
+ <seealso marker="#type-callback_mode">callback_mode()</seealso> |
+ [ <seealso marker="#type-callback_mode">callback_mode()</seealso>
+ | <seealso marker="#type-state_enter">state_enter()</seealso> ]
+ </v>
+ </type>
+ <desc>
+ <p>
+ This function is called by a <c>gen_statem</c>
+ when it needs to find out the
+ <seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
+ of the callback module. The value is cached by <c>gen_statem</c>
+ for efficiency reasons, so this function is only called
+ once after server start and after code change,
+ but before the first
+ <seealso marker="#state callback">state callback</seealso>
+ in the current code version is called.
+ More occasions may be added in future versions
+ of <c>gen_statem</c>.
+ </p>
+ <p>
+ Server start happens either when
+ <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso>
+ returns or when
+ <seealso marker="#enter_loop/4"><c>enter_loop/4-6</c></seealso>
+ is called. Code change happens when
+ <seealso marker="#Module:code_change/4"><c>Module:code_change/4</c></seealso>
+ returns.
+ </p>
+ <p>
+ The <c>CallbackMode</c> is either just
+ <seealso marker="#type-callback_mode"><c>callback_mode()</c></seealso>
+ or a list containing
+ <seealso marker="#type-callback_mode"><c>callback_mode()</c></seealso>
+ and possibly the atom
+ <seealso marker="#type-state_enter"><c>state_enter</c></seealso>.
+ </p>
+ <note>
+ <p>
+ If this function's body does not return an inline constant
+ value the callback module is doing something strange.
+ </p>
+ </note>
+ </desc>
+ </func>
+
+ <func>
<name>Module:code_change(OldVsn, OldState, OldData, Extra) ->
Result
</name>
@@ -1262,11 +1744,7 @@ handle_event(_, _, State, Data) ->
<v>&nbsp;&nbsp;Vsn = term()</v>
<v>OldState = NewState = term()</v>
<v>Extra = term()</v>
- <v>Result = {NewCallbackMode,NewState,NewData} | Reason</v>
- <v>
- NewCallbackMode =
- <seealso marker="#type-callback_mode">callback_mode()</seealso>
- </v>
+ <v>Result = {ok,NewState,NewData} | Reason</v>
<v>
OldState = NewState =
<seealso marker="#type-state">state()</seealso>
@@ -1278,6 +1756,16 @@ handle_event(_, _, State, Data) ->
<v>Reason = term()</v>
</type>
<desc>
+ <note>
+ <p>
+ This callback is optional, so callback modules need not export it.
+ If a release upgrade/downgrade with
+ <c>Change={advanced,Extra}</c>
+ specified in the <c>.appup</c> file is made
+ when <c>code_change/4</c> is not implemented
+ the process will crash with exit reason <c>undef</c>.
+ </p>
+ </note>
<p>
This function is called by a <c>gen_statem</c> when it is to
update its internal state during a release upgrade/downgrade,
@@ -1295,21 +1783,6 @@ handle_event(_, _, State, Data) ->
<c>Module</c>. If no such attribute is defined, the version
is the checksum of the Beam file.
</p>
- <note>
- <p>
- If you would dare to change
- <seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
- during release upgrade/downgrade, the upgrade is no problem,
- as the new code surely knows what <em>callback mode</em>
- it needs. However, for a downgrade this function must
- know from argument <c>Extra</c> that comes from the
- <seealso marker="sasl:appup"><c>sasl:appup</c></seealso>
- file what <em>callback mode</em> the old code did use.
- It can also be possible to figure this out
- from argument <c>{down,Vsn}</c>, as <c>Vsn</c>
- in effect defines the old callback module version.
- </p>
- </note>
<p>
<c>OldState</c> and <c>OldData</c> is the internal state
of the <c>gen_statem</c>.
@@ -1321,41 +1794,46 @@ handle_event(_, _, State, Data) ->
<p>
If successful, the function must return the updated
internal state in an
- <c>{NewCallbackMode,NewState,NewData}</c> tuple.
- </p>
- <p>
- If the function returns <c>Reason</c>, the ongoing
- upgrade fails and rolls back to the old release.</p>
- <p>
- This function can use
- <seealso marker="erts:erlang#throw/1"><c>erlang:throw/1</c></seealso>
- to return <c>Result</c> or <c>Reason</c>.
+ <c>{ok,NewState,NewData}</c> tuple.
+ </p>
+ <p>
+ If the function returns a failure <c>Reason</c>, the ongoing
+ upgrade fails and rolls back to the old release.
+ Note that <c>Reason</c> can not be an <c>{ok,_,_}</c> tuple
+ since that will be regarded as a
+ <c>{ok,NewState,NewData}</c> tuple,
+ and that a tuple matching <c>{ok,_}</c>
+ is an also invalid failure <c>Reason</c>.
+ It is recommended to use an atom as <c>Reason</c> since
+ it will be wrapped in an <c>{error,Reason}</c> tuple.
+ </p>
+ <p>
+ Also note when upgrading a <c>gen_statem</c>,
+ this function and hence
+ the <c>Change={advanced,Extra}</c> parameter in the
+ <seealso marker="sasl:appup"><c>appup</c></seealso> file
+ is not only needed to update the internal state
+ or to act on the <c>Extra</c> argument.
+ It is also needed if an upgrade or downgrade should change
+ <seealso marker="#type-callback_mode"><em>callback mode</em></seealso>,
+ or else the callback mode after the code change
+ will not be honoured,
+ most probably causing a server crash.
</p>
</desc>
</func>
<func>
- <name>Module:init(Args) -> Result</name>
- <fsummary>Initialize process and internal state.</fsummary>
+ <name>Module:init(Args) -> Result(StateType)</name>
+ <fsummary>
+ Initializing process and internal state.
+ </fsummary>
<type>
<v>Args = term()</v>
- <v>Result = {CallbackMode,State,Data}</v>
- <v>&nbsp;| {CallbackMode,State,Data,Actions}</v>
- <v>&nbsp;| {stop,Reason} | ignore</v>
<v>
- CallbackMode =
- <seealso marker="#type-callback_mode">callback_mode()</seealso>
+ Result(StateType) =
+ <seealso marker="#type-init_result">init_result(StateType)</seealso>
</v>
- <v>State = <seealso marker="#type-state">state()</seealso></v>
- <v>
- Data = <seealso marker="#type-data">data()</seealso>
- </v>
- <v>
- Actions =
- [<seealso marker="#type-action">action()</seealso>] |
- <seealso marker="#type-action">action()</seealso>
- </v>
- <v>Reason = term()</v>
</type>
<desc>
<marker id="Module:init-1"/>
@@ -1368,38 +1846,22 @@ handle_event(_, _, State, Data) ->
the implementation state and server data.
</p>
<p>
- <c>Args</c> is the <c>Args</c> argument provided to the start
+ <c>Args</c> is the <c>Args</c> argument provided to that start
function.
</p>
- <p>
- If the initialization is successful, the function is to
- return <c>{CallbackMode,State,Data}</c> or
- <c>{CallbackMode,State,Data,Actions}</c>.
- <c>CallbackMode</c> selects the
- <seealso marker="#type-callback_mode"><em>callback mode</em></seealso>
- of the <c>gen_statem</c>.
- <c>State</c> is the initial
- <seealso marker="#type-state"><c>state()</c></seealso>
- and <c>Data</c> the initial server
- <seealso marker="#type-data"><c>data()</c></seealso>.
- </p>
- <p>
- The <seealso marker="#type-action"><c>Actions</c></seealso>
- are executed when entering the first
- <seealso marker="#type-state">state</seealso> just as for a
- <seealso marker="#state_function">state function</seealso>.
- </p>
- <p>
- If the initialization fails,
- the function is to return <c>{stop,Reason}</c>
- or <c>ignore</c>; see
- <seealso marker="#start_link/3"><c>start_link/3,4</c></seealso>.
- </p>
- <p>
- This function can use
- <seealso marker="erts:erlang#throw/1"><c>erlang:throw/1</c></seealso>
- to return <c>Result</c>.
- </p>
+ <note>
+ <p>
+ Note that if the <c>gen_statem</c> is started trough
+ <seealso marker="proc_lib"><c>proc_lib</c></seealso>
+ and
+ <seealso marker="#enter_loop/4"><c>enter_loop/4-6</c></seealso>,
+ this callback will never be called.
+ Since this callback is not optional it can
+ in that case be implemented as:
+ </p>
+ <pre>
+init(Args) -> erlang:error(not_implemented, [Args]).</pre>
+ </note>
</desc>
</func>
@@ -1430,10 +1892,14 @@ handle_event(_, _, State, Data) ->
This callback is optional, so a callback module does not need
to export it. The <c>gen_statem</c> module provides a default
implementation of this function that returns
- <c>{State,Data}</c>. If this callback fails, the default
- function returns <c>{State,Info}</c>,
- where <c>Info</c> informs of the crash but no details,
- to hide possibly sensitive data.
+ <c>{State,Data}</c>.
+ </p>
+ <p>
+ If this callback is exported but fails,
+ to hide possibly sensitive data,
+ the default function will instead return <c>{State,Info}</c>,
+ where <c>Info</c> says nothing but the fact that
+ <c>format_status/2</c> has crashed.
</p>
</note>
<p>This function is called by a <c>gen_statem</c> process when
@@ -1474,7 +1940,8 @@ handle_event(_, _, State, Data) ->
</p>
<p>
The function is to return <c>Status</c>, a term that
- changes the details of the current state and status of
+ contains the appropriate details
+ of the current state and status of
the <c>gen_statem</c>. There are no restrictions on the
form <c>Status</c> can take, but for the
<seealso marker="sys#get_status/1"><c>sys:get_status/1,2</c></seealso>
@@ -1494,20 +1961,21 @@ handle_event(_, _, State, Data) ->
printed in log files. Another use is to hide sensitive data from
being written to the error log.
</p>
- <p>
- This function can use
- <seealso marker="erts:erlang#throw/1"><c>erlang:throw/1</c></seealso>
- to return <c>Status</c>.
- </p>
</desc>
</func>
<func>
+ <name>Module:StateName(enter, OldState, Data) ->
+ StateEnterResult(StateName)
+ </name>
<name>Module:StateName(EventType, EventContent, Data) ->
StateFunctionResult
</name>
- <name>Module:handle_event(EventType, EventContent,
- State, Data) -> HandleEventResult
+ <name>Module:handle_event(enter, OldState, State, Data) ->
+ StateEnterResult(State)
+ </name>
+ <name>Module:handle_event(EventType, EventContent, State, Data) ->
+ HandleEventResult
</name>
<fsummary>Handle an event.</fsummary>
<type>
@@ -1525,12 +1993,20 @@ handle_event(_, _, State, Data) ->
<seealso marker="#type-data">data()</seealso>
</v>
<v>
+ StateEnterResult(StateName) =
+ <seealso marker="#type-state_enter_result">state_enter_result(StateName)</seealso>
+ </v>
+ <v>
StateFunctionResult =
- <seealso marker="#type-state_function_result">state_function_result()</seealso>
+ <seealso marker="#type-event_handler_result">event_handler_result</seealso>(<seealso marker="#type-state_name">state_name()</seealso>)
+ </v>
+ <v>
+ StateEnterResult(State) =
+ <seealso marker="#type-state_enter_result">state_enter_result(State)</seealso>
</v>
<v>
HandleEventResult =
- <seealso marker="#type-handle_event_result">handle_event_result()</seealso>
+ <seealso marker="#type-event_handler_result">event_handler_result</seealso>(<seealso marker="#type-state">state()</seealso>)
</v>
</type>
<desc>
@@ -1549,7 +2025,7 @@ handle_event(_, _, State, Data) ->
<seealso marker="#type-event_type"><c>{call,From}</c></seealso>,
the caller waits for a reply. The reply can be sent
from this or from any other
- <seealso marker="#state_function">state function</seealso>
+ <seealso marker="#state callback">state callback</seealso>
by returning with <c>{reply,From,Reply}</c> in
<seealso marker="#type-action"><c>Actions</c></seealso>, in
<seealso marker="#type-reply_action"><c>Replies</c></seealso>,
@@ -1573,9 +2049,41 @@ handle_event(_, _, State, Data) ->
see <seealso marker="#type-action"><c>action()</c></seealso>.
</p>
<p>
- These functions can use
- <seealso marker="erts:erlang#throw/1"><c>erlang:throw/1</c></seealso>,
- to return the result.
+ When the <c>gen_statem</c> runs with
+ <seealso marker="#type-state_enter">state enter calls</seealso>,
+ these functions are also called with arguments
+ <c>(enter, OldState, ...)</c> whenever the state changes.
+ In this case there are some restrictions on the
+ <seealso marker="#type-enter_action">actions</seealso>
+ that may be returned:
+ <seealso marker="#type-postpone"><c>postpone()</c></seealso>
+ is not allowed since a <em>state enter call</em> is not
+ an event so there is no event to postpone, and
+ <seealso marker="#type-action"><c>{next_event,_,_}</c></seealso>
+ is not allowed since using <em>state enter calls</em>
+ should not affect how events are consumed and produced.
+ You may also not change states from this call.
+ Should you return <c>{next_state,NextState, ...}</c>
+ with <c>NextState =/= State</c> the <c>gen_statem</c> crashes.
+ It is possible to use <c>{repeat_state, ...}</c>,
+ <c>{repeat_state_and_data,_}</c> or
+ <c>repeat_state_and_data</c> but all of them makes little
+ sense since you immediately will be called again with a new
+ <em>state enter call</em> making this just a weird way
+ of looping, and there are better ways to loop in Erlang.
+ You are advised to use <c>{keep_state,...}</c>,
+ <c>{keep_state_and_data,_}</c> or
+ <c>keep_state_and_data</c> since you can not change states
+ from a <em>state enter call</em> anyway.
+ </p>
+ <p>
+ Note the fact that you can use
+ <seealso marker="erts:erlang#throw/1"><c>throw</c></seealso>
+ to return the result, which can be useful.
+ For example to bail out with <c>throw(keep_state_and_data)</c>
+ from deep within complex code that can not
+ return <c>{next_state,State,Data}</c> because
+ <c>State</c> or <c>Data</c> is no longer in scope.
</p>
</desc>
</func>
@@ -1590,6 +2098,11 @@ handle_event(_, _, State, Data) ->
<v>Ignored = term()</v>
</type>
<desc>
+ <note>
+ <p>This callback is optional, so callback modules need not
+ export it. The <c>gen_statem</c> module provides a default
+ implementation without cleanup.</p>
+ </note>
<p>
This function is called by a <c>gen_statem</c>
when it is about to terminate. It is to be the opposite of
@@ -1648,11 +2161,6 @@ handle_event(_, _, State, Data) ->
and an error report is issued using
<seealso marker="kernel:error_logger#format/2"><c>error_logger:format/2</c></seealso>.
</p>
- <p>
- This function can use
- <seealso marker="erts:erlang#throw/1"><c>erlang:throw/1</c></seealso>
- to return <c>Ignored</c>, which is ignored anyway.
- </p>
</desc>
</func>
</funcs>
diff --git a/lib/stdlib/doc/src/introduction.xml b/lib/stdlib/doc/src/introduction.xml
index 5bf545c65f..642ca02430 100644
--- a/lib/stdlib/doc/src/introduction.xml
+++ b/lib/stdlib/doc/src/introduction.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1999</year>
- <year>2013</year>
+ <year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/stdlib/doc/src/io.xml b/lib/stdlib/doc/src/io.xml
index 11a64c7f8a..64fcf4379f 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>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -265,6 +265,8 @@ ok
<p>Writes data with the standard syntax. This is used to
output Erlang terms. Atoms are printed within quotes if
they contain embedded non-printable characters.
+ Atom characters &gt; 255 are escaped unless the
+ Unicode translation modifier (<c>t</c>) is used.
Floats are printed accurately as the shortest, correctly
rounded string.</p>
</item>
@@ -567,8 +569,6 @@ Prompt> <input>&lt;Characters beyond latin1 range not printable in this medium&g
<item>
<p>Similar to <c>s</c>, but the resulting string is
converted into an atom.</p>
- <p>The Unicode translation modifier is not allowed (atoms
- cannot contain characters beyond the <c>latin1</c> range).</p>
</item>
<tag><c>c</c></tag>
<item>
diff --git a/lib/stdlib/doc/src/io_lib.xml b/lib/stdlib/doc/src/io_lib.xml
index 931e50f6f2..bc1d77ac83 100644
--- a/lib/stdlib/doc/src/io_lib.xml
+++ b/lib/stdlib/doc/src/io_lib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -147,7 +147,7 @@
format string (that is, <c>~ts</c> or <c>~tc</c>), the resulting list
can contain characters beyond the ISO Latin-1 character range
(that is, numbers &gt; 255). If so, the
- result is not an ordinary Erlang <c>string()</c>, but can well be
+ result is still an ordinary Erlang <c>string()</c>, and can well be
used in any context where Unicode data is allowed.</p>
</desc>
</func>
@@ -356,7 +356,8 @@
<func>
<name name="write" arity="1"/>
- <name name="write" arity="2"/>
+ <name name="write" arity="2" clause_i="1"/>
+ <name name="write" arity="2" clause_i="2"/>
<fsummary>Write a term.</fsummary>
<desc>
<p>Returns a character list that represents <c><anno>Term</anno></c>.
@@ -384,6 +385,16 @@
</func>
<func>
+ <name name="write_atom_as_latin1" arity="1"/>
+ <fsummary>Write an atom.</fsummary>
+ <desc>
+ <p>Returns the list of characters needed to print atom
+ <c><anno>Atom</anno></c>. Non-Latin-1 characters
+ are escaped.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="write_char" arity="1"/>
<fsummary>Write a character.</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/maps.xml b/lib/stdlib/doc/src/maps.xml
index e1edbadcd3..8c7270816b 100644
--- a/lib/stdlib/doc/src/maps.xml
+++ b/lib/stdlib/doc/src/maps.xml
@@ -160,7 +160,7 @@ val1
<p><em>Example:</em></p>
<code type="none">
> Map = #{"42" => value}.
-#{"42"> => value}
+#{"42" => value}
> maps:is_key("42",Map).
true
> maps:is_key(value,Map).
diff --git a/lib/stdlib/doc/src/math.xml b/lib/stdlib/doc/src/math.xml
index 1358ce5cbf..b4f096217a 100644
--- a/lib/stdlib/doc/src/math.xml
+++ b/lib/stdlib/doc/src/math.xml
@@ -57,9 +57,12 @@
<name name="atan" arity="1"/>
<name name="atan2" arity="2"/>
<name name="atanh" arity="1"/>
+ <name name="ceil" arity="1"/>
<name name="cos" arity="1"/>
<name name="cosh" arity="1"/>
<name name="exp" arity="1"/>
+ <name name="floor" arity="1"/>
+ <name name="fmod" arity="2"/>
<name name="log" arity="1"/>
<name name="log10" arity="1"/>
<name name="log2" arity="1"/>
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index ad2599c5a0..46454e9b80 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,665 @@
</header>
<p>This document describes the changes made to the STDLIB application.</p>
+<section><title>STDLIB 3.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>For many releases, it has been legal to override a BIF
+ with a local function having the same name. However,
+ calling a local function with the same name as guard BIF
+ as filter in a list comprehension was not allowed.</p>
+ <p>
+ Own Id: OTP-13690</p>
+ </item>
+ <item>
+ <p> A new (default) pseudo-random number generator
+ algorithm Xoroshiro116+ has been implemented in the
+ <c>rand</c> module. </p><p> The old algorithm
+ implementations had a number of flaws so they are all
+ deprecated, but corrected versions of two of them have
+ been added. See the documentation. </p>
+ <p>
+ Own Id: OTP-14295 Aux Id: PR-1372 </p>
+ </item>
+ <item>
+ <p> The Erlang shell, <c>qlc:string_to_handle()</c>, and
+ the Debugger (the Evaluator area and Edit variable window
+ of the Bindings area) can parse pids, ports, references,
+ and external funs, as long as they can be created in the
+ running system. </p>
+ <p>
+ Own Id: OTP-14296</p>
+ </item>
+ <item>
+ <p>Internal code change: Calls to <c>catch</c> followed
+ by a call to <c>erlang:get_stacktrace/0</c> has been
+ rewritten to use <c>try</c> instead of <c>catch</c> to
+ make the code future-proof.</p>
+ <p>
+ Own Id: OTP-14400</p>
+ </item>
+ <item>
+ <p> The <c>ms_transform</c> module, used by
+ <c>ets:fun2ms/1</c> and <c>dbg:fun2ms/1</c>, evaluates
+ constant arithmetic expressions. This is necessary since
+ the Erlang compiler, which normally evaluates constant
+ expressions, does not recognize the format generated by
+ <c>ms_transform</c>. </p>
+ <p>
+ Own Id: OTP-14454 Aux Id: ERIERL-29 </p>
+ </item>
+ <item>
+ <p> The state machine engine <c>gen_statem</c> can now
+ handle generic time-outs (multiple named) as well as
+ absolute time-out time. See the documentation. </p><p>
+ The <c>gen_statem</c> callback <c>Module:init/1</c> has
+ become mandatory to harmonize with other <c>gen_*</c>
+ modules. This may be an incompatibility for
+ <c>gen_statem</c> callback modules that use
+ <c>gen_statem:enter_loop/4-6</c>. </p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14531</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improved unicode support for strings. Added normalization
+ functions in the <c>unicode</c> module. Extended the
+ <c>string</c> module API with new functions with improved
+ unicode handling and that works on grapheme clusters. The
+ new functions operates on the <c>unicode:chardata()</c>
+ type, thus they also accept <c>UTF-8 binaries</c> as
+ input. </p>
+ <p>
+ The old string API have been marked as obsolete. The
+ return values have been changed for some error cases.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-10289 Aux Id: OTP-10309 </p>
+ </item>
+ <item>
+ <p>There are two new guard BIFs '<c>floor/1</c>' and
+ '<c>ceil/1</c>'. They both return integers. In the
+ '<c>math</c>' module, there are two new BIFs with the
+ same names that return floating point values.</p>
+ <p>
+ Own Id: OTP-13692</p>
+ </item>
+ <item>
+ <p>
+ Making code_change, terminate and handle_info callbacks
+ optional in the OTP behaviours.</p>
+ <p>
+ Own Id: OTP-13801</p>
+ </item>
+ <item>
+ <p> The support for Dets files created with Erlang/OTP R7
+ and earlier is removed. </p>
+ <p>
+ Own Id: OTP-13830</p>
+ </item>
+ <item>
+ <p>Replaced usage of deprecated symbolic <seealso
+ marker="erts:erlang#type-time_unit"><c>time
+ unit</c></seealso> representations.</p>
+ <p>
+ Own Id: OTP-13831 Aux Id: OTP-13735 </p>
+ </item>
+ <item>
+ <p>The function <c>fmod/2</c> has been added to the
+ <c>math</c> module.</p>
+ <p>
+ Own Id: OTP-14000</p>
+ </item>
+ <item>
+ <p>The EXIT signals received from processes using
+ <c>proc_lib</c> now looks like EXIT signals from
+ processes that were spawned using <c>spawn_link</c>. In
+ particular, that means that the stack trace is now
+ included in the EXIT signal so that it can see where the
+ process crashed.</p>
+ <p>
+ Own Id: OTP-14001</p>
+ </item>
+ <item>
+ <p><c>sets:add_element/2</c> is faster when adding an
+ element that is already present, and
+ <c>sets:del_element/2</c> is faster when the element to
+ be deleted is not present. This optimization can make
+ certain operations, such as sets:union/2 with many
+ overlapping elements, up to two orders of magnitude
+ faster.</p>
+ <p>
+ Own Id: OTP-14035</p>
+ </item>
+ <item>
+ <p>
+ Add information in doc about supervisor shutdown reason
+ when maximum restart frequency is reached.</p>
+ <p>
+ Own Id: OTP-14037 Aux Id: PR-1233 </p>
+ </item>
+ <item>
+ <p>
+ Added <c>rand:jump/[0|1]</c> functions.</p>
+ <p>
+ Own Id: OTP-14038 Aux Id: PR-1235 </p>
+ </item>
+ <item>
+ <p>Functions for detecting changed code has been added.
+ <c>code:modified_modules/0</c> returns all currently
+ loaded modules that have changed on disk.
+ <c>code:module_status/1</c> returns the status for a
+ module. In the shell and in <c>c</c> module, <c>mm/0</c>
+ is short for <c>code:modified_modules/0</c>, and
+ <c>lm/0</c> reloads all currently loaded modules that
+ have changed on disk.</p>
+ <p>
+ Own Id: OTP-14059</p>
+ </item>
+ <item>
+ <p>Each assert macro in <c>assert.hrl</c> now has a
+ corresponding version with an extra argument, for adding
+ comments to assertions. These can for example be printed
+ as part of error reports, to clarify the meaning of the
+ check that failed.</p>
+ <p>
+ Own Id: OTP-14066</p>
+ </item>
+ <item>
+ <p><c>error_logger_tty_h</c> and
+ <c>error_logger_file_h</c> now inserts the node
+ information for nonlocal messages before the message
+ itself instead of after, both for readability and so as
+ not to change the line termination property at the end of
+ the message.</p>
+ <p>
+ Own Id: OTP-14068</p>
+ </item>
+ <item>
+ <p>The Erlang code linter checks for badly formed type
+ constraints. </p>
+ <p>
+ Own Id: OTP-14070 Aux Id: PR-1214 </p>
+ </item>
+ <item>
+ <p>By default, there will now be a warning when
+ <c>export_all</c> is used. The warning can be disabled
+ using <c>nowarn_export_all</c>.</p>
+ <p>
+ Own Id: OTP-14071</p>
+ </item>
+ <item>
+ <p>When a <c>gen_server</c> process crashes, the
+ stacktrace for the client will be printed to facilitate
+ debugging.</p>
+ <p>
+ Own Id: OTP-14089</p>
+ </item>
+ <item>
+ <p>Optimized ETS operations by changing table identifier
+ type from integer to reference. The reference enables a
+ more direct mapping to the table with less potential lock
+ contention and makes especially creation and deletion of
+ tables scale much better.</p> <p>The change of the opaque
+ type for the ETS table identifiers may cause failure in
+ code that make faulty assumptions about this opaque
+ type.</p> <note> <p> The number of tables stored at one
+ Erlang node <em>used</em> to be limited. This is no
+ longer the case (except by memory usage). The previous
+ default limit was about 1400 tables and could be
+ increased by setting the environment variable
+ <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang
+ runtime system. This hard limit has been removed, but it
+ is currently useful to set the <c>ERL_MAX_ETS_TABLES</c>
+ anyway. It should be set to an approximate of the maximum
+ amount of tables used. This since an internal table for
+ named tables is sized using this value. If large amounts
+ of named tables are used and <c>ERL_MAX_ETS_TABLES</c>
+ hasn't been increased, the performance of named table
+ lookup will degrade. </p> </note>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14094</p>
+ </item>
+ <item>
+ <p><c>take/2</c> has been added to <c>dict</c>,
+ <c>orddict</c>, and <c>gb_trees</c>. <c>take_any/2</c>
+ has been added to <c>gb_trees</c>.</p>
+ <p>
+ Own Id: OTP-14102</p>
+ </item>
+ <item>
+ <p>
+ Extend gen_event API to handle options as well.</p>
+ <p>
+ Own Id: OTP-14123</p>
+ </item>
+ <item>
+ <p>
+ Advice on how to tune the supervisor restart frequency
+ (intensity and period) is added to System Documentation -
+ Design Principles - Supervisor Behaviour.</p>
+ <p>
+ Own Id: OTP-14168 Aux Id: PR-1289 </p>
+ </item>
+ <item>
+ <p>
+ gen_fsm is deprecated and is replaced by gen_statem,
+ however for backwards compatibility reasons gen_fsm may
+ continue to exist as an undocumented feature for quite
+ some time.</p>
+ <p>
+ Own Id: OTP-14183</p>
+ </item>
+ <item>
+ <p>The shell functions <c>c/1</c> and <c>c/2</c> have
+ been extended so that if the argument is a module name
+ instead of a file name, it automatically locates the
+ .beam file and the corresponding source file, and then
+ recompiles the module using the same compiler options
+ (plus any options passed to c/2). If compilation fails,
+ the old beam file is preserved. Also adds <c>c(Mod, Opts,
+ Filter)</c>, where the Filter argument allows you to
+ remove old compiler options before the new options are
+ added.</p> <p>New utility functions <c>file_find/2/3</c>
+ and <c>find_source/1/2/3</c> have been added to
+ <c>filelib</c>.</p>
+ <p>
+ Own Id: OTP-14190</p>
+ </item>
+ <item>
+ <p><c>erl_tar</c> in previous versions of OTP only
+ supports the USTAR format. That limited path names to at
+ most 255 bytes, and did not support Unicode characters in
+ names in a portable way.</p>
+ <p><c>erl_tar</c> now has support for reading tar
+ archives in the formats currently in common use, such as
+ v7, STAR, USTAR, PAX, and GNU tar's extensions to the
+ STAR/USTAR format. When writing tar archives,
+ <c>erl_tar</c> can now write them in the <c>PAX</c>
+ format if necessary (for example, to support very long
+ filenames or filenames with Unicode characters). If
+ possible, <c>erl_tar</c> will still write tar archives in
+ the USTAR for maximum portability.</p>
+ <p>
+ Own Id: OTP-14226</p>
+ </item>
+ <item>
+ <p><c>base64:mime_decode/1</c> has been optimized so that
+ it is now almost as fast as<c>base64:decode/1</c>; it
+ used be noticeably slower.</p>
+ <p>
+ Own Id: OTP-14245</p>
+ </item>
+ <item>
+ <p><c>erl_tar</c> will now strip any leading '<c>/</c>'
+ from pathnames when extracting files from a tar archive
+ and write a message to the error logger. There is also
+ new check for directory traversal attacks; if a relative
+ path points above the current working directory the
+ extraction will be aborted.</p>
+ <p>
+ Own Id: OTP-14278</p>
+ </item>
+ <item>
+ <p> Miscellaneous updates due to atoms containing
+ arbitrary Unicode characters. </p>
+ <p>
+ Own Id: OTP-14285</p>
+ </item>
+ <item>
+ <p>
+ The Crypto application now supports generation of
+ cryptographically strong random numbers (floats &lt; 1.0
+ and integer arbitrary ranges) as a plugin to the 'rand'
+ module.</p>
+ <p>
+ Own Id: OTP-14317 Aux Id: PR-1372 </p>
+ </item>
+ <item>
+ <p>
+ Add new function <c>ets:select_replace/2</c> which
+ performs atomic "compare-and-swap" operations for ETS
+ objects using match specifications.</p>
+ <p>
+ Own Id: OTP-14319 Aux Id: PR-1076 </p>
+ </item>
+ <item>
+ <p> The Erlang code linter checks for bad <c>dialyzer</c>
+ attributes. It also checks for bad type variables in type
+ declarations. </p>
+ <p>
+ Own Id: OTP-14323</p>
+ </item>
+ <item>
+ <p> Two new functions has been implemented in the
+ <c>rand</c> module; <c>normal/2</c> and
+ <c>normal_s/3</c>, that both produce normal distribution
+ (pseudo) random numbers with mean value and variance
+ according to arguments. </p>
+ <p>
+ Own Id: OTP-14328 Aux Id: PR-1382 </p>
+ </item>
+ <item>
+ <p>
+ Upgraded the OTP internal PCRE library from version 8.33
+ to version 8.40. This library is used for implementation
+ of the <seealso marker="stdlib:re"><c>re</c></seealso>
+ regular expressions module.</p>
+ <p>
+ Besides various bug fixes, the new version allows for
+ better stack protection. In order to utilize this
+ feature, the stack size of normal scheduler threads is
+ now by default set to 128 kilo words on all platforms.
+ The stack size of normal scheduler threads can be set
+ upon system start by passing the <seealso
+ marker="erts:erl#sched_thread_stack_size"><c>+sss</c></seealso>
+ command line argument to the <seealso
+ marker="erts:erl"><c>erl</c></seealso> command.</p>
+ <p>
+ See <url
+ href="http://pcre.org/original/changelog.txt"><c>http://pcre.org/original/changelog.txt</c></url>
+ for information about changes made to PCRE between the
+ versions 8.33 and 8.40.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14331 Aux Id: ERL-208 </p>
+ </item>
+ <item>
+ <p>
+ Added function <c>re:version/0</c> which returns
+ information about the OTP internal PCRE version used for
+ implementation of the <c>re</c> module.</p>
+ <p>
+ Own Id: OTP-14347 Aux Id: PR-1412 </p>
+ </item>
+ <item>
+ <p>The format of debug information that is stored in BEAM
+ files (when <c>debug_info</c> is used) has been changed.
+ The purpose of the change is to better support other
+ BEAM-based languages such as Elixir or LFE.</p>
+ <p>All tools included in OTP (dialyzer, debugger, cover,
+ and so on) will handle both the new format and the
+ previous format. Tools that retrieve the debug
+ information using <c>beam_lib:chunk(Beam,
+ [abstract_code])</c> will continue to work with both the
+ new and old format. Tools that call
+ <c>beam_lib:chunk(Beam, ["Abst"])</c> will not work with
+ the new format.</p>
+ <p>For more information, see the description of
+ <c>debug_info</c> in the documentation for
+ <c>beam_lib</c> and the description of the
+ <c>{debug_info,{Backend,Data}}</c> option in the
+ documentation for <c>compile</c>.</p>
+ <p>
+ Own Id: OTP-14369 Aux Id: PR-1367 </p>
+ </item>
+ <item>
+ <p>
+ Add option hibernate_after to gen_server, gen_statem and
+ gen_event. Also added to the deprecated gen_fsm
+ behaviour.</p>
+ <p>
+ Own Id: OTP-14405</p>
+ </item>
+ <item>
+ <p> The size of crash reports created by
+ <c>gen_server</c>, <c>gen_statem</c> and <c>proc_lib</c>
+ is limited with aid of the Kernel application variable
+ <c>error_logger_format_depth</c>. The purpose is to limit
+ the size of the messages sent to the <c>error_logger</c>
+ process when processes with huge message queues or states
+ crash. </p> <p>The crash report generated by
+ <c>proc_lib</c> includes the new tag
+ <c>message_queue_len</c>. The neighbour report also
+ includes the new tag <c>current_stacktrace</c>. Finally,
+ the neighbour report no longer includes the tags
+ <c>messages</c> and <c>dictionary</c>. </p> <p> The new
+ function <c>error_logger:get_format_depth/0</c> can be
+ used to retrieve the value of the Kernel application
+ variable <c>error_logger_format_depth</c>. </p>
+ <p>
+ Own Id: OTP-14417</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>STDLIB 3.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>An escript with only two lines would not work.</p>
+ <p>
+ Own Id: OTP-14098</p>
+ </item>
+ <item>
+ <p> Characters (<c>$char</c>) can be used in constant
+ pattern expressions. They can also be used in types and
+ contracts. </p>
+ <p>
+ Own Id: OTP-14103 Aux Id: ERL-313 </p>
+ </item>
+ <item>
+ <p> The signatures of <c>erl_parse:anno_to_term/1</c> and
+ <c>erl_parse:anno_from_term/1</c> are corrected. Using
+ these functions no longer results in false Dialyzer
+ warnings. </p>
+ <p>
+ Own Id: OTP-14131</p>
+ </item>
+ <item>
+ <p>Pretty-printing of maps is improved. </p>
+ <p>
+ Own Id: OTP-14175 Aux Id: seq13277 </p>
+ </item>
+ <item>
+ <p>If any of the following functions in the <c>zip</c>
+ module crashed, a file would be left open:
+ <c>extract()</c>, <c>unzip()</c>, <c>create()</c>, or
+ <c>zip()</c>. This has been corrected.</p>
+ <p>A <c>zip</c> file having a "Unix header" could not be
+ unpacked.</p>
+ <p>
+ Own Id: OTP-14189 Aux Id: ERL-348, ERL-349 </p>
+ </item>
+ <item>
+ <p> Improve the Erlang shell's tab-completion of long
+ names. </p>
+ <p>
+ Own Id: OTP-14200 Aux Id: ERL-352 </p>
+ </item>
+ <item>
+ <p>
+ The reference manual for <c>sys</c> had some faulty
+ information about the 'get_modules' message used by
+ processes where modules change dynamically during
+ runtime. The documentation is now corrected.</p>
+ <p>
+ Own Id: OTP-14248 Aux Id: ERL-367 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Bug fixes, new features and improvements to gen_statem:</p>
+ <p>
+ A new type init_result/1 has replaced the old
+ init_result/0, so if you used that old type (that was
+ never documented) you have to change your code, which may
+ be regarded as a potential incompatibility.</p>
+ <p>
+ Changing callback modes after code change did not work
+ since the new callback mode was not recorded. This bug
+ has been fixed.</p>
+ <p>
+ The event types state_timeout and {call,From} could not
+ be generated with a {next_event,EventType,EventContent}
+ action since they did not pass the runtime type check.
+ This bug has now been corrected.</p>
+ <p>
+ State entry calls can now be repeated using (new) state
+ callback returns {repeat_state,...},
+ {repeat_state_and_data,_} and repeat_state_and_data.</p>
+ <p>
+ There have been lots of code cleanup in particular
+ regarding timer handling. For example is async
+ cancel_timer now used. Error handling has also been
+ cleaned up.</p>
+ <p>
+ To align with probable future changes to the rest of
+ gen_*, terminate/3 has now got a fallback and
+ code_change/4 is not mandatory.</p>
+ <p>
+ Own Id: OTP-14114</p>
+ </item>
+ <item>
+ <p><c>filename:safe_relative_path/1</c> to sanitize a
+ relative path has been added.</p>
+ <p>
+ Own Id: OTP-14215</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>STDLIB 3.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ When a simple_one_for_one supervisor is shutting down,
+ and a child exits with an exit reason of the form
+ {shutdown, Term}, an error report was earlier printed.
+ This is now corrected.</p>
+ <p>
+ Own Id: OTP-13907 Aux Id: PR-1158, ERL-163 </p>
+ </item>
+ <item>
+ <p> Allow empty list as parameter of the fun used with
+ <c>dbg:fun2ms/1</c>. </p>
+ <p>
+ Own Id: OTP-13974</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The new behaviour gen_statem has been improved with 3 new
+ features: the possibility to use old style non-proxy
+ timeouts for gen_statem:call/2,3, state entry code, and
+ state timeouts. These are backwards compatible. Minor
+ code and documentation improvements has been performed
+ including a borderline semantics correction of timeout
+ zero handling.</p>
+ <p>
+ Own Id: OTP-13929 Aux Id: PR-1170, ERL-284 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>STDLIB 3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The <c>zip:unzip/1,2</c> and <c>zip:extract/1,2</c>
+ functions have been updated to handle directory traversal
+ exploits. Any element in the zip file that contains a
+ path that points to a directory above the top level
+ working directory, <c>cwd</c>, will instead be extracted
+ in <c>cwd</c>. An error message is printed for any such
+ element in the zip file during the unzip operation. The
+ <c>keep_old_files</c> option determines if a file will
+ overwrite a previous file with the same name within the
+ zip file.</p>
+ <p>
+ Own Id: OTP-13633</p>
+ </item>
+ <item>
+ <p> Correct the contracts for
+ <c>ets:match_object/1,3</c>. </p>
+ <p>
+ Own Id: OTP-13721 Aux Id: PR-1113 </p>
+ </item>
+ <item>
+ <p>
+ Errors in type specification and Emacs template
+ generation for <c>gen_statem:code_change/4</c> has been
+ fixed from bugs.erlang.org's Jira cases ERL-172 and
+ ERL-187.</p>
+ <p>
+ Own Id: OTP-13746 Aux Id: ERL-172, ERL-187 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ gen_statem has been changed to set the callback mode for
+ a server to what Module:callback_mode/0 returns. This
+ facilitates e.g code downgrade since the callback mode
+ now becomes a property of the currently active code, not
+ of the server process.</p>
+ <p>
+ Exception handling from Module:init/1 has also been
+ improved.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-13752</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>STDLIB 3.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Correct a bug regarding typed records in the Erlang
+ shell. The bug was introduced in OTP-19.0. </p>
+ <p>
+ Own Id: OTP-13719 Aux Id: ERL-182 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>STDLIB 3.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -511,7 +1170,7 @@
</item>
<item>
<p>
- The <c>stdlib</c> reference manual is updated to show
+ The STDLIB reference manual is updated to show
correct information about the return value of
<c>gen_fsm:reply/2</c>.</p>
<p>
@@ -3046,7 +3705,7 @@
<p>
Two bugs in io:format for ~F.~Ps has been corrected. When
length(S) >= abs(F) > P, the precision P was incorrectly
- ignored. When F == P > lenght(S) the result was
+ ignored. When F == P > length(S) the result was
incorrectly left adjusted. Bug found by Ali Yakout who
also provided a fix.</p>
<p>
@@ -6221,7 +6880,7 @@
documentation for <c>compile</c> on how to provide the key
for encrypting, and the documentation for <c>beam_lib</c>
on how to provide the key for decryption so that tools such
- as the Debugger, <c>xref</c>, or <c>cover</c> can be used.</p>
+ as the Debugger, Xref, or Cover can be used.</p>
<p>The <c>beam_lib:chunks/2</c> functions now accepts an
additional chunk type <c>compile_info</c> to retrieve
the compilation information directly as a term. (Thanks
diff --git a/lib/stdlib/doc/src/orddict.xml b/lib/stdlib/doc/src/orddict.xml
index 076b06fc38..26bbf499c6 100644
--- a/lib/stdlib/doc/src/orddict.xml
+++ b/lib/stdlib/doc/src/orddict.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2015</year>
+ <year>2000</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -38,7 +38,7 @@
<p>This module provides a <c>Key</c>-<c>Value</c> dictionary.
An <c>orddict</c> is a representation of a dictionary, where a
list of pairs is used to store the keys and values. The list is
- ordered after the keys.</p>
+ ordered after the keys in the <em>Erlang term order</em>.</p>
<p>This module provides the same interface as the
<seealso marker="dict"><c>dict(3)</c></seealso> module
@@ -113,6 +113,15 @@
</func>
<func>
+ <name name="take" arity="2"/>
+ <fsummary>Return value and new dictionary without element with this value.</fsummary>
+ <desc>
+ <p>This function returns value from dictionary and new dictionary without this value.
+ Returns <c>error</c> if the key is not present in the dictionary.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="filter" arity="2"/>
<fsummary>Select elements that satisfy a predicate.</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/ordsets.xml b/lib/stdlib/doc/src/ordsets.xml
index 148281fcf7..7b590932e4 100644
--- a/lib/stdlib/doc/src/ordsets.xml
+++ b/lib/stdlib/doc/src/ordsets.xml
@@ -39,7 +39,8 @@
<p>Sets are collections of elements with no duplicate elements.
An <c>ordset</c> is a representation of a set, where an ordered
list is used to store the elements of the set. An ordered list
- is more efficient than an unordered list.</p>
+ is more efficient than an unordered list. Elements are ordered
+ according to the <em>Erlang term order</em>.</p>
<p>This module provides the same interface as the
<seealso marker="sets"><c>sets(3)</c></seealso> module
diff --git a/lib/stdlib/doc/src/proc_lib.xml b/lib/stdlib/doc/src/proc_lib.xml
index 58ca5644cf..cb152d1935 100644
--- a/lib/stdlib/doc/src/proc_lib.xml
+++ b/lib/stdlib/doc/src/proc_lib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -36,7 +36,7 @@
the <seealso marker="doc/design_principles:des_princ">
OTP Design Principles</seealso>. Specifically, the functions in this
module are used by the OTP standard behaviors (for example,
- <c>gen_server</c>, <c>gen_fsm</c>, and <c>gen_statem</c>)
+ <c>gen_server</c> and <c>gen_statem</c>)
when starting new processes. The functions
can also be used to start <em>special processes</em>, user-defined
processes that comply to the OTP design principles. For an example,
@@ -59,13 +59,19 @@
<p>When a process that is started using <c>proc_lib</c> terminates
abnormally (that is, with another exit reason than <c>normal</c>,
<c>shutdown</c>, or <c>{shutdown,Term}</c>), a <em>crash report</em>
- is generated, which is written to terminal by the default <c>SASL</c>
+ is generated, which is written to terminal by the default SASL
event handler. That is, the crash report is normally only visible
- if the <c>SASL</c> application is started; see
+ if the SASL application is started; see
<seealso marker="sasl:sasl_app"><c>sasl(6)</c></seealso> and section
<seealso marker="sasl:error_logging">SASL Error Logging</seealso>
in the SASL User's Guide.</p>
+ <p>Unlike in "plain Erlang", <c>proc_lib</c> processes will not generate
+ <em>error reports</em>, which are written to the terminal by the
+ emulator and do not require SASL to be started. All exceptions are
+ converted to <em>exits</em> which are ignored by the default
+ <c>error_logger</c> handler.</p>
+
<p>The crash report contains the previously stored information, such
as ancestors and initial function, the termination reason, and
information about other processes that terminate as a result
diff --git a/lib/stdlib/doc/src/proplists.xml b/lib/stdlib/doc/src/proplists.xml
index fe6b8cc3bf..f9a54bf804 100644
--- a/lib/stdlib/doc/src/proplists.xml
+++ b/lib/stdlib/doc/src/proplists.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2016</year>
+ <year>2002</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -344,7 +344,7 @@ split([{c, 2}, {e, 1}, a, {c, 3, 4}, d, {b, 5}, b], [a, b, c])</code>
with <c>{K2, true}</c>, thus changing the name of the option and
simultaneously negating the value specified by
<seealso marker="#get_bool/2">
- <c>get_bool(Key, <anno>ListIn</anno></c></seealso>.
+ <c>get_bool(Key, <anno>ListIn</anno>)</c></seealso>.
If the same <c>K1</c> occurs more than once in
<c><anno>Negations</anno></c>, only the first occurrence is used.</p>
<p>For example, <c>substitute_negations([{no_foo, foo}], L)</c>
diff --git a/lib/stdlib/doc/src/queue.xml b/lib/stdlib/doc/src/queue.xml
index a46ca47033..9f3aff03a3 100644
--- a/lib/stdlib/doc/src/queue.xml
+++ b/lib/stdlib/doc/src/queue.xml
@@ -401,7 +401,7 @@
</func>
<func>
- <name name="liat" arity="1"/>v
+ <name name="liat" arity="1"/>
<fsummary>Remove the tail item from a queue.</fsummary>
<desc>
<p>Returns a queue <c><anno>Q2</anno></c> that is the result of removing
diff --git a/lib/stdlib/doc/src/rand.xml b/lib/stdlib/doc/src/rand.xml
index 1dcc3de000..e06d7e467d 100644
--- a/lib/stdlib/doc/src/rand.xml
+++ b/lib/stdlib/doc/src/rand.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2015</year>
+ <year>2015</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -41,27 +41,82 @@
Sebastiano Vigna</url>. The normal distribution algorithm uses the
<url href="http://www.jstatsoft.org/v05/i08">Ziggurat Method by Marsaglia
and Tsang</url>.</p>
+ <p>For some algorithms, jump functions are provided for generating
+ non-overlapping sequences for parallel computations.
+ The jump functions perform calculations
+ equivalent to perform a large number of repeated calls
+ for calculating new states. </p>
<p>The following algorithms are provided:</p>
<taglist>
- <tag><c>exsplus</c></tag>
+ <tag><c>exrop</c></tag>
<item>
- <p>Xorshift116+, 58 bits precision and period of 2^116-1</p>
+ <p>Xoroshiro116+, 58 bits precision and period of 2^116-1</p>
+ <p>Jump function: equivalent to 2^64 calls</p>
</item>
- <tag><c>exs64</c></tag>
+ <tag><c>exs1024s</c></tag>
<item>
- <p>Xorshift64*, 64 bits precision and a period of 2^64-1</p>
+ <p>Xorshift1024*, 64 bits precision and a period of 2^1024-1</p>
+ <p>Jump function: equivalent to 2^512 calls</p>
</item>
- <tag><c>exs1024</c></tag>
+ <tag><c>exsp</c></tag>
<item>
- <p>Xorshift1024*, 64 bits precision and a period of 2^1024-1</p>
+ <p>Xorshift116+, 58 bits precision and period of 2^116-1</p>
+ <p>Jump function: equivalent to 2^64 calls</p>
+ <p>
+ This is a corrected version of the previous default algorithm,
+ that now has been superseeded by Xoroshiro116+ (<c>exrop</c>).
+ Since there is no native 58 bit rotate instruction this
+ algorithm executes a little (say &lt; 15%) faster than <c>exrop</c>.
+ See the
+ <url href="http://xorshift.di.unimi.it">algorithms' homepage</url>.
+ </p>
</item>
</taglist>
- <p>The default algorithm is <c>exsplus</c>. If a specific algorithm is
+ <p>
+ The default algorithm is <c>exrop</c> (Xoroshiro116+).
+ If a specific algorithm is
required, ensure to always use <seealso marker="#seed-1">
- <c>seed/1</c></seealso> to initialize the state.</p>
+ <c>seed/1</c></seealso> to initialize the state.
+ </p>
+
+ <p>
+ Undocumented (old) algorithms are deprecated but still implemented
+ so old code relying on them will produce
+ the same pseudo random sequences as before.
+ </p>
+
+ <note>
+ <p>
+ There were a number of problems in the implementation
+ of the now undocumented algorithms, which is why
+ they are deprecated. The new algorithms are a bit slower
+ but do not have these problems:
+ </p>
+ <p>
+ Uniform integer ranges had a skew in the probability distribution
+ that was not noticable for small ranges but for large ranges
+ less than the generator's precision the probability to produce
+ a low number could be twice the probability for a high.
+ </p>
+ <p>
+ Uniform integer ranges larger than or equal to the generator's
+ precision used a floating point fallback that only calculated
+ with 52 bits which is smaller than the requested range
+ and therefore were not all numbers in the requested range
+ even possible to produce.
+ </p>
+ <p>
+ Uniform floats had a non-uniform density so small values
+ i.e less than 0.5 had got smaller intervals decreasing
+ as the generated value approached 0.0 although still uniformly
+ distributed for sufficiently large subranges. The new algorithms
+ produces uniformly distributed floats on the form N * 2.0^(-53)
+ hence equally spaced.
+ </p>
+ </note>
<p>Every time a random number is requested, a state is used to
calculate it and a new state is produced. The state can either be
@@ -91,19 +146,19 @@ R1 = rand:uniform(),</pre>
<p>Use a specified algorithm:</p>
<pre>
-_ = rand:seed(exs1024),
+_ = rand:seed(exs1024s),
R2 = rand:uniform(),</pre>
<p>Use a specified algorithm with a constant seed:</p>
<pre>
-_ = rand:seed(exs1024, {123, 123534, 345345}),
+_ = rand:seed(exs1024s, {123, 123534, 345345}),
R3 = rand:uniform(),</pre>
<p>Use the functional API with a non-constant seed:</p>
<pre>
-S0 = rand:seed_s(exsplus),
+S0 = rand:seed_s(exrop),
{R4, S1} = rand:uniform_s(S0),</pre>
<p>Create a standard normal deviate:</p>
@@ -111,28 +166,93 @@ S0 = rand:seed_s(exsplus),
<pre>
{SND0, S2} = rand:normal_s(S1),</pre>
+ <p>Create a normal deviate with mean -3 and variance 0.5:</p>
+
+ <pre>
+{ND0, S3} = rand:normal_s(-3, 0.5, S2),</pre>
+
<note>
- <p>This random number generator is not cryptographically
- strong. If a strong cryptographic random number generator is
- needed, use one of functions in the
- <seealso marker="crypto:crypto"><c>crypto</c></seealso>
- module, for example, <seealso marker="crypto:crypto">
- <c>crypto:strong_rand_bytes/1</c></seealso>.</p>
+ <p>The builtin random number generator algorithms are not
+ cryptographically strong. If a cryptographically strong
+ random number generator is needed, use something like
+ <seealso marker="crypto:crypto#rand_seed-0"><c>crypto:rand_seed/0</c></seealso>.
+ </p>
</note>
+ <p>
+ For all these generators the lowest bit(s) has got
+ a slightly less random behaviour than all other bits.
+ 1 bit for <c>exrop</c> (and <c>exsp</c>),
+ and 3 bits for <c>exs1024s</c>.
+ See for example the explanation in the
+ <url href="http://xoroshiro.di.unimi.it/xoroshiro128plus.c">
+ Xoroshiro128+
+ </url>
+ generator source code:
+ </p>
+ <pre>
+Beside passing BigCrush, this generator passes the PractRand test suite
+up to (and included) 16TB, with the exception of binary rank tests,
+which fail due to the lowest bit being an LFSR; all other bits pass all
+tests. We suggest to use a sign test to extract a random Boolean value.</pre>
+ <p>
+ If this is a problem; to generate a boolean
+ use something like this:
+ </p>
+ <pre>(rand:uniform(16) > 8)</pre>
+ <p>
+ And for a general range, with <c>N = 1</c> for <c>exrop</c>,
+ and <c>N = 3</c> for <c>exs1024s</c>:
+ </p>
+ <pre>(((rand:uniform(Range bsl N) - 1) bsr N) + 1)</pre>
+ <p>
+ The floating point generating functions in this module
+ waste the lowest bits when converting from an integer
+ so they avoid this snag.
+ </p>
+
+
</description>
<datatypes>
<datatype>
+ <name name="builtin_alg"/>
+ </datatype>
+ <datatype>
<name name="alg"/>
</datatype>
<datatype>
+ <name name="alg_handler"/>
+ </datatype>
+ <datatype>
+ <name name="alg_state"/>
+ </datatype>
+ <datatype>
<name name="state"/>
<desc><p>Algorithm-dependent state.</p></desc>
</datatype>
<datatype>
<name name="export_state"/>
- <desc><p>Algorithm-dependent state that can be printed or saved to
- file.</p></desc>
+ <desc>
+ <p>
+ Algorithm-dependent state that can be printed or saved to file.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="exs64_state"/>
+ <desc><p>Algorithm specific internal state</p></desc>
+ </datatype>
+ <datatype>
+ <name name="exsplus_state"/>
+ <desc><p>Algorithm specific internal state</p></desc>
+ </datatype>
+ <datatype>
+ <name name="exs1024_state"/>
+ <desc><p>Algorithm specific internal state</p></desc>
+ </datatype>
+ <datatype>
+ <name name="exrop_state"/>
+ <desc><p>Algorithm specific internal state</p></desc>
</datatype>
</datatypes>
@@ -156,6 +276,33 @@ S0 = rand:seed_s(exsplus),
</func>
<func>
+ <name name="jump" arity="0"/>
+ <fsummary>Return the seed after performing jump calculation
+ to the state in the process dictionary.</fsummary>
+ <desc><marker id="jump-0" />
+ <p>Returns the state
+ after performing jump calculation
+ to the state in the process dictionary.</p>
+ <p>This function generates a <c>not_implemented</c> error exception
+ when the jump function is not implemented for
+ the algorithm specified in the state
+ in the process dictionary.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="jump" arity="1"/>
+ <fsummary>Return the seed after performing jump calculation.</fsummary>
+ <desc><marker id="jump-1" />
+ <p>Returns the state after performing jump calculation
+ to the given state. </p>
+ <p>This function generates a <c>not_implemented</c> error exception
+ when the jump function is not implemented for
+ the algorithm specified in the state.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="normal" arity="0"/>
<fsummary>Return a standard normal distributed random float.</fsummary>
<desc>
@@ -166,6 +313,15 @@ S0 = rand:seed_s(exsplus),
</func>
<func>
+ <name name="normal" arity="2"/>
+ <fsummary>Return a normal distributed random float.</fsummary>
+ <desc>
+ <p>Returns a normal N(Mean, Variance) deviate float
+ and updates the state in the process dictionary.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="normal_s" arity="1"/>
<fsummary>Return a standard normal distributed random float.</fsummary>
<desc>
@@ -176,12 +332,24 @@ S0 = rand:seed_s(exsplus),
</func>
<func>
+ <name name="normal_s" arity="3"/>
+ <fsummary>Return a normal distributed random float.</fsummary>
+ <desc>
+ <p>Returns, for a specified state, a normal N(Mean, Variance)
+ deviate float and a new state.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="seed" arity="1"/>
<fsummary>Seed random number generator.</fsummary>
<desc>
<marker id="seed-1"/>
- <p>Seeds random number generation with the specifed algorithm and
- time-dependent data if <anno>AlgOrExpState</anno> is an algorithm.</p>
+ <p>
+ Seeds random number generation with the specifed algorithm and
+ time-dependent data if <c><anno>AlgOrStateOrExpState</anno></c>
+ is an algorithm.
+ </p>
<p>Otherwise recreates the exported seed in the process dictionary,
and returns the state. See also
<seealso marker="#export_seed-0"><c>export_seed/0</c></seealso>.</p>
@@ -201,8 +369,11 @@ S0 = rand:seed_s(exsplus),
<name name="seed_s" arity="1"/>
<fsummary>Seed random number generator.</fsummary>
<desc>
- <p>Seeds random number generation with the specifed algorithm and
- time-dependent data if <anno>AlgOrExpState</anno> is an algorithm.</p>
+ <p>
+ Seeds random number generation with the specifed algorithm and
+ time-dependent data if <c><anno>AlgOrStateOrExpState</anno></c>
+ is an algorithm.
+ </p>
<p>Otherwise recreates the exported seed and returns the state.
See also <seealso marker="#export_seed-0">
<c>export_seed/0</c></seealso>.</p>
@@ -223,7 +394,7 @@ S0 = rand:seed_s(exsplus),
<fsummary>Return a random float.</fsummary>
<desc><marker id="uniform-0"/>
<p>Returns a random float uniformly distributed in the value
- range <c>0.0 &lt; <anno>X</anno> &lt; 1.0</c> and
+ range <c>0.0 =&lt; <anno>X</anno> &lt; 1.0</c> and
updates the state in the process dictionary.</p>
</desc>
</func>
@@ -234,7 +405,7 @@ S0 = rand:seed_s(exsplus),
<desc><marker id="uniform-1"/>
<p>Returns, for a specified integer <c><anno>N</anno> >= 1</c>,
a random integer uniformly distributed in the value range
- <c>1 &lt;= <anno>X</anno> &lt;= <anno>N</anno></c> and
+ <c>1 =&lt; <anno>X</anno> =&lt; <anno>N</anno></c> and
updates the state in the process dictionary.</p>
</desc>
</func>
@@ -244,7 +415,7 @@ S0 = rand:seed_s(exsplus),
<fsummary>Return a random float.</fsummary>
<desc>
<p>Returns, for a specified state, random float
- uniformly distributed in the value range <c>0.0 &lt;
+ uniformly distributed in the value range <c>0.0 =&lt;
<anno>X</anno> &lt; 1.0</c> and a new state.</p>
</desc>
</func>
@@ -255,7 +426,7 @@ S0 = rand:seed_s(exsplus),
<desc>
<p>Returns, for a specified integer <c><anno>N</anno> >= 1</c>
and a state, a random integer uniformly distributed in the value
- range <c>1 &lt;= <anno>X</anno> &lt;= <anno>N</anno></c> and a
+ range <c>1 =&lt; <anno>X</anno> =&lt; <anno>N</anno></c> and a
new state.</p>
</desc>
</func>
diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml
index 7f4f0aa18c..078ca0e38c 100644
--- a/lib/stdlib/doc/src/re.xml
+++ b/lib/stdlib/doc/src/re.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2007</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -45,9 +45,10 @@
<p>The matching algorithms of the library are based on the
PCRE library, but not all of the PCRE library is interfaced and
- some parts of the library go beyond what PCRE offers. The sections of
- the PCRE documentation that are relevant to this module are included
- here.</p>
+ some parts of the library go beyond what PCRE offers. Currently
+ PCRE version 8.40 (release date 2017-01-11) is used. The sections
+ of the PCRE documentation that are relevant to this module are
+ included here.</p>
<note>
<p>The Erlang literal syntax for strings uses the &quot;\&quot;
@@ -78,6 +79,14 @@
<funcs>
<func>
+ <name name="version" arity="0"/>
+ <fsummary>Gives the PCRE version of the system in a string format</fsummary>
+ <desc>
+ <p>The return of this function is a string with the PCRE version of the system that was used in the Erlang/OTP compilation.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="compile" arity="1"/>
<fsummary>Compile a regular expression into a match program</fsummary>
<desc>
@@ -149,13 +158,25 @@
</item>
<tag><c>extended</c></tag>
<item>
- <p>Whitespace data characters in the pattern are ignored except
- when escaped or inside a character class. Whitespace does not
- include character 'vt' (ASCII 11). Characters between an
- unescaped <c>#</c> outside a character class and the next newline,
- inclusive, are also ignored. This is equivalent to Perl option
- <c>/x</c> and can be changed within a pattern by a <c>(?x)</c>
- option setting.</p>
+ <p>If this option is set, most white space characters in the
+ pattern are totally ignored except when escaped or inside a
+ character class. However, white space is not allowed within
+ sequences such as <c>(?&#62;</c> that introduce various
+ parenthesized subpatterns, nor within a numerical quantifier
+ such as <c>{1,3}</c>. However, ignorable white space is permitted
+ between an item and a following quantifier and between a
+ quantifier and a following + that indicates possessiveness.
+ </p>
+ <p>White space did not used to include the VT character (code
+ 11), because Perl did not treat this character as white space.
+ However, Perl changed at release 5.18, so PCRE followed at
+ release 8.34, and VT is now treated as white space.
+ </p>
+ <p>This also causes characters between an unescaped #
+ outside a character class and the next newline, inclusive, to
+ be ignored. This is equivalent to Perl's <c>/x</c> option, and it
+ can be changed within a pattern by a <c>(?x)</c> option setting.
+ </p>
<p>With this option, comments inside complicated patterns can be
included. However, notice that this applies only to data
characters. Whitespace characters can never appear within special
@@ -1321,6 +1342,8 @@ re:split("Erlang","[lg]",[{return,list},{parts,4}]).</code>
VM. Notice that the recursion limit does not affect the stack depth of the
VM, as PCRE for Erlang is compiled in such a way that the match function
never does recursion on the C stack.</p>
+ <p>Note that <c>LIMIT_MATCH</c> and <c>LIMIT_RECURSION</c> can only reduce
+ the value of the limits set by the caller, not increase them.</p>
</section>
<section>
@@ -1444,12 +1467,17 @@ Pattern PCRE matches Perl matches
<tag>\n</tag><item>Line feed (hex 0A)</item>
<tag>\r</tag><item>Carriage return (hex 0D)</item>
<tag>\t</tag><item>Tab (hex 09)</item>
+ <tag>\0dd</tag><item>Character with octal code 0dd</item>
<tag>\ddd</tag><item>Character with octal code ddd, or back reference
</item>
+ <tag>\o{ddd..}</tag><item>character with octal code ddd..</item>
<tag>\xhh</tag><item>Character with hex code hh</item>
<tag>\x{hhh..}</tag><item>Character with hex code hhh..</item>
</taglist>
+ <note><p>Note that \0dd is always an octal code, and that \8 and \9 are
+ the literal characters "8" and "9".</p></note>
+
<p>The precise effect of \cx on ASCII characters is as follows: if x is a
lowercase letter, it is converted to upper case. Then bit 6 of the
character (hex 40) is inverted. Thus \cA to \cZ become hex 01 to hex 1A
@@ -1461,50 +1489,38 @@ Pattern PCRE matches Perl matches
<p>The \c facility was designed for use with ASCII characters, but with the
extension to Unicode it is even less useful than it once was.</p>
- <p>By default, after \x, from zero to two hexadecimal digits are read
- (letters can be in upper or lower case). Any number of hexadecimal digits
- can appear between \x{ and }, but the character code is constrained as
- follows:</p>
-
- <taglist>
- <tag>8-bit non-Unicode mode</tag>
- <item>&lt; 0x100</item>
- <tag>8-bit UTF-8 mode</tag>
- <item>&lt; 0x10ffff and a valid code point</item>
- </taglist>
-
- <p>Invalid Unicode code points are the range 0xd800 to 0xdfff (the so-called
- "surrogate" code points), and 0xffef.</p>
-
- <p>If characters other than hexadecimal digits appear between \x{ and },
- or if there is no terminating }, this form of escape is not recognized.
- Instead, the initial \x is interpreted as a basic hexadecimal escape,
- with no following digits, giving a character whose value is zero.</p>
-
- <p>Characters whose value is &lt; 256 can be defined by either of the two
- syntaxes for \x. There is no difference in the way they are handled. For
- example, \xdc is the same as \x{dc}.</p>
-
<p>After \0 up to two further octal digits are read. If there are fewer than
- two digits, only those that are present are used. Thus the sequence
- \0\x\07 specifies two binary zeros followed by a BEL character (code value
- 7). Ensure to supply two digits after the initial zero if the pattern
- character that follows is itself an octal digit.</p>
+ two digits, just those that are present are used. Thus the sequence
+ \0\x\015 specifies two binary zeros followed by a CR character (code value
+ 13). Make sure you supply two digits after the initial zero if the pattern
+ character that follows is itself an octal digit.</p>
+
+ <p>The escape \o must be followed by a sequence of octal digits, enclosed
+ in braces. An error occurs if this is not the case. This escape is a recent
+ addition to Perl; it provides way of specifying character code points as
+ octal numbers greater than 0777, and it also allows octal numbers and back
+ references to be unambiguously specified.</p>
+
+ <p>For greater clarity and unambiguity, it is best to avoid following \ by
+ a digit greater than zero. Instead, use \o{} or \x{} to specify character
+ numbers, and \g{} to specify back references. The following paragraphs
+ describe the old, ambiguous syntax.</p>
<p>The handling of a backslash followed by a digit other than 0 is
- complicated. Outside a character class, PCRE reads it and any following
- digits as a decimal number. If the number is &lt; 10, or if there have
+ complicated, and Perl has changed in recent releases, causing PCRE also
+ to change. Outside a character class, PCRE reads the digit and any following
+ digits as a decimal number. If the number is &lt; 8, or if there have
been at least that many previous capturing left parentheses in the
expression, the entire sequence is taken as a <em>back reference</em>. A
description of how this works is provided later, following the discussion
of parenthesized subpatterns.</p>
- <p>Inside a character class, or if the decimal number is &gt; 9 and there
- have not been that many capturing subpatterns, PCRE re-reads up to three
- octal digits following the backslash, and uses them to generate a data
- character. Any subsequent digits stand for themselves. The value of the
- character is constrained in the same way as characters specified in
- hexadecimal. For example:</p>
+ <p>Inside a character class, or if the decimal number following \ is &gt;
+ 7 and there have not been that many capturing subpatterns, PCRE handles
+ \8 and \9 as the literal characters "8" and "9", and otherwise re-reads
+ up to three octal digits following the backslash, and using them to
+ generate a data character. Any subsequent digits stand for themselves.
+ For example:</p>
<taglist>
<tag>\040</tag>
@@ -1526,12 +1542,38 @@ Pattern PCRE matches Perl matches
<tag>\377</tag>
<item>Can be a back reference, otherwise value 255 (decimal)</item>
<tag>\81</tag>
- <item>Either a back reference, or a binary zero followed by the two
- characters "8" and "1"</item>
+ <item>Either a back reference, or the two characters "8" and "1"</item>
</taglist>
- <p>Notice that octal values &gt;= 100 must not be introduced by a leading
- zero, as no more than three octal digits are ever read.</p>
+ <p>Notice that octal values &gt;= 100 that are specified using this syntax
+ must not be introduced by a leading zero, as no more than three octal digits
+ are ever read.</p>
+
+ <p>By default, after \x that is not followed by {, from zero to two
+ hexadecimal digits are read (letters can be in upper or lower case). Any
+ number of hexadecimal digits may appear between \x{ and }. If a character
+ other than a hexadecimal digit appears between \x{ and }, or if there is no
+ terminating }, an error occurs.
+ </p>
+
+ <p>Characters whose value is less than 256 can be defined by either of the
+ two syntaxes for \x. There is no difference in the way they are handled. For
+ example, \xdc is exactly the same as \x{dc}.</p>
+
+ <p><em>Constraints on character values</em></p>
+
+ <p>Characters that are specified using octal or hexadecimal numbers are
+ limited to certain values, as follows:</p>
+ <taglist>
+ <tag>8-bit non-UTF mode</tag>
+ <item><p>&lt; 0x100</p></item>
+ <tag>8-bit UTF-8 mode</tag>
+ <item><p>&lt; 0x10ffff and a valid codepoint</p></item>
+ </taglist>
+ <p>Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the
+ so-called "surrogate" codepoints), and 0xffef.</p>
+
+ <p><em>Escape sequences in character classes</em></p>
<p>All the sequences that define a single character value can be used both
inside and outside character classes. Also, inside a character class, \b
@@ -1597,11 +1639,14 @@ Pattern PCRE matches Perl matches
appropriate type. If the current matching point is at the end of the
subject string, all fail, as there is no character to match.</p>
- <p>For compatibility with Perl, \s does not match the VT character
- (code 11). This makes it different from the Posix "space" class. The \s
- characters are HT (9), LF (10), FF (12), CR (13), and space (32). If "use
- locale;" is included in a Perl script, \s can match the VT character. In
- PCRE, it never does.</p>
+ <p>For compatibility with Perl, \s did not used to match the VT character (code
+ 11), which made it different from the the POSIX "space" class. However, Perl
+ added VT at release 5.18, and PCRE followed suit at release 8.34. The default
+ \s characters are now HT (9), LF (10), VT (11), FF (12), CR (13), and space
+ (32), which are defined as white space in the "C" locale. This list may vary if
+ locale-specific matching is taking place. For example, in some locales the
+ "non-breaking space" character (\xA0) is recognized as white space, and in
+ others the VT character is not.</p>
<p>A "word" character is an underscore or any character that is a letter or
a digit. By default, the definition of letters and digits is controlled by
@@ -1619,9 +1664,9 @@ Pattern PCRE matches Perl matches
<taglist>
<tag>\d</tag><item>Any character that \p{Nd} matches (decimal digit)
</item>
- <tag>\s</tag><item>Any character that \p{Z} matches, plus HT, LF, FF, CR
+ <tag>\s</tag><item>Any character that \p{Z} or \h or \v
</item>
- <tag>\w</tag><item>Any character that \p{L} or \p{N} matches, plus
+ <tag>\w</tag><item>Any character that matches \p{L} or \p{N} matches, plus
underscore</item>
</taglist>
@@ -1769,6 +1814,7 @@ Pattern PCRE matches Perl matches
<item>Avestan</item>
<item>Balinese</item>
<item>Bamum</item>
+ <item>Bassa_Vah</item>
<item>Batak</item>
<item>Bengali</item>
<item>Bopomofo</item>
@@ -1777,6 +1823,7 @@ Pattern PCRE matches Perl matches
<item>Buhid</item>
<item>Canadian_Aboriginal</item>
<item>Carian</item>
+ <item>Caucasian_Albanian</item>
<item>Chakma</item>
<item>Cham</item>
<item>Cherokee</item>
@@ -1787,11 +1834,14 @@ Pattern PCRE matches Perl matches
<item>Cyrillic</item>
<item>Deseret</item>
<item>Devanagari</item>
+ <item>Duployan</item>
<item>Egyptian_Hieroglyphs</item>
+ <item>Elbasan</item>
<item>Ethiopic</item>
<item>Georgian</item>
<item>Glagolitic</item>
<item>Gothic</item>
+ <item>Grantha</item>
<item>Greek</item>
<item>Gujarati</item>
<item>Gurmukhi</item>
@@ -1811,40 +1861,56 @@ Pattern PCRE matches Perl matches
<item>Kayah_Li</item>
<item>Kharoshthi</item>
<item>Khmer</item>
+ <item>Khojki</item>
+ <item>Khudawadi</item>
<item>Lao</item>
<item>Latin</item>
<item>Lepcha</item>
<item>Limbu</item>
+ <item>Linear_A</item>
<item>Linear_B</item>
<item>Lisu</item>
<item>Lycian</item>
<item>Lydian</item>
+ <item>Mahajani</item>
<item>Malayalam</item>
<item>Mandaic</item>
+ <item>Manichaean</item>
<item>Meetei_Mayek</item>
+ <item>Mende_Kikakui</item>
<item>Meroitic_Cursive</item>
<item>Meroitic_Hieroglyphs</item>
<item>Miao</item>
+ <item>Modi</item>
<item>Mongolian</item>
+ <item>Mro</item>
<item>Myanmar</item>
+ <item>Nabataean</item>
<item>New_Tai_Lue</item>
<item>Nko</item>
<item>Ogham</item>
+ <item>Ol_Chiki</item>
<item>Old_Italic</item>
+ <item>Old_North_Arabian</item>
+ <item>Old_Permic</item>
<item>Old_Persian</item>
<item>Oriya</item>
<item>Old_South_Arabian</item>
<item>Old_Turkic</item>
- <item>Ol_Chiki</item>
<item>Osmanya</item>
+ <item>Pahawh_Hmong</item>
+ <item>Palmyrene</item>
+ <item>Pau_Cin_Hau</item>
<item>Phags_Pa</item>
<item>Phoenician</item>
+ <item>Psalter_Pahlavi</item>
<item>Rejang</item>
<item>Runic</item>
<item>Samaritan</item>
<item>Saurashtra</item>
<item>Sharada</item>
<item>Shavian</item>
+ <item>Siddham</item>
<item>Sinhala</item>
<item>Sora_Sompeng</item>
<item>Sundanese</item>
@@ -1862,8 +1928,10 @@ Pattern PCRE matches Perl matches
<item>Thai</item>
<item>Tibetan</item>
<item>Tifinagh</item>
+ <item>Tirhuta</item>
<item>Ugaritic</item>
<item>Vai</item>
+ <item>Warang_Citi</item>
<item>Yi</item>
</list>
@@ -2001,10 +2069,10 @@ Pattern PCRE matches Perl matches
<p>In addition to the standard Unicode properties described earlier, PCRE
supports four more that make it possible to convert traditional escape
- sequences, such as \w and \s, and Posix character classes to use Unicode
+ sequences, such as \w and \s to use Unicode
properties. PCRE uses these non-standard, non-Perl properties internally
- when <c>PCRE_UCP</c> is set. However, they can also be used explicitly.
- The properties are as follows:</p>
+ when the <c>ucp</c> option is passed. However, they can also be used
+ explicitly. The properties are as follows:</p>
<taglist>
<tag>Xan</tag>
@@ -2030,6 +2098,16 @@ Pattern PCRE matches Perl matches
</item>
</taglist>
+ <p>Perl and POSIX space are now the same. Perl added VT to its space
+ character set at release 5.18 and PCRE changed at release 8.34.</p>
+
+ <p>Xan matches characters that have either the L (letter) or the N (number)
+ property. Xps matches the characters tab, linefeed, vertical tab, form feed,
+ or carriage return, and any other character that has the Z (separator)
+ property. Xsp is the same as Xps; it used to exclude vertical tab, for Perl
+ compatibility, but Perl changed, and so PCRE followed at release 8.34. Xwd
+ matches the same characters as Xan, plus underscore.
+ </p>
<p>There is another non-standard property, Xuc, which matches any character
that can be represented by a Universal Character Name in C++ and other
programming languages. These are the characters $, @, ` (grave accent),
@@ -2062,7 +2140,9 @@ foo\Kbar</code>
<p>Perl documents that the use of \K within assertions is "not well
defined". In PCRE, \K is acted upon when it occurs inside positive
- assertions, but is ignored in negative assertions.</p>
+ assertions, but is ignored in negative assertions. Note that when a
+ pattern such as (?=ab\K) matches, the reported start of the match can
+ be greater than the end of the match.</p>
<p><em>Simple Assertions</em></p>
@@ -2301,7 +2381,8 @@ foo\Kbar</code>
m, inclusive. If a minus character is required in a class, it must be
escaped with a backslash or appear in a position where it cannot be
interpreted as indicating a range, typically as the first or last
- character in the class.</p>
+ character in the class, or immediately after a range. For example, [b-d-z]
+ matches letters in the range b to d, a hyphen character, or z.</p>
<p>The literal character "]" cannot be the end character of a range. A
pattern such as [W-]46] is interpreted as a class of two characters ("W"
@@ -2311,6 +2392,11 @@ foo\Kbar</code>
followed by two other characters. The octal or hexadecimal representation
of "]" can also be used to end a range.</p>
+ <p>An error is generated if a POSIX character class (see below) or an
+ escape sequence other than one that defines a single character appears at
+ a point where a range ending character is expected. For example, [z-\xff]
+ is valid, but [A-\d] and [A-[:digit:]] are not.</p>
+
<p>Ranges operate in the collating sequence of character values. They can
also be used for characters specified numerically, for example,
[\000-\037]. Ranges can include any characters that are valid for the
@@ -2353,7 +2439,8 @@ foo\Kbar</code>
range)</item>
<item>Circumflex (only at the start)</item>
<item>Opening square bracket (only when it can be interpreted as
- introducing a Posix class name; see the next section)</item>
+ introducing a Posix class name, or for a special compatibility
+ feature; see the next two sections)</item>
<item>Terminating closing square bracket</item>
</list>
@@ -2385,16 +2472,18 @@ foo\Kbar</code>
<tag>print</tag><item>Printing characters, including space</item>
<tag>punct</tag><item>Printing characters, excluding letters, digits, and
space</item>
- <tag>space</tag><item>Whitespace (not quite the same as \s)</item>
+ <tag>space</tag><item>Whitespace (the same as \s from PCRE 8.34)</item>
<tag>upper</tag><item>Uppercase letters</item>
<tag>word</tag><item>"Word" characters (same as \w)</item>
<tag>xdigit</tag><item>Hexadecimal digits</item>
</taglist>
- <p>The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13),
- and space (32). Notice that this list includes the VT character (code 11).
- This makes "space" different to \s, which does not include VT (for Perl
- compatibility).</p>
+ <p>The default "space" characters are HT (9), LF (10), VT (11), FF (12),
+ CR (13), and space (32). If locale-specific matching is taking place, the
+ list of space characters may be different; there may be fewer or more of
+ them. "Space" used to be different to \s, which did not include VT, for
+ Perl compatibility. However, Perl changed at release 5.18, and PCRE followed
+ at release 8.34. "Space" and \s now match the same set of characters.</p>
<p>The name "word" is a Perl extension, and "blank" is a GNU extension from
Perl 5.8. Another Perl extension is negation, which is indicated by a ^
@@ -2408,11 +2497,11 @@ foo\Kbar</code>
"ch" is a "collating element", but these are not supported, and an error
is given if they are encountered.</p>
- <p>By default, in UTF modes, characters with values &gt; 255 do not match
+ <p>By default, characters with values &gt; 255 do not match
any of the Posix character classes. However, if option <c>PCRE_UCP</c> is
passed to <c>pcre_compile()</c>, some of the classes are changed so that
- Unicode character properties are used. This is achieved by replacing the
- Posix classes by other sequences, as follows:</p>
+ Unicode character properties are used. This is achieved by replacing
+ certain Posix classes by other sequences, as follows:</p>
<taglist>
<tag>[:alnum:]</tag><item>Becomes <em>\p{Xan}</em></item>
@@ -2425,9 +2514,49 @@ foo\Kbar</code>
<tag>[:word:]</tag><item>Becomes <em>\p{Xwd}</em></item>
</taglist>
- <p>Negated versions, such as [:^alpha:], use \P instead of \p. The other
- Posix classes are unchanged, and match only characters with code points
- &lt; 256.</p>
+ <p>Negated versions, such as [:^alpha:], use \P instead of \p. Three other
+ POSIX classes are handled specially in UCP mode:</p>
+ <taglist>
+ <tag>[:graph:]</tag>
+ <item><p>This matches characters that have glyphs that mark the page
+ when printed. In Unicode property terms, it matches all characters with
+ the L, M, N, P, S, or Cf properties, except for:</p>
+ <taglist>
+ <tag>U+061C</tag><item><p>Arabic Letter Mark</p></item>
+ <tag>U+180E</tag><item><p>Mongolian Vowel Separator</p></item>
+ <tag>U+2066 - U+2069</tag><item><p>Various "isolate"s</p></item>
+ </taglist>
+ </item>
+ <tag>[:print:]</tag>
+ <item><p>This matches the same characters as [:graph:] plus space
+ characters that are not controls, that is, characters with the Zs
+ property.</p></item>
+ <tag>[:punct:]</tag><item><p>This matches all characters that have
+ the Unicode P (punctuation) property, plus those characters whose code
+ points are less than 128 that have the S (Symbol) property.</p></item>
+ </taglist>
+ <p>The other POSIX classes are unchanged, and match only characters with
+ code points less than 128.
+ </p>
+
+ <p><em>Compatibility Feature for Word Boundaries</em></p>
+
+ <p>In the POSIX.2 compliant library that was included in 4.4BSD Unix,
+ the ugly syntax [[:&#60;:]] and [[:&#62;:]] is used for matching "start
+ of word" and "end of word". PCRE treats these items as follows:</p>
+ <taglist>
+ <tag>[[:&#60;:]]</tag><item><p>is converted to \b(?=\w)</p></item>
+ <tag>[[:&#62;:]]</tag><item><p>is converted to \b(?&#60;=\w)</p></item>
+ </taglist>
+ <p>Only these exact character sequences are recognized. A sequence such as
+ [a[:&#60;:]b] provokes error for an unrecognized POSIX class name. This
+ support is not compatible with Perl. It is provided to help migrations from
+ other environments, and is best not used in any new patterns. Note that \b
+ matches at the start and the end of a word (see "Simple assertions" above),
+ and in a Perl-style pattern the preceding or following character normally
+ shows which is wanted, without the need for the assertions that are used
+ above in order to give exactly the POSIX behaviour.</p>
+
</section>
<section>
@@ -2476,8 +2605,7 @@ gilbert|sullivan</code>
<p>When one of these option changes occurs at top-level (that is, not inside
subpattern parentheses), the change applies to the remainder of the
- pattern that follows. If the change is placed right at the start of a
- pattern, PCRE extracts it into the global options.</p>
+ pattern that follows.</p>
<p>An option change within a subpattern (see section
<seealso marker="#sect11">Subpatterns</seealso>) affects only that part of
the subpattern that follows it. So, the following matches abc and aBc and
@@ -2645,9 +2773,9 @@ the ((?:red|white) (king|queen))</code>
parentheses from other parts of the pattern, such as back references,
recursion, and conditions, can be made by name and by number.</p>
- <p>Names consist of up to 32 alphanumeric characters and underscores. Named
- capturing parentheses are still allocated numbers as well as names,
- exactly as if the names were not present.
+ <p>Names consist of up to 32 alphanumeric characters and underscores, but
+ must start with a non-digit. Named capturing parentheses are still allocated
+ numbers as well as names, exactly as if the names were not present.
The <c>capture</c> specification to <seealso marker="#run/3">
<c>run/3</c></seealso> can use named values if they are present in the
regular expression.</p>
@@ -3118,7 +3246,14 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</code>
purposes of numbering the capturing subpatterns in the whole pattern.
However, substring capturing is done only for positive assertions. (Perl
sometimes, but not always, performs capturing in negative assertions.)</p>
-
+ <warning>
+ <p>If a positive assertion containing one or more capturing subpatterns
+ succeeds, but failure to match later in the pattern causes backtracking over
+ this assertion, the captures within the assertion are reset only if no higher
+ numbered captures are already set. This is, unfortunately, a fundamental
+ limitation of the current implementation, and as PCRE1 is now in
+ maintenance-only status, it is unlikely ever to change.</p>
+ </warning>
<p>For compatibility with Perl, assertion subpatterns can be repeated.
However, it makes no sense to assert the same thing many times, the side
effect of capturing parentheses can occasionally be useful. In practice,
@@ -3371,12 +3506,7 @@ abcd$</code>
<p>Perl uses the syntax (?(&lt;name&gt;)...) or (?('name')...) to test for a
used subpattern by name. For compatibility with earlier versions of PCRE,
which had this facility before Perl, the syntax (?(name)...) is also
- recognized. However, there is a possible ambiguity with this syntax, as
- subpattern names can consist entirely of digits. PCRE looks first for a
- named subpattern; if it cannot find one and the name consists entirely of
- digits, PCRE looks for a subpattern of that number, which must be &gt; 0.
- Using subpattern names that consist entirely of digits is not
- recommended.</p>
+ recognized.</p>
<p>Rewriting the previous example to use a named subpattern gives:</p>
@@ -3958,11 +4088,13 @@ a+(*COMMIT)b</code>
2&gt; re:run("xyzabc","(*COMMIT)abc",[{capture,all,list},no_start_optimize]).
nomatch</code>
- <p>PCRE knows that any match must start with "a", so the optimization skips
- along the subject to "a" before running the first match attempt, which
- succeeds. When the optimization is disabled by option
- <c>no_start_optimize</c>, the match starts at "x" and so the (*COMMIT)
- causes it to fail without trying any other starting points.</p>
+ <p>For this pattern, PCRE knows that any match must start with "a", so the
+ optimization skips along the subject to "a" before applying the pattern to the
+ first set of data. The match attempt then succeeds. In the second call the
+ <c>no_start_optimize</c> disables the optimization that skips along to the
+ first character. The pattern is now applied starting at "x", and so the
+ (*COMMIT) causes the match to fail without trying any other starting
+ points.</p>
<p>The following verb causes the match to fail at the current starting
position in the subject if there is a later matching failure that causes
@@ -4138,7 +4270,7 @@ A (B(*THEN)C | (*FAIL)) | D</code>
...(*COMMIT)(*PRUNE)...</code>
<p>If there is a matching failure to the right, backtracking onto (*PRUNE)
- cases it to be triggered, and its action is taken. There can never be a
+ causes it to be triggered, and its action is taken. There can never be a
backtrack onto (*COMMIT).</p>
<p><em>Backtracking Verbs in Repeated Groups</em></p>
diff --git a/lib/stdlib/doc/src/sets.xml b/lib/stdlib/doc/src/sets.xml
index f7668af1ed..4934bed365 100644
--- a/lib/stdlib/doc/src/sets.xml
+++ b/lib/stdlib/doc/src/sets.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2015</year>
+ <year>2000</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -40,7 +40,7 @@
<p>This module provides the same interface as the
<seealso marker="ordsets"><c>ordsets(3)</c></seealso> module
- but with a defined representation. One difference is
+ but with an undefined representation. One difference is
that while this module considers two elements as different if they
do not match (<c>=:=</c>), <c>ordsets</c> considers two elements as
different if and only if they do not compare equal (<c>==</c>).</p>
diff --git a/lib/stdlib/doc/src/shell.xml b/lib/stdlib/doc/src/shell.xml
index d6e8036d4e..2593d3690b 100644
--- a/lib/stdlib/doc/src/shell.xml
+++ b/lib/stdlib/doc/src/shell.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -165,12 +165,12 @@
<item>
<p>Evaluates <c>shell_default:help()</c>.</p>
</item>
- <tag><c>c(File)</c></tag>
+ <tag><c>c(Mod)</c></tag>
<item>
- <p>Evaluates <c>shell_default:c(File)</c>. This compiles
- and loads code in <c>File</c> and purges old versions of
- code, if necessary. Assumes that the file and module names
- are the same.</p>
+ <p>Evaluates <c>shell_default:c(Mod)</c>. This compiles and
+ loads the module <c>Mod</c> and purges old versions of the
+ code, if necessary. <c>Mod</c> can be either a module name or a
+ a source file path, with or without <c>.erl</c> extension.</p>
</item>
<tag><c>catch_exception(Bool)</c></tag>
<item>
@@ -569,7 +569,7 @@ Hello Number: 3378
<pre>
42> <input>E = ets:new(t, []).</input>
-17</pre>
+#Ref&lt;0.1662103692.2407923716.214192></pre>
<p>Command 42 creates an ETS table.</p>
@@ -602,7 +602,7 @@ false</pre>
<pre>
47> <input>E = ets:new(t, []).</input>
-18
+#Ref&lt;0.1662103692.2407923716.214197>
48> <input>ets:insert({d,1,2}).</input>
* exception error: undefined function ets:insert/1</pre>
@@ -617,10 +617,23 @@ true</pre>
<p>Command 49 successfully inserts the tuple into the ETS table.</p>
<pre>
-50> <input>halt().</input>
+50> <input>ets:insert(#Ref&lt;0.1662103692.2407923716.214197>, {e,3,4}).</input>
+true</pre>
+
+ <p>Command 50 inserts another tuple into the ETS table. This time
+ the first argument is the table identifier itself. The shell can
+ parse commands with pids (<c>&lt;0.60.0></c>), ports
+ (<c>#Port&lt;0.536></c>), references
+ (<c>#Ref&lt;0.1662103692.2407792644.214210></c>), and external
+ functions (<c>#Fun&lt;a.b.1></c>), but the command fails unless
+ the corresponding pid, port, reference, or function can be created
+ in the running system.</p>
+
+ <pre>
+51> <input>halt().</input>
strider 2></pre>
- <p>Command 50 exits the Erlang runtime system.</p>
+ <p>Command 51 exits the Erlang runtime system.</p>
</section>
<section>
@@ -854,7 +867,7 @@ q - quit erlang
<c>{history, N}</c>, where <c>N</c> is the current command number. The
function is to return a list of characters or an atom. This
constraint is because of the Erlang I/O protocol. Unicode characters
- beyond code point 255 are allowed in the list. Notice
+ beyond code point 255 are allowed in the list and the atom. Notice
that in restricted mode the call <c>Mod:Func(L)</c> must be
allowed or the default shell prompt function is called.</p>
</section>
diff --git a/lib/stdlib/doc/src/shell_default.xml b/lib/stdlib/doc/src/shell_default.xml
index 81c99bce10..75bf89ba8d 100644
--- a/lib/stdlib/doc/src/shell_default.xml
+++ b/lib/stdlib/doc/src/shell_default.xml
@@ -51,7 +51,7 @@
<p>In command one, module <seealso marker="lists"><c>lists</c></seealso> is
called. In command two, no module name is specified. The shell searches
module <c>user_default</c> followed by module <c>shell_default</c> for
- function <c>foo/1</c>.</p>
+ function <c>c/1</c>.</p>
<p><c>shell_default</c> is intended for "system wide"
customizations to the shell. <c>user_default</c> is intended for
diff --git a/lib/stdlib/doc/src/stdlib_app.xml b/lib/stdlib/doc/src/stdlib_app.xml
index cde73269a8..f857cc394b 100644
--- a/lib/stdlib/doc/src/stdlib_app.xml
+++ b/lib/stdlib/doc/src/stdlib_app.xml
@@ -31,14 +31,14 @@
<app>STDLIB</app>
<appsummary>The STDLIB application.</appsummary>
<description>
- <p>The <c>STDLIB</c> application is mandatory in the sense that the minimal
- system based on Erlang/OTP consists of <c>Kernel</c> and <c>STDLIB</c>.
- The <c>STDLIB</c> application contains no services.</p>
+ <p>The STDLIB application is mandatory in the sense that the minimal
+ system based on Erlang/OTP consists of Kernel and STDLIB.
+ The STDLIB application contains no services.</p>
</description>
<section>
<title>Configuration</title>
- <p>The following configuration parameters are defined for the <c>STDLIB</c>
+ <p>The following configuration parameters are defined for the STDLIB
application. For more information about configuration parameters, see the
<seealso marker="kernel:app"><c>app(4)</c></seealso> module in Kernel.</p>
diff --git a/lib/stdlib/doc/src/string.xml b/lib/stdlib/doc/src/string.xml
index dddedf1132..9d5edd9ecf 100644
--- a/lib/stdlib/doc/src/string.xml
+++ b/lib/stdlib/doc/src/string.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -36,8 +36,617 @@
<modulesummary>String processing functions.</modulesummary>
<description>
<p>This module provides functions for string processing.</p>
+ <p>A string in this module is represented by <seealso marker="unicode#type-chardata">
+ <c>unicode:chardata()</c></seealso>, that is, a list of codepoints,
+ binaries with UTF-8-encoded codepoints
+ (<em>UTF-8 binaries</em>), or a mix of the two.</p>
+ <code>
+"abcd" is a valid string
+&lt;&lt;"abcd">> is a valid string
+["abcd"] is a valid string
+&lt;&lt;"abc..åäö"/utf8>> is a valid string
+&lt;&lt;"abc..åäö">> is NOT a valid string,
+ but a binary with Latin-1-encoded codepoints
+[&lt;&lt;"abc">>, "..åäö"] is a valid string
+[atom] is NOT a valid string</code>
+ <p>
+ This module operates on grapheme clusters. A <em>grapheme cluster</em>
+ is a user-perceived character, which can be represented by several
+ codepoints.
+ </p>
+ <code>
+"å" [229] or [97, 778]
+"e̊" [101, 778]</code>
+ <p>
+ The string length of "ß↑e̊" is 3, even though it is represented by the
+ codepoints <c>[223,8593,101,778]</c> or the UTF-8 binary
+ <c>&lt;&lt;195,159,226,134,145,101,204,138>></c>.
+ </p>
+ <p>
+ Grapheme clusters for codepoints of class <c>prepend</c>
+ and non-modern (or decomposed) Hangul is not handled for performance
+ reasons in
+ <seealso marker="#find/3"><c>find/3</c></seealso>,
+ <seealso marker="#replace/3"><c>replace/3</c></seealso>,
+ <seealso marker="#split/2"><c>split/2</c></seealso>,
+ <seealso marker="#lexemes/2"><c>split/2</c></seealso> and
+ <seealso marker="#trim/3"><c>trim/3</c></seealso>.
+ </p>
+ <p>
+ Splitting and appending strings is to be done on grapheme clusters
+ borders.
+ There is no verification that the results of appending strings are
+ valid or normalized.
+ </p>
+ <p>
+ Most of the functions expect all input to be normalized to one form,
+ see for example <seealso marker="unicode#characters_to_nfc_list/1">
+ <c>unicode:characters_to_nfc_list/1</c></seealso>.
+ </p>
+ <p>
+ Language or locale specific handling of input is not considered
+ in any function.
+ </p>
+ <p>
+ The functions can crash for non-valid input strings. For example,
+ the functions expect UTF-8 binaries but not all functions
+ verify that all binaries are encoded correctly.
+ </p>
+ <p>
+ Unless otherwise specified the return value type is the same as
+ the input type. That is, binary input returns binary output,
+ list input returns a list output, and mixed input can return a
+ mixed output.</p>
+ <code>
+1> string:trim(" sarah ").
+"sarah"
+2> string:trim(&lt;&lt;" sarah ">>).
+&lt;&lt;"sarah">>
+3> string:lexemes("foo bar", " ").
+["foo","bar"]
+4> string:lexemes(&lt;&lt;"foo bar">>, " ").
+[&lt;&lt;"foo">>,&lt;&lt;"bar">>]</code>
+ <p>This module has been reworked in Erlang/OTP 20 to
+ handle <seealso marker="unicode#type-chardata">
+ <c>unicode:chardata()</c></seealso> and operate on grapheme
+ clusters. The <seealso marker="#oldapi"> <c>old
+ functions</c></seealso> that only work on Latin-1 lists as input
+ are still available but should not be
+ used. They will be deprecated in Erlang/OTP 21.
+ </p>
</description>
+ <datatypes>
+ <datatype>
+ <name name="direction"/>
+ <name name="grapheme_cluster"/>
+ <desc>
+ <p>A user-perceived character, consisting of one or more
+ codepoints.</p>
+ </desc>
+ </datatype>
+ </datatypes>
+
+ <funcs>
+
+ <func>
+ <name name="casefold" arity="1"/>
+ <fsummary>Convert a string to a comparable string.</fsummary>
+ <desc>
+ <p>
+ Converts <c><anno>String</anno></c> to a case-agnostic
+ comparable string. Function <c>casefold/1</c> is preferred
+ over <c>lowercase/1</c> when two strings are to be compared
+ for equality. See also <seealso marker="#equal/4"><c>equal/4</c></seealso>.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:casefold("Ω and ẞ SHARP S").</input>
+"ω and ss sharp s"</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="chomp" arity="1"/>
+ <fsummary>Remove trailing end of line control characters.</fsummary>
+ <desc>
+ <p>
+ Returns a string where any trailing <c>\n</c> or
+ <c>\r\n</c> have been removed from <c><anno>String</anno></c>.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+182> <input>string:chomp(&lt;&lt;"\nHello\n\n">>).</input>
+&lt;&lt;"\nHello">>
+183> <input>string:chomp("\nHello\r\r\n").</input>
+"\nHello\r"</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="equal" arity="2"/>
+ <name name="equal" arity="3"/>
+ <name name="equal" arity="4"/>
+ <fsummary>Test string equality.</fsummary>
+ <desc>
+ <p>
+ Returns <c>true</c> if <c><anno>A</anno></c> and
+ <c><anno>B</anno></c> are equal, otherwise <c>false</c>.
+ </p>
+ <p>
+ If <c><anno>IgnoreCase</anno></c> is <c>true</c>
+ the function does <seealso marker="#casefold/1">
+ <c>casefold</c>ing</seealso> on the fly before the equality test.
+ </p>
+ <p>If <c><anno>Norm</anno></c> is not <c>none</c>
+ the function applies normalization on the fly before the equality test.
+ There are four available normalization forms:
+ <seealso marker="unicode#characters_to_nfc_list/1"> <c>nfc</c></seealso>,
+ <seealso marker="unicode#characters_to_nfd_list/1"> <c>nfd</c></seealso>,
+ <seealso marker="unicode#characters_to_nfkc_list/1"> <c>nfkc</c></seealso>, and
+ <seealso marker="unicode#characters_to_nfkd_list/1"> <c>nfkd</c></seealso>.
+ </p>
+ <p>By default,
+ <c><anno>IgnoreCase</anno></c> is <c>false</c> and
+ <c><anno>Norm</anno></c> is <c>none</c>.</p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:equal("åäö", &lt;&lt;"åäö"/utf8>>).</input>
+true
+2> <input>string:equal("åäö", unicode:characters_to_nfd_binary("åäö")).</input>
+false
+3> <input>string:equal("åäö", unicode:characters_to_nfd_binary("ÅÄÖ"), true, nfc).</input>
+true</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="find" arity="2"/>
+ <name name="find" arity="3"/>
+ <fsummary>Find start of substring.</fsummary>
+ <desc>
+ <p>
+ Removes anything before <c><anno>SearchPattern</anno></c> in <c><anno>String</anno></c>
+ and returns the remainder of the string or <c>nomatch</c> if <c><anno>SearchPattern</anno></c> is not
+ found.
+ <c><anno>Dir</anno></c>, which can be <c>leading</c> or
+ <c>trailing</c>, indicates from which direction characters
+ are to be searched.
+ </p>
+ <p>
+ By default, <c><anno>Dir</anno></c> is <c>leading</c>.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:find("ab..cd..ef", ".").</input>
+"..cd..ef"
+2> <input>string:find(&lt;&lt;"ab..cd..ef">>, "..", trailing).</input>
+&lt;&lt;"..ef">>
+3> <input>string:find(&lt;&lt;"ab..cd..ef">>, "x", leading).</input>
+nomatch
+4> <input>string:find("ab..cd..ef", "x", trailing).</input>
+nomatch</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="is_empty" arity="1"/>
+ <fsummary>Check if the string is empty.</fsummary>
+ <desc>
+ <p>Returns <c>true</c> if <c><anno>String</anno></c> is the
+ empty string, otherwise <c>false</c>.</p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:is_empty("foo").</input>
+false
+2> <input>string:is_empty(["",&lt;&lt;>>]).</input>
+true</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="length" arity="1"/>
+ <fsummary>Calculate length of the string.</fsummary>
+ <desc>
+ <p>
+ Returns the number of grapheme clusters in <c><anno>String</anno></c>.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:length("ß↑e̊").</input>
+3
+2> <input>string:length(&lt;&lt;195,159,226,134,145,101,204,138>>).</input>
+3</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="lexemes" arity="2"/>
+ <fsummary>Split string into lexemes.</fsummary>
+ <desc>
+ <p>
+ Returns a list of lexemes in <c><anno>String</anno></c>, separated
+ by the grapheme clusters in <c><anno>SeparatorList</anno></c>.
+ </p>
+ <p>
+ Notice that, as shown in this example, two or more
+ adjacent separator graphemes clusters in <c><anno>String</anno></c>
+ are treated as one. That is, there are no empty
+ strings in the resulting list of lexemes.
+ See also <seealso marker="#split/3"><c>split/3</c></seealso> which returns
+ empty strings.
+ </p>
+ <p>Notice that <c>[$\r,$\n]</c> is one grapheme cluster.</p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:lexemes("abc de̊fxxghix jkl\r\nfoo", "x e" ++ [[$\r,$\n]]).</input>
+["abc","de̊f","ghi","jkl","foo"]
+2> <input>string:lexemes(&lt;&lt;"abc de̊fxxghix jkl\r\nfoo"/utf8>>, "x e" ++ [$\r,$\n]).</input>
+[&lt;&lt;"abc">>,&lt;&lt;"de̊f"/utf8>>,&lt;&lt;"ghi">>,&lt;&lt;"jkl\r\nfoo">>]</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="lowercase" arity="1"/>
+ <fsummary>Convert a string to lowercase</fsummary>
+ <desc>
+ <p>
+ Converts <c><anno>String</anno></c> to lowercase.
+ </p>
+ <p>
+ Notice that function <seealso marker="#casefold/1"><c>casefold/1</c></seealso>
+ should be used when converting a string to
+ be tested for equality.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+2> <input>string:lowercase(string:uppercase("Michał")).</input>
+"michał"</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="next_codepoint" arity="1"/>
+ <fsummary>Pick the first codepoint.</fsummary>
+ <desc>
+ <p>
+ Returns the first codepoint in <c><anno>String</anno></c>
+ and the rest of <c><anno>String</anno></c> in the tail. Returns
+ an empty list if <c><anno>String</anno></c> is empty or an
+ <c>{error, String}</c> tuple if the next byte is invalid.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:next_codepoint(unicode:characters_to_binary("e̊fg")).</input>
+[101|&lt;&lt;"̊fg"/utf8>>]</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="next_grapheme" arity="1"/>
+ <fsummary>Pick the first grapheme cluster.</fsummary>
+ <desc>
+ <p>
+ Returns the first grapheme cluster in <c><anno>String</anno></c>
+ and the rest of <c><anno>String</anno></c> in the tail. Returns
+ an empty list if <c><anno>String</anno></c> is empty or an
+ <c>{error, String}</c> tuple if the next byte is invalid.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:next_grapheme(unicode:characters_to_binary("e̊fg")).</input>
+["e̊"|&lt;&lt;"fg">>]</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="nth_lexeme" arity="3"/>
+ <fsummary>Pick the nth lexeme.</fsummary>
+ <desc>
+ <p>Returns lexeme number <c><anno>N</anno></c> in
+ <c><anno>String</anno></c>, where lexemes are separated by
+ the grapheme clusters in <c><anno>SeparatorList</anno></c>.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:nth_lexeme("abc.de̊f.ghiejkl", 3, ".e").</input>
+"ghi"</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="pad" arity="2"/>
+ <name name="pad" arity="3"/>
+ <name name="pad" arity="4"/>
+ <fsummary>Pad a string to given length.</fsummary>
+ <desc>
+ <p>
+ Pads <c><anno>String</anno></c> to <c><anno>Length</anno></c> with
+ grapheme cluster <c><anno>Char</anno></c>.
+ <c><anno>Dir</anno></c>, which can be <c>leading</c>, <c>trailing</c>,
+ or <c>both</c>, indicates where the padding should be added.
+ </p>
+ <p>By default, <c><anno>Char</anno></c> is <c>$\s</c> and
+ <c><anno>Dir</anno></c> is <c>trailing</c>.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:pad(&lt;&lt;"He̊llö"/utf8>>, 8).</input>
+[&lt;&lt;72,101,204,138,108,108,195,182>>,32,32,32]
+2> <input>io:format("'~ts'~n",[string:pad("He̊llö", 8, leading)]).</input>
+' He̊llö'
+3> <input>io:format("'~ts'~n",[string:pad("He̊llö", 8, both)]).</input>
+' He̊llö '</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="prefix" arity="2"/>
+ <fsummary>Remove prefix from string.</fsummary>
+ <desc>
+ <p>
+ If <c><anno>Prefix</anno></c> is the prefix of
+ <c><anno>String</anno></c>, removes it and returns the
+ remainder of <c><anno>String</anno></c>, otherwise returns
+ <c>nomatch</c>.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:prefix(&lt;&lt;"prefix of string">>, "pre").</input>
+&lt;&lt;"fix of string">>
+2> <input>string:prefix("pre", "prefix").</input>
+nomatch</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="replace" arity="3"/>
+ <name name="replace" arity="4"/>
+ <fsummary>Replace a pattern in string.</fsummary>
+ <desc>
+ <p>
+ Replaces <c><anno>SearchPattern</anno></c> in <c><anno>String</anno></c>
+ with <c><anno>Replacement</anno></c>.
+ <c><anno>Where</anno></c>, default <c>leading</c>, indicates whether
+ the <c>leading</c>, the <c>trailing</c> or <c>all</c> encounters of
+ <c><anno>SearchPattern</anno></c> are to be replaced.
+ </p>
+ <p>Can be implemented as:</p>
+ <pre>lists:join(Replacement, split(String, SearchPattern, Where)).</pre>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:replace(&lt;&lt;"ab..cd..ef">>, "..", "*").</input>
+[&lt;&lt;"ab">>,"*",&lt;&lt;"cd..ef">>]
+2> <input>string:replace(&lt;&lt;"ab..cd..ef">>, "..", "*", all).</input>
+[&lt;&lt;"ab">>,"*",&lt;&lt;"cd">>,"*",&lt;&lt;"ef">>]</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="reverse" arity="1"/>
+ <fsummary>Reverses a string</fsummary>
+ <desc>
+ <p>
+ Returns the reverse list of the grapheme clusters in <c><anno>String</anno></c>.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> Reverse = <input>string:reverse(unicode:characters_to_nfd_binary("ÅÄÖ")).</input>
+[[79,776],[65,776],[65,778]]
+2> <input>io:format("~ts~n",[Reverse]).</input>
+ÖÄÅ</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="slice" arity="2"/>
+ <name name="slice" arity="3"/>
+ <fsummary>Extract a part of string</fsummary>
+ <desc>
+ <p>Returns a substring of <c><anno>String</anno></c> of
+ at most <c><anno>Length</anno></c> grapheme clusters, starting at position
+ <c><anno>Start</anno></c>.</p>
+ <p>By default, <c><anno>Length</anno></c> is <c>infinity</c>.</p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:slice(&lt;&lt;"He̊llö Wörld"/utf8>>, 4).</input>
+&lt;&lt;"ö Wörld"/utf8>>
+2> <input>string:slice(["He̊llö ", &lt;&lt;"Wörld"/utf8>>], 4,4).</input>
+"ö Wö"
+3> <input>string:slice(["He̊llö ", &lt;&lt;"Wörld"/utf8>>], 4,50).</input>
+"ö Wörld"</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="split" arity="2"/>
+ <name name="split" arity="3"/>
+ <fsummary>Split a string into substrings.</fsummary>
+ <desc>
+ <p>
+ Splits <c><anno>String</anno></c> where <c><anno>SearchPattern</anno></c>
+ is encountered and return the remaining parts.
+ <c><anno>Where</anno></c>, default <c>leading</c>, indicates whether
+ the <c>leading</c>, the <c>trailing</c> or <c>all</c> encounters of
+ <c><anno>SearchPattern</anno></c> will split <c><anno>String</anno></c>.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+0> <input>string:split("ab..bc..cd", "..").</input>
+["ab","bc..cd"]
+1> <input>string:split(&lt;&lt;"ab..bc..cd">>, "..", trailing).</input>
+[&lt;&lt;"ab..bc">>,&lt;&lt;"cd">>]
+2> <input>string:split(&lt;&lt;"ab..bc....cd">>, "..", all).</input>
+[&lt;&lt;"ab">>,&lt;&lt;"bc">>,&lt;&lt;>>,&lt;&lt;"cd">>]</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="take" arity="2"/>
+ <name name="take" arity="3"/>
+ <name name="take" arity="4"/>
+ <fsummary>Take leading or trailing parts.</fsummary>
+ <desc>
+ <p>Takes characters from <c><anno>String</anno></c> as long as
+ the characters are members of set <c><anno>Characters</anno></c>
+ or the complement of set <c><anno>Characters</anno></c>.
+ <c><anno>Dir</anno></c>,
+ which can be <c>leading</c> or <c>trailing</c>, indicates from
+ which direction characters are to be taken.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+5> <input>string:take("abc0z123", lists:seq($a,$z)).</input>
+{"abc","0z123"}
+6> <input>string:take(&lt;&lt;"abc0z123">>, lists:seq($0,$9), true, leading).</input>
+{&lt;&lt;"abc">>,&lt;&lt;"0z123">>}
+7> <input>string:take("abc0z123", lists:seq($0,$9), false, trailing).</input>
+{"abc0z","123"}
+8> <input>string:take(&lt;&lt;"abc0z123">>, lists:seq($a,$z), true, trailing).</input>
+{&lt;&lt;"abc0z">>,&lt;&lt;"123">>}</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="titlecase" arity="1"/>
+ <fsummary>Convert a string to titlecase.</fsummary>
+ <desc>
+ <p>
+ Converts <c><anno>String</anno></c> to titlecase.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:titlecase("ß is a SHARP s").</input>
+"Ss is a SHARP s"</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="to_float" arity="1"/>
+ <fsummary>Return a float whose text representation is the integers
+ (ASCII values) of a string.</fsummary>
+ <desc>
+ <p>Argument <c><anno>String</anno></c> is expected to start with a
+ valid text represented float (the digits are ASCII values).
+ Remaining characters in the string after the float are returned in
+ <c><anno>Rest</anno></c>.</p>
+ <p><em>Example:</em></p>
+ <pre>
+> <input>{F1,Fs} = string:to_float("1.0-1.0e-1"),</input>
+> <input>{F2,[]} = string:to_float(Fs),</input>
+> <input>F1+F2.</input>
+0.9
+> <input>string:to_float("3/2=1.5").</input>
+{error,no_float}
+> <input>string:to_float("-1.5eX").</input>
+{-1.5,"eX"}</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="to_integer" arity="1"/>
+ <fsummary>Return an integer whose text representation is the integers
+ (ASCII values) of a string.</fsummary>
+ <desc>
+ <p>Argument <c><anno>String</anno></c> is expected to start with a
+ valid text represented integer (the digits are ASCII values).
+ Remaining characters in the string after the integer are returned in
+ <c><anno>Rest</anno></c>.</p>
+ <p><em>Example:</em></p>
+ <pre>
+> <input>{I1,Is} = string:to_integer("33+22"),</input>
+> <input>{I2,[]} = string:to_integer(Is),</input>
+> <input>I1-I2.</input>
+11
+> <input>string:to_integer("0.5").</input>
+{0,".5"}
+> <input>string:to_integer("x=2").</input>
+{error,no_integer}</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="to_graphemes" arity="1"/>
+ <fsummary>Convert a string to a list of grapheme clusters.</fsummary>
+ <desc>
+ <p>
+ Converts <c><anno>String</anno></c> to a list of grapheme clusters.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:to_graphemes("ß↑e̊").</input>
+[223,8593,[101,778]]
+2> <input>string:to_graphemes(&lt;&lt;"ß↑e̊"/utf8>>).</input>
+[223,8593,[101,778]]</pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="trim" arity="1"/>
+ <name name="trim" arity="2"/>
+ <name name="trim" arity="3"/>
+ <fsummary>Trim leading or trailing, or both, characters.</fsummary>
+ <desc>
+ <p>
+ Returns a string, where leading or trailing, or both,
+ <c><anno>Characters</anno></c> have been removed.
+ <c><anno>Dir</anno></c> which can be <c>leading</c>, <c>trailing</c>,
+ or <c>both</c>, indicates from which direction characters
+ are to be removed.
+ </p>
+ <p> Default <c><anno>Characters</anno></c> are the set of
+ nonbreakable whitespace codepoints, defined as
+ Pattern_White_Space in
+ <url href="http://unicode.org/reports/tr31/">Unicode Standard Annex #31</url>.
+ <c>By default, <anno>Dir</anno></c> is <c>both</c>.
+ </p>
+ <p>
+ Notice that <c>[$\r,$\n]</c> is one grapheme cluster according
+ to the Unicode Standard.
+ </p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:trim("\t Hello \n").</input>
+"Hello"
+2> <input>string:trim(&lt;&lt;"\t Hello \n">>, leading).</input>
+&lt;&lt;"Hello \n">>
+3> <input>string:trim(&lt;&lt;".Hello.\n">>, trailing, "\n.").</input>
+&lt;&lt;".Hello">></pre>
+ </desc>
+ </func>
+
+ <func>
+ <name name="uppercase" arity="1"/>
+ <fsummary>Convert a string to uppercase.</fsummary>
+ <desc>
+ <p>
+ Converts <c><anno>String</anno></c> to uppercase.
+ </p>
+ <p>See also <seealso marker="#titlecase/1"><c>titlecase/1</c></seealso>.</p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>string:uppercase("Michał").</input>
+"MICHAŁ"</pre>
+ </desc>
+ </func>
+
+ </funcs>
+
+ <section>
+ <marker id="oldapi"/>
+ <title>Obsolete API functions</title>
+ <p>Here follows the function of the old API.
+ These functions only work on a list of Latin-1 characters.
+ </p>
+ <note><p>
+ The functions are kept for backward compatibility, but are
+ not recommended.
+ They will be deprecated in Erlang/OTP 21.
+ </p>
+ <p>Any undocumented functions in <c>string</c> are not to be used.</p>
+ </note>
+ </section>
+
<funcs>
<func>
<name name="centre" arity="2"/>
@@ -47,17 +656,24 @@
<p>Returns a string, where <c><anno>String</anno></c> is centered in the
string and surrounded by blanks or <c><anno>Character</anno></c>.
The resulting string has length <c><anno>Number</anno></c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#pad/3"><c>pad/3</c></seealso>.
+ </p>
</desc>
</func>
<func>
<name name="chars" arity="2"/>
<name name="chars" arity="3"/>
- <fsummary>Returns a string consisting of numbers of characters.</fsummary>
+ <fsummary>Return a string consisting of numbers of characters.</fsummary>
<desc>
<p>Returns a string consisting of <c><anno>Number</anno></c> characters
<c><anno>Character</anno></c>. Optionally, the string can end with
string <c><anno>Tail</anno></c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="lists#duplicate/2"><c>lists:duplicate/2</c></seealso>.</p>
</desc>
</func>
@@ -69,6 +685,9 @@
<p>Returns the index of the first occurrence of
<c><anno>Character</anno></c> in <c><anno>String</anno></c>. Returns
<c>0</c> if <c><anno>Character</anno></c> does not occur.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#find/2"><c>find/2</c></seealso>.</p>
</desc>
</func>
@@ -79,6 +698,16 @@
<p>Concatenates <c><anno>String1</anno></c> and
<c><anno>String2</anno></c> to form a new string
<c><anno>String3</anno></c>, which is returned.</p>
+ <p>
+ This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use <c>[<anno>String1</anno>, <anno>String2</anno>]</c> as
+ <c>Data</c> argument, and call
+ <seealso marker="unicode#characters_to_list/2">
+ <c>unicode:characters_to_list/2</c></seealso> or
+ <seealso marker="unicode#characters_to_binary/2">
+ <c>unicode:characters_to_binary/2</c></seealso>
+ to flatten the output.
+ </p>
</desc>
</func>
@@ -88,6 +717,9 @@
<desc>
<p>Returns a string containing <c><anno>String</anno></c> repeated
<c><anno>Number</anno></c> times.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="lists#duplicate/2"><c>lists:duplicate/2</c></seealso>.</p>
</desc>
</func>
@@ -98,6 +730,9 @@
<p>Returns the length of the maximum initial segment of
<c><anno>String</anno></c>, which consists entirely of characters
not from <c><anno>Chars</anno></c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#take/3"><c>take/3</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
> string:cspan("\t abcdef", " \t").
@@ -106,20 +741,14 @@
</func>
<func>
- <name name="equal" arity="2"/>
- <fsummary>Test string equality.</fsummary>
- <desc>
- <p>Returns <c>true</c> if <c><anno>String1</anno></c> and
- <c><anno>String2</anno></c> are equal, otherwise <c>false</c>.</p>
- </desc>
- </func>
-
- <func>
<name name="join" arity="2"/>
<fsummary>Join a list of strings with separator.</fsummary>
<desc>
<p>Returns a string with the elements of <c><anno>StringList</anno></c>
separated by the string in <c><anno>Separator</anno></c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="lists#join/2"><c>lists:join/2</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
> join(["one", "two", "three"], ", ").
@@ -137,6 +766,10 @@
fixed. If <c>length(<anno>String</anno>)</c> &lt;
<c><anno>Number</anno></c>, then <c><anno>String</anno></c> is padded
with blanks or <c><anno>Character</anno></c>s.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#pad/2"><c>pad/2</c></seealso> or
+ <seealso marker="#pad/3"><c>pad/3</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
> string:left("Hello",10,$.).
@@ -149,6 +782,9 @@
<fsummary>Return the length of a string.</fsummary>
<desc>
<p>Returns the number of characters in <c><anno>String</anno></c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#length/1"><c>length/1</c></seealso>.</p>
</desc>
</func>
@@ -160,6 +796,9 @@
<p>Returns the index of the last occurrence of
<c><anno>Character</anno></c> in <c><anno>String</anno></c>. Returns
<c>0</c> if <c><anno>Character</anno></c> does not occur.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#find/3"><c>find/3</c></seealso>.</p>
</desc>
</func>
@@ -173,6 +812,9 @@
fixed. If the length of <c>(<anno>String</anno>)</c> &lt;
<c><anno>Number</anno></c>, then <c><anno>String</anno></c> is padded
with blanks or <c><anno>Character</anno></c>s.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#pad/3"><c>pad/3</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
> string:right("Hello", 10, $.).
@@ -188,6 +830,9 @@
<c><anno>SubString</anno></c> begins in <c><anno>String</anno></c>.
Returns <c>0</c> if <c><anno>SubString</anno></c>
does not exist in <c><anno>String</anno></c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#find/3"><c>find/3</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
> string:rstr(" Hello Hello World World ", "Hello World").
@@ -202,6 +847,9 @@
<p>Returns the length of the maximum initial segment of
<c><anno>String</anno></c>, which consists entirely of characters
from <c><anno>Chars</anno></c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#take/2"><c>take/2</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
> string:span("\t abcdef", " \t").
@@ -217,6 +865,9 @@
<c><anno>SubString</anno></c> begins in <c><anno>String</anno></c>.
Returns <c>0</c> if <c><anno>SubString</anno></c>
does not exist in <c><anno>String</anno></c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#find/2"><c>find/2</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
> string:str(" Hello Hello World World ", "Hello World").
@@ -230,12 +881,15 @@
<name name="strip" arity="3"/>
<fsummary>Strip leading or trailing characters.</fsummary>
<desc>
- <p>Returns a string, where leading and/or trailing blanks or a
+ <p>Returns a string, where leading or trailing, or both, blanks or a
number of <c><anno>Character</anno></c> have been removed.
<c><anno>Direction</anno></c>, which can be <c>left</c>, <c>right</c>,
or <c>both</c>, indicates from which direction blanks are to be
removed. <c>strip/1</c> is equivalent to
<c>strip(String, both)</c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#trim/3"><c>trim/3</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
> string:strip("...Hello.....", both, $.).
@@ -251,6 +905,9 @@
<p>Returns a substring of <c><anno>String</anno></c>, starting at
position <c><anno>Start</anno></c> to the end of the string, or to
and including position <c><anno>Stop</anno></c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#slice/3"><c>slice/3</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
sub_string("Hello World", 4, 8).
@@ -266,6 +923,9 @@ sub_string("Hello World", 4, 8).
<p>Returns a substring of <c><anno>String</anno></c>, starting at
position <c><anno>Start</anno></c>, and ending at the end of the
string or at length <c><anno>Length</anno></c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#slice/3"><c>slice/3</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
> substr("Hello World", 4, 5).
@@ -281,6 +941,9 @@ sub_string("Hello World", 4, 8).
<p>Returns the word in position <c><anno>Number</anno></c> of
<c><anno>String</anno></c>. Words are separated by blanks or
<c><anno>Character</anno></c>s.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#nth_lexeme/3"><c>nth_lexeme/3</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
> string:sub_word(" Hello old boy !",3,$o).
@@ -289,50 +952,6 @@ sub_string("Hello World", 4, 8).
</func>
<func>
- <name name="to_float" arity="1"/>
- <fsummary>Returns a float whose text representation is the integers
- (ASCII values) in a string.</fsummary>
- <desc>
- <p>Argument <c><anno>String</anno></c> is expected to start with a
- valid text represented float (the digits are ASCII values).
- Remaining characters in the string after the float are returned in
- <c><anno>Rest</anno></c>.</p>
- <p><em>Example:</em></p>
- <code type="none">
-> {F1,Fs} = string:to_float("1.0-1.0e-1"),
-> {F2,[]} = string:to_float(Fs),
-> F1+F2.
-0.9
-> string:to_float("3/2=1.5").
-{error,no_float}
-> string:to_float("-1.5eX").
-{-1.5,"eX"}</code>
- </desc>
- </func>
-
- <func>
- <name name="to_integer" arity="1"/>
- <fsummary>Returns an integer whose text representation is the integers
- (ASCII values) in a string.</fsummary>
- <desc>
- <p>Argument <c><anno>String</anno></c> is expected to start with a
- valid text represented integer (the digits are ASCII values).
- Remaining characters in the string after the integer are returned in
- <c><anno>Rest</anno></c>.</p>
- <p><em>Example:</em></p>
- <code type="none">
-> {I1,Is} = string:to_integer("33+22"),
-> {I2,[]} = string:to_integer(Is),
-> I1-I2.
-11
-> string:to_integer("0.5").
-{0,".5"}
-> string:to_integer("x=2").
-{error,no_integer}</code>
- </desc>
- </func>
-
- <func>
<name name="to_lower" arity="1" clause_i="1"/>
<name name="to_lower" arity="1" clause_i="2"/>
<name name="to_upper" arity="1" clause_i="1"/>
@@ -346,6 +965,11 @@ sub_string("Hello World", 4, 8).
<p>The specified string or character is case-converted. Notice that
the supported character set is ISO/IEC 8859-1 (also called Latin 1);
all values outside this set are unchanged</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso> use
+ <seealso marker="#lowercase/1"><c>lowercase/1</c></seealso>,
+ <seealso marker="#uppercase/1"><c>uppercase/1</c></seealso>,
+ <seealso marker="#titlecase/1"><c>titlecase/1</c></seealso> or
+ <seealso marker="#casefold/1"><c>casefold/1</c></seealso>.</p>
</desc>
</func>
@@ -363,6 +987,9 @@ sub_string("Hello World", 4, 8).
adjacent separator characters in <c><anno>String</anno></c>
are treated as one. That is, there are no empty
strings in the resulting list of tokens.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#lexemes/2"><c>lexemes/2</c></seealso>.</p>
</desc>
</func>
@@ -373,6 +1000,9 @@ sub_string("Hello World", 4, 8).
<desc>
<p>Returns the number of words in <c><anno>String</anno></c>, separated
by blanks or <c><anno>Character</anno></c>.</p>
+ <p>This function is <seealso marker="#oldapi">obsolete</seealso>.
+ Use
+ <seealso marker="#lexemes/2"><c>lexemes/2</c></seealso>.</p>
<p><em>Example:</em></p>
<code type="none">
> words(" Hello old boy!", $o).
@@ -387,10 +1017,7 @@ sub_string("Hello World", 4, 8).
other. The reason is that this string package is the
combination of two earlier packages and all functions of
both packages have been retained.</p>
-
- <note>
- <p>Any undocumented functions in <c>string</c> are not to be used.</p>
- </note>
</section>
+
</erlref>
diff --git a/lib/stdlib/doc/src/supervisor.xml b/lib/stdlib/doc/src/supervisor.xml
index 294196f746..6d5065ca02 100644
--- a/lib/stdlib/doc/src/supervisor.xml
+++ b/lib/stdlib/doc/src/supervisor.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2016</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -36,7 +36,6 @@
process can either be another supervisor or a worker process.
Worker processes are normally implemented using one of the
<seealso marker="gen_event"><c>gen_event</c></seealso>,
- <seealso marker="gen_fsm"><c>gen_fsm</c></seealso>,
<seealso marker="gen_server"><c>gen_server</c></seealso>, or
<seealso marker="gen_statem"><c>gen_statem</c></seealso>
behaviors. A supervisor implemented using this module has
@@ -133,8 +132,10 @@ sup_flags() = #{strategy => strategy(), % optional
map. Assuming the values <c>MaxR</c> for <c>intensity</c>
and <c>MaxT</c> for <c>period</c>, then, if more than <c>MaxR</c>
restarts occur within <c>MaxT</c> seconds, the supervisor
- terminates all child processes and then itself. <c>intensity</c>
- defaults to <c>1</c> and <c>period</c> defaults to <c>5</c>.</p>
+ terminates all child processes and then itself. The termination
+ reason for the supervisor itself in that case will be <c>shutdown</c>.
+ <c>intensity</c> defaults to <c>1</c> and <c>period</c> defaults to
+ <c>5</c>.</p>
<marker id="child_spec"/>
<p>The type definition of a child specification is as follows:</p>
@@ -235,8 +236,8 @@ child_spec() = #{id => child_id(), % mandatory
<p><c>modules</c> is used by the release handler during code
replacement to determine which processes are using a certain
module. As a rule of thumb, if the child process is a
- <c>supervisor</c>, <c>gen_server</c>,
- <c>gen_statem</c>, or <c>gen_fsm</c>,
+ <c>supervisor</c>, <c>gen_server</c> or,
+ <c>gen_statem</c>,
this is to be a list with one element <c>[Module]</c>,
where <c>Module</c> is the callback module. If the child
process is an event manager (<c>gen_event</c>) with a
@@ -704,7 +705,6 @@ child_spec() = #{id => child_id(), % mandatory
<section>
<title>See Also</title>
<p><seealso marker="gen_event"><c>gen_event(3)</c></seealso>,
- <seealso marker="gen_fsm"><c>gen_fsm(3)</c></seealso>,
<seealso marker="gen_statem"><c>gen_statem(3)</c></seealso>,
<seealso marker="gen_server"><c>gen_server(3)</c></seealso>,
<seealso marker="sys"><c>sys(3)</c></seealso></p>
diff --git a/lib/stdlib/doc/src/sys.xml b/lib/stdlib/doc/src/sys.xml
index 1120b926d5..64d8789016 100644
--- a/lib/stdlib/doc/src/sys.xml
+++ b/lib/stdlib/doc/src/sys.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2014</year>
+ <year>1996</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -83,8 +83,8 @@
<p>If the modules used to implement the process change dynamically
during runtime, the process must understand one more message. An
example is the <seealso marker="gen_event"><c>gen_event</c></seealso>
- processes. The message is <c>{get_modules, From}</c>.
- The reply to this message is <c>From ! {modules, Modules}</c>, where
+ processes. The message is <c>{_Label, {From, Ref}, get_modules}</c>.
+ The reply to this message is <c>From ! {Ref, Modules}</c>, where
<c>Modules</c> is a list of the currently active modules in the
process.</p>
<p>This message is used by the release handler to find which
@@ -168,12 +168,6 @@
</item>
<item>
<p>For a
- <seealso marker="gen_fsm"><c>gen_fsm</c></seealso>
- process, <c><anno>State</anno></c> is the tuple
- <c>{CurrentStateName, CurrentStateData}</c>.</p>
- </item>
- <item>
- <p>For a
<seealso marker="gen_statem"><c>gen_statem</c></seealso>
process, <c><anno>State</anno></c> is the tuple
<c>{CurrentState,CurrentData}</c>.</p>
@@ -222,7 +216,7 @@
<p>Function <c>system_get_state/1</c> is primarily useful for
user-defined behaviors and modules that implement OTP
<seealso marker="#special_process">special processes</seealso>.
- The <c>gen_server</c>, <c>gen_fsm</c>,
+ The <c>gen_server</c>,
<c>gen_statem</c>, and <c>gen_event</c> OTP
behavior modules export this function, so callback modules for those
behaviors need not to supply their own.</p>
@@ -246,11 +240,6 @@
process returns the state of the callback module.</p>
</item>
<item>
- <p>A <seealso marker="gen_fsm"><c>gen_fsm</c></seealso>
- process returns information, such as its current
- state name and state data.</p>
- </item>
- <item>
<p>A <seealso marker="gen_statem"><c>gen_statem</c></seealso>
process returns information, such as its current
state name and state data.</p>
@@ -262,14 +251,12 @@
</item>
</list>
<p>Callback modules for <c>gen_server</c>,
- <c>gen_fsm</c>, <c>gen_statem</c>, and <c>gen_event</c>
+ <c>gen_statem</c>, and <c>gen_event</c>
can also change the value of <c><anno>Misc</anno></c>
by exporting a function <c>format_status/2</c>, which contributes
module-specific information. For details, see
<seealso marker="gen_server#Module:format_status/2">
<c>gen_server:format_status/2</c></seealso>,
- <seealso marker="gen_fsm#Module:format_status/2">
- <c>gen_fsm:format_status/2</c></seealso>,
<seealso marker="gen_statem#Module:format_status/2">
<c>gen_statem:format_status/2</c></seealso>, and
<seealso marker="gen_event#Module:format_status/2">
@@ -321,7 +308,7 @@
format to the file. The events are formatted with a function that is
defined by the process that generated the event (with a call to
<seealso marker="#handle_debug/4"><c>handle_debug/4</c></seealso>).
- </p>
+ The file is opened with encoding UTF-8.</p>
</desc>
</func>
@@ -373,13 +360,6 @@
is a new instance of that state.</p>
</item>
<item>
- <p>For a <seealso marker="gen_fsm"><c>gen_fsm</c></seealso> process,
- <c><anno>State</anno></c> is the tuple <c>{CurrentStateName,
- CurrentStateData}</c>, and <c><anno>NewState</anno></c> is a
- similar tuple, which can contain
- a new state name, new state data, or both.</p>
- </item>
- <item>
<p>For a <seealso marker="gen_statem"><c>gen_statem</c></seealso>
process, <c><anno>State</anno></c> is the
tuple <c>{CurrentState,CurrentData}</c>,
@@ -422,7 +402,7 @@
return its <c><anno>State</anno></c> argument.</p>
<p>If a <c><anno>StateFun</anno></c> function crashes or throws an
exception, the original state of the process is unchanged for
- <c>gen_server</c>, <c>gen_fsm</c>, and <c>gen_statem</c> processes.
+ <c>gen_server</c>, and <c>gen_statem</c> processes.
For <c>gen_event</c> processes, a crashing or
failing <c><anno>StateFun</anno></c> function
means that only the state of the particular event handler it was
@@ -462,7 +442,7 @@
user-defined behaviors and modules that implement OTP
<seealso marker="#special_process">special processes</seealso>. The
OTP behavior modules <c>gen_server</c>,
- <c>gen_fsm</c>, <c>gen_statem</c>, and <c>gen_event</c>
+ <c>gen_statem</c>, and <c>gen_event</c>
export this function, so callback modules for those
behaviors need not to supply their own.</p>
</desc>
diff --git a/lib/stdlib/doc/src/timer.xml b/lib/stdlib/doc/src/timer.xml
index 8f2ce36b06..fcaccdb2cb 100644
--- a/lib/stdlib/doc/src/timer.xml
+++ b/lib/stdlib/doc/src/timer.xml
@@ -253,7 +253,7 @@
is needed. This is useful during development, but in a
target system the server is to be started explicitly. Use
configuration parameters for
- <seealso marker="kernel:index"><c>Kernel</c></seealso> for this.</p>
+ <seealso marker="kernel:index">Kernel</seealso> for this.</p>
</desc>
</func>
diff --git a/lib/stdlib/doc/src/unicode.xml b/lib/stdlib/doc/src/unicode.xml
index 93d0d37456..e86f45431f 100644
--- a/lib/stdlib/doc/src/unicode.xml
+++ b/lib/stdlib/doc/src/unicode.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1996</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -50,8 +50,35 @@
external entities where this is required. When working inside the
Erlang/OTP environment, it is recommended to keep binaries in UTF-8 when
representing Unicode characters. ISO Latin-1 encoding is supported both
- for backward compatibility and for communication
- with external entities not supporting Unicode character sets.</p>
+ for backward compatibility and for communication
+ with external entities not supporting Unicode character sets.</p>
+ <p>Programs should always operate on a normalized form and compare
+ canonical-equivalent Unicode characters as equal. All characters
+ should thus be normalized to one form once on the system borders.
+ One of the following functions can convert characters to their
+ normalized forms <seealso marker="#characters_to_nfc_list/1">
+ <c>characters_to_nfc_list/1</c></seealso>,
+ <seealso marker="#characters_to_nfc_binary/1">
+ <c>characters_to_nfc_binary/1</c></seealso>,
+ <seealso marker="#characters_to_nfd_list/1">
+ <c>characters_to_nfd_list/1</c></seealso> or
+ <seealso marker="#characters_to_nfd_binary/1">
+ <c>characters_to_nfd_binary/1</c></seealso>.
+ For general text
+ <seealso marker="#characters_to_nfc_list/1">
+ <c>characters_to_nfc_list/1</c></seealso> or
+ <seealso marker="#characters_to_nfc_binary/1">
+ <c>characters_to_nfc_binary/1</c></seealso> is preferred, and
+ for identifiers one of the compatibility normalization
+ functions, such as
+ <seealso marker="#characters_to_nfkc_list/1">
+ <c>characters_to_nfkc_list/1</c></seealso>,
+ is preferred for security reasons.
+ The normalization functions where introduced in OTP 20.
+ Additional information on normalization can be found in the
+ <url href="http://unicode.org/faq/normalization.html">Unicode FAQ</url>.
+ </p>
+
</description>
<datatypes>
@@ -335,6 +362,154 @@ decode_data(Data) ->
</func>
<func>
+ <name name="characters_to_nfc_list" arity="1"/>
+ <fsummary>Normalize characters to a list of canonical equivalent
+ composed Unicode characters.</fsummary>
+ <desc>
+ <p>Converts a possibly deep list of characters and binaries
+ into a Normalized Form of canonical equivalent Composed
+ characters according to the Unicode standard.</p>
+ <p>Any binaries in the input must be encoded with utf8
+ encoding.
+ </p>
+ <p>The result is a list of characters.</p>
+ <code>
+3> unicode:characters_to_nfc_list([&lt;&lt;"abc..a">>,[778],$a,[776],$o,[776]]).
+"abc..åäö"
+</code>
+ </desc>
+ </func>
+
+ <func>
+ <name name="characters_to_nfc_binary" arity="1"/>
+ <fsummary>Normalize characters to a utf8 binary of canonical equivalent
+ composed Unicode characters.</fsummary>
+ <desc>
+ <p>Converts a possibly deep list of characters and binaries
+ into a Normalized Form of canonical equivalent Composed
+ characters according to the Unicode standard.</p>
+ <p>Any binaries in the input must be encoded with utf8
+ encoding.</p>
+ <p>The result is an utf8 encoded binary.</p>
+ <code>
+4> unicode:characters_to_nfc_binary([&lt;&lt;"abc..a">>,[778],$a,[776],$o,[776]]).
+&lt;&lt;"abc..åäö"/utf8>>
+</code>
+ </desc>
+ </func>
+
+ <func>
+ <name name="characters_to_nfd_list" arity="1"/>
+ <fsummary>Normalize characters to a list of canonical equivalent
+ decomposed Unicode characters.</fsummary>
+ <desc>
+ <p>Converts a possibly deep list of characters and binaries
+ into a Normalized Form of canonical equivalent Decomposed
+ characters according to the Unicode standard.</p>
+ <p>Any binaries in the input must be encoded with utf8
+ encoding.
+ </p>
+ <p>The result is a list of characters.</p>
+ <code>
+1> unicode:characters_to_nfd_list("abc..åäö").
+[97,98,99,46,46,97,778,97,776,111,776]
+</code>
+ </desc>
+ </func>
+
+ <func>
+ <name name="characters_to_nfd_binary" arity="1"/>
+ <fsummary>Normalize characters to a utf8 binary of canonical equivalent
+ decomposed Unicode characters.</fsummary>
+ <desc>
+ <p>Converts a possibly deep list of characters and binaries
+ into a Normalized Form of canonical equivalent Decomposed
+ characters according to the Unicode standard.</p>
+ <p>Any binaries in the input must be encoded with utf8
+ encoding.</p>
+ <p>The result is an utf8 encoded binary.</p>
+ <code>
+2> unicode:characters_to_nfd_binary("abc..åäö").
+&lt;&lt;97,98,99,46,46,97,204,138,97,204,136,111,204,136>>
+</code>
+ </desc>
+ </func>
+
+ <func>
+ <name name="characters_to_nfkc_list" arity="1"/>
+ <fsummary>Normalize characters to a list of canonical equivalent
+ composed Unicode characters.</fsummary>
+ <desc>
+ <p>Converts a possibly deep list of characters and binaries
+ into a Normalized Form of compatibly equivalent Composed
+ characters according to the Unicode standard.</p>
+ <p>Any binaries in the input must be encoded with utf8
+ encoding.
+ </p>
+ <p>The result is a list of characters.</p>
+ <code>
+3> unicode:characters_to_nfkc_list([&lt;&lt;"abc..a">>,[778],$a,[776],$o,[776],[65299,65298]]).
+"abc..åäö32"
+</code>
+ </desc>
+ </func>
+
+ <func>
+ <name name="characters_to_nfkc_binary" arity="1"/>
+ <fsummary>Normalize characters to a utf8 binary of compatibly equivalent
+ composed Unicode characters.</fsummary>
+ <desc>
+ <p>Converts a possibly deep list of characters and binaries
+ into a Normalized Form of compatibly equivalent Composed
+ characters according to the Unicode standard.</p>
+ <p>Any binaries in the input must be encoded with utf8
+ encoding.</p>
+ <p>The result is an utf8 encoded binary.</p>
+ <code>
+4> unicode:characters_to_nfkc_binary([&lt;&lt;"abc..a">>,[778],$a,[776],$o,[776],[65299,65298]]).
+&lt;&lt;"abc..åäö32"/utf8>>
+</code>
+ </desc>
+ </func>
+
+ <func>
+ <name name="characters_to_nfkd_list" arity="1"/>
+ <fsummary>Normalize characters to a list of compatibly equivalent
+ decomposed Unicode characters.</fsummary>
+ <desc>
+ <p>Converts a possibly deep list of characters and binaries
+ into a Normalized Form of compatibly equivalent Decomposed
+ characters according to the Unicode standard.</p>
+ <p>Any binaries in the input must be encoded with utf8
+ encoding.
+ </p>
+ <p>The result is a list of characters.</p>
+ <code>
+1> unicode:characters_to_nfkd_list(["abc..åäö",[65299,65298]]).
+[97,98,99,46,46,97,778,97,776,111,776,51,50]
+</code>
+ </desc>
+ </func>
+
+ <func>
+ <name name="characters_to_nfkd_binary" arity="1"/>
+ <fsummary>Normalize characters to a utf8 binary of compatibly equivalent
+ decomposed Unicode characters.</fsummary>
+ <desc>
+ <p>Converts a possibly deep list of characters and binaries
+ into a Normalized Form of compatibly equivalent Decomposed
+ characters according to the Unicode standard.</p>
+ <p>Any binaries in the input must be encoded with utf8
+ encoding.</p>
+ <p>The result is an utf8 encoded binary.</p>
+ <code>
+2> unicode:characters_to_nfkd_binary(["abc..åäö",[65299,65298]]).
+&lt;&lt;97,98,99,46,46,97,204,138,97,204,136,111,204,136,51,50>>
+</code>
+ </desc>
+ </func>
+
+ <func>
<name name="encoding_to_bom" arity="1"/>
<fsummary>Create a binary UTF byte order mark from encoding.</fsummary>
<type_desc variable="Bin">
diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml
index 7f79ac88a1..26dc46719e 100644
--- a/lib/stdlib/doc/src/unicode_usage.xml
+++ b/lib/stdlib/doc/src/unicode_usage.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1999</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -62,6 +62,13 @@
<item><p>In Erlang/OTP 17.0, the encoding default for Erlang
source files was switched to UTF-8.</p></item>
+
+ <item><p>In Erlang/OTP 20.0, atoms and function can contain
+ Unicode characters. Module names, application names, and node
+ names are still restricted to the ISO Latin-1 range.</p>
+ <p>Support was added for normalizations forms in
+ <c>unicode</c> and the <c>string</c> module now handles
+ utf8-encoded binaries.</p></item>
</list>
<p>This section outlines the current Unicode support and gives some
@@ -106,23 +113,27 @@
</item>
</list>
- <p>So, a conversion function must know not only one character at a time,
- but possibly the whole sentence, the natural language to translate to,
- the differences in input and output string length, and so on.
- Erlang/OTP has currently no Unicode <c>to_upper</c>/<c>to_lower</c>
- functionality, but publicly available libraries address these issues.</p>
-
- <p>Another example is the accented characters, where the same glyph has two
- different representations. The Swedish letter "ö" is one example.
- The Unicode standard has a code point for it, but you can also write it
- as "o" followed by "U+0308" (Combining Diaeresis, with the simplified
- meaning that the last letter is to have "¨" above). They have the same
- glyph. They are for most purposes the same, but have different
- representations. For example, MacOS X converts all filenames to use
- Combining Diaeresis, while most other programs (including Erlang) try to
- hide that by doing the opposite when, for example, listing directories.
- However it is done, it is usually important to normalize such
- characters to avoid confusion.</p>
+ <p>So, a conversion function must know not only one character at a
+ time, but possibly the whole sentence, the natural language to
+ translate to, the differences in input and output string length,
+ and so on. Erlang/OTP has currently no Unicode
+ <c>uppercase</c>/<c>lowercase</c> functionality with language
+ specific handling, but publicly available libraries address these
+ issues.</p>
+
+ <p>Another example is the accented characters, where the same
+ glyph has two different representations. The Swedish letter "ö" is
+ one example. The Unicode standard has a code point for it, but
+ you can also write it as "o" followed by "U+0308" (Combining
+ Diaeresis, with the simplified meaning that the last letter is to
+ have "¨" above). They have the same glyph, user perceived
+ character. They are for most purposes the same, but have different
+ representations. For example, MacOS X converts all filenames to
+ use Combining Diaeresis, while most other programs (including
+ Erlang) try to hide that by doing the opposite when, for example,
+ listing directories. However it is done, it is usually important
+ to normalize such characters to avoid confusion.
+ </p>
<p>The list of examples can be made long. One need a kind of knowledge that
was not needed when programs only considered one or two languages. The
@@ -269,13 +280,13 @@
them. In some cases functionality has been added to already
existing interfaces (as the <seealso
marker="stdlib:string"><c>string</c></seealso> module now can
- handle lists with any code points). In some cases new
+ handle strings with any code points). In some cases new
functionality or options have been added (as in the <seealso
marker="stdlib:io"><c>io</c></seealso> module, the file
handling, the <seealso
marker="stdlib:unicode"><c>unicode</c></seealso> module, and
- the bit syntax). Today most modules in <c>Kernel</c> and
- <c>STDLIB</c>, as well as the VM are Unicode-aware.</p>
+ the bit syntax). Today most modules in Kernel and
+ STDLIB, as well as the VM are Unicode-aware.</p>
</item>
<tag>File I/O</tag>
<item>
@@ -339,11 +350,13 @@
<tag>The language</tag>
<item>
<p>Having the source code in UTF-8 also allows you to write string
- literals containing Unicode characters with code points &gt; 255,
- although atoms, module names, and function names are restricted to
- the ISO Latin-1 range. Binary literals, where you use type
+ literals, function names, and atoms containing Unicode
+ characters with code points &gt; 255.
+ Module names, application names, and node names are still restricted
+ to the ISO Latin-1 range. Binary literals, where you use type
<c>/utf8</c>, can also be expressed using Unicode characters &gt; 255.
- Having module names using characters other than 7-bit ASCII can cause
+ Having module names or application names using characters other than
+ 7-bit ASCII can cause
trouble on operating systems with inconsistent file naming schemes,
and can hurt portability, so it is not recommended.</p>
<p>EEP 40 suggests that the language is also to allow for Unicode
@@ -432,15 +445,17 @@ external_charlist() = maybe_improper_list(char() | external_unicode_binary() |
<section>
<title>Basic Language Support</title>
- <p><marker id="unicode_in_erlang"/>As from Erlang/OTP R16, Erlang source
- files can be written in UTF-8 or bytewise (<c>latin1</c>) encoding. For
- information about how to state the encoding of an Erlang source file, see
- the <seealso marker="stdlib:epp#encoding"><c>epp(3)</c></seealso> module.
- Strings and comments can be written using Unicode, but functions must
- still be named using characters from the ISO Latin-1 character set, and
- atoms are restricted to the same ISO Latin-1 range. These restrictions in
- the language are of course independent of the encoding of the source
- file.</p>
+ <p><marker id="unicode_in_erlang"/>As from Erlang/OTP R16, Erlang
+ source files can be written in UTF-8 or bytewise (<c>latin1</c>)
+ encoding. For information about how to state the encoding of an
+ Erlang source file, see the <seealso
+ marker="stdlib:epp#encoding"><c>epp(3)</c></seealso> module. As
+ from Erlang/OTP R16, strings and comments can be written using
+ Unicode. As from Erlang/OTP 20, also atoms and functions can be
+ written using Unicode. Modules, applications, and nodes must still be
+ named using characters from the ISO Latin-1 character set. (These
+ restrictions in the language are independent of the encoding of
+ the source file.)</p>
<section>
<title>Bit Syntax</title>
@@ -765,8 +780,8 @@ Eshell V5.10.1 (abort with ^G)
file system). The Unicode character list is used to denote
filenames or directory names. If the file system content is
listed, you also get Unicode lists as return value. The support
- lies in the <c>Kernel</c> and <c>STDLIB</c> modules, which is why
- most applications (that does not explicitly require the filenames
+ lies in the Kernel and STDLIB modules, which is why
+ most applications (that do not explicitly require the filenames
to be in the ISO Latin-1 range) benefit from the Unicode support
without change.</p>
@@ -843,7 +858,7 @@ Eshell V5.10.1 (abort with ^G)
<title>Notes About Raw Filenames</title>
<marker id="notes-about-raw-filenames"/>
<p>Raw filenames were introduced together with Unicode filename support
- in <c>ERTS</c> 5.8.2 (Erlang/OTP R14B01). The reason &quot;raw
+ in ERTS 5.8.2 (Erlang/OTP R14B01). The reason &quot;raw
filenames&quot; were introduced in the system was
to be able to represent
filenames, specified in different encodings on the same system,
@@ -970,7 +985,7 @@ Eshell V5.10.1 (abort with ^G)
<p>Fortunately, most textual data has been stored in lists and range
checking has been sparse, so modules like <c>string</c> work well for
- Unicode lists with little need for conversion or extension.</p>
+ Unicode strings with little need for conversion or extension.</p>
<p>Some modules are, however, changed to be explicitly Unicode-aware. These
modules include:</p>
@@ -1021,18 +1036,17 @@ Eshell V5.10.1 (abort with ^G)
has extensive support for Unicode text.</p></item>
</taglist>
- <p>The <seealso marker="stdlib:string"><c>string</c></seealso> module works
- perfectly for Unicode strings and ISO Latin-1 strings, except the
- language-dependent functions
- <seealso marker="stdlib:string#to_upper/1"><c>string:to_upper/1</c></seealso>
- and
- <seealso marker="stdlib:string#to_lower/1"><c>string:to_lower/1</c></seealso>,
- which are only correct for the ISO Latin-1 character set. These two
- functions can never function correctly for Unicode characters in their
- current form, as there are language and locale issues as well as
- multi-character mappings to consider when converting text between cases.
- Converting case in an international environment is a large subject not
- yet addressed in OTP.</p>
+ <p>The <seealso marker="stdlib:string"><c>string</c></seealso>
+ module works perfectly for Unicode strings and ISO Latin-1
+ strings, except the language-dependent functions <seealso
+ marker="stdlib:string#uppercase/1"><c>string:uppercase/1</c></seealso>
+ and <seealso
+ marker="stdlib:string#lowercase/1"><c>string:lowercase/1</c></seealso>.
+ These two functions can never function correctly for Unicode
+ characters in their current form, as there are language and locale
+ issues to consider when converting text between cases. Converting
+ case in an international environment is a large subject not yet
+ addressed in OTP.</p>
</section>
<section>
diff --git a/lib/stdlib/doc/src/zip.xml b/lib/stdlib/doc/src/zip.xml
index de23608046..0b5eac1e16 100644
--- a/lib/stdlib/doc/src/zip.xml
+++ b/lib/stdlib/doc/src/zip.xml
@@ -138,7 +138,7 @@
<p>File information as in
<seealso marker="kernel:file#read_file_info/1">
<c>file:read_file_info/1</c></seealso>
- in <c>Kernel</c></p>
+ in Kernel</p>
</item>
<tag><c>comment</c></tag>
<item>
@@ -345,7 +345,7 @@
prepended to filenames when extracting them from the
zip archive. (Acting like
<seealso marker="kernel:file#set_cwd/1">
- <c>file:set_cwd/1</c></seealso> in <c>Kernel</c>,
+ <c>file:set_cwd/1</c></seealso> in Kernel,
but without changing the global <c>cwd</c> property.)</p>
</item>
</taglist>
@@ -420,7 +420,7 @@
(<c>cwd</c>). This is prepended to filenames when adding them,
although not in the zip archive (acting like
<seealso marker="kernel:file#set_cwd/1">
- <c>file:set_cwd/1</c></seealso> in <c>Kernel</c>, but without
+ <c>file:set_cwd/1</c></seealso> in Kernel, but without
changing the global <c>cwd</c> property.).</p>
</item>
<tag><c>{compress, <anno>What</anno>}</c></tag>
diff --git a/lib/stdlib/include/assert.hrl b/lib/stdlib/include/assert.hrl
index 9e5d4eb598..2fbaeba0b2 100644
--- a/lib/stdlib/include/assert.hrl
+++ b/lib/stdlib/include/assert.hrl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright (C) 2004-2016 Richard Carlsson, Mickaël Rémond
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +10,7 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
+%% Copyright (C) 2004-2016 Richard Carlsson, Mickaël Rémond
-ifndef(ASSERT_HRL).
-define(ASSERT_HRL, true).
@@ -56,7 +50,8 @@
%% It is not possible to nest assert macros.
-ifdef(NOASSERT).
--define(assert(BoolExpr),ok).
+-define(assert(BoolExpr), ok).
+-define(assert(BoolExpr, Comment), ok).
-else.
%% The assert macro is written the way it is so as not to cause warnings
%% for clauses that cannot match, even if the expression is a constant or
@@ -79,11 +74,31 @@
end
end)())
end).
+-define(assert(BoolExpr, Comment),
+ begin
+ ((fun () ->
+ __T = is_process_alive(self()), % cheap source of truth
+ case (BoolExpr) of
+ __T -> ok;
+ __V -> erlang:error({assert,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??BoolExpr)},
+ {expected, true},
+ case not __T of
+ __V -> {value, false};
+ _ -> {not_boolean, __V}
+ end]})
+ end
+ end)())
+ end).
-endif.
%% This is the inverse case of assert, for convenience.
-ifdef(NOASSERT).
-define(assertNot(BoolExpr),ok).
+-define(assertNot(BoolExpr, Comment), ok).
-else.
-define(assertNot(BoolExpr),
begin
@@ -103,12 +118,32 @@
end
end)())
end).
+-define(assertNot(BoolExpr, Comment),
+ begin
+ ((fun () ->
+ __F = not is_process_alive(self()),
+ case (BoolExpr) of
+ __F -> ok;
+ __V -> erlang:error({assert,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??BoolExpr)},
+ {expected, false},
+ case not __F of
+ __V -> {value, true};
+ _ -> {not_boolean, __V}
+ end]})
+ end
+ end)())
+ end).
-endif.
%% This is mostly a convenience which gives more detailed reports.
%% Note: Guard is a guarded pattern, and can not be used for value.
-ifdef(NOASSERT).
-define(assertMatch(Guard, Expr), ok).
+-define(assertMatch(Guard, Expr, Comment), ok).
-else.
-define(assertMatch(Guard, Expr),
begin
@@ -124,11 +159,27 @@
end
end)())
end).
+-define(assertMatch(Guard, Expr, Comment),
+ begin
+ ((fun () ->
+ case (Expr) of
+ Guard -> ok;
+ __V -> erlang:error({assertMatch,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern, (??Guard)},
+ {value, __V}]})
+ end
+ end)())
+ end).
-endif.
%% This is the inverse case of assertMatch, for convenience.
-ifdef(NOASSERT).
-define(assertNotMatch(Guard, Expr), ok).
+-define(assertNotMatch(Guard, Expr, Comment), ok).
-else.
-define(assertNotMatch(Guard, Expr),
begin
@@ -145,12 +196,29 @@
end
end)())
end).
+-define(assertNotMatch(Guard, Expr, Comment),
+ begin
+ ((fun () ->
+ __V = (Expr),
+ case __V of
+ Guard -> erlang:error({assertNotMatch,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern, (??Guard)},
+ {value, __V}]});
+ _ -> ok
+ end
+ end)())
+ end).
-endif.
%% This is a convenience macro which gives more detailed reports when
%% the expected LHS value is not a pattern, but a computed value
-ifdef(NOASSERT).
-define(assertEqual(Expect, Expr), ok).
+-define(assertEqual(Expect, Expr, Comment), ok).
-else.
-define(assertEqual(Expect, Expr),
begin
@@ -167,11 +235,28 @@
end
end)())
end).
+-define(assertEqual(Expect, Expr, Comment),
+ begin
+ ((fun () ->
+ __X = (Expect),
+ case (Expr) of
+ __X -> ok;
+ __V -> erlang:error({assertEqual,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {expected, __X},
+ {value, __V}]})
+ end
+ end)())
+ end).
-endif.
%% This is the inverse case of assertEqual, for convenience.
-ifdef(NOASSERT).
-define(assertNotEqual(Unexpected, Expr), ok).
+-define(assertNotEqual(Unexpected, Expr, Comment), ok).
-else.
-define(assertNotEqual(Unexpected, Expr),
begin
@@ -187,12 +272,28 @@
end
end)())
end).
+-define(assertNotEqual(Unexpected, Expr, Comment),
+ begin
+ ((fun () ->
+ __X = (Unexpected),
+ case (Expr) of
+ __X -> erlang:error({assertNotEqual,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {value, __X}]});
+ _ -> ok
+ end
+ end)())
+ end).
-endif.
%% Note: Class and Term are patterns, and can not be used for value.
%% Term can be a guarded pattern, but Class cannot.
-ifdef(NOASSERT).
-define(assertException(Class, Term, Expr), ok).
+-define(assertException(Class, Term, Expr, Comment), ok).
-else.
-define(assertException(Class, Term, Expr),
begin
@@ -222,17 +323,54 @@
end
end)())
end).
+-define(assertException(Class, Term, Expr, Comment),
+ begin
+ ((fun () ->
+ try (Expr) of
+ __V -> erlang:error({assertException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "++(??Term)
+ ++" , [...] }"},
+ {unexpected_success, __V}]})
+ catch
+ Class:Term -> ok;
+ __C:__T ->
+ erlang:error({assertException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "++(??Term)
+ ++" , [...] }"},
+ {unexpected_exception,
+ {__C, __T,
+ erlang:get_stacktrace()}}]})
+ end
+ end)())
+ end).
-endif.
-define(assertError(Term, Expr), ?assertException(error, Term, Expr)).
+-define(assertError(Term, Expr, Comment),
+ ?assertException(error, Term, Expr, Comment)).
-define(assertExit(Term, Expr), ?assertException(exit, Term, Expr)).
+-define(assertExit(Term, Expr, Comment),
+ ?assertException(exit, Term, Expr, Comment)).
-define(assertThrow(Term, Expr), ?assertException(throw, Term, Expr)).
+-define(assertThrow(Term, Expr, Comment),
+ ?assertException(throw, Term, Expr, Comment)).
%% This is the inverse case of assertException, for convenience.
%% Note: Class and Term are patterns, and can not be used for value.
%% Both Class and Term can be guarded patterns.
-ifdef(NOASSERT).
-define(assertNotException(Class, Term, Expr), ok).
+-define(assertNotException(Class, Term, Expr, Comment), ok).
-else.
-define(assertNotException(Class, Term, Expr),
begin
@@ -263,6 +401,36 @@
end
end)())
end).
+-define(assertNotException(Class, Term, Expr, Comment),
+ begin
+ ((fun () ->
+ try (Expr) of
+ _ -> ok
+ catch
+ __C:__T ->
+ case __C of
+ Class ->
+ case __T of
+ Term ->
+ erlang:error({assertNotException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "
+ ++(??Term)++" , [...] }"},
+ {unexpected_exception,
+ {__C, __T,
+ erlang:get_stacktrace()
+ }}]});
+ _ -> ok
+ end;
+ _ -> ok
+ end
+ end
+ end)())
+ end).
-endif.
-endif. % ASSERT_HRL
diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile
index 302834f9d0..bf836203ec 100644
--- a/lib/stdlib/src/Makefile
+++ b/lib/stdlib/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2016. All Rights Reserved.
+# Copyright Ericsson AB 1996-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -51,7 +51,6 @@ MODULES= \
dets_server \
dets_sup \
dets_utils \
- dets_v8 \
dets_v9 \
dict \
digraph \
@@ -59,6 +58,7 @@ MODULES= \
edlin \
edlin_expand \
epp \
+ erl_abstract_code \
erl_anno \
erl_bits \
erl_compile \
@@ -120,6 +120,7 @@ MODULES= \
sys \
timer \
unicode \
+ unicode_util \
win32reg \
zip
@@ -131,7 +132,7 @@ HRL_FILES= \
../include/qlc.hrl \
../include/zip.hrl
-INTERNAL_HRL_FILES= dets.hrl
+INTERNAL_HRL_FILES= dets.hrl erl_tar.hrl
ERL_FILES= $(MODULES:%=%.erl)
@@ -201,6 +202,9 @@ $(APP_TARGET): $(APP_SRC) ../vsn.mk
$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
$(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
+unicode_util.erl: ../uc_spec/*
+ escript ../uc_spec/gen_unicode_mod.escript
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
@@ -225,12 +229,11 @@ $(EBIN)/beam_lib.beam: ../include/erl_compile.hrl ../../kernel/include/file.hrl
$(EBIN)/dets.beam: dets.hrl ../../kernel/include/file.hrl
$(EBIN)/dets_server.beam: dets.hrl
$(EBIN)/dets_utils.beam: dets.hrl
-$(EBIN)/dets_v8.beam: dets.hrl
$(EBIN)/dets_v9.beam: dets.hrl
$(EBIN)/erl_bits.beam: ../include/erl_bits.hrl
$(EBIN)/erl_compile.beam: ../include/erl_compile.hrl ../../kernel/include/file.hrl
$(EBIN)/erl_lint.beam: ../include/erl_bits.hrl
-$(EBIN)/erl_tar.beam: ../../kernel/include/file.hrl
+$(EBIN)/erl_tar.beam: ../../kernel/include/file.hrl erl_tar.hrl
$(EBIN)/file_sorter.beam: ../../kernel/include/file.hrl
$(EBIN)/filelib.beam: ../../kernel/include/file.hrl
$(EBIN)/filename.beam: ../../kernel/include/file.hrl
diff --git a/lib/stdlib/src/array.erl b/lib/stdlib/src/array.erl
index d5757dda5b..079b761463 100644
--- a/lib/stdlib/src/array.erl
+++ b/lib/stdlib/src/array.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,13 +9,12 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-%% @author Richard Carlsson <[email protected]>
+%% Copyright (C) 2006-2016 Richard Carlsson and Ericsson AB
+%%
+%% @author Richard Carlsson <[email protected]>
%% @author Dan Gudmundsson <[email protected]>
-%% @version 1.0
-
+%%
%% @doc Functional, extendible arrays. Arrays can have fixed size, or
%% can grow automatically as needed. A default value is used for entries
%% that have not been explicitly set.
diff --git a/lib/stdlib/src/base64.erl b/lib/stdlib/src/base64.erl
index bf259e6691..5885745fb1 100644
--- a/lib/stdlib/src/base64.erl
+++ b/lib/stdlib/src/base64.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -219,38 +219,49 @@ mime_decode_binary(Result, <<0:8,T/bits>>) ->
mime_decode_binary(Result, T);
mime_decode_binary(Result0, <<C:8,T/bits>>) ->
case element(C, ?DECODE_MAP) of
- Bits when is_integer(Bits) ->
- mime_decode_binary(<<Result0/bits,Bits:6>>, T);
- eq ->
- case tail_contains_more(T, false) of
- {<<>>, Eq} ->
- %% No more valid data.
- case bit_size(Result0) rem 8 of
- 0 ->
- %% '====' is not uncommon.
- Result0;
- 4 when Eq ->
- %% enforce at least one more '=' only ignoring illegals and spacing
- Split = byte_size(Result0) - 1,
- <<Result:Split/bytes,_:4>> = Result0,
- Result;
- 2 ->
- %% remove 2 bits
- Split = byte_size(Result0) - 1,
- <<Result:Split/bytes,_:2>> = Result0,
- Result
- end;
- {More, _} ->
- %% More valid data, skip the eq as invalid
- mime_decode_binary(Result0, More)
- end;
- _ ->
- mime_decode_binary(Result0, T)
+ Bits when is_integer(Bits) ->
+ mime_decode_binary(<<Result0/bits,Bits:6>>, T);
+ eq ->
+ mime_decode_binary_after_eq(Result0, T, false);
+ _ ->
+ mime_decode_binary(Result0, T)
end;
-mime_decode_binary(Result, <<>>) ->
+mime_decode_binary(Result, _) ->
true = is_binary(Result),
Result.
+mime_decode_binary_after_eq(Result, <<0:8,T/bits>>, Eq) ->
+ mime_decode_binary_after_eq(Result, T, Eq);
+mime_decode_binary_after_eq(Result0, <<C:8,T/bits>>, Eq) ->
+ case element(C, ?DECODE_MAP) of
+ bad ->
+ mime_decode_binary_after_eq(Result0, T, Eq);
+ ws ->
+ mime_decode_binary_after_eq(Result0, T, Eq);
+ eq ->
+ mime_decode_binary_after_eq(Result0, T, true);
+ Bits when is_integer(Bits) ->
+ %% More valid data, skip the eq as invalid
+ mime_decode_binary(<<Result0/bits,Bits:6>>, T)
+ end;
+mime_decode_binary_after_eq(Result0, <<>>, Eq) ->
+ %% No more valid data.
+ case bit_size(Result0) rem 8 of
+ 0 ->
+ %% '====' is not uncommon.
+ Result0;
+ 4 when Eq ->
+ %% enforce at least one more '=' only ignoring illegals and spacing
+ Split = byte_size(Result0) - 1,
+ <<Result:Split/bytes,_:4>> = Result0,
+ Result;
+ 2 ->
+ %% remove 2 bits
+ Split = byte_size(Result0) - 1,
+ <<Result:Split/bytes,_:2>> = Result0,
+ Result
+ end.
+
decode([], A) -> A;
decode([$=,$=,C2,C1|Cs], A) ->
Bits2x6 = (b64d(C1) bsl 18) bor (b64d(C2) bsl 12),
diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl
index fe9df601eb..06c15fceda 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -54,8 +54,9 @@
%%-------------------------------------------------------------------------
-type beam() :: module() | file:filename() | binary().
+-type debug_info() :: {DbgiVersion :: atom(), Backend :: module(), Data :: term()} | 'no_debug_info'.
--type forms() :: [erl_parse:abstract_form()].
+-type forms() :: [erl_parse:abstract_form() | erl_parse:form_info()].
-type abst_code() :: {AbstVersion :: atom(), forms()} | 'no_abstract_code'.
-type dataB() :: binary().
@@ -63,8 +64,9 @@
-type label() :: integer().
-type chunkid() :: nonempty_string(). % approximation of the strings below
-%% "Abst" | "Attr" | "CInf" | "ExpT" | "ImpT" | "LocT" | "Atom".
--type chunkname() :: 'abstract_code' | 'attributes' | 'compile_info'
+%% "Abst" | "Dbgi" | "Attr" | "CInf" | "ExpT" | "ImpT" | "LocT" | "Atom" | "AtU8".
+-type chunkname() :: 'abstract_code' | 'debug_info'
+ | 'attributes' | 'compile_info'
| 'exports' | 'labeled_exports'
| 'imports' | 'indexed_imports'
| 'locals' | 'labeled_locals'
@@ -77,6 +79,7 @@
-type chunkdata() :: {chunkid(), dataB()}
| {'abstract_code', abst_code()}
+ | {'debug_info', debug_info()}
| {'attributes', [attrib_entry()]}
| {'compile_info', [compinfo_entry()]}
| {'exports', [{atom(), arity()}]}
@@ -99,7 +102,7 @@
| {'file_error', file:filename(), file:posix()}.
-type chnk_rsn() :: {'unknown_chunk', file:filename(), atom()}
| {'key_missing_or_invalid', file:filename(),
- 'abstract_code'}
+ 'abstract_code' | 'debug_info'}
| info_rsn().
-type cmp_rsn() :: {'modules_different', module(), module()}
| {'chunks_different', chunkid()}
@@ -267,9 +270,9 @@ format_error({modules_different, Module1, Module2}) ->
[Module1, Module2]);
format_error({not_a_directory, Name}) ->
io_lib:format("~tp: Not a directory~n", [Name]);
-format_error({key_missing_or_invalid, File, abstract_code}) ->
- io_lib:format("~tp: Cannot decrypt abstract code because key is missing or invalid",
- [File]);
+format_error({key_missing_or_invalid, File, ChunkId}) ->
+ io_lib:format("~tp: Cannot decrypt ~ts because key is missing or invalid",
+ [File, ChunkId]);
format_error(badfun) ->
"not a fun or the fun has the wrong arity";
format_error(exists) ->
@@ -510,9 +513,9 @@ read_chunk_data(File0, ChunkNames) ->
read_chunk_data(File0, ChunkNames0, Options)
when is_atom(File0); is_list(File0); is_binary(File0) ->
File = beam_filename(File0),
- {ChunkIds, Names} = check_chunks(ChunkNames0, File, [], []),
+ {ChunkIds, Names, Optional} = check_chunks(ChunkNames0, File, [], [], []),
AllowMissingChunks = member(allow_missing_chunks, Options),
- {ok, Module, Chunks} = scan_beam(File, ChunkIds, AllowMissingChunks),
+ {ok, Module, Chunks} = scan_beam(File, ChunkIds, AllowMissingChunks, Optional),
AT = ets:new(beam_symbols, []),
T = {empty, AT},
try chunks_to_data(Names, Chunks, File, Chunks, Module, T, [])
@@ -520,25 +523,34 @@ read_chunk_data(File0, ChunkNames0, Options)
end.
%% -> {ok, list()} | throw(Error)
-check_chunks([ChunkName | Ids], File, IL, L) when is_atom(ChunkName) ->
+check_chunks([atoms | Ids], File, IL, L, O) ->
+ check_chunks(Ids, File, ["Atom", "AtU8" | IL],
+ [{atom_chunk, atoms} | L], ["Atom", "AtU8" | O]);
+check_chunks([abstract_code | Ids], File, IL, L, O) ->
+ check_chunks(Ids, File, ["Abst", "Dbgi" | IL],
+ [{abst_chunk, abstract_code} | L], ["Abst", "Dbgi" | O]);
+check_chunks([ChunkName | Ids], File, IL, L, O) when is_atom(ChunkName) ->
ChunkId = chunk_name_to_id(ChunkName, File),
- check_chunks(Ids, File, [ChunkId | IL], [{ChunkId, ChunkName} | L]);
-check_chunks([ChunkId | Ids], File, IL, L) -> % when is_list(ChunkId)
- check_chunks(Ids, File, [ChunkId | IL], [{ChunkId, ChunkId} | L]);
-check_chunks([], _File, IL, L) ->
- {lists:usort(IL), reverse(L)}.
+ check_chunks(Ids, File, [ChunkId | IL], [{ChunkId, ChunkName} | L], O);
+check_chunks([ChunkId | Ids], File, IL, L, O) -> % when is_list(ChunkId)
+ check_chunks(Ids, File, [ChunkId | IL], [{ChunkId, ChunkId} | L], O);
+check_chunks([], _File, IL, L, O) ->
+ {lists:usort(IL), reverse(L), O}.
%% -> {ok, Module, Data} | throw(Error)
scan_beam(File, What) ->
- scan_beam(File, What, false).
+ scan_beam(File, What, false, []).
%% -> {ok, Module, Data} | throw(Error)
-scan_beam(File, What0, AllowMissingChunks) ->
+scan_beam(File, What0, AllowMissingChunks, OptionalChunks) ->
case scan_beam1(File, What0) of
{missing, _FD, Mod, Data, What} when AllowMissingChunks ->
{ok, Mod, [{Id, missing_chunk} || Id <- What] ++ Data};
- {missing, FD, _Mod, _Data, What} ->
- error({missing_chunk, filename(FD), hd(What)});
+ {missing, FD, Mod, Data, What} ->
+ case What -- OptionalChunks of
+ [] -> {ok, Mod, Data};
+ [Missing | _] -> error({missing_chunk, filename(FD), Missing})
+ end;
R ->
R
end.
@@ -581,18 +593,23 @@ scan_beam(FD, Pos, What, Mod, Data) ->
error({invalid_beam_file, filename(FD), Pos})
end.
-get_data(Cs, "Atom"=Id, FD, Size, Pos, Pos2, _Mod, Data) ->
+get_atom_data(Cs, Id, FD, Size, Pos, Pos2, Data, Encoding) ->
NewCs = del_chunk(Id, Cs),
{NFD, Chunk} = get_chunk(Id, Pos, Size, FD),
<<_Num:32, Chunk2/binary>> = Chunk,
- {Module, _} = extract_atom(Chunk2),
+ {Module, _} = extract_atom(Chunk2, Encoding),
C = case Cs of
info ->
{Id, Pos, Size};
_ ->
{Id, Chunk}
end,
- scan_beam(NFD, Pos2, NewCs, Module, [C | Data]);
+ scan_beam(NFD, Pos2, NewCs, Module, [C | Data]).
+
+get_data(Cs, "Atom" = Id, FD, Size, Pos, Pos2, _Mod, Data) ->
+ get_atom_data(Cs, Id, FD, Size, Pos, Pos2, Data, latin1);
+get_data(Cs, "AtU8" = Id, FD, Size, Pos, Pos2, _Mod, Data) ->
+ get_atom_data(Cs, Id, FD, Size, Pos, Pos2, Data, utf8);
get_data(info, Id, FD, Size, Pos, Pos2, Mod, Data) ->
scan_beam(FD, Pos2, info, Mod, [{Id, Pos, Size} | Data]);
get_data(Chunks, Id, FD, Size, Pos, Pos2, Mod, Data) ->
@@ -624,6 +641,25 @@ get_chunk(Id, Pos, Size, FD) ->
{NFD, Chunk}
end.
+chunks_to_data([{atom_chunk, Name} | CNs], Chunks, File, Cs, Module, Atoms, L) ->
+ {NewAtoms, Ret} = chunk_to_data(Name, <<"">>, File, Cs, Atoms, Module),
+ chunks_to_data(CNs, Chunks, File, Cs, Module, NewAtoms, [Ret | L]);
+chunks_to_data([{abst_chunk, Name} | CNs], Chunks, File, Cs, Module, Atoms, L) ->
+ DbgiChunk = proplists:get_value("Dbgi", Chunks, <<"">>),
+ {NewAtoms, Ret} =
+ case catch chunk_to_data(debug_info, DbgiChunk, File, Cs, Atoms, Module) of
+ {DbgiAtoms, {debug_info, {debug_info_v1, Backend, Metadata}}} ->
+ case Backend:debug_info(erlang_v1, Module, Metadata, []) of
+ {ok, Code} -> {DbgiAtoms, {abstract_code, {raw_abstract_v1, Code}}};
+ {error, _} -> {DbgiAtoms, {abstract_code, no_abstract_code}}
+ end;
+ {error,beam_lib,{key_missing_or_invalid,Path,debug_info}} ->
+ error({key_missing_or_invalid,Path,abstract_code});
+ _ ->
+ AbstChunk = proplists:get_value("Abst", Chunks, <<"">>),
+ chunk_to_data(Name, AbstChunk, File, Cs, Atoms, Module)
+ end,
+ chunks_to_data(CNs, Chunks, File, Cs, Module, NewAtoms, [Ret | L]);
chunks_to_data([{Id, Name} | CNs], Chunks, File, Cs, Module, Atoms, L) ->
{_Id, Chunk} = lists:keyfind(Id, 1, Chunks),
{NewAtoms, Ret} = chunk_to_data(Name, Chunk, File, Cs, Atoms, Module),
@@ -646,13 +682,30 @@ chunk_to_data(compile_info=Id, Chunk, File, _Cs, AtomTable, _Mod) ->
error:badarg ->
error({invalid_chunk, File, chunk_name_to_id(Id, File)})
end;
+chunk_to_data(debug_info=Id, Chunk, File, _Cs, AtomTable, Mod) ->
+ case Chunk of
+ <<>> ->
+ {AtomTable, {Id, no_debug_info}};
+ <<0:8,N:8,Mode0:N/binary,Rest/binary>> ->
+ Mode = binary_to_atom(Mode0, utf8),
+ Term = decrypt_chunk(Mode, Mod, File, Id, Rest),
+ {AtomTable, {Id, Term}};
+ _ ->
+ case catch binary_to_term(Chunk) of
+ {'EXIT', _} ->
+ error({invalid_chunk, File, chunk_name_to_id(Id, File)});
+ Term ->
+ {AtomTable, {Id, Term}}
+ end
+ end;
chunk_to_data(abstract_code=Id, Chunk, File, _Cs, AtomTable, Mod) ->
case Chunk of
<<>> ->
{AtomTable, {Id, no_abstract_code}};
<<0:8,N:8,Mode0:N/binary,Rest/binary>> ->
- Mode = list_to_atom(binary_to_list(Mode0)),
- decrypt_abst(Mode, Mod, File, Id, AtomTable, Rest);
+ Mode = binary_to_atom(Mode0, utf8),
+ Term = decrypt_chunk(Mode, Mod, File, Id, Rest),
+ {AtomTable, {Id, anno_from_term(Term)}};
_ ->
case catch binary_to_term(Chunk) of
{'EXIT', _} ->
@@ -683,7 +736,6 @@ chunk_to_data(ChunkId, Chunk, _File,
_Cs, AtomTable, _Module) when is_list(ChunkId) ->
{AtomTable, {ChunkId, Chunk}}. % Chunk is a binary
-chunk_name_to_id(atoms, _) -> "Atom";
chunk_name_to_id(indexed_imports, _) -> "ImpT";
chunk_name_to_id(imports, _) -> "ImpT";
chunk_name_to_id(exports, _) -> "ExpT";
@@ -692,6 +744,7 @@ chunk_name_to_id(locals, _) -> "LocT";
chunk_name_to_id(labeled_locals, _) -> "LocT";
chunk_name_to_id(attributes, _) -> "Attr";
chunk_name_to_id(abstract_code, _) -> "Abst";
+chunk_name_to_id(debug_info, _) -> "Dbgi";
chunk_name_to_id(compile_info, _) -> "CInf";
chunk_name_to_id(Other, File) ->
error({unknown_chunk, File, Other}).
@@ -738,25 +791,30 @@ atm(AT, N) ->
%% AT is updated.
ensure_atoms({empty, AT}, Cs) ->
- {_Id, AtomChunk} = lists:keyfind("Atom", 1, Cs),
- extract_atoms(AtomChunk, AT),
+ case lists:keyfind("AtU8", 1, Cs) of
+ {_Id, AtomChunk} when is_binary(AtomChunk) ->
+ extract_atoms(AtomChunk, AT, utf8);
+ _ ->
+ {_Id, AtomChunk} = lists:keyfind("Atom", 1, Cs),
+ extract_atoms(AtomChunk, AT, latin1)
+ end,
AT;
ensure_atoms(AT, _Cs) ->
AT.
-extract_atoms(<<_Num:32, B/binary>>, AT) ->
- extract_atoms(B, 1, AT).
+extract_atoms(<<_Num:32, B/binary>>, AT, Encoding) ->
+ extract_atoms(B, 1, AT, Encoding).
-extract_atoms(<<>>, _I, _AT) ->
+extract_atoms(<<>>, _I, _AT, _Encoding) ->
true;
-extract_atoms(B, I, AT) ->
- {Atom, B1} = extract_atom(B),
+extract_atoms(B, I, AT, Encoding) ->
+ {Atom, B1} = extract_atom(B, Encoding),
true = ets:insert(AT, {I, Atom}),
- extract_atoms(B1, I+1, AT).
+ extract_atoms(B1, I+1, AT, Encoding).
-extract_atom(<<Len, B/binary>>) ->
+extract_atom(<<Len, B/binary>>, Encoding) ->
<<SB:Len/binary, Tail/binary>> = B,
- {list_to_atom(binary_to_list(SB)), Tail}.
+ {binary_to_atom(SB, Encoding), Tail}.
%%% Utils.
@@ -856,12 +914,12 @@ significant_chunks() ->
%% for a module. They are listed in the order that they should be MD5:ed.
md5_chunks() ->
- ["Atom", "Code", "StrT", "ImpT", "ExpT", "FunT", "LitT"].
+ ["Atom", "AtU8", "Code", "StrT", "ImpT", "ExpT", "FunT", "LitT"].
%% The following chunks are mandatory in every Beam file.
mandatory_chunks() ->
- ["Code", "ExpT", "ImpT", "StrT", "Atom"].
+ ["Code", "ExpT", "ImpT", "StrT"].
%%% ====================================================================
%%% The rest of the file handles encrypted debug info.
@@ -876,23 +934,18 @@ mandatory_chunks() ->
-define(CRYPTO_KEY_SERVER, beam_lib__crypto_key_server).
-decrypt_abst(Type, Module, File, Id, AtomTable, Bin) ->
+decrypt_chunk(Type, Module, File, Id, Bin) ->
try
KeyString = get_crypto_key({debug_info, Type, Module, File}),
- Key = make_crypto_key(Type, KeyString),
- Term = decrypt_abst_1(Key, Bin),
- {AtomTable, {Id, Term}}
+ {Type,Key,IVec,_BlockSize} = make_crypto_key(Type, KeyString),
+ ok = start_crypto(),
+ NewBin = crypto:block_decrypt(Type, Key, IVec, Bin),
+ binary_to_term(NewBin)
catch
_:_ ->
error({key_missing_or_invalid, File, Id})
end.
-decrypt_abst_1({Type,Key,IVec,_BlockSize}, Bin) ->
- ok = start_crypto(),
- NewBin = crypto:block_decrypt(Type, Key, IVec, Bin),
- Term = binary_to_term(NewBin),
- anno_from_term(Term).
-
anno_from_term({raw_abstract_v1, Forms}) ->
{raw_abstract_v1, anno_from_forms(Forms)};
anno_from_term({Tag, Forms}) when Tag =:= abstract_v1; Tag =:= abstract_v2 ->
diff --git a/lib/stdlib/src/binary.erl b/lib/stdlib/src/binary.erl
index ccc827ca2d..6a64133b45 100644
--- a/lib/stdlib/src/binary.erl
+++ b/lib/stdlib/src/binary.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
-export_type([cp/0]).
--opaque cp() :: {'am' | 'bm', binary()}.
+-opaque cp() :: {'am' | 'bm', reference()}.
-type part() :: {Start :: non_neg_integer(), Length :: integer()}.
%%% BIFs.
diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl
index ad4915eabe..4ab9234b81 100644
--- a/lib/stdlib/src/c.erl
+++ b/lib/stdlib/src/c.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -23,10 +23,10 @@
%% Avoid warning for local function error/2 clashing with autoimported BIF.
-compile({no_auto_import,[error/2]}).
--export([help/0,lc/1,c/1,c/2,nc/1,nc/2, nl/1,l/1,i/0,i/1,ni/0,
+-export([help/0,lc/1,c/1,c/2,c/3,nc/1,nc/2, nl/1,l/1,i/0,i/1,ni/0,
y/1, y/2,
lc_batch/0, lc_batch/1,
- i/3,pid/3,m/0,m/1,
+ i/3,pid/3,m/0,m/1,mm/0,lm/0,
bt/1, q/0,
erlangrc/0,erlangrc/1,bi/1, flush/0, regs/0, uptime/0,
nregs/0,pwd/0,ls/0,ls/1,cd/1,memory/1,memory/0, xm/1]).
@@ -35,7 +35,7 @@
-export([appcall/4]).
-import(lists, [reverse/1,flatten/1,sublist/3,sort/1,keysort/2,
- concat/1,max/1,min/1,foreach/2,foldl/3,flatmap/2]).
+ max/1,min/1,foreach/2,foldl/3,flatmap/2]).
-import(io, [format/1, format/2]).
%%-----------------------------------------------------------------------
@@ -44,7 +44,7 @@
help() ->
io:put_chars(<<"bt(Pid) -- stack backtrace for a process\n"
- "c(File) -- compile and load code in <File>\n"
+ "c(Mod) -- compile and load module or file <Mod>\n"
"cd(Dir) -- change working directory\n"
"flush() -- flush any messages sent to the shell\n"
"help() -- help info\n"
@@ -52,11 +52,13 @@ help() ->
"ni() -- information about the networked system\n"
"i(X,Y,Z) -- information about pid <X,Y,Z>\n"
"l(Module) -- load or reload module\n"
+ "lm() -- load all modified modules\n"
"lc([File]) -- compile a list of Erlang modules\n"
"ls() -- list files in the current directory\n"
"ls(Dir) -- list files in directory <Dir>\n"
"m() -- which modules are loaded\n"
"m(Mod) -- information about module <Mod>\n"
+ "mm() -- list all modified modules\n"
"memory() -- memory allocation information\n"
"memory(T) -- memory allocation information of type <T>\n"
"nc(File) -- compile and load code in <File> on all nodes\n"
@@ -70,32 +72,224 @@ help() ->
"xm(M) -- cross reference check a module\n"
"y(File) -- generate a Yecc parser\n">>).
-%% c(FileName)
-%% Compile a file/module.
-
--spec c(File) -> {'ok', Module} | 'error' when
- File :: file:name(),
- Module :: module().
+%% c(Module)
+%% Compile a module/file.
+
+-spec c(Module) -> {'ok', ModuleName} | 'error' when
+ Module :: file:name(),
+ ModuleName :: module().
+
+c(Module) -> c(Module, []).
+
+-spec c(Module, Options) -> {'ok', ModuleName} | 'error' when
+ Module :: file:name(),
+ Options :: [compile:option()] | compile:option(),
+ ModuleName :: module().
+
+c(Module, SingleOption) when not is_list(SingleOption) ->
+ c(Module, [SingleOption]);
+c(Module, Opts) when is_atom(Module) ->
+ %% either a module name or a source file name (possibly without
+ %% suffix); if such a source file exists, it is used to compile from
+ %% scratch with the given options, otherwise look for an object file
+ Suffix = case filename:extension(Module) of
+ "" -> src_suffix(Opts);
+ S -> S
+ end,
+ SrcFile = filename:rootname(Module, Suffix) ++ Suffix,
+ case filelib:is_file(SrcFile) of
+ true ->
+ compile_and_load(SrcFile, Opts);
+ false ->
+ c(Module, Opts, fun (_) -> true end)
+ end;
+c(Module, Opts) ->
+ %% we never interpret a string as a module name, only as a file
+ compile_and_load(Module, Opts).
-c(File) -> c(File, []).
+%% This tries to find an existing object file and use its compile_info and
+%% source path to recompile the module, overwriting the old object file.
+%% The Filter parameter is applied to the old compile options
--spec c(File, Options) -> {'ok', Module} | 'error' when
- File :: file:name(),
+-spec c(Module, Options, Filter) -> {'ok', ModuleName} | 'error' when
+ Module :: atom(),
Options :: [compile:option()],
- Module :: module().
+ Filter :: fun ((compile:option()) -> boolean()),
+ ModuleName :: module().
+
+c(Module, Options, Filter) when is_atom(Module) ->
+ case find_beam(Module) of
+ BeamFile when is_list(BeamFile) ->
+ c(Module, Options, Filter, BeamFile);
+ Error ->
+ {error, Error}
+ end.
+
+c(Module, Options, Filter, BeamFile) ->
+ case compile_info(Module, BeamFile) of
+ Info when is_list(Info) ->
+ case find_source(BeamFile, Info) of
+ SrcFile when is_list(SrcFile) ->
+ c(SrcFile, Options, Filter, BeamFile, Info);
+ Error ->
+ Error
+ end;
+ Error ->
+ Error
+ end.
-c(File, Opts0) when is_list(Opts0) ->
- Opts = [report_errors,report_warnings|Opts0],
+c(SrcFile, NewOpts, Filter, BeamFile, Info) ->
+ %% Filter old options; also remove options that will be replaced.
+ %% Write new beam over old beam unless other outdir is specified.
+ F = fun (Opt) -> not is_outdir_opt(Opt) andalso Filter(Opt) end,
+ Options = (NewOpts ++ [{outdir,filename:dirname(BeamFile)}]
+ ++ lists:filter(F, old_options(Info))),
+ format("Recompiling ~ts\n", [SrcFile]),
+ safe_recompile(SrcFile, Options, BeamFile).
+
+old_options(Info) ->
+ case lists:keyfind(options, 1, Info) of
+ {options, Opts} -> Opts;
+ false -> []
+ end.
+
+%% prefer the source path in the compile info if the file exists,
+%% otherwise do a standard source search relative to the beam file
+find_source(BeamFile, Info) ->
+ case lists:keyfind(source, 1, Info) of
+ {source, SrcFile} ->
+ case filelib:is_file(SrcFile) of
+ true -> SrcFile;
+ false -> find_source(BeamFile)
+ end;
+ _ ->
+ find_source(BeamFile)
+ end.
+
+find_source(BeamFile) ->
+ case filelib:find_source(BeamFile) of
+ {ok, SrcFile} -> SrcFile;
+ _ -> {error, no_source}
+ end.
+
+%% find the beam file for a module, preferring the path reported by code:which()
+%% if it still exists, or otherwise by searching the code path
+find_beam(Module) when is_atom(Module) ->
+ case code:which(Module) of
+ Beam when is_list(Beam), Beam =/= "" ->
+ case erlang:module_loaded(Module) of
+ false ->
+ Beam; % code:which/1 found this in the path
+ true ->
+ case filelib:is_file(Beam) of
+ true -> Beam;
+ false -> find_beam_1(Module) % file moved?
+ end
+ end;
+ Other when Other =:= ""; Other =:= cover_compiled ->
+ %% module is loaded but not compiled directly from source
+ find_beam_1(Module);
+ Error ->
+ Error
+ end.
+
+find_beam_1(Module) ->
+ File = atom_to_list(Module) ++ code:objfile_extension(),
+ case code:where_is_file(File) of
+ Beam when is_list(Beam) ->
+ Beam;
+ Error ->
+ Error
+ end.
+
+%% get the compile_info for a module
+%% -will report the info for the module in memory, if loaded
+%% -will try to find and examine the beam file if not in memory
+%% -will not cause a module to become loaded by accident
+compile_info(Module, Beam) when is_atom(Module) ->
+ case erlang:module_loaded(Module) of
+ true ->
+ %% getting the compile info for a loaded module should normally
+ %% work, but return an empty info list if it fails
+ try erlang:get_module_info(Module, compile)
+ catch _:_ -> []
+ end;
+ false ->
+ case beam_lib:chunks(Beam, [compile_info]) of
+ {ok, {_Module, [{compile_info, Info}]}} ->
+ Info;
+ Error ->
+ Error
+ end
+ end.
+
+%% compile module, backing up any existing target file and restoring the
+%% old version if compilation fails (this should only be used when we have
+%% an old beam file that we want to preserve)
+safe_recompile(File, Options, BeamFile) ->
+ %% Note that it's possible that because of options such as 'to_asm',
+ %% the compiler might not actually write a new beam file at all
+ Backup = BeamFile ++ ".bak",
+ case file:rename(BeamFile, Backup) of
+ Status when Status =:= ok; Status =:= {error,enoent} ->
+ case compile_and_load(File, Options) of
+ {ok, _} = Result ->
+ _ = if Status =:= ok -> file:delete(Backup);
+ true -> ok
+ end,
+ Result;
+ Error ->
+ _ = if Status =:= ok -> file:rename(Backup, BeamFile);
+ true -> ok
+ end,
+ Error
+ end;
+ Error ->
+ Error
+ end.
+
+%% Compile the file and load the resulting object code (if any).
+%% Automatically ensures that there is an outdir option, by default the
+%% directory of File, and that a 'from' option will be passed to match the
+%% actual source suffix if needed (unless already specified).
+compile_and_load(File, Opts0) when is_list(Opts0) ->
+ Opts = [report_errors, report_warnings
+ | ensure_from(filename:extension(File),
+ ensure_outdir(filename:dirname(File), Opts0))],
case compile:file(File, Opts) of
{ok,Mod} -> %Listing file.
- machine_load(Mod, File, Opts);
+ purge_and_load(Mod, File, Opts);
{ok,Mod,_Ws} -> %Warnings maybe turned on.
- machine_load(Mod, File, Opts);
+ purge_and_load(Mod, File, Opts);
Other -> %Errors go here
Other
end;
-c(File, Opt) ->
- c(File, [Opt]).
+compile_and_load(File, Opt) ->
+ compile_and_load(File, [Opt]).
+
+ensure_from(Suffix, Opts0) ->
+ case lists:partition(fun is_from_opt/1, Opts0++from_opt(Suffix)) of
+ {[Opt|_], Opts} -> [Opt | Opts];
+ {[], Opts} -> Opts
+ end.
+
+ensure_outdir(Dir, Opts0) ->
+ {[Opt|_], Opts} = lists:partition(fun is_outdir_opt/1,
+ Opts0++[{outdir,Dir}]),
+ [Opt | Opts].
+
+is_outdir_opt({outdir, _}) -> true;
+is_outdir_opt(_) -> false.
+
+is_from_opt(from_core) -> true;
+is_from_opt(from_asm) -> true;
+is_from_opt(from_beam) -> true;
+is_from_opt(_) -> false.
+
+from_opt(".core") -> [from_core];
+from_opt(".S") -> [from_asm];
+from_opt(".beam") -> [from_beam];
+from_opt(_) -> [].
%%% Obtain the 'outdir' option from the argument. Return "." if no
%%% such option was given.
@@ -111,18 +305,29 @@ outdir([Opt|Rest]) ->
outdir(Rest)
end.
+%% mimic how suffix is selected in compile:file().
+src_suffix([from_core|_]) -> ".core";
+src_suffix([from_asm|_]) -> ".S";
+src_suffix([from_beam|_]) -> ".beam";
+src_suffix([_|Opts]) -> src_suffix(Opts);
+src_suffix([]) -> ".erl".
+
%%% We have compiled File with options Opts. Find out where the
-%%% output file went to, and load it.
-machine_load(Mod, File, Opts) ->
+%%% output file went and load it, purging any old version.
+purge_and_load(Mod, File, Opts) ->
Dir = outdir(Opts),
- File2 = filename:join(Dir, filename:basename(File, ".erl")),
+ Base = filename:basename(File, src_suffix(Opts)),
+ OutFile = filename:join(Dir, Base),
case compile:output_generated(Opts) of
true ->
- Base = atom_to_list(Mod),
- case filename:basename(File, ".erl") of
+ case atom_to_list(Mod) of
Base ->
code:purge(Mod),
- check_load(code:load_abs(File2,Mod), Mod);
+ %% Note that load_abs() adds the object file suffix
+ case code:load_abs(OutFile, Mod) of
+ {error, _R}=Error -> Error;
+ _ -> {ok, Mod}
+ end;
_OtherMod ->
format("** Module name '~p' does not match file name '~tp' **~n",
[Mod,File]),
@@ -133,13 +338,6 @@ machine_load(Mod, File, Opts) ->
ok
end.
-%%% This function previously warned if the loaded module was
-%%% loaded from some other place than current directory.
-%%% Now, loading from other than current directory is supposed to work.
-%%% so this function does nothing special.
-check_load({error, _R} = Error, _) -> Error;
-check_load(_, Mod) -> {ok, Mod}.
-
%% Compile a list of modules
%% enables the nice unix shell cmd
%% erl -s c lc f1 f2 f3 @d c1=v1 @c2 @i IDir @o ODir -s erlang halt
@@ -202,7 +400,7 @@ split_def([], Res) -> {d, list_to_atom(reverse(Res))}.
make_term(Str) ->
case erl_scan:string(Str) of
{ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens ++ [{dot, 1}]) of
+ case erl_parse:parse_term(Tokens ++ [{dot, erl_anno:new(1)}]) of
{ok, Term} -> Term;
{error, {_,_,Reason}} ->
io:format("~ts: ~ts~n", [Reason, Str]),
@@ -350,7 +548,7 @@ mfa_string(Fun) when is_function(Fun) ->
{arity,A} = erlang:fun_info(Fun, arity),
mfa_string({M,F,A});
mfa_string({M,F,A}) ->
- io_lib:format("~w:~w/~w", [M,F,A]);
+ io_lib:format("~w:~tw/~w", [M,F,A]);
mfa_string(X) ->
w(X).
@@ -374,7 +572,7 @@ display_info(Pid) ->
w(Reds), w(LM)),
iformat(case fetch(registered_name, Info) of
0 -> "";
- X -> w(X)
+ X -> io_lib:format("~tw", [X])
end,
mfa_string(Curr),
w(SS),
@@ -396,7 +594,7 @@ initial_call(Info) ->
end.
iformat(A1, A2, A3, A4, A5) ->
- format("~-21s ~-33s ~8s ~8s ~4s~n", [A1,A2,A3,A4,A5]).
+ format("~-21ts ~-33ts ~8s ~8s ~4s~n", [A1,A2,A3,A4,A5]).
all_procs() ->
case is_alive() of
@@ -459,6 +657,16 @@ m() ->
mformat(A1, A2) ->
format("~-20s ~ts\n", [A1,A2]).
+-spec mm() -> [module()].
+
+mm() ->
+ code:modified_modules().
+
+-spec lm() -> [code:load_ret()].
+
+lm() ->
+ [l(M) || M <- mm()].
+
%% erlangrc(Home)
%% Try to run a ".erlang" file, first in the current directory
%% else in home directory.
@@ -559,7 +767,7 @@ print_exports(X) when length(X) > 16 ->
split_print_exports(X);
print_exports([]) -> ok;
print_exports([{F, A} |Tail]) ->
- format(" ~w/~w~n",[F, A]),
+ format(" ~tw/~w~n",[F, A]),
print_exports(Tail).
split_print_exports(L) ->
@@ -571,11 +779,11 @@ split_print_exports(L) ->
split_print_exports([], [{F, A}|T]) ->
Str = " ",
- format("~-30s~w/~w~n", [Str, F, A]),
+ format("~-30ts~tw/~w~n", [Str, F, A]),
split_print_exports([], T);
split_print_exports([{F1, A1}|T1], [{F2, A2} | T2]) ->
- Str = flatten(io_lib:format("~w/~w", [F1, A1])),
- format("~-30s~w/~w~n", [Str, F2, A2]),
+ Str = flatten(io_lib:format("~tw/~w", [F1, A1])),
+ format("~-30ts~tw/~w~n", [Str, F2, A2]),
split_print_exports(T1, T2);
split_print_exports([], []) -> ok.
@@ -675,22 +883,22 @@ procline(Name, Info, Pid) ->
Call = initial_call(Info),
Reds = fetch(reductions, Info),
LM = length(fetch(messages, Info)),
- procformat(io_lib:format("~w",[Name]),
+ procformat(io_lib:format("~tw",[Name]),
io_lib:format("~w",[Pid]),
- io_lib:format("~s",[mfa_string(Call)]),
+ io_lib:format("~ts",[mfa_string(Call)]),
integer_to_list(Reds), integer_to_list(LM)).
procformat(Name, Pid, Call, Reds, LM) ->
- format("~-21s ~-12s ~-25s ~12s ~4s~n", [Name,Pid,Call,Reds,LM]).
+ format("~-21ts ~-12s ~-25ts ~12s ~4s~n", [Name,Pid,Call,Reds,LM]).
portline(Name, Info, Id) ->
Cmd = fetch(name, Info),
- portformat(io_lib:format("~w",[Name]),
+ portformat(io_lib:format("~tw",[Name]),
erlang:port_to_list(Id),
Cmd).
portformat(Name, Id, Cmd) ->
- format("~-21s ~-15s ~-40s~n", [Name,Id,Cmd]).
+ format("~-21ts ~-15s ~-40ts~n", [Name,Id,Cmd]).
%% pwd()
%% cd(Directory)
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl
index bf22949870..10e8c9c800 100644
--- a/lib/stdlib/src/dets.erl
+++ b/lib/stdlib/src/dets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -105,9 +105,6 @@
%%% the file with the split indicator, size etc is held in ram by the
%%% server at all times.
%%%
-%%% The parts specific for formats up to and including 8(c) are
-%%% implemented in dets_v8.erl, parts specific for format 9 are
-%%% implemented in dets_v9.erl.
%% The method of hashing is the so called linear hashing algorithm
%% with segments.
@@ -140,28 +137,33 @@
%%% written, and a repair is forced next time the file is opened.
-record(dets_cont, {
- what, % object | bindings | select | bchunk
- no_objs, % requested number of objects: default | integer() > 0
- bin, % small chunk not consumed, or 'eof' at end-of-file
- alloc, % the part of the file not yet scanned, mostly a binary
- tab,
- proc, % the pid of the Dets process
- match_program % true | compiled_match_spec() | undefined
+ what :: 'undefined' | 'bchunk' | 'bindings' | 'object' | 'select',
+ no_objs :: 'default' | pos_integer(), % requested number of objects
+ bin :: 'eof' | binary(), % small chunk not consumed,
+ % or 'eof' at end-of-file
+ alloc :: binary() % the part of the file not yet scanned
+ | {From :: non_neg_integer(),
+ To :: non_neg_integer,
+ binary()},
+ tab :: tab_name(),
+ proc :: 'undefined' | pid(), % the pid of the Dets process
+ match_program :: 'true'
+ | 'undefined'
+ | {'match_spec', ets:comp_match_spec()}
}).
-record(open_args, {
- file,
- type,
- keypos,
- repair,
- min_no_slots,
- max_no_slots,
- ram_file,
- delayed_write,
- auto_save,
- access,
- version,
- debug
+ file :: list(),
+ type :: type(),
+ keypos :: keypos(),
+ repair :: 'force' | boolean(),
+ min_no_slots :: no_slots(),
+ max_no_slots :: no_slots(),
+ ram_file :: boolean(),
+ delayed_write :: cache_parms(),
+ auto_save :: auto_save(),
+ access :: access(),
+ debug :: boolean()
}).
-define(PATTERN_TO_OBJECT_MATCH_SPEC(Pat), [{Pat,[],['$_']}]).
@@ -177,20 +179,13 @@
%%-define(PROFILE(C), C).
-define(PROFILE(C), void).
--type access() :: 'read' | 'read_write'.
--type auto_save() :: 'infinity' | non_neg_integer().
-opaque bindings_cont() :: #dets_cont{}.
-opaque cont() :: #dets_cont{}.
--type keypos() :: pos_integer().
-type match_spec() :: ets:match_spec().
-type object() :: tuple().
--type no_slots() :: non_neg_integer() | 'default'.
-opaque object_cont() :: #dets_cont{}.
-type pattern() :: atom() | tuple().
-opaque select_cont() :: #dets_cont{}.
--type tab_name() :: term().
--type type() :: 'bag' | 'duplicate_bag' | 'set'.
--type version() :: 8 | 9 | 'default'.
%%% Some further debug code was added in R12B-1 (stdlib-1.15.1):
%%% - there is a new open_file() option 'debug';
@@ -273,19 +268,20 @@ delete_all_objects(Tab) ->
delete_object(Tab, O) ->
badarg(treq(Tab, {delete_object, [O]}), [Tab, O]).
+%% Backwards compatibility.
+fsck(Fname, _Version) ->
+ fsck(Fname).
+
%% Given a filename, fsck it. Debug.
fsck(Fname) ->
- fsck(Fname, default).
-
-fsck(Fname, Version) ->
catch begin
{ok, Fd, FH} = read_file_header(Fname, read, false),
?DEBUGF("FileHeader: ~p~n", [FH]),
- case (FH#fileheader.mod):check_file_header(FH, Fd) of
+ case dets_v9:check_file_header(FH, Fd) of
{error, not_closed} ->
- fsck(Fd, make_ref(), Fname, FH, default, default, Version);
- {ok, _Head, _Extra} ->
- fsck(Fd, make_ref(), Fname, FH, default, default, Version);
+ fsck(Fd, make_ref(), Fname, FH, default, default);
+ {ok, _Head} ->
+ fsck(Fd, make_ref(), Fname, FH, default, default);
Error ->
Error
end
@@ -372,7 +368,7 @@ info(Tab) ->
Item :: 'access' | 'auto_save' | 'bchunk_format'
| 'hash' | 'file_size' | 'filename' | 'keypos' | 'memory'
| 'no_keys' | 'no_objects' | 'no_slots' | 'owner' | 'ram_file'
- | 'safe_fixed' | 'safe_fixed_monotonic_time' | 'size' | 'type' | 'version',
+ | 'safe_fixed' | 'safe_fixed_monotonic_time' | 'size' | 'type',
Value :: term().
info(Tab, owner) ->
@@ -640,8 +636,7 @@ open_file(File) ->
| {'keypos', keypos()}
| {'ram_file', boolean()}
| {'repair', boolean() | 'force'}
- | {'type', type()}
- | {'version', version()},
+ | {'type', type()},
Reason :: term().
open_file(Tab, Args) when is_list(Args) ->
@@ -674,13 +669,13 @@ remove_user(Pid, From) ->
Continuation2 :: select_cont(),
MatchSpec :: match_spec().
-repair_continuation(#dets_cont{match_program = B}=Cont, MS)
- when is_binary(B) ->
+repair_continuation(#dets_cont{match_program = {match_spec, B}}=Cont, MS) ->
case ets:is_compiled_ms(B) of
true ->
Cont;
false ->
- Cont#dets_cont{match_program = ets:match_spec_compile(MS)}
+ Cont#dets_cont{match_program = {match_spec,
+ ets:match_spec_compile(MS)}}
end;
repair_continuation(#dets_cont{}=Cont, _MS) ->
Cont;
@@ -999,7 +994,9 @@ init_chunk_match(Tab, Pat, What, N, Safe) when is_integer(N), N >= 0;
case req(Proc, {match, MP, Spec, N, Safe}) of
{done, L} ->
{L, #dets_cont{tab = Tab, proc = Proc,
- what = What, bin = eof}};
+ what = What, bin = eof,
+ no_objs = default,
+ alloc = <<>>}};
{cont, State} ->
chunk_match(State#dets_cont{what = What,
tab = Tab,
@@ -1041,17 +1038,17 @@ chunk_match(#dets_cont{proc = Proc}=State, Safe) ->
do_foldl_bins(Bins, true) ->
foldl_bins(Bins, []);
-do_foldl_bins(Bins, MP) ->
+do_foldl_bins(Bins, {match_spec, MP}) ->
foldl_bins(Bins, MP, []).
foldl_bins([], Terms) ->
- %% Preserve time order (version 9).
+ %% Preserve time order.
Terms;
foldl_bins([Bin | Bins], Terms) ->
foldl_bins(Bins, [binary_to_term(Bin) | Terms]).
foldl_bins([], _MP, Terms) ->
- %% Preserve time order (version 9).
+ %% Preserve time order.
Terms;
foldl_bins([Bin | Bins], MP, Terms) ->
Term = binary_to_term(Bin),
@@ -1066,11 +1063,8 @@ foldl_bins([Bin | Bins], MP, Terms) ->
compile_match_spec(select, ?PATTERN_TO_OBJECT_MATCH_SPEC('_') = Spec) ->
{Spec, true};
compile_match_spec(select, Spec) ->
- case catch ets:match_spec_compile(Spec) of
- X when is_binary(X) ->
- {Spec, X};
- _ ->
- badarg
+ try {Spec, {match_spec, ets:match_spec_compile(Spec)}}
+ catch error:_ -> badarg
end;
compile_match_spec(object, Pat) ->
compile_match_spec(select, ?PATTERN_TO_OBJECT_MATCH_SPEC(Pat));
@@ -1091,16 +1085,10 @@ defaults(Tab, Args) ->
delayed_write = ?DEFAULT_CACHE,
auto_save = timer:minutes(?DEFAULT_AUTOSAVE),
access = read_write,
- version = default,
debug = false},
Fun = fun repl/2,
Defaults = lists:foldl(Fun, Defaults0, Args),
- case Defaults#open_args.version of
- 8 ->
- Defaults#open_args{max_no_slots = default};
- _ ->
- is_comp_min_max(Defaults)
- end.
+ is_comp_min_max(Defaults).
to_list(T) when is_atom(T) -> atom_to_list(T);
to_list(T) -> T.
@@ -1131,7 +1119,6 @@ repl({file, File}, Defs) when is_atom(File) ->
repl({keypos, P}, Defs) when is_integer(P), P > 0 ->
Defs#open_args{keypos =P};
repl({max_no_slots, I}, Defs) ->
- %% Version 9 only.
MaxSlots = is_max_no_slots(I),
Defs#open_args{max_no_slots = MaxSlots};
repl({min_no_slots, I}, Defs) ->
@@ -1147,8 +1134,9 @@ repl({type, T}, Defs) ->
mem(T, [set, bag, duplicate_bag]),
Defs#open_args{type =T};
repl({version, Version}, Defs) ->
- V = is_version(Version),
- Defs#open_args{version = V};
+ %% Backwards compatibility.
+ is_version(Version),
+ Defs;
repl({debug, Bool}, Defs) ->
%% Not documented.
mem(Bool, [true, false]),
@@ -1164,16 +1152,15 @@ is_max_no_slots(default) -> default;
is_max_no_slots(I) when is_integer(I), I > 0, I < 1 bsl 31 -> I.
is_comp_min_max(Defs) ->
- #open_args{max_no_slots = Max, min_no_slots = Min, version = V} = Defs,
- case V of
- _ when Min =:= default -> Defs;
- _ when Max =:= default -> Defs;
- _ -> true = Min =< Max, Defs
+ #open_args{max_no_slots = Max, min_no_slots = Min} = Defs,
+ if
+ Min =:= default -> Defs;
+ Max =:= default -> Defs;
+ true -> true = Min =< Max, Defs
end.
-is_version(default) -> default;
-is_version(8) -> 8;
-is_version(9) -> 9.
+is_version(default) -> true;
+is_version(9) -> true.
mem(X, L) ->
case lists:member(X, L) of
@@ -1288,17 +1275,23 @@ badarg_exit(Reply, _A) ->
init(Parent, Server) ->
process_flag(trap_exit, true),
- open_file_loop(#head{parent = Parent, server = Server}).
-
-open_file_loop(Head) ->
%% The Dets server pretends the file is open before
%% internal_open() has been called, which means that unless the
%% internal_open message is applied first, other processes can
%% find the pid by calling dets_server:get_pid() and do things
%% before Head has been initialized properly.
receive
- ?DETS_CALL(From, {internal_open, _Ref, _Args}=Op) ->
- do_apply_op(Op, From, Head, 0)
+ ?DETS_CALL(From, {internal_open, Ref, Args}=Op) ->
+ try do_internal_open(Parent, Server, From, Ref, Args) of
+ Head ->
+ open_file_loop(Head, 0)
+ catch
+ exit:normal ->
+ exit(normal);
+ _:Bad ->
+ bug_found(no_name, Op, Bad, From),
+ exit(Bad) % give up
+ end
end.
open_file_loop(Head, N) when element(1, Head#head.update_mode) =:= error ->
@@ -1379,28 +1372,7 @@ do_apply_op(Op, From, Head, N) ->
exit:normal ->
exit(normal);
_:Bad ->
- Name = Head#head.name,
- case dets_utils:debug_mode() of
- true ->
- %% If stream_op/5 found more requests, this is not
- %% the last operation.
- error_logger:format
- ("** dets: Bug was found when accessing table ~w,~n"
- "** dets: operation was ~p and reply was ~w.~n"
- "** dets: Stacktrace: ~w~n",
- [Name, Op, Bad, erlang:get_stacktrace()]);
- false ->
- error_logger:format
- ("** dets: Bug was found when accessing table ~w~n",
- [Name])
- end,
- if
- From =/= self() ->
- From ! {self(), {error, {dets_bug, Name, Op, Bad}}},
- ok;
- true -> % auto_save | may_grow | {delayed_write, _}
- ok
- end,
+ bug_found(Head#head.name, Op, Bad, From),
open_file_loop(Head, N)
end.
@@ -1408,10 +1380,7 @@ apply_op(Op, From, Head, N) ->
case Op of
{add_user, Tab, OpenArgs}->
#open_args{file = Fname, type = Type, keypos = Keypos,
- ram_file = Ram, access = Access,
- version = Version} = OpenArgs,
- VersionOK = (Version =:= default) or
- (Head#head.version =:= Version),
+ ram_file = Ram, access = Access} = OpenArgs,
%% min_no_slots and max_no_slots are not tested
Res = if
Tab =:= Head#head.name,
@@ -1419,7 +1388,6 @@ apply_op(Op, From, Head, N) ->
Head#head.type =:= Type,
Head#head.ram_file =:= Ram,
Head#head.access =:= Access,
- VersionOK,
Fname =:= Head#head.filename ->
ok;
true ->
@@ -1475,21 +1443,14 @@ apply_op(Op, From, Head, N) ->
From ! {self(), Res},
ok;
{internal_open, Ref, Args} ->
- ?PROFILE(ep:do()),
- case do_open_file(Args, Head#head.parent, Head#head.server,Ref) of
- {ok, H2} ->
- From ! {self(), ok},
- H2;
- Error ->
- From ! {self(), Error},
- exit(normal)
- end;
+ do_internal_open(Head#head.parent, Head#head.server, From,
+ Ref, Args);
may_grow when Head#head.update_mode =/= saved ->
if
Head#head.update_mode =:= dirty ->
%% Won't grow more if the table is full.
{H2, _Res} =
- (Head#head.mod):may_grow(Head, 0, many_times),
+ dets_v9:may_grow(Head, 0, many_times),
{N + 1, H2};
true ->
ok
@@ -1519,21 +1480,10 @@ apply_op(Op, From, Head, N) ->
From ! {self(), Res},
erlang:garbage_collect(),
{0, H2};
- {delete_key, Keys} when Head#head.update_mode =:= dirty ->
- if
- Head#head.version =:= 8 ->
- {H2, Res} = fdelete_key(Head, Keys),
- From ! {self(), Res},
- {N + 1, H2};
- true ->
- stream_op(Op, From, [], Head, N)
- end;
+ {delete_key, _Keys} when Head#head.update_mode =:= dirty ->
+ stream_op(Op, From, [], Head, N);
{delete_object, Objs} when Head#head.update_mode =:= dirty ->
case check_objects(Objs, Head#head.keypos) of
- true when Head#head.version =:= 8 ->
- {H2, Res} = fdelete_object(Head, Objs),
- From ! {self(), Res},
- {N + 1, H2};
true ->
stream_op(Op, From, [], Head, N);
false ->
@@ -1551,10 +1501,6 @@ apply_op(Op, From, Head, N) ->
H2;
{insert, Objs} when Head#head.update_mode =:= dirty ->
case check_objects(Objs, Head#head.keypos) of
- true when Head#head.version =:= 8 ->
- {H2, Res} = finsert(Head, Objs),
- From ! {self(), Res},
- {N + 1, H2};
true ->
stream_op(Op, From, [], Head, N);
false ->
@@ -1565,10 +1511,6 @@ apply_op(Op, From, Head, N) ->
{H2, Res} = finsert_new(Head, Objs),
From ! {self(), Res},
{N + 1, H2};
- {lookup_keys, Keys} when Head#head.version =:= 8 ->
- {H2, Res} = flookup_keys(Head, Keys),
- From ! {self(), Res},
- H2;
{lookup_keys, _Keys} ->
stream_op(Op, From, [], Head, N);
{match_init, State, Safe} ->
@@ -1584,10 +1526,6 @@ apply_op(Op, From, Head, N) ->
{H2, Res} = fmatch(Head, MP, Spec, NObjs, Safe, From),
From ! {self(), Res},
H2;
- {member, Key} when Head#head.version =:= 8 ->
- {H2, Res} = fmember(Head, Key),
- From ! {self(), Res},
- H2;
{member, _Key} = Op ->
stream_op(Op, From, [], Head, N);
{next, Key} ->
@@ -1628,7 +1566,7 @@ apply_op(Op, From, Head, N) ->
apply_op(WriteOp, From, H2, 0);
WriteOp when Head#head.access =:= read_write,
Head#head.update_mode =:= saved ->
- case catch (Head#head.mod):mark_dirty(Head) of
+ case catch dets_v9:mark_dirty(Head) of
ok ->
start_auto_save_timer(Head),
H2 = Head#head{update_mode = dirty},
@@ -1643,6 +1581,40 @@ apply_op(Op, From, Head, N) ->
ok
end.
+bug_found(Name, Op, Bad, From) ->
+ case dets_utils:debug_mode() of
+ true ->
+ %% If stream_op/5 found more requests, this is not
+ %% the last operation.
+ error_logger:format
+ ("** dets: Bug was found when accessing table ~w,~n"
+ "** dets: operation was ~p and reply was ~w.~n"
+ "** dets: Stacktrace: ~w~n",
+ [Name, Op, Bad, erlang:get_stacktrace()]);
+ false ->
+ error_logger:format
+ ("** dets: Bug was found when accessing table ~w~n",
+ [Name])
+ end,
+ if
+ From =/= self() ->
+ From ! {self(), {error, {dets_bug, Name, Op, Bad}}},
+ ok;
+ true -> % auto_save | may_grow | {delayed_write, _}
+ ok
+ end.
+
+do_internal_open(Parent, Server, From, Ref, Args) ->
+ ?PROFILE(ep:do()),
+ case do_open_file(Args, Parent, Server, Ref) of
+ {ok, Head} ->
+ From ! {self(), ok},
+ Head;
+ Error ->
+ From ! {self(), Error},
+ exit(normal)
+ end.
+
start_auto_save_timer(Head) when Head#head.auto_save =:= infinity ->
ok;
start_auto_save_timer(Head) ->
@@ -1650,7 +1622,7 @@ start_auto_save_timer(Head) ->
_Ref = erlang:send_after(Millis, self(), ?DETS_CALL(self(), auto_save)),
ok.
-%% Version 9: Peek the message queue and try to evaluate several
+%% Peek the message queue and try to evaluate several
%% lookup requests in parallel. Evalute delete_object, delete and
%% insert as well.
stream_op(Op, Pid, Pids, Head, N) ->
@@ -1760,7 +1732,7 @@ lookup_reply(P, O) ->
%% Callback functions for system messages handling.
%%-----------------------------------------------------------------
system_continue(_Parent, _, Head) ->
- open_file_loop(Head).
+ open_file_loop(Head, 0).
system_terminate(Reason, _Parent, _, Head) ->
_NewHead = do_stop(Head),
@@ -1793,7 +1765,8 @@ read_file_header(FileName, Access, RamFile) ->
dets_utils:pread_close(Fd, FileName, ?FILE_FORMAT_VERSION_POS, 4),
if
Version =< 8 ->
- dets_v8:read_file_header(Fd, FileName);
+ _ = file:close(Fd),
+ throw({error, {format_8_no_longer_supported, FileName}});
Version =:= 9 ->
dets_v9:read_file_header(Fd, FileName);
true ->
@@ -1820,7 +1793,7 @@ perform_save(Head, DoSync) when Head#head.update_mode =:= dirty;
Head#head.update_mode =:= new_dirty ->
case catch begin
{Head1, []} = write_cache(Head),
- {Head2, ok} = (Head1#head.mod):do_perform_save(Head1),
+ {Head2, ok} = dets_v9:do_perform_save(Head1),
ok = ensure_written(Head2, DoSync),
{Head2#head{update_mode = saved}, ok}
end of
@@ -1853,7 +1826,7 @@ ensure_written(Head, false) when not Head#head.ram_file ->
do_bchunk_init(Head, Tab) ->
case catch write_cache(Head) of
{H2, []} ->
- case (H2#head.mod):table_parameters(H2) of
+ case dets_v9:table_parameters(H2) of
undefined ->
{H2, {error, old_version}};
Parms ->
@@ -1862,9 +1835,9 @@ do_bchunk_init(Head, Tab) ->
L =:= <<>> -> eof;
true -> <<>>
end,
- C0 = #dets_cont{no_objs = default, bin = Bin, alloc = L},
BinParms = term_to_binary(Parms),
- {H2, {C0#dets_cont{tab = Tab, proc = self(),what = bchunk},
+ {H2, {#dets_cont{no_objs = default, bin = Bin, alloc = L,
+ tab = Tab, proc = self(),what = bchunk},
[BinParms]}}
end;
{NewHead, _} = HeadError when is_record(NewHead, head) ->
@@ -1904,16 +1877,8 @@ do_delete_all_objects(Head) ->
max_no_slots = MaxSlots, cache = Cache} = Head,
CacheSz = dets_utils:cache_size(Cache),
ok = dets_utils:truncate(Fd, Fname, bof),
- (Head#head.mod):initiate_file(Fd, Tab, Fname, Type, Kp, MinSlots, MaxSlots,
- Ram, CacheSz, Auto, true).
-
-%% -> {NewHead, Reply}, Reply = ok | Error.
-fdelete_key(Head, Keys) ->
- do_delete(Head, Keys, delete_key).
-
-%% -> {NewHead, Reply}, Reply = ok | badarg | Error.
-fdelete_object(Head, Objects) ->
- do_delete(Head, Objects, delete_object).
+ dets_v9:initiate_file(Fd, Tab, Fname, Type, Kp, MinSlots, MaxSlots,
+ Ram, CacheSz, Auto, true).
ffirst(H) ->
Ref = make_ref(),
@@ -1930,7 +1895,7 @@ ffirst1(H) ->
ffirst(NH, 0).
ffirst(H, Slot) ->
- case (H#head.mod):slot_objs(H, Slot) of
+ case dets_v9:slot_objs(H, Slot) of
'$end_of_table' -> {H, '$end_of_table'};
[] -> ffirst(H, Slot+1);
[X|_] -> {H, element(H#head.keypos, X)}
@@ -2067,7 +2032,7 @@ finfo(H, auto_save) -> {H, H#head.auto_save};
finfo(H, bchunk_format) ->
case catch write_cache(H) of
{H2, []} ->
- case (H2#head.mod):table_parameters(H2) of
+ case dets_v9:table_parameters(H2) of
undefined = Undef ->
{H2, Undef};
Parms ->
@@ -2100,7 +2065,7 @@ finfo(H, no_keys) ->
{H2, _} = HeadError when is_record(H2, head) ->
HeadError
end;
-finfo(H, no_slots) -> {H, (H#head.mod):no_slots(H)};
+finfo(H, no_slots) -> {H, dets_v9:no_slots(H)};
finfo(H, pid) -> {H, self()};
finfo(H, ram_file) -> {H, H#head.ram_file};
finfo(H, safe_fixed) ->
@@ -2127,7 +2092,7 @@ finfo(H, size) ->
HeadError
end;
finfo(H, type) -> {H, H#head.type};
-finfo(H, version) -> {H, H#head.version};
+finfo(H, version) -> {H, 9};
finfo(H, _) -> {H, undefined}.
file_size(Fd, FileName) ->
@@ -2136,8 +2101,6 @@ file_size(Fd, FileName) ->
test_bchunk_format(_Head, undefined) ->
false;
-test_bchunk_format(Head, _Term) when Head#head.version =:= 8 ->
- false;
test_bchunk_format(Head, Term) ->
dets_v9:try_bchunk_header(Term, Head) =/= not_ok.
@@ -2206,7 +2169,7 @@ do_finit(Head, Init, Format, NoSlots) ->
#head{fptr = Fd, type = Type, keypos = Kp, auto_save = Auto,
cache = Cache, filename = Fname, ram_file = Ram,
min_no_slots = MinSlots0, max_no_slots = MaxSlots,
- name = Tab, update_mode = UpdateMode, mod = HMod} = Head,
+ name = Tab, update_mode = UpdateMode} = Head,
CacheSz = dets_utils:cache_size(Cache),
{How, Head1} =
case Format of
@@ -2219,9 +2182,10 @@ do_finit(Head, Init, Format, NoSlots) ->
{general_init, Head};
true ->
ok = dets_utils:truncate(Fd, Fname, bof),
- {ok, H} = HMod:initiate_file(Fd, Tab, Fname, Type, Kp,
- MinSlots, MaxSlots, Ram,
- CacheSz, Auto, false),
+ {ok, H} =
+ dets_v9:initiate_file(Fd, Tab, Fname, Type, Kp,
+ MinSlots, MaxSlots, Ram,
+ CacheSz, Auto, false),
{general_init, H}
end;
bchunk ->
@@ -2230,7 +2194,7 @@ do_finit(Head, Init, Format, NoSlots) ->
end,
case How of
bchunk_init ->
- case HMod:bchunk_init(Head1, Init) of
+ case dets_v9:bchunk_init(Head1, Init) of
{ok, NewHead} ->
{ok, NewHead#head{update_mode = dirty}};
Error ->
@@ -2238,10 +2202,10 @@ do_finit(Head, Init, Format, NoSlots) ->
end;
general_init ->
Cntrs = ets:new(dets_init, []),
- Input = HMod:bulk_input(Head1, Init, Cntrs),
+ Input = dets_v9:bulk_input(Head1, Init, Cntrs),
SlotNumbers = {Head1#head.min_no_slots, bulk_init, MaxSlots},
{Reply, SizeData} =
- do_sort(Head1, SlotNumbers, Input, Cntrs, Fname, not_used),
+ do_sort(Head1, SlotNumbers, Input, Cntrs, Fname),
Bulk = true,
case Reply of
{ok, NoDups, H1} ->
@@ -2297,7 +2261,8 @@ fmatch(Head, MP, Spec, N, Safe, From) ->
{NewHead, Reply} = flookup_keys(Head, Keys),
case Reply of
Objs when is_list(Objs) ->
- MatchingObjs = ets:match_spec_run(Objs, MP),
+ {match_spec, MS} = MP,
+ MatchingObjs = ets:match_spec_run(Objs, MS),
{NewHead, {done, MatchingObjs}};
Error ->
{NewHead, Error}
@@ -2377,7 +2342,7 @@ fmatch_delete(Head, C) ->
{[], _} ->
{Head, {done, 0}};
{RTs, NC} ->
- MP = C#dets_cont.match_program,
+ {match_spec, MP} = C#dets_cont.match_program,
case catch filter_binary_terms(RTs, MP, []) of
{'EXIT', _} ->
Bad = dets_utils:bad_object(fmatch_delete, RTs),
@@ -2405,7 +2370,7 @@ do_fmatch_delete_var_keys(Head, MP, _Spec, From) ->
C0 = init_scan(NewHead, default),
{NewHead, {cont, C0#dets_cont{match_program = MP}, 0}}.
-do_fmatch_constant_keys(Head, Keys, MP) ->
+do_fmatch_constant_keys(Head, Keys, {match_spec, MP}) ->
case flookup_keys(Head, Keys) of
{NewHead, ReadTerms} when is_list(ReadTerms) ->
Terms = filter_terms(ReadTerms, MP, []),
@@ -2454,18 +2419,8 @@ do_delete(Head, Things, What) ->
HeadError
end.
-fmember(Head, Key) ->
- case catch begin
- {Head2, [{_NoPid,Objs}]} =
- update_cache(Head, [Key], {lookup, nopid}),
- {Head2, Objs =/= []}
- end of
- {NewHead, _} = Reply when is_record(NewHead, head) ->
- Reply
- end.
-
fnext(Head, Key) ->
- Slot = (Head#head.mod):db_hash(Key, Head),
+ Slot = dets_v9:db_hash(Key, Head),
Ref = make_ref(),
case catch {Ref, fnext(Head, Key, Slot)} of
{Ref, {H, R}} ->
@@ -2476,7 +2431,7 @@ fnext(Head, Key) ->
fnext(H, Key, Slot) ->
{NH, []} = write_cache(H),
- case (H#head.mod):slot_objs(NH, Slot) of
+ case dets_v9:slot_objs(NH, Slot) of
'$end_of_table' -> {NH, '$end_of_table'};
L -> fnext_search(NH, Key, Slot, L)
end.
@@ -2490,7 +2445,7 @@ fnext_search(H, K, Slot, L) ->
%% We've got to continue to search for the next key in the next slot
fnext_slot(H, K, Slot) ->
- case (H#head.mod):slot_objs(H, Slot) of
+ case dets_v9:slot_objs(H, Slot) of
'$end_of_table' -> {H, '$end_of_table'};
[] -> fnext_slot(H, K, Slot+1);
L -> {H, element(H#head.keypos, hd(L))}
@@ -2518,11 +2473,10 @@ fopen2(Fname, Tab) ->
Acc = read_write,
Ram = false,
{ok, Fd, FH} = read_file_header(Fname, Acc, Ram),
- Mod = FH#fileheader.mod,
- Do = case Mod:check_file_header(FH, Fd) of
- {ok, Head1, ExtraInfo} ->
+ Do = case dets_v9:check_file_header(FH, Fd) of
+ {ok, Head1} ->
Head2 = Head1#head{filename = Fname},
- try {ok, Mod:init_freelist(Head2, ExtraInfo)}
+ try {ok, dets_v9:init_freelist(Head2)}
catch
throw:_ ->
{repair, " has bad free lists, repairing ..."}
@@ -2536,8 +2490,7 @@ fopen2(Fname, Tab) ->
case Do of
{repair, Mess} ->
io:format(user, "dets: file ~tp~s~n", [Fname, Mess]),
- Version = default,
- case fsck(Fd, Tab, Fname, FH, default, default, Version) of
+ case fsck(Fd, Tab, Fname, FH, default, default) of
ok ->
fopen2(Fname, Tab);
Error ->
@@ -2570,33 +2523,23 @@ fopen_existing_file(Tab, OpenArgs) ->
#open_args{file = Fname, type = Type, keypos = Kp, repair = Rep,
min_no_slots = MinSlots, max_no_slots = MaxSlots,
ram_file = Ram, delayed_write = CacheSz, auto_save =
- Auto, access = Acc, version = Version, debug = Debug} =
+ Auto, access = Acc, debug = Debug} =
OpenArgs,
{ok, Fd, FH} = read_file_header(Fname, Acc, Ram),
- V9 = (Version =:= 9) or (Version =:= default),
MinF = (MinSlots =:= default) or (MinSlots =:= FH#fileheader.min_no_slots),
MaxF = (MaxSlots =:= default) or (MaxSlots =:= FH#fileheader.max_no_slots),
- Mod = (FH#fileheader.mod),
- Wh = case Mod:check_file_header(FH, Fd) of
- {ok, Head, true} when Rep =:= force, Acc =:= read_write,
- FH#fileheader.version =:= 9,
- FH#fileheader.no_colls =/= undefined,
- MinF, MaxF, V9 ->
- {compact, Head, true};
- {ok, _Head, _Extra} when Rep =:= force, Acc =:= read ->
+ Wh = case dets_v9:check_file_header(FH, Fd) of
+ {ok, Head} when Rep =:= force, Acc =:= read_write,
+ FH#fileheader.no_colls =/= undefined,
+ MinF, MaxF ->
+ {compact, Head};
+ {ok, _Head} when Rep =:= force, Acc =:= read ->
throw({error, {access_mode, Fname}});
- {ok, Head, need_compacting} when Acc =:= read ->
- {final, Head, true}; % Version 8 only.
- {ok, _Head, need_compacting} when Rep =:= true ->
- %% The file needs to be compacted due to a very big
- %% and fragmented free_list. Version 8 only.
- M = " is now compacted ...",
- {repair, M};
- {ok, _Head, _Extra} when Rep =:= force ->
+ {ok, _Head} when Rep =:= force ->
M = ", repair forced.",
{repair, M};
- {ok, Head, ExtraInfo} ->
- {final, Head, ExtraInfo};
+ {ok, Head} ->
+ {final, Head};
{error, not_closed} when Rep =:= force, Acc =:= read_write ->
M = ", repair forced.",
{repair, M};
@@ -2605,17 +2548,13 @@ fopen_existing_file(Tab, OpenArgs) ->
{repair, M};
{error, not_closed} when Rep =:= false ->
throw({error, {needs_repair, Fname}});
- {error, version_bump} when Rep =:= true, Acc =:= read_write ->
- %% Version 8 only
- M = " old version, upgrading ...",
- {repair, M};
{error, Reason} ->
throw({error, {Reason, Fname}})
end,
Do = case Wh of
- {Tag, Hd, Extra} when Tag =:= final; Tag =:= compact ->
+ {Tag, Hd} when Tag =:= final; Tag =:= compact ->
Hd1 = Hd#head{filename = Fname},
- try {Tag, Mod:init_freelist(Hd1, Extra)}
+ try {Tag, dets_v9:init_freelist(Hd1)}
catch
throw:_ ->
{repair, " has bad free lists, repairing ..."}
@@ -2643,23 +2582,20 @@ fopen_existing_file(Tab, OpenArgs) ->
"now repairing ...~n", [Fname]),
{ok, Fd2, _FH} = read_file_header(Fname, Acc, Ram),
do_repair(Fd2, Tab, Fname, FH, MinSlots, MaxSlots,
- Version, OpenArgs)
+ OpenArgs)
end;
{repair, Mess} ->
io:format(user, "dets: file ~tp~s~n", [Fname, Mess]),
do_repair(Fd, Tab, Fname, FH, MinSlots, MaxSlots,
- Version, OpenArgs);
- _ when FH#fileheader.version =/= Version, Version =/= default ->
- throw({error, {version_mismatch, Fname}});
+ OpenArgs);
{final, H} ->
H1 = H#head{auto_save = Auto},
open_final(H1, Fname, Acc, Ram, CacheSz, Tab, Debug)
end.
-do_repair(Fd, Tab, Fname, FH, MinSlots, MaxSlots, Version, OpenArgs) ->
- case fsck(Fd, Tab, Fname, FH, MinSlots, MaxSlots, Version) of
+do_repair(Fd, Tab, Fname, FH, MinSlots, MaxSlots, OpenArgs) ->
+ case fsck(Fd, Tab, Fname, FH, MinSlots, MaxSlots) of
ok ->
- %% No need to update 'version'.
erlang:garbage_collect(),
fopen3(Tab, OpenArgs#open_args{repair = false});
Error ->
@@ -2673,8 +2609,8 @@ open_final(Head, Fname, Acc, Ram, CacheSz, Tab, Debug) ->
filename = Fname,
name = Tab,
cache = dets_utils:new_cache(CacheSz)},
- init_disk_map(Head1#head.version, Tab, Debug),
- (Head1#head.mod):cache_segps(Head1#head.fptr, Fname, Head1#head.next),
+ init_disk_map(Tab, Debug),
+ dets_v9:cache_segps(Head1#head.fptr, Fname, Head1#head.next),
check_growth(Head1),
{ok, Head1}.
@@ -2683,7 +2619,7 @@ fopen_init_file(Tab, OpenArgs) ->
#open_args{file = Fname, type = Type, keypos = Kp,
min_no_slots = MinSlotsArg, max_no_slots = MaxSlotsArg,
ram_file = Ram, delayed_write = CacheSz, auto_save = Auto,
- version = UseVersion, debug = Debug} = OpenArgs,
+ debug = Debug} = OpenArgs,
MinSlots = choose_no_slots(MinSlotsArg, ?DEFAULT_MIN_NO_SLOTS),
MaxSlots = choose_no_slots(MaxSlotsArg, ?DEFAULT_MAX_NO_SLOTS),
FileSpec = if
@@ -2691,20 +2627,11 @@ fopen_init_file(Tab, OpenArgs) ->
true -> Fname
end,
{ok, Fd} = dets_utils:open(FileSpec, open_args(read_write, Ram)),
- Version = if
- UseVersion =:= default ->
- case os:getenv("DETS_USE_FILE_FORMAT") of
- "8" -> 8;
- _ -> 9
- end;
- true ->
- UseVersion
- end,
- Mod = version2module(Version),
%% No need to truncate an empty file.
- init_disk_map(Version, Tab, Debug),
- case catch Mod:initiate_file(Fd, Tab, Fname, Type, Kp, MinSlots, MaxSlots,
- Ram, CacheSz, Auto, true) of
+ init_disk_map(Tab, Debug),
+ case catch dets_v9:initiate_file(Fd, Tab, Fname, Type, Kp,
+ MinSlots, MaxSlots,
+ Ram, CacheSz, Auto, true) of
{error, Reason} when Ram ->
_ = file:close(Fd),
throw({error, Reason});
@@ -2719,15 +2646,13 @@ fopen_init_file(Tab, OpenArgs) ->
end.
%% Debug.
-init_disk_map(9, Name, Debug) ->
+init_disk_map(Name, Debug) ->
case Debug orelse dets_utils:debug_mode() of
true ->
dets_utils:init_disk_map(Name);
false ->
ok
- end;
-init_disk_map(_Version, _Name, _Debug) ->
- ok.
+ end.
open_args(Access, RamFile) ->
A1 = case Access of
@@ -2740,15 +2665,7 @@ open_args(Access, RamFile) ->
end,
A1 ++ A2 ++ [binary, read].
-version2module(V) when V =< 8 -> dets_v8;
-version2module(9) -> dets_v9.
-
-module2version(dets_v8) -> 8;
-module2version(dets_v9) -> 9;
-module2version(not_used) -> 9.
-
%% -> ok | throw(Error)
-%% For version 9 tables only.
compact(SourceHead) ->
#head{name = Tab, filename = Fname, fptr = SFd, type = Type, keypos = Kp,
ram_file = Ram, auto_save = Auto} = SourceHead,
@@ -2759,7 +2676,7 @@ compact(SourceHead) ->
%% It is normally not possible to have two open tables in the same
%% process since the process dictionary is used for caching
%% segment pointers, but here is works anyway--when reading a file
- %% serially the pointers to not need to be used.
+ %% serially the pointers do not need to be used.
Head = case catch dets_v9:prep_table_copy(Fd, Tab, Tmp, Type, Kp, Ram,
CacheSz, Auto, TblParms) of
{ok, H} ->
@@ -2794,7 +2711,7 @@ compact(SourceHead) ->
%% -> ok | Error
%% Closes Fd.
-fsck(Fd, Tab, Fname, FH, MinSlotsArg, MaxSlotsArg, Version) ->
+fsck(Fd, Tab, Fname, FH, MinSlotsArg, MaxSlotsArg) ->
%% MinSlots and MaxSlots are the option values.
#fileheader{min_no_slots = MinSlotsFile,
max_no_slots = MaxSlotsFile} = FH,
@@ -2807,10 +2724,10 @@ fsck(Fd, Tab, Fname, FH, MinSlotsArg, MaxSlotsArg, Version) ->
%% If the number of objects (keys) turns out to be significantly
%% different from NoSlots, we try again with the correct number of
%% objects (keys).
- case fsck_try(Fd, Tab, FH, Fname, SlotNumbers, Version) of
+ case fsck_try(Fd, Tab, FH, Fname, SlotNumbers) of
{try_again, BetterNoSlots} ->
BetterSlotNumbers = {MinSlots, BetterNoSlots, MaxSlots},
- case fsck_try(Fd, Tab, FH, Fname, BetterSlotNumbers, Version) of
+ case fsck_try(Fd, Tab, FH, Fname, BetterSlotNumbers) of
{try_again, _} ->
_ = file:close(Fd),
{error, {cannot_repair, Fname}};
@@ -2829,7 +2746,7 @@ choose_no_slots(NoSlots, _) -> NoSlots.
%% Initiating a table using a fun and repairing (or converting) a
%% file are completely different things, but nevertheless the same
%% method is used in both cases...
-fsck_try(Fd, Tab, FH, Fname, SlotNumbers, Version) ->
+fsck_try(Fd, Tab, FH, Fname, SlotNumbers) ->
Tmp = tempfile(Fname),
#fileheader{type = Type, keypos = KeyPos} = FH,
{_MinSlots, EstNoSlots, MaxSlots} = SlotNumbers,
@@ -2838,7 +2755,7 @@ fsck_try(Fd, Tab, FH, Fname, SlotNumbers, Version) ->
max_no_slots = MaxSlots,
ram_file = false, delayed_write = ?DEFAULT_CACHE,
auto_save = infinity, access = read_write,
- version = Version, debug = false},
+ debug = false},
case catch fopen3(Tab, OpenArgs) of
{ok, Head} ->
case fsck_try_est(Head, Fd, Fname, SlotNumbers, FH) of
@@ -2888,10 +2805,9 @@ assure_no_file(File) ->
%% -> {ok, NewHead} | {try_again, integer()} | Error
fsck_try_est(Head, Fd, Fname, SlotNumbers, FH) ->
%% Mod is the module to use for reading input when repairing.
- Mod = FH#fileheader.mod,
Cntrs = ets:new(dets_repair, []),
- Input = Mod:fsck_input(Head, Fd, Cntrs, FH),
- {Reply, SizeData} = do_sort(Head, SlotNumbers, Input, Cntrs, Fname, Mod),
+ Input = dets_v9:fsck_input(Head, Fd, Cntrs, FH),
+ {Reply, SizeData} = do_sort(Head, SlotNumbers, Input, Cntrs, Fname),
Bulk = false,
case Reply of
{ok, NoDups, H1} ->
@@ -2906,14 +2822,13 @@ fsck_try_est(Head, Fd, Fname, SlotNumbers, FH) ->
Else
end.
-do_sort(Head, SlotNumbers, Input, Cntrs, Fname, Mod) ->
- OldV = module2version(Mod),
+do_sort(Head, SlotNumbers, Input, Cntrs, Fname) ->
%% output_objs/4 replaces {LogSize,NoObjects} in Cntrs by
%% {LogSize,Position,Data,NoObjects | NoCollections}.
%% Data = {FileName,FileDescriptor} | [object()]
- %% For small tables Data may be a list of objects which is more
+ %% For small tables Data can be a list of objects which is more
%% efficient since no temporary files are created.
- Output = (Head#head.mod):output_objs(OldV, Head, SlotNumbers, Cntrs),
+ Output = dets_v9:output_objs(Head, SlotNumbers, Cntrs),
TmpDir = filename:dirname(Fname),
Reply = (catch file_sorter:sort(Input, Output,
[{format, binary},{tmpdir, TmpDir}])),
@@ -2954,13 +2869,6 @@ fsck_copy1([SzData | L], Head, Bulk, NoDups) ->
{ok, Copied} when Copied =:= ExpectedSize;
NoObjects =:= 0 -> % the segments
fsck_copy1(L, Head, Bulk, NoDups);
- {ok, Copied} when Bulk, Head#head.version =:= 8 ->
- NoZeros = ExpectedSize - Copied,
- Dups = NoZeros div Size,
- Addr = Pos+Copied,
- NewHead = free_n_objects(Head, Addr, Size-1, NoDups),
- NewNoDups = NoDups - Dups,
- fsck_copy1(L, NewHead, Bulk, NewNoDups);
{ok, _Copied} -> % should never happen
close_files(Bulk, L, Head),
Reason = if Bulk -> initialization_failed;
@@ -2975,13 +2883,6 @@ fsck_copy1([], Head, _Bulk, NoDups) when NoDups =/= 0 ->
fsck_copy1([], Head, _Bulk, _NoDups) ->
{ok, Head#head{update_mode = dirty}}.
-free_n_objects(Head, _Addr, _Size, 0) ->
- Head;
-free_n_objects(Head, Addr, Size, N) ->
- {NewHead, _} = dets_utils:free(Head, Addr, Size),
- NewAddr = Addr + Size + 1,
- free_n_objects(NewHead, NewAddr, Size, N-1).
-
close_files(false, SizeData, Head) ->
_ = file:close(Head#head.fptr),
close_files(true, SizeData, Head);
@@ -3000,7 +2901,7 @@ close_tmp(Fd) ->
fslot(H, Slot) ->
case catch begin
{NH, []} = write_cache(H),
- Objs = (NH#head.mod):slot_objs(NH, Slot),
+ Objs = dets_v9:slot_objs(NH, Slot),
{NH, Objs}
end of
{NewHead, _Objects} = Reply when is_record(NewHead, head) ->
@@ -3050,7 +2951,7 @@ where_is_object(Head, Object) ->
true ->
case catch write_cache(Head) of
{NewHead, []} ->
- {NewHead, (Head#head.mod):find_object(NewHead, Object)};
+ {NewHead, dets_v9:find_object(NewHead, Object)};
{NewHead, _} = HeadError when is_record(NewHead, head) ->
HeadError
end;
@@ -3063,13 +2964,9 @@ check_objects([T | Ts], Kp) when tuple_size(T) >= Kp ->
check_objects(L, _Kp) ->
L =:= [].
-no_things(Head) when Head#head.no_keys =:= undefined ->
- Head#head.no_objects;
no_things(Head) ->
Head#head.no_keys.
-file_no_things(FH) when FH#fileheader.no_keys =:= undefined ->
- FH#fileheader.no_objects;
file_no_things(FH) ->
FH#fileheader.no_keys.
@@ -3110,7 +3007,7 @@ update_cache(Head, ToAdd) ->
if
Lookup; NewSize >= Cache#cache.tsize ->
%% The cache is considered full, or some lookup.
- {NewHead, LU, PwriteList} = (Head#head.mod):write_cache(Head1),
+ {NewHead, LU, PwriteList} = dets_v9:write_cache(Head1),
{NewHead, Found ++ LU, PwriteList};
NewC =:= [] ->
{Head1, Found, []};
@@ -3195,7 +3092,7 @@ delayed_write(Head, WrTime) ->
%% -> {NewHead, [LookedUpObject]} | throw({NewHead, Error})
write_cache(Head) ->
- {Head1, LU, PwriteList} = (Head#head.mod):write_cache(Head),
+ {Head1, LU, PwriteList} = dets_v9:write_cache(Head),
{NewHead, ok} = dets_utils:pwrite(Head1, PwriteList),
{NewHead, LU}.
@@ -3248,7 +3145,7 @@ scan(Head, C) -> % when is_record(C, dets_cont)
scan(Bin, Head, From, To, L, [], R, {C, Head#head.type}).
scan(Bin, H, From, To, L, Ts, R, {C0, Type} = C) ->
- case (H#head.mod):scan_objs(H, Bin, From, To, L, Ts, R, Type) of
+ case dets_v9:scan_objs(H, Bin, From, To, L, Ts, R, Type) of
{more, NFrom, NTo, NL, NTs, NR, Sz} ->
scan_read(H, NFrom, NTo, Sz, NL, NTs, NR, C);
{stop, <<>>=B, NFrom, NTo, <<>>=NL, NTs} ->
@@ -3305,7 +3202,7 @@ time_now() ->
make_timestamp(MonTime, TimeOffset) ->
ErlangSystemTime = erlang:convert_time_unit(MonTime+TimeOffset,
native,
- micro_seconds),
+ microsecond),
MegaSecs = ErlangSystemTime div 1000000000000,
Secs = ErlangSystemTime div 1000000 - MegaSecs*1000000,
MicroSecs = ErlangSystemTime rem 1000000,
@@ -3317,7 +3214,7 @@ file_info(FileName) ->
case catch read_file_header(FileName, read, false) of
{ok, Fd, FH} ->
_ = file:close(Fd),
- (FH#fileheader.mod):file_info(FH);
+ dets_v9:file_info(FH);
Other ->
Other
end.
@@ -3332,15 +3229,13 @@ get_head_field(Fd, Field) ->
view(FileName) ->
case catch read_file_header(FileName, read, false) of
{ok, Fd, FH} ->
- Mod = FH#fileheader.mod,
- try Mod:check_file_header(FH, Fd) of
- {ok, H0, ExtraInfo} ->
- Mod = FH#fileheader.mod,
- case Mod:check_file_header(FH, Fd) of
- {ok, H0, ExtraInfo} ->
- H = Mod:init_freelist(H0, ExtraInfo),
+ try dets_v9:check_file_header(FH, Fd) of
+ {ok, H0} ->
+ case dets_v9:check_file_header(FH, Fd) of
+ {ok, H0} ->
+ H = dets_v9:init_freelist(H0),
v_free_list(H),
- Mod:v_segments(H),
+ dets_v9:v_segments(H),
ok;
X ->
X
diff --git a/lib/stdlib/src/dets.hrl b/lib/stdlib/src/dets.hrl
index 6ebeb96156..b5e732b08f 100644
--- a/lib/stdlib/src/dets.hrl
+++ b/lib/stdlib/src/dets.hrl
@@ -21,7 +21,7 @@
-define(DEFAULT_MIN_NO_SLOTS, 256).
-define(DEFAULT_MAX_NO_SLOTS, 32*1024*1024).
-define(DEFAULT_AUTOSAVE, 3). % minutes
--define(DEFAULT_CACHE, {3000, 14000}). % {delay,size} in {milliseconds,bytes}
+-define(DEFAULT_CACHE, {3000, 14000}). % cache_parms()
%% Type.
-define(SET, 1).
@@ -46,83 +46,111 @@
-define(DETS_CALL(Pid, Req), {'$dets_call', Pid, Req}).
+-type access() :: 'read' | 'read_write'.
+-type auto_save() :: 'infinity' | non_neg_integer().
+-type hash_bif() :: 'phash' | 'phash2'.
+-type keypos() :: pos_integer().
+-type no_colls() :: [{LogSize :: non_neg_integer(),
+ NoCollections :: non_neg_integer()}].
+-type no_slots() :: 'default' | non_neg_integer().
+-type tab_name() :: term().
+-type type() :: 'bag' | 'duplicate_bag' | 'set'.
+-type update_mode() :: 'dirty'
+ | 'new_dirty'
+ | 'saved'
+ | {'error', Reason :: term()}.
+
%% Record holding the file header and more.
-record(head, {
- m, % size
- m2, % m * 2
- next, % next position for growth (segm mgmt only)
- fptr, % the file descriptor
- no_objects, % number of objects in table,
- no_keys, % number of keys (version 9 only)
- maxobjsize, % 2-log of the size of the biggest object
- % collection (version 9 only)
+ m :: non_neg_integer(), % size
+ m2 :: non_neg_integer(), % m * 2
+ next :: non_neg_integer(), % next position for growth
+ % (segm mgmt only)
+ fptr :: file:fd(), % the file descriptor
+ no_objects :: non_neg_integer() , % number of objects in table,
+ no_keys :: non_neg_integer(), % number of keys
+ maxobjsize :: 'undefined' | non_neg_integer(), % 2-log of
+ % the size of the biggest object collection
n, % split indicator
- type, % set | bag | duplicate_bag
- keypos, % default is 1 as for ets
- freelists, % tuple of free lists of buddies
- % if fixed =/= false, then a pair of freelists
- freelists_p, % cached FreelistsPointer
- no_collections, % [{LogSize,NoCollections}] | undefined; number of
- % object collections per size (version 9(b))
- auto_save, % Integer | infinity
- update_mode, % saved | dirty | new_dirty | {error, Reason}
- fixed = false, % false | {now_time(), [{pid(),Counter}]}
- % time of first fix, and number of fixes per process
- hash_bif, % hash bif used for this file (phash2, phash, hash)
- has_md5, % whether the header has an MD5 sum (version 9(c))
- min_no_slots, % minimum number of slots (default or integer)
- max_no_slots, % maximum number of slots (default or integer)
- cache, % cache(). Write cache.
-
- filename, % name of the file being used
- access = read_write, % read | read_write
- ram_file = false, % true | false
- name, % the name of the table
-
- parent, % The supervisor of Dets processes.
- server, % The creator of Dets processes.
-
- %% Depending on the file format:
- version,
- mod,
- bump,
- base
+ type :: type(),
+ keypos :: keypos(), % default is 1 as for ets
+ freelists :: 'undefined'
+ | tuple(), % tuple of free lists of buddies
+ % if fixed =/= false, then a pair of freelists
+ freelists_p :: 'undefined'
+ | non_neg_integer(), % cached FreelistsPointer
+ no_collections :: 'undefined'
+ | no_colls(), % number of object collections
+ % per size (version 9(b))
+ auto_save :: auto_save(),
+ update_mode :: update_mode(),
+ fixed = false :: 'false'
+ | {{integer(), integer()}, % time of first fix,
+ [{pid(), % and number of fixes per process
+ non_neg_integer()}]},
+ hash_bif :: hash_bif(), % hash bif used for this file
+ has_md5 :: boolean(), % whether the header has
+ % an MD5 sum (version 9(c))
+ min_no_slots :: no_slots(), % minimum number of slots
+ max_no_slots :: no_slots(), % maximum number of slots
+ cache :: 'undefined' | cache(), % Write cache.
+
+ filename :: file:name(), % name of the file being used
+ access = read_write :: access(),
+ ram_file = false :: boolean(),
+ name :: tab_name(), % the name of the table
+
+ parent :: 'undefined' | pid(), % The supervisor of Dets processes.
+ server :: 'undefined' | pid(), % The creator of Dets processes.
+
+ bump :: non_neg_integer(),
+ base :: non_neg_integer()
}).
%% Info extracted from the file header.
-record(fileheader, {
- freelist,
- fl_base,
- cookie,
- closed_properly,
- type,
- version,
- m,
- next,
- keypos,
- no_objects,
- no_keys,
- min_no_slots,
- max_no_slots,
- no_colls,
- hash_method,
- read_md5,
- has_md5,
- md5,
- trailer,
- eof,
- n,
- mod
+ freelist :: non_neg_integer(),
+ fl_base :: non_neg_integer(),
+ cookie :: non_neg_integer(),
+ closed_properly :: non_neg_integer(),
+ type :: 'badtype' | type(),
+ version :: non_neg_integer(),
+ m :: non_neg_integer(),
+ next :: non_neg_integer(),
+ keypos :: keypos(),
+ no_objects :: non_neg_integer(),
+ no_keys :: non_neg_integer(),
+ min_no_slots :: non_neg_integer(),
+ max_no_slots :: non_neg_integer(),
+ no_colls :: 'undefined' | no_colls(),
+ hash_method :: non_neg_integer(),
+ read_md5 :: binary(),
+ has_md5 :: boolean(),
+ md5 :: binary(),
+ trailer :: non_neg_integer(),
+ eof :: non_neg_integer(),
+ n
}).
+-type delay() :: non_neg_integer().
+-type threshold() :: non_neg_integer().
+-type cache_parms() ::
+ {Delay :: delay(), % max time items are kept in RAM only,
+ % in milliseconds
+ Size :: threshold()}. % threshold size of cache, in bytes
+
%% Write Cache.
-record(cache, {
- cache, % [{Key,{Seq,Item}}], write cache, last item first
- csize, % current size of the cached items
- inserts, % upper limit on number of inserted keys
- wrtime, % last write or update time
- tsize, % threshold size of cache, in bytes
- delay % max time items are kept in RAM only, in milliseconds
+ cache :: % write cache, last item first
+ [{Key :: term(),
+ {Seq :: non_neg_integer(), Item :: term()}}],
+ csize :: non_neg_integer(), % current size of the cached items
+ inserts :: % upper limit on number of inserted keys
+ non_neg_integer(),
+ wrtime :: 'undefined' | integer(), % last write or update time
+ tsize :: threshold(), % threshold size of cache
+ delay :: delay() % max time items are kept in RAM only
}).
+-type cache() :: #cache{}.
diff --git a/lib/stdlib/src/dets_utils.erl b/lib/stdlib/src/dets_utils.erl
index 34a8ddddaa..da6ebd18f2 100644
--- a/lib/stdlib/src/dets_utils.erl
+++ b/lib/stdlib/src/dets_utils.erl
@@ -20,13 +20,13 @@
-module(dets_utils).
%% Utility functions common to several dets file formats.
-%% To be used from dets, dets_v8 and dets_v9 only.
+%% To be used from modules dets and dets_v9 only.
-export([cmp/2, msort/1, mkeysort/2, mkeysearch/3, family/1]).
-export([rename/2, pread/2, pread/4, ipread/3, pwrite/2, write/2,
truncate/2, position/2, sync/1, open/2, truncate/3, fwrite/3,
- write_file/2, position/3, position_close/3, pwrite/4,
+ write_file/2, position/3, position_close/3,
pwrite/3, pread_close/4, read_n/2, pread_n/3, read_4/2]).
-export([code_to_type/1, type_to_code/1]).
@@ -44,8 +44,6 @@
all_allocated_as_list/1, find_allocated/4, find_next_allocated/3,
log2/1, make_zeros/1]).
--export([init_slots_from_old_file/2]).
-
-export([list_to_tree/1, tree_to_bin/5]).
-compile({inline, [{sz2pos,1}, {adjust_addr,3}]}).
@@ -308,12 +306,6 @@ position_close(Fd, FileName, Pos) ->
OK -> OK
end.
-pwrite(Fd, FileName, Position, B) ->
- case file:pwrite(Fd, Position, B) of
- ok -> ok;
- Error -> file_error(FileName, {error, Error})
- end.
-
pwrite(Fd, FileName, Bins) ->
case file:pwrite(Fd, Bins) of
ok ->
@@ -478,20 +470,6 @@ new_cache({Delay, Size}) ->
%%% Ullman. I think buddy systems were invented by Knuth, a long
%%% time ago.
-init_slots_from_old_file([{Slot,Addr} | T], Ftab) ->
- init_slot(Slot+1,[{Slot,Addr} | T], Ftab);
-init_slots_from_old_file([], Ftab) ->
- Ftab.
-
-init_slot(_Slot,[], Ftab) ->
- Ftab; % should never happen
-init_slot(_Slot,[{_Addr,0}|T], Ftab) ->
- init_slots_from_old_file(T, Ftab);
-init_slot(Slot,[{_Slot1,Addr}|T], Ftab) ->
- Stree = element(Slot, Ftab),
- %% io:format("init_slot ~p:~p~n",[Slot, Addr]),
- init_slot(Slot,T,setelement(Slot, Ftab, bplus_insert(Stree, Addr))).
-
%%% The free lists are kept in RAM, and written to the end of the file
%%% from time to time. It is possible that a considerable amount of
%%% memory is used for a fragmented file.
diff --git a/lib/stdlib/src/dets_v8.erl b/lib/stdlib/src/dets_v8.erl
deleted file mode 100644
index 1bf53d91b1..0000000000
--- a/lib/stdlib/src/dets_v8.erl
+++ /dev/null
@@ -1,1594 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(dets_v8).
-
-%% Dets files, implementation part. This module handles versions up to
-%% and including 8(c). To be called from dets.erl only.
-
--export([mark_dirty/1, read_file_header/2,
- check_file_header/2, do_perform_save/1, initiate_file/11,
- init_freelist/2, fsck_input/4,
- bulk_input/3, output_objs/4, write_cache/1, may_grow/3,
- find_object/2, re_hash/2, slot_objs/2, scan_objs/8,
- db_hash/2, no_slots/1, table_parameters/1]).
-
--export([file_info/1, v_segments/1]).
-
--export([cache_segps/3]).
-
-%% For backward compatibility.
--export([sz2pos/1]).
-
--dialyzer(no_improper_lists).
-
--compile({inline, [{sz2pos,1},{scan_skip,7}]}).
--compile({inline, [{skip_bytes,5}, {get_segp,1}]}).
--compile({inline, [{wl_lookup,5}]}).
--compile({inline, [{actual_seg_size,0}]}).
-
--include("dets.hrl").
-
-%% The layout of the file is :
-%%
-%% bytes decsription
-%% ---------------------- File header
-%% 4 FreelistsPointer
-%% 4 Cookie
-%% 4 ClosedProperly (pos=8)
-%% 4 Type (pos=12)
-%% 4 Version (pos=16)
-%% 4 M
-%% 4 Next
-%% 4 KeyPos
-%% 4 NoObjects
-%% 4 N
-%% ------------------ end of file header
-%% 4*8192 SegmentArray
-%% ------------------
-%% 4*256 First segment
-%% ----------------------------- This is BASE.
-%% ??? Objects (free and alive)
-%% 4*256 Second segment (2 kB now, due to a bug)
-%% ??? Objects (free and alive)
-%% ... more objects and segments ...
-%% -----------------------------
-%% ??? Free lists
-%% -----------------------------
-%% 4 File size, in bytes.
-
-%% The first slot (0) in the segment array always points to the
-%% pre-allocated first segment.
-%% Before we can find an object we must find the slot where the
-%% object resides. Each slot is a (possibly empty) list (or chain) of
-%% objects that hash to the same slot. If the value stored in the
-%% slot is zero, the slot chain is empty. If the slot value is
-%% non-zero, the value points to a position in the file where the
-%% chain starts. Each object in a chain has the following layout:
-%%
-%% bytes decsription
-%% --------------------
-%% 4 Pointer to the next object of the chain.
-%% 4 Size of the object in bytes (Sz).
-%% 4 Status (FREE or ACTIVE)
-%% Sz Binary representing the object
-%%
-%% The status field is used while repairing a file (but not next or size).
-%%
-%%|---------------|
-%%| head |
-%%| |
-%%| |
-%%|_______________|
-%%| |------|
-%%|___seg ptr1____| |
-%%| | |
-%%|__ seg ptr 2___| |
-%%| | | segment 1
-%%| .... | V _____________
-%% | |
-%% | |
-%% |___slot 0 ____|
-%% | |
-%% |___slot 1 ____|-----|
-%% | | |
-%% | ..... | | 1:st obj in slot 1
-%% V segment 1
-%% |-----------|
-%% | next |
-%% |___________|
-%% | size |
-%% |___________|
-%% | status |
-%% |___________|
-%% | |
-%% | |
-%% | obj |
-%% | |
-
-%%%
-%%% File header
-%%%
-
--define(HEADSZ, 40). % The size of the file header, in bytes.
--define(SEGSZ, 256). % Size of a segment, in words.
--define(SEGSZ_LOG2, 8).
--define(SEGARRSZ, 8192). % Maximal number of segments.
--define(SEGADDR(SegN), (?HEADSZ + (4 * (SegN)))).
--define(BASE, ?SEGADDR((?SEGSZ + ?SEGARRSZ))).
--define(MAXOBJS, (?SEGSZ * ?SEGARRSZ)). % 2 M objects
-
--define(SLOT2SEG(S), ((S) bsr ?SEGSZ_LOG2)).
-
-%% BIG is used for hashing. BIG must be greater than the maximum
-%% number of slots, currently MAXOBJS.
--define(BIG, 16#ffffff).
-
-%% Hard coded positions into the file header:
--define(FREELIST_POS, 0).
--define(CLOSED_PROPERLY_POS, 8).
--define(D_POS, 20).
--define(NO_OBJECTS_POS, (?D_POS + 12)).
-
-%% The version of a dets file is indicated by the ClosedProperly
-%% field. Version 6 was used in the R1A release, and version 7 in the
-%% R1B release up to and including the R3B01 release. Both version 6
-%% and version 7 indicate properly closed files by the value
-%% CLOSED_PROPERLY.
-%%
-%% The current version, 8, has three sub-versions:
-%%
-%% - 8(a), indicated by the value CLOSED_PROPERLY (same as in versions 6
-%% and 7), introduced in R3B02;
-%% - 8(b), indicated by the value CLOSED_PROPERLY2(_NEED_COMPACTING),
-%% introduced in R5A and used up to and including R6A;
-%% - 8(c), indicated by the value CLOSED_PROPERLY_NEW_HASH(_NEED_COMPACTING),
-%% in use since R6B.
-%%
-%% The difference between the 8(a) and the 8(b) versions is the format
-%% used for free lists saved on dets files.
-%% The 8(c) version uses a different hashing algorithm, erlang:phash
-%% (former versions use erlang:hash).
-%% Version 8(b) files are only converted to version 8(c) if repair is
-%% done, so we need compatibility with 8(b) for a _long_ time.
-%%
-%% There are known bugs due to the fact that keys and objects are
-%% sometimes compared (==) and sometimes matched (=:=). The version
-%% used by default (9, see dets_v9.erl) does not have this problem.
-
--define(NOT_PROPERLY_CLOSED,0).
--define(CLOSED_PROPERLY,1).
--define(CLOSED_PROPERLY2,2).
--define(CLOSED_PROPERLY2_NEED_COMPACTING,3).
--define(CLOSED_PROPERLY_NEW_HASH,4).
--define(CLOSED_PROPERLY_NEW_HASH_NEED_COMPACTING,5).
-
--define(FILE_FORMAT_VERSION, 8).
--define(CAN_BUMP_BY_REPAIR, [6, 7]).
--define(CAN_CONVERT_FREELIST, [8]).
-
-%%%
-%%% Object header (next, size, status).
-%%%
-
--define(OHDSZ, 12). % The size of the object header, in bytes.
--define(STATUS_POS, 8). % Position of the status field.
-
-%% The size of each object is a multiple of 16.
-%% BUMP is used when repairing files.
--define(BUMP, 16).
-
--define(ReadAhead, 512).
-
-%%-define(DEBUGF(X,Y), io:format(X, Y)).
--define(DEBUGF(X,Y), void).
-
-%% -> ok | throw({NewHead,Error})
-mark_dirty(Head) ->
- Dirty = [{?CLOSED_PROPERLY_POS, <<?NOT_PROPERLY_CLOSED:32>>}],
- {_NewHead, ok} = dets_utils:pwrite(Head, Dirty),
- ok = dets_utils:sync(Head),
- {ok, _Pos} = dets_utils:position(Head, Head#head.freelists_p),
- ok = dets_utils:truncate(Head, cur).
-
-%% -> {ok, head()} | throw(Error)
-initiate_file(Fd, Tab, Fname, Type, Kp, MinSlots, MaxSlots,
- Ram, CacheSz, Auto, _DoInitSegments) ->
- Freelist = 0,
- Cookie = ?MAGIC,
- ClosedProperly = ?NOT_PROPERLY_CLOSED, % immediately overwritten
- Version = ?FILE_FORMAT_VERSION,
- Factor = est_no_segments(MinSlots),
- N = 0,
- M = Next = ?SEGSZ * Factor,
- NoObjects = 0,
- dets_utils:pwrite(Fd, Fname, 0,
- <<Freelist:32,
- Cookie:32,
- ClosedProperly:32,
- (dets_utils:type_to_code(Type)):32,
- Version:32,
- M:32,
- Next:32,
- Kp:32,
- NoObjects:32,
- N:32,
- 0:(?SEGARRSZ*4)/unit:8, % Initialize SegmentArray
- 0:(?SEGSZ*4)/unit:8>>), % Initialize first segment
- %% We must set the first slot of the segment pointer array to
- %% point to the first segment
- Pos = ?SEGADDR(0),
- SegP = (?HEADSZ + (4 * ?SEGARRSZ)),
- dets_utils:pwrite(Fd, Fname, Pos, <<SegP:32>>),
- segp_cache(Pos, SegP),
-
- Ftab = dets_utils:init_alloc(?BASE),
- H0 = #head{freelists=Ftab, fptr = Fd, base = ?BASE},
- {H1, Ws} = init_more_segments(H0, 1, Factor, undefined, []),
-
- %% This is not optimal but simple: always initiate the segments.
- dets_utils:pwrite(Fd, Fname, Ws),
-
- %% Return a new nice head structure
- Head = #head{
- m = M,
- m2 = M * 2,
- next = Next,
- fptr = Fd,
- no_objects = NoObjects,
- n = N,
- type = Type,
- update_mode = dirty,
- freelists = H1#head.freelists,
- auto_save = Auto,
- hash_bif = phash,
- keypos = Kp,
- min_no_slots = Factor * ?SEGSZ,
- max_no_slots = no_segs(MaxSlots) * ?SEGSZ,
-
- ram_file = Ram,
- filename = Fname,
- name = Tab,
- cache = dets_utils:new_cache(CacheSz),
- version = Version,
- bump = ?BUMP,
- base = ?BASE,
- mod = ?MODULE
- },
- {ok, Head}.
-
-est_no_segments(MinSlots) when 1 + ?SLOT2SEG(MinSlots) > ?SEGARRSZ ->
- ?SEGARRSZ;
-est_no_segments(MinSlots) ->
- 1 + ?SLOT2SEG(MinSlots).
-
-init_more_segments(Head, SegNo, Factor, undefined, Ws) when SegNo < Factor ->
- init_more_segments(Head, SegNo, Factor, seg_zero(), Ws);
-init_more_segments(Head, SegNo, Factor, SegZero, Ws) when SegNo < Factor ->
- {NewHead, W} = allocate_segment(Head, SegZero, SegNo),
- init_more_segments(NewHead, SegNo+1, Factor, SegZero, W++Ws);
-init_more_segments(Head, _SegNo, _Factor, _SegZero, Ws) ->
- {Head, Ws}.
-
-allocate_segment(Head, SegZero, SegNo) ->
- %% may throw error:
- {NewHead, Segment, _} = dets_utils:alloc(Head, 4 * ?SEGSZ),
- InitSegment = {Segment, SegZero},
- Pos = ?SEGADDR(SegNo),
- segp_cache(Pos, Segment),
- SegPointer = {Pos, <<Segment:32>>},
- {NewHead, [InitSegment, SegPointer]}.
-
-%% Read free lists (using a Buddy System) from file.
-init_freelist(Head, {convert_freelist,_Version}) ->
- %% This function converts the saved freelist of the form
- %% [{Slot1,Addr1},{Addr1,Addr2},...,{AddrN,0},{Slot2,Addr},...]
- %% i.e each slot is a linked list which ends with a 0.
- %% This is stored in a bplus_tree per Slot.
- %% Each Slot is a position in a tuple.
-
- Ftab = dets_utils:empty_free_lists(),
- Pos = Head#head.freelists_p,
- case catch prterm(Head, Pos, ?OHDSZ) of
- {0, _Sz, Term} ->
- FreeList1 = lists:reverse(Term),
- FreeList = dets_utils:init_slots_from_old_file(FreeList1, Ftab),
- Head#head{freelists = FreeList, base = ?BASE};
- _ ->
- throw({error, {bad_freelists, Head#head.filename}})
- end;
-init_freelist(Head, _) ->
- %% bplus_tree stored as is
- Pos = Head#head.freelists_p,
- case catch prterm(Head, Pos, ?OHDSZ) of
- {0, _Sz, Term} ->
- Head#head{freelists = Term, base = ?BASE};
- _ ->
- throw({error, {bad_freelists, Head#head.filename}})
- end.
-
-%% -> {ok, Fd, fileheader()} | throw(Error)
-read_file_header(Fd, FileName) ->
- {ok, Bin} = dets_utils:pread_close(Fd, FileName, 0, ?HEADSZ),
- [Freelist, Cookie, CP, Type2, Version, M, Next, Kp, NoObjects, N] =
- bin2ints(Bin),
- {ok, EOF} = dets_utils:position_close(Fd, FileName, eof),
- {ok, <<FileSize:32>>} = dets_utils:pread_close(Fd, FileName, EOF-4, 4),
- FH = #fileheader{freelist = Freelist,
- fl_base = ?BASE,
- cookie = Cookie,
- closed_properly = CP,
- type = dets_utils:code_to_type(Type2),
- version = Version,
- m = M,
- next = Next,
- keypos = Kp,
- no_objects = NoObjects,
- min_no_slots = ?DEFAULT_MIN_NO_SLOTS,
- max_no_slots = ?DEFAULT_MAX_NO_SLOTS,
- trailer = FileSize,
- eof = EOF,
- n = N,
- mod = ?MODULE},
- {ok, Fd, FH}.
-
-%% -> {ok, head(), ExtraInfo} | {error, Reason} (Reason lacking file name)
-%% ExtraInfo = {convert_freelist, Version} | true | need_compacting
-check_file_header(FH, Fd) ->
- Test =
- if
- FH#fileheader.cookie =/= ?MAGIC ->
- {error, not_a_dets_file};
- FH#fileheader.type =:= badtype ->
- {error, invalid_type_code};
- FH#fileheader.version =/= ?FILE_FORMAT_VERSION ->
- case lists:member(FH#fileheader.version,
- ?CAN_BUMP_BY_REPAIR) of
- true ->
- {error, version_bump};
- false ->
- {error, bad_version}
- end;
- FH#fileheader.trailer =/= FH#fileheader.eof ->
- {error, not_closed};
- FH#fileheader.closed_properly =:= ?CLOSED_PROPERLY ->
- case lists:member(FH#fileheader.version,
- ?CAN_CONVERT_FREELIST) of
- true ->
- {ok, {convert_freelist, FH#fileheader.version}, hash};
- false ->
- {error, not_closed} % should not happen
- end;
- FH#fileheader.closed_properly =:= ?CLOSED_PROPERLY2 ->
- {ok, true, hash};
- FH#fileheader.closed_properly =:=
- ?CLOSED_PROPERLY2_NEED_COMPACTING ->
- {ok, need_compacting, hash};
- FH#fileheader.closed_properly =:= ?CLOSED_PROPERLY_NEW_HASH ->
- {ok, true, phash};
- FH#fileheader.closed_properly =:=
- ?CLOSED_PROPERLY_NEW_HASH_NEED_COMPACTING ->
- {ok, need_compacting, phash};
- FH#fileheader.closed_properly =:= ?NOT_PROPERLY_CLOSED ->
- {error, not_closed};
- FH#fileheader.closed_properly >
- ?CLOSED_PROPERLY_NEW_HASH_NEED_COMPACTING ->
- {error, not_closed};
- true ->
- {error, not_a_dets_file}
- end,
- case Test of
- {ok, ExtraInfo, HashAlg} ->
- H = #head{
- m = FH#fileheader.m,
- m2 = FH#fileheader.m * 2,
- next = FH#fileheader.next,
- fptr = Fd,
- no_objects= FH#fileheader.no_objects,
- n = FH#fileheader.n,
- type = FH#fileheader.type,
- update_mode = saved,
- auto_save = infinity, % not saved on file
- fixed = false, % not saved on file
- freelists_p = FH#fileheader.freelist,
- hash_bif = HashAlg,
- keypos = FH#fileheader.keypos,
- min_no_slots = FH#fileheader.min_no_slots,
- max_no_slots = FH#fileheader.max_no_slots,
- version = ?FILE_FORMAT_VERSION,
- mod = ?MODULE,
- bump = ?BUMP,
- base = FH#fileheader.fl_base},
- {ok, H, ExtraInfo};
- Error ->
- Error
- end.
-
-cache_segps(Fd, FileName, M) ->
- NSegs = no_segs(M),
- {ok, Bin} = dets_utils:pread_close(Fd, FileName, ?HEADSZ, 4 * NSegs),
- Fun = fun(S, P) -> segp_cache(P, S), P+4 end,
- lists:foldl(Fun, ?HEADSZ, bin2ints(Bin)).
-
-no_segs(NoSlots) ->
- ?SLOT2SEG(NoSlots - 1) + 1.
-
-bin2ints(<<Int:32, B/binary>>) ->
- [Int | bin2ints(B)];
-bin2ints(<<>>) ->
- [].
-
-%%%
-%%% Repair, conversion and initialization of a dets file.
-%%%
-
-bulk_input(Head, InitFun, Cntrs) ->
- bulk_input(Head, InitFun, Cntrs, make_ref()).
-
-bulk_input(Head, InitFun, Cntrs, Ref) ->
- fun(close) ->
- ok;
- (read) ->
- case catch {Ref, InitFun(read)} of
- {Ref, end_of_input} ->
- end_of_input;
- {Ref, {L0, NewInitFun}} when is_list(L0),
- is_function(NewInitFun) ->
- Kp = Head#head.keypos,
- case catch bulk_objects(L0, Head, Cntrs, Kp, []) of
- {'EXIT', _Error} ->
- _ = (catch NewInitFun(close)),
- {error, invalid_objects_list};
- L ->
- {L, bulk_input(Head, NewInitFun, Cntrs, Ref)}
- end;
- {Ref, Value} ->
- {error, {init_fun, Value}};
- Error ->
- throw({thrown, Error})
- end
- end.
-
-bulk_objects([T | Ts], Head, Cntrs, Kp, L) ->
- BT = term_to_binary(T),
- Sz = byte_size(BT),
- LogSz = sz2pos(Sz+?OHDSZ),
- count_object(Cntrs, LogSz),
- Key = element(Kp, T),
- bulk_objects(Ts, Head, Cntrs, Kp, [make_object(Head, Key, LogSz, BT) | L]);
-bulk_objects([], _Head, _Cntrs, _Kp, L) ->
- L.
-
--define(FSCK_SEGMENT, 10000).
-
--define(DCT(D, CT), [D | CT]).
-
--define(VNEW(N, E), erlang:make_tuple(N, E)).
--define(VSET(I, V, E), setelement(I, V, E)).
--define(VGET(I, V), element(I, V)).
-
-%% OldVersion not used, assuming later versions have been converted already.
-output_objs(OldVersion, Head, SlotNumbers, Cntrs) ->
- fun(close) ->
- {ok, 0, Head};
- ([]) ->
- output_objs(OldVersion, Head, SlotNumbers, Cntrs);
- (L) ->
- %% Descending sizes.
- Count = lists:sort(ets:tab2list(Cntrs)),
- RCount = lists:reverse(Count),
- NoObjects = lists:foldl(fun({_Sz,No}, A) -> A + No end, 0, Count),
- {_, MinSlots, _} = SlotNumbers,
- if
- %% Using number of objects for bags and duplicate bags
- %% is not ideal; number of (unique) keys should be
- %% used instead. The effect is that there will be more
- %% segments than "necessary".
- MinSlots =/= bulk_init,
- abs(?SLOT2SEG(NoObjects) - ?SLOT2SEG(MinSlots)) > 5,
- (NoObjects < ?MAXOBJS) ->
- {try_again, NoObjects};
- true ->
- Head1 = Head#head{no_objects = NoObjects},
- SegSz = actual_seg_size(),
- {_, End, _} = dets_utils:alloc(Head, SegSz-1),
- %% Now {LogSize,NoObjects} in Cntrs is replaced by
- %% {LogSize,Position,{FileName,FileDescriptor},NoObjects}.
- {Head2, CT} = allocate_all_objects(Head1, RCount, Cntrs),
- [E | Es] = bin2term(L, []),
- {NE, Acc, DCT1} =
- output_slots(E, Es, [E], Head2, ?DCT(0, CT)),
- NDCT = write_all_sizes(DCT1, Cntrs),
- Max = ets:info(Cntrs, size),
- output_objs2(NE, Acc, Head2, Cntrs, NDCT, End, Max,Max)
- end
- end.
-
-output_objs2(E, Acc, Head, Cntrs, DCT, End, 0, MaxNoChunks) ->
- NDCT = write_all_sizes(DCT, Cntrs),
- output_objs2(E, Acc, Head, Cntrs, NDCT, End, MaxNoChunks, MaxNoChunks);
-output_objs2(E, Acc, Head, Cntrs, DCT, End, ChunkI, MaxNoChunks) ->
- fun(close) ->
- DCT1 = output_slot(Acc, Head, DCT),
- NDCT = write_all_sizes(DCT1, Cntrs),
- ?DCT(NoDups, CT) = NDCT,
- [SegAddr | []] = ?VGET(tuple_size(CT), CT),
- FinalZ = End - SegAddr,
- [{?FSCK_SEGMENT, _, {FileName, Fd}, _}] =
- ets:lookup(Cntrs, ?FSCK_SEGMENT),
- ok = dets_utils:fwrite(Fd, FileName,
- dets_utils:make_zeros(FinalZ)),
- NewHead = Head#head{no_objects = Head#head.no_objects - NoDups},
- {ok, NoDups, NewHead};
- (L) ->
- Es = bin2term(L, []),
- {NE, NAcc, NDCT} = output_slots(E, Es, Acc, Head, DCT),
- output_objs2(NE, NAcc, Head, Cntrs, NDCT, End,
- ChunkI-1, MaxNoChunks)
- end.
-
-%% By allocating bigger objects before smaller ones, holes in the
-%% buddy system memory map are avoided. Unfortunately, the segments
-%% are always allocated first, so if there are objects bigger than a
-%% segment, there is a hole to handle. (Haven't considered placing the
-%% segments among other objects of the same size.)
-allocate_all_objects(Head, Count, Cntrs) ->
- SegSize = actual_seg_size(),
- {Head1, HSz, HN, HA} = alloc_hole(Count, Head, SegSize),
- {Max, _} = hd(Count),
- CT = ?VNEW(Max+1, not_used),
- {Head2, NCT} = allocate_all(Head1, Count, Cntrs, CT),
- Head3 = free_hole(Head2, HSz, HN, HA),
- {Head3, NCT}.
-
-alloc_hole([{LSize,_} | _], Head, SegSz) when ?POW(LSize-1) > SegSz ->
- {_, SegAddr, _} = dets_utils:alloc(Head, SegSz-1),
- Size = ?POW(LSize-1)-1,
- {_, Addr, _} = dets_utils:alloc(Head, Size),
- N = (Addr - SegAddr) div SegSz,
- Head1 = dets_utils:alloc_many(Head, SegSz, N, SegAddr),
- {Head1, SegSz-1, N, SegAddr};
-alloc_hole(_Count, Head, _SegSz) ->
- {Head, 0, 0, 0}.
-
-free_hole(Head, _Size, 0, _Addr) ->
- Head;
-free_hole(Head, Size, N, Addr) ->
- {Head1, _} = dets_utils:free(Head, Addr, Size),
- free_hole(Head1, Size, N-1, Addr+Size+1).
-
-%% One (temporary) file for each buddy size, write all objects of that
-%% size to the file.
-allocate_all(Head, [{LSize,NoObjects} | Count], Cntrs, CT) ->
- Size = ?POW(LSize-1)-1,
- {_Head, Addr, _} = dets_utils:alloc(Head, Size),
- NewHead = dets_utils:alloc_many(Head, Size+1, NoObjects, Addr),
- {FileName, Fd} = temp_file(Head, LSize),
- true = ets:insert(Cntrs, {LSize, Addr, {FileName, Fd}, NoObjects}),
- NCT = ?VSET(LSize, CT, [Addr | []]),
- allocate_all(NewHead, Count, Cntrs, NCT);
-allocate_all(Head, [], Cntrs, CT) ->
- %% Note that space for the segments has been allocated already.
- %% And one file for the segments...
- {FileName, Fd} = temp_file(Head, ?FSCK_SEGMENT),
- Addr = ?SEGADDR(?SEGARRSZ),
- true = ets:insert(Cntrs, {?FSCK_SEGMENT, Addr, {FileName, Fd}, 0}),
- NCT = ?VSET(tuple_size(CT), CT, [Addr | []]),
- {Head, NCT}.
-
-temp_file(Head, N) ->
- TmpName = lists:concat([Head#head.filename, '.', N]),
- {ok, Fd} = dets_utils:open(TmpName, [raw, binary, write]),
- {TmpName, Fd}.
-
-bin2term([<<Slot:32, LogSize:8, BinTerm/binary>> | BTs], L) ->
- bin2term(BTs, [{Slot, LogSize, BinTerm} | L]);
-bin2term([], L) ->
- lists:reverse(L).
-
-write_all_sizes(?DCT(D, CT), Cntrs) ->
- ?DCT(D, write_sizes(1, tuple_size(CT), CT, Cntrs)).
-
-write_sizes(Sz, Sz, CT, Cntrs) ->
- write_size(Sz, ?FSCK_SEGMENT, CT, Cntrs);
-write_sizes(Sz, MaxSz, CT, Cntrs) ->
- NCT = write_size(Sz, Sz, CT, Cntrs),
- write_sizes(Sz+1, MaxSz, NCT, Cntrs).
-
-write_size(Sz, I, CT, Cntrs) ->
- case ?VGET(Sz, CT) of
- not_used ->
- CT;
- [Addr | L] ->
- {FileName, Fd} = ets:lookup_element(Cntrs, I, 3),
- case file:write(Fd, lists:reverse(L)) of
- ok ->
- ?VSET(Sz, CT, [Addr | []]);
- Error ->
- dets_utils:file_error(FileName, Error)
- end
- end.
-
-output_slots(E, [E1 | Es], Acc, Head, DCT)
- when element(1, E) =:= element(1, E1) ->
- output_slots(E1, Es, [E1 | Acc], Head, DCT);
-output_slots(_E, [E | L], Acc, Head, DCT) ->
- NDCT = output_slot(Acc, Head, DCT),
- output_slots(E, L, [E], Head, NDCT);
-output_slots(E, [], Acc, _Head, DCT) ->
- {E, Acc, DCT}.
-
-output_slot([E], _Head, ?DCT(D, CT)) ->
- ?DCT(D, output_slot([{foo, E}], 0, foo, CT));
-output_slot(Es0, Head, ?DCT(D, CT)) ->
- Kp = Head#head.keypos,
- Fun = fun({_Slot, _LSize, BinTerm} = E) ->
- Key = element(Kp, binary_to_term(BinTerm)),
- {Key, E}
- end,
- Es = lists:map(Fun, Es0),
- NEs = case Head#head.type of
- set ->
- [{Key0,_} = E | L0] = lists:sort(Es),
- choose_one(lists:sort(L0), Key0, [E]);
- bag ->
- lists:usort(Es);
- duplicate_bag ->
- lists:sort(Es)
- end,
- Dups = D + length(Es) - length(NEs),
- ?DCT(Dups, output_slot(NEs, 0, foo, CT)).
-
-choose_one([{Key,_} | Es], Key, L) ->
- choose_one(Es, Key, L);
-choose_one([{Key,_} = E | Es], _Key, L) ->
- choose_one(Es, Key, [E | L]);
-choose_one([], _Key, L) ->
- L.
-
-output_slot([E | Es], Next, _Slot, CT) ->
- {_Key, {Slot, LSize, BinTerm}} = E,
- Size = byte_size(BinTerm),
- Size2 = ?POW(LSize-1),
- Pad = <<0:(Size2-Size-?OHDSZ)/unit:8>>,
- BinObject = [<<Next:32, Size:32, ?ACTIVE:32>>, BinTerm | Pad],
- [Addr | L] = ?VGET(LSize, CT),
- NCT = ?VSET(LSize, CT, [Addr+Size2 | [BinObject | L]]),
- output_slot(Es, Addr, Slot, NCT);
-output_slot([], Next, Slot, CT) ->
- I = tuple_size(CT),
- [Addr | L] = ?VGET(I, CT),
- {Pos, _} = slot_position(Slot),
- NoZeros = Pos - Addr,
- BinObject = if
- NoZeros > 100 ->
- [dets_utils:make_zeros(NoZeros) | <<Next:32>>];
- true ->
- <<0:NoZeros/unit:8,Next:32>>
- end,
- Size = NoZeros+4,
- ?VSET(I, CT, [Addr+Size | [BinObject | L]]).
-
-%% Does not close Fd.
-fsck_input(Head, Fd, Cntrs, _FileHeader) ->
- %% The file is not compressed, so the object size cannot exceed
- %% the filesize, for all objects.
- MaxSz = case file:position(Fd, eof) of
- {ok, Pos} ->
- Pos;
- _ ->
- (1 bsl 32) - 1
- end,
- State0 = fsck_read(?BASE, Fd, []),
- fsck_input1(Head, State0, Fd, MaxSz, Cntrs).
-
-fsck_input1(Head, State, Fd, MaxSz, Cntrs) ->
- fun(close) ->
- ok;
- (read) ->
- case State of
- done ->
- end_of_input;
- {done, L} ->
- R = count_input(Cntrs, L, []),
- {R, fsck_input1(Head, done, Fd, MaxSz, Cntrs)};
- {cont, L, Bin, Pos} ->
- R = count_input(Cntrs, L, []),
- FR = fsck_objs(Bin, Head#head.keypos, Head, []),
- NewState = fsck_read(FR, Pos, Fd, MaxSz, Head),
- {R, fsck_input1(Head, NewState, Fd, MaxSz, Cntrs)}
- end
- end.
-
-%% The ets table Cntrs is used for counting objects per size.
-count_input(Cntrs, [[LogSz | B] | Ts], L) ->
- count_object(Cntrs, LogSz),
- count_input(Cntrs, Ts, [B | L]);
-count_input(_Cntrs, [], L) ->
- L.
-
-count_object(Cntrs, LogSz) ->
- case catch ets:update_counter(Cntrs, LogSz, 1) of
- N when is_integer(N) -> ok;
- _Badarg -> true = ets:insert(Cntrs, {LogSz, 1})
- end.
-
-fsck_read(Pos, F, L) ->
- case file:position(F, Pos) of
- {ok, _} ->
- read_more_bytes(<<>>, 0, Pos, F, L);
- _Error ->
- {done, L}
- end.
-
-fsck_read({more, Bin, Sz, L}, Pos, F, MaxSz, Head) when Sz > MaxSz ->
- FR = skip_bytes(Bin, ?BUMP, Head#head.keypos, Head, L),
- fsck_read(FR, Pos, F, MaxSz, Head);
-fsck_read({more, Bin, Sz, L}, Pos, F, _MaxSz, _Head) ->
- read_more_bytes(Bin, Sz, Pos, F, L);
-fsck_read({new, Skip, L}, Pos, F, _MaxSz, _Head) ->
- NewPos = Pos + Skip,
- fsck_read(NewPos, F, L).
-
-read_more_bytes(B, Min, Pos, F, L) ->
- Max = if
- Min < ?CHUNK_SIZE -> ?CHUNK_SIZE;
- true -> Min
- end,
- case dets_utils:read_n(F, Max) of
- eof ->
- {done, L};
- Bin ->
- NewPos = Pos + byte_size(Bin),
- {cont, L, list_to_binary([B, Bin]), NewPos}
- end.
-
-fsck_objs(Bin = <<_N:32, Sz:32, Status:32, Tail/binary>>, Kp, Head, L) ->
- if
- Status =:= ?ACTIVE ->
- case Tail of
- <<BinTerm:Sz/binary, Tail2/binary>> ->
- case catch element(Kp, binary_to_term(BinTerm)) of
- {'EXIT', _} ->
- skip_bytes(Bin, ?BUMP, Kp, Head, L);
- Key ->
- LogSz = sz2pos(Sz+?OHDSZ),
- Obj = make_object(Head, Key, LogSz, BinTerm),
- NL = [[LogSz | Obj] | L],
- Skip = ?POW(LogSz-1) - Sz - ?OHDSZ,
- skip_bytes(Tail2, Skip, Kp, Head, NL)
- end;
- _ ->
- {more, Bin, Sz, L}
- end;
- true ->
- skip_bytes(Bin, ?BUMP, Kp, Head, L)
- end;
-fsck_objs(Bin, _Kp, _Head, L) ->
- {more, Bin, 0, L}.
-
-%% Version 8 has to know about version 9.
-make_object(Head, Key, _LogSz, BT) when Head#head.version =:= 9 ->
- Slot = dets_v9:db_hash(Key, Head),
- <<Slot:32, BT/binary>>;
-make_object(Head, Key, LogSz, BT) ->
- Slot = db_hash(Key, Head),
- <<Slot:32, LogSz:8, BT/binary>>.
-
-%% Inlined.
-skip_bytes(Bin, Skip, Kp, Head, L) ->
- case Bin of
- <<_:Skip/binary, Tail/binary>> ->
- fsck_objs(Tail, Kp, Head, L);
- _ ->
- {new, Skip - byte_size(Bin), L}
- end.
-
-%% -> {NewHead, ok} | throw({Head, Error})
-do_perform_save(H) ->
- FL = dets_utils:get_freelists(H),
- B = term_to_binary(FL),
- Size = byte_size(B),
- ?DEBUGF("size of freelist = ~p~n", [Size]),
- ?DEBUGF("head.m = ~p~n", [H#head.m]),
- ?DEBUGF("head.no_objects = ~p~n", [H#head.no_objects]),
-
- {ok, Pos} = dets_utils:position(H, eof),
- H1 = H#head{freelists_p = Pos},
- W1 = {?FREELIST_POS, <<Pos:32>>},
- W2 = {Pos, [<<0:32, Size:32, ?FREE:32>>, B]},
-
- W3 = {?D_POS, <<(H1#head.m):32,
- (H1#head.next):32,
- (H1#head.keypos):32,
- (H1#head.no_objects):32,
- (H1#head.n):32>>},
- {ClosedProperly, ClosedProperlyNeedCompacitng} =
- case H1#head.hash_bif of
- hash ->
- {?CLOSED_PROPERLY2, ?CLOSED_PROPERLY2_NEED_COMPACTING};
- phash ->
- {?CLOSED_PROPERLY_NEW_HASH,
- ?CLOSED_PROPERLY_NEW_HASH_NEED_COMPACTING}
- end,
- W4 =
- if
- Size > 1000, Size > H1#head.no_objects ->
- {?CLOSED_PROPERLY_POS,
- <<ClosedProperlyNeedCompacitng:32>>};
- true ->
- {?CLOSED_PROPERLY_POS, <<ClosedProperly:32>>}
- end,
- W5 = {?FILE_FORMAT_VERSION_POS, <<?FILE_FORMAT_VERSION:32>>},
- {H2, ok} = dets_utils:pwrite(H1, [W1,W2,W3,W4,W5]),
- {ok, Pos2} = dets_utils:position(H2, eof),
- ?DEBUGF("Writing file size ~p, eof at ~p~n", [Pos2+4, Pos2]),
- dets_utils:pwrite(H2, [{Pos2, <<(Pos2 + 4):32>>}]).
-
-%% -> [term()] | throw({Head, Error})
-slot_objs(H, Slot) when Slot >= H#head.next ->
- '$end_of_table';
-slot_objs(H, Slot) ->
- {_Pos, Chain} = chain(H, Slot),
- collect_chain(H, Chain).
-
-collect_chain(_H, 0) -> [];
-collect_chain(H, Pos) ->
- {Next, _Sz, Term} = prterm(H, Pos, ?ReadAhead),
- [Term | collect_chain(H, Next)].
-
-db_hash(Key, Head) ->
- H = h(Key, Head#head.hash_bif),
- Hash = H rem Head#head.m,
- if
- Hash < Head#head.n ->
- H rem (Head#head.m2); % H rem (2 * m)
- true ->
- Hash
- end.
-
-h(I, phash) -> erlang:phash(I, ?BIG) - 1;
-h(I, HF) -> erlang:HF(I, ?BIG) - 1. %% stupid BIF has 1 counts.
-
-no_slots(_Head) ->
- undefined.
-
-table_parameters(_Head) ->
- undefined.
-
-%% Re-hashing a segment, starting with SlotStart.
-%%
-%% On the average, half of the objects of the chain are put into a new
-%% chain. If the slot of the old chain is i, then the slot of the new
-%% chain is i+m.
-%% Note that the insertion of objects into the new chain is simplified
-%% by the fact that the chains are not sorted on key, which means that
-%% each moved object can be inserted first in the new chain.
-%% (It is also a fact that the objects with the same key are not sorted.)
-%%
-%% -> {ok, Writes} | throw({Head, Error})
-re_hash(Head, SlotStart) ->
- {SlotPos, _4} = slot_position(SlotStart),
- {ok, Bin} = dets_utils:pread(Head, SlotPos, 4*?SEGSZ, 0),
- {Read, Cs} = split_bin(SlotPos, Bin, [], []),
- re_hash_read(Head, [], Read, Cs).
-
-split_bin(Pos, <<P:32, B/binary>>, R, Cs) ->
- if
- P =:= 0 ->
- split_bin(Pos+4, B, R, Cs);
- true ->
- split_bin(Pos+4, B, [{P,?ReadAhead} | R], [[Pos] | Cs])
- end;
-split_bin(_Pos, <<>>, R, Cs) ->
- {R, Cs}.
-
-re_hash_read(Head, Cs, R, RCs) ->
- {ok, Bins} = dets_utils:pread(R, Head),
- re_hash_read(Head, R, RCs, Bins, Cs, [], []).
-
-re_hash_read(Head, [{Pos, Size} | Ps], [C | Cs],
- [<<Next:32, Sz:32, _Status:32, Bin0/binary>> | Bins],
- DoneCs, R, RCs) ->
- case byte_size(Bin0) of
- BinSz when BinSz >= Sz ->
- case catch binary_to_term(Bin0) of
- {'EXIT', _Error} ->
- throw(dets_utils:corrupt_reason(Head, bad_object));
- Term ->
- Key = element(Head#head.keypos, Term),
- New = h(Key, Head#head.hash_bif) rem Head#head.m2,
- NC = case New >= Head#head.m of
- true -> [{Pos,New} | C];
- false -> [Pos | C]
- end,
- if
- Next =:= 0 ->
- NDoneCs = [NC | DoneCs],
- re_hash_read(Head, Ps, Cs, Bins, NDoneCs, R, RCs);
- true ->
- NR = [{Next,?ReadAhead} | R],
- NRCs = [NC | RCs],
- re_hash_read(Head, Ps, Cs, Bins, DoneCs, NR, NRCs)
- end
- end;
- BinSz when Size =:= BinSz+?OHDSZ ->
- NR = [{Pos, Sz+?OHDSZ} | R],
- re_hash_read(Head, Ps, Cs, Bins, DoneCs, NR, [C | RCs]);
- _BinSz ->
- throw({Head, {error, {premature_eof, Head#head.filename}}})
- end;
-re_hash_read(Head, [], [], [], Cs, [], []) ->
- re_hash_traverse_chains(Cs, Head, [], [], []);
-re_hash_read(Head, [], [], [], Cs, R, RCs) ->
- re_hash_read(Head, Cs, R, RCs).
-
-re_hash_traverse_chains([C | Cs], Head, Rs, Ns, Ws) ->
- case re_hash_find_new(C, Rs, start, start) of
- false ->
- re_hash_traverse_chains(Cs, Head, Rs, Ns, Ws);
- {NRs, FirstNew, LastNew} ->
- LastInNew = case C of
- [{_,_} | _] -> true;
- _ -> false
- end,
- N = {FirstNew, LastNew, LastInNew},
- NWs = re_hash_link(C, start, start, start, Ws),
- re_hash_traverse_chains(Cs, Head, NRs, [N | Ns], NWs)
- end;
-re_hash_traverse_chains([], Head, Rs, Ns, Ws) ->
- {ok, Bins} = dets_utils:pread(Rs, Head),
- {ok, insert_new(Rs, Bins, Ns, Ws)}.
-
-re_hash_find_new([{Pos,NewSlot} | C], R, start, start) ->
- {SPos, _4} = slot_position(NewSlot),
- re_hash_find_new(C, [{SPos,4} | R], Pos, Pos);
-re_hash_find_new([{Pos,_SPos} | C], R, _FirstNew, LastNew) ->
- re_hash_find_new(C, R, Pos, LastNew);
-re_hash_find_new([_Pos | C], R, FirstNew, LastNew) ->
- re_hash_find_new(C, R, FirstNew, LastNew);
-re_hash_find_new([], _R, start, start) ->
- false;
-re_hash_find_new([], R, FirstNew, LastNew) ->
- {R, FirstNew, LastNew}.
-
-re_hash_link([{Pos,_SPos} | C], LastOld, start, _LastInNew, Ws) ->
- re_hash_link(C, LastOld, Pos, true, Ws);
-re_hash_link([{Pos,_SPos} | C], LastOld, LastNew, false, Ws) ->
- re_hash_link(C, LastOld, Pos, true, [{Pos,<<LastNew:32>>} | Ws]);
-re_hash_link([{Pos,_SPos} | C], LastOld, _LastNew, LastInNew, Ws) ->
- re_hash_link(C, LastOld, Pos, LastInNew, Ws);
-re_hash_link([Pos | C], start, LastNew, true, Ws) ->
- re_hash_link(C, Pos, LastNew, false, [{Pos,<<0:32>>} | Ws]);
-re_hash_link([Pos | C], LastOld, LastNew, true, Ws) ->
- re_hash_link(C, Pos, LastNew, false, [{Pos,<<LastOld:32>>} | Ws]);
-re_hash_link([Pos | C], _LastOld, LastNew, LastInNew, Ws) ->
- re_hash_link(C, Pos, LastNew, LastInNew, Ws);
-re_hash_link([], _LastOld, _LastNew, _LastInNew, Ws) ->
- Ws.
-
-insert_new([{NewSlotPos,_4} | Rs], [<<P:32>> = PB | Bins], [N | Ns], Ws) ->
- {FirstNew, LastNew, LastInNew} = N,
- Ws1 = case P of
- 0 when LastInNew ->
- Ws;
- 0 ->
- [{LastNew, <<0:32>>} | Ws];
- _ ->
- [{LastNew, PB} | Ws]
- end,
- NWs = [{NewSlotPos, <<FirstNew:32>>} | Ws1],
- insert_new(Rs, Bins, Ns, NWs);
-insert_new([], [], [], Ws) ->
- Ws.
-
-%% When writing the cache, a 'work list' is first created:
-%% WorkList = [{Key, {Delete,Lookup,[Inserted]}}]
-%% Delete = keep | delete
-%% Lookup = skip | lookup
-%% Inserted = {object(), No}
-%% No = integer()
-%% If No =< 0 then there will be -No instances of object() on the file
-%% when the cache has been written. If No > 0 then No instances of
-%% object() will be added to the file.
-%% If Delete has the value 'delete', then all objects with the key Key
-%% have been deleted. (This could be viewed as a shorthand for {Object,0}
-%% for each object Object on the file not mentioned in some Inserted.)
-%% If Lookup has the value 'lookup', all objects with the key Key will
-%% be returned.
-%%
-
-%% -> {NewHead, [LookedUpObject], pwrite_list()} | throw({NewHead, Error})
-write_cache(Head) ->
- #head{cache = C, type = Type} = Head,
- case dets_utils:is_empty_cache(C) of
- true -> {Head, [], []};
- false ->
- {NewC, _MaxInserts, PerKey} = dets_utils:reset_cache(C),
- %% NoInsertedKeys is an upper limit on the number of new keys.
- {WL, NoInsertedKeys} = make_wl(PerKey, Type),
- Head1 = Head#head{cache = NewC},
- case may_grow(Head1, NoInsertedKeys, once) of
- {Head2, ok} ->
- eval_work_list(Head2, WL);
- HeadError ->
- throw(HeadError)
- end
- end.
-
-make_wl(PerKey, Type) ->
- make_wl(PerKey, Type, [], 0).
-
-make_wl([{Key,L} | PerKey], Type, WL, Ins) ->
- [Cs | I] = wl(L, Type),
- make_wl(PerKey, Type, [{Key,Cs} | WL], Ins+I);
-make_wl([], _Type, WL, Ins) ->
- {WL, Ins}.
-
-wl(L, Type) ->
- wl(L, Type, keep, skip, 0, []).
-
-wl([{_Seq, delete_key} | Cs], Type, _Del, Lookup, _I, _Objs) ->
- wl(Cs, Type, delete, Lookup, 0, []);
-wl([{_Seq, {delete_object, Object}} | Cs], Type, Del, Lookup, I, Objs) ->
- NObjs = lists:keydelete(Object, 1, Objs),
- wl(Cs, Type, Del, Lookup, I, [{Object,0} | NObjs]);
-wl([{_Seq, {insert, Object}} | Cs], Type, _Del, Lookup, _I, _Objs)
- when Type =:= set ->
- wl(Cs, Type, delete, Lookup, 1, [{Object,-1}]);
-wl([{_Seq, {insert, Object}} | Cs], Type, Del, Lookup, _I, Objs) ->
- NObjs =
- case lists:keyfind(Object, 1, Objs) of
- {_, 0} ->
- lists:keyreplace(Object, 1, Objs, {Object,-1});
- {_, _C} when Type =:= bag -> % C =:= 1; C =:= -1
- Objs;
- {_, C} when C < 0 -> % when Type =:= duplicate_bag
- lists:keyreplace(Object, 1, Objs, {Object,C-1});
- {_, C} -> % when C > 0, Type =:= duplicate_bag
- lists:keyreplace(Object, 1, Objs, {Object,C+1});
- false when Del =:= delete ->
- [{Object, -1} | Objs];
- false ->
- [{Object, 1} | Objs]
- end,
- wl(Cs, Type, Del, Lookup, 1, NObjs);
-wl([{_Seq, {lookup,_Pid}=Lookup} | Cs], Type, Del, _Lookup, I, Objs) ->
- wl(Cs, Type, Del, Lookup, I, Objs);
-wl([], _Type, Del, Lookup, I, Objs) ->
- [{Del, Lookup, Objs} | I].
-
-%% -> {NewHead, ok} | {NewHead, Error}
-may_grow(Head, 0, once) ->
- {Head, ok};
-may_grow(Head, _N, _How) when Head#head.fixed =/= false ->
- {Head, ok};
-may_grow(#head{access = read}=Head, _N, _How) ->
- {Head, ok};
-may_grow(Head, _N, _How) when Head#head.next >= ?MAXOBJS ->
- {Head, ok};
-may_grow(Head, N, How) ->
- Extra = erlang:min(2*?SEGSZ, Head#head.no_objects + N - Head#head.next),
- case catch may_grow1(Head, Extra, How) of
- {error, Reason} -> % alloc may throw error
- {Head, {error, Reason}};
- Reply ->
- Reply
- end.
-
-may_grow1(Head, Extra, many_times) when Extra > ?SEGSZ ->
- Reply = grow(Head, 1, undefined),
- self() ! ?DETS_CALL(self(), may_grow),
- Reply;
-may_grow1(Head, Extra, _How) ->
- grow(Head, Extra, undefined).
-
-%% -> {Head, ok} | throw({Head, Error})
-grow(Head, Extra, _SegZero) when Extra =< 0 ->
- {Head, ok};
-grow(Head, Extra, undefined) ->
- grow(Head, Extra, seg_zero());
-grow(Head, Extra, SegZero) ->
- #head{n = N, next = Next, m = M} = Head,
- SegNum = ?SLOT2SEG(Next),
- {Head0, Ws1} = allocate_segment(Head, SegZero, SegNum),
- {Head1, ok} = dets_utils:pwrite(Head0, Ws1),
- %% If re_hash fails, segp_cache has been called, but it does not matter.
- {ok, Ws2} = re_hash(Head1, N),
- {Head2, ok} = dets_utils:pwrite(Head1, Ws2),
- NewHead =
- if
- N + ?SEGSZ =:= M ->
- Head2#head{n = 0, next = Next + ?SEGSZ, m = 2 * M, m2 = 4 * M};
- true ->
- Head2#head{n = N + ?SEGSZ, next = Next + ?SEGSZ}
- end,
- grow(NewHead, Extra - ?SEGSZ, SegZero).
-
-seg_zero() ->
- <<0:(4*?SEGSZ)/unit:8>>.
-
-find_object(Head, Object) ->
- Key = element(Head#head.keypos, Object),
- Slot = db_hash(Key, Head),
- find_object(Head, Object, Slot).
-
-find_object(H, _Obj, Slot) when Slot >= H#head.next ->
- false;
-find_object(H, Obj, Slot) ->
- {_Pos, Chain} = chain(H, Slot),
- case catch find_obj(H, Obj, Chain) of
- {ok, Pos} ->
- {ok, Pos};
- _Else ->
- false
- end.
-
-find_obj(H, Obj, Pos) when Pos > 0 ->
- {Next, _Sz, Term} = prterm(H, Pos, ?ReadAhead),
- if
- Term == Obj ->
- {ok, Pos};
- true ->
- find_obj(H, Obj, Next)
- end.
-
-%% Given, a slot, return the {Pos, Chain} in the file where the
-%% objects hashed to this slot reside. Pos is the position in the
-%% file where the chain pointer is written and Chain is the position
-%% in the file where the first object resides.
-chain(Head, Slot) ->
- Pos = ?SEGADDR(?SLOT2SEG(Slot)),
- Segment = get_segp(Pos),
- FinalPos = Segment + (4 * ?REM2(Slot, ?SEGSZ)),
- {ok, <<Chain:32>>} = dets_utils:pread(Head, FinalPos, 4, 0),
- {FinalPos, Chain}.
-
-%%%
-%%% Cache routines depending on the dets file format.
-%%%
-
-%% -> {Head, [LookedUpObject], pwrite_list()} | throw({Head, Error})
-eval_work_list(Head, WorkLists) ->
- SWLs = tag_with_slot(WorkLists, Head, []),
- P1 = dets_utils:family(SWLs),
- {PerSlot, SlotPositions} = remove_slot_tag(P1, [], []),
- {ok, Bins} = dets_utils:pread(SlotPositions, Head),
- first_object(PerSlot, SlotPositions, Bins, Head, [], [], [], []).
-
-tag_with_slot([{K,_} = WL | WLs], Head, L) ->
- tag_with_slot(WLs, Head, [{db_hash(K, Head), WL} | L]);
-tag_with_slot([], _Head, L) ->
- L.
-
-remove_slot_tag([{S,SWLs} | SSWLs], Ls, SPs) ->
- remove_slot_tag(SSWLs, [SWLs | Ls], [slot_position(S) | SPs]);
-remove_slot_tag([], Ls, SPs) ->
- {Ls, SPs}.
-
-%% The initial chain pointers and the first object in each chain are
-%% read "in parallel", that is, with one call to file:pread/2 (two
-%% calls altogether). The following chain objects are read one by
-%% one. This is a compromise: if the chains are long and threads are
-%% active, it would be faster to keep a state for each chain and read
-%% the objects of the chains in parallel, but the overhead would be
-%% quite substantial.
-
-first_object([WorkLists | SPs], [{P1,_4} | Ss], [<<P2:32>> | Bs], Head,
- ObjsToRead, ToRead, Ls, LU) when P2 =:= 0 ->
- L0 = [{old,P1}],
- {L, NLU} = eval_slot(Head, ?ReadAhead, P2, WorkLists, L0, LU),
- first_object(SPs, Ss, Bs, Head, ObjsToRead, ToRead, [L | Ls], NLU);
-first_object([WorkLists | SPs], [{P1,_4} | Ss], [<<P2:32>> | Bs], Head,
- ObjsToRead, ToRead, Ls, LU) ->
- E = {P1,P2,WorkLists},
- first_object(SPs, Ss, Bs, Head,
- [E | ObjsToRead], [{P2, ?ReadAhead} | ToRead], Ls, LU);
-first_object([], [], [], Head, ObjsToRead, ToRead, Ls, LU) ->
- {ok, Bins} = dets_utils:pread(ToRead, Head),
- case catch eval_first(Bins, ObjsToRead, Head, Ls, LU) of
- {ok, NLs, NLU} ->
- case create_writes(NLs, Head, [], 0) of
- {Head1, [], 0} ->
- {Head1, NLU, []};
- {Head1, Ws, No} ->
- {NewHead, Ws2} = update_no_objects(Head1, Ws, No),
- {NewHead, NLU, Ws2}
- end;
- _Error ->
- throw(dets_utils:corrupt_reason(Head, bad_object))
- end.
-
-%% Update no_objects on the file too, if the number of segments that
-%% dets:fsck/6 use for estimate has changed.
-update_no_objects(Head, Ws, 0) -> {Head, Ws};
-update_no_objects(Head, Ws, Delta) ->
- No = Head#head.no_objects,
- NewNo = No + Delta,
- NWs =
- if
- NewNo > ?MAXOBJS ->
- Ws;
- ?SLOT2SEG(No) =:= ?SLOT2SEG(NewNo) ->
- Ws;
- true ->
- [{?NO_OBJECTS_POS, <<NewNo:32>>} | Ws]
- end,
- {Head#head{no_objects = NewNo}, NWs}.
-
-eval_first([<<Next:32, Sz:32, _Status:32, Bin/binary>> | Bins],
- [SP | SPs], Head, Ls, LU) ->
- {P1, P2, WLs} = SP,
- L0 = [{old,P1}],
- case byte_size(Bin) of
- BinSz when BinSz >= Sz ->
- Term = binary_to_term(Bin),
- Key = element(Head#head.keypos, Term),
- {L, NLU} = find_key(Head, P2, Next, Sz, Term, Key, WLs, L0, LU),
- eval_first(Bins, SPs, Head, [L | Ls], NLU);
- _BinSz ->
- {L, NLU} = eval_slot(Head, Sz+?OHDSZ, P2, WLs, L0, LU),
- eval_first(Bins, SPs, Head, [L | Ls], NLU)
- end;
-eval_first([], [], _Head, Ls, LU) ->
- {ok, Ls, LU}.
-
-eval_slot(_Head, _TrySize, _Pos=0, [], L, LU) ->
- {L, LU};
-eval_slot(Head, _TrySize, Pos=0, [WL | WLs], L, LU) ->
- {_Key, {_Delete, LookUp, Objects}} = WL,
- {NL, NLU} = end_of_key(Objects, LookUp, L, []),
- eval_slot(Head, ?ReadAhead, Pos, WLs, NL, NLU++LU);
-eval_slot(Head, TrySize, Pos, WLs, L, LU) ->
- {NextPos, Size, Term} = prterm(Head, Pos, TrySize),
- Key = element(Head#head.keypos, Term),
- find_key(Head, Pos, NextPos, Size, Term, Key, WLs, L, LU).
-
-find_key(Head, Pos, NextPos, Size, Term, Key, WLs, L, LU) ->
- case lists:keyfind(Key, 1, WLs) of
- {_, {Delete, LookUp, Objects}} = WL ->
- NWLs = lists:delete(WL, WLs),
- {NewObjects, NL, LUK} = eval_object(Size, Term, Delete, LookUp,
- Objects, Head, Pos, L, []),
- eval_key(Key, Delete, LookUp, NewObjects, Head, NextPos,
- NWLs, NL, LU, LUK);
- false ->
- L0 = [{old,Pos} | L],
- eval_slot(Head, ?ReadAhead, NextPos, WLs, L0, LU)
- end.
-
-eval_key(_Key, _Delete, Lookup, _Objects, Head, Pos, WLs, L, LU, LUK)
- when Head#head.type =:= set ->
- NLU = case Lookup of
- {lookup, Pid} -> [{Pid,LUK} | LU];
- skip -> LU
- end,
- eval_slot(Head, ?ReadAhead, Pos, WLs, L, NLU);
-eval_key(_Key, _Delete, LookUp, Objects, Head, Pos, WLs, L, LU, LUK)
- when Pos =:= 0 ->
- {NL, NLU} = end_of_key(Objects, LookUp, L, LUK),
- eval_slot(Head, ?ReadAhead, Pos, WLs, NL, NLU++LU);
-eval_key(Key, Delete, LookUp, Objects, Head, Pos, WLs, L, LU, LUK) ->
- {NextPos, Size, Term} = prterm(Head, Pos, ?ReadAhead),
- case element(Head#head.keypos, Term) of
- Key ->
- {NewObjects, NL, LUK1} =
- eval_object(Size, Term, Delete, LookUp,Objects,Head,Pos,L,LUK),
- eval_key(Key, Delete, LookUp, NewObjects, Head, NextPos, WLs,
- NL, LU, LUK1);
- Key2 ->
- {L1, NLU} = end_of_key(Objects, LookUp, L, LUK),
- find_key(Head, Pos, NextPos, Size, Term, Key2, WLs, L1, NLU++LU)
- end.
-
-%% All objects in Objects have the key Key.
-eval_object(Size, Term, Delete, LookUp, Objects, Head, Pos, L, LU) ->
- Type = Head#head.type,
- case lists:keyfind(Term, 1, Objects) of
- {_Object, N} when N =:= 0 ->
- L1 = [{delete,Pos,Size} | L],
- {Objects, L1, LU};
- {_Object, N} when N < 0, Type =:= set ->
- L1 = [{old,Pos} | L],
- wl_lookup(LookUp, Objects, Term, L1, LU);
- {Object, _N} when Type =:= bag -> % when N =:= 1; N =:= -1
- L1 = [{old,Pos} | L],
- Objects1 = lists:keydelete(Object, 1, Objects),
- wl_lookup(LookUp, Objects1, Term, L1, LU);
- {Object, N} when N < 0, Type =:= duplicate_bag ->
- L1 = [{old,Pos} | L],
- Objects1 = lists:keyreplace(Object, 1, Objects, {Object,N+1}),
- wl_lookup(LookUp, Objects1, Term, L1, LU);
- {_Object, N} when N > 0, Type =:= duplicate_bag ->
- L1 = [{old,Pos} | L],
- wl_lookup(LookUp, Objects, Term, L1, LU);
- false when Type =:= set, Delete =:= delete ->
- case lists:keyfind(-1, 2, Objects) of
- false -> % no inserted object, perhaps deleted objects
- L1 = [{delete,Pos,Size} | L],
- {[], L1, LU};
- {Term2, -1} ->
- Bin2 = term_to_binary(Term2),
- NSize = byte_size(Bin2),
- Overwrite =
- if
- NSize =:= Size ->
- true;
- true ->
- SizePos = sz2pos(Size+?OHDSZ),
- NSizePos = sz2pos(NSize+?OHDSZ),
- SizePos =:= NSizePos
- end,
- E = if
- Overwrite ->
- {overwrite,Bin2,Pos};
- true ->
- {replace,Bin2,Pos,Size}
- end,
- wl_lookup(LookUp, [], Term2, [E | L], LU)
- end;
- false when Delete =:= delete ->
- L1 = [{delete,Pos,Size} | L],
- {Objects, L1, LU};
- false ->
- L1 = [{old,Pos} | L],
- wl_lookup(LookUp, Objects, Term, L1, LU)
- end.
-
-%% Inlined.
-wl_lookup({lookup,_}, Objects, Term, L, LU) ->
- {Objects, L, [Term | LU]};
-wl_lookup(skip, Objects, _Term, L, LU) ->
- {Objects, L, LU}.
-
-end_of_key([{Object,N0} | Objs], LookUp, L, LU) when N0 =/= 0 ->
- N = abs(N0),
- NL = [{insert,N,term_to_binary(Object)} | L],
- NLU = case LookUp of
- {lookup, _} ->
- lists:duplicate(N, Object) ++ LU;
- skip ->
- LU
- end,
- end_of_key(Objs, LookUp, NL, NLU);
-end_of_key([_ | Objects], LookUp, L, LU) ->
- end_of_key(Objects, LookUp, L, LU);
-end_of_key([], {lookup,Pid}, L, LU) ->
- {L, [{Pid,LU}]};
-end_of_key([], skip, L, LU) ->
- {L, LU}.
-
-create_writes([L | Ls], H, Ws, No) ->
- {NH, NWs, NNo} = create_writes(L, H, Ws, No, 0, true),
- create_writes(Ls, NH, NWs, NNo);
-create_writes([], H, Ws, No) ->
- {H, lists:reverse(Ws), No}.
-
-create_writes([{old,Pos} | L], H, Ws, No, _Next, true) ->
- create_writes(L, H, Ws, No, Pos, true);
-create_writes([{old,Pos} | L], H, Ws, No, Next, false) ->
- W = {Pos, <<Next:32>>},
- create_writes(L, H, [W | Ws], No, Pos, true);
-create_writes([{insert,N,Bin} | L], H, Ws, No, Next, _NextIsOld) ->
- {NH, NWs, Pos} = create_inserts(N, H, Ws, Next, byte_size(Bin), Bin),
- create_writes(L, NH, NWs, No+N, Pos, false);
-create_writes([{overwrite,Bin,Pos} | L], H, Ws, No, Next, _) ->
- Size = byte_size(Bin),
- W = {Pos, [<<Next:32, Size:32, ?ACTIVE:32>>, Bin]},
- create_writes(L, H, [W | Ws], No, Pos, true);
-create_writes([{replace,Bin,Pos,OSize} | L], H, Ws, No, Next, _) ->
- Size = byte_size(Bin),
- {H1, _} = dets_utils:free(H, Pos, OSize+?OHDSZ),
- {NH, NewPos, _} = dets_utils:alloc(H1, ?OHDSZ + Size),
- W1 = {NewPos, [<<Next:32, Size:32, ?ACTIVE:32>>, Bin]},
- NWs = if
- Pos =:= NewPos ->
- [W1 | Ws];
- true ->
- W2 = {Pos+?STATUS_POS, <<?FREE:32>>},
- [W1,W2 | Ws]
- end,
- create_writes(L, NH, NWs, No, NewPos, false);
-create_writes([{delete,Pos,Size} | L], H, Ws, No, Next, _) ->
- {NH, _} = dets_utils:free(H, Pos, Size+?OHDSZ),
- NWs = [{Pos+?STATUS_POS,<<?FREE:32>>} | Ws],
- create_writes(L, NH, NWs, No-1, Next, false);
-create_writes([], H, Ws, No, _Next, _NextIsOld) ->
- {H, Ws, No}.
-
-create_inserts(0, H, Ws, Next, _Size, _Bin) ->
- {H, Ws, Next};
-create_inserts(N, H, Ws, Next, Size, Bin) ->
- {NH, Pos, _} = dets_utils:alloc(H, ?OHDSZ + Size),
- W = {Pos, [<<Next:32, Size:32, ?ACTIVE:32>>, Bin]},
- create_inserts(N-1, NH, [W | Ws], Pos, Size, Bin).
-
-slot_position(S) ->
- Pos = ?SEGADDR(?SLOT2SEG(S)),
- Segment = get_segp(Pos),
- FinalPos = Segment + (4 * ?REM2(S, ?SEGSZ)),
- {FinalPos, 4}.
-
-%% Twice the size of a segment due to the bug in sz2pos/1. Inlined.
-actual_seg_size() ->
- ?POW(sz2pos(?SEGSZ*4)-1).
-
-segp_cache(Pos, Segment) ->
- put(Pos, Segment).
-
-%% Inlined.
-get_segp(Pos) ->
- get(Pos).
-
-%% Bug: If Sz0 is equal to 2**k for some k, then 2**(k+1) bytes are
-%% allocated (wasting 2**k bytes).
-sz2pos(N) ->
- 1 + dets_utils:log2(N+1).
-
-scan_objs(_Head, Bin, From, To, L, Ts, R, _Type) ->
- scan_objs(Bin, From, To, L, Ts, R).
-
-scan_objs(Bin, From, To, L, Ts, -1) ->
- {stop, Bin, From, To, L, Ts};
-scan_objs(B = <<_N:32, Sz:32, St:32, T/binary>>, From, To, L, Ts, R) ->
- if
- St =:= ?ACTIVE;
- St =:= ?FREE -> % deleted after scanning started
- case T of
- <<BinTerm:Sz/binary, T2/binary>> ->
- NTs = [BinTerm | Ts],
- OSz = Sz + ?OHDSZ,
- Skip = ?POW(sz2pos(OSz)-1) - OSz,
- F2 = From + OSz,
- NR = if
- R < 0 ->
- R + 1;
- true ->
- R + OSz + Skip
- end,
- scan_skip(T2, F2, To, Skip, L, NTs, NR);
- _ ->
- {more, From, To, L, Ts, R, Sz+?OHDSZ}
- end;
- true -> % a segment
- scan_skip(B, From, To, actual_seg_size(), L, Ts, R)
- end;
-scan_objs(_B, From, To, L, Ts, R) ->
- {more, From, To, L, Ts, R, 0}.
-
-scan_skip(Bin, From, To, Skip, L, Ts, R) when From + Skip < To ->
- SkipPos = From + Skip,
- case Bin of
- <<_:Skip/binary, Tail/binary>> ->
- scan_objs(Tail, SkipPos, To, L, Ts, R);
- _ ->
- {more, SkipPos, To, L, Ts, R, 0}
- end;
-scan_skip(Bin, From, To, Skip, L, Ts, R) when From + Skip =:= To ->
- scan_next_allocated(Bin, From, To, L, Ts, R);
-scan_skip(_Bin, From, _To, Skip, L, Ts, R) -> % when From + Skip > _To
- From1 = From + Skip,
- {more, From1, From1, L, Ts, R, 0}.
-
-scan_next_allocated(_Bin, _From, To, <<>>=L, Ts, R) ->
- {more, To, To, L, Ts, R, 0};
-scan_next_allocated(Bin, From0, _To, <<From:32, To:32, L/binary>>, Ts, R) ->
- Skip = From - From0,
- scan_skip(Bin, From0, To, Skip, L, Ts, R).
-
-%% Read term from file at position Pos
-prterm(Head, Pos, ReadAhead) ->
- Res = dets_utils:pread(Head, Pos, ?OHDSZ, ReadAhead),
- ?DEBUGF("file:pread(~tp, ~p, ?) -> ~p~n", [Head#head.filename, Pos, Res]),
- {ok, <<Next:32, Sz:32, _Status:32, Bin0/binary>>} = Res,
- ?DEBUGF("{Next, Sz} = ~p~n", [{Next, Sz}]),
- Bin = case byte_size(Bin0) of
- Actual when Actual >= Sz ->
- Bin0;
- _ ->
- {ok, Bin1} = dets_utils:pread(Head, Pos + ?OHDSZ, Sz, 0),
- Bin1
- end,
- Term = binary_to_term(Bin),
- {Next, Sz, Term}.
-
-%%%%%%%%%%%%%%%%% DEBUG functions %%%%%%%%%%%%%%%%
-
-file_info(FH) ->
- #fileheader{closed_properly = CP, keypos = Kp,
- m = M, next = Next, n = N, version = Version,
- type = Type, no_objects = NoObjects}
- = FH,
- if
- CP =:= 0 ->
- {error, not_closed};
- FH#fileheader.cookie =/= ?MAGIC ->
- {error, not_a_dets_file};
- FH#fileheader.version =/= ?FILE_FORMAT_VERSION ->
- {error, bad_version};
- true ->
- {ok, [{closed_properly,CP},{keypos,Kp},{m, M},
- {n,N},{next,Next},{no_objects,NoObjects},
- {type,Type},{version,Version}]}
- end.
-
-v_segments(H) ->
- v_segments(H, 0).
-
-v_segments(_H, ?SEGARRSZ) ->
- done;
-v_segments(H, SegNo) ->
- Seg = dets_utils:read_4(H#head.fptr, ?SEGADDR(SegNo)),
- if
- Seg =:= 0 ->
- done;
- true ->
- io:format("SEGMENT ~w ", [SegNo]),
- io:format("At position ~w~n", [Seg]),
- v_segment(H, SegNo, Seg, 0),
- v_segments(H, SegNo+1)
- end.
-
-v_segment(_H, _, _SegPos, ?SEGSZ) ->
- done;
-v_segment(H, SegNo, SegPos, SegSlot) ->
- Slot = SegSlot + (SegNo * ?SEGSZ),
- Chain = dets_utils:read_4(H#head.fptr, SegPos + (4 * SegSlot)),
- if
- Chain =:= 0 -> %% don't print empty chains
- true;
- true ->
- io:format(" <~p>~p: [",[SegPos + (4 * SegSlot), Slot]),
- print_chain(H, Chain)
- end,
- v_segment(H, SegNo, SegPos, SegSlot+1).
-
-print_chain(_H, 0) ->
- io:format("] \n", []);
-print_chain(H, Pos) ->
- {ok, _} = file:position(H#head.fptr, Pos),
- case rterm(H#head.fptr) of
- {ok, 0, _Sz, Term} ->
- io:format("<~p>~p] \n",[Pos, Term]);
- {ok, Next, _Sz, Term} ->
- io:format("<~p>~p, ", [Pos, Term]),
- print_chain(H, Next);
- Other ->
- io:format("~nERROR ~p~n", [Other])
- end.
-
-%% Can't be used at the bucket level!!!!
-%% Only when we go down a chain
-rterm(F) ->
- case catch rterm2(F) of
- {'EXIT', Reason} -> %% truncated DAT file
- dets_utils:vformat("** dets: Corrupt or truncated dets file~n",
- []),
- {error, Reason};
- Other ->
- Other
- end.
-
-rterm2(F) ->
- {ok, <<Next:32, Sz:32, _:32>>} = file:read(F, ?OHDSZ),
- {ok, Bin} = file:read(F, Sz),
- Term = binary_to_term(Bin),
- {ok, Next, Sz, Term}.
-
-
diff --git a/lib/stdlib/src/dets_v9.erl b/lib/stdlib/src/dets_v9.erl
index 6c406fc03a..3ab8f87ebf 100644
--- a/lib/stdlib/src/dets_v9.erl
+++ b/lib/stdlib/src/dets_v9.erl
@@ -24,8 +24,8 @@
-export([mark_dirty/1, read_file_header/2,
check_file_header/2, do_perform_save/1, initiate_file/11,
- prep_table_copy/9, init_freelist/2, fsck_input/4,
- bulk_input/3, output_objs/4, bchunk_init/2,
+ prep_table_copy/9, init_freelist/1, fsck_input/4,
+ bulk_input/3, output_objs/3, bchunk_init/2,
try_bchunk_header/2, compact_init/3, read_bchunks/2,
write_cache/1, may_grow/3, find_object/2, slot_objs/2,
scan_objs/8, db_hash/2, no_slots/1, table_parameters/1]).
@@ -228,8 +228,8 @@
-define(CLOSED_PROPERLY_POS, 8).
-define(D_POS, 20).
-%%% Dets file versions up to 8 are handled in dets_v8. This module
-%%% handles version 9, introduced in R8.
+%%% This module handles Dets file format version 9, introduced in
+%%% Erlang/OTP R8.
%%%
%%% Version 9(a) tables have 256 reserved bytes in the file header,
%%% all initialized to zero.
@@ -249,32 +249,32 @@
-define(OHDSZ, 8). % The size of the object header, in bytes.
-define(STATUS_POS, 4). % Position of the status field.
--define(OHDSZ_v8, 12). % The size of the version 8 object header.
-
%% The size of each object is a multiple of 16.
%% BUMP is used when repairing files.
-define(BUMP, 16).
-%%% '$hash' is the value of HASH_PARMS in R8, '$hash2' is the value in R9.
+%%% '$hash' is the value of HASH_PARMS in Erlang/OTP R8, '$hash2' is
+%%% the value in Erlang/OTP R9.
%%%
%%% The fields of the ?HASH_PARMS records are the same, but having
-%%% different tags makes bchunk_init on R8 nodes reject data from R9
-%%% nodes, and vice versa. This is overkill, and due to an oversight.
-%%% What should have been done in R8 was to check the hash method, not
-%%% only the type of the table and the key position. R8 nodes cannot
-%%% handle the phash2 method.
+%%% different tags makes bchunk_init on Erlang/OTP R8 nodes reject
+%%% data from Erlang/OTP R9 nodes, and vice versa. This is overkill,
+%%% and due to an oversight. What should have been done in Erlang/OTP
+%%% R8 was to check the hash method, not only the type of the table
+%%% and the key position. Erlang/OTP R8 nodes cannot handle the phash2
+%%% method.
-define(HASH_PARMS, '$hash2').
-define(BCHUNK_FORMAT_VERSION, 1).
-record(?HASH_PARMS, {
- file_format_version,
+ file_format_version,
bchunk_format_version,
file, type, keypos, hash_method,
n,m,next,
min,max,
no_objects,no_keys,
- no_colls % [{LogSz,NoColls}], NoColls >= 0
+ no_colls :: no_colls()
}).
-define(ACTUAL_SEG_SIZE, (?SEGSZ*4)).
@@ -364,10 +364,8 @@ init_file(Fd, Tab, Fname, Type, Kp, MinSlots, MaxSlots, Ram, CacheSz,
filename = Fname,
name = Tab,
cache = dets_utils:new_cache(CacheSz),
- version = ?FILE_FORMAT_VERSION,
bump = ?BUMP,
- base = ?BASE, % to be overwritten
- mod = ?MODULE
+ base = ?BASE % to be overwritten
},
FreeListsPointer = 0,
@@ -457,7 +455,7 @@ alloc_seg(Head, SegZero, SegNo, Part) ->
{NewHead, InitSegment, [SegPointer]}.
%% Read free lists (using a Buddy System) from file.
-init_freelist(Head, true) ->
+init_freelist(Head) ->
Pos = Head#head.freelists_p,
free_lists_from_file(Head, Pos).
@@ -510,12 +508,10 @@ read_file_header(Fd, FileName) ->
md5 = erlang:md5(MD5DigestedPart),
trailer = FileSize + FlBase,
eof = EOF,
- n = N,
- mod = ?MODULE},
+ n = N},
{ok, Fd, FH}.
-%% -> {ok, head(), ExtraInfo} | {error, Reason} (Reason lacking file name)
-%% ExtraInfo = true
+%% -> {ok, head()} | {error, Reason} (Reason lacking file name)
check_file_header(FH, Fd) ->
HashBif = code_to_hash_method(FH#fileheader.hash_method),
Test =
@@ -534,14 +530,14 @@ check_file_header(FH, Fd) ->
HashBif =:= undefined ->
{error, bad_hash_bif};
FH#fileheader.closed_properly =:= ?CLOSED_PROPERLY ->
- {ok, true};
+ ok;
FH#fileheader.closed_properly =:= ?NOT_PROPERLY_CLOSED ->
{error, not_closed};
true ->
{error, not_a_dets_file}
end,
case Test of
- {ok, ExtraInfo} ->
+ ok ->
MaxObjSize = max_objsize(FH#fileheader.no_colls),
H = #head{
m = FH#fileheader.m,
@@ -563,11 +559,9 @@ check_file_header(FH, Fd) ->
min_no_slots = FH#fileheader.min_no_slots,
max_no_slots = FH#fileheader.max_no_slots,
no_collections = FH#fileheader.no_colls,
- version = ?FILE_FORMAT_VERSION,
- mod = ?MODULE,
bump = ?BUMP,
base = FH#fileheader.fl_base},
- {ok, H, ExtraInfo};
+ {ok, H};
Error ->
Error
end.
@@ -621,7 +615,7 @@ no_segs(NoSlots) ->
%%%
%%% bulk_input/3. Initialization, the general case (any stream of objects).
-%%% output_objs/4. Initialization (general case) and repair.
+%%% output_objs/3. Initialization (general case) and repair.
%%% bchunk_init/2. Initialization using bchunk.
bulk_input(Head, InitFun, _Cntrs) ->
@@ -678,7 +672,7 @@ bulk_objects([], _Head, Kp, Seq, L) when is_integer(Kp), is_integer(Seq) ->
-define(OBJ_COUNTER, 2).
-define(KEY_COUNTER, 3).
-output_objs(OldV, Head, SlotNums, Cntrs) when OldV =< 9 ->
+output_objs(Head, SlotNums, Cntrs) ->
fun(close) ->
%% Make sure that the segments are initialized in case
%% init_table has been called.
@@ -686,31 +680,31 @@ output_objs(OldV, Head, SlotNums, Cntrs) when OldV =< 9 ->
Acc = [], % This is the only way Acc can be empty.
true = ets:insert(Cntrs, {?FSCK_SEGMENT,0,[],0}),
true = ets:insert(Cntrs, {?COUNTERS, 0, 0}),
- Fun = output_objs2(foo, Acc, OldV, Head, Cache, Cntrs,
+ Fun = output_objs2(foo, Acc, Head, Cache, Cntrs,
SlotNums, bar),
Fun(close);
([]) ->
- output_objs(OldV, Head, SlotNums, Cntrs);
+ output_objs(Head, SlotNums, Cntrs);
(L) ->
%% Information about number of objects per size is not
%% relevant for version 9. It is the number of collections
%% that matters.
true = ets:delete_all_objects(Cntrs),
true = ets:insert(Cntrs, {?COUNTERS, 0, 0}),
- Es = bin2term(L, OldV, Head#head.keypos),
+ Es = bin2term(L, Head#head.keypos),
%% The cache is a tuple indexed by the (log) size. An element
%% is [BinaryObject].
Cache = ?VEMPTY,
{NE, NAcc, NCache} = output_slots(Es, Head, Cache, Cntrs, 0, 0),
- output_objs2(NE, NAcc, OldV, Head, NCache, Cntrs, SlotNums, 1)
+ output_objs2(NE, NAcc, Head, NCache, Cntrs, SlotNums, 1)
end.
-output_objs2(E, Acc, OldV, Head, Cache, SizeT, SlotNums, 0) ->
+output_objs2(E, Acc, Head, Cache, SizeT, SlotNums, 0) ->
NCache = write_all_sizes(Cache, SizeT, Head, more),
%% Number of handled file_sorter chunks before writing:
Max = erlang:max(1, erlang:min(tuple_size(NCache), 10)),
- output_objs2(E, Acc, OldV, Head, NCache, SizeT, SlotNums, Max);
-output_objs2(E, Acc, OldV, Head, Cache, SizeT, SlotNums, ChunkI) ->
+ output_objs2(E, Acc, Head, NCache, SizeT, SlotNums, Max);
+output_objs2(E, Acc, Head, Cache, SizeT, SlotNums, ChunkI) ->
fun(close) ->
{_, [], Cache1} =
if
@@ -747,11 +741,10 @@ output_objs2(E, Acc, OldV, Head, Cache, SizeT, SlotNums, ChunkI) ->
end
end;
(L) ->
- Es = bin2term(L, OldV, Head#head.keypos),
+ Es = bin2term(L, Head#head.keypos),
{NE, NAcc, NCache} =
output_slots(E, Es, Acc, Head, Cache, SizeT, 0, 0),
- output_objs2(NE, NAcc, OldV, Head, NCache, SizeT, SlotNums,
- ChunkI-1)
+ output_objs2(NE, NAcc, Head, NCache, SizeT, SlotNums, ChunkI-1)
end.
%%% Compaction.
@@ -1245,10 +1238,8 @@ allocate_all(Head, [{LSize,_,Data,NoCollections} | DTL], L) ->
E = {LSize,Addr,Data,NoCollections},
allocate_all(NewHead, DTL, [E | L]).
-bin2term(Bin, 9, Kp) ->
- bin2term1(Bin, Kp, []);
-bin2term(Bin, 8, Kp) ->
- bin2term_v8(Bin, Kp, []).
+bin2term(Bin, Kp) ->
+ bin2term1(Bin, Kp, []).
bin2term1([<<Slot:32, Seq:32, BinTerm/binary>> | BTs], Kp, L) ->
Term = binary_to_term(BinTerm),
@@ -1257,13 +1248,6 @@ bin2term1([<<Slot:32, Seq:32, BinTerm/binary>> | BTs], Kp, L) ->
bin2term1([], _Kp, L) ->
lists:reverse(L).
-bin2term_v8([<<Slot:32, BinTerm/binary>> | BTs], Kp, L) ->
- Term = binary_to_term(BinTerm),
- Key = element(Kp, Term),
- bin2term_v8(BTs, Kp, [{Slot, Key, foo, Term, BinTerm} | L]);
-bin2term_v8([], _Kp, L) ->
- lists:reverse(L).
-
write_all_sizes({}=Cache, _SizeT, _Head, _More) ->
Cache;
write_all_sizes(Cache, SizeT, Head, More) ->
@@ -1461,7 +1445,7 @@ temp_file(Head, SizeT, N) ->
%% Does not close Fd.
fsck_input(Head, Fd, Cntrs, FileHeader) ->
MaxSz0 = case FileHeader#fileheader.has_md5 of
- true when is_integer(FileHeader#fileheader.no_colls) ->
+ true when is_list(FileHeader#fileheader.no_colls) ->
?POW(max_objsize(FileHeader#fileheader.no_colls));
_ ->
%% The file is not compressed, so the bucket size
@@ -1485,10 +1469,10 @@ fsck_input(Head, State, Fd, MaxSz, Cntrs) ->
done ->
end_of_input;
{done, L, _Seq} ->
- R = count_input(Head, Cntrs, L),
+ R = count_input(L),
{R, fsck_input(Head, done, Fd, MaxSz, Cntrs)};
{cont, L, Bin, Pos, Seq} ->
- R = count_input(Head, Cntrs, L),
+ R = count_input(L),
FR = fsck_objs(Bin, Head#head.keypos, Head, [], Seq),
NewState = fsck_read(FR, Pos, Fd, MaxSz, Head),
{R, fsck_input(Head, NewState, Fd, MaxSz, Cntrs)}
@@ -1496,20 +1480,9 @@ fsck_input(Head, State, Fd, MaxSz, Cntrs) ->
end.
%% The ets table Cntrs is used for counting objects per size.
-count_input(Head, Cntrs, L) when Head#head.version =:= 8 ->
- count_input1(Cntrs, L, []);
-count_input(_Head, _Cntrs, L) ->
+count_input(L) ->
lists:reverse(L).
-count_input1(Cntrs, [[LogSz | B] | Ts], L) ->
- case catch ets:update_counter(Cntrs, LogSz, 1) of
- N when is_integer(N) -> ok;
- _Badarg -> true = ets:insert(Cntrs, {LogSz, 1})
- end,
- count_input1(Cntrs, Ts, [B | L]);
-count_input1(_Cntrs, [], L) ->
- L.
-
fsck_read(Pos, F, L, Seq) ->
case file:position(F, Pos) of
{ok, _} ->
@@ -1564,11 +1537,6 @@ fsck_objs(Bin = <<Sz:32, Status:32, Tail/binary>>, Kp, Head, L, Seq) ->
fsck_objs(Bin, _Kp, _Head, L, Seq) ->
{more, Bin, 0, L, Seq}.
-make_objects([{K,BT}|Os], Seq, Kp, Head, L) when Head#head.version =:= 8 ->
- LogSz = dets_v8:sz2pos(byte_size(BT)+?OHDSZ_v8),
- Slot = dets_v8:db_hash(K, Head),
- Obj = [LogSz | <<Slot:32, LogSz:8, BT/binary>>],
- make_objects(Os, Seq, Kp, Head, [Obj | L]);
make_objects([{K,BT} | Os], Seq, Kp, Head, L) ->
Obj = make_object(Head, K, Seq, BT),
make_objects(Os, Seq+1, Kp, Head, [Obj | L]);
@@ -1607,7 +1575,7 @@ do_perform_save(H) ->
FileHeader = file_header(H1, FreeListsPointer, ?CLOSED_PROPERLY),
case dets_utils:debug_mode() of
true ->
- TmpHead0 = init_freelist(H1#head{fixed = false}, true),
+ TmpHead0 = init_freelist(H1#head{fixed = false}),
TmpHead = TmpHead0#head{base = H1#head.base},
case
catch dets_utils:all_allocated_as_list(TmpHead)
@@ -1794,7 +1762,7 @@ table_parameters(Head) ->
(E, A) -> [E | A]
end, [], CL),
NoColls = lists:reverse(NoColls0),
- #?HASH_PARMS{file_format_version = Head#head.version,
+ #?HASH_PARMS{file_format_version = ?FILE_FORMAT_VERSION,
bchunk_format_version = ?BCHUNK_FORMAT_VERSION,
file = filename:basename(Head#head.filename),
type = Head#head.type,
diff --git a/lib/stdlib/src/dict.erl b/lib/stdlib/src/dict.erl
index f921e28ef6..9449ba3dc2 100644
--- a/lib/stdlib/src/dict.erl
+++ b/lib/stdlib/src/dict.erl
@@ -38,7 +38,7 @@
%% Standard interface.
-export([new/0,is_key/2,to_list/1,from_list/1,size/1,is_empty/1]).
--export([fetch/2,find/2,fetch_keys/1,erase/2]).
+-export([fetch/2,find/2,fetch_keys/1,erase/2,take/2]).
-export([store/3,append/3,append_list/3,update/3,update/4,update_counter/3]).
-export([fold/3,map/2,filter/2,merge/3]).
@@ -172,6 +172,27 @@ erase_key(Key, [E|Bkt0]) ->
{[E|Bkt1],Dc};
erase_key(_, []) -> {[],0}.
+-spec take(Key, Dict) -> {Value, Dict1} | error when
+ Dict :: dict(Key, Value),
+ Dict1 :: dict(Key, Value),
+ Key :: term(),
+ Value :: term().
+
+take(Key, D0) ->
+ Slot = get_slot(D0, Key),
+ case on_bucket(fun (B0) -> take_key(Key, B0) end, D0, Slot) of
+ {D1,{Value,Dc}} ->
+ {Value, maybe_contract(D1, Dc)};
+ {_,error} -> error
+ end.
+
+take_key(Key, [?kv(Key,Val)|Bkt]) ->
+ {Bkt,{Val,1}};
+take_key(Key, [E|Bkt0]) ->
+ {Bkt1,Res} = take_key(Key, Bkt0),
+ {[E|Bkt1],Res};
+take_key(_, []) -> {[],error}.
+
-spec store(Key, Value, Dict1) -> Dict2 when
Dict1 :: dict(Key, Value),
Dict2 :: dict(Key, Value).
diff --git a/lib/stdlib/src/edlin_expand.erl b/lib/stdlib/src/edlin_expand.erl
index ec64470461..a1a97af4c5 100644
--- a/lib/stdlib/src/edlin_expand.erl
+++ b/lib/stdlib/src/edlin_expand.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -101,44 +101,77 @@ match(Prefix, Alts, Extra0) ->
%% Return the list of names L in multiple columns.
format_matches(L) ->
- S = format_col(lists:sort(L), []),
+ {S1, Dots} = format_col(lists:sort(L), []),
+ S = case Dots of
+ true ->
+ {_, Prefix} = longest_common_head(vals(L)),
+ PrefixLen = length(Prefix),
+ case PrefixLen =< 3 of
+ true -> S1; % Do not replace the prefix with "...".
+ false ->
+ LeadingDotsL = leading_dots(L, PrefixLen),
+ {S2, _} = format_col(lists:sort(LeadingDotsL), []),
+ S2
+ end;
+ false -> S1
+ end,
["\n" | S].
format_col([], _) -> [];
-format_col(L, Acc) -> format_col(L, field_width(L), 0, Acc).
-
-format_col(X, Width, Len, Acc) when Width + Len > 79 ->
- format_col(X, Width, 0, ["\n" | Acc]);
-format_col([A|T], Width, Len, Acc0) ->
- H = case A of
- %% If it's a tuple {string(), integer()}, we assume it's an
- %% arity, and meant to be printed.
- {H0, I} when is_integer(I) ->
- H0 ++ "/" ++ integer_to_list(I);
- {H1, _} -> H1;
- H2 -> H2
- end,
- Acc = [io_lib:format("~-*s", [Width,H]) | Acc0],
- format_col(T, Width, Len+Width, Acc);
-format_col([], _, _, Acc) ->
- lists:reverse(Acc, "\n").
-
-field_width(L) -> field_width(L, 0).
-
-field_width([{H,_}|T], W) ->
+format_col(L, Acc) ->
+ LL = 79,
+ format_col(L, field_width(L, LL), 0, Acc, LL, false).
+
+format_col(X, Width, Len, Acc, LL, Dots) when Width + Len > LL ->
+ format_col(X, Width, 0, ["\n" | Acc], LL, Dots);
+format_col([A|T], Width, Len, Acc0, LL, Dots) ->
+ {H0, R} = format_val(A),
+ Hmax = LL - length(R),
+ {H, NewDots} =
+ case length(H0) > Hmax of
+ true -> {io_lib:format("~-*ts", [Hmax - 3, H0]) ++ "...", true};
+ false -> {H0, Dots}
+ end,
+ Acc = [io_lib:format("~-*ts", [Width, H ++ R]) | Acc0],
+ format_col(T, Width, Len+Width, Acc, LL, NewDots);
+format_col([], _, _, Acc, _LL, Dots) ->
+ {lists:reverse(Acc, "\n"), Dots}.
+
+format_val({H, I}) when is_integer(I) ->
+ %% If it's a tuple {string(), integer()}, we assume it's an
+ %% arity, and meant to be printed.
+ {H, "/" ++ integer_to_list(I)};
+format_val({H, _}) ->
+ {H, ""};
+format_val(H) ->
+ {H, ""}.
+
+field_width(L, LL) -> field_width(L, 0, LL).
+
+field_width([{H,_}|T], W, LL) ->
case length(H) of
- L when L > W -> field_width(T, L);
- _ -> field_width(T, W)
+ L when L > W -> field_width(T, L, LL);
+ _ -> field_width(T, W, LL)
end;
-field_width([H|T], W) ->
+field_width([H|T], W, LL) ->
case length(H) of
- L when L > W -> field_width(T, L);
- _ -> field_width(T, W)
+ L when L > W -> field_width(T, L, LL);
+ _ -> field_width(T, W, LL)
end;
-field_width([], W) when W < 40 ->
+field_width([], W, LL) when W < LL - 3 ->
W + 4;
-field_width([], _) ->
- 40.
+field_width([], _, LL) ->
+ LL.
+
+vals([]) -> [];
+vals([{S, _}|L]) -> [S|vals(L)];
+vals([S|L]) -> [S|vals(L)].
+
+leading_dots([], _Len) -> [];
+leading_dots([{H, I}|L], Len) ->
+ [{"..." ++ nthtail(Len, H), I}|leading_dots(L, Len)];
+leading_dots([H|L], Len) ->
+ ["..." ++ nthtail(Len, H)|leading_dots(L, Len)].
longest_common_head([]) ->
no;
diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index 40eba4ad67..31d0d499e3 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -194,27 +194,27 @@ format_error(missing_parenthesis) ->
format_error(premature_end) ->
"premature end";
format_error({call,What}) ->
- io_lib:format("illegal macro call '~s'",[What]);
+ io_lib:format("illegal macro call '~ts'",[What]);
format_error({undefined,M,none}) ->
- io_lib:format("undefined macro '~s'", [M]);
+ io_lib:format("undefined macro '~ts'", [M]);
format_error({undefined,M,A}) ->
- io_lib:format("undefined macro '~s/~p'", [M,A]);
+ io_lib:format("undefined macro '~ts/~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 '~s'", [M]);
+ io_lib:format("argument mismatch for macro '~ts'", [M]);
format_error({arg_error,M}) ->
- io_lib:format("badly formed argument for macro '~s'", [M]);
+ io_lib:format("badly formed argument for macro '~ts'", [M]);
format_error({redefine,M}) ->
- io_lib:format("redefining macro '~s'", [M]);
+ io_lib:format("redefining macro '~ts'", [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]);
+ io_lib:format("circular macro '~ts'", [M]);
format_error({circular,M,A}) ->
- io_lib:format("circular macro '~s/~p'", [M,A]);
+ io_lib:format("circular macro '~ts/~p'", [M,A]);
format_error({include,W,F}) ->
- io_lib:format("can't find include ~s \"~s\"", [W,F]);
+ io_lib:format("can't find include ~s \"~ts\"", [W,F]);
format_error({illegal,How,What}) ->
io_lib:format("~s '-~s'", [How,What]);
format_error({illegal_function,Macro}) ->
@@ -224,9 +224,9 @@ format_error({illegal_function_usage,Macro}) ->
format_error({'NYI',What}) ->
io_lib:format("not yet implemented '~s'", [What]);
format_error({error,Term}) ->
- io_lib:format("-error(~p).", [Term]);
+ io_lib:format("-error(~tp).", [Term]);
format_error({warning,Term}) ->
- io_lib:format("-warning(~p).", [Term]);
+ io_lib:format("-warning(~tp).", [Term]);
format_error(E) -> file:format_error(E).
-spec parse_file(FileName, IncludePath, PredefMacros) ->
@@ -286,7 +286,7 @@ parse_file(Epp) ->
{warning,W} ->
[{warning,W}|parse_file(Epp)];
{eof,Location} ->
- [{eof,erl_anno:new(Location)}]
+ [{eof,Location}]
end.
-spec default_encoding() -> source_encoding().
@@ -1307,7 +1307,7 @@ expand_macros([{'?',_Lq},Token|_Toks], _St) ->
Text;
undefined ->
Symbol = erl_scan:symbol(Token),
- io_lib:write(Symbol)
+ io_lib:fwrite(<<"~tp">>, [Symbol])
end,
throw({error,loc(Token),{call,[$?|T]}});
expand_macros([T|Ts], St) ->
diff --git a/lib/stdlib/src/erl_abstract_code.erl b/lib/stdlib/src/erl_abstract_code.erl
new file mode 100644
index 0000000000..6e45f11aa3
--- /dev/null
+++ b/lib/stdlib/src/erl_abstract_code.erl
@@ -0,0 +1,28 @@
+-module(erl_abstract_code).
+-export([debug_info/4]).
+
+debug_info(_Format, _Module, {none,_CompilerOpts}, _Opts) ->
+ {error, missing};
+debug_info(erlang_v1, _Module, {AbstrCode,_CompilerOpts}, _Opts) ->
+ {ok, AbstrCode};
+debug_info(core_v1, _Module, {AbstrCode,CompilerOpts}, Opts) ->
+ CoreOpts = add_core_returns(delete_reports(CompilerOpts ++ Opts)),
+ try compile:noenv_forms(AbstrCode, CoreOpts) of
+ {ok, _, Core, _} -> {ok, Core};
+ _What -> {error, failed_conversion}
+ catch
+ error:_ -> {error, failed_conversion}
+ end;
+debug_info(_, _, _, _) ->
+ {error, unknown_format}.
+
+delete_reports(Opts) ->
+ [Opt || Opt <- Opts, not is_report_option(Opt)].
+
+is_report_option(report) -> true;
+is_report_option(report_errors) -> true;
+is_report_option(report_warnings) -> true;
+is_report_option(_) -> false.
+
+add_core_returns(Opts) ->
+ [to_core, return_errors, return_warnings] ++ Opts.
diff --git a/lib/stdlib/src/erl_anno.erl b/lib/stdlib/src/erl_anno.erl
index d32c34dabd..d0310f52e2 100644
--- a/lib/stdlib/src/erl_anno.erl
+++ b/lib/stdlib/src/erl_anno.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@
%% Debug: define DEBUG to make sure that annotations are handled as an
%% opaque type. Note that all abstract code need to be compiled with
-%% DEBUG=true. See also ./erl_pp.erl.
+%% DEBUG=true. See also ./erl_pp.erl and ./erl_parse.yrl.
%-define(DEBUG, true).
@@ -52,7 +52,11 @@
| {'record', record()}
| {'text', string()}.
+-ifdef(DEBUG).
+-opaque anno() :: [annotation(), ...].
+-else.
-opaque anno() :: location() | [annotation(), ...].
+-endif.
-type anno_term() :: term().
-type column() :: pos_integer().
diff --git a/lib/stdlib/src/erl_compile.erl b/lib/stdlib/src/erl_compile.erl
index a6ae398d03..18d7548fdc 100644
--- a/lib/stdlib/src/erl_compile.erl
+++ b/lib/stdlib/src/erl_compile.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -181,7 +181,7 @@ parse_generic_option("P", T, #options{specific=Spec}=Opts) ->
parse_generic_option("S", T, #options{specific=Spec}=Opts) ->
compile1(T, Opts#options{specific=['S'|Spec]});
parse_generic_option(Option, _T, _Opts) ->
- io:format(?STDERR, "Unknown option: -~s\n", [Option]),
+ io:format(?STDERR, "Unknown option: -~ts\n", [Option]),
usage().
parse_dep_option("", T) ->
@@ -202,7 +202,7 @@ parse_dep_option("T"++Opt, T0) ->
{Target,T} = get_option("MT", Opt, T0),
{[{makedep_target,Target}],T};
parse_dep_option(Opt, _T) ->
- io:format(?STDERR, "Unknown option: -M~s\n", [Opt]),
+ io:format(?STDERR, "Unknown option: -M~ts\n", [Opt]),
usage().
usage() ->
@@ -337,7 +337,7 @@ file_or_directory(Name) ->
make_term(Str) ->
case erl_scan:string(Str) of
{ok, Tokens, _} ->
- case erl_parse:parse_term(Tokens ++ [{dot, 1}]) of
+ case erl_parse:parse_term(Tokens ++ [{dot, erl_anno:new(1)}]) of
{ok, Term} -> Term;
{error, {_,_,Reason}} ->
io:format(?STDERR, "~ts: ~ts~n", [Reason, Str]),
diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl
index 40a34aa30f..eafee346eb 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.erl
@@ -1306,6 +1306,7 @@ partial_eval(Expr) ->
ev_expr({op,_,Op,L,R}) -> erlang:Op(ev_expr(L), ev_expr(R));
ev_expr({op,_,Op,A}) -> erlang:Op(ev_expr(A));
ev_expr({integer,_,X}) -> X;
+ev_expr({char,_,X}) -> X;
ev_expr({float,_,X}) -> X;
ev_expr({atom,_,X}) -> X;
ev_expr({tuple,_,Es}) ->
diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl
index ebcbc54ab1..d7bd15d9db 100644
--- a/lib/stdlib/src/erl_expand_records.erl
+++ b/lib/stdlib/src/erl_expand_records.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -17,7 +17,8 @@
%%
%% %CopyrightEnd%
%%
-%% Purpose : Expand records into tuples.
+%% Purpose: Expand records into tuples. Also add explicit module
+%% names to calls to imported functions and BIFs.
%% N.B. Although structs (tagged tuples) are not yet allowed in the
%% language there is code included in pattern/2 and expr/3 (commented out)
@@ -29,13 +30,13 @@
-import(lists, [map/2,foldl/3,foldr/3,sort/1,reverse/1,duplicate/2]).
--record(exprec, {compile=[], % Compile flags
- vcount=0, % Variable counter
- imports=[], % Imports
- records=dict:new(), % Record definitions
- strict_ra=[], % strict record accesses
- checked_ra=[] % successfully accessed records
- }).
+-record(exprec, {compile=[], % Compile flags
+ vcount=0, % Variable counter
+ calltype=#{}, % Call types
+ records=#{}, % Record definitions
+ strict_ra=[], % strict record accesses
+ checked_ra=[] % successfully accessed records
+ }).
-spec(module(AbsForms, CompileOptions) -> AbsForms2 when
AbsForms :: [erl_parse:abstract_form()],
@@ -46,22 +47,34 @@
%% erl_lint without errors.
module(Fs0, Opts0) ->
Opts = compiler_options(Fs0) ++ Opts0,
- St0 = #exprec{compile = Opts},
+ Calltype = init_calltype(Fs0),
+ St0 = #exprec{compile = Opts, calltype = Calltype},
{Fs,_St} = forms(Fs0, St0),
Fs.
compiler_options(Forms) ->
lists:flatten([C || {attribute,_,compile,C} <- Forms]).
+init_calltype(Forms) ->
+ Locals = [{{Name,Arity},local} || {function,_,Name,Arity,_} <- Forms],
+ Ctype = maps:from_list(Locals),
+ init_calltype_imports(Forms, Ctype).
+
+init_calltype_imports([{attribute,_,import,{Mod,Fs}}|T], Ctype0) ->
+ true = is_atom(Mod),
+ Ctype = foldl(fun(FA, Acc) ->
+ Acc#{FA=>{imported,Mod}}
+ end, Ctype0, Fs),
+ init_calltype_imports(T, Ctype);
+init_calltype_imports([_|T], Ctype) ->
+ init_calltype_imports(T, Ctype);
+init_calltype_imports([], Ctype) -> Ctype.
+
forms([{attribute,_,record,{Name,Defs}}=Attr | Fs], St0) ->
NDefs = normalise_fields(Defs),
- St = St0#exprec{records=dict:store(Name, NDefs, St0#exprec.records)},
+ St = St0#exprec{records=maps:put(Name, NDefs, St0#exprec.records)},
{Fs1, St1} = forms(Fs, St),
{[Attr | Fs1], St1};
-forms([{attribute,L,import,Is} | Fs0], St0) ->
- St1 = import(Is, St0),
- {Fs,St2} = forms(Fs0, St1),
- {[{attribute,L,import,Is} | Fs], St2};
forms([{function,L,N,A,Cs0} | Fs0], St0) ->
{Cs,St1} = clauses(Cs0, St0),
{Fs,St2} = forms(Fs0, St1),
@@ -334,8 +347,16 @@ expr({'receive',Line,Cs0,To0,ToEs0}, St0) ->
{ToEs,St2} = exprs(ToEs0, St1),
{Cs,St3} = clauses(Cs0, St2),
{{'receive',Line,Cs,To,ToEs},St3};
-expr({'fun',_,{function,_F,_A}}=Fun, St) ->
- {Fun,St};
+expr({'fun',Lf,{function,F,A}}=Fun0, St0) ->
+ case erl_internal:bif(F, A) of
+ true ->
+ {As,St1} = new_vars(A, Lf, St0),
+ Cs = [{clause,Lf,As,[],[{call,Lf,{atom,Lf,F},As}]}],
+ Fun = {'fun',Lf,{clauses,Cs}},
+ expr(Fun, St1);
+ false ->
+ {Fun0,St0}
+ end;
expr({'fun',_,{function,_M,_F,_A}}=Fun, St) ->
{Fun,St};
expr({'fun',Line,{clauses,Cs0}}, St0) ->
@@ -352,14 +373,30 @@ expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}},
expr({call,Line,{tuple,_,[{atom,_,erlang},{atom,_,is_record}]},
[A,{atom,_,Name}]}, St) ->
record_test(Line, A, Name, St);
+expr({call,Line,{atom,_La,record_info},[_,_]=As0}, St0) ->
+ {As,St1} = expr_list(As0, St0),
+ record_info_call(Line, As, St1);
expr({call,Line,{atom,_La,N}=Atom,As0}, St0) ->
{As,St1} = expr_list(As0, St0),
Ar = length(As),
- case {N,Ar} =:= {record_info,2} andalso not imported(N, Ar, St1) of
- true ->
- record_info_call(Line, As, St1);
- false ->
- {{call,Line,Atom,As},St1}
+ NA = {N,Ar},
+ case St0#exprec.calltype of
+ #{NA := local} ->
+ {{call,Line,Atom,As},St1};
+ #{NA := {imported,Module}} ->
+ ModAtom = {atom,Line,Module},
+ {{call,Line,{remote,Line,ModAtom,Atom},As},St1};
+ _ ->
+ case erl_internal:bif(N, Ar) of
+ true ->
+ ModAtom = {atom,Line,erlang},
+ {{call,Line,{remote,Line,ModAtom,Atom},As},St1};
+ false ->
+ %% Call to a module_info/0,1 or one of the
+ %% pseudo-functions in the shell. Leave it as
+ %% a local call.
+ {{call,Line,Atom,As},St1}
+ end
end;
expr({call,Line,{remote,Lr,M,F},As0}, St0) ->
{[M1,F1 | As1],St1} = expr_list([M,F | As0], St0),
@@ -470,9 +507,16 @@ lc_tq(Line, [{b_generate,Lg,P0,G0} | Qs0], St0) ->
{P1,St2} = pattern(P0, St1),
{Qs1,St3} = lc_tq(Line, Qs0, St2),
{[{b_generate,Lg,P1,G1} | Qs1],St3};
-lc_tq(Line, [F0 | Qs0], St0) ->
+lc_tq(Line, [F0 | Qs0], #exprec{calltype=Calltype}=St0) ->
%% Allow record/2 and expand out as guard test.
- case erl_lint:is_guard_test(F0) of
+ IsOverriden = fun(FA) ->
+ case Calltype of
+ #{FA := local} -> true;
+ #{FA := {imported,_}} -> true;
+ _ -> false
+ end
+ end,
+ case erl_lint:is_guard_test(F0, [], IsOverriden) of
true ->
{F1,St1} = guard_test(F0, St0),
{Qs1,St2} = lc_tq(Line, Qs0, St1),
@@ -502,7 +546,7 @@ normalise_fields(Fs) ->
%% record_fields(RecordName, State)
%% find_field(FieldName, Fields)
-record_fields(R, St) -> dict:fetch(R, St#exprec.records).
+record_fields(R, St) -> maps:get(R, St#exprec.records).
find_field(F, [{record_field,_,{atom,_,F},Val} | _]) -> {ok,Val};
find_field(F, [_ | Fs]) -> find_field(F, Fs);
@@ -769,6 +813,13 @@ bin_element({bin_element,Line,Expr,Size,Type}, {Es,St0}) ->
end,
{[{bin_element,Line,Expr1,Size1,Type} | Es],St2}.
+new_vars(N, L, St) -> new_vars(N, L, St, []).
+
+new_vars(N, L, St0, Vs) when N > 0 ->
+ {V,St1} = new_var(L, St0),
+ new_vars(N-1, L, St1, [V|Vs]);
+new_vars(0, _L, St, Vs) -> {Vs,St}.
+
new_var(L, St0) ->
{New,St1} = new_var_name(St0),
{{var,L,New},St1}.
@@ -783,18 +834,6 @@ make_list(Ts, Line) ->
call_error(L, R) ->
{call,L,{remote,L,{atom,L,erlang},{atom,L,error}},[R]}.
-import({Mod,Fs}, St) ->
- St#exprec{imports=add_imports(Mod, Fs, St#exprec.imports)};
-import(_Mod0, St) ->
- St.
-
-add_imports(Mod, [F | Fs], Is) ->
- add_imports(Mod, Fs, orddict:store(F, Mod, Is));
-add_imports(_, [], Is) -> Is.
-
-imported(F, A, St) ->
- orddict:is_key({F,A}, St#exprec.imports).
-
%%%
%%% Replace is_record/3 in guards with matching if possible.
%%%
diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl
index c08328b4b7..89b97b901e 100644
--- a/lib/stdlib/src/erl_internal.erl
+++ b/lib/stdlib/src/erl_internal.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -54,6 +54,8 @@
-export([is_type/2]).
+-export([add_predefined_functions/1]).
+
%%---------------------------------------------------------------------------
%% Erlang builtin functions allowed in guards.
@@ -61,42 +63,28 @@
Name :: atom(),
Arity :: arity().
+%% Please keep the alphabetical order.
guard_bif(abs, 1) -> true;
-guard_bif(float, 1) -> true;
-guard_bif(trunc, 1) -> true;
-guard_bif(round, 1) -> true;
-guard_bif(length, 1) -> true;
-guard_bif(hd, 1) -> true;
-guard_bif(tl, 1) -> true;
-guard_bif(size, 1) -> true;
+guard_bif(binary_part, 2) -> true;
+guard_bif(binary_part, 3) -> true;
guard_bif(bit_size, 1) -> true;
guard_bif(byte_size, 1) -> true;
+guard_bif(ceil, 1) -> true;
guard_bif(element, 2) -> true;
-guard_bif(self, 0) -> true;
+guard_bif(float, 1) -> true;
+guard_bif(floor, 1) -> true;
+guard_bif(hd, 1) -> true;
+guard_bif(length, 1) -> true;
guard_bif(map_size, 1) -> true;
guard_bif(node, 0) -> true;
guard_bif(node, 1) -> true;
+guard_bif(round, 1) -> true;
+guard_bif(self, 0) -> true;
+guard_bif(size, 1) -> true;
+guard_bif(tl, 1) -> true;
+guard_bif(trunc, 1) -> true;
guard_bif(tuple_size, 1) -> true;
-guard_bif(is_atom, 1) -> true;
-guard_bif(is_binary, 1) -> true;
-guard_bif(is_bitstring, 1) -> true;
-guard_bif(is_boolean, 1) -> true;
-guard_bif(is_float, 1) -> true;
-guard_bif(is_function, 1) -> true;
-guard_bif(is_function, 2) -> true;
-guard_bif(is_integer, 1) -> true;
-guard_bif(is_list, 1) -> true;
-guard_bif(is_map, 1) -> true;
-guard_bif(is_number, 1) -> true;
-guard_bif(is_pid, 1) -> true;
-guard_bif(is_port, 1) -> true;
-guard_bif(is_reference, 1) -> true;
-guard_bif(is_tuple, 1) -> true;
-guard_bif(is_record, 2) -> true;
-guard_bif(is_record, 3) -> true;
-guard_bif(binary_part, 2) -> true;
-guard_bif(binary_part, 3) -> true;
-guard_bif(Name, A) when is_atom(Name), is_integer(A) -> false.
+guard_bif(Name, A) -> new_type_test(Name, A).
%% Erlang type tests.
-spec type_test(Name, Arity) -> boolean() when
@@ -109,10 +97,11 @@ type_test(Name, Arity) ->
%% Erlang new-style type tests.
-spec new_type_test(Name::atom(), Arity::arity()) -> boolean().
+%% Please keep the alphabetical order.
new_type_test(is_atom, 1) -> true;
-new_type_test(is_boolean, 1) -> true;
new_type_test(is_binary, 1) -> true;
new_type_test(is_bitstring, 1) -> true;
+new_type_test(is_boolean, 1) -> true;
new_type_test(is_float, 1) -> true;
new_type_test(is_function, 1) -> true;
new_type_test(is_function, 2) -> true;
@@ -122,10 +111,10 @@ new_type_test(is_map, 1) -> true;
new_type_test(is_number, 1) -> true;
new_type_test(is_pid, 1) -> true;
new_type_test(is_port, 1) -> true;
-new_type_test(is_reference, 1) -> true;
-new_type_test(is_tuple, 1) -> true;
new_type_test(is_record, 2) -> true;
new_type_test(is_record, 3) -> true;
+new_type_test(is_reference, 1) -> true;
+new_type_test(is_tuple, 1) -> true;
new_type_test(Name, A) when is_atom(Name), is_integer(A) -> false.
%% Erlang old-style type tests.
@@ -271,6 +260,7 @@ bif(bitsize, 1) -> true;
bif(bit_size, 1) -> true;
bif(bitstring_to_list, 1) -> true;
bif(byte_size, 1) -> true;
+bif(ceil, 1) -> true;
bif(check_old_code, 1) -> true;
bif(check_process_code, 2) -> true;
bif(check_process_code, 3) -> true;
@@ -291,6 +281,7 @@ bif(float_to_list, 1) -> true;
bif(float_to_list, 2) -> true;
bif(float_to_binary, 1) -> true;
bif(float_to_binary, 2) -> true;
+bif(floor, 1) -> true;
bif(garbage_collect, 0) -> true;
bif(garbage_collect, 1) -> true;
bif(garbage_collect, 2) -> true;
@@ -340,6 +331,8 @@ bif(list_to_float, 1) -> true;
bif(list_to_integer, 1) -> true;
bif(list_to_integer, 2) -> true;
bif(list_to_pid, 1) -> true;
+bif(list_to_port, 1) -> true;
+bif(list_to_ref, 1) -> true;
bif(list_to_tuple, 1) -> true;
bif(load_module, 2) -> true;
bif(make_ref, 0) -> true;
@@ -357,6 +350,7 @@ bif(nodes, 1) -> true;
bif(now, 0) -> true;
bif(open_port, 2) -> true;
bif(pid_to_list, 1) -> true;
+bif(port_to_list, 1) -> true;
bif(port_close, 1) -> true;
bif(port_command, 2) -> true;
bif(port_command, 3) -> true;
@@ -370,6 +364,7 @@ bif(process_info, 2) -> true;
bif(processes, 0) -> true;
bif(purge_module, 1) -> true;
bif(put, 2) -> true;
+bif(ref_to_list, 1) -> true;
bif(register, 2) -> true;
bif(registered, 0) -> true;
bif(round, 1) -> true;
@@ -584,3 +579,68 @@ is_type(term, 0) -> true;
is_type(timeout, 0) -> true;
is_type(tuple, 0) -> true;
is_type(_, _) -> false.
+
+%%%
+%%% Add and export the pre-defined functions:
+%%%
+%%% module_info/0
+%%% module_info/1
+%%% behaviour_info/1 (optional)
+%%%
+
+-spec add_predefined_functions(Forms) -> UpdatedForms when
+ Forms :: [erl_parse:abstract_form() | erl_parse:form_info()],
+ UpdatedForms :: [erl_parse:abstract_form() | erl_parse:form_info()].
+
+add_predefined_functions(Forms) ->
+ Forms ++ predefined_functions(Forms).
+
+predefined_functions(Forms) ->
+ Attrs = [{Name,Val} || {attribute,_,Name,Val} <- Forms],
+ {module,Mod} = lists:keyfind(module, 1, Attrs),
+ Callbacks = [Callback || {callback,Callback} <- Attrs],
+ OptionalCallbacks = get_optional_callbacks(Attrs),
+ Mpf1 = module_predef_func_beh_info(Callbacks, OptionalCallbacks),
+ Mpf2 = module_predef_funcs_mod_info(Mod),
+ Mpf = [erl_parse:new_anno(F) || F <- Mpf1++Mpf2],
+ Exp = [{F,A} || {function,_,F,A,_} <- Mpf],
+ [{attribute,0,export,Exp}|Mpf].
+
+get_optional_callbacks(Attrs) ->
+ L = [O || {optional_callbacks,O} <- Attrs, is_fa_list(O)],
+ lists:append(L).
+
+is_fa_list([{FuncName, Arity}|L])
+ when is_atom(FuncName), is_integer(Arity), Arity >= 0 ->
+ is_fa_list(L);
+is_fa_list([]) -> true;
+is_fa_list(_) -> false.
+
+module_predef_func_beh_info([], _) ->
+ [];
+module_predef_func_beh_info(Callbacks0, OptionalCallbacks) ->
+ Callbacks = [FA || {{_,_}=FA,_} <- Callbacks0],
+ List = make_list(Callbacks),
+ OptionalList = make_list(OptionalCallbacks),
+ [{function,0,behaviour_info,1,
+ [{clause,0,[{atom,0,callbacks}],[],[List]},
+ {clause,0,[{atom,0,optional_callbacks}],[],[OptionalList]}]}].
+
+make_list([]) -> {nil,0};
+make_list([{Name,Arity}|Rest]) ->
+ {cons,0,
+ {tuple,0,
+ [{atom,0,Name},
+ {integer,0,Arity}]},
+ make_list(Rest)}.
+
+module_predef_funcs_mod_info(Mod) ->
+ ModAtom = {atom,0,Mod},
+ [{function,0,module_info,0,
+ [{clause,0,[],[],
+ [{call,0,{remote,0,{atom,0,erlang},{atom,0,get_module_info}},
+ [ModAtom]}]}]},
+ {function,0,module_info,1,
+ [{clause,0,[{var,0,'X'}],[],
+ [{call,0,{remote,0,{atom,0,erlang},{atom,0,get_module_info}},
+ [ModAtom,{var,0,'X'}]}]}]}].
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index e9332ce069..fcfd0d8493 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@
-export([module/1,module/2,module/3,format_error/1]).
-export([exprs/2,exprs_opt/3,used_vars/2]). % Used from erl_eval.erl.
--export([is_pattern_expr/1,is_guard_test/1,is_guard_test/2]).
+-export([is_pattern_expr/1,is_guard_test/1,is_guard_test/2,is_guard_test/3]).
-export([is_guard_expr/1]).
-export([bool_option/4,value_option/3,value_option/7]).
@@ -92,6 +92,14 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
:: dict:dict(ta(), line())
}).
+
+%% Are we outside or inside a catch or try/catch?
+-type catch_scope() :: 'none'
+ | 'after_old_catch'
+ | 'after_try'
+ | 'wrong_part_of_try'
+ | 'try_catch'.
+
%% Define the lint state record.
%% 'called' and 'exports' contain {Line, {Function, Arity}},
%% the other function collections contain {Function, Arity}.
@@ -135,7 +143,9 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
types = dict:new() %Type definitions
:: dict:dict(ta(), #typeinfo{}),
exp_types=gb_sets:empty() %Exported types
- :: gb_sets:set(ta())
+ :: gb_sets:set(ta()),
+ catch_scope = none %Inside/outside try or catch
+ :: catch_scope()
}).
-type lint_state() :: #lint{}.
@@ -156,6 +166,8 @@ format_error(pmod_unsupported) ->
"parameterized modules are no longer supported";
%% format_error({redefine_mod_import, M, P}) ->
%% io_lib:format("module '~s' already imported from package '~s'", [M, P]);
+format_error(non_latin1_module_unsupported) ->
+ "module names with non-latin1 characters are not supported";
format_error(invalid_call) ->
"invalid function call";
@@ -163,49 +175,50 @@ format_error(invalid_record) ->
"invalid record expression";
format_error({attribute,A}) ->
- io_lib:format("attribute '~w' after function definitions", [A]);
+ io_lib:format("attribute ~tw after function definitions", [A]);
format_error({missing_qlc_hrl,A}) ->
io_lib:format("qlc:q/~w called, but \"qlc.hrl\" not included", [A]);
format_error({redefine_import,{{F,A},M}}) ->
- io_lib:format("function ~w/~w already imported from ~w", [F,A,M]);
+ io_lib:format("function ~tw/~w already imported from ~w", [F,A,M]);
format_error({bad_inline,{F,A}}) ->
- io_lib:format("inlined function ~w/~w undefined", [F,A]);
+ io_lib:format("inlined function ~tw/~w undefined", [F,A]);
format_error({invalid_deprecated,D}) ->
- io_lib:format("badly formed deprecated attribute ~w", [D]);
+ io_lib:format("badly formed deprecated attribute ~tw", [D]);
format_error({bad_deprecated,{F,A}}) ->
- io_lib:format("deprecated function ~w/~w undefined or not exported", [F,A]);
+ io_lib:format("deprecated function ~tw/~w undefined or not exported",
+ [F,A]);
format_error({bad_nowarn_unused_function,{F,A}}) ->
- io_lib:format("function ~w/~w undefined", [F,A]);
+ io_lib:format("function ~tw/~w undefined", [F,A]);
format_error({bad_nowarn_bif_clash,{F,A}}) ->
- io_lib:format("function ~w/~w undefined", [F,A]);
+ io_lib:format("function ~tw/~w undefined", [F,A]);
format_error(disallowed_nowarn_bif_clash) ->
io_lib:format("compile directive nowarn_bif_clash is no longer allowed,~n"
" - use explicit module names or -compile({no_auto_import, [F/A]})", []);
format_error({bad_nowarn_deprecated_function,{M,F,A}}) ->
- io_lib:format("~w:~w/~w is not a deprecated function", [M,F,A]);
+ io_lib:format("~tw:~tw/~w is not a deprecated function", [M,F,A]);
format_error({bad_on_load,Term}) ->
- io_lib:format("badly formed on_load attribute: ~w", [Term]);
+ io_lib:format("badly formed on_load attribute: ~tw", [Term]);
format_error(multiple_on_loads) ->
"more than one on_load attribute";
format_error({bad_on_load_arity,{F,A}}) ->
- io_lib:format("function ~w/~w has wrong arity (must be 0)", [F,A]);
+ io_lib:format("function ~tw/~w has wrong arity (must be 0)", [F,A]);
format_error({undefined_on_load,{F,A}}) ->
- io_lib:format("function ~w/~w undefined", [F,A]);
+ io_lib:format("function ~tw/~w undefined", [F,A]);
format_error(export_all) ->
"export_all flag enabled - all functions will be exported";
format_error({duplicated_export, {F,A}}) ->
- io_lib:format("function ~w/~w already exported", [F,A]);
+ io_lib:format("function ~tw/~w already exported", [F,A]);
format_error({unused_import,{{F,A},M}}) ->
- io_lib:format("import ~w:~w/~w is unused", [M,F,A]);
+ io_lib:format("import ~w:~tw/~w is unused", [M,F,A]);
format_error({undefined_function,{F,A}}) ->
- io_lib:format("function ~w/~w undefined", [F,A]);
+ io_lib:format("function ~tw/~w undefined", [F,A]);
format_error({redefine_function,{F,A}}) ->
- io_lib:format("function ~w/~w already defined", [F,A]);
+ io_lib:format("function ~tw/~w already defined", [F,A]);
format_error({define_import,{F,A}}) ->
- io_lib:format("defining imported function ~w/~w", [F,A]);
+ io_lib:format("defining imported function ~tw/~w", [F,A]);
format_error({unused_function,{F,A}}) ->
- io_lib:format("function ~w/~w is unused", [F,A]);
+ io_lib:format("function ~tw/~w is unused", [F,A]);
format_error({call_to_redefined_bif,{F,A}}) ->
io_lib:format("ambiguous call of overridden auto-imported BIF ~w/~w~n"
" - use erlang:~w/~w or \"-compile({no_auto_import,[~w/~w]}).\" "
@@ -221,7 +234,15 @@ format_error({redefine_old_bif_import,{F,A}}) ->
format_error({redefine_bif_import,{F,A}}) ->
io_lib:format("import directive overrides auto-imported BIF ~w/~w~n"
" - use \"-compile({no_auto_import,[~w/~w]}).\" to resolve name clash", [F,A,F,A]);
-
+format_error({get_stacktrace,wrong_part_of_try}) ->
+ "erlang:get_stacktrace/0 used in the wrong part of 'try' expression. "
+ "(Use it in the block between 'catch' and 'end'.)";
+format_error({get_stacktrace,after_old_catch}) ->
+ "erlang:get_stacktrace/0 used following an old-style 'catch' "
+ "may stop working in a future release. (Use it inside 'try'.)";
+format_error({get_stacktrace,after_try}) ->
+ "erlang:get_stacktrace/0 used following a 'try' expression "
+ "may stop working in a future release. (Use it inside 'try'.)";
format_error({deprecated, MFA, ReplacementMFA, Rel}) ->
io_lib:format("~s is deprecated and will be removed in ~s; use ~s",
[format_mfa(MFA), Rel, format_mfa(ReplacementMFA)]);
@@ -238,7 +259,11 @@ format_error({removed_type, MNA, ReplacementMNA, Rel}) ->
io_lib:format("the type ~s was removed in ~s; use ~s instead",
[format_mna(MNA), Rel, format_mna(ReplacementMNA)]);
format_error({obsolete_guard, {F, A}}) ->
- io_lib:format("~p/~p obsolete", [F, A]);
+ io_lib:format("~p/~p obsolete (use is_~p/~p)", [F, A, F, A]);
+format_error({obsolete_guard_overridden,Test}) ->
+ io_lib:format("obsolete ~s/1 (meaning is_~s/1) is illegal when "
+ "there is a local/imported function named is_~p/1 ",
+ [Test,Test,Test]);
format_error({too_many_arguments,Arity}) ->
io_lib:format("too many arguments (~w) - "
"maximum allowed is ~w", [Arity,?MAX_ARGUMENTS]);
@@ -249,7 +274,7 @@ format_error(illegal_bin_pattern) ->
"binary patterns cannot be matched in parallel using '='";
format_error(illegal_expr) -> "illegal expression";
format_error({illegal_guard_local_call, {F,A}}) ->
- io_lib:format("call to local/imported function ~w/~w is illegal in guard",
+ io_lib:format("call to local/imported function ~tw/~w is illegal in guard",
[F,A]);
format_error(illegal_guard_expr) -> "illegal guard expression";
%% --- maps ---
@@ -257,23 +282,23 @@ format_error(illegal_map_construction) ->
"only association operators '=>' are allowed in map construction";
%% --- records ---
format_error({undefined_record,T}) ->
- io_lib:format("record ~w undefined", [T]);
+ io_lib:format("record ~tw undefined", [T]);
format_error({redefine_record,T}) ->
- io_lib:format("record ~w already defined", [T]);
+ io_lib:format("record ~tw already defined", [T]);
format_error({redefine_field,T,F}) ->
- io_lib:format("field ~w already defined in record ~w", [F,T]);
+ io_lib:format("field ~tw already defined in record ~tw", [F,T]);
format_error({undefined_field,T,F}) ->
- io_lib:format("field ~w undefined in record ~w", [F,T]);
+ io_lib:format("field ~tw undefined in record ~tw", [F,T]);
format_error(illegal_record_info) ->
"illegal record info";
format_error({field_name_is_variable,T,F}) ->
- io_lib:format("field ~w is not an atom or _ in record ~w", [F,T]);
+ io_lib:format("field ~tw is not an atom or _ in record ~tw", [F,T]);
format_error({wildcard_in_update,T}) ->
- io_lib:format("meaningless use of _ in update of record ~w", [T]);
+ io_lib:format("meaningless use of _ in update of record ~tw", [T]);
format_error({unused_record,T}) ->
- io_lib:format("record ~w is unused", [T]);
+ io_lib:format("record ~tw is unused", [T]);
format_error({untyped_record,T}) ->
- io_lib:format("record ~w has field(s) without type information", [T]);
+ io_lib:format("record ~tw has field(s) without type information", [T]);
%% --- variables ----
format_error({unbound_var,V}) ->
io_lib:format("variable ~w is unbound", [V]);
@@ -291,7 +316,7 @@ format_error({variable_in_record_def,V}) ->
io_lib:format("variable ~w in record definition", [V]);
%% --- binaries ---
format_error({undefined_bittype,Type}) ->
- io_lib:format("bit type ~w undefined", [Type]);
+ io_lib:format("bit type ~tw undefined", [Type]);
format_error({bittype_mismatch,Val1,Val2,What}) ->
io_lib:format("conflict in ~s specification for bit field: '~p' and '~p'",
[What,Val1,Val2]);
@@ -311,13 +336,13 @@ format_error(unsized_binary_in_bin_gen_pattern) ->
"binary fields without size are not allowed in patterns of bit string generators";
%% --- behaviours ---
format_error({conflicting_behaviours,{Name,Arity},B,FirstL,FirstB}) ->
- io_lib:format("conflicting behaviours - callback ~w/~w required by both '~p' "
+ io_lib:format("conflicting behaviours - callback ~tw/~w required by both '~p' "
"and '~p' ~s", [Name,Arity,B,FirstB,format_where(FirstL)]);
format_error({undefined_behaviour_func, {Func,Arity}, Behaviour}) ->
- io_lib:format("undefined callback function ~w/~w (behaviour '~w')",
+ io_lib:format("undefined callback function ~tw/~w (behaviour '~w')",
[Func,Arity,Behaviour]);
format_error({undefined_behaviour,Behaviour}) ->
- io_lib:format("behaviour ~w undefined", [Behaviour]);
+ io_lib:format("behaviour ~tw undefined", [Behaviour]);
format_error({undefined_behaviour_callbacks,Behaviour}) ->
io_lib:format("behaviour ~w callback functions are undefined",
[Behaviour]);
@@ -328,23 +353,23 @@ format_error({ill_defined_optional_callbacks,Behaviour}) ->
io_lib:format("behaviour ~w optional callback functions erroneously defined",
[Behaviour]);
format_error({behaviour_info, {_M,F,A}}) ->
- io_lib:format("cannot define callback attibute for ~w/~w when "
+ io_lib:format("cannot define callback attibute for ~tw/~w when "
"behaviour_info is defined",[F,A]);
format_error({redefine_optional_callback, {F, A}}) ->
- io_lib:format("optional callback ~w/~w duplicated", [F, A]);
+ io_lib:format("optional callback ~tw/~w duplicated", [F, A]);
format_error({undefined_callback, {_M, F, A}}) ->
- io_lib:format("callback ~w/~w is undefined", [F, A]);
+ io_lib:format("callback ~tw/~w is undefined", [F, A]);
%% --- types and specs ---
format_error({singleton_typevar, Name}) ->
io_lib:format("type variable ~w is only used once (is unbound)", [Name]);
format_error({bad_export_type, _ETs}) ->
io_lib:format("bad export_type declaration", []);
format_error({duplicated_export_type, {T, A}}) ->
- io_lib:format("type ~w/~w already exported", [T, A]);
+ io_lib:format("type ~tw/~w already exported", [T, A]);
format_error({undefined_type, {TypeName, Arity}}) ->
- io_lib:format("type ~w~s undefined", [TypeName, gen_type_paren(Arity)]);
+ io_lib:format("type ~tw~s undefined", [TypeName, gen_type_paren(Arity)]);
format_error({unused_type, {TypeName, Arity}}) ->
- io_lib:format("type ~w~s is unused", [TypeName, gen_type_paren(Arity)]);
+ io_lib:format("type ~tw~s is unused", [TypeName, gen_type_paren(Arity)]);
format_error({new_builtin_type, {TypeName, Arity}}) ->
io_lib:format("type ~w~s is a new builtin type; "
"its (re)definition is allowed only until the next release",
@@ -356,25 +381,26 @@ format_error({renamed_type, OldName, NewName}) ->
io_lib:format("type ~w() is now called ~w(); "
"please use the new name instead", [OldName, NewName]);
format_error({redefine_type, {TypeName, Arity}}) ->
- io_lib:format("type ~w~s already defined",
+ io_lib:format("type ~tw~s already defined",
[TypeName, gen_type_paren(Arity)]);
format_error({type_syntax, Constr}) ->
- io_lib:format("bad ~w type", [Constr]);
+ io_lib:format("bad ~tw type", [Constr]);
format_error(old_abstract_code) ->
io_lib:format("abstract code generated before Erlang/OTP 19.0 and "
"having typed record fields cannot be compiled", []);
format_error({redefine_spec, {M, F, A}}) ->
- io_lib:format("spec for ~w:~w/~w already defined", [M, F, A]);
+ io_lib:format("spec for ~tw:~tw/~w already defined", [M, F, A]);
format_error({redefine_spec, {F, A}}) ->
- io_lib:format("spec for ~w/~w already defined", [F, A]);
+ io_lib:format("spec for ~tw/~w already defined", [F, A]);
format_error({redefine_callback, {F, A}}) ->
- io_lib:format("callback ~w/~w already defined", [F, A]);
+ io_lib:format("callback ~tw/~w already defined", [F, A]);
format_error({bad_callback, {M, F, A}}) ->
- io_lib:format("explicit module not allowed for callback ~w:~w/~w ", [M, F, A]);
+ io_lib:format("explicit module not allowed for callback ~tw:~tw/~w",
+ [M, F, A]);
format_error({spec_fun_undefined, {F, A}}) ->
- io_lib:format("spec for undefined function ~w/~w", [F, A]);
+ io_lib:format("spec for undefined function ~tw/~w", [F, A]);
format_error({missing_spec, {F,A}}) ->
- io_lib:format("missing specification for function ~w/~w", [F, A]);
+ io_lib:format("missing specification for function ~tw/~w", [F, A]);
format_error(spec_wrong_arity) ->
"spec has wrong arity";
format_error(callback_wrong_arity) ->
@@ -393,11 +419,15 @@ format_error({deprecated_builtin_type, {Name, Arity},
"removed in ~s; use ~s",
[Name, Arity, Rel, UseS]);
format_error({not_exported_opaque, {TypeName, Arity}}) ->
- io_lib:format("opaque type ~w~s is not exported",
+ io_lib:format("opaque type ~tw~s is not exported",
[TypeName, gen_type_paren(Arity)]);
format_error({underspecified_opaque, {TypeName, Arity}}) ->
- io_lib:format("opaque type ~w~s is underspecified and therefore meaningless",
+ io_lib:format("opaque type ~tw~s is underspecified and therefore meaningless",
[TypeName, gen_type_paren(Arity)]);
+format_error({bad_dialyzer_attribute,Term}) ->
+ io_lib:format("badly formed dialyzer attribute: ~tw", [Term]);
+format_error({bad_dialyzer_option,Term}) ->
+ io_lib:format("unknown dialyzer warning option: ~tw", [Term]);
%% --- obsolete? unused? ---
format_error({format_error, {Fmt, Args}}) ->
io_lib:format(Fmt, Args).
@@ -522,7 +552,7 @@ start(File, Opts) ->
true, Opts)},
{export_all,
bool_option(warn_export_all, nowarn_export_all,
- false, Opts)},
+ true, Opts)},
{export_vars,
bool_option(warn_export_vars, nowarn_export_vars,
false, Opts)},
@@ -558,7 +588,10 @@ start(File, Opts) ->
false, Opts)},
{missing_spec_all,
bool_option(warn_missing_spec_all, nowarn_missing_spec_all,
- false, Opts)}
+ false, Opts)},
+ {get_stacktrace,
+ bool_option(warn_get_stacktrace, nowarn_get_stacktrace,
+ true, Opts)}
],
Enabled1 = [Category || {Category,true} <- Enabled0],
Enabled = ordsets:from_list(Enabled1),
@@ -729,11 +762,17 @@ form(Form, #lint{state=State}=St) ->
start_state({attribute,Line,module,{_,_}}=Form, St0) ->
St1 = add_error(Line, pmod_unsupported, St0),
attribute_state(Form, St1#lint{state=attribute});
-start_state({attribute,_,module,M}, St0) ->
+start_state({attribute,Line,module,M}, St0) ->
St1 = St0#lint{module=M},
- St1#lint{state=attribute};
+ St2 = St1#lint{state=attribute},
+ check_module_name(M, Line, St2);
start_state(Form, St) ->
- St1 = add_error(element(2, Form), undefined_module, St),
+ Anno = case Form of
+ {eof, L} -> erl_anno:new(L);
+ %% {warning, Warning} and {error, Error} not possible here.
+ _ -> element(2, Form)
+ end,
+ St1 = add_error(Anno, undefined_module, St),
attribute_state(Form, St1#lint{state=attribute}).
%% attribute_state(Form, State) ->
@@ -776,8 +815,7 @@ attribute_state(Form, St) ->
%% State'
%% Allow for record, type and opaque type definitions and spec
%% declarations to be intersperced within function definitions.
-%% Dialyzer attributes are also allowed everywhere, but are not
-%% checked at all.
+%% Dialyzer attributes are also allowed everywhere.
function_state({attribute,L,record,{Name,Fields}}, St) ->
record_def(L, Name, Fields, St);
@@ -821,7 +859,11 @@ not_deprecated(Forms, St0) ->
Bad = [MFAL || {{M,F,A},_L}=MFAL <- MFAsL,
otp_internal:obsolete(M, F, A) =:= no],
St1 = func_line_warning(bad_nowarn_deprecated_function, Bad, St0),
- St1#lint{not_deprecated = ordsets:from_list(Nowarn)}.
+ ML = [{M,L} || {{M,_F,_A},L} <- MFAsL, is_atom(M)],
+ St3 = foldl(fun ({M,L}, St2) ->
+ check_module_name(M, L, St2)
+ end, St1, ML),
+ St3#lint{not_deprecated = ordsets:from_list(Nowarn)}.
%% The nowarn_bif_clash directive is not only deprecated, it's actually an error from R14A
disallowed_compile_flags(Forms, St0) ->
@@ -863,7 +905,8 @@ post_traversal_check(Forms, St0) ->
StD = check_on_load(StC),
StE = check_unused_records(Forms, StD),
StF = check_local_opaque_types(StE),
- check_callback_information(StF).
+ StG = check_dialyzer_attribute(Forms, StF),
+ check_callback_information(StG).
%% check_behaviour(State0) -> State
%% Check that the behaviour attribute is valid.
@@ -927,7 +970,8 @@ behaviour_callbacks(Line, B, St0) ->
catch
_:_ ->
St1 = add_warning(Line, {undefined_behaviour, B}, St0),
- {[], [], St1}
+ St2 = check_module_name(B, Line, St1),
+ {[], [], St2}
end.
behaviour_missing_callbacks([{{Line,B},Bfs0,OBfs}|T], St0) ->
@@ -1265,7 +1309,8 @@ exports(#lint{compile = Opts, defined = Defs, exports = Es}) ->
-type import() :: {module(), [fa()]} | module().
-spec import(line(), import(), lint_state()) -> lint_state().
-import(Line, {Mod,Fs}, St) ->
+import(Line, {Mod,Fs}, St00) ->
+ St = check_module_name(Mod, Line, St00),
Mfs = ordsets:from_list(Fs),
case check_imports(Line, Mfs, St#lint.imports) of
[] ->
@@ -1381,8 +1426,9 @@ call_function(Line, F, A, #lint{usage=Usage0,called=Cd,func=Func,file=File}=St)
%% function(Line, Name, Arity, Clauses, State) -> State.
function(Line, Name, Arity, Cs, St0) ->
- St1 = define_function(Line, Name, Arity, St0#lint{func={Name,Arity}}),
- clauses(Cs, St1).
+ St1 = St0#lint{func={Name,Arity},catch_scope=none},
+ St2 = define_function(Line, Name, Arity, St1),
+ clauses(Cs, St2).
-spec define_function(line(), atom(), arity(), lint_state()) -> lint_state().
@@ -1765,7 +1811,8 @@ bit_size({atom,_Line,all}, _Vt, St, _Check) -> {all,[],St};
bit_size(Size, Vt, St, Check) ->
%% Try to safely evaluate Size if constant to get size,
%% otherwise just treat it as an expression.
- case is_gexpr(Size, St#lint.records) of
+ Info = is_guard_test2_info(St),
+ case is_gexpr(Size, Info) of
true ->
case erl_eval:partial_eval(Size) of
{integer,_ILn,I} -> {I,[],St};
@@ -2000,77 +2047,104 @@ gexpr_list(Es, Vt, St) ->
%% is_guard_test(Expression) -> boolean().
%% Test if a general expression is a guard test.
+%%
+%% Note: Only use this function in contexts where there can be
+%% no definition of a local function that may override a guard BIF
+%% (for example, in the shell).
-spec is_guard_test(Expr) -> boolean() when
Expr :: erl_parse:abstract_expr().
is_guard_test(E) ->
- is_guard_test2(E, dict:new()).
+ is_guard_test2(E, {dict:new(),fun(_) -> false end}).
%% is_guard_test(Expression, Forms) -> boolean().
is_guard_test(Expression, Forms) ->
+ is_guard_test(Expression, Forms, fun(_) -> false end).
+
+
+%% is_guard_test(Expression, Forms, IsOverridden) -> boolean().
+%% Test if a general expression is a guard test.
+%%
+%% IsOverridden({Name,Arity}) should return 'true' if Name/Arity is
+%% a local or imported function in the module. If the abstract code has
+%% passed through erl_expand_records, any call without an explicit
+%% module is to a local function, so IsOverridden can be defined as:
+%%
+%% fun(_) -> true end
+%%
+-spec is_guard_test(Expr, Forms, IsOverridden) -> boolean() when
+ Expr :: erl_parse:abstract_expr(),
+ Forms :: [erl_parse:abstract_form() | erl_parse:form_info()],
+ IsOverridden :: fun((fa()) -> boolean()).
+
+is_guard_test(Expression, Forms, IsOverridden) ->
RecordAttributes = [A || A = {attribute, _, record, _D} <- Forms],
St0 = foldl(fun(Attr0, St1) ->
Attr = set_file(Attr0, "none"),
attribute_state(Attr, St1)
end, start(), RecordAttributes),
- is_guard_test2(set_file(Expression, "nofile"), St0#lint.records).
+ is_guard_test2(set_file(Expression, "nofile"),
+ {St0#lint.records,IsOverridden}).
%% is_guard_test2(Expression, RecordDefs :: dict:dict()) -> boolean().
-is_guard_test2({call,Line,{atom,Lr,record},[E,A]}, RDs) ->
- is_gexpr({call,Line,{atom,Lr,is_record},[E,A]}, RDs);
-is_guard_test2({call,_Line,{atom,_La,Test},As}=Call, RDs) ->
- case erl_internal:type_test(Test, length(As)) of
- true -> is_gexpr_list(As, RDs);
- false -> is_gexpr(Call, RDs)
- end;
-is_guard_test2(G, RDs) ->
+is_guard_test2({call,Line,{atom,Lr,record},[E,A]}, Info) ->
+ is_gexpr({call,Line,{atom,Lr,is_record},[E,A]}, Info);
+is_guard_test2({call,_Line,{atom,_La,Test},As}=Call, {_,IsOverridden}=Info) ->
+ A = length(As),
+ not IsOverridden({Test,A}) andalso
+ case erl_internal:type_test(Test, A) of
+ true -> is_gexpr_list(As, Info);
+ false -> is_gexpr(Call, Info)
+ end;
+is_guard_test2(G, Info) ->
%%Everything else is a guard expression.
- is_gexpr(G, RDs).
+ is_gexpr(G, Info).
%% is_guard_expr(Expression) -> boolean().
%% Test if an expression is a guard expression.
is_guard_expr(E) -> is_gexpr(E, []).
-is_gexpr({var,_L,_V}, _RDs) -> true;
-is_gexpr({char,_L,_C}, _RDs) -> true;
-is_gexpr({integer,_L,_I}, _RDs) -> true;
-is_gexpr({float,_L,_F}, _RDs) -> true;
-is_gexpr({atom,_L,_A}, _RDs) -> true;
-is_gexpr({string,_L,_S}, _RDs) -> true;
-is_gexpr({nil,_L}, _RDs) -> true;
-is_gexpr({cons,_L,H,T}, RDs) -> is_gexpr_list([H,T], RDs);
-is_gexpr({tuple,_L,Es}, RDs) -> is_gexpr_list(Es, RDs);
-%%is_gexpr({struct,_L,_Tag,Es}, RDs) ->
-%% is_gexpr_list(Es, RDs);
-is_gexpr({record_index,_L,_Name,Field}, RDs) ->
- is_gexpr(Field, RDs);
-is_gexpr({record_field,_L,Rec,_Name,Field}, RDs) ->
- is_gexpr_list([Rec,Field], RDs);
-is_gexpr({record,L,Name,Inits}, RDs) ->
- is_gexpr_fields(Inits, L, Name, RDs);
-is_gexpr({bin,_L,Fs}, RDs) ->
+is_gexpr({var,_L,_V}, _Info) -> true;
+is_gexpr({char,_L,_C}, _Info) -> true;
+is_gexpr({integer,_L,_I}, _Info) -> true;
+is_gexpr({float,_L,_F}, _Info) -> true;
+is_gexpr({atom,_L,_A}, _Info) -> true;
+is_gexpr({string,_L,_S}, _Info) -> true;
+is_gexpr({nil,_L}, _Info) -> true;
+is_gexpr({cons,_L,H,T}, Info) -> is_gexpr_list([H,T], Info);
+is_gexpr({tuple,_L,Es}, Info) -> is_gexpr_list(Es, Info);
+%%is_gexpr({struct,_L,_Tag,Es}, Info) ->
+%% is_gexpr_list(Es, Info);
+is_gexpr({record_index,_L,_Name,Field}, Info) ->
+ is_gexpr(Field, Info);
+is_gexpr({record_field,_L,Rec,_Name,Field}, Info) ->
+ is_gexpr_list([Rec,Field], Info);
+is_gexpr({record,L,Name,Inits}, Info) ->
+ is_gexpr_fields(Inits, L, Name, Info);
+is_gexpr({bin,_L,Fs}, Info) ->
all(fun ({bin_element,_Line,E,Sz,_Ts}) ->
- is_gexpr(E, RDs) and (Sz =:= default orelse is_gexpr(Sz, RDs))
+ is_gexpr(E, Info) and (Sz =:= default orelse is_gexpr(Sz, Info))
end, Fs);
-is_gexpr({call,_L,{atom,_Lf,F},As}, RDs) ->
+is_gexpr({call,_L,{atom,_Lf,F},As}, {_,IsOverridden}=Info) ->
A = length(As),
- erl_internal:guard_bif(F, A) andalso is_gexpr_list(As, RDs);
-is_gexpr({call,_L,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,F}},As}, RDs) ->
+ not IsOverridden({F,A}) andalso erl_internal:guard_bif(F, A)
+ andalso is_gexpr_list(As, Info);
+is_gexpr({call,_L,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,F}},As}, Info) ->
A = length(As),
(erl_internal:guard_bif(F, A) orelse is_gexpr_op(F, A))
- andalso is_gexpr_list(As, RDs);
-is_gexpr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,F}]},As}, RDs) ->
- is_gexpr({call,L,{remote,Lt,{atom,Lm,erlang},{atom,Lf,F}},As}, RDs);
-is_gexpr({op,_L,Op,A}, RDs) ->
- is_gexpr_op(Op, 1) andalso is_gexpr(A, RDs);
-is_gexpr({op,_L,'andalso',A1,A2}, RDs) ->
- is_gexpr_list([A1,A2], RDs);
-is_gexpr({op,_L,'orelse',A1,A2}, RDs) ->
- is_gexpr_list([A1,A2], RDs);
-is_gexpr({op,_L,Op,A1,A2}, RDs) ->
- is_gexpr_op(Op, 2) andalso is_gexpr_list([A1,A2], RDs);
-is_gexpr(_Other, _RDs) -> false.
+ andalso is_gexpr_list(As, Info);
+is_gexpr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,F}]},As}, Info) ->
+ is_gexpr({call,L,{remote,Lt,{atom,Lm,erlang},{atom,Lf,F}},As}, Info);
+is_gexpr({op,_L,Op,A}, Info) ->
+ is_gexpr_op(Op, 1) andalso is_gexpr(A, Info);
+is_gexpr({op,_L,'andalso',A1,A2}, Info) ->
+ is_gexpr_list([A1,A2], Info);
+is_gexpr({op,_L,'orelse',A1,A2}, Info) ->
+ is_gexpr_list([A1,A2], Info);
+is_gexpr({op,_L,Op,A1,A2}, Info) ->
+ is_gexpr_op(Op, 2) andalso is_gexpr_list([A1,A2], Info);
+is_gexpr(_Other, _Info) -> false.
is_gexpr_op(Op, A) ->
try erl_internal:op_type(Op, A) of
@@ -2082,14 +2156,14 @@ is_gexpr_op(Op, A) ->
catch _:_ -> false
end.
-is_gexpr_list(Es, RDs) -> all(fun (E) -> is_gexpr(E, RDs) end, Es).
+is_gexpr_list(Es, Info) -> all(fun (E) -> is_gexpr(E, Info) end, Es).
-is_gexpr_fields(Fs, L, Name, RDs) ->
+is_gexpr_fields(Fs, L, Name, {RDs,_}=Info) ->
IFs = case dict:find(Name, RDs) of
{ok,{_Line,Fields}} -> Fs ++ init_fields(Fs, L, Fields);
error -> Fs
end,
- all(fun ({record_field,_Lf,_Name,V}) -> is_gexpr(V, RDs);
+ all(fun ({record_field,_Lf,_Name,V}) -> is_gexpr(V, Info);
(_Other) -> false end, IFs).
%% exprs(Sequence, VarTable, State) ->
@@ -2220,11 +2294,18 @@ expr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,is_record}]},As}, Vt, St) ->
expr({call,Line,{remote,_Lr,{atom,_Lm,M},{atom,Lf,F}},As}, Vt, St0) ->
St1 = keyword_warning(Lf, F, St0),
St2 = check_remote_function(Line, M, F, As, St1),
- expr_list(As, Vt, St2);
+ St3 = check_module_name(M, Line, St2),
+ expr_list(As, Vt, St3);
expr({call,Line,{remote,_Lr,M,F},As}, Vt, St0) ->
St1 = keyword_warning(Line, M, St0),
St2 = keyword_warning(Line, F, St1),
- expr_list([M,F|As], Vt, St2);
+ St3 = case M of
+ {atom,Lm,Mod} ->
+ check_module_name(Mod, Lm, St2);
+ _ ->
+ St2
+ end,
+ expr_list([M,F|As], Vt, St3);
expr({call,Line,{atom,La,F},As}, Vt, St0) ->
St1 = keyword_warning(La, F, St0),
{Asvt,St2} = expr_list(As, Vt, St1),
@@ -2286,22 +2367,24 @@ expr({call,Line,F,As}, Vt, St0) ->
expr({'try',Line,Es,Scs,Ccs,As}, Vt, St0) ->
%% Currently, we don't allow any exports because later
%% passes cannot handle exports in combination with 'after'.
- {Evt0,St1} = exprs(Es, Vt, St0),
+ {Evt0,St1} = exprs(Es, Vt, St0#lint{catch_scope=wrong_part_of_try}),
TryLine = {'try',Line},
Uvt = vtunsafe(TryLine, Evt0, Vt),
Evt1 = vtupdate(Uvt, Evt0),
- {Sccs,St2} = icrt_clauses(Scs++Ccs, TryLine, vtupdate(Evt1, Vt), St1),
+ {Sccs,St2} = try_clauses(Scs, Ccs, TryLine,
+ vtupdate(Evt1, Vt), St1),
Rvt0 = Sccs,
Rvt1 = vtupdate(vtunsafe(TryLine, Rvt0, Vt), Rvt0),
Evt2 = vtmerge(Evt1, Rvt1),
{Avt0,St} = exprs(As, vtupdate(Evt2, Vt), St2),
Avt1 = vtupdate(vtunsafe(TryLine, Avt0, Vt), Avt0),
Avt = vtmerge(Evt2, Avt1),
- {Avt,St};
+ {Avt,St#lint{catch_scope=after_try}};
expr({'catch',Line,E}, Vt, St0) ->
%% No new variables added, flag new variables as unsafe.
{Evt,St} = expr(E, Vt, St0),
- {vtupdate(vtunsafe({'catch',Line}, Evt, Vt), Evt),St};
+ {vtupdate(vtunsafe({'catch',Line}, Evt, Vt), Evt),
+ St#lint{catch_scope=after_old_catch}};
expr({match,_Line,P,E}, Vt, St0) ->
{Evt,St1} = expr(E, Vt, St0),
{Pvt,Bvt,St2} = pattern(P, vtupdate(Evt, Vt), St1),
@@ -2738,7 +2821,8 @@ check_type(Types, St) ->
check_type({ann_type, _L, [_Var, Type]}, SeenVars, St) ->
check_type(Type, SeenVars, St);
check_type({remote_type, L, [{atom, _, Mod}, {atom, _, Name}, Args]},
- SeenVars, St0) ->
+ SeenVars, St00) ->
+ St0 = check_module_name(Mod, L, St00),
St = deprecated_type(L, Mod, Name, Args, St0),
CurrentMod = St#lint.module,
case Mod =:= CurrentMod of
@@ -2897,11 +2981,12 @@ obsolete_builtin_type({Name, A}) when is_atom(Name), is_integer(A) -> no.
%% spec_decl(Line, Fun, Types, State) -> State.
-spec_decl(Line, MFA0, TypeSpecs, St0 = #lint{specs = Specs, module = Mod}) ->
+spec_decl(Line, MFA0, TypeSpecs, St00 = #lint{specs = Specs, module = Mod}) ->
MFA = case MFA0 of
{F, Arity} -> {Mod, F, Arity};
{_M, _F, Arity} -> MFA0
end,
+ St0 = check_module_name(element(1, MFA), Line, St00),
St1 = St0#lint{specs = dict:store(MFA, Line, Specs)},
case dict:is_key(MFA, Specs) of
true -> add_error(Line, {redefine_spec, MFA0}, St1);
@@ -2913,7 +2998,9 @@ spec_decl(Line, MFA0, TypeSpecs, St0 = #lint{specs = Specs, module = Mod}) ->
callback_decl(Line, MFA0, TypeSpecs,
St0 = #lint{callbacks = Callbacks, module = Mod}) ->
case MFA0 of
- {_M, _F, _A} -> add_error(Line, {bad_callback, MFA0}, St0);
+ {M, _F, _A} ->
+ St1 = check_module_name(M, Line, St0),
+ add_error(Line, {bad_callback, MFA0}, St1);
{F, Arity} ->
MFA = {Mod, F, Arity},
St1 = St0#lint{callbacks = dict:store(MFA, Line, Callbacks)},
@@ -2957,6 +3044,16 @@ is_fa({FuncName, Arity})
when is_atom(FuncName), is_integer(Arity), Arity >= 0 -> true;
is_fa(_) -> false.
+check_module_name(M, Line, St) ->
+ case is_latin1_name(M) of
+ true -> St;
+ false ->
+ add_error(Line, non_latin1_module_unsupported, St)
+ end.
+
+is_latin1_name(Name) ->
+ io_lib:latin1_char_list(atom_to_list(Name)).
+
check_specs([FunType|Left], ETag, Arity, St0) ->
{FunType1, CTypes} =
case FunType of
@@ -3068,6 +3165,70 @@ check_local_opaque_types(St) ->
end,
dict:fold(FoldFun, St, Ts).
+check_dialyzer_attribute(Forms, St0) ->
+ Vals = [{L,V} ||
+ {attribute,L,dialyzer,Val} <- Forms,
+ V0 <- lists:flatten([Val]),
+ V <- case V0 of
+ {O,F} ->
+ [{A,B} ||
+ A <- lists:flatten([O]),
+ B <- lists:flatten([F])];
+ T -> [T]
+ end],
+ {Wellformed, Bad} =
+ lists:partition(fun ({_,{Option,FA}}) when is_atom(Option) ->
+ is_fa(FA);
+ ({_,Option}) when is_atom(Option) -> true;
+ (_) -> false
+ end, Vals),
+ St1 = foldl(fun ({L,Term}, St) ->
+ add_error(L, {bad_dialyzer_attribute,Term}, St)
+ end, St0, Bad),
+ DefFunctions = (gb_sets:to_list(St0#lint.defined) -- pseudolocals()),
+ Fun = fun ({L,{Option,FA}}, St) ->
+ case is_function_dialyzer_option(Option) of
+ true ->
+ case lists:member(FA, DefFunctions) of
+ true -> St;
+ false ->
+ add_error(L, {undefined_function,FA}, St)
+ end;
+ false ->
+ add_error(L, {bad_dialyzer_option,Option}, St)
+ end;
+ ({L,Option}, St) ->
+ case is_module_dialyzer_option(Option) of
+ true -> St;
+ false ->
+ add_error(L, {bad_dialyzer_option,Option}, St)
+ end
+ end,
+ foldl(Fun, St1, Wellformed).
+
+is_function_dialyzer_option(nowarn_function) -> true;
+is_function_dialyzer_option(Option) ->
+ is_module_dialyzer_option(Option).
+
+is_module_dialyzer_option(Option) ->
+ lists:member(Option,
+ [no_return,no_unused,no_improper_lists,no_fun_app,
+ no_match,no_opaque,no_fail_call,no_contracts,
+ no_behaviours,no_undefined_callbacks,unmatched_returns,
+ error_handling,race_conditions,no_missing_calls,
+ specdiffs,overspecs,underspecs,unknown]).
+
+%% try_catch_clauses(Scs, Ccs, In, ImportVarTable, State) ->
+%% {UpdVt,State}.
+
+try_clauses(Scs, Ccs, In, Vt, St0) ->
+ {Csvt0,St1} = icrt_clauses(Scs, Vt, St0),
+ St2 = St1#lint{catch_scope=try_catch},
+ {Csvt1,St3} = icrt_clauses(Ccs, Vt, St2),
+ Csvt = Csvt0 ++ Csvt1,
+ UpdVt = icrt_export(Csvt, Vt, In, St3),
+ {UpdVt,St3}.
+
%% icrt_clauses(Clauses, In, ImportVarTable, State) ->
%% {UpdVt,State}.
@@ -3193,7 +3354,8 @@ lc_quals([{b_generate,_Line,P,E} | Qs], Vt0, Uvt0, St0) ->
{Vt,Uvt,St} = handle_generator(P,E,Vt0,Uvt0,St1),
lc_quals(Qs, Vt, Uvt, St);
lc_quals([F|Qs], Vt, Uvt, St0) ->
- {Fvt,St1} = case is_guard_test2(F, St0#lint.records) of
+ Info = is_guard_test2_info(St0),
+ {Fvt,St1} = case is_guard_test2(F, Info) of
true -> guard_test(F, Vt, St0);
false -> expr(F, Vt, St0)
end,
@@ -3201,6 +3363,12 @@ lc_quals([F|Qs], Vt, Uvt, St0) ->
lc_quals([], Vt, Uvt, St) ->
{Vt, Uvt, St}.
+is_guard_test2_info(#lint{records=RDs,locals=Locals,imports=Imports}) ->
+ {RDs,fun(FA) ->
+ is_local_function(Locals, FA) orelse
+ is_imported_function(Imports, FA)
+ end}.
+
handle_generator(P,E,Vt,Uvt,St0) ->
{Evt,St1} = expr(E, Vt, St0),
%% Forget variables local to E immediately.
@@ -3545,7 +3713,8 @@ has_wildcard_field([]) -> false.
check_remote_function(Line, M, F, As, St0) ->
St1 = deprecated_function(Line, M, F, As, St0),
St2 = check_qlc_hrl(Line, M, F, As, St1),
- format_function(Line, M, F, As, St2).
+ St3 = check_get_stacktrace(Line, M, F, As, St2),
+ format_function(Line, M, F, As, St3).
%% check_qlc_hrl(Line, ModName, FuncName, [Arg], State) -> State
%% Add warning if qlc:q/1,2 has been called but qlc.hrl has not
@@ -3594,6 +3763,23 @@ deprecated_function(Line, M, F, As, St) ->
St
end.
+check_get_stacktrace(Line, erlang, get_stacktrace, [], St) ->
+ case St of
+ #lint{catch_scope=none} ->
+ St;
+ #lint{catch_scope=try_catch} ->
+ St;
+ #lint{catch_scope=Scope} ->
+ case is_warn_enabled(get_stacktrace, St) of
+ false ->
+ St;
+ true ->
+ add_warning(Line, {get_stacktrace,Scope}, St)
+ end
+ end;
+check_get_stacktrace(_, _, _, _, St) ->
+ St.
+
-dialyzer({no_match, deprecated_type/5}).
deprecated_type(L, M, N, As, St) ->
@@ -3618,16 +3804,26 @@ obsolete_guard({call,Line,{atom,Lr,F},As}, St0) ->
false ->
deprecated_function(Line, erlang, F, As, St0);
true ->
- case is_warn_enabled(obsolete_guard, St0) of
- true ->
- add_warning(Lr,{obsolete_guard, {F, Arity}}, St0);
- false ->
- St0
- end
+ St = case is_warn_enabled(obsolete_guard, St0) of
+ true ->
+ add_warning(Lr, {obsolete_guard, {F, Arity}}, St0);
+ false ->
+ St0
+ end,
+ test_overriden_by_local(Lr, F, Arity, St)
end;
obsolete_guard(_G, St) ->
St.
+test_overriden_by_local(Line, OldTest, Arity, St) ->
+ ModernTest = list_to_atom("is_"++atom_to_list(OldTest)),
+ case is_local_function(St#lint.locals, {ModernTest, Arity}) of
+ true ->
+ add_error(Line, {obsolete_guard_overridden,OldTest}, St);
+ false ->
+ St
+ end.
+
%% keyword_warning(Line, Atom, State) -> State.
%% Add warning for atoms that will be reserved keywords in the future.
%% (Currently, no such keywords to warn for.)
@@ -3761,6 +3957,10 @@ extract_sequence(4, [$t, $p | Fmt], Need) ->
extract_sequence(5, [$p|Fmt], Need);
extract_sequence(4, [$t, $P | Fmt], Need) ->
extract_sequence(5, [$P|Fmt], Need);
+extract_sequence(4, [$t, $w | Fmt], Need) ->
+ extract_sequence(5, [$w|Fmt], Need);
+extract_sequence(4, [$t, $W | Fmt], Need) ->
+ extract_sequence(5, [$W|Fmt], Need);
extract_sequence(4, [$t, C | _Fmt], _Need) ->
{error,"invalid control ~t" ++ [C]};
extract_sequence(4, [$l, $p | Fmt], Need) ->
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index 85b2816451..6e72d64acc 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,7 +33,6 @@ list tail
list_comprehension lc_expr lc_exprs
binary_comprehension
tuple
-%struct
record_expr record_tuple record_field record_fields
map_expr map_tuple map_field map_field_assoc map_field_exact map_fields map_key
if_expr if_clause if_clauses case_expr cr_clause cr_clauses receive_expr
@@ -108,9 +107,8 @@ type_sig -> fun_type 'when' type_guards : {type, ?anno('$1'), bounded_fun,
type_guards -> type_guard : ['$1'].
type_guards -> type_guard ',' type_guards : ['$1'|'$3'].
-type_guard -> atom '(' top_types ')' : {type, ?anno('$1'), constraint,
- ['$1', '$3']}.
-type_guard -> var '::' top_type : build_def('$1', '$3').
+type_guard -> atom '(' top_types ')' : build_compat_constraint('$1', '$3').
+type_guard -> var '::' top_type : build_constraint('$1', '$3').
top_types -> top_type : ['$1'].
top_types -> top_type ',' top_types : ['$1'|'$3'].
@@ -156,6 +154,7 @@ type -> '#' atom '{' field_types '}' : {type, ?anno('$1'),
record, ['$2'|'$4']}.
type -> binary_type : '$1'.
type -> integer : '$1'.
+type -> char : '$1'.
type -> 'fun' '(' ')' : {type, ?anno('$1'), 'fun', []}.
type -> 'fun' '(' fun_type_100 ')' : '$3'.
@@ -268,7 +267,6 @@ expr_max -> binary : '$1'.
expr_max -> list_comprehension : '$1'.
expr_max -> binary_comprehension : '$1'.
expr_max -> tuple : '$1'.
-%%expr_max -> struct : '$1'.
expr_max -> '(' expr ')' : '$2'.
expr_max -> 'begin' exprs 'end' : {block,?anno('$1'),'$2'}.
expr_max -> if_expr : '$1'.
@@ -327,10 +325,6 @@ lc_expr -> binary '<=' expr : {b_generate,?anno('$2'),'$1','$3'}.
tuple -> '{' '}' : {tuple,?anno('$1'),[]}.
tuple -> '{' exprs '}' : {tuple,?anno('$1'),'$2'}.
-
-%%struct -> atom tuple :
-%% {struct,?anno('$1'),element(3, '$1'),element(3, '$2')}.
-
map_expr -> '#' map_tuple :
{map, ?anno('$1'),'$2'}.
map_expr -> expr_max '#' map_tuple :
@@ -516,6 +510,22 @@ comp_op -> '>' : '$1'.
comp_op -> '=:=' : '$1'.
comp_op -> '=/=' : '$1'.
+Header
+"%% This file was automatically generated from the file \"erl_parse.yrl\"."
+"%%"
+"%% Copyright Ericsson AB 1996-2015. All Rights Reserved."
+"%%"
+"%% Licensed under the Apache License, Version 2.0 (the \"License\"); you may"
+"%% not use this file except in compliance with the License. You may obtain"
+"%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>"
+"%%"
+"%% Unless required by applicable law or agreed to in writing, software"
+"%% distributed under the License is distributed on an \"AS IS\" BASIS,"
+"%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."
+"%% See the License for the specific language governing permissions and"
+"%% limitations under the License."
+"".
+
Erlang code.
-export([parse_form/1,parse_exprs/1,parse_term/1]).
@@ -612,11 +622,11 @@ Erlang code.
| af_bin(abstract_expr())
| af_binary_op(abstract_expr())
| af_unary_op(abstract_expr())
- | af_record_access(abstract_expr())
+ | af_record_creation(abstract_expr())
| af_record_update(abstract_expr())
| af_record_index()
| af_record_field_access(abstract_expr())
- | af_map_access(abstract_expr())
+ | af_map_creation(abstract_expr())
| af_map_update(abstract_expr())
| af_catch()
| af_local_call()
@@ -720,26 +730,25 @@ Erlang code.
| af_bin(af_guard_test())
| af_binary_op(af_guard_test())
| af_unary_op(af_guard_test())
- | af_record_access(af_guard_test())
+ | af_record_creation(af_guard_test())
| af_record_index()
| af_record_field_access(af_guard_test())
- | af_map_access(abstract_expr()) % FIXME
- | af_map_update(abstract_expr()) % FIXME
+ | af_map_creation(abstract_expr())
+ | af_map_update(abstract_expr())
| af_guard_call()
| af_remote_guard_call().
-type af_record_field_access(T) ::
{'record_field', anno(), T, record_name(), af_field_name()}.
--type af_map_access(T) :: {'map', anno(), [af_map_field(T)]}.
-
--type af_map_update(T) :: {'map', anno(), T, [af_map_field(T)]}.
+-type af_map_creation(T) :: {'map', anno(), [af_assoc(T)]}.
--type af_map_field(T) :: af_map_field_assoc(T) | af_map_field_exact(T).
+-type af_map_update(T) :: {'map', anno(), T, [af_assoc(T)]}.
--type af_map_field_assoc(T) :: {'map_field_assoc', anno(), T, T}.
+-type af_assoc(T) :: {'map_field_assoc', anno(), T, T}
+ | af_assoc_exact(T).
--type af_map_field_exact(T) :: {'map_field_exact', anno(), T, T}.
+-type af_assoc_exact(T) :: {'map_field_exact', anno(), T, T}.
-type af_guard_call() :: {'call', anno(), function_name(), [af_guard_test()]}.
@@ -757,20 +766,20 @@ Erlang code.
| af_bin(af_pattern())
| af_binary_op(af_pattern())
| af_unary_op(af_pattern())
- | af_record_access(af_pattern())
+ | af_record_creation(af_pattern())
| af_record_index()
| af_map_pattern().
-type af_record_index() ::
{'record_index', anno(), record_name(), af_field_name()}.
--type af_record_access(T) ::
+-type af_record_creation(T) ::
{'record', anno(), record_name(), [af_record_field(T)]}.
-type af_record_field(T) :: {'record_field', anno(), af_field_name(), T}.
-type af_map_pattern() ::
- {'map', anno(), [af_map_field_exact(abstract_expr)]}. % FIXME?
+ {'map', anno(), [af_assoc_exact(abstract_expr)]}.
-type abstract_type() :: af_annotated_type()
| af_atom()
@@ -807,9 +816,9 @@ Erlang code.
{'type', anno(), 'range', [af_singleton_integer_type()]}.
-type af_map_type() :: {'type', anno(), 'map', 'any'}
- | {'type', anno(), 'map', [af_map_pair_type()]}.
+ | {'type', anno(), 'map', [af_assoc_type()]}.
--type af_map_pair_type() ::
+-type af_assoc_type() ::
{'type', anno(), 'map_field_assoc', [abstract_type()]}
| {'type', anno(), 'map_field_exact', [abstract_type()]}.
@@ -972,6 +981,16 @@ Erlang code.
%% keep track of annotation info in tokens
-define(anno(Tup), element(2, Tup)).
+%-define(DEBUG, true).
+
+-ifdef(DEBUG).
+%% Assumes that erl_anno has been compiled with DEBUG=true.
+-define(ANNO_CHECK(Tokens),
+ [] = [T || T <- Tokens, not is_list(element(2, T))]).
+-else.
+-define(ANNO_CHECK(Tokens), ok).
+-endif.
+
%% Entry points compatible to old erl_parse.
%% These really suck and are only here until Calle gets multiple
%% entry points working.
@@ -981,10 +1000,15 @@ Erlang code.
AbsForm :: abstract_form(),
ErrorInfo :: error_info().
parse_form([{'-',A1},{atom,A2,spec}|Tokens]) ->
- parse([{'-',A1},{'spec',A2}|Tokens]);
+ NewTokens = [{'-',A1},{'spec',A2}|Tokens],
+ ?ANNO_CHECK(NewTokens),
+ parse(NewTokens);
parse_form([{'-',A1},{atom,A2,callback}|Tokens]) ->
- parse([{'-',A1},{'callback',A2}|Tokens]);
+ NewTokens = [{'-',A1},{'callback',A2}|Tokens],
+ ?ANNO_CHECK(NewTokens),
+ parse(NewTokens);
parse_form(Tokens) ->
+ ?ANNO_CHECK(Tokens),
parse(Tokens).
-spec parse_exprs(Tokens) -> {ok, ExprList} | {error, ErrorInfo} when
@@ -992,6 +1016,7 @@ parse_form(Tokens) ->
ExprList :: [abstract_expr()],
ErrorInfo :: error_info().
parse_exprs(Tokens) ->
+ ?ANNO_CHECK(Tokens),
A = erl_anno:new(0),
case parse([{atom,A,f},{'(',A},{')',A},{'->',A}|Tokens]) of
{ok,{function,_Lf,f,0,[{clause,_Lc,[],[],Exprs}]}} ->
@@ -1004,6 +1029,7 @@ parse_exprs(Tokens) ->
Term :: term(),
ErrorInfo :: error_info().
parse_term(Tokens) ->
+ ?ANNO_CHECK(Tokens),
A = erl_anno:new(0),
case parse([{atom,A,f},{'(',A},{')',A},{'->',A}|Tokens]) of
{ok,{function,_Af,f,0,[{clause,_Ac,[],[],[Expr]}]}} ->
@@ -1026,6 +1052,9 @@ build_typed_attribute({atom,Aa,record},
build_typed_attribute({atom,Aa,Attr},
{type_def, {call,_,{atom,_,TypeName},Args}, Type})
when Attr =:= 'type' ; Attr =:= 'opaque' ->
+ lists:foreach(fun({var, A, '_'}) -> ret_err(A, "bad type variable");
+ (_) -> ok
+ end, Args),
case lists:all(fun({var, _, _}) -> true;
(_) -> false
end, Args) of
@@ -1041,13 +1070,13 @@ build_typed_attribute({atom,Aa,Attr},_) ->
end.
build_type_spec({Kind,Aa}, {SpecFun, TypeSpecs})
- when (Kind =:= spec) or (Kind =:= callback) ->
+ when Kind =:= spec ; Kind =:= callback ->
NewSpecFun =
case SpecFun of
{atom, _, Fun} ->
{Fun, find_arity_from_specs(TypeSpecs)};
- {{atom,_, Mod}, {atom,_, Fun}} ->
- {Mod,Fun,find_arity_from_specs(TypeSpecs)}
+ {{atom, _, Mod}, {atom, _, Fun}} ->
+ {Mod, Fun, find_arity_from_specs(TypeSpecs)}
end,
{attribute,Aa,Kind,{NewSpecFun, TypeSpecs}}.
@@ -1061,11 +1090,24 @@ find_arity_from_specs([Spec|_]) ->
{type, _, 'fun', [{type, _, product, Args},_]} = Fun,
length(Args).
-build_def({var, A, '_'}, _Types) ->
+%% The 'is_subtype(V, T)' syntax is not supported as of Erlang/OTP
+%% 19.0, but is kept for backward compatibility.
+build_compat_constraint({atom, _, is_subtype}, [{var, _, _}=LHS, Type]) ->
+ build_constraint(LHS, Type);
+build_compat_constraint({atom, _, is_subtype}, [LHS, _Type]) ->
+ ret_err(?anno(LHS), "bad type variable");
+build_compat_constraint({atom, A, Atom}, _Types) ->
+ ret_err(A, io_lib:format("unsupported constraint ~tw", [Atom])).
+
+build_constraint({atom, _, is_subtype}, [{var, _, _}=LHS, Type]) ->
+ build_constraint(LHS, Type);
+build_constraint({atom, A, Atom}, _Foo) ->
+ ret_err(A, io_lib:format("unsupported constraint ~tw", [Atom]));
+build_constraint({var, A, '_'}, _Types) ->
ret_err(A, "bad type variable");
-build_def(LHS, Types) ->
+build_constraint(LHS, Type) ->
IsSubType = {atom, ?anno(LHS), is_subtype},
- {type, ?anno(LHS), constraint, [IsSubType, [LHS, Types]]}.
+ {type, ?anno(LHS), constraint, [IsSubType, [LHS, Type]]}.
lift_unions(T1, {type, _Aa, union, List}) ->
{type, ?anno(T1), union, [T1|List]};
@@ -1178,7 +1220,7 @@ attribute_farity_map(Args) ->
-spec error_bad_decl(erl_anno:anno(), attributes()) -> no_return().
error_bad_decl(Anno, S) ->
- ret_err(Anno, io_lib:format("bad ~w declaration", [S])).
+ ret_err(Anno, io_lib:format("bad ~tw declaration", [S])).
farity_list({cons,_Ac,{op,_Ao,'/',{atom,_Aa,A},{integer,_Ai,I}},Tail}) ->
[{A,I}|farity_list(Tail)];
@@ -1509,8 +1551,8 @@ type_preop_prec('#') -> {700,800}.
Fun :: fun((Anno) -> NewAnno),
Anno :: erl_anno:anno(),
NewAnno :: erl_anno:anno(),
- Abstr :: erl_parse_tree(),
- NewAbstr :: erl_parse_tree().
+ Abstr :: erl_parse_tree() | form_info(),
+ NewAbstr :: erl_parse_tree() | form_info().
map_anno(F0, Abstr) ->
F = fun(A, Acc) -> {F0(A), Acc} end,
@@ -1524,7 +1566,7 @@ map_anno(F0, Abstr) ->
Acc1 :: term(),
AccIn :: term(),
AccOut :: term(),
- Abstr :: erl_parse_tree().
+ Abstr :: erl_parse_tree() | form_info().
fold_anno(F0, Acc0, Abstr) ->
F = fun(A, Acc) -> {A, F0(A, Acc)} end,
@@ -1539,15 +1581,15 @@ fold_anno(F0, Acc0, Abstr) ->
Acc1 :: term(),
AccIn :: term(),
AccOut :: term(),
- Abstr :: erl_parse_tree(),
- NewAbstr :: erl_parse_tree().
+ Abstr :: erl_parse_tree() | form_info(),
+ NewAbstr :: erl_parse_tree() | form_info().
mapfold_anno(F, Acc0, Abstr) ->
modify_anno1(Abstr, Acc0, F).
-spec new_anno(Term) -> Abstr when
Term :: term(),
- Abstr :: erl_parse_tree().
+ Abstr :: erl_parse_tree() | form_info().
new_anno(Term) ->
F = fun(L, Acc) -> {erl_anno:new(L), Acc} end,
@@ -1555,31 +1597,22 @@ new_anno(Term) ->
NewAbstr.
-spec anno_to_term(Abstr) -> term() when
- Abstr :: erl_parse_tree().
+ Abstr :: erl_parse_tree() | form_info().
anno_to_term(Abstract) ->
- map_anno(fun erl_anno:to_term/1, Abstract).
+ F = fun(Anno, Acc) -> {erl_anno:to_term(Anno), Acc} end,
+ {NewAbstract, []} = modify_anno1(Abstract, [], F),
+ NewAbstract.
--spec anno_from_term(Term) -> erl_parse_tree() when
+-spec anno_from_term(Term) -> erl_parse_tree() | form_info() when
Term :: term().
anno_from_term(Term) ->
- map_anno(fun erl_anno:from_term/1, Term).
+ F = fun(T, Acc) -> {erl_anno:from_term(T), Acc} end,
+ {NewTerm, []} = modify_anno1(Term, [], F),
+ NewTerm.
%% Forms.
-%% Recognize what sys_pre_expand does:
-modify_anno1({'fun',A,F,{_,_,_}=Id}, Ac, Mf) ->
- {A1,Ac1} = Mf(A, Ac),
- {F1,Ac2} = modify_anno1(F, Ac1, Mf),
- {{'fun',A1,F1,Id},Ac2};
-modify_anno1({named_fun,A,N,F,{_,_,_}=Id}, Ac, Mf) ->
- {A1,Ac1} = Mf(A, Ac),
- {F1,Ac2} = modify_anno1(F, Ac1, Mf),
- {{named_fun,A1,N,F1,Id},Ac2};
-modify_anno1({attribute,A,N,[V]}, Ac, Mf) ->
- {{attribute,A1,N1,V1},Ac1} = modify_anno1({attribute,A,N,V}, Ac, Mf),
- {{attribute,A1,N1,[V1]},Ac1};
-%% End of sys_pre_expand special forms.
modify_anno1({function,F,A}, Ac, _Mf) ->
{{function,F,A},Ac};
modify_anno1({function,M,F,A}, Ac, Mf) ->
@@ -1616,6 +1649,8 @@ modify_anno1({warning,W}, Ac, _Mf) ->
{{warning,W},Ac};
modify_anno1({error,W}, Ac, _Mf) ->
{{error,W},Ac};
+modify_anno1({eof,L}, Ac, _Mf) ->
+ {{eof,L},Ac};
%% Expressions.
modify_anno1({clauses,Cs}, Ac, Mf) ->
{Cs1,Ac1} = modify_anno1(Cs, Ac, Mf),
diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl
index d30cd508c1..ee5e7a11bf 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -44,13 +44,22 @@
| {encoding, latin1 | unicode | utf8}).
-type(options() :: hook_function() | [option()]).
--record(pp, {string_fun, char_fun}).
+-record(pp, {value_fun, string_fun, char_fun}).
-record(options, {hook, encoding, opts}).
%-define(DEBUG, true).
-ifdef(DEBUG).
+-define(FORM_TEST(T),
+ _ = case T of
+ {eof, _Line} -> ok;
+ {warning, _W} -> ok;
+ {error, _E} -> ok;
+ _ -> ?TEST(T)
+ end).
+-define(EXPRS_TEST(L),
+ [?TEST(E) || E <- L]).
-define(TEST(T),
%% Assumes that erl_anno has been compiled with DEBUG=true.
%% erl_pp does not use the annoations, but test it anyway.
@@ -62,6 +71,8 @@
erlang:error(badarg, [T])
end).
-else.
+-define(FORM_TEST(T), ok).
+-define(EXPRS_TEST(T), ok).
-define(TEST(T), ok).
-endif.
@@ -80,7 +91,7 @@ form(Thing) ->
Options :: options()).
form(Thing, Options) ->
- ?TEST(Thing),
+ ?FORM_TEST(Thing),
State = state(Options),
frmt(lform(Thing, options(Options)), State).
@@ -124,7 +135,7 @@ guard(Gs) ->
Options :: options()).
guard(Gs, Options) ->
- ?TEST(Gs),
+ ?EXPRS_TEST(Gs),
frmt(lguard(Gs, options(Options)), state(Options)).
-spec(exprs(Expressions) -> io_lib:chars() when
@@ -146,7 +157,7 @@ exprs(Es, Options) ->
Options :: options()).
exprs(Es, I, Options) ->
- ?TEST(Es),
+ ?EXPRS_TEST(Es),
frmt({seq,[],[],[$,],lexprs(Es, options(Options))}, I, state(Options)).
-spec(expr(Expression) -> io_lib:chars() when
@@ -203,11 +214,15 @@ state(_Hook) ->
state().
state() ->
- #pp{string_fun = fun io_lib:write_string_as_latin1/1,
+ Options = [{encoding,latin1}],
+ #pp{value_fun = fun(V) -> io_lib_pretty:print(V, Options) end,
+ string_fun = fun io_lib:write_string_as_latin1/1,
char_fun = fun io_lib:write_char_as_latin1/1}.
unicode_state() ->
- #pp{string_fun = fun io_lib:write_string/1,
+ Options = [{encoding,unicode}],
+ #pp{value_fun = fun(V) -> io_lib_pretty:print(V, Options) end,
+ string_fun = fun io_lib:write_string/1,
char_fun = fun io_lib:write_char/1}.
encoding(Options) ->
@@ -242,31 +257,30 @@ lattribute({attribute,_Line,Name,Arg}, Opts) ->
lattribute(module, {M,Vs}, _Opts) ->
A = a0(),
- attr("module",[{var,A,pname(M)},
- foldr(fun(V, C) -> {cons,A,{var,A,V},C}
- end, {nil,A}, Vs)]);
+ attr(module,[{var,A,pname(M)},
+ foldr(fun(V, C) -> {cons,A,{var,A,V},C}
+ end, {nil,A}, Vs)]);
lattribute(module, M, _Opts) ->
- attr("module", [{var,a0(),pname(M)}]);
+ attr(module, [{var,a0(),pname(M)}]);
lattribute(export, Falist, _Opts) ->
- call({var,a0(),"-export"}, [falist(Falist)], 0, options(none));
+ attrib(export, falist(Falist));
lattribute(import, Name, _Opts) when is_list(Name) ->
- attr("import", [{var,a0(),pname(Name)}]);
+ attr(import, [{var,a0(),pname(Name)}]);
lattribute(import, {From,Falist}, _Opts) ->
- attr("import",[{var,a0(),pname(From)},falist(Falist)]);
+ attrib(import, [leaf(pname(From)),falist(Falist)]);
lattribute(export_type, Talist, _Opts) ->
- call({var,a0(),"-export_type"}, [falist(Talist)], 0, options(none));
+ attrib(export_type, falist(Talist));
lattribute(optional_callbacks, Falist, Opts) ->
- ArgL = try falist(Falist)
- catch _:_ -> abstract(Falist, Opts)
- end,
- call({var,a0(),"-optional_callbacks"}, [ArgL], 0, options(none));
+ try attrib(optional_callbacks, falist(Falist))
+ catch _:_ -> attr(optional_callbacks, [abstract(Falist, Opts)])
+ end;
lattribute(file, {Name,Line}, _Opts) ->
- attr("file", [{string,a0(),Name},{integer,a0(),Line}]);
+ attr(file, [{string,a0(),Name},{integer,a0(),Line}]);
lattribute(record, {Name,Is}, Opts) ->
- Nl = leaf(format("-record(~w,", [Name])),
+ Nl = [leaf("-record("),{atom,Name},$,],
[{first,Nl,record_fields(Is, Opts)},$)];
lattribute(Name, Arg, Options) ->
- attr(write(Name), [abstract(Arg, Options)]).
+ attr(Name, [abstract(Arg, Options)]).
abstract(Arg, #options{encoding = Encoding}) ->
erl_parse:abstract(Arg, [{encoding,Encoding}]).
@@ -329,7 +343,7 @@ ltype({user_type,Line,T,Ts}, _) ->
ltype({remote_type,Line,[M,F,Ts]}, _) ->
simple_type({remote,Line,M,F}, Ts);
ltype({atom,_,T}, _) ->
- leaf(write(T));
+ {atom,T};
ltype(E, P) ->
lexpr(E, P, options(none)).
@@ -371,12 +385,12 @@ tuple_type(Ts, F) ->
specattr(SpecKind, {FuncSpec,TypeSpecs}) ->
Func = case FuncSpec of
{F,_A} ->
- format("~w", [F]);
+ {atom,F};
{M,F,_A} ->
- format("~w:~w", [M, F])
+ [{atom,M},$:,{atom,F}]
end,
{first,leaf(lists:concat(["-", SpecKind, " "])),
- {list,[{first,leaf(Func),spec_clauses(TypeSpecs)}]}}.
+ {list,[{first,Func,spec_clauses(TypeSpecs)}]}}.
spec_clauses(TypeSpecs) ->
{prefer_nl,[$;],[sig_type(T) || T <- TypeSpecs]}.
@@ -418,7 +432,10 @@ ltypes(Ts, F, Prec) ->
[F(T, Prec) || T <- Ts].
attr(Name, Args) ->
- call({var,a0(),format("-~s", [Name])}, Args, 0, options(none)).
+ {first,[$-,{atom,Name}],args(Args, options(none))}.
+
+attrib(Name, Args) ->
+ {first,[$-,{atom,Name}],[{seq,$(,$),[$,],Args}]}.
pname(['' | As]) ->
[$. | pname(As)];
@@ -430,10 +447,13 @@ pname(A) when is_atom(A) ->
write(A).
falist([]) ->
- {nil,a0()};
-falist([{Name,Arity}|Falist]) ->
- A = a0(),
- {cons,A,{var,A,format("~w/~w", [Name,Arity])},falist(Falist)}.
+ [leaf("[]")];
+falist(Falist) ->
+ L = [begin
+ {Name,Arity} = Fa,
+ [{atom,Name},leaf(format("/~w", [Arity]))]
+ end || Fa <- Falist],
+ [{seq,$[,$],$,,L}].
lfunction({function,_Line,Name,_Arity,Cs}, Opts) ->
Cll = nl_clauses(fun (C, H) -> func_clause(Name, C, H) end, $;, Opts, Cs),
@@ -478,7 +498,7 @@ lexpr({var,_,V}, _, _) -> leaf(format("~ts", [V]));
lexpr({char,_,C}, _, _) -> {char,C};
lexpr({integer,_,N}, _, _) -> leaf(write(N));
lexpr({float,_,F}, _, _) -> leaf(write(F));
-lexpr({atom,_,A}, _, _) -> leaf(write(A));
+lexpr({atom,_,A}, _, _) -> {atom,A};
lexpr({string,_,S}, _, _) -> {string,S};
lexpr({nil,_}, _, _) -> '[]';
lexpr({cons,_,H,T}, _, Opts) ->
@@ -508,7 +528,7 @@ lexpr({record, _, Name, Fs}, Prec, Opts) ->
lexpr({record_field, _, Rec, Name, F}, Prec, Opts) ->
{L,P,R} = inop_prec('#'),
Rl = lexpr(Rec, L, Opts),
- Nl = leaf(format("#~w.", [Name])),
+ Nl = [$#,{atom,Name},$.],
El = [Rl,Nl,lexpr(F, R, Opts)],
maybe_paren(P, Prec, El);
lexpr({record, _, Rec, Name, Fs}, Prec, Opts) ->
@@ -527,12 +547,12 @@ lexpr({record_field, _, Rec, F}, Prec, Opts) ->
maybe_paren(P, Prec, El);
lexpr({map, _, Fs}, Prec, Opts) ->
{P,_R} = preop_prec('#'),
- El = {first,leaf("#"),map_fields(Fs, Opts)},
+ El = {first,$#,map_fields(Fs, Opts)},
maybe_paren(P, Prec, El);
lexpr({map, _, Map, Fs}, Prec, Opts) ->
{L,P,_R} = inop_prec('#'),
Rl = lexpr(Map, L, Opts),
- El = {first,[Rl,leaf("#")],map_fields(Fs, Opts)},
+ El = {first,[Rl,$#],map_fields(Fs, Opts)},
maybe_paren(P, Prec, El);
lexpr({block,_,Es}, _, Opts) ->
{list,[{step,'begin',body(Es, Opts)},'end']};
@@ -552,13 +572,16 @@ lexpr({'receive',_,Cs,To,ToOpt}, _, Opts) ->
{step,'after',Al},
'end']};
lexpr({'fun',_,{function,F,A}}, _Prec, _Opts) ->
- leaf(format("fun ~w/~w", [F,A]));
-lexpr({'fun',_,{function,F,A},Extra}, _Prec, _Opts) ->
- {force_nl,fun_info(Extra),leaf(format("fun ~w/~w", [F,A]))};
-lexpr({'fun',_,{function,M,F,A}}, _Prec, _Opts)
+ [leaf("fun "),{atom,F},leaf(format("/~w", [A]))];
+lexpr({'fun',L,{function,_,_}=Func,Extra}, Prec, Opts) ->
+ {force_nl,fun_info(Extra),lexpr({'fun',L,Func}, Prec, Opts)};
+lexpr({'fun',L,{function,M,F,A}}, Prec, Opts)
when is_atom(M), is_atom(F), is_integer(A) ->
%% For backward compatibility with pre-R15 abstract format.
- leaf(format("fun ~w:~w/~w", [M,F,A]));
+ Mod = erl_parse:abstract(M),
+ Fun = erl_parse:abstract(F),
+ Arity = erl_parse:abstract(A),
+ lexpr({'fun',L,{function,Mod,Fun,Arity}}, Prec, Opts);
lexpr({'fun',_,{function,M,F,A}}, _Prec, Opts) ->
%% New format in R15.
NameItem = lexpr(M, Opts),
@@ -649,7 +672,7 @@ lexpr({bin,_,Fs}, _, Opts) ->
bit_grp(Fs, Opts);
%% Special case for straight values.
lexpr({value,_,Val}, _,_) ->
- leaf(write(Val));
+ {value,Val};
%% Now do the hook.
lexpr(Other, _Precedence, #options{hook = none}) ->
leaf(format("INVALID-FORM:~w:",[Other]));
@@ -665,7 +688,7 @@ call(Name, Args, Prec, Opts) ->
maybe_paren(P, Prec, Item).
fun_info(Extra) ->
- leaf(format("% fun-info: ~w", [Extra])).
+ [leaf("% fun-info: "),{value,Extra}].
%% BITS:
@@ -706,7 +729,7 @@ bit_elem_type(T) ->
%% end of BITS
record_name(Name) ->
- leaf(format("#~w", [Name])).
+ [$#,{atom,Name}].
record_fields(Fs, Opts) ->
tuple(Fs, fun record_field/2, Opts).
@@ -908,8 +931,10 @@ frmt(Item, I, PP) ->
%%% - {force_nl,ExtraInfo,I}: fun-info (a comment) forces linebreak before I.
%%% - {prefer_nl,Sep,IPs}: forces linebreak between Is unlesss negative
%%% indentation.
+%%% - {atom,A}: an atom
%%% - {char,C}: a character
%%% - {string,S}: a string.
+%%% - {value,T}: a term.
%%% - {hook,...}, {ehook,...}: hook expressions.
%%%
%%% list, first, seq, force_nl, and prefer_nl all accept IPs, where each
@@ -970,6 +995,10 @@ f({prefer_nl,Sep,LItems}, I0, ST, WT, PP) ->
true ->
{insert_newlines(CharsSize2L, I0, ST),nsz(lists:last(Sizes), I0)}
end;
+f({value,V}, I, ST, WT, PP) ->
+ f(write_a_value(V, PP), I, ST, WT, PP);
+f({atom,A}, I, ST, WT, PP) ->
+ f(write_an_atom(A, PP), I, ST, WT, PP);
f({char,C}, I, ST, WT, PP) ->
f(write_a_char(C, PP), I, ST, WT, PP);
f({string,S}, I, ST, WT, PP) ->
@@ -1108,6 +1137,12 @@ has_nl([C|Cs]) ->
has_nl([]) ->
false.
+write_a_value(V, PP) ->
+ flat_leaf(write_value(V, PP)).
+
+write_an_atom(A, PP) ->
+ flat_leaf(write_atom(A, PP)).
+
write_a_char(C, PP) ->
flat_leaf(write_char(C, PP)).
@@ -1124,7 +1159,7 @@ write_a_string([], _N, _Len, _PP) ->
write_a_string(S, N, Len, PP) ->
SS = string:sub_string(S, 1, N),
Sl = write_string(SS, PP),
- case (length(Sl) > Len) and (N > ?MIN_SUBSTRING) of
+ case (chars_size(Sl) > Len) and (N > ?MIN_SUBSTRING) of
true ->
write_a_string(S, N-1, Len, PP);
false ->
@@ -1136,11 +1171,17 @@ flat_leaf(S) ->
L = lists:flatten(S),
{leaf,length(L),L}.
+write_value(V, PP) ->
+ (PP#pp.value_fun)(V).
+
+write_atom(A, PP) ->
+ (PP#pp.value_fun)(A).
+
write_string(S, PP) ->
- lists:flatten((PP#pp.string_fun)(S)).
+ (PP#pp.string_fun)(S).
write_char(C, PP) ->
- lists:flatten((PP#pp.char_fun)(C)).
+ (PP#pp.char_fun)(C).
%%
%% Utilities
diff --git a/lib/stdlib/src/erl_tar.erl b/lib/stdlib/src/erl_tar.erl
index a383a0fc67..76f0b38108 100644
--- a/lib/stdlib/src/erl_tar.erl
+++ b/lib/stdlib/src/erl_tar.erl
@@ -1,8 +1,8 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
+%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,191 +14,259 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
+%%
%% %CopyrightEnd%
%%
+%% This module implements extraction/creation of tar archives.
+%% It supports reading most common tar formats, namely V7, STAR,
+%% USTAR, GNU, BSD/libarchive, and PAX. It produces archives in USTAR
+%% format, unless it must use PAX headers, in which case it produces PAX
+%% format.
+%%
+%% The following references where used:
+%% http://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5
+%% http://www.gnu.org/software/tar/manual/html_node/Standard.html
+%% http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html
-module(erl_tar).
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Purpose: Unix tar (tape archive) utility.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
--export([init/3, create/2, create/3, extract/1, extract/2, table/1, table/2,
- open/2, close/1, add/3, add/4,
- t/1, tt/1, format_error/1]).
+-export([init/3,
+ create/2, create/3,
+ extract/1, extract/2,
+ table/1, table/2, t/1, tt/1,
+ open/2, close/1,
+ add/3, add/4,
+ format_error/1]).
-include_lib("kernel/include/file.hrl").
+-include_lib("erl_tar.hrl").
--record(add_opts,
- {read_info, % Fun to use for read file/link info.
- chunk_size = 0, % For file reading when sending to sftp. 0=do not chunk
- verbose = false :: boolean()}). % Verbose on/off.
-
-%% Opens a tar archive.
-
-init(UsrHandle, AccessMode, Fun) when is_function(Fun,2) ->
- {ok, {AccessMode,{tar_descriptor,UsrHandle,Fun}}}.
-
-%%%================================================================
-%%% The open function with friends is to keep the file and binary api of this module
-open(Name, Mode) ->
- case open_mode(Mode) of
- {ok, Access, Raw, Opts} ->
- open1(Name, Access, Raw, Opts);
- {error, Reason} ->
- {error, {Name, Reason}}
- end.
-
-open1({binary,Bin}, read, _Raw, Opts) ->
- case file:open(Bin, [ram,binary,read]) of
- {ok,File} ->
- _ = [ram_file:uncompress(File) || Opts =:= [compressed]],
- init(File,read,file_fun());
- Error ->
- Error
- end;
-open1({file, Fd}, read, _Raw, _Opts) ->
- init(Fd, read, file_fun());
-open1(Name, Access, Raw, Opts) ->
- case file:open(Name, Raw ++ [binary, Access|Opts]) of
- {ok, File} ->
- init(File, Access, file_fun());
- {error, Reason} ->
- {error, {Name, Reason}}
- end.
-
-file_fun() ->
- fun(write, {Fd,Data}) -> file:write(Fd, Data);
- (position, {Fd,Pos}) -> file:position(Fd, Pos);
- (read2, {Fd,Size}) -> file:read(Fd,Size);
- (close, Fd) -> file:close(Fd)
- end.
-
-%%% End of file and binary api (except for open_mode/1 downwards
-%%%================================================================
-
-%% Closes a tar archive.
-
-close({read, File}) ->
- ok = do_close(File);
-close({write, File}) ->
- PadResult = pad_file(File),
- ok = do_close(File),
- PadResult;
-close(_) ->
- {error, einval}.
-
-%% Adds a file to a tape archive.
-
-add(File, Name, Options) ->
- add(File, Name, Name, Options).
-add({write, File}, Name, NameInArchive, Options) ->
- Opts = #add_opts{read_info=fun(F) -> file:read_link_info(F) end},
- add1(File, Name, NameInArchive, add_opts(Options, Opts));
-add({read, _File}, _, _, _) ->
- {error, eacces};
-add(_, _, _, _) ->
- {error, einval}.
-
-add_opts([dereference|T], Opts) ->
- add_opts(T, Opts#add_opts{read_info=fun(F) -> file:read_file_info(F) end});
-add_opts([verbose|T], Opts) ->
- add_opts(T, Opts#add_opts{verbose=true});
-add_opts([{chunks,N}|T], Opts) ->
- add_opts(T, Opts#add_opts{chunk_size=N});
-add_opts([_|T], Opts) ->
- add_opts(T, Opts);
-add_opts([], Opts) ->
- Opts.
-
-%% Creates a tar file Name containing the given files.
-
-create(Name, Filenames) ->
- create(Name, Filenames, []).
-
-%% Creates a tar archive Name containing the given files.
-%% Accepted options: verbose, compressed, cooked
+%% Converts the short error reason to a descriptive string.
+-spec format_error(term()) -> string().
+format_error(invalid_tar_checksum) ->
+ "Checksum failed";
+format_error(bad_header) ->
+ "Unrecognized tar header format";
+format_error({bad_header, Reason}) ->
+ lists:flatten(io_lib:format("Unrecognized tar header format: ~p", [Reason]));
+format_error({invalid_header, negative_size}) ->
+ "Invalid header: negative size";
+format_error(invalid_sparse_header_size) ->
+ "Invalid sparse header: negative size";
+format_error(invalid_sparse_map_entry) ->
+ "Invalid sparse map entry";
+format_error({invalid_sparse_map_entry, Reason}) ->
+ lists:flatten(io_lib:format("Invalid sparse map entry: ~p", [Reason]));
+format_error(invalid_end_of_archive) ->
+ "Invalid end of archive";
+format_error(eof) ->
+ "Unexpected end of file";
+format_error(integer_overflow) ->
+ "Failed to parse numeric: integer overflow";
+format_error({misaligned_read, Pos}) ->
+ lists:flatten(io_lib:format("Read a block which was misaligned: block_size=~p pos=~p",
+ [?BLOCK_SIZE, Pos]));
+format_error(invalid_gnu_1_0_sparsemap) ->
+ "Invalid GNU sparse map (version 1.0)";
+format_error({invalid_gnu_0_1_sparsemap, Format}) ->
+ lists:flatten(io_lib:format("Invalid GNU sparse map (version ~s)", [Format]));
+format_error(unsafe_path) ->
+ "The path points above the current working directory";
+format_error({Name,Reason}) ->
+ lists:flatten(io_lib:format("~ts: ~ts", [Name,format_error(Reason)]));
+format_error(Atom) when is_atom(Atom) ->
+ file:format_error(Atom);
+format_error(Term) ->
+ lists:flatten(io_lib:format("~tp", [Term])).
-create(Name, FileList, Options) ->
- Mode = lists:filter(fun(X) -> (X=:=compressed) or (X=:=cooked)
- end, Options),
- case open(Name, [write|Mode]) of
- {ok, TarFile} ->
- Add = fun({NmInA, NmOrBin}) ->
- add(TarFile, NmOrBin, NmInA, Options);
- (Nm) ->
- add(TarFile, Nm, Nm, Options)
- end,
- Result = foreach_while_ok(Add, FileList),
- case {Result, close(TarFile)} of
- {ok, Res} -> Res;
- {Res, _} -> Res
- end;
- Reason ->
- Reason
- end.
+%% Initializes a new reader given a custom file handle and I/O wrappers
+-spec init(handle(), write | read, file_op()) -> {ok, reader()} | {error, badarg}.
+init(Handle, AccessMode, Fun) when is_function(Fun, 2) ->
+ Reader = #reader{handle=Handle,access=AccessMode,func=Fun},
+ {ok, Pos, Reader2} = do_position(Reader, {cur, 0}),
+ {ok, Reader2#reader{pos=Pos}};
+init(_Handle, _AccessMode, _Fun) ->
+ {error, badarg}.
+%%%================================================================
%% Extracts all files from the tar file Name.
-
+-spec extract(open_handle()) -> ok | {error, term()}.
extract(Name) ->
extract(Name, []).
%% Extracts (all) files from the tar file Name.
-%% Options accepted: keep_old_files, {files, ListOfFilesToExtract}, verbose,
-%% {cwd, AbsoluteDirectory}
+%% Options accepted:
+%% - cooked: Opens the tar file without mode `raw`
+%% - compressed: Uncompresses the tar file when reading
+%% - memory: Returns the tar contents as a list of tuples {Name, Bin}
+%% - keep_old_files: Extracted files will not overwrite the destination
+%% - {files, ListOfFilesToExtract}: Only extract ListOfFilesToExtract
+%% - verbose: Prints verbose information about the extraction,
+%% - {cwd, AbsoluteDir}: Sets the current working directory for the extraction
+-spec extract(open_handle(), [extract_opt()]) ->
+ ok
+ | {ok, [{string(), binary()}]}
+ | {error, term()}.
+extract({binary, Bin}, Opts) when is_list(Opts) ->
+ do_extract({binary, Bin}, Opts);
+extract({file, Fd}, Opts) when is_list(Opts) ->
+ do_extract({file, Fd}, Opts);
+extract(#reader{}=Reader, Opts) when is_list(Opts) ->
+ do_extract(Reader, Opts);
+extract(Name, Opts) when is_list(Name); is_binary(Name), is_list(Opts) ->
+ do_extract(Name, Opts).
+
+do_extract(Handle, Opts) when is_list(Opts) ->
+ Opts2 = extract_opts(Opts),
+ Acc = if Opts2#read_opts.output =:= memory -> []; true -> ok end,
+ foldl_read(Handle, fun extract1/4, Acc, Opts2).
+
+extract1(eof, Reader, _, Acc) when is_list(Acc) ->
+ {ok, {ok, lists:reverse(Acc)}, Reader};
+extract1(eof, Reader, _, leading_slash) ->
+ error_logger:info_msg("erl_tar: removed leading '/' from member names\n"),
+ {ok, ok, Reader};
+extract1(eof, Reader, _, Acc) ->
+ {ok, Acc, Reader};
+extract1(#tar_header{name=Name,size=Size}=Header, Reader0, Opts, Acc0) ->
+ case check_extract(Name, Opts) of
+ true ->
+ case do_read(Reader0, Size) of
+ {ok, Bin, Reader1} ->
+ Acc = extract2(Header, Bin, Opts, Acc0),
+ {ok, Acc, Reader1};
+ {error, _} = Err ->
+ throw(Err)
+ end;
+ false ->
+ {ok, Acc0, skip_file(Reader0)}
+ end.
-extract(Name, Opts) ->
- foldl_read(Name, fun extract1/4, ok, extract_opts(Opts)).
+extract2(Header, Bin, Opts, Acc) ->
+ case write_extracted_element(Header, Bin, Opts) of
+ ok ->
+ case Header of
+ #tar_header{name="/"++_} ->
+ leading_slash;
+ #tar_header{} ->
+ Acc
+ end;
+ {ok, NameBin} when is_list(Acc) ->
+ [NameBin | Acc];
+ {error, _} = Err ->
+ throw(Err)
+ end.
-%% Returns a list of names of the files in the tar file Name.
-%% Options accepted: verbose
+%% Checks if the file Name should be extracted.
+check_extract(_, #read_opts{files=all}) ->
+ true;
+check_extract(Name, #read_opts{files=Files}) ->
+ ordsets:is_element(Name, Files).
+
+%%%================================================================
+%% The following table functions produce a list of information about
+%% the files contained in the archive.
+-type filename() :: string().
+-type typeflag() :: regular | link | symlink |
+ char | block | directory |
+ fifo | reserved | unknown.
+-type mode() :: non_neg_integer().
+-type uid() :: non_neg_integer().
+-type gid() :: non_neg_integer().
+
+-type tar_entry() :: {filename(),
+ typeflag(),
+ non_neg_integer(),
+ tar_time(),
+ mode(),
+ uid(),
+ gid()}.
+%% Returns a list of names of the files in the tar file Name.
+-spec table(open_handle()) -> {ok, [string()]} | {error, term()}.
table(Name) ->
table(Name, []).
%% Returns a list of names of the files in the tar file Name.
%% Options accepted: compressed, verbose, cooked.
-
-table(Name, Opts) ->
+-spec table(open_handle(), [compressed | verbose | cooked]) ->
+ {ok, [tar_entry()]} | {error, term()}.
+table(Name, Opts) when is_list(Opts) ->
foldl_read(Name, fun table1/4, [], table_opts(Opts)).
+table1(eof, Reader, _, Result) ->
+ {ok, {ok, lists:reverse(Result)}, Reader};
+table1(#tar_header{}=Header, Reader, #read_opts{verbose=Verbose}, Result) ->
+ Attrs = table1_attrs(Header, Verbose),
+ Reader2 = skip_file(Reader),
+ {ok, [Attrs|Result], Reader2}.
+%% Extracts attributes relevant to table1's output
+table1_attrs(#tar_header{typeflag=Typeflag,mode=Mode}=Header, true) ->
+ Type = typeflag(Typeflag),
+ Name = Header#tar_header.name,
+ Mtime = Header#tar_header.mtime,
+ Uid = Header#tar_header.uid,
+ Gid = Header#tar_header.gid,
+ Size = Header#tar_header.size,
+ {Name, Type, Size, Mtime, Mode, Uid, Gid};
+table1_attrs(#tar_header{name=Name}, _Verbose) ->
+ Name.
+
+typeflag(?TYPE_REGULAR) -> regular;
+typeflag(?TYPE_REGULAR_A) -> regular;
+typeflag(?TYPE_GNU_SPARSE) -> regular;
+typeflag(?TYPE_CONT) -> regular;
+typeflag(?TYPE_LINK) -> link;
+typeflag(?TYPE_SYMLINK) -> symlink;
+typeflag(?TYPE_CHAR) -> char;
+typeflag(?TYPE_BLOCK) -> block;
+typeflag(?TYPE_DIR) -> directory;
+typeflag(?TYPE_FIFO) -> fifo;
+typeflag(_) -> unknown.
+
+%%%================================================================
%% Comments for printing the contents of a tape archive,
%% meant to be invoked from the shell.
-t(Name) ->
+%% Prints each filename in the archive
+-spec t(file:filename()) -> ok | {error, term()}.
+t(Name) when is_list(Name); is_binary(Name) ->
case table(Name) of
- {ok, List} ->
- lists:foreach(fun(N) -> ok = io:format("~ts\n", [N]) end, List);
- Error ->
- Error
+ {ok, List} ->
+ lists:foreach(fun(N) -> ok = io:format("~ts\n", [N]) end, List);
+ Error ->
+ Error
end.
+%% Prints verbose information about each file in the archive
+-spec tt(open_handle()) -> ok | {error, term()}.
tt(Name) ->
case table(Name, [verbose]) of
- {ok, List} ->
- lists:foreach(fun print_header/1, List);
- Error ->
- Error
+ {ok, List} ->
+ lists:foreach(fun print_header/1, List);
+ Error ->
+ Error
end.
+%% Used by tt/1 to print a tar_entry tuple
+-spec print_header(tar_entry()) -> ok.
print_header({Name, Type, Size, Mtime, Mode, Uid, Gid}) ->
io:format("~s~s ~4w/~-4w ~7w ~s ~s\n",
- [type_to_string(Type), mode_to_string(Mode),
- Uid, Gid, Size, time_to_string(Mtime), Name]).
+ [type_to_string(Type), mode_to_string(Mode),
+ Uid, Gid, Size, time_to_string(Mtime), Name]).
-type_to_string(regular) -> "-";
+type_to_string(regular) -> "-";
type_to_string(directory) -> "d";
-type_to_string(link) -> "l";
-type_to_string(symlink) -> "s";
-type_to_string(char) -> "c";
-type_to_string(block) -> "b";
-type_to_string(fifo) -> "f";
-type_to_string(_) -> "?".
-
+type_to_string(link) -> "l";
+type_to_string(symlink) -> "s";
+type_to_string(char) -> "c";
+type_to_string(block) -> "b";
+type_to_string(fifo) -> "f";
+type_to_string(unknown) -> "?".
+
+%% Converts a numeric mode to its human-readable representation
mode_to_string(Mode) ->
mode_to_string(Mode, "xwrxwrxwr", []).
-
mode_to_string(Mode, [C|T], Acc) when Mode band 1 =:= 1 ->
mode_to_string(Mode bsr 1, T, [C|Acc]);
mode_to_string(Mode, [_|T], Acc) ->
@@ -206,7 +274,13 @@ mode_to_string(Mode, [_|T], Acc) ->
mode_to_string(_, [], Acc) ->
Acc.
-time_to_string({{Y, Mon, Day}, {H, Min, _}}) ->
+%% Converts a tar_time() (POSIX time) to a readable string
+time_to_string(Secs0) ->
+ Epoch = calendar:datetime_to_gregorian_seconds(?EPOCH),
+ Secs = Epoch + Secs0,
+ DateTime0 = calendar:gregorian_seconds_to_datetime(Secs),
+ DateTime = calendar:universal_time_to_local_time(DateTime0),
+ {{Y, Mon, Day}, {H, Min, _}} = DateTime,
io_lib:format("~s ~2w ~s:~s ~w", [month(Mon), Day, two_d(H), two_d(Min), Y]).
two_d(N) ->
@@ -225,809 +299,1607 @@ month(10) -> "Oct";
month(11) -> "Nov";
month(12) -> "Dec".
-%% Converts the short error reason to a descriptive string.
+%%%================================================================
+%% The open function with friends is to keep the file and binary api of this module
+-type open_handle() :: file:filename()
+ | {binary, binary()}
+ | {file, term()}.
+-spec open(open_handle(), [write | compressed | cooked]) ->
+ {ok, reader()} | {error, term()}.
+open({binary, Bin}, Mode) when is_binary(Bin) ->
+ do_open({binary, Bin}, Mode);
+open({file, Fd}, Mode) ->
+ do_open({file, Fd}, Mode);
+open(Name, Mode) when is_list(Name); is_binary(Name) ->
+ do_open(Name, Mode).
+
+do_open(Name, Mode) when is_list(Mode) ->
+ case open_mode(Mode) of
+ {ok, Access, Raw, Opts} ->
+ open1(Name, Access, Raw, Opts);
+ {error, Reason} ->
+ {error, {Name, Reason}}
+ end.
-format_error(bad_header) -> "Bad directory header";
-format_error(eof) -> "Unexpected end of file";
-format_error(symbolic_link_too_long) -> "Symbolic link too long";
-format_error({Name,Reason}) ->
- lists:flatten(io_lib:format("~ts: ~ts", [Name,format_error(Reason)]));
-format_error(Atom) when is_atom(Atom) ->
- file:format_error(Atom);
-format_error(Term) ->
- lists:flatten(io_lib:format("~tp", [Term])).
+open1({binary,Bin}, read, _Raw, Opts) when is_binary(Bin) ->
+ case file:open(Bin, [ram,binary,read]) of
+ {ok,File} ->
+ _ = [ram_file:uncompress(File) || Opts =:= [compressed]],
+ {ok, #reader{handle=File,access=read,func=fun file_op/2}};
+ Error ->
+ Error
+ end;
+open1({file, Fd}, read, _Raw, _Opts) ->
+ Reader = #reader{handle=Fd,access=read,func=fun file_op/2},
+ case do_position(Reader, {cur, 0}) of
+ {ok, Pos, Reader2} ->
+ {ok, Reader2#reader{pos=Pos}};
+ {error, _} = Err ->
+ Err
+ end;
+open1(Name, Access, Raw, Opts) when is_list(Name) or is_binary(Name) ->
+ case file:open(Name, Raw ++ [binary, Access|Opts]) of
+ {ok, File} ->
+ {ok, #reader{handle=File,access=Access,func=fun file_op/2}};
+ {error, Reason} ->
+ {error, {Name, Reason}}
+ end.
+open_mode(Mode) ->
+ open_mode(Mode, false, [raw], []).
+
+open_mode(read, _, Raw, _) ->
+ {ok, read, Raw, []};
+open_mode(write, _, Raw, _) ->
+ {ok, write, Raw, []};
+open_mode([read|Rest], false, Raw, Opts) ->
+ open_mode(Rest, read, Raw, Opts);
+open_mode([write|Rest], false, Raw, Opts) ->
+ open_mode(Rest, write, Raw, Opts);
+open_mode([compressed|Rest], Access, Raw, Opts) ->
+ open_mode(Rest, Access, Raw, [compressed|Opts]);
+open_mode([cooked|Rest], Access, _Raw, Opts) ->
+ open_mode(Rest, Access, [], Opts);
+open_mode([], Access, Raw, Opts) ->
+ {ok, Access, Raw, Opts};
+open_mode(_, _, _, _) ->
+ {error, einval}.
+
+file_op(write, {Fd, Data}) ->
+ file:write(Fd, Data);
+file_op(position, {Fd, Pos}) ->
+ file:position(Fd, Pos);
+file_op(read2, {Fd, Size}) ->
+ file:read(Fd, Size);
+file_op(close, Fd) ->
+ file:close(Fd).
+
+%% Closes a tar archive.
+-spec close(reader()) -> ok | {error, term()}.
+close(#reader{access=read}=Reader) ->
+ ok = do_close(Reader);
+close(#reader{access=write}=Reader) ->
+ {ok, Reader2} = pad_file(Reader),
+ ok = do_close(Reader2),
+ ok;
+close(_) ->
+ {error, einval}.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%
-%%% Useful definitions (also start of implementation).
-%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% Offset for fields in the tar header.
-%% Note that these offsets are ZERO-based as in the POSIX standard
-%% document, while binaries use ONE-base offset. Caveat Programmer.
-
--define(th_name, 0).
--define(th_mode, 100).
--define(th_uid, 108).
--define(th_gid, 116).
--define(th_size, 124).
--define(th_mtime, 136).
--define(th_chksum, 148).
--define(th_typeflag, 156).
--define(th_linkname, 157).
--define(th_magic, 257).
--define(th_version, 263).
--define(th_prefix, 345).
-
-%% Length of these fields.
-
--define(th_name_len, 100).
--define(th_mode_len, 8).
--define(th_uid_len, 8).
--define(th_gid_len, 8).
--define(th_size_len, 12).
--define(th_mtime_len, 12).
--define(th_chksum_len, 8).
--define(th_linkname_len, 100).
--define(th_magic_len, 6).
--define(th_version_len, 2).
--define(th_prefix_len, 167).
-
--record(tar_header,
- {name, % Name of file.
- mode, % Mode bits.
- uid, % User id.
- gid, % Group id.
- size, % Size of file
- mtime, % Last modified (seconds since
- % Jan 1, 1970).
- chksum, % Checksum of header.
- typeflag = [], % Type of file.
- linkname = [], % Name of link.
- filler = [],
- prefix}). % Filename prefix.
-
--define(record_size, 512).
--define(block_size, (512*20)).
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%
-%%% Adding members to a tar archive.
-%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-add1(TarFile, Bin, NameInArchive, Opts) when is_binary(Bin) ->
- Now = calendar:now_to_local_time(erlang:timestamp()),
- Info = #file_info{size = byte_size(Bin),
- type = regular,
- access = read_write,
- atime = Now,
- mtime = Now,
- ctime = Now,
- mode = 8#100644,
- links = 1,
- major_device = 0,
- minor_device = 0,
- inode = 0,
- uid = 0,
- gid = 0},
- Header = create_header(NameInArchive, Info),
- add1(TarFile, NameInArchive, Header, Bin, Opts);
-add1(TarFile, Name, NameInArchive, Opts) ->
- case read_file_and_info(Name, Opts) of
- {ok, Bin, Info} when Info#file_info.type =:= regular ->
- Header = create_header(NameInArchive, Info),
- add1(TarFile, Name, Header, Bin, Opts);
- {ok, PointsTo, Info} when Info#file_info.type =:= symlink ->
- if
- length(PointsTo) > 100 ->
- {error,{PointsTo,symbolic_link_too_long}};
- true ->
- Info2 = Info#file_info{size=0},
- Header = create_header(NameInArchive, Info2, PointsTo),
- add1(TarFile, Name, Header, list_to_binary([]), Opts)
- end;
- {ok, _, Info} when Info#file_info.type =:= directory ->
- add_directory(TarFile, Name, NameInArchive, Info, Opts);
- {ok, _, #file_info{type=Type}} ->
- {error, {bad_file_type, Name, Type}};
- {error, Reason} ->
- {error, {Name, Reason}}
+pad_file(#reader{pos=Pos}=Reader) ->
+ %% There must be at least two zero blocks at the end.
+ PadCurrent = skip_padding(Pos+?BLOCK_SIZE),
+ Padding = <<0:PadCurrent/unit:8>>,
+ do_write(Reader, [Padding, ?ZERO_BLOCK, ?ZERO_BLOCK]).
+
+
+%%%================================================================
+%% Creation/modification of tar archives
+
+%% Creates a tar file Name containing the given files.
+-spec create(file:filename(), filelist()) -> ok | {error, {string(), term()}}.
+create(Name, FileList) when is_list(Name); is_binary(Name) ->
+ create(Name, FileList, []).
+
+%% Creates a tar archive Name containing the given files.
+%% Accepted options: verbose, compressed, cooked
+-spec create(file:filename(), filelist(), [create_opt()]) ->
+ ok | {error, term()} | {error, {string(), term()}}.
+create(Name, FileList, Options) when is_list(Name); is_binary(Name) ->
+ Mode = lists:filter(fun(X) -> (X=:=compressed) or (X=:=cooked)
+ end, Options),
+ case open(Name, [write|Mode]) of
+ {ok, TarFile} ->
+ do_create(TarFile, FileList, Options);
+ {error, _} = Err ->
+ Err
end.
-add1(Tar, Name, Header, chunked, Options) ->
- add_verbose(Options, "a ~ts [chunked ", [Name]),
- try
- ok = do_write(Tar, Header),
- {ok,D} = file:open(Name, [read,binary]),
- {ok,NumBytes} = add_read_write_chunks(D, Tar, Options#add_opts.chunk_size, 0, Options),
- _ = file:close(D),
- ok = do_write(Tar, padding(NumBytes,?record_size))
- of
- ok ->
- add_verbose(Options, "~n", []),
- ok
- catch
- error:{badmatch,{error,Error}} ->
- add_verbose(Options, "~n", []),
- {error,{Name,Error}}
+do_create(TarFile, [], _Opts) ->
+ close(TarFile);
+do_create(TarFile, [{NameInArchive, NameOrBin}|Rest], Opts) ->
+ case add(TarFile, NameOrBin, NameInArchive, Opts) of
+ ok ->
+ do_create(TarFile, Rest, Opts);
+ {error, _} = Err ->
+ _ = close(TarFile),
+ Err
+ end;
+do_create(TarFile, [Name|Rest], Opts) ->
+ case add(TarFile, Name, Name, Opts) of
+ ok ->
+ do_create(TarFile, Rest, Opts);
+ {error, _} = Err ->
+ _ = close(TarFile),
+ Err
+ end.
+
+%% Adds a file to a tape archive.
+-type add_type() :: string()
+ | {string(), string()}
+ | {string(), binary()}.
+-spec add(reader(), add_type(), [add_opt()]) -> ok | {error, term()}.
+add(Reader, {NameInArchive, Name}, Opts)
+ when is_list(NameInArchive), is_list(Name) ->
+ do_add(Reader, Name, NameInArchive, Opts);
+add(Reader, {NameInArchive, Bin}, Opts)
+ when is_list(NameInArchive), is_binary(Bin) ->
+ do_add(Reader, Bin, NameInArchive, Opts);
+add(Reader, Name, Opts) when is_list(Name) ->
+ do_add(Reader, Name, Name, Opts).
+
+
+-spec add(reader(), string() | binary(), string(), [add_opt()]) ->
+ ok | {error, term()}.
+add(Reader, NameOrBin, NameInArchive, Options)
+ when is_list(NameOrBin); is_binary(NameOrBin),
+ is_list(NameInArchive), is_list(Options) ->
+ do_add(Reader, NameOrBin, NameInArchive, Options).
+
+do_add(#reader{access=write}=Reader, Name, NameInArchive, Options)
+ when is_list(NameInArchive), is_list(Options) ->
+ RF = fun(F) -> file:read_link_info(F, [{time, posix}]) end,
+ Opts = #add_opts{read_info=RF},
+ add1(Reader, Name, NameInArchive, add_opts(Options, Opts));
+do_add(#reader{access=read},_,_,_) ->
+ {error, eacces};
+do_add(Reader,_,_,_) ->
+ {error, {badarg, Reader}}.
+
+add_opts([dereference|T], Opts) ->
+ RF = fun(F) -> file:read_file_info(F, [{time, posix}]) end,
+ add_opts(T, Opts#add_opts{read_info=RF});
+add_opts([verbose|T], Opts) ->
+ add_opts(T, Opts#add_opts{verbose=true});
+add_opts([{chunks,N}|T], Opts) ->
+ add_opts(T, Opts#add_opts{chunk_size=N});
+add_opts([_|T], Opts) ->
+ add_opts(T, Opts);
+add_opts([], Opts) ->
+ Opts.
+
+add1(#reader{}=Reader, Name, NameInArchive, #add_opts{read_info=ReadInfo}=Opts)
+ when is_list(Name) ->
+ Res = case ReadInfo(Name) of
+ {error, Reason0} ->
+ {error, {Name, Reason0}};
+ {ok, #file_info{type=symlink}=Fi} ->
+ add_verbose(Opts, "a ~ts~n", [NameInArchive]),
+ {ok, Linkname} = file:read_link(Name),
+ Header = fileinfo_to_header(NameInArchive, Fi, Linkname),
+ add_header(Reader, Header, Opts);
+ {ok, #file_info{type=regular}=Fi} ->
+ add_verbose(Opts, "a ~ts~n", [NameInArchive]),
+ Header = fileinfo_to_header(NameInArchive, Fi, false),
+ {ok, Reader2} = add_header(Reader, Header, Opts),
+ FileSize = Header#tar_header.size,
+ {ok, FileSize, Reader3} = do_copy(Reader2, Name, Opts),
+ Padding = skip_padding(FileSize),
+ Pad = <<0:Padding/unit:8>>,
+ do_write(Reader3, Pad);
+ {ok, #file_info{type=directory}=Fi} ->
+ add_directory(Reader, Name, NameInArchive, Fi, Opts);
+ {ok, #file_info{}=Fi} ->
+ add_verbose(Opts, "a ~ts~n", [NameInArchive]),
+ Header = fileinfo_to_header(NameInArchive, Fi, false),
+ add_header(Reader, Header, Opts)
+ end,
+ case Res of
+ ok -> ok;
+ {ok, _Reader} -> ok;
+ {error, _Reason} = Err -> Err
end;
-add1(Tar, Name, Header, Bin, Options) ->
- add_verbose(Options, "a ~ts~n", [Name]),
- do_write(Tar, [Header, Bin, padding(byte_size(Bin), ?record_size)]).
-
-add_read_write_chunks(D, Tar, ChunkSize, SumNumBytes, Options) ->
- case file:read(D, ChunkSize) of
- {ok,Bin} ->
- ok = do_write(Tar, Bin),
- add_verbose(Options, ".", []),
- add_read_write_chunks(D, Tar, ChunkSize, SumNumBytes+byte_size(Bin), Options);
- eof ->
- add_verbose(Options, "]", []),
- {ok,SumNumBytes};
- Other ->
- Other
+add1(Reader, Bin, NameInArchive, Opts) when is_binary(Bin) ->
+ add_verbose(Opts, "a ~ts~n", [NameInArchive]),
+ Now = os:system_time(seconds),
+ Header = #tar_header{
+ name = NameInArchive,
+ size = byte_size(Bin),
+ typeflag = ?TYPE_REGULAR,
+ atime = Now,
+ mtime = Now,
+ ctime = Now,
+ mode = 8#100644},
+ {ok, Reader2} = add_header(Reader, Header, Opts),
+ Padding = skip_padding(byte_size(Bin)),
+ Data = [Bin, <<0:Padding/unit:8>>],
+ case do_write(Reader2, Data) of
+ {ok, _Reader3} -> ok;
+ {error, Reason} -> {error, {NameInArchive, Reason}}
end.
-add_directory(TarFile, DirName, NameInArchive, Info, Options) ->
+add_directory(Reader, DirName, NameInArchive, Info, Opts) ->
case file:list_dir(DirName) of
- {ok, []} ->
- add_verbose(Options, "a ~ts~n", [DirName]),
- Header = create_header(NameInArchive, Info),
- do_write(TarFile, Header);
- {ok, Files} ->
- Add = fun (File) ->
- add1(TarFile,
- filename:join(DirName, File),
- filename:join(NameInArchive, File),
- Options) end,
- foreach_while_ok(Add, Files);
- {error, Reason} ->
- {error, {DirName, Reason}}
+ {ok, []} ->
+ add_verbose(Opts, "a ~ts~n", [NameInArchive]),
+ Header = fileinfo_to_header(NameInArchive, Info, false),
+ add_header(Reader, Header, Opts);
+ {ok, Files} ->
+ add_verbose(Opts, "a ~ts~n", [NameInArchive]),
+ try add_files(Reader, Files, DirName, NameInArchive, Opts) of
+ ok -> ok;
+ {error, _} = Err -> Err
+ catch
+ throw:{error, {_Name, _Reason}} = Err -> Err;
+ throw:{error, Reason} -> {error, {DirName, Reason}}
+ end;
+ {error, Reason} ->
+ {error, {DirName, Reason}}
end.
-
-%% Creates a header for file in a tar file.
-
-create_header(Name, Info) ->
- create_header(Name, Info, []).
-create_header(Name, #file_info {mode=Mode, uid=Uid, gid=Gid,
- size=Size, mtime=Mtime0, type=Type}, Linkname) ->
- Mtime = posix_time(erlang:localtime_to_universaltime(Mtime0)),
- {Prefix,Suffix} = split_filename(Name),
- H0 = [to_string(Suffix, 100),
- to_octal(Mode, 8),
- to_octal(Uid, 8),
- to_octal(Gid, 8),
- to_octal(Size, ?th_size_len),
- to_octal(Mtime, ?th_mtime_len),
- <<" ">>,
- file_type(Type),
- to_string(Linkname, ?th_linkname_len),
- "ustar",0,
- "00",
- zeroes(?th_prefix-?th_version-?th_version_len),
- to_string(Prefix, ?th_prefix_len)],
- H = list_to_binary(H0),
- 512 = byte_size(H), %Assertion.
- ChksumString = to_octal(checksum(H), 6, [0,$\s]),
- <<Before:?th_chksum/binary,_:?th_chksum_len/binary,After/binary>> = H,
- [Before,ChksumString,After].
-
-file_type(regular) -> $0;
-file_type(symlink) -> $2;
-file_type(directory) -> $5.
-
-to_octal(Int, Count) when Count > 1 ->
- to_octal(Int, Count-1, [0]).
-
-to_octal(_, 0, Result) -> Result;
-to_octal(Int, Count, Result) ->
- to_octal(Int div 8, Count-1, [Int rem 8 + $0|Result]).
-
-to_string(Str0, Count) ->
- Str = case file:native_name_encoding() of
- utf8 ->
- unicode:characters_to_binary(Str0);
- latin1 ->
- list_to_binary(Str0)
- end,
- case byte_size(Str) of
- Size when Size < Count ->
- [Str|zeroes(Count-Size)];
- _ -> Str
+
+add_files(_Reader, [], _Dir, _DirInArchive, _Opts) ->
+ ok;
+add_files(Reader, [Name|Rest], Dir, DirInArchive, #add_opts{read_info=Info}=Opts) ->
+ FullName = filename:join(Dir, Name),
+ NameInArchive = filename:join(DirInArchive, Name),
+ Res = case Info(FullName) of
+ {error, Reason} ->
+ {error, {FullName, Reason}};
+ {ok, #file_info{type=directory}=Fi} ->
+ add_directory(Reader, FullName, NameInArchive, Fi, Opts);
+ {ok, #file_info{type=symlink}=Fi} ->
+ add_verbose(Opts, "a ~ts~n", [NameInArchive]),
+ {ok, Linkname} = file:read_link(FullName),
+ Header = fileinfo_to_header(NameInArchive, Fi, Linkname),
+ add_header(Reader, Header, Opts);
+ {ok, #file_info{type=regular}=Fi} ->
+ add_verbose(Opts, "a ~ts~n", [NameInArchive]),
+ Header = fileinfo_to_header(NameInArchive, Fi, false),
+ {ok, Reader2} = add_header(Reader, Header, Opts),
+ FileSize = Header#tar_header.size,
+ {ok, FileSize, Reader3} = do_copy(Reader2, FullName, Opts),
+ Padding = skip_padding(FileSize),
+ Pad = <<0:Padding/unit:8>>,
+ do_write(Reader3, Pad);
+ {ok, #file_info{}=Fi} ->
+ add_verbose(Opts, "a ~ts~n", [NameInArchive]),
+ Header = fileinfo_to_header(NameInArchive, Fi, false),
+ add_header(Reader, Header, Opts)
+ end,
+ case Res of
+ ok -> add_files(Reader, Rest, Dir, DirInArchive, Opts);
+ {ok, ReaderNext} -> add_files(ReaderNext, Rest, Dir, DirInArchive, Opts);
+ {error, _} = Err -> Err
end.
-%% Pads out end of file.
-
-pad_file(File) ->
- {ok,Position} = do_position(File, {cur,0}),
- %% There must be at least two zero records at the end.
- Fill = case ?block_size - (Position rem ?block_size) of
- Fill0 when Fill0 < 2*?record_size ->
- %% We need to another block here to ensure that there
- %% are at least two zero records at the end.
- Fill0 + ?block_size;
- Fill0 ->
- %% Large enough.
- Fill0
- end,
- do_write(File, zeroes(Fill)).
-
-split_filename(Name) when length(Name) =< ?th_name_len ->
- {"", Name};
-split_filename(Name0) ->
- split_filename(lists:reverse(filename:split(Name0)), [], [], 0).
-
-split_filename([Comp|Rest], Prefix, Suffix, Len)
- when Len+length(Comp) < ?th_name_len ->
- split_filename(Rest, Prefix, [Comp|Suffix], Len+length(Comp)+1);
-split_filename([Comp|Rest], Prefix, Suffix, Len) ->
- split_filename(Rest, [Comp|Prefix], Suffix, Len+length(Comp)+1);
-split_filename([], Prefix, Suffix, _) ->
- {filename:join(Prefix),filename:join(Suffix)}.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%
-%%% Retrieving files from a tape archive.
-%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% Options used when reading a tar archive.
-
--record(read_opts,
- {cwd :: string(), % Current working directory.
- keep_old_files = false :: boolean(), % Owerwrite or not.
- files = all, % Set of files to extract
- % (or all).
- output = file :: 'file' | 'memory',
- open_mode = [], % Open mode options.
- verbose = false :: boolean()}). % Verbose on/off.
+format_string(String, Size) when length(String) > Size ->
+ throw({error, {write_string, field_too_long}});
+format_string(String, Size) ->
+ Ascii = to_ascii(String),
+ if byte_size(Ascii) < Size ->
+ [Ascii, 0];
+ true ->
+ Ascii
+ end.
-extract_opts(List) ->
- extract_opts(List, default_options()).
+format_octal(Octal) ->
+ iolist_to_binary(io_lib:fwrite("~.8B", [Octal])).
+
+add_header(#reader{}=Reader, #tar_header{}=Header, Opts) ->
+ {ok, Iodata} = build_header(Header, Opts),
+ do_write(Reader, Iodata).
+
+write_to_block(Block, IoData, Start) when is_list(IoData) ->
+ write_to_block(Block, iolist_to_binary(IoData), Start);
+write_to_block(Block, Bin, Start) when is_binary(Bin) ->
+ Size = byte_size(Bin),
+ <<Head:Start/unit:8, _:Size/unit:8, Rest/binary>> = Block,
+ <<Head:Start/unit:8, Bin/binary, Rest/binary>>.
+
+build_header(#tar_header{}=Header, Opts) ->
+ #tar_header{
+ name=Name,
+ mode=Mode,
+ uid=Uid,
+ gid=Gid,
+ size=Size,
+ typeflag=Type,
+ linkname=Linkname,
+ uname=Uname,
+ gname=Gname,
+ devmajor=Devmaj,
+ devminor=Devmin
+ } = Header,
+ Mtime = Header#tar_header.mtime,
+
+ Block0 = ?ZERO_BLOCK,
+ {Block1, Pax0} = write_string(Block0, ?V7_NAME, ?V7_NAME_LEN, Name, ?PAX_PATH, #{}),
+ Block2 = write_octal(Block1, ?V7_MODE, ?V7_MODE_LEN, Mode),
+ {Block3, Pax1} = write_numeric(Block2, ?V7_UID, ?V7_UID_LEN, Uid, ?PAX_UID, Pax0),
+ {Block4, Pax2} = write_numeric(Block3, ?V7_GID, ?V7_GID_LEN, Gid, ?PAX_GID, Pax1),
+ {Block5, Pax3} = write_numeric(Block4, ?V7_SIZE, ?V7_SIZE_LEN, Size, ?PAX_SIZE, Pax2),
+ {Block6, Pax4} = write_numeric(Block5, ?V7_MTIME, ?V7_MTIME_LEN, Mtime, ?PAX_NONE, Pax3),
+ {Block7, Pax5} = write_string(Block6, ?V7_TYPE, ?V7_TYPE_LEN, <<Type>>, ?PAX_NONE, Pax4),
+ {Block8, Pax6} = write_string(Block7, ?V7_LINKNAME, ?V7_LINKNAME_LEN,
+ Linkname, ?PAX_LINKPATH, Pax5),
+ {Block9, Pax7} = write_string(Block8, ?USTAR_UNAME, ?USTAR_UNAME_LEN,
+ Uname, ?PAX_UNAME, Pax6),
+ {Block10, Pax8} = write_string(Block9, ?USTAR_GNAME, ?USTAR_GNAME_LEN,
+ Gname, ?PAX_GNAME, Pax7),
+ {Block11, Pax9} = write_numeric(Block10, ?USTAR_DEVMAJ, ?USTAR_DEVMAJ_LEN,
+ Devmaj, ?PAX_NONE, Pax8),
+ {Block12, Pax10} = write_numeric(Block11, ?USTAR_DEVMIN, ?USTAR_DEVMIN_LEN,
+ Devmin, ?PAX_NONE, Pax9),
+ {Block13, Pax11} = set_path(Block12, Pax10),
+ PaxEntry = case maps:size(Pax11) of
+ 0 -> [];
+ _ -> build_pax_entry(Header, Pax11, Opts)
+ end,
+ Block14 = set_format(Block13, ?FORMAT_USTAR),
+ Block15 = set_checksum(Block14),
+ {ok, [PaxEntry, Block15]}.
+
+set_path(Block0, Pax) ->
+ %% only use ustar header when name is too long
+ case maps:get(?PAX_PATH, Pax, nil) of
+ nil ->
+ {Block0, Pax};
+ PaxPath ->
+ case split_ustar_path(PaxPath) of
+ {ok, UstarName, UstarPrefix} ->
+ {Block1, _} = write_string(Block0, ?V7_NAME, ?V7_NAME_LEN,
+ UstarName, ?PAX_NONE, #{}),
+ {Block2, _} = write_string(Block1, ?USTAR_PREFIX, ?USTAR_PREFIX_LEN,
+ UstarPrefix, ?PAX_NONE, #{}),
+ {Block2, maps:remove(?PAX_PATH, Pax)};
+ false ->
+ {Block0, Pax}
+ end
+ end.
-table_opts(List) ->
- read_opts(List, default_options()).
+set_format(Block0, Format)
+ when Format =:= ?FORMAT_USTAR; Format =:= ?FORMAT_PAX ->
+ Block1 = write_to_block(Block0, ?MAGIC_USTAR, ?USTAR_MAGIC),
+ write_to_block(Block1, ?VERSION_USTAR, ?USTAR_VERSION);
+set_format(_Block, Format) ->
+ throw({error, {invalid_format, Format}}).
+
+set_checksum(Block) ->
+ Checksum = compute_checksum(Block),
+ write_octal(Block, ?V7_CHKSUM, ?V7_CHKSUM_LEN, Checksum).
+
+build_pax_entry(Header, PaxAttrs, Opts) ->
+ Path = Header#tar_header.name,
+ Filename = filename:basename(Path),
+ Dir = filename:dirname(Path),
+ Path2 = filename:join([Dir, "PaxHeaders.0", Filename]),
+ AsciiPath = to_ascii(Path2),
+ Path3 = if byte_size(AsciiPath) > ?V7_NAME_LEN ->
+ binary_part(AsciiPath, 0, ?V7_NAME_LEN - 1);
+ true ->
+ AsciiPath
+ end,
+ Keys = maps:keys(PaxAttrs),
+ SortedKeys = lists:sort(Keys),
+ PaxFile = build_pax_file(SortedKeys, PaxAttrs),
+ Size = byte_size(PaxFile),
+ Padding = (?BLOCK_SIZE -
+ (byte_size(PaxFile) rem ?BLOCK_SIZE)) rem ?BLOCK_SIZE,
+ Pad = <<0:Padding/unit:8>>,
+ PaxHeader = #tar_header{
+ name=unicode:characters_to_list(Path3),
+ size=Size,
+ mtime=Header#tar_header.mtime,
+ atime=Header#tar_header.atime,
+ ctime=Header#tar_header.ctime,
+ typeflag=?TYPE_X_HEADER
+ },
+ {ok, PaxHeaderData} = build_header(PaxHeader, Opts),
+ [PaxHeaderData, PaxFile, Pad].
+
+build_pax_file(Keys, PaxAttrs) ->
+ build_pax_file(Keys, PaxAttrs, []).
+build_pax_file([], _, Acc) ->
+ unicode:characters_to_binary(Acc);
+build_pax_file([K|Rest], Attrs, Acc) ->
+ V = maps:get(K, Attrs),
+ Size = sizeof(K) + sizeof(V) + 3,
+ Size2 = sizeof(Size) + Size,
+ Key = to_string(K),
+ Value = to_string(V),
+ Record = unicode:characters_to_binary(io_lib:format("~B ~ts=~ts\n", [Size2, Key, Value])),
+ if byte_size(Record) =/= Size2 ->
+ Size3 = byte_size(Record),
+ Record2 = io_lib:format("~B ~ts=~ts\n", [Size3, Key, Value]),
+ build_pax_file(Rest, Attrs, [Acc, Record2]);
+ true ->
+ build_pax_file(Rest, Attrs, [Acc, Record])
+ end.
-default_options() ->
- {ok, Cwd} = file:get_cwd(),
- #read_opts{cwd=Cwd}.
+sizeof(Bin) when is_binary(Bin) ->
+ byte_size(Bin);
+sizeof(List) when is_list(List) ->
+ length(List);
+sizeof(N) when is_integer(N) ->
+ byte_size(integer_to_binary(N));
+sizeof(N) when is_float(N) ->
+ byte_size(float_to_binary(N)).
+
+to_string(Bin) when is_binary(Bin) ->
+ unicode:characters_to_list(Bin);
+to_string(List) when is_list(List) ->
+ List;
+to_string(N) when is_integer(N) ->
+ integer_to_list(N);
+to_string(N) when is_float(N) ->
+ float_to_list(N).
+
+split_ustar_path(Path) ->
+ Len = length(Path),
+ NotAscii = not is_ascii(Path),
+ if Len =< ?V7_NAME_LEN; NotAscii ->
+ false;
+ true ->
+ PathBin = binary:list_to_bin(Path),
+ case binary:split(PathBin, [<<$/>>], [global, trim_all]) of
+ [Part] when byte_size(Part) >= ?V7_NAME_LEN ->
+ false;
+ Parts ->
+ case lists:last(Parts) of
+ Name when byte_size(Name) >= ?V7_NAME_LEN ->
+ false;
+ Name ->
+ Parts2 = lists:sublist(Parts, length(Parts) - 1),
+ join_split_ustar_path(Parts2, {ok, Name, nil})
+ end
+ end
+ end.
-%% Parse options for extract.
+join_split_ustar_path([], Acc) ->
+ Acc;
+join_split_ustar_path([Part|_], {ok, _, nil})
+ when byte_size(Part) > ?USTAR_PREFIX_LEN ->
+ false;
+join_split_ustar_path([Part|_], {ok, _Name, Acc})
+ when (byte_size(Part)+byte_size(Acc)) > ?USTAR_PREFIX_LEN ->
+ false;
+join_split_ustar_path([Part|Rest], {ok, Name, nil}) ->
+ join_split_ustar_path(Rest, {ok, Name, Part});
+join_split_ustar_path([Part|Rest], {ok, Name, Acc}) ->
+ join_split_ustar_path(Rest, {ok, Name, <<Acc/binary,$/,Part/binary>>}).
+
+write_octal(Block, Pos, Size, X) ->
+ Octal = zero_pad(format_octal(X), Size-1),
+ if byte_size(Octal) < Size ->
+ write_to_block(Block, Octal, Pos);
+ true ->
+ throw({error, {write_failed, octal_field_too_long}})
+ end.
-extract_opts([keep_old_files|Rest], Opts) ->
- extract_opts(Rest, Opts#read_opts{keep_old_files=true});
-extract_opts([{cwd, Cwd}|Rest], Opts) ->
- extract_opts(Rest, Opts#read_opts{cwd=Cwd});
-extract_opts([{files, Files}|Rest], Opts) ->
- Set = ordsets:from_list(Files),
- extract_opts(Rest, Opts#read_opts{files=Set});
-extract_opts([memory|Rest], Opts) ->
- extract_opts(Rest, Opts#read_opts{output=memory});
-extract_opts([compressed|Rest], Opts=#read_opts{open_mode=OpenMode}) ->
- extract_opts(Rest, Opts#read_opts{open_mode=[compressed|OpenMode]});
-extract_opts([cooked|Rest], Opts=#read_opts{open_mode=OpenMode}) ->
- extract_opts(Rest, Opts#read_opts{open_mode=[cooked|OpenMode]});
-extract_opts([verbose|Rest], Opts) ->
- extract_opts(Rest, Opts#read_opts{verbose=true});
-extract_opts([Other|Rest], Opts) ->
- extract_opts(Rest, read_opts([Other], Opts));
-extract_opts([], Opts) ->
- Opts.
+write_string(Block, Pos, Size, Str, PaxAttr, Pax0) ->
+ NotAscii = not is_ascii(Str),
+ if PaxAttr =/= ?PAX_NONE andalso (length(Str) > Size orelse NotAscii) ->
+ Pax1 = maps:put(PaxAttr, Str, Pax0),
+ {Block, Pax1};
+ true ->
+ Formatted = format_string(Str, Size),
+ {write_to_block(Block, Formatted, Pos), Pax0}
+ end.
+write_numeric(Block, Pos, Size, X, PaxAttr, Pax0) ->
+ %% attempt octal
+ Octal = zero_pad(format_octal(X), Size-1),
+ if byte_size(Octal) < Size ->
+ {write_to_block(Block, [Octal, 0], Pos), Pax0};
+ PaxAttr =/= ?PAX_NONE ->
+ Pax1 = maps:put(PaxAttr, X, Pax0),
+ {Block, Pax1};
+ true ->
+ throw({error, {write_failed, numeric_field_too_long}})
+ end.
-%% Common options for all read operations.
+zero_pad(Str, Size) when byte_size(Str) >= Size ->
+ Str;
+zero_pad(Str, Size) ->
+ Padding = Size - byte_size(Str),
+ Pad = binary:copy(<<$0>>, Padding),
+ <<Pad/binary, Str/binary>>.
-read_opts([compressed|Rest], Opts=#read_opts{open_mode=OpenMode}) ->
- read_opts(Rest, Opts#read_opts{open_mode=[compressed|OpenMode]});
-read_opts([cooked|Rest], Opts=#read_opts{open_mode=OpenMode}) ->
- read_opts(Rest, Opts#read_opts{open_mode=[cooked|OpenMode]});
-read_opts([verbose|Rest], Opts) ->
- read_opts(Rest, Opts#read_opts{verbose=true});
-read_opts([_|Rest], Opts) ->
- read_opts(Rest, Opts);
-read_opts([], Opts) ->
- Opts.
-foldl_read({AccessMode,TD={tar_descriptor,_UsrHandle,_AccessFun}}, Fun, Accu, Opts) ->
- case AccessMode of
- read ->
- foldl_read0(TD, Fun, Accu, Opts);
- _ ->
- {error,{read_mode_expected,AccessMode}}
- end;
-foldl_read(TarName, Fun, Accu, Opts) ->
- case open(TarName, [read|Opts#read_opts.open_mode]) of
- {ok, {read, File}} ->
- Result = foldl_read0(File, Fun, Accu, Opts),
- ok = do_close(File),
- Result;
- Error ->
- Error
+%%%================================================================
+%% Functions for creating or modifying tar archives
+
+read_block(Reader) ->
+ case do_read(Reader, ?BLOCK_SIZE) of
+ eof ->
+ throw({error, eof});
+ %% Two zero blocks mark the end of the archive
+ {ok, ?ZERO_BLOCK, Reader1} ->
+ case do_read(Reader1, ?BLOCK_SIZE) of
+ eof ->
+ % This is technically a malformed end-of-archive marker,
+ % as two ZERO_BLOCKs are expected as the marker,
+ % but if we've already made it this far, we should just ignore it
+ eof;
+ {ok, ?ZERO_BLOCK, _Reader2} ->
+ eof;
+ {ok, _Block, _Reader2} ->
+ throw({error, invalid_end_of_archive});
+ {error,_} = Err ->
+ throw(Err)
+ end;
+ {ok, Block, Reader1} when is_binary(Block) ->
+ {ok, Block, Reader1};
+ {error, _} = Err ->
+ throw(Err)
end.
-foldl_read0(File, Fun, Accu, Opts) ->
- case catch foldl_read1(Fun, Accu, File, Opts) of
- {'EXIT', Reason} ->
- exit(Reason);
- {error, {Reason, Format, Args}} ->
- read_verbose(Opts, Format, Args),
- {error, Reason};
- {error, Reason} ->
- {error, Reason};
- Ok ->
- Ok
+get_header(#reader{}=Reader) ->
+ case read_block(Reader) of
+ eof ->
+ eof;
+ {ok, Block, Reader1} ->
+ convert_header(Block, Reader1)
end.
-foldl_read1(Fun, Accu0, File, Opts) ->
- case get_header(File) of
- eof ->
- Fun(eof, File, Opts, Accu0);
- Header ->
- {ok, NewAccu} = Fun(Header, File, Opts, Accu0),
- foldl_read1(Fun, NewAccu, File, Opts)
+%% Converts the tar header to a record.
+to_v7(Bin) when is_binary(Bin), byte_size(Bin) =:= ?BLOCK_SIZE ->
+ #header_v7{
+ name=binary_part(Bin, ?V7_NAME, ?V7_NAME_LEN),
+ mode=binary_part(Bin, ?V7_MODE, ?V7_MODE_LEN),
+ uid=binary_part(Bin, ?V7_UID, ?V7_UID_LEN),
+ gid=binary_part(Bin, ?V7_GID, ?V7_GID_LEN),
+ size=binary_part(Bin, ?V7_SIZE, ?V7_SIZE_LEN),
+ mtime=binary_part(Bin, ?V7_MTIME, ?V7_MTIME_LEN),
+ checksum=binary_part(Bin, ?V7_CHKSUM, ?V7_CHKSUM_LEN),
+ typeflag=binary:at(Bin, ?V7_TYPE),
+ linkname=binary_part(Bin, ?V7_LINKNAME, ?V7_LINKNAME_LEN)
+ };
+to_v7(_) ->
+ {error, header_block_too_small}.
+
+to_gnu(#header_v7{}=V7, Bin)
+ when is_binary(Bin), byte_size(Bin) =:= ?BLOCK_SIZE ->
+ #header_gnu{
+ header_v7=V7,
+ magic=binary_part(Bin, ?GNU_MAGIC, ?GNU_MAGIC_LEN),
+ version=binary_part(Bin, ?GNU_VERSION, ?GNU_VERSION_LEN),
+ uname=binary_part(Bin, 265, 32),
+ gname=binary_part(Bin, 297, 32),
+ devmajor=binary_part(Bin, 329, 8),
+ devminor=binary_part(Bin, 337, 8),
+ atime=binary_part(Bin, 345, 12),
+ ctime=binary_part(Bin, 357, 12),
+ sparse=to_sparse_array(binary_part(Bin, 386, 24*4+1)),
+ real_size=binary_part(Bin, 483, 12)
+ }.
+
+to_star(#header_v7{}=V7, Bin)
+ when is_binary(Bin), byte_size(Bin) =:= ?BLOCK_SIZE ->
+ #header_star{
+ header_v7=V7,
+ magic=binary_part(Bin, ?USTAR_MAGIC, ?USTAR_MAGIC_LEN),
+ version=binary_part(Bin, ?USTAR_VERSION, ?USTAR_VERSION_LEN),
+ uname=binary_part(Bin, ?USTAR_UNAME, ?USTAR_UNAME_LEN),
+ gname=binary_part(Bin, ?USTAR_GNAME, ?USTAR_GNAME_LEN),
+ devmajor=binary_part(Bin, ?USTAR_DEVMAJ, ?USTAR_DEVMAJ_LEN),
+ devminor=binary_part(Bin, ?USTAR_DEVMIN, ?USTAR_DEVMIN_LEN),
+ prefix=binary_part(Bin, 345, 131),
+ atime=binary_part(Bin, 476, 12),
+ ctime=binary_part(Bin, 488, 12),
+ trailer=binary_part(Bin, ?STAR_TRAILER, ?STAR_TRAILER_LEN)
+ }.
+
+to_ustar(#header_v7{}=V7, Bin)
+ when is_binary(Bin), byte_size(Bin) =:= ?BLOCK_SIZE ->
+ #header_ustar{
+ header_v7=V7,
+ magic=binary_part(Bin, ?USTAR_MAGIC, ?USTAR_MAGIC_LEN),
+ version=binary_part(Bin, ?USTAR_VERSION, ?USTAR_VERSION_LEN),
+ uname=binary_part(Bin, ?USTAR_UNAME, ?USTAR_UNAME_LEN),
+ gname=binary_part(Bin, ?USTAR_GNAME, ?USTAR_GNAME_LEN),
+ devmajor=binary_part(Bin, ?USTAR_DEVMAJ, ?USTAR_DEVMAJ_LEN),
+ devminor=binary_part(Bin, ?USTAR_DEVMIN, ?USTAR_DEVMIN_LEN),
+ prefix=binary_part(Bin, 345, 155)
+ }.
+
+to_sparse_array(Bin) when is_binary(Bin) ->
+ MaxEntries = byte_size(Bin) div 24,
+ IsExtended = 1 =:= binary:at(Bin, 24*MaxEntries),
+ Entries = parse_sparse_entries(Bin, MaxEntries-1, []),
+ #sparse_array{
+ entries=Entries,
+ max_entries=MaxEntries,
+ is_extended=IsExtended
+ }.
+
+parse_sparse_entries(<<>>, _, Acc) ->
+ Acc;
+parse_sparse_entries(_, -1, Acc) ->
+ Acc;
+parse_sparse_entries(Bin, N, Acc) ->
+ case to_sparse_entry(binary_part(Bin, N*24, 24)) of
+ nil ->
+ parse_sparse_entries(Bin, N-1, Acc);
+ Entry = #sparse_entry{} ->
+ parse_sparse_entries(Bin, N-1, [Entry|Acc])
end.
-table1(eof, _, _, Result) ->
- {ok, lists:reverse(Result)};
-table1(Header = #tar_header{}, File, #read_opts{verbose=true}, Result) ->
- #tar_header{name=Name, size=Size, mtime=Mtime, typeflag=Type,
- mode=Mode, uid=Uid, gid=Gid} = Header,
- skip(File, Size),
- {ok, [{Name, Type, Size, posix_to_erlang_time(Mtime), Mode, Uid, Gid}|Result]};
-table1(#tar_header{name=Name, size=Size}, File, _, Result) ->
- skip(File, Size),
- {ok, [Name|Result]}.
-
-extract1(eof, _, _, Acc) ->
- if
- is_list(Acc) ->
- {ok, lists:reverse(Acc)};
- true ->
- Acc
- end;
-extract1(Header, File, Opts, Acc) ->
- Name = Header#tar_header.name,
- case check_extract(Name, Opts) of
- true ->
- {ok, Bin} = get_element(File, Header),
- case write_extracted_element(Header, Bin, Opts) of
- ok ->
- {ok, Acc};
- {ok, NameBin} when is_list(Acc) ->
- {ok, [NameBin | Acc]};
- {ok, NameBin} when Acc =:= ok ->
- {ok, [NameBin]}
- end;
- false ->
- ok = skip(File, Header#tar_header.size),
- {ok, Acc}
+-define(EMPTY_ENTRY, <<0,0,0,0,0,0,0,0,0,0,0,0>>).
+to_sparse_entry(Bin) when is_binary(Bin), byte_size(Bin) =:= 24 ->
+ OffsetBin = binary_part(Bin, 0, 12),
+ NumBytesBin = binary_part(Bin, 12, 12),
+ case {OffsetBin, NumBytesBin} of
+ {?EMPTY_ENTRY, ?EMPTY_ENTRY} ->
+ nil;
+ _ ->
+ #sparse_entry{
+ offset=parse_numeric(OffsetBin),
+ num_bytes=parse_numeric(NumBytesBin)}
end.
-%% Checks if the file Name should be extracted.
+-spec get_format(binary()) -> {ok, pos_integer(), header_v7()}
+ | ?FORMAT_UNKNOWN
+ | {error, term()}.
+get_format(Bin) when is_binary(Bin), byte_size(Bin) =:= ?BLOCK_SIZE ->
+ do_get_format(to_v7(Bin), Bin).
+
+do_get_format({error, _} = Err, _Bin) ->
+ Err;
+do_get_format(#header_v7{}=V7, Bin)
+ when is_binary(Bin), byte_size(Bin) =:= ?BLOCK_SIZE ->
+ Checksum = parse_octal(V7#header_v7.checksum),
+ Chk1 = compute_checksum(Bin),
+ Chk2 = compute_signed_checksum(Bin),
+ if Checksum =/= Chk1 andalso Checksum =/= Chk2 ->
+ ?FORMAT_UNKNOWN;
+ true ->
+ %% guess magic
+ Ustar = to_ustar(V7, Bin),
+ Star = to_star(V7, Bin),
+ Magic = Ustar#header_ustar.magic,
+ Version = Ustar#header_ustar.version,
+ Trailer = Star#header_star.trailer,
+ Format = if
+ Magic =:= ?MAGIC_USTAR, Trailer =:= ?TRAILER_STAR ->
+ ?FORMAT_STAR;
+ Magic =:= ?MAGIC_USTAR ->
+ ?FORMAT_USTAR;
+ Magic =:= ?MAGIC_GNU, Version =:= ?VERSION_GNU ->
+ ?FORMAT_GNU;
+ true ->
+ ?FORMAT_V7
+ end,
+ {ok, Format, V7}
+ end.
-check_extract(_, #read_opts{files=all}) ->
+unpack_format(Format, #header_v7{}=V7, Bin, Reader)
+ when is_binary(Bin), byte_size(Bin) =:= ?BLOCK_SIZE ->
+ Mtime = parse_numeric(V7#header_v7.mtime),
+ Header0 = #tar_header{
+ name=parse_string(V7#header_v7.name),
+ mode=parse_numeric(V7#header_v7.mode),
+ uid=parse_numeric(V7#header_v7.uid),
+ gid=parse_numeric(V7#header_v7.gid),
+ size=parse_numeric(V7#header_v7.size),
+ mtime=Mtime,
+ atime=Mtime,
+ ctime=Mtime,
+ typeflag=V7#header_v7.typeflag,
+ linkname=parse_string(V7#header_v7.linkname)
+ },
+ Typeflag = Header0#tar_header.typeflag,
+ Header1 = if Format > ?FORMAT_V7 ->
+ unpack_modern(Format, V7, Bin, Header0);
+ true ->
+ Name = Header0#tar_header.name,
+ Header0#tar_header{name=safe_join_path("", Name)}
+ end,
+ HeaderOnly = is_header_only_type(Typeflag),
+ Header2 = if HeaderOnly ->
+ Header1#tar_header{size=0};
+ true ->
+ Header1
+ end,
+ if Typeflag =:= ?TYPE_GNU_SPARSE ->
+ Gnu = to_gnu(V7, Bin),
+ RealSize = parse_numeric(Gnu#header_gnu.real_size),
+ {Sparsemap, Reader2} = parse_sparse_map(Gnu, Reader),
+ Header3 = Header2#tar_header{size=RealSize},
+ {Header3, new_sparse_file_reader(Reader2, Sparsemap, RealSize)};
+ true ->
+ FileReader = #reg_file_reader{
+ handle=Reader,
+ num_bytes=Header2#tar_header.size,
+ size=Header2#tar_header.size,
+ pos = 0
+ },
+ {Header2, FileReader}
+ end.
+
+unpack_modern(Format, #header_v7{}=V7, Bin, #tar_header{}=Header0)
+ when is_binary(Bin) ->
+ Typeflag = Header0#tar_header.typeflag,
+ Ustar = to_ustar(V7, Bin),
+ H0 = Header0#tar_header{
+ uname=parse_string(Ustar#header_ustar.uname),
+ gname=parse_string(Ustar#header_ustar.gname)},
+ H1 = if Typeflag =:= ?TYPE_CHAR
+ orelse Typeflag =:= ?TYPE_BLOCK ->
+ Ma = parse_numeric(Ustar#header_ustar.devmajor),
+ Mi = parse_numeric(Ustar#header_ustar.devminor),
+ H0#tar_header{
+ devmajor=Ma,
+ devminor=Mi
+ };
+ true ->
+ H0
+ end,
+ {Prefix, H2} = case Format of
+ ?FORMAT_USTAR ->
+ {parse_string(Ustar#header_ustar.prefix), H1};
+ ?FORMAT_STAR ->
+ Star = to_star(V7, Bin),
+ Prefix0 = parse_string(Star#header_star.prefix),
+ Atime0 = Star#header_star.atime,
+ Atime = parse_numeric(Atime0),
+ Ctime0 = Star#header_star.ctime,
+ Ctime = parse_numeric(Ctime0),
+ {Prefix0, H1#tar_header{
+ atime=Atime,
+ ctime=Ctime
+ }};
+ _ ->
+ {"", H1}
+ end,
+ Name = H2#tar_header.name,
+ H2#tar_header{name=safe_join_path(Prefix, Name)}.
+
+
+safe_join_path([], Name) ->
+ filename:join([Name]);
+safe_join_path(Prefix, []) ->
+ filename:join([Prefix]);
+safe_join_path(Prefix, Name) ->
+ filename:join(Prefix, Name).
+
+new_sparse_file_reader(Reader, Sparsemap, RealSize) ->
+ true = validate_sparse_entries(Sparsemap, RealSize),
+ #sparse_file_reader{
+ handle = Reader,
+ num_bytes = RealSize,
+ pos = 0,
+ size = RealSize,
+ sparse_map = Sparsemap}.
+
+validate_sparse_entries(Entries, RealSize) ->
+ validate_sparse_entries(Entries, RealSize, 0, 0).
+validate_sparse_entries([], _RealSize, _I, _LastOffset) ->
true;
-check_extract(Name, #read_opts{files=Files}) ->
- ordsets:is_element(Name, Files).
+validate_sparse_entries([#sparse_entry{}=Entry|Rest], RealSize, I, LastOffset) ->
+ Offset = Entry#sparse_entry.offset,
+ NumBytes = Entry#sparse_entry.num_bytes,
+ if
+ Offset > ?MAX_INT64-NumBytes ->
+ throw({error, {invalid_sparse_map_entry, offset_too_large}});
+ Offset+NumBytes > RealSize ->
+ throw({error, {invalid_sparse_map_entry, offset_too_large}});
+ I > 0 andalso LastOffset > Offset ->
+ throw({error, {invalid_sparse_map_entry, overlapping_offsets}});
+ true ->
+ ok
+ end,
+ validate_sparse_entries(Rest, RealSize, I+1, Offset+NumBytes).
+
+
+-spec parse_sparse_map(header_gnu(), reader_type()) ->
+ {[sparse_entry()], reader_type()}.
+parse_sparse_map(#header_gnu{sparse=Sparse}, Reader)
+ when Sparse#sparse_array.is_extended ->
+ parse_sparse_map(Sparse, Reader, []);
+parse_sparse_map(#header_gnu{sparse=Sparse}, Reader) ->
+ {Sparse#sparse_array.entries, Reader}.
+parse_sparse_map(#sparse_array{is_extended=true,entries=Entries}, Reader, Acc) ->
+ case read_block(Reader) of
+ eof ->
+ throw({error, eof});
+ {ok, Block, Reader2} ->
+ Sparse2 = to_sparse_array(Block),
+ parse_sparse_map(Sparse2, Reader2, Entries++Acc)
+ end;
+parse_sparse_map(#sparse_array{entries=Entries}, Reader, Acc) ->
+ Sorted = lists:sort(fun (#sparse_entry{offset=A},#sparse_entry{offset=B}) ->
+ A =< B
+ end, Entries++Acc),
+ {Sorted, Reader}.
+
+%% Defined by taking the sum of the unsigned byte values of the
+%% entire header record, treating the checksum bytes to as ASCII spaces
+compute_checksum(<<H1:?V7_CHKSUM/binary,
+ H2:?V7_CHKSUM_LEN/binary,
+ Rest:(?BLOCK_SIZE - ?V7_CHKSUM - ?V7_CHKSUM_LEN)/binary,
+ _/binary>>) ->
+ C0 = checksum(H1) + (byte_size(H2) * $\s),
+ C1 = checksum(Rest),
+ C0 + C1.
+
+compute_signed_checksum(<<H1:?V7_CHKSUM/binary,
+ H2:?V7_CHKSUM_LEN/binary,
+ Rest:(?BLOCK_SIZE - ?V7_CHKSUM - ?V7_CHKSUM_LEN)/binary,
+ _/binary>>) ->
+ C0 = signed_checksum(H1) + (byte_size(H2) * $\s),
+ C1 = signed_checksum(Rest),
+ C0 + C1.
-get_header(File) ->
- case do_read(File, ?record_size) of
- eof ->
- throw({error,eof});
- {ok, Bin} when is_binary(Bin) ->
- convert_header(Bin);
- {ok, List} ->
- convert_header(list_to_binary(List));
- {error, Reason} ->
- throw({error, Reason})
- end.
+%% Returns the checksum of a binary.
+checksum(Bin) -> checksum(Bin, 0).
+checksum(<<A/unsigned,Rest/binary>>, Sum) ->
+ checksum(Rest, Sum+A);
+checksum(<<>>, Sum) -> Sum.
-%% Converts the tar header to a record.
+signed_checksum(Bin) -> signed_checksum(Bin, 0).
+signed_checksum(<<A/signed,Rest/binary>>, Sum) ->
+ signed_checksum(Rest, Sum+A);
+signed_checksum(<<>>, Sum) -> Sum.
+
+-spec parse_numeric(binary()) -> non_neg_integer().
+parse_numeric(<<>>) ->
+ 0;
+parse_numeric(<<First, _/binary>> = Bin) ->
+ %% check for base-256 format first
+ %% if the bit is set, then all following bits constitute a two's
+ %% complement encoded number in big-endian byte order
+ if
+ First band 16#80 =/= 0 ->
+ %% Handling negative numbers relies on the following identity:
+ %% -a-1 == ^a
+ %% If the number is negative, we use an inversion mask to invert
+ %% the data bytes and treat the value as an unsigned number
+ Inv = if First band 16#40 =/= 0 -> 16#00; true -> 16#FF end,
+ Bytes = binary:bin_to_list(Bin),
+ Reducer = fun (C, {I, X}) ->
+ C1 = C bxor Inv,
+ C2 = if I =:= 0 -> C1 band 16#7F; true -> C1 end,
+ if (X bsr 56) > 0 ->
+ throw({error,integer_overflow});
+ true ->
+ {I+1, (X bsl 8) bor C2}
+ end
+ end,
+ {_, N} = lists:foldl(Reducer, {0,0}, Bytes),
+ if (N bsr 63) > 0 ->
+ throw({error, integer_overflow});
+ true ->
+ if Inv =:= 16#FF ->
+ -1 bxor N;
+ true ->
+ N
+ end
+ end;
+ true ->
+ %% normal case is an octal number
+ parse_octal(Bin)
+ end.
-convert_header(Bin) when byte_size(Bin) =:= ?record_size ->
- case verify_checksum(Bin) of
- ok ->
- Hd = #tar_header{name=get_name(Bin),
- mode=from_octal(Bin, ?th_mode, ?th_mode_len),
- uid=from_octal(Bin, ?th_uid, ?th_uid_len),
- gid=from_octal(Bin, ?th_gid, ?th_gid_len),
- size=from_octal(Bin, ?th_size, ?th_size_len),
- mtime=from_octal(Bin, ?th_mtime, ?th_mtime_len),
- linkname=from_string(Bin,
- ?th_linkname, ?th_linkname_len),
- typeflag=typeflag(Bin)},
- convert_header1(Hd);
- eof ->
- eof
+parse_octal(Bin) when is_binary(Bin) ->
+ %% skip leading/trailing zero bytes and spaces
+ do_parse_octal(Bin, <<>>).
+do_parse_octal(<<>>, <<>>) ->
+ 0;
+do_parse_octal(<<>>, Acc) ->
+ case io_lib:fread("~8u", binary:bin_to_list(Acc)) of
+ {error, _} -> throw({error, invalid_tar_checksum});
+ {ok, [Octal], []} -> Octal;
+ {ok, _, _} -> throw({error, invalid_tar_checksum})
+ end;
+do_parse_octal(<<$\s,Rest/binary>>, Acc) ->
+ do_parse_octal(Rest, Acc);
+do_parse_octal(<<0, Rest/binary>>, Acc) ->
+ do_parse_octal(Rest, Acc);
+do_parse_octal(<<C, Rest/binary>>, Acc) ->
+ do_parse_octal(Rest, <<Acc/binary, C>>).
+
+parse_string(Bin) when is_binary(Bin) ->
+ do_parse_string(Bin, <<>>).
+do_parse_string(<<>>, Acc) ->
+ case unicode:characters_to_list(Acc) of
+ Str when is_list(Str) ->
+ Str;
+ {incomplete, _Str, _Rest} ->
+ binary:bin_to_list(Acc);
+ {error, _Str, _Rest} ->
+ throw({error, {bad_header, invalid_string}})
end;
-convert_header(Bin) when byte_size(Bin) =:= 0 ->
+do_parse_string(<<0, _/binary>>, Acc) ->
+ do_parse_string(<<>>, Acc);
+do_parse_string(<<C, Rest/binary>>, Acc) ->
+ do_parse_string(Rest, <<Acc/binary, C>>).
+
+convert_header(Bin, #reader{pos=Pos}=Reader)
+ when byte_size(Bin) =:= ?BLOCK_SIZE, (Pos rem ?BLOCK_SIZE) =:= 0 ->
+ case get_format(Bin) of
+ ?FORMAT_UNKNOWN ->
+ throw({error, bad_header});
+ {ok, Format, V7} ->
+ unpack_format(Format, V7, Bin, Reader);
+ {error, Reason} ->
+ throw({error, {bad_header, Reason}})
+ end;
+convert_header(Bin, #reader{pos=Pos}) when byte_size(Bin) =:= ?BLOCK_SIZE ->
+ throw({error, misaligned_read, Pos});
+convert_header(Bin, _Reader) when byte_size(Bin) =:= 0 ->
eof;
-convert_header(_Bin) ->
+convert_header(_Bin, _Reader) ->
throw({error, eof}).
-%% Basic sanity. Better set the element size to zero here if the type
-%% always is of zero length.
-
-convert_header1(H) when H#tar_header.typeflag =:= symlink, H#tar_header.size =/= 0 ->
- convert_header1(H#tar_header{size=0});
-convert_header1(H) when H#tar_header.typeflag =:= directory, H#tar_header.size =/= 0 ->
- convert_header1(H#tar_header{size=0});
-convert_header1(Header) ->
- Header.
-
-typeflag(Bin) ->
- [T] = binary_to_list(Bin, ?th_typeflag+1, ?th_typeflag+1),
- case T of
- 0 -> regular;
- $0 -> regular;
- $1 -> link;
- $2 -> symlink;
- $3 -> char;
- $4 -> block;
- $5 -> directory;
- $6 -> fifo;
- $7 -> regular;
- _ -> unknown
+%% Creates a partially-populated header record based
+%% on the provided file_info record. If the file is
+%% a symlink, then `link` is used as the link target.
+%% If the file is a directory, a slash is appended to the name.
+fileinfo_to_header(Name, #file_info{}=Fi, Link) when is_list(Name) ->
+ BaseHeader = #tar_header{name=Name,
+ mtime=Fi#file_info.mtime,
+ atime=Fi#file_info.atime,
+ ctime=Fi#file_info.ctime,
+ mode=Fi#file_info.mode,
+ uid=Fi#file_info.uid,
+ gid=Fi#file_info.gid,
+ typeflag=?TYPE_REGULAR},
+ do_fileinfo_to_header(BaseHeader, Fi, Link).
+
+do_fileinfo_to_header(Header, #file_info{size=Size,type=regular}, _Link) ->
+ Header#tar_header{size=Size,typeflag=?TYPE_REGULAR};
+do_fileinfo_to_header(#tar_header{name=Name}=Header,
+ #file_info{type=directory}, _Link) ->
+ Header#tar_header{name=Name++"/",typeflag=?TYPE_DIR};
+do_fileinfo_to_header(Header, #file_info{type=symlink}, Link) ->
+ Header#tar_header{typeflag=?TYPE_SYMLINK,linkname=Link};
+do_fileinfo_to_header(Header, #file_info{type=device,mode=Mode}=Fi, _Link)
+ when (Mode band ?S_IFMT) =:= ?S_IFCHR ->
+ Header#tar_header{typeflag=?TYPE_CHAR,
+ devmajor=Fi#file_info.major_device,
+ devminor=Fi#file_info.minor_device};
+do_fileinfo_to_header(Header, #file_info{type=device,mode=Mode}=Fi, _Link)
+ when (Mode band ?S_IFMT) =:= ?S_IFBLK ->
+ Header#tar_header{typeflag=?TYPE_BLOCK,
+ devmajor=Fi#file_info.major_device,
+ devminor=Fi#file_info.minor_device};
+do_fileinfo_to_header(Header, #file_info{type=other,mode=Mode}, _Link)
+ when (Mode band ?S_IFMT) =:= ?S_FIFO ->
+ Header#tar_header{typeflag=?TYPE_FIFO};
+do_fileinfo_to_header(Header, Fi, _Link) ->
+ {error, {invalid_file_type, Header#tar_header.name, Fi}}.
+
+is_ascii(Str) when is_list(Str) ->
+ not lists:any(fun (Char) -> Char >= 16#80 end, Str);
+is_ascii(Bin) when is_binary(Bin) ->
+ is_ascii1(Bin).
+
+is_ascii1(<<>>) ->
+ true;
+is_ascii1(<<C,_Rest/binary>>) when C >= 16#80 ->
+ false;
+is_ascii1(<<_, Rest/binary>>) ->
+ is_ascii1(Rest).
+
+to_ascii(Str) when is_list(Str) ->
+ case is_ascii(Str) of
+ true ->
+ unicode:characters_to_binary(Str);
+ false ->
+ Chars = lists:filter(fun (Char) -> Char < 16#80 end, Str),
+ unicode:characters_to_binary(Chars)
+ end;
+to_ascii(Bin) when is_binary(Bin) ->
+ to_ascii(Bin, <<>>).
+to_ascii(<<>>, Acc) ->
+ Acc;
+to_ascii(<<C, Rest/binary>>, Acc) when C < 16#80 ->
+ to_ascii(Rest, <<Acc/binary,C>>);
+to_ascii(<<_, Rest/binary>>, Acc) ->
+ to_ascii(Rest, Acc).
+
+is_header_only_type(?TYPE_SYMLINK) -> true;
+is_header_only_type(?TYPE_LINK) -> true;
+is_header_only_type(?TYPE_DIR) -> true;
+is_header_only_type(_) -> false.
+
+foldl_read(#reader{access=read}=Reader, Fun, Accu, #read_opts{}=Opts)
+ when is_function(Fun,4) ->
+ case foldl_read0(Reader, Fun, Accu, Opts) of
+ {ok, Result, _Reader2} ->
+ Result;
+ {error, _} = Err ->
+ Err
+ end;
+foldl_read(#reader{access=Access}, _Fun, _Accu, _Opts) ->
+ {error, {read_mode_expected, Access}};
+foldl_read(TarName, Fun, Accu, #read_opts{}=Opts)
+ when is_function(Fun,4) ->
+ try open(TarName, [read|Opts#read_opts.open_mode]) of
+ {ok, #reader{access=read}=Reader} ->
+ try
+ foldl_read(Reader, Fun, Accu, Opts)
+ after
+ _ = close(Reader)
+ end;
+ {error, _} = Err ->
+ Err
+ catch
+ throw:Err ->
+ Err
end.
-%% Get the name of the file from the prefix and name fields of the
-%% tar header.
-
-get_name(Bin0) ->
- List0 = get_name_raw(Bin0),
- case file:native_name_encoding() of
- utf8 ->
- Bin = list_to_binary(List0),
- case unicode:characters_to_list(Bin) of
- {error,_,_} ->
- List0;
- List when is_list(List) ->
- List
- end;
- latin1 ->
- List0
+foldl_read0(Reader, Fun, Accu, Opts) ->
+ try foldl_read1(Fun, Accu, Reader, Opts, #{}) of
+ {ok,_,_} = Ok ->
+ Ok
+ catch
+ throw:{error, {Reason, Format, Args}} ->
+ read_verbose(Opts, Format, Args),
+ {error, Reason};
+ throw:Err ->
+ Err
end.
-get_name_raw(Bin) ->
- Name = from_string(Bin, ?th_name, ?th_name_len),
- case binary_to_list(Bin, ?th_prefix+1, ?th_prefix+1) of
- [0] ->
- Name;
- [_] ->
- Prefix = binary_to_list(Bin, ?th_prefix+1, byte_size(Bin)),
- lists:reverse(remove_nulls(Prefix), [$/|Name])
+foldl_read1(Fun, Accu0, Reader0, Opts, ExtraHeaders) ->
+ {ok, Reader1} = skip_unread(Reader0),
+ case get_header(Reader1) of
+ eof ->
+ Fun(eof, Reader1, Opts, Accu0);
+ {Header, Reader2} ->
+ case Header#tar_header.typeflag of
+ ?TYPE_X_HEADER ->
+ {ExtraHeaders2, Reader3} = parse_pax(Reader2),
+ ExtraHeaders3 = maps:merge(ExtraHeaders, ExtraHeaders2),
+ foldl_read1(Fun, Accu0, Reader3, Opts, ExtraHeaders3);
+ ?TYPE_GNU_LONGNAME ->
+ {RealName, Reader3} = get_real_name(Reader2),
+ ExtraHeaders2 = maps:put(?PAX_PATH,
+ parse_string(RealName), ExtraHeaders),
+ foldl_read1(Fun, Accu0, Reader3, Opts, ExtraHeaders2);
+ ?TYPE_GNU_LONGLINK ->
+ {RealName, Reader3} = get_real_name(Reader2),
+ ExtraHeaders2 = maps:put(?PAX_LINKPATH,
+ parse_string(RealName), ExtraHeaders),
+ foldl_read1(Fun, Accu0, Reader3, Opts, ExtraHeaders2);
+ _ ->
+ Header1 = merge_pax(Header, ExtraHeaders),
+ {ok, NewAccu, Reader3} = Fun(Header1, Reader2, Opts, Accu0),
+ foldl_read1(Fun, NewAccu, Reader3, Opts, #{})
+ end
end.
-from_string(Bin, Pos, Len) ->
- lists:reverse(remove_nulls(binary_to_list(Bin, Pos+1, Pos+Len))).
-
-%% Returns all characters up to (but not including) the first null
-%% character, in REVERSE order.
-
-remove_nulls(List) ->
- remove_nulls(List, []).
-
-remove_nulls([0|_], Result) ->
- remove_nulls([], Result);
-remove_nulls([C|Rest], Result) ->
- remove_nulls(Rest, [C|Result]);
-remove_nulls([], Result) ->
- Result.
-
-from_octal(Bin, Pos, Len) ->
- from_octal(binary_to_list(Bin, Pos+1, Pos+Len)).
-
-from_octal([$\s|Rest]) ->
- from_octal(Rest);
-from_octal([Digit|Rest]) when $0 =< Digit, Digit =< $7 ->
- from_octal(Rest, Digit-$0);
-from_octal(Bin) when is_binary(Bin) ->
- from_octal(binary_to_list(Bin));
-from_octal(Other) ->
- throw({error, {bad_header, "Bad octal number: ~p", [Other]}}).
-
-from_octal([Digit|Rest], Result) when $0 =< Digit, Digit =< $7 ->
- from_octal(Rest, Result*8+Digit-$0);
-from_octal([$\s|_], Result) ->
- Result;
-from_octal([0|_], Result) ->
- Result;
-from_octal(Other, _) ->
- throw({error, {bad_header, "Bad contents in octal field: ~p", [Other]}}).
-
-%% Retrieves the next element from the archive.
-%% Returns {ok, Bin} | eof | {error, Reason}
-
-get_element(File, #tar_header{size = 0}) ->
- skip_to_next(File),
- {ok,<<>>};
-get_element(File, #tar_header{size = Size}) ->
- case do_read(File, Size) of
- {ok,Bin}=Res when byte_size(Bin) =:= Size ->
- skip_to_next(File),
- Res;
- {ok,List} when length(List) =:= Size ->
- skip_to_next(File),
- {ok,list_to_binary(List)};
- {ok,_} -> throw({error,eof});
- {error, Reason} -> throw({error, Reason});
- eof -> throw({error,eof})
+%% Applies all known PAX attributes to the current tar header
+-spec merge_pax(tar_header(), #{binary() => binary()}) -> tar_header().
+merge_pax(Header, ExtraHeaders) when is_map(ExtraHeaders) ->
+ do_merge_pax(Header, maps:to_list(ExtraHeaders)).
+
+do_merge_pax(Header, []) ->
+ Header;
+do_merge_pax(Header, [{?PAX_PATH, Path}|Rest]) ->
+ do_merge_pax(Header#tar_header{name=unicode:characters_to_list(Path)}, Rest);
+do_merge_pax(Header, [{?PAX_LINKPATH, LinkPath}|Rest]) ->
+ do_merge_pax(Header#tar_header{linkname=unicode:characters_to_list(LinkPath)}, Rest);
+do_merge_pax(Header, [{?PAX_GNAME, Gname}|Rest]) ->
+ do_merge_pax(Header#tar_header{gname=unicode:characters_to_list(Gname)}, Rest);
+do_merge_pax(Header, [{?PAX_UNAME, Uname}|Rest]) ->
+ do_merge_pax(Header#tar_header{uname=unicode:characters_to_list(Uname)}, Rest);
+do_merge_pax(Header, [{?PAX_UID, Uid}|Rest]) ->
+ Uid2 = binary_to_integer(Uid),
+ do_merge_pax(Header#tar_header{uid=Uid2}, Rest);
+do_merge_pax(Header, [{?PAX_GID, Gid}|Rest]) ->
+ Gid2 = binary_to_integer(Gid),
+ do_merge_pax(Header#tar_header{gid=Gid2}, Rest);
+do_merge_pax(Header, [{?PAX_ATIME, Atime}|Rest]) ->
+ Atime2 = parse_pax_time(Atime),
+ do_merge_pax(Header#tar_header{atime=Atime2}, Rest);
+do_merge_pax(Header, [{?PAX_MTIME, Mtime}|Rest]) ->
+ Mtime2 = parse_pax_time(Mtime),
+ do_merge_pax(Header#tar_header{mtime=Mtime2}, Rest);
+do_merge_pax(Header, [{?PAX_CTIME, Ctime}|Rest]) ->
+ Ctime2 = parse_pax_time(Ctime),
+ do_merge_pax(Header#tar_header{ctime=Ctime2}, Rest);
+do_merge_pax(Header, [{?PAX_SIZE, Size}|Rest]) ->
+ Size2 = binary_to_integer(Size),
+ do_merge_pax(Header#tar_header{size=Size2}, Rest);
+do_merge_pax(Header, [{<<?PAX_XATTR_STR, _Key/binary>>, _Value}|Rest]) ->
+ do_merge_pax(Header, Rest);
+do_merge_pax(Header, [_Ignore|Rest]) ->
+ do_merge_pax(Header, Rest).
+
+%% Returns the time since UNIX epoch as a datetime
+-spec parse_pax_time(binary()) -> tar_time().
+parse_pax_time(Bin) when is_binary(Bin) ->
+ TotalNano = case binary:split(Bin, [<<$.>>]) of
+ [SecondsStr, NanoStr0] ->
+ Seconds = binary_to_integer(SecondsStr),
+ if byte_size(NanoStr0) < ?MAX_NANO_INT_SIZE ->
+ %% right pad
+ PaddingN = ?MAX_NANO_INT_SIZE-byte_size(NanoStr0),
+ Padding = binary:copy(<<$0>>, PaddingN),
+ NanoStr1 = <<NanoStr0/binary,Padding/binary>>,
+ Nano = binary_to_integer(NanoStr1),
+ (Seconds*?BILLION)+Nano;
+ byte_size(NanoStr0) > ?MAX_NANO_INT_SIZE ->
+ %% right truncate
+ NanoStr1 = binary_part(NanoStr0, 0, ?MAX_NANO_INT_SIZE),
+ Nano = binary_to_integer(NanoStr1),
+ (Seconds*?BILLION)+Nano;
+ true ->
+ (Seconds*?BILLION)+binary_to_integer(NanoStr0)
+ end;
+ [SecondsStr] ->
+ binary_to_integer(SecondsStr)*?BILLION
+ end,
+ %% truncate to microseconds
+ Micro = TotalNano div 1000,
+ Mega = Micro div 1000000000000,
+ Secs = Micro div 1000000 - (Mega*1000000),
+ Secs.
+
+%% Given a regular file reader, reads the whole file and
+%% parses all extended attributes it contains.
+parse_pax(#reg_file_reader{handle=Handle,num_bytes=0}) ->
+ {#{}, Handle};
+parse_pax(#reg_file_reader{handle=Handle0,num_bytes=NumBytes}) ->
+ case do_read(Handle0, NumBytes) of
+ {ok, Bytes, Handle1} ->
+ do_parse_pax(Handle1, Bytes, #{});
+ {error, _} = Err ->
+ throw(Err)
end.
-%% Verify the checksum in the header. First try an unsigned addition
-%% of all bytes in the header (as it should be according to Posix).
-
-verify_checksum(Bin) ->
- <<H1:?th_chksum/binary,CheckStr:?th_chksum_len/binary,H2/binary>> = Bin,
- case checksum(H1) + checksum(H2) of
- 0 -> eof;
- Checksum0 ->
- Csum = from_octal(CheckStr),
- CsumInit = ?th_chksum_len * $\s,
- case Checksum0 + CsumInit of
- Csum -> ok;
- Unsigned ->
- verify_checksum(H1, H2, CsumInit, Csum, Unsigned)
- end
+do_parse_pax(Reader, <<>>, Headers) ->
+ {Headers, Reader};
+do_parse_pax(Reader, Bin, Headers) ->
+ {Key, Value, Residual} = parse_pax_record(Bin),
+ NewHeaders = maps:put(Key, Value, Headers),
+ do_parse_pax(Reader, Residual, NewHeaders).
+
+%% Parse an extended attribute
+parse_pax_record(Bin) when is_binary(Bin) ->
+ case binary:split(Bin, [<<$\n>>]) of
+ [Record, Residual] ->
+ case binary:split(Record, [<<$\s>>], [trim_all]) of
+ [_Len, Record1] ->
+ case binary:split(Record1, [<<$=>>], [trim_all]) of
+ [AttrName, AttrValue] ->
+ {AttrName, AttrValue, Residual};
+ _Other ->
+ throw({error, malformed_pax_record})
+ end;
+ _Other ->
+ throw({error, malformed_pax_record})
+ end;
+ _Other ->
+ throw({error, malformed_pax_record})
end.
-%% The checksums didn't match. Now try a signed addition.
+get_real_name(#reg_file_reader{handle=Handle,num_bytes=0}) ->
+ {"", Handle};
+get_real_name(#reg_file_reader{handle=Handle0,num_bytes=NumBytes}) ->
+ case do_read(Handle0, NumBytes) of
+ {ok, RealName, Handle1} ->
+ {RealName, Handle1};
+ {error, _} = Err ->
+ throw(Err)
+ end;
+get_real_name(#sparse_file_reader{num_bytes=NumBytes}=Reader0) ->
+ case do_read(Reader0, NumBytes) of
+ {ok, RealName, Reader1} ->
+ {RealName, Reader1};
+ {error, _} = Err ->
+ throw(Err)
+ end.
-verify_checksum(H1, H2, Csum, ShouldBe, Unsigned) ->
- case signed_sum(binary_to_list(H1), signed_sum(binary_to_list(H2), Csum)) of
- ShouldBe -> ok;
- Signed ->
- throw({error,
- {bad_header,
- "Incorrect directory checksum ~w (~w), should be ~w",
- [Signed, Unsigned, ShouldBe]}})
+%% Skip the remaining bytes for the current file entry
+skip_file(#reg_file_reader{handle=Handle0,pos=Pos,size=Size}=Reader) ->
+ Padding = skip_padding(Size),
+ AbsPos = Handle0#reader.pos + (Size-Pos) + Padding,
+ case do_position(Handle0, AbsPos) of
+ {ok, _, Handle1} ->
+ Reader#reg_file_reader{handle=Handle1,num_bytes=0,pos=Size};
+ Err ->
+ throw(Err)
+ end;
+skip_file(#sparse_file_reader{pos=Pos,size=Size}=Reader) ->
+ case do_read(Reader, Size-Pos) of
+ {ok, _, Reader2} ->
+ Reader2;
+ Err ->
+ throw(Err)
end.
-signed_sum([C|Rest], Sum) when C < 128 ->
- signed_sum(Rest, Sum+C);
-signed_sum([C|Rest], Sum) ->
- signed_sum(Rest, Sum+C-256);
-signed_sum([], Sum) -> Sum.
-
-write_extracted_element(Header, Bin, Opts)
- when Opts#read_opts.output =:= memory ->
- case Header#tar_header.typeflag of
- regular ->
- {ok, {Header#tar_header.name, Bin}};
- _ ->
- ok
+skip_padding(0) ->
+ 0;
+skip_padding(Size) when (Size rem ?BLOCK_SIZE) =:= 0 ->
+ 0;
+skip_padding(Size) when Size =< ?BLOCK_SIZE ->
+ ?BLOCK_SIZE - Size;
+skip_padding(Size) ->
+ ?BLOCK_SIZE - (Size rem ?BLOCK_SIZE).
+
+skip_unread(#reader{pos=Pos}=Reader0) when (Pos rem ?BLOCK_SIZE) > 0 ->
+ Padding = skip_padding(Pos + ?BLOCK_SIZE),
+ AbsPos = Pos + Padding,
+ case do_position(Reader0, AbsPos) of
+ {ok, _, Reader1} ->
+ {ok, Reader1};
+ Err ->
+ throw(Err)
+ end;
+skip_unread(#reader{}=Reader) ->
+ {ok, Reader};
+skip_unread(#reg_file_reader{handle=Handle,num_bytes=0}) ->
+ skip_unread(Handle);
+skip_unread(#reg_file_reader{}=Reader) ->
+ #reg_file_reader{handle=Handle} = skip_file(Reader),
+ {ok, Handle};
+skip_unread(#sparse_file_reader{handle=Handle,num_bytes=0}) ->
+ skip_unread(Handle);
+skip_unread(#sparse_file_reader{}=Reader) ->
+ #sparse_file_reader{handle=Handle} = skip_file(Reader),
+ {ok, Handle}.
+
+write_extracted_element(#tar_header{name=Name,typeflag=Type},
+ Bin,
+ #read_opts{output=memory}=Opts) ->
+ case typeflag(Type) of
+ regular ->
+ read_verbose(Opts, "x ~ts~n", [Name]),
+ {ok, {Name, Bin}};
+ _ ->
+ ok
end;
-write_extracted_element(Header, Bin, Opts) ->
- Name = filename:absname(Header#tar_header.name, Opts#read_opts.cwd),
- Created =
- case Header#tar_header.typeflag of
- regular ->
- write_extracted_file(Name, Bin, Opts);
- directory ->
- create_extracted_dir(Name, Opts);
- symlink ->
- create_symlink(Name, Header, Opts);
- Other -> % Ignore.
- read_verbose(Opts, "x ~ts - unsupported type ~p~n",
- [Name, Other]),
- not_written
- end,
+write_extracted_element(#tar_header{name=Name0}=Header, Bin, Opts) ->
+ Name1 = make_safe_path(Name0, Opts),
+ Created =
+ case typeflag(Header#tar_header.typeflag) of
+ regular ->
+ create_regular(Name1, Name0, Bin, Opts);
+ directory ->
+ read_verbose(Opts, "x ~ts~n", [Name0]),
+ create_extracted_dir(Name1, Opts);
+ symlink ->
+ read_verbose(Opts, "x ~ts~n", [Name0]),
+ create_symlink(Name1, Header#tar_header.linkname, Opts);
+ Device when Device =:= char orelse Device =:= block ->
+ %% char/block devices will be created as empty files
+ %% and then have their major/minor device set later
+ create_regular(Name1, Name0, <<>>, Opts);
+ fifo ->
+ %% fifo devices will be created as empty files
+ create_regular(Name1, Name0, <<>>, Opts);
+ Other -> % Ignore.
+ read_verbose(Opts, "x ~ts - unsupported type ~p~n",
+ [Name0, Other]),
+ not_written
+ end,
case Created of
- ok -> set_extracted_file_info(Name, Header);
- not_written -> ok
+ ok -> set_extracted_file_info(Name1, Header);
+ not_written -> ok
+ end.
+
+make_safe_path([$/|Path], Opts) ->
+ make_safe_path(Path, Opts);
+make_safe_path(Path, #read_opts{cwd=Cwd}) ->
+ case filename:safe_relative_path(Path) of
+ unsafe ->
+ throw({error,{Path,unsafe_path}});
+ SafePath ->
+ filename:absname(SafePath, Cwd)
+ end.
+
+create_regular(Name, NameInArchive, Bin, Opts) ->
+ case write_extracted_file(Name, Bin, Opts) of
+ not_written ->
+ read_verbose(Opts, "x ~ts - exists, not created~n", [NameInArchive]),
+ not_written;
+ Ok ->
+ read_verbose(Opts, "x ~ts~n", [NameInArchive]),
+ Ok
end.
create_extracted_dir(Name, _Opts) ->
case file:make_dir(Name) of
- ok -> ok;
- {error,enotsup} -> not_written;
- {error,eexist} -> not_written;
- {error,enoent} -> make_dirs(Name, dir);
- {error,Reason} -> throw({error, Reason})
+ ok -> ok;
+ {error,enotsup} -> not_written;
+ {error,eexist} -> not_written;
+ {error,enoent} -> make_dirs(Name, dir);
+ {error,Reason} -> throw({error, Reason})
end.
-create_symlink(Name, #tar_header{linkname=Linkname}=Header, Opts) ->
+create_symlink(Name, Linkname, Opts) ->
case file:make_symlink(Linkname, Name) of
- ok -> ok;
- {error,enoent} ->
- ok = make_dirs(Name, file),
- create_symlink(Name, Header, Opts);
- {error,eexist} -> not_written;
- {error,enotsup} ->
- read_verbose(Opts, "x ~ts - symbolic links not supported~n", [Name]),
- not_written;
- {error,Reason} -> throw({error, Reason})
+ ok -> ok;
+ {error,enoent} ->
+ ok = make_dirs(Name, file),
+ create_symlink(Name, Linkname, Opts);
+ {error,eexist} -> not_written;
+ {error,enotsup} ->
+ read_verbose(Opts, "x ~ts - symbolic links not supported~n", [Name]),
+ not_written;
+ {error,Reason} -> throw({error, Reason})
end.
write_extracted_file(Name, Bin, Opts) ->
Write =
- case Opts#read_opts.keep_old_files of
- true ->
- case file:read_file_info(Name) of
- {ok, _} -> false;
- _ -> true
- end;
- false -> true
- end,
+ case Opts#read_opts.keep_old_files of
+ true ->
+ case file:read_file_info(Name) of
+ {ok, _} -> false;
+ _ -> true
+ end;
+ false -> true
+ end,
case Write of
- true ->
- read_verbose(Opts, "x ~ts~n", [Name]),
- write_file(Name, Bin);
- false ->
- read_verbose(Opts, "x ~ts - exists, not created~n", [Name]),
- not_written
+ true -> write_file(Name, Bin);
+ false -> not_written
end.
write_file(Name, Bin) ->
case file:write_file(Name, Bin) of
- ok -> ok;
- {error,enoent} ->
- ok = make_dirs(Name, file),
- write_file(Name, Bin);
- {error,Reason} ->
- throw({error, Reason})
+ ok -> ok;
+ {error,enoent} ->
+ ok = make_dirs(Name, file),
+ write_file(Name, Bin);
+ {error,Reason} ->
+ throw({error, Reason})
end.
-set_extracted_file_info(_, #tar_header{typeflag = symlink}) -> ok;
-set_extracted_file_info(Name, #tar_header{mode=Mode, mtime=Mtime}) ->
- Info = #file_info{mode=Mode, mtime=posix_to_erlang_time(Mtime)},
+set_extracted_file_info(_, #tar_header{typeflag = ?TYPE_SYMLINK}) -> ok;
+set_extracted_file_info(_, #tar_header{typeflag = ?TYPE_LINK}) -> ok;
+set_extracted_file_info(Name, #tar_header{typeflag = ?TYPE_CHAR}=Header) ->
+ set_device_info(Name, Header);
+set_extracted_file_info(Name, #tar_header{typeflag = ?TYPE_BLOCK}=Header) ->
+ set_device_info(Name, Header);
+set_extracted_file_info(Name, #tar_header{mtime=Mtime,mode=Mode}) ->
+ Info = #file_info{mode=Mode, mtime=Mtime},
+ file:write_file_info(Name, Info, [{time, posix}]).
+
+set_device_info(Name, #tar_header{}=Header) ->
+ Mtime = Header#tar_header.mtime,
+ Mode = Header#tar_header.mode,
+ Devmajor = Header#tar_header.devmajor,
+ Devminor = Header#tar_header.devminor,
+ Info = #file_info{
+ mode=Mode,
+ mtime=Mtime,
+ major_device=Devmajor,
+ minor_device=Devminor
+ },
file:write_file_info(Name, Info).
%% Makes all directories leading up to the file.
make_dirs(Name, file) ->
- filelib:ensure_dir(Name);
+ filelib:ensure_dir(Name);
make_dirs(Name, dir) ->
- filelib:ensure_dir(filename:join(Name,"*")).
+ filelib:ensure_dir(filename:join(Name,"*")).
%% Prints the message on if the verbose option is given (for reading).
-
read_verbose(#read_opts{verbose=true}, Format, Args) ->
- io:format(Format, Args),
- io:nl();
+ io:format(Format, Args);
read_verbose(_, _, _) ->
ok.
+%% Prints the message on if the verbose option is given.
+add_verbose(#add_opts{verbose=true}, Format, Args) ->
+ io:format(Format, Args);
+add_verbose(_, _, _) ->
+ ok.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%
-%%% Utility functions.
-%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% Returns the checksum of a binary.
-
-checksum(Bin) -> checksum(Bin, 0).
-
-checksum(<<A,B,C,D,E,F,G,H,T/binary>>, Sum) ->
- checksum(T, Sum+A+B+C+D+E+F+G+H);
-checksum(<<A,T/binary>>, Sum) ->
- checksum(T, Sum+A);
-checksum(<<>>, Sum) -> Sum.
-
-%% Returns a list of zeroes to pad out to the given block size.
-
-padding(Size, BlockSize) ->
- zeroes(pad_size(Size, BlockSize)).
-
-pad_size(Size, BlockSize) ->
- case Size rem BlockSize of
- 0 -> 0;
- Rem -> BlockSize-Rem
+%%%%%%%%%%%%%%%%%%
+%% I/O primitives
+%%%%%%%%%%%%%%%%%%
+
+do_write(#reader{handle=Handle,func=Fun}=Reader0, Data)
+ when is_function(Fun,2) ->
+ case Fun(write,{Handle,Data}) of
+ ok ->
+ {ok, Pos, Reader1} = do_position(Reader0, {cur,0}),
+ {ok, Reader1#reader{pos=Pos}};
+ {error, _} = Err ->
+ Err
end.
-zeroes(0) -> [];
-zeroes(1) -> [0];
-zeroes(2) -> [0,0];
-zeroes(Number) ->
- Half = zeroes(Number div 2),
- case Number rem 2 of
- 0 -> [Half|Half];
- 1 -> [Half|[0|Half]]
+do_copy(#reader{func=Fun}=Reader, Source, #add_opts{chunk_size=0}=Opts)
+ when is_function(Fun, 2) ->
+ do_copy(Reader, Source, Opts#add_opts{chunk_size=65536});
+do_copy(#reader{func=Fun}=Reader, Source, #add_opts{chunk_size=ChunkSize})
+ when is_function(Fun, 2) ->
+ case file:open(Source, [read, binary]) of
+ {ok, SourceFd} ->
+ case copy_chunked(Reader, SourceFd, ChunkSize, 0) of
+ {ok, _Copied, _Reader2} = Ok->
+ _ = file:close(SourceFd),
+ Ok;
+ Err ->
+ _ = file:close(SourceFd),
+ throw(Err)
+ end;
+ Err ->
+ throw(Err)
end.
-%% Skips the given number of bytes rounded up to an even record.
+copy_chunked(#reader{}=Reader, Source, ChunkSize, Copied) ->
+ case file:read(Source, ChunkSize) of
+ {ok, Bin} ->
+ {ok, Reader2} = do_write(Reader, Bin),
+ copy_chunked(Reader2, Source, ChunkSize, Copied+byte_size(Bin));
+ eof ->
+ {ok, Copied, Reader};
+ Other ->
+ Other
+ end.
-skip(File, Size) ->
- %% Note: There is no point in handling failure to get the current position
- %% in the file. If it doesn't work, something serious is wrong.
- Amount = ((Size + ?record_size - 1) div ?record_size) * ?record_size,
- {ok,_} = do_position(File, {cur, Amount}),
- ok.
-%% Skips to the next record in the file.
+do_position(#reader{handle=Handle,func=Fun}=Reader, Pos)
+ when is_function(Fun,2)->
+ case Fun(position, {Handle,Pos}) of
+ {ok, NewPos} ->
+ %% since Pos may not always be an absolute seek,
+ %% make sure we update the reader with the new absolute position
+ {ok, AbsPos} = Fun(position, {Handle, {cur, 0}}),
+ {ok, NewPos, Reader#reader{pos=AbsPos}};
+ Other ->
+ Other
+ end.
-skip_to_next(File) ->
- %% Note: There is no point in handling failure to get the current position
- %% in the file. If it doesn't work, something serious is wrong.
- {ok, Position} = do_position(File, {cur, 0}),
- NewPosition = ((Position + ?record_size - 1) div ?record_size) * ?record_size,
- {ok,NewPosition} = do_position(File, NewPosition),
- ok.
+do_read(#reg_file_reader{handle=Handle,pos=Pos,size=Size}=Reader, Len) ->
+ NumBytes = Size - Pos,
+ ActualLen = if NumBytes - Len < 0 -> NumBytes; true -> Len end,
+ case do_read(Handle, ActualLen) of
+ {ok, Bin, Handle2} ->
+ NewPos = Pos + ActualLen,
+ NumBytes2 = Size - NewPos,
+ Reader1 = Reader#reg_file_reader{
+ handle=Handle2,
+ pos=NewPos,
+ num_bytes=NumBytes2},
+ {ok, Bin, Reader1};
+ Other ->
+ Other
+ end;
+do_read(#sparse_file_reader{}=Reader, Len) ->
+ do_sparse_read(Reader, Len);
+do_read(#reader{pos=Pos,handle=Handle,func=Fun}=Reader, Len)
+ when is_function(Fun,2)->
+ %% Always convert to binary internally
+ case Fun(read2,{Handle,Len}) of
+ {ok, List} when is_list(List) ->
+ Bin = list_to_binary(List),
+ NewPos = Pos+byte_size(Bin),
+ {ok, Bin, Reader#reader{pos=NewPos}};
+ {ok, Bin} when is_binary(Bin) ->
+ NewPos = Pos+byte_size(Bin),
+ {ok, Bin, Reader#reader{pos=NewPos}};
+ Other ->
+ Other
+ end.
-%% Prints the message on if the verbose option is given.
-add_verbose(#add_opts{verbose=true}, Format, Args) ->
- io:format(Format, Args);
-add_verbose(_, _, _) ->
- ok.
-
-%% Converts a tuple containing the time to a Posix time (seconds
-%% since Jan 1, 1970).
-
-posix_time(Time) ->
- EpochStart = {{1970,1,1},{0,0,0}},
- {Days,{Hour,Min,Sec}} = calendar:time_difference(EpochStart, Time),
- 86400*Days + 3600*Hour + 60*Min + Sec.
-
-posix_to_erlang_time(Sec) ->
- OneMillion = 1000000,
- Time = calendar:now_to_datetime({Sec div OneMillion, Sec rem OneMillion, 0}),
- erlang:universaltime_to_localtime(Time).
-
-read_file_and_info(Name, Opts) ->
- ReadInfo = Opts#add_opts.read_info,
- case ReadInfo(Name) of
- {ok,Info} when Info#file_info.type =:= regular,
- Opts#add_opts.chunk_size>0 ->
- {ok,chunked,Info};
- {ok,Info} when Info#file_info.type =:= regular ->
- case file:read_file(Name) of
- {ok,Bin} ->
- {ok,Bin,Info};
- Error ->
- Error
- end;
- {ok,Info} when Info#file_info.type =:= symlink ->
- case file:read_link(Name) of
- {ok,PointsTo} ->
- {ok,PointsTo,Info};
- Error ->
- Error
- end;
- {ok, Info} ->
- {ok,[],Info};
- Error ->
- Error
+do_sparse_read(Reader, Len) ->
+ do_sparse_read(Reader, Len, <<>>).
+
+do_sparse_read(#sparse_file_reader{sparse_map=[#sparse_entry{num_bytes=0}|Entries]
+ }=Reader0, Len, Acc) ->
+ %% skip all empty fragments
+ Reader1 = Reader0#sparse_file_reader{sparse_map=Entries},
+ do_sparse_read(Reader1, Len, Acc);
+do_sparse_read(#sparse_file_reader{sparse_map=[],
+ pos=Pos,size=Size}=Reader0, Len, Acc)
+ when Pos < Size ->
+ %% if there are no more fragments, it is possible that there is one last sparse hole
+ %% this behaviour matches the BSD tar utility
+ %% however, GNU tar stops returning data even if we haven't reached the end
+ {ok, Bin, Reader1} = read_sparse_hole(Reader0, Size, Len),
+ do_sparse_read(Reader1, Len-byte_size(Bin), <<Acc/binary,Bin/binary>>);
+do_sparse_read(#sparse_file_reader{sparse_map=[]}=Reader, _Len, Acc) ->
+ {ok, Acc, Reader};
+do_sparse_read(#sparse_file_reader{}=Reader, 0, Acc) ->
+ {ok, Acc, Reader};
+do_sparse_read(#sparse_file_reader{sparse_map=[#sparse_entry{offset=Offset}|_],
+ pos=Pos}=Reader0, Len, Acc)
+ when Pos < Offset ->
+ {ok, Bin, Reader1} = read_sparse_hole(Reader0, Offset, Offset-Pos),
+ do_sparse_read(Reader1, Len-byte_size(Bin), <<Acc/binary,Bin/binary>>);
+do_sparse_read(#sparse_file_reader{sparse_map=[Entry|Entries],
+ pos=Pos}=Reader0, Len, Acc) ->
+ %% we're in a data fragment, so read from it
+ %% end offset of fragment
+ EndPos = Entry#sparse_entry.offset + Entry#sparse_entry.num_bytes,
+ %% bytes left in fragment
+ NumBytes = EndPos - Pos,
+ ActualLen = if Len > NumBytes -> NumBytes; true -> Len end,
+ case do_read(Reader0#sparse_file_reader.handle, ActualLen) of
+ {ok, Bin, Handle} ->
+ BytesRead = byte_size(Bin),
+ ActualEndPos = Pos+BytesRead,
+ Reader1 = if ActualEndPos =:= EndPos ->
+ Reader0#sparse_file_reader{sparse_map=Entries};
+ true ->
+ Reader0
+ end,
+ Size = Reader1#sparse_file_reader.size,
+ NumBytes2 = Size - ActualEndPos,
+ Reader2 = Reader1#sparse_file_reader{
+ handle=Handle,
+ pos=ActualEndPos,
+ num_bytes=NumBytes2},
+ do_sparse_read(Reader2, Len-byte_size(Bin), <<Acc/binary,Bin/binary>>);
+ Other ->
+ Other
end.
-foreach_while_ok(Fun, [First|Rest]) ->
- case Fun(First) of
- ok -> foreach_while_ok(Fun, Rest);
- Other -> Other
- end;
-foreach_while_ok(_, []) -> ok.
-
-open_mode(Mode) ->
- open_mode(Mode, false, [raw], []).
+%% Reads a sparse hole ending at Offset
+read_sparse_hole(#sparse_file_reader{pos=Pos}=Reader, Offset, Len) ->
+ N = Offset - Pos,
+ N2 = if N > Len ->
+ Len;
+ true ->
+ N
+ end,
+ Bin = <<0:N2/unit:8>>,
+ NumBytes = Reader#sparse_file_reader.size - (Pos+N2),
+ {ok, Bin, Reader#sparse_file_reader{
+ num_bytes=NumBytes,
+ pos=Pos+N2}}.
+
+-spec do_close(reader()) -> ok | {error, term()}.
+do_close(#reader{handle=Handle,func=Fun}) when is_function(Fun,2) ->
+ Fun(close,Handle).
+
+%%%%%%%%%%%%%%%%%%
+%% Option parsing
+%%%%%%%%%%%%%%%%%%
-open_mode(read, _, Raw, _) ->
- {ok, read, Raw, []};
-open_mode(write, _, Raw, _) ->
- {ok, write, Raw, []};
-open_mode([read|Rest], false, Raw, Opts) ->
- open_mode(Rest, read, Raw, Opts);
-open_mode([write|Rest], false, Raw, Opts) ->
- open_mode(Rest, write, Raw, Opts);
-open_mode([compressed|Rest], Access, Raw, Opts) ->
- open_mode(Rest, Access, Raw, [compressed|Opts]);
-open_mode([cooked|Rest], Access, _Raw, Opts) ->
- open_mode(Rest, Access, [], Opts);
-open_mode([], Access, Raw, Opts) ->
- {ok, Access, Raw, Opts};
-open_mode(_, _, _, _) ->
- {error, einval}.
+extract_opts(List) ->
+ extract_opts(List, default_options()).
-%%%================================================================
-do_write({tar_descriptor,UsrHandle,Fun}, Data) -> Fun(write,{UsrHandle,Data}).
+table_opts(List) ->
+ read_opts(List, default_options()).
-do_position({tar_descriptor,UsrHandle,Fun}, Pos) -> Fun(position,{UsrHandle,Pos}).
+default_options() ->
+ {ok, Cwd} = file:get_cwd(),
+ #read_opts{cwd=Cwd}.
-do_read({tar_descriptor,UsrHandle,Fun}, Len) -> Fun(read2,{UsrHandle,Len}).
+extract_opts([keep_old_files|Rest], Opts) ->
+ extract_opts(Rest, Opts#read_opts{keep_old_files=true});
+extract_opts([{cwd, Cwd}|Rest], Opts) ->
+ extract_opts(Rest, Opts#read_opts{cwd=Cwd});
+extract_opts([{files, Files}|Rest], Opts) ->
+ Set = ordsets:from_list(Files),
+ extract_opts(Rest, Opts#read_opts{files=Set});
+extract_opts([memory|Rest], Opts) ->
+ extract_opts(Rest, Opts#read_opts{output=memory});
+extract_opts([compressed|Rest], Opts=#read_opts{open_mode=OpenMode}) ->
+ extract_opts(Rest, Opts#read_opts{open_mode=[compressed|OpenMode]});
+extract_opts([cooked|Rest], Opts=#read_opts{open_mode=OpenMode}) ->
+ extract_opts(Rest, Opts#read_opts{open_mode=[cooked|OpenMode]});
+extract_opts([verbose|Rest], Opts) ->
+ extract_opts(Rest, Opts#read_opts{verbose=true});
+extract_opts([Other|Rest], Opts) ->
+ extract_opts(Rest, read_opts([Other], Opts));
+extract_opts([], Opts) ->
+ Opts.
-do_close({tar_descriptor,UsrHandle,Fun}) -> Fun(close,UsrHandle).
+read_opts([compressed|Rest], Opts=#read_opts{open_mode=OpenMode}) ->
+ read_opts(Rest, Opts#read_opts{open_mode=[compressed|OpenMode]});
+read_opts([cooked|Rest], Opts=#read_opts{open_mode=OpenMode}) ->
+ read_opts(Rest, Opts#read_opts{open_mode=[cooked|OpenMode]});
+read_opts([verbose|Rest], Opts) ->
+ read_opts(Rest, Opts#read_opts{verbose=true});
+read_opts([_|Rest], Opts) ->
+ read_opts(Rest, Opts);
+read_opts([], Opts) ->
+ Opts.
diff --git a/lib/stdlib/src/erl_tar.hrl b/lib/stdlib/src/erl_tar.hrl
new file mode 100644
index 0000000000..cff0c2f500
--- /dev/null
+++ b/lib/stdlib/src/erl_tar.hrl
@@ -0,0 +1,396 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+
+%% Options used when adding files to a tar archive.
+-record(add_opts, {
+ read_info, %% Fun to use for read file/link info.
+ chunk_size = 0, %% For file reading when sending to sftp. 0=do not chunk
+ verbose = false}). %% Verbose on/off.
+-type add_opts() :: #add_opts{}.
+
+%% Options used when reading a tar archive.
+-record(read_opts, {
+ cwd :: string(), %% Current working directory.
+ keep_old_files = false :: boolean(), %% Owerwrite or not.
+ files = all, %% Set of files to extract (or all)
+ output = file :: 'file' | 'memory',
+ open_mode = [], %% Open mode options.
+ verbose = false :: boolean()}). %% Verbose on/off.
+-type read_opts() :: #read_opts{}.
+
+-type add_opt() :: dereference |
+ verbose |
+ {chunks, pos_integer()}.
+
+-type extract_opt() :: {cwd, string()} |
+ {files, [string()]} |
+ compressed |
+ cooked |
+ memory |
+ keep_old_files |
+ verbose.
+
+-type create_opt() :: compressed |
+ cooked |
+ dereference |
+ verbose.
+
+-type filelist() :: [file:filename() |
+ {string(), binary()} |
+ {string(), file:filename()}].
+
+-type tar_time() :: non_neg_integer().
+
+%% The tar header, once fully parsed.
+-record(tar_header, {
+ name = "" :: string(), %% name of header file entry
+ mode = 8#100644 :: non_neg_integer(), %% permission and mode bits
+ uid = 0 :: non_neg_integer(), %% user id of owner
+ gid = 0 :: non_neg_integer(), %% group id of owner
+ size = 0 :: non_neg_integer(), %% length in bytes
+ mtime :: tar_time(), %% modified time
+ typeflag :: char(), %% type of header entry
+ linkname = "" :: string(), %% target name of link
+ uname = "" :: string(), %% user name of owner
+ gname = "" :: string(), %% group name of owner
+ devmajor = 0 :: non_neg_integer(), %% major number of character or block device
+ devminor = 0 :: non_neg_integer(), %% minor number of character or block device
+ atime :: tar_time(), %% access time
+ ctime :: tar_time() %% status change time
+ }).
+-type tar_header() :: #tar_header{}.
+
+%% Metadata for a sparse file fragment
+-record(sparse_entry, {
+ offset = 0 :: non_neg_integer(),
+ num_bytes = 0 :: non_neg_integer()}).
+-type sparse_entry() :: #sparse_entry{}.
+%% Contains metadata about fragments of a sparse file
+-record(sparse_array, {
+ entries = [] :: [sparse_entry()],
+ is_extended = false :: boolean(),
+ max_entries = 0 :: non_neg_integer()}).
+-type sparse_array() :: #sparse_array{}.
+%% A subset of tar header fields common to all tar implementations
+-record(header_v7, {
+ name :: binary(),
+ mode :: binary(), %% octal
+ uid :: binary(), %% integer
+ gid :: binary(), %% integer
+ size :: binary(), %% integer
+ mtime :: binary(), %% integer
+ checksum :: binary(), %% integer
+ typeflag :: byte(), %% char
+ linkname :: binary()}).
+-type header_v7() :: #header_v7{}.
+%% The set of fields specific to GNU tar formatted archives
+-record(header_gnu, {
+ header_v7 :: header_v7(),
+ magic :: binary(),
+ version :: binary(),
+ uname :: binary(),
+ gname :: binary(),
+ devmajor :: binary(), %% integer
+ devminor :: binary(), %% integer
+ atime :: binary(), %% integer
+ ctime :: binary(), %% integer
+ sparse :: sparse_array(),
+ real_size :: binary()}). %% integer
+-type header_gnu() :: #header_gnu{}.
+%% The set of fields specific to STAR-formatted archives
+-record(header_star, {
+ header_v7 :: header_v7(),
+ magic :: binary(),
+ version :: binary(),
+ uname :: binary(),
+ gname :: binary(),
+ devmajor :: binary(), %% integer
+ devminor :: binary(), %% integer
+ prefix :: binary(),
+ atime :: binary(), %% integer
+ ctime :: binary(), %% integer
+ trailer :: binary()}).
+-type header_star() :: #header_star{}.
+%% The set of fields specific to USTAR-formatted archives
+-record(header_ustar, {
+ header_v7 :: header_v7(),
+ magic :: binary(),
+ version :: binary(),
+ uname :: binary(),
+ gname :: binary(),
+ devmajor :: binary(), %% integer
+ devminor :: binary(), %% integer
+ prefix :: binary()}).
+-type header_ustar() :: #header_ustar{}.
+
+-type header_fields() :: header_v7() |
+ header_gnu() |
+ header_star() |
+ header_ustar().
+
+%% The overall tar reader, it holds the low-level file handle,
+%% its access, position, and the I/O primitives wrapper.
+-record(reader, {
+ handle :: file:io_device() | term(),
+ access :: read | write | ram,
+ pos = 0 :: non_neg_integer(),
+ func :: file_op()
+ }).
+-type reader() :: #reader{}.
+%% A reader for a regular file within the tar archive,
+%% It tracks its current state relative to that file.
+-record(reg_file_reader, {
+ handle :: reader(),
+ num_bytes = 0,
+ pos = 0,
+ size = 0
+ }).
+-type reg_file_reader() :: #reg_file_reader{}.
+%% A reader for a sparse file within the tar archive,
+%% It tracks its current state relative to that file.
+-record(sparse_file_reader, {
+ handle :: reader(),
+ num_bytes = 0, %% bytes remaining
+ pos = 0, %% pos
+ size = 0, %% total size of file
+ sparse_map = #sparse_array{}
+ }).
+-type sparse_file_reader() :: #sparse_file_reader{}.
+
+%% Types for the readers
+-type reader_type() :: reader() | reg_file_reader() | sparse_file_reader().
+-type handle() :: file:io_device() | term().
+
+%% Type for the I/O primitive wrapper function
+-type file_op() :: fun((write | close | read2 | position,
+ {handle(), iodata()} | handle() | {handle(), non_neg_integer()}
+ | {handle(), non_neg_integer()}) ->
+ ok | eof | {ok, string() | binary()} | {ok, non_neg_integer()}
+ | {error, term()}).
+
+%% These constants (except S_IFMT) are
+%% used to determine what type of device
+%% a file is. Namely, `S_IFMT band file_info.mode`
+%% will equal one of these contants, and tells us
+%% which type it is. The stdlib file_info record
+%% does not differentiate between device types, and
+%% will not allow us to differentiate between sockets
+%% and named pipes. These constants are pulled from libc.
+-define(S_IFMT, 61440).
+-define(S_IFSOCK, 49152). %% socket
+-define(S_FIFO, 4096). %% fifo/named pipe
+-define(S_IFBLK, 24576). %% block device
+-define(S_IFCHR, 8192). %% character device
+
+%% Typeflag constants for the tar header
+-define(TYPE_REGULAR, $0). %% regular file
+-define(TYPE_REGULAR_A, 0). %% regular file
+-define(TYPE_LINK, $1). %% hard link
+-define(TYPE_SYMLINK, $2). %% symbolic link
+-define(TYPE_CHAR, $3). %% character device node
+-define(TYPE_BLOCK, $4). %% block device node
+-define(TYPE_DIR, $5). %% directory
+-define(TYPE_FIFO, $6). %% fifo node
+-define(TYPE_CONT, $7). %% reserved
+-define(TYPE_X_HEADER, $x). %% extended header
+-define(TYPE_X_GLOBAL_HEADER, $g). %% global extended header
+-define(TYPE_GNU_LONGNAME, $L). %% next file has a long name
+-define(TYPE_GNU_LONGLINK, $K). %% next file symlinks to a file with a long name
+-define(TYPE_GNU_SPARSE, $S). %% sparse file
+
+%% Mode constants from tar spec
+-define(MODE_ISUID, 4000). %% set uid
+-define(MODE_ISGID, 2000). %% set gid
+-define(MODE_ISVTX, 1000). %% save text (sticky bit)
+-define(MODE_ISDIR, 40000). %% directory
+-define(MODE_ISFIFO, 10000). %% fifo
+-define(MODE_ISREG, 100000). %% regular file
+-define(MODE_ISLNK, 120000). %% symbolic link
+-define(MODE_ISBLK, 60000). %% block special file
+-define(MODE_ISCHR, 20000). %% character special file
+-define(MODE_ISSOCK, 140000). %% socket
+
+%% Keywords for PAX extended header
+-define(PAX_ATIME, <<"atime">>).
+-define(PAX_CHARSET, <<"charset">>).
+-define(PAX_COMMENT, <<"comment">>).
+-define(PAX_CTIME, <<"ctime">>). %% ctime is not a valid pax header
+-define(PAX_GID, <<"gid">>).
+-define(PAX_GNAME, <<"gname">>).
+-define(PAX_LINKPATH, <<"linkpath">>).
+-define(PAX_MTIME, <<"mtime">>).
+-define(PAX_PATH, <<"path">>).
+-define(PAX_SIZE, <<"size">>).
+-define(PAX_UID, <<"uid">>).
+-define(PAX_UNAME, <<"uname">>).
+-define(PAX_XATTR, <<"SCHILY.xattr.">>).
+-define(PAX_XATTR_STR, "SCHILY.xattr.").
+-define(PAX_NONE, <<"">>).
+
+%% Tar format constants
+%% Unknown format
+-define(FORMAT_UNKNOWN, 0).
+%% The format of the original Unix V7 tar tool prior to standardization
+-define(FORMAT_V7, 1).
+%% The old and new GNU formats, incompatible with USTAR.
+%% This covers the old GNU sparse extension, but it does
+%% not cover the GNU sparse extensions using PAX headers,
+%% versions 0.0, 0.1, and 1.0; these fall under the PAX format.
+-define(FORMAT_GNU, 2).
+%% Schily's tar format, which is incompatible with USTAR.
+%% This does not cover STAR extensions to the PAX format; these
+%% fall under the PAX format.
+-define(FORMAT_STAR, 3).
+%% USTAR is the former standardization of tar defined in POSIX.1-1988,
+%% it is incompatible with the GNU and STAR formats.
+-define(FORMAT_USTAR, 4).
+%% PAX is the latest standardization of tar defined in POSIX.1-2001.
+%% This is an extension of USTAR and is "backwards compatible" with it.
+%%
+%% Some newer formats add their own extensions to PAX, such as GNU sparse
+%% files and SCHILY extended attributes. Since they are backwards compatible
+%% with PAX, they will be labelled as "PAX".
+-define(FORMAT_PAX, 5).
+
+%% Magic constants
+-define(MAGIC_GNU, <<"ustar ">>).
+-define(VERSION_GNU, <<" \x00">>).
+-define(MAGIC_USTAR, <<"ustar\x00">>).
+-define(VERSION_USTAR, <<"00">>).
+-define(TRAILER_STAR, <<"tar\x00">>).
+
+%% Size constants
+-define(BLOCK_SIZE, 512). %% size of each block in a tar stream
+-define(NAME_SIZE, 100). %% max length of the name field in USTAR format
+-define(PREFIX_SIZE, 155). %% max length of the prefix field in USTAR format
+
+%% Maximum size of a nanosecond value as an integer
+-define(MAX_NANO_INT_SIZE, 9).
+%% Maximum size of a 64-bit signed integer
+-define(MAX_INT64, (1 bsl 63 - 1)).
+
+-define(PAX_GNU_SPARSE_NUMBLOCKS, <<"GNU.sparse.numblocks">>).
+-define(PAX_GNU_SPARSE_OFFSET, <<"GNU.sparse.offset">>).
+-define(PAX_GNU_SPARSE_NUMBYTES, <<"GNU.sparse.numbytes">>).
+-define(PAX_GNU_SPARSE_MAP, <<"GNU.sparse.map">>).
+-define(PAX_GNU_SPARSE_NAME, <<"GNU.sparse.name">>).
+-define(PAX_GNU_SPARSE_MAJOR, <<"GNU.sparse.major">>).
+-define(PAX_GNU_SPARSE_MINOR, <<"GNU.sparse.minor">>).
+-define(PAX_GNU_SPARSE_SIZE, <<"GNU.sparse.size">>).
+-define(PAX_GNU_SPARSE_REALSIZE, <<"GNU.sparse.realsize">>).
+
+-define(V7_NAME, 0).
+-define(V7_NAME_LEN, 100).
+-define(V7_MODE, 100).
+-define(V7_MODE_LEN, 8).
+-define(V7_UID, 108).
+-define(V7_UID_LEN, 8).
+-define(V7_GID, 116).
+-define(V7_GID_LEN, 8).
+-define(V7_SIZE, 124).
+-define(V7_SIZE_LEN, 12).
+-define(V7_MTIME, 136).
+-define(V7_MTIME_LEN, 12).
+-define(V7_CHKSUM, 148).
+-define(V7_CHKSUM_LEN, 8).
+-define(V7_TYPE, 156).
+-define(V7_TYPE_LEN, 1).
+-define(V7_LINKNAME, 157).
+-define(V7_LINKNAME_LEN, 100).
+
+-define(STAR_TRAILER, 508).
+-define(STAR_TRAILER_LEN, 4).
+
+-define(USTAR_MAGIC, 257).
+-define(USTAR_MAGIC_LEN, 6).
+-define(USTAR_VERSION, 263).
+-define(USTAR_VERSION_LEN, 2).
+-define(USTAR_UNAME, 265).
+-define(USTAR_UNAME_LEN, 32).
+-define(USTAR_GNAME, 297).
+-define(USTAR_GNAME_LEN, 32).
+-define(USTAR_DEVMAJ, 329).
+-define(USTAR_DEVMAJ_LEN, 8).
+-define(USTAR_DEVMIN, 337).
+-define(USTAR_DEVMIN_LEN, 8).
+-define(USTAR_PREFIX, 345).
+-define(USTAR_PREFIX_LEN, 155).
+
+-define(GNU_MAGIC, 257).
+-define(GNU_MAGIC_LEN, 6).
+-define(GNU_VERSION, 263).
+-define(GNU_VERSION_LEN, 2).
+
+%% ?BLOCK_SIZE of zero-bytes.
+%% Two of these in a row mark the end of an archive.
+-define(ZERO_BLOCK, <<0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0>>).
+
+-define(BILLION, 1000000000).
+
+-define(EPOCH, {{1970,1,1}, {0,0,0}}).
diff --git a/lib/stdlib/src/error_logger_file_h.erl b/lib/stdlib/src/error_logger_file_h.erl
index 665685d3ee..b7c193f965 100644
--- a/lib/stdlib/src/error_logger_file_h.erl
+++ b/lib/stdlib/src/error_logger_file_h.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -55,9 +55,9 @@ init(File) ->
init(File, PrevHandler) ->
process_flag(trap_exit, true),
- case file:open(File, [write]) of
+ case file:open(File, [write,{encoding,utf8}]) of
{ok,Fd} ->
- Depth = get_depth(),
+ Depth = error_logger:get_format_depth(),
State = #st{fd=Fd,filename=File,prev_handler=PrevHandler,
depth=Depth},
{ok, State};
@@ -65,14 +65,6 @@ init(File, PrevHandler) ->
Error
end.
-get_depth() ->
- case application:get_env(kernel, error_logger_format_depth) of
- {ok, Depth} when is_integer(Depth) ->
- max(10, Depth);
- undefined ->
- unlimited
- end.
-
handle_event({_Type, GL, _Msg}, State) when node(GL) =/= node() ->
{ok, State};
handle_event(Event, State) ->
@@ -116,8 +108,8 @@ write_event(#st{fd=Fd}=State, Event) ->
ignore ->
ok;
{Head,Pid,FormatList} ->
- Time = maybe_utc(erlang:universaltime()),
- Header = write_time(Time, Head),
+ Time = erlang:universaltime(),
+ Header = header(Time, Head),
Body = format_body(State, FormatList),
AtNode = if
node(Pid) =/= node() ->
@@ -125,7 +117,7 @@ write_event(#st{fd=Fd}=State, Event) ->
true ->
[]
end,
- io:put_chars(Fd, [Header,Body,AtNode])
+ io:put_chars(Fd, [Header,AtNode,Body])
end.
format_body(State, [{Format,Args}|T]) ->
@@ -172,21 +164,6 @@ parse_event({warning_report, _GL, {Pid, std_warning, Args}}) ->
{"WARNING REPORT",Pid,format_term(Args)};
parse_event(_) -> ignore.
-maybe_utc(Time) ->
- UTC = case application:get_env(sasl, utc_log) of
- {ok, Val} -> Val;
- undefined ->
- %% Backwards compatible:
- case application:get_env(stdlib, utc_log) of
- {ok, Val} -> Val;
- undefined -> false
- end
- end,
- maybe_utc(Time, UTC).
-
-maybe_utc(Time, true) -> {utc, Time};
-maybe_utc(Time, _) -> {local, calendar:universal_time_to_local_time(Time)}.
-
format_term(Term) when is_list(Term) ->
case string_p(Term) of
true ->
@@ -227,17 +204,33 @@ string_p1([H|T]) when is_list(H) ->
string_p1([]) -> true;
string_p1(_) -> false.
-write_time({utc,{{Y,Mo,D},{H,Mi,S}}}, Type) ->
- io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s UTC ===~n",
- [Type,D,month(Mo),Y,t(H),t(Mi),t(S)]);
-write_time({local, {{Y,Mo,D},{H,Mi,S}}}, Type) ->
- io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s ===~n",
- [Type,D,month(Mo),Y,t(H),t(Mi),t(S)]).
+get_utc_config() ->
+ %% SASL utc_log configuration overrides stdlib config
+ %% in order to have uniform timestamps in log messages
+ case application:get_env(sasl, utc_log) of
+ {ok, Val} -> Val;
+ undefined ->
+ case application:get_env(stdlib, utc_log) of
+ {ok, Val} -> Val;
+ undefined -> false
+ end
+ end.
+
+header(Time, Title) ->
+ case get_utc_config() of
+ true ->
+ header(Time, Title, "UTC ");
+ _ ->
+ header(calendar:universal_time_to_local_time(Time), Title, "")
+ end.
+
+header({{Y,Mo,D},{H,Mi,S}}, Title, UTC) ->
+ io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s ~s===~n",
+ [Title,D,month(Mo),Y,t(H),t(Mi),t(S),UTC]).
t(X) when is_integer(X) ->
- t1(integer_to_list(X));
-t(_) ->
- "".
+ t1(integer_to_list(X)).
+
t1([X]) -> [$0,X];
t1(X) -> X.
@@ -253,5 +246,3 @@ month(9) -> "Sep";
month(10) -> "Oct";
month(11) -> "Nov";
month(12) -> "Dec".
-
-
diff --git a/lib/stdlib/src/error_logger_tty_h.erl b/lib/stdlib/src/error_logger_tty_h.erl
index cb22a8c0b6..8f0d7b0362 100644
--- a/lib/stdlib/src/error_logger_tty_h.erl
+++ b/lib/stdlib/src/error_logger_tty_h.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -44,7 +44,7 @@
%% This one is used when we takeover from the simple error_logger.
init({[], {error_logger, Buf}}) ->
User = set_group_leader(),
- Depth = get_depth(),
+ Depth = error_logger:get_format_depth(),
State = #st{user=User,prev_handler=error_logger,depth=Depth},
write_events(State, Buf),
{ok, State};
@@ -56,17 +56,9 @@ init({[], {error_logger_tty_h, PrevHandler}}) ->
%% This one is used when we are started directly.
init([]) ->
User = set_group_leader(),
- Depth = get_depth(),
+ Depth = error_logger:get_format_depth(),
{ok, #st{user=User,prev_handler=[],depth=Depth}}.
-get_depth() ->
- case application:get_env(kernel, error_logger_format_depth) of
- {ok, Depth} when is_integer(Depth) ->
- max(10, Depth);
- undefined ->
- unlimited
- end.
-
handle_event({_Type, GL, _Msg}, State) when node(GL) =/= node() ->
{ok, State};
handle_event(Event, State) ->
@@ -128,13 +120,12 @@ write_events(State, [Ev|Es]) ->
write_events(_State, []) ->
ok.
-do_write_event(State, {Time0, Event}) ->
+do_write_event(State, {Time, Event}) ->
case parse_event(Event) of
ignore ->
ok;
- {Head,Pid,FormatList} ->
- Time = maybe_utc(Time0),
- Header = write_time(Time, Head),
+ {Title,Pid,FormatList} ->
+ Header = header(Time, Title),
Body = format_body(State, FormatList),
AtNode = if
node(Pid) =/= node() ->
@@ -142,7 +133,7 @@ do_write_event(State, {Time0, Event}) ->
true ->
[]
end,
- Str = [Header,Body,AtNode],
+ Str = [Header,AtNode,Body],
case State#st.io_mod of
io_lib ->
Str;
@@ -197,21 +188,6 @@ parse_event({warning_report, _GL, {Pid, std_warning, Args}}) ->
{"WARNING REPORT",Pid,format_term(Args)};
parse_event(_) -> ignore.
-maybe_utc(Time) ->
- UTC = case application:get_env(sasl, utc_log) of
- {ok, Val} -> Val;
- undefined ->
- %% Backwards compatible:
- case application:get_env(stdlib, utc_log) of
- {ok, Val} -> Val;
- undefined -> false
- end
- end,
- maybe_utc(Time, UTC).
-
-maybe_utc(Time, true) -> {utc, Time};
-maybe_utc(Time, _) -> {local, calendar:universal_time_to_local_time(Time)}.
-
format_term(Term) when is_list(Term) ->
case string_p(Term) of
true ->
@@ -255,12 +231,29 @@ string_p1([H|T]) when is_list(H) ->
string_p1([]) -> true;
string_p1(_) -> false.
-write_time({utc,{{Y,Mo,D},{H,Mi,S}}},Type) ->
- io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s UTC ===~n",
- [Type,D,month(Mo),Y,t(H),t(Mi),t(S)]);
-write_time({local, {{Y,Mo,D},{H,Mi,S}}},Type) ->
- io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s ===~n",
- [Type,D,month(Mo),Y,t(H),t(Mi),t(S)]).
+get_utc_config() ->
+ %% SASL utc_log configuration overrides stdlib config
+ %% in order to have uniform timestamps in log messages
+ case application:get_env(sasl, utc_log) of
+ {ok, Val} -> Val;
+ undefined ->
+ case application:get_env(stdlib, utc_log) of
+ {ok, Val} -> Val;
+ undefined -> false
+ end
+ end.
+
+header(Time, Title) ->
+ case get_utc_config() of
+ true ->
+ header(Time, Title, "UTC ");
+ _ ->
+ header(calendar:universal_time_to_local_time(Time), Title, "")
+ end.
+
+header({{Y,Mo,D},{H,Mi,S}}, Title, UTC) ->
+ io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s ~s===~n",
+ [Title,D,month(Mo),Y,t(H),t(Mi),t(S),UTC]).
t(X) when is_integer(X) ->
t1(integer_to_list(X));
@@ -281,8 +274,3 @@ month(9) -> "Sep";
month(10) -> "Oct";
month(11) -> "Nov";
month(12) -> "Dec".
-
-
-
-
-
diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl
index f53b0e2246..2093916a7c 100644
--- a/lib/stdlib/src/escript.erl
+++ b/lib/stdlib/src/escript.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -281,11 +281,12 @@ start(EscriptOptions) ->
end
catch
throw:Str ->
- io:format("escript: ~s\n", [Str]),
+ io:format("escript: ~ts\n", [Str]),
my_halt(127);
_:Reason ->
- io:format("escript: Internal error: ~p\n", [Reason]),
- io:format("~p\n", [erlang:get_stacktrace()]),
+ Stk = erlang:get_stacktrace(),
+ io:format("escript: Internal error: ~tp\n", [Reason]),
+ io:format("~tp\n", [Stk]),
my_halt(127)
end.
@@ -481,46 +482,49 @@ find_first_body_line(Fd, HeaderSz0, LineNo, KeepFirst, Sections) ->
%% Look for special comment on second line
Line2 = get_line(Fd),
{ok, HeaderSz2} = file:position(Fd, cur),
- case classify_line(Line2) of
- emu_args ->
- %% Skip special comment on second line
- Line3 = get_line(Fd),
- {HeaderSz2, LineNo + 2, Fd,
- Sections#sections{type = guess_type(Line3),
- comment = undefined,
- emu_args = Line2}};
- Line2Type ->
- %% Look for special comment on third line
- Line3 = get_line(Fd),
- {ok, HeaderSz3} = file:position(Fd, cur),
- Line3Type = classify_line(Line3),
- if
- Line3Type =:= emu_args ->
- %% Skip special comment on third line
- Line4 = get_line(Fd),
- {HeaderSz3, LineNo + 3, Fd,
- Sections#sections{type = guess_type(Line4),
- comment = Line2,
- emu_args = Line3}};
- Sections#sections.shebang =:= undefined,
- KeepFirst =:= true ->
- %% No shebang. Use the entire file
- {HeaderSz0, LineNo, Fd,
- Sections#sections{type = guess_type(Line2)}};
- Sections#sections.shebang =:= undefined ->
- %% No shebang. Skip the first line
- {HeaderSz1, LineNo, Fd,
- Sections#sections{type = guess_type(Line2)}};
- Line2Type =:= comment ->
- %% Skip shebang on first line and comment on second
- {HeaderSz2, LineNo + 2, Fd,
- Sections#sections{type = guess_type(Line3),
- comment = Line2}};
- true ->
- %% Just skip shebang on first line
- {HeaderSz1, LineNo + 1, Fd,
- Sections#sections{type = guess_type(Line2)}}
- end
+ if
+ Sections#sections.shebang =:= undefined,
+ KeepFirst =:= true ->
+ %% No shebang. Use the entire file
+ {HeaderSz0, LineNo, Fd,
+ Sections#sections{type = guess_type(Line2)}};
+ Sections#sections.shebang =:= undefined ->
+ %% No shebang. Skip the first line
+ {HeaderSz1, LineNo, Fd,
+ Sections#sections{type = guess_type(Line2)}};
+ true ->
+ case classify_line(Line2) of
+ emu_args ->
+ %% Skip special comment on second line
+ Line3 = get_line(Fd),
+ {HeaderSz2, LineNo + 2, Fd,
+ Sections#sections{type = guess_type(Line3),
+ comment = undefined,
+ emu_args = Line2}};
+ comment ->
+ %% Look for special comment on third line
+ Line3 = get_line(Fd),
+ {ok, HeaderSz3} = file:position(Fd, cur),
+ Line3Type = classify_line(Line3),
+ if
+ Line3Type =:= emu_args ->
+ %% Skip special comment on third line
+ Line4 = get_line(Fd),
+ {HeaderSz3, LineNo + 3, Fd,
+ Sections#sections{type = guess_type(Line4),
+ comment = Line2,
+ emu_args = Line3}};
+ true ->
+ %% Skip shebang on first line and comment on second
+ {HeaderSz2, LineNo + 2, Fd,
+ Sections#sections{type = guess_type(Line3),
+ comment = Line2}}
+ end;
+ _ ->
+ %% Just skip shebang on first line
+ {HeaderSz1, LineNo + 1, Fd,
+ Sections#sections{type = guess_type(Line2)}}
+ end
end.
classify_line(Line) ->
@@ -626,8 +630,7 @@ parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly) ->
{error, _} ->
epp_parse_file2(Epp, S2, [FileForm], OptModRes);
{eof, LastLine} ->
- Anno = anno(LastLine),
- S#state{forms_or_bin = [FileForm, {eof, Anno}]}
+ S#state{forms_or_bin = [FileForm, {eof, LastLine}]}
end,
ok = epp:close(Epp),
ok = file:close(Fd),
@@ -725,8 +728,7 @@ epp_parse_file2(Epp, S, Forms, Parsed) ->
[S#state.file,Ln,Mod:format_error(Args)]),
epp_parse_file(Epp, S#state{n_errors = S#state.n_errors + 1}, [Form | Forms]);
{eof, LastLine} ->
- Anno = anno(LastLine),
- S#state{forms_or_bin = lists:reverse([{eof, Anno} | Forms])}
+ S#state{forms_or_bin = lists:reverse([{eof, LastLine} | Forms])}
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl
index 3f74e01692..898b2f5bba 100644
--- a/lib/stdlib/src/ets.erl
+++ b/lib/stdlib/src/ets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -51,10 +51,10 @@
-type tab() :: atom() | tid().
-type type() :: set | ordered_set | bag | duplicate_bag.
-type continuation() :: '$end_of_table'
- | {tab(),integer(),integer(),binary(),list(),integer()}
- | {tab(),_,_,integer(),binary(),list(),integer(),integer()}.
+ | {tab(),integer(),integer(),comp_match_spec(),list(),integer()}
+ | {tab(),_,_,integer(),comp_match_spec(),list(),integer(),integer()}.
--opaque tid() :: integer().
+-opaque tid() :: reference().
-type match_pattern() :: atom() | tuple().
-type match_spec() :: [{match_pattern(), [_], [_]}].
@@ -70,15 +70,33 @@
match_object/2, match_object/3, match_spec_compile/1,
match_spec_run_r/3, member/2, new/2, next/2, prev/2,
rename/2, safe_fixtable/2, select/1, select/2, select/3,
- select_count/2, select_delete/2, select_reverse/1,
+ select_count/2, select_delete/2, select_replace/2, select_reverse/1,
select_reverse/2, select_reverse/3, setopts/2, slot/2,
take/2,
update_counter/3, update_counter/4, update_element/3]).
+%% internal exports
+-export([internal_request_all/0]).
+
-spec all() -> [Tab] when
Tab :: tab().
all() ->
+ receive_all(ets:internal_request_all(),
+ erlang:system_info(schedulers),
+ []).
+
+receive_all(_Ref, 0, All) ->
+ All;
+receive_all(Ref, N, All) ->
+ receive
+ {Ref, SchedAll} ->
+ receive_all(Ref, N-1, SchedAll ++ All)
+ end.
+
+-spec internal_request_all() -> reference().
+
+internal_request_all() ->
erlang:nif_error(undef).
-spec delete(Tab) -> true when
@@ -232,20 +250,20 @@ match(_) ->
match_object(_, _) ->
erlang:nif_error(undef).
--spec match_object(Tab, Pattern, Limit) -> {[Match], Continuation} |
+-spec match_object(Tab, Pattern, Limit) -> {[Object], Continuation} |
'$end_of_table' when
Tab :: tab(),
Pattern :: match_pattern(),
Limit :: pos_integer(),
- Match :: [term()],
+ Object :: tuple(),
Continuation :: continuation().
match_object(_, _, _) ->
erlang:nif_error(undef).
--spec match_object(Continuation) -> {[Match], Continuation} |
+-spec match_object(Continuation) -> {[Object], Continuation} |
'$end_of_table' when
- Match :: [term()],
+ Object :: tuple(),
Continuation :: continuation().
match_object(_) ->
@@ -361,6 +379,14 @@ select_count(_, _) ->
select_delete(_, _) ->
erlang:nif_error(undef).
+-spec select_replace(Tab, MatchSpec) -> NumReplaced when
+ Tab :: tab(),
+ MatchSpec :: match_spec(),
+ NumReplaced :: non_neg_integer().
+
+select_replace(_, _) ->
+ erlang:nif_error(undef).
+
-spec select_reverse(Tab, MatchSpec) -> [Match] when
Tab :: tab(),
MatchSpec :: match_spec(),
@@ -488,7 +514,7 @@ update_element(_, _, _) ->
%%% End of BIFs
--opaque comp_match_spec() :: binary(). %% this one is REALLY opaque
+-opaque comp_match_spec() :: reference().
-spec match_spec_run(List, CompiledMatchSpec) -> list() when
List :: [tuple()],
@@ -505,28 +531,28 @@ match_spec_run(List, CompiledMS) ->
repair_continuation('$end_of_table', _) ->
'$end_of_table';
%% ordered_set
-repair_continuation(Untouched = {Table,Lastkey,EndCondition,N2,Bin,L2,N3,N4}, MS)
+repair_continuation(Untouched = {Table,Lastkey,EndCondition,N2,MSRef,L2,N3,N4}, MS)
when %% (is_atom(Table) or is_integer(Table)),
is_integer(N2),
- byte_size(Bin) =:= 0,
+ %% is_reference(MSRef),
is_list(L2),
is_integer(N3),
is_integer(N4) ->
- case ets:is_compiled_ms(Bin) of
+ case ets:is_compiled_ms(MSRef) of
true ->
Untouched;
false ->
{Table,Lastkey,EndCondition,N2,ets:match_spec_compile(MS),L2,N3,N4}
end;
%% set/bag/duplicate_bag
-repair_continuation(Untouched = {Table,N1,N2,Bin,L,N3}, MS)
+repair_continuation(Untouched = {Table,N1,N2,MSRef,L,N3}, MS)
when %% (is_atom(Table) or is_integer(Table)),
is_integer(N1),
is_integer(N2),
- byte_size(Bin) =:= 0,
+ %% is_reference(MSRef),
is_list(L),
is_integer(N3) ->
- case ets:is_compiled_ms(Bin) of
+ case ets:is_compiled_ms(MSRef) of
true ->
Untouched;
false ->
diff --git a/lib/stdlib/src/eval_bits.erl b/lib/stdlib/src/eval_bits.erl
index 80667023fb..631faa3be5 100644
--- a/lib/stdlib/src/eval_bits.erl
+++ b/lib/stdlib/src/eval_bits.erl
@@ -67,16 +67,20 @@ expr_grp([Field | FS], Bs0, Lf, Acc) ->
expr_grp([], Bs0, _Lf, Acc) ->
{value,Acc,Bs0}.
+eval_field({bin_element, _, {string, _, S}, {integer,_,8}, [integer,{unit,1},unsigned,big]}, Bs0, _Fun) ->
+ Latin1 = [C band 16#FF || C <- S],
+ {list_to_binary(Latin1),Bs0};
eval_field({bin_element, _, {string, _, S}, default, default}, Bs0, _Fun) ->
Latin1 = [C band 16#FF || C <- S],
{list_to_binary(Latin1),Bs0};
-eval_field({bin_element, Line, {string, _, S}, Size0, Options0}, Bs, _Fun) ->
- {_Size,[Type,_Unit,_Sign,Endian]} =
+eval_field({bin_element, Line, {string, _, S}, Size0, Options0}, Bs0, Fun) ->
+ {Size1,[Type,{unit,Unit},Sign,Endian]} =
make_bit_type(Line, Size0, Options0),
- Res = << <<(eval_exp_field1(C, no_size, no_unit,
- Type, Endian, no_sign))/binary>> ||
+ {value,Size,Bs1} = Fun(Size1, Bs0),
+ Res = << <<(eval_exp_field1(C, Size, Unit,
+ Type, Endian, Sign))/binary>> ||
C <- S >>,
- {Res,Bs};
+ {Res,Bs1};
eval_field({bin_element,Line,E,Size0,Options0}, Bs0, Fun) ->
{value,V,Bs1} = Fun(E, Bs0),
{Size1,[Type,{unit,Unit},Sign,Endian]} =
diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl
index 7029389e2f..d7c313f214 100644
--- a/lib/stdlib/src/filelib.erl
+++ b/lib/stdlib/src/filelib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
-export([fold_files/5, last_modified/1, file_size/1, ensure_dir/1]).
-export([wildcard/3, is_dir/2, is_file/2, is_regular/2]).
-export([fold_files/6, last_modified/2, file_size/2]).
+-export([find_file/2, find_file/3, find_source/1, find_source/2, find_source/3]).
%% For debugging/testing.
-export([compile_wildcard/1]).
@@ -517,3 +518,124 @@ eval_list_dir(Dir, erl_prim_loader) ->
end;
eval_list_dir(Dir, Mod) ->
Mod:list_dir(Dir).
+
+%% Getting the rules to use for file search
+
+keep_dir_search_rules(Rules) ->
+ [T || {_,_}=T <- Rules].
+
+keep_suffix_search_rules(Rules) ->
+ [T || {_,_,_}=T <- Rules].
+
+get_search_rules() ->
+ case application:get_env(kernel, source_search_rules) of
+ undefined -> default_search_rules();
+ {ok, []} -> default_search_rules();
+ {ok, R} when is_list(R) -> R
+ end.
+
+default_search_rules() ->
+ [%% suffix-speficic rules for source search
+ {".beam", ".erl", erl_source_search_rules()},
+ {".erl", ".yrl", []},
+ {"", ".src", erl_source_search_rules()},
+ {".so", ".c", c_source_search_rules()},
+ {".o", ".c", c_source_search_rules()},
+ {"", ".c", c_source_search_rules()},
+ {"", ".in", basic_source_search_rules()},
+ %% plain old directory rules, backwards compatible
+ {"", ""},
+ {"ebin","src"},
+ {"ebin","esrc"}
+ ].
+
+basic_source_search_rules() ->
+ (erl_source_search_rules()
+ ++ c_source_search_rules()).
+
+erl_source_search_rules() ->
+ [{"ebin","src"}, {"ebin","esrc"}].
+
+c_source_search_rules() ->
+ [{"priv","c_src"}, {"priv","src"}, {"bin","c_src"}, {"bin","src"}, {"", "src"}].
+
+%% Looks for a file relative to a given directory
+
+-type find_file_rule() :: {ObjDirSuffix::string(), SrcDirSuffix::string()}.
+
+-spec find_file(filename(), filename()) ->
+ {ok, filename()} | {error, not_found}.
+find_file(Filename, Dir) ->
+ find_file(Filename, Dir, []).
+
+-spec find_file(filename(), filename(), [find_file_rule()]) ->
+ {ok, filename()} | {error, not_found}.
+find_file(Filename, Dir, []) ->
+ find_file(Filename, Dir, get_search_rules());
+find_file(Filename, Dir, Rules) ->
+ try_dir_rules(keep_dir_search_rules(Rules), Filename, Dir).
+
+%% Looks for a source file relative to the object file name and directory
+
+-type find_source_rule() :: {ObjExtension::string(), SrcExtension::string(),
+ [find_file_rule()]}.
+
+-spec find_source(filename()) ->
+ {ok, filename()} | {error, not_found}.
+find_source(FilePath) ->
+ find_source(filename:basename(FilePath), filename:dirname(FilePath)).
+
+-spec find_source(filename(), filename()) ->
+ {ok, filename()} | {error, not_found}.
+find_source(Filename, Dir) ->
+ find_source(Filename, Dir, []).
+
+-spec find_source(filename(), filename(), [find_source_rule()]) ->
+ {ok, filename()} | {error, not_found}.
+find_source(Filename, Dir, []) ->
+ find_source(Filename, Dir, get_search_rules());
+find_source(Filename, Dir, Rules) ->
+ try_suffix_rules(keep_suffix_search_rules(Rules), Filename, Dir).
+
+try_suffix_rules(Rules, Filename, Dir) ->
+ Ext = filename:extension(Filename),
+ try_suffix_rules(Rules, filename:rootname(Filename, Ext), Dir, Ext).
+
+try_suffix_rules([{Ext,Src,Rules}|Rest], Root, Dir, Ext)
+ when is_list(Src), is_list(Rules) ->
+ case try_dir_rules(add_local_search(Rules), Root ++ Src, Dir) of
+ {ok, File} -> {ok, File};
+ _Other ->
+ try_suffix_rules(Rest, Root, Dir, Ext)
+ end;
+try_suffix_rules([_|Rest], Root, Dir, Ext) ->
+ try_suffix_rules(Rest, Root, Dir, Ext);
+try_suffix_rules([], _Root, _Dir, _Ext) ->
+ {error, not_found}.
+
+%% ensuring we check the directory of the object file before any other directory
+add_local_search(Rules) ->
+ Local = {"",""},
+ [Local] ++ lists:filter(fun (X) -> X =/= Local end, Rules).
+
+try_dir_rules([{From, To}|Rest], Filename, Dir)
+ when is_list(From), is_list(To) ->
+ case try_dir_rule(Dir, Filename, From, To) of
+ {ok, File} -> {ok, File};
+ error -> try_dir_rules(Rest, Filename, Dir)
+ end;
+try_dir_rules([], _Filename, _Dir) ->
+ {error, not_found}.
+
+try_dir_rule(Dir, Filename, From, To) ->
+ case lists:suffix(From, Dir) of
+ true ->
+ NewDir = lists:sublist(Dir, 1, length(Dir)-length(From))++To,
+ Src = filename:join(NewDir, Filename),
+ case is_regular(Src) of
+ true -> {ok, Src};
+ false -> error
+ end;
+ false ->
+ error
+ end.
diff --git a/lib/stdlib/src/filename.erl b/lib/stdlib/src/filename.erl
index c4586171ca..9bf4290916 100644
--- a/lib/stdlib/src/filename.erl
+++ b/lib/stdlib/src/filename.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,6 +19,9 @@
%%
-module(filename).
+-deprecated({find_src,1,next_major_release}).
+-deprecated({find_src,2,next_major_release}).
+
%% Purpose: Provides generic manipulation of filenames.
%%
%% Generally, these functions accept filenames in the native format
@@ -34,8 +37,9 @@
-export([absname/1, absname/2, absname_join/2,
basename/1, basename/2, dirname/1,
extension/1, join/1, join/2, pathtype/1,
- rootname/1, rootname/2, split/1, nativename/1]).
--export([find_src/1, find_src/2, flatten/1]).
+ rootname/1, rootname/2, split/1, flatten/1, nativename/1,
+ safe_relative_path/1]).
+-export([find_src/1, find_src/2]). % deprecated
-export([basedir/2, basedir/3]).
%% Undocumented and unsupported exports.
@@ -750,7 +754,45 @@ separators() ->
_ -> {false, false}
end.
+-spec safe_relative_path(Filename) -> 'unsafe' | SafeFilename when
+ Filename :: file:name_all(),
+ SafeFilename :: file:name_all().
+
+safe_relative_path(Path) ->
+ case pathtype(Path) of
+ relative ->
+ Cs0 = split(Path),
+ safe_relative_path_1(Cs0, []);
+ _ ->
+ unsafe
+ end.
+safe_relative_path_1(["."|T], Acc) ->
+ safe_relative_path_1(T, Acc);
+safe_relative_path_1([<<".">>|T], Acc) ->
+ safe_relative_path_1(T, Acc);
+safe_relative_path_1([".."|T], Acc) ->
+ climb(T, Acc);
+safe_relative_path_1([<<"..">>|T], Acc) ->
+ climb(T, Acc);
+safe_relative_path_1([H|T], Acc) ->
+ safe_relative_path_1(T, [H|Acc]);
+safe_relative_path_1([], []) ->
+ [];
+safe_relative_path_1([], Acc) ->
+ join(lists:reverse(Acc)).
+
+climb(_, []) ->
+ unsafe;
+climb(T, [_|Acc]) ->
+ safe_relative_path_1(T, Acc).
+
+%% NOTE: The find_src/1/2 functions are deprecated; they try to do too much
+%% at once and are not a good fit for this module. Parts of the code have
+%% been moved to filelib:find_file/2 instead. Only this part of this
+%% module is allowed to call the filelib module; such mutual dependency
+%% should otherwise be avoided! This code should eventually be removed.
+%%
%% find_src(Module) --
%% find_src(Module, Rules) --
@@ -793,14 +835,7 @@ separators() ->
| {'d', atom()},
ErrorReason :: 'non_existing' | 'preloaded' | 'interpreted'.
find_src(Mod) ->
- Default = [{"", ""}, {"ebin", "src"}, {"ebin", "esrc"}],
- Rules =
- case application:get_env(kernel, source_search_rules) of
- undefined -> Default;
- {ok, []} -> Default;
- {ok, R} when is_list(R) -> R
- end,
- find_src(Mod, Rules).
+ find_src(Mod, []).
-spec find_src(Beam, Rules) -> {SourceFile, Options}
| {error, {ErrorReason, Module}} when
@@ -816,44 +851,47 @@ find_src(Mod) ->
ErrorReason :: 'non_existing' | 'preloaded' | 'interpreted'.
find_src(Mod, Rules) when is_atom(Mod) ->
find_src(atom_to_list(Mod), Rules);
-find_src(File0, Rules) when is_list(File0) ->
- Mod = list_to_atom(basename(File0, ".erl")),
- File = rootname(File0, ".erl"),
- case readable_file(File++".erl") of
- true ->
- try_file(File, Mod, Rules);
- false ->
- try_file(undefined, Mod, Rules)
- end.
-
-try_file(File, Mod, Rules) ->
+find_src(ModOrFile, Rules) when is_list(ModOrFile) ->
+ Extension = ".erl",
+ Mod = list_to_atom(basename(ModOrFile, Extension)),
case code:which(Mod) of
Possibly_Rel_Path when is_list(Possibly_Rel_Path) ->
- {ok, Cwd} = file:get_cwd(),
- Path = join(Cwd, Possibly_Rel_Path),
- try_file(File, Path, Mod, Rules);
+ {ok, Cwd} = file:get_cwd(),
+ ObjPath = make_abs_path(Cwd, Possibly_Rel_Path),
+ find_src_1(ModOrFile, ObjPath, Mod, Extension, Rules);
Ecode when is_atom(Ecode) -> % Ecode :: ecode()
{error, {Ecode, Mod}}
end.
%% At this point, the Mod is known to be valid.
%% If the source name is not known, find it.
-%% Then get the compilation options.
-%% Returns: {SrcFile, Options}
+find_src_1(ModOrFile, ObjPath, Mod, Extension, Rules) ->
+ %% The documentation says this function must return the found path
+ %% without extension in all cases. Also, ModOrFile could be given with
+ %% or without extension. Hence the calls to rootname below.
+ ModOrFileRoot = rootname(ModOrFile, Extension),
+ case filelib:is_regular(ModOrFileRoot++Extension) of
+ true ->
+ find_src_2(ModOrFileRoot, Mod);
+ false ->
+ SrcName = basename(ObjPath, code:objfile_extension()) ++ Extension,
+ case filelib:find_file(SrcName, dirname(ObjPath), Rules) of
+ {ok, SrcFile} ->
+ find_src_2(rootname(SrcFile, Extension), Mod);
+ Error ->
+ Error
+ end
+ end.
-try_file(undefined, ObjFilename, Mod, Rules) ->
- case get_source_file(ObjFilename, Mod, Rules) of
- {ok, File} -> try_file(File, ObjFilename, Mod, Rules);
- Error -> Error
- end;
-try_file(Src, _ObjFilename, Mod, _Rules) ->
+%% Get the compilation options and return {SrcFileRoot, Options}
+find_src_2(SrcRoot, Mod) ->
List = case Mod:module_info(compile) of
none -> [];
List0 -> List0
end,
Options = proplists:get_value(options, List, []),
{ok, Cwd} = file:get_cwd(),
- AbsPath = make_abs_path(Cwd, Src),
+ AbsPath = make_abs_path(Cwd, SrcRoot),
{AbsPath, filter_options(dirname(AbsPath), Options, [])}.
%% Filters the options.
@@ -884,42 +922,6 @@ filter_options(Base, [_|Rest], Result) ->
filter_options(_Base, [], Result) ->
Result.
-%% Gets the source file given path of object code and module name.
-
-get_source_file(Obj, Mod, Rules) ->
- source_by_rules(dirname(Obj), atom_to_list(Mod), Rules).
-
-source_by_rules(Dir, Base, [{From, To}|Rest]) ->
- case try_rule(Dir, Base, From, To) of
- {ok, File} -> {ok, File};
- error -> source_by_rules(Dir, Base, Rest)
- end;
-source_by_rules(_Dir, _Base, []) ->
- {error, source_file_not_found}.
-
-try_rule(Dir, Base, From, To) ->
- case lists:suffix(From, Dir) of
- true ->
- NewDir = lists:sublist(Dir, 1, length(Dir)-length(From))++To,
- Src = join(NewDir, Base),
- case readable_file(Src++".erl") of
- true -> {ok, Src};
- false -> error
- end;
- false ->
- error
- end.
-
-readable_file(File) ->
- case file:read_file_info(File) of
- {ok, #file_info{type=regular, access=read}} ->
- true;
- {ok, #file_info{type=regular, access=read_write}} ->
- true;
- _Other ->
- false
- end.
-
make_abs_path(BasePath, Path) ->
join(BasePath, Path).
diff --git a/lib/stdlib/src/gb_sets.erl b/lib/stdlib/src/gb_sets.erl
index 47a8fa6db0..6d6f7d40ac 100644
--- a/lib/stdlib/src/gb_sets.erl
+++ b/lib/stdlib/src/gb_sets.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% =====================================================================
%% Ordered Sets implemented as General Balanced Trees
diff --git a/lib/stdlib/src/gb_trees.erl b/lib/stdlib/src/gb_trees.erl
index c4a20d92a7..c0cdde012e 100644
--- a/lib/stdlib/src/gb_trees.erl
+++ b/lib/stdlib/src/gb_trees.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% =====================================================================
%% General Balanced Trees - highly efficient dictionaries.
@@ -59,6 +52,13 @@
%% - delete_any(X, T): removes key X from tree T if the key is present
%% in the tree, otherwise does nothing; returns new tree.
%%
+%% - take(X, T): removes element with key X from tree T; returns new tree
+%% without removed element. Assumes that the key is present in the tree.
+%%
+%% - take_any(X, T): removes element with key X from tree T and returns
+%% a new tree if the key is present; otherwise does nothing and returns
+%% 'error'.
+%%
%% - balance(T): rebalances tree T. Note that this is rarely necessary,
%% but may be motivated when a large number of entries have been
%% deleted from the tree without further insertions. Rebalancing could
@@ -121,7 +121,8 @@
-export([empty/0, is_empty/1, size/1, lookup/2, get/2, insert/3,
update/3, enter/3, delete/2, delete_any/2, balance/1,
is_defined/2, keys/1, values/1, to_list/1, from_orddict/1,
- smallest/1, largest/1, take_smallest/1, take_largest/1,
+ smallest/1, largest/1, take/2, take_any/2,
+ take_smallest/1, take_largest/1,
iterator/1, iterator_from/2, next/1, map/2]).
@@ -423,6 +424,41 @@ merge(Smaller, Larger) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec take_any(Key, Tree1) -> {Value, Tree2} | 'error' when
+ Tree1 :: tree(Key, _),
+ Tree2 :: tree(Key, _),
+ Key :: term(),
+ Value :: term().
+
+take_any(Key, Tree) ->
+ case is_defined(Key, Tree) of
+ true -> take(Key, Tree);
+ false -> error
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-spec take(Key, Tree1) -> {Value, Tree2} when
+ Tree1 :: tree(Key, _),
+ Tree2 :: tree(Key, _),
+ Key :: term(),
+ Value :: term().
+
+take(Key, {S, T}) when is_integer(S), S >= 0 ->
+ {Value, Res} = take_1(Key, T),
+ {Value, {S - 1, Res}}.
+
+take_1(Key, {Key1, Value, Smaller, Larger}) when Key < Key1 ->
+ {Value2, Smaller1} = take_1(Key, Smaller),
+ {Value2, {Key1, Value, Smaller1, Larger}};
+take_1(Key, {Key1, Value, Smaller, Bigger}) when Key > Key1 ->
+ {Value2, Bigger1} = take_1(Key, Bigger),
+ {Value2, {Key1, Value, Smaller, Bigger1}};
+take_1(_, {_Key, Value, Smaller, Larger}) ->
+ {Value, merge(Smaller, Larger)}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
-spec take_smallest(Tree1) -> {Key, Value, Tree2} when
Tree1 :: tree(Key, Value),
Tree2 :: tree(Key, Value).
diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl
index 597830cf9a..32f43fc706 100644
--- a/lib/stdlib/src/gen.erl
+++ b/lib/stdlib/src/gen.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
%%%
%%% The standard behaviour should export init_it/6.
%%%-----------------------------------------------------------------
--export([start/5, start/6, debug_options/2,
+-export([start/5, start/6, debug_options/2, hibernate_after/1,
name/1, unregister_name/1, get_proc_name/1, get_parent/0,
call/3, call/4, reply/2, stop/1, stop/3]).
@@ -408,6 +408,14 @@ spawn_opts(Options) ->
[]
end.
+hibernate_after(Options) ->
+ case lists:keyfind(hibernate_after, 1, Options) of
+ {_,HibernateAfterTimeout} ->
+ HibernateAfterTimeout;
+ false ->
+ infinity
+ end.
+
debug_options(Name, Opts) ->
case lists:keyfind(debug, 1, Opts) of
{_,Options} ->
diff --git a/lib/stdlib/src/gen_event.erl b/lib/stdlib/src/gen_event.erl
index ccacf658e9..da2b0da3ca 100644
--- a/lib/stdlib/src/gen_event.erl
+++ b/lib/stdlib/src/gen_event.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,10 +32,12 @@
%%% Modified by Martin - uses proc_lib, sys and gen!
--export([start/0, start/1, start_link/0, start_link/1, stop/1, stop/3,
+-export([start/0, start/1, start/2,
+ start_link/0, start_link/1, start_link/2,
+ stop/1, stop/3,
notify/2, sync_notify/2,
add_handler/3, add_sup_handler/3, delete_handler/3, swap_handler/3,
- swap_sup_handler/3, which_handlers/1, call/3, call/4, wake_hib/4]).
+ swap_sup_handler/3, which_handlers/1, call/3, call/4, wake_hib/5]).
-export([init_it/6,
system_continue/3,
@@ -107,7 +109,8 @@
State :: term(),
Status :: term().
--optional_callbacks([format_status/2]).
+-optional_callbacks(
+ [handle_info/2, terminate/2, code_change/3, format_status/2]).
%%---------------------------------------------------------------------------
@@ -117,30 +120,64 @@
-type del_handler_ret() :: ok | term() | {'EXIT',term()}.
-type emgr_name() :: {'local', atom()} | {'global', atom()}
- | {'via', atom(), term()}.
+ | {'via', atom(), term()}.
+-type debug_flag() :: 'trace' | 'log' | 'statistics' | 'debug'
+ | {'logfile', string()}.
+-type option() :: {'timeout', timeout()}
+ | {'debug', [debug_flag()]}
+ | {'spawn_opt', [proc_lib:spawn_option()]}.
-type emgr_ref() :: atom() | {atom(), atom()} | {'global', atom()}
- | {'via', atom(), term()} | pid().
+ | {'via', atom(), term()} | pid().
-type start_ret() :: {'ok', pid()} | {'error', term()}.
%%---------------------------------------------------------------------------
-define(NO_CALLBACK, 'no callback module').
+%% -----------------------------------------------------------------
+%% Starts a generic event handler.
+%% start()
+%% start(MgrName | Options)
+%% start(MgrName, Options)
+%% start_link()
+%% start_link(MgrName | Options)
+%% start_link(MgrName, Options)
+%% MgrName ::= {local, atom()} | {global, atom()} | {via, atom(), term()}
+%% Options ::= [{timeout, Timeout} | {debug, [Flag]} | {spawn_opt,SOpts}]
+%% Flag ::= trace | log | {logfile, File} | statistics | debug
+%% (debug == log && statistics)
+%% Returns: {ok, Pid} |
+%% {error, {already_started, Pid}} |
+%% {error, Reason}
+%% -----------------------------------------------------------------
+
-spec start() -> start_ret().
start() ->
gen:start(?MODULE, nolink, ?NO_CALLBACK, [], []).
--spec start(emgr_name()) -> start_ret().
-start(Name) ->
- gen:start(?MODULE, nolink, Name, ?NO_CALLBACK, [], []).
+-spec start(emgr_name() | [option()]) -> start_ret().
+start(Name) when is_tuple(Name) ->
+ gen:start(?MODULE, nolink, Name, ?NO_CALLBACK, [], []);
+start(Options) when is_list(Options) ->
+ gen:start(?MODULE, nolink, ?NO_CALLBACK, [], Options).
+
+-spec start(emgr_name(), [option()]) -> start_ret().
+start(Name, Options) ->
+ gen:start(?MODULE, nolink, Name, ?NO_CALLBACK, [], Options).
-spec start_link() -> start_ret().
start_link() ->
gen:start(?MODULE, link, ?NO_CALLBACK, [], []).
--spec start_link(emgr_name()) -> start_ret().
-start_link(Name) ->
- gen:start(?MODULE, link, Name, ?NO_CALLBACK, [], []).
+-spec start_link(emgr_name() | [option()]) -> start_ret().
+start_link(Name) when is_tuple(Name) ->
+ gen:start(?MODULE, link, Name, ?NO_CALLBACK, [], []);
+start_link(Options) when is_list(Options) ->
+ gen:start(?MODULE, link, ?NO_CALLBACK, [], Options).
+
+-spec start_link(emgr_name(), [option()]) -> start_ret().
+start_link(Name, Options) ->
+ gen:start(?MODULE, link, Name, ?NO_CALLBACK, [], Options).
%% -spec init_it(pid(), 'self' | pid(), emgr_name(), module(), [term()], [_]) ->
init_it(Starter, self, Name, Mod, Args, Options) ->
@@ -149,8 +186,9 @@ init_it(Starter, Parent, Name0, _, _, Options) ->
process_flag(trap_exit, true),
Name = gen:name(Name0),
Debug = gen:debug_options(Name, Options),
+ HibernateAfterTimeout = gen:hibernate_after(Options),
proc_lib:init_ack(Starter, {ok, self()}),
- loop(Parent, Name, [], Debug, false).
+ loop(Parent, Name, [], HibernateAfterTimeout, Debug, false).
-spec add_handler(emgr_ref(), handler(), term()) -> term().
add_handler(M, Handler, Args) -> rpc(M, {add_handler, Handler, Args}).
@@ -160,7 +198,7 @@ add_sup_handler(M, Handler, Args) ->
rpc(M, {add_sup_handler, Handler, Args, self()}).
-spec notify(emgr_ref(), term()) -> 'ok'.
-notify(M, Event) -> send(M, {notify, Event}).
+notify(M, Event) -> send(M, {notify, Event}).
-spec sync_notify(emgr_ref(), term()) -> 'ok'.
sync_notify(M, Event) -> rpc(M, {sync_notify, Event}).
@@ -193,7 +231,7 @@ stop(M) ->
stop(M, Reason, Timeout) ->
gen:stop(M, Reason, Timeout).
-rpc(M, Cmd) ->
+rpc(M, Cmd) ->
{ok, Reply} = gen:call(M, self(), Cmd, infinity),
Reply.
@@ -227,81 +265,83 @@ send(M, Cmd) ->
M ! Cmd,
ok.
-loop(Parent, ServerName, MSL, Debug, true) ->
- proc_lib:hibernate(?MODULE, wake_hib, [Parent, ServerName, MSL, Debug]);
-loop(Parent, ServerName, MSL, Debug, _) ->
- fetch_msg(Parent, ServerName, MSL, Debug, false).
+loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, true) ->
+ proc_lib:hibernate(?MODULE, wake_hib, [Parent, ServerName, MSL, HibernateAfterTimeout, Debug]);
+loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, _) ->
+ fetch_msg(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, false).
-wake_hib(Parent, ServerName, MSL, Debug) ->
- fetch_msg(Parent, ServerName, MSL, Debug, true).
+wake_hib(Parent, ServerName, MSL, HibernateAfterTimeout, Debug) ->
+ fetch_msg(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, true).
-fetch_msg(Parent, ServerName, MSL, Debug, Hib) ->
+fetch_msg(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, Hib) ->
receive
{system, From, Req} ->
sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
- [ServerName, MSL, Hib],Hib);
+ [ServerName, MSL, HibernateAfterTimeout, Hib],Hib);
{'EXIT', Parent, Reason} ->
terminate_server(Reason, Parent, MSL, ServerName);
Msg when Debug =:= [] ->
- handle_msg(Msg, Parent, ServerName, MSL, []);
+ handle_msg(Msg, Parent, ServerName, MSL, HibernateAfterTimeout, []);
Msg ->
Debug1 = sys:handle_debug(Debug, fun print_event/3,
ServerName, {in, Msg}),
- handle_msg(Msg, Parent, ServerName, MSL, Debug1)
+ handle_msg(Msg, Parent, ServerName, MSL, HibernateAfterTimeout, Debug1)
+ after HibernateAfterTimeout ->
+ loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, true)
end.
-handle_msg(Msg, Parent, ServerName, MSL, Debug) ->
+handle_msg(Msg, Parent, ServerName, MSL, HibernateAfterTimeout, Debug) ->
case Msg of
{notify, Event} ->
{Hib,MSL1} = server_notify(Event, handle_event, MSL, ServerName),
- loop(Parent, ServerName, MSL1, Debug, Hib);
+ loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
{_From, Tag, {sync_notify, Event}} ->
{Hib, MSL1} = server_notify(Event, handle_event, MSL, ServerName),
reply(Tag, ok),
- loop(Parent, ServerName, MSL1, Debug, Hib);
+ loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
{'EXIT', From, Reason} ->
MSL1 = handle_exit(From, Reason, MSL, ServerName),
- loop(Parent, ServerName, MSL1, Debug, false);
+ loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, false);
{_From, Tag, {call, Handler, Query}} ->
{Hib, Reply, MSL1} = server_call(Handler, Query, MSL, ServerName),
reply(Tag, Reply),
- loop(Parent, ServerName, MSL1, Debug, Hib);
+ loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
{_From, Tag, {add_handler, Handler, Args}} ->
{Hib, Reply, MSL1} = server_add_handler(Handler, Args, MSL),
reply(Tag, Reply),
- loop(Parent, ServerName, MSL1, Debug, Hib);
+ loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
{_From, Tag, {add_sup_handler, Handler, Args, SupP}} ->
{Hib, Reply, MSL1} = server_add_sup_handler(Handler, Args, MSL, SupP),
reply(Tag, Reply),
- loop(Parent, ServerName, MSL1, Debug, Hib);
+ loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
{_From, Tag, {delete_handler, Handler, Args}} ->
{Reply, MSL1} = server_delete_handler(Handler, Args, MSL,
ServerName),
reply(Tag, Reply),
- loop(Parent, ServerName, MSL1, Debug, false);
+ loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, false);
{_From, Tag, {swap_handler, Handler1, Args1, Handler2, Args2}} ->
{Hib, Reply, MSL1} = server_swap_handler(Handler1, Args1, Handler2,
Args2, MSL, ServerName),
reply(Tag, Reply),
- loop(Parent, ServerName, MSL1, Debug, Hib);
+ loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
{_From, Tag, {swap_sup_handler, Handler1, Args1, Handler2, Args2,
Sup}} ->
{Hib, Reply, MSL1} = server_swap_handler(Handler1, Args1, Handler2,
Args2, MSL, Sup, ServerName),
reply(Tag, Reply),
- loop(Parent, ServerName, MSL1, Debug, Hib);
+ loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib);
{_From, Tag, stop} ->
catch terminate_server(normal, Parent, MSL, ServerName),
reply(Tag, ok);
{_From, Tag, which_handlers} ->
reply(Tag, the_handlers(MSL)),
- loop(Parent, ServerName, MSL, Debug, false);
+ loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, false);
{_From, Tag, get_modules} ->
reply(Tag, get_modules(MSL)),
- loop(Parent, ServerName, MSL, Debug, false);
+ loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, false);
Other ->
{Hib, MSL1} = server_notify(Other, handle_info, MSL, ServerName),
- loop(Parent, ServerName, MSL1, Debug, Hib)
+ loop(Parent, ServerName, MSL1, HibernateAfterTimeout, Debug, Hib)
end.
terminate_server(Reason, Parent, MSL, ServerName) ->
@@ -355,18 +395,18 @@ terminate_supervised(Pid, Reason, MSL, SName) ->
%%-----------------------------------------------------------------
%% Callback functions for system messages handling.
%%-----------------------------------------------------------------
-system_continue(Parent, Debug, [ServerName, MSL, Hib]) ->
- loop(Parent, ServerName, MSL, Debug, Hib).
+system_continue(Parent, Debug, [ServerName, MSL, HibernateAfterTimeout, Hib]) ->
+ loop(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, Hib).
-spec system_terminate(_, _, _, [_]) -> no_return().
-system_terminate(Reason, Parent, _Debug, [ServerName, MSL, _Hib]) ->
+system_terminate(Reason, Parent, _Debug, [ServerName, MSL, _HibernateAfterTimeout, _Hib]) ->
terminate_server(Reason, Parent, MSL, ServerName).
%%-----------------------------------------------------------------
%% Module here is sent in the system msg change_code. It specifies
%% which module should be changed.
%%-----------------------------------------------------------------
-system_code_change([ServerName, MSL, Hib], Module, OldVsn, Extra) ->
+system_code_change([ServerName, MSL, HibernateAfterTimeout, Hib], Module, OldVsn, Extra) ->
MSL1 = lists:zf(fun(H) when H#handler.module =:= Module ->
{ok, NewState} =
Module:code_change(OldVsn,
@@ -375,12 +415,12 @@ system_code_change([ServerName, MSL, Hib], Module, OldVsn, Extra) ->
(_) -> true
end,
MSL),
- {ok, [ServerName, MSL1, Hib]}.
+ {ok, [ServerName, MSL1, HibernateAfterTimeout, Hib]}.
-system_get_state([_ServerName, MSL, _Hib]) ->
+system_get_state([_ServerName, MSL, _HibernateAfterTimeout, _Hib]) ->
{ok, [{Mod,Id,State} || #handler{module=Mod, id=Id, state=State} <- MSL]}.
-system_replace_state(StateFun, [ServerName, MSL, Hib]) ->
+system_replace_state(StateFun, [ServerName, MSL, HibernateAfterTimeout, Hib]) ->
{NMSL, NStates} =
lists:unzip([begin
Cur = {Mod,Id,State},
@@ -392,7 +432,7 @@ system_replace_state(StateFun, [ServerName, MSL, Hib]) ->
{HS, Cur}
end
end || #handler{module=Mod, id=Id, state=State}=HS <- MSL]),
- {ok, NStates, [ServerName, NMSL, Hib]}.
+ {ok, NStates, [ServerName, NMSL, HibernateAfterTimeout, Hib]}.
%%-----------------------------------------------------------------
%% Format debug messages. Print them as the call-back module sees
@@ -421,7 +461,7 @@ server_add_handler({Mod,Id}, Args, MSL) ->
Handler = #handler{module = Mod,
id = Id},
server_add_handler(Mod, Handler, Args, MSL);
-server_add_handler(Mod, Args, MSL) ->
+server_add_handler(Mod, Args, MSL) ->
Handler = #handler{module = Mod},
server_add_handler(Mod, Handler, Args, MSL).
@@ -446,7 +486,7 @@ server_add_sup_handler({Mod,Id}, Args, MSL, Parent) ->
id = Id,
supervised = Parent},
server_add_handler(Mod, Handler, Args, MSL);
-server_add_sup_handler(Mod, Args, MSL, Parent) ->
+server_add_sup_handler(Mod, Args, MSL, Parent) ->
link(Parent),
Handler = #handler{module = Mod,
supervised = Parent},
@@ -454,7 +494,7 @@ server_add_sup_handler(Mod, Args, MSL, Parent) ->
%% server_delete_handler(HandlerId, Args, MSL) -> {Ret, MSL'}
-server_delete_handler(HandlerId, Args, MSL, SName) ->
+server_delete_handler(HandlerId, Args, MSL, SName) ->
case split(HandlerId, MSL) of
{Mod, Handler, MSL1} ->
{do_terminate(Mod, Handler, Args,
@@ -511,7 +551,7 @@ split_and_terminate(HandlerId, Args, MSL, SName, Handler2, Sup) ->
%% server_notify(Event, Func, MSL, SName) -> MSL'
-server_notify(Event, Func, [Handler|T], SName) ->
+server_notify(Event, Func, [Handler|T], SName) ->
case server_update(Handler, Func, Event, SName) of
{ok, Handler1} ->
{Hib, NewHandlers} = server_notify(Event, Func, T, SName),
@@ -531,9 +571,9 @@ server_update(Handler1, Func, Event, SName) ->
Mod1 = Handler1#handler.module,
State = Handler1#handler.state,
case catch Mod1:Func(Event, State) of
- {ok, State1} ->
+ {ok, State1} ->
{ok, Handler1#handler{state = State1}};
- {ok, State1, hibernate} ->
+ {ok, State1, hibernate} ->
{hibernate, Handler1#handler{state = State1}};
{swap_handler, Args1, State1, Handler2, Args2} ->
do_swap(Mod1, Handler1, Args1, State1, Handler2, Args2, SName);
@@ -541,6 +581,10 @@ server_update(Handler1, Func, Event, SName) ->
do_terminate(Mod1, Handler1, remove_handler, State,
remove, SName, normal),
no;
+ {'EXIT', {undef, [{Mod1, handle_info, [_,_], _}|_]}} ->
+ error_logger:warning_msg("** Undefined handle_info in ~p~n"
+ "** Unhandled message: ~p~n", [Mod1, Event]),
+ {ok, Handler1};
Other ->
do_terminate(Mod1, Handler1, {error, Other}, State,
Event, SName, crash),
@@ -644,14 +688,14 @@ server_call_update(Handler1, Query, SName) ->
Mod1 = Handler1#handler.module,
State = Handler1#handler.state,
case catch Mod1:handle_call(Query, State) of
- {ok, Reply, State1} ->
+ {ok, Reply, State1} ->
{{ok, Handler1#handler{state = State1}}, Reply};
- {ok, Reply, State1, hibernate} ->
- {{hibernate, Handler1#handler{state = State1}},
+ {ok, Reply, State1, hibernate} ->
+ {{hibernate, Handler1#handler{state = State1}},
Reply};
{swap_handler, Reply, Args1, State1, Handler2, Args2} ->
{do_swap(Mod1,Handler1,Args1,State1,Handler2,Args2,SName), Reply};
- {remove_handler, Reply} ->
+ {remove_handler, Reply} ->
do_terminate(Mod1, Handler1, remove_handler, State,
remove, SName, normal),
{no, Reply};
@@ -662,9 +706,15 @@ server_call_update(Handler1, Query, SName) ->
end.
do_terminate(Mod, Handler, Args, State, LastIn, SName, Reason) ->
- Res = (catch Mod:terminate(Args, State)),
- report_terminate(Handler, Reason, Args, State, LastIn, SName, Res),
- Res.
+ case erlang:function_exported(Mod, terminate, 2) of
+ true ->
+ Res = (catch Mod:terminate(Args, State)),
+ report_terminate(Handler, Reason, Args, State, LastIn, SName, Res),
+ Res;
+ false ->
+ report_terminate(Handler, Reason, Args, State, LastIn, SName, ok),
+ ok
+ end.
report_terminate(Handler, crash, {error, Why}, State, LastIn, SName, _) ->
report_terminate(Handler, Why, State, LastIn, SName);
@@ -686,7 +736,7 @@ report_error(_Handler, normal, _, _, _) -> ok;
report_error(_Handler, shutdown, _, _, _) -> ok;
report_error(_Handler, {swapped,_,_}, _, _, _) -> ok;
report_error(Handler, Reason, State, LastIn, SName) ->
- Reason1 =
+ Reason1 =
case Reason of
{'EXIT',{undef,[{M,F,A,L}|MFAs]}} ->
case code:is_loaded(M) of
@@ -742,7 +792,7 @@ stop_handlers([], _) ->
[].
%% Message from the release_handler.
-%% The list of modules got to be a set !
+%% The list of modules got to be a set, i.e. no duplicate elements!
get_modules(MSL) ->
Mods = [Handler#handler.module || Handler <- MSL],
ordsets:to_list(ordsets:from_list(Mods)).
@@ -751,7 +801,7 @@ get_modules(MSL) ->
%% Status information
%%-----------------------------------------------------------------
format_status(Opt, StatusData) ->
- [PDict, SysState, Parent, _Debug, [ServerName, MSL, _Hib]] = StatusData,
+ [PDict, SysState, Parent, _Debug, [ServerName, MSL, _HibernateAfterTimeout, _Hib]] = StatusData,
Header = gen:format_status_header("Status for event handler",
ServerName),
FmtMSL = [case erlang:function_exported(Mod, format_status, 2) of
diff --git a/lib/stdlib/src/gen_fsm.erl b/lib/stdlib/src/gen_fsm.erl
index 6e7528fd98..9ef0ca818c 100644
--- a/lib/stdlib/src/gen_fsm.erl
+++ b/lib/stdlib/src/gen_fsm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -113,7 +113,7 @@
sync_send_all_state_event/2, sync_send_all_state_event/3,
reply/2,
start_timer/2,send_event_after/2,cancel_timer/1,
- enter_loop/4, enter_loop/5, enter_loop/6, wake_hib/6]).
+ enter_loop/4, enter_loop/5, enter_loop/6, wake_hib/7]).
%% Internal exports
-export([init_it/6,
@@ -124,6 +124,26 @@
system_replace_state/2,
format_status/2]).
+-deprecated({start, 3, next_major_release}).
+-deprecated({start, 4, next_major_release}).
+-deprecated({start_link, 3, next_major_release}).
+-deprecated({start_link, 4, next_major_release}).
+-deprecated({stop, 1, next_major_release}).
+-deprecated({stop, 3, next_major_release}).
+-deprecated({send_event, 2, next_major_release}).
+-deprecated({sync_send_event, 2, next_major_release}).
+-deprecated({sync_send_event, 3, next_major_release}).
+-deprecated({send_all_state_event, 2, next_major_release}).
+-deprecated({sync_send_all_state_event, 2, next_major_release}).
+-deprecated({sync_send_all_state_event, 3, next_major_release}).
+-deprecated({reply, 2, next_major_release}).
+-deprecated({start_timer, 2, next_major_release}).
+-deprecated({send_event_after, 2, next_major_release}).
+-deprecated({cancel_timer, 1, next_major_release}).
+-deprecated({enter_loop, 4, next_major_release}).
+-deprecated({enter_loop, 5, next_major_release}).
+-deprecated({enter_loop, 6, next_major_release}).
+
-import(error_logger, [format/2]).
%%% ---------------------------------------------------
@@ -169,7 +189,8 @@
State :: term(),
Status :: term().
--optional_callbacks([format_status/2]).
+-optional_callbacks(
+ [handle_info/3, terminate/3, code_change/4, format_status/2]).
%%% ---------------------------------------------------
%%% Starts a generic state machine.
@@ -273,7 +294,7 @@ start_timer(Time, Msg) ->
send_event_after(Time, Event) ->
erlang:start_timer(Time, self(), {'$gen_event', Event}).
-%% Returns the remaing time for the timer if Ref referred to
+%% Returns the remaining time for the timer if Ref referred to
%% an active timer/send_event_after, false otherwise.
cancel_timer(Ref) ->
case erlang:cancel_timer(Ref) of
@@ -308,7 +329,8 @@ enter_loop(Mod, Options, StateName, StateData, ServerName, Timeout) ->
Name = gen:get_proc_name(ServerName),
Parent = gen:get_parent(),
Debug = gen:debug_options(Name, Options),
- loop(Parent, Name, StateName, StateData, Mod, Timeout, Debug).
+ HibernateAfterTimeout = gen:hibernate_after(Options),
+ loop(Parent, Name, StateName, StateData, Mod, Timeout, HibernateAfterTimeout, Debug).
%%% ---------------------------------------------------
%%% Initiate the new process.
@@ -322,13 +344,14 @@ init_it(Starter, self, Name, Mod, Args, Options) ->
init_it(Starter, Parent, Name0, Mod, Args, Options) ->
Name = gen:name(Name0),
Debug = gen:debug_options(Name, Options),
- case catch Mod:init(Args) of
+ HibernateAfterTimeout = gen:hibernate_after(Options),
+ case catch Mod:init(Args) of
{ok, StateName, StateData} ->
proc_lib:init_ack(Starter, {ok, self()}),
- loop(Parent, Name, StateName, StateData, Mod, infinity, Debug);
+ loop(Parent, Name, StateName, StateData, Mod, infinity, HibernateAfterTimeout, Debug);
{ok, StateName, StateData, Timeout} ->
proc_lib:init_ack(Starter, {ok, self()}),
- loop(Parent, Name, StateName, StateData, Mod, Timeout, Debug);
+ loop(Parent, Name, StateName, StateData, Mod, Timeout, HibernateAfterTimeout, Debug);
{stop, Reason} ->
gen:unregister_name(Name0),
proc_lib:init_ack(Starter, {error, Reason}),
@@ -350,68 +373,77 @@ init_it(Starter, Parent, Name0, Mod, Args, Options) ->
%%-----------------------------------------------------------------
%% The MAIN loop
%%-----------------------------------------------------------------
-loop(Parent, Name, StateName, StateData, Mod, hibernate, Debug) ->
+loop(Parent, Name, StateName, StateData, Mod, hibernate, HibernateAfterTimeout, Debug) ->
proc_lib:hibernate(?MODULE,wake_hib,
- [Parent, Name, StateName, StateData, Mod,
+ [Parent, Name, StateName, StateData, Mod, HibernateAfterTimeout,
Debug]);
-loop(Parent, Name, StateName, StateData, Mod, Time, Debug) ->
+
+loop(Parent, Name, StateName, StateData, Mod, infinity, HibernateAfterTimeout, Debug) ->
+ receive
+ Msg ->
+ decode_msg(Msg,Parent, Name, StateName, StateData, Mod, infinity, HibernateAfterTimeout, Debug, false)
+ after HibernateAfterTimeout ->
+ loop(Parent, Name, StateName, StateData, Mod, hibernate, HibernateAfterTimeout, Debug)
+ end;
+
+loop(Parent, Name, StateName, StateData, Mod, Time, HibernateAfterTimeout, Debug) ->
Msg = receive
Input ->
Input
after Time ->
{'$gen_event', timeout}
end,
- decode_msg(Msg,Parent, Name, StateName, StateData, Mod, Time, Debug, false).
+ decode_msg(Msg,Parent, Name, StateName, StateData, Mod, Time, HibernateAfterTimeout, Debug, false).
-wake_hib(Parent, Name, StateName, StateData, Mod, Debug) ->
+wake_hib(Parent, Name, StateName, StateData, Mod, HibernateAfterTimeout, Debug) ->
Msg = receive
Input ->
Input
end,
- decode_msg(Msg, Parent, Name, StateName, StateData, Mod, hibernate, Debug, true).
+ decode_msg(Msg, Parent, Name, StateName, StateData, Mod, hibernate, HibernateAfterTimeout, Debug, true).
-decode_msg(Msg,Parent, Name, StateName, StateData, Mod, Time, Debug, Hib) ->
+decode_msg(Msg,Parent, Name, StateName, StateData, Mod, Time, HibernateAfterTimeout, Debug, Hib) ->
case Msg of
{system, From, Req} ->
sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
- [Name, StateName, StateData, Mod, Time], Hib);
+ [Name, StateName, StateData, Mod, Time, HibernateAfterTimeout], Hib);
{'EXIT', Parent, Reason} ->
terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug);
_Msg when Debug =:= [] ->
- handle_msg(Msg, Parent, Name, StateName, StateData, Mod, Time);
+ handle_msg(Msg, Parent, Name, StateName, StateData, Mod, Time, HibernateAfterTimeout);
_Msg ->
Debug1 = sys:handle_debug(Debug, fun print_event/3,
{Name, StateName}, {in, Msg}),
handle_msg(Msg, Parent, Name, StateName, StateData,
- Mod, Time, Debug1)
+ Mod, Time, HibernateAfterTimeout, Debug1)
end.
%%-----------------------------------------------------------------
%% Callback functions for system messages handling.
%%-----------------------------------------------------------------
-system_continue(Parent, Debug, [Name, StateName, StateData, Mod, Time]) ->
- loop(Parent, Name, StateName, StateData, Mod, Time, Debug).
+system_continue(Parent, Debug, [Name, StateName, StateData, Mod, Time, HibernateAfterTimeout]) ->
+ loop(Parent, Name, StateName, StateData, Mod, Time, HibernateAfterTimeout, Debug).
-spec system_terminate(term(), _, _, [term(),...]) -> no_return().
system_terminate(Reason, _Parent, Debug,
- [Name, StateName, StateData, Mod, _Time]) ->
+ [Name, StateName, StateData, Mod, _Time, _HibernateAfterTimeout]) ->
terminate(Reason, Name, [], Mod, StateName, StateData, Debug).
-system_code_change([Name, StateName, StateData, Mod, Time],
+system_code_change([Name, StateName, StateData, Mod, Time, HibernateAfterTimeout],
_Module, OldVsn, Extra) ->
case catch Mod:code_change(OldVsn, StateName, StateData, Extra) of
{ok, NewStateName, NewStateData} ->
- {ok, [Name, NewStateName, NewStateData, Mod, Time]};
+ {ok, [Name, NewStateName, NewStateData, Mod, Time, HibernateAfterTimeout]};
Else -> Else
end.
-system_get_state([_Name, StateName, StateData, _Mod, _Time]) ->
+system_get_state([_Name, StateName, StateData, _Mod, _Time, _HibernateAfterTimeout]) ->
{ok, {StateName, StateData}}.
-system_replace_state(StateFun, [Name, StateName, StateData, Mod, Time]) ->
+system_replace_state(StateFun, [Name, StateName, StateData, Mod, Time, HibernateAfterTimeout]) ->
Result = {NStateName, NStateData} = StateFun({StateName, StateData}),
- {ok, Result, [Name, NStateName, NStateData, Mod, Time]}.
+ {ok, Result, [Name, NStateName, NStateData, Mod, Time, HibernateAfterTimeout]}.
%%-----------------------------------------------------------------
%% Format debug messages. Print them as the call-back module sees
@@ -446,19 +478,19 @@ print_event(Dev, return, {Name, StateName}) ->
io:format(Dev, "*DBG* ~p switched to state ~w~n",
[Name, StateName]).
-handle_msg(Msg, Parent, Name, StateName, StateData, Mod, _Time) -> %No debug here
+handle_msg(Msg, Parent, Name, StateName, StateData, Mod, _Time, HibernateAfterTimeout) -> %No debug here
From = from(Msg),
case catch dispatch(Msg, Mod, StateName, StateData) of
{next_state, NStateName, NStateData} ->
- loop(Parent, Name, NStateName, NStateData, Mod, infinity, []);
+ loop(Parent, Name, NStateName, NStateData, Mod, infinity, HibernateAfterTimeout, []);
{next_state, NStateName, NStateData, Time1} ->
- loop(Parent, Name, NStateName, NStateData, Mod, Time1, []);
+ loop(Parent, Name, NStateName, NStateData, Mod, Time1, HibernateAfterTimeout, []);
{reply, Reply, NStateName, NStateData} when From =/= undefined ->
reply(From, Reply),
- loop(Parent, Name, NStateName, NStateData, Mod, infinity, []);
+ loop(Parent, Name, NStateName, NStateData, Mod, infinity, HibernateAfterTimeout, []);
{reply, Reply, NStateName, NStateData, Time1} when From =/= undefined ->
reply(From, Reply),
- loop(Parent, Name, NStateName, NStateData, Mod, Time1, []);
+ loop(Parent, Name, NStateName, NStateData, Mod, Time1, HibernateAfterTimeout, []);
{stop, Reason, NStateData} ->
terminate(Reason, Name, Msg, Mod, StateName, NStateData, []);
{stop, Reason, Reply, NStateData} when From =/= undefined ->
@@ -466,6 +498,10 @@ handle_msg(Msg, Parent, Name, StateName, StateData, Mod, _Time) -> %No debug her
StateName, NStateData, [])),
reply(From, Reply),
exit(R);
+ {'EXIT', {undef, [{Mod, handle_info, [_,_,_], _}|_]}} ->
+ error_logger:warning_msg("** Undefined handle_info in ~p~n"
+ "** Unhandled message: ~p~n", [Mod, Msg]),
+ loop(Parent, Name, StateName, StateData, Mod, infinity, HibernateAfterTimeout, []);
{'EXIT', What} ->
terminate(What, Name, Msg, Mod, StateName, StateData, []);
Reply ->
@@ -473,23 +509,23 @@ handle_msg(Msg, Parent, Name, StateName, StateData, Mod, _Time) -> %No debug her
Name, Msg, Mod, StateName, StateData, [])
end.
-handle_msg(Msg, Parent, Name, StateName, StateData, Mod, _Time, Debug) ->
+handle_msg(Msg, Parent, Name, StateName, StateData, Mod, _Time, HibernateAfterTimeout, Debug) ->
From = from(Msg),
case catch dispatch(Msg, Mod, StateName, StateData) of
{next_state, NStateName, NStateData} ->
Debug1 = sys:handle_debug(Debug, fun print_event/3,
{Name, NStateName}, return),
- loop(Parent, Name, NStateName, NStateData, Mod, infinity, Debug1);
+ loop(Parent, Name, NStateName, NStateData, Mod, infinity, HibernateAfterTimeout, Debug1);
{next_state, NStateName, NStateData, Time1} ->
Debug1 = sys:handle_debug(Debug, fun print_event/3,
{Name, NStateName}, return),
- loop(Parent, Name, NStateName, NStateData, Mod, Time1, Debug1);
+ loop(Parent, Name, NStateName, NStateData, Mod, Time1, HibernateAfterTimeout, Debug1);
{reply, Reply, NStateName, NStateData} when From =/= undefined ->
Debug1 = reply(Name, From, Reply, Debug, NStateName),
- loop(Parent, Name, NStateName, NStateData, Mod, infinity, Debug1);
+ loop(Parent, Name, NStateName, NStateData, Mod, infinity, HibernateAfterTimeout, Debug1);
{reply, Reply, NStateName, NStateData, Time1} when From =/= undefined ->
Debug1 = reply(Name, From, Reply, Debug, NStateName),
- loop(Parent, Name, NStateName, NStateData, Mod, Time1, Debug1);
+ loop(Parent, Name, NStateName, NStateData, Mod, Time1, HibernateAfterTimeout, Debug1);
{stop, Reason, NStateData} ->
terminate(Reason, Name, Msg, Mod, StateName, NStateData, Debug);
{stop, Reason, Reply, NStateData} when From =/= undefined ->
@@ -540,24 +576,30 @@ reply(Name, {To, Tag}, Reply, Debug, StateName) ->
-spec terminate(term(), _, _, atom(), _, _, _) -> no_return().
terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug) ->
- case catch Mod:terminate(Reason, StateName, StateData) of
- {'EXIT', R} ->
- FmtStateData = format_status(terminate, Mod, get(), StateData),
- error_info(R, Name, Msg, StateName, FmtStateData, Debug),
- exit(R);
- _ ->
- case Reason of
- normal ->
- exit(normal);
- shutdown ->
- exit(shutdown);
- {shutdown,_}=Shutdown ->
- exit(Shutdown);
+ case erlang:function_exported(Mod, terminate, 3) of
+ true ->
+ case catch Mod:terminate(Reason, StateName, StateData) of
+ {'EXIT', R} ->
+ FmtStateData = format_status(terminate, Mod, get(), StateData),
+ error_info(R, Name, Msg, StateName, FmtStateData, Debug),
+ exit(R);
_ ->
- FmtStateData = format_status(terminate, Mod, get(), StateData),
- error_info(Reason,Name,Msg,StateName,FmtStateData,Debug),
- exit(Reason)
- end
+ ok
+ end;
+ false ->
+ ok
+ end,
+ case Reason of
+ normal ->
+ exit(normal);
+ shutdown ->
+ exit(shutdown);
+ {shutdown,_}=Shutdown ->
+ exit(Shutdown);
+ _ ->
+ FmtStateData1 = format_status(terminate, Mod, get(), StateData),
+ error_info(Reason,Name,Msg,StateName,FmtStateData1,Debug),
+ exit(Reason)
end.
error_info(Reason, Name, Msg, StateName, StateData, Debug) ->
@@ -614,7 +656,7 @@ get_msg(Msg) -> Msg.
%% Status information
%%-----------------------------------------------------------------
format_status(Opt, StatusData) ->
- [PDict, SysState, Parent, Debug, [Name, StateName, StateData, Mod, _Time]] =
+ [PDict, SysState, Parent, Debug, [Name, StateName, StateData, Mod, _Time, _HibernateAfterTimeout]] =
StatusData,
Header = gen:format_status_header("Status for state machine",
Name),
diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl
index 5800aca66f..a3d53efd0d 100644
--- a/lib/stdlib/src/gen_server.erl
+++ b/lib/stdlib/src/gen_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -94,7 +94,7 @@
cast/2, reply/2,
abcast/2, abcast/3,
multi_call/2, multi_call/3, multi_call/4,
- enter_loop/3, enter_loop/4, enter_loop/5, wake_hib/5]).
+ enter_loop/3, enter_loop/4, enter_loop/5, wake_hib/6]).
%% System exports
-export([system_continue/3,
@@ -107,7 +107,9 @@
%% Internal exports
-export([init_it/6]).
--import(error_logger, [format/2]).
+-define(
+ STACKTRACE(),
+ try throw(ok) catch _ -> erlang:get_stacktrace() end).
%%%=========================================================================
%%% API
@@ -146,8 +148,8 @@
State :: term(),
Status :: term().
--optional_callbacks([format_status/2]).
-
+-optional_callbacks(
+ [handle_info/2, terminate/2, code_change/3, format_status/2]).
%%% -----------------------------------------------------------------
%%% Starts a generic server.
@@ -307,7 +309,8 @@ enter_loop(Mod, Options, State, ServerName, Timeout) ->
Name = gen:get_proc_name(ServerName),
Parent = gen:get_parent(),
Debug = gen:debug_options(Name, Options),
- loop(Parent, Name, State, Mod, Timeout, Debug).
+ HibernateAfterTimeout = gen:hibernate_after(Options),
+ loop(Parent, Name, State, Mod, Timeout, HibernateAfterTimeout, Debug).
%%%========================================================================
%%% Gen-callback functions
@@ -325,14 +328,16 @@ init_it(Starter, self, Name, Mod, Args, Options) ->
init_it(Starter, Parent, Name0, Mod, Args, Options) ->
Name = gen:name(Name0),
Debug = gen:debug_options(Name, Options),
- case catch Mod:init(Args) of
- {ok, State} ->
+ HibernateAfterTimeout = gen:hibernate_after(Options),
+
+ case init_it(Mod, Args) of
+ {ok, {ok, State}} ->
proc_lib:init_ack(Starter, {ok, self()}),
- loop(Parent, Name, State, Mod, infinity, Debug);
- {ok, State, Timeout} ->
+ loop(Parent, Name, State, Mod, infinity, HibernateAfterTimeout, Debug);
+ {ok, {ok, State, Timeout}} ->
proc_lib:init_ack(Starter, {ok, self()}),
- loop(Parent, Name, State, Mod, Timeout, Debug);
- {stop, Reason} ->
+ loop(Parent, Name, State, Mod, Timeout, HibernateAfterTimeout, Debug);
+ {ok, {stop, Reason}} ->
%% For consistency, we must make sure that the
%% registered name (if any) is unregistered before
%% the parent process is notified about the failure.
@@ -342,18 +347,25 @@ init_it(Starter, Parent, Name0, Mod, Args, Options) ->
gen:unregister_name(Name0),
proc_lib:init_ack(Starter, {error, Reason}),
exit(Reason);
- ignore ->
+ {ok, ignore} ->
gen:unregister_name(Name0),
proc_lib:init_ack(Starter, ignore),
exit(normal);
- {'EXIT', Reason} ->
- gen:unregister_name(Name0),
- proc_lib:init_ack(Starter, {error, Reason}),
- exit(Reason);
- Else ->
+ {ok, Else} ->
Error = {bad_return_value, Else},
proc_lib:init_ack(Starter, {error, Error}),
- exit(Error)
+ exit(Error);
+ {'EXIT', Class, Reason, Stacktrace} ->
+ gen:unregister_name(Name0),
+ proc_lib:init_ack(Starter, {error, terminate_reason(Class, Reason, Stacktrace)}),
+ erlang:raise(Class, Reason, Stacktrace)
+ end.
+init_it(Mod, Args) ->
+ try
+ {ok, Mod:init(Args)}
+ catch
+ throw:R -> {ok, R};
+ Class:R -> {'EXIT', Class, R, erlang:get_stacktrace()}
end.
%%%========================================================================
@@ -362,37 +374,46 @@ init_it(Starter, Parent, Name0, Mod, Args, Options) ->
%%% ---------------------------------------------------
%%% The MAIN loop.
%%% ---------------------------------------------------
-loop(Parent, Name, State, Mod, hibernate, Debug) ->
- proc_lib:hibernate(?MODULE,wake_hib,[Parent, Name, State, Mod, Debug]);
-loop(Parent, Name, State, Mod, Time, Debug) ->
+loop(Parent, Name, State, Mod, hibernate, HibernateAfterTimeout, Debug) ->
+ proc_lib:hibernate(?MODULE,wake_hib,[Parent, Name, State, Mod, HibernateAfterTimeout, Debug]);
+
+loop(Parent, Name, State, Mod, infinity, HibernateAfterTimeout, Debug) ->
+ receive
+ Msg ->
+ decode_msg(Msg, Parent, Name, State, Mod, infinity, HibernateAfterTimeout, Debug, false)
+ after HibernateAfterTimeout ->
+ loop(Parent, Name, State, Mod, hibernate, HibernateAfterTimeout, Debug)
+ end;
+
+loop(Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug) ->
Msg = receive
Input ->
Input
after Time ->
timeout
end,
- decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, false).
+ decode_msg(Msg, Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug, false).
-wake_hib(Parent, Name, State, Mod, Debug) ->
+wake_hib(Parent, Name, State, Mod, HibernateAfterTimeout, Debug) ->
Msg = receive
Input ->
Input
end,
- decode_msg(Msg, Parent, Name, State, Mod, hibernate, Debug, true).
+ decode_msg(Msg, Parent, Name, State, Mod, hibernate, HibernateAfterTimeout, Debug, true).
-decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, Hib) ->
+decode_msg(Msg, Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug, Hib) ->
case Msg of
{system, From, Req} ->
sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
- [Name, State, Mod, Time], Hib);
+ [Name, State, Mod, Time, HibernateAfterTimeout], Hib);
{'EXIT', Parent, Reason} ->
- terminate(Reason, Name, Msg, Mod, State, Debug);
+ terminate(Reason, ?STACKTRACE(), Name, undefined, Msg, Mod, State, Debug);
_Msg when Debug =:= [] ->
- handle_msg(Msg, Parent, Name, State, Mod);
+ handle_msg(Msg, Parent, Name, State, Mod, HibernateAfterTimeout);
_Msg ->
Debug1 = sys:handle_debug(Debug, fun print_event/3,
Name, {in, Msg}),
- handle_msg(Msg, Parent, Name, State, Mod, Debug1)
+ handle_msg(Msg, Parent, Name, State, Mod, HibernateAfterTimeout, Debug1)
end.
%%% ---------------------------------------------------
@@ -578,17 +599,11 @@ start_monitor(Node, Name) when is_atom(Node), is_atom(Name) ->
%% ---------------------------------------------------
%% Helper functions for try-catch of callbacks.
%% Returns the return value of the callback, or
-%% {'EXIT', ExitReason, ReportReason} (if an exception occurs)
-%%
-%% ExitReason is the reason that shall be used when the process
-%% terminates.
-%%
-%% ReportReason is the reason that shall be printed in the error
-%% report.
+%% {'EXIT', Class, Reason, Stack} (if an exception occurs)
%%
-%% These functions are introduced in order to add the stack trace in
-%% the error report produced when a callback is terminated with
-%% erlang:exit/1 (OTP-12263).
+%% The Class, Reason and Stack are given to erlang:raise/3
+%% to make sure proc_lib receives the proper reasons and
+%% stacktraces.
%% ---------------------------------------------------
try_dispatch({'$gen_cast', Msg}, Mod, State) ->
@@ -602,12 +617,18 @@ try_dispatch(Mod, Func, Msg, State) ->
catch
throw:R ->
{ok, R};
- error:R ->
- Stacktrace = erlang:get_stacktrace(),
- {'EXIT', {R, Stacktrace}, {R, Stacktrace}};
- exit:R ->
- Stacktrace = erlang:get_stacktrace(),
- {'EXIT', R, {R, Stacktrace}}
+ error:undef = R when Func == handle_info ->
+ case erlang:function_exported(Mod, handle_info, 2) of
+ false ->
+ error_logger:warning_msg("** Undefined handle_info in ~p~n"
+ "** Unhandled message: ~p~n",
+ [Mod, Msg]),
+ {ok, {noreply, State}};
+ true ->
+ {'EXIT', error, R, erlang:get_stacktrace()}
+ end;
+ Class:R ->
+ {'EXIT', Class, R, erlang:get_stacktrace()}
end.
try_handle_call(Mod, Msg, From, State) ->
@@ -616,26 +637,23 @@ try_handle_call(Mod, Msg, From, State) ->
catch
throw:R ->
{ok, R};
- error:R ->
- Stacktrace = erlang:get_stacktrace(),
- {'EXIT', {R, Stacktrace}, {R, Stacktrace}};
- exit:R ->
- Stacktrace = erlang:get_stacktrace(),
- {'EXIT', R, {R, Stacktrace}}
+ Class:R ->
+ {'EXIT', Class, R, erlang:get_stacktrace()}
end.
try_terminate(Mod, Reason, State) ->
- try
- {ok, Mod:terminate(Reason, State)}
- catch
- throw:R ->
- {ok, R};
- error:R ->
- Stacktrace = erlang:get_stacktrace(),
- {'EXIT', {R, Stacktrace}, {R, Stacktrace}};
- exit:R ->
- Stacktrace = erlang:get_stacktrace(),
- {'EXIT', R, {R, Stacktrace}}
+ case erlang:function_exported(Mod, terminate, 2) of
+ true ->
+ try
+ {ok, Mod:terminate(Reason, State)}
+ catch
+ throw:R ->
+ {ok, R};
+ Class:R ->
+ {'EXIT', Class, R, erlang:get_stacktrace()}
+ end;
+ false ->
+ {ok, ok}
end.
@@ -643,89 +661,91 @@ try_terminate(Mod, Reason, State) ->
%%% Message handling functions
%%% ---------------------------------------------------
-handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod) ->
+handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, HibernateAfterTimeout) ->
Result = try_handle_call(Mod, Msg, From, State),
case Result of
{ok, {reply, Reply, NState}} ->
reply(From, Reply),
- loop(Parent, Name, NState, Mod, infinity, []);
+ loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, []);
{ok, {reply, Reply, NState, Time1}} ->
reply(From, Reply),
- loop(Parent, Name, NState, Mod, Time1, []);
+ loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, []);
{ok, {noreply, NState}} ->
- loop(Parent, Name, NState, Mod, infinity, []);
+ loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, []);
{ok, {noreply, NState, Time1}} ->
- loop(Parent, Name, NState, Mod, Time1, []);
+ loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, []);
{ok, {stop, Reason, Reply, NState}} ->
- {'EXIT', R} =
- (catch terminate(Reason, Name, Msg, Mod, NState, [])),
- reply(From, Reply),
- exit(R);
- Other -> handle_common_reply(Other, Parent, Name, Msg, Mod, State)
+ try
+ terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, [])
+ after
+ reply(From, Reply)
+ end;
+ Other -> handle_common_reply(Other, Parent, Name, From, Msg, Mod, HibernateAfterTimeout, State)
end;
-handle_msg(Msg, Parent, Name, State, Mod) ->
+handle_msg(Msg, Parent, Name, State, Mod, HibernateAfterTimeout) ->
Reply = try_dispatch(Msg, Mod, State),
- handle_common_reply(Reply, Parent, Name, Msg, Mod, State).
+ handle_common_reply(Reply, Parent, Name, undefined, Msg, Mod, HibernateAfterTimeout, State).
-handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Debug) ->
+handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, HibernateAfterTimeout, Debug) ->
Result = try_handle_call(Mod, Msg, From, State),
case Result of
{ok, {reply, Reply, NState}} ->
Debug1 = reply(Name, From, Reply, NState, Debug),
- loop(Parent, Name, NState, Mod, infinity, Debug1);
+ loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, Debug1);
{ok, {reply, Reply, NState, Time1}} ->
Debug1 = reply(Name, From, Reply, NState, Debug),
- loop(Parent, Name, NState, Mod, Time1, Debug1);
+ loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, Debug1);
{ok, {noreply, NState}} ->
Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
{noreply, NState}),
- loop(Parent, Name, NState, Mod, infinity, Debug1);
+ loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, Debug1);
{ok, {noreply, NState, Time1}} ->
Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
{noreply, NState}),
- loop(Parent, Name, NState, Mod, Time1, Debug1);
+ loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, Debug1);
{ok, {stop, Reason, Reply, NState}} ->
- {'EXIT', R} =
- (catch terminate(Reason, Name, Msg, Mod, NState, Debug)),
- _ = reply(Name, From, Reply, NState, Debug),
- exit(R);
+ try
+ terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, Debug)
+ after
+ _ = reply(Name, From, Reply, NState, Debug)
+ end;
Other ->
- handle_common_reply(Other, Parent, Name, Msg, Mod, State, Debug)
+ handle_common_reply(Other, Parent, Name, From, Msg, Mod, HibernateAfterTimeout, State, Debug)
end;
-handle_msg(Msg, Parent, Name, State, Mod, Debug) ->
+handle_msg(Msg, Parent, Name, State, Mod, HibernateAfterTimeout, Debug) ->
Reply = try_dispatch(Msg, Mod, State),
- handle_common_reply(Reply, Parent, Name, Msg, Mod, State, Debug).
+ handle_common_reply(Reply, Parent, Name, undefined, Msg, Mod, HibernateAfterTimeout, State, Debug).
-handle_common_reply(Reply, Parent, Name, Msg, Mod, State) ->
+handle_common_reply(Reply, Parent, Name, From, Msg, Mod, HibernateAfterTimeout, State) ->
case Reply of
{ok, {noreply, NState}} ->
- loop(Parent, Name, NState, Mod, infinity, []);
+ loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, []);
{ok, {noreply, NState, Time1}} ->
- loop(Parent, Name, NState, Mod, Time1, []);
+ loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, []);
{ok, {stop, Reason, NState}} ->
- terminate(Reason, Name, Msg, Mod, NState, []);
- {'EXIT', ExitReason, ReportReason} ->
- terminate(ExitReason, ReportReason, Name, Msg, Mod, State, []);
+ terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, []);
+ {'EXIT', Class, Reason, Stacktrace} ->
+ terminate(Class, Reason, Stacktrace, Name, From, Msg, Mod, State, []);
{ok, BadReply} ->
- terminate({bad_return_value, BadReply}, Name, Msg, Mod, State, [])
+ terminate({bad_return_value, BadReply}, ?STACKTRACE(), Name, From, Msg, Mod, State, [])
end.
-handle_common_reply(Reply, Parent, Name, Msg, Mod, State, Debug) ->
+handle_common_reply(Reply, Parent, Name, From, Msg, Mod, HibernateAfterTimeout, State, Debug) ->
case Reply of
{ok, {noreply, NState}} ->
Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
{noreply, NState}),
- loop(Parent, Name, NState, Mod, infinity, Debug1);
+ loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, Debug1);
{ok, {noreply, NState, Time1}} ->
Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
{noreply, NState}),
- loop(Parent, Name, NState, Mod, Time1, Debug1);
+ loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, Debug1);
{ok, {stop, Reason, NState}} ->
- terminate(Reason, Name, Msg, Mod, NState, Debug);
- {'EXIT', ExitReason, ReportReason} ->
- terminate(ExitReason, ReportReason, Name, Msg, Mod, State, Debug);
+ terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, Debug);
+ {'EXIT', Class, Reason, Stacktrace} ->
+ terminate(Class, Reason, Stacktrace, Name, From, Msg, Mod, State, Debug);
{ok, BadReply} ->
- terminate({bad_return_value, BadReply}, Name, Msg, Mod, State, Debug)
+ terminate({bad_return_value, BadReply}, ?STACKTRACE(), Name, From, Msg, Mod, State, Debug)
end.
reply(Name, {To, Tag}, Reply, State, Debug) ->
@@ -737,26 +757,26 @@ reply(Name, {To, Tag}, Reply, State, Debug) ->
%%-----------------------------------------------------------------
%% Callback functions for system messages handling.
%%-----------------------------------------------------------------
-system_continue(Parent, Debug, [Name, State, Mod, Time]) ->
- loop(Parent, Name, State, Mod, Time, Debug).
+system_continue(Parent, Debug, [Name, State, Mod, Time, HibernateAfterTimeout]) ->
+ loop(Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug).
-spec system_terminate(_, _, _, [_]) -> no_return().
-system_terminate(Reason, _Parent, Debug, [Name, State, Mod, _Time]) ->
- terminate(Reason, Name, [], Mod, State, Debug).
+system_terminate(Reason, _Parent, Debug, [Name, State, Mod, _Time, _HibernateAfterTimeout]) ->
+ terminate(Reason, ?STACKTRACE(), Name, undefined, [], Mod, State, Debug).
-system_code_change([Name, State, Mod, Time], _Module, OldVsn, Extra) ->
+system_code_change([Name, State, Mod, Time, HibernateAfterTimeout], _Module, OldVsn, Extra) ->
case catch Mod:code_change(OldVsn, State, Extra) of
- {ok, NewState} -> {ok, [Name, NewState, Mod, Time]};
+ {ok, NewState} -> {ok, [Name, NewState, Mod, Time, HibernateAfterTimeout]};
Else -> Else
end.
-system_get_state([_Name, State, _Mod, _Time]) ->
+system_get_state([_Name, State, _Mod, _Time, _HibernateAfterTimeout]) ->
{ok, State}.
-system_replace_state(StateFun, [Name, State, Mod, Time]) ->
+system_replace_state(StateFun, [Name, State, Mod, Time, HibernateAfterTimeout]) ->
NState = StateFun(State),
- {ok, NState, [Name, NState, Mod, Time]}.
+ {ok, NState, [Name, NState, Mod, Time, HibernateAfterTimeout]}.
%%-----------------------------------------------------------------
%% Format debug messages. Print them as the call-back module sees
@@ -784,41 +804,64 @@ print_event(Dev, Event, Name) ->
%%% ---------------------------------------------------
%%% Terminate the server.
+%%%
+%%% terminate/8 is triggered by {stop, Reason} or bad
+%%% return values. The stacktrace is generated via the
+%%% ?STACKTRACE() macro and the ReportReason must not
+%%% be wrapped in tuples.
+%%%
+%%% terminate/9 is triggered in case of error/exit in
+%%% the user callback. In this case the report reason
+%%% always includes the user stacktrace.
+%%%
+%%% The reason received in the terminate/2 callbacks
+%%% always includes the stacktrace for errors and never
+%%% for exits.
%%% ---------------------------------------------------
--spec terminate(_, _, _, _, _, _) -> no_return().
-terminate(Reason, Name, Msg, Mod, State, Debug) ->
- terminate(Reason, Reason, Name, Msg, Mod, State, Debug).
+-spec terminate(_, _, _, _, _, _, _, _) -> no_return().
+terminate(Reason, Stacktrace, Name, From, Msg, Mod, State, Debug) ->
+ terminate(exit, Reason, Stacktrace, Reason, Name, From, Msg, Mod, State, Debug).
+
+-spec terminate(_, _, _, _, _, _, _, _, _) -> no_return().
+terminate(Class, Reason, Stacktrace, Name, From, Msg, Mod, State, Debug) ->
+ ReportReason = {Reason, Stacktrace},
+ terminate(Class, Reason, Stacktrace, ReportReason, Name, From, Msg, Mod, State, Debug).
--spec terminate(_, _, _, _, _, _, _) -> no_return().
-terminate(ExitReason, ReportReason, Name, Msg, Mod, State, Debug) ->
- Reply = try_terminate(Mod, ExitReason, State),
+-spec terminate(_, _, _, _, _, _, _, _, _, _) -> no_return().
+terminate(Class, Reason, Stacktrace, ReportReason, Name, From, Msg, Mod, State, Debug) ->
+ Reply = try_terminate(Mod, terminate_reason(Class, Reason, Stacktrace), State),
case Reply of
- {'EXIT', ExitReason1, ReportReason1} ->
+ {'EXIT', C, R, S} ->
FmtState = format_status(terminate, Mod, get(), State),
- error_info(ReportReason1, Name, Msg, FmtState, Debug),
- exit(ExitReason1);
+ error_info({R, S}, Name, From, Msg, FmtState, Debug),
+ erlang:raise(C, R, S);
_ ->
- case ExitReason of
- normal ->
- exit(normal);
- shutdown ->
- exit(shutdown);
- {shutdown,_}=Shutdown ->
- exit(Shutdown);
+ case {Class, Reason} of
+ {exit, normal} -> ok;
+ {exit, shutdown} -> ok;
+ {exit, {shutdown,_}} -> ok;
_ ->
FmtState = format_status(terminate, Mod, get(), State),
- error_info(ReportReason, Name, Msg, FmtState, Debug),
- exit(ExitReason)
+ error_info(ReportReason, Name, From, Msg, FmtState, Debug)
end
+ end,
+ case Stacktrace of
+ [] ->
+ erlang:Class(Reason);
+ _ ->
+ erlang:raise(Class, Reason, Stacktrace)
end.
-error_info(_Reason, application_controller, _Msg, _State, _Debug) ->
+terminate_reason(error, Reason, Stacktrace) -> {Reason, Stacktrace};
+terminate_reason(exit, Reason, _Stacktrace) -> Reason.
+
+error_info(_Reason, application_controller, _From, _Msg, _State, _Debug) ->
%% OTP-5811 Don't send an error report if it's the system process
%% application_controller which is terminating - let init take care
%% of it instead
ok;
-error_info(Reason, Name, Msg, State, Debug) ->
+error_info(Reason, Name, From, Msg, State, Debug) ->
Reason1 =
case Reason of
{undef,[{M,F,A,L}|MFAs]} ->
@@ -834,21 +877,42 @@ error_info(Reason, Name, Msg, State, Debug) ->
end
end;
_ ->
- Reason
+ error_logger:limit_term(Reason)
end,
- format("** Generic server ~p terminating \n"
- "** Last message in was ~p~n"
- "** When Server state == ~p~n"
- "** Reason for termination == ~n** ~p~n",
- [Name, Msg, State, Reason1]),
+ {ClientFmt, ClientArgs} = client_stacktrace(From),
+ LimitedState = error_logger:limit_term(State),
+ error_logger:format("** Generic server ~p terminating \n"
+ "** Last message in was ~p~n"
+ "** When Server state == ~p~n"
+ "** Reason for termination == ~n** ~p~n" ++ ClientFmt,
+ [Name, Msg, LimitedState, Reason1] ++ ClientArgs),
sys:print_log(Debug),
ok.
+client_stacktrace(undefined) ->
+ {"", []};
+client_stacktrace({From, _Tag}) ->
+ client_stacktrace(From);
+client_stacktrace(From) when is_pid(From), node(From) =:= node() ->
+ case process_info(From, [current_stacktrace, registered_name]) of
+ undefined ->
+ {"** Client ~p is dead~n", [From]};
+ [{current_stacktrace, Stacktrace}, {registered_name, []}] ->
+ {"** Client ~p stacktrace~n"
+ "** ~p~n",
+ [From, Stacktrace]};
+ [{current_stacktrace, Stacktrace}, {registered_name, Name}] ->
+ {"** Client ~p stacktrace~n"
+ "** ~p~n",
+ [Name, Stacktrace]}
+ end;
+client_stacktrace(From) when is_pid(From) ->
+ {"** Client ~p is remote on node ~p~n", [From, node(From)]}.
%%-----------------------------------------------------------------
%% Status information
%%-----------------------------------------------------------------
format_status(Opt, StatusData) ->
- [PDict, SysState, Parent, Debug, [Name, State, Mod, _Time]] = StatusData,
+ [PDict, SysState, Parent, Debug, [Name, State, Mod, _Time, _HibernateAfterTimeout]] = StatusData,
Header = gen:format_status_header("Status for generic server", Name),
Log = sys:get_debug(log, Debug, []),
Specfic = case format_status(Opt, Mod, PDict, State) of
diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl
index 23bddafeed..b5e9da1e66 100644
--- a/lib/stdlib/src/gen_statem.erl
+++ b/lib/stdlib/src/gen_statem.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2016. All Rights Reserved.
+%% Copyright Ericsson AB 2016-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
[start/3,start/4,start_link/3,start_link/4,
stop/1,stop/3,
cast/2,call/2,call/3,
- enter_loop/5,enter_loop/6,enter_loop/7,
+ enter_loop/4,enter_loop/5,enter_loop/6,
reply/1,reply/2]).
%% gen callbacks
@@ -44,15 +44,22 @@
-export(
[wakeup_from_hibernate/3]).
-%% Type exports for templates
+%% Type exports for templates and callback modules
-export_type(
[event_type/0,
- callback_mode/0,
- state_function_result/0,
- handle_event_result/0,
+ callback_mode_result/0,
+ init_result/1,
+ state_enter_result/1,
+ event_handler_result/1,
+ reply_action/0,
+ enter_action/0,
action/0]).
+%% Old types, not advertised
+-export_type(
+ [state_function_result/0,
+ handle_event_result/0]).
-%% Fix problem for doc build
+%% Type that is exported just to be documented
-export_type([transition_option/0]).
%%%==========================================================================
@@ -63,21 +70,26 @@
{To :: pid(), Tag :: term()}. % Reply-to specifier for call
-type state() ::
- state_name() | % For state callback function StateName/5
- term(). % For state callback function handle_event/5
+ state_name() | % For StateName/3 callback functions
+ term(). % For handle_event/4 callback function
-type state_name() :: atom().
-type data() :: term().
-type event_type() ::
- {'call',From :: from()} | 'cast' |
- 'info' | 'timeout' | 'internal'.
+ {'call',From :: from()} | 'cast' | 'info' |
+ 'timeout' | {'timeout', Name :: term()} | 'state_timeout' |
+ 'internal'.
+-type callback_mode_result() ::
+ callback_mode() | [callback_mode() | state_enter()].
-type callback_mode() :: 'state_functions' | 'handle_event_function'.
+-type state_enter() :: 'state_enter'.
-type transition_option() ::
- postpone() | hibernate() | event_timeout().
+ postpone() | hibernate() |
+ event_timeout() | generic_timeout() | state_timeout().
-type postpone() ::
%% If 'true' postpone the current event
%% and retry it when the state changes (=/=)
@@ -86,9 +98,17 @@
%% If 'true' hibernate the server instead of going into receive
boolean().
-type event_timeout() ::
- %% Generate a ('timeout', EventContent, ...) event after Time
+ %% Generate a ('timeout', EventContent, ...) event
%% unless some other event is delivered
- Time :: timeout().
+ Time :: timeout() | integer().
+-type generic_timeout() ::
+ %% Generate a ({'timeout',Name}, EventContent, ...) event
+ Time :: timeout() | integer().
+-type state_timeout() ::
+ %% Generate a ('state_timeout', EventContent, ...) event
+ %% unless the state is changed
+ Time :: timeout() | integer().
+-type timeout_option() :: {abs,Abs :: boolean()}.
-type action() ::
%% During a state change:
@@ -96,7 +116,7 @@
%% * All action()s are executed in order of apperance.
%% * Postponing the current event is performed
%% iff 'postpone' is 'true'.
- %% * A state timer is started iff 'timeout' is set.
+ %% * A state timeout is started iff 'timeout' is set.
%% * Pending events are handled or if there are
%% no pending events the server goes into receive
%% or hibernate (iff 'hibernate' is 'true')
@@ -108,100 +128,153 @@
'postpone' | % Set the postpone option
{'postpone', Postpone :: postpone()} |
%%
+ %% All 'next_event' events are kept in a list and then
+ %% inserted at state changes so the first in the
+ %% action() list is the first to be delivered.
+ {'next_event', % Insert event as the next to handle
+ EventType :: event_type(),
+ EventContent :: term()} |
+ enter_action().
+-type enter_action() ::
'hibernate' | % Set the hibernate option
{'hibernate', Hibernate :: hibernate()} |
%%
(Timeout :: event_timeout()) | % {timeout,Timeout}
- {'timeout', % Set the event timeout option
+ {'timeout', % Set the event_timeout option
Time :: event_timeout(), EventContent :: term()} |
+ {'timeout', % Set the event_timeout option
+ Time :: event_timeout(),
+ EventContent :: term(),
+ Options :: (timeout_option() | [timeout_option()])} |
%%
- reply_action() |
+ {{'timeout', Name :: term()}, % Set the generic_timeout option
+ Time :: generic_timeout(), EventContent :: term()} |
+ {{'timeout', Name :: term()}, % Set the generic_timeout option
+ Time :: generic_timeout(),
+ EventContent :: term(),
+ Options :: (timeout_option() | [timeout_option()])} |
%%
- %% All 'next_event' events are kept in a list and then
- %% inserted at state changes so the first in the
- %% action() list is the first to be delivered.
- {'next_event', % Insert event as the next to handle
- EventType :: event_type(),
- EventContent :: term()}.
+ {'state_timeout', % Set the state_timeout option
+ Time :: state_timeout(), EventContent :: term()} |
+ {'state_timeout', % Set the state_timeout option
+ Time :: state_timeout(),
+ EventContent :: term(),
+ Options :: (timeout_option() | [timeout_option()])} |
+ %%
+ reply_action().
-type reply_action() ::
{'reply', % Reply to a caller
From :: from(), Reply :: term()}.
+-type init_result(StateType) ::
+ {ok, State :: StateType, Data :: data()} |
+ {ok, State :: StateType, Data :: data(),
+ Actions :: [action()] | action()} |
+ 'ignore' |
+ {'stop', Reason :: term()}.
+
+%% Old, not advertised
-type state_function_result() ::
- {'next_state', % {next_state,NextStateName,NewData,[]}
- NextStateName :: state_name(),
+ event_handler_result(state_name()).
+-type handle_event_result() ::
+ event_handler_result(state()).
+%%
+-type state_enter_result(State) ::
+ {'next_state', % {next_state,NextState,NewData,[]}
+ State,
NewData :: data()} |
{'next_state', % State transition, maybe to the same state
- NextStateName :: state_name(),
+ State,
NewData :: data(),
- Actions :: [action()] | action()} |
- common_state_callback_result().
--type handle_event_result() ::
+ Actions :: [enter_action()] | enter_action()} |
+ state_callback_result(enter_action()).
+-type event_handler_result(StateType) ::
{'next_state', % {next_state,NextState,NewData,[]}
- NextState :: state(),
+ NextState :: StateType,
NewData :: data()} |
{'next_state', % State transition, maybe to the same state
- NextState :: state(),
+ NextState :: StateType,
NewData :: data(),
Actions :: [action()] | action()} |
- common_state_callback_result().
--type common_state_callback_result() ::
+ state_callback_result(action()).
+-type state_callback_result(ActionType) ::
+ {'keep_state', % {keep_state,NewData,[]}
+ NewData :: data()} |
+ {'keep_state', % Keep state, change data
+ NewData :: data(),
+ Actions :: [ActionType] | ActionType} |
+ 'keep_state_and_data' | % {keep_state_and_data,[]}
+ {'keep_state_and_data', % Keep state and data -> only actions
+ Actions :: [ActionType] | ActionType} |
+ %%
+ {'repeat_state', % {repeat_state,NewData,[]}
+ NewData :: data()} |
+ {'repeat_state', % Repeat state, change data
+ NewData :: data(),
+ Actions :: [ActionType] | ActionType} |
+ 'repeat_state_and_data' | % {repeat_state_and_data,[]}
+ {'repeat_state_and_data', % Repeat state and data -> only actions
+ Actions :: [ActionType] | ActionType} |
+ %%
'stop' | % {stop,normal}
{'stop', % Stop the server
Reason :: term()} |
{'stop', % Stop the server
Reason :: term(),
NewData :: data()} |
+ %%
{'stop_and_reply', % Reply then stop the server
Reason :: term(),
Replies :: [reply_action()] | reply_action()} |
{'stop_and_reply', % Reply then stop the server
Reason :: term(),
Replies :: [reply_action()] | reply_action(),
- NewData :: data()} |
- {'keep_state', % {keep_state,NewData,[]}
- NewData :: data()} |
- {'keep_state', % Keep state, change data
- NewData :: data(),
- Actions :: [action()] | action()} |
- 'keep_state_and_data' | % {keep_state_and_data,[]}
- {'keep_state_and_data', % Keep state and data -> only actions
- Actions :: [action()] | action()}.
+ NewData :: data()}.
%% The state machine init function. It is called only once and
%% the server is not running until this function has returned
%% an {ok, ...} tuple. Thereafter the state callbacks are called
%% for all events to this server.
--callback init(Args :: term()) ->
- {callback_mode(), state(), data()} |
- {callback_mode(), state(), data(), [action()] | action()} |
- 'ignore' |
- {'stop', Reason :: term()}.
+-callback init(Args :: term()) -> init_result(state()).
-%% Example state callback for callback_mode() =:= state_functions
-%% state name 'state_name'.
+%% This callback shall return the callback mode of the callback module.
%%
-%% In this mode all states has to be type state_name() i.e atom().
+%% It is called once after init/0 and code_change/4 but before
+%% the first state callback StateName/3 or handle_event/4.
+-callback callback_mode() -> callback_mode_result().
+
+%% Example state callback for StateName = 'state_name'
+%% when callback_mode() =:= state_functions.
+%%
+%% In this mode all states has to be of type state_name() i.e atom().
%%
-%% Note that state callbacks and only state callbacks have arity 5
-%% and that is intended.
+%% Note that the only callbacks that have arity 3 are these
+%% StateName/3 callbacks and terminate/3, so the state name
+%% 'terminate' is unusable in this mode.
-callback state_name(
- event_type(),
+ 'enter',
+ OldStateName :: state_name(),
+ Data :: data()) ->
+ state_enter_result('state_name');
+ (event_type(),
EventContent :: term(),
Data :: data()) ->
- state_function_result().
-%%
-%% State callback for callback_mode() =:= handle_event_function.
+ event_handler_result(state_name()).
%%
-%% Note that state callbacks and only state callbacks have arity 5
-%% and that is intended.
+%% State callback for all states
+%% when callback_mode() =:= handle_event_function.
-callback handle_event(
- event_type(),
+ 'enter',
+ OldState :: state(),
+ State, % Current state
+ Data :: data()) ->
+ state_enter_result(State);
+ (event_type(),
EventContent :: term(),
State :: state(), % Current state
Data :: data()) ->
- handle_event_result().
+ event_handler_result(state()).
%% Clean up before the server terminates.
-callback terminate(
@@ -219,9 +292,8 @@
OldState :: state(),
OldData :: data(),
Extra :: term()) ->
- {NewCallbackMode :: callback_mode(),
- NewState :: state(),
- NewData :: data()}.
+ {ok, NewState :: state(), NewData :: data()} |
+ (Reason :: term()).
%% Format the callback module state in some sensible that is
%% often condensed way. For StatusOption =:= 'normal' the perferred
@@ -236,44 +308,41 @@
StatusOption :: 'normal' | 'terminate'.
-optional_callbacks(
- [init/1, % One may use enter_loop/5,6,7 instead
- format_status/2, % Has got a default implementation
+ [format_status/2, % Has got a default implementation
+ terminate/3, % Has got a default implementation
+ code_change/4, % Only needed by advanced soft upgrade
%%
- state_name/3, % Example for callback_mode =:= state_functions:
- %% there has to be a StateName/5 callback function for every StateName.
+ state_name/3, % Example for callback_mode() =:= state_functions:
+ %% there has to be a StateName/3 callback function
+ %% for every StateName in your state machine but the state name
+ %% 'state_name' does of course not have to be used.
%%
- handle_event/4]). % For callback_mode =:= handle_event_function
+ handle_event/4 % For callback_mode() =:= handle_event_function
+ ]).
%% Type validation functions
callback_mode(CallbackMode) ->
case CallbackMode of
- state_functions ->
- true;
- handle_event_function ->
- true;
- _ ->
- false
+ state_functions -> true;
+ handle_event_function -> true;
+ _ -> false
end.
%%
-from({Pid,_}) when is_pid(Pid) ->
- true;
-from(_) ->
- false.
+from({Pid,_}) when is_pid(Pid) -> true;
+from(_) -> false.
%%
event_type({call,From}) ->
from(From);
event_type(Type) ->
case Type of
- cast ->
- true;
- info ->
- true;
- timeout ->
- true;
- internal ->
- true;
- _ ->
- false
+ {call,From} -> from(From);
+ cast -> true;
+ info -> true;
+ timeout -> true;
+ state_timeout -> true;
+ internal -> true;
+ {timeout,_} -> true;
+ _ -> false
end.
@@ -300,9 +369,12 @@ event_type(Type) ->
Dbgs ::
['trace' | 'log' | 'statistics' | 'debug'
| {'logfile', string()}]}.
+-type hibernate_after_opt() ::
+ {'hibernate_after', HibernateAfterTimeout :: timeout()}.
-type start_opt() ::
debug_opt()
| {'timeout', Time :: timeout()}
+ | hibernate_after_opt()
| {'spawn_opt', [proc_lib:spawn_option()]}.
-type start_ret() :: {'ok', pid()} | 'ignore' | {'error', term()}.
@@ -378,53 +450,79 @@ call(ServerRef, Request) ->
-spec call(
ServerRef :: server_ref(),
Request :: term(),
- Timeout :: timeout()) ->
+ Timeout ::
+ timeout() |
+ {'clean_timeout',T :: timeout()} |
+ {'dirty_timeout',T :: timeout()}) ->
Reply :: term().
-call(ServerRef, Request, infinity) ->
- try gen:call(ServerRef, '$gen_call', Request, infinity) of
- {ok,Reply} ->
- Reply
- catch
- Class:Reason ->
- erlang:raise(
- Class,
- {Reason,{?MODULE,call,[ServerRef,Request,infinity]}},
- erlang:get_stacktrace())
- end;
call(ServerRef, Request, Timeout) ->
- %% Call server through proxy process to dodge any late reply
- Ref = make_ref(),
- Self = self(),
- Pid = spawn(
- fun () ->
- Self !
- try gen:call(
- ServerRef, '$gen_call', Request, Timeout) of
- Result ->
- {Ref,Result}
- catch Class:Reason ->
- {Ref,Class,Reason,erlang:get_stacktrace()}
- end
- end),
- Mref = monitor(process, Pid),
- receive
- {Ref,Result} ->
- demonitor(Mref, [flush]),
- case Result of
+ case parse_timeout(Timeout) of
+ {dirty_timeout,T} ->
+ try gen:call(ServerRef, '$gen_call', Request, T) of
{ok,Reply} ->
Reply
+ catch
+ Class:Reason ->
+ erlang:raise(
+ Class,
+ {Reason,{?MODULE,call,[ServerRef,Request,Timeout]}},
+ erlang:get_stacktrace())
+ end;
+ {clean_timeout,T} ->
+ %% Call server through proxy process to dodge any late reply
+ Ref = make_ref(),
+ Self = self(),
+ Pid = spawn(
+ fun () ->
+ Self !
+ try gen:call(
+ ServerRef, '$gen_call', Request, T) of
+ Result ->
+ {Ref,Result}
+ catch Class:Reason ->
+ {Ref,Class,Reason,
+ erlang:get_stacktrace()}
+ end
+ end),
+ Mref = monitor(process, Pid),
+ receive
+ {Ref,Result} ->
+ demonitor(Mref, [flush]),
+ case Result of
+ {ok,Reply} ->
+ Reply
+ end;
+ {Ref,Class,Reason,Stacktrace} ->
+ demonitor(Mref, [flush]),
+ erlang:raise(
+ Class,
+ {Reason,{?MODULE,call,[ServerRef,Request,Timeout]}},
+ Stacktrace);
+ {'DOWN',Mref,_,_,Reason} ->
+ %% There is a theoretical possibility that the
+ %% proxy process gets killed between try--of and !
+ %% so this clause is in case of that
+ exit(Reason)
end;
- {Ref,Class,Reason,Stacktrace} ->
- demonitor(Mref, [flush]),
- erlang:raise(
- Class,
- {Reason,{?MODULE,call,[ServerRef,Request,Timeout]}},
- Stacktrace);
- {'DOWN',Mref,_,_,Reason} ->
- %% There is a theoretical possibility that the
- %% proxy process gets killed between try--of and !
- %% so this clause is in case of that
- exit(Reason)
+ Error when is_atom(Error) ->
+ erlang:error(Error, [ServerRef,Request,Timeout])
+ end.
+
+parse_timeout(Timeout) ->
+ case Timeout of
+ {clean_timeout,infinity} ->
+ {dirty_timeout,infinity};
+ {clean_timeout,_} ->
+ Timeout;
+ {dirty_timeout,_} ->
+ Timeout;
+ {_,_} ->
+ %% Be nice and throw a badarg for speling errors
+ badarg;
+ infinity ->
+ {dirty_timeout,infinity};
+ T ->
+ {clean_timeout,T}
end.
%% Reply from a state machine callback to whom awaits in call/2
@@ -449,44 +547,36 @@ reply({To,Tag}, Reply) when is_pid(To) ->
%% started by proc_lib into a state machine using
%% the same arguments as you would have returned from init/1
-spec enter_loop(
- Module :: module(), Opts :: [debug_opt()],
- CallbackMode :: callback_mode(),
+ Module :: module(), Opts :: [debug_opt() | hibernate_after_opt()],
State :: state(), Data :: data()) ->
no_return().
-enter_loop(Module, Opts, CallbackMode, State, Data) ->
- enter_loop(Module, Opts, CallbackMode, State, Data, self()).
+enter_loop(Module, Opts, State, Data) ->
+ enter_loop(Module, Opts, State, Data, self()).
%%
-spec enter_loop(
- Module :: module(), Opts :: [debug_opt()],
- CallbackMode :: callback_mode(),
+ Module :: module(), Opts :: [debug_opt() | hibernate_after_opt()],
State :: state(), Data :: data(),
Server_or_Actions ::
server_name() | pid() | [action()]) ->
no_return().
-enter_loop(Module, Opts, CallbackMode, State, Data, Server_or_Actions) ->
+enter_loop(Module, Opts, State, Data, Server_or_Actions) ->
if
is_list(Server_or_Actions) ->
- enter_loop(
- Module, Opts, CallbackMode, State, Data,
- self(), Server_or_Actions);
+ enter_loop(Module, Opts, State, Data, self(), Server_or_Actions);
true ->
- enter_loop(
- Module, Opts, CallbackMode, State, Data,
- Server_or_Actions, [])
+ enter_loop(Module, Opts, State, Data, Server_or_Actions, [])
end.
%%
-spec enter_loop(
- Module :: module(), Opts :: [debug_opt()],
- CallbackMode :: callback_mode(),
+ Module :: module(), Opts :: [debug_opt() | hibernate_after_opt()],
State :: state(), Data :: data(),
Server :: server_name() | pid(),
Actions :: [action()] | action()) ->
no_return().
-enter_loop(Module, Opts, CallbackMode, State, Data, Server, Actions) ->
+enter_loop(Module, Opts, State, Data, Server, Actions) ->
is_atom(Module) orelse error({atom,Module}),
- callback_mode(CallbackMode) orelse error({callback_mode,CallbackMode}),
Parent = gen:get_parent(),
- enter(Module, Opts, CallbackMode, State, Data, Server, Actions, Parent).
+ enter(Module, Opts, State, Data, Server, Actions, Parent).
%%---------------------------------------------------------------------------
%% API helpers
@@ -514,12 +604,14 @@ send(Proc, Msg) ->
end.
%% Here the init_it/6 and enter_loop/5,6,7 functions converge
-enter(Module, Opts, CallbackMode, State, Data, Server, Actions, Parent) ->
+enter(Module, Opts, State, Data, Server, Actions, Parent) ->
%% The values should already have been type checked
Name = gen:get_proc_name(Server),
Debug = gen:debug_options(Name, Opts),
- P = Events = [],
- Event = {internal,initial_state},
+ HibernateAfterTimeout = gen:hibernate_after(Opts),
+ Events = [],
+ P = [],
+ Event = {internal,init_state},
%% We enforce {postpone,false} to ensure that
%% our fake Event gets discarded, thought it might get logged
NewActions =
@@ -529,21 +621,51 @@ enter(Module, Opts, CallbackMode, State, Data, Server, Actions, Parent) ->
true ->
[Actions,{postpone,false}]
end,
+ TimerRefs = #{},
+ %% Key: timer ref
+ %% Value: the timer type i.e the timer's event type
+ %%
+ TimerTypes = #{},
+ %% Key: timer type i.e the timer's event type
+ %% Value: timer ref
+ %%
+ %% We add a timer to both timer_refs and timer_types
+ %% when we start it. When we request an asynchronous
+ %% timer cancel we remove it from timer_types. When
+ %% the timer cancel message arrives we remove it from
+ %% timer_refs.
+ %%
+ Hibernate = false,
+ CancelTimers = 0,
S = #{
- callback_mode => CallbackMode,
+ callback_mode => undefined,
+ state_enter => false,
module => Module,
name => Name,
- %% All fields below will be replaced according to the arguments to
- %% loop_event_actions/10 when it finally loops back to loop/3
state => State,
data => Data,
postponed => P,
- hibernate => false,
- timer => undefined},
+ %%
+ %% The following fields are finally set from to the arguments to
+ %% loop_event_actions/9 when it finally loops back to loop/3
+ %% in loop_event_result/11
+ timer_refs => TimerRefs,
+ timer_types => TimerTypes,
+ hibernate => Hibernate,
+ hibernate_after => HibernateAfterTimeout,
+ cancel_timers => CancelTimers
+ },
NewDebug = sys_debug(Debug, S, State, {enter,Event,State}),
- loop_event_actions(
- Parent, NewDebug, S, Events,
- State, Data, P, Event, State, NewActions).
+ case call_callback_mode(S) of
+ {ok,NewS} ->
+ loop_event_actions(
+ Parent, NewDebug, NewS,
+ Events, Event, State, Data, NewActions, true);
+ {Class,Reason,Stacktrace} ->
+ terminate(
+ Class, Reason, Stacktrace, NewDebug,
+ S, [Event|Events])
+ end.
%%%==========================================================================
%%% gen callbacks
@@ -558,9 +680,17 @@ init_it(Starter, Parent, ServerRef, Module, Args, Opts) ->
Result ->
init_result(Starter, Parent, ServerRef, Module, Result, Opts);
Class:Reason ->
+ Stacktrace = erlang:get_stacktrace(),
+ Name = gen:get_proc_name(ServerRef),
gen:unregister_name(ServerRef),
proc_lib:init_ack(Starter, {error,Reason}),
- erlang:raise(Class, Reason, erlang:get_stacktrace())
+ error_info(
+ Class, Reason, Stacktrace,
+ #{name => Name,
+ callback_mode => undefined,
+ state_enter => false},
+ [], [], undefined),
+ erlang:raise(Class, Reason, Stacktrace)
end.
%%---------------------------------------------------------------------------
@@ -568,30 +698,12 @@ init_it(Starter, Parent, ServerRef, Module, Args, Opts) ->
init_result(Starter, Parent, ServerRef, Module, Result, Opts) ->
case Result of
- {CallbackMode,State,Data} ->
- case callback_mode(CallbackMode) of
- true ->
- proc_lib:init_ack(Starter, {ok,self()}),
- enter(
- Module, Opts, CallbackMode, State, Data,
- ServerRef, [], Parent);
- false ->
- Error = {callback_mode,CallbackMode},
- proc_lib:init_ack(Starter, {error,Error}),
- exit(Error)
- end;
- {CallbackMode,State,Data,Actions} ->
- case callback_mode(CallbackMode) of
- true ->
- proc_lib:init_ack(Starter, {ok,self()}),
- enter(
- Module, Opts, CallbackMode, State, Data,
- ServerRef, Actions, Parent);
- false ->
- Error = {callback_mode,CallbackMode},
- proc_lib:init_ack(Starter, {error,Error}),
- exit(Error)
- end;
+ {ok,State,Data} ->
+ proc_lib:init_ack(Starter, {ok,self()}),
+ enter(Module, Opts, State, Data, ServerRef, [], Parent);
+ {ok,State,Data,Actions} ->
+ proc_lib:init_ack(Starter, {ok,self()}),
+ enter(Module, Opts, State, Data, ServerRef, Actions, Parent);
{stop,Reason} ->
gen:unregister_name(ServerRef),
proc_lib:init_ack(Starter, {error,Reason}),
@@ -601,8 +713,16 @@ init_result(Starter, Parent, ServerRef, Module, Result, Opts) ->
proc_lib:init_ack(Starter, ignore),
exit(normal);
_ ->
- Error = {bad_return_value,Result},
+ Name = gen:get_proc_name(ServerRef),
+ gen:unregister_name(ServerRef),
+ Error = {bad_return_from_init,Result},
proc_lib:init_ack(Starter, {error,Error}),
+ error_info(
+ error, Error, ?STACKTRACE(),
+ #{name => Name,
+ callback_mode => undefined,
+ state_enter => false},
+ [], [], undefined),
exit(Error)
end.
@@ -612,12 +732,8 @@ init_result(Starter, Parent, ServerRef, Module, Result, Opts) ->
system_continue(Parent, Debug, S) ->
loop(Parent, Debug, S).
-system_terminate(
- Reason, _Parent, Debug,
- #{state := State, data := Data, postponed := P} = S) ->
- terminate(
- exit, Reason, ?STACKTRACE(),
- Debug, S, [], State, Data, P).
+system_terminate(Reason, _Parent, Debug, S) ->
+ terminate(exit, Reason, ?STACKTRACE(), Debug, S, []).
system_code_change(
#{module := Module,
@@ -630,11 +746,9 @@ system_code_change(
Result -> Result
end
of
- {NewCallbackMode,NewState,NewData} ->
- callback_mode(NewCallbackMode) orelse
- error({callback_mode,NewCallbackMode}),
+ {ok,NewState,NewData} ->
{ok,
- S#{callback_mode := NewCallbackMode,
+ S#{callback_mode := undefined,
state := NewState,
data := NewData}};
{ok,_} = Error ->
@@ -656,7 +770,7 @@ system_replace_state(
format_status(
Opt,
[PDict,SysState,Parent,Debug,
- #{name := Name, postponed := P, state := State, data := Data} = S]) ->
+ #{name := Name, postponed := P} = S]) ->
Header = gen:format_status_header("Status for state machine", Name),
Log = sys:get_debug(log, Debug, []),
[{header,Header},
@@ -665,7 +779,7 @@ format_status(
{"Parent",Parent},
{"Logged Events",Log},
{"Postponed",P}]} |
- case format_status(Opt, PDict, S, State, Data) of
+ case format_status(Opt, PDict, S) of
L when is_list(L) -> L;
T -> [T]
end].
@@ -675,14 +789,18 @@ format_status(
%% them, not as the real erlang messages. Use trace for that.
%%---------------------------------------------------------------------------
-print_event(Dev, {in,Event}, {Name,_}) ->
+print_event(Dev, {in,Event}, {Name,State}) ->
+ io:format(
+ Dev, "*DBG* ~p receive ~s in state ~p~n",
+ [Name,event_string(Event),State]);
+print_event(Dev, {out,Reply,{To,_Tag}}, {Name,State}) ->
io:format(
- Dev, "*DBG* ~p received ~s~n",
- [Name,event_string(Event)]);
-print_event(Dev, {out,Reply,{To,_Tag}}, {Name,_}) ->
+ Dev, "*DBG* ~p send ~p to ~p from state ~p~n",
+ [Name,Reply,To,State]);
+print_event(Dev, {terminate,Reason}, {Name,State}) ->
io:format(
- Dev, "*DBG* ~p sent ~p to ~p~n",
- [Name,Reply,To]);
+ Dev, "*DBG* ~p terminate ~p in state ~p~n",
+ [Name,Reason,State]);
print_event(Dev, {Tag,Event,NextState}, {Name,State}) ->
StateString =
case NextState of
@@ -726,22 +844,22 @@ wakeup_from_hibernate(Parent, Debug, S) ->
%% and detours through sys:handle_system_message/7 and proc_lib:hibernate/3
%% Entry point for system_continue/3
-loop(Parent, Debug, #{hibernate := Hibernate} = S) ->
- case Hibernate of
- true ->
- %% Does not return but restarts process at
- %% wakeup_from_hibernate/3 that jumps to loop_receive/3
- proc_lib:hibernate(
- ?MODULE, wakeup_from_hibernate, [Parent,Debug,S]),
- error(
- {should_not_have_arrived_here_but_instead_in,
- {wakeup_from_hibernate,3}});
- false ->
- loop_receive(Parent, Debug, S)
- end.
+loop(Parent, Debug, #{hibernate := true, cancel_timers := 0} = S) ->
+ loop_hibernate(Parent, Debug, S);
+loop(Parent, Debug, S) ->
+ loop_receive(Parent, Debug, S).
+
+loop_hibernate(Parent, Debug, S) ->
+ %% Does not return but restarts process at
+ %% wakeup_from_hibernate/3 that jumps to loop_receive/3
+ proc_lib:hibernate(
+ ?MODULE, wakeup_from_hibernate, [Parent,Debug,S]),
+ error(
+ {should_not_have_arrived_here_but_instead_in,
+ {wakeup_from_hibernate,3}}).
%% Entry point for wakeup_from_hibernate/3
-loop_receive(Parent, Debug, #{timer := Timer} = S) ->
+loop_receive(Parent, Debug, #{hibernate_after := HibernateAfterTimeout} = S) ->
receive
Msg ->
case Msg of
@@ -750,36 +868,87 @@ loop_receive(Parent, Debug, #{timer := Timer} = S) ->
%% Does not return but tail recursively calls
%% system_continue/3 that jumps to loop/3
sys:handle_system_msg(
- Req, Pid, Parent, ?MODULE, Debug, S, Hibernate);
+ Req, Pid, Parent, ?MODULE, Debug, S,
+ Hibernate);
{'EXIT',Parent,Reason} = EXIT ->
- #{state := State, data := Data, postponed := P} = S,
- %% EXIT is not a 2-tuple and therefore
- %% not an event and has no event_type(),
- %% but this will stand out in the crash report...
- terminate(
- exit, Reason, ?STACKTRACE(),
- Debug, S, [EXIT], State, Data, P);
- {timeout,Timer,Content} when Timer =/= undefined ->
- loop_receive_result(
- Parent, Debug, S, {timeout,Content});
- _ ->
- %% Cancel Timer if running
- case Timer of
- undefined ->
- ok;
+ %% EXIT is not a 2-tuple therefore
+ %% not an event but this will stand out
+ %% in the crash report...
+ Q = [EXIT],
+ terminate(exit, Reason, ?STACKTRACE(), Debug, S, Q);
+ {timeout,TimerRef,TimerMsg} ->
+ #{timer_refs := TimerRefs,
+ timer_types := TimerTypes,
+ hibernate := Hibernate} = S,
+ case TimerRefs of
+ #{TimerRef := TimerType} ->
+ %% We know of this timer; is it a running
+ %% timer or a timer being cancelled that
+ %% managed to send a late timeout message?
+ case TimerTypes of
+ #{TimerType := TimerRef} ->
+ %% The timer type maps back to this
+ %% timer ref, so it was a running timer
+ Event = {TimerType,TimerMsg},
+ %% Unregister the triggered timeout
+ NewTimerRefs =
+ maps:remove(TimerRef, TimerRefs),
+ NewTimerTypes =
+ maps:remove(TimerType, TimerTypes),
+ loop_receive_result(
+ Parent, Debug,
+ S#{
+ timer_refs := NewTimerRefs,
+ timer_types := NewTimerTypes},
+ Hibernate,
+ Event);
+ _ ->
+ %% This was a late timeout message
+ %% from timer being cancelled, so
+ %% ignore it and expect a cancel_timer
+ %% msg shortly
+ loop_receive(Parent, Debug, S)
+ end;
+ _ ->
+ %% Not our timer; present it as an event
+ Event = {info,Msg},
+ loop_receive_result(
+ Parent, Debug, S, Hibernate, Event)
+ end;
+ {cancel_timer,TimerRef,_} ->
+ #{timer_refs := TimerRefs,
+ cancel_timers := CancelTimers,
+ hibernate := Hibernate} = S,
+ case TimerRefs of
+ #{TimerRef := _} ->
+ %% We must have requested a cancel
+ %% of this timer so it is already
+ %% removed from TimerTypes
+ NewTimerRefs =
+ maps:remove(TimerRef, TimerRefs),
+ NewCancelTimers = CancelTimers - 1,
+ NewS =
+ S#{
+ timer_refs := NewTimerRefs,
+ cancel_timers := NewCancelTimers},
+ if
+ Hibernate =:= true, NewCancelTimers =:= 0 ->
+ %% No more cancel_timer msgs to expect;
+ %% we can hibernate
+ loop_hibernate(Parent, Debug, NewS);
+ NewCancelTimers >= 0 -> % Assert
+ loop_receive(Parent, Debug, NewS)
+ end;
_ ->
- case erlang:cancel_timer(Timer) of
- TimeLeft when is_integer(TimeLeft) ->
- ok;
- false ->
- receive
- {timeout,Timer,_} ->
- ok
- after 0 ->
- ok
- end
- end
- end,
+ %% Not our cancel_timer msg;
+ %% present it as an event
+ Event = {info,Msg},
+ loop_receive_result(
+ Parent, Debug, S, Hibernate, Event)
+ end;
+ _ ->
+ %% External msg
+ #{hibernate := Hibernate} = S,
Event =
case Msg of
{'$gen_call',From,Request} ->
@@ -789,388 +958,690 @@ loop_receive(Parent, Debug, #{timer := Timer} = S) ->
_ ->
{info,Msg}
end,
- loop_receive_result(Parent, Debug, S, Event)
+ loop_receive_result(
+ Parent, Debug, S, Hibernate, Event)
end
+ after
+ HibernateAfterTimeout ->
+ loop_hibernate(Parent, Debug, S)
end.
loop_receive_result(
Parent, Debug,
#{state := State,
- data := Data,
- postponed := P} = S,
- Event) ->
- %% The engine state map S is now dismantled
- %% and will not be restored until we return to loop/3.
- %%
- %% The fields 'callback_mode', 'module', and 'name' are still valid.
- %% The fields 'state', 'data', and 'postponed' are held in arguments.
- %% The fields 'timer' and 'hibernate' will be recalculated.
- %%
+ timer_types := TimerTypes, cancel_timers := CancelTimers} = S,
+ Hibernate, Event) ->
+ %% From now the 'hibernate' field in S is invalid
+ %% and will be restored when looping back
+ %% in loop_event_result/11
NewDebug = sys_debug(Debug, S, State, {in,Event}),
- %% Here the queue of not yet handled events is created
+ %% Here is the queue of not yet handled events created
Events = [],
- Hibernate = false,
- loop_event(
- Parent, NewDebug, S, Events, State, Data, P, Event, Hibernate).
-
-%% Process the event queue, or if it is empty
-%% loop back to loop/3 to receive a new event
-loop_events(
- Parent, Debug, S, [Event|Events],
- State, Data, P, Hibernate, _Timeout) ->
- %%
- %% If there was a state timer requested we just ignore that
- %% since we have events to handle which cancels the timer
- loop_event(
- Parent, Debug, S, Events, State, Data, P, Event, Hibernate);
-loop_events(
- Parent, Debug, S, [],
- State, Data, P, Hibernate, Timeout) ->
- case Timeout of
- {timeout,0,EventContent} ->
- %% Immediate timeout - simulate it
- %% so we do not get the timeout message
- %% after any received event
- loop_event(
- Parent, Debug, S, [],
- State, Data, P, {timeout,EventContent}, Hibernate);
- {timeout,Time,EventContent} ->
- %% Actually start a timer
- Timer = erlang:start_timer(Time, self(), EventContent),
- loop_events_done(
- Parent, Debug, S, Timer, State, Data, P, Hibernate);
- undefined ->
- %% No state timeout has been requested
- Timer = undefined,
- loop_events_done(
- Parent, Debug, S, Timer, State, Data, P, Hibernate)
+ %% Cancel any running event timer
+ case
+ cancel_timer_by_type(timeout, TimerTypes, CancelTimers)
+ of
+ {_,CancelTimers} ->
+ %% No timer cancelled
+ loop_event(Parent, NewDebug, S, Events, Event, Hibernate);
+ {NewTimerTypes,NewCancelTimers} ->
+ %% The timer is removed from NewTimerTypes but
+ %% remains in TimerRefs until we get
+ %% the cancel_timer msg
+ NewS =
+ S#{
+ timer_types := NewTimerTypes,
+ cancel_timers := NewCancelTimers},
+ loop_event(Parent, NewDebug, NewS, Events, Event, Hibernate)
end.
-%%
-loop_events_done(Parent, Debug, S, Timer, State, Data, P, Hibernate) ->
- NewS =
- S#{
- state := State,
- data := Data,
- postponed := P,
- hibernate := Hibernate,
- timer := Timer},
- loop(Parent, Debug, NewS).
+%% Entry point for handling an event, received or enqueued
loop_event(
Parent, Debug,
- #{callback_mode := CallbackMode,
- module := Module} = S,
- Events,
- State, Data, P, {Type,Content} = Event, Hibernate) ->
+ #{state := State, data := Data} = S,
+ Events, {Type,Content} = Event, Hibernate) ->
%%
- %% If Hibernate is true here it can only be
+ %% If (this old) Hibernate is true here it can only be
%% because it was set from an event action
- %% and we did not go into hibernation since there
- %% were events in queue, so we do what the user
- %% might depend on i.e collect garbage which
+ %% and we did not go into hibernation since there were
+ %% events in queue, so we do what the user
+ %% might rely on i.e collect garbage which
%% would have happened if we actually hibernated
%% and immediately was awakened
Hibernate andalso garbage_collect(),
+ case call_state_function(S, Type, Content, State, Data) of
+ {ok,Result,NewS} ->
+ {NextState,NewData,Actions,EnterCall} =
+ parse_event_result(
+ true, Debug, NewS,
+ Events, Event, State, Data, Result),
+ loop_event_actions(
+ Parent, Debug, NewS,
+ Events, Event, NextState, NewData, Actions, EnterCall);
+ {Class,Reason,Stacktrace} ->
+ terminate(
+ Class, Reason, Stacktrace, Debug, S,
+ [Event|Events])
+ end.
+
+loop_event_actions(
+ Parent, Debug,
+ #{state := State, state_enter := StateEnter} = S,
+ Events, Event, NextState, NewData,
+ Actions, EnterCall) ->
+ %% Hibernate is reborn here as false being
+ %% the default value from parse_actions/4
+ case parse_actions(Debug, S, State, Actions) of
+ {ok,NewDebug,Hibernate,TimeoutsR,Postpone,NextEventsR} ->
+ if
+ StateEnter, EnterCall ->
+ loop_event_enter(
+ Parent, NewDebug, S,
+ Events, Event, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR);
+ true ->
+ loop_event_result(
+ Parent, NewDebug, S,
+ Events, Event, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR)
+ end;
+ {Class,Reason,Stacktrace} ->
+ terminate(
+ Class, Reason, Stacktrace, Debug, S,
+ [Event|Events])
+ end.
+
+loop_event_enter(
+ Parent, Debug, #{state := State} = S,
+ Events, Event, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR) ->
+ case call_state_function(S, enter, State, NextState, NewData) of
+ {ok,Result,NewS} ->
+ case parse_event_result(
+ false, Debug, NewS,
+ Events, Event, NextState, NewData, Result) of
+ {_,NewerData,Actions,EnterCall} ->
+ loop_event_enter_actions(
+ Parent, Debug, NewS,
+ Events, Event, NextState, NewerData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR,
+ Actions, EnterCall)
+ end;
+ {Class,Reason,Stacktrace} ->
+ terminate(
+ Class, Reason, Stacktrace, Debug,
+ S#{
+ state := NextState,
+ data := NewData,
+ hibernate := Hibernate},
+ [Event|Events])
+ end.
+
+loop_event_enter_actions(
+ Parent, Debug, #{state_enter := StateEnter} = S,
+ Events, Event, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR,
+ Actions, EnterCall) ->
+ case
+ parse_enter_actions(
+ Debug, S, NextState, Actions, Hibernate, TimeoutsR)
+ of
+ {ok,NewDebug,NewHibernate,NewTimeoutsR,_,_} ->
+ if
+ StateEnter, EnterCall ->
+ loop_event_enter(
+ Parent, NewDebug, S,
+ Events, Event, NextState, NewData,
+ NewHibernate, NewTimeoutsR, Postpone, NextEventsR);
+ true ->
+ loop_event_result(
+ Parent, NewDebug, S,
+ Events, Event, NextState, NewData,
+ NewHibernate, NewTimeoutsR, Postpone, NextEventsR)
+ end;
+ {Class,Reason,Stacktrace} ->
+ terminate(
+ Class, Reason, Stacktrace, Debug,
+ S#{
+ state := NextState,
+ data := NewData,
+ hibernate := Hibernate},
+ [Event|Events])
+ end.
+
+loop_event_result(
+ Parent, Debug_0,
+ #{state := State, postponed := P_0,
+ timer_refs := TimerRefs_0, timer_types := TimerTypes_0,
+ cancel_timers := CancelTimers_0} = S_0,
+ Events_0, Event_0, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR) ->
%%
+ %% All options have been collected and next_events are buffered.
+ %% Do the actual state transition.
+ %%
+ {Debug_1,P_1} = % Move current event to postponed if Postpone
+ case Postpone of
+ true ->
+ {sys_debug(Debug_0, S_0, State, {postpone,Event_0,State}),
+ [Event_0|P_0]};
+ false ->
+ {sys_debug(Debug_0, S_0, State, {consume,Event_0,State}),
+ P_0}
+ end,
+ {Events_1,P_2,{TimerTypes_1,CancelTimers_1}} =
+ %% Move all postponed events to queue and cancel the
+ %% state timeout if the state changes
+ if
+ NextState =:= State ->
+ {Events_0,P_1,{TimerTypes_0,CancelTimers_0}};
+ true ->
+ {lists:reverse(P_1, Events_0),
+ [],
+ cancel_timer_by_type(
+ state_timeout, TimerTypes_0, CancelTimers_0)}
+ %% The state timer is removed from TimerTypes_1
+ %% but remains in TimerRefs_0 until we get
+ %% the cancel_timer msg
+ end,
+ {TimerRefs_2,TimerTypes_2,CancelTimers_2,TimeoutEvents} =
+ %% Stop and start non-event timers
+ parse_timers(TimerRefs_0, TimerTypes_1, CancelTimers_1, TimeoutsR),
+ %% Place next events last in reversed queue
+ Events_2R = lists:reverse(Events_1, NextEventsR),
+ %% Enqueue immediate timeout events and start event timer
+ Events_3R = prepend_timeout_events(TimeoutEvents, Events_2R),
+ S_1 =
+ S_0#{
+ state := NextState,
+ data := NewData,
+ postponed := P_2,
+ timer_refs := TimerRefs_2,
+ timer_types := TimerTypes_2,
+ cancel_timers := CancelTimers_2,
+ hibernate := Hibernate},
+ case lists:reverse(Events_3R) of
+ [] ->
+ %% Get a new event
+ loop(Parent, Debug_1, S_1);
+ [Event|Events] ->
+ %% Loop until out of enqueued events
+ loop_event(Parent, Debug_1, S_1, Events, Event, Hibernate)
+ end.
+
+
+%%---------------------------------------------------------------------------
+%% Server loop helpers
+
+call_callback_mode(#{module := Module} = S) ->
+ try Module:callback_mode() of
+ CallbackMode ->
+ callback_mode_result(S, CallbackMode)
+ catch
+ CallbackMode ->
+ callback_mode_result(S, CallbackMode);
+ Class:Reason ->
+ {Class,Reason,erlang:get_stacktrace()}
+ end.
+
+callback_mode_result(S, CallbackMode) ->
+ case
+ parse_callback_mode(
+ if
+ is_atom(CallbackMode) ->
+ [CallbackMode];
+ true ->
+ CallbackMode
+ end, undefined, false)
+ of
+ {undefined,_} ->
+ {error,
+ {bad_return_from_callback_mode,CallbackMode},
+ ?STACKTRACE()};
+ {CBMode,StateEnter} ->
+ {ok,
+ S#{
+ callback_mode := CBMode,
+ state_enter := StateEnter}}
+ end.
+
+parse_callback_mode([], CBMode, StateEnter) ->
+ {CBMode,StateEnter};
+parse_callback_mode([H|T], CBMode, StateEnter) ->
+ case callback_mode(H) of
+ true ->
+ parse_callback_mode(T, H, StateEnter);
+ false ->
+ case H of
+ state_enter ->
+ parse_callback_mode(T, CBMode, true);
+ _ ->
+ {undefined,StateEnter}
+ end
+ end;
+parse_callback_mode(_, _CBMode, StateEnter) ->
+ {undefined,StateEnter}.
+
+
+call_state_function(
+ #{callback_mode := undefined} = S, Type, Content, State, Data) ->
+ case call_callback_mode(S) of
+ {ok,NewS} ->
+ call_state_function(NewS, Type, Content, State, Data);
+ Error ->
+ Error
+ end;
+call_state_function(
+ #{callback_mode := CallbackMode, module := Module} = S,
+ Type, Content, State, Data) ->
try
case CallbackMode of
state_functions ->
Module:State(Type, Content, Data);
handle_event_function ->
Module:handle_event(Type, Content, State, Data)
- end of
+ end
+ of
Result ->
- loop_event_result(
- Parent, Debug, S, Events, State, Data, P, Event, Result)
+ {ok,Result,S}
catch
Result ->
- loop_event_result(
- Parent, Debug, S, Events, State, Data, P, Event, Result);
- error:badarg when CallbackMode =:= state_functions ->
- case erlang:get_stacktrace() of
- [{erlang,apply,[Module,State,_],_}|Stacktrace] ->
- Args = [Type,Content,Data],
- terminate(
- error,
- {undef_state_function,{Module,State,Args}},
- Stacktrace,
- Debug, S, [Event|Events], State, Data, P);
- Stacktrace ->
- terminate(
- error, badarg, Stacktrace,
- Debug, S, [Event|Events], State, Data, P)
- end;
- error:undef ->
- %% Process an undef to check for the simple mistake
- %% of calling a nonexistent state function
- case erlang:get_stacktrace() of
- [{Module,State,
- [Type,Content,Data]=Args,
- _}
- |Stacktrace]
- when CallbackMode =:= state_functions ->
- terminate(
- error,
- {undef_state_function,{Module,State,Args}},
- Stacktrace,
- Debug, S, [Event|Events], State, Data, P);
- [{Module,handle_event,
- [Type,Content,State,Data]=Args,
- _}
- |Stacktrace]
- when CallbackMode =:= handle_event_function ->
- terminate(
- error,
- {undef_state_function,{Module,handle_event,Args}},
- Stacktrace,
- Debug, S, [Event|Events], State, Data, P);
- Stacktrace ->
- terminate(
- error, undef, Stacktrace,
- Debug, S, [Event|Events], State, Data, P)
- end;
+ {ok,Result,S};
Class:Reason ->
- Stacktrace = erlang:get_stacktrace(),
- terminate(
- Class, Reason, Stacktrace,
- Debug, S, [Event|Events], State, Data, P)
+ {Class,Reason,erlang:get_stacktrace()}
end.
+
%% Interpret all callback return variants
-loop_event_result(
- Parent, Debug, S, Events, State, Data, P, Event, Result) ->
+parse_event_result(
+ AllowStateChange, Debug, S,
+ Events, Event, State, Data, Result) ->
case Result of
stop ->
terminate(
- exit, normal, ?STACKTRACE(),
- Debug, S, [Event|Events], State, Data, P);
+ exit, normal, ?STACKTRACE(), Debug,
+ S#{state := State, data := Data},
+ [Event|Events]);
{stop,Reason} ->
terminate(
- exit, Reason, ?STACKTRACE(),
- Debug, S, [Event|Events], State, Data, P);
+ exit, Reason, ?STACKTRACE(), Debug,
+ S#{state := State, data := Data},
+ [Event|Events]);
{stop,Reason,NewData} ->
terminate(
- exit, Reason, ?STACKTRACE(),
- Debug, S, [Event|Events], State, NewData, P);
+ exit, Reason, ?STACKTRACE(), Debug,
+ S#{state := State, data := NewData},
+ [Event|Events]);
+ %%
{stop_and_reply,Reason,Replies} ->
- Q = [Event|Events],
reply_then_terminate(
- exit, Reason, ?STACKTRACE(),
- Debug, S, Q, State, Data, P, Replies);
+ exit, Reason, ?STACKTRACE(), Debug,
+ S#{state := State, data := Data},
+ [Event|Events], Replies);
{stop_and_reply,Reason,Replies,NewData} ->
- Q = [Event|Events],
reply_then_terminate(
- exit, Reason, ?STACKTRACE(),
- Debug, S, Q, State, NewData, P, Replies);
- {next_state,NextState,NewData} ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, []);
- {next_state,NextState,NewData,Actions} ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, Actions);
+ exit, Reason, ?STACKTRACE(), Debug,
+ S#{state := State, data := NewData},
+ [Event|Events], Replies);
+ %%
+ {next_state,State,NewData} ->
+ {State,NewData,[],false};
+ {next_state,NextState,NewData} when AllowStateChange ->
+ {NextState,NewData,[],true};
+ {next_state,State,NewData,Actions} ->
+ {State,NewData,Actions,false};
+ {next_state,NextState,NewData,Actions} when AllowStateChange ->
+ {NextState,NewData,Actions,true};
+ %%
{keep_state,NewData} ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, State, []);
+ {State,NewData,[],false};
{keep_state,NewData,Actions} ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, State, Actions);
+ {State,NewData,Actions,false};
keep_state_and_data ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, Data, P, Event, State, []);
+ {State,Data,[],false};
{keep_state_and_data,Actions} ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, Data, P, Event, State, Actions);
+ {State,Data,Actions,false};
+ %%
+ {repeat_state,NewData} ->
+ {State,NewData,[],true};
+ {repeat_state,NewData,Actions} ->
+ {State,NewData,Actions,true};
+ repeat_state_and_data ->
+ {State,Data,[],true};
+ {repeat_state_and_data,Actions} ->
+ {State,Data,Actions,true};
+ %%
_ ->
terminate(
- error, {bad_return_value,Result}, ?STACKTRACE(),
- Debug, S, [Event|Events], State, Data, P)
+ error,
+ {bad_return_from_state_function,Result},
+ ?STACKTRACE(), Debug,
+ S#{state := State, data := Data},
+ [Event|Events])
end.
-loop_event_actions(
- Parent, Debug, S, Events, State, NewData, P, Event, NextState, Actions) ->
- Postpone = false, % Shall we postpone this event; boolean()
+
+parse_enter_actions(Debug, S, State, Actions, Hibernate, TimeoutsR) ->
+ Postpone = forbidden,
+ NextEventsR = forbidden,
+ parse_actions(
+ Debug, S, State, listify(Actions),
+ Hibernate, TimeoutsR, Postpone, NextEventsR).
+
+parse_actions(Debug, S, State, Actions) ->
Hibernate = false,
- Timeout = undefined,
- NextEvents = [],
- loop_event_actions(
- Parent, Debug, S, Events, State, NewData, P, Event, NextState,
- if
- is_list(Actions) ->
- Actions;
- true ->
- [Actions]
- end,
- Postpone, Hibernate, Timeout, NextEvents).
+ TimeoutsR = [infinity], %% Will cancel event timer
+ Postpone = false,
+ NextEventsR = [],
+ parse_actions(
+ Debug, S, State, listify(Actions),
+ Hibernate, TimeoutsR, Postpone, NextEventsR).
%%
-%% Process all actions
-loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, [Action|Actions],
- Postpone, Hibernate, Timeout, NextEvents) ->
+parse_actions(
+ Debug, _S, _State, [],
+ Hibernate, TimeoutsR, Postpone, NextEventsR) ->
+ {ok,Debug,Hibernate,TimeoutsR,Postpone,NextEventsR};
+parse_actions(
+ Debug, S, State, [Action|Actions],
+ Hibernate, TimeoutsR, Postpone, NextEventsR) ->
case Action of
%% Actual actions
{reply,From,Reply} ->
case from(From) of
true ->
NewDebug = do_reply(Debug, S, State, From, Reply),
- loop_event_actions(
- Parent, NewDebug, S, Events,
- State, NewData, P, Event, NextState, Actions,
- Postpone, Hibernate, Timeout, NextEvents);
+ parse_actions(
+ NewDebug, S, State, Actions,
+ Hibernate, TimeoutsR, Postpone, NextEventsR);
false ->
- terminate(
- error, {bad_action,Action}, ?STACKTRACE(),
- Debug, S, [Event|Events], State, NewData, P)
+ {error,
+ {bad_action_from_state_function,Action},
+ ?STACKTRACE()}
end;
+ %%
+ %% Actions that set options
+ {hibernate,NewHibernate} when is_boolean(NewHibernate) ->
+ parse_actions(
+ Debug, S, State, Actions,
+ NewHibernate, TimeoutsR, Postpone, NextEventsR);
+ hibernate ->
+ NewHibernate = true,
+ parse_actions(
+ Debug, S, State, Actions,
+ NewHibernate, TimeoutsR, Postpone, NextEventsR);
+ %%
+ {postpone,NewPostpone}
+ when is_boolean(NewPostpone), Postpone =/= forbidden ->
+ parse_actions(
+ Debug, S, State, Actions,
+ Hibernate, TimeoutsR, NewPostpone, NextEventsR);
+ postpone when Postpone =/= forbidden ->
+ NewPostpone = true,
+ parse_actions(
+ Debug, S, State, Actions,
+ Hibernate, TimeoutsR, NewPostpone, NextEventsR);
+ %%
{next_event,Type,Content} ->
case event_type(Type) of
+ true when NextEventsR =/= forbidden ->
+ NewDebug =
+ sys_debug(Debug, S, State, {in,{Type,Content}}),
+ parse_actions(
+ NewDebug, S, State, Actions,
+ Hibernate, TimeoutsR, Postpone,
+ [{Type,Content}|NextEventsR]);
+ _ ->
+ {error,
+ {bad_action_from_state_function,Action},
+ ?STACKTRACE()}
+ end;
+ %%
+ {{timeout,_},_,_} = Timeout ->
+ parse_actions_timeout(
+ Debug, S, State, Actions,
+ Hibernate, TimeoutsR, Postpone, NextEventsR, Timeout);
+ {{timeout,_},_,_,_} = Timeout ->
+ parse_actions_timeout(
+ Debug, S, State, Actions,
+ Hibernate, TimeoutsR, Postpone, NextEventsR, Timeout);
+ {timeout,_,_} = Timeout ->
+ parse_actions_timeout(
+ Debug, S, State, Actions,
+ Hibernate, TimeoutsR, Postpone, NextEventsR, Timeout);
+ {timeout,_,_,_} = Timeout ->
+ parse_actions_timeout(
+ Debug, S, State, Actions,
+ Hibernate, TimeoutsR, Postpone, NextEventsR, Timeout);
+ {state_timeout,_,_} = Timeout ->
+ parse_actions_timeout(
+ Debug, S, State, Actions,
+ Hibernate, TimeoutsR, Postpone, NextEventsR, Timeout);
+ {state_timeout,_,_,_} = Timeout ->
+ parse_actions_timeout(
+ Debug, S, State, Actions,
+ Hibernate, TimeoutsR, Postpone, NextEventsR, Timeout);
+ Time ->
+ parse_actions_timeout(
+ Debug, S, State, Actions,
+ Hibernate, TimeoutsR, Postpone, NextEventsR, Time)
+ end.
+
+parse_actions_timeout(
+ Debug, S, State, Actions,
+ Hibernate, TimeoutsR, Postpone, NextEventsR, Timeout) ->
+ case Timeout of
+ {TimerType,Time,TimerMsg,TimerOpts} ->
+ case validate_timer_args(Time, listify(TimerOpts)) of
true ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, Actions,
- Postpone, Hibernate, Timeout,
- [{Type,Content}|NextEvents]);
+ parse_actions(
+ Debug, S, State, Actions,
+ Hibernate, [Timeout|TimeoutsR],
+ Postpone, NextEventsR);
false ->
- terminate(
- error, {bad_action,Action}, ?STACKTRACE(),
- Debug, S, [Event|Events], State, NewData, P)
+ NewTimeout = {TimerType,Time,TimerMsg},
+ parse_actions(
+ Debug, S, State, Actions,
+ Hibernate, [NewTimeout|TimeoutsR],
+ Postpone, NextEventsR);
+ error ->
+ {error,
+ {bad_action_from_state_function,Timeout},
+ ?STACKTRACE()}
end;
- %% Actions that set options
- {postpone,NewPostpone} when is_boolean(NewPostpone) ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, Actions,
- NewPostpone, Hibernate, Timeout, NextEvents);
- {postpone,_} ->
- terminate(
- error, {bad_action,Action}, ?STACKTRACE(),
- Debug, S, [Event|Events], State, NewData, P);
- postpone ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, Actions,
- true, Hibernate, Timeout, NextEvents);
- {hibernate,NewHibernate} when is_boolean(NewHibernate) ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, Actions,
- Postpone, NewHibernate, Timeout, NextEvents);
- {hibernate,_} ->
- terminate(
- error, {bad_action,Action}, ?STACKTRACE(),
- Debug, S, [Event|Events], State, NewData, P);
- hibernate ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, Actions,
- Postpone, true, Timeout, NextEvents);
- {timeout,infinity,_} -> % Clear timer - it will never trigger
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, Actions,
- Postpone, Hibernate, undefined, NextEvents);
- {timeout,Time,_} = NewTimeout when is_integer(Time), Time >= 0 ->
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, Actions,
- Postpone, Hibernate, NewTimeout, NextEvents);
- {timeout,_,_} ->
- terminate(
- error, {bad_action,Action}, ?STACKTRACE(),
- Debug, S, [Event|Events], State, NewData, P);
- infinity -> % Clear timer - it will never trigger
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, Actions,
- Postpone, Hibernate, undefined, NextEvents);
- Time when is_integer(Time), Time >= 0 ->
- NewTimeout = {timeout,Time,Time},
- loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P, Event, NextState, Actions,
- Postpone, Hibernate, NewTimeout, NextEvents);
- _ ->
- terminate(
- error, {bad_action,Action}, ?STACKTRACE(),
- Debug, S, [Event|Events], State, NewData, P)
- end;
+ {_,Time,_} ->
+ case validate_timer_args(Time, []) of
+ false ->
+ parse_actions(
+ Debug, S, State, Actions,
+ Hibernate, [Timeout|TimeoutsR],
+ Postpone, NextEventsR);
+ error ->
+ {error,
+ {bad_action_from_state_function,Timeout},
+ ?STACKTRACE()}
+ end;
+ Time ->
+ case validate_timer_args(Time, []) of
+ false ->
+ parse_actions(
+ Debug, S, State, Actions,
+ Hibernate, [Timeout|TimeoutsR],
+ Postpone, NextEventsR);
+ error ->
+ {error,
+ {bad_action_from_state_function,Timeout},
+ ?STACKTRACE()}
+ end
+ end.
+
+validate_timer_args(Time, Opts) ->
+ validate_timer_args(Time, Opts, false).
%%
-%% End of actions list
-loop_event_actions(
- Parent, Debug, S, Events,
- State, NewData, P0, Event, NextState, [],
- Postpone, Hibernate, Timeout, NextEvents) ->
- %%
- %% All options have been collected and next_events are buffered.
- %% Do the actual state transition.
- %%
- P1 = % Move current event to postponed if Postpone
- case Postpone of
- true ->
- [Event|P0];
- false ->
- P0
- end,
- {Q2,P} = % Move all postponed events to queue if state change
- if
- NextState =:= State ->
- {Events,P1};
- true ->
- {lists:reverse(P1, Events),[]}
- end,
- %% Place next events first in queue
- Q = lists:reverse(NextEvents, Q2),
- %%
- NewDebug =
- sys_debug(
- Debug, S, State,
- case Postpone of
- true ->
- {postpone,Event,NextState};
- false ->
- {consume,Event,NextState}
- end),
- loop_events(
- Parent, NewDebug, S, Q, NextState, NewData, P, Hibernate, Timeout).
+validate_timer_args(Time, [], true) when is_integer(Time) ->
+ true;
+validate_timer_args(Time, [], false) when is_integer(Time), Time >= 0 ->
+ false;
+validate_timer_args(infinity, [], Abs) ->
+ Abs;
+validate_timer_args(Time, [{abs,Abs}|Opts], _) when is_boolean(Abs) ->
+ validate_timer_args(Time, Opts, Abs);
+validate_timer_args(_, [_|_], _) ->
+ error.
+
+%% Stop and start timers as well as create timeout zero events
+%% and pending event timer
+%%
+%% Stop and start timers non-event timers
+parse_timers(TimerRefs, TimerTypes, CancelTimers, TimeoutsR) ->
+ parse_timers(TimerRefs, TimerTypes, CancelTimers, TimeoutsR, #{}, []).
+%%
+parse_timers(
+ TimerRefs, TimerTypes, CancelTimers, [], _Seen, TimeoutEvents) ->
+ {TimerRefs,TimerTypes,CancelTimers,TimeoutEvents};
+parse_timers(
+ TimerRefs, TimerTypes, CancelTimers, [Timeout|TimeoutsR],
+ Seen, TimeoutEvents) ->
+ case Timeout of
+ {TimerType,Time,TimerMsg,TimerOpts} ->
+ %% Absolute timer
+ parse_timers(
+ TimerRefs, TimerTypes, CancelTimers, TimeoutsR,
+ Seen, TimeoutEvents,
+ TimerType, Time, TimerMsg, listify(TimerOpts));
+ %% Relative timers below
+ {TimerType,0,TimerMsg} ->
+ parse_timers(
+ TimerRefs, TimerTypes, CancelTimers, TimeoutsR,
+ Seen, TimeoutEvents,
+ TimerType, zero, TimerMsg, []);
+ {TimerType,Time,TimerMsg} ->
+ parse_timers(
+ TimerRefs, TimerTypes, CancelTimers, TimeoutsR,
+ Seen, TimeoutEvents,
+ TimerType, Time, TimerMsg, []);
+ 0 ->
+ parse_timers(
+ TimerRefs, TimerTypes, CancelTimers, TimeoutsR,
+ Seen, TimeoutEvents,
+ timeout, zero, 0, []);
+ Time ->
+ parse_timers(
+ TimerRefs, TimerTypes, CancelTimers, TimeoutsR,
+ Seen, TimeoutEvents,
+ timeout, Time, Time, [])
+ end.
+
+parse_timers(
+ TimerRefs, TimerTypes, CancelTimers, TimeoutsR,
+ Seen, TimeoutEvents,
+ TimerType, Time, TimerMsg, TimerOpts) ->
+ case Seen of
+ #{TimerType := _} ->
+ %% Type seen before - ignore
+ parse_timers(
+ TimerRefs, TimerTypes, CancelTimers, TimeoutsR,
+ Seen, TimeoutEvents);
+ #{} ->
+ %% Unseen type - handle
+ NewSeen = Seen#{TimerType => true},
+ case Time of
+ infinity ->
+ %% Cancel any running timer
+ {NewTimerTypes,NewCancelTimers} =
+ cancel_timer_by_type(
+ TimerType, TimerTypes, CancelTimers),
+ parse_timers(
+ TimerRefs, NewTimerTypes, NewCancelTimers, TimeoutsR,
+ NewSeen, TimeoutEvents);
+ zero ->
+ %% Cancel any running timer
+ {NewTimerTypes,NewCancelTimers} =
+ cancel_timer_by_type(
+ TimerType, TimerTypes, CancelTimers),
+ %% Handle zero time timeouts later
+ TimeoutEvent = {TimerType,TimerMsg},
+ parse_timers(
+ TimerRefs, NewTimerTypes, NewCancelTimers, TimeoutsR,
+ NewSeen, [TimeoutEvent|TimeoutEvents]);
+ _ ->
+ %% (Re)start the timer
+ TimerRef =
+ erlang:start_timer(
+ Time, self(), TimerMsg, TimerOpts),
+ case TimerTypes of
+ #{TimerType := OldTimerRef} ->
+ %% Cancel the running timer
+ cancel_timer(OldTimerRef),
+ NewCancelTimers = CancelTimers + 1,
+ %% Insert the new timer into
+ %% both TimerRefs and TimerTypes
+ parse_timers(
+ TimerRefs#{TimerRef => TimerType},
+ TimerTypes#{TimerType => TimerRef},
+ NewCancelTimers, TimeoutsR,
+ NewSeen, TimeoutEvents);
+ #{} ->
+ %% Insert the new timer into
+ %% both TimerRefs and TimerTypes
+ parse_timers(
+ TimerRefs#{TimerRef => TimerType},
+ TimerTypes#{TimerType => TimerRef},
+ CancelTimers, TimeoutsR,
+ NewSeen, TimeoutEvents)
+ end
+ end
+ end.
+
+%% Enqueue immediate timeout events (timeout 0 events)
+%%
+%% Event timer timeout 0 events gets special treatment since
+%% an event timer is cancelled by any received event,
+%% so if there are enqueued events before the event timer
+%% timeout 0 event - the event timer is cancelled hence no event.
+%%
+%% Other (state_timeout) timeout 0 events that are after
+%% the event timer timeout 0 events are considered to
+%% belong to timers that were started after the event timer
+%% timeout 0 event fired, so they do not cancel the event timer.
+%%
+prepend_timeout_events([], EventsR) ->
+ EventsR;
+prepend_timeout_events([{timeout,_} = TimeoutEvent|TimeoutEvents], []) ->
+ prepend_timeout_events(TimeoutEvents, [TimeoutEvent]);
+prepend_timeout_events([{timeout,_}|TimeoutEvents], EventsR) ->
+ prepend_timeout_events(TimeoutEvents, EventsR);
+prepend_timeout_events([TimeoutEvent|TimeoutEvents], EventsR) ->
+ %% Just prepend all others
+ prepend_timeout_events(TimeoutEvents, [TimeoutEvent|EventsR]).
+
+
%%---------------------------------------------------------------------------
%% Server helpers
reply_then_terminate(
- Class, Reason, Stacktrace,
- Debug, S, Q, State, Data, P, Replies) ->
- if
- is_list(Replies) ->
- do_reply_then_terminate(
- Class, Reason, Stacktrace,
- Debug, S, Q, State, Data, P, Replies);
- true ->
- do_reply_then_terminate(
- Class, Reason, Stacktrace,
- Debug, S, Q, State, Data, P, [Replies])
- end.
+ Class, Reason, Stacktrace, Debug,
+ #{state := State} = S, Q, Replies) ->
+ do_reply_then_terminate(
+ Class, Reason, Stacktrace, Debug,
+ S, Q, listify(Replies), State).
%%
do_reply_then_terminate(
- Class, Reason, Stacktrace, Debug, S, Q, State, Data, P, []) ->
- terminate(Class, Reason, Stacktrace, Debug, S, Q, State, Data, P);
+ Class, Reason, Stacktrace, Debug, S, Q, [], _State) ->
+ terminate(Class, Reason, Stacktrace, Debug, S, Q);
do_reply_then_terminate(
- Class, Reason, Stacktrace, Debug, S, Q, State, Data, P, [R|Rs]) ->
+ Class, Reason, Stacktrace, Debug, S, Q, [R|Rs], State) ->
case R of
{reply,{_To,_Tag}=From,Reply} ->
NewDebug = do_reply(Debug, S, State, From, Reply),
do_reply_then_terminate(
- Class, Reason, Stacktrace,
- NewDebug, S, Q, State, Data, P, Rs);
+ Class, Reason, Stacktrace, NewDebug, S, Q, Rs, State);
_ ->
terminate(
- error, {bad_action,R}, ?STACKTRACE(),
- Debug, S, Q, State, Data, P)
+ error,
+ {bad_reply_action_from_state_function,R},
+ ?STACKTRACE(),
+ Debug, S, Q)
end.
do_reply(Debug, S, State, From, Reply) ->
@@ -1179,28 +1650,40 @@ do_reply(Debug, S, State, From, Reply) ->
terminate(
- Class, Reason, Stacktrace,
- Debug, #{module := Module} = S, Q, State, Data, P) ->
- try Module:terminate(Reason, State, Data) of
- _ -> ok
- catch
- _ -> ok;
- C:R ->
- ST = erlang:get_stacktrace(),
- error_info(
- C, R, ST, Debug, S, Q, P,
- format_status(terminate, get(), S, State, Data)),
- erlang:raise(C, R, ST)
- end,
- case Reason of
- normal -> ok;
- shutdown -> ok;
- {shutdown,_} -> ok;
- _ ->
- error_info(
- Class, Reason, Stacktrace, Debug, S, Q, P,
- format_status(terminate, get(), S, State, Data))
+ Class, Reason, Stacktrace, Debug,
+ #{module := Module, state := State, data := Data, postponed := P} = S,
+ Q) ->
+ case erlang:function_exported(Module, terminate, 3) of
+ true ->
+ try Module:terminate(Reason, State, Data) of
+ _ -> ok
+ catch
+ _ -> ok;
+ C:R ->
+ ST = erlang:get_stacktrace(),
+ error_info(
+ C, R, ST, S, Q, P,
+ format_status(terminate, get(), S)),
+ sys:print_log(Debug),
+ erlang:raise(C, R, ST)
+ end;
+ false ->
+ ok
end,
+ _ =
+ case Reason of
+ normal ->
+ sys_debug(Debug, S, State, {terminate,Reason});
+ shutdown ->
+ sys_debug(Debug, S, State, {terminate,Reason});
+ {shutdown,_} ->
+ sys_debug(Debug, S, State, {terminate,Reason});
+ _ ->
+ error_info(
+ Class, Reason, Stacktrace, S, Q, P,
+ format_status(terminate, get(), S)),
+ sys:print_log(Debug)
+ end,
case Stacktrace of
[] ->
erlang:Class(Reason);
@@ -1209,8 +1692,10 @@ terminate(
end.
error_info(
- Class, Reason, Stacktrace, Debug,
- #{name := Name, callback_mode := CallbackMode},
+ Class, Reason, Stacktrace,
+ #{name := Name,
+ callback_mode := CallbackMode,
+ state_enter := StateEnter},
Q, P, FmtData) ->
{FixedReason,FixedStacktrace} =
case Stacktrace of
@@ -1237,6 +1722,15 @@ error_info(
end;
_ -> {Reason,Stacktrace}
end,
+ [LimitedP, LimitedFmtData, LimitedFixedReason] =
+ [error_logger:limit_term(D) || D <- [P, FmtData, FixedReason]],
+ CBMode =
+ case StateEnter of
+ true ->
+ [CallbackMode,state_enter];
+ false ->
+ CallbackMode
+ end,
error_logger:format(
"** State machine ~p terminating~n" ++
case Q of
@@ -1263,26 +1757,27 @@ error_info(
[] -> [];
[Event|_] -> [Event]
end] ++
- [FmtData,Class,FixedReason,
- CallbackMode] ++
+ [LimitedFmtData,
+ Class,LimitedFixedReason,
+ CBMode] ++
case Q of
[_|[_|_] = Events] -> [Events];
_ -> []
end ++
case P of
[] -> [];
- _ -> [P]
+ _ -> [LimitedP]
end ++
case FixedStacktrace of
[] -> [];
_ -> [FixedStacktrace]
- end),
- sys:print_log(Debug),
- ok.
+ end).
%% Call Module:format_status/2 or return a default value
-format_status(Opt, PDict, #{module := Module}, State, Data) ->
+format_status(
+ Opt, PDict,
+ #{module := Module, state := State, data := Data}) ->
case erlang:function_exported(Module, format_status, 2) of
true ->
try Module:format_status(Opt, [PDict,State,Data])
@@ -1291,7 +1786,7 @@ format_status(Opt, PDict, #{module := Module}, State, Data) ->
_:_ ->
format_status_default(
Opt, State,
- "Module:format_status/2 crashed")
+ atom_to_list(Module) ++ ":format_status/2 crashed")
end;
false ->
format_status_default(Opt, State, Data)
@@ -1299,10 +1794,35 @@ format_status(Opt, PDict, #{module := Module}, State, Data) ->
%% The default Module:format_status/2
format_status_default(Opt, State, Data) ->
- SSD = {State,Data},
+ StateData = {State,Data},
case Opt of
terminate ->
- SSD;
+ StateData;
_ ->
- [{data,[{"State",SSD}]}]
+ [{data,[{"State",StateData}]}]
+ end.
+
+listify(Item) when is_list(Item) ->
+ Item;
+listify(Item) ->
+ [Item].
+
+%% Cancel timer if running, otherwise no op
+%%
+%% This is an asynchronous cancel so the timer is not really cancelled
+%% until we get a cancel_timer msg i.e {cancel_timer,TimerRef,_}.
+%% In the mean time we might get a timeout message.
+%%
+%% Remove the timer from TimerTypes.
+%% When we get the cancel_timer msg we remove it from TimerRefs.
+cancel_timer_by_type(TimerType, TimerTypes, CancelTimers) ->
+ case TimerTypes of
+ #{TimerType := TimerRef} ->
+ cancel_timer(TimerRef),
+ {maps:remove(TimerType, TimerTypes),CancelTimers + 1};
+ #{} ->
+ {TimerTypes,CancelTimers}
end.
+
+cancel_timer(TimerRef) ->
+ ok = erlang:cancel_timer(TimerRef, [{async,true}]).
diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl
index ad98bc0420..9d447418f8 100644
--- a/lib/stdlib/src/io_lib.erl
+++ b/lib/stdlib/src/io_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@
%% Most of the code here is derived from the original prolog versions and
%% from similar code written by Joe Armstrong and myself.
%%
-%% This module has been split into seperate modules:
+%% This module has been split into separate modules:
%% io_lib - basic write and utilities
%% io_lib_format - formatted output
%% io_lib_fread - formatted input
@@ -68,8 +68,8 @@
-export([write_atom/1,write_string/1,write_string/2,write_latin1_string/1,
write_latin1_string/2, write_char/1, write_latin1_char/1]).
--export([write_string_as_latin1/1, write_string_as_latin1/2,
- write_char_as_latin1/1]).
+-export([write_atom_as_latin1/1, write_string_as_latin1/1,
+ write_string_as_latin1/2, write_char_as_latin1/1]).
-export([quote_atom/2, char_list/1, latin1_char_list/1,
deep_char_list/1, deep_latin1_char_list/1,
@@ -84,6 +84,8 @@
-export([write_unicode_string/1, write_unicode_char/1,
deep_unicode_char_list/1]).
+-export([limit_term/2]).
+
-export_type([chars/0, latin1_string/0, continuation/0,
fread_error/0, fread_item/0, format_spec/0]).
@@ -268,47 +270,61 @@ write(Term, D, false) ->
-spec write(Term, Depth) -> chars() when
Term :: term(),
+ Depth :: depth();
+ (Term, Options) -> chars() when
+ Term :: term(),
+ Options :: [Option],
+ Option :: {'depth', Depth}
+ | {'encoding', 'latin1' | 'utf8' | 'unicode'},
Depth :: depth().
-write(_Term, 0) -> "...";
-write(Term, _D) when is_integer(Term) -> integer_to_list(Term);
-write(Term, _D) when is_float(Term) -> io_lib_format:fwrite_g(Term);
-write(Atom, _D) when is_atom(Atom) -> write_atom(Atom);
-write(Term, _D) when is_port(Term) -> write_port(Term);
-write(Term, _D) when is_pid(Term) -> pid_to_list(Term);
-write(Term, _D) when is_reference(Term) -> write_ref(Term);
-write(<<_/bitstring>>=Term, D) -> write_binary(Term, D);
-write([], _D) -> "[]";
-write({}, _D) -> "{}";
-write([H|T], D) ->
+write(Term, Options) when is_list(Options) ->
+ Depth = get_option(depth, Options, -1),
+ Encoding = get_option(encoding, Options, epp:default_encoding()),
+ write1(Term, Depth, Encoding);
+write(Term, Depth) ->
+ write1(Term, Depth, latin1).
+
+write1(_Term, 0, _E) -> "...";
+write1(Term, _D, _E) when is_integer(Term) -> integer_to_list(Term);
+write1(Term, _D, _E) when is_float(Term) -> io_lib_format:fwrite_g(Term);
+write1(Atom, _D, latin1) when is_atom(Atom) -> write_atom_as_latin1(Atom);
+write1(Atom, _D, _E) when is_atom(Atom) -> write_atom(Atom);
+write1(Term, _D, _E) when is_port(Term) -> write_port(Term);
+write1(Term, _D, _E) when is_pid(Term) -> pid_to_list(Term);
+write1(Term, _D, _E) when is_reference(Term) -> write_ref(Term);
+write1(<<_/bitstring>>=Term, D, _E) -> write_binary(Term, D);
+write1([], _D, _E) -> "[]";
+write1({}, _D, _E) -> "{}";
+write1([H|T], D, E) ->
if
D =:= 1 -> "[...]";
true ->
- [$[,[write(H, D-1)|write_tail(T, D-1, $|)],$]]
+ [$[,[write1(H, D-1, E)|write_tail(T, D-1, E, $|)],$]]
end;
-write(F, _D) when is_function(F) ->
+write1(F, _D, _E) when is_function(F) ->
erlang:fun_to_list(F);
-write(Term, D) when is_map(Term) ->
- write_map(Term, D);
-write(T, D) when is_tuple(T) ->
+write1(Term, D, E) when is_map(Term) ->
+ write_map(Term, D, E);
+write1(T, D, E) when is_tuple(T) ->
if
D =:= 1 -> "{...}";
true ->
[${,
- [write(element(1, T), D-1)|
- write_tail(tl(tuple_to_list(T)), D-1, $,)],
+ [write1(element(1, T), D-1, E)|
+ write_tail(tl(tuple_to_list(T)), D-1, E, $,)],
$}]
end.
%% write_tail(List, Depth, CharacterBeforeDots)
%% Test the terminating case first as this looks better with depth.
-write_tail([], _D, _S) -> "";
-write_tail(_, 1, S) -> [S | "..."];
-write_tail([H|T], D, S) ->
- [$,,write(H, D-1)|write_tail(T, D-1, S)];
-write_tail(Other, D, S) ->
- [S,write(Other, D-1)].
+write_tail([], _D, _E, _S) -> "";
+write_tail(_, 1, _E, S) -> [S | "..."];
+write_tail([H|T], D, E, S) ->
+ [$,,write1(H, D-1, E)|write_tail(T, D-1, E, S)];
+write_tail(Other, D, E, S) ->
+ [S,write1(Other, D-1, E)].
write_port(Port) ->
erlang:port_to_list(Port).
@@ -316,17 +332,17 @@ write_port(Port) ->
write_ref(Ref) ->
erlang:ref_to_list(Ref).
-write_map(Map, D) when is_integer(D) ->
- [$#,${,write_map_body(maps:to_list(Map), D),$}].
+write_map(Map, D, E) when is_integer(D) ->
+ [$#,${,write_map_body(maps:to_list(Map), D, E),$}].
-write_map_body(_, 0) -> "...";
-write_map_body([],_) -> [];
-write_map_body([{K,V}],D) -> write_map_assoc(K,V,D);
-write_map_body([{K,V}|KVs], D) ->
- [write_map_assoc(K,V,D),$, | write_map_body(KVs,D-1)].
+write_map_body(_, 0, _E) -> "...";
+write_map_body([], _, _E) -> [];
+write_map_body([{K,V}], D, E) -> write_map_assoc(K, V, D, E);
+write_map_body([{K,V}|KVs], D, E) ->
+ [write_map_assoc(K, V, D, E),$, | write_map_body(KVs, D-1, E)].
-write_map_assoc(K,V,D) ->
- [write(K,D - 1),"=>",write(V,D-1)].
+write_map_assoc(K, V, D, E) ->
+ [write1(K, D - 1, E),"=>",write1(V, D-1, E)].
write_binary(B, D) when is_integer(D) ->
[$<,$<,write_binary_body(B, D),$>,$>].
@@ -344,6 +360,18 @@ write_binary_body(B, _D) ->
<<X:L>> = B,
[integer_to_list(X),$:,integer_to_list(L)].
+get_option(Key, TupleList, Default) ->
+ case lists:keyfind(Key, 1, TupleList) of
+ false -> Default;
+ {Key, Value} -> Value;
+ _ -> Default
+ end.
+
+%%% There are two functions to write Unicode atoms:
+%%% - they both escape control characters < 160;
+%%% - write_atom() never escapes characters >= 160;
+%%% - write_atom_as_latin1() also escapes characters >= 255.
+
%% write_atom(Atom) -> [Char]
%% Generate the list of characters needed to print an atom.
@@ -351,17 +379,26 @@ write_binary_body(B, _D) ->
Atom :: atom().
write_atom(Atom) ->
+ write_possibly_quoted_atom(Atom, fun write_string/2).
+
+-spec write_atom_as_latin1(Atom) -> latin1_string() when
+ Atom :: atom().
+
+write_atom_as_latin1(Atom) ->
+ write_possibly_quoted_atom(Atom, fun write_string_as_latin1/2).
+
+write_possibly_quoted_atom(Atom, PFun) ->
Chars = atom_to_list(Atom),
case quote_atom(Atom, Chars) of
true ->
- write_string(Chars, $'); %'
+ PFun(Chars, $'); %'
false ->
Chars
end.
%% quote_atom(Atom, CharList)
%% Return 'true' if atom with chars in CharList needs to be quoted, else
-%% return 'false'.
+%% return 'false'. Notice that characters >= 160 are always quoted.
-spec quote_atom(atom(), chars()) -> boolean().
@@ -876,3 +913,116 @@ binrev(L) ->
binrev(L, T) ->
list_to_binary(lists:reverse(L, T)).
+
+-spec limit_term(term(), non_neg_integer()) -> term().
+
+%% The intention is to mimic the depth limitation of io_lib:write()
+%% and io_lib_pretty:print(). The leaves ('...') should never be
+%% seen when printed with the same depth. Bitstrings are never
+%% truncated, which is OK as long as they are not sent to other nodes.
+limit_term(Term, Depth) ->
+ try test_limit(Term, Depth) of
+ ok -> Term
+ catch
+ throw:limit ->
+ limit(Term, Depth)
+ end.
+
+limit(_, 0) -> '...';
+limit([H|T]=L, D) ->
+ if
+ D =:= 1 -> '...';
+ true ->
+ case printable_list(L) of
+ true -> L;
+ false ->
+ [limit(H, D-1)|limit_tail(T, D-1)]
+ end
+ end;
+limit(Term, D) when is_map(Term) ->
+ limit_map(Term, D);
+limit({}=T, _D) -> T;
+limit(T, D) when is_tuple(T) ->
+ if
+ D =:= 1 -> '...';
+ true ->
+ list_to_tuple([limit(element(1, T), D-1)|
+ limit_tail(tl(tuple_to_list(T)), D-1)])
+ end;
+limit(<<_/bitstring>>=Term, D) -> limit_bitstring(Term, D);
+limit(Term, _D) -> Term.
+
+limit_tail([], _D) -> [];
+limit_tail(_, 1) -> ['...'];
+limit_tail([H|T], D) ->
+ [limit(H, D-1)|limit_tail(T, D-1)];
+limit_tail(Other, D) ->
+ limit(Other, D-1).
+
+%% Cannot limit maps properly since there is no guarantee that
+%% maps:from_list() creates a map with the same internal ordering of
+%% the selected associations as in Map.
+limit_map(Map, D) ->
+ maps:from_list(erts_internal:maps_to_list(Map, D)).
+%% maps:from_list(limit_map_body(erts_internal:maps_to_list(Map, D), D)).
+
+%% limit_map_body(_, 0) -> [{'...', '...'}];
+%% limit_map_body([], _) -> [];
+%% limit_map_body([{K,V}], D) -> [limit_map_assoc(K, V, D)];
+%% limit_map_body([{K,V}|KVs], D) ->
+%% [limit_map_assoc(K, V, D) | limit_map_body(KVs, D-1)].
+
+%% limit_map_assoc(K, V, D) ->
+%% {limit(K, D-1), limit(V, D-1)}.
+
+limit_bitstring(B, _D) -> B. %% Keeps all printable binaries.
+
+test_limit(_, 0) -> throw(limit);
+test_limit([H|T]=L, D) when is_integer(D) ->
+ if
+ D =:= 1 -> throw(limit);
+ true ->
+ case printable_list(L) of
+ true -> ok;
+ false ->
+ test_limit(H, D-1),
+ test_limit_tail(T, D-1)
+ end
+ end;
+test_limit(Term, D) when is_map(Term) ->
+ test_limit_map(Term, D);
+test_limit({}, _D) -> ok;
+test_limit(T, D) when is_tuple(T) ->
+ test_limit_tuple(T, 1, tuple_size(T), D);
+test_limit(<<_/bitstring>>=Term, D) -> test_limit_bitstring(Term, D);
+test_limit(_Term, _D) -> ok.
+
+test_limit_tail([], _D) -> ok;
+test_limit_tail(_, 1) -> throw(limit);
+test_limit_tail([H|T], D) ->
+ test_limit(H, D-1),
+ test_limit_tail(T, D-1);
+test_limit_tail(Other, D) ->
+ test_limit(Other, D-1).
+
+test_limit_tuple(_T, I, Sz, _D) when I > Sz -> ok;
+test_limit_tuple(_, _, _, 1) -> throw(limit);
+test_limit_tuple(T, I, Sz, D) ->
+ test_limit(element(I, T), D-1),
+ test_limit_tuple(T, I+1, Sz, D-1).
+
+test_limit_map(_Map, _D) -> ok.
+%% test_limit_map_body(erts_internal:maps_to_list(Map, D), D).
+
+%% test_limit_map_body(_, 0) -> throw(limit);
+%% test_limit_map_body([], _) -> ok;
+%% test_limit_map_body([{K,V}], D) -> test_limit_map_assoc(K, V, D);
+%% test_limit_map_body([{K,V}|KVs], D) ->
+%% test_limit_map_assoc(K, V, D),
+%% test_limit_map_body(KVs, D-1).
+
+%% test_limit_map_assoc(K, V, D) ->
+%% test_limit(K, D-1),
+%% test_limit(V, D-1).
+
+test_limit_bitstring(_, _) -> ok.
diff --git a/lib/stdlib/src/io_lib_format.erl b/lib/stdlib/src/io_lib_format.erl
index 1da866dc88..4b2d15c8b3 100644
--- a/lib/stdlib/src/io_lib_format.erl
+++ b/lib/stdlib/src/io_lib_format.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -257,15 +257,18 @@ indentation([], I) -> I.
%% This is the main dispatch function for the various formatting commands.
%% Field widths and precisions have already been calculated.
-control($w, [A], F, Adj, P, Pad, _Enc, _Str, _I) ->
- term(io_lib:write(A, -1), F, Adj, P, Pad);
+control($w, [A], F, Adj, P, Pad, Enc, _Str, _I) ->
+ term(io_lib:write(A, [{depth,-1}, {encoding, Enc}]), F, Adj, P, Pad);
control($p, [A], F, Adj, P, Pad, Enc, Str, I) ->
print(A, -1, F, Adj, P, Pad, Enc, Str, I);
-control($W, [A,Depth], F, Adj, P, Pad, _Enc, _Str, _I) when is_integer(Depth) ->
- term(io_lib:write(A, Depth), F, Adj, P, Pad);
+control($W, [A,Depth], F, Adj, P, Pad, Enc, _Str, _I) when is_integer(Depth) ->
+ term(io_lib:write(A, [{depth,Depth}, {encoding, Enc}]), F, Adj, P, Pad);
control($P, [A,Depth], F, Adj, P, Pad, Enc, Str, I) when is_integer(Depth) ->
print(A, Depth, F, Adj, P, Pad, Enc, Str, I);
-control($s, [A], F, Adj, P, Pad, _Enc, _Str, _I) when is_atom(A) ->
+control($s, [A], F, Adj, P, Pad, latin1, _Str, _I) when is_atom(A) ->
+ L = iolist_to_chars(atom_to_list(A)),
+ string(L, F, Adj, P, Pad);
+control($s, [A], F, Adj, P, Pad, unicode, _Str, _I) when is_atom(A) ->
string(atom_to_list(A), F, Adj, P, Pad);
control($s, [L0], F, Adj, P, Pad, latin1, _Str, _I) ->
L = iolist_to_chars(L0),
@@ -332,7 +335,7 @@ base(B) when is_integer(B) ->
term(T, none, _Adj, none, _Pad) -> T;
term(T, none, Adj, P, Pad) -> term(T, P, Adj, P, Pad);
term(T, F, Adj, P0, Pad) ->
- L = lists:flatlength(T),
+ L = string:length(T),
P = erlang:min(L, case P0 of none -> F; _ -> min(P0, F) end),
if
L > P ->
@@ -343,7 +346,8 @@ term(T, F, Adj, P0, Pad) ->
%% print(Term, Depth, Field, Adjust, Precision, PadChar, Encoding,
%% Indentation)
-%% Print a term.
+%% Print a term. Field width sets maximum line length, Precision sets
+%% initial indentation.
print(T, D, none, Adj, P, Pad, E, Str, I) ->
print(T, D, 80, Adj, P, Pad, E, Str, I);
@@ -671,11 +675,11 @@ cdata_to_chars(B) when is_binary(B) ->
string(S, none, _Adj, none, _Pad) -> S;
string(S, F, Adj, none, Pad) ->
- string_field(S, F, Adj, lists:flatlength(S), Pad);
+ string_field(S, F, Adj, string:length(S), Pad);
string(S, none, _Adj, P, Pad) ->
- string_field(S, P, left, lists:flatlength(S), Pad);
+ string_field(S, P, left, string:length(S), Pad);
string(S, F, Adj, P, Pad) when F >= P ->
- N = lists:flatlength(S),
+ N = string:length(S),
if F > P ->
if N > P ->
adjust(flat_trunc(S, P), chars(Pad, F-P), Adj);
@@ -745,18 +749,7 @@ adjust(Data, Pad, right) -> [Pad|Data].
%% Flatten and truncate a deep list to at most N elements.
flat_trunc(List, N) when is_integer(N), N >= 0 ->
- flat_trunc(List, N, [], []).
-
-flat_trunc(L, 0, _, R) when is_list(L) ->
- lists:reverse(R);
-flat_trunc([H|T], N, S, R) when is_list(H) ->
- flat_trunc(H, N, [T|S], R);
-flat_trunc([H|T], N, S, R) ->
- flat_trunc(T, N-1, S, [H|R]);
-flat_trunc([], N, [H|S], R) ->
- flat_trunc(H, N, S, R);
-flat_trunc([], _, [], R) ->
- lists:reverse(R).
+ string:slice(List, 0, N).
%% A deep version of string:chars/2,3
diff --git a/lib/stdlib/src/io_lib_fread.erl b/lib/stdlib/src/io_lib_fread.erl
index 6a8f8f728e..983e8d4566 100644
--- a/lib/stdlib/src/io_lib_fread.erl
+++ b/lib/stdlib/src/io_lib_fread.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -159,8 +159,8 @@ fread_field([$t|Format], F, Sup, _Unic) ->
fread_field(Format, F, Sup, Unic) ->
{Format,F,Sup,Unic}.
-%% fread1(Format, FieldWidth, Suppress, Line, N, Results, AllFormat)
-%% fread1(Format, FieldWidth, Suppress, Line, N, Results)
+%% fread1(Format, FieldWidth, Suppress, Unicode, Line, N, Results, AllFormat)
+%% fread1(Format, FieldWidth, Suppress, Unicode, Line, N, Results)
%% The main dispatch function for the formatting commands. Done in two
%% stages so format commands that need no input can always be processed.
@@ -231,9 +231,8 @@ fread1([$s|Format], none, Sup, U, Line0, N0, Res) ->
fread1([$s|Format], F, Sup, U, Line0, N, Res) ->
{Line,Cs} = fread_chars(Line0, F, U),
fread_string(Cs, Sup, U, Format, Line, N+F, Res);
-%% XXX:PaN Atoms still only latin1...
-fread1([$a|Format], none, Sup, false, Line0, N0, Res) ->
- {Line,N,Cs} = fread_string_cs(Line0, N0, false),
+fread1([$a|Format], none, Sup, U, Line0, N0, Res) ->
+ {Line,N,Cs} = fread_string_cs(Line0, N0, U),
fread_atom(Cs, Sup, Format, Line, N, Res);
fread1([$a|Format], F, Sup, false, Line0, N, Res) ->
{Line,Cs} = fread_chars(Line0, F, false),
diff --git a/lib/stdlib/src/io_lib_pretty.erl b/lib/stdlib/src/io_lib_pretty.erl
index 16ca2f41dc..505613b80e 100644
--- a/lib/stdlib/src/io_lib_pretty.erl
+++ b/lib/stdlib/src/io_lib_pretty.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -97,37 +97,54 @@ print(Term, Col, Ll, D, RecDefFun) ->
print(Term, Col, Ll, D, M, RecDefFun) ->
print(Term, Col, Ll, D, M, RecDefFun, latin1, true).
+%% D = Depth, default -1 (infinite), or LINEMAX=30 when printing from shell
+%% Col = current column, default 1
+%% Ll = line length/~p field width, default 80
+%% M = CHAR_MAX (-1 if no max, 60 when printing from shell)
print(_, _, _, 0, _M, _RF, _Enc, _Str) -> "...";
print(Term, Col, Ll, D, M, RecDefFun, Enc, Str) when Col =< 0 ->
+ %% ensure Col is at least 1
print(Term, 1, Ll, D, M, RecDefFun, Enc, Str);
+print(Atom, _Col, _Ll, _D, _M, _RF, Enc, _Str) when is_atom(Atom) ->
+ write_atom(Atom, Enc);
print(Term, Col, Ll, D, M0, RecDefFun, Enc, Str) when is_tuple(Term);
is_list(Term);
is_map(Term);
is_bitstring(Term) ->
+ %% preprocess and compute total number of chars
If = {_S, Len} = print_length(Term, D, RecDefFun, Enc, Str),
+ %% use Len as CHAR_MAX if M0 = -1
M = max_cs(M0, Len),
if
Len < Ll - Col, Len =< M ->
+ %% write the whole thing on a single line when there is room
write(If);
true ->
+ %% compute the indentation TInd for tagged tuples and records
TInd = while_fail([-1, 4],
fun(I) -> cind(If, Col, Ll, M, I, 0, 0) end,
1),
pp(If, Col, Ll, M, TInd, indent(Col), 0, 0)
end;
print(Term, _Col, _Ll, _D, _M, _RF, _Enc, _Str) ->
+ %% atomic data types (bignums, atoms, ...) are never truncated
io_lib:write(Term).
%%%
%%% Local functions
%%%
+%% use M only if nonnegative, otherwise use Len as default value
max_cs(M, Len) when M < 0 ->
Len;
max_cs(M, _Len) ->
M.
-define(ATM(T), is_list(element(1, T))).
+-define(ATM_PAIR(Pair),
+ ?ATM(element(2, element(1, Pair))) % Key
+ andalso
+ ?ATM(element(3, element(1, Pair)))). % Value
-define(ATM_FLD(Field), ?ATM(element(4, element(1, Field)))).
pp({_S, Len} = If, Col, Ll, M, _TInd, _Ind, LD, W)
@@ -140,9 +157,8 @@ pp({{tuple,true,L}, _Len}, Col, Ll, M, TInd, Ind, LD, W) ->
pp({{tuple,false,L}, _Len}, Col, Ll, M, TInd, Ind, LD, W) ->
[${, pp_list(L, Col + 1, Ll, M, TInd, indent(1, Ind), LD, $,, W + 1), $}];
pp({{map,Pairs},_Len}, Col, Ll, M, TInd, Ind, LD, W) ->
- [$#,${, pp_list(Pairs, Col + 2, Ll, M, TInd, indent(2, Ind), LD, $,, W + 1), $}];
-pp({{map_pair,K,V},_Len}, Col, Ll, M, TInd, Ind, LD, W) ->
- [pp(K, Col, Ll, M, TInd, Ind, LD, W), " => ", pp(V, Col, Ll, M, TInd, Ind, LD, W)];
+ [$#, ${, pp_map(Pairs, Col + 2, Ll, M, TInd, indent(2, Ind), LD, W + 1),
+ $}];
pp({{record,[{Name,NLen} | L]}, _Len}, Col, Ll, M, TInd, Ind, LD, W) ->
[Name, ${, pp_record(L, NLen, Col, Ll, M, TInd, Ind, LD, W + NLen+1), $}];
pp({{bin,S}, _Len}, Col, Ll, M, _TInd, Ind, LD, W) ->
@@ -153,6 +169,7 @@ pp({S, _Len}, _Col, _Ll, _M, _TInd, _Ind, _LD, _W) ->
%% Print a tagged tuple by indenting the rest of the elements
%% differently to the tag. Tuple has size >= 2.
pp_tag_tuple([{Tag,Tlen} | L], Col, Ll, M, TInd, Ind, LD, W) ->
+ %% this uses TInd
TagInd = Tlen + 2,
Tcol = Col + TagInd,
S = $,,
@@ -166,6 +183,46 @@ pp_tag_tuple([{Tag,Tlen} | L], Col, Ll, M, TInd, Ind, LD, W) ->
[Tag, S | pp_list(L, Tcol, Ll, M, TInd, Indent, LD, S, W+Tlen+1)]
end.
+pp_map([], _Col, _Ll, _M, _TInd, _Ind, _LD, _W) ->
+ "";
+pp_map({dots, _}, _Col, _Ll, _M, _TInd, _Ind, _LD, _W) ->
+ "...";
+pp_map([P | Ps], Col, Ll, M, TInd, Ind, LD, W) ->
+ {PS, PW} = pp_pair(P, Col, Ll, M, TInd, Ind, last_depth(Ps, LD), W),
+ [PS | pp_pairs_tail(Ps, Col, Col + PW, Ll, M, TInd, Ind, LD, PW)].
+
+pp_pairs_tail([], _Col0, _Col, _Ll, _M, _TInd, _Ind, _LD, _W) ->
+ "";
+pp_pairs_tail({dots, _}, _Col0, _Col, _M, _Ll, _TInd, _Ind, _LD, _W) ->
+ ",...";
+pp_pairs_tail([{_, Len}=P | Ps], Col0, Col, Ll, M, TInd, Ind, LD, W) ->
+ LD1 = last_depth(Ps, LD),
+ ELen = 1 + Len,
+ if
+ LD1 =:= 0, ELen + 1 < Ll - Col, W + ELen + 1 =< M, ?ATM_PAIR(P);
+ LD1 > 0, ELen < Ll - Col - LD1, W + ELen + LD1 =< M, ?ATM_PAIR(P) ->
+ [$,, write_pair(P) |
+ pp_pairs_tail(Ps, Col0, Col+ELen, Ll, M, TInd, Ind, LD, W+ELen)];
+ true ->
+ {PS, PW} = pp_pair(P, Col0, Ll, M, TInd, Ind, LD1, 0),
+ [$,, $\n, Ind, PS |
+ pp_pairs_tail(Ps, Col0, Col0 + PW, Ll, M, TInd, Ind, LD, PW)]
+ end.
+
+pp_pair({_, Len}=Pair, Col, Ll, M, _TInd, _Ind, LD, W)
+ when Len < Ll - Col - LD, Len + W + LD =< M ->
+ {write_pair(Pair), if
+ ?ATM_PAIR(Pair) ->
+ Len;
+ true ->
+ Ll % force nl
+ end};
+pp_pair({{map_pair, K, V}, _Len}, Col0, Ll, M, TInd, Ind0, LD, W) ->
+ I = map_value_indent(TInd),
+ Ind = indent(I, Ind0),
+ {[pp(K, Col0, Ll, M, TInd, Ind0, LD, W), " =>\n",
+ Ind | pp(V, Col0 + I, Ll, M, TInd, Ind, LD, 0)], Ll}. % force nl
+
pp_record([], _Nlen, _Col, _Ll, _M, _TInd, _Ind, _LD, _W) ->
"";
pp_record({dots, _}, _Nlen, _Col, _Ll, _M, _TInd, _Ind, _LD, _W) ->
@@ -204,9 +261,14 @@ pp_field({_, Len}=Fl, Col, Ll, M, _TInd, _Ind, LD, W)
end};
pp_field({{field, Name, NameL, F}, _Len}, Col0, Ll, M, TInd, Ind0, LD, W0) ->
{Col, Ind, S, W} = rec_indent(NameL, TInd, Col0, Ind0, W0 + NameL),
- {[Name, " = ", S | pp(F, Col, Ll, M, TInd, Ind, LD, W)], Ll}. % force nl
+ Sep = case S of
+ [$\n | _] -> " =";
+ _ -> " = "
+ end,
+ {[Name, Sep, S | pp(F, Col, Ll, M, TInd, Ind, LD, W)], Ll}. % force nl
rec_indent(RInd, TInd, Col0, Ind0, W0) ->
+ %% this uses TInd
Nl = (TInd > 0) and (RInd > TInd),
DCol = case Nl of
true -> TInd;
@@ -285,14 +347,15 @@ pp_binary(S, N, _N0, Ind) ->
S
end.
+%% write the whole thing on a single line
write({{tuple, _IsTagged, L}, _}) ->
[${, write_list(L, $,), $}];
write({{list, L}, _}) ->
[$[, write_list(L, $|), $]];
write({{map, Pairs}, _}) ->
[$#,${, write_list(Pairs, $,), $}];
-write({{map_pair, K, V}, _}) ->
- [write(K)," => ",write(V)];
+write({{map_pair, _K, _V}, _}=Pair) ->
+ write_pair(Pair);
write({{record, [{Name,_} | L]}, _}) ->
[Name, ${, write_fields(L), $}];
write({{bin, S}, _}) ->
@@ -300,6 +363,9 @@ write({{bin, S}, _}) ->
write({S, _}) ->
S.
+write_pair({{map_pair, K, V}, _}) ->
+ [write(K), " => ", write(V)].
+
write_fields([]) ->
"";
write_fields({dots, _}) ->
@@ -333,7 +399,7 @@ write_tail(E, S) ->
%% The depth (D) is used for extracting and counting the characters to
%% print. The structure is kept so that the returned intermediate
-%% format can be formatted. The separators (list, tuple, record) are
+%% format can be formatted. The separators (list, tuple, record, map) are
%% counted but need to be added later.
%% D =/= 0
@@ -343,9 +409,14 @@ print_length({}, _D, _RF, _Enc, _Str) ->
{"{}", 2};
print_length(#{}=M, _D, _RF, _Enc, _Str) when map_size(M) =:= 0 ->
{"#{}", 3};
+print_length(Atom, _D, _RF, Enc, _Str) when is_atom(Atom) ->
+ S = write_atom(Atom, Enc),
+ {S, lists:flatlength(S)};
print_length(List, D, RF, Enc, Str) when is_list(List) ->
+ %% only flat lists are "printable"
case Str andalso printable_list(List, D, Enc) of
true ->
+ %% print as string, escaping double-quotes in the list
S = write_string(List, Enc),
{S, length(S)};
%% Truncated lists could break some existing code.
@@ -401,26 +472,28 @@ print_length(<<_/bitstring>>=Bin, D, _RF, Enc, Str) ->
end;
print_length(Term, _D, _RF, _Enc, _Str) ->
S = io_lib:write(Term),
- {S, lists:flatlength(S)}.
+ %% S can contain unicode, so iolist_size(S) cannot be used here
+ {S, string:length(S)}.
print_length_map(_Map, 1, _RF, _Enc, _Str) ->
{"#{...}", 6};
print_length_map(Map, D, RF, Enc, Str) when is_map(Map) ->
- Pairs = print_length_map_pairs(maps:to_list(Map), D, RF, Enc, Str),
+ Pairs = print_length_map_pairs(erts_internal:maps_to_list(Map, D), D, RF, Enc, Str),
{{map, Pairs}, list_length(Pairs, 3)}.
print_length_map_pairs([], _D, _RF, _Enc, _Str) ->
[];
print_length_map_pairs(_Pairs, 1, _RF, _Enc, _Str) ->
{dots, 3};
-print_length_map_pairs([{K,V}|Pairs], D, RF, Enc, Str) ->
- [print_length_map_pair(K,V,D-1,RF,Enc,Str) |
- print_length_map_pairs(Pairs,D-1,RF,Enc,Str)].
+print_length_map_pairs([{K, V} | Pairs], D, RF, Enc, Str) ->
+ [print_length_map_pair(K, V, D - 1, RF, Enc, Str) |
+ print_length_map_pairs(Pairs, D - 1, RF, Enc, Str)].
print_length_map_pair(K, V, D, RF, Enc, Str) ->
{KS, KL} = print_length(K, D, RF, Enc, Str),
{VS, VL} = print_length(V, D, RF, Enc, Str),
- {{map_pair, {KS,KL}, {VS,VL}}, KL + VL}.
+ KL1 = KL + 4,
+ {{map_pair, {KS, KL1}, {VS, VL}}, KL1 + VL}.
print_length_tuple(_Tuple, 1, _RF, _Enc, _Str) ->
{"{...}", 5};
@@ -432,7 +505,7 @@ print_length_tuple(Tuple, D, RF, Enc, Str) ->
print_length_record(_Tuple, 1, _RF, _RDefs, _Enc, _Str) ->
{"{...}", 5};
print_length_record(Tuple, D, RF, RDefs, Enc, Str) ->
- Name = [$# | io_lib:write_atom(element(1, Tuple))],
+ Name = [$# | write_atom(element(1, Tuple), Enc)],
NameL = length(Name),
Elements = tl(tuple_to_list(Tuple)),
L = print_length_fields(RDefs, D - 1, Elements, RF, Enc, Str),
@@ -447,7 +520,7 @@ print_length_fields([Def | Defs], D, [E | Es], RF, Enc, Str) ->
print_length_fields(Defs, D - 1, Es, RF, Enc, Str)].
print_length_field(Def, D, E, RF, Enc, Str) ->
- Name = io_lib:write_atom(Def),
+ Name = write_atom(Def, Enc),
{S, L} = print_length(E, D, RF, Enc, Str),
NameL = length(Name) + 3,
{{field, Name, NameL, {S, L}}, NameL + L}.
@@ -483,6 +556,7 @@ list_length_tail({_, Len}, Acc) ->
%% ?CHARS printable characters has depth 1.
-define(CHARS, 4).
+%% only flat lists are "printable"
printable_list(_L, 1, _Enc) ->
false;
printable_list(L, _D, latin1) ->
@@ -595,6 +669,11 @@ printable_char(C,unicode) ->
C > 16#DFFF andalso C < 16#FFFE orelse
C > 16#FFFF andalso C =< 16#10FFFF.
+write_atom(A, latin1) ->
+ io_lib:write_atom_as_latin1(A);
+write_atom(A, _Uni) ->
+ io_lib:write_atom(A).
+
write_string(S, latin1) ->
io_lib:write_latin1_string(S, $"); %"
write_string(S, _Uni) ->
@@ -612,6 +691,8 @@ cind({{tuple,true,L}, _Len}, Col, Ll, M, Ind, LD, W) ->
cind_tag_tuple(L, Col, Ll, M, Ind, LD, W + 1);
cind({{tuple,false,L}, _Len}, Col, Ll, M, Ind, LD, W) ->
cind_list(L, Col + 1, Ll, M, Ind, LD, W + 1);
+cind({{map,Pairs},_Len}, Col, Ll, M, Ind, LD, W) ->
+ cind_map(Pairs, Col + 2, Ll, M, Ind, LD, W + 2);
cind({{record,[{_Name,NLen} | L]}, _Len}, Col, Ll, M, Ind, LD, W) ->
cind_record(L, NLen, Col, Ll, M, Ind, LD, W + NLen + 1);
cind({{bin,_S}, _Len}, _Col, _Ll, _M, Ind, _LD, _W) ->
@@ -637,6 +718,48 @@ cind_tag_tuple([{_Tag,Tlen} | L], Col, Ll, M, Ind, LD, W) ->
throw(no_good)
end.
+cind_map([P | Ps], Col, Ll, M, Ind, LD, W) ->
+ PW = cind_pair(P, Col, Ll, M, Ind, last_depth(Ps, LD), W),
+ cind_pairs_tail(Ps, Col, Col + PW, Ll, M, Ind, LD, W + PW);
+cind_map(_, _Col, _Ll, _M, Ind, _LD, _W) ->
+ Ind.
+
+cind_pairs_tail([{_, Len}=P | Ps], Col0, Col, Ll, M, Ind, LD, W) ->
+ LD1 = last_depth(Ps, LD),
+ ELen = 1 + Len,
+ if
+ LD1 =:= 0, ELen + 1 < Ll - Col, W + ELen + 1 =< M, ?ATM_PAIR(P);
+ LD1 > 0, ELen < Ll - Col - LD1, W + ELen + LD1 =< M, ?ATM_PAIR(P) ->
+ cind_pairs_tail(Ps, Col0, Col + ELen, Ll, M, Ind, LD, W + ELen);
+ true ->
+ PW = cind_pair(P, Col0, Ll, M, Ind, LD1, 0),
+ cind_pairs_tail(Ps, Col0, Col0 + PW, Ll, M, Ind, LD, PW)
+ end;
+cind_pairs_tail(_, _Col0, _Col, _Ll, _M, Ind, _LD, _W) ->
+ Ind.
+
+cind_pair({{map_pair, _Key, _Value}, Len}=Pair, Col, Ll, M, _Ind, LD, W)
+ when Len < Ll - Col - LD, Len + W + LD =< M ->
+ if
+ ?ATM_PAIR(Pair) ->
+ Len;
+ true ->
+ Ll
+ end;
+cind_pair({{map_pair, K, V}, _Len}, Col0, Ll, M, Ind, LD, W0) ->
+ cind(K, Col0, Ll, M, Ind, LD, W0),
+ I = map_value_indent(Ind),
+ cind(V, Col0 + I, Ll, M, Ind, LD, 0),
+ Ll.
+
+map_value_indent(TInd) ->
+ case TInd > 0 of
+ true ->
+ TInd;
+ false ->
+ 4
+ end.
+
cind_record([F | Fs], Nlen, Col0, Ll, M, Ind, LD, W0) ->
Nind = Nlen + 1,
{Col, W} = cind_rec(Nind, Col0, Ll, M, Ind, W0),
@@ -736,9 +859,11 @@ while_fail([], _F, V) ->
while_fail([A | As], F, V) ->
try F(A) catch _ -> while_fail(As, F, V) end.
+%% make a string of N spaces
indent(N) when is_integer(N), N > 0 ->
chars($\s, N-1).
+%% prepend N spaces onto Ind
indent(1, Ind) -> % Optimization of common case
[$\s | Ind];
indent(4, Ind) -> % Optimization of common case
diff --git a/lib/stdlib/src/lib.erl b/lib/stdlib/src/lib.erl
index 56654097d9..c6eb0d7915 100644
--- a/lib/stdlib/src/lib.erl
+++ b/lib/stdlib/src/lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,9 +22,12 @@
-export([flush_receive/0, error_message/2, progname/0, nonl/1, send/2,
sendw/2, eval_str/1]).
+-export([extended_parse_exprs/1, extended_parse_term/1,
+ subst_values_for_vars/2]).
+
-export([format_exception/6, format_exception/7,
format_stacktrace/4, format_stacktrace/5,
- format_call/4, format_call/5, format_fun/1]).
+ format_call/4, format_call/5, format_fun/1, format_fun/2]).
-spec flush_receive() -> 'ok'.
@@ -127,6 +130,224 @@ all_white([$\t|T]) -> all_white(T);
all_white([]) -> true;
all_white(_) -> false.
+%% `Tokens' is assumed to have been scanned with the 'text' option.
+%% The annotations of the returned expressions are locations.
+%%
+%% Can handle pids, ports, references, and external funs ("items").
+%% Known items are represented by variables in the erl_parse tree, and
+%% the items themselves are stored in the returned bindings.
+
+-spec extended_parse_exprs(Tokens) ->
+ {'ok', ExprList, Bindings} | {'error', ErrorInfo} when
+ Tokens :: [erl_scan:token()],
+ ExprList :: [erl_parse:abstract_expr()],
+ Bindings :: erl_eval:binding_struct(),
+ ErrorInfo :: erl_parse:error_info().
+
+extended_parse_exprs(Tokens) ->
+ Ts = tokens_fixup(Tokens),
+ case erl_parse:parse_exprs(Ts) of
+ {ok, Exprs0} ->
+ {Exprs, Bs} = expr_fixup(Exprs0),
+ {ok, reset_expr_anno(Exprs), Bs};
+ _ErrorInfo ->
+ erl_parse:parse_exprs(reset_token_anno(Ts))
+ end.
+
+tokens_fixup([]) -> [];
+tokens_fixup([T|Ts]=Ts0) ->
+ try token_fixup(Ts0) of
+ {NewT, NewTs} ->
+ [NewT|tokens_fixup(NewTs)]
+ catch
+ _:_ ->
+ [T|tokens_fixup(Ts)]
+ end.
+
+token_fixup(Ts) ->
+ {AnnoL, NewTs, FixupTag} = unscannable(Ts),
+ String = lists:append([erl_anno:text(A) || A <- AnnoL]),
+ _ = (fixup_fun(FixupTag))(String),
+ NewAnno = erl_anno:set_text(fixup_text(FixupTag), hd(AnnoL)),
+ {{string, NewAnno, String}, NewTs}.
+
+unscannable([{'#', A1}, {var, A2, 'Fun'}, {'<', A3}, {atom, A4, _},
+ {'.', A5}, {float, A6, _}, {'>', A7}|Ts]) ->
+ {[A1, A2, A3, A4, A5, A6, A7], Ts, function};
+unscannable([{'#', A1}, {var, A2, 'Fun'}, {'<', A3}, {atom, A4, _},
+ {'.', A5}, {atom, A6, _}, {'.', A7}, {integer, A8, _},
+ {'>', A9}|Ts]) ->
+ {[A1, A2, A3, A4, A5, A6, A7, A8, A9], Ts, function};
+unscannable([{'<', A1}, {float, A2, _}, {'.', A3}, {integer, A4, _},
+ {'>', A5}|Ts]) ->
+ {[A1, A2, A3, A4, A5], Ts, pid};
+unscannable([{'#', A1}, {var, A2, 'Port'}, {'<', A3}, {float, A4, _},
+ {'>', A5}|Ts]) ->
+ {[A1, A2, A3, A4, A5], Ts, port};
+unscannable([{'#', A1}, {var, A2, 'Ref'}, {'<', A3}, {float, A4, _},
+ {'.', A5}, {float, A6, _}, {'>', A7}|Ts]) ->
+ {[A1, A2, A3, A4, A5, A6, A7], Ts, reference}.
+
+expr_fixup(Expr0) ->
+ {Expr, Bs, _} = expr_fixup(Expr0, erl_eval:new_bindings(), 1),
+ {Expr, Bs}.
+
+expr_fixup({string,A,S}=T, Bs0, I) ->
+ try string_fixup(A, S) of
+ Value ->
+ Var = new_var(I),
+ Bs = erl_eval:add_binding(Var, Value, Bs0),
+ {{var, A, Var}, Bs, I+1}
+ catch
+ _:_ ->
+ {T, Bs0, I}
+ end;
+expr_fixup(Tuple, Bs0, I0) when is_tuple(Tuple) ->
+ {L, Bs, I} = expr_fixup(tuple_to_list(Tuple), Bs0, I0),
+ {list_to_tuple(L), Bs, I};
+expr_fixup([E0|Es0], Bs0, I0) ->
+ {E, Bs1, I1} = expr_fixup(E0, Bs0, I0),
+ {Es, Bs, I} = expr_fixup(Es0, Bs1, I1),
+ {[E|Es], Bs, I};
+expr_fixup(T, Bs, I) ->
+ {T, Bs, I}.
+
+string_fixup(A, S) ->
+ Text = erl_anno:text(A),
+ FixupTag = fixup_tag(Text, S),
+ (fixup_fun(FixupTag))(S).
+
+new_var(I) ->
+ list_to_atom(lists:concat(['__ExtendedParseExprs_', I, '__'])).
+
+reset_token_anno(Tokens) ->
+ [setelement(2, T, (reset_anno())(element(2, T))) || T <- Tokens].
+
+reset_expr_anno(Exprs) ->
+ [erl_parse:map_anno(reset_anno(), E) || E <- Exprs].
+
+reset_anno() ->
+ fun(A) -> erl_anno:new(erl_anno:location(A)) end.
+
+fixup_fun(function) -> fun function/1;
+fixup_fun(pid) -> fun erlang:list_to_pid/1;
+fixup_fun(port) -> fun erlang:list_to_port/1;
+fixup_fun(reference) -> fun erlang:list_to_ref/1.
+
+function(S) ->
+ %% External function.
+ {ok, [_, _, _,
+ {atom, _, Module}, _,
+ {atom, _, Function}, _,
+ {integer, _, Arity}|_], _} = erl_scan:string(S),
+ erlang:make_fun(Module, Function, Arity).
+
+fixup_text(function) -> "function";
+fixup_text(pid) -> "pid";
+fixup_text(port) -> "port";
+fixup_text(reference) -> "reference".
+
+fixup_tag("function", "#"++_) -> function;
+fixup_tag("pid", "<"++_) -> pid;
+fixup_tag("port", "#"++_) -> port;
+fixup_tag("reference", "#"++_) -> reference.
+
+%%% End of extended_parse_exprs.
+
+%% `Tokens' is assumed to have been scanned with the 'text' option.
+%%
+%% Can handle pids, ports, references, and external funs.
+
+-spec extended_parse_term(Tokens) ->
+ {'ok', Term} | {'error', ErrorInfo} when
+ Tokens :: [erl_scan:token()],
+ Term :: term(),
+ ErrorInfo :: erl_parse:error_info().
+
+extended_parse_term(Tokens) ->
+ case extended_parse_exprs(Tokens) of
+ {ok, [Expr], Bindings} ->
+ try normalise(Expr, Bindings) of
+ Term ->
+ {ok, Term}
+ catch
+ _:_ ->
+ Loc = erl_anno:location(element(2, Expr)),
+ {error,{Loc,?MODULE,"bad term"}}
+ end;
+ {ok, [_,Expr|_], _Bindings} ->
+ Loc = erl_anno:location(element(2, Expr)),
+ {error,{Loc,?MODULE,"bad term"}};
+ {error, _} = Error ->
+ Error
+ end.
+
+%% From erl_parse.
+normalise({var, _, V}, Bs) ->
+ {value, Value} = erl_eval:binding(V, Bs),
+ Value;
+normalise({char,_,C}, _Bs) -> C;
+normalise({integer,_,I}, _Bs) -> I;
+normalise({float,_,F}, _Bs) -> F;
+normalise({atom,_,A}, _Bs) -> A;
+normalise({string,_,S}, _Bs) -> S;
+normalise({nil,_}, _Bs) -> [];
+normalise({bin,_,Fs}, Bs) ->
+ {value, B, _} =
+ eval_bits:expr_grp(Fs, [],
+ fun(E, _) ->
+ {value, normalise(E, Bs), []}
+ end, [], true),
+ B;
+normalise({cons,_,Head,Tail}, Bs) ->
+ [normalise(Head, Bs)|normalise(Tail, Bs)];
+normalise({tuple,_,Args}, Bs) ->
+ list_to_tuple(normalise_list(Args, Bs));
+normalise({map,_,Pairs}, Bs) ->
+ maps:from_list(lists:map(fun
+ %% only allow '=>'
+ ({map_field_assoc,_,K,V}) ->
+ {normalise(K, Bs),normalise(V, Bs)}
+ end, Pairs));
+%% Special case for unary +/-.
+normalise({op,_,'+',{char,_,I}}, _Bs) -> I;
+normalise({op,_,'+',{integer,_,I}}, _Bs) -> I;
+normalise({op,_,'+',{float,_,F}}, _Bs) -> F;
+normalise({op,_,'-',{char,_,I}}, _Bs) -> -I; %Weird, but compatible!
+normalise({op,_,'-',{integer,_,I}}, _Bs) -> -I;
+normalise({op,_,'-',{float,_,F}}, _Bs) -> -F;
+normalise({'fun',_,{function,{atom,_,M},{atom,_,F},{integer,_,A}}}, _Bs) ->
+ %% Since "#Fun<M.F.A>" is recognized, "fun M:F/A" should be too.
+ fun M:F/A.
+
+normalise_list([H|T], Bs) ->
+ [normalise(H, Bs)|normalise_list(T, Bs)];
+normalise_list([], _Bs) ->
+ [].
+
+%% To be used on ExprList and Bindings returned from extended_parse_exprs().
+%% Substitute {value, A, Item} for {var, A, ExtendedParseVar}.
+%% {value, A, Item} is a shell/erl_eval convention, and for example
+%% the linter cannot handle it.
+
+-spec subst_values_for_vars(ExprList, Bindings) -> [term()] when
+ ExprList :: [erl_parse:abstract_expr()],
+ Bindings :: erl_eval:binding_struct().
+
+subst_values_for_vars({var, A, V}=Var, Bs) ->
+ case erl_eval:binding(V, Bs) of
+ {value, Value} ->
+ {value, A, Value};
+ unbound ->
+ Var
+ end;
+subst_values_for_vars(L, Bs) when is_list(L) ->
+ [subst_values_for_vars(E, Bs) || E <- L];
+subst_values_for_vars(T, Bs) when is_tuple(T) ->
+ list_to_tuple(subst_values_for_vars(tuple_to_list(T), Bs));
+subst_values_for_vars(T, _Bs) ->
+ T.
+
%%% Formatting of exceptions, mfa:s and funs.
%% -> iolist() (no \n at end)
@@ -179,7 +400,11 @@ format_call(I, ForMForFun, As, FormatFun, Enc)
format_call("", n_spaces(I-1), ForMForFun, As, FormatFun, Enc).
%% -> iolist() (no \n at end)
-format_fun(Fun) when is_function(Fun) ->
+format_fun(Fun) ->
+ format_fun(Fun, latin1).
+
+%% -> iolist() (no \n at end)
+format_fun(Fun, Enc) when is_function(Fun) ->
{module, M} = erlang:fun_info(Fun, module),
{name, F} = erlang:fun_info(Fun, name),
{arity, A} = erlang:fun_info(Fun, arity),
@@ -189,9 +414,9 @@ format_fun(Fun) when is_function(Fun) ->
{type, local} when M =:= erl_eval ->
io_lib:fwrite(<<"interpreted function with arity ~w">>, [A]);
{type, local} ->
- mfa_to_string(M, F, A);
+ mfa_to_string(M, F, A, Enc);
{type, external} ->
- mfa_to_string(M, F, A)
+ mfa_to_string(M, F, A, Enc)
end.
analyze_exception(error, Term, Stack) ->
@@ -233,11 +458,11 @@ explain_reason({badarg,V}, error=Cl, [], PF, S, _Enc) -> % orelse, andalso
format_value(V, <<"bad argument: ">>, Cl, PF, S);
explain_reason(badarith, error, [], _PF, _S, _Enc) ->
<<"an error occurred when evaluating an arithmetic expression">>;
-explain_reason({badarity,{Fun,As}}, error, [], _PF, _S, _Enc)
+explain_reason({badarity,{Fun,As}}, error, [], _PF, _S, Enc)
when is_function(Fun) ->
%% Only the arity is displayed, not the arguments As.
- io_lib:fwrite(<<"~s called with ~s">>,
- [format_fun(Fun), argss(length(As))]);
+ io_lib:fwrite(<<"~ts called with ~s">>,
+ [format_fun(Fun, Enc), argss(length(As))]);
explain_reason({badfun,Term}, error=Cl, [], PF, S, _Enc) ->
format_value(Term, <<"bad function ">>, Cl, PF, S);
explain_reason({badmatch,Term}, error=Cl, [], PF, S, _Enc) ->
@@ -268,14 +493,15 @@ explain_reason({try_clause,V}, error=Cl, [], PF, S, _Enc) ->
%% "there is no try clause with a true guard sequence and a
%% pattern matching..."
format_value(V, <<"no try clause matching ">>, Cl, PF, S);
-explain_reason(undef, error, [{M,F,A,_}], _PF, _S, _Enc) ->
+explain_reason(undef, error, [{M,F,A,_}], _PF, _S, Enc) ->
%% Only the arity is displayed, not the arguments, if there are any.
- io_lib:fwrite(<<"undefined function ~s">>,
- [mfa_to_string(M, F, n_args(A))]);
-explain_reason({shell_undef,F,A,_}, error, [], _PF, _S, _Enc) ->
+ io_lib:fwrite(<<"undefined function ~ts">>,
+ [mfa_to_string(M, F, n_args(A), Enc)]);
+explain_reason({shell_undef,F,A,_}, error, [], _PF, _S, Enc) ->
%% Give nicer reports for undefined shell functions
%% (but not when the user actively calls shell_default:F(...)).
- io_lib:fwrite(<<"undefined shell command ~s/~w">>, [F, n_args(A)]);
+ FS = to_string(F, Enc),
+ io_lib:fwrite(<<"undefined shell command ~ts/~w">>, [FS, n_args(A)]);
%% Exit codes returned by erl_eval only:
explain_reason({argument_limit,_Fun}, error, [], _PF, _S, _Enc) ->
io_lib:fwrite(<<"limit of number of arguments to interpreted function"
@@ -325,17 +551,18 @@ format_stacktrace1(S0, Stack0, PF, SF, Enc) ->
format_stacktrace2(S, Stack, 1, PF, Enc).
format_stacktrace2(S, [{M,F,A,L}|Fs], N, PF, Enc) when is_integer(A) ->
- [io_lib:fwrite(<<"~s~s ~s ~s">>,
+ [io_lib:fwrite(<<"~s~s ~ts ~s">>,
[sep(N, S), origin(N, M, F, A),
- mfa_to_string(M, F, A),
+ mfa_to_string(M, F, A, Enc),
location(L)])
| format_stacktrace2(S, Fs, N + 1, PF, Enc)];
format_stacktrace2(S, [{M,F,As,_}|Fs], N, PF, Enc) when is_list(As) ->
A = length(As),
CalledAs = [S,<<" called as ">>],
C = format_call("", CalledAs, {M,F}, As, PF, Enc),
- [io_lib:fwrite(<<"~s~s ~s\n~s~ts">>,
- [sep(N, S), origin(N, M, F, A), mfa_to_string(M, F, A),
+ [io_lib:fwrite(<<"~s~s ~ts\n~s~ts">>,
+ [sep(N, S), origin(N, M, F, A),
+ mfa_to_string(M, F, A, Enc),
CalledAs, C])
| format_stacktrace2(S, Fs, N + 1, PF, Enc)];
format_stacktrace2(_S, [], _N, _PF, _Enc) ->
@@ -373,10 +600,10 @@ format_call(ErrStr, Pre1, ForMForFun, As, PF, Enc) ->
{yes,Op} ->
format_op(ErrStr, Pre1, Op, As, PF, Enc);
no ->
- MFs = mf_to_string(ForMForFun, Arity),
- I1 = iolist_size([Pre1,ErrStr|MFs]),
+ MFs = mf_to_string(ForMForFun, Arity, Enc),
+ I1 = string:length([Pre1,ErrStr|MFs]),
S1 = pp_arguments(PF, As, I1, Enc),
- S2 = pp_arguments(PF, As, iolist_size([Pre1|MFs]), Enc),
+ S2 = pp_arguments(PF, As, string:length([Pre1|MFs]), Enc),
Long = count_nl(pp_arguments(PF, [a2345,b2345], I1, Enc)) > 0,
case Long or (count_nl(S2) < count_nl(S1)) of
true ->
@@ -435,10 +662,10 @@ printable_list(latin1, As) ->
printable_list(_, As) ->
io_lib:printable_list(As).
-mfa_to_string(M, F, A) ->
- io_lib:fwrite(<<"~s/~w">>, [mf_to_string({M, F}, A), A]).
+mfa_to_string(M, F, A, Enc) ->
+ io_lib:fwrite(<<"~ts/~w">>, [mf_to_string({M, F}, A, Enc), A]).
-mf_to_string({M, F}, A) ->
+mf_to_string({M, F}, A, Enc) ->
case erl_internal:bif(M, F, A) of
true ->
io_lib:fwrite(<<"~w">>, [F]);
@@ -449,13 +676,15 @@ mf_to_string({M, F}, A) ->
{yes, F} ->
atom_to_list(F);
no ->
- io_lib:fwrite(<<"~w:~w">>, [M, F])
+ FS = to_string(F, Enc),
+ io_lib:fwrite(<<"~w:~ts">>, [M, FS])
end
end;
-mf_to_string(Fun, _A) when is_function(Fun) ->
- format_fun(Fun);
-mf_to_string(F, _A) ->
- io_lib:fwrite(<<"~w">>, [F]).
+mf_to_string(Fun, _A, Enc) when is_function(Fun) ->
+ format_fun(Fun, Enc);
+mf_to_string(F, _A, Enc) ->
+ FS = to_string(F, Enc),
+ io_lib:fwrite(<<"~ts">>, [FS]).
format_value(V, ErrStr, Class, PF, S) ->
Pre1Sz = exited_size(Class),
@@ -504,9 +733,14 @@ exited(exit) ->
exited(throw) ->
<<"exception throw: ">>.
+to_string(A, latin1) ->
+ io_lib:write_atom_as_latin1(A);
+to_string(A, _) ->
+ io_lib:write_atom(A).
+
size(latin1, S) ->
{iolist_size(S),S};
size(_, S0) ->
S = unicode:characters_to_list(S0, unicode),
true = is_list(S),
- {length(S),S}.
+ {string:length(S),S}.
diff --git a/lib/stdlib/src/math.erl b/lib/stdlib/src/math.erl
index 97c965e27a..3a3b384d8f 100644
--- a/lib/stdlib/src/math.erl
+++ b/lib/stdlib/src/math.erl
@@ -25,7 +25,9 @@
-export([sin/1, cos/1, tan/1, asin/1, acos/1, atan/1, atan2/2, sinh/1,
cosh/1, tanh/1, asinh/1, acosh/1, atanh/1, exp/1, log/1,
- log2/1, log10/1, pow/2, sqrt/1, erf/1, erfc/1]).
+ log2/1, log10/1, pow/2, sqrt/1, erf/1, erfc/1,
+ ceil/1, floor/1,
+ fmod/2]).
-spec acos(X) -> float() when
X :: number().
@@ -63,6 +65,11 @@ atan2(_, _) ->
atanh(_) ->
erlang:nif_error(undef).
+-spec ceil(X) -> float() when
+ X :: number().
+ceil(_) ->
+ erlang:nif_error(undef).
+
-spec cos(X) -> float() when
X :: number().
cos(_) ->
@@ -88,6 +95,16 @@ erfc(_) ->
exp(_) ->
erlang:nif_error(undef).
+-spec floor(X) -> float() when
+ X :: number().
+floor(_) ->
+ erlang:nif_error(undef).
+
+-spec fmod(X, Y) -> float() when
+ X :: number(), Y :: number().
+fmod(_, _) ->
+ erlang:nif_error(undef).
+
-spec log(X) -> float() when
X :: number().
log(_) ->
diff --git a/lib/stdlib/src/ms_transform.erl b/lib/stdlib/src/ms_transform.erl
index c0eea652e7..6616e957c0 100644
--- a/lib/stdlib/src/ms_transform.erl
+++ b/lib/stdlib/src/ms_transform.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -91,12 +91,12 @@ format_error(?ERR_GUARDMATCH) ->
"fun with guard matching ('=' in guard) is illegal as match_spec as well";
format_error({?ERR_GUARDLOCALCALL, Name, Arithy}) ->
lists:flatten(io_lib:format("fun containing the local function call "
- "'~w/~w' (called in guard) "
+ "'~tw/~w' (called in guard) "
"cannot be translated into match_spec",
[Name, Arithy]));
format_error({?ERR_GUARDREMOTECALL, Module, Name, Arithy}) ->
lists:flatten(io_lib:format("fun containing the remote function call "
- "'~w:~w/~w' (called in guard) "
+ "'~w:~tw/~w' (called in guard) "
"cannot be translated into match_spec",
[Module,Name,Arithy]));
format_error({?ERR_GUARDELEMENT, Str}) ->
@@ -117,12 +117,12 @@ format_error(?ERR_BODYMATCH) ->
"fun with body matching ('=' in body) is illegal as match_spec";
format_error({?ERR_BODYLOCALCALL, Name, Arithy}) ->
lists:flatten(io_lib:format("fun containing the local function "
- "call '~w/~w' (called in body) "
+ "call '~tw/~w' (called in body) "
"cannot be translated into match_spec",
[Name,Arithy]));
format_error({?ERR_BODYREMOTECALL, Module, Name, Arithy}) ->
lists:flatten(io_lib:format("fun containing the remote function call "
- "'~w:~w/~w' (called in body) "
+ "'~w:~tw/~w' (called in body) "
"cannot be translated into match_spec",
[Module,Name,Arithy]));
format_error({?ERR_BODYELEMENT, Str}) ->
@@ -147,15 +147,15 @@ format_error({?ERR_UNBOUND_VARIABLE, Str}) ->
"into match_spec", [Str]));
format_error({?ERR_HEADBADREC,Name}) ->
lists:flatten(
- io_lib:format("fun head contains unknown record type ~w",[Name]));
+ io_lib:format("fun head contains unknown record type ~tw",[Name]));
format_error({?ERR_HEADBADFIELD,RName,FName}) ->
lists:flatten(
- io_lib:format("fun head contains reference to unknown field ~w in "
- "record type ~w",[FName, RName]));
+ io_lib:format("fun head contains reference to unknown field ~tw in "
+ "record type ~tw",[FName, RName]));
format_error({?ERR_HEADMULTIFIELD,RName,FName}) ->
lists:flatten(
- io_lib:format("fun head contains already defined field ~w in "
- "record type ~w",[FName, RName]));
+ io_lib:format("fun head contains already defined field ~tw in "
+ "record type ~tw",[FName, RName]));
format_error({?ERR_HEADDOLLARATOM,Atom}) ->
lists:flatten(
io_lib:format("fun head contains atom ~w, which conflics with reserved "
@@ -166,28 +166,28 @@ format_error({?ERR_HEADBINMATCH,Atom}) ->
"which cannot be translated into match_spec", [Atom]));
format_error({?ERR_GUARDBADREC,Name}) ->
lists:flatten(
- io_lib:format("fun guard contains unknown record type ~w",[Name]));
+ io_lib:format("fun guard contains unknown record type ~tw",[Name]));
format_error({?ERR_GUARDBADFIELD,RName,FName}) ->
lists:flatten(
- io_lib:format("fun guard contains reference to unknown field ~w in "
- "record type ~w",[FName, RName]));
+ io_lib:format("fun guard contains reference to unknown field ~tw in "
+ "record type ~tw",[FName, RName]));
format_error({?ERR_GUARDMULTIFIELD,RName,FName}) ->
lists:flatten(
- io_lib:format("fun guard contains already defined field ~w in "
- "record type ~w",[FName, RName]));
+ io_lib:format("fun guard contains already defined field ~tw in "
+ "record type ~tw",[FName, RName]));
format_error({?ERR_BODYBADREC,Name}) ->
lists:flatten(
- io_lib:format("fun body contains unknown record type ~w",[Name]));
+ io_lib:format("fun body contains unknown record type ~tw",[Name]));
format_error({?ERR_BODYBADFIELD,RName,FName}) ->
lists:flatten(
- io_lib:format("fun body contains reference to unknown field ~w in "
- "record type ~w",[FName, RName]));
+ io_lib:format("fun body contains reference to unknown field ~tw in "
+ "record type ~tw",[FName, RName]));
format_error({?ERR_BODYMULTIFIELD,RName,FName}) ->
lists:flatten(
- io_lib:format("fun body contains already defined field ~w in "
- "record type ~w",[FName, RName]));
+ io_lib:format("fun body contains already defined field ~tw in "
+ "record type ~tw",[FName, RName]));
format_error(Else) ->
- lists:flatten(io_lib:format("Unknown error code ~w",[Else])).
+ lists:flatten(io_lib:format("Unknown error code ~tw",[Else])).
%%
%% Called when translating in shell
@@ -451,6 +451,8 @@ check_type(_,[{record,_,_,_}],ets) ->
ok;
check_type(_,[{cons,_,_,_}],dbg) ->
ok;
+check_type(_,[{nil,_}],dbg) ->
+ ok;
check_type(Line0,[{match,_,{var,_,_},X}],Any) ->
check_type(Line0,[X],Any);
check_type(Line0,[{match,_,X,{var,_,_}}],Any) ->
@@ -499,10 +501,20 @@ tg0(Line,[H|T],B) ->
tg({match,Line,_,_},B) ->
throw({error,Line,?ERR_GENMATCH+B#tgd.eb});
-tg({op, Line, Operator, O1, O2}, B) ->
- {tuple, Line, [{atom, Line, Operator}, tg(O1,B), tg(O2,B)]};
-tg({op, Line, Operator, O1}, B) ->
- {tuple, Line, [{atom, Line, Operator}, tg(O1,B)]};
+tg({op, Line, Operator, O1, O2}=Expr, B) ->
+ case erl_eval:partial_eval(Expr) of
+ Expr ->
+ {tuple, Line, [{atom, Line, Operator}, tg(O1, B), tg(O2, B)]};
+ Value ->
+ Value
+ end;
+tg({op, Line, Operator, O1}=Expr, B) ->
+ case erl_eval:partial_eval(Expr) of
+ Expr ->
+ {tuple, Line, [{atom, Line, Operator}, tg(O1, B)]};
+ Value ->
+ Value
+ end;
tg({call, _Line, {atom, Line2, bindings},[]},_B) ->
{atom, Line2, '$*'};
tg({call, _Line, {atom, Line2, object},[]},_B) ->
@@ -721,7 +733,7 @@ tg(T,B) when is_tuple(T), tuple_size(T) >= 2 ->
throw({error,Line,{?ERR_GENELEMENT+B#tgd.eb,
translate_language_element(Element)}});
tg(Other,B) ->
- Element = io_lib:format("unknown element ~w", [Other]),
+ Element = io_lib:format("unknown element ~tw", [Other]),
throw({error,unknown,{?ERR_GENELEMENT+B#tgd.eb,Element}}).
transform_head([V],OuterBound) ->
diff --git a/lib/stdlib/src/orddict.erl b/lib/stdlib/src/orddict.erl
index 37cf0084f0..9a2772949b 100644
--- a/lib/stdlib/src/orddict.erl
+++ b/lib/stdlib/src/orddict.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@
%% Standard interface.
-export([new/0,is_key/2,to_list/1,from_list/1,size/1,is_empty/1]).
--export([fetch/2,find/2,fetch_keys/1,erase/2]).
+-export([fetch/2,find/2,fetch_keys/1,erase/2,take/2]).
-export([store/3,append/3,append_list/3,update/3,update/4,update_counter/3]).
-export([fold/3,map/2,filter/2,merge/3]).
@@ -106,6 +106,23 @@ erase(Key, [{K,_}=E|Dict]) when Key > K ->
erase(_Key, [{_K,_Val}|Dict]) -> Dict; %Key == K
erase(_, []) -> [].
+-spec take(Key, Orddict) -> {Value, Orddict1} | error when
+ Orddict :: orddict(Key, Value),
+ Orddict1 :: orddict(Key, Value),
+ Key :: term(),
+ Value :: term().
+
+take(Key, Dict) ->
+ take_1(Key, Dict, []).
+
+take_1(Key, [{K,_}|_], _Acc) when Key < K ->
+ error;
+take_1(Key, [{K,_}=P|D], Acc) when Key > K ->
+ take_1(Key, D, [P|Acc]);
+take_1(_Key, [{_K,Value}|D], Acc) ->
+ {Value,lists:reverse(Acc, D)};
+take_1(_, [], _) -> error.
+
-spec store(Key, Value, Orddict1) -> Orddict2 when
Orddict1 :: orddict(Key, Value),
Orddict2 :: orddict(Key, Value).
diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl
index 3bd338071b..9e9c0dc413 100644
--- a/lib/stdlib/src/otp_internal.erl
+++ b/lib/stdlib/src/otp_internal.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -47,9 +47,6 @@ obsolete(Module, Name, Arity) ->
obsolete_1(net, _, _) ->
{deprecated, "module 'net' obsolete; use 'net_adm'"};
-obsolete_1(erlang, hash, 2) ->
- {deprecated, {erlang, phash2, 2}};
-
obsolete_1(erlang, now, 0) ->
{deprecated,
"Deprecated BIF. See the \"Time and Time Correction in Erlang\" "
@@ -58,6 +55,60 @@ obsolete_1(erlang, now, 0) ->
obsolete_1(calendar, local_time_to_universal_time, 1) ->
{deprecated, {calendar, local_time_to_universal_time_dst, 1}};
+%% *** STDLIB added in OTP 20 ***
+
+obsolete_1(gen_fsm, start, 3) ->
+ {deprecated, {gen_statem, start, 3}};
+obsolete_1(gen_fsm, start, 4) ->
+ {deprecated, {gen_statem, start, 4}};
+
+obsolete_1(gen_fsm, start_link, 3) ->
+ {deprecated, {gen_statem, start, 3}};
+obsolete_1(gen_fsm, start_link, 4) ->
+ {deprecated, {gen_statem, start, 4}};
+
+obsolete_1(gen_fsm, stop, 1) ->
+ {deprecated, {gen_statem, stop, 1}};
+obsolete_1(gen_fsm, stop, 3) ->
+ {deprecated, {gen_statem, stop, 3}};
+
+obsolete_1(gen_fsm, enter_loop, 4) ->
+ {deprecated, {gen_statem, enter_loop, 4}};
+obsolete_1(gen_fsm, enter_loop, 5) ->
+ {deprecated, {gen_statem, enter_loop, 5}};
+obsolete_1(gen_fsm, enter_loop, 6) ->
+ {deprecated, {gen_statem, enter_loop, 6}};
+
+obsolete_1(gen_fsm, reply, 2) ->
+ {deprecated, {gen_statem, reply, 2}};
+
+obsolete_1(gen_fsm, send_event, 2) ->
+ {deprecated, {gen_statem, cast, 1}};
+obsolete_1(gen_fsm, send_all_state_event, 2) ->
+ {deprecated, {gen_statem, cast, 1}};
+
+obsolete_1(gen_fsm, sync_send_event, 2) ->
+ {deprecated, {gen_statem, call, 2}};
+obsolete_1(gen_fsm, sync_send_event, 3) ->
+ {deprecated, {gen_statem, call, 3}};
+
+obsolete_1(gen_fsm, sync_send_all_state_event, 2) ->
+ {deprecated, {gen_statem, call, 2}};
+obsolete_1(gen_fsm, sync_send_all_state_event, 3) ->
+ {deprecated, {gen_statem, call, 3}};
+
+obsolete_1(gen_fsm, start_timer, 2) ->
+ {deprecated, {erlang, start_timer, 2}};
+obsolete_1(gen_fsm, cancel_timer, 1) ->
+ {deprecated, {erlang, cancel_timer, 1}};
+obsolete_1(gen_fsm, send_event_after, 2) ->
+ {deprecated, {erlang, send_after, 2}};
+
+%% *** CRYPTO added in OTP 20 ***
+
+obsolete_1(crypto, rand_uniform, 2) ->
+ {deprecated, {rand, uniform, 1}};
+
%% *** CRYPTO added in OTP 19 ***
obsolete_1(crypto, rand_bytes, 1) ->
@@ -66,178 +117,178 @@ obsolete_1(crypto, rand_bytes, 1) ->
%% *** CRYPTO added in R16B01 ***
obsolete_1(crypto, md4, 1) ->
- {deprecated, {crypto, hash, 2}};
+ {removed, {crypto, hash, 2}, "20.0"};
obsolete_1(crypto, md5, 1) ->
- {deprecated, {crypto, hash, 2}};
+ {removed, {crypto, hash, 2}, "20.0"};
obsolete_1(crypto, sha, 1) ->
- {deprecated, {crypto, hash, 2}};
+ {removed, {crypto, hash, 2}, "20.0"};
obsolete_1(crypto, md4_init, 0) ->
- {deprecated, {crypto, hash_init, 1}};
+ {removed, {crypto, hash_init, 1}, "20.0"};
obsolete_1(crypto, md5_init, 0) ->
- {deprecated, {crypto, hash_init, 1}};
+ {removed, {crypto, hash_init, 1}, "20.0"};
obsolete_1(crypto, sha_init, 0) ->
- {deprecated, {crypto, hash_init, 1}};
+ {removed, {crypto, hash_init, 1}, "20.0"};
obsolete_1(crypto, md4_update, 2) ->
- {deprecated, {crypto, hash_update, 2}};
+ {removed, {crypto, hash_update, 2}, "20.0"};
obsolete_1(crypto, md5_update, 2) ->
- {deprecated, {crypto, hash_update, 2}};
+ {removed, {crypto, hash_update, 2}, "20.0"};
obsolete_1(crypto, sha_update, 2) ->
- {deprecated, {crypto, hash_update, 2}};
+ {removed, {crypto, hash_update, 2}, "20.0"};
obsolete_1(crypto, md4_final, 1) ->
- {deprecated, {crypto, hash_final, 1}};
+ {removed, {crypto, hash_final, 1}, "20.0"};
obsolete_1(crypto, md5_final, 1) ->
- {deprecated, {crypto, hash_final, 1}};
+ {removed, {crypto, hash_final, 1}, "20.0"};
obsolete_1(crypto, sha_final, 1) ->
- {deprecated, {crypto, hash_final, 1}};
+ {removed, {crypto, hash_final, 1}, "20.0"};
obsolete_1(crypto, md5_mac, 2) ->
- {deprecated, {crypto, hmac, 3}};
+ {removed, {crypto, hmac, 3}, "20.0"};
obsolete_1(crypto, sha_mac, 2) ->
- {deprecated, {crypto, hmac, 3}};
+ {removed, {crypto, hmac, 3}, "20.0"};
obsolete_1(crypto, sha_mac, 3) ->
- {deprecated, {crypto, hmac, 4}};
+ {removed, {crypto, hmac, 4}, "20.0"};
obsolete_1(crypto, sha_mac_96, 2) ->
- {deprecated, {crypto, hmac, 4}};
+ {removed, {crypto, hmac, 4}, "20.0"};
obsolete_1(crypto, md5_mac_96, 2) ->
- {deprecated, {crypto, hmac, 4}};
+ {removed, {crypto, hmac, 4}, "20.0"};
obsolete_1(crypto, rsa_sign, 2) ->
- {deprecated, {crypto, sign, 4}};
+ {removed, {crypto, sign, 4}, "20.0"};
obsolete_1(crypto, rsa_sign, 3) ->
- {deprecated, {crypto, sign, 4}};
+ {removed, {crypto, sign, 4}, "20.0"};
obsolete_1(crypto, rsa_verify, 3) ->
- {deprecated, {crypto, verify, 5}};
+ {removed, {crypto, verify, 5}, "20.0"};
obsolete_1(crypto, rsa_verify, 4) ->
- {deprecated, {crypto, verify, 5}};
+ {removed, {crypto, verify, 5}, "20.0"};
obsolete_1(crypto, dss_sign, 2) ->
- {deprecated, {crypto, sign, 4}};
+ {removed, {crypto, sign, 4}, "20.0"};
obsolete_1(crypto, dss_sign, 3) ->
- {deprecated, {crypto, sign, 4}};
+ {removed, {crypto, sign, 4}, "20.0"};
obsolete_1(crypto, dss_verify, 3) ->
- {deprecated, {crypto, verify, 5}};
+ {removed, {crypto, verify, 5}, "20.0"};
obsolete_1(crypto, dss_verify, 4) ->
- {deprecated, {crypto, verify, 5}};
+ {removed, {crypto, verify, 5}, "20.0"};
obsolete_1(crypto, mod_exp, 3) ->
- {deprecated, {crypto, mod_pow, 3}};
+ {removed, {crypto, mod_pow, 3}, "20.0"};
obsolete_1(crypto, dh_compute_key, 3) ->
- {deprecated, {crypto, compute_key, 4}};
+ {removed, {crypto, compute_key, 4}, "20.0"};
obsolete_1(crypto, dh_generate_key, 1) ->
- {deprecated, {crypto, generate_key, 2}};
+ {removed, {crypto, generate_key, 2}, "20.0"};
obsolete_1(crypto, dh_generate_key, 2) ->
- {deprecated, {crypto, generate_key, 3}};
+ {removed, {crypto, generate_key, 3}, "20.0"};
obsolete_1(crypto, des_cbc_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, des3_cbc_encrypt, 5) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, des_ecb_encrypt, 2) ->
- {deprecated, {crypto, block_encrypt, 3}};
+ {removed, {crypto, block_encrypt, 3}, "20.0"};
obsolete_1(crypto, des_ede3_cbc_encrypt, 5) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, des_cfb_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, des3_cfb_encrypt, 5) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_ecb_encrypt, 2) ->
- {deprecated, {crypto, block_encrypt, 3}};
+ {removed, {crypto, block_encrypt, 3}, "20.0"};
obsolete_1(crypto, blowfish_cbc_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_cfb64_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_ofb64_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cfb_128_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cbc_128_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cbc_256_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto,rc2_cbc_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto,rc2_40_cbc_encrypt, 3) ->
- {deprecated, {crypto, block_encrypt, 4}};
+ {removed, {crypto, block_encrypt, 4}, "20.0"};
obsolete_1(crypto, des_cbc_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, des3_cbc_decrypt, 5) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, des_ecb_decrypt, 2) ->
- {deprecated, {crypto, block_decrypt, 3}};
+ {removed, {crypto, block_decrypt, 3}, "20.0"};
obsolete_1(crypto, des_ede3_cbc_decrypt, 5) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, des_cfb_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, des3_cfb_decrypt, 5) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_ecb_decrypt, 2) ->
- {deprecated, {crypto, block_decrypt, 3}};
+ {removed, {crypto, block_decrypt, 3}, "20.0"};
obsolete_1(crypto, blowfish_cbc_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_cfb64_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, blowfish_ofb64_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cfb_128_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cbc_128_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, aes_cbc_256_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto,rc2_cbc_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto,rc2_40_cbc_decrypt, 3) ->
- {deprecated, {crypto, block_decrypt, 4}};
+ {removed, {crypto, block_decrypt, 4}, "20.0"};
obsolete_1(crypto, aes_ctr_stream_decrypt, 2) ->
- {deprecated, {crypto, stream_decrypt, 2}};
+ {removed, {crypto, stream_decrypt, 2}, "20.0"};
obsolete_1(crypto, aes_ctr_stream_encrypt, 2) ->
- {deprecated, {crypto, stream_encrypt, 2}};
+ {removed, {crypto, stream_encrypt, 2}, "20.0"};
obsolete_1(crypto, aes_ctr_decrypt, 3) ->
- {deprecated, {crypto, stream_decrypt, 2}};
+ {removed, {crypto, stream_decrypt, 2}, "20.0"};
obsolete_1(crypto, aes_ctr_encrypt, 3) ->
- {deprecated, {crypto, stream_encrypt, 2}};
+ {removed, {crypto, stream_encrypt, 2}, "20.0"};
obsolete_1(crypto, rc4_encrypt, 2) ->
- {deprecated, {crypto, stream_encrypt, 2}};
+ {removed, {crypto, stream_encrypt, 2}, "20.0"};
obsolete_1(crypto, rc4_encrypt_with_state, 2) ->
- {deprecated, {crypto, stream_encrypt, 2}};
+ {removed, {crypto, stream_encrypt, 2}, "20.0"};
obsolete_1(crypto, aes_ctr_stream_init, 2) ->
- {deprecated, {crypto, stream_init, 3}};
+ {removed, {crypto, stream_init, 3}, "20.0"};
obsolete_1(crypto, rc4_set_key, 1) ->
- {deprecated, {crypto, stream_init, 2}};
+ {removed, {crypto, stream_init, 2}, "20.0"};
obsolete_1(crypto, rsa_private_decrypt, 3) ->
- {deprecated, {crypto, private_decrypt, 4}};
+ {removed, {crypto, private_decrypt, 4}, "20.0"};
obsolete_1(crypto, rsa_public_decrypt, 3) ->
- {deprecated, {crypto, public_decrypt, 4}};
+ {removed, {crypto, public_decrypt, 4}, "20.0"};
obsolete_1(crypto, rsa_private_encrypt, 3) ->
- {deprecated, {crypto, private_encrypt, 4}};
+ {removed, {crypto, private_encrypt, 4}, "20.0"};
obsolete_1(crypto, rsa_public_encrypt, 3) ->
- {deprecated, {crypto, public_encrypt, 4}};
+ {removed, {crypto, public_encrypt, 4}, "20.0"};
obsolete_1(crypto, des_cfb_ivec, 2) ->
- {deprecated, {crypto, next_iv, 3}};
+ {removed, {crypto, next_iv, 3}, "20.0"};
obsolete_1(crypto,des_cbc_ivec, 1) ->
- {deprecated, {crypto, next_iv, 2}};
+ {removed, {crypto, next_iv, 2}, "20.0"};
obsolete_1(crypto, aes_cbc_ivec, 1) ->
- {deprecated, {crypto, next_iv, 2}};
+ {removed, {crypto, next_iv, 2}, "20.0"};
obsolete_1(crypto,info, 0) ->
- {deprecated, {crypto, module_info, 0}};
+ {removed, {crypto, module_info, 0}, "20.0"};
obsolete_1(crypto, strong_rand_mpint, 3) ->
- {deprecated, "needed only by deprecated functions"};
+ {removed, "removed in 20.0; only needed by removed functions"};
obsolete_1(crypto, erlint, 1) ->
- {deprecated, "needed only by deprecated functions"};
+ {removed, "removed in 20.0; only needed by removed functions"};
obsolete_1(crypto, mpint, 1) ->
- {deprecated, "needed only by deprecated functions"};
+ {removed, "removed in 20.0; only needed by removed functions"};
%% *** SNMP ***
@@ -390,13 +441,13 @@ obsolete_1(erlang, concat_binary, 1) ->
%% Added in R14A.
obsolete_1(ssl, peercert, 2) ->
- {deprecated,"deprecated (will be removed in R15A); use ssl:peercert/1 and public_key:pkix_decode_cert/2 instead"};
+ {removed ,"removed in R15A; use ssl:peercert/1 and public_key:pkix_decode_cert/2 instead"};
%% Added in R14B.
obsolete_1(public_key, pem_to_der, 1) ->
- {deprecated,"deprecated (will be removed in R15A); use file:read_file/1 and public_key:pem_decode/1"};
+ {removed,"removed in R15A; use file:read_file/1 and public_key:pem_decode/1"};
obsolete_1(public_key, decode_private_key, A) when A =:= 1; A =:= 2 ->
- {deprecated,{public_key,pem_entry_decode,1},"R15A"};
+ {removed, "removed in R15A; use public_key:pem_entry_decode/1"};
%% Added in R14B03.
obsolete_1(docb_gen, _, _) ->
@@ -408,7 +459,7 @@ obsolete_1(docb_xml_check, _, _) ->
%% Added in R15B
obsolete_1(asn1rt, F, _) when F == load_driver; F == unload_driver ->
- {deprecated,"deprecated (will be removed in OTP 18); has no effect as drivers are no longer used"};
+ {removed,"removed (will be removed in OTP 18); has no effect as drivers are no longer used"};
obsolete_1(ssl, pid, 1) ->
{removed,"was removed in R16; is no longer needed"};
obsolete_1(inviso, _, _) ->
@@ -416,12 +467,12 @@ obsolete_1(inviso, _, _) ->
%% Added in R15B01.
obsolete_1(gs, _, _) ->
- {deprecated,"the gs application has been deprecated and will be removed in OTP 18; use the wx application instead"};
+ {removed,"the gs application has been removed; use the wx application instead"};
obsolete_1(ssh, sign_data, 2) ->
- {deprecated,"deprecated (will be removed in R16A); use public_key:pem_decode/1, public_key:pem_entry_decode/1 "
+ {removed,"removed in R16A; use public_key:pem_decode/1, public_key:pem_entry_decode/1 "
"and public_key:sign/3 instead"};
obsolete_1(ssh, verify_data, 3) ->
- {deprecated,"deprecated (will be removed in R16A); use public_key:ssh_decode/1, and public_key:verify/4 instead"};
+ {removed,"removed in R16A; use public_key:ssh_decode/1, and public_key:verify/4 instead"};
%% Added in R16
obsolete_1(wxCalendarCtrl, enableYearChange, _) -> %% wx bug documented?
@@ -463,21 +514,23 @@ obsolete_1(wxCursor, new, 4) ->
%% Added in OTP 17.
obsolete_1(asn1ct, decode,3) ->
- {deprecated,"deprecated; use Mod:decode/2 instead"};
+ {removed,"removed; use Mod:decode/2 instead"};
+obsolete_1(asn1ct, encode, 2) ->
+ {removed,"removed; use Mod:encode/2 instead"};
obsolete_1(asn1ct, encode, 3) ->
- {deprecated,"deprecated; use Mod:encode/2 instead"};
+ {removed,"removed; use Mod:encode/2 instead"};
obsolete_1(asn1rt, decode,3) ->
- {deprecated,"deprecated; use Mod:decode/2 instead"};
+ {removed,"removed; use Mod:decode/2 instead"};
obsolete_1(asn1rt, encode, 2) ->
- {deprecated,"deprecated; use Mod:encode/2 instead"};
+ {removed,"removed; use Mod:encode/2 instead"};
obsolete_1(asn1rt, encode, 3) ->
- {deprecated,"deprecated; use Mod:encode/2 instead"};
+ {removed,"removed; use Mod:encode/2 instead"};
obsolete_1(asn1rt, info, 1) ->
- {deprecated,"deprecated; use Mod:info/0 instead"};
+ {removed,"removed; use Mod:info/0 instead"};
obsolete_1(asn1rt, utf8_binary_to_list, 1) ->
- {deprecated,{unicode,characters_to_list,1}};
+ {removed,{unicode,characters_to_list,1},"OTP 20"};
obsolete_1(asn1rt, utf8_list_to_binary, 1) ->
- {deprecated,{unicode,characters_to_binary,1}};
+ {removed,{unicode,characters_to_binary,1},"OTP 20"};
%% Added in OTP 18.
obsolete_1(core_lib, get_anno, 1) ->
@@ -516,10 +569,9 @@ obsolete_1(erl_parse, get_attribute, 2) ->
obsolete_1(erl_lint, modify_line, 2) ->
{removed,{erl_parse,map_anno,2},"19.0"};
obsolete_1(ssl, negotiated_next_protocol, 1) ->
- {deprecated,{ssl,negotiated_protocol,1}};
-
+ {removed,"removed in 20.0; use ssl:negotiated_protocol/1 instead"};
obsolete_1(ssl, connection_info, 1) ->
- {deprecated, "deprecated; use connection_information/[1,2] instead"};
+ {removed, "removed in 20.0; use ssl:connection_information/[1,2] instead"};
obsolete_1(httpd_conf, check_enum, 2) ->
{deprecated, "deprecated; use lists:member/2 instead"};
@@ -549,7 +601,21 @@ obsolete_1(queue, lait, 1) ->
obsolete_1(overload, _, _) ->
{removed, "removed in OTP 19"};
obsolete_1(rpc, safe_multi_server_call, A) when A =:= 2; A =:= 3 ->
- {removed, {rpc, multi_server_call, A}};
+ {removed, {rpc, multi_server_call, A}, "removed in OTP 19"};
+
+%% Added in OTP 20.
+
+obsolete_1(filename, find_src, 1) ->
+ {deprecated, "deprecated; use filelib:find_source/1 instead"};
+obsolete_1(filename, find_src, 2) ->
+ {deprecated, "deprecated; use filelib:find_source/3 instead"};
+
+%% Removed in OTP 20.
+
+obsolete_1(erlang, hash, 2) ->
+ {removed, {erlang, phash2, 2}, "20.0"};
+
+%% not obsolete
obsolete_1(_, _, _) ->
no.
diff --git a/lib/stdlib/src/proc_lib.erl b/lib/stdlib/src/proc_lib.erl
index 3dc1848550..9ce8e7d60e 100644
--- a/lib/stdlib/src/proc_lib.erl
+++ b/lib/stdlib/src/proc_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -232,7 +232,7 @@ init_p(Parent, Ancestors, Fun) when is_function(Fun) ->
Fun()
catch
Class:Reason ->
- exit_p(Class, Reason)
+ exit_p(Class, Reason, erlang:get_stacktrace())
end.
-spec init_p(pid(), [pid()], atom(), atom(), [term()]) -> term().
@@ -247,7 +247,7 @@ init_p_do_apply(M, F, A) ->
apply(M, F, A)
catch
Class:Reason ->
- exit_p(Class, Reason)
+ exit_p(Class, Reason, erlang:get_stacktrace())
end.
-spec wake_up(atom(), atom(), [term()]) -> term().
@@ -257,22 +257,29 @@ wake_up(M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
apply(M, F, A)
catch
Class:Reason ->
- exit_p(Class, Reason)
+ exit_p(Class, Reason, erlang:get_stacktrace())
end.
-exit_p(Class, Reason) ->
+exit_p(Class, Reason, Stacktrace) ->
case get('$initial_call') of
{M,F,A} when is_atom(M), is_atom(F), is_integer(A) ->
MFA = {M,F,make_dummy_args(A, [])},
- crash_report(Class, Reason, MFA),
- exit(Reason);
+ crash_report(Class, Reason, MFA, Stacktrace),
+ erlang:raise(exit, exit_reason(Class, Reason, Stacktrace), Stacktrace);
_ ->
%% The process dictionary has been cleared or
%% possibly modified.
- crash_report(Class, Reason, []),
- exit(Reason)
+ crash_report(Class, Reason, [], Stacktrace),
+ erlang:raise(exit, exit_reason(Class, Reason, Stacktrace), Stacktrace)
end.
+exit_reason(error, Reason, Stacktrace) ->
+ {Reason, Stacktrace};
+exit_reason(exit, Reason, _Stacktrace) ->
+ Reason;
+exit_reason(throw, Reason, Stacktrace) ->
+ {{nocatch, Reason}, Stacktrace}.
+
-spec start(Module, Function, Args) -> Ret when
Module :: module(),
Function :: atom(),
@@ -492,26 +499,28 @@ trans_init(M, F, A) when is_atom(M), is_atom(F) ->
%% Generate a crash report.
%% -----------------------------------------------------
-crash_report(exit, normal, _) -> ok;
-crash_report(exit, shutdown, _) -> ok;
-crash_report(exit, {shutdown,_}, _) -> ok;
-crash_report(Class, Reason, StartF) ->
- OwnReport = my_info(Class, Reason, StartF),
+crash_report(exit, normal, _, _) -> ok;
+crash_report(exit, shutdown, _, _) -> ok;
+crash_report(exit, {shutdown,_}, _, _) -> ok;
+crash_report(Class, Reason, StartF, Stacktrace) ->
+ OwnReport = my_info(Class, Reason, StartF, Stacktrace),
LinkReport = linked_info(self()),
Rep = [OwnReport,LinkReport],
error_logger:error_report(crash_report, Rep).
-my_info(Class, Reason, []) ->
- my_info_1(Class, Reason);
-my_info(Class, Reason, StartF) ->
- [{initial_call, StartF}|my_info_1(Class, Reason)].
+my_info(Class, Reason, [], Stacktrace) ->
+ my_info_1(Class, Reason, Stacktrace);
+my_info(Class, Reason, StartF, Stacktrace) ->
+ [{initial_call, StartF}|
+ my_info_1(Class, Reason, Stacktrace)].
-my_info_1(Class, Reason) ->
+my_info_1(Class, Reason, Stacktrace) ->
[{pid, self()},
get_process_info(self(), registered_name),
- {error_info, {Class,Reason,erlang:get_stacktrace()}},
+ {error_info, {Class,Reason,Stacktrace}},
get_ancestors(self()),
- get_process_info(self(), messages),
+ get_process_info(self(), message_queue_len),
+ get_messages(self()),
get_process_info(self(), links),
get_cleaned_dictionary(self()),
get_process_info(self(), trap_exit),
@@ -531,12 +540,49 @@ get_ancestors(Pid) ->
{ancestors,[]}
end.
+%% The messages and the dictionary are possibly limited too much if
+%% some error handles output the messages or the dictionary using ~P
+%% or ~W with depth greater than the depth used here (the depth of
+%% control characters P and W takes precedence over the depth set by
+%% application variable error_logger_format_depth). However, it is
+%% assumed that all report handlers call proc_lib:format().
+get_messages(Pid) ->
+ Messages = get_process_messages(Pid),
+ {messages, error_logger:limit_term(Messages)}.
+
+get_process_messages(Pid) ->
+ Depth = error_logger:get_format_depth(),
+ case Pid =/= self() orelse Depth =:= unlimited of
+ true ->
+ {messages, Messages} = get_process_info(Pid, messages),
+ Messages;
+ false ->
+ %% If there are more messages than Depth, garbage
+ %% collection can sometimes be avoided by collecting just
+ %% enough messages for the crash report. It is assumed the
+ %% process is about to die anyway.
+ receive_messages(Depth)
+ end.
+
+receive_messages(0) -> [];
+receive_messages(N) ->
+ receive
+ M ->
+ [M|receive_messages(N - 1)]
+ after 0 ->
+ []
+ end.
+
get_cleaned_dictionary(Pid) ->
case get_process_info(Pid,dictionary) of
- {dictionary,Dict} -> {dictionary,clean_dict(Dict)};
+ {dictionary,Dict} -> {dictionary,cleaned_dict(Dict)};
_ -> {dictionary,[]}
end.
+cleaned_dict(Dict) ->
+ CleanDict = clean_dict(Dict),
+ error_logger:limit_term(CleanDict).
+
clean_dict([{'$ancestors',_}|Dict]) ->
clean_dict(Dict);
clean_dict([{'$initial_call',_}|Dict]) ->
@@ -574,20 +620,24 @@ make_neighbour_reports1([P|Ps]) ->
make_neighbour_reports1([]) ->
[].
+%% Do not include messages or process dictionary, even if
+%% error_logger_format_depth is unlimited.
make_neighbour_report(Pid) ->
[{pid, Pid},
get_process_info(Pid, registered_name),
get_initial_call(Pid),
get_process_info(Pid, current_function),
get_ancestors(Pid),
- get_process_info(Pid, messages),
+ get_process_info(Pid, message_queue_len),
+ %% get_messages(Pid),
get_process_info(Pid, links),
- get_cleaned_dictionary(Pid),
+ %% get_cleaned_dictionary(Pid),
get_process_info(Pid, trap_exit),
get_process_info(Pid, status),
get_process_info(Pid, heap_size),
get_process_info(Pid, stack_size),
- get_process_info(Pid, reductions)
+ get_process_info(Pid, reductions),
+ get_process_info(Pid, current_stacktrace)
].
get_initial_call(Pid) ->
@@ -714,24 +764,37 @@ format(CrashReport, Encoding) ->
format([OwnReport,LinkReport], Encoding, Depth) ->
Extra = {Encoding,Depth},
- OwnFormat = format_report(OwnReport, Extra),
- LinkFormat = format_report(LinkReport, Extra),
+ MyIndent = " ",
+ OwnFormat = format_report(OwnReport, MyIndent, Extra),
+ LinkFormat = format_link_report(LinkReport, MyIndent, Extra),
Str = io_lib:format(" crasher:~n~ts neighbours:~n~ts",
[OwnFormat, LinkFormat]),
lists:flatten(Str).
-format_report(Rep, Extra) when is_list(Rep) ->
- format_rep(Rep, Extra);
-format_report(Rep, {Enc,_}) ->
- io_lib:format("~"++modifier(Enc)++"p~n", [Rep]).
-
-format_rep([{initial_call,InitialCall}|Rep], {_Enc,Depth}=Extra) ->
- [format_mfa(InitialCall, Depth)|format_rep(Rep, Extra)];
-format_rep([{error_info,{Class,Reason,StackTrace}}|Rep], Extra) ->
- [format_exception(Class, Reason, StackTrace, Extra)|format_rep(Rep, Extra)];
-format_rep([{Tag,Data}|Rep], Extra) ->
- [format_tag(Tag, Data, Extra)|format_rep(Rep, Extra)];
-format_rep(_, _Extra) ->
+format_link_report([Link|Reps], Indent, Extra) ->
+ Rep = case Link of
+ {neighbour,Rep0} -> Rep0;
+ _ -> Link
+ end,
+ LinkIndent = [" ",Indent],
+ [Indent,"neighbour:\n",format_report(Rep, LinkIndent, Extra)|
+ format_link_report(Reps, Indent, Extra)];
+format_link_report([], _, _) ->
+ [].
+
+format_report(Rep, Indent, Extra) when is_list(Rep) ->
+ format_rep(Rep, Indent, Extra);
+format_report(Rep, Indent, {Enc,Depth}) ->
+ io_lib:format("~s~"++modifier(Enc)++"P~n", [Indent, Rep, Depth]).
+
+format_rep([{initial_call,InitialCall}|Rep], Indent, Extra) ->
+ [format_mfa(Indent, InitialCall, Extra)|format_rep(Rep, Indent, Extra)];
+format_rep([{error_info,{Class,Reason,StackTrace}}|Rep], Indent, Extra) ->
+ [format_exception(Class, Reason, StackTrace, Extra)|
+ format_rep(Rep, Indent, Extra)];
+format_rep([{Tag,Data}|Rep], Indent, Extra) ->
+ [format_tag(Indent, Tag, Data, Extra)|format_rep(Rep, Indent, Extra)];
+format_rep(_, _, _Extra) ->
[].
format_exception(Class, Reason, StackTrace, {Enc,_}=Extra) ->
@@ -742,16 +805,21 @@ format_exception(Class, Reason, StackTrace, {Enc,_}=Extra) ->
[EI, lib:format_exception(1+length(EI), Class, Reason,
StackTrace, StackFun, PF, Enc), "\n"].
-format_mfa({M,F,Args}=StartF, Depth) ->
+format_mfa(Indent, {M,F,Args}=StartF, {Enc,_}=Extra) ->
try
A = length(Args),
- [" initial call: ",atom_to_list(M),$:,atom_to_list(F),$/,
+ [Indent,"initial call: ",atom_to_list(M),$:,to_string(F, Enc),$/,
integer_to_list(A),"\n"]
catch
error:_ ->
- format_tag(initial_call, StartF, Depth)
+ format_tag(Indent, initial_call, StartF, Extra)
end.
+to_string(A, latin1) ->
+ io_lib:write_atom_as_latin1(A);
+to_string(A, _) ->
+ io_lib:write_atom(A).
+
pp_fun({Enc,Depth}) ->
{Letter,Tl} = case Depth of
unlimited -> {"p",[]};
@@ -762,12 +830,12 @@ pp_fun({Enc,Depth}) ->
io_lib:format("~." ++ integer_to_list(I) ++ P, [Term|Tl])
end.
-format_tag(Tag, Data, {_Enc,Depth}) ->
+format_tag(Indent, Tag, Data, {_Enc,Depth}) ->
case Depth of
unlimited ->
- io_lib:format(" ~p: ~80.18p~n", [Tag, Data]);
+ io_lib:format("~s~p: ~80.18p~n", [Indent, Tag, Data]);
_ ->
- io_lib:format(" ~p: ~80.18P~n", [Tag, Data, Depth])
+ io_lib:format("~s~p: ~80.18P~n", [Indent, Tag, Data, Depth])
end.
modifier(latin1) -> "";
diff --git a/lib/stdlib/src/proplists.erl b/lib/stdlib/src/proplists.erl
index 5356467b19..340dfdcac9 100644
--- a/lib/stdlib/src/proplists.erl
+++ b/lib/stdlib/src/proplists.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,14 +10,8 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% =====================================================================
-%% Support functions for property lists
-%%
-%% Copyright (C) 2000-2003 Richard Carlsson
-%% ---------------------------------------------------------------------
-%%
+%% @copyright 2000-2003 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Support functions for property lists.
%%
%% <p>Property lists are ordinary lists containing entries in the form
@@ -94,7 +83,7 @@ property(Key, Value) ->
%% ---------------------------------------------------------------------
-%% @doc Unfolds all occurences of atoms in <code>ListIn</code> to tuples
+%% @doc Unfolds all occurrences of atoms in <code>ListIn</code> to tuples
%% <code>{Atom, true}</code>.
%%
%% @see compact/1
diff --git a/lib/stdlib/src/qlc.erl b/lib/stdlib/src/qlc.erl
index f3665824f2..535ca57a6b 100644
--- a/lib/stdlib/src/qlc.erl
+++ b/lib/stdlib/src/qlc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -635,14 +635,25 @@ string_to_handle(Str, Options, Bindings) when is_list(Str) ->
badarg ->
erlang:error(badarg, [Str, Options, Bindings]);
[Unique, Cache, MaxLookup, Join, Lookup] ->
- case erl_scan:string(Str) of
+ case erl_scan:string(Str, 1, [text]) of
{ok, Tokens, _} ->
- case erl_parse:parse_exprs(Tokens) of
- {ok, [Expr]} ->
- case qlc_pt:transform_expression(Expr, Bindings) of
+ ScanRes =
+ case lib:extended_parse_exprs(Tokens) of
+ {ok, [Expr0], SBs} ->
+ {ok, Expr0, SBs};
+ {ok, _ExprList, _SBs} ->
+ erlang:error(badarg,
+ [Str, Options, Bindings]);
+ E ->
+ E
+ end,
+ case ScanRes of
+ {ok, Expr, XBs} ->
+ Bs1 = merge_binding_structs(Bindings, XBs),
+ case qlc_pt:transform_expression(Expr, Bs1) of
{ok, {call, _, _QlcQ, Handle}} ->
{value, QLC_lc, _} =
- erl_eval:exprs(Handle, Bindings),
+ erl_eval:exprs(Handle, Bs1),
O = #qlc_opt{unique = Unique,
cache = Cache,
max_lookup = MaxLookup,
@@ -652,8 +663,6 @@ string_to_handle(Str, Options, Bindings) when is_list(Str) ->
{not_ok, [{error, Error} | _]} ->
error(Error)
end;
- {ok, _ExprList} ->
- erlang:error(badarg, [Str, Options, Bindings]);
{error, ErrorInfo} ->
error(ErrorInfo)
end;
@@ -770,6 +779,10 @@ all_selections([{I,Cs} | ICs]) ->
%%% Local functions
%%%
+merge_binding_structs(Bs1, Bs2) ->
+ lists:foldl(fun({N, V}, Bs) -> erl_eval:add_binding(N, V, Bs)
+ end, Bs1, erl_eval:bindings(Bs2)).
+
aux_name1(Name, N, AllNames) ->
SN = name_suffix(Name, N),
case sets:is_element(SN, AllNames) of
@@ -1180,9 +1193,12 @@ abstract1({table, {M, F, As0}}, _NElements, _Depth, Anno)
abstract1({table, TableDesc}, _NElements, _Depth, _A) ->
case io_lib:deep_char_list(TableDesc) of
true ->
- {ok, Tokens, _} = erl_scan:string(lists:flatten(TableDesc++".")),
- {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
- Expr;
+ {ok, Tokens, _} =
+ erl_scan:string(lists:flatten(TableDesc++"."), 1, [text]),
+ {ok, Es, Bs} =
+ lib:extended_parse_exprs(Tokens),
+ [Expr] = lib:subst_values_for_vars(Es, Bs),
+ special(Expr);
false -> % abstract expression
TableDesc
end;
@@ -1210,6 +1226,15 @@ abstract1({list, L}, NElements, Depth, _A) when NElements =:= infinity;
abstract1({list, L}, NElements, Depth, _A) ->
abstract_term(depth(lists:sublist(L, NElements), Depth) ++ '...', 1).
+special({value, _, Thing}) ->
+ abstract_term(Thing);
+special(Tuple) when is_tuple(Tuple) ->
+ list_to_tuple(special(tuple_to_list(Tuple)));
+special([E|Es]) ->
+ [special(E)|special(Es)];
+special(Expr) ->
+ Expr.
+
depth(List, infinity) ->
List;
depth(List, Depth) ->
@@ -1292,6 +1317,10 @@ abstr_term(Fun, Line) when is_function(Fun) ->
end;
abstr_term(PPR, Line) when is_pid(PPR); is_port(PPR); is_reference(PPR) ->
{special, Line, lists:flatten(io_lib:write(PPR))};
+abstr_term(Map, Line) when is_map(Map) ->
+ {map,Line,
+ [{map_field_assoc,Line,abstr_term(K, Line),abstr_term(V, Line)} ||
+ {K,V} <- maps:to_list(Map)]};
abstr_term(Simple, Line) ->
erl_parse:abstract(Simple, erl_anno:line(Line)).
@@ -1363,8 +1392,10 @@ next_loop(Pid, L, N) when N =/= 0 ->
{caught, throw, Error, [?THROWN_ERROR | _]} ->
Error;
{caught, Class, Reason, Stacktrace} ->
- _ = (catch erlang:error(foo)),
- erlang:raise(Class, Reason, Stacktrace ++ erlang:get_stacktrace());
+ CurrentStacktrace = try erlang:error(foo)
+ catch error:_ -> erlang:get_stacktrace()
+ end,
+ erlang:raise(Class, Reason, Stacktrace ++ CurrentStacktrace);
error ->
erlang:error({qlc_cursor_pid_no_longer_exists, Pid})
end;
diff --git a/lib/stdlib/src/qlc_pt.erl b/lib/stdlib/src/qlc_pt.erl
index 0db63b81f4..4a39f8ae9d 100644
--- a/lib/stdlib/src/qlc_pt.erl
+++ b/lib/stdlib/src/qlc_pt.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@
}).
-record(state, {imp,
+ overridden,
maxargs,
records,
xwarnings = [],
@@ -184,7 +185,9 @@ initiate(Forms0, Imported) ->
exclude_integers_from_unique_line_numbers(Forms0, NodeInfo),
?DEBUG("node info0 ~p~n",
[lists:sort(ets:tab2list(NodeInfo))]),
+ IsOverridden = set_up_overridden(Forms0),
State0 = #state{imp = Imported,
+ overridden = IsOverridden,
maxargs = ?EVAL_MAX_NUM_OF_ARGS,
records = record_attributes(Forms0),
node_info = NodeInfo},
@@ -436,7 +439,7 @@ compile_forms(Forms0, Options) ->
(_) -> false
end,
Forms = ([F || F <- Forms0, not Exclude(element(1, F))]
- ++ [{eof,anno0()}]),
+ ++ [{eof,0}]),
try
case compile:noenv_forms(Forms, compile_options(Options)) of
{ok, _ModName, Ws0} ->
@@ -1519,36 +1522,35 @@ filter_info(FilterData, AllIVs, Dependencies, State) ->
%% to be placed after further generators (the docs states otherwise, but
%% this seems to be common practice).
filter_list(FilterData, Dependencies, State) ->
- RDs = State#state.records,
- sel_gf(FilterData, 1, Dependencies, RDs, [], []).
+ sel_gf(FilterData, 1, Dependencies, State, [], []).
sel_gf([], _N, _Deps, _RDs, _Gens, _Gens1) ->
[];
-sel_gf([{#qid{no = N}=Id,{fil,F}}=Fil | FData], N, Deps, RDs, Gens, Gens1) ->
- case erl_lint:is_guard_test(F, RDs) of
+sel_gf([{#qid{no = N}=Id,{fil,F}}=Fil | FData], N, Deps, State, Gens, Gens1) ->
+ case is_guard_test(F, State) of
true ->
{Id,GIds} = lists:keyfind(Id, 1, Deps),
case length(GIds) =< 1 of
true ->
case generators_in_scope(GIds, Gens1) of
true ->
- [Fil|sel_gf(FData, N+1, Deps, RDs, Gens, Gens1)];
+ [Fil|sel_gf(FData, N+1, Deps, State, Gens, Gens1)];
false ->
- sel_gf(FData, N + 1, Deps, RDs, [], [])
+ sel_gf(FData, N + 1, Deps, State, [], [])
end;
false ->
case generators_in_scope(GIds, Gens) of
true ->
- [Fil | sel_gf(FData, N + 1, Deps, RDs, Gens, [])];
+ [Fil | sel_gf(FData, N + 1, Deps, State, Gens, [])];
false ->
- sel_gf(FData, N + 1, Deps, RDs, [], [])
+ sel_gf(FData, N + 1, Deps, State, [], [])
end
end;
false ->
- sel_gf(FData, N + 1, Deps, RDs, [], [])
+ sel_gf(FData, N + 1, Deps, State, [], [])
end;
-sel_gf(FData, N, Deps, RDs, Gens, Gens1) ->
- sel_gf(FData, N + 1, Deps, RDs, [N | Gens], [N | Gens1]).
+sel_gf(FData, N, Deps, State, Gens, Gens1) ->
+ sel_gf(FData, N + 1, Deps, State, [N | Gens], [N | Gens1]).
generators_in_scope(GenIds, GenNumbers) ->
lists:all(fun(#qid{no=N}) -> lists:member(N, GenNumbers) end, GenIds).
@@ -1870,7 +1872,8 @@ prep_expr(E, F, S, BF, Imported) ->
unify_column(Frame, Var, Col, BindFun, Imported) ->
A = anno0(),
- Call = {call,A,{atom,A,element},[{integer,A,Col}, {var,A,Var}]},
+ Call = {call,A,{remote,A,{atom,A,erlang},{atom,A,element}},
+ [{integer,A,Col}, {var,A,Var}]},
element_calls(Call, Frame, BindFun, Imported).
%% cons_tuple is used for representing {V1, ..., Vi | TupleTail}.
@@ -1880,6 +1883,8 @@ unify_column(Frame, Var, Col, BindFun, Imported) ->
%% about the size of the tuple is known.
element_calls({call,_,{remote,_,{atom,_,erlang},{atom,_,element}},
[{integer,_,I},Term0]}, F0, BF, Imported) when I > 0 ->
+ %% Note: erl_expand_records ensures that all calls to element/2
+ %% have an explicit "erlang:" prefix.
TupleTail = unique_var(),
VarsL = [unique_var() || _ <- lists:seq(1, I)],
Vars = VarsL ++ TupleTail,
@@ -1887,10 +1892,6 @@ element_calls({call,_,{remote,_,{atom,_,erlang},{atom,_,element}},
VarI = lists:nth(I, VarsL),
{Term, F} = element_calls(Term0, F0, BF, Imported),
{VarI, unify('=:=', Tuple, Term, F, BF, Imported)};
-element_calls({call,L1,{atom,_,element}=E,As}, F0, BF, Imported) ->
- %% erl_expand_records should add "erlang:"...
- element_calls({call,L1,{remote,L1,{atom,L1,erlang},E}, As}, F0, BF,
- Imported);
element_calls(T, F0, BF, Imported) when is_tuple(T) ->
{L, F} = element_calls(tuple_to_list(T), F0, BF, Imported),
{list_to_tuple(L), F};
@@ -2484,7 +2485,7 @@ filter(E, L, QIVs, S, RL, Fun, Go, GoI, IVs, State) ->
%% This is the "guard semantics" used in ordinary list
%% comprehension: if a filter looks like a guard test, it returns
%% 'false' rather than fails.
- Body = case erl_lint:is_guard_test(E, State#state.records) of
+ Body = case is_guard_test(E, State) of
true ->
CT = {clause,L,[],[[E]],[{call,L,?V(Fun),NAsT}]},
CF = {clause,L,[],[[?A(true)]],[{call,L,?V(Fun),NAsF}]},
@@ -2888,6 +2889,26 @@ family_list(L) ->
family(L) ->
sofs:relation_to_family(sofs:relation(L)).
+is_guard_test(E, #state{records = RDs, overridden = IsOverridden}) ->
+ erl_lint:is_guard_test(E, RDs, IsOverridden).
+
+%% In code that has been run through erl_expand_records, a guard
+%% test will never contain calls without an explicit module
+%% prefix. Unfortunately, this module runs *some* of the code
+%% through erl_expand_records, but not all of it.
+%%
+%% Therefore, we must set up our own list of local and imported functions
+%% that will override a BIF with the same name.
+
+set_up_overridden(Forms) ->
+ Locals = [{Name,Arity} || {function,_,Name,Arity,_} <- Forms],
+ Imports0 = [Fs || {attribute,_,import,Fs} <- Forms],
+ Imports1 = lists:flatten(Imports0),
+ Imports2 = [Fs || {_,Fs} <- Imports1],
+ Imports = lists:flatten(Imports2),
+ Overridden = gb_sets:from_list(Imports ++ Locals),
+ fun(FA) -> gb_sets:is_element(FA, Overridden) end.
+
-ifdef(debug).
display_forms(Forms) ->
io:format("Forms ***~n"),
diff --git a/lib/stdlib/src/rand.erl b/lib/stdlib/src/rand.erl
index 93409d95df..7a8a5e6d4a 100644
--- a/lib/stdlib/src/rand.erl
+++ b/lib/stdlib/src/rand.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,7 +19,10 @@
%%
%% =====================================================================
%% Multiple PRNG module for Erlang/OTP
-%% Copyright (c) 2015 Kenji Rikitake
+%% Copyright (c) 2015-2016 Kenji Rikitake
+%%
+%% exrop (xoroshiro116+) added and statistical distribution
+%% improvements by the Erlang/OTP team 2017
%% =====================================================================
-module(rand).
@@ -27,34 +30,180 @@
-export([seed_s/1, seed_s/2, seed/1, seed/2,
export_seed/0, export_seed_s/1,
uniform/0, uniform/1, uniform_s/1, uniform_s/2,
- normal/0, normal_s/1
+ jump/0, jump/1,
+ normal/0, normal/2, normal_s/1, normal_s/3
]).
-compile({inline, [exs64_next/1, exsplus_next/1,
exs1024_next/1, exs1024_calc/2,
+ exrop_next/1, exrop_next_s/2,
get_52/1, normal_kiwi/1]}).
--define(DEFAULT_ALG_HANDLER, exsplus).
+-define(DEFAULT_ALG_HANDLER, exrop).
-define(SEED_DICT, rand_seed).
%% =====================================================================
+%% Bit fiddling macros
+%% =====================================================================
+
+-define(BIT(Bits), (1 bsl (Bits))).
+-define(MASK(Bits), (?BIT(Bits) - 1)).
+-define(MASK(Bits, X), ((X) band ?MASK(Bits))).
+-define(
+ BSL(Bits, X, N),
+ %% N is evaluated 2 times
+ (?MASK((Bits)-(N), (X)) bsl (N))).
+-define(
+ ROTL(Bits, X, N),
+ %% Bits is evaluated 2 times
+ %% X is evaluated 2 times
+ %% N i evaluated 3 times
+ (?BSL((Bits), (X), (N)) bor ((X) bsr ((Bits)-(N))))).
+
+%%-define(TWO_POW_MINUS53, (math:pow(2, -53))).
+-define(TWO_POW_MINUS53, 1.11022302462515657e-16).
+
+%% =====================================================================
%% Types
%% =====================================================================
+-type uint64() :: 0..?MASK(64).
+-type uint58() :: 0..?MASK(58).
+
%% This depends on the algorithm handler function
--type alg_seed() :: exs64_state() | exsplus_state() | exs1024_state().
-%% This is the algorithm handler function within this module
--type alg_handler() :: #{type := alg(),
- max := integer(),
- next := fun(),
- uniform := fun(),
- uniform_n := fun()}.
-
-%% Internal state
--opaque state() :: {alg_handler(), alg_seed()}.
--type alg() :: exs64 | exsplus | exs1024.
--opaque export_state() :: {alg(), alg_seed()}.
--export_type([alg/0, state/0, export_state/0]).
+-type alg_state() ::
+ exs64_state() | exsplus_state() | exs1024_state() |
+ exrop_state() | term().
+
+%% This is the algorithm handling definition within this module,
+%% and the type to use for plugins.
+%%
+%% The 'type' field must be recognized by the module that implements
+%% the algorithm, to interpret an exported state.
+%%
+%% The 'bits' field indicates how many bits the integer
+%% returned from 'next' has got, i.e 'next' shall return
+%% an random integer in the range 0..(2^Bits - 1).
+%% At least 53 bits is required for the floating point
+%% producing fallbacks. This field is only used when
+%% the 'uniform' or 'uniform_n' fields are not defined.
+%%
+%% The fields 'next', 'uniform' and 'uniform_n'
+%% implement the algorithm. If 'uniform' or 'uinform_n'
+%% is not present there is a fallback using 'next' and either
+%% 'bits' or the deprecated 'max'.
+%%
+-type alg_handler() ::
+ #{type := alg(),
+ bits => non_neg_integer(),
+ weak_low_bits => non_neg_integer(),
+ max => non_neg_integer(), % Deprecated
+ next :=
+ fun ((alg_state()) -> {non_neg_integer(), alg_state()}),
+ uniform =>
+ fun ((state()) -> {float(), state()}),
+ uniform_n =>
+ fun ((pos_integer(), state()) -> {pos_integer(), state()}),
+ jump =>
+ fun ((state()) -> state())}.
+
+%% Algorithm state
+-type state() :: {alg_handler(), alg_state()}.
+-type builtin_alg() :: exs64 | exsplus | exsp | exs1024 | exs1024s | exrop.
+-type alg() :: builtin_alg() | atom().
+-type export_state() :: {alg(), alg_state()}.
+-export_type(
+ [builtin_alg/0, alg/0, alg_handler/0, alg_state/0,
+ state/0, export_state/0]).
+-export_type(
+ [exs64_state/0, exsplus_state/0, exs1024_state/0, exrop_state/0]).
+
+%% =====================================================================
+%% Range macro and helper
+%% =====================================================================
+
+-define(
+ uniform_range(Range, Alg, R, V, MaxMinusRange, I),
+ if
+ 0 =< (MaxMinusRange) ->
+ if
+ %% Really work saving in odd cases;
+ %% large ranges in particular
+ (V) < (Range) ->
+ {(V) + 1, {(Alg), (R)}};
+ true ->
+ (I) = (V) rem (Range),
+ if
+ (V) - (I) =< (MaxMinusRange) ->
+ {(I) + 1, {(Alg), (R)}};
+ true ->
+ %% V in the truncated top range
+ %% - try again
+ ?FUNCTION_NAME((Range), {(Alg), (R)})
+ end
+ end;
+ true ->
+ uniform_range((Range), (Alg), (R), (V))
+ end).
+
+%% For ranges larger than the algorithm bit size
+uniform_range(Range, #{next:=Next, bits:=Bits} = Alg, R, V) ->
+ WeakLowBits =
+ case Alg of
+ #{weak_low_bits:=WLB} -> WLB;
+ #{} -> 0
+ end,
+ %% Maybe waste the lowest bit(s) when shifting in new bits
+ Shift = Bits - WeakLowBits,
+ ShiftMask = bnot ?MASK(WeakLowBits),
+ RangeMinus1 = Range - 1,
+ if
+ (Range band RangeMinus1) =:= 0 -> % Power of 2
+ %% Generate at least the number of bits for the range
+ {V1, R1, _} =
+ uniform_range(
+ Range bsr Bits, Next, R, V, ShiftMask, Shift, Bits),
+ {(V1 band RangeMinus1) + 1, {Alg, R1}};
+ true ->
+ %% Generate a value with at least two bits more than the range
+ %% and try that for a fit, otherwise recurse
+ %%
+ %% Just one bit more should ensure that the generated
+ %% number range is at least twice the size of the requested
+ %% range, which would make the probability to draw a good
+ %% number better than 0.5. And repeating that until
+ %% success i guess would take 2 times statistically amortized.
+ %% But since the probability for fairly many attemtpts
+ %% is not that low, use two bits more than the range which
+ %% should make the probability to draw a bad number under 0.25,
+ %% which decreases the bad case probability a lot.
+ {V1, R1, B} =
+ uniform_range(
+ Range bsr (Bits - 2), Next, R, V, ShiftMask, Shift, Bits),
+ I = V1 rem Range,
+ if
+ (V1 - I) =< (1 bsl B) - Range ->
+ {I + 1, {Alg, R1}};
+ true ->
+ %% V1 drawn from the truncated top range
+ %% - try again
+ {V2, R2} = Next(R1),
+ uniform_range(Range, Alg, R2, V2)
+ end
+ end.
+%%
+uniform_range(Range, Next, R, V, ShiftMask, Shift, B) ->
+ if
+ Range =< 1 ->
+ {V, R, B};
+ true ->
+ {V1, R1} = Next(R),
+ %% Waste the lowest bit(s) when shifting in new bits
+ uniform_range(
+ Range bsr Shift, Next, R1,
+ ((V band ShiftMask) bsl Shift) bor V1,
+ ShiftMask, Shift, B + Shift)
+ end.
%% =====================================================================
%% API
@@ -68,7 +217,7 @@ export_seed() ->
_ -> undefined
end.
--spec export_seed_s(state()) -> export_state().
+-spec export_seed_s(State :: state()) -> export_state().
export_seed_s({#{type:=Alg}, Seed}) -> {Alg, Seed}.
%% seed(Alg) seeds RNG with runtime dependent values
@@ -77,31 +226,37 @@ export_seed_s({#{type:=Alg}, Seed}) -> {Alg, Seed}.
%% seed({Alg,Seed}) setup RNG with a previously exported seed
%% and return the NEW state
--spec seed(AlgOrExpState::alg() | export_state()) -> state().
+-spec seed(
+ AlgOrStateOrExpState :: builtin_alg() | state() | export_state()) ->
+ state().
seed(Alg) ->
- R = seed_s(Alg),
- _ = seed_put(R),
- R.
+ seed_put(seed_s(Alg)).
--spec seed_s(AlgOrExpState::alg() | export_state()) -> state().
-seed_s(Alg) when is_atom(Alg) ->
- seed_s(Alg, {erlang:phash2([{node(),self()}]),
- erlang:system_time(),
- erlang:unique_integer()});
+-spec seed_s(
+ AlgOrStateOrExpState :: builtin_alg() | state() | export_state()) ->
+ state().
+seed_s({AlgHandler, _Seed} = State) when is_map(AlgHandler) ->
+ State;
seed_s({Alg0, Seed}) ->
{Alg,_SeedFun} = mk_alg(Alg0),
- {Alg, Seed}.
+ {Alg, Seed};
+seed_s(Alg) ->
+ seed_s(Alg, {erlang:phash2([{node(),self()}]),
+ erlang:system_time(),
+ erlang:unique_integer()}).
%% seed/2: seeds RNG with the algorithm and given values
%% and returns the NEW state.
--spec seed(Alg :: alg(), {integer(), integer(), integer()}) -> state().
+-spec seed(
+ Alg :: builtin_alg(), Seed :: {integer(), integer(), integer()}) ->
+ state().
seed(Alg0, S0) ->
- State = seed_s(Alg0, S0),
- _ = seed_put(State),
- State.
+ seed_put(seed_s(Alg0, S0)).
--spec seed_s(Alg :: alg(), {integer(), integer(), integer()}) -> state().
+-spec seed_s(
+ Alg :: builtin_alg(), Seed :: {integer(), integer(), integer()}) ->
+ state().
seed_s(Alg0, S0 = {_, _, _}) ->
{Alg, Seed} = mk_alg(Alg0),
AS = Seed(S0),
@@ -110,10 +265,10 @@ seed_s(Alg0, S0 = {_, _, _}) ->
%%% uniform/0, uniform/1, uniform_s/1, uniform_s/2 are all
%%% uniformly distributed random numbers.
-%% uniform/0: returns a random float X where 0.0 < X < 1.0,
+%% uniform/0: returns a random float X where 0.0 =< X < 1.0,
%% updating the state in the process dictionary.
--spec uniform() -> X::float().
+-spec uniform() -> X :: float().
uniform() ->
{X, Seed} = uniform_s(seed_get()),
_ = seed_put(Seed),
@@ -123,32 +278,76 @@ uniform() ->
%% uniform/1 returns a random integer X where 1 =< X =< N,
%% updating the state in the process dictionary.
--spec uniform(N :: pos_integer()) -> X::pos_integer().
+-spec uniform(N :: pos_integer()) -> X :: pos_integer().
uniform(N) ->
{X, Seed} = uniform_s(N, seed_get()),
_ = seed_put(Seed),
X.
%% uniform_s/1: given a state, uniform_s/1
-%% returns a random float X where 0.0 < X < 1.0,
+%% returns a random float X where 0.0 =< X < 1.0,
%% and a new state.
--spec uniform_s(state()) -> {X::float(), NewS :: state()}.
+-spec uniform_s(State :: state()) -> {X :: float(), NewState :: state()}.
uniform_s(State = {#{uniform:=Uniform}, _}) ->
- Uniform(State).
+ Uniform(State);
+uniform_s({#{bits:=Bits, next:=Next} = Alg, R0}) ->
+ {V, R1} = Next(R0),
+ %% Produce floats on the form N * 2^(-53)
+ {(V bsr (Bits - 53)) * ?TWO_POW_MINUS53, {Alg, R1}};
+uniform_s({#{max:=Max, next:=Next} = Alg, R0}) ->
+ {V, R1} = Next(R0),
+ %% Old broken algorithm with non-uniform density
+ {V / (Max + 1), {Alg, R1}}.
+
%% uniform_s/2: given an integer N >= 1 and a state, uniform_s/2
%% uniform_s/2 returns a random integer X where 1 =< X =< N,
%% and a new state.
--spec uniform_s(N::pos_integer(), state()) -> {X::pos_integer(), NewS::state()}.
-uniform_s(N, State = {#{uniform_n:=Uniform, max:=Max}, _})
- when 0 < N, N =< Max ->
- Uniform(N, State);
-uniform_s(N, State0 = {#{uniform:=Uniform}, _})
- when is_integer(N), 0 < N ->
- {F, State} = Uniform(State0),
- {trunc(F * N) + 1, State}.
+-spec uniform_s(N :: pos_integer(), State :: state()) ->
+ {X :: pos_integer(), NewState :: state()}.
+uniform_s(N, State = {#{uniform_n:=UniformN}, _})
+ when is_integer(N), 1 =< N ->
+ UniformN(N, State);
+uniform_s(N, {#{bits:=Bits, next:=Next} = Alg, R0})
+ when is_integer(N), 1 =< N ->
+ {V, R1} = Next(R0),
+ MaxMinusN = ?BIT(Bits) - N,
+ ?uniform_range(N, Alg, R1, V, MaxMinusN, I);
+uniform_s(N, {#{max:=Max, next:=Next} = Alg, R0})
+ when is_integer(N), 1 =< N ->
+ %% Old broken algorithm with skewed probability
+ %% and gap in ranges > Max
+ {V, R1} = Next(R0),
+ if
+ N =< Max ->
+ {(V rem N) + 1, {Alg, R1}};
+ true ->
+ F = V / (Max + 1),
+ {trunc(F * N) + 1, {Alg, R1}}
+ end.
+
+%% jump/1: given a state, jump/1
+%% returns a new state which is equivalent to that
+%% after a large number of call defined for each algorithm.
+%% The large number is algorithm dependent.
+
+-spec jump(state()) -> NewState :: state().
+jump(State = {#{jump:=Jump}, _}) ->
+ Jump(State);
+jump({#{}, _}) ->
+ erlang:error(not_implemented).
+
+
+%% jump/0: read the internal state and
+%% apply the jump function for the state as in jump/1
+%% and write back the new value to the internal state,
+%% then returns the new value.
+
+-spec jump() -> NewState :: state().
+jump() ->
+ seed_put(jump(seed_get())).
%% normal/0: returns a random float with standard normal distribution
%% updating the state in the process dictionary.
@@ -159,14 +358,21 @@ normal() ->
_ = seed_put(Seed),
X.
+%% normal/2: returns a random float with N(μ, σ²) normal distribution
+%% updating the state in the process dictionary.
+
+-spec normal(Mean :: number(), Variance :: number()) -> float().
+normal(Mean, Variance) ->
+ Mean + (math:sqrt(Variance) * normal()).
+
%% normal_s/1: returns a random float with standard normal distribution
%% The Ziggurat Method for generating random variables - Marsaglia and Tsang
%% Paper and reference code: http://www.jstatsoft.org/v05/i08/
--spec normal_s(state()) -> {float(), NewS :: state()}.
+-spec normal_s(State :: state()) -> {float(), NewState :: state()}.
normal_s(State0) ->
{Sign, R, State} = get_52(State0),
- Idx = R band 16#FF,
+ Idx = ?MASK(8, R),
Idx1 = Idx+1,
{Ki, Wi} = normal_kiwi(Idx1),
X = R * Wi,
@@ -179,22 +385,20 @@ normal_s(State0) ->
false -> normal_s(Idx, Sign, -X, State)
end.
-%% =====================================================================
-%% Internal functions
+%% normal_s/3: returns a random float with normal N(μ, σ²) distribution
--define(UINT21MASK, 16#00000000001fffff).
--define(UINT32MASK, 16#00000000ffffffff).
--define(UINT33MASK, 16#00000001ffffffff).
--define(UINT39MASK, 16#0000007fffffffff).
--define(UINT58MASK, 16#03ffffffffffffff).
--define(UINT64MASK, 16#ffffffffffffffff).
+-spec normal_s(Mean :: number(), Variance :: number(), state()) -> {float(), NewS :: state()}.
+normal_s(Mean, Variance, State0) when Variance > 0 ->
+ {X, State} = normal_s(State0),
+ {Mean + (math:sqrt(Variance) * X), State}.
--type uint64() :: 0..16#ffffffffffffffff.
--type uint58() :: 0..16#03ffffffffffffff.
+%% =====================================================================
+%% Internal functions
--spec seed_put(state()) -> undefined | state().
+-spec seed_put(state()) -> state().
seed_put(Seed) ->
- put(?SEED_DICT, Seed).
+ put(?SEED_DICT, Seed),
+ Seed.
seed_get() ->
case get(?SEED_DICT) of
@@ -204,17 +408,30 @@ seed_get() ->
%% Setup alg record
mk_alg(exs64) ->
- {#{type=>exs64, max=>?UINT64MASK, next=>fun exs64_next/1,
- uniform=>fun exs64_uniform/1, uniform_n=>fun exs64_uniform/2},
+ {#{type=>exs64, max=>?MASK(64), next=>fun exs64_next/1},
fun exs64_seed/1};
mk_alg(exsplus) ->
- {#{type=>exsplus, max=>?UINT58MASK, next=>fun exsplus_next/1,
- uniform=>fun exsplus_uniform/1, uniform_n=>fun exsplus_uniform/2},
+ {#{type=>exsplus, max=>?MASK(58), next=>fun exsplus_next/1,
+ jump=>fun exsplus_jump/1},
+ fun exsplus_seed/1};
+mk_alg(exsp) ->
+ {#{type=>exsp, bits=>58, weak_low_bits=>1, next=>fun exsplus_next/1,
+ uniform=>fun exsp_uniform/1, uniform_n=>fun exsp_uniform/2,
+ jump=>fun exsplus_jump/1},
fun exsplus_seed/1};
mk_alg(exs1024) ->
- {#{type=>exs1024, max=>?UINT64MASK, next=>fun exs1024_next/1,
- uniform=>fun exs1024_uniform/1, uniform_n=>fun exs1024_uniform/2},
- fun exs1024_seed/1}.
+ {#{type=>exs1024, max=>?MASK(64), next=>fun exs1024_next/1,
+ jump=>fun exs1024_jump/1},
+ fun exs1024_seed/1};
+mk_alg(exs1024s) ->
+ {#{type=>exs1024s, bits=>64, weak_low_bits=>3, next=>fun exs1024_next/1,
+ jump=>fun exs1024_jump/1},
+ fun exs1024_seed/1};
+mk_alg(exrop) ->
+ {#{type=>exrop, bits=>58, weak_low_bits=>1, next=>fun exrop_next/1,
+ uniform=>fun exrop_uniform/1, uniform_n=>fun exrop_uniform/2,
+ jump=>fun exrop_jump/1},
+ fun exrop_seed/1}.
%% =====================================================================
%% exs64 PRNG: Xorshift64*
@@ -222,29 +439,21 @@ mk_alg(exs1024) ->
%% Reference URL: http://xorshift.di.unimi.it/
%% =====================================================================
--type exs64_state() :: uint64().
+-opaque exs64_state() :: uint64().
exs64_seed({A1, A2, A3}) ->
- {V1, _} = exs64_next(((A1 band ?UINT32MASK) * 4294967197 + 1)),
- {V2, _} = exs64_next(((A2 band ?UINT32MASK) * 4294967231 + 1)),
- {V3, _} = exs64_next(((A3 band ?UINT32MASK) * 4294967279 + 1)),
- ((V1 * V2 * V3) rem (?UINT64MASK - 1)) + 1.
+ {V1, _} = exs64_next((?MASK(32, A1) * 4294967197 + 1)),
+ {V2, _} = exs64_next((?MASK(32, A2) * 4294967231 + 1)),
+ {V3, _} = exs64_next((?MASK(32, A3) * 4294967279 + 1)),
+ ((V1 * V2 * V3) rem (?MASK(64) - 1)) + 1.
%% Advance xorshift64* state for one step and generate 64bit unsigned integer
-spec exs64_next(exs64_state()) -> {uint64(), exs64_state()}.
exs64_next(R) ->
R1 = R bxor (R bsr 12),
- R2 = R1 bxor ((R1 band ?UINT39MASK) bsl 25),
+ R2 = R1 bxor ?BSL(64, R1, 25),
R3 = R2 bxor (R2 bsr 27),
- {(R3 * 2685821657736338717) band ?UINT64MASK, R3}.
-
-exs64_uniform({Alg, R0}) ->
- {V, R1} = exs64_next(R0),
- {V / 18446744073709551616, {Alg, R1}}.
-
-exs64_uniform(Max, {Alg, R}) ->
- {V, R1} = exs64_next(R),
- {(V rem Max) + 1, {Alg, R1}}.
+ {?MASK(64, R3 * 2685821657736338717), R3}.
%% =====================================================================
%% exsplus PRNG: Xorshift116+
@@ -254,15 +463,17 @@ exs64_uniform(Max, {Alg, R}) ->
%% Modification of the original Xorshift128+ algorithm to 116
%% by Sebastiano Vigna, a lot of thanks for his help and work.
%% =====================================================================
--type exsplus_state() :: nonempty_improper_list(uint58(), uint58()).
+-opaque exsplus_state() :: nonempty_improper_list(uint58(), uint58()).
-dialyzer({no_improper_lists, exsplus_seed/1}).
exsplus_seed({A1, A2, A3}) ->
- {_, R1} = exsplus_next([(((A1 * 4294967197) + 1) band ?UINT58MASK)|
- (((A2 * 4294967231) + 1) band ?UINT58MASK)]),
- {_, R2} = exsplus_next([(((A3 * 4294967279) + 1) band ?UINT58MASK)|
- tl(R1)]),
+ {_, R1} = exsplus_next(
+ [?MASK(58, (A1 * 4294967197) + 1)|
+ ?MASK(58, (A2 * 4294967231) + 1)]),
+ {_, R2} = exsplus_next(
+ [?MASK(58, (A3 * 4294967279) + 1)|
+ tl(R1)]),
R2.
-dialyzer({no_improper_lists, exsplus_next/1}).
@@ -271,17 +482,56 @@ exsplus_seed({A1, A2, A3}) ->
-spec exsplus_next(exsplus_state()) -> {uint58(), exsplus_state()}.
exsplus_next([S1|S0]) ->
%% Note: members s0 and s1 are swapped here
- S11 = (S1 bxor (S1 bsl 24)) band ?UINT58MASK,
+ S11 = S1 bxor ?BSL(58, S1, 24),
S12 = S11 bxor S0 bxor (S11 bsr 11) bxor (S0 bsr 41),
- {(S0 + S12) band ?UINT58MASK, [S0|S12]}.
+ {?MASK(58, S0 + S12), [S0|S12]}.
-exsplus_uniform({Alg, R0}) ->
+
+exsp_uniform({Alg, R0}) ->
{I, R1} = exsplus_next(R0),
- {I / (?UINT58MASK+1), {Alg, R1}}.
+ %% Waste the lowest bit since it is of lower
+ %% randomness quality than the others
+ {(I bsr (58-53)) * ?TWO_POW_MINUS53, {Alg, R1}}.
-exsplus_uniform(Max, {Alg, R}) ->
+exsp_uniform(Range, {Alg, R}) ->
{V, R1} = exsplus_next(R),
- {(V rem Max) + 1, {Alg, R1}}.
+ MaxMinusRange = ?BIT(58) - Range,
+ ?uniform_range(Range, Alg, R1, V, MaxMinusRange, I).
+
+
+%% This is the jump function for the exsplus generator, equivalent
+%% to 2^64 calls to next/1; it can be used to generate 2^52
+%% non-overlapping subsequences for parallel computations.
+%% Note: the jump function takes 116 times of the execution time of
+%% next/1.
+
+%% -define(JUMPCONST, 16#000d174a83e17de2302f8ea6bc32c797).
+%% split into 58-bit chunks
+%% and two iterative executions
+
+-define(JUMPCONST1, 16#02f8ea6bc32c797).
+-define(JUMPCONST2, 16#345d2a0f85f788c).
+-define(JUMPELEMLEN, 58).
+
+-dialyzer({no_improper_lists, exsplus_jump/1}).
+-spec exsplus_jump(state()) -> state().
+exsplus_jump({Alg, S}) ->
+ {S1, AS1} = exsplus_jump(S, [0|0], ?JUMPCONST1, ?JUMPELEMLEN),
+ {_, AS2} = exsplus_jump(S1, AS1, ?JUMPCONST2, ?JUMPELEMLEN),
+ {Alg, AS2}.
+
+-dialyzer({no_improper_lists, exsplus_jump/4}).
+exsplus_jump(S, AS, _, 0) ->
+ {S, AS};
+exsplus_jump(S, [AS0|AS1], J, N) ->
+ {_, NS} = exsplus_next(S),
+ case ?MASK(1, J) of
+ 1 ->
+ [S0|S1] = S,
+ exsplus_jump(NS, [(AS0 bxor S0)|(AS1 bxor S1)], J bsr 1, N-1);
+ 0 ->
+ exsplus_jump(NS, [AS0|AS1], J bsr 1, N-1)
+ end.
%% =====================================================================
%% exs1024 PRNG: Xorshift1024*
@@ -289,12 +539,12 @@ exsplus_uniform(Max, {Alg, R}) ->
%% Reference URL: http://xorshift.di.unimi.it/
%% =====================================================================
--type exs1024_state() :: {list(uint64()), list(uint64())}.
+-opaque exs1024_state() :: {list(uint64()), list(uint64())}.
exs1024_seed({A1, A2, A3}) ->
- B1 = (((A1 band ?UINT21MASK) + 1) * 2097131) band ?UINT21MASK,
- B2 = (((A2 band ?UINT21MASK) + 1) * 2097133) band ?UINT21MASK,
- B3 = (((A3 band ?UINT21MASK) + 1) * 2097143) band ?UINT21MASK,
+ B1 = ?MASK(21, (?MASK(21, A1) + 1) * 2097131),
+ B2 = ?MASK(21, (?MASK(21, A2) + 1) * 2097133),
+ B3 = ?MASK(21, (?MASK(21, A3) + 1) * 2097143),
{exs1024_gen1024((B1 bsl 43) bor (B2 bsl 22) bor (B3 bsl 1) bor 1),
[]}.
@@ -317,11 +567,11 @@ exs1024_gen1024(N, R, L) ->
%% X: random number output
-spec exs1024_calc(uint64(), uint64()) -> {uint64(), uint64()}.
exs1024_calc(S0, S1) ->
- S11 = S1 bxor ((S1 band ?UINT33MASK) bsl 31),
+ S11 = S1 bxor ?BSL(64, S1, 31),
S12 = S11 bxor (S11 bsr 11),
S01 = S0 bxor (S0 bsr 30),
NS1 = S01 bxor S12,
- {(NS1 * 1181783497276652981) band ?UINT64MASK, NS1}.
+ {?MASK(64, NS1 * 1181783497276652981), NS1}.
%% Advance xorshift1024* state for one step and generate 64bit unsigned integer
-spec exs1024_next(exs1024_state()) -> {uint64(), exs1024_state()}.
@@ -332,13 +582,190 @@ exs1024_next({[H], RL}) ->
NL = [H|lists:reverse(RL)],
exs1024_next({NL, []}).
-exs1024_uniform({Alg, R0}) ->
- {V, R1} = exs1024_next(R0),
- {V / 18446744073709551616, {Alg, R1}}.
-exs1024_uniform(Max, {Alg, R}) ->
- {V, R1} = exs1024_next(R),
- {(V rem Max) + 1, {Alg, R1}}.
+%% This is the jump function for the exs1024 generator, equivalent
+%% to 2^512 calls to next(); it can be used to generate 2^512
+%% non-overlapping subsequences for parallel computations.
+%% Note: the jump function takes ~2000 times of the execution time of
+%% next/1.
+
+%% Jump constant here split into 58 bits for speed
+-define(JUMPCONSTHEAD, 16#00242f96eca9c41d).
+-define(JUMPCONSTTAIL,
+ [16#0196e1ddbe5a1561,
+ 16#0239f070b5837a3c,
+ 16#03f393cc68796cd2,
+ 16#0248316f404489af,
+ 16#039a30088bffbac2,
+ 16#02fea70dc2d9891f,
+ 16#032ae0d9644caec4,
+ 16#0313aac17d8efa43,
+ 16#02f132e055642626,
+ 16#01ee975283d71c93,
+ 16#00552321b06f5501,
+ 16#00c41d10a1e6a569,
+ 16#019158ecf8aa1e44,
+ 16#004e9fc949d0b5fc,
+ 16#0363da172811fdda,
+ 16#030e38c3b99181f2,
+ 16#0000000a118038fc]).
+-define(JUMPTOTALLEN, 1024).
+-define(RINGLEN, 16).
+
+-spec exs1024_jump(state()) -> state().
+
+exs1024_jump({Alg, {L, RL}}) ->
+ P = length(RL),
+ AS = exs1024_jump({L, RL},
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ ?JUMPCONSTTAIL, ?JUMPCONSTHEAD, ?JUMPELEMLEN, ?JUMPTOTALLEN),
+ {ASL, ASR} = lists:split(?RINGLEN - P, AS),
+ {Alg, {ASL, lists:reverse(ASR)}}.
+
+exs1024_jump(_, AS, _, _, _, 0) ->
+ AS;
+exs1024_jump(S, AS, [H|T], _, 0, TN) ->
+ exs1024_jump(S, AS, T, H, ?JUMPELEMLEN, TN);
+exs1024_jump({L, RL}, AS, JL, J, N, TN) ->
+ {_, NS} = exs1024_next({L, RL}),
+ case ?MASK(1, J) of
+ 1 ->
+ AS2 = lists:zipwith(fun(X, Y) -> X bxor Y end,
+ AS, L ++ lists:reverse(RL)),
+ exs1024_jump(NS, AS2, JL, J bsr 1, N-1, TN-1);
+ 0 ->
+ exs1024_jump(NS, AS, JL, J bsr 1, N-1, TN-1)
+ end.
+
+%% =====================================================================
+%% exrop PRNG: Xoroshiro116+
+%%
+%% Reference URL: http://xorshift.di.unimi.it/
+%%
+%% 58 bits fits into an immediate on 64bits Erlang and is thus much faster.
+%% In fact, an immediate number is 60 bits signed in Erlang so you can
+%% add two positive 58 bit numbers and get a 59 bit number that still is
+%% a positive immediate, which is a property we utilize here...
+%%
+%% Modification of the original Xororhiro128+ algorithm to 116 bits
+%% by Sebastiano Vigna. A lot of thanks for his help and work.
+%% =====================================================================
+%% (a, b, c) = (24, 2, 35)
+%% JUMP Polynomial = 0x9863200f83fcd4a11293241fcb12a (116 bit)
+%%
+%% From http://xoroshiro.di.unimi.it/xoroshiro116plus.c:
+%% ---------------------------------------------------------------------
+%% /* Written in 2017 by Sebastiano Vigna ([email protected]).
+%%
+%% To the extent possible under law, the author has dedicated all copyright
+%% and related and neighboring rights to this software to the public domain
+%% worldwide. This software is distributed without any warranty.
+%%
+%% See <http://creativecommons.org/publicdomain/zero/1.0/>. */
+%%
+%% #include <stdint.h>
+%%
+%% #define UINT58MASK (uint64_t)((UINT64_C(1) << 58) - 1)
+%%
+%% uint64_t s[2];
+%%
+%% static inline uint64_t rotl58(const uint64_t x, int k) {
+%% return (x << k) & UINT58MASK | (x >> (58 - k));
+%% }
+%%
+%% uint64_t next(void) {
+%% uint64_t s1 = s[1];
+%% const uint64_t s0 = s[0];
+%% const uint64_t result = (s0 + s1) & UINT58MASK;
+%%
+%% s1 ^= s0;
+%% s[0] = rotl58(s0, 24) ^ s1 ^ ((s1 << 2) & UINT58MASK); // a, b
+%% s[1] = rotl58(s1, 35); // c
+%% return result;
+%% }
+%%
+%% void jump(void) {
+%% static const uint64_t JUMP[] =
+%% { 0x4a11293241fcb12a, 0x0009863200f83fcd };
+%%
+%% uint64_t s0 = 0;
+%% uint64_t s1 = 0;
+%% for(int i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
+%% for(int b = 0; b < 64; b++) {
+%% if (JUMP[i] & UINT64_C(1) << b) {
+%% s0 ^= s[0];
+%% s1 ^= s[1];
+%% }
+%% next();
+%% }
+%% s[0] = s0;
+%% s[1] = s1;
+%% }
+
+-opaque exrop_state() :: nonempty_improper_list(uint58(), uint58()).
+
+-dialyzer({no_improper_lists, exrop_seed/1}).
+exrop_seed({A1, A2, A3}) ->
+ [_|S1] =
+ exrop_next_s(
+ ?MASK(58, (A1 * 4294967197) + 1),
+ ?MASK(58, (A2 * 4294967231) + 1)),
+ exrop_next_s(?MASK(58, (A3 * 4294967279) + 1), S1).
+
+-dialyzer({no_improper_lists, exrop_next_s/2}).
+%% Advance xoroshiro116+ state one step
+%% [a, b, c] = [24, 2, 35]
+-define(
+ exrop_next_s(S0, S1, S1_a),
+ begin
+ S1_a = S1 bxor S0,
+ [?ROTL(58, S0, 24) bxor S1_a bxor ?BSL(58, S1_a, 2)| % a, b
+ ?ROTL(58, S1_a, 35)] % c
+ end).
+exrop_next_s(S0, S1) ->
+ ?exrop_next_s(S0, S1, S1_a).
+
+-dialyzer({no_improper_lists, exrop_next/1}).
+%% Advance xoroshiro116+ state one step, generate 58 bit unsigned integer,
+%% and waste the lowest bit since it is of lower randomness quality
+exrop_next([S0|S1]) ->
+ {?MASK(58, S0 + S1), ?exrop_next_s(S0, S1, S1_a)}.
+
+exrop_uniform({Alg, R}) ->
+ {V, R1} = exrop_next(R),
+ %% Waste the lowest bit since it is of lower
+ %% randomness quality than the others
+ {(V bsr (58-53)) * ?TWO_POW_MINUS53, {Alg, R1}}.
+
+exrop_uniform(Range, {Alg, R}) ->
+ {V, R1} = exrop_next(R),
+ MaxMinusRange = ?BIT(58) - Range,
+ ?uniform_range(Range, Alg, R1, V, MaxMinusRange, I).
+
+%% Split a 116 bit constant into two 58 bit words,
+%% a top '1' marks the end of the low word.
+-define(
+ JUMP_116(Jump),
+ [?BIT(58) bor ?MASK(58, (Jump)),(Jump) bsr 58]).
+%%
+exrop_jump({Alg,S}) ->
+ [J|Js] = ?JUMP_116(16#9863200f83fcd4a11293241fcb12a),
+ {Alg, exrop_jump(S, 0, 0, J, Js)}.
+%%
+-dialyzer({no_improper_lists, exrop_jump/5}).
+exrop_jump(_S, S0, S1, 0, []) -> % End of jump constant
+ [S0|S1];
+exrop_jump(S, S0, S1, 1, [J|Js]) -> % End of word
+ exrop_jump(S, S0, S1, J, Js);
+exrop_jump([S__0|S__1] = _S, S0, S1, J, Js) ->
+ case ?MASK(1, J) of
+ 1 ->
+ NewS = exrop_next_s(S__0, S__1),
+ exrop_jump(NewS, S0 bxor S__0, S1 bxor S__1, J bsr 1, Js);
+ 0 ->
+ NewS = exrop_next_s(S__0, S__1),
+ exrop_jump(NewS, S0, S1, J bsr 1, Js)
+ end.
%% =====================================================================
%% Ziggurat cont
@@ -347,9 +774,13 @@ exs1024_uniform(Max, {Alg, R}) ->
-define(NOR_INV_R, 1/?NOR_R).
%% return a {sign, Random51bits, State}
+get_52({Alg=#{bits:=Bits, next:=Next}, S0}) ->
+ %% Use the high bits
+ {Int,S1} = Next(S0),
+ {?BIT(Bits - 51 - 1) band Int, Int bsr (Bits - 51), {Alg, S1}};
get_52({Alg=#{next:=Next}, S0}) ->
{Int,S1} = Next(S0),
- {((1 bsl 51) band Int), Int band ((1 bsl 51)-1), {Alg, S1}}.
+ {?BIT(51) band Int, ?MASK(51, Int), {Alg, S1}}.
%% Slow path
normal_s(0, Sign, X0, State0) ->
diff --git a/lib/stdlib/src/re.erl b/lib/stdlib/src/re.erl
index 52d3c35608..726b409d4d 100644
--- a/lib/stdlib/src/re.erl
+++ b/lib/stdlib/src/re.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,7 +33,12 @@
%%% BIFs
--export([compile/1, compile/2, run/2, run/3, inspect/2]).
+-export([version/0, compile/1, compile/2, run/2, run/3, inspect/2]).
+
+-spec version() -> binary().
+
+version() ->
+ erlang:nif_error(undef).
-spec compile(Regexp) -> {ok, MP} | {error, ErrSpec} when
Regexp :: iodata(),
diff --git a/lib/stdlib/src/sets.erl b/lib/stdlib/src/sets.erl
index 3e70450320..c65a13b22e 100644
--- a/lib/stdlib/src/sets.erl
+++ b/lib/stdlib/src/sets.erl
@@ -128,14 +128,14 @@ is_element(E, S) ->
Set2 :: set(Element).
add_element(E, S0) ->
Slot = get_slot(S0, E),
- {S1,Ic} = on_bucket(fun (B0) -> add_bkt_el(E, B0, B0) end, S0, Slot),
- maybe_expand(S1, Ic).
-
--spec add_bkt_el(T, [T], [T]) -> {[T], 0 | 1}.
-add_bkt_el(E, [E|_], Bkt) -> {Bkt,0};
-add_bkt_el(E, [_|B], Bkt) ->
- add_bkt_el(E, B, Bkt);
-add_bkt_el(E, [], Bkt) -> {[E|Bkt],1}.
+ Bkt = get_bucket(S0, Slot),
+ case lists:member(E, Bkt) of
+ true ->
+ S0;
+ false ->
+ S1 = update_bucket(S0, Slot, [E | Bkt]),
+ maybe_expand(S1)
+ end.
%% del_element(Element, Set) -> Set.
%% Return Set but with Element removed.
@@ -144,15 +144,28 @@ add_bkt_el(E, [], Bkt) -> {[E|Bkt],1}.
Set2 :: set(Element).
del_element(E, S0) ->
Slot = get_slot(S0, E),
- {S1,Dc} = on_bucket(fun (B0) -> del_bkt_el(E, B0) end, S0, Slot),
- maybe_contract(S1, Dc).
+ Bkt = get_bucket(S0, Slot),
+ case lists:member(E, Bkt) of
+ false ->
+ S0;
+ true ->
+ S1 = update_bucket(S0, Slot, lists:delete(E, Bkt)),
+ maybe_contract(S1, 1)
+ end.
--spec del_bkt_el(T, [T]) -> {[T], 0 | 1}.
-del_bkt_el(E, [E|Bkt]) -> {Bkt,1};
-del_bkt_el(E, [Other|Bkt0]) ->
- {Bkt1,Dc} = del_bkt_el(E, Bkt0),
- {[Other|Bkt1],Dc};
-del_bkt_el(_, []) -> {[],0}.
+%% update_bucket(Set, Slot, NewBucket) -> UpdatedSet.
+%% Replace bucket in Slot by NewBucket
+-spec update_bucket(Set1, Slot, Bkt) -> Set2 when
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Slot :: non_neg_integer(),
+ Bkt :: [Element].
+update_bucket(Set, Slot, NewBucket) ->
+ SegI = ((Slot-1) div ?seg_size) + 1,
+ BktI = ((Slot-1) rem ?seg_size) + 1,
+ Segs = Set#set.segs,
+ Seg = element(SegI, Segs),
+ Set#set{segs = setelement(SegI, Segs, setelement(BktI, Seg, NewBucket))}.
%% union(Set1, Set2) -> Set
%% Return the union of Set1 and Set2.
@@ -272,19 +285,6 @@ get_slot(T, Key) ->
-spec get_bucket(set(), non_neg_integer()) -> term().
get_bucket(T, Slot) -> get_bucket_s(T#set.segs, Slot).
-%% on_bucket(Fun, Hashdb, Slot) -> {NewHashDb,Result}.
-%% Apply Fun to the bucket in Slot and replace the returned bucket.
--spec on_bucket(fun((_) -> {[_], 0 | 1}), set(E), non_neg_integer()) ->
- {set(E), 0 | 1}.
-on_bucket(F, T, Slot) ->
- SegI = ((Slot-1) div ?seg_size) + 1,
- BktI = ((Slot-1) rem ?seg_size) + 1,
- Segs = T#set.segs,
- Seg = element(SegI, Segs),
- B0 = element(BktI, Seg),
- {B1, Res} = F(B0), %Op on the bucket.
- {T#set{segs = setelement(SegI, Segs, setelement(BktI, Seg, B1))},Res}.
-
%% fold_set(Fun, Acc, Dictionary) -> Dictionary.
%% filter_set(Fun, Dictionary) -> Dictionary.
@@ -349,8 +349,8 @@ put_bucket_s(Segs, Slot, Bkt) ->
Seg = setelement(BktI, element(SegI, Segs), Bkt),
setelement(SegI, Segs, Seg).
--spec maybe_expand(set(E), 0 | 1) -> set(E).
-maybe_expand(T0, Ic) when T0#set.size + Ic > T0#set.exp_size ->
+-spec maybe_expand(set(E)) -> set(E).
+maybe_expand(T0) when T0#set.size + 1 > T0#set.exp_size ->
T = maybe_expand_segs(T0), %Do we need more segments.
N = T#set.n + 1, %Next slot to expand into
Segs0 = T#set.segs,
@@ -360,12 +360,12 @@ maybe_expand(T0, Ic) when T0#set.size + Ic > T0#set.exp_size ->
{B1,B2} = rehash(B, Slot1, Slot2, T#set.maxn),
Segs1 = put_bucket_s(Segs0, Slot1, B1),
Segs2 = put_bucket_s(Segs1, Slot2, B2),
- T#set{size = T#set.size + Ic,
+ T#set{size = T#set.size + 1,
n = N,
exp_size = N * ?expand_load,
con_size = N * ?contract_load,
segs = Segs2};
-maybe_expand(T, Ic) -> T#set{size = T#set.size + Ic}.
+maybe_expand(T) -> T#set{size = T#set.size + 1}.
-spec maybe_expand_segs(set(E)) -> set(E).
maybe_expand_segs(T) when T#set.n =:= T#set.maxn ->
diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl
index 82a3a2be4f..6eafc7b209 100644
--- a/lib/stdlib/src/shell.erl
+++ b/lib/stdlib/src/shell.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -229,8 +229,9 @@ server_loop(N0, Eval_0, Bs00, RT, Ds00, History0, Results0) ->
{Eval_1,Bs0,Ds0,Prompt} = prompt(N, Eval_0, Bs00, RT, Ds00),
{Res,Eval0} = get_command(Prompt, Eval_1, Bs0, RT, Ds0),
case Res of
- {ok,Es0} ->
- case expand_hist(Es0, N) of
+ {ok,Es0,XBs} ->
+ Es1 = lib:subst_values_for_vars(Es0, XBs),
+ case expand_hist(Es1, N) of
{ok,Es} ->
{V,Eval,Bs,Ds} = shell_cmd(Es, Eval0, Bs0, RT, Ds0, cmd),
{History,Results} = check_and_get_history_and_results(),
@@ -276,10 +277,10 @@ get_command(Prompt, Eval, Bs, RT, Ds) ->
fun() ->
exit(
case
- io:scan_erl_exprs(group_leader(), Prompt, 1)
+ io:scan_erl_exprs(group_leader(), Prompt, 1, [text])
of
{ok,Toks,_EndPos} ->
- erl_parse:parse_exprs(Toks);
+ lib:extended_parse_exprs(Toks);
{eof,_EndPos} ->
eof;
{error,ErrorInfo,_EndPos} ->
@@ -768,6 +769,8 @@ used_records({call,_,{atom,_,record_info},[A,{atom,_,Name}]}) ->
{name, Name, A};
used_records({call,Line,{tuple,_,[M,F]},As}) ->
used_records({call,Line,{remote,Line,M,F},As});
+used_records({type,_,record,[{atom,_,Name}|Fs]}) ->
+ {name, Name, Fs};
used_records(T) when is_tuple(T) ->
{expr, tuple_to_list(T)};
used_records(E) ->
@@ -965,10 +968,11 @@ local_func(f, [{var,_,Name}], Bs, _Shell, _RT, _Lf, _Ef) ->
{value,ok,erl_eval:del_binding(Name, Bs)};
local_func(f, [_Other], _Bs, _Shell, _RT, _Lf, _Ef) ->
erlang:raise(error, function_clause, [{shell,f,1}]);
-local_func(rd, [{atom,_,RecName},RecDef0], Bs, _Shell, RT, _Lf, _Ef) ->
+local_func(rd, [{atom,_,RecName0},RecDef0], Bs, _Shell, RT, _Lf, _Ef) ->
RecDef = expand_value(RecDef0),
RDs = lists:flatten(erl_pp:expr(RecDef)),
- Attr = lists:concat(["-record('", RecName, "',", RDs, ")."]),
+ RecName = io_lib:write_atom_as_latin1(RecName0),
+ Attr = lists:concat(["-record(", RecName, ",", RDs, ")."]),
{ok, Tokens, _} = erl_scan:string(Attr),
case erl_parse:parse_form(Tokens) of
{ok,AttrForm} ->
@@ -1234,22 +1238,22 @@ read_file_records(File, Opts) ->
end.
%% This is how the debugger searches for source files. See int.erl.
-try_source(Beam, CB) ->
- Os = case lists:keyfind(options, 1, binary_to_term(CB)) of
- false -> [];
- {_, Os0} -> Os0
- end,
+try_source(Beam, RawCB) ->
+ EbinDir = filename:dirname(Beam),
+ CB = binary_to_term(RawCB),
+ Os = proplists:get_value(options,CB, []),
Src0 = filename:rootname(Beam) ++ ".erl",
- case is_file(Src0) of
- true -> parse_file(Src0, Os);
- false ->
- EbinDir = filename:dirname(Beam),
- Src = filename:join([filename:dirname(EbinDir), "src",
- filename:basename(Src0)]),
- case is_file(Src) of
- true -> parse_file(Src, Os);
- false -> {error, nofile}
- end
+ Src1 = filename:join([filename:dirname(EbinDir), "src",
+ filename:basename(Src0)]),
+ Src2 = proplists:get_value(source, CB, []),
+ try_sources([Src0,Src1,Src2], Os).
+
+try_sources([], _) ->
+ {error, nofile};
+try_sources([Src|Rest], Os) ->
+ case is_file(Src) of
+ true -> parse_file(Src, Os);
+ false -> try_sources(Rest, Os)
end.
is_file(Name) ->
@@ -1415,9 +1419,11 @@ columns() ->
{ok,N} -> N;
_ -> 80
end.
+
encoding() ->
[{encoding, Encoding}] = enc(),
Encoding.
+
enc() ->
case lists:keyfind(encoding, 1, io:getopts()) of
false -> [{encoding,latin1}]; % should never happen
diff --git a/lib/stdlib/src/shell_default.erl b/lib/stdlib/src/shell_default.erl
index 6947cf181b..a0c1d98513 100644
--- a/lib/stdlib/src/shell_default.erl
+++ b/lib/stdlib/src/shell_default.erl
@@ -23,7 +23,7 @@
-module(shell_default).
--export([help/0,lc/1,c/1,c/2,nc/1,nl/1,l/1,i/0,pid/3,i/3,m/0,m/1,
+-export([help/0,lc/1,c/1,c/2,c/3,nc/1,nl/1,l/1,i/0,pid/3,i/3,m/0,m/1,lm/0,mm/0,
memory/0,memory/1,uptime/0,
erlangrc/1,bi/1, regs/0, flush/0,pwd/0,ls/0,ls/1,cd/1,
y/1, y/2,
@@ -72,6 +72,7 @@ bi(I) -> c:bi(I).
bt(Pid) -> c:bt(Pid).
c(File) -> c:c(File).
c(File, Opt) -> c:c(File, Opt).
+c(File, Opt, Filter) -> c:c(File, Opt, Filter).
cd(D) -> c:cd(D).
erlangrc(X) -> c:erlangrc(X).
flush() -> c:flush().
@@ -83,6 +84,8 @@ ls() -> c:ls().
ls(S) -> c:ls(S).
m() -> c:m().
m(Mod) -> c:m(Mod).
+lm() -> c:lm().
+mm() -> c:mm().
memory() -> c:memory().
memory(Type) -> c:memory(Type).
nc(X) -> c:nc(X).
diff --git a/lib/stdlib/src/sofs.erl b/lib/stdlib/src/sofs.erl
index c244e06ca4..cc50e1b52c 100644
--- a/lib/stdlib/src/sofs.erl
+++ b/lib/stdlib/src/sofs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -76,7 +76,7 @@
%%
%% See also "Naive Set Theory" by Paul R. Halmos.
%%
-%% By convention, erlang:error/2 is called from exported functions.
+%% By convention, erlang:error/1 is called from exported functions.
-define(TAG, 'Set').
-define(ORDTAG, 'OrdSet').
@@ -87,12 +87,6 @@
-define(LIST(S), (S)#?TAG.data).
-define(TYPE(S), (S)#?TAG.type).
-%%-define(SET(L, T),
-%% case is_type(T) of
-%% true -> #?TAG{data = L, type = T};
-%% false -> erlang:error(badtype, [T])
-%% end
-%% ).
-define(SET(L, T), #?TAG{data = L, type = T}).
-define(IS_SET(S), is_record(S, ?TAG)).
-define(IS_UNTYPED_SET(S), ?TYPE(S) =:= ?ANYTYPE).
@@ -154,11 +148,8 @@ from_term(T) ->
_ when is_list(T) -> [?ANYTYPE];
_ -> ?ANYTYPE
end,
- case catch setify(T, Type) of
- {'EXIT', _} ->
- erlang:error(badarg, [T]);
- Set ->
- Set
+ try setify(T, Type)
+ catch _:_ -> erlang:error(badarg)
end.
-spec(from_term(Term, Type) -> AnySet when
@@ -168,14 +159,11 @@ from_term(T) ->
from_term(L, T) ->
case is_type(T) of
true ->
- case catch setify(L, T) of
- {'EXIT', _} ->
- erlang:error(badarg, [L, T]);
- Set ->
- Set
+ try setify(L, T)
+ catch _:_ -> erlang:error(badarg)
end;
false ->
- erlang:error(badarg, [L, T])
+ erlang:error(badarg)
end.
-spec(from_external(ExternalSet, Type) -> AnySet when
@@ -208,33 +196,26 @@ is_type(_T) ->
Set :: a_set(),
Terms :: [term()]).
set(L) ->
- case catch usort(L) of
- {'EXIT', _} ->
- erlang:error(badarg, [L]);
- SL ->
- ?SET(SL, ?ATOM_TYPE)
+ try usort(L) of
+ SL -> ?SET(SL, ?ATOM_TYPE)
+ catch _:_ -> erlang:error(badarg)
end.
-spec(set(Terms, Type) -> Set when
Set :: a_set(),
Terms :: [term()],
Type :: type()).
-set(L, ?SET_OF(Type) = T) when ?IS_ATOM_TYPE(Type), Type =/= ?ANYTYPE ->
- case catch usort(L) of
- {'EXIT', _} ->
- erlang:error(badarg, [L, T]);
- SL ->
- ?SET(SL, Type)
+set(L, ?SET_OF(Type)) when ?IS_ATOM_TYPE(Type), Type =/= ?ANYTYPE ->
+ try usort(L) of
+ SL -> ?SET(SL, Type)
+ catch _:_ -> erlang:error(badarg)
end;
set(L, ?SET_OF(_) = T) ->
- case catch setify(L, T) of
- {'EXIT', _} ->
- erlang:error(badarg, [L, T]);
- Set ->
- Set
+ try setify(L, T)
+ catch _:_ -> erlang:error(badarg)
end;
-set(L, T) ->
- erlang:error(badarg, [L, T]).
+set(_, _) ->
+ erlang:error(badarg).
-spec(from_sets(ListOfSets) -> Set when
Set :: a_set(),
@@ -245,19 +226,19 @@ set(L, T) ->
from_sets(Ss) when is_list(Ss) ->
case set_of_sets(Ss, [], ?ANYTYPE) of
{error, Error} ->
- erlang:error(Error, [Ss]);
+ erlang:error(Error);
Set ->
Set
end;
from_sets(Tuple) when is_tuple(Tuple) ->
case ordset_of_sets(tuple_to_list(Tuple), [], []) of
error ->
- erlang:error(badarg, [Tuple]);
+ erlang:error(badarg);
Set ->
Set
end;
-from_sets(T) ->
- erlang:error(badarg, [T]).
+from_sets(_) ->
+ erlang:error(badarg).
-spec(relation(Tuples) -> Relation when
Relation :: relation(),
@@ -265,14 +246,11 @@ from_sets(T) ->
relation([]) ->
?SET([], ?BINREL(?ATOM_TYPE, ?ATOM_TYPE));
relation(Ts = [T | _]) when is_tuple(T) ->
- case catch rel(Ts, tuple_size(T)) of
- {'EXIT', _} ->
- erlang:error(badarg, [Ts]);
- Set ->
- Set
+ try rel(Ts, tuple_size(T))
+ catch _:_ -> erlang:error(badarg)
end;
-relation(E) ->
- erlang:error(badarg, [E]).
+relation(_) ->
+ erlang:error(badarg).
-spec(relation(Tuples, Type) -> Relation when
N :: integer(),
@@ -280,24 +258,20 @@ relation(E) ->
Relation :: relation(),
Tuples :: [tuple()]).
relation(Ts, TS) ->
- case catch rel(Ts, TS) of
- {'EXIT', _} ->
- erlang:error(badarg, [Ts, TS]);
- Set ->
- Set
+ try rel(Ts, TS)
+ catch _:_ -> erlang:error(badarg)
end.
-spec(a_function(Tuples) -> Function when
Function :: a_function(),
Tuples :: [tuple()]).
a_function(Ts) ->
- case catch func(Ts, ?BINREL(?ATOM_TYPE, ?ATOM_TYPE)) of
- {'EXIT', _} ->
- erlang:error(badarg, [Ts]);
+ try func(Ts, ?BINREL(?ATOM_TYPE, ?ATOM_TYPE)) of
Bad when is_atom(Bad) ->
- erlang:error(Bad, [Ts]);
- Set ->
- Set
+ erlang:error(Bad);
+ Set ->
+ Set
+ catch _:_ -> erlang:error(badarg)
end.
-spec(a_function(Tuples, Type) -> Function when
@@ -305,26 +279,24 @@ a_function(Ts) ->
Tuples :: [tuple()],
Type :: type()).
a_function(Ts, T) ->
- case catch a_func(Ts, T) of
- {'EXIT', _} ->
- erlang:error(badarg, [Ts, T]);
+ try a_func(Ts, T) of
Bad when is_atom(Bad) ->
- erlang:error(Bad, [Ts, T]);
+ erlang:error(Bad);
Set ->
Set
+ catch _:_ -> erlang:error(badarg)
end.
-spec(family(Tuples) -> Family when
Family :: family(),
Tuples :: [tuple()]).
family(Ts) ->
- case catch fam2(Ts, ?FAMILY(?ATOM_TYPE, ?ATOM_TYPE)) of
- {'EXIT', _} ->
- erlang:error(badarg, [Ts]);
+ try fam2(Ts, ?FAMILY(?ATOM_TYPE, ?ATOM_TYPE)) of
Bad when is_atom(Bad) ->
- erlang:error(Bad, [Ts]);
+ erlang:error(Bad);
Set ->
Set
+ catch _:_ -> erlang:error(badarg)
end.
-spec(family(Tuples, Type) -> Family when
@@ -332,13 +304,12 @@ family(Ts) ->
Tuples :: [tuple()],
Type :: type()).
family(Ts, T) ->
- case catch fam(Ts, T) of
- {'EXIT', _} ->
- erlang:error(badarg, [Ts, T]);
+ try fam(Ts, T) of
Bad when is_atom(Bad) ->
- erlang:error(Bad, [Ts, T]);
+ erlang:error(Bad);
Set ->
Set
+ catch _:_ -> erlang:error(badarg)
end.
%%%
@@ -373,7 +344,7 @@ to_sets(S) when ?IS_SET(S) ->
to_sets(S) when ?IS_ORDSET(S), is_tuple(?ORDTYPE(S)) ->
tuple_of_sets(tuple_to_list(?ORDDATA(S)), tuple_to_list(?ORDTYPE(S)), []);
to_sets(S) when ?IS_ORDSET(S) ->
- erlang:error(badarg, [S]).
+ erlang:error(badarg).
-spec(no_elements(ASet) -> NoElements when
ASet :: a_set() | ordset(),
@@ -383,7 +354,7 @@ no_elements(S) when ?IS_SET(S) ->
no_elements(S) when ?IS_ORDSET(S), is_tuple(?ORDTYPE(S)) ->
tuple_size(?ORDDATA(S));
no_elements(S) when ?IS_ORDSET(S) ->
- erlang:error(badarg, [S]).
+ erlang:error(badarg).
-spec(specification(Fun, Set1) -> Set2 when
Fun :: spec_fun(),
@@ -401,7 +372,7 @@ specification(Fun, S) when ?IS_SET(S) ->
SL when is_list(SL) ->
?SET(SL, Type);
Bad ->
- erlang:error(Bad, [Fun, S])
+ erlang:error(Bad)
end.
-spec(union(Set1, Set2) -> Set3 when
@@ -410,7 +381,7 @@ specification(Fun, S) when ?IS_SET(S) ->
Set3 :: a_set()).
union(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case unify_types(?TYPE(S1), ?TYPE(S2)) of
- [] -> erlang:error(type_mismatch, [S1, S2]);
+ [] -> erlang:error(type_mismatch);
Type -> ?SET(umerge(?LIST(S1), ?LIST(S2)), Type)
end.
@@ -420,7 +391,7 @@ union(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
Set3 :: a_set()).
intersection(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case unify_types(?TYPE(S1), ?TYPE(S2)) of
- [] -> erlang:error(type_mismatch, [S1, S2]);
+ [] -> erlang:error(type_mismatch);
Type -> ?SET(intersection(?LIST(S1), ?LIST(S2), []), Type)
end.
@@ -430,7 +401,7 @@ intersection(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
Set3 :: a_set()).
difference(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case unify_types(?TYPE(S1), ?TYPE(S2)) of
- [] -> erlang:error(type_mismatch, [S1, S2]);
+ [] -> erlang:error(type_mismatch);
Type -> ?SET(difference(?LIST(S1), ?LIST(S2), []), Type)
end.
@@ -440,7 +411,7 @@ difference(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
Set3 :: a_set()).
symdiff(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case unify_types(?TYPE(S1), ?TYPE(S2)) of
- [] -> erlang:error(type_mismatch, [S1, S2]);
+ [] -> erlang:error(type_mismatch);
Type -> ?SET(symdiff(?LIST(S1), ?LIST(S2), []), Type)
end.
@@ -452,7 +423,7 @@ symdiff(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
Set5 :: a_set()).
symmetric_partition(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case unify_types(?TYPE(S1), ?TYPE(S2)) of
- [] -> erlang:error(type_mismatch, [S1, S2]);
+ [] -> erlang:error(type_mismatch);
Type -> sympart(?LIST(S1), ?LIST(S2), [], [], [], Type)
end.
@@ -477,11 +448,9 @@ product({S1, S2}) ->
product(S1, S2);
product(T) when is_tuple(T) ->
Ss = tuple_to_list(T),
- case catch sets_to_list(Ss) of
- {'EXIT', _} ->
- erlang:error(badarg, [T]);
+ try sets_to_list(Ss) of
[] ->
- erlang:error(badarg, [T]);
+ erlang:error(badarg);
L ->
Type = types(Ss, []),
case member([], L) of
@@ -490,6 +459,7 @@ product(T) when is_tuple(T) ->
false ->
?SET(reverse(prod(L, [], [])), Type)
end
+ catch _:_ -> erlang:error(badarg)
end.
-spec(constant_function(Set, AnySet) -> Function when
@@ -502,10 +472,10 @@ constant_function(S, E) when ?IS_SET(S) ->
{Type, true} ->
NType = ?BINREL(Type, type(E)),
?SET(constant_function(?LIST(S), to_external(E), []), NType);
- _ -> erlang:error(badarg, [S, E])
+ _ -> erlang:error(badarg)
end;
-constant_function(S, E) when ?IS_ORDSET(S) ->
- erlang:error(badarg, [S, E]).
+constant_function(S, _) when ?IS_ORDSET(S) ->
+ erlang:error(badarg).
-spec(is_equal(AnySet1, AnySet2) -> Bool when
AnySet1 :: anyset(),
@@ -514,17 +484,17 @@ constant_function(S, E) when ?IS_ORDSET(S) ->
is_equal(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case match_types(?TYPE(S1), ?TYPE(S2)) of
true -> ?LIST(S1) == ?LIST(S2);
- false -> erlang:error(type_mismatch, [S1, S2])
+ false -> erlang:error(type_mismatch)
end;
is_equal(S1, S2) when ?IS_ORDSET(S1), ?IS_ORDSET(S2) ->
case match_types(?ORDTYPE(S1), ?ORDTYPE(S2)) of
true -> ?ORDDATA(S1) == ?ORDDATA(S2);
- false -> erlang:error(type_mismatch, [S1, S2])
+ false -> erlang:error(type_mismatch)
end;
is_equal(S1, S2) when ?IS_SET(S1), ?IS_ORDSET(S2) ->
- erlang:error(type_mismatch, [S1, S2]);
+ erlang:error(type_mismatch);
is_equal(S1, S2) when ?IS_ORDSET(S1), ?IS_SET(S2) ->
- erlang:error(type_mismatch, [S1, S2]).
+ erlang:error(type_mismatch).
-spec(is_subset(Set1, Set2) -> Bool when
Bool :: boolean(),
@@ -533,7 +503,7 @@ is_equal(S1, S2) when ?IS_ORDSET(S1), ?IS_SET(S2) ->
is_subset(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case match_types(?TYPE(S1), ?TYPE(S2)) of
true -> subset(?LIST(S1), ?LIST(S2));
- false -> erlang:error(type_mismatch, [S1, S2])
+ false -> erlang:error(type_mismatch)
end.
-spec(is_sofs_set(Term) -> Bool when
@@ -573,7 +543,7 @@ is_disjoint(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
[] -> true;
[A | As] -> disjoint(?LIST(S2), A, As)
end;
- false -> erlang:error(type_mismatch, [S1, S2])
+ false -> erlang:error(type_mismatch)
end.
%%%
@@ -587,7 +557,7 @@ union(Sets) when ?IS_SET(Sets) ->
case ?TYPE(Sets) of
?SET_OF(Type) -> ?SET(lunion(?LIST(Sets)), Type);
?ANYTYPE -> Sets;
- _ -> erlang:error(badarg, [Sets])
+ _ -> erlang:error(badarg)
end.
-spec(intersection(SetOfSets) -> Set when
@@ -595,12 +565,12 @@ union(Sets) when ?IS_SET(Sets) ->
SetOfSets :: set_of_sets()).
intersection(Sets) when ?IS_SET(Sets) ->
case ?LIST(Sets) of
- [] -> erlang:error(badarg, [Sets]);
+ [] -> erlang:error(badarg);
[L | Ls] ->
case ?TYPE(Sets) of
?SET_OF(Type) ->
?SET(lintersection(Ls, L), Type);
- _ -> erlang:error(badarg, [Sets])
+ _ -> erlang:error(badarg)
end
end.
@@ -614,7 +584,7 @@ canonical_relation(Sets) when ?IS_SET(Sets) ->
?SET_OF(Type) ->
?SET(can_rel(?LIST(Sets), []), ?BINREL(Type, ST));
?ANYTYPE -> Sets;
- _ -> erlang:error(badarg, [Sets])
+ _ -> erlang:error(badarg)
end.
%%%
@@ -636,7 +606,7 @@ relation_to_family(R) when ?IS_SET(R) ->
?BINREL(DT, RT) ->
?SET(rel2family(?LIST(R)), ?FAMILY(DT, RT));
?ANYTYPE -> R;
- _Else -> erlang:error(badarg, [R])
+ _Else -> erlang:error(badarg)
end.
-spec(domain(BinRel) -> Set when
@@ -646,7 +616,7 @@ domain(R) when ?IS_SET(R) ->
case ?TYPE(R) of
?BINREL(DT, _) -> ?SET(dom(?LIST(R)), DT);
?ANYTYPE -> R;
- _Else -> erlang:error(badarg, [R])
+ _Else -> erlang:error(badarg)
end.
-spec(range(BinRel) -> Set when
@@ -656,7 +626,7 @@ range(R) when ?IS_SET(R) ->
case ?TYPE(R) of
?BINREL(_, RT) -> ?SET(ran(?LIST(R), []), RT);
?ANYTYPE -> R;
- _ -> erlang:error(badarg, [R])
+ _ -> erlang:error(badarg)
end.
-spec(field(BinRel) -> Set when
@@ -679,7 +649,7 @@ relative_product(RT) when is_tuple(RT) ->
relative_product(RL) when is_list(RL) ->
case relprod_n(RL, foo, false, false) of
{error, Reason} ->
- erlang:error(Reason, [RL]);
+ erlang:error(Reason);
Reply ->
Reply
end.
@@ -703,11 +673,11 @@ relative_product(RL, R) when is_list(RL), ?IS_SET(R) ->
EmptyR = case ?TYPE(R) of
?BINREL(_, _) -> ?LIST(R) =:= [];
?ANYTYPE -> true;
- _ -> erlang:error(badarg, [RL, R])
+ _ -> erlang:error(badarg)
end,
case relprod_n(RL, R, EmptyR, true) of
{error, Reason} ->
- erlang:error(Reason, [RL, R]);
+ erlang:error(Reason);
Reply ->
Reply
end.
@@ -720,18 +690,18 @@ relative_product1(R1, R2) when ?IS_SET(R1), ?IS_SET(R2) ->
{DTR1, RTR1} = case ?TYPE(R1) of
?BINREL(_, _) = R1T -> R1T;
?ANYTYPE -> {?ANYTYPE, ?ANYTYPE};
- _ -> erlang:error(badarg, [R1, R2])
+ _ -> erlang:error(badarg)
end,
{DTR2, RTR2} = case ?TYPE(R2) of
?BINREL(_, _) = R2T -> R2T;
?ANYTYPE -> {?ANYTYPE, ?ANYTYPE};
- _ -> erlang:error(badarg, [R1, R2])
+ _ -> erlang:error(badarg)
end,
case match_types(DTR1, DTR2) of
true when DTR1 =:= ?ANYTYPE -> R1;
true when DTR2 =:= ?ANYTYPE -> R2;
true -> ?SET(relprod(?LIST(R1), ?LIST(R2)), ?BINREL(RTR1, RTR2));
- false -> erlang:error(type_mismatch, [R1, R2])
+ false -> erlang:error(type_mismatch)
end.
-spec(converse(BinRel1) -> BinRel2 when
@@ -741,7 +711,7 @@ converse(R) when ?IS_SET(R) ->
case ?TYPE(R) of
?BINREL(DT, RT) -> ?SET(converse(?LIST(R), []), ?BINREL(RT, DT));
?ANYTYPE -> R;
- _ -> erlang:error(badarg, [R])
+ _ -> erlang:error(badarg)
end.
-spec(image(BinRel, Set1) -> Set2 when
@@ -755,10 +725,10 @@ image(R, S) when ?IS_SET(R), ?IS_SET(S) ->
true ->
?SET(usort(restrict(?LIST(S), ?LIST(R))), RT);
false ->
- erlang:error(type_mismatch, [R, S])
+ erlang:error(type_mismatch)
end;
?ANYTYPE -> R;
- _ -> erlang:error(badarg, [R, S])
+ _ -> erlang:error(badarg)
end.
-spec(inverse_image(BinRel, Set1) -> Set2 when
@@ -773,10 +743,10 @@ inverse_image(R, S) when ?IS_SET(R), ?IS_SET(S) ->
NL = restrict(?LIST(S), converse(?LIST(R), [])),
?SET(usort(NL), DT);
false ->
- erlang:error(type_mismatch, [R, S])
+ erlang:error(type_mismatch)
end;
?ANYTYPE -> R;
- _ -> erlang:error(badarg, [R, S])
+ _ -> erlang:error(badarg)
end.
-spec(strict_relation(BinRel1) -> BinRel2 when
@@ -787,7 +757,7 @@ strict_relation(R) when ?IS_SET(R) ->
Type = ?BINREL(_, _) ->
?SET(strict(?LIST(R), []), Type);
?ANYTYPE -> R;
- _ -> erlang:error(badarg, [R])
+ _ -> erlang:error(badarg)
end.
-spec(weak_relation(BinRel1) -> BinRel2 when
@@ -798,12 +768,12 @@ weak_relation(R) when ?IS_SET(R) ->
?BINREL(DT, RT) ->
case unify_types(DT, RT) of
[] ->
- erlang:error(badarg, [R]);
+ erlang:error(badarg);
Type ->
?SET(weak(?LIST(R)), ?BINREL(Type, Type))
end;
?ANYTYPE -> R;
- _ -> erlang:error(badarg, [R])
+ _ -> erlang:error(badarg)
end.
-spec(extension(BinRel1, Set, AnySet) -> BinRel2 when
@@ -816,7 +786,7 @@ extension(R, S, E) when ?IS_SET(R), ?IS_SET(S) ->
{T=?BINREL(DT, RT), ST, true} ->
case match_types(DT, ST) and match_types(RT, type(E)) of
false ->
- erlang:error(type_mismatch, [R, S, E]);
+ erlang:error(type_mismatch);
true ->
RL = ?LIST(R),
case extc([], ?LIST(S), to_external(E), RL) of
@@ -836,7 +806,7 @@ extension(R, S, E) when ?IS_SET(R), ?IS_SET(S) ->
?SET([], ?BINREL(ST, ET))
end;
{_, _, true} ->
- erlang:error(badarg, [R, S, E])
+ erlang:error(badarg)
end.
-spec(is_a_function(BinRel) -> Bool when
@@ -850,7 +820,7 @@ is_a_function(R) when ?IS_SET(R) ->
[{V,_} | Es] -> is_a_func(Es, V)
end;
?ANYTYPE -> true;
- _ -> erlang:error(badarg, [R])
+ _ -> erlang:error(badarg)
end.
-spec(restriction(BinRel1, Set) -> BinRel2 when
@@ -879,12 +849,12 @@ composite(Fn1, Fn2) when ?IS_SET(Fn1), ?IS_SET(Fn2) ->
?BINREL(DTF1, RTF1) = case ?TYPE(Fn1)of
?BINREL(_, _) = F1T -> F1T;
?ANYTYPE -> {?ANYTYPE, ?ANYTYPE};
- _ -> erlang:error(badarg, [Fn1, Fn2])
+ _ -> erlang:error(badarg)
end,
?BINREL(DTF2, RTF2) = case ?TYPE(Fn2) of
?BINREL(_, _) = F2T -> F2T;
?ANYTYPE -> {?ANYTYPE, ?ANYTYPE};
- _ -> erlang:error(badarg, [Fn1, Fn2])
+ _ -> erlang:error(badarg)
end,
case match_types(RTF1, DTF2) of
true when DTF1 =:= ?ANYTYPE -> Fn1;
@@ -894,9 +864,9 @@ composite(Fn1, Fn2) when ?IS_SET(Fn1), ?IS_SET(Fn2) ->
SL when is_list(SL) ->
?SET(sort(SL), ?BINREL(DTF1, RTF2));
Bad ->
- erlang:error(Bad, [Fn1, Fn2])
+ erlang:error(Bad)
end;
- false -> erlang:error(type_mismatch, [Fn1, Fn2])
+ false -> erlang:error(type_mismatch)
end.
-spec(inverse(Function1) -> Function2 when
@@ -909,10 +879,10 @@ inverse(Fn) when ?IS_SET(Fn) ->
SL when is_list(SL) ->
?SET(SL, ?BINREL(RT, DT));
Bad ->
- erlang:error(Bad, [Fn])
+ erlang:error(Bad)
end;
?ANYTYPE -> Fn;
- _ -> erlang:error(badarg, [Fn])
+ _ -> erlang:error(badarg)
end.
%%%
@@ -932,7 +902,7 @@ restriction(I, R, S) when is_integer(I), ?IS_SET(R), ?IS_SET(S) ->
empty ->
R;
error ->
- erlang:error(badarg, [I, R, S]);
+ erlang:error(badarg);
Sort ->
RL = ?LIST(R),
case {match_types(?REL_TYPE(I, RT), ST), ?LIST(S)} of
@@ -945,7 +915,7 @@ restriction(I, R, S) when is_integer(I), ?IS_SET(R), ?IS_SET(S) ->
{true, [E | Es]} ->
?SET(sort(restrict_n(I, keysort(I, RL), E, Es, [])), RT);
{false, _SL} ->
- erlang:error(type_mismatch, [I, R, S])
+ erlang:error(type_mismatch)
end
end;
restriction(SetFun, S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
@@ -963,28 +933,27 @@ restriction(SetFun, S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
NL = sort(restrict(?LIST(S2), converse(NSL, []))),
?SET(NL, Type1);
false ->
- erlang:error(type_mismatch, [SetFun, S1, S2])
+ erlang:error(type_mismatch)
end;
Bad ->
- erlang:error(Bad, [SetFun, S1, S2])
+ erlang:error(Bad)
end;
_ when Type1 =:= ?ANYTYPE ->
S1;
_XFun when ?IS_SET_OF(Type1) ->
- erlang:error(badarg, [SetFun, S1, S2]);
+ erlang:error(badarg);
XFun ->
FunT = XFun(Type1),
- case catch check_fun(Type1, XFun, FunT) of
- {'EXIT', _} ->
- erlang:error(badarg, [SetFun, S1, S2]);
+ try check_fun(Type1, XFun, FunT) of
Sort ->
case match_types(FunT, Type2) of
true ->
R1 = inverse_substitution(SL1, XFun, Sort),
?SET(sort(Sort, restrict(?LIST(S2), R1)), Type1);
false ->
- erlang:error(type_mismatch, [SetFun, S1, S2])
+ erlang:error(type_mismatch)
end
+ catch _:_ -> erlang:error(badarg)
end
end.
@@ -1000,7 +969,7 @@ drestriction(I, R, S) when is_integer(I), ?IS_SET(R), ?IS_SET(S) ->
empty ->
R;
error ->
- erlang:error(badarg, [I, R, S]);
+ erlang:error(badarg);
Sort ->
RL = ?LIST(R),
case {match_types(?REL_TYPE(I, RT), ST), ?LIST(S)} of
@@ -1013,7 +982,7 @@ drestriction(I, R, S) when is_integer(I), ?IS_SET(R), ?IS_SET(S) ->
{true, [E | Es]} ->
?SET(diff_restrict_n(I, keysort(I, RL), E, Es, []), RT);
{false, _SL} ->
- erlang:error(type_mismatch, [I, R, S])
+ erlang:error(type_mismatch)
end
end;
drestriction(SetFun, S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
@@ -1032,20 +1001,18 @@ drestriction(SetFun, S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
NL = sort(diff_restrict(SL2, converse(NSL, []))),
?SET(NL, Type1);
false ->
- erlang:error(type_mismatch, [SetFun, S1, S2])
+ erlang:error(type_mismatch)
end;
Bad ->
- erlang:error(Bad, [SetFun, S1, S2])
+ erlang:error(Bad)
end;
_ when Type1 =:= ?ANYTYPE ->
S1;
_XFun when ?IS_SET_OF(Type1) ->
- erlang:error(badarg, [SetFun, S1, S2]);
+ erlang:error(badarg);
XFun ->
FunT = XFun(Type1),
- case catch check_fun(Type1, XFun, FunT) of
- {'EXIT', _} ->
- erlang:error(badarg, [SetFun, S1, S2]);
+ try check_fun(Type1, XFun, FunT) of
Sort ->
case match_types(FunT, Type2) of
true ->
@@ -1053,8 +1020,9 @@ drestriction(SetFun, S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
SL2 = ?LIST(S2),
?SET(sort(Sort, diff_restrict(SL2, R1)), Type1);
false ->
- erlang:error(type_mismatch, [SetFun, S1, S2])
+ erlang:error(type_mismatch)
end
+ catch _:_ -> erlang:error(badarg)
end
end.
@@ -1068,7 +1036,7 @@ projection(I, Set) when is_integer(I), ?IS_SET(Set) ->
empty ->
Set;
error ->
- erlang:error(badarg, [I, Set]);
+ erlang:error(badarg);
_ when I =:= 1 ->
?SET(projection1(?LIST(Set)), ?REL_TYPE(I, Type));
_ ->
@@ -1087,7 +1055,7 @@ substitution(I, Set) when is_integer(I), ?IS_SET(Set) ->
empty ->
Set;
error ->
- erlang:error(badarg, [I, Set]);
+ erlang:error(badarg);
_Sort ->
NType = ?REL_TYPE(I, Type),
NSL = substitute_element(?LIST(Set), I, []),
@@ -1102,22 +1070,21 @@ substitution(SetFun, Set) when ?IS_SET(Set) ->
{SL, NewType} ->
?SET(reverse(SL), ?BINREL(Type, NewType));
Bad ->
- erlang:error(Bad, [SetFun, Set])
+ erlang:error(Bad)
end;
false ->
empty_set();
_ when Type =:= ?ANYTYPE ->
empty_set();
_XFun when ?IS_SET_OF(Type) ->
- erlang:error(badarg, [SetFun, Set]);
+ erlang:error(badarg);
XFun ->
FunT = XFun(Type),
- case catch check_fun(Type, XFun, FunT) of
- {'EXIT', _} ->
- erlang:error(badarg, [SetFun, Set]);
+ try check_fun(Type, XFun, FunT) of
_Sort ->
SL = substitute(L, XFun, []),
?SET(SL, ?BINREL(Type, FunT))
+ catch _:_ -> erlang:error(badarg)
end
end.
@@ -1139,7 +1106,7 @@ partition(I, Set) when is_integer(I), ?IS_SET(Set) ->
empty ->
Set;
error ->
- erlang:error(badarg, [I, Set]);
+ erlang:error(badarg);
false -> % I =:= 1
?SET(partition_n(I, ?LIST(Set)), ?SET_OF(Type));
true ->
@@ -1161,7 +1128,7 @@ partition(I, R, S) when is_integer(I), ?IS_SET(R), ?IS_SET(S) ->
empty ->
{R, R};
error ->
- erlang:error(badarg, [I, R, S]);
+ erlang:error(badarg);
Sort ->
RL = ?LIST(R),
case {match_types(?REL_TYPE(I, RT), ST), ?LIST(S)} of
@@ -1176,7 +1143,7 @@ partition(I, R, S) when is_integer(I), ?IS_SET(R), ?IS_SET(S) ->
[L1 | L2] = partition3_n(I, keysort(I,RL), E, Es, [], []),
{?SET(L1, RT), ?SET(L2, RT)};
{false, _SL} ->
- erlang:error(type_mismatch, [I, R, S])
+ erlang:error(type_mismatch)
end
end;
partition(SetFun, S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
@@ -1195,20 +1162,18 @@ partition(SetFun, S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
[L1 | L2] = partition3(?LIST(S2), R1),
{?SET(sort(L1), Type1), ?SET(sort(L2), Type1)};
false ->
- erlang:error(type_mismatch, [SetFun, S1, S2])
+ erlang:error(type_mismatch)
end;
Bad ->
- erlang:error(Bad, [SetFun, S1, S2])
+ erlang:error(Bad)
end;
_ when Type1 =:= ?ANYTYPE ->
{S1, S1};
_XFun when ?IS_SET_OF(Type1) ->
- erlang:error(badarg, [SetFun, S1, S2]);
+ erlang:error(badarg);
XFun ->
FunT = XFun(Type1),
- case catch check_fun(Type1, XFun, FunT) of
- {'EXIT', _} ->
- erlang:error(badarg, [SetFun, S1, S2]);
+ try check_fun(Type1, XFun, FunT) of
Sort ->
case match_types(FunT, Type2) of
true ->
@@ -1216,8 +1181,9 @@ partition(SetFun, S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
[L1 | L2] = partition3(?LIST(S2), R1),
{?SET(sort(L1), Type1), ?SET(sort(L2), Type1)};
false ->
- erlang:error(type_mismatch, [SetFun, S1, S2])
+ erlang:error(type_mismatch)
end
+ catch _:_ -> erlang:error(badarg)
end
end.
@@ -1234,7 +1200,7 @@ multiple_relative_product(T, R) when is_tuple(T), ?IS_SET(R) ->
MProd = mul_relprod(tuple_to_list(T), 1, R),
relative_product(MProd);
false ->
- erlang:error(badarg, [T, R])
+ erlang:error(badarg)
end.
-spec(join(Relation1, I, Relation2, J) -> Relation3 when
@@ -1246,8 +1212,7 @@ multiple_relative_product(T, R) when is_tuple(T), ?IS_SET(R) ->
join(R1, I1, R2, I2)
when ?IS_SET(R1), ?IS_SET(R2), is_integer(I1), is_integer(I2) ->
case test_rel(R1, I1, lte) and test_rel(R2, I2, lte) of
- false ->
- erlang:error(badarg, [R1, I1, R2, I2]);
+ false -> erlang:error(badarg);
true when ?TYPE(R1) =:= ?ANYTYPE -> R1;
true when ?TYPE(R2) =:= ?ANYTYPE -> R2;
true ->
@@ -1294,7 +1259,7 @@ family_to_relation(F) when ?IS_SET(F) ->
?FAMILY(DT, RT) ->
?SET(family2rel(?LIST(F), []), ?BINREL(DT, RT));
?ANYTYPE -> F;
- _ -> erlang:error(badarg, [F])
+ _ -> erlang:error(badarg)
end.
-spec(family_specification(Fun, Family1) -> Family2 when
@@ -1314,10 +1279,10 @@ family_specification(Fun, F) when ?IS_SET(F) ->
SL when is_list(SL) ->
?SET(SL, FType);
Bad ->
- erlang:error(Bad, [Fun, F])
+ erlang:error(Bad)
end;
?ANYTYPE -> F;
- _ -> erlang:error(badarg, [Fun, F])
+ _ -> erlang:error(badarg)
end.
-spec(union_of_family(Family) -> Set when
@@ -1328,7 +1293,7 @@ union_of_family(F) when ?IS_SET(F) ->
?FAMILY(_DT, Type) ->
?SET(un_of_fam(?LIST(F), []), Type);
?ANYTYPE -> F;
- _ -> erlang:error(badarg, [F])
+ _ -> erlang:error(badarg)
end.
-spec(intersection_of_family(Family) -> Set when
@@ -1341,9 +1306,9 @@ intersection_of_family(F) when ?IS_SET(F) ->
FU when is_list(FU) ->
?SET(FU, Type);
Bad ->
- erlang:error(Bad, [F])
+ erlang:error(Bad)
end;
- _ -> erlang:error(badarg, [F])
+ _ -> erlang:error(badarg)
end.
-spec(family_union(Family1) -> Family2 when
@@ -1354,7 +1319,7 @@ family_union(F) when ?IS_SET(F) ->
?FAMILY(DT, ?SET_OF(Type)) ->
?SET(fam_un(?LIST(F), []), ?FAMILY(DT, Type));
?ANYTYPE -> F;
- _ -> erlang:error(badarg, [F])
+ _ -> erlang:error(badarg)
end.
-spec(family_intersection(Family1) -> Family2 when
@@ -1367,10 +1332,10 @@ family_intersection(F) when ?IS_SET(F) ->
FU when is_list(FU) ->
?SET(FU, ?FAMILY(DT, Type));
Bad ->
- erlang:error(Bad, [F])
+ erlang:error(Bad)
end;
?ANYTYPE -> F;
- _ -> erlang:error(badarg, [F])
+ _ -> erlang:error(badarg)
end.
-spec(family_domain(Family1) -> Family2 when
@@ -1382,7 +1347,7 @@ family_domain(F) when ?IS_SET(F) ->
?SET(fam_dom(?LIST(F), []), ?FAMILY(FDT, DT));
?ANYTYPE -> F;
?FAMILY(_, ?ANYTYPE) -> F;
- _ -> erlang:error(badarg, [F])
+ _ -> erlang:error(badarg)
end.
-spec(family_range(Family1) -> Family2 when
@@ -1394,7 +1359,7 @@ family_range(F) when ?IS_SET(F) ->
?SET(fam_ran(?LIST(F), []), ?FAMILY(DT, RT));
?ANYTYPE -> F;
?FAMILY(_, ?ANYTYPE) -> F;
- _ -> erlang:error(badarg, [F])
+ _ -> erlang:error(badarg)
end.
-spec(family_field(Family1) -> Family2 when
@@ -1428,12 +1393,12 @@ family_difference(F1, F2) ->
fam_binop(F1, F2, FF) when ?IS_SET(F1), ?IS_SET(F2) ->
case unify_types(?TYPE(F1), ?TYPE(F2)) of
[] ->
- erlang:error(type_mismatch, [F1, F2]);
+ erlang:error(type_mismatch);
?ANYTYPE ->
F1;
Type = ?FAMILY(_, _) ->
?SET(FF(?LIST(F1), ?LIST(F2), []), Type);
- _ -> erlang:error(badarg, [F1, F2])
+ _ -> erlang:error(badarg)
end.
-spec(partition_family(SetFun, Set) -> Family when
@@ -1446,7 +1411,7 @@ partition_family(I, Set) when is_integer(I), ?IS_SET(Set) ->
empty ->
Set;
error ->
- erlang:error(badarg, [I, Set]);
+ erlang:error(badarg);
false -> % when I =:= 1
?SET(fam_partition_n(I, ?LIST(Set)),
?BINREL(?REL_TYPE(I, Type), ?SET_OF(Type)));
@@ -1464,23 +1429,22 @@ partition_family(SetFun, Set) when ?IS_SET(Set) ->
P = fam_partition(converse(NSL, []), true),
?SET(reverse(P), ?BINREL(NewType, ?SET_OF(Type)));
Bad ->
- erlang:error(Bad, [SetFun, Set])
+ erlang:error(Bad)
end;
false ->
empty_set();
_ when Type =:= ?ANYTYPE ->
empty_set();
_XFun when ?IS_SET_OF(Type) ->
- erlang:error(badarg, [SetFun, Set]);
+ erlang:error(badarg);
XFun ->
DType = XFun(Type),
- case catch check_fun(Type, XFun, DType) of
- {'EXIT', _} ->
- erlang:error(badarg, [SetFun, Set]);
+ try check_fun(Type, XFun, DType) of
Sort ->
Ts = inverse_substitution(?LIST(Set), XFun, Sort),
P = fam_partition(Ts, Sort),
?SET(reverse(P), ?BINREL(DType, ?SET_OF(Type)))
+ catch _:_ -> erlang:error(badarg)
end
end.
@@ -1499,13 +1463,13 @@ family_projection(SetFun, F) when ?IS_SET(F) ->
{SL, NewType} ->
?SET(SL, ?BINREL(DT, NewType));
Bad ->
- erlang:error(Bad, [SetFun, F])
+ erlang:error(Bad)
end;
_ ->
- erlang:error(badarg, [SetFun, F])
+ erlang:error(badarg)
end;
?ANYTYPE -> F;
- _ -> erlang:error(badarg, [SetFun, F])
+ _ -> erlang:error(badarg)
end.
%%%
@@ -1519,7 +1483,7 @@ family_to_digraph(F) when ?IS_SET(F) ->
case ?TYPE(F) of
?FAMILY(_, _) -> fam2digraph(F, digraph:new());
?ANYTYPE -> digraph:new();
- _Else -> erlang:error(badarg, [F])
+ _Else -> erlang:error(badarg)
end.
-spec(family_to_digraph(Family, GraphType) -> Graph when
@@ -1530,27 +1494,27 @@ family_to_digraph(F, Type) when ?IS_SET(F) ->
case ?TYPE(F) of
?FAMILY(_, _) -> ok;
?ANYTYPE -> ok;
- _Else -> erlang:error(badarg, [F, Type])
+ _Else -> erlang:error(badarg)
end,
try digraph:new(Type) of
G -> case catch fam2digraph(F, G) of
{error, Reason} ->
true = digraph:delete(G),
- erlang:error(Reason, [F, Type]);
+ erlang:error(Reason);
_ ->
G
end
catch
- error:badarg -> erlang:error(badarg, [F, Type])
+ error:badarg -> erlang:error(badarg)
end.
-spec(digraph_to_family(Graph) -> Family when
Graph :: digraph:graph(),
Family :: family()).
digraph_to_family(G) ->
- case catch digraph_family(G) of
- {'EXIT', _} -> erlang:error(badarg, [G]);
+ try digraph_family(G) of
L -> ?SET(L, ?FAMILY(?ATOM_TYPE, ?ATOM_TYPE))
+ catch _:_ -> erlang:error(badarg)
end.
-spec(digraph_to_family(Graph, Type) -> Family when
@@ -1560,12 +1524,12 @@ digraph_to_family(G) ->
digraph_to_family(G, T) ->
case {is_type(T), T} of
{true, ?SET_OF(?FAMILY(_,_) = Type)} ->
- case catch digraph_family(G) of
- {'EXIT', _} -> erlang:error(badarg, [G, T]);
+ try digraph_family(G) of
L -> ?SET(L, Type)
+ catch _:_ -> erlang:error(badarg)
end;
_ ->
- erlang:error(badarg, [G, T])
+ erlang:error(badarg)
end.
%%
@@ -1713,14 +1677,15 @@ func_type([], SL, Type, F) ->
setify(L, ?SET_OF(Atom)) when ?IS_ATOM_TYPE(Atom), Atom =/= ?ANYTYPE ->
?SET(usort(L), Atom);
setify(L, ?SET_OF(Type0)) ->
- case catch is_no_lists(Type0) of
- {'EXIT', _} ->
- {?SET_OF(Type), Set} = create(L, Type0, Type0, []),
- ?SET(Set, Type);
+ try is_no_lists(Type0) of
N when is_integer(N) ->
- rel(L, N, Type0);
+ rel(L, N, Type0);
Sizes ->
make_oset(L, Sizes, L, Type0)
+ catch
+ _:_ ->
+ {?SET_OF(Type), Set} = create(L, Type0, Type0, []),
+ ?SET(Set, Type)
end;
setify(E, Type0) ->
{Type, OrdSet} = make_element(E, Type0, Type0),
diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src
index 09176d2ca0..3c449d3cb9 100644
--- a/lib/stdlib/src/stdlib.app.src
+++ b/lib/stdlib/src/stdlib.app.src
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -31,7 +31,6 @@
dets_server,
dets_sup,
dets_utils,
- dets_v8,
dets_v9,
dict,
digraph,
@@ -40,6 +39,7 @@
edlin_expand,
epp,
eval_bits,
+ erl_abstract_code,
erl_anno,
erl_bits,
erl_compile,
@@ -100,13 +100,14 @@
sys,
timer,
unicode,
+ unicode_util,
win32reg,
zip]},
{registered,[timer_server,rsh_starter,take_over_monitor,pool_master,
dets]},
{applications, [kernel]},
{env, []},
- {runtime_dependencies, ["sasl-3.0","kernel-5.0","erts-8.0","crypto-3.3",
+ {runtime_dependencies, ["sasl-3.0","kernel-5.0","erts-9.0","crypto-3.3",
"compiler-5.0"]}
]}.
diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src
index 9877662743..3100504a80 100644
--- a/lib/stdlib/src/stdlib.appup.src
+++ b/lib/stdlib/src/stdlib.appup.src
@@ -1,7 +1,7 @@
%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,9 +18,7 @@
%% %CopyrightEnd%
{"%VSN%",
%% Up from - max one major revision back
- [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-18.*
+ [{<<"3\\.[0-3](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-19.*
%% Down to - max one major revision back
- [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-18.*
+ [{<<"3\\.[0-3](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-19.*
}.
diff --git a/lib/stdlib/src/string.erl b/lib/stdlib/src/string.erl
index c659db78bd..6f7009b5d9 100644
--- a/lib/stdlib/src/string.erl
+++ b/lib/stdlib/src/string.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -17,43 +17,1324 @@
%%
%% %CopyrightEnd%
%%
+%% A string library that works on grapheme clusters, with the exception
+%% of codepoints of class 'prepend' and non modern (or decomposed) Hangul.
+%% If these codepoints appear, functions like 'find/2' may return a string
+%% which starts inside a grapheme cluster.
+%% These exceptions are made because the codepoints classes are
+%% seldom used and require that we are able look at previous codepoints in
+%% the stream and is thus hard to implement effectively.
+%%
+%% GC (grapheme cluster) implies that the length of string 'ß↑e̊' is 3 though
+%% it is represented by the codepoints [223,8593,101,778] or the
+%% utf8 binary <<195,159,226,134,145,101,204,138>>
+%%
+%% And that searching for strings or graphemes finds the correct positions:
+%%
+%% find("eeeee̊eee", "e̊") -> "e̊ee".:
+%% find("1£4e̊abcdef", "e") -> "ef"
+%%
+%% Most functions expect all input to be normalized to one form,
+%% see unicode:characters_to_nfc and unicode:characters_to_nfd functions.
+%% When appending strings no checking is done to verify that the
+%% result is valid unicode strings.
+%%
+%% The functions may crash for invalid utf-8 input.
+%%
+%% Return value should be kept consistent when return type is
+%% unicode:chardata() i.e. binary input => binary output,
+%% list input => list output mixed input => mixed output
+%%
-module(string).
--export([len/1,equal/2,concat/2,chr/2,rchr/2,str/2,rstr/2,
- span/2,cspan/2,substr/2,substr/3,tokens/2,chars/2,chars/3]).
+-export([is_empty/1, length/1, to_graphemes/1,
+ reverse/1,
+ equal/2, equal/3, equal/4,
+ slice/2, slice/3,
+ pad/2, pad/3, pad/4, trim/1, trim/2, trim/3, chomp/1,
+ take/2, take/3, take/4,
+ lexemes/2, nth_lexeme/3,
+ uppercase/1, lowercase/1, titlecase/1,casefold/1,
+ prefix/2,
+ split/2,split/3,replace/3,replace/4,
+ find/2,find/3,
+ next_codepoint/1, next_grapheme/1
+ ]).
+
+-export([to_float/1, to_integer/1]).
+
+%% Old (will be deprecated) lists/string API kept for backwards compability
+-export([len/1, concat/2, % equal/2, (extended in the new api)
+ chr/2,rchr/2,str/2,rstr/2,
+ span/2,cspan/2,substr/2,substr/3, tokens/2,
+ chars/2,chars/3]).
-export([copies/2,words/1,words/2,strip/1,strip/2,strip/3,
sub_word/2,sub_word/3,left/2,left/3,right/2,right/3,
sub_string/2,sub_string/3,centre/2,centre/3, join/2]).
-export([to_upper/1, to_lower/1]).
+%%
+-import(lists,[member/2]).
--import(lists,[reverse/1,member/2]).
+-compile({no_auto_import,[length/1]}).
-%%---------------------------------------------------------------------------
+-export_type([grapheme_cluster/0]).
-%%% BIFs
+-type grapheme_cluster() :: char() | [char()].
+-type direction() :: 'leading' | 'trailing'.
--export([to_float/1, to_integer/1]).
+-dialyzer({no_improper_lists, stack/2}).
+%%% BIFs internal (not documented) should not to be used outside of this module
+%%% May be removed
+-export([list_to_float/1, list_to_integer/1]).
--spec to_float(String) -> {Float, Rest} | {error, Reason} when
+%% Uses bifs: string:list_to_float/1 and string:list_to_integer/1
+-spec list_to_float(String) -> {Float, Rest} | {'error', Reason} when
String :: string(),
Float :: float(),
Rest :: string(),
- Reason :: no_float | not_a_list.
+ Reason :: 'no_float' | 'not_a_list'.
-to_float(_) ->
+list_to_float(_) ->
erlang:nif_error(undef).
--spec to_integer(String) -> {Int, Rest} | {error, Reason} when
+-spec list_to_integer(String) -> {Int, Rest} | {'error', Reason} when
String :: string(),
Int :: integer(),
Rest :: string(),
- Reason :: no_integer | not_a_list.
+ Reason :: 'no_integer' | 'not_a_list'.
-to_integer(_) ->
+list_to_integer(_) ->
erlang:nif_error(undef).
%%% End of BIFs
+%% Check if string is the empty string
+-spec is_empty(String::unicode:chardata()) -> boolean().
+is_empty([]) -> true;
+is_empty(<<>>) -> true;
+is_empty([L|R]) -> is_empty(L) andalso is_empty(R);
+is_empty(_) -> false.
+
+%% Count the number of grapheme clusters in chardata
+-spec length(String::unicode:chardata()) -> non_neg_integer().
+length(CD) ->
+ length_1(unicode_util:gc(CD), 0).
+
+%% Convert a string to a list of grapheme clusters
+-spec to_graphemes(String::unicode:chardata()) -> [grapheme_cluster()].
+to_graphemes(CD0) ->
+ case unicode_util:gc(CD0) of
+ [GC|CD] -> [GC|to_graphemes(CD)];
+ [] -> []
+ end.
+
+%% Compare two strings return boolean, assumes that the input are
+%% normalized to same form, see unicode:characters_to_nfX_xxx(..)
+-spec equal(A, B) -> boolean() when
+ A::unicode:chardata(),
+ B::unicode:chardata().
+equal(A,B) when is_binary(A), is_binary(B) ->
+ A =:= B;
+equal(A,B) ->
+ equal_1(A,B).
+
+%% Compare two strings return boolean, assumes that the input are
+%% normalized to same form, see unicode:characters_to_nfX_xxx(..)
+%% does casefold on the fly
+-spec equal(A, B, IgnoreCase) -> boolean() when
+ A::unicode:chardata(),
+ B::unicode:chardata(),
+ IgnoreCase :: boolean().
+equal(A, B, false) ->
+ equal(A,B);
+equal(A, B, true) ->
+ equal_nocase(A,B).
+
+%% Compare two strings return boolean
+%% if specified does casefold and normalization on the fly
+-spec equal(A, B, IgnoreCase, Norm) -> boolean() when
+ A :: unicode:chardata(),
+ B :: unicode:chardata(),
+ IgnoreCase :: boolean(),
+ Norm :: 'none' | 'nfc' | 'nfd' | 'nfkc' | 'nfkd'.
+equal(A, B, Case, none) ->
+ equal(A,B,Case);
+equal(A, B, false, Norm) ->
+ equal_norm(A, B, Norm);
+equal(A, B, true, Norm) ->
+ equal_norm_nocase(A, B, Norm).
+
+%% Reverse grapheme clusters
+-spec reverse(String::unicode:chardata()) -> [grapheme_cluster()].
+reverse(CD) ->
+ reverse_1(CD, []).
+
+%% Slice a string and return rest of string
+%% Note: counts grapheme_clusters
+-spec slice(String, Start) -> Slice when
+ String::unicode:chardata(),
+ Start :: non_neg_integer(),
+ Slice :: unicode:chardata().
+slice(CD, N) when is_integer(N), N >= 0 ->
+ slice_l(CD, N, is_binary(CD)).
+
+-spec slice(String, Start, Length) -> Slice when
+ String::unicode:chardata(),
+ Start :: non_neg_integer(),
+ Length :: 'infinity' | non_neg_integer(),
+ Slice :: unicode:chardata().
+slice(CD, N, Length)
+ when is_integer(N), N >= 0, is_integer(Length), Length > 0 ->
+ slice_trail(slice_l(CD, N, is_binary(CD)), Length);
+slice(CD, N, infinity) ->
+ slice_l(CD, N, is_binary(CD));
+slice(CD, _, 0) ->
+ case is_binary(CD) of
+ true -> <<>>;
+ false -> []
+ end.
+
+%% Pad a string to desired length
+-spec pad(String, Length) -> unicode:charlist() when
+ String ::unicode:chardata(),
+ Length :: integer().
+pad(CD, Length) ->
+ pad(CD, Length, trailing, $\s).
+
+-spec pad(String, Length, Dir) -> unicode:charlist() when
+ String ::unicode:chardata(),
+ Length :: integer(),
+ Dir :: direction() | 'both'.
+pad(CD, Length, Dir) ->
+ pad(CD, Length, Dir, $\s).
+
+-spec pad(String, Length, Dir, Char) -> unicode:charlist() when
+ String ::unicode:chardata(),
+ Length :: integer(),
+ Dir :: direction() | 'both',
+ Char :: grapheme_cluster().
+pad(CD, Length, leading, Char) when is_integer(Length) ->
+ Len = length(CD),
+ [lists:duplicate(max(0, Length-Len), Char), CD];
+pad(CD, Length, trailing, Char) when is_integer(Length) ->
+ Len = length(CD),
+ [CD|lists:duplicate(max(0, Length-Len), Char)];
+pad(CD, Length, both, Char) when is_integer(Length) ->
+ Len = length(CD),
+ Size = max(0, Length-Len),
+ Pre = lists:duplicate(Size div 2, Char),
+ Post = case Size rem 2 of
+ 1 -> [Char];
+ _ -> []
+ end,
+ [Pre, CD, Pre|Post].
+
+%% Strip characters from whitespace or Separator in Direction
+-spec trim(String) -> unicode:chardata() when
+ String :: unicode:chardata().
+trim(Str) ->
+ trim(Str, both, unicode_util:whitespace()).
+
+-spec trim(String, Dir) -> unicode:chardata() when
+ String :: unicode:chardata(),
+ Dir :: direction() | 'both'.
+trim(Str, Dir) ->
+ trim(Str, Dir, unicode_util:whitespace()).
+
+-spec trim(String, Dir, Characters) -> unicode:chardata() when
+ String :: unicode:chardata(),
+ Dir :: direction() | 'both',
+ Characters :: [grapheme_cluster()].
+trim(Str, _, []) -> Str;
+trim(Str, leading, Sep) when is_list(Sep) ->
+ trim_l(Str, search_pattern(Sep));
+trim(Str, trailing, Sep) when is_list(Sep) ->
+ trim_t(Str, 0, search_pattern(Sep));
+trim(Str, both, Sep0) when is_list(Sep0) ->
+ Sep = search_pattern(Sep0),
+ trim_t(trim_l(Str,Sep), 0, Sep).
+
+%% Delete trailing newlines or \r\n
+-spec chomp(String::unicode:chardata()) -> unicode:chardata().
+chomp(Str) ->
+ trim_t(Str,0, {[[$\r,$\n],$\n], [$\r,$\n], [<<$\r>>,<<$\n>>]}).
+
+%% Split String into two parts where the leading part consists of Characters
+-spec take(String, Characters) -> {Leading, Trailing} when
+ String::unicode:chardata(),
+ Characters::[grapheme_cluster()],
+ Leading::unicode:chardata(),
+ Trailing::unicode:chardata().
+take(Str, Sep) ->
+ take(Str, Sep, false, leading).
+-spec take(String, Characters, Complement) -> {Leading, Trailing} when
+ String::unicode:chardata(),
+ Characters::[grapheme_cluster()],
+ Complement::boolean(),
+ Leading::unicode:chardata(),
+ Trailing::unicode:chardata().
+take(Str, Sep, Complement) ->
+ take(Str, Sep, Complement, leading).
+-spec take(String, Characters, Complement, Dir) -> {Leading, Trailing} when
+ String::unicode:chardata(),
+ Characters::[grapheme_cluster()],
+ Complement::boolean(),
+ Dir::direction(),
+ Leading::unicode:chardata(),
+ Trailing::unicode:chardata().
+take(Str, [], Complement, Dir) ->
+ Empty = case is_binary(Str) of true -> <<>>; false -> [] end,
+ case {Complement,Dir} of
+ {false, leading} -> {Empty, Str};
+ {false, trailing} -> {Str, Empty};
+ {true, leading} -> {Str, Empty};
+ {true, trailing} -> {Empty, Str}
+ end;
+take(Str, Sep0, false, leading) ->
+ Sep = search_pattern(Sep0),
+ take_l(Str, Sep, []);
+take(Str, Sep0, true, leading) ->
+ Sep = search_pattern(Sep0),
+ take_lc(Str, Sep, []);
+take(Str, Sep0, false, trailing) ->
+ Sep = search_pattern(Sep0),
+ take_t(Str, 0, Sep);
+take(Str, Sep0, true, trailing) ->
+ Sep = search_pattern(Sep0),
+ take_tc(Str, 0, Sep).
+
+%% Uppercase all chars in Str
+-spec uppercase(String::unicode:chardata()) -> unicode:chardata().
+uppercase(CD) when is_list(CD) ->
+ uppercase_list(CD);
+uppercase(CD) when is_binary(CD) ->
+ uppercase_bin(CD,<<>>).
+
+%% Lowercase all chars in Str
+-spec lowercase(String::unicode:chardata()) -> unicode:chardata().
+lowercase(CD) when is_list(CD) ->
+ lowercase_list(CD);
+lowercase(CD) when is_binary(CD) ->
+ lowercase_bin(CD,<<>>).
+
+%% Make a titlecase of the first char in Str
+-spec titlecase(String::unicode:chardata()) -> unicode:chardata().
+titlecase(CD) when is_list(CD) ->
+ case unicode_util:titlecase(CD) of
+ [GC|Tail] -> append(GC,Tail);
+ Empty -> Empty
+ end;
+titlecase(CD) when is_binary(CD) ->
+ case unicode_util:titlecase(CD) of
+ [CP|Chars] when is_integer(CP) -> <<CP/utf8,Chars/binary>>;
+ [CPs|Chars] ->
+ << << <<CP/utf8>> || CP <- CPs>>/binary, Chars/binary>>;
+ [] -> <<>>
+ end.
+
+%% Make a comparable string of the Str should be used for equality tests only
+-spec casefold(String::unicode:chardata()) -> unicode:chardata().
+casefold(CD) when is_list(CD) ->
+ casefold_list(CD);
+casefold(CD) when is_binary(CD) ->
+ casefold_bin(CD,<<>>).
+
+-spec to_integer(String) -> {Int, Rest} | {'error', Reason} when
+ String :: unicode:chardata(),
+ Int :: integer(),
+ Rest :: unicode:chardata(),
+ Reason :: 'no_integer' | badarg.
+
+to_integer(String) ->
+ try take(String, "+-0123456789") of
+ {Head, Tail} ->
+ case is_empty(Head) of
+ true -> {error, no_integer};
+ false ->
+ List = unicode:characters_to_list(Head),
+ case string:list_to_integer(List) of
+ {error, _} = Err -> Err;
+ {Int, Rest} ->
+ to_number(String, Int, Rest, List, Tail)
+ end
+ end
+ catch _:_ -> {error, badarg}
+ end.
+
+-spec to_float(String) -> {Float, Rest} | {'error', Reason} when
+ String :: unicode:chardata(),
+ Float :: float(),
+ Rest :: unicode:chardata(),
+ Reason :: 'no_float' | 'badarg'.
+
+to_float(String) ->
+ try take(String, "+-0123456789eE.,") of
+ {Head, Tail} ->
+ case is_empty(Head) of
+ true -> {error, no_float};
+ false ->
+ List = unicode:characters_to_list(Head),
+ case string:list_to_float(List) of
+ {error, _} = Err -> Err;
+ {Float, Rest} ->
+ to_number(String, Float, Rest, List, Tail)
+ end
+ end
+ catch _:_ -> {error, badarg}
+ end.
+
+to_number(String, Number, Rest, List, _Tail) when is_binary(String) ->
+ BSz = length(List)-length(Rest),
+ <<_:BSz/binary, Cont/binary>> = String,
+ {Number, Cont};
+to_number(_, Number, Rest, _, Tail) ->
+ {Number, concat(Rest,Tail)}.
+
+%% Return the remaining string with prefix removed or else nomatch
+-spec prefix(String::unicode:chardata(), Prefix::unicode:chardata()) ->
+ 'nomatch' | unicode:chardata().
+prefix(Str, []) -> Str;
+prefix(Str, Prefix0) ->
+ Prefix = unicode:characters_to_list(Prefix0),
+ case prefix_1(Str, Prefix) of
+ [] when is_binary(Str) -> <<>>;
+ Res -> Res
+ end.
+
+%% split String with the first occurrence of SearchPattern, return list of splits
+-spec split(String, SearchPattern) -> [unicode:chardata()] when
+ String :: unicode:chardata(),
+ SearchPattern :: unicode:chardata().
+split(String, SearchPattern) ->
+ split(String, SearchPattern, leading).
+
+%% split String with SearchPattern, return list of splits
+-spec split(String, SearchPattern, Where) -> [unicode:chardata()] when
+ String :: unicode:chardata(),
+ SearchPattern :: unicode:chardata(),
+ Where :: direction() | 'all'.
+split(String, SearchPattern, Where) ->
+ case is_empty(SearchPattern) of
+ true -> [String];
+ false ->
+ SearchPatternCPs = unicode:characters_to_list(SearchPattern),
+ case split_1(String, SearchPatternCPs, 0, Where, [], []) of
+ {_Curr, []} -> [String];
+ {_Curr, Acc} when Where =:= trailing -> Acc;
+ {Curr, Acc} when Where =:= all -> lists:reverse([Curr|Acc]);
+ Acc when is_list(Acc) -> Acc
+ end
+ end.
+
+%% Replace the first SearchPattern in String with Replacement
+-spec replace(String, SearchPattern, Replacement) ->
+ [unicode:chardata()] when
+ String :: unicode:chardata(),
+ SearchPattern :: unicode:chardata(),
+ Replacement :: unicode:chardata().
+replace(String, SearchPattern, Replacement) ->
+ lists:join(Replacement, split(String, SearchPattern)).
+
+%% Replace Where SearchPattern in String with Replacement
+-spec replace(String, SearchPattern, Replacement, Where) ->
+ [unicode:chardata()] when
+ String :: unicode:chardata(),
+ SearchPattern :: unicode:chardata(),
+ Replacement :: unicode:chardata(),
+ Where :: direction() | 'all'.
+replace(String, SearchPattern, Replacement, Where) ->
+ lists:join(Replacement, split(String, SearchPattern, Where)).
+
+%% Split Str into a list of chardata separated by one of the grapheme
+%% clusters in Seps
+-spec lexemes(String::unicode:chardata(),
+ SeparatorList::[grapheme_cluster()]) ->
+ [unicode:chardata()].
+lexemes([], _) -> [];
+lexemes(Str, Seps0) when is_list(Seps0) ->
+ Seps = search_pattern(Seps0),
+ lexemes_m(Str, Seps, []).
+
+-spec nth_lexeme(String, N, SeparatorList) -> unicode:chardata() when
+ String::unicode:chardata(),
+ N::non_neg_integer(),
+ SeparatorList::[grapheme_cluster()].
+
+nth_lexeme(Str, 1, []) -> Str;
+nth_lexeme(Str, N, Seps0) when is_list(Seps0), is_integer(N), N > 0 ->
+ Seps = search_pattern(Seps0),
+ nth_lexeme_m(Str, Seps, N).
+
+%% find first SearchPattern in String return rest of string
+-spec find(String, SearchPattern) -> unicode:chardata() | 'nomatch' when
+ String::unicode:chardata(),
+ SearchPattern::unicode:chardata().
+find(String, SearchPattern) ->
+ find(String, SearchPattern, leading).
+
+%% find SearchPattern in String (search in Dir direction) return rest of string
+-spec find(String, SearchPattern, Dir) -> unicode:chardata() | 'nomatch' when
+ String::unicode:chardata(),
+ SearchPattern::unicode:chardata(),
+ Dir::direction().
+find(String, "", _) -> String;
+find(String, <<>>, _) -> String;
+find(String, SearchPattern, leading) ->
+ find_l(String, unicode:characters_to_list(SearchPattern));
+find(String, SearchPattern, trailing) ->
+ find_r(String, unicode:characters_to_list(SearchPattern), nomatch).
+
+%% Fetch first codepoint and return rest in tail
+-spec next_grapheme(String::unicode:chardata()) ->
+ maybe_improper_list(grapheme_cluster(),unicode:chardata()) |
+ {error,unicode:chardata()}.
+next_grapheme(CD) -> unicode_util:gc(CD).
+
+%% Fetch first grapheme cluster and return rest in tail
+-spec next_codepoint(String::unicode:chardata()) ->
+ maybe_improper_list(char(),unicode:chardata()) |
+ {error,unicode:chardata()}.
+next_codepoint(CD) -> unicode_util:cp(CD).
+
+%% Internals
+
+length_1([_|Rest], N) ->
+ length_1(unicode_util:gc(Rest), N+1);
+length_1([], N) ->
+ N.
+
+equal_1([A|AR], [B|BR]) when is_integer(A), is_integer(B) ->
+ A =:= B andalso equal_1(AR, BR);
+equal_1([], BR) -> is_empty(BR);
+equal_1(A0,B0) ->
+ case {unicode_util:cp(A0), unicode_util:cp(B0)} of
+ {[CP|A],[CP|B]} -> equal_1(A,B);
+ {[], []} -> true;
+ {L1,L2} when is_list(L1), is_list(L2) -> false
+ end.
+
+equal_nocase(A, A) -> true;
+equal_nocase(A0, B0) ->
+ case {unicode_util:cp(unicode_util:casefold(A0)),
+ unicode_util:cp(unicode_util:casefold(B0))} of
+ {[CP|A],[CP|B]} -> equal_nocase(A,B);
+ {[], []} -> true;
+ {L1,L2} when is_list(L1), is_list(L2) -> false
+ end.
+
+equal_norm(A, A, _Norm) -> true;
+equal_norm(A0, B0, Norm) ->
+ case {unicode_util:cp(unicode_util:Norm(A0)),
+ unicode_util:cp(unicode_util:Norm(B0))} of
+ {[CP|A],[CP|B]} -> equal_norm(A,B, Norm);
+ {[], []} -> true;
+ {L1,L2} when is_list(L1), is_list(L2) -> false
+ end.
+
+equal_norm_nocase(A, A, _Norm) -> true;
+equal_norm_nocase(A0, B0, Norm) ->
+ case {unicode_util:cp(unicode_util:casefold(unicode_util:Norm(A0))),
+ unicode_util:cp(unicode_util:casefold(unicode_util:Norm(B0)))} of
+ {[CP|A],[CP|B]} -> equal_norm_nocase(A,B, Norm);
+ {[], []} -> true;
+ {L1,L2} when is_list(L1), is_list(L2) -> false
+ end.
+
+reverse_1(CD, Acc) ->
+ case unicode_util:gc(CD) of
+ [GC|Rest] -> reverse_1(Rest, [GC|Acc]);
+ [] -> Acc
+ end.
+
+slice_l(CD, N, Binary) when N > 0 ->
+ case unicode_util:gc(CD) of
+ [_|Cont] -> slice_l(Cont, N-1, Binary);
+ [] when Binary -> <<>>;
+ [] -> []
+ end;
+slice_l(Cont, 0, Binary) ->
+ case is_empty(Cont) of
+ true when Binary -> <<>>;
+ _ -> Cont
+ end.
+
+slice_trail(CD, N) when is_list(CD) ->
+ slice_list(CD, N);
+slice_trail(CD, N) when is_binary(CD) ->
+ slice_bin(CD, N, CD).
+
+slice_list(CD, N) when N > 0 ->
+ case unicode_util:gc(CD) of
+ [GC|Cont] -> append(GC, slice_list(Cont, N-1));
+ [] -> []
+ end;
+slice_list(_, 0) ->
+ [].
+
+slice_bin(CD, N, Orig) when N > 0 ->
+ case unicode_util:gc(CD) of
+ [_|Cont] -> slice_bin(Cont, N-1, Orig);
+ [] -> Orig
+ end;
+slice_bin([], 0, Orig) ->
+ Orig;
+slice_bin(CD, 0, Orig) ->
+ Sz = byte_size(Orig) - byte_size(CD),
+ <<Keep:Sz/binary, _/binary>> = Orig,
+ Keep.
+
+uppercase_list(CPs0) ->
+ case unicode_util:uppercase(CPs0) of
+ [Char|CPs] -> append(Char,uppercase_list(CPs));
+ [] -> []
+ end.
+
+uppercase_bin(CPs0, Acc) ->
+ case unicode_util:uppercase(CPs0) of
+ [Char|CPs] when is_integer(Char) ->
+ uppercase_bin(CPs, <<Acc/binary, Char/utf8>>);
+ [Chars|CPs] ->
+ uppercase_bin(CPs, <<Acc/binary,
+ << <<CP/utf8>> || CP <- Chars>>/binary >>);
+ [] -> Acc
+ end.
+
+lowercase_list(CPs0) ->
+ case unicode_util:lowercase(CPs0) of
+ [Char|CPs] -> append(Char,lowercase_list(CPs));
+ [] -> []
+ end.
+
+lowercase_bin(CPs0, Acc) ->
+ case unicode_util:lowercase(CPs0) of
+ [Char|CPs] when is_integer(Char) ->
+ lowercase_bin(CPs, <<Acc/binary, Char/utf8>>);
+ [Chars|CPs] ->
+ lowercase_bin(CPs, <<Acc/binary,
+ << <<CP/utf8>> || CP <- Chars>>/binary >>);
+ [] -> Acc
+ end.
+
+casefold_list(CPs0) ->
+ case unicode_util:casefold(CPs0) of
+ [Char|CPs] -> append(Char, casefold_list(CPs));
+ [] -> []
+ end.
+
+casefold_bin(CPs0, Acc) ->
+ case unicode_util:casefold(CPs0) of
+ [Char|CPs] when is_integer(Char) ->
+ casefold_bin(CPs, <<Acc/binary, Char/utf8>>);
+ [Chars|CPs] ->
+ casefold_bin(CPs, <<Acc/binary,
+ << <<CP/utf8>> || CP <- Chars>>/binary >>);
+ [] -> Acc
+ end.
+
+
+trim_l([Bin|Cont0], Sep) when is_binary(Bin) ->
+ case bin_search_inv(Bin, Cont0, Sep) of
+ {nomatch, Cont} -> trim_l(Cont, Sep);
+ Keep -> Keep
+ end;
+trim_l(Str, {GCs, _, _}=Sep) when is_list(Str) ->
+ case unicode_util:gc(Str) of
+ [C|Cs] ->
+ case lists:member(C, GCs) of
+ true -> trim_l(Cs, Sep);
+ false -> Str
+ end;
+ [] -> []
+ end;
+trim_l(Bin, Sep) when is_binary(Bin) ->
+ case bin_search_inv(Bin, [], Sep) of
+ {nomatch,_} -> <<>>;
+ [Keep] -> Keep
+ end.
+
+trim_t([Bin|Cont0], N, Sep) when is_binary(Bin) ->
+ <<_:N/binary, Rest/binary>> = Bin,
+ case bin_search(Rest, Cont0, Sep) of
+ {nomatch,_} ->
+ stack(Bin, trim_t(Cont0, 0, Sep));
+ [SepStart|Cont1] ->
+ case bin_search_inv(SepStart, Cont1, Sep) of
+ {nomatch, Cont} ->
+ Tail = trim_t(Cont, 0, Sep),
+ case is_empty(Tail) of
+ true ->
+ KeepSz = byte_size(Bin) - byte_size(SepStart),
+ <<Keep:KeepSz/binary, _/binary>> = Bin,
+ Keep;
+ false ->
+ Used = cp_prefix(Cont0, Cont),
+ stack(Bin, stack(Used, Tail))
+ end;
+ [NonSep|Cont] when is_binary(NonSep) ->
+ KeepSz = byte_size(Bin) - byte_size(NonSep),
+ trim_t([Bin|Cont], KeepSz, Sep)
+ end
+ end;
+trim_t(Str, 0, {GCs,CPs,_}=Sep) when is_list(Str) ->
+ case unicode_util:cp(Str) of
+ [CP|Cs] ->
+ case lists:member(CP, CPs) of
+ true ->
+ [GC|Cs1] = unicode_util:gc(Str),
+ case lists:member(GC, GCs) of
+ true ->
+ Tail = trim_t(Cs1, 0, Sep),
+ case is_empty(Tail) of
+ true -> [];
+ false -> append(GC,Tail)
+ end;
+ false ->
+ append(GC,trim_t(Cs1, 0, Sep))
+ end;
+ false ->
+ append(CP,trim_t(Cs, 0, Sep))
+ end;
+ [] -> []
+ end;
+trim_t(Bin, N, Sep) when is_binary(Bin) ->
+ <<_:N/binary, Rest/binary>> = Bin,
+ case bin_search(Rest, Sep) of
+ {nomatch,_} -> Bin;
+ [SepStart] ->
+ case bin_search_inv(SepStart, [], Sep) of
+ {nomatch,_} ->
+ KeepSz = byte_size(Bin) - byte_size(SepStart),
+ <<Keep:KeepSz/binary, _/binary>> = Bin,
+ Keep;
+ [NonSep] ->
+ KeepSz = byte_size(Bin) - byte_size(NonSep),
+ trim_t(Bin, KeepSz, Sep)
+ end
+ end.
+
+take_l([Bin|Cont0], Sep, Acc) when is_binary(Bin) ->
+ case bin_search_inv(Bin, Cont0, Sep) of
+ {nomatch, Cont} ->
+ Used = cp_prefix(Cont0, Cont),
+ take_l(Cont, Sep, [unicode:characters_to_binary([Bin|Used])|Acc]);
+ [Bin1|_]=After when is_binary(Bin1) ->
+ First = byte_size(Bin) - byte_size(Bin1),
+ <<Keep:First/binary, _/binary>> = Bin,
+ {btoken(Keep,Acc), After}
+ end;
+take_l(Str, {GCs, _, _}=Sep, Acc) when is_list(Str) ->
+ case unicode_util:gc(Str) of
+ [C|Cs] ->
+ case lists:member(C, GCs) of
+ true -> take_l(Cs, Sep, append(rev(C),Acc));
+ false -> {rev(Acc), Str}
+ end;
+ [] -> {rev(Acc), []}
+ end;
+take_l(Bin, Sep, Acc) when is_binary(Bin) ->
+ case bin_search_inv(Bin, [], Sep) of
+ {nomatch,_} ->
+ {btoken(Bin, Acc), <<>>};
+ [After] ->
+ First = byte_size(Bin) - byte_size(After),
+ <<Keep:First/binary, _/binary>> = Bin,
+ {btoken(Keep, Acc), After}
+ end.
+
+take_lc([Bin|Cont0], Sep, Acc) when is_binary(Bin) ->
+ case bin_search(Bin, Cont0, Sep) of
+ {nomatch, Cont} ->
+ Used = cp_prefix(Cont0, Cont),
+ take_lc(Cont, Sep, [unicode:characters_to_binary([Bin|Used])|Acc]);
+ [Bin1|_]=After when is_binary(Bin1) ->
+ First = byte_size(Bin) - byte_size(Bin1),
+ <<Keep:First/binary, _/binary>> = Bin,
+ {btoken(Keep,Acc), After}
+ end;
+take_lc(Str, {GCs, _, _}=Sep, Acc) when is_list(Str) ->
+ case unicode_util:gc(Str) of
+ [C|Cs] ->
+ case lists:member(C, GCs) of
+ false -> take_lc(Cs, Sep, append(rev(C),Acc));
+ true -> {rev(Acc), Str}
+ end;
+ [] -> {rev(Acc), []}
+ end;
+take_lc(Bin, Sep, Acc) when is_binary(Bin) ->
+ case bin_search(Bin, [], Sep) of
+ {nomatch,_} ->
+ {btoken(Bin, Acc), <<>>};
+ [After] ->
+ First = byte_size(Bin) - byte_size(After),
+ <<Keep:First/binary, _/binary>> = Bin,
+ {btoken(Keep, Acc), After}
+ end.
+
+take_t([Bin|Cont0], N, Sep) when is_binary(Bin) ->
+ <<_:N/binary, Rest/binary>> = Bin,
+ case bin_search(Rest, Cont0, Sep) of
+ {nomatch,Cont} ->
+ Used = cp_prefix(Cont0, Cont),
+ {Head, Tail} = take_t(Cont, 0, Sep),
+ {stack(unicode:characters_to_binary([Bin|Used]), Head), Tail};
+ [SepStart|Cont1] ->
+ case bin_search_inv(SepStart, Cont1, Sep) of
+ {nomatch, Cont} ->
+ {Head, Tail} = take_t(Cont, 0, Sep),
+ Used = cp_prefix(Cont0, Cont),
+ case equal(Tail, Cont) of
+ true ->
+ KeepSz = byte_size(Bin) - byte_size(SepStart),
+ <<Keep:KeepSz/binary, End/binary>> = Bin,
+ {stack(Keep,Head), stack(stack(End,Used),Tail)};
+ false ->
+ {stack(unicode:characters_to_binary([Bin|Used]),Head), Tail}
+ end;
+ [NonSep|Cont] when is_binary(NonSep) ->
+ KeepSz = byte_size(Bin) - byte_size(NonSep),
+ take_t([Bin|Cont], KeepSz, Sep)
+ end
+ end;
+take_t(Str, 0, {GCs,CPs,_}=Sep) when is_list(Str) ->
+ case unicode_util:cp(Str) of
+ [CP|Cs] ->
+ case lists:member(CP, CPs) of
+ true ->
+ [GC|Cs1] = unicode_util:gc(Str),
+ case lists:member(GC, GCs) of
+ true ->
+ {Head, Tail} = take_t(Cs1, 0, Sep),
+ case equal(Tail, Cs1) of
+ true -> {Head, append(GC,Tail)};
+ false -> {append(GC,Head), Tail}
+ end;
+ false ->
+ {Head, Tail} = take_t(Cs, 0, Sep),
+ {append(CP,Head), Tail}
+ end;
+ false ->
+ {Head, Tail} = take_t(Cs, 0, Sep),
+ {append(CP,Head), Tail}
+ end;
+ [] -> {[],[]}
+ end;
+take_t(Bin, N, Sep) when is_binary(Bin) ->
+ <<_:N/binary, Rest/binary>> = Bin,
+ case bin_search(Rest, Sep) of
+ {nomatch,_} -> {Bin, <<>>};
+ [SepStart] ->
+ case bin_search_inv(SepStart, [], Sep) of
+ {nomatch,_} ->
+ KeepSz = byte_size(Bin) - byte_size(SepStart),
+ <<Before:KeepSz/binary, End/binary>> = Bin,
+ {Before, End};
+ [NonSep] ->
+ KeepSz = byte_size(Bin) - byte_size(NonSep),
+ take_t(Bin, KeepSz, Sep)
+ end
+ end.
+
+take_tc([Bin|Cont0], N, Sep) when is_binary(Bin) ->
+ <<_:N/binary, Rest/binary>> = Bin,
+ case bin_search_inv(Rest, Cont0, Sep) of
+ {nomatch,Cont} ->
+ Used = cp_prefix(Cont0, Cont),
+ {Head, Tail} = take_tc(Cont, 0, Sep),
+ {stack(unicode:characters_to_binary([Bin|Used]), Head), Tail};
+ [SepStart|Cont1] ->
+ case bin_search(SepStart, Cont1, Sep) of
+ {nomatch, Cont} ->
+ {Head, Tail} = take_tc(Cont, 0, Sep),
+ Used = cp_prefix(Cont0, Cont),
+ case equal(Tail, Cont) of
+ true ->
+ KeepSz = byte_size(Bin) - byte_size(SepStart),
+ <<Keep:KeepSz/binary, End/binary>> = Bin,
+ {stack(Keep,Head), stack(stack(End,Used),Tail)};
+ false ->
+ {stack(unicode:characters_to_binary([Bin|Used]),Head), Tail}
+ end;
+ [NonSep|Cont] when is_binary(NonSep) ->
+ KeepSz = byte_size(Bin) - byte_size(NonSep),
+ take_tc([Bin|Cont], KeepSz, Sep)
+ end
+ end;
+take_tc(Str, 0, {GCs,CPs,_}=Sep) when is_list(Str) ->
+ case unicode_util:cp(Str) of
+ [CP|Cs] ->
+ case lists:member(CP, CPs) of
+ true ->
+ [GC|Cs1] = unicode_util:gc(Str),
+ case lists:member(GC, GCs) of
+ false ->
+ {Head, Tail} = take_tc(Cs1, 0, Sep),
+ case equal(Tail, Cs1) of
+ true -> {Head, append(GC,Tail)};
+ false -> {append(GC,Head), Tail}
+ end;
+ true ->
+ {Head, Tail} = take_tc(Cs1, 0, Sep),
+ {append(GC,Head), Tail}
+ end;
+ false ->
+ {Head, Tail} = take_tc(Cs, 0, Sep),
+ case equal(Tail, Cs) of
+ true -> {Head, append(CP,Tail)};
+ false -> {append(CP,Head), Tail}
+ end
+ end;
+ [] -> {[],[]}
+ end;
+take_tc(Bin, N, Sep) when is_binary(Bin) ->
+ <<_:N/binary, Rest/binary>> = Bin,
+ case bin_search_inv(Rest, [], Sep) of
+ {nomatch,_} -> {Bin, <<>>};
+ [SepStart] ->
+ case bin_search(SepStart, [], Sep) of
+ {nomatch,_} ->
+ KeepSz = byte_size(Bin) - byte_size(SepStart),
+ <<Before:KeepSz/binary, End/binary>> = Bin,
+ {Before, End};
+ [NonSep] ->
+ KeepSz = byte_size(Bin) - byte_size(NonSep),
+ take_tc(Bin, KeepSz, Sep)
+ end
+ end.
+
+prefix_1(Cs, []) -> Cs;
+prefix_1(Cs, [_]=Pre) ->
+ prefix_2(unicode_util:gc(Cs), Pre);
+prefix_1(Cs, Pre) ->
+ prefix_2(unicode_util:cp(Cs), Pre).
+
+prefix_2([C|Cs], [C|Pre]) ->
+ prefix_1(Cs, Pre);
+prefix_2(_, _) ->
+ nomatch.
+
+split_1([Bin|Cont0], Needle, Start, Where, Curr0, Acc)
+ when is_binary(Bin) ->
+ case bin_search_str(Bin, Start, Cont0, Needle) of
+ {nomatch,Sz,Cont} ->
+ <<Keep:Sz/binary, _/binary>> = Bin,
+ split_1(Cont, Needle, 0, Where, [Keep|Curr0], Acc);
+ {Before, [Cs0|Cont], After} ->
+ Curr = add_non_empty(Before,Curr0),
+ case Where of
+ leading ->
+ [rev(Curr),After];
+ trailing ->
+ <<_/utf8, Cs/binary>> = Cs0,
+ Next = byte_size(Bin) - byte_size(Cs),
+ split_1([Bin|Cont], Needle, Next, Where,
+ Curr0, [rev(Curr),After]);
+ all ->
+ split_1(After, Needle, 0, Where, [], [rev(Curr)|Acc])
+ end
+ end;
+split_1(Cs0, [C|_]=Needle, _, Where, Curr, Acc) when is_list(Cs0) ->
+ case unicode_util:cp(Cs0) of
+ [C|Cs] ->
+ case prefix_1(Cs0, Needle) of
+ nomatch -> split_1(Cs, Needle, 0, Where, append(C,Curr), Acc);
+ Rest when Where =:= leading ->
+ [rev(Curr), Rest];
+ Rest when Where =:= trailing ->
+ split_1(Cs, Needle, 0, Where, [C|Curr], [rev(Curr), Rest]);
+ Rest when Where =:= all ->
+ split_1(Rest, Needle, 0, Where, [], [rev(Curr)|Acc])
+ end;
+ [Other|Cs] ->
+ split_1(Cs, Needle, 0, Where, append(Other,Curr), Acc);
+ [] ->
+ {rev(Curr), Acc}
+ end;
+split_1(Bin, [_C|_]=Needle, Start, Where, Curr0, Acc) ->
+ case bin_search_str(Bin, Start, [], Needle) of
+ {nomatch,_,_} ->
+ <<_:Start/binary, Keep/binary>> = Bin,
+ {rev([Keep|Curr0]), Acc};
+ {Before, [Cs0], After} ->
+ case Where of
+ leading ->
+ [rev([Before|Curr0]),After];
+ trailing ->
+ <<_/utf8, Cs/binary>> = Cs0,
+ Next = byte_size(Bin) - byte_size(Cs),
+ split_1(Bin, Needle, Next, Where, Curr0,
+ [btoken(Before,Curr0),After]);
+ all ->
+ Next = byte_size(Bin) - byte_size(After),
+ <<_:Start/binary, Keep/binary>> = Before,
+ Curr = [Keep|Curr0],
+ split_1(Bin, Needle, Next, Where, [], [rev(Curr)|Acc])
+ end
+ end.
+
+lexemes_m([Bin|Cont0], Seps, Ts) when is_binary(Bin) ->
+ case bin_search_inv(Bin, Cont0, Seps) of
+ {nomatch,Cont} ->
+ lexemes_m(Cont, Seps, Ts);
+ Cs ->
+ {Lexeme,Rest} = lexeme_pick(Cs, Seps, []),
+ lexemes_m(Rest, Seps, [Lexeme|Ts])
+ end;
+lexemes_m(Cs0, {GCs, _, _}=Seps, Ts) when is_list(Cs0) ->
+ case unicode_util:gc(Cs0) of
+ [C|Cs] ->
+ case lists:member(C, GCs) of
+ true ->
+ lexemes_m(Cs, Seps, Ts);
+ false ->
+ {Lexeme,Rest} = lexeme_pick(Cs0, Seps, []),
+ lexemes_m(Rest, Seps, [Lexeme|Ts])
+ end;
+ [] ->
+ lists:reverse(Ts)
+ end;
+lexemes_m(Bin, Seps, Ts) when is_binary(Bin) ->
+ case bin_search_inv(Bin, [], Seps) of
+ {nomatch,_} ->
+ lists:reverse(Ts);
+ [Cs] ->
+ {Lexeme,Rest} = lexeme_pick(Cs, Seps, []),
+ lexemes_m(Rest, Seps, add_non_empty(Lexeme,Ts))
+ end.
+
+lexeme_pick([CP|Cs1]=Cs0, {GCs,CPs,_}=Seps, Tkn) when is_integer(CP) ->
+ case lists:member(CP, CPs) of
+ true ->
+ [GC|Cs2] = unicode_util:gc(Cs0),
+ case lists:member(GC, GCs) of
+ true -> {rev(Tkn), Cs2};
+ false -> lexeme_pick(Cs2, Seps, append(rev(GC),Tkn))
+ end;
+ false -> lexeme_pick(Cs1, Seps, [CP|Tkn])
+ end;
+lexeme_pick([Bin|Cont0], Seps, Tkn) when is_binary(Bin) ->
+ case bin_search(Bin, Cont0, Seps) of
+ {nomatch,_} ->
+ lexeme_pick(Cont0, Seps, [Bin|Tkn]);
+ [Left|_Cont] = Cs ->
+ Bytes = byte_size(Bin) - byte_size(Left),
+ <<Lexeme:Bytes/binary, _/binary>> = Bin,
+ {btoken(Lexeme, Tkn), Cs}
+ end;
+lexeme_pick(Cs0, {GCs, CPs, _} = Seps, Tkn) when is_list(Cs0) ->
+ case unicode_util:cp(Cs0) of
+ [CP|Cs] ->
+ case lists:member(CP, CPs) of
+ true ->
+ [GC|Cs2] = unicode_util:gc(Cs0),
+ case lists:member(GC, GCs) of
+ true -> {rev(Tkn), Cs0};
+ false -> lexeme_pick(Cs2, Seps, append(rev(GC),Tkn))
+ end;
+ false ->
+ lexeme_pick(Cs, Seps, append(CP,Tkn))
+ end;
+ [] ->
+ {rev(Tkn), []}
+ end;
+lexeme_pick(Bin, Seps, Tkn) when is_binary(Bin) ->
+ case bin_search(Bin, Seps) of
+ {nomatch,_} ->
+ {btoken(Bin,Tkn), []};
+ [Left] ->
+ Bytes = byte_size(Bin) - byte_size(Left),
+ <<Lexeme:Bytes/binary, _/binary>> = Bin,
+ {btoken(Lexeme, Tkn), Left}
+ end.
+
+nth_lexeme_m([Bin|Cont0], Seps, N) when is_binary(Bin) ->
+ case bin_search_inv(Bin, Cont0, Seps) of
+ {nomatch,Cont} ->
+ nth_lexeme_m(Cont, Seps, N);
+ Cs when N > 1 ->
+ Rest = lexeme_skip(Cs, Seps),
+ nth_lexeme_m(Rest, Seps, N-1);
+ Cs ->
+ {Lexeme,_} = lexeme_pick(Cs, Seps, []),
+ Lexeme
+ end;
+nth_lexeme_m(Cs0, {GCs, _, _}=Seps, N) when is_list(Cs0) ->
+ case unicode_util:gc(Cs0) of
+ [C|Cs] ->
+ case lists:member(C, GCs) of
+ true ->
+ nth_lexeme_m(Cs, Seps, N);
+ false when N > 1 ->
+ Cs1 = lexeme_skip(Cs, Seps),
+ nth_lexeme_m(Cs1, Seps, N-1);
+ false ->
+ {Lexeme,_} = lexeme_pick(Cs0, Seps, []),
+ Lexeme
+ end;
+ [] ->
+ []
+ end;
+nth_lexeme_m(Bin, Seps, N) when is_binary(Bin) ->
+ case bin_search_inv(Bin, [], Seps) of
+ [Cs] when N > 1 ->
+ Cs1 = lexeme_skip(Cs, Seps),
+ nth_lexeme_m(Cs1, Seps, N-1);
+ [Cs] ->
+ {Lexeme,_} = lexeme_pick(Cs, Seps, []),
+ Lexeme;
+ {nomatch,_} ->
+ <<>>
+ end.
+
+lexeme_skip([CP|Cs1]=Cs0, {GCs,CPs,_}=Seps) when is_integer(CP) ->
+ case lists:member(CP, CPs) of
+ true ->
+ [GC|Cs2] = unicode_util:gc(Cs0),
+ case lists:member(GC, GCs) of
+ true -> Cs0;
+ false -> lexeme_skip(Cs2, Seps)
+ end;
+ false ->
+ lexeme_skip(Cs1, Seps)
+ end;
+lexeme_skip([Bin|Cont0], Seps) when is_binary(Bin) ->
+ case bin_search(Bin, Cont0, Seps) of
+ {nomatch,_} -> lexeme_skip(Cont0, Seps);
+ Cs -> Cs
+ end;
+lexeme_skip(Cs0, {GCs, CPs, _} = Seps) when is_list(Cs0) ->
+ case unicode_util:cp(Cs0) of
+ [CP|Cs] ->
+ case lists:member(CP, CPs) of
+ true ->
+ [GC|Cs2] = unicode_util:gc(Cs0),
+ case lists:member(GC, GCs) of
+ true -> Cs0;
+ false -> lexeme_skip(Cs2, Seps)
+ end;
+ false ->
+ lexeme_skip(Cs, Seps)
+ end;
+ [] ->
+ []
+ end;
+lexeme_skip(Bin, Seps) when is_binary(Bin) ->
+ case bin_search(Bin, Seps) of
+ {nomatch,_} -> <<>>;
+ [Left] -> Left
+ end.
+
+find_l([Bin|Cont0], Needle) when is_binary(Bin) ->
+ case bin_search_str(Bin, 0, Cont0, Needle) of
+ {nomatch, _, Cont} ->
+ find_l(Cont, Needle);
+ {_Before, Cs, _After} ->
+ Cs
+ end;
+find_l(Cs0, [C|_]=Needle) when is_list(Cs0) ->
+ case unicode_util:cp(Cs0) of
+ [C|Cs] ->
+ case prefix_1(Cs0, Needle) of
+ nomatch -> find_l(Cs, Needle);
+ _ -> Cs0
+ end;
+ [_C|Cs] ->
+ find_l(Cs, Needle);
+ [] -> nomatch
+ end;
+find_l(Bin, Needle) ->
+ case bin_search_str(Bin, 0, [], Needle) of
+ {nomatch,_,_} -> nomatch;
+ {_Before, [Cs], _After} -> Cs
+ end.
+
+find_r([Bin|Cont0], Needle, Res) when is_binary(Bin) ->
+ case bin_search_str(Bin, 0, Cont0, Needle) of
+ {nomatch,_,Cont} ->
+ find_r(Cont, Needle, Res);
+ {_, Cs0, _} ->
+ [_|Cs] = unicode_util:gc(Cs0),
+ find_r(Cs, Needle, Cs0)
+ end;
+find_r(Cs0, [C|_]=Needle, Res) when is_list(Cs0) ->
+ case unicode_util:cp(Cs0) of
+ [C|Cs] ->
+ case prefix_1(Cs0, Needle) of
+ nomatch -> find_r(Cs, Needle, Res);
+ _ -> find_r(Cs, Needle, Cs0)
+ end;
+ [_C|Cs] ->
+ find_r(Cs, Needle, Res);
+ [] -> Res
+ end;
+find_r(Bin, Needle, Res) ->
+ case bin_search_str(Bin, 0, [], Needle) of
+ {nomatch,_,_} -> Res;
+ {_Before, [Cs0], _After} ->
+ <<_/utf8, Cs/binary>> = Cs0,
+ find_r(Cs, Needle, Cs0)
+ end.
+
+%% These are used to avoid creating lists around binaries
+%% might be unnecessary, is there a better solution?
+btoken(Token, []) -> Token;
+btoken(BinPart, [C]) when is_integer(C) -> <<C/utf8, BinPart/binary>>;
+btoken(<<>>, Tkn) -> lists:reverse(Tkn);
+btoken(BinPart, Cs) -> [lists:reverse(Cs),BinPart].
+
+rev([B]) when is_binary(B) -> B;
+rev(L) when is_list(L) -> lists:reverse(L);
+rev(C) when is_integer(C) -> C.
+
+append(Char, <<>>) when is_integer(Char) -> [Char];
+append(Char, <<>>) when is_list(Char) -> Char;
+append(Char, Bin) when is_binary(Bin) -> [Char,Bin];
+append(Char, Str) when is_integer(Char) -> [Char|Str];
+append(GC, Str) when is_list(GC) -> GC ++ Str.
+
+stack(Bin, []) -> Bin;
+stack(<<>>, St) -> St;
+stack([], St) -> St;
+stack(Bin, St) -> [Bin|St].
+
+add_non_empty(<<>>, L) -> L;
+add_non_empty(Token, L) -> [Token|L].
+
+cp_prefix(Orig, Cont) ->
+ case unicode_util:cp(Cont) of
+ [] -> Orig;
+ [Cp|Rest] -> cp_prefix_1(Orig, Cp, Rest)
+ end.
+
+cp_prefix_1(Orig, Until, Cont) ->
+ case unicode_util:cp(Orig) of
+ [Until|Rest] ->
+ case equal(Rest, Cont) of
+ true -> [];
+ false-> [Until|cp_prefix_1(Rest, Until, Cont)]
+ end;
+ [CP|Rest] -> [CP|cp_prefix_1(Rest, Until, Cont)]
+ end.
+
+
+%% Binary special
+bin_search(Bin, Seps) ->
+ bin_search(Bin, [], Seps).
+
+bin_search(_Bin, Cont, {[],_,_}) ->
+ {nomatch, Cont};
+bin_search(Bin, Cont, {Seps,_,BP}) ->
+ bin_search_loop(Bin, 0, BP, Cont, Seps).
+
+%% Need to work with [<<$a>>, <<778/utf8>>],
+%% i.e. å in nfd form $a "COMBINING RING ABOVE"
+%% and PREPEND characters like "ARABIC NUMBER SIGN" 1536 <<216,128>>
+%% combined with other characters are currently ignored.
+search_pattern(Seps) ->
+ CPs = search_cp(Seps),
+ Bin = bin_pattern(CPs),
+ {Seps, CPs, Bin}.
+
+search_cp([CP|Seps]) when is_integer(CP) ->
+ [CP|search_cp(Seps)];
+search_cp([Pattern|Seps]) ->
+ [CP|_] = unicode_util:cp(Pattern),
+ [CP|search_cp(Seps)];
+search_cp([]) -> [].
+
+bin_pattern([CP|Seps]) ->
+ [<<CP/utf8>>|bin_pattern(Seps)];
+bin_pattern([]) -> [].
+
+bin_search_loop(Bin0, Start, _, Cont, _Seps)
+ when byte_size(Bin0) =< Start; Start < 0 ->
+ {nomatch, Cont};
+bin_search_loop(Bin0, Start, BinSeps, Cont, Seps) ->
+ <<_:Start/binary, Bin/binary>> = Bin0,
+ case binary:match(Bin, BinSeps) of
+ nomatch ->
+ {nomatch,Cont};
+ {Where, _CL} ->
+ <<_:Where/binary, Cont0/binary>> = Bin,
+ Cont1 = stack(Cont0, Cont),
+ [GC|Cont2] = unicode_util:gc(Cont1),
+ case lists:member(GC, Seps) of
+ false ->
+ case Cont2 of
+ [BinR|Cont] when is_binary(BinR) ->
+ Next = byte_size(Bin0) - byte_size(BinR),
+ bin_search_loop(Bin0, Next, BinSeps, Cont, Seps);
+ BinR when is_binary(BinR), Cont =:= [] ->
+ Next = byte_size(Bin0) - byte_size(BinR),
+ bin_search_loop(Bin0, Next, BinSeps, Cont, Seps);
+ _ ->
+ {nomatch, Cont2}
+ end;
+ true when is_list(Cont1) ->
+ Cont1;
+ true ->
+ [Cont1]
+ end
+ end.
+
+bin_search_inv(Bin, Cont, {[], _, _}) ->
+ [Bin|Cont];
+bin_search_inv(Bin, Cont, {[Sep], _, _}) ->
+ bin_search_inv_1([Bin|Cont], Sep);
+bin_search_inv(Bin, Cont, {Seps, _, _}) ->
+ bin_search_inv_n([Bin|Cont], Seps).
+
+bin_search_inv_1([<<>>|CPs], _) ->
+ {nomatch, CPs};
+bin_search_inv_1(CPs = [Bin0|Cont], Sep) when is_binary(Bin0) ->
+ case unicode_util:gc(CPs) of
+ [Sep|Bin] when is_binary(Bin), Cont =:= [] ->
+ bin_search_inv_1([Bin], Sep);
+ [Sep|[Bin|Cont]=Cs] when is_binary(Bin) ->
+ bin_search_inv_1(Cs, Sep);
+ [Sep|Cs] ->
+ {nomatch, Cs};
+ _ -> CPs
+ end.
+
+bin_search_inv_n([<<>>|CPs], _) ->
+ {nomatch, CPs};
+bin_search_inv_n([Bin0|Cont]=CPs, Seps) when is_binary(Bin0) ->
+ [C|Cs0] = unicode_util:gc(CPs),
+ case {lists:member(C, Seps), Cs0} of
+ {true, Cs} when is_binary(Cs), Cont =:= [] ->
+ bin_search_inv_n([Cs], Seps);
+ {true, [Bin|Cont]=Cs} when is_binary(Bin) ->
+ bin_search_inv_n(Cs, Seps);
+ {true, Cs} -> {nomatch, Cs};
+ {false, _} -> CPs
+ end.
+
+bin_search_str(Bin0, Start, Cont, [CP|_]=SearchCPs) ->
+ <<_:Start/binary, Bin/binary>> = Bin0,
+ case binary:match(Bin, <<CP/utf8>>) of
+ nomatch -> {nomatch, byte_size(Bin0), Cont};
+ {Where0, _} ->
+ Where = Start+Where0,
+ <<Keep:Where/binary, Cs0/binary>> = Bin0,
+ [GC|Cs]=unicode_util:gc(Cs0),
+ case prefix_1(stack(Cs0,Cont), SearchCPs) of
+ nomatch when is_binary(Cs) ->
+ KeepSz = byte_size(Bin0) - byte_size(Cs),
+ bin_search_str(Bin0, KeepSz, Cont, SearchCPs);
+ nomatch ->
+ {nomatch, Where, stack([GC|Cs],Cont)};
+ [] ->
+ {Keep, [Cs0|Cont], <<>>};
+ Rest ->
+ {Keep, [Cs0|Cont], Rest}
+ end
+ end.
+
+
+%%---------------------------------------------------------------------------
+%% OLD lists API kept for backwards compability
+%%---------------------------------------------------------------------------
+
%% Robert's bit
%% len(String)
@@ -68,12 +1349,12 @@ len(S) -> length(S).
%% equal(String1, String2)
%% Test if 2 strings are equal.
--spec equal(String1, String2) -> boolean() when
- String1 :: string(),
- String2 :: string().
+%% -spec equal(String1, String2) -> boolean() when
+%% String1 :: string(),
+%% String2 :: string().
-equal(S, S) -> true;
-equal(_, _) -> false.
+%% equal(S, S) -> true;
+%% equal(_, _) -> false.
%% concat(String1, String2)
%% Concatenate 2 strings.
@@ -127,7 +1408,7 @@ rchr([], _C, _I, L) -> L.
str(S, Sub) when is_list(Sub) -> str(S, Sub, 1).
str([C|S], [C|Sub], I) ->
- case prefix(Sub, S) of
+ case l_prefix(Sub, S) of
true -> I;
false -> str(S, [C|Sub], I+1)
end;
@@ -142,16 +1423,16 @@ str([], _Sub, _I) -> 0.
rstr(S, Sub) when is_list(Sub) -> rstr(S, Sub, 1, 0).
rstr([C|S], [C|Sub], I, L) ->
- case prefix(Sub, S) of
+ case l_prefix(Sub, S) of
true -> rstr(S, [C|Sub], I+1, I);
false -> rstr(S, [C|Sub], I+1, L)
end;
rstr([_|S], Sub, I, L) -> rstr(S, Sub, I+1, L);
rstr([], _Sub, _I, L) -> L.
-prefix([C|Pre], [C|String]) -> prefix(Pre, String);
-prefix([], String) when is_list(String) -> true;
-prefix(Pre, String) when is_list(Pre), is_list(String) -> false.
+l_prefix([C|Pre], [C|String]) -> l_prefix(Pre, String);
+l_prefix([], String) when is_list(String) -> true;
+l_prefix(Pre, String) when is_list(Pre), is_list(String) -> false.
%% span(String, Chars) -> Length.
%% cspan(String, Chars) -> Length.
@@ -229,9 +1510,9 @@ tokens(S, Seps) ->
[_|_] -> [S]
end;
[C] ->
- tokens_single_1(reverse(S), C, []);
+ tokens_single_1(lists:reverse(S), C, []);
[_|_] ->
- tokens_multiple_1(reverse(S), Seps, [])
+ tokens_multiple_1(lists:reverse(S), Seps, [])
end.
tokens_single_1([Sep|S], Sep, Toks) ->
@@ -342,8 +1623,8 @@ sub_word(String, Index, Char) when is_integer(Index), is_integer(Char) ->
s_word(strip(String, left, Char), Index, Char, 1, [])
end.
-s_word([], _, _, _,Res) -> reverse(Res);
-s_word([Char|_],Index,Char,Index,Res) -> reverse(Res);
+s_word([], _, _, _,Res) -> lists:reverse(Res);
+s_word([Char|_],Index,Char,Index,Res) -> lists:reverse(Res);
s_word([H|T],Index,Char,Index,Res) -> s_word(T,Index,Char,Index,[H|Res]);
s_word([Char|T],Stop,Char,Index,Res) when Index < Stop ->
s_word(strip(T,left,Char),Stop,Char,Index+1,Res);
@@ -359,7 +1640,7 @@ strip(String) -> strip(String, both).
-spec strip(String, Direction) -> Stripped when
String :: string(),
Stripped :: string(),
- Direction :: left | right | both.
+ Direction :: 'left' | 'right' | 'both'.
strip(String, left) -> strip_left(String, $\s);
strip(String, right) -> strip_right(String, $\s);
@@ -369,7 +1650,7 @@ strip(String, both) ->
-spec strip(String, Direction, Character) -> Stripped when
String :: string(),
Stripped :: string(),
- Direction :: left | right | both,
+ Direction :: 'left' | 'right' | 'both',
Character :: char().
strip(String, right, Char) -> strip_right(String, Char);
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index c81e72689c..1cd65fbf18 100644
--- a/lib/stdlib/src/supervisor.erl
+++ b/lib/stdlib/src/supervisor.erl
@@ -1087,6 +1087,10 @@ wait_dynamic_children(#child{restart_type=RType} = Child, Pids, Sz,
wait_dynamic_children(Child, ?SETS:del_element(Pid, Pids), Sz-1,
TRef, EStack);
+ {'DOWN', _MRef, process, Pid, {shutdown, _}} ->
+ wait_dynamic_children(Child, ?SETS:del_element(Pid, Pids), Sz-1,
+ TRef, EStack);
+
{'DOWN', _MRef, process, Pid, normal} when RType =/= permanent ->
wait_dynamic_children(Child, ?SETS:del_element(Pid, Pids), Sz-1,
TRef, EStack);
diff --git a/lib/stdlib/src/sys.erl b/lib/stdlib/src/sys.erl
index a6ecf03716..1f966411c5 100644
--- a/lib/stdlib/src/sys.erl
+++ b/lib/stdlib/src/sys.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -525,7 +525,7 @@ debug_cmd({log_to_file, false}, Debug) ->
{ok, NDebug};
debug_cmd({log_to_file, FileName}, Debug) ->
NDebug = close_log_file(Debug),
- case file:open(FileName, [write]) of
+ case file:open(FileName, [write,{encoding,utf8}]) of
{ok, Fd} ->
{ok, install_debug(log_to_file, Fd, NDebug)};
_Error ->
@@ -648,7 +648,7 @@ debug_options([{log, N} | T], Debug) when is_integer(N), N > 0 ->
debug_options([statistics | T], Debug) ->
debug_options(T, install_debug(statistics, init_stat(), Debug));
debug_options([{log_to_file, FileName} | T], Debug) ->
- case file:open(FileName, [write]) of
+ case file:open(FileName, [write,{encoding,utf8}]) of
{ok, Fd} ->
debug_options(T, install_debug(log_to_file, Fd, Debug));
_Error ->
diff --git a/lib/stdlib/src/timer.erl b/lib/stdlib/src/timer.erl
index ca868627a9..df10790ea0 100644
--- a/lib/stdlib/src/timer.erl
+++ b/lib/stdlib/src/timer.erl
@@ -165,7 +165,7 @@ tc(F) ->
T1 = erlang:monotonic_time(),
Val = F(),
T2 = erlang:monotonic_time(),
- Time = erlang:convert_time_unit(T2 - T1, native, micro_seconds),
+ Time = erlang:convert_time_unit(T2 - T1, native, microsecond),
{Time, Val}.
%%
@@ -180,7 +180,7 @@ tc(F, A) ->
T1 = erlang:monotonic_time(),
Val = apply(F, A),
T2 = erlang:monotonic_time(),
- Time = erlang:convert_time_unit(T2 - T1, native, micro_seconds),
+ Time = erlang:convert_time_unit(T2 - T1, native, microsecond),
{Time, Val}.
%%
@@ -196,7 +196,7 @@ tc(M, F, A) ->
T1 = erlang:monotonic_time(),
Val = apply(M, F, A),
T2 = erlang:monotonic_time(),
- Time = erlang:convert_time_unit(T2 - T1, native, micro_seconds),
+ Time = erlang:convert_time_unit(T2 - T1, native, microsecond),
{Time, Val}.
%%
diff --git a/lib/stdlib/src/unicode.erl b/lib/stdlib/src/unicode.erl
index 617da11ba8..fbe8a94074 100644
--- a/lib/stdlib/src/unicode.erl
+++ b/lib/stdlib/src/unicode.erl
@@ -1,8 +1,8 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
+%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,7 +14,7 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(unicode).
@@ -22,7 +22,12 @@
-export([characters_to_list/1, characters_to_list_int/2,
characters_to_binary/1, characters_to_binary_int/2,
characters_to_binary/3,
- bom_to_encoding/1, encoding_to_bom/1]).
+ bom_to_encoding/1, encoding_to_bom/1,
+ characters_to_nfd_list/1, characters_to_nfd_binary/1,
+ characters_to_nfc_list/1, characters_to_nfc_binary/1,
+ characters_to_nfkd_list/1, characters_to_nfkd_binary/1,
+ characters_to_nfkc_list/1, characters_to_nfkc_binary/1
+ ]).
-export_type([chardata/0, charlist/0, encoding/0, external_chardata/0,
external_charlist/0, latin1_char/0, latin1_chardata/0,
@@ -102,35 +107,6 @@ characters_to_list(_, _) ->
characters_to_list(ML) ->
unicode:characters_to_list(ML,unicode).
-characters_to_list_int(ML, Encoding) ->
- try
- do_characters_to_list(ML,Encoding)
- catch
- error:AnyError ->
- TheError = case AnyError of
- system_limit ->
- system_limit;
- _ ->
- badarg
- end,
- {'EXIT',{new_stacktrace,[{Mod,_,L,_}|Rest]}} =
- (catch erlang:error(new_stacktrace,
- [ML,Encoding])),
- erlang:raise(error,TheError,[{Mod,characters_to_list,L}|Rest])
- end.
-
-% XXX: Optimize me!
-do_characters_to_list(ML, Encoding) ->
- case unicode:characters_to_binary(ML,Encoding) of
- Bin when is_binary(Bin) ->
- unicode:characters_to_list(Bin,utf8);
- {error,Encoded,Rest} ->
- {error,unicode:characters_to_list(Encoded,utf8),Rest};
- {incomplete, Encoded2, Rest2} ->
- {incomplete,unicode:characters_to_list(Encoded2,utf8),Rest2}
- end.
-
-
-spec characters_to_binary(Data) -> Result when
Data :: latin1_chardata() | chardata() | external_chardata(),
Result :: binary()
@@ -154,24 +130,6 @@ characters_to_binary(ML) ->
[ML])),
erlang:raise(error,TheError,[{Mod,characters_to_binary,L}|Rest])
end.
-
-
-characters_to_binary_int(ML,InEncoding) ->
- try
- characters_to_binary_int(ML,InEncoding,unicode)
- catch
- error:AnyError ->
- TheError = case AnyError of
- system_limit ->
- system_limit;
- _ ->
- badarg
- end,
- {'EXIT',{new_stacktrace,[{Mod,_,L,_}|Rest]}} =
- (catch erlang:error(new_stacktrace,
- [ML,InEncoding])),
- erlang:raise(error,TheError,[{Mod,characters_to_binary,L}|Rest])
- end.
-spec characters_to_binary(Data, InEncoding, OutEncoding) -> Result when
Data :: latin1_chardata() | chardata() | external_chardata(),
@@ -192,7 +150,7 @@ characters_to_binary(ML, latin1, Uni) when is_binary(ML) and ((Uni =:= utf8) or
try
characters_to_binary_int(ML,latin1,utf8)
catch
- error:AnyError ->
+ error:AnyError ->
TheError = case AnyError of
system_limit ->
system_limit;
@@ -228,7 +186,7 @@ characters_to_binary(ML,Uni,latin1) when is_binary(ML) and ((Uni =:= utf8) or
[{Mod,characters_to_binary,L}|Rest])
end
end;
-
+
characters_to_binary(ML, InEncoding, OutEncoding) ->
try
characters_to_binary_int(ML,InEncoding,OutEncoding)
@@ -246,53 +204,6 @@ characters_to_binary(ML, InEncoding, OutEncoding) ->
erlang:raise(error,TheError,[{Mod,characters_to_binary,L}|Rest])
end.
-characters_to_binary_int(ML, InEncoding, OutEncoding) when
- InEncoding =:= latin1, OutEncoding =:= unicode;
- InEncoding =:= latin1, OutEncoding =:= utf8;
- InEncoding =:= unicode, OutEncoding =:= unicode;
- InEncoding =:= unicode, OutEncoding =:= utf8;
- InEncoding =:= utf8, OutEncoding =:= unicode;
- InEncoding =:= utf8, OutEncoding =:= utf8 ->
- unicode:characters_to_binary(ML,InEncoding);
-
-characters_to_binary_int(ML, InEncoding, OutEncoding) ->
- {InTrans,Limit} = case OutEncoding of
- latin1 -> {i_trans_chk(InEncoding),255};
- _ -> {i_trans(InEncoding),case InEncoding of latin1 -> 255; _ -> 16#10FFFF end}
- end,
- OutTrans = o_trans(OutEncoding),
- Res =
- ml_map(ML,
- fun(Part,Accum) when is_binary(Part) ->
- case InTrans(Part) of
- List when is_list(List) ->
- Tail = OutTrans(List),
- <<Accum/binary, Tail/binary>>;
- {error, Translated, Rest} ->
- Tail = OutTrans(Translated),
- {error, <<Accum/binary,Tail/binary>>, Rest};
- {incomplete, Translated, Rest, Missing} ->
- Tail = OutTrans(Translated),
- {incomplete, <<Accum/binary,Tail/binary>>, Rest,
- Missing}
- end;
- (Part, Accum) when is_integer(Part), Part =< Limit ->
- case OutTrans([Part]) of
- Binary when is_binary(Binary) ->
- <<Accum/binary, Binary/binary>>;
- {error, _, [Part]} ->
- {error,Accum,[Part]}
- end;
- (Part, Accum) ->
- {error, Accum, [Part]}
- end,<<>>),
- case Res of
- {incomplete,A,B,_} ->
- {incomplete,A,B};
- _ ->
- Res
- end.
-
-spec bom_to_encoding(Bin) -> {Encoding, Length} when
Bin :: binary(),
Encoding :: 'latin1' | 'utf8'
@@ -335,11 +246,215 @@ encoding_to_bom({utf32,little}) ->
<<255,254,0,0>>;
encoding_to_bom(latin1) ->
<<>>.
-
-cbv(utf8,<<1:1,1:1,0:1,_:5>>) ->
+-define(GC_N, 200). %% arbitrary number
+
+%% Canonical decompose string to list of chars
+-spec characters_to_nfd_list(chardata()) -> [char()] | {error, [char()], chardata()}.
+characters_to_nfd_list(CD) ->
+ characters_to_nfd_list(CD, []).
+characters_to_nfd_list(CD, Acc) ->
+ case unicode_util:nfd(CD) of
+ [GC|Str] when is_list(GC) -> characters_to_nfd_list(Str, lists:reverse(GC, Acc));
+ [CP|Str] -> characters_to_nfd_list(Str, [CP | Acc]);
+ [] -> lists:reverse(Acc);
+ {error,Error} -> {error, lists:reverse(Acc), Error}
+ end.
+
+-spec characters_to_nfd_binary(chardata()) -> unicode_binary() | {error, unicode_binary(), chardata()}.
+characters_to_nfd_binary(CD) ->
+ characters_to_nfd_binary(CD, ?GC_N, [], []).
+
+characters_to_nfd_binary(CD, N, Row, Acc) when N > 0 ->
+ case unicode_util:nfd(CD) of
+ [GC|Str] -> characters_to_nfd_binary(Str, N-1, [GC|Row], Acc);
+ [] -> acc_to_binary(prepend_row_to_acc(Row, Acc));
+ {error, Error} -> {error, acc_to_binary(prepend_row_to_acc(Row, Acc)), Error}
+ end;
+characters_to_nfd_binary(CD, _, Row, Acc) ->
+ characters_to_nfd_binary(CD, ?GC_N, [], prepend_row_to_acc(Row, Acc)).
+
+%% Compability Canonical decompose string to list of chars.
+-spec characters_to_nfkd_list(chardata()) -> [char()] | {error, [char()], chardata()}.
+characters_to_nfkd_list(CD) ->
+ characters_to_nfkd_list(CD, []).
+characters_to_nfkd_list(CD, Acc) ->
+ case unicode_util:nfkd(CD) of
+ [GC|Str] when is_list(GC) -> characters_to_nfkd_list(Str, lists:reverse(GC, Acc));
+ [CP|Str] -> characters_to_nfkd_list(Str, [CP | Acc]);
+ [] -> lists:reverse(Acc);
+ {error,Error} -> {error, lists:reverse(Acc), Error}
+ end.
+
+-spec characters_to_nfkd_binary(chardata()) -> unicode_binary() | {error, unicode_binary(), chardata()}.
+characters_to_nfkd_binary(CD) ->
+ characters_to_nfkd_binary(CD, ?GC_N, [], []).
+
+characters_to_nfkd_binary(CD, N, Row, Acc) when N > 0 ->
+ case unicode_util:nfkd(CD) of
+ [GC|Str] -> characters_to_nfkd_binary(Str, N-1, [GC|Row], Acc);
+ [] -> acc_to_binary(prepend_row_to_acc(Row, Acc));
+ {error, Error} -> {error, acc_to_binary(prepend_row_to_acc(Row, Acc)), Error}
+ end;
+characters_to_nfkd_binary(CD, _, Row, Acc) ->
+ characters_to_nfkd_binary(CD, ?GC_N, [], prepend_row_to_acc(Row, Acc)).
+
+
+%% Canonical compose string to list of chars
+-spec characters_to_nfc_list(chardata()) -> [char()] | {error, [char()], chardata()}.
+characters_to_nfc_list(CD) ->
+ characters_to_nfc_list(CD, []).
+characters_to_nfc_list(CD, Acc) ->
+ case unicode_util:nfc(CD) of
+ [GC|Str] when is_list(GC) -> characters_to_nfc_list(Str, lists:reverse(GC, Acc));
+ [CP|Str] -> characters_to_nfc_list(Str, [CP | Acc]);
+ [] -> lists:reverse(Acc);
+ {error,Error} -> {error, lists:reverse(Acc), Error}
+ end.
+
+-spec characters_to_nfc_binary(chardata()) -> unicode_binary() | {error, unicode_binary(), chardata()}.
+characters_to_nfc_binary(CD) ->
+ characters_to_nfc_binary(CD, ?GC_N, [], []).
+
+characters_to_nfc_binary(CD, N, Row, Acc) when N > 0 ->
+ case unicode_util:nfc(CD) of
+ [GC|Str] -> characters_to_nfc_binary(Str, N-1, [GC|Row], Acc);
+ [] -> acc_to_binary(prepend_row_to_acc(Row, Acc));
+ {error, Error} -> {error, acc_to_binary(prepend_row_to_acc(Row, Acc)), Error}
+ end;
+characters_to_nfc_binary(CD, _, Row, Acc) ->
+ characters_to_nfc_binary(CD, ?GC_N, [], prepend_row_to_acc(Row, Acc)).
+
+%% Compability Canonical compose string to list of chars
+-spec characters_to_nfkc_list(chardata()) -> [char()] | {error, [char()], chardata()}.
+characters_to_nfkc_list(CD) ->
+ characters_to_nfkc_list(CD, []).
+characters_to_nfkc_list(CD, Acc) ->
+ case unicode_util:nfkc(CD) of
+ [GC|Str] when is_list(GC) -> characters_to_nfkc_list(Str, lists:reverse(GC, Acc));
+ [CP|Str] -> characters_to_nfkc_list(Str, [CP | Acc]);
+ [] -> lists:reverse(Acc);
+ {error,Error} -> {error, lists:reverse(Acc), Error}
+ end.
+
+-spec characters_to_nfkc_binary(chardata()) -> unicode_binary() | {error, unicode_binary(), chardata()}.
+characters_to_nfkc_binary(CD) ->
+ characters_to_nfkc_binary(CD, ?GC_N, [], []).
+
+characters_to_nfkc_binary(CD, N, Row, Acc) when N > 0 ->
+ case unicode_util:nfkc(CD) of
+ [GC|Str] -> characters_to_nfkc_binary(Str, N-1, [GC|Row], Acc);
+ [] -> acc_to_binary(prepend_row_to_acc(Row, Acc));
+ {error, Error} -> {error, acc_to_binary(prepend_row_to_acc(Row, Acc)), Error}
+ end;
+characters_to_nfkc_binary(CD, _, Row, Acc) ->
+ characters_to_nfkc_binary(CD, ?GC_N, [], prepend_row_to_acc(Row, Acc)).
+
+acc_to_binary(Acc) ->
+ list_to_binary(lists:reverse(Acc)).
+prepend_row_to_acc(Row, Acc) ->
+ [characters_to_binary(lists:reverse(Row))|Acc].
+
+%% internals
+
+characters_to_list_int(ML, Encoding) ->
+ try
+ do_characters_to_list(ML,Encoding)
+ catch
+ error:AnyError ->
+ TheError = case AnyError of
+ system_limit ->
+ system_limit;
+ _ ->
+ badarg
+ end,
+ {'EXIT',{new_stacktrace,[{Mod,_,L,_}|Rest]}} =
+ (catch erlang:error(new_stacktrace,
+ [ML,Encoding])),
+ erlang:raise(error,TheError,[{Mod,characters_to_list,L}|Rest])
+ end.
+
+ % XXX: Optimize me!
+do_characters_to_list(ML, Encoding) ->
+ case unicode:characters_to_binary(ML,Encoding) of
+ Bin when is_binary(Bin) ->
+ unicode:characters_to_list(Bin,utf8);
+ {error,Encoded,Rest} ->
+ {error,unicode:characters_to_list(Encoded,utf8),Rest};
+ {incomplete, Encoded2, Rest2} ->
+ {incomplete,unicode:characters_to_list(Encoded2,utf8),Rest2}
+ end.
+
+
+characters_to_binary_int(ML,InEncoding) ->
+ try
+ characters_to_binary_int(ML,InEncoding,unicode)
+ catch
+ error:AnyError ->
+ TheError = case AnyError of
+ system_limit ->
+ system_limit;
+ _ ->
+ badarg
+ end,
+ {'EXIT',{new_stacktrace,[{Mod,_,L,_}|Rest]}} =
+ (catch erlang:error(new_stacktrace,
+ [ML,InEncoding])),
+ erlang:raise(error,TheError,[{Mod,characters_to_binary,L}|Rest])
+ end.
+
+
+characters_to_binary_int(ML, InEncoding, OutEncoding) when
+ InEncoding =:= latin1, OutEncoding =:= unicode;
+ InEncoding =:= latin1, OutEncoding =:= utf8;
+ InEncoding =:= unicode, OutEncoding =:= unicode;
+ InEncoding =:= unicode, OutEncoding =:= utf8;
+ InEncoding =:= utf8, OutEncoding =:= unicode;
+ InEncoding =:= utf8, OutEncoding =:= utf8 ->
+ unicode:characters_to_binary(ML,InEncoding);
+
+characters_to_binary_int(ML, InEncoding, OutEncoding) ->
+ {InTrans,Limit} = case OutEncoding of
+ latin1 -> {i_trans_chk(InEncoding),255};
+ _ -> {i_trans(InEncoding),case InEncoding of latin1 -> 255; _ -> 16#10FFFF end}
+ end,
+ OutTrans = o_trans(OutEncoding),
+ Res =
+ ml_map(ML,
+ fun(Part,Accum) when is_binary(Part) ->
+ case InTrans(Part) of
+ List when is_list(List) ->
+ Tail = OutTrans(List),
+ <<Accum/binary, Tail/binary>>;
+ {error, Translated, Rest} ->
+ Tail = OutTrans(Translated),
+ {error, <<Accum/binary,Tail/binary>>, Rest};
+ {incomplete, Translated, Rest, Missing} ->
+ Tail = OutTrans(Translated),
+ {incomplete, <<Accum/binary,Tail/binary>>, Rest,
+ Missing}
+ end;
+ (Part, Accum) when is_integer(Part), Part =< Limit ->
+ case OutTrans([Part]) of
+ Binary when is_binary(Binary) ->
+ <<Accum/binary, Binary/binary>>;
+ {error, _, [Part]} ->
+ {error,Accum,[Part]}
+ end;
+ (Part, Accum) ->
+ {error, Accum, [Part]}
+ end,<<>>),
+ case Res of
+ {incomplete,A,B,_} ->
+ {incomplete,A,B};
+ _ ->
+ Res
+ end.
+
+
+cbv(utf8,<<1:1,1:1,0:1,_:5>>) ->
1;
-cbv(utf8,<<1:1,1:1,1:1,0:1,_:4,R/binary>>) ->
+cbv(utf8,<<1:1,1:1,1:1,0:1,_:4,R/binary>>) ->
case R of
<<>> ->
2;
@@ -386,18 +501,18 @@ cbv({utf32,big}, <<0:8>>) ->
3;
cbv({utf32,big}, <<0:8,X:8>>) when X =< 16 ->
2;
-cbv({utf32,big}, <<0:8,X:8,Y:8>>)
+cbv({utf32,big}, <<0:8,X:8,Y:8>>)
when X =< 16, ((X > 0) or ((Y =< 215) or (Y >= 224))) ->
1;
cbv({utf32,big},_) ->
false;
cbv({utf32,little},<<_:8>>) ->
3;
-cbv({utf32,little},<<_:8,_:8>>) ->
+cbv({utf32,little},<<_:8,_:8>>) ->
2;
cbv({utf32,little},<<X:8,255:8,0:8>>) when X =:= 254; X =:= 255 ->
false;
-cbv({utf32,little},<<_:8,Y:8,X:8>>)
+cbv({utf32,little},<<_:8,Y:8,X:8>>)
when X =< 16, ((X > 0) or ((Y =< 215) or (Y >= 224))) ->
1;
cbv({utf32,little},_) ->
@@ -417,8 +532,8 @@ ml_map([Part|T],Fun,Accum) when is_integer(Part) ->
Bin2 when is_binary(Bin2) ->
Bin2;
{error, Converted, Rest} ->
- {error, Converted, Rest};
- {incomplete, Converted, Rest,X} ->
+ {error, Converted, Rest};
+ {incomplete, Converted, Rest,X} ->
{incomplete, Converted, Rest,X}
end;
% Can not be incomplete - it's an integer
@@ -471,7 +586,7 @@ ml_map(Part,Fun,Accum) when is_binary(Part), byte_size(Part) > 8192 ->
ml_map(Bin,Fun,Accum) when is_binary(Bin) ->
Fun(Bin,Accum).
-
+
@@ -523,7 +638,7 @@ o_trans(utf8) ->
<<One/utf8>>
end, L)
end;
-
+
o_trans(utf16) ->
fun(L) ->
do_o_binary(fun(One) ->
@@ -577,9 +692,9 @@ do_o_binary2(F,[H|T]) ->
[Bin|Bin3]
end
end.
-
+
%% Specific functions only allowing codepoints in latin1 range
-
+
do_i_utf8_chk(<<>>) ->
[];
do_i_utf8_chk(<<U/utf8,R/binary>>) when U =< 255 ->
diff --git a/lib/stdlib/src/zip.erl b/lib/stdlib/src/zip.erl
index f8ba6f18e9..81f927f399 100644
--- a/lib/stdlib/src/zip.erl
+++ b/lib/stdlib/src/zip.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -179,19 +179,6 @@
external_attr,
local_header_offset}).
-%% Unix extra fields (not yet supported)
--define(UNIX_EXTRA_FIELD_TAG, 16#000d).
--record(unix_extra_field, {atime,
- mtime,
- uid,
- gid}).
-
-%% extended timestamps (not yet supported)
--define(EXTENDED_TIMESTAMP_TAG, 16#5455).
-%% -record(extended_timestamp, {mtime,
-%% atime,
-%% ctime}).
-
-define(END_OF_CENTRAL_DIR_MAGIC, 16#06054b50).
-define(END_OF_CENTRAL_DIR_SZ, (4+2+2+2+2+4+4+2)).
@@ -279,7 +266,8 @@ do_openzip_get(F, #openzip{files = Files, in = In0, input = Input,
case file_name_search(F, Files) of
{#zip_file{offset = Offset},_}=ZFile ->
In1 = Input({seek, bof, Offset}, In0),
- case get_z_file(In1, Z, Input, Output, [], fun silent/1, CWD, ZFile) of
+ case get_z_file(In1, Z, Input, Output, [], fun silent/1,
+ CWD, ZFile, fun all/1) of
{file, R, _In2} -> {ok, R};
_ -> throw(file_not_found)
end;
@@ -380,9 +368,12 @@ do_unzip(F, Options) ->
{Info, In1} = get_central_dir(In0, RawIterator, Input),
%% get rid of zip-comment
Z = zlib:open(),
- Files = get_z_files(Info, Z, In1, Opts, []),
- zlib:close(Z),
- Input(close, In1),
+ Files = try
+ get_z_files(Info, Z, In1, Opts, [])
+ after
+ zlib:close(Z),
+ Input(close, In1)
+ end,
{ok, Files}.
%% Iterate over all files in a zip archive
@@ -459,11 +450,20 @@ do_zip(F, Files, Options) ->
#zip_opts{output = Output, open_opts = OpO} = Opts,
Out0 = Output({open, F, OpO}, []),
Z = zlib:open(),
- {Out1, LHS, Pos} = put_z_files(Files, Z, Out0, 0, Opts, []),
- zlib:close(Z),
- Out2 = put_central_dir(LHS, Pos, Out1, Opts),
- Out3 = Output({close, F}, Out2),
- {ok, Out3}.
+ try
+ {Out1, LHS, Pos} = put_z_files(Files, Z, Out0, 0, Opts, []),
+ zlib:close(Z),
+ Out2 = put_central_dir(LHS, Pos, Out1, Opts),
+ Out3 = Output({close, F}, Out2),
+ {ok, Out3}
+ catch
+ C:R ->
+ Stk = erlang:get_stacktrace(),
+ zlib:close(Z),
+ Output({close, F}, Out0),
+ erlang:raise(C, R, Stk)
+ end.
+
%% List zip directory contents
%%
@@ -1378,12 +1378,7 @@ cd_file_header_to_file_info(FileName,
gid = 0},
add_extra_info(FI, ExtraField).
-%% add extra info to file (some day when we implement it)
-add_extra_info(FI, <<?EXTENDED_TIMESTAMP_TAG:16/little, _Rest/binary>>) ->
- FI; % not yet supported, some other day...
-add_extra_info(FI, <<?UNIX_EXTRA_FIELD_TAG:16/little, Rest/binary>>) ->
- _UnixExtra = unix_extra_field_and_var_from_bin(Rest),
- FI; % not yet supported, and not widely used
+%% Currently, we ignore all the extra fields.
add_extra_info(FI, _) ->
FI.
@@ -1403,9 +1398,10 @@ get_z_files([{#zip_file{offset = Offset},_} = ZFile | Rest], Z, In0,
true ->
In1 = Input({seek, bof, Offset}, In0),
{In2, Acc1} =
- case get_z_file(In1, Z, Input, Output, OpO, FB, CWD, ZFile) of
+ case get_z_file(In1, Z, Input, Output, OpO, FB,
+ CWD, ZFile, Filter) of
{file, GZD, Inx} -> {Inx, [GZD | Acc0]};
- {dir, Inx} -> {Inx, Acc0}
+ {_, Inx} -> {Inx, Acc0}
end,
get_z_files(Rest, Z, In2, Opts, Acc1);
_ ->
@@ -1413,7 +1409,8 @@ get_z_files([{#zip_file{offset = Offset},_} = ZFile | Rest], Z, In0,
end.
%% get a file from the archive, reading chunks
-get_z_file(In0, Z, Input, Output, OpO, FB, CWD, {ZipFile,Extra}) ->
+get_z_file(In0, Z, Input, Output, OpO, FB,
+ CWD, {ZipFile,Extra}, Filter) ->
case Input({read, ?LOCAL_FILE_HEADER_SZ}, In0) of
{eof, In1} ->
{eof, In1};
@@ -1433,29 +1430,64 @@ get_z_file(In0, Z, Input, Output, OpO, FB, CWD, {ZipFile,Extra}) ->
end,
{BFileN, In3} = Input({read, FileNameLen + ExtraLen}, In1),
{FileName, _} = get_file_name_extra(FileNameLen, ExtraLen, BFileN),
- FileName1 = add_cwd(CWD, FileName),
- case lists:last(FileName) of
- $/ ->
- %% perhaps this should always be done?
- Output({ensure_dir,FileName1},[]),
- {dir, In3};
- _ ->
- %% FileInfo = local_file_header_to_file_info(LH)
- %%{Out, In4, CRC, UncompSize} =
- {Out, In4, CRC, _UncompSize} =
- get_z_data(CompMethod, In3, FileName1,
- CompSize, Input, Output, OpO, Z),
- In5 = skip_z_data_descriptor(GPFlag, Input, In4),
- %% TODO This should be fixed some day:
- %% In5 = Input({set_file_info, FileName, FileInfo#file_info{size=UncompSize}}, In4),
- FB(FileName),
- CRC =:= CRC32 orelse throw({bad_crc, FileName}),
- {file, Out, In5}
+ ReadAndWrite =
+ case check_valid_location(CWD, FileName) of
+ {true,FileName1} ->
+ true;
+ {false,FileName1} ->
+ Filter({ZipFile#zip_file{name = FileName1},Extra})
+ end,
+ case ReadAndWrite of
+ true ->
+ case lists:last(FileName) of
+ $/ ->
+ %% perhaps this should always be done?
+ Output({ensure_dir,FileName1},[]),
+ {dir, In3};
+ _ ->
+ %% FileInfo = local_file_header_to_file_info(LH)
+ %%{Out, In4, CRC, UncompSize} =
+ {Out, In4, CRC, _UncompSize} =
+ get_z_data(CompMethod, In3, FileName1,
+ CompSize, Input, Output, OpO, Z),
+ In5 = skip_z_data_descriptor(GPFlag, Input, In4),
+ %% TODO This should be fixed some day:
+ %% In5 = Input({set_file_info, FileName,
+ %% FileInfo#file_info{size=UncompSize}}, In4),
+ FB(FileName),
+ CRC =:= CRC32 orelse throw({bad_crc, FileName}),
+ {file, Out, In5}
+ end;
+ false ->
+ {ignore, In3}
end;
_ ->
throw(bad_local_file_header)
end.
+%% make sure FileName doesn't have relative path that points over CWD
+check_valid_location(CWD, FileName) ->
+ %% check for directory traversal exploit
+ case check_dir_level(filename:split(FileName), 0) of
+ {FileOrDir,Level} when Level < 0 ->
+ CWD1 = if CWD == "" -> "./";
+ true -> CWD
+ end,
+ error_logger:format("Illegal path: ~ts, extracting in ~ts~n",
+ [add_cwd(CWD,FileName),CWD1]),
+ {false,add_cwd(CWD, FileOrDir)};
+ _ ->
+ {true,add_cwd(CWD, FileName)}
+ end.
+
+check_dir_level([FileOrDir], Level) ->
+ {FileOrDir,Level};
+check_dir_level(["." | Parts], Level) ->
+ check_dir_level(Parts, Level);
+check_dir_level([".." | Parts], Level) ->
+ check_dir_level(Parts, Level-1);
+check_dir_level([_Dir | Parts], Level) ->
+ check_dir_level(Parts, Level+1).
get_file_name_extra(FileNameLen, ExtraLen, B) ->
case B of
@@ -1534,20 +1566,6 @@ dos_date_time_from_datetime({{Year, Month, Day}, {Hour, Min, Sec}}) ->
<<DosDate:16>> = <<YearFrom1980:7, Month:4, Day:5>>,
{DosDate, DosTime}.
-unix_extra_field_and_var_from_bin(<<TSize:16/little,
- ATime:32/little,
- MTime:32/little,
- UID:16/little,
- GID:16/little,
- Var:TSize/binary>>) ->
- {#unix_extra_field{atime = ATime,
- mtime = MTime,
- uid = UID,
- gid = GID},
- Var};
-unix_extra_field_and_var_from_bin(_) ->
- throw(bad_unix_extra_field).
-
%% A pwrite-like function for iolists (used by memory-option)
pwrite_binary(B, Pos, Bin) when byte_size(B) =:= Pos ->
diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile
index 28c35aed55..72211332e9 100644
--- a/lib/stdlib/test/Makefile
+++ b/lib/stdlib/test/Makefile
@@ -52,6 +52,7 @@ MODULES= \
io_proto_SUITE \
lists_SUITE \
log_mf_h_SUITE \
+ math_SUITE \
ms_transform_SUITE \
proc_lib_SUITE \
qlc_SUITE \
@@ -83,6 +84,7 @@ MODULES= \
timer_SUITE \
timer_simple_SUITE \
unicode_SUITE \
+ unicode_util_SUITE \
win32reg_SUITE \
y2k_SUITE \
select_SUITE \
diff --git a/lib/stdlib/test/base64_SUITE.erl b/lib/stdlib/test/base64_SUITE.erl
index 9176a3664a..48b3f5f959 100644
--- a/lib/stdlib/test/base64_SUITE.erl
+++ b/lib/stdlib/test/base64_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -23,9 +23,7 @@
-include_lib("common_test/include/ct.hrl").
%% Test server specific exports
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2,
- init_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0, groups/0, group/1]).
%% Test cases must be exported.
-export([base64_encode/1, base64_decode/1, base64_otp_5635/1,
@@ -33,41 +31,26 @@
mime_decode_to_string/1,
roundtrip_1/1, roundtrip_2/1, roundtrip_3/1, roundtrip_4/1]).
-init_per_testcase(_, Config) ->
- Config.
-
-end_per_testcase(_, _Config) ->
- ok.
-
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
+
suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap,{minutes,4}}].
-all() ->
+all() ->
[base64_encode, base64_decode, base64_otp_5635,
base64_otp_6279, big, illegal, mime_decode, mime_decode_to_string,
{group, roundtrip}].
-groups() ->
+groups() ->
[{roundtrip, [parallel],
[roundtrip_1, roundtrip_2, roundtrip_3, roundtrip_4]}].
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
+group(roundtrip) ->
+ %% valgrind needs a lot of time
+ [{timetrap,{minutes,10}}].
%%-------------------------------------------------------------------------
%% Test base64:encode/1.
@@ -78,9 +61,9 @@ base64_encode(Config) when is_list(Config) ->
%% One pad
<<"SGVsbG8gV29ybGQ=">> = base64:encode(<<"Hello World">>),
%% No pad
- "QWxhZGRpbjpvcGVuIHNlc2Ft" =
+ "QWxhZGRpbjpvcGVuIHNlc2Ft" =
base64:encode_to_string("Aladdin:open sesam"),
-
+
"MDEyMzQ1Njc4OSFAIzBeJiooKTs6PD4sLiBbXXt9" =
base64:encode_to_string(<<"0123456789!@#0^&*();:<>,. []{}">>),
ok.
@@ -93,13 +76,13 @@ base64_decode(Config) when is_list(Config) ->
%% One pad
<<"Hello World">> = base64:decode(<<"SGVsbG8gV29ybGQ=">>),
%% No pad
- <<"Aladdin:open sesam">> =
+ <<"Aladdin:open sesam">> =
base64:decode("QWxhZGRpbjpvcGVuIHNlc2Ft"),
Alphabet = list_to_binary(lists:seq(0, 255)),
Alphabet = base64:decode(base64:encode(Alphabet)),
- %% Encoded base 64 strings may be devided by non base 64 chars.
+ %% Encoded base 64 strings may be divided by non base 64 chars.
%% In this cases whitespaces.
"0123456789!@#0^&*();:<>,. []{}" =
base64:decode_to_string(
@@ -208,7 +191,7 @@ mime_decode_to_string(Config) when is_list(Config) ->
%% One pad to ignore, followed by more text
"Hello World!!" = base64:mime_decode_to_string(<<"SGVsb)(G8gV29ybGQ=h IQ= =">>),
%% No pad
- "Aladdin:open sesam" =
+ "Aladdin:open sesam" =
base64:mime_decode_to_string("QWxhZGRpbjpvcG¤\")(VuIHNlc2Ft"),
%% Encoded base 64 strings may be divided by non base 64 chars.
%% In this cases whitespaces.
@@ -314,7 +297,7 @@ interleaved_ws_roundtrip_1([], Base64List, Bin, List) ->
random_byte_list(0, Acc) ->
Acc;
-random_byte_list(N, Acc) ->
+random_byte_list(N, Acc) ->
random_byte_list(N-1, [rand:uniform(255)|Acc]).
make_big_binary(N) ->
diff --git a/lib/stdlib/test/beam_lib_SUITE.erl b/lib/stdlib/test/beam_lib_SUITE.erl
index 4521ecc0ef..73219f8fd8 100644
--- a/lib/stdlib/test/beam_lib_SUITE.erl
+++ b/lib/stdlib/test/beam_lib_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -81,14 +81,12 @@ normal(Conf) when is_list(Conf) ->
NoOfTables = length(ets:all()),
P0 = pps(),
- CompileFlags = [{outdir,PrivDir}, debug_info],
- {ok,_} = compile:file(Source, CompileFlags),
- {ok, Binary} = file:read_file(BeamFile),
-
- do_normal(BeamFile),
- do_normal(Binary),
+ do_normal(Source, PrivDir, BeamFile, []),
+ do_normal(Source, PrivDir, BeamFile, [no_utf8_atoms]),
{ok,_} = compile:file(Source, [{outdir,PrivDir}, no_debug_info]),
+ {ok, {simple, [{debug_info, {debug_info_v1, erl_abstract_code, {none, _}}}]}} =
+ beam_lib:chunks(BeamFile, [debug_info]),
{ok, {simple, [{abstract_code, no_abstract_code}]}} =
beam_lib:chunks(BeamFile, [abstract_code]),
@@ -101,7 +99,15 @@ normal(Conf) when is_list(Conf) ->
true = (P0 == pps()),
ok.
-do_normal(BeamFile) ->
+do_normal(Source, PrivDir, BeamFile, Opts) ->
+ CompileFlags = [{outdir,PrivDir}, debug_info | Opts],
+ {ok,_} = compile:file(Source, CompileFlags),
+ {ok, Binary} = file:read_file(BeamFile),
+
+ do_normal(BeamFile, Opts),
+ do_normal(Binary, Opts).
+
+do_normal(BeamFile, Opts) ->
Imports = {imports, [{erlang, get_module_info, 1},
{erlang, get_module_info, 2},
{lists, member, 2}]},
@@ -126,24 +132,37 @@ do_normal(BeamFile) ->
{ok, {simple, [{labeled_locals, _LLocals}]}} =
beam_lib:chunks(BeamFile, [labeled_locals]),
{ok, {simple, [_Vsn]}} = beam_lib:version(BeamFile),
- {ok, {simple, [{abstract_code, _}]}} =
+ {ok, {simple, [{abstract_code, {_, _}}]}} =
beam_lib:chunks(BeamFile, [abstract_code]),
+ {ok, {simple, [{debug_info, {debug_info_v1, erl_abstract_code, _}}]}} =
+ beam_lib:chunks(BeamFile, [debug_info]),
%% Test reading optional chunks.
- All = ["Atom", "Code", "StrT", "ImpT", "ExpT", "FunT", "LitT"],
+ All = ["Atom", "Code", "StrT", "ImpT", "ExpT", "FunT", "LitT", "AtU8"],
{ok,{simple,Chunks}} = beam_lib:chunks(BeamFile, All, [allow_missing_chunks]),
- verify_simple(Chunks).
+ case {verify_simple(Chunks),Opts} of
+ {{missing_chunk, AtomBin}, []} when is_binary(AtomBin) -> ok;
+ {{AtomBin, missing_chunk}, [no_utf8_atoms]} when is_binary(AtomBin) -> ok
+ end,
+
+ %% Make sure that reading the atom chunk works when the 'allow_missing_chunks'
+ %% option is used.
+ Some = ["Code",atoms,"ExpT","LitT"],
+ {ok,{simple,SomeChunks}} = beam_lib:chunks(BeamFile, Some, [allow_missing_chunks]),
+ [{"Code",<<_/binary>>},{atoms,[_|_]},{"ExpT",<<_/binary>>},{"LitT",missing_chunk}] =
+ SomeChunks.
-verify_simple([{"Atom", AtomBin},
+verify_simple([{"Atom", PlainAtomChunk},
{"Code", CodeBin},
{"StrT", StrBin},
{"ImpT", ImpBin},
{"ExpT", ExpBin},
{"FunT", missing_chunk},
- {"LitT", missing_chunk}])
- when is_binary(AtomBin), is_binary(CodeBin), is_binary(StrBin),
+ {"LitT", missing_chunk},
+ {"AtU8", AtU8Chunk}])
+ when is_binary(CodeBin), is_binary(StrBin),
is_binary(ImpBin), is_binary(ExpBin) ->
- ok.
+ {PlainAtomChunk, AtU8Chunk}.
%% Read invalid beam files.
error(Conf) when is_list(Conf) ->
@@ -182,11 +201,11 @@ error(Conf) when is_list(Conf) ->
LastChunk = last_chunk(Binary),
verify(chunk_too_big, beam_lib:chunks(Binary1, [LastChunk])),
Chunks = chunk_info(Binary),
- {value, {_, AbstractStart, _}} = lists:keysearch("Abst", 1, Chunks),
- {Binary2, _} = split_binary(Binary, AbstractStart),
- verify(chunk_too_big, beam_lib:chunks(Binary2, ["Abst"])),
- {Binary3, _} = split_binary(Binary, AbstractStart-4),
- verify(invalid_beam_file, beam_lib:chunks(Binary3, ["Abst"])),
+ {value, {_, DebugInfoStart, _}} = lists:keysearch("Dbgi", 1, Chunks),
+ {Binary2, _} = split_binary(Binary, DebugInfoStart),
+ verify(chunk_too_big, beam_lib:chunks(Binary2, ["Dbgi"])),
+ {Binary3, _} = split_binary(Binary, DebugInfoStart-4),
+ verify(invalid_beam_file, beam_lib:chunks(Binary3, ["Dbgi"])),
%% Instead of the 5:32 field below, there used to be control characters
%% (including zero bytes) directly in the string. Because inferior programs
@@ -211,9 +230,9 @@ last_chunk(Bin) ->
do_error(BeamFile, ACopy) ->
%% evil tests
Chunks = chunk_info(BeamFile),
- {value, {_, AtomStart, _}} = lists:keysearch("Atom", 1, Chunks),
+ {value, {_, AtomStart, _}} = lists:keysearch("AtU8", 1, Chunks),
{value, {_, ImportStart, _}} = lists:keysearch("ImpT", 1, Chunks),
- {value, {_, AbstractStart, _}} = lists:keysearch("Abst", 1, Chunks),
+ {value, {_, DebugInfoStart, _}} = lists:keysearch("Dbgi", 1, Chunks),
{value, {_, AttributesStart, _}} =
lists:keysearch("Attr", 1, Chunks),
{value, {_, CompileInfoStart, _}} =
@@ -223,9 +242,9 @@ do_error(BeamFile, ACopy) ->
verify(invalid_chunk, beam_lib:chunks(BF2, [imports])),
BF3 = set_byte(ACopy, BeamFile, AtomStart-6, 17),
verify(missing_chunk, beam_lib:chunks(BF3, [imports])),
- BF4 = set_byte(ACopy, BeamFile, AbstractStart+10, 17),
- verify(invalid_chunk, beam_lib:chunks(BF4, [abstract_code])),
- BF5 = set_byte(ACopy, BeamFile, AttributesStart+10, 17),
+ BF4 = set_byte(ACopy, BeamFile, DebugInfoStart+10, 17),
+ verify(invalid_chunk, beam_lib:chunks(BF4, [debug_info])),
+ BF5 = set_byte(ACopy, BeamFile, AttributesStart+8, 17),
verify(invalid_chunk, beam_lib:chunks(BF5, [attributes])),
BF6 = set_byte(ACopy, BeamFile, 1, 17),
@@ -234,9 +253,9 @@ do_error(BeamFile, ACopy) ->
verify(not_a_beam_file, beam_lib:info(BF7)),
BF8 = set_byte(ACopy, BeamFile, 13, 17),
- verify(missing_chunk, beam_lib:chunks(BF8, ["Atom"])),
+ verify(missing_chunk, beam_lib:chunks(BF8, ["AtU8"])),
- BF9 = set_byte(ACopy, BeamFile, CompileInfoStart+10, 17),
+ BF9 = set_byte(ACopy, BeamFile, CompileInfoStart+8, 17),
verify(invalid_chunk, beam_lib:chunks(BF9, [compile_info])).
@@ -535,11 +554,11 @@ encrypted_abstr_1(Conf) ->
ok.
do_encrypted_abstr(Beam, Key) ->
- verify(key_missing_or_invalid, beam_lib:chunks(Beam, [abstract_code])),
+ verify(key_missing_or_invalid, beam_lib:chunks(Beam, [debug_info])),
- %% The raw chunk "Abst" can still be read even without a key.
- {ok,{simple,[{"Abst",Abst}]}} = beam_lib:chunks(Beam, ["Abst"]),
- <<0:8,8:8,"des3_cbc",_/binary>> = Abst,
+ %% The raw chunk "Dbgi" can still be read even without a key.
+ {ok,{simple,[{"Dbgi",Dbgi}]}} = beam_lib:chunks(Beam, ["Dbgi"]),
+ <<0:8,8:8,"des3_cbc",_/binary>> = Dbgi,
%% Try som invalid funs.
bad_fun(badfun, fun() -> ok end),
@@ -570,7 +589,7 @@ do_encrypted_abstr(Beam, Key) ->
{ok,_} = beam_lib:clear_crypto_key_fun(),
ok = beam_lib:crypto_key_fun(simple_crypto_fun(Key)),
verify_abstract(Beam),
- {ok,{simple,[{"Abst",Abst}]}} = beam_lib:chunks(Beam, ["Abst"]),
+ {ok,{simple,[{"Dbgi",Dbgi}]}} = beam_lib:chunks(Beam, ["Dbgi"]),
%% Installing a new key fun is not possible without clearing the old.
verify(exists, beam_lib:crypto_key_fun(ets_crypto_fun(Key))),
@@ -579,7 +598,7 @@ do_encrypted_abstr(Beam, Key) ->
{ok,_} = beam_lib:clear_crypto_key_fun(),
ok = beam_lib:crypto_key_fun(ets_crypto_fun(Key)),
verify_abstract(Beam),
- {ok,{simple,[{"Abst",Abst}]}} = beam_lib:chunks(Beam, ["Abst"]),
+ {ok,{simple,[{"Dbgi",Dbgi}]}} = beam_lib:chunks(Beam, ["Dbgi"]),
{ok,cleared} = beam_lib:clear_crypto_key_fun(),
@@ -602,10 +621,10 @@ bad_fun(F) ->
bad_fun(S, F) ->
verify(S, beam_lib:crypto_key_fun(F)).
-
verify_abstract(Beam) ->
- {ok,{simple,[Chunk]}} = beam_lib:chunks(Beam, [abstract_code]),
- {abstract_code,{raw_abstract_v1,_}} = Chunk.
+ {ok,{simple,[Abst, Dbgi]}} = beam_lib:chunks(Beam, [abstract_code, debug_info]),
+ {abstract_code,{raw_abstract_v1,_}} = Abst,
+ {debug_info,{debug_info_v1,erl_abstract_code,_}} = Dbgi.
simple_crypto_fun(Key) ->
fun(init) -> ok;
diff --git a/lib/stdlib/test/dets_SUITE.erl b/lib/stdlib/test/dets_SUITE.erl
index 8948f496c4..d667bd82a2 100644
--- a/lib/stdlib/test/dets_SUITE.erl
+++ b/lib/stdlib/test/dets_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -35,26 +35,18 @@
-endif.
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2,
- newly_started/1, basic_v8/1, basic_v9/1,
- open_v8/1, open_v9/1, sets_v8/1, sets_v9/1, bags_v8/1,
- bags_v9/1, duplicate_bags_v8/1, duplicate_bags_v9/1,
- access_v8/1, access_v9/1, dirty_mark/1, dirty_mark2/1,
- bag_next_v8/1, bag_next_v9/1, oldbugs_v8/1, oldbugs_v9/1,
- unsafe_assumptions/1, truncated_segment_array_v8/1,
- truncated_segment_array_v9/1, open_file_v8/1, open_file_v9/1,
- init_table_v8/1, init_table_v9/1, repair_v8/1, repair_v9/1,
- hash_v8b_v8c/1, phash/1, fold_v8/1, fold_v9/1, fixtable_v8/1,
- fixtable_v9/1, match_v8/1, match_v9/1, select_v8/1,
- select_v9/1, update_counter/1, badarg/1, cache_sets_v8/1,
- cache_sets_v9/1, cache_bags_v8/1, cache_bags_v9/1,
- cache_duplicate_bags_v8/1, cache_duplicate_bags_v9/1,
+ init_per_group/2,end_per_group/2, newly_started/1, basic/1,
+ open/1, sets/1, bags/1, duplicate_bags/1, access/1, dirty_mark/1,
+ dirty_mark2/1, bag_next/1, oldbugs/1,
+ truncated_segment_array/1, open_file/1, init_table/1, repair/1,
+ phash/1, fold/1, fixtable/1, match/1, select/1, update_counter/1,
+ badarg/1, cache_sets/1, cache_bags/1, cache_duplicate_bags/1,
otp_4208/1, otp_4989/1, many_clients/1, otp_4906/1, otp_5402/1,
simultaneous_open/1, insert_new/1, repair_continuation/1,
otp_5487/1, otp_6206/1, otp_6359/1, otp_4738/1, otp_7146/1,
otp_8070/1, otp_8856/1, otp_8898/1, otp_8899/1, otp_8903/1,
otp_8923/1, otp_9282/1, otp_11245/1, otp_11709/1, otp_13229/1,
- otp_13260/1]).
+ otp_13260/1, otp_13830/1]).
-export([dets_dirty_loop/0]).
@@ -73,8 +65,7 @@
-define(DETS_SERVER, dets).
-%% HEADSZ taken from dets_v8.erl and dets_v9.erl.
--define(HEADSZ_v8, 40).
+%% HEADSZ taken from dets_v9.erl.
-define(HEADSZ_v9, (56+28*4+16)).
-define(NO_KEYS_POS_v9, 36).
-define(CLOSED_PROPERLY_POS, 8).
@@ -94,24 +85,16 @@ suite() ->
all() ->
[
- basic_v8, basic_v9, open_v8, open_v9, sets_v8, sets_v9,
- bags_v8, bags_v9, duplicate_bags_v8, duplicate_bags_v9,
- newly_started, open_file_v8, open_file_v9,
- init_table_v8, init_table_v9, repair_v8, repair_v9,
- access_v8, access_v9, oldbugs_v8, oldbugs_v9,
- unsafe_assumptions, truncated_segment_array_v8,
- truncated_segment_array_v9, dirty_mark, dirty_mark2,
- bag_next_v8, bag_next_v9, hash_v8b_v8c, phash, fold_v8,
- fold_v9, fixtable_v8, fixtable_v9, match_v8, match_v9,
- select_v8, select_v9, update_counter, badarg,
- cache_sets_v8, cache_sets_v9, cache_bags_v8,
- cache_bags_v9, cache_duplicate_bags_v8,
- cache_duplicate_bags_v9, otp_4208, otp_4989,
+ basic, open, sets, bags, duplicate_bags, newly_started, open_file,
+ init_table, repair, access, oldbugs,
+ truncated_segment_array, dirty_mark, dirty_mark2, bag_next,
+ phash, fold, fixtable, match, select, update_counter, badarg,
+ cache_sets, cache_bags, cache_duplicate_bags, otp_4208, otp_4989,
many_clients, otp_4906, otp_5402, simultaneous_open,
insert_new, repair_continuation, otp_5487, otp_6206,
otp_6359, otp_4738, otp_7146, otp_8070, otp_8856, otp_8898,
otp_8899, otp_8903, otp_8923, otp_9282, otp_11245, otp_11709,
- otp_13229, otp_13260
+ otp_13229, otp_13260, otp_13830
].
groups() ->
@@ -137,20 +120,12 @@ newly_started(Config) when is_list(Config) ->
test_server:stop_node(Node),
ok.
-%% Basic test case.
-basic_v8(Config) when is_list(Config) ->
- basic(Config, 8).
-
-%% Basic test case.
-basic_v9(Config) when is_list(Config) ->
- basic(Config, 9).
-
-basic(Config, Version) ->
+basic(Config) when is_list(Config) ->
Tab = dets_basic_test,
FName = filename(Tab, Config),
P0 = pps(),
- {ok, _} = dets:open_file(Tab,[{file, FName},{version,Version}]),
+ {ok, _} = dets:open_file(Tab,[{file, FName}]),
ok = dets:insert(Tab,{mazda,japan}),
ok = dets:insert(Tab,{toyota,japan}),
ok = dets:insert(Tab,{suzuki,japan}),
@@ -174,13 +149,7 @@ basic(Config, Version) ->
ok.
-open_v8(Config) when is_list(Config) ->
- open(Config, 8).
-
-open_v9(Config) when is_list(Config) ->
- open(Config, 9).
-
-open(Config, Version) ->
+open(Config) when is_list(Config) ->
%% Running this test twice means that the Dets server is restarted
%% twice. dets_sup specifies a maximum of 4 restarts in an hour.
%% If this becomes a problem, one should consider running this
@@ -194,14 +163,14 @@ open(Config, Version) ->
Data = make_data(1),
P0 = pps(),
- Tabs = open_files(1, All, Version),
+ Tabs = open_files(1, All),
initialize(Tabs, Data),
check(Tabs, Data),
foreach(fun(Tab) -> ok = dets:close(Tab) end, Tabs),
%% Now reopen the files
?format("Reopening closed files \n", []),
- Tabs = open_files(1, All, Version),
+ Tabs = open_files(1, All),
?format("Checking contents of reopened files \n", []),
check(Tabs, Data),
%% crash the dets server
@@ -216,7 +185,7 @@ open(Config, Version) ->
%% Now reopen the files again
?format("Reopening crashed files \n", []),
- open_files(1, All, Version),
+ open_files(1, All),
?format("Checking contents of repaired files \n", []),
check(Tabs, Data),
@@ -266,20 +235,13 @@ bad(_Tab, _Item) ->
exit(badtab).
%% Perform traversal and match testing on set type dets tables.
-sets_v8(Config) when is_list(Config) ->
- sets(Config, 8).
-
-%% Perform traversal and match testing on set type dets tables.
-sets_v9(Config) when is_list(Config) ->
- sets(Config, 9).
-
-sets(Config, Version) ->
+sets(Config) when is_list(Config) ->
{Sets, _, _} = args(Config),
Data = make_data(1),
delete_files(Sets),
P0 = pps(),
- Tabs = open_files(1, Sets, Version),
+ Tabs = open_files(1, Sets),
Bigger = [{17,q,w,w}, {48,q,w,w,w,w,w,w}], % 48 requires a bigger buddy
initialize(Tabs, Data++Bigger++Data), % overwrite
Len = length(Data),
@@ -302,19 +264,12 @@ sets(Config, Version) ->
ok.
%% Perform traversal and match testing on bag type dets tables.
-bags_v8(Config) when is_list(Config) ->
- bags(Config, 8).
-
-%% Perform traversal and match testing on bag type dets tables.
-bags_v9(Config) when is_list(Config) ->
- bags(Config, 9).
-
-bags(Config, Version) ->
+bags(Config) when is_list(Config) ->
{_, Bags, _} = args(Config),
Data = make_data(1, bag), %% gives twice as many objects
delete_files(Bags),
P0 = pps(),
- Tabs = open_files(1, Bags, Version),
+ Tabs = open_files(1, Bags),
initialize(Tabs, Data++Data),
Len = length(Data),
foreach(fun(Tab) -> trav_test(Data, Len, Tab) end, Tabs),
@@ -336,19 +291,12 @@ bags(Config, Version) ->
%% Perform traversal and match testing on duplicate_bag type dets tables.
-duplicate_bags_v8(Config) when is_list(Config) ->
- duplicate_bags(Config, 8).
-
-%% Perform traversal and match testing on duplicate_bag type dets tables.
-duplicate_bags_v9(Config) when is_list(Config) ->
- duplicate_bags(Config, 9).
-
-duplicate_bags(Config, Version) when is_list(Config) ->
+duplicate_bags(Config) when is_list(Config) ->
{_, _, Dups} = args(Config),
Data = make_data(1, duplicate_bag), %% gives twice as many objects
delete_files(Dups),
P0 = pps(),
- Tabs = open_files(1, Dups, Version),
+ Tabs = open_files(1, Dups),
initialize(Tabs, Data),
Len = length(Data),
foreach(fun(Tab) -> trav_test(Data, Len, Tab) end, Tabs),
@@ -369,13 +317,7 @@ duplicate_bags(Config, Version) when is_list(Config) ->
ok.
-access_v8(Config) when is_list(Config) ->
- access(Config, 8).
-
-access_v9(Config) when is_list(Config) ->
- access(Config, 9).
-
-access(Config, Version) ->
+access(Config) when is_list(Config) ->
Args_acc = [[{ram_file, true}, {access, read}],
[{access, read}]],
Args = [[{ram_file, true}],
@@ -388,9 +330,9 @@ access(Config, Version) ->
P0 = pps(),
{error, {file_error,_,enoent}} = dets:open_file('1', hd(Args_acc_1)),
- Tabs = open_files(1, Args_1, Version),
+ Tabs = open_files(1, Args_1),
close_all(Tabs),
- Tabs = open_files(1, Args_acc_1, Version),
+ Tabs = open_files(1, Args_acc_1),
foreach(fun(Tab) ->
{error, {access_mode,_}} = dets:insert(Tab, {1,2}),
@@ -522,16 +464,12 @@ dets_dirty_loop() ->
%% Check that bags and next work as expected.
-bag_next_v8(Config) when is_list(Config) ->
- bag_next(Config, 8).
-
-%% Check that bags and next work as expected.
-bag_next_v9(Config) when is_list(Config) ->
+bag_next(Config) when is_list(Config) ->
Tab = dets_bag_next_test,
FName = filename(Tab, Config),
%% first and next crash upon error
- dets:open_file(Tab,[{file, FName}, {type, bag},{version,9}]),
+ dets:open_file(Tab,[{file, FName}, {type, bag}]),
ok = dets:insert(Tab, [{1,1},{2,2},{3,3},{4,4}]),
FirstKey = dets:first(Tab),
NextKey = dets:next(Tab, FirstKey),
@@ -548,13 +486,8 @@ bag_next_v9(Config) when is_list(Config) ->
dets:close(Tab),
file:delete(FName),
- bag_next(Config, 9).
-
-bag_next(Config, Version) ->
- Tab = dets_bag_next_test,
- FName = filename(Tab, Config),
P0 = pps(),
- dets:open_file(Tab,[{file, FName}, {type, bag},{version,Version}]),
+ dets:open_file(Tab,[{file, FName}, {type, bag}]),
dets:insert(Tab,{698,hopp}),
dets:insert(Tab,{186,hopp}),
dets:insert(Tab,{hej,hopp}),
@@ -578,17 +511,10 @@ bag_next(Config, Version) ->
check_pps(P0),
ok.
-oldbugs_v8(Config) when is_list(Config) ->
- oldbugs(Config, 8).
-
-oldbugs_v9(Config) when is_list(Config) ->
- oldbugs(Config, 9).
-
-oldbugs(Config, Version) ->
+oldbugs(Config) when is_list(Config) ->
FName = filename(dets_suite_oldbugs_test, Config),
P0 = pps(),
- {ok, ob} = dets:open_file(ob, [{version, Version},
- {type, bag}, {file, FName}]),
+ {ok, ob} = dets:open_file(ob, [{type, bag}, {file, FName}]),
ok = dets:insert(ob, {1, 2}),
ok = dets:insert(ob, {1,3}),
ok = dets:insert(ob, {1, 2}),
@@ -598,56 +524,19 @@ oldbugs(Config, Version) ->
check_pps(P0),
ok.
-%% Test that shrinking an object and then expanding it works.
-unsafe_assumptions(Config) when is_list(Config) ->
- FName = filename(dets_suite_unsafe_assumptions_test, Config),
- file:delete(FName),
- P0 = pps(),
- {ok, a} = dets:open_file(a, [{version,8},{file, FName}]),
- O0 = {2,false},
- O1 = {1, false},
- O2 = {1, true},
- O3 = {1, duplicate(20,false)},
- O4 = {1, duplicate(25,false)}, % same 2-log as O3
- ok = dets:insert(a, O1),
- ok = dets:insert(a, O0),
- true = [O1,O0] =:= sort(get_all_objects(a)),
- true = [O1,O0] =:= sort(get_all_objects_fast(a)),
- ok = dets:insert(a, O2),
- true = [O2,O0] =:= sort(get_all_objects(a)),
- true = [O2,O0] =:= sort(get_all_objects_fast(a)),
- ok = dets:insert(a, O3),
- true = [O3,O0] =:= sort(get_all_objects(a)),
- true = [O3,O0] =:= sort(get_all_objects_fast(a)),
- ok = dets:insert(a, O4),
- true = [O4,O0] =:= sort(get_all_objects(a)),
- true = [O4,O0] =:= sort(get_all_objects_fast(a)),
- ok = dets:close(a),
- file:delete(FName),
- check_pps(P0),
- ok.
-
-%% Test that a file where the segment array has been truncated
-%% is possible to repair.
-truncated_segment_array_v8(Config) when is_list(Config) ->
- trunc_seg_array(Config, 8).
-
%% Test that a file where the segment array has been truncated
%% is possible to repair.
-truncated_segment_array_v9(Config) when is_list(Config) ->
- trunc_seg_array(Config, 9).
-
-trunc_seg_array(Config, V) ->
+truncated_segment_array(Config) when is_list(Config) ->
TabRef = dets_suite_truncated_segment_array_test,
Fname = filename(TabRef, Config),
%% Create file that needs to be repaired
file:delete(Fname),
P0 = pps(),
- {ok, TabRef} = dets:open_file(TabRef, [{file, Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file, Fname}]),
ok = dets:close(TabRef),
%% Truncate the file
- HeadSize = headsz(V),
+ HeadSize = headsz(),
truncate(Fname, HeadSize + 10),
%% Open the truncated file
@@ -660,19 +549,13 @@ trunc_seg_array(Config, V) ->
ok.
%% Test open_file/1.
-open_file_v8(Config) when is_list(Config) ->
- open_1(Config, 8).
-
-%% Test open_file/1.
-open_file_v9(Config) when is_list(Config) ->
+open_file(Config) when is_list(Config) ->
T = open_v9,
Fname = filename(T, Config),
- {ok, _} = dets:open_file(T, [{file,Fname},{version,9}]),
- 9 = dets:info(T, version),
+ {ok, _} = dets:open_file(T, [{file,Fname}]),
+ 9 = dets:info(T, version), % Backwards compatibility.
true = [self()] =:= dets:info(T, users),
- {ok, _} = dets:open_file(T, [{file,Fname},{version,9}]),
- {error,incompatible_arguments} =
- dets:open_file(T, [{file,Fname},{version,8}]),
+ {ok, _} = dets:open_file(T, [{file,Fname}]),
true = [self(),self()] =:= dets:info(T, users),
ok = dets:close(T),
true = [self()] =:= dets:info(T, users),
@@ -680,9 +563,9 @@ open_file_v9(Config) when is_list(Config) ->
undefined = ets:info(T, users),
file:delete(Fname),
- open_1(Config, 9).
+ open_1(Config).
-open_1(Config, V) ->
+open_1(Config) ->
TabRef = open_file_1_test,
Fname = filename(TabRef, Config),
file:delete(Fname),
@@ -694,8 +577,8 @@ open_1(Config, V) ->
{error,{not_a_dets_file,Fname}} = dets:open_file(Fname),
file:delete(Fname),
- HeadSize = headsz(V),
- {ok, TabRef} = dets:open_file(TabRef, [{file, Fname},{version,V}]),
+ HeadSize = headsz(),
+ {ok, TabRef} = dets:open_file(TabRef, [{file, Fname}]),
ok = dets:close(TabRef),
truncate(Fname, HeadSize + 10),
true = dets:is_dets_file(Fname),
@@ -705,7 +588,7 @@ open_1(Config, V) ->
file:delete(Fname),
%% truncated file header, invalid type
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = ins(TabRef, 3000),
ok = dets:close(TabRef),
TypePos = 12,
@@ -714,7 +597,7 @@ open_1(Config, V) ->
truncate(Fname, HeadSize - 10),
{error,{not_a_dets_file,Fname}} = dets:open_file(Fname),
{error,{not_a_dets_file,Fname}} =
- dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ dets:open_file(TabRef, [{file,Fname}]),
file:delete(Fname),
{error,{file_error,{foo,bar},_}} = dets:is_dets_file({foo,bar}),
@@ -722,35 +605,30 @@ open_1(Config, V) ->
ok.
%% Test initialize_table/2 and from_ets/2.
-init_table_v8(Config) when is_list(Config) ->
- init_table(Config, 8).
-
-%% Test initialize_table/2 and from_ets/2.
-init_table_v9(Config) when is_list(Config) ->
+init_table(Config) when is_list(Config) ->
%% Objects are returned in "time order".
T = init_table_v9,
Fname = filename(T, Config),
file:delete(Fname),
L = [{1,a},{2,b},{1,c},{2,c},{1,c},{2,a},{1,b}],
Input = init([L]),
- {ok, _} = dets:open_file(T, [{file,Fname},{version,9},
- {type,duplicate_bag}]),
+ {ok, _} = dets:open_file(T, [{file,Fname},{type,duplicate_bag}]),
ok = dets:init_table(T, Input),
[{1,a},{1,c},{1,c},{1,b}] = dets:lookup(T, 1),
[{2,b},{2,c},{2,a}] = dets:lookup(T, 2),
ok = dets:close(T),
file:delete(Fname),
- init_table(Config, 9),
+ init_table_1(Config),
fast_init_table(Config).
-init_table(Config, V) ->
+init_table_1(Config) ->
TabRef = init_table_test,
Fname = filename(TabRef, Config),
file:delete(Fname),
P0 = pps(),
- Args = [{file,Fname},{version,V},{auto_save,120000}],
+ Args = [{file,Fname},{auto_save,120000}],
{ok, _} = dets:open_file(TabRef, Args),
{'EXIT', _} =
(catch dets:init_table(TabRef, fun(foo) -> bar end)),
@@ -800,13 +678,13 @@ init_table(Config, V) ->
file:delete(Fname),
L1 = [[{1,a},{2,b}],[],[{3,c}],[{4,d}],[]],
- bulk_init(L1, set, 4, Config, V),
+ bulk_init(L1, set, 4, Config),
L2 = [[{1,a},{2,b}],[],[{2,q},{3,c}],[{4,d}],[{4,e},{2,q}]],
- bulk_init(L2, set, 4, Config, V),
- bulk_init(L2, bag, 6, Config, V),
- bulk_init(L2, duplicate_bag, 7, Config, V),
- bulk_init(L1, set, 4, 512, Config, V),
- bulk_init([], set, 0, 10000, Config, V),
+ bulk_init(L2, set, 4, Config),
+ bulk_init(L2, bag, 6, Config),
+ bulk_init(L2, duplicate_bag, 7, Config),
+ bulk_init(L1, set, 4, 512, Config),
+ bulk_init([], set, 0, 10000, Config),
file:delete(Fname),
%% Initiate a file that contains a lot of objects.
@@ -834,16 +712,16 @@ init_table(Config, V) ->
check_pps(P0),
ok.
-bulk_init(Ls, Type, N, Config, V) ->
- bulk_init(Ls, Type, N, 256, Config, V).
+bulk_init(Ls, Type, N, Config) ->
+ bulk_init(Ls, Type, N, 256, Config).
-bulk_init(Ls, Type, N, Est, Config, V) ->
+bulk_init(Ls, Type, N, Est, Config) ->
T = init_table_test,
Fname = filename(T, Config),
file:delete(Fname),
Input = init(Ls),
Args = [{ram_file,false}, {type,Type},{keypos,1},{file,Fname},
- {estimated_no_objects, Est},{version,V}],
+ {estimated_no_objects, Est}],
{ok, T} = dets:open_file(T, Args),
ok = dets:init_table(T, Input),
All = sort(get_all_objects(T)),
@@ -882,18 +760,17 @@ init_fun(I, N) ->
end.
fast_init_table(Config) ->
- V = 9,
TabRef = init_table_test,
Fname = filename(TabRef, Config),
file:delete(Fname),
P0 = pps(),
- Args = [{file,Fname},{version,V},{auto_save,120000}],
+ Args = [{file,Fname},{auto_save,120000}],
Source = init_table_test_source,
SourceFname = filename(Source, Config),
file:delete(SourceFname),
- SourceArgs = [{file,SourceFname},{version,V},{auto_save,120000}],
+ SourceArgs = [{file,SourceFname},{auto_save,120000}],
{ok, Source} = dets:open_file(Source, SourceArgs),
@@ -1015,13 +892,13 @@ fast_init_table(Config) ->
file:delete(SourceFname),
L1 = [{1,a},{2,b},{3,c},{4,d}],
- fast_bulk_init(L1, set, 4, 4, Config, V),
+ fast_bulk_init(L1, set, 4, 4, Config),
L2 = [{1,a},{2,b},{2,q},{3,c},{4,d},{4,e},{2,q}],
- fast_bulk_init(L2, set, 4, 4, Config, V),
- fast_bulk_init(L2, bag, 6, 4, Config, V),
- fast_bulk_init(L2, duplicate_bag, 7, 4, Config, V),
- fast_bulk_init(L1, set, 4, 4, 512, Config, V),
- fast_bulk_init([], set, 0, 0, 10000, Config, V),
+ fast_bulk_init(L2, set, 4, 4, Config),
+ fast_bulk_init(L2, bag, 6, 4, Config),
+ fast_bulk_init(L2, duplicate_bag, 7, 4, Config),
+ fast_bulk_init(L1, set, 4, 4, 512, Config),
+ fast_bulk_init([], set, 0, 0, 10000, Config),
file:delete(Fname),
%% Initiate a file that contains a lot of objects.
@@ -1112,16 +989,16 @@ fast_init_table(Config) ->
check_pps(P0),
ok.
-fast_bulk_init(L, Type, N, NoKeys, Config, V) ->
- fast_bulk_init(L, Type, N, NoKeys, 256, Config, V).
+fast_bulk_init(L, Type, N, NoKeys, Config) ->
+ fast_bulk_init(L, Type, N, NoKeys, 256, Config).
-fast_bulk_init(L, Type, N, NoKeys, Est, Config, V) ->
+fast_bulk_init(L, Type, N, NoKeys, Est, Config) ->
T = init_table_test,
Fname = filename(T, Config),
file:delete(Fname),
Args0 = [{ram_file,false}, {type,Type},{keypos,1},
- {estimated_no_objects, Est},{version,V}],
+ {estimated_no_objects, Est}],
Args = [{file,Fname} | Args0],
S = init_table_test_source,
SFname = filename(S, Config),
@@ -1189,35 +1066,7 @@ items(I, N, C, L) ->
items(I+1, N, C-1, [{I, item(I)} | L]).
%% Test open_file and repair.
-repair_v8(Config) when is_list(Config) ->
- repair(Config, 8).
-
-%% Test open_file and repair.
-repair_v9(Config) when is_list(Config) ->
- %% Convert from format 9 to format 8.
- T = convert_98,
- Fname = filename(T, Config),
- file:delete(Fname),
- {ok, _} = dets:open_file(T, [{file,Fname},{version,9},
- {type,duplicate_bag}]),
- 9 = dets:info(T, version),
- true = is_binary(dets:info(T, bchunk_format)),
- ok = dets:insert(T, [{1,a},{2,b},{1,c},{2,c},{1,c},{2,a},{1,b}]),
- dets:close(T),
- {error, {version_mismatch, _}} =
- dets:open_file(T, [{file,Fname},{version,8},{type,duplicate_bag}]),
- {ok, _} = dets:open_file(T, [{file,Fname},{version,8},
- {type,duplicate_bag},{repair,force}]),
- 8 = dets:info(T, version),
- true = undefined =:= dets:info(T, bchunk_format),
- [{1,a},{1,b},{1,c},{1,c}] = sort(dets:lookup(T, 1)),
- [{2,a},{2,b},{2,c}] = sort(dets:lookup(T, 2)),
- 7 = dets:info(T, no_objects),
- no_keys_test(T),
- _ = histogram(T, silent),
- ok = dets:close(T),
- file:delete(Fname),
-
+repair(Config) when is_list(Config) ->
%% The short lived format 9(a).
%% Not very throughly tested here.
A9 = a9,
@@ -1238,13 +1087,13 @@ repair_v9(Config) when is_list(Config) ->
ok = dets:close(A9),
file:delete(Version9aT),
- repair(Config, 9).
+ repair_1(Config).
-repair(Config, V) ->
+repair_1(Config) ->
TabRef = repair_test,
Fname = filename(TabRef, Config),
file:delete(Fname),
- HeadSize = headsz(V),
+ HeadSize = headsz(),
P0 = pps(),
{'EXIT', {badarg, _}} =
@@ -1255,7 +1104,7 @@ repair(Config, V) ->
dets:open_file(TabRef, [{file, Fname}, {access, read}]),
%% compacting, and some kind of test that free lists are saved OK on file
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
0 = dets:info(TabRef, size),
ok = ins(TabRef, 30000),
ok = del(TabRef, 30000, 3),
@@ -1268,38 +1117,20 @@ repair(Config, V) ->
20000 = count_objects_quite_fast(Ref3), % actually a test of match
no_keys_test(Ref3),
ok = dets:close(Ref3),
- if
- V =:= 8 ->
- {ok, TabRef} = dets:open_file(TabRef,
- [{file, Fname},{version,V},{access,read}]),
- ok = dets:close(TabRef),
- io:format("Expect compacting repair:~n"),
- {ok, TabRef} = dets:open_file(TabRef,
- [{file, Fname},{version,V}]),
- 20000 = dets:info(TabRef, size),
- _ = histogram(TabRef, silent),
- ok = dets:close(TabRef);
- true ->
- ok
- end,
{error,{keypos_mismatch,Fname}} =
dets:open_file(TabRef, [{file, Fname},{keypos,17}]),
{error,{type_mismatch,Fname}} =
dets:open_file(TabRef, [{file, Fname},{type,duplicate_bag}]),
%% make one of the temporary files unwritable
- TmpFile = if
- V =:= 8 ->
- Fname ++ ".TMP.10000";
- true -> Fname ++ ".TMP.1"
- end,
+ TmpFile = Fname ++ ".TMP.1",
file:delete(TmpFile),
{ok, TmpFd} = file:open(TmpFile, [read,write]),
ok = file:close(TmpFd),
unwritable(TmpFile),
- {error,{file_error,TmpFile,eacces}} = dets:fsck(Fname, V),
+ {error,{file_error,TmpFile,eacces}} = dets:fsck(Fname),
{ok, _} = dets:open_file(TabRef,
- [{repair,false},{file, Fname},{version,V}]),
+ [{repair,false},{file, Fname}]),
20000 = length(get_all_objects(TabRef)),
_ = histogram(TabRef, silent),
20000 = length(get_all_objects_fast(TabRef)),
@@ -1318,68 +1149,15 @@ repair(Config, V) ->
file:delete(Fname),
%% truncated file header
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = ins(TabRef, 100),
ok = dets:close(TabRef),
file:delete(Fname),
- %% version bump (v8)
- Version7S = filename:join(?datadir(Config), "version_r2d.dets"),
- Version7T = filename('v2.dets', Config),
- {ok, _} = file:copy(Version7S, Version7T),
- {error,{version_bump, Version7T}} = dets:open_file(Version7T),
- {error,{version_bump, Version7T}} =
- dets:open_file(Version7T, [{file,Version7T},{repair,false}]),
- {error,{version_bump, Version7T}} =
- dets:open_file(Version7T, [{file, Version7T}, {access, read}]),
- io:format("Expect upgrade:~n"),
- {ok, _} = dets:open_file(Version7T,
- [{file, Version7T},{version, V}]),
- [{1,a},{2,b}] = sort(get_all_objects(Version7T)),
- [{1,a},{2,b}] = sort(get_all_objects_fast(Version7T)),
- Phash = if
- V =:= 8 -> phash;
- true -> phash2
- end,
- Phash = dets:info(Version7T, hash),
- _ = histogram(Version7T, silent),
- ok = dets:close(Version7T),
- {ok, _} = dets:open_file(Version7T, [{file, Version7T}]),
- Phash = dets:info(Version7T, hash),
- ok = dets:close(Version7T),
- file:delete(Version7T),
-
- %% converting free lists
- Version8aS = filename:join(?datadir(Config), "version_r3b02.dets"),
- Version8aT = filename('v3.dets', Config),
- {ok, _} = file:copy(Version8aS, Version8aT),
- %% min_no_slots and max_no_slots are ignored - no repair is taking place
- {ok, _} = dets:open_file(version_8a,
- [{file, Version8aT},{min_no_slots,1000},
- {max_no_slots,100000}]),
- [{1,b},{2,a},{a,1},{b,2}] = sort(get_all_objects(version_8a)),
- [{1,b},{2,a},{a,1},{b,2}] = sort(get_all_objects_fast(version_8a)),
- ok = ins(version_8a, 1000),
- 1002 = dets:info(version_8a, size),
- no_keys_test(version_8a),
- All8a = sort(get_all_objects(version_8a)),
- 1002 = length(All8a),
- FAll8a = sort(get_all_objects_fast(version_8a)),
- true = sort(All8a) =:= sort(FAll8a),
- ok = del(version_8a, 300, 3),
- 902 = dets:info(version_8a, size),
- no_keys_test(version_8a),
- All8a2 = sort(get_all_objects(version_8a)),
- 902 = length(All8a2),
- FAll8a2 = sort(get_all_objects_fast(version_8a)),
- true = sort(All8a2) =:= sort(FAll8a2),
- _ = histogram(version_8a, silent),
- ok = dets:close(version_8a),
- file:delete(Version8aT),
-
+ %% FIXME.
%% will fail unless the slots are properly sorted when repairing (v8)
BArgs = [{file, Fname},{type,duplicate_bag},
- {delayed_write,{3000,10000}},{version,V}],
+ {delayed_write,{3000,10000}}],
{ok, TabRef} = dets:open_file(TabRef, BArgs),
Seq = seq(1, 500),
Small = map(fun(X) -> {X,X} end, Seq),
@@ -1393,18 +1171,14 @@ repair(Config, V) ->
io:format("Expect forced repair:~n"),
{ok, _} =
dets:open_file(TabRef, [{repair,force},{min_no_slots,2000} | BArgs]),
- if
- V =:= 9 ->
- {MinNoSlots,_,MaxNoSlots} = dets:info(TabRef, no_slots),
- ok = dets:close(TabRef),
- io:format("Expect compaction:~n"),
- {ok, _} =
- dets:open_file(TabRef, [{repair,force},
- {min_no_slots,MinNoSlots},
- {max_no_slots,MaxNoSlots} | BArgs]);
- true ->
- ok
- end,
+
+ {MinNoSlots,_,MaxNoSlots} = dets:info(TabRef, no_slots),
+ ok = dets:close(TabRef),
+ io:format("Expect compaction:~n"),
+ {ok, _} =
+ dets:open_file(TabRef, [{repair,force},
+ {min_no_slots,MinNoSlots},
+ {max_no_slots,MaxNoSlots} | BArgs]),
All2 = get_all_objects(TabRef),
true = All =:= sort(All2),
FAll2 = get_all_objects_fast(TabRef),
@@ -1418,35 +1192,15 @@ repair(Config, V) ->
file:delete(Fname),
%% object bigger than segments, the "hole" is taken care of
- {ok, TabRef} = dets:open_file(TabRef, [{file, Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file, Fname}]),
Tuple = erlang:make_tuple(1000, foobar), % > 2 kB
ok = dets:insert(TabRef, Tuple),
%% at least one full segment (objects smaller than 2 kB):
ins(TabRef, 2000),
ok = dets:close(TabRef),
- if
- V =:= 8 ->
- %% first estimated number of objects is wrong, repair once more
- {ok, Fd} = file:open(Fname, [read,write]),
- NoPos = HeadSize - 8, % no_objects
- file:pwrite(Fd, NoPos, <<0:32>>), % NoItems
- ok = file:close(Fd),
- dets:fsck(Fname, V),
- {ok, _} =
- dets:open_file(TabRef,
- [{repair,false},{file, Fname},{version,V}]),
- 2001 = length(get_all_objects(TabRef)),
- _ = histogram(TabRef, silent),
- 2001 = length(get_all_objects_fast(TabRef)),
- ok = dets:close(TabRef);
- true ->
- ok
- end,
-
{ok, _} =
- dets:open_file(TabRef,
- [{repair,false},{file, Fname},{version,V}]),
+ dets:open_file(TabRef, [{repair,false},{file, Fname}]),
{ok, ObjPos} = dets:where(TabRef, {66,{item,number,66}}),
ok = dets:close(TabRef),
%% Damaged object.
@@ -1454,25 +1208,24 @@ repair(Config, V) ->
crash(Fname, ObjPos+Pos),
io:format(
"Expect forced repair (possibly after attempted compaction):~n"),
- {ok, _} =
- dets:open_file(TabRef, [{repair,force},{file, Fname},{version,V}]),
+ {ok, _} = dets:open_file(TabRef, [{repair,force},{file, Fname}]),
true = dets:info(TabRef, size) < 2001,
ok = dets:close(TabRef),
file:delete(Fname),
%% The file is smaller than the padded object.
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = dets:insert(TabRef, Tuple),
ok = dets:close(TabRef),
io:format("Expect forced repair or compaction:~n"),
{ok, _} =
- dets:open_file(TabRef, [{repair,force},{file, Fname},{version,V}]),
+ dets:open_file(TabRef, [{repair,force},{file, Fname}]),
true = 1 =:= dets:info(TabRef, size),
ok = dets:close(TabRef),
file:delete(Fname),
%% Damaged free lists.
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = ins(TabRef, 300),
ok = dets:sync(TabRef),
ok = del(TabRef, 300, 3),
@@ -1481,48 +1234,42 @@ repair(Config, V) ->
ok = dets:close(TabRef),
crash(Fname, FileSize+20),
%% Used to return bad_freelists, but that changed in OTP-9622
- {ok, TabRef} =
- dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = dets:close(TabRef),
file:delete(Fname),
%% File not closed, opening with read and read_write access tried.
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = ins(TabRef, 300),
ok = dets:close(TabRef),
crash(Fname, ?CLOSED_PROPERLY_POS+3, ?NOT_PROPERLY_CLOSED),
{error, {not_closed, Fname}} =
- dets:open_file(foo, [{file,Fname},{version,V},{repair,force},
+ dets:open_file(foo, [{file,Fname},{repair,force},
{access,read}]),
{error, {not_closed, Fname}} =
- dets:open_file(foo, [{file,Fname},{version,V},{repair,true},
+ dets:open_file(foo, [{file,Fname},{repair,true},
{access,read}]),
io:format("Expect repair:~n"),
{ok, TabRef} =
- dets:open_file(TabRef, [{file,Fname},{version,V},{repair,true},
+ dets:open_file(TabRef, [{file,Fname},{repair,true},
{access,read_write}]),
ok = dets:close(TabRef),
crash(Fname, ?CLOSED_PROPERLY_POS+3, ?NOT_PROPERLY_CLOSED),
io:format("Expect forced repair:~n"),
{ok, TabRef} =
- dets:open_file(TabRef, [{file,Fname},{version,V},{repair,force},
+ dets:open_file(TabRef, [{file,Fname},{repair,force},
{access,read_write}]),
ok = dets:close(TabRef),
file:delete(Fname),
%% The size of an object is huge.
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = dets:insert(TabRef, [{1,2,3},{2,3,4}]),
{ok, ObjPos2} = dets:where(TabRef, {1,2,3}),
ok = dets:close(TabRef),
- ObjPos3 = if
- V =:= 8 -> ObjPos2 + 4;
- V =:= 9 -> ObjPos2
- end,
- crash(Fname, ObjPos3, 255),
+ crash(Fname, ObjPos2, 255),
io:format("Expect forced repair:~n"),
- {ok, TabRef} =
- dets:open_file(TabRef, [{file,Fname},{version,V},{repair,force}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{repair,force}]),
ok = dets:close(TabRef),
file:delete(Fname),
@@ -1530,82 +1277,6 @@ repair(Config, V) ->
ok.
-%% Test the use of different hashing algorithms in v8b and v8c of the
-%% Dets file format.
-hash_v8b_v8c(Config) when is_list(Config) ->
- Source =
- filename:join(?datadir(Config), "dets_test_v8b.dets"),
- %% Little endian version of old file (there is an endianess bug in
- %% the old hash). This is all about version 8 of the dets file format.
-
- P0 = pps(),
- SourceLE =
- filename:join(?datadir(Config),
- "dets_test_v8b_little_endian.dets"),
- Target1 = filename('oldhash1.dets', Config),
- Target1LE = filename('oldhash1le.dets', Config),
- Target2 = filename('oldhash2.dets', Config),
- {ok, Bin} = file:read_file(Source),
- {ok, BinLE} = file:read_file(SourceLE),
- ok = file:write_file(Target1,Bin),
- ok = file:write_file(Target1LE,BinLE),
- ok = file:write_file(Target2,Bin),
- {ok, d1} = dets:open_file(d1,[{file,Target1}]),
- {ok, d1le} = dets:open_file(d1le,[{file,Target1LE}]),
- {ok, d2} = dets:open_file(d2,[{file,Target2},{repair,force},
- {version,8}]),
- FF = fun(N,_F,_T) when N > 16#FFFFFFFFFFFFFFFF ->
- ok;
- (N,F,T) ->
- V = integer_to_list(N),
- case dets:lookup(T,N) of
- [{N,V}] ->
- F(N*2,F,T);
- _Error ->
- exit({failed,{lookup,T,N}})
- end
- end,
- Mess = case (catch FF(1,FF,d1)) of
- {'EXIT', {failed, {lookup,_,_}}} ->
- ok = dets:close(d1),
- FF(1,FF,d1le),
- hash = dets:info(d1le,hash),
- dets:insert(d1le,{33333333333,hejsan}),
- [{33333333333,hejsan}] =
- dets:lookup(d1le,33333333333),
- ok = dets:close(d1le),
- {ok, d1le} = dets:open_file(d1le,
- [{file,Target1LE}]),
- [{33333333333,hejsan}] =
- dets:lookup(d1le,33333333333),
- FF(1,FF,d1le),
- ok = dets:close(d1le),
- "Seems to be a little endian machine";
- {'EXIT', Fault} ->
- exit(Fault);
- _ ->
- ok = dets:close(d1le),
- hash = dets:info(d1,hash),
- dets:insert(d1,{33333333333,hejsan}),
- [{33333333333,hejsan}] =
- dets:lookup(d1,33333333333),
- ok = dets:close(d1),
- {ok, d1} = dets:open_file(d1,[{file,Target1}]),
- [{33333333333,hejsan}] =
- dets:lookup(d1,33333333333),
- FF(1,FF,d1),
- ok = dets:close(d1),
- "Seems to be a big endian machine"
- end,
- FF(1,FF,d2),
- phash = dets:info(d2,hash),
- ok = dets:close(d2),
- file:delete(Target1),
- file:delete(Target1LE),
- file:delete(Target2),
- check_pps(P0),
- {comment, Mess}.
-
%% Test version 9(b) with erlang:phash/2 as hash function.
phash(Config) when is_list(Config) ->
T = phash,
@@ -1643,9 +1314,10 @@ phash(Config) when is_list(Config) ->
ok = dets:close(T),
%% One cannot use the bchunk format when copying between a phash
- %% table and a phash2 table. (There is no test for the case an R9
- %% (or later) node (using phash2) copies a table to an R8 node
- %% (using phash).) See also the comment on HASH_PARMS in dets_v9.erl.
+ %% table and a phash2 table. (There is no test for the case an
+ %% Erlang/OTP R9 (or later) node (using phash2) copies a table to
+ %% an Erlang/OTP R8 node (using phash).) See also the comment on
+ %% HASH_PARMS in dets_v9.erl.
{ok, _} = file:copy(Phash_v9bS, Fname),
{ok, T} = dets:open_file(T, [{file, Fname}]),
Type = dets:info(T, type),
@@ -1653,7 +1325,7 @@ phash(Config) when is_list(Config) ->
Input = init_bchunk(T),
T2 = phash_table,
Fname2 = filename(T2, Config),
- Args = [{type,Type},{keypos,KeyPos},{version,9},{file,Fname2}],
+ Args = [{type,Type},{keypos,KeyPos},{file,Fname2}],
{ok, T2} = dets:open_file(T2, Args),
{error, {init_fun, _}} =
dets:init_table(T2, Input, {format,bchunk}),
@@ -1665,21 +1337,14 @@ phash(Config) when is_list(Config) ->
ok.
%% Test foldl, foldr, to_ets.
-fold_v8(Config) when is_list(Config) ->
- fold(Config, 8).
-
-%% Test foldl, foldr, to_ets.
-fold_v9(Config) when is_list(Config) ->
- fold(Config, 9).
-
-fold(Config, Version) ->
+fold(Config) when is_list(Config) ->
T = test_table,
N = 100,
Fname = filename(T, Config),
file:delete(Fname),
P0 = pps(),
- Args = [{version, Version}, {file,Fname}, {estimated_no_objects, N}],
+ Args = [{file,Fname}, {estimated_no_objects, N}],
{ok, _} = dets:open_file(T, Args),
ok = ins(T, N),
@@ -1721,10 +1386,7 @@ fold(Config, Version) ->
ok = dets:close(T),
%% Damaged object.
- Pos = if
- Version =:= 8 -> 12;
- Version =:= 9 -> 8
- end,
+ Pos = 8,
crash(Fname, ObjPos+Pos),
{ok, _} = dets:open_file(T, Args),
io:format("Expect corrupt table:~n"),
@@ -1738,18 +1400,11 @@ fold(Config, Version) ->
ok.
%% Add objects to a fixed table.
-fixtable_v8(Config) when is_list(Config) ->
- fixtable(Config, 8).
-
-%% Add objects to a fixed table.
-fixtable_v9(Config) when is_list(Config) ->
- fixtable(Config, 9).
-
-fixtable(Config, Version) when is_list(Config) ->
+fixtable(Config) when is_list(Config) ->
T = fixtable,
Fname = filename(fixtable, Config),
file:delete(Fname),
- Args = [{version,Version},{file,Fname}],
+ Args = [{file,Fname}],
P0 = pps(),
{ok, _} = dets:open_file(T, Args),
@@ -1832,21 +1487,13 @@ fixtable(Config, Version) when is_list(Config) ->
ok.
%% Matching objects of a fixed table.
-match_v8(Config) when is_list(Config) ->
- match(Config, 8).
-
-%% Matching objects of a fixed table.
-match_v9(Config) when is_list(Config) ->
- match(Config, 9).
-
-match(Config, Version) ->
+match(Config) when is_list(Config) ->
T = match,
Fname = filename(match, Config),
file:delete(Fname),
P0 = pps(),
- Args = [{version, Version}, {file,Fname}, {type, duplicate_bag},
- {estimated_no_objects,550}],
+ Args = [{file,Fname}, {type, duplicate_bag}, {estimated_no_objects,550}],
{ok, _} = dets:open_file(T, Args),
ok = dets:insert(T, {1, a, b}),
ok = dets:insert(T, {1, b, a}),
@@ -1901,7 +1548,7 @@ match(Config, Version) ->
{_, TmpCont} = dets:match_object(T, '_', 200),
{_, TmpCont1} = dets:match_object(TmpCont),
{TTL, _} = dets:match_object(TmpCont1),
- DI = if Version =:= 8 -> last(TTL); Version =:= 9 -> hd(TTL) end,
+ DI = hd(TTL),
dets:safe_fixtable(T, true),
{L1, C20} = dets:match_object(T, '_', 200),
true = 200 =< length(L1),
@@ -1957,8 +1604,7 @@ match(Config, Version) ->
ok = dets:close(T),
%% Damaged size of object.
- %% In v8, there is a next pointer before the size.
- CrashPos = if Version =:= 8 -> 5; Version =:= 9 -> 1 end,
+ CrashPos = 1,
crash(Fname, ObjPos2+CrashPos),
{ok, _} = dets:open_file(T, Args),
case dets:insert_new(T, Obj) of % OTP-12024
@@ -1986,7 +1632,7 @@ match(Config, Version) ->
ok = dets:close(T),
%% match_delete finds an error
- CrashPos3 = if Version =:= 8 -> 12; Version =:= 9 -> 16 end,
+ CrashPos3 = 16,
crash(Fname, ObjPos3+CrashPos3),
{ok, _} = dets:open_file(T, Args),
bad_object(dets:match_delete(T, Spec), Fname),
@@ -2008,21 +1654,13 @@ match(Config, Version) ->
ok.
%% Selecting objects of a fixed table.
-select_v8(Config) when is_list(Config) ->
- select(Config, 8).
-
-%% Selecting objects of a fixed table.
-select_v9(Config) when is_list(Config) ->
- select(Config, 9).
-
-select(Config, Version) ->
+select(Config) when is_list(Config) ->
T = select,
Fname = filename(select, Config),
file:delete(Fname),
P0 = pps(),
- Args = [{version,Version}, {file,Fname}, {type, duplicate_bag},
- {estimated_no_objects,550}],
+ Args = [{file,Fname}, {type, duplicate_bag},{estimated_no_objects,550}],
{ok, _} = dets:open_file(T, Args),
ok = dets:insert(T, {1, a, b}),
ok = dets:insert(T, {1, b, a}),
@@ -2074,7 +1712,7 @@ select(Config, Version) ->
{_, TmpCont} = dets:match_object(T, '_', 200),
{_, TmpCont1} = dets:match_object(TmpCont),
{TTL, _} = dets:match_object(TmpCont1),
- DI = if Version =:= 8 -> last(TTL); Version =:= 9 -> hd(TTL) end,
+ DI = hd(TTL),
dets:safe_fixtable(T, true),
{L1, C20} = dets:select(T, AllSpec, 200),
true = 200 =< length(L1),
@@ -2281,28 +1919,21 @@ badarg(Config) when is_list(Config) ->
ok.
%% Test the write cache for sets.
-cache_sets_v8(Config) when is_list(Config) ->
- cache_sets(Config, 8).
-
-%% Test the write cache for sets.
-cache_sets_v9(Config) when is_list(Config) ->
- cache_sets(Config, 9).
-
-cache_sets(Config, Version) ->
+cache_sets(Config) when is_list(Config) ->
Small = 2,
- cache_sets(Config, {0,0}, false, Small, Version),
- cache_sets(Config, {0,0}, true, Small, Version),
- cache_sets(Config, {5000,5000}, false, Small, Version),
- cache_sets(Config, {5000,5000}, true, Small, Version),
+ cache_sets(Config, {0,0}, false, Small),
+ cache_sets(Config, {0,0}, true, Small),
+ cache_sets(Config, {5000,5000}, false, Small),
+ cache_sets(Config, {5000,5000}, true, Small),
%% Objects of size greater than 2 kB.
Big = 1200,
- cache_sets(Config, {0,0}, false, Big, Version),
- cache_sets(Config, {0,0}, true, Big, Version),
- cache_sets(Config, {5000,5000}, false, Big, Version),
- cache_sets(Config, {5000,5000}, true, Big, Version),
+ cache_sets(Config, {0,0}, false, Big),
+ cache_sets(Config, {0,0}, true, Big),
+ cache_sets(Config, {5000,5000}, false, Big),
+ cache_sets(Config, {5000,5000}, true, Big),
ok.
-cache_sets(Config, DelayedWrite, Extra, Sz, Version) ->
+cache_sets(Config, DelayedWrite, Extra, Sz) ->
%% Extra = bool(). Insert tuples until the tested key is not alone.
%% Sz = integer(). Size of the inserted tuples.
@@ -2311,9 +1942,8 @@ cache_sets(Config, DelayedWrite, Extra, Sz, Version) ->
file:delete(Fname),
P0 = pps(),
- {ok, _} =
- dets:open_file(T,[{version, Version}, {file,Fname}, {type,set},
- {delayed_write, DelayedWrite}]),
+ {ok, _} = dets:open_file(T,[{file,Fname}, {type,set},
+ {delayed_write, DelayedWrite}]),
Dups = 1,
{Key, OtherKeys} =
@@ -2430,28 +2060,21 @@ cache_sets(Config, DelayedWrite, Extra, Sz, Version) ->
ok.
%% Test the write cache for bags.
-cache_bags_v8(Config) when is_list(Config) ->
- cache_bags(Config, 8).
-
-%% Test the write cache for bags.
-cache_bags_v9(Config) when is_list(Config) ->
- cache_bags(Config, 9).
-
-cache_bags(Config, Version) ->
+cache_bags(Config) when is_list(Config) ->
Small = 2,
- cache_bags(Config, {0,0}, false, Small, Version),
- cache_bags(Config, {0,0}, true, Small, Version),
- cache_bags(Config, {5000,5000}, false, Small, Version),
- cache_bags(Config, {5000,5000}, true, Small, Version),
+ cache_bags(Config, {0,0}, false, Small),
+ cache_bags(Config, {0,0}, true, Small),
+ cache_bags(Config, {5000,5000}, false, Small),
+ cache_bags(Config, {5000,5000}, true, Small),
%% Objects of size greater than 2 kB.
Big = 1200,
- cache_bags(Config, {0,0}, false, Big, Version),
- cache_bags(Config, {0,0}, true, Big, Version),
- cache_bags(Config, {5000,5000}, false, Big, Version),
- cache_bags(Config, {5000,5000}, true, Big, Version),
+ cache_bags(Config, {0,0}, false, Big),
+ cache_bags(Config, {0,0}, true, Big),
+ cache_bags(Config, {5000,5000}, false, Big),
+ cache_bags(Config, {5000,5000}, true, Big),
ok.
-cache_bags(Config, DelayedWrite, Extra, Sz, Version) ->
+cache_bags(Config, DelayedWrite, Extra, Sz) ->
%% Extra = bool(). Insert tuples until the tested key is not alone.
%% Sz = integer(). Size of the inserted tuples.
@@ -2460,9 +2083,8 @@ cache_bags(Config, DelayedWrite, Extra, Sz, Version) ->
file:delete(Fname),
P0 = pps(),
- {ok, _} =
- dets:open_file(T,[{version, Version}, {file,Fname}, {type,bag},
- {delayed_write, DelayedWrite}]),
+ {ok, _} = dets:open_file(T,[{file,Fname}, {type,bag},
+ {delayed_write, DelayedWrite}]),
Dups = 1,
{Key, OtherKeys} =
@@ -2588,8 +2210,7 @@ cache_bags(Config, DelayedWrite, Extra, Sz, Version) ->
R1 = {index_test,1,2,3,4},
R2 = {index_test,2,2,13,14},
R3 = {index_test,1,12,13,14},
- {ok, _} = dets:open_file(T,[{version,Version},{type,bag},
- {keypos,2},{file,Fname}]),
+ {ok, _} = dets:open_file(T,[{type,bag}, {keypos,2},{file,Fname}]),
ok = dets:insert(T,R1),
ok = dets:sync(T),
ok = dets:insert(T,R2),
@@ -2606,27 +2227,20 @@ cache_bags(Config, DelayedWrite, Extra, Sz, Version) ->
ok.
%% Test the write cache for duplicate bags.
-cache_duplicate_bags_v8(Config) when is_list(Config) ->
- cache_duplicate_bags(Config, 8).
-
-%% Test the write cache for duplicate bags.
-cache_duplicate_bags_v9(Config) when is_list(Config) ->
- cache_duplicate_bags(Config, 9).
-
-cache_duplicate_bags(Config, Version) ->
+cache_duplicate_bags(Config) when is_list(Config) ->
Small = 2,
- cache_dup_bags(Config, {0,0}, false, Small, Version),
- cache_dup_bags(Config, {0,0}, true, Small, Version),
- cache_dup_bags(Config, {5000,5000}, false, Small, Version),
- cache_dup_bags(Config, {5000,5000}, true, Small, Version),
+ cache_dup_bags(Config, {0,0}, false, Small),
+ cache_dup_bags(Config, {0,0}, true, Small),
+ cache_dup_bags(Config, {5000,5000}, false, Small),
+ cache_dup_bags(Config, {5000,5000}, true, Small),
%% Objects of size greater than 2 kB.
Big = 1200,
- cache_dup_bags(Config, {0,0}, false, Big, Version),
- cache_dup_bags(Config, {0,0}, true, Big, Version),
- cache_dup_bags(Config, {5000,5000}, false, Big, Version),
- cache_dup_bags(Config, {5000,5000}, true, Big, Version).
+ cache_dup_bags(Config, {0,0}, false, Big),
+ cache_dup_bags(Config, {0,0}, true, Big),
+ cache_dup_bags(Config, {5000,5000}, false, Big),
+ cache_dup_bags(Config, {5000,5000}, true, Big).
-cache_dup_bags(Config, DelayedWrite, Extra, Sz, Version) ->
+cache_dup_bags(Config, DelayedWrite, Extra, Sz) ->
%% Extra = bool(). Insert tuples until the tested key is not alone.
%% Sz = integer(). Size of the inserted tuples.
@@ -2635,10 +2249,8 @@ cache_dup_bags(Config, DelayedWrite, Extra, Sz, Version) ->
file:delete(Fname),
P0 = pps(),
- {ok, _} =
- dets:open_file(T,[{version, Version}, {file,Fname},
- {type,duplicate_bag},
- {delayed_write, DelayedWrite}]),
+ {ok, _} = dets:open_file(T,[{file,Fname}, {type,duplicate_bag},
+ {delayed_write, DelayedWrite}]),
Dups = 2,
{Key, OtherKeys} =
@@ -2869,7 +2481,7 @@ otp_8899(Config) when is_list(Config) ->
Server = self(),
file:delete(FName),
- {ok, _} = dets:open_file(Tab,[{file, FName},{version,9}]),
+ {ok, _} = dets:open_file(Tab,[{file, FName}]),
[P1,P2,P3,P4] = new_clients(4, Tab),
MC = [Tab],
@@ -2895,7 +2507,7 @@ many_clients(Config) when is_list(Config) ->
file:delete(FName),
P0 = pps(),
- {ok, _} = dets:open_file(Tab,[{file, FName},{version,9}]),
+ {ok, _} = dets:open_file(Tab,[{file, FName}]),
[P1,P2,P3,P4] = new_clients(4, Tab),
%% dets:init_table/2 is used for making sure that all processes
@@ -2954,14 +2566,14 @@ many_clients(Config) when is_list(Config) ->
file:delete(FName),
%% Check that errors are handled correctly by the streaming operators.
- {ok, _} = dets:open_file(Tab,[{file, FName},{version,9}]),
+ {ok, _} = dets:open_file(Tab,[{file, FName}]),
ok = ins(Tab, 100),
Obj = {66,{item,number,66}},
{ok, ObjPos} = dets:where(Tab, Obj),
ok = dets:close(Tab),
%% Damaged object.
crash(FName, ObjPos+12),
- {ok, _} = dets:open_file(Tab,[{file, FName},{version,9}]),
+ {ok, _} = dets:open_file(Tab,[{file, FName}]),
BadObject1 = dets:lookup_keys(Tab, [65,66,67,68,69]),
bad_object(BadObject1, FName),
_Error = dets:close(Tab),
@@ -3400,8 +3012,13 @@ repair_continuation(Config) ->
MS = [{'_',[],[true]}],
- {[true], C1} = dets:select(Tab, MS, 1),
- C2 = binary_to_term(term_to_binary(C1)),
+ SRes = term_to_binary(dets:select(Tab, MS, 1)),
+ %% Get rid of compiled match spec
+ lists:foreach(fun (P) ->
+ garbage_collect(P)
+ end, processes()),
+ {[true], C2} = binary_to_term(SRes),
+
{'EXIT', {badarg, _}} = (catch dets:select(C2)),
C3 = dets:repair_continuation(C2, MS),
{[true], C4} = dets:select(C3),
@@ -3415,18 +3032,13 @@ repair_continuation(Config) ->
%% OTP-5487. Growth of read-only table (again).
otp_5487(Config) ->
- otp_5487(Config, 9),
- otp_5487(Config, 8),
- ok.
-
-otp_5487(Config, Version) ->
Tab = otp_5487,
Fname = filename(otp_5487, Config),
file:delete(Fname),
Ets = ets:new(otp_5487, [public, set]),
lists:foreach(fun(I) -> ets:insert(Ets, {I,I+1}) end,
lists:seq(0,1000)),
- {ok, _} = dets:open_file(Tab, [{file,Fname},{version,Version}]),
+ {ok, _} = dets:open_file(Tab, [{file,Fname}]),
ok = dets:from_ets(Tab, Ets),
ok = dets:sync(Tab),
ok = dets:close(Tab),
@@ -3470,14 +3082,12 @@ otp_6359(Config) ->
%% OTP-4738. ==/2 and =:=/2.
otp_4738(Config) ->
- %% Version 8 has not been corrected.
- %% (The constant -12857447 is for version 9 only.)
- otp_4738_set(9, Config),
- otp_4738_bag(9, Config),
- otp_4738_dupbag(9, Config),
+ otp_4738_set(Config),
+ otp_4738_bag(Config),
+ otp_4738_dupbag(Config),
ok.
-otp_4738_dupbag(Version, Config) ->
+otp_4738_dupbag(Config) ->
Tab = otp_4738,
File = filename(Tab, Config),
file:delete(File),
@@ -3485,7 +3095,7 @@ otp_4738_dupbag(Version, Config) ->
F = float(I),
One = 1,
FOne = float(One),
- Args = [{file,File},{type,duplicate_bag},{version,Version}],
+ Args = [{file,File},{type,duplicate_bag}],
{ok, Tab} = dets:open_file(Tab, Args),
ok = dets:insert(Tab, [{I,One},{F,One},{I,FOne},{F,FOne}]),
ok = dets:sync(Tab),
@@ -3530,7 +3140,7 @@ otp_4738_dupbag(Version, Config) ->
file:delete(File),
ok.
-otp_4738_bag(Version, Config) ->
+otp_4738_bag(Config) ->
Tab = otp_4738,
File = filename(Tab, Config),
file:delete(File),
@@ -3538,7 +3148,7 @@ otp_4738_bag(Version, Config) ->
F = float(I),
One = 1,
FOne = float(One),
- Args = [{file,File},{type,bag},{version,Version}],
+ Args = [{file,File},{type,bag}],
{ok, Tab} = dets:open_file(Tab, Args),
ok = dets:insert(Tab, [{I,One},{F,One},{I,FOne},{F,FOne}]),
ok = dets:sync(Tab),
@@ -3561,11 +3171,11 @@ otp_4738_bag(Version, Config) ->
ok = dets:close(Tab),
file:delete(File).
-otp_4738_set(Version, Config) ->
+otp_4738_set(Config) ->
Tab = otp_4738,
File = filename(Tab, Config),
file:delete(File),
- Args = [{file,File},{type,set},{version,Version}],
+ Args = [{file,File},{type,set}],
%% I and F share the same slot.
I = -12857447,
@@ -3864,6 +3474,19 @@ wait_for_close(Tab) ->
wait_for_close(Tab)
end.
+%% OTP-13830. Format 8 is no longer supported.
+otp_13830(Config) ->
+ Tab = otp_13830,
+ File8 = filename:join(?datadir(Config), "version_8.dets"),
+ {error,{format_8_no_longer_supported,_}} =
+ dets:open_file(Tab, [{file, File8}]),
+ File = filename(Tab, Config),
+ %% Check the 'version' option, for backwards compatibility:
+ {ok, Tab} = dets:open_file(Tab, [{file, File}, {version, 9}]),
+ ok = dets:close(Tab),
+ {ok, Tab} = dets:open_file(Tab, [{file, File}, {version, default}]),
+ ok = dets:close(Tab).
+
%%
%% Parts common to several test cases
%%
@@ -4000,9 +3623,7 @@ match_test(Data, Tab) ->
%% Utilities
%%
-headsz(8) ->
- ?HEADSZ_v8;
-headsz(_) ->
+headsz() ->
?HEADSZ_v9.
unwritable(Fname) ->
@@ -4030,13 +3651,13 @@ filename(Name, Config) when is_atom(Name) ->
filename(Name, _Config) ->
filename:join(?privdir(_Config), Name).
-open_files(_Name, [], _Version) ->
+open_files(_Name, []) ->
[];
-open_files(Name0, [Args | Tail], Version) ->
+open_files(Name0, [Args | Tail]) ->
?format("init ~p~n", [Args]),
Name = list_to_atom(integer_to_list(Name0)),
- {ok, Name} = dets:open_file(Name, [{version,Version} | Args]),
- [Name | open_files(Name0+1, Tail, Version)].
+ {ok, Name} = dets:open_file(Name, Args),
+ [Name | open_files(Name0+1, Tail)].
close_all(Tabs) -> foreach(fun(Tab) -> ok = dets:close(Tab) end, Tabs).
@@ -4137,20 +3758,15 @@ no_keys_test([T | Ts]) ->
no_keys_test([]) ->
ok;
no_keys_test(T) ->
- case dets:info(T, version) of
- 8 ->
- ok;
- 9 ->
- Kp = dets:info(T, keypos),
- All = dets:match_object(T, '_'),
- L = lists:map(fun(X) -> element(Kp, X) end, All),
- NoKeys = length(lists:usort(L)),
- case {dets:info(T, no_keys), NoKeys} of
- {N, N} ->
- ok;
- {N1, N2} ->
- exit({no_keys_test, N1, N2})
- end
+ Kp = dets:info(T, keypos),
+ All = dets:match_object(T, '_'),
+ L = lists:map(fun(X) -> element(Kp, X) end, All),
+ NoKeys = length(lists:usort(L)),
+ case {dets:info(T, no_keys), NoKeys} of
+ {N, N} ->
+ ok;
+ {N1, N2} ->
+ exit({no_keys_test, N1, N2})
end.
safe_get_all_objects(Tab) ->
@@ -4182,7 +3798,6 @@ count_objs_1({Ts,C}, N) when is_list(Ts) ->
get_all_objects_fast(Tab) ->
dets:match_object(Tab, '_').
-%% Relevant for version 8.
histogram(Tab) ->
OnePercent = case dets:info(Tab, no_slots) of
undefined -> undefined;
@@ -4244,10 +3859,6 @@ ave_histogram([{S,N1} | H], N) ->
ave_histogram([], N) ->
N.
-bad_object({error,{bad_object,FileName}}, FileName) ->
- ok; % Version 8, no debug.
-bad_object({error,{{bad_object,_,_},FileName}}, FileName) ->
- ok; % Version 8, debug...
bad_object({error,{{bad_object,_}, FileName}}, FileName) ->
ok; % No debug.
bad_object({error,{{{bad_object,_,_},_,_,_}, FileName}}, FileName) ->
diff --git a/lib/stdlib/test/dets_SUITE_data/version_r2d.dets b/lib/stdlib/test/dets_SUITE_data/version_8.dets
index 327072f99e..278187e85c 100644
--- a/lib/stdlib/test/dets_SUITE_data/version_r2d.dets
+++ b/lib/stdlib/test/dets_SUITE_data/version_8.dets
Binary files differ
diff --git a/lib/stdlib/test/dict_SUITE.erl b/lib/stdlib/test/dict_SUITE.erl
index 47358d729f..e99af9ad42 100644
--- a/lib/stdlib/test/dict_SUITE.erl
+++ b/lib/stdlib/test/dict_SUITE.erl
@@ -23,10 +23,10 @@
-module(dict_SUITE).
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
- create/1,store/1,iterate/1]).
+ create/1,store/1,iterate/1,remove/1]).
-include_lib("common_test/include/ct.hrl").
@@ -37,7 +37,7 @@ suite() ->
{timetrap,{minutes,5}}].
all() ->
- [create, store, iterate].
+ [create, store, remove, iterate].
groups() ->
[].
@@ -92,6 +92,27 @@ store_1(List, M) ->
end,
D0.
+remove(_Config) ->
+ test_all([{0,87}], fun remove_1/2).
+
+remove_1(List0, M) ->
+ %% Make sure that keys are unique. Randomize key order.
+ List1 = orddict:from_list(List0),
+ List2 = lists:sort([{rand:uniform(),E} || E <- List1]),
+ List = [E || {_,E} <- List2],
+ D0 = M(from_list, List),
+ remove_2(List, D0, M).
+
+remove_2([{Key,Val}|T], D0, M) ->
+ {Val,D1} = M(take, {Key,D0}),
+ error = M(take, {Key,D1}),
+ D2 = M(erase, {Key,D0}),
+ true = M(equal, {D1,D2}),
+ remove_2(T, D1, M);
+remove_2([], D, M) ->
+ true = M(is_empty, D),
+ D.
+
%%%
%%% Test specifics for gb_trees.
%%%
diff --git a/lib/stdlib/test/dict_test_lib.erl b/lib/stdlib/test/dict_test_lib.erl
index 7c4c3572ae..8f999f7cad 100644
--- a/lib/stdlib/test/dict_test_lib.erl
+++ b/lib/stdlib/test/dict_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,7 +33,9 @@ new(Mod, Eq) ->
(iterator, S) -> Mod:iterator(S);
(iterator_from, {Start, S}) -> Mod:iterator_from(Start, S);
(next, I) -> Mod:next(I);
- (to_list, D) -> to_list(Mod, D)
+ (to_list, D) -> to_list(Mod, D);
+ (erase, {K,D}) -> erase(Mod, K, D);
+ (take, {K,D}) -> take(Mod, K, D)
end.
empty(Mod) ->
@@ -67,3 +69,19 @@ enter(Mod, Key, Val, Dict) ->
true ->
Mod:store(Key, Val, Dict)
end.
+
+erase(Mod, Key, Val) when Mod =:= dict; Mod =:= orddict ->
+ Mod:erase(Key, Val);
+erase(gb_trees, Key, Val) ->
+ gb_trees:delete_any(Key, Val).
+
+take(gb_trees, Key, Val) ->
+ Res = try
+ gb_trees:take(Key, Val)
+ catch
+ error:_ ->
+ error
+ end,
+ Res = gb_trees:take_any(Key, Val);
+take(Mod, Key, Val) ->
+ Mod:take(Key, Val).
diff --git a/lib/stdlib/test/dummy_h.erl b/lib/stdlib/test/dummy_h.erl
index bc89cb4fde..7a9eb11f98 100644
--- a/lib/stdlib/test/dummy_h.erl
+++ b/lib/stdlib/test/dummy_h.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -26,6 +26,8 @@
init(make_error) ->
{error, my_error};
+init({state, State}) ->
+ {ok, State};
init([Parent]) ->
{ok, Parent}; %% We will send special responses for every handled event.
init([Parent,hibernate]) ->
@@ -41,6 +43,9 @@ handle_event(hibernate, _State) ->
{ok,[],hibernate};
handle_event(wakeup, _State) ->
{ok,[]};
+handle_event({From, handle_event}, _State) ->
+ From ! handled_event,
+ {ok,[]};
handle_event(Event, Parent) ->
Parent ! {dummy_h, Event},
{ok, Parent}.
@@ -73,6 +78,9 @@ handle_info(wake, _State) ->
{ok, []};
handle_info(gnurf, _State) ->
{ok, []};
+handle_info({From, handle_info}, _State) ->
+ From ! handled_info,
+ {ok, []};
handle_info(Info, Parent) ->
Parent ! {dummy_h, Info},
{ok, Parent}.
@@ -83,7 +91,9 @@ terminate(swap, State) ->
{ok, State};
terminate({error, {return, faulty}}, Parent) ->
Parent ! {dummy_h, returned_error};
+terminate(_Reason, {undef_in_terminate, {Mod, Fun}}) ->
+ Mod:Fun(),
+ ok;
terminate(_Reason, _State) ->
ok.
-
diff --git a/lib/stdlib/test/edlin_expand_SUITE.erl b/lib/stdlib/test/edlin_expand_SUITE.erl
index ccffa2e244..1f694ea549 100644
--- a/lib/stdlib/test/edlin_expand_SUITE.erl
+++ b/lib/stdlib/test/edlin_expand_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,7 +21,8 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_testcase/2, end_per_testcase/2,
init_per_group/2,end_per_group/2]).
--export([normal/1, quoted_fun/1, quoted_module/1, quoted_both/1]).
+-export([normal/1, quoted_fun/1, quoted_module/1, quoted_both/1, erl_1152/1,
+ erl_352/1]).
-include_lib("common_test/include/ct.hrl").
@@ -36,7 +37,7 @@ suite() ->
{timetrap,{minutes,1}}].
all() ->
- [normal, quoted_fun, quoted_module, quoted_both].
+ [normal, quoted_fun, quoted_module, quoted_both, erl_1152, erl_352].
groups() ->
[].
@@ -149,5 +150,84 @@ quoted_both(Config) when is_list(Config) ->
{yes,"weird-fun-name'()",[]} = do_expand("'ExpandTestCaps1':'#"),
ok.
+erl_1152(Config) when is_list(Config) ->
+ "\n"++"foo"++" "++[1089]++_ = do_format(["foo",[1089]]),
+ ok.
+
+erl_352(Config) when is_list(Config) ->
+ erl_352_test(3, 3),
+
+ erl_352_test(3, 75),
+ erl_352_test(3, 76, [trailing]),
+ erl_352_test(4, 74),
+ erl_352_test(4, 75, [leading]),
+ erl_352_test(4, 76, [leading, trailing]),
+
+ erl_352_test(75, 3),
+ erl_352_test(76, 3, [leading]),
+ erl_352_test(74, 4),
+ erl_352_test(75, 4, [leading]),
+ erl_352_test(76, 4, [leading]),
+
+ erl_352_test(74, 74, [leading]),
+ erl_352_test(74, 75, [leading]),
+ erl_352_test(74, 76, [leading, trailing]).
+
+erl_352_test(PrefixLen, SuffixLen) ->
+ erl_352_test(PrefixLen, SuffixLen, []).
+
+erl_352_test(PrefixLen, SuffixLen, Dots) ->
+ io:format("\nPrefixLen = ~w, SuffixLen = ~w\n", [PrefixLen, SuffixLen]),
+
+ PrefixM = lists:duplicate(PrefixLen, $p),
+ SuffixM = lists:duplicate(SuffixLen, $s),
+ LM = [PrefixM ++ S ++ SuffixM || S <- ["1", "2"]],
+ StrM = do_format(LM),
+ check_leading(StrM, "", PrefixM, SuffixM, Dots),
+
+ PrefixF = lists:duplicate(PrefixLen, $p),
+ SuffixF = lists:duplicate(SuffixLen-2, $s),
+ LF = [{PrefixF ++ S ++ SuffixF, 1} || S <- ["1", "2"]],
+ StrF = do_format(LF),
+ true = check_leading(StrF, "/1", PrefixF, SuffixF, Dots),
+
+ ok.
+
+check_leading(FormStr, ArityStr, Prefix, Suffix, Dots) ->
+ List = string:tokens(FormStr, "\n "),
+ io:format("~p\n", [List]),
+ true = lists:all(fun(L) -> length(L) < 80 end, List),
+ case lists:member(leading, Dots) of
+ true ->
+ true = lists:all(fun(L) ->
+ {"...", Rest} = lists:split(3, L),
+ check_trailing(Rest, ArityStr,
+ Suffix, Dots)
+ end, List);
+ false ->
+ true = lists:all(fun(L) ->
+ {Prefix, Rest} =
+ lists:split(length(Prefix), L),
+ check_trailing(Rest, ArityStr,
+ Suffix, Dots)
+ end, List)
+ end.
+
+check_trailing([I|Str], ArityStr, Suffix, Dots) ->
+ true = lists:member(I, [$1, $2]),
+ case lists:member(trailing, Dots) of
+ true ->
+ {Rest, "..." ++ ArityStr} =
+ lists:split(length(Str) - (3 + length(ArityStr)), Str),
+ true = lists:prefix(Rest, Suffix);
+ false ->
+ {Rest, ArityStr} =
+ lists:split(length(Str) - length(ArityStr), Str),
+ Rest =:= Suffix
+ end.
+
do_expand(String) ->
edlin_expand:expand(lists:reverse(String)).
+
+do_format(StringList) ->
+ lists:flatten(edlin_expand:format_matches(StringList)).
diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl
index 4078513e38..915f478dfa 100644
--- a/lib/stdlib/test/epp_SUITE.erl
+++ b/lib/stdlib/test/epp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@
otp_8130/1, overload_mac/1, otp_8388/1, otp_8470/1,
otp_8562/1, otp_8665/1, otp_8911/1, otp_10302/1, otp_10820/1,
otp_11728/1, encoding/1, extends/1, function_macro/1,
- test_error/1, test_warning/1]).
+ test_error/1, test_warning/1, otp_14285/1]).
-export([epp_parse_erl_form/2]).
@@ -68,7 +68,8 @@ all() ->
not_circular, skip_header, otp_6277, otp_7702, otp_8130,
overload_mac, otp_8388, otp_8470, otp_8562,
otp_8665, otp_8911, otp_10302, otp_10820, otp_11728,
- encoding, extends, function_macro, test_error, test_warning].
+ encoding, extends, function_macro, test_error, test_warning,
+ otp_14285].
groups() ->
[{upcase_mac, [], [upcase_mac_1, upcase_mac_2]},
@@ -306,7 +307,7 @@ otp_5362(Config) when is_list(Config) ->
File_Back_hrl = filename:join(Dir, "back_5362.hrl"),
Back = <<"-module(back_5362).
- -compile(export_all).
+ -export([foo/1]).
-file(?FILE, 1).
-include(\"back_5362.hrl\").
@@ -334,7 +335,7 @@ otp_5362(Config) when is_list(Config) ->
-file(?FILE, 100).
- -compile(export_all).
+ -export([foo/1,bar/1]).
-file(\"other.file\", ?LINE). % like an included file...
foo(A) -> % line 105
@@ -362,7 +363,7 @@ otp_5362(Config) when is_list(Config) ->
Blank = <<"-module(blank_5362).
- -compile(export_all).
+ -export([q/1,a/1,b/1,c/1]).
-
file(?FILE, 18). q(Q) -> foo. % line 18
@@ -677,7 +678,7 @@ otp_8130(Config) when is_list(Config) ->
{otp_8130_c6,
<<"-define(M3(), A).\n"
"t() -> A = 1, ?3.14159}.\n">>,
- {errors,[{{2,16},epp,{call,"?3.14159"}}],[]}},
+ {errors,[{{2,16},epp,{call,[$?,"3.14159"]}}],[]}},
{otp_8130_c7,
<<"\nt() -> ?A.\n">>,
@@ -1258,7 +1259,7 @@ do_otp_8911(Config) ->
File = "i.erl",
Cont = <<"-module(i).
- -compile(export_all).
+ -export([t/0]).
-file(\"fil1\", 100).
-include(\"i1.erl\").
t() ->
@@ -1384,6 +1385,26 @@ do_otp_10820(File, C, PC) ->
true = test_server:stop_node(Node),
ok.
+%% OTP_14285: Unicode atoms.
+otp_14285(Config) when is_list(Config) ->
+ %% This is just a sample of errors.
+ Cs = [{otp_8562,
+ <<"-export([f/0]).
+ -define('a\x{400}b', 'a\x{400}d').
+ f() ->
+ ?'a\x{400}b'.
+ g() ->
+ ?\"a\x{400}b\".
+ h() ->
+ ?'a\x{400}no'().
+ "/utf8>>,
+ {errors,[{6,epp,{call,[63,[91,["97",44,"1024",44,"98"],93]]}},
+ {8,epp,{undefined,'a\x{400}no',0}}],
+ []}}
+ ],
+ [] = compile(Config, Cs),
+ ok.
+
%% OTP-11728. Bugfix circular macro.
otp_11728(Config) when is_list(Config) ->
Dir = proplists:get_value(priv_dir, Config),
@@ -1391,7 +1412,7 @@ otp_11728(Config) when is_list(Config) ->
HrlFile = filename:join(Dir, "otp_11728.hrl"),
ok = file:write_file(HrlFile, H),
C = <<"-module(otp_11728).
- -compile(export_all).
+ -export([function_name/0]).
-include(\"otp_11728.hrl\").
@@ -1599,12 +1620,12 @@ check_test(Config, Test) ->
end.
compile_test(Config, Test0) ->
- Test = [<<"-module(epp_test). -compile(export_all). ">>, Test0],
+ Test = [<<"-module(epp_test). ">>, Test0],
Filename = "epp_test.erl",
PrivDir = proplists:get_value(priv_dir, Config),
File = filename:join(PrivDir, Filename),
ok = file:write_file(File, Test),
- Opts = [export_all,return,nowarn_unused_record,{outdir,PrivDir}],
+ Opts = [export_all,nowarn_export_all,return,nowarn_unused_record,{outdir,PrivDir}],
case compile_file(File, Opts) of
{ok, Ws} -> warnings(File, Ws);
Else -> Else
@@ -1653,7 +1674,7 @@ unopaque_forms(Forms) ->
[erl_parse:anno_to_term(Form) || Form <- Forms].
run_test(Config, Test0) ->
- Test = [<<"-module(epp_test). -compile(export_all). ">>, Test0],
+ Test = [<<"-module(epp_test). -export([t/0]). ">>, Test0],
Filename = "epp_test.erl",
PrivDir = proplists:get_value(priv_dir, Config),
File = filename:join(PrivDir, Filename),
diff --git a/lib/stdlib/test/erl_internal_SUITE.erl b/lib/stdlib/test/erl_internal_SUITE.erl
index bfa48de6b7..789a9d4363 100644
--- a/lib/stdlib/test/erl_internal_SUITE.erl
+++ b/lib/stdlib/test/erl_internal_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -60,7 +60,7 @@ end_per_testcase(_Case, _Config) ->
%% Check that the behaviour callbacks are correctly defined.
behav(_) ->
Modules = [application, gen_server, gen_fsm, gen_event,
- supervisor_bridge, supervisor],
+ gen_statem, supervisor_bridge, supervisor],
lists:foreach(fun check_behav/1, Modules).
check_behav(Module) ->
@@ -89,6 +89,10 @@ callbacks(gen_event) ->
[{init,1}, {handle_event,2}, {handle_call,2},
{handle_info,2}, {terminate,2}, {code_change,3},
{format_status,2}];
+callbacks(gen_statem) ->
+ [{init, 1}, {callback_mode, 0}, {state_name, 3},
+ {handle_event, 4}, {terminate, 3}, {code_change, 4},
+ {format_status, 2}];
callbacks(supervisor_bridge) ->
[{init,1}, {terminate,2}];
callbacks(supervisor) ->
@@ -97,11 +101,14 @@ callbacks(supervisor) ->
optional_callbacks(application) ->
[];
optional_callbacks(gen_server) ->
- [{format_status,2}];
+ [{handle_info, 2}, {terminate, 2}, {code_change, 3}, {format_status, 2}];
optional_callbacks(gen_fsm) ->
- [{format_status,2}];
+ [{handle_info, 3}, {terminate, 3}, {code_change, 4}, {format_status, 2}];
optional_callbacks(gen_event) ->
- [{format_status,2}];
+ [{handle_info, 2}, {terminate, 2}, {code_change, 3}, {format_status, 2}];
+optional_callbacks(gen_statem) ->
+ [{state_name, 3}, {handle_event, 4},
+ {terminate, 3}, {code_change, 4}, {format_status, 2}];
optional_callbacks(supervisor_bridge) ->
[];
optional_callbacks(supervisor) ->
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index d916eb3eef..6a75eaa737 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -64,7 +64,9 @@
predef/1,
maps/1,maps_type/1,maps_parallel_match/1,
otp_11851/1,otp_11879/1,otp_13230/1,
- record_errors/1]).
+ record_errors/1, otp_11879_cont/1,
+ non_latin1_module/1, otp_14323/1,
+ get_stacktrace/1, otp_14285/1]).
suite() ->
[{ct_hooks,[ts_install_cth]},
@@ -84,7 +86,8 @@ all() ->
too_many_arguments, basic_errors, bin_syntax_errors, predef,
maps, maps_type, maps_parallel_match,
otp_11851, otp_11879, otp_13230,
- record_errors].
+ record_errors, otp_11879_cont, non_latin1_module, otp_14323,
+ get_stacktrace, otp_14285].
groups() ->
[{unused_vars_warn, [],
@@ -1554,7 +1557,15 @@ guard(Config) when is_list(Config) ->
[],
{errors,[{1,erl_lint,illegal_guard_expr},
{2,erl_lint,illegal_guard_expr}],
- []}}
+ []}},
+ {guard10,
+ <<"is_port(_) -> false.
+ t(P) when port(P) -> ok.
+ ">>,
+ [],
+ {error,
+ [{2,erl_lint,{obsolete_guard_overridden,port}}],
+ [{2,erl_lint,{obsolete_guard,{port,1}}}]}}
],
[] = run(Config, Ts1),
ok.
@@ -1855,7 +1866,7 @@ otp_5276(Config) when is_list(Config) ->
%% OTP-5917. Check the 'deprecated' attributed.
otp_5917(Config) when is_list(Config) ->
Ts = [{otp_5917_1,
- <<"-compile(export_all).
+ <<"-export([t/0]).
-deprecated({t,0}).
@@ -1870,7 +1881,7 @@ otp_5917(Config) when is_list(Config) ->
%% OTP-6585. Check the deprecated guards list/1, pid/1, ....
otp_6585(Config) when is_list(Config) ->
Ts = [{otp_6585_1,
- <<"-compile(export_all).
+ <<"-export([t/0]).
-record(r, {}).
@@ -1994,22 +2005,22 @@ otp_5362(Config) when is_list(Config) ->
<<"-compile(nowarn_deprecated_function).
-compile(nowarn_bif_clash).
spawn(A) ->
- erlang:hash(A, 3000),
+ erlang:now(),
spawn(A).
">>,
- {[nowarn_unused_function,
+ {[nowarn_unused_function,
warn_deprecated_function,
warn_bif_clash]},
{error,
[{5,erl_lint,{call_to_redefined_old_bif,{spawn,1}}}],
- [{4,erl_lint,{deprecated,{erlang,hash,2},{erlang,phash2,2},
- "a future release"}}]}},
-
+ [{4,erl_lint,{deprecated,{erlang,now,0},
+ "Deprecated BIF. See the \"Time and Time Correction in Erlang\" "
+ "chapter of the ERTS User's Guide for more information."}}]}},
{otp_5362_5,
<<"-compile(nowarn_deprecated_function).
-compile(nowarn_bif_clash).
spawn(A) ->
- erlang:hash(A, 3000),
+ erlang:now(),
spawn(A).
">>,
{[nowarn_unused_function]},
@@ -2018,37 +2029,37 @@ otp_5362(Config) when is_list(Config) ->
%% The special nowarn_X are not affected by general warn_X.
{otp_5362_6,
- <<"-compile({nowarn_deprecated_function,{erlang,hash,2}}).
+ <<"-compile({nowarn_deprecated_function,{erlang,now,0}}).
-compile({nowarn_bif_clash,{spawn,1}}).
spawn(A) ->
- erlang:hash(A, 3000),
+ erlang:now(),
spawn(A).
">>,
- {[nowarn_unused_function,
- warn_deprecated_function,
+ {[nowarn_unused_function,
+ warn_deprecated_function,
warn_bif_clash]},
{errors,
[{2,erl_lint,disallowed_nowarn_bif_clash}],[]}},
{otp_5362_7,
<<"-export([spawn/1]).
- -compile({nowarn_deprecated_function,{erlang,hash,2}}).
+ -compile({nowarn_deprecated_function,{erlang,now,0}}).
-compile({nowarn_bif_clash,{spawn,1}}).
-compile({nowarn_bif_clash,{spawn,2}}). % bad
-compile([{nowarn_deprecated_function,
- [{erlang,hash,-1},{3,hash,-1}]}, % 2 bad
- {nowarn_deprecated_function, {{a,b,c},hash,-1}}]). % bad
+ [{erlang,now,-1},{3,now,-1}]}, % 2 bad
+ {nowarn_deprecated_function, {{a,b,c},now,-1}}]). % bad
spawn(A) ->
- erlang:hash(A, 3000),
+ erlang:now(),
spawn(A).
">>,
{[nowarn_unused_function]},
{error,[{3,erl_lint,disallowed_nowarn_bif_clash},
{4,erl_lint,disallowed_nowarn_bif_clash},
{4,erl_lint,{bad_nowarn_bif_clash,{spawn,2}}}],
- [{5,erl_lint,{bad_nowarn_deprecated_function,{3,hash,-1}}},
- {5,erl_lint,{bad_nowarn_deprecated_function,{erlang,hash,-1}}},
- {5,erl_lint,{bad_nowarn_deprecated_function,{{a,b,c},hash,-1}}}]}
+ [{5,erl_lint,{bad_nowarn_deprecated_function,{3,now,-1}}},
+ {5,erl_lint,{bad_nowarn_deprecated_function,{erlang,now,-1}}},
+ {5,erl_lint,{bad_nowarn_deprecated_function,{{a,b,c},now,-1}}}]}
},
{otp_5362_8,
@@ -2056,14 +2067,15 @@ otp_5362(Config) when is_list(Config) ->
-compile(warn_deprecated_function).
-compile(warn_bif_clash).
spawn(A) ->
- erlang:hash(A, 3000),
+ erlang:now(),
spawn(A).
">>,
{[nowarn_unused_function,
{nowarn_bif_clash,{spawn,1}}]}, % has no effect
{warnings,
- [{5,erl_lint,{deprecated,{erlang,hash,2},{erlang,phash2,2},
- "a future release"}}]}},
+ [{5,erl_lint,{deprecated,{erlang,now,0},
+ "Deprecated BIF. See the \"Time and Time Correction in Erlang\" "
+ "chapter of the ERTS User's Guide for more information."}}]}},
{otp_5362_9,
<<"-include_lib(\"stdlib/include/qlc.hrl\").
@@ -2075,11 +2087,11 @@ otp_5362(Config) when is_list(Config) ->
[]},
{otp_5362_10,
- <<"-compile({nowarn_deprecated_function,{erlang,hash,2}}).
+ <<"-compile({nowarn_deprecated_function,{erlang,now,0}}).
-compile({nowarn_bif_clash,{spawn,1}}).
-import(x,[spawn/1]).
spin(A) ->
- erlang:hash(A, 3000),
+ erlang:now(),
spawn(A).
">>,
{[nowarn_unused_function,
@@ -2089,11 +2101,11 @@ otp_5362(Config) when is_list(Config) ->
[{2,erl_lint,disallowed_nowarn_bif_clash}],[]}},
{call_deprecated_function,
- <<"t(X) -> erlang:hash(X, 2000).">>,
+ <<"t(X) -> calendar:local_time_to_universal_time(X).">>,
[],
{warnings,
- [{1,erl_lint,{deprecated,{erlang,hash,2},
- {erlang,phash2,2},"a future release"}}]}},
+ [{1,erl_lint,{deprecated,{calendar,local_time_to_universal_time,1},
+ {calendar,local_time_to_universal_time_dst,1}, "a future release"}}]}},
{call_removed_function,
<<"t(X) -> regexp:match(X).">>,
@@ -2540,7 +2552,7 @@ otp_5878(Config) when is_list(Config) ->
{function,9,t,0,[{clause,9,[],[],[{record,10,r,[]}]}]},
{eof,11}],
{error,[{"rec.erl",[{7,erl_lint,old_abstract_code}]}],[]} =
- compile:forms(OldAbstract, [return, report]),
+ compile_forms(OldAbstract, [return, report]),
ok.
@@ -2619,7 +2631,7 @@ otp_11772(Config) when is_list(Config) ->
Ts = <<"
-module(newly).
- -compile(export_all).
+ -export([t/0]).
%% Built-in:
-type node() :: node().
@@ -2644,7 +2656,7 @@ otp_11771(Config) when is_list(Config) ->
Ts = <<"
-module(newly).
- -compile(export_all).
+ -export([t/0]).
%% No longer allowed in 17.0:
-type arity() :: atom().
@@ -2671,7 +2683,7 @@ otp_11872(Config) when is_list(Config) ->
Ts = <<"
-module(map).
- -compile(export_all).
+ -export([t/0]).
-export_type([map/0, product/0]).
@@ -2694,9 +2706,9 @@ export_all(Config) when is_list(Config) ->
id(I) -> I.
">>,
- [] = run_test2(Config, Ts, []),
+ [] = run_test2(Config, Ts, [nowarn_export_all]),
{warnings,[{2,erl_lint,export_all}]} =
- run_test2(Config, Ts, [warn_export_all]),
+ run_test2(Config, Ts, []),
ok.
%% Test warnings for functions that clash with BIFs.
@@ -2997,7 +3009,7 @@ behaviour_basic(Config) when is_list(Config) ->
{behaviour4,
<<"-behavior(application). %% Test callbacks with export_all
- -compile(export_all).
+ -compile([export_all, nowarn_export_all]).
stop(_) -> ok.
">>,
[],
@@ -3048,10 +3060,7 @@ behaviour_multiple(Config) when is_list(Config) ->
handle_info(_, _) -> ok.
">>,
[],
- {warnings,[{1,erl_lint,
- {undefined_behaviour_func,{code_change,3},gen_server}},
- {1,erl_lint,{undefined_behaviour_func,{init,1},gen_server}},
- {1,erl_lint,{undefined_behaviour_func,{terminate,2},gen_server}},
+ {warnings,[{1,erl_lint,{undefined_behaviour_func,{init,1},gen_server}},
{2,erl_lint,{undefined_behaviour_func,{init,1},supervisor}},
{2,
erl_lint,
@@ -3065,10 +3074,7 @@ behaviour_multiple(Config) when is_list(Config) ->
handle_info(_, _) -> ok.
">>,
[],
- {warnings,[{1,erl_lint,
- {undefined_behaviour_func,{code_change,3},gen_server}},
- {1,erl_lint,{undefined_behaviour_func,{init,1},gen_server}},
- {1,erl_lint,{undefined_behaviour_func,{terminate,2},gen_server}},
+ {warnings,[{1,erl_lint,{undefined_behaviour_func,{init,1},gen_server}},
{2,erl_lint,{undefined_behaviour_func,{init,1},supervisor}},
{2,
erl_lint,
@@ -3839,9 +3845,13 @@ otp_11879(_Config) ->
[{1,erl_lint,{spec_fun_undefined,{f,1}}},
{2,erl_lint,spec_wrong_arity},
{22,erl_lint,callback_wrong_arity}]}],
- []} = compile:forms(Fs, [return,report]),
+ []} = compile_forms(Fs, [return,report]),
ok.
+compile_forms(Terms, Opts) ->
+ Forms = [erl_parse:anno_from_term(Term) || Term <- Terms],
+ compile:forms(Forms, Opts).
+
%% OTP-13230: -deprecated without -module.
otp_13230(Config) when is_list(Config) ->
Abstr = <<"-deprecated([{frutt,0,next_version}]).">>,
@@ -3861,6 +3871,287 @@ record_errors(Config) when is_list(Config) ->
{3,erl_lint,{redefine_field,r,a}}],[]}}],
run(Config, Ts).
+otp_11879_cont(Config) ->
+ Ts = [{constraint1,
+ <<"-export([t/1]).
+ -spec t(X) -> X when is_subtype(integer()).
+ t(a) -> foo:bar().
+ ">>,
+ [],
+ {errors,
+ [{2,erl_parse,"unsupported constraint " ++ ["is_subtype"]}],
+ []}},
+ {constraint2,
+ <<"-export([t/1]).
+ -spec t(X) -> X when bad_atom(X, integer()).
+ t(a) -> foo:bar().
+ ">>,
+ [],
+ {errors,
+ [{2,erl_parse,"unsupported constraint " ++ ["bad_atom"]}],
+ []}},
+ {constraint3,
+ <<"-export([t/1]).
+ -spec t(X) -> X when is_subtype(bad_variable, integer()).
+ t(a) -> foo:bar().
+ ">>,
+ [],
+ {errors,[{2,erl_parse,"bad type variable"}],[]}},
+ {constraint4,
+ <<"-export([t/1]).
+ -spec t(X) -> X when is_subtype(atom(), integer()).
+ t(a) -> foo:bar().
+ ">>,
+ [],
+ {errors,[{2,erl_parse,"bad type variable"}],[]}},
+ {constraint5,
+ <<"-export([t/1]).
+ -spec t(X) -> X when is_subtype(X, integer()).
+ t(a) -> foo:bar().
+ ">>,
+ [],
+ []},
+ {constraint6,
+ <<"-export([t/1]).
+ -spec t(X) -> X when X :: integer().
+ t(a) -> foo:bar().
+ ">>,
+ [],
+ []}],
+ run(Config, Ts).
+
+%% OTP-14285: We currently don't support non-latin1 module names.
+
+non_latin1_module(Config) ->
+ do_non_latin1_module('юникод'),
+ do_non_latin1_module(list_to_atom([256,$a,$b,$c])),
+ do_non_latin1_module(list_to_atom([$a,$b,256,$c])),
+
+ "module names with non-latin1 characters are not supported" =
+ format_error(non_latin1_module_unsupported),
+ BadCallback =
+ {bad_callback,{'кирилли́ческий атом','кирилли́ческий атом',0}},
+ "explicit module not allowed for callback "
+ "'кирилли́ческий атом':'кирилли́ческий атом'/0" =
+ format_error(BadCallback),
+ UndefBehav = {undefined_behaviour,'кирилли́ческий атом'},
+ "behaviour 'кирилли́ческий атом' undefined" =
+ format_error(UndefBehav),
+ BadDepr = {bad_nowarn_deprecated_function,
+ {'кирилли́ческий атом','кирилли́ческий атом',18}},
+ "'кирилли́ческий атом':'кирилли́ческий атом'/18 is not a deprecated "
+ "function" = format_error(BadDepr),
+ Ts = [{non_latin1_module,
+ <<"
+ %% Report uses of module names with non-Latin-1 characters.
+
+ -import('кирилли́ческий атом', []).
+ -behaviour('кирилли́ческий атом').
+ -behavior('кирилли́ческий атом').
+
+ -callback 'кирилли́ческий атом':'кирилли́ческий атом'() -> a.
+
+ -compile([{nowarn_deprecated_function,
+ [{'кирилли́ческий атом','кирилли́ческий атом',18}]}]).
+
+ %% erl_lint:gexpr/3 is not extended to check module name here:
+ t1() when 'кирилли́ческий атом':'кирилли́ческий атом'(1) ->
+ b.
+
+ t2() ->
+ 'кирилли́ческий атом':'кирилли́ческий атом'().
+
+ -spec 'кирилли́ческий атом':'кирилли́ческий атом'() -> atom().
+
+ -spec 'кирилли́ческий атом'(integer()) ->
+ 'кирилли́ческий атом':'кирилли́ческий атом'().
+
+ 'кирилли́ческий атом'(1) ->
+ 'кирилли́ческий атом':f(),
+ F = f,
+ 'кирилли́ческий атом':F()."/utf8>>,
+ [],
+ {error,
+ [{4,erl_lint,non_latin1_module_unsupported},
+ {5,erl_lint,non_latin1_module_unsupported},
+ {6,erl_lint,non_latin1_module_unsupported},
+ {8,erl_lint,non_latin1_module_unsupported},
+ {8,erl_lint,BadCallback},
+ {10,erl_lint,non_latin1_module_unsupported},
+ {14,erl_lint,illegal_guard_expr},
+ {18,erl_lint,non_latin1_module_unsupported},
+ {20,erl_lint,non_latin1_module_unsupported},
+ {23,erl_lint,non_latin1_module_unsupported},
+ {26,erl_lint,non_latin1_module_unsupported},
+ {28,erl_lint,non_latin1_module_unsupported}],
+ [{5,erl_lint,UndefBehav},
+ {6,erl_lint,UndefBehav},
+ {10,erl_lint,BadDepr}]}}],
+ run(Config, Ts),
+ ok.
+
+do_non_latin1_module(Mod) ->
+ File = atom_to_list(Mod) ++ ".erl",
+ Forms = [{attribute,1,file,{File,1}},
+ {attribute,1,module,Mod},
+ {eof,2}],
+ error = compile:forms(Forms),
+ {error,_,[]} = compile:forms(Forms, [return]),
+ ok.
+
+
+%% OTP-14323: Check the dialyzer attribute.
+otp_14323(Config) ->
+ Ts = [
+ {otp_14323_1,
+ <<"-import(mod, [m/1]).
+
+ -export([f/0, g/0, h/0]).
+
+ -dialyzer({nowarn_function,module_info/0}). % undefined function
+ -dialyzer({nowarn_function,record_info/2}). % undefined function
+ -dialyzer({nowarn_function,m/1}). % undefined function
+
+ -dialyzer(nowarn_function). % unknown option
+ -dialyzer(1). % badly formed
+ -dialyzer(malformed). % unkonwn option
+ -dialyzer({malformed,f/0}). % unkonwn option
+ -dialyzer({nowarn_function,a/1}). % undefined function
+ -dialyzer({nowarn_function,{a,-1}}). % badly formed
+
+ -dialyzer([no_return, no_match]).
+ -dialyzer({nowarn_function, f/0}).
+ -dialyzer(no_improper_lists).
+ -dialyzer([{nowarn_function, [f/0]}, no_improper_lists]).
+ -dialyzer({no_improper_lists, g/0}).
+ -dialyzer({[no_return, no_match], [g/0, h/0]}).
+
+ f() -> a.
+ g() -> b.
+ h() -> c.">>,
+ [],
+ {errors,[{5,erl_lint,{undefined_function,{module_info,0}}},
+ {6,erl_lint,{undefined_function,{record_info,2}}},
+ {7,erl_lint,{undefined_function,{m,1}}},
+ {9,erl_lint,{bad_dialyzer_option,nowarn_function}},
+ {10,erl_lint,{bad_dialyzer_attribute,1}},
+ {11,erl_lint,{bad_dialyzer_option,malformed}},
+ {12,erl_lint,{bad_dialyzer_option,malformed}},
+ {13,erl_lint,{undefined_function,{a,1}}},
+ {14,erl_lint,{bad_dialyzer_attribute,
+ {nowarn_function,{a,-1}}}}],
+ []}},
+ {otp_14323_2,
+ <<"-type t(_) :: atom().">>,
+ [],
+ {errors,[{1,erl_parse,"bad type variable"}],[]}}],
+ [] = run(Config, Ts),
+ ok.
+
+get_stacktrace(Config) ->
+ Ts = [{old_catch,
+ <<"t1() ->
+ catch error(foo),
+ erlang:get_stacktrace().
+ ">>,
+ [],
+ {warnings,[{3,erl_lint,{get_stacktrace,after_old_catch}}]}},
+ {nowarn_get_stacktrace,
+ <<"t1() ->
+ catch error(foo),
+ erlang:get_stacktrace().
+ ">>,
+ [nowarn_get_stacktrace],
+ []},
+ {try_catch,
+ <<"t1(X) ->
+ try abs(X) of
+ _ ->
+ erlang:get_stacktrace()
+ catch
+ _:_ -> ok
+ end.
+
+ t2() ->
+ try error(foo)
+ catch _:_ -> ok
+ end,
+ erlang:get_stacktrace().
+
+ t3() ->
+ try error(foo)
+ catch _:_ ->
+ try error(bar)
+ catch _:_ ->
+ ok
+ end,
+ erlang:get_stacktrace()
+ end.
+
+ no_warning(X) ->
+ try
+ abs(X)
+ catch
+ _:_ ->
+ erlang:get_stacktrace()
+ end.
+ ">>,
+ [],
+ {warnings,[{4,erl_lint,{get_stacktrace,wrong_part_of_try}},
+ {13,erl_lint,{get_stacktrace,after_try}},
+ {22,erl_lint,{get_stacktrace,after_try}}]}}],
+
+ run(Config, Ts),
+ ok.
+
+%% Unicode atoms.
+otp_14285(Config) ->
+ %% A small sample of all the errors and warnings in module erl_lint.
+ E1 = {redefine_function,{'кирилли́ческий атом',0}},
+ E2 = {attribute,'кирилли́ческий атом'},
+ E3 = {undefined_record,'кирилли́ческий атом'},
+ E4 = {undefined_bittype,'кирилли́ческий атом'},
+ "function 'кирилли́ческий атом'/0 already defined" = format_error(E1),
+ "attribute 'кирилли́ческий атом' after function definitions" =
+ format_error(E2),
+ "record 'кирилли́ческий атом' undefined" = format_error(E3),
+ "bit type 'кирилли́ческий атом' undefined" = format_error(E4),
+ Ts = [{otp_14285_1,
+ <<"'кирилли́ческий атом'() -> a.
+ 'кирилли́ческий атом'() -> a.
+ "/utf8>>,
+ [],
+ {errors,
+ [{2,erl_lint,E1}],
+ []}},
+ {otp_14285_2,
+ <<"'кирилли́ческий атом'() -> a.
+ -'кирилли́ческий атом'(a).
+ "/utf8>>,
+ [],
+ {errors,
+ [{2,erl_lint,E2}],
+ []}},
+ {otp_14285_3,
+ <<"'кирилли́ческий атом'() -> #'кирилли́ческий атом'{}.
+ "/utf8>>,
+ [],
+ {errors,
+ [{1,erl_lint,E3}],
+ []}},
+ {otp_14285_4,
+ <<"t() -> <<34/'кирилли́ческий атом'>>.
+ "/utf8>>,
+ [],
+ {errors,
+ [{1,erl_lint,E4}],
+ []}}],
+ run(Config, Ts),
+ ok.
+
+format_error(E) ->
+ lists:flatten(erl_lint:format_error(E)).
+
run(Config, Tests) ->
F = fun({N,P,Ws,E}, BadL) ->
case catch run_test(Config, P, Ws) of
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index a103f6dc53..808ba9b4c1 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@
otp_6321/1, otp_6911/1, otp_6914/1, otp_8150/1, otp_8238/1,
otp_8473/1, otp_8522/1, otp_8567/1, otp_8664/1, otp_9147/1,
otp_10302/1, otp_10820/1, otp_11100/1, otp_11861/1, pr_1014/1,
- otp_13662/1]).
+ otp_13662/1, otp_14285/1]).
%% Internal export.
-export([ehook/6]).
@@ -80,7 +80,8 @@ groups() ->
{tickets, [],
[otp_6321, otp_6911, otp_6914, otp_8150, otp_8238,
otp_8473, otp_8522, otp_8567, otp_8664, otp_9147,
- otp_10302, otp_10820, otp_11100, otp_11861, pr_1014, otp_13662]}].
+ otp_10302, otp_10820, otp_11100, otp_11861, pr_1014, otp_13662,
+ otp_14285]}].
init_per_suite(Config) ->
Config.
@@ -627,11 +628,6 @@ do_hook(HookFun) ->
true =
"{some,value}" =:= lists:flatten(erl_pp:expr({value,A0,{some,value}})),
- %% Silly...
- true =
- "if true -> 0 end" =:=
- flat_expr({'if',0,[{clause,0,[],[],[{atom,0,0}]}]}),
-
%% More compatibility: before R6
OldIf = {'if',A0,[{clause,A0,[],[{atom,A0,true}],[{atom,A0,b}]}]},
NewIf = {'if',A0,[{clause,A0,[],[[{atom,A0,true}]],[{atom,A0,b}]}]},
@@ -825,12 +821,13 @@ type_examples() ->
%% is_subtype(V, T) syntax, we need a few examples of the syntax.
{ex31,<<"-spec t1(FooBar :: t99()) -> t99();"
"(t2()) -> t2();"
- "('\\'t::4'()) -> '\\'t::4'() when is_subtype('\\'t::4'(), t24);"
- "(t23()) -> t23() when is_subtype(t23(), atom()),"
- " is_subtype(t23(), t14());"
- "(t24()) -> t24() when is_subtype(t24(), atom()),"
- " is_subtype(t24(), t14()),"
- " is_subtype(t24(), '\\'t::4'()).">>},
+ "('\\'t::4'()) -> {'\\'t::4'(), B}"
+ " when is_subtype(B, '\\'t::4'());"
+ "(t23()) -> C when is_subtype(C, atom()),"
+ " is_subtype(C, t14());"
+ "(t24()) -> D when is_subtype(D, atom()),"
+ " is_subtype(D, t14()),"
+ " is_subtype(D, '\\'t::4'()).">>},
{ex32,<<"-spec mod:t2() -> any(). ">>},
{ex33,<<"-opaque attributes_data() :: "
"[{'column', column()} | {'line', info_line()} |"
@@ -1067,9 +1064,6 @@ otp_11100(Config) when is_list(Config) ->
%% There are a few places where the added code ("options(none)")
%% doesn't make a difference (pp:bit_elem_type/1 is an example).
- %% Cannot trigger the use of the hook function with export/import.
- "-export([{fy,a}/b]).\n" =
- pf({attribute,1,export,[{{fy,a},b}]}),
A1 = erl_anno:new(1),
"-type foo() :: integer(INVALID-FORM:{foo,bar}:).\n" =
pf({attribute,A1,type,{foo,{type,A1,integer,[{foo,bar}]},[]}}),
@@ -1099,10 +1093,11 @@ otp_11100(Config) when is_list(Config) ->
%% OTP-11861. behaviour_info() and -callback.
otp_11861(Config) when is_list(Config) ->
+ A3 = erl_anno:new(3),
"-optional_callbacks([bar/0]).\n" =
- pf({attribute,3,optional_callbacks,[{bar,0}]}),
+ pf({attribute,A3,optional_callbacks,[{bar,0}]}),
"-optional_callbacks([{bar,1,bad}]).\n" =
- pf({attribute,4,optional_callbacks,[{bar,1,bad}]}),
+ pf({attribute,A3,optional_callbacks,[{bar,1,bad}]}),
ok.
pf(Form) ->
@@ -1144,6 +1139,34 @@ otp_13662(Config) ->
],
compile(Config, Ts).
+otp_14285(_Config) ->
+ pp_forms(<<"-export([t/0, '\\x{400}\\''/0]).">>),
+ pp_forms(<<"-import(lists, [append/2]).">>),
+ pp_forms(<<"-optional_callbacks([]).">>),
+ pp_forms(<<"-optional_callbacks(['\\x{400}\\''/1]).">>),
+ pp_forms(<<"-'\\x{400}\\''('\\x{400}\\'').">>),
+ pp_forms(<<"-type '\\x{400}\\''() :: '\\x{400}\\''.">>),
+ pp_forms(<<"-record('\\x{400}\\'', {'\\x{400}\\''}).">>),
+ pp_forms(<<"-callback '\\x{400}\\''(_) -> '\\x{400}\\''.">>),
+ pp_forms(<<"t() -> '\\x{400}\\''('\\x{400}\\'').">>),
+ pp_forms(<<"'\\x{400}\\''(_) -> '\\x{400}\\''.">>),
+ pp_forms(<<"-spec '\\x{400}'() -> "
+ "#'\\x{400}'{'\\x{400}' :: '\\x{400}'}.">>),
+ pp_forms(<<"'\\x{400}\\''() ->"
+ "R = #'\\x{400}\\''{},"
+ "#'\\x{400}\\''{'\\x{400}\\'' ="
+ "{'\\x{400}\\'',"
+ "fun '\\x{400}\\''/0,"
+ "R#'\\x{400}\\''.'\\x{400}\\'',"
+ "#'\\x{400}\\''.'\\x{400}\\''}}.">>),
+
+ %% Special...
+ true =
+ "{some,'\\x{400}\\''}" =:=
+ lists:flatten(erl_pp:expr({value,erl_anno:new(0),{some,'\x{400}\''}},
+ [{encoding,latin1}])),
+ ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
compile(Config, Tests) ->
@@ -1166,19 +1189,21 @@ compile(Config, Tests) ->
lists:foldl(F, [], Tests).
compile_file(Config, Test0) ->
- case compile_file(Config, Test0, ['E']) of
+ Test = ["-module(erl_pp_test).\n",
+ "-compile(export_all).\n",
+ Test0],
+ case compile_file(Config, Test, ['E']) of
{ok, RootFile} ->
File = RootFile ++ ".E",
{ok, Bin0} = file:read_file(File),
- Bin = strip_module_info(Bin0),
%% A very simple check: just try to compile the output.
- case compile_file(Config, Bin, []) of
+ case compile_file(Config, Bin0, []) of
{ok, RootFile2} ->
File2 = RootFile2 ++ ".E",
{ok, Bin1} = file:read_file(File2),
case Bin0 =:= Bin1 of
true ->
- test_max_line(binary_to_list(Bin));
+ test_max_line(binary_to_list(Bin0));
false ->
{error, file_contents_modified, {Bin0, Bin1}}
end;
@@ -1189,11 +1214,8 @@ compile_file(Config, Test0) ->
Error
end.
-compile_file(Config, Test0, Opts0) ->
+compile_file(Config, Test, Opts0) ->
FileName = filename('erl_pp_test.erl', Config),
- Test = list_to_binary(["-module(erl_pp_test). "
- "-compile(export_all). ",
- Test0]),
Opts = [export_all,return,nowarn_unused_record,{outdir,?privdir} | Opts0],
ok = file:write_file(FileName, Test),
case compile:file(FileName, Opts) of
@@ -1202,11 +1224,6 @@ compile_file(Config, Test0, Opts0) ->
Error -> Error
end.
-strip_module_info(Bin) ->
- {match, [{Start,_Len}|_]} = re:run(Bin, "module_info"),
- <<R:Start/binary,_/binary>> = Bin,
- R.
-
flat_expr1(Expr0) ->
Expr = erl_parse:new_anno(Expr0),
lists:flatten(erl_pp:expr(Expr)).
diff --git a/lib/stdlib/test/erl_scan_SUITE.erl b/lib/stdlib/test/erl_scan_SUITE.erl
index 4ae734eb65..aca5b1e54f 100644
--- a/lib/stdlib/test/erl_scan_SUITE.erl
+++ b/lib/stdlib/test/erl_scan_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -772,10 +772,9 @@ unicode() ->
erl_scan:string([1089]),
{error,{{1,1},erl_scan,{illegal,character}},{1,2}} =
erl_scan:string([1089], {1,1}),
- {error,{1,erl_scan,{illegal,atom}},1} =
- erl_scan:string("'a"++[1089]++"b'", 1),
- {error,{{1,1},erl_scan,{illegal,atom}},{1,6}} =
- erl_scan:string("'a"++[1089]++"b'", {1,1}),
+ {error,{{1,3},erl_scan,{illegal,character}},{1,4}} =
+ erl_scan:string("'a" ++ [999999999] ++ "c'", {1,1}),
+
test("\"a"++[1089]++"b\""),
{ok,[{char,1,1}],1} =
erl_scan_string([$$,$\\,$^,1089], 1),
@@ -786,8 +785,8 @@ unicode() ->
erl_scan:format_error(Error),
{error,{{1,1},erl_scan,_},{1,11}} =
erl_scan:string("\"qa\\x{aaa}",{1,1}),
- {error,{{1,1},erl_scan,{illegal,atom}},{1,12}} =
- erl_scan:string("'qa\\x{aaa}'",{1,1}),
+ {error,{{1,1},erl_scan,_},{1,11}} =
+ erl_scan:string("'qa\\x{aaa}",{1,1}),
{ok,[{char,1,1089}],1} =
erl_scan_string([$$,1089], 1),
@@ -904,10 +903,10 @@ more_chars() ->
%% OTP-10302. Unicode characters scanner/parser.
otp_10302(Config) when is_list(Config) ->
%% From unicode():
- {error,{1,erl_scan,{illegal,atom}},1} =
- erl_scan:string("'a"++[1089]++"b'", 1),
- {error,{{1,1},erl_scan,{illegal,atom}},{1,12}} =
- erl_scan:string("'qa\\x{aaa}'",{1,1}),
+ {ok,[{atom,1,'aсb'}],1} =
+ erl_scan_string("'a"++[1089]++"b'", 1),
+ {ok,[{atom,{1,1},'qaપ'}],{1,12}} =
+ erl_scan_string("'qa\\x{aaa}'",{1,1}),
{ok,[{char,1,1089}],1} = erl_scan_string([$$,1089], 1),
{ok,[{char,1,1089}],1} = erl_scan_string([$$,$\\,1089],1),
diff --git a/lib/stdlib/test/error_logger_h_SUITE.erl b/lib/stdlib/test/error_logger_h_SUITE.erl
index 2a34c7764f..30f96e0522 100644
--- a/lib/stdlib/test/error_logger_h_SUITE.erl
+++ b/lib/stdlib/test/error_logger_h_SUITE.erl
@@ -297,13 +297,13 @@ match_format(Tag, [Format,Args], [Head|Lines], AtNode, Depth) ->
iolist_to_binary(S)
end,
Expected0 = binary:split(Bin, <<"\n">>, [global,trim]),
- Expected = Expected0 ++ AtNode,
+ Expected = AtNode ++ Expected0,
match_term_lines(Expected, Lines).
match_term(Tag, [Arg], [Head|Lines], AtNode, Depth) ->
match_head(Tag, Head),
Expected0 = match_term_get_expected(Arg, Depth),
- Expected = Expected0 ++ AtNode,
+ Expected = AtNode ++ Expected0,
match_term_lines(Expected, Lines).
match_term_get_expected(List, Depth) when is_list(List) ->
diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl
index 28d69232a0..0b9106a99c 100644
--- a/lib/stdlib/test/escript_SUITE.erl
+++ b/lib/stdlib/test/escript_SUITE.erl
@@ -28,6 +28,7 @@
strange_name/1,
emulator_flags/1,
emulator_flags_no_shebang/1,
+ two_lines/1,
module_script/1,
beam_script/1,
archive_script/1,
@@ -49,7 +50,7 @@ suite() ->
all() ->
[basic, errors, strange_name, emulator_flags,
- emulator_flags_no_shebang,
+ emulator_flags_no_shebang, two_lines,
module_script, beam_script, archive_script, epp,
create_and_extract, foldl, overflow,
archive_script_file_access, unicode].
@@ -153,6 +154,18 @@ emulator_flags(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+two_lines(Config) when is_list(Config) ->
+ Data = proplists:get_value(data_dir, Config),
+ Dir = filename:absname(Data), %Get rid of trailing slash.
+ run(Dir, "two_lines -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>]),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
emulator_flags_no_shebang(Config) when is_list(Config) ->
Data = proplists:get_value(data_dir, Config),
Dir = filename:absname(Data), %Get rid of trailing slash.
diff --git a/lib/stdlib/test/escript_SUITE_data/two_lines b/lib/stdlib/test/escript_SUITE_data/two_lines
new file mode 100755
index 0000000000..cf4e99639c
--- /dev/null
+++ b/lib/stdlib/test/escript_SUITE_data/two_lines
@@ -0,0 +1,2 @@
+#! /usr/bin/env escript
+main(MainArgs) -> io:format("main:~p\n", [MainArgs]), ErlArgs = init:get_arguments(), io:format("ERL_FLAGS=~p\n", [os:getenv("ERL_FLAGS")]), io:format("unknown:~p\n",[[E || E <- ErlArgs, element(1, E) =:= unknown]]).
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 8c1c625676..05451a83fb 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,10 +19,10 @@
%%
-module(ets_SUITE).
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2]).
-export([default/1,setbag/1,badnew/1,verybadnew/1,named/1,keypos2/1,
- privacy/1,privacy_owner/2]).
+ privacy/1]).
-export([empty/1,badinsert/1]).
-export([time_lookup/1,badlookup/1,lookup_order/1]).
-export([delete_elem/1,delete_tab/1,delete_large_tab/1,
@@ -31,22 +31,23 @@
-export([match_delete3/1]).
-export([firstnext/1,firstnext_concurrent/1]).
-export([slot/1]).
--export([ match1/1, match2/1, match_object/1, match_object2/1]).
--export([ dups/1, misc1/1, safe_fixtable/1, info/1, tab2list/1]).
--export([ tab2file/1, tab2file2/1, tabfile_ext1/1,
- tabfile_ext2/1, tabfile_ext3/1, tabfile_ext4/1, badfile/1]).
--export([ heavy_lookup/1, heavy_lookup_element/1, heavy_concurrent/1]).
--export([ lookup_element_mult/1]).
--export([]).
+-export([match1/1, match2/1, match_object/1, match_object2/1]).
+-export([dups/1, misc1/1, safe_fixtable/1, info/1, tab2list/1]).
+-export([tab2file/1, tab2file2/1, tabfile_ext1/1,
+ tabfile_ext2/1, tabfile_ext3/1, tabfile_ext4/1, badfile/1]).
+-export([heavy_lookup/1, heavy_lookup_element/1, heavy_concurrent/1]).
+-export([lookup_element_mult/1]).
-export([foldl_ordered/1, foldr_ordered/1, foldl/1, foldr/1, fold_empty/1]).
--export([t_delete_object/1, t_init_table/1, t_whitebox/1,
+-export([t_delete_object/1, t_init_table/1, t_whitebox/1,
+ select_bound_chunk/1,
t_delete_all_objects/1, t_insert_list/1, t_test_ms/1,
- t_select_delete/1,t_ets_dets/1]).
+ t_select_delete/1,t_select_replace/1,t_ets_dets/1]).
-export([ordered/1, ordered_match/1, interface_equality/1,
fixtable_next/1, fixtable_insert/1, rename/1, rename_unnamed/1, evil_rename/1,
update_element/1, update_counter/1, evil_update_counter/1, partly_bound/1, match_heavy/1]).
-export([update_counter_with_default/1]).
+-export([update_counter_table_growth/1]).
-export([member/1]).
-export([memory/1]).
-export([select_fail/1]).
@@ -60,12 +61,11 @@
-export([otp_7665/1]).
-export([meta_wb/1]).
-export([grow_shrink/1, grow_pseudo_deleted/1, shrink_pseudo_deleted/1]).
--export([
- meta_lookup_unnamed_read/1, meta_lookup_unnamed_write/1,
+-export([meta_lookup_unnamed_read/1, meta_lookup_unnamed_write/1,
meta_lookup_named_read/1, meta_lookup_named_write/1,
meta_newdel_unnamed/1, meta_newdel_named/1]).
-export([smp_insert/1, smp_fixed_delete/1, smp_unfix_fix/1, smp_select_delete/1,
- otp_8166/1, otp_8732/1]).
+ smp_select_replace/1, otp_8166/1, otp_8732/1]).
-export([exit_large_table_owner/1,
exit_many_large_table_owner/1,
exit_many_tables_owner/1,
@@ -76,45 +76,25 @@
-export([otp_9423/1]).
-export([otp_10182/1]).
-export([ets_all/1]).
--export([memory_check_summary/1]).
+-export([massive_ets_all/1]).
-export([take/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
%% Convenience for manual testing
-export([random_test/0]).
-%% internal exports
--export([dont_make_worse_sub/0, make_better_sub1/0, make_better_sub2/0]).
--export([t_repair_continuation_do/1, t_bucket_disappears_do/1,
- select_fail_do/1, whitebox_1/1, whitebox_2/1, t_delete_all_objects_do/1,
- t_delete_object_do/1, t_init_table_do/1, t_insert_list_do/1,
- update_element_opts/1, update_element_opts/4, update_element/4, update_element_do/4,
- update_element_neg/1, update_element_neg_do/1, update_counter_do/1, update_counter_neg/1,
- evil_update_counter_do/1, fixtable_next_do/1, heir_do/1, give_away_do/1, setopts_do/1,
- rename_do/1, rename_unnamed_do/1, interface_equality_do/1, ordered_match_do/1,
- ordered_do/1, privacy_do/1, empty_do/1, badinsert_do/1, time_lookup_do/1,
- lookup_order_do/1, lookup_element_mult_do/1, delete_tab_do/1, delete_elem_do/1,
- match_delete_do/1, match_delete3_do/1, firstnext_do/1,
- slot_do/1, match1_do/1, match2_do/1, match_object_do/1, match_object2_do/1,
- misc1_do/1, safe_fixtable_do/1, info_do/1, dups_do/1, heavy_lookup_do/1,
- heavy_lookup_element_do/1, member_do/1, otp_5340_do/1, otp_7665_do/1, meta_wb_do/1,
- do_heavy_concurrent/1, tab2file2_do/2, exit_large_table_owner_do/2,
- types_do/1, sleeper/0, memory_do/1, update_counter_with_default_do/1,
- ms_tracee_dummy/1, ms_tracee_dummy/2, ms_tracee_dummy/3, ms_tracee_dummy/4
- ]).
-
-export([t_select_reverse/1]).
-include_lib("common_test/include/ct.hrl").
-define(m(A,B), assert_eq(A,B)).
+-define(heap_binary_size, 64).
init_per_testcase(Case, Config) ->
rand:seed(exsplus),
io:format("*** SEED: ~p ***\n", [rand:export_seed()]),
start_spawn_logger(),
wait_for_test_procs(), %% Ensure previous case cleaned up
- put('__ETS_TEST_CASE__', Case),
[{test_case, Case} | Config].
end_per_testcase(_Func, _Config) ->
@@ -127,7 +107,7 @@ suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap,{minutes,5}}].
-all() ->
+all() ->
[{group, new}, {group, insert}, {group, lookup},
{group, delete}, firstnext, firstnext_concurrent, slot,
{group, match}, t_match_spec_run,
@@ -137,16 +117,18 @@ all() ->
rename, rename_unnamed, evil_rename, update_element,
update_counter, evil_update_counter,
update_counter_with_default, partly_bound,
+ update_counter_table_growth,
match_heavy, {group, fold}, member, t_delete_object,
+ select_bound_chunk,
t_init_table, t_whitebox, t_delete_all_objects,
- t_insert_list, t_test_ms, t_select_delete, t_ets_dets,
- memory, t_select_reverse, t_bucket_disappears,
+ t_insert_list, t_test_ms, t_select_delete, t_select_replace,
+ t_ets_dets, memory, t_select_reverse, t_bucket_disappears,
select_fail, t_insert_new, t_repair_continuation,
otp_5340, otp_6338, otp_6842_select_1000, otp_7665,
otp_8732, meta_wb, grow_shrink, grow_pseudo_deleted,
shrink_pseudo_deleted, {group, meta_smp}, smp_insert,
- smp_fixed_delete, smp_unfix_fix, smp_select_delete,
- otp_8166, exit_large_table_owner,
+ smp_fixed_delete, smp_unfix_fix, smp_select_replace,
+ smp_select_delete, otp_8166, exit_large_table_owner,
exit_many_large_table_owner, exit_many_tables_owner,
exit_many_many_tables_owner, write_concurrency, heir,
give_away, setopts, bad_table, types,
@@ -154,11 +136,10 @@ all() ->
otp_9932,
otp_9423,
ets_all,
- take,
-
- memory_check_summary]. % MUST BE LAST
+ massive_ets_all,
+ take].
-groups() ->
+groups() ->
[{new, [],
[default, setbag, badnew, verybadnew, named, keypos2,
privacy]},
@@ -201,33 +182,12 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-%% Test that we did not have "too many" failed verify_etsmem()'s
-%% in the test suite.
-%% verify_etsmem() may give a low number of false positives
-%% as concurrent activities, such as lingering processes
-%% from earlier test suites, may do unrelated ets (de)allocations.
-memory_check_summary(_Config) ->
- case whereis(ets_test_spawn_logger) of
- undefined ->
- ct:fail("No spawn logger exist");
- _ ->
- ets_test_spawn_logger ! {self(), get_failed_memchecks},
- receive {get_failed_memchecks, FailedMemchecks} -> ok end,
- io:format("Failed memchecks: ~p\n",[FailedMemchecks]),
- NoFailedMemchecks = length(FailedMemchecks),
- if NoFailedMemchecks > 3 ->
- ct:fail("Too many failed (~p) memchecks", [NoFailedMemchecks]);
- true ->
- ok
- end
- end.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Test that a disappearing bucket during select of a non-fixed table works.
t_bucket_disappears(Config) when is_list(Config) ->
- repeat_for_opts(t_bucket_disappears_do).
+ repeat_for_opts(fun t_bucket_disappears_do/1).
t_bucket_disappears_do(Opts) ->
EtsMem = etsmem(),
@@ -246,6 +206,7 @@ t_bucket_disappears_do(Opts) ->
%% Check ets:match_spec_run/2.
t_match_spec_run(Config) when is_list(Config) ->
+ ct:timetrap({minutes,30}), %% valgrind needs a lot
init_externals(),
EtsMem = etsmem(),
@@ -394,11 +355,16 @@ ms_tracer_collect(Tracee, Ref, Acc) ->
ms_tracee(Parent, CallArgList) ->
Parent ! {self(), ready},
receive start -> ok end,
- lists:foreach(fun(Args) ->
- erlang:apply(?MODULE, ms_tracee_dummy, tuple_to_list(Args))
- end, CallArgList).
-
-
+ F = fun({A1}) ->
+ ms_tracee_dummy(A1);
+ ({A1,A2}) ->
+ ms_tracee_dummy(A1, A2);
+ ({A1,A2,A3}) ->
+ ms_tracee_dummy(A1, A2, A3);
+ ({A1,A2,A3,A4}) ->
+ ms_tracee_dummy(A1, A2, A3, A4)
+ end,
+ lists:foreach(F, CallArgList).
ms_tracee_dummy(_) -> ok.
ms_tracee_dummy(_,_) -> ok.
@@ -416,7 +382,7 @@ assert_eq(A,B) ->
%% Test ets:repair_continuation/2.
t_repair_continuation(Config) when is_list(Config) ->
- repeat_for_opts(t_repair_continuation_do).
+ repeat_for_opts(fun t_repair_continuation_do/1).
t_repair_continuation_do(Opts) ->
@@ -562,7 +528,8 @@ default(Config) when is_list(Config) ->
%% Test that select fails even if nothing can match.
select_fail(Config) when is_list(Config) ->
EtsMem = etsmem(),
- repeat_for_opts(select_fail_do, [all_types,write_concurrency]),
+ repeat_for_opts(fun select_fail_do/1,
+ [all_types,write_concurrency]),
verify_etsmem(EtsMem).
select_fail_do(Opts) ->
@@ -588,27 +555,21 @@ select_fail_do(Opts) ->
-define(S(T),ets:info(T,memory)).
--define(TAB_STRUCT_SZ, erts_debug:get_internal_state('DbTable_words')).
-%%-define(NORMAL_TAB_STRUCT_SZ, 26). %% SunOS5.8, 32-bit, non smp, private heap
-%%
-%% The hardcoded expected memory sizes (in words) are the ones we expect on:
-%% SunOS5.8, 32-bit, non smp, private heap
-%%
%% Whitebox test of ets:info(X, memory).
memory(Config) when is_list(Config) ->
ok = chk_normal_tab_struct_size(),
- repeat_for_opts(memory_do,[compressed]),
+ repeat_for_opts(fun memory_do/1, [compressed]),
catch erts_debug:set_internal_state(available_internal_state, false).
memory_do(Opts) ->
L = [T1,T2,T3,T4] = fill_sets_int(1000,Opts),
XR1 = case mem_mode(T1) of
- {normal,_} -> {13836,13046,13046,13052}; %{13862,13072,13072,13078};
- {compressed,4} -> {11041,10251,10251,10252}; %{11067,10277,10277,10278};
- {compressed,8} -> {10050,9260,9260,9260} %{10076,9286,9286,9286}
+ {normal,_} -> {13836, 15346, 15346, 15346+6};
+ {compressed,4} -> {11041, 12551, 12551, 12551+1};
+ {compressed,8} -> {10050, 11560, 11560, 11560}
end,
- XRes1 = adjust_xmem(L, XR1),
+ XRes1 = adjust_xmem(L, XR1, 1),
Res1 = {?S(T1),?S(T2),?S(T3),?S(T4)},
lists:foreach(fun(T) ->
Before = ets:info(T,size),
@@ -620,11 +581,11 @@ memory_do(Opts) ->
end,
L),
XR2 = case mem_mode(T1) of
- {normal,_} -> {13826,13037,13028,13034}; %{13852,13063,13054,13060};
- {compressed,4} -> {11031,10242,10233,10234}; %{11057,10268,10259,10260};
- {compressed,8} -> {10040,9251,9242,9242} %10066,9277,9268,9268}
+ {normal,_} -> {13826, 15337, 15337-9, 15337-3};
+ {compressed,4} -> {11031, 12542, 12542-9, 12542-8};
+ {compressed,8} -> {10040, 11551, 11551-9, 11551-9}
end,
- XRes2 = adjust_xmem(L, XR2),
+ XRes2 = adjust_xmem(L, XR2, 1),
Res2 = {?S(T1),?S(T2),?S(T3),?S(T4)},
lists:foreach(fun(T) ->
Before = ets:info(T,size),
@@ -636,17 +597,17 @@ memory_do(Opts) ->
end,
L),
XR3 = case mem_mode(T1) of
- {normal,_} -> {13816,13028,13010,13016}; %{13842,13054,13036,13042};
- {compressed,4} -> {11021,10233,10215,10216}; %{11047,10259,10241,10242};
- {compressed,8} -> {10030,9242,9224,9224} %{10056,9268,9250,9250}
+ {normal,_} -> {13816, 15328, 15328-18, 15328-12};
+ {compressed,4} -> {11021, 12533, 12533-18, 12533-17};
+ {compressed,8} -> {10030, 11542, 11542-18, 11542-18}
end,
- XRes3 = adjust_xmem(L, XR3),
+ XRes3 = adjust_xmem(L, XR3, 1),
Res3 = {?S(T1),?S(T2),?S(T3),?S(T4)},
lists:foreach(fun(T) ->
ets:delete_all_objects(T)
end,
L),
- XRes4 = adjust_xmem(L, {50,260,260,260}), %{76,286,286,286}),
+ XRes4 = adjust_xmem(L, {50, 256, 256, 256}, 0),
Res4 = {?S(T1),?S(T2),?S(T3),?S(T4)},
lists:foreach(fun(T) ->
ets:delete(T)
@@ -657,7 +618,7 @@ memory_do(Opts) ->
ets:select_delete(T,[{'_',[],[true]}])
end,
L2),
- XRes5 = adjust_xmem(L2, {50,260,260,260}), %{76,286,286,286}),
+ XRes5 = adjust_xmem(L2, {50, 256, 256, 256}, 0),
Res5 = {?S(T11),?S(T12),?S(T13),?S(T14)},
io:format("XRes1 = ~p~n"
" Res1 = ~p~n~n"
@@ -695,25 +656,25 @@ chk_normal_tab_struct_size() ->
erlang:system_info(smp_support),
erlang:system_info(heap_type)},
io:format("System = ~p~n", [System]),
- io:format("?TAB_STRUCT_SZ=~p~n", [?TAB_STRUCT_SZ]),
ok.
-adjust_xmem([_T1,_T2,_T3,_T4], {A0,B0,C0,D0} = _Mem0) ->
+adjust_xmem([_T1,_T2,_T3,_T4], {A0,B0,C0,D0} = _Mem0, EstCnt) ->
%% Adjust for 64-bit, smp, and os:
%% Table struct size may differ.
- TabDiff = ?TAB_STRUCT_SZ,
- {A0+TabDiff, B0+TabDiff, C0+TabDiff, D0+TabDiff}.
+ {TabSz, EstSz} = erts_debug:get_internal_state('DbTable_words'),
+ HTabSz = TabSz + EstCnt*EstSz,
+ {A0+TabSz, B0+HTabSz, C0+HTabSz, D0+HTabSz}.
%% Misc. whitebox tests
-t_whitebox(Config) when is_list(Config) ->
+t_whitebox(Config) when is_list(Config) ->
EtsMem = etsmem(),
- repeat_for_opts(whitebox_1),
- repeat_for_opts(whitebox_1),
- repeat_for_opts(whitebox_1),
- repeat_for_opts(whitebox_2),
- repeat_for_opts(whitebox_2),
- repeat_for_opts(whitebox_2),
+ repeat_for_opts(fun whitebox_1/1),
+ repeat_for_opts(fun whitebox_1/1),
+ repeat_for_opts(fun whitebox_1/1),
+ repeat_for_opts(fun whitebox_2/1),
+ repeat_for_opts(fun whitebox_2/1),
+ repeat_for_opts(fun whitebox_2/1),
verify_etsmem(EtsMem).
whitebox_1(Opts) ->
@@ -737,6 +698,15 @@ whitebox_2(Opts) ->
ets:delete(T2),
ok.
+select_bound_chunk(Config) ->
+ repeat_for_opts(fun select_bound_chunk_do/1, [all_types]).
+
+select_bound_chunk_do(Opts) ->
+ T = ets:new(x, Opts),
+ ets:insert(T, [{key, 1}]),
+ {[{key, 1}], '$end_of_table'} = ets:select(T, [{{key,1},[],['$_']}], 100000),
+ ok.
+
%% Test ets:to/from_dets.
t_ets_dets(Config) when is_list(Config) ->
@@ -778,7 +748,7 @@ check_badarg({'EXIT', {badarg, [{M,F,A,_} | _]}}, M, F, Args) ->
%% Test ets:delete_all_objects/1.
t_delete_all_objects(Config) when is_list(Config) ->
EtsMem = etsmem(),
- repeat_for_opts(t_delete_all_objects_do),
+ repeat_for_opts(fun t_delete_all_objects_do/1),
verify_etsmem(EtsMem).
get_kept_objects(T) ->
@@ -812,7 +782,7 @@ t_delete_all_objects_do(Opts) ->
%% Test ets:delete_object/2.
t_delete_object(Config) when is_list(Config) ->
EtsMem = etsmem(),
- repeat_for_opts(t_delete_object_do),
+ repeat_for_opts(fun t_delete_object_do/1),
verify_etsmem(EtsMem).
t_delete_object_do(Opts) ->
@@ -885,7 +855,7 @@ make_init_fun(N) ->
%% Test ets:init_table/2.
t_init_table(Config) when is_list(Config)->
EtsMem = etsmem(),
- repeat_for_opts(t_init_table_do),
+ repeat_for_opts(fun t_init_table_do/1),
verify_etsmem(EtsMem).
t_init_table_do(Opts) ->
@@ -961,7 +931,7 @@ t_insert_new(Config) when is_list(Config) ->
%% Test ets:insert/2 with list of objects.
t_insert_list(Config) when is_list(Config) ->
EtsMem = etsmem(),
- repeat_for_opts(t_insert_list_do),
+ repeat_for_opts(fun t_insert_list_do/1),
verify_etsmem(EtsMem).
t_insert_list_do(Opts) ->
@@ -1047,6 +1017,7 @@ do_reverse_chunked({L,C},Acc) ->
%% Test the ets:select_delete/2 and ets:select_count/2 BIFs.
t_select_delete(Config) when is_list(Config) ->
+ ct:timetrap({minutes,30}), %% valgrind needs a lot
EtsMem = etsmem(),
Tables = fill_sets_int(10000) ++ fill_sets_int(10000,[{write_concurrency,true}]),
lists:foreach
@@ -1177,6 +1148,231 @@ t_select_delete(Config) when is_list(Config) ->
lists:foreach(fun(Tab) -> ets:delete(Tab) end,Tables),
verify_etsmem(EtsMem).
+%% Tests the ets:select_replace/2 BIF
+t_select_replace(Config) when is_list(Config) ->
+ EtsMem = etsmem(),
+ Tables = fill_sets_int(10000) ++ fill_sets_int(10000, [{write_concurrency,true}]),
+
+ TestFun = fun (Table, TableType) when TableType =:= bag ->
+ % Operation not supported; bag implementation
+ % presented both semantic consistency and performance issues.
+ 10000 = ets:select_delete(Table, [{'_',[],[true]}]);
+
+ (Table, TableType) ->
+ % Invalid replacement doesn't keep the key
+ MatchSpec1 = [{{'$1', '$2'},
+ [{'=:=', {'band', '$1', 2#11}, 2#11},
+ {'=/=', {'hd', '$2'}, $x}],
+ [{{'$2', '$1'}}]}],
+ {'EXIT',{badarg,_}} = (catch ets:select_replace(Table, MatchSpec1)),
+
+ % Invalid replacement doesn't keep the key (even though it would be the same value)
+ MatchSpec2 = [{{'$1', '$2'},
+ [{'=:=', {'band', '$1', 2#11}, 2#11}],
+ [{{{'+', '$1', 0}, '$2'}}]},
+ {{'$1', '$2'},
+ [{'=/=', {'band', '$1', 2#11}, 2#11}],
+ [{{{'-', '$1', 0}, '$2'}}]}],
+ {'EXIT',{badarg,_}} = (catch ets:select_replace(Table, MatchSpec2)),
+
+ % Invalid replacement changes key to float equivalent
+ MatchSpec3 = [{{'$1', '$2'},
+ [{'=:=', {'band', '$1', 2#11}, 2#11},
+ {'=/=', {'hd', '$2'}, $x}],
+ [{{{'*', '$1', 1.0}, '$2'}}]}],
+ {'EXIT',{badarg,_}} = (catch ets:select_replace(Table, MatchSpec3)),
+
+ % Replacements are differently-sized tuples
+ MatchSpec4_A = [{{'$1','$2'},
+ [{'<', {'rem', '$1', 5}, 2}],
+ [{{'$1', [$x | '$2'], stuff}}]}],
+ MatchSpec4_B = [{{'$1','$2','_'},
+ [],
+ [{{'$1','$2'}}]}],
+ 4000 = ets:select_replace(Table, MatchSpec4_A),
+ 4000 = ets:select_replace(Table, MatchSpec4_B),
+
+ % Replacement is the same tuple
+ MatchSpec5 = [{{'$1', '$2'},
+ [{'>', {'rem', '$1', 5}, 3}],
+ ['$_']}],
+ 2000 = ets:select_replace(Table, MatchSpec5),
+
+ % Replacement reconstructs an equal tuple
+ MatchSpec6 = [{{'$1', '$2'},
+ [{'>', {'rem', '$1', 5}, 3}],
+ [{{'$1', '$2'}}]}],
+ 2000 = ets:select_replace(Table, MatchSpec6),
+
+ % Replacement uses {element,KeyPos,T} for key
+ 2000 = ets:select_replace(Table,
+ [{{'$1', '$2'},
+ [{'>', {'rem', '$1', 5}, 3}],
+ [{{{element, 1, '$_'}, '$2'}}]}]),
+
+ % Replacement uses wrong {element,KeyPos,T} for key
+ {'EXIT',{badarg,_}} = (catch ets:select_replace(Table,
+ [{{'$1', '$2'},
+ [],
+ [{{{element, 2, '$_'}, '$2'}}]}])),
+
+ check(Table,
+ fun ({N, [$x, C | _]}) when ((N rem 5) < 2) -> (C >= $0) andalso (C =< $9);
+ ({N, [C | _]}) when is_float(N) -> (C >= $0) andalso (C =< $9);
+ ({N, [C | _]}) when ((N rem 5) > 3) -> (C >= $0) andalso (C =< $9);
+ ({_, [C | _]}) -> (C >= $0) andalso (C =< $9)
+ end,
+ 10000),
+
+ % Replace unbound range (>)
+ MatchSpec7 = [{{'$1', '$2'},
+ [{'>', '$1', 7000}],
+ [{{'$1', {{gt_range, '$2'}}}}]}],
+ 3000 = ets:select_replace(Table, MatchSpec7),
+
+ % Replace unbound range (<)
+ MatchSpec8 = [{{'$1', '$2'},
+ [{'<', '$1', 3000}],
+ [{{'$1', {{le_range, '$2'}}}}]}],
+ case TableType of
+ ordered_set -> 2999 = ets:select_replace(Table, MatchSpec8);
+ set -> 2999 = ets:select_replace(Table, MatchSpec8);
+ duplicate_bag -> 2998 = ets:select_replace(Table, MatchSpec8)
+ end,
+
+ % Replace bound range
+ MatchSpec9 = [{{'$1', '$2'},
+ [{'>=', '$1', 3001},
+ {'<', '$1', 7000}],
+ [{{'$1', {{range, '$2'}}}}]}],
+ case TableType of
+ ordered_set -> 3999 = ets:select_replace(Table, MatchSpec9);
+ set -> 3999 = ets:select_replace(Table, MatchSpec9);
+ duplicate_bag -> 3998 = ets:select_replace(Table, MatchSpec9)
+ end,
+
+ % Replace particular keys
+ MatchSpec10 = [{{'$1', '$2'},
+ [{'==', '$1', 3000}],
+ [{{'$1', {{specific1, '$2'}}}}]},
+ {{'$1', '$2'},
+ [{'==', '$1', 7000}],
+ [{{'$1', {{specific2, '$2'}}}}]}],
+ case TableType of
+ ordered_set -> 2 = ets:select_replace(Table, MatchSpec10);
+ set -> 2 = ets:select_replace(Table, MatchSpec10);
+ duplicate_bag -> 4 = ets:select_replace(Table, MatchSpec10)
+ end,
+
+ check(Table,
+ fun ({N, {gt_range, _}}) -> N > 7000;
+ ({N, {le_range, _}}) -> N < 3000;
+ ({N, {range, _}}) -> (N >= 3001) andalso (N < 7000);
+ ({N, {specific1, _}}) -> N == 3000;
+ ({N, {specific2, _}}) -> N == 7000
+ end,
+ 10000),
+
+ 10000 = ets:select_delete(Table, [{'_',[],[true]}]),
+ check(Table, fun (_) -> false end, 0)
+ end,
+
+ lists:foreach(
+ fun(Table) ->
+ TestFun(Table, ets:info(Table, type)),
+ ets:delete(Table)
+ end,
+ Tables),
+
+ %% Test key-safe match-specs are accepted
+ BigNum = (123 bsl 123),
+ RefcBin = list_to_binary(lists:seq(1,?heap_binary_size+1)),
+ Terms = [a, "hej", 123, 1.23, BigNum , <<"123">>, RefcBin, TestFun, self()],
+ EqPairs = fun(X,Y) ->
+ [{ '$1', '$1'},
+ { {X, Y}, {{X, Y}}},
+ { {'$1', Y}, {{'$1', Y}}},
+ { {{X, Y}}, {{{{X, Y}}}}},
+ { {X}, {{X}}},
+ { X, {const, X}},
+ { {X,Y}, {const, {X,Y}}},
+ { {X}, {const, {X}}},
+ { {X, Y}, {{X, {const, Y}}}},
+ { {X, {Y,'$1'}}, {{{const, X}, {{Y,'$1'}}}}},
+ { [X, Y | '$1'], [X, Y | '$1']},
+ { [{X, '$1'}, Y], [{{X, '$1'}}, Y]},
+ { [{X, Y} | '$1'], [{const, {X, Y}} | '$1']},
+ { [$p,$r,$e,$f,$i,$x | '$1'], [$p,$r,$e,$f,$i,$x | '$1']},
+ { {[{X,Y}]}, {{[{{X,Y}}]}}},
+ { {[{X,Y}]}, {{{const, [{X,Y}]}}}},
+ { {[{X,Y}]}, {{[{const,{X,Y}}]}}}
+ ]
+ end,
+
+ T2 = ets:new(x, []),
+ [lists:foreach(fun({A, B}) ->
+ %% just check that matchspec is accepted
+ 0 = ets:select_replace(T2, [{{A, '$2', '$3'}, [], [{{B, '$3', '$2'}}]}])
+ end,
+ EqPairs(X,Y)) || X <- Terms, Y <- Terms],
+
+ %% Test key-unsafe matchspecs are rejected
+ NeqPairs = fun(X, Y) ->
+ [{'$1', '$2'},
+ {{X, Y}, {X, Y}},
+ {{{X, Y}}, {{{X, Y}}}},
+ {{X}, {{{X}}}},
+ {{const, X}, {const, X}},
+ {{const, {X,Y}}, {const, {X,Y}}},
+ {'$1', {const, '$1'}},
+ {{X}, {const, {{X}}}},
+ {{X, {Y,'$1'}}, {{{const, X}, {Y,'$1'}}}},
+ {[X, Y | '$1'], [X, Y]},
+ {[X, Y], [X, Y | '$1']},
+ {[{X, '$1'}, Y], [{X, '$1'}, Y]},
+ {[$p,$r,$e,$f,$i,$x | '$1'], [$p,$r,$e,$f,$I,$x | '$1']},
+ { {[{X,Y}]}, {{[{X,Y}]}}},
+ { {[{X,Y}]}, {{{const, [{{X,Y}}]}}}},
+ { {[{X,Y}]}, {{[{const,{{X,Y}}}]}}},
+ {'_', '_'},
+ {'$_', '$_'},
+ {'$$', '$$'},
+ {#{}, #{}},
+ {#{X => '$1'}, #{X => '$1'}}
+ ]
+ end,
+
+ [lists:foreach(fun({A, B}) ->
+ %% just check that matchspec is rejected
+ {'EXIT',{badarg,_}} = (catch ets:select_replace(T2, [{{A, '$2', '$3'}, [], [{{B, '$3', '$2'}}]}]))
+ end,
+ NeqPairs(X,Y)) || X <- Terms, Y <- Terms],
+
+
+ %% Wrap entire tuple with 'const'
+ [[begin
+ Old = {Key, 1, 2},
+ ets:insert(T2, Old),
+ 1 = ets:select_replace(T2, [{Old, [], [{const, New}]}]),
+ [New] = ets:lookup(T2, Key),
+ ets:delete(T2, Key)
+ end || New <- [{Key, 1, 2}, {Key, 3, 4}, {Key, 1}, {Key, 1, 2, 3}, {Key}]
+ ]
+ || Key <- [{1, tuple}, {nested, {tuple, {a,b}}} | Terms]],
+
+ %% 'const' wrap does not work with maps or variables in keys
+ [[begin
+ Old = {Key, 1, 2},
+ {'EXIT',{badarg,_}} = (catch ets:select_replace(T2, [{Old, [], [{const, New}]}]))
+ end || New <- [{Key, 1, 2}, {Key, 3, 4}, {Key, 1}, {Key, 1, 2, 3}, {Key}]
+ ]
+ || Key <- [#{a => 1}, {nested, #{a => 1}}, '$1']],
+
+
+ ets:delete(T2),
+
+ verify_etsmem(EtsMem).
+
%% Test that partly bound keys gives faster matches.
partly_bound(Config) when is_list(Config) ->
case os:type() of
@@ -1190,7 +1386,7 @@ partly_bound(Config) when is_list(Config) ->
end.
dont_make_worse() ->
- seventyfive_percent_success({?MODULE,dont_make_worse_sub,[]},0,0,10).
+ seventyfive_percent_success(fun dont_make_worse_sub/0, 0, 0, 10).
dont_make_worse_sub() ->
T = build_table([a,b],[a,b],15000),
@@ -1202,8 +1398,9 @@ dont_make_worse_sub() ->
ok.
make_better() ->
- fifty_percent_success({?MODULE,make_better_sub2,[]},0,0,10),
- fifty_percent_success({?MODULE,make_better_sub1,[]},0,0,10).
+ fifty_percent_success(fun make_better_sub2/0, 0, 0, 10),
+ fifty_percent_success(fun make_better_sub1/0, 0, 0, 10).
+
make_better_sub1() ->
T = build_table2([a,b],[a,b],15000),
T1 = time_match_object(T,{'_',1500,a,a}, [{{1500,a,a},1500,a,a}]),
@@ -1488,19 +1685,19 @@ do_random_test() ->
%% Ttest various variants of update_element.
update_element(Config) when is_list(Config) ->
EtsMem = etsmem(),
- repeat_for_opts(update_element_opts),
+ repeat_for_opts(fun update_element_opts/1),
verify_etsmem(EtsMem).
update_element_opts(Opts) ->
- TupleCases = [{{key,val}, 1 ,2},
- {{val,key}, 2, 1},
- {{key,val}, 1 ,[2]},
+ TupleCases = [{{key,val}, 1 ,2},
+ {{val,key}, 2, 1},
+ {{key,val}, 1 ,[2]},
{{key,val,val}, 1, [2,3]},
{{val,key,val,val}, 2, [3,4,1]},
{{val,val,key,val}, 3, [1,4,1,2]}, % update pos1 twice
{{val,val,val,key}, 4, [2,1,2,3]}],% update pos2 twice
- lists:foreach(fun({Tuple,KeyPos,UpdPos}) -> update_element_opts(Tuple,KeyPos,UpdPos,Opts) end,
+ lists:foreach(fun({Tuple,KeyPos,UpdPos}) -> update_element_opts(Tuple,KeyPos,UpdPos,Opts) end,
TupleCases),
update_element_neg(Opts).
@@ -1516,9 +1713,9 @@ update_element_opts(Tuple,KeyPos,UpdPos,Opts) ->
true = ets:delete(OrdSet),
ok.
-update_element(T,Tuple,KeyPos,UpdPos) ->
+update_element(T,Tuple,KeyPos,UpdPos) ->
KeyList = [17,"seventeen",<<"seventeen">>,{17},list_to_binary(lists:seq(1,100)),make_ref(), self()],
- lists:foreach(fun(Key) ->
+ lists:foreach(fun(Key) ->
TupleWithKey = setelement(KeyPos,Tuple,Key),
update_element_do(T,TupleWithKey,Key,UpdPos)
end,
@@ -1553,29 +1750,29 @@ update_element_do(Tab,Tuple,Key,UpdPos) ->
{Pos, element(ToIx+1,Values)} % single {pos,value} arg
end,
- UpdateF = fun(ToIx,Rand) ->
- PosValArg = PosValArgF(ToIx,[],UpdPos,Rand,PosValArgF),
- %%io:format("update_element(~p)~n",[PosValArg]),
- ArgHash = erlang:phash2({Tab,Key,PosValArg}),
- true = ets:update_element(Tab, Key, PosValArg),
- ArgHash = erlang:phash2({Tab,Key,PosValArg}),
- NewTuple = update_tuple(PosValArg,Tuple),
- [NewTuple] = ets:lookup(Tab,Key)
+ UpdateF = fun(ToIx,Rand) ->
+ PosValArg = PosValArgF(ToIx,[],UpdPos,Rand,PosValArgF),
+ %%io:format("update_element(~p)~n",[PosValArg]),
+ ArgHash = erlang:phash2({Tab,Key,PosValArg}),
+ true = ets:update_element(Tab, Key, PosValArg),
+ ArgHash = erlang:phash2({Tab,Key,PosValArg}),
+ NewTuple = update_tuple(PosValArg,Tuple),
+ [NewTuple] = ets:lookup(Tab,Key)
end,
- LoopF = fun(_FromIx, Incr, _Times, Checksum, _MeF) when Incr >= Length ->
+ LoopF = fun(_FromIx, Incr, _Times, Checksum, _MeF) when Incr >= Length ->
Checksum; % done
- (FromIx, Incr, 0, Checksum, MeF) ->
+ (FromIx, Incr, 0, Checksum, MeF) ->
MeF(FromIx, Incr+1, Length, Checksum, MeF);
- (FromIx, Incr, Times, Checksum, MeF) ->
+ (FromIx, Incr, Times, Checksum, MeF) ->
ToIx = (FromIx + Incr) rem Length,
UpdateF(ToIx,Checksum),
- if
+ if
Incr =:= 0 -> UpdateF(ToIx,Checksum); % extra update to same value
true -> true
- end,
+ end,
MeF(ToIx, Incr, Times-1, Checksum+ToIx+1, MeF)
end,
@@ -1619,7 +1816,7 @@ update_element_neg_do(T) ->
Object = {key, 0, "Hej"},
true = ets:insert(T,Object),
- UpdateF = fun(Arg3) ->
+ UpdateF = fun(Arg3) ->
ArgHash = erlang:phash2({T,key,Arg3}),
{'EXIT',{badarg,_}} = (catch ets:update_element(T,key,Arg3)),
ArgHash = erlang:phash2({T,key,Arg3}),
@@ -1650,7 +1847,7 @@ update_element_neg_do(T) ->
%% test various variants of update_counter.
update_counter(Config) when is_list(Config) ->
EtsMem = etsmem(),
- repeat_for_opts(update_counter_do),
+ repeat_for_opts(fun update_counter_do/1),
verify_etsmem(EtsMem).
update_counter_do(Opts) ->
@@ -1694,7 +1891,7 @@ update_counter_for(T) ->
true = ets:lookup(T, b) =:= [setelement(1, NewObj, b)],
ets:delete(T, b),
Myself(NewObj,Times-1,Arg3,Myself)
- end,
+ end,
LoopF = fun(Obj, Times, Arg3) ->
%%io:format("Loop start:\nObj = ~p\nArg3=~p\n",[Obj,Arg3]),
@@ -1803,7 +2000,7 @@ uc_mimic(Obj, [Pits|Tail], Acc) ->
uc_adder(Init, {_Pos, Add}) ->
Init + Add;
-uc_adder(Init, {_Pos, Add, Thres, Warp}) ->
+uc_adder(Init, {_Pos, Add, Thres, Warp}) ->
case Init + Add of
X when X > Thres, Add > 0 ->
Warp;
@@ -1835,7 +2032,7 @@ update_counter_neg_for(T) ->
Object = {key,0,false,1},
true = ets:insert(T,Object),
- UpdateF = fun(Arg3) ->
+ UpdateF = fun(Arg3) ->
ArgHash = erlang:phash2({T,key,Arg3}),
{'EXIT',{badarg,_}} = (catch ets:update_counter(T,key,Arg3)),
ArgHash = erlang:phash2({T,key,Arg3}),
@@ -1871,7 +2068,7 @@ evil_update_counter(Config) when is_list(Config) ->
ordsets:module_info(),
rand:module_info(),
- repeat_for_opts(evil_update_counter_do).
+ repeat_for_opts(fun evil_update_counter_do/1).
evil_update_counter_do(Opts) ->
EtsMem = etsmem(),
@@ -1905,7 +2102,7 @@ evil_counter(I,Opts) ->
end,
Start = Start0 + rand:uniform(100000),
ets:insert(T, {dracula,Start}),
- Iter = 40000,
+ Iter = 40000 div syrup_factor(),
End = Start + Iter,
End = evil_counter_1(Iter, T),
ets:delete(T).
@@ -1918,7 +2115,7 @@ evil_counter_1(Iter, T) ->
evil_counter_1(Iter-1, T).
update_counter_with_default(Config) when is_list(Config) ->
- repeat_for_opts(update_counter_with_default_do).
+ repeat_for_opts(fun update_counter_with_default_do/1).
update_counter_with_default_do(Opts) ->
T1 = ets_new(a, [set | Opts]),
@@ -1955,9 +2152,20 @@ update_counter_with_default_do(Opts) ->
ok.
+update_counter_table_growth(_Config) ->
+ repeat_for_opts(fun update_counter_table_growth_do/1).
+
+update_counter_table_growth_do(Opts) ->
+ Set = ets_new(b, [set | Opts]),
+ [ets:update_counter(Set, N, {2, 1}, {N, 1}) || N <- lists:seq(1,10000)],
+ OrderedSet = ets_new(b, [ordered_set | Opts]),
+ [ets:update_counter(OrderedSet, N, {2, 1}, {N, 1}) || N <- lists:seq(1,10000)],
+ ok.
+
%% Check that a first-next sequence always works on a fixed table.
fixtable_next(Config) when is_list(Config) ->
- repeat_for_opts(fixtable_next_do, [write_concurrency,all_types]).
+ repeat_for_opts(fun fixtable_next_do/1,
+ [write_concurrency,all_types]).
fixtable_next_do(Opts) ->
EtsMem = etsmem(),
@@ -1965,15 +2173,16 @@ fixtable_next_do(Opts) ->
verify_etsmem(EtsMem).
do_fixtable_next(Tab) ->
- F = fun(X,T,FF) -> case X of
- 0 -> true;
- _ ->
- ets:insert(T, {X,
- integer_to_list(X),
- X rem 10}),
- FF(X-1,T,FF)
- end
- end,
+ F = fun(X,T,FF) ->
+ case X of
+ 0 -> true;
+ _ ->
+ ets:insert(T, {X,
+ integer_to_list(X),
+ X rem 10}),
+ FF(X-1,T,FF)
+ end
+ end,
F(100,Tab,F),
ets:safe_fixtable(Tab,true),
First = ets:first(Tab),
@@ -1988,7 +2197,7 @@ do_fixtable_next(Tab) ->
%% Check inserts of deleted keys in fixed bags.
fixtable_insert(Config) when is_list(Config) ->
- Combos = [[Type,{write_concurrency,WC}] || Type<- [bag,duplicate_bag],
+ Combos = [[Type,{write_concurrency,WC}] || Type<- [bag,duplicate_bag],
WC <- [false,true]],
lists:foreach(fun(Opts) -> fixtable_insert_do(Opts) end,
Combos),
@@ -2096,7 +2305,7 @@ write_concurrency(Config) when is_list(Config) ->
%% The 'heir' option.
heir(Config) when is_list(Config) ->
- repeat_for_opts(heir_do).
+ repeat_for_opts(fun heir_do/1).
heir_do(Opts) ->
EtsMem = etsmem(),
@@ -2104,7 +2313,7 @@ heir_do(Opts) ->
%% Different types of heir data and link/monitor relations
TestFun = fun(Arg) -> {EtsMem,Arg} end,
- Combos = [{Data,Mode} || Data<-[foo_data, <<"binary">>,
+ Combos = [{Data,Mode} || Data<-[foo_data, <<"binary">>,
lists:seq(1,10), {17,TestFun,self()},
"The busy heir"],
Mode<-[none,link,monitor]],
@@ -2144,7 +2353,7 @@ heir_do(Opts) ->
Founder4 ! {go, Heir4},
{'DOWN', MrefH4, process, Heir4, normal} = receive_any(),
erts_debug:set_internal_state(next_pid, NextPidIx),
- DoppelGanger = spawn_monitor_with_pid(Heir4,
+ DoppelGanger = spawn_monitor_with_pid(Heir4,
fun()-> die_please = receive_any() end),
Founder4 ! die_please,
{'DOWN', MrefF4, process, Founder4, normal} = receive_any(),
@@ -2157,12 +2366,12 @@ heir_do(Opts) ->
failed ->
io:format("Failed to spawn process with pid ~p\n", [Heir4]),
true % try again
- end
+ end
end),
verify_etsmem(EtsMem).
-heir_founder(Master, HeirData, Opts) ->
+heir_founder(Master, HeirData, Opts) ->
{go,Heir} = receive_any(),
HeirTpl = case Heir of
none -> {heir,none};
@@ -2235,8 +2444,8 @@ heir_1(HeirData,Mode,Opts) ->
{'DOWN', Mref, process, Heir, normal} = receive_any().
%% Test ets:give_way/3.
-give_away(Config) when is_list(Config) ->
- repeat_for_opts(give_away_do).
+give_away(Config) when is_list(Config) ->
+ repeat_for_opts(fun give_away_do/1).
give_away_do(Opts) ->
T = ets_new(foo,[named_table, private | Opts]),
@@ -2317,7 +2526,7 @@ give_away_receiver(T, Giver) ->
%% Test ets:setopts/2.
setopts(Config) when is_list(Config) ->
- repeat_for_opts(setopts_do,[write_concurrency,all_types]).
+ repeat_for_opts(fun setopts_do/1, [write_concurrency,all_types]).
setopts_do(Opts) ->
Self = self(),
@@ -2374,7 +2583,7 @@ bad_table(Config) when is_list(Config) ->
ok.
bad_table_do(Opts, DummyFile) ->
- Parent = self(),
+ Parent = self(),
{Pid,Mref} = my_spawn_opt(fun()-> ets_new(priv,[private,named_table | Opts]),
Priv = ets_new(priv,[private | Opts]),
ets_new(prot,[protected,named_table | Opts]),
@@ -2429,7 +2638,7 @@ bad_table_do(Opts, DummyFile) ->
],
Info = {Opts, Priv, Prot},
lists:foreach(fun(Op) -> bad_table_op(Info, Op) end,
- OpList),
+ OpList),
Pid ! die_please,
{'DOWN', Mref, process, Pid, normal} = receive_any(),
ok.
@@ -2467,7 +2676,7 @@ bad_table_call(T,{F,Args,_,{return,Return}}) ->
%% Check rename of ets tables.
rename(Config) when is_list(Config) ->
- repeat_for_opts(rename_do, [write_concurrency, all_types]).
+ repeat_for_opts(fun rename_do/1, [write_concurrency, all_types]).
rename_do(Opts) ->
EtsMem = etsmem(),
@@ -2482,7 +2691,8 @@ rename_do(Opts) ->
%% Check rename of unnamed ets table.
rename_unnamed(Config) when is_list(Config) ->
- repeat_for_opts(rename_unnamed_do,[write_concurrency,all_types]).
+ repeat_for_opts(fun rename_unnamed_do/1,
+ [write_concurrency,all_types]).
rename_unnamed_do(Opts) ->
EtsMem = etsmem(),
@@ -2557,21 +2767,21 @@ evil_create_fixed_tab() ->
%% Tests that the return values and errors are equal for set's and
%% ordered_set's where applicable.
interface_equality(Config) when is_list(Config) ->
- repeat_for_opts(interface_equality_do).
+ repeat_for_opts(fun interface_equality_do/1).
interface_equality_do(Opts) ->
EtsMem = etsmem(),
Set = ets_new(set,[set | Opts]),
OrderedSet = ets_new(ordered_set,[ordered_set | Opts]),
F = fun(X,T,FF) -> case X of
- 0 -> true;
- _ ->
- ets:insert(T, {X,
- integer_to_list(X),
- X rem 10}),
- FF(X-1,T,FF)
- end
- end,
+ 0 -> true;
+ _ ->
+ ets:insert(T, {X,
+ integer_to_list(X),
+ X rem 10}),
+ FF(X-1,T,FF)
+ end
+ end,
F(100,Set,F),
F(100,OrderedSet,F),
equal_results(ets, insert, Set, OrderedSet, [{a,"a"}]),
@@ -2621,7 +2831,7 @@ maybe_sort(Any) ->
%% Test match, match_object and match_delete in ordered set's.
ordered_match(Config) when is_list(Config)->
- repeat_for_opts(ordered_match_do).
+ repeat_for_opts(fun ordered_match_do/1).
ordered_match_do(Opts) ->
EtsMem = etsmem(),
@@ -2640,20 +2850,20 @@ ordered_match_do(Opts) ->
F(3000,T1,F),
[[3,3],[3,3],[3,3]] = ets:match(T1, {'_','_','$1','$2',3}),
F2 = fun(X,Rem,Res,FF) -> case X of
- 0 -> [];
- _ ->
+ 0 -> [];
+ _ ->
case X rem Rem of
Res ->
FF(X-1,Rem,Res,FF) ++
[{X,
- integer_to_list(X),
+ integer_to_list(X),
X rem 10,
X rem 100,
X rem 1000}];
_ ->
FF(X-1,Rem,Res,FF)
end
- end
+ end
end,
OL1 = F2(3000,100,2,F2),
OL1 = ets:match_object(T1, {'_','_','_',2,'_'}),
@@ -2667,7 +2877,7 @@ ordered_match_do(Opts) ->
%% Test basic functionality in ordered_set's.
ordered(Config) when is_list(Config) ->
- repeat_for_opts(ordered_do).
+ repeat_for_opts(fun ordered_do/1).
ordered_do(Opts) ->
EtsMem = etsmem(),
@@ -2731,7 +2941,7 @@ pick_all_backwards(T) ->
%% Small test case for both set and bag type ets tables.
-setbag(Config) when is_list(Config) ->
+setbag(Config) when is_list(Config) ->
EtsMem = etsmem(),
Set = ets_new(set,[set]),
Bag = ets_new(bag,[bag]),
@@ -2793,12 +3003,13 @@ keypos2(Config) when is_list(Config) ->
%% Privacy check. Check that a named(public/private/protected) table
%% cannot be read by the wrong process(es).
privacy(Config) when is_list(Config) ->
- repeat_for_opts(privacy_do).
+ repeat_for_opts(fun privacy_do/1).
privacy_do(Opts) ->
EtsMem = etsmem(),
process_flag(trap_exit,true),
- Owner = my_spawn_link(?MODULE,privacy_owner,[self(),Opts]),
+ Parent = self(),
+ Owner = my_spawn_link(fun() -> privacy_owner(Parent, Opts) end),
receive
{'EXIT',Owner,Reason} ->
exit({privacy_test,Reason});
@@ -2808,7 +3019,7 @@ privacy_do(Opts) ->
privacy_check(pub,prot,priv),
- Owner ! {shift,1,{pub,prot,priv}},
+ Owner ! {shift,1,{pub,prot,priv}},
receive
{Pub1,Prot1,Priv1} ->
ok = privacy_check(Pub1,Prot1,Priv1),
@@ -2878,7 +3089,7 @@ rotate_tuple(Tuple, N) ->
%% Check lookup in an empty table and lookup of a non-existing key.
empty(Config) when is_list(Config) ->
- repeat_for_opts(empty_do).
+ repeat_for_opts(fun empty_do/1).
empty_do(Opts) ->
EtsMem = etsmem(),
@@ -2891,7 +3102,7 @@ empty_do(Opts) ->
%% Check proper return values for illegal insert operations.
badinsert(Config) when is_list(Config) ->
- repeat_for_opts(badinsert_do).
+ repeat_for_opts(fun badinsert_do/1).
badinsert_do(Opts) ->
EtsMem = etsmem(),
@@ -2915,7 +3126,7 @@ badinsert_do(Opts) ->
time_lookup(Config) when is_list(Config) ->
%% just for timing, really
EtsMem = etsmem(),
- Values = repeat_for_opts(time_lookup_do),
+ Values = repeat_for_opts(fun time_lookup_do/1),
verify_etsmem(EtsMem),
{comment,lists:flatten(io_lib:format(
"~p ets lookups/s",[Values]))}.
@@ -2947,9 +3158,10 @@ badlookup(Config) when is_list(Config) ->
verify_etsmem(EtsMem).
%% Test that lookup returns objects in order of insertion for bag and dbag.
-lookup_order(Config) when is_list(Config) ->
+lookup_order(Config) when is_list(Config) ->
EtsMem = etsmem(),
- repeat_for_opts(lookup_order_do, [write_concurrency,[bag,duplicate_bag]]),
+ repeat_for_opts(fun lookup_order_do/1,
+ [write_concurrency,[bag,duplicate_bag]]),
verify_etsmem(EtsMem),
ok.
@@ -2969,7 +3181,7 @@ lookup_order_2(Opts, Fixed) ->
case Fixed of
true -> ets:safe_fixtable(T,true);
false -> ok
- end,
+ end,
S10 = {T,[],key},
S20 = check_insert(S10,A),
S30 = check_insert(S20,B),
@@ -2981,7 +3193,7 @@ lookup_order_2(Opts, Fixed) ->
S80 = check_delete(S70,D2b),
S90 = check_insert(S80,D2a),
SA0 = check_delete(S90,D3a),
- SB0 = check_delete(SA0,D3b),
+ SB0 = check_delete(SA0,D3b),
check_insert_new(SB0,D3b),
true = ets:delete(T)
@@ -2994,7 +3206,7 @@ check_insert({T,List0,Key},Val) ->
ets:insert(T,{Key,Val}),
List1 = case (ets:info(T,type) =:= bag andalso
lists:member({Key,Val},List0)) of
- true -> List0;
+ true -> List0;
false -> [{Key,Val} | List0]
end,
check_check({T,List1,Key}).
@@ -3027,8 +3239,6 @@ check_check(S={T,List,Key}) ->
Items = length(List),
S.
-
-
fill_tab(Tab,Val) ->
ets:insert(Tab,{key,Val}),
ets:insert(Tab,{{a,144},Val}),
@@ -3042,7 +3252,7 @@ fill_tab(Tab,Val) ->
%% OTP-2386. Multiple return elements.
lookup_element_mult(Config) when is_list(Config) ->
- repeat_for_opts(lookup_element_mult_do).
+ repeat_for_opts(fun lookup_element_mult_do/1).
lookup_element_mult_do(Opts) ->
EtsMem = etsmem(),
@@ -3056,13 +3266,11 @@ lookup_element_mult_do(Opts) ->
verify_etsmem(EtsMem).
lem_data() ->
- [
- {service,'eddie2@boromir',{150,236,14,103},httpd88,self()},
+ [{service,'eddie2@boromir',{150,236,14,103},httpd88,self()},
{service,'eddie2@boromir',{150,236,14,103},httpd80,self()},
{service,'eddie3@boromir',{150,236,14,107},httpd88,self()},
{service,'eddie3@boromir',{150,236,14,107},httpd80,self()},
- {service,'eddie4@boromir',{150,236,14,108},httpd88,self()}
- ].
+ {service,'eddie4@boromir',{150,236,14,108},httpd88,self()}].
lem_crash(T) ->
L = ets:lookup_element(T, 'eddie2@boromir', 3),
@@ -3082,7 +3290,8 @@ lem_crash_3(T) ->
%% Check delete of an element inserted in a `filled' table.
delete_elem(Config) when is_list(Config) ->
- repeat_for_opts(delete_elem_do, [write_concurrency, all_types]).
+ repeat_for_opts(fun delete_elem_do/1,
+ [write_concurrency, all_types]).
delete_elem_do(Opts) ->
EtsMem = etsmem(),
@@ -3099,7 +3308,8 @@ delete_elem_do(Opts) ->
%% Check that ets:delete() works and releases the name of the
%% deleted table.
delete_tab(Config) when is_list(Config) ->
- repeat_for_opts(delete_tab_do,[write_concurrency,all_types]).
+ repeat_for_opts(fun delete_tab_do/1,
+ [write_concurrency,all_types]).
delete_tab_do(Opts) ->
Name = foo,
@@ -3113,6 +3323,7 @@ delete_tab_do(Opts) ->
%% Check that ets:delete/1 works and that other processes can run.
delete_large_tab(Config) when is_list(Config) ->
+ ct:timetrap({minutes,30}), %% valgrind needs a lot
Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 200000)],
EtsMem = etsmem(),
repeat_for_opts(fun(Opts) -> delete_large_tab_do(Opts,Data) end),
@@ -3135,7 +3346,7 @@ delete_large_tab_1(Name, Flags, Data, Fix) ->
lists:foreach(fun({K,_}) -> ets:delete(Tab, K) end, Data)
end,
- {priority, Prio} = process_info(self(), priority),
+ {priority, Prio} = process_info(self(), priority),
Deleter = self(),
[SchedTracer]
= start_loopers(1,
@@ -3182,7 +3393,7 @@ delete_large_tab_1(Name, Flags, Data, Fix) ->
%% Delete a large name table and try to create a new table with
%% the same name in another process.
-delete_large_named_table(Config) when is_list(Config) ->
+delete_large_named_table(Config) when is_list(Config) ->
Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 200000)],
EtsMem = etsmem(),
repeat_for_opts(fun(Opts) -> delete_large_named_table_do(Opts,Data) end),
@@ -3289,23 +3500,29 @@ evil_delete_owner(Name, Flags, Data, Fix) ->
exit_large_table_owner(Config) when is_list(Config) ->
%%Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)],
- FEData = fun(Do) -> repeat_while(fun(500000) -> {false,ok};
+ Laps = 500000 div syrup_factor(),
+ FEData = fun(Do) -> repeat_while(fun(I) when I =:= Laps -> {false,ok};
(I) -> Do({erlang:phash2(I, 16#ffffff),I}),
{true, I+1}
end, 1)
end,
EtsMem = etsmem(),
- repeat_for_opts({exit_large_table_owner_do,{FEData,Config}}),
+ repeat_for_opts(fun(Opts) ->
+ exit_large_table_owner_do(Opts,
+ FEData,
+ Config)
+ end),
verify_etsmem(EtsMem).
-exit_large_table_owner_do(Opts,{FEData,Config}) ->
+exit_large_table_owner_do(Opts, FEData, Config) ->
verify_rescheduling_exit(Config, FEData, [named_table | Opts], true, 1, 1),
verify_rescheduling_exit(Config, FEData, Opts, false, 1, 1).
exit_many_large_table_owner(Config) when is_list(Config) ->
ct:timetrap({minutes,30}), %% valgrind needs a lot
%%Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)],
- FEData = fun(Do) -> repeat_while(fun(500000) -> {false,ok};
+ Laps = 500000 div syrup_factor(),
+ FEData = fun(Do) -> repeat_while(fun(I) when I =:= Laps -> {false,ok};
(I) -> Do({erlang:phash2(I, 16#ffffff),I}),
{true, I+1}
end, 1)
@@ -3465,7 +3682,8 @@ baddelete(Config) when is_list(Config) ->
%% Check that match_delete works. Also tests tab2list function.
match_delete(Config) when is_list(Config) ->
EtsMem = etsmem(),
- repeat_for_opts(match_delete_do,[write_concurrency,all_types]),
+ repeat_for_opts(fun match_delete_do/1,
+ [write_concurrency,all_types]),
verify_etsmem(EtsMem).
match_delete_do(Opts) ->
@@ -3482,7 +3700,7 @@ match_delete_do(Opts) ->
%% OTP-3005: check match_delete with constant argument.
match_delete3(Config) when is_list(Config) ->
- repeat_for_opts(match_delete3_do).
+ repeat_for_opts(fun match_delete3_do/1).
match_delete3_do(Opts) ->
EtsMem = etsmem(),
@@ -3507,7 +3725,7 @@ match_delete3_do(Opts) ->
%% Test ets:first/1 & ets:next/2.
firstnext(Config) when is_list(Config) ->
- repeat_for_opts(firstnext_do).
+ repeat_for_opts(fun firstnext_do/1).
firstnext_do(Opts) ->
EtsMem = etsmem(),
@@ -3553,7 +3771,7 @@ dyn_lookup(T) -> dyn_lookup(T, ets:first(T)).
dyn_lookup(_T, '$end_of_table') -> [];
dyn_lookup(T, K) ->
- NextKey=ets:next(T,K),
+ NextKey = ets:next(T,K),
case ets:next(T,K) of
NextKey ->
dyn_lookup(T, NextKey);
@@ -3565,7 +3783,7 @@ dyn_lookup(T, K) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
slot(Config) when is_list(Config) ->
- repeat_for_opts(slot_do).
+ repeat_for_opts(fun slot_do/1).
slot_do(Opts) ->
EtsMem = etsmem(),
@@ -3590,7 +3808,7 @@ slot_loop(Tab,SlotNo,EltsSoFar) ->
match1(Config) when is_list(Config) ->
- repeat_for_opts(match1_do).
+ repeat_for_opts(fun match1_do/1).
match1_do(Opts) ->
EtsMem = etsmem(),
@@ -3626,7 +3844,7 @@ match1_do(Opts) ->
%% Test match with specified keypos bag table.
match2(Config) when is_list(Config) ->
- repeat_for_opts(match2_do).
+ repeat_for_opts(fun match2_do/1).
match2_do(Opts) ->
EtsMem = etsmem(),
@@ -3653,7 +3871,7 @@ match2_do(Opts) ->
%% Some ets:match_object tests.
match_object(Config) when is_list(Config) ->
- repeat_for_opts(match_object_do).
+ repeat_for_opts(fun match_object_do/1).
match_object_do(Opts) ->
EtsMem = etsmem(),
@@ -3753,7 +3971,7 @@ match_object_do(Opts) ->
%% Tests that db_match_object does not generate a `badarg' when
%% resuming a search with no previous matches.
match_object2(Config) when is_list(Config) ->
- repeat_for_opts(match_object2_do).
+ repeat_for_opts(fun match_object2_do/1).
match_object2_do(Opts) ->
EtsMem = etsmem(),
@@ -3789,7 +4007,7 @@ tab2list(Config) when is_list(Config) ->
%% Simple general small test. If this fails, ets is in really bad
%% shape.
misc1(Config) when is_list(Config) ->
- repeat_for_opts(misc1_do).
+ repeat_for_opts(fun misc1_do/1).
misc1_do(Opts) ->
EtsMem = etsmem(),
@@ -3807,7 +4025,7 @@ misc1_do(Opts) ->
%% Check the safe_fixtable function.
safe_fixtable(Config) when is_list(Config) ->
- repeat_for_opts(safe_fixtable_do).
+ repeat_for_opts(fun safe_fixtable_do/1).
safe_fixtable_do(Opts) ->
EtsMem = etsmem(),
@@ -3865,7 +4083,7 @@ safe_fixtable_do(Opts) ->
%% Tests ets:info result for required tuples.
info(Config) when is_list(Config) ->
- repeat_for_opts(info_do).
+ repeat_for_opts(fun info_do/1).
info_do(Opts) ->
EtsMem = etsmem(),
@@ -3897,7 +4115,7 @@ info_do(Opts) ->
%% Test various duplicate_bags stuff.
dups(Config) when is_list(Config) ->
- repeat_for_opts(dups_do).
+ repeat_for_opts(fun dups_do/1).
dups_do(Opts) ->
EtsMem = etsmem(),
@@ -3963,7 +4181,9 @@ tab2file_do(FName, Opts) ->
%% Check the ets:tab2file function on a filled set/bag type ets table.
tab2file2(Config) when is_list(Config) ->
- repeat_for_opts({tab2file2_do,Config}, [[set,bag],compressed]).
+ repeat_for_opts(fun(Opts) ->
+ tab2file2_do(Opts, Config)
+ end, [[set,bag],compressed]).
tab2file2_do(Opts, Config) ->
EtsMem = etsmem(),
@@ -4072,9 +4292,9 @@ tabfile_ext2_do(Opts,Config) ->
Name = make_ref(),
[ets:insert(T,{X,integer_to_list(X)}) || X <- L],
ok = ets:tab2file(T,FName,[{extended_info,[md5sum]}]),
- true = lists:sort(ets:tab2list(T)) =:=
+ true = lists:sort(ets:tab2list(T)) =:=
lists:sort(ets:tab2list(element(2,ets:file2tab(FName)))),
- true = lists:sort(ets:tab2list(T)) =:=
+ true = lists:sort(ets:tab2list(T)) =:=
lists:sort(ets:tab2list(
element(2,ets:file2tab(FName,[{verify,true}])))),
{ok, Name} = disk_log:open([{name,Name},{file,FName}]),
@@ -4089,9 +4309,9 @@ tabfile_ext2_do(Opts,Config) ->
ets:tab2list(
element(2,ets:file2tab(FName2)))),
{error,checksum_error} = ets:file2tab(FName2,[{verify,true}]),
- {value,{extended_info,[md5sum]}} =
+ {value,{extended_info,[md5sum]}} =
lists:keysearch(extended_info,1,element(2,ets:tabfile_info(FName2))),
- {value,{extended_info,[md5sum]}} =
+ {value,{extended_info,[md5sum]}} =
lists:keysearch(extended_info,1,element(2,ets:tabfile_info(FName))),
file:delete(FName),
file:delete(FName2),
@@ -4136,15 +4356,14 @@ tabfile_ext4(Config) when is_list(Config) ->
Name2 = make_ref(),
[ets:insert(TL,{X,integer_to_list(X)}) || X <- LL],
ok = ets:tab2file(TL,FName,[{extended_info,[md5sum]}]),
- {ok, Name2} = disk_log:open([{name, Name2}, {file, FName},
+ {ok, Name2} = disk_log:open([{name, Name2}, {file, FName},
{mode, read_only}]),
{C,[_|_]} = disk_log:chunk(Name2,start),
{_,[_|_]} = disk_log:chunk(Name2,C),
disk_log:close(Name2),
- true = lists:sort(ets:tab2list(TL)) =:=
+ true = lists:sort(ets:tab2list(TL)) =:=
lists:sort(ets:tab2list(element(2,ets:file2tab(FName)))),
- Res = [
- begin
+ Res = [begin
{ok,FD} = file:open(FName,[binary,read,write]),
{ok, Bin} = file:pread(FD,0,1000),
<<B1:N/binary,Ch:8,B2/binary>> = Bin,
@@ -4154,7 +4373,7 @@ tabfile_ext4(Config) when is_list(Config) ->
ok = file:close(FD),
X = case ets:file2tab(FName) of
{ok,TL2} ->
- true = lists:sort(ets:tab2list(TL)) =/=
+ true = lists:sort(ets:tab2list(TL)) =/=
lists:sort(ets:tab2list(TL2));
_ ->
totally_broken
@@ -4162,7 +4381,7 @@ tabfile_ext4(Config) when is_list(Config) ->
{error,Y} = ets:file2tab(FName,[{verify,true}]),
ets:tab2file(TL,FName,[{extended_info,[md5sum]}]),
{X,Y}
- end || N <- lists:seq(500,600) ],
+ end || N <- lists:seq(500,600)],
io:format("~p~n",[Res]),
file:delete(FName),
ok.
@@ -4228,7 +4447,7 @@ make_sub_binary(List, Num) when is_list(List) ->
%% Perform multiple lookups for every key in a large table.
heavy_lookup(Config) when is_list(Config) ->
- repeat_for_opts(heavy_lookup_do).
+ repeat_for_opts(fun heavy_lookup_do/1).
heavy_lookup_do(Opts) ->
EtsMem = etsmem(),
@@ -4251,14 +4470,15 @@ do_lookup(Tab, N) ->
%% Perform multiple lookups for every element in a large table.
heavy_lookup_element(Config) when is_list(Config) ->
- repeat_for_opts(heavy_lookup_element_do).
+ repeat_for_opts(fun heavy_lookup_element_do/1).
heavy_lookup_element_do(Opts) ->
EtsMem = etsmem(),
Tab = ets_new(foobar_table, [set, protected, {keypos, 2} | Opts]),
ok = fill_tab2(Tab, 0, 7000),
%% lookup ALL elements 50 times
- _ = [do_lookup_element(Tab, 6999, 1) || _ <- lists:seq(1, 50)],
+ Laps = 50 div syrup_factor(),
+ _ = [do_lookup_element(Tab, 6999, 1) || _ <- lists:seq(1, Laps)],
true = ets:delete(Tab),
verify_etsmem(EtsMem).
@@ -4278,10 +4498,11 @@ do_lookup_element(Tab, N, M) ->
heavy_concurrent(Config) when is_list(Config) ->
ct:timetrap({minutes,30}), %% valgrind needs a lot of time
- repeat_for_opts(do_heavy_concurrent).
+ repeat_for_opts(fun do_heavy_concurrent/1).
do_heavy_concurrent(Opts) ->
Size = 10000,
+ Laps = 10000 div syrup_factor(),
EtsMem = etsmem(),
Tab = ets_new(blupp, [set, public, {keypos, 2} | Opts]),
ok = fill_tab2(Tab, 0, Size),
@@ -4289,7 +4510,7 @@ do_heavy_concurrent(Opts) ->
fun (N) ->
my_spawn_link(
fun () ->
- do_heavy_concurrent_proc(Tab, Size, N)
+ do_heavy_concurrent_proc(Tab, Laps, N)
end)
end,
lists:seq(1, 500)),
@@ -4362,7 +4583,7 @@ foldr_ordered(Config) when is_list(Config) ->
%% Test ets:member BIF.
member(Config) when is_list(Config) ->
- repeat_for_opts(member_do, [write_concurrency, all_types]).
+ repeat_for_opts(fun member_do/1, [write_concurrency, all_types]).
member_do(Opts) ->
EtsMem = etsmem(),
@@ -4391,16 +4612,14 @@ member_do(Opts) ->
build_table(L1,L2,Num) ->
- T = ets_new(xxx, [ordered_set]
- ),
+ T = ets_new(xxx, [ordered_set]),
lists:foreach(
fun(X1) ->
lists:foreach(
fun(X2) ->
F = fun(FF,N) ->
- ets:insert(T,{{X1,X2,N},
- X1, X2, N}),
- case N of
+ ets:insert(T,{{X1,X2,N}, X1, X2, N}),
+ case N of
0 ->
ok;
_ ->
@@ -4413,16 +4632,14 @@ build_table(L1,L2,Num) ->
T.
build_table2(L1,L2,Num) ->
- T = ets_new(xxx, [ordered_set]
- ),
+ T = ets_new(xxx, [ordered_set]),
lists:foreach(
fun(X1) ->
lists:foreach(
fun(X2) ->
F = fun(FF,N) ->
- ets:insert(T,{{N,X1,X2},
- N, X1, X2}),
- case N of
+ ets:insert(T,{{N,X1,X2}, N, X1, X2}),
+ case N of
0 ->
ok;
_ ->
@@ -4435,40 +4652,40 @@ build_table2(L1,L2,Num) ->
T.
time_match_object(Tab,Match, Res) ->
- T1 = erlang:monotonic_time(micro_seconds),
+ T1 = erlang:monotonic_time(microsecond),
Res = ets:match_object(Tab,Match),
- T2 = erlang:monotonic_time(micro_seconds),
+ T2 = erlang:monotonic_time(microsecond),
T2 - T1.
time_match(Tab,Match) ->
- T1 = erlang:monotonic_time(micro_seconds),
+ T1 = erlang:monotonic_time(microsecond),
ets:match(Tab,Match),
- T2 = erlang:monotonic_time(micro_seconds),
+ T2 = erlang:monotonic_time(microsecond),
T2 - T1.
seventyfive_percent_success(_,S,Fa,0) ->
true = (S > ((S + Fa) * 0.75));
-seventyfive_percent_success({M,F,A},S,Fa,N) ->
- case (catch apply(M,F,A)) of
- {'EXIT', _} ->
- seventyfive_percent_success({M,F,A},S,Fa+1,N-1);
- _ ->
- seventyfive_percent_success({M,F,A},S+1,Fa,N-1)
+seventyfive_percent_success(F, S, Fa, N) when is_function(F, 0) ->
+ try F() of
+ _ ->
+ seventyfive_percent_success(F, S+1, Fa, N-1)
+ catch error:_ ->
+ seventyfive_percent_success(F, S, Fa+1, N-1)
end.
fifty_percent_success(_,S,Fa,0) ->
true = (S > ((S + Fa) * 0.5));
-fifty_percent_success({M,F,A},S,Fa,N) ->
- case (catch apply(M,F,A)) of
- {'EXIT', _} ->
- fifty_percent_success({M,F,A},S,Fa+1,N-1);
- _ ->
- fifty_percent_success({M,F,A},S+1,Fa,N-1)
+fifty_percent_success(F, S, Fa, N) when is_function(F, 0) ->
+ try F() of
+ _ ->
+ fifty_percent_success(F, S+1, Fa, N-1)
+ catch
+ error:_ ->
+ fifty_percent_success(F, S, Fa+1, N-1)
end.
-
create_random_string(0) ->
[];
@@ -4713,7 +4930,7 @@ del_one_by_one_dbag_3(T,From,To) ->
N = (ets:info(T,size) + 1),
Obj2 = {From, integer_to_list(From)},
ets:delete_object(T,Obj2),
- N = (ets:info(T,size) + 2)
+ N = (ets:info(T,size) + 2)
end,
Next = if
From < To ->
@@ -4760,14 +4977,14 @@ gen_dets_filename(Config,N) ->
filename:join(proplists:get_value(priv_dir,Config),
"testdets_" ++ integer_to_list(N) ++ ".dets").
-otp_6842_select_1000(Config) when is_list(Config) ->
+otp_6842_select_1000(Config) when is_list(Config) ->
Tab = ets_new(xxx,[ordered_set]),
[ets:insert(Tab,{X,X}) || X <- lists:seq(1,10000)],
AllTrue = lists:duplicate(10,true),
AllTrue =
[ length(
element(1,
- ets:select(Tab,[{'_',[],['$_']}],X*1000))) =:=
+ ets:select(Tab,[{'_',[],['$_']}],X*1000))) =:=
X*1000 || X <- lists:seq(1,10) ],
Sequences = [[1000,1000,1000,1000,1000,1000,1000,1000,1000,1000],
[2000,2000,2000,2000,2000],
@@ -4793,7 +5010,13 @@ check_seq(A,B,C) ->
false.
otp_6338(Config) when is_list(Config) ->
- L = binary_to_term(<<131,108,0,0,0,2,104,2,108,0,0,0,2,103,100,0,19,112,112,98,49,95,98,115,49,50,64,98,108,97,100,101,95,48,95,53,0,0,33,50,0,0,0,4,1,98,0,0,23,226,106,100,0,4,101,120,105,116,104,2,108,0,0,0,2,104,2,100,0,3,115,98,109,100,0,19,112,112,98,50,95,98,115,49,50,64,98,108,97,100,101,95,48,95,56,98,0,0,18,231,106,100,0,4,114,101,99,118,106>>),
+ L = binary_to_term(<<131,108,0,0,0,2,104,2,108,0,0,0,2,103,100,0,19,112,112,
+ 98,49,95,98,115,49,50,64,98,108,97,100,101,95,48,95,53,
+ 0,0,33,50,0,0,0,4,1,98,0,0,23,226,106,100,0,4,101,120,
+ 105,116,104,2,108,0,0,0,2,104,2,100,0,3,115,98,109,100,
+ 0,19,112,112,98,50,95,98,115,49,50,64,98,108,97,100,
+ 101,95,48,95,56,98,0,0,18,231,106,100,0,4,114,101,99,
+ 118,106>>),
T = ets_new(xxx,[ordered_set]),
lists:foreach(fun(X) -> ets:insert(T,X) end,L),
[[4839,recv]] = ets:match(T,{[{sbm,ppb2_bs12@blade_0_8},'$1'],'$2'}),
@@ -4801,7 +5024,7 @@ otp_6338(Config) when is_list(Config) ->
%% Elements could come in the wrong order in a bag if a rehash occurred.
otp_5340(Config) when is_list(Config) ->
- repeat_for_opts(otp_5340_do).
+ repeat_for_opts(fun otp_5340_do/1).
otp_5340_do(Opts) ->
N = 3000,
@@ -4812,7 +5035,7 @@ otp_5340_do(Opts) ->
ets:delete(T).
w(_,0, _) -> ok;
-w(T,N, Id) ->
+w(T,N, Id) ->
ets:insert(T, {N, Id}),
w(T,N-1,Id).
@@ -4837,7 +5060,7 @@ verify2(_Err, _) ->
%% delete_object followed by delete on fixed bag failed to delete objects.
otp_7665(Config) when is_list(Config) ->
- repeat_for_opts(otp_7665_do).
+ repeat_for_opts(fun otp_7665_do/1).
otp_7665_do(Opts) ->
Tab = ets_new(otp_7665,[bag | Opts]),
@@ -4867,7 +5090,7 @@ otp_7665_act(Tab,Min,Max,DelNr) ->
%% Whitebox testing of meta name table hashing.
meta_wb(Config) when is_list(Config) ->
EtsMem = etsmem(),
- repeat_for_opts(meta_wb_do),
+ repeat_for_opts(fun meta_wb_do/1),
verify_etsmem(EtsMem).
@@ -4902,7 +5125,7 @@ meta_wb_new(Name, _, Tabs, Opts) ->
case (catch ets_new(Name,[named_table|Opts])) of
Name ->
false = lists:member(Name, Tabs),
- [Name | Tabs];
+ [Name | Tabs];
{'EXIT',{badarg,_}} ->
true = lists:member(Name, Tabs),
Tabs
@@ -5077,11 +5300,11 @@ meta_lookup_unnamed_read(Config) when is_list(Config) ->
Tab
end,
ExecF = fun(Tab) -> [{key,data}] = ets:lookup(Tab,key),
- Tab
+ Tab
end,
FiniF = fun(Tab) -> true = ets:delete(Tab)
end,
- run_workers(InitF,ExecF,FiniF,10000).
+ run_smp_workers(InitF,ExecF,FiniF,10000).
meta_lookup_unnamed_write(Config) when is_list(Config) ->
InitF = fun(_) -> Tab = ets_new(unnamed,[]),
@@ -5092,7 +5315,7 @@ meta_lookup_unnamed_write(Config) when is_list(Config) ->
end,
FiniF = fun({Tab,_}) -> true = ets:delete(Tab)
end,
- run_workers(InitF,ExecF,FiniF,10000).
+ run_smp_workers(InitF,ExecF,FiniF,10000).
meta_lookup_named_read(Config) when is_list(Config) ->
InitF = fun([ProcN|_]) -> Name = list_to_atom(integer_to_list(ProcN)),
@@ -5101,11 +5324,11 @@ meta_lookup_named_read(Config) when is_list(Config) ->
Tab
end,
ExecF = fun(Tab) -> [{key,data}] = ets:lookup(Tab,key),
- Tab
+ Tab
end,
FiniF = fun(Tab) -> true = ets:delete(Tab)
end,
- run_workers(InitF,ExecF,FiniF,10000).
+ run_smp_workers(InitF,ExecF,FiniF,10000).
meta_lookup_named_write(Config) when is_list(Config) ->
InitF = fun([ProcN|_]) -> Name = list_to_atom(integer_to_list(ProcN)),
@@ -5117,7 +5340,7 @@ meta_lookup_named_write(Config) when is_list(Config) ->
end,
FiniF = fun({Tab,_}) -> true = ets:delete(Tab)
end,
- run_workers(InitF,ExecF,FiniF,10000).
+ run_smp_workers(InitF,ExecF,FiniF,10000).
meta_newdel_unnamed(Config) when is_list(Config) ->
InitF = fun(_) -> ok end,
@@ -5125,7 +5348,7 @@ meta_newdel_unnamed(Config) when is_list(Config) ->
true = ets:delete(Tab)
end,
FiniF = fun(_) -> ok end,
- run_workers(InitF,ExecF,FiniF,10000).
+ run_smp_workers(InitF,ExecF,FiniF,10000).
meta_newdel_named(Config) when is_list(Config) ->
InitF = fun([ProcN|_]) -> list_to_atom(integer_to_list(ProcN))
@@ -5135,7 +5358,7 @@ meta_newdel_named(Config) when is_list(Config) ->
Name
end,
FiniF = fun(_) -> ok end,
- run_workers(InitF,ExecF,FiniF,10000).
+ run_smp_workers(InitF,ExecF,FiniF,10000).
%% Concurrent insert's on same table.
smp_insert(Config) when is_list(Config) ->
@@ -5144,7 +5367,7 @@ smp_insert(Config) when is_list(Config) ->
ExecF = fun(_) -> true = ets:insert(smp_insert,{rand:uniform(10000)})
end,
FiniF = fun(_) -> ok end,
- run_workers(InitF,ExecF,FiniF,100000),
+ run_smp_workers(InitF,ExecF,FiniF,100000),
verify_table_load(smp_insert),
ets:delete(smp_insert).
@@ -5160,14 +5383,14 @@ smp_fixed_delete_do() ->
ets:safe_fixtable(T,true),
Buckets = num_of_buckets(T),
InitF = fun([ProcN,NumOfProcs|_]) -> {ProcN,NumOfProcs} end,
- ExecF = fun({Key,_}) when Key > NumOfObjs ->
+ ExecF = fun({Key,_}) when Key > NumOfObjs ->
[end_of_work];
- ({Key,Increment}) ->
+ ({Key,Increment}) ->
true = ets:delete(T,Key),
{Key+Increment,Increment}
end,
FiniF = fun(_) -> ok end,
- run_workers_do(InitF,ExecF,FiniF,NumOfObjs),
+ run_sched_workers(InitF,ExecF,FiniF,NumOfObjs),
0 = ets:info(T,size),
true = ets:info(T,fixed),
Buckets = num_of_buckets(T),
@@ -5191,7 +5414,7 @@ smp_unfix_fix_do() ->
T = ets_new(foo,[public,{write_concurrency,true}]),
%%Mem = ets:info(T,memory),
NumOfObjs = 100000,
- Deleted = 50000,
+ Deleted = 50000,
filltabint(T,NumOfObjs),
ets:safe_fixtable(T,true),
Buckets = num_of_buckets(T),
@@ -5204,7 +5427,7 @@ smp_unfix_fix_do() ->
true = ets:info(T,fixed),
Deleted = get_kept_objects(T),
- {Child, Mref} =
+ {Child, Mref} =
my_spawn_opt(
fun()->
true = ets:info(T,fixed),
@@ -5263,22 +5486,19 @@ otp_8166_do(WC) ->
NumOfObjs = 3000, %% Need more than 1000 live objects for match_object to trap one time
Deleted = NumOfObjs div 2,
filltabint(T,NumOfObjs),
- {ReaderPid, ReaderMref} =
- my_spawn_opt(fun()-> otp_8166_reader(T,NumOfObjs) end,
- [link, monitor, {scheduler,2}]),
- {ZombieCrPid, ZombieCrMref} =
- my_spawn_opt(fun()-> otp_8166_zombie_creator(T,Deleted) end,
- [link, monitor, {scheduler,3}]),
+ {ReaderPid, ReaderMref} = my_spawn_opt(fun()-> otp_8166_reader(T,NumOfObjs) end,
+ [link, monitor, {scheduler,2}]),
+ {ZombieCrPid, ZombieCrMref} = my_spawn_opt(fun()-> otp_8166_zombie_creator(T,Deleted) end,
+ [link, monitor, {scheduler,3}]),
repeat(fun() -> ZombieCrPid ! {loop, self()},
zombies_created = receive_any(),
otp_8166_trapper(T, 10, ZombieCrPid)
- end,
- 100),
+ end, 100),
ReaderPid ! quit,
{'DOWN', ReaderMref, process, ReaderPid, normal} = receive_any(),
- ZombieCrPid ! quit,
+ ZombieCrPid ! quit,
{'DOWN', ZombieCrMref, process, ZombieCrPid, normal} = receive_any(),
false = ets:info(T,fixed),
0 = get_kept_objects(T),
@@ -5288,7 +5508,7 @@ otp_8166_do(WC) ->
%% Keep reading the table
otp_8166_reader(T, NumOfObjs) ->
- repeat_while(fun(0) ->
+ repeat_while(fun(0) ->
receive quit -> {false,done}
after 0 -> {true,NumOfObjs}
end;
@@ -5302,14 +5522,14 @@ otp_8166_reader(T, NumOfObjs) ->
otp_8166_trapper(T, Try, ZombieCrPid) ->
[] = ets:match_object(T,{'_',"Pink Unicorn"}),
case {ets:info(T,fixed),Try} of
- {true,1} ->
+ {true,1} ->
io:format("failed to provoke unsafe unfix, give up...\n",[]),
ZombieCrPid ! unfix;
- {true,_} ->
+ {true,_} ->
io:format("trapper too fast, trying again...\n",[]),
otp_8166_trapper(T, Try-1, ZombieCrPid);
{false,_} -> done
- end.
+ end.
%% Fixate table and create some pseudo-deleted objects (zombies)
@@ -5329,7 +5549,7 @@ otp_8166_zombie_creator(T,Deleted) ->
repeat_while(fun() -> case ets:info(T,safe_fixed_monotonic_time) of
{_,[_P1,_P2]} ->
false;
- _ ->
+ _ ->
receive unfix -> false
after 0 -> true
end
@@ -5350,12 +5570,12 @@ verify_table_load(T) ->
Stats = ets:info(T,stats),
{Buckets,AvgLen,StdDev,ExpSD,_MinLen,_MaxLen,_} = Stats,
ok = if
- AvgLen > 7 ->
+ AvgLen > 1.2 ->
io:format("Table overloaded: Stats=~p\n~p\n",
[Stats, ets:info(T)]),
false;
- Buckets>256, AvgLen < 6 ->
+ Buckets>256, AvgLen < 0.47 ->
io:format("Table underloaded: Stats=~p\n~p\n",
[Stats, ets:info(T)]),
false;
@@ -5386,7 +5606,7 @@ smp_select_delete(Config) when is_list(Config) ->
Mod = 17,
Zeros = erlang:make_tuple(Mod,0),
InitF = fun(_) -> Zeros end,
- ExecF = fun(Diffs0) ->
+ ExecF = fun(Diffs0) ->
case rand:uniform(20) of
1 ->
Mod = 17,
@@ -5408,10 +5628,10 @@ smp_select_delete(Config) when is_list(Config) ->
Diffs1;
false -> Diffs0
end
- end
+ end
end,
FiniF = fun(Result) -> Result end,
- Results = run_workers_do(InitF,ExecF,FiniF,20000),
+ Results = run_sched_workers(InitF,ExecF,FiniF,20000),
TotCnts = lists:foldl(fun(Diffs, Sum) -> add_lists(Sum,tuple_to_list(Diffs)) end,
lists:duplicate(Mod, 0), Results),
io:format("TotCnts = ~p\n",[TotCnts]),
@@ -5419,7 +5639,7 @@ smp_select_delete(Config) when is_list(Config) ->
0, TotCnts),
io:format("LeftInTab = ~p\n",[LeftInTab]),
LeftInTab = ets:info(T,size),
- lists:foldl(fun(Cnt,Eq) ->
+ lists:foldl(fun(Cnt,Eq) ->
WasCnt = ets:select_count(T,
[{{'_', '$1'},
[{'=:=', {'rem', '$1', Mod}, Eq}],
@@ -5427,18 +5647,58 @@ smp_select_delete(Config) when is_list(Config) ->
io:format("~p: ~p =?= ~p\n",[Eq,Cnt,WasCnt]),
Cnt = WasCnt,
Eq+1
- end,
+ end,
0, TotCnts),
- verify_table_load(T),
+ %% May fail as select_delete does not shrink table (enough)
+ %%verify_table_load(T),
LeftInTab = ets:select_delete(T, [{{'$1','$1'}, [], [true]}]),
0 = ets:info(T,size),
false = ets:info(T,fixed),
ets:delete(T).
+smp_select_replace(Config) when is_list(Config) ->
+ repeat_for_opts(fun smp_select_replace_do/1,
+ [[set,ordered_set,duplicate_bag]]).
+
+smp_select_replace_do(Opts) ->
+ T = ets_new(smp_select_replace,
+ [public, {write_concurrency, true} | Opts]),
+ ObjCount = 20,
+ InitF = fun (_) -> 0 end,
+ ExecF = fun (Cnt0) ->
+ CounterId = rand:uniform(ObjCount),
+ Match = [{{'$1', '$2'},
+ [{'=:=', '$1', CounterId}],
+ [{{'$1', {'+', '$2', 1}}}]}],
+ Cnt1 = case ets:select_replace(T, Match) of
+ 1 -> Cnt0+1;
+ 0 ->
+ ets:insert_new(T, {CounterId, 0}),
+ Cnt0
+ end,
+ receive stop ->
+ [end_of_work | Cnt1]
+ after 0 ->
+ Cnt1
+ end
+ end,
+ FiniF = fun (Cnt) -> Cnt end,
+ Pids = run_sched_workers(InitF, ExecF, FiniF, infinite),
+ receive after 3*1000 -> ok end,
+ [P ! stop || P <- Pids],
+ Results = wait_pids(Pids),
+ FinalCounts = ets:select(T, [{{'_', '$1'}, [], ['$1']}]),
+ Total = lists:sum(FinalCounts),
+ Total = lists:sum(Results),
+ ObjCount = ets:select_delete(T, [{{'_', '_'}, [], [true]}]),
+ 0 = ets:info(T, size),
+ true = ets:delete(T),
+ ok.
+
%% Test different types.
types(Config) when is_list(Config) ->
init_externals(),
- repeat_for_opts(types_do,[[set,ordered_set],compressed]).
+ repeat_for_opts(fun types_do/1, [[set,ordered_set],compressed]).
types_do(Opts) ->
EtsMem = etsmem(),
@@ -5465,8 +5725,8 @@ types_do(Opts) ->
%% OTP-9932: Memory overwrite when inserting large integers in compressed bag.
%% Will crash with segv on 64-bit opt if not fixed.
otp_9932(Config) when is_list(Config) ->
- T = ets:new(xxx, [bag, compressed]),
- Fun = fun(N) ->
+ T = ets:new(xxx, [bag, compressed]),
+ Fun = fun(N) ->
Key = {1316110174588445 bsl N,1316110174588583 bsl N},
S = {Key, Key},
true = ets:insert(T, S),
@@ -5482,9 +5742,9 @@ otp_9932(Config) when is_list(Config) ->
%% write_concurrency table.
otp_9423(Config) when is_list(Config) ->
InitF = fun(_) -> {0,0} end,
- ExecF = fun({S,F}) ->
- receive
- stop ->
+ ExecF = fun({S,F}) ->
+ receive
+ stop ->
io:format("~p got stop\n", [self()]),
[end_of_work | {"Succeded=",S,"Failed=",F}]
after 0 ->
@@ -5497,7 +5757,7 @@ otp_9423(Config) when is_list(Config) ->
end
end,
FiniF = fun(R) -> R end,
- case run_workers(InitF, ExecF, FiniF, infinite, 1) of
+ case run_smp_workers(InitF, ExecF, FiniF, infinite, 1) of
Pids when is_list(Pids) ->
%%[P ! start || P <- Pids],
repeat(fun() -> ets:new(otp_9423, [named_table, public, {write_concurrency,true}]),
@@ -5538,6 +5798,68 @@ ets_all_run() ->
false = lists:member(Table, ets:all()),
ets_all_run().
+create_tables(N) ->
+ create_tables(N, []).
+
+create_tables(0, Ts) ->
+ Ts;
+create_tables(N, Ts) ->
+ create_tables(N-1, [ets:new(tjo, [])|Ts]).
+
+massive_ets_all(Config) when is_list(Config) ->
+ Me = self(),
+ InitTables = lists:sort(ets:all()),
+ io:format("InitTables=~p~n", [InitTables]),
+ PMs0 = lists:map(fun (Sid) ->
+ my_spawn_opt(fun () ->
+ Ts = create_tables(250),
+ Me ! {self(), up, Ts},
+ receive {Me, die} -> ok end
+ end,
+ [link, monitor, {scheduler, Sid}])
+ end,
+ lists:seq(1, erlang:system_info(schedulers_online))),
+ AllRes = lists:sort(lists:foldl(fun ({P, _M}, Ts) ->
+ receive
+ {P, up, PTs} ->
+ PTs ++ Ts
+ end
+ end,
+ InitTables,
+ PMs0)),
+ AllRes = lists:sort(ets:all()),
+ PMs1 = lists:map(fun (_) ->
+ my_spawn_opt(fun () ->
+ AllRes = lists:sort(ets:all())
+ end,
+ [link, monitor])
+ end, lists:seq(1, 50)),
+ lists:foreach(fun ({P, M}) ->
+ receive
+ {'DOWN', M, process, P, _} ->
+ ok
+ end
+ end, PMs1),
+ PMs2 = lists:map(fun (_) ->
+ my_spawn_opt(fun () ->
+ _ = ets:all()
+ end,
+ [link, monitor])
+ end, lists:seq(1, 50)),
+ lists:foreach(fun ({P, _M}) ->
+ P ! {Me, die}
+ end, PMs0),
+ lists:foreach(fun ({P, M}) ->
+ receive
+ {'DOWN', M, process, P, _} ->
+ ok
+ end
+ end, PMs0 ++ PMs2),
+ EndTables = lists:sort(ets:all()),
+ io:format("EndTables=~p~n", [EndTables]),
+ InitTables = EndTables,
+ ok.
+
take(Config) when is_list(Config) ->
%% Simple test for set tables.
@@ -5580,30 +5902,34 @@ take(Config) when is_list(Config) ->
%% Utility functions:
%%
-add_lists(L1,L2) ->
+add_lists(L1,L2) ->
add_lists(L1,L2,[]).
add_lists([],[],Acc) ->
lists:reverse(Acc);
add_lists([E1|T1], [E2|T2], Acc) ->
- add_lists(T1, T2, [E1+E2 | Acc]).
+ add_lists(T1, T2, [E1+E2 | Acc]).
-run_workers(InitF,ExecF,FiniF,Laps) ->
- run_workers(InitF,ExecF,FiniF,Laps, 0).
-run_workers(InitF,ExecF,FiniF,Laps, Exclude) ->
+run_smp_workers(InitF,ExecF,FiniF,Laps) ->
+ run_smp_workers(InitF,ExecF,FiniF,Laps, 0).
+run_smp_workers(InitF,ExecF,FiniF,Laps, Exclude) ->
case erlang:system_info(smp_support) of
true ->
- run_workers_do(InitF,ExecF,FiniF,Laps, Exclude);
+ case erlang:system_info(schedulers_online) of
+ N when N > Exclude ->
+ run_workers_do(InitF,ExecF,FiniF,Laps, N - Exclude);
+ _ ->
+ {skipped, "Too few schedulers online"}
+ end;
false ->
{skipped,"No smp support"}
end.
-run_workers_do(InitF,ExecF,FiniF,Laps) ->
- run_workers_do(InitF,ExecF,FiniF,Laps, 0).
-run_workers_do(InitF,ExecF,FiniF,Laps, Exclude) ->
- NumOfProcs = case erlang:system_info(schedulers) of
- N when (N > Exclude) -> N - Exclude
- end,
- io:format("smp starting ~p workers\n",[NumOfProcs]),
+run_sched_workers(InitF,ExecF,FiniF,Laps) ->
+ run_workers_do(InitF,ExecF,FiniF,Laps,
+ erlang:system_info(schedulers)).
+
+run_workers_do(InitF,ExecF,FiniF,Laps, NumOfProcs) ->
+ io:format("starting ~p workers\n",[NumOfProcs]),
Seeds = [{ProcN,rand:uniform(9999)} || ProcN <- lists:seq(1,NumOfProcs)],
Parent = self(),
Pids = [my_spawn_link(fun()-> worker(Seed,InitF,ExecF,FiniF,Laps,Parent,NumOfProcs) end)
@@ -5631,9 +5957,9 @@ worker_loop(infinite, ExecF, State) ->
worker_loop(N, ExecF, State) ->
worker_loop(N-1,ExecF,ExecF(State)).
-wait_pids(Pids) ->
+wait_pids(Pids) ->
wait_pids(Pids,[]).
-wait_pids([],Acc) ->
+wait_pids([],Acc) ->
Acc;
wait_pids(Pids, Acc) ->
receive
@@ -5670,7 +5996,7 @@ etsmem() ->
wait_for_memory_deallocations(),
AllTabs = lists:map(fun(T) -> {T,ets:info(T,name),ets:info(T,size),
- ets:info(T,memory),ets:info(T,type)}
+ ets:info(T,memory),ets:info(T,type)}
end, ets:all()),
EtsAllocInfo = erlang:system_info({allocator,ets_alloc}),
@@ -5717,15 +6043,15 @@ verify_etsmem({MemInfo,AllTabs}) ->
%% Use 'erl +Mea max' to do more complete memory leak testing.
{comment,"Incomplete or no mem leak testing"};
_ ->
- ok
+ ok
end;
+
{MemInfo2, AllTabs2} ->
io:format("Expected: ~p", [MemInfo]),
io:format("Actual: ~p", [MemInfo2]),
io:format("Changed tables before: ~p\n",[AllTabs -- AllTabs2]),
io:format("Changed tables after: ~p\n", [AllTabs2 -- AllTabs]),
- ets_test_spawn_logger ! {failed_memcheck, get('__ETS_TEST_CASE__')},
- {comment, "Failed memory check"}
+ ct:fail("Failed memory check")
end.
@@ -5747,10 +6073,10 @@ stop_loopers(Loopers) ->
looper(Fun, State) ->
looper(Fun, Fun(State)).
-spawn_logger(Procs, FailedMemchecks) ->
+spawn_logger(Procs) ->
receive
{new_test_proc, Proc} ->
- spawn_logger([Proc|Procs], FailedMemchecks);
+ spawn_logger([Proc|Procs]);
{sync_test_procs, Kill, From} ->
lists:foreach(fun (Proc) when From == Proc ->
ok;
@@ -5774,14 +6100,7 @@ spawn_logger(Procs, FailedMemchecks) ->
end
end, Procs),
From ! test_procs_synced,
- spawn_logger([From], FailedMemchecks);
-
- {failed_memcheck, TestCase} ->
- spawn_logger(Procs, [TestCase|FailedMemchecks]);
-
- {Pid, get_failed_memchecks} ->
- Pid ! {get_failed_memchecks, FailedMemchecks},
- spawn_logger(Procs, FailedMemchecks)
+ spawn_logger([From])
end.
pid_status(Pid) ->
@@ -5797,7 +6116,7 @@ start_spawn_logger() ->
case whereis(ets_test_spawn_logger) of
Pid when is_pid(Pid) -> true;
_ -> register(ets_test_spawn_logger,
- spawn_opt(fun () -> spawn_logger([], []) end,
+ spawn_opt(fun () -> spawn_logger([]) end,
[{priority, max}]))
end.
@@ -5822,12 +6141,8 @@ log_test_proc(Proc) when is_pid(Proc) ->
Proc.
my_spawn(Fun) -> log_test_proc(spawn(Fun)).
-%%my_spawn(M,F,A) -> log_test_proc(spawn(M,F,A)).
-%%my_spawn(N,M,F,A) -> log_test_proc(spawn(N,M,F,A)).
my_spawn_link(Fun) -> log_test_proc(spawn_link(Fun)).
-my_spawn_link(M,F,A) -> log_test_proc(spawn_link(M,F,A)).
-%%my_spawn_link(N,M,F,A) -> log_test_proc(spawn_link(N,M,F,A)).
my_spawn_opt(Fun,Opts) ->
case spawn_opt(Fun,Opts) of
@@ -5882,7 +6197,7 @@ receive_any() ->
receive_any_spinning() ->
receive_any_spinning(1000000).
receive_any_spinning(Loops) ->
- receive_any_spinning(Loops,Loops,1).
+ receive_any_spinning(Loops,Loops,1).
receive_any_spinning(Loops,0,Tries) ->
receive M ->
io:format("Spinning process ~p got msg ~p after ~p tries\n", [self(),M,Tries]),
@@ -5924,7 +6239,6 @@ only_if_smp(Schedulers, Func) ->
end.
%% Copy-paste from emulator/test/binary_SUITE.erl
--define(heap_binary_size, 64).
test_terms(Test_Func, Mode) ->
garbage_collect(),
Pib0 = process_info(self(),binary),
@@ -6070,7 +6384,7 @@ make_port() ->
open_port({spawn, "efile"}, [eof]).
make_pid() ->
- spawn_link(?MODULE, sleeper, []).
+ spawn_link(fun sleeper/0).
sleeper() ->
receive after infinity -> ok end.
@@ -6206,11 +6520,7 @@ make_unaligned_sub_binary(List) ->
repeat_for_opts(F) ->
repeat_for_opts(F, [write_concurrency, read_concurrency, compressed]).
-repeat_for_opts(F, OptGenList) when is_atom(F) ->
- repeat_for_opts(fun(Opts) -> ?MODULE:F(Opts) end, OptGenList);
-repeat_for_opts({F,Args}, OptGenList) when is_atom(F) ->
- repeat_for_opts(fun(Opts) -> ?MODULE:F(Opts,Args) end, OptGenList);
-repeat_for_opts(F, OptGenList) ->
+repeat_for_opts(F, OptGenList) when is_function(F, 1) ->
repeat_for_opts(F, OptGenList, []).
repeat_for_opts(F, [], Acc) ->
@@ -6246,5 +6556,11 @@ do_tc(Do, Report) ->
T1 = erlang:monotonic_time(),
Do(),
T2 = erlang:monotonic_time(),
- Elapsed = erlang:convert_time_unit(T2 - T1, native, milli_seconds),
+ Elapsed = erlang:convert_time_unit(T2 - T1, native, millisecond),
Report(Elapsed).
+
+syrup_factor() ->
+ case erlang:system_info(build_type) of
+ valgrind -> 20;
+ _ -> 1
+ end.
diff --git a/lib/stdlib/test/ets_tough_SUITE.erl b/lib/stdlib/test/ets_tough_SUITE.erl
index 49aba7a529..ae9b2ec8e1 100644
--- a/lib/stdlib/test/ets_tough_SUITE.erl
+++ b/lib/stdlib/test/ets_tough_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,10 +19,15 @@
%%
-module(ets_tough_SUITE).
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2,ex1/1]).
--export([init/1,terminate/2,handle_call/3,handle_info/2]).
+ init_per_group/2,end_per_group/2,
+ ex1/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
--compile([export_all]).
+
+%% gen_server behavior.
+-behavior(gen_server).
+-export([init/1,terminate/2,handle_call/3,handle_cast/2,
+ handle_info/2,code_change/3]).
+
-include_lib("common_test/include/ct.hrl").
suite() ->
@@ -235,33 +240,6 @@ random_element(T) ->
I = rand:uniform(tuple_size(T)),
element(I,T).
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-show_table(N) ->
- FileName = ["etsdump.",integer_to_list(N)],
- case file:open(FileName,read) of
- {ok,Fd} ->
- show_entries(Fd);
- _ ->
- error
- end.
-
-show_entries(Fd) ->
- case phys_read_len(Fd) of
- {ok,Len} ->
- case phys_read_entry(Fd,Len) of
- {ok,ok} ->
- ok;
- {ok,{Key,Val}} ->
- io:format("~w\n",[{Key,Val}]),
- show_entries(Fd);
- _ ->
- error
- end;
- _ ->
- error
- end.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -378,20 +356,6 @@ dget_class(ServerPid,Class,Condition) ->
derase_class(ServerPid,Class) ->
gen_server:call(ServerPid,{handle_delete_class,Class}, infinity).
-%%% dmodify(ServerPid,Application) -> ok
-%%%
-%%% Applies a function on every instance in the database.
-%%% The user provided function must always return one of the
-%%% terms {ok,NewItem}, true, or false.
-%%% Aug 96, this is only used to reset all timestamp values
-%%% in the database.
-%%% The function is supplied as Application = {Mod, Fun, ExtraArgs},
-%%% where the instance will be prepended to ExtraArgs before each
-%%% call is made.
-
-dmodify(ServerPid,Application) ->
- gen_server:call(ServerPid,{handle_dmodify,Application}, infinity).
-
%%% ddump_first(ServerPid,DumpDir) -> {dump_more,Ticket} | already_dumping
%%%
%%% Starts dumping the database. This call redirects all database updates
@@ -643,9 +607,15 @@ handle_call(stop,_From,Admin) ->
?ets_delete(Admin), % Make sure table is gone before reply is sent.
{stop, normal, ok, []}.
+handle_cast(_Req, Admin) ->
+ {noreply, Admin}.
+
handle_info({'EXIT',_Pid,_Reason},Admin) ->
{stop,normal,Admin}.
+code_change(_OldVsn, StateData, _Extra) ->
+ {ok, StateData}.
+
handle_delete(Class, Key, Admin) ->
handle_call({handle_delete,Class,Key},from,Admin).
diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl
index 4f8936edbf..c94821bc75 100644
--- a/lib/stdlib/test/filelib_SUITE.erl
+++ b/lib/stdlib/test/filelib_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,7 +25,8 @@
init_per_testcase/2,end_per_testcase/2,
wildcard_one/1,wildcard_two/1,wildcard_errors/1,
fold_files/1,otp_5960/1,ensure_dir_eexist/1,ensure_dir_symlink/1,
- wildcard_symlink/1, is_file_symlink/1, file_props_symlink/1]).
+ wildcard_symlink/1, is_file_symlink/1, file_props_symlink/1,
+ find_source/1]).
-import(lists, [foreach/2]).
@@ -45,7 +46,8 @@ suite() ->
all() ->
[wildcard_one, wildcard_two, wildcard_errors,
fold_files, otp_5960, ensure_dir_eexist, ensure_dir_symlink,
- wildcard_symlink, is_file_symlink, file_props_symlink].
+ wildcard_symlink, is_file_symlink, file_props_symlink,
+ find_source].
groups() ->
[].
@@ -503,3 +505,57 @@ file_props_symlink(Config) ->
FileSize = filelib:file_size(Alias, erl_prim_loader),
FileSize = filelib:file_size(Alias, prim_file)
end.
+
+find_source(Config) when is_list(Config) ->
+ %% filename:find_{file,source}() does not work if the files are
+ %% cover-compiled. To make sure that the test does not fail
+ %% when the STDLIB is cover-compiled, search for modules in
+ %% the compiler application.
+
+ BeamFile = code:which(compile),
+ BeamName = filename:basename(BeamFile),
+ BeamDir = filename:dirname(BeamFile),
+ SrcName = filename:basename(BeamFile, ".beam") ++ ".erl",
+
+ {ok, BeamFile} = filelib:find_file(BeamName, BeamDir),
+ {ok, BeamFile} = filelib:find_file(BeamName, BeamDir, []),
+ {ok, BeamFile} = filelib:find_file(BeamName, BeamDir, [{"",""},{"ebin","src"}]),
+ {error, not_found} = filelib:find_file(BeamName, BeamDir, [{"ebin","src"}]),
+
+ {ok, SrcFile} = filelib:find_file(SrcName, BeamDir),
+ {ok, SrcFile} = filelib:find_file(SrcName, BeamDir, []),
+ {ok, SrcFile} = filelib:find_file(SrcName, BeamDir, [{"foo","bar"},{"ebin","src"}]),
+ {error, not_found} = filelib:find_file(SrcName, BeamDir, [{"",""}]),
+
+ {ok, SrcFile} = filelib:find_source(BeamFile),
+ {ok, SrcFile} = filelib:find_source(BeamName, BeamDir),
+ {ok, SrcFile} = filelib:find_source(BeamName, BeamDir,
+ [{".erl",".yrl",[{"",""}]},
+ {".beam",".erl",[{"ebin","src"}]}]),
+ {error, not_found} = filelib:find_source(BeamName, BeamDir,
+ [{".erl",".yrl",[{"",""}]}]),
+
+ {ok, ParserErl} = filelib:find_source(code:which(core_parse)),
+ {ok, ParserYrl} = filelib:find_source(ParserErl),
+ "lry." ++ _ = lists:reverse(ParserYrl),
+ {ok, ParserYrl} = filelib:find_source(ParserErl,
+ [{".beam",".erl",[{"ebin","src"}]},
+ {".erl",".yrl",[{"",""}]}]),
+
+ %% find_source automatically checks the local directory regardless of rules
+ {ok, ParserYrl} = filelib:find_source(ParserErl),
+ {ok, ParserYrl} = filelib:find_source(ParserErl,
+ [{".beam",".erl",[{"ebin","src"}]}]),
+
+ %% find_file does not check the local directory unless in the rules
+ ParserYrlName = filename:basename(ParserYrl),
+ ParserYrlDir = filename:dirname(ParserYrl),
+ {ok, ParserYrl} = filelib:find_file(ParserYrlName, ParserYrlDir,
+ [{"",""}]),
+ {error, not_found} = filelib:find_file(ParserYrlName, ParserYrlDir,
+ [{"ebin","src"}]),
+
+ %% local directory is in the default list for find_file
+ {ok, ParserYrl} = filelib:find_file(ParserYrlName, ParserYrlDir),
+ {ok, ParserYrl} = filelib:find_file(ParserYrlName, ParserYrlDir, []),
+ ok.
diff --git a/lib/stdlib/test/filename_SUITE.erl b/lib/stdlib/test/filename_SUITE.erl
index b7c4d3a6e5..fc77593bb8 100644
--- a/lib/stdlib/test/filename_SUITE.erl
+++ b/lib/stdlib/test/filename_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@
dirname_bin/1, extension_bin/1, join_bin/1, t_nativename_bin/1]).
-export([pathtype_bin/1,rootname_bin/1,split_bin/1]).
-export([t_basedir_api/1, t_basedir_xdg/1, t_basedir_windows/1]).
+-export([safe_relative_path/1]).
-include_lib("common_test/include/ct.hrl").
@@ -41,7 +42,8 @@ all() ->
find_src,
absname_bin, absname_bin_2,
{group,p},
- t_basedir_xdg, t_basedir_windows].
+ t_basedir_xdg, t_basedir_windows,
+ safe_relative_path].
groups() ->
[{p, [parallel],
@@ -421,8 +423,10 @@ t_nativename(Config) when is_list(Config) ->
find_src(Config) when is_list(Config) ->
{Source,_} = filename:find_src(file),
["file"|_] = lists:reverse(filename:split(Source)),
- {_,_} = filename:find_src(init, [{".","."}, {"ebin","src"}]),
-
+ {Source,_} = filename:find_src(file, [{"",""}, {"ebin","src"}]),
+ {Source,_} = filename:find_src(Source),
+ {Source,_} = filename:find_src(Source ++ ".erl"),
+
%% Try to find the source for a preloaded module.
{error,{preloaded,init}} = filename:find_src(init),
@@ -768,6 +772,71 @@ t_nativename_bin(Config) when is_list(Config) ->
filename:nativename(<<"/usr/tmp//arne/">>)
end.
+safe_relative_path(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Root = filename:join(PrivDir, ?FUNCTION_NAME),
+ ok = file:make_dir(Root),
+ ok = file:set_cwd(Root),
+
+ ok = file:make_dir("a"),
+ ok = file:set_cwd("a"),
+ ok = file:make_dir("b"),
+ ok = file:set_cwd("b"),
+ ok = file:make_dir("c"),
+
+ ok = file:set_cwd(Root),
+
+ "a" = test_srp("a"),
+ "a/b" = test_srp("a/b"),
+ "a/b" = test_srp("a/./b"),
+ "a/b" = test_srp("a/./b/."),
+
+ "" = test_srp("a/.."),
+ "" = test_srp("a/./.."),
+ "" = test_srp("a/../."),
+ "a" = test_srp("a/b/.."),
+ "a" = test_srp("a/../a"),
+ "a" = test_srp("a/../a/../a"),
+ "a/b/c" = test_srp("a/../a/b/c"),
+
+ unsafe = test_srp("a/../.."),
+ unsafe = test_srp("a/../../.."),
+ unsafe = test_srp("a/./../.."),
+ unsafe = test_srp("a/././../../.."),
+ unsafe = test_srp("a/b/././../../.."),
+
+ unsafe = test_srp(PrivDir), %Absolute path.
+
+ ok.
+
+test_srp(RelPath) ->
+ Res = do_test_srp(RelPath),
+ Res = case do_test_srp(list_to_binary(RelPath)) of
+ Bin when is_binary(Bin) ->
+ binary_to_list(Bin);
+ Other ->
+ Other
+ end.
+
+do_test_srp(RelPath) ->
+ {ok,Root} = file:get_cwd(),
+ ok = file:set_cwd(RelPath),
+ {ok,Cwd} = file:get_cwd(),
+ ok = file:set_cwd(Root),
+ case filename:safe_relative_path(RelPath) of
+ unsafe ->
+ true = length(Cwd) < length(Root),
+ unsafe;
+ "" ->
+ "";
+ SafeRelPath ->
+ ok = file:set_cwd(SafeRelPath),
+ {ok,Cwd} = file:get_cwd(),
+ true = length(Cwd) >= length(Root),
+ ok = file:set_cwd(Root),
+ SafeRelPath
+ end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% basedirs
t_basedir_api(Config) when is_list(Config) ->
diff --git a/lib/stdlib/test/gen_event_SUITE.erl b/lib/stdlib/test/gen_event_SUITE.erl
index 4415c2d09d..880b10117c 100644
--- a/lib/stdlib/test/gen_event_SUITE.erl
+++ b/lib/stdlib/test/gen_event_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,26 +21,35 @@
-include_lib("common_test/include/ct.hrl").
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, init_per_testcase/2,
+ end_per_testcase/2]).
-export([start/1, add_handler/1, add_sup_handler/1,
delete_handler/1, swap_handler/1, swap_sup_handler/1,
- notify/1, sync_notify/1, call/1, info/1, hibernate/1,
+ notify/1, sync_notify/1, call/1, info/1, hibernate/1, auto_hibernate/1,
call_format_status/1, call_format_status_anon/1,
- error_format_status/1, get_state/1, replace_state/1]).
+ error_format_status/1, get_state/1, replace_state/1,
+ start_opt/1,
+ undef_init/1, undef_handle_call/1, undef_handle_event/1,
+ undef_handle_info/1, undef_code_change/1, undef_terminate/1,
+ undef_in_terminate/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
-all() ->
- [start, {group, test_all}, hibernate,
+all() ->
+ [start, {group, test_all}, hibernate, auto_hibernate,
call_format_status, call_format_status_anon, error_format_status,
- get_state, replace_state].
+ get_state, replace_state,
+ start_opt, {group, undef_callbacks}, undef_in_terminate].
-groups() ->
+groups() ->
[{test_all, [],
[add_handler, add_sup_handler, delete_handler,
swap_handler, swap_sup_handler, notify, sync_notify,
- call, info]}].
+ call, info]},
+ {undef_callbacks, [],
+ [undef_init, undef_handle_call, undef_handle_event, undef_handle_info,
+ undef_code_change, undef_terminate]}].
init_per_suite(Config) ->
Config.
@@ -48,17 +57,48 @@ init_per_suite(Config) ->
end_per_suite(_Config) ->
ok.
+init_per_group(undef_callbacks, Config) ->
+ DataDir = ?config(data_dir, Config),
+ Event1 = filename:join(DataDir, "oc_event.erl"),
+ {ok, oc_event} = compile:file(Event1),
+ Config;
init_per_group(_GroupName, Config) ->
Config.
end_per_group(_GroupName, Config) ->
Config.
+init_per_testcase(Case, Config) when Case == undef_handle_call;
+ Case == undef_handle_info;
+ Case == undef_handle_event;
+ Case == undef_code_change;
+ Case == undef_terminate ->
+ {ok, Pid} = oc_event:start(),
+ [{event_pid, Pid}|Config];
+init_per_testcase(undef_init, Config) ->
+ {ok, Pid} = gen_event:start({local, oc_init_event}),
+ [{event_pid, Pid}|Config];
+init_per_testcase(_Case, Config) ->
+ Config.
+
+end_per_testcase(Case, Config) when Case == undef_init;
+ Case == undef_handle_call;
+ Case == undef_handle_info;
+ Case == undef_handle_event;
+ Case == undef_code_change;
+ Case == undef_terminate ->
+ Pid = ?config(event_pid, Config),
+ gen_event:stop(Pid);
+end_per_testcase(_Case, _Config) ->
+ ok.
%% --------------------------------------
%% Start an event manager.
%% --------------------------------------
+-define(LMGR, {local, my_dummy_name}).
+-define(GMGR, {global, my_dummy_name}).
+
start(Config) when is_list(Config) ->
OldFl = process_flag(trap_exit, true),
@@ -72,40 +112,36 @@ start(Config) when is_list(Config) ->
[] = gen_event:which_handlers(Pid1),
ok = gen_event:stop(Pid1),
- {ok, Pid2} = gen_event:start({local, my_dummy_name}),
+ {ok, Pid2} = gen_event:start(?LMGR),
[] = gen_event:which_handlers(my_dummy_name),
[] = gen_event:which_handlers(Pid2),
ok = gen_event:stop(my_dummy_name),
- {ok, Pid3} = gen_event:start_link({local, my_dummy_name}),
+ {ok, Pid3} = gen_event:start_link(?LMGR),
[] = gen_event:which_handlers(my_dummy_name),
[] = gen_event:which_handlers(Pid3),
ok = gen_event:stop(my_dummy_name),
- {ok, Pid4} = gen_event:start_link({global, my_dummy_name}),
- [] = gen_event:which_handlers({global, my_dummy_name}),
+ {ok, Pid4} = gen_event:start_link(?GMGR),
+ [] = gen_event:which_handlers(?GMGR),
[] = gen_event:which_handlers(Pid4),
- ok = gen_event:stop({global, my_dummy_name}),
+ ok = gen_event:stop(?GMGR),
{ok, Pid5} = gen_event:start_link({via, dummy_via, my_dummy_name}),
[] = gen_event:which_handlers({via, dummy_via, my_dummy_name}),
[] = gen_event:which_handlers(Pid5),
ok = gen_event:stop({via, dummy_via, my_dummy_name}),
- {ok, _} = gen_event:start_link({local, my_dummy_name}),
- {error, {already_started, _}} =
- gen_event:start_link({local, my_dummy_name}),
- {error, {already_started, _}} =
- gen_event:start({local, my_dummy_name}),
+ {ok, _} = gen_event:start_link(?LMGR),
+ {error, {already_started, _}} = gen_event:start_link(?LMGR),
+ {error, {already_started, _}} = gen_event:start(?LMGR),
ok = gen_event:stop(my_dummy_name),
- {ok, Pid6} = gen_event:start_link({global, my_dummy_name}),
- {error, {already_started, _}} =
- gen_event:start_link({global, my_dummy_name}),
- {error, {already_started, _}} =
- gen_event:start({global, my_dummy_name}),
+ {ok, Pid6} = gen_event:start_link(?GMGR),
+ {error, {already_started, _}} = gen_event:start_link(?GMGR),
+ {error, {already_started, _}} = gen_event:start(?GMGR),
- ok = gen_event:stop({global, my_dummy_name}, shutdown, 10000),
+ ok = gen_event:stop(?GMGR, shutdown, 10000),
receive
{'EXIT', Pid6, shutdown} -> ok
after 10000 ->
@@ -113,10 +149,8 @@ start(Config) when is_list(Config) ->
end,
{ok, Pid7} = gen_event:start_link({via, dummy_via, my_dummy_name}),
- {error, {already_started, _}} =
- gen_event:start_link({via, dummy_via, my_dummy_name}),
- {error, {already_started, _}} =
- gen_event:start({via, dummy_via, my_dummy_name}),
+ {error, {already_started, _}} = gen_event:start_link({via, dummy_via, my_dummy_name}),
+ {error, {already_started, _}} = gen_event:start({via, dummy_via, my_dummy_name}),
exit(Pid7, shutdown),
receive
@@ -128,6 +162,83 @@ start(Config) when is_list(Config) ->
process_flag(trap_exit, OldFl),
ok.
+start_opt(Config) when is_list(Config) ->
+ OldFl = process_flag(trap_exit, true),
+
+ dummy_via:reset(),
+
+ {ok, Pid0} = gen_event:start([]), %anonymous
+ [] = gen_event:which_handlers(Pid0),
+ ok = gen_event:stop(Pid0),
+
+ {ok, Pid1} = gen_event:start_link([]), %anonymous
+ [] = gen_event:which_handlers(Pid1),
+ ok = gen_event:stop(Pid1),
+
+ {ok, Pid2} = gen_event:start(?LMGR, []),
+ [] = gen_event:which_handlers(my_dummy_name),
+ [] = gen_event:which_handlers(Pid2),
+ ok = gen_event:stop(my_dummy_name),
+
+ {ok, Pid3} = gen_event:start_link(?LMGR, []),
+ [] = gen_event:which_handlers(my_dummy_name),
+ [] = gen_event:which_handlers(Pid3),
+ ok = gen_event:stop(my_dummy_name),
+
+ {ok, Pid4} = gen_event:start_link(?GMGR, []),
+ [] = gen_event:which_handlers(?GMGR),
+ [] = gen_event:which_handlers(Pid4),
+ ok = gen_event:stop(?GMGR),
+
+ {ok, Pid5} = gen_event:start_link({via, dummy_via, my_dummy_name}, []),
+ [] = gen_event:which_handlers({via, dummy_via, my_dummy_name}),
+ [] = gen_event:which_handlers(Pid5),
+ ok = gen_event:stop({via, dummy_via, my_dummy_name}),
+
+ {ok, _} = gen_event:start_link(?LMGR, []),
+ {error, {already_started, _}} = gen_event:start_link(?LMGR, []),
+ {error, {already_started, _}} = gen_event:start(?LMGR, []),
+ ok = gen_event:stop(my_dummy_name),
+
+ {ok, Pid7} = gen_event:start_link(?GMGR),
+ {error, {already_started, _}} = gen_event:start_link(?GMGR, []),
+ {error, {already_started, _}} = gen_event:start(?GMGR, []),
+
+ ok = gen_event:stop(?GMGR, shutdown, 10000),
+ receive
+ {'EXIT', Pid7, shutdown} -> ok
+ after 10000 ->
+ ct:fail(exit_gen_event)
+ end,
+
+ {ok, Pid8} = gen_event:start_link({via, dummy_via, my_dummy_name}),
+ {error, {already_started, _}} = gen_event:start_link({via, dummy_via, my_dummy_name}, []),
+ {error, {already_started, _}} = gen_event:start({via, dummy_via, my_dummy_name}, []),
+
+ exit(Pid8, shutdown),
+ receive
+ {'EXIT', Pid8, shutdown} -> ok
+ after 10000 ->
+ ct:fail(exit_gen_event)
+ end,
+
+ %% test spawn_opt
+ MinHeapSz = 10000,
+ {ok, Pid9} = gen_event:start_link(?LMGR, [{spawn_opt, [{min_heap_size, MinHeapSz}]}]),
+ {error, {already_started, _}} = gen_event:start_link(?LMGR, []),
+ {error, {already_started, _}} = gen_event:start(?LMGR, []),
+ {heap_size, HeapSz} = erlang:process_info(Pid9, heap_size),
+ true = HeapSz > MinHeapSz,
+ ok = gen_event:stop(my_dummy_name),
+
+ %% test debug opt
+ {ok, _} = gen_event:start_link(?LMGR, [{debug,[debug]}]),
+ {error, {already_started, _}} = gen_event:start_link(?LMGR, []),
+ {error, {already_started, _}} = gen_event:start(?LMGR, []),
+ ok = gen_event:stop(my_dummy_name),
+
+ process_flag(trap_exit, OldFl),
+ ok.
hibernate(Config) when is_list(Config) ->
{ok,Pid} = gen_event:start({local, my_dummy_handler}),
@@ -195,6 +306,48 @@ hibernate(Config) when is_list(Config) ->
ok.
+auto_hibernate(Config) when is_list(Config) ->
+ HibernateAfterTimeout = 100,
+ State = {auto_hibernate_state},
+ {ok,Pid} = gen_event:start({local, auto_hibernate_handler}, [{hibernate_after, HibernateAfterTimeout}]),
+ %% After init test
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_event:add_handler(auto_hibernate_handler, dummy_h, [State]),
+ %% Get state test
+ [{dummy_h,false,State}] = sys:get_state(Pid),
+ is_in_erlang_hibernate(Pid),
+ %% Call test
+ {ok, hejhopp} = gen_event:call(auto_hibernate_handler, dummy_h, hejsan),
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% Event test
+ ok = gen_event:notify(auto_hibernate_handler, {self(), handle_event}),
+ receive
+ handled_event ->
+ ok
+ after 1000 ->
+ ct:fail(event)
+ end,
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% Info test
+ Pid ! {self(), handle_info},
+ receive
+ handled_info ->
+ ok
+ after 1000 ->
+ ct:fail(info)
+ end,
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ ok = gen_event:stop(auto_hibernate_handler),
+ ok.
+
is_in_erlang_hibernate(Pid) ->
receive after 1 -> ok end,
is_in_erlang_hibernate_1(200, Pid).
@@ -979,3 +1132,92 @@ replace_state(Config) when is_list(Config) ->
ok = sys:resume(Pid),
[{dummy1_h,false,NState3}] = sys:get_state(Pid),
ok.
+
+%% No default provided for init, so it should fail
+undef_init(Config) ->
+ Pid = ?config(event_pid, Config),
+ {'EXIT', {undef, [{oc_init_event, init, [_], _}|_]}}
+ = gen_event:add_handler(Pid, oc_init_event, []),
+ ok.
+
+%% No default provided for init, so it should fail
+undef_handle_call(Config) when is_list(Config) ->
+ Pid = ?config(event_pid, Config),
+ {error, {'EXIT', {undef, [{oc_event, handle_call, _, _}|_]}}}
+ = gen_event:call(Pid, oc_event, call_msg),
+ [] = gen_event:which_handlers(Pid),
+ ok.
+
+%% No default provided for init, so it should fail
+undef_handle_event(Config) ->
+ Pid = ?config(event_pid, Config),
+ ok = gen_event:sync_notify(Pid, event_msg),
+ [] = gen_event:which_handlers(Pid),
+
+ gen_event:add_handler(oc_event, oc_event, []),
+ [oc_event] = gen_event:which_handlers(Pid),
+
+ ok = gen_event:notify(Pid, event_msg),
+ [] = gen_event:which_handlers(Pid),
+ ok.
+
+%% Defaulting to doing nothing with a log warning.
+undef_handle_info(Config) when is_list(Config) ->
+ error_logger_forwarder:register(),
+ Pid = ?config(event_pid, Config),
+ Pid ! hej,
+ wait_until_processed(Pid, hej, 10),
+ [oc_event] = gen_event:which_handlers(Pid),
+ receive
+ {warning_msg, _GroupLeader,
+ {Pid, "** Undefined handle_info in " ++ _, [oc_event, hej]}} ->
+ ok;
+ Other ->
+ io:format("Unexpected: ~p", [Other]),
+ ct:fail(failed)
+ end.
+
+wait_until_processed(_Pid, _Message, 0) ->
+ ct:fail(not_processed);
+wait_until_processed(Pid, Message, N) ->
+ {messages, Messages} = erlang:process_info(Pid, messages),
+ case lists:member(Message, Messages) of
+ true ->
+ timer:sleep(100),
+ wait_until_processed(Pid, Message, N-1);
+ false ->
+ ok
+ end.
+
+%% No default provided for init, so it should fail
+undef_code_change(Config) when is_list(Config) ->
+ Pid = ?config(event_pid, Config),
+ {error, {'EXIT', {undef, [{oc_event, code_change, [_, _, _], _}|_]}}} =
+ fake_upgrade(Pid, oc_event),
+ [oc_event] = gen_event:which_handlers(Pid),
+ ok.
+
+%% Defaulting to doing nothing. Test that it works when not defined.
+undef_terminate(Config) when is_list(Config) ->
+ Pid = ?config(event_pid, Config),
+ ok = gen_event:delete_handler(Pid, oc_event, []),
+ [] = gen_event:which_handlers(Pid),
+ ok.
+
+%% Test that the default implementation doesn't catch the wrong undef error
+undef_in_terminate(_Config) ->
+ {ok, Pid} = gen_event:start({local, dummy}),
+ State = {undef_in_terminate, {dummy_h, terminate}},
+ ok = gen_event:add_handler(Pid, dummy_h, {state, State}),
+ [dummy_h] = gen_event:which_handlers(Pid),
+ {'EXIT', {undef, [{dummy_h, terminate, [], []}|_]}}
+ = gen_event:delete_handler(Pid, dummy_h, []),
+ [] = gen_event:which_handlers(Pid),
+ ok.
+
+fake_upgrade(Pid, Mod) ->
+ sys:suspend(Pid),
+ sys:replace_state(Pid, fun(S) -> {new, S} end),
+ Ret = sys:change_code(Pid, Mod, old_vsn, []),
+ ok = sys:resume(Pid),
+ Ret.
diff --git a/lib/stdlib/test/gen_event_SUITE_data/oc_event.erl b/lib/stdlib/test/gen_event_SUITE_data/oc_event.erl
new file mode 100644
index 0000000000..eb664ef550
--- /dev/null
+++ b/lib/stdlib/test/gen_event_SUITE_data/oc_event.erl
@@ -0,0 +1,40 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(oc_event).
+
+-behaviour(gen_event).
+
+%% API
+-export([start/0]).
+
+%% gen_event callbacks
+-export([init/1]).
+
+-define(SERVER, ?MODULE).
+
+-record(state, {}).
+
+start() ->
+ {ok, Pid} = gen_event:start({local, ?SERVER}),
+ gen_event:add_handler(?SERVER, ?MODULE, []),
+ {ok, Pid}.
+
+init([]) ->
+ {ok, #state{}}.
diff --git a/lib/stdlib/test/gen_fsm_SUITE.erl b/lib/stdlib/test/gen_fsm_SUITE.erl
index d6bb002b5f..86cf58566b 100644
--- a/lib/stdlib/test/gen_fsm_SUITE.erl
+++ b/lib/stdlib/test/gen_fsm_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -39,7 +39,12 @@
call_format_status/1, error_format_status/1, terminate_crash_format/1,
get_state/1, replace_state/1]).
--export([hibernate/1,hiber_idle/3,hiber_wakeup/3,hiber_idle/2,hiber_wakeup/2]).
+-export([undef_handle_event/1, undef_handle_sync_event/1, undef_handle_info/1,
+ undef_init/1, undef_code_change/1, undef_terminate1/1, undef_terminate2/1]).
+
+-export([undef_in_handle_info/1, undef_in_terminate/1]).
+
+-export([hibernate/1,auto_hibernate/1,hiber_idle/3,hiber_wakeup/3,hiber_idle/2,hiber_wakeup/2]).
-export([enter_loop/1]).
@@ -48,7 +53,7 @@
%% The gen_fsm behaviour
-export([init/1, handle_event/3, handle_sync_event/4, terminate/3,
- handle_info/3, format_status/2]).
+ handle_info/3, format_status/2, code_change/4]).
-export([idle/2, idle/3,
timeout/2,
wfor_conf/2, wfor_conf/3,
@@ -63,7 +68,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[{group, start}, {group, abnormal}, shutdown,
- {group, sys}, hibernate, enter_loop].
+ {group, sys}, hibernate, auto_hibernate, enter_loop, {group, undef_callbacks},
+ undef_in_handle_info, undef_in_terminate].
groups() ->
[{start, [],
@@ -74,7 +80,10 @@ groups() ->
{abnormal, [], [abnormal1, abnormal2]},
{sys, [],
[sys1, call_format_status, error_format_status, terminate_crash_format,
- get_state, replace_state]}].
+ get_state, replace_state]},
+ {undef_callbacks, [],
+ [undef_handle_event, undef_handle_sync_event, undef_handle_info,
+ undef_init, undef_code_change, undef_terminate1, undef_terminate2]}].
init_per_suite(Config) ->
Config.
@@ -82,6 +91,11 @@ init_per_suite(Config) ->
end_per_suite(_Config) ->
ok.
+init_per_group(undef_callbacks, Config) ->
+ DataDir = ?config(data_dir, Config),
+ Server = filename:join(DataDir, "oc_fsm.erl"),
+ {ok, oc_fsm} = compile:file(Server),
+ Config;
init_per_group(_GroupName, Config) ->
Config.
@@ -686,6 +700,43 @@ hibernate(Config) when is_list(Config) ->
process_flag(trap_exit, OldFl),
ok.
+%% Auto hibernation
+auto_hibernate(Config) when is_list(Config) ->
+ OldFl = process_flag(trap_exit, true),
+ HibernateAfterTimeout = 100,
+ State = {auto_hibernate_state},
+ {ok, Pid} = gen_fsm:start_link({local, my_test_name_auto_hibernate}, ?MODULE, {state_data, State}, [{hibernate_after, HibernateAfterTimeout}]),
+ %% After init test
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% Get state test
+ {_, State} = sys:get_state(my_test_name_auto_hibernate),
+ is_in_erlang_hibernate(Pid),
+ %% Sync send event test
+ 'alive!' = gen_fsm:sync_send_event(Pid,'alive?'),
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% Send event test
+ ok = gen_fsm:send_all_state_event(Pid,{'alive?', self()}),
+ wfor(yes),
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% Info test
+ Pid ! {self(), handle_info},
+ wfor({Pid, handled_info}),
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ stop_it(Pid),
+ receive
+ {'EXIT',Pid,normal} -> ok
+ end,
+ process_flag(trap_exit, OldFl),
+ ok.
+
is_in_erlang_hibernate(Pid) ->
receive after 1 -> ok end,
is_in_erlang_hibernate_1(200, Pid).
@@ -868,6 +919,99 @@ enter_loop(Reg1, Reg2) ->
gen_fsm:enter_loop(?MODULE, [], state0, [])
end.
+%% Start should return an undef error if init isn't implemented
+undef_init(Config) when is_list(Config) ->
+ {error, {undef, [{oc_init_fsm, init, [[]], []}|_]}}
+ = gen_fsm:start(oc_init_fsm, [], []),
+ ok.
+
+%% Test that the server crashes correctly if the handle_event callback is
+%% not exported in the callback module
+undef_handle_event(Config) when is_list(Config) ->
+ {ok, FSM} = gen_fsm:start(oc_fsm, [], []),
+ MRef = monitor(process, FSM),
+ gen_fsm:send_all_state_event(FSM, state_name),
+ ok = verify_undef_down(MRef, FSM, oc_fsm, handle_event).
+
+%% Test that the server crashes correctly if the handle_sync_event callback is
+%% not exported in the callback module
+undef_handle_sync_event(Config) when is_list(Config) ->
+ {ok, FSM} = gen_fsm:start(oc_fsm, [], []),
+ try
+ gen_fsm:sync_send_all_state_event(FSM, state_name),
+ ct:fail(should_crash)
+ catch exit:{{undef, [{oc_fsm, handle_sync_event, _, _}|_]},_} ->
+ ok
+ end.
+
+%% The fsm should log but not crash if the handle_info callback is
+%% calling an undefined function
+undef_handle_info(Config) when is_list(Config) ->
+ error_logger_forwarder:register(),
+ {ok, FSM} = gen_fsm:start(oc_fsm, [], []),
+ MRef = monitor(process, FSM),
+ FSM ! hej,
+ receive
+ {'DOWN', MRef, process, FSM, _} ->
+ ct:fail(should_not_crash)
+ after 500 ->
+ ok
+ end,
+ receive
+ {warning_msg, _GroupLeader,
+ {FSM, "** Undefined handle_info in " ++ _, [oc_fsm, hej]}} ->
+ ok;
+ Other ->
+ io:format("Unexpected: ~p", [Other]),
+ ct:fail(failed)
+ end.
+
+%% The upgrade should fail if code_change is expected in the callback module
+%% but not exported, but the fsm should continue with the old code
+undef_code_change(Config) when is_list(Config) ->
+ {ok, FSM} = gen_fsm:start(oc_fsm, [], []),
+ {error, {'EXIT', {undef, [{oc_fsm, code_change, [_, _, _, _], _}|_]}}}
+ = fake_upgrade(FSM, oc_fsm),
+ ok.
+
+%% Test the default implementation of terminate with normal reason if the
+%% callback module does not export it
+undef_terminate1(Config) when is_list(Config) ->
+ {ok, FSM} = gen_fsm:start(oc_fsm, [], []),
+ MRef = monitor(process, FSM),
+ ok = gen_fsm:stop(FSM),
+ ok = verify_down_reason(MRef, FSM, normal).
+
+%% Test the default implementation of terminate with error reason if the
+%% callback module does not export it
+undef_terminate2(Config) when is_list(Config) ->
+ {ok, FSM} = gen_fsm:start(oc_fsm, [], []),
+ MRef = monitor(process, FSM),
+ ok = gen_fsm:stop(FSM, {error, test}, infinity),
+ ok = verify_down_reason(MRef, FSM, {error, test}).
+
+%% Test that the server crashes correctly if the handle_info callback is
+%% calling an undefined function
+undef_in_handle_info(Config) when is_list(Config) ->
+ {ok, FSM} = gen_fsm:start(?MODULE, [], []),
+ MRef = monitor(process, FSM),
+ FSM ! {call_undef_fun, {?MODULE, handle_info}},
+ verify_undef_down(MRef, FSM, ?MODULE, handle_info),
+ ok.
+
+%% Test that the server crashes correctly if the terminate callback is
+%% calling an undefined function
+undef_in_terminate(Config) when is_list(Config) ->
+ State = {undef_in_terminate, {?MODULE, terminate}},
+ {ok, FSM} = gen_fsm:start(?MODULE, {state_data, State}, []),
+ try
+ gen_fsm:stop(FSM),
+ ct:fail(failed)
+ catch
+ exit:{undef, [{?MODULE, terminate, _, _}|_]} ->
+ ok
+ end.
+
%%
%% Functionality check
%%
@@ -962,7 +1106,31 @@ do_sync_disconnect(FSM) ->
yes = gen_fsm:sync_send_event(FSM, disconnect),
check_state(FSM, idle).
+verify_down_reason(MRef, Pid, Reason) ->
+ receive
+ {'DOWN', MRef, process, Pid, Reason} ->
+ ok;
+ {'DOWN', MRef, process, Pid, Other}->
+ ct:fail({wrong_down_reason, Other})
+ after 5000 ->
+ ct:fail(should_shutdown)
+ end.
+
+verify_undef_down(MRef, Pid, Mod, Fun) ->
+ ok = receive
+ {'DOWN', MRef, process, Pid,
+ {undef, [{Mod, Fun, _, _}|_]}} ->
+ ok
+ after 5000 ->
+ ct:fail(should_crash)
+ end.
+fake_upgrade(Pid, Mod) ->
+ sys:suspend(Pid),
+ sys:replace_state(Pid, fun(State) -> {new, State} end),
+ Ret = sys:change_code(Pid, Mod, old_vsn, []),
+ ok = sys:resume(Pid),
+ Ret.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -992,6 +1160,9 @@ init(_) ->
terminate(_, _State, crash_terminate) ->
exit({crash, terminate});
+terminate(_, _, {undef_in_terminate, {Mod, Fun}}) ->
+ Mod:Fun(),
+ ok;
terminate({From, stopped}, State, _Data) ->
From ! {self(), {stopped, State}},
ok;
@@ -1017,6 +1188,8 @@ idle(badreturn, _From, _Data) ->
idle({timeout,Time}, From, _Data) ->
gen_fsm:send_event_after(Time, {timeout,Time}),
{next_state, timeout, From};
+idle('alive?', _From, Data) ->
+ {reply, 'alive!', idle, Data};
idle(_, _From, Data) ->
{reply, 'eh?', idle, Data}.
@@ -1089,7 +1262,12 @@ handle_info(hibernate_now, _SName, _State) ->
{next_state, hiber_idle, [], hibernate};
handle_info(hibernate_later, _SName, _State) ->
{next_state, hiber_idle, hibernate_me, 1000};
-
+handle_info({call_undef_fun, {Mod, Fun}}, State, Data) ->
+ Mod:Fun(),
+ {next_state, State, Data};
+handle_info({From, handle_info}, SName, State) ->
+ From ! {self(), handled_info},
+ {next_state, SName, State};
handle_info(Info, _State, Data) ->
{stop, {unexpected,Info}, Data}.
@@ -1134,6 +1312,13 @@ format_status(terminate, [_Pdict, StateData]) ->
format_status(normal, [_Pdict, _StateData]) ->
[format_status_called].
+code_change(_OldVsn, State,
+ {idle, {undef_in_code_change, {Mod, Fun}}} = Data, _Extra) ->
+ Mod:Fun(),
+ {ok, State, Data};
+code_change(_OldVsn, State, Data, _Extra) ->
+ {ok, State, Data}.
+
get_messages() ->
receive
Msg -> [Msg|get_messages()]
diff --git a/lib/stdlib/test/gen_fsm_SUITE_data/oc_fsm.erl b/lib/stdlib/test/gen_fsm_SUITE_data/oc_fsm.erl
new file mode 100644
index 0000000000..27fb1bc3b6
--- /dev/null
+++ b/lib/stdlib/test/gen_fsm_SUITE_data/oc_fsm.erl
@@ -0,0 +1,48 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(oc_fsm).
+
+-behaviour(gen_fsm).
+
+%% API
+-export([start/0]).
+
+%% gen_fsm callbacks
+-export([init/1,
+ state_name/2,
+ state_name/3]).
+
+-define(SERVER, ?MODULE).
+
+-record(state, {}).
+
+start() ->
+ gen_fsm:start({local, ?SERVER}, ?MODULE, [], []).
+
+init([]) ->
+ {ok, state_name, #state{}}.
+
+state_name(_Event, State) ->
+ {next_state, state_name, State}.
+
+state_name(_Event, _From, State) ->
+ Reply = ok,
+ {reply, Reply, state_name, State}.
+
diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl
index 338cd3dc0a..2e9dc4d4fb 100644
--- a/lib/stdlib/test/gen_server_SUITE.erl
+++ b/lib/stdlib/test/gen_server_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -32,9 +32,12 @@
call_remote_n1/1, call_remote_n2/1, call_remote_n3/1, spec_init/1,
spec_init_local_registered_parent/1,
spec_init_global_registered_parent/1,
- otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1,
+ otp_5854/1, hibernate/1, auto_hibernate/1, otp_7669/1, call_format_status/1,
error_format_status/1, terminate_crash_format/1,
- get_state/1, replace_state/1, call_with_huge_message_queue/1
+ get_state/1, replace_state/1, call_with_huge_message_queue/1,
+ undef_handle_call/1, undef_handle_cast/1, undef_handle_info/1,
+ undef_init/1, undef_code_change/1, undef_terminate1/1,
+ undef_terminate2/1, undef_in_terminate/1, undef_in_handle_info/1
]).
-export([stop1/1, stop2/1, stop3/1, stop4/1, stop5/1, stop6/1, stop7/1,
@@ -50,7 +53,7 @@
%% The gen_server behaviour
-export([init/1, handle_call/3, handle_cast/2,
- handle_info/2, terminate/2, format_status/2]).
+ handle_info/2, code_change/3, terminate/2, format_status/2]).
suite() ->
[{ct_hooks,[ts_install_cth]},
@@ -62,15 +65,20 @@ all() ->
call_remote3, call_remote_n1, call_remote_n2,
call_remote_n3, spec_init,
spec_init_local_registered_parent,
- spec_init_global_registered_parent, otp_5854, hibernate,
+ spec_init_global_registered_parent, otp_5854, hibernate, auto_hibernate,
otp_7669,
call_format_status, error_format_status, terminate_crash_format,
get_state, replace_state,
- call_with_huge_message_queue].
+ call_with_huge_message_queue, {group, undef_callbacks},
+ undef_in_terminate, undef_in_handle_info].
groups() ->
[{stop, [],
- [stop1, stop2, stop3, stop4, stop5, stop6, stop7, stop8, stop9, stop10]}].
+ [stop1, stop2, stop3, stop4, stop5, stop6, stop7, stop8, stop9, stop10]},
+ {undef_callbacks, [],
+ [undef_handle_call, undef_handle_cast, undef_handle_info,
+ undef_init, undef_code_change, undef_terminate1, undef_terminate2]}].
+
init_per_suite(Config) ->
Config.
@@ -78,6 +86,11 @@ init_per_suite(Config) ->
end_per_suite(_Config) ->
ok.
+init_per_group(undef_callbacks, Config) ->
+ DataDir = ?config(data_dir, Config),
+ Server = filename:join(DataDir, "oc_server.erl"),
+ {ok, oc_server} = compile:file(Server),
+ Config;
init_per_group(_GroupName, Config) ->
Config.
@@ -93,6 +106,7 @@ init_per_testcase(Case, Config) when Case == call_remote1;
Case == call_remote_n3 ->
{ok,N} = start_node(hubba),
[{node,N} | Config];
+
init_per_testcase(_Case, Config) ->
Config.
@@ -375,12 +389,14 @@ crash(Config) when is_list(Config) ->
%% from gen_server.
{ok,Pid4} = gen_server:start(?MODULE, {state,state4}, []),
{'EXIT',{crashed,_}} = (catch gen_server:call(Pid4, crash)),
+ ClientPid = self(),
receive
{error,_GroupLeader4,{Pid4,
"** Generic server"++_,
[Pid4,crash,{formatted, state4},
{crashed,[{?MODULE,handle_call,3,_}
- |_Stacktrace]}]}} ->
+ |_Stacktrace]},
+ ClientPid, [_|_] = _ClientStack]}} ->
ok;
Other4a ->
io:format("Unexpected: ~p", [Other4a]),
@@ -388,7 +404,7 @@ crash(Config) when is_list(Config) ->
end,
receive
{error_report,_,{Pid4,crash_report,[List4|_]}} ->
- {exit,crashed,_} = proplists:get_value(error_info, List4),
+ {exit,crashed,[{?MODULE, handle_call, 3, _}|_]} = proplists:get_value(error_info, List4),
Pid4 = proplists:get_value(pid, List4);
Other4 ->
io:format("Unexpected: ~p", [Other4]),
@@ -714,6 +730,58 @@ hibernate(Config) when is_list(Config) ->
process_flag(trap_exit, OldFl),
ok.
+auto_hibernate(Config) when is_list(Config) ->
+ OldFl = process_flag(trap_exit, true),
+ HibernateAfterTimeout = 100,
+ State = {auto_hibernate_state},
+ {ok, Pid} =
+ gen_server:start_link({local, my_test_name_auto_hibernate},
+ gen_server_SUITE, {state,State}, [{hibernate_after, HibernateAfterTimeout}]),
+ %% After init test
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% Get state test
+ State = sys:get_state(my_test_name_auto_hibernate),
+ is_in_erlang_hibernate(Pid),
+ %% Call test
+ ok = gen_server:call(my_test_name_auto_hibernate, started_p),
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% Cast test
+ ok = gen_server:cast(my_test_name_auto_hibernate, {self(),handle_cast}),
+ receive
+ {Pid, handled_cast} ->
+ ok
+ after 1000 ->
+ ct:fail(cast)
+ end,
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% Info test
+ Pid ! {self(),handle_info},
+ receive
+ {Pid, handled_info} ->
+ ok
+ after 1000 ->
+ ct:fail(info)
+ end,
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+
+ ok = gen_server:call(my_test_name_auto_hibernate, stop),
+ receive
+ {'EXIT', Pid, stopped} ->
+ ok
+ after 5000 ->
+ ct:fail(gen_server_did_not_die)
+ end,
+ process_flag(trap_exit, OldFl),
+ ok.
+
is_in_erlang_hibernate(Pid) ->
receive after 1 -> ok end,
is_in_erlang_hibernate_1(200, Pid).
@@ -731,6 +799,23 @@ is_in_erlang_hibernate_1(N, Pid) ->
is_in_erlang_hibernate_1(N-1, Pid)
end.
+is_not_in_erlang_hibernate(Pid) ->
+ receive after 1 -> ok end,
+ is_not_in_erlang_hibernate_1(200, Pid).
+
+is_not_in_erlang_hibernate_1(0, Pid) ->
+ io:format("~p\n", [erlang:process_info(Pid, current_function)]),
+ ct:fail(not_in_erlang_hibernate_3);
+is_not_in_erlang_hibernate_1(N, Pid) ->
+ {current_function,MFA} = erlang:process_info(Pid, current_function),
+ case MFA of
+ {erlang,hibernate,3} ->
+ receive after 10 -> ok end,
+ is_not_in_erlang_hibernate_1(N-1, Pid);
+ _ ->
+ ok
+ end.
+
%% --------------------------------------
%% Test gen_server:abcast and handle_cast.
%% Test all different return values from
@@ -1115,12 +1200,14 @@ error_format_status(Config) when is_list(Config) ->
{'EXIT', Pid, crashed} ->
ok
end,
+ ClientPid = self(),
receive
{error,_GroupLeader,{Pid,
"** Generic server"++_,
[Pid,crash,{formatted, State},
{crashed,[{?MODULE,handle_call,3,_}
- |_Stacktrace]}]}} ->
+ |_Stacktrace]},
+ ClientPid, [_|_] = _ClientStack]}} ->
ok;
Other ->
io:format("Unexpected: ~p", [Other]),
@@ -1138,12 +1225,14 @@ terminate_crash_format(Config) when is_list(Config) ->
{ok, Pid} = gen_server:start_link(?MODULE, {state, State}, []),
gen_server:call(Pid, stop),
receive {'EXIT', Pid, {crash, terminate}} -> ok end,
+ ClientPid = self(),
receive
{error,_GroupLeader,{Pid,
"** Generic server"++_,
[Pid,stop, {formatted, State},
- {{crash, terminate},[{?MODULE,terminate,2,_}
- |_Stacktrace]}]}} ->
+ {{crash, terminate},
+ [{?MODULE,terminate,2,_}|_Stacktrace]},
+ ClientPid, [_|_] = _ClientStack]}} ->
ok;
Other ->
io:format("Unexpected: ~p", [Other]),
@@ -1254,6 +1343,141 @@ echo_loop() ->
echo_loop()
end.
+%% Test the default implementation of terminate if the callback module
+%% does not export it
+undef_terminate1(Config) when is_list(Config) ->
+ {ok, Server} = gen_server:start(oc_server, [], []),
+ MRef = monitor(process, Server),
+ ok = gen_server:stop(Server),
+ ok = verify_down_reason(MRef, Server, normal).
+
+%% Test the default implementation of terminate if the callback module
+%% does not export it
+undef_terminate2(Config) when is_list(Config) ->
+ {ok, Server} = gen_server:start(oc_server, [], []),
+ MRef = monitor(process, Server),
+ ok = gen_server:stop(Server, {error, test}, infinity),
+ ok = verify_down_reason(MRef, Server, {error, test}).
+
+%% Start should return an undef error if init isn't implemented
+undef_init(_Config) ->
+ {error, {undef, [{oc_init_server, init, [_], _}|_]}} =
+ gen_server:start(oc_init_server, [], []),
+ process_flag(trap_exit, true),
+ {error, {undef, [{oc_init_server, init, [_], _}|_]}} =
+ (catch gen_server:start_link(oc_init_server, [], [])),
+ receive
+ {'EXIT', Server,
+ {undef, [{oc_init_server, init, [_], _}|_]}} when is_pid(Server) ->
+ ok
+ after 1000 ->
+ ct:fail(expected_exit_msg)
+ end.
+
+%% The upgrade should fail if code_change is expected in the callback module
+%% but not exported, but the server should continue with the old code
+undef_code_change(Config) when is_list(Config) ->
+ {ok, Server} = gen_server:start(oc_server, [], []),
+ {error, {'EXIT', {undef, [{oc_server, code_change, [_, _, _], _}|_]}}}
+ = fake_upgrade(Server, ?MODULE),
+ true = is_process_alive(Server).
+
+%% The server should crash if the handle_call callback is
+%% not exported in the callback module
+undef_handle_call(_Config) ->
+ {ok, Server} = gen_server:start(oc_server, [], []),
+ try
+ gen_server:call(Server, call_msg),
+ ct:fail(should_crash)
+ catch exit:{{undef, [{oc_server, handle_call, _, _}|_]},
+ {gen_server, call, _}} ->
+ ok
+ end.
+
+%% The server should crash if the handle_cast callback is
+%% not exported in the callback module
+undef_handle_cast(_Config) ->
+ {ok, Server} = gen_server:start(oc_server, [], []),
+ MRef = monitor(process, Server),
+ gen_server:cast(Server, cast_msg),
+ verify_undef_down(MRef, Server, oc_server, handle_cast),
+ ok.
+
+%% The server should log but not crash if the handle_info callback is
+%% calling an undefined function
+undef_handle_info(Config) when is_list(Config) ->
+ error_logger_forwarder:register(),
+ {ok, Server} = gen_server:start(oc_server, [], []),
+ Server ! hej,
+ wait_until_processed(Server, hej, 10),
+ true = is_process_alive(Server),
+ receive
+ {warning_msg, _GroupLeader,
+ {Server, "** Undefined handle_info in " ++ _, [oc_server, hej]}} ->
+ ok;
+ Other ->
+ io:format("Unexpected: ~p", [Other]),
+ ct:fail(failed)
+ end.
+
+%% Test that the default implementation of terminate isn't catching the
+%% wrong undef error
+undef_in_terminate(Config) when is_list(Config) ->
+ State = {undef_in_terminate, {oc_server, terminate}},
+ {ok, Server} = gen_server:start(?MODULE, {state, State}, []),
+ try
+ gen_server:stop(Server),
+ ct:fail(failed)
+ catch
+ exit:{undef, [{oc_server, terminate, [], _}|_]} ->
+ ok
+ end.
+
+%% Test that the default implementation of handle_info isn't catching the
+%% wrong undef error
+undef_in_handle_info(Config) when is_list(Config) ->
+ {ok, Server} = gen_server:start(?MODULE, [], []),
+ MRef = monitor(process, Server),
+ Server ! {call_undef_fun, ?MODULE, handle_info},
+ verify_undef_down(MRef, Server, ?MODULE, handle_info),
+ ok.
+
+verify_down_reason(MRef, Server, Reason) ->
+ receive
+ {'DOWN', MRef, process, Server, Reason} ->
+ ok
+ after 5000 ->
+ ct:fail(failed)
+ end.
+
+verify_undef_down(MRef, Pid, Mod, Fun) ->
+ ok = receive
+ {'DOWN', MRef, process, Pid,
+ {undef, [{Mod, Fun, _, _}|_]}} ->
+ ok
+ after 5000 ->
+ ct:fail(should_crash)
+ end.
+
+fake_upgrade(Pid, Mod) ->
+ sys:suspend(Pid),
+ sys:replace_state(Pid, fun(State) -> {new, State} end),
+ Ret = sys:change_code(Pid, Mod, old_vsn, []),
+ ok = sys:resume(Pid),
+ Ret.
+
+wait_until_processed(_Pid, _Message, 0) ->
+ ct:fail(not_processed);
+wait_until_processed(Pid, Message, N) ->
+ {messages, Messages} = erlang:process_info(Pid, messages),
+ case lists:member(Message, Messages) of
+ true ->
+ timer:sleep(100),
+ wait_until_processed(Pid, Message, N-1);
+ false ->
+ ok
+ end.
+
%%--------------------------------------------------------------
%% Help functions to spec_init_*
start_link(Init, Options) ->
@@ -1377,6 +1601,9 @@ handle_call(stop_shutdown, _From, State) ->
{stop,shutdown,State};
handle_call(shutdown_reason, _From, _State) ->
exit({shutdown,reason});
+handle_call({call_undef_fun, Mod, Fun}, _From, State) ->
+ Mod:Fun(),
+ {reply, ok, State};
handle_call(stop_shutdown_reason, _From, State) ->
{stop,{shutdown,stop_reason},State}.
@@ -1390,6 +1617,9 @@ handle_cast(hibernate_now, _State) ->
handle_cast(hibernate_later, _State) ->
timer:send_after(1000,self(),hibernate_now),
{noreply, []};
+handle_cast({call_undef_fun, Mod, Fun}, State) ->
+ Mod:Fun(),
+ {noreply, State};
handle_cast({From, stop}, State) ->
io:format("BAZ"),
{stop, {From,stopped}, State}.
@@ -1414,6 +1644,9 @@ handle_info(timeout, {delayed_cast, From}) ->
handle_info(timeout, {delayed_info, From}) ->
From ! {self(), delayed_info},
{noreply, []};
+handle_info({call_undef_fun, Mod, Fun}, State) ->
+ Mod:Fun(),
+ {noreply, State};
handle_info({From, handle_info}, _State) ->
From ! {self(), handled_info},
{noreply, []};
@@ -1427,6 +1660,12 @@ handle_info({From, stop}, State) ->
handle_info(_Info, State) ->
{noreply, State}.
+code_change(_OldVsn,
+ {new, {undef_in_code_change, {Mod, Fun}}} = State,
+ _Extra) ->
+ Mod:Fun(),
+ {ok, State}.
+
terminate({From, stopped}, _State) ->
io:format("FOOBAR"),
From ! {self(), stopped},
@@ -1436,6 +1675,9 @@ terminate({From, stopped_info}, _State) ->
ok;
terminate(_, crash_terminate) ->
exit({crash, terminate});
+terminate(_, {undef_in_terminate, {Mod, Fun}}) ->
+ Mod:Fun(),
+ ok;
terminate(_Reason, _State) ->
ok.
diff --git a/lib/gs/src/gstk.hrl b/lib/stdlib/test/gen_server_SUITE_data/oc_server.erl
index 931057573f..4ba37987f3 100644
--- a/lib/gs/src/gstk.hrl
+++ b/lib/stdlib/test/gen_server_SUITE_data/oc_server.erl
@@ -1,8 +1,8 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,16 +14,24 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
+%%
%% %CopyrightEnd%
%%
+-module(oc_server).
-%%
+-behaviour(gen_server).
+
+%% API
+-export([start/0]).
+
+%% gen_server callbacks
+-export([init/1]).
-%% *NOTE*: if you change here, change ets:match in gstk_db too!
--record(gstkid, {id=undefined, widget, widget_data, owner, parent,
- objtype}).
+-record(state, {}).
--record(so, {main, object, hscroll, vscroll, misc}).
+start() ->
+ gen_server:start({local, ?MODULE}, ?MODULE, [], []).
+init([]) ->
+ {ok, #state{}}.
diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl
index 364314f91b..5b9daecfd3 100644
--- a/lib/stdlib/test/gen_statem_SUITE.erl
+++ b/lib/stdlib/test/gen_statem_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2016. All Rights Reserved.
+%% Copyright Ericsson AB 2016-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -37,33 +37,36 @@ all() ->
{group, stop_handle_event},
{group, abnormal},
{group, abnormal_handle_event},
- shutdown, stop_and_reply, event_order,
+ shutdown, stop_and_reply, state_enter, event_order,
+ state_timeout, event_types, generic_timers, code_change,
{group, sys},
- hibernate, enter_loop].
+ hibernate, auto_hibernate, enter_loop, {group, undef_callbacks},
+ undef_in_terminate].
groups() ->
- [{start, [],
- [start1, start2, start3, start4, start5, start6, start7,
- start8, start9, start10, start11, start12, next_events]},
- {start_handle_event, [],
- [start1, start2, start3, start4, start5, start6, start7,
- start8, start9, start10, start11, start12, next_events]},
- {stop, [],
- [stop1, stop2, stop3, stop4, stop5, stop6, stop7, stop8, stop9, stop10]},
- {stop_handle_event, [],
- [stop1, stop2, stop3, stop4, stop5, stop6, stop7, stop8, stop9, stop10]},
- {abnormal, [], [abnormal1, abnormal2]},
- {abnormal_handle_event, [], [abnormal1, abnormal2]},
- {sys, [],
- [sys1, code_change,
- call_format_status,
- error_format_status, terminate_crash_format,
- get_state, replace_state]},
- {sys_handle_event, [],
- [sys1,
- call_format_status,
- error_format_status, terminate_crash_format,
- get_state, replace_state]}].
+ [{start, [], tcs(start)},
+ {start_handle_event, [], tcs(start)},
+ {stop, [], tcs(stop)},
+ {stop_handle_event, [], tcs(stop)},
+ {abnormal, [], tcs(abnormal)},
+ {abnormal_handle_event, [], tcs(abnormal)},
+ {sys, [], tcs(sys)},
+ {sys_handle_event, [], tcs(sys)},
+ {undef_callbacks, [], tcs(undef_callbacks)}].
+
+tcs(start) ->
+ [start1, start2, start3, start4, start5, start6, start7,
+ start8, start9, start10, start11, start12, next_events];
+tcs(stop) ->
+ [stop1, stop2, stop3, stop4, stop5, stop6, stop7, stop8, stop9, stop10];
+tcs(abnormal) ->
+ [abnormal1, abnormal1clean, abnormal1dirty, abnormal2];
+tcs(sys) ->
+ [sys1, call_format_status,
+ error_format_status, terminate_crash_format,
+ get_state, replace_state];
+tcs(undef_callbacks) ->
+ [undef_code_change, undef_terminate1, undef_terminate2].
init_per_suite(Config) ->
Config.
@@ -77,6 +80,11 @@ init_per_group(GroupName, Config)
GroupName =:= abnormal_handle_event;
GroupName =:= sys_handle_event ->
[{callback_mode,handle_event_function}|Config];
+init_per_group(undef_callbacks, Config) ->
+ DataDir = ?config(data_dir, Config),
+ StatemPath = filename:join(DataDir, "oc_statem.erl"),
+ {ok, oc_statem} = compile:file(StatemPath),
+ Config;
init_per_group(_GroupName, Config) ->
Config.
@@ -452,8 +460,52 @@ abnormal1(Config) ->
gen_statem:call(Name, {delayed_answer,1000}, 10),
Reason),
ok = gen_statem:stop(Name),
+ ?t:sleep(1100),
ok = verify_empty_msgq().
+%% Check that time outs in calls work
+abnormal1clean(Config) ->
+ Name = abnormal1clean,
+ LocalSTM = {local,Name},
+
+ {ok, _Pid} =
+ gen_statem:start(LocalSTM, ?MODULE, start_arg(Config, []), []),
+
+ %% timeout call.
+ delayed =
+ gen_statem:call(Name, {delayed_answer,1}, {clean_timeout,100}),
+ {timeout,_} =
+ ?EXPECT_FAILURE(
+ gen_statem:call(
+ Name, {delayed_answer,1000}, {clean_timeout,10}),
+ Reason),
+ ok = gen_statem:stop(Name),
+ ?t:sleep(1100),
+ ok = verify_empty_msgq().
+
+%% Check that time outs in calls work
+abnormal1dirty(Config) ->
+ Name = abnormal1dirty,
+ LocalSTM = {local,Name},
+
+ {ok, _Pid} =
+ gen_statem:start(LocalSTM, ?MODULE, start_arg(Config, []), []),
+
+ %% timeout call.
+ delayed =
+ gen_statem:call(Name, {delayed_answer,1}, {dirty_timeout,100}),
+ {timeout,_} =
+ ?EXPECT_FAILURE(
+ gen_statem:call(
+ Name, {delayed_answer,1000}, {dirty_timeout,10}),
+ Reason),
+ ok = gen_statem:stop(Name),
+ ?t:sleep(1100),
+ case flush() of
+ [{Ref,delayed}] when is_reference(Ref) ->
+ ok
+ end.
+
%% Check that bad return values makes the stm crash. Note that we must
%% trap exit since we must link to get the real bad_return_ error
abnormal2(Config) ->
@@ -461,10 +513,10 @@ abnormal2(Config) ->
{ok,Pid} = gen_statem:start_link(?MODULE, start_arg(Config, []), []),
%% bad return value in the gen_statem loop
- {{bad_return_value,badreturn},_} =
+ {{{bad_return_from_state_function,badreturn},_},_} =
?EXPECT_FAILURE(gen_statem:call(Pid, badreturn), Reason),
receive
- {'EXIT',Pid,{bad_return_value,badreturn}} -> ok
+ {'EXIT',Pid,{{bad_return_from_state_function,badreturn},_}} -> ok
after 5000 ->
ct:fail(gen_statem_did_not_die)
end,
@@ -513,7 +565,8 @@ stop_and_reply(_Config) ->
{stop_and_reply,Reason,
[R1,{reply,From2,Reply2}]}
end},
- {ok,STM} = gen_statem:start_link(?MODULE, {map_statem,Machine}, []),
+ {ok,STM} =
+ gen_statem:start_link(?MODULE, {map_statem,Machine,[]}, []),
Self = self(),
Tag1 = make_ref(),
@@ -538,6 +591,76 @@ stop_and_reply(_Config) ->
+state_enter(_Config) ->
+ process_flag(trap_exit, true),
+ Self = self(),
+
+ Machine =
+ %% Abusing the internal format of From...
+ #{init =>
+ fun () ->
+ {ok,start,1}
+ end,
+ start =>
+ fun (enter, Prev, N) ->
+ Self ! {enter,start,Prev,N},
+ {keep_state,N + 1};
+ (internal, Prev, N) ->
+ Self ! {internal,start,Prev,N},
+ {keep_state,N + 1};
+ ({call,From}, repeat, N) ->
+ {repeat_state,N + 1,
+ [{reply,From,{repeat,start,N}}]};
+ ({call,From}, echo, N) ->
+ {next_state,wait,N + 1,
+ {reply,From,{echo,start,N}}};
+ ({call,From}, {stop,Reason}, N) ->
+ {stop_and_reply,Reason,
+ [{reply,From,{stop,N}}],N + 1}
+ end,
+ wait =>
+ fun (enter, Prev, N) when N < 5 ->
+ {repeat_state,N + 1,
+ {reply,{Self,N},{enter,Prev}}};
+ (enter, Prev, N) ->
+ Self ! {enter,wait,Prev,N},
+ {keep_state,N + 1};
+ ({call,From}, repeat, N) ->
+ {repeat_state_and_data,
+ [{reply,From,{repeat,wait,N}}]};
+ ({call,From}, echo, N) ->
+ {next_state,start,N + 1,
+ [{next_event,internal,wait},
+ {reply,From,{echo,wait,N}}]}
+ end},
+ {ok,STM} =
+ gen_statem:start_link(
+ ?MODULE, {map_statem,Machine,[state_enter]}, []),
+
+ [{enter,start,start,1}] = flush(),
+ {echo,start,2} = gen_statem:call(STM, echo),
+ [{3,{enter,start}},{4,{enter,start}},{enter,wait,start,5}] = flush(),
+ {wait,[6|_]} = sys:get_state(STM),
+ {repeat,wait,6} = gen_statem:call(STM, repeat),
+ [{enter,wait,wait,6}] = flush(),
+ {echo,wait,7} = gen_statem:call(STM, echo),
+ [{enter,start,wait,8},{internal,start,wait,9}] = flush(),
+ {repeat,start,10} = gen_statem:call(STM, repeat),
+ [{enter,start,start,11}] = flush(),
+ {stop,12} = gen_statem:call(STM, {stop,bye}),
+ [{'EXIT',STM,bye}] = flush(),
+
+ {noproc,_} =
+ ?EXPECT_FAILURE(gen_statem:call(STM, hej), Reason),
+ case flush() of
+ [] ->
+ ok;
+ Other2 ->
+ ct:fail({unexpected,Other2})
+ end.
+
+
+
event_order(_Config) ->
process_flag(trap_exit, true),
@@ -580,7 +703,7 @@ event_order(_Config) ->
Result
end},
- {ok,STM} = gen_statem:start_link(?MODULE, {map_statem,Machine}, []),
+ {ok,STM} = gen_statem:start_link(?MODULE, {map_statem,Machine,[]}, []),
Self = self(),
Tag1 = make_ref(),
gen_statem:cast(STM, {reply,{Self,Tag1},ok1}),
@@ -610,6 +733,233 @@ event_order(_Config) ->
+state_timeout(_Config) ->
+ process_flag(trap_exit, true),
+
+ Machine =
+ #{init =>
+ fun () ->
+ {ok,start,0}
+ end,
+ start =>
+ fun
+ ({call,From}, {go,Time}, 0) ->
+ self() ! message_to_self,
+ {next_state, state1, {Time,From},
+ %% Verify that internal events goes before external
+ [{state_timeout,Time,1},
+ {next_event,internal,1}]}
+ end,
+ state1 =>
+ fun
+ (internal, 1, Data) ->
+ %% Verify that a state change cancels timeout 1
+ {next_state, state2, Data,
+ [{timeout,0,2},
+ {state_timeout,0,2},
+ {next_event,internal,2}]}
+ end,
+ state2 =>
+ fun
+ (internal, 2, Data) ->
+ %% Verify that {state_timeout,0,_}
+ %% comes after next_event and that
+ %% {timeout,0,_} is cancelled by
+ %% pending {state_timeout,0,_}
+ {keep_state, {ok,2,Data},
+ [{timeout,0,3}]};
+ (state_timeout, 2, {ok,2,Data}) ->
+ %% Verify that timeout 0's are processed
+ %% in order
+ {keep_state, {ok,3,Data},
+ [{timeout,0,4},{state_timeout,0,5}]};
+ (timeout, 4, {ok,3,Data}) ->
+ %% Verify that timeout 0 is cancelled by
+ %% enqueued state_timeout 0 and that
+ %% multiple state_timeout 0 can be enqueued
+ {keep_state, {ok,4,Data},
+ [{state_timeout,0,6},{timeout,0,7}]};
+ (state_timeout, 5, {ok,4,Data}) ->
+ {keep_state, {ok,5,Data}};
+ (state_timeout, 6, {ok,5,{Time,From}}) ->
+ {next_state, state3, 6,
+ [{reply,From,ok},
+ {state_timeout,Time,8}]}
+ end,
+ state3 =>
+ fun
+ (info, message_to_self, 6) ->
+ {keep_state, 7};
+ ({call,From}, check, 7) ->
+ {keep_state, From};
+ (state_timeout, 8, From) ->
+ {stop_and_reply, normal,
+ {reply,From,ok}}
+ end},
+
+ {ok,STM} = gen_statem:start_link(?MODULE, {map_statem,Machine,[]}, []),
+ sys:trace(STM, true),
+ TRef = erlang:start_timer(1000, self(), kull),
+ ok = gen_statem:call(STM, {go,500}),
+ ok = gen_statem:call(STM, check),
+ receive
+ {timeout,TRef,kull} ->
+ ct:fail(late_timeout)
+ after 0 ->
+ receive
+ {timeout,TRef,kull} ->
+ ok
+ after 1000 ->
+ ct:fail(no_check_timeout)
+ end
+ end,
+ receive
+ {'EXIT',STM,normal} ->
+ ok
+ after 500 ->
+ ct:fail(did_not_stop)
+ end,
+
+ verify_empty_msgq().
+
+
+
+%% Test that all event types can be sent with {next_event,EventType,_}
+event_types(_Config) ->
+ process_flag(trap_exit, true),
+
+ Machine =
+ %% Abusing the internal format of From...
+ #{init =>
+ fun () ->
+ {ok, start, undefined}
+ end,
+ start =>
+ fun ({call,_} = Call, Req, undefined) ->
+ {next_state, state1, undefined,
+ [{next_event,internal,1},
+ {next_event,state_timeout,2},
+ {next_event,timeout,3},
+ {next_event,info,4},
+ {next_event,cast,5},
+ {next_event,{timeout,6}, 6},
+ {next_event,Call,Req}]}
+ end,
+ state1 =>
+ fun (internal, 1, undefined) ->
+ {next_state, state2, undefined}
+ end,
+ state2 =>
+ fun (state_timeout, 2, undefined) ->
+ {next_state, state3, undefined}
+ end,
+ state3 =>
+ fun (timeout, 3, undefined) ->
+ {next_state, state4, undefined}
+ end,
+ state4 =>
+ fun (info, 4, undefined) ->
+ {next_state, state5, undefined}
+ end,
+ state5 =>
+ fun (cast, 5, undefined) ->
+ {next_state, state6, undefined}
+ end,
+ state6 =>
+ fun ({timeout,6}, 6, undefined) ->
+ {next_state, state7, undefined}
+ end,
+ state7 =>
+ fun ({call,From}, stop, undefined) ->
+ {stop_and_reply, shutdown,
+ [{reply,From,stopped}]}
+ end},
+ {ok,STM} =
+ gen_statem:start_link(
+ ?MODULE, {map_statem,Machine,[]}, [{debug,[trace]}]),
+
+ stopped = gen_statem:call(STM, stop),
+ receive
+ {'EXIT',STM,shutdown} ->
+ ok
+ after 500 ->
+ ct:fail(did_not_stop)
+ end,
+
+ {noproc,_} =
+ ?EXPECT_FAILURE(gen_statem:call(STM, hej), Reason),
+ case flush() of
+ [] ->
+ ok;
+ Other2 ->
+ ct:fail({unexpected,Other2})
+ end.
+
+
+
+generic_timers(_Config) ->
+ process_flag(trap_exit, true),
+
+ Machine =
+ %% Abusing the internal format of From...
+ #{init =>
+ fun () ->
+ {ok, start, undefined}
+ end,
+ start =>
+ fun ({call,_} = Call, Req, undefined) ->
+ {next_state, state1, undefined,
+ [{{timeout,a},1500,1},
+ {state_timeout,1500,1},
+ {{timeout,b},1000,1},
+ {next_event,Call,Req}]}
+ end,
+ state1 =>
+ fun ({call,_} = Call, Req, undefined) ->
+ T = erlang:monotonic_time(millisecond) + 500,
+ {next_state, state2, undefined,
+ [{{timeout,c},T,2,{abs,true}},
+ {{timeout,d},0,2,[{abs,false}]},
+ {timeout,0,2},
+ {{timeout,b},infinity,2},
+ {{timeout,a},1000,{Call,Req}}]}
+ end,
+ state2 =>
+ fun ({timeout,d}, 2, undefined) ->
+ {next_state, state3, undefined}
+ end,
+ state3 =>
+ fun ({timeout,c}, 2, undefined) ->
+ {next_state, state4, undefined}
+ end,
+ state4 =>
+ fun ({timeout,a}, {{call,From},stop}, undefined) ->
+ {stop_and_reply, shutdown,
+ [{reply,From,stopped}]}
+ end},
+ {ok,STM} =
+ gen_statem:start_link(
+ ?MODULE, {map_statem,Machine,[]}, [{debug,[trace]}]),
+
+ stopped = gen_statem:call(STM, stop),
+ receive
+ {'EXIT',STM,shutdown} ->
+ ok
+ after 500 ->
+ ct:fail(did_not_stop)
+ end,
+
+ {noproc,_} =
+ ?EXPECT_FAILURE(gen_statem:call(STM, hej), Reason),
+ case flush() of
+ [] ->
+ ok;
+ Other2 ->
+ ct:fail({unexpected,Other2})
+ end.
+
+
+
sys1(Config) ->
{ok,Pid} = gen_statem:start(?MODULE, start_arg(Config, []), []),
{status, Pid, {module,gen_statem}, _} = sys:get_status(Pid),
@@ -633,11 +983,13 @@ sys1(Config) ->
sys:resume(Pid),
stop_it(Pid).
-code_change(Config) ->
- Mode = handle_event_function,
- {ok,Pid} = gen_statem:start(?MODULE, start_arg(Config, []), []),
+code_change(_Config) ->
+ {ok,Pid} =
+ gen_statem:start(
+ ?MODULE, {callback_mode,state_functions,[]}, []),
{idle,data} = sys:get_state(Pid),
sys:suspend(Pid),
+ Mode = handle_event_function,
sys:change_code(Pid, ?MODULE, old_vsn, Mode),
sys:resume(Pid),
{idle,{old_vsn,data,Mode}} = sys:get_state(Pid),
@@ -708,7 +1060,7 @@ error_format_status(Config) ->
gen_statem:start(
?MODULE, start_arg(Config, {data,Data}), []),
%% bad return value in the gen_statem loop
- {{bad_return_value,badreturn},_} =
+ {{{bad_return_from_state_function,badreturn},_},_} =
?EXPECT_FAILURE(gen_statem:call(Pid, badreturn), Reason),
receive
{error,_,
@@ -716,7 +1068,7 @@ error_format_status(Config) ->
"** State machine"++_,
[Pid,{{call,_},badreturn},
{formatted,idle,Data},
- error,{bad_return_value,badreturn}|_]}} ->
+ error,{bad_return_from_state_function,badreturn}|_]}} ->
ok;
Other when is_tuple(Other), element(1, Other) =:= error ->
error_logger_forwarder:unregister(),
@@ -932,6 +1284,84 @@ hibernate(Config) ->
end,
ok = verify_empty_msgq().
+%% Auto-hibernation timeout
+auto_hibernate(Config) ->
+ OldFl = process_flag(trap_exit, true),
+ HibernateAfterTimeout = 100,
+
+ {ok,Pid} =
+ gen_statem:start_link(
+ ?MODULE, start_arg(Config, []), [{hibernate_after, HibernateAfterTimeout}]),
+ %% After init test
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% After info test
+ Pid ! {hping, self()},
+ receive
+ {Pid, hpong} ->
+ ok
+ after 1000 ->
+ ct:fail(info)
+ end,
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% After cast test
+ ok = gen_statem:cast(Pid, {hping, self()}),
+ receive
+ {Pid, hpong} ->
+ ok
+ after 1000 ->
+ ct:fail(cast)
+ end,
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% After call test
+ hpong = gen_statem:call(Pid, hping),
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% Timer test 1
+ TimerTimeout1 = 50,
+ ok = gen_statem:call(Pid, {arm_htimer, self(), TimerTimeout1}),
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(TimerTimeout1),
+ is_not_in_erlang_hibernate(Pid),
+ receive
+ {Pid, htimer_armed} ->
+ ok
+ after 1000 ->
+ ct:fail(timer1)
+ end,
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ %% Timer test 2
+ TimerTimeout2 = 150,
+ ok = gen_statem:call(Pid, {arm_htimer, self(), TimerTimeout2}),
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ receive
+ {Pid, htimer_armed} ->
+ ok
+ after 1000 ->
+ ct:fail(timer2)
+ end,
+ is_not_in_erlang_hibernate(Pid),
+ timer:sleep(HibernateAfterTimeout),
+ is_in_erlang_hibernate(Pid),
+ stop_it(Pid),
+ process_flag(trap_exit, OldFl),
+ receive
+ {'EXIT',Pid,normal} -> ok
+ after 5000 ->
+ ct:fail(gen_statem_did_not_die)
+ end,
+ ok = verify_empty_msgq().
+
is_in_erlang_hibernate(Pid) ->
receive after 1 -> ok end,
is_in_erlang_hibernate_1(200, Pid).
@@ -1029,11 +1459,7 @@ enter_loop(_Config) ->
end,
%% Process not started using proc_lib
- CallbackMode = state_functions,
- Pid4 =
- spawn_link(
- gen_statem, enter_loop,
- [?MODULE,[],CallbackMode,state0,[]]),
+ Pid4 = spawn_link(gen_statem, enter_loop, [?MODULE,[],state0,[]]),
receive
{'EXIT',Pid4,process_was_not_started_by_proc_lib} ->
ok
@@ -1107,23 +1533,65 @@ enter_loop(Reg1, Reg2) ->
anon -> ignore
end,
proc_lib:init_ack({ok, self()}),
- CallbackMode = state_functions,
case Reg2 of
local ->
gen_statem:enter_loop(
- ?MODULE, [], CallbackMode, state0, [], {local,armitage});
+ ?MODULE, [], state0, [], {local,armitage});
global ->
gen_statem:enter_loop(
- ?MODULE, [], CallbackMode, state0, [], {global,armitage});
+ ?MODULE, [], state0, [], {global,armitage});
via ->
gen_statem:enter_loop(
- ?MODULE, [], CallbackMode, state0, [],
- {via, dummy_via, armitage});
+ ?MODULE, [], state0, [], {via, dummy_via, armitage});
anon ->
- gen_statem:enter_loop(
- ?MODULE, [], CallbackMode, state0, [])
+ gen_statem:enter_loop(?MODULE, [], state0, [])
+ end.
+
+undef_code_change(_Config) ->
+ {ok, Statem} = gen_statem:start(oc_statem, [], []),
+ {error, {'EXIT',
+ {undef, [{oc_statem, code_change, [_, _, _, _], _}|_]}}}
+ = fake_upgrade(Statem, oc_statem).
+
+fake_upgrade(Pid, Mod) ->
+ sys:suspend(Pid),
+ sys:replace_state(Pid, fun(State) -> {new, State} end),
+ Ret = sys:change_code(Pid, Mod, old_vsn, []),
+ ok = sys:resume(Pid),
+ Ret.
+
+undef_terminate1(_Config) ->
+ {ok, Statem} = gen_statem:start(oc_statem, [], []),
+ MRef = monitor(process, Statem),
+ ok = gen_statem:stop(Statem),
+ verify_down(Statem, MRef, normal),
+ ok.
+
+undef_terminate2(_Config) ->
+ Reason = {error, test},
+ {ok, Statem} = oc_statem:start(),
+ MRef = monitor(process, Statem),
+ ok = gen_statem:stop(Statem, Reason, infinity),
+ verify_down(Statem, MRef, Reason).
+
+undef_in_terminate(_Config) ->
+ Data = {undef_in_terminate, {?MODULE, terminate}},
+ {ok, Statem} = gen_statem:start(?MODULE, {data, Data}, []),
+ try
+ gen_statem:stop(Statem),
+ ct:fail(should_crash)
+ catch
+ exit:{undef, [{?MODULE, terminate, _, _}|_]} ->
+ ok
end.
+verify_down(Statem, MRef, Reason) ->
+ receive
+ {'DOWN', MRef, process, Statem, Reason} ->
+ ok
+ after 5000 ->
+ ct:fail(default_terminate_failed)
+ end.
%% Test the order for multiple {next_event,T,C}
next_events(Config) ->
@@ -1266,36 +1734,45 @@ init(stop_shutdown) ->
{stop,shutdown};
init(sleep) ->
?t:sleep(1000),
- {state_functions,idle,data};
+ {ok,idle,data};
init(hiber) ->
- {state_functions,hiber_idle,[]};
+ {ok,hiber_idle,[]};
init(hiber_now) ->
- {state_functions,hiber_idle,[],[hibernate]};
+ {ok,hiber_idle,[],[hibernate]};
init({data, Data}) ->
- {state_functions,idle,Data};
+ {ok,idle,Data};
init({callback_mode,CallbackMode,Arg}) ->
- case init(Arg) of
- {_,State,Data,Ops} ->
- {CallbackMode,State,Data,Ops};
- {_,State,Data} ->
- {CallbackMode,State,Data};
- Other ->
- Other
- end;
-init({map_statem,#{init := Init}=Machine}) ->
+ ets:new(?MODULE, [named_table,private]),
+ ets:insert(?MODULE, {callback_mode,CallbackMode}),
+ init(Arg);
+init({map_statem,#{init := Init}=Machine,Modes}) ->
+ ets:new(?MODULE, [named_table,private]),
+ ets:insert(?MODULE, {callback_mode,[handle_event_function|Modes]}),
case Init() of
{ok,State,Data,Ops} ->
- {handle_event_function,State,[Data|Machine],Ops};
+ {ok,State,[Data|Machine],Ops};
{ok,State,Data} ->
- {handle_event_function,State,[Data|Machine]};
+ {ok,State,[Data|Machine]};
Other ->
Other
end;
init([]) ->
- {state_functions,idle,data}.
+ {ok,idle,data}.
+
+callback_mode() ->
+ try ets:lookup(?MODULE, callback_mode) of
+ [{callback_mode,CallbackMode}] ->
+ CallbackMode
+ catch
+ error:badarg ->
+ state_functions
+ end.
terminate(_, _State, crash_terminate) ->
exit({crash,terminate});
+terminate(_, _State, {undef_in_terminate, {Mod, Fun}}) ->
+ Mod:Fun(),
+ ok;
terminate({From,stopped}, State, _Data) ->
From ! {self(),{stopped,State}},
ok;
@@ -1305,6 +1782,19 @@ terminate(_Reason, _State, _Data) ->
%% State functions
+idle(info, {hping,Pid}, _Data) ->
+ Pid ! {self(), hpong},
+ keep_state_and_data;
+idle(cast, {hping,Pid}, Data) ->
+ Pid ! {self(), hpong},
+ {keep_state, Data};
+idle({call, From}, hping, _Data) ->
+ {keep_state_and_data, [{reply, From, hpong}]};
+idle({call, From}, {arm_htimer, Pid, Timeout}, _Data) ->
+ {keep_state_and_data, [{reply, From, ok}, {timeout, Timeout, {arm_htimer, Pid}}]};
+idle(timeout, {arm_htimer, Pid}, _Data) ->
+ Pid ! {self(), htimer_armed},
+ keep_state_and_data;
idle(cast, {connect,Pid}, Data) ->
Pid ! accept,
{next_state,wfor_conf,Data,infinity}; % NoOp timeout just to test API
@@ -1322,8 +1812,9 @@ idle({call,From}, {delayed_answer,T}, Data) ->
throw({keep_state,Data})
end;
idle({call,From}, {timeout,Time}, _Data) ->
+ AbsTime = erlang:monotonic_time(millisecond) + Time,
{next_state,timeout,{From,Time},
- {timeout,Time,idle}};
+ {timeout,AbsTime,idle,[{abs,true}]}};
idle(cast, next_event, _Data) ->
{next_state,next_events,[a,b,c],
[{next_event,internal,a},
@@ -1530,6 +2021,10 @@ handle_event(
{keep_state,[NewData|Machine]};
{keep_state,NewData,Ops} ->
{keep_state,[NewData|Machine],Ops};
+ {repeat_state,NewData} ->
+ {repeat_state,[NewData|Machine]};
+ {repeat_state,NewData,Ops} ->
+ {repeat_state,[NewData|Machine],Ops};
Other ->
Other
end;
@@ -1568,7 +2063,12 @@ wrap_result(Result) ->
code_change(OldVsn, State, Data, CallbackMode) ->
- {CallbackMode,State,{OldVsn,Data,CallbackMode}}.
+ io:format(
+ "code_change(~p, ~p, ~p, ~p)~n", [OldVsn,State,Data,CallbackMode]),
+ ets:insert(?MODULE, {callback_mode,CallbackMode}),
+ io:format(
+ "code_change(~p, ~p, ~p, ~p)~n", [OldVsn,State,Data,CallbackMode]),
+ {ok,State,{OldVsn,Data,CallbackMode}}.
format_status(terminate, [_Pdict,State,Data]) ->
{formatted,State,Data};
diff --git a/lib/hipe/util/hipe_vectors.hrl b/lib/stdlib/test/gen_statem_SUITE_data/oc_statem.erl
index d4556e9dc4..27c9e0718d 100644
--- a/lib/hipe/util/hipe_vectors.hrl
+++ b/lib/stdlib/test/gen_statem_SUITE_data/oc_statem.erl
@@ -1,8 +1,8 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,16 +14,24 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-%%-define(USE_TUPLES, true).
--define(USE_GBTREES, true).
+-module(oc_statem).
+
+-behaviour(gen_statem).
+
+%% API
+-export([start/0]).
+
+%% gen_statem callbacks
+-export([init/1, callback_mode/0]).
+
+start() ->
+ gen_statem:start({local, ?MODULE}, ?MODULE, [], []).
--ifdef(USE_TUPLES).
--type hipe_vector() :: tuple().
--endif.
+init([]) ->
+ {ok, state_name, #{}}.
--ifdef(USE_GBTREES).
--type hipe_vector() :: gb_trees:tree().
--endif.
+callback_mode() ->
+ handle_event_function.
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl
index 7d48cbc97c..e2c73371cd 100644
--- a/lib/stdlib/test/io_SUITE.erl
+++ b/lib/stdlib/test/io_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -30,7 +30,8 @@
io_lib_print_binary_depth_one/1, otp_10302/1, otp_10755/1,
otp_10836/1, io_lib_width_too_small/1,
io_with_huge_message_queue/1, format_string/1,
- maps/1, coverage/1]).
+ maps/1, coverage/1, otp_14178_unicode_atoms/1, otp_14175/1,
+ otp_14285/1, limit_term/1]).
-export([pretty/2]).
@@ -61,7 +62,8 @@ all() ->
printable_range, bad_printable_range,
io_lib_print_binary_depth_one, otp_10302, otp_10755, otp_10836,
io_lib_width_too_small, io_with_huge_message_queue,
- format_string, maps, coverage].
+ format_string, maps, coverage, otp_14178_unicode_atoms, otp_14175,
+ otp_14285, limit_term].
%% Error cases for output.
error_1(Config) when is_list(Config) ->
@@ -415,13 +417,13 @@ otp_6354(Config) when is_list(Config) ->
bt(<<"#rrrrr{\n"
" f1 = 1,\n"
" f2 = #rrrrr{f1 = a,f2 = b,f3 = c},\n"
- " f3 = \n"
+ " f3 =\n"
" #rrrrr{\n"
" f1 = h,f2 = i,\n"
- " f3 = \n"
+ " f3 =\n"
" #rrrrr{\n"
" f1 = aa,\n"
- " f2 = \n"
+ " f2 =\n"
" #rrrrr{\n"
" f1 = #rrrrr{f1 = a,f2 = b,f3 = c},\n"
" f2 = 2,f3 = 3},\n"
@@ -431,17 +433,17 @@ otp_6354(Config) when is_list(Config) ->
2,3},bb}}},
-1)),
bt(<<"#d{aaaaaaaaaaaaaaaaaaaa = 1,\n"
- " bbbbbbbbbbbbbbbbbbbb = \n"
+ " bbbbbbbbbbbbbbbbbbbb =\n"
" #d{aaaaaaaaaaaaaaaaaaaa = a,bbbbbbbbbbbbbbbbbbbb = b,\n"
" cccccccccccccccccccc = c,dddddddddddddddddddd = d,\n"
" eeeeeeeeeeeeeeeeeeee = e},\n"
" cccccccccccccccccccc = 3,\n"
- " dddddddddddddddddddd = \n"
+ " dddddddddddddddddddd =\n"
" #d{aaaaaaaaaaaaaaaaaaaa = h,bbbbbbbbbbbbbbbbbbbb = i,\n"
- " cccccccccccccccccccc = \n"
+ " cccccccccccccccccccc =\n"
" #d{aaaaaaaaaaaaaaaaaaaa = aa,"
"bbbbbbbbbbbbbbbbbbbb = bb,\n"
- " cccccccccccccccccccc = \n"
+ " cccccccccccccccccccc =\n"
" #d{aaaaaaaaaaaaaaaaaaaa = 1,"
"bbbbbbbbbbbbbbbbbbbb = 2,\n"
" cccccccccccccccccccc = 3,"
@@ -534,21 +536,21 @@ otp_6354(Config) when is_list(Config) ->
p({A,{A,{A,{A,{A,{A,{A,
{g,{h,{i,{j,{k,{l,{m,{n,{o,{a}}}}}}}}}}}}}}}}}, 100)),
bt(<<"#c{\n"
- " f1 = \n"
+ " f1 =\n"
" #c{\n"
- " f1 = \n"
+ " f1 =\n"
" #c{\n"
- " f1 = \n"
+ " f1 =\n"
" #c{\n"
- " f1 = \n"
+ " f1 =\n"
" #c{\n"
- " f1 = \n"
+ " f1 =\n"
" #c{\n"
- " f1 = \n"
+ " f1 =\n"
" #c{\n"
- " f1 = \n"
+ " f1 =\n"
" #c{\n"
- " f1 = \n"
+ " f1 =\n"
" #c{\n"
" f1 = #c{f1 = #c{f1 = #c{f1 = a,"
"f2 = b},f2 = b},f2 = b},\n"
@@ -564,13 +566,13 @@ otp_6354(Config) when is_list(Config) ->
p({c,{c,{c,{c,{c,{c,{c,{c,{c,{c,{c,{c,a,b},b},b},b},b},b},
b},b},b},b},b},b}, -1)),
bt(<<"#rrrrr{\n"
- " f1 = \n"
+ " f1 =\n"
" #rrrrr{\n"
- " f1 = \n"
+ " f1 =\n"
" #rrrrr{\n"
- " f1 = \n"
+ " f1 =\n"
" #rrrrr{\n"
- " f1 = \n"
+ " f1 =\n"
" {rrrrr,{rrrrr,a,#rrrrr{f1 = {rrrrr,1,2},f2 = a,"
"f3 = b}},b},\n"
" f2 = {rrrrr,c,d},\n"
@@ -755,6 +757,8 @@ rfd(rrrrr, 3) ->
[f1, f2, f3];
rfd(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0) ->
[];
+rfd('\x{400}', 1) ->
+ ['\x{400}'];
rfd(_, _) ->
no.
@@ -1881,6 +1885,7 @@ otp_10302(Suite) when is_list(Suite) ->
pretty(Term, Depth) when is_integer(Depth) ->
Opts = [{column, 1}, {line_length, 20},
{depth, Depth}, {max_chars, 60},
+ {record_print_fun, fun rfd/2},
{encoding, unicode}],
pretty(Term, Opts);
pretty(Term, Opts) when is_list(Opts) ->
@@ -2106,3 +2111,320 @@ coverage(_Config) ->
io:format("~s\n", [S2]),
ok.
+
+%% Test UTF-8 atoms.
+otp_14178_unicode_atoms(_Config) ->
+ "atom" = fmt("~ts", ['atom']),
+ "кирилли́ческий атом" = fmt("~ts", ['кирилли́ческий атом']),
+ [16#10FFFF] = fmt("~ts", ['\x{10FFFF}']),
+
+ %% ~s must not accept code points greater than 255.
+ bad_io_lib_format("~s", ['\x{100}']),
+ bad_io_lib_format("~s", ['кирилли́ческий атом']),
+
+ ok.
+
+bad_io_lib_format(F, S) ->
+ try io_lib:format(F, S) of
+ _ ->
+ ct:fail({should_fail,F,S})
+ catch
+ error:badarg ->
+ ok
+ end.
+
+otp_14175(_Config) ->
+ "..." = p(#{}, 0),
+ "#{}" = p(#{}, 1),
+ "#{...}" = p(#{a => 1}, 1),
+ "#{#{} => a}" = p(#{#{} => a}, 2),
+ "#{a => 1,...}" = p(#{a => 1, b => 2}, 2),
+ "#{a => 1,b => 2}" = p(#{a => 1, b => 2}, -1),
+
+ M = #{kaaaaaaaaaaaaaaaaaaa => v1,kbbbbbbbbbbbbbbbbbbb => v2,
+ kccccccccccccccccccc => v3,kddddddddddddddddddd => v4,
+ keeeeeeeeeeeeeeeeeee => v5},
+ "#{...}" = p(M, 1),
+ mt("#{kaaaaaaaaaaaaaaaaaaaa => v1,...}", p(M, 2)),
+ mt("#{kaaaaaaaaaaaaaaaaaaaa => 1,kbbbbbbbbbbbbbbbbbbbb => 2,...}",
+ p(M, 3)),
+
+ mt("#{kaaaaaaaaaaaaaaaaaaa => v1,kbbbbbbbbbbbbbbbbbbb => v2,\n"
+ " kccccccccccccccccccc => v3,...}", p(M, 4)),
+
+ mt("#{kaaaaaaaaaaaaaaaaaaa => v1,kbbbbbbbbbbbbbbbbbbb => v2,\n"
+ " kccccccccccccccccccc => v3,kddddddddddddddddddd => v4,...}",
+ p(M, 5)),
+
+ mt("#{kaaaaaaaaaaaaaaaaaaa => v1,kbbbbbbbbbbbbbbbbbbb => v2,\n"
+ " kccccccccccccccccccc => v3,kddddddddddddddddddd => v4,\n"
+ " keeeeeeeeeeeeeeeeeee => v5}", p(M, 6)),
+
+ weak("#{aaaaaaaaaaaaaaaaaaa => 1,bbbbbbbbbbbbbbbbbbbb => 2,\n"
+ " cccccccccccccccccccc => {3},\n"
+ " dddddddddddddddddddd => 4,eeeeeeeeeeeeeeeeeeee => 5}",
+ p(#{aaaaaaaaaaaaaaaaaaa => 1,bbbbbbbbbbbbbbbbbbbb => 2,
+ cccccccccccccccccccc => {3},
+ dddddddddddddddddddd => 4,eeeeeeeeeeeeeeeeeeee => 5}, -1)),
+
+ M2 = #{dddddddddddddddddddd => {1}, {aaaaaaaaaaaaaaaaaaaa} => 2,
+ {bbbbbbbbbbbbbbbbbbbb} => 3,{cccccccccccccccccccc} => 4,
+ {eeeeeeeeeeeeeeeeeeee} => 5},
+ "#{...}" = p(M2, 1),
+ weak("#{dddddddddddddddddddd => {...},...}", p(M2, 2)),
+ weak("#{dddddddddddddddddddd => {1},{...} => 2,...}", p(M2, 3)),
+
+ weak("#{dddddddddddddddddddd => {1},\n"
+ " {aaaaaaaaaaaaaaaaaaaa} => 2,\n"
+ " {...} => 3,...}", p(M2, 4)),
+
+ weak("#{dddddddddddddddddddd => {1},\n"
+ " {aaaaaaaaaaaaaaaaaaaa} => 2,\n"
+ " {bbbbbbbbbbbbbbbbbbbb} => 3,\n"
+ " {...} => 4,...}", p(M2, 5)),
+
+ weak("#{dddddddddddddddddddd => {1},\n"
+ " {aaaaaaaaaaaaaaaaaaaa} => 2,\n"
+ " {bbbbbbbbbbbbbbbbbbbb} => 3,\n"
+ " {cccccccccccccccccccc} => 4,\n"
+ " {...} => 5}", p(M2, 6)),
+
+ weak("#{dddddddddddddddddddd => {1},\n"
+ " {aaaaaaaaaaaaaaaaaaaa} => 2,\n"
+ " {bbbbbbbbbbbbbbbbbbbb} => 3,\n"
+ " {cccccccccccccccccccc} => 4,\n"
+ " {eeeeeeeeeeeeeeeeeeee} => 5}", p(M2, 7)),
+
+ M3 = #{kaaaaaaaaaaaaaaaaaaa => vuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,
+ kbbbbbbbbbbbbbbbbbbb => vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv,
+ kccccccccccccccccccc => vxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
+ kddddddddddddddddddd => vyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy,
+ keeeeeeeeeeeeeeeeeee => vzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz},
+
+ mt("#{aaaaaaaaaaaaaaaaaaaa =>\n"
+ " uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,\n"
+ " bbbbbbbbbbbbbbbbbbbb =>\n"
+ " vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv,\n"
+ " cccccccccccccccccccc =>\n"
+ " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,\n"
+ " dddddddddddddddddddd =>\n"
+ " yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy,\n"
+ " eeeeeeeeeeeeeeeeeeee =>\n"
+ " zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz}", p(M3, -1)),
+
+ R4 = {c,{c,{c,{c,{c,{c,{c,{c,{c,{c,{c,{c,a,b},b},b},b},b},b},
+ b},b},b},b},b},b},
+ M4 = #{aaaaaaaaaaaaaaaaaaaa => R4,
+ bbbbbbbbbbbbbbbbbbbb => R4,
+ cccccccccccccccccccc => R4,
+ dddddddddddddddddddd => R4,
+ eeeeeeeeeeeeeeeeeeee => R4},
+
+ weak("#{aaaaaaaaaaaaaaaaaaaa =>\n"
+ " #c{f1 = #c{f1 = #c{...},f2 = b},f2 = b},\n"
+ " bbbbbbbbbbbbbbbbbbbb => #c{f1 = #c{f1 = {...},...},f2 = b},\n"
+ " cccccccccccccccccccc => #c{f1 = #c{...},f2 = b},\n"
+ " dddddddddddddddddddd => #c{f1 = {...},...},\n"
+ " eeeeeeeeeeeeeeeeeeee => #c{...}}", p(M4, 7)),
+
+ M5 = #{aaaaaaaaaaaaaaaaaaaa => R4},
+ mt("#{aaaaaaaaaaaaaaaaaaaa =>\n"
+ " #c{\n"
+ " f1 =\n"
+ " #c{\n"
+ " f1 =\n"
+ " #c{\n"
+ " f1 =\n"
+ " #c{\n"
+ " f1 =\n"
+ " #c{\n"
+ " f1 =\n"
+ " #c{\n"
+ " f1 =\n"
+ " #c{\n"
+ " f1 =\n"
+ " #c{\n"
+ " f1 =\n"
+ " #c{\n"
+ " f1 = #c{f1 = #c{f1 = #c{f1 = a,f2 = b},f2 = b},"
+ "f2 = b},\n"
+ " f2 = b},\n"
+ " f2 = b},\n"
+ " f2 = b},\n"
+ " f2 = b},\n"
+ " f2 = b},\n"
+ " f2 = b},\n"
+ " f2 = b},\n"
+ " f2 = b},\n"
+ " f2 = b}}", p(M5, -1)),
+ ok.
+
+%% Just check number of newlines and dots ('...').
+-define(WEAK, true).
+
+-ifdef(WEAK).
+
+weak(S, R) ->
+ (nl(S) =:= nl(R) andalso
+ dots(S) =:= dots(S)).
+
+nl(S) ->
+ [C || C <- S, C =:= $\n].
+
+dots(S) ->
+ [C || C <- S, C =:= $\.].
+
+-else. % WEAK
+
+weak(S, R) ->
+ mt(S, R).
+
+-endif. % WEAK
+
+%% If EXACT is defined: mt() matches strings exactly.
+%%
+%% if EXACT is not defined: do not match the strings exactly, but
+%% compare them assuming that all map keys and all map values are
+%% equal (by assuming all map keys and all map values have the same
+%% length and begin with $k and $v respectively).
+
+%-define(EXACT, true).
+
+-ifdef(EXACT).
+
+mt(S, R) ->
+ S =:= R.
+
+-else. % EXACT
+
+mt(S, R) ->
+ anon(S) =:= anon(R).
+
+anon(S) ->
+ {ok, Ts0, _} = erl_scan:string(S, 1, [text]),
+ Ts = anon1(Ts0),
+ text(Ts).
+
+anon1([]) -> [];
+anon1([{atom,Anno,Atom}=T|Ts]) ->
+ case erl_anno:text(Anno) of
+ "k" ++ _ ->
+ NewAnno = erl_anno:set_text("key", Anno),
+ [{atom,NewAnno,Atom}|anon1(Ts)];
+ "v" ++ _ ->
+ NewAnno = erl_anno:set_text("val", Anno),
+ [{atom,NewAnno,Atom}|anon1(Ts)];
+ _ ->
+ [T|anon1(Ts)]
+ end;
+anon1([T|Ts]) ->
+ [T|anon1(Ts)].
+
+text(Ts) ->
+ lists:append(text1(Ts)).
+
+text1([]) -> [];
+text1([T|Ts]) ->
+ Anno = element(2, T),
+ [erl_anno:text(Anno) | text1(Ts)].
+
+-endif. % EXACT
+
+otp_14285(_Config) ->
+ UOpts = [{record_print_fun, fun rfd/2},
+ {encoding, unicode}],
+ LOpts = [{record_print_fun, fun rfd/2},
+ {encoding, latin1}],
+
+ RT = {'\x{400}','\x{400}'},
+ "#'\x{400}'{'\x{400}' = '\x{400}'}" = pretty(RT, UOpts),
+ "#'\\x{400}'{'\\x{400}' = '\\x{400}'}" = pretty(RT, LOpts),
+
+ Chars = lists:seq(0, 512),
+ [] = [C ||
+ C <- Chars,
+ S <- io_lib:write_atom_as_latin1(list_to_atom([C])),
+ not is_latin1(S)],
+ L1 = [S || C <- Chars, S <- io_lib:write_atom(list_to_atom([C])),
+ not is_latin1(S)],
+ L1 = lists:seq(256, 512),
+
+ latin1_fmt("~w", ['кирилли́ческий атом']),
+ latin1_fmt("~w", ['\x{10FFFF}']),
+ "'кирилли́ческий атом'" = fmt("~tw", ['кирилли́ческий атом']),
+ [$',16#10FFFF,$'] = fmt("~tw", ['\x{10FFFF}']),
+
+ latin1_fmt("~W", ['кирилли́ческий атом', 13]),
+ latin1_fmt("~W", ['\x{10FFFF}', 13]),
+ "'кирилли́ческий атом'" = fmt("~tW", ['кирилли́ческий атом', 13]),
+ [$',16#10FFFF,$'] = fmt("~tW", ['\x{10FFFF}', 13]),
+
+ {ok, [an_atom],[]} = io_lib:fread("~a", "an_atom"),
+ {ok, [an_atom],[]} = io_lib:fread("~ta", "an_atom"),
+ Str = "\"ab" ++ [1089] ++ "cd\"",
+ {ok, ["\"ab"], [1089]++"cd\""} = io_lib:fread("~s", Str),
+ {ok, ['\"ab'], [1089]++"cd\""} = io_lib:fread("~a", Str),
+ {ok,[Str], []} = io_lib:fread("~ts", Str),
+ {ok,[Atom],[]} = io_lib:fread("~ta", Str),
+ Str = atom_to_list(Atom),
+
+ ok.
+
+latin1_fmt(Fmt, Args) ->
+ L = fmt(Fmt, Args),
+ true = lists:all(fun is_latin1/1, L).
+
+limit_term(_Config) ->
+ {_, 2} = limt([a,b,c], 2),
+ {_, 2} = limt([a,b,c], 3),
+ {_, 2} = limt([a,b|c], 2),
+ {_, 2} = limt([a,b|c], 3),
+ {_, 2} = limt({a,b,c,[d,e]}, 2),
+ {_, 2} = limt({a,b,c,[d,e]}, 3),
+ {_, 2} = limt({a,b,c,[d,e]}, 4),
+ {_, 1} = limt(<<"foo">>, 18),
+ ok = blimt(<<"123456789012345678901234567890">>),
+ {_, 1} = limt(<<7:3>>, 2),
+ {_, 1} = limt(<<7:21>>, 2),
+ {_, 1} = limt([], 2),
+ {_, 1} = limt({}, 2),
+ {_, 1} = limt(#{}, 2),
+ {_, 1} = limt(#{[] => {}}, 2),
+ {_, 1} = limt(#{[] => {}}, 3),
+ T = #{[] => {},[a] => [b]},
+ {_, 1} = limt(T, 2),
+ {_, 1} = limt(T, 3),
+ {_, 1} = limt(T, 4),
+ ok.
+
+blimt(Binary) ->
+ blimt(Binary, byte_size(Binary)).
+
+blimt(_B, 1) -> ok;
+blimt(B, D) ->
+ {_, 1} = limt(B, D),
+ blimt(B, D - 1).
+
+limt(Term, Depth) when is_integer(Depth) ->
+ T1 = io_lib:limit_term(Term, Depth),
+ S = form(Term, Depth),
+ S1 = form(T1, Depth),
+ OK1 = S1 =:= S,
+
+ T2 = io_lib:limit_term(Term, Depth+1),
+ S2 = form(T2, Depth),
+ OK2 = S2 =:= S,
+
+ T3 = io_lib:limit_term(Term, Depth-1),
+ S3 = form(T3, Depth),
+ OK3 = S3 =/= S,
+
+ R = case {OK1, OK2, OK3} of
+ {true, true, true} -> 2;
+ {true, true, false} -> 1;
+ _ -> 0
+ end,
+ {{S, S1, S2}, R}.
+
+form(Term, Depth) ->
+ lists:flatten(io_lib:format("~W", [Term, Depth])).
diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl
index 1e286a9306..e497b2fb5d 100644
--- a/lib/stdlib/test/io_proto_SUITE.erl
+++ b/lib/stdlib/test/io_proto_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
%% %CopyrightEnd%
%%
-module(io_proto_SUITE).
--compile(r12).
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2]).
@@ -26,15 +25,14 @@
-export([init_per_testcase/2, end_per_testcase/2]).
-export([setopts_getopts/1,unicode_options/1,unicode_options_gen/1,
- binary_options/1, bc_with_r12/1,
- bc_with_r12_gl/1, read_modes_gl/1,bc_with_r12_ogl/1,
+ binary_options/1, read_modes_gl/1,
read_modes_ogl/1, broken_unicode/1,eof_on_pipe/1,unicode_prompt/1]).
-export([io_server_proxy/1,start_io_server_proxy/0, proxy_getall/1,
proxy_setnext/2, proxy_quit/1]).
%% For spawn
--export([toerl_server/3,hold_the_line/3,answering_machine1/3,
+-export([toerl_server/3,answering_machine1/3,
answering_machine2/3]).
-export([uprompt/1]).
@@ -79,8 +77,7 @@ suite() ->
all() ->
[setopts_getopts, unicode_options, unicode_options_gen,
- binary_options, bc_with_r12, bc_with_r12_gl,
- bc_with_r12_ogl, read_modes_gl, read_modes_ogl,
+ binary_options, read_modes_gl, read_modes_ogl,
broken_unicode, eof_on_pipe, unicode_prompt].
groups() ->
@@ -742,263 +739,7 @@ binary_options(Config) when is_list(Config) ->
],[],[],"-oldshell"),
ok.
-%% Test io protocol compatibility with R12 nodes.
-bc_with_r12(Config) when is_list(Config) ->
- case test_server:is_release_available("r12b") of
- true -> bc_with_r12_1(Config);
- false -> {skip,"No R12B found"}
- end.
-
-bc_with_r12_1(Config) ->
- PA = filename:dirname(code:which(?MODULE)),
- Name1 = io_proto_r12_1,
- N1 = list_to_atom(atom_to_list(Name1) ++ "@" ++ hostname()),
- test_server:start_node(Name1, peer, [{args, "-pz \""++PA++"\""},
- {erl,[{release,"r12b"}]}]),
- DataDir = proplists:get_value(data_dir,Config),
- FileName1 = filename:join([DataDir,"testdata_latin1.dat"]),
- TestDataLine1 = [229,228,246],
- TestDataLine2 = [197,196,214],
- SPid1 = rpc:call(N1,erlang,spawn,[?MODULE,hold_the_line,[self(),FileName1,[read]]]),
- {ok,F1} = receive
- {SPid1,Res1} ->
- Res1
- after 5000 ->
- exit(timeout)
- end,
- TestDataLine1 = chomp(io:get_line(F1,'')),
- SPid1 ! die,
- receive after 1000 -> ok end,
- SPid2 = rpc:call(N1,erlang,spawn,[?MODULE,hold_the_line,[self(),FileName1,[read,binary]]]),
- {ok,F2} = receive
- {SPid2,Res2} ->
- Res2
- after 5000 ->
- exit(timeout)
- end,
- TestDataLine1BinUtf = unicode:characters_to_binary(TestDataLine1),
- TestDataLine1BinLatin = list_to_binary(TestDataLine1),
- TestDataLine2BinUtf = unicode:characters_to_binary(TestDataLine2),
- TestDataLine2BinLatin = list_to_binary(TestDataLine2),
- TestDataLine1BinUtf = chomp(io:get_line(F2,'')),
- TestDataLine2BinUtf = chomp(io:get_line(F2,'')),
- %%io:format(standard_error,"Exec:~s\r\n",[rpc:call(N1,os,find_executable,["erl"])]),
- %%io:format(standard_error,"Io:~s\r\n",[rpc:call(N1,code,which,[io])]),
- %%io:format(standard_error,"File_io_server:~s\r\n",[rpc:call(N1,code,which,[file_io_server])]),
- file:position(F2,0),
- TestDataLine1BinLatin = chomp(rpc:call(N1,io,get_line,[F2,''])),
- TestDataLine2BinUtf = chomp(io:get_line(F2,'')),
- file:position(F2,0),
- TestDataLine1BinUtf = chomp(io:get_line(F2,'')),
- TestDataLine2BinLatin = chomp(rpc:call(N1,io,get_line,[F2,''])),
- eof = chomp(rpc:call(N1,io,get_line,[F2,''])),
- file:position(F2,0),
- TestDataLine1BinLatin = rpc:call(N1,io,get_chars,[F2,'',3]),
- io:get_chars(F2,'',1),
- TestDataLine2BinLatin = chomp(rpc:call(N1,io,get_line,[F2,''])),
- file:position(F2,0),
- {ok,[TestDataLine1]} = io:fread(F2,'',"~s"),
- {ok,[TestDataLine2]} = rpc:call(N1,io,fread,[F2,'',"~s"]),
-
- DataLen1 = length(TestDataLine1),
- DataLen2 = length(TestDataLine2),
- file:position(F2,0),
- {ok,TestDataLine1BinLatin} = file:read(F2,DataLen1),
- {ok,_} = file:read(F2,1),
- {ok,TestDataLine2BinLatin} = rpc:call(N1,file,read,[F2,DataLen2]),
- {ok,_} = file:read(F2,1),
- eof = rpc:call(N1,file,read,[F2,1]),
- %% As r12 has a bug when setting options with setopts, we need
- %% to reopen the file...
- SPid2 ! die,
- receive after 1000 -> ok end,
- SPid3 = rpc:call(N1,erlang,spawn,[?MODULE,hold_the_line,[self(),FileName1,[read]]]),
- {ok,F3} = receive
- {SPid3,Res3} ->
- Res3
- after 5000 ->
- exit(timeout)
- end,
-
- file:position(F3,0),
- {ok,[TestDataLine1]} = io:fread(F3,'',"~s"),
- {ok,[TestDataLine2]} = rpc:call(N1,io,fread,[F3,'',"~s"]),
-
-
- file:position(F3,0),
- {ok,TestDataLine1} = file:read(F3,DataLen1),
- {ok,_} = file:read(F3,1),
- {ok,TestDataLine2} = rpc:call(N1,file,read,[F3,DataLen2]),
- {ok,_} = file:read(F3,1),
- eof = rpc:call(N1,file,read,[F3,1]),
-
-
- %% So, lets do it all again, but the other way around
- {ok,F4} = file:open(FileName1,[read]),
- TestDataLine1 = chomp(io:get_line(F4,'')),
- file:position(F4,0),
- io:setopts(F4,[binary]),
- TestDataLine1BinUtf = chomp(io:get_line(F4,'')),
- TestDataLine2BinUtf = chomp(io:get_line(F4,'')),
- file:position(F4,0),
- TestDataLine1BinUtf = chomp(io:get_line(F4,'')),
- TestDataLine2BinUtf = chomp(io:get_line(F4,'')),
- file:position(F4,0),
- TestDataLine1BinUtf = chomp(io:get_line(F4,'')),
- TestDataLine2BinLatin = chomp(rpc:call(N1,io,get_line,[F4,''])),
- file:position(F4,0),
- TestDataLine1BinLatin = chomp(rpc:call(N1,io,get_line,[F4,''])),
- TestDataLine2BinUtf = chomp(io:get_line(F4,'')),
- eof = chomp(rpc:call(N1,io,get_line,[F4,''])),
- file:position(F4,0),
- TestDataLine1BinLatin = rpc:call(N1,io,get_chars,[F4,'',3]),
- io:get_chars(F4,'',1),
- TestDataLine2BinLatin = chomp(rpc:call(N1,io,get_line,[F4,''])),
- file:position(F4,0),
- {ok,[TestDataLine1]} = io:fread(F4,'',"~s"),
- {ok,[TestDataLine2]} = rpc:call(N1,io,fread,[F4,'',"~s"]),
- file:position(F4,0),
- {ok,TestDataLine1BinLatin} = file:read(F4,DataLen1),
- {ok,_} = file:read(F4,1),
- {ok,TestDataLine2BinLatin} = rpc:call(N1,file,read,[F4,DataLen2]),
- {ok,_} = file:read(F4,1),
- eof = rpc:call(N1,file,read,[F4,1]),
- io:setopts(F4,[list]),
-
- file:position(F4,0),
- {ok,[TestDataLine1]} = io:fread(F4,'',"~s"),
- {ok,[TestDataLine2]} = rpc:call(N1,io,fread,[F4,'',"~s"]),
-
-
- file:position(F4,0),
- {ok,TestDataLine1} = file:read(F4,DataLen1),
- {ok,_} = file:read(F4,1),
- {ok,TestDataLine2} = rpc:call(N1,file,read,[F4,DataLen2]),
- {ok,_} = file:read(F4,1),
- eof = rpc:call(N1,file,read,[F4,1]),
-
- file:close(F4),
- test_server:stop_node(N1),
- ok.
-
-hold_the_line(Parent,Filename,Options) ->
- Parent ! {self(), file:open(Filename,Options)},
- receive
- die ->
- ok
- end.
-
-
-%% Test io protocol compatibility with R12 nodes (terminals).
-bc_with_r12_gl(Config) when is_list(Config) ->
- case test_server:is_release_available("r12b") of
- true ->
- case get_progs() of
- {error,Reason} ->
- {skip, Reason};
- _ ->
- bc_with_r12_gl_1(Config,answering_machine1)
- end;
- false ->
- {skip,"No R12B found"}
- end.
-
-%% Test io protocol compatibility with R12 nodes (oldshell).
-bc_with_r12_ogl(Config) when is_list(Config) ->
- case test_server:is_release_available("r12b") of
- true ->
- case get_progs() of
- {error,Reason} ->
- {skip, Reason};
- _ ->
- bc_with_r12_gl_1(Config,answering_machine2)
- end;
- false ->
- {skip,"No R12B found"}
- end.
-
-bc_with_r12_gl_1(_Config,Machine) ->
- PA = filename:dirname(code:which(?MODULE)),
- Name1 = io_proto_r12_gl_1,
- N1 = list_to_atom(atom_to_list(Name1) ++ "@" ++ hostname()),
- test_server:start_node(Name1, peer, [{args, "-pz \""++PA++"\""},
- {erl,[{release,"r12b"}]}]),
- TestDataLine1 = [229,228,246],
- TestDataLine1BinUtf = unicode:characters_to_binary(TestDataLine1),
- TestDataLine1BinLatin = list_to_binary(TestDataLine1),
-
- {ok,N2List} = create_nodename(),
- MyNodeList = atom2list(node()),
- register(io_proto_suite,self()),
- AM1 = spawn(?MODULE,Machine,
- [MyNodeList, "io_proto_suite", N2List]),
-
- GL = receive X when is_pid(X) -> X end,
- %% get_line
- "Hej\n" = rpc:call(N1,io,get_line,[GL,"Prompt\n"]),
- io:setopts(GL,[binary]),
- io:format(GL,"Okej~n",[]),
- <<"Hej\n">> = rpc:call(N1,io,get_line,[GL,"Prompt\n"]),
- io:setopts(GL,[{encoding,latin1}]),
- io:format(GL,"Okej~n",[]),
- TestDataLine1BinLatin = chomp(rpc:call(N1,io,get_line,[GL,"Prompt\n"])),
- io:format(GL,"Okej~n",[]),
- TestDataLine1BinUtf = chomp(io:get_line(GL,"Prompt\n")),
- io:setopts(GL,[{encoding,unicode}]),
-
- io:format(GL,"Okej~n",[]),
- TestDataLine1BinLatin = chomp(rpc:call(N1,io,get_line,[GL,"Prompt\n"])),
- io:format(GL,"Okej~n",[]),
- TestDataLine1BinUtf = chomp(io:get_line(GL,"Prompt\n")),
- io:setopts(GL,[list]),
- io:format(GL,"Okej~n",[]),
-
- %%get_chars
- "Hej" = rpc:call(N1,io,get_chars,[GL,"Prompt\n",3]),
- io:setopts(GL,[binary]),
- io:format(GL,"Okej~n",[]),
- <<"Hej">> = rpc:call(N1,io,get_chars,[GL,"Prompt\n",3]),
- io:setopts(GL,[{encoding,latin1}]),
- io:format(GL,"Okej~n",[]),
- TestDataLine1BinLatin = rpc:call(N1,io,get_chars,[GL,"Prompt\n",3]),
- io:format(GL,"Okej~n",[]),
- TestDataLine1BinUtf = io:get_chars(GL,"Prompt\n",3),
- io:setopts(GL,[{encoding,unicode}]),
-
- io:format(GL,"Okej~n",[]),
- TestDataLine1BinLatin = rpc:call(N1,io,get_chars,[GL,"Prompt\n",3]),
- io:format(GL,"Okej~n",[]),
- TestDataLine1BinUtf = io:get_chars(GL,"Prompt\n",3),
- io:setopts(GL,[list]),
- io:format(GL,"Okej~n",[]),
- %%fread
- {ok,["Hej"]} = rpc:call(N1,io,fread,[GL,"Prompt\n","~s"]),
- io:setopts(GL,[binary]),
- io:format(GL,"Okej~n",[]),
- {ok,["Hej"]} = rpc:call(N1,io,fread,[GL,"Prompt\n","~s"]),
- io:setopts(GL,[{encoding,latin1}]),
- io:format(GL,"Okej~n",[]),
- {ok,[TestDataLine1]} = rpc:call(N1,io,fread,[GL,"Prompt\n","~s"]),
- io:format(GL,"Okej~n",[]),
- {ok,[TestDataLine1]} = io:fread(GL,"Prompt\n","~s"),
- io:setopts(GL,[{encoding,unicode}]),
- io:format(GL,"Okej~n",[]),
- {ok,[TestDataLine1]} = rpc:call(N1,io,fread,[GL,"Prompt\n","~s"]),
- io:format(GL,"Okej~n",[]),
- {ok,[TestDataLine1]} = io:fread(GL,"Prompt\n","~s"),
- io:setopts(GL,[list]),
- io:format(GL,"Okej~n",[]),
-
-
- receive
- {AM1,done} ->
- ok
- after 5000 ->
- exit(timeout)
- end,
- test_server:stop_node(N1),
- ok.
answering_machine1(OthNode,OthReg,Me) ->
@@ -1715,7 +1456,7 @@ toerl_loop(Port,Acc) ->
end.
millistamp() ->
- erlang:monotonic_time(milli_seconds).
+ erlang:monotonic_time(millisecond).
get_data_within(Port, X, Acc) when X =< 0 ->
?dbg({get_data_within, X, Acc, ?LINE}),
@@ -1900,13 +1641,6 @@ convert(Data, latin1, binary) ->
{error, {cannot_convert, unicode, latin1}}
end.
-hostname() ->
- from($@, atom_to_list(node())).
-
-from(H, [H | T]) -> T;
-from(H, [_ | T]) -> from(H, T);
-from(_, []) -> [].
-
atom2list(A) ->
lists:flatten(io_lib:format("~w", [A])).
diff --git a/lib/stdlib/test/lists_SUITE.erl b/lib/stdlib/test/lists_SUITE.erl
index 531e97e8d6..7c99244b36 100644
--- a/lib/stdlib/test/lists_SUITE.erl
+++ b/lib/stdlib/test/lists_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -121,7 +121,7 @@ groups() ->
{zip, [parallel], [zip_unzip, zip_unzip3, zipwith, zipwith3]},
{misc, [parallel], [reverse, member, dropwhile, takewhile,
filter_partition, suffix, subtract, join,
- hof]}
+ hof, droplast]}
].
init_per_suite(Config) ->
diff --git a/lib/stdlib/test/math_SUITE.erl b/lib/stdlib/test/math_SUITE.erl
new file mode 100644
index 0000000000..2b29e44228
--- /dev/null
+++ b/lib/stdlib/test/math_SUITE.erl
@@ -0,0 +1,92 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(math_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+
+%% Test server specific exports
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases
+-export([floor_ceil/1]).
+
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,1}}].
+
+all() ->
+ [floor_ceil].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_testcase(_Case, Config) ->
+ Config.
+
+end_per_testcase(_Case, _Config) ->
+ ok.
+
+floor_ceil(_Config) ->
+ MinusZero = 0.0/(-1.0),
+ -43.0 = do_floor_ceil(-42.1),
+ -43.0 = do_floor_ceil(-42.7),
+ 0.0 = do_floor_ceil(MinusZero),
+ 10.0 = do_floor_ceil(10.1),
+ 10.0 = do_floor_ceil(10.9),
+
+ -533.0 = do_floor_ceil(-533.0),
+ 453555.0 = do_floor_ceil(453555.0),
+
+ -58.0 = do_floor_ceil(-58),
+ 777.0 = do_floor_ceil(777),
+
+ ok.
+
+do_floor_ceil(Val) ->
+ Floor = math:floor(Val),
+ Ceil = math:ceil(Val),
+
+ true = is_float(Floor),
+ true = is_float(Ceil),
+
+ if
+ Floor =:= Ceil ->
+ Floor;
+ true ->
+ 1.0 = Ceil - Floor,
+ Floor
+ end.
diff --git a/lib/stdlib/test/ms_transform_SUITE.erl b/lib/stdlib/test/ms_transform_SUITE.erl
index 1c5faa960b..d1e6faf863 100644
--- a/lib/stdlib/test/ms_transform_SUITE.erl
+++ b/lib/stdlib/test/ms_transform_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@
-export([warnings/1]).
-export([no_warnings/1]).
-export([eep37/1]).
+-export([otp_14454/1]).
init_per_testcase(_Func, Config) ->
Config.
@@ -59,7 +60,7 @@ all() ->
record_index, multipass, bitsyntax, record_defaults,
andalso_orelse, float_1_function, action_function,
warnings, no_warnings, top_match, old_guards, autoimported,
- semicolon, eep37].
+ semicolon, eep37, otp_14454].
groups() ->
[].
@@ -296,6 +297,8 @@ basic_dbg(Config) when is_list(Config) ->
compile_and_run(<<"dbg:fun2ms(fun([A,B]) -> bindings() end)">>),
[{['$1','$2'],[],['$_']}] =
compile_and_run(<<"dbg:fun2ms(fun([A,B]) -> object() end)">>),
+ [{[],[],[{return_trace}]}] =
+ compile_and_run(<<"dbg:fun2ms(fun([]) -> return_trace() end)">>),
ok.
%% Test calling of ets/dbg:fun2ms from the shell.
@@ -769,6 +772,16 @@ eep37(Config) when is_list(Config) ->
"F()">>).
+otp_14454(Config) when is_list(Config) ->
+ setup(Config),
+ [{'$1',[],[{'band','$1',136}]}] =
+ compile_and_run(
+ <<"ets:fun2ms(fun(A) -> A band ( -(-17) bsl 3) end)">>),
+ [{'$1',[],[{'band','$1',136}]}] =
+ compile_and_run(
+ <<"ets:fun2ms(fun(A) -> A band ( erlang:'bsl'(-(-17), 3)) end)">>),
+ ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Helpers
diff --git a/lib/stdlib/test/proc_lib_SUITE.erl b/lib/stdlib/test/proc_lib_SUITE.erl
index 416650e27e..029e6286e4 100644
--- a/lib/stdlib/test/proc_lib_SUITE.erl
+++ b/lib/stdlib/test/proc_lib_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -26,8 +26,8 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
- crash/1, sync_start_nolink/1, sync_start_link/1,
- spawn_opt/1, sp1/0, sp2/0, sp3/1, sp4/2, sp5/1,
+ crash/1, stacktrace/1, sync_start_nolink/1, sync_start_link/1,
+ spawn_opt/1, sp1/0, sp2/0, sp3/1, sp4/2, sp5/1, '\x{447}'/0,
hibernate/1, stop/1, t_format/1]).
-export([ otp_6345/1, init_dont_hang/1]).
@@ -50,7 +50,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [crash, {group, sync_start}, spawn_opt, hibernate,
+ [crash, stacktrace, {group, sync_start}, spawn_opt, hibernate,
{group, tickets}, stop, t_format].
groups() ->
@@ -139,6 +139,14 @@ crash(Config) when is_list(Config) ->
{error_info,{exit,abnormal,{stacktrace}}}],
analyse_crash(Pid5, Exp5, []),
+ %% Unicode atom
+ Pid6 = proc_lib:spawn(?MODULE, '\x{447}', []),
+ Pid6 ! die,
+ Exp6 = [{initial_call,{?MODULE,'\x{447}',[]}},
+ {ancestors,[self()]},
+ {error_info,{exit,die,{stacktrace}}}],
+ analyse_crash(Pid6, Exp6, []),
+
error_logger:delete_report_handler(?MODULE),
ok.
@@ -198,6 +206,31 @@ match_info(Tuple1, Tuple2) when tuple_size(Tuple1) =:= tuple_size(Tuple2) ->
match_info(_, _) ->
throw(no_match).
+stacktrace(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ %% Errors.
+ Pid1 = proc_lib:spawn_link(fun() -> 1 = 2 end),
+ receive
+ {'EXIT',Pid1,{{badmatch,2},_Stack1}} -> ok
+ after 500 ->
+ ct:fail(error)
+ end,
+ %% Exits.
+ Pid2 = proc_lib:spawn_link(fun() -> exit(bye) end),
+ receive
+ {'EXIT',Pid2,bye} -> ok
+ after 500 ->
+ ct:fail(exit)
+ end,
+ %% Throws.
+ Pid3 = proc_lib:spawn_link(fun() -> throw(ball) end),
+ receive
+ {'EXIT',Pid3,{{nocatch,ball},_Stack3}} -> ok
+ after 500 ->
+ ct:fail(throw)
+ end,
+ ok.
+
sync_start_nolink(Config) when is_list(Config) ->
_Pid = spawn_link(?MODULE, sp5, [self()]),
receive
@@ -279,6 +312,12 @@ sp4(Parent, Tester) ->
end,
proc_lib:init_ack(Parent, self()).
+'\x{447}'() ->
+ receive
+ die -> exit(die);
+ _ -> sp1()
+ end.
+
hibernate(Config) when is_list(Config) ->
Ref = make_ref(),
Self = self(),
@@ -457,7 +496,7 @@ stop(_Config) ->
%% System message is handled, but process dies with other reason
%% than the given (in system_terminate/4 below)
Pid5 = proc_lib:spawn(SysMsgProc),
- {'EXIT',{badmatch,2}} = (catch proc_lib:stop(Pid5,crash,infinity)),
+ {'EXIT',{{badmatch,2},_Stacktrace}} = (catch proc_lib:stop(Pid5,crash,infinity)),
false = erlang:is_process_alive(Pid5),
%% Local registered name
diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl
index 2bd940020c..5e9e03e410 100644
--- a/lib/stdlib/test/qlc_SUITE.erl
+++ b/lib/stdlib/test/qlc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -58,7 +58,7 @@
-export([
badarg/1, nested_qlc/1, unused_var/1, lc/1, fun_clauses/1,
filter_var/1, single/1, exported_var/1, generator_vars/1,
- nomatch/1, errors/1, pattern/1,
+ nomatch/1, errors/1, pattern/1, overridden_bif/1,
eval/1, cursor/1, fold/1, eval_unique/1, eval_cache/1, append/1,
evaluator/1, string_to_handle/1, table/1, process_dies/1,
@@ -126,7 +126,7 @@ groups() ->
[{parse_transform, [],
[badarg, nested_qlc, unused_var, lc, fun_clauses,
filter_var, single, exported_var, generator_vars,
- nomatch, errors, pattern]},
+ nomatch, errors, pattern, overridden_bif]},
{evaluation, [],
[eval, cursor, fold, eval_unique, eval_cache, append,
evaluator, string_to_handle, table, process_dies, sort,
@@ -468,6 +468,23 @@ pattern(Config) when is_list(Config) ->
-record(k, {t,v}).\n">>, Ts),
ok.
+%% Override a guard BIF with an imported or local function.
+overridden_bif(Config) ->
+ Ts = [
+ <<"[2] = qlc:e(qlc:q([P || P <- [1,2,3], port(P)])),
+ [10] = qlc:e(qlc:q([P || P <- [0,9,10,11,12],
+ (is_reference(P) andalso P > 5)])),
+ Empty = gb_sets:empty(), Single = gb_sets:singleton(42),
+ GbSets = [Empty,Single],
+ [Single] = qlc:e(qlc:q([S || S <- GbSets, size(S) =/= 0]))
+ ">>
+ ],
+ run(Config, "-import(gb_sets, [size/1]).
+ -compile({no_auto_import, [size/1, is_reference/1]}).
+ port(N) -> N rem 2 =:= 0.
+ is_reference(N) -> N rem 10 =:= 0.\n", Ts),
+ ok.
+
%% eval/2
eval(Config) when is_list(Config) ->
@@ -869,11 +886,12 @@ eval_unique(Config) when is_list(Config) ->
[a] = qlc:e(Q2, {unique_all, true})
">>,
- <<"Q = qlc:q([SQV || SQV <- qlc:q([X || X <- [1,2,1]],unique)],
+ <<"Q = qlc:q([SQV || SQV <- qlc:q([X || X <- [1,2,1,#{a => 1}]],
+ unique)],
unique),
{call,_,_,[{lc,_,{var,_,'X'},[{generate,_,{var,_,'X'},_}]},_]} =
qlc:info(Q, [{format,abstract_code},unique_all]),
- [1,2] = qlc:e(Q)">>,
+ [1,2,#{a := 1}] = qlc:e(Q)">>,
<<"Q = qlc:q([X || X <- [1,2,1]]),
{call,_,_,[{lc,_,{var,_,'X'},[{generate,_,{var,_,'X'},_}]},_]} =
@@ -1222,6 +1240,17 @@ string_to_handle(Config) when is_list(Config) ->
{'EXIT', {no_lookup_to_carry_out, _}} =
(catch qlc:e(qlc:string_to_handle(Q, {lookup,true}, Bs2))),
ets:delete(Ets),
+
+ %% References can be scanned and parsed.
+ E2 = ets:new(test, [bag]),
+ Ref = make_ref(),
+ true = ets:insert(E2, [{Ref,Ref}]),
+ S2 = "[{Val1} || {Ref1, Val1} <- ets:table("++io_lib:write(E2)++"),"
+ "Ref1 =:= Ref].",
+ Bs = erl_eval:add_binding('Ref', Ref, erl_eval:new_bindings()),
+ [{Ref}] = qlc:e(qlc:string_to_handle(S2, [], Bs)),
+ ets:delete(E2),
+
ok.
%% table
@@ -2620,7 +2649,16 @@ info(Config) when is_list(Config) ->
{cons, _, _, _}]},
{nil,_}}]}]} = i(QH, {format, abstract_code}),
[{5},{6}] = qlc:e(QH),
- [{4},{5},{6}] = qlc:e(F(3))">>
+ [{4},{5},{6}] = qlc:e(F(3))">>,
+
+ <<"Fun = fun ?MODULE:i/2,
+ L = [{#{k => #{v => Fun}}, Fun}],
+ H = qlc:q([Q || Q <- L, Q =:= {#{k => #{v => Fun}}, Fun}]),
+ L = qlc:e(H),
+ {call,_,_,[{lc,_,{var,_,'Q'},
+ [{generate,_,_,_},
+ {op,_,_,_,_}]}]} =
+ qlc:info(H, [{format,abstract_code}])">>
],
run(Config, Ts),
@@ -4294,7 +4332,18 @@ ets(Config) when is_list(Config) ->
R = qlc:e(Q),
ets:delete(E),
[] = R">>]
- end
+ end,
+
+ <<"E2 = ets:new(test, [bag]),
+ Ref = make_ref(),
+ true = ets:insert(E2, [{Ref,Ref}]),
+ Q2 = qlc:q([{Val1} ||
+ {Ref1, Val1} <- ets:table(E2),
+ Ref1 =:= Ref]),
+ S = qlc:info(Q2),
+ true = is_list(S),
+ [{Ref}] = qlc:e(Q2),
+ ets:delete(E2)">>
],
@@ -7044,7 +7093,7 @@ otp_12946(Config) when is_list(Config) ->
%% Examples from qlc(3).
manpage(Config) when is_list(Config) ->
-
+ dets:start(),
ok = compile_gb_table(Config),
Ts = [
@@ -7111,11 +7160,14 @@ manpage(Config) when is_list(Config) ->
\" [{X,Z}|{W,Y}] <- V2\n\"
\" ])\n\"
\"end\",
- Info =
+ Info1 =
re:replace(qlc:info(Q),
- \"table\\\\(-*[0-9]*\",
+ \"table\\\\(#Ref<[\\.0-9]*>\",
\"table(_\", [{return,list},global]),
- L = Info,
+ F = fun(C) -> C =/= $\n andalso C =/= $\s end,
+ Info = lists:filter(F, Info1),
+ L1 = lists:filter(F, L),
+ L1 = Info,
ets:delete(E1),
ets:delete(E2)">>,
@@ -7418,10 +7470,10 @@ etsc(F, Opts, Objs) ->
V.
join_info(H) ->
- {qlc, S, Options} = strip_qlc_call(H),
+ {{qlc, S, Options}, Bs} = strip_qlc_call2(H),
%% "Hide" the call to qlc_pt from the test in run_test().
LoadedPT = code:is_loaded(qlc_pt),
- QH = qlc:string_to_handle(S, Options),
+ QH = qlc:string_to_handle(S, Options, Bs),
_ = [unload_pt() || false <- [LoadedPT]], % doesn't take long...
case {join_info_count(H), join_info_count(QH)} of
{N, N} ->
@@ -7431,30 +7483,34 @@ join_info(H) ->
end.
strip_qlc_call(H) ->
+ {Expr, _Bs} = strip_qlc_call2(H),
+ Expr.
+
+strip_qlc_call2(H) ->
S = qlc:info(H, {flat, false}),
- {ok, Tokens, _EndLine} = erl_scan:string(S++"."),
- {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
- case Expr of
- {call,_,{remote,_,{atom,_,qlc},{atom,_,q}},[LC]} ->
- {qlc, lists:flatten([erl_pp:expr(LC), "."]), []};
- {call,_,{remote,_,{atom,_,qlc},{atom,_,q}},[LC, Opts]} ->
- {qlc, lists:flatten([erl_pp:expr(LC), "."]),
- erl_parse:normalise(Opts)};
- {call,_,{remote,_,{atom,_,ets},{atom,_,match_spec_run}},_} ->
- {match_spec, Expr};
- {call,_,{remote,_,{atom,_,M},{atom,_,table}},_} ->
- {table, M, Expr};
- _ ->
- []
- end.
+ {ok, Tokens, _EndLine} = erl_scan:string(S++".", 1, [text]),
+ {ok, [Expr], Bs} = lib:extended_parse_exprs(Tokens),
+ {case Expr of
+ {call,_,{remote,_,{atom,_,qlc},{atom,_,q}},[LC]} ->
+ {qlc, lists:flatten([erl_pp:expr(LC), "."]), []};
+ {call,_,{remote,_,{atom,_,qlc},{atom,_,q}},[LC, Opts]} ->
+ {qlc, lists:flatten([erl_pp:expr(LC), "."]),
+ erl_parse:normalise(Opts)};
+ {call,_,{remote,_,{atom,_,ets},{atom,_,match_spec_run}},_} ->
+ {match_spec, Expr};
+ {call,_,{remote,_,{atom,_,M},{atom,_,table}},_} ->
+ {table, M, Expr};
+ _ ->
+ []
+ end, Bs}.
-record(ji, {nmerge = 0, nlookup = 0, nnested_loop = 0, nkeysort = 0}).
%% Counts join options and (all) calls to qlc:keysort().
join_info_count(H) ->
S = qlc:info(H, {flat, false}),
- {ok, Tokens, _EndLine} = erl_scan:string(S++"."),
- {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
+ {ok, Tokens, _EndLine} = erl_scan:string(S++".", 1, [text]),
+ {ok, [Expr], _Bs} = lib:extended_parse_exprs(Tokens),
#ji{nmerge = Nmerge, nlookup = Nlookup,
nkeysort = NKeysort, nnested_loop = Nnested_loop} =
ji(Expr, #ji{}),
@@ -7497,8 +7553,8 @@ lookup_keys({list,Q,_}, L) ->
lookup_keys({generate,_,Q}, L) ->
lookup_keys(Q, L);
lookup_keys({table,Chars}, L) when is_list(Chars) ->
- {ok, Tokens, _} = erl_scan:string(lists:flatten(Chars++".")),
- {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
+ {ok, Tokens, _} = erl_scan:string(lists:flatten(Chars++"."), 1, [text]),
+ {ok, [Expr], _Bs} = lib:extended_parse_exprs(Tokens),
case Expr of
{call,_,_,[_fun,AKs]} ->
case erl_parse:normalise(AKs) of
@@ -7815,7 +7871,7 @@ run_test(Config, Extra, {cres, Body, Opts, ExpectedCompileReturn}) ->
{module, _} = code:load_abs(AbsFile, Mod),
Ms0 = erlang:process_info(self(),messages),
- Before = {{get(), ets:all(), Ms0}, pps()},
+ Before = {{get(), lists:sort(ets:all()), Ms0}, pps()},
%% Prepare the check that the qlc module does not call qlc_pt.
_ = [unload_pt() || {file, Name} <- [code:is_loaded(qlc_pt)],
@@ -7847,7 +7903,7 @@ run_test(Config, Extra, Body) ->
wait_for_expected(R, {Strict0,PPS0}=Before, SourceFile, Wait) ->
Ms = erlang:process_info(self(),messages),
- After = {_,PPS1} = {{get(), ets:all(), Ms}, pps()},
+ After = {_,PPS1} = {{get(), lists:sort(ets:all()), Ms}, pps()},
case {R, After} of
{ok, Before} ->
ok;
@@ -7919,7 +7975,6 @@ compile(Config, Tests, Fun) ->
compile_file(Config, Test0, Opts0) ->
{File, Mod} = compile_file_mod(Config),
Test = list_to_binary(["-module(", atom_to_list(Mod), "). "
- "-compile(export_all). "
"-import(qlc_SUITE, [i/1,i/2,format_info/2]). "
"-import(qlc_SUITE, [etsc/2, etsc/3]). "
"-import(qlc_SUITE, [create_ets/2]). "
@@ -7929,7 +7984,7 @@ compile_file(Config, Test0, Opts0) ->
"-import(qlc_SUITE, [lookup_keys/1]). "
"-include_lib(\"stdlib/include/qlc.hrl\"). ",
Test0]),
- Opts = [export_all,return,nowarn_unused_record,{outdir,?privdir}|Opts0],
+ Opts = [export_all,nowarn_export_all,return,nowarn_unused_record,{outdir,?privdir}|Opts0],
ok = file:write_file(File, Test),
case compile:file(File, Opts) of
{ok, _M, Ws} -> warnings(File, Ws);
diff --git a/lib/stdlib/test/rand_SUITE.erl b/lib/stdlib/test/rand_SUITE.erl
index cb778c96d4..432293b656 100644
--- a/lib/stdlib/test/rand_SUITE.erl
+++ b/lib/stdlib/test/rand_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,13 +18,19 @@
%% %CopyrightEnd%
-module(rand_SUITE).
--export([all/0, suite/0,groups/0]).
+-compile({nowarn_deprecated_function,[{random,seed,1},
+ {random,uniform_s,1},
+ {random,uniform_s,2}]}).
+
+-export([all/0, suite/0, groups/0, group/1]).
-export([interval_int/1, interval_float/1, seed/1,
api_eq/1, reference/1,
basic_stats_uniform_1/1, basic_stats_uniform_2/1,
+ basic_stats_standard_normal/1,
basic_stats_normal/1,
- plugin/1, measure/1]).
+ plugin/1, measure/1,
+ reference_jump_state/1, reference_jump_procdict/1]).
-export([test/0, gen/1]).
@@ -41,27 +47,40 @@ all() ->
api_eq,
reference,
{group, basic_stats},
- plugin, measure].
+ plugin, measure,
+ {group, reference_jump}
+ ].
groups() ->
[{basic_stats, [parallel],
- [basic_stats_uniform_1, basic_stats_uniform_2, basic_stats_normal]}].
+ [basic_stats_uniform_1, basic_stats_uniform_2,
+ basic_stats_standard_normal]},
+ {reference_jump, [parallel],
+ [reference_jump_state, reference_jump_procdict]}].
+
+group(basic_stats) ->
+ %% valgrind needs a lot of time
+ [{timetrap,{minutes,10}}];
+group(reference_jump) ->
+ %% valgrind needs a lot of time
+ [{timetrap,{minutes,10}}].
%% A simple helper to test without test_server during dev
test() ->
Tests = all(),
- lists:foreach(fun(Test) ->
- try
- ok = ?MODULE:Test([]),
- io:format("~p: ok~n", [Test])
- catch _:Reason ->
- io:format("Failed: ~p: ~p ~p~n",
- [Test, Reason, erlang:get_stacktrace()])
- end
- end, Tests).
+ lists:foreach(
+ fun (Test) ->
+ try
+ ok = ?MODULE:Test([]),
+ io:format("~p: ok~n", [Test])
+ catch _:Reason ->
+ io:format("Failed: ~p: ~p ~p~n",
+ [Test, Reason, erlang:get_stacktrace()])
+ end
+ end, Tests).
algs() ->
- [exs64, exsplus, exs1024].
+ [exs64, exsplus, exsp, exrop, exs1024, exs1024s].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -210,17 +229,17 @@ interval_float_1(0) -> ok;
interval_float_1(N) ->
X = rand:uniform(),
if
- 0.0 < X, X < 1.0 ->
+ 0.0 =< X, X < 1.0 ->
ok;
true ->
- io:format("X=~p 0<~p<1.0~n", [X,X]),
+ io:format("X=~p 0=<~p<1.0~n", [X,X]),
exit({X, rand:export_seed()})
end,
interval_float_1(N-1).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Check if exs64 algorithm generates the proper sequence.
+%% Check if each algorithm generates the proper sequence.
reference(Config) when is_list(Config) ->
[reference_1(Alg) || Alg <- algs()],
ok.
@@ -230,33 +249,39 @@ reference_1(Alg) ->
Testval = gen(Alg),
case Refval =:= Testval of
true -> ok;
+ false when Refval =:= not_implemented ->
+ exit({not_implemented,Alg});
false ->
io:format("Failed: ~p~n",[Alg]),
io:format("Length ~p ~p~n",[length(Refval), length(Testval)]),
io:format("Head ~p ~p~n",[hd(Refval), hd(Testval)]),
- ok
+ exit(wrong_value)
end.
gen(Algo) ->
- Seed = case Algo of
- exsplus -> %% Printed with orig 'C' code and this seed
- rand:seed_s({exsplus, [12345678|12345678]});
- exs64 -> %% Printed with orig 'C' code and this seed
- rand:seed_s({exs64, 12345678});
- exs1024 -> %% Printed with orig 'C' code and this seed
- rand:seed_s({exs1024, {lists:duplicate(16, 12345678), []}});
- _ ->
- rand:seed(Algo, {100, 200, 300})
- end,
- gen(?LOOP, Seed, []).
+ State =
+ case Algo of
+ exs64 -> %% Printed with orig 'C' code and this seed
+ rand:seed_s({exs64, 12345678});
+ _ when Algo =:= exsplus; Algo =:= exsp; Algo =:= exrop ->
+ %% Printed with orig 'C' code and this seed
+ rand:seed_s({Algo, [12345678|12345678]});
+ _ when Algo =:= exs1024; Algo =:= exs1024s ->
+ %% Printed with orig 'C' code and this seed
+ rand:seed_s({Algo, {lists:duplicate(16, 12345678), []}});
+ _ ->
+ rand:seed(Algo, {100, 200, 300})
+ end,
+ Max = range(State),
+ gen(?LOOP, State, Max, []).
-gen(N, State0 = {#{max:=Max}, _}, Acc) when N > 0 ->
+gen(N, State0, Max, Acc) when N > 0 ->
{Random, State} = rand:uniform_s(Max, State0),
case N rem (?LOOP div 100) of
- 0 -> gen(N-1, State, [Random|Acc]);
- _ -> gen(N-1, State, Acc)
+ 0 -> gen(N-1, State, Max, [Random|Acc]);
+ _ -> gen(N-1, State, Max, Acc)
end;
-gen(_, _, Acc) -> lists:reverse(Acc).
+gen(_, _, _, Acc) -> lists:reverse(Acc).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This just tests the basics so we have not made any serious errors
@@ -267,23 +292,47 @@ gen(_, _, Acc) -> lists:reverse(Acc).
%% Check that the algorithms generate sound values.
basic_stats_uniform_1(Config) when is_list(Config) ->
- ct:timetrap({minutes,6}), %% valgrind needs a lot of time
+ ct:timetrap({minutes,15}), %% valgrind needs a lot of time
[basic_uniform_1(?LOOP, rand:seed_s(Alg), 0.0, array:new([{default, 0}]))
|| Alg <- algs()],
ok.
basic_stats_uniform_2(Config) when is_list(Config) ->
- ct:timetrap({minutes,6}), %% valgrind needs a lot of time
+ ct:timetrap({minutes,15}), %% valgrind needs a lot of time
[basic_uniform_2(?LOOP, rand:seed_s(Alg), 0, array:new([{default, 0}]))
|| Alg <- algs()],
ok.
-basic_stats_normal(Config) when is_list(Config) ->
+basic_stats_standard_normal(Config) when is_list(Config) ->
ct:timetrap({minutes,6}), %% valgrind needs a lot of time
- io:format("Testing normal~n",[]),
- [basic_normal_1(?LOOP, rand:seed_s(Alg), 0, 0) || Alg <- algs()],
+ io:format("Testing standard normal~n",[]),
+ IntendedMean = 0,
+ IntendedVariance = 1,
+ [basic_normal_1(?LOOP, IntendedMean, IntendedVariance,
+ rand:seed_s(Alg), 0, 0)
+ || Alg <- algs()],
ok.
+basic_stats_normal(Config) when is_list(Config) ->
+ IntendedMeans = [-1.0e6, -50, -math:pi(), -math:exp(-1),
+ 0.12345678, math:exp(1), 100, 1.0e6],
+ IntendedVariances = [1.0e-6, math:exp(-1), 1, math:pi(), 1.0e6],
+ IntendedMeanVariancePairs =
+ [{Mean, Variance} || Mean <- IntendedMeans,
+ Variance <- IntendedVariances],
+
+ ct:timetrap({minutes, 6 * length(IntendedMeanVariancePairs)}), %% valgrind needs a lot of time
+ lists:foreach(
+ fun ({IntendedMean, IntendedVariance}) ->
+ ct:pal(
+ "Testing normal(~.2f, ~.2f)~n",
+ [float(IntendedMean), float(IntendedVariance)]),
+ [basic_normal_1(?LOOP, IntendedMean, IntendedVariance,
+ rand:seed_s(Alg), 0, 0)
+ || Alg <- algs()]
+ end,
+ IntendedMeanVariancePairs).
+
basic_uniform_1(N, S0, Sum, A0) when N > 0 ->
{X,S} = rand:uniform_s(S0),
I = trunc(X*100),
@@ -291,11 +340,11 @@ basic_uniform_1(N, S0, Sum, A0) when N > 0 ->
basic_uniform_1(N-1, S, Sum+X, A);
basic_uniform_1(0, {#{type:=Alg}, _}, Sum, A) ->
AverN = Sum / ?LOOP,
- io:format("~.10w: Average: ~.4f~n", [Alg, AverN]),
+ io:format("~.12w: Average: ~.4f~n", [Alg, AverN]),
Counters = array:to_list(A),
Min = lists:min(Counters),
Max = lists:max(Counters),
- io:format("~.10w: Min: ~p Max: ~p~n", [Alg, Min, Max]),
+ io:format("~.12w: Min: ~p Max: ~p~n", [Alg, Min, Max]),
%% Verify that the basic statistics are ok
%% be gentle we don't want to see to many failing tests
@@ -310,11 +359,11 @@ basic_uniform_2(N, S0, Sum, A0) when N > 0 ->
basic_uniform_2(N-1, S, Sum+X, A);
basic_uniform_2(0, {#{type:=Alg}, _}, Sum, A) ->
AverN = Sum / ?LOOP,
- io:format("~.10w: Average: ~.4f~n", [Alg, AverN]),
+ io:format("~.12w: Average: ~.4f~n", [Alg, AverN]),
Counters = tl(array:to_list(A)),
Min = lists:min(Counters),
Max = lists:max(Counters),
- io:format("~.10w: Min: ~p Max: ~p~n", [Alg, Min, Max]),
+ io:format("~.12w: Min: ~p Max: ~p~n", [Alg, Min, Max]),
%% Verify that the basic statistics are ok
%% be gentle we don't want to see to many failing tests
@@ -323,107 +372,443 @@ basic_uniform_2(0, {#{type:=Alg}, _}, Sum, A) ->
abs(?LOOP div 100 - Max) < 1000 orelse ct:fail({max, Alg, Max}),
ok.
-basic_normal_1(N, S0, Sum, Sq) when N > 0 ->
- {X,S} = rand:normal_s(S0),
- basic_normal_1(N-1, S, X+Sum, X*X+Sq);
-basic_normal_1(0, {#{type:=Alg}, _}, Sum, SumSq) ->
- Mean = Sum / ?LOOP,
- StdDev = math:sqrt((SumSq - (Sum*Sum/?LOOP))/(?LOOP - 1)),
- io:format("~.10w: Average: ~7.4f StdDev ~6.4f~n", [Alg, Mean, StdDev]),
+basic_normal_1(N, IntendedMean, IntendedVariance, S0, StandardSum, StandardSq) when N > 0 ->
+ {X,S} = normal_s(IntendedMean, IntendedVariance, S0),
+ % We now shape X into a standard normal distribution (in case it wasn't already)
+ % in order to minimise the accumulated error on Sum / SumSq;
+ % otherwise said error would prevent us of making a fair judgment on
+ % the overall distribution when targeting large means and variances.
+ StandardX = (X - IntendedMean) / math:sqrt(IntendedVariance),
+ basic_normal_1(N-1, IntendedMean, IntendedVariance, S,
+ StandardX+StandardSum, StandardX*StandardX+StandardSq);
+basic_normal_1(0, _IntendedMean, _IntendedVariance, {#{type:=Alg}, _}, StandardSum, StandardSumSq) ->
+ StandardMean = StandardSum / ?LOOP,
+ StandardVariance = (StandardSumSq - (StandardSum*StandardSum/?LOOP))/(?LOOP - 1),
+ StandardStdDev = math:sqrt(StandardVariance),
+ io:format("~.12w: Standardised Average: ~7.4f, Standardised StdDev ~6.4f~n",
+ [Alg, StandardMean, StandardStdDev]),
%% Verify that the basic statistics are ok
%% be gentle we don't want to see to many failing tests
- abs(Mean) < 0.005 orelse ct:fail({average, Alg, Mean}),
- abs(StdDev - 1.0) < 0.005 orelse ct:fail({stddev, Alg, StdDev}),
+ abs(StandardMean) < 0.005 orelse ct:fail({average, Alg, StandardMean}),
+ abs(StandardStdDev - 1.0) < 0.005 orelse ct:fail({stddev, Alg, StandardStdDev}),
ok.
+normal_s(Mean, Variance, State0) when Mean == 0, Variance == 1 ->
+ % Make sure we're also testing the standard normal interface
+ rand:normal_s(State0);
+normal_s(Mean, Variance, State0) ->
+ rand:normal_s(Mean, Variance, State0).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Test that the user can write algorithms.
plugin(Config) when is_list(Config) ->
- _ = lists:foldl(fun(_, S0) ->
- {V1, S1} = rand:uniform_s(10000, S0),
- true = is_integer(V1),
- {V2, S2} = rand:uniform_s(S1),
- true = is_float(V2),
- S2
- end, crypto_seed(), lists:seq(1, 200)),
- ok.
+ try crypto:strong_rand_bytes(1) of
+ <<_>> ->
+ _ = lists:foldl(
+ fun(_, S0) ->
+ {V1, S1} = rand:uniform_s(10000, S0),
+ true = is_integer(V1),
+ {V2, S2} = rand:uniform_s(S1),
+ true = is_float(V2),
+ S2
+ end, crypto64_seed(), lists:seq(1, 200)),
+ ok
+ catch
+ error:low_entropy ->
+ {skip,low_entropy};
+ error:undef ->
+ {skip,no_crypto}
+ end.
%% Test implementation
-crypto_seed() ->
- {#{type=>crypto,
- max=>(1 bsl 64)-1,
- next=>fun crypto_next/1,
- uniform=>fun crypto_uniform/1,
- uniform_n=>fun crypto_uniform_n/2},
+crypto64_seed() ->
+ {#{type=>crypto64,
+ bits=>64,
+ next=>fun crypto64_next/1,
+ uniform=>fun crypto64_uniform/1,
+ uniform_n=>fun crypto64_uniform_n/2},
<<>>}.
%% Be fair and create bignums i.e. 64bits otherwise use 58bits
-crypto_next(<<Num:64, Bin/binary>>) ->
+crypto64_next(<<Num:64, Bin/binary>>) ->
{Num, Bin};
-crypto_next(_) ->
- crypto_next(crypto:strong_rand_bytes((64 div 8)*100)).
+crypto64_next(_) ->
+ crypto64_next(crypto:strong_rand_bytes((64 div 8)*100)).
-crypto_uniform({Api, Data0}) ->
- {Int, Data} = crypto_next(Data0),
+crypto64_uniform({Api, Data0}) ->
+ {Int, Data} = crypto64_next(Data0),
{Int / (1 bsl 64), {Api, Data}}.
-crypto_uniform_n(N, {Api, Data0}) when N < (1 bsl 64) ->
- {Int, Data} = crypto_next(Data0),
+crypto64_uniform_n(N, {Api, Data0}) when N < (1 bsl 64) ->
+ {Int, Data} = crypto64_next(Data0),
{(Int rem N)+1, {Api, Data}};
-crypto_uniform_n(N, State0) ->
- {F,State} = crypto_uniform(State0),
+crypto64_uniform_n(N, State0) ->
+ {F,State} = crypto64_uniform(State0),
{trunc(F * N) + 1, State}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Not a test but measures the time characteristics of the different algorithms
-measure(Suite) when is_atom(Suite) -> [];
-measure(_Config) ->
- ct:timetrap({minutes,6}), %% valgrind needs a lot of time
- Algos = [crypto64|algs()],
- io:format("RNG uniform integer performance~n",[]),
- _ = measure_1(random, fun(State) -> {int, random:uniform_s(10000, State)} end),
- _ = [measure_1(Algo, fun(State) -> {int, rand:uniform_s(10000, State)} end) || Algo <- Algos],
- io:format("RNG uniform float performance~n",[]),
- _ = measure_1(random, fun(State) -> {uniform, random:uniform_s(State)} end),
- _ = [measure_1(Algo, fun(State) -> {uniform, rand:uniform_s(State)} end) || Algo <- Algos],
- io:format("RNG normal float performance~n",[]),
- io:format("~.10w: not implemented (too few bits)~n", [random]),
- _ = [measure_1(Algo, fun(State) -> {normal, rand:normal_s(State)} end) || Algo <- Algos],
+measure(Config) ->
+ ct:timetrap({minutes,60}), %% valgrind needs a lot of time
+ case ct:get_timetrap_info() of
+ {_,{_,1}} -> % No scaling
+ do_measure(Config);
+ {_,{_,Scale}} ->
+ {skip,{will_not_run_in_scaled_time,Scale}}
+ end.
+
+do_measure(_Config) ->
+ Algos =
+ try crypto:strong_rand_bytes(1) of
+ <<_>> -> [crypto64, crypto]
+ catch
+ error:low_entropy -> [];
+ error:undef -> []
+ end ++ algs(),
+ %%
+ ct:pal("RNG uniform integer performance~n",[]),
+ TMark1 =
+ measure_1(
+ random,
+ fun (_) -> 10000 end,
+ undefined,
+ fun (Range, State) ->
+ {int, random:uniform_s(Range, State)}
+ end),
+ _ =
+ [measure_1(
+ Algo,
+ fun (_) -> 10000 end,
+ TMark1,
+ fun (Range, State) ->
+ {int, rand:uniform_s(Range, State)}
+ end) || Algo <- Algos],
+ %%
+ ct:pal("~nRNG uniform integer half range performance~n",[]),
+ HalfRangeFun = fun (State) -> half_range(State) end,
+ TMark2 =
+ measure_1(
+ random,
+ HalfRangeFun,
+ undefined,
+ fun (Range, State) ->
+ {int, random:uniform_s(Range, State)}
+ end),
+ _ =
+ [measure_1(
+ Algo,
+ HalfRangeFun,
+ TMark2,
+ fun (Range, State) ->
+ {int, rand:uniform_s(Range, State)}
+ end) || Algo <- Algos],
+ %%
+ ct:pal("~nRNG uniform integer half range + 1 performance~n",[]),
+ HalfRangePlus1Fun = fun (State) -> half_range(State) + 1 end,
+ TMark3 =
+ measure_1(
+ random,
+ HalfRangePlus1Fun,
+ undefined,
+ fun (Range, State) ->
+ {int, random:uniform_s(Range, State)}
+ end),
+ _ =
+ [measure_1(
+ Algo,
+ HalfRangePlus1Fun,
+ TMark3,
+ fun (Range, State) ->
+ {int, rand:uniform_s(Range, State)}
+ end) || Algo <- Algos],
+ %%
+ ct:pal("~nRNG uniform integer full range - 1 performance~n",[]),
+ FullRangeMinus1Fun = fun (State) -> (half_range(State) bsl 1) - 1 end,
+ TMark4 =
+ measure_1(
+ random,
+ FullRangeMinus1Fun,
+ undefined,
+ fun (Range, State) ->
+ {int, random:uniform_s(Range, State)}
+ end),
+ _ =
+ [measure_1(
+ Algo,
+ FullRangeMinus1Fun,
+ TMark4,
+ fun (Range, State) ->
+ {int, rand:uniform_s(Range, State)}
+ end) || Algo <- Algos],
+ %%
+ ct:pal("~nRNG uniform integer full range performance~n",[]),
+ FullRangeFun = fun (State) -> half_range(State) bsl 1 end,
+ TMark5 =
+ measure_1(
+ random,
+ FullRangeFun,
+ undefined,
+ fun (Range, State) ->
+ {int, random:uniform_s(Range, State)}
+ end),
+ _ =
+ [measure_1(
+ Algo,
+ FullRangeFun,
+ TMark5,
+ fun (Range, State) ->
+ {int, rand:uniform_s(Range, State)}
+ end) || Algo <- Algos],
+ %%
+ ct:pal("~nRNG uniform integer full range + 1 performance~n",[]),
+ FullRangePlus1Fun = fun (State) -> (half_range(State) bsl 1) + 1 end,
+ TMark6 =
+ measure_1(
+ random,
+ FullRangePlus1Fun,
+ undefined,
+ fun (Range, State) ->
+ {int, random:uniform_s(Range, State)}
+ end),
+ _ =
+ [measure_1(
+ Algo,
+ FullRangePlus1Fun,
+ TMark6,
+ fun (Range, State) ->
+ {int, rand:uniform_s(Range, State)}
+ end) || Algo <- Algos],
+ %%
+ ct:pal("~nRNG uniform integer double range performance~n",[]),
+ DoubleRangeFun = fun (State) -> half_range(State) bsl 2 end,
+ TMark7 =
+ measure_1(
+ random,
+ DoubleRangeFun,
+ undefined,
+ fun (Range, State) ->
+ {int, random:uniform_s(Range, State)}
+ end),
+ _ =
+ [measure_1(
+ Algo,
+ DoubleRangeFun,
+ TMark7,
+ fun (Range, State) ->
+ {int, rand:uniform_s(Range, State)}
+ end) || Algo <- Algos],
+ %%
+ ct:pal("~nRNG uniform integer double range + 1 performance~n",[]),
+ DoubleRangePlus1Fun = fun (State) -> (half_range(State) bsl 2) + 1 end,
+ TMark8 =
+ measure_1(
+ random,
+ DoubleRangePlus1Fun,
+ undefined,
+ fun (Range, State) ->
+ {int, random:uniform_s(Range, State)}
+ end),
+ _ =
+ [measure_1(
+ Algo,
+ DoubleRangePlus1Fun,
+ TMark8,
+ fun (Range, State) ->
+ {int, rand:uniform_s(Range, State)}
+ end) || Algo <- Algos],
+ %%
+ ct:pal("~nRNG uniform float performance~n",[]),
+ TMark9 =
+ measure_1(
+ random,
+ fun (_) -> 0 end,
+ undefined,
+ fun (_, State) ->
+ {uniform, random:uniform_s(State)}
+ end),
+ _ =
+ [measure_1(
+ Algo,
+ fun (_) -> 0 end,
+ TMark9,
+ fun (_, State) ->
+ {uniform, rand:uniform_s(State)}
+ end) || Algo <- Algos],
+ %%
+ ct:pal("~nRNG normal float performance~n",[]),
+ io:format("~.12w: not implemented (too few bits)~n", [random]),
+ _ = [measure_1(
+ Algo,
+ fun (_) -> 0 end,
+ TMark9,
+ fun (_, State) ->
+ {normal, rand:normal_s(State)}
+ end) || Algo <- Algos],
ok.
-measure_1(Algo, Gen) ->
+measure_1(Algo, RangeFun, TMark, Gen) ->
Parent = self(),
- Seed = fun(crypto64) -> crypto_seed();
- (random) -> random:seed(os:timestamp()), get(random_seed);
- (Alg) -> rand:seed_s(Alg)
- end,
-
- Pid = spawn_link(fun() ->
- Fun = fun() -> measure_2(?LOOP, Seed(Algo), Gen) end,
- {Time, ok} = timer:tc(Fun),
- io:format("~.10w: ~pµs~n", [Algo, Time]),
- Parent ! {self(), ok},
- normal
- end),
+ Seed =
+ case Algo of
+ crypto64 ->
+ crypto64_seed();
+ crypto ->
+ crypto:rand_seed_s();
+ random ->
+ random:seed(os:timestamp()), get(random_seed);
+ _ ->
+ rand:seed_s(Algo)
+ end,
+ Range = RangeFun(Seed),
+ Pid = spawn_link(
+ fun() ->
+ Fun = fun() -> measure_2(?LOOP, Range, Seed, Gen) end,
+ {Time, ok} = timer:tc(Fun),
+ Percent =
+ case TMark of
+ undefined -> 100;
+ _ -> (Time * 100 + 50) div TMark
+ end,
+ io:format(
+ "~.12w: ~p ns ~p% [16#~.16b]~n",
+ [Algo, (Time * 1000 + 500) div ?LOOP, Percent, Range]),
+ Parent ! {self(), Time},
+ normal
+ end),
receive
{Pid, Msg} -> Msg
end.
-measure_2(N, State0, Fun) when N > 0 ->
- case Fun(State0) of
+measure_2(N, Range, State0, Fun) when N > 0 ->
+ case Fun(Range, State0) of
{int, {Random, State}}
- when is_integer(Random), Random >= 1, Random =< 100000 ->
- measure_2(N-1, State, Fun);
- {uniform, {Random, State}} when is_float(Random), Random > 0, Random < 1 ->
- measure_2(N-1, State, Fun);
+ when is_integer(Random), Random >= 1, Random =< Range ->
+ measure_2(N-1, Range, State, Fun);
+ {uniform, {Random, State}}
+ when is_float(Random), 0.0 =< Random, Random < 1.0 ->
+ measure_2(N-1, Range, State, Fun);
{normal, {Random, State}} when is_float(Random) ->
- measure_2(N-1, State, Fun);
+ measure_2(N-1, Range, State, Fun);
Res ->
exit({error, Res, State0})
end;
-measure_2(0, _, _) -> ok.
+measure_2(0, _, _, _) -> ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% The jump sequence tests has two parts
+%% for those with the functional API (jump/1)
+%% and for those with the internal state
+%% in process dictionary (jump/0).
+
+-define(LOOP_JUMP, (?LOOP div 1000)).
+
+%% Check if each algorithm generates the proper jump sequence
+%% with the functional API.
+reference_jump_state(Config) when is_list(Config) ->
+ [reference_jump_1(Alg) || Alg <- algs()],
+ ok.
+
+reference_jump_1(Alg) ->
+ Refval = reference_jump_val(Alg),
+ Testval = gen_jump_1(Alg),
+ case Refval =:= Testval of
+ true -> ok;
+ false ->
+ io:format("Failed: ~p~n",[Alg]),
+ io:format("Length ~p ~p~n",[length(Refval), length(Testval)]),
+ io:format("Head ~p ~p~n",[hd(Refval), hd(Testval)]),
+ io:format("Vals ~p ~p~n",[Refval, Testval]),
+ exit(wrong_value)
+ end.
+
+gen_jump_1(Algo) ->
+ State =
+ case Algo of
+ exs64 -> %% Test exception of not_implemented notice
+ try rand:jump(rand:seed_s(exs64))
+ catch
+ error:not_implemented -> not_implemented
+ end;
+ _ when Algo =:= exsplus; Algo =:= exsp; Algo =:= exrop ->
+ %% Printed with orig 'C' code and this seed
+ rand:seed_s({Algo, [12345678|12345678]});
+ _ when Algo =:= exs1024; Algo =:= exs1024s ->
+ %% Printed with orig 'C' code and this seed
+ rand:seed_s({Algo, {lists:duplicate(16, 12345678), []}});
+ _ -> % unimplemented
+ not_implemented
+ end,
+ case State of
+ not_implemented -> [not_implemented];
+ _ ->
+ Max = range(State),
+ gen_jump_1(?LOOP_JUMP, State, Max, [])
+ end.
+
+gen_jump_1(N, State0, Max, Acc) when N > 0 ->
+ {_, State1} = rand:uniform_s(Max, State0),
+ {Random, State2} = rand:uniform_s(Max, rand:jump(State1)),
+ case N rem (?LOOP_JUMP div 100) of
+ 0 -> gen_jump_1(N-1, State2, Max, [Random|Acc]);
+ _ -> gen_jump_1(N-1, State2, Max, Acc)
+ end;
+gen_jump_1(_, _, _, Acc) -> lists:reverse(Acc).
+
+
+%% Check if each algorithm generates the proper jump sequence
+%% with the internal state in the process dictionary.
+reference_jump_procdict(Config) when is_list(Config) ->
+ [reference_jump_0(Alg) || Alg <- algs()],
+ ok.
+
+reference_jump_0(Alg) ->
+ Refval = reference_jump_val(Alg),
+ Testval = gen_jump_0(Alg),
+ case Refval =:= Testval of
+ true -> ok;
+ false ->
+ io:format("Failed: ~p~n",[Alg]),
+ io:format("Length ~p ~p~n",[length(Refval), length(Testval)]),
+ io:format("Head ~p ~p~n",[hd(Refval), hd(Testval)]),
+ exit(wrong_value)
+ end.
+
+gen_jump_0(Algo) ->
+ Seed = case Algo of
+ exs64 -> %% Test exception of not_implemented notice
+ try
+ _ = rand:seed(exs64),
+ rand:jump()
+ catch
+ error:not_implemented -> not_implemented
+ end;
+ _ when Algo =:= exsplus; Algo =:= exsp; Algo =:= exrop ->
+ %% Printed with orig 'C' code and this seed
+ rand:seed({Algo, [12345678|12345678]});
+ _ when Algo =:= exs1024; Algo =:= exs1024s ->
+ %% Printed with orig 'C' code and this seed
+ rand:seed({Algo, {lists:duplicate(16, 12345678), []}});
+ _ -> % unimplemented
+ not_implemented
+ end,
+ case Seed of
+ not_implemented -> [not_implemented];
+ _ ->
+ Max = range(Seed),
+ gen_jump_0(?LOOP_JUMP, Max, [])
+ end.
+
+gen_jump_0(N, Max, Acc) when N > 0 ->
+ _ = rand:uniform(Max),
+ _ = rand:jump(),
+ Random = rand:uniform(Max),
+ case N rem (?LOOP_JUMP div 100) of
+ 0 -> gen_jump_0(N-1, Max, [Random|Acc]);
+ _ -> gen_jump_0(N-1, Max, Acc)
+ end;
+gen_jump_0(_, _, Acc) -> lists:reverse(Acc).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Data
@@ -506,4 +891,219 @@ reference_val(exsplus) ->
16#6c6145ffa1169d,16#18ec2c393d45359,16#1f1a5f256e7130c,16#131cc2f49b8004f,
16#36f715a249f4ec2,16#1c27629826c50d3,16#914d9a6648726a,16#27f5bf5ce2301e8,
16#3dd493b8012970f,16#be13bed1e00e5c,16#ceef033b74ae10,16#3da38c6a50abe03,
- 16#15cbd1a421c7a8c,16#22794e3ec6ef3b1,16#26154d26e7ea99f,16#3a66681359a6ab6].
+ 16#15cbd1a421c7a8c,16#22794e3ec6ef3b1,16#26154d26e7ea99f,16#3a66681359a6ab6];
+
+reference_val(exsp) ->
+ reference_val(exsplus);
+reference_val(exs1024s) ->
+ reference_val(exs1024);
+reference_val(exrop) ->
+%% #include <stdint.h>
+%% #include <stdio.h>
+%%
+%% uint64_t s[2];
+%% uint64_t next(void);
+%% /* Xoroshiro116+ PRNG here */
+%%
+%% int main(char *argv[]) {
+%% int n;
+%% uint64_t r;
+%% s[0] = 12345678;
+%% s[1] = 12345678;
+%%
+%% for (n = 1000000; n > 0; n--) {
+%% r = next();
+%% if ((n % 10000) == 0) {
+%% printf("%llu,", (unsigned long long) (r + 1));
+%% }
+%% }
+%% printf("\n");
+%% }
+ [24691357,29089185972758626,135434857127264790,
+ 277209758236304485,101045429972817342,
+ 241950202080388093,283018380268425711,268233672110762489,
+ 173241488791227202,245038518481669421,
+ 253627577363613736,234979870724373477,115607127954560275,
+ 96445882796968228,166106849348423677,
+ 83614184550774836,109634510785746957,68415533259662436,
+ 12078288820568786,246413981014863011,
+ 96953486962147513,138629231038332640,206078430370986460,
+ 11002780552565714,238837272913629203,
+ 60272901610411077,148828243883348685,203140738399788939,
+ 131001610760610046,30717739120305678,
+ 262903815608472425,31891125663924935,107252017522511256,
+ 241577109487224033,263801934853180827,
+ 155517416581881714,223609336630639997,112175917931581716,
+ 16523497284706825,201453767973653420,
+ 35912153101632769,211525452750005043,96678037860996922,
+ 70962216125870068,107383886372877124,
+ 223441708670831233,247351119445661499,233235283318278995,
+ 280646255087307741,232948506631162445,
+ %%
+ 117394974124526779,55395923845250321,274512622756597759,
+ 31754154862553492,222645458401498438,
+ 161643932692872858,11771755227312868,93933211280589745,
+ 92242631276348831,197206910466548143,
+ 150370169849735808,229903773212075765,264650708561842793,
+ 30318996509793571,158249985447105184,
+ 220423733894955738,62892844479829080,112941952955911674,
+ 203157000073363030,54175707830615686,
+ 50121351829191185,115891831802446962,62298417197154985,
+ 6569598473421167,69822368618978464,
+ 176271134892968134,160793729023716344,271997399244980560,
+ 59100661824817999,150500611720118722,
+ 23707133151561128,25156834940231911,257788052162304719,
+ 176517852966055005,247173855600850875,
+ 83440973524473396,94711136045581604,154881198769946042,
+ 236537934330658377,152283781345006019,
+ 250789092615679985,78848633178610658,72059442721196128,
+ 98223942961505519,191144652663779840,
+ 102425686803727694,89058927716079076,80721467542933080,
+ 8462479817391645,2774921106204163].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+reference_jump_val(exsplus) ->
+ [82445318862816932, 145810727464480743, 16514517716894509, 247642377064868650,
+ 162385642339156908, 251810707075252101, 82288275771998924, 234412731596926322,
+ 49960883129071044, 200690077681656596, 213743196668671647, 131182800982967108,
+ 144200072021941728, 263557425008503277, 194858522616874272, 185869394820993172,
+ 80384502675241453, 262654144824057588, 90033295011291362, 4494510449302659,
+ 226005372746479588, 116780561309220553, 47048528594475843, 39168929349768743,
+ 139615163424415552, 55330632656603925, 237575574720486569, 102381140288455025,
+ 18452933910354323, 150248612130579752, 269358096791922740, 61313433522002187,
+ 160327361842676597, 185187983548528938, 57378981505594193, 167510799293984067,
+ 105117045862954303, 176126685946302943, 123590876906828803, 69185336947273487,
+ 9098689247665808, 49906154674145057, 131575138412788650, 161843880211677185,
+ 30743946051071186, 187578920583823612, 45008401528636978, 122454158686456658,
+ 111195992644229524, 17962783958752862, 13579507636941108, 130137843317798663,
+ 144202635170576832, 132539563255093922, 159785575703967124, 187241848364816640,
+ 183044737781926478, 12921559769912263, 83553932242922001, 96698298841984688,
+ 281664320227537824, 224233030818578263, 77812932110318774, 169729351013291728,
+ 164475402723178734, 242780633011249051, 51095111179609125, 19249189591963554,
+ 221412426221439180, 265700202856282653, 265342254311932308, 241218503498385511,
+ 255400887248486575, 212083616929812076, 227947034485840579, 268261881651571692,
+ 104846262373404908, 49690734329496661, 213259196633566308, 186966479726202436,
+ 282157378232384574, 11272948584603747, 166540426999573480, 50628164001018755,
+ 65235580992800860, 230664399047956956, 64575592354687978, 40519393736078511,
+ 108341851194332747, 115426411532008961, 120656817002338193, 234537867870809797,
+ 12504080415362731, 45083100453836317, 270968267812126657, 93505647407734103,
+ 252852934678537969, 258758309277167202, 74250882143432077, 141629095984552833];
+
+reference_jump_val(exs1024) ->
+ [2655961906500790629, 17003395417078685063, 10466831598958356428, 7603399148503548021,
+ 1650550950190587188, 12294992315080723704, 15743995773860389219, 5492181000145247327,
+ 14118165228742583601, 1024386975263610703, 10124872895886669513, 6445624517813169301,
+ 6238575554686562601, 14108646153524288915, 11804141635807832816, 8421575378006186238,
+ 6354993374304550369, 838493020029548163, 14759355804308819469, 12212491527912522022,
+ 16943204735100571602, 198964074252287588, 7325922870779721649, 15853102065526570574,
+ 16294058349151823341, 6153379962047409781, 15874031679495957261, 17299265255608442340,
+ 984658421210027171, 17408042033939375278, 3326465916992232353, 5222817718770538733,
+ 13262385796795170510, 15648751121811336061, 6718721549566546451, 7353765235619801875,
+ 16110995049882478788, 14559143407227563441, 4189805181268804683, 10938587948346538224,
+ 1635025506014383478, 12619562911869525411, 17469465615861488695, 125252234176411528,
+ 2004192558503448853, 13175467866790974840, 17712272336167363518, 1710549840100880318,
+ 17486892343528340916, 5337910082227550967, 8333082060923612691, 6284787745504163856,
+ 8072221024586708290, 6077032673910717705, 11495200863352251610, 11722792537523099594,
+ 14642059504258647996, 8595733246938141113, 17223366528010341891, 17447739753327015776,
+ 6149800490736735996, 11155866914574313276, 7123864553063709909, 15982886296520662323,
+ 5775920250955521517, 8624640108274906072, 8652974210855988961, 8715770416136907275,
+ 11841689528820039868, 10991309078149220415, 11758038663970841716, 7308750055935299261,
+ 15939068400245256963, 6920341533033919644, 8017706063646646166, 15814376391419160498,
+ 13529376573221932937, 16749061963269842448, 14639730709921425830, 3265850480169354066,
+ 4569394597532719321, 16594515239012200038, 13372824240764466517, 16892840440503406128,
+ 11260004846380394643, 2441660009097834955, 10566922722880085440, 11463315545387550692,
+ 5252492021914937692, 10404636333478845345, 11109538423683960387, 5525267334484537655,
+ 17936751184378118743, 4224632875737239207, 15888641556987476199, 9586888813112229805,
+ 9476861567287505094, 14909536929239540332, 17996844556292992842, 2699310519182298856];
+
+reference_jump_val(exsp) ->
+ reference_jump_val(exsplus);
+reference_jump_val(exs1024s) ->
+ reference_jump_val(exs1024);
+reference_jump_val(exs64) -> [not_implemented];
+reference_jump_val(exrop) ->
+%% #include <stdint.h>
+%% #include <stdio.h>
+%%
+%% uint64_t s[2];
+%% uint64_t next(void);
+%% /* Xoroshiro116+ PRNG here */
+%%
+%% int main(char *argv[]) {
+%% int n;
+%% uint64_t r;
+%% s[0] = 12345678;
+%% s[1] = 12345678;
+
+%% for (n = 1000; n > 0; n--) {
+%% next();
+%% jump();
+%% r = next();
+%% if ((n % 10) == 0) {
+%% printf("%llu,", (unsigned long long) (r + 1));
+%% }
+%% }
+%% printf("\n");
+%% }
+ [60301713907476001,135397949584721850,4148159712710727,
+ 110297784509908316,18753463199438866,
+ 106699913259182846,2414728156662676,237591345910610406,
+ 48519427605486503,38071665570452612,
+ 235484041375354592,45428997361037927,112352324717959775,
+ 226084403445232507,270797890380258829,
+ 160587966336947922,80453153271416820,222758573634013699,
+ 195715386237881435,240975253876429810,
+ 93387593470886224,23845439014202236,235376123357642262,
+ 22286175195310374,239068556844083490,
+ 120126027410954482,250690865061862527,113265144383673111,
+ 57986825640269127,206087920253971490,
+ 265971029949338955,40654558754415167,185972161822891882,
+ 72224917962819036,116613804322063968,
+ 129103518989198416,236110607653724474,98446977363728314,
+ 122264213760984600,55635665885245081,
+ 42625530794327559,288031254029912894,81654312180555835,
+ 261800844953573559,144734008151358432,
+ 77095621402920587,286730580569820386,274596992060316466,
+ 97977034409404188,5517946553518132,
+ %%
+ 56460292644964432,252118572460428657,38694442746260303,
+ 165653145330192194,136968555571402812,
+ 64905200201714082,257386366768713186,22702362175273017,
+ 208480936480037395,152926769756967697,
+ 256751159334239189,130982960476845557,21613531985982870,
+ 87016962652282927,130446710536726404,
+ 188769410109327420,282891129440391928,251807515151187951,
+ 262029034126352975,30694713572208714,
+ 46430187445005589,176983177204884508,144190360369444480,
+ 14245137612606100,126045457407279122,
+ 169277107135012393,42599413368851184,130940158341360014,
+ 113412693367677211,119353175256553456,
+ 96339829771832349,17378172025472134,110141940813943768,
+ 253735613682893347,234964721082540068,
+ 85668779779185140,164542570671430062,18205512302089755,
+ 282380693509970845,190996054681051049,
+ 250227633882474729,171181147785250210,55437891969696407,
+ 241227318715885854,77323084015890802,
+ 1663590009695191,234064400749487599,222983191707424780,
+ 254956809144783896,203898972156838252].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% The old algorithms used a range 2^N - 1 for their reference val
+%% tests, which was incorrect but works as long as you do not draw
+%% the value 2^N, which is very unlikely. It was not possible
+%% to simply correct the range to 2^N due to another incorrectness
+%% in that the old algorithms changed to using the broken
+%% (multiply a float approach with too few bits) approach for
+%% ranges >= 2^N. This function digs out the range to use
+%% for the reference tests for old and new algorithms.
+range({#{bits:=Bits}, _}) -> 1 bsl Bits;
+range({#{max:=Max}, _}) -> Max; %% Old incorrect range
+range({_, _, _}) -> 51. % random
+
+
+half_range({#{bits:=Bits}, _}) -> 1 bsl (Bits - 1);
+half_range({#{max:=Max}, _}) -> (Max bsr 1) + 1;
+half_range({#{}, _}) -> 1 bsl 63; % crypto
+half_range({_, _, _}) -> 1 bsl 50. % random
diff --git a/lib/stdlib/test/random_iolist.erl b/lib/stdlib/test/random_iolist.erl
index 555f063e0a..6621c7ac77 100644
--- a/lib/stdlib/test/random_iolist.erl
+++ b/lib/stdlib/test/random_iolist.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,17 +24,13 @@
-module(random_iolist).
--export([run/3, run2/3, standard_seed/0, compare/3, compare2/3,
+-export([run/3, standard_seed/0, compare/3,
random_iolist/1]).
run(Iter,Fun1,Fun2) ->
standard_seed(),
compare(Iter,Fun1,Fun2).
-run2(Iter,Fun1,Fun2) ->
- standard_seed(),
- compare2(Iter,Fun1,Fun2).
-
random_byte() ->
rand:uniform(256) - 1.
@@ -150,16 +146,6 @@ do_comp(List,F1,F2) ->
_ ->
true
end.
-
-do_comp(List,List2,F1,F2) ->
- X = F1(List,List2),
- Y = F2(List,List2),
- case X =:= Y of
- false ->
- exit({not_matching,List,List2,X,Y});
- _ ->
- true
- end.
compare(0,Fun1,Fun2) ->
do_comp(<<>>,Fun1,Fun2),
@@ -172,25 +158,3 @@ compare(N,Fun1,Fun2) ->
L = random_iolist(N),
do_comp(L,Fun1,Fun2),
compare(N-1,Fun1,Fun2).
-
-compare2(0,Fun1,Fun2) ->
- L = random_iolist(100),
- do_comp(<<>>,L,Fun1,Fun2),
- do_comp(L,<<>>,Fun1,Fun2),
- do_comp(<<>>,<<>>,Fun1,Fun2),
- do_comp([],L,Fun1,Fun2),
- do_comp(L,[],Fun1,Fun2),
- do_comp([],[],Fun1,Fun2),
- do_comp([[]|<<>>],L,Fun1,Fun2),
- do_comp(L,[[]|<<>>],Fun1,Fun2),
- do_comp([[]|<<>>],[[]|<<>>],Fun1,Fun2),
- do_comp([<<>>,[]|<<>>],L,Fun1,Fun2),
- do_comp(L,[<<>>,[]|<<>>],Fun1,Fun2),
- do_comp([<<>>,[]|<<>>],[<<>>,[]|<<>>],Fun1,Fun2),
- true;
-
-compare2(N,Fun1,Fun2) ->
- L = random_iolist(N),
- L2 = random_iolist(N),
- do_comp(L,L2,Fun1,Fun2),
- compare2(N-1,Fun1,Fun2).
diff --git a/lib/stdlib/test/random_unicode_list.erl b/lib/stdlib/test/random_unicode_list.erl
index 8db2fa8b56..af3d44af75 100644
--- a/lib/stdlib/test/random_unicode_list.erl
+++ b/lib/stdlib/test/random_unicode_list.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
-module(random_unicode_list).
--export([run/3, run/4, run2/3, standard_seed/0, compare/4, compare2/3,
+-export([run/3, run/4, standard_seed/0, compare/4,
random_unicode_list/2]).
run(I,F1,F2) ->
@@ -33,10 +33,6 @@ run(Iter,Fun1,Fun2,Enc) ->
standard_seed(),
compare(Iter,Fun1,Fun2,Enc).
-run2(Iter,Fun1,Fun2) ->
- standard_seed(),
- compare2(Iter,Fun1,Fun2).
-
int_to_utf8(I) when I =< 16#7F ->
<<I>>;
int_to_utf8(I) when I =< 16#7FF ->
@@ -225,16 +221,6 @@ do_comp(List,F1,F2) ->
_ ->
true
end.
-
-do_comp(List,List2,F1,F2) ->
- X = F1(List,List2),
- Y = F2(List,List2),
- case X =:= Y of
- false ->
- exit({not_matching,List,List2,X,Y});
- _ ->
- true
- end.
compare(0,Fun1,Fun2,_Enc) ->
do_comp(<<>>,Fun1,Fun2),
@@ -247,25 +233,3 @@ compare(N,Fun1,Fun2,Enc) ->
L = random_unicode_list(N,Enc),
do_comp(L,Fun1,Fun2),
compare(N-1,Fun1,Fun2,Enc).
-
-compare2(0,Fun1,Fun2) ->
- L = random_unicode_list(100,utf8),
- do_comp(<<>>,L,Fun1,Fun2),
- do_comp(L,<<>>,Fun1,Fun2),
- do_comp(<<>>,<<>>,Fun1,Fun2),
- do_comp([],L,Fun1,Fun2),
- do_comp(L,[],Fun1,Fun2),
- do_comp([],[],Fun1,Fun2),
- do_comp([[]|<<>>],L,Fun1,Fun2),
- do_comp(L,[[]|<<>>],Fun1,Fun2),
- do_comp([[]|<<>>],[[]|<<>>],Fun1,Fun2),
- do_comp([<<>>,[]|<<>>],L,Fun1,Fun2),
- do_comp(L,[<<>>,[]|<<>>],Fun1,Fun2),
- do_comp([<<>>,[]|<<>>],[<<>>,[]|<<>>],Fun1,Fun2),
- true;
-
-compare2(N,Fun1,Fun2) ->
- L = random_unicode_list(N,utf8),
- L2 = random_unicode_list(N,utf8),
- do_comp(L,L2,Fun1,Fun2),
- compare2(N-1,Fun1,Fun2).
diff --git a/lib/stdlib/test/re_SUITE.erl b/lib/stdlib/test/re_SUITE.erl
index 52d3a9f797..71f86e32e5 100644
--- a/lib/stdlib/test/re_SUITE.erl
+++ b/lib/stdlib/test/re_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
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,pcre_cve_2008_2371/1,
+ error_handling/1,pcre_cve_2008_2371/1,re_version/1,
pcre_compile_workspace_overflow/1,re_infinite_loop/1,
re_backwards_accented/1,opt_dupnames/1,opt_all_names/1,inspect/1,
opt_no_start_optimize/1,opt_never_utf/1,opt_ucp/1,
@@ -45,7 +45,7 @@ all() ->
pcre_compile_workspace_overflow, re_infinite_loop,
re_backwards_accented, opt_dupnames, opt_all_names,
inspect, opt_no_start_optimize,opt_never_utf,opt_ucp,
- match_limit, sub_binaries].
+ match_limit, sub_binaries, re_version].
groups() ->
[].
@@ -194,6 +194,14 @@ run_options(Config) when is_list(Config) ->
+%% Test the version is retorned correctly
+re_version(_Config) ->
+ Version = re:version(),
+ {match,[Version]} = re:run(Version,"^[0-9]\\.[0-9]{2} 20[0-9]{2}-[0-9]{2}-[0-9]{2}",[{capture,all,binary}]),
+ ok.
+
+
+
%% Test compile options given directly to run.
combined_options(Config) when is_list(Config) ->
ok = crtest("ABDabcdABCD","abcd",[],true,{match,[{3,4}]}),
@@ -612,9 +620,15 @@ pcre_cve_2008_2371(Config) when is_list(Config) ->
%% http://vcs.pcre.org/viewvc/code/trunk/pcre_compile.c?r1=504&r2=505&view=patch
pcre_compile_workspace_overflow(Config) when is_list(Config) ->
N = 819,
- {error,{"internal error: overran compiling workspace",799}} =
- re:compile([lists:duplicate(N, $(), lists:duplicate(N, $))]),
- ok.
+ ExpStr = "Got expected error: ",
+ case re:compile([lists:duplicate(N, $(), lists:duplicate(N, $))]) of
+ {error, {"regular expression is too complicated" = Str,799}} ->
+ {comment, ExpStr ++ Str};
+ {error, {"parentheses are too deeply nested (stack check)" = Str, _No}} ->
+ {comment, ExpStr ++ Str};
+ Other ->
+ ?t:fail({unexpected, Other})
+ end.
%% Make sure matches that really loop infinitely actually fail.
re_infinite_loop(Config) when is_list(Config) ->
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput1 b/lib/stdlib/test/re_SUITE_data/testoutput1
index 3ed635146a..a2b3cffe9d 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput1
+++ b/lib/stdlib/test/re_SUITE_data/testoutput1
@@ -1,6 +1,8 @@
/-- This set of tests is for features that are compatible with all versions of
- Perl >= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and
- 16-bit PCRE libraries. --/
+ Perl >= 5.10, in non-UTF-8 mode. It should run clean for the 8-bit, 16-bit,
+ and 32-bit PCRE libraries. --/
+
+< forbid 89?=ABCDEFfGILMNPTUWXZ<
/the quick brown fox/
the quick brown fox
@@ -221,7 +223,7 @@ No match
babababc
No match
-/^\ca\cA\c[\c{\c:/
+/^\ca\cA\c[;\c:/
\x01\x01\e;z
0: \x01\x01\x1b;z
@@ -2149,18 +2151,35 @@ No match
abc\100\60
0: abc@0
1: abc
-
-/abc\81/
- abc\081
- 0: abc\x0081
- abc\0\x38\x31
- 0: abc\x0081
-
-/abc\91/
- abc\091
- 0: abc\x0091
- abc\0\x39\x31
- 0: abc\x0091
+
+/^A\8B\9C$/
+ A8B9C
+ 0: A8B9C
+ *** Failers
+No match
+ A\08B\09C
+No match
+
+/^(A)(B)(C)(D)(E)(F)(G)(H)(I)\8\9$/
+ ABCDEFGHIHI
+ 0: ABCDEFGHIHI
+ 1: A
+ 2: B
+ 3: C
+ 4: D
+ 5: E
+ 6: F
+ 7: G
+ 8: H
+ 9: I
+
+/^[A\8B\9C]+$/
+ A8B9C
+ 0: A8B9C
+ *** Failers
+No match
+ A8B9C\x00
+No match
/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\12\123/
abcdefghijkllS
@@ -5972,18 +5991,6 @@ No match
0:
0:
-/^[a-\d]/
- abcde
- 0: a
- -things
- 0: -
- 0digit
- 0: 0
- *** Failers
-No match
- bcdef
-No match
-
/^[\d-a]/
abcde
0: a
@@ -6006,15 +6013,15 @@ No match
/[\s]+/
> \x09\x0a\x0c\x0d\x0b<
- 0: \x09\x0a\x0c\x0d
+ 0: \x09\x0a\x0c\x0d\x0b
/\s+/
> \x09\x0a\x0c\x0d\x0b<
- 0: \x09\x0a\x0c\x0d
+ 0: \x09\x0a\x0c\x0d\x0b
/a b/x
ab
-No match
+ 0: ab
/(?!\A)x/m
a\nxb\n
@@ -6904,10 +6911,6 @@ No match
bc
0: b
-/^(?=(a)){0}b(?1)/
- backgammon
- 0: ba
-
/^(?=(?1))?[az]([abc])d/
abd
0: abd
@@ -8231,6 +8234,16 @@ MK: M
aaaabcde
0: aaaab
1: aaaab
+
+/((?(R)a|(?1)))*/
+ aaa
+ 0: aaa
+ 1: a
+
+/((?(R)a|(?1)))+/
+ aaa
+ 0: aaa
+ 1: a
/a(*:any
name)/K
@@ -9200,4 +9213,233 @@ No match
aaa
No match
+/(?(?=ab)ab)/+
+ ca
+ 0:
+ 0+ ca
+ cd
+ 0:
+ 0+ cd
+
+/(?:(?<n>foo)|(?<n>bar))\k<n>/J
+ foofoo
+ 0: foofoo
+ 1: foo
+ barbar
+ 0: barbar
+ 1: <unset>
+ 2: bar
+
+/(?<n>A)(?:(?<n>foo)|(?<n>bar))\k<n>/J
+ AfooA
+ 0: AfooA
+ 1: A
+ 2: foo
+ AbarA
+ 0: AbarA
+ 1: A
+ 2: <unset>
+ 3: bar
+ ** Failers
+No match
+ Afoofoo
+No match
+ Abarbar
+No match
+
+/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/
+ 1 IN SOA non-sp1 non-sp2(
+ 0: 1 IN SOA non-sp1 non-sp2(
+ 1: 1
+ 2: non-sp1
+ 3: non-sp2
+
+/^ (?:(?<A>A)|(?'B'B)(?<A>A)) (?('A')x) (?(<B>)y)$/xJ
+ Ax
+ 0: Ax
+ 1: A
+ BAxy
+ 0: BAxy
+ 1: <unset>
+ 2: B
+ 3: A
+
+/^A\xZ/
+ A\0Z
+ 0: A\x00Z
+
+/^A\o{123}B/
+ A\123B
+ 0: ASB
+
+/ ^ a + + b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ a + #comment
+ + b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ a + #comment
+ #comment
+ + b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ (?> a + ) b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ ( a + ) + + \w $ /x
+ aaaab
+ 0: aaaab
+ 1: aaaa
+
+/(?:a\Kb)*+/+
+ ababc
+ 0: b
+ 0+ c
+
+/(?>a\Kb)*/+
+ ababc
+ 0: b
+ 0+ c
+
+/(?:a\Kb)*/+
+ ababc
+ 0: b
+ 0+ c
+
+/(a\Kb)*+/+
+ ababc
+ 0: b
+ 0+ c
+ 1: ab
+
+/(a\Kb)*/+
+ ababc
+ 0: b
+ 0+ c
+ 1: ab
+
+/(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc/
+ acb
+No match
+
+'\A(?:[^\"]++|\"(?:[^\"]*+|\"\")*+\")++'
+ NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+ 0: NON QUOTED "QUOT""ED" AFTER
+
+'\A(?:[^\"]++|\"(?:[^\"]++|\"\")*+\")++'
+ NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+ 0: NON QUOTED "QUOT""ED" AFTER
+
+'\A(?:[^\"]++|\"(?:[^\"]++|\"\")++\")++'
+ NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+ 0: NON QUOTED "QUOT""ED" AFTER
+
+'\A([^\"1]++|[\"2]([^\"3]*+|[\"4][\"5])*+[\"6])++'
+ NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+ 0: NON QUOTED "QUOT""ED" AFTER
+ 1: AFTER
+ 2:
+
+/^\w+(?>\s*)(?<=\w)/
+ test test
+ 0: tes
+
+/(?P<same>a)(?P<same>b)/gJ
+ abbaba
+ 0: ab
+ 1: a
+ 2: b
+ 0: ab
+ 1: a
+ 2: b
+
+/(?P<same>a)(?P<same>b)(?P=same)/gJ
+ abbaba
+ 0: aba
+ 1: a
+ 2: b
+
+/(?P=same)?(?P<same>a)(?P<same>b)/gJ
+ abbaba
+ 0: ab
+ 1: a
+ 2: b
+ 0: ab
+ 1: a
+ 2: b
+
+/(?:(?P=same)?(?:(?P<same>a)|(?P<same>b))(?P=same))+/gJ
+ bbbaaabaabb
+ 0: bbbaaaba
+ 1: a
+ 2: b
+ 0: bb
+ 1: <unset>
+ 2: b
+
+/(?:(?P=same)?(?:(?P=same)(?P<same>a)(?P=same)|(?P=same)?(?P<same>b)(?P=same)){2}(?P=same)(?P<same>c)(?P=same)){2}(?P<same>z)?/gJ
+ bbbaaaccccaaabbbcc
+No match
+
+/(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l/
+ acl
+ 0: acl
+ 1: a
+ bdl
+ 0: bdl
+ 1: <unset>
+ 2: b
+ adl
+ 0: dl
+ bcl
+ 0: l
+
+/\sabc/
+ \x{0b}abc
+ 0: \x0babc
+
+/[\Qa]\E]+/
+ aa]]
+ 0: aa]]
+
+/[\Q]a\E]+/
+ aa]]
+ 0: aa]]
+
+/(?:((abcd))|(((?:(?:(?:(?:abc|(?:abcdef))))b)abcdefghi)abc)|((*ACCEPT)))/
+ 1234abcd
+ 0:
+ 1: <unset>
+ 2: <unset>
+ 3: <unset>
+ 4: <unset>
+ 5:
+
+/(\2)(\1)/
+
+"Z*(|d*){216}"
+
+"(?1)(?#?'){8}(a)"
+ baaaaaaaaac
+ 0: aaaaaaaaa
+ 1: a
+
+"(?|(\k'Pm')|(?'Pm'))"
+ abcd
+ 0:
+ 1:
+
+/(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\s])/
+ \ Fred:099
+ 0:
+
+/(?=.*X)X$/
+ \ X
+ 0: X
+
/-- End of testinput1 --/
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput10 b/lib/stdlib/test/re_SUITE_data/testoutput10
index c1c85f9a3b..5a4fbb2366 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput10
+++ b/lib/stdlib/test/re_SUITE_data/testoutput10
@@ -63,6 +63,7 @@ Memory allocation (code space): 7
6 End
------------------------------------------------------------------
Capturing subpattern count = 0
+May match empty string
Options: extended
No first char
No need char
@@ -99,15 +100,13 @@ Memory allocation (code space): 9
------------------------------------------------------------------
/x{1,3}+/BM
-Memory allocation (code space): 19
+Memory allocation (code space): 13
------------------------------------------------------------------
- 0 15 Bra
- 3 9 Once
- 6 x
- 8 x{0,2}
- 12 9 Ket
- 15 15 Ket
- 18 End
+ 0 9 Bra
+ 3 x
+ 5 x{0,2}+
+ 9 9 Ket
+ 12 End
------------------------------------------------------------------
/(x)*+/BM
@@ -138,7 +137,7 @@ Memory allocation (code space): 120
66 [bc]+
100 39 Ket
103 7 CBra 5
-108 \w*
+108 \w*+
110 7 Ket
113 109 Ket
116 116 Ket
@@ -232,7 +231,7 @@ Memory allocation (code space): 45
------------------------------------------------------------------
/(?P<a>a)...(?P=a)bbb(?P>a)d/BM
-Memory allocation (code space): 34
+Memory allocation (code space): 62
------------------------------------------------------------------
0 30 Bra
3 7 CBra 1
@@ -327,7 +326,7 @@ Memory allocation (code space): 12
------------------------------------------------------------------
/\x{110000}/8BM
-Failed: character value in \x{...} sequence is too large at offset 9
+Failed: character value in \x{} or \o{} is too large at offset 9
/[\x{ff}]/8BM
Memory allocation (code space): 10
@@ -503,7 +502,7 @@ Memory allocation (code space): 15
Memory allocation (code space): 48
------------------------------------------------------------------
0 44 Bra
- 3 [+\-\p{Nd}]+
+ 3 [+\-\p{Nd}]++
44 44 Ket
47 End
------------------------------------------------------------------
@@ -651,24 +650,24 @@ Memory allocation (code space): 10
/[[:^alpha:][:^cntrl:]]+/8WB
------------------------------------------------------------------
- 0 44 Bra
- 3 [ -~\x80-\xff\P{L}]+
- 44 44 Ket
- 47 End
+ 0 51 Bra
+ 3 [ -~\x80-\xff\P{L}\x{100}-\x{10ffff}]++
+ 51 51 Ket
+ 54 End
------------------------------------------------------------------
/[[:^cntrl:][:^alpha:]]+/8WB
------------------------------------------------------------------
- 0 44 Bra
- 3 [ -~\x80-\xff\P{L}]+
- 44 44 Ket
- 47 End
+ 0 51 Bra
+ 3 [ -~\x80-\xff\x{100}-\x{10ffff}\P{L}]++
+ 51 51 Ket
+ 54 End
------------------------------------------------------------------
/[[:alpha:]]+/8WB
------------------------------------------------------------------
0 12 Bra
- 3 [\p{L}]+
+ 3 [\p{L}]++
12 12 Ket
15 End
------------------------------------------------------------------
@@ -676,7 +675,7 @@ Memory allocation (code space): 10
/[[:^alpha:]\S]+/8WB
------------------------------------------------------------------
0 15 Bra
- 3 [\P{L}\P{Xsp}]+
+ 3 [\P{L}\P{Xsp}]++
15 15 Ket
18 End
------------------------------------------------------------------
@@ -710,4 +709,63 @@ Memory allocation (code space): 10
76 End
------------------------------------------------------------------
+/(((a\2)|(a*)\g<-1>))*a?/B
+------------------------------------------------------------------
+ 0 57 Bra
+ 3 Brazero
+ 4 48 SCBra 1
+ 9 40 Once
+ 12 18 CBra 2
+ 17 10 CBra 3
+ 22 a
+ 24 \2
+ 27 10 Ket
+ 30 16 Alt
+ 33 7 CBra 4
+ 38 a*
+ 40 7 Ket
+ 43 33 Recurse
+ 46 34 Ket
+ 49 40 Ket
+ 52 48 KetRmax
+ 55 a?+
+ 57 57 Ket
+ 60 End
+------------------------------------------------------------------
+
+/((?+1)(\1))/B
+------------------------------------------------------------------
+ 0 31 Bra
+ 3 25 Once
+ 6 19 CBra 1
+ 11 14 Recurse
+ 14 8 CBra 2
+ 19 \1
+ 22 8 Ket
+ 25 19 Ket
+ 28 25 Ket
+ 31 31 Ket
+ 34 End
+------------------------------------------------------------------
+
+/.((?2)(?R)\1)()/B
+------------------------------------------------------------------
+ 0 35 Bra
+ 3 Any
+ 4 20 Once
+ 7 14 CBra 1
+ 12 27 Recurse
+ 15 0 Recurse
+ 18 \1
+ 21 14 Ket
+ 24 20 Ket
+ 27 5 CBra 2
+ 32 5 Ket
+ 35 35 Ket
+ 38 End
+------------------------------------------------------------------
+
+/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/
+Failed: missing ) at offset 509
+
/-- End of testinput11 --/
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput2 b/lib/stdlib/test/re_SUITE_data/testoutput2
index fd958c2eb7..811bbefc84 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput2
+++ b/lib/stdlib/test/re_SUITE_data/testoutput2
@@ -7,9 +7,12 @@
NOTE: This is a non-UTF set of tests. When UTF support is needed, use
test 5, and if Unicode Property Support is needed, use test 7. --/
+
+< forbid 8W
/(a)b|/I
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
@@ -175,7 +178,7 @@ No options
No first char
No need char
Subject length lower bound = 3
-Starting byte set: c d e
+Starting chars: c d e
this sentence eventually mentions a cat
0: cat
this sentences rambles on and on for a while and then reaches elephant
@@ -187,7 +190,7 @@ Options: caseless
No first char
No need char
Subject length lower bound = 3
-Starting byte set: C D E c d e
+Starting chars: C D E c d e
this sentence eventually mentions a CAT cat
0: CAT
this sentences rambles on and on for a while to elephant ElePhant
@@ -199,7 +202,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/(a|[^\dZ])/IS
Capturing subpattern count = 1
@@ -207,7 +210,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
\x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19
\x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / : ; < = >
? @ 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 [ \ ] ^ _ ` a b c d
@@ -228,7 +231,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x09 \x0a \x0c \x0d \x20 a b
+Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 a b
/(ab\2)/
Failed: reference to non-existent subpattern at offset 6
@@ -416,7 +419,7 @@ Need char = '>'
/(?U)<.*>/I
Capturing subpattern count = 0
-Options: ungreedy
+No options
First char = '<'
Need char = '>'
abc<def>ghi<klm>nop
@@ -440,7 +443,7 @@ Need char = '='
/(?U)={3,}?/I
Capturing subpattern count = 0
-Options: ungreedy
+No options
First char = '='
Need char = '='
abc========def
@@ -474,7 +477,7 @@ Failed: lookbehind assertion is not fixed length at offset 12
/(?i)abc/I
Capturing subpattern count = 0
-Options: caseless
+No options
First char = 'a' (caseless)
Need char = 'c' (caseless)
@@ -486,7 +489,7 @@ No need char
/(?i)^1234/I
Capturing subpattern count = 0
-Options: anchored caseless
+Options: anchored
No first char
No need char
@@ -498,7 +501,8 @@ No need char
/(?s).*/I
Capturing subpattern count = 0
-Options: anchored dotall
+May match empty string
+Options: anchored
No first char
No need char
@@ -508,23 +512,23 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/(?i)[abcd]/IS
Capturing subpattern count = 0
-Options: caseless
+No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: A B C D a b c d
+Starting chars: A B C D a b c d
/(?m)[xy]|(b|c)/IS
Capturing subpattern count = 1
-Options: multiline
+No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: b c x y
+Starting chars: b c x y
/(^a|^b)/Im
Capturing subpattern count = 1
@@ -534,7 +538,7 @@ No need char
/(?i)(^a|^b)/Im
Capturing subpattern count = 1
-Options: caseless multiline
+Options: multiline
First char at start or follows newline
No need char
@@ -545,19 +549,19 @@ Failed: conditional group contains more than two branches at offset 13
Failed: conditional group contains more than two branches at offset 12
/(?(1a)/
-Failed: missing ) at offset 6
+Failed: malformed number or name after (?( at offset 4
/(?(1a))/
-Failed: reference to non-existent subpattern at offset 6
+Failed: malformed number or name after (?( at offset 4
/(?(?i))/
-Failed: assertion expected after (?( at offset 3
+Failed: assertion expected after (?( or (?(?C) at offset 3
/(?(abc))/
Failed: reference to non-existent subpattern at offset 7
/(?(?<ab))/
-Failed: syntax error in subpattern name (missing terminator) at offset 7
+Failed: assertion expected after (?( or (?(?C) at offset 3
/((?s)blah)\s+\1/I
Capturing subpattern count = 1
@@ -587,7 +591,7 @@ No options
First char = 'b' (caseless)
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/(a*b|(?i:c*(?-i)d))/IS
Capturing subpattern count = 1
@@ -595,7 +599,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: C a b c d
+Starting chars: C a b c d
/a$/I
Capturing subpattern count = 0
@@ -662,7 +666,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
/(?<!foo)(alpha|omega)/IS
Capturing subpattern count = 1
@@ -671,7 +675,7 @@ No options
No first char
Need char = 'a'
Subject length lower bound = 5
-Starting byte set: a o
+Starting chars: a o
/(?!alphabet)[ab]/IS
Capturing subpattern count = 0
@@ -679,7 +683,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
/(?<=foo\n)^bar/Im
Capturing subpattern count = 0
@@ -762,6 +766,7 @@ No match
/(?<=ab(?i)x|y|z)/I
Capturing subpattern count = 0
Max lookbehind = 3
+May match empty string
No options
No first char
No need char
@@ -769,6 +774,7 @@ No need char
/(?>.*)(?<=(abcd)|(xyz))/I
Capturing subpattern count = 2
Max lookbehind = 4
+May match empty string
No options
No first char
No need char
@@ -1173,7 +1179,7 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 1
-Options: anchored dotall
+Options: anchored
No first char
No need char
@@ -1377,6 +1383,7 @@ Need char = 'c'
/a*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -1395,6 +1402,7 @@ Need char = 'a'
/a{0,3}/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -1558,30 +1566,35 @@ Need char = 'b'
/a(?(1)b)(.)/I
Capturing subpattern count = 1
+Max back reference = 1
No options
First char = 'a'
No need char
/a(?(1)bag|big)(.)/I
Capturing subpattern count = 1
+Max back reference = 1
No options
First char = 'a'
Need char = 'g'
/a(?(1)bag|big)*(.)/I
Capturing subpattern count = 1
+Max back reference = 1
No options
First char = 'a'
No need char
/a(?(1)bag|big)+(.)/I
Capturing subpattern count = 1
+Max back reference = 1
No options
First char = 'a'
Need char = 'g'
/a(?(1)b..|b..)(.)/I
Capturing subpattern count = 1
+Max back reference = 1
No options
First char = 'a'
Need char = 'b'
@@ -1594,6 +1607,7 @@ Need char = 'e'
/a?b?/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -1612,6 +1626,7 @@ No match
/|-/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -1632,7 +1647,7 @@ Options: anchored
No first char
Need char = 'd'
Subject length lower bound = 4
-No set of starting bytes
+No starting char list
/\( # ( at start
(?: # Non-capturing bracket
@@ -1865,7 +1880,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: 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
+Starting chars: 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
/^[[:ascii:]]/DZ
@@ -1927,7 +1942,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20
+Starting chars: \x09 \x0a \x0b \x0c \x0d \x20
/^[[:cntrl:]]/DZ
------------------------------------------------------------------
@@ -2625,6 +2640,7 @@ Need char = '-'
End
------------------------------------------------------------------
Capturing subpattern count = 0
+May match empty string
Options: extended
No first char
No need char
@@ -2644,7 +2660,7 @@ No need char
/[\s]/DZ
------------------------------------------------------------------
Bra
- [\x09\x0a\x0c\x0d ]
+ [\x09-\x0d ]
Ket
End
------------------------------------------------------------------
@@ -2656,7 +2672,7 @@ No need char
/[\S]/DZ
------------------------------------------------------------------
Bra
- [\x00-\x08\x0b\x0e-\x1f!-\xff] (neg)
+ [\x00-\x08\x0e-\x1f!-\xff] (neg)
Ket
End
------------------------------------------------------------------
@@ -2719,7 +2735,7 @@ No match
End
------------------------------------------------------------------
Capturing subpattern count = 0
-Options: caseless extended
+Options: extended
First char = 'a' (caseless)
Need char = 'c' (caseless)
@@ -2732,7 +2748,7 @@ Need char = 'c' (caseless)
End
------------------------------------------------------------------
Capturing subpattern count = 0
-Options: caseless extended
+Options: extended
First char = 'a' (caseless)
Need char = 'c' (caseless)
@@ -2767,6 +2783,7 @@ Need char = '0'
End
------------------------------------------------------------------
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -2866,6 +2883,7 @@ No match
End
------------------------------------------------------------------
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -2882,20 +2900,41 @@ No options
First char = 'x'
No need char
-/x{1,3}+/DZ
+/x{1,3}+/BZO
------------------------------------------------------------------
Bra
- Once
x
- x{0,2}
+ x{0,2}+
Ket
+ End
+------------------------------------------------------------------
+
+/x{1,3}+/BZOi
+------------------------------------------------------------------
+ Bra
+ /i x
+ /i x{0,2}+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^x]{1,3}+/BZO
+------------------------------------------------------------------
+ Bra
+ [^x]
+ [^x]{0,2}+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^x]{1,3}+/BZOi
+------------------------------------------------------------------
+ Bra
+ /i [^x]
+ /i [^x]{0,2}+
Ket
End
------------------------------------------------------------------
-Capturing subpattern count = 0
-No options
-First char = 'x'
-No need char
/(x)*+/DZ
------------------------------------------------------------------
@@ -2908,12 +2947,14 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
/^(\w++|\s++)*$/I
Capturing subpattern count = 1
+May match empty string
Options: anchored
No first char
No need char
@@ -3054,7 +3095,7 @@ Need char = 'b'
End
------------------------------------------------------------------
Capturing subpattern count = 0
-Options: ungreedy
+No options
First char = 'x'
Need char = 'b'
xaaaab
@@ -3075,7 +3116,7 @@ Need char = 'b'
[bc]+
Ket
CBra 5
- \w*
+ \w*+
Ket
Ket
Ket
@@ -3142,6 +3183,10 @@ Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1
/\U/I
Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1
+/a{1,3}b/U
+ ab
+ 0: ab
+
/[/I
Failed: missing terminating ] for character class at offset 1
@@ -3154,7 +3199,7 @@ Failed: missing terminating ] for character class at offset 10
/[\s]/IDZ
------------------------------------------------------------------
Bra
- [\x09\x0a\x0c\x0d ]
+ [\x09-\x0d ]
Ket
End
------------------------------------------------------------------
@@ -3289,6 +3334,7 @@ Need char = 'b'
/(?=a).*/I
Capturing subpattern count = 0
+May match empty string
No options
First char = 'a'
No need char
@@ -3307,6 +3353,7 @@ Need char = 'z' (caseless)
/(?=a)(?=b)/I
Capturing subpattern count = 0
+May match empty string
No options
First char = 'a'
No need char
@@ -3337,24 +3384,28 @@ Need char = 'a'
/(?(1)ab|ac)(.)/I
Capturing subpattern count = 1
+Max back reference = 1
No options
First char = 'a'
No need char
/(?(1)abz|acz)(.)/I
Capturing subpattern count = 1
+Max back reference = 1
No options
First char = 'a'
Need char = 'z'
/(?(1)abz)(.)/I
Capturing subpattern count = 1
+Max back reference = 1
No options
No first char
No need char
/(?(1)abz)(1)23/I
Capturing subpattern count = 1
+Max back reference = 1
No options
No first char
Need char = '3'
@@ -3373,6 +3424,7 @@ Need char = 'a'
/(a)*/I
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
@@ -3395,7 +3447,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
/[^a]/I
Capturing subpattern count = 0
@@ -3415,7 +3467,7 @@ No options
No first char
Need char = '6'
Subject length lower bound = 4
-Starting byte set: 0 1 2 3 4 5 6 7 8 9
+Starting chars: 0 1 2 3 4 5 6 7 8 9
/a^b/I
Capturing subpattern count = 0
@@ -3445,11 +3497,11 @@ Need char = 'c'
/(?i)[ab]/IS
Capturing subpattern count = 0
-Options: caseless
+No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: A B a b
+Starting chars: A B a b
/[ab](?i)cd/IS
Capturing subpattern count = 0
@@ -3457,7 +3509,7 @@ No options
No first char
Need char = 'd' (caseless)
Subject length lower bound = 3
-Starting byte set: a b
+Starting chars: a b
/abc(?C)def/I
Capturing subpattern count = 0
@@ -3498,7 +3550,7 @@ No options
No first char
Need char = 'f'
Subject length lower bound = 7
-Starting byte set: 0 1 2 3 4 5 6 7 8 9
+Starting chars: 0 1 2 3 4 5 6 7 8 9
1234abcdef
--->1234abcdef
1 ^ \d
@@ -3601,6 +3653,7 @@ No match
/(?C0)(abc(?C1))*/I
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
@@ -3634,6 +3687,7 @@ No need char
/(\d{3}(?C))*/I
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
@@ -3770,20 +3824,6 @@ Need char = 'b'
--->abbbbbccc
1 ^ ^
Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
No match
/a(b+?)(c*?)(?C1)/I
@@ -3829,7 +3869,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
/(?R)/I
Failed: recursive call could loop indefinitely at offset 3
@@ -3880,6 +3920,7 @@ Failed: recursive call could loop indefinitely at offset 16
/^([^()]|\((?1)*\))*$/I
Capturing subpattern count = 1
+May match empty string
Options: anchored
No first char
No need char
@@ -4159,6 +4200,7 @@ Named capturing subpatterns:
one 1
three 3
two 2
+May match empty string
Options: anchored caseless
No first char
No need char
@@ -4258,6 +4300,7 @@ Need char = 'z'
/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a/Is
Capturing subpattern count = 31
+May match empty string
Options: anchored dotall
No first char
No need char
@@ -4265,6 +4308,7 @@ No need char
/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31/Is
Capturing subpattern count = 31
Max back reference = 31
+May match empty string
Options: dotall
No first char
No need char
@@ -4272,6 +4316,7 @@ No need char
/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32/Is
Capturing subpattern count = 32
Max back reference = 32
+May match empty string
Options: dotall
No first char
No need char
@@ -4423,6 +4468,7 @@ Capturing subpattern count = 2
Named capturing subpatterns:
Tes 1
Test 2
+May match empty string
No options
No first char
No need char
@@ -4441,6 +4487,7 @@ Capturing subpattern count = 2
Named capturing subpatterns:
Tes 2
Test 1
+May match empty string
No options
No first char
No need char
@@ -4518,6 +4565,7 @@ Need char = ']'
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
No options
No first char
No need char
@@ -4538,6 +4586,7 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
No options
No first char
No need char
@@ -4569,6 +4618,7 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
No options
No first char
No need char
@@ -4576,9 +4626,7 @@ No need char
/[ab]{1}+/DZ
------------------------------------------------------------------
Bra
- Once
- [ab]{1,1}
- Ket
+ [ab]{1,1}+
Ket
End
------------------------------------------------------------------
@@ -4602,7 +4650,7 @@ Options: caseless
No first char
Need char = 'g' (caseless)
Subject length lower bound = 8
-No set of starting bytes
+No starting char list
Baby Bjorn Active Carrier - With free SHIPPING!!
0: Baby Bjorn Active Carrier - With free SHIPPING!!
1: Baby Bjorn Active Carrier - With free SHIPPING!!
@@ -4621,7 +4669,7 @@ No options
No first char
Need char = 'b'
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/(a|b)*.?c/ISDZ
------------------------------------------------------------------
@@ -4642,7 +4690,7 @@ No options
No first char
Need char = 'c'
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/abc(?C255)de(?C)f/DZ
------------------------------------------------------------------
@@ -4715,7 +4763,7 @@ Options:
No first char
Need char = 'b'
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
ab
--->ab
+0 ^ a*
@@ -4858,7 +4906,7 @@ Options:
No first char
Need char = 'x'
Subject length lower bound = 4
-Starting byte set: a d
+Starting chars: a d
abcx
--->abcx
+0 ^ (abc|def)
@@ -5092,7 +5140,7 @@ Options:
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b x
+Starting chars: a b x
Note: that { does NOT introduce a quantifier
--->Note: that { does NOT introduce a quantifier
+0 ^ ([ab]{,4}c|xy)
@@ -5290,7 +5338,7 @@ No match
Callout 255 0 21
CBra 1
Callout 255 1 9
- [ab]{1,4}
+ [ab]{1,4}+
Callout 255 10 1
c
Callout 255 11 0
@@ -5303,7 +5351,7 @@ No match
Ket
CBra 1
Callout 255 1 9
- [ab]{1,4}
+ [ab]{1,4}+
Callout 255 10 1
c
Callout 255 11 0
@@ -5316,7 +5364,7 @@ No match
Ket
CBra 1
Callout 255 1 9
- [ab]{1,4}
+ [ab]{1,4}+
Callout 255 10 1
c
Callout 255 11 0
@@ -5329,7 +5377,7 @@ No match
Ket
CBra 1
Callout 255 1 9
- [ab]{1,4}
+ [ab]{1,4}+
Callout 255 10 1
c
Callout 255 11 0
@@ -5343,7 +5391,7 @@ No match
Braminzero
CBra 1
Callout 255 1 9
- [ab]{1,4}
+ [ab]{1,4}+
Callout 255 10 1
c
Callout 255 11 0
@@ -5397,6 +5445,7 @@ Need char = '3'
/\b.*/I
Capturing subpattern count = 0
Max lookbehind = 1
+May match empty string
No options
No first char
No need char
@@ -5406,6 +5455,7 @@ No need char
/\b.*/Is
Capturing subpattern count = 0
Max lookbehind = 1
+May match empty string
Options: dotall
No first char
No need char
@@ -5414,6 +5464,7 @@ No need char
/(?!.bcd).*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -5563,13 +5614,17 @@ No match
123456\P
No match
+//KF>testsavedregex
+Compiled pattern written to testsavedregex
+Study data written to testsavedregex
+
/abc/IS>testsavedregex
Capturing subpattern count = 0
No options
First char = 'a'
Need char = 'c'
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
Compiled pattern written to testsavedregex
Study data written to testsavedregex
<testsavedregex
@@ -5604,7 +5659,7 @@ No options
First char = 'a'
Need char = 'c'
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
Compiled pattern written to testsavedregex
Study data written to testsavedregex
<testsavedregex
@@ -5639,7 +5694,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
Compiled pattern written to testsavedregex
Study data written to testsavedregex
<testsavedregex
@@ -5678,7 +5733,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
Compiled pattern written to testsavedregex
Study data written to testsavedregex
<testsavedregex
@@ -5779,13 +5834,13 @@ No match
No match
/a{11111111111111111111}/I
-Failed: number too big in {} quantifier at offset 22
+Failed: number too big in {} quantifier at offset 8
/(){64294967295}/I
-Failed: number too big in {} quantifier at offset 14
+Failed: number too big in {} quantifier at offset 9
/(){2,4294967295}/I
-Failed: number too big in {} quantifier at offset 15
+Failed: number too big in {} quantifier at offset 11
"(?i:a)(?i:b)(?i:c)(?i:d)(?i:e)(?i:f)(?i:g)(?i:h)(?i:i)(?i:j)(k)(?i:l)A\1B"I
Capturing subpattern count = 1
@@ -6002,6 +6057,7 @@ Matched, but too many substrings
/[^()]*(?:\((?R)\)[^()]*)*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -6014,6 +6070,7 @@ No need char
/[^()]*(?:\((?>(?R))\)[^()]*)*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -6024,6 +6081,7 @@ No need char
/[^()]*(?:\((?R)\))*[^()]*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -6034,6 +6092,7 @@ No need char
/(?:\((?R)\))*[^()]*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -6046,6 +6105,7 @@ No need char
/(?:\((?R)\))|[^()]*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -6095,6 +6155,17 @@ no parentheses with name "Z"
2: a1
copy substring Z failed -7
C a1 (2) A
+
+/(?|(?<a>)(?<b>)(?<a>)|(?<a>)(?<b>)(?<a>))/IJ
+Capturing subpattern count = 3
+Named capturing subpatterns:
+ a 1
+ a 3
+ b 2
+May match empty string
+Options: dupnames
+No first char
+No need char
/^(?P<A>a)(?P<A>b)/IJ
Capturing subpattern count = 2
@@ -6228,7 +6299,7 @@ Capturing subpattern count = 3
Named capturing subpatterns:
A 2
A 3
-Options: anchored dupnames
+Options: anchored
Duplicate name status changes
No first char
No need char
@@ -6278,6 +6349,7 @@ No need char
/^(?P<A>a)?(?(A)a|b)/I
Capturing subpattern count = 1
+Max back reference = 1
Named capturing subpatterns:
A 1
Options: anchored
@@ -6295,6 +6367,7 @@ No match
/(?:(?(ZZ)a|b)(?P<ZZ>X))+/I
Capturing subpattern count = 1
+Max back reference = 1
Named capturing subpatterns:
ZZ 1
No options
@@ -6305,13 +6378,14 @@ Need char = 'X'
1: X
/(?:(?(2y)a|b)(X))+/I
-Failed: reference to non-existent subpattern at offset 9
+Failed: malformed number or name after (?( at offset 7
/(?:(?(ZA)a|b)(?P<ZZ>X))+/I
Failed: reference to non-existent subpattern at offset 9
/(?:(?(ZZ)a|b)(?(ZZ)a|b)(?P<ZZ>X))+/I
Capturing subpattern count = 1
+Max back reference = 1
Named capturing subpatterns:
ZZ 1
No options
@@ -6323,6 +6397,7 @@ Need char = 'X'
/(?:(?(ZZ)a|\(b\))\\(?P<ZZ>X))+/I
Capturing subpattern count = 1
+Max back reference = 1
Named capturing subpatterns:
ZZ 1
No options
@@ -6377,9 +6452,9 @@ No options
No first char
Need char = ','
Subject length lower bound = 1
-Starting byte set: \x09 \x0a \x0c \x0d \x20 ,
+Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 ,
\x0b,\x0b
- 0: ,
+ 0: \x0b,\x0b
\x0c,\x0d
0: \x0c,\x0d
@@ -6488,7 +6563,7 @@ No match
No match
/^abc/Im<bad>
-Unknown newline type at: <bad>
+Unknown modifier at: <bad>
/abc/I
@@ -6497,12 +6572,13 @@ No options
First char = 'a'
Need char = 'c'
xyz\rabc\<bad>
-Unknown newline type at: <bad>
+Unknown escape sequence at: <bad>
abc
0: abc
/.*/I<lf>
Capturing subpattern count = 0
+May match empty string
Options:
Forced newline sequence: LF
First char at start or follows newline
@@ -6544,6 +6620,7 @@ Need char = 'f'
+((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)+I
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
@@ -6682,7 +6759,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: C a b c d
+Starting chars: C a b c d
/()[ab]xyz/IS
Capturing subpattern count = 1
@@ -6690,7 +6767,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b
+Starting chars: a b
/(|)[ab]xyz/IS
Capturing subpattern count = 1
@@ -6698,7 +6775,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b
+Starting chars: a b
/(|c)[ab]xyz/IS
Capturing subpattern count = 1
@@ -6706,7 +6783,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b c
+Starting chars: a b c
/(|c?)[ab]xyz/IS
Capturing subpattern count = 1
@@ -6714,7 +6791,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b c
+Starting chars: a b c
/(d?|c?)[ab]xyz/IS
Capturing subpattern count = 1
@@ -6722,7 +6799,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b c d
+Starting chars: a b c d
/(d?|c)[ab]xyz/IS
Capturing subpattern count = 1
@@ -6730,7 +6807,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b c d
+Starting chars: a b c d
/^a*b\d/DZ
------------------------------------------------------------------
@@ -6823,7 +6900,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/(a+|b*)[cd]/IS
Capturing subpattern count = 1
@@ -6831,7 +6908,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/(a*|b+)[cd]/IS
Capturing subpattern count = 1
@@ -6839,7 +6916,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/(a+|b+)[cd]/IS
Capturing subpattern count = 1
@@ -6847,7 +6924,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
@@ -7467,7 +7544,7 @@ Matched, but too many substrings
/a*[^a]/BZ
------------------------------------------------------------------
Bra
- a*
+ a*+
[^a]
Ket
End
@@ -7609,7 +7686,7 @@ No match
------------------------------------------------------------------
Bra
^
- [a-z]+
+ [a-z]++
Ket
End
------------------------------------------------------------------
@@ -7650,7 +7727,7 @@ No match
^
CBra 1
Cond
- 2 Cond nref
+ 2 Cond ref
y
Ket
[()]
@@ -7710,6 +7787,7 @@ Named capturing subpatterns:
one 1
three 3
two 2
+May match empty string
Options: anchored caseless
No first char
No need char
@@ -7792,7 +7870,7 @@ No match
Failed: malformed number or name after (?( at offset 6
/(?(''))/
-Failed: assertion expected after (?( at offset 4
+Failed: assertion expected after (?( or (?(?C) at offset 4
/(?('R')stuff)/
Failed: reference to non-existent subpattern at offset 7
@@ -7809,15 +7887,9 @@ Failed: reference to non-existent subpattern at offset 7
1: abcabc1Xabc2XabcX
2: abcabc1Xabc2XabcX
-/(?<A> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x
+/(?<A> (?'B' abc (?(R) (?(R&C)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x
Failed: reference to non-existent subpattern at offset 29
-/(?<1> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x
- abcabc1Xabc2XabcXabcabc
- 0: abcabc1Xabc2XabcX
- 1: abcabc1Xabc2XabcX
- 2: abcabc1Xabc2XabcX
-
/^(?(DEFINE) abc | xyz ) /x
Failed: DEFINE group contains more than one branch at offset 22
@@ -8041,7 +8113,7 @@ Failed: a numbered reference must not be zero at offset 8
/^(a)\g{3/
Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 8
-/^(a)\g{4a}/
+/^(a)\g{aa}/
Failed: reference to non-existent subpattern at offset 9
/^a.b/<lf>
@@ -8546,7 +8618,7 @@ No match
\d
\v++
\w
- \v+
+ \v++
\S
\v++
\V
@@ -8644,27 +8716,18 @@ No match
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
- +4 ^ ^ c+
- +2 ^ ^ b?
- +4 ^ ^ c+
- +2 ^^ b?
- +4 ^^ c+
+0 ^ a+
+2 ^ ^ b?
+4 ^ ^ c+
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
- +4 ^ ^ c+
- +2 ^^ b?
- +4 ^^ c+
+0 ^ a+
+2 ^^ b?
+4 ^ ^ c+
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
- +4 ^^ c+
No match
/a+b?(*PRUNE)c+(*FAIL)/C
@@ -9072,10 +9135,10 @@ Failed: subpattern name expected at offset 3
Failed: subpattern name expected at offset 3
/\k/
-Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 2
+Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 1
/\kabc/
-Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 5
+Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 1
/(?P=)/
Failed: subpattern name expected at offset 4
@@ -9123,7 +9186,7 @@ Failed: unknown POSIX class name at offset 6
Failed: unknown POSIX class name at offset 3
/(^(a|b\g<-1'c))/
-Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 15
+Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 8
/^(?+1)(?<a>x|y){0}z/
xzxx
@@ -9233,8 +9296,28 @@ No match
ab
No match
-/a(?!)+b/
-Failed: nothing to repeat at offset 5
+/a(?!)b/BZ
+------------------------------------------------------------------
+ Bra
+ a
+ *FAIL
+ b
+ Ket
+ End
+------------------------------------------------------------------
+
+/(?!)?a/BZ
+------------------------------------------------------------------
+ Bra
+ Brazero
+ Assert not
+ Ket
+ a
+ Ket
+ End
+------------------------------------------------------------------
+ ab
+ 0: a
/a(*FAIL)+b/
Failed: nothing to repeat at offset 8
@@ -9245,10 +9328,11 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: x y z
+Starting chars: x y z
/(?(?=.*b)b|^)/CI
Capturing subpattern count = 0
+May match empty string
Options:
No first char
No need char
@@ -9296,7 +9380,7 @@ No need char
/(?(?=.*b).*b|^d)/I
Capturing subpattern count = 0
No options
-First char at start or follows newline
+No first char
No need char
/xyz/C
@@ -9353,7 +9437,7 @@ No match
No match
/(*NO_START_OPT)xyz/C
- abcxyz
+ abcxyz
--->abcxyz
+15 ^ x
+15 ^ x
@@ -9363,6 +9447,15 @@ No match
+17 ^ ^ z
+18 ^ ^
0: xyz
+
+/(*NO_AUTO_POSSESS)a+b/BZ
+------------------------------------------------------------------
+ Bra
+ a+
+ b
+ Ket
+ End
+------------------------------------------------------------------
/xyz/CY
abcxyz
@@ -10024,7 +10117,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/(a|bc)\1{2,3}/SI
Capturing subpattern count = 1
@@ -10033,7 +10126,7 @@ No options
No first char
No need char
Subject length lower bound = 3
-Starting byte set: a b
+Starting chars: a b
/(a|bc)(?1)/SI
Capturing subpattern count = 1
@@ -10041,7 +10134,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/(a|b\1)(a|b\1)/SI
Capturing subpattern count = 2
@@ -10050,7 +10143,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/(a|b\1){2}/SI
Capturing subpattern count = 1
@@ -10059,7 +10152,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/(a|bbbb\1)(a|bbbb\1)/SI
Capturing subpattern count = 2
@@ -10068,7 +10161,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/(a|bbbb\1){2}/SI
Capturing subpattern count = 1
@@ -10077,7 +10170,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/SI
Capturing subpattern count = 1
@@ -10085,7 +10178,7 @@ Options: anchored
No first char
Need char = ':'
Subject length lower bound = 22
-No set of starting bytes
+No starting char list
/<tr([\w\W\s\d][^<>]{0,})><TD([\w\W\s\d][^<>]{0,})>([\d]{0,}\.)(.*)((<BR>([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/isIS
Capturing subpattern count = 11
@@ -10093,7 +10186,7 @@ Options: caseless dotall
First char = '<'
Need char = '>'
Subject length lower bound = 47
-No set of starting bytes
+No starting char list
"(?>.*/)foo"SI
Capturing subpattern count = 0
@@ -10101,7 +10194,7 @@ No options
No first char
Need char = 'o'
Subject length lower bound = 4
-No set of starting bytes
+No starting char list
/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /xSI
Capturing subpattern count = 0
@@ -10109,7 +10202,7 @@ Options: extended
No first char
Need char = '-'
Subject length lower bound = 8
-No set of starting bytes
+No starting char list
/(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))/iSI
Capturing subpattern count = 1
@@ -10117,7 +10210,7 @@ Options: caseless
No first char
No need char
Subject length lower bound = 1
-Starting byte set: A B C a b c
+Starting chars: A B C a b c
/(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/SI
Capturing subpattern count = 0
@@ -10125,7 +10218,7 @@ No options
No first char
Need char = 'b'
Subject length lower bound = 41
-Starting byte set: c d
+Starting chars: c d
/<a[\s]+href[\s]*=[\s]* # find <a href=
([\"\'])? # find single or double quote
@@ -10138,7 +10231,7 @@ Options: caseless extended dotall
First char = '<'
Need char = '='
Subject length lower bound = 9
-No set of starting bytes
+No starting char list
/^(?!:) # colon disallowed at start
(?: # start of item
@@ -10150,17 +10243,17 @@ No set of starting bytes
(?(1)|.) # check that there was an empty component
/xiIS
Capturing subpattern count = 1
+Max back reference = 1
Options: anchored caseless extended
No first char
Need char = ':'
Subject length lower bound = 2
-No set of starting bytes
+No starting char list
/(?|(?<a>A)|(?<a>B))/I
Capturing subpattern count = 1
Named capturing subpatterns:
a 1
- a 1
No options
No first char
No need char
@@ -10180,6 +10273,7 @@ Failed: different names for subpatterns of the same number are not allowed at of
b(?<quote> (?<apostrophe>')|(?<realquote>")) )
(?('quote')[a-z]+|[0-9]+)/JIx
Capturing subpattern count = 6
+Max back reference = 1
Named capturing subpatterns:
apostrophe 2
apostrophe 5
@@ -10233,7 +10327,7 @@ No match
Ket
Ket
Cond
- 4 Cond nref
+ Cond ref <D>2
X
Alt
Y
@@ -10242,6 +10336,7 @@ No match
End
------------------------------------------------------------------
Capturing subpattern count = 4
+Max back reference = 4
Named capturing subpatterns:
D 4
D 1
@@ -10279,7 +10374,7 @@ No match
CBra 4
d
Cond
- Cond nrecurse 1
+ Cond recurse <A>2
$
Alt
Recurse
@@ -10289,6 +10384,7 @@ No match
End
------------------------------------------------------------------
Capturing subpattern count = 4
+Max back reference = 1
Named capturing subpatterns:
A 1
A 4
@@ -10379,7 +10475,7 @@ Options:
No first char
Need char = 'a'
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
cat
0: a
1:
@@ -10393,7 +10489,7 @@ No options
No first char
Need char = 'a'
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
cat
No match
@@ -10405,17 +10501,18 @@ No options
First char = 'i'
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
i
0: i
/()i(?(1)a)/SI
Capturing subpattern count = 1
+Max back reference = 1
No options
No first char
Need char = 'i'
Subject length lower bound = 1
-Starting byte set: i
+Starting chars: i
ia
0: ia
1:
@@ -11009,7 +11106,7 @@ No options
First char = 'a'
Need char = '4'
Subject length lower bound = 5
-No set of starting bytes
+No starting char list
/([abc])++1234/SI
Capturing subpattern count = 1
@@ -11017,7 +11114,7 @@ No options
No first char
Need char = '4'
Subject length lower bound = 5
-Starting byte set: a b c
+Starting chars: a b c
/(?<=(abc)+)X/
Failed: lookbehind assertion is not fixed length at offset 10
@@ -11036,12 +11133,14 @@ No need char
/(^ab|^)+/I
Capturing subpattern count = 1
+May match empty string
Options: anchored
No first char
No need char
/(^ab|^)++/I
Capturing subpattern count = 1
+May match empty string
Options: anchored
No first char
No need char
@@ -11060,12 +11159,14 @@ No need char
/(?:^ab|^)+/I
Capturing subpattern count = 0
+May match empty string
Options: anchored
No first char
No need char
/(?:^ab|^)++/I
Capturing subpattern count = 0
+May match empty string
Options: anchored
No first char
No need char
@@ -11084,12 +11185,14 @@ Need char = 'b'
/(.*ab|.*)+/I
Capturing subpattern count = 1
+May match empty string
No options
First char at start or follows newline
No need char
/(.*ab|.*)++/I
Capturing subpattern count = 1
+May match empty string
No options
First char at start or follows newline
No need char
@@ -11108,12 +11211,14 @@ Need char = 'b'
/(?:.*ab|.*)+/I
Capturing subpattern count = 0
+May match empty string
No options
First char at start or follows newline
No need char
/(?:.*ab|.*)++/I
Capturing subpattern count = 0
+May match empty string
No options
First char at start or follows newline
No need char
@@ -11290,7 +11395,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/(a(?2)|b)(b(?1)|a)(?:(?1)|(?2))/SI
Capturing subpattern count = 2
@@ -11298,7 +11403,7 @@ No options
No first char
No need char
Subject length lower bound = 3
-Starting byte set: a b
+Starting chars: a b
/(a(?2)|b)(b(?1)|a)(?1)(?2)/SI
Capturing subpattern count = 2
@@ -11306,7 +11411,7 @@ No options
No first char
No need char
Subject length lower bound = 4
-Starting byte set: a b
+Starting chars: a b
/(abc)(?1)/SI
Capturing subpattern count = 1
@@ -11314,7 +11419,7 @@ No options
First char = 'a'
Need char = 'c'
Subject length lower bound = 6
-No set of starting bytes
+No starting char list
/^(?>a)++/
aa\M
@@ -11519,7 +11624,7 @@ Matched, but too many substrings
Assert not
a
Ket
- \w+
+ \w++
Ket
End
------------------------------------------------------------------
@@ -11632,7 +11737,7 @@ No options
First char = 't'
Need char = 't'
Subject length lower bound = 18
-No set of starting bytes
+No starting char list
/\btype\b\W*?\btext\b\W*?\bjavascript\b|\burl\b\W*?\bshell:|<input\b.*?\btype\b\W*?\bimage\b|\bonkeyup\b\W*?\=/IS
Capturing subpattern count = 0
@@ -11641,15 +11746,16 @@ No options
No first char
No need char
Subject length lower bound = 8
-Starting byte set: < o t u
+Starting chars: < o t u
/a(*SKIP)c|b(*ACCEPT)|/+S!I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
Subject length lower bound = -1
-No set of starting bytes
+No starting char list
a
0:
0+
@@ -11660,7 +11766,7 @@ No options
No first char
No need char
Subject length lower bound = -1
-Starting byte set: a b x
+Starting chars: a b x
ax
0: x
@@ -11715,11 +11821,11 @@ Minimum match() recursion limit = 45
Bra
^
Once_NC
- a+
+ a++
Ket
Once
CBra 1
- z+
+ z++
Ket
Ket
\w
@@ -11778,14 +11884,14 @@ No match
/^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/
\Maabbccddee
-Minimum match() limit = 12
-Minimum match() recursion limit = 3
+Minimum match() limit = 7
+Minimum match() recursion limit = 2
0: aabbccddee
/^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/
\Maabbccddee
-Minimum match() limit = 22
-Minimum match() recursion limit = 21
+Minimum match() limit = 17
+Minimum match() recursion limit = 16
0: aabbccddee
1: aa
2: bb
@@ -11795,8 +11901,8 @@ Minimum match() recursion limit = 21
/^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/
\Maabbccddee
-Minimum match() limit = 18
-Minimum match() recursion limit = 13
+Minimum match() limit = 13
+Minimum match() recursion limit = 10
0: aabbccddee
1: aa
2: cc
@@ -11887,7 +11993,10 @@ No match
Failed: \N is not supported in a class at offset 3
/a[B-\Nc]/
-Failed: \N is not supported in a class at offset 5
+Failed: invalid range in character class at offset 5
+
+/a[B\Nc]/
+Failed: \N is not supported in a class at offset 4
/(a)(?2){0,1999}?(b)/
@@ -12293,6 +12402,7 @@ No need char
/(?>.*?)(?<=(abcd)|(wxyz))/I
Capturing subpattern count = 2
Max lookbehind = 4
+May match empty string
No options
No first char
No need char
@@ -12300,6 +12410,7 @@ No need char
/(?>.*)(?<=(abcd)|(wxyz))/I
Capturing subpattern count = 2
Max lookbehind = 4
+May match empty string
No options
No first char
No need char
@@ -12338,6 +12449,7 @@ Need char = 'c'
/.?/S-I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -12345,11 +12457,12 @@ Study returned NULL
/.?/S!I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
Subject length lower bound = -1
-No set of starting bytes
+No starting char list
/(?:(a)+(?C1)bb|aa(?C2)b)/
aab\C+
@@ -12635,7 +12748,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 2
-Starting byte set: a z
+Starting chars: a z
aaaaaaaaaaaaaz
Error -21 (recursion limit exceeded)
aaaaaaaaaaaaaz\Q1000
@@ -12648,7 +12761,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 2
-Starting byte set: a z
+Starting chars: a z
aaaaaaaaaaaaaz
Error -21 (recursion limit exceeded)
@@ -12659,10 +12772,1937 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 2
-Starting byte set: a z
+Starting chars: a z
aaaaaaaaaaaaaz
No match
aaaaaaaaaaaaaz\Q10
Error -21 (recursion limit exceeded)
+/-- This test causes a segfault with Perl 5.18.0 --/
+
+/^(?=(a)){0}b(?1)/
+ backgammon
+ 0: ba
+
+/(?|(?<n>f)|(?<n>b))/JI
+Capturing subpattern count = 1
+Named capturing subpatterns:
+ n 1
+Options: dupnames
+No first char
+No need char
+
+/(?<a>abc)(?<a>z)\k<a>()/JDZS
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ abc
+ Ket
+ CBra 2
+ z
+ Ket
+ \k<a>2
+ CBra 3
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 3
+Max back reference = 2
+Named capturing subpatterns:
+ a 1
+ a 2
+Options: dupnames
+First char = 'a'
+Need char = 'z'
+Subject length lower bound = 5
+No starting char list
+
+/a*[bcd]/BZ
+------------------------------------------------------------------
+ Bra
+ a*+
+ [b-d]
+ Ket
+ End
+------------------------------------------------------------------
+
+/[bcd]*a/BZ
+------------------------------------------------------------------
+ Bra
+ [b-d]*+
+ a
+ Ket
+ End
+------------------------------------------------------------------
+
+/-- A complete set of tests for auto-possessification of character types --/
+
+/\D+\D \D+\d \D+\S \D+\s \D+\W \D+\w \D+. \D+\C \D+\R \D+\H \D+\h \D+\V \D+\v \D+\Z \D+\z \D+$/BZx
+------------------------------------------------------------------
+ Bra
+ \D+
+ \D
+ \D++
+ \d
+ \D+
+ \S
+ \D+
+ \s
+ \D+
+ \W
+ \D+
+ \w
+ \D+
+ Any
+ \D+
+ AllAny
+ \D+
+ \R
+ \D+
+ \H
+ \D+
+ \h
+ \D+
+ \V
+ \D+
+ \v
+ \D+
+ \Z
+ \D++
+ \z
+ \D+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\d+\D \d+\d \d+\S \d+\s \d+\W \d+\w \d+. \d+\C \d+\R \d+\H \d+\h \d+\V \d+\v \d+\Z \d+\z \d+$/BZx
+------------------------------------------------------------------
+ Bra
+ \d++
+ \D
+ \d+
+ \d
+ \d+
+ \S
+ \d++
+ \s
+ \d++
+ \W
+ \d+
+ \w
+ \d+
+ Any
+ \d+
+ AllAny
+ \d++
+ \R
+ \d+
+ \H
+ \d++
+ \h
+ \d+
+ \V
+ \d++
+ \v
+ \d++
+ \Z
+ \d++
+ \z
+ \d++
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\S+\D \S+\d \S+\S \S+\s \S+\W \S+\w \S+. \S+\C \S+\R \S+\H \S+\h \S+\V \S+\v \S+\Z \S+\z \S+$/BZx
+------------------------------------------------------------------
+ Bra
+ \S+
+ \D
+ \S+
+ \d
+ \S+
+ \S
+ \S++
+ \s
+ \S+
+ \W
+ \S+
+ \w
+ \S+
+ Any
+ \S+
+ AllAny
+ \S++
+ \R
+ \S+
+ \H
+ \S++
+ \h
+ \S+
+ \V
+ \S++
+ \v
+ \S++
+ \Z
+ \S++
+ \z
+ \S++
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\s+\D \s+\d \s+\S \s+\s \s+\W \s+\w \s+. \s+\C \s+\R \s+\H \s+\h \s+\V \s+\v \s+\Z \s+\z \s+$/BZx
+------------------------------------------------------------------
+ Bra
+ \s+
+ \D
+ \s++
+ \d
+ \s++
+ \S
+ \s+
+ \s
+ \s+
+ \W
+ \s++
+ \w
+ \s+
+ Any
+ \s+
+ AllAny
+ \s+
+ \R
+ \s+
+ \H
+ \s+
+ \h
+ \s+
+ \V
+ \s+
+ \v
+ \s+
+ \Z
+ \s++
+ \z
+ \s+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\W+\D \W+\d \W+\S \W+\s \W+\W \W+\w \W+. \W+\C \W+\R \W+\H \W+\h \W+\V \W+\v \W+\Z \W+\z \W+$/BZx
+------------------------------------------------------------------
+ Bra
+ \W+
+ \D
+ \W++
+ \d
+ \W+
+ \S
+ \W+
+ \s
+ \W+
+ \W
+ \W++
+ \w
+ \W+
+ Any
+ \W+
+ AllAny
+ \W+
+ \R
+ \W+
+ \H
+ \W+
+ \h
+ \W+
+ \V
+ \W+
+ \v
+ \W+
+ \Z
+ \W++
+ \z
+ \W+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\w+\D \w+\d \w+\S \w+\s \w+\W \w+\w \w+. \w+\C \w+\R \w+\H \w+\h \w+\V \w+\v \w+\Z \w+\z \w+$/BZx
+------------------------------------------------------------------
+ Bra
+ \w+
+ \D
+ \w+
+ \d
+ \w+
+ \S
+ \w++
+ \s
+ \w++
+ \W
+ \w+
+ \w
+ \w+
+ Any
+ \w+
+ AllAny
+ \w++
+ \R
+ \w+
+ \H
+ \w++
+ \h
+ \w+
+ \V
+ \w++
+ \v
+ \w++
+ \Z
+ \w++
+ \z
+ \w++
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\C+\D \C+\d \C+\S \C+\s \C+\W \C+\w \C+. \C+\C \C+\R \C+\H \C+\h \C+\V \C+\v \C+\Z \C+\z \C+$/BZx
+------------------------------------------------------------------
+ Bra
+ AllAny+
+ \D
+ AllAny+
+ \d
+ AllAny+
+ \S
+ AllAny+
+ \s
+ AllAny+
+ \W
+ AllAny+
+ \w
+ AllAny+
+ Any
+ AllAny+
+ AllAny
+ AllAny+
+ \R
+ AllAny+
+ \H
+ AllAny+
+ \h
+ AllAny+
+ \V
+ AllAny+
+ \v
+ AllAny+
+ \Z
+ AllAny++
+ \z
+ AllAny+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\R+\D \R+\d \R+\S \R+\s \R+\W \R+\w \R+. \R+\C \R+\R \R+\H \R+\h \R+\V \R+\v \R+\Z \R+\z \R+$/BZx
+------------------------------------------------------------------
+ Bra
+ \R+
+ \D
+ \R++
+ \d
+ \R+
+ \S
+ \R++
+ \s
+ \R+
+ \W
+ \R++
+ \w
+ \R++
+ Any
+ \R+
+ AllAny
+ \R+
+ \R
+ \R+
+ \H
+ \R++
+ \h
+ \R+
+ \V
+ \R+
+ \v
+ \R+
+ \Z
+ \R++
+ \z
+ \R+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\H+\D \H+\d \H+\S \H+\s \H+\W \H+\w \H+. \H+\C \H+\R \H+\H \H+\h \H+\V \H+\v \H+\Z \H+\z \H+$/BZx
+------------------------------------------------------------------
+ Bra
+ \H+
+ \D
+ \H+
+ \d
+ \H+
+ \S
+ \H+
+ \s
+ \H+
+ \W
+ \H+
+ \w
+ \H+
+ Any
+ \H+
+ AllAny
+ \H+
+ \R
+ \H+
+ \H
+ \H++
+ \h
+ \H+
+ \V
+ \H+
+ \v
+ \H+
+ \Z
+ \H++
+ \z
+ \H+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\h+\D \h+\d \h+\S \h+\s \h+\W \h+\w \h+. \h+\C \h+\R \h+\H \h+\h \h+\V \h+\v \h+\Z \h+\z \h+$/BZx
+------------------------------------------------------------------
+ Bra
+ \h+
+ \D
+ \h++
+ \d
+ \h++
+ \S
+ \h+
+ \s
+ \h+
+ \W
+ \h++
+ \w
+ \h+
+ Any
+ \h+
+ AllAny
+ \h++
+ \R
+ \h++
+ \H
+ \h+
+ \h
+ \h+
+ \V
+ \h++
+ \v
+ \h+
+ \Z
+ \h++
+ \z
+ \h+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\V+\D \V+\d \V+\S \V+\s \V+\W \V+\w \V+. \V+\C \V+\R \V+\H \V+\h \V+\V \V+\v \V+\Z \V+\z \V+$/BZx
+------------------------------------------------------------------
+ Bra
+ \V+
+ \D
+ \V+
+ \d
+ \V+
+ \S
+ \V+
+ \s
+ \V+
+ \W
+ \V+
+ \w
+ \V+
+ Any
+ \V+
+ AllAny
+ \V++
+ \R
+ \V+
+ \H
+ \V+
+ \h
+ \V+
+ \V
+ \V++
+ \v
+ \V+
+ \Z
+ \V++
+ \z
+ \V+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\v+\D \v+\d \v+\S \v+\s \v+\W \v+\w \v+. \v+\C \v+\R \v+\H \v+\h \v+\V \v+\v \v+\Z \v+\z \v+$/BZx
+------------------------------------------------------------------
+ Bra
+ \v+
+ \D
+ \v++
+ \d
+ \v++
+ \S
+ \v+
+ \s
+ \v+
+ \W
+ \v++
+ \w
+ \v+
+ Any
+ \v+
+ AllAny
+ \v+
+ \R
+ \v+
+ \H
+ \v++
+ \h
+ \v++
+ \V
+ \v+
+ \v
+ \v+
+ \Z
+ \v++
+ \z
+ \v+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/ a+\D a+\d a+\S a+\s a+\W a+\w a+. a+\C a+\R a+\H a+\h a+\V a+\v a+\Z a+\z a+$/BZx
+------------------------------------------------------------------
+ Bra
+ a+
+ \D
+ a++
+ \d
+ a+
+ \S
+ a++
+ \s
+ a++
+ \W
+ a+
+ \w
+ a+
+ Any
+ a+
+ AllAny
+ a++
+ \R
+ a+
+ \H
+ a++
+ \h
+ a+
+ \V
+ a++
+ \v
+ a++
+ \Z
+ a++
+ \z
+ a++
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\n+\D \n+\d \n+\S \n+\s \n+\W \n+\w \n+. \n+\C \n+\R \n+\H \n+\h \n+\V \n+\v \n+\Z \n+\z \n+$/BZx
+------------------------------------------------------------------
+ Bra
+ \x0a+
+ \D
+ \x0a++
+ \d
+ \x0a++
+ \S
+ \x0a+
+ \s
+ \x0a+
+ \W
+ \x0a++
+ \w
+ \x0a+
+ Any
+ \x0a+
+ AllAny
+ \x0a+
+ \R
+ \x0a+
+ \H
+ \x0a++
+ \h
+ \x0a++
+ \V
+ \x0a+
+ \v
+ \x0a+
+ \Z
+ \x0a++
+ \z
+ \x0a+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/ .+\D .+\d .+\S .+\s .+\W .+\w .+. .+\C .+\R .+\H .+\h .+\V .+\v .+\Z .+\z .+$/BZx
+------------------------------------------------------------------
+ Bra
+ Any+
+ \D
+ Any+
+ \d
+ Any+
+ \S
+ Any+
+ \s
+ Any+
+ \W
+ Any+
+ \w
+ Any+
+ Any
+ Any+
+ AllAny
+ Any++
+ \R
+ Any+
+ \H
+ Any+
+ \h
+ Any+
+ \V
+ Any+
+ \v
+ Any+
+ \Z
+ Any++
+ \z
+ Any+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/ .+\D .+\d .+\S .+\s .+\W .+\w .+. .+\C .+\R .+\H .+\h .+\V .+\v .+\Z .+\z .+$/BZxs
+------------------------------------------------------------------
+ Bra
+ AllAny+
+ \D
+ AllAny+
+ \d
+ AllAny+
+ \S
+ AllAny+
+ \s
+ AllAny+
+ \W
+ AllAny+
+ \w
+ AllAny+
+ AllAny
+ AllAny+
+ AllAny
+ AllAny+
+ \R
+ AllAny+
+ \H
+ AllAny+
+ \h
+ AllAny+
+ \V
+ AllAny+
+ \v
+ AllAny+
+ \Z
+ AllAny++
+ \z
+ AllAny+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\D+$ \d+$ \S+$ \s+$ \W+$ \w+$ \C+$ \R+$ \H+$ \h+$ \V+$ \v+$ a+$ \n+$ .+$ .+$/BZxm
+------------------------------------------------------------------
+ Bra
+ \D+
+ /m $
+ \d++
+ /m $
+ \S++
+ /m $
+ \s+
+ /m $
+ \W+
+ /m $
+ \w++
+ /m $
+ AllAny+
+ /m $
+ \R+
+ /m $
+ \H+
+ /m $
+ \h+
+ /m $
+ \V+
+ /m $
+ \v+
+ /m $
+ a+
+ /m $
+ \x0a+
+ /m $
+ Any+
+ /m $
+ Any+
+ /m $
+ Ket
+ End
+------------------------------------------------------------------
+
+/(?=a+)a(a+)++a/BZ
+------------------------------------------------------------------
+ Bra
+ Assert
+ a++
+ Ket
+ a
+ CBraPos 1
+ a++
+ KetRpos
+ a
+ Ket
+ End
+------------------------------------------------------------------
+
+/a+(bb|cc)a+(?:bb|cc)a+(?>bb|cc)a+(?:bb|cc)+a+(aa)a+(?:bb|aa)/BZ
+------------------------------------------------------------------
+ Bra
+ a++
+ CBra 1
+ bb
+ Alt
+ cc
+ Ket
+ a++
+ Bra
+ bb
+ Alt
+ cc
+ Ket
+ a++
+ Once_NC
+ bb
+ Alt
+ cc
+ Ket
+ a++
+ Bra
+ bb
+ Alt
+ cc
+ KetRmax
+ a+
+ CBra 2
+ aa
+ Ket
+ a+
+ Bra
+ bb
+ Alt
+ aa
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+/a+(bb|cc)?#a+(?:bb|cc)??#a+(?:bb|cc)?+#a+(?:bb|cc)*#a+(bb|cc)?a#a+(?:aa)?/BZ
+------------------------------------------------------------------
+ Bra
+ a++
+ Brazero
+ CBra 1
+ bb
+ Alt
+ cc
+ Ket
+ #
+ a++
+ Braminzero
+ Bra
+ bb
+ Alt
+ cc
+ Ket
+ #
+ a++
+ Once
+ Brazero
+ Bra
+ bb
+ Alt
+ cc
+ Ket
+ Ket
+ #
+ a++
+ Brazero
+ Bra
+ bb
+ Alt
+ cc
+ KetRmax
+ #
+ a+
+ Brazero
+ CBra 2
+ bb
+ Alt
+ cc
+ Ket
+ a#
+ a+
+ Brazero
+ Bra
+ aa
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+/a+(?:bb)?a#a+(?:|||)#a+(?:|b)a#a+(?:|||)?a/BZ
+------------------------------------------------------------------
+ Bra
+ a+
+ Brazero
+ Bra
+ bb
+ Ket
+ a#
+ a++
+ Bra
+ Alt
+ Alt
+ Alt
+ Ket
+ #
+ a+
+ Bra
+ Alt
+ b
+ Ket
+ a#
+ a+
+ Brazero
+ Bra
+ Alt
+ Alt
+ Alt
+ Ket
+ a
+ Ket
+ End
+------------------------------------------------------------------
+
+/[ab]*/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]*+
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aaaa
+
+/[ab]*?/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]*?
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0:
+
+/[ab]?/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]?+
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: a
+
+/[ab]??/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]??
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0:
+
+/[ab]+/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]++
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aaaa
+
+/[ab]+?/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]+?
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: a
+
+/[ab]{2,3}/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]{2,3}+
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aaa
+
+/[ab]{2,3}?/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]{2,3}?
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aa
+
+/[ab]{2,}/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]{2,}+
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aaaa
+
+/[ab]{2,}?/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]{2,}?
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aa
+
+/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/BZ
+------------------------------------------------------------------
+ Bra
+ \d++
+ \s{0,5}+
+ =
+ \s*+
+ \S?
+ =
+ \w{0,4}+
+ \W*+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-d]{5,12}[e-z0-9]*#[^a-z]+[b-y]*a[2-7]?[^0-9a-z]+/BZ
+------------------------------------------------------------------
+ Bra
+ [a-d]{5,12}+
+ [0-9e-z]*+
+ #
+ [\x00-`{-\xff] (neg)++
+ [b-y]*+
+ a
+ [2-7]?+
+ [\x00-/:-`{-\xff] (neg)++
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-z]*\s#[ \t]?\S#[a-c]*\S#[C-G]+?\d#[4-8]*\D#[4-9,]*\D#[!$]{0,5}\w#[M-Xf-l]+\W#[a-c,]?\W/BZ
+------------------------------------------------------------------
+ Bra
+ [a-z]*+
+ \s
+ #
+ [\x09 ]?+
+ \S
+ #
+ [a-c]*
+ \S
+ #
+ [C-G]++
+ \d
+ #
+ [4-8]*+
+ \D
+ #
+ [,4-9]*
+ \D
+ #
+ [!$]{0,5}+
+ \w
+ #
+ [M-Xf-l]++
+ \W
+ #
+ [,a-c]?
+ \W
+ Ket
+ End
+------------------------------------------------------------------
+
+/a+(aa|bb)*c#a*(bb|cc)*a#a?(bb|cc)*d#[a-f]*(g|hh)*f/BZ
+------------------------------------------------------------------
+ Bra
+ a+
+ Brazero
+ CBra 1
+ aa
+ Alt
+ bb
+ KetRmax
+ c#
+ a*
+ Brazero
+ CBra 2
+ bb
+ Alt
+ cc
+ KetRmax
+ a#
+ a?+
+ Brazero
+ CBra 3
+ bb
+ Alt
+ cc
+ KetRmax
+ d#
+ [a-f]*
+ Brazero
+ CBra 4
+ g
+ Alt
+ hh
+ KetRmax
+ f
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-f]*(g|hh|i)*i#[a-x]{4,}(y{0,6})*y#[a-k]+(ll|mm)+n/BZ
+------------------------------------------------------------------
+ Bra
+ [a-f]*+
+ Brazero
+ CBra 1
+ g
+ Alt
+ hh
+ Alt
+ i
+ KetRmax
+ i#
+ [a-x]{4,}
+ Brazero
+ SCBra 2
+ y{0,6}
+ KetRmax
+ y#
+ [a-k]++
+ CBra 3
+ ll
+ Alt
+ mm
+ KetRmax
+ n
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-f]*(?>gg|hh)+#[a-f]*(?>gg|hh)?#[a-f]*(?>gg|hh)*a#[a-f]*(?>gg|hh)*h/BZ
+------------------------------------------------------------------
+ Bra
+ [a-f]*+
+ Once_NC
+ gg
+ Alt
+ hh
+ KetRmax
+ #
+ [a-f]*+
+ Brazero
+ Once_NC
+ gg
+ Alt
+ hh
+ Ket
+ #
+ [a-f]*
+ Brazero
+ Once_NC
+ gg
+ Alt
+ hh
+ KetRmax
+ a#
+ [a-f]*+
+ Brazero
+ Once_NC
+ gg
+ Alt
+ hh
+ KetRmax
+ h
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-c]*d/DZS
+------------------------------------------------------------------
+ Bra
+ [a-c]*+
+ d
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'd'
+Subject length lower bound = 1
+Starting chars: a b c d
+
+/[a-c]+d/DZS
+------------------------------------------------------------------
+ Bra
+ [a-c]++
+ d
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'd'
+Subject length lower bound = 2
+Starting chars: a b c
+
+/[a-c]?d/DZS
+------------------------------------------------------------------
+ Bra
+ [a-c]?+
+ d
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'd'
+Subject length lower bound = 1
+Starting chars: a b c d
+
+/[a-c]{4,6}d/DZS
+------------------------------------------------------------------
+ Bra
+ [a-c]{4,6}+
+ d
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'd'
+Subject length lower bound = 5
+Starting chars: a b c
+
+/[a-c]{0,6}d/DZS
+------------------------------------------------------------------
+ Bra
+ [a-c]{0,6}+
+ d
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'd'
+Subject length lower bound = 1
+Starting chars: a b c d
+
+/-- End of special auto-possessive tests --/
+
+/^A\o{1239}B/
+Failed: non-octal character in \o{} (closing brace missing?) at offset 8
+
+/^A\oB/
+Failed: missing opening brace after \o at offset 3
+
+/^A\x{zz}B/
+Failed: non-hex character in \x{} (closing brace missing?) at offset 5
+
+/^A\x{12Z/
+Failed: non-hex character in \x{} (closing brace missing?) at offset 7
+
+/^A\x{/
+Failed: non-hex character in \x{} (closing brace missing?) at offset 5
+
+/[ab]++/BZO
+------------------------------------------------------------------
+ Bra
+ [ab]++
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^ab]*+/BZO
+------------------------------------------------------------------
+ Bra
+ [\x00-`c-\xff] (neg)*+
+ Ket
+ End
+------------------------------------------------------------------
+
+/a{4}+/BZO
+------------------------------------------------------------------
+ Bra
+ a{4}
+ Ket
+ End
+------------------------------------------------------------------
+
+/a{4}+/BZOi
+------------------------------------------------------------------
+ Bra
+ /i a{4}
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-[:digit:]]+/
+Failed: invalid range in character class at offset 3
+
+/[A-[:digit:]]+/
+Failed: invalid range in character class at offset 3
+
+/[a-[.xxx.]]+/
+Failed: invalid range in character class at offset 3
+
+/[a-[=xxx=]]+/
+Failed: invalid range in character class at offset 3
+
+/[a-[!xxx!]]+/
+Failed: range out of order in character class at offset 3
+
+/[A-[!xxx!]]+/
+ A]]]
+ 0: A]]]
+
+/[a-\d]+/
+Failed: invalid range in character class at offset 4
+
+/(?<0abc>xx)/
+Failed: group name must start with a non-digit at offset 3
+
+/(?&1abc)xx(?<1abc>y)/
+Failed: group name must start with a non-digit at offset 3
+
+/(?<ab-cd>xx)/
+Failed: syntax error in subpattern name (missing terminator) at offset 5
+
+/(?'0abc'xx)/
+Failed: group name must start with a non-digit at offset 3
+
+/(?P<0abc>xx)/
+Failed: group name must start with a non-digit at offset 4
+
+/\k<5ghj>/
+Failed: group name must start with a non-digit at offset 3
+
+/\k'5ghj'/
+Failed: group name must start with a non-digit at offset 3
+
+/\k{2fgh}/
+Failed: group name must start with a non-digit at offset 3
+
+/(?P=8yuki)/
+Failed: group name must start with a non-digit at offset 4
+
+/\g{4df}/
+Failed: group name must start with a non-digit at offset 3
+
+/(?&1abc)xx(?<1abc>y)/
+Failed: group name must start with a non-digit at offset 3
+
+/(?P>1abc)xx(?<1abc>y)/
+Failed: group name must start with a non-digit at offset 4
+
+/\g'3gh'/
+Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 2
+
+/\g<5fg>/
+Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 2
+
+/(?(<4gh>)abc)/
+Failed: group name must start with a non-digit at offset 4
+
+/(?('4gh')abc)/
+Failed: group name must start with a non-digit at offset 4
+
+/(?(4gh)abc)/
+Failed: malformed number or name after (?( at offset 4
+
+/(?(R&6yh)abc)/
+Failed: group name must start with a non-digit at offset 5
+
+/(((a\2)|(a*)\g<-1>))*a?/BZ
+------------------------------------------------------------------
+ Bra
+ Brazero
+ SCBra 1
+ Once
+ CBra 2
+ CBra 3
+ a
+ \2
+ Ket
+ Alt
+ CBra 4
+ a*
+ Ket
+ Recurse
+ Ket
+ Ket
+ KetRmax
+ a?+
+ Ket
+ End
+------------------------------------------------------------------
+
+/-- Test the ugly "start or end of word" compatibility syntax --/
+
+/[[:<:]]red[[:>:]]/BZ
+------------------------------------------------------------------
+ Bra
+ \b
+ Assert
+ \w
+ Ket
+ red
+ \b
+ AssertB
+ Reverse
+ \w
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+ little red riding hood
+ 0: red
+ a /red/ thing
+ 0: red
+ red is a colour
+ 0: red
+ put it all on red
+ 0: red
+ ** Failers
+No match
+ no reduction
+No match
+ Alfred Winifred
+No match
+
+/[a[:<:]] should give error/
+Failed: unknown POSIX class name at offset 4
+
+/(?=ab\K)/+
+ abcd
+Start of matched string is beyond its end - displaying from end to start.
+ 0: ab
+ 0+ abcd
+
+/abcd/f<lf>
+ xx\nxabcd
+No match
+
+/ -- Test stack check external calls --/
+
+/(((((a)))))/Q0
+
+/(((((a)))))/Q1
+Failed: parentheses are too deeply nested (stack check) at offset 0
+
+/(((((a)))))/Q
+** Missing 0 or 1 after /Q
+
+/^\w+(?>\s*)(?<=\w)/BZ
+------------------------------------------------------------------
+ Bra
+ ^
+ \w+
+ Once_NC
+ \s*+
+ Ket
+ AssertB
+ Reverse
+ \w
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+/\othing/
+Failed: missing opening brace after \o at offset 1
+
+/\o{}/
+Failed: digits missing in \x{} or \o{} at offset 1
+
+/\o{whatever}/
+Failed: non-octal character in \o{} (closing brace missing?) at offset 3
+
+/\xthing/
+
+/\x{}/
+Failed: digits missing in \x{} or \o{} at offset 3
+
+/\x{whatever}/
+Failed: non-hex character in \x{} (closing brace missing?) at offset 3
+
+"((?=(?(?=(?(?=(?(?=()))))))))"
+ a
+ 0:
+ 1:
+ 2:
+
+"(?(?=)==)(((((((((?=)))))))))"
+ a
+No match
+
+/^(?:(a)|b)(?(1)A|B)/I
+Capturing subpattern count = 1
+Max back reference = 1
+Options: anchored
+No first char
+No need char
+ aA123\O3
+Matched, but too many substrings
+ 0: aA
+ aA123\O6
+ 0: aA
+ 1: a
+
+'^(?:(?<AA>a)|b)(?(<AA>)A|B)'
+ aA123\O3
+Matched, but too many substrings
+ 0: aA
+ aA123\O6
+ 0: aA
+ 1: a
+
+'^(?<AA>)(?:(?<AA>a)|b)(?(<AA>)A|B)'J
+ aA123\O3
+Matched, but too many substrings
+ 0: aA
+ aA123\O6
+Matched, but too many substrings
+ 0: aA
+ 1:
+
+'^(?:(?<AA>X)|)(?:(?<AA>a)|b)\k{AA}'J
+ aa123\O3
+Matched, but too many substrings
+ 0: aa
+ aa123\O6
+Matched, but too many substrings
+ 0: aa
+ 1: <unset>
+
+/(?<N111>(?J)(?<N111>1(111111)11|)1|1|)(?(<N111>)1)/
+
+/(?(?=0)?)+/
+Failed: nothing to repeat at offset 7
+
+/(?(?=0)(?=00)?00765)/
+ 00765
+ 0: 00765
+
+/(?(?=0)(?=00)?00765|(?!3).56)/
+ 00765
+ 0: 00765
+ 456
+ 0: 456
+ ** Failers
+No match
+ 356
+No match
+
+'^(a)*+(\w)'
+ g
+ 0: g
+ 1: <unset>
+ 2: g
+ g\O3
+Matched, but too many substrings
+ 0: g
+
+'^(?:a)*+(\w)'
+ g
+ 0: g
+ 1: g
+ g\O3
+Matched, but too many substrings
+ 0: g
+
+//C
+ \O\C+
+Callout 255: last capture = -1
+--->
+ +0 ^
+Matched, but too many substrings
+
+"((?2){0,1999}())?"
+
+/((?+1)(\1))/BZ
+------------------------------------------------------------------
+ Bra
+ Once
+ CBra 1
+ Recurse
+ CBra 2
+ \1
+ Ket
+ Ket
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+/(?(?!)a|b)/
+ bbb
+ 0: b
+ aaa
+No match
+
+"((?2)+)((?1))"
+
+"(?(?<E>.*!.*)?)"
+Failed: assertion expected after (?( or (?(?C) at offset 3
+
+"X((?2)()*+){2}+"BZ
+------------------------------------------------------------------
+ Bra
+ X
+ Once
+ CBra 1
+ Recurse
+ Braposzero
+ SCBraPos 2
+ KetRpos
+ Ket
+ CBra 1
+ Recurse
+ Braposzero
+ SCBraPos 2
+ KetRpos
+ Ket
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+"X((?2)()*+){2}"BZ
+------------------------------------------------------------------
+ Bra
+ X
+ CBra 1
+ Recurse
+ Braposzero
+ SCBraPos 2
+ KetRpos
+ Ket
+ CBra 1
+ Recurse
+ Braposzero
+ SCBraPos 2
+ KetRpos
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+"(?<=((?2))((?1)))"
+Failed: lookbehind assertion is not fixed length at offset 17
+
+/(?<=\Ka)/g+
+ aaaaa
+ 0: a
+ 0+ aaaa
+ 0: a
+ 0+ aaaa
+ 0: a
+ 0+ aaa
+ 0: a
+ 0+ aa
+ 0: a
+ 0+ a
+ 0: a
+ 0+
+
+/(?<=\Ka)/G+
+ aaaaa
+ 0: a
+ 0+ aaaa
+ 0: a
+ 0+ aaa
+ 0: a
+ 0+ aa
+ 0: a
+ 0+ a
+ 0: a
+ 0+
+
+/((?2){73}(?2))((?1))/
+
+/.((?2)(?R)\1)()/BZ
+------------------------------------------------------------------
+ Bra
+ Any
+ Once
+ CBra 1
+ Recurse
+ Recurse
+ \1
+ Ket
+ Ket
+ CBra 2
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+/(?1)()((((((\1++))\x85)+)|))/
+
+/(\9*+(?2);\3++()2|)++{/
+Failed: reference to non-existent subpattern at offset 22
+
+/\V\x85\9*+((?2)\3++()2)*:2/
+Failed: reference to non-existent subpattern at offset 26
+
+/(((?(R)){0,2}) (?''((?'R')((?'R')))))/J
+
+/(((?(X)){0,2}) (?''((?'X')((?'X')))))/J
+
+/(((?(R)){0,2}) (?''((?'X')((?'R')))))/
+
+"(?J)(?'d'(?'d'\g{d}))"
+
+".*?\h.+.\.+\R*?\xd(?i)(?=!(?=b`b`b`\`b\xa9b!)`\a`bbbbbbbbbbbbb`bbbbbbbbbbbb*R\x85bbbbbbb\C?{((?2)(?))((
+\H){8(?<=(?1){29}\xa8bbbb\x16\xd\xc6^($(?<! )(\xa9H4){4}h}1)B))\x15')"
+
+"(?J:(?|(?'R')(\k'R')|((?'R'))))"
+
+/(?<=|(\,\$(?73591620449005828816)\xa8.{7}){6}\x09)/
+Failed: number is too big at offset 32
+
+//
+\O1
+Matched, but too many substrings
+
+/^(?:(?(1)x|)+)+$()/BZ
+------------------------------------------------------------------
+ Bra
+ ^
+ SBra
+ SCond
+ 1 Cond ref
+ x
+ Alt
+ KetRmax
+ KetRmax
+ $
+ CBra 1
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+/(?=di(?<=(?1))|(?=(.))))/
+Failed: unmatched parentheses at offset 23
+
+/(?(R))*+/BZ
+------------------------------------------------------------------
+ Bra
+ Braposzero
+ SBraPos
+ SCond
+ Cond recurse any
+ Ket
+ KetRpos
+ Ket
+ End
+------------------------------------------------------------------
+
+/[[:\\](?'abc')[a:]/
+
+"[[[.\xe8Nq\xffq\xff\xe0\x2|||::Nq\xffq\xff\xe0\x6\x2|||::[[[:[::::::[[[[[::::::::[:[[[:[:::[[[[[[[[[[[[:::::::::::::::::[[.\xe8Nq\xffq\xff\xe0\x2|||::Nq\xffq\xff\xe0\x6\x2|||::[[[:[::::::[[[[[::::::::[:[[[:[:::[[[[[[[[[[[[[[:::E[[[:[:[[:[:::[[:::E[[[:[:[[:'[:::::E[[[:[::::::[[[:[[[[[[[::E[[[:[::::::[[[:[[[[[[[[:[[::[::::[[:::::::[[:[[[[[[[:[[::[:[[:[~"
+Failed: missing terminating ] for character class at offset 353
+
+/()(?(R)0)*+/BZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ Ket
+ Braposzero
+ SBraPos
+ SCond
+ Cond recurse any
+ 0
+ Ket
+ KetRpos
+ Ket
+ End
+------------------------------------------------------------------
+
+/(?R-:(?</
+Failed: (?R or (?[+-]digits must be followed by ) at offset 3
+
+/(?1){3918}(((((0(\k'R'))))(?J)(?'R'(?'R'\3){99})))/I
+Capturing subpattern count = 8
+Max back reference = 8
+Named capturing subpatterns:
+ R 7
+ R 8
+No options
+Duplicate name status changes
+No first char
+Need char = '0'
+
+/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/
+
+/0(?0)|(1)(*THEN)(*SKIP:0)(*FAIL)/
+ 01
+No match
+
+/((?(R8000000000)))/
+Failed: number is too big at offset 16
+
+/(?(8000000000/
+Failed: number is too big at offset 13
+
+/(?:ab)?(?:ab)(?:ab)/
+ abab
+ 0: abab
+ ababab
+ 0: ababab
+ aba
+No match
+
+/((*MARK:A))++a(*SKIP:B)b/
+ aacb
+No match
+
+/(?J:(?|(:(?|(?'R')(\z(?|(?'R')(\k'R')|((?'R')))k'R')|((?'R')))H'Ak'Rf)|s(?'R')))/
+
+/(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?<a>1)/
+
+/a[[:punct:]b]/BZ
+------------------------------------------------------------------
+ Bra
+ a
+ [!-/:-@[-`b{-~]
+ Ket
+ End
+------------------------------------------------------------------
+
+/L(?#(|++<!(2)?/BZ
+------------------------------------------------------------------
+ Bra
+ L?+
+ Ket
+ End
+------------------------------------------------------------------
+
+/L(?#(|++<!(2)?/BOZ
+------------------------------------------------------------------
+ Bra
+ L?
+ Ket
+ End
+------------------------------------------------------------------
+
+/L(?#(|++<!(2)?/BCZ
+------------------------------------------------------------------
+ Bra
+ Callout 255 0 14
+ L?+
+ Callout 255 14 0
+ Ket
+ End
+------------------------------------------------------------------
+
+/L(?#(|++<!(2)?/BCOZ
+------------------------------------------------------------------
+ Bra
+ Callout 255 0 14
+ L?
+ Callout 255 14 0
+ Ket
+ End
+------------------------------------------------------------------
+
+/(A*)\E+/CBZ
+------------------------------------------------------------------
+ Bra
+ Callout 255 0 7
+ SCBra 1
+ Callout 255 1 2
+ A*
+ Callout 255 3 0
+ KetRmax
+ Callout 255 7 0
+ Ket
+ End
+------------------------------------------------------------------
+
+/()\Q\E*]/BCZ
+------------------------------------------------------------------
+ Bra
+ Callout 255 0 7
+ Brazero
+ SCBra 1
+ Callout 255 1 0
+ KetRmax
+ Callout 255 7 1
+ ]
+ Callout 255 8 0
+ Ket
+ End
+------------------------------------------------------------------
+
+/(?<A>)(?J:(?<B>)(?<B>))(?<C>)/
+ \O\CC
+Matched, but too many substrings
+copy substring C failed -7
+
+/(?=a\K)/
+ ring bpattingbobnd $ 1,oern cou \rb\L
+Start of matched string is beyond its end - displaying from end to start.
+ 0: a
+ 0L
+
+/(?<=((?C)0))/
+ 9010
+--->9010
+ 0 ^ 0
+ 0 ^ 0
+ 0:
+ 1: 0
+ abcd
+--->abcd
+ 0 ^ 0
+ 0 ^ 0
+ 0 ^ 0
+ 0 ^ 0
+No match
+
+/((?J)(?'R'(?'R'(?'R'(?'R'(?'R'(?|(\k'R'))))))))/
+
+/\N(?(?C)0?!.)*/
+Failed: assertion expected after (?( or (?(?C) at offset 4
+
+/(?<RA>abc)(?(R)xyz)/BZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ abc
+ Ket
+ Cond
+ Cond recurse any
+ xyz
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+/(?<R>abc)(?(R)xyz)/BZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ abc
+ Ket
+ Cond
+ 1 Cond ref
+ xyz
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+/(?=.*[A-Z])/I
+Capturing subpattern count = 0
+May match empty string
+No options
+No first char
+No need char
+
/-- End of testinput2 --/
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput3 b/lib/stdlib/test/re_SUITE_data/testoutput3
index 7b0a3e926e..73119ab4b7 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput3
+++ b/lib/stdlib/test/re_SUITE_data/testoutput3
@@ -1,6 +1,11 @@
-/-- This set of tests checks local-specific features, using the fr_FR locale.
- It is not Perl-compatible. There is different version called wintestinput3
- f or use on Windows, where the locale is called "french". --/
+/-- This set of tests checks local-specific features, using the "fr_FR" locale.
+ It is not Perl-compatible. When run via RunTest, the locale is edited to
+ be whichever of "fr_FR", "french", or "fr" is found to exist. There is
+ different version of this file called wintestinput3 for use on Windows,
+ where the locale is called "french" and the tests are run using
+ RunTest.bat. --/
+
+< forbid 8W
/^[\w]+/
*** Failers
@@ -88,7 +93,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+Starting chars: 0 1 2 3 4 5 6 7 8 9 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
/\w/ISLfr_FR
@@ -97,7 +102,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+Starting chars: 0 1 2 3 4 5 6 7 8 9 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
� � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
� � � � � � � � � � � � � � � � � � � � � � � � � � � �
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput4 b/lib/stdlib/test/re_SUITE_data/testoutput4
index 6694111fb5..d43c12392d 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput4
+++ b/lib/stdlib/test/re_SUITE_data/testoutput4
@@ -1,6 +1,8 @@
/-- This set of tests is for UTF support, excluding Unicode properties. It is
compatible with all versions of Perl >= 5.10 and both the 8-bit and 16-bit
PCRE libraries. --/
+
+< forbid 9?=ABCDEFfGILMNPTUWXZ<
/a.b/8
acb
@@ -1257,4 +1259,22 @@ No match
\x{100}\x{100}\x{100}
No match
+/^a+[a\x{200}]/8
+ aa
+ 0: aa
+
+/^.\B.\B./8
+ \x{10123}\x{10124}\x{10125}
+ 0: \x{10123}\x{10124}\x{10125}
+
+/^#[^\x{ffff}]#[^\x{ffff}]#[^\x{ffff}]#/8
+ #\x{10000}#\x{100}#\x{10ffff}#
+ 0: #\x{10000}#\x{100}#\x{10ffff}#
+
+"[\S\V\H]"8
+
+/\C(\W?ſ)'?{{/8
+ \\C(\\W?ſ)'?{{
+No match
+
/-- End of testinput4 --/
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput5 b/lib/stdlib/test/re_SUITE_data/testoutput5
index d583119dd9..bab989ca7e 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput5
+++ b/lib/stdlib/test/re_SUITE_data/testoutput5
@@ -1,26 +1,47 @@
/-- This set of tests checks the API, internals, and non-Perl stuff for UTF
support, excluding Unicode properties. However, tests that give different
results in 8-bit and 16-bit modes are excluded (see tests 16 and 17). --/
+
+< forbid W
/\x{110000}/8DZ
-Failed: character value in \x{...} sequence is too large at offset 9
+Failed: character value in \x{} or \o{} is too large at offset 9
+
+/\o{4200000}/8DZ
+Failed: character value in \x{} or \o{} is too large at offset 10
/\x{ffffffff}/8
-Failed: character value in \x{...} sequence is too large at offset 11
+Failed: character value in \x{} or \o{} is too large at offset 11
+
+/\o{37777777777}/8
+Failed: character value in \x{} or \o{} is too large at offset 14
/\x{100000000}/8
-Failed: character value in \x{...} sequence is too large at offset 12
+Failed: character value in \x{} or \o{} is too large at offset 12
+
+/\o{77777777777}/8
+Failed: character value in \x{} or \o{} is too large at offset 14
/\x{d800}/8
Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
+/\o{154000}/8
+Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 9
+
/\x{dfff}/8
Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
+/\o{157777}/8
+Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 9
+
/\x{d7ff}/8
+/\o{153777}/8
+
/\x{e000}/8
+/\o{170000}/8
+
/^\x{100}a\x{1234}/8
\x{100}a\x{1234}bcd
0: \x{100}a\x{1234}
@@ -146,11 +167,12 @@ No match
/\x{100}*/8DZ
------------------------------------------------------------------
Bra
- \x{100}*
+ \x{100}*+
Ket
End
------------------------------------------------------------------
Capturing subpattern count = 0
+May match empty string
Options: utf
No first char
No need char
@@ -159,7 +181,7 @@ No need char
------------------------------------------------------------------
Bra
a
- \x{100}*
+ \x{100}*+
Ket
End
------------------------------------------------------------------
@@ -172,7 +194,7 @@ No need char
------------------------------------------------------------------
Bra
ab
- \x{100}*
+ \x{100}*+
Ket
End
------------------------------------------------------------------
@@ -248,7 +270,7 @@ No match
/[z-\x{100}]/8DZ
------------------------------------------------------------------
Bra
- [z-\x{100}]
+ [z-\xff\x{100}]
Ket
End
------------------------------------------------------------------
@@ -373,6 +395,7 @@ Need char = 'z'
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
Options: utf
No first char
No need char
@@ -404,6 +427,7 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
Options: utf
No first char
No need char
@@ -424,6 +448,7 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
Options: utf
No first char
No need char
@@ -455,6 +480,7 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
Options: utf
No first char
No need char
@@ -768,7 +794,7 @@ No match
/[\h]{3,}/8BZ
------------------------------------------------------------------
Bra
- [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]{3,}
+ [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]{3,}+
Ket
End
------------------------------------------------------------------
@@ -786,7 +812,7 @@ No match
/[\H]/8BZ
------------------------------------------------------------------
Bra
- [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}]
+ [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}]
Ket
End
------------------------------------------------------------------
@@ -794,7 +820,7 @@ No match
/[\V]/8BZ
------------------------------------------------------------------
Bra
- [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{10ffff}]
+ [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}]
Ket
End
------------------------------------------------------------------
@@ -1510,7 +1536,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/[^\x{1234}]+?/iS8I
Capturing subpattern count = 0
@@ -1518,7 +1544,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/[^\x{1234}]++/iS8I
Capturing subpattern count = 0
@@ -1526,7 +1552,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/[^\x{1234}]{2}/iS8I
Capturing subpattern count = 0
@@ -1534,7 +1560,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 2
-No set of starting bytes
+No starting char list
//<bsr_anycrlf><bsr_unicode>
Failed: inconsistent NEWLINE options at offset 0
@@ -1572,7 +1598,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
/[\h\x{e000}]+/8BZ
------------------------------------------------------------------
Bra
- [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{e000}]+
+ [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{e000}]++
Ket
End
------------------------------------------------------------------
@@ -1594,7 +1620,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
/[\H\x{d7ff}]+/8BZ
------------------------------------------------------------------
Bra
- [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}\x{d7ff}]+
+ [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}\x{d7ff}]++
Ket
End
------------------------------------------------------------------
@@ -1616,7 +1642,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
/[\v\x{e000}]+/8BZ
------------------------------------------------------------------
Bra
- [\x0a-\x0d\x85\x{2028}-\x{2029}\x{e000}]+
+ [\x0a-\x0d\x85\x{2028}-\x{2029}\x{e000}]++
Ket
End
------------------------------------------------------------------
@@ -1634,7 +1660,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
/[\V\x{d7ff}]+/8BZ
------------------------------------------------------------------
Bra
- [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]+
+ [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]++
Ket
End
------------------------------------------------------------------
@@ -1808,10 +1834,8 @@ Partial match: \x{0d}\x{0d}
/i [^\x{8000}]*
/i [^\x{7fff}]{2}
/i [^\x{7fff}]{0,7}?
- Once
/i [^\x{fffff}]{5}
- /i [^\x{fffff}]?
- Ket
+ /i [^\x{fffff}]?+
Ket
End
------------------------------------------------------------------
@@ -1846,4 +1870,76 @@ No match
/\ud800/<JS>8
Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 5
+/^a+[a\x{200}]/8BZ
+------------------------------------------------------------------
+ Bra
+ ^
+ a+
+ [a\x{200}]
+ Ket
+ End
+------------------------------------------------------------------
+ aa
+ 0: aa
+
+/[b-d\x{200}-\x{250}]*[ae-h]?#[\x{200}-\x{250}]{0,8}[\x00-\xff]*#[\x{200}-\x{250}]+[a-z]/8BZ
+------------------------------------------------------------------
+ Bra
+ [b-d\x{200}-\x{250}]*+
+ [ae-h]?+
+ #
+ [\x{200}-\x{250}]{0,8}+
+ [\x00-\xff]*
+ #
+ [\x{200}-\x{250}]++
+ [a-z]
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^\xff]*PRUNE:\x{100}abc(xyz(?1))/8DZ
+------------------------------------------------------------------
+ Bra
+ [^\x{ff}]*
+ PRUNE:\x{100}abc
+ CBra 1
+ xyz
+ Recurse
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+Need char = 'z'
+
+/(?<=\K\x{17f})/8g+
+ \x{17f}\x{17f}\x{17f}\x{17f}\x{17f}
+ 0: \x{17f}
+ 0+ \x{17f}\x{17f}\x{17f}\x{17f}
+ 0: \x{17f}
+ 0+ \x{17f}\x{17f}\x{17f}\x{17f}
+ 0: \x{17f}
+ 0+ \x{17f}\x{17f}\x{17f}
+ 0: \x{17f}
+ 0+ \x{17f}\x{17f}
+ 0: \x{17f}
+ 0+ \x{17f}
+ 0: \x{17f}
+ 0+
+
+/(?<=\K\x{17f})/8G+
+ \x{17f}\x{17f}\x{17f}\x{17f}\x{17f}
+ 0: \x{17f}
+ 0+ \x{17f}\x{17f}\x{17f}\x{17f}
+ 0: \x{17f}
+ 0+ \x{17f}\x{17f}\x{17f}
+ 0: \x{17f}
+ 0+ \x{17f}\x{17f}
+ 0: \x{17f}
+ 0+ \x{17f}
+ 0: \x{17f}
+ 0+
+
/-- End of testinput5 --/
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput6 b/lib/stdlib/test/re_SUITE_data/testoutput6
index b1d4579926..422d383357 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput6
+++ b/lib/stdlib/test/re_SUITE_data/testoutput6
@@ -1,5 +1,7 @@
/-- This set of tests is for Unicode property support. It is compatible with
Perl >= 5.15. --/
+
+< forbid 9?=ABCDEFfGILMNPTUXZ<
/^\pC\pL\pM\pN\pP\pS\pZ</8
\x7f\x{c0}\x{30f}\x{660}\x{66c}\x{f01}\x{1680}<
@@ -543,16 +545,6 @@ No match
abc
No match
-/\p{Lu}/8i
- A
- 0: A
- aZ
- 0: Z
- ** Failers
- 0: F
- abc
-No match
-
/\p{Ll}/8
a
0: a
@@ -729,6 +721,8 @@ No match
0: \x{60b}
** Failers
No match
+ \x{061c}
+No match
X\x{06e9}
No match
@@ -1310,7 +1304,7 @@ No match
/^>\s+/8W
>\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b}
- 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{09}
+ 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{09}\x{0b}
/^>\pZ+/8W
>\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b}
@@ -1338,15 +1332,15 @@ No match
/^[[:graph:]]*/8W
A\x{a1}\x{a0}
- 0: A
+ 0: A\x{a1}
/^[[:print:]]*/8W
A z\x{a0}\x{a1}
- 0: A z
+ 0: A z\x{a0}\x{a1}
/^[[:punct:]]*/8W
.+\x{a1}\x{a0}
- 0: .+
+ 0: .+\x{a1}
/\p{Zs}*?\R/
** Failers
@@ -1548,6 +1542,19 @@ No match
0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X
0+
+/\X*Z/8Y
+ A\x{300}
+No match
+
+/\X*(.)/8Y
+ A\x{1111}\x{ae4c}\x{1169}
+ 0: A\x{1111}
+ 1: \x{1111}
+
+/\X?abc/8Y
+\xff\x7f\x00\x00\x03\x00\x41\xcc\x80\x41\x{300}\x61\x62\x63\x00\>06\?
+ 0: A\x{300}abc
+
/-- --/
/\x{1e9e}+/8i
@@ -2139,11 +2146,439 @@ No match
0: 1234
123
No match
-
+
/^\X*\w{4}/8
1234
0: 1234
123
No match
+
+/^A\s+Z/8W
+ A\x{2005}Z
+ 0: A\x{2005}Z
+ A\x{85}\x{180e}\x{2005}Z
+ 0: A\x{85}\x{180e}\x{2005}Z
+
+/^A[\s]+Z/8W
+ A\x{2005}Z
+ 0: A\x{2005}Z
+ A\x{85}\x{180e}\x{2005}Z
+ 0: A\x{85}\x{180e}\x{2005}Z
+
+/^[[:graph:]]+$/8W
+ Letter:ABC
+ 0: Letter:ABC
+ Mark:\x{300}\x{1d172}\x{1d17b}
+ 0: Mark:\x{300}\x{1d172}\x{1d17b}
+ Number:9\x{660}
+ 0: Number:9\x{660}
+ Punctuation:\x{66a},;
+ 0: Punctuation:\x{66a},;
+ Symbol:\x{6de}<>\x{fffc}
+ 0: Symbol:\x{6de}<>\x{fffc}
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ 0: Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ 0: \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ 0: \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ 0: \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ 0: \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ \x{feff}
+ 0: \x{feff}
+ \x{fff9}\x{fffa}\x{fffb}
+ 0: \x{fff9}\x{fffa}\x{fffb}
+ \x{110bd}
+ 0: \x{110bd}
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ 0: \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ \x{e0001}
+ 0: \x{e0001}
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+ 0: \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+ ** Failers
+No match
+ \x{09}
+No match
+ \x{0a}
+No match
+ \x{1D}
+No match
+ \x{20}
+No match
+ \x{85}
+No match
+ \x{a0}
+No match
+ \x{61c}
+No match
+ \x{1680}
+No match
+ \x{180e}
+No match
+ \x{2028}
+No match
+ \x{2029}
+No match
+ \x{202f}
+No match
+ \x{2065}
+No match
+ \x{2066}
+No match
+ \x{2067}
+No match
+ \x{2068}
+No match
+ \x{2069}
+No match
+ \x{3000}
+No match
+ \x{e0002}
+No match
+ \x{e001f}
+No match
+ \x{e0080}
+No match
+
+/^[[:print:]]+$/8W
+ Space: \x{a0}
+ 0: Space: \x{a0}
+ \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005}
+ 0: \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005}
+ \x{2006}\x{2007}\x{2008}\x{2009}\x{200a}
+ 0: \x{2006}\x{2007}\x{2008}\x{2009}\x{200a}
+ \x{202f}\x{205f}
+ 0: \x{202f}\x{205f}
+ \x{3000}
+ 0: \x{3000}
+ Letter:ABC
+ 0: Letter:ABC
+ Mark:\x{300}\x{1d172}\x{1d17b}
+ 0: Mark:\x{300}\x{1d172}\x{1d17b}
+ Number:9\x{660}
+ 0: Number:9\x{660}
+ Punctuation:\x{66a},;
+ 0: Punctuation:\x{66a},;
+ Symbol:\x{6de}<>\x{fffc}
+ 0: Symbol:\x{6de}<>\x{fffc}
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ 0: Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ \x{180e}
+ 0: \x{180e}
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ 0: \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ 0: \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ \x{202f}
+ 0: \x{202f}
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ 0: \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ 0: \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ \x{feff}
+ 0: \x{feff}
+ \x{fff9}\x{fffa}\x{fffb}
+ 0: \x{fff9}\x{fffa}\x{fffb}
+ \x{110bd}
+ 0: \x{110bd}
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ 0: \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ \x{e0001}
+ 0: \x{e0001}
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+ 0: \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+ ** Failers
+ 0: ** Failers
+ \x{09}
+No match
+ \x{1D}
+No match
+ \x{85}
+No match
+ \x{61c}
+No match
+ \x{2028}
+No match
+ \x{2029}
+No match
+ \x{2065}
+No match
+ \x{2066}
+No match
+ \x{2067}
+No match
+ \x{2068}
+No match
+ \x{2069}
+No match
+ \x{e0002}
+No match
+ \x{e001f}
+No match
+ \x{e0080}
+No match
+
+/^[[:punct:]]+$/8W
+ \$+<=>^`|~
+ 0: $+<=>^`|~
+ !\"#%&'()*,-./:;?@[\\]_{}
+ 0: !"#%&'()*,-./:;?@[\]_{}
+ \x{a1}\x{a7}
+ 0: \x{a1}\x{a7}
+ \x{37e}
+ 0: \x{37e}
+ ** Failers
+No match
+ abcde
+No match
+
+/^[[:^graph:]]+$/8W
+ \x{09}\x{0a}\x{1D}\x{20}\x{85}\x{a0}\x{61c}\x{1680}\x{180e}
+ 0: \x{09}\x{0a}\x{1d} \x{85}\x{a0}\x{61c}\x{1680}\x{180e}
+ \x{2028}\x{2029}\x{202f}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}
+ 0: \x{2028}\x{2029}\x{202f}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}
+ \x{3000}\x{e0002}\x{e001f}\x{e0080}
+ 0: \x{3000}\x{e0002}\x{e001f}\x{e0080}
+ ** Failers
+No match
+ Letter:ABC
+No match
+ Mark:\x{300}\x{1d172}\x{1d17b}
+No match
+ Number:9\x{660}
+No match
+ Punctuation:\x{66a},;
+No match
+ Symbol:\x{6de}<>\x{fffc}
+No match
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+No match
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+No match
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+No match
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+No match
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+No match
+ \x{feff}
+No match
+ \x{fff9}\x{fffa}\x{fffb}
+No match
+ \x{110bd}
+No match
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+No match
+ \x{e0001}
+No match
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+No match
+
+/^[[:^print:]]+$/8W
+ \x{09}\x{1D}\x{85}\x{61c}\x{2028}\x{2029}\x{2065}\x{2066}\x{2067}
+ 0: \x{09}\x{1d}\x{85}\x{61c}\x{2028}\x{2029}\x{2065}\x{2066}\x{2067}
+ \x{2068}\x{2069}\x{e0002}\x{e001f}\x{e0080}
+ 0: \x{2068}\x{2069}\x{e0002}\x{e001f}\x{e0080}
+ ** Failers
+No match
+ Space: \x{a0}
+No match
+ \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005}
+No match
+ \x{2006}\x{2007}\x{2008}\x{2009}\x{200a}
+No match
+ \x{202f}\x{205f}
+No match
+ \x{3000}
+No match
+ Letter:ABC
+No match
+ Mark:\x{300}\x{1d172}\x{1d17b}
+No match
+ Number:9\x{660}
+No match
+ Punctuation:\x{66a},;
+No match
+ Symbol:\x{6de}<>\x{fffc}
+No match
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+No match
+ \x{180e}
+No match
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+No match
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+No match
+ \x{202f}
+No match
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+No match
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+No match
+ \x{feff}
+No match
+ \x{fff9}\x{fffa}\x{fffb}
+No match
+ \x{110bd}
+No match
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+No match
+ \x{e0001}
+No match
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+No match
+
+/^[[:^punct:]]+$/8W
+ abcde
+ 0: abcde
+ ** Failers
+No match
+ \$+<=>^`|~
+No match
+ !\"#%&'()*,-./:;?@[\\]_{}
+No match
+ \x{a1}\x{a7}
+No match
+ \x{37e}
+No match
+
+/[RST]+/8iW
+ Ss\x{17f}
+ 0: Ss\x{17f}
+
+/[R-T]+/8iW
+ Ss\x{17f}
+ 0: Ss\x{17f}
+
+/[q-u]+/8iW
+ Ss\x{17f}
+ 0: Ss\x{17f}
+
+/^s?c/mi8
+ scat
+ 0: sc
+
+/[A-`]/i8
+ abcdefghijklmno
+ 0: a
+
+/\C\X*QT/8
+ Ӆ\x0aT
+No match
+
+/[\pS#moq]/
+ =
+ 0: =
+
+/[[:punct:]]/8W
+ \xc2\xb4
+No match
+ \x{b4}
+No match
+
+/[[:^ascii:]]/8W
+ \x{100}
+ 0: \x{100}
+ \x{200}
+ 0: \x{200}
+ \x{300}
+ 0: \x{300}
+ \x{37e}
+ 0: \x{37e}
+ a
+No match
+ 9
+No match
+ g
+No match
+
+/[[:^ascii:]\w]/8W
+ a
+ 0: a
+ 9
+ 0: 9
+ g
+ 0: g
+ \x{100}
+ 0: \x{100}
+ \x{200}
+ 0: \x{200}
+ \x{300}
+ 0: \x{300}
+ \x{37e}
+ 0: \x{37e}
+
+/[\w[:^ascii:]]/8W
+ a
+ 0: a
+ 9
+ 0: 9
+ g
+ 0: g
+ \x{100}
+ 0: \x{100}
+ \x{200}
+ 0: \x{200}
+ \x{300}
+ 0: \x{300}
+ \x{37e}
+ 0: \x{37e}
+
+/[^[:ascii:]\W]/8W
+ a
+No match
+ 9
+No match
+ g
+No match
+ \x{100}
+ 0: \x{100}
+ \x{200}
+ 0: \x{200}
+ \x{300}
+No match
+ \x{37e}
+No match
+
+/[[:^ascii:]a]/8W
+ a
+ 0: a
+ 9
+No match
+ g
+No match
+ \x{100}
+ 0: \x{100}
+ \x{200}
+ 0: \x{200}
+ \x{37e}
+ 0: \x{37e}
+
+/[^[:^ascii:]\d]/8W
+ a
+ 0: a
+ ~
+ 0: ~
+ 0
+No match
+ \a
+ 0: \x{07}
+ \x{7f}
+ 0: \x{7f}
+ \x{389}
+No match
+ \x{20ac}
+No match
+
+/(?=.*b)\pL/
+ 11bb
+ 0: b
+/(?(?=.*b)(?=.*b)\pL|.*c)/
+ 11bb
+ 0: b
+
/-- End of testinput6 --/
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput7 b/lib/stdlib/test/re_SUITE_data/testoutput7
index ddd96fc2ed..2b167b28d1 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput7
+++ b/lib/stdlib/test/re_SUITE_data/testoutput7
@@ -78,7 +78,7 @@ No need char
/[\p{Nd}+-]+/8DZ
------------------------------------------------------------------
Bra
- [+\-\p{Nd}]+
+ [+\-\p{Nd}]++
Ket
End
------------------------------------------------------------------
@@ -124,7 +124,7 @@ No match
/[z-\x{100}]/8iDZ
------------------------------------------------------------------
Bra
- [Z\x{39c}\x{3bc}\x{1e9e}\x{178}z-\x{101}]
+ [Zz-\xff\x{39c}\x{3bc}\x{212b}\x{1e9e}\x{212b}\x{178}\x{100}-\x{101}]
Ket
End
------------------------------------------------------------------
@@ -162,7 +162,7 @@ No match
/[z-\x{100}]/8DZi
------------------------------------------------------------------
Bra
- [Z\x{39c}\x{3bc}\x{1e9e}\x{178}z-\x{101}]
+ [Zz-\xff\x{39c}\x{3bc}\x{212b}\x{1e9e}\x{212b}\x{178}\x{100}-\x{101}]
Ket
End
------------------------------------------------------------------
@@ -270,6 +270,20 @@ No need char
End
------------------------------------------------------------------
+/^\p{Cf}/8
+ \x{180e}
+ 0: \x{180e}
+ \x{061c}
+ 0: \x{61c}
+ \x{2066}
+ 0: \x{2066}
+ \x{2067}
+ 0: \x{2067}
+ \x{2068}
+ 0: \x{2068}
+ \x{2069}
+ 0: \x{2069}
+
/^\p{Cs}/8
\?\x{dfff}
0: \x{dfff}
@@ -278,6 +292,22 @@ No match
\x{09f}
No match
+/^\p{Mn}/8
+ \x{1a1b}
+ 0: \x{1a1b}
+
+/^\p{Pe}/8
+ \x{2309}
+ 0: \x{2309}
+ \x{230b}
+ 0: \x{230b}
+
+/^\p{Ps}/8
+ \x{2308}
+ 0: \x{2308}
+ \x{230a}
+ 0: \x{230a}
+
/^\p{Sc}+/8
$\x{a2}\x{a3}\x{a4}\x{a5}\x{a6}
0: $\x{a2}\x{a3}\x{a4}\x{a5}
@@ -297,8 +327,6 @@ No match
0: \x{a0}
\x{1680}
0: \x{1680}
- \x{180e}
- 0: \x{180e}
\x{2000}
0: \x{2000}
\x{2001}
@@ -310,8 +338,9 @@ No match
\x{200d}
No match
-/-- These four are here rather than in test 6 because Perl has problems with
- the negative versions of the properties. --/
+/-- These are here rather than in test 6 because Perl has problems with
+ the negative versions of the properties and behaves has changed how
+ it behaves for caseless matching. --/
/\p{^Lu}/8i
1234
@@ -351,6 +380,16 @@ No match
\x{1d00}
No match
+/\p{Lu}/8i
+ A
+ 0: A
+ aZ
+ 0: Z
+ ** Failers
+ 0: F
+ abc
+No match
+
/[\x{c0}\x{391}]/8i
\x{c0}
0: \x{c0}
@@ -501,7 +540,7 @@ No match
/^>\p{Xsp}+/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
/^>\p{Xsp}+?/8
>\x{1680}\x{2028}\x{0b}
@@ -509,11 +548,11 @@ No match
/^>\p{Xsp}*/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
/^>\p{Xsp}{2,9}/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
/^>\p{Xsp}{2,9}?/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
@@ -525,7 +564,7 @@ No match
/^>[\p{Xsp}]+/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
/^>\p{Xps}/8
>\x{1680}\x{2028}\x{0b}
@@ -820,7 +859,7 @@ No match
/[[:graph:]]/WBZ
------------------------------------------------------------------
Bra
- [!-~]
+ [[:graph:]]
Ket
End
------------------------------------------------------------------
@@ -828,7 +867,7 @@ No match
/[[:print:]]/WBZ
------------------------------------------------------------------
Bra
- [ -~]
+ [[:print:]]
Ket
End
------------------------------------------------------------------
@@ -836,7 +875,7 @@ No match
/[[:punct:]]/WBZ
------------------------------------------------------------------
Bra
- [!-/:-@[-`{-~]
+ [[:punct:]]
Ket
End
------------------------------------------------------------------
@@ -910,7 +949,7 @@ No match
/[[:^alpha:][:^cntrl:]]+/8WBZ
------------------------------------------------------------------
Bra
- [ -~\x80-\xff\P{L}]+
+ [ -~\x80-\xff\P{L}\x{100}-\x{10ffff}]++
Ket
End
------------------------------------------------------------------
@@ -922,7 +961,7 @@ No match
/[[:^cntrl:][:^alpha:]]+/8WBZ
------------------------------------------------------------------
Bra
- [ -~\x80-\xff\P{L}]+
+ [ -~\x80-\xff\x{100}-\x{10ffff}\P{L}]++
Ket
End
------------------------------------------------------------------
@@ -934,7 +973,7 @@ No match
/[[:alpha:]]+/8WBZ
------------------------------------------------------------------
Bra
- [\p{L}]+
+ [\p{L}]++
Ket
End
------------------------------------------------------------------
@@ -944,7 +983,7 @@ No match
/[[:^alpha:]\S]+/8WBZ
------------------------------------------------------------------
Bra
- [\P{L}\P{Xsp}]+
+ [\P{L}\P{Xsp}]++
Ket
End
------------------------------------------------------------------
@@ -956,7 +995,7 @@ No match
/[^\d]+/8WBZ
------------------------------------------------------------------
Bra
- [^\p{Nd}]+
+ [^\p{Nd}]++
Ket
End
------------------------------------------------------------------
@@ -1070,8 +1109,8 @@ No match
prop Nd
B+
prop N *+
- B+
- prop Nd *
+ B++
+ prop Nd *+
Ket
End
------------------------------------------------------------------
@@ -1347,7 +1386,7 @@ Need char = 'B' (caseless)
/[\x{3a3}]+/8iBZ
------------------------------------------------------------------
Bra
- clist 03a3 03c2 03c3 +
+ clist 03a3 03c2 03c3 ++
Ket
End
------------------------------------------------------------------
@@ -1355,7 +1394,7 @@ Need char = 'B' (caseless)
/[^\x{3a3}]+/8iBZ
------------------------------------------------------------------
Bra
- not clist 03a3 03c2 03c3 +
+ not clist 03a3 03c2 03c3 ++
Ket
End
------------------------------------------------------------------
@@ -1577,5 +1616,730 @@ No match
No match
\x{1234}abc
No match
+
+/-- Some auto-possessification tests --/
+
+/\pN+\z/BZ
+------------------------------------------------------------------
+ Bra
+ prop N ++
+ \z
+ Ket
+ End
+------------------------------------------------------------------
+
+/\PN+\z/BZ
+------------------------------------------------------------------
+ Bra
+ notprop N ++
+ \z
+ Ket
+ End
+------------------------------------------------------------------
+
+/\pN+/BZ
+------------------------------------------------------------------
+ Bra
+ prop N ++
+ Ket
+ End
+------------------------------------------------------------------
+
+/\PN+/BZ
+------------------------------------------------------------------
+ Bra
+ notprop N ++
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Any}+\p{Any} \p{Any}+\P{Any} \p{Any}+\p{L&} \p{Any}+\p{L} \p{Any}+\p{Lu} \p{Any}+\p{Han} \p{Any}+\p{Xan} \p{Any}+\p{Xsp} \p{Any}+\p{Xps} \p{Xwd}+\p{Any} \p{Any}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Any +
+ prop Any
+ prop Any +
+ notprop Any
+ prop Any +
+ prop L&
+ prop Any +
+ prop L
+ prop Any +
+ prop Lu
+ prop Any +
+ prop Han
+ prop Any +
+ prop Xan
+ prop Any +
+ prop Xsp
+ prop Any +
+ prop Xps
+ prop Xwd +
+ prop Any
+ prop Any +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{L&}+\p{Any} \p{L&}+\p{L&} \P{L&}+\p{L&} \p{L&}+\p{L} \p{L&}+\p{Lu} \p{L&}+\p{Han} \p{L&}+\p{Xan} \p{L&}+\P{Xan} \p{L&}+\p{Xsp} \p{L&}+\p{Xps} \p{Xwd}+\p{L&} \p{L&}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop L& +
+ prop Any
+ prop L& +
+ prop L&
+ notprop L& ++
+ prop L&
+ prop L& +
+ prop L
+ prop L& +
+ prop Lu
+ prop L& +
+ prop Han
+ prop L& +
+ prop Xan
+ prop L& ++
+ notprop Xan
+ prop L& ++
+ prop Xsp
+ prop L& ++
+ prop Xps
+ prop Xwd +
+ prop L&
+ prop L& +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{N}+\p{Any} \p{N}+\p{L&} \p{N}+\p{L} \p{N}+\P{L} \p{N}+\P{N} \p{N}+\p{Lu} \p{N}+\p{Han} \p{N}+\p{Xan} \p{N}+\p{Xsp} \p{N}+\p{Xps} \p{Xwd}+\p{N} \p{N}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop N +
+ prop Any
+ prop N +
+ prop L&
+ prop N ++
+ prop L
+ prop N +
+ notprop L
+ prop N ++
+ notprop N
+ prop N ++
+ prop Lu
+ prop N +
+ prop Han
+ prop N +
+ prop Xan
+ prop N ++
+ prop Xsp
+ prop N ++
+ prop Xps
+ prop Xwd +
+ prop N
+ prop N +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Lu}+\p{Any} \p{Lu}+\p{L&} \p{Lu}+\p{L} \p{Lu}+\p{Lu} \P{Lu}+\p{Lu} \p{Lu}+\p{Nd} \p{Lu}+\P{Nd} \p{Lu}+\p{Han} \p{Lu}+\p{Xan} \p{Lu}+\p{Xsp} \p{Lu}+\p{Xps} \p{Xwd}+\p{Lu} \p{Lu}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Lu +
+ prop Any
+ prop Lu +
+ prop L&
+ prop Lu +
+ prop L
+ prop Lu +
+ prop Lu
+ notprop Lu ++
+ prop Lu
+ prop Lu ++
+ prop Nd
+ prop Lu +
+ notprop Nd
+ prop Lu +
+ prop Han
+ prop Lu +
+ prop Xan
+ prop Lu ++
+ prop Xsp
+ prop Lu ++
+ prop Xps
+ prop Xwd +
+ prop Lu
+ prop Lu +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Han}+\p{Lu} \p{Han}+\p{L&} \p{Han}+\p{L} \p{Han}+\p{Lu} \p{Han}+\p{Arabic} \p{Arabic}+\p{Arabic} \p{Han}+\p{Xan} \p{Han}+\p{Xsp} \p{Han}+\p{Xps} \p{Xwd}+\p{Han} \p{Han}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Han +
+ prop Lu
+ prop Han +
+ prop L&
+ prop Han +
+ prop L
+ prop Han +
+ prop Lu
+ prop Han ++
+ prop Arabic
+ prop Arabic +
+ prop Arabic
+ prop Han +
+ prop Xan
+ prop Han +
+ prop Xsp
+ prop Han +
+ prop Xps
+ prop Xwd +
+ prop Han
+ prop Han +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xan}+\p{Any} \p{Xan}+\p{L&} \P{Xan}+\p{L&} \p{Xan}+\p{L} \p{Xan}+\p{Lu} \p{Xan}+\p{Han} \p{Xan}+\p{Xan} \p{Xan}+\P{Xan} \p{Xan}+\p{Xsp} \p{Xan}+\p{Xps} \p{Xwd}+\p{Xan} \p{Xan}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xan +
+ prop Any
+ prop Xan +
+ prop L&
+ notprop Xan ++
+ prop L&
+ prop Xan +
+ prop L
+ prop Xan +
+ prop Lu
+ prop Xan +
+ prop Han
+ prop Xan +
+ prop Xan
+ prop Xan ++
+ notprop Xan
+ prop Xan ++
+ prop Xsp
+ prop Xan ++
+ prop Xps
+ prop Xwd +
+ prop Xan
+ prop Xan +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xsp}+\p{Any} \p{Xsp}+\p{L&} \p{Xsp}+\p{L} \p{Xsp}+\p{Lu} \p{Xsp}+\p{Han} \p{Xsp}+\p{Xan} \p{Xsp}+\p{Xsp} \P{Xsp}+\p{Xsp} \p{Xsp}+\p{Xps} \p{Xwd}+\p{Xsp} \p{Xsp}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xsp +
+ prop Any
+ prop Xsp ++
+ prop L&
+ prop Xsp ++
+ prop L
+ prop Xsp ++
+ prop Lu
+ prop Xsp +
+ prop Han
+ prop Xsp ++
+ prop Xan
+ prop Xsp +
+ prop Xsp
+ notprop Xsp ++
+ prop Xsp
+ prop Xsp +
+ prop Xps
+ prop Xwd ++
+ prop Xsp
+ prop Xsp +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xwd}+\p{Any} \p{Xwd}+\p{L&} \p{Xwd}+\p{L} \p{Xwd}+\p{Lu} \p{Xwd}+\p{Han} \p{Xwd}+\p{Xan} \p{Xwd}+\p{Xsp} \p{Xwd}+\p{Xps} \p{Xwd}+\p{Xwd} \p{Xwd}+\P{Xwd} \p{Xwd}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xwd +
+ prop Any
+ prop Xwd +
+ prop L&
+ prop Xwd +
+ prop L
+ prop Xwd +
+ prop Lu
+ prop Xwd +
+ prop Han
+ prop Xwd +
+ prop Xan
+ prop Xwd ++
+ prop Xsp
+ prop Xwd ++
+ prop Xps
+ prop Xwd +
+ prop Xwd
+ prop Xwd ++
+ notprop Xwd
+ prop Xwd +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xuc}+\p{Any} \p{Xuc}+\p{L&} \p{Xuc}+\p{L} \p{Xuc}+\p{Lu} \p{Xuc}+\p{Han} \p{Xuc}+\p{Xan} \p{Xuc}+\p{Xsp} \p{Xuc}+\p{Xps} \p{Xwd}+\p{Xuc} \p{Xuc}+\p{Xuc} \p{Xuc}+\P{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xuc +
+ prop Any
+ prop Xuc +
+ prop L&
+ prop Xuc +
+ prop L
+ prop Xuc +
+ prop Lu
+ prop Xuc +
+ prop Han
+ prop Xuc +
+ prop Xan
+ prop Xuc +
+ prop Xsp
+ prop Xuc +
+ prop Xps
+ prop Xwd +
+ prop Xuc
+ prop Xuc +
+ prop Xuc
+ prop Xuc ++
+ notprop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{N}+\p{Ll} \p{N}+\p{Nd} \p{N}+\P{Nd}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop N ++
+ prop Ll
+ prop N +
+ prop Nd
+ prop N +
+ notprop Nd
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xan}+\p{L} \p{Xan}+\p{N} \p{Xan}+\p{C} \p{Xan}+\P{L} \P{Xan}+\p{N} \p{Xan}+\P{C}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xan +
+ prop L
+ prop Xan +
+ prop N
+ prop Xan ++
+ prop C
+ prop Xan +
+ notprop L
+ notprop Xan ++
+ prop N
+ prop Xan +
+ notprop C
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{L}+\p{Xan} \p{N}+\p{Xan} \p{C}+\p{Xan} \P{L}+\p{Xan} \p{N}+\p{Xan} \P{C}+\p{Xan} \p{L}+\P{Xan}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop L +
+ prop Xan
+ prop N +
+ prop Xan
+ prop C ++
+ prop Xan
+ notprop L +
+ prop Xan
+ prop N +
+ prop Xan
+ notprop C +
+ prop Xan
+ prop L ++
+ notprop Xan
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xan}+\p{Lu} \p{Xan}+\p{Nd} \p{Xan}+\p{Cc} \p{Xan}+\P{Ll} \P{Xan}+\p{No} \p{Xan}+\P{Cf}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xan +
+ prop Lu
+ prop Xan +
+ prop Nd
+ prop Xan ++
+ prop Cc
+ prop Xan +
+ notprop Ll
+ notprop Xan ++
+ prop No
+ prop Xan +
+ notprop Cf
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Lu}+\p{Xan} \p{Nd}+\p{Xan} \p{Cs}+\p{Xan} \P{Lt}+\p{Xan} \p{Nl}+\p{Xan} \P{Cc}+\p{Xan} \p{Lt}+\P{Xan}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Lu +
+ prop Xan
+ prop Nd +
+ prop Xan
+ prop Cs ++
+ prop Xan
+ notprop Lt +
+ prop Xan
+ prop Nl +
+ prop Xan
+ notprop Cc +
+ prop Xan
+ prop Lt ++
+ notprop Xan
+ Ket
+ End
+------------------------------------------------------------------
+
+/\w+\p{P} \w+\p{Po} \w+\s \p{Xan}+\s \s+\p{Xan} \s+\w/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xwd +
+ prop P
+ prop Xwd +
+ prop Po
+ prop Xwd ++
+ prop Xsp
+ prop Xan ++
+ prop Xsp
+ prop Xsp ++
+ prop Xan
+ prop Xsp ++
+ prop Xwd
+ Ket
+ End
+------------------------------------------------------------------
+
+/\w+\P{P} \W+\p{Po} \w+\S \P{Xan}+\s \s+\P{Xan} \s+\W/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xwd +
+ notprop P
+ notprop Xwd +
+ prop Po
+ prop Xwd +
+ notprop Xsp
+ notprop Xan +
+ prop Xsp
+ prop Xsp +
+ notprop Xan
+ prop Xsp +
+ notprop Xwd
+ Ket
+ End
+------------------------------------------------------------------
+
+/\w+\p{Po} \w+\p{Pc} \W+\p{Po} \W+\p{Pc} \w+\P{Po} \w+\P{Pc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xwd +
+ prop Po
+ prop Xwd ++
+ prop Pc
+ notprop Xwd +
+ prop Po
+ notprop Xwd +
+ prop Pc
+ prop Xwd +
+ notprop Po
+ prop Xwd +
+ notprop Pc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Nl}+\p{Xan} \P{Nl}+\p{Xan} \p{Nl}+\P{Xan} \P{Nl}+\P{Xan}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Nl +
+ prop Xan
+ notprop Nl +
+ prop Xan
+ prop Nl ++
+ notprop Xan
+ notprop Nl +
+ notprop Xan
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xan}+\p{Nl} \P{Xan}+\p{Nl} \p{Xan}+\P{Nl} \P{Xan}+\P{Nl}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xan +
+ prop Nl
+ notprop Xan ++
+ prop Nl
+ prop Xan +
+ notprop Nl
+ notprop Xan +
+ notprop Nl
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xan}+\p{Nd} \P{Xan}+\p{Nd} \p{Xan}+\P{Nd} \P{Xan}+\P{Nd}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xan +
+ prop Nd
+ notprop Xan ++
+ prop Nd
+ prop Xan +
+ notprop Nd
+ notprop Xan +
+ notprop Nd
+ Ket
+ End
+------------------------------------------------------------------
+
+/-- End auto-possessification tests --/
+
+/\w+/8CWBZ
+------------------------------------------------------------------
+ Bra
+ Callout 255 0 3
+ prop Xwd ++
+ Callout 255 3 0
+ Ket
+ End
+------------------------------------------------------------------
+ abcd
+--->abcd
+ +0 ^ \w+
+ +3 ^ ^
+ 0: abcd
+
+/[\p{N}]?+/BZO
+------------------------------------------------------------------
+ Bra
+ [\p{N}]?+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[\p{L}ab]{2,3}+/BZO
+------------------------------------------------------------------
+ Bra
+ [ab\p{L}]{2,3}+
+ Ket
+ End
+------------------------------------------------------------------
+
+/\D+\X \d+\X \S+\X \s+\X \W+\X \w+\X \C+\X \R+\X \H+\X \h+\X \V+\X \v+\X a+\X \n+\X .+\X/BZx
+------------------------------------------------------------------
+ Bra
+ \D+
+ extuni
+ \d+
+ extuni
+ \S+
+ extuni
+ \s+
+ extuni
+ \W+
+ extuni
+ \w+
+ extuni
+ AllAny+
+ extuni
+ \R+
+ extuni
+ \H+
+ extuni
+ \h+
+ extuni
+ \V+
+ extuni
+ \v+
+ extuni
+ a+
+ extuni
+ \x0a+
+ extuni
+ Any+
+ extuni
+ Ket
+ End
+------------------------------------------------------------------
+
+/.+\X/BZxs
+------------------------------------------------------------------
+ Bra
+ AllAny+
+ extuni
+ Ket
+ End
+------------------------------------------------------------------
+
+/\X+$/BZxm
+------------------------------------------------------------------
+ Bra
+ extuni+
+ /m $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\X+\D \X+\d \X+\S \X+\s \X+\W \X+\w \X+. \X+\C \X+\R \X+\H \X+\h \X+\V \X+\v \X+\X \X+\Z \X+\z \X+$/BZx
+------------------------------------------------------------------
+ Bra
+ extuni+
+ \D
+ extuni+
+ \d
+ extuni+
+ \S
+ extuni+
+ \s
+ extuni+
+ \W
+ extuni+
+ \w
+ extuni+
+ Any
+ extuni+
+ AllAny
+ extuni+
+ \R
+ extuni+
+ \H
+ extuni+
+ \h
+ extuni+
+ \V
+ extuni+
+ \v
+ extuni+
+ extuni
+ extuni+
+ \Z
+ extuni++
+ \z
+ extuni+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/8WBZ
+------------------------------------------------------------------
+ Bra
+ prop Nd ++
+ prop Xsp {0,5}+
+ =
+ prop Xsp *+
+ notprop Xsp ?
+ =
+ prop Xwd {0,4}+
+ notprop Xwd *+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[RST]+/8iWBZ
+------------------------------------------------------------------
+ Bra
+ [R-Tr-t\x{17f}]++
+ Ket
+ End
+------------------------------------------------------------------
+
+/[R-T]+/8iWBZ
+------------------------------------------------------------------
+ Bra
+ [R-Tr-t\x{17f}]++
+ Ket
+ End
+------------------------------------------------------------------
+
+/[Q-U]+/8iWBZ
+------------------------------------------------------------------
+ Bra
+ [Q-Uq-u\x{17f}]++
+ Ket
+ End
+------------------------------------------------------------------
+
+/^s?c/mi8I
+Capturing subpattern count = 0
+Options: caseless multiline utf
+First char at start or follows newline
+Need char = 'c' (caseless)
+ scat
+ 0: sc
+
+/a[[:punct:]b]/WBZ
+------------------------------------------------------------------
+ Bra
+ a
+ [b[:punct:]]
+ Ket
+ End
+------------------------------------------------------------------
+
+/a[[:punct:]b]/8WBZ
+------------------------------------------------------------------
+ Bra
+ a
+ [b[:punct:]]
+ Ket
+ End
+------------------------------------------------------------------
+
+/a[b[:punct:]]/8WBZ
+------------------------------------------------------------------
+ Bra
+ a
+ [b[:punct:]]
+ Ket
+ End
+------------------------------------------------------------------
+
+/L(?#(|++<!(2)?/B8COZ
+------------------------------------------------------------------
+ Bra
+ Callout 255 0 14
+ L?
+ Callout 255 14 0
+ Ket
+ End
+------------------------------------------------------------------
+
+/L(?#(|++<!(2)?/B8WCZ
+------------------------------------------------------------------
+ Bra
+ Callout 255 0 14
+ L?+
+ Callout 255 14 0
+ Ket
+ End
+------------------------------------------------------------------
/-- End of testinput7 --/
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput8 b/lib/stdlib/test/re_SUITE_data/testoutput8
index 75affbe2d4..17b667a980 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput8
+++ b/lib/stdlib/test/re_SUITE_data/testoutput8
@@ -1,5 +1,8 @@
-/-- This set of tests check the DFA matching functionality of pcre_dfa_exec().
- The -dfa flag must be used with pcretest when running it. --/
+/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(),
+ excluding UTF and Unicode property support. The -dfa flag must be used with
+ pcretest when running it. --/
+
+< forbid 8W
/abc/
abc
@@ -25,7 +28,7 @@ No match
ab
No match
-/a*/
+/a*/O
a
0: a
1:
@@ -341,7 +344,7 @@ No match
axyzq
No match
-/[^a]+/
+/[^a]+/O
bac
0: b
bcdefax
@@ -359,7 +362,7 @@ No match
aaaaa
No match
-/[^a]*/
+/[^a]*/O
bac
0: b
1:
@@ -380,7 +383,7 @@ No match
aaaaa
0:
-/[^a]{3,5}/
+/[^a]{3,5}/O
xyz
0: xyz
awxyza
@@ -408,29 +411,18 @@ No match
/\d*/
1234b567
0: 1234
- 1: 123
- 2: 12
- 3: 1
- 4:
xyz
0:
/\D*/
a1234b567
0: a
- 1:
xyz
0: xyz
- 1: xy
- 2: x
- 3:
/\d+/
ab1234c56
0: 1234
- 1: 123
- 2: 12
- 3: 1
*** Failers
No match
xyz
@@ -439,19 +431,8 @@ No match
/\D+/
ab123c56
0: ab
- 1: a
*** Failers
0: *** Failers
- 1: *** Failer
- 2: *** Faile
- 3: *** Fail
- 4: *** Fai
- 5: *** Fa
- 6: *** F
- 7: ***
- 8: ***
- 9: **
-10: *
789
No match
@@ -478,9 +459,6 @@ No match
/a+/
aaaa
0: aaaa
- 1: aaa
- 2: aa
- 3: a
/^.*xyz/
xyz
@@ -886,9 +864,6 @@ No match
0:
aaabcd
0: aaa
- 1: aa
- 2: a
- 3:
xyz
0: xyz
1:
@@ -1577,18 +1552,6 @@ No match
/^[.^$|()*+?{,}]+/
.^\$(*+)|{?,?}
0: .^$(*+)|{?,?}
- 1: .^$(*+)|{?,?
- 2: .^$(*+)|{?,
- 3: .^$(*+)|{?
- 4: .^$(*+)|{
- 5: .^$(*+)|
- 6: .^$(*+)
- 7: .^$(*+
- 8: .^$(*
- 9: .^$(
-10: .^$
-11: .^
-12: .
/^a*\w/
z
@@ -1744,38 +1707,16 @@ No match
/foo(?!bar)(.*)/
foobar is foolish see?
0: foolish see?
- 1: foolish see
- 2: foolish se
- 3: foolish s
- 4: foolish
- 5: foolish
- 6: foolis
- 7: fooli
- 8: fool
- 9: foo
/(?:(?!foo)...|^.{0,2})bar(.*)/
foobar crowbar etc
0: rowbar etc
- 1: rowbar et
- 2: rowbar e
- 3: rowbar
- 4: rowbar
barrel
0: barrel
- 1: barre
- 2: barr
- 3: bar
2barrel
0: 2barrel
- 1: 2barre
- 2: 2barr
- 3: 2bar
A barrel
0: A barrel
- 1: A barre
- 2: A barr
- 3: A bar
/^(\D*)(?=\d)(?!123)/
abc456
@@ -1820,7 +1761,7 @@ No match
the abc
No match
-/^[ab]{1,3}(ab*|b)/
+/^[ab]{1,3}(ab*|b)/O
aabbbbb
0: aabbbbb
1: aabbbb
@@ -1829,7 +1770,7 @@ No match
4: aab
5: aa
-/^[ab]{1,3}?(ab*|b)/
+/^[ab]{1,3}?(ab*|b)/O
aabbbbb
0: aabbbbb
1: aabbbb
@@ -1838,7 +1779,7 @@ No match
4: aab
5: aa
-/^[ab]{1,3}?(ab*?|b)/
+/^[ab]{1,3}?(ab*?|b)/O
aabbbbb
0: aabbbbb
1: aabbbb
@@ -1847,7 +1788,7 @@ No match
4: aab
5: aa
-/^[ab]{1,3}(ab*?|b)/
+/^[ab]{1,3}(ab*?|b)/O
aabbbbb
0: aabbbbb
1: aabbbb
@@ -2705,10 +2646,6 @@ No match
/\0*/
\0\0\0\0
0: \x00\x00\x00\x00
- 1: \x00\x00\x00
- 2: \x00\x00
- 3: \x00
- 4:
/A\x0{2,3}Z/
The A\x0\x0Z
@@ -2760,56 +2697,14 @@ No match
/([^.]*)\.([^:]*):[T ]+(.*)/
track1.title:TBlah blah blah
0: track1.title:TBlah blah blah
- 1: track1.title:TBlah blah bla
- 2: track1.title:TBlah blah bl
- 3: track1.title:TBlah blah b
- 4: track1.title:TBlah blah
- 5: track1.title:TBlah blah
- 6: track1.title:TBlah bla
- 7: track1.title:TBlah bl
- 8: track1.title:TBlah b
- 9: track1.title:TBlah
-10: track1.title:TBlah
-11: track1.title:TBla
-12: track1.title:TBl
-13: track1.title:TB
-14: track1.title:T
/([^.]*)\.([^:]*):[T ]+(.*)/i
track1.title:TBlah blah blah
0: track1.title:TBlah blah blah
- 1: track1.title:TBlah blah bla
- 2: track1.title:TBlah blah bl
- 3: track1.title:TBlah blah b
- 4: track1.title:TBlah blah
- 5: track1.title:TBlah blah
- 6: track1.title:TBlah bla
- 7: track1.title:TBlah bl
- 8: track1.title:TBlah b
- 9: track1.title:TBlah
-10: track1.title:TBlah
-11: track1.title:TBla
-12: track1.title:TBl
-13: track1.title:TB
-14: track1.title:T
/([^.]*)\.([^:]*):[t ]+(.*)/i
track1.title:TBlah blah blah
0: track1.title:TBlah blah blah
- 1: track1.title:TBlah blah bla
- 2: track1.title:TBlah blah bl
- 3: track1.title:TBlah blah b
- 4: track1.title:TBlah blah
- 5: track1.title:TBlah blah
- 6: track1.title:TBlah bla
- 7: track1.title:TBlah bl
- 8: track1.title:TBlah b
- 9: track1.title:TBlah
-10: track1.title:TBlah
-11: track1.title:TBla
-12: track1.title:TBl
-13: track1.title:TB
-14: track1.title:T
/^[W-c]+$/
WXY_^abc
@@ -2882,13 +2777,10 @@ No match
0: b
c::b
0: ::
- 1: :
/[-az]+/
az-
0: az-
- 1: az
- 2: a
*** Failers
0: a
b
@@ -2897,8 +2789,6 @@ No match
/[az-]+/
za-
0: za-
- 1: za
- 2: z
*** Failers
0: a
b
@@ -2907,8 +2797,6 @@ No match
/[a\-z]+/
a-z
0: a-z
- 1: a-
- 2: a
*** Failers
0: a
b
@@ -2917,20 +2805,10 @@ No match
/[a-z]+/
abcdxyz
0: abcdxyz
- 1: abcdxy
- 2: abcdx
- 3: abcd
- 4: abc
- 5: ab
- 6: a
/[\d-]+/
12-34
0: 12-34
- 1: 12-3
- 2: 12-
- 3: 12
- 4: 1
*** Failers
No match
aaa
@@ -2939,11 +2817,6 @@ No match
/[\d-z]+/
12-34z
0: 12-34z
- 1: 12-34
- 2: 12-3
- 3: 12-
- 4: 12
- 5: 1
*** Failers
No match
aaa
@@ -3027,18 +2900,22 @@ No match
abc\100\60
0: abc@0
-/abc\81/
- abc\081
- 0: abc\x0081
- abc\0\x38\x31
- 0: abc\x0081
-
-/abc\91/
- abc\091
- 0: abc\x0091
- abc\0\x39\x31
- 0: abc\x0091
-
+/^A\8B\9C$/
+ A8B9C
+ 0: A8B9C
+ *** Failers
+No match
+ A\08B\09C
+No match
+
+/^[A\8B\9C]+$/
+ A8B9C
+ 0: A8B9C
+ *** Failers
+No match
+ A8B9C\x00
+No match
+
/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/
abcdefghijk\12S
0: abcdefghijk\x0aS
@@ -3077,16 +2954,13 @@ No match
1: baNOTccc
2: baNOTcc
3: baNOTc
- 4: baNOT
baNOTcccd
0: baNOTccc
1: baNOTcc
2: baNOTc
- 3: baNOT
baNOTccd
0: baNOTcc
1: baNOTc
- 2: baNOT
bacccd
0: baccc
*** Failers
@@ -3096,7 +2970,6 @@ No match
3: *** Fail
4: *** Fai
5: *** Fa
- 6: *** F
anything
No match
b\bc
@@ -3115,23 +2988,14 @@ No match
/[^a]+/
AAAaAbc
0: AAA
- 1: AA
- 2: A
/[^a]+/i
AAAaAbc
0: bc
- 1: b
/[^a]+/
bbb\nccc
0: bbb\x0accc
- 1: bbb\x0acc
- 2: bbb\x0ac
- 3: bbb\x0a
- 4: bbb
- 5: bb
- 6: b
/[^k]$/
abc
@@ -3208,20 +3072,8 @@ No match
/(\.\d\d[1-9]?)\d+/
1.230003938
0: .230003938
- 1: .23000393
- 2: .2300039
- 3: .230003
- 4: .23000
- 5: .2300
- 6: .230
1.875000282
0: .875000282
- 1: .87500028
- 2: .8750002
- 3: .875000
- 4: .87500
- 5: .8750
- 6: .875
1.235
0: .235
@@ -3243,10 +3095,6 @@ No match
/\b(foo)\s+(\w+)/i
Food is on the foo table
0: foo table
- 1: foo tabl
- 2: foo tab
- 3: foo ta
- 4: foo t
/foo(.*)bar/
The food is under the bar in the barn.
@@ -3258,7 +3106,7 @@ No match
0: food is under the bar in the bar
1: food is under the bar
-/(.*)(\d*)/
+/(.*)(\d*)/O
I have 2 numbers: 53147
Matched, but offsets vector is too small to show all matches
0: I have 2 numbers: 53147
@@ -3287,13 +3135,9 @@ Matched, but offsets vector is too small to show all matches
/(.*)(\d+)/
I have 2 numbers: 53147
0: I have 2 numbers: 53147
- 1: I have 2 numbers: 5314
- 2: I have 2 numbers: 531
- 3: I have 2 numbers: 53
- 4: I have 2 numbers: 5
- 5: I have 2
+ 1: I have 2
-/(.*?)(\d*)/
+/(.*?)(\d*)/O
I have 2 numbers: 53147
Matched, but offsets vector is too small to show all matches
0: I have 2 numbers: 53147
@@ -3322,11 +3166,7 @@ Matched, but offsets vector is too small to show all matches
/(.*?)(\d+)/
I have 2 numbers: 53147
0: I have 2 numbers: 53147
- 1: I have 2 numbers: 5314
- 2: I have 2 numbers: 531
- 3: I have 2 numbers: 53
- 4: I have 2 numbers: 5
- 5: I have 2
+ 1: I have 2
/(.*)(\d+)$/
I have 2 numbers: 53147
@@ -3738,13 +3578,8 @@ No match
0: a
ab
0: ab
- 1: a
abbbb
0: abbbb
- 1: abbb
- 2: abb
- 3: ab
- 4: a
*** Failers
0: a
bbbbb
@@ -3930,19 +3765,8 @@ No match
/(?>(\.\d\d[1-9]?))\d+/
1.230003938
0: .230003938
- 1: .23000393
- 2: .2300039
- 3: .230003
- 4: .23000
- 5: .2300
- 6: .230
1.875000282
0: .875000282
- 1: .87500028
- 2: .8750002
- 3: .875000
- 4: .87500
- 5: .8750
*** Failers
No match
1.235
@@ -4561,7 +4385,6 @@ No match
/.{3,4}/
abbbbc
0: abbb
- 1: abb
/ab{0,}bc/
abbbbc
@@ -4929,9 +4752,6 @@ No match
/[^ab]*/
cde
0: cde
- 1: cd
- 2: c
- 3:
/abc/
*** Failers
@@ -4966,7 +4786,6 @@ No match
/ab*/
xabyabbbz
0: ab
- 1: a
xayabbbz
0: a
@@ -4995,8 +4814,7 @@ No match
/a([bc]*)c*/
abc
0: abc
- 1: ab
- 2: a
+ 1: a
/a([bc]*)(c*d)/
abcd
@@ -5033,10 +4851,6 @@ No match
/[a-zA-Z_][a-zA-Z0-9_]*/
alpha
0: alpha
- 1: alph
- 2: alp
- 3: al
- 4: a
/^a(bc+|b[eh])g|.h$/
abh
@@ -5079,8 +4893,6 @@ No match
/(.*)c(.*)/
abcde
0: abcde
- 1: abcd
- 2: abc
/\((.*), (.*)\)/
(a, b)
@@ -5395,9 +5207,6 @@ No match
/[^ab]*/i
CDE
0: CDE
- 1: CD
- 2: C
- 3:
/abc/i
@@ -5427,7 +5236,6 @@ No match
/ab*/i
XABYABBBZ
0: AB
- 1: A
XAYABBBZ
0: A
@@ -5458,8 +5266,7 @@ No match
/a([bc]*)c*/i
ABC
0: ABC
- 1: AB
- 2: A
+ 1: A
/a([bc]*)(c*d)/i
ABCD
@@ -5490,10 +5297,6 @@ No match
/[a-zA-Z_][a-zA-Z0-9_]*/i
ALPHA
0: ALPHA
- 1: ALPH
- 2: ALP
- 3: AL
- 4: A
/^a(bc+|b[eh])g|.h$/i
ABH
@@ -5546,8 +5349,6 @@ No match
/(.*)c(.*)/i
ABCDE
0: ABCDE
- 1: ABCD
- 2: ABC
/\((.*), (.*)\)/i
(A, B)
@@ -6052,17 +5853,14 @@ No match
/([[:]+)/
a:[b]:
0: :[
- 1: :
/([[=]+)/
a=[b]=
0: =[
- 1: =
/([[.]+)/
a.[b].
0: .[
- 1: .
/((?>a+)b)/
aaab
@@ -6196,26 +5994,12 @@ No match
/a*/g
abbab
0: a
- 1:
0:
0:
0: a
- 1:
0:
0:
-/^[a-\d]/
- abcde
- 0: a
- -things
- 0: -
- 0digit
- 0: 0
- *** Failers
-No match
- bcdef
-No match
-
/^[\d-a]/
abcde
0: a
@@ -6231,36 +6015,22 @@ No match
/[[:space:]]+/
> \x09\x0a\x0c\x0d\x0b<
0: \x09\x0a\x0c\x0d\x0b
- 1: \x09\x0a\x0c\x0d
- 2: \x09\x0a\x0c
- 3: \x09\x0a
- 4: \x09
- 5:
/[[:blank:]]+/
> \x09\x0a\x0c\x0d\x0b<
0: \x09
- 1:
/[\s]+/
> \x09\x0a\x0c\x0d\x0b<
- 0: \x09\x0a\x0c\x0d
- 1: \x09\x0a\x0c
- 2: \x09\x0a
- 3: \x09
- 4:
+ 0: \x09\x0a\x0c\x0d\x0b
/\s+/
> \x09\x0a\x0c\x0d\x0b<
- 0: \x09\x0a\x0c\x0d
- 1: \x09\x0a\x0c
- 2: \x09\x0a
- 3: \x09
- 4:
+ 0: \x09\x0a\x0c\x0d\x0b
/a b/x
ab
-No match
+ 0: ab
/(?!\A)x/m
a\nxb\n
@@ -6563,8 +6333,6 @@ Partial match: 123
/Content-Type\x3A[^\r\n]{6,}/
Content-Type:xxxxxyyy
0: Content-Type:xxxxxyyy
- 1: Content-Type:xxxxxyy
- 2: Content-Type:xxxxxy
/Content-Type\x3A[^\r\n]{6,}z/
Content-Type:xxxxxyyyz
@@ -6661,66 +6429,22 @@ No match
/.*/<lf>
abc\ndef
0: abc
- 1: ab
- 2: a
- 3:
abc\rdef
0: abc\x0ddef
- 1: abc\x0dde
- 2: abc\x0dd
- 3: abc\x0d
- 4: abc
- 5: ab
- 6: a
- 7:
abc\r\ndef
0: abc\x0d
- 1: abc
- 2: ab
- 3: a
- 4:
\<cr>abc\ndef
0: abc\x0adef
- 1: abc\x0ade
- 2: abc\x0ad
- 3: abc\x0a
- 4: abc
- 5: ab
- 6: a
- 7:
\<cr>abc\rdef
0: abc
- 1: ab
- 2: a
- 3:
\<cr>abc\r\ndef
0: abc
- 1: ab
- 2: a
- 3:
\<crlf>abc\ndef
0: abc\x0adef
- 1: abc\x0ade
- 2: abc\x0ad
- 3: abc\x0a
- 4: abc
- 5: ab
- 6: a
- 7:
\<crlf>abc\rdef
0: abc\x0ddef
- 1: abc\x0dde
- 2: abc\x0dd
- 3: abc\x0d
- 4: abc
- 5: ab
- 6: a
- 7:
\<crlf>abc\r\ndef
0: abc
- 1: ab
- 2: a
- 3:
/\w+(.)(.)?def/s
abc\ndef
@@ -7033,10 +6757,8 @@ No match
/\H*\h+\V?\v{3,4}/
\x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a
0: \x09 \xa0X\x0a\x0b\x0c\x0d
- 1: \x09 \xa0X\x0a\x0b\x0c
\x09\x20\xa0\x0a\x0b\x0c\x0d\x0a
0: \x09 \xa0\x0a\x0b\x0c\x0d
- 1: \x09 \xa0\x0a\x0b\x0c
\x09\x20\xa0\x0a\x0b\x0c
0: \x09 \xa0\x0a\x0b\x0c
** Failers
@@ -7047,7 +6769,6 @@ No match
/\H{3,4}/
XY ABCDE
0: ABCD
- 1: ABC
XY PQR ST
0: PQR
@@ -7511,7 +7232,7 @@ No options
No first char
No need char
Subject length lower bound = 3
-Starting byte set: a d x
+Starting chars: a d x
terhjk;abcdaadsfe
0: abc
the quick xyz brown fox
@@ -7531,15 +7252,11 @@ No match
xxxxabcd\P
0: abcd
0+
- 1: abc
xxxxabcd\P\P
Partial match: abcd
dddxxx\R
0: ddd
0+ xxx
- 1: dd
- 2: d
- 3:
xxxxabcd\P\P
Partial match: abcd
xxx\R
@@ -7549,27 +7266,22 @@ Partial match: abcd
/abcd*/i
xxxxabcd\P
0: abcd
- 1: abc
xxxxabcd\P\P
Partial match: abcd
XXXXABCD\P
0: ABCD
- 1: ABC
XXXXABCD\P\P
Partial match: ABCD
/abc\d*/
xxxxabc1\P
0: abc1
- 1: abc
xxxxabc1\P\P
Partial match: abc1
/abc[de]*/
xxxxabcde\P
0: abcde
- 1: abcd
- 2: abc
xxxxabcde\P\P
Partial match: abcde
@@ -7684,11 +7396,8 @@ Partial match: abc
/.+/
abc\>0
0: abc
- 1: ab
- 2: a
abc\>1
0: bc
- 1: b
abc\>2
0: c
abc\>3
@@ -7811,10 +7520,6 @@ No match
/^(?!a){0}\w+/
aaaaa
0: aaaaa
- 1: aaaa
- 2: aaa
- 3: aa
- 4: a
/(?<=(abc))?xyz/
abcxyz
@@ -7846,7 +7551,7 @@ Error -17 (backreference condition or recursion test not supported for DFA match
aaaabcde
Error -26 (nested recursion at the same subject position)
-/(a+)/
+/(a+)/O
\O6aaaa
Matched, but offsets vector is too small to show all matches
0: aaaa
@@ -7971,7 +7676,6 @@ Partial match: \x0d
Partial match: \x0d\x0d
\r\r\r\P
0: \x0d\x0d\x0d
- 1: \x0d\x0d
\r\r\r\P\P
Partial match: \x0d\x0d\x0d
@@ -8020,4 +7724,81 @@ Error -30 (invalid data in workspace for DFA restart)
abcd\O0
Matched, but offsets vector is too small to show all matches
+/-- These tests show up auto-possessification --/
+
+/[ab]*/
+ aaaa
+ 0: aaaa
+
+/[ab]*?/
+ aaaa
+ 0: aaaa
+ 1: aaa
+ 2: aa
+ 3: a
+ 4:
+
+/[ab]?/
+ aaaa
+ 0: a
+
+/[ab]??/
+ aaaa
+ 0: a
+ 1:
+
+/[ab]+/
+ aaaa
+ 0: aaaa
+
+/[ab]+?/
+ aaaa
+ 0: aaaa
+ 1: aaa
+ 2: aa
+ 3: a
+
+/[ab]{2,3}/
+ aaaa
+ 0: aaa
+
+/[ab]{2,3}?/
+ aaaa
+ 0: aaa
+ 1: aa
+
+/[ab]{2,}/
+ aaaa
+ 0: aaaa
+
+/[ab]{2,}?/
+ aaaa
+ 0: aaaa
+ 1: aaa
+ 2: aa
+
+'\A(?:[^\"]++|\"(?:[^\"]*+|\"\")*+\")++'
+ NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+ 0: NON QUOTED "QUOT""ED" AFTER
+
+'\A(?:[^\"]++|\"(?:[^\"]++|\"\")*+\")++'
+ NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
+ 0: NON QUOTED "QUOT""ED" AFTER
+
+/(?(?!)a|b)/
+ bbb
+ 0: b
+ aaa
+No match
+
+/()()a+/O=
+ aaa\D
+** Show all captures ignored after DFA matching
+ 0: aaa
+ 1: aa
+ 2: a
+ a\D
+** Show all captures ignored after DFA matching
+ 0: a
+
/-- End of testinput8 --/
diff --git a/lib/stdlib/test/re_SUITE_data/testoutput9 b/lib/stdlib/test/re_SUITE_data/testoutput9
index 0bb101ad61..efbbf18010 100644
--- a/lib/stdlib/test/re_SUITE_data/testoutput9
+++ b/lib/stdlib/test/re_SUITE_data/testoutput9
@@ -1,6 +1,8 @@
/-- This set of tests checks UTF-8 support with the DFA matching functionality
- of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running
- it. --/
+ of pcre_dfa_exec(), excluding Unicode property support. The -dfa flag must
+ be used with pcretest when running it. --/
+
+< forbid W
/\x{100}ab/8
\x{100}ab
@@ -313,13 +315,9 @@ No match
/[^a]+/8g
bcd
0: bcd
- 1: bc
- 2: b
\x{100}aY\x{256}Z
0: \x{100}
0: Y\x{256}Z
- 1: Y\x{256}
- 2: Y
/^[^a]{2}/8
\x{100}bc
@@ -328,8 +326,6 @@ No match
/^[^a]{2,}/8
\x{100}bcAa
0: \x{100}bcA
- 1: \x{100}bc
- 2: \x{100}b
/^[^a]{2,}?/8
\x{100}bca
@@ -339,13 +335,9 @@ No match
/[^a]+/8ig
bcd
0: bcd
- 1: bc
- 2: b
\x{100}aY\x{256}Z
0: \x{100}
0: Y\x{256}Z
- 1: Y\x{256}
- 2: Y
/^[^a]{2}/8i
\x{100}bc
@@ -354,7 +346,6 @@ No match
/^[^a]{2,}/8i
\x{100}bcAa
0: \x{100}bc
- 1: \x{100}b
/^[^a]{2,}?/8i
\x{100}bca
@@ -370,28 +361,18 @@ No match
0:
\x{100}\x{100}
0: \x{100}
- 1:
/\x{100}{0,3}/8
\x{100}\x{100}
0: \x{100}\x{100}
- 1: \x{100}
- 2:
\x{100}\x{100}\x{100}\x{100}
0: \x{100}\x{100}\x{100}
- 1: \x{100}\x{100}
- 2: \x{100}
- 3:
/\x{100}*/8
abce
0:
\x{100}\x{100}\x{100}\x{100}
0: \x{100}\x{100}\x{100}\x{100}
- 1: \x{100}\x{100}\x{100}
- 2: \x{100}\x{100}
- 3: \x{100}
- 4:
/\x{100}{1,1}/8
abcd\x{100}\x{100}\x{100}\x{100}
@@ -400,15 +381,10 @@ No match
/\x{100}{1,3}/8
abcd\x{100}\x{100}\x{100}\x{100}
0: \x{100}\x{100}\x{100}
- 1: \x{100}\x{100}
- 2: \x{100}
/\x{100}+/8
abcd\x{100}\x{100}\x{100}\x{100}
0: \x{100}\x{100}\x{100}\x{100}
- 1: \x{100}\x{100}\x{100}
- 2: \x{100}\x{100}
- 3: \x{100}
/\x{100}{3}/8
abcd\x{100}\x{100}\x{100}XX
@@ -417,10 +393,8 @@ No match
/\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}
- 1: \x{100}\x{100}\x{100}\x{100}
- 2: \x{100}\x{100}\x{100}
-/\x{100}{3,}/8
+/\x{100}{3,}/8O
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}
1: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
@@ -432,7 +406,7 @@ No match
Xyyya\x{100}\x{100}bXzzz
0: X
-/\D*/8
+/\D*/8O
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Matched, but offsets vector is too small to show all matches
0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -458,7 +432,7 @@ Matched, but offsets vector is too small to show all matches
20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-/\D*/8
+/\D*/8O
\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
Matched, but offsets vector is too small to show all matches
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}
@@ -507,33 +481,18 @@ Matched, but offsets vector is too small to show all matches
/\D+/8
12abcd34
0: abcd
- 1: abc
- 2: ab
- 3: a
*** Failers
0: *** Failers
- 1: *** Failer
- 2: *** Faile
- 3: *** Fail
- 4: *** Fai
- 5: *** Fa
- 6: *** F
- 7: ***
- 8: ***
- 9: **
-10: *
1234
No match
/\D{2,3}/8
12abcd34
0: abc
- 1: ab
12ab34
0: ab
*** Failers
0: ***
- 1: **
1234
No match
12a34
@@ -556,7 +515,6 @@ No match
/\d+/8
12abcd34
0: 12
- 1: 1
*** Failers
No match
@@ -565,7 +523,6 @@ No match
0: 12
1234abcd
0: 123
- 1: 12
*** Failers
No match
1.4
@@ -585,30 +542,18 @@ No match
/\S+/8
12abcd34
0: 12abcd34
- 1: 12abcd3
- 2: 12abcd
- 3: 12abc
- 4: 12ab
- 5: 12a
- 6: 12
- 7: 1
*** Failers
0: ***
- 1: **
- 2: *
\ \
No match
/\S{2,3}/8
12abcd34
0: 12a
- 1: 12
1234abcd
0: 123
- 1: 12
*** Failers
0: ***
- 1: **
\ \
No match
@@ -654,15 +599,8 @@ No match
/\w+/8
12 34
0: 12
- 1: 1
*** Failers
0: Failers
- 1: Failer
- 2: Faile
- 3: Fail
- 4: Fai
- 5: Fa
- 6: F
+++=*!
No match
@@ -671,10 +609,8 @@ No match
0: ab
abcd ce
0: abc
- 1: ab
*** Failers
0: Fai
- 1: Fa
a.b.c
No match
@@ -693,26 +629,18 @@ No match
/\W+/8
12====34
0: ====
- 1: ===
- 2: ==
- 3: =
*** Failers
0: ***
- 1: ***
- 2: **
- 3: *
abcd
No match
/\W{2,3}/8
ab====cd
0: ===
- 1: ==
ab==cd
0: ==
*** Failers
0: ***
- 1: **
a.b.c
No match
@@ -825,8 +753,6 @@ No match
0: \x{200}
ab\x{200}\x{100}\x{200}\x{100}cd
0: \x{200}\x{100}\x{200}
- 1: \x{200}\x{100}
- 2: \x{200}
*** Failers
No match
@@ -849,8 +775,6 @@ No match
0: \x{200}
ab\x{200}\x{100}\x{200}\x{100}cd
0: \x{200}\x{100}\x{200}
- 1: \x{200}\x{100}
- 2: \x{200}
*** Failers
No match
@@ -1126,21 +1050,21 @@ No match
a\r
No match
-/\h+\V?\v{3,4}/8
+/\h+\V?\v{3,4}/8O
\x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d}
1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}
-/\V?\v{3,4}/8
+/\V?\v{3,4}/8O
\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
0: X\x{0a}\x{0b}\x{0c}\x{0d}
1: X\x{0a}\x{0b}\x{0c}
-/\h+\V?\v{3,4}/8
+/\h+\V?\v{3,4}/8O
>\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
+/\V?\v{3,4}/8O
>\x09\x20\x{a0}X\x0a\x0a\x0a<
0: X\x{0a}\x{0a}\x{0a}
@@ -1154,7 +1078,7 @@ No match
\x{a0} X\x0a
No match
-/\H*\h+\V?\v{3,4}/8
+/\H*\h+\V?\v{3,4}/8O
\x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d}
1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}
@@ -1178,7 +1102,7 @@ No match
\x{2009} X\x0a
No match
-/\H*\h+\V?\v{3,4}/8
+/\H*\h+\V?\v{3,4}/8O
\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}
1: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}
@@ -1279,34 +1203,28 @@ No match
/abcd*/8
xxxxabcd\P
0: abcd
- 1: abc
xxxxabcd\P\P
Partial match: abcd
/abcd*/i8
xxxxabcd\P
0: abcd
- 1: abc
xxxxabcd\P\P
Partial match: abcd
XXXXABCD\P
0: ABCD
- 1: ABC
XXXXABCD\P\P
Partial match: ABCD
/abc\d*/8
xxxxabc1\P
0: abc1
- 1: abc
xxxxabc1\P\P
Partial match: abc1
/abc[de]*/8
xxxxabcde\P
0: abcde
- 1: abcd
- 2: abc
xxxxabcde\P\P
Partial match: abcde
@@ -1340,7 +1258,6 @@ Partial match: \x{0d}
Partial match: \x{0d}\x{0d}
\r\r\r\P
0: \x{0d}\x{0d}\x{0d}
- 1: \x{0d}\x{0d}
\r\r\r\P\P
Partial match: \x{0d}\x{0d}\x{0d}
@@ -1366,6 +1283,5 @@ Partial match: \x{0d}\x{0d}\x{0d}
/[^\x{100}]+/8
\x{100}\x{101}X
0: \x{101}X
- 1: \x{101}
/-- End of testinput9 --/
diff --git a/lib/stdlib/test/re_testoutput1_replacement_test.erl b/lib/stdlib/test/re_testoutput1_replacement_test.erl
index a40800d760..f14df547ef 100644
--- a/lib/stdlib/test/re_testoutput1_replacement_test.erl
+++ b/lib/stdlib/test/re_testoutput1_replacement_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
%% %CopyrightEnd%
%%
-module(re_testoutput1_replacement_test).
--compile(export_all).
+-export([run/0]).
-compile(no_native).
%% This file is generated by running run_pcre_tests:gen_repl_test("re_SUITE_data/testoutput1")
run() ->
@@ -77,697 +77,703 @@ run() ->
run52(),
run53(),
run54(),
+ run55(),
+ run56(),
ok.
run0() ->
- <<"KXii">> = iolist_to_binary(re:replace("the quick brown fox","the quick brown fox","KXii",[])),
- <<"KXii">> = iolist_to_binary(re:replace("the quick brown fox","the quick brown fox","KXii",[global])),
- <<"The quick brown FOX">> = iolist_to_binary(re:replace("The quick brown FOX","the quick brown fox","HRC\\1&rBc&X&M\\1",[])),
- <<"The quick brown FOX">> = iolist_to_binary(re:replace("The quick brown FOX","the quick brown fox","HRC\\1&rBc&X&M\\1",[global])),
- <<"What do you know about Hthe quick brown foxgViGthe quick brown fox?">> = iolist_to_binary(re:replace("What do you know about the quick brown fox?","the quick brown fox","H&gViG\\1&",[])),
- <<"What do you know about Hthe quick brown foxgViGthe quick brown fox?">> = iolist_to_binary(re:replace("What do you know about the quick brown fox?","the quick brown fox","H&gViG\\1&",[global])),
- <<"What do you know about THE QUICK BROWN FOX?">> = iolist_to_binary(re:replace("What do you know about THE QUICK BROWN FOX?","the quick brown fox","N&hDtbGaV",[])),
- <<"What do you know about THE QUICK BROWN FOX?">> = iolist_to_binary(re:replace("What do you know about THE QUICK BROWN FOX?","the quick brown fox","N&hDtbGaV",[global])),
- <<"hQCthe quick brown foxthe quick brown foxjQpvbBuHjthe quick brown foxw">> = iolist_to_binary(re:replace("the quick brown fox","The quick brown fox","hQC&&jQ\\1pvbBuHj&w",[caseless])),
- <<"hQCthe quick brown foxthe quick brown foxjQpvbBuHjthe quick brown foxw">> = iolist_to_binary(re:replace("the quick brown fox","The quick brown fox","hQC&&jQ\\1pvbBuHj&w",[caseless,
- global])),
- <<"gkWwP">> = iolist_to_binary(re:replace("The quick brown FOX","The quick brown fox","gkWwP",[caseless])),
- <<"gkWwP">> = iolist_to_binary(re:replace("The quick brown FOX","The quick brown fox","gkWwP",[caseless,
- global])),
- <<"What do you know about ncBxuJXMsIrBx?">> = iolist_to_binary(re:replace("What do you know about the quick brown fox?","The quick brown fox","ncBxuJXMsIr\\1Bx",[caseless])),
- <<"What do you know about ncBxuJXMsIrBx?">> = iolist_to_binary(re:replace("What do you know about the quick brown fox?","The quick brown fox","ncBxuJXMsIr\\1Bx",[caseless,
- global])),
- <<"What do you know about ESkbGx?">> = iolist_to_binary(re:replace("What do you know about THE QUICK BROWN FOX?","The quick brown fox","ESkbGx",[caseless])),
- <<"What do you know about ESkbGx?">> = iolist_to_binary(re:replace("What do you know about THE QUICK BROWN FOX?","The quick brown fox","ESkbGx",[caseless,
- global])),
- <<"UImxeSkabcd
- 9;$\\?caxyzF">> = iolist_to_binary(re:replace("abcd
- 9;$\\?caxyz","abcd\\t\\n\\r\\f\\a\\e\\071\\x3b\\$\\\\\\?caxyz","UImxeSk&F",[])),
- <<"UImxeSkabcd
- 9;$\\?caxyzF">> = iolist_to_binary(re:replace("abcd
- 9;$\\?caxyz","abcd\\t\\n\\r\\f\\a\\e\\071\\x3b\\$\\\\\\?caxyz","UImxeSk&F",[global])),
- <<"LhHLabxyzpqrrrabbxyyyypqAzzkWRsxabxyzpqrrrabbxyyyypqAzzVMIt">> = iolist_to_binary(re:replace("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","LhHL&kWRsx\\1\\1&VMIt",[])),
- <<"LhHLabxyzpqrrrabbxyyyypqAzzkWRsxabxyzpqrrrabbxyyyypqAzzVMIt">> = iolist_to_binary(re:replace("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","LhHL&kWRsx\\1\\1&VMIt",[global])),
- <<"HLabxyzpqrrrabbxyyyypqAzzOTupMnssabxyzpqrrrabbxyyyypqAzzJs">> = iolist_to_binary(re:replace("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","HL&OTupMnss&\\1Js",[])),
- <<"HLabxyzpqrrrabbxyyyypqAzzOTupMnssabxyzpqrrrabbxyyyypqAzzJs">> = iolist_to_binary(re:replace("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","HL&OTupMnss&\\1Js",[global])),
- <<"HrnoCAoMBaabxyzpqrrrabbxyyyypqAzzUYaabxyzpqrrrabbxyyyypqAzzXaabxyzpqrrrabbxyyyypqAzzaabxyzpqrrrabbxyyyypqAzzaabxyzpqrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("aabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","HrnoCA\\1oM\\1B&\\1UY&X&&&",[])),
- <<"HrnoCAoMBaabxyzpqrrrabbxyyyypqAzzUYaabxyzpqrrrabbxyyyypqAzzXaabxyzpqrrrabbxyyyypqAzzaabxyzpqrrrabbxyyyypqAzzaabxyzpqrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("aabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","HrnoCA\\1oM\\1B&\\1UY&X&&&",[global])),
- <<"aaabxyzpqrrrabbxyyyypqAzzsiD">> = iolist_to_binary(re:replace("aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&siD",[])),
- <<"aaabxyzpqrrrabbxyyyypqAzzsiD">> = iolist_to_binary(re:replace("aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&siD",[global])),
- <<"aaaabxyzpqrrrabbxyyyypqAzzqgRtoWloBl">> = iolist_to_binary(re:replace("aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&q\\1gRt\\1oWloB\\1\\1\\1l",[])),
- <<"aaaabxyzpqrrrabbxyyyypqAzzqgRtoWloBl">> = iolist_to_binary(re:replace("aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&q\\1gRt\\1oWloB\\1\\1\\1l",[global])),
- <<"sRmsQabcxyzpqrrrabbxyyyypqAzzThd">> = iolist_to_binary(re:replace("abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","sRmsQ&Thd",[])),
- <<"sRmsQabcxyzpqrrrabbxyyyypqAzzThd">> = iolist_to_binary(re:replace("abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","sRmsQ&Thd",[global])),
- <<"aabcxyzpqrrrabbxyyyypqAzzRHoaabcxyzpqrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("aabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&RHo&",[])),
- <<"aabcxyzpqrrrabbxyyyypqAzzRHoaabcxyzpqrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("aabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&RHo&",[global])),
- <<"kaaabcxyzpqrrrabbxyyyypAzz">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","k\\1&",[])),
- <<"kaaabcxyzpqrrrabbxyyyypAzz">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","k\\1&",[global])),
- <<"RxvGiseEerlAfPpFb">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","RxvGiseEerlAfPp\\1F\\1b",[])),
- <<"RxvGiseEerlAfPpFb">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","RxvGiseEerlAfPp\\1F\\1b",[global])),
- <<"sUgRgemex">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","sUgR\\1gem\\1ex\\1",[])),
- <<"sUgRgemex">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","sUgR\\1gem\\1ex\\1",[global])),
- <<"S">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","S",[])),
- <<"S">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","S",[global])),
- <<"QCVAHkaaabcxyzpqrrrabbxyyyypqqqqAzzCsM">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","QCVAHk&CsM",[])),
- <<"QCVAHkaaabcxyzpqrrrabbxyyyypqqqqAzzCsM">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","QCVAHk&CsM",[global])),
- <<"kV">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","kV",[])),
- <<"kV">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","kV",[global])),
- <<"sEX">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","sEX",[])),
- <<"sEX">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","sEX",[global])),
- <<"lgaaaabcxyzpqrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","\\1lg&",[])),
- <<"lgaaaabcxyzpqrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","\\1lg&",[global])),
- <<"H">> = iolist_to_binary(re:replace("abxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","H",[])),
- <<"H">> = iolist_to_binary(re:replace("abxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","H",[global])),
- <<"sLyaabxyzzzpqrrrabbxyyyypqAzzJJPghXisEdXaabxyzzzpqrrrabbxyyyypqAzzS">> = iolist_to_binary(re:replace("aabxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","sLy&JJPghXi\\1sEdX&S\\1",[])),
- <<"sLyaabxyzzzpqrrrabbxyyyypqAzzJJPghXisEdXaabxyzzzpqrrrabbxyyyypqAzzS">> = iolist_to_binary(re:replace("aabxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","sLy&JJPghXi\\1sEdX&S\\1",[global])),
- <<"">> = iolist_to_binary(re:replace("aaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","\\1",[])),
- <<"">> = iolist_to_binary(re:replace("aaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","\\1",[global])),
- <<"XHrPpSaaaabxyzzzzpqrrrabbxyyyypqAzzgAh">> = iolist_to_binary(re:replace("aaaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","XHr\\1PpS&gAh",[])),
- <<"XHrPpSaaaabxyzzzzpqrrrabbxyyyypqAzzgAh">> = iolist_to_binary(re:replace("aaaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","XHr\\1PpS&gAh",[global])),
- <<"NeJBabcxyzzpqrrrabbxyyyypqAzzGo">> = iolist_to_binary(re:replace("abcxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","NeJB&Go",[])),
- <<"NeJBabcxyzzpqrrrabbxyyyypqAzzGo">> = iolist_to_binary(re:replace("abcxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","NeJB&Go",[global])),
- <<"mu">> = iolist_to_binary(re:replace("aabcxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","mu",[])),
- <<"mu">> = iolist_to_binary(re:replace("aabcxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","mu",[global])),
- <<"aaabcxyzzzzpqrrrabbxyyyypqAzzaaabcxyzzzzpqrrrabbxyyyypqAzzN">> = iolist_to_binary(re:replace("aaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&&N",[])),
- <<"aaabcxyzzzzpqrrrabbxyyyypqAzzaaabcxyzzzzpqrrrabbxyyyypqAzzN">> = iolist_to_binary(re:replace("aaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&&N",[global])),
- <<"TY">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","TY",[])),
- <<"TY">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","TY",[global])),
- <<"BSUyMaaaabcxyzzzzpqrrrabbbxyyyypqAzzeeab">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","BSUyM&e\\1eab",[])),
- <<"BSUyMaaaabcxyzzzzpqrrrabbbxyyyypqAzzeeab">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","BSUyM&e\\1eab",[global])),
- <<"bLbpTaaaabcxyzzzzpqrrrabbbxyyyyypqAzzcn">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","\\1bLbp\\1T&cn",[])),
- <<"bLbpTaaaabcxyzzzzpqrrrabbbxyyyyypqAzzcn">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","\\1bLbp\\1T&cn",[global])),
- <<"qOqibaaabcxyzpqrrrabbxyyyypABzzFnNENBaaabcxyzpqrrrabbxyyyypABzza">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypABzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","qOqib&F\\1\\1nNENB\\1&a",[])),
- <<"qOqibaaabcxyzpqrrrabbxyyyypABzzFnNENBaaabcxyzpqrrrabbxyyyypABzza">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypABzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","qOqib&F\\1\\1nNENB\\1&a",[global])),
- <<"SBfQjRuQKXkm">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypABBzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","SBf\\1\\1QjR\\1uQKXkm\\1",[])),
- <<"SBfQjRuQKXkm">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypABBzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","SBf\\1\\1QjR\\1uQKXkm\\1",[global])),
- <<">>>bVaaabxyzpqrrrabbxyyyypqAzzaaabxyzpqrrrabbxyyyypqAzzAiToCwaaabxyzpqrrrabbxyyyypqAzzcehOK">> = iolist_to_binary(re:replace(">>>aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","bV\\1\\1&&\\1AiToCw&cehOK",[])),
- <<">>>bVaaabxyzpqrrrabbxyyyypqAzzaaabxyzpqrrrabbxyyyypqAzzAiToCwaaabxyzpqrrrabbxyyyypqAzzcehOK">> = iolist_to_binary(re:replace(">>>aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","bV\\1\\1&&\\1AiToCw&cehOK",[global])),
- <<">RYHNAEdfNPaaaabxyzpqrrrabbxyyyypqAzzHLi">> = iolist_to_binary(re:replace(">aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","RY\\1HNA\\1\\1EdfNP&HLi",[])),
- <<">RYHNAEdfNPaaaabxyzpqrrrabbxyyyypqAzzHLi">> = iolist_to_binary(re:replace(">aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","RY\\1HNA\\1\\1EdfNP&HLi",[global])),
- <<">>>>wRIXabcxyzpqrrrabbxyyyypqAzzhabcxyzpqrrrabbxyyyypqAzzaCoikaFu">> = iolist_to_binary(re:replace(">>>>abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","\\1wRIX&h&aCoika\\1Fu",[])),
- <<">>>>wRIXabcxyzpqrrrabbxyyyypqAzzhabcxyzpqrrrabbxyyyypqAzzaCoikaFu">> = iolist_to_binary(re:replace(">>>>abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","\\1wRIX&h&aCoika\\1Fu",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","XSdFB",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","XSdFB",[global])),
- <<"abxyzpqrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","p&sjpo&\\1MeLw",[])),
- <<"abxyzpqrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","p&sjpo&\\1MeLw",[global])),
- <<"abxyzpqrrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","Np\\1BvTaI&WRss&",[])),
- <<"abxyzpqrrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","Np\\1BvTaI&WRss&",[global])),
- <<"abxyzpqrrrabxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrrabxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","Jm\\1&IqjePLT",[])),
- <<"abxyzpqrrrabxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrrabxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","Jm\\1&IqjePLT",[global])),
- <<"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","X&\\1EJejYwBT\\1N&Vu\\1\\1hj",[])),
- <<"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","X&\\1EJejYwBT\\1N&Vu\\1\\1hj",[global])),
- <<"aaaabcxyzzzzpqrrrabbbxyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","ACr\\1ExPn&TggeSRc&pgC",[])),
- <<"aaaabcxyzzzzpqrrrabbbxyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","ACr\\1ExPn&TggeSRc&pgC",[global])),
- <<"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","AQG",[])),
- <<"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","AQG",[global])),
- <<"Ms">> = iolist_to_binary(re:replace("abczz","^(abc){1,2}zz","Ms",[])),
- <<"Ms">> = iolist_to_binary(re:replace("abczz","^(abc){1,2}zz","Ms",[global])),
- <<"abcjqKYJWAabcabczzXCsCP">> = iolist_to_binary(re:replace("abcabczz","^(abc){1,2}zz","\\1jqKYJWA&XCsCP",[])),
- <<"abcjqKYJWAabcabczzXCsCP">> = iolist_to_binary(re:replace("abcabczz","^(abc){1,2}zz","\\1jqKYJWA&XCsCP",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(abc){1,2}zz","Q\\1PQoCjb\\1eQ&\\1JaSTQ",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(abc){1,2}zz","Q\\1PQoCjb\\1eQ&\\1JaSTQ",[global])),
- <<"zz">> = iolist_to_binary(re:replace("zz","^(abc){1,2}zz","DxU",[])),
- <<"zz">> = iolist_to_binary(re:replace("zz","^(abc){1,2}zz","DxU",[global])),
- <<"abcabcabczz">> = iolist_to_binary(re:replace("abcabcabczz","^(abc){1,2}zz","wRiyMR&vafm&",[])),
- <<"abcabcabczz">> = iolist_to_binary(re:replace("abcabcabczz","^(abc){1,2}zz","wRiyMR&vafm&",[global])),
- <<">>abczz">> = iolist_to_binary(re:replace(">>abczz","^(abc){1,2}zz","fCQBocoTpl&om",[])),
- <<">>abczz">> = iolist_to_binary(re:replace(">>abczz","^(abc){1,2}zz","fCQBocoTpl&om",[global])),
- <<"BbtYviciAuOmX">> = iolist_to_binary(re:replace("bc","^(b+?|a){1,2}?c","B\\1tYviciAuOmX",[])),
- <<"BbtYviciAuOmX">> = iolist_to_binary(re:replace("bc","^(b+?|a){1,2}?c","B\\1tYviciAuOmX",[global])),
- <<"bbcbbcmoxNDbcM">> = iolist_to_binary(re:replace("bbc","^(b+?|a){1,2}?c","&&moxND\\1cM",[])),
- <<"bbcbbcmoxNDbcM">> = iolist_to_binary(re:replace("bbc","^(b+?|a){1,2}?c","&&moxND\\1cM",[global])),
- <<"HmYAbbbcbbuUEdmhvgxQbbbb">> = iolist_to_binary(re:replace("bbbc","^(b+?|a){1,2}?c","HmYA&\\1uUEdmhvgxQ\\1\\1",[])),
- <<"HmYAbbbcbbuUEdmhvgxQbbbb">> = iolist_to_binary(re:replace("bbbc","^(b+?|a){1,2}?c","HmYA&\\1uUEdmhvgxQ\\1\\1",[global])),
- <<"YRq">> = iolist_to_binary(re:replace("bac","^(b+?|a){1,2}?c","YRq",[])),
- <<"YRq">> = iolist_to_binary(re:replace("bac","^(b+?|a){1,2}?c","YRq",[global])),
- <<"bbacaOVQYgoesBaHi">> = iolist_to_binary(re:replace("bbac","^(b+?|a){1,2}?c","&\\1OVQYgoesB\\1Hi",[])),
- <<"bbacaOVQYgoesBaHi">> = iolist_to_binary(re:replace("bbac","^(b+?|a){1,2}?c","&\\1OVQYgoesB\\1Hi",[global])),
- <<"dIraaacvlpk">> = iolist_to_binary(re:replace("aac","^(b+?|a){1,2}?c","dIr\\1&vlpk",[])),
- <<"dIraaacvlpk">> = iolist_to_binary(re:replace("aac","^(b+?|a){1,2}?c","dIr\\1&vlpk",[global])),
- <<"KbbbbbbbbbbbobbbbbbbbbbbFjgyx">> = iolist_to_binary(re:replace("abbbbbbbbbbbc","^(b+?|a){1,2}?c","K\\1o\\1Fjgyx",[])),
- <<"KbbbbbbbbbbbobbbbbbbbbbbFjgyx">> = iolist_to_binary(re:replace("abbbbbbbbbbbc","^(b+?|a){1,2}?c","K\\1o\\1Fjgyx",[global])),
- <<"dkNSkahOVMwoAfbbbbbbbbbbbacchbbbbbbbbbbbacKA">> = iolist_to_binary(re:replace("bbbbbbbbbbbac","^(b+?|a){1,2}?c","dkNSk\\1hOVMwoAf&ch&KA",[])),
- <<"dkNSkahOVMwoAfbbbbbbbbbbbacchbbbbbbbbbbbacKA">> = iolist_to_binary(re:replace("bbbbbbbbbbbac","^(b+?|a){1,2}?c","dkNSk\\1hOVMwoAf&ch&KA",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b+?|a){1,2}?c","lRqMfmvH",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b+?|a){1,2}?c","lRqMfmvH",[global])),
- <<"aaac">> = iolist_to_binary(re:replace("aaac","^(b+?|a){1,2}?c","Ya\\1SeSYOH",[])),
- <<"aaac">> = iolist_to_binary(re:replace("aaac","^(b+?|a){1,2}?c","Ya\\1SeSYOH",[global])),
- <<"abbbbbbbbbbbac">> = iolist_to_binary(re:replace("abbbbbbbbbbbac","^(b+?|a){1,2}?c","Mjs\\1&mpd",[])),
- <<"abbbbbbbbbbbac">> = iolist_to_binary(re:replace("abbbbbbbbbbbac","^(b+?|a){1,2}?c","Mjs\\1&mpd",[global])),
- <<"MbGjTbfbuoXTyLDU">> = iolist_to_binary(re:replace("bc","^(b+|a){1,2}c","M\\1GjT\\1f\\1uoXTyLDU",[])),
- <<"MbGjTbfbuoXTyLDU">> = iolist_to_binary(re:replace("bc","^(b+|a){1,2}c","M\\1GjT\\1f\\1uoXTyLDU",[global])),
- <<"Xbbbbcbbihpfm">> = iolist_to_binary(re:replace("bbc","^(b+|a){1,2}c","X\\1&\\1ihpfm",[])),
- <<"Xbbbbcbbihpfm">> = iolist_to_binary(re:replace("bbc","^(b+|a){1,2}c","X\\1&\\1ihpfm",[global])),
- <<"bbbbbbpCDbbLKbbbq">> = iolist_to_binary(re:replace("bbbc","^(b+|a){1,2}c","\\1\\1pCDbbLK\\1q",[])),
- <<"bbbbbbpCDbbLKbbbq">> = iolist_to_binary(re:replace("bbbc","^(b+|a){1,2}c","\\1\\1pCDbbLK\\1q",[global])),
- <<"bacjc">> = iolist_to_binary(re:replace("bac","^(b+|a){1,2}c","&jc",[])),
- <<"bacjc">> = iolist_to_binary(re:replace("bac","^(b+|a){1,2}c","&jc",[global])),
- <<"bbacmybbacWtbbacjPQXaybbacl">> = iolist_to_binary(re:replace("bbac","^(b+|a){1,2}c","&my&Wt&jPQXay&l",[])),
- <<"bbacmybbacWtbbacjPQXaybbacl">> = iolist_to_binary(re:replace("bbac","^(b+|a){1,2}c","&my&Wt&jPQXay&l",[global])),
- <<"QcYXpaaGA">> = iolist_to_binary(re:replace("aac","^(b+|a){1,2}c","QcYXpa\\1GA",[])),
- <<"QcYXpaaGA">> = iolist_to_binary(re:replace("aac","^(b+|a){1,2}c","QcYXpa\\1GA",[global])),
- <<"habbbbbbbbbbbcYbbbbbbbbbbbY">> = iolist_to_binary(re:replace("abbbbbbbbbbbc","^(b+|a){1,2}c","h&Y\\1Y",[])),
- <<"habbbbbbbbbbbcYbbbbbbbbbbbY">> = iolist_to_binary(re:replace("abbbbbbbbbbbc","^(b+|a){1,2}c","h&Y\\1Y",[global])),
- <<"DkD">> = iolist_to_binary(re:replace("bbbbbbbbbbbac","^(b+|a){1,2}c","DkD",[])),
- <<"DkD">> = iolist_to_binary(re:replace("bbbbbbbbbbbac","^(b+|a){1,2}c","DkD",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b+|a){1,2}c","UgARueRrJoL\\1\\1WgjAP",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b+|a){1,2}c","UgARueRrJoL\\1\\1WgjAP",[global])),
- <<"aaac">> = iolist_to_binary(re:replace("aaac","^(b+|a){1,2}c","IGJPbXNc&kfu\\1xi",[])),
- <<"aaac">> = iolist_to_binary(re:replace("aaac","^(b+|a){1,2}c","IGJPbXNc&kfu\\1xi",[global])),
- <<"abbbbbbbbbbbac">> = iolist_to_binary(re:replace("abbbbbbbbbbbac","^(b+|a){1,2}c","pWvBeG&&iyL",[])),
- <<"abbbbbbbbbbbac">> = iolist_to_binary(re:replace("abbbbbbbbbbbac","^(b+|a){1,2}c","pWvBeG&&iyL",[global])),
- <<"g">> = iolist_to_binary(re:replace("bbc","^(b+|a){1,2}?bc","g",[])),
- <<"g">> = iolist_to_binary(re:replace("bbc","^(b+|a){1,2}?bc","g",[global])),
- <<"rXsdbaababcQbambabcWcnvbj">> = iolist_to_binary(re:replace("babc","^(b*|ba){1,2}?bc","rXsd\\1a&Q\\1m&Wcnvbj",[])),
- <<"rXsdbaababcQbambabcWcnvbj">> = iolist_to_binary(re:replace("babc","^(b*|ba){1,2}?bc","rXsd\\1a&Q\\1m&Wcnvbj",[global])),
- <<"x">> = iolist_to_binary(re:replace("bbabc","^(b*|ba){1,2}?bc","x",[])),
- <<"x">> = iolist_to_binary(re:replace("bbabc","^(b*|ba){1,2}?bc","x",[global])),
- <<"TMNcgqpTbaE">> = iolist_to_binary(re:replace("bababc","^(b*|ba){1,2}?bc","TMNcgqpT\\1E",[])),
- <<"TMNcgqpTbaE">> = iolist_to_binary(re:replace("bababc","^(b*|ba){1,2}?bc","TMNcgqpT\\1E",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b*|ba){1,2}?bc","IM",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b*|ba){1,2}?bc","IM",[global])),
- <<"bababbc">> = iolist_to_binary(re:replace("bababbc","^(b*|ba){1,2}?bc","TbVp\\1&mhNgFw\\1",[])),
- <<"bababbc">> = iolist_to_binary(re:replace("bababbc","^(b*|ba){1,2}?bc","TbVp\\1&mhNgFw\\1",[global])),
- <<"babababc">> = iolist_to_binary(re:replace("babababc","^(b*|ba){1,2}?bc","&yrdhkl&hx&\\1M\\1\\1BiFK",[])),
- <<"babababc">> = iolist_to_binary(re:replace("babababc","^(b*|ba){1,2}?bc","&yrdhkl&hx&\\1M\\1\\1BiFK",[global])),
- <<"bailvqbafDWIOQe">> = iolist_to_binary(re:replace("babc","^(ba|b*){1,2}?bc","\\1ilvq\\1fDWIOQe",[])),
- <<"bailvqbafDWIOQe">> = iolist_to_binary(re:replace("babc","^(ba|b*){1,2}?bc","\\1ilvq\\1fDWIOQe",[global])),
- <<"o">> = iolist_to_binary(re:replace("bbabc","^(ba|b*){1,2}?bc","o",[])),
- <<"o">> = iolist_to_binary(re:replace("bbabc","^(ba|b*){1,2}?bc","o",[global])),
- <<"qyH">> = iolist_to_binary(re:replace("bababc","^(ba|b*){1,2}?bc","qyH",[])),
- <<"qyH">> = iolist_to_binary(re:replace("bababc","^(ba|b*){1,2}?bc","qyH",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(ba|b*){1,2}?bc","GBLVYAxKwO",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(ba|b*){1,2}?bc","GBLVYAxKwO",[global])),
- <<"bababbc">> = iolist_to_binary(re:replace("bababbc","^(ba|b*){1,2}?bc","u&GWGypjK&r\\1\\1&",[])),
- <<"bababbc">> = iolist_to_binary(re:replace("bababbc","^(ba|b*){1,2}?bc","u&GWGypjK&r\\1\\1&",[global])),
- <<"babababc">> = iolist_to_binary(re:replace("babababc","^(ba|b*){1,2}?bc","Vb",[])),
- <<"babababc">> = iolist_to_binary(re:replace("babababc","^(ba|b*){1,2}?bc","Vb",[global])),
- <<"nli;znvMfDQEb;zGHXN">> = iolist_to_binary(re:replace(";z","^\\ca\\cA\\c[\\c{\\c:","nli\\1\\1&nv\\1MfDQEb&GHXN",[])),
- <<"nli;znvMfDQEb;zGHXN">> = iolist_to_binary(re:replace(";z","^\\ca\\cA\\c[\\c{\\c:","nli\\1\\1&nv\\1MfDQEb&GHXN",[global])),
- <<"yxcaleHEFWgGiwbQathing">> = iolist_to_binary(re:replace("athing","^[ab\\]cde]","\\1yxc\\1&leHE\\1FWgGiwbQ&",[])),
- <<"yxcaleHEFWgGiwbQathing">> = iolist_to_binary(re:replace("athing","^[ab\\]cde]","\\1yxc\\1&leHE\\1FWgGiwbQ&",[global])),
- <<"MeNvthing">> = iolist_to_binary(re:replace("bthing","^[ab\\]cde]","MeNv\\1",[])),
- <<"MeNvthing">> = iolist_to_binary(re:replace("bthing","^[ab\\]cde]","MeNv\\1",[global])),
- <<"]T]qQDvRdthing">> = iolist_to_binary(re:replace("]thing","^[ab\\]cde]","&T&qQDvRd",[])),
- <<"]T]qQDvRdthing">> = iolist_to_binary(re:replace("]thing","^[ab\\]cde]","&T&qQDvRd",[global])),
- <<"GFxthing">> = iolist_to_binary(re:replace("cthing","^[ab\\]cde]","GFx",[])),
- <<"GFxthing">> = iolist_to_binary(re:replace("cthing","^[ab\\]cde]","GFx",[global])),
- <<"kLFxTOaEthing">> = iolist_to_binary(re:replace("dthing","^[ab\\]cde]","kLFxTOaE",[])),
- <<"kLFxTOaEthing">> = iolist_to_binary(re:replace("dthing","^[ab\\]cde]","kLFxTOaE",[global])),
- <<"RtthVFthing">> = iolist_to_binary(re:replace("ething","^[ab\\]cde]","Rtt\\1hVF",[])),
- <<"RtthVFthing">> = iolist_to_binary(re:replace("ething","^[ab\\]cde]","Rtt\\1hVF",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[ab\\]cde]","Srer\\1pi",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[ab\\]cde]","Srer\\1pi",[global])),
- <<"fthing">> = iolist_to_binary(re:replace("fthing","^[ab\\]cde]","&AaO",[])),
- <<"fthing">> = iolist_to_binary(re:replace("fthing","^[ab\\]cde]","&AaO",[global])),
- <<"[thing">> = iolist_to_binary(re:replace("[thing","^[ab\\]cde]","GujQJxlam\\1f\\1FD",[])),
- <<"[thing">> = iolist_to_binary(re:replace("[thing","^[ab\\]cde]","GujQJxlam\\1f\\1FD",[global])),
- <<"\\thing">> = iolist_to_binary(re:replace("\\thing","^[ab\\]cde]","&&yX",[])),
- <<"\\thing">> = iolist_to_binary(re:replace("\\thing","^[ab\\]cde]","&&yX",[global])),
- <<"s]tXLkthing">> = iolist_to_binary(re:replace("]thing","^[]cde]","s&tXLk",[])),
- <<"s]tXLkthing">> = iolist_to_binary(re:replace("]thing","^[]cde]","s&tXLk",[global])),
- <<"HiVDFyrMvAaDvdYdUthing">> = iolist_to_binary(re:replace("cthing","^[]cde]","H\\1iVDFyrMvAaDv\\1\\1dYdU",[])),
- <<"HiVDFyrMvAaDvdYdUthing">> = iolist_to_binary(re:replace("cthing","^[]cde]","H\\1iVDFyrMvAaDv\\1\\1dYdU",[global])),
- <<"jkWeKNthing">> = iolist_to_binary(re:replace("dthing","^[]cde]","jkWeKN",[])),
- <<"jkWeKNthing">> = iolist_to_binary(re:replace("dthing","^[]cde]","jkWeKN",[global])),
- <<"strycWDFQcthing">> = iolist_to_binary(re:replace("ething","^[]cde]","stry\\1cWDFQc",[])),
- <<"strycWDFQcthing">> = iolist_to_binary(re:replace("ething","^[]cde]","stry\\1cWDFQc",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[]cde]","s",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[]cde]","s",[global])),
- <<"athing">> = iolist_to_binary(re:replace("athing","^[]cde]","\\1xREinh\\1vCv",[])),
- <<"athing">> = iolist_to_binary(re:replace("athing","^[]cde]","\\1xREinh\\1vCv",[global])),
- <<"fthing">> = iolist_to_binary(re:replace("fthing","^[]cde]","\\1h&Y\\1HwTkCc",[])),
- <<"fthing">> = iolist_to_binary(re:replace("fthing","^[]cde]","\\1h&Y\\1HwTkCc",[global])),
- <<"uifmTffffWmKXllBthing">> = iolist_to_binary(re:replace("fthing","^[^ab\\]cde]","ui&mT&f&&WmKXllB",[])),
- <<"uifmTffffWmKXllBthing">> = iolist_to_binary(re:replace("fthing","^[^ab\\]cde]","ui&mT&f&&WmKXllB",[global])),
- <<"Kyn[lihrXoXthing">> = iolist_to_binary(re:replace("[thing","^[^ab\\]cde]","Kyn&lihrXoX",[])),
- <<"Kyn[lihrXoXthing">> = iolist_to_binary(re:replace("[thing","^[^ab\\]cde]","Kyn&lihrXoX",[global])),
- <<"UXMYd\\fthing">> = iolist_to_binary(re:replace("\\thing","^[^ab\\]cde]","U\\1XMYd\\1\\1&f\\1",[])),
- <<"UXMYd\\fthing">> = iolist_to_binary(re:replace("\\thing","^[^ab\\]cde]","U\\1XMYd\\1\\1&f\\1",[global])),
- <<"QYuh*KpbKbO** Failers">> = iolist_to_binary(re:replace("*** Failers","^[^ab\\]cde]","\\1QYuh&KpbKbO",[])),
- <<"QYuh*KpbKbO** Failers">> = iolist_to_binary(re:replace("*** Failers","^[^ab\\]cde]","\\1QYuh&KpbKbO",[global])),
- <<"athing">> = iolist_to_binary(re:replace("athing","^[^ab\\]cde]","JwKDqeNpO\\1&m",[])),
- <<"athing">> = iolist_to_binary(re:replace("athing","^[^ab\\]cde]","JwKDqeNpO\\1&m",[global])),
- <<"bthing">> = iolist_to_binary(re:replace("bthing","^[^ab\\]cde]","G",[])),
- <<"bthing">> = iolist_to_binary(re:replace("bthing","^[^ab\\]cde]","G",[global])),
- <<"]thing">> = iolist_to_binary(re:replace("]thing","^[^ab\\]cde]","VomLLa&\\1xDtJWx",[])),
- <<"]thing">> = iolist_to_binary(re:replace("]thing","^[^ab\\]cde]","VomLLa&\\1xDtJWx",[global])),
- <<"cthing">> = iolist_to_binary(re:replace("cthing","^[^ab\\]cde]","&DWkG&&kk",[])),
- <<"cthing">> = iolist_to_binary(re:replace("cthing","^[^ab\\]cde]","&DWkG&&kk",[global])),
- <<"dthing">> = iolist_to_binary(re:replace("dthing","^[^ab\\]cde]","MYpgcbh&\\1knLFcDqwN",[])),
- <<"dthing">> = iolist_to_binary(re:replace("dthing","^[^ab\\]cde]","MYpgcbh&\\1knLFcDqwN",[global])),
- <<"ething">> = iolist_to_binary(re:replace("ething","^[^ab\\]cde]","h\\1nb\\1c&&KMVOIu",[])),
- <<"ething">> = iolist_to_binary(re:replace("ething","^[^ab\\]cde]","h\\1nb\\1c&&KMVOIu",[global])),
- <<"qRaQDneiathing">> = iolist_to_binary(re:replace("athing","^[^]cde]","qR&QDnei&",[])),
- <<"qRaQDneiathing">> = iolist_to_binary(re:replace("athing","^[^]cde]","qR&QDnei&",[global])),
- <<"YtUthing">> = iolist_to_binary(re:replace("fthing","^[^]cde]","YtU",[])),
- <<"YtUthing">> = iolist_to_binary(re:replace("fthing","^[^]cde]","YtU",[global])),
- <<"PUGKhoJ*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[^]cde]","P\\1UGKhoJ&",[])),
- <<"PUGKhoJ*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[^]cde]","P\\1UGKhoJ&",[global])),
- <<"]thing">> = iolist_to_binary(re:replace("]thing","^[^]cde]","Xh&gbPHspjXNu&YKXwHH",[])),
- <<"]thing">> = iolist_to_binary(re:replace("]thing","^[^]cde]","Xh&gbPHspjXNu&YKXwHH",[global])),
- <<"cthing">> = iolist_to_binary(re:replace("cthing","^[^]cde]","kmMlgoXI&xF\\1hwlT",[])),
- <<"cthing">> = iolist_to_binary(re:replace("cthing","^[^]cde]","kmMlgoXI&xF\\1hwlT",[global])),
- <<"dthing">> = iolist_to_binary(re:replace("dthing","^[^]cde]","ue\\1\\1DU",[])),
- <<"dthing">> = iolist_to_binary(re:replace("dthing","^[^]cde]","ue\\1\\1DU",[global])),
- <<"ething">> = iolist_to_binary(re:replace("ething","^[^]cde]","x\\1CM",[])),
- <<"ething">> = iolist_to_binary(re:replace("ething","^[^]cde]","x\\1CM",[global])),
- <<"skV">> = iolist_to_binary(re:replace("0","^[0-9]+$","sk\\1V\\1",[])),
- <<"skV">> = iolist_to_binary(re:replace("0","^[0-9]+$","sk\\1V\\1",[global])),
- <<"dchqDQcnPE1m">> = iolist_to_binary(re:replace("1","^[0-9]+$","dchqDQcnPE&m",[])),
- <<"dchqDQcnPE1m">> = iolist_to_binary(re:replace("1","^[0-9]+$","dchqDQcnPE&m",[global])),
- <<"iKMEYpXlyVKXB">> = iolist_to_binary(re:replace("2","^[0-9]+$","iKMEYpXlyVK\\1XB",[])),
- <<"iKMEYpXlyVKXB">> = iolist_to_binary(re:replace("2","^[0-9]+$","iKMEYpXlyVK\\1XB",[global])),
- <<"lTM3XtBQD3KqG33G">> = iolist_to_binary(re:replace("3","^[0-9]+$","lTM&X\\1tBQD&KqG&&G",[])),
- <<"lTM3XtBQD3KqG33G">> = iolist_to_binary(re:replace("3","^[0-9]+$","lTM&X\\1tBQD&KqG&&G",[global])),
- <<"A4RtR4paCNffVmKS44ru">> = iolist_to_binary(re:replace("4","^[0-9]+$","A&RtR&paCNffVmKS&&ru",[])),
- <<"A4RtR4paCNffVmKS44ru">> = iolist_to_binary(re:replace("4","^[0-9]+$","A&RtR&paCNffVmKS&&ru",[global])),
- <<"FvNdw">> = iolist_to_binary(re:replace("5","^[0-9]+$","F\\1vNdw",[])),
- <<"FvNdw">> = iolist_to_binary(re:replace("5","^[0-9]+$","F\\1vNdw",[global])),
- <<"6bMIirlh">> = iolist_to_binary(re:replace("6","^[0-9]+$","&bMIi\\1rlh",[])),
- <<"6bMIirlh">> = iolist_to_binary(re:replace("6","^[0-9]+$","&bMIi\\1rlh",[global])),
- <<"7IgF">> = iolist_to_binary(re:replace("7","^[0-9]+$","\\1\\1&IgF\\1\\1",[])),
- <<"7IgF">> = iolist_to_binary(re:replace("7","^[0-9]+$","\\1\\1&IgF\\1\\1",[global])),
- <<"kXpaB8C">> = iolist_to_binary(re:replace("8","^[0-9]+$","kXpaB&C",[])),
- <<"kXpaB8C">> = iolist_to_binary(re:replace("8","^[0-9]+$","kXpaB&C",[global])),
- <<"rxDNFoULsT">> = iolist_to_binary(re:replace("9","^[0-9]+$","rxDNFoULsT",[])),
- <<"rxDNFoULsT">> = iolist_to_binary(re:replace("9","^[0-9]+$","rxDNFoULsT",[global])),
- <<"YmBdr10cd10f10RQlRK">> = iolist_to_binary(re:replace("10","^[0-9]+$","YmBd\\1r&cd&f&RQlRK",[])),
- <<"YmBdr10cd10f10RQlRK">> = iolist_to_binary(re:replace("10","^[0-9]+$","YmBd\\1r&cd&f&RQlRK",[global])),
- <<"RLqdwwceTW">> = iolist_to_binary(re:replace("100","^[0-9]+$","RLqdwwceTW\\1",[])),
- <<"RLqdwwceTW">> = iolist_to_binary(re:replace("100","^[0-9]+$","RLqdwwceTW\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[0-9]+$","BdnjJh\\1urLa&",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[0-9]+$","BdnjJh\\1urLa&",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","^[0-9]+$","&&oa&dfYGxAdt&\\1\\1Q&m",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","^[0-9]+$","&&oa&dfYGxAdt&\\1\\1Q&m",[global])),
- <<"ndenterMpPenterqHbSYUGGN">> = iolist_to_binary(re:replace("enter","^.*nter","nd&MpP&qHb\\1SY\\1UGGN",[])),
- <<"ndenterMpPenterqHbSYUGGN">> = iolist_to_binary(re:replace("enter","^.*nter","nd&MpP&qHb\\1SY\\1UGGN",[global])),
- <<"LSinterEPdYinterHoNIyUIDOinter">> = iolist_to_binary(re:replace("inter","^.*nter","LS&\\1EPdY&Ho\\1NIyUIDO&",[])),
- <<"LSinterEPdYinterHoNIyUIDOinter">> = iolist_to_binary(re:replace("inter","^.*nter","LS&\\1EPdY&Ho\\1NIyUIDO&",[global])),
- <<"IIUwhHsQfXMYBSb">> = iolist_to_binary(re:replace("uponter","^.*nter","IIUwhHsQ\\1fX\\1MYBS\\1b",[])),
- <<"IIUwhHsQfXMYBSb">> = iolist_to_binary(re:replace("uponter","^.*nter","IIUwhHsQ\\1fX\\1MYBS\\1b",[global])),
+ <<"SSxHvfHfMHTdP">> = iolist_to_binary(re:replace("the quick brown fox","the quick brown fox","SSx\\1HvfHfMHTdP",[])),
+ <<"SSxHvfHfMHTdP">> = iolist_to_binary(re:replace("the quick brown fox","the quick brown fox","SSx\\1HvfHfMHTdP",[global])),
+ <<"The quick brown FOX">> = iolist_to_binary(re:replace("The quick brown FOX","the quick brown fox","sSrOvIDlw&sr",[])),
+ <<"The quick brown FOX">> = iolist_to_binary(re:replace("The quick brown FOX","the quick brown fox","sSrOvIDlw&sr",[global])),
+ <<"What do you know about HAthe quick brown foxExLcRRqeQthe quick brown foxe?">> = iolist_to_binary(re:replace("What do you know about the quick brown fox?","the quick brown fox","HA&ExLcRRqeQ&e",[])),
+ <<"What do you know about HAthe quick brown foxExLcRRqeQthe quick brown foxe?">> = iolist_to_binary(re:replace("What do you know about the quick brown fox?","the quick brown fox","HA&ExLcRRqeQ&e",[global])),
+ <<"What do you know about THE QUICK BROWN FOX?">> = iolist_to_binary(re:replace("What do you know about THE QUICK BROWN FOX?","the quick brown fox","l",[])),
+ <<"What do you know about THE QUICK BROWN FOX?">> = iolist_to_binary(re:replace("What do you know about THE QUICK BROWN FOX?","the quick brown fox","l",[global])),
+ <<"x">> = iolist_to_binary(re:replace("the quick brown fox","The quick brown fox","x",[caseless])),
+ <<"x">> = iolist_to_binary(re:replace("the quick brown fox","The quick brown fox","x",[caseless,
+ global])),
+ <<"SODNIyIgxThe quick brown FOXBThe quick brown FOXbBb">> = iolist_to_binary(re:replace("The quick brown FOX","The quick brown fox","SOD\\1NIy\\1Igx&B&b\\1Bb",[caseless])),
+ <<"SODNIyIgxThe quick brown FOXBThe quick brown FOXbBb">> = iolist_to_binary(re:replace("The quick brown FOX","The quick brown fox","SOD\\1NIy\\1Igx&B&b\\1Bb",[caseless,
+ global])),
+ <<"What do you know about TI?">> = iolist_to_binary(re:replace("What do you know about the quick brown fox?","The quick brown fox","TI",[caseless])),
+ <<"What do you know about TI?">> = iolist_to_binary(re:replace("What do you know about the quick brown fox?","The quick brown fox","TI",[caseless,
+ global])),
+ <<"What do you know about miTHE QUICK BROWN FOX?">> = iolist_to_binary(re:replace("What do you know about THE QUICK BROWN FOX?","The quick brown fox","mi&",[caseless])),
+ <<"What do you know about miTHE QUICK BROWN FOX?">> = iolist_to_binary(re:replace("What do you know about THE QUICK BROWN FOX?","The quick brown fox","mi&",[caseless,
+ global])),
+ <<"LhLxqabcd
+ 9;$\\?caxyzBxFJ">> = iolist_to_binary(re:replace("abcd
+ 9;$\\?caxyz","abcd\\t\\n\\r\\f\\a\\e\\071\\x3b\\$\\\\\\?caxyz","LhLxq&\\1Bx\\1FJ",[])),
+ <<"LhLxqabcd
+ 9;$\\?caxyzBxFJ">> = iolist_to_binary(re:replace("abcd
+ 9;$\\?caxyz","abcd\\t\\n\\r\\f\\a\\e\\071\\x3b\\$\\\\\\?caxyz","LhLxq&\\1Bx\\1FJ",[global])),
+ <<"wqqHkXDku">> = iolist_to_binary(re:replace("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","wqqHkXDku",[])),
+ <<"wqqHkXDku">> = iolist_to_binary(re:replace("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","wqqHkXDku",[global])),
+ <<"jL">> = iolist_to_binary(re:replace("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","jL",[])),
+ <<"jL">> = iolist_to_binary(re:replace("abxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","jL",[global])),
+ <<"IIBgfOPaabxyzpqrrrabbxyyyypqAzzaabxyzpqrrrabbxyyyypqAzzUE">> = iolist_to_binary(re:replace("aabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","IIBgfOP&&UE",[])),
+ <<"IIBgfOPaabxyzpqrrrabbxyyyypqAzzaabxyzpqrrrabbxyyyypqAzzUE">> = iolist_to_binary(re:replace("aabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","IIBgfOP&&UE",[global])),
+ <<"asmnbaRlhmj">> = iolist_to_binary(re:replace("aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","as\\1mnbaRlhmj",[])),
+ <<"asmnbaRlhmj">> = iolist_to_binary(re:replace("aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","as\\1mnbaRlhmj",[global])),
+ <<"PPkDpiQNRoIwOISn">> = iolist_to_binary(re:replace("aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","PPkDpiQNRoIwOISn",[])),
+ <<"PPkDpiQNRoIwOISn">> = iolist_to_binary(re:replace("aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","PPkDpiQNRoIwOISn",[global])),
+ <<"WA">> = iolist_to_binary(re:replace("abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","WA",[])),
+ <<"WA">> = iolist_to_binary(re:replace("abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","WA",[global])),
+ <<"MmDiT">> = iolist_to_binary(re:replace("aabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","MmDiT\\1",[])),
+ <<"MmDiT">> = iolist_to_binary(re:replace("aabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","MmDiT\\1",[global])),
+ <<"rvMxRG">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","r\\1vMxRG",[])),
+ <<"rvMxRG">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","r\\1vMxRG",[global])),
+ <<"PNbQpnwvNqPbU">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","PNbQpnwvNqPb\\1U",[])),
+ <<"PNbQpnwvNqPbU">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","PNbQpnwvNqPb\\1U",[global])),
+ <<"aaabcxyzpqrrrabbxyyyypqqAzzYVt">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&YVt",[])),
+ <<"aaabcxyzpqrrrabbxyyyypqqAzzYVt">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&YVt",[global])),
+ <<"gMA">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","gMA",[])),
+ <<"gMA">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","gMA",[global])),
+ <<"PkGaaabcxyzpqrrrabbxyyyypqqqqAzzHIbA">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","PkG&HIbA",[])),
+ <<"PkGaaabcxyzpqrrrabbxyyyypqqqqAzzHIbA">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","PkG&HIbA",[global])),
+ <<"NAVDRk">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","N\\1AVDRk\\1",[])),
+ <<"NAVDRk">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","N\\1AVDRk\\1",[global])),
+ <<"l">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","l",[])),
+ <<"l">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","l",[global])),
+ <<"i">> = iolist_to_binary(re:replace("aaaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","i",[])),
+ <<"i">> = iolist_to_binary(re:replace("aaaabcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","i",[global])),
+ <<"gsLSabxyzzpqrrrabbxyyyypqAzzmSnQdb">> = iolist_to_binary(re:replace("abxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","gsLS&mSnQdb",[])),
+ <<"gsLSabxyzzpqrrrabbxyyyypqAzzmSnQdb">> = iolist_to_binary(re:replace("abxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","gsLS&mSnQdb",[global])),
+ <<"kaabxyzzzpqrrrabbxyyyypqAzzKdaabxyzzzpqrrrabbxyyyypqAzzaabxyzzzpqrrrabbxyyyypqAzzoPf">> = iolist_to_binary(re:replace("aabxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","k\\1&Kd&&oPf",[])),
+ <<"kaabxyzzzpqrrrabbxyyyypqAzzKdaabxyzzzpqrrrabbxyyyypqAzzaabxyzzzpqrrrabbxyyyypqAzzoPf">> = iolist_to_binary(re:replace("aabxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","k\\1&Kd&&oPf",[global])),
+ <<"dgKHkAqsVS">> = iolist_to_binary(re:replace("aaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","dgKH\\1kAqsVS",[])),
+ <<"dgKHkAqsVS">> = iolist_to_binary(re:replace("aaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","dgKH\\1kAqsVS",[global])),
+ <<"meKaaaabxyzzzzpqrrrabbxyyyypqAzzPvFP">> = iolist_to_binary(re:replace("aaaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","\\1meK&\\1\\1PvFP",[])),
+ <<"meKaaaabxyzzzzpqrrrabbxyyyypqAzzPvFP">> = iolist_to_binary(re:replace("aaaabxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","\\1meK&\\1\\1PvFP",[global])),
+ <<"YNabcxyzzpqrrrabbxyyyypqAzzTEpGJfWxCPabcxyzzpqrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("abcxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","YN&TEpGJfWxCP&",[])),
+ <<"YNabcxyzzpqrrrabbxyyyypqAzzTEpGJfWxCPabcxyzzpqrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("abcxyzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","YN&TEpGJfWxCP&",[global])),
+ <<"SaabcxyzzzpqrrrabbxyyyypqAzzwJjqEgHHwYYq">> = iolist_to_binary(re:replace("aabcxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","S&w\\1JjqE\\1gHHwYYq",[])),
+ <<"SaabcxyzzzpqrrrabbxyyyypqAzzwJjqEgHHwYYq">> = iolist_to_binary(re:replace("aabcxyzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","S&w\\1JjqE\\1gHHwYYq",[global])),
+ <<"aaabcxyzzzzpqrrrabbxyyyypqAzzGwVGaaabcxyzzzzpqrrrabbxyyyypqAzzlvXk">> = iolist_to_binary(re:replace("aaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&GwVG&lvXk\\1\\1",[])),
+ <<"aaabcxyzzzzpqrrrabbxyyyypqAzzGwVGaaabcxyzzzzpqrrrabbxyyyypqAzzlvXk">> = iolist_to_binary(re:replace("aaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&GwVG&lvXk\\1\\1",[global])),
+ <<"aaaabcxyzzzzpqrrrabbxyyyypqAzznNjmmVWTBVTADm">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&nN\\1jmmVWTBVTADm",[])),
+ <<"aaaabcxyzzzzpqrrrabbxyyyypqAzznNjmmVWTBVTADm">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&nN\\1jmmVWTBVTADm",[global])),
+ <<"PoqkwiYVqDWATAJwKaaaabcxyzzzzpqrrrabbbxyyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","Po\\1qkwiYVqDWATAJw\\1K&",[])),
+ <<"PoqkwiYVqDWATAJwKaaaabcxyzzzzpqrrrabbbxyyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","Po\\1qkwiYVqDWATAJw\\1K&",[global])),
+ <<"JNUVqARhXKto">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","JNUVqARh\\1\\1XKto",[])),
+ <<"JNUVqARhXKto">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","JNUVqARh\\1\\1XKto",[global])),
+ <<"ssvjVvyXuCJeoj">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypABzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","ss\\1vjVvyXuCJ\\1eoj\\1",[])),
+ <<"ssvjVvyXuCJeoj">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypABzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","ss\\1vjVvyXuCJ\\1eoj\\1",[global])),
+ <<"IKBpn">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypABBzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","IK\\1Bpn",[])),
+ <<"IKBpn">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypABBzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","IK\\1Bpn",[global])),
+ <<">>>GGeaaabxyzpqrrrabbxyyyypqAzzrpKAckaaabxyzpqrrrabbxyyyypqAzzaGC">> = iolist_to_binary(re:replace(">>>aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","GGe&rpKAc\\1k&aGC",[])),
+ <<">>>GGeaaabxyzpqrrrabbxyyyypqAzzrpKAckaaabxyzpqrrrabbxyyyypqAzzaGC">> = iolist_to_binary(re:replace(">>>aaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","GGe&rpKAc\\1k&aGC",[global])),
+ <<">P">> = iolist_to_binary(re:replace(">aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","P",[])),
+ <<">P">> = iolist_to_binary(re:replace(">aaaabxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","P",[global])),
+ <<">>>>abcxyzpqrrrabbxyyyypqAzzqKSkoXQtabcxyzpqrrrabbxyyyypqAzzabcxyzpqrrrabbxyyyypqAzzGFnXukr">> = iolist_to_binary(re:replace(">>>>abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&qKSkoXQt&&GFnXukr",[])),
+ <<">>>>abcxyzpqrrrabbxyyyypqAzzqKSkoXQtabcxyzpqrrrabbxyyyypqAzzabcxyzpqrrrabbxyyyypqAzzGFnXukr">> = iolist_to_binary(re:replace(">>>>abcxyzpqrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&qKSkoXQt&&GFnXukr",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","th\\1ha",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","th\\1ha",[global])),
+ <<"abxyzpqrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&h&ni&NOS&oHE&M&DW",[])),
+ <<"abxyzpqrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","&h&ni&NOS&oHE&M&DW",[global])),
+ <<"abxyzpqrrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","DyO",[])),
+ <<"abxyzpqrrrrabbxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrrrabbxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","DyO",[global])),
+ <<"abxyzpqrrrabxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrrabxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","nRi\\1FPGQknWL",[])),
+ <<"abxyzpqrrrabxyyyypqAzz">> = iolist_to_binary(re:replace("abxyzpqrrrabxyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","nRi\\1FPGQknWL",[global])),
+ <<"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","Gx\\1lJTyU\\1&dN\\1lmHTg",[])),
+ <<"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","Gx\\1lJTyU\\1&dN\\1lmHTg",[global])),
+ <<"aaaabcxyzzzzpqrrrabbbxyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","uX",[])),
+ <<"aaaabcxyzzzzpqrrrabbbxyyypqAzz">> = iolist_to_binary(re:replace("aaaabcxyzzzzpqrrrabbbxyyypqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","uX",[global])),
+ <<"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","uP\\1\\1P",[])),
+ <<"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz">> = iolist_to_binary(re:replace("aaabcxyzpqrrrabbxyyyypqqqqqqqAzz","a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz","uP\\1\\1P",[global])),
+ <<"AabczzNnWikVeHlabcthmw">> = iolist_to_binary(re:replace("abczz","^(abc){1,2}zz","A&NnWikVeHl\\1thmw",[])),
+ <<"AabczzNnWikVeHlabcthmw">> = iolist_to_binary(re:replace("abczz","^(abc){1,2}zz","A&NnWikVeHl\\1thmw",[global])),
+ <<"ljC">> = iolist_to_binary(re:replace("abcabczz","^(abc){1,2}zz","ljC",[])),
+ <<"ljC">> = iolist_to_binary(re:replace("abcabczz","^(abc){1,2}zz","ljC",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(abc){1,2}zz","H&dW",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(abc){1,2}zz","H&dW",[global])),
+ <<"zz">> = iolist_to_binary(re:replace("zz","^(abc){1,2}zz","NaUG",[])),
+ <<"zz">> = iolist_to_binary(re:replace("zz","^(abc){1,2}zz","NaUG",[global])),
+ <<"abcabcabczz">> = iolist_to_binary(re:replace("abcabcabczz","^(abc){1,2}zz","jed",[])),
+ <<"abcabcabczz">> = iolist_to_binary(re:replace("abcabcabczz","^(abc){1,2}zz","jed",[global])),
+ <<">>abczz">> = iolist_to_binary(re:replace(">>abczz","^(abc){1,2}zz","IfDMCUaBC\\1UiUD",[])),
+ <<">>abczz">> = iolist_to_binary(re:replace(">>abczz","^(abc){1,2}zz","IfDMCUaBC\\1UiUD",[global])),
+ <<"bcaiQbcWXgAtsqFbbcb">> = iolist_to_binary(re:replace("bc","^(b+?|a){1,2}?c","&aiQ&WXgAtsqF\\1&b",[])),
+ <<"bcaiQbcWXgAtsqFbbcb">> = iolist_to_binary(re:replace("bc","^(b+?|a){1,2}?c","&aiQ&WXgAtsqF\\1&b",[global])),
+ <<"SOnbIUtbbcSM">> = iolist_to_binary(re:replace("bbc","^(b+?|a){1,2}?c","SOn\\1IUt&SM",[])),
+ <<"SOnbIUtbbcSM">> = iolist_to_binary(re:replace("bbc","^(b+?|a){1,2}?c","SOn\\1IUt&SM",[global])),
+ <<"Obrubbk">> = iolist_to_binary(re:replace("bbbc","^(b+?|a){1,2}?c","Obru\\1k",[])),
+ <<"Obrubbk">> = iolist_to_binary(re:replace("bbbc","^(b+?|a){1,2}?c","Obru\\1k",[global])),
+ <<"YJSoHCQdPaswf">> = iolist_to_binary(re:replace("bac","^(b+?|a){1,2}?c","YJSoHCQdP\\1swf",[])),
+ <<"YJSoHCQdPaswf">> = iolist_to_binary(re:replace("bac","^(b+?|a){1,2}?c","YJSoHCQdP\\1swf",[global])),
+ <<"bbacc">> = iolist_to_binary(re:replace("bbac","^(b+?|a){1,2}?c","&c",[])),
+ <<"bbacc">> = iolist_to_binary(re:replace("bbac","^(b+?|a){1,2}?c","&c",[global])),
+ <<"jcBr">> = iolist_to_binary(re:replace("aac","^(b+?|a){1,2}?c","jcBr",[])),
+ <<"jcBr">> = iolist_to_binary(re:replace("aac","^(b+?|a){1,2}?c","jcBr",[global])),
+ <<"ubbbbbbbbbbboLR">> = iolist_to_binary(re:replace("abbbbbbbbbbbc","^(b+?|a){1,2}?c","u\\1oLR",[])),
+ <<"ubbbbbbbbbbboLR">> = iolist_to_binary(re:replace("abbbbbbbbbbbc","^(b+?|a){1,2}?c","u\\1oLR",[global])),
+ <<"qVSagCR">> = iolist_to_binary(re:replace("bbbbbbbbbbbac","^(b+?|a){1,2}?c","qVS\\1gCR",[])),
+ <<"qVSagCR">> = iolist_to_binary(re:replace("bbbbbbbbbbbac","^(b+?|a){1,2}?c","qVS\\1gCR",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b+?|a){1,2}?c","e&&lu\\1vX&EjbrQGRD&lv",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b+?|a){1,2}?c","e&&lu\\1vX&EjbrQGRD&lv",[global])),
+ <<"aaac">> = iolist_to_binary(re:replace("aaac","^(b+?|a){1,2}?c","&ofSdXa",[])),
+ <<"aaac">> = iolist_to_binary(re:replace("aaac","^(b+?|a){1,2}?c","&ofSdXa",[global])),
+ <<"abbbbbbbbbbbac">> = iolist_to_binary(re:replace("abbbbbbbbbbbac","^(b+?|a){1,2}?c","yeCWNqemq",[])),
+ <<"abbbbbbbbbbbac">> = iolist_to_binary(re:replace("abbbbbbbbbbbac","^(b+?|a){1,2}?c","yeCWNqemq",[global])),
+ <<"HvbccsbJrdMbc">> = iolist_to_binary(re:replace("bc","^(b+|a){1,2}c","Hv&cs\\1JrdM&",[])),
+ <<"HvbccsbJrdMbc">> = iolist_to_binary(re:replace("bc","^(b+|a){1,2}c","Hv&cs\\1JrdM&",[global])),
+ <<"qRubbcFTMebbWdERwX">> = iolist_to_binary(re:replace("bbc","^(b+|a){1,2}c","qRu&FTMe\\1WdERwX",[])),
+ <<"qRubbcFTMebbWdERwX">> = iolist_to_binary(re:replace("bbc","^(b+|a){1,2}c","qRu&FTMe\\1WdERwX",[global])),
+ <<"bbbcdbbbbcbbbWigSlFD">> = iolist_to_binary(re:replace("bbbc","^(b+|a){1,2}c","&db&\\1WigSlFD",[])),
+ <<"bbbcdbbbbcbbbWigSlFD">> = iolist_to_binary(re:replace("bbbc","^(b+|a){1,2}c","&db&\\1WigSlFD",[global])),
+ <<"jaGWX">> = iolist_to_binary(re:replace("bac","^(b+|a){1,2}c","j\\1GWX",[])),
+ <<"jaGWX">> = iolist_to_binary(re:replace("bac","^(b+|a){1,2}c","j\\1GWX",[global])),
+ <<"tRXTQuVicYa">> = iolist_to_binary(re:replace("bbac","^(b+|a){1,2}c","tRXTQuVicY\\1",[])),
+ <<"tRXTQuVicYa">> = iolist_to_binary(re:replace("bbac","^(b+|a){1,2}c","tRXTQuVicY\\1",[global])),
+ <<"aaacWSaacSaacauTERLsT">> = iolist_to_binary(re:replace("aac","^(b+|a){1,2}c","\\1&WS&S&\\1uTERLsT",[])),
+ <<"aaacWSaacSaacauTERLsT">> = iolist_to_binary(re:replace("aac","^(b+|a){1,2}c","\\1&WS&S&\\1uTERLsT",[global])),
+ <<"DBabbbbbbbbbbbcabbbbbbbbbbbcKcnVC">> = iolist_to_binary(re:replace("abbbbbbbbbbbc","^(b+|a){1,2}c","DB&&KcnVC",[])),
+ <<"DBabbbbbbbbbbbcabbbbbbbbbbbcKcnVC">> = iolist_to_binary(re:replace("abbbbbbbbbbbc","^(b+|a){1,2}c","DB&&KcnVC",[global])),
+ <<"EeIDBbbbbbbbbbbbaciagibbbbbbbbbbbacaa">> = iolist_to_binary(re:replace("bbbbbbbbbbbac","^(b+|a){1,2}c","EeIDB&i\\1gi&\\1\\1",[])),
+ <<"EeIDBbbbbbbbbbbbaciagibbbbbbbbbbbacaa">> = iolist_to_binary(re:replace("bbbbbbbbbbbac","^(b+|a){1,2}c","EeIDB&i\\1gi&\\1\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b+|a){1,2}c","a&o&Hxqiw&jogpDTgJ",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b+|a){1,2}c","a&o&Hxqiw&jogpDTgJ",[global])),
+ <<"aaac">> = iolist_to_binary(re:replace("aaac","^(b+|a){1,2}c","&G&\\1h\\1wNk&Ywpciljc",[])),
+ <<"aaac">> = iolist_to_binary(re:replace("aaac","^(b+|a){1,2}c","&G&\\1h\\1wNk&Ywpciljc",[global])),
+ <<"abbbbbbbbbbbac">> = iolist_to_binary(re:replace("abbbbbbbbbbbac","^(b+|a){1,2}c","HEjJIPg\\1n\\1&kTh",[])),
+ <<"abbbbbbbbbbbac">> = iolist_to_binary(re:replace("abbbbbbbbbbbac","^(b+|a){1,2}c","HEjJIPg\\1n\\1&kTh",[global])),
+ <<"bbcP">> = iolist_to_binary(re:replace("bbc","^(b+|a){1,2}?bc","&P",[])),
+ <<"bbcP">> = iolist_to_binary(re:replace("bbc","^(b+|a){1,2}?bc","&P",[global])),
+ <<"kGDMabaIlbabcKSq">> = iolist_to_binary(re:replace("babc","^(b*|ba){1,2}?bc","kGDMa\\1Il&KSq",[])),
+ <<"kGDMabaIlbabcKSq">> = iolist_to_binary(re:replace("babc","^(b*|ba){1,2}?bc","kGDMa\\1Il&KSq",[global])),
+ <<"babayLobbabcOLYmIGfTNbbabci">> = iolist_to_binary(re:replace("bbabc","^(b*|ba){1,2}?bc","\\1\\1yLo&OLYmIGfTN&i",[])),
+ <<"babayLobbabcOLYmIGfTNbbabci">> = iolist_to_binary(re:replace("bbabc","^(b*|ba){1,2}?bc","\\1\\1yLo&OLYmIGfTN&i",[global])),
+ <<"pMjVc">> = iolist_to_binary(re:replace("bababc","^(b*|ba){1,2}?bc","pMjVc",[])),
+ <<"pMjVc">> = iolist_to_binary(re:replace("bababc","^(b*|ba){1,2}?bc","pMjVc",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b*|ba){1,2}?bc","wT",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(b*|ba){1,2}?bc","wT",[global])),
+ <<"bababbc">> = iolist_to_binary(re:replace("bababbc","^(b*|ba){1,2}?bc","g&dFfWePhsR&XN\\1Vq",[])),
+ <<"bababbc">> = iolist_to_binary(re:replace("bababbc","^(b*|ba){1,2}?bc","g&dFfWePhsR&XN\\1Vq",[global])),
+ <<"babababc">> = iolist_to_binary(re:replace("babababc","^(b*|ba){1,2}?bc","\\1",[])),
+ <<"babababc">> = iolist_to_binary(re:replace("babababc","^(b*|ba){1,2}?bc","\\1",[global])),
+ <<"HQbatSN">> = iolist_to_binary(re:replace("babc","^(ba|b*){1,2}?bc","HQ\\1tSN",[])),
+ <<"HQbatSN">> = iolist_to_binary(re:replace("babc","^(ba|b*){1,2}?bc","HQ\\1tSN",[global])),
+ <<"Wba">> = iolist_to_binary(re:replace("bbabc","^(ba|b*){1,2}?bc","W\\1",[])),
+ <<"Wba">> = iolist_to_binary(re:replace("bbabc","^(ba|b*){1,2}?bc","W\\1",[global])),
+ <<"NsH">> = iolist_to_binary(re:replace("bababc","^(ba|b*){1,2}?bc","NsH",[])),
+ <<"NsH">> = iolist_to_binary(re:replace("bababc","^(ba|b*){1,2}?bc","NsH",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(ba|b*){1,2}?bc","n\\1QUxH&c\\1vARRpu\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(ba|b*){1,2}?bc","n\\1QUxH&c\\1vARRpu\\1",[global])),
+ <<"bababbc">> = iolist_to_binary(re:replace("bababbc","^(ba|b*){1,2}?bc","X&pfoImgghpuaCj\\1h\\1T&",[])),
+ <<"bababbc">> = iolist_to_binary(re:replace("bababbc","^(ba|b*){1,2}?bc","X&pfoImgghpuaCj\\1h\\1T&",[global])),
+ <<"babababc">> = iolist_to_binary(re:replace("babababc","^(ba|b*){1,2}?bc","O\\1dyBuNmjs&QHb&",[])),
+ <<"babababc">> = iolist_to_binary(re:replace("babababc","^(ba|b*){1,2}?bc","O\\1dyBuNmjs&QHb&",[global])),
+ <<"MjwccSIya;z;zXkruR">> = iolist_to_binary(re:replace(";z","^\\ca\\cA\\c[;\\c:","MjwccSIy\\1a&&XkruR",[])),
+ <<"MjwccSIya;z;zXkruR">> = iolist_to_binary(re:replace(";z","^\\ca\\cA\\c[;\\c:","MjwccSIy\\1a&&XkruR",[global])),
+ <<"KmseihnaDthing">> = iolist_to_binary(re:replace("athing","^[ab\\]cde]","Kms\\1eihn&D",[])),
+ <<"KmseihnaDthing">> = iolist_to_binary(re:replace("athing","^[ab\\]cde]","Kms\\1eihn&D",[global])),
+ <<"VtYything">> = iolist_to_binary(re:replace("bthing","^[ab\\]cde]","V\\1\\1tYy\\1",[])),
+ <<"VtYything">> = iolist_to_binary(re:replace("bthing","^[ab\\]cde]","V\\1\\1tYy\\1",[global])),
+ <<"BUicE]cTfPthing">> = iolist_to_binary(re:replace("]thing","^[ab\\]cde]","B\\1UicE\\1&cTfP",[])),
+ <<"BUicE]cTfPthing">> = iolist_to_binary(re:replace("]thing","^[ab\\]cde]","B\\1UicE\\1&cTfP",[global])),
+ <<"Jthing">> = iolist_to_binary(re:replace("cthing","^[ab\\]cde]","J",[])),
+ <<"Jthing">> = iolist_to_binary(re:replace("cthing","^[ab\\]cde]","J",[global])),
+ <<"ecfIHwcPLwCQVmthing">> = iolist_to_binary(re:replace("dthing","^[ab\\]cde]","ecfIHwcPLwCQVm",[])),
+ <<"ecfIHwcPLwCQVmthing">> = iolist_to_binary(re:replace("dthing","^[ab\\]cde]","ecfIHwcPLwCQVm",[global])),
+ <<"jthing">> = iolist_to_binary(re:replace("ething","^[ab\\]cde]","j\\1",[])),
+ <<"jthing">> = iolist_to_binary(re:replace("ething","^[ab\\]cde]","j\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[ab\\]cde]","XitEhS",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[ab\\]cde]","XitEhS",[global])),
+ <<"fthing">> = iolist_to_binary(re:replace("fthing","^[ab\\]cde]","jftUvqtHSk&",[])),
+ <<"fthing">> = iolist_to_binary(re:replace("fthing","^[ab\\]cde]","jftUvqtHSk&",[global])),
+ <<"[thing">> = iolist_to_binary(re:replace("[thing","^[ab\\]cde]","BVEV&n",[])),
+ <<"[thing">> = iolist_to_binary(re:replace("[thing","^[ab\\]cde]","BVEV&n",[global])),
+ <<"\\thing">> = iolist_to_binary(re:replace("\\thing","^[ab\\]cde]","&",[])),
+ <<"\\thing">> = iolist_to_binary(re:replace("\\thing","^[ab\\]cde]","&",[global])),
+ <<"CLkR]]rBddXHyi]Hrjthing">> = iolist_to_binary(re:replace("]thing","^[]cde]","CLkR&&rBddXHyi&H\\1\\1rj",[])),
+ <<"CLkR]]rBddXHyi]Hrjthing">> = iolist_to_binary(re:replace("]thing","^[]cde]","CLkR&&rBddXHyi&H\\1\\1rj",[global])),
+ <<"sHqJwDKDjCAxIofXvVthing">> = iolist_to_binary(re:replace("cthing","^[]cde]","s\\1HqJwD\\1KDjCAxIofXvV",[])),
+ <<"sHqJwDKDjCAxIofXvVthing">> = iolist_to_binary(re:replace("cthing","^[]cde]","s\\1HqJwD\\1KDjCAxIofXvV",[global])),
+ <<"hcfONJPTXdthing">> = iolist_to_binary(re:replace("dthing","^[]cde]","hcfONJPTX&",[])),
+ <<"hcfONJPTXdthing">> = iolist_to_binary(re:replace("dthing","^[]cde]","hcfONJPTX&",[global])),
+ <<"eEbyOxFupOoOReKucqkthing">> = iolist_to_binary(re:replace("ething","^[]cde]","&EbyOxFupOoO\\1R&Kucqk",[])),
+ <<"eEbyOxFupOoOReKucqkthing">> = iolist_to_binary(re:replace("ething","^[]cde]","&EbyOxFupOoO\\1R&Kucqk",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[]cde]","ViA&j\\1r&&eE",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[]cde]","ViA&j\\1r&&eE",[global])),
+ <<"athing">> = iolist_to_binary(re:replace("athing","^[]cde]","l\\1m",[])),
+ <<"athing">> = iolist_to_binary(re:replace("athing","^[]cde]","l\\1m",[global])),
+ <<"fthing">> = iolist_to_binary(re:replace("fthing","^[]cde]","&X",[])),
+ <<"fthing">> = iolist_to_binary(re:replace("fthing","^[]cde]","&X",[global])),
+ <<"iexifgnSthing">> = iolist_to_binary(re:replace("fthing","^[^ab\\]cde]","iexi&gnS",[])),
+ <<"iexifgnSthing">> = iolist_to_binary(re:replace("fthing","^[^ab\\]cde]","iexi&gnS",[global])),
+ <<"KbDPthing">> = iolist_to_binary(re:replace("[thing","^[^ab\\]cde]","Kb\\1DP",[])),
+ <<"KbDPthing">> = iolist_to_binary(re:replace("[thing","^[^ab\\]cde]","Kb\\1DP",[global])),
+ <<"qsMjdRastMthing">> = iolist_to_binary(re:replace("\\thing","^[^ab\\]cde]","qsMjd\\1RastM",[])),
+ <<"qsMjdRastMthing">> = iolist_to_binary(re:replace("\\thing","^[^ab\\]cde]","qsMjd\\1RastM",[global])),
+ <<"OMrBm** Failers">> = iolist_to_binary(re:replace("*** Failers","^[^ab\\]cde]","OMrBm",[])),
+ <<"OMrBm** Failers">> = iolist_to_binary(re:replace("*** Failers","^[^ab\\]cde]","OMrBm",[global])),
+ <<"athing">> = iolist_to_binary(re:replace("athing","^[^ab\\]cde]","blc",[])),
+ <<"athing">> = iolist_to_binary(re:replace("athing","^[^ab\\]cde]","blc",[global])),
+ <<"bthing">> = iolist_to_binary(re:replace("bthing","^[^ab\\]cde]","rkdVhImX&Sci\\1srkpB",[])),
+ <<"bthing">> = iolist_to_binary(re:replace("bthing","^[^ab\\]cde]","rkdVhImX&Sci\\1srkpB",[global])),
+ <<"]thing">> = iolist_to_binary(re:replace("]thing","^[^ab\\]cde]","R",[])),
+ <<"]thing">> = iolist_to_binary(re:replace("]thing","^[^ab\\]cde]","R",[global])),
+ <<"cthing">> = iolist_to_binary(re:replace("cthing","^[^ab\\]cde]","MTBI&N\\1Hu&G&vMV&",[])),
+ <<"cthing">> = iolist_to_binary(re:replace("cthing","^[^ab\\]cde]","MTBI&N\\1Hu&G&vMV&",[global])),
+ <<"dthing">> = iolist_to_binary(re:replace("dthing","^[^ab\\]cde]","L&iy\\1&&rL",[])),
+ <<"dthing">> = iolist_to_binary(re:replace("dthing","^[^ab\\]cde]","L&iy\\1&&rL",[global])),
+ <<"ething">> = iolist_to_binary(re:replace("ething","^[^ab\\]cde]","fAG\\1TYq\\1LAa\\1amIUKu",[])),
+ <<"ething">> = iolist_to_binary(re:replace("ething","^[^ab\\]cde]","fAG\\1TYq\\1LAa\\1amIUKu",[global])),
+ <<"gathing">> = iolist_to_binary(re:replace("athing","^[^]cde]","\\1\\1g&\\1",[])),
+ <<"gathing">> = iolist_to_binary(re:replace("athing","^[^]cde]","\\1\\1g&\\1",[global])),
+ <<"XGfAfLNiMaKLathing">> = iolist_to_binary(re:replace("fthing","^[^]cde]","XG&A&LNiMa\\1KLa",[])),
+ <<"XGfAfLNiMaKLathing">> = iolist_to_binary(re:replace("fthing","^[^]cde]","XG&A&LNiMa\\1KLa",[global])),
+ <<"pCXwvleUk*NHE*wG*wiU** Failers">> = iolist_to_binary(re:replace("*** Failers","^[^]cde]","pCXwvleUk&NHE&wG&wiU",[])),
+ <<"pCXwvleUk*NHE*wG*wiU** Failers">> = iolist_to_binary(re:replace("*** Failers","^[^]cde]","pCXwvleUk&NHE&wG&wiU",[global])),
+ <<"]thing">> = iolist_to_binary(re:replace("]thing","^[^]cde]","D\\1mYIuXYOFQyO&Yx&",[])),
+ <<"]thing">> = iolist_to_binary(re:replace("]thing","^[^]cde]","D\\1mYIuXYOFQyO&Yx&",[global])),
+ <<"cthing">> = iolist_to_binary(re:replace("cthing","^[^]cde]","iJI\\1fdd&",[])),
+ <<"cthing">> = iolist_to_binary(re:replace("cthing","^[^]cde]","iJI\\1fdd&",[global])),
+ <<"dthing">> = iolist_to_binary(re:replace("dthing","^[^]cde]","BqndYPF\\1lxs\\1\\1hPxSdgK",[])),
+ <<"dthing">> = iolist_to_binary(re:replace("dthing","^[^]cde]","BqndYPF\\1lxs\\1\\1hPxSdgK",[global])),
+ <<"ething">> = iolist_to_binary(re:replace("ething","^[^]cde]","E",[])),
+ <<"ething">> = iolist_to_binary(re:replace("ething","^[^]cde]","E",[global])),
+ <<"0AMd">> = iolist_to_binary(re:replace("0","^[0-9]+$","&AM\\1\\1d",[])),
+ <<"0AMd">> = iolist_to_binary(re:replace("0","^[0-9]+$","&AM\\1\\1d",[global])),
+ <<"LUfQMm1n">> = iolist_to_binary(re:replace("1","^[0-9]+$","L\\1\\1Uf\\1Q\\1Mm&n",[])),
+ <<"LUfQMm1n">> = iolist_to_binary(re:replace("1","^[0-9]+$","L\\1\\1Uf\\1Q\\1Mm&n",[global])),
+ <<"yty2aJl22M">> = iolist_to_binary(re:replace("2","^[0-9]+$","yty\\1&aJl&\\1&M",[])),
+ <<"yty2aJl22M">> = iolist_to_binary(re:replace("2","^[0-9]+$","yty\\1&aJl&\\1&M",[global])),
+ <<"eX3">> = iolist_to_binary(re:replace("3","^[0-9]+$","eX&",[])),
+ <<"eX3">> = iolist_to_binary(re:replace("3","^[0-9]+$","eX&",[global])),
+ <<"ypukToFRSissUH">> = iolist_to_binary(re:replace("4","^[0-9]+$","ypukToFRSissUH",[])),
+ <<"ypukToFRSissUH">> = iolist_to_binary(re:replace("4","^[0-9]+$","ypukToFRSissUH",[global])),
+ <<"e55dU5aoURF5N">> = iolist_to_binary(re:replace("5","^[0-9]+$","e&&dU&a\\1oURF&N",[])),
+ <<"e55dU5aoURF5N">> = iolist_to_binary(re:replace("5","^[0-9]+$","e&&dU&a\\1oURF&N",[global])),
+ <<"nrnSg6E">> = iolist_to_binary(re:replace("6","^[0-9]+$","nrnSg&\\1\\1E",[])),
+ <<"nrnSg6E">> = iolist_to_binary(re:replace("6","^[0-9]+$","nrnSg&\\1\\1E",[global])),
+ <<"uBv">> = iolist_to_binary(re:replace("7","^[0-9]+$","uBv",[])),
+ <<"uBv">> = iolist_to_binary(re:replace("7","^[0-9]+$","uBv",[global])),
+ <<"R">> = iolist_to_binary(re:replace("8","^[0-9]+$","R",[])),
+ <<"R">> = iolist_to_binary(re:replace("8","^[0-9]+$","R",[global])),
+ <<"t9gys9DIukLiJU9Qb9">> = iolist_to_binary(re:replace("9","^[0-9]+$","t&gys\\1&DIukLiJU&Qb&",[])),
+ <<"t9gys9DIukLiJU9Qb9">> = iolist_to_binary(re:replace("9","^[0-9]+$","t&gys\\1&DIukLiJU&Qb&",[global])),
+ <<"tIOqKYBcuX10">> = iolist_to_binary(re:replace("10","^[0-9]+$","tIOqKYBcuX&",[])),
+ <<"tIOqKYBcuX10">> = iolist_to_binary(re:replace("10","^[0-9]+$","tIOqKYBcuX&",[global])),
+ <<"QfE">> = iolist_to_binary(re:replace("100","^[0-9]+$","QfE",[])),
+ <<"QfE">> = iolist_to_binary(re:replace("100","^[0-9]+$","QfE",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[0-9]+$","UDbN\\1jnxythM\\1\\1sdH&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[0-9]+$","UDbN\\1jnxythM\\1\\1sdH&",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","^[0-9]+$","cUQQDAc",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","^[0-9]+$","cUQQDAc",[global])),
+ <<"CVuenterheUenterWenter">> = iolist_to_binary(re:replace("enter","^.*nter","C\\1Vu&heU&\\1W&",[])),
+ <<"CVuenterheUenterWenter">> = iolist_to_binary(re:replace("enter","^.*nter","C\\1Vu&heU&\\1W&",[global])),
+ <<"IEc">> = iolist_to_binary(re:replace("inter","^.*nter","IEc",[])),
+ <<"IEc">> = iolist_to_binary(re:replace("inter","^.*nter","IEc",[global])),
+ <<"EJPILFHXKDCNvaTC">> = iolist_to_binary(re:replace("uponter","^.*nter","EJPIL\\1FHXKDCNvaTC",[])),
+ <<"EJPILFHXKDCNvaTC">> = iolist_to_binary(re:replace("uponter","^.*nter","EJPIL\\1FHXKDCNvaTC",[global])),
ok.
run1() ->
- <<"Bp">> = iolist_to_binary(re:replace("xxx0","^xxx[0-9]+$","B\\1\\1\\1p",[])),
- <<"Bp">> = iolist_to_binary(re:replace("xxx0","^xxx[0-9]+$","B\\1\\1\\1p",[global])),
- <<"xxx1234okNYhxxx1234tobCxxx1234fg">> = iolist_to_binary(re:replace("xxx1234","^xxx[0-9]+$","&okNYh&tobC\\1&fg",[])),
- <<"xxx1234okNYhxxx1234tobCxxx1234fg">> = iolist_to_binary(re:replace("xxx1234","^xxx[0-9]+$","&okNYh&tobC\\1&fg",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^xxx[0-9]+$","hQ&ULnO\\1\\1\\1nNlLbQ",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^xxx[0-9]+$","hQ&ULnO\\1\\1\\1nNlLbQ",[global])),
- <<"xxx">> = iolist_to_binary(re:replace("xxx","^xxx[0-9]+$","&KwHk\\1a\\1\\1\\1&&i",[])),
- <<"xxx">> = iolist_to_binary(re:replace("xxx","^xxx[0-9]+$","&KwHk\\1a\\1\\1\\1&&i",[global])),
- <<"ohMDx123xpx123mNT">> = iolist_to_binary(re:replace("x123","^.+[0-9][0-9][0-9]$","ohMD&xp\\1&mNT",[])),
- <<"ohMDx123xpx123mNT">> = iolist_to_binary(re:replace("x123","^.+[0-9][0-9][0-9]$","ohMD&xp\\1&mNT",[global])),
- <<"gYaxx123xx123XaaNxx123bNU">> = iolist_to_binary(re:replace("xx123","^.+[0-9][0-9][0-9]$","gYa&&XaaN&bNU",[])),
- <<"gYaxx123xx123XaaNxx123bNU">> = iolist_to_binary(re:replace("xx123","^.+[0-9][0-9][0-9]$","gYa&&XaaN&bNU",[global])),
- <<"iElVtor">> = iolist_to_binary(re:replace("123456","^.+[0-9][0-9][0-9]$","i\\1ElV\\1tor",[])),
- <<"iElVtor">> = iolist_to_binary(re:replace("123456","^.+[0-9][0-9][0-9]$","i\\1ElV\\1tor",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.+[0-9][0-9][0-9]$","BWxJ\\1uhGy&vgMLA",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.+[0-9][0-9][0-9]$","BWxJ\\1uhGy&vgMLA",[global])),
- <<"123">> = iolist_to_binary(re:replace("123","^.+[0-9][0-9][0-9]$","xTGS&sW\\1G&NlcW",[])),
- <<"123">> = iolist_to_binary(re:replace("123","^.+[0-9][0-9][0-9]$","xTGS&sW\\1G&NlcW",[global])),
- <<"Ix1234IUy">> = iolist_to_binary(re:replace("x1234","^.+[0-9][0-9][0-9]$","I\\1&\\1I\\1Uy",[])),
- <<"Ix1234IUy">> = iolist_to_binary(re:replace("x1234","^.+[0-9][0-9][0-9]$","I\\1&\\1I\\1Uy",[global])),
- <<"DBYEAgkI">> = iolist_to_binary(re:replace("x123","^.+?[0-9][0-9][0-9]$","DBYE\\1AgkI",[])),
- <<"DBYEAgkI">> = iolist_to_binary(re:replace("x123","^.+?[0-9][0-9][0-9]$","DBYE\\1AgkI",[global])),
- <<"EABxx123">> = iolist_to_binary(re:replace("xx123","^.+?[0-9][0-9][0-9]$","EAB&\\1",[])),
- <<"EABxx123">> = iolist_to_binary(re:replace("xx123","^.+?[0-9][0-9][0-9]$","EAB&\\1",[global])),
- <<"w">> = iolist_to_binary(re:replace("123456","^.+?[0-9][0-9][0-9]$","w",[])),
- <<"w">> = iolist_to_binary(re:replace("123456","^.+?[0-9][0-9][0-9]$","w",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.+?[0-9][0-9][0-9]$","jiMwkAneSrQ&",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.+?[0-9][0-9][0-9]$","jiMwkAneSrQ&",[global])),
- <<"123">> = iolist_to_binary(re:replace("123","^.+?[0-9][0-9][0-9]$","pg\\1cjQ&&&",[])),
- <<"123">> = iolist_to_binary(re:replace("123","^.+?[0-9][0-9][0-9]$","pg\\1cjQ&&&",[global])),
- <<"APdx1234Jdelcg">> = iolist_to_binary(re:replace("x1234","^.+?[0-9][0-9][0-9]$","A\\1Pd&Jdelcg",[])),
- <<"APdx1234Jdelcg">> = iolist_to_binary(re:replace("x1234","^.+?[0-9][0-9][0-9]$","A\\1Pd&Jdelcg",[global])),
- <<"abcVE">> = iolist_to_binary(re:replace("abc!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","\\1VE",[])),
- <<"abcVE">> = iolist_to_binary(re:replace("abc!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","\\1VE",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","ysSa&O\\1ogTi\\1e\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","ysSa&O\\1ogTi\\1e\\1",[global])),
- <<"!pqr=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","eCQWoiG\\1",[])),
- <<"!pqr=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","eCQWoiG\\1",[global])),
- <<"abc!=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("abc!=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","rYbgJDpc",[])),
- <<"abc!=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("abc!=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","rYbgJDpc",[global])),
- <<"abc!pqr=apquxz:ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("abc!pqr=apquxz:ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","vkuwBMsxa",[])),
- <<"abc!pqr=apquxz:ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("abc!pqr=apquxz:ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","vkuwBMsxa",[global])),
- <<"abc!pqr=apquxz.ixr.zzz.ac.ukk">> = iolist_to_binary(re:replace("abc!pqr=apquxz.ixr.zzz.ac.ukk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","e\\1KF&BD\\1C&kxH&rwWnu",[])),
- <<"abc!pqr=apquxz.ixr.zzz.ac.ukk">> = iolist_to_binary(re:replace("abc!pqr=apquxz.ixr.zzz.ac.ukk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","e\\1KF&BD\\1C&kxH&rwWnu",[global])),
- <<"Well, we need a colongxIksrpvcmlefi:WmR somewhere">> = iolist_to_binary(re:replace("Well, we need a colon: somewhere",":","g\\1xIksrpvcmlefi&WmR",[])),
- <<"Well, we need a colongxIksrpvcmlefi:WmR somewhere">> = iolist_to_binary(re:replace("Well, we need a colon: somewhere",":","g\\1xIksrpvcmlefi&WmR",[global])),
- <<"*** Fail if we don't">> = iolist_to_binary(re:replace("*** Fail if we don't",":","g&BggNgoAXIe&s\\1NH",[])),
- <<"*** Fail if we don't">> = iolist_to_binary(re:replace("*** Fail if we don't",":","g&BggNgoAXIe&s\\1NH",[global])),
- <<"TkV0abcQpF0abci0abcyiC">> = iolist_to_binary(re:replace("0abc","([\\da-f:]+)$","TkV\\1QpF\\1i&yiC",[caseless])),
- <<"TkV0abcQpF0abci0abcyiC">> = iolist_to_binary(re:replace("0abc","([\\da-f:]+)$","TkV\\1QpF\\1i&yiC",[caseless,
- global])),
- <<"gAHIDgPO">> = iolist_to_binary(re:replace("abc","([\\da-f:]+)$","gAHIDgPO",[caseless])),
- <<"gAHIDgPO">> = iolist_to_binary(re:replace("abc","([\\da-f:]+)$","gAHIDgPO",[caseless,
- global])),
- <<"QqLxYfedlXtfedNm">> = iolist_to_binary(re:replace("fed","([\\da-f:]+)$","QqLxY&lXt\\1Nm",[caseless])),
- <<"QqLxYfedlXtfedNm">> = iolist_to_binary(re:replace("fed","([\\da-f:]+)$","QqLxY&lXt\\1Nm",[caseless,
- global])),
- <<"aXaxRLpEPRwSlQEEw">> = iolist_to_binary(re:replace("E","([\\da-f:]+)$","aXaxRLp\\1PRwSlQ\\1\\1w",[caseless])),
- <<"aXaxRLpEPRwSlQEEw">> = iolist_to_binary(re:replace("E","([\\da-f:]+)$","aXaxRLp\\1PRwSlQ\\1\\1w",[caseless,
- global])),
- <<"srXTndsE::::kfsP::LR">> = iolist_to_binary(re:replace("::","([\\da-f:]+)$","srXTndsE&&kfsP&LR",[caseless])),
- <<"srXTndsE::::kfsP::LR">> = iolist_to_binary(re:replace("::","([\\da-f:]+)$","srXTndsE&&kfsP&LR",[caseless,
- global])),
- <<"5f03:12C0::932ejAFV">> = iolist_to_binary(re:replace("5f03:12C0::932e","([\\da-f:]+)$","&jAFV",[caseless])),
- <<"5f03:12C0::932ejAFV">> = iolist_to_binary(re:replace("5f03:12C0::932e","([\\da-f:]+)$","&jAFV",[caseless,
+ <<"P">> = iolist_to_binary(re:replace("xxx0","^xxx[0-9]+$","P",[])),
+ <<"P">> = iolist_to_binary(re:replace("xxx0","^xxx[0-9]+$","P",[global])),
+ <<"eSFOJJrLwTwUxxx1234xxx1234Mqmxxx1234P">> = iolist_to_binary(re:replace("xxx1234","^xxx[0-9]+$","eSFOJJrLwTwU&&Mqm&P",[])),
+ <<"eSFOJJrLwTwUxxx1234xxx1234Mqmxxx1234P">> = iolist_to_binary(re:replace("xxx1234","^xxx[0-9]+$","eSFOJJrLwTwU&&Mqm&P",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^xxx[0-9]+$","rqtBg",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^xxx[0-9]+$","rqtBg",[global])),
+ <<"xxx">> = iolist_to_binary(re:replace("xxx","^xxx[0-9]+$","BC&WMPvffc&kTc",[])),
+ <<"xxx">> = iolist_to_binary(re:replace("xxx","^xxx[0-9]+$","BC&WMPvffc&kTc",[global])),
+ <<"x123lx123x123x123UnCsPMYYkPx123mE">> = iolist_to_binary(re:replace("x123","^.+[0-9][0-9][0-9]$","&l&&&Un\\1CsPMYYkP\\1&mE",[])),
+ <<"x123lx123x123x123UnCsPMYYkPx123mE">> = iolist_to_binary(re:replace("x123","^.+[0-9][0-9][0-9]$","&l&&&Un\\1CsPMYYkP\\1&mE",[global])),
+ <<"IdKDxx123rQnxx123gDqdon">> = iolist_to_binary(re:replace("xx123","^.+[0-9][0-9][0-9]$","IdKD&rQ\\1\\1n&gD\\1qdo\\1n",[])),
+ <<"IdKDxx123rQnxx123gDqdon">> = iolist_to_binary(re:replace("xx123","^.+[0-9][0-9][0-9]$","IdKD&rQ\\1\\1n&gD\\1qdo\\1n",[global])),
+ <<"RkaqCHlxR">> = iolist_to_binary(re:replace("123456","^.+[0-9][0-9][0-9]$","Rk\\1aqCHlxR",[])),
+ <<"RkaqCHlxR">> = iolist_to_binary(re:replace("123456","^.+[0-9][0-9][0-9]$","Rk\\1aqCHlxR",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.+[0-9][0-9][0-9]$","cgy\\1xVdgl&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.+[0-9][0-9][0-9]$","cgy\\1xVdgl&",[global])),
+ <<"123">> = iolist_to_binary(re:replace("123","^.+[0-9][0-9][0-9]$","CGIYKCWyECIvTQ",[])),
+ <<"123">> = iolist_to_binary(re:replace("123","^.+[0-9][0-9][0-9]$","CGIYKCWyECIvTQ",[global])),
+ <<"FtyEkgTx1234aW">> = iolist_to_binary(re:replace("x1234","^.+[0-9][0-9][0-9]$","FtyEkg\\1T&aW",[])),
+ <<"FtyEkgTx1234aW">> = iolist_to_binary(re:replace("x1234","^.+[0-9][0-9][0-9]$","FtyEkg\\1T&aW",[global])),
+ <<"KeT">> = iolist_to_binary(re:replace("x123","^.+?[0-9][0-9][0-9]$","KeT",[])),
+ <<"KeT">> = iolist_to_binary(re:replace("x123","^.+?[0-9][0-9][0-9]$","KeT",[global])),
+ <<"Lxx123ikqEJxx123xx123">> = iolist_to_binary(re:replace("xx123","^.+?[0-9][0-9][0-9]$","L&ikqEJ\\1&&\\1\\1",[])),
+ <<"Lxx123ikqEJxx123xx123">> = iolist_to_binary(re:replace("xx123","^.+?[0-9][0-9][0-9]$","L&ikqEJ\\1&&\\1\\1",[global])),
+ <<"X123456R">> = iolist_to_binary(re:replace("123456","^.+?[0-9][0-9][0-9]$","X&R",[])),
+ <<"X123456R">> = iolist_to_binary(re:replace("123456","^.+?[0-9][0-9][0-9]$","X&R",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.+?[0-9][0-9][0-9]$","tKJBvn",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.+?[0-9][0-9][0-9]$","tKJBvn",[global])),
+ <<"123">> = iolist_to_binary(re:replace("123","^.+?[0-9][0-9][0-9]$","hVg\\1P\\1\\1",[])),
+ <<"123">> = iolist_to_binary(re:replace("123","^.+?[0-9][0-9][0-9]$","hVg\\1P\\1\\1",[global])),
+ <<"Tx1234amxVpJx1234egSsUBIV">> = iolist_to_binary(re:replace("x1234","^.+?[0-9][0-9][0-9]$","T&a\\1mxVpJ\\1&egSsUBIV",[])),
+ <<"Tx1234amxVpJx1234egSsUBIV">> = iolist_to_binary(re:replace("x1234","^.+?[0-9][0-9][0-9]$","T&a\\1mxVpJ\\1&egSsUBIV",[global])),
+ <<"YWynbrCtabcabc">> = iolist_to_binary(re:replace("abc!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","YWynbrCt\\1\\1",[])),
+ <<"YWynbrCtabcabc">> = iolist_to_binary(re:replace("abc!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","YWynbrCt\\1\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","gXiCw\\1HR&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","gXiCw\\1HR&",[global])),
+ <<"!pqr=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","p&jt\\1a",[])),
+ <<"!pqr=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("!pqr=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","p&jt\\1a",[global])),
+ <<"abc!=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("abc!=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","\\1RDbvMJ&",[])),
+ <<"abc!=apquxz.ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("abc!=apquxz.ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","\\1RDbvMJ&",[global])),
+ <<"abc!pqr=apquxz:ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("abc!pqr=apquxz:ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","I\\1\\1c\\1&\\1AnFPifD&C",[])),
+ <<"abc!pqr=apquxz:ixr.zzz.ac.uk">> = iolist_to_binary(re:replace("abc!pqr=apquxz:ixr.zzz.ac.uk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","I\\1\\1c\\1&\\1AnFPifD&C",[global])),
+ <<"abc!pqr=apquxz.ixr.zzz.ac.ukk">> = iolist_to_binary(re:replace("abc!pqr=apquxz.ixr.zzz.ac.ukk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","byM\\1qyusNtwD",[])),
+ <<"abc!pqr=apquxz.ixr.zzz.ac.ukk">> = iolist_to_binary(re:replace("abc!pqr=apquxz.ixr.zzz.ac.ukk","^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$","byM\\1qyusNtwD",[global])),
+ <<"Well, we need a colonwOsWUYkpQEYQO somewhere">> = iolist_to_binary(re:replace("Well, we need a colon: somewhere",":","wOsWUYkpQEYQO",[])),
+ <<"Well, we need a colonwOsWUYkpQEYQO somewhere">> = iolist_to_binary(re:replace("Well, we need a colon: somewhere",":","wOsWUYkpQEYQO",[global])),
+ <<"*** Fail if we don't">> = iolist_to_binary(re:replace("*** Fail if we don't",":","ehPt&NEI\\1P\\1ceGP",[])),
+ <<"*** Fail if we don't">> = iolist_to_binary(re:replace("*** Fail if we don't",":","ehPt&NEI\\1P\\1ceGP",[global])),
+ <<"u0abcPr0abcfewT0abcqIyT0abcD">> = iolist_to_binary(re:replace("0abc","([\\da-f:]+)$","u\\1Pr&fewT&qIyT\\1D",[caseless])),
+ <<"u0abcPr0abcfewT0abcqIyT0abcD">> = iolist_to_binary(re:replace("0abc","([\\da-f:]+)$","u\\1Pr&fewT&qIyT\\1D",[caseless,
+ global])),
+ <<"rTODdabcvabcKUabc">> = iolist_to_binary(re:replace("abc","([\\da-f:]+)$","rTODd\\1v&KU&",[caseless])),
+ <<"rTODdabcvabcKUabc">> = iolist_to_binary(re:replace("abc","([\\da-f:]+)$","rTODd\\1v&KU&",[caseless,
+ global])),
+ <<"UhjfwcfedwPfedMkfedSM">> = iolist_to_binary(re:replace("fed","([\\da-f:]+)$","Uhjfwc&wP&Mk\\1SM",[caseless])),
+ <<"UhjfwcfedwPfedMkfedSM">> = iolist_to_binary(re:replace("fed","([\\da-f:]+)$","Uhjfwc&wP&Mk\\1SM",[caseless,
+ global])),
+ <<"tsEwEtEEnWpuswMEEv">> = iolist_to_binary(re:replace("E","([\\da-f:]+)$","ts\\1w&t\\1&nWpuswM\\1&v",[caseless])),
+ <<"tsEwEtEEnWpuswMEEv">> = iolist_to_binary(re:replace("E","([\\da-f:]+)$","ts\\1w&t\\1&nWpuswM\\1&v",[caseless,
+ global])),
+ <<"fXlt::X::::f::iL::tsbvQOv">> = iolist_to_binary(re:replace("::","([\\da-f:]+)$","fXlt&X&&f\\1iL&tsbvQOv",[caseless])),
+ <<"fXlt::X::::f::iL::tsbvQOv">> = iolist_to_binary(re:replace("::","([\\da-f:]+)$","fXlt&X&&f\\1iL&tsbvQOv",[caseless,
+ global])),
+ <<"AAW5f03:12C0::932exM">> = iolist_to_binary(re:replace("5f03:12C0::932e","([\\da-f:]+)$","AAW&xM",[caseless])),
+ <<"AAW5f03:12C0::932exM">> = iolist_to_binary(re:replace("5f03:12C0::932e","([\\da-f:]+)$","AAW&xM",[caseless,
+ global])),
+ <<"fed defSdefndefHJy">> = iolist_to_binary(re:replace("fed def","([\\da-f:]+)$","\\1S\\1n&HJy",[caseless])),
+ <<"fed defSdefndefHJy">> = iolist_to_binary(re:replace("fed def","([\\da-f:]+)$","\\1S\\1n&HJy",[caseless,
global])),
- <<"fed yjdefSWAl">> = iolist_to_binary(re:replace("fed def","([\\da-f:]+)$","yj&SWAl",[caseless])),
- <<"fed yjdefSWAl">> = iolist_to_binary(re:replace("fed def","([\\da-f:]+)$","yj&SWAl",[caseless,
- global])),
- <<"Any old stuqffffafSffkdOlpalffuffR">> = iolist_to_binary(re:replace("Any old stuff","([\\da-f:]+)$","q&\\1afS&kdOlpal&u\\1R",[caseless])),
- <<"Any old stuqffffafSffkdOlpalffuffR">> = iolist_to_binary(re:replace("Any old stuff","([\\da-f:]+)$","q&\\1afS&kdOlpal&u\\1R",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","([\\da-f:]+)$","IyKK\\1DBvmhe",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","([\\da-f:]+)$","IyKK\\1DBvmhe",[caseless,
- global])),
- <<"0zzz">> = iolist_to_binary(re:replace("0zzz","([\\da-f:]+)$","rdo\\1x&nKGAa",[caseless])),
- <<"0zzz">> = iolist_to_binary(re:replace("0zzz","([\\da-f:]+)$","rdo\\1x&nKGAa",[caseless,
+ <<"Any old stuPffte">> = iolist_to_binary(re:replace("Any old stuff","([\\da-f:]+)$","P&te",[caseless])),
+ <<"Any old stuPffte">> = iolist_to_binary(re:replace("Any old stuff","([\\da-f:]+)$","P&te",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","([\\da-f:]+)$","\\1RRODRx\\1gQSrTrwC",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","([\\da-f:]+)$","\\1RRODRx\\1gQSrTrwC",[caseless,
+ global])),
+ <<"0zzz">> = iolist_to_binary(re:replace("0zzz","([\\da-f:]+)$","C\\1",[caseless])),
+ <<"0zzz">> = iolist_to_binary(re:replace("0zzz","([\\da-f:]+)$","C\\1",[caseless,
+ global])),
+ <<"gzzz">> = iolist_to_binary(re:replace("gzzz","([\\da-f:]+)$","MtJG&NF\\1PgL&gg\\1",[caseless])),
+ <<"gzzz">> = iolist_to_binary(re:replace("gzzz","([\\da-f:]+)$","MtJG&NF\\1PgL&gg\\1",[caseless,
+ global])),
+ <<"fed ">> = iolist_to_binary(re:replace("fed ","([\\da-f:]+)$","yL&WjLe&\\1NC&GCG\\1xD",[caseless])),
+ <<"fed ">> = iolist_to_binary(re:replace("fed ","([\\da-f:]+)$","yL&WjLe&\\1NC&GCG\\1xD",[caseless,
+ global])),
+ <<"Any old rubbish">> = iolist_to_binary(re:replace("Any old rubbish","([\\da-f:]+)$","bJbtPIaR",[caseless])),
+ <<"Any old rubbish">> = iolist_to_binary(re:replace("Any old rubbish","([\\da-f:]+)$","bJbtPIaR",[caseless,
+ global])),
+ <<"T1">> = iolist_to_binary(re:replace(".1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","T\\1",[])),
+ <<"T1">> = iolist_to_binary(re:replace(".1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","T\\1",[global])),
+ <<"dOdvJFA.12.123.012">> = iolist_to_binary(re:replace("A.12.123.0","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","dOdvJF&\\1",[])),
+ <<"dOdvJFA.12.123.012">> = iolist_to_binary(re:replace("A.12.123.0","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","dOdvJF&\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","hLnol",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","hLnol",[global])),
+ <<".1.2.3333">> = iolist_to_binary(re:replace(".1.2.3333","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","fFUsmk\\1Ltx",[])),
+ <<".1.2.3333">> = iolist_to_binary(re:replace(".1.2.3333","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","fFUsmk\\1Ltx",[global])),
+ <<"1.2.3">> = iolist_to_binary(re:replace("1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","v",[])),
+ <<"1.2.3">> = iolist_to_binary(re:replace("1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","v",[global])),
+ <<"1234.2.3">> = iolist_to_binary(re:replace("1234.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","tcSnhlApa",[])),
+ <<"1234.2.3">> = iolist_to_binary(re:replace("1234.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","tcSnhlApa",[global])),
+ <<"rdN">> = iolist_to_binary(re:replace("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","rdN",[])),
+ <<"rdN">> = iolist_to_binary(re:replace("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","rdN",[global])),
+ <<"1 IN SOA non-sp1 non-sp2 (nPIbyKLvCyOobyW1RC1 IN SOA non-sp1 non-sp2 (">> = iolist_to_binary(re:replace("1 IN SOA non-sp1 non-sp2 (","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","&nPIbyKLvCyOobyW\\1RC&",[])),
+ <<"1 IN SOA non-sp1 non-sp2 (nPIbyKLvCyOobyW1RC1 IN SOA non-sp1 non-sp2 (">> = iolist_to_binary(re:replace("1 IN SOA non-sp1 non-sp2 (","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","&nPIbyKLvCyOobyW\\1RC&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","YYlMHXKMT&K\\1w&sJ",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","YYlMHXKMT&K\\1w&sJ",[global])),
+ <<"1IN SOA non-sp1 non-sp2(">> = iolist_to_binary(re:replace("1IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","L\\1nyk",[])),
+ <<"1IN SOA non-sp1 non-sp2(">> = iolist_to_binary(re:replace("1IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","L\\1nyk",[global])),
+ <<"rnRluS">> = iolist_to_binary(re:replace("a.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","rnRluS",[])),
+ <<"rnRluS">> = iolist_to_binary(re:replace("a.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","rnRluS",[global])),
+ <<"IfUFYgPEDZ.g">> = iolist_to_binary(re:replace("Z.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","IfUFYg\\1P\\1ED&g",[])),
+ <<"IfUFYgPEDZ.g">> = iolist_to_binary(re:replace("Z.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","IfUFYg\\1P\\1ED&g",[global])),
+ <<"hB">> = iolist_to_binary(re:replace("2.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","\\1hB",[])),
+ <<"hB">> = iolist_to_binary(re:replace("2.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","\\1hB",[global])),
+ <<"Lu">> = iolist_to_binary(re:replace("ab-c.pq-r.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","Lu",[])),
+ <<"Lu">> = iolist_to_binary(re:replace("ab-c.pq-r.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","Lu",[global])),
+ <<"XY">> = iolist_to_binary(re:replace("sxk.zzz.ac.uk.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","XY",[])),
+ <<"XY">> = iolist_to_binary(re:replace("sxk.zzz.ac.uk.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","XY",[global])),
+ <<"AxgSFCHEmS">> = iolist_to_binary(re:replace("x-.y-.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","AxgSFCHEmS",[])),
+ <<"AxgSFCHEmS">> = iolist_to_binary(re:replace("x-.y-.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","AxgSFCHEmS",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","jAGN",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","jAGN",[global])),
+ <<"-abc.peq.">> = iolist_to_binary(re:replace("-abc.peq.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","OL",[])),
+ <<"-abc.peq.">> = iolist_to_binary(re:replace("-abc.peq.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","OL",[global])),
+ <<"utUWVifAF">> = iolist_to_binary(re:replace("*.a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","\\1u\\1t\\1UWVifAF",[])),
+ <<"utUWVifAF">> = iolist_to_binary(re:replace("*.a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","\\1u\\1t\\1UWVifAF",[global])),
+ <<"IG*.b0-a*.b0-aBgtmNURrKatUh*.b0-aGc">> = iolist_to_binary(re:replace("*.b0-a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","IG&&BgtmNURrKatUh&Gc",[])),
+ <<"IG*.b0-a*.b0-aBgtmNURrKatUh*.b0-aGc">> = iolist_to_binary(re:replace("*.b0-a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","IG&&BgtmNURrKatUh&Gc",[global])),
+ <<"Du3-bV*.c3-b.c3-beGytl3-bhNPYv*.c3-b.c3-bM">> = iolist_to_binary(re:replace("*.c3-b.c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","Du\\1V&\\1eGytl\\1hNPYv&\\1M",[])),
+ <<"Du3-bV*.c3-b.c3-beGytl3-bhNPYv*.c3-b.c3-bM">> = iolist_to_binary(re:replace("*.c3-b.c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","Du\\1V&\\1eGytl\\1hNPYv&\\1M",[global])),
+ <<"gImvCJR-a*.c-a.b-cvbRP">> = iolist_to_binary(re:replace("*.c-a.b-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","gImvCJR\\1&vbRP",[])),
+ <<"gImvCJR-a*.c-a.b-cvbRP">> = iolist_to_binary(re:replace("*.c-a.b-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","gImvCJR\\1&vbRP",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","pRl\\1&\\1j&h&ENE&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","pRl\\1&\\1j&h&ENE&",[global])),
+ <<"*.0">> = iolist_to_binary(re:replace("*.0","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","k\\1\\1LrQNL&",[])),
+ <<"*.0">> = iolist_to_binary(re:replace("*.0","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","k\\1\\1LrQNL&",[global])),
+ <<"*.a-">> = iolist_to_binary(re:replace("*.a-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","&IphIN",[])),
+ <<"*.a-">> = iolist_to_binary(re:replace("*.a-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","&IphIN",[global])),
+ <<"*.a-b.c-">> = iolist_to_binary(re:replace("*.a-b.c-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","tUY",[])),
+ <<"*.a-b.c-">> = iolist_to_binary(re:replace("*.a-b.c-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","tUY",[global])),
+ <<"*.c-a.0-c">> = iolist_to_binary(re:replace("*.c-a.0-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","tspwqyti\\1maFJR\\1Vhlja",[])),
+ <<"*.c-a.0-c">> = iolist_to_binary(re:replace("*.c-a.0-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","tspwqyti\\1maFJR\\1Vhlja",[global])),
+ <<"deabdedeYddeBOpd">> = iolist_to_binary(re:replace("abde","^(?=ab(de))(abd)(e)","\\1&\\1Yd\\1BOpd",[])),
+ <<"deabdedeYddeBOpd">> = iolist_to_binary(re:replace("abde","^(?=ab(de))(abd)(e)","\\1&\\1Yd\\1BOpd",[global])),
+ <<"fP">> = iolist_to_binary(re:replace("abdf","^(?!(ab)de|x)(abd)(f)","fP",[])),
+ <<"fP">> = iolist_to_binary(re:replace("abdf","^(?!(ab)de|x)(abd)(f)","fP",[global])),
+ <<"sAabcdabLioGabcdwHabcdgMvvDIcd">> = iolist_to_binary(re:replace("abcd","^(?=(ab(cd)))(ab)","sA\\1&LioG\\1wH\\1gMvvDI",[])),
+ <<"sAabcdabLioGabcdwHabcdgMvvDIcd">> = iolist_to_binary(re:replace("abcd","^(?=(ab(cd)))(ab)","sA\\1&LioG\\1wH\\1gMvvDI",[global])),
+ <<"D">> = iolist_to_binary(re:replace("a.b.c.d","^[\\da-f](\\.[\\da-f])*$","D",[caseless])),
+ <<"D">> = iolist_to_binary(re:replace("a.b.c.d","^[\\da-f](\\.[\\da-f])*$","D",[caseless,
+ global])),
+ <<"ma.Dy.D">> = iolist_to_binary(re:replace("A.B.C.D","^[\\da-f](\\.[\\da-f])*$","ma\\1y\\1",[caseless])),
+ <<"ma.Dy.D">> = iolist_to_binary(re:replace("A.B.C.D","^[\\da-f](\\.[\\da-f])*$","ma\\1y\\1",[caseless,
+ global])),
+ <<"N.CfP.CXXa.b.c.1.2.3.CYyl">> = iolist_to_binary(re:replace("a.b.c.1.2.3.C","^[\\da-f](\\.[\\da-f])*$","N\\1fP\\1XX&Yyl",[caseless])),
+ <<"N.CfP.CXXa.b.c.1.2.3.CYyl">> = iolist_to_binary(re:replace("a.b.c.1.2.3.C","^[\\da-f](\\.[\\da-f])*$","N\\1fP\\1XX&Yyl",[caseless,
+ global])),
+ <<"hoN">> = iolist_to_binary(re:replace("\"1234\"","^\\\".*\\\"\\s*(;.*)?$","hoN",[])),
+ <<"hoN">> = iolist_to_binary(re:replace("\"1234\"","^\\\".*\\\"\\s*(;.*)?$","hoN",[global])),
+ <<"mAGoxP\"abcd\" ;LTrowOqTtkrS">> = iolist_to_binary(re:replace("\"abcd\" ;","^\\\".*\\\"\\s*(;.*)?$","mAGoxP&LTrowOqTtkrS",[])),
+ <<"mAGoxP\"abcd\" ;LTrowOqTtkrS">> = iolist_to_binary(re:replace("\"abcd\" ;","^\\\".*\\\"\\s*(;.*)?$","mAGoxP&LTrowOqTtkrS",[global])),
+ <<"; rhubarb\"\" ; rhubarbACq; rhubarbJhxa; rhubarb">> = iolist_to_binary(re:replace("\"\" ; rhubarb","^\\\".*\\\"\\s*(;.*)?$","\\1&ACq\\1Jhxa\\1",[])),
+ <<"; rhubarb\"\" ; rhubarbACq; rhubarbJhxa; rhubarb">> = iolist_to_binary(re:replace("\"\" ; rhubarb","^\\\".*\\\"\\s*(;.*)?$","\\1&ACq\\1Jhxa\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\\".*\\\"\\s*(;.*)?$","uuJoIhaVnwJ",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\\".*\\\"\\s*(;.*)?$","uuJoIhaVnwJ",[global])),
+ <<"\"1234\" : things">> = iolist_to_binary(re:replace("\"1234\" : things","^\\\".*\\\"\\s*(;.*)?$","&",[])),
+ <<"\"1234\" : things">> = iolist_to_binary(re:replace("\"1234\" : things","^\\\".*\\\"\\s*(;.*)?$","&",[global])),
+ <<"IHpbwDeDoVJ">> = iolist_to_binary(re:replace("","^$","IHpbw\\1DeDoV\\1J",[])),
+ <<"IHpbwDeDoVJ">> = iolist_to_binary(re:replace("","^$","IHpbw\\1DeDoV\\1J",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^$","uhGdgAUnWJEF",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^$","uhGdgAUnWJEF",[global])),
+ <<"ab cab cWr">> = iolist_to_binary(re:replace("ab c"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","&&Wr",[extended])),
+ <<"ab cab cWr">> = iolist_to_binary(re:replace("ab c"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","&&Wr",[extended,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","GGresSs\\1Q&yX",[extended])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","GGresSs\\1Q&yX",[extended,
+ global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","li\\1Qy\\1XfY",[extended])),
+ <<"abc">> = iolist_to_binary(re:replace("abc"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","li\\1Qy\\1XfY",[extended,
+ global])),
+ <<"ab cde">> = iolist_to_binary(re:replace("ab cde"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","c\\1H&",[extended])),
+ <<"ab cde">> = iolist_to_binary(re:replace("ab cde"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","c\\1H&",[extended,
+ global])),
+ <<"fGTimsjSab cRab clKbab cn">> = iolist_to_binary(re:replace("ab c","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","\\1fGTimsjS&R&lK\\1b&\\1n",[])),
+ <<"fGTimsjSab cRab clKbab cn">> = iolist_to_binary(re:replace("ab c","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","\\1fGTimsjS&R&lK\\1b&\\1n",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","BiO\\1OITSCrXtQNI\\1Wkc",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","BiO\\1OITSCrXtQNI\\1Wkc",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","myYnx\\1OS\\1DTaa",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","myYnx\\1OS\\1DTaa",[global])),
+ <<"ab cde">> = iolist_to_binary(re:replace("ab cde","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","nJCbPkJnDbYu&SNbC",[])),
+ <<"ab cde">> = iolist_to_binary(re:replace("ab cde","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","nJCbPkJnDbYu&SNbC",[global])),
+ <<"NkFMbyd">> = iolist_to_binary(re:replace("a bcd","^ a\\ b[c ]d $","NkFMbyd",[extended])),
+ <<"NkFMbyd">> = iolist_to_binary(re:replace("a bcd","^ a\\ b[c ]d $","NkFMbyd",[extended,
+ global])),
+ <<"VEOn">> = iolist_to_binary(re:replace("a b d","^ a\\ b[c ]d $","VEOn",[extended])),
+ <<"VEOn">> = iolist_to_binary(re:replace("a b d","^ a\\ b[c ]d $","VEOn",[extended,
global])),
- <<"gzzz">> = iolist_to_binary(re:replace("gzzz","([\\da-f:]+)$","CUmRDqbGoniV\\1",[caseless])),
- <<"gzzz">> = iolist_to_binary(re:replace("gzzz","([\\da-f:]+)$","CUmRDqbGoniV\\1",[caseless,
- global])),
- <<"fed ">> = iolist_to_binary(re:replace("fed ","([\\da-f:]+)$","bMg\\1\\1Smk",[caseless])),
- <<"fed ">> = iolist_to_binary(re:replace("fed ","([\\da-f:]+)$","bMg\\1\\1Smk",[caseless,
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^ a\\ b[c ]d $","aiLS",[extended])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^ a\\ b[c ]d $","aiLS",[extended,
+ global])),
+ <<"abcd">> = iolist_to_binary(re:replace("abcd","^ a\\ b[c ]d $","&TlY\\1\\1J&VFir",[extended])),
+ <<"abcd">> = iolist_to_binary(re:replace("abcd","^ a\\ b[c ]d $","&TlY\\1\\1J&VFir",[extended,
+ global])),
+ <<"ab d">> = iolist_to_binary(re:replace("ab d","^ a\\ b[c ]d $","EPKW",[extended])),
+ <<"ab d">> = iolist_to_binary(re:replace("ab d","^ a\\ b[c ]d $","EPKW",[extended,
global])),
- <<"Any old rubbish">> = iolist_to_binary(re:replace("Any old rubbish","([\\da-f:]+)$","&NxG\\1osbOqKBX\\1UUxiI",[caseless])),
- <<"Any old rubbish">> = iolist_to_binary(re:replace("Any old rubbish","([\\da-f:]+)$","&NxG\\1osbOqKBX\\1UUxiI",[caseless,
- global])),
- <<"xn1t">> = iolist_to_binary(re:replace(".1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","xn\\1t",[])),
- <<"xn1t">> = iolist_to_binary(re:replace(".1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","xn\\1t",[global])),
- <<"xuA.12.123.0pmID">> = iolist_to_binary(re:replace("A.12.123.0","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","xu&pmID",[])),
- <<"xuA.12.123.0pmID">> = iolist_to_binary(re:replace("A.12.123.0","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","xu&pmID",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","p&&t\\1\\1M&oKI",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","p&&t\\1\\1M&oKI",[global])),
- <<".1.2.3333">> = iolist_to_binary(re:replace(".1.2.3333","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","&p",[])),
- <<".1.2.3333">> = iolist_to_binary(re:replace(".1.2.3333","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","&p",[global])),
- <<"1.2.3">> = iolist_to_binary(re:replace("1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","\\1&LbVkk&K&F&b",[])),
- <<"1.2.3">> = iolist_to_binary(re:replace("1.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","\\1&LbVkk&K&F&b",[global])),
- <<"1234.2.3">> = iolist_to_binary(re:replace("1234.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","Paehh\\1",[])),
- <<"1234.2.3">> = iolist_to_binary(re:replace("1234.2.3","^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$","Paehh\\1",[global])),
- <<"1LAfJBRwFABikGlQ1 IN SOA non-sp1 non-sp2(jE1 IN SOA non-sp1 non-sp2(">> = iolist_to_binary(re:replace("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","\\1LAfJBRwFABikGlQ&jE&",[])),
- <<"1LAfJBRwFABikGlQ1 IN SOA non-sp1 non-sp2(jE1 IN SOA non-sp1 non-sp2(">> = iolist_to_binary(re:replace("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","\\1LAfJBRwFABikGlQ&jE&",[global])),
- <<"vcbW">> = iolist_to_binary(re:replace("1 IN SOA non-sp1 non-sp2 (","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","vcbW",[])),
- <<"vcbW">> = iolist_to_binary(re:replace("1 IN SOA non-sp1 non-sp2 (","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","vcbW",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","N",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","N",[global])),
- <<"1IN SOA non-sp1 non-sp2(">> = iolist_to_binary(re:replace("1IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","F\\1lEQb&&o&c&&",[])),
- <<"1IN SOA non-sp1 non-sp2(">> = iolist_to_binary(re:replace("1IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","F\\1lEQb&&o&c&&",[global])),
- <<"csJqaGLOa.a.Ca.Ma.ja.r">> = iolist_to_binary(re:replace("a.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","c\\1s\\1JqaGLO&&C&M&j&r",[])),
- <<"csJqaGLOa.a.Ca.Ma.ja.r">> = iolist_to_binary(re:replace("a.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","c\\1s\\1JqaGLO&&C&M&j&r",[global])),
- <<"TBVOOLuZ.Y">> = iolist_to_binary(re:replace("Z.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","TBVOO\\1Lu&Y",[])),
- <<"TBVOOLuZ.Y">> = iolist_to_binary(re:replace("Z.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","TBVOO\\1Lu&Y",[global])),
- <<"lAHLHAaNu2.yfAUu">> = iolist_to_binary(re:replace("2.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","lAH\\1LHAaNu\\1&yfAUu",[])),
- <<"lAHLHAaNu2.yfAUu">> = iolist_to_binary(re:replace("2.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","lAH\\1LHAaNu\\1&yfAUu",[global])),
- <<"EKpab-c.pq-r.">> = iolist_to_binary(re:replace("ab-c.pq-r.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","EKp&",[])),
- <<"EKpab-c.pq-r.">> = iolist_to_binary(re:replace("ab-c.pq-r.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","EKp&",[global])),
- <<"Ersxk.zzz.ac.uk.">> = iolist_to_binary(re:replace("sxk.zzz.ac.uk.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","Er&",[])),
- <<"Ersxk.zzz.ac.uk.">> = iolist_to_binary(re:replace("sxk.zzz.ac.uk.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","Er&",[global])),
- <<"Xqs">> = iolist_to_binary(re:replace("x-.y-.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","Xqs",[])),
- <<"Xqs">> = iolist_to_binary(re:replace("x-.y-.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","Xqs",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","&DsB",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","&DsB",[global])),
- <<"-abc.peq.">> = iolist_to_binary(re:replace("-abc.peq.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","Kqq&&AIru&&FA\\1gbG",[])),
- <<"-abc.peq.">> = iolist_to_binary(re:replace("-abc.peq.","^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$","Kqq&&AIru&&FA\\1gbG",[global])),
- <<"OmWMM*.acuHiylpsiKq">> = iolist_to_binary(re:replace("*.a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","\\1OmWMM&cuHiylpsiKq",[])),
- <<"OmWMM*.acuHiylpsiKq">> = iolist_to_binary(re:replace("*.a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","\\1OmWMM&cuHiylpsiKq",[global])),
- <<"j0-a0-aXQ">> = iolist_to_binary(re:replace("*.b0-a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","j\\1\\1XQ",[])),
- <<"j0-a0-aXQ">> = iolist_to_binary(re:replace("*.b0-a","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","j\\1\\1XQ",[global])),
- <<"r3-b">> = iolist_to_binary(re:replace("*.c3-b.c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","r\\1",[])),
- <<"r3-b">> = iolist_to_binary(re:replace("*.c3-b.c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","r\\1",[global])),
- <<"EAXRf*.c-a.b-cpOaqRe*.c-a.b-c-a*.c-a.b-cpGer*.c-a.b-c">> = iolist_to_binary(re:replace("*.c-a.b-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","EAXRf&pOaqRe&\\1&pGer&",[])),
- <<"EAXRf*.c-a.b-cpOaqRe*.c-a.b-c-a*.c-a.b-cpGer*.c-a.b-c">> = iolist_to_binary(re:replace("*.c-a.b-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","EAXRf&pOaqRe&\\1&pGer&",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","RmO\\1XAOA\\1p",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","RmO\\1XAOA\\1p",[global])),
- <<"*.0">> = iolist_to_binary(re:replace("*.0","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","&&iBqKyU",[])),
- <<"*.0">> = iolist_to_binary(re:replace("*.0","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","&&iBqKyU",[global])),
- <<"*.a-">> = iolist_to_binary(re:replace("*.a-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","sHEtAniwkH&",[])),
- <<"*.a-">> = iolist_to_binary(re:replace("*.a-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","sHEtAniwkH&",[global])),
- <<"*.a-b.c-">> = iolist_to_binary(re:replace("*.a-b.c-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","qy",[])),
- <<"*.a-b.c-">> = iolist_to_binary(re:replace("*.a-b.c-","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","qy",[global])),
- <<"*.c-a.0-c">> = iolist_to_binary(re:replace("*.c-a.0-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","iH\\1J\\1\\1&iul\\1uosFI",[])),
- <<"*.c-a.0-c">> = iolist_to_binary(re:replace("*.c-a.0-c","^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$","iH\\1J\\1\\1&iul\\1uosFI",[global])),
- <<"RW">> = iolist_to_binary(re:replace("abde","^(?=ab(de))(abd)(e)","RW",[])),
- <<"RW">> = iolist_to_binary(re:replace("abde","^(?=ab(de))(abd)(e)","RW",[global])),
- <<"xrNrabdft">> = iolist_to_binary(re:replace("abdf","^(?!(ab)de|x)(abd)(f)","xrNr&t",[])),
- <<"xrNrabdft">> = iolist_to_binary(re:replace("abdf","^(?!(ab)de|x)(abd)(f)","xrNr&t",[global])),
- <<"PaGpuabSCqabcdabababpbcd">> = iolist_to_binary(re:replace("abcd","^(?=(ab(cd)))(ab)","PaGpu&SCq\\1&&&pb",[])),
- <<"PaGpuabSCqabcdabababpbcd">> = iolist_to_binary(re:replace("abcd","^(?=(ab(cd)))(ab)","PaGpu&SCq\\1&&&pb",[global])),
- <<"eB.d.dgKSFa.b.c.dVO">> = iolist_to_binary(re:replace("a.b.c.d","^[\\da-f](\\.[\\da-f])*$","eB\\1\\1gKSF&VO",[caseless])),
- <<"eB.d.dgKSFa.b.c.dVO">> = iolist_to_binary(re:replace("a.b.c.d","^[\\da-f](\\.[\\da-f])*$","eB\\1\\1gKSF&VO",[caseless,
- global])),
- <<"jpA.B.C.D.Dc.DTWA.B.C.Dl.DKIiy">> = iolist_to_binary(re:replace("A.B.C.D","^[\\da-f](\\.[\\da-f])*$","jp&\\1c\\1TW&l\\1KIiy",[caseless])),
- <<"jpA.B.C.D.Dc.DTWA.B.C.Dl.DKIiy">> = iolist_to_binary(re:replace("A.B.C.D","^[\\da-f](\\.[\\da-f])*$","jp&\\1c\\1TW&l\\1KIiy",[caseless,
- global])),
- <<"NToo.Ca.Ca.b.c.1.2.3.C">> = iolist_to_binary(re:replace("a.b.c.1.2.3.C","^[\\da-f](\\.[\\da-f])*$","NToo\\1a\\1&",[caseless])),
- <<"NToo.Ca.Ca.b.c.1.2.3.C">> = iolist_to_binary(re:replace("a.b.c.1.2.3.C","^[\\da-f](\\.[\\da-f])*$","NToo\\1a\\1&",[caseless,
- global])),
- <<"EftEvTFmRH">> = iolist_to_binary(re:replace("\"1234\"","^\\\".*\\\"\\s*(;.*)?$","\\1\\1EftEvTFmRH",[])),
- <<"EftEvTFmRH">> = iolist_to_binary(re:replace("\"1234\"","^\\\".*\\\"\\s*(;.*)?$","\\1\\1EftEvTFmRH",[global])),
- <<"j\"abcd\" ;Hyx\"abcd\" ;QTtQvYM\"abcd\" ;BK">> = iolist_to_binary(re:replace("\"abcd\" ;","^\\\".*\\\"\\s*(;.*)?$","j&Hyx&QTtQvYM&BK",[])),
- <<"j\"abcd\" ;Hyx\"abcd\" ;QTtQvYM\"abcd\" ;BK">> = iolist_to_binary(re:replace("\"abcd\" ;","^\\\".*\\\"\\s*(;.*)?$","j&Hyx&QTtQvYM&BK",[global])),
- <<"nM">> = iolist_to_binary(re:replace("\"\" ; rhubarb","^\\\".*\\\"\\s*(;.*)?$","nM",[])),
- <<"nM">> = iolist_to_binary(re:replace("\"\" ; rhubarb","^\\\".*\\\"\\s*(;.*)?$","nM",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\\".*\\\"\\s*(;.*)?$","oRWmakO\\1L&pj",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\\".*\\\"\\s*(;.*)?$","oRWmakO\\1L&pj",[global])),
- <<"\"1234\" : things">> = iolist_to_binary(re:replace("\"1234\" : things","^\\\".*\\\"\\s*(;.*)?$","kLuRd&B",[])),
- <<"\"1234\" : things">> = iolist_to_binary(re:replace("\"1234\" : things","^\\\".*\\\"\\s*(;.*)?$","kLuRd&B",[global])),
- <<"ixuQHwgCDVra">> = iolist_to_binary(re:replace("","^$","\\1&i\\1x\\1uQHw&\\1&gCDVra",[])),
- <<"ixuQHwgCDVra">> = iolist_to_binary(re:replace("","^$","\\1&i\\1x\\1uQHw&\\1&gCDVra",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^$","Rg\\1SwLH\\1bP\\1&&S\\1Xa\\1S&",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^$","Rg\\1SwLH\\1bP\\1&&S\\1Xa\\1S&",[global])),
- <<"bgab cxhab cxfOtXqErdcf">> = iolist_to_binary(re:replace("ab c"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","bg&xh&xfOtXqE\\1rdcf",[extended])),
- <<"bgab cxhab cxfOtXqErdcf">> = iolist_to_binary(re:replace("ab c"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","bg&xh&xfOtXqE\\1rdcf",[extended,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","kltlQqVmioWPcgb\\1",[extended])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","kltlQqVmioWPcgb\\1",[extended,
- global])),
- <<"abc">> = iolist_to_binary(re:replace("abc"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","F\\1FmlIs\\1\\1A&gEMuW",[extended])),
- <<"abc">> = iolist_to_binary(re:replace("abc"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","F\\1FmlIs\\1\\1A&gEMuW",[extended,
- global])),
- <<"ab cde">> = iolist_to_binary(re:replace("ab cde"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","&wqEXOys\\1L",[extended])),
- <<"ab cde">> = iolist_to_binary(re:replace("ab cde"," ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","&wqEXOys\\1L",[extended,
- global])),
- <<"yxGLPQCju">> = iolist_to_binary(re:replace("ab c","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","yxGLPQCju",[])),
- <<"yxGLPQCju">> = iolist_to_binary(re:replace("ab c","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","yxGLPQCju",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","JqU&Xjf\\1JY\\1c",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","JqU&Xjf\\1JY\\1c",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","ASnRhMlmWOb\\1Y&&",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","ASnRhMlmWOb\\1Y&&",[global])),
- <<"ab cde">> = iolist_to_binary(re:replace("ab cde","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","QcD",[])),
- <<"ab cde">> = iolist_to_binary(re:replace("ab cde","(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)","QcD",[global])),
- <<"yao">> = iolist_to_binary(re:replace("a bcd","^ a\\ b[c ]d $","\\1yao",[extended])),
- <<"yao">> = iolist_to_binary(re:replace("a bcd","^ a\\ b[c ]d $","\\1yao",[extended,
- global])),
- <<"TrwOQA">> = iolist_to_binary(re:replace("a b d","^ a\\ b[c ]d $","TrwOQA",[extended])),
- <<"TrwOQA">> = iolist_to_binary(re:replace("a b d","^ a\\ b[c ]d $","TrwOQA",[extended,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^ a\\ b[c ]d $","&rUS&afjjm&",[extended])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^ a\\ b[c ]d $","&rUS&afjjm&",[extended,
- global])),
- <<"abcd">> = iolist_to_binary(re:replace("abcd","^ a\\ b[c ]d $","L&XB\\1P",[extended])),
- <<"abcd">> = iolist_to_binary(re:replace("abcd","^ a\\ b[c ]d $","L&XB\\1P",[extended,
- global])),
- <<"ab d">> = iolist_to_binary(re:replace("ab d","^ a\\ b[c ]d $","UMS&\\1tPBWwogPDQ&",[extended])),
- <<"ab d">> = iolist_to_binary(re:replace("ab d","^ a\\ b[c ]d $","UMS&\\1tPBWwogPDQ&",[extended,
- global])),
- <<"xToOqchxqabch">> = iolist_to_binary(re:replace("abcdefhijklm","^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$","xToOqchxq\\1h",[])),
- <<"xToOqchxqabch">> = iolist_to_binary(re:replace("abcdefhijklm","^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$","xToOqchxq\\1h",[global])),
+ <<"JabcdefhijklmSJtCtOhgCabcbabce">> = iolist_to_binary(re:replace("abcdefhijklm","^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$","J&SJtCtOhgC\\1b\\1e",[])),
+ <<"JabcdefhijklmSJtCtOhgCabcbabce">> = iolist_to_binary(re:replace("abcdefhijklm","^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$","J&SJtCtOhgC\\1b\\1e",[global])),
ok.
run2() ->
- <<"LpAcLI">> = iolist_to_binary(re:replace("abcdefhijklm","^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$","LpAcLI",[])),
- <<"LpAcLI">> = iolist_to_binary(re:replace("abcdefhijklm","^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$","LpAcLI",[global])),
- <<"MFa+ Z0+
-QQ">> = iolist_to_binary(re:replace("a+ Z0+
-","^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]","MF\\1&QQ",[])),
- <<"MFa+ Z0+
-QQ">> = iolist_to_binary(re:replace("a+ Z0+
-","^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]","MF\\1&QQ",[global])),
- <<".^$(*+)|{?,?}.^$(*+)|{?,?}suXo">> = iolist_to_binary(re:replace(".^$(*+)|{?,?}","^[.^$|()*+?{,}]+","&&s\\1uX\\1o",[])),
- <<".^$(*+)|{?,?}.^$(*+)|{?,?}suXo">> = iolist_to_binary(re:replace(".^$(*+)|{?,?}","^[.^$|()*+?{,}]+","&&s\\1uX\\1o",[global])),
- <<"KDgPpAUcYEXSK">> = iolist_to_binary(re:replace("z","^a*\\w","KDgP\\1pAUcYEX\\1SK",[])),
- <<"KDgPpAUcYEXSK">> = iolist_to_binary(re:replace("z","^a*\\w","KDgP\\1pAUcYEX\\1SK",[global])),
- <<"slipoLkQ">> = iolist_to_binary(re:replace("az","^a*\\w","slipoLkQ",[])),
- <<"slipoLkQ">> = iolist_to_binary(re:replace("az","^a*\\w","slipoLkQ",[global])),
- <<"ritcgAWBT">> = iolist_to_binary(re:replace("aaaz","^a*\\w","ritcgAWBT",[])),
- <<"ritcgAWBT">> = iolist_to_binary(re:replace("aaaz","^a*\\w","ritcgAWBT",[global])),
- <<"XcRsWQyYNjiYwb">> = iolist_to_binary(re:replace("a","^a*\\w","X\\1cRsWQyYNjiYwb",[])),
- <<"XcRsWQyYNjiYwb">> = iolist_to_binary(re:replace("a","^a*\\w","X\\1cRsWQyYNjiYwb",[global])),
- <<"MaaFKe">> = iolist_to_binary(re:replace("aa","^a*\\w","M&F\\1\\1K\\1e",[])),
- <<"MaaFKe">> = iolist_to_binary(re:replace("aa","^a*\\w","M&F\\1\\1K\\1e",[global])),
- <<"h">> = iolist_to_binary(re:replace("aaaa","^a*\\w","h",[])),
- <<"h">> = iolist_to_binary(re:replace("aaaa","^a*\\w","h",[global])),
- <<"qYN+">> = iolist_to_binary(re:replace("a+","^a*\\w","qYN",[])),
- <<"qYN+">> = iolist_to_binary(re:replace("a+","^a*\\w","qYN",[global])),
- <<"EfVPxKaaaaewBXaaaawUW+">> = iolist_to_binary(re:replace("aa+","^a*\\w","EfVPx\\1K&&ewBX&&wUW",[])),
- <<"EfVPxKaaaaewBXaaaawUW+">> = iolist_to_binary(re:replace("aa+","^a*\\w","EfVPx\\1K&&ewBX&&wUW",[global])),
- <<"hslzzPMpWzzIkdYL">> = iolist_to_binary(re:replace("z","^a*?\\w","hsl&&PMpW&&I\\1kdYL",[])),
- <<"hslzzPMpWzzIkdYL">> = iolist_to_binary(re:replace("z","^a*?\\w","hsl&&PMpW&&I\\1kdYL",[global])),
- <<"RBz">> = iolist_to_binary(re:replace("az","^a*?\\w","R\\1B",[])),
- <<"RBz">> = iolist_to_binary(re:replace("az","^a*?\\w","R\\1B",[global])),
- <<"IvEhVdavyqnaaz">> = iolist_to_binary(re:replace("aaaz","^a*?\\w","IvEhVd&vy\\1qn",[])),
- <<"IvEhVdavyqnaaz">> = iolist_to_binary(re:replace("aaaz","^a*?\\w","IvEhVd&vy\\1qn",[global])),
- <<"JnVaaH">> = iolist_to_binary(re:replace("a","^a*?\\w","JnV&&\\1H\\1",[])),
- <<"JnVaaH">> = iolist_to_binary(re:replace("a","^a*?\\w","JnV&&\\1H\\1",[global])),
- <<"JFfVUa">> = iolist_to_binary(re:replace("aa","^a*?\\w","\\1J\\1FfVU",[])),
- <<"JFfVUa">> = iolist_to_binary(re:replace("aa","^a*?\\w","\\1J\\1FfVU",[global])),
- <<"aDPvxaYarvWrRabShaHaaa">> = iolist_to_binary(re:replace("aaaa","^a*?\\w","aDPvx&Y&rvWrR&bShaH",[])),
- <<"aDPvxaYarvWrRabShaHaaa">> = iolist_to_binary(re:replace("aaaa","^a*?\\w","aDPvx&Y&rvWrR&bShaH",[global])),
- <<"Aih+">> = iolist_to_binary(re:replace("a+","^a*?\\w","Ai\\1h",[])),
- <<"Aih+">> = iolist_to_binary(re:replace("a+","^a*?\\w","Ai\\1h",[global])),
- <<"xbMsOXBdaaAa+">> = iolist_to_binary(re:replace("aa+","^a*?\\w","xbMsOXBd&&A",[])),
- <<"xbMsOXBdaaAa+">> = iolist_to_binary(re:replace("aa+","^a*?\\w","xbMsOXBd&&A",[global])),
- <<"azvPASpIqMtrikazJ">> = iolist_to_binary(re:replace("az","^a+\\w","&vPASpIq\\1Mt\\1r\\1ik&J",[])),
- <<"azvPASpIqMtrikazJ">> = iolist_to_binary(re:replace("az","^a+\\w","&vPASpIq\\1Mt\\1r\\1ik&J",[global])),
- <<"ofnsOlLLpmuNPiXJE">> = iolist_to_binary(re:replace("aaaz","^a+\\w","ofnsOlLLpmuNPiXJE",[])),
- <<"ofnsOlLLpmuNPiXJE">> = iolist_to_binary(re:replace("aaaz","^a+\\w","ofnsOlLLpmuNPiXJE",[global])),
- <<"baaDpxe">> = iolist_to_binary(re:replace("aa","^a+\\w","b&D\\1pxe",[])),
- <<"baaDpxe">> = iolist_to_binary(re:replace("aa","^a+\\w","b&D\\1pxe",[global])),
- <<"blkOVluqr">> = iolist_to_binary(re:replace("aaaa","^a+\\w","b\\1lkOV\\1luqr",[])),
- <<"blkOVluqr">> = iolist_to_binary(re:replace("aaaa","^a+\\w","b\\1lkOV\\1luqr",[global])),
- <<"RNRBD+">> = iolist_to_binary(re:replace("aa+","^a+\\w","RNRBD",[])),
- <<"RNRBD+">> = iolist_to_binary(re:replace("aa+","^a+\\w","RNRBD",[global])),
- <<"CyazerWDQaNazazxDT">> = iolist_to_binary(re:replace("az","^a+?\\w","Cy&\\1erWDQaN&&xDT\\1",[])),
- <<"CyazerWDQaNazazxDT">> = iolist_to_binary(re:replace("az","^a+?\\w","Cy&\\1erWDQaN&&xDT\\1",[global])),
- <<"pqJrRaaNRaz">> = iolist_to_binary(re:replace("aaaz","^a+?\\w","pq\\1J\\1rR&NR",[])),
- <<"pqJrRaaNRaz">> = iolist_to_binary(re:replace("aaaz","^a+?\\w","pq\\1J\\1rR&NR",[global])),
- <<"aaAdj">> = iolist_to_binary(re:replace("aa","^a+?\\w","&Ad\\1j",[])),
- <<"aaAdj">> = iolist_to_binary(re:replace("aa","^a+?\\w","&Ad\\1j",[global])),
- <<"JsRWaaEHmuaaFaaArLaNaaaa">> = iolist_to_binary(re:replace("aaaa","^a+?\\w","JsRW&EHmu&F&\\1ArLaN&",[])),
- <<"JsRWaaEHmuaaFaaArLaNaaaa">> = iolist_to_binary(re:replace("aaaa","^a+?\\w","JsRW&EHmu&F&\\1ArLaN&",[global])),
- <<"hQmeo+">> = iolist_to_binary(re:replace("aa+","^a+?\\w","hQmeo",[])),
- <<"hQmeo+">> = iolist_to_binary(re:replace("aa+","^a+?\\w","hQmeo",[global])),
- <<"tSwgJd1234567890">> = iolist_to_binary(re:replace("1234567890","^\\d{8}\\w{2,}","tSwgJd&",[])),
- <<"tSwgJd1234567890">> = iolist_to_binary(re:replace("1234567890","^\\d{8}\\w{2,}","tSwgJd&",[global])),
- <<"u">> = iolist_to_binary(re:replace("12345678ab","^\\d{8}\\w{2,}","u",[])),
- <<"u">> = iolist_to_binary(re:replace("12345678ab","^\\d{8}\\w{2,}","u",[global])),
- <<"12345678__JvTBhjF">> = iolist_to_binary(re:replace("12345678__","^\\d{8}\\w{2,}","&JvTBhj\\1F",[])),
- <<"12345678__JvTBhjF">> = iolist_to_binary(re:replace("12345678__","^\\d{8}\\w{2,}","&JvTBhj\\1F",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\d{8}\\w{2,}","JQw&GNCBooSB",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\d{8}\\w{2,}","JQw&GNCBooSB",[global])),
- <<"1234567">> = iolist_to_binary(re:replace("1234567","^\\d{8}\\w{2,}","oTp&mFd\\1",[])),
- <<"1234567">> = iolist_to_binary(re:replace("1234567","^\\d{8}\\w{2,}","oTp&mFd\\1",[global])),
- <<"truoieVC">> = iolist_to_binary(re:replace("uoie","^[aeiou\\d]{4,5}$","tr&V\\1\\1C",[])),
- <<"truoieVC">> = iolist_to_binary(re:replace("uoie","^[aeiou\\d]{4,5}$","tr&V\\1\\1C",[global])),
- <<"SIBB1234a">> = iolist_to_binary(re:replace("1234","^[aeiou\\d]{4,5}$","SIBB\\1&a",[])),
- <<"SIBB1234a">> = iolist_to_binary(re:replace("1234","^[aeiou\\d]{4,5}$","SIBB\\1&a",[global])),
- <<"12345KiNQWVML12345HyU">> = iolist_to_binary(re:replace("12345","^[aeiou\\d]{4,5}$","&KiN\\1QWVML&HyU",[])),
- <<"12345KiNQWVML12345HyU">> = iolist_to_binary(re:replace("12345","^[aeiou\\d]{4,5}$","&KiN\\1QWVML&HyU",[global])),
- <<"hxENo">> = iolist_to_binary(re:replace("aaaaa","^[aeiou\\d]{4,5}$","\\1hxENo\\1",[])),
- <<"hxENo">> = iolist_to_binary(re:replace("aaaaa","^[aeiou\\d]{4,5}$","\\1hxENo\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[aeiou\\d]{4,5}$","h&RGpLB\\1hlS&pk\\1&yKh",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[aeiou\\d]{4,5}$","h&RGpLB\\1hlS&pk\\1&yKh",[global])),
- <<"123456">> = iolist_to_binary(re:replace("123456","^[aeiou\\d]{4,5}$","&\\1rrEfxa\\1mc",[])),
- <<"123456">> = iolist_to_binary(re:replace("123456","^[aeiou\\d]{4,5}$","&\\1rrEfxa\\1mc",[global])),
- <<"hJscruoieFbuoie">> = iolist_to_binary(re:replace("uoie","^[aeiou\\d]{4,5}?","hJs\\1cr&Fb&",[])),
- <<"hJscruoieFbuoie">> = iolist_to_binary(re:replace("uoie","^[aeiou\\d]{4,5}?","hJs\\1cr&Fb&",[global])),
- <<"OK12341234bV">> = iolist_to_binary(re:replace("1234","^[aeiou\\d]{4,5}?","OK&&bV",[])),
- <<"OK12341234bV">> = iolist_to_binary(re:replace("1234","^[aeiou\\d]{4,5}?","OK&&bV",[global])),
- <<"g5">> = iolist_to_binary(re:replace("12345","^[aeiou\\d]{4,5}?","g\\1",[])),
- <<"g5">> = iolist_to_binary(re:replace("12345","^[aeiou\\d]{4,5}?","g\\1",[global])),
- <<"MKbLkaaaajjoeeykaaaaa">> = iolist_to_binary(re:replace("aaaaa","^[aeiou\\d]{4,5}?","MKbLk&jjoeeyk&",[])),
- <<"MKbLkaaaajjoeeykaaaaa">> = iolist_to_binary(re:replace("aaaaa","^[aeiou\\d]{4,5}?","MKbLk&jjoeeyk&",[global])),
- <<"qExB1234GQ56">> = iolist_to_binary(re:replace("123456","^[aeiou\\d]{4,5}?","qExB&GQ",[])),
- <<"qExB1234GQ56">> = iolist_to_binary(re:replace("123456","^[aeiou\\d]{4,5}?","qExB&GQ",[global])),
- <<"abc=abcabcshRMauJabceabcMabcvDjywabcw">> = iolist_to_binary(re:replace("abc=abcabc","\\A(abc|def)=(\\1){2,3}\\Z","&shRMauJ\\1e\\1M\\1vDjyw\\1w",[])),
- <<"abc=abcabcshRMauJabceabcMabcvDjywabcw">> = iolist_to_binary(re:replace("abc=abcabc","\\A(abc|def)=(\\1){2,3}\\Z","&shRMauJ\\1e\\1M\\1vDjyw\\1w",[global])),
- <<"def=defdefdefM">> = iolist_to_binary(re:replace("def=defdefdef","\\A(abc|def)=(\\1){2,3}\\Z","&M",[])),
- <<"def=defdefdefM">> = iolist_to_binary(re:replace("def=defdefdef","\\A(abc|def)=(\\1){2,3}\\Z","&M",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\A(abc|def)=(\\1){2,3}\\Z","\\1ums",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\A(abc|def)=(\\1){2,3}\\Z","\\1ums",[global])),
- <<"abc=defdef">> = iolist_to_binary(re:replace("abc=defdef","\\A(abc|def)=(\\1){2,3}\\Z","DkIJLD&Cwg&\\1kq&tsp&&",[])),
- <<"abc=defdef">> = iolist_to_binary(re:replace("abc=defdef","\\A(abc|def)=(\\1){2,3}\\Z","DkIJLD&Cwg&\\1kq&tsp&&",[global])),
- <<"uaahabcdefghijkcda2aqkRJhtVuiyWJaG">> = iolist_to_binary(re:replace("abcdefghijkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$","u\\1ah&\\1qkRJhtVuiyWJaG",[])),
- <<"uaahabcdefghijkcda2aqkRJhtVuiyWJaG">> = iolist_to_binary(re:replace("abcdefghijkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$","u\\1ah&\\1qkRJhtVuiyWJaG",[global])),
- <<"lBSDdJXabcdefghijkkkkcda2DPEXjc">> = iolist_to_binary(re:replace("abcdefghijkkkkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$","lBSDdJX&DPEXjc",[])),
- <<"lBSDdJXabcdefghijkkkkcda2DPEXjc">> = iolist_to_binary(re:replace("abcdefghijkkkkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$","lBSDdJX&DPEXjc",[global])),
- <<"tEYloj">> = iolist_to_binary(re:replace("cataract cataract23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","tEYloj",[])),
- <<"tEYloj">> = iolist_to_binary(re:replace("cataract cataract23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","tEYloj",[global])),
- <<"catatonic catatonic23HiXcatatonic catatonic23">> = iolist_to_binary(re:replace("catatonic catatonic23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","&HiX&",[])),
- <<"catatonic catatonic23HiXcatatonic catatonic23">> = iolist_to_binary(re:replace("catatonic catatonic23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","&HiX&",[global])),
- <<"EtmqcaterpillarvtVmieDAa">> = iolist_to_binary(re:replace("caterpillar caterpillar23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","Etmq\\1vtVmieDAa",[])),
- <<"EtmqcaterpillarvtVmieDAa">> = iolist_to_binary(re:replace("caterpillar caterpillar23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","Etmq\\1vtVmieDAa",[global])),
- <<"rFrom abcd Mon Sep 01 12:33aThFrom abcd Mon Sep 01 12:33rJabcd:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 01 12:33:02 1997","^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]","r&aTh&rJ\\1",[])),
- <<"rFrom abcd Mon Sep 01 12:33aThFrom abcd Mon Sep 01 12:33rJabcd:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 01 12:33:02 1997","^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]","r&aTh&rJ\\1",[global])),
- <<"tKjeGYi:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","tKjeGYi",[])),
- <<"tKjeGYi:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","tKjeGYi",[global])),
- <<"From abcd Mon Sep 1 12:33Sep WqBFrom abcd Mon Sep 1 12:33UFrom abcd Mon Sep 1 12:33MHUFrom abcd Mon Sep 1 12:33:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 1 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","&\\1WqB&U&MHU&",[])),
- <<"From abcd Mon Sep 1 12:33Sep WqBFrom abcd Mon Sep 1 12:33UFrom abcd Mon Sep 1 12:33MHUFrom abcd Mon Sep 1 12:33:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 1 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","&\\1WqB&U&MHU&",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","RWw&\\1f",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","RWw&\\1f",[global])),
- <<"From abcd Sep 01 12:33:02 1997">> = iolist_to_binary(re:replace("From abcd Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","lDKNKPmMpd",[])),
- <<"From abcd Sep 01 12:33:02 1997">> = iolist_to_binary(re:replace("From abcd Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","lDKNKPmMpd",[global])),
- <<"eNnWbKP">> = iolist_to_binary(re:replace("12
-34","^12.34","eNnWbK\\1P",[dotall])),
- <<"eNnWbKP">> = iolist_to_binary(re:replace("12
-34","^12.34","eNnWbK\\1P",[dotall,global])),
- <<"fI12 34N">> = iolist_to_binary(re:replace("12 34","^12.34","fI&N\\1",[dotall])),
- <<"fI12 34N">> = iolist_to_binary(re:replace("12 34","^12.34","fI&N\\1",[dotall,
- global])),
- <<"the quick jmlgbrownfrbrownIaXThxdySok fox">> = iolist_to_binary(re:replace("the quick brown fox","\\w+(?=\\t)","j\\1mlg&fr&IaXThxdySok",[])),
- <<"the quick jmlgbrownfrbrownIaXThxdySok fox">> = iolist_to_binary(re:replace("the quick brown fox","\\w+(?=\\t)","j\\1mlg&fr&IaXThxdySok",[global])),
- <<"foobar is vjQvQsKSfoolish see?cmTPlish see?DB">> = iolist_to_binary(re:replace("foobar is foolish see?","foo(?!bar)(.*)","vjQvQsKS&cmTP\\1DB",[])),
- <<"foobar is vjQvQsKSfoolish see?cmTPlish see?DB">> = iolist_to_binary(re:replace("foobar is foolish see?","foo(?!bar)(.*)","vjQvQsKS&cmTP\\1DB",[global])),
- <<"foobar cGBmrowbar etcrowbar etcxPCf etc">> = iolist_to_binary(re:replace("foobar crowbar etc","(?:(?!foo)...|^.{0,2})bar(.*)","GBm&&xPCf\\1",[])),
- <<"foobar cGBmrowbar etcrowbar etcxPCf etc">> = iolist_to_binary(re:replace("foobar crowbar etc","(?:(?!foo)...|^.{0,2})bar(.*)","GBm&&xPCf\\1",[global])),
- <<"GDErP">> = iolist_to_binary(re:replace("barrel","(?:(?!foo)...|^.{0,2})bar(.*)","GDErP",[])),
- <<"GDErP">> = iolist_to_binary(re:replace("barrel","(?:(?!foo)...|^.{0,2})bar(.*)","GDErP",[global])),
- <<"VFDc2barrelqsDrelRKrelbMVIi2barrelb2barrel">> = iolist_to_binary(re:replace("2barrel","(?:(?!foo)...|^.{0,2})bar(.*)","VFDc&qsD\\1RK\\1bMVIi&b&",[])),
- <<"VFDc2barrelqsDrelRKrelbMVIi2barrelb2barrel">> = iolist_to_binary(re:replace("2barrel","(?:(?!foo)...|^.{0,2})bar(.*)","VFDc&qsD\\1RK\\1bMVIi&b&",[global])),
- <<"DreltMOOKlgrelMMOgA barrel">> = iolist_to_binary(re:replace("A barrel","(?:(?!foo)...|^.{0,2})bar(.*)","D\\1tMOOKlg\\1MMOg&",[])),
- <<"DreltMOOKlgrelMMOgA barrel">> = iolist_to_binary(re:replace("A barrel","(?:(?!foo)...|^.{0,2})bar(.*)","D\\1tMOOKlg\\1MMOg&",[global])),
- <<"DiLKve456">> = iolist_to_binary(re:replace("abc456","^(\\D*)(?=\\d)(?!123)","DiLKve",[])),
- <<"DiLKve456">> = iolist_to_binary(re:replace("abc456","^(\\D*)(?=\\d)(?!123)","DiLKve",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\D*)(?=\\d)(?!123)","BTbC",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\D*)(?=\\d)(?!123)","BTbC",[global])),
- <<"abc123">> = iolist_to_binary(re:replace("abc123","^(\\D*)(?=\\d)(?!123)","DJbM\\1wLxB\\1J&&H\\1&uHc",[])),
- <<"abc123">> = iolist_to_binary(re:replace("abc123","^(\\D*)(?=\\d)(?!123)","DJbM\\1wLxB\\1J&&H\\1&uHc",[global])),
+ <<"vbcbcFLoswabcdefhijklmAEBTabcdefhijklmLxgR">> = iolist_to_binary(re:replace("abcdefhijklm","^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$","v\\1\\1FLosw&AEBT&LxgR",[])),
+ <<"vbcbcFLoswabcdefhijklmAEBTabcdefhijklmLxgR">> = iolist_to_binary(re:replace("abcdefhijklm","^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$","v\\1\\1FLosw&AEBT&LxgR",[global])),
+ <<"rfhXDTtoGIitUa+ Z0+
+aq">> = iolist_to_binary(re:replace("a+ Z0+
+","^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]","rf\\1hXDT\\1toGIitU&aq",[])),
+ <<"rfhXDTtoGIitUa+ Z0+
+aq">> = iolist_to_binary(re:replace("a+ Z0+
+","^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]","rf\\1hXDT\\1toGIitU&aq",[global])),
+ <<"CU.^$(*+)|{?,?}">> = iolist_to_binary(re:replace(".^$(*+)|{?,?}","^[.^$|()*+?{,}]+","CU\\1&",[])),
+ <<"CU.^$(*+)|{?,?}">> = iolist_to_binary(re:replace(".^$(*+)|{?,?}","^[.^$|()*+?{,}]+","CU\\1&",[global])),
+ <<"YBmuTIAl">> = iolist_to_binary(re:replace("z","^a*\\w","YBmuTIAl",[])),
+ <<"YBmuTIAl">> = iolist_to_binary(re:replace("z","^a*\\w","YBmuTIAl",[global])),
+ <<"oQyLlPbDtbyg">> = iolist_to_binary(re:replace("az","^a*\\w","oQyLlP\\1\\1bDt\\1by\\1g",[])),
+ <<"oQyLlPbDtbyg">> = iolist_to_binary(re:replace("az","^a*\\w","oQyLlP\\1\\1bDt\\1by\\1g",[global])),
+ <<"mWdReExiMyALqM">> = iolist_to_binary(re:replace("aaaz","^a*\\w","mWdReExiMyALqM",[])),
+ <<"mWdReExiMyALqM">> = iolist_to_binary(re:replace("aaaz","^a*\\w","mWdReExiMyALqM",[global])),
+ <<"YxwJd">> = iolist_to_binary(re:replace("a","^a*\\w","Yx\\1wJd",[])),
+ <<"YxwJd">> = iolist_to_binary(re:replace("a","^a*\\w","Yx\\1wJd",[global])),
+ <<"WrOXRQ">> = iolist_to_binary(re:replace("aa","^a*\\w","WrOXRQ\\1",[])),
+ <<"WrOXRQ">> = iolist_to_binary(re:replace("aa","^a*\\w","WrOXRQ\\1",[global])),
+ <<"IUtgwPFjpaaaaax">> = iolist_to_binary(re:replace("aaaa","^a*\\w","IUtgwPFjp&ax",[])),
+ <<"IUtgwPFjpaaaaax">> = iolist_to_binary(re:replace("aaaa","^a*\\w","IUtgwPFjp&ax",[global])),
+ <<"CmcxaBmvbENiCdje+">> = iolist_to_binary(re:replace("a+","^a*\\w","Cmcx&BmvbENiCdje\\1",[])),
+ <<"CmcxaBmvbENiCdje+">> = iolist_to_binary(re:replace("a+","^a*\\w","Cmcx&BmvbENiCdje\\1",[global])),
+ <<"ppr+">> = iolist_to_binary(re:replace("aa+","^a*\\w","ppr",[])),
+ <<"ppr+">> = iolist_to_binary(re:replace("aa+","^a*\\w","ppr",[global])),
+ <<"PzqITvYUDMzBNhfmHb">> = iolist_to_binary(re:replace("z","^a*?\\w","P&qITvYUDM\\1&BNhfm\\1Hb",[])),
+ <<"PzqITvYUDMzBNhfmHb">> = iolist_to_binary(re:replace("z","^a*?\\w","P&qITvYUDM\\1&BNhfm\\1Hb",[global])),
+ <<"xjz">> = iolist_to_binary(re:replace("az","^a*?\\w","\\1xj",[])),
+ <<"xjz">> = iolist_to_binary(re:replace("az","^a*?\\w","\\1xj",[global])),
+ <<"nSGvgEaaz">> = iolist_to_binary(re:replace("aaaz","^a*?\\w","nSGvgE",[])),
+ <<"nSGvgEaaz">> = iolist_to_binary(re:replace("aaaz","^a*?\\w","nSGvgE",[global])),
+ <<"akBYqdpnDpF">> = iolist_to_binary(re:replace("a","^a*?\\w","\\1&\\1kBYqdpnDpF",[])),
+ <<"akBYqdpnDpF">> = iolist_to_binary(re:replace("a","^a*?\\w","\\1&\\1kBYqdpnDpF",[global])),
+ <<"aWWhBaca">> = iolist_to_binary(re:replace("aa","^a*?\\w","aWWhB&c",[])),
+ <<"aWWhBaca">> = iolist_to_binary(re:replace("aa","^a*?\\w","aWWhB&c",[global])),
+ <<"EVKLmPxhaadNVCaaa">> = iolist_to_binary(re:replace("aaaa","^a*?\\w","EVKLmPxh&&dNVC\\1",[])),
+ <<"EVKLmPxhaadNVCaaa">> = iolist_to_binary(re:replace("aaaa","^a*?\\w","EVKLmPxh&&dNVC\\1",[global])),
+ <<"ue+">> = iolist_to_binary(re:replace("a+","^a*?\\w","u\\1e",[])),
+ <<"ue+">> = iolist_to_binary(re:replace("a+","^a*?\\w","u\\1e",[global])),
+ <<"xa+">> = iolist_to_binary(re:replace("aa+","^a*?\\w","x",[])),
+ <<"xa+">> = iolist_to_binary(re:replace("aa+","^a*?\\w","x",[global])),
+ <<"mtSazhiAQKFcLgcy">> = iolist_to_binary(re:replace("az","^a+\\w","mtS&hiAQK\\1FcLgcy",[])),
+ <<"mtSazhiAQKFcLgcy">> = iolist_to_binary(re:replace("az","^a+\\w","mtS&hiAQK\\1FcLgcy",[global])),
+ <<"aaazLYLsP">> = iolist_to_binary(re:replace("aaaz","^a+\\w","&LY\\1LsP",[])),
+ <<"aaazLYLsP">> = iolist_to_binary(re:replace("aaaz","^a+\\w","&LY\\1LsP",[global])),
+ <<"JWV">> = iolist_to_binary(re:replace("aa","^a+\\w","JWV",[])),
+ <<"JWV">> = iolist_to_binary(re:replace("aa","^a+\\w","JWV",[global])),
+ <<"GHYCIRYhTaaaaYk">> = iolist_to_binary(re:replace("aaaa","^a+\\w","GHYC\\1IR\\1YhT&Yk",[])),
+ <<"GHYCIRYhTaaaaYk">> = iolist_to_binary(re:replace("aaaa","^a+\\w","GHYC\\1IR\\1YhT&Yk",[global])),
+ <<"qWLubkoR+">> = iolist_to_binary(re:replace("aa+","^a+\\w","qWLubkoR",[])),
+ <<"qWLubkoR+">> = iolist_to_binary(re:replace("aa+","^a+\\w","qWLubkoR",[global])),
+ <<"QgHtshICxVl">> = iolist_to_binary(re:replace("az","^a+?\\w","QgHt\\1shI\\1CxVl",[])),
+ <<"QgHtshICxVl">> = iolist_to_binary(re:replace("az","^a+?\\w","QgHt\\1shI\\1CxVl",[global])),
+ <<"QAUTaz">> = iolist_to_binary(re:replace("aaaz","^a+?\\w","QAUT",[])),
+ <<"QAUTaz">> = iolist_to_binary(re:replace("aaaz","^a+?\\w","QAUT",[global])),
+ <<"aaNKKDqaaXXJvkgaathj">> = iolist_to_binary(re:replace("aa","^a+?\\w","&NKKDq&XXJvkg&thj",[])),
+ <<"aaNKKDqaaXXJvkgaathj">> = iolist_to_binary(re:replace("aa","^a+?\\w","&NKKDq&XXJvkg&thj",[global])),
+ <<"paajyaNtcaa">> = iolist_to_binary(re:replace("aaaa","^a+?\\w","p\\1&jyaNtc",[])),
+ <<"paajyaNtcaa">> = iolist_to_binary(re:replace("aaaa","^a+?\\w","p\\1&jyaNtc",[global])),
+ <<"eKfjhSmMfKaaaap+">> = iolist_to_binary(re:replace("aa+","^a+?\\w","eKfjhSmMfK&&p",[])),
+ <<"eKfjhSmMfKaaaap+">> = iolist_to_binary(re:replace("aa+","^a+?\\w","eKfjhSmMfK&&p",[global])),
+ <<"fqmX1234567890KYJD1234567890dLdQYNvF12345678901234567890">> = iolist_to_binary(re:replace("1234567890","^\\d{8}\\w{2,}","fqmX&KYJD&dLdQYNvF&&",[])),
+ <<"fqmX1234567890KYJD1234567890dLdQYNvF12345678901234567890">> = iolist_to_binary(re:replace("1234567890","^\\d{8}\\w{2,}","fqmX&KYJD&dLdQYNvF&&",[global])),
+ <<"GNln">> = iolist_to_binary(re:replace("12345678ab","^\\d{8}\\w{2,}","G\\1Nln",[])),
+ <<"GNln">> = iolist_to_binary(re:replace("12345678ab","^\\d{8}\\w{2,}","G\\1Nln",[global])),
+ <<"F12345678__LL12345678__JU12345678__IbAQiv12345678__D">> = iolist_to_binary(re:replace("12345678__","^\\d{8}\\w{2,}","F&LL&JU&IbAQi\\1v&D",[])),
+ <<"F12345678__LL12345678__JU12345678__IbAQiv12345678__D">> = iolist_to_binary(re:replace("12345678__","^\\d{8}\\w{2,}","F&LL&JU&IbAQi\\1v&D",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\d{8}\\w{2,}","iStSHxD&bBUiQjj",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\d{8}\\w{2,}","iStSHxD&bBUiQjj",[global])),
+ <<"1234567">> = iolist_to_binary(re:replace("1234567","^\\d{8}\\w{2,}","EEa",[])),
+ <<"1234567">> = iolist_to_binary(re:replace("1234567","^\\d{8}\\w{2,}","EEa",[global])),
+ <<"uoieprPRCuoie">> = iolist_to_binary(re:replace("uoie","^[aeiou\\d]{4,5}$","&pr\\1PRC&",[])),
+ <<"uoieprPRCuoie">> = iolist_to_binary(re:replace("uoie","^[aeiou\\d]{4,5}$","&pr\\1PRC&",[global])),
+ <<"a1234xXJ1234G1234">> = iolist_to_binary(re:replace("1234","^[aeiou\\d]{4,5}$","a&xXJ&G&",[])),
+ <<"a1234xXJ1234G1234">> = iolist_to_binary(re:replace("1234","^[aeiou\\d]{4,5}$","a&xXJ&G&",[global])),
+ <<"GtEhJ12345l">> = iolist_to_binary(re:replace("12345","^[aeiou\\d]{4,5}$","GtEhJ&l",[])),
+ <<"GtEhJ12345l">> = iolist_to_binary(re:replace("12345","^[aeiou\\d]{4,5}$","GtEhJ&l",[global])),
+ <<"bJBYcRNEc">> = iolist_to_binary(re:replace("aaaaa","^[aeiou\\d]{4,5}$","bJBYc\\1RNEc",[])),
+ <<"bJBYcRNEc">> = iolist_to_binary(re:replace("aaaaa","^[aeiou\\d]{4,5}$","bJBYc\\1RNEc",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[aeiou\\d]{4,5}$","\\1CbAy&Gejrv&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[aeiou\\d]{4,5}$","\\1CbAy&Gejrv&",[global])),
+ <<"123456">> = iolist_to_binary(re:replace("123456","^[aeiou\\d]{4,5}$","&ftepSatEwgqIL",[])),
+ <<"123456">> = iolist_to_binary(re:replace("123456","^[aeiou\\d]{4,5}$","&ftepSatEwgqIL",[global])),
+ <<"kJipvPhUNA">> = iolist_to_binary(re:replace("uoie","^[aeiou\\d]{4,5}?","k\\1\\1JipvPhUNA",[])),
+ <<"kJipvPhUNA">> = iolist_to_binary(re:replace("uoie","^[aeiou\\d]{4,5}?","k\\1\\1JipvPhUNA",[global])),
+ <<"yXeJ1234spOtaDGQEa">> = iolist_to_binary(re:replace("1234","^[aeiou\\d]{4,5}?","yXeJ\\1&spOtaDGQ\\1E\\1a",[])),
+ <<"yXeJ1234spOtaDGQEa">> = iolist_to_binary(re:replace("1234","^[aeiou\\d]{4,5}?","yXeJ\\1&spOtaDGQ\\1E\\1a",[global])),
+ <<"otWuaaL12341234F1234Ej5">> = iolist_to_binary(re:replace("12345","^[aeiou\\d]{4,5}?","otWuaaL&&F&E\\1\\1j",[])),
+ <<"otWuaaL12341234F1234Ej5">> = iolist_to_binary(re:replace("12345","^[aeiou\\d]{4,5}?","otWuaaL&&F&E\\1\\1j",[global])),
+ <<"OjJFYaaaafaaaaaaaajmxxNEiDa">> = iolist_to_binary(re:replace("aaaaa","^[aeiou\\d]{4,5}?","\\1OjJFY&f&&jmxxNEiD",[])),
+ <<"OjJFYaaaafaaaaaaaajmxxNEiDa">> = iolist_to_binary(re:replace("aaaaa","^[aeiou\\d]{4,5}?","\\1OjJFY&f&&jmxxNEiD",[global])),
+ <<"xvM1234Anq1234UpiOggGI56">> = iolist_to_binary(re:replace("123456","^[aeiou\\d]{4,5}?","xv\\1M&Anq&Up\\1iOggGI",[])),
+ <<"xvM1234Anq1234UpiOggGI56">> = iolist_to_binary(re:replace("123456","^[aeiou\\d]{4,5}?","xv\\1M&Anq&Up\\1iOggGI",[global])),
+ <<"Cqabc=abcabcabc=abcabcybabcvabcrabcAgJK">> = iolist_to_binary(re:replace("abc=abcabc","\\A(abc|def)=(\\1){2,3}\\Z","Cq&&yb\\1v\\1r\\1AgJK",[])),
+ <<"Cqabc=abcabcabc=abcabcybabcvabcrabcAgJK">> = iolist_to_binary(re:replace("abc=abcabc","\\A(abc|def)=(\\1){2,3}\\Z","Cq&&yb\\1v\\1r\\1AgJK",[global])),
+ <<"e">> = iolist_to_binary(re:replace("def=defdefdef","\\A(abc|def)=(\\1){2,3}\\Z","e",[])),
+ <<"e">> = iolist_to_binary(re:replace("def=defdefdef","\\A(abc|def)=(\\1){2,3}\\Z","e",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\A(abc|def)=(\\1){2,3}\\Z","LC\\1\\1cX&r\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\A(abc|def)=(\\1){2,3}\\Z","LC\\1\\1cX&r\\1",[global])),
+ <<"abc=defdef">> = iolist_to_binary(re:replace("abc=defdef","\\A(abc|def)=(\\1){2,3}\\Z","W&Oq&\\1",[])),
+ <<"abc=defdef">> = iolist_to_binary(re:replace("abc=defdef","\\A(abc|def)=(\\1){2,3}\\Z","W&Oq&\\1",[global])),
+ <<"RbEDawyPg">> = iolist_to_binary(re:replace("abcdefghijkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$","RbED\\1wyPg",[])),
+ <<"RbEDawyPg">> = iolist_to_binary(re:replace("abcdefghijkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$","RbED\\1wyPg",[global])),
+ <<"SglXayyabcdefghijkkkkcda2cXHhsvvXdoa">> = iolist_to_binary(re:replace("abcdefghijkkkkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$","SglX\\1yy&cXHhsvvXdo\\1",[])),
+ <<"SglXayyabcdefghijkkkkcda2cXHhsvvXdoa">> = iolist_to_binary(re:replace("abcdefghijkkkkcda2","^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$","SglX\\1yy&cXHhsvvXdo\\1",[global])),
+ <<"v">> = iolist_to_binary(re:replace("cataract cataract23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","v",[])),
+ <<"v">> = iolist_to_binary(re:replace("cataract cataract23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","v",[global])),
+ <<"acatatonicurmvcatatonic">> = iolist_to_binary(re:replace("catatonic catatonic23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","a\\1urmv\\1",[])),
+ <<"acatatonicurmvcatatonic">> = iolist_to_binary(re:replace("catatonic catatonic23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","a\\1urmv\\1",[global])),
+ <<"XVEjcaterpillar caterpillar23YcaterpillarAnxyWcaterpillarTvYyY">> = iolist_to_binary(re:replace("caterpillar caterpillar23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","XVEj&Y\\1AnxyW\\1TvYyY",[])),
+ <<"XVEjcaterpillar caterpillar23YcaterpillarAnxyWcaterpillarTvYyY">> = iolist_to_binary(re:replace("caterpillar caterpillar23","(cat(a(ract|tonic)|erpillar)) \\1()2(3)","XVEj&Y\\1AnxyW\\1TvYyY",[global])),
+ <<"W:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 01 12:33:02 1997","^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]","W",[])),
+ <<"W:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 01 12:33:02 1997","^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]","W",[global])),
+ <<"IywFrom abcd Mon Sep 01 12:33From abcd Mon Sep 01 12:33Agja:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","Iyw&&Agja",[])),
+ <<"IywFrom abcd Mon Sep 01 12:33From abcd Mon Sep 01 12:33Agja:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","Iyw&&Agja",[global])),
+ <<"TFrom abcd Mon Sep 1 12:33KLniu:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 1 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","T&KLniu",[])),
+ <<"TFrom abcd Mon Sep 1 12:33KLniu:02 1997">> = iolist_to_binary(re:replace("From abcd Mon Sep 1 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","T&KLniu",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","vYiLq&doiJVeyAm",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","vYiLq&doiJVeyAm",[global])),
+ <<"From abcd Sep 01 12:33:02 1997">> = iolist_to_binary(re:replace("From abcd Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","hfXkAD\\1eyf&\\1T&AE",[])),
+ <<"From abcd Sep 01 12:33:02 1997">> = iolist_to_binary(re:replace("From abcd Sep 01 12:33:02 1997","^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d","hfXkAD\\1eyf&\\1T&AE",[global])),
+ <<"wgMRV12
+34dXcgTVheaqJ12
+34uR">> = iolist_to_binary(re:replace("12
+34","^12.34","wgMRV&dXcgTVheaqJ&uR",[dotall])),
+ <<"wgMRV12
+34dXcgTVheaqJ12
+34uR">> = iolist_to_binary(re:replace("12
+34","^12.34","wgMRV&dXcgTVheaqJ&uR",[dotall,global])),
+ <<"Nx12 34XXami">> = iolist_to_binary(re:replace("12 34","^12.34","Nx&XXami",[dotall])),
+ <<"Nx12 34XXami">> = iolist_to_binary(re:replace("12 34","^12.34","Nx&XXami",[dotall,
+ global])),
+ <<"the quick IYgNNy fox">> = iolist_to_binary(re:replace("the quick brown fox","\\w+(?=\\t)","IYgNNy",[])),
+ <<"the quick IYgNNy fox">> = iolist_to_binary(re:replace("the quick brown fox","\\w+(?=\\t)","IYgNNy",[global])),
+ <<"foobar is lish see?VpOwivKT">> = iolist_to_binary(re:replace("foobar is foolish see?","foo(?!bar)(.*)","\\1VpOwivKT",[])),
+ <<"foobar is lish see?VpOwivKT">> = iolist_to_binary(re:replace("foobar is foolish see?","foo(?!bar)(.*)","\\1VpOwivKT",[global])),
+ <<"foobar ctmTbrowbar etcUVS etc etc etcVu">> = iolist_to_binary(re:replace("foobar crowbar etc","(?:(?!foo)...|^.{0,2})bar(.*)","tmTb&UVS\\1\\1\\1Vu",[])),
+ <<"foobar ctmTbrowbar etcUVS etc etc etcVu">> = iolist_to_binary(re:replace("foobar crowbar etc","(?:(?!foo)...|^.{0,2})bar(.*)","tmTb&UVS\\1\\1\\1Vu",[global])),
+ <<"relJSQucc">> = iolist_to_binary(re:replace("barrel","(?:(?!foo)...|^.{0,2})bar(.*)","\\1JSQucc",[])),
+ <<"relJSQucc">> = iolist_to_binary(re:replace("barrel","(?:(?!foo)...|^.{0,2})bar(.*)","\\1JSQucc",[global])),
+ <<"rdrSoV">> = iolist_to_binary(re:replace("2barrel","(?:(?!foo)...|^.{0,2})bar(.*)","rdrSoV",[])),
+ <<"rdrSoV">> = iolist_to_binary(re:replace("2barrel","(?:(?!foo)...|^.{0,2})bar(.*)","rdrSoV",[global])),
+ <<"eXfWy">> = iolist_to_binary(re:replace("A barrel","(?:(?!foo)...|^.{0,2})bar(.*)","eXfWy",[])),
+ <<"eXfWy">> = iolist_to_binary(re:replace("A barrel","(?:(?!foo)...|^.{0,2})bar(.*)","eXfWy",[global])),
+ <<"w456">> = iolist_to_binary(re:replace("abc456","^(\\D*)(?=\\d)(?!123)","w",[])),
+ <<"w456">> = iolist_to_binary(re:replace("abc456","^(\\D*)(?=\\d)(?!123)","w",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\D*)(?=\\d)(?!123)","K\\1\\1AqfXA&w\\1u",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\D*)(?=\\d)(?!123)","K\\1\\1AqfXA&w\\1u",[global])),
+ <<"abc123">> = iolist_to_binary(re:replace("abc123","^(\\D*)(?=\\d)(?!123)","JdWVKM&yVT",[])),
+ <<"abc123">> = iolist_to_binary(re:replace("abc123","^(\\D*)(?=\\d)(?!123)","JdWVKM&yVT",[global])),
ok.
run3() ->
- <<"1234cNbGaCaxuI">> = iolist_to_binary(re:replace("1234","^1234(?# test newlines
- inside)","&cNbGaCaxuI",[])),
- <<"1234cNbGaCaxuI">> = iolist_to_binary(re:replace("1234","^1234(?# test newlines
- inside)","&cNbGaCaxuI",[global])),
- <<"jmCvIAMNV1234nNrfW1234GM">> = iolist_to_binary(re:replace("1234","^1234 #comment in extended re
- ","\\1jmCvIAMNV\\1&nNrfW&GM",[extended])),
- <<"jmCvIAMNV1234nNrfW1234GM">> = iolist_to_binary(re:replace("1234","^1234 #comment in extended re
- ","\\1jmCvIAMNV\\1&nNrfW&GM",[extended,global])),
- <<"YyiILRKFjY">> = iolist_to_binary(re:replace("abcd","#rhubarb
- abcd","YyiILRKFjY",[extended])),
- <<"YyiILRKFjY">> = iolist_to_binary(re:replace("abcd","#rhubarb
- abcd","YyiILRKFjY",[extended,global])),
- <<"XbpsAef">> = iolist_to_binary(re:replace("abcd","^abcd#rhubarb","Xbps\\1Aef",[extended])),
- <<"XbpsAef">> = iolist_to_binary(re:replace("abcd","^abcd#rhubarb","Xbps\\1Aef",[extended,
- global])),
- <<"iPHiDDB">> = iolist_to_binary(re:replace("aaab","^(a)\\1{2,3}(.)","iPHiDDB",[])),
- <<"iPHiDDB">> = iolist_to_binary(re:replace("aaab","^(a)\\1{2,3}(.)","iPHiDDB",[global])),
- <<"IXEQflgnaWgr">> = iolist_to_binary(re:replace("aaaab","^(a)\\1{2,3}(.)","IXEQflgn\\1Wgr",[])),
- <<"IXEQflgnaWgr">> = iolist_to_binary(re:replace("aaaab","^(a)\\1{2,3}(.)","IXEQflgn\\1Wgr",[global])),
- <<"gToJhaaaaaOaaaaaaaaaaaiaaaaaHLaNAWab">> = iolist_to_binary(re:replace("aaaaab","^(a)\\1{2,3}(.)","gToJh&O\\1&&i&HL\\1NAW\\1",[])),
- <<"gToJhaaaaaOaaaaaaaaaaaiaaaaaHLaNAWab">> = iolist_to_binary(re:replace("aaaaab","^(a)\\1{2,3}(.)","gToJh&O\\1&&i&HL\\1NAW\\1",[global])),
- <<"aaaaaaGwEYYdXmTRmaaaaasXab">> = iolist_to_binary(re:replace("aaaaaab","^(a)\\1{2,3}(.)","&\\1GwEYYdXmTRm&sX",[])),
- <<"aaaaaaGwEYYdXmTRmaaaaasXab">> = iolist_to_binary(re:replace("aaaaaab","^(a)\\1{2,3}(.)","&\\1GwEYYdXmTRm&sX",[global])),
- <<"the abcabcLiXhGXmrloabcEfabcAbS">> = iolist_to_binary(re:replace("the abc","(?!^)abc","&&LiXhGXmrlo&Ef&AbS",[])),
- <<"the abcabcLiXhGXmrloabcEfabcAbS">> = iolist_to_binary(re:replace("the abc","(?!^)abc","&&LiXhGXmrlo&Ef&AbS",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?!^)abc","uyPPG",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?!^)abc","uyPPG",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(?!^)abc","x\\1sgS\\1tB\\1RcyA\\1enf",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(?!^)abc","x\\1sgS\\1tB\\1RcyA\\1enf",[global])),
- <<"abcubl">> = iolist_to_binary(re:replace("abc","(?=^)abc","&ubl",[])),
- <<"abcubl">> = iolist_to_binary(re:replace("abc","(?=^)abc","&ubl",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?=^)abc","NPTqioPj",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?=^)abc","NPTqioPj",[global])),
- <<"the abc">> = iolist_to_binary(re:replace("the abc","(?=^)abc","\\1pNTRQmK\\1Hj",[])),
- <<"the abc">> = iolist_to_binary(re:replace("the abc","(?=^)abc","\\1pNTRQmK\\1Hj",[global])),
- <<"QpbbCJcbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}(ab*|b)","Qp\\1bCJc",[])),
- <<"QpbbCJcbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}(ab*|b)","Qp\\1bCJc",[global])),
- <<"PcVuJcWmvIiq">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}?(ab*|b)","PcVuJcWmvIiq",[])),
- <<"PcVuJcWmvIiq">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}?(ab*|b)","PcVuJcWmvIiq",[global])),
- <<"fwRaaeKbsaanjaKaUaadaaybbbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}?(ab*?|b)","fwR&eKbs&nj\\1K\\1U&d\\1\\1y",[])),
- <<"fwRaaeKbsaanjaKaUaadaaybbbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}?(ab*?|b)","fwR&eKbs&nj\\1K\\1U&d\\1\\1y",[global])),
- <<"bblQaabbCsbbeeQvYbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}(ab*?|b)","\\1\\1lQ&Cs\\1\\1eeQvY",[])),
- <<"bblQaabbCsbbeeQvYbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}(ab*?|b)","\\1\\1lQ&Cs\\1\\1eeQvY",[global])),
+ <<"iuO1234wOcoFuHtrEJy">> = iolist_to_binary(re:replace("1234","^1234(?# test newlines
+ inside)","iuO&wOcoFuHtrE\\1Jy",[])),
+ <<"iuO1234wOcoFuHtrEJy">> = iolist_to_binary(re:replace("1234","^1234(?# test newlines
+ inside)","iuO&wOcoFuHtrE\\1Jy",[global])),
+ <<"gJCrEQqo1234JrkS">> = iolist_to_binary(re:replace("1234","^1234 #comment in extended re
+ ","gJC\\1rE\\1Qq\\1o&JrkS",[extended])),
+ <<"gJCrEQqo1234JrkS">> = iolist_to_binary(re:replace("1234","^1234 #comment in extended re
+ ","gJC\\1rE\\1Qq\\1o&JrkS",[extended,global])),
+ <<"MTEpBuVJ">> = iolist_to_binary(re:replace("abcd","#rhubarb
+ abcd","MTEpBuVJ",[extended])),
+ <<"MTEpBuVJ">> = iolist_to_binary(re:replace("abcd","#rhubarb
+ abcd","MTEpBuVJ",[extended,global])),
+ <<"abcdjMyabcdxPHwTRWabcdgliA">> = iolist_to_binary(re:replace("abcd","^abcd#rhubarb","&jMy&xPHwTRW&g\\1liA",[extended])),
+ <<"abcdjMyabcdxPHwTRWabcdgliA">> = iolist_to_binary(re:replace("abcd","^abcd#rhubarb","&jMy&xPHwTRW&g\\1liA",[extended,
+ global])),
+ <<"OaE">> = iolist_to_binary(re:replace("aaab","^(a)\\1{2,3}(.)","O\\1E",[])),
+ <<"OaE">> = iolist_to_binary(re:replace("aaab","^(a)\\1{2,3}(.)","O\\1E",[global])),
+ <<"CapFaBaaaabGaaaabg">> = iolist_to_binary(re:replace("aaaab","^(a)\\1{2,3}(.)","C\\1pF\\1B&G&g",[])),
+ <<"CapFaBaaaabGaaaabg">> = iolist_to_binary(re:replace("aaaab","^(a)\\1{2,3}(.)","C\\1pF\\1B&G&g",[global])),
+ <<"Faaaaab">> = iolist_to_binary(re:replace("aaaaab","^(a)\\1{2,3}(.)","F&",[])),
+ <<"Faaaaab">> = iolist_to_binary(re:replace("aaaaab","^(a)\\1{2,3}(.)","F&",[global])),
+ <<"caaaaaHRiaaaaaCFuIab">> = iolist_to_binary(re:replace("aaaaaab","^(a)\\1{2,3}(.)","c&HRi&CFuI",[])),
+ <<"caaaaaHRiaaaaaCFuIab">> = iolist_to_binary(re:replace("aaaaaab","^(a)\\1{2,3}(.)","c&HRi&CFuI",[global])),
+ <<"the gjabcPpEkyabcIiyEk">> = iolist_to_binary(re:replace("the abc","(?!^)abc","gj&PpEky&Ii\\1yEk",[])),
+ <<"the gjabcPpEkyabcIiyEk">> = iolist_to_binary(re:replace("the abc","(?!^)abc","gj&PpEky&Ii\\1yEk",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?!^)abc","tRf&&sbxQaC",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?!^)abc","tRf&&sbxQaC",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(?!^)abc","H\\1BG&fg&PqEB&VP\\1",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(?!^)abc","H\\1BG&fg&PqEB&VP\\1",[global])),
+ <<"ybQFSlI">> = iolist_to_binary(re:replace("abc","(?=^)abc","\\1yb\\1QFSlI",[])),
+ <<"ybQFSlI">> = iolist_to_binary(re:replace("abc","(?=^)abc","\\1yb\\1QFSlI",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?=^)abc","J",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?=^)abc","J",[global])),
+ <<"the abc">> = iolist_to_binary(re:replace("the abc","(?=^)abc","x&",[])),
+ <<"the abc">> = iolist_to_binary(re:replace("the abc","(?=^)abc","x&",[global])),
+ <<"hfsXbvuonxbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}(ab*|b)","hfsX\\1vuonx",[])),
+ <<"hfsXbvuonxbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}(ab*|b)","hfsX\\1vuonx",[global])),
+ <<"ddI">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}?(ab*|b)","ddI",[])),
+ <<"ddI">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}?(ab*|b)","ddI",[global])),
+ <<"abbbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}?(ab*?|b)","\\1",[])),
+ <<"abbbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}?(ab*?|b)","\\1",[global])),
+ <<"bRgwsOaabbaabbKBhbbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}(ab*?|b)","\\1RgwsO&&KBh\\1",[])),
+ <<"bRgwsOaabbaabbKBhbbbb">> = iolist_to_binary(re:replace("aabbbbb","^[ab]{1,3}(ab*?|b)","\\1RgwsO&&KBh\\1",[global])),
<<"Alan Other <user.ain>">> = iolist_to_binary(re:replace("Alan Other <user.ain>"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -960,7 +966,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","SOd&j",[extended])),
+\\) )* # optional trailing comment","KOt\\1Sm",[extended])),
<<"Alan Other <user.ain>">> = iolist_to_binary(re:replace("Alan Other <user.ain>"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -1153,8 +1159,8 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","SOd&j",[extended,
- global])),
+\\) )* # optional trailing comment","KOt\\1Sm",[extended,
+ global])),
<<"<user.ain>">> = iolist_to_binary(re:replace("<user.ain>"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -1347,7 +1353,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","Rli",[extended])),
+\\) )* # optional trailing comment","\\1",[extended])),
<<"<user.ain>">> = iolist_to_binary(re:replace("<user.ain>"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -1540,8 +1546,8 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","Rli",[extended,
- global])),
+\\) )* # optional trailing comment","\\1",[extended,
+ global])),
<<"user.ain">> = iolist_to_binary(re:replace("user.ain"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -1734,7 +1740,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","g&TWfEDY",[extended])),
+\\) )* # optional trailing comment","B&N\\1mWiqND\\1Ye",[extended])),
<<"user.ain">> = iolist_to_binary(re:replace("user.ain"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -1927,8 +1933,8 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","g&TWfEDY",[extended,
- global])),
+\\) )* # optional trailing comment","B&N\\1mWiqND\\1Ye",[extended,
+ global])),
<<"\"A. Other\" <user.1234.ain> (a comment)">> = iolist_to_binary(re:replace("\"A. Other\" <user.1234.ain> (a comment)"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -2121,7 +2127,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","Cw",[extended])),
+\\) )* # optional trailing comment","k&&P&fhieC&HuV\\1&",[extended])),
<<"\"A. Other\" <user.1234.ain> (a comment)">> = iolist_to_binary(re:replace("\"A. Other\" <user.1234.ain> (a comment)"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -2314,8 +2320,8 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","Cw",[extended,
- global])),
+\\) )* # optional trailing comment","k&&P&fhieC&HuV\\1&",[extended,
+ global])),
<<"A. Other <user.1234.ain> (a comment)">> = iolist_to_binary(re:replace("A. Other <user.1234.ain> (a comment)"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -2508,7 +2514,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","ej",[extended])),
+\\) )* # optional trailing comment","FM",[extended])),
<<"A. Other <user.1234.ain> (a comment)">> = iolist_to_binary(re:replace("A. Other <user.1234.ain> (a comment)"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -2701,7 +2707,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","ej",[extended,
+\\) )* # optional trailing comment","FM",[extended,
global])),
<<"\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay">> = iolist_to_binary(re:replace("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
@@ -2895,7 +2901,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","y\\1D",[extended])),
+\\) )* # optional trailing comment","aIlGG",[extended])),
<<"\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay">> = iolist_to_binary(re:replace("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -3088,8 +3094,8 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","y\\1D",[extended,
- global])),
+\\) )* # optional trailing comment","aIlGG",[extended,
+ global])),
<<"A missing angle <user.where">> = iolist_to_binary(re:replace("A missing angle <user.where"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -3282,7 +3288,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","\\1jrwjC",[extended])),
+\\) )* # optional trailing comment","nAjRNoagN&FbIU&T\\1",[extended])),
<<"A missing angle <user.where">> = iolist_to_binary(re:replace("A missing angle <user.where"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -3475,8 +3481,8 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","\\1jrwjC",[extended,
- global])),
+\\) )* # optional trailing comment","nAjRNoagN&FbIU&T\\1",[extended,
+ global])),
<<"*** Failers">> = iolist_to_binary(re:replace("*** Failers"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -3669,7 +3675,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","&qqjm",[extended])),
+\\) )* # optional trailing comment","WS&e",[extended])),
<<"*** Failers">> = iolist_to_binary(re:replace("*** Failers"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -3862,8 +3868,8 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","&qqjm",[extended,
- global])),
+\\) )* # optional trailing comment","WS&e",[extended,
+ global])),
<<"The quick brown fox">> = iolist_to_binary(re:replace("The quick brown fox"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -4056,7 +4062,7 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","m\\1K&o&&mg&qC&f\\1V\\1i",[extended])),
+\\) )* # optional trailing comment","jr&XvtMJM\\1kk\\1EUHVx",[extended])),
<<"The quick brown fox">> = iolist_to_binary(re:replace("The quick brown fox"," (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
\\) )* # optional leading comment
@@ -4249,8 +4255,8 @@ run3() ->
# name and address
) (?: [\\040\\t] | \\(
(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*
-\\) )* # optional trailing comment","m\\1K&o&&mg&qC&f\\1V\\1i",[extended,
- global])),
+\\) )* # optional trailing comment","jr&XvtMJM\\1kk\\1EUHVx",[extended,
+ global])),
<<"Alan Other <user.ain>">> = iolist_to_binary(re:replace("Alan Other <user.ain>","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -4831,7 +4837,7 @@ run3() ->
# address spec
> # >
# name and address
-)","d\\1&sJD\\1oA\\1Aruv",[extended])),
+)","Q&W&\\1Y\\1xPgs\\1rlH\\1BF",[extended])),
<<"Alan Other <user.ain>">> = iolist_to_binary(re:replace("Alan Other <user.ain>","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -5412,7 +5418,7 @@ run3() ->
# address spec
> # >
# name and address
-)","d\\1&sJD\\1oA\\1Aruv",[extended,global])),
+)","Q&W&\\1Y\\1xPgs\\1rlH\\1BF",[extended,global])),
<<"<user.ain>">> = iolist_to_binary(re:replace("<user.ain>","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -5993,7 +5999,7 @@ run3() ->
# address spec
> # >
# name and address
-)","HuWGl&iF&NPX&",[extended])),
+)","&",[extended])),
<<"<user.ain>">> = iolist_to_binary(re:replace("<user.ain>","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -6574,7 +6580,7 @@ run3() ->
# address spec
> # >
# name and address
-)","HuWGl&iF&NPX&",[extended,global])),
+)","&",[extended,global])),
<<"user.ain">> = iolist_to_binary(re:replace("user.ain","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -7155,7 +7161,7 @@ run3() ->
# address spec
> # >
# name and address
-)","VhK&cYXg&Bq\\1f&F",[extended])),
+)","&i\\1Gf\\1siR\\1e&Dl\\1BkGV",[extended])),
<<"user.ain">> = iolist_to_binary(re:replace("user.ain","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -7736,7 +7742,7 @@ run3() ->
# address spec
> # >
# name and address
-)","VhK&cYXg&Bq\\1f&F",[extended,global])),
+)","&i\\1Gf\\1siR\\1e&Dl\\1BkGV",[extended,global])),
<<"\"A. Other\" <user.1234.ain> (a comment)">> = iolist_to_binary(re:replace("\"A. Other\" <user.1234.ain> (a comment)","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -8317,7 +8323,7 @@ run3() ->
# address spec
> # >
# name and address
-)","a\\1&eMwwW",[extended])),
+)","&&CV&S&OMP\\1iO\\1&vbRN",[extended])),
<<"\"A. Other\" <user.1234.ain> (a comment)">> = iolist_to_binary(re:replace("\"A. Other\" <user.1234.ain> (a comment)","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -8898,7 +8904,7 @@ run3() ->
# address spec
> # >
# name and address
-)","a\\1&eMwwW",[extended,global])),
+)","&&CV&S&OMP\\1iO\\1&vbRN",[extended,global])),
<<"A. Other <user.1234.ain> (a comment)">> = iolist_to_binary(re:replace("A. Other <user.1234.ain> (a comment)","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -9479,7 +9485,7 @@ run3() ->
# address spec
> # >
# name and address
-)","\\1n\\1nYhyxBv&nk&&Sa",[extended])),
+)","YI&Yg\\1T",[extended])),
<<"A. Other <user.1234.ain> (a comment)">> = iolist_to_binary(re:replace("A. Other <user.1234.ain> (a comment)","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -10060,7 +10066,7 @@ run3() ->
# address spec
> # >
# name and address
-)","\\1n\\1nYhyxBv&nk&&Sa",[extended,global])),
+)","YI&Yg\\1T",[extended,global])),
<<"\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay">> = iolist_to_binary(re:replace("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -10641,7 +10647,7 @@ run3() ->
# address spec
> # >
# name and address
-)","\\1fdORBWKv\\1&",[extended])),
+)","\\1TIeRL\\1UKGJ",[extended])),
<<"\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay">> = iolist_to_binary(re:replace("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"-re.lay","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -11222,7 +11228,7 @@ run3() ->
# address spec
> # >
# name and address
-)","\\1fdORBWKv\\1&",[extended,global])),
+)","\\1TIeRL\\1UKGJ",[extended,global])),
<<"A missing angle <user.where">> = iolist_to_binary(re:replace("A missing angle <user.where","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -11803,7 +11809,7 @@ run3() ->
# address spec
> # >
# name and address
-)","Utb&\\1l&M\\1aori&\\1&W",[extended])),
+)","eHSpF&XJCAH",[extended])),
<<"A missing angle <user.where">> = iolist_to_binary(re:replace("A missing angle <user.where","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -12384,7 +12390,7 @@ run3() ->
# address spec
> # >
# name and address
-)","Utb&\\1l&M\\1aori&\\1&W",[extended,global])),
+)","eHSpF&XJCAH",[extended,global])),
<<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -12965,7 +12971,7 @@ run3() ->
# address spec
> # >
# name and address
-)","\\1&RUPp\\1",[extended])),
+)","&kowbne",[extended])),
<<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -13546,7 +13552,7 @@ run3() ->
# address spec
> # >
# name and address
-)","\\1&RUPp\\1",[extended,global])),
+)","&kowbne",[extended,global])),
<<"The quick brown fox">> = iolist_to_binary(re:replace("The quick brown fox","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -14127,7 +14133,7 @@ run3() ->
# address spec
> # >
# name and address
-)","M",[extended])),
+)","Gx\\1NKVD",[extended])),
<<"The quick brown fox">> = iolist_to_binary(re:replace("The quick brown fox","[\\040\\t]* # Nab whitespace.
(?:
\\( # (
@@ -14708,805 +14714,784 @@ run3() ->
# address spec
> # >
# name and address
-)","M",[extended,global])),
- <<"abcdefpqrxyz0AB">> = iolist_to_binary(re:replace("abcdefpqrxyz0AB","abc\\0def\\00pqr\\000xyz\\0000AB","\\1\\1giII\\1hWW&bdV&",[])),
- <<"abcdefpqrxyz0AB">> = iolist_to_binary(re:replace("abcdefpqrxyz0AB","abc\\0def\\00pqr\\000xyz\\0000AB","\\1\\1giII\\1hWW&bdV&",[global])),
- <<"abc456 abcdefpqrxyz0ABCDE">> = iolist_to_binary(re:replace("abc456 abcdefpqrxyz0ABCDE","abc\\0def\\00pqr\\000xyz\\0000AB","cc\\1IiVp",[])),
- <<"abc456 abcdefpqrxyz0ABCDE">> = iolist_to_binary(re:replace("abc456 abcdefpqrxyz0ABCDE","abc\\0def\\00pqr\\000xyz\\0000AB","cc\\1IiVp",[global])),
- <<"abc efpqr0xyz00AB">> = iolist_to_binary(re:replace("abc efpqr0xyz00AB","abc\\x0def\\x00pqr\\x000xyz\\x0000AB","prtuhkbIaj&qwHuPpE",[])),
- <<"abc efpqr0xyz00AB">> = iolist_to_binary(re:replace("abc efpqr0xyz00AB","abc\\x0def\\x00pqr\\x000xyz\\x0000AB","prtuhkbIaj&qwHuPpE",[global])),
- <<"abc456 abc efpqr0xyz00ABCDE">> = iolist_to_binary(re:replace("abc456 abc efpqr0xyz00ABCDE","abc\\x0def\\x00pqr\\x000xyz\\x0000AB","&yfjpcn",[])),
- <<"abc456 abc efpqr0xyz00ABCDE">> = iolist_to_binary(re:replace("abc456 abc efpqr0xyz00ABCDE","abc\\x0def\\x00pqr\\x000xyz\\x0000AB","&yfjpcn",[global])),
- <<"A">> = iolist_to_binary(re:replace("A","^[\\000-\\037]","fNpC&qUvThkjHh",[])),
- <<"A">> = iolist_to_binary(re:replace("A","^[\\000-\\037]","fNpC&qUvThkjHh",[global])),
- <<"QyKsB">> = iolist_to_binary(re:replace("B","^[\\000-\\037]","QyKs",[])),
- <<"QyKsB">> = iolist_to_binary(re:replace("B","^[\\000-\\037]","QyKs",[global])),
- <<"ESQC">> = iolist_to_binary(re:replace("C","^[\\000-\\037]","ESQ",[])),
- <<"ESQC">> = iolist_to_binary(re:replace("C","^[\\000-\\037]","ESQ",[global])),
- <<"aTcfAMkUonvqo">> = iolist_to_binary(re:replace("","\\0*","aT&cfAM&\\1kU\\1onvq&o",[])),
- <<"aTcfAMkUonvqo">> = iolist_to_binary(re:replace("","\\0*","aT&cfAM&\\1kU\\1onvq&o",[global])),
- <<"The AZ">> = iolist_to_binary(re:replace("The AZ","A\\x0{2,3}Z","vmgVokP\\1Omhk&",[])),
- <<"The AZ">> = iolist_to_binary(re:replace("The AZ","A\\x0{2,3}Z","vmgVokP\\1Omhk&",[global])),
- <<"An AZ">> = iolist_to_binary(re:replace("An AZ","A\\x0{2,3}Z","VQmaqWv&eULrw\\1glxho",[])),
- <<"An AZ">> = iolist_to_binary(re:replace("An AZ","A\\x0{2,3}Z","VQmaqWv&eULrw\\1glxho",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","A\\x0{2,3}Z","UjPLaoqUhTok\\1&kA\\1G",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","A\\x0{2,3}Z","UjPLaoqUhTok\\1&kA\\1G",[global])),
- <<"AZ">> = iolist_to_binary(re:replace("AZ","A\\x0{2,3}Z","\\1&y&cuh&VgTD&wTnGp",[])),
- <<"AZ">> = iolist_to_binary(re:replace("AZ","A\\x0{2,3}Z","\\1&y&cuh&VgTD&wTnGp",[global])),
- <<"AZ">> = iolist_to_binary(re:replace("AZ","A\\x0{2,3}Z","gEElh\\1ECMKe&HElIjJc",[])),
- <<"AZ">> = iolist_to_binary(re:replace("AZ","A\\x0{2,3}Z","gEElh\\1ECMKe&HElIjJc",[global])),
- <<"cowcowbellYcowcowbelludyJcowE">> = iolist_to_binary(re:replace("cowcowbell","^(cow|)\\1(bell)","&Y&udyJ\\1E",[])),
- <<"cowcowbellYcowcowbelludyJcowE">> = iolist_to_binary(re:replace("cowcowbell","^(cow|)\\1(bell)","&Y&udyJ\\1E",[global])),
- <<"XIIG">> = iolist_to_binary(re:replace("bell","^(cow|)\\1(bell)","XIIG\\1",[])),
- <<"XIIG">> = iolist_to_binary(re:replace("bell","^(cow|)\\1(bell)","XIIG\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(cow|)\\1(bell)","FV&UIVc&",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(cow|)\\1(bell)","FV&UIVc&",[global])),
- <<"cowbell">> = iolist_to_binary(re:replace("cowbell","^(cow|)\\1(bell)","C&&\\1YwKbOHQIgm&R\\1\\1t",[])),
- <<"cowbell">> = iolist_to_binary(re:replace("cowbell","^(cow|)\\1(bell)","C&&\\1YwKbOHQIgm&R\\1\\1t",[global])),
- <<"ywr abc">> = iolist_to_binary(re:replace(" abc","^\\s","ywr&",[])),
- <<"ywr abc">> = iolist_to_binary(re:replace(" abc","^\\s","ywr&",[global])),
- <<" fRabc">> = iolist_to_binary(re:replace(" abc","^\\s","&fR",[])),
- <<" fRabc">> = iolist_to_binary(re:replace(" abc","^\\s","&fR",[global])),
- <<"CHbSJabc">> = iolist_to_binary(re:replace("
-abc","^\\s","CHbSJ",[])),
- <<"CHbSJabc">> = iolist_to_binary(re:replace("
-abc","^\\s","CHbSJ",[global])),
- <<"nivOFemIauK XVEPabc">> = iolist_to_binary(re:replace(" abc","^\\s","n\\1ivOFemIauK&&XVEP",[])),
- <<"nivOFemIauK XVEPabc">> = iolist_to_binary(re:replace(" abc","^\\s","n\\1ivOFemIauK&&XVEP",[global])),
- <<"Hs Cwabc">> = iolist_to_binary(re:replace(" abc","^\\s","Hs&Cw",[])),
- <<"Hs Cwabc">> = iolist_to_binary(re:replace(" abc","^\\s","Hs&Cw",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\s","wydaKxDrmaSC\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\s","wydaKxDrmaSC\\1",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","^\\s","&mmImPqIRmsQLWtEuv\\1",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","^\\s","&mmImPqIRmsQLWtEuv\\1",[global])),
+)","Gx\\1NKVD",[extended,global])),
+ <<"abcdefpqrxyz0AB">> = iolist_to_binary(re:replace("abcdefpqrxyz0AB","abc\\0def\\00pqr\\000xyz\\0000AB","dkxNTS&f",[])),
+ <<"abcdefpqrxyz0AB">> = iolist_to_binary(re:replace("abcdefpqrxyz0AB","abc\\0def\\00pqr\\000xyz\\0000AB","dkxNTS&f",[global])),
+ <<"abc456 abcdefpqrxyz0ABCDE">> = iolist_to_binary(re:replace("abc456 abcdefpqrxyz0ABCDE","abc\\0def\\00pqr\\000xyz\\0000AB","nJiU&",[])),
+ <<"abc456 abcdefpqrxyz0ABCDE">> = iolist_to_binary(re:replace("abc456 abcdefpqrxyz0ABCDE","abc\\0def\\00pqr\\000xyz\\0000AB","nJiU&",[global])),
+ <<"abc efpqr0xyz00AB">> = iolist_to_binary(re:replace("abc efpqr0xyz00AB","abc\\x0def\\x00pqr\\x000xyz\\x0000AB","V&ijCkR\\1gwPa\\1voR&",[])),
+ <<"abc efpqr0xyz00AB">> = iolist_to_binary(re:replace("abc efpqr0xyz00AB","abc\\x0def\\x00pqr\\x000xyz\\x0000AB","V&ijCkR\\1gwPa\\1voR&",[global])),
+ <<"abc456 abc efpqr0xyz00ABCDE">> = iolist_to_binary(re:replace("abc456 abc efpqr0xyz00ABCDE","abc\\x0def\\x00pqr\\x000xyz\\x0000AB","X\\1\\1wk",[])),
+ <<"abc456 abc efpqr0xyz00ABCDE">> = iolist_to_binary(re:replace("abc456 abc efpqr0xyz00ABCDE","abc\\x0def\\x00pqr\\x000xyz\\x0000AB","X\\1\\1wk",[global])),
+ <<"A">> = iolist_to_binary(re:replace("A","^[\\000-\\037]","tyqFsu&vfUBb&kaQBG",[])),
+ <<"A">> = iolist_to_binary(re:replace("A","^[\\000-\\037]","tyqFsu&vfUBb&kaQBG",[global])),
+ <<"DWjvqBB">> = iolist_to_binary(re:replace("B","^[\\000-\\037]","DWjvqB",[])),
+ <<"DWjvqBB">> = iolist_to_binary(re:replace("B","^[\\000-\\037]","DWjvqB",[global])),
+ <<"ctmC">> = iolist_to_binary(re:replace("C","^[\\000-\\037]","ctm",[])),
+ <<"ctmC">> = iolist_to_binary(re:replace("C","^[\\000-\\037]","ctm",[global])),
+ <<"tQmDpnh">> = iolist_to_binary(re:replace("","\\0*","tQ&mDpnh",[])),
+ <<"tQmDpnh">> = iolist_to_binary(re:replace("","\\0*","tQ&mDpnh",[global])),
+ <<"The AZ">> = iolist_to_binary(re:replace("The AZ","A\\x0{2,3}Z","pmlUUNWGtb",[])),
+ <<"The AZ">> = iolist_to_binary(re:replace("The AZ","A\\x0{2,3}Z","pmlUUNWGtb",[global])),
+ <<"An AZ">> = iolist_to_binary(re:replace("An AZ","A\\x0{2,3}Z","y",[])),
+ <<"An AZ">> = iolist_to_binary(re:replace("An AZ","A\\x0{2,3}Z","y",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","A\\x0{2,3}Z","h&yF&Oe",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","A\\x0{2,3}Z","h&yF&Oe",[global])),
+ <<"AZ">> = iolist_to_binary(re:replace("AZ","A\\x0{2,3}Z","\\1U\\1",[])),
+ <<"AZ">> = iolist_to_binary(re:replace("AZ","A\\x0{2,3}Z","\\1U\\1",[global])),
+ <<"AZ">> = iolist_to_binary(re:replace("AZ","A\\x0{2,3}Z","vlOt\\1DNTdL&T",[])),
+ <<"AZ">> = iolist_to_binary(re:replace("AZ","A\\x0{2,3}Z","vlOt\\1DNTdL&T",[global])),
+ <<"cowcowbellcowcowbellNBJqwwYkcowuI">> = iolist_to_binary(re:replace("cowcowbell","^(cow|)\\1(bell)","&&NBJqwwYk\\1uI",[])),
+ <<"cowcowbellcowcowbellNBJqwwYkcowuI">> = iolist_to_binary(re:replace("cowcowbell","^(cow|)\\1(bell)","&&NBJqwwYk\\1uI",[global])),
+ <<"VGNLxyRxhavyOhbell">> = iolist_to_binary(re:replace("bell","^(cow|)\\1(bell)","VGNLxyRxhavyOh&",[])),
+ <<"VGNLxyRxhavyOhbell">> = iolist_to_binary(re:replace("bell","^(cow|)\\1(bell)","VGNLxyRxhavyOh&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(cow|)\\1(bell)","Fe&GxeL&lybNB&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(cow|)\\1(bell)","Fe&GxeL&lybNB&",[global])),
+ <<"cowbell">> = iolist_to_binary(re:replace("cowbell","^(cow|)\\1(bell)","Wgx&BGClp",[])),
+ <<"cowbell">> = iolist_to_binary(re:replace("cowbell","^(cow|)\\1(bell)","Wgx&BGClp",[global])),
+ <<"K e BfRGaOUxabc">> = iolist_to_binary(re:replace(" abc","^\\s","K&e&BfRGaOUx",[])),
+ <<"K e BfRGaOUxabc">> = iolist_to_binary(re:replace(" abc","^\\s","K&e&BfRGaOUx",[global])),
+ <<"GrLooFQabc">> = iolist_to_binary(re:replace(" abc","^\\s","GrLooFQ",[])),
+ <<"GrLooFQabc">> = iolist_to_binary(re:replace(" abc","^\\s","GrLooFQ",[global])),
+ <<"
+IaCpCUh
+NCFWKSeQ
+abc">> = iolist_to_binary(re:replace("
+abc","^\\s","&IaCpCUh&N\\1CFWKSeQ&",[])),
+ <<"
+IaCpCUh
+NCFWKSeQ
+abc">> = iolist_to_binary(re:replace("
+abc","^\\s","&IaCpCUh&N\\1CFWKSeQ&",[global])),
+ <<"SAkruTkabc">> = iolist_to_binary(re:replace(" abc","^\\s","SAkr\\1\\1uTk",[])),
+ <<"SAkruTkabc">> = iolist_to_binary(re:replace(" abc","^\\s","SAkr\\1\\1uTk",[global])),
+ <<"yJfqnwmjabc">> = iolist_to_binary(re:replace(" abc","^\\s","yJfqnwmj\\1",[])),
+ <<"yJfqnwmjabc">> = iolist_to_binary(re:replace(" abc","^\\s","yJfqnwmj\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\s","&GwsRTRpcU",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\s","&GwsRTRpcU",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","^\\s","piG\\1AslUT&rVHB&",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","^\\s","piG\\1AslUT&rVHB&",[global])),
ok.
run4() ->
- <<"KvcEQcubkfx">> = iolist_to_binary(re:replace("abc","^a b
- c","KvcEQc\\1\\1ubkfx",[extended])),
- <<"KvcEQcubkfx">> = iolist_to_binary(re:replace("abc","^a b
- c","KvcEQc\\1\\1ubkfx",[extended,global])),
- <<"IEabanuYG">> = iolist_to_binary(re:replace("ab","^(a|)\\1*b","IE&\\1nuYG",[])),
- <<"IEabanuYG">> = iolist_to_binary(re:replace("ab","^(a|)\\1*b","IE&\\1nuYG",[global])),
- <<"oaVSaaaabg">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1*b","o\\1VS&g",[])),
- <<"oaVSaaaabg">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1*b","o\\1VS&g",[global])),
- <<"midgkQDfLoqgoK">> = iolist_to_binary(re:replace("b","^(a|)\\1*b","midgk\\1\\1Q\\1DfLoqgoK",[])),
- <<"midgkQDfLoqgoK">> = iolist_to_binary(re:replace("b","^(a|)\\1*b","midgk\\1\\1Q\\1DfLoqgoK",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1*b","iq\\1HM&PoX",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1*b","iq\\1HM&PoX",[global])),
- <<"acb">> = iolist_to_binary(re:replace("acb","^(a|)\\1*b","pGDNJCvYBCUc&G&\\1\\1nc",[])),
- <<"acb">> = iolist_to_binary(re:replace("acb","^(a|)\\1*b","pGDNJCvYBCUc&G&\\1\\1nc",[global])),
- <<"NFaDYqrUAXIDCar">> = iolist_to_binary(re:replace("aab","^(a|)\\1+b","NFaDYqrUAXIDC\\1r",[])),
- <<"NFaDYqrUAXIDCar">> = iolist_to_binary(re:replace("aab","^(a|)\\1+b","NFaDYqrUAXIDC\\1r",[global])),
- <<"rVeVeoaaaabXIMIhaaaaboaRr">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1+b","rVeVeo&XIMIh&o\\1Rr",[])),
- <<"rVeVeoaaaabXIMIhaaaaboaRr">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1+b","rVeVeo&XIMIh&o\\1Rr",[global])),
- <<"MOSbVKbFIBNV">> = iolist_to_binary(re:replace("b","^(a|)\\1+b","MOS\\1&VKbFIBNV",[])),
- <<"MOSbVKbFIBNV">> = iolist_to_binary(re:replace("b","^(a|)\\1+b","MOS\\1&VKbFIBNV",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1+b","&X\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1+b","&X\\1",[global])),
- <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1+b","HAk\\1RB",[])),
- <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1+b","HAk\\1RB",[global])),
- <<"T">> = iolist_to_binary(re:replace("ab","^(a|)\\1?b","T",[])),
- <<"T">> = iolist_to_binary(re:replace("ab","^(a|)\\1?b","T",[global])),
- <<"NpaabpafbAIXVrowk">> = iolist_to_binary(re:replace("aab","^(a|)\\1?b","Np&p\\1fbAIXVrowk",[])),
- <<"NpaabpafbAIXVrowk">> = iolist_to_binary(re:replace("aab","^(a|)\\1?b","Np&p\\1fbAIXVrowk",[global])),
- <<"bTLqWwDhuNEDr">> = iolist_to_binary(re:replace("b","^(a|)\\1?b","&TLqWwDhuNEDr",[])),
- <<"bTLqWwDhuNEDr">> = iolist_to_binary(re:replace("b","^(a|)\\1?b","&TLqWwDhuNEDr",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1?b","k&M&WqVpmLKP",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1?b","k&M&WqVpmLKP",[global])),
- <<"acb">> = iolist_to_binary(re:replace("acb","^(a|)\\1?b","sukwIjuiB",[])),
- <<"acb">> = iolist_to_binary(re:replace("acb","^(a|)\\1?b","sukwIjuiB",[global])),
- <<"rHnDYYvSYMasyvaMyaaabqJ">> = iolist_to_binary(re:replace("aaab","^(a|)\\1{2}b","rHnDYYvSYM\\1syv\\1My&qJ",[])),
- <<"rHnDYYvSYMasyvaMyaaabqJ">> = iolist_to_binary(re:replace("aaab","^(a|)\\1{2}b","rHnDYYvSYM\\1syv\\1My&qJ",[global])),
- <<"gdeUBJebtvLObDlYQ">> = iolist_to_binary(re:replace("b","^(a|)\\1{2}b","gdeU\\1BJe&tvL\\1ObDlYQ",[])),
- <<"gdeUBJebtvLObDlYQ">> = iolist_to_binary(re:replace("b","^(a|)\\1{2}b","gdeU\\1BJe&tvL\\1ObDlYQ",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1{2}b","AVUEjXCeg&i\\1T\\1ejtKi",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1{2}b","AVUEjXCeg&i\\1T\\1ejtKi",[global])),
- <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1{2}b","E\\1YBlG",[])),
- <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1{2}b","E\\1YBlG",[global])),
- <<"aab">> = iolist_to_binary(re:replace("aab","^(a|)\\1{2}b","&Oq&\\1IcB&LT",[])),
- <<"aab">> = iolist_to_binary(re:replace("aab","^(a|)\\1{2}b","&Oq&\\1IcB&LT",[global])),
- <<"aaaab">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1{2}b","Xh",[])),
- <<"aaaab">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1{2}b","Xh",[global])),
- <<"gPaMHaaabaaabnaaOMIaVa">> = iolist_to_binary(re:replace("aaab","^(a|)\\1{2,3}b","gP\\1MH&&n\\1aOMI\\1Va",[])),
- <<"gPaMHaaabaaabnaaOMIaVa">> = iolist_to_binary(re:replace("aaab","^(a|)\\1{2,3}b","gP\\1MH&&n\\1aOMI\\1Va",[global])),
- <<"aaaabWf">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1{2,3}b","&Wf",[])),
- <<"aaaabWf">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1{2,3}b","&Wf",[global])),
- <<"KKYfigIbbfyLvtL">> = iolist_to_binary(re:replace("b","^(a|)\\1{2,3}b","KKYfigI&&fyL\\1v\\1tL",[])),
- <<"KKYfigIbbfyLvtL">> = iolist_to_binary(re:replace("b","^(a|)\\1{2,3}b","KKYfigI&&fyL\\1v\\1tL",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1{2,3}b","NFHl",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1{2,3}b","NFHl",[global])),
- <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1{2,3}b","ob\\1\\1J&ES\\1av\\1AM",[])),
- <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1{2,3}b","ob\\1\\1J&ES\\1av\\1AM",[global])),
- <<"aab">> = iolist_to_binary(re:replace("aab","^(a|)\\1{2,3}b","\\1viNfcaQTcNH&ggGt",[])),
- <<"aab">> = iolist_to_binary(re:replace("aab","^(a|)\\1{2,3}b","\\1viNfcaQTcNH&ggGt",[global])),
- <<"aaaaab">> = iolist_to_binary(re:replace("aaaaab","^(a|)\\1{2,3}b","vu",[])),
- <<"aaaaab">> = iolist_to_binary(re:replace("aaaaab","^(a|)\\1{2,3}b","vu",[global])),
- <<"aHJVskcmUR">> = iolist_to_binary(re:replace("abbbbc","ab{1,3}bc","\\1aHJVskcmUR",[])),
- <<"aHJVskcmUR">> = iolist_to_binary(re:replace("abbbbc","ab{1,3}bc","\\1aHJVskcmUR",[global])),
- <<"Rmabbbccackw">> = iolist_to_binary(re:replace("abbbc","ab{1,3}bc","Rm&cackw",[])),
- <<"Rmabbbccackw">> = iolist_to_binary(re:replace("abbbc","ab{1,3}bc","Rm&cackw",[global])),
- <<"VHGaMs">> = iolist_to_binary(re:replace("abbc","ab{1,3}bc","VHGaMs",[])),
- <<"VHGaMs">> = iolist_to_binary(re:replace("abbc","ab{1,3}bc","VHGaMs",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{1,3}bc","UM&MN\\1&vHpV\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{1,3}bc","UM&MN\\1&vHpV\\1",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","ab{1,3}bc","os&Rm\\1akB\\1pkOAH",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","ab{1,3}bc","os&Rm\\1akB\\1pkOAH",[global])),
- <<"abbbbbc">> = iolist_to_binary(re:replace("abbbbbc","ab{1,3}bc","oujXAne\\1\\1JsV&Y&I&",[])),
- <<"abbbbbc">> = iolist_to_binary(re:replace("abbbbbc","ab{1,3}bc","oujXAne\\1\\1JsV&Y&I&",[global])),
- <<"NCkLQtrack1">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)","NCkLQ\\1",[])),
- <<"NCkLQtrack1">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)","NCkLQ\\1",[global])),
- <<"track1.title:TBlah blah blahOtrack1.title:TBlah blah blahwtrack1fuQWtrack1.title:TBlah blah blahStrack1.title:TBlah blah blahkEFVKOH">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)","&O&w\\1fuQW&S&kEFVKOH",[caseless])),
- <<"track1.title:TBlah blah blahOtrack1.title:TBlah blah blahwtrack1fuQWtrack1.title:TBlah blah blahStrack1.title:TBlah blah blahkEFVKOH">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)","&O&w\\1fuQW&S&kEFVKOH",[caseless,
- global])),
- <<"VWgicEGtrack1">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[t ]+(.*)","VWgicEG\\1",[caseless])),
- <<"VWgicEGtrack1">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[t ]+(.*)","VWgicEG\\1",[caseless,
- global])),
- <<"UKrqsWXY_^abcTa">> = iolist_to_binary(re:replace("WXY_^abc","^[W-c]+$","UKr\\1\\1qs&Ta",[])),
- <<"UKrqsWXY_^abcTa">> = iolist_to_binary(re:replace("WXY_^abc","^[W-c]+$","UKr\\1\\1qs&Ta",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-c]+$","LV\\1&\\1&\\1Je&M\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-c]+$","LV\\1&\\1&\\1Je&M\\1",[global])),
- <<"wxy">> = iolist_to_binary(re:replace("wxy","^[W-c]+$","yqUKKN",[])),
- <<"wxy">> = iolist_to_binary(re:replace("wxy","^[W-c]+$","yqUKKN",[global])),
- <<"MxOWXY_^abcqjWXY_^abcWXY_^abcocGDNJgwU">> = iolist_to_binary(re:replace("WXY_^abc","^[W-c]+$","MxO&qj&&ocGDNJgwU",[caseless])),
- <<"MxOWXY_^abcqjWXY_^abcWXY_^abcocGDNJgwU">> = iolist_to_binary(re:replace("WXY_^abc","^[W-c]+$","MxO&qj&&ocGDNJgwU",[caseless,
- global])),
- <<"lgkBEwxy_^ABCC">> = iolist_to_binary(re:replace("wxy_^ABC","^[W-c]+$","\\1lgkBE&C\\1",[caseless])),
- <<"lgkBEwxy_^ABCC">> = iolist_to_binary(re:replace("wxy_^ABC","^[W-c]+$","\\1lgkBE&C\\1",[caseless,
- global])),
- <<"QSQrWXY_^abcvBpJUdCPFVxS">> = iolist_to_binary(re:replace("WXY_^abc","^[\\x3f-\\x5F]+$","QSQr&vBpJUdCP\\1F\\1VxS",[caseless])),
- <<"QSQrWXY_^abcvBpJUdCPFVxS">> = iolist_to_binary(re:replace("WXY_^abc","^[\\x3f-\\x5F]+$","QSQr&vBpJUdCP\\1F\\1VxS",[caseless,
- global])),
- <<"tgwxy_^ABChAjHBwxy_^ABC">> = iolist_to_binary(re:replace("wxy_^ABC","^[\\x3f-\\x5F]+$","tg&hAjHB&",[caseless])),
- <<"tgwxy_^ABChAjHBwxy_^ABC">> = iolist_to_binary(re:replace("wxy_^ABC","^[\\x3f-\\x5F]+$","tg&hAjHB&",[caseless,
- global])),
- <<"uyphoJSabcD">> = iolist_to_binary(re:replace("abc","^abc$","uyphoJS&D",[multiline])),
- <<"uyphoJSabcD">> = iolist_to_binary(re:replace("abc","^abc$","uyphoJS&D",[multiline,
- global])),
+ <<"oYnuqock">> = iolist_to_binary(re:replace("abc","^a b
+ c","oYnuq\\1ock",[extended])),
+ <<"oYnuqock">> = iolist_to_binary(re:replace("abc","^a b
+ c","oYnuq\\1ock",[extended,global])),
+ <<"aabixSVYFQoVAIabtuGababab">> = iolist_to_binary(re:replace("ab","^(a|)\\1*b","\\1&ixSVYFQoVAI&tuG&&&",[])),
+ <<"aabixSVYFQoVAIabtuGababab">> = iolist_to_binary(re:replace("ab","^(a|)\\1*b","\\1&ixSVYFQoVAI&tuG&&&",[global])),
+ <<"FvaaaabaIaaaab">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1*b","Fv&\\1I&",[])),
+ <<"FvaaaabaIaaaab">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1*b","Fv&\\1I&",[global])),
+ <<"bCOyfHmNbMpQpaqrGbs">> = iolist_to_binary(re:replace("b","^(a|)\\1*b","bCOyfHmN&MpQpaqrG&s",[])),
+ <<"bCOyfHmNbMpQpaqrGbs">> = iolist_to_binary(re:replace("b","^(a|)\\1*b","bCOyfHmN&MpQpaqrG&s",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1*b","Ni&\\1\\1&nB\\1Jh&&&fOjpr",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1*b","Ni&\\1\\1&nB\\1Jh&&&fOjpr",[global])),
+ <<"acb">> = iolist_to_binary(re:replace("acb","^(a|)\\1*b","w\\1GCswa&ex\\1JpP&&u",[])),
+ <<"acb">> = iolist_to_binary(re:replace("acb","^(a|)\\1*b","w\\1GCswa&ex\\1JpP&&u",[global])),
+ <<"fplaYSyrA">> = iolist_to_binary(re:replace("aab","^(a|)\\1+b","fplaYSyrA",[])),
+ <<"fplaYSyrA">> = iolist_to_binary(re:replace("aab","^(a|)\\1+b","fplaYSyrA",[global])),
+ <<"q">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1+b","q",[])),
+ <<"q">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1+b","q",[global])),
+ <<"bGdqs">> = iolist_to_binary(re:replace("b","^(a|)\\1+b","&Gdq\\1s",[])),
+ <<"bGdqs">> = iolist_to_binary(re:replace("b","^(a|)\\1+b","&Gdq\\1s",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1+b","EmUWBUOM",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1+b","EmUWBUOM",[global])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1+b","\\1",[])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1+b","\\1",[global])),
+ <<"VaaU">> = iolist_to_binary(re:replace("ab","^(a|)\\1?b","V\\1\\1U",[])),
+ <<"VaaU">> = iolist_to_binary(re:replace("ab","^(a|)\\1?b","V\\1\\1U",[global])),
+ <<"yRFaHEaabgaguAOyRdwa">> = iolist_to_binary(re:replace("aab","^(a|)\\1?b","yRF\\1HE&g\\1guAOyRdw\\1",[])),
+ <<"yRFaHEaabgaguAOyRdwa">> = iolist_to_binary(re:replace("aab","^(a|)\\1?b","yRF\\1HE&g\\1guAOyRdw\\1",[global])),
+ <<"jdes">> = iolist_to_binary(re:replace("b","^(a|)\\1?b","j\\1des",[])),
+ <<"jdes">> = iolist_to_binary(re:replace("b","^(a|)\\1?b","j\\1des",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1?b","TIrmv",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1?b","TIrmv",[global])),
+ <<"acb">> = iolist_to_binary(re:replace("acb","^(a|)\\1?b","S\\1iKv&guYQgKcq",[])),
+ <<"acb">> = iolist_to_binary(re:replace("acb","^(a|)\\1?b","S\\1iKv&guYQgKcq",[global])),
+ <<"TRaaabaaabGJaaabeeaaabreHRnfrtKb">> = iolist_to_binary(re:replace("aaab","^(a|)\\1{2}b","TR&&GJ&ee&reHRnfrtKb",[])),
+ <<"TRaaabaaabGJaaabeeaaabreHRnfrtKb">> = iolist_to_binary(re:replace("aaab","^(a|)\\1{2}b","TR&&GJ&ee&reHRnfrtKb",[global])),
+ <<"ALqjMQmcPDj">> = iolist_to_binary(re:replace("b","^(a|)\\1{2}b","ALqjMQ\\1mcPDj",[])),
+ <<"ALqjMQmcPDj">> = iolist_to_binary(re:replace("b","^(a|)\\1{2}b","ALqjMQ\\1mcPDj",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1{2}b","\\1\\1Xdd&Y\\1&e",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1{2}b","\\1\\1Xdd&Y\\1&e",[global])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1{2}b","qeS\\1gi",[])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1{2}b","qeS\\1gi",[global])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","^(a|)\\1{2}b","nwCRrci\\1RdOBbhlx",[])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","^(a|)\\1{2}b","nwCRrci\\1RdOBbhlx",[global])),
+ <<"aaaab">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1{2}b","Lg&\\1XeI\\1Nyj",[])),
+ <<"aaaab">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1{2}b","Lg&\\1XeI\\1Nyj",[global])),
+ <<"GOaaabaaag">> = iolist_to_binary(re:replace("aaab","^(a|)\\1{2,3}b","GO&\\1\\1\\1g",[])),
+ <<"GOaaabaaag">> = iolist_to_binary(re:replace("aaab","^(a|)\\1{2,3}b","GO&\\1\\1\\1g",[global])),
+ <<"lxmKaaaabaaaabaaaabeXuoa">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1{2,3}b","lxmK&&&eXuo\\1",[])),
+ <<"lxmKaaaabaaaabaaaabeXuoa">> = iolist_to_binary(re:replace("aaaab","^(a|)\\1{2,3}b","lxmK&&&eXuo\\1",[global])),
+ <<"TvbwJ">> = iolist_to_binary(re:replace("b","^(a|)\\1{2,3}b","Tv&wJ\\1",[])),
+ <<"TvbwJ">> = iolist_to_binary(re:replace("b","^(a|)\\1{2,3}b","Tv&wJ\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1{2,3}b","ab\\1bOcVb&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a|)\\1{2,3}b","ab\\1bOcVb&",[global])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1{2,3}b","WMYjIOMVqCgU\\1GVPH",[])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","^(a|)\\1{2,3}b","WMYjIOMVqCgU\\1GVPH",[global])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","^(a|)\\1{2,3}b","EjtNGCa",[])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","^(a|)\\1{2,3}b","EjtNGCa",[global])),
+ <<"aaaaab">> = iolist_to_binary(re:replace("aaaaab","^(a|)\\1{2,3}b","R\\1VC\\1vdVw",[])),
+ <<"aaaaab">> = iolist_to_binary(re:replace("aaaaab","^(a|)\\1{2,3}b","R\\1VC\\1vdVw",[global])),
+ <<"VkSvabbbbcabbbbcAabbbbcO">> = iolist_to_binary(re:replace("abbbbc","ab{1,3}bc","Vk\\1Sv&&A&O",[])),
+ <<"VkSvabbbbcabbbbcAabbbbcO">> = iolist_to_binary(re:replace("abbbbc","ab{1,3}bc","Vk\\1Sv&&A&O",[global])),
+ <<"EYabbbcWLBYcabbbcPiCg">> = iolist_to_binary(re:replace("abbbc","ab{1,3}bc","EY&WLBYc&PiCg",[])),
+ <<"EYabbbcWLBYcabbbcPiCg">> = iolist_to_binary(re:replace("abbbc","ab{1,3}bc","EY&WLBYc&PiCg",[global])),
+ <<"gGY">> = iolist_to_binary(re:replace("abbc","ab{1,3}bc","gG\\1Y",[])),
+ <<"gGY">> = iolist_to_binary(re:replace("abbc","ab{1,3}bc","gG\\1Y",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{1,3}bc","TXERvv\\1HEnguTRN",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{1,3}bc","TXERvv\\1HEnguTRN",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","ab{1,3}bc","jQE&DJFGc\\1\\1b\\1c\\1&&XBX",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","ab{1,3}bc","jQE&DJFGc\\1\\1b\\1c\\1&&XBX",[global])),
+ <<"abbbbbc">> = iolist_to_binary(re:replace("abbbbbc","ab{1,3}bc","WQWQvwRSQle&",[])),
+ <<"abbbbbc">> = iolist_to_binary(re:replace("abbbbbc","ab{1,3}bc","WQWQvwRSQle&",[global])),
+ <<"BUftrack1BsOeN">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)","BUf\\1BsOeN",[])),
+ <<"BUftrack1BsOeN">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)","BUf\\1BsOeN",[global])),
+ <<"NpupceROgJW">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)","NpupceROgJW",[caseless])),
+ <<"NpupceROgJW">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[T ]+(.*)","NpupceROgJW",[caseless,
+ global])),
+ <<"DxJtrack1rCNtrack1.title:TBlah blah blahKXmSNktrack1Strack1">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[t ]+(.*)","DxJ\\1rCN&KXmSNk\\1S\\1",[caseless])),
+ <<"DxJtrack1rCNtrack1.title:TBlah blah blahKXmSNktrack1Strack1">> = iolist_to_binary(re:replace("track1.title:TBlah blah blah","([^.]*)\\.([^:]*):[t ]+(.*)","DxJ\\1rCN&KXmSNk\\1S\\1",[caseless,
+ global])),
+ <<"HHLLlESKV">> = iolist_to_binary(re:replace("WXY_^abc","^[W-c]+$","HHLLlESKV",[])),
+ <<"HHLLlESKV">> = iolist_to_binary(re:replace("WXY_^abc","^[W-c]+$","HHLLlESKV",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-c]+$","wLJlupvA\\1\\1kNnalxEwVh",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-c]+$","wLJlupvA\\1\\1kNnalxEwVh",[global])),
+ <<"wxy">> = iolist_to_binary(re:replace("wxy","^[W-c]+$","JvOAObw\\1pP\\1",[])),
+ <<"wxy">> = iolist_to_binary(re:replace("wxy","^[W-c]+$","JvOAObw\\1pP\\1",[global])),
+ <<"gwuwm">> = iolist_to_binary(re:replace("WXY_^abc","^[W-c]+$","gwuwm",[caseless])),
+ <<"gwuwm">> = iolist_to_binary(re:replace("WXY_^abc","^[W-c]+$","gwuwm",[caseless,
+ global])),
+ <<"wxy_^ABCxkqVcwxy_^ABCaE">> = iolist_to_binary(re:replace("wxy_^ABC","^[W-c]+$","&xk\\1qVc&aE",[caseless])),
+ <<"wxy_^ABCxkqVcwxy_^ABCaE">> = iolist_to_binary(re:replace("wxy_^ABC","^[W-c]+$","&xk\\1qVc&aE",[caseless,
+ global])),
+ <<"WWXY_^abcOgKgjfsLWNy">> = iolist_to_binary(re:replace("WXY_^abc","^[\\x3f-\\x5F]+$","\\1W\\1&Og\\1Kgj\\1fsLWNy",[caseless])),
+ <<"WWXY_^abcOgKgjfsLWNy">> = iolist_to_binary(re:replace("WXY_^abc","^[\\x3f-\\x5F]+$","\\1W\\1&Og\\1Kgj\\1fsLWNy",[caseless,
+ global])),
+ <<"egunTysOf">> = iolist_to_binary(re:replace("wxy_^ABC","^[\\x3f-\\x5F]+$","egunT\\1\\1y\\1sOf",[caseless])),
+ <<"egunTysOf">> = iolist_to_binary(re:replace("wxy_^ABC","^[\\x3f-\\x5F]+$","egunT\\1\\1y\\1sOf",[caseless,
+ global])),
+ <<"CPTKOdIA">> = iolist_to_binary(re:replace("abc","^abc$","CPTKOdI\\1A",[multiline])),
+ <<"CPTKOdIA">> = iolist_to_binary(re:replace("abc","^abc$","CPTKOdI\\1A",[multiline,
+ global])),
<<"qqq
-wupoAabcauHHyGGVeUwVabc">> = iolist_to_binary(re:replace("qqq
-abc","^abc$","wupoA&au\\1HHyGGVeUwV&",[multiline])),
+bQdPqCFxabcndDcFfikPvc">> = iolist_to_binary(re:replace("qqq
+abc","^abc$","bQdPqCFx&ndDcFfikPvc",[multiline])),
<<"qqq
-wupoAabcauHHyGGVeUwVabc">> = iolist_to_binary(re:replace("qqq
-abc","^abc$","wupoA&au\\1HHyGGVeUwV&",[multiline,global])),
- <<"gfEviFcl
+bQdPqCFxabcndDcFfikPvc">> = iolist_to_binary(re:replace("qqq
+abc","^abc$","bQdPqCFx&ndDcFfikPvc",[multiline,global])),
+ <<"IhabcKXoLYabce
zzz">> = iolist_to_binary(re:replace("abc
-zzz","^abc$","gf\\1EviFcl",[multiline])),
- <<"gfEviFcl
+zzz","^abc$","Ih&KX\\1oLY&e",[multiline])),
+ <<"IhabcKXoLYabce
zzz">> = iolist_to_binary(re:replace("abc
-zzz","^abc$","gf\\1EviFcl",[multiline,global])),
+zzz","^abc$","Ih&KX\\1oLY&e",[multiline,global])),
<<"qqq
-jwoabcabcBysLOHCR
+v
zzz">> = iolist_to_binary(re:replace("qqq
abc
-zzz","^abc$","jwo&&BysLOHC\\1R",[multiline])),
+zzz","^abc$","v",[multiline])),
<<"qqq
-jwoabcabcBysLOHCR
+v
zzz">> = iolist_to_binary(re:replace("qqq
abc
-zzz","^abc$","jwo&&BysLOHC\\1R",[multiline,global])),
- <<"fPMabcFHNJXabcJChQyabcU">> = iolist_to_binary(re:replace("abc","^abc$","fPM&FHNJX&JCh\\1Qy&U",[])),
- <<"fPMabcFHNJXabcJChQyabcU">> = iolist_to_binary(re:replace("abc","^abc$","fPM&FHNJX&JCh\\1Qy&U",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","&\\1&R\\1oixQQMrImGsd&",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","&\\1&R\\1oixQQMrImGsd&",[global])),
+zzz","^abc$","v",[multiline,global])),
+ <<"rsDabcabcSRpKNvKVJ">> = iolist_to_binary(re:replace("abc","^abc$","rsD&&SRpKNvKVJ",[])),
+ <<"rsDabcabcSRpKNvKVJ">> = iolist_to_binary(re:replace("abc","^abc$","rsD&&SRpKNvKVJ",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","yVq",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","yVq",[global])),
<<"qqq
abc">> = iolist_to_binary(re:replace("qqq
-abc","^abc$","rAUAF&gmNHyoIX\\1ymqk",[])),
+abc","^abc$","snXy",[])),
<<"qqq
abc">> = iolist_to_binary(re:replace("qqq
-abc","^abc$","rAUAF&gmNHyoIX\\1ymqk",[global])),
+abc","^abc$","snXy",[global])),
<<"abc
zzz">> = iolist_to_binary(re:replace("abc
-zzz","^abc$","&&qL\\1YUdNN\\1\\1\\1O\\1",[])),
+zzz","^abc$","&f\\1dlb\\1EAWc&",[])),
<<"abc
zzz">> = iolist_to_binary(re:replace("abc
-zzz","^abc$","&&qL\\1YUdNN\\1\\1\\1O\\1",[global])),
+zzz","^abc$","&f\\1dlb\\1EAWc&",[global])),
<<"qqq
abc
zzz">> = iolist_to_binary(re:replace("qqq
abc
-zzz","^abc$","u",[])),
+zzz","^abc$","cSNFGiC",[])),
<<"qqq
abc
zzz">> = iolist_to_binary(re:replace("qqq
abc
-zzz","^abc$","u",[global])),
- <<"abcRqIabcuWabcabcFN">> = iolist_to_binary(re:replace("abc","\\Aabc\\Z","&\\1RqI&uW&&F\\1N",[multiline])),
- <<"abcRqIabcuWabcabcFN">> = iolist_to_binary(re:replace("abc","\\Aabc\\Z","&\\1RqI&uW&&F\\1N",[multiline,
- global])),
- <<"abciwrfICONabcYabc">> = iolist_to_binary(re:replace("abc","\\Aabc\\Z","&iwrf\\1ICON&\\1Y&\\1\\1",[multiline])),
- <<"abciwrfICONabcYabc">> = iolist_to_binary(re:replace("abc","\\Aabc\\Z","&iwrf\\1ICON&\\1Y&\\1\\1",[multiline,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Aabc\\Z","RsIorq&kLBrJVt&Dq",[multiline])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Aabc\\Z","RsIorq&kLBrJVt&Dq",[multiline,
- global])),
+zzz","^abc$","cSNFGiC",[global])),
+ <<"lCoBH">> = iolist_to_binary(re:replace("abc","\\Aabc\\Z","lC\\1o\\1BH\\1",[multiline])),
+ <<"lCoBH">> = iolist_to_binary(re:replace("abc","\\Aabc\\Z","lC\\1o\\1BH\\1",[multiline,
+ global])),
+ <<"JVdoPUmabcxTP">> = iolist_to_binary(re:replace("abc","\\Aabc\\Z","JVd\\1oP\\1Um&xTP",[multiline])),
+ <<"JVdoPUmabcxTP">> = iolist_to_binary(re:replace("abc","\\Aabc\\Z","JVd\\1oP\\1Um&xTP",[multiline,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Aabc\\Z","cEqLBiFmo&YRu&QCAvtf",[multiline])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Aabc\\Z","cEqLBiFmo&YRu&QCAvtf",[multiline,
+ global])),
<<"qqq
abc">> = iolist_to_binary(re:replace("qqq
-abc","\\Aabc\\Z","bByD\\1yC\\1hlr",[multiline])),
+abc","\\Aabc\\Z","kc&H\\1Pd\\1PDS",[multiline])),
<<"qqq
abc">> = iolist_to_binary(re:replace("qqq
-abc","\\Aabc\\Z","bByD\\1yC\\1hlr",[multiline,global])),
+abc","\\Aabc\\Z","kc&H\\1Pd\\1PDS",[multiline,global])),
<<"abc
zzz">> = iolist_to_binary(re:replace("abc
-zzz","\\Aabc\\Z","AuwHER\\1cj\\1XMx\\1jBcr&u",[multiline])),
+zzz","\\Aabc\\Z","XQVTFMq",[multiline])),
<<"abc
zzz">> = iolist_to_binary(re:replace("abc
-zzz","\\Aabc\\Z","AuwHER\\1cj\\1XMx\\1jBcr&u",[multiline,
- global])),
+zzz","\\Aabc\\Z","XQVTFMq",[multiline,global])),
<<"qqq
abc
zzz">> = iolist_to_binary(re:replace("qqq
abc
-zzz","\\Aabc\\Z","kiYxAVR&jFLIO&t\\1to&",[multiline])),
+zzz","\\Aabc\\Z","J\\1fh",[multiline])),
<<"qqq
abc
zzz">> = iolist_to_binary(re:replace("qqq
abc
-zzz","\\Aabc\\Z","kiYxAVR&jFLIO&t\\1to&",[multiline,global])),
- <<"DGWRrfDctbIpuofabc
-defabc
-defHPf">> = iolist_to_binary(re:replace("abc
-def","\\A(.)*\\Z","DGWRr\\1DctbIpuo\\1&&HPf",[dotall])),
- <<"DGWRrfDctbIpuofabc
-defabc
-defHPf">> = iolist_to_binary(re:replace("abc
-def","\\A(.)*\\Z","DGWRr\\1DctbIpuo\\1&&HPf",[dotall,global])),
- <<"XsHV*** FailerstLRmsk*** FailersMPy">> = iolist_to_binary(re:replace("*** Failers","\\A(.)*\\Z","XsHV&tLRm\\1k&MPy",[multiline])),
- <<"XsHV*** FailerstLRmsk*** FailersMPy">> = iolist_to_binary(re:replace("*** Failers","\\A(.)*\\Z","XsHV&tLRm\\1k&MPy",[multiline,
- global])),
+zzz","\\Aabc\\Z","J\\1fh",[multiline,global])),
+ <<"o">> = iolist_to_binary(re:replace("abc
+def","\\A(.)*\\Z","o",[dotall])),
+ <<"o">> = iolist_to_binary(re:replace("abc
+def","\\A(.)*\\Z","o",[dotall,global])),
+ <<"*** FailersssD">> = iolist_to_binary(re:replace("*** Failers","\\A(.)*\\Z","&\\1\\1D",[multiline])),
+ <<"*** FailersssD">> = iolist_to_binary(re:replace("*** Failers","\\A(.)*\\Z","&\\1\\1D",[multiline,
+ global])),
<<"abc
def">> = iolist_to_binary(re:replace("abc
-def","\\A(.)*\\Z","v",[multiline])),
+def","\\A(.)*\\Z","&FyyfdbkSw",[multiline])),
<<"abc
def">> = iolist_to_binary(re:replace("abc
-def","\\A(.)*\\Z","v",[multiline,global])),
- <<"RmbbMhEEp::c">> = iolist_to_binary(re:replace("b::c","(?:b)|(?::+)","Rmb&MhEEp",[])),
- <<"RmbbMhEEpRmb::MhEEpc">> = iolist_to_binary(re:replace("b::c","(?:b)|(?::+)","Rmb&MhEEp",[global])),
- <<"cYDT::rLb">> = iolist_to_binary(re:replace("c::b","(?:b)|(?::+)","YDT\\1&rL",[])),
- <<"cYDT::rLYDTbrL">> = iolist_to_binary(re:replace("c::b","(?:b)|(?::+)","YDT\\1&rL",[global])),
- <<"ehR">> = iolist_to_binary(re:replace("az-","[-az]+","ehR",[])),
- <<"ehR">> = iolist_to_binary(re:replace("az-","[-az]+","ehR",[global])),
- <<"*** FsaiTaeaWvwilers">> = iolist_to_binary(re:replace("*** Failers","[-az]+","s&\\1iT\\1&eaWvw",[])),
- <<"*** FsaiTaeaWvwilers">> = iolist_to_binary(re:replace("*** Failers","[-az]+","s&\\1iT\\1&eaWvw",[global])),
- <<"b">> = iolist_to_binary(re:replace("b","[-az]+","mdHw",[])),
- <<"b">> = iolist_to_binary(re:replace("b","[-az]+","mdHw",[global])),
+def","\\A(.)*\\Z","&FyyfdbkSw",[multiline,global])),
+ <<"JbDSWbbCxetpbHwOmBy::c">> = iolist_to_binary(re:replace("b::c","(?:b)|(?::+)","J&DSW&bCxetp&HwOmBy",[])),
+ <<"JbDSWbbCxetpbHwOmByJ::DSW::bCxetp::HwOmByc">> = iolist_to_binary(re:replace("b::c","(?:b)|(?::+)","J&DSW&bCxetp&HwOmBy",[global])),
+ <<"cVMqgmhvamVbb">> = iolist_to_binary(re:replace("c::b","(?:b)|(?::+)","VMqgmh\\1vamVb",[])),
+ <<"cVMqgmhvamVbVMqgmhvamVb">> = iolist_to_binary(re:replace("c::b","(?:b)|(?::+)","VMqgmh\\1vamVb",[global])),
+ <<"az-Oaz-Taz-rDxaz-rN">> = iolist_to_binary(re:replace("az-","[-az]+","&O&\\1T&rDx&r\\1N",[])),
+ <<"az-Oaz-Taz-rDxaz-rN">> = iolist_to_binary(re:replace("az-","[-az]+","&O&\\1T&rDx&r\\1N",[global])),
+ <<"*** FEaJakaDTgMFYQIVaTilers">> = iolist_to_binary(re:replace("*** Failers","[-az]+","\\1E&JakaDTgMFY\\1QIV&T",[])),
+ <<"*** FEaJakaDTgMFYQIVaTilers">> = iolist_to_binary(re:replace("*** Failers","[-az]+","\\1E&JakaDTgMFY\\1QIV&T",[global])),
+ <<"b">> = iolist_to_binary(re:replace("b","[-az]+","okQx\\1K\\1KgjAExrmhx",[])),
+ <<"b">> = iolist_to_binary(re:replace("b","[-az]+","okQx\\1K\\1KgjAExrmhx",[global])),
ok.
run5() ->
- <<"EDUoLiFaCJDko">> = iolist_to_binary(re:replace("za-","[az-]+","EDUoL\\1i\\1FaCJ\\1Dko",[])),
- <<"EDUoLiFaCJDko">> = iolist_to_binary(re:replace("za-","[az-]+","EDUoL\\1i\\1FaCJ\\1Dko",[global])),
- <<"*** FapAfSayQoaaFksilers">> = iolist_to_binary(re:replace("*** Failers","[az-]+","&\\1pAfS&yQo&&Fks\\1",[])),
- <<"*** FapAfSayQoaaFksilers">> = iolist_to_binary(re:replace("*** Failers","[az-]+","&\\1pAfS&yQo&&Fks\\1",[global])),
- <<"b">> = iolist_to_binary(re:replace("b","[az-]+","\\1LDAG\\1JLRNo",[])),
- <<"b">> = iolist_to_binary(re:replace("b","[az-]+","\\1LDAG\\1JLRNo",[global])),
- <<"">> = iolist_to_binary(re:replace("a-z","[a\\-z]+","\\1",[])),
- <<"">> = iolist_to_binary(re:replace("a-z","[a\\-z]+","\\1",[global])),
- <<"*** FvVgilers">> = iolist_to_binary(re:replace("*** Failers","[a\\-z]+","vVg",[])),
- <<"*** FvVgilers">> = iolist_to_binary(re:replace("*** Failers","[a\\-z]+","vVg",[global])),
- <<"b">> = iolist_to_binary(re:replace("b","[a\\-z]+","bfgfonbXIj",[])),
- <<"b">> = iolist_to_binary(re:replace("b","[a\\-z]+","bfgfonbXIj",[global])),
- <<"QYKd">> = iolist_to_binary(re:replace("abcdxyz","[a-z]+","Q\\1\\1Y\\1Kd\\1",[])),
- <<"QYKd">> = iolist_to_binary(re:replace("abcdxyz","[a-z]+","Q\\1\\1Y\\1Kd\\1",[global])),
- <<"UYmP12-3412-34">> = iolist_to_binary(re:replace("12-34","[\\d-]+","U\\1\\1YmP&&",[])),
- <<"UYmP12-3412-34">> = iolist_to_binary(re:replace("12-34","[\\d-]+","U\\1\\1YmP&&",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\d-]+","JWPgf\\1Eng\\1E\\1n",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\d-]+","JWPgf\\1Eng\\1E\\1n",[global])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","[\\d-]+","sRhgqdg&E",[])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","[\\d-]+","sRhgqdg&E",[global])),
- <<"efmQUhkdSK12-34zR12-34z12-34zTb">> = iolist_to_binary(re:replace("12-34z","[\\d-z]+","ef\\1mQUh\\1kdSK&R&&Tb",[])),
- <<"efmQUhkdSK12-34zR12-34z12-34zTb">> = iolist_to_binary(re:replace("12-34z","[\\d-z]+","ef\\1mQUh\\1kdSK&R&&Tb",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\d-z]+","PJaMxeM",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\d-z]+","PJaMxeM",[global])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","[\\d-z]+","My\\1Kbyr&\\1",[])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","[\\d-z]+","My\\1Kbyr&\\1",[global])),
- <<"QpJFT\\cphXBPQ ">> = iolist_to_binary(re:replace("\\ ","\\x5c","QpJF\\1T&cphXBPQ\\1",[])),
- <<"QpJFT\\cphXBPQ ">> = iolist_to_binary(re:replace("\\ ","\\x5c","QpJF\\1T&cphXBPQ\\1",[global])),
- <<"theHwjgWjRYr ZofH ZkBtIoo">> = iolist_to_binary(re:replace("the Zoo","\\x20Z","HwjgWjRYr&\\1ofH&kBtI",[])),
- <<"theHwjgWjRYr ZofH ZkBtIoo">> = iolist_to_binary(re:replace("the Zoo","\\x20Z","HwjgWjRYr&\\1ofH&kBtI",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\x20Z","&STbBPwwLA",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\x20Z","&STbBPwwLA",[global])),
- <<"Zulu">> = iolist_to_binary(re:replace("Zulu","\\x20Z","buG&ki&QEXQhj\\1\\1W",[])),
- <<"Zulu">> = iolist_to_binary(re:replace("Zulu","\\x20Z","buG&ki&QEXQhj\\1\\1W",[global])),
- <<"bhNKmH">> = iolist_to_binary(re:replace("abcabc","(abc)\\1","bhNKmH",[caseless])),
- <<"bhNKmH">> = iolist_to_binary(re:replace("abcabc","(abc)\\1","bhNKmH",[caseless,
- global])),
- <<"jdFUGABCabcjABCabc">> = iolist_to_binary(re:replace("ABCabc","(abc)\\1","jdFUG&j&",[caseless])),
- <<"jdFUGABCabcjABCabc">> = iolist_to_binary(re:replace("ABCabc","(abc)\\1","jdFUG&j&",[caseless,
- global])),
- <<"YSEabcsfRWrD">> = iolist_to_binary(re:replace("abcABC","(abc)\\1","YSE\\1sfRWrD",[caseless])),
- <<"YSEabcsfRWrD">> = iolist_to_binary(re:replace("abcABC","(abc)\\1","YSE\\1sfRWrD",[caseless,
- global])),
- <<"CbQoKIFQqeNT">> = iolist_to_binary(re:replace("ab{3cd","ab{3cd","CbQoKIFQqeNT\\1",[])),
- <<"CbQoKIFQqeNT">> = iolist_to_binary(re:replace("ab{3cd","ab{3cd","CbQoKIFQqeNT\\1",[global])),
- <<"rhgUEyXbklwXmp">> = iolist_to_binary(re:replace("ab{3,cd","ab{3,cd","rhgUEyXbk\\1lwXmp",[])),
- <<"rhgUEyXbklwXmp">> = iolist_to_binary(re:replace("ab{3,cd","ab{3,cd","rhgUEyXbk\\1lwXmp",[global])),
- <<"Xlab{3,4a}cdcbaPbaKyKQGBb">> = iolist_to_binary(re:replace("ab{3,4a}cd","ab{3,4a}cd","Xl&cbaPbaKyKQG\\1Bb",[])),
- <<"Xlab{3,4a}cdcbaPbaKyKQGBb">> = iolist_to_binary(re:replace("ab{3,4a}cd","ab{3,4a}cd","Xl&cbaPbaKyKQG\\1Bb",[global])),
- <<"bSQWjrSvge">> = iolist_to_binary(re:replace("{4,5a}bc","{4,5a}bc","b\\1SQWjr\\1\\1Svge",[])),
- <<"bSQWjrSvge">> = iolist_to_binary(re:replace("{4,5a}bc","{4,5a}bc","b\\1SQWjr\\1\\1Svge",[global])),
- <<"SLxoL">> = iolist_to_binary(re:replace("abc","abc$","SLxoL",[])),
- <<"SLxoL">> = iolist_to_binary(re:replace("abc","abc$","SLxoL",[global])),
- <<"RJabcnabcqnisabctgJA">> = iolist_to_binary(re:replace("abc","abc$","RJ&n&qnis&tgJA",[])),
- <<"RJabcnabcqnisabctgJA">> = iolist_to_binary(re:replace("abc","abc$","RJ&n&qnis&tgJA",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc$","cEO&P&qRklP&Nlb\\1H\\1K",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc$","cEO&P&qRklP&Nlb\\1H\\1K",[global])),
+ <<"BUiIgkpFguybl">> = iolist_to_binary(re:replace("za-","[az-]+","BU\\1iIgkpFguybl",[])),
+ <<"BUiIgkpFguybl">> = iolist_to_binary(re:replace("za-","[az-]+","BU\\1iIgkpFguybl",[global])),
+ <<"*** FVSpIRyVilers">> = iolist_to_binary(re:replace("*** Failers","[az-]+","VSpIRyV",[])),
+ <<"*** FVSpIRyVilers">> = iolist_to_binary(re:replace("*** Failers","[az-]+","VSpIRyV",[global])),
+ <<"b">> = iolist_to_binary(re:replace("b","[az-]+","\\1rfMIWIp\\1eA\\1BK",[])),
+ <<"b">> = iolist_to_binary(re:replace("b","[az-]+","\\1rfMIWIp\\1eA\\1BK",[global])),
+ <<"fuJua">> = iolist_to_binary(re:replace("a-z","[a\\-z]+","fuJua",[])),
+ <<"fuJua">> = iolist_to_binary(re:replace("a-z","[a\\-z]+","fuJua",[global])),
+ <<"*** Fwpjilers">> = iolist_to_binary(re:replace("*** Failers","[a\\-z]+","wpj",[])),
+ <<"*** Fwpjilers">> = iolist_to_binary(re:replace("*** Failers","[a\\-z]+","wpj",[global])),
+ <<"b">> = iolist_to_binary(re:replace("b","[a\\-z]+","nf&cDP\\1\\1Gu\\1b\\1xqHex",[])),
+ <<"b">> = iolist_to_binary(re:replace("b","[a\\-z]+","nf&cDP\\1\\1Gu\\1b\\1xqHex",[global])),
+ <<"HabcdxyzdykWGVxyCbA">> = iolist_to_binary(re:replace("abcdxyz","[a-z]+","H&dykWGVx\\1yC\\1\\1b\\1A",[])),
+ <<"HabcdxyzdykWGVxyCbA">> = iolist_to_binary(re:replace("abcdxyz","[a-z]+","H&dykWGVx\\1yC\\1\\1b\\1A",[global])),
+ <<"Ge12-34A12-34s12-34wEDOs12-34a12-34">> = iolist_to_binary(re:replace("12-34","[\\d-]+","Ge&A&s&wED\\1Os&\\1a\\1&",[])),
+ <<"Ge12-34A12-34s12-34wEDOs12-34a12-34">> = iolist_to_binary(re:replace("12-34","[\\d-]+","Ge&A&s&wED\\1Os&\\1a\\1&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\d-]+","\\1GK&npQ",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\d-]+","\\1GK&npQ",[global])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","[\\d-]+","&&IDTvQkHC\\1klFHnC\\1",[])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","[\\d-]+","&&IDTvQkHC\\1klFHnC\\1",[global])),
+ <<"XbYl12-34z12-34zDmCQVrbP">> = iolist_to_binary(re:replace("12-34z","[\\d-z]+","X\\1bYl&&Dm\\1CQVr\\1bP",[])),
+ <<"XbYl12-34z12-34zDmCQVrbP">> = iolist_to_binary(re:replace("12-34z","[\\d-z]+","X\\1bYl&&Dm\\1CQVr\\1bP",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\d-z]+","PTn&XmiYqAKkS&BW&&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\d-z]+","PTn&XmiYqAKkS&BW&&",[global])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","[\\d-z]+","WReIgpFjW&A",[])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","[\\d-z]+","WReIgpFjW&A",[global])),
+ <<"VYdXtmOgjmuYAiVjA\\ ">> = iolist_to_binary(re:replace("\\ ","\\x5c","VYdXtmOgjmuYAiVjA&",[])),
+ <<"VYdXtmOgjmuYAiVjA\\ ">> = iolist_to_binary(re:replace("\\ ","\\x5c","VYdXtmOgjmuYAiVjA&",[global])),
+ <<"theiljDu ZIwQuwEoo">> = iolist_to_binary(re:replace("the Zoo","\\x20Z","iljDu&Iw\\1Q\\1uwE\\1",[])),
+ <<"theiljDu ZIwQuwEoo">> = iolist_to_binary(re:replace("the Zoo","\\x20Z","iljDu&Iw\\1Q\\1uwE\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\x20Z","\\1ojkRRJFT\\1hV\\1xv",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\x20Z","\\1ojkRRJFT\\1hV\\1xv",[global])),
+ <<"Zulu">> = iolist_to_binary(re:replace("Zulu","\\x20Z","uaSyVYwn",[])),
+ <<"Zulu">> = iolist_to_binary(re:replace("Zulu","\\x20Z","uaSyVYwn",[global])),
+ <<"h">> = iolist_to_binary(re:replace("abcabc","(abc)\\1","h",[caseless])),
+ <<"h">> = iolist_to_binary(re:replace("abcabc","(abc)\\1","h",[caseless,
+ global])),
+ <<"yvNMtIABClHrnq">> = iolist_to_binary(re:replace("ABCabc","(abc)\\1","yvNMtI\\1lHrnq",[caseless])),
+ <<"yvNMtIABClHrnq">> = iolist_to_binary(re:replace("ABCabc","(abc)\\1","yvNMtI\\1lHrnq",[caseless,
+ global])),
+ <<"TVabcABCGmabcJabcABCKIEp">> = iolist_to_binary(re:replace("abcABC","(abc)\\1","TV&Gm\\1J&KIEp",[caseless])),
+ <<"TVabcABCGmabcJabcABCKIEp">> = iolist_to_binary(re:replace("abcABC","(abc)\\1","TV&Gm\\1J&KIEp",[caseless,
+ global])),
+ <<"nuHYndp">> = iolist_to_binary(re:replace("ab{3cd","ab{3cd","nuHYndp",[])),
+ <<"nuHYndp">> = iolist_to_binary(re:replace("ab{3cd","ab{3cd","nuHYndp",[global])),
+ <<"yab{3,cdohtmab{3,cdhlKJyab{3,cdx">> = iolist_to_binary(re:replace("ab{3,cd","ab{3,cd","y&ohtm&\\1hlKJy&x",[])),
+ <<"yab{3,cdohtmab{3,cdhlKJyab{3,cdx">> = iolist_to_binary(re:replace("ab{3,cd","ab{3,cd","y&ohtm&\\1hlKJy&x",[global])),
+ <<"EmVUOVQKbyOvWq">> = iolist_to_binary(re:replace("ab{3,4a}cd","ab{3,4a}cd","EmV\\1UO\\1VQKbyO\\1vW\\1q",[])),
+ <<"EmVUOVQKbyOvWq">> = iolist_to_binary(re:replace("ab{3,4a}cd","ab{3,4a}cd","EmV\\1UO\\1VQKbyO\\1vW\\1q",[global])),
+ <<"DsOhHFoWiLok{4,5a}bcVgG">> = iolist_to_binary(re:replace("{4,5a}bc","{4,5a}bc","DsOhH\\1FoWiLok&V\\1gG",[])),
+ <<"DsOhHFoWiLok{4,5a}bcVgG">> = iolist_to_binary(re:replace("{4,5a}bc","{4,5a}bc","DsOhH\\1FoWiLok&V\\1gG",[global])),
+ <<"iWchabcX">> = iolist_to_binary(re:replace("abc","abc$","iW\\1ch&X",[])),
+ <<"iWchabcX">> = iolist_to_binary(re:replace("abc","abc$","iW\\1ch&X",[global])),
+ <<"plBoHLBabcb">> = iolist_to_binary(re:replace("abc","abc$","plBoHLB&b",[])),
+ <<"plBoHLBabcb">> = iolist_to_binary(re:replace("abc","abc$","plBoHLB&b",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc$","EM",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc$","EM",[global])),
<<"abc
def">> = iolist_to_binary(re:replace("abc
-def","abc$","h&&nb\\1&NBSkhYb",[])),
+def","abc$","\\1aguwNOw&Q&p&",[])),
<<"abc
def">> = iolist_to_binary(re:replace("abc
-def","abc$","h&&nb\\1&NBSkhYb",[global])),
- <<"trlaTa">> = iolist_to_binary(re:replace("abcS","(abc)\\123","trlaTa",[])),
- <<"trlaTa">> = iolist_to_binary(re:replace("abcS","(abc)\\123","trlaTa",[global])),
- <<"Oabc“MWabcjRDvJhyeF">> = iolist_to_binary(re:replace("abc“","(abc)\\223","O&MW\\1jRDvJhyeF",[])),
- <<"Oabc“MWabcjRDvJhyeF">> = iolist_to_binary(re:replace("abc“","(abc)\\223","O&MW\\1jRDvJhyeF",[global])),
- <<"uLBUEpabcÓabcjn">> = iolist_to_binary(re:replace("abcÓ","(abc)\\323","uLBUEp&\\1jn",[])),
- <<"uLBUEpabcÓabcjn">> = iolist_to_binary(re:replace("abcÓ","(abc)\\323","uLBUEp&\\1jn",[global])),
- <<"Pi">> = iolist_to_binary(re:replace("abc@","(abc)\\100","Pi",[])),
- <<"Pi">> = iolist_to_binary(re:replace("abc@","(abc)\\100","Pi",[global])),
- <<"NLS">> = iolist_to_binary(re:replace("abc@","(abc)\\100","NLS",[])),
- <<"NLS">> = iolist_to_binary(re:replace("abc@","(abc)\\100","NLS",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","gshb&NCwCI&\\1&O\\1Y&OU",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","gshb&NCwCI&\\1&O\\1Y&OU",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","wfQfG",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","wfQfG",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","nlTLMMuUL\\1dek",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","nlTLMMuUL\\1dek",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","VP\\1&nVqym",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","VP\\1&nVqym",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","YmKMMo",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","YmKMMo",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","POFFExkEtjS",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","POFFExkEtjS",[global])),
- <<"abc81">> = iolist_to_binary(re:replace("abc81","abc\\81","FLXryNI\\1vKW\\1l",[])),
- <<"abc81">> = iolist_to_binary(re:replace("abc81","abc\\81","FLXryNI\\1vKW\\1l",[global])),
- <<"abc81">> = iolist_to_binary(re:replace("abc81","abc\\81","xwedFGU&&joLFV",[])),
- <<"abc81">> = iolist_to_binary(re:replace("abc81","abc\\81","xwedFGU&&joLFV",[global])),
- <<"abc91">> = iolist_to_binary(re:replace("abc91","abc\\91","QiTym",[])),
- <<"abc91">> = iolist_to_binary(re:replace("abc91","abc\\91","QiTym",[global])),
- <<"abc91">> = iolist_to_binary(re:replace("abc91","abc\\91","r",[])),
- <<"abc91">> = iolist_to_binary(re:replace("abc91","abc\\91","r",[global])),
+def","abc$","\\1aguwNOw&Q&p&",[global])),
+ <<"abcSuqabcSwabcabcSabcsxWGOk">> = iolist_to_binary(re:replace("abcS","(abc)\\123","&uq&w\\1&\\1sxWGOk",[])),
+ <<"abcSuqabcSwabcabcSabcsxWGOk">> = iolist_to_binary(re:replace("abcS","(abc)\\123","&uq&w\\1&\\1sxWGOk",[global])),
+ <<"dMwabc“Xqyabc“abc“i">> = iolist_to_binary(re:replace("abc“","(abc)\\223","dMw&Xqy&&i",[])),
+ <<"dMwabc“Xqyabc“abc“i">> = iolist_to_binary(re:replace("abc“","(abc)\\223","dMw&Xqy&&i",[global])),
+ <<"MiqonlGabcÓYdXabcf">> = iolist_to_binary(re:replace("abcÓ","(abc)\\323","MiqonlG&YdX\\1f",[])),
+ <<"MiqonlGabcÓYdXabcf">> = iolist_to_binary(re:replace("abcÓ","(abc)\\323","MiqonlG&YdX\\1f",[global])),
+ <<"mTlabc@bdhBATwW">> = iolist_to_binary(re:replace("abc@","(abc)\\100","mTl&bdhBATwW",[])),
+ <<"mTlabc@bdhBATwW">> = iolist_to_binary(re:replace("abc@","(abc)\\100","mTl&bdhBATwW",[global])),
+ <<"QabcRSbUabc@Rabc@abc@fabckabcWabc">> = iolist_to_binary(re:replace("abc@","(abc)\\100","Q\\1RSbU&R&&f\\1k\\1W\\1",[])),
+ <<"QabcRSbUabc@Rabc@abc@fabckabcWabc">> = iolist_to_binary(re:replace("abc@","(abc)\\100","Q\\1RSbU&R&&f\\1k\\1W\\1",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","LCsN",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","LCsN",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","cotASR\\1IJoJ\\1r\\1k",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","cotASR\\1IJoJ\\1r\\1k",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","&",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","&",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","gUfvqdMO&FeVgh&\\1K",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","gUfvqdMO&FeVgh&\\1K",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","foMAR\\1CWg&y&dngF&EL\\1",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","foMAR\\1CWg&y&dngF&EL\\1",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","\\1muHsU&g",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1000","\\1muHsU&g",[global])),
+ <<"AABCDEFGHIHIwisSqVPABCDEFGHIHIfM">> = iolist_to_binary(re:replace("ABCDEFGHIHI","^(A)(B)(C)(D)(E)(F)(G)(H)(I)\\8\\9$","\\1&wisSqVP&fM",[])),
+ <<"AABCDEFGHIHIwisSqVPABCDEFGHIHIfM">> = iolist_to_binary(re:replace("ABCDEFGHIHI","^(A)(B)(C)(D)(E)(F)(G)(H)(I)\\8\\9$","\\1&wisSqVP&fM",[global])),
ok.
run6() ->
- <<"JavrrCGIJrabcdefghijkllSabcdefghijkllSRCgujabcdefghijkllSnS">> = iolist_to_binary(re:replace("abcdefghijkllS","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123","J\\1vrrCGIJr&&RCguj&nS",[])),
- <<"JavrrCGIJrabcdefghijkllSabcdefghijkllSRCgujabcdefghijkllSnS">> = iolist_to_binary(re:replace("abcdefghijkllS","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123","J\\1vrrCGIJr&&RCguj&nS",[global])),
- <<"Iabcdefghijk
-SoGoIaaBybRYC">> = iolist_to_binary(re:replace("abcdefghijk
-S","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\\123","I&oGoI\\1\\1BybRYC",[])),
- <<"Iabcdefghijk
-SoGoIaaBybRYC">> = iolist_to_binary(re:replace("abcdefghijk
-S","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\\123","I&oGoI\\1\\1BybRYC",[global])),
- <<"RGabidefuGO">> = iolist_to_binary(re:replace("abidef","ab\\idef","RG&u\\1G\\1O",[])),
- <<"RGabidefuGO">> = iolist_to_binary(re:replace("abidef","ab\\idef","RG&u\\1G\\1O",[global])),
- <<"khlnfNEs">> = iolist_to_binary(re:replace("bc","a{0}bc","khlnfNEs",[])),
- <<"khlnfNEs">> = iolist_to_binary(re:replace("bc","a{0}bc","khlnfNEs",[global])),
- <<"rqJj">> = iolist_to_binary(re:replace("xyz","(a|(bc)){0,0}?xyz","rqJj",[])),
- <<"rqJj">> = iolist_to_binary(re:replace("xyz","(a|(bc)){0,0}?xyz","rqJj",[global])),
- <<"lSP">> = iolist_to_binary(re:replace("abcde","abc[\\10]de","lSP",[])),
- <<"lSP">> = iolist_to_binary(re:replace("abcde","abc[\\10]de","lSP",[global])),
- <<"CKJxmayjvTnPabcdeFvA">> = iolist_to_binary(re:replace("abcde","abc[\\1]de","CKJxmayjvTnP&FvA",[])),
- <<"CKJxmayjvTnPabcdeFvA">> = iolist_to_binary(re:replace("abcde","abc[\\1]de","CKJxmayjvTnP&FvA",[global])),
- <<"WyBabcdeCxJkWabcdeipq">> = iolist_to_binary(re:replace("abcde","(abc)[\\1]de","WyB&CxJkW&ipq",[])),
- <<"WyBabcdeCxJkWabcdeipq">> = iolist_to_binary(re:replace("abcde","(abc)[\\1]de","WyB&CxJkW&ipq",[global])),
- <<"Ua
-bXVska
-bg">> = iolist_to_binary(re:replace("a
-b","(?s)a.b","U&XVsk&g",[])),
- <<"Ua
-bXVska
-bg">> = iolist_to_binary(re:replace("a
-b","(?s)a.b","U&XVsk&g",[global])),
- <<"WgjbaNOTcccckIbd">> = iolist_to_binary(re:replace("baNOTccccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","Wgj&kI\\1",[])),
- <<"WgjbaNOTcccckIbd">> = iolist_to_binary(re:replace("baNOTccccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","Wgj&kI\\1",[global])),
- <<"DoCtbaMWiqd">> = iolist_to_binary(re:replace("baNOTcccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","DoCt\\1aMWiq",[])),
- <<"DoCtbaMWiqd">> = iolist_to_binary(re:replace("baNOTcccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","DoCt\\1aMWiq",[global])),
- <<"thYPIiibbhwYvfLkd">> = iolist_to_binary(re:replace("baNOTccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","thYPIii\\1bhwYvfLk",[])),
- <<"thYPIiibbhwYvfLkd">> = iolist_to_binary(re:replace("baNOTccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","thYPIii\\1bhwYvfLk",[global])),
- <<"RibMcQxAKFpd">> = iolist_to_binary(re:replace("bacccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","Ri\\1McQxAKFp",[])),
- <<"RibMcQxAKFpd">> = iolist_to_binary(re:replace("bacccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","Ri\\1McQxAKFp",[global])),
- <<"vQUa">> = iolist_to_binary(re:replace("*** Failers","^([^a])([^\\b])([^c]*)([^d]{3,4})","vQUa",[])),
- <<"vQUa">> = iolist_to_binary(re:replace("*** Failers","^([^a])([^\\b])([^c]*)([^d]{3,4})","vQUa",[global])),
- <<"anything">> = iolist_to_binary(re:replace("anything","^([^a])([^\\b])([^c]*)([^d]{3,4})","bR\\1Bb&yOfWxBSieYBnJ",[])),
- <<"anything">> = iolist_to_binary(re:replace("anything","^([^a])([^\\b])([^c]*)([^d]{3,4})","bR\\1Bb&yOfWxBSieYBnJ",[global])),
- <<"bc">> = iolist_to_binary(re:replace("bc","^([^a])([^\\b])([^c]*)([^d]{3,4})","W\\1i\\1DbDlQDP&rWwmD&",[])),
- <<"bc">> = iolist_to_binary(re:replace("bc","^([^a])([^\\b])([^c]*)([^d]{3,4})","W\\1i\\1DbDlQDP&rWwmD&",[global])),
- <<"baccd">> = iolist_to_binary(re:replace("baccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","ICMQ\\1pRu",[])),
- <<"baccd">> = iolist_to_binary(re:replace("baccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","ICMQ\\1pRu",[global])),
- <<"eUfAADRbc">> = iolist_to_binary(re:replace("Abc","[^a]","\\1\\1e\\1Uf&&\\1DR",[])),
- <<"eUfAADReUfbbDReUfccDR">> = iolist_to_binary(re:replace("Abc","[^a]","\\1\\1e\\1Uf&&\\1DR",[global])),
- <<"AbGc">> = iolist_to_binary(re:replace("Abc","[^a]","\\1&G\\1",[caseless])),
- <<"AbGcG">> = iolist_to_binary(re:replace("Abc","[^a]","\\1&G\\1",[caseless,
- global])),
- <<"AAAGAAAIXPHIaAbc">> = iolist_to_binary(re:replace("AAAaAbc","[^a]+","&G&I\\1XPHI\\1",[])),
- <<"AAAGAAAIXPHIaAbcGAbcIXPHI">> = iolist_to_binary(re:replace("AAAaAbc","[^a]+","&G&I\\1XPHI\\1",[global])),
- <<"AAAaAIxSfS">> = iolist_to_binary(re:replace("AAAaAbc","[^a]+","IxSf\\1S",[caseless])),
- <<"AAAaAIxSfS">> = iolist_to_binary(re:replace("AAAaAbc","[^a]+","IxSf\\1S",[caseless,
- global])),
- <<"AfTCbbb
-cccEbbb
-cccfDUfwWtHuS">> = iolist_to_binary(re:replace("bbb
-ccc","[^a]+","AfTC&E&fDUfwWtH\\1uS",[])),
- <<"AfTCbbb
-cccEbbb
-cccfDUfwWtHuS">> = iolist_to_binary(re:replace("bbb
-ccc","[^a]+","AfTC&E&fDUfwWtH\\1uS",[global])),
- <<"abUUudTcI">> = iolist_to_binary(re:replace("abc","[^k]$","UUud\\1TcI",[])),
- <<"abUUudTcI">> = iolist_to_binary(re:replace("abc","[^k]$","UUud\\1TcI",[global])),
- <<"*** FailerAiOYV">> = iolist_to_binary(re:replace("*** Failers","[^k]$","AiOYV",[])),
- <<"*** FailerAiOYV">> = iolist_to_binary(re:replace("*** Failers","[^k]$","AiOYV",[global])),
- <<"abk">> = iolist_to_binary(re:replace("abk","[^k]$","UV&w&TjG&\\1O\\1m",[])),
- <<"abk">> = iolist_to_binary(re:replace("abk","[^k]$","UV&w&TjG&\\1O\\1m",[global])),
- <<"cabcH">> = iolist_to_binary(re:replace("abc","[^k]{2,3}$","\\1c&\\1H",[])),
- <<"cabcH">> = iolist_to_binary(re:replace("abc","[^k]{2,3}$","\\1c&\\1H",[global])),
- <<"kUyCfbcubJVf">> = iolist_to_binary(re:replace("kbc","[^k]{2,3}$","UyCf&\\1\\1ub\\1JVf",[])),
- <<"kUyCfbcubJVf">> = iolist_to_binary(re:replace("kbc","[^k]{2,3}$","UyCf&\\1\\1ub\\1JVf",[global])),
- <<"kgiGjY">> = iolist_to_binary(re:replace("kabc","[^k]{2,3}$","giGj\\1\\1\\1Y",[])),
- <<"kgiGjY">> = iolist_to_binary(re:replace("kabc","[^k]{2,3}$","giGj\\1\\1\\1Y",[global])),
- <<"*** FailWjNDersauWgsT">> = iolist_to_binary(re:replace("*** Failers","[^k]{2,3}$","WjND&auWgsT",[])),
- <<"*** FailWjNDersauWgsT">> = iolist_to_binary(re:replace("*** Failers","[^k]{2,3}$","WjND&auWgsT",[global])),
- <<"abk">> = iolist_to_binary(re:replace("abk","[^k]{2,3}$","Gu\\1",[])),
- <<"abk">> = iolist_to_binary(re:replace("abk","[^k]{2,3}$","Gu\\1",[global])),
- <<"akb">> = iolist_to_binary(re:replace("akb","[^k]{2,3}$","a&Wrx\\1hniTRTJRP\\1",[])),
- <<"akb">> = iolist_to_binary(re:replace("akb","[^k]{2,3}$","a&Wrx\\1hniTRTJRP\\1",[global])),
- <<"akk">> = iolist_to_binary(re:replace("akk","[^k]{2,3}$","AkLa&fhMYWpv",[])),
- <<"akk">> = iolist_to_binary(re:replace("akk","[^k]{2,3}$","AkLa&fhMYWpv",[global])),
- <<"12345678.b.c.d">> = iolist_to_binary(re:replace("12345678.b.c.d","^\\d{8,}\\@.+[^k]$","HDxYDn",[])),
- <<"12345678.b.c.d">> = iolist_to_binary(re:replace("12345678.b.c.d","^\\d{8,}\\@.+[^k]$","HDxYDn",[global])),
- <<"123456789.y.z">> = iolist_to_binary(re:replace("123456789.y.z","^\\d{8,}\\@.+[^k]$","VU\\1D",[])),
- <<"123456789.y.z">> = iolist_to_binary(re:replace("123456789.y.z","^\\d{8,}\\@.+[^k]$","VU\\1D",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\d{8,}\\@.+[^k]$","GeBqm\\1Dmbs&G\\1vR",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\d{8,}\\@.+[^k]$","GeBqm\\1Dmbs&G\\1vR",[global])),
- <<"12345678.y.uk">> = iolist_to_binary(re:replace("12345678.y.uk","^\\d{8,}\\@.+[^k]$","a&VS\\1&BvR",[])),
- <<"12345678.y.uk">> = iolist_to_binary(re:replace("12345678.y.uk","^\\d{8,}\\@.+[^k]$","a&VS\\1&BvR",[global])),
- <<"1234567.b.c.d">> = iolist_to_binary(re:replace("1234567.b.c.d","^\\d{8,}\\@.+[^k]$","A&Ex&\\1\\1M\\1",[])),
- <<"1234567.b.c.d">> = iolist_to_binary(re:replace("1234567.b.c.d","^\\d{8,}\\@.+[^k]$","A&Ex&\\1\\1M\\1",[global])),
- <<"UNaaaaaaaaaASae">> = iolist_to_binary(re:replace("aaaaaaaaa","(a)\\1{8,}","UN&AS\\1e",[])),
- <<"UNaaaaaaaaaASae">> = iolist_to_binary(re:replace("aaaaaaaaa","(a)\\1{8,}","UN&AS\\1e",[global])),
- <<"tceAbivVhQav">> = iolist_to_binary(re:replace("aaaaaaaaaa","(a)\\1{8,}","tceAbivVhQ\\1v",[])),
- <<"tceAbivVhQav">> = iolist_to_binary(re:replace("aaaaaaaaaa","(a)\\1{8,}","tceAbivVhQ\\1v",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a)\\1{8,}","&\\1CR\\1G\\1lXwnVv",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a)\\1{8,}","&\\1CR\\1G\\1lXwnVv",[global])),
- <<"aaaaaaa">> = iolist_to_binary(re:replace("aaaaaaa","(a)\\1{8,}","\\1okyxc\\1yX\\1vEJ&&",[])),
- <<"aaaaaaa">> = iolist_to_binary(re:replace("aaaaaaa","(a)\\1{8,}","\\1okyxc\\1yX\\1vEJ&&",[global])),
- <<"aaaaXxrcd">> = iolist_to_binary(re:replace("aaaabcd","[^a]","Xxr",[])),
- <<"aaaaXxrXxrXxr">> = iolist_to_binary(re:replace("aaaabcd","[^a]","Xxr",[global])),
- <<"aaarLbBCUOMivTWabcd">> = iolist_to_binary(re:replace("aaAabcd","[^a]","arLbBC\\1UOMivTW",[])),
- <<"aaarLbBCUOMivTWaarLbBCUOMivTWarLbBCUOMivTWarLbBCUOMivTW">> = iolist_to_binary(re:replace("aaAabcd","[^a]","arLbBC\\1UOMivTW",[global])),
+ <<"ntA8B9CNSA8B9CLRL">> = iolist_to_binary(re:replace("A8B9C","^[A\\8B\\9C]+$","nt\\1&NS\\1&LRL",[])),
+ <<"ntA8B9CNSA8B9CLRL">> = iolist_to_binary(re:replace("A8B9C","^[A\\8B\\9C]+$","nt\\1&NS\\1&LRL",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[A\\8B\\9C]+$","YwqNG",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[A\\8B\\9C]+$","YwqNG",[global])),
+ <<"k">> = iolist_to_binary(re:replace("A8B9C","^[A\\8B\\9C]+$","k",[])),
+ <<"k">> = iolist_to_binary(re:replace("A8B9C","^[A\\8B\\9C]+$","k",[global])),
+ <<"KwWOabcdefghijkllSabcdefghijkllSvstprfvanSvjsa">> = iolist_to_binary(re:replace("abcdefghijkllS","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123","KwWO&&vstprfv\\1nSvjs\\1",[])),
+ <<"KwWOabcdefghijkllSabcdefghijkllSvstprfvanSvjsa">> = iolist_to_binary(re:replace("abcdefghijkllS","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123","KwWO&&vstprfv\\1nSvjs\\1",[global])),
+ <<"abcdefghijk
+SDuSaDcpmCspdNx">> = iolist_to_binary(re:replace("abcdefghijk
+S","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\\123","&DuSaDcpmCspdNx",[])),
+ <<"abcdefghijk
+SDuSaDcpmCspdNx">> = iolist_to_binary(re:replace("abcdefghijk
+S","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\\123","&DuSaDcpmCspdNx",[global])),
+ <<"abidefabidefvPJabidefabidefVKxVnKE">> = iolist_to_binary(re:replace("abidef","ab\\idef","\\1&&vPJ&&VKxVnKE",[])),
+ <<"abidefabidefvPJabidefabidefVKxVnKE">> = iolist_to_binary(re:replace("abidef","ab\\idef","\\1&&vPJ&&VKxVnKE",[global])),
+ <<"gkpETbcFhESR">> = iolist_to_binary(re:replace("bc","a{0}bc","gkpET&F\\1hESR",[])),
+ <<"gkpETbcFhESR">> = iolist_to_binary(re:replace("bc","a{0}bc","gkpET&F\\1hESR",[global])),
+ <<"wpngtyXvInxyzIb">> = iolist_to_binary(re:replace("xyz","(a|(bc)){0,0}?xyz","wpngtyXvIn&Ib",[])),
+ <<"wpngtyXvInxyzIb">> = iolist_to_binary(re:replace("xyz","(a|(bc)){0,0}?xyz","wpngtyXvIn&Ib",[global])),
+ <<"CdxabcdeJtWN">> = iolist_to_binary(re:replace("abcde","abc[\\10]de","Cdx\\1&JtWN",[])),
+ <<"CdxabcdeJtWN">> = iolist_to_binary(re:replace("abcde","abc[\\10]de","Cdx\\1&JtWN",[global])),
+ <<"nXabcdeLWqofabcdeabcdeM">> = iolist_to_binary(re:replace("abcde","abc[\\1]de","nX&LWqof&&M",[])),
+ <<"nXabcdeLWqofabcdeabcdeM">> = iolist_to_binary(re:replace("abcde","abc[\\1]de","nX&LWqof&&M",[global])),
+ <<"cxVabcdeXabcdeUabcdeabcdeabcIT">> = iolist_to_binary(re:replace("abcde","(abc)[\\1]de","cxV&X&U&&\\1IT",[])),
+ <<"cxVabcdeXabcdeUabcdeabcdeabcIT">> = iolist_to_binary(re:replace("abcde","(abc)[\\1]de","cxV&X&U&&\\1IT",[global])),
+ <<"nDa
+bOua
+bEE">> = iolist_to_binary(re:replace("a
+b","(?s)a.b","nD&Ou&EE",[])),
+ <<"nDa
+bOua
+bEE">> = iolist_to_binary(re:replace("a
+b","(?s)a.b","nD&Ou&EE",[global])),
+ <<"ytBjWJbyKhvRd">> = iolist_to_binary(re:replace("baNOTccccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","ytBjWJ\\1yKhvR",[])),
+ <<"ytBjWJbyKhvRd">> = iolist_to_binary(re:replace("baNOTccccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","ytBjWJ\\1yKhvR",[global])),
+ <<"rKbaNOTcccNsPd">> = iolist_to_binary(re:replace("baNOTcccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","rK&NsP",[])),
+ <<"rKbaNOTcccNsPd">> = iolist_to_binary(re:replace("baNOTcccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","rK&NsP",[global])),
+ <<"ADtLINvwgrd">> = iolist_to_binary(re:replace("baNOTccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","ADtLINvwgr",[])),
+ <<"ADtLINvwgrd">> = iolist_to_binary(re:replace("baNOTccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","ADtLINvwgr",[global])),
+ <<"XbbLidrbacccJbacccbQdd">> = iolist_to_binary(re:replace("bacccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","X\\1\\1Lidr&J&\\1Qd",[])),
+ <<"XbbLidrbacccJbacccbQdd">> = iolist_to_binary(re:replace("bacccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","X\\1\\1Lidr&J&\\1Qd",[global])),
+ <<"QAX">> = iolist_to_binary(re:replace("*** Failers","^([^a])([^\\b])([^c]*)([^d]{3,4})","QAX",[])),
+ <<"QAX">> = iolist_to_binary(re:replace("*** Failers","^([^a])([^\\b])([^c]*)([^d]{3,4})","QAX",[global])),
+ <<"anything">> = iolist_to_binary(re:replace("anything","^([^a])([^\\b])([^c]*)([^d]{3,4})","\\1nMgDDeE&j\\1IL",[])),
+ <<"anything">> = iolist_to_binary(re:replace("anything","^([^a])([^\\b])([^c]*)([^d]{3,4})","\\1nMgDDeE&j\\1IL",[global])),
+ <<"bc">> = iolist_to_binary(re:replace("bc","^([^a])([^\\b])([^c]*)([^d]{3,4})","WSh\\1fvByAl&",[])),
+ <<"bc">> = iolist_to_binary(re:replace("bc","^([^a])([^\\b])([^c]*)([^d]{3,4})","WSh\\1fvByAl&",[global])),
+ <<"baccd">> = iolist_to_binary(re:replace("baccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","BQkU&N&sI\\1M&Aaxu",[])),
+ <<"baccd">> = iolist_to_binary(re:replace("baccd","^([^a])([^\\b])([^c]*)([^d]{3,4})","BQkU&N&sI\\1M&Aaxu",[global])),
+ <<"AyfrxEdFbc">> = iolist_to_binary(re:replace("Abc","[^a]","&yfrxEdF",[])),
+ <<"AyfrxEdFbyfrxEdFcyfrxEdF">> = iolist_to_binary(re:replace("Abc","[^a]","&yfrxEdF",[global])),
+ <<"AOuc">> = iolist_to_binary(re:replace("Abc","[^a]","Ou",[caseless])),
+ <<"AOuOu">> = iolist_to_binary(re:replace("Abc","[^a]","Ou",[caseless,
+ global])),
+ <<"AAAqCQCkBIVIMNQHYaAbc">> = iolist_to_binary(re:replace("AAAaAbc","[^a]+","&qCQCkBIVIMN\\1QHY",[])),
+ <<"AAAqCQCkBIVIMNQHYaAbcqCQCkBIVIMNQHY">> = iolist_to_binary(re:replace("AAAaAbc","[^a]+","&qCQCkBIVIMN\\1QHY",[global])),
+ <<"AAAaABepbcHkVKbcFjuIYfIMUy">> = iolist_to_binary(re:replace("AAAaAbc","[^a]+","Bep&HkVK&FjuIYfIMUy",[caseless])),
+ <<"AAAaABepbcHkVKbcFjuIYfIMUy">> = iolist_to_binary(re:replace("AAAaAbc","[^a]+","Bep&HkVK&FjuIYfIMUy",[caseless,
+ global])),
+ <<"VUQibbb
+cccJFuaTHwoAPgw">> = iolist_to_binary(re:replace("bbb
+ccc","[^a]+","VUQi&\\1\\1JFuaTHwoAPgw",[])),
+ <<"VUQibbb
+cccJFuaTHwoAPgw">> = iolist_to_binary(re:replace("bbb
+ccc","[^a]+","VUQi&\\1\\1JFuaTHwoAPgw",[global])),
+ <<"abwR">> = iolist_to_binary(re:replace("abc","[^k]$","wR",[])),
+ <<"abwR">> = iolist_to_binary(re:replace("abc","[^k]$","wR",[global])),
+ <<"*** FailerrJBXyKAos">> = iolist_to_binary(re:replace("*** Failers","[^k]$","rJBXyKAo\\1&",[])),
+ <<"*** FailerrJBXyKAos">> = iolist_to_binary(re:replace("*** Failers","[^k]$","rJBXyKAo\\1&",[global])),
+ <<"abk">> = iolist_to_binary(re:replace("abk","[^k]$","\\1tMfh\\1rw&&X&",[])),
+ <<"abk">> = iolist_to_binary(re:replace("abk","[^k]$","\\1tMfh\\1rw&&X&",[global])),
+ <<"BabcMabcBstTttabcC">> = iolist_to_binary(re:replace("abc","[^k]{2,3}$","B&M\\1&B\\1stTtt&C",[])),
+ <<"BabcMabcBstTttabcC">> = iolist_to_binary(re:replace("abc","[^k]{2,3}$","B&M\\1&B\\1stTtt&C",[global])),
+ <<"kGmnpTVRbbcthURLl">> = iolist_to_binary(re:replace("kbc","[^k]{2,3}$","Gmnp\\1TVRb&thURLl",[])),
+ <<"kGmnpTVRbbcthURLl">> = iolist_to_binary(re:replace("kbc","[^k]{2,3}$","Gmnp\\1TVRb&thURLl",[global])),
+ <<"kSwSBmFSuyEabcic">> = iolist_to_binary(re:replace("kabc","[^k]{2,3}$","SwSBmFSu\\1yE&ic",[])),
+ <<"kSwSBmFSuyEabcic">> = iolist_to_binary(re:replace("kabc","[^k]{2,3}$","SwSBmFSu\\1yE&ic",[global])),
+ <<"*** FailmVk">> = iolist_to_binary(re:replace("*** Failers","[^k]{2,3}$","mVk\\1",[])),
+ <<"*** FailmVk">> = iolist_to_binary(re:replace("*** Failers","[^k]{2,3}$","mVk\\1",[global])),
+ <<"abk">> = iolist_to_binary(re:replace("abk","[^k]{2,3}$","f",[])),
+ <<"abk">> = iolist_to_binary(re:replace("abk","[^k]{2,3}$","f",[global])),
+ <<"akb">> = iolist_to_binary(re:replace("akb","[^k]{2,3}$","XISfG\\1L&Yg",[])),
+ <<"akb">> = iolist_to_binary(re:replace("akb","[^k]{2,3}$","XISfG\\1L&Yg",[global])),
+ <<"akk">> = iolist_to_binary(re:replace("akk","[^k]{2,3}$","JnS\\1Snscc\\1\\1WP\\1\\1",[])),
+ <<"akk">> = iolist_to_binary(re:replace("akk","[^k]{2,3}$","JnS\\1Snscc\\1\\1WP\\1\\1",[global])),
+ <<"12345678.b.c.d">> = iolist_to_binary(re:replace("12345678.b.c.d","^\\d{8,}\\@.+[^k]$","uF&rXNLErr\\1yUY",[])),
+ <<"12345678.b.c.d">> = iolist_to_binary(re:replace("12345678.b.c.d","^\\d{8,}\\@.+[^k]$","uF&rXNLErr\\1yUY",[global])),
+ <<"123456789.y.z">> = iolist_to_binary(re:replace("123456789.y.z","^\\d{8,}\\@.+[^k]$","YFlP&",[])),
+ <<"123456789.y.z">> = iolist_to_binary(re:replace("123456789.y.z","^\\d{8,}\\@.+[^k]$","YFlP&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\d{8,}\\@.+[^k]$","twTFob&o&kbYfyf&N",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\d{8,}\\@.+[^k]$","twTFob&o&kbYfyf&N",[global])),
+ <<"12345678.y.uk">> = iolist_to_binary(re:replace("12345678.y.uk","^\\d{8,}\\@.+[^k]$","iN&UAvL",[])),
+ <<"12345678.y.uk">> = iolist_to_binary(re:replace("12345678.y.uk","^\\d{8,}\\@.+[^k]$","iN&UAvL",[global])),
+ <<"1234567.b.c.d">> = iolist_to_binary(re:replace("1234567.b.c.d","^\\d{8,}\\@.+[^k]$","r&h\\1PJBc&xhdRAd&",[])),
+ <<"1234567.b.c.d">> = iolist_to_binary(re:replace("1234567.b.c.d","^\\d{8,}\\@.+[^k]$","r&h\\1PJBc&xhdRAd&",[global])),
+ <<"JUaaaaaaaaaakaaaaaaaaaaJByoSTnBssaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","(a)\\1{8,}","JUa&k\\1&JByoSTnBss&",[])),
+ <<"JUaaaaaaaaaakaaaaaaaaaaJByoSTnBssaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","(a)\\1{8,}","JUa&k\\1&JByoSTnBss&",[global])),
+ <<"haoaaaaaaaaaacp">> = iolist_to_binary(re:replace("aaaaaaaaaa","(a)\\1{8,}","hao&cp",[])),
+ <<"haoaaaaaaaaaacp">> = iolist_to_binary(re:replace("aaaaaaaaaa","(a)\\1{8,}","hao&cp",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a)\\1{8,}","Ns",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a)\\1{8,}","Ns",[global])),
+ <<"aaaaaaa">> = iolist_to_binary(re:replace("aaaaaaa","(a)\\1{8,}","Ye\\1kfvX&&crmMcd",[])),
+ <<"aaaaaaa">> = iolist_to_binary(re:replace("aaaaaaa","(a)\\1{8,}","Ye\\1kfvX&&crmMcd",[global])),
ok.
run7() ->
- <<"aaaapwMAbnNcRDBcd">> = iolist_to_binary(re:replace("aaaabcd","[^a]","pwMA&\\1n\\1NcRDB",[caseless])),
- <<"aaaapwMAbnNcRDBpwMAcnNcRDBpwMAdnNcRDB">> = iolist_to_binary(re:replace("aaaabcd","[^a]","pwMA&\\1n\\1NcRDB",[caseless,
- global])),
- <<"aaAaUjWwoTQoHtojaVMGDcd">> = iolist_to_binary(re:replace("aaAabcd","[^a]","UjWwoTQoHtoja\\1\\1VMGD\\1",[caseless])),
- <<"aaAaUjWwoTQoHtojaVMGDUjWwoTQoHtojaVMGDUjWwoTQoHtojaVMGD">> = iolist_to_binary(re:replace("aaAabcd","[^a]","UjWwoTQoHtoja\\1\\1VMGD\\1",[caseless,
- global])),
- <<"aaaapmJHbuyrGSgPWcd">> = iolist_to_binary(re:replace("aaaabcd","[^az]","pmJH&uyr\\1GSgPW",[])),
- <<"aaaapmJHbuyrGSgPWpmJHcuyrGSgPWpmJHduyrGSgPW">> = iolist_to_binary(re:replace("aaaabcd","[^az]","pmJH&uyr\\1GSgPW",[global])),
- <<"aaYcjbFRuBabcd">> = iolist_to_binary(re:replace("aaAabcd","[^az]","Y\\1cjbFRu\\1B",[])),
- <<"aaYcjbFRuBaYcjbFRuBYcjbFRuBYcjbFRuB">> = iolist_to_binary(re:replace("aaAabcd","[^az]","Y\\1cjbFRu\\1B",[global])),
- <<"aaaaBbjBVQSSpboacd">> = iolist_to_binary(re:replace("aaaabcd","[^az]","\\1B&jB\\1VQSSp&\\1\\1o\\1a",[caseless])),
- <<"aaaaBbjBVQSSpboaBcjBVQSSpcoaBdjBVQSSpdoa">> = iolist_to_binary(re:replace("aaaabcd","[^az]","\\1B&jB\\1VQSSp&\\1\\1o\\1a",[caseless,
- global])),
- <<"aaAaibNcd">> = iolist_to_binary(re:replace("aaAabcd","[^az]","i&N",[caseless])),
- <<"aaAaibNicNidN">> = iolist_to_binary(re:replace("aaAabcd","[^az]","i&N",[caseless,
- global])),
- <<"xxxxxxxxxxxyxxxxxxxxx">> = iolist_to_binary(re:replace("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,6}?LL","y",[])),
- <<"xxxxxxxxxxxyxxxxxxxxx">> = iolist_to_binary(re:replace("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,6}?LL","y",[global])),
- <<"xxxxxxxxxxxPSTAIREISLLQxxxxxxxxx">> = iolist_to_binary(re:replace("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,}?LL","&Q",[])),
- <<"xxxxxxxxxxxPSTAIREISLLQxxxxxxxxx">> = iolist_to_binary(re:replace("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,}?LL","&Q",[global])),
- <<"1uJmu.23V.23UHIOGab">> = iolist_to_binary(re:replace("1.230003938","(\\.\\d\\d[1-9]?)\\d+","uJmu\\1V\\1UHIOGab",[])),
- <<"1uJmu.23V.23UHIOGab">> = iolist_to_binary(re:replace("1.230003938","(\\.\\d\\d[1-9]?)\\d+","uJmu\\1V\\1UHIOGab",[global])),
- <<"1DI.875.875000282NK.875000282.875j">> = iolist_to_binary(re:replace("1.875000282","(\\.\\d\\d[1-9]?)\\d+","DI\\1&NK&\\1j",[])),
- <<"1DI.875.875000282NK.875000282.875j">> = iolist_to_binary(re:replace("1.875000282","(\\.\\d\\d[1-9]?)\\d+","DI\\1&NK&\\1j",[global])),
- <<"1L.235.23HWQNY.23KfHhq.235.23ggY">> = iolist_to_binary(re:replace("1.235","(\\.\\d\\d[1-9]?)\\d+","L&\\1HWQNY\\1KfHhq&\\1ggY",[])),
- <<"1L.235.23HWQNY.23KfHhq.235.23ggY">> = iolist_to_binary(re:replace("1.235","(\\.\\d\\d[1-9]?)\\d+","L&\\1HWQNY\\1KfHhq&\\1ggY",[global])),
- <<"1DSE0003938">> = iolist_to_binary(re:replace("1.230003938","(\\.\\d\\d((?=0)|\\d(?=\\d)))","DSE",[])),
- <<"1DSE0003938">> = iolist_to_binary(re:replace("1.230003938","(\\.\\d\\d((?=0)|\\d(?=\\d)))","DSE",[global])),
- <<"1LaUySoWUFF.875.875.875000282">> = iolist_to_binary(re:replace("1.875000282","(\\.\\d\\d((?=0)|\\d(?=\\d)))","LaUySoWUFF&&\\1",[])),
- <<"1LaUySoWUFF.875.875.875000282">> = iolist_to_binary(re:replace("1.875000282","(\\.\\d\\d((?=0)|\\d(?=\\d)))","LaUySoWUFF&&\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(\\.\\d\\d((?=0)|\\d(?=\\d)))","tRWNXmOIDc\\1&GGpOuk",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(\\.\\d\\d((?=0)|\\d(?=\\d)))","tRWNXmOIDc\\1&GGpOuk",[global])),
- <<"1.235">> = iolist_to_binary(re:replace("1.235","(\\.\\d\\d((?=0)|\\d(?=\\d)))","lYmo&PAOYv",[])),
- <<"1.235">> = iolist_to_binary(re:replace("1.235","(\\.\\d\\d((?=0)|\\d(?=\\d)))","lYmo&PAOYv",[global])),
- <<"reSOwDabTAGPdSa">> = iolist_to_binary(re:replace("ab","a(?)b","reSOwD\\1&TAGPdSa",[])),
- <<"reSOwDabTAGPdSa">> = iolist_to_binary(re:replace("ab","a(?)b","reSOwD\\1&TAGPdSa",[global])),
- <<"Food is on the OvbQHtTuN">> = iolist_to_binary(re:replace("Food is on the foo table","\\b(foo)\\s+(\\w+)","OvbQHtTuN",[caseless])),
- <<"Food is on the OvbQHtTuN">> = iolist_to_binary(re:replace("Food is on the foo table","\\b(foo)\\s+(\\w+)","OvbQHtTuN",[caseless,
- global])),
- <<"The jd is under the bar in the d is under the bar in the food is under the bar in the barRfood is under the bar in the barfood is under the bar in the barjESIDd is under the bar in the GWBDn.">> = iolist_to_binary(re:replace("The food is under the bar in the barn.","foo(.*)bar","j\\1\\1&R&&jESID\\1GWBD",[])),
- <<"The jd is under the bar in the d is under the bar in the food is under the bar in the barRfood is under the bar in the barfood is under the bar in the barjESIDd is under the bar in the GWBDn.">> = iolist_to_binary(re:replace("The food is under the bar in the barn.","foo(.*)bar","j\\1\\1&R&&jESID\\1GWBD",[global])),
- <<"The Mtfood is under the bard is under the sCjcC in the barn.">> = iolist_to_binary(re:replace("The food is under the bar in the barn.","foo(.*?)bar","Mt&\\1sCjcC",[])),
- <<"The Mtfood is under the bard is under the sCjcC in the barn.">> = iolist_to_binary(re:replace("The food is under the bar in the barn.","foo(.*?)bar","Mt&\\1sCjcC",[global])),
- <<"II have 2 numbers: 53147sQEJI have 2 numbers: 53147I have 2 numbers: 53147QI have 2 numbers: 53147I have 2 numbers: 53147Y">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d*)","I&sQEJ\\1\\1Q\\1\\1Y",[])),
- <<"II have 2 numbers: 53147sQEJI have 2 numbers: 53147I have 2 numbers: 53147QI have 2 numbers: 53147I have 2 numbers: 53147YIsQEJQY">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d*)","I&sQEJ\\1\\1Q\\1\\1Y",[global])),
- <<"BjeLtTBnKKfmuI have 2 numbers: 53147Q">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d+)","BjeLtTBnKKfmu&Q",[])),
- <<"BjeLtTBnKKfmuI have 2 numbers: 53147Q">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d+)","BjeLtTBnKKfmu&Q",[global])),
- <<"XjUoIVWVCosccRPCI have 2 numbers: 53147">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d*)","XjUoIVW\\1VCosccRPC&&",[])),
- <<"XjUoIVWVCosccRPCXjUoIVWIVCosccRPCIIXjUoIVWVCosccRPCXjUoIVW VCosccRPC XjUoIVWVCosccRPCXjUoIVWhVCosccRPChhXjUoIVWVCosccRPCXjUoIVWaVCosccRPCaaXjUoIVWVCosccRPCXjUoIVWvVCosccRPCvvXjUoIVWVCosccRPCXjUoIVWeVCosccRPCeeXjUoIVWVCosccRPCXjUoIVW VCosccRPC 2 2XjUoIVWVCosccRPCXjUoIVW VCosccRPC XjUoIVWVCosccRPCXjUoIVWnVCosccRPCnnXjUoIVWVCosccRPCXjUoIVWuVCosccRPCuuXjUoIVWVCosccRPCXjUoIVWmVCosccRPCmmXjUoIVWVCosccRPCXjUoIVWbVCosccRPCbbXjUoIVWVCosccRPCXjUoIVWeVCosccRPCeeXjUoIVWVCosccRPCXjUoIVWrVCosccRPCrrXjUoIVWVCosccRPCXjUoIVWsVCosccRPCssXjUoIVWVCosccRPCXjUoIVW:VCosccRPC::XjUoIVWVCosccRPCXjUoIVW VCosccRPC 53147 53147XjUoIVWVCosccRPC">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d*)","XjUoIVW\\1VCosccRPC&&",[global])),
- <<"LnetbRUI have woRN numbers: 53147">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d+)","LnetbRU\\1woRN",[])),
- <<"LnetbRUI have woRNLnetbRU numbers: woRN">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d+)","LnetbRU\\1woRN",[global])),
- <<"dD">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d+)$","dD",[])),
- <<"dD">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d+)$","dD",[global])),
- <<"I have 2 numbers: vpu">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d+)$","\\1vpu",[])),
- <<"I have 2 numbers: vpu">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d+)$","\\1vpu",[global])),
- <<"rEcQnOiThojYmI have 2 numbers: ysnN">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)\\b(\\d+)$","rEcQnOiThojYm\\1ysnN",[])),
- <<"rEcQnOiThojYmI have 2 numbers: ysnN">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)\\b(\\d+)$","rEcQnOiThojYm\\1ysnN",[global])),
- <<"DI have 2 numbers: 53147WrwmlgEQLiI have 2 numbers: 53147NE">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*\\D)(\\d+)$","D&WrwmlgEQLi&NE",[])),
- <<"DI have 2 numbers: 53147WrwmlgEQLiI have 2 numbers: 53147NE">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*\\D)(\\d+)$","D&WrwmlgEQLi&NE",[global])),
+ <<"aaaaltSVkYwcd">> = iolist_to_binary(re:replace("aaaabcd","[^a]","ltSVkYw\\1",[])),
+ <<"aaaaltSVkYwltSVkYwltSVkYw">> = iolist_to_binary(re:replace("aaaabcd","[^a]","ltSVkYw\\1",[global])),
+ <<"aasDabcd">> = iolist_to_binary(re:replace("aaAabcd","[^a]","sD",[])),
+ <<"aasDasDsDsD">> = iolist_to_binary(re:replace("aaAabcd","[^a]","sD",[global])),
+ <<"aaaaRlocpcd">> = iolist_to_binary(re:replace("aaaabcd","[^a]","Rlocp",[caseless])),
+ <<"aaaaRlocpRlocpRlocp">> = iolist_to_binary(re:replace("aaaabcd","[^a]","Rlocp",[caseless,
+ global])),
+ <<"aaAakvpCtRfJcd">> = iolist_to_binary(re:replace("aaAabcd","[^a]","kvpCtRfJ",[caseless])),
+ <<"aaAakvpCtRfJkvpCtRfJkvpCtRfJ">> = iolist_to_binary(re:replace("aaAabcd","[^a]","kvpCtRfJ",[caseless,
+ global])),
+ <<"aaaaHKcd">> = iolist_to_binary(re:replace("aaaabcd","[^az]","HK",[])),
+ <<"aaaaHKHKHK">> = iolist_to_binary(re:replace("aaaabcd","[^az]","HK",[global])),
+ <<"aaGTgGQtMuEWBAASqhabcd">> = iolist_to_binary(re:replace("aaAabcd","[^az]","GTgGQtMuEWB&&Sqh",[])),
+ <<"aaGTgGQtMuEWBAASqhaGTgGQtMuEWBbbSqhGTgGQtMuEWBccSqhGTgGQtMuEWBddSqh">> = iolist_to_binary(re:replace("aaAabcd","[^az]","GTgGQtMuEWB&&Sqh",[global])),
+ <<"aaaaJbKddOBcd">> = iolist_to_binary(re:replace("aaaabcd","[^az]","\\1J&KddOB",[caseless])),
+ <<"aaaaJbKddOBJcKddOBJdKddOB">> = iolist_to_binary(re:replace("aaaabcd","[^az]","\\1J&KddOB",[caseless,
+ global])),
+ <<"aaAasOBrbksjdVYVcd">> = iolist_to_binary(re:replace("aaAabcd","[^az]","sO\\1Br&ksjdVYV",[caseless])),
+ <<"aaAasOBrbksjdVYVsOBrcksjdVYVsOBrdksjdVYV">> = iolist_to_binary(re:replace("aaAabcd","[^az]","sO\\1Br&ksjdVYV",[caseless,
+ global])),
+ <<"xxxxxxxxxxxIWxxxxxxxxx">> = iolist_to_binary(re:replace("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,6}?LL","IW",[])),
+ <<"xxxxxxxxxxxIWxxxxxxxxx">> = iolist_to_binary(re:replace("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,6}?LL","IW",[global])),
+ <<"xxxxxxxxxxxguMkfUyxxxxxxxxx">> = iolist_to_binary(re:replace("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,}?LL","\\1guMkfU\\1y",[])),
+ <<"xxxxxxxxxxxguMkfUyxxxxxxxxx">> = iolist_to_binary(re:replace("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx","P[^*]TAIRE[^*]{1,}?LL","\\1guMkfU\\1y",[global])),
+ <<"1ELdCrl.23X.230003938">> = iolist_to_binary(re:replace("1.230003938","(\\.\\d\\d[1-9]?)\\d+","ELdCrl\\1X&",[])),
+ <<"1ELdCrl.23X.230003938">> = iolist_to_binary(re:replace("1.230003938","(\\.\\d\\d[1-9]?)\\d+","ELdCrl\\1X&",[global])),
+ <<"1bq">> = iolist_to_binary(re:replace("1.875000282","(\\.\\d\\d[1-9]?)\\d+","bq",[])),
+ <<"1bq">> = iolist_to_binary(re:replace("1.875000282","(\\.\\d\\d[1-9]?)\\d+","bq",[global])),
+ <<"1ODL">> = iolist_to_binary(re:replace("1.235","(\\.\\d\\d[1-9]?)\\d+","ODL",[])),
+ <<"1ODL">> = iolist_to_binary(re:replace("1.235","(\\.\\d\\d[1-9]?)\\d+","ODL",[global])),
+ <<"1ncD0003938">> = iolist_to_binary(re:replace("1.230003938","(\\.\\d\\d((?=0)|\\d(?=\\d)))","ncD",[])),
+ <<"1ncD0003938">> = iolist_to_binary(re:replace("1.230003938","(\\.\\d\\d((?=0)|\\d(?=\\d)))","ncD",[global])),
+ <<"1qgBuDW.875yC000282">> = iolist_to_binary(re:replace("1.875000282","(\\.\\d\\d((?=0)|\\d(?=\\d)))","qgBuDW\\1yC",[])),
+ <<"1qgBuDW.875yC000282">> = iolist_to_binary(re:replace("1.875000282","(\\.\\d\\d((?=0)|\\d(?=\\d)))","qgBuDW\\1yC",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(\\.\\d\\d((?=0)|\\d(?=\\d)))","X&Y",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(\\.\\d\\d((?=0)|\\d(?=\\d)))","X&Y",[global])),
+ <<"1.235">> = iolist_to_binary(re:replace("1.235","(\\.\\d\\d((?=0)|\\d(?=\\d)))","\\1luUxXVR&J\\1&\\1",[])),
+ <<"1.235">> = iolist_to_binary(re:replace("1.235","(\\.\\d\\d((?=0)|\\d(?=\\d)))","\\1luUxXVR&J\\1&\\1",[global])),
+ <<"Qko">> = iolist_to_binary(re:replace("ab","a(?)b","\\1Qko",[])),
+ <<"Qko">> = iolist_to_binary(re:replace("ab","a(?)b","\\1Qko",[global])),
+ <<"Food is on the dfoo tablefoofoo tabledfoofoofoo tablelEfooUAnHX">> = iolist_to_binary(re:replace("Food is on the foo table","\\b(foo)\\s+(\\w+)","d&\\1&d\\1\\1&lE\\1UAnHX",[caseless])),
+ <<"Food is on the dfoo tablefoofoo tabledfoofoofoo tablelEfooUAnHX">> = iolist_to_binary(re:replace("Food is on the foo table","\\b(foo)\\s+(\\w+)","d&\\1&d\\1\\1&lE\\1UAnHX",[caseless,
+ global])),
+ <<"The vUTXiRfood is under the bar in the bardPCn.">> = iolist_to_binary(re:replace("The food is under the bar in the barn.","foo(.*)bar","vUTXiR&dPC",[])),
+ <<"The vUTXiRfood is under the bar in the bardPCn.">> = iolist_to_binary(re:replace("The food is under the bar in the barn.","foo(.*)bar","vUTXiR&dPC",[global])),
+ <<"The PYYEJfood is under the barYsN in the barn.">> = iolist_to_binary(re:replace("The food is under the bar in the barn.","foo(.*?)bar","PYYEJ&YsN",[])),
+ <<"The PYYEJfood is under the barYsN in the barn.">> = iolist_to_binary(re:replace("The food is under the bar in the barn.","foo(.*?)bar","PYYEJ&YsN",[global])),
+ <<"HHotxYrI have 2 numbers: 53147MmBIIeE">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d*)","HHotxYr&MmBIIeE",[])),
+ <<"HHotxYrI have 2 numbers: 53147MmBIIeEHHotxYrMmBIIeE">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d*)","HHotxYr&MmBIIeE",[global])),
+ <<"qDOVI have 2 numbers: 53147omApQI have 2 numbers: 5314sBev">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d+)","qDOV&omApQ\\1sBev",[])),
+ <<"qDOVI have 2 numbers: 53147omApQI have 2 numbers: 5314sBev">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d+)","qDOV&omApQ\\1sBev",[global])),
+ <<"RvAXeRffNRsnI have 2 numbers: 53147">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d*)","Rv&AXeR&f&fNRsn&",[])),
+ <<"RvAXeRffNRsnRvIAXeRIfIfNRsnIRvAXeRffNRsnRv AXeR f fNRsn RvAXeRffNRsnRvhAXeRhfhfNRsnhRvAXeRffNRsnRvaAXeRafafNRsnaRvAXeRffNRsnRvvAXeRvfvfNRsnvRvAXeRffNRsnRveAXeRefefNRsneRvAXeRffNRsnRv 2AXeR 2f 2fNRsn 2RvAXeRffNRsnRv AXeR f fNRsn RvAXeRffNRsnRvnAXeRnfnfNRsnnRvAXeRffNRsnRvuAXeRufufNRsnuRvAXeRffNRsnRvmAXeRmfmfNRsnmRvAXeRffNRsnRvbAXeRbfbfNRsnbRvAXeRffNRsnRveAXeRefefNRsneRvAXeRffNRsnRvrAXeRrfrfNRsnrRvAXeRffNRsnRvsAXeRsfsfNRsnsRvAXeRffNRsnRv:AXeR:f:fNRsn:RvAXeRffNRsnRv 53147AXeR 53147f 53147fNRsn 53147RvAXeRffNRsn">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d*)","Rv&AXeR&f&fNRsn&",[global])),
+ <<"TOVi numbers: 53147">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d+)","TOVi",[])),
+ <<"TOViTOVi">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d+)","TOVi",[global])),
+ <<"CAI have 2 numbers: 5314I have 2 numbers: 5314OgviGuI have 2 numbers: 53147nI have 2 numbers: 53147G">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d+)$","CA\\1\\1OgviGu&n&G",[])),
+ <<"CAI have 2 numbers: 5314I have 2 numbers: 5314OgviGuI have 2 numbers: 53147nI have 2 numbers: 53147G">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)(\\d+)$","CA\\1\\1OgviGu&n&G",[global])),
+ <<"uMVspI have 2 numbers: 53147VVs">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d+)$","uMVsp&VVs",[])),
+ <<"uMVspI have 2 numbers: 53147VVs">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*?)(\\d+)$","uMVsp&VVs",[global])),
+ <<"exxLI have 2 numbers: 53147KHfPaoE">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)\\b(\\d+)$","exxL&KHfPaoE",[])),
+ <<"exxLI have 2 numbers: 53147KHfPaoE">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*)\\b(\\d+)$","exxL&KHfPaoE",[global])),
ok.
run8() ->
- <<"ABcsqUeQdAAByYxNC123">> = iolist_to_binary(re:replace("ABC123","^\\D*(?!123)","&csq\\1UeQdA&yYxN",[])),
- <<"ABcsqUeQdAAByYxNC123">> = iolist_to_binary(re:replace("ABC123","^\\D*(?!123)","&csq\\1UeQdA&yYxN",[global])),
- <<"KABCABCBP445">> = iolist_to_binary(re:replace("ABC445","^(\\D*)(?=\\d)(?!123)","K\\1&BP",[])),
- <<"KABCABCBP445">> = iolist_to_binary(re:replace("ABC445","^(\\D*)(?=\\d)(?!123)","K\\1&BP",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\D*)(?=\\d)(?!123)","kBiY&gp\\1BUO\\1l",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\D*)(?=\\d)(?!123)","kBiY&gp\\1BUO\\1l",[global])),
- <<"ABC123">> = iolist_to_binary(re:replace("ABC123","^(\\D*)(?=\\d)(?!123)","\\1YYe",[])),
- <<"ABC123">> = iolist_to_binary(re:replace("ABC123","^(\\D*)(?=\\d)(?!123)","\\1YYe",[global])),
- <<"W46]pbAIEqJRW46]W46]cNuYW46]789">> = iolist_to_binary(re:replace("W46]789","^[W-]46]","&pbAIEqJ\\1R&&cNuY&",[])),
- <<"W46]pbAIEqJRW46]W46]cNuYW46]789">> = iolist_to_binary(re:replace("W46]789","^[W-]46]","&pbAIEqJ\\1R&&cNuY&",[global])),
- <<"AXCFhT-46]LP-46]gILH-46]rA789">> = iolist_to_binary(re:replace("-46]789","^[W-]46]","AXCFhT&LP&gIL\\1H&rA",[])),
- <<"AXCFhT-46]LP-46]gILH-46]rA789">> = iolist_to_binary(re:replace("-46]789","^[W-]46]","AXCFhT&LP&gIL\\1H&rA",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-]46]","ke&s",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-]46]","ke&s",[global])),
- <<"Wall">> = iolist_to_binary(re:replace("Wall","^[W-]46]","\\1C\\1VS&grCoMvM\\1",[])),
- <<"Wall">> = iolist_to_binary(re:replace("Wall","^[W-]46]","\\1C\\1VS&grCoMvM\\1",[global])),
- <<"Zebra">> = iolist_to_binary(re:replace("Zebra","^[W-]46]","G\\1\\1",[])),
- <<"Zebra">> = iolist_to_binary(re:replace("Zebra","^[W-]46]","G\\1\\1",[global])),
- <<"42">> = iolist_to_binary(re:replace("42","^[W-]46]","k\\1p&\\1&E&OlmU",[])),
- <<"42">> = iolist_to_binary(re:replace("42","^[W-]46]","k\\1p&\\1&E&OlmU",[global])),
- <<"[abcd]">> = iolist_to_binary(re:replace("[abcd]","^[W-]46]","BHuM&QWt&V&Fw&R\\1",[])),
- <<"[abcd]">> = iolist_to_binary(re:replace("[abcd]","^[W-]46]","BHuM&QWt&V&Fw&R\\1",[global])),
- <<"]abcd[">> = iolist_to_binary(re:replace("]abcd[","^[W-]46]","bm\\1kBng&&HJv",[])),
- <<"]abcd[">> = iolist_to_binary(re:replace("]abcd[","^[W-]46]","bm\\1kBng&&HJv",[global])),
- <<"YiVQVvgWY46]789">> = iolist_to_binary(re:replace("W46]789","^[W-\\]46]","Yi\\1VQVv\\1g&Y",[])),
- <<"YiVQVvgWY46]789">> = iolist_to_binary(re:replace("W46]789","^[W-\\]46]","Yi\\1VQVv\\1g&Y",[global])),
- <<"KJall">> = iolist_to_binary(re:replace("Wall","^[W-\\]46]","K\\1J",[])),
- <<"KJall">> = iolist_to_binary(re:replace("Wall","^[W-\\]46]","K\\1J",[global])),
- <<"ghebra">> = iolist_to_binary(re:replace("Zebra","^[W-\\]46]","gh",[])),
- <<"ghebra">> = iolist_to_binary(re:replace("Zebra","^[W-\\]46]","gh",[global])),
- <<"TQpylophone">> = iolist_to_binary(re:replace("Xylophone","^[W-\\]46]","TQp\\1",[])),
- <<"TQpylophone">> = iolist_to_binary(re:replace("Xylophone","^[W-\\]46]","TQp\\1",[global])),
- <<"4yTdgOXvDDmWf2">> = iolist_to_binary(re:replace("42","^[W-\\]46]","&y\\1TdgOXvDDm\\1Wf",[])),
- <<"4yTdgOXvDDmWf2">> = iolist_to_binary(re:replace("42","^[W-\\]46]","&y\\1TdgOXvDDm\\1Wf",[global])),
- <<"[OVexyXabcd]">> = iolist_to_binary(re:replace("[abcd]","^[W-\\]46]","&OVexyX",[])),
- <<"[OVexyXabcd]">> = iolist_to_binary(re:replace("[abcd]","^[W-\\]46]","&OVexyX",[global])),
- <<"HparACpuFCvG]abcd[">> = iolist_to_binary(re:replace("]abcd[","^[W-\\]46]","HparACp\\1uFCvG&",[])),
- <<"HparACpuFCvG]abcd[">> = iolist_to_binary(re:replace("]abcd[","^[W-\\]46]","HparACp\\1uFCvG&",[global])),
- <<"HQnantyI\\wNbackslash">> = iolist_to_binary(re:replace("\\backslash","^[W-\\]46]","HQnantyI&wN",[])),
- <<"HQnantyI\\wNbackslash">> = iolist_to_binary(re:replace("\\backslash","^[W-\\]46]","HQnantyI&wN",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-\\]46]","AMd&J\\1SokjY\\1\\1nK",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-\\]46]","AMd&J\\1SokjY\\1\\1nK",[global])),
- <<"-46]789">> = iolist_to_binary(re:replace("-46]789","^[W-\\]46]","RyY&cCj",[])),
- <<"-46]789">> = iolist_to_binary(re:replace("-46]789","^[W-\\]46]","RyY&cCj",[global])),
- <<"well">> = iolist_to_binary(re:replace("well","^[W-\\]46]","XPRm\\1VTejwB",[])),
- <<"well">> = iolist_to_binary(re:replace("well","^[W-\\]46]","XPRm\\1VTejwB",[global])),
- <<"oroGlaQAqnbI">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?:[a-zA-Z0-9]+ ){0,10}otherword","oroGlaQAqnbI",[])),
- <<"oroGlaQAqnbI">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?:[a-zA-Z0-9]+ ){0,10}otherword","oroGlaQAqnbI",[global])),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark","word (?:[a-zA-Z0-9]+ ){0,10}otherword","&E\\1",[])),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark","word (?:[a-zA-Z0-9]+ ){0,10}otherword","&E\\1",[global])),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?:[a-zA-Z0-9]+ ){0,300}otherword","b\\1sLq\\1\\1P",[])),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?:[a-zA-Z0-9]+ ){0,300}otherword","b\\1sLq\\1\\1P",[global])),
- <<"fPbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,0}","fP",[])),
- <<"fPbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,0}","fP",[global])),
- <<"jFVHnjWvnETRabc">> = iolist_to_binary(re:replace("abc","^(a){0,0}","jFVHn&j&WvnETR",[])),
- <<"jFVHnjWvnETRabc">> = iolist_to_binary(re:replace("abc","^(a){0,0}","jFVHn&j&WvnETR",[global])),
- <<"NDaab">> = iolist_to_binary(re:replace("aab","^(a){0,0}","ND",[])),
- <<"NDaab">> = iolist_to_binary(re:replace("aab","^(a){0,0}","ND",[global])),
- <<"RNIIKIcNvfeSEvtOPRObcd">> = iolist_to_binary(re:replace("bcd","^(a){0,1}","RNIIKIcNvfeSEvtO\\1PRO",[])),
- <<"RNIIKIcNvfeSEvtOPRObcd">> = iolist_to_binary(re:replace("bcd","^(a){0,1}","RNIIKIcNvfeSEvtO\\1PRO",[global])),
- <<"dDaaaaCaSvbc">> = iolist_to_binary(re:replace("abc","^(a){0,1}","dD&&&&C&Sv",[])),
- <<"dDaaaaCaSvbc">> = iolist_to_binary(re:replace("abc","^(a){0,1}","dD&&&&C&Sv",[global])),
- <<"cBbGtgJQnrojHMab">> = iolist_to_binary(re:replace("aab","^(a){0,1}","cBbGtgJQnrojHM",[])),
- <<"cBbGtgJQnrojHMab">> = iolist_to_binary(re:replace("aab","^(a){0,1}","cBbGtgJQnrojHM",[global])),
- <<"Mhbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,2}","\\1&M\\1h",[])),
- <<"Mhbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,2}","\\1&M\\1h",[global])),
- <<"aauJmduMieraXgHfaobc">> = iolist_to_binary(re:replace("abc","^(a){0,2}","&&uJmduMier\\1XgHf&o",[])),
- <<"aauJmduMieraXgHfaobc">> = iolist_to_binary(re:replace("abc","^(a){0,2}","&&uJmduMier\\1XgHf&o",[global])),
- <<"aaunb">> = iolist_to_binary(re:replace("aab","^(a){0,2}","&un",[])),
- <<"aaunb">> = iolist_to_binary(re:replace("aab","^(a){0,2}","&un",[global])),
- <<"osculgsNbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,3}","osculg&s&N&",[])),
- <<"osculgsNbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,3}","osculg&s&N&",[global])),
- <<"gerhgaeJRbnhIdabc">> = iolist_to_binary(re:replace("abc","^(a){0,3}","gerhg&eJRbnhId&",[])),
- <<"gerhgaeJRbnhIdabc">> = iolist_to_binary(re:replace("abc","^(a){0,3}","gerhg&eJRbnhId&",[global])),
- <<"emmqaaaesYb">> = iolist_to_binary(re:replace("aab","^(a){0,3}","emmq&\\1esY",[])),
- <<"emmqaaaesYb">> = iolist_to_binary(re:replace("aab","^(a){0,3}","emmq&\\1esY",[global])),
- <<"Rfafau">> = iolist_to_binary(re:replace("aaa","^(a){0,3}","Rf\\1f\\1u",[])),
- <<"Rfafau">> = iolist_to_binary(re:replace("aaa","^(a){0,3}","Rf\\1f\\1u",[global])),
- <<"Bbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,}","B",[])),
- <<"Bbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,}","B",[global])),
- <<"aOlCbc">> = iolist_to_binary(re:replace("abc","^(a){0,}","\\1OlC",[])),
- <<"aOlCbc">> = iolist_to_binary(re:replace("abc","^(a){0,}","\\1OlC",[global])),
- <<"ab">> = iolist_to_binary(re:replace("aab","^(a){0,}","\\1",[])),
- <<"ab">> = iolist_to_binary(re:replace("aab","^(a){0,}","\\1",[global])),
- <<"ECTqSuTCy">> = iolist_to_binary(re:replace("aaa","^(a){0,}","ECTqSuTCy",[])),
- <<"ECTqSuTCy">> = iolist_to_binary(re:replace("aaa","^(a){0,}","ECTqSuTCy",[global])),
- <<"WQhDeFb">> = iolist_to_binary(re:replace("aaaaaaaa","^(a){0,}","WQhDeFb",[])),
- <<"WQhDeFb">> = iolist_to_binary(re:replace("aaaaaaaa","^(a){0,}","WQhDeFb",[global])),
- <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,1}","k&&&pAWV&FHAQeCpc",[])),
- <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,1}","k&&&pAWV&FHAQeCpc",[global])),
- <<"rorUbgMQXaSaYGambc">> = iolist_to_binary(re:replace("abc","^(a){1,1}","rorUbgMQX&S\\1YG\\1m",[])),
- <<"rorUbgMQXaSaYGambc">> = iolist_to_binary(re:replace("abc","^(a){1,1}","rorUbgMQX&S\\1YG\\1m",[global])),
- <<"aNaaab">> = iolist_to_binary(re:replace("aab","^(a){1,1}","aN&\\1",[])),
- <<"aNaaab">> = iolist_to_binary(re:replace("aab","^(a){1,1}","aN&\\1",[global])),
- <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,2}","j\\1w\\1UDgbH",[])),
- <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,2}","j\\1w\\1UDgbH",[global])),
- <<"kNacaAaaHgaaWTaWaubc">> = iolist_to_binary(re:replace("abc","^(a){1,2}","kN\\1c\\1Aa&Hg\\1&WT&W&u",[])),
- <<"kNacaAaaHgaaWTaWaubc">> = iolist_to_binary(re:replace("abc","^(a){1,2}","kN\\1c\\1Aa&Hg\\1&WT&W&u",[global])),
- <<"AjaaammeJIb">> = iolist_to_binary(re:replace("aab","^(a){1,2}","Aj&\\1mmeJI",[])),
- <<"AjaaammeJIb">> = iolist_to_binary(re:replace("aab","^(a){1,2}","Aj&\\1mmeJI",[global])),
- <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,3}","&&TTjl\\1nt",[])),
- <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,3}","&&TTjl\\1nt",[global])),
- <<"UeMuRbc">> = iolist_to_binary(re:replace("abc","^(a){1,3}","UeMuR",[])),
- <<"UeMuRbc">> = iolist_to_binary(re:replace("abc","^(a){1,3}","UeMuR",[global])),
- <<"vFaaaSDjb">> = iolist_to_binary(re:replace("aab","^(a){1,3}","vF\\1&SDj",[])),
- <<"vFaaaSDjb">> = iolist_to_binary(re:replace("aab","^(a){1,3}","vF\\1&SDj",[global])),
- <<"CNwXaaa">> = iolist_to_binary(re:replace("aaa","^(a){1,3}","CNwX&",[])),
- <<"CNwXaaa">> = iolist_to_binary(re:replace("aaa","^(a){1,3}","CNwX&",[global])),
- <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,}","E\\1eK",[])),
- <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,}","E\\1eK",[global])),
- <<"IWaNYMwyOaJnfoPPMbc">> = iolist_to_binary(re:replace("abc","^(a){1,}","IW&NYMwyO\\1JnfoPPM",[])),
- <<"IWaNYMwyOaJnfoPPMbc">> = iolist_to_binary(re:replace("abc","^(a){1,}","IW&NYMwyO\\1JnfoPPM",[global])),
- <<"SaaafHrCab">> = iolist_to_binary(re:replace("aab","^(a){1,}","S&\\1fHrCa",[])),
- <<"SaaafHrCab">> = iolist_to_binary(re:replace("aab","^(a){1,}","S&\\1fHrCa",[global])),
- <<"MaYaaaRaAXUO">> = iolist_to_binary(re:replace("aaa","^(a){1,}","M\\1Y&R\\1AXUO",[])),
- <<"MaYaaaRaAXUO">> = iolist_to_binary(re:replace("aaa","^(a){1,}","M\\1Y&R\\1AXUO",[global])),
- <<"BsHaS">> = iolist_to_binary(re:replace("aaaaaaaa","^(a){1,}","BsH\\1S",[])),
- <<"BsHaS">> = iolist_to_binary(re:replace("aaaaaaaa","^(a){1,}","BsH\\1S",[global])),
- <<"borfle
-nJEnJAvwAybib.gifXvq
-no">> = iolist_to_binary(re:replace("borfle
-bib.gif
-no",".*\\.gif","nJEnJAvwAy&Xvq\\1",[])),
+ <<"GI have 2 numbers: 53147wBxahbWqKI have 2 numbers: 53147">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*\\D)(\\d+)$","G&wBxahbWqK&",[])),
+ <<"GI have 2 numbers: 53147wBxahbWqKI have 2 numbers: 53147">> = iolist_to_binary(re:replace("I have 2 numbers: 53147","(.*\\D)(\\d+)$","G&wBxahbWqK&",[global])),
+ <<"ooXOkmSKHJC123">> = iolist_to_binary(re:replace("ABC123","^\\D*(?!123)","ooXOkm\\1SKHJ",[])),
+ <<"ooXOkmSKHJC123">> = iolist_to_binary(re:replace("ABC123","^\\D*(?!123)","ooXOkm\\1SKHJ",[global])),
+ <<"SABCIvPvMFj445">> = iolist_to_binary(re:replace("ABC445","^(\\D*)(?=\\d)(?!123)","S\\1IvPvMFj",[])),
+ <<"SABCIvPvMFj445">> = iolist_to_binary(re:replace("ABC445","^(\\D*)(?=\\d)(?!123)","S\\1IvPvMFj",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\D*)(?=\\d)(?!123)","AUFFK&dgWBBmewQfx&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\D*)(?=\\d)(?!123)","AUFFK&dgWBBmewQfx&",[global])),
+ <<"ABC123">> = iolist_to_binary(re:replace("ABC123","^(\\D*)(?=\\d)(?!123)","MHrweJqRiSN&vMX",[])),
+ <<"ABC123">> = iolist_to_binary(re:replace("ABC123","^(\\D*)(?=\\d)(?!123)","MHrweJqRiSN&vMX",[global])),
+ <<"dykX789">> = iolist_to_binary(re:replace("W46]789","^[W-]46]","dyk\\1X",[])),
+ <<"dykX789">> = iolist_to_binary(re:replace("W46]789","^[W-]46]","dyk\\1X",[global])),
+ <<"-46]-46]rksdKohP789">> = iolist_to_binary(re:replace("-46]789","^[W-]46]","&&rksdKohP",[])),
+ <<"-46]-46]rksdKohP789">> = iolist_to_binary(re:replace("-46]789","^[W-]46]","&&rksdKohP",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-]46]","kRw",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-]46]","kRw",[global])),
+ <<"Wall">> = iolist_to_binary(re:replace("Wall","^[W-]46]","abc&\\1NpH\\1&iHWAa&",[])),
+ <<"Wall">> = iolist_to_binary(re:replace("Wall","^[W-]46]","abc&\\1NpH\\1&iHWAa&",[global])),
+ <<"Zebra">> = iolist_to_binary(re:replace("Zebra","^[W-]46]","g",[])),
+ <<"Zebra">> = iolist_to_binary(re:replace("Zebra","^[W-]46]","g",[global])),
+ <<"42">> = iolist_to_binary(re:replace("42","^[W-]46]","Uj",[])),
+ <<"42">> = iolist_to_binary(re:replace("42","^[W-]46]","Uj",[global])),
+ <<"[abcd]">> = iolist_to_binary(re:replace("[abcd]","^[W-]46]","lIXi\\1\\1GIq",[])),
+ <<"[abcd]">> = iolist_to_binary(re:replace("[abcd]","^[W-]46]","lIXi\\1\\1GIq",[global])),
+ <<"]abcd[">> = iolist_to_binary(re:replace("]abcd[","^[W-]46]","ALpo\\1E\\1X\\1Acu&",[])),
+ <<"]abcd[">> = iolist_to_binary(re:replace("]abcd[","^[W-]46]","ALpo\\1E\\1X\\1Acu&",[global])),
+ <<"ltduUrjtoW46]789">> = iolist_to_binary(re:replace("W46]789","^[W-\\]46]","ltduU\\1rj\\1to&",[])),
+ <<"ltduUrjtoW46]789">> = iolist_to_binary(re:replace("W46]789","^[W-\\]46]","ltduU\\1rj\\1to&",[global])),
+ <<"HeHall">> = iolist_to_binary(re:replace("Wall","^[W-\\]46]","H\\1eH",[])),
+ <<"HeHall">> = iolist_to_binary(re:replace("Wall","^[W-\\]46]","H\\1eH",[global])),
+ <<"uebra">> = iolist_to_binary(re:replace("Zebra","^[W-\\]46]","u",[])),
+ <<"uebra">> = iolist_to_binary(re:replace("Zebra","^[W-\\]46]","u",[global])),
+ <<"ysQfXpOVCXaylophone">> = iolist_to_binary(re:replace("Xylophone","^[W-\\]46]","ysQf\\1&pO\\1VC&a",[])),
+ <<"ysQfXpOVCXaylophone">> = iolist_to_binary(re:replace("Xylophone","^[W-\\]46]","ysQf\\1&pO\\1VC&a",[global])),
+ <<"BX4UMd4MBxorPoSKMb2">> = iolist_to_binary(re:replace("42","^[W-\\]46]","\\1BX&UMd&MBxorPoSK\\1Mb",[])),
+ <<"BX4UMd4MBxorPoSKMb2">> = iolist_to_binary(re:replace("42","^[W-\\]46]","\\1BX&UMd&MBxorPoSK\\1Mb",[global])),
+ <<"S[abcd]">> = iolist_to_binary(re:replace("[abcd]","^[W-\\]46]","\\1S&",[])),
+ <<"S[abcd]">> = iolist_to_binary(re:replace("[abcd]","^[W-\\]46]","\\1S&",[global])),
+ <<"XKhbeUQxIlabcd[">> = iolist_to_binary(re:replace("]abcd[","^[W-\\]46]","X\\1K\\1hb\\1e\\1\\1UQxIl",[])),
+ <<"XKhbeUQxIlabcd[">> = iolist_to_binary(re:replace("]abcd[","^[W-\\]46]","X\\1K\\1hb\\1e\\1\\1UQxIl",[global])),
+ <<"dXqbackslash">> = iolist_to_binary(re:replace("\\backslash","^[W-\\]46]","\\1dXq",[])),
+ <<"dXqbackslash">> = iolist_to_binary(re:replace("\\backslash","^[W-\\]46]","\\1dXq",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-\\]46]","HOyNFM\\1mIhSgQdQ&K\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[W-\\]46]","HOyNFM\\1mIhSgQdQ&K\\1",[global])),
+ <<"-46]789">> = iolist_to_binary(re:replace("-46]789","^[W-\\]46]","rh&&Of\\1hH",[])),
+ <<"-46]789">> = iolist_to_binary(re:replace("-46]789","^[W-\\]46]","rh&&Of\\1hH",[global])),
+ <<"well">> = iolist_to_binary(re:replace("well","^[W-\\]46]","cbWVIYcxbQg\\1",[])),
+ <<"well">> = iolist_to_binary(re:replace("well","^[W-\\]46]","cbWVIYcxbQg\\1",[global])),
+ <<"NArawword cat dog elephant mussel cow horse canary baboon snake shark otherwordQ">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?:[a-zA-Z0-9]+ ){0,10}otherword","NAraw&\\1Q",[])),
+ <<"NArawword cat dog elephant mussel cow horse canary baboon snake shark otherwordQ">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?:[a-zA-Z0-9]+ ){0,10}otherword","NAraw&\\1Q",[global])),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark","word (?:[a-zA-Z0-9]+ ){0,10}otherword","&&NApA\\1v\\1\\1cnExjYTArB",[])),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark","word (?:[a-zA-Z0-9]+ ){0,10}otherword","&&NApA\\1v\\1\\1cnExjYTArB",[global])),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?:[a-zA-Z0-9]+ ){0,300}otherword","A&qAIOCV",[])),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?:[a-zA-Z0-9]+ ){0,300}otherword","A&qAIOCV",[global])),
+ <<"KqTqEDmbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,0}","KqTqEDm",[])),
+ <<"KqTqEDmbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,0}","KqTqEDm",[global])),
+ <<"ioXlXnsoNabc">> = iolist_to_binary(re:replace("abc","^(a){0,0}","&ioXlXns&oN\\1",[])),
+ <<"ioXlXnsoNabc">> = iolist_to_binary(re:replace("abc","^(a){0,0}","&ioXlXns&oN\\1",[global])),
+ <<"kwaab">> = iolist_to_binary(re:replace("aab","^(a){0,0}","kw",[])),
+ <<"kwaab">> = iolist_to_binary(re:replace("aab","^(a){0,0}","kw",[global])),
+ <<"UcTyIixbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,1}","Uc&TyI&ix",[])),
+ <<"UcTyIixbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,1}","Uc&TyI&ix",[global])),
+ <<"mIikbc">> = iolist_to_binary(re:replace("abc","^(a){0,1}","mIik",[])),
+ <<"mIikbc">> = iolist_to_binary(re:replace("abc","^(a){0,1}","mIik",[global])),
+ <<"dqceagxefBaadIOab">> = iolist_to_binary(re:replace("aab","^(a){0,1}","dqce&gxefB\\1\\1dIO",[])),
+ <<"dqceagxefBaadIOab">> = iolist_to_binary(re:replace("aab","^(a){0,1}","dqce&gxefB\\1\\1dIO",[global])),
+ <<"wLwgjiEJTwmbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,2}","w&L&wg&ji&EJTwm",[])),
+ <<"wLwgjiEJTwmbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,2}","w&L&wg&ji&EJTwm",[global])),
+ <<"YaanaRwaEjbc">> = iolist_to_binary(re:replace("abc","^(a){0,2}","Y&&n\\1Rw\\1Ej",[])),
+ <<"YaanaRwaEjbc">> = iolist_to_binary(re:replace("abc","^(a){0,2}","Y&&n\\1Rw\\1Ej",[global])),
+ <<"xXpYPTdeIaeCaaamaIb">> = iolist_to_binary(re:replace("aab","^(a){0,2}","xXpYPTdeI\\1eC&\\1maI",[])),
+ <<"xXpYPTdeIaeCaaamaIb">> = iolist_to_binary(re:replace("aab","^(a){0,2}","xXpYPTdeI\\1eC&\\1maI",[global])),
+ <<"rbRgYffbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,3}","rbRgYff",[])),
+ <<"rbRgYffbcd">> = iolist_to_binary(re:replace("bcd","^(a){0,3}","rbRgYff",[global])),
+ <<"qFVJLbc">> = iolist_to_binary(re:replace("abc","^(a){0,3}","qFVJL",[])),
+ <<"qFVJLbc">> = iolist_to_binary(re:replace("abc","^(a){0,3}","qFVJL",[global])),
+ <<"QtqBOxb">> = iolist_to_binary(re:replace("aab","^(a){0,3}","QtqBOx",[])),
+ <<"QtqBOxb">> = iolist_to_binary(re:replace("aab","^(a){0,3}","QtqBOx",[global])),
+ <<"tXNokRjRKvXaaaIaaaaWSIA">> = iolist_to_binary(re:replace("aaa","^(a){0,3}","tXNokRjRKvX&I\\1&WSIA",[])),
+ <<"tXNokRjRKvXaaaIaaaaWSIA">> = iolist_to_binary(re:replace("aaa","^(a){0,3}","tXNokRjRKvX&I\\1&WSIA",[global])),
+ <<"eopBsGmBubcd">> = iolist_to_binary(re:replace("bcd","^(a){0,}","eopBsGmB&u\\1",[])),
+ <<"eopBsGmBubcd">> = iolist_to_binary(re:replace("bcd","^(a){0,}","eopBsGmB&u\\1",[global])),
+ <<"XGaKIdSoshwbLyuUaEbc">> = iolist_to_binary(re:replace("abc","^(a){0,}","XG&KIdSoshwbLyuU&E",[])),
+ <<"XGaKIdSoshwbLyuUaEbc">> = iolist_to_binary(re:replace("abc","^(a){0,}","XG&KIdSoshwbLyuU&E",[global])),
+ <<"QVBStnKyKwiFaarwKKaKtb">> = iolist_to_binary(re:replace("aab","^(a){0,}","QVBStnKyKwiF&rwKK\\1Kt",[])),
+ <<"QVBStnKyKwiFaarwKKaKtb">> = iolist_to_binary(re:replace("aab","^(a){0,}","QVBStnKyKwiF&rwKK\\1Kt",[global])),
+ <<"aaafFGmLJOyaxg">> = iolist_to_binary(re:replace("aaa","^(a){0,}","&fFGmLJOy\\1xg",[])),
+ <<"aaafFGmLJOyaxg">> = iolist_to_binary(re:replace("aaa","^(a){0,}","&fFGmLJOy\\1xg",[global])),
+ <<"vvdaSSUIVja">> = iolist_to_binary(re:replace("aaaaaaaa","^(a){0,}","vvd\\1SSUIVj\\1",[])),
+ <<"vvdaSSUIVja">> = iolist_to_binary(re:replace("aaaaaaaa","^(a){0,}","vvd\\1SSUIVj\\1",[global])),
+ <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,1}","\\1cU",[])),
+ <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,1}","\\1cU",[global])),
+ <<"aXagESUEcdbc">> = iolist_to_binary(re:replace("abc","^(a){1,1}","\\1X&gESUEcd",[])),
+ <<"aXagESUEcdbc">> = iolist_to_binary(re:replace("abc","^(a){1,1}","\\1X&gESUEcd",[global])),
+ <<"XMYab">> = iolist_to_binary(re:replace("aab","^(a){1,1}","XMY",[])),
+ <<"XMYab">> = iolist_to_binary(re:replace("aab","^(a){1,1}","XMY",[global])),
+ <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,2}","tGJ&&",[])),
+ <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,2}","tGJ&&",[global])),
+ <<"aduQQOassaHGbc">> = iolist_to_binary(re:replace("abc","^(a){1,2}","\\1duQQO&ss\\1HG",[])),
+ <<"aduQQOassaHGbc">> = iolist_to_binary(re:replace("abc","^(a){1,2}","\\1duQQO&ss\\1HG",[global])),
+ <<"acmBfjb">> = iolist_to_binary(re:replace("aab","^(a){1,2}","\\1cmBfj",[])),
+ <<"acmBfjb">> = iolist_to_binary(re:replace("aab","^(a){1,2}","\\1cmBfj",[global])),
+ <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,3}","tQ&ktkv\\1VkD&K",[])),
+ <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,3}","tQ&ktkv\\1VkD&K",[global])),
+ <<"chaaBsFRlbc">> = iolist_to_binary(re:replace("abc","^(a){1,3}","ch&\\1BsFRl",[])),
+ <<"chaaBsFRlbc">> = iolist_to_binary(re:replace("abc","^(a){1,3}","ch&\\1BsFRl",[global])),
+ <<"USb">> = iolist_to_binary(re:replace("aab","^(a){1,3}","US",[])),
+ <<"USb">> = iolist_to_binary(re:replace("aab","^(a){1,3}","US",[global])),
+ <<"QUVwfLaFRTxkapVJd">> = iolist_to_binary(re:replace("aaa","^(a){1,3}","QUVwfL\\1FRTxk\\1pVJd",[])),
+ <<"QUVwfLaFRTxkapVJd">> = iolist_to_binary(re:replace("aaa","^(a){1,3}","QUVwfL\\1FRTxk\\1pVJd",[global])),
+ <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,}","xN\\1mi",[])),
+ <<"bcd">> = iolist_to_binary(re:replace("bcd","^(a){1,}","xN\\1mi",[global])),
+ <<"aCauataXanaETbc">> = iolist_to_binary(re:replace("abc","^(a){1,}","&C&u&t&X&n&ET",[])),
+ <<"aCauataXanaETbc">> = iolist_to_binary(re:replace("abc","^(a){1,}","&C&u&t&X&n&ET",[global])),
+ <<"Bb">> = iolist_to_binary(re:replace("aab","^(a){1,}","B",[])),
+ <<"Bb">> = iolist_to_binary(re:replace("aab","^(a){1,}","B",[global])),
+ <<"XFykuakPaulQTqER">> = iolist_to_binary(re:replace("aaa","^(a){1,}","XFyku\\1kP\\1ulQTqER",[])),
+ <<"XFykuakPaulQTqER">> = iolist_to_binary(re:replace("aaa","^(a){1,}","XFyku\\1kP\\1ulQTqER",[global])),
+ <<"uaaaaaaaasAaaaaaaaaiaaaaaaaaObkaQXXqLaPgaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaa","^(a){1,}","u&sA&i&Obk\\1QXXqL\\1Pg&",[])),
+ <<"uaaaaaaaasAaaaaaaaaiaaaaaaaaObkaQXXqLaPgaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaa","^(a){1,}","u&sA&i&Obk\\1QXXqL\\1Pg&",[global])),
<<"borfle
-nJEnJAvwAybib.gifXvq
+JMhXbib.gifxEbib.gifhBlXkR
no">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*\\.gif","nJEnJAvwAy&Xvq\\1",[global])),
+no",".*\\.gif","JMhX&xE&hBl\\1Xk\\1R",[])),
<<"borfle
-Nmmq
+JMhXbib.gifxEbib.gifhBlXkR
no">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".{0,}\\.gif","Nmmq",[])),
+no",".*\\.gif","JMhX&xE&hBl\\1Xk\\1R",[global])),
<<"borfle
-Nmmq
+riUNlLbib.giff
no">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".{0,}\\.gif","Nmmq",[global])),
+no",".{0,}\\.gif","riUNlL&f",[])),
<<"borfle
-BVKBwIDwbib.gifjgEqWxbib.gifEW
+riUNlLbib.giff
no">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*\\.gif","BVKBwIDw&jgEqW\\1x&EW",[multiline])),
+no",".{0,}\\.gif","riUNlL&f",[global])),
<<"borfle
-BVKBwIDwbib.gifjgEqWxbib.gifEW
+GuWxO
no">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*\\.gif","BVKBwIDw&jgEqW\\1x&EW",[multiline,global])),
+no",".*\\.gif","GuWxO",[multiline])),
<<"borfle
-bib.giffF
+GuWxO
no">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*\\.gif","&fF",[dotall])),
- <<"borfle
-bib.giffF
-no">> = iolist_to_binary(re:replace("borfle
-bib.gif
-no",".*\\.gif","&fF",[dotall,global])),
+no",".*\\.gif","GuWxO",[multiline,global])),
ok.
run9() ->
- <<"ARdLYmTSnXAA
+ <<"PMnborfle
+bib.gifborfle
+bib.gifPMt
no">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*\\.gif","AR\\1dLYmTSnXAA",[multiline,dotall])),
- <<"ARdLYmTSnXAA
+no",".*\\.gif","PMn&&PMt",[dotall])),
+ <<"PMnborfle
+bib.gifborfle
+bib.gifPMt
no">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*\\.gif","AR\\1dLYmTSnXAA",[multiline,dotall,global])),
- <<"borfle
-bib.gif
-anoc">> = iolist_to_binary(re:replace("borfle
-bib.gif
-no",".*$","a&c",[])),
- <<"borfle
-bib.gif
-anocac">> = iolist_to_binary(re:replace("borfle
-bib.gif
-no",".*$","a&c",[global])),
- <<"fborfleDas
+no",".*\\.gif","PMn&&PMt",[dotall,global])),
+ <<"rxywwborfle
bib.gif
no">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","f&Das",[multiline])),
- <<"fborfleDasfDas
-fbib.gifDasfDas
-fnoDasfDas">> = iolist_to_binary(re:replace("borfle
-bib.gif
-no",".*$","f&Das",[multiline,global])),
- <<"eUveborfle
+no",".*\\.gif","rx\\1\\1yww&",[multiline,dotall])),
+ <<"rxywwborfle
bib.gif
-nopjBhborfle
-bib.gif
-noEXborfle
-bib.gif
-nodborfle
-bib.gif
-noiGXw">> = iolist_to_binary(re:replace("borfle
+no">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","eUve&pjBh&EX&d&iGXw",[dotall])),
- <<"eUveborfle
+no",".*\\.gif","rx\\1\\1yww&",[multiline,dotall,global])),
+ <<"borfle
bib.gif
-nopjBhborfle
+fEMAOjEdetPXRnocBSck">> = iolist_to_binary(re:replace("borfle
bib.gif
-noEXborfle
+no",".*$","fEMAOjEdetPXR&cBSck",[])),
+ <<"borfle
bib.gif
-nodborfle
+fEMAOjEdetPXRnocBSckfEMAOjEdetPXRcBSck">> = iolist_to_binary(re:replace("borfle
bib.gif
-noiGXweUvepjBhEXdiGXw">> = iolist_to_binary(re:replace("borfle
+no",".*$","fEMAOjEdetPXR&cBSck",[global])),
+ <<"FdiFlvyqFlWRsa
bib.gif
-no",".*$","eUve&pjBh&EX&d&iGXw",[dotall,global])),
- <<"RIMAHborfle
+no">> = iolist_to_binary(re:replace("borfle
bib.gif
-norborfle
+no",".*$","\\1FdiFlvyqFlW\\1Rsa",[multiline])),
+ <<"FdiFlvyqFlWRsaFdiFlvyqFlWRsa
+FdiFlvyqFlWRsaFdiFlvyqFlWRsa
+FdiFlvyqFlWRsaFdiFlvyqFlWRsa">> = iolist_to_binary(re:replace("borfle
bib.gif
-no">> = iolist_to_binary(re:replace("borfle
+no",".*$","\\1FdiFlvyqFlW\\1Rsa",[multiline,global])),
+ <<"n">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","R\\1IMAH&\\1r&",[multiline,dotall])),
- <<"RIMAHborfle
+no",".*$","n",[dotall])),
+ <<"nn">> = iolist_to_binary(re:replace("borfle
bib.gif
-norborfle
+no",".*$","n",[dotall,global])),
+ <<"xbTBQedCtvvd">> = iolist_to_binary(re:replace("borfle
bib.gif
-noRIMAHr">> = iolist_to_binary(re:replace("borfle
+no",".*$","xbTBQe\\1dCtvvd",[multiline,dotall])),
+ <<"xbTBQedCtvvdxbTBQedCtvvd">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","R\\1IMAH&\\1r&",[multiline,dotall,global])),
+no",".*$","xbTBQe\\1dCtvvd",[multiline,dotall,global])),
<<"borfle
bib.gif
-IXHXnoNO">> = iolist_to_binary(re:replace("borfle
+snononoKyt">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","IXHX&NO",[])),
+no",".*$","s&&&Kyt",[])),
<<"borfle
bib.gif
-IXHXnoNOIXHXNO">> = iolist_to_binary(re:replace("borfle
+snononoKytsKyt">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","IXHX&NO",[global])),
- <<"iGCnBCJborfleUborflenLutTYS
+no",".*$","s&&&Kyt",[global])),
+ <<"BrborflevYCe
bib.gif
no">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","\\1iGCnBC\\1J&U&nL\\1utTYS",[multiline])),
- <<"iGCnBCJborfleUborflenLutTYSiGCnBCJUnLutTYS
-iGCnBCJbib.gifUbib.gifnLutTYSiGCnBCJUnLutTYS
-iGCnBCJnoUnonLutTYSiGCnBCJUnLutTYS">> = iolist_to_binary(re:replace("borfle
+no",".*$","Br&vYCe",[multiline])),
+ <<"BrborflevYCeBrvYCe
+Brbib.gifvYCeBrvYCe
+BrnovYCeBrvYCe">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","\\1iGCnBC\\1J&U&nL\\1utTYS",[multiline,global])),
- <<"dkaborfle
+no",".*$","Br&vYCe",[multiline,global])),
+ <<"gborfle
bib.gif
-nocxpCSRwborfle
+noPQFusOgmXaynmLborfle
bib.gif
-noJQHcx">> = iolist_to_binary(re:replace("borfle
+noS">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","dka&cxpCSRw&JQ\\1Hc\\1x",[dotall])),
- <<"dkaborfle
+no",".*$","g&PQFusOgmXayn\\1mL&S",[dotall])),
+ <<"gborfle
bib.gif
-nocxpCSRwborfle
+noPQFusOgmXaynmLborfle
bib.gif
-noJQHcxdkacxpCSRwJQHcx">> = iolist_to_binary(re:replace("borfle
+noSgPQFusOgmXaynmLS">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","dka&cxpCSRw&JQ\\1Hc\\1x",[dotall,global])),
- <<"tnQDxLEhTFjTiWwouU">> = iolist_to_binary(re:replace("borfle
+no",".*$","g&PQFusOgmXayn\\1mL&S",[dotall,global])),
+ <<"yVEV">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","tnQDxLEhTF\\1jTiWwouU",[multiline,dotall])),
- <<"tnQDxLEhTFjTiWwouUtnQDxLEhTFjTiWwouU">> = iolist_to_binary(re:replace("borfle
+no",".*$","yVEV",[multiline,dotall])),
+ <<"yVEVyVEV">> = iolist_to_binary(re:replace("borfle
bib.gif
-no",".*$","tnQDxLEhTF\\1jTiWwouU",[multiline,dotall,global])),
+no",".*$","yVEV",[multiline,dotall,global])),
<<"abcde
-fSiqVi1234Xw1234XWyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(.*X|^B)","fSiqVi&w\\1W",[])),
+1234XP1234Xyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(.*X|^B)","\\1P&",[])),
<<"abcde
-fSiqVi1234Xw1234XWyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(.*X|^B)","fSiqVi&w\\1W",[global])),
- <<"apCVoPCVMeDBpBBarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","apCVoPCVMeD&p\\1&",[])),
- <<"apCVoPCVMeDBpBBarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","apCVoPCVMeD&p\\1&",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(.*X|^B)","FiTmKNSyXk",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(.*X|^B)","FiTmKNSyXk",[global])),
+1234XP1234Xyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(.*X|^B)","\\1P&",[global])),
+ <<"qarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","q",[])),
+ <<"qarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","q",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(.*X|^B)","&PNmWin\\1XCGPwUmQi",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(.*X|^B)","&PNmWin\\1XCGPwUmQi",[global])),
<<"abcde
Bar">> = iolist_to_binary(re:replace("abcde
Bar","(.*X|^B)","&",[])),
@@ -15514,2627 +15499,2637 @@ Bar","(.*X|^B)","&",[])),
Bar">> = iolist_to_binary(re:replace("abcde
Bar","(.*X|^B)","&",[global])),
<<"abcde
-1234XY1234X1234X1234XiJfcfLjk1234Xyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(.*X|^B)","&Y\\1\\1\\1iJfcfLjk\\1",[multiline])),
+1234Xk1234XSbVXyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(.*X|^B)","\\1k&SbVX",[multiline])),
<<"abcde
-1234XY1234X1234X1234XiJfcfLjk1234Xyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(.*X|^B)","&Y\\1\\1\\1iJfcfLjk\\1",[multiline,global])),
- <<"BUrWBJarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","&UrW\\1J",[multiline])),
- <<"BUrWBJarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","&UrW\\1J",[multiline,
- global])),
+1234Xk1234XSbVXyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(.*X|^B)","\\1k&SbVX",[multiline,global])),
+ <<"BLBjHdCBpTarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","BL\\1jHdC&pT",[multiline])),
+ <<"BLBjHdCBpTarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","BL\\1jHdC&pT",[multiline,
+ global])),
<<"abcde
-vpiar">> = iolist_to_binary(re:replace("abcde
-Bar","(.*X|^B)","vpi",[multiline])),
+AOBrLBaBuLgKctar">> = iolist_to_binary(re:replace("abcde
+Bar","(.*X|^B)","AO&rL\\1a&uLgKct",[multiline])),
<<"abcde
-vpiar">> = iolist_to_binary(re:replace("abcde
-Bar","(.*X|^B)","vpi",[multiline,global])),
+AOBrLBaBuLgKctar">> = iolist_to_binary(re:replace("abcde
+Bar","(.*X|^B)","AO&rL\\1a&uLgKct",[multiline,global])),
+ <<"IhhXeabcde
+1234Xyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(.*X|^B)","IhhXe\\1",[dotall])),
+ <<"IhhXeabcde
+1234Xyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(.*X|^B)","IhhXe\\1",[dotall,global])),
+ <<"NfmmMjBGBBShBiBBqABfarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","NfmmMj\\1G&&Sh\\1i&&qA\\1f",[dotall])),
+ <<"NfmmMjBGBBShBiBBqABfarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","NfmmMj\\1G&&Sh\\1i&&qA\\1f",[dotall,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(.*X|^B)","fDWQoN&&DK\\1X\\1QE&hqEG",[dotall])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(.*X|^B)","fDWQoN&&DK\\1X\\1QE&hqEG",[dotall,
+ global])),
<<"abcde
-1234Xabcde
-1234Xabcde
-1234XOwvyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(.*X|^B)","\\1\\1&Owv",[dotall])),
+Bar">> = iolist_to_binary(re:replace("abcde
+Bar","(.*X|^B)","sSxs",[dotall])),
<<"abcde
+Bar">> = iolist_to_binary(re:replace("abcde
+Bar","(.*X|^B)","sSxs",[dotall,global])),
+ <<"svIYJDEofMMvabcde
+1234XDCabcde
+1234Xeabcde
1234Xabcde
+1234Xyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(.*X|^B)","svIYJDEofMMv&DC\\1e&\\1",[multiline,dotall])),
+ <<"svIYJDEofMMvabcde
+1234XDCabcde
+1234Xeabcde
1234Xabcde
-1234XOwvyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(.*X|^B)","\\1\\1&Owv",[dotall,global])),
- <<"csBOSrLyBynarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","cs\\1OSrLy\\1yn",[dotall])),
- <<"csBOSrLyBynarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","cs\\1OSrLy\\1yn",[dotall,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(.*X|^B)","\\1qVOKf\\1jqa",[dotall])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(.*X|^B)","\\1qVOKf\\1jqa",[dotall,
+1234Xyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(.*X|^B)","svIYJDEofMMv&DC\\1e&\\1",[multiline,dotall,
+ global])),
+ <<"APkjMTOkxTRvMqaBjpxarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","APkjMTOkxTRvMqa&jpx",[multiline,
+ dotall])),
+ <<"APkjMTOkxTRvMqaBjpxarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","APkjMTOkxTRvMqa&jpx",[multiline,
+ dotall,
global])),
<<"abcde
-Bar">> = iolist_to_binary(re:replace("abcde
-Bar","(.*X|^B)","p",[dotall])),
- <<"abcde
-Bar">> = iolist_to_binary(re:replace("abcde
-Bar","(.*X|^B)","p",[dotall,global])),
- <<"YiHiyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(.*X|^B)","YiHi",[multiline,dotall])),
- <<"YiHiyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(.*X|^B)","YiHi",[multiline,dotall,global])),
- <<"DDQRgXBHBBSBcHarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","DDQRgXBH&&S\\1cH",[multiline,
- dotall])),
- <<"DDQRgXBHBBSBcHarFoo">> = iolist_to_binary(re:replace("BarFoo","(.*X|^B)","DDQRgXBH&&S\\1cH",[multiline,
- dotall,
- global])),
- <<"abcde
-KTLNdCWtmar">> = iolist_to_binary(re:replace("abcde
-Bar","(.*X|^B)","KTLNdCWtm",[multiline,dotall])),
+gLgBDTusNbxpABaVxar">> = iolist_to_binary(re:replace("abcde
+Bar","(.*X|^B)","gLg\\1DTusNbxpA\\1aVx",[multiline,dotall])),
<<"abcde
-KTLNdCWtmar">> = iolist_to_binary(re:replace("abcde
-Bar","(.*X|^B)","KTLNdCWtm",[multiline,dotall,global])),
- <<"UnqSIGfraCIjabcde
-1234Xlyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(?s)(.*X|^B)","UnqSIGfraCIj&l",[])),
- <<"UnqSIGfraCIjabcde
-1234Xlyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(?s)(.*X|^B)","UnqSIGfraCIj&l",[global])),
- <<"aDBarFoo">> = iolist_to_binary(re:replace("BarFoo","(?s)(.*X|^B)","aDB",[])),
- <<"aDBarFoo">> = iolist_to_binary(re:replace("BarFoo","(?s)(.*X|^B)","aDB",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s)(.*X|^B)","hbfv",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s)(.*X|^B)","hbfv",[global])),
+gLgBDTusNbxpABaVxar">> = iolist_to_binary(re:replace("abcde
+Bar","(.*X|^B)","gLg\\1DTusNbxpA\\1aVx",[multiline,dotall,global])),
+ <<"jvVabcde
+1234XIabcde
+1234XLsYyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(?s)(.*X|^B)","jvV\\1I&LsY",[])),
+ <<"jvVabcde
+1234XIabcde
+1234XLsYyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(?s)(.*X|^B)","jvV\\1I&LsY",[global])),
+ <<"TlTBebymLLEyQBarFoo">> = iolist_to_binary(re:replace("BarFoo","(?s)(.*X|^B)","TlT\\1ebymLLEyQ\\1",[])),
+ <<"TlTBebymLLEyQBarFoo">> = iolist_to_binary(re:replace("BarFoo","(?s)(.*X|^B)","TlT\\1ebymLLEyQ\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s)(.*X|^B)","jrpMnKp\\1&LavAr&vf\\1o",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s)(.*X|^B)","jrpMnKp\\1&LavAr&vf\\1o",[global])),
<<"abcde
Bar">> = iolist_to_binary(re:replace("abcde
-Bar","(?s)(.*X|^B)","&UWQV\\1&\\1\\1E",[])),
+Bar","(?s)(.*X|^B)","MB\\1k&&iuX\\1\\1\\1DJKoRl",[])),
<<"abcde
Bar">> = iolist_to_binary(re:replace("abcde
-Bar","(?s)(.*X|^B)","&UWQV\\1&\\1\\1E",[global])),
- <<"KYpUjyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(?s:.*X|^B)","KY\\1\\1pUj\\1",[])),
- <<"KYpUjyz">> = iolist_to_binary(re:replace("abcde
-1234Xyz","(?s:.*X|^B)","KY\\1\\1pUj\\1",[global])),
- <<"BSkyfarFoo">> = iolist_to_binary(re:replace("BarFoo","(?s:.*X|^B)","\\1BSk\\1y\\1\\1f",[])),
- <<"BSkyfarFoo">> = iolist_to_binary(re:replace("BarFoo","(?s:.*X|^B)","\\1BSk\\1y\\1\\1f",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s:.*X|^B)","IG\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s:.*X|^B)","IG\\1",[global])),
+Bar","(?s)(.*X|^B)","MB\\1k&&iuX\\1\\1\\1DJKoRl",[global])),
+ <<"rPUccTvabcde
+1234XyMyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(?s:.*X|^B)","rPUccT\\1v&yM",[])),
+ <<"rPUccTvabcde
+1234XyMyz">> = iolist_to_binary(re:replace("abcde
+1234Xyz","(?s:.*X|^B)","rPUccT\\1v&yM",[global])),
+ <<"ybPFHwvSYTarFoo">> = iolist_to_binary(re:replace("BarFoo","(?s:.*X|^B)","y\\1bPF\\1HwvSYT",[])),
+ <<"ybPFHwvSYTarFoo">> = iolist_to_binary(re:replace("BarFoo","(?s:.*X|^B)","y\\1bPF\\1HwvSYT",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s:.*X|^B)","cM",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s:.*X|^B)","cM",[global])),
<<"abcde
Bar">> = iolist_to_binary(re:replace("abcde
-Bar","(?s:.*X|^B)","&OchEkLBdrDrxVm&",[])),
+Bar","(?s:.*X|^B)","YwekY\\1N&cbCoStuYolo",[])),
<<"abcde
Bar">> = iolist_to_binary(re:replace("abcde
-Bar","(?s:.*X|^B)","&OchEkLBdrDrxVm&",[global])),
- <<"**** Failers">> = iolist_to_binary(re:replace("**** Failers","^.*B","cYoDF\\1rwds&i&y&&XoFT",[])),
- <<"**** Failers">> = iolist_to_binary(re:replace("**** Failers","^.*B","cYoDF\\1rwds&i&y&&XoFT",[global])),
+Bar","(?s:.*X|^B)","YwekY\\1N&cbCoStuYolo",[global])),
+ <<"**** Failers">> = iolist_to_binary(re:replace("**** Failers","^.*B","Sf",[])),
+ <<"**** Failers">> = iolist_to_binary(re:replace("**** Failers","^.*B","Sf",[global])),
<<"abc
B">> = iolist_to_binary(re:replace("abc
-B","^.*B","gXmgvN\\1oh",[])),
+B","^.*B","&uu\\1L\\1JdE",[])),
<<"abc
B">> = iolist_to_binary(re:replace("abc
-B","^.*B","gXmgvN\\1oh",[global])),
- <<"EQuXabc
-Babc
-BcTMO">> = iolist_to_binary(re:replace("abc
-B","(?s)^.*B","EQuX&&\\1cTMO",[])),
- <<"EQuXabc
-Babc
-BcTMO">> = iolist_to_binary(re:replace("abc
-B","(?s)^.*B","EQuX&&\\1cTMO",[global])),
- <<"abc
-gtvPyITnci">> = iolist_to_binary(re:replace("abc
-B","(?m)^.*B","\\1gtvPyIT\\1\\1nci\\1",[])),
+B","^.*B","&uu\\1L\\1JdE",[global])),
+ <<"vveCq">> = iolist_to_binary(re:replace("abc
+B","(?s)^.*B","vveC\\1q\\1",[])),
+ <<"vveCq">> = iolist_to_binary(re:replace("abc
+B","(?s)^.*B","vveC\\1q\\1",[global])),
<<"abc
-gtvPyITnci">> = iolist_to_binary(re:replace("abc
-B","(?m)^.*B","\\1gtvPyIT\\1\\1nci\\1",[global])),
- <<"Xiabc
-BFQs">> = iolist_to_binary(re:replace("abc
-B","(?ms)^.*B","Xi&FQs",[])),
- <<"Xiabc
-BFQs">> = iolist_to_binary(re:replace("abc
-B","(?ms)^.*B","Xi&FQs",[global])),
+AIykFFUtx">> = iolist_to_binary(re:replace("abc
+B","(?m)^.*B","AIykFFUtx",[])),
<<"abc
-KEQlgWBJydBXBMDBU">> = iolist_to_binary(re:replace("abc
-B","(?ms)^B","KEQlgW&Jy\\1d&X&\\1\\1MD&U",[])),
- <<"abc
-KEQlgWBJydBXBMDBU">> = iolist_to_binary(re:replace("abc
-B","(?ms)^B","KEQlgW&Jy\\1d&X&\\1\\1MD&U",[global])),
+AIykFFUtx">> = iolist_to_binary(re:replace("abc
+B","(?m)^.*B","AIykFFUtx",[global])),
+ <<"tmabc
+BkwwOabc
+B">> = iolist_to_binary(re:replace("abc
+B","(?ms)^.*B","tm&k\\1wwO\\1&",[])),
+ <<"tmabc
+BkwwOabc
+B">> = iolist_to_binary(re:replace("abc
+B","(?ms)^.*B","tm&k\\1wwO\\1&",[global])),
ok.
run10() ->
- <<"eucnXdJhktgj">> = iolist_to_binary(re:replace("B","(?s)B$","eucnXd\\1Jhktgj",[])),
- <<"eucnXdJhktgj">> = iolist_to_binary(re:replace("B","(?s)B$","eucnXd\\1Jhktgj",[global])),
- <<"huCb">> = iolist_to_binary(re:replace("123456654321","^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]","huCb",[])),
- <<"huCb">> = iolist_to_binary(re:replace("123456654321","^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]","huCb",[global])),
- <<"X123456654321">> = iolist_to_binary(re:replace("123456654321","^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d","X&",[])),
- <<"X123456654321">> = iolist_to_binary(re:replace("123456654321","^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d","X&",[global])),
- <<"TYfrdKv123456654321eOFnwwLVc">> = iolist_to_binary(re:replace("123456654321","^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]","TY\\1frdK\\1\\1v&eOFnwwLVc",[])),
- <<"TYfrdKv123456654321eOFnwwLVc">> = iolist_to_binary(re:replace("123456654321","^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]","TY\\1frdK\\1\\1v&eOFnwwLVc",[global])),
- <<"ARvxabcabcabcabcbhP">> = iolist_to_binary(re:replace("abcabcabcabc","^[abc]{12}","ARvx&bhP",[])),
- <<"ARvxabcabcabcabcbhP">> = iolist_to_binary(re:replace("abcabcabcabc","^[abc]{12}","ARvx&bhP",[global])),
- <<"VtabcabcabcabcaabcabcabcabcoPm">> = iolist_to_binary(re:replace("abcabcabcabc","^[a-c]{12}","V\\1t&a&oPm",[])),
- <<"VtabcabcabcabcaabcabcabcabcoPm">> = iolist_to_binary(re:replace("abcabcabcabc","^[a-c]{12}","V\\1t&a&oPm",[global])),
- <<"XSAxPcCWabcabcabcabccaabcabcabcabcC">> = iolist_to_binary(re:replace("abcabcabcabc","^(a|b|c){12}","XSAxPcCW&\\1a&C",[])),
- <<"XSAxPcCWabcabcabcabccaabcabcabcabcC">> = iolist_to_binary(re:replace("abcabcabcabc","^(a|b|c){12}","XSAxPcCW&\\1a&C",[global])),
- <<"KlnPsQA">> = iolist_to_binary(re:replace("n","^[abcdefghijklmnopqrstuvwxy0123456789]","Kl&\\1PsQA",[])),
- <<"KlnPsQA">> = iolist_to_binary(re:replace("n","^[abcdefghijklmnopqrstuvwxy0123456789]","Kl&\\1PsQA",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[abcdefghijklmnopqrstuvwxy0123456789]","\\1fJAGtEidKGXUnys",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[abcdefghijklmnopqrstuvwxy0123456789]","\\1fJAGtEidKGXUnys",[global])),
- <<"z">> = iolist_to_binary(re:replace("z","^[abcdefghijklmnopqrstuvwxy0123456789]","\\1rHkd&\\1jm&b&RxM\\1SHJ",[])),
- <<"z">> = iolist_to_binary(re:replace("z","^[abcdefghijklmnopqrstuvwxy0123456789]","\\1rHkd&\\1jm&b&RxM\\1SHJ",[global])),
- <<"imcGUm">> = iolist_to_binary(re:replace("abcd","abcde{0,0}","imcGUm",[])),
- <<"imcGUm">> = iolist_to_binary(re:replace("abcd","abcde{0,0}","imcGUm",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abcde{0,0}","Tqn",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abcde{0,0}","Tqn",[global])),
- <<"abce">> = iolist_to_binary(re:replace("abce","abcde{0,0}","&vfSkYqj",[])),
- <<"abce">> = iolist_to_binary(re:replace("abce","abcde{0,0}","&vfSkYqj",[global])),
- <<"DvcVJ">> = iolist_to_binary(re:replace("abe","ab[cd]{0,0}e","D\\1vc\\1VJ",[])),
- <<"DvcVJ">> = iolist_to_binary(re:replace("abe","ab[cd]{0,0}e","D\\1vc\\1VJ",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab[cd]{0,0}e","fqC",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab[cd]{0,0}e","fqC",[global])),
- <<"abcde">> = iolist_to_binary(re:replace("abcde","ab[cd]{0,0}e","EVGlB",[])),
- <<"abcde">> = iolist_to_binary(re:replace("abcde","ab[cd]{0,0}e","EVGlB",[global])),
- <<"ttqYHXMabdKMHbogw">> = iolist_to_binary(re:replace("abd","ab(c){0,0}d","ttqY\\1HXM&KMHbo\\1gw",[])),
- <<"ttqYHXMabdKMHbogw">> = iolist_to_binary(re:replace("abd","ab(c){0,0}d","ttqY\\1HXM&KMHbo\\1gw",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab(c){0,0}d","UO\\1n&&dgD&x&puRS\\1PEE",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab(c){0,0}d","UO\\1n&&dgD&x&puRS\\1PEE",[global])),
- <<"abcd">> = iolist_to_binary(re:replace("abcd","ab(c){0,0}d","AnMJgUHAxI\\1ekAaM",[])),
- <<"abcd">> = iolist_to_binary(re:replace("abcd","ab(c){0,0}d","AnMJgUHAxI\\1ekAaM",[global])),
- <<"OXylllC">> = iolist_to_binary(re:replace("a","a(b*)","OX\\1ylllC",[])),
- <<"OXylllC">> = iolist_to_binary(re:replace("a","a(b*)","OX\\1ylllC",[global])),
- <<"BDoOabpX">> = iolist_to_binary(re:replace("ab","a(b*)","BDoO&pX",[])),
- <<"BDoOabpX">> = iolist_to_binary(re:replace("ab","a(b*)","BDoO&pX",[global])),
- <<"WumvpDmPRlDEFbbbbbbbbw">> = iolist_to_binary(re:replace("abbbb","a(b*)","WumvpDmPRlDEF\\1\\1w",[])),
- <<"WumvpDmPRlDEFbbbbbbbbw">> = iolist_to_binary(re:replace("abbbb","a(b*)","WumvpDmPRlDEF\\1\\1w",[global])),
- <<"*** FXEpRailers">> = iolist_to_binary(re:replace("*** Failers","a(b*)","XEpR&",[])),
- <<"*** FXEpRailers">> = iolist_to_binary(re:replace("*** Failers","a(b*)","XEpR&",[global])),
- <<"bbbbb">> = iolist_to_binary(re:replace("bbbbb","a(b*)","oxX\\1mji\\1R&A",[])),
- <<"bbbbb">> = iolist_to_binary(re:replace("bbbbb","a(b*)","oxX\\1mji\\1R&A",[global])),
- <<"nabehjEWAKJbF">> = iolist_to_binary(re:replace("abe","ab\\d{0}e","n&hjEWA\\1\\1KJbF",[])),
- <<"nabehjEWAKJbF">> = iolist_to_binary(re:replace("abe","ab\\d{0}e","n&hjEWA\\1\\1KJbF",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab\\d{0}e","IK\\1nN\\1xr",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab\\d{0}e","IK\\1nN\\1xr",[global])),
- <<"ab1e">> = iolist_to_binary(re:replace("ab1e","ab\\d{0}e","S\\1HX\\1V\\1hjKR",[])),
- <<"ab1e">> = iolist_to_binary(re:replace("ab1e","ab\\d{0}e","S\\1HX\\1V\\1hjKR",[global])),
- <<"the quickf\"quick\"cqEH\"quick\"quickWsS brown fox">> = iolist_to_binary(re:replace("the \"quick\" brown fox","\"([^\\\\\"]+|\\\\.)*\"","\\1f&cqEH&\\1WsS",[])),
- <<"the quickf\"quick\"cqEH\"quick\"quickWsS brown fox">> = iolist_to_binary(re:replace("the \"quick\" brown fox","\"([^\\\\\"]+|\\\\.)*\"","\\1f&cqEH&\\1WsS",[global])),
- <<"mRaOvRxI">> = iolist_to_binary(re:replace("\"the \\\"quick\\\" brown fox\"","\"([^\\\\\"]+|\\\\.)*\"","mRaOvRxI",[])),
- <<"mRaOvRxI">> = iolist_to_binary(re:replace("\"the \\\"quick\\\" brown fox\"","\"([^\\\\\"]+|\\\\.)*\"","mRaOvRxI",[global])),
- <<"OVRmBCabc">> = iolist_to_binary(re:replace("abc","","OVR&m&BC",[])),
- <<"OVRmBCaOVRmBCbOVRmBCcOVRmBC">> = iolist_to_binary(re:replace("abc","","OVR&m&BC",[global])),
- <<"lMTacbbGqK">> = iolist_to_binary(re:replace("acb","a[^a]b","lMT&bGq\\1K",[])),
- <<"lMTacbbGqK">> = iolist_to_binary(re:replace("acb","a[^a]b","lMT&bGq\\1K",[global])),
- <<"a
-ba
-bLxcQMea
-bHjqB">> = iolist_to_binary(re:replace("a
-b","a[^a]b","\\1\\1&&LxcQMe&Hj\\1qB",[])),
- <<"a
-ba
-bLxcQMea
-bHjqB">> = iolist_to_binary(re:replace("a
-b","a[^a]b","\\1\\1&&LxcQMe&Hj\\1qB",[global])),
- <<"acbVVpcHAOaqv">> = iolist_to_binary(re:replace("acb","a.b","&VVpcHAOaqv",[])),
- <<"acbVVpcHAOaqv">> = iolist_to_binary(re:replace("acb","a.b","&VVpcHAOaqv",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a.b","rP",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a.b","rP",[global])),
+ <<"abc
+sIBCmqcRbBEopSkFr">> = iolist_to_binary(re:replace("abc
+B","(?ms)^B","sI&\\1CmqcRb&EopSkFr",[])),
+ <<"abc
+sIBCmqcRbBEopSkFr">> = iolist_to_binary(re:replace("abc
+B","(?ms)^B","sI&\\1CmqcRb&EopSkFr",[global])),
+ <<"cDRlERYdxLVljB">> = iolist_to_binary(re:replace("B","(?s)B$","cDRlERYdx\\1LVlj&\\1",[])),
+ <<"cDRlERYdxLVljB">> = iolist_to_binary(re:replace("B","(?s)B$","cDRlERYdx\\1LVlj&\\1",[global])),
+ <<"ojREj">> = iolist_to_binary(re:replace("123456654321","^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]","o\\1jREj",[])),
+ <<"ojREj">> = iolist_to_binary(re:replace("123456654321","^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]","o\\1jREj",[global])),
+ <<"123456654321el">> = iolist_to_binary(re:replace("123456654321","^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d","&\\1el",[])),
+ <<"123456654321el">> = iolist_to_binary(re:replace("123456654321","^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d","&\\1el",[global])),
+ <<"lb123456654321x123456654321V">> = iolist_to_binary(re:replace("123456654321","^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]","lb&x&V",[])),
+ <<"lb123456654321x123456654321V">> = iolist_to_binary(re:replace("123456654321","^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]","lb&x&V",[global])),
+ <<"XpabcabcabcabcAyWDhuR">> = iolist_to_binary(re:replace("abcabcabcabc","^[abc]{12}","Xp&Ay\\1WDhuR",[])),
+ <<"XpabcabcabcabcAyWDhuR">> = iolist_to_binary(re:replace("abcabcabcabc","^[abc]{12}","Xp&Ay\\1WDhuR",[global])),
+ <<"u">> = iolist_to_binary(re:replace("abcabcabcabc","^[a-c]{12}","u",[])),
+ <<"u">> = iolist_to_binary(re:replace("abcabcabcabc","^[a-c]{12}","u",[global])),
+ <<"xmIAabcabcabcabcacHwppQabcabcabcabccscvp">> = iolist_to_binary(re:replace("abcabcabcabc","^(a|b|c){12}","xmIA&a\\1HwppQ&cs\\1vp",[])),
+ <<"xmIAabcabcabcabcacHwppQabcabcabcabccscvp">> = iolist_to_binary(re:replace("abcabcabcabc","^(a|b|c){12}","xmIA&a\\1HwppQ&cs\\1vp",[global])),
+ <<"nDhnL">> = iolist_to_binary(re:replace("n","^[abcdefghijklmnopqrstuvwxy0123456789]","&Dh&L",[])),
+ <<"nDhnL">> = iolist_to_binary(re:replace("n","^[abcdefghijklmnopqrstuvwxy0123456789]","&Dh&L",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[abcdefghijklmnopqrstuvwxy0123456789]","TPu\\1&wb",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[abcdefghijklmnopqrstuvwxy0123456789]","TPu\\1&wb",[global])),
+ <<"z">> = iolist_to_binary(re:replace("z","^[abcdefghijklmnopqrstuvwxy0123456789]","OJhKNSyPeRoI&Wnp",[])),
+ <<"z">> = iolist_to_binary(re:replace("z","^[abcdefghijklmnopqrstuvwxy0123456789]","OJhKNSyPeRoI&Wnp",[global])),
+ <<"K">> = iolist_to_binary(re:replace("abcd","abcde{0,0}","K",[])),
+ <<"K">> = iolist_to_binary(re:replace("abcd","abcde{0,0}","K",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abcde{0,0}","E\\1\\1toPe\\1lGQK",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abcde{0,0}","E\\1\\1toPe\\1lGQK",[global])),
+ <<"abce">> = iolist_to_binary(re:replace("abce","abcde{0,0}","Ki&aBhP&lDx",[])),
+ <<"abce">> = iolist_to_binary(re:replace("abce","abcde{0,0}","Ki&aBhP&lDx",[global])),
+ <<"iQiLCUpSr">> = iolist_to_binary(re:replace("abe","ab[cd]{0,0}e","iQiLCUpSr",[])),
+ <<"iQiLCUpSr">> = iolist_to_binary(re:replace("abe","ab[cd]{0,0}e","iQiLCUpSr",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab[cd]{0,0}e","Hr&PimCU",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab[cd]{0,0}e","Hr&PimCU",[global])),
+ <<"abcde">> = iolist_to_binary(re:replace("abcde","ab[cd]{0,0}e","DC&KnrfLxyCvn&",[])),
+ <<"abcde">> = iolist_to_binary(re:replace("abcde","ab[cd]{0,0}e","DC&KnrfLxyCvn&",[global])),
+ <<"LabdiARUDvV">> = iolist_to_binary(re:replace("abd","ab(c){0,0}d","\\1L\\1\\1&iARUDvV",[])),
+ <<"LabdiARUDvV">> = iolist_to_binary(re:replace("abd","ab(c){0,0}d","\\1L\\1\\1&iARUDvV",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab(c){0,0}d","&\\1Mgf\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab(c){0,0}d","&\\1Mgf\\1",[global])),
+ <<"abcd">> = iolist_to_binary(re:replace("abcd","ab(c){0,0}d","&jO\\1aGGc",[])),
+ <<"abcd">> = iolist_to_binary(re:replace("abcd","ab(c){0,0}d","&jO\\1aGGc",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","a(b*)","&",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","a(b*)","&",[global])),
+ <<"tBTI">> = iolist_to_binary(re:replace("ab","a(b*)","tBTI",[])),
+ <<"tBTI">> = iolist_to_binary(re:replace("ab","a(b*)","tBTI",[global])),
+ <<"habbbbquabbbbbbbbabbbbmjPabbbbiabbbbqU">> = iolist_to_binary(re:replace("abbbb","a(b*)","h&qu&\\1&mjP&i&qU",[])),
+ <<"habbbbquabbbbbbbbabbbbmjPabbbbiabbbbqU">> = iolist_to_binary(re:replace("abbbb","a(b*)","h&qu&\\1&mjP&i&qU",[global])),
+ <<"*** FmYIhaIbaacAjQLailers">> = iolist_to_binary(re:replace("*** Failers","a(b*)","mYIhaIb&acAjQLa",[])),
+ <<"*** FmYIhaIbaacAjQLailers">> = iolist_to_binary(re:replace("*** Failers","a(b*)","mYIhaIb&acAjQLa",[global])),
+ <<"bbbbb">> = iolist_to_binary(re:replace("bbbbb","a(b*)","VG&iplC",[])),
+ <<"bbbbb">> = iolist_to_binary(re:replace("bbbbb","a(b*)","VG&iplC",[global])),
+ <<"al">> = iolist_to_binary(re:replace("abe","ab\\d{0}e","al",[])),
+ <<"al">> = iolist_to_binary(re:replace("abe","ab\\d{0}e","al",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab\\d{0}e","SDV\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab\\d{0}e","SDV\\1",[global])),
+ <<"ab1e">> = iolist_to_binary(re:replace("ab1e","ab\\d{0}e","C&p&eF\\1QF&mi\\1&",[])),
+ <<"ab1e">> = iolist_to_binary(re:replace("ab1e","ab\\d{0}e","C&p&eF\\1QF&mi\\1&",[global])),
+ <<"the LsC\"quick\"v\"quick\"NOdFhYFVvFQ brown fox">> = iolist_to_binary(re:replace("the \"quick\" brown fox","\"([^\\\\\"]+|\\\\.)*\"","LsC&v&NOdFhYFVvFQ",[])),
+ <<"the LsC\"quick\"v\"quick\"NOdFhYFVvFQ brown fox">> = iolist_to_binary(re:replace("the \"quick\" brown fox","\"([^\\\\\"]+|\\\\.)*\"","LsC&v&NOdFhYFVvFQ",[global])),
+ <<"Bymi\"the \\\"quick\\\" brown fox\"OuWN">> = iolist_to_binary(re:replace("\"the \\\"quick\\\" brown fox\"","\"([^\\\\\"]+|\\\\.)*\"","Bymi&OuWN",[])),
+ <<"Bymi\"the \\\"quick\\\" brown fox\"OuWN">> = iolist_to_binary(re:replace("\"the \\\"quick\\\" brown fox\"","\"([^\\\\\"]+|\\\\.)*\"","Bymi&OuWN",[global])),
+ <<"Cyabc">> = iolist_to_binary(re:replace("abc","","Cy",[])),
+ <<"CyaCybCycCy">> = iolist_to_binary(re:replace("abc","","Cy",[global])),
+ <<"cVsDacbW">> = iolist_to_binary(re:replace("acb","a[^a]b","\\1cVsD&W",[])),
+ <<"cVsDacbW">> = iolist_to_binary(re:replace("acb","a[^a]b","\\1cVsD&W",[global])),
+ <<"wa
+bojyKixPq">> = iolist_to_binary(re:replace("a
+b","a[^a]b","w&ojyKixPq",[])),
+ <<"wa
+bojyKixPq">> = iolist_to_binary(re:replace("a
+b","a[^a]b","w&ojyKixPq",[global])),
+ <<"DXPqrDQ">> = iolist_to_binary(re:replace("acb","a.b","\\1DX\\1Pqr\\1\\1DQ",[])),
+ <<"DXPqrDQ">> = iolist_to_binary(re:replace("acb","a.b","\\1DX\\1Pqr\\1\\1DQ",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a.b","x&dFsqqlLfIA",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a.b","x&dFsqqlLfIA",[global])),
<<"a
b">> = iolist_to_binary(re:replace("a
-b","a.b","rUNVcR\\1i\\1S",[])),
+b","a.b","P&jObNmClO",[])),
<<"a
b">> = iolist_to_binary(re:replace("a
-b","a.b","rUNVcR\\1i\\1S",[global])),
- <<"UHo">> = iolist_to_binary(re:replace("acb","a[^a]b","UHo",[dotall])),
- <<"UHo">> = iolist_to_binary(re:replace("acb","a[^a]b","UHo",[dotall,
- global])),
- <<"muQa
-bDGfm">> = iolist_to_binary(re:replace("a
-b","a[^a]b","muQ&DGfm",[dotall])),
- <<"muQa
-bDGfm">> = iolist_to_binary(re:replace("a
-b","a[^a]b","muQ&DGfm",[dotall,global])),
- <<"mPIfJVBacbQacbtacbVacb">> = iolist_to_binary(re:replace("acb","a.b","m\\1PIfJVB&Q&t\\1&V&",[dotall])),
- <<"mPIfJVBacbQacbtacbVacb">> = iolist_to_binary(re:replace("acb","a.b","m\\1PIfJVB&Q&t\\1&V&",[dotall,
- global])),
- <<"aNa
-bBIrkip">> = iolist_to_binary(re:replace("a
-b","a.b","aN&BIrkip",[dotall])),
- <<"aNa
-bBIrkip">> = iolist_to_binary(re:replace("a
-b","a.b","aN&BIrkip",[dotall,global])),
+b","a.b","P&jObNmClO",[global])),
+ <<"xacbpLkf">> = iolist_to_binary(re:replace("acb","a[^a]b","x&pLkf",[dotall])),
+ <<"xacbpLkf">> = iolist_to_binary(re:replace("acb","a[^a]b","x&pLkf",[dotall,
+ global])),
+ <<"FEa
+bcWUa
+bpdda
+ba
+bALbNurmn">> = iolist_to_binary(re:replace("a
+b","a[^a]b","FE&cWU&pdd&&ALbNurmn",[dotall])),
+ <<"FEa
+bcWUa
+bpdda
+ba
+bALbNurmn">> = iolist_to_binary(re:replace("a
+b","a[^a]b","FE&cWU&pdd&&ALbNurmn",[dotall,global])),
ok.
run11() ->
- <<"vhgx">> = iolist_to_binary(re:replace("bac","^(b+?|a){1,2}?c","vhgx",[])),
- <<"vhgx">> = iolist_to_binary(re:replace("bac","^(b+?|a){1,2}?c","vhgx",[global])),
- <<"ybvbbac">> = iolist_to_binary(re:replace("bbac","^(b+?|a){1,2}?c","ybv&",[])),
- <<"ybvbbac">> = iolist_to_binary(re:replace("bbac","^(b+?|a){1,2}?c","ybv&",[global])),
- <<"KDBmQaFUbbbbacKDvahagVH">> = iolist_to_binary(re:replace("bbbac","^(b+?|a){1,2}?c","KDBmQ\\1FUb&KDv\\1h\\1gVH",[])),
- <<"KDBmQaFUbbbbacKDvahagVH">> = iolist_to_binary(re:replace("bbbac","^(b+?|a){1,2}?c","KDBmQ\\1FUb&KDv\\1h\\1gVH",[global])),
- <<"uPboDyBKbbbbaccsL">> = iolist_to_binary(re:replace("bbbbac","^(b+?|a){1,2}?c","uPboDyBK&csL",[])),
- <<"uPboDyBKbbbbaccsL">> = iolist_to_binary(re:replace("bbbbac","^(b+?|a){1,2}?c","uPboDyBK&csL",[global])),
- <<"QeDbbbbbacbbbbbacXxKbbbbbacTlGRhFObbbbbaccF">> = iolist_to_binary(re:replace("bbbbbac","^(b+?|a){1,2}?c","QeD&&XxK&TlGRhFO&cF",[])),
- <<"QeDbbbbbacbbbbbacXxKbbbbbacTlGRhFObbbbbaccF">> = iolist_to_binary(re:replace("bbbbbac","^(b+?|a){1,2}?c","QeD&&XxK&TlGRhFO&cF",[global])),
- <<"bacUbacihaieDLiAIBbacGLD">> = iolist_to_binary(re:replace("bac","^(b+|a){1,2}?c","&U&ih\\1ieDLiAIB&GLD",[])),
- <<"bacUbacihaieDLiAIBbacGLD">> = iolist_to_binary(re:replace("bac","^(b+|a){1,2}?c","&U&ih\\1ieDLiAIB&GLD",[global])),
- <<"YFsyGywxuIMvbbacmaha">> = iolist_to_binary(re:replace("bbac","^(b+|a){1,2}?c","YFsyGywxuIMv&m\\1h\\1",[])),
- <<"YFsyGywxuIMvbbacmaha">> = iolist_to_binary(re:replace("bbac","^(b+|a){1,2}?c","YFsyGywxuIMv&m\\1h\\1",[global])),
- <<"qbbbacaLIOdWFbbbacbbbacJBItjgaqJ">> = iolist_to_binary(re:replace("bbbac","^(b+|a){1,2}?c","q&\\1LIOdWF&&JBItjg\\1qJ",[])),
- <<"qbbbacaLIOdWFbbbacbbbacJBItjgaqJ">> = iolist_to_binary(re:replace("bbbac","^(b+|a){1,2}?c","q&\\1LIOdWF&&JBItjg\\1qJ",[global])),
- <<"QqiEfi">> = iolist_to_binary(re:replace("bbbbac","^(b+|a){1,2}?c","QqiEfi",[])),
- <<"QqiEfi">> = iolist_to_binary(re:replace("bbbbac","^(b+|a){1,2}?c","QqiEfi",[global])),
- <<"YDPanLeWvajbbbbbacabnHyjk">> = iolist_to_binary(re:replace("bbbbbac","^(b+|a){1,2}?c","YDPanLeWv\\1j&\\1bnHyjk",[])),
- <<"YDPanLeWvajbbbbbacabnHyjk">> = iolist_to_binary(re:replace("bbbbbac","^(b+|a){1,2}?c","YDPanLeWv\\1j&\\1bnHyjk",[global])),
+ <<"GXcllkWrIacbBG">> = iolist_to_binary(re:replace("acb","a.b","\\1GXcllkWrI&\\1BG",[dotall])),
+ <<"GXcllkWrIacbBG">> = iolist_to_binary(re:replace("acb","a.b","\\1GXcllkWrI&\\1BG",[dotall,
+ global])),
+ <<"bmMeaNSa
+bVvJW">> = iolist_to_binary(re:replace("a
+b","a.b","bmMeaNS&VvJW",[dotall])),
+ <<"bmMeaNSa
+bVvJW">> = iolist_to_binary(re:replace("a
+b","a.b","bmMeaNS&VvJW",[dotall,global])),
+ <<"FabacNvbacaGaWYRb">> = iolist_to_binary(re:replace("bac","^(b+?|a){1,2}?c","F\\1&Nv&\\1G\\1WYRb",[])),
+ <<"FabacNvbacaGaWYRb">> = iolist_to_binary(re:replace("bac","^(b+?|a){1,2}?c","F\\1&Nv&\\1G\\1WYRb",[global])),
+ <<"WGbbacksaSqpuabXCRDoMob">> = iolist_to_binary(re:replace("bbac","^(b+?|a){1,2}?c","WG&ks\\1Sqpu\\1bXCRDoMob",[])),
+ <<"WGbbacksaSqpuabXCRDoMob">> = iolist_to_binary(re:replace("bbac","^(b+?|a){1,2}?c","WG&ks\\1Sqpu\\1bXCRDoMob",[global])),
+ <<"aya">> = iolist_to_binary(re:replace("bbbac","^(b+?|a){1,2}?c","\\1y\\1",[])),
+ <<"aya">> = iolist_to_binary(re:replace("bbbac","^(b+?|a){1,2}?c","\\1y\\1",[global])),
+ <<"bbbbacjqGxgxaVAbbbbacSKEda">> = iolist_to_binary(re:replace("bbbbac","^(b+?|a){1,2}?c","&jqGxgx\\1VA&SKEd\\1",[])),
+ <<"bbbbacjqGxgxaVAbbbbacSKEda">> = iolist_to_binary(re:replace("bbbbac","^(b+?|a){1,2}?c","&jqGxgx\\1VA&SKEd\\1",[global])),
+ <<"nCebbbbbacpljEau">> = iolist_to_binary(re:replace("bbbbbac","^(b+?|a){1,2}?c","nCe&pljE\\1u",[])),
+ <<"nCebbbbbacpljEau">> = iolist_to_binary(re:replace("bbbbbac","^(b+?|a){1,2}?c","nCe&pljE\\1u",[global])),
+ <<"aehaicAQxGvl">> = iolist_to_binary(re:replace("bac","^(b+|a){1,2}?c","\\1ehaicAQxGvl",[])),
+ <<"aehaicAQxGvl">> = iolist_to_binary(re:replace("bac","^(b+|a){1,2}?c","\\1ehaicAQxGvl",[global])),
+ <<"ggbbactWBanbbacPcVaBlWkC">> = iolist_to_binary(re:replace("bbac","^(b+|a){1,2}?c","gg&tWB\\1n&PcV\\1BlWkC",[])),
+ <<"ggbbactWBanbbacPcVaBlWkC">> = iolist_to_binary(re:replace("bbac","^(b+|a){1,2}?c","gg&tWB\\1n&PcV\\1BlWkC",[global])),
+ <<"bbbbacaRcabbbacS">> = iolist_to_binary(re:replace("bbbac","^(b+|a){1,2}?c","b&\\1Rc\\1&S",[])),
+ <<"bbbbacaRcabbbacS">> = iolist_to_binary(re:replace("bbbac","^(b+|a){1,2}?c","b&\\1Rc\\1&S",[global])),
+ <<"lrNbbbbacMarFghJVbbbbac">> = iolist_to_binary(re:replace("bbbbac","^(b+|a){1,2}?c","lrN&M\\1rFghJV&",[])),
+ <<"lrNbbbbacMarFghJVbbbbac">> = iolist_to_binary(re:replace("bbbbac","^(b+|a){1,2}?c","lrN&M\\1rFghJV&",[global])),
+ <<"aybajbbbbbacli">> = iolist_to_binary(re:replace("bbbbbac","^(b+|a){1,2}?c","\\1yb\\1j&li",[])),
+ <<"aybajbbbbbacli">> = iolist_to_binary(re:replace("bbbbbac","^(b+|a){1,2}?c","\\1yb\\1j&li",[global])),
<<"x
b">> = iolist_to_binary(re:replace("x
-b","(?!\\A)x","TB&e&lCSta",[multiline])),
+b","(?!\\A)x","qdtT&xXSc",[multiline])),
<<"x
b">> = iolist_to_binary(re:replace("x
-b","(?!\\A)x","TB&e&lCSta",[multiline,global])),
- <<"axHTxRqfqP">> = iolist_to_binary(re:replace("ax","(?!\\A)x","&HT&\\1Rq\\1fqP",[multiline])),
- <<"axHTxRqfqP">> = iolist_to_binary(re:replace("ax","(?!\\A)x","&HT&\\1Rq\\1fqP",[multiline,
- global])),
- <<"{ab}">> = iolist_to_binary(re:replace("{ab}","\\x0{ab}","nqnNdxgun\\1T",[])),
- <<"{ab}">> = iolist_to_binary(re:replace("{ab}","\\x0{ab}","nqnNdxgun\\1T",[global])),
- <<"OrUCDJnCTtDo">> = iolist_to_binary(re:replace("CD","(A|B)*?CD","OrU&J\\1nCTtDo",[])),
- <<"OrUCDJnCTtDo">> = iolist_to_binary(re:replace("CD","(A|B)*?CD","OrU&J\\1nCTtDo",[global])),
- <<"MkLtcbirH">> = iolist_to_binary(re:replace("CD","(A|B)*CD","MkLtcbirH",[])),
- <<"MkLtcbirH">> = iolist_to_binary(re:replace("CD","(A|B)*CD","MkLtcbirH",[global])),
- <<"ABABrABABomDFFpAABABSfrABGABVAB">> = iolist_to_binary(re:replace("ABABAB","(AB)*?\\1","\\1\\1r&omDFFpA&Sfr\\1G\\1V",[])),
- <<"ABABrABABomDFFpAABABSfrABGABVAB">> = iolist_to_binary(re:replace("ABABAB","(AB)*?\\1","\\1\\1r&omDFFpA&Sfr\\1G\\1V",[global])),
- <<"NpABABABGmqeABABABABrmlyABABABdq">> = iolist_to_binary(re:replace("ABABAB","(AB)*\\1","Np&Gmqe\\1&rmly&dq",[])),
- <<"NpABABABGmqeABABABABrmlyABABABdq">> = iolist_to_binary(re:replace("ABABAB","(AB)*\\1","Np&Gmqe\\1&rmly&dq",[global])),
- <<"qRqrQeDLnUtUIooiI">> = iolist_to_binary(re:replace("foo","(?<!bar)foo","q\\1RqrQeDLn\\1UtUIoo\\1iI",[])),
- <<"qRqrQeDLnUtUIooiI">> = iolist_to_binary(re:replace("foo","(?<!bar)foo","q\\1RqrQeDLn\\1UtUIoo\\1iI",[global])),
- <<"catOdXBXoDHfooHbldUpfood">> = iolist_to_binary(re:replace("catfood","(?<!bar)foo","OdXBXoDH&HbldUp&",[])),
- <<"catOdXBXoDHfooHbldUpfood">> = iolist_to_binary(re:replace("catfood","(?<!bar)foo","OdXBXoDH&HbldUp&",[global])),
- <<"arDtle">> = iolist_to_binary(re:replace("arfootle","(?<!bar)foo","D",[])),
- <<"arDtle">> = iolist_to_binary(re:replace("arfootle","(?<!bar)foo","D",[global])),
- <<"rYPYoYugCsh">> = iolist_to_binary(re:replace("rfoosh","(?<!bar)foo","YPYoYug\\1C",[])),
- <<"rYPYoYugCsh">> = iolist_to_binary(re:replace("rfoosh","(?<!bar)foo","YPYoYug\\1C",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<!bar)foo","i",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<!bar)foo","i",[global])),
- <<"barfoo">> = iolist_to_binary(re:replace("barfoo","(?<!bar)foo","cbUElrx&&\\1\\1YM\\1aBcUl",[])),
- <<"barfoo">> = iolist_to_binary(re:replace("barfoo","(?<!bar)foo","cbUElrx&&\\1\\1YM\\1aBcUl",[global])),
- <<"towbarfoo">> = iolist_to_binary(re:replace("towbarfoo","(?<!bar)foo","saPM\\1\\1OgLT\\1h\\1KWyOtmQ",[])),
- <<"towbarfoo">> = iolist_to_binary(re:replace("towbarfoo","(?<!bar)foo","saPM\\1\\1OgLT\\1h\\1KWyOtmQ",[global])),
- <<"EPmld">> = iolist_to_binary(re:replace("catfood","\\w{3}(?<!bar)foo","EPml",[])),
- <<"EPmld">> = iolist_to_binary(re:replace("catfood","\\w{3}(?<!bar)foo","EPml",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\w{3}(?<!bar)foo","MhJ&dGwUuIb\\1JIoqE",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\w{3}(?<!bar)foo","MhJ&dGwUuIb\\1JIoqE",[global])),
- <<"foo">> = iolist_to_binary(re:replace("foo","\\w{3}(?<!bar)foo","&wjHKW&gb",[])),
- <<"foo">> = iolist_to_binary(re:replace("foo","\\w{3}(?<!bar)foo","&wjHKW&gb",[global])),
- <<"barfoo">> = iolist_to_binary(re:replace("barfoo","\\w{3}(?<!bar)foo","B",[])),
- <<"barfoo">> = iolist_to_binary(re:replace("barfoo","\\w{3}(?<!bar)foo","B",[global])),
- <<"towbarfoo">> = iolist_to_binary(re:replace("towbarfoo","\\w{3}(?<!bar)foo","Jspqw\\1R\\1ldUs",[])),
- <<"towbarfoo">> = iolist_to_binary(re:replace("towbarfoo","\\w{3}(?<!bar)foo","Jspqw\\1R\\1ldUs",[global])),
- <<"fooarfooVALbarfooUbfooCrGfoobarhbarlfu">> = iolist_to_binary(re:replace("fooabar","(?<=(foo)a)bar","r\\1VAL&\\1Ub\\1CrG\\1&h&lfu",[])),
- <<"fooarfooVALbarfooUbfooCrGfoobarhbarlfu">> = iolist_to_binary(re:replace("fooabar","(?<=(foo)a)bar","r\\1VAL&\\1Ub\\1CrG\\1&h&lfu",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(foo)a)bar","Xup&&F\\1h\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(foo)a)bar","Xup&&F\\1h\\1",[global])),
- <<"bar">> = iolist_to_binary(re:replace("bar","(?<=(foo)a)bar","IyyUVRu\\1&J&EmI&",[])),
- <<"bar">> = iolist_to_binary(re:replace("bar","(?<=(foo)a)bar","IyyUVRu\\1&J&EmI&",[global])),
- <<"foobbar">> = iolist_to_binary(re:replace("foobbar","(?<=(foo)a)bar","yUdI",[])),
- <<"foobbar">> = iolist_to_binary(re:replace("foobbar","(?<=(foo)a)bar","yUdI",[global])),
- <<"TjyabckVlQOnp">> = iolist_to_binary(re:replace("abc","\\Aabc\\z","Tjy&kVlQOnp",[multiline])),
- <<"TjyabckVlQOnp">> = iolist_to_binary(re:replace("abc","\\Aabc\\z","Tjy&kVlQOnp",[multiline,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Aabc\\z","jAW\\1V&Gcxh&iaRsV\\1",[multiline])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Aabc\\z","jAW\\1V&Gcxh&iaRsV\\1",[multiline,
- global])),
- <<"xQWabcHT">> = iolist_to_binary(re:replace("abc","\\Aabc\\z","\\1xQW&H\\1T",[multiline])),
- <<"xQWabcHT">> = iolist_to_binary(re:replace("abc","\\Aabc\\z","\\1xQW&H\\1T",[multiline,
- global])),
+b","(?!\\A)x","qdtT&xXSc",[multiline,global])),
+ <<"axa">> = iolist_to_binary(re:replace("ax","(?!\\A)x","&a",[multiline])),
+ <<"axa">> = iolist_to_binary(re:replace("ax","(?!\\A)x","&a",[multiline,
+ global])),
+ <<"{ab}">> = iolist_to_binary(re:replace("{ab}","\\x0{ab}","&aQi\\1rM&TR&\\1e",[])),
+ <<"{ab}">> = iolist_to_binary(re:replace("{ab}","\\x0{ab}","&aQi\\1rM&TR&\\1e",[global])),
+ <<"KNDG">> = iolist_to_binary(re:replace("CD","(A|B)*?CD","K\\1NDG",[])),
+ <<"KNDG">> = iolist_to_binary(re:replace("CD","(A|B)*?CD","K\\1NDG",[global])),
+ <<"AgdCDyU">> = iolist_to_binary(re:replace("CD","(A|B)*CD","Agd&\\1yU",[])),
+ <<"AgdCDyU">> = iolist_to_binary(re:replace("CD","(A|B)*CD","Agd&\\1yU",[global])),
+ <<"KNLvABjABABKKABABAB">> = iolist_to_binary(re:replace("ABABAB","(AB)*?\\1","KNLv\\1j&KK&",[])),
+ <<"KNLvABjABABKKABABAB">> = iolist_to_binary(re:replace("ABABAB","(AB)*?\\1","KNLv\\1j&KK&",[global])),
+ <<"GnM">> = iolist_to_binary(re:replace("ABABAB","(AB)*\\1","GnM",[])),
+ <<"GnM">> = iolist_to_binary(re:replace("ABABAB","(AB)*\\1","GnM",[global])),
+ <<"fooRBfoomXVc">> = iolist_to_binary(re:replace("foo","(?<!bar)foo","&RB&mXVc",[])),
+ <<"fooRBfoomXVc">> = iolist_to_binary(re:replace("foo","(?<!bar)foo","&RB&mXVc",[global])),
+ <<"catjWUnJUSd">> = iolist_to_binary(re:replace("catfood","(?<!bar)foo","jWUnJUS",[])),
+ <<"catjWUnJUSd">> = iolist_to_binary(re:replace("catfood","(?<!bar)foo","jWUnJUS",[global])),
+ <<"arPgBuMtle">> = iolist_to_binary(re:replace("arfootle","(?<!bar)foo","PgBuM",[])),
+ <<"arPgBuMtle">> = iolist_to_binary(re:replace("arfootle","(?<!bar)foo","PgBuM",[global])),
+ <<"rfoorKCsmwsrXilqsh">> = iolist_to_binary(re:replace("rfoosh","(?<!bar)foo","&rKCsmwsrXilq",[])),
+ <<"rfoorKCsmwsrXilqsh">> = iolist_to_binary(re:replace("rfoosh","(?<!bar)foo","&rKCsmwsrXilq",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<!bar)foo","\\1aT&&Wgmx",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<!bar)foo","\\1aT&&Wgmx",[global])),
+ <<"barfoo">> = iolist_to_binary(re:replace("barfoo","(?<!bar)foo","ljtkcC",[])),
+ <<"barfoo">> = iolist_to_binary(re:replace("barfoo","(?<!bar)foo","ljtkcC",[global])),
+ <<"towbarfoo">> = iolist_to_binary(re:replace("towbarfoo","(?<!bar)foo","&&\\1Tmj\\1aBVw&Su\\1nww\\1",[])),
+ <<"towbarfoo">> = iolist_to_binary(re:replace("towbarfoo","(?<!bar)foo","&&\\1Tmj\\1aBVw&Su\\1nww\\1",[global])),
+ <<"ogelleKhJPBRcatfooBpBd">> = iolist_to_binary(re:replace("catfood","\\w{3}(?<!bar)foo","ogel\\1leKhJPBR\\1&B\\1pB",[])),
+ <<"ogelleKhJPBRcatfooBpBd">> = iolist_to_binary(re:replace("catfood","\\w{3}(?<!bar)foo","ogel\\1leKhJPBR\\1&B\\1pB",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\w{3}(?<!bar)foo","DfK&xr&sMv&&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\w{3}(?<!bar)foo","DfK&xr&sMv&&",[global])),
+ <<"foo">> = iolist_to_binary(re:replace("foo","\\w{3}(?<!bar)foo","&DDDKoimlSswYrm&w",[])),
+ <<"foo">> = iolist_to_binary(re:replace("foo","\\w{3}(?<!bar)foo","&DDDKoimlSswYrm&w",[global])),
+ <<"barfoo">> = iolist_to_binary(re:replace("barfoo","\\w{3}(?<!bar)foo","iBoc&&NxWYj\\1xympSmB",[])),
+ <<"barfoo">> = iolist_to_binary(re:replace("barfoo","\\w{3}(?<!bar)foo","iBoc&&NxWYj\\1xympSmB",[global])),
+ <<"towbarfoo">> = iolist_to_binary(re:replace("towbarfoo","\\w{3}(?<!bar)foo","u&dq&",[])),
+ <<"towbarfoo">> = iolist_to_binary(re:replace("towbarfoo","\\w{3}(?<!bar)foo","u&dq&",[global])),
+ <<"fooalCkfooPbarqRySQfoobarYHrF">> = iolist_to_binary(re:replace("fooabar","(?<=(foo)a)bar","lCk\\1P&qRySQ\\1&YHrF",[])),
+ <<"fooalCkfooPbarqRySQfoobarYHrF">> = iolist_to_binary(re:replace("fooabar","(?<=(foo)a)bar","lCk\\1P&qRySQ\\1&YHrF",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(foo)a)bar","QkbJD&bLtir&fa",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(foo)a)bar","QkbJD&bLtir&fa",[global])),
+ <<"bar">> = iolist_to_binary(re:replace("bar","(?<=(foo)a)bar","&J\\1DGniTa",[])),
+ <<"bar">> = iolist_to_binary(re:replace("bar","(?<=(foo)a)bar","&J\\1DGniTa",[global])),
+ <<"foobbar">> = iolist_to_binary(re:replace("foobbar","(?<=(foo)a)bar","\\1bfWxNNO\\1\\1uiB",[])),
+ <<"foobbar">> = iolist_to_binary(re:replace("foobbar","(?<=(foo)a)bar","\\1bfWxNNO\\1\\1uiB",[global])),
+ <<"inSfgh">> = iolist_to_binary(re:replace("abc","\\Aabc\\z","inSf\\1\\1gh",[multiline])),
+ <<"inSfgh">> = iolist_to_binary(re:replace("abc","\\Aabc\\z","inSf\\1\\1gh",[multiline,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Aabc\\z","&JtcOT\\1qU",[multiline])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Aabc\\z","&JtcOT\\1qU",[multiline,
+ global])),
+ <<"fEQ">> = iolist_to_binary(re:replace("abc","\\Aabc\\z","fEQ",[multiline])),
+ <<"fEQ">> = iolist_to_binary(re:replace("abc","\\Aabc\\z","fEQ",[multiline,
+ global])),
<<"qqq
abc">> = iolist_to_binary(re:replace("qqq
-abc","\\Aabc\\z","Y\\1YcwSrGNHt&\\1bI&",[multiline])),
+abc","\\Aabc\\z","ilQoSPAJ",[multiline])),
<<"qqq
abc">> = iolist_to_binary(re:replace("qqq
-abc","\\Aabc\\z","Y\\1YcwSrGNHt&\\1bI&",[multiline,global])),
+abc","\\Aabc\\z","ilQoSPAJ",[multiline,global])),
<<"abc
zzz">> = iolist_to_binary(re:replace("abc
-zzz","\\Aabc\\z","hxWEtDjrfttJGQ",[multiline])),
+zzz","\\Aabc\\z","sOIiDw\\1U\\1Mul&\\1NN\\1",[multiline])),
<<"abc
zzz">> = iolist_to_binary(re:replace("abc
-zzz","\\Aabc\\z","hxWEtDjrfttJGQ",[multiline,global])),
+zzz","\\Aabc\\z","sOIiDw\\1U\\1Mul&\\1NN\\1",[multiline,
+ global])),
<<"qqq
abc
zzz">> = iolist_to_binary(re:replace("qqq
abc
-zzz","\\Aabc\\z","\\1AYG&TDth",[multiline])),
+zzz","\\Aabc\\z","&On&obtglyVw",[multiline])),
<<"qqq
abc
zzz">> = iolist_to_binary(re:replace("qqq
abc
-zzz","\\Aabc\\z","\\1AYG&TDth",[multiline,global])),
- <<"1D">> = iolist_to_binary(re:replace("1.230003938","(?>(\\.\\d\\d[1-9]?))\\d+","D",[])),
- <<"1D">> = iolist_to_binary(re:replace("1.230003938","(?>(\\.\\d\\d[1-9]?))\\d+","D",[global])),
- <<"1.875Vkl.875egB.875000282cg">> = iolist_to_binary(re:replace("1.875000282","(?>(\\.\\d\\d[1-9]?))\\d+","\\1Vkl\\1egB&cg",[])),
- <<"1.875Vkl.875egB.875000282cg">> = iolist_to_binary(re:replace("1.875000282","(?>(\\.\\d\\d[1-9]?))\\d+","\\1Vkl\\1egB&cg",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>(\\.\\d\\d[1-9]?))\\d+","d&&VkB&QYebMC",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>(\\.\\d\\d[1-9]?))\\d+","d&&VkB&QYebMC",[global])),
- <<"1.235">> = iolist_to_binary(re:replace("1.235","(?>(\\.\\d\\d[1-9]?))\\d+","i\\1S\\1\\1&Yq&Pg&J&\\1",[])),
- <<"1.235">> = iolist_to_binary(re:replace("1.235","(?>(\\.\\d\\d[1-9]?))\\d+","i\\1S\\1\\1&Yq&Pg&J&\\1",[global])),
- <<"cjqYdkkpartyparty">> = iolist_to_binary(re:replace("now is the time for all good men to come to the aid of the party","^((?>\\w+)|(?>\\s+))*$","cjqYdkk\\1\\1",[])),
- <<"cjqYdkkpartyparty">> = iolist_to_binary(re:replace("now is the time for all good men to come to the aid of the party","^((?>\\w+)|(?>\\s+))*$","cjqYdkk\\1\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^((?>\\w+)|(?>\\s+))*$","BK",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^((?>\\w+)|(?>\\s+))*$","BK",[global])),
- <<"this is not a line with only words and spaces!">> = iolist_to_binary(re:replace("this is not a line with only words and spaces!","^((?>\\w+)|(?>\\s+))*$","sakHEC\\1tyC",[])),
- <<"this is not a line with only words and spaces!">> = iolist_to_binary(re:replace("this is not a line with only words and spaces!","^((?>\\w+)|(?>\\s+))*$","sakHEC\\1tyC",[global])),
- <<"a12345ax12345a">> = iolist_to_binary(re:replace("12345a","(\\d+)(\\w)","a&x&",[])),
- <<"a12345ax12345a">> = iolist_to_binary(re:replace("12345a","(\\d+)(\\w)","a&x&",[global])),
- <<"12345Mx1234LDmSq+">> = iolist_to_binary(re:replace("12345+","(\\d+)(\\w)","&Mx\\1LDmSq",[])),
- <<"12345Mx1234LDmSq+">> = iolist_to_binary(re:replace("12345+","(\\d+)(\\w)","&Mx\\1LDmSq",[global])),
- <<"kx12345GkJIBKkR12345aIDW12345ar">> = iolist_to_binary(re:replace("12345a","((?>\\d+))(\\w)","kx\\1GkJIBKkR&IDW&r",[])),
- <<"kx12345GkJIBKkR12345aIDW12345ar">> = iolist_to_binary(re:replace("12345a","((?>\\d+))(\\w)","kx\\1GkJIBKkR&IDW&r",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?>\\d+))(\\w)","AFie\\1JMiAGf&BhuHi\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?>\\d+))(\\w)","AFie\\1JMiAGf&BhuHi\\1",[global])),
- <<"12345+">> = iolist_to_binary(re:replace("12345+","((?>\\d+))(\\w)","l&&bFVdpjaGHV",[])),
- <<"12345+">> = iolist_to_binary(re:replace("12345+","((?>\\d+))(\\w)","l&&bFVdpjaGHV",[global])),
- <<"EqHtaaabaaabaaabSwdBiGUaaab">> = iolist_to_binary(re:replace("aaab","(?>a+)b","EqHt&&&SwdBiGU&",[])),
- <<"EqHtaaabaaabaaabSwdBiGUaaab">> = iolist_to_binary(re:replace("aaab","(?>a+)b","EqHt&&&SwdBiGU&",[global])),
- <<"SfjgLalqtcaaabaaablpXe">> = iolist_to_binary(re:replace("aaab","((?>a+)b)","SfjgLalqtc\\1&lpXe",[])),
- <<"SfjgLalqtcaaabaaablpXe">> = iolist_to_binary(re:replace("aaab","((?>a+)b)","SfjgLalqtc\\1&lpXe",[global])),
+zzz","\\Aabc\\z","&On&obtglyVw",[multiline,global])),
+ <<"1p.23">> = iolist_to_binary(re:replace("1.230003938","(?>(\\.\\d\\d[1-9]?))\\d+","p\\1",[])),
+ <<"1p.23">> = iolist_to_binary(re:replace("1.230003938","(?>(\\.\\d\\d[1-9]?))\\d+","p\\1",[global])),
+ <<"1.875ShDPcSaaE.875000282">> = iolist_to_binary(re:replace("1.875000282","(?>(\\.\\d\\d[1-9]?))\\d+","\\1ShDPcSaaE&",[])),
+ <<"1.875ShDPcSaaE.875000282">> = iolist_to_binary(re:replace("1.875000282","(?>(\\.\\d\\d[1-9]?))\\d+","\\1ShDPcSaaE&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>(\\.\\d\\d[1-9]?))\\d+","kgx\\1&RsUCY",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>(\\.\\d\\d[1-9]?))\\d+","kgx\\1&RsUCY",[global])),
+ <<"1.235">> = iolist_to_binary(re:replace("1.235","(?>(\\.\\d\\d[1-9]?))\\d+","\\1OwWeWH",[])),
+ <<"1.235">> = iolist_to_binary(re:replace("1.235","(?>(\\.\\d\\d[1-9]?))\\d+","\\1OwWeWH",[global])),
+ <<"RKNdIe">> = iolist_to_binary(re:replace("now is the time for all good men to come to the aid of the party","^((?>\\w+)|(?>\\s+))*$","RKNdIe",[])),
+ <<"RKNdIe">> = iolist_to_binary(re:replace("now is the time for all good men to come to the aid of the party","^((?>\\w+)|(?>\\s+))*$","RKNdIe",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^((?>\\w+)|(?>\\s+))*$","&dYBP",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^((?>\\w+)|(?>\\s+))*$","&dYBP",[global])),
+ <<"this is not a line with only words and spaces!">> = iolist_to_binary(re:replace("this is not a line with only words and spaces!","^((?>\\w+)|(?>\\s+))*$","cGurgcY\\1oWHq&qXicAl",[])),
+ <<"this is not a line with only words and spaces!">> = iolist_to_binary(re:replace("this is not a line with only words and spaces!","^((?>\\w+)|(?>\\s+))*$","cGurgcY\\1oWHq&qXicAl",[global])),
+ <<"hXTky12345aEl12345aGX12345kFf">> = iolist_to_binary(re:replace("12345a","(\\d+)(\\w)","hXTky&El&GX\\1kFf",[])),
+ <<"hXTky12345aEl12345aGX12345kFf">> = iolist_to_binary(re:replace("12345a","(\\d+)(\\w)","hXTky&El&GX\\1kFf",[global])),
+ <<"hd1234x+">> = iolist_to_binary(re:replace("12345+","(\\d+)(\\w)","hd\\1x",[])),
+ <<"hd1234x+">> = iolist_to_binary(re:replace("12345+","(\\d+)(\\w)","hd\\1x",[global])),
+ <<"12345">> = iolist_to_binary(re:replace("12345a","((?>\\d+))(\\w)","\\1",[])),
+ <<"12345">> = iolist_to_binary(re:replace("12345a","((?>\\d+))(\\w)","\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?>\\d+))(\\w)","aGjfXar",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?>\\d+))(\\w)","aGjfXar",[global])),
+ <<"12345+">> = iolist_to_binary(re:replace("12345+","((?>\\d+))(\\w)","DmEP\\1AVjI&r",[])),
+ <<"12345+">> = iolist_to_binary(re:replace("12345+","((?>\\d+))(\\w)","DmEP\\1AVjI&r",[global])),
+ <<"TaaabtTxSOuYhbPTaaabFKp">> = iolist_to_binary(re:replace("aaab","(?>a+)b","T&tTxS\\1O\\1uYhbPT&\\1FKp",[])),
+ <<"TaaabtTxSOuYhbPTaaabFKp">> = iolist_to_binary(re:replace("aaab","(?>a+)b","T&tTxS\\1O\\1uYhbPT&\\1FKp",[global])),
ok.
run12() ->
- <<"uUMJaaabSIfpB">> = iolist_to_binary(re:replace("aaab","(?>(a+))b","uUMJ&SIfpB",[])),
- <<"uUMJaaabSIfpB">> = iolist_to_binary(re:replace("aaab","(?>(a+))b","uUMJ&SIfpB",[global])),
- <<"aaaYgHODtKiOcNErSSbbbccc">> = iolist_to_binary(re:replace("aaabbbccc","(?>b)+","YgHODtKiOcNErSS&\\1",[])),
- <<"aaaYgHODtKiOcNErSSbbbccc">> = iolist_to_binary(re:replace("aaabbbccc","(?>b)+","YgHODtKiOcNErSS&\\1",[global])),
- <<"oaaabbbbcaaabbbbcEpdElkPiPeaeLnncccd">> = iolist_to_binary(re:replace("aaabbbbccccd","(?>a+|b+|c+)*c","o\\1&&EpdEl\\1kPiPeaeLnn",[])),
- <<"oaaabbbbcaaabbbbcEpdElkPiPeaeLnnoccEpdElkPiPeaeLnnoccEpdElkPiPeaeLnnoccEpdElkPiPeaeLnnd">> = iolist_to_binary(re:replace("aaabbbbccccd","(?>a+|b+|c+)*c","o\\1&&EpdEl\\1kPiPeaeLnn",[global])),
- <<"((HxYTsih">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+","HxYTsih",[])),
- <<"((HxYTsih">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+","HxYTsih",[global])),
- <<"iJnuXdUjqgsabcM(abc)OUgSEW">> = iolist_to_binary(re:replace("(abc)","\\(((?>[^()]+)|\\([^()]+\\))+\\)","iJnuXdUjqgs\\1M&OUgSEW",[])),
- <<"iJnuXdUjqgsabcM(abc)OUgSEW">> = iolist_to_binary(re:replace("(abc)","\\(((?>[^()]+)|\\([^()]+\\))+\\)","iJnuXdUjqgs\\1M&OUgSEW",[global])),
- <<"oxyzdq">> = iolist_to_binary(re:replace("(abc(def)xyz)","\\(((?>[^()]+)|\\([^()]+\\))+\\)","o\\1dq",[])),
- <<"oxyzdq">> = iolist_to_binary(re:replace("(abc(def)xyz)","\\(((?>[^()]+)|\\([^()]+\\))+\\)","o\\1dq",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\(((?>[^()]+)|\\([^()]+\\))+\\)","RViX",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\(((?>[^()]+)|\\([^()]+\\))+\\)","RViX",[global])),
- <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(((?>[^()]+)|\\([^()]+\\))+\\)","H",[])),
- <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(((?>[^()]+)|\\([^()]+\\))+\\)","H",[global])),
- <<"tbhUMBhabLFA">> = iolist_to_binary(re:replace("ab","a(?-i)b","tbhUMBh&\\1LFA",[caseless])),
- <<"tbhUMBhabLFA">> = iolist_to_binary(re:replace("ab","a(?-i)b","tbhUMBh&\\1LFA",[caseless,
- global])),
- <<"QUAETVEmTTESUWK">> = iolist_to_binary(re:replace("Ab","a(?-i)b","QUAETVEmTT\\1\\1ESUWK",[caseless])),
- <<"QUAETVEmTTESUWK">> = iolist_to_binary(re:replace("Ab","a(?-i)b","QUAETVEmTT\\1\\1ESUWK",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?-i)b","\\1UHB",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?-i)b","\\1UHB",[caseless,
- global])),
- <<"aB">> = iolist_to_binary(re:replace("aB","a(?-i)b","\\1\\1tHVtVAphgcPH",[caseless])),
- <<"aB">> = iolist_to_binary(re:replace("aB","a(?-i)b","\\1\\1tHVtVAphgcPH",[caseless,
+ <<"LhIrrFgkHmaaabfdaaaboY">> = iolist_to_binary(re:replace("aaab","((?>a+)b)","LhIrrFgkHm&fd\\1oY",[])),
+ <<"LhIrrFgkHmaaabfdaaaboY">> = iolist_to_binary(re:replace("aaab","((?>a+)b)","LhIrrFgkHm&fd\\1oY",[global])),
+ <<"ImaaaaaacADcaaabpHh">> = iolist_to_binary(re:replace("aaab","(?>(a+))b","Im\\1\\1cADc&pHh",[])),
+ <<"ImaaaaaacADcaaabpHh">> = iolist_to_binary(re:replace("aaab","(?>(a+))b","Im\\1\\1cADc&pHh",[global])),
+ <<"aaatKEdbbbccc">> = iolist_to_binary(re:replace("aaabbbccc","(?>b)+","tKEd&\\1",[])),
+ <<"aaatKEdbbbccc">> = iolist_to_binary(re:replace("aaabbbccc","(?>b)+","tKEd&\\1",[global])),
+ <<"mnyiaaabbbbcEwbrLGfNMcccd">> = iolist_to_binary(re:replace("aaabbbbccccd","(?>a+|b+|c+)*c","m\\1nyi&EwbrLGfNM",[])),
+ <<"mnyiaaabbbbcEwbrLGfNMmnyicEwbrLGfNMmnyicEwbrLGfNMmnyicEwbrLGfNMd">> = iolist_to_binary(re:replace("aaabbbbccccd","(?>a+|b+|c+)*c","m\\1nyi&EwbrLGfNM",[global])),
+ <<"((Iqlkabc(ade)ufh()()xbhmeIrGmiGmVd">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+","Iqlk&bhmeIrGmiGmVd",[])),
+ <<"((Iqlkabc(ade)ufh()()xbhmeIrGmiGmVd">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+","Iqlk&bhmeIrGmiGmVd",[global])),
+ <<"CIsFJQabcgcRrp">> = iolist_to_binary(re:replace("(abc)","\\(((?>[^()]+)|\\([^()]+\\))+\\)","CIsFJQ\\1gcRrp",[])),
+ <<"CIsFJQabcgcRrp">> = iolist_to_binary(re:replace("(abc)","\\(((?>[^()]+)|\\([^()]+\\))+\\)","CIsFJQ\\1gcRrp",[global])),
+ <<"lmHuxyzxyzCxyzBxyzfyc">> = iolist_to_binary(re:replace("(abc(def)xyz)","\\(((?>[^()]+)|\\([^()]+\\))+\\)","lmHu\\1\\1C\\1B\\1fyc",[])),
+ <<"lmHuxyzxyzCxyzBxyzfyc">> = iolist_to_binary(re:replace("(abc(def)xyz)","\\(((?>[^()]+)|\\([^()]+\\))+\\)","lmHu\\1\\1C\\1B\\1fyc",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\(((?>[^()]+)|\\([^()]+\\))+\\)","GQrbsavAq",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\(((?>[^()]+)|\\([^()]+\\))+\\)","GQrbsavAq",[global])),
+ <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(((?>[^()]+)|\\([^()]+\\))+\\)","\\1TXU&lHlMOA&&\\1EB&EF",[])),
+ <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(((?>[^()]+)|\\([^()]+\\))+\\)","\\1TXU&lHlMOA&&\\1EB&EF",[global])),
+ <<"idabiAQbk">> = iolist_to_binary(re:replace("ab","a(?-i)b","id\\1&iAQbk",[caseless])),
+ <<"idabiAQbk">> = iolist_to_binary(re:replace("ab","a(?-i)b","id\\1&iAQbk",[caseless,
+ global])),
+ <<"ymJEoJHMVXAbpfeH">> = iolist_to_binary(re:replace("Ab","a(?-i)b","ymJEo\\1JHMVX&pfeH",[caseless])),
+ <<"ymJEoJHMVXAbpfeH">> = iolist_to_binary(re:replace("Ab","a(?-i)b","ymJEo\\1JHMVX&pfeH",[caseless,
global])),
- <<"AB">> = iolist_to_binary(re:replace("AB","a(?-i)b","EHcIhNYa\\1KSgqWOK",[caseless])),
- <<"AB">> = iolist_to_binary(re:replace("AB","a(?-i)b","EHcIhNYa\\1KSgqWOK",[caseless,
- global])),
- <<"FILLIygQ">> = iolist_to_binary(re:replace("a bcd e","(a (?x)b c)d e","FILLIygQ",[])),
- <<"FILLIygQ">> = iolist_to_binary(re:replace("a bcd e","(a (?x)b c)d e","FILLIygQ",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a (?x)b c)d e","wJGN&cKBOuESq\\1&Wj",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a (?x)b c)d e","wJGN&cKBOuESq\\1&Wj",[global])),
- <<"a b cd e">> = iolist_to_binary(re:replace("a b cd e","(a (?x)b c)d e","A\\1AwoRg&BJXQG",[])),
- <<"a b cd e">> = iolist_to_binary(re:replace("a b cd e","(a (?x)b c)d e","A\\1AwoRg&BJXQG",[global])),
- <<"abcd e">> = iolist_to_binary(re:replace("abcd e","(a (?x)b c)d e","u",[])),
- <<"abcd e">> = iolist_to_binary(re:replace("abcd e","(a (?x)b c)d e","u",[global])),
- <<"a bcde">> = iolist_to_binary(re:replace("a bcde","(a (?x)b c)d e","oNi\\1yapjj\\1GmPvu\\1Y\\1qv",[])),
- <<"a bcde">> = iolist_to_binary(re:replace("a bcde","(a (?x)b c)d e","oNi\\1yapjj\\1GmPvu\\1Y\\1qv",[global])),
- <<"Aa bcde fa bcde faa bcde fEL">> = iolist_to_binary(re:replace("a bcde f","(a b(?x)c d (?-x)e f)","A&&a&EL",[])),
- <<"Aa bcde fa bcde faa bcde fEL">> = iolist_to_binary(re:replace("a bcde f","(a b(?x)c d (?-x)e f)","A&&a&EL",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a b(?x)c d (?-x)e f)","tNNP\\1V&C",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a b(?x)c d (?-x)e f)","tNNP\\1V&C",[global])),
- <<"abcdef">> = iolist_to_binary(re:replace("abcdef","(a b(?x)c d (?-x)e f)","ty&TPg&J\\1hrKvQIX\\1",[])),
- <<"abcdef">> = iolist_to_binary(re:replace("abcdef","(a b(?x)c d (?-x)e f)","ty&TPg&J\\1hrKvQIX\\1",[global])),
- <<"Bfe">> = iolist_to_binary(re:replace("abc","(a(?i)b)c","Bfe",[])),
- <<"Bfe">> = iolist_to_binary(re:replace("abc","(a(?i)b)c","Bfe",[global])),
- <<"aBaBeoqaBaBdaIDJFJSKhel">> = iolist_to_binary(re:replace("aBc","(a(?i)b)c","\\1\\1eoq\\1\\1daIDJFJSKhel",[])),
- <<"aBaBeoqaBaBdaIDJFJSKhel">> = iolist_to_binary(re:replace("aBc","(a(?i)b)c","\\1\\1eoq\\1\\1daIDJFJSKhel",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a(?i)b)c","RRCuLD&CCSP&",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a(?i)b)c","RRCuLD&CCSP&",[global])),
- <<"abC">> = iolist_to_binary(re:replace("abC","(a(?i)b)c","&YVGhj",[])),
- <<"abC">> = iolist_to_binary(re:replace("abC","(a(?i)b)c","&YVGhj",[global])),
- <<"aBC">> = iolist_to_binary(re:replace("aBC","(a(?i)b)c","&\\1ABy\\1Tud",[])),
- <<"aBC">> = iolist_to_binary(re:replace("aBC","(a(?i)b)c","&\\1ABy\\1Tud",[global])),
- <<"Abc">> = iolist_to_binary(re:replace("Abc","(a(?i)b)c","vHc&EssOdEtsm",[])),
- <<"Abc">> = iolist_to_binary(re:replace("Abc","(a(?i)b)c","vHc&EssOdEtsm",[global])),
- <<"ABc">> = iolist_to_binary(re:replace("ABc","(a(?i)b)c","&&O",[])),
- <<"ABc">> = iolist_to_binary(re:replace("ABc","(a(?i)b)c","&&O",[global])),
- <<"ABC">> = iolist_to_binary(re:replace("ABC","(a(?i)b)c","&&&G\\1GLMkRej\\1y\\1aOQ",[])),
- <<"ABC">> = iolist_to_binary(re:replace("ABC","(a(?i)b)c","&&&G\\1GLMkRej\\1y\\1aOQ",[global])),
- <<"AbC">> = iolist_to_binary(re:replace("AbC","(a(?i)b)c","ajN\\1emNFkTh&UCTlp&Y",[])),
- <<"AbC">> = iolist_to_binary(re:replace("AbC","(a(?i)b)c","ajN\\1emNFkTh&UCTlp&Y",[global])),
- <<"fabcabcccGlcVpJl">> = iolist_to_binary(re:replace("abc","a(?i:b)c","f&&ccGlcVpJl",[])),
- <<"fabcabcccGlcVpJl">> = iolist_to_binary(re:replace("abc","a(?i:b)c","f&&ccGlcVpJl",[global])),
- <<"NeHDaBcCVyaBcpFA">> = iolist_to_binary(re:replace("aBc","a(?i:b)c","Ne\\1\\1\\1HD&C\\1Vy&pFA",[])),
- <<"NeHDaBcCVyaBcpFA">> = iolist_to_binary(re:replace("aBc","a(?i:b)c","Ne\\1\\1\\1HD&C\\1Vy&pFA",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?i:b)c","Sqq",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?i:b)c","Sqq",[global])),
- <<"ABC">> = iolist_to_binary(re:replace("ABC","a(?i:b)c","&FRMp\\1nIrrC\\1IVSckPvd",[])),
- <<"ABC">> = iolist_to_binary(re:replace("ABC","a(?i:b)c","&FRMp\\1nIrrC\\1IVSckPvd",[global])),
- <<"abC">> = iolist_to_binary(re:replace("abC","a(?i:b)c","x\\1WM&dj&&KIBo",[])),
- <<"abC">> = iolist_to_binary(re:replace("abC","a(?i:b)c","x\\1WM&dj&&KIBo",[global])),
- <<"aBC">> = iolist_to_binary(re:replace("aBC","a(?i:b)c","XiKEHtEtj",[])),
- <<"aBC">> = iolist_to_binary(re:replace("aBC","a(?i:b)c","XiKEHtEtj",[global])),
- <<"SjNSaBcGWaBcwcaBcTf">> = iolist_to_binary(re:replace("aBc","a(?i:b)*c","\\1\\1SjNS&GW&wc&Tf",[])),
- <<"SjNSaBcGWaBcwcaBcTf">> = iolist_to_binary(re:replace("aBc","a(?i:b)*c","\\1\\1SjNS&GW&wc&Tf",[global])),
- <<"rOaBBckjJDolGaBBcie">> = iolist_to_binary(re:replace("aBBc","a(?i:b)*c","rO&kjJDolG&\\1ie",[])),
- <<"rOaBBckjJDolGaBBcie">> = iolist_to_binary(re:replace("aBBc","a(?i:b)*c","rO&kjJDolG&\\1ie",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?i:b)*c","rnHfd\\1uJBJn",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?i:b)*c","rnHfd\\1uJBJn",[global])),
- <<"aBC">> = iolist_to_binary(re:replace("aBC","a(?i:b)*c","T",[])),
- <<"aBC">> = iolist_to_binary(re:replace("aBC","a(?i:b)*c","T",[global])),
- <<"aBBC">> = iolist_to_binary(re:replace("aBBC","a(?i:b)*c","qC&IV\\1WPwD&&raPOEJG",[])),
- <<"aBBC">> = iolist_to_binary(re:replace("aBBC","a(?i:b)*c","qC&IV\\1WPwD&&raPOEJG",[global])),
- <<"fxbDabcdcebhuXknd">> = iolist_to_binary(re:replace("abcd","a(?=b(?i)c)\\w\\wd","fxbD&cebhuX\\1knd",[])),
- <<"fxbDabcdcebhuXknd">> = iolist_to_binary(re:replace("abcd","a(?=b(?i)c)\\w\\wd","fxbD&cebhuX\\1knd",[global])),
- <<"hmNjfiwabCdOns">> = iolist_to_binary(re:replace("abCd","a(?=b(?i)c)\\w\\wd","hmN\\1jfiw&On\\1s",[])),
- <<"hmNjfiwabCdOns">> = iolist_to_binary(re:replace("abCd","a(?=b(?i)c)\\w\\wd","hmN\\1jfiw&On\\1s",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?=b(?i)c)\\w\\wd","l",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?=b(?i)c)\\w\\wd","l",[global])),
- <<"aBCd">> = iolist_to_binary(re:replace("aBCd","a(?=b(?i)c)\\w\\wd","QVfGTQBraI&PoV&&B\\1B",[])),
- <<"aBCd">> = iolist_to_binary(re:replace("aBCd","a(?=b(?i)c)\\w\\wd","QVfGTQBraI&PoV&&B\\1B",[global])),
- <<"abcD">> = iolist_to_binary(re:replace("abcD","a(?=b(?i)c)\\w\\wd","WTVxdU\\1Ql&Ori\\1DCqn&",[])),
- <<"abcD">> = iolist_to_binary(re:replace("abcD","a(?=b(?i)c)\\w\\wd","WTVxdU\\1Ql&Ori\\1DCqn&",[global])),
- <<"yHdfkVmore than millionmore than millione">> = iolist_to_binary(re:replace("more than million","(?s-i:more.*than).*million","yHd\\1fkV&&e\\1",[caseless])),
- <<"yHdfkVmore than millionmore than millione">> = iolist_to_binary(re:replace("more than million","(?s-i:more.*than).*million","yHd\\1fkV&&e\\1",[caseless,
- global])),
- <<"mQsFkPLr">> = iolist_to_binary(re:replace("more than MILLION","(?s-i:more.*than).*million","mQsFkPLr",[caseless])),
- <<"mQsFkPLr">> = iolist_to_binary(re:replace("more than MILLION","(?s-i:more.*than).*million","mQsFkPLr",[caseless,
- global])),
- <<"mvDmore
- than MillionmVTJEmore
- than MillionTJNmore
- than MillionLwu">> = iolist_to_binary(re:replace("more
- than Million","(?s-i:more.*than).*million","mvD&mVTJE&TJN&Lwu",[caseless])),
- <<"mvDmore
- than MillionmVTJEmore
- than MillionTJNmore
- than MillionLwu">> = iolist_to_binary(re:replace("more
- than Million","(?s-i:more.*than).*million","mvD&mVTJE&TJN&Lwu",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s-i:more.*than).*million","t\\1vYtKJq&frCR\\1",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s-i:more.*than).*million","t\\1vYtKJq&frCR\\1",[caseless,
- global])),
- <<"MORE THAN MILLION">> = iolist_to_binary(re:replace("MORE THAN MILLION","(?s-i:more.*than).*million","\\1gn&G\\1&",[caseless])),
- <<"MORE THAN MILLION">> = iolist_to_binary(re:replace("MORE THAN MILLION","(?s-i:more.*than).*million","\\1gn&G\\1&",[caseless,
- global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?-i)b","vPR\\1TpFC\\1FV",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?-i)b","vPR\\1TpFC\\1FV",[caseless,
+ global])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","a(?-i)b","&",[caseless])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","a(?-i)b","&",[caseless,
+ global])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","a(?-i)b","&\\1VTAYjnm&anO",[caseless])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","a(?-i)b","&\\1VTAYjnm&anO",[caseless,
+ global])),
+ <<"wa bcd eNsa bcd eU">> = iolist_to_binary(re:replace("a bcd e","(a (?x)b c)d e","w&Ns&U",[])),
+ <<"wa bcd eNsa bcd eU">> = iolist_to_binary(re:replace("a bcd e","(a (?x)b c)d e","w&Ns&U",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a (?x)b c)d e","J\\1\\1&\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a (?x)b c)d e","J\\1\\1&\\1",[global])),
+ <<"a b cd e">> = iolist_to_binary(re:replace("a b cd e","(a (?x)b c)d e","kmHqh\\1V&xPLo&d\\1kD&c\\1",[])),
+ <<"a b cd e">> = iolist_to_binary(re:replace("a b cd e","(a (?x)b c)d e","kmHqh\\1V&xPLo&d\\1kD&c\\1",[global])),
+ <<"abcd e">> = iolist_to_binary(re:replace("abcd e","(a (?x)b c)d e","JeuSTa",[])),
+ <<"abcd e">> = iolist_to_binary(re:replace("abcd e","(a (?x)b c)d e","JeuSTa",[global])),
+ <<"a bcde">> = iolist_to_binary(re:replace("a bcde","(a (?x)b c)d e","rGvPufM&S",[])),
+ <<"a bcde">> = iolist_to_binary(re:replace("a bcde","(a (?x)b c)d e","rGvPufM&S",[global])),
+ <<"Ta bcde fa bcde fUmmu">> = iolist_to_binary(re:replace("a bcde f","(a b(?x)c d (?-x)e f)","T\\1\\1Ummu",[])),
+ <<"Ta bcde fa bcde fUmmu">> = iolist_to_binary(re:replace("a bcde f","(a b(?x)c d (?-x)e f)","T\\1\\1Ummu",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a b(?x)c d (?-x)e f)","IRrlhH\\1TBy\\1hR&SlYv",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a b(?x)c d (?-x)e f)","IRrlhH\\1TBy\\1hR&SlYv",[global])),
+ <<"abcdef">> = iolist_to_binary(re:replace("abcdef","(a b(?x)c d (?-x)e f)","&W&QjaDduHuWkQDe&f",[])),
+ <<"abcdef">> = iolist_to_binary(re:replace("abcdef","(a b(?x)c d (?-x)e f)","&W&QjaDduHuWkQDe&f",[global])),
+ <<"nPOwabcHbn">> = iolist_to_binary(re:replace("abc","(a(?i)b)c","nPOw&Hbn",[])),
+ <<"nPOwabcHbn">> = iolist_to_binary(re:replace("abc","(a(?i)b)c","nPOw&Hbn",[global])),
+ <<"lUDErmsSNiolx">> = iolist_to_binary(re:replace("aBc","(a(?i)b)c","lUDErmsSNiolx",[])),
+ <<"lUDErmsSNiolx">> = iolist_to_binary(re:replace("aBc","(a(?i)b)c","lUDErmsSNiolx",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a(?i)b)c","\\1nnmRyE\\1TDu\\1gSpew&lo",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a(?i)b)c","\\1nnmRyE\\1TDu\\1gSpew&lo",[global])),
+ <<"abC">> = iolist_to_binary(re:replace("abC","(a(?i)b)c","\\1yod\\1Yx&CeJlaBW",[])),
+ <<"abC">> = iolist_to_binary(re:replace("abC","(a(?i)b)c","\\1yod\\1Yx&CeJlaBW",[global])),
+ <<"aBC">> = iolist_to_binary(re:replace("aBC","(a(?i)b)c","&SAguoo",[])),
+ <<"aBC">> = iolist_to_binary(re:replace("aBC","(a(?i)b)c","&SAguoo",[global])),
+ <<"Abc">> = iolist_to_binary(re:replace("Abc","(a(?i)b)c","gK&",[])),
+ <<"Abc">> = iolist_to_binary(re:replace("Abc","(a(?i)b)c","gK&",[global])),
+ <<"ABc">> = iolist_to_binary(re:replace("ABc","(a(?i)b)c","VqTSha",[])),
+ <<"ABc">> = iolist_to_binary(re:replace("ABc","(a(?i)b)c","VqTSha",[global])),
+ <<"ABC">> = iolist_to_binary(re:replace("ABC","(a(?i)b)c","umIMCIf&IcUxswr\\1PAle",[])),
+ <<"ABC">> = iolist_to_binary(re:replace("ABC","(a(?i)b)c","umIMCIf&IcUxswr\\1PAle",[global])),
+ <<"AbC">> = iolist_to_binary(re:replace("AbC","(a(?i)b)c","IrRia&&\\1\\1xxN",[])),
+ <<"AbC">> = iolist_to_binary(re:replace("AbC","(a(?i)b)c","IrRia&&\\1\\1xxN",[global])),
+ <<"BhNg">> = iolist_to_binary(re:replace("abc","a(?i:b)c","B\\1hNg",[])),
+ <<"BhNg">> = iolist_to_binary(re:replace("abc","a(?i:b)c","B\\1hNg",[global])),
+ <<"ksleilaBcnaBcgaBcckag">> = iolist_to_binary(re:replace("aBc","a(?i:b)c","ksleil\\1&n&\\1g&ckag",[])),
+ <<"ksleilaBcnaBcgaBcckag">> = iolist_to_binary(re:replace("aBc","a(?i:b)c","ksleil\\1&n&\\1g&ckag",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?i:b)c","HOFVAgJOK&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?i:b)c","HOFVAgJOK&",[global])),
+ <<"ABC">> = iolist_to_binary(re:replace("ABC","a(?i:b)c","AqQnVO",[])),
+ <<"ABC">> = iolist_to_binary(re:replace("ABC","a(?i:b)c","AqQnVO",[global])),
+ <<"abC">> = iolist_to_binary(re:replace("abC","a(?i:b)c","vnKNXwp\\1rp\\1JxY",[])),
+ <<"abC">> = iolist_to_binary(re:replace("abC","a(?i:b)c","vnKNXwp\\1rp\\1JxY",[global])),
+ <<"aBC">> = iolist_to_binary(re:replace("aBC","a(?i:b)c","&&l&\\1CMbjHlAnNY",[])),
+ <<"aBC">> = iolist_to_binary(re:replace("aBC","a(?i:b)c","&&l&\\1CMbjHlAnNY",[global])),
+ <<"CrbBlrjAUcQReBRN">> = iolist_to_binary(re:replace("aBc","a(?i:b)*c","CrbBlrjAUcQReBRN",[])),
+ <<"CrbBlrjAUcQReBRN">> = iolist_to_binary(re:replace("aBc","a(?i:b)*c","CrbBlrjAUcQReBRN",[global])),
+ <<"FTHvDKUVGaBBcJaBBca">> = iolist_to_binary(re:replace("aBBc","a(?i:b)*c","FT\\1HvDKUVG&J\\1&\\1a",[])),
+ <<"FTHvDKUVGaBBcJaBBca">> = iolist_to_binary(re:replace("aBBc","a(?i:b)*c","FT\\1HvDKUVG&J\\1&\\1a",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?i:b)*c","qHE\\1PBQLSx",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?i:b)*c","qHE\\1PBQLSx",[global])),
+ <<"aBC">> = iolist_to_binary(re:replace("aBC","a(?i:b)*c","ceuREb\\1nlQIA\\1tjv",[])),
+ <<"aBC">> = iolist_to_binary(re:replace("aBC","a(?i:b)*c","ceuREb\\1nlQIA\\1tjv",[global])),
+ <<"aBBC">> = iolist_to_binary(re:replace("aBBC","a(?i:b)*c","\\1xa&d\\1\\1\\1&y",[])),
+ <<"aBBC">> = iolist_to_binary(re:replace("aBBC","a(?i:b)*c","\\1xa&d\\1\\1\\1&y",[global])),
+ <<"ulvseXcnAHfTux">> = iolist_to_binary(re:replace("abcd","a(?=b(?i)c)\\w\\wd","\\1ulvseXc\\1nAHf\\1Tux",[])),
+ <<"ulvseXcnAHfTux">> = iolist_to_binary(re:replace("abcd","a(?=b(?i)c)\\w\\wd","\\1ulvseXc\\1nAHf\\1Tux",[global])),
+ <<"JabCdfEqTKkUYCsYRBa">> = iolist_to_binary(re:replace("abCd","a(?=b(?i)c)\\w\\wd","J&fEqTKkUYCsYR\\1Ba",[])),
+ <<"JabCdfEqTKkUYCsYRBa">> = iolist_to_binary(re:replace("abCd","a(?=b(?i)c)\\w\\wd","J&fEqTKkUYCsYR\\1Ba",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?=b(?i)c)\\w\\wd","&ucD&KTCpy&hM\\1JmdG\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?=b(?i)c)\\w\\wd","&ucD&KTCpy&hM\\1JmdG\\1",[global])),
+ <<"aBCd">> = iolist_to_binary(re:replace("aBCd","a(?=b(?i)c)\\w\\wd","un&fMos&GsMoI\\1IOOgT\\1",[])),
+ <<"aBCd">> = iolist_to_binary(re:replace("aBCd","a(?=b(?i)c)\\w\\wd","un&fMos&GsMoI\\1IOOgT\\1",[global])),
+ <<"abcD">> = iolist_to_binary(re:replace("abcD","a(?=b(?i)c)\\w\\wd","\\1TX&",[])),
+ <<"abcD">> = iolist_to_binary(re:replace("abcD","a(?=b(?i)c)\\w\\wd","\\1TX&",[global])),
+ <<"more than millionxmore than millionDMymore than millionvobHjfHmore than millionHqL">> = iolist_to_binary(re:replace("more than million","(?s-i:more.*than).*million","&x&DMy&vobHjfH&HqL",[caseless])),
+ <<"more than millionxmore than millionDMymore than millionvobHjfHmore than millionHqL">> = iolist_to_binary(re:replace("more than million","(?s-i:more.*than).*million","&x&DMy&vobHjfH&HqL",[caseless,
+ global])),
+ <<"more than MILLIONKImore than MILLIONmore than MILLIONuDxH">> = iolist_to_binary(re:replace("more than MILLION","(?s-i:more.*than).*million","\\1&\\1KI&&uDxH",[caseless])),
+ <<"more than MILLIONKImore than MILLIONmore than MILLIONuDxH">> = iolist_to_binary(re:replace("more than MILLION","(?s-i:more.*than).*million","\\1&\\1KI&&uDxH",[caseless,
+ global])),
+ <<"DIwUfD">> = iolist_to_binary(re:replace("more
+ than Million","(?s-i:more.*than).*million","DIwU\\1fD",[caseless])),
+ <<"DIwUfD">> = iolist_to_binary(re:replace("more
+ than Million","(?s-i:more.*than).*million","DIwU\\1fD",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s-i:more.*than).*million","&&m&lYA",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?s-i:more.*than).*million","&&m&lYA",[caseless,
+ global])),
+ <<"MORE THAN MILLION">> = iolist_to_binary(re:replace("MORE THAN MILLION","(?s-i:more.*than).*million","hC\\1c\\1QaE\\1ejLMkpMbOoW",[caseless])),
+ <<"MORE THAN MILLION">> = iolist_to_binary(re:replace("MORE THAN MILLION","(?s-i:more.*than).*million","hC\\1c\\1QaE\\1ejLMkpMbOoW",[caseless,
+ global])),
<<"more
than
million">> = iolist_to_binary(re:replace("more
than
- million","(?s-i:more.*than).*million","WmlNcmK\\1\\1DMpX\\1WToOHF",[caseless])),
+ million","(?s-i:more.*than).*million","hU\\1&DhqAQkrYaH",[caseless])),
<<"more
than
million">> = iolist_to_binary(re:replace("more
than
- million","(?s-i:more.*than).*million","WmlNcmK\\1\\1DMpX\\1WToOHF",[caseless,
- global])),
- <<"psmore than millionTuKupIvfmRjB">> = iolist_to_binary(re:replace("more than million","(?:(?s-i)more.*than).*million","ps&T\\1uKupIvfmRjB",[caseless])),
- <<"psmore than millionTuKupIvfmRjB">> = iolist_to_binary(re:replace("more than million","(?:(?s-i)more.*than).*million","ps&T\\1uKupIvfmRjB",[caseless,
+ million","(?s-i:more.*than).*million","hU\\1&DhqAQkrYaH",[caseless,
+ global])),
+ <<"rBTLmore than millionY">> = iolist_to_binary(re:replace("more than million","(?:(?s-i)more.*than).*million","rBTL&Y",[caseless])),
+ <<"rBTLmore than millionY">> = iolist_to_binary(re:replace("more than million","(?:(?s-i)more.*than).*million","rBTL&Y",[caseless,
+ global])),
+ <<"SmyMhdAN">> = iolist_to_binary(re:replace("more than MILLION","(?:(?s-i)more.*than).*million","S\\1myMhdAN",[caseless])),
+ <<"SmyMhdAN">> = iolist_to_binary(re:replace("more than MILLION","(?:(?s-i)more.*than).*million","S\\1myMhdAN",[caseless,
+ global])),
+ <<"VCDSmcyPWmore
+ than Milliondg">> = iolist_to_binary(re:replace("more
+ than Million","(?:(?s-i)more.*than).*million","VCDSmcyPW\\1&dg",[caseless])),
+ <<"VCDSmcyPWmore
+ than Milliondg">> = iolist_to_binary(re:replace("more
+ than Million","(?:(?s-i)more.*than).*million","VCDSmcyPW\\1&dg",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?s-i)more.*than).*million","\\1B&",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?s-i)more.*than).*million","\\1B&",[caseless,
+ global])),
+ <<"MORE THAN MILLION">> = iolist_to_binary(re:replace("MORE THAN MILLION","(?:(?s-i)more.*than).*million","\\1R&\\1IUeeXdQa&",[caseless])),
+ <<"MORE THAN MILLION">> = iolist_to_binary(re:replace("MORE THAN MILLION","(?:(?s-i)more.*than).*million","\\1R&\\1IUeeXdQa&",[caseless,
global])),
- <<"IhKcRCpQge">> = iolist_to_binary(re:replace("more than MILLION","(?:(?s-i)more.*than).*million","I\\1\\1hKcRCpQg\\1e",[caseless])),
- <<"IhKcRCpQge">> = iolist_to_binary(re:replace("more than MILLION","(?:(?s-i)more.*than).*million","I\\1\\1hKcRCpQg\\1e",[caseless,
- global])),
- <<"more
- than MillionOISUnAOTGvtRakU">> = iolist_to_binary(re:replace("more
- than Million","(?:(?s-i)more.*than).*million","&OISU\\1nAOTGvtRakU\\1",[caseless])),
- <<"more
- than MillionOISUnAOTGvtRakU">> = iolist_to_binary(re:replace("more
- than Million","(?:(?s-i)more.*than).*million","&OISU\\1nAOTGvtRakU\\1",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?s-i)more.*than).*million","TNips\\1&J\\1mqnbuyC",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?s-i)more.*than).*million","TNips\\1&J\\1mqnbuyC",[caseless,
- global])),
- <<"MORE THAN MILLION">> = iolist_to_binary(re:replace("MORE THAN MILLION","(?:(?s-i)more.*than).*million","\\1qCci&VKLJ&QtwPOr",[caseless])),
- <<"MORE THAN MILLION">> = iolist_to_binary(re:replace("MORE THAN MILLION","(?:(?s-i)more.*than).*million","\\1qCci&VKLJ&QtwPOr",[caseless,
- global])),
<<"more
than
million">> = iolist_to_binary(re:replace("more
than
- million","(?:(?s-i)more.*than).*million","N",[caseless])),
+ million","(?:(?s-i)more.*than).*million","QA\\1&",[caseless])),
<<"more
than
million">> = iolist_to_binary(re:replace("more
than
- million","(?:(?s-i)more.*than).*million","N",[caseless,global])),
- <<"dAgcabcrYrHG">> = iolist_to_binary(re:replace("abc","(?>a(?i)b+)+c","dAgc&rYrH\\1\\1G",[])),
- <<"dAgcabcrYrHG">> = iolist_to_binary(re:replace("abc","(?>a(?i)b+)+c","dAgc&rYrH\\1\\1G",[global])),
- <<"fXy">> = iolist_to_binary(re:replace("aBbc","(?>a(?i)b+)+c","fXy",[])),
- <<"fXy">> = iolist_to_binary(re:replace("aBbc","(?>a(?i)b+)+c","fXy",[global])),
- <<"y">> = iolist_to_binary(re:replace("aBBc","(?>a(?i)b+)+c","y",[])),
- <<"y">> = iolist_to_binary(re:replace("aBBc","(?>a(?i)b+)+c","y",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>a(?i)b+)+c","riGTl\\1gCN&tFIx",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>a(?i)b+)+c","riGTl\\1gCN&tFIx",[global])),
- <<"Abc">> = iolist_to_binary(re:replace("Abc","(?>a(?i)b+)+c","QnNFHC\\1\\1AJpJokFLyM",[])),
- <<"Abc">> = iolist_to_binary(re:replace("Abc","(?>a(?i)b+)+c","QnNFHC\\1\\1AJpJokFLyM",[global])),
- <<"abAb">> = iolist_to_binary(re:replace("abAb","(?>a(?i)b+)+c","yrdamBD",[])),
- <<"abAb">> = iolist_to_binary(re:replace("abAb","(?>a(?i)b+)+c","yrdamBD",[global])),
- <<"abbC">> = iolist_to_binary(re:replace("abbC","(?>a(?i)b+)+c","\\1&a&x",[])),
- <<"abbC">> = iolist_to_binary(re:replace("abbC","(?>a(?i)b+)+c","\\1&a&x",[global])),
- <<"WnabchdOabcXw">> = iolist_to_binary(re:replace("abc","(?=a(?i)b)\\w\\wc","Wn\\1\\1&hdO&Xw",[])),
- <<"WnabchdOabcXw">> = iolist_to_binary(re:replace("abc","(?=a(?i)b)\\w\\wc","Wn\\1\\1&hdO&Xw",[global])),
- <<"NUnsaGHpA">> = iolist_to_binary(re:replace("aBc","(?=a(?i)b)\\w\\wc","NUnsaGHp\\1A",[])),
- <<"NUnsaGHpA">> = iolist_to_binary(re:replace("aBc","(?=a(?i)b)\\w\\wc","NUnsaGHp\\1A",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?=a(?i)b)\\w\\wc","J",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?=a(?i)b)\\w\\wc","J",[global])),
- <<"Ab">> = iolist_to_binary(re:replace("Ab","(?=a(?i)b)\\w\\wc","rA\\1tmLWYJdpHtIJ\\1",[])),
- <<"Ab">> = iolist_to_binary(re:replace("Ab","(?=a(?i)b)\\w\\wc","rA\\1tmLWYJdpHtIJ\\1",[global])),
- <<"abC">> = iolist_to_binary(re:replace("abC","(?=a(?i)b)\\w\\wc","O",[])),
- <<"abC">> = iolist_to_binary(re:replace("abC","(?=a(?i)b)\\w\\wc","O",[global])),
- <<"aBC">> = iolist_to_binary(re:replace("aBC","(?=a(?i)b)\\w\\wc","xrOeHr\\1Ws\\1FvkVpoU",[])),
- <<"aBC">> = iolist_to_binary(re:replace("aBC","(?=a(?i)b)\\w\\wc","xrOeHr\\1Ws\\1FvkVpoU",[global])),
- <<"abcFSPxxcxxctgbJkxxNdQS">> = iolist_to_binary(re:replace("abxxc","(?<=a(?i)b)(\\w\\w)c","cFSP&&tgbJk\\1NdQS",[])),
- <<"abcFSPxxcxxctgbJkxxNdQS">> = iolist_to_binary(re:replace("abxxc","(?<=a(?i)b)(\\w\\w)c","cFSP&&tgbJk\\1NdQS",[global])),
- <<"aBQNAt">> = iolist_to_binary(re:replace("aBxxc","(?<=a(?i)b)(\\w\\w)c","QNAt",[])),
- <<"aBQNAt">> = iolist_to_binary(re:replace("aBxxc","(?<=a(?i)b)(\\w\\w)c","QNAt",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=a(?i)b)(\\w\\w)c","inxwegNttyrc",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=a(?i)b)(\\w\\w)c","inxwegNttyrc",[global])),
- <<"Abxxc">> = iolist_to_binary(re:replace("Abxxc","(?<=a(?i)b)(\\w\\w)c","YUsRHD&",[])),
- <<"Abxxc">> = iolist_to_binary(re:replace("Abxxc","(?<=a(?i)b)(\\w\\w)c","YUsRHD&",[global])),
- <<"ABxxc">> = iolist_to_binary(re:replace("ABxxc","(?<=a(?i)b)(\\w\\w)c","CXJBefD\\1kemWbn&fyJ",[])),
- <<"ABxxc">> = iolist_to_binary(re:replace("ABxxc","(?<=a(?i)b)(\\w\\w)c","CXJBefD\\1kemWbn&fyJ",[global])),
- <<"abxxC">> = iolist_to_binary(re:replace("abxxC","(?<=a(?i)b)(\\w\\w)c","UjT\\1hGcc&\\1K",[])),
- <<"abxxC">> = iolist_to_binary(re:replace("abxxC","(?<=a(?i)b)(\\w\\w)c","UjT\\1hGcc&\\1K",[global])),
- <<"e">> = iolist_to_binary(re:replace("aA","(?:(a)|b)(?(1)A|B)","e",[])),
- <<"e">> = iolist_to_binary(re:replace("aA","(?:(a)|b)(?(1)A|B)","e",[global])),
- <<"NMcPpQyHaNfjCbBaD">> = iolist_to_binary(re:replace("bB","(?:(a)|b)(?(1)A|B)","\\1NMcPpQyHaNfjC&aD",[])),
- <<"NMcPpQyHaNfjCbBaD">> = iolist_to_binary(re:replace("bB","(?:(a)|b)(?(1)A|B)","\\1NMcPpQyHaNfjC&aD",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(a)|b)(?(1)A|B)","\\1Q",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(a)|b)(?(1)A|B)","\\1Q",[global])),
- <<"aB">> = iolist_to_binary(re:replace("aB","(?:(a)|b)(?(1)A|B)","&SMEo&XGCCInDGmiby",[])),
- <<"aB">> = iolist_to_binary(re:replace("aB","(?:(a)|b)(?(1)A|B)","&SMEo&XGCCInDGmiby",[global])),
- <<"bA">> = iolist_to_binary(re:replace("bA","(?:(a)|b)(?(1)A|B)","UUW&\\1&SC\\1",[])),
- <<"bA">> = iolist_to_binary(re:replace("bA","(?:(a)|b)(?(1)A|B)","UUW&\\1&SC\\1",[global])),
- <<"FeSwwOaSaLaaSV">> = iolist_to_binary(re:replace("aa","^(a)?(?(1)a|b)+$","FeSwwO\\1S\\1L&SV",[])),
- <<"FeSwwOaSaLaaSV">> = iolist_to_binary(re:replace("aa","^(a)?(?(1)a|b)+$","FeSwwO\\1S\\1L&SV",[global])),
- <<"JTW">> = iolist_to_binary(re:replace("b","^(a)?(?(1)a|b)+$","JTW",[])),
- <<"JTW">> = iolist_to_binary(re:replace("b","^(a)?(?(1)a|b)+$","JTW",[global])),
- <<"rbbbbmbfbxJobbhlCHbbbbdR">> = iolist_to_binary(re:replace("bb","^(a)?(?(1)a|b)+$","r&&mbfbxJo&hlCH&&dR\\1",[])),
- <<"rbbbbmbfbxJobbhlCHbbbbdR">> = iolist_to_binary(re:replace("bb","^(a)?(?(1)a|b)+$","r&&mbfbxJo&hlCH&&dR\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a)?(?(1)a|b)+$","RLV&s",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a)?(?(1)a|b)+$","RLV&s",[global])),
- <<"ab">> = iolist_to_binary(re:replace("ab","^(a)?(?(1)a|b)+$","QoxGv\\1Pa&\\1mowml",[])),
- <<"ab">> = iolist_to_binary(re:replace("ab","^(a)?(?(1)a|b)+$","QoxGv\\1Pa&\\1mowml",[global])),
- <<"cfabc:abc:">> = iolist_to_binary(re:replace("abc:","^(?(?=abc)\\w{3}:|\\d\\d)$","cf&&",[])),
- <<"cfabc:abc:">> = iolist_to_binary(re:replace("abc:","^(?(?=abc)\\w{3}:|\\d\\d)$","cf&&",[global])),
- <<"IKeMxScgslGf">> = iolist_to_binary(re:replace("12","^(?(?=abc)\\w{3}:|\\d\\d)$","IKeMxScgsl\\1\\1Gf",[])),
- <<"IKeMxScgslGf">> = iolist_to_binary(re:replace("12","^(?(?=abc)\\w{3}:|\\d\\d)$","IKeMxScgsl\\1\\1Gf",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(?=abc)\\w{3}:|\\d\\d)$","cCGveJFFUHnS\\1S",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(?=abc)\\w{3}:|\\d\\d)$","cCGveJFFUHnS\\1S",[global])),
- <<"123">> = iolist_to_binary(re:replace("123","^(?(?=abc)\\w{3}:|\\d\\d)$","kudsG&Hdk",[])),
- <<"123">> = iolist_to_binary(re:replace("123","^(?(?=abc)\\w{3}:|\\d\\d)$","kudsG&Hdk",[global])),
- <<"xyz">> = iolist_to_binary(re:replace("xyz","^(?(?=abc)\\w{3}:|\\d\\d)$","&kyqj\\1U\\1\\1\\1",[])),
- <<"xyz">> = iolist_to_binary(re:replace("xyz","^(?(?=abc)\\w{3}:|\\d\\d)$","&kyqj\\1U\\1\\1\\1",[global])),
+ million","(?:(?s-i)more.*than).*million","QA\\1&",[caseless,global])),
+ <<"DxMdabcH">> = iolist_to_binary(re:replace("abc","(?>a(?i)b+)+c","DxMd&H",[])),
+ <<"DxMdabcH">> = iolist_to_binary(re:replace("abc","(?>a(?i)b+)+c","DxMd&H",[global])),
+ <<"GBQiDroaaBbcF">> = iolist_to_binary(re:replace("aBbc","(?>a(?i)b+)+c","GBQiDroa&F\\1",[])),
+ <<"GBQiDroaaBbcF">> = iolist_to_binary(re:replace("aBbc","(?>a(?i)b+)+c","GBQiDroa&F\\1",[global])),
+ <<"daBBcvQhyA">> = iolist_to_binary(re:replace("aBBc","(?>a(?i)b+)+c","d&vQhyA",[])),
+ <<"daBBcvQhyA">> = iolist_to_binary(re:replace("aBBc","(?>a(?i)b+)+c","d&vQhyA",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>a(?i)b+)+c","htKB",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>a(?i)b+)+c","htKB",[global])),
+ <<"Abc">> = iolist_to_binary(re:replace("Abc","(?>a(?i)b+)+c","vR&jLCa\\1y\\1cD",[])),
+ <<"Abc">> = iolist_to_binary(re:replace("Abc","(?>a(?i)b+)+c","vR&jLCa\\1y\\1cD",[global])),
+ <<"abAb">> = iolist_to_binary(re:replace("abAb","(?>a(?i)b+)+c","lG",[])),
+ <<"abAb">> = iolist_to_binary(re:replace("abAb","(?>a(?i)b+)+c","lG",[global])),
+ <<"abbC">> = iolist_to_binary(re:replace("abbC","(?>a(?i)b+)+c","cb&\\1",[])),
+ <<"abbC">> = iolist_to_binary(re:replace("abbC","(?>a(?i)b+)+c","cb&\\1",[global])),
+ <<"QBObvsfLS">> = iolist_to_binary(re:replace("abc","(?=a(?i)b)\\w\\wc","QBObvsfLS",[])),
+ <<"QBObvsfLS">> = iolist_to_binary(re:replace("abc","(?=a(?i)b)\\w\\wc","QBObvsfLS",[global])),
+ <<"muFQTEaBcEaBcPEBB">> = iolist_to_binary(re:replace("aBc","(?=a(?i)b)\\w\\wc","mu\\1FQ\\1TE&E&P\\1EBB\\1",[])),
+ <<"muFQTEaBcEaBcPEBB">> = iolist_to_binary(re:replace("aBc","(?=a(?i)b)\\w\\wc","mu\\1FQ\\1TE&E&P\\1EBB\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?=a(?i)b)\\w\\wc","drqTU\\1pJ\\1&vsu&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?=a(?i)b)\\w\\wc","drqTU\\1pJ\\1&vsu&",[global])),
+ <<"Ab">> = iolist_to_binary(re:replace("Ab","(?=a(?i)b)\\w\\wc","w&t\\1S\\1Q&",[])),
+ <<"Ab">> = iolist_to_binary(re:replace("Ab","(?=a(?i)b)\\w\\wc","w&t\\1S\\1Q&",[global])),
+ <<"abC">> = iolist_to_binary(re:replace("abC","(?=a(?i)b)\\w\\wc","BU\\1mgeWbSPrmQu\\1h",[])),
+ <<"abC">> = iolist_to_binary(re:replace("abC","(?=a(?i)b)\\w\\wc","BU\\1mgeWbSPrmQu\\1h",[global])),
+ <<"aBC">> = iolist_to_binary(re:replace("aBC","(?=a(?i)b)\\w\\wc","Ahi\\1D",[])),
+ <<"aBC">> = iolist_to_binary(re:replace("aBC","(?=a(?i)b)\\w\\wc","Ahi\\1D",[global])),
+ <<"abxJwrB">> = iolist_to_binary(re:replace("abxxc","(?<=a(?i)b)(\\w\\w)c","xJwrB",[])),
+ <<"abxJwrB">> = iolist_to_binary(re:replace("abxxc","(?<=a(?i)b)(\\w\\w)c","xJwrB",[global])),
+ <<"aBWqYokXSFmo">> = iolist_to_binary(re:replace("aBxxc","(?<=a(?i)b)(\\w\\w)c","WqYokXSFmo",[])),
+ <<"aBWqYokXSFmo">> = iolist_to_binary(re:replace("aBxxc","(?<=a(?i)b)(\\w\\w)c","WqYokXSFmo",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=a(?i)b)(\\w\\w)c","ViVjAQCNIlGCB\\1RW\\1Ks",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=a(?i)b)(\\w\\w)c","ViVjAQCNIlGCB\\1RW\\1Ks",[global])),
+ <<"Abxxc">> = iolist_to_binary(re:replace("Abxxc","(?<=a(?i)b)(\\w\\w)c","c&\\1y&",[])),
+ <<"Abxxc">> = iolist_to_binary(re:replace("Abxxc","(?<=a(?i)b)(\\w\\w)c","c&\\1y&",[global])),
+ <<"ABxxc">> = iolist_to_binary(re:replace("ABxxc","(?<=a(?i)b)(\\w\\w)c","U",[])),
+ <<"ABxxc">> = iolist_to_binary(re:replace("ABxxc","(?<=a(?i)b)(\\w\\w)c","U",[global])),
+ <<"abxxC">> = iolist_to_binary(re:replace("abxxC","(?<=a(?i)b)(\\w\\w)c","\\1qT\\1bjyP\\1\\1Ki\\1iMujiN",[])),
+ <<"abxxC">> = iolist_to_binary(re:replace("abxxC","(?<=a(?i)b)(\\w\\w)c","\\1qT\\1bjyP\\1\\1Ki\\1iMujiN",[global])),
+ <<"PLaeaJqVIraaAoco">> = iolist_to_binary(re:replace("aA","(?:(a)|b)(?(1)A|B)","PLae\\1JqVIra&oco",[])),
+ <<"PLaeaJqVIraaAoco">> = iolist_to_binary(re:replace("aA","(?:(a)|b)(?(1)A|B)","PLae\\1JqVIra&oco",[global])),
+ <<"GsAhcAqbBHmjdSmKbBt">> = iolist_to_binary(re:replace("bB","(?:(a)|b)(?(1)A|B)","GsAhcAq&HmjdSm\\1K&t",[])),
+ <<"GsAhcAqbBHmjdSmKbBt">> = iolist_to_binary(re:replace("bB","(?:(a)|b)(?(1)A|B)","GsAhcAq&HmjdSm\\1K&t",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(a)|b)(?(1)A|B)","jMnYwcU\\1q\\1D\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(a)|b)(?(1)A|B)","jMnYwcU\\1q\\1D\\1",[global])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","(?:(a)|b)(?(1)A|B)","B&\\1\\1fcB\\1IWxCjS&liri",[])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","(?:(a)|b)(?(1)A|B)","B&\\1\\1fcB\\1IWxCjS&liri",[global])),
+ <<"bA">> = iolist_to_binary(re:replace("bA","(?:(a)|b)(?(1)A|B)","wN&v\\1em",[])),
+ <<"bA">> = iolist_to_binary(re:replace("bA","(?:(a)|b)(?(1)A|B)","wN&v\\1em",[global])),
+ <<"oX">> = iolist_to_binary(re:replace("aa","^(a)?(?(1)a|b)+$","oX",[])),
+ <<"oX">> = iolist_to_binary(re:replace("aa","^(a)?(?(1)a|b)+$","oX",[global])),
+ <<"EjqBbBji">> = iolist_to_binary(re:replace("b","^(a)?(?(1)a|b)+$","Ej\\1qB&Bj\\1i",[])),
+ <<"EjqBbBji">> = iolist_to_binary(re:replace("b","^(a)?(?(1)a|b)+$","Ej\\1qB&Bj\\1i",[global])),
+ <<"">> = iolist_to_binary(re:replace("bb","^(a)?(?(1)a|b)+$","\\1",[])),
+ <<"">> = iolist_to_binary(re:replace("bb","^(a)?(?(1)a|b)+$","\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a)?(?(1)a|b)+$","ra",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a)?(?(1)a|b)+$","ra",[global])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","^(a)?(?(1)a|b)+$","EHLgXekX",[])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","^(a)?(?(1)a|b)+$","EHLgXekX",[global])),
ok.
run13() ->
- <<"yLejabc:ClvDam">> = iolist_to_binary(re:replace("abc:","^(?(?!abc)\\d\\d|\\w{3}:)$","yLej&C\\1lvDa\\1m",[])),
- <<"yLejabc:ClvDam">> = iolist_to_binary(re:replace("abc:","^(?(?!abc)\\d\\d|\\w{3}:)$","yLej&C\\1lvDa\\1m",[global])),
- <<"eH12Ase">> = iolist_to_binary(re:replace("12","^(?(?!abc)\\d\\d|\\w{3}:)$","e\\1H&A\\1s\\1\\1e",[])),
- <<"eH12Ase">> = iolist_to_binary(re:replace("12","^(?(?!abc)\\d\\d|\\w{3}:)$","e\\1H&A\\1s\\1\\1e",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(?!abc)\\d\\d|\\w{3}:)$","SMtlNLKd\\1Va",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(?!abc)\\d\\d|\\w{3}:)$","SMtlNLKd\\1Va",[global])),
- <<"123">> = iolist_to_binary(re:replace("123","^(?(?!abc)\\d\\d|\\w{3}:)$","VsMY&We",[])),
- <<"123">> = iolist_to_binary(re:replace("123","^(?(?!abc)\\d\\d|\\w{3}:)$","VsMY&We",[global])),
- <<"xyz">> = iolist_to_binary(re:replace("xyz","^(?(?!abc)\\d\\d|\\w{3}:)$","j&k\\1tUeAYRn",[])),
- <<"xyz">> = iolist_to_binary(re:replace("xyz","^(?(?!abc)\\d\\d|\\w{3}:)$","j&k\\1tUeAYRn",[global])),
- <<"fooS">> = iolist_to_binary(re:replace("foobar","(?(?<=foo)bar|cat)","S\\1",[])),
- <<"fooS">> = iolist_to_binary(re:replace("foobar","(?(?<=foo)bar|cat)","S\\1",[global])),
- <<"catdEUboccGWTaRjQo">> = iolist_to_binary(re:replace("cat","(?(?<=foo)bar|cat)","&dEU\\1boccGWTaRjQo\\1",[])),
- <<"catdEUboccGWTaRjQo">> = iolist_to_binary(re:replace("cat","(?(?<=foo)bar|cat)","&dEU\\1boccGWTaRjQo\\1",[global])),
- <<"fcatrspJwF">> = iolist_to_binary(re:replace("fcat","(?(?<=foo)bar|cat)","\\1&rs\\1pJwF",[])),
- <<"fcatrspJwF">> = iolist_to_binary(re:replace("fcat","(?(?<=foo)bar|cat)","\\1&rs\\1pJwF",[global])),
- <<"foncatePTv">> = iolist_to_binary(re:replace("focat","(?(?<=foo)bar|cat)","n&ePTv",[])),
- <<"foncatePTv">> = iolist_to_binary(re:replace("focat","(?(?<=foo)bar|cat)","n&ePTv",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?<=foo)bar|cat)","jI",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?<=foo)bar|cat)","jI",[global])),
- <<"foocat">> = iolist_to_binary(re:replace("foocat","(?(?<=foo)bar|cat)","\\1qBlA\\1veXv",[])),
- <<"foocat">> = iolist_to_binary(re:replace("foocat","(?(?<=foo)bar|cat)","\\1qBlA\\1veXv",[global])),
- <<"fooYHnkCeSOb">> = iolist_to_binary(re:replace("foobar","(?(?<!foo)cat|bar)","YHnkCeSOb",[])),
- <<"fooYHnkCeSOb">> = iolist_to_binary(re:replace("foobar","(?(?<!foo)cat|bar)","YHnkCeSOb",[global])),
- <<"catcatQAKgfdmvWBVj">> = iolist_to_binary(re:replace("cat","(?(?<!foo)cat|bar)","&&QAK\\1gfdmvWBVj",[])),
- <<"catcatQAKgfdmvWBVj">> = iolist_to_binary(re:replace("cat","(?(?<!foo)cat|bar)","&&QAK\\1gfdmvWBVj",[global])),
- <<"fPR">> = iolist_to_binary(re:replace("fcat","(?(?<!foo)cat|bar)","PR",[])),
- <<"fPR">> = iolist_to_binary(re:replace("fcat","(?(?<!foo)cat|bar)","PR",[global])),
- <<"fo">> = iolist_to_binary(re:replace("focat","(?(?<!foo)cat|bar)","\\1",[])),
- <<"fo">> = iolist_to_binary(re:replace("focat","(?(?<!foo)cat|bar)","\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?<!foo)cat|bar)","qsIpnmEbaYk\\1H",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?<!foo)cat|bar)","qsIpnmEbaYk\\1H",[global])),
- <<"foocat">> = iolist_to_binary(re:replace("foocat","(?(?<!foo)cat|bar)","B",[])),
- <<"foocat">> = iolist_to_binary(re:replace("foocat","(?(?<!foo)cat|bar)","B",[global])),
- <<"bclabcdfaLGxBabcdHtjFC">> = iolist_to_binary(re:replace("abcd","( \\( )? [^()]+ (?(1) \\) |) ","bcl&faLGxB\\1&HtjFC",[extended])),
- <<"bclabcdfaLGxBabcdHtjFC">> = iolist_to_binary(re:replace("abcd","( \\( )? [^()]+ (?(1) \\) |) ","bcl&faLGxB\\1&HtjFC",[extended,
- global])),
- <<"JpguAHp((E(AF(">> = iolist_to_binary(re:replace("(abcd)","( \\( )? [^()]+ (?(1) \\) |) ","JpguAHp\\1\\1E\\1AF\\1",[extended])),
- <<"JpguAHp((E(AF(">> = iolist_to_binary(re:replace("(abcd)","( \\( )? [^()]+ (?(1) \\) |) ","JpguAHp\\1\\1E\\1AF\\1",[extended,
- global])),
- <<"yBpRsrthe quick Nr(abcd) fox">> = iolist_to_binary(re:replace("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) |) ","yBpRsr&Nr\\1",[extended])),
- <<"yBpRsrthe quick NryBpRsr(abcd)Nr(yBpRsr foxNr">> = iolist_to_binary(re:replace("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) |) ","yBpRsr&Nr\\1",[extended,
- global])),
- <<"(dfabcdMfidabcdORabcdXp">> = iolist_to_binary(re:replace("(abcd","( \\( )? [^()]+ (?(1) \\) |) ","df&Mfid\\1\\1&OR&Xp",[extended])),
- <<"(dfabcdMfidabcdORabcdXp">> = iolist_to_binary(re:replace("(abcd","( \\( )? [^()]+ (?(1) \\) |) ","df&Mfid\\1\\1&OR&Xp",[extended,
- global])),
- <<"NEKtshVcSbEQreXJUgabcd">> = iolist_to_binary(re:replace("abcd","( \\( )? [^()]+ (?(1) \\) ) ","NEKtshVcSbEQre\\1XJUg&",[extended])),
- <<"NEKtshVcSbEQreXJUgabcd">> = iolist_to_binary(re:replace("abcd","( \\( )? [^()]+ (?(1) \\) ) ","NEKtshVcSbEQre\\1XJUg&",[extended,
- global])),
- <<"C">> = iolist_to_binary(re:replace("(abcd)","( \\( )? [^()]+ (?(1) \\) ) ","C",[extended])),
- <<"C">> = iolist_to_binary(re:replace("(abcd)","( \\( )? [^()]+ (?(1) \\) ) ","C",[extended,
+ <<"rabc:abc:Kabc:rcuwyQBhDRgB">> = iolist_to_binary(re:replace("abc:","^(?(?=abc)\\w{3}:|\\d\\d)$","r&&K&\\1rcuwyQBhD\\1RgB",[])),
+ <<"rabc:abc:Kabc:rcuwyQBhDRgB">> = iolist_to_binary(re:replace("abc:","^(?(?=abc)\\w{3}:|\\d\\d)$","r&&K&\\1rcuwyQBhD\\1RgB",[global])),
+ <<"DMbrBdk">> = iolist_to_binary(re:replace("12","^(?(?=abc)\\w{3}:|\\d\\d)$","DM\\1br\\1Bdk",[])),
+ <<"DMbrBdk">> = iolist_to_binary(re:replace("12","^(?(?=abc)\\w{3}:|\\d\\d)$","DM\\1br\\1Bdk",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(?=abc)\\w{3}:|\\d\\d)$","XeCprJu&qUw\\1Af&&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(?=abc)\\w{3}:|\\d\\d)$","XeCprJu&qUw\\1Af&&",[global])),
+ <<"123">> = iolist_to_binary(re:replace("123","^(?(?=abc)\\w{3}:|\\d\\d)$","r\\1jcw",[])),
+ <<"123">> = iolist_to_binary(re:replace("123","^(?(?=abc)\\w{3}:|\\d\\d)$","r\\1jcw",[global])),
+ <<"xyz">> = iolist_to_binary(re:replace("xyz","^(?(?=abc)\\w{3}:|\\d\\d)$","\\1usowFJ\\1EG\\1MYM",[])),
+ <<"xyz">> = iolist_to_binary(re:replace("xyz","^(?(?=abc)\\w{3}:|\\d\\d)$","\\1usowFJ\\1EG\\1MYM",[global])),
+ <<"Aabc:Fabc:tlJ">> = iolist_to_binary(re:replace("abc:","^(?(?!abc)\\d\\d|\\w{3}:)$","A&F&tlJ",[])),
+ <<"Aabc:Fabc:tlJ">> = iolist_to_binary(re:replace("abc:","^(?(?!abc)\\d\\d|\\w{3}:)$","A&F&tlJ",[global])),
+ <<"iX">> = iolist_to_binary(re:replace("12","^(?(?!abc)\\d\\d|\\w{3}:)$","iX",[])),
+ <<"iX">> = iolist_to_binary(re:replace("12","^(?(?!abc)\\d\\d|\\w{3}:)$","iX",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(?!abc)\\d\\d|\\w{3}:)$","j&&J\\1&I",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(?!abc)\\d\\d|\\w{3}:)$","j&&J\\1&I",[global])),
+ <<"123">> = iolist_to_binary(re:replace("123","^(?(?!abc)\\d\\d|\\w{3}:)$","kj\\1lukbPh&su\\1Cghlveb",[])),
+ <<"123">> = iolist_to_binary(re:replace("123","^(?(?!abc)\\d\\d|\\w{3}:)$","kj\\1lukbPh&su\\1Cghlveb",[global])),
+ <<"xyz">> = iolist_to_binary(re:replace("xyz","^(?(?!abc)\\d\\d|\\w{3}:)$","uXqdQvfv&\\1tC\\1ipRP",[])),
+ <<"xyz">> = iolist_to_binary(re:replace("xyz","^(?(?!abc)\\d\\d|\\w{3}:)$","uXqdQvfv&\\1tC\\1ipRP",[global])),
+ <<"foopoYUMCLsWcRfrX">> = iolist_to_binary(re:replace("foobar","(?(?<=foo)bar|cat)","poYUMCLsWcR\\1fr\\1X\\1",[])),
+ <<"foopoYUMCLsWcRfrX">> = iolist_to_binary(re:replace("foobar","(?(?<=foo)bar|cat)","poYUMCLsWcR\\1fr\\1X\\1",[global])),
+ <<"EcatihCGRgMPqq">> = iolist_to_binary(re:replace("cat","(?(?<=foo)bar|cat)","E&ihCGRgMPqq\\1",[])),
+ <<"EcatihCGRgMPqq">> = iolist_to_binary(re:replace("cat","(?(?<=foo)bar|cat)","E&ihCGRgMPqq\\1",[global])),
+ <<"fQRocatSScatcat">> = iolist_to_binary(re:replace("fcat","(?(?<=foo)bar|cat)","QRo&SS&&",[])),
+ <<"fQRocatSScatcat">> = iolist_to_binary(re:replace("fcat","(?(?<=foo)bar|cat)","QRo&SS&&",[global])),
+ <<"foDk">> = iolist_to_binary(re:replace("focat","(?(?<=foo)bar|cat)","D\\1k\\1",[])),
+ <<"foDk">> = iolist_to_binary(re:replace("focat","(?(?<=foo)bar|cat)","D\\1k\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?<=foo)bar|cat)","soL&R\\1GSAmJChxOln",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?<=foo)bar|cat)","soL&R\\1GSAmJChxOln",[global])),
+ <<"foocat">> = iolist_to_binary(re:replace("foocat","(?(?<=foo)bar|cat)","y&e",[])),
+ <<"foocat">> = iolist_to_binary(re:replace("foocat","(?(?<=foo)bar|cat)","y&e",[global])),
+ <<"fookbarnSruMXTFCE">> = iolist_to_binary(re:replace("foobar","(?(?<!foo)cat|bar)","k\\1&nSruMXTFCE\\1",[])),
+ <<"fookbarnSruMXTFCE">> = iolist_to_binary(re:replace("foobar","(?(?<!foo)cat|bar)","k\\1&nSruMXTFCE\\1",[global])),
+ <<"ynvicatccatYCXYPUdcatHi">> = iolist_to_binary(re:replace("cat","(?(?<!foo)cat|bar)","\\1y\\1\\1nvi&c&YCXYPUd&Hi",[])),
+ <<"ynvicatccatYCXYPUdcatHi">> = iolist_to_binary(re:replace("cat","(?(?<!foo)cat|bar)","\\1y\\1\\1nvi&c&YCXYPUd&Hi",[global])),
+ <<"fGOpcatbyuUbSQjcatV">> = iolist_to_binary(re:replace("fcat","(?(?<!foo)cat|bar)","GOp&by\\1uUbSQj&V",[])),
+ <<"fGOpcatbyuUbSQjcatV">> = iolist_to_binary(re:replace("fcat","(?(?<!foo)cat|bar)","GOp&by\\1uUbSQj&V",[global])),
+ <<"foU">> = iolist_to_binary(re:replace("focat","(?(?<!foo)cat|bar)","U",[])),
+ <<"foU">> = iolist_to_binary(re:replace("focat","(?(?<!foo)cat|bar)","U",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?<!foo)cat|bar)","NglUgPv\\1IB&\\1XMXPO",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?<!foo)cat|bar)","NglUgPv\\1IB&\\1XMXPO",[global])),
+ <<"foocat">> = iolist_to_binary(re:replace("foocat","(?(?<!foo)cat|bar)","&tLnp",[])),
+ <<"foocat">> = iolist_to_binary(re:replace("foocat","(?(?<!foo)cat|bar)","&tLnp",[global])),
+ <<"vF">> = iolist_to_binary(re:replace("abcd","( \\( )? [^()]+ (?(1) \\) |) ","vF",[extended])),
+ <<"vF">> = iolist_to_binary(re:replace("abcd","( \\( )? [^()]+ (?(1) \\) |) ","vF",[extended,
global])),
- <<"VsQthe quick tPGwwMthe quick WRxuthe quick (abcd) fox">> = iolist_to_binary(re:replace("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) ) ","VsQ&tP\\1Gww\\1M&WRxu&",[extended])),
- <<"VsQthe quick tPGwwMthe quick WRxuthe quick VsQ(abcd)tP(Gww(M(abcd)WRxu(abcd)VsQ foxtPGwwM foxWRxu fox">> = iolist_to_binary(re:replace("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) ) ","VsQ&tP\\1Gww\\1M&WRxu&",[extended,
- global])),
- <<"(BxtHoabcdhwabcdMSlPc">> = iolist_to_binary(re:replace("(abcd","( \\( )? [^()]+ (?(1) \\) ) ","BxtHo&hw&MSlPc",[extended])),
- <<"(BxtHoabcdhwabcdMSlPc">> = iolist_to_binary(re:replace("(abcd","( \\( )? [^()]+ (?(1) \\) ) ","BxtHo&hw&MSlPc",[extended,
- global])),
- <<"112MIb11212MLRT11">> = iolist_to_binary(re:replace("12","^(?(2)a|(1)(2))+$","\\1&MIb\\1&&MLRT\\1\\1",[])),
- <<"112MIb11212MLRT11">> = iolist_to_binary(re:replace("12","^(?(2)a|(1)(2))+$","\\1&MIb\\1&&MLRT\\1\\1",[global])),
- <<"NKCJyodsYQD">> = iolist_to_binary(re:replace("12a","^(?(2)a|(1)(2))+$","NKCJyodsYQD",[])),
- <<"NKCJyodsYQD">> = iolist_to_binary(re:replace("12a","^(?(2)a|(1)(2))+$","NKCJyodsYQD",[global])),
- <<"12aarChjGgkuN">> = iolist_to_binary(re:replace("12aa","^(?(2)a|(1)(2))+$","&rChjGgkuN",[])),
- <<"12aarChjGgkuN">> = iolist_to_binary(re:replace("12aa","^(?(2)a|(1)(2))+$","&rChjGgkuN",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(2)a|(1)(2))+$","\\1\\1be\\1ix",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(2)a|(1)(2))+$","\\1\\1be\\1ix",[global])),
- <<"1234">> = iolist_to_binary(re:replace("1234","^(?(2)a|(1)(2))+$","cLDE&D",[])),
- <<"1234">> = iolist_to_binary(re:replace("1234","^(?(2)a|(1)(2))+$","cLDE&D",[global])),
- <<"kNHtojblahPblahcuUuarKNnoK">> = iolist_to_binary(re:replace("blah blah","((?i)blah)\\s+\\1","kNHtoj\\1P\\1cuUuarKNnoK",[])),
- <<"kNHtojblahPblahcuUuarKNnoK">> = iolist_to_binary(re:replace("blah blah","((?i)blah)\\s+\\1","kNHtoj\\1P\\1cuUuarKNnoK",[global])),
- <<"eNBLAHlXaMBLAH BLAH">> = iolist_to_binary(re:replace("BLAH BLAH","((?i)blah)\\s+\\1","eN\\1lXaM&",[])),
- <<"eNBLAHlXaMBLAH BLAH">> = iolist_to_binary(re:replace("BLAH BLAH","((?i)blah)\\s+\\1","eN\\1lXaM&",[global])),
- <<"rBlah BlahSGW">> = iolist_to_binary(re:replace("Blah Blah","((?i)blah)\\s+\\1","r&SGW",[])),
- <<"rBlah BlahSGW">> = iolist_to_binary(re:replace("Blah Blah","((?i)blah)\\s+\\1","r&SGW",[global])),
- <<"fUTblaH blaHblaH blaHtHeblaH blaHDlblaH blaHwQonyN">> = iolist_to_binary(re:replace("blaH blaH","((?i)blah)\\s+\\1","fUT&&tHe&Dl&wQonyN",[])),
- <<"fUTblaH blaHblaH blaHtHeblaH blaHDlblaH blaHwQonyN">> = iolist_to_binary(re:replace("blaH blaH","((?i)blah)\\s+\\1","fUT&&tHe&Dl&wQonyN",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?i)blah)\\s+\\1","rjKWYO&gqg",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?i)blah)\\s+\\1","rjKWYO&gqg",[global])),
- <<"blah BLAH">> = iolist_to_binary(re:replace("blah BLAH","((?i)blah)\\s+\\1","\\1PJEx&&NqPQ",[])),
- <<"blah BLAH">> = iolist_to_binary(re:replace("blah BLAH","((?i)blah)\\s+\\1","\\1PJEx&&NqPQ",[global])),
- <<"Blah blah">> = iolist_to_binary(re:replace("Blah blah","((?i)blah)\\s+\\1","&IAtxxKcfurkyev\\1nvDJ",[])),
- <<"Blah blah">> = iolist_to_binary(re:replace("Blah blah","((?i)blah)\\s+\\1","&IAtxxKcfurkyev\\1nvDJ",[global])),
- <<"blaH blah">> = iolist_to_binary(re:replace("blaH blah","((?i)blah)\\s+\\1","\\1\\1H&YJdrM\\1qcj&&",[])),
- <<"blaH blah">> = iolist_to_binary(re:replace("blaH blah","((?i)blah)\\s+\\1","\\1\\1H&YJdrM\\1qcj&&",[global])),
- <<"QROIQmblah blahmblahblah blahDWblahJ">> = iolist_to_binary(re:replace("blah blah","((?i)blah)\\s+(?i:\\1)","QROIQm&m\\1&DW\\1J",[])),
- <<"QROIQmblah blahmblahblah blahDWblahJ">> = iolist_to_binary(re:replace("blah blah","((?i)blah)\\s+(?i:\\1)","QROIQm&m\\1&DW\\1J",[global])),
- <<"vmvjMIXCFx">> = iolist_to_binary(re:replace("BLAH BLAH","((?i)blah)\\s+(?i:\\1)","vmvjMIXCFx",[])),
- <<"vmvjMIXCFx">> = iolist_to_binary(re:replace("BLAH BLAH","((?i)blah)\\s+(?i:\\1)","vmvjMIXCFx",[global])),
- <<"FBlahSrBlah BlahfdMtkYBlah Blah">> = iolist_to_binary(re:replace("Blah Blah","((?i)blah)\\s+(?i:\\1)","F\\1Sr&fdMtkY&",[])),
- <<"FBlahSrBlah BlahfdMtkYBlah Blah">> = iolist_to_binary(re:replace("Blah Blah","((?i)blah)\\s+(?i:\\1)","F\\1Sr&fdMtkY&",[global])),
- <<"cblaH blaHfGEblaHwablaH blaHDGblaH blaHblaH blaHLcblaHVyTC">> = iolist_to_binary(re:replace("blaH blaH","((?i)blah)\\s+(?i:\\1)","c&fGE\\1wa&DG&&Lc\\1VyTC",[])),
- <<"cblaH blaHfGEblaHwablaH blaHDGblaH blaHblaH blaHLcblaHVyTC">> = iolist_to_binary(re:replace("blaH blaH","((?i)blah)\\s+(?i:\\1)","c&fGE\\1wa&DG&&Lc\\1VyTC",[global])),
- <<"blahaefgWblah">> = iolist_to_binary(re:replace("blah BLAH","((?i)blah)\\s+(?i:\\1)","\\1aefgW\\1",[])),
- <<"blahaefgWblah">> = iolist_to_binary(re:replace("blah BLAH","((?i)blah)\\s+(?i:\\1)","\\1aefgW\\1",[global])),
- <<"Blah">> = iolist_to_binary(re:replace("Blah blah","((?i)blah)\\s+(?i:\\1)","\\1",[])),
- <<"Blah">> = iolist_to_binary(re:replace("Blah blah","((?i)blah)\\s+(?i:\\1)","\\1",[global])),
- <<"RXsblaHe">> = iolist_to_binary(re:replace("blaH blah","((?i)blah)\\s+(?i:\\1)","RXs\\1e",[])),
- <<"RXsblaHe">> = iolist_to_binary(re:replace("blaH blah","((?i)blah)\\s+(?i:\\1)","RXs\\1e",[global])),
- <<"lanoXtvE">> = iolist_to_binary(re:replace("a","(?>a*)*","lano\\1Xt\\1vE",[])),
- <<"lanoXtvElanoXtvE">> = iolist_to_binary(re:replace("a","(?>a*)*","lano\\1Xt\\1vE",[global])),
- <<"EfuiyyaaybkaaVI">> = iolist_to_binary(re:replace("aa","(?>a*)*","Ef\\1uiyy&ybk&VI",[])),
- <<"EfuiyyaaybkaaVIEfuiyyybkVI">> = iolist_to_binary(re:replace("aa","(?>a*)*","Ef\\1uiyy&ybk&VI",[global])),
- <<"DFPlAS">> = iolist_to_binary(re:replace("aaaa","(?>a*)*","DFPlAS",[])),
- <<"DFPlASDFPlAS">> = iolist_to_binary(re:replace("aaaa","(?>a*)*","DFPlAS",[global])),
- <<"swvEIpc">> = iolist_to_binary(re:replace("abc","(abc|)+","sw\\1vEIpc",[])),
- <<"swvEIpcswvEIpc">> = iolist_to_binary(re:replace("abc","(abc|)+","sw\\1vEIpc",[global])),
- <<"Vm">> = iolist_to_binary(re:replace("abcabc","(abc|)+","Vm",[])),
- <<"VmVm">> = iolist_to_binary(re:replace("abcabc","(abc|)+","Vm",[global])),
- <<"vabcabcabcIecAabcabcabcvabcabcabcabcabcabcPMS">> = iolist_to_binary(re:replace("abcabcabc","(abc|)+","v&\\1IecA&v\\1&&PMS",[])),
- <<"vabcabcabcIecAabcabcabcvabcabcabcabcabcabcPMSvIecAvPMS">> = iolist_to_binary(re:replace("abcabcabc","(abc|)+","v&\\1IecA&v\\1&&PMS",[global])),
- <<"YpHLvbPebgHxyz">> = iolist_to_binary(re:replace("xyz","(abc|)+","YpH&LvbPebgH\\1",[])),
- <<"YpHLvbPebgHxYpHLvbPebgHyYpHLvbPebgHzYpHLvbPebgH">> = iolist_to_binary(re:replace("xyz","(abc|)+","YpH&LvbPebgH\\1",[global])),
- <<"aaUe">> = iolist_to_binary(re:replace("a","([a]*)*","&&Ue",[])),
- <<"aaUeUe">> = iolist_to_binary(re:replace("a","([a]*)*","&&Ue",[global])),
- <<"PaaaaapgFufTSYIkBuaaaaabKYVD">> = iolist_to_binary(re:replace("aaaaa","([a]*)*","P&pgFufTSYIkBu&bKYVD",[])),
- <<"PaaaaapgFufTSYIkBuaaaaabKYVDPpgFufTSYIkBubKYVD">> = iolist_to_binary(re:replace("aaaaa","([a]*)*","P&pgFufTSYIkBu&bKYVD",[global])),
- <<"qFRFDX">> = iolist_to_binary(re:replace("a","([ab]*)*","qFRFDX",[])),
- <<"qFRFDXqFRFDX">> = iolist_to_binary(re:replace("a","([ab]*)*","qFRFDX",[global])),
- <<"rcPIcjqP">> = iolist_to_binary(re:replace("b","([ab]*)*","rcP\\1IcjqP",[])),
- <<"rcPIcjqPrcPIcjqP">> = iolist_to_binary(re:replace("b","([ab]*)*","rcP\\1IcjqP",[global])),
- <<"sRJuN">> = iolist_to_binary(re:replace("ababab","([ab]*)*","s\\1R\\1JuN",[])),
- <<"sRJuNsRJuN">> = iolist_to_binary(re:replace("ababab","([ab]*)*","s\\1R\\1JuN",[global])),
- <<"GIaaaabFaYFbcde">> = iolist_to_binary(re:replace("aaaabcde","([ab]*)*","GI&FaYFb",[])),
- <<"GIaaaabFaYFbGIFaYFbcGIFaYFbdGIFaYFbeGIFaYFb">> = iolist_to_binary(re:replace("aaaabcde","([ab]*)*","GI&FaYFb",[global])),
- <<"meTmwKOIyGCbbbbANbbbbbbbbH">> = iolist_to_binary(re:replace("bbbb","([ab]*)*","meTmwK\\1OIy\\1GC&AN&&H",[])),
- <<"meTmwKOIyGCbbbbANbbbbbbbbHmeTmwKOIyGCANH">> = iolist_to_binary(re:replace("bbbb","([ab]*)*","meTmwK\\1OIy\\1GC&AN&&H",[global])),
- <<"nbjCbhrDRrlgSUiVJ">> = iolist_to_binary(re:replace("b","([^a]*)*","nbjC&hrDRrlgSUiV\\1J",[])),
- <<"nbjCbhrDRrlgSUiVJnbjChrDRrlgSUiVJ">> = iolist_to_binary(re:replace("b","([^a]*)*","nbjC&hrDRrlgSUiV\\1J",[global])),
- <<"EDtjVbbbbKGDbbbbmbbbbwKLjiR">> = iolist_to_binary(re:replace("bbbb","([^a]*)*","EDtjV&KGD&m&wK\\1Lj\\1iR",[])),
- <<"EDtjVbbbbKGDbbbbmbbbbwKLjiREDtjVKGDmwKLjiR">> = iolist_to_binary(re:replace("bbbb","([^a]*)*","EDtjV&KGD&m&wK\\1Lj\\1iR",[global])),
- <<"HlaUYcKUiWycCnKHNaaa">> = iolist_to_binary(re:replace("aaa","([^a]*)*","HlaUYcKUiWycCnKH\\1N",[])),
- <<"HlaUYcKUiWycCnKHNaHlaUYcKUiWycCnKHNaHlaUYcKUiWycCnKHNaHlaUYcKUiWycCnKHN">> = iolist_to_binary(re:replace("aaa","([^a]*)*","HlaUYcKUiWycCnKH\\1N",[global])),
- <<"eaccccgCccccOYNUlccccTcccc">> = iolist_to_binary(re:replace("cccc","([^ab]*)*","ea&g\\1C&OYNUl&\\1T&",[])),
- <<"eaccccgCccccOYNUlccccTcccceagCOYNUlT">> = iolist_to_binary(re:replace("cccc","([^ab]*)*","ea&g\\1C&OYNUl&\\1T&",[global])),
- <<"JyKBqDRhnabab">> = iolist_to_binary(re:replace("abab","([^ab]*)*","Jy&\\1KBqDRhn",[])),
- <<"JyKBqDRhnaJyKBqDRhnbJyKBqDRhnaJyKBqDRhnbJyKBqDRhn">> = iolist_to_binary(re:replace("abab","([^ab]*)*","Jy&\\1KBqDRhn",[global])),
- <<"vnligHISDuDiBa">> = iolist_to_binary(re:replace("a","([a]*?)*","v\\1nli&\\1gHISDuD\\1iB",[])),
- <<"vnligHISDuDiBvnliagHISDuDiBvnligHISDuDiB">> = iolist_to_binary(re:replace("a","([a]*?)*","v\\1nli&\\1gHISDuD\\1iB",[global])),
- <<"CrarAftguXnYNULohKyaaaa">> = iolist_to_binary(re:replace("aaaa","([a]*?)*","CrarAftguXnYN&ULohKy",[])),
- <<"CrarAftguXnYNULohKyCrarAftguXnYNaULohKyCrarAftguXnYNULohKyCrarAftguXnYNaULohKyCrarAftguXnYNULohKyCrarAftguXnYNaULohKyCrarAftguXnYNULohKyCrarAftguXnYNaULohKyCrarAftguXnYNULohKy">> = iolist_to_binary(re:replace("aaaa","([a]*?)*","CrarAftguXnYN&ULohKy",[global])),
- <<"BOfINa">> = iolist_to_binary(re:replace("a","([ab]*?)*","B&OfIN&",[])),
- <<"BOfINBaOfINaBOfIN">> = iolist_to_binary(re:replace("a","([ab]*?)*","B&OfIN&",[global])),
- <<"HBxFab">> = iolist_to_binary(re:replace("b","([ab]*?)*","H\\1\\1BxF\\1a",[])),
- <<"HBxFaHBxFaHBxFa">> = iolist_to_binary(re:replace("b","([ab]*?)*","H\\1\\1BxF\\1a",[global])),
- <<"rkuWEckrabab">> = iolist_to_binary(re:replace("abab","([ab]*?)*","rkuWEc\\1kr",[])),
- <<"rkuWEckrrkuWEckrrkuWEckrrkuWEckrrkuWEckrrkuWEckrrkuWEckrrkuWEckrrkuWEckr">> = iolist_to_binary(re:replace("abab","([ab]*?)*","rkuWEc\\1kr",[global])),
- <<"dedrbsbaba">> = iolist_to_binary(re:replace("baba","([ab]*?)*","dedrbs",[])),
- <<"dedrbsdedrbsdedrbsdedrbsdedrbsdedrbsdedrbsdedrbsdedrbs">> = iolist_to_binary(re:replace("baba","([ab]*?)*","dedrbs",[global])),
- <<"b">> = iolist_to_binary(re:replace("b","([^a]*?)*","\\1",[])),
- <<"">> = iolist_to_binary(re:replace("b","([^a]*?)*","\\1",[global])),
- <<"rrARQqtjsbbbb">> = iolist_to_binary(re:replace("bbbb","([^a]*?)*","rr&ARQq\\1\\1tjs",[])),
- <<"rrARQqtjsrrbARQqtjsrrARQqtjsrrbARQqtjsrrARQqtjsrrbARQqtjsrrARQqtjsrrbARQqtjsrrARQqtjs">> = iolist_to_binary(re:replace("bbbb","([^a]*?)*","rr&ARQq\\1\\1tjs",[global])),
- <<"PGcsmlReJQeaaa">> = iolist_to_binary(re:replace("aaa","([^a]*?)*","PGcsm&&lReJQe&",[])),
- <<"PGcsmlReJQeaPGcsmlReJQeaPGcsmlReJQeaPGcsmlReJQe">> = iolist_to_binary(re:replace("aaa","([^a]*?)*","PGcsm&&lReJQe&",[global])),
- <<"nuspMpmvVOsyyChRc">> = iolist_to_binary(re:replace("c","([^ab]*?)*","nusp&Mp\\1mvVOsyyChR",[])),
- <<"nuspMpmvVOsyyChRnuspcMpmvVOsyyChRnuspMpmvVOsyyChR">> = iolist_to_binary(re:replace("c","([^ab]*?)*","nusp&Mp\\1mvVOsyyChR",[global])),
- <<"GbhjrQmJMQvcccc">> = iolist_to_binary(re:replace("cccc","([^ab]*?)*","Gbhj&rQmJMQv",[])),
- <<"GbhjrQmJMQvGbhjcrQmJMQvGbhjrQmJMQvGbhjcrQmJMQvGbhjrQmJMQvGbhjcrQmJMQvGbhjrQmJMQvGbhjcrQmJMQvGbhjrQmJMQv">> = iolist_to_binary(re:replace("cccc","([^ab]*?)*","Gbhj&rQmJMQv",[global])),
- <<"qlNFbaba">> = iolist_to_binary(re:replace("baba","([^ab]*?)*","qlNF",[])),
- <<"qlNFbqlNFaqlNFbqlNFaqlNF">> = iolist_to_binary(re:replace("baba","([^ab]*?)*","qlNF",[global])),
- <<"KQaNecIrOxNy">> = iolist_to_binary(re:replace("a","(?>a*)*","KQ\\1&NecIrOxNy",[])),
- <<"KQaNecIrOxNyKQNecIrOxNy">> = iolist_to_binary(re:replace("a","(?>a*)*","KQ\\1&NecIrOxNy",[global])),
- <<"VSaaaJEKwmaaaUrFoAmveCbcde">> = iolist_to_binary(re:replace("aaabcde","(?>a*)*","VS&JEKwm&UrFoAmv\\1eC",[])),
- <<"VSaaaJEKwmaaaUrFoAmveCVSJEKwmUrFoAmveCbVSJEKwmUrFoAmveCcVSJEKwmUrFoAmveCdVSJEKwmUrFoAmveCeVSJEKwmUrFoAmveC">> = iolist_to_binary(re:replace("aaabcde","(?>a*)*","VS&JEKwm&UrFoAmv\\1eC",[global])),
- <<"UCWWaaaaaSi">> = iolist_to_binary(re:replace("aaaaa","((?>a*))*","UCW\\1W&Si",[])),
- <<"UCWWaaaaaSiUCWWSi">> = iolist_to_binary(re:replace("aaaaa","((?>a*))*","UCW\\1W&Si",[global])),
- <<"Ynbbaa">> = iolist_to_binary(re:replace("aabbaa","((?>a*))*","Yn",[])),
- <<"YnYnbYnbYnYn">> = iolist_to_binary(re:replace("aabbaa","((?>a*))*","Yn",[global])),
+ <<"j(xp(abcd)mKu(HHgUS(abcd)IE(abcd)">> = iolist_to_binary(re:replace("(abcd)","( \\( )? [^()]+ (?(1) \\) |) ","j\\1xp&mKu\\1HHgUS&IE&",[extended])),
+ <<"j(xp(abcd)mKu(HHgUS(abcd)IE(abcd)">> = iolist_to_binary(re:replace("(abcd)","( \\( )? [^()]+ (?(1) \\) |) ","j\\1xp&mKu\\1HHgUS&IE&",[extended,
+ global])),
+ <<"yiIibTMatthe quick Rkn(abcd) fox">> = iolist_to_binary(re:replace("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) |) ","yi\\1IibTMat&Rkn",[extended])),
+ <<"yiIibTMatthe quick Rknyi(IibTMat(abcd)RknyiIibTMat foxRkn">> = iolist_to_binary(re:replace("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) |) ","yi\\1IibTMat&Rkn",[extended,
+ global])),
+ <<"(ruXsFSabcdLabcdbadX">> = iolist_to_binary(re:replace("(abcd","( \\( )? [^()]+ (?(1) \\) |) ","ruXsFS&L&b\\1adX",[extended])),
+ <<"(ruXsFSabcdLabcdbadX">> = iolist_to_binary(re:replace("(abcd","( \\( )? [^()]+ (?(1) \\) |) ","ruXsFS&L&b\\1adX",[extended,
+ global])),
+ <<"kCb">> = iolist_to_binary(re:replace("abcd","( \\( )? [^()]+ (?(1) \\) ) ","kCb",[extended])),
+ <<"kCb">> = iolist_to_binary(re:replace("abcd","( \\( )? [^()]+ (?(1) \\) ) ","kCb",[extended,
+ global])),
+ <<"ufsBIAN(">> = iolist_to_binary(re:replace("(abcd)","( \\( )? [^()]+ (?(1) \\) ) ","ufsBIAN\\1",[extended])),
+ <<"ufsBIAN(">> = iolist_to_binary(re:replace("(abcd)","( \\( )? [^()]+ (?(1) \\) ) ","ufsBIAN\\1",[extended,
+ global])),
+ <<"VECNLXf(abcd) fox">> = iolist_to_binary(re:replace("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) ) ","V\\1\\1ECNL\\1Xf",[extended])),
+ <<"VECNLXfV((ECNL(XfVECNLXf">> = iolist_to_binary(re:replace("the quick (abcd) fox","( \\( )? [^()]+ (?(1) \\) ) ","V\\1\\1ECNL\\1Xf",[extended,
+ global])),
+ <<"(PBNukCrgiybP">> = iolist_to_binary(re:replace("(abcd","( \\( )? [^()]+ (?(1) \\) ) ","PBNukCrgiybP",[extended])),
+ <<"(PBNukCrgiybP">> = iolist_to_binary(re:replace("(abcd","( \\( )? [^()]+ (?(1) \\) ) ","PBNukCrgiybP",[extended,
+ global])),
+ <<"eFGTe1q12hFWn12">> = iolist_to_binary(re:replace("12","^(?(2)a|(1)(2))+$","eFGTe\\1q&hFWn&",[])),
+ <<"eFGTe1q12hFWn12">> = iolist_to_binary(re:replace("12","^(?(2)a|(1)(2))+$","eFGTe\\1q&hFWn&",[global])),
+ <<"GQ">> = iolist_to_binary(re:replace("12a","^(?(2)a|(1)(2))+$","GQ",[])),
+ <<"GQ">> = iolist_to_binary(re:replace("12a","^(?(2)a|(1)(2))+$","GQ",[global])),
+ <<"t12aa">> = iolist_to_binary(re:replace("12aa","^(?(2)a|(1)(2))+$","t&",[])),
+ <<"t12aa">> = iolist_to_binary(re:replace("12aa","^(?(2)a|(1)(2))+$","t&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(2)a|(1)(2))+$","PaHcMWBmFjXXO",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?(2)a|(1)(2))+$","PaHcMWBmFjXXO",[global])),
+ <<"1234">> = iolist_to_binary(re:replace("1234","^(?(2)a|(1)(2))+$","R\\1u",[])),
+ <<"1234">> = iolist_to_binary(re:replace("1234","^(?(2)a|(1)(2))+$","R\\1u",[global])),
+ <<"geopblahblah blah">> = iolist_to_binary(re:replace("blah blah","((?i)blah)\\s+\\1","geop\\1&",[])),
+ <<"geopblahblah blah">> = iolist_to_binary(re:replace("blah blah","((?i)blah)\\s+\\1","geop\\1&",[global])),
+ <<"JTHjDKqA">> = iolist_to_binary(re:replace("BLAH BLAH","((?i)blah)\\s+\\1","JTHjDKqA",[])),
+ <<"JTHjDKqA">> = iolist_to_binary(re:replace("BLAH BLAH","((?i)blah)\\s+\\1","JTHjDKqA",[global])),
+ <<"Blah BlahGvSBlahBlah BlahBlahtBhBlahBlah">> = iolist_to_binary(re:replace("Blah Blah","((?i)blah)\\s+\\1","&GvS\\1&\\1tBh\\1\\1",[])),
+ <<"Blah BlahGvSBlahBlah BlahBlahtBhBlahBlah">> = iolist_to_binary(re:replace("Blah Blah","((?i)blah)\\s+\\1","&GvS\\1&\\1tBh\\1\\1",[global])),
+ <<"iCveQdblaHWblaH blaH">> = iolist_to_binary(re:replace("blaH blaH","((?i)blah)\\s+\\1","iCveQd\\1W&",[])),
+ <<"iCveQdblaHWblaH blaH">> = iolist_to_binary(re:replace("blaH blaH","((?i)blah)\\s+\\1","iCveQd\\1W&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?i)blah)\\s+\\1","thGaLpke&&mlDI",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?i)blah)\\s+\\1","thGaLpke&&mlDI",[global])),
+ <<"blah BLAH">> = iolist_to_binary(re:replace("blah BLAH","((?i)blah)\\s+\\1","eIP\\1xN",[])),
+ <<"blah BLAH">> = iolist_to_binary(re:replace("blah BLAH","((?i)blah)\\s+\\1","eIP\\1xN",[global])),
+ <<"Blah blah">> = iolist_to_binary(re:replace("Blah blah","((?i)blah)\\s+\\1","KKqbLs",[])),
+ <<"Blah blah">> = iolist_to_binary(re:replace("Blah blah","((?i)blah)\\s+\\1","KKqbLs",[global])),
+ <<"blaH blah">> = iolist_to_binary(re:replace("blaH blah","((?i)blah)\\s+\\1","&jYN&OlnrIjJAVLKO",[])),
+ <<"blaH blah">> = iolist_to_binary(re:replace("blaH blah","((?i)blah)\\s+\\1","&jYN&OlnrIjJAVLKO",[global])),
+ <<"PYINshqOHfblah blahblah blahawstrlblahblah blah">> = iolist_to_binary(re:replace("blah blah","((?i)blah)\\s+(?i:\\1)","PYINshqOHf&&awstrl\\1&",[])),
+ <<"PYINshqOHfblah blahblah blahawstrlblahblah blah">> = iolist_to_binary(re:replace("blah blah","((?i)blah)\\s+(?i:\\1)","PYINshqOHf&&awstrl\\1&",[global])),
+ <<"HqueiI">> = iolist_to_binary(re:replace("BLAH BLAH","((?i)blah)\\s+(?i:\\1)","HqueiI",[])),
+ <<"HqueiI">> = iolist_to_binary(re:replace("BLAH BLAH","((?i)blah)\\s+(?i:\\1)","HqueiI",[global])),
+ <<"MRJcrKPNBlahhmh">> = iolist_to_binary(re:replace("Blah Blah","((?i)blah)\\s+(?i:\\1)","MRJcrKPN\\1hmh",[])),
+ <<"MRJcrKPNBlahhmh">> = iolist_to_binary(re:replace("Blah Blah","((?i)blah)\\s+(?i:\\1)","MRJcrKPN\\1hmh",[global])),
+ <<"blaH">> = iolist_to_binary(re:replace("blaH blaH","((?i)blah)\\s+(?i:\\1)","\\1",[])),
+ <<"blaH">> = iolist_to_binary(re:replace("blaH blaH","((?i)blah)\\s+(?i:\\1)","\\1",[global])),
+ <<"KVSblah BLAHlXp">> = iolist_to_binary(re:replace("blah BLAH","((?i)blah)\\s+(?i:\\1)","KVS&lXp",[])),
+ <<"KVSblah BLAHlXp">> = iolist_to_binary(re:replace("blah BLAH","((?i)blah)\\s+(?i:\\1)","KVS&lXp",[global])),
+ <<"grKSEVpBlah blah">> = iolist_to_binary(re:replace("Blah blah","((?i)blah)\\s+(?i:\\1)","grKSEVp&",[])),
+ <<"grKSEVpBlah blah">> = iolist_to_binary(re:replace("Blah blah","((?i)blah)\\s+(?i:\\1)","grKSEVp&",[global])),
+ <<"dblaHqblaHqQpRmENblaH blahKbSKWblaH blahx">> = iolist_to_binary(re:replace("blaH blah","((?i)blah)\\s+(?i:\\1)","d\\1q\\1qQpRmEN&KbSKW&x",[])),
+ <<"dblaHqblaHqQpRmENblaH blahKbSKWblaH blahx">> = iolist_to_binary(re:replace("blaH blah","((?i)blah)\\s+(?i:\\1)","d\\1q\\1qQpRmEN&KbSKW&x",[global])),
+ <<"WCdJaih">> = iolist_to_binary(re:replace("a","(?>a*)*","WCdJ&ih",[])),
+ <<"WCdJaihWCdJih">> = iolist_to_binary(re:replace("a","(?>a*)*","WCdJ&ih",[global])),
+ <<"YjUDqaafbyqfUOv">> = iolist_to_binary(re:replace("aa","(?>a*)*","Yj\\1UDq&fbyqfUOv",[])),
+ <<"YjUDqaafbyqfUOvYjUDqfbyqfUOv">> = iolist_to_binary(re:replace("aa","(?>a*)*","Yj\\1UDq&fbyqfUOv",[global])),
+ <<"DuaOoTKn">> = iolist_to_binary(re:replace("aaaa","(?>a*)*","DuaOoTKn\\1",[])),
+ <<"DuaOoTKnDuaOoTKn">> = iolist_to_binary(re:replace("aaaa","(?>a*)*","DuaOoTKn\\1",[global])),
+ <<"lUAkQQE">> = iolist_to_binary(re:replace("abc","(abc|)+","lUAkQQE",[])),
+ <<"lUAkQQElUAkQQE">> = iolist_to_binary(re:replace("abc","(abc|)+","lUAkQQE",[global])),
+ <<"e">> = iolist_to_binary(re:replace("abcabc","(abc|)+","e",[])),
+ <<"ee">> = iolist_to_binary(re:replace("abcabc","(abc|)+","e",[global])),
+ <<"LOeabcabcabcRabcabcabcxkWabcabcabcFSngiabcabcabcdabcabcabcDm">> = iolist_to_binary(re:replace("abcabcabc","(abc|)+","LOe&R&xkW&FSngi&d&Dm",[])),
+ <<"LOeabcabcabcRabcabcabcxkWabcabcabcFSngiabcabcabcdabcabcabcDmLOeRxkWFSngidDm">> = iolist_to_binary(re:replace("abcabcabc","(abc|)+","LOe&R&xkW&FSngi&d&Dm",[global])),
+ <<"IFSvaLmRAwsxyz">> = iolist_to_binary(re:replace("xyz","(abc|)+","IFSvaLmRAws",[])),
+ <<"IFSvaLmRAwsxIFSvaLmRAwsyIFSvaLmRAwszIFSvaLmRAws">> = iolist_to_binary(re:replace("xyz","(abc|)+","IFSvaLmRAws",[global])),
+ <<"DQUraaUYwApYRiYSqa">> = iolist_to_binary(re:replace("a","([a]*)*","DQUr\\1&&\\1UYwApYRiYSq&",[])),
+ <<"DQUraaUYwApYRiYSqaDQUrUYwApYRiYSq">> = iolist_to_binary(re:replace("a","([a]*)*","DQUr\\1&&\\1UYwApYRiYSq&",[global])),
+ <<"pfGYlaaaaadNpJmOaQHl">> = iolist_to_binary(re:replace("aaaaa","([a]*)*","pfGYl&dNpJm\\1OaQHl",[])),
+ <<"pfGYlaaaaadNpJmOaQHlpfGYldNpJmOaQHl">> = iolist_to_binary(re:replace("aaaaa","([a]*)*","pfGYl&dNpJm\\1OaQHl",[global])),
+ <<"IHNVcUg">> = iolist_to_binary(re:replace("a","([ab]*)*","\\1IHNVcUg",[])),
+ <<"IHNVcUgIHNVcUg">> = iolist_to_binary(re:replace("a","([ab]*)*","\\1IHNVcUg",[global])),
+ <<"N">> = iolist_to_binary(re:replace("b","([ab]*)*","N",[])),
+ <<"NN">> = iolist_to_binary(re:replace("b","([ab]*)*","N",[global])),
+ <<"dxkmabababdmRGQJb">> = iolist_to_binary(re:replace("ababab","([ab]*)*","dxkm&dmRGQJb",[])),
+ <<"dxkmabababdmRGQJbdxkmdmRGQJb">> = iolist_to_binary(re:replace("ababab","([ab]*)*","dxkm&dmRGQJb",[global])),
+ <<"urCYmaaaabYvaaaabFcde">> = iolist_to_binary(re:replace("aaaabcde","([ab]*)*","urCY\\1m&Yv&F",[])),
+ <<"urCYmaaaabYvaaaabFurCYmYvFcurCYmYvFdurCYmYvFeurCYmYvF">> = iolist_to_binary(re:replace("aaaabcde","([ab]*)*","urCY\\1m&Yv&F",[global])),
+ <<"W">> = iolist_to_binary(re:replace("bbbb","([ab]*)*","W\\1",[])),
+ <<"WW">> = iolist_to_binary(re:replace("bbbb","([ab]*)*","W\\1",[global])),
+ <<"LocbFbvgb">> = iolist_to_binary(re:replace("b","([^a]*)*","Loc&F&vg&",[])),
+ <<"LocbFbvgbLocFvg">> = iolist_to_binary(re:replace("b","([^a]*)*","Loc&F&vg&",[global])),
+ <<"tWIlHMJfBx">> = iolist_to_binary(re:replace("bbbb","([^a]*)*","tWIlHMJ\\1\\1fBx\\1",[])),
+ <<"tWIlHMJfBxtWIlHMJfBx">> = iolist_to_binary(re:replace("bbbb","([^a]*)*","tWIlHMJ\\1\\1fBx\\1",[global])),
+ <<"IoytBGaaa">> = iolist_to_binary(re:replace("aaa","([^a]*)*","Io\\1ytBG&",[])),
+ <<"IoytBGaIoytBGaIoytBGaIoytBG">> = iolist_to_binary(re:replace("aaa","([^a]*)*","Io\\1ytBG&",[global])),
+ <<"EPDyK">> = iolist_to_binary(re:replace("cccc","([^ab]*)*","EPDyK",[])),
+ <<"EPDyKEPDyK">> = iolist_to_binary(re:replace("cccc","([^ab]*)*","EPDyK",[global])),
+ <<"ovFfXExcDncDabab">> = iolist_to_binary(re:replace("abab","([^ab]*)*","ovFfXE\\1&x\\1cDncD",[])),
+ <<"ovFfXExcDncDaovFfXExcDncDbovFfXExcDncDaovFfXExcDncDbovFfXExcDncD">> = iolist_to_binary(re:replace("abab","([^ab]*)*","ovFfXE\\1&x\\1cDncD",[global])),
+ <<"DJadEBdkEMaRtCWFGEa">> = iolist_to_binary(re:replace("a","([a]*?)*","DJadEBdkEMa&RtCWFGE",[])),
+ <<"DJadEBdkEMaRtCWFGEDJadEBdkEMaaRtCWFGEDJadEBdkEMaRtCWFGE">> = iolist_to_binary(re:replace("a","([a]*?)*","DJadEBdkEMa&RtCWFGE",[global])),
+ <<"Tdgoaaaa">> = iolist_to_binary(re:replace("aaaa","([a]*?)*","T\\1dgo",[])),
+ <<"TdgoTdgoTdgoTdgoTdgoTdgoTdgoTdgoTdgo">> = iolist_to_binary(re:replace("aaaa","([a]*?)*","T\\1dgo",[global])),
+ <<"rvda">> = iolist_to_binary(re:replace("a","([ab]*?)*","&&rvd",[])),
+ <<"rvdaarvdrvd">> = iolist_to_binary(re:replace("a","([ab]*?)*","&&rvd",[global])),
+ <<"JEKgTqgvKb">> = iolist_to_binary(re:replace("b","([ab]*?)*","JEKgT\\1q&gvK",[])),
+ <<"JEKgTqgvKJEKgTqbgvKJEKgTqgvK">> = iolist_to_binary(re:replace("b","([ab]*?)*","JEKgT\\1q&gvK",[global])),
+ <<"UPWVyabab">> = iolist_to_binary(re:replace("abab","([ab]*?)*","UP\\1WVy",[])),
+ <<"UPWVyUPWVyUPWVyUPWVyUPWVyUPWVyUPWVyUPWVyUPWVy">> = iolist_to_binary(re:replace("abab","([ab]*?)*","UP\\1WVy",[global])),
+ <<"AbOomfYRdLAuDFGbaba">> = iolist_to_binary(re:replace("baba","([ab]*?)*","\\1AbO&omfYRdL\\1Au&DFG\\1",[])),
+ <<"AbOomfYRdLAuDFGAbObomfYRdLAubDFGAbOomfYRdLAuDFGAbOaomfYRdLAuaDFGAbOomfYRdLAuDFGAbObomfYRdLAubDFGAbOomfYRdLAuDFGAbOaomfYRdLAuaDFGAbOomfYRdLAuDFG">> = iolist_to_binary(re:replace("baba","([ab]*?)*","\\1AbO&omfYRdL\\1Au&DFG\\1",[global])),
+ <<"vpmFxwVLtNDmRVb">> = iolist_to_binary(re:replace("b","([^a]*?)*","v\\1pmFxwVLtNDmRV",[])),
+ <<"vpmFxwVLtNDmRVvpmFxwVLtNDmRVvpmFxwVLtNDmRV">> = iolist_to_binary(re:replace("b","([^a]*?)*","v\\1pmFxwVLtNDmRV",[global])),
+ <<"yVlokOKtokQKSbbbb">> = iolist_to_binary(re:replace("bbbb","([^a]*?)*","yVlokOK\\1\\1tok\\1\\1Q&KS&",[])),
+ <<"yVlokOKtokQKSyVlokOKtokQbKSbyVlokOKtokQKSyVlokOKtokQbKSbyVlokOKtokQKSyVlokOKtokQbKSbyVlokOKtokQKSyVlokOKtokQbKSbyVlokOKtokQKS">> = iolist_to_binary(re:replace("bbbb","([^a]*?)*","yVlokOK\\1\\1tok\\1\\1Q&KS&",[global])),
+ <<"eMcDykUaaa">> = iolist_to_binary(re:replace("aaa","([^a]*?)*","e\\1&McDykU\\1&",[])),
+ <<"eMcDykUaeMcDykUaeMcDykUaeMcDykU">> = iolist_to_binary(re:replace("aaa","([^a]*?)*","e\\1&McDykU\\1&",[global])),
+ <<"QEARocc">> = iolist_to_binary(re:replace("c","([^ab]*?)*","QEARo&c",[])),
+ <<"QEARocQEARoccQEARoc">> = iolist_to_binary(re:replace("c","([^ab]*?)*","QEARo&c",[global])),
+ <<"KFGQOVcccc">> = iolist_to_binary(re:replace("cccc","([^ab]*?)*","KFG&QO\\1V",[])),
+ <<"KFGQOVKFGcQOVKFGQOVKFGcQOVKFGQOVKFGcQOVKFGQOVKFGcQOVKFGQOV">> = iolist_to_binary(re:replace("cccc","([^ab]*?)*","KFG&QO\\1V",[global])),
+ <<"bhTlpTdfebaba">> = iolist_to_binary(re:replace("baba","([^ab]*?)*","bhTlp\\1Tdfe\\1",[])),
+ <<"bhTlpTdfebbhTlpTdfeabhTlpTdfebbhTlpTdfeabhTlpTdfe">> = iolist_to_binary(re:replace("baba","([^ab]*?)*","bhTlp\\1Tdfe\\1",[global])),
+ <<"PJllegKeFhjiLa">> = iolist_to_binary(re:replace("a","(?>a*)*","PJllegKeFh\\1j\\1iL&",[])),
+ <<"PJllegKeFhjiLaPJllegKeFhjiL">> = iolist_to_binary(re:replace("a","(?>a*)*","PJllegKeFh\\1j\\1iL&",[global])),
+ <<"gUuqhRhIObcde">> = iolist_to_binary(re:replace("aaabcde","(?>a*)*","\\1g\\1U\\1\\1uqhRh\\1IO",[])),
+ <<"gUuqhRhIOgUuqhRhIObgUuqhRhIOcgUuqhRhIOdgUuqhRhIOegUuqhRhIO">> = iolist_to_binary(re:replace("aaabcde","(?>a*)*","\\1g\\1U\\1\\1uqhRh\\1IO",[global])),
ok.
run14() ->
- <<"MLgsOWdfTvaaaaa">> = iolist_to_binary(re:replace("aaaaa","((?>a*?))*","MLgs&OW\\1df&T&v",[])),
- <<"MLgsOWdfTvaMLgsOWdfTvaMLgsOWdfTvaMLgsOWdfTvaMLgsOWdfTvaMLgsOWdfTv">> = iolist_to_binary(re:replace("aaaaa","((?>a*?))*","MLgs&OW\\1df&T&v",[global])),
- <<"aabbaa">> = iolist_to_binary(re:replace("aabbaa","((?>a*?))*","&",[])),
- <<"aabbaa">> = iolist_to_binary(re:replace("aabbaa","((?>a*?))*","&",[global])),
- <<"gTBVcFPFf12-sep-98nd">> = iolist_to_binary(re:replace("12-sep-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","gTBVcFPFf&\\1nd",[extended])),
- <<"gTBVcFPFf12-sep-98nd">> = iolist_to_binary(re:replace("12-sep-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","gTBVcFPFf&\\1nd",[extended,
- global])),
- <<"12-09-98h12-09-98Vrh12-09-98">> = iolist_to_binary(re:replace("12-09-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","&h&\\1Vrh\\1&",[extended])),
- <<"12-09-98h12-09-98Vrh12-09-98">> = iolist_to_binary(re:replace("12-09-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","&h&\\1Vrh\\1&",[extended,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","W&ve&i&",[extended])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","W&ve&i&",[extended,
- global])),
- <<"sep-12-98">> = iolist_to_binary(re:replace("sep-12-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","UrC",[extended])),
- <<"sep-12-98">> = iolist_to_binary(re:replace("sep-12-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","UrC",[extended,
- global])),
- <<"foodfooCEjVBAfoo">> = iolist_to_binary(re:replace("foobarfoo","(?<=(foo))bar\\1","d\\1CEjVBA\\1",[])),
- <<"foodfooCEjVBAfoo">> = iolist_to_binary(re:replace("foobarfoo","(?<=(foo))bar\\1","d\\1CEjVBA\\1",[global])),
- <<"foovctling">> = iolist_to_binary(re:replace("foobarfootling","(?<=(foo))bar\\1","vc",[])),
- <<"foovctling">> = iolist_to_binary(re:replace("foobarfootling","(?<=(foo))bar\\1","vc",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(foo))bar\\1","UXvqXj\\1yXDrW\\1&UV&aD",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(foo))bar\\1","UXvqXj\\1yXDrW\\1&UV&aD",[global])),
- <<"foobar">> = iolist_to_binary(re:replace("foobar","(?<=(foo))bar\\1","VWpBPnVuwGDg",[])),
- <<"foobar">> = iolist_to_binary(re:replace("foobar","(?<=(foo))bar\\1","VWpBPnVuwGDg",[global])),
- <<"barfoo">> = iolist_to_binary(re:replace("barfoo","(?<=(foo))bar\\1","&jX",[])),
- <<"barfoo">> = iolist_to_binary(re:replace("barfoo","(?<=(foo))bar\\1","&jX",[global])),
- <<"sQWfkfUNJnPcyC">> = iolist_to_binary(re:replace("saturday","(?i:saturday|sunday)","sQ\\1Wf\\1kfUNJnPcyC",[])),
- <<"sQWfkfUNJnPcyC">> = iolist_to_binary(re:replace("saturday","(?i:saturday|sunday)","sQ\\1Wf\\1kfUNJnPcyC",[global])),
- <<"xWJnRsundayofsundayP">> = iolist_to_binary(re:replace("sunday","(?i:saturday|sunday)","xWJn\\1R&of\\1&P",[])),
- <<"xWJnRsundayofsundayP">> = iolist_to_binary(re:replace("sunday","(?i:saturday|sunday)","xWJn\\1R&of\\1&P",[global])),
- <<"SaturdayWo">> = iolist_to_binary(re:replace("Saturday","(?i:saturday|sunday)","&W\\1o",[])),
- <<"SaturdayWo">> = iolist_to_binary(re:replace("Saturday","(?i:saturday|sunday)","&W\\1o",[global])),
- <<"TdQtxuqoDxI">> = iolist_to_binary(re:replace("Sunday","(?i:saturday|sunday)","TdQtxuqoDxI",[])),
- <<"TdQtxuqoDxI">> = iolist_to_binary(re:replace("Sunday","(?i:saturday|sunday)","TdQtxuqoDxI",[global])),
- <<"tSATURDAYpA">> = iolist_to_binary(re:replace("SATURDAY","(?i:saturday|sunday)","t&\\1pA",[])),
- <<"tSATURDAYpA">> = iolist_to_binary(re:replace("SATURDAY","(?i:saturday|sunday)","t&\\1pA",[global])),
- <<"PSUNDAYVdHPKeqeCHsbPht">> = iolist_to_binary(re:replace("SUNDAY","(?i:saturday|sunday)","P&VdHPKeqeCH\\1sbPht",[])),
- <<"PSUNDAYVdHPKeqeCHsbPht">> = iolist_to_binary(re:replace("SUNDAY","(?i:saturday|sunday)","P&VdHPKeqeCH\\1sbPht",[global])),
- <<"ADh">> = iolist_to_binary(re:replace("SunDay","(?i:saturday|sunday)","A\\1D\\1h\\1",[])),
- <<"ADh">> = iolist_to_binary(re:replace("SunDay","(?i:saturday|sunday)","A\\1D\\1h\\1",[global])),
- <<"mGKtRabcxPabcxJ">> = iolist_to_binary(re:replace("abcx","(a(?i)bc|BB)x","mGKtR&P&J",[])),
- <<"mGKtRabcxPabcxJ">> = iolist_to_binary(re:replace("abcx","(a(?i)bc|BB)x","mGKtR&P&J",[global])),
- <<"oaBCxMk">> = iolist_to_binary(re:replace("aBCx","(a(?i)bc|BB)x","o&Mk",[])),
- <<"oaBCxMk">> = iolist_to_binary(re:replace("aBCx","(a(?i)bc|BB)x","o&Mk",[global])),
- <<"BbbxAbbbbw">> = iolist_to_binary(re:replace("bbx","(a(?i)bc|BB)x","B&A\\1\\1w",[])),
- <<"BbbxAbbbbw">> = iolist_to_binary(re:replace("bbx","(a(?i)bc|BB)x","B&A\\1\\1w",[global])),
- <<"mJcBBAxatfogiBBBBOBBxw">> = iolist_to_binary(re:replace("BBx","(a(?i)bc|BB)x","mJc\\1Axatfogi\\1\\1O&w",[])),
- <<"mJcBBAxatfogiBBBBOBBxw">> = iolist_to_binary(re:replace("BBx","(a(?i)bc|BB)x","mJc\\1Axatfogi\\1\\1O&w",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a(?i)bc|BB)x","snLiVTr\\1v&GcLOx",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a(?i)bc|BB)x","snLiVTr\\1v&GcLOx",[global])),
- <<"abcX">> = iolist_to_binary(re:replace("abcX","(a(?i)bc|BB)x","cUgeDoMeUddk\\1X&",[])),
- <<"abcX">> = iolist_to_binary(re:replace("abcX","(a(?i)bc|BB)x","cUgeDoMeUddk\\1X&",[global])),
- <<"aBCX">> = iolist_to_binary(re:replace("aBCX","(a(?i)bc|BB)x","x\\1a&yaxHWdGs&udxU",[])),
- <<"aBCX">> = iolist_to_binary(re:replace("aBCX","(a(?i)bc|BB)x","x\\1a&yaxHWdGs&udxU",[global])),
- <<"bbX">> = iolist_to_binary(re:replace("bbX","(a(?i)bc|BB)x","AmUQ&rURn&&",[])),
- <<"bbX">> = iolist_to_binary(re:replace("bbX","(a(?i)bc|BB)x","AmUQ&rURn&&",[global])),
- <<"BBX">> = iolist_to_binary(re:replace("BBX","(a(?i)bc|BB)x","&\\1bNvEcoUrediWbu&Pbp",[])),
- <<"BBX">> = iolist_to_binary(re:replace("BBX","(a(?i)bc|BB)x","&\\1bNvEcoUrediWbu&Pbp",[global])),
- <<"UvDhoExRiacBIgOkt">> = iolist_to_binary(re:replace("ac","^([ab](?i)[cd]|[ef])","UvDhoExRi&BIgOkt",[])),
- <<"UvDhoExRiacBIgOkt">> = iolist_to_binary(re:replace("ac","^([ab](?i)[cd]|[ef])","UvDhoExRi&BIgOkt",[global])),
- <<"xPaCaCRDAtETUaCMGcb">> = iolist_to_binary(re:replace("aC","^([ab](?i)[cd]|[ef])","xP&\\1RDAtETU\\1MGcb",[])),
- <<"xPaCaCRDAtETUaCMGcb">> = iolist_to_binary(re:replace("aC","^([ab](?i)[cd]|[ef])","xP&\\1RDAtETU\\1MGcb",[global])),
- <<"YrbDPg">> = iolist_to_binary(re:replace("bD","^([ab](?i)[cd]|[ef])","Yr&Pg",[])),
- <<"YrbDPg">> = iolist_to_binary(re:replace("bD","^([ab](?i)[cd]|[ef])","Yr&Pg",[global])),
- <<"vxPeqqmHlephant">> = iolist_to_binary(re:replace("elephant","^([ab](?i)[cd]|[ef])","vxP&qqmH",[])),
- <<"vxPeqqmHlephant">> = iolist_to_binary(re:replace("elephant","^([ab](?i)[cd]|[ef])","vxP&qqmH",[global])),
- <<"CXttEDburope">> = iolist_to_binary(re:replace("Europe","^([ab](?i)[cd]|[ef])","CXtt\\1Db",[])),
- <<"CXttEDburope">> = iolist_to_binary(re:replace("Europe","^([ab](?i)[cd]|[ef])","CXtt\\1Db",[global])),
- <<"ckdAsOrog">> = iolist_to_binary(re:replace("frog","^([ab](?i)[cd]|[ef])","ckdAsO",[])),
- <<"ckdAsOrog">> = iolist_to_binary(re:replace("frog","^([ab](?i)[cd]|[ef])","ckdAsO",[global])),
- <<"FLAarance">> = iolist_to_binary(re:replace("France","^([ab](?i)[cd]|[ef])","\\1LAa",[])),
- <<"FLAarance">> = iolist_to_binary(re:replace("France","^([ab](?i)[cd]|[ef])","\\1LAa",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^([ab](?i)[cd]|[ef])","&dK",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^([ab](?i)[cd]|[ef])","&dK",[global])),
- <<"Africa">> = iolist_to_binary(re:replace("Africa","^([ab](?i)[cd]|[ef])","he&mN&m",[])),
- <<"Africa">> = iolist_to_binary(re:replace("Africa","^([ab](?i)[cd]|[ef])","he&mN&m",[global])),
- <<"QwnababababWRxgc">> = iolist_to_binary(re:replace("ab","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","Qwn&\\1\\1&WRxgc",[])),
- <<"QwnababababWRxgc">> = iolist_to_binary(re:replace("ab","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","Qwn&\\1\\1&WRxgc",[global])),
- <<"alixQPHvMhCA">> = iolist_to_binary(re:replace("aBd","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","alixQPHvMhCA",[])),
- <<"alixQPHvMhCA">> = iolist_to_binary(re:replace("aBd","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","alixQPHvMhCA",[global])),
- <<"fRTxgJVEjxyBxyliXrOuh">> = iolist_to_binary(re:replace("xy","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","fRTxgJVEj\\1B\\1liXrOuh",[])),
- <<"fRTxgJVEjxyBxyliXrOuh">> = iolist_to_binary(re:replace("xy","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","fRTxgJVEj\\1B\\1liXrOuh",[global])),
- <<"xYRFpytKCFxYlEt">> = iolist_to_binary(re:replace("xY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","&RFpytKCF&lEt",[])),
- <<"xYRFpytKCFxYlEt">> = iolist_to_binary(re:replace("xY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","&RFpytKCF&lEt",[global])),
- <<"vgzjebra">> = iolist_to_binary(re:replace("zebra","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","vg&j",[])),
- <<"vgzjebra">> = iolist_to_binary(re:replace("zebra","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","vg&j",[global])),
- <<"eZFmjyambesi">> = iolist_to_binary(re:replace("Zambesi","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","e&Fmjy",[])),
- <<"eZFmjyambesi">> = iolist_to_binary(re:replace("Zambesi","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","e&Fmjy",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","a",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","a",[global])),
- <<"aCD">> = iolist_to_binary(re:replace("aCD","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","gEOo",[])),
- <<"aCD">> = iolist_to_binary(re:replace("aCD","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","gEOo",[global])),
- <<"XY">> = iolist_to_binary(re:replace("XY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","&OrTvY&r\\1a\\1tNgO\\1",[])),
- <<"XY">> = iolist_to_binary(re:replace("XY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","&OrTvY&r\\1a\\1tNgO\\1",[global])),
+ <<"QVEsbJSBcadjBEjT">> = iolist_to_binary(re:replace("aaaaa","((?>a*))*","QVEsbJSBcadjB\\1EjT\\1",[])),
+ <<"QVEsbJSBcadjBEjTQVEsbJSBcadjBEjT">> = iolist_to_binary(re:replace("aaaaa","((?>a*))*","QVEsbJSBcadjB\\1EjT\\1",[global])),
+ <<"aajWaaDjOsitnxUkGdbbaa">> = iolist_to_binary(re:replace("aabbaa","((?>a*))*","&j\\1W&DjOsitnxUkGd",[])),
+ <<"aajWaaDjOsitnxUkGdjWDjOsitnxUkGdbjWDjOsitnxUkGdbaajWaaDjOsitnxUkGdjWDjOsitnxUkGd">> = iolist_to_binary(re:replace("aabbaa","((?>a*))*","&j\\1W&DjOsitnxUkGd",[global])),
+ <<"mpYoteiaaaaa">> = iolist_to_binary(re:replace("aaaaa","((?>a*?))*","&mpYotei",[])),
+ <<"mpYoteiampYoteiampYoteiampYoteiampYoteiampYotei">> = iolist_to_binary(re:replace("aaaaa","((?>a*?))*","&mpYotei",[global])),
+ <<"xwNaabbaa">> = iolist_to_binary(re:replace("aabbaa","((?>a*?))*","xwN",[])),
+ <<"xwNaxwNaxwNbxwNbxwNaxwNaxwN">> = iolist_to_binary(re:replace("aabbaa","((?>a*?))*","xwN",[global])),
+ <<"MHqWb12-sep-98tn12-sep-98">> = iolist_to_binary(re:replace("12-sep-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","MHqWb\\1&\\1\\1tn&",[extended])),
+ <<"MHqWb12-sep-98tn12-sep-98">> = iolist_to_binary(re:replace("12-sep-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","MHqWb\\1&\\1\\1tn&",[extended,
+ global])),
+ <<"DgNMNfEyu">> = iolist_to_binary(re:replace("12-09-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","DgNM\\1NfEyu",[extended])),
+ <<"DgNMNfEyu">> = iolist_to_binary(re:replace("12-09-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","DgNM\\1NfEyu",[extended,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","dJbs&PvrBmxnM",[extended])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","dJbs&PvrBmxnM",[extended,
+ global])),
+ <<"sep-12-98">> = iolist_to_binary(re:replace("sep-12-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","WdMj&nqA\\1",[extended])),
+ <<"sep-12-98">> = iolist_to_binary(re:replace("sep-12-98","(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ","WdMj&nqA\\1",[extended,
+ global])),
+ <<"fooKBbarfooDAfoofbarfooMfooDQfqvJdYVQ">> = iolist_to_binary(re:replace("foobarfoo","(?<=(foo))bar\\1","KB&DA\\1f&M\\1DQfqvJdYVQ",[])),
+ <<"fooKBbarfooDAfoofbarfooMfooDQfqvJdYVQ">> = iolist_to_binary(re:replace("foobarfoo","(?<=(foo))bar\\1","KB&DA\\1f&M\\1DQfqvJdYVQ",[global])),
+ <<"foofKNfoofooQlDdcmBPbarfooCfooUbarfoofootling">> = iolist_to_binary(re:replace("foobarfootling","(?<=(foo))bar\\1","fKN\\1\\1QlDdcmBP&C\\1U&\\1",[])),
+ <<"foofKNfoofooQlDdcmBPbarfooCfooUbarfoofootling">> = iolist_to_binary(re:replace("foobarfootling","(?<=(foo))bar\\1","fKN\\1\\1QlDdcmBP&C\\1U&\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(foo))bar\\1","aN&pf\\1\\1\\1mf\\1frWLf&d&m",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(foo))bar\\1","aN&pf\\1\\1\\1mf\\1frWLf&d&m",[global])),
+ <<"foobar">> = iolist_to_binary(re:replace("foobar","(?<=(foo))bar\\1","NQ&IvkhD&RYe\\1\\1\\1",[])),
+ <<"foobar">> = iolist_to_binary(re:replace("foobar","(?<=(foo))bar\\1","NQ&IvkhD&RYe\\1\\1\\1",[global])),
+ <<"barfoo">> = iolist_to_binary(re:replace("barfoo","(?<=(foo))bar\\1","RV\\1lCqK\\1k",[])),
+ <<"barfoo">> = iolist_to_binary(re:replace("barfoo","(?<=(foo))bar\\1","RV\\1lCqK\\1k",[global])),
+ <<"WXSaOsXBjgsaturdayx">> = iolist_to_binary(re:replace("saturday","(?i:saturday|sunday)","W\\1X\\1S\\1aOsXBj\\1g&x",[])),
+ <<"WXSaOsXBjgsaturdayx">> = iolist_to_binary(re:replace("saturday","(?i:saturday|sunday)","W\\1X\\1S\\1aOsXBj\\1g&x",[global])),
+ <<"LogM">> = iolist_to_binary(re:replace("sunday","(?i:saturday|sunday)","Lo\\1gM",[])),
+ <<"LogM">> = iolist_to_binary(re:replace("sunday","(?i:saturday|sunday)","Lo\\1gM",[global])),
+ <<"bAkcTSaturdayamcSaturdayx">> = iolist_to_binary(re:replace("Saturday","(?i:saturday|sunday)","bAk\\1cT&amc&x",[])),
+ <<"bAkcTSaturdayamcSaturdayx">> = iolist_to_binary(re:replace("Saturday","(?i:saturday|sunday)","bAk\\1cT&amc&x",[global])),
+ <<"WJeSunday">> = iolist_to_binary(re:replace("Sunday","(?i:saturday|sunday)","WJe&",[])),
+ <<"WJeSunday">> = iolist_to_binary(re:replace("Sunday","(?i:saturday|sunday)","WJe&",[global])),
+ <<"HPSATURDAYOIKerWiY">> = iolist_to_binary(re:replace("SATURDAY","(?i:saturday|sunday)","HP&OIKerWi\\1Y",[])),
+ <<"HPSATURDAYOIKerWiY">> = iolist_to_binary(re:replace("SATURDAY","(?i:saturday|sunday)","HP&OIKerWi\\1Y",[global])),
+ <<"OgUOq">> = iolist_to_binary(re:replace("SUNDAY","(?i:saturday|sunday)","\\1OgUOq",[])),
+ <<"OgUOq">> = iolist_to_binary(re:replace("SUNDAY","(?i:saturday|sunday)","\\1OgUOq",[global])),
+ <<"UKulSunDaykpSunDayv">> = iolist_to_binary(re:replace("SunDay","(?i:saturday|sunday)","UKul&kp&v",[])),
+ <<"UKulSunDaykpSunDayv">> = iolist_to_binary(re:replace("SunDay","(?i:saturday|sunday)","UKul&kp&v",[global])),
+ <<"uKOqaabcexabcxpabcsJydJMabchE">> = iolist_to_binary(re:replace("abcx","(a(?i)bc|BB)x","uKOqa\\1ex&p\\1sJydJM\\1hE",[])),
+ <<"uKOqaabcexabcxpabcsJydJMabchE">> = iolist_to_binary(re:replace("abcx","(a(?i)bc|BB)x","uKOqa\\1ex&p\\1sJydJM\\1hE",[global])),
+ <<"rRNaBC">> = iolist_to_binary(re:replace("aBCx","(a(?i)bc|BB)x","rRN\\1",[])),
+ <<"rRNaBC">> = iolist_to_binary(re:replace("aBCx","(a(?i)bc|BB)x","rRN\\1",[global])),
+ <<"oJ">> = iolist_to_binary(re:replace("bbx","(a(?i)bc|BB)x","oJ",[])),
+ <<"oJ">> = iolist_to_binary(re:replace("bbx","(a(?i)bc|BB)x","oJ",[global])),
+ <<"BBxR">> = iolist_to_binary(re:replace("BBx","(a(?i)bc|BB)x","&R",[])),
+ <<"BBxR">> = iolist_to_binary(re:replace("BBx","(a(?i)bc|BB)x","&R",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a(?i)bc|BB)x","T&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(a(?i)bc|BB)x","T&",[global])),
+ <<"abcX">> = iolist_to_binary(re:replace("abcX","(a(?i)bc|BB)x","whvhAvFn",[])),
+ <<"abcX">> = iolist_to_binary(re:replace("abcX","(a(?i)bc|BB)x","whvhAvFn",[global])),
+ <<"aBCX">> = iolist_to_binary(re:replace("aBCX","(a(?i)bc|BB)x","Nb&vemA",[])),
+ <<"aBCX">> = iolist_to_binary(re:replace("aBCX","(a(?i)bc|BB)x","Nb&vemA",[global])),
+ <<"bbX">> = iolist_to_binary(re:replace("bbX","(a(?i)bc|BB)x","s\\1GdP\\1\\1dEQ\\1YO",[])),
+ <<"bbX">> = iolist_to_binary(re:replace("bbX","(a(?i)bc|BB)x","s\\1GdP\\1\\1dEQ\\1YO",[global])),
+ <<"BBX">> = iolist_to_binary(re:replace("BBX","(a(?i)bc|BB)x","oFBOVOb",[])),
+ <<"BBX">> = iolist_to_binary(re:replace("BBX","(a(?i)bc|BB)x","oFBOVOb",[global])),
+ <<"tacacotHFLuTEAHCbR">> = iolist_to_binary(re:replace("ac","^([ab](?i)[cd]|[ef])","t&\\1otHFLuTEAHCbR",[])),
+ <<"tacacotHFLuTEAHCbR">> = iolist_to_binary(re:replace("ac","^([ab](?i)[cd]|[ef])","t&\\1otHFLuTEAHCbR",[global])),
+ <<"BaCaCJ">> = iolist_to_binary(re:replace("aC","^([ab](?i)[cd]|[ef])","B&\\1J",[])),
+ <<"BaCaCJ">> = iolist_to_binary(re:replace("aC","^([ab](?i)[cd]|[ef])","B&\\1J",[global])),
+ <<"vbDvbDMbDnOy">> = iolist_to_binary(re:replace("bD","^([ab](?i)[cd]|[ef])","v&v\\1M&nOy",[])),
+ <<"vbDvbDMbDnOy">> = iolist_to_binary(re:replace("bD","^([ab](?i)[cd]|[ef])","v&v\\1M&nOy",[global])),
+ <<"HSegelephant">> = iolist_to_binary(re:replace("elephant","^([ab](?i)[cd]|[ef])","HS&ge",[])),
+ <<"HSegelephant">> = iolist_to_binary(re:replace("elephant","^([ab](?i)[cd]|[ef])","HS&ge",[global])),
+ <<"KmuWEkIQYqurope">> = iolist_to_binary(re:replace("Europe","^([ab](?i)[cd]|[ef])","KmuW&kIQYq",[])),
+ <<"KmuWEkIQYqurope">> = iolist_to_binary(re:replace("Europe","^([ab](?i)[cd]|[ef])","KmuW&kIQYq",[global])),
+ <<"qwwffEncmLfJNGOfOrog">> = iolist_to_binary(re:replace("frog","^([ab](?i)[cd]|[ef])","qww\\1&EncmL\\1JNGO&O",[])),
+ <<"qwwffEncmLfJNGOfOrog">> = iolist_to_binary(re:replace("frog","^([ab](?i)[cd]|[ef])","qww\\1&EncmL\\1JNGO&O",[global])),
+ <<"uVBupFMFDFFBwfMmnlfFrance">> = iolist_to_binary(re:replace("France","^([ab](?i)[cd]|[ef])","uVBup\\1M&D\\1\\1BwfMmnlf&",[])),
+ <<"uVBupFMFDFFBwfMmnlfFrance">> = iolist_to_binary(re:replace("France","^([ab](?i)[cd]|[ef])","uVBup\\1M&D\\1\\1BwfMmnlf&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^([ab](?i)[cd]|[ef])","\\1cOIQhxWWs\\1F\\1&nEAw",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^([ab](?i)[cd]|[ef])","\\1cOIQhxWWs\\1F\\1&nEAw",[global])),
+ <<"Africa">> = iolist_to_binary(re:replace("Africa","^([ab](?i)[cd]|[ef])","h",[])),
+ <<"Africa">> = iolist_to_binary(re:replace("Africa","^([ab](?i)[cd]|[ef])","h",[global])),
+ <<"rWababXF">> = iolist_to_binary(re:replace("ab","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","rW\\1&XF",[])),
+ <<"rWababXF">> = iolist_to_binary(re:replace("ab","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","rW\\1&XF",[global])),
+ <<"wlBBHaBdG">> = iolist_to_binary(re:replace("aBd","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","wlBBH&G",[])),
+ <<"wlBBHaBdG">> = iolist_to_binary(re:replace("aBd","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","wlBBH&G",[global])),
+ <<"vxyxyyCoOgxy">> = iolist_to_binary(re:replace("xy","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","v\\1\\1yCoOg&",[])),
+ <<"vxyxyyCoOgxy">> = iolist_to_binary(re:replace("xy","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","v\\1\\1yCoOg&",[global])),
+ <<"sEBLg">> = iolist_to_binary(re:replace("xY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","sEBLg",[])),
+ <<"sEBLg">> = iolist_to_binary(re:replace("xY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","sEBLg",[global])),
+ <<"CxGBTmzFzaoxSvnzIJzxebra">> = iolist_to_binary(re:replace("zebra","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","CxGBTm&F&aoxSvn&IJ&x",[])),
+ <<"CxGBTmzFzaoxSvnzIJzxebra">> = iolist_to_binary(re:replace("zebra","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","CxGBTm&F&aoxSvn&IJ&x",[global])),
+ <<"tcaZQambesi">> = iolist_to_binary(re:replace("Zambesi","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","tca\\1Q",[])),
+ <<"tcaZQambesi">> = iolist_to_binary(re:replace("Zambesi","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","tca\\1Q",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","tSnco&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","tSnco&",[global])),
+ <<"aCD">> = iolist_to_binary(re:replace("aCD","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","dfo",[])),
+ <<"aCD">> = iolist_to_binary(re:replace("aCD","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","dfo",[global])),
+ <<"XY">> = iolist_to_binary(re:replace("XY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","U",[])),
+ <<"XY">> = iolist_to_binary(re:replace("XY","^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)","U",[global])),
<<"foo
-sutSyiAVbardY">> = iolist_to_binary(re:replace("foo
-bar","(?<=foo\\n)^bar","sutSyiAV&dY",[multiline])),
+NRWmeVkGqvP">> = iolist_to_binary(re:replace("foo
+bar","(?<=foo\\n)^bar","NRWmeVkGqv\\1P",[multiline])),
<<"foo
-sutSyiAVbardY">> = iolist_to_binary(re:replace("foo
-bar","(?<=foo\\n)^bar","sutSyiAV&dY",[multiline,global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=foo\\n)^bar","SbD\\1F&CKeqGUc\\1&",[multiline])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=foo\\n)^bar","SbD\\1F&CKeqGUc\\1&",[multiline,
- global])),
- <<"bar">> = iolist_to_binary(re:replace("bar","(?<=foo\\n)^bar","yi&DP",[multiline])),
- <<"bar">> = iolist_to_binary(re:replace("bar","(?<=foo\\n)^bar","yi&DP",[multiline,
- global])),
+NRWmeVkGqvP">> = iolist_to_binary(re:replace("foo
+bar","(?<=foo\\n)^bar","NRWmeVkGqv\\1P",[multiline,global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=foo\\n)^bar","pcR&ta\\1wJMdM&KPN",[multiline])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=foo\\n)^bar","pcR&ta\\1wJMdM&KPN",[multiline,
+ global])),
+ <<"bar">> = iolist_to_binary(re:replace("bar","(?<=foo\\n)^bar","jByCJtDS\\1o&THKBAM&y",[multiline])),
+ <<"bar">> = iolist_to_binary(re:replace("bar","(?<=foo\\n)^bar","jByCJtDS\\1o&THKBAM&y",[multiline,
+ global])),
<<"baz
bar">> = iolist_to_binary(re:replace("baz
-bar","(?<=foo\\n)^bar","hGG",[multiline])),
+bar","(?<=foo\\n)^bar","qsa\\1EcHRVFjLsoO&fk",[multiline])),
<<"baz
bar">> = iolist_to_binary(re:replace("baz
-bar","(?<=foo\\n)^bar","hGG",[multiline,global])),
- <<"barTsM">> = iolist_to_binary(re:replace("barbaz","(?<=(?<!foo)bar)baz","TsM",[])),
- <<"barTsM">> = iolist_to_binary(re:replace("barbaz","(?<=(?<!foo)bar)baz","TsM",[global])),
- <<"barbarbazJYNeeiOkukbazbaze">> = iolist_to_binary(re:replace("barbarbaz","(?<=(?<!foo)bar)baz","&JYNeeiOkuk&&e",[])),
- <<"barbarbazJYNeeiOkukbazbaze">> = iolist_to_binary(re:replace("barbarbaz","(?<=(?<!foo)bar)baz","&JYNeeiOkuk&&e",[global])),
- <<"koobarbazJDRvnHPtlJvlqbazha">> = iolist_to_binary(re:replace("koobarbaz","(?<=(?<!foo)bar)baz","&JD\\1RvnHPtlJvlq&ha",[])),
- <<"koobarbazJDRvnHPtlJvlqbazha">> = iolist_to_binary(re:replace("koobarbaz","(?<=(?<!foo)bar)baz","&JD\\1RvnHPtlJvlq&ha",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(?<!foo)bar)baz","se&q\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(?<!foo)bar)baz","se&q\\1",[global])),
- <<"baz">> = iolist_to_binary(re:replace("baz","(?<=(?<!foo)bar)baz","\\1FnT\\1ncG\\1qiLitBVlR",[])),
- <<"baz">> = iolist_to_binary(re:replace("baz","(?<=(?<!foo)bar)baz","\\1FnT\\1ncG\\1qiLitBVlR",[global])),
- <<"foobarbaz">> = iolist_to_binary(re:replace("foobarbaz","(?<=(?<!foo)bar)baz","TGjyDWNaukC\\1D",[])),
- <<"foobarbaz">> = iolist_to_binary(re:replace("foobarbaz","(?<=(?<!foo)bar)baz","TGjyDWNaukC\\1D",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","^(a\\1?){4}$","PqtMwjvc&wXddSH",[])),
- <<"a">> = iolist_to_binary(re:replace("a","^(a\\1?){4}$","PqtMwjvc&wXddSH",[global])),
- <<"aa">> = iolist_to_binary(re:replace("aa","^(a\\1?){4}$","GgSSdPHMYJhXx",[])),
- <<"aa">> = iolist_to_binary(re:replace("aa","^(a\\1?){4}$","GgSSdPHMYJhXx",[global])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a\\1?){4}$","ucLn&Fx&kXfW",[])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a\\1?){4}$","ucLn&Fx&kXfW",[global])),
- <<"naaaaaaQNEaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaa","^(a\\1?){4}$","n&\\1QNE&&&",[])),
- <<"naaaaaaQNEaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaa","^(a\\1?){4}$","n&\\1QNE&&&",[global])),
- <<"ielIaAaXNwripBgIaHTa">> = iolist_to_binary(re:replace("aaaaaaa","^(a\\1?){4}$","ielI\\1A\\1XNwripBgI\\1HT\\1",[])),
- <<"ielIaAaXNwripBgIaHTa">> = iolist_to_binary(re:replace("aaaaaaa","^(a\\1?){4}$","ielI\\1A\\1XNwripBgI\\1HT\\1",[global])),
- <<"aaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaa","^(a\\1?){4}$","HRYVEqqIFqY&Dl",[])),
- <<"aaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaa","^(a\\1?){4}$","HRYVEqqIFqY&Dl",[global])),
- <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?){4}$","&&t\\1s",[])),
- <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?){4}$","&&t\\1s",[global])),
- <<"NaaaadLeaaaaxAL">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?){4}$","N\\1dLe\\1xAL",[])),
- <<"NaaaadLeaaaaxAL">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?){4}$","N\\1dLe\\1xAL",[global])),
- <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?){4}$","\\1jr",[])),
- <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?){4}$","\\1jr",[global])),
- <<"aaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaa","^(a\\1?){4}$","N\\1",[])),
- <<"aaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaa","^(a\\1?){4}$","N\\1",[global])),
- <<"aaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaa","^(a\\1?){4}$","sQ&xSjdecK&&rSQkA",[])),
- <<"aaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaa","^(a\\1?){4}$","sQ&xSjdecK&&rSQkA",[global])),
- <<"aaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaa","^(a\\1?){4}$","CsOa",[])),
- <<"aaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaa","^(a\\1?){4}$","CsOa",[global])),
- <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaa","^(a\\1?){4}$","&pAEvtoqYnBxGT&Uox",[])),
- <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaa","^(a\\1?){4}$","&pAEvtoqYnBxGT&Uox",[global])),
- <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaa","^(a\\1?){4}$","&icuBLN",[])),
- <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaa","^(a\\1?){4}$","&icuBLN",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","wxtPJAs&D\\1V&xlkaXy&",[])),
- <<"a">> = iolist_to_binary(re:replace("a","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","wxtPJAs&D\\1V&xlkaXy&",[global])),
- <<"aa">> = iolist_to_binary(re:replace("aa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","GO\\1&NlEm",[])),
- <<"aa">> = iolist_to_binary(re:replace("aa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","GO\\1&NlEm",[global])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","trMv\\1vGRRdT&L",[])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","trMv\\1vGRRdT&L",[global])),
- <<"dtEvrhKayRa">> = iolist_to_binary(re:replace("aaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","dtEvrhK\\1yR\\1",[])),
- <<"dtEvrhKayRa">> = iolist_to_binary(re:replace("aaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","dtEvrhK\\1yR\\1",[global])),
- <<"swnY">> = iolist_to_binary(re:replace("aaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","swnY",[])),
- <<"swnY">> = iolist_to_binary(re:replace("aaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","swnY",[global])),
- <<"aaaaaarinTIDxAHEMa">> = iolist_to_binary(re:replace("aaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","&rinTIDxAHEM\\1",[])),
- <<"aaaaaarinTIDxAHEMa">> = iolist_to_binary(re:replace("aaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","&rinTIDxAHEM\\1",[global])),
- <<"UBvaoaaaaaaaaDUiX">> = iolist_to_binary(re:replace("aaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","UBvao\\1&DUiX",[])),
- <<"UBvaoaaaaaaaaDUiX">> = iolist_to_binary(re:replace("aaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","UBvao\\1&DUiX",[global])),
- <<"aaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","H\\1aLBBEpEaB",[])),
- <<"aaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","H\\1aLBBEpEaB",[global])),
- <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","dpC",[])),
- <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","dpC",[global])),
- <<"taaaaaaaaaahaaaaaaaaaaf">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","t&h&f",[])),
- <<"taaaaaaaaaahaaaaaaaaaaf">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","t&h&f",[global])),
- <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","rgxaXLiOHjVaKNJyPJ",[])),
- <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","rgxaXLiOHjVaKNJyPJ",[global])),
- <<"aaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","a\\1UVnCvM\\1bOy",[])),
- <<"aaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","a\\1UVnCvM\\1bOy",[global])),
- <<"aaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","mnxwE",[])),
- <<"aaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","mnxwE",[global])),
- <<"aaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","R",[])),
- <<"aaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","R",[global])),
- <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","CKEn&",[])),
- <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","CKEn&",[global])),
- <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","dr\\1B\\1G&W\\1\\1\\1",[])),
- <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","dr\\1B\\1G&W\\1\\1\\1",[global])),
- <<"mTTwWHMeBAnTMAy">> = iolist_to_binary(re:replace("abc","abc","mTTwWHMe\\1B\\1AnTMAy",[])),
- <<"mTTwWHMeBAnTMAy">> = iolist_to_binary(re:replace("abc","abc","mTTwWHMe\\1B\\1AnTMAy",[global])),
- <<"xFRFntrFXSabcyBabcRky">> = iolist_to_binary(re:replace("xabcy","abc","FRFntrFXS&yB&\\1Rk",[])),
- <<"xFRFntrFXSabcyBabcRky">> = iolist_to_binary(re:replace("xabcy","abc","FRFntrFXS&yB&\\1Rk",[global])),
- <<"abmabceyJl">> = iolist_to_binary(re:replace("ababc","abc","m&eyJl",[])),
- <<"abmabceyJl">> = iolist_to_binary(re:replace("ababc","abc","m&eyJl",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","\\1kN",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","\\1kN",[global])),
- <<"xbc">> = iolist_to_binary(re:replace("xbc","abc","Rd",[])),
- <<"xbc">> = iolist_to_binary(re:replace("xbc","abc","Rd",[global])),
- <<"axc">> = iolist_to_binary(re:replace("axc","abc","qQP\\1gBdX&cfJfv&f",[])),
- <<"axc">> = iolist_to_binary(re:replace("axc","abc","qQP\\1gBdX&cfJfv&f",[global])),
- <<"abx">> = iolist_to_binary(re:replace("abx","abc","VMtbG",[])),
- <<"abx">> = iolist_to_binary(re:replace("abx","abc","VMtbG",[global])),
- <<"jNyOabclmQAUUabcabcabcM">> = iolist_to_binary(re:replace("abc","ab*c","jNyO&lmQA\\1UU&&&M",[])),
- <<"jNyOabclmQAUUabcabcabcM">> = iolist_to_binary(re:replace("abc","ab*c","jNyO&lmQA\\1UU&&&M",[global])),
- <<"NuNKaVVP">> = iolist_to_binary(re:replace("abc","ab*bc","NuNKaVV\\1\\1P",[])),
- <<"NuNKaVVP">> = iolist_to_binary(re:replace("abc","ab*bc","NuNKaVV\\1\\1P",[global])),
- <<"v">> = iolist_to_binary(re:replace("abbc","ab*bc","v",[])),
- <<"v">> = iolist_to_binary(re:replace("abbc","ab*bc","v",[global])),
- <<"IabbbbcLNYRgEvYHyabbbbctwq">> = iolist_to_binary(re:replace("abbbbc","ab*bc","I&LNYRgEvYHy&tw\\1q",[])),
- <<"IabbbbcLNYRgEvYHyabbbbctwq">> = iolist_to_binary(re:replace("abbbbc","ab*bc","I&LNYRgEvYHy&tw\\1q",[global])),
- <<"dcWrPQwrWtCeinonDembbbbc">> = iolist_to_binary(re:replace("abbbbc",".{1}","dcWrPQwrWtCeinonDem",[])),
- <<"dcWrPQwrWtCeinonDemdcWrPQwrWtCeinonDemdcWrPQwrWtCeinonDemdcWrPQwrWtCeinonDemdcWrPQwrWtCeinonDemdcWrPQwrWtCeinonDem">> = iolist_to_binary(re:replace("abbbbc",".{1}","dcWrPQwrWtCeinonDem",[global])),
- <<"NwOwabbbabbbCOvabbbenaNbc">> = iolist_to_binary(re:replace("abbbbc",".{3,4}","NwOw&&COv&e\\1naN",[])),
- <<"NwOwabbbabbbCOvabbbenaNbc">> = iolist_to_binary(re:replace("abbbbc",".{3,4}","NwOw&&COv&e\\1naN",[global])),
- <<"abbbbcCeTetSKDvAvrabbbbcpa">> = iolist_to_binary(re:replace("abbbbc","ab{0,}bc","&CeTetSKDvAvr&pa",[])),
- <<"abbbbcCeTetSKDvAvrabbbbcpa">> = iolist_to_binary(re:replace("abbbbc","ab{0,}bc","&CeTetSKDvAvr&pa",[global])),
- <<"TbtqfbcUrEcTU">> = iolist_to_binary(re:replace("abbc","ab+bc","Tb\\1tqfb\\1cUrEcTU",[])),
- <<"TbtqfbcUrEcTU">> = iolist_to_binary(re:replace("abbc","ab+bc","Tb\\1tqfb\\1cUrEcTU",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab+bc","TeS\\1\\1F",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab+bc","TeS\\1\\1F",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","ab+bc","EHEtuOC&GTMRx",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","ab+bc","EHEtuOC&GTMRx",[global])),
- <<"abq">> = iolist_to_binary(re:replace("abq","ab+bc","\\1ywtK\\1hfkEVdoXy\\1eH",[])),
- <<"abq">> = iolist_to_binary(re:replace("abq","ab+bc","\\1ywtK\\1hfkEVdoXy\\1eH",[global])),
- <<"GlETcsroCIlRt">> = iolist_to_binary(re:replace("abbbbc","ab+bc","GlETcsro\\1CIlRt\\1",[])),
- <<"GlETcsroCIlRt">> = iolist_to_binary(re:replace("abbbbc","ab+bc","GlETcsro\\1CIlRt\\1",[global])),
+bar","(?<=foo\\n)^bar","qsa\\1EcHRVFjLsoO&fk",[multiline,global])),
+ <<"barrVqQArLvUbazrlnI">> = iolist_to_binary(re:replace("barbaz","(?<=(?<!foo)bar)baz","r\\1\\1VqQArLvU&r\\1lnI",[])),
+ <<"barrVqQArLvUbazrlnI">> = iolist_to_binary(re:replace("barbaz","(?<=(?<!foo)bar)baz","r\\1\\1VqQArLvU&r\\1lnI",[global])),
+ <<"barbargh">> = iolist_to_binary(re:replace("barbarbaz","(?<=(?<!foo)bar)baz","gh",[])),
+ <<"barbargh">> = iolist_to_binary(re:replace("barbarbaz","(?<=(?<!foo)bar)baz","gh",[global])),
+ <<"koobarvdKYQDIVnwbazbazQWKBgh">> = iolist_to_binary(re:replace("koobarbaz","(?<=(?<!foo)bar)baz","vdKYQDIVnw&&QWKBgh",[])),
+ <<"koobarvdKYQDIVnwbazbazQWKBgh">> = iolist_to_binary(re:replace("koobarbaz","(?<=(?<!foo)bar)baz","vdKYQDIVnw&&QWKBgh",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(?<!foo)bar)baz","FjVsA\\1&B",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(?<!foo)bar)baz","FjVsA\\1&B",[global])),
+ <<"baz">> = iolist_to_binary(re:replace("baz","(?<=(?<!foo)bar)baz","HgWqxfrr\\1qYwT",[])),
+ <<"baz">> = iolist_to_binary(re:replace("baz","(?<=(?<!foo)bar)baz","HgWqxfrr\\1qYwT",[global])),
+ <<"foobarbaz">> = iolist_to_binary(re:replace("foobarbaz","(?<=(?<!foo)bar)baz","yjWsT\\1DYmUlc",[])),
+ <<"foobarbaz">> = iolist_to_binary(re:replace("foobarbaz","(?<=(?<!foo)bar)baz","yjWsT\\1DYmUlc",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","^(a\\1?){4}$","xfcMrdAu",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","^(a\\1?){4}$","xfcMrdAu",[global])),
+ <<"aa">> = iolist_to_binary(re:replace("aa","^(a\\1?){4}$","\\1BliC&LQrU\\1r",[])),
+ <<"aa">> = iolist_to_binary(re:replace("aa","^(a\\1?){4}$","\\1BliC&LQrU\\1r",[global])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a\\1?){4}$","TeTeD\\1X&&l\\1w",[])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a\\1?){4}$","TeTeD\\1X&&l\\1w",[global])),
+ <<"HV">> = iolist_to_binary(re:replace("aaaaa","^(a\\1?){4}$","HV",[])),
+ <<"HV">> = iolist_to_binary(re:replace("aaaaa","^(a\\1?){4}$","HV",[global])),
+ <<"GmaaaaaaaawlpUaaaaaaaOy">> = iolist_to_binary(re:replace("aaaaaaa","^(a\\1?){4}$","Gm\\1&wlpU&Oy",[])),
+ <<"GmaaaaaaaawlpUaaaaaaaOy">> = iolist_to_binary(re:replace("aaaaaaa","^(a\\1?){4}$","Gm\\1&wlpU&Oy",[global])),
+ <<"aaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaa","^(a\\1?){4}$","snNvqcf\\1mxQ\\1DRPIP",[])),
+ <<"aaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaa","^(a\\1?){4}$","snNvqcf\\1mxQ\\1DRPIP",[global])),
+ <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?){4}$","\\1RtbPoOkgRgQnokJdP",[])),
+ <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?){4}$","\\1RtbPoOkgRgQnokJdP",[global])),
+ <<"aaaaaaaaaaaaaagBhaaaaaaaaaaIaaaaaaaaaaKaaaaaaaaaaeSvaaaanYhNTc">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?){4}$","&\\1gBh&I&K&eSv\\1nYhNTc",[])),
+ <<"aaaaaaaaaaaaaagBhaaaaaaaaaaIaaaaaaaaaaKaaaaaaaaaaeSvaaaanYhNTc">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?){4}$","&\\1gBh&I&K&eSv\\1nYhNTc",[global])),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?){4}$","\\1O",[])),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?){4}$","\\1O",[global])),
+ <<"aaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaa","^(a\\1?){4}$","\\1&&",[])),
+ <<"aaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaa","^(a\\1?){4}$","\\1&&",[global])),
+ <<"aaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaa","^(a\\1?){4}$","gbGDh\\1\\1\\1PlvFnq",[])),
+ <<"aaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaa","^(a\\1?){4}$","gbGDh\\1\\1\\1PlvFnq",[global])),
+ <<"aaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaa","^(a\\1?){4}$","o\\1\\1\\1nIbiYVy&",[])),
+ <<"aaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaa","^(a\\1?){4}$","o\\1\\1\\1nIbiYVy&",[global])),
+ <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaa","^(a\\1?){4}$","K\\1IGHABBJDNX",[])),
+ <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaa","^(a\\1?){4}$","K\\1IGHABBJDNX",[global])),
+ <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaa","^(a\\1?){4}$","\\1&\\1wvNlo",[])),
+ <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaa","^(a\\1?){4}$","\\1&\\1wvNlo",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","MMsqXp\\1L\\1",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","MMsqXp\\1L\\1",[global])),
+ <<"aa">> = iolist_to_binary(re:replace("aa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","&\\1\\1cblGbrY\\1\\1sIosd",[])),
+ <<"aa">> = iolist_to_binary(re:replace("aa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","&\\1\\1cblGbrY\\1\\1sIosd",[global])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","WyI\\1\\1fd&A\\1",[])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","WyI\\1\\1fd&A\\1",[global])),
+ <<"hJaaaaKOGfPaaaanTbA">> = iolist_to_binary(re:replace("aaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","hJ&KOGfP&nTbA",[])),
+ <<"hJaaaaKOGfPaaaanTbA">> = iolist_to_binary(re:replace("aaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","hJ&KOGfP&nTbA",[global])),
+ <<"akBaaaaaaJapLD">> = iolist_to_binary(re:replace("aaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","\\1kB&aJ\\1pLD",[])),
+ <<"akBaaaaaaJapLD">> = iolist_to_binary(re:replace("aaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","\\1kB&aJ\\1pLD",[global])),
+ <<"aaadYLlnNBfn">> = iolist_to_binary(re:replace("aaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","a\\1adYLlnNBfn",[])),
+ <<"aaadYLlnNBfn">> = iolist_to_binary(re:replace("aaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","a\\1adYLlnNBfn",[global])),
+ <<"haaaaaaaMn">> = iolist_to_binary(re:replace("aaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","h&Mn",[])),
+ <<"haaaaaaaMn">> = iolist_to_binary(re:replace("aaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","h&Mn",[global])),
+ <<"aaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","F&\\1&",[])),
+ <<"aaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","F&\\1&",[global])),
+ <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","ig&\\1hVNoqXY\\1kTDTB\\1qO",[])),
+ <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","ig&\\1hVNoqXY\\1kTDTB\\1qO",[global])),
+ <<"jRaaaaaaaaaamEaTlkygaaaaaaaaaadSaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","jR&mE\\1Tlkyg&dS&",[])),
+ <<"jRaaaaaaaaaamEaTlkygaaaaaaaaaadSaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","jR&mE\\1Tlkyg&dS&",[global])),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","Tec&gBdh\\1x",[])),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","Tec&gBdh\\1x",[global])),
+ <<"aaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","MMXY&yRoehQihV&b\\1txa",[])),
+ <<"aaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","MMXY&yRoehQihV&b\\1txa",[global])),
+ <<"aaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","&",[])),
+ <<"aaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","&",[global])),
+ <<"aaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","SnhXn&km\\1BaVtSJUu",[])),
+ <<"aaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","SnhXn&km\\1BaVtSJUu",[global])),
+ <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","FToR",[])),
+ <<"aaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","FToR",[global])),
+ <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","\\1",[])),
+ <<"aaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaa","^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$","\\1",[global])),
+ <<"abcJJvjL">> = iolist_to_binary(re:replace("abc","abc","&J\\1\\1JvjL",[])),
+ <<"abcJJvjL">> = iolist_to_binary(re:replace("abc","abc","&J\\1\\1JvjL",[global])),
+ <<"xtsyy">> = iolist_to_binary(re:replace("xabcy","abc","tsy",[])),
+ <<"xtsyy">> = iolist_to_binary(re:replace("xabcy","abc","tsy",[global])),
+ <<"abr">> = iolist_to_binary(re:replace("ababc","abc","r",[])),
+ <<"abr">> = iolist_to_binary(re:replace("ababc","abc","r",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","&CvW\\1J&hP\\1kp",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","&CvW\\1J&hP\\1kp",[global])),
+ <<"xbc">> = iolist_to_binary(re:replace("xbc","abc","xONy",[])),
+ <<"xbc">> = iolist_to_binary(re:replace("xbc","abc","xONy",[global])),
+ <<"axc">> = iolist_to_binary(re:replace("axc","abc","O&RYgOFW&\\1b",[])),
+ <<"axc">> = iolist_to_binary(re:replace("axc","abc","O&RYgOFW&\\1b",[global])),
+ <<"abx">> = iolist_to_binary(re:replace("abx","abc","\\1wEEGj\\1Pu\\1E",[])),
+ <<"abx">> = iolist_to_binary(re:replace("abx","abc","\\1wEEGj\\1Pu\\1E",[global])),
+ <<"HnabcabcrHTQ">> = iolist_to_binary(re:replace("abc","ab*c","Hn&&rHTQ",[])),
+ <<"HnabcabcrHTQ">> = iolist_to_binary(re:replace("abc","ab*c","Hn&&rHTQ",[global])),
+ <<"xTpXkabc">> = iolist_to_binary(re:replace("abc","ab*bc","xTpXk&",[])),
+ <<"xTpXkabc">> = iolist_to_binary(re:replace("abc","ab*bc","xTpXk&",[global])),
+ <<"xLoabbchcabbckehh">> = iolist_to_binary(re:replace("abbc","ab*bc","xLo&hc&k\\1ehh",[])),
+ <<"xLoabbchcabbckehh">> = iolist_to_binary(re:replace("abbc","ab*bc","xLo&hc&k\\1ehh",[global])),
+ <<"Tkaj">> = iolist_to_binary(re:replace("abbbbc","ab*bc","Tkaj",[])),
+ <<"Tkaj">> = iolist_to_binary(re:replace("abbbbc","ab*bc","Tkaj",[global])),
+ <<"KJCYEgbbbbc">> = iolist_to_binary(re:replace("abbbbc",".{1}","\\1KJCYEg",[])),
+ <<"KJCYEgKJCYEgKJCYEgKJCYEgKJCYEgKJCYEg">> = iolist_to_binary(re:replace("abbbbc",".{1}","\\1KJCYEg",[global])),
+ <<"XabbbOSpFbFfabbbbc">> = iolist_to_binary(re:replace("abbbbc",".{3,4}","X&O\\1SpFbFf&",[])),
+ <<"XabbbOSpFbFfabbbbc">> = iolist_to_binary(re:replace("abbbbc",".{3,4}","X&O\\1SpFbFf&",[global])),
+ <<"FMabbbbcELDoDirqkHb">> = iolist_to_binary(re:replace("abbbbc","ab{0,}bc","FM&ELDoDirqkHb",[])),
+ <<"FMabbbbcELDoDirqkHb">> = iolist_to_binary(re:replace("abbbbc","ab{0,}bc","FM&ELDoDirqkHb",[global])),
+ <<"nVWfSGeKlL">> = iolist_to_binary(re:replace("abbc","ab+bc","n\\1VWfSGe\\1KlL",[])),
+ <<"nVWfSGeKlL">> = iolist_to_binary(re:replace("abbc","ab+bc","n\\1VWfSGe\\1KlL",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab+bc","\\1jmWD&n\\1\\1mX&mJMl\\1X",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab+bc","\\1jmWD&n\\1\\1mX&mJMl\\1X",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","ab+bc","\\1&W&Kf&\\1dU&T",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","ab+bc","\\1&W&Kf&\\1dU&T",[global])),
+ <<"abq">> = iolist_to_binary(re:replace("abq","ab+bc","l\\1yn\\1E&P\\1JeWGV",[])),
+ <<"abq">> = iolist_to_binary(re:replace("abq","ab+bc","l\\1yn\\1E&P\\1JeWGV",[global])),
ok.
run15() ->
- <<"GjnPRabbbbcabbbbcANabbbbcH">> = iolist_to_binary(re:replace("abbbbc","ab{1,}bc","Gj\\1nPR&&A\\1N&H",[])),
- <<"GjnPRabbbbcabbbbcANabbbbcH">> = iolist_to_binary(re:replace("abbbbc","ab{1,}bc","Gj\\1nPR&&A\\1N&H",[global])),
- <<"iPhrUY">> = iolist_to_binary(re:replace("abbbbc","ab{1,3}bc","i\\1Phr\\1UY\\1",[])),
- <<"iPhrUY">> = iolist_to_binary(re:replace("abbbbc","ab{1,3}bc","i\\1Phr\\1UY\\1",[global])),
- <<"oBEnPKpabbbbcAUrXVFQn">> = iolist_to_binary(re:replace("abbbbc","ab{3,4}bc","oBEnPK\\1p&AUr\\1X\\1VFQn\\1",[])),
- <<"oBEnPKpabbbbcAUrXVFQn">> = iolist_to_binary(re:replace("abbbbc","ab{3,4}bc","oBEnPK\\1p&AUr\\1X\\1VFQn\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{4,5}bc","VJPhAjJ&qt&R",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{4,5}bc","VJPhAjJ&qt&R",[global])),
- <<"abq">> = iolist_to_binary(re:replace("abq","ab{4,5}bc","\\1issDnwN",[])),
- <<"abq">> = iolist_to_binary(re:replace("abq","ab{4,5}bc","\\1issDnwN",[global])),
- <<"abbbbc">> = iolist_to_binary(re:replace("abbbbc","ab{4,5}bc","&ty&x",[])),
- <<"abbbbc">> = iolist_to_binary(re:replace("abbbbc","ab{4,5}bc","&ty&x",[global])),
- <<"UWGc">> = iolist_to_binary(re:replace("abbc","ab?bc","UWGc",[])),
- <<"UWGc">> = iolist_to_binary(re:replace("abbc","ab?bc","UWGc",[global])),
- <<"QpFXHqWog">> = iolist_to_binary(re:replace("abc","ab?bc","QpFXHqWog",[])),
- <<"QpFXHqWog">> = iolist_to_binary(re:replace("abc","ab?bc","QpFXHqWog",[global])),
- <<"lFwRabc">> = iolist_to_binary(re:replace("abc","ab{0,1}bc","lFwR&\\1",[])),
- <<"lFwRabc">> = iolist_to_binary(re:replace("abc","ab{0,1}bc","lFwR&\\1",[global])),
- <<"abcmabcJvgabcabco">> = iolist_to_binary(re:replace("abc","ab?c","&m&Jvg&&\\1\\1o",[])),
- <<"abcmabcJvgabcabco">> = iolist_to_binary(re:replace("abc","ab?c","&m&Jvg&&\\1\\1o",[global])),
- <<"jJ">> = iolist_to_binary(re:replace("abc","ab{0,1}c","jJ",[])),
- <<"jJ">> = iolist_to_binary(re:replace("abc","ab{0,1}c","jJ",[global])),
- <<"uPAtKYsKtqCBkkp">> = iolist_to_binary(re:replace("abc","^abc$","uPAtKYsKtqCBkkp\\1",[])),
- <<"uPAtKYsKtqCBkkp">> = iolist_to_binary(re:replace("abc","^abc$","uPAtKYsKtqCBkkp\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","e\\1XAs",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","e\\1XAs",[global])),
- <<"abbbbc">> = iolist_to_binary(re:replace("abbbbc","^abc$","\\1o&fsbP\\1pwbiIRIGb\\1UD",[])),
- <<"abbbbc">> = iolist_to_binary(re:replace("abbbbc","^abc$","\\1o&fsbP\\1pwbiIRIGb\\1UD",[global])),
- <<"abcc">> = iolist_to_binary(re:replace("abcc","^abc$","WJthAfXWWmv\\1IWjIe",[])),
- <<"abcc">> = iolist_to_binary(re:replace("abcc","^abc$","WJthAfXWWmv\\1IWjIe",[global])),
- <<"UTlfrQeHrOQCMnfc">> = iolist_to_binary(re:replace("abcc","^abc","UTlfr\\1QeH\\1rOQCMnf",[])),
- <<"UTlfrQeHrOQCMnfc">> = iolist_to_binary(re:replace("abcc","^abc","UTlfr\\1QeH\\1rOQCMnf",[global])),
- <<"aARabcppSYabcEIbcGwjE">> = iolist_to_binary(re:replace("aabc","abc$","\\1AR&ppSY&EIbc\\1G\\1wjE",[])),
- <<"aARabcppSYabcEIbcGwjE">> = iolist_to_binary(re:replace("aabc","abc$","\\1AR&ppSY&EIbc\\1G\\1wjE",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc$","FnSwJ&tmv",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc$","FnSwJ&tmv",[global])),
- <<"aAmIBNLxa">> = iolist_to_binary(re:replace("aabc","abc$","Am\\1IB\\1NLxa",[])),
- <<"aAmIBNLxa">> = iolist_to_binary(re:replace("aabc","abc$","Am\\1IB\\1NLxa",[global])),
- <<"aabcd">> = iolist_to_binary(re:replace("aabcd","abc$","&EuxC&eEGEWnwI",[])),
- <<"aabcd">> = iolist_to_binary(re:replace("aabcd","abc$","&EuxC&eEGEWnwI",[global])),
- <<"cOryAkFNmtoLruabc">> = iolist_to_binary(re:replace("abc","^","cO\\1r&yAkFNmto\\1Lru&",[])),
- <<"cOryAkFNmtoLruabc">> = iolist_to_binary(re:replace("abc","^","cO\\1r&yAkFNmto\\1Lru&",[global])),
- <<"abcKpXarNeriGOdu">> = iolist_to_binary(re:replace("abc","$","Kp\\1XarNeriGOdu&",[])),
- <<"abcKpXarNeriGOdu">> = iolist_to_binary(re:replace("abc","$","Kp\\1XarNeriGOdu&",[global])),
- <<"FIusabcabcceEbtWBabc">> = iolist_to_binary(re:replace("abc","a.c","FIus&&ceEb\\1tWB&",[])),
- <<"FIusabcabcceEbtWBabc">> = iolist_to_binary(re:replace("abc","a.c","FIus&&ceEb\\1tWB&",[global])),
- <<"KqevmaxcVysaxcPaxc">> = iolist_to_binary(re:replace("axc","a.c","Kqevm&Vys&\\1\\1P&",[])),
- <<"KqevmaxcVysaxcPaxc">> = iolist_to_binary(re:replace("axc","a.c","Kqevm&Vys&\\1\\1P&",[global])),
- <<"xUdGxhaJQaxyzc">> = iolist_to_binary(re:replace("axyzc","a.*c","x\\1UdGxhaJQ&",[])),
- <<"xUdGxhaJQaxyzc">> = iolist_to_binary(re:replace("axyzc","a.*c","x\\1UdGxhaJQ&",[global])),
- <<"abdHpbYpV">> = iolist_to_binary(re:replace("abd","a[bc]d","&Hp\\1bYpV",[])),
- <<"abdHpbYpV">> = iolist_to_binary(re:replace("abd","a[bc]d","&Hp\\1bYpV",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[bc]d","J&dGU\\1rioQPR\\1&S&",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[bc]d","J&dGU\\1rioQPR\\1&S&",[global])),
- <<"axyzd">> = iolist_to_binary(re:replace("axyzd","a[bc]d","LF\\1QgQx\\1kUO&\\1",[])),
- <<"axyzd">> = iolist_to_binary(re:replace("axyzd","a[bc]d","LF\\1QgQx\\1kUO&\\1",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","a[bc]d","tiUJYyxfVfeAM",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","a[bc]d","tiUJYyxfVfeAM",[global])),
- <<"lSBTQLYWjuaceCjDace">> = iolist_to_binary(re:replace("ace","a[b-d]e","lSBTQLYWju&CjD&",[])),
- <<"lSBTQLYWjuaceCjDace">> = iolist_to_binary(re:replace("ace","a[b-d]e","lSBTQLYWju&CjD&",[global])),
- <<"aWEgjXuNyAacQTNVqSl">> = iolist_to_binary(re:replace("aac","a[b-d]","WEgjXuNyA&QTNVqSl",[])),
- <<"aWEgjXuNyAacQTNVqSl">> = iolist_to_binary(re:replace("aac","a[b-d]","WEgjXuNyA&QTNVqSl",[global])),
+ <<"oOAIabbbbcabbbbcabbbbcio">> = iolist_to_binary(re:replace("abbbbc","ab+bc","oOAI&&&io",[])),
+ <<"oOAIabbbbcabbbbcabbbbcio">> = iolist_to_binary(re:replace("abbbbc","ab+bc","oOAI&&&io",[global])),
+ <<"eKDbRMig">> = iolist_to_binary(re:replace("abbbbc","ab{1,}bc","\\1eKDb\\1R\\1Mig",[])),
+ <<"eKDbRMig">> = iolist_to_binary(re:replace("abbbbc","ab{1,}bc","\\1eKDb\\1R\\1Mig",[global])),
+ <<"abbbbc">> = iolist_to_binary(re:replace("abbbbc","ab{1,3}bc","&\\1",[])),
+ <<"abbbbc">> = iolist_to_binary(re:replace("abbbbc","ab{1,3}bc","&\\1",[global])),
+ <<"lLsEYiU">> = iolist_to_binary(re:replace("abbbbc","ab{3,4}bc","lLsEYiU",[])),
+ <<"lLsEYiU">> = iolist_to_binary(re:replace("abbbbc","ab{3,4}bc","lLsEYiU",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{4,5}bc","K\\1Q\\1Sjr&\\1&e&V\\1TQy",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{4,5}bc","K\\1Q\\1Sjr&\\1&e&V\\1TQy",[global])),
+ <<"abq">> = iolist_to_binary(re:replace("abq","ab{4,5}bc","O&C",[])),
+ <<"abq">> = iolist_to_binary(re:replace("abq","ab{4,5}bc","O&C",[global])),
+ <<"abbbbc">> = iolist_to_binary(re:replace("abbbbc","ab{4,5}bc","iqc",[])),
+ <<"abbbbc">> = iolist_to_binary(re:replace("abbbbc","ab{4,5}bc","iqc",[global])),
+ <<"epUFDnxBdDXmIWF">> = iolist_to_binary(re:replace("abbc","ab?bc","epUFDnxBdDXmIW\\1F\\1",[])),
+ <<"epUFDnxBdDXmIWF">> = iolist_to_binary(re:replace("abbc","ab?bc","epUFDnxBdDXmIW\\1F\\1",[global])),
+ <<"WhqERQJGEPXkYabcqW">> = iolist_to_binary(re:replace("abc","ab?bc","Whq\\1ERQJGEPXkY&qW",[])),
+ <<"WhqERQJGEPXkYabcqW">> = iolist_to_binary(re:replace("abc","ab?bc","Whq\\1ERQJGEPXkY&qW",[global])),
+ <<"aabcLmSkjuaNwdKc">> = iolist_to_binary(re:replace("abc","ab{0,1}bc","\\1a&\\1LmSkjuaNwd\\1Kc\\1",[])),
+ <<"aabcLmSkjuaNwdKc">> = iolist_to_binary(re:replace("abc","ab{0,1}bc","\\1a&\\1LmSkjuaNwd\\1Kc\\1",[global])),
+ <<"bpSabcEqqmi">> = iolist_to_binary(re:replace("abc","ab?c","bp\\1S&Eqqmi\\1",[])),
+ <<"bpSabcEqqmi">> = iolist_to_binary(re:replace("abc","ab?c","bp\\1S&Eqqmi\\1",[global])),
+ <<"Clxabc">> = iolist_to_binary(re:replace("abc","ab{0,1}c","Clx&",[])),
+ <<"Clxabc">> = iolist_to_binary(re:replace("abc","ab{0,1}c","Clx&",[global])),
+ <<"SlhQaJwtnpw">> = iolist_to_binary(re:replace("abc","^abc$","Sl\\1h\\1Q\\1aJwtnpw",[])),
+ <<"SlhQaJwtnpw">> = iolist_to_binary(re:replace("abc","^abc$","Sl\\1h\\1Q\\1aJwtnpw",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","eiP",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","eiP",[global])),
+ <<"abbbbc">> = iolist_to_binary(re:replace("abbbbc","^abc$","g\\1Qnq\\1jC&jh\\1wFsOwY\\1",[])),
+ <<"abbbbc">> = iolist_to_binary(re:replace("abbbbc","^abc$","g\\1Qnq\\1jC&jh\\1wFsOwY\\1",[global])),
+ <<"abcc">> = iolist_to_binary(re:replace("abcc","^abc$","CjHXsgNepVYlWp",[])),
+ <<"abcc">> = iolist_to_binary(re:replace("abcc","^abc$","CjHXsgNepVYlWp",[global])),
+ <<"HETabcc">> = iolist_to_binary(re:replace("abcc","^abc","HE\\1T&",[])),
+ <<"HETabcc">> = iolist_to_binary(re:replace("abcc","^abc","HE\\1T&",[global])),
+ <<"aodabcujLupqR">> = iolist_to_binary(re:replace("aabc","abc$","od&ujLupqR",[])),
+ <<"aodabcujLupqR">> = iolist_to_binary(re:replace("aabc","abc$","od&ujLupqR",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc$","R",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc$","R",[global])),
+ <<"aFvyvrxXtabcs">> = iolist_to_binary(re:replace("aabc","abc$","Fvyvrx\\1Xt&s",[])),
+ <<"aFvyvrxXtabcs">> = iolist_to_binary(re:replace("aabc","abc$","Fvyvrx\\1Xt&s",[global])),
+ <<"aabcd">> = iolist_to_binary(re:replace("aabcd","abc$","Pj\\1wNa&XbegI&F",[])),
+ <<"aabcd">> = iolist_to_binary(re:replace("aabcd","abc$","Pj\\1wNa&XbegI&F",[global])),
+ <<"ABvCLJOpNeVHhabc">> = iolist_to_binary(re:replace("abc","^","ABvC&&LJOpNeVH\\1h",[])),
+ <<"ABvCLJOpNeVHhabc">> = iolist_to_binary(re:replace("abc","^","ABvC&&LJOpNeVH\\1h",[global])),
+ <<"abcJEFEIGYBydFwJM">> = iolist_to_binary(re:replace("abc","$","JEFEIG&&&Y\\1BydFwJM",[])),
+ <<"abcJEFEIGYBydFwJM">> = iolist_to_binary(re:replace("abc","$","JEFEIG&&&Y\\1BydFwJM",[global])),
+ <<"UEUMgabcabclGDFuMsIl">> = iolist_to_binary(re:replace("abc","a.c","UEUMg&&lGDFu\\1MsIl",[])),
+ <<"UEUMgabcabclGDFuMsIl">> = iolist_to_binary(re:replace("abc","a.c","UEUMg&&lGDFu\\1MsIl",[global])),
+ <<"LAYr">> = iolist_to_binary(re:replace("axc","a.c","LAYr",[])),
+ <<"LAYr">> = iolist_to_binary(re:replace("axc","a.c","LAYr",[global])),
+ <<"EoYP">> = iolist_to_binary(re:replace("axyzc","a.*c","EoY\\1P",[])),
+ <<"EoYP">> = iolist_to_binary(re:replace("axyzc","a.*c","EoY\\1P",[global])),
+ <<"qYbmPPabd">> = iolist_to_binary(re:replace("abd","a[bc]d","qYbmPP&",[])),
+ <<"qYbmPPabd">> = iolist_to_binary(re:replace("abd","a[bc]d","qYbmPP&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[bc]d","\\1C\\1SFfkHmrCTJ",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[bc]d","\\1C\\1SFfkHmrCTJ",[global])),
+ <<"axyzd">> = iolist_to_binary(re:replace("axyzd","a[bc]d","J&\\1J&",[])),
+ <<"axyzd">> = iolist_to_binary(re:replace("axyzd","a[bc]d","J&\\1J&",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","a[bc]d","Q&HAQK&t",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","a[bc]d","Q&HAQK&t",[global])),
+ <<"WbKKCNjyC">> = iolist_to_binary(re:replace("ace","a[b-d]e","\\1WbKKCNjyC",[])),
+ <<"WbKKCNjyC">> = iolist_to_binary(re:replace("ace","a[b-d]e","\\1WbKKCNjyC",[global])),
ok.
run16() ->
- <<"qQmna-Ga-a-rA">> = iolist_to_binary(re:replace("a-","a[-b]","q\\1Qmn&G&&rA",[])),
- <<"qQmna-Ga-a-rA">> = iolist_to_binary(re:replace("a-","a[-b]","q\\1Qmn&G&&rA",[global])),
- <<"QJ">> = iolist_to_binary(re:replace("a-","a[b-]","QJ",[])),
- <<"QJ">> = iolist_to_binary(re:replace("a-","a[b-]","QJ",[global])),
- <<"yia]ao">> = iolist_to_binary(re:replace("a]","a]","\\1yi&ao",[])),
- <<"yia]ao">> = iolist_to_binary(re:replace("a]","a]","\\1yi&ao",[global])),
- <<"FfC">> = iolist_to_binary(re:replace("a]b","a[]]b","FfC",[])),
- <<"FfC">> = iolist_to_binary(re:replace("a]b","a[]]b","FfC",[global])),
- <<"oXfcTOWQKFAlvTaedi">> = iolist_to_binary(re:replace("aed","a[^bc]d","oXfcTOWQKFAlvT\\1\\1&i",[])),
- <<"oXfcTOWQKFAlvTaedi">> = iolist_to_binary(re:replace("aed","a[^bc]d","oXfcTOWQKFAlvT\\1\\1&i",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^bc]d","&bDyTqTc",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^bc]d","&bDyTqTc",[global])),
- <<"abd">> = iolist_to_binary(re:replace("abd","a[^bc]d","FjC&R\\1",[])),
- <<"abd">> = iolist_to_binary(re:replace("abd","a[^bc]d","FjC&R\\1",[global])),
- <<"abd">> = iolist_to_binary(re:replace("abd","a[^bc]d","aENw",[])),
- <<"abd">> = iolist_to_binary(re:replace("abd","a[^bc]d","aENw",[global])),
- <<"adcdOJ">> = iolist_to_binary(re:replace("adc","a[^-b]c","&dOJ",[])),
- <<"adcdOJ">> = iolist_to_binary(re:replace("adc","a[^-b]c","&dOJ",[global])),
- <<"ANuydyM">> = iolist_to_binary(re:replace("adc","a[^]b]c","ANuydyM",[])),
- <<"ANuydyM">> = iolist_to_binary(re:replace("adc","a[^]b]c","ANuydyM",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^]b]c","SweRAVF\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^]b]c","SweRAVF\\1",[global])),
- <<"UoNrja-cLOLdIhqaTGLt">> = iolist_to_binary(re:replace("a-c","a[^]b]c","UoNrj&LOLdIhqaTGLt",[])),
- <<"UoNrja-cLOLdIhqaTGLt">> = iolist_to_binary(re:replace("a-c","a[^]b]c","UoNrj&LOLdIhqaTGLt",[global])),
- <<"a]c">> = iolist_to_binary(re:replace("a]c","a[^]b]c","w&UlR&\\1\\1Oo&I&",[])),
- <<"a]c">> = iolist_to_binary(re:replace("a]c","a[^]b]c","w&UlR&\\1\\1Oo&I&",[global])),
- <<"keSyyVigJfGa-">> = iolist_to_binary(re:replace("a-","\\ba\\b","\\1keSyy\\1VigJfG&",[])),
- <<"keSyyVigJfGa-">> = iolist_to_binary(re:replace("a-","\\ba\\b","\\1keSyy\\1VigJfG&",[global])),
- <<"-QajTaYNwiaOblsalRbJ">> = iolist_to_binary(re:replace("-a","\\ba\\b","Q&jT&YNwiaOb\\1ls&lRbJ",[])),
- <<"-QajTaYNwiaOblsalRbJ">> = iolist_to_binary(re:replace("-a","\\ba\\b","Q&jT&YNwiaOb\\1ls&lRbJ",[global])),
- <<"-jrLliKmS-">> = iolist_to_binary(re:replace("-a-","\\ba\\b","jrLliKm\\1S",[])),
- <<"-jrLliKmS-">> = iolist_to_binary(re:replace("-a-","\\ba\\b","jrLliKm\\1S",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\by\\b","tFe\\1K\\1&P&w",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\by\\b","tFe\\1K\\1&P&w",[global])),
- <<"xy">> = iolist_to_binary(re:replace("xy","\\by\\b","&&cw&p\\1BkixXR",[])),
- <<"xy">> = iolist_to_binary(re:replace("xy","\\by\\b","&&cw&p\\1BkixXR",[global])),
- <<"yz">> = iolist_to_binary(re:replace("yz","\\by\\b","Mlv\\1O",[])),
- <<"yz">> = iolist_to_binary(re:replace("yz","\\by\\b","Mlv\\1O",[global])),
- <<"xyz">> = iolist_to_binary(re:replace("xyz","\\by\\b","o&V\\1\\1&vaBPhc&YhjA\\1Hl",[])),
- <<"xyz">> = iolist_to_binary(re:replace("xyz","\\by\\b","o&V\\1\\1&vaBPhc&YhjA\\1Hl",[global])),
- <<"*** FEnnRHgdUlleafatdRwilers">> = iolist_to_binary(re:replace("*** Failers","\\Ba\\B","EnnRHgdUlle&f&tdRw",[])),
- <<"*** FEnnRHgdUlleafatdRwilers">> = iolist_to_binary(re:replace("*** Failers","\\Ba\\B","EnnRHgdUlle&f&tdRw",[global])),
- <<"a-">> = iolist_to_binary(re:replace("a-","\\Ba\\B","wXKR&jlEbdM&QBJmvK",[])),
- <<"a-">> = iolist_to_binary(re:replace("a-","\\Ba\\B","wXKR&jlEbdM&QBJmvK",[global])),
- <<"-a">> = iolist_to_binary(re:replace("-a","\\Ba\\B","f\\1dQc",[])),
- <<"-a">> = iolist_to_binary(re:replace("-a","\\Ba\\B","f\\1dQc",[global])),
- <<"-a-">> = iolist_to_binary(re:replace("-a-","\\Ba\\B","WTMu\\1drSum",[])),
- <<"-a-">> = iolist_to_binary(re:replace("-a-","\\Ba\\B","WTMu\\1drSum",[global])),
- <<"xheOtJ">> = iolist_to_binary(re:replace("xy","\\By\\b","\\1heOtJ\\1",[])),
- <<"xheOtJ">> = iolist_to_binary(re:replace("xy","\\By\\b","\\1heOtJ\\1",[global])),
- <<"xYHVuz">> = iolist_to_binary(re:replace("yz","\\by\\B","xYH\\1\\1Vu",[])),
- <<"xYHVuz">> = iolist_to_binary(re:replace("yz","\\by\\B","xYH\\1\\1Vu",[global])),
- <<"xUyfxgltgVyjPz">> = iolist_to_binary(re:replace("xyz","\\By\\B","\\1Uyf\\1xglt\\1gV\\1\\1&jP",[])),
- <<"xUyfxgltgVyjPz">> = iolist_to_binary(re:replace("xyz","\\By\\B","\\1Uyf\\1xglt\\1gV\\1\\1&jP",[global])),
- <<"PqSMLiChcHwx">> = iolist_to_binary(re:replace("a","\\w","PqSMLiChcHwx",[])),
- <<"PqSMLiChcHwx">> = iolist_to_binary(re:replace("a","\\w","PqSMLiChcHwx",[global])),
- <<"Bl">> = iolist_to_binary(re:replace("-","\\W","Bl",[])),
- <<"Bl">> = iolist_to_binary(re:replace("-","\\W","Bl",[global])),
- <<"**rPBnOGDkc** Failers">> = iolist_to_binary(re:replace("*** Failers","\\W","&&\\1rPBnOGDkc",[])),
- <<"**rPBnOGDkc**rPBnOGDkc**rPBnOGDkc rPBnOGDkcFailers">> = iolist_to_binary(re:replace("*** Failers","\\W","&&\\1rPBnOGDkc",[global])),
- <<"rI">> = iolist_to_binary(re:replace("-","\\W","rI",[])),
- <<"rI">> = iolist_to_binary(re:replace("-","\\W","rI",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","\\W","N&\\1h&mf\\1eJ&T",[])),
- <<"a">> = iolist_to_binary(re:replace("a","\\W","N&\\1h&mf\\1eJ&T",[global])),
- <<"Ia bHMFKnjmeDa bNCX">> = iolist_to_binary(re:replace("a b","a\\sb","I&HMFKnjm\\1eD&NCX",[])),
- <<"Ia bHMFKnjmeDa bNCX">> = iolist_to_binary(re:replace("a b","a\\sb","I&HMFKnjm\\1eD&NCX",[global])),
- <<"a-ba-ba-bnaNLABX">> = iolist_to_binary(re:replace("a-b","a\\Sb","&&&naN\\1LABX\\1",[])),
- <<"a-ba-ba-bnaNLABX">> = iolist_to_binary(re:replace("a-b","a\\Sb","&&&naN\\1LABX\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a\\Sb","\\1bI&cDB\\1Bpe",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a\\Sb","\\1bI&cDB\\1Bpe",[global])),
- <<"ILRpJeKfXTxFTY">> = iolist_to_binary(re:replace("a-b","a\\Sb","I\\1L\\1RpJe\\1KfXTxFTY",[])),
- <<"ILRpJeKfXTxFTY">> = iolist_to_binary(re:replace("a-b","a\\Sb","I\\1L\\1RpJe\\1KfXTxFTY",[global])),
- <<"a b">> = iolist_to_binary(re:replace("a b","a\\Sb","\\1ngH\\1OgaFGbI",[])),
- <<"a b">> = iolist_to_binary(re:replace("a b","a\\Sb","\\1ngH\\1OgaFGbI",[global])),
- <<"oOycwxv1FKdF">> = iolist_to_binary(re:replace("1","\\d","oOycwxv&FK\\1dF\\1",[])),
- <<"oOycwxv1FKdF">> = iolist_to_binary(re:replace("1","\\d","oOycwxv&FK\\1dF\\1",[global])),
- <<"YdKRXgdlJSvnIO">> = iolist_to_binary(re:replace("-","\\D","YdKRXgdl\\1JSvnIO",[])),
- <<"YdKRXgdlJSvnIO">> = iolist_to_binary(re:replace("-","\\D","YdKRXgdl\\1JSvnIO",[global])),
- <<"lxE*lk*V** Failers">> = iolist_to_binary(re:replace("*** Failers","\\D","lx\\1E&lk&V",[])),
- <<"lxE*lk*VlxE*lk*VlxE*lk*VlxE lk VlxEFlkFVlxEalkaVlxEilkiVlxEllklVlxEelkeVlxErlkrVlxEslksV">> = iolist_to_binary(re:replace("*** Failers","\\D","lx\\1E&lk&V",[global])),
- <<"JRKLvPGXEGf-a">> = iolist_to_binary(re:replace("-","\\D","JRK\\1LvPG\\1XEGf&a",[])),
- <<"JRKLvPGXEGf-a">> = iolist_to_binary(re:replace("-","\\D","JRK\\1LvPG\\1XEGf&a",[global])),
- <<"1">> = iolist_to_binary(re:replace("1","\\D","aTH&MPmaOF\\1\\1r",[])),
- <<"1">> = iolist_to_binary(re:replace("1","\\D","aTH&MPmaOF\\1\\1r",[global])),
- <<"MGKXIbaJcyWbp">> = iolist_to_binary(re:replace("a","[\\w]","MGKXIb&Jc\\1yWbp",[])),
- <<"MGKXIbaJcyWbp">> = iolist_to_binary(re:replace("a","[\\w]","MGKXIb&Jc\\1yWbp",[global])),
+ <<"aTHHUYacigdJtNac">> = iolist_to_binary(re:replace("aac","a[b-d]","THHUY&igdJt\\1N&",[])),
+ <<"aTHHUYacigdJtNac">> = iolist_to_binary(re:replace("aac","a[b-d]","THHUY&igdJt\\1N&",[global])),
+ <<"JdNla-BpgoAJobghPXXK">> = iolist_to_binary(re:replace("a-","a[-b]","JdNl&BpgoAJobghPXXK",[])),
+ <<"JdNla-BpgoAJobghPXXK">> = iolist_to_binary(re:replace("a-","a[-b]","JdNl&BpgoAJobghPXXK",[global])),
+ <<"ka-a-">> = iolist_to_binary(re:replace("a-","a[b-]","k&&\\1",[])),
+ <<"ka-a-">> = iolist_to_binary(re:replace("a-","a[b-]","k&&\\1",[global])),
+ <<"hXKn">> = iolist_to_binary(re:replace("a]","a]","hXKn",[])),
+ <<"hXKn">> = iolist_to_binary(re:replace("a]","a]","hXKn",[global])),
+ <<"Mpa]bJQ">> = iolist_to_binary(re:replace("a]b","a[]]b","\\1Mp&JQ",[])),
+ <<"Mpa]bJQ">> = iolist_to_binary(re:replace("a]b","a[]]b","\\1Mp&JQ",[global])),
+ <<"BqnaedgwNu">> = iolist_to_binary(re:replace("aed","a[^bc]d","Bqn\\1&gw\\1Nu",[])),
+ <<"BqnaedgwNu">> = iolist_to_binary(re:replace("aed","a[^bc]d","Bqn\\1&gw\\1Nu",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^bc]d","\\1BbD&v",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^bc]d","\\1BbD&v",[global])),
+ <<"abd">> = iolist_to_binary(re:replace("abd","a[^bc]d","wsTKas&SjtLxJf\\1\\1hMC",[])),
+ <<"abd">> = iolist_to_binary(re:replace("abd","a[^bc]d","wsTKas&SjtLxJf\\1\\1hMC",[global])),
+ <<"abd">> = iolist_to_binary(re:replace("abd","a[^bc]d","NeK&\\1F",[])),
+ <<"abd">> = iolist_to_binary(re:replace("abd","a[^bc]d","NeK&\\1F",[global])),
+ <<"hLeXkpLIvadcW">> = iolist_to_binary(re:replace("adc","a[^-b]c","hLeXkpLIv&W",[])),
+ <<"hLeXkpLIvadcW">> = iolist_to_binary(re:replace("adc","a[^-b]c","hLeXkpLIv&W",[global])),
+ <<"adcadc">> = iolist_to_binary(re:replace("adc","a[^]b]c","&&\\1",[])),
+ <<"adcadc">> = iolist_to_binary(re:replace("adc","a[^]b]c","&&\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^]b]c","aELhPe\\1sLAnpxtxB",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^]b]c","aELhPe\\1sLAnpxtxB",[global])),
+ <<"SKH">> = iolist_to_binary(re:replace("a-c","a[^]b]c","SKH",[])),
+ <<"SKH">> = iolist_to_binary(re:replace("a-c","a[^]b]c","SKH",[global])),
+ <<"a]c">> = iolist_to_binary(re:replace("a]c","a[^]b]c","IB",[])),
+ <<"a]c">> = iolist_to_binary(re:replace("a]c","a[^]b]c","IB",[global])),
+ <<"COboVXMd-">> = iolist_to_binary(re:replace("a-","\\ba\\b","COboVXMd",[])),
+ <<"COboVXMd-">> = iolist_to_binary(re:replace("a-","\\ba\\b","COboVXMd",[global])),
+ <<"-ydGtl">> = iolist_to_binary(re:replace("-a","\\ba\\b","\\1ydGtl",[])),
+ <<"-ydGtl">> = iolist_to_binary(re:replace("-a","\\ba\\b","\\1ydGtl",[global])),
+ <<"-awxvweaXGdlD-">> = iolist_to_binary(re:replace("-a-","\\ba\\b","&wx\\1vweaX\\1GdlD",[])),
+ <<"-awxvweaXGdlD-">> = iolist_to_binary(re:replace("-a-","\\ba\\b","&wx\\1vweaX\\1GdlD",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\by\\b","V&Yu",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\by\\b","V&Yu",[global])),
+ <<"xy">> = iolist_to_binary(re:replace("xy","\\by\\b","&uQiJpvCwJtLUQ&n&e",[])),
+ <<"xy">> = iolist_to_binary(re:replace("xy","\\by\\b","&uQiJpvCwJtLUQ&n&e",[global])),
+ <<"yz">> = iolist_to_binary(re:replace("yz","\\by\\b","JnTOLWX\\1&mW&F\\1",[])),
+ <<"yz">> = iolist_to_binary(re:replace("yz","\\by\\b","JnTOLWX\\1&mW&F\\1",[global])),
+ <<"xyz">> = iolist_to_binary(re:replace("xyz","\\by\\b","y&h\\1&u",[])),
+ <<"xyz">> = iolist_to_binary(re:replace("xyz","\\by\\b","y&h\\1&u",[global])),
+ <<"*** Fdailers">> = iolist_to_binary(re:replace("*** Failers","\\Ba\\B","d&\\1",[])),
+ <<"*** Fdailers">> = iolist_to_binary(re:replace("*** Failers","\\Ba\\B","d&\\1",[global])),
+ <<"a-">> = iolist_to_binary(re:replace("a-","\\Ba\\B","sfBOnWLWdrl",[])),
+ <<"a-">> = iolist_to_binary(re:replace("a-","\\Ba\\B","sfBOnWLWdrl",[global])),
+ <<"-a">> = iolist_to_binary(re:replace("-a","\\Ba\\B","kQ",[])),
+ <<"-a">> = iolist_to_binary(re:replace("-a","\\Ba\\B","kQ",[global])),
+ <<"-a-">> = iolist_to_binary(re:replace("-a-","\\Ba\\B","&jYf&iIQh\\1",[])),
+ <<"-a-">> = iolist_to_binary(re:replace("-a-","\\Ba\\B","&jYf&iIQh\\1",[global])),
+ <<"xyyEyso">> = iolist_to_binary(re:replace("xy","\\By\\b","y&E&so",[])),
+ <<"xyyEyso">> = iolist_to_binary(re:replace("xy","\\By\\b","y&E&so",[global])),
+ <<"yymuiNz">> = iolist_to_binary(re:replace("yz","\\by\\B","\\1&&\\1muiN",[])),
+ <<"yymuiNz">> = iolist_to_binary(re:replace("yz","\\by\\B","\\1&&\\1muiN",[global])),
+ <<"xUyz">> = iolist_to_binary(re:replace("xyz","\\By\\B","U&",[])),
+ <<"xUyz">> = iolist_to_binary(re:replace("xyz","\\By\\B","U&",[global])),
+ <<"yohceaHvakiaxgGAPsc">> = iolist_to_binary(re:replace("a","\\w","yohce&Hv&ki&xgGAPsc",[])),
+ <<"yohceaHvakiaxgGAPsc">> = iolist_to_binary(re:replace("a","\\w","yohce&Hv&ki&xgGAPsc",[global])),
+ <<"t--q">> = iolist_to_binary(re:replace("-","\\W","t&&q",[])),
+ <<"t--q">> = iolist_to_binary(re:replace("-","\\W","t&&q",[global])),
+ <<"wSEi*VKdBOyBw** Failers">> = iolist_to_binary(re:replace("*** Failers","\\W","w\\1SEi\\1&VKdBOyB\\1w",[])),
+ <<"wSEi*VKdBOyBwwSEi*VKdBOyBwwSEi*VKdBOyBwwSEi VKdBOyBwFailers">> = iolist_to_binary(re:replace("*** Failers","\\W","w\\1SEi\\1&VKdBOyB\\1w",[global])),
+ <<"nI-H">> = iolist_to_binary(re:replace("-","\\W","nI&H",[])),
+ <<"nI-H">> = iolist_to_binary(re:replace("-","\\W","nI&H",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","\\W","kxKDSoW",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","\\W","kxKDSoW",[global])),
+ <<"d">> = iolist_to_binary(re:replace("a b","a\\sb","d",[])),
+ <<"d">> = iolist_to_binary(re:replace("a b","a\\sb","d",[global])),
+ <<"IQboAe">> = iolist_to_binary(re:replace("a-b","a\\Sb","IQboAe",[])),
+ <<"IQboAe">> = iolist_to_binary(re:replace("a-b","a\\Sb","IQboAe",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a\\Sb","Ii&smqXytI\\1w\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a\\Sb","Ii&smqXytI\\1w\\1",[global])),
+ <<"fXa-bEijX">> = iolist_to_binary(re:replace("a-b","a\\Sb","fX&EijX",[])),
+ <<"fXa-bEijX">> = iolist_to_binary(re:replace("a-b","a\\Sb","fX&EijX",[global])),
+ <<"a b">> = iolist_to_binary(re:replace("a b","a\\Sb","u&WnxKsF\\1EaL\\1",[])),
+ <<"a b">> = iolist_to_binary(re:replace("a b","a\\Sb","u&WnxKsF\\1EaL\\1",[global])),
+ <<"VOo1">> = iolist_to_binary(re:replace("1","\\d","VOo&",[])),
+ <<"VOo1">> = iolist_to_binary(re:replace("1","\\d","VOo&",[global])),
+ <<"--GGkJ---qWNn">> = iolist_to_binary(re:replace("-","\\D","&&GG\\1k\\1J&&&qWNn",[])),
+ <<"--GGkJ---qWNn">> = iolist_to_binary(re:replace("-","\\D","&&GG\\1k\\1J&&&qWNn",[global])),
+ <<"QOREoyFBbWu** Failers">> = iolist_to_binary(re:replace("*** Failers","\\D","QOREo\\1y\\1FBbWu",[])),
+ <<"QOREoyFBbWuQOREoyFBbWuQOREoyFBbWuQOREoyFBbWuQOREoyFBbWuQOREoyFBbWuQOREoyFBbWuQOREoyFBbWuQOREoyFBbWuQOREoyFBbWuQOREoyFBbWu">> = iolist_to_binary(re:replace("*** Failers","\\D","QOREo\\1y\\1FBbWu",[global])),
+ <<"Pcnt-nSAvUGvRwiwct">> = iolist_to_binary(re:replace("-","\\D","\\1Pcn\\1t&nSAvUGvRwiwct",[])),
+ <<"Pcnt-nSAvUGvRwiwct">> = iolist_to_binary(re:replace("-","\\D","\\1Pcn\\1t&nSAvUGvRwiwct",[global])),
+ <<"1">> = iolist_to_binary(re:replace("1","\\D","WOH\\1UuhFQnuf&u",[])),
+ <<"1">> = iolist_to_binary(re:replace("1","\\D","WOH\\1UuhFQnuf&u",[global])),
ok.
run17() ->
- <<"YqG">> = iolist_to_binary(re:replace("-","[\\W]","YqG",[])),
- <<"YqG">> = iolist_to_binary(re:replace("-","[\\W]","YqG",[global])),
- <<"*nxdd*geTTc** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\W]","&nx\\1dd&geTTc",[])),
- <<"*nxdd*geTTc*nxdd*geTTc*nxdd*geTTc nxdd geTTcFailers">> = iolist_to_binary(re:replace("*** Failers","[\\W]","&nx\\1dd&geTTc",[global])),
- <<"iqqe">> = iolist_to_binary(re:replace("-","[\\W]","iqqe",[])),
- <<"iqqe">> = iolist_to_binary(re:replace("-","[\\W]","iqqe",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","[\\W]","wwF\\1Q",[])),
- <<"a">> = iolist_to_binary(re:replace("a","[\\W]","wwF\\1Q",[global])),
- <<"a b">> = iolist_to_binary(re:replace("a b","a[\\s]b","&",[])),
- <<"a b">> = iolist_to_binary(re:replace("a b","a[\\s]b","&",[global])),
- <<"SPqkyVa-bP">> = iolist_to_binary(re:replace("a-b","a[\\S]b","SPqkyV&P",[])),
- <<"SPqkyVa-bP">> = iolist_to_binary(re:replace("a-b","a[\\S]b","SPqkyV&P",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[\\S]b","\\1FDeRsoK&IAJD&",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[\\S]b","\\1FDeRsoK&IAJD&",[global])),
- <<"VDpMoFi">> = iolist_to_binary(re:replace("a-b","a[\\S]b","VDpMoFi",[])),
- <<"VDpMoFi">> = iolist_to_binary(re:replace("a-b","a[\\S]b","VDpMoFi",[global])),
- <<"a b">> = iolist_to_binary(re:replace("a b","a[\\S]b","r&\\1C&XvsB&",[])),
- <<"a b">> = iolist_to_binary(re:replace("a b","a[\\S]b","r&\\1C&XvsB&",[global])),
- <<"oHYpsb1fsM1IhN1n">> = iolist_to_binary(re:replace("1","[\\d]","oHY\\1psb&fsM&IhN\\1&n",[])),
- <<"oHYpsb1fsM1IhN1n">> = iolist_to_binary(re:replace("1","[\\d]","oHY\\1psb&fsM&IhN\\1&n",[global])),
- <<"-KJX">> = iolist_to_binary(re:replace("-","[\\D]","&KJX",[])),
- <<"-KJX">> = iolist_to_binary(re:replace("-","[\\D]","&KJX",[global])),
- <<"S*I*KU** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\D]","S&\\1I&KU",[])),
- <<"S*I*KUS*I*KUS*I*KUS I KUSFIFKUSaIaKUSiIiKUSlIlKUSeIeKUSrIrKUSsIsKU">> = iolist_to_binary(re:replace("*** Failers","[\\D]","S&\\1I&KU",[global])),
- <<"WSKtUY">> = iolist_to_binary(re:replace("-","[\\D]","WSKtUY",[])),
- <<"WSKtUY">> = iolist_to_binary(re:replace("-","[\\D]","WSKtUY",[global])),
- <<"1">> = iolist_to_binary(re:replace("1","[\\D]","B\\1iB",[])),
- <<"1">> = iolist_to_binary(re:replace("1","[\\D]","B\\1iB",[global])),
- <<"bkabprVc">> = iolist_to_binary(re:replace("abc","ab|cd","bk&prV",[])),
- <<"bkabprVc">> = iolist_to_binary(re:replace("abc","ab|cd","bk&prV",[global])),
- <<"oxPHxnpgpabTabDdTmMcd">> = iolist_to_binary(re:replace("abcd","ab|cd","oxPHxnpgp&T&DdTmM",[])),
- <<"oxPHxnpgpabTabDdTmMoxPHxnpgpcdTcdDdTmM">> = iolist_to_binary(re:replace("abcd","ab|cd","oxPHxnpgp&T&DdTmM",[global])),
- <<"dpfHboradY">> = iolist_to_binary(re:replace("def","()ef","pfH\\1bor\\1adY",[])),
- <<"dpfHboradY">> = iolist_to_binary(re:replace("def","()ef","pfH\\1bor\\1adY",[global])),
- <<"Uma(b">> = iolist_to_binary(re:replace("a(b","a\\(b","Um&",[])),
- <<"Uma(b">> = iolist_to_binary(re:replace("a(b","a\\(b","Um&",[global])),
- <<"YyxabuKXMauxXBpkrd">> = iolist_to_binary(re:replace("ab","a\\(*b","Yyx&uKXMauxXBpkrd",[])),
- <<"YyxabuKXMauxXBpkrd">> = iolist_to_binary(re:replace("ab","a\\(*b","Yyx&uKXMauxXBpkrd",[global])),
- <<"pDTwGyKkiLEWnnefa((b">> = iolist_to_binary(re:replace("a((b","a\\(*b","pDTwGyKkiLEWnnef&",[])),
- <<"pDTwGyKkiLEWnnefa((b">> = iolist_to_binary(re:replace("a((b","a\\(*b","pDTwGyKkiLEWnnef&",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","a\\\\b","G\\1H\\1qrOi&\\1&aUty",[])),
- <<"a">> = iolist_to_binary(re:replace("a","a\\\\b","G\\1H\\1qrOi&\\1&aUty",[global])),
- <<"eaywaaaVSCBcjnuIfRXabc">> = iolist_to_binary(re:replace("abc","((a))","e&yw&\\1&VSCBcjnuIfRX\\1",[])),
- <<"eaywaaaVSCBcjnuIfRXabc">> = iolist_to_binary(re:replace("abc","((a))","e&yw&\\1&VSCBcjnuIfRX\\1",[global])),
- <<"IbabcEabc">> = iolist_to_binary(re:replace("abc","(a)b(c)","Ib&E&",[])),
- <<"IbabcEabc">> = iolist_to_binary(re:replace("abc","(a)b(c)","Ib&E&",[global])),
- <<"aabbgflabcrIsYKabcUvEj">> = iolist_to_binary(re:replace("aabbabc","a+b+c","gf\\1\\1l&rIsYK&UvEj",[])),
- <<"aabbgflabcrIsYKabcUvEj">> = iolist_to_binary(re:replace("aabbabc","a+b+c","gf\\1\\1l&rIsYK&UvEj",[global])),
- <<"aabbUMebt">> = iolist_to_binary(re:replace("aabbabc","a{1,}b{1,}c","UMeb\\1t",[])),
- <<"aabbUMebt">> = iolist_to_binary(re:replace("aabbabc","a{1,}b{1,}c","UMeb\\1t",[global])),
- <<"pPfLrjPUFRjvuHjcjabc">> = iolist_to_binary(re:replace("abcabc","a.+?c","pPf\\1LrjPUFRjvuH\\1jcj\\1",[])),
- <<"pPfLrjPUFRjvuHjcjpPfLrjPUFRjvuHjcj">> = iolist_to_binary(re:replace("abcabc","a.+?c","pPf\\1LrjPUFRjvuH\\1jcj\\1",[global])),
- <<"abocUabav">> = iolist_to_binary(re:replace("ab","(a+|b)*","&ocU&av",[])),
- <<"abocUabavocUav">> = iolist_to_binary(re:replace("ab","(a+|b)*","&ocU&av",[global])),
- <<"FWabLo">> = iolist_to_binary(re:replace("ab","(a+|b){0,}","FW&Lo",[])),
- <<"FWabLoFWLo">> = iolist_to_binary(re:replace("ab","(a+|b){0,}","FW&Lo",[global])),
- <<"EGbhiYYab">> = iolist_to_binary(re:replace("ab","(a+|b)+","EG\\1hiYY&",[])),
- <<"EGbhiYYab">> = iolist_to_binary(re:replace("ab","(a+|b)+","EG\\1hiYY&",[global])),
- <<"jbtiMbbNbCoAUbUC">> = iolist_to_binary(re:replace("ab","(a+|b){1,}","j\\1tiM\\1\\1N\\1CoAU\\1UC",[])),
- <<"jbtiMbbNbCoAUbUC">> = iolist_to_binary(re:replace("ab","(a+|b){1,}","j\\1tiM\\1\\1N\\1CoAU\\1UC",[global])),
+ <<"ayglGX">> = iolist_to_binary(re:replace("a","[\\w]","&yglGX",[])),
+ <<"ayglGX">> = iolist_to_binary(re:replace("a","[\\w]","&yglGX",[global])),
+ <<"xHBNG-KPNeTiy--ANU">> = iolist_to_binary(re:replace("-","[\\W]","\\1xHBNG&KPNeTiy&&ANU",[])),
+ <<"xHBNG-KPNeTiy--ANU">> = iolist_to_binary(re:replace("-","[\\W]","\\1xHBNG&KPNeTiy&&ANU",[global])),
+ <<"dLaJCwC** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\W]","dLaJCwC",[])),
+ <<"dLaJCwCdLaJCwCdLaJCwCdLaJCwCFailers">> = iolist_to_binary(re:replace("*** Failers","[\\W]","dLaJCwC",[global])),
+ <<"wRDLkv-">> = iolist_to_binary(re:replace("-","[\\W]","wRDLkv\\1&",[])),
+ <<"wRDLkv-">> = iolist_to_binary(re:replace("-","[\\W]","wRDLkv\\1&",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","[\\W]","y&sFW&WNGfXd\\1gihko&",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","[\\W]","y&sFW&WNGfXd\\1gihko&",[global])),
+ <<"PTJaa bD">> = iolist_to_binary(re:replace("a b","a[\\s]b","PT\\1Ja&D",[])),
+ <<"PTJaa bD">> = iolist_to_binary(re:replace("a b","a[\\s]b","PT\\1Ja&D",[global])),
+ <<"a-bDGOD">> = iolist_to_binary(re:replace("a-b","a[\\S]b","&DGOD",[])),
+ <<"a-bDGOD">> = iolist_to_binary(re:replace("a-b","a[\\S]b","&DGOD",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[\\S]b","KI\\1qEIlJv\\1cnqM&pJC\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[\\S]b","KI\\1qEIlJv\\1cnqM&pJC\\1",[global])),
+ <<"gSDxa-bBtYNus">> = iolist_to_binary(re:replace("a-b","a[\\S]b","gSDx&BtYNus",[])),
+ <<"gSDxa-bBtYNus">> = iolist_to_binary(re:replace("a-b","a[\\S]b","gSDx&BtYNus",[global])),
+ <<"a b">> = iolist_to_binary(re:replace("a b","a[\\S]b","&h",[])),
+ <<"a b">> = iolist_to_binary(re:replace("a b","a[\\S]b","&h",[global])),
+ <<"ykt1W1">> = iolist_to_binary(re:replace("1","[\\d]","ykt&W&",[])),
+ <<"ykt1W1">> = iolist_to_binary(re:replace("1","[\\d]","ykt&W&",[global])),
+ <<"-a">> = iolist_to_binary(re:replace("-","[\\D]","&a",[])),
+ <<"-a">> = iolist_to_binary(re:replace("-","[\\D]","&a",[global])),
+ <<"*WbIHLJ** Failers">> = iolist_to_binary(re:replace("*** Failers","[\\D]","&WbIHLJ",[])),
+ <<"*WbIHLJ*WbIHLJ*WbIHLJ WbIHLJFWbIHLJaWbIHLJiWbIHLJlWbIHLJeWbIHLJrWbIHLJsWbIHLJ">> = iolist_to_binary(re:replace("*** Failers","[\\D]","&WbIHLJ",[global])),
+ <<"-ktR-">> = iolist_to_binary(re:replace("-","[\\D]","&kt\\1\\1R&",[])),
+ <<"-ktR-">> = iolist_to_binary(re:replace("-","[\\D]","&kt\\1\\1R&",[global])),
+ <<"1">> = iolist_to_binary(re:replace("1","[\\D]","ux",[])),
+ <<"1">> = iolist_to_binary(re:replace("1","[\\D]","ux",[global])),
+ <<"qKHabdvc">> = iolist_to_binary(re:replace("abc","ab|cd","qKH&dv",[])),
+ <<"qKHabdvc">> = iolist_to_binary(re:replace("abc","ab|cd","qKH&dv",[global])),
+ <<"DUTiacd">> = iolist_to_binary(re:replace("abcd","ab|cd","DUTia",[])),
+ <<"DUTiaDUTia">> = iolist_to_binary(re:replace("abcd","ab|cd","DUTia",[global])),
+ <<"dydMawOaiUefuVTct">> = iolist_to_binary(re:replace("def","()ef","ydMawOai\\1U&\\1uVTct",[])),
+ <<"dydMawOaiUefuVTct">> = iolist_to_binary(re:replace("def","()ef","ydMawOai\\1U&\\1uVTct",[global])),
+ <<"sca(bMyXpsUtrgSD">> = iolist_to_binary(re:replace("a(b","a\\(b","sc&MyXpsUtrgSD",[])),
+ <<"sca(bMyXpsUtrgSD">> = iolist_to_binary(re:replace("a(b","a\\(b","sc&MyXpsUtrgSD",[global])),
+ <<"tkabU">> = iolist_to_binary(re:replace("ab","a\\(*b","tk&U\\1",[])),
+ <<"tkabU">> = iolist_to_binary(re:replace("ab","a\\(*b","tk&U\\1",[global])),
+ <<"dETFop">> = iolist_to_binary(re:replace("a((b","a\\(*b","dE\\1TFop\\1",[])),
+ <<"dETFop">> = iolist_to_binary(re:replace("a((b","a\\(*b","dE\\1TFop\\1",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","a\\\\b","&wTiaRcRV",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","a\\\\b","&wTiaRcRV",[global])),
+ <<"aDOaQaITtabc">> = iolist_to_binary(re:replace("abc","((a))","\\1DO\\1Q&ITt&",[])),
+ <<"aDOaQaITtabc">> = iolist_to_binary(re:replace("abc","((a))","\\1DO\\1Q&ITt&",[global])),
+ <<"SQSxbQRhSUBA">> = iolist_to_binary(re:replace("abc","(a)b(c)","SQSxbQRhSUBA",[])),
+ <<"SQSxbQRhSUBA">> = iolist_to_binary(re:replace("abc","(a)b(c)","SQSxbQRhSUBA",[global])),
+ <<"aabbKDx">> = iolist_to_binary(re:replace("aabbabc","a+b+c","KDx",[])),
+ <<"aabbKDx">> = iolist_to_binary(re:replace("aabbabc","a+b+c","KDx",[global])),
+ <<"aabbabcVFjoRUjDtvnALeSGQ">> = iolist_to_binary(re:replace("aabbabc","a{1,}b{1,}c","&VFjoRU\\1jDtvnALeSGQ",[])),
+ <<"aabbabcVFjoRUjDtvnALeSGQ">> = iolist_to_binary(re:replace("aabbabc","a{1,}b{1,}c","&VFjoRU\\1jDtvnALeSGQ",[global])),
+ <<"abcWvfQRkKyUAabc">> = iolist_to_binary(re:replace("abcabc","a.+?c","&WvfQRkK\\1y\\1UA",[])),
+ <<"abcWvfQRkKyUAabcWvfQRkKyUA">> = iolist_to_binary(re:replace("abcabc","a.+?c","&WvfQRkK\\1y\\1UA",[global])),
+ <<"jiaeNJbKxbe">> = iolist_to_binary(re:replace("ab","(a+|b)*","jiaeNJ\\1Kx\\1e",[])),
+ <<"jiaeNJbKxbejiaeNJKxe">> = iolist_to_binary(re:replace("ab","(a+|b)*","jiaeNJ\\1Kx\\1e",[global])),
+ <<"EVnwucab">> = iolist_to_binary(re:replace("ab","(a+|b){0,}","EVnwuc&",[])),
+ <<"EVnwucabEVnwuc">> = iolist_to_binary(re:replace("ab","(a+|b){0,}","EVnwuc&",[global])),
+ <<"aKTbabLK">> = iolist_to_binary(re:replace("ab","(a+|b)+","aKT\\1&LK",[])),
+ <<"aKTbabLK">> = iolist_to_binary(re:replace("ab","(a+|b)+","aKT\\1&LK",[global])),
ok.
run18() ->
- <<"aLWaSkPahb">> = iolist_to_binary(re:replace("ab","(a+|b)?","\\1LW\\1SkP&h",[])),
- <<"aLWaSkPahbLWbSkPbhLWSkPh">> = iolist_to_binary(re:replace("ab","(a+|b)?","\\1LW\\1SkP&h",[global])),
- <<"Aab">> = iolist_to_binary(re:replace("ab","(a+|b){0,1}","A\\1",[])),
- <<"AaAbA">> = iolist_to_binary(re:replace("ab","(a+|b){0,1}","A\\1",[global])),
- <<"QOcdemOcded">> = iolist_to_binary(re:replace("cde","[^ab]*","QO&mO&d",[])),
- <<"QOcdemOcdedQOmOd">> = iolist_to_binary(re:replace("cde","[^ab]*","QO&mO&d",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","iTWYAHkkEiJ&r",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","iTWYAHkkEiJ&r",[global])),
- <<"b">> = iolist_to_binary(re:replace("b","abc","Q",[])),
- <<"b">> = iolist_to_binary(re:replace("b","abc","Q",[global])),
- <<"nboabbbcdffWetJfpMLDkabbbcdjOabbbcd">> = iolist_to_binary(re:replace("abbbcd","([abc])*d","nbo&ffWetJfpMLDk&jO&",[])),
- <<"nboabbbcdffWetJfpMLDkabbbcdjOabbbcd">> = iolist_to_binary(re:replace("abbbcd","([abc])*d","nbo&ffWetJfpMLDk&jO&",[global])),
- <<"JaabcduaabcdVPsa">> = iolist_to_binary(re:replace("abcd","([abc])*bcd","J\\1&ua&VPs\\1",[])),
- <<"JaabcduaabcdVPsa">> = iolist_to_binary(re:replace("abcd","([abc])*bcd","J\\1&ua&VPs\\1",[global])),
- <<"e">> = iolist_to_binary(re:replace("e","a|b|c|d|e","&",[])),
- <<"e">> = iolist_to_binary(re:replace("e","a|b|c|d|e","&",[global])),
- <<"kefefAeXq">> = iolist_to_binary(re:replace("ef","(a|b|c|d|e)f","k&&A\\1Xq",[])),
- <<"kefefAeXq">> = iolist_to_binary(re:replace("ef","(a|b|c|d|e)f","k&&A\\1Xq",[global])),
- <<"fsGDN">> = iolist_to_binary(re:replace("abcdefg","abcd*efg","fsG\\1D\\1\\1N\\1",[])),
- <<"fsGDN">> = iolist_to_binary(re:replace("abcdefg","abcd*efg","fsG\\1D\\1\\1N\\1",[global])),
- <<"xThMpLDjpnyabbbz">> = iolist_to_binary(re:replace("xabyabbbz","ab*","T\\1hMpLDjpn",[])),
- <<"xThMpLDjpnyThMpLDjpnz">> = iolist_to_binary(re:replace("xabyabbbz","ab*","T\\1hMpLDjpn",[global])),
- <<"xqjaJaVJVyabbbz">> = iolist_to_binary(re:replace("xayabbbz","ab*","qj&J&VJV",[])),
- <<"xqjaJaVJVyqjabbbJabbbVJVz">> = iolist_to_binary(re:replace("xayabbbz","ab*","qj&J&VJV",[global])),
- <<"abCcdeQnNecduqUkMSfcdGcdecdeh">> = iolist_to_binary(re:replace("abcde","(ab|cd)e","C&QnNe\\1uqUkMSf\\1G&&h",[])),
- <<"abCcdeQnNecduqUkMSfcdGcdecdeh">> = iolist_to_binary(re:replace("abcde","(ab|cd)e","C&QnNe\\1uqUkMSf\\1G&&h",[global])),
- <<"gJyOb">> = iolist_to_binary(re:replace("hij","[abhgefdc]ij","gJyOb",[])),
- <<"gJyOb">> = iolist_to_binary(re:replace("hij","[abhgefdc]ij","gJyOb",[global])),
- <<"abcdGbYcPqM">> = iolist_to_binary(re:replace("abcdef","(abc|)ef","GbY\\1cPqM",[])),
- <<"abcdGbYcPqM">> = iolist_to_binary(re:replace("abcdef","(abc|)ef","GbY\\1cPqM",[global])),
- <<"aUbcdUBbcdAUpIFAbVerWgt">> = iolist_to_binary(re:replace("abcd","(a|b)c*d","U&UB&AUpIFA\\1VerWgt",[])),
- <<"aUbcdUBbcdAUpIFAbVerWgt">> = iolist_to_binary(re:replace("abcd","(a|b)c*d","U&UB&AUpIFA\\1VerWgt",[global])),
- <<"abckK">> = iolist_to_binary(re:replace("abc","(ab|ab*)bc","&kK",[])),
- <<"abckK">> = iolist_to_binary(re:replace("abc","(ab|ab*)bc","&kK",[global])),
- <<"MFabcMbcbcabcXbcGWabcbc">> = iolist_to_binary(re:replace("abc","a([bc]*)c*","MF&M\\1\\1&X\\1GW&\\1",[])),
- <<"MFabcMbcbcabcXbcGWabcbc">> = iolist_to_binary(re:replace("abc","a([bc]*)c*","MF&M\\1\\1&X\\1GW&\\1",[global])),
- <<"bcEbcyv">> = iolist_to_binary(re:replace("abcd","a([bc]*)(c*d)","\\1E\\1yv",[])),
- <<"bcEbcyv">> = iolist_to_binary(re:replace("abcd","a([bc]*)(c*d)","\\1E\\1yv",[global])),
- <<"HJx">> = iolist_to_binary(re:replace("abcd","a([bc]+)(c*d)","HJx",[])),
- <<"HJx">> = iolist_to_binary(re:replace("abcd","a([bc]+)(c*d)","HJx",[global])),
+ <<"RgGBbwcmabTgNL">> = iolist_to_binary(re:replace("ab","(a+|b){1,}","RgGB\\1wcm&TgNL",[])),
+ <<"RgGBbwcmabTgNL">> = iolist_to_binary(re:replace("ab","(a+|b){1,}","RgGB\\1wcm&TgNL",[global])),
+ <<"TawgaFaOxEylUb">> = iolist_to_binary(re:replace("ab","(a+|b)?","T&wg&F\\1OxEylU",[])),
+ <<"TawgaFaOxEylUTbwgbFbOxEylUTwgFOxEylU">> = iolist_to_binary(re:replace("ab","(a+|b)?","T&wg&F\\1OxEylU",[global])),
+ <<"aaaLnab">> = iolist_to_binary(re:replace("ab","(a+|b){0,1}","\\1&&Ln&",[])),
+ <<"aaaLnabbbLnbLn">> = iolist_to_binary(re:replace("ab","(a+|b){0,1}","\\1&&Ln&",[global])),
+ <<"slxWNnoiUcdeJcdercde">> = iolist_to_binary(re:replace("cde","[^ab]*","s\\1lxW\\1NnoiU\\1&J\\1&r&",[])),
+ <<"slxWNnoiUcdeJcdercdeslxWNnoiUJr">> = iolist_to_binary(re:replace("cde","[^ab]*","s\\1lxW\\1NnoiU\\1&J\\1&r&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","vVEiRHOJeg&j\\1CJbVaYo",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","vVEiRHOJeg&j\\1CJbVaYo",[global])),
+ <<"b">> = iolist_to_binary(re:replace("b","abc","G\\1tppsRP\\1RDSBHMk&kQ",[])),
+ <<"b">> = iolist_to_binary(re:replace("b","abc","G\\1tppsRP\\1RDSBHMk&kQ",[global])),
+ <<"clNPcDSOUbWFhRtX">> = iolist_to_binary(re:replace("abbbcd","([abc])*d","\\1lNP\\1DSOUbWFhRtX",[])),
+ <<"clNPcDSOUbWFhRtX">> = iolist_to_binary(re:replace("abbbcd","([abc])*d","\\1lNP\\1DSOUbWFhRtX",[global])),
+ <<"bIaKUaabcdabcdjUqa">> = iolist_to_binary(re:replace("abcd","([abc])*bcd","bI\\1KU\\1&&jUq\\1",[])),
+ <<"bIaKUaabcdabcdjUqa">> = iolist_to_binary(re:replace("abcd","([abc])*bcd","bI\\1KU\\1&&jUq\\1",[global])),
+ <<"vBRef">> = iolist_to_binary(re:replace("e","a|b|c|d|e","vBR&f",[])),
+ <<"vBRef">> = iolist_to_binary(re:replace("e","a|b|c|d|e","vBR&f",[global])),
+ <<"eesSfPHTpUXDPv">> = iolist_to_binary(re:replace("ef","(a|b|c|d|e)f","\\1\\1sSfPHTpUXDPv",[])),
+ <<"eesSfPHTpUXDPv">> = iolist_to_binary(re:replace("ef","(a|b|c|d|e)f","\\1\\1sSfPHTpUXDPv",[global])),
+ <<"srtWRpRn">> = iolist_to_binary(re:replace("abcdefg","abcd*efg","sr\\1tWRpRn",[])),
+ <<"srtWRpRn">> = iolist_to_binary(re:replace("abcdefg","abcd*efg","sr\\1tWRpRn",[global])),
+ <<"xpLuYECabyabbbz">> = iolist_to_binary(re:replace("xabyabbbz","ab*","pLuYEC&",[])),
+ <<"xpLuYECabypLuYECabbbz">> = iolist_to_binary(re:replace("xabyabbbz","ab*","pLuYEC&",[global])),
+ <<"xGaaxBDcnaOuAXyabbbz">> = iolist_to_binary(re:replace("xayabbbz","ab*","G&&xBDc\\1n&O\\1\\1uAX\\1\\1\\1\\1",[])),
+ <<"xGaaxBDcnaOuAXyGabbbabbbxBDcnabbbOuAXz">> = iolist_to_binary(re:replace("xayabbbz","ab*","G&&xBDc\\1n&O\\1\\1uAX\\1\\1\\1\\1",[global])),
+ <<"abJiuiBBGK">> = iolist_to_binary(re:replace("abcde","(ab|cd)e","JiuiBBGK",[])),
+ <<"abJiuiBBGK">> = iolist_to_binary(re:replace("abcde","(ab|cd)e","JiuiBBGK",[global])),
+ <<"QIhijHNIh">> = iolist_to_binary(re:replace("hij","[abhgefdc]ij","QI\\1&HNI\\1h",[])),
+ <<"QIhijHNIh">> = iolist_to_binary(re:replace("hij","[abhgefdc]ij","QI\\1&HNI\\1h",[global])),
+ <<"abcdNy">> = iolist_to_binary(re:replace("abcdef","(abc|)ef","Ny",[])),
+ <<"abcdNy">> = iolist_to_binary(re:replace("abcdef","(abc|)ef","Ny",[global])),
+ <<"ahYR">> = iolist_to_binary(re:replace("abcd","(a|b)c*d","hYR",[])),
+ <<"ahYR">> = iolist_to_binary(re:replace("abcd","(a|b)c*d","hYR",[global])),
+ <<"LaabcUlMoCaAoluf">> = iolist_to_binary(re:replace("abc","(ab|ab*)bc","L\\1&UlMoC\\1Aoluf",[])),
+ <<"LaabcUlMoCaAoluf">> = iolist_to_binary(re:replace("abc","(ab|ab*)bc","L\\1&UlMoC\\1Aoluf",[global])),
+ <<"babcqrDkwikibc">> = iolist_to_binary(re:replace("abc","a([bc]*)c*","b&qrDkwiki\\1",[])),
+ <<"babcqrDkwikibc">> = iolist_to_binary(re:replace("abc","a([bc]*)c*","b&qrDkwiki\\1",[global])),
+ <<"VrVOACabcdHnObcsbc">> = iolist_to_binary(re:replace("abcd","a([bc]*)(c*d)","VrVOAC&HnO\\1s\\1",[])),
+ <<"VrVOACabcdHnObcsbc">> = iolist_to_binary(re:replace("abcd","a([bc]*)(c*d)","VrVOAC&HnO\\1s\\1",[global])),
ok.
run19() ->
- <<"HdbW">> = iolist_to_binary(re:replace("abcd","a([bc]*)(c+d)","Hd\\1W",[])),
- <<"HdbW">> = iolist_to_binary(re:replace("abcd","a([bc]*)(c+d)","Hd\\1W",[global])),
- <<"FqCeJOadcdcdeIvQpadcdcdeadcdcdeadcdcdeH">> = iolist_to_binary(re:replace("adcdcde","a[bcd]*dcdcde","FqCeJO&IvQp\\1\\1&&&H",[])),
- <<"FqCeJOadcdcdeIvQpadcdcdeadcdcdeadcdcdeH">> = iolist_to_binary(re:replace("adcdcde","a[bcd]*dcdcde","FqCeJO&IvQp\\1\\1&&&H",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[bcd]+dcdcde","\\1&TNEyDw",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[bcd]+dcdcde","\\1&TNEyDw",[global])),
- <<"abcde">> = iolist_to_binary(re:replace("abcde","a[bcd]+dcdcde","PqeS\\1GQJ&vSq&YhS",[])),
- <<"abcde">> = iolist_to_binary(re:replace("abcde","a[bcd]+dcdcde","PqeS\\1GQJ&vSq&YhS",[global])),
- <<"adcdcde">> = iolist_to_binary(re:replace("adcdcde","a[bcd]+dcdcde","vdBav\\1Ild",[])),
- <<"adcdcde">> = iolist_to_binary(re:replace("adcdcde","a[bcd]+dcdcde","vdBav\\1Ild",[global])),
- <<"GIjXVoAJXroabclW">> = iolist_to_binary(re:replace("abc","(ab|a)b*c","GIjXVoAJXro&lW",[])),
- <<"GIjXVoAJXroabclW">> = iolist_to_binary(re:replace("abc","(ab|a)b*c","GIjXVoAJXro&lW",[global])),
- <<"pKabcabctabcdqabcdaAabcdpgPtdK">> = iolist_to_binary(re:replace("abcd","((a)(b)c)(d)","pK\\1\\1t&q&aA&pgPtdK",[])),
- <<"pKabcabctabcdqabcdaAabcdpgPtdK">> = iolist_to_binary(re:replace("abcd","((a)(b)c)(d)","pK\\1\\1t&q&aA&pgPtdK",[global])),
- <<"XrxalphaplnalphaMFGv">> = iolist_to_binary(re:replace("alpha","[a-zA-Z_][a-zA-Z0-9_]*","Xrx&pln&MFG\\1v",[])),
- <<"XrxalphaplnalphaMFGv">> = iolist_to_binary(re:replace("alpha","[a-zA-Z_][a-zA-Z0-9_]*","Xrx&pln&MFG\\1v",[global])),
- <<"ajbhHEObuuuMEIegbh">> = iolist_to_binary(re:replace("abh","^a(bc+|b[eh])g|.h$","j&HEObuu\\1uMEIeg&",[])),
- <<"ajbhHEObuuuMEIegbh">> = iolist_to_binary(re:replace("abh","^a(bc+|b[eh])g|.h$","j&HEObuu\\1uMEIeg&",[global])),
- <<"effgzFiGeffgzUwqI">> = iolist_to_binary(re:replace("effgz","(bc+d$|ef*g.|h?i(j|k))","&FiG\\1UwqI",[])),
- <<"effgzFiGeffgzUwqI">> = iolist_to_binary(re:replace("effgz","(bc+d$|ef*g.|h?i(j|k))","&FiG\\1UwqI",[global])),
- <<"ijJMstbxCWsijpVijVwQav">> = iolist_to_binary(re:replace("ij","(bc+d$|ef*g.|h?i(j|k))","&JMstbxCWs&pV\\1VwQav",[])),
- <<"ijJMstbxCWsijpVijVwQav">> = iolist_to_binary(re:replace("ij","(bc+d$|ef*g.|h?i(j|k))","&JMstbxCWs&pV\\1VwQav",[global])),
- <<"rqYdteffgzVIpOoenIHdd">> = iolist_to_binary(re:replace("reffgz","(bc+d$|ef*g.|h?i(j|k))","qYdt&VIpOoenIHdd",[])),
- <<"rqYdteffgzVIpOoenIHdd">> = iolist_to_binary(re:replace("reffgz","(bc+d$|ef*g.|h?i(j|k))","qYdt&VIpOoenIHdd",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(bc+d$|ef*g.|h?i(j|k))","aq",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(bc+d$|ef*g.|h?i(j|k))","aq",[global])),
- <<"effg">> = iolist_to_binary(re:replace("effg","(bc+d$|ef*g.|h?i(j|k))","yHtJLFej\\1yYR\\1sQo&np",[])),
- <<"effg">> = iolist_to_binary(re:replace("effg","(bc+d$|ef*g.|h?i(j|k))","yHtJLFej\\1yYR\\1sQo&np",[global])),
- <<"bcdd">> = iolist_to_binary(re:replace("bcdd","(bc+d$|ef*g.|h?i(j|k))","y\\1WeuT\\1",[])),
- <<"bcdd">> = iolist_to_binary(re:replace("bcdd","(bc+d$|ef*g.|h?i(j|k))","y\\1WeuT\\1",[global])),
- <<"wodvWYlegweBrV">> = iolist_to_binary(re:replace("a","((((((((((a))))))))))","wodvWYlegweBrV",[])),
- <<"wodvWYlegweBrV">> = iolist_to_binary(re:replace("a","((((((((((a))))))))))","wodvWYlegweBrV",[global])),
- <<"gqasCpaas">> = iolist_to_binary(re:replace("aa","((((((((((a))))))))))\\10","gq\\1sCp\\1\\1s",[])),
- <<"gqasCpaas">> = iolist_to_binary(re:replace("aa","((((((((((a))))))))))\\10","gq\\1sCp\\1\\1s",[global])),
- <<"GwagSDfa">> = iolist_to_binary(re:replace("a","(((((((((a)))))))))","Gw&gSDf&",[])),
- <<"GwagSDfa">> = iolist_to_binary(re:replace("a","(((((((((a)))))))))","Gw&gSDf&",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","multiple words of text","qj&H&TFbc&WmR",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","multiple words of text","qj&H&TFbc&WmR",[global])),
- <<"aa">> = iolist_to_binary(re:replace("aa","multiple words of text","FwU",[])),
- <<"aa">> = iolist_to_binary(re:replace("aa","multiple words of text","FwU",[global])),
- <<"uh-uh">> = iolist_to_binary(re:replace("uh-uh","multiple words of text","Tf&&&bwM&KOaXHg\\1WRNk",[])),
- <<"uh-uh">> = iolist_to_binary(re:replace("uh-uh","multiple words of text","Tf&&&bwM&KOaXHg\\1WRNk",[global])),
- <<"RdXXlExbAbHAgDE, yeah">> = iolist_to_binary(re:replace("multiple words, yeah","multiple words","R\\1dXXl\\1ExbAbHAgDE",[])),
- <<"RdXXlExbAbHAgDE, yeah">> = iolist_to_binary(re:replace("multiple words, yeah","multiple words","R\\1dXXl\\1ExbAbHAgDE",[global])),
- <<"ababcCxabsCTYB">> = iolist_to_binary(re:replace("abcde","(.*)c(.*)","\\1\\1cCx\\1sCTYB",[])),
- <<"ababcCxabsCTYB">> = iolist_to_binary(re:replace("abcde","(.*)c(.*)","\\1\\1cCx\\1sCTYB",[global])),
- <<"rW">> = iolist_to_binary(re:replace("(a, b)","\\((.*), (.*)\\)","rW",[])),
- <<"rW">> = iolist_to_binary(re:replace("(a, b)","\\((.*), (.*)\\)","rW",[global])),
- <<"dabcd">> = iolist_to_binary(re:replace("abcd","abcd","d&",[])),
- <<"dabcd">> = iolist_to_binary(re:replace("abcd","abcd","d&",[global])),
- <<"bclAbcTn">> = iolist_to_binary(re:replace("abcd","a(bc)d","\\1lA\\1Tn",[])),
- <<"bclAbcTn">> = iolist_to_binary(re:replace("abcd","a(bc)d","\\1lA\\1Tn",[global])),
- <<"waf">> = iolist_to_binary(re:replace("ac","a[-]?c","waf",[])),
- <<"waf">> = iolist_to_binary(re:replace("ac","a[-]?c","waf",[global])),
- <<"HpOuFXbFnUEO">> = iolist_to_binary(re:replace("abcabc","(abc)\\1","HpOuFXbFnUEO",[])),
- <<"HpOuFXbFnUEO">> = iolist_to_binary(re:replace("abcabc","(abc)\\1","HpOuFXbFnUEO",[global])),
+ <<"KBrNXAjqQYabcdRvj">> = iolist_to_binary(re:replace("abcd","a([bc]+)(c*d)","KBrNXAjqQY&Rvj",[])),
+ <<"KBrNXAjqQYabcdRvj">> = iolist_to_binary(re:replace("abcd","a([bc]+)(c*d)","KBrNXAjqQY&Rvj",[global])),
+ <<"o">> = iolist_to_binary(re:replace("abcd","a([bc]*)(c+d)","o",[])),
+ <<"o">> = iolist_to_binary(re:replace("abcd","a([bc]*)(c+d)","o",[global])),
+ <<"mXgwSISPpB">> = iolist_to_binary(re:replace("adcdcde","a[bcd]*dcdcde","mXgw\\1S\\1ISPpB",[])),
+ <<"mXgwSISPpB">> = iolist_to_binary(re:replace("adcdcde","a[bcd]*dcdcde","mXgw\\1S\\1ISPpB",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[bcd]+dcdcde","uJpSxOBN",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[bcd]+dcdcde","uJpSxOBN",[global])),
+ <<"abcde">> = iolist_to_binary(re:replace("abcde","a[bcd]+dcdcde","aDD\\1OV",[])),
+ <<"abcde">> = iolist_to_binary(re:replace("abcde","a[bcd]+dcdcde","aDD\\1OV",[global])),
+ <<"adcdcde">> = iolist_to_binary(re:replace("adcdcde","a[bcd]+dcdcde","sSDdKN\\1SAhXJR\\1Xwp",[])),
+ <<"adcdcde">> = iolist_to_binary(re:replace("adcdcde","a[bcd]+dcdcde","sSDdKN\\1SAhXJR\\1Xwp",[global])),
+ <<"HHwQpababUNd">> = iolist_to_binary(re:replace("abc","(ab|a)b*c","HHwQp\\1\\1UNd",[])),
+ <<"HHwQpababUNd">> = iolist_to_binary(re:replace("abc","(ab|a)b*c","HHwQp\\1\\1UNd",[global])),
+ <<"kvabcDX">> = iolist_to_binary(re:replace("abcd","((a)(b)c)(d)","kv\\1DX",[])),
+ <<"kvabcDX">> = iolist_to_binary(re:replace("abcd","((a)(b)c)(d)","kv\\1DX",[global])),
+ <<"odmopDrikjpbalphaalphaV">> = iolist_to_binary(re:replace("alpha","[a-zA-Z_][a-zA-Z0-9_]*","odmop\\1Drikjpb\\1&&V",[])),
+ <<"odmopDrikjpbalphaalphaV">> = iolist_to_binary(re:replace("alpha","[a-zA-Z_][a-zA-Z0-9_]*","odmop\\1Drikjpb\\1&&V",[global])),
+ <<"aJBuUN">> = iolist_to_binary(re:replace("abh","^a(bc+|b[eh])g|.h$","JBuU\\1N",[])),
+ <<"aJBuUN">> = iolist_to_binary(re:replace("abh","^a(bc+|b[eh])g|.h$","JBuU\\1N",[global])),
+ <<"GeffgzTeffgzeffgzVpRCp">> = iolist_to_binary(re:replace("effgz","(bc+d$|ef*g.|h?i(j|k))","G\\1T\\1\\1VpRCp",[])),
+ <<"GeffgzTeffgzeffgzVpRCp">> = iolist_to_binary(re:replace("effgz","(bc+d$|ef*g.|h?i(j|k))","G\\1T\\1\\1VpRCp",[global])),
+ <<"aqNijfRFijIAijWeij">> = iolist_to_binary(re:replace("ij","(bc+d$|ef*g.|h?i(j|k))","aqN&fRF\\1IA\\1We&",[])),
+ <<"aqNijfRFijIAijWeij">> = iolist_to_binary(re:replace("ij","(bc+d$|ef*g.|h?i(j|k))","aqN&fRF\\1IA\\1We&",[global])),
+ <<"roTeffgzdfhkqWsMVteffgzL">> = iolist_to_binary(re:replace("reffgz","(bc+d$|ef*g.|h?i(j|k))","oT\\1dfhkqWsMVt&L",[])),
+ <<"roTeffgzdfhkqWsMVteffgzL">> = iolist_to_binary(re:replace("reffgz","(bc+d$|ef*g.|h?i(j|k))","oT\\1dfhkqWsMVt&L",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(bc+d$|ef*g.|h?i(j|k))","Dq&f&xNUnXDDAU",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(bc+d$|ef*g.|h?i(j|k))","Dq&f&xNUnXDDAU",[global])),
+ <<"effg">> = iolist_to_binary(re:replace("effg","(bc+d$|ef*g.|h?i(j|k))","qtqCY\\1k",[])),
+ <<"effg">> = iolist_to_binary(re:replace("effg","(bc+d$|ef*g.|h?i(j|k))","qtqCY\\1k",[global])),
+ <<"bcdd">> = iolist_to_binary(re:replace("bcdd","(bc+d$|ef*g.|h?i(j|k))","JuBrHsMekXgTKSL&",[])),
+ <<"bcdd">> = iolist_to_binary(re:replace("bcdd","(bc+d$|ef*g.|h?i(j|k))","JuBrHsMekXgTKSL&",[global])),
+ <<"aDaQVaKxbaaHaatahXTm">> = iolist_to_binary(re:replace("a","((((((((((a))))))))))","\\1DaQV&Kxb\\1\\1H\\1&t\\1hXTm",[])),
+ <<"aDaQVaKxbaaHaatahXTm">> = iolist_to_binary(re:replace("a","((((((((((a))))))))))","\\1DaQV&Kxb\\1\\1H\\1&t\\1hXTm",[global])),
+ <<"m">> = iolist_to_binary(re:replace("aa","((((((((((a))))))))))\\10","m",[])),
+ <<"m">> = iolist_to_binary(re:replace("aa","((((((((((a))))))))))\\10","m",[global])),
+ <<"jaakGadYaFafTMa">> = iolist_to_binary(re:replace("a","(((((((((a)))))))))","j\\1&kGadY&F\\1fTM\\1",[])),
+ <<"jaakGadYaFafTMa">> = iolist_to_binary(re:replace("a","(((((((((a)))))))))","j\\1&kGadY&F\\1fTM\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","multiple words of text","WEPrQ&rD&usui\\1D\\1VY",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","multiple words of text","WEPrQ&rD&usui\\1D\\1VY",[global])),
+ <<"aa">> = iolist_to_binary(re:replace("aa","multiple words of text","&wQ\\1",[])),
+ <<"aa">> = iolist_to_binary(re:replace("aa","multiple words of text","&wQ\\1",[global])),
+ <<"uh-uh">> = iolist_to_binary(re:replace("uh-uh","multiple words of text","SLs\\1",[])),
+ <<"uh-uh">> = iolist_to_binary(re:replace("uh-uh","multiple words of text","SLs\\1",[global])),
+ <<"CRemultiple wordsKmultiple wordsQICTcCoH, yeah">> = iolist_to_binary(re:replace("multiple words, yeah","multiple words","CRe&K&QICT\\1cCoH",[])),
+ <<"CRemultiple wordsKmultiple wordsQICTcCoH, yeah">> = iolist_to_binary(re:replace("multiple words, yeah","multiple words","CRe&K&QICT\\1cCoH",[global])),
+ <<"hsyabSabFJkfGRG">> = iolist_to_binary(re:replace("abcde","(.*)c(.*)","hsy\\1S\\1FJkfGRG",[])),
+ <<"hsyabSabFJkfGRG">> = iolist_to_binary(re:replace("abcde","(.*)c(.*)","hsy\\1S\\1FJkfGRG",[global])),
+ <<"aOu">> = iolist_to_binary(re:replace("(a, b)","\\((.*), (.*)\\)","\\1Ou",[])),
+ <<"aOu">> = iolist_to_binary(re:replace("(a, b)","\\((.*), (.*)\\)","\\1Ou",[global])),
+ <<"WCvfBkLabcd">> = iolist_to_binary(re:replace("abcd","abcd","WCvfBkL&",[])),
+ <<"WCvfBkLabcd">> = iolist_to_binary(re:replace("abcd","abcd","WCvfBkL&",[global])),
+ <<"bcNBWgjxabcdFGdbcabcdw">> = iolist_to_binary(re:replace("abcd","a(bc)d","\\1NBWgjx&FGd\\1&w",[])),
+ <<"bcNBWgjxabcdFGdbcabcdw">> = iolist_to_binary(re:replace("abcd","a(bc)d","\\1NBWgjx&FGd\\1&w",[global])),
+ <<"acx">> = iolist_to_binary(re:replace("ac","a[-]?c","&x\\1",[])),
+ <<"acx">> = iolist_to_binary(re:replace("ac","a[-]?c","&x\\1",[global])),
ok.
run20() ->
- <<"XvCLIKabcabcohl">> = iolist_to_binary(re:replace("abcabc","([a-c]*)\\1","XvCLIK&ohl",[])),
- <<"XvCLIKabcabcohlXvCLIKohl">> = iolist_to_binary(re:replace("abcabc","([a-c]*)\\1","XvCLIK&ohl",[global])),
- <<"THmLVdxHpEOamaQ">> = iolist_to_binary(re:replace("a","(a)|\\1","THmLVdxHpEOam\\1Q",[])),
- <<"THmLVdxHpEOamaQ">> = iolist_to_binary(re:replace("a","(a)|\\1","THmLVdxHpEOam\\1Q",[global])),
- <<"*** FjGfKKSoilers">> = iolist_to_binary(re:replace("*** Failers","(a)|\\1","jGfKKSo",[])),
- <<"*** FjGfKKSoilers">> = iolist_to_binary(re:replace("*** Failers","(a)|\\1","jGfKKSo",[global])),
- <<"pCab">> = iolist_to_binary(re:replace("ab","(a)|\\1","pC&",[])),
- <<"pCab">> = iolist_to_binary(re:replace("ab","(a)|\\1","pC&",[global])),
- <<"x">> = iolist_to_binary(re:replace("x","(a)|\\1","U",[])),
- <<"x">> = iolist_to_binary(re:replace("x","(a)|\\1","U",[global])),
- <<"nwvlinqmgabbLababbvbcbc">> = iolist_to_binary(re:replace("ababbbcbc","(([a-c])b*?\\2)*","nwvlinqmga\\1L&v",[])),
- <<"nwvlinqmgabbLababbvnwvlinqmgaLvbnwvlinqmgacbcLcbcvnwvlinqmgaLv">> = iolist_to_binary(re:replace("ababbbcbc","(([a-c])b*?\\2)*","nwvlinqmga\\1L&v",[global])),
- <<"XEababbbcbccbcnoei">> = iolist_to_binary(re:replace("ababbbcbc","(([a-c])b*?\\2){3}","XE&\\1noei",[])),
- <<"XEababbbcbccbcnoei">> = iolist_to_binary(re:replace("ababbbcbc","(([a-c])b*?\\2){3}","XE&\\1noei",[global])),
- <<"aaaxabaxbaaxbbaxQHJip">> = iolist_to_binary(re:replace("aaaxabaxbaaxbbax","((\\3|b)\\2(a)x)+","&QHJip",[])),
- <<"aaaxabaxbaaxbbaxQHJip">> = iolist_to_binary(re:replace("aaaxabaxbaaxbbax","((\\3|b)\\2(a)x)+","&QHJip",[global])),
- <<"bbaababbabaaaaaFjrtkQstbbaaaabbabbaaaabbaRobbaaaabbaQwbbaJbbaaaabbabbaaaabba">> = iolist_to_binary(re:replace("bbaababbabaaaaabbaaaabba","((\\3|b)\\2(a)){2,}","FjrtkQst&&Ro&Qw\\1J&&",[])),
- <<"bbaababbabaaaaaFjrtkQstbbaaaabbabbaaaabbaRobbaaaabbaQwbbaJbbaaaabbabbaaaabba">> = iolist_to_binary(re:replace("bbaababbabaaaaabbaaaabba","((\\3|b)\\2(a)){2,}","FjrtkQst&&Ro&Qw\\1J&&",[global])),
- <<"hryRShiLJ">> = iolist_to_binary(re:replace("ABC","abc","hryRShiL\\1J",[caseless])),
- <<"hryRShiLJ">> = iolist_to_binary(re:replace("ABC","abc","hryRShiL\\1J",[caseless,
- global])),
- <<"XHUenvABCCmAOuuCY">> = iolist_to_binary(re:replace("XABCY","abc","HUenv&C\\1mAOuuC",[caseless])),
- <<"XHUenvABCCmAOuuCY">> = iolist_to_binary(re:replace("XABCY","abc","HUenv&C\\1mAOuuC",[caseless,
- global])),
- <<"AB">> = iolist_to_binary(re:replace("ABABC","abc","\\1",[caseless])),
- <<"AB">> = iolist_to_binary(re:replace("ABABC","abc","\\1",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","qc&a\\1M&&\\1qqO&&YaV",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","qc&a\\1M&&\\1qqO&&YaV",[caseless,
- global])),
- <<"aaxabxbaxbbx">> = iolist_to_binary(re:replace("aaxabxbaxbbx","abc","YoMmmB&v\\1N\\1voc",[caseless])),
- <<"aaxabxbaxbbx">> = iolist_to_binary(re:replace("aaxabxbaxbbx","abc","YoMmmB&v\\1N\\1voc",[caseless,
+ <<"huMWbabcsRaEC">> = iolist_to_binary(re:replace("abcabc","(abc)\\1","huMWb\\1sRaEC",[])),
+ <<"huMWbabcsRaEC">> = iolist_to_binary(re:replace("abcabc","(abc)\\1","huMWb\\1sRaEC",[global])),
+ <<"iexabcabcabcabcNCHabcabcvuWaLb">> = iolist_to_binary(re:replace("abcabc","([a-c]*)\\1","iex&&NCH&vuWaLb",[])),
+ <<"iexabcabcabcabcNCHabcabcvuWaLbiexNCHvuWaLb">> = iolist_to_binary(re:replace("abcabc","([a-c]*)\\1","iex&&NCH&vuWaLb",[global])),
+ <<"yJihtasaOaRaI">> = iolist_to_binary(re:replace("a","(a)|\\1","yJihtas&O&R&I",[])),
+ <<"yJihtasaOaRaI">> = iolist_to_binary(re:replace("a","(a)|\\1","yJihtas&O&R&I",[global])),
+ <<"*** FIaHjkilers">> = iolist_to_binary(re:replace("*** Failers","(a)|\\1","I\\1Hjk",[])),
+ <<"*** FIaHjkilers">> = iolist_to_binary(re:replace("*** Failers","(a)|\\1","I\\1Hjk",[global])),
+ <<"EamavFGoBaaBPRaFOhib">> = iolist_to_binary(re:replace("ab","(a)|\\1","E\\1m\\1vFGoB\\1&BPR\\1FOhi",[])),
+ <<"EamavFGoBaaBPRaFOhib">> = iolist_to_binary(re:replace("ab","(a)|\\1","E\\1m\\1vFGoB\\1&BPR\\1FOhi",[global])),
+ <<"x">> = iolist_to_binary(re:replace("x","(a)|\\1","NnSvRd&pb",[])),
+ <<"x">> = iolist_to_binary(re:replace("x","(a)|\\1","NnSvRd&pb",[global])),
+ <<"uBuYmababbcqWpqxebcbc">> = iolist_to_binary(re:replace("ababbbcbc","(([a-c])b*?\\2)*","uBuYm&cqWpqxe",[])),
+ <<"uBuYmababbcqWpqxeuBuYmcqWpqxebuBuYmcbccqWpqxeuBuYmcqWpqxe">> = iolist_to_binary(re:replace("ababbbcbc","(([a-c])b*?\\2)*","uBuYm&cqWpqxe",[global])),
+ <<"EcbcOTScbccbc">> = iolist_to_binary(re:replace("ababbbcbc","(([a-c])b*?\\2){3}","E\\1OTS\\1\\1",[])),
+ <<"EcbcOTScbccbc">> = iolist_to_binary(re:replace("ababbbcbc","(([a-c])b*?\\2){3}","E\\1OTS\\1\\1",[global])),
+ <<"aaaxabaxbaaxMcBMqqECobbaxAWhbbax">> = iolist_to_binary(re:replace("aaaxabaxbaaxbbax","((\\3|b)\\2(a)x)+","McBMqqECo\\1AWh\\1",[])),
+ <<"aaaxabaxbaaxMcBMqqECobbaxAWhbbax">> = iolist_to_binary(re:replace("aaaxabaxbaaxbbax","((\\3|b)\\2(a)x)+","McBMqqECo\\1AWh\\1",[global])),
+ <<"bbaababbabaaaaaqjbbaaaabbabbaVgmcpcbbajpNX">> = iolist_to_binary(re:replace("bbaababbabaaaaabbaaaabba","((\\3|b)\\2(a)){2,}","qj&\\1Vgmcpc\\1jpNX",[])),
+ <<"bbaababbabaaaaaqjbbaaaabbabbaVgmcpcbbajpNX">> = iolist_to_binary(re:replace("bbaababbabaaaaabbaaaabba","((\\3|b)\\2(a)){2,}","qj&\\1Vgmcpc\\1jpNX",[global])),
+ <<"ABCyABCdyvLRsRMABCihr">> = iolist_to_binary(re:replace("ABC","abc","&y&dy\\1vLRsRM&ihr",[caseless])),
+ <<"ABCyABCdyvLRsRMABCihr">> = iolist_to_binary(re:replace("ABC","abc","&y&dy\\1vLRsRM&ihr",[caseless,
+ global])),
+ <<"XfgcwoIpABCY">> = iolist_to_binary(re:replace("XABCY","abc","fgcwoIp&",[caseless])),
+ <<"XfgcwoIpABCY">> = iolist_to_binary(re:replace("XABCY","abc","fgcwoIp&",[caseless,
+ global])),
+ <<"ABWoWCFrcHpLABCpDF">> = iolist_to_binary(re:replace("ABABC","abc","WoW\\1CFrcHpL&p\\1DF",[caseless])),
+ <<"ABWoWCFrcHpLABCpDF">> = iolist_to_binary(re:replace("ABABC","abc","WoW\\1CFrcHpL&p\\1DF",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","\\1dHtGrvxuN&bjVI\\1LF&",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","abc","\\1dHtGrvxuN&bjVI\\1LF&",[caseless,
+ global])),
+ <<"aaxabxbaxbbx">> = iolist_to_binary(re:replace("aaxabxbaxbbx","abc","FMCY&jfPDp&ePPmkBaNK",[caseless])),
+ <<"aaxabxbaxbbx">> = iolist_to_binary(re:replace("aaxabxbaxbbx","abc","FMCY&jfPDp&ePPmkBaNK",[caseless,
+ global])),
+ <<"XBC">> = iolist_to_binary(re:replace("XBC","abc","yK",[caseless])),
+ <<"XBC">> = iolist_to_binary(re:replace("XBC","abc","yK",[caseless,
+ global])),
+ <<"AXC">> = iolist_to_binary(re:replace("AXC","abc","y\\1Bxx\\1c",[caseless])),
+ <<"AXC">> = iolist_to_binary(re:replace("AXC","abc","y\\1Bxx\\1c",[caseless,
+ global])),
+ <<"ABX">> = iolist_to_binary(re:replace("ABX","abc","&e\\1",[caseless])),
+ <<"ABX">> = iolist_to_binary(re:replace("ABX","abc","&e\\1",[caseless,
+ global])),
+ <<"wIDivFpmRD">> = iolist_to_binary(re:replace("ABC","ab*c","w\\1IDivFpmRD",[caseless])),
+ <<"wIDivFpmRD">> = iolist_to_binary(re:replace("ABC","ab*c","w\\1IDivFpmRD",[caseless,
+ global])),
+ <<"mjJOdABCVwUnuEHfFUblABCE">> = iolist_to_binary(re:replace("ABC","ab*bc","mjJOd&VwUnuEHfFUbl&E",[caseless])),
+ <<"mjJOdABCVwUnuEHfFUblABCE">> = iolist_to_binary(re:replace("ABC","ab*bc","mjJOd&VwUnuEHfFUbl&E",[caseless,
+ global])),
+ <<"aqlXiaaCABBCtGMyJr">> = iolist_to_binary(re:replace("ABBC","ab*bc","aqlXia\\1aC\\1&tGMyJr",[caseless])),
+ <<"aqlXiaaCABBCtGMyJr">> = iolist_to_binary(re:replace("ABBC","ab*bc","aqlXia\\1aC\\1&tGMyJr",[caseless,
+ global])),
+ <<"QsHTFT">> = iolist_to_binary(re:replace("ABBBBC","ab*?bc","Q\\1sHTFT",[caseless])),
+ <<"QsHTFT">> = iolist_to_binary(re:replace("ABBBBC","ab*?bc","Q\\1sHTFT",[caseless,
+ global])),
+ <<"UdwHeAkxpFABBBBCTJI">> = iolist_to_binary(re:replace("ABBBBC","ab{0,}?bc","\\1UdwHeAk\\1xpF&\\1T\\1JI",[caseless])),
+ <<"UdwHeAkxpFABBBBCTJI">> = iolist_to_binary(re:replace("ABBBBC","ab{0,}?bc","\\1UdwHeAk\\1xpF&\\1T\\1JI",[caseless,
+ global])),
+ <<"paupnNUOYjABBCXABBC">> = iolist_to_binary(re:replace("ABBC","ab+?bc","pa\\1upnNUO\\1Yj&\\1X&",[caseless])),
+ <<"paupnNUOYjABBCXABBC">> = iolist_to_binary(re:replace("ABBC","ab+?bc","pa\\1upnNUO\\1Yj&\\1X&",[caseless,
global])),
- <<"XBC">> = iolist_to_binary(re:replace("XBC","abc","\\1gwN\\1pcAL\\1le&B",[caseless])),
- <<"XBC">> = iolist_to_binary(re:replace("XBC","abc","\\1gwN\\1pcAL\\1le&B",[caseless,
- global])),
- <<"AXC">> = iolist_to_binary(re:replace("AXC","abc","vQ&&a\\1Kw",[caseless])),
- <<"AXC">> = iolist_to_binary(re:replace("AXC","abc","vQ&&a\\1Kw",[caseless,
- global])),
- <<"ABX">> = iolist_to_binary(re:replace("ABX","abc","pSJJqa&TbyEb",[caseless])),
- <<"ABX">> = iolist_to_binary(re:replace("ABX","abc","pSJJqa&TbyEb",[caseless,
- global])),
- <<"ABCYSKriNcABCxqw">> = iolist_to_binary(re:replace("ABC","ab*c","&YSKriNc&xqw",[caseless])),
- <<"ABCYSKriNcABCxqw">> = iolist_to_binary(re:replace("ABC","ab*c","&YSKriNc&xqw",[caseless,
- global])),
- <<"">> = iolist_to_binary(re:replace("ABC","ab*bc","\\1",[caseless])),
- <<"">> = iolist_to_binary(re:replace("ABC","ab*bc","\\1",[caseless,
- global])),
- <<"xd">> = iolist_to_binary(re:replace("ABBC","ab*bc","xd",[caseless])),
- <<"xd">> = iolist_to_binary(re:replace("ABBC","ab*bc","xd",[caseless,
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab+bc","uD\\1trygh\\1FV&xf&I",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab+bc","uD\\1trygh\\1FV&xf&I",[caseless,
+ global])),
+ <<"ABC">> = iolist_to_binary(re:replace("ABC","ab+bc","&yTFr&\\1OfkVpLjJ",[caseless])),
+ <<"ABC">> = iolist_to_binary(re:replace("ABC","ab+bc","&yTFr&\\1OfkVpLjJ",[caseless,
+ global])),
+ <<"ABQ">> = iolist_to_binary(re:replace("ABQ","ab+bc","D\\1MfU\\1&",[caseless])),
+ <<"ABQ">> = iolist_to_binary(re:replace("ABQ","ab+bc","D\\1MfU\\1&",[caseless,
+ global])),
+ <<"jLBDBABBBBCVABBBBCCLPUeBABBBBCE">> = iolist_to_binary(re:replace("ABBBBC","ab+bc","jLBDB&V&CLPU\\1eB&E",[caseless])),
+ <<"jLBDBABBBBCVABBBBCCLPUeBABBBBCE">> = iolist_to_binary(re:replace("ABBBBC","ab+bc","jLBDB&V&CLPU\\1eB&E",[caseless,
+ global])),
+ <<"vXw">> = iolist_to_binary(re:replace("ABBBBC","ab{1,}?bc","vXw",[caseless])),
+ <<"vXw">> = iolist_to_binary(re:replace("ABBBBC","ab{1,}?bc","vXw",[caseless,
+ global])),
+ <<"DE">> = iolist_to_binary(re:replace("ABBBBC","ab{1,3}?bc","DE",[caseless])),
+ <<"DE">> = iolist_to_binary(re:replace("ABBBBC","ab{1,3}?bc","DE",[caseless,
+ global])),
+ <<"oIRAABBBBCABBBBCoXH">> = iolist_to_binary(re:replace("ABBBBC","ab{3,4}?bc","oIRA&&oXH",[caseless])),
+ <<"oIRAABBBBCABBBBCoXH">> = iolist_to_binary(re:replace("ABBBBC","ab{3,4}?bc","oIRA&&oXH",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{4,5}?bc","&&JUwgUCSBcHYmFv&OQ",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{4,5}?bc","&&JUwgUCSBcHYmFv&OQ",[caseless,
+ global])),
+ <<"ABQ">> = iolist_to_binary(re:replace("ABQ","ab{4,5}?bc","\\1&yu&\\1ps&A",[caseless])),
+ <<"ABQ">> = iolist_to_binary(re:replace("ABQ","ab{4,5}?bc","\\1&yu&\\1ps&A",[caseless,
+ global])),
+ <<"ABBBBC">> = iolist_to_binary(re:replace("ABBBBC","ab{4,5}?bc","TgOJWMyTNuK&rOFr\\1n",[caseless])),
+ <<"ABBBBC">> = iolist_to_binary(re:replace("ABBBBC","ab{4,5}?bc","TgOJWMyTNuK&rOFr\\1n",[caseless,
+ global])),
+ ok.
+run21() ->
+ <<"DxABBCYABBCEhABBCISWH">> = iolist_to_binary(re:replace("ABBC","ab??bc","Dx\\1&Y&E\\1h\\1&ISWH",[caseless])),
+ <<"DxABBCYABBCEhABBCISWH">> = iolist_to_binary(re:replace("ABBC","ab??bc","Dx\\1&Y&E\\1h\\1&ISWH",[caseless,
+ global])),
+ <<"Qw">> = iolist_to_binary(re:replace("ABC","ab??bc","Qw",[caseless])),
+ <<"Qw">> = iolist_to_binary(re:replace("ABC","ab??bc","Qw",[caseless,
global])),
- <<"fSNABBBBCXyDgO">> = iolist_to_binary(re:replace("ABBBBC","ab*?bc","fSN&\\1\\1XyDgO\\1",[caseless])),
- <<"fSNABBBBCXyDgO">> = iolist_to_binary(re:replace("ABBBBC","ab*?bc","fSN&\\1\\1XyDgO\\1",[caseless,
+ <<"O">> = iolist_to_binary(re:replace("ABC","ab{0,1}?bc","O",[caseless])),
+ <<"O">> = iolist_to_binary(re:replace("ABC","ab{0,1}?bc","O",[caseless,
+ global])),
+ <<"vABCwErLBABCFLQaOAoABCJPx">> = iolist_to_binary(re:replace("ABC","ab??c","v&wErLB\\1&FLQaOAo&JPx",[caseless])),
+ <<"vABCwErLBABCFLQaOAoABCJPx">> = iolist_to_binary(re:replace("ABC","ab??c","v&wErLB\\1&FLQaOAo&JPx",[caseless,
global])),
- <<"kp">> = iolist_to_binary(re:replace("ABBBBC","ab{0,}?bc","kp",[caseless])),
- <<"kp">> = iolist_to_binary(re:replace("ABBBBC","ab{0,}?bc","kp",[caseless,
- global])),
- <<"TjPcYlpdNDABBCAJoFsABBC">> = iolist_to_binary(re:replace("ABBC","ab+?bc","TjPcYlpdND\\1\\1&AJoFs&",[caseless])),
- <<"TjPcYlpdNDABBCAJoFsABBC">> = iolist_to_binary(re:replace("ABBC","ab+?bc","TjPcYlpdND\\1\\1&AJoFs&",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab+bc","WWQXKaM\\1xLF&",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab+bc","WWQXKaM\\1xLF&",[caseless,
- global])),
- <<"ABC">> = iolist_to_binary(re:replace("ABC","ab+bc","w",[caseless])),
- <<"ABC">> = iolist_to_binary(re:replace("ABC","ab+bc","w",[caseless,
- global])),
- <<"ABQ">> = iolist_to_binary(re:replace("ABQ","ab+bc","SYdD",[caseless])),
- <<"ABQ">> = iolist_to_binary(re:replace("ABQ","ab+bc","SYdD",[caseless,
- global])),
- <<"TABBBBC">> = iolist_to_binary(re:replace("ABBBBC","ab+bc","T&",[caseless])),
- <<"TABBBBC">> = iolist_to_binary(re:replace("ABBBBC","ab+bc","T&",[caseless,
- global])),
- <<"grMABBBBCABBBBCnRD">> = iolist_to_binary(re:replace("ABBBBC","ab{1,}?bc","grM&&nRD",[caseless])),
- <<"grMABBBBCABBBBCnRD">> = iolist_to_binary(re:replace("ABBBBC","ab{1,}?bc","grM&&nRD",[caseless,
+ <<"lphGtTIqlw">> = iolist_to_binary(re:replace("ABC","ab{0,1}?c","lph\\1GtTIqlw",[caseless])),
+ <<"lphGtTIqlw">> = iolist_to_binary(re:replace("ABC","ab{0,1}?c","lph\\1GtTIqlw",[caseless,
+ global])),
+ <<"Ubn">> = iolist_to_binary(re:replace("ABC","^abc$","Ubn",[caseless])),
+ <<"Ubn">> = iolist_to_binary(re:replace("ABC","^abc$","Ubn",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","&DcgWCx",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","&DcgWCx",[caseless,
global])),
- <<"JJtIBfABBBBCaKtYmqwv">> = iolist_to_binary(re:replace("ABBBBC","ab{1,3}?bc","\\1JJtIBf&\\1aKtYmqwv",[caseless])),
- <<"JJtIBfABBBBCaKtYmqwv">> = iolist_to_binary(re:replace("ABBBBC","ab{1,3}?bc","\\1JJtIBf&\\1aKtYmqwv",[caseless,
- global])),
- <<"gwAlxwDfABBBBCNQKABBBBClABBBBCLxf">> = iolist_to_binary(re:replace("ABBBBC","ab{3,4}?bc","gw\\1AlxwDf&NQK&l\\1&Lxf",[caseless])),
- <<"gwAlxwDfABBBBCNQKABBBBClABBBBCLxf">> = iolist_to_binary(re:replace("ABBBBC","ab{3,4}?bc","gw\\1AlxwDf&NQK&l\\1&Lxf",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{4,5}?bc","qiwoP\\1bmIlc\\1&",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","ab{4,5}?bc","qiwoP\\1bmIlc\\1&",[caseless,
- global])),
- <<"ABQ">> = iolist_to_binary(re:replace("ABQ","ab{4,5}?bc","aBG\\1YIvTYXxiuDt&",[caseless])),
- <<"ABQ">> = iolist_to_binary(re:replace("ABQ","ab{4,5}?bc","aBG\\1YIvTYXxiuDt&",[caseless,
+ <<"ABBBBC">> = iolist_to_binary(re:replace("ABBBBC","^abc$","H",[caseless])),
+ <<"ABBBBC">> = iolist_to_binary(re:replace("ABBBBC","^abc$","H",[caseless,
+ global])),
+ <<"ABCC">> = iolist_to_binary(re:replace("ABCC","^abc$","NmNp",[caseless])),
+ <<"ABCC">> = iolist_to_binary(re:replace("ABCC","^abc$","NmNp",[caseless,
+ global])),
+ <<"ABCABCSTBJNuWABCfUXC">> = iolist_to_binary(re:replace("ABCC","^abc","&&STBJNu\\1W\\1&fUX",[caseless])),
+ <<"ABCABCSTBJNuWABCfUXC">> = iolist_to_binary(re:replace("ABCC","^abc","&&STBJNu\\1W\\1&fUX",[caseless,
+ global])),
+ <<"Aotm">> = iolist_to_binary(re:replace("AABC","abc$","otm\\1",[caseless])),
+ <<"Aotm">> = iolist_to_binary(re:replace("AABC","abc$","otm\\1",[caseless,
+ global])),
+ <<"wnRBtWpABC">> = iolist_to_binary(re:replace("ABC","^","\\1wnR\\1Bt\\1Wp",[caseless])),
+ <<"wnRBtWpABC">> = iolist_to_binary(re:replace("ABC","^","\\1wnR\\1Bt\\1Wp",[caseless,
+ global])),
+ <<"ABCcfCNQPaSTn">> = iolist_to_binary(re:replace("ABC","$","\\1\\1\\1cfCNQPaST\\1n",[caseless])),
+ <<"ABCcfCNQPaSTn">> = iolist_to_binary(re:replace("ABC","$","\\1\\1\\1cfCNQPaST\\1n",[caseless,
+ global])),
+ <<"KqbIu">> = iolist_to_binary(re:replace("ABC","a.c","KqbIu\\1",[caseless])),
+ <<"KqbIu">> = iolist_to_binary(re:replace("ABC","a.c","KqbIu\\1",[caseless,
+ global])),
+ <<"mSBBDWnWtWlJVLdWWAXC">> = iolist_to_binary(re:replace("AXC","a.c","mSBBDWnWtWlJVLdWW\\1&\\1",[caseless])),
+ <<"mSBBDWnWtWlJVLdWWAXC">> = iolist_to_binary(re:replace("AXC","a.c","mSBBDWnWtWlJVLdWW\\1&\\1",[caseless,
+ global])),
+ <<"gIkgDqEBaPTmSAXYZC">> = iolist_to_binary(re:replace("AXYZC","a.*?c","gIkgDq\\1EBa\\1PTmS&",[caseless])),
+ <<"gIkgDqEBaPTmSAXYZC">> = iolist_to_binary(re:replace("AXYZC","a.*?c","gIkgDq\\1EBa\\1PTmS&",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a.*c","Sg&&rIwBxW&MAd",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a.*c","Sg&&rIwBxW&MAd",[caseless,
+ global])),
+ <<"IkVJFLsCAABCqbiO">> = iolist_to_binary(re:replace("AABC","a.*c","\\1\\1IkVJFLsC\\1&qbiO",[caseless])),
+ <<"IkVJFLsCAABCqbiO">> = iolist_to_binary(re:replace("AABC","a.*c","\\1\\1IkVJFLsC\\1&qbiO",[caseless,
global])),
- <<"ABBBBC">> = iolist_to_binary(re:replace("ABBBBC","ab{4,5}?bc","T\\1d&vifs\\1n\\1Jvt",[caseless])),
- <<"ABBBBC">> = iolist_to_binary(re:replace("ABBBBC","ab{4,5}?bc","T\\1d&vifs\\1n\\1Jvt",[caseless,
- global])),
- <<"MvyHLhAABBCiABBCN">> = iolist_to_binary(re:replace("ABBC","ab??bc","M\\1vyHLhA\\1&\\1i&N",[caseless])),
- <<"MvyHLhAABBCiABBCN">> = iolist_to_binary(re:replace("ABBC","ab??bc","M\\1vyHLhA\\1&\\1i&N",[caseless,
- global])),
- <<"mlLABCgtDiemoB">> = iolist_to_binary(re:replace("ABC","ab??bc","mlL&gtDiemoB",[caseless])),
- <<"mlLABCgtDiemoB">> = iolist_to_binary(re:replace("ABC","ab??bc","mlL&gtDiemoB",[caseless,
+ <<"AXYZD">> = iolist_to_binary(re:replace("AXYZD","a.*c","&r",[caseless])),
+ <<"AXYZD">> = iolist_to_binary(re:replace("AXYZD","a.*c","&r",[caseless,
+ global])),
+ <<"mABDJFh">> = iolist_to_binary(re:replace("ABD","a[bc]d","m&J\\1\\1Fh",[caseless])),
+ <<"mABDJFh">> = iolist_to_binary(re:replace("ABD","a[bc]d","m&J\\1\\1Fh",[caseless,
+ global])),
+ <<"ysVqaiqxHWEb">> = iolist_to_binary(re:replace("ACE","a[b-d]e","ys\\1\\1Vqai\\1qx\\1HWEb",[caseless])),
+ <<"ysVqaiqxHWEb">> = iolist_to_binary(re:replace("ACE","a[b-d]e","ys\\1\\1Vqai\\1qx\\1HWEb",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[b-d]e","\\1eIyFD\\1",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[b-d]e","\\1eIyFD\\1",[caseless,
+ global])),
+ <<"ABC">> = iolist_to_binary(re:replace("ABC","a[b-d]e","UU&&GPw&AHE",[caseless])),
+ <<"ABC">> = iolist_to_binary(re:replace("ABC","a[b-d]e","UU&&GPw&AHE",[caseless,
+ global])),
+ <<"ABD">> = iolist_to_binary(re:replace("ABD","a[b-d]e","SKAyypUXUE\\1IHTdcqv&r",[caseless])),
+ <<"ABD">> = iolist_to_binary(re:replace("ABD","a[b-d]e","SKAyypUXUE\\1IHTdcqv&r",[caseless,
+ global])),
+ <<"AqACkKluACPPACf">> = iolist_to_binary(re:replace("AAC","a[b-d]","q&kKlu&PP&f",[caseless])),
+ <<"AqACkKluACPPACf">> = iolist_to_binary(re:replace("AAC","a[b-d]","q&kKlu&PP&f",[caseless,
global])),
+ <<"A-Wnm">> = iolist_to_binary(re:replace("A-","a[-b]","&Wnm",[caseless])),
+ <<"A-Wnm">> = iolist_to_binary(re:replace("A-","a[-b]","&Wnm",[caseless,
+ global])),
+ <<"paPAAKruyA-Wwd">> = iolist_to_binary(re:replace("A-","a[b-]","paPAAKruy&Wwd",[caseless])),
+ <<"paPAAKruyA-Wwd">> = iolist_to_binary(re:replace("A-","a[b-]","paPAAKruy&Wwd",[caseless,
+ global])),
+ <<"ImJu">> = iolist_to_binary(re:replace("A]","a]","I\\1m\\1Ju",[caseless])),
+ <<"ImJu">> = iolist_to_binary(re:replace("A]","a]","I\\1m\\1Ju",[caseless,
+ global])),
ok.
-run21() ->
- <<"aMKJBABCqBQrABCWvqqJABCVi">> = iolist_to_binary(re:replace("ABC","ab{0,1}?bc","aMKJB&qBQr&WvqqJ&Vi",[caseless])),
- <<"aMKJBABCqBQrABCWvqqJABCVi">> = iolist_to_binary(re:replace("ABC","ab{0,1}?bc","aMKJB&qBQr&WvqqJ&Vi",[caseless,
- global])),
- <<"KABCqKjWXyABC">> = iolist_to_binary(re:replace("ABC","ab??c","K\\1&qKjWXy\\1&",[caseless])),
- <<"KABCqKjWXyABC">> = iolist_to_binary(re:replace("ABC","ab??c","K\\1&qKjWXy\\1&",[caseless,
- global])),
- <<"t">> = iolist_to_binary(re:replace("ABC","ab{0,1}?c","t",[caseless])),
- <<"t">> = iolist_to_binary(re:replace("ABC","ab{0,1}?c","t",[caseless,
- global])),
- <<"djnySdABCABCxQAR">> = iolist_to_binary(re:replace("ABC","^abc$","djnyS\\1d&&\\1\\1x\\1QAR",[caseless])),
- <<"djnySdABCABCxQAR">> = iolist_to_binary(re:replace("ABC","^abc$","djnyS\\1d&&\\1\\1x\\1QAR",[caseless,
+run22() ->
+ <<"kdsETioUcshOFDldx">> = iolist_to_binary(re:replace("A]B","a[]]b","k\\1dsET\\1ioU\\1cshOFDldx",[caseless])),
+ <<"kdsETioUcshOFDldx">> = iolist_to_binary(re:replace("A]B","a[]]b","k\\1dsET\\1ioU\\1cshOFDldx",[caseless,
global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","&cOwCIe",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^abc$","&cOwCIe",[caseless,
- global])),
- <<"ABBBBC">> = iolist_to_binary(re:replace("ABBBBC","^abc$","DTRA&tGT\\1WCjF\\1\\1",[caseless])),
- <<"ABBBBC">> = iolist_to_binary(re:replace("ABBBBC","^abc$","DTRA&tGT\\1WCjF\\1\\1",[caseless,
- global])),
- <<"ABCC">> = iolist_to_binary(re:replace("ABCC","^abc$","YC\\1",[caseless])),
- <<"ABCC">> = iolist_to_binary(re:replace("ABCC","^abc$","YC\\1",[caseless,
- global])),
- <<"oCxwvYlagrHYCUNjC">> = iolist_to_binary(re:replace("ABCC","^abc","oC\\1xwvYlagrHYCUN\\1j",[caseless])),
- <<"oCxwvYlagrHYCUNjC">> = iolist_to_binary(re:replace("ABCC","^abc","oC\\1xwvYlagrHYCUN\\1j",[caseless,
- global])),
- <<"AABCYOABCqABCABCXABCKHJVXnu">> = iolist_to_binary(re:replace("AABC","abc$","&YO&q&&X&\\1KHJVXnu",[caseless])),
- <<"AABCYOABCqABCABCXABCKHJVXnu">> = iolist_to_binary(re:replace("AABC","abc$","&YO&q&&X&\\1KHJVXnu",[caseless,
+ <<"uv">> = iolist_to_binary(re:replace("AED","a[^bc]d","uv\\1",[caseless])),
+ <<"uv">> = iolist_to_binary(re:replace("AED","a[^bc]d","uv\\1",[caseless,
+ global])),
+ <<"l">> = iolist_to_binary(re:replace("ADC","a[^-b]c","l",[caseless])),
+ <<"l">> = iolist_to_binary(re:replace("ADC","a[^-b]c","l",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^-b]c","vyfP\\1yX\\1onrR&f\\1\\1J&",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^-b]c","vyfP\\1yX\\1onrR&f\\1\\1J&",[caseless,
+ global])),
+ <<"ABD">> = iolist_to_binary(re:replace("ABD","a[^-b]c","gE&RxnGk&&\\1\\1mK",[caseless])),
+ <<"ABD">> = iolist_to_binary(re:replace("ABD","a[^-b]c","gE&RxnGk&&\\1\\1mK",[caseless,
global])),
- <<"YKSscFvdcxhKQAABC">> = iolist_to_binary(re:replace("ABC","^","YKSscFvdcx\\1hKQA\\1",[caseless])),
- <<"YKSscFvdcxhKQAABC">> = iolist_to_binary(re:replace("ABC","^","YKSscFvdcx\\1hKQA\\1",[caseless,
+ <<"A-C">> = iolist_to_binary(re:replace("A-C","a[^-b]c","xJw&DKvLJC",[caseless])),
+ <<"A-C">> = iolist_to_binary(re:replace("A-C","a[^-b]c","xJw&DKvLJC",[caseless,
+ global])),
+ <<"gm">> = iolist_to_binary(re:replace("ADC","a[^]b]c","gm",[caseless])),
+ <<"gm">> = iolist_to_binary(re:replace("ADC","a[^]b]c","gm",[caseless,
+ global])),
+ <<"RrLABABABUVLUehwC">> = iolist_to_binary(re:replace("ABC","ab|cd","RrL\\1&&&UVLUehw",[caseless])),
+ <<"RrLABABABUVLUehwC">> = iolist_to_binary(re:replace("ABC","ab|cd","RrL\\1&&&UVLUehw",[caseless,
+ global])),
+ <<"giABOABABqXGgxFhABdprogCD">> = iolist_to_binary(re:replace("ABCD","ab|cd","gi&O&&qXGgxFh&dprog",[caseless])),
+ <<"giABOABABqXGgxFhABdproggiCDOCDCDqXGgxFhCDdprog">> = iolist_to_binary(re:replace("ABCD","ab|cd","gi&O&&qXGgxFh&dprog",[caseless,
+ global])),
+ <<"DqEFRtXCOkEFdCHWAxqmEF">> = iolist_to_binary(re:replace("DEF","()ef","q&Rt\\1XCOk&dCHWAxqm&",[caseless])),
+ <<"DqEFRtXCOkEFdCHWAxqmEF">> = iolist_to_binary(re:replace("DEF","()ef","q&Rt\\1XCOk&dCHWAxqm&",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","$b","e&y",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","$b","e&y",[caseless,
+ global])),
+ <<"A]C">> = iolist_to_binary(re:replace("A]C","$b","Mu&NYopF&e\\1u",[caseless])),
+ <<"A]C">> = iolist_to_binary(re:replace("A]C","$b","Mu&NYopF&e\\1u",[caseless,
+ global])),
+ <<"B">> = iolist_to_binary(re:replace("B","$b","PgdiGyTFyntpg\\1",[caseless])),
+ <<"B">> = iolist_to_binary(re:replace("B","$b","PgdiGyTFyntpg\\1",[caseless,
+ global])),
+ <<"h">> = iolist_to_binary(re:replace("A(B","a\\(b","h",[caseless])),
+ <<"h">> = iolist_to_binary(re:replace("A(B","a\\(b","h",[caseless,
+ global])),
+ <<"UwxbpwNvAsyQI">> = iolist_to_binary(re:replace("AB","a\\(*b","\\1UwxbpwNvAsyQI",[caseless])),
+ <<"UwxbpwNvAsyQI">> = iolist_to_binary(re:replace("AB","a\\(*b","\\1UwxbpwNvAsyQI",[caseless,
global])),
- <<"ABCJPmJKxRqaJn">> = iolist_to_binary(re:replace("ABC","$","JPmJ&K\\1\\1x\\1RqaJ\\1n",[caseless])),
- <<"ABCJPmJKxRqaJn">> = iolist_to_binary(re:replace("ABC","$","JPmJ&K\\1\\1x\\1RqaJ\\1n",[caseless,
+ <<"M">> = iolist_to_binary(re:replace("A((B","a\\(*b","M",[caseless])),
+ <<"M">> = iolist_to_binary(re:replace("A((B","a\\(*b","M",[caseless,
+ global])),
+ <<"A">> = iolist_to_binary(re:replace("A","a\\\\b","h&t",[caseless,
+ notbol])),
+ <<"A">> = iolist_to_binary(re:replace("A","a\\\\b","h&t",[caseless,
+ notbol,
+ global])),
+ <<"vMPmAAlHguqIoSmcuudIBC">> = iolist_to_binary(re:replace("ABC","((a))","vMPm\\1&lHguqIoSmcuudI",[caseless])),
+ <<"vMPmAAlHguqIoSmcuudIBC">> = iolist_to_binary(re:replace("ABC","((a))","vMPm\\1&lHguqIoSmcuudI",[caseless,
global])),
- <<"KovmYABCBPABCY">> = iolist_to_binary(re:replace("ABC","a.c","KovmY&BP&Y",[caseless])),
- <<"KovmYABCBPABCY">> = iolist_to_binary(re:replace("ABC","a.c","KovmY&BP&Y",[caseless,
- global])),
- <<"tnMtqk">> = iolist_to_binary(re:replace("AXC","a.c","t\\1\\1n\\1Mtqk",[caseless])),
- <<"tnMtqk">> = iolist_to_binary(re:replace("AXC","a.c","t\\1\\1n\\1Mtqk",[caseless,
- global])),
- <<"PTEd">> = iolist_to_binary(re:replace("AXYZC","a.*?c","PTEd",[caseless])),
- <<"PTEd">> = iolist_to_binary(re:replace("AXYZC","a.*?c","PTEd",[caseless,
+ <<"RhLw">> = iolist_to_binary(re:replace("ABC","(a)b(c)","RhLw",[caseless])),
+ <<"RhLw">> = iolist_to_binary(re:replace("ABC","(a)b(c)","RhLw",[caseless,
global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a.*c","\\1XFiq\\1uvPbLR",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a.*c","\\1XFiq\\1uvPbLR",[caseless,
- global])),
- <<"cqlTAABCy">> = iolist_to_binary(re:replace("AABC","a.*c","cqlT&\\1y",[caseless])),
- <<"cqlTAABCy">> = iolist_to_binary(re:replace("AABC","a.*c","cqlT&\\1y",[caseless,
- global])),
- <<"AXYZD">> = iolist_to_binary(re:replace("AXYZD","a.*c","nHl&b\\1Xh",[caseless])),
- <<"AXYZD">> = iolist_to_binary(re:replace("AXYZD","a.*c","nHl&b\\1Xh",[caseless,
- global])),
- <<"ABDABDdC">> = iolist_to_binary(re:replace("ABD","a[bc]d","&&dC",[caseless])),
- <<"ABDABDdC">> = iolist_to_binary(re:replace("ABD","a[bc]d","&&dC",[caseless,
- global])),
- <<"UqQFWlGkACEBdlidOCI">> = iolist_to_binary(re:replace("ACE","a[b-d]e","UqQF\\1WlGk&BdlidOCI\\1",[caseless])),
- <<"UqQFWlGkACEBdlidOCI">> = iolist_to_binary(re:replace("ACE","a[b-d]e","UqQF\\1WlGk&BdlidOCI\\1",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[b-d]e","UKuM",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[b-d]e","UKuM",[caseless,
- global])),
- <<"ABC">> = iolist_to_binary(re:replace("ABC","a[b-d]e","W",[caseless])),
- <<"ABC">> = iolist_to_binary(re:replace("ABC","a[b-d]e","W",[caseless,
- global])),
- <<"ABD">> = iolist_to_binary(re:replace("ABD","a[b-d]e","HF",[caseless])),
- <<"ABD">> = iolist_to_binary(re:replace("ABD","a[b-d]e","HF",[caseless,
- global])),
- <<"AFX">> = iolist_to_binary(re:replace("AAC","a[b-d]","FX",[caseless])),
- <<"AFX">> = iolist_to_binary(re:replace("AAC","a[b-d]","FX",[caseless,
- global])),
- <<"aWjCeJjBuA-eA-wLdnI">> = iolist_to_binary(re:replace("A-","a[-b]","aWjCeJj\\1Bu&e&wLdnI",[caseless])),
- <<"aWjCeJjBuA-eA-wLdnI">> = iolist_to_binary(re:replace("A-","a[-b]","aWjCeJj\\1Bu&e&wLdnI",[caseless,
- global])),
- <<"vEBoA-A-hhUA-oyIbqdTA">> = iolist_to_binary(re:replace("A-","a[b-]","vEBo&&hhU&oyIbq\\1d\\1TA",[caseless])),
- <<"vEBoA-A-hhUA-oyIbqdTA">> = iolist_to_binary(re:replace("A-","a[b-]","vEBo&&hhU&oyIbq\\1d\\1TA",[caseless,
- global])),
- <<"lxsWAAwljA]">> = iolist_to_binary(re:replace("A]","a]","lxsW\\1AAwlj&",[caseless])),
- <<"lxsWAAwljA]">> = iolist_to_binary(re:replace("A]","a]","lxsW\\1AAwlj&",[caseless,
- global])),
- <<"A]BBA]BwueRHPvA]BFaS">> = iolist_to_binary(re:replace("A]B","a[]]b","&B&\\1wueRHPv&FaS",[caseless])),
- <<"A]BBA]BwueRHPvA]BFaS">> = iolist_to_binary(re:replace("A]B","a[]]b","&B&\\1wueRHPv&FaS",[caseless,
- global])),
- ok.
-run22() ->
- <<"UTPAEDUuRpFvTKUIXNAEDH">> = iolist_to_binary(re:replace("AED","a[^bc]d","U\\1TP&UuRpFvTKUIXN&H",[caseless])),
- <<"UTPAEDUuRpFvTKUIXNAEDH">> = iolist_to_binary(re:replace("AED","a[^bc]d","U\\1TP&UuRpFvTKUIXN&H",[caseless,
- global])),
- <<"EEkBKqX">> = iolist_to_binary(re:replace("ADC","a[^-b]c","EEk\\1BKqX",[caseless])),
- <<"EEkBKqX">> = iolist_to_binary(re:replace("ADC","a[^-b]c","EEk\\1BKqX",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^-b]c","W&hcyn\\1LTFcrP",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a[^-b]c","W&hcyn\\1LTFcrP",[caseless,
+ <<"AABBABCJqvleABCABCoABCmABCFUTm">> = iolist_to_binary(re:replace("AABBABC","a+b+c","&Jqvle\\1&&o&m&FUTm",[caseless])),
+ <<"AABBABCJqvleABCABCoABCmABCFUTm">> = iolist_to_binary(re:replace("AABBABC","a+b+c","&Jqvle\\1&&o&m&FUTm",[caseless,
global])),
- <<"ABD">> = iolist_to_binary(re:replace("ABD","a[^-b]c","l&hDcBVR&&P\\1HyoS&",[caseless])),
- <<"ABD">> = iolist_to_binary(re:replace("ABD","a[^-b]c","l&hDcBVR&&P\\1HyoS&",[caseless,
- global])),
- <<"A-C">> = iolist_to_binary(re:replace("A-C","a[^-b]c","r&\\1",[caseless])),
- <<"A-C">> = iolist_to_binary(re:replace("A-C","a[^-b]c","r&\\1",[caseless,
- global])),
- <<"wsKsChmsBbyoCwJGFq">> = iolist_to_binary(re:replace("ADC","a[^]b]c","wsKsChm\\1sB\\1byoCwJGFq",[caseless])),
- <<"wsKsChmsBbyoCwJGFq">> = iolist_to_binary(re:replace("ADC","a[^]b]c","wsKsChm\\1sB\\1byoCwJGFq",[caseless,
- global])),
- <<"AdCuC">> = iolist_to_binary(re:replace("ABC","ab|cd","AdCu",[caseless])),
- <<"AdCuC">> = iolist_to_binary(re:replace("ABC","ab|cd","AdCu",[caseless,
+ <<"AABBac">> = iolist_to_binary(re:replace("AABBABC","a{1,}b{1,}c","ac",[caseless])),
+ <<"AABBac">> = iolist_to_binary(re:replace("AABBABC","a{1,}b{1,}c","ac",[caseless,
+ global])),
+ <<"OABC">> = iolist_to_binary(re:replace("ABCABC","a.+?c","O",[caseless])),
+ <<"OO">> = iolist_to_binary(re:replace("ABCABC","a.+?c","O",[caseless,
global])),
- <<"kPjHRmkRWABOFqNCD">> = iolist_to_binary(re:replace("ABCD","ab|cd","kPjHRm\\1k\\1RW&OFqN",[caseless])),
- <<"kPjHRmkRWABOFqNkPjHRmkRWCDOFqN">> = iolist_to_binary(re:replace("ABCD","ab|cd","kPjHRm\\1k\\1RW&OFqN",[caseless,
+ <<"scmlABC">> = iolist_to_binary(re:replace("ABCABC","a.*?c","scml",[caseless])),
+ <<"scmlscml">> = iolist_to_binary(re:replace("ABCABC","a.*?c","scml",[caseless,
+ global])),
+ <<"lPmBjogUPNEABC">> = iolist_to_binary(re:replace("ABCABC","a.{0,5}?c","lPmB\\1jogUPNE\\1",[caseless])),
+ <<"lPmBjogUPNElPmBjogUPNE">> = iolist_to_binary(re:replace("ABCABC","a.{0,5}?c","lPmB\\1jogUPNE\\1",[caseless,
+ global])),
+ <<"lytYeABWABABFmABccWBV">> = iolist_to_binary(re:replace("AB","(a+|b)*","lytYe&W&&Fm&ccW\\1V",[caseless])),
+ <<"lytYeABWABABFmABccWBVlytYeWFmccWV">> = iolist_to_binary(re:replace("AB","(a+|b)*","lytYe&W&&Fm&ccW\\1V",[caseless,
global])),
- <<"DipEFEFNEFXjXNBJMTG">> = iolist_to_binary(re:replace("DEF","()ef","ip&&N&XjXNBJMTG\\1",[caseless])),
- <<"DipEFEFNEFXjXNBJMTG">> = iolist_to_binary(re:replace("DEF","()ef","ip&&N&XjXNBJMTG\\1",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","$b","jl",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","$b","jl",[caseless,
- global])),
- <<"A]C">> = iolist_to_binary(re:replace("A]C","$b","Ghx\\1\\1nMcXP&D\\1hXTKGqJ",[caseless])),
- <<"A]C">> = iolist_to_binary(re:replace("A]C","$b","Ghx\\1\\1nMcXP&D\\1hXTKGqJ",[caseless,
- global])),
- <<"B">> = iolist_to_binary(re:replace("B","$b","&CU&s",[caseless])),
- <<"B">> = iolist_to_binary(re:replace("B","$b","&CU&s",[caseless,
- global])),
- <<"q">> = iolist_to_binary(re:replace("A(B","a\\(b","q",[caseless])),
- <<"q">> = iolist_to_binary(re:replace("A(B","a\\(b","q",[caseless,
- global])),
- <<"LbAKAddxuaGFABjds">> = iolist_to_binary(re:replace("AB","a\\(*b","LbAKAddx\\1\\1uaGF&jd\\1s",[caseless])),
- <<"LbAKAddxuaGFABjds">> = iolist_to_binary(re:replace("AB","a\\(*b","LbAKAddx\\1\\1uaGF&jd\\1s",[caseless,
- global])),
- <<"WcHNHA((BeLNHyhL">> = iolist_to_binary(re:replace("A((B","a\\(*b","WcH\\1\\1\\1NH&\\1\\1eLNHy\\1hL",[caseless])),
- <<"WcHNHA((BeLNHyhL">> = iolist_to_binary(re:replace("A((B","a\\(*b","WcH\\1\\1\\1NH&\\1\\1eLNHy\\1hL",[caseless,
- global])),
- <<"A">> = iolist_to_binary(re:replace("A","a\\\\b","FD\\1dW",[caseless,
- notbol])),
- <<"A">> = iolist_to_binary(re:replace("A","a\\\\b","FD\\1dW",[caseless,
- notbol,
- global])),
- <<"AojAgACCaWeAfuBC">> = iolist_to_binary(re:replace("ABC","((a))","\\1oj&g\\1CCaWe\\1fu",[caseless])),
- <<"AojAgACCaWeAfuBC">> = iolist_to_binary(re:replace("ABC","((a))","\\1oj&g\\1CCaWe\\1fu",[caseless,
- global])),
- <<"xSJDAQoInQAfBNwlABCJAO">> = iolist_to_binary(re:replace("ABC","(a)b(c)","xSJD\\1QoInQ\\1fBNwl&J\\1O",[caseless])),
- <<"xSJDAQoInQAfBNwlABCJAO">> = iolist_to_binary(re:replace("ABC","(a)b(c)","xSJD\\1QoInQ\\1fBNwl&J\\1O",[caseless,
- global])),
- <<"AABBABCWpU">> = iolist_to_binary(re:replace("AABBABC","a+b+c","&W\\1pU",[caseless])),
- <<"AABBABCWpU">> = iolist_to_binary(re:replace("AABBABC","a+b+c","&W\\1pU",[caseless,
+ <<"BBq">> = iolist_to_binary(re:replace("AB","(a+|b){0,}","\\1\\1q",[caseless])),
+ <<"BBqq">> = iolist_to_binary(re:replace("AB","(a+|b){0,}","\\1\\1q",[caseless,
global])),
- <<"AABBvuHyJYABClhsNABCABC">> = iolist_to_binary(re:replace("AABBABC","a{1,}b{1,}c","vuHyJY&lhsN&&",[caseless])),
- <<"AABBvuHyJYABClhsNABCABC">> = iolist_to_binary(re:replace("AABBABC","a{1,}b{1,}c","vuHyJY&lhsN&&",[caseless,
- global])),
- <<"PuUbOABC">> = iolist_to_binary(re:replace("ABCABC","a.+?c","Pu\\1UbO",[caseless])),
- <<"PuUbOPuUbO">> = iolist_to_binary(re:replace("ABCABC","a.+?c","Pu\\1UbO",[caseless,
- global])),
- <<"FGYfABCDdRACwIXABC">> = iolist_to_binary(re:replace("ABCABC","a.*?c","FGYf&DdRA\\1C\\1\\1wIX",[caseless])),
- <<"FGYfABCDdRACwIXFGYfABCDdRACwIX">> = iolist_to_binary(re:replace("ABCABC","a.*?c","FGYf&DdRA\\1C\\1\\1wIX",[caseless,
- global])),
- <<"hfyssBtPoqABC">> = iolist_to_binary(re:replace("ABCABC","a.{0,5}?c","\\1hfyssBt\\1Poq",[caseless])),
- <<"hfyssBtPoqhfyssBtPoq">> = iolist_to_binary(re:replace("ABCABC","a.{0,5}?c","\\1hfyssBt\\1Poq",[caseless,
- global])),
- <<"aoHgobCXYeRwABSXtABB">> = iolist_to_binary(re:replace("AB","(a+|b)*","aoHgobCXYeRw&SXt&\\1",[caseless])),
- <<"aoHgobCXYeRwABSXtABBaoHgobCXYeRwSXt">> = iolist_to_binary(re:replace("AB","(a+|b)*","aoHgobCXYeRw&SXt&\\1",[caseless,
- global])),
- <<"LYWAHKusKAgrXKh">> = iolist_to_binary(re:replace("AB","(a+|b){0,}","LYWAHKusKAgrXKh",[caseless])),
- <<"LYWAHKusKAgrXKhLYWAHKusKAgrXKh">> = iolist_to_binary(re:replace("AB","(a+|b){0,}","LYWAHKusKAgrXKh",[caseless,
- global])),
- <<"UVXSWR">> = iolist_to_binary(re:replace("AB","(a+|b)+","UVXSWR",[caseless])),
- <<"UVXSWR">> = iolist_to_binary(re:replace("AB","(a+|b)+","UVXSWR",[caseless,
- global])),
- <<"lXCwBqLtjKMQjABBokVR">> = iolist_to_binary(re:replace("AB","(a+|b){1,}","lXCw\\1qLtjKMQj&\\1okVR",[caseless])),
- <<"lXCwBqLtjKMQjABBokVR">> = iolist_to_binary(re:replace("AB","(a+|b){1,}","lXCw\\1qLtjKMQj&\\1okVR",[caseless,
+ <<"xBPvBwqaXlIBysBBNnQs">> = iolist_to_binary(re:replace("AB","(a+|b)+","x\\1Pv\\1wqaXlIBys\\1BNnQs",[caseless])),
+ <<"xBPvBwqaXlIBysBBNnQs">> = iolist_to_binary(re:replace("AB","(a+|b)+","x\\1Pv\\1wqaXlIBys\\1BNnQs",[caseless,
global])),
ok.
run23() ->
- <<"MAFkB">> = iolist_to_binary(re:replace("AB","(a+|b)?","M\\1Fk",[caseless])),
- <<"MAFkMBFkMFk">> = iolist_to_binary(re:replace("AB","(a+|b)?","M\\1Fk",[caseless,
+ <<"vJrBABXpcvqi">> = iolist_to_binary(re:replace("AB","(a+|b){1,}","vJr\\1&Xpcvqi",[caseless])),
+ <<"vJrBABXpcvqi">> = iolist_to_binary(re:replace("AB","(a+|b){1,}","vJr\\1&Xpcvqi",[caseless,
+ global])),
+ <<"hAKhhwB">> = iolist_to_binary(re:replace("AB","(a+|b)?","h&Khhw",[caseless])),
+ <<"hAKhhwhBKhhwhKhhw">> = iolist_to_binary(re:replace("AB","(a+|b)?","h&Khhw",[caseless,
global])),
- <<"STYCeRAuyArB">> = iolist_to_binary(re:replace("AB","(a+|b){0,1}","STYCeR\\1uy\\1r",[caseless])),
- <<"STYCeRAuyArSTYCeRBuyBrSTYCeRuyr">> = iolist_to_binary(re:replace("AB","(a+|b){0,1}","STYCeR\\1uy\\1r",[caseless,
- global])),
- <<"WBHxgnNQAB">> = iolist_to_binary(re:replace("AB","(a+|b){0,1}?","W&BH\\1&\\1x&gnNQ",[caseless])),
- <<"WBHxgnNQWABHAAAxAgnNQWBHxgnNQWBBHBBBxBgnNQWBHxgnNQ">> = iolist_to_binary(re:replace("AB","(a+|b){0,1}?","W&BH\\1&\\1x&gnNQ",[caseless,
- global])),
- <<"MbLbSWbCDEggiClWfEM">> = iolist_to_binary(re:replace("CDE","[^ab]*","MbLbSWb&ggiClWfEM",[caseless])),
- <<"MbLbSWbCDEggiClWfEMMbLbSWbggiClWfEM">> = iolist_to_binary(re:replace("CDE","[^ab]*","MbLbSWb&ggiClWfEM",[caseless,
- global])),
- <<"rjABBBCDfICJABBBCDABBBCDEjJ">> = iolist_to_binary(re:replace("ABBBCD","([abc])*d","rj&fICJ&&EjJ",[caseless])),
- <<"rjABBBCDfICJABBBCDABBBCDEjJ">> = iolist_to_binary(re:replace("ABBBCD","([abc])*d","rj&fICJ&&EjJ",[caseless,
- global])),
- <<"xQ">> = iolist_to_binary(re:replace("ABCD","([abc])*bcd","xQ",[caseless])),
- <<"xQ">> = iolist_to_binary(re:replace("ABCD","([abc])*bcd","xQ",[caseless,
- global])),
- <<"AllmaUiAaKG">> = iolist_to_binary(re:replace("E","a|b|c|d|e","AllmaUiAa\\1KG",[caseless])),
- <<"AllmaUiAaKG">> = iolist_to_binary(re:replace("E","a|b|c|d|e","AllmaUiAa\\1KG",[caseless,
- global])),
- <<"QdfE">> = iolist_to_binary(re:replace("EF","(a|b|c|d|e)f","Qdf\\1",[caseless])),
- <<"QdfE">> = iolist_to_binary(re:replace("EF","(a|b|c|d|e)f","Qdf\\1",[caseless,
- global])),
- <<"ABCDEFGTvQSeJABCDEFGWMXdIOTh">> = iolist_to_binary(re:replace("ABCDEFG","abcd*efg","\\1&TvQSeJ&\\1WMXdIO\\1Th",[caseless])),
- <<"ABCDEFGTvQSeJABCDEFGWMXdIOTh">> = iolist_to_binary(re:replace("ABCDEFG","abcd*efg","\\1&TvQSeJ&\\1WMXdIO\\1Th",[caseless,
- global])),
- <<"XlSgABJHbKHRjUuNjOrYABBBZ">> = iolist_to_binary(re:replace("XABYABBBZ","ab*","lSg&JHbKHRjUuNjOr",[caseless])),
- <<"XlSgABJHbKHRjUuNjOrYlSgABBBJHbKHRjUuNjOrZ">> = iolist_to_binary(re:replace("XABYABBBZ","ab*","lSg&JHbKHRjUuNjOr",[caseless,
- global])),
- <<"XNjAAesIAgAYABBBZ">> = iolist_to_binary(re:replace("XAYABBBZ","ab*","Nj&&esI&g&",[caseless])),
- <<"XNjAAesIAgAYNjABBBABBBesIABBBgABBBZ">> = iolist_to_binary(re:replace("XAYABBBZ","ab*","Nj&&esI&g&",[caseless,
+ <<"rfOTAksYhKEDAAKAoWuB">> = iolist_to_binary(re:replace("AB","(a+|b){0,1}","rfOT\\1ksYhKED&&K\\1oWu",[caseless])),
+ <<"rfOTAksYhKEDAAKAoWurfOTBksYhKEDBBKBoWurfOTksYhKEDKoWu">> = iolist_to_binary(re:replace("AB","(a+|b){0,1}","rfOT\\1ksYhKED&&K\\1oWu",[caseless,
+ global])),
+ <<"MGbpmvAB">> = iolist_to_binary(re:replace("AB","(a+|b){0,1}?","\\1MGbpmv",[caseless])),
+ <<"MGbpmvAMGbpmvMGbpmvBMGbpmvMGbpmv">> = iolist_to_binary(re:replace("AB","(a+|b){0,1}?","\\1MGbpmv",[caseless,
+ global])),
+ <<"udAFEstNiUeKkd">> = iolist_to_binary(re:replace("CDE","[^ab]*","udAFEstNiUeKkd",[caseless])),
+ <<"udAFEstNiUeKkdudAFEstNiUeKkd">> = iolist_to_binary(re:replace("CDE","[^ab]*","udAFEstNiUeKkd",[caseless,
global])),
- <<"ABpvCDEayXCDEDCDSCDECDEwh">> = iolist_to_binary(re:replace("ABCDE","(ab|cd)e","pv&ayX&D\\1S&&wh",[caseless])),
- <<"ABpvCDEayXCDEDCDSCDECDEwh">> = iolist_to_binary(re:replace("ABCDE","(ab|cd)e","pv&ayX&D\\1S&&wh",[caseless,
- global])),
- <<"HIJAJ">> = iolist_to_binary(re:replace("HIJ","[abhgefdc]ij","&A\\1J\\1",[caseless])),
- <<"HIJAJ">> = iolist_to_binary(re:replace("HIJ","[abhgefdc]ij","&A\\1J\\1",[caseless,
+ <<"ABBBCDvDABBBCDABBBCDGllMCdwv">> = iolist_to_binary(re:replace("ABBBCD","([abc])*d","&vD&&GllMCdwv",[caseless])),
+ <<"ABBBCDvDABBBCDABBBCDGllMCdwv">> = iolist_to_binary(re:replace("ABBBCD","([abc])*d","&vD&&GllMCdwv",[caseless,
+ global])),
+ <<"SAABCDbA">> = iolist_to_binary(re:replace("ABCD","([abc])*bcd","S\\1&b\\1",[caseless])),
+ <<"SAABCDbA">> = iolist_to_binary(re:replace("ABCD","([abc])*bcd","S\\1&b\\1",[caseless,
global])),
- <<"ABCDE">> = iolist_to_binary(re:replace("ABCDE","^(ab|cd)e","y&gKEPudO&f\\1Vf",[caseless])),
- <<"ABCDE">> = iolist_to_binary(re:replace("ABCDE","^(ab|cd)e","y&gKEPudO&f\\1Vf",[caseless,
- global])),
- <<"ABCDsEFmkoWgwo">> = iolist_to_binary(re:replace("ABCDEF","(abc|)ef","s&mkoWgwo",[caseless])),
- <<"ABCDsEFmkoWgwo">> = iolist_to_binary(re:replace("ABCDEF","(abc|)ef","s&mkoWgwo",[caseless,
+ <<"COkGEqEpREwm">> = iolist_to_binary(re:replace("E","a|b|c|d|e","COkG&q&pR&wm\\1",[caseless])),
+ <<"COkGEqEpREwm">> = iolist_to_binary(re:replace("E","a|b|c|d|e","COkG&q&pR&wm\\1",[caseless,
+ global])),
+ <<"EFEYUF">> = iolist_to_binary(re:replace("EF","(a|b|c|d|e)f","&\\1YUF",[caseless])),
+ <<"EFEYUF">> = iolist_to_binary(re:replace("EF","(a|b|c|d|e)f","&\\1YUF",[caseless,
+ global])),
+ <<"keABCDEFGn">> = iolist_to_binary(re:replace("ABCDEFG","abcd*efg","\\1ke&n",[caseless])),
+ <<"keABCDEFGn">> = iolist_to_binary(re:replace("ABCDEFG","abcd*efg","\\1ke&n",[caseless,
+ global])),
+ <<"XTpYABBBZ">> = iolist_to_binary(re:replace("XABYABBBZ","ab*","Tp",[caseless])),
+ <<"XTpYTpZ">> = iolist_to_binary(re:replace("XABYABBBZ","ab*","Tp",[caseless,
+ global])),
+ <<"XcWRYABBBZ">> = iolist_to_binary(re:replace("XAYABBBZ","ab*","cWR\\1",[caseless])),
+ <<"XcWRYcWRZ">> = iolist_to_binary(re:replace("XAYABBBZ","ab*","cWR\\1",[caseless,
+ global])),
+ <<"ABICDg">> = iolist_to_binary(re:replace("ABCDE","(ab|cd)e","I\\1g",[caseless])),
+ <<"ABICDg">> = iolist_to_binary(re:replace("ABCDE","(ab|cd)e","I\\1g",[caseless,
+ global])),
+ <<"HIJe">> = iolist_to_binary(re:replace("HIJ","[abhgefdc]ij","&\\1e",[caseless])),
+ <<"HIJe">> = iolist_to_binary(re:replace("HIJ","[abhgefdc]ij","&\\1e",[caseless,
+ global])),
+ <<"ABCDE">> = iolist_to_binary(re:replace("ABCDE","^(ab|cd)e","YHPf",[caseless])),
+ <<"ABCDE">> = iolist_to_binary(re:replace("ABCDE","^(ab|cd)e","YHPf",[caseless,
+ global])),
+ <<"ABCDqDYnUXHWSlxXQRHVxU">> = iolist_to_binary(re:replace("ABCDEF","(abc|)ef","qDYnUXHWSlxXQRHVxU\\1",[caseless])),
+ <<"ABCDqDYnUXHWSlxXQRHVxU">> = iolist_to_binary(re:replace("ABCDEF","(abc|)ef","qDYnUXHWSlxXQRHVxU\\1",[caseless,
+ global])),
+ <<"ApMu">> = iolist_to_binary(re:replace("ABCD","(a|b)c*d","pMu",[caseless])),
+ <<"ApMu">> = iolist_to_binary(re:replace("ABCD","(a|b)c*d","pMu",[caseless,
+ global])),
+ <<"ntLDenfA">> = iolist_to_binary(re:replace("ABC","(ab|ab*)bc","ntLDenf\\1",[caseless])),
+ <<"ntLDenfA">> = iolist_to_binary(re:replace("ABC","(ab|ab*)bc","ntLDenf\\1",[caseless,
global])),
- <<"AEKBBQPBA">> = iolist_to_binary(re:replace("ABCD","(a|b)c*d","EK\\1\\1QP\\1A",[caseless])),
- <<"AEKBBQPBA">> = iolist_to_binary(re:replace("ABCD","(a|b)c*d","EK\\1\\1QP\\1A",[caseless,
- global])),
- <<"NnxIEABC">> = iolist_to_binary(re:replace("ABC","(ab|ab*)bc","NnxIE&",[caseless])),
- <<"NnxIEABC">> = iolist_to_binary(re:replace("ABC","(ab|ab*)bc","NnxIE&",[caseless,
- global])),
- <<"owDpyYBCHVgp">> = iolist_to_binary(re:replace("ABC","a([bc]*)c*","owDpyY\\1HVgp",[caseless])),
- <<"owDpyYBCHVgp">> = iolist_to_binary(re:replace("ABC","a([bc]*)c*","owDpyY\\1HVgp",[caseless,
- global])),
- <<"ABCDABCDaSWTqABCDBCABCDKOABCD">> = iolist_to_binary(re:replace("ABCD","a([bc]*)(c*d)","&&aSWTq&\\1&KO&",[caseless])),
- <<"ABCDABCDaSWTqABCDBCABCDKOABCD">> = iolist_to_binary(re:replace("ABCD","a([bc]*)(c*d)","&&aSWTq&\\1&KO&",[caseless,
- global])),
+ <<"kBC">> = iolist_to_binary(re:replace("ABC","a([bc]*)c*","k\\1",[caseless])),
+ <<"kBC">> = iolist_to_binary(re:replace("ABC","a([bc]*)c*","k\\1",[caseless,
+ global])),
ok.
run24() ->
- <<"llhYIK">> = iolist_to_binary(re:replace("ABCD","a([bc]+)(c*d)","llhYIK",[caseless])),
- <<"llhYIK">> = iolist_to_binary(re:replace("ABCD","a([bc]+)(c*d)","llhYIK",[caseless,
- global])),
- <<"qBhyABCDRsUdeBABCDcnABCDJOj">> = iolist_to_binary(re:replace("ABCD","a([bc]*)(c+d)","q\\1hy&RsUde\\1&cn&JOj",[caseless])),
- <<"qBhyABCDRsUdeBABCDcnABCDJOj">> = iolist_to_binary(re:replace("ABCD","a([bc]*)(c+d)","q\\1hy&RsUde\\1&cn&JOj",[caseless,
- global])),
- <<"sXpCRWnaew">> = iolist_to_binary(re:replace("ADCDCDE","a[bcd]*dcdcde","sXpCRWnae\\1w",[caseless])),
- <<"sXpCRWnaew">> = iolist_to_binary(re:replace("ADCDCDE","a[bcd]*dcdcde","sXpCRWnae\\1w",[caseless,
- global])),
- <<"PKABCMuYNABCABCXtIsm">> = iolist_to_binary(re:replace("ABC","(ab|a)b*c","PK&MuYN&&XtIsm",[caseless])),
- <<"PKABCMuYNABCABCXtIsm">> = iolist_to_binary(re:replace("ABC","(ab|a)b*c","PK&MuYN&&XtIsm",[caseless,
- global])),
- <<"pMOU">> = iolist_to_binary(re:replace("ABCD","((a)(b)c)(d)","pMOU",[caseless])),
- <<"pMOU">> = iolist_to_binary(re:replace("ABCD","((a)(b)c)(d)","pMOU",[caseless,
- global])),
- <<"bnFWpQALPHAjXlptg">> = iolist_to_binary(re:replace("ALPHA","[a-zA-Z_][a-zA-Z0-9_]*","bnFW\\1pQ&jXl\\1ptg\\1",[caseless])),
- <<"bnFWpQALPHAjXlptg">> = iolist_to_binary(re:replace("ALPHA","[a-zA-Z_][a-zA-Z0-9_]*","bnFW\\1pQ&jXl\\1ptg\\1",[caseless,
- global])),
- <<"ARTSHBHAfemfBHJIBHBHBH">> = iolist_to_binary(re:replace("ABH","^a(bc+|b[eh])g|.h$","RT\\1SH&Afemf&JI&&&",[caseless])),
- <<"ARTSHBHAfemfBHJIBHBHBH">> = iolist_to_binary(re:replace("ABH","^a(bc+|b[eh])g|.h$","RT\\1SH&Afemf&JI&&&",[caseless,
- global])),
- <<"lEFFGZichPjsHBEFFGZe">> = iolist_to_binary(re:replace("EFFGZ","(bc+d$|ef*g.|h?i(j|k))","l\\1ichPjsHB\\1e",[caseless])),
- <<"lEFFGZichPjsHBEFFGZe">> = iolist_to_binary(re:replace("EFFGZ","(bc+d$|ef*g.|h?i(j|k))","l\\1ichPjsHB\\1e",[caseless,
- global])),
- <<"IJnqeTnhpIJ">> = iolist_to_binary(re:replace("IJ","(bc+d$|ef*g.|h?i(j|k))","&nqeTnhp\\1",[caseless])),
- <<"IJnqeTnhpIJ">> = iolist_to_binary(re:replace("IJ","(bc+d$|ef*g.|h?i(j|k))","&nqeTnhp\\1",[caseless,
+ <<"dDECvKABCDBCABCDKBC">> = iolist_to_binary(re:replace("ABCD","a([bc]*)(c*d)","dDECvK&\\1&K\\1",[caseless])),
+ <<"dDECvKABCDBCABCDKBC">> = iolist_to_binary(re:replace("ABCD","a([bc]*)(c*d)","dDECvK&\\1&K\\1",[caseless,
+ global])),
+ <<"BCVkXABCDROnLhn">> = iolist_to_binary(re:replace("ABCD","a([bc]+)(c*d)","\\1VkX&ROnLhn",[caseless])),
+ <<"BCVkXABCDROnLhn">> = iolist_to_binary(re:replace("ABCD","a([bc]+)(c*d)","\\1VkX&ROnLhn",[caseless,
+ global])),
+ <<"sABCDfIigwcUBfcAtBAdBd">> = iolist_to_binary(re:replace("ABCD","a([bc]*)(c+d)","s&fIigwcU\\1fcAt\\1Ad\\1d",[caseless])),
+ <<"sABCDfIigwcUBfcAtBAdBd">> = iolist_to_binary(re:replace("ABCD","a([bc]*)(c+d)","s&fIigwcU\\1fcAt\\1Ad\\1d",[caseless,
+ global])),
+ <<"wkVJSCADCDCDEbeusn">> = iolist_to_binary(re:replace("ADCDCDE","a[bcd]*dcdcde","w\\1kVJSC&beus\\1\\1n",[caseless])),
+ <<"wkVJSCADCDCDEbeusn">> = iolist_to_binary(re:replace("ADCDCDE","a[bcd]*dcdcde","w\\1kVJSC&beus\\1\\1n",[caseless,
+ global])),
+ <<"fIEmgxyABXgAmoxnNTABCb">> = iolist_to_binary(re:replace("ABC","(ab|a)b*c","fIEmgxy\\1XgAmoxnNT&b",[caseless])),
+ <<"fIEmgxyABXgAmoxnNTABCb">> = iolist_to_binary(re:replace("ABC","(ab|a)b*c","fIEmgxy\\1XgAmoxnNT&b",[caseless,
+ global])),
+ <<"YSwweMKEtREGmRxABCEp">> = iolist_to_binary(re:replace("ABCD","((a)(b)c)(d)","YSwweMKEtREGmRx\\1Ep",[caseless])),
+ <<"YSwweMKEtREGmRxABCEp">> = iolist_to_binary(re:replace("ABCD","((a)(b)c)(d)","YSwweMKEtREGmRx\\1Ep",[caseless,
global])),
- <<"RTAEFFGZEFFGZtiL">> = iolist_to_binary(re:replace("REFFGZ","(bc+d$|ef*g.|h?i(j|k))","TA\\1&tiL",[caseless])),
- <<"RTAEFFGZEFFGZtiL">> = iolist_to_binary(re:replace("REFFGZ","(bc+d$|ef*g.|h?i(j|k))","TA\\1&tiL",[caseless,
+ <<"JMWvNALPHAHEALPHAgTLgLgw">> = iolist_to_binary(re:replace("ALPHA","[a-zA-Z_][a-zA-Z0-9_]*","JMWvN&HE&\\1gTLgLgw",[caseless])),
+ <<"JMWvNALPHAHEALPHAgTLgLgw">> = iolist_to_binary(re:replace("ALPHA","[a-zA-Z_][a-zA-Z0-9_]*","JMWvN&HE&\\1gTLgLgw",[caseless,
+ global])),
+ <<"ALoaDSHAABHcNcg">> = iolist_to_binary(re:replace("ABH","^a(bc+|b[eh])g|.h$","LoaDSHAA&c\\1Ncg",[caseless])),
+ <<"ALoaDSHAABHcNcg">> = iolist_to_binary(re:replace("ABH","^a(bc+|b[eh])g|.h$","LoaDSHAA&c\\1Ncg",[caseless,
global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(bc+d$|ef*g.|h?i(j|k))","QSIQtF",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(bc+d$|ef*g.|h?i(j|k))","QSIQtF",[caseless,
- global])),
- <<"ADCDCDE">> = iolist_to_binary(re:replace("ADCDCDE","(bc+d$|ef*g.|h?i(j|k))","hkkg&\\1M",[caseless])),
- <<"ADCDCDE">> = iolist_to_binary(re:replace("ADCDCDE","(bc+d$|ef*g.|h?i(j|k))","hkkg&\\1M",[caseless,
+ <<"AWnYrnkPEFFGZ">> = iolist_to_binary(re:replace("EFFGZ","(bc+d$|ef*g.|h?i(j|k))","AWnYrnkP&",[caseless])),
+ <<"AWnYrnkPEFFGZ">> = iolist_to_binary(re:replace("EFFGZ","(bc+d$|ef*g.|h?i(j|k))","AWnYrnkP&",[caseless,
+ global])),
+ <<"iIJYPJxCXsht">> = iolist_to_binary(re:replace("IJ","(bc+d$|ef*g.|h?i(j|k))","i&YPJxCXsht",[caseless])),
+ <<"iIJYPJxCXsht">> = iolist_to_binary(re:replace("IJ","(bc+d$|ef*g.|h?i(j|k))","i&YPJxCXsht",[caseless,
+ global])),
+ <<"ROdSmgEnEFFGZbUEFFGZxEFFGZEFFGZjiEFFGZD">> = iolist_to_binary(re:replace("REFFGZ","(bc+d$|ef*g.|h?i(j|k))","OdSmgEn&bU&x&&ji\\1D",[caseless])),
+ <<"ROdSmgEnEFFGZbUEFFGZxEFFGZEFFGZjiEFFGZD">> = iolist_to_binary(re:replace("REFFGZ","(bc+d$|ef*g.|h?i(j|k))","OdSmgEn&bU&x&&ji\\1D",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(bc+d$|ef*g.|h?i(j|k))","ITOSQR&JRMPdo",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(bc+d$|ef*g.|h?i(j|k))","ITOSQR&JRMPdo",[caseless,
+ global])),
+ <<"ADCDCDE">> = iolist_to_binary(re:replace("ADCDCDE","(bc+d$|ef*g.|h?i(j|k))","Vy&&ec&TLeQ",[caseless])),
+ <<"ADCDCDE">> = iolist_to_binary(re:replace("ADCDCDE","(bc+d$|ef*g.|h?i(j|k))","Vy&&ec&TLeQ",[caseless,
+ global])),
+ <<"EFFG">> = iolist_to_binary(re:replace("EFFG","(bc+d$|ef*g.|h?i(j|k))","PCmRtstvtrOjn",[caseless])),
+ <<"EFFG">> = iolist_to_binary(re:replace("EFFG","(bc+d$|ef*g.|h?i(j|k))","PCmRtstvtrOjn",[caseless,
global])),
- <<"EFFG">> = iolist_to_binary(re:replace("EFFG","(bc+d$|ef*g.|h?i(j|k))","b",[caseless])),
- <<"EFFG">> = iolist_to_binary(re:replace("EFFG","(bc+d$|ef*g.|h?i(j|k))","b",[caseless,
- global])),
- <<"BCDD">> = iolist_to_binary(re:replace("BCDD","(bc+d$|ef*g.|h?i(j|k))","TW&UdGE\\1S&N\\1u&LM",[caseless])),
- <<"BCDD">> = iolist_to_binary(re:replace("BCDD","(bc+d$|ef*g.|h?i(j|k))","TW&UdGE\\1S&N\\1u&LM",[caseless,
- global])),
- <<"APvAegF">> = iolist_to_binary(re:replace("A","((((((((((a))))))))))","\\1Pv\\1egF",[caseless])),
- <<"APvAegF">> = iolist_to_binary(re:replace("A","((((((((((a))))))))))","\\1Pv\\1egF",[caseless,
- global])),
- <<"vCaAAVsbLoAAcsIToC">> = iolist_to_binary(re:replace("AA","((((((((((a))))))))))\\10","vCa&VsbLo&csIToC",[caseless])),
- <<"vCaAAVsbLoAAcsIToC">> = iolist_to_binary(re:replace("AA","((((((((((a))))))))))\\10","vCa&VsbLo&csIToC",[caseless,
- global])),
- <<"ADAqIbKy">> = iolist_to_binary(re:replace("A","(((((((((a)))))))))","\\1D\\1qIbKy",[caseless])),
- <<"ADAqIbKy">> = iolist_to_binary(re:replace("A","(((((((((a)))))))))","\\1D\\1qIbKy",[caseless,
- global])),
- <<"HdAAToxA">> = iolist_to_binary(re:replace("A","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))","Hd\\1\\1Tox&",[caseless])),
- <<"HdAAToxA">> = iolist_to_binary(re:replace("A","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))","Hd\\1\\1Tox&",[caseless,
- global])),
- <<"FoLn">> = iolist_to_binary(re:replace("C","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))","FoLn",[caseless])),
- <<"FoLn">> = iolist_to_binary(re:replace("C","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))","FoLn",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","multiple words of text","eKwT&ytF",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","multiple words of text","eKwT&ytF",[caseless,
- global])),
- <<"AA">> = iolist_to_binary(re:replace("AA","multiple words of text","&&naWXBUAJEX&uN\\1eWT&",[caseless])),
- <<"AA">> = iolist_to_binary(re:replace("AA","multiple words of text","&&naWXBUAJEX&uN\\1eWT&",[caseless,
- global])),
- <<"UH-UH">> = iolist_to_binary(re:replace("UH-UH","multiple words of text","AxWlS&OyQU",[caseless])),
- <<"UH-UH">> = iolist_to_binary(re:replace("UH-UH","multiple words of text","AxWlS&OyQU",[caseless,
- global])),
- <<"WkAfGvMULTIPLE WORDSvMULTIPLE WORDS, YEAH">> = iolist_to_binary(re:replace("MULTIPLE WORDS, YEAH","multiple words","WkAfGv&v&\\1",[caseless])),
- <<"WkAfGvMULTIPLE WORDSvMULTIPLE WORDS, YEAH">> = iolist_to_binary(re:replace("MULTIPLE WORDS, YEAH","multiple words","WkAfGv&v&\\1",[caseless,
- global])),
- <<"KN">> = iolist_to_binary(re:replace("ABCDE","(.*)c(.*)","KN",[caseless])),
- <<"KN">> = iolist_to_binary(re:replace("ABCDE","(.*)c(.*)","KN",[caseless,
- global])),
- <<"TMyXAYMUnYaLqLp">> = iolist_to_binary(re:replace("(A, B)","\\((.*), (.*)\\)","TMyX\\1YMUnYaLqLp",[caseless])),
- <<"TMyXAYMUnYaLqLp">> = iolist_to_binary(re:replace("(A, B)","\\((.*), (.*)\\)","TMyX\\1YMUnYaLqLp",[caseless,
- global])),
- <<"trKKABCDSCXABCDotxTyYR">> = iolist_to_binary(re:replace("ABCD","abcd","t\\1rKK&SCX&otxTyY\\1R",[caseless])),
- <<"trKKABCDSCXABCDotxTyYR">> = iolist_to_binary(re:replace("ABCD","abcd","t\\1rKK&SCX&otxTyY\\1R",[caseless,
+ <<"BCDD">> = iolist_to_binary(re:replace("BCDD","(bc+d$|ef*g.|h?i(j|k))","Sa\\1",[caseless])),
+ <<"BCDD">> = iolist_to_binary(re:replace("BCDD","(bc+d$|ef*g.|h?i(j|k))","Sa\\1",[caseless,
global])),
+ <<"ApAYGkIxvjAQAXrHAAD">> = iolist_to_binary(re:replace("A","((((((((((a))))))))))","\\1p&YGkIxvjAQ&XrH\\1\\1D",[caseless])),
+ <<"ApAYGkIxvjAQAXrHAAD">> = iolist_to_binary(re:replace("A","((((((((((a))))))))))","\\1p&YGkIxvjAQ&XrH\\1\\1D",[caseless,
+ global])),
+ <<"ggQ">> = iolist_to_binary(re:replace("AA","((((((((((a))))))))))\\10","ggQ",[caseless])),
+ <<"ggQ">> = iolist_to_binary(re:replace("AA","((((((((((a))))))))))\\10","ggQ",[caseless,
+ global])),
+ <<"hdkAdxeeAQGHCDfdU">> = iolist_to_binary(re:replace("A","(((((((((a)))))))))","hdk\\1dxee\\1QGHCDfdU",[caseless])),
+ <<"hdkAdxeeAQGHCDfdU">> = iolist_to_binary(re:replace("A","(((((((((a)))))))))","hdk\\1dxee\\1QGHCDfdU",[caseless,
+ global])),
+ <<"fnjTAfWdAoA">> = iolist_to_binary(re:replace("A","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))","fnjT\\1fWd\\1o&",[caseless])),
+ <<"fnjTAfWdAoA">> = iolist_to_binary(re:replace("A","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))","fnjT\\1fWd\\1o&",[caseless,
+ global])),
+ <<"GqCEOfPIdb">> = iolist_to_binary(re:replace("C","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))","Gq\\1EOfPIdb",[caseless])),
+ <<"GqCEOfPIdb">> = iolist_to_binary(re:replace("C","(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))","Gq\\1EOfPIdb",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","multiple words of text","Q&",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","multiple words of text","Q&",[caseless,
+ global])),
+ <<"AA">> = iolist_to_binary(re:replace("AA","multiple words of text","gEn\\1",[caseless])),
+ <<"AA">> = iolist_to_binary(re:replace("AA","multiple words of text","gEn\\1",[caseless,
+ global])),
+ <<"UH-UH">> = iolist_to_binary(re:replace("UH-UH","multiple words of text","P\\1ls&muNytHsf",[caseless])),
+ <<"UH-UH">> = iolist_to_binary(re:replace("UH-UH","multiple words of text","P\\1ls&muNytHsf",[caseless,
+ global])),
+ <<"SJgPidMULTIPLE WORDS, YEAH">> = iolist_to_binary(re:replace("MULTIPLE WORDS, YEAH","multiple words","SJgPid&",[caseless])),
+ <<"SJgPidMULTIPLE WORDS, YEAH">> = iolist_to_binary(re:replace("MULTIPLE WORDS, YEAH","multiple words","SJgPid&",[caseless,
+ global])),
+ <<"NJFRwABCDEpl">> = iolist_to_binary(re:replace("ABCDE","(.*)c(.*)","NJFRw&pl",[caseless])),
+ <<"NJFRwABCDEpl">> = iolist_to_binary(re:replace("ABCDE","(.*)c(.*)","NJFRw&pl",[caseless,
+ global])),
+ <<"(A, B)E">> = iolist_to_binary(re:replace("(A, B)","\\((.*), (.*)\\)","&E",[caseless])),
+ <<"(A, B)E">> = iolist_to_binary(re:replace("(A, B)","\\((.*), (.*)\\)","&E",[caseless,
+ global])),
ok.
run25() ->
- <<"DMHBCoABCDlywnlEABCDj">> = iolist_to_binary(re:replace("ABCD","a(bc)d","DMH\\1o&lywnlE&j",[caseless])),
- <<"DMHBCoABCDlywnlEABCDj">> = iolist_to_binary(re:replace("ABCD","a(bc)d","DMH\\1o&lywnlE&j",[caseless,
- global])),
- <<"T">> = iolist_to_binary(re:replace("AC","a[-]?c","T",[caseless])),
- <<"T">> = iolist_to_binary(re:replace("AC","a[-]?c","T",[caseless,
- global])),
- <<"ABCsVoEdFABCABCABCABCpABCyABCABCWmPtsF">> = iolist_to_binary(re:replace("ABCABC","(abc)\\1","\\1sVoEdF&&p\\1y&WmPtsF",[caseless])),
- <<"ABCsVoEdFABCABCABCABCpABCyABCABCWmPtsF">> = iolist_to_binary(re:replace("ABCABC","(abc)\\1","\\1sVoEdF&&p\\1y&WmPtsF",[caseless,
- global])),
- <<"KfsABCABCeufABC">> = iolist_to_binary(re:replace("ABCABC","([a-c]*)\\1","Kfs&euf\\1",[caseless])),
- <<"KfsABCABCeufABCKfseuf">> = iolist_to_binary(re:replace("ABCABC","([a-c]*)\\1","Kfs&euf\\1",[caseless,
+ <<"owcnsqyFeABCDEQABCD">> = iolist_to_binary(re:replace("ABCD","abcd","owcnsqyFe&EQ&",[caseless])),
+ <<"owcnsqyFeABCDEQABCD">> = iolist_to_binary(re:replace("ABCD","abcd","owcnsqyFe&EQ&",[caseless,
+ global])),
+ <<"ruKABCDABCDABCDjGNABCDoQdaABCDO">> = iolist_to_binary(re:replace("ABCD","a(bc)d","ruK&&&jGN&oQda&O",[caseless])),
+ <<"ruKABCDABCDABCDjGNABCDoQdaABCDO">> = iolist_to_binary(re:replace("ABCD","a(bc)d","ruK&&&jGN&oQda&O",[caseless,
global])),
- <<"abfexgBadad">> = iolist_to_binary(re:replace("abad","a(?!b).","fexg\\1B&&",[])),
- <<"abfexgBadad">> = iolist_to_binary(re:replace("abad","a(?!b).","fexg\\1B&&",[global])),
- <<"abArfxtCIjx">> = iolist_to_binary(re:replace("abad","a(?=d).","ArfxtCIjx",[])),
- <<"abArfxtCIjx">> = iolist_to_binary(re:replace("abad","a(?=d).","ArfxtCIjx",[global])),
- <<"abQluadxad">> = iolist_to_binary(re:replace("abad","a(?=c|d).","Qlu&x&",[])),
- <<"abQluadxad">> = iolist_to_binary(re:replace("abad","a(?=c|d).","Qlu&x&",[global])),
- <<"YMKqcsWCacepOaceeY">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)(.)","YMKqcsWC&pO&\\1Y",[])),
- <<"YMKqcsWCacepOaceeY">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)(.)","YMKqcsWC&pO&\\1Y",[global])),
- <<"HHmlgyeRvN">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)*(.)","HHmlgyeRvN",[])),
- <<"HHmlgyeRvN">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)*(.)","HHmlgyeRvN",[global])),
- <<"xdTgRuweeyuwdlSacepeacee">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)+?(.)","xdTgRuw\\1\\1yuwdlS&p\\1&\\1",[])),
- <<"xdTgRuweeyuwdlSacepeacee">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)+?(.)","xdTgRuw\\1\\1yuwdlS&p\\1&\\1",[global])),
- <<"TYYAdCdfMbcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d)+?(.)","TYYA\\1CdfM",[])),
- <<"TYYAdCdfMbcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d)+?(.)","TYYA\\1CdfM",[global])),
- <<"rHwRaCuUc">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d)+(.)","rHwRaCuUc",[])),
- <<"rHwRaCuUc">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d)+(.)","rHwRaCuUc",[global])),
- <<"acdbWhFfMbSbtdcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){2}(.)","&WhFfM\\1S\\1td",[])),
- <<"acdbWhFfMbSbtdcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){2}(.)","&WhFfM\\1S\\1td",[global])),
- <<"bXacdbcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){4,5}(.)","\\1X&",[])),
- <<"bXacdbcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){4,5}(.)","\\1X&",[global])),
- <<"bCacdbcdobe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){4,5}?(.)","bC&o",[])),
- <<"bCacdbcdobe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){4,5}?(.)","bC&o",[global])),
- <<"barYfoobarsbxTHafoobarIbm">> = iolist_to_binary(re:replace("foobar","((foo)|(bar))*","\\1Y&sbxTHa&Ibm",[])),
- <<"barYfoobarsbxTHafoobarIbmYsbxTHaIbm">> = iolist_to_binary(re:replace("foobar","((foo)|(bar))*","\\1Y&sbxTHa&Ibm",[global])),
- <<"eeBieacdbcdbeeIHacdbcdbeNPRhLo">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){6,7}(.)","\\1\\1Bi\\1&\\1IH&NPRhLo",[])),
- <<"eeBieacdbcdbeeIHacdbcdbeNPRhLo">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){6,7}(.)","\\1\\1Bi\\1&\\1IH&NPRhLo",[global])),
- <<"acdbcdbeiacdbcdbevacdbcdbeorW">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){6,7}?(.)","&i&v&orW",[])),
- <<"acdbcdbeiacdbcdbevacdbcdbeorW">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){6,7}?(.)","&i&v&orW",[global])),
- <<"LeePacdbcdbeacdbcdbeCth">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,6}(.)","L\\1\\1P&&Cth",[])),
- <<"LeePacdbcdbeacdbcdbeCth">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,6}(.)","L\\1\\1P&&Cth",[global])),
- <<"uVacdbcdbWhMacdbcdbNbEue">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,6}?(.)","uV&WhM&N\\1Eu",[])),
- <<"uVacdbcdbWhMacdbcdbNbEue">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,6}?(.)","uV&WhM&N\\1Eu",[global])),
- <<"acdbcdbeuqWHNeI">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,7}(.)","&uqWHNeI",[])),
- <<"acdbcdbeuqWHNeI">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,7}(.)","&uqWHNeI",[global])),
+ <<"NACWHMsODnACQCvNsAC">> = iolist_to_binary(re:replace("AC","a[-]?c","N&WHM\\1sODn&QCvN\\1s&",[caseless])),
+ <<"NACWHMsODnACQCvNsAC">> = iolist_to_binary(re:replace("AC","a[-]?c","N&WHM\\1sODn&QCvN\\1s&",[caseless,
+ global])),
+ <<"sABCgQuaFABCh">> = iolist_to_binary(re:replace("ABCABC","(abc)\\1","s\\1gQuaF\\1h",[caseless])),
+ <<"sABCgQuaFABCh">> = iolist_to_binary(re:replace("ABCABC","(abc)\\1","s\\1gQuaF\\1h",[caseless,
+ global])),
+ <<"lABCmSQABCABCaXJqwxUYswqABCABC">> = iolist_to_binary(re:replace("ABCABC","([a-c]*)\\1","l\\1mSQ&aXJqwxUYswq&",[caseless])),
+ <<"lABCmSQABCABCaXJqwxUYswqABCABClmSQaXJqwxUYswq">> = iolist_to_binary(re:replace("ABCABC","([a-c]*)\\1","l\\1mSQ&aXJqwxUYswq&",[caseless,
+ global])),
+ <<"abdSPadcRcbUkgXmcHGW">> = iolist_to_binary(re:replace("abad","a(?!b).","dSP&\\1cRcbUkgXmcHGW\\1",[])),
+ <<"abdSPadcRcbUkgXmcHGW">> = iolist_to_binary(re:replace("abad","a(?!b).","dSP&\\1cRcbUkgXmcHGW\\1",[global])),
+ <<"abIRqW">> = iolist_to_binary(re:replace("abad","a(?=d).","IRqW",[])),
+ <<"abIRqW">> = iolist_to_binary(re:replace("abad","a(?=d).","IRqW",[global])),
+ <<"abykWXvthadUfKUlbLTp">> = iolist_to_binary(re:replace("abad","a(?=c|d).","y\\1kWXv\\1th&UfKUlbLTp",[])),
+ <<"abykWXvthadUfKUlbLTp">> = iolist_to_binary(re:replace("abad","a(?=c|d).","y\\1kWXv\\1th&UfKUlbLTp",[global])),
+ <<"pelUw">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)(.)","pelUw",[])),
+ <<"pelUw">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)(.)","pelUw",[global])),
+ <<"cfhcWSNABYeNMLh">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)*(.)","cfhcWSNABY\\1NMLh",[])),
+ <<"cfhcWSNABYeNMLh">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)*(.)","cfhcWSNABY\\1NMLh",[global])),
+ <<"etfeq">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)+?(.)","\\1tf\\1q",[])),
+ <<"etfeq">> = iolist_to_binary(re:replace("ace","a(?:b|c|d)+?(.)","\\1tf\\1q",[global])),
+ <<"acdOEfbcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d)+?(.)","&OEf",[])),
+ <<"acdOEfbcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d)+?(.)","&OEf",[global])),
+ <<"Vmfyu">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d)+(.)","Vmfyu",[])),
+ <<"Vmfyu">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d)+(.)","Vmfyu",[global])),
+ <<"FIbbMUVjTEcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){2}(.)","FI\\1\\1MUVjTE",[])),
+ <<"FIbbMUVjTEcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){2}(.)","FI\\1\\1MUVjTE",[global])),
+ <<"eicDcYacdbcdboLhMacdbcdbacdbcdbKRqe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){4,5}(.)","eicDcY&oLhM&&KRq",[])),
+ <<"eicDcYacdbcdboLhMacdbcdbacdbcdbKRqe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){4,5}(.)","eicDcY&oLhM&&KRq",[global])),
+ <<"acdbcdqsacdbcdrbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){4,5}?(.)","&qs&r",[])),
+ <<"acdbcdqsacdbcdrbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){4,5}?(.)","&qs&r",[global])),
+ <<"barbarOSJfoobar">> = iolist_to_binary(re:replace("foobar","((foo)|(bar))*","\\1\\1OSJ&",[])),
+ <<"barbarOSJfoobarOSJ">> = iolist_to_binary(re:replace("foobar","((foo)|(bar))*","\\1\\1OSJ&",[global])),
+ <<"HYIAacdbcdbeeRhacdbcdbeacdbcdbeacdbcdbeGQ">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){6,7}(.)","HYIA&\\1Rh&&&GQ",[])),
+ <<"HYIAacdbcdbeeRhacdbcdbeacdbcdbeacdbcdbeGQ">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){6,7}(.)","HYIA&\\1Rh&&&GQ",[global])),
+ <<"eacdbcdbeBcQacdbcdbewOmacdbcdbeacdbcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){6,7}?(.)","\\1&BcQ&wOm&&",[])),
+ <<"eacdbcdbeBcQacdbcdbewOmacdbcdbeacdbcdbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){6,7}?(.)","\\1&BcQ&wOm&&",[global])),
+ <<"xacdbcdbeN">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,6}(.)","x&N",[])),
+ <<"xacdbcdbeN">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,6}(.)","x&N",[global])),
+ <<"bWxPOAbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,6}?(.)","\\1WxPOA\\1",[])),
+ <<"bWxPOAbe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,6}?(.)","\\1WxPOA\\1",[global])),
ok.
run26() ->
- <<"GacdbcdbbbPbGFTve">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,7}?(.)","G&\\1\\1P\\1GFTv",[])),
- <<"GacdbcdbbbPbGFTve">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,7}?(.)","G&\\1\\1P\\1GFTv",[global])),
- <<"taceacecgacefBmaHeYaceuace">> = iolist_to_binary(re:replace("ace","a(?:b|(c|e){1,2}?|d)+?(.)","t&&\\1g&fBmaHeY&u&",[])),
- <<"taceacecgacefBmaHeYaceuace">> = iolist_to_binary(re:replace("ace","a(?:b|(c|e){1,2}?|d)+?(.)","t&&\\1g&fBmaHeY&u&",[global])),
- <<"FcNioABABQKKAbfVA">> = iolist_to_binary(re:replace("AB","^(.+)?B","FcNio&&QKK\\1bfV\\1",[])),
- <<"FcNioABABQKKAbfVA">> = iolist_to_binary(re:replace("AB","^(.+)?B","FcNio&&QKK\\1bfV\\1",[global])),
- <<"QpJsSlDdk">> = iolist_to_binary(re:replace(".","^([^a-z])|(\\^)$","QpJsSlDdk",[])),
- <<"QpJsSlDdk">> = iolist_to_binary(re:replace(".","^([^a-z])|(\\^)$","QpJsSlDdk",[global])),
- <<"YtMLJWT<&GSA<&jOUT">> = iolist_to_binary(re:replace("<&OUT","^[<>]&","Y\\1tMLJWT&GSA&j",[])),
- <<"YtMLJWT<&GSA<&jOUT">> = iolist_to_binary(re:replace("<&OUT","^[<>]&","Y\\1tMLJWT&GSA&j",[global])),
- <<"RBbN">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?){4}$","RBbN",[])),
- <<"RBbN">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?){4}$","RBbN",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a\\1?){4}$","FHwc\\1\\1biSR",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a\\1?){4}$","FHwc\\1\\1biSR",[global])),
- <<"AB">> = iolist_to_binary(re:replace("AB","^(a\\1?){4}$","rqMyo&\\1IoOAjaJ\\1vY",[])),
- <<"AB">> = iolist_to_binary(re:replace("AB","^(a\\1?){4}$","rqMyo&\\1IoOAjaJ\\1vY",[global])),
- <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?){4}$","ebuyIYAaCuRmxbiVR",[])),
- <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?){4}$","ebuyIYAaCuRmxbiVR",[global])),
- <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?){4}$","U&\\1R&jmiM\\1\\1W",[])),
- <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?){4}$","U&\\1R&jmiM\\1\\1W",[global])),
- <<"SyepNqAqGr">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a(?(1)\\1)){4}$","SyepNqAqGr",[])),
- <<"SyepNqAqGr">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a(?(1)\\1)){4}$","SyepNqAqGr",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a(?(1)\\1)){4}$","idrNArkV&XUmhWGrp\\1rN",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a(?(1)\\1)){4}$","idrNArkV&XUmhWGrp\\1rN",[global])),
- <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a(?(1)\\1)){4}$","dVYMTCeoR",[])),
- <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a(?(1)\\1)){4}$","dVYMTCeoR",[global])),
- <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a(?(1)\\1)){4}$","wtDhOT\\1Pu\\1xOt&P&&&",[])),
- <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a(?(1)\\1)){4}$","wtDhOT\\1Pu\\1xOt&P&&&",[global])),
- <<"oUbvLQMfrfVt">> = iolist_to_binary(re:replace("foobar","(?:(f)(o)(o)|(b)(a)(r))*","oUbvLQMfr\\1Vt",[])),
- <<"oUbvLQMfrfVtoUbvLQMfrVt">> = iolist_to_binary(re:replace("foobar","(?:(f)(o)(o)|(b)(a)(r))*","oUbvLQMfr\\1Vt",[global])),
- <<"aIbOkhquTbuWHx">> = iolist_to_binary(re:replace("ab","(?<=a)b","I&OkhquT&uWH\\1x",[])),
- <<"aIbOkhquTbuWHx">> = iolist_to_binary(re:replace("ab","(?<=a)b","I&OkhquT&uWH\\1x",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=a)b","BQobLoQagH&I&Gf",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=a)b","BQobLoQagH&I&Gf",[global])),
- <<"cb">> = iolist_to_binary(re:replace("cb","(?<=a)b","\\1qi\\1cF&xVKJl\\1&HHO&TH",[])),
- <<"cb">> = iolist_to_binary(re:replace("cb","(?<=a)b","\\1qi\\1cF&xVKJl\\1&HHO&TH",[global])),
- <<"b">> = iolist_to_binary(re:replace("b","(?<=a)b","aRw&xSWDbr\\1wsnnJ&G",[])),
- <<"b">> = iolist_to_binary(re:replace("b","(?<=a)b","aRw&xSWDbr\\1wsnnJ&G",[global])),
- <<"albBEJPbhoUqwpHlyll">> = iolist_to_binary(re:replace("ab","(?<!c)b","l&BEJPbhoUqwpHlyll",[])),
- <<"albBEJPbhoUqwpHlyll">> = iolist_to_binary(re:replace("ab","(?<!c)b","l&BEJPbhoUqwpHlyll",[global])),
- <<"iNbLxxT">> = iolist_to_binary(re:replace("b","(?<!c)b","iN&LxxT",[])),
- <<"iNbLxxT">> = iolist_to_binary(re:replace("b","(?<!c)b","iN&LxxT",[global])),
- <<"byOfPd">> = iolist_to_binary(re:replace("b","(?<!c)b","&yOfPd",[])),
- <<"byOfPd">> = iolist_to_binary(re:replace("b","(?<!c)b","&yOfPd",[global])),
- <<"IblabamNFubVS">> = iolist_to_binary(re:replace("aba","(?:..)*a","Ibl&mNFubVS",[])),
- <<"IblabamNFubVS">> = iolist_to_binary(re:replace("aba","(?:..)*a","Ibl&mNFubVS",[global])),
- <<"wvNuoyarrAWFba">> = iolist_to_binary(re:replace("aba","(?:..)*?a","wvNuo\\1y&rrAWF",[])),
- <<"wvNuoyarrAWFbwvNuoyarrAWF">> = iolist_to_binary(re:replace("aba","(?:..)*?a","wvNuo\\1y&rrAWF",[global])),
- <<"abVmnPSDabPXSc">> = iolist_to_binary(re:replace("abc","^(?:b|a(?=(.)))*\\1","&VmnPSD&PXS",[])),
- <<"abVmnPSDabPXSc">> = iolist_to_binary(re:replace("abc","^(?:b|a(?=(.)))*\\1","&VmnPSD&PXS",[global])),
- <<"MNhLuKuRgFcjoiabc">> = iolist_to_binary(re:replace("abc","^(){3,5}","MNhL\\1uK&uRgFcj\\1o&i\\1\\1",[])),
- <<"MNhLuKuRgFcjoiabc">> = iolist_to_binary(re:replace("abc","^(){3,5}","MNhL\\1uK&uRgFcj\\1o&i\\1\\1",[global])),
- <<"aax">> = iolist_to_binary(re:replace("aax","^(a+)*ax","&",[])),
- <<"aax">> = iolist_to_binary(re:replace("aax","^(a+)*ax","&",[global])),
- <<"aax">> = iolist_to_binary(re:replace("aax","^((a|b)+)*ax","&",[])),
- <<"aax">> = iolist_to_binary(re:replace("aax","^((a|b)+)*ax","&",[global])),
- <<"UaaxEVMyUJoaafaaxbXAGlnX">> = iolist_to_binary(re:replace("aax","^((a|bc)+)*ax","U&EVMyUJoa\\1f&bXAGlnX",[])),
- <<"UaaxEVMyUJoaafaaxbXAGlnX">> = iolist_to_binary(re:replace("aax","^((a|bc)+)*ax","U&EVMyUJoa\\1f&bXAGlnX",[global])),
- <<"cHRavababj">> = iolist_to_binary(re:replace("cab","(a|x)*ab","HR\\1av&&j",[])),
- <<"cHRavababj">> = iolist_to_binary(re:replace("cab","(a|x)*ab","HR\\1av&&j",[global])),
- <<"ceqqArfabLqGjflabab">> = iolist_to_binary(re:replace("cab","(a)*ab","eqqA\\1rf&LqGjfl&&",[])),
- <<"ceqqArfabLqGjflabab">> = iolist_to_binary(re:replace("cab","(a)*ab","eqqA\\1rf&LqGjfl&&",[global])),
- <<"aMdQQ">> = iolist_to_binary(re:replace("ab","(?:(?i)a)b","aMdQQ",[])),
- <<"aMdQQ">> = iolist_to_binary(re:replace("ab","(?:(?i)a)b","aMdQQ",[global])),
+ <<"DJeLeA">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,7}(.)","DJ\\1LeA",[])),
+ <<"DJeLeA">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,7}(.)","DJ\\1LeA",[global])),
+ <<"qinMoe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,7}?(.)","qinMo",[])),
+ <<"qinMoe">> = iolist_to_binary(re:replace("acdbcdbe","a(?:b|c|d){5,7}?(.)","qinMo",[global])),
+ <<"acecXdaceaKTrIIqhpiWP">> = iolist_to_binary(re:replace("ace","a(?:b|(c|e){1,2}?|d)+?(.)","&\\1Xd&aKTrIIqhpiWP",[])),
+ <<"acecXdaceaKTrIIqhpiWP">> = iolist_to_binary(re:replace("ace","a(?:b|(c|e){1,2}?|d)+?(.)","&\\1Xd&aKTrIIqhpiWP",[global])),
+ <<"CiaeiABbFyjW">> = iolist_to_binary(re:replace("AB","^(.+)?B","Ciaei&bFyjW",[])),
+ <<"CiaeiABbFyjW">> = iolist_to_binary(re:replace("AB","^(.+)?B","Ciaei&bFyjW",[global])),
+ <<"..Ch.IWXxoeCE">> = iolist_to_binary(re:replace(".","^([^a-z])|(\\^)$","\\1&Ch&IWXxoeCE",[])),
+ <<"..Ch.IWXxoeCE">> = iolist_to_binary(re:replace(".","^([^a-z])|(\\^)$","\\1&Ch&IWXxoeCE",[global])),
+ <<"<&<&tOUT">> = iolist_to_binary(re:replace("<&OUT","^[<>]&","&&t",[])),
+ <<"<&<&tOUT">> = iolist_to_binary(re:replace("<&OUT","^[<>]&","&&t",[global])),
+ <<"Paaaaaaaaaaw">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?){4}$","P&w",[])),
+ <<"Paaaaaaaaaaw">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a\\1?){4}$","P&w",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a\\1?){4}$","&jEcxWNe",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a\\1?){4}$","&jEcxWNe",[global])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","^(a\\1?){4}$","&QByhvIPMdVCvMAk",[])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","^(a\\1?){4}$","&QByhvIPMdVCvMAk",[global])),
+ <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?){4}$","LKyhXCAKO&fKp&",[])),
+ <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a\\1?){4}$","LKyhXCAKO&fKp&",[global])),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?){4}$","PktYBS",[])),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a\\1?){4}$","PktYBS",[global])),
+ <<"aaaaaaaaaaLaaaaaaaaaaaaaaaaaaaaAB">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a(?(1)\\1)){4}$","&L&&AB",[])),
+ <<"aaaaaaaaaaLaaaaaaaaaaaaaaaaaaaaAB">> = iolist_to_binary(re:replace("aaaaaaaaaa","^(a(?(1)\\1)){4}$","&L&&AB",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a(?(1)\\1)){4}$","&NExLuXAoRv",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a(?(1)\\1)){4}$","&NExLuXAoRv",[global])),
+ <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a(?(1)\\1)){4}$","TNhbF",[])),
+ <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a(?(1)\\1)){4}$","TNhbF",[global])),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a(?(1)\\1)){4}$","Nc\\1&GIjjbuiMOSVl",[])),
+ <<"aaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaa","^(a(?(1)\\1)){4}$","Nc\\1&GIjjbuiMOSVl",[global])),
+ <<"OO">> = iolist_to_binary(re:replace("foobar","(?:(f)(o)(o)|(b)(a)(r))*","OO",[])),
+ <<"OOOO">> = iolist_to_binary(re:replace("foobar","(?:(f)(o)(o)|(b)(a)(r))*","OO",[global])),
+ <<"aOVOqSRYFwv">> = iolist_to_binary(re:replace("ab","(?<=a)b","OVOqSRYFwv",[])),
+ <<"aOVOqSRYFwv">> = iolist_to_binary(re:replace("ab","(?<=a)b","OVOqSRYFwv",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=a)b","fIH\\1c\\1A\\1&&sdSLy",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=a)b","fIH\\1c\\1A\\1&&sdSLy",[global])),
+ <<"cb">> = iolist_to_binary(re:replace("cb","(?<=a)b","ncyI",[])),
+ <<"cb">> = iolist_to_binary(re:replace("cb","(?<=a)b","ncyI",[global])),
+ <<"b">> = iolist_to_binary(re:replace("b","(?<=a)b","suOoPj&\\1M",[])),
+ <<"b">> = iolist_to_binary(re:replace("b","(?<=a)b","suOoPj&\\1M",[global])),
+ <<"abriAFAbbvRIl">> = iolist_to_binary(re:replace("ab","(?<!c)b","&riAFA&&vR\\1Il",[])),
+ <<"abriAFAbbvRIl">> = iolist_to_binary(re:replace("ab","(?<!c)b","&riAFA&&vR\\1Il",[global])),
+ <<"oBIIxbHJbHrNT">> = iolist_to_binary(re:replace("b","(?<!c)b","oBIIx&HJ&H\\1rNT",[])),
+ <<"oBIIxbHJbHrNT">> = iolist_to_binary(re:replace("b","(?<!c)b","oBIIx&HJ&H\\1rNT",[global])),
+ <<"wWbIuHcu">> = iolist_to_binary(re:replace("b","(?<!c)b","wWbIuHcu",[])),
+ <<"wWbIuHcu">> = iolist_to_binary(re:replace("b","(?<!c)b","wWbIuHcu",[global])),
+ <<"abaNabaabaaba">> = iolist_to_binary(re:replace("aba","(?:..)*a","&N&&&",[])),
+ <<"abaNabaabaaba">> = iolist_to_binary(re:replace("aba","(?:..)*a","&N&&&",[global])),
+ <<"dmba">> = iolist_to_binary(re:replace("aba","(?:..)*?a","d\\1m",[])),
+ <<"dmbdm">> = iolist_to_binary(re:replace("aba","(?:..)*?a","d\\1m",[global])),
+ <<"Ywc">> = iolist_to_binary(re:replace("abc","^(?:b|a(?=(.)))*\\1","Yw",[])),
+ <<"Ywc">> = iolist_to_binary(re:replace("abc","^(?:b|a(?=(.)))*\\1","Yw",[global])),
+ <<"mwetmXoabc">> = iolist_to_binary(re:replace("abc","^(){3,5}","mwet\\1mXo",[])),
+ <<"mwetmXoabc">> = iolist_to_binary(re:replace("abc","^(){3,5}","mwet\\1mXo",[global])),
+ <<"agaYaDwEIxdcATaajdie">> = iolist_to_binary(re:replace("aax","^(a+)*ax","\\1g\\1Y\\1DwEIxdcAT\\1\\1jdie",[])),
+ <<"agaYaDwEIxdcATaajdie">> = iolist_to_binary(re:replace("aax","^(a+)*ax","\\1g\\1Y\\1DwEIxdcAT\\1\\1jdie",[global])),
+ <<"oOs">> = iolist_to_binary(re:replace("aax","^((a|b)+)*ax","oOs",[])),
+ <<"oOs">> = iolist_to_binary(re:replace("aax","^((a|b)+)*ax","oOs",[global])),
+ <<"XhaaxEdaassqaxiHJabBaK">> = iolist_to_binary(re:replace("aax","^((a|bc)+)*ax","Xh&Ed\\1\\1ssq\\1xiHJ\\1bB\\1K",[])),
+ <<"XhaaxEdaassqaxiHJabBaK">> = iolist_to_binary(re:replace("aax","^((a|bc)+)*ax","Xh&Ed\\1\\1ssq\\1xiHJ\\1bB\\1K",[global])),
+ <<"cXkxsSHRksqVJf">> = iolist_to_binary(re:replace("cab","(a|x)*ab","XkxsSHRk\\1sqVJf",[])),
+ <<"cXkxsSHRksqVJf">> = iolist_to_binary(re:replace("cab","(a|x)*ab","XkxsSHRk\\1sqVJf",[global])),
+ <<"cTOrWuaboDtjqjUj">> = iolist_to_binary(re:replace("cab","(a)*ab","TOrWu\\1&o\\1D\\1tjqjUj\\1\\1\\1",[])),
+ <<"cTOrWuaboDtjqjUj">> = iolist_to_binary(re:replace("cab","(a)*ab","TOrWu\\1&o\\1D\\1tjqjUj\\1\\1\\1",[global])),
ok.
run27() ->
- <<"qpLuqQJ">> = iolist_to_binary(re:replace("ab","((?i)a)b","qpLuqQJ",[])),
- <<"qpLuqQJ">> = iolist_to_binary(re:replace("ab","((?i)a)b","qpLuqQJ",[global])),
- <<"KU">> = iolist_to_binary(re:replace("Ab","(?:(?i)a)b","KU\\1",[])),
- <<"KU">> = iolist_to_binary(re:replace("Ab","(?:(?i)a)b","KU\\1",[global])),
- <<"HbAbcmtA">> = iolist_to_binary(re:replace("Ab","((?i)a)b","Hb&cmt\\1",[])),
- <<"HbAbcmtA">> = iolist_to_binary(re:replace("Ab","((?i)a)b","Hb&cmt\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?i)a)b","\\1&d\\1h",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?i)a)b","\\1&d\\1h",[global])),
- <<"cb">> = iolist_to_binary(re:replace("cb","(?:(?i)a)b","QGy\\1\\1s",[])),
- <<"cb">> = iolist_to_binary(re:replace("cb","(?:(?i)a)b","QGy\\1\\1s",[global])),
- <<"aB">> = iolist_to_binary(re:replace("aB","(?:(?i)a)b","h&LcJB&\\1koG",[])),
- <<"aB">> = iolist_to_binary(re:replace("aB","(?:(?i)a)b","h&LcJB&\\1koG",[global])),
- <<"hQoabBcSA">> = iolist_to_binary(re:replace("ab","(?i:a)b","h\\1Qo&B\\1cSA",[])),
- <<"hQoabBcSA">> = iolist_to_binary(re:replace("ab","(?i:a)b","h\\1Qo&B\\1cSA",[global])),
- <<"C">> = iolist_to_binary(re:replace("ab","((?i:a))b","C",[])),
- <<"C">> = iolist_to_binary(re:replace("ab","((?i:a))b","C",[global])),
- <<"GAMAbeosONsSFAblyS">> = iolist_to_binary(re:replace("Ab","(?i:a)b","GAM&eos\\1O\\1Ns\\1SF&lyS",[])),
- <<"GAMAbeosONsSFAblyS">> = iolist_to_binary(re:replace("Ab","(?i:a)b","GAM&eos\\1O\\1Ns\\1SF&lyS",[global])),
- <<"AbASQYAbA">> = iolist_to_binary(re:replace("Ab","((?i:a))b","&\\1SQY&\\1",[])),
- <<"AbASQYAbA">> = iolist_to_binary(re:replace("Ab","((?i:a))b","&\\1SQY&\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?i:a)b","EW&tEN\\1\\1&\\1\\1yd",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?i:a)b","EW&tEN\\1\\1&\\1\\1yd",[global])),
- <<"aB">> = iolist_to_binary(re:replace("aB","(?i:a)b","bK&xdvtcfqVCo",[])),
- <<"aB">> = iolist_to_binary(re:replace("aB","(?i:a)b","bK&xdvtcfqVCo",[global])),
- <<"aB">> = iolist_to_binary(re:replace("aB","(?i:a)b","rU",[])),
- <<"aB">> = iolist_to_binary(re:replace("aB","(?i:a)b","rU",[global])),
- <<"fabvvabeKvWlUCaababk">> = iolist_to_binary(re:replace("ab","(?:(?-i)a)b","f&vv&eKvWlUC\\1\\1a&\\1&k",[caseless])),
- <<"fabvvabeKvWlUCaababk">> = iolist_to_binary(re:replace("ab","(?:(?-i)a)b","f&vv&eKvWlUC\\1\\1a&\\1&k",[caseless,
- global])),
- <<"a">> = iolist_to_binary(re:replace("ab","((?-i)a)b","a",[caseless])),
- <<"a">> = iolist_to_binary(re:replace("ab","((?-i)a)b","a",[caseless,
- global])),
- <<"YgwHaBaBEobvWdcKm">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","YgwH&&E\\1o\\1bvWdcKm",[caseless])),
- <<"YgwHaBaBEobvWdcKm">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","YgwH&&E\\1o\\1bvWdcKm",[caseless,
- global])),
- <<"gPQtaBiM">> = iolist_to_binary(re:replace("aB","((?-i)a)b","gPQt\\1BiM",[caseless])),
- <<"gPQtaBiM">> = iolist_to_binary(re:replace("aB","((?-i)a)b","gPQt\\1BiM",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?-i)a)b","dAPB\\1lhgJnXJM\\1",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?-i)a)b","dAPB\\1lhgJnXJM\\1",[caseless,
- global])),
- <<"cpmMjqeoMjqXPSCxgaB">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","cpmMjqeoMjqXPSC\\1xg&",[caseless])),
- <<"cpmMjqeoMjqXPSCxgaB">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","cpmMjqeoMjqXPSC\\1xg&",[caseless,
- global])),
- <<"Ab">> = iolist_to_binary(re:replace("Ab","(?:(?-i)a)b","ehCMjHfdoLOUT",[caseless])),
- <<"Ab">> = iolist_to_binary(re:replace("Ab","(?:(?-i)a)b","ehCMjHfdoLOUT",[caseless,
- global])),
- <<"aBaBXheDmRWIj">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","&&XheDmRW\\1Ij",[caseless])),
- <<"aBaBXheDmRWIj">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","&&XheDmRW\\1Ij",[caseless,
- global])),
- <<"HaBaBwaBaBarQLsPaLaBH">> = iolist_to_binary(re:replace("aB","((?-i)a)b","H&&w&&\\1rQLsP\\1L&H",[caseless])),
- <<"HaBaBwaBaBarQLsPaLaBH">> = iolist_to_binary(re:replace("aB","((?-i)a)b","H&&w&&\\1rQLsP\\1L&H",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?-i)a)b","rA&&\\1Ox\\1x",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?-i)a)b","rA&&\\1Ox\\1x",[caseless,
- global])),
- <<"Ab">> = iolist_to_binary(re:replace("Ab","(?:(?-i)a)b","qU\\1qgKirHcB",[caseless])),
- <<"Ab">> = iolist_to_binary(re:replace("Ab","(?:(?-i)a)b","qU\\1qgKirHcB",[caseless,
- global])),
- <<"AB">> = iolist_to_binary(re:replace("AB","(?:(?-i)a)b","rtc&FUes&I&&V\\1Wi&o",[caseless])),
- <<"AB">> = iolist_to_binary(re:replace("AB","(?:(?-i)a)b","rtc&FUes&I&&V\\1Wi&o",[caseless,
- global])),
+ <<"itod">> = iolist_to_binary(re:replace("ab","(?:(?i)a)b","itod",[])),
+ <<"itod">> = iolist_to_binary(re:replace("ab","(?:(?i)a)b","itod",[global])),
+ <<"WjabMNVeskabFabMkNj">> = iolist_to_binary(re:replace("ab","((?i)a)b","Wj&MNVesk&F&MkNj",[])),
+ <<"WjabMNVeskabFabMkNj">> = iolist_to_binary(re:replace("ab","((?i)a)b","Wj&MNVesk&F&MkNj",[global])),
+ <<"K">> = iolist_to_binary(re:replace("Ab","(?:(?i)a)b","K\\1",[])),
+ <<"K">> = iolist_to_binary(re:replace("Ab","(?:(?i)a)b","K\\1",[global])),
+ <<"KAbmpSqMJmrScTHEHA">> = iolist_to_binary(re:replace("Ab","((?i)a)b","K&mpSqMJmrScTHEH\\1",[])),
+ <<"KAbmpSqMJmrScTHEHA">> = iolist_to_binary(re:replace("Ab","((?i)a)b","K&mpSqMJmrScTHEH\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?i)a)b","jONwRrcyS&bFO",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?i)a)b","jONwRrcyS&bFO",[global])),
+ <<"cb">> = iolist_to_binary(re:replace("cb","(?:(?i)a)b","DIfuf&vF\\1&o&yYq",[])),
+ <<"cb">> = iolist_to_binary(re:replace("cb","(?:(?i)a)b","DIfuf&vF\\1&o&yYq",[global])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","(?:(?i)a)b","\\1\\1ntgcmKqp",[])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","(?:(?i)a)b","\\1\\1ntgcmKqp",[global])),
+ <<"jI">> = iolist_to_binary(re:replace("ab","(?i:a)b","jI",[])),
+ <<"jI">> = iolist_to_binary(re:replace("ab","(?i:a)b","jI",[global])),
+ <<"bVgmsFMa">> = iolist_to_binary(re:replace("ab","((?i:a))b","bVgmsFMa",[])),
+ <<"bVgmsFMa">> = iolist_to_binary(re:replace("ab","((?i:a))b","bVgmsFMa",[global])),
+ <<"cEcAlebAbOIAbmOu">> = iolist_to_binary(re:replace("Ab","(?i:a)b","cEcAl\\1eb\\1&OI&\\1mOu",[])),
+ <<"cEcAlebAbOIAbmOu">> = iolist_to_binary(re:replace("Ab","(?i:a)b","cEcAl\\1eb\\1&OI&\\1mOu",[global])),
+ <<"hA">> = iolist_to_binary(re:replace("Ab","((?i:a))b","h\\1",[])),
+ <<"hA">> = iolist_to_binary(re:replace("Ab","((?i:a))b","h\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?i:a)b","ip",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?i:a)b","ip",[global])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","(?i:a)b","\\1pL",[])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","(?i:a)b","\\1pL",[global])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","(?i:a)b","qL&OvIX\\1G&&rRe&x\\1o\\1",[])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","(?i:a)b","qL&OvIX\\1G&&rRe&x\\1o\\1",[global])),
+ <<"RsYIqopkaabwdwdgKabT">> = iolist_to_binary(re:replace("ab","(?:(?-i)a)b","RsYIqopka&\\1wdwdgK&T",[caseless])),
+ <<"RsYIqopkaabwdwdgKabT">> = iolist_to_binary(re:replace("ab","(?:(?-i)a)b","RsYIqopka&\\1wdwdgK&T",[caseless,
+ global])),
+ <<"lLfababYHTqsmO">> = iolist_to_binary(re:replace("ab","((?-i)a)b","lLf&&YHTqsmO",[caseless])),
+ <<"lLfababYHTqsmO">> = iolist_to_binary(re:replace("ab","((?-i)a)b","lLf&&YHTqsmO",[caseless,
+ global])),
+ <<"JCuXbQvaBXV">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","JCuXbQv&XV",[caseless])),
+ <<"JCuXbQvaBXV">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","JCuXbQv&XV",[caseless,
+ global])),
+ <<"najlatTu">> = iolist_to_binary(re:replace("aB","((?-i)a)b","n\\1jl\\1tTu",[caseless])),
+ <<"najlatTu">> = iolist_to_binary(re:replace("aB","((?-i)a)b","n\\1jl\\1tTu",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?-i)a)b","oRHrhfYgmYE",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?-i)a)b","oRHrhfYgmYE",[caseless,
+ global])),
+ <<"C">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","C",[caseless])),
+ <<"C">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","C",[caseless,
+ global])),
+ <<"Ab">> = iolist_to_binary(re:replace("Ab","(?:(?-i)a)b","MbmyjKDJY",[caseless])),
+ <<"Ab">> = iolist_to_binary(re:replace("Ab","(?:(?-i)a)b","MbmyjKDJY",[caseless,
+ global])),
+ <<"KRBaBYDPTaBIetfKafk">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","K\\1RB&YDPT&Ietf\\1Kafk",[caseless])),
+ <<"KRBaBYDPTaBIetfKafk">> = iolist_to_binary(re:replace("aB","(?:(?-i)a)b","K\\1RB&YDPT&Ietf\\1Kafk",[caseless,
+ global])),
+ <<"FAeMLQgRgVVahad">> = iolist_to_binary(re:replace("aB","((?-i)a)b","FAeMLQgRgVV\\1h\\1d",[caseless])),
+ <<"FAeMLQgRgVVahad">> = iolist_to_binary(re:replace("aB","((?-i)a)b","FAeMLQgRgVV\\1h\\1d",[caseless,
+ global])),
ok.
run28() ->
- <<"gGfbP">> = iolist_to_binary(re:replace("ab","(?-i:a)b","\\1gGfbP",[caseless])),
- <<"gGfbP">> = iolist_to_binary(re:replace("ab","(?-i:a)b","\\1gGfbP",[caseless,
- global])),
- <<"oibsT">> = iolist_to_binary(re:replace("ab","((?-i:a))b","oibsT",[caseless])),
- <<"oibsT">> = iolist_to_binary(re:replace("ab","((?-i:a))b","oibsT",[caseless,
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?-i)a)b","V",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?:(?-i)a)b","V",[caseless,
+ global])),
+ <<"Ab">> = iolist_to_binary(re:replace("Ab","(?:(?-i)a)b","vOEiltgjc",[caseless])),
+ <<"Ab">> = iolist_to_binary(re:replace("Ab","(?:(?-i)a)b","vOEiltgjc",[caseless,
+ global])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","(?:(?-i)a)b","hCMP",[caseless])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","(?:(?-i)a)b","hCMP",[caseless,
global])),
- <<"erLkRe">> = iolist_to_binary(re:replace("aB","(?-i:a)b","erLkRe",[caseless])),
- <<"erLkRe">> = iolist_to_binary(re:replace("aB","(?-i:a)b","erLkRe",[caseless,
- global])),
- <<"NcuVaBaPaBqlgVJaaAMaBjt">> = iolist_to_binary(re:replace("aB","((?-i:a))b","NcuV&aP&qlgVJ\\1\\1AM&jt",[caseless])),
- <<"NcuVaBaPaBqlgVJaaAMaBjt">> = iolist_to_binary(re:replace("aB","((?-i:a))b","NcuV&aP&qlgVJ\\1\\1AM&jt",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?-i:a)b","xW",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?-i:a)b","xW",[caseless,
- global])),
- <<"AB">> = iolist_to_binary(re:replace("AB","(?-i:a)b","rBT\\1&D&jmNXx",[caseless])),
- <<"AB">> = iolist_to_binary(re:replace("AB","(?-i:a)b","rBT\\1&D&jmNXx",[caseless,
- global])),
- <<"Ab">> = iolist_to_binary(re:replace("Ab","(?-i:a)b","oyAx&&hEq\\1",[caseless])),
- <<"Ab">> = iolist_to_binary(re:replace("Ab","(?-i:a)b","oyAx&&hEq\\1",[caseless,
- global])),
- <<"shG">> = iolist_to_binary(re:replace("aB","(?-i:a)b","\\1shG",[caseless])),
- <<"shG">> = iolist_to_binary(re:replace("aB","(?-i:a)b","\\1shG",[caseless,
- global])),
- <<"OKLO">> = iolist_to_binary(re:replace("aB","((?-i:a))b","OKLO",[caseless])),
- <<"OKLO">> = iolist_to_binary(re:replace("aB","((?-i:a))b","OKLO",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?-i:a)b","DV\\1NmsJ&bJn&F",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?-i:a)b","DV\\1NmsJ&bJn&F",[caseless,
- global])),
- <<"Ab">> = iolist_to_binary(re:replace("Ab","(?-i:a)b","I",[caseless])),
- <<"Ab">> = iolist_to_binary(re:replace("Ab","(?-i:a)b","I",[caseless,
- global])),
- <<"AB">> = iolist_to_binary(re:replace("AB","(?-i:a)b","WVyTncmcNoIfn\\1B",[caseless])),
- <<"AB">> = iolist_to_binary(re:replace("AB","(?-i:a)b","WVyTncmcNoIfn\\1B",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?-i:a.))b","&UW\\1PRmJQx\\1inQ\\1o&&C",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?-i:a.))b","&UW\\1PRmJQx\\1inQ\\1o&&C",[caseless,
- global])),
- <<"AB">> = iolist_to_binary(re:replace("AB","((?-i:a.))b","xFK&bFAyoLB\\1F",[caseless])),
- <<"AB">> = iolist_to_binary(re:replace("AB","((?-i:a.))b","xFK&bFAyoLB\\1F",[caseless,
+ <<"WVjqJoaFabihXyIK">> = iolist_to_binary(re:replace("ab","(?-i:a)b","WVjqJoaF&\\1ihXy\\1IK",[caseless])),
+ <<"WVjqJoaFabihXyIK">> = iolist_to_binary(re:replace("ab","(?-i:a)b","WVjqJoaF&\\1ihXy\\1IK",[caseless,
+ global])),
+ <<"hEauHabaabI">> = iolist_to_binary(re:replace("ab","((?-i:a))b","hE\\1uH&\\1&I",[caseless])),
+ <<"hEauHabaabI">> = iolist_to_binary(re:replace("ab","((?-i:a))b","hE\\1uH&\\1&I",[caseless,
+ global])),
+ <<"PyNYkfxaBaFAYik">> = iolist_to_binary(re:replace("aB","(?-i:a)b","PyNYkfx&aFAYi\\1k",[caseless])),
+ <<"PyNYkfxaBaFAYik">> = iolist_to_binary(re:replace("aB","(?-i:a)b","PyNYkfx&aFAYi\\1k",[caseless,
+ global])),
+ <<"laBaBG">> = iolist_to_binary(re:replace("aB","((?-i:a))b","l&&G",[caseless])),
+ <<"laBaBG">> = iolist_to_binary(re:replace("aB","((?-i:a))b","l&&G",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?-i:a)b","eS\\1dn",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?-i:a)b","eS\\1dn",[caseless,
+ global])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","(?-i:a)b","MhsbM&x\\1ydTksl",[caseless])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","(?-i:a)b","MhsbM&x\\1ydTksl",[caseless,
+ global])),
+ <<"Ab">> = iolist_to_binary(re:replace("Ab","(?-i:a)b","\\1srennTK\\1qOyk&LVOv",[caseless])),
+ <<"Ab">> = iolist_to_binary(re:replace("Ab","(?-i:a)b","\\1srennTK\\1qOyk&LVOv",[caseless,
+ global])),
+ <<"JJVTKIsthgwfb">> = iolist_to_binary(re:replace("aB","(?-i:a)b","JJVTKIst\\1hgwfb",[caseless])),
+ <<"JJVTKIsthgwfb">> = iolist_to_binary(re:replace("aB","(?-i:a)b","JJVTKIst\\1hgwfb",[caseless,
+ global])),
+ <<"CyLaBaaBaFaBUQLaBYD">> = iolist_to_binary(re:replace("aB","((?-i:a))b","CyL&a&aF&UQL&YD",[caseless])),
+ <<"CyLaBaaBaFaBUQLaBYD">> = iolist_to_binary(re:replace("aB","((?-i:a))b","CyL&a&aF&UQL&YD",[caseless,
global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?-i:a)b","mWmXxiABWTMo&\\1bHX&m",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?-i:a)b","mWmXxiABWTMo&\\1bHX&m",[caseless,
+ global])),
+ <<"Ab">> = iolist_to_binary(re:replace("Ab","(?-i:a)b","KxfwWNxNB&uWywN",[caseless])),
+ <<"Ab">> = iolist_to_binary(re:replace("Ab","(?-i:a)b","KxfwWNxNB&uWywN",[caseless,
+ global])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","(?-i:a)b","FB&EbQh",[caseless])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","(?-i:a)b","FB&EbQh",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?-i:a.))b","GeHOW",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?-i:a.))b","GeHOW",[caseless,
+ global])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","((?-i:a.))b","t&\\1\\1wNwJd&umtr&\\1P&v",[caseless])),
+ <<"AB">> = iolist_to_binary(re:replace("AB","((?-i:a.))b","t&\\1\\1wNwJd&umtr&\\1P&v",[caseless,
+ global])),
<<"a
B">> = iolist_to_binary(re:replace("a
-B","((?-i:a.))b","\\1E\\1AL\\1QP",[caseless])),
+B","((?-i:a.))b","xLBhf&h",[caseless])),
<<"a
B">> = iolist_to_binary(re:replace("a
-B","((?-i:a.))b","\\1E\\1AL\\1QP",[caseless,global])),
- <<"bja
-Ba
-wRNOa
-LMvela
-w">> = iolist_to_binary(re:replace("a
-B","((?s-i:a.))b","bj&\\1wRNO\\1LMvel\\1w",[caseless])),
- <<"bja
-Ba
-wRNOa
-LMvela
-w">> = iolist_to_binary(re:replace("a
-B","((?s-i:a.))b","bj&\\1wRNO\\1LMvel\\1w",[caseless,global])),
- <<"oi">> = iolist_to_binary(re:replace("cabbbb","(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))","oi",[])),
- <<"oi">> = iolist_to_binary(re:replace("cabbbb","(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))","oi",[global])),
- <<"LPIaGAjcBB">> = iolist_to_binary(re:replace("caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))","LPIaGAjc\\1B\\1B",[])),
- <<"LPIaGAjcBB">> = iolist_to_binary(re:replace("caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))","LPIaGAjc\\1B\\1B",[global])),
- <<"Ab4abmaeqLAb4abK">> = iolist_to_binary(re:replace("Ab4ab","(ab)\\d\\1","&maeqL&K",[caseless])),
- <<"Ab4abmaeqLAb4abK">> = iolist_to_binary(re:replace("Ab4ab","(ab)\\d\\1","&maeqL&K",[caseless,
- global])),
- <<"AUMabjlQ">> = iolist_to_binary(re:replace("ab4Ab","(ab)\\d\\1","AUM\\1jlQ",[caseless])),
- <<"AUMabjlQ">> = iolist_to_binary(re:replace("ab4Ab","(ab)\\d\\1","AUM\\1jlQ",[caseless,
- global])),
- <<"XmYfoobar1234bazkhCJfoobar1234bazrE">> = iolist_to_binary(re:replace("foobar1234baz","foo\\w*\\d{4}baz","\\1\\1XmY&khCJ&rE",[])),
- <<"XmYfoobar1234bazkhCJfoobar1234bazrE">> = iolist_to_binary(re:replace("foobar1234baz","foo\\w*\\d{4}baz","\\1\\1XmY&khCJ&rE",[global])),
- <<"j">> = iolist_to_binary(re:replace("x~~","x(~~)*(?:(?:F)?)?","j",[])),
- <<"j">> = iolist_to_binary(re:replace("x~~","x(~~)*(?:(?:F)?)?","j",[global])),
- <<"dvmR">> = iolist_to_binary(re:replace("aaac","^a(?#xxx){3}c","dvmR",[])),
- <<"dvmR">> = iolist_to_binary(re:replace("aaac","^a(?#xxx){3}c","dvmR",[global])),
- <<"TcvCihggCC">> = iolist_to_binary(re:replace("aaac","^a (?#xxx) (?#yyy) {3}c","TcvCihggCC\\1",[extended])),
- <<"TcvCihggCC">> = iolist_to_binary(re:replace("aaac","^a (?#xxx) (?#yyy) {3}c","TcvCihggCC\\1",[extended,
- global])),
+B","((?-i:a.))b","xLBhf&h",[caseless,global])),
+ <<"a
+BeNa
+a
+ra
+B">> = iolist_to_binary(re:replace("a
+B","((?s-i:a.))b","&eN\\1\\1r&",[caseless])),
+ <<"a
+BeNa
+a
+ra
+B">> = iolist_to_binary(re:replace("a
+B","((?s-i:a.))b","&eN\\1\\1r&",[caseless,global])),
+ <<"xDgxGuTySBL">> = iolist_to_binary(re:replace("cabbbb","(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))","xDgxGuTySB\\1L",[])),
+ <<"xDgxGuTySBL">> = iolist_to_binary(re:replace("cabbbb","(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))","xDgxGuTySB\\1L",[global])),
+ <<"S">> = iolist_to_binary(re:replace("caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))","S",[])),
+ <<"S">> = iolist_to_binary(re:replace("caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))","S",[global])),
+ <<"oAb4abQPdAAb">> = iolist_to_binary(re:replace("Ab4ab","(ab)\\d\\1","o&QPdA\\1",[caseless])),
+ <<"oAb4abQPdAAb">> = iolist_to_binary(re:replace("Ab4ab","(ab)\\d\\1","o&QPdA\\1",[caseless,
+ global])),
+ <<"xDxHH">> = iolist_to_binary(re:replace("ab4Ab","(ab)\\d\\1","xDxHH",[caseless])),
+ <<"xDxHH">> = iolist_to_binary(re:replace("ab4Ab","(ab)\\d\\1","xDxHH",[caseless,
+ global])),
+ <<"iEooNfoobar1234bazWrIlfoobar1234baznlqjBfoobar1234bazb">> = iolist_to_binary(re:replace("foobar1234baz","foo\\w*\\d{4}baz","iEooN&WrIl&nlqjB&\\1b",[])),
+ <<"iEooNfoobar1234bazWrIlfoobar1234baznlqjBfoobar1234bazb">> = iolist_to_binary(re:replace("foobar1234baz","foo\\w*\\d{4}baz","iEooN&WrIl&nlqjB&\\1b",[global])),
+ <<"dph">> = iolist_to_binary(re:replace("x~~","x(~~)*(?:(?:F)?)?","dph",[])),
+ <<"dph">> = iolist_to_binary(re:replace("x~~","x(~~)*(?:(?:F)?)?","dph",[global])),
+ <<"aaacCaaaciHua">> = iolist_to_binary(re:replace("aaac","^a(?#xxx){3}c","&C&iHua",[])),
+ <<"aaacCaaaciHua">> = iolist_to_binary(re:replace("aaac","^a(?#xxx){3}c","&C&iHua",[global])),
ok.
run29() ->
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<![cd])b","aDLvRLT\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<![cd])b","aDLvRLT\\1",[global])),
+ <<"UkKlOLQggowaaaclFkU">> = iolist_to_binary(re:replace("aaac","^a (?#xxx) (?#yyy) {3}c","UkKlO\\1LQggow&lFkU",[extended])),
+ <<"UkKlOLQggowaaaclFkU">> = iolist_to_binary(re:replace("aaac","^a (?#xxx) (?#yyy) {3}c","UkKlO\\1LQggow&lFkU",[extended,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<![cd])b","qVEB\\1Buo",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<![cd])b","qVEB\\1Buo",[global])),
<<"B
B">> = iolist_to_binary(re:replace("B
-B","(?<![cd])b","&rX",[])),
+B","(?<![cd])b","&PINm\\1tQW&u",[])),
<<"B
B">> = iolist_to_binary(re:replace("B
-B","(?<![cd])b","&rX",[global])),
- <<"dbcb">> = iolist_to_binary(re:replace("dbcb","(?<![cd])b","RAdHe",[])),
- <<"dbcb">> = iolist_to_binary(re:replace("dbcb","(?<![cd])b","RAdHe",[global])),
- <<"dbLDvFpkRnyKFiqpapacb">> = iolist_to_binary(re:replace("dbaacb","(?<![cd])[ab]","LDvFpkRnyKFiqpap",[])),
- <<"dbLDvFpkRnyKFiqpapLDvFpkRnyKFiqpapcb">> = iolist_to_binary(re:replace("dbaacb","(?<![cd])[ab]","LDvFpkRnyKFiqpap",[global])),
- <<"dbpCgFRSanfBwdBHacb">> = iolist_to_binary(re:replace("dbaacb","(?<!(c|d))[ab]","pCgFRS&\\1nfBwdBH",[])),
- <<"dbpCgFRSanfBwdBHpCgFRSanfBwdBHcb">> = iolist_to_binary(re:replace("dbaacb","(?<!(c|d))[ab]","pCgFRS&\\1nfBwdBH",[global])),
- <<"cdaccJYb">> = iolist_to_binary(re:replace("cdaccb","(?<!cd)[ab]","J\\1Yb",[])),
- <<"cdaccJYb">> = iolist_to_binary(re:replace("cdaccb","(?<!cd)[ab]","J\\1Yb",[global])),
- <<"QQBKENcxCtDv">> = iolist_to_binary(re:replace("","^(?:a?b?)*$","\\1&QQ\\1BKENcxCtD&v",[])),
- <<"QQBKENcxCtDv">> = iolist_to_binary(re:replace("","^(?:a?b?)*$","\\1&QQ\\1BKENcxCtD&v",[global])),
- <<"EUVqGakpKtkaa">> = iolist_to_binary(re:replace("a","^(?:a?b?)*$","EUVqG&kp\\1\\1Ktk&&",[])),
- <<"EUVqGakpKtkaa">> = iolist_to_binary(re:replace("a","^(?:a?b?)*$","EUVqG&kp\\1\\1Ktk&&",[global])),
- <<"PJebYabVrwtUnyyi">> = iolist_to_binary(re:replace("ab","^(?:a?b?)*$","PJebY&Vrw\\1tUnyyi",[])),
- <<"PJebYabVrwtUnyyi">> = iolist_to_binary(re:replace("ab","^(?:a?b?)*$","PJebY&Vrw\\1tUnyyi",[global])),
- <<"TaaaaJgnBHpNaaaqW">> = iolist_to_binary(re:replace("aaa","^(?:a?b?)*$","Ta&JgnBHpN&qW",[])),
- <<"TaaaaJgnBHpNaaaqW">> = iolist_to_binary(re:replace("aaa","^(?:a?b?)*$","Ta&JgnBHpN&qW",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?:a?b?)*$","s",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?:a?b?)*$","s",[global])),
- <<"dbcb">> = iolist_to_binary(re:replace("dbcb","^(?:a?b?)*$","D",[])),
- <<"dbcb">> = iolist_to_binary(re:replace("dbcb","^(?:a?b?)*$","D",[global])),
- <<"a--">> = iolist_to_binary(re:replace("a--","^(?:a?b?)*$","xqeccmA\\1PK&\\1j\\1QcQv&",[])),
- <<"a--">> = iolist_to_binary(re:replace("a--","^(?:a?b?)*$","xqeccmA\\1PK&\\1j\\1QcQv&",[global])),
- <<"aa--">> = iolist_to_binary(re:replace("aa--","^(?:a?b?)*$","&y&JYUp&omM",[])),
- <<"aa--">> = iolist_to_binary(re:replace("aa--","^(?:a?b?)*$","&y&JYUp&omM",[global])),
- <<"suK
+B","(?<![cd])b","&PINm\\1tQW&u",[global])),
+ <<"dbcb">> = iolist_to_binary(re:replace("dbcb","(?<![cd])b","JN\\1nXQWo\\1gpGr",[])),
+ <<"dbcb">> = iolist_to_binary(re:replace("dbcb","(?<![cd])b","JN\\1nXQWo\\1gpGr",[global])),
+ <<"dbgLxFuiCCrajPsTmTacb">> = iolist_to_binary(re:replace("dbaacb","(?<![cd])[ab]","gLxFuiCCrajP\\1sTmT",[])),
+ <<"dbgLxFuiCCrajPsTmTgLxFuiCCrajPsTmTcb">> = iolist_to_binary(re:replace("dbaacb","(?<![cd])[ab]","gLxFuiCCrajP\\1sTmT",[global])),
+ <<"dbiyqEacb">> = iolist_to_binary(re:replace("dbaacb","(?<!(c|d))[ab]","iyqE",[])),
+ <<"dbiyqEiyqEcb">> = iolist_to_binary(re:replace("dbaacb","(?<!(c|d))[ab]","iyqE",[global])),
+ <<"cdaccfGWRbbyWukeN">> = iolist_to_binary(re:replace("cdaccb","(?<!cd)[ab]","\\1\\1fGWR\\1&\\1&yWukeN",[])),
+ <<"cdaccfGWRbbyWukeN">> = iolist_to_binary(re:replace("cdaccb","(?<!cd)[ab]","\\1\\1fGWR\\1&\\1&yWukeN",[global])),
+ <<"radhOoMmkTyvp">> = iolist_to_binary(re:replace("","^(?:a?b?)*$","radhO&oMmkTy&vp",[])),
+ <<"radhOoMmkTyvp">> = iolist_to_binary(re:replace("","^(?:a?b?)*$","radhO&oMmkTy&vp",[global])),
+ <<"iaraX">> = iolist_to_binary(re:replace("a","^(?:a?b?)*$","i&r&X",[])),
+ <<"iaraX">> = iolist_to_binary(re:replace("a","^(?:a?b?)*$","i&r&X",[global])),
+ <<"uvabababcGDFD">> = iolist_to_binary(re:replace("ab","^(?:a?b?)*$","uv&&&cGDFD",[])),
+ <<"uvabababcGDFD">> = iolist_to_binary(re:replace("ab","^(?:a?b?)*$","uv&&&cGDFD",[global])),
+ <<"aaawlwIRsqaaallaaaAnaaaBraaa">> = iolist_to_binary(re:replace("aaa","^(?:a?b?)*$","&wlwIRsq&ll\\1&An&B\\1r&",[])),
+ <<"aaawlwIRsqaaallaaaAnaaaBraaa">> = iolist_to_binary(re:replace("aaa","^(?:a?b?)*$","&wlwIRsq&ll\\1&An&B\\1r&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?:a?b?)*$","HQDGKPOboFhEDT&FLu&D",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?:a?b?)*$","HQDGKPOboFhEDT&FLu&D",[global])),
+ <<"dbcb">> = iolist_to_binary(re:replace("dbcb","^(?:a?b?)*$","dWU\\1&MLWjnDLY\\1\\1M",[])),
+ <<"dbcb">> = iolist_to_binary(re:replace("dbcb","^(?:a?b?)*$","dWU\\1&MLWjnDLY\\1\\1M",[global])),
+ <<"a--">> = iolist_to_binary(re:replace("a--","^(?:a?b?)*$","\\1&KaprjNw&yXkKe",[])),
+ <<"a--">> = iolist_to_binary(re:replace("a--","^(?:a?b?)*$","\\1&KaprjNw&yXkKe",[global])),
+ <<"aa--">> = iolist_to_binary(re:replace("aa--","^(?:a?b?)*$","Rr&FlU",[])),
+ <<"aa--">> = iolist_to_binary(re:replace("aa--","^(?:a?b?)*$","Rr&FlU",[global])),
+ <<"Ta
+ba
+Bkga
+bx
c">> = iolist_to_binary(re:replace("a
b
-c","((?s)^a(.))((?m)^b$)","suK",[])),
- <<"suK
+c","((?s)^a(.))((?m)^b$)","T&\\1Bkg&x",[])),
+ <<"Ta
+ba
+Bkga
+bx
c">> = iolist_to_binary(re:replace("a
b
-c","((?s)^a(.))((?m)^b$)","suK",[global])),
+c","((?s)^a(.))((?m)^b$)","T&\\1Bkg&x",[global])),
<<"a
-bsbrmbHobdxBbb
+fRyiaWcebhcY
c">> = iolist_to_binary(re:replace("a
b
-c","((?m)^b$)","\\1s&rm\\1Ho&dxB&\\1",[])),
+c","((?m)^b$)","fRyiaWce&hcY",[])),
<<"a
-bsbrmbHobdxBbb
+fRyiaWcebhcY
c">> = iolist_to_binary(re:replace("a
b
-c","((?m)^b$)","\\1s&rm\\1Ho&dxB&\\1",[global])),
+c","((?m)^b$)","fRyiaWce&hcY",[global])),
<<"a
-DbLxnGxIyQMiaCJKYa">> = iolist_to_binary(re:replace("a
-b","(?m)^b","D&LxnGxIyQMiaCJKYa\\1",[])),
+j">> = iolist_to_binary(re:replace("a
+b","(?m)^b","j\\1",[])),
<<"a
-DbLxnGxIyQMiaCJKYa">> = iolist_to_binary(re:replace("a
-b","(?m)^b","D&LxnGxIyQMiaCJKYa\\1",[global])),
+j">> = iolist_to_binary(re:replace("a
+b","(?m)^b","j\\1",[global])),
<<"a
-TbTgrAWgAV">> = iolist_to_binary(re:replace("a
-b","(?m)^(b)","T\\1TgrAWgAV",[])),
+tbDLKbpbbqBbWXNbjBU">> = iolist_to_binary(re:replace("a
+b","(?m)^(b)","t\\1DLK\\1p&\\1qB\\1WXNbjBU",[])),
<<"a
-TbTgrAWgAV">> = iolist_to_binary(re:replace("a
-b","(?m)^(b)","T\\1TgrAWgAV",[global])),
+tbDLKbpbbqBbWXNbjBU">> = iolist_to_binary(re:replace("a
+b","(?m)^(b)","t\\1DLK\\1p&\\1qB\\1WXNbjBU",[global])),
<<"a
-KvbbbEUIbCFmvpdpI">> = iolist_to_binary(re:replace("a
-b","((?m)^b)","Kv\\1&&EUI&CFmvpdpI",[])),
+hJUkbQmbMMdabmm">> = iolist_to_binary(re:replace("a
+b","((?m)^b)","hJUk&Qm\\1MMda&mm",[])),
<<"a
-KvbbbEUIbCFmvpdpI">> = iolist_to_binary(re:replace("a
-b","((?m)^b)","Kv\\1&&EUI&CFmvpdpI",[global])),
- <<"amFIqrSY
-bYBDTRTmIb">> = iolist_to_binary(re:replace("a
-b","\\n((?m)^b)","mFIqrSY&YBDTRTmI\\1",[])),
- <<"amFIqrSY
-bYBDTRTmIb">> = iolist_to_binary(re:replace("a
-b","\\n((?m)^b)","mFIqrSY&YBDTRTmI\\1",[global])),
+hJUkbQmbMMdabmm">> = iolist_to_binary(re:replace("a
+b","((?m)^b)","hJUk&Qm\\1MMda&mm",[global])),
+ <<"ad">> = iolist_to_binary(re:replace("a
+b","\\n((?m)^b)","d",[])),
+ <<"ad">> = iolist_to_binary(re:replace("a
+b","\\n((?m)^b)","d",[global])),
<<"a
-bGyvT
-WAEIfT
-">> = iolist_to_binary(re:replace("a
+bu">> = iolist_to_binary(re:replace("a
b
-c","((?s).)c(?!.)","GyvT\\1WAEIfT\\1",[])),
+c","((?s).)c(?!.)","u",[])),
<<"a
-bGyvT
-WAEIfT
-">> = iolist_to_binary(re:replace("a
+bu">> = iolist_to_binary(re:replace("a
b
-c","((?s).)c(?!.)","GyvT\\1WAEIfT\\1",[global])),
+c","((?s).)c(?!.)","u",[global])),
<<"a
-bu
-
-ciY
-ONSatC
-q
-cgqg">> = iolist_to_binary(re:replace("a
+bpB">> = iolist_to_binary(re:replace("a
b
-c","((?s).)c(?!.)","u\\1&iY\\1ONSatC\\1q&gqg",[])),
+c","((?s).)c(?!.)","pB",[])),
<<"a
-bu
-
-ciY
-ONSatC
-q
-cgqg">> = iolist_to_binary(re:replace("a
+bpB">> = iolist_to_binary(re:replace("a
b
-c","((?s).)c(?!.)","u\\1&iY\\1ONSatC\\1q&gqg",[global])),
+c","((?s).)c(?!.)","pB",[global])),
<<"a
-EaHhNb
-cc">> = iolist_to_binary(re:replace("a
b
-c","((?s)b.)c(?!.)","EaHhN&c",[])),
+cIe">> = iolist_to_binary(re:replace("a
+b
+c","((?s)b.)c(?!.)","&Ie",[])),
<<"a
-EaHhNb
-cc">> = iolist_to_binary(re:replace("a
b
-c","((?s)b.)c(?!.)","EaHhN&c",[global])),
+cIe">> = iolist_to_binary(re:replace("a
+b
+c","((?s)b.)c(?!.)","&Ie",[global])),
<<"a
-Qyf">> = iolist_to_binary(re:replace("a
+sqb
+">> = iolist_to_binary(re:replace("a
b
-c","((?s)b.)c(?!.)","Qyf",[])),
+c","((?s)b.)c(?!.)","sq\\1",[])),
<<"a
-Qyf">> = iolist_to_binary(re:replace("a
+sqb
+">> = iolist_to_binary(re:replace("a
b
-c","((?s)b.)c(?!.)","Qyf",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","()^b","uPupHDfyOM",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","()^b","uPupHDfyOM",[global])),
+c","((?s)b.)c(?!.)","sq\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","()^b","ov",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","()^b","ov",[global])),
<<"a
b
c">> = iolist_to_binary(re:replace("a
b
-c","()^b","ie",[])),
+c","()^b","uMvMIoSdSSJ",[])),
<<"a
b
c">> = iolist_to_binary(re:replace("a
b
-c","()^b","ie",[global])),
+c","()^b","uMvMIoSdSSJ",[global])),
<<"a
b
c">> = iolist_to_binary(re:replace("a
b
-c","()^b","XOjtYTE&",[])),
+c","()^b","CWpw",[])),
<<"a
b
c">> = iolist_to_binary(re:replace("a
b
-c","()^b","XOjtYTE&",[global])),
+c","()^b","CWpw",[global])),
<<"a
-up
+VJbfDbMGQCbssq
c">> = iolist_to_binary(re:replace("a
b
-c","((?m)^b)","up",[])),
+c","((?m)^b)","VJ&fD&MGQC&ssq",[])),
<<"a
-up
+VJbfDbMGQCbssq
c">> = iolist_to_binary(re:replace("a
b
-c","((?m)^b)","up",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(x)?(?(1)a|b)","Q&VpBvd&HCANVl",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(x)?(?(1)a|b)","Q&VpBvd&HCANVl",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","(x)?(?(1)a|b)","PJENMvR\\1&\\1nkq\\1j&P&",[])),
- <<"a">> = iolist_to_binary(re:replace("a","(x)?(?(1)a|b)","PJENMvR\\1&\\1nkq\\1j&P&",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","(x)?(?(1)a|b)","hStdV\\1o",[])),
- <<"a">> = iolist_to_binary(re:replace("a","(x)?(?(1)a|b)","hStdV\\1o",[global])),
- <<"bpiiYpjmbL">> = iolist_to_binary(re:replace("a","(x)?(?(1)b|a)","bpiiYpjmbL",[])),
- <<"bpiiYpjmbL">> = iolist_to_binary(re:replace("a","(x)?(?(1)b|a)","bpiiYpjmbL",[global])),
- <<"ldpcm">> = iolist_to_binary(re:replace("a","()?(?(1)b|a)","ldpc\\1m",[])),
- <<"ldpcm">> = iolist_to_binary(re:replace("a","()?(?(1)b|a)","ldpc\\1m",[global])),
+c","((?m)^b)","VJ&fD&MGQC&ssq",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(x)?(?(1)a|b)","LNqS&m",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(x)?(?(1)a|b)","LNqS&m",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","(x)?(?(1)a|b)","OkYauyNGxeWuW\\1\\1&MWr",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","(x)?(?(1)a|b)","OkYauyNGxeWuW\\1\\1&MWr",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","(x)?(?(1)a|b)","scDk\\1nM",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","(x)?(?(1)a|b)","scDk\\1nM",[global])),
+ <<"YcA">> = iolist_to_binary(re:replace("a","(x)?(?(1)b|a)","\\1YcA",[])),
+ <<"YcA">> = iolist_to_binary(re:replace("a","(x)?(?(1)b|a)","\\1YcA",[global])),
ok.
run30() ->
- <<"XVaoQoPYY">> = iolist_to_binary(re:replace("a","()?(?(1)a|b)","\\1X\\1V&oQoPYY",[])),
- <<"XVaoQoPYY">> = iolist_to_binary(re:replace("a","()?(?(1)a|b)","\\1X\\1V&oQoPYY",[global])),
- <<"NIfcW(blah)G">> = iolist_to_binary(re:replace("(blah)","^(\\()?blah(?(1)(\\)))$","NIfcW&G",[])),
- <<"NIfcW(blah)G">> = iolist_to_binary(re:replace("(blah)","^(\\()?blah(?(1)(\\)))$","NIfcW&G",[global])),
- <<"pnblahSJOoELoLblah">> = iolist_to_binary(re:replace("blah","^(\\()?blah(?(1)(\\)))$","pn&SJOoELoL&",[])),
- <<"pnblahSJOoELoLblah">> = iolist_to_binary(re:replace("blah","^(\\()?blah(?(1)(\\)))$","pn&SJOoELoL&",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\()?blah(?(1)(\\)))$","&qo&jitI",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\()?blah(?(1)(\\)))$","&qo&jitI",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","^(\\()?blah(?(1)(\\)))$","nvEsX\\1dtIq",[])),
- <<"a">> = iolist_to_binary(re:replace("a","^(\\()?blah(?(1)(\\)))$","nvEsX\\1dtIq",[global])),
- <<"blah)">> = iolist_to_binary(re:replace("blah)","^(\\()?blah(?(1)(\\)))$","QkLbrxtPSiEFXY",[])),
- <<"blah)">> = iolist_to_binary(re:replace("blah)","^(\\()?blah(?(1)(\\)))$","QkLbrxtPSiEFXY",[global])),
- <<"(blah">> = iolist_to_binary(re:replace("(blah","^(\\()?blah(?(1)(\\)))$","lAP",[])),
- <<"(blah">> = iolist_to_binary(re:replace("(blah","^(\\()?blah(?(1)(\\)))$","lAP",[global])),
- <<"(LsJwkbg(bfkt(NulbXR">> = iolist_to_binary(re:replace("(blah)","^(\\(+)?blah(?(1)(\\)))$","\\1LsJwkbg\\1bfkt\\1NulbXR",[])),
- <<"(LsJwkbg(bfkt(NulbXR">> = iolist_to_binary(re:replace("(blah)","^(\\(+)?blah(?(1)(\\)))$","\\1LsJwkbg\\1bfkt\\1NulbXR",[global])),
- <<"d">> = iolist_to_binary(re:replace("blah","^(\\(+)?blah(?(1)(\\)))$","\\1d",[])),
- <<"d">> = iolist_to_binary(re:replace("blah","^(\\(+)?blah(?(1)(\\)))$","\\1d",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\(+)?blah(?(1)(\\)))$","EMgTAXywJ\\1sx",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\(+)?blah(?(1)(\\)))$","EMgTAXywJ\\1sx",[global])),
- <<"blah)">> = iolist_to_binary(re:replace("blah)","^(\\(+)?blah(?(1)(\\)))$","LdpE",[])),
- <<"blah)">> = iolist_to_binary(re:replace("blah)","^(\\(+)?blah(?(1)(\\)))$","LdpE",[global])),
- <<"(blah">> = iolist_to_binary(re:replace("(blah","^(\\(+)?blah(?(1)(\\)))$","x",[])),
- <<"(blah">> = iolist_to_binary(re:replace("(blah","^(\\(+)?blah(?(1)(\\)))$","x",[global])),
- <<"DTG">> = iolist_to_binary(re:replace("a","(?(?!a)b|a)","DT\\1G\\1",[])),
- <<"DTG">> = iolist_to_binary(re:replace("a","(?(?!a)b|a)","DT\\1G\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?=a)b|a)","d\\1lnf&YLYNM",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?=a)b|a)","d\\1lnf&YLYNM",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","(?(?=a)b|a)","\\1SGC\\1&hP&OBDNrG",[])),
- <<"a">> = iolist_to_binary(re:replace("a","(?(?=a)b|a)","\\1SGC\\1&hP&OBDNrG",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","(?(?=a)b|a)","\\1O",[])),
- <<"a">> = iolist_to_binary(re:replace("a","(?(?=a)b|a)","\\1O",[global])),
- <<"ToKaPapJTYo">> = iolist_to_binary(re:replace("a","(?(?=a)a|b)","\\1ToKaP&pJTYo",[])),
- <<"ToKaPapJTYo">> = iolist_to_binary(re:replace("a","(?(?=a)a|b)","\\1ToKaP&pJTYo",[global])),
- <<"aaYfA">> = iolist_to_binary(re:replace("aaab","(?=(a+?))(\\1ab)","\\1YfA",[])),
- <<"aaYfA">> = iolist_to_binary(re:replace("aaab","(?=(a+?))(\\1ab)","\\1YfA",[global])),
- <<"Oone:LVumwJGPxKone:">> = iolist_to_binary(re:replace("one:","(\\w+:)+","O&LVumwJGPxK\\1",[])),
- <<"Oone:LVumwJGPxKone:">> = iolist_to_binary(re:replace("one:","(\\w+:)+","O&LVumwJGPxK\\1",[global])),
- <<"axOGBQtmfLikDGlXSft">> = iolist_to_binary(re:replace("a","$(?<=^(a))","xOGBQtmfLikDGlXSft",[])),
- <<"axOGBQtmfLikDGlXSft">> = iolist_to_binary(re:replace("a","$(?<=^(a))","xOGBQtmfLikDGlXSft",[global])),
- <<"auQKtSaabLmmqtekWvRQaWJ">> = iolist_to_binary(re:replace("aaab","(?=(a+?))(\\1ab)","uQKtS&LmmqtekWvRQ\\1WJ",[])),
- <<"auQKtSaabLmmqtekWvRQaWJ">> = iolist_to_binary(re:replace("aaab","(?=(a+?))(\\1ab)","uQKtS&LmmqtekWvRQ\\1WJ",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?=(a+?))\\1ab","&&USoct\\1R",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?=(a+?))\\1ab","&&USoct\\1R",[global])),
- <<"aaab">> = iolist_to_binary(re:replace("aaab","^(?=(a+?))\\1ab","nNyoTw&TuS\\1oXos",[])),
- <<"aaab">> = iolist_to_binary(re:replace("aaab","^(?=(a+?))\\1ab","nNyoTw&TuS\\1oXos",[global])),
- <<"aaab">> = iolist_to_binary(re:replace("aaab","^(?=(a+?))\\1ab","MAutXFUx",[])),
- <<"aaab">> = iolist_to_binary(re:replace("aaab","^(?=(a+?))\\1ab","MAutXFUx",[global])),
- <<"cXabcdPLyeVVq">> = iolist_to_binary(re:replace("abcd","([\\w:]+::)?(\\w+)$","c\\1X&\\1PLyeV\\1Vq",[])),
- <<"cXabcdPLyeVVq">> = iolist_to_binary(re:replace("abcd","([\\w:]+::)?(\\w+)$","c\\1X&\\1PLyeV\\1Vq",[global])),
- <<"jxy:z:::abcdYDxy:z:::Ixy:z:::abcdA">> = iolist_to_binary(re:replace("xy:z:::abcd","([\\w:]+::)?(\\w+)$","j&YD\\1I&A",[])),
- <<"jxy:z:::abcdYDxy:z:::Ixy:z:::abcdA">> = iolist_to_binary(re:replace("xy:z:::abcd","([\\w:]+::)?(\\w+)$","j&YD\\1I&A",[global])),
- <<"IbkqaaexycIVtbd">> = iolist_to_binary(re:replace("aexycd","^[^bcd]*(c+)","Ibkqa&IVtb",[])),
- <<"IbkqaaexycIVtbd">> = iolist_to_binary(re:replace("aexycd","^[^bcd]*(c+)","Ibkqa&IVtb",[global])),
- <<"cSLuXFBaavfbUaahyxuWowk">> = iolist_to_binary(re:replace("caab","(a*)b+","SLuXFB\\1vfbU\\1hyxuWowk",[])),
- <<"cSLuXFBaavfbUaahyxuWowk">> = iolist_to_binary(re:replace("caab","(a*)b+","SLuXFB\\1vfbU\\1hyxuWowk",[global])),
- <<"n">> = iolist_to_binary(re:replace("abcd","([\\w:]+::)?(\\w+)$","n",[])),
- <<"n">> = iolist_to_binary(re:replace("abcd","([\\w:]+::)?(\\w+)$","n",[global])),
- <<"xy:z:::abcdSfCyKxy:z:::abcdxy:z:::rOIxy:z:::qaXJV">> = iolist_to_binary(re:replace("xy:z:::abcd","([\\w:]+::)?(\\w+)$","&SfCyK&\\1rOI\\1qaXJV",[])),
- <<"xy:z:::abcdSfCyKxy:z:::abcdxy:z:::rOIxy:z:::qaXJV">> = iolist_to_binary(re:replace("xy:z:::abcd","([\\w:]+::)?(\\w+)$","&SfCyK&\\1rOI\\1qaXJV",[global])),
- <<"*** FDIubo">> = iolist_to_binary(re:replace("*** Failers","([\\w:]+::)?(\\w+)$","FDIubo",[])),
- <<"*** FDIubo">> = iolist_to_binary(re:replace("*** Failers","([\\w:]+::)?(\\w+)$","FDIubo",[global])),
- <<"abcd:">> = iolist_to_binary(re:replace("abcd:","([\\w:]+::)?(\\w+)$","\\1\\1FqKhObWFBLnW",[])),
- <<"abcd:">> = iolist_to_binary(re:replace("abcd:","([\\w:]+::)?(\\w+)$","\\1\\1FqKhObWFBLnW",[global])),
- <<"abcd:">> = iolist_to_binary(re:replace("abcd:","([\\w:]+::)?(\\w+)$","\\1\\1\\1JSX&vwHeWnyicJH",[])),
- <<"abcd:">> = iolist_to_binary(re:replace("abcd:","([\\w:]+::)?(\\w+)$","\\1\\1\\1JSX&vwHeWnyicJH",[global])),
- <<"bsuraexycHejcJAclcd">> = iolist_to_binary(re:replace("aexycd","^[^bcd]*(c+)","bsur&HejcJA\\1l\\1",[])),
- <<"bsuraexycHejcJAclcd">> = iolist_to_binary(re:replace("aexycd","^[^bcd]*(c+)","bsur&HejcJA\\1l\\1",[global])),
+ <<"xNapUFFvOIj">> = iolist_to_binary(re:replace("a","()?(?(1)b|a)","xN&pU\\1FFvOIj",[])),
+ <<"xNapUFFvOIj">> = iolist_to_binary(re:replace("a","()?(?(1)b|a)","xN&pU\\1FFvOIj",[global])),
+ <<"XuaPbWvaWaalBtsa">> = iolist_to_binary(re:replace("a","()?(?(1)a|b)","Xu&PbWv&W&&lBts&",[])),
+ <<"XuaPbWvaWaalBtsa">> = iolist_to_binary(re:replace("a","()?(?(1)a|b)","Xu&PbWv&W&&lBts&",[global])),
+ <<"(fyCFuvHU((puIwItIx(">> = iolist_to_binary(re:replace("(blah)","^(\\()?blah(?(1)(\\)))$","\\1fyCFuvHU\\1\\1puIwItIx\\1",[])),
+ <<"(fyCFuvHU((puIwItIx(">> = iolist_to_binary(re:replace("(blah)","^(\\()?blah(?(1)(\\)))$","\\1fyCFuvHU\\1\\1puIwItIx\\1",[global])),
+ <<"AyRblahEPvK">> = iolist_to_binary(re:replace("blah","^(\\()?blah(?(1)(\\)))$","AyR&EPvK",[])),
+ <<"AyRblahEPvK">> = iolist_to_binary(re:replace("blah","^(\\()?blah(?(1)(\\)))$","AyR&EPvK",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\()?blah(?(1)(\\)))$","SbDcblGvpFYoX&J&Gu",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\()?blah(?(1)(\\)))$","SbDcblGvpFYoX&J&Gu",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","^(\\()?blah(?(1)(\\)))$","&m",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","^(\\()?blah(?(1)(\\)))$","&m",[global])),
+ <<"blah)">> = iolist_to_binary(re:replace("blah)","^(\\()?blah(?(1)(\\)))$","k\\1",[])),
+ <<"blah)">> = iolist_to_binary(re:replace("blah)","^(\\()?blah(?(1)(\\)))$","k\\1",[global])),
+ <<"(blah">> = iolist_to_binary(re:replace("(blah","^(\\()?blah(?(1)(\\)))$","BufqWrp\\1\\1UijV",[])),
+ <<"(blah">> = iolist_to_binary(re:replace("(blah","^(\\()?blah(?(1)(\\)))$","BufqWrp\\1\\1UijV",[global])),
+ <<"pIOc(eAW(">> = iolist_to_binary(re:replace("(blah)","^(\\(+)?blah(?(1)(\\)))$","pIOc\\1eAW\\1",[])),
+ <<"pIOc(eAW(">> = iolist_to_binary(re:replace("(blah)","^(\\(+)?blah(?(1)(\\)))$","pIOc\\1eAW\\1",[global])),
+ <<"p">> = iolist_to_binary(re:replace("blah","^(\\(+)?blah(?(1)(\\)))$","p",[])),
+ <<"p">> = iolist_to_binary(re:replace("blah","^(\\(+)?blah(?(1)(\\)))$","p",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\(+)?blah(?(1)(\\)))$","y&&&AOp\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\(+)?blah(?(1)(\\)))$","y&&&AOp\\1",[global])),
+ <<"blah)">> = iolist_to_binary(re:replace("blah)","^(\\(+)?blah(?(1)(\\)))$","\\1VJMcD\\1vw&NweMFm",[])),
+ <<"blah)">> = iolist_to_binary(re:replace("blah)","^(\\(+)?blah(?(1)(\\)))$","\\1VJMcD\\1vw&NweMFm",[global])),
+ <<"(blah">> = iolist_to_binary(re:replace("(blah","^(\\(+)?blah(?(1)(\\)))$","nmpAKxmhP\\1VH\\1DE\\1",[])),
+ <<"(blah">> = iolist_to_binary(re:replace("(blah","^(\\(+)?blah(?(1)(\\)))$","nmpAKxmhP\\1VH\\1DE\\1",[global])),
+ <<"sVrnWeaaBWqoEe">> = iolist_to_binary(re:replace("a","(?(?!a)b|a)","sVrnWea&BWqoE\\1e\\1",[])),
+ <<"sVrnWeaaBWqoEe">> = iolist_to_binary(re:replace("a","(?(?!a)b|a)","sVrnWea&BWqoE\\1e\\1",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?=a)b|a)","yKlwaKvFuDaY&",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?(?=a)b|a)","yKlwaKvFuDaY&",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","(?(?=a)b|a)","a&xlo",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","(?(?=a)b|a)","a&xlo",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","(?(?=a)b|a)","HA\\1fUFNxI",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","(?(?=a)b|a)","HA\\1fUFNxI",[global])),
+ <<"UTGiYaXaqADaSaxgaG">> = iolist_to_binary(re:replace("a","(?(?=a)a|b)","UTGiY&\\1X&qAD\\1&S&xgaG",[])),
+ <<"UTGiYaXaqADaSaxgaG">> = iolist_to_binary(re:replace("a","(?(?=a)a|b)","UTGiY&\\1X&qAD\\1&S&xgaG",[global])),
+ <<"aTjaOYiTQLgjuOn">> = iolist_to_binary(re:replace("aaab","(?=(a+?))(\\1ab)","Tj\\1OYiTQLgjuOn",[])),
+ <<"aTjaOYiTQLgjuOn">> = iolist_to_binary(re:replace("aaab","(?=(a+?))(\\1ab)","Tj\\1OYiTQLgjuOn",[global])),
+ <<"one:Yone:hI">> = iolist_to_binary(re:replace("one:","(\\w+:)+","&Y&hI",[])),
+ <<"one:Yone:hI">> = iolist_to_binary(re:replace("one:","(\\w+:)+","&Y&hI",[global])),
+ <<"aJdMoadBqra">> = iolist_to_binary(re:replace("a","$(?<=^(a))","JdMo\\1&dBqr&\\1",[])),
+ <<"aJdMoadBqra">> = iolist_to_binary(re:replace("a","$(?<=^(a))","JdMo\\1&dBqr&\\1",[global])),
+ <<"aRayaTFQFN">> = iolist_to_binary(re:replace("aaab","(?=(a+?))(\\1ab)","R\\1yaTFQFN",[])),
+ <<"aRayaTFQFN">> = iolist_to_binary(re:replace("aaab","(?=(a+?))(\\1ab)","R\\1yaTFQFN",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?=(a+?))\\1ab","w",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?=(a+?))\\1ab","w",[global])),
+ <<"aaab">> = iolist_to_binary(re:replace("aaab","^(?=(a+?))\\1ab","TAs",[])),
+ <<"aaab">> = iolist_to_binary(re:replace("aaab","^(?=(a+?))\\1ab","TAs",[global])),
+ <<"aaab">> = iolist_to_binary(re:replace("aaab","^(?=(a+?))\\1ab","gObuYj\\1f\\1&Y\\1&\\1",[])),
+ <<"aaab">> = iolist_to_binary(re:replace("aaab","^(?=(a+?))\\1ab","gObuYj\\1f\\1&Y\\1&\\1",[global])),
+ <<"WqUamivVmXabcdLd">> = iolist_to_binary(re:replace("abcd","([\\w:]+::)?(\\w+)$","W\\1qUamiv\\1V\\1mX&Ld",[])),
+ <<"WqUamivVmXabcdLd">> = iolist_to_binary(re:replace("abcd","([\\w:]+::)?(\\w+)$","W\\1qUamiv\\1V\\1mX&Ld",[global])),
+ <<"Ixy:z:::abcdxy:z:::abcdnxy:z:::xy:z:::abcdbsHvXRBC">> = iolist_to_binary(re:replace("xy:z:::abcd","([\\w:]+::)?(\\w+)$","I&&n\\1&bsHvXRBC",[])),
+ <<"Ixy:z:::abcdxy:z:::abcdnxy:z:::xy:z:::abcdbsHvXRBC">> = iolist_to_binary(re:replace("xy:z:::abcd","([\\w:]+::)?(\\w+)$","I&&n\\1&bsHvXRBC",[global])),
+ <<"Xd">> = iolist_to_binary(re:replace("aexycd","^[^bcd]*(c+)","X",[])),
+ <<"Xd">> = iolist_to_binary(re:replace("aexycd","^[^bcd]*(c+)","X",[global])),
+ <<"cxqAaaeaabaaLWaaaaQJTaaaaxG">> = iolist_to_binary(re:replace("caab","(a*)b+","xqA\\1e&\\1LW\\1\\1QJT\\1\\1xG",[])),
+ <<"cxqAaaeaabaaLWaaaaQJTaaaaxG">> = iolist_to_binary(re:replace("caab","(a*)b+","xqA\\1e&\\1LW\\1\\1QJT\\1\\1xG",[global])),
+ <<"PabcdoXTDiScdQabcdE">> = iolist_to_binary(re:replace("abcd","([\\w:]+::)?(\\w+)$","P&\\1o\\1XTDiScdQ&E",[])),
+ <<"PabcdoXTDiScdQabcdE">> = iolist_to_binary(re:replace("abcd","([\\w:]+::)?(\\w+)$","P&\\1o\\1XTDiScdQ&E",[global])),
+ <<"ltxy:z:::abcdOkVmTnmtexy:z:::MMY">> = iolist_to_binary(re:replace("xy:z:::abcd","([\\w:]+::)?(\\w+)$","lt&OkVmTnmte\\1MMY",[])),
+ <<"ltxy:z:::abcdOkVmTnmtexy:z:::MMY">> = iolist_to_binary(re:replace("xy:z:::abcd","([\\w:]+::)?(\\w+)$","lt&OkVmTnmte\\1MMY",[global])),
+ <<"*** hdDdHBCKXpUraMooFailersFailersW">> = iolist_to_binary(re:replace("*** Failers","([\\w:]+::)?(\\w+)$","hdDdHBCKXpUraMoo&\\1&W",[])),
+ <<"*** hdDdHBCKXpUraMooFailersFailersW">> = iolist_to_binary(re:replace("*** Failers","([\\w:]+::)?(\\w+)$","hdDdHBCKXpUraMoo&\\1&W",[global])),
+ <<"abcd:">> = iolist_to_binary(re:replace("abcd:","([\\w:]+::)?(\\w+)$","W&CE",[])),
+ <<"abcd:">> = iolist_to_binary(re:replace("abcd:","([\\w:]+::)?(\\w+)$","W&CE",[global])),
+ <<"abcd:">> = iolist_to_binary(re:replace("abcd:","([\\w:]+::)?(\\w+)$","HS&xAXhj\\1&h\\1oJanfg",[])),
+ <<"abcd:">> = iolist_to_binary(re:replace("abcd:","([\\w:]+::)?(\\w+)$","HS&xAXhj\\1&h\\1oJanfg",[global])),
+ <<"gncfaexycKcgd">> = iolist_to_binary(re:replace("aexycd","^[^bcd]*(c+)","gn\\1f&K\\1g",[])),
+ <<"gncfaexycKcgd">> = iolist_to_binary(re:replace("aexycd","^[^bcd]*(c+)","gn\\1f&K\\1g",[global])),
ok.
run31() ->
- <<"C">> = iolist_to_binary(re:replace("aaab","(?>a+)b","\\1C",[])),
- <<"C">> = iolist_to_binary(re:replace("aaab","(?>a+)b","\\1C",[global])),
- <<"aNO:[pGn:[:[Hb]:">> = iolist_to_binary(re:replace("a:[b]:","([[:]+)","NO\\1pGn&\\1H",[])),
- <<"aNO:[pGn:[:[Hb]NO:pGn::H">> = iolist_to_binary(re:replace("a:[b]:","([[:]+)","NO\\1pGn&\\1H",[global])),
- <<"aUSAUCBri=[uNyXKFxsgAib]=">> = iolist_to_binary(re:replace("a=[b]=","([[=]+)","USAUCBri&uNyXKFxsgAi",[])),
- <<"aUSAUCBri=[uNyXKFxsgAib]USAUCBri=uNyXKFxsgAi">> = iolist_to_binary(re:replace("a=[b]=","([[=]+)","USAUCBri&uNyXKFxsgAi",[global])),
- <<"alNmxCu.[.[iUB.[.[b].">> = iolist_to_binary(re:replace("a.[b].","([[.]+)","lNmxCu&&iUB&\\1",[])),
- <<"alNmxCu.[.[iUB.[.[b]lNmxCu..iUB..">> = iolist_to_binary(re:replace("a.[b].","([[.]+)","lNmxCu&&iUB&\\1",[global])),
- <<"gGaaab">> = iolist_to_binary(re:replace("aaab","((?>a+)b)","gG&",[])),
- <<"gGaaab">> = iolist_to_binary(re:replace("aaab","((?>a+)b)","gG&",[global])),
- <<"XaaaSaaaFUaaabJnaaabMCaaabedCQAgh">> = iolist_to_binary(re:replace("aaab","(?>(a+))b","X\\1S\\1FU&Jn&MC&edCQAgh",[])),
- <<"XaaaSaaaFUaaabJnaaabMCaaabedCQAgh">> = iolist_to_binary(re:replace("aaab","(?>(a+))b","X\\1S\\1FU&Jn&MC&edCQAgh",[global])),
- <<"((nxgvJb">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+","n\\1gvJb",[])),
- <<"((nxgvJb">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+","n\\1gvJb",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a\\Z","dnHcIc\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a\\Z","dnHcIc\\1",[global])),
- <<"aaab">> = iolist_to_binary(re:replace("aaab","a\\Z","TMH",[])),
- <<"aaab">> = iolist_to_binary(re:replace("aaab","a\\Z","TMH",[global])),
+ <<"dIgTpbIaaabHEixaaaby">> = iolist_to_binary(re:replace("aaab","(?>a+)b","dI\\1gTpbI&HEix&y",[])),
+ <<"dIgTpbIaaabHEixaaaby">> = iolist_to_binary(re:replace("aaab","(?>a+)b","dI\\1gTpbI&HEix&y",[global])),
+ <<"a:[xKoXTWDN:[:[P:[b]:">> = iolist_to_binary(re:replace("a:[b]:","([[:]+)","&xKoXTWDN\\1\\1P\\1",[])),
+ <<"a:[xKoXTWDN:[:[P:[b]:xKoXTWDN::P:">> = iolist_to_binary(re:replace("a:[b]:","([[:]+)","&xKoXTWDN\\1\\1P\\1",[global])),
+ <<"a=[b]=">> = iolist_to_binary(re:replace("a=[b]=","([[=]+)","\\1",[])),
+ <<"a=[b]=">> = iolist_to_binary(re:replace("a=[b]=","([[=]+)","\\1",[global])),
+ <<"aAULOvS.[q.[cI.[O.[K.[WMIpb].">> = iolist_to_binary(re:replace("a.[b].","([[.]+)","AULOvS&q\\1cI\\1O&K&WMIp",[])),
+ <<"aAULOvS.[q.[cI.[O.[K.[WMIpb]AULOvS.q.cI.O.K.WMIp">> = iolist_to_binary(re:replace("a.[b].","([[.]+)","AULOvS&q\\1cI\\1O&K&WMIp",[global])),
+ <<"tkaYMfUUpaaabHTyQAreKh">> = iolist_to_binary(re:replace("aaab","((?>a+)b)","tkaYMfUUp&HTyQAreKh",[])),
+ <<"tkaYMfUUpaaabHTyQAreKh">> = iolist_to_binary(re:replace("aaab","((?>a+)b)","tkaYMfUUp&HTyQAreKh",[global])),
+ <<"EHaaaGtlKGyaaaEAaaaaaahAK">> = iolist_to_binary(re:replace("aaab","(?>(a+))b","EH\\1GtlKGy\\1EA\\1\\1hAK",[])),
+ <<"EHaaaGtlKGyaaaEAaaaaaahAK">> = iolist_to_binary(re:replace("aaab","(?>(a+))b","EH\\1GtlKGy\\1EA\\1\\1hAK",[global])),
+ <<"((GwfYxOabc(ade)ufh()()xW">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+","GwfY\\1O&W",[])),
+ <<"((GwfYxOabc(ade)ufh()()xW">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","((?>[^()]+)|\\([^()]*\\))+","GwfY\\1O&W",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a\\Z","mItu\\1oJX&CQC&UvIK",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a\\Z","mItu\\1oJX&CQC&UvIK",[global])),
+ <<"aaab">> = iolist_to_binary(re:replace("aaab","a\\Z","IaLyKsEnQnMtfj\\1",[])),
+ <<"aaab">> = iolist_to_binary(re:replace("aaab","a\\Z","IaLyKsEnQnMtfj\\1",[global])),
<<"a
b">> = iolist_to_binary(re:replace("a
-b","a\\Z","Dt\\1LIek",[])),
+b","a\\Z","eslV\\1s",[])),
<<"a
b">> = iolist_to_binary(re:replace("a
-b","a\\Z","Dt\\1LIek",[global])),
+b","a\\Z","eslV\\1s",[global])),
<<"a
-ihO">> = iolist_to_binary(re:replace("a
-b","b\\Z","ihO",[])),
+MKbmAwNCnGbLYb">> = iolist_to_binary(re:replace("a
+b","b\\Z","M\\1K&mAwNCnG&LY\\1&",[])),
<<"a
-ihO">> = iolist_to_binary(re:replace("a
-b","b\\Z","ihO",[global])),
+MKbmAwNCnGbLYb">> = iolist_to_binary(re:replace("a
+b","b\\Z","M\\1K&mAwNCnG&LY\\1&",[global])),
<<"a
-xaybR">> = iolist_to_binary(re:replace("a
-b","b\\Z","xaybR",[])),
+YxEpUt">> = iolist_to_binary(re:replace("a
+b","b\\Z","YxEpUt",[])),
<<"a
-xaybR">> = iolist_to_binary(re:replace("a
-b","b\\Z","xaybR",[global])),
+YxEpUt">> = iolist_to_binary(re:replace("a
+b","b\\Z","YxEpUt",[global])),
<<"a
-b">> = iolist_to_binary(re:replace("a
-b","b\\z","&",[])),
+nocMyHoQWrYuE">> = iolist_to_binary(re:replace("a
+b","b\\z","nocMyHoQ\\1WrY\\1uE",[])),
<<"a
-b">> = iolist_to_binary(re:replace("a
-b","b\\z","&",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","b\\z","L\\1\\1ffT&Q\\1\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","b\\z","L\\1\\1ffT&Q\\1\\1",[global])),
- <<"lKtonNambJv">> = iolist_to_binary(re:replace("a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","lKt\\1onN&mbJ\\1v",[])),
- <<"lKtonNambJv">> = iolist_to_binary(re:replace("a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","lKt\\1onN&mbJ\\1v",[global])),
- <<"pabcYFSdblfLabcy">> = iolist_to_binary(re:replace("abc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","p&\\1YFSdbl\\1fL&y",[])),
- <<"pabcYFSdblfLabcy">> = iolist_to_binary(re:replace("abc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","p&\\1YFSdbl\\1fL&y",[global])),
- <<"Ta-bKyCljTYNdT">> = iolist_to_binary(re:replace("a-b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","T&KyCljTYN\\1dT",[])),
- <<"Ta-bKyCljTYNdT">> = iolist_to_binary(re:replace("a-b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","T&KyCljTYN\\1dT",[global])),
- <<"RHSJc">> = iolist_to_binary(re:replace("0-9","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","RHSJc",[])),
- <<"RHSJc">> = iolist_to_binary(re:replace("0-9","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","RHSJc",[global])),
- <<"dMwhrVYNNa.ba.bGa.br">> = iolist_to_binary(re:replace("a.b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","\\1dMwhrVYNN&&G&r",[])),
- <<"dMwhrVYNNa.ba.bGa.br">> = iolist_to_binary(re:replace("a.b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","\\1dMwhrVYNN&&G&r",[global])),
- <<"kPaiiQUiPl">> = iolist_to_binary(re:replace("5.6.7","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","kPaiiQUiPl\\1",[])),
- <<"kPaiiQUiPl">> = iolist_to_binary(re:replace("5.6.7","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","kPaiiQUiPl\\1",[global])),
- <<"wvQrLEJUiDlAr">> = iolist_to_binary(re:replace("the.quick.brown.fox","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","wvQ\\1rLEJUi\\1DlAr",[])),
- <<"wvQrLEJUiDlAr">> = iolist_to_binary(re:replace("the.quick.brown.fox","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","wvQ\\1rLEJUi\\1DlAr",[global])),
- <<"iHa100.b200.300cGyVda100.b200.300cekCw">> = iolist_to_binary(re:replace("a100.b200.300c","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","iH&GyVd&\\1ekCw",[])),
- <<"iHa100.b200.300cGyVda100.b200.300cekCw">> = iolist_to_binary(re:replace("a100.b200.300c","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","iH&GyVd&\\1ekCw",[global])),
- <<"O">> = iolist_to_binary(re:replace("12-ab.1245","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","O",[])),
- <<"O">> = iolist_to_binary(re:replace("12-ab.1245","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","O",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","HUtU\\1hwSyIT&Oh\\1&&y",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","HUtU\\1hwSyIT&Oh\\1&&y",[global])),
- <<"">> = iolist_to_binary(re:replace("","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","hNvuQF&Qs&",[])),
- <<"">> = iolist_to_binary(re:replace("","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","hNvuQF&Qs&",[global])),
- <<".a">> = iolist_to_binary(re:replace(".a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","QqXr&DuJWM",[])),
- <<".a">> = iolist_to_binary(re:replace(".a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","QqXr&DuJWM",[global])),
- <<"-a">> = iolist_to_binary(re:replace("-a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","sk\\1IEt",[])),
- <<"-a">> = iolist_to_binary(re:replace("-a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","sk\\1IEt",[global])),
- <<"a-">> = iolist_to_binary(re:replace("a-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","q&NPicpE",[])),
- <<"a-">> = iolist_to_binary(re:replace("a-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","q&NPicpE",[global])),
- <<"a.">> = iolist_to_binary(re:replace("a.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","CQXy",[])),
- <<"a.">> = iolist_to_binary(re:replace("a.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","CQXy",[global])),
- <<"a_b">> = iolist_to_binary(re:replace("a_b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","LYXq",[])),
- <<"a_b">> = iolist_to_binary(re:replace("a_b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","LYXq",[global])),
- <<"a.-">> = iolist_to_binary(re:replace("a.-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","MD\\1",[])),
- <<"a.-">> = iolist_to_binary(re:replace("a.-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","MD\\1",[global])),
- <<"a..">> = iolist_to_binary(re:replace("a..","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","L",[])),
- <<"a..">> = iolist_to_binary(re:replace("a..","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","L",[global])),
- <<"ab..bc">> = iolist_to_binary(re:replace("ab..bc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","BCKwcl\\1kueBcjj",[])),
- <<"ab..bc">> = iolist_to_binary(re:replace("ab..bc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","BCKwcl\\1kueBcjj",[global])),
- <<"the.quick.brown.fox-">> = iolist_to_binary(re:replace("the.quick.brown.fox-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","JT&&v&ADCCjyxv",[])),
- <<"the.quick.brown.fox-">> = iolist_to_binary(re:replace("the.quick.brown.fox-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","JT&&v&ADCCjyxv",[global])),
- <<"the.quick.brown.fox.">> = iolist_to_binary(re:replace("the.quick.brown.fox.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","ss",[])),
- <<"the.quick.brown.fox.">> = iolist_to_binary(re:replace("the.quick.brown.fox.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","ss",[global])),
- <<"the.quick.brown.fox_">> = iolist_to_binary(re:replace("the.quick.brown.fox_","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","oN\\1QUG",[])),
- <<"the.quick.brown.fox_">> = iolist_to_binary(re:replace("the.quick.brown.fox_","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","oN\\1QUG",[global])),
- <<"the.quick.brown.fox+">> = iolist_to_binary(re:replace("the.quick.brown.fox+","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","dOn\\1&jl\\1b&",[])),
- <<"the.quick.brown.fox+">> = iolist_to_binary(re:replace("the.quick.brown.fox+","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","dOn\\1&jl\\1b&",[global])),
- <<"fkIx">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*)(?<=(abcd|wxyz))","fkIx",[])),
- <<"fkIxfkIx">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*)(?<=(abcd|wxyz))","fkIx",[global])),
- <<"endingwxyzendingwxyzuyEXDtendingwxyzFCFendingwxyzgoLpALi">> = iolist_to_binary(re:replace("endingwxyz","(?>.*)(?<=(abcd|wxyz))","&&uyEXDt&FCF&goLpALi",[])),
- <<"endingwxyzendingwxyzuyEXDtendingwxyzFCFendingwxyzgoLpALiuyEXDtFCFgoLpALi">> = iolist_to_binary(re:replace("endingwxyz","(?>.*)(?<=(abcd|wxyz))","&&uyEXDt&FCF&goLpALi",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>.*)(?<=(abcd|wxyz))","ElH",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>.*)(?<=(abcd|wxyz))","ElH",[global])),
- <<"a rather long string that doesn't end with one of them">> = iolist_to_binary(re:replace("a rather long string that doesn't end with one of them","(?>.*)(?<=(abcd|wxyz))","&GVy",[])),
- <<"a rather long string that doesn't end with one of them">> = iolist_to_binary(re:replace("a rather long string that doesn't end with one of them","(?>.*)(?<=(abcd|wxyz))","&GVy",[global])),
- <<"IpFbERword cat dog elephant mussel cow horse canary baboon snake shark otherwordvjword cat dog elephant mussel cow horse canary baboon snake shark otherwordaul">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword","IpFbER&vj&aul",[])),
- <<"IpFbERword cat dog elephant mussel cow horse canary baboon snake shark otherwordvjword cat dog elephant mussel cow horse canary baboon snake shark otherwordaul">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword","IpFbER&vj&aul",[global])),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword","JMrCXcb\\1Q&T\\1ypBy",[])),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword","JMrCXcb\\1Q&T\\1ypBy",[global])),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?>[a-zA-Z0-9]+ ){0,30}otherword","TD&O",[])),
- <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?>[a-zA-Z0-9]+ ){0,30}otherword","TD&O",[global])),
- <<"999fooKfooJ">> = iolist_to_binary(re:replace("999foo","(?<=\\d{3}(?!999))foo","&K&J",[])),
- <<"999fooKfooJ">> = iolist_to_binary(re:replace("999foo","(?<=\\d{3}(?!999))foo","&K&J",[global])),
- <<"123999ncsryomxOKBBikcY">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}(?!999))foo","\\1ncsry\\1omxOKBBikcY",[])),
- <<"123999ncsryomxOKBBikcY">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}(?!999))foo","\\1ncsry\\1omxOKBBikcY",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}(?!999))foo","NMXv",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}(?!999))foo","NMXv",[global])),
- <<"123abcfoo">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}(?!999))foo","B\\1\\1",[])),
- <<"123abcfoo">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}(?!999))foo","B\\1\\1",[global])),
- <<"999faWvYAfooyphbfooC">> = iolist_to_binary(re:replace("999foo","(?<=(?!...999)\\d{3})foo","f\\1aW\\1vYA\\1&yphb&C",[])),
- <<"999faWvYAfooyphbfooC">> = iolist_to_binary(re:replace("999foo","(?<=(?!...999)\\d{3})foo","f\\1aW\\1vYA\\1&yphb&C",[global])),
- <<"123999D">> = iolist_to_binary(re:replace("123999foo","(?<=(?!...999)\\d{3})foo","D",[])),
- <<"123999D">> = iolist_to_binary(re:replace("123999foo","(?<=(?!...999)\\d{3})foo","D",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(?!...999)\\d{3})foo","xk\\1&NP",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(?!...999)\\d{3})foo","xk\\1&NP",[global])),
- <<"123abcfoo">> = iolist_to_binary(re:replace("123abcfoo","(?<=(?!...999)\\d{3})foo","Cpoo",[])),
- <<"123abcfoo">> = iolist_to_binary(re:replace("123abcfoo","(?<=(?!...999)\\d{3})foo","Cpoo",[global])),
- <<"123abcKgjBJrwxNA">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}(?!999)...)foo","KgjBJrwxNA",[])),
- <<"123abcKgjBJrwxNA">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}(?!999)...)foo","KgjBJrwxNA",[global])),
- <<"123456foomfooUfooUg">> = iolist_to_binary(re:replace("123456foo","(?<=\\d{3}(?!999)...)foo","&m&U&Ug\\1",[])),
- <<"123456foomfooUfooUg">> = iolist_to_binary(re:replace("123456foo","(?<=\\d{3}(?!999)...)foo","&m&U&Ug\\1",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}(?!999)...)foo","Ccj\\1&vjH&",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}(?!999)...)foo","Ccj\\1&vjH&",[global])),
- <<"123999foo">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}(?!999)...)foo","&MeuE&",[])),
- <<"123999foo">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}(?!999)...)foo","&MeuE&",[global])),
- <<"123abcMdRfooqtYhLSo">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}...)(?<!999)foo","Md\\1R&qtYhLSo",[])),
- <<"123abcMdRfooqtYhLSo">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}...)(?<!999)foo","Md\\1R&qtYhLSo",[global])),
- <<"123456IfooHfooFgGWfoobS">> = iolist_to_binary(re:replace("123456foo","(?<=\\d{3}...)(?<!999)foo","I&H\\1\\1&\\1FgGW&bS",[])),
- <<"123456IfooHfooFgGWfoobS">> = iolist_to_binary(re:replace("123456foo","(?<=\\d{3}...)(?<!999)foo","I&H\\1\\1&\\1FgGW&bS",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}...)(?<!999)foo","x&KVkVB\\1mIkDO\\1",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}...)(?<!999)foo","x&KVkVB\\1mIkDO\\1",[global])),
- <<"123999foo">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}...)(?<!999)foo","imQyT&\\1",[])),
- <<"123999foo">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}...)(?<!999)foo","imQyT&\\1",[global])),
+nocMyHoQWrYuE">> = iolist_to_binary(re:replace("a
+b","b\\z","nocMyHoQ\\1WrY\\1uE",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","b\\z","WYbAyvR",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","b\\z","WYbAyvR",[global])),
+ <<"hnvNIpoJVjsUM">> = iolist_to_binary(re:replace("a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","hnvNIpoJVjsU\\1M",[])),
+ <<"hnvNIpoJVjsUM">> = iolist_to_binary(re:replace("a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","hnvNIpoJVjsU\\1M",[global])),
+ <<"hxMJiijTWX">> = iolist_to_binary(re:replace("abc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","hxMJiijTWX",[])),
+ <<"hxMJiijTWX">> = iolist_to_binary(re:replace("abc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","hxMJiijTWX",[global])),
+ <<"YbRuX">> = iolist_to_binary(re:replace("a-b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","YbRuX",[])),
+ <<"YbRuX">> = iolist_to_binary(re:replace("a-b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","YbRuX",[global])),
+ <<"SxvuEx0-9jSlY">> = iolist_to_binary(re:replace("0-9","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","SxvuEx\\1&j\\1\\1Sl\\1Y",[])),
+ <<"SxvuEx0-9jSlY">> = iolist_to_binary(re:replace("0-9","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","SxvuEx\\1&j\\1\\1Sl\\1Y",[global])),
+ <<"f">> = iolist_to_binary(re:replace("a.b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","f",[])),
+ <<"f">> = iolist_to_binary(re:replace("a.b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","f",[global])),
+ <<"ITsyB5.6.7Aaf">> = iolist_to_binary(re:replace("5.6.7","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","ITsyB&\\1Aaf",[])),
+ <<"ITsyB5.6.7Aaf">> = iolist_to_binary(re:replace("5.6.7","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","ITsyB&\\1Aaf",[global])),
+ <<"VwsTKcuXijrhthe.quick.brown.foxtk">> = iolist_to_binary(re:replace("the.quick.brown.fox","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","VwsTK\\1cu\\1Xijrh&tk",[])),
+ <<"VwsTKcuXijrhthe.quick.brown.foxtk">> = iolist_to_binary(re:replace("the.quick.brown.fox","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","VwsTK\\1cu\\1Xijrh&tk",[global])),
+ <<"nnlUga100.b200.300cnaspQDy">> = iolist_to_binary(re:replace("a100.b200.300c","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","nnlUg&\\1naspQDy",[])),
+ <<"nnlUga100.b200.300cnaspQDy">> = iolist_to_binary(re:replace("a100.b200.300c","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","nnlUg&\\1naspQDy",[global])),
+ <<"Dg12-ab.1245dwIGWfGU12-ab.1245G">> = iolist_to_binary(re:replace("12-ab.1245","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","Dg&\\1dwIGW\\1fGU&G",[])),
+ <<"Dg12-ab.1245dwIGWfGU12-ab.1245G">> = iolist_to_binary(re:replace("12-ab.1245","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","Dg&\\1dwIGW\\1fGU&G",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","pRExPwXG\\1OMYxM&DJu",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","pRExPwXG\\1OMYxM&DJu",[global])),
+ <<"">> = iolist_to_binary(re:replace("","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","onWS&OuXOY\\1URE",[])),
+ <<"">> = iolist_to_binary(re:replace("","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","onWS&OuXOY\\1URE",[global])),
+ <<".a">> = iolist_to_binary(re:replace(".a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","D\\1",[])),
+ <<".a">> = iolist_to_binary(re:replace(".a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","D\\1",[global])),
+ <<"-a">> = iolist_to_binary(re:replace("-a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","CU&qX&&",[])),
+ <<"-a">> = iolist_to_binary(re:replace("-a","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","CU&qX&&",[global])),
+ <<"a-">> = iolist_to_binary(re:replace("a-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","AWEksHnb",[])),
+ <<"a-">> = iolist_to_binary(re:replace("a-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","AWEksHnb",[global])),
+ <<"a.">> = iolist_to_binary(re:replace("a.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","pDdW\\1Ja",[])),
+ <<"a.">> = iolist_to_binary(re:replace("a.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","pDdW\\1Ja",[global])),
+ <<"a_b">> = iolist_to_binary(re:replace("a_b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","sX\\1GuXg\\1M",[])),
+ <<"a_b">> = iolist_to_binary(re:replace("a_b","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","sX\\1GuXg\\1M",[global])),
+ <<"a.-">> = iolist_to_binary(re:replace("a.-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","XerO",[])),
+ <<"a.-">> = iolist_to_binary(re:replace("a.-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","XerO",[global])),
+ <<"a..">> = iolist_to_binary(re:replace("a..","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","c&oypUmVFTuQ\\1",[])),
+ <<"a..">> = iolist_to_binary(re:replace("a..","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","c&oypUmVFTuQ\\1",[global])),
+ <<"ab..bc">> = iolist_to_binary(re:replace("ab..bc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","lfUtOX&i",[])),
+ <<"ab..bc">> = iolist_to_binary(re:replace("ab..bc","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","lfUtOX&i",[global])),
+ <<"the.quick.brown.fox-">> = iolist_to_binary(re:replace("the.quick.brown.fox-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","d&SWUEw\\1lw&EK",[])),
+ <<"the.quick.brown.fox-">> = iolist_to_binary(re:replace("the.quick.brown.fox-","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","d&SWUEw\\1lw&EK",[global])),
+ <<"the.quick.brown.fox.">> = iolist_to_binary(re:replace("the.quick.brown.fox.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","Sn\\1",[])),
+ <<"the.quick.brown.fox.">> = iolist_to_binary(re:replace("the.quick.brown.fox.","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","Sn\\1",[global])),
+ <<"the.quick.brown.fox_">> = iolist_to_binary(re:replace("the.quick.brown.fox_","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","&pfLJ",[])),
+ <<"the.quick.brown.fox_">> = iolist_to_binary(re:replace("the.quick.brown.fox_","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","&pfLJ",[global])),
+ <<"the.quick.brown.fox+">> = iolist_to_binary(re:replace("the.quick.brown.fox+","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","TgSSa",[])),
+ <<"the.quick.brown.fox+">> = iolist_to_binary(re:replace("the.quick.brown.fox+","^(?>(?(1)\\.|())[^\\W_](?>[a-z0-9-]*[^\\W_])?)+$","TgSSa",[global])),
+ <<"QalphabetabcdkrolcqqNP">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*)(?<=(abcd|wxyz))","Q&krolcqqNP",[])),
+ <<"QalphabetabcdkrolcqqNPQkrolcqqNP">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*)(?<=(abcd|wxyz))","Q&krolcqqNP",[global])),
+ <<"VIJWRwxyzSk">> = iolist_to_binary(re:replace("endingwxyz","(?>.*)(?<=(abcd|wxyz))","VIJWR\\1Sk",[])),
+ <<"VIJWRwxyzSkVIJWRwxyzSk">> = iolist_to_binary(re:replace("endingwxyz","(?>.*)(?<=(abcd|wxyz))","VIJWR\\1Sk",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>.*)(?<=(abcd|wxyz))","\\1&gWuF",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?>.*)(?<=(abcd|wxyz))","\\1&gWuF",[global])),
+ <<"a rather long string that doesn't end with one of them">> = iolist_to_binary(re:replace("a rather long string that doesn't end with one of them","(?>.*)(?<=(abcd|wxyz))","H&ltPpih\\1o",[])),
+ <<"a rather long string that doesn't end with one of them">> = iolist_to_binary(re:replace("a rather long string that doesn't end with one of them","(?>.*)(?<=(abcd|wxyz))","H&ltPpih\\1o",[global])),
+ <<"EJTgrword cat dog elephant mussel cow horse canary baboon snake shark otherwordMRkhYV">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword","EJ\\1Tgr&MRk\\1h\\1YV",[])),
+ <<"EJTgrword cat dog elephant mussel cow horse canary baboon snake shark otherwordMRkhYV">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark otherword","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword","EJ\\1Tgr&MRk\\1h\\1YV",[global])),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword","AJGCQ&uuuLVT",[])),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark","word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword","AJGCQ&uuuLVT",[global])),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?>[a-zA-Z0-9]+ ){0,30}otherword","ncMPhkKY&ume",[])),
+ <<"word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope">> = iolist_to_binary(re:replace("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope","word (?>[a-zA-Z0-9]+ ){0,30}otherword","ncMPhkKY&ume",[global])),
+ <<"999Kofooh">> = iolist_to_binary(re:replace("999foo","(?<=\\d{3}(?!999))foo","Ko&h",[])),
+ <<"999Kofooh">> = iolist_to_binary(re:replace("999foo","(?<=\\d{3}(?!999))foo","Ko&h",[global])),
+ <<"123999eqaOjvQcm">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}(?!999))foo","\\1eqaO\\1jvQc\\1m",[])),
+ <<"123999eqaOjvQcm">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}(?!999))foo","\\1eqaO\\1jvQc\\1m",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}(?!999))foo","Re\\1UYpTHfhCxdlxiq",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}(?!999))foo","Re\\1UYpTHfhCxdlxiq",[global])),
+ <<"123abcfoo">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}(?!999))foo","ww",[])),
+ <<"123abcfoo">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}(?!999))foo","ww",[global])),
+ <<"999yvTHkcfoofoo">> = iolist_to_binary(re:replace("999foo","(?<=(?!...999)\\d{3})foo","yvT\\1Hkc\\1&&",[])),
+ <<"999yvTHkcfoofoo">> = iolist_to_binary(re:replace("999foo","(?<=(?!...999)\\d{3})foo","yvT\\1Hkc\\1&&",[global])),
+ <<"123999yatIrmp">> = iolist_to_binary(re:replace("123999foo","(?<=(?!...999)\\d{3})foo","yatIrmp",[])),
+ <<"123999yatIrmp">> = iolist_to_binary(re:replace("123999foo","(?<=(?!...999)\\d{3})foo","yatIrmp",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(?!...999)\\d{3})foo","QnIaJrp\\1SWvhckCE",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=(?!...999)\\d{3})foo","QnIaJrp\\1SWvhckCE",[global])),
+ <<"123abcfoo">> = iolist_to_binary(re:replace("123abcfoo","(?<=(?!...999)\\d{3})foo","racp\\1ypxW",[])),
+ <<"123abcfoo">> = iolist_to_binary(re:replace("123abcfoo","(?<=(?!...999)\\d{3})foo","racp\\1ypxW",[global])),
+ <<"123abcHMcfoofoofoofooSLctffooFhIYC">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}(?!999)...)foo","HMc&&&&SLctf&FhIYC",[])),
+ <<"123abcHMcfoofoofoofooSLctffooFhIYC">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}(?!999)...)foo","HMc&&&&SLctf&FhIYC",[global])),
+ <<"123456tDCqfoo">> = iolist_to_binary(re:replace("123456foo","(?<=\\d{3}(?!999)...)foo","t\\1DCq&",[])),
+ <<"123456tDCqfoo">> = iolist_to_binary(re:replace("123456foo","(?<=\\d{3}(?!999)...)foo","t\\1DCq&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}(?!999)...)foo","hME",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}(?!999)...)foo","hME",[global])),
+ <<"123999foo">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}(?!999)...)foo","UyaU\\1e&PfYQtNU",[])),
+ <<"123999foo">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}(?!999)...)foo","UyaU\\1e&PfYQtNU",[global])),
ok.
run32() ->
- <<"YXkVs xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
+ <<"123abccaCEM">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}...)(?<!999)foo","caCEM",[])),
+ <<"123abccaCEM">> = iolist_to_binary(re:replace("123abcfoo","(?<=\\d{3}...)(?<!999)foo","caCEM",[global])),
+ <<"123456fSpVHIfooj">> = iolist_to_binary(re:replace("123456foo","(?<=\\d{3}...)(?<!999)foo","fSpVHI&j",[])),
+ <<"123456fSpVHIfooj">> = iolist_to_binary(re:replace("123456foo","(?<=\\d{3}...)(?<!999)foo","fSpVHI&j",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}...)(?<!999)foo","eLqPt",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?<=\\d{3}...)(?<!999)foo","eLqPt",[global])),
+ <<"123999foo">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}...)(?<!999)foo","&ORV",[])),
+ <<"123999foo">> = iolist_to_binary(re:replace("123999foo","(?<=\\d{3}...)(?<!999)foo","&ORV",[global])),
+ <<"gIWbF<a href=abcdNFWj xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","YX\\1kVs",[caseless,
+ # quote, otherwise match up to next space","gIWbF&NFWj",[caseless,
dotall,
extended])),
- <<"YXkVs xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
+ <<"gIWbF<a href=abcdNFWj xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","YX\\1kVs",[caseless,
+ # quote, otherwise match up to next space","gIWbF&NFWj",[caseless,
dotall,
extended,
global])),
- <<"j\"rurrrUhbILCWDO<a href=\"abcd xyz pqr\" cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
+ <<"l\"Ac cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","j\\1rurrrUhbILCWDO&",[caseless,
- dotall,
- extended])),
- <<"j\"rurrrUhbILCWDO<a href=\"abcd xyz pqr\" cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
+ # quote, otherwise match up to next space","l\\1Ac",[caseless,
+ dotall,
+ extended])),
+ <<"l\"Ac cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","j\\1rurrrUhbILCWDO&",[caseless,
- dotall,
- extended,
- global])),
- <<"KHDcRniMHRJEBi cats">> = iolist_to_binary(re:replace("<a href='abcd xyz pqr' cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
+ # quote, otherwise match up to next space","l\\1Ac",[caseless,
+ dotall,
+ extended,
+ global])),
+ <<"wMK'N'IKKxMErnc cats">> = iolist_to_binary(re:replace("<a href='abcd xyz pqr' cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","KHDcRniMHRJEBi",[caseless,
- dotall,
- extended])),
- <<"KHDcRniMHRJEBi cats">> = iolist_to_binary(re:replace("<a href='abcd xyz pqr' cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
+ # quote, otherwise match up to next space","wMK\\1N\\1IKKxMErnc",[caseless,
+ dotall,
+ extended])),
+ <<"wMK'N'IKKxMErnc cats">> = iolist_to_binary(re:replace("<a href='abcd xyz pqr' cats","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","KHDcRniMHRJEBi",[caseless,
- dotall,
- extended,
- global])),
- <<"DRkc<a href=abcd xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a\\s+href\\s*=\\s* # find <a href=
- ([\"'])? # find single or double quote
- (?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","DRkc&\\1",[caseless,
- dotall,
- extended])),
- <<"DRkc<a href=abcd xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a\\s+href\\s*=\\s* # find <a href=
+ # quote, otherwise match up to next space","wMK\\1N\\1IKKxMErnc",[caseless,
+ dotall,
+ extended,
+ global])),
+ <<"OB<a href=abcdNftFV<a href=abcd xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","DRkc&\\1",[caseless,
- dotall,
- extended,
- global])),
- <<"M\"b\"cG cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a\\s+href\\s*=\\s* # find <a href=
- ([\"'])? # find single or double quote
- (?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","M\\1b\\1cG",[caseless,
+ # quote, otherwise match up to next space","OB&NftFV&\\1",[caseless,
dotall,
extended])),
- <<"M\"b\"cG cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a\\s+href\\s*=\\s* # find <a href=
+ <<"OB<a href=abcdNftFV<a href=abcd xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","M\\1b\\1cG",[caseless,
+ # quote, otherwise match up to next space","OB&NftFV&\\1",[caseless,
dotall,
extended,
global])),
- <<"<a href = 'abcd xyz pqr'K'RAApBAC'TjXhwL cats">> = iolist_to_binary(re:replace("<a href = 'abcd xyz pqr' cats","<a\\s+href\\s*=\\s* # find <a href=
+ <<"<a href=\"abcd xyz pqr\"LxBb<a href=\"abcd xyz pqr\"\"EuHPuB\"\"dqn\"U cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a\\s+href\\s*=\\s* # find <a href=
+ ([\"'])? # find single or double quote
+ (?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
+ # quote, otherwise match up to next space","&LxBb&\\1EuHPuB\\1\\1dqn\\1U",[caseless,
+ dotall,
+ extended])),
+ <<"<a href=\"abcd xyz pqr\"LxBb<a href=\"abcd xyz pqr\"\"EuHPuB\"\"dqn\"U cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a\\s+href\\s*=\\s* # find <a href=
+ ([\"'])? # find single or double quote
+ (?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
+ # quote, otherwise match up to next space","&LxBb&\\1EuHPuB\\1\\1dqn\\1U",[caseless,
+ dotall,
+ extended,
+ global])),
+ <<"KCm'''H'Sd'O cats">> = iolist_to_binary(re:replace("<a href = 'abcd xyz pqr' cats","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","&K\\1RAApBAC\\1TjXhwL",[caseless,
- dotall,
- extended])),
- <<"<a href = 'abcd xyz pqr'K'RAApBAC'TjXhwL cats">> = iolist_to_binary(re:replace("<a href = 'abcd xyz pqr' cats","<a\\s+href\\s*=\\s* # find <a href=
+ # quote, otherwise match up to next space","KCm\\1\\1\\1H\\1Sd\\1O",[caseless,
+ dotall,
+ extended])),
+ <<"KCm'''H'Sd'O cats">> = iolist_to_binary(re:replace("<a href = 'abcd xyz pqr' cats","<a\\s+href\\s*=\\s* # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","&K\\1RAApBAC\\1TjXhwL",[caseless,
- dotall,
- extended,
- global])),
- <<"udPf<a href=abcd<a href=abcdVmHT xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
+ # quote, otherwise match up to next space","KCm\\1\\1\\1H\\1Sd\\1O",[caseless,
+ dotall,
+ extended,
+ global])),
+ <<"hnRxfhjlJxA xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","\\1udPf&&VmHT\\1",[caseless,
- dotall,
- extended])),
- <<"udPf<a href=abcd<a href=abcdVmHT xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
+ # quote, otherwise match up to next space","hnRxfhjlJxA",[caseless,
+ dotall,
+ extended])),
+ <<"hnRxfhjlJxA xyz">> = iolist_to_binary(re:replace("<a href=abcd xyz","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","\\1udPf&&VmHT\\1",[caseless,
- dotall,
- extended,
- global])),
- <<"lO<a href=\"abcd xyz pqr\"C<a href=\"abcd xyz pqr\"dAuVMQlg cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
+ # quote, otherwise match up to next space","hnRxfhjlJxA",[caseless,
+ dotall,
+ extended,
+ global])),
+ <<"Md cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","lO&C&dAuVMQlg",[caseless,
- dotall,
- extended])),
- <<"lO<a href=\"abcd xyz pqr\"C<a href=\"abcd xyz pqr\"dAuVMQlg cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
+ # quote, otherwise match up to next space","Md",[caseless,
+ dotall,
+ extended])),
+ <<"Md cats">> = iolist_to_binary(re:replace("<a href=\"abcd xyz pqr\" cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","lO&C&dAuVMQlg",[caseless,
- dotall,
- extended,
- global])),
- <<"kNUDBNNpwgKs'j cats">> = iolist_to_binary(re:replace("<a href = 'abcd xyz pqr' cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
+ # quote, otherwise match up to next space","Md",[caseless,
+ dotall,
+ extended,
+ global])),
+ <<"TYyXigPSfkp<a href = 'abcd xyz pqr'vsJ'B cats">> = iolist_to_binary(re:replace("<a href = 'abcd xyz pqr' cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","kNUDBNNpwgKs\\1j",[caseless,
- dotall,
- extended])),
- <<"kNUDBNNpwgKs'j cats">> = iolist_to_binary(re:replace("<a href = 'abcd xyz pqr' cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
+ # quote, otherwise match up to next space","TYyXigPSfkp&vsJ\\1B",[caseless,
+ dotall,
+ extended])),
+ <<"TYyXigPSfkp<a href = 'abcd xyz pqr'vsJ'B cats">> = iolist_to_binary(re:replace("<a href = 'abcd xyz pqr' cats","<a\\s+href(?>\\s*)=(?>\\s*) # find <a href=
([\"'])? # find single or double quote
(?(1) (.*?)\\1 | (\\S+)) # if quote found, match up to next matching
- # quote, otherwise match up to next space","kNUDBNNpwgKs\\1j",[caseless,
- dotall,
- extended,
- global])),
- <<"SBBCDEFG">> = iolist_to_binary(re:replace("ZABCDEFG","((Z)+|A)*","SB",[])),
- <<"SBSBBSBCSBDSBESBFSBGSB">> = iolist_to_binary(re:replace("ZABCDEFG","((Z)+|A)*","SB",[global])),
- <<"TGWhfNtEZAQBCDEFG">> = iolist_to_binary(re:replace("ZABCDEFG","(Z()|A)*","TGWhfNtE&Q",[])),
- <<"TGWhfNtEZAQTGWhfNtEQBTGWhfNtEQCTGWhfNtEQDTGWhfNtEQETGWhfNtEQFTGWhfNtEQGTGWhfNtEQ">> = iolist_to_binary(re:replace("ZABCDEFG","(Z()|A)*","TGWhfNtE&Q",[global])),
- <<"QATmcAAZABCDEFG">> = iolist_to_binary(re:replace("ZABCDEFG","(Z(())|A)*","Q\\1Tmc\\1\\1&",[])),
- <<"QATmcAAZAQTmcBQTmcCQTmcDQTmcEQTmcFQTmcGQTmc">> = iolist_to_binary(re:replace("ZABCDEFG","(Z(())|A)*","Q\\1Tmc\\1\\1&",[global])),
- <<"LUBCDEFG">> = iolist_to_binary(re:replace("ZABCDEFG","((?>Z)+|A)*","LU",[])),
- <<"LULUBLUCLUDLUELUFLUGLU">> = iolist_to_binary(re:replace("ZABCDEFG","((?>Z)+|A)*","LU",[global])),
- <<"YLMbVmHKJJdvuAVZABCDEFG">> = iolist_to_binary(re:replace("ZABCDEFG","((?>)+|A)*","YL&MbVmHKJJdv\\1&uAV",[])),
- <<"YLMbVmHKJJdvuAVZYLMbVmHKJJdvuAVYLAMbVmHKJJdvAuAVYLMbVmHKJJdvuAVBYLMbVmHKJJdvuAVCYLMbVmHKJJdvuAVDYLMbVmHKJJdvuAVEYLMbVmHKJJdvuAVFYLMbVmHKJJdvuAVGYLMbVmHKJJdvuAV">> = iolist_to_binary(re:replace("ZABCDEFG","((?>)+|A)*","YL&MbVmHKJJdv\\1&uAV",[global])),
- <<"qewqabbab">> = iolist_to_binary(re:replace("abbab","a*","qewq&",[])),
- <<"qewqaqewqbqewqbqewqaqewqbqewq">> = iolist_to_binary(re:replace("abbab","a*","qewq&",[global])),
- <<"Nabcde">> = iolist_to_binary(re:replace("abcde","^[a-\\d]","N&",[])),
- <<"Nabcde">> = iolist_to_binary(re:replace("abcde","^[a-\\d]","N&",[global])),
- <<"sg-aOs-tithings">> = iolist_to_binary(re:replace("-things","^[a-\\d]","sg&a\\1Os&ti",[])),
- <<"sg-aOs-tithings">> = iolist_to_binary(re:replace("-things","^[a-\\d]","sg&a\\1Os&ti",[global])),
- <<"DtMdigit">> = iolist_to_binary(re:replace("0digit","^[a-\\d]","DtM",[])),
- <<"DtMdigit">> = iolist_to_binary(re:replace("0digit","^[a-\\d]","DtM",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[a-\\d]","dJiX",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[a-\\d]","dJiX",[global])),
- <<"bcdef">> = iolist_to_binary(re:replace("bcdef","^[a-\\d]","AGDlhSs&Gk&u\\1L",[])),
- <<"bcdef">> = iolist_to_binary(re:replace("bcdef","^[a-\\d]","AGDlhSs&Gk&u\\1L",[global])),
- <<"crLvRhrTbcde">> = iolist_to_binary(re:replace("abcde","^[\\d-a]","crLvRhrT",[])),
- <<"crLvRhrTbcde">> = iolist_to_binary(re:replace("abcde","^[\\d-a]","crLvRhrT",[global])),
- <<"XaUtelthings">> = iolist_to_binary(re:replace("-things","^[\\d-a]","XaUtel",[])),
- <<"XaUtelthings">> = iolist_to_binary(re:replace("-things","^[\\d-a]","XaUtel",[global])),
- <<"0digit">> = iolist_to_binary(re:replace("0digit","^[\\d-a]","&",[])),
- <<"0digit">> = iolist_to_binary(re:replace("0digit","^[\\d-a]","&",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[\\d-a]","E&gL&oOMM&E",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[\\d-a]","E&gL&oOMM&E",[global])),
- <<"bcdef">> = iolist_to_binary(re:replace("bcdef","^[\\d-a]","\\1kIKJw&Id",[])),
- <<"bcdef">> = iolist_to_binary(re:replace("bcdef","^[\\d-a]","\\1kIKJw&Id",[global])),
- <<">Qi<">> = iolist_to_binary(re:replace(">
- <","[[:space:]]+","\\1Qi",[])),
- <<">Qi<">> = iolist_to_binary(re:replace(">
- <","[[:space:]]+","\\1Qi",[global])),
- <<">VYrL AlFvYN
+ # quote, otherwise match up to next space","TYyXigPSfkp&vsJ\\1B",[caseless,
+ dotall,
+ extended,
+ global])),
+ <<"wMBCDEFG">> = iolist_to_binary(re:replace("ZABCDEFG","((Z)+|A)*","wM",[])),
+ <<"wMwMBwMCwMDwMEwMFwMGwM">> = iolist_to_binary(re:replace("ZABCDEFG","((Z)+|A)*","wM",[global])),
+ <<"bbZAKgAEEXBCDEFG">> = iolist_to_binary(re:replace("ZABCDEFG","(Z()|A)*","bb&Kg\\1EEX",[])),
+ <<"bbZAKgAEEXbbKgEEXBbbKgEEXCbbKgEEXDbbKgEEXEbbKgEEXFbbKgEEXGbbKgEEX">> = iolist_to_binary(re:replace("ZABCDEFG","(Z()|A)*","bb&Kg\\1EEX",[global])),
+ <<"dNoAtAFSCaAAZAXLDIZATBCDEFG">> = iolist_to_binary(re:replace("ZABCDEFG","(Z(())|A)*","dNo\\1t\\1FSCa\\1A&XLDI&T",[])),
+ <<"dNoAtAFSCaAAZAXLDIZATdNotFSCaAXLDITBdNotFSCaAXLDITCdNotFSCaAXLDITDdNotFSCaAXLDITEdNotFSCaAXLDITFdNotFSCaAXLDITGdNotFSCaAXLDIT">> = iolist_to_binary(re:replace("ZABCDEFG","(Z(())|A)*","dNo\\1t\\1FSCa\\1A&XLDI&T",[global])),
+ <<"ALpUZABCDEFG">> = iolist_to_binary(re:replace("ZABCDEFG","((?>Z)+|A)*","\\1LpU&",[])),
+ <<"ALpUZALpUBLpUCLpUDLpUELpUFLpUGLpU">> = iolist_to_binary(re:replace("ZABCDEFG","((?>Z)+|A)*","\\1LpU&",[global])),
+ <<"cMqaXsBwaDZABCDEFG">> = iolist_to_binary(re:replace("ZABCDEFG","((?>)+|A)*","cMq\\1\\1aX&sBw\\1aD",[])),
+ <<"cMqaXsBwaDZcMqaXsBwaDcMqaXAsBwaDcMqaXsBwaDBcMqaXsBwaDCcMqaXsBwaDDcMqaXsBwaDEcMqaXsBwaDFcMqaXsBwaDGcMqaXsBwaD">> = iolist_to_binary(re:replace("ZABCDEFG","((?>)+|A)*","cMq\\1\\1aX&sBw\\1aD",[global])),
+ <<"akaDGHXFpdvXlyHabbab">> = iolist_to_binary(re:replace("abbab","a*","&k&DGHXFpdvXlyH&",[])),
+ <<"akaDGHXFpdvXlyHakDGHXFpdvXlyHbkDGHXFpdvXlyHbakaDGHXFpdvXlyHakDGHXFpdvXlyHbkDGHXFpdvXlyH">> = iolist_to_binary(re:replace("abbab","a*","&k&DGHXFpdvXlyH&",[global])),
+ <<"YudMQIhVhnAHEwYsbcde">> = iolist_to_binary(re:replace("abcde","^[\\d-a]","YudMQIhVhnA\\1HE\\1wYs",[])),
+ <<"YudMQIhVhnAHEwYsbcde">> = iolist_to_binary(re:replace("abcde","^[\\d-a]","YudMQIhVhnA\\1HE\\1wYs",[global])),
+ <<"ITGPfithings">> = iolist_to_binary(re:replace("-things","^[\\d-a]","ITGPfi",[])),
+ <<"ITGPfithings">> = iolist_to_binary(re:replace("-things","^[\\d-a]","ITGPfi",[global])),
+ <<"LnPbdQ0digit">> = iolist_to_binary(re:replace("0digit","^[\\d-a]","\\1L\\1nP\\1\\1bdQ&",[])),
+ <<"LnPbdQ0digit">> = iolist_to_binary(re:replace("0digit","^[\\d-a]","\\1L\\1nP\\1\\1bdQ&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[\\d-a]","iDE&bvLKwXgDAsFK\\1Bjx",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^[\\d-a]","iDE&bvLKwXgDAsFK\\1Bjx",[global])),
+ <<"bcdef">> = iolist_to_binary(re:replace("bcdef","^[\\d-a]","Hni&",[])),
+ <<"bcdef">> = iolist_to_binary(re:replace("bcdef","^[\\d-a]","Hni&",[global])),
+ <<">Aqg<">> = iolist_to_binary(re:replace(">
+ <","[[:space:]]+","Aqg",[])),
+ <<">Aqg<">> = iolist_to_binary(re:replace(">
+ <","[[:space:]]+","Aqg",[global])),
+ <<"> p EdRI wCXk jvFPn
<">> = iolist_to_binary(re:replace(">
- <","[[:blank:]]+","VYrL&AlFvYN",[])),
- <<">VYrL AlFvYN
+ <","[[:blank:]]+","&p&&\\1EdRI&wCXk&jvFPn",[])),
+ <<"> p EdRI wCXk jvFPn
<">> = iolist_to_binary(re:replace(">
- <","[[:blank:]]+","VYrL&AlFvYN",[global])),
- <<">HJRfpOlI <">> = iolist_to_binary(re:replace(">
- <","[\\s]+","HJRfpOlI",[])),
- <<">HJRfpOlI <">> = iolist_to_binary(re:replace(">
- <","[\\s]+","HJRfpOlI",[global])),
- <<">
- t
- FtuuC <">> = iolist_to_binary(re:replace(">
- <","\\s+","&\\1t&FtuuC",[])),
- <<">
- t
- FtuuC <">> = iolist_to_binary(re:replace(">
- <","\\s+","&\\1t&FtuuC",[global])),
- <<"ab">> = iolist_to_binary(re:replace("ab","a b","&lH\\1E&J\\1&L&&Rx",[extended])),
- <<"ab">> = iolist_to_binary(re:replace("ab","a b","&lH\\1E&J\\1&L&&Rx",[extended,
- global])),
+ <","[[:blank:]]+","&p&&\\1EdRI&wCXk&jvFPn",[global])),
+ <<">uUfO
+ Y
+
+ kF
+ yXDhdgEU<">> = iolist_to_binary(re:replace(">
+ <","[\\s]+","uUfO&Y&&kF&yXDhdgEU",[])),
+ <<">uUfO
+ Y
+
+ kF
+ yXDhdgEU<">> = iolist_to_binary(re:replace(">
+ <","[\\s]+","uUfO&Y&&kF&yXDhdgEU",[global])),
+ <<">LJx
+ SrSQ
+ LLV
+ c<">> = iolist_to_binary(re:replace(">
+ <","\\s+","L\\1Jx&SrSQ&LLV&c",[])),
+ <<">LJx
+ SrSQ
+ LLV
+ c<">> = iolist_to_binary(re:replace(">
+ <","\\s+","L\\1Jx&SrSQ&LLV&c",[global])),
+ <<"hjBvDrJpGabab">> = iolist_to_binary(re:replace("ab","a b","hjBv\\1DrJpG&&",[extended])),
+ <<"hjBvDrJpGabab">> = iolist_to_binary(re:replace("ab","a b","hjBv\\1DrJpG&&",[extended,
+ global])),
<<"a
-xWxKmxNIb">> = iolist_to_binary(re:replace("a
-xb","(?!\\A)x","&W&Km&NI",[multiline])),
+MHFuJMpPfb">> = iolist_to_binary(re:replace("a
+xb","(?!\\A)x","MHFuJ\\1MpPf",[multiline])),
<<"a
-xWxKmxNIb">> = iolist_to_binary(re:replace("a
-xb","(?!\\A)x","&W&Km&NI",[multiline,global])),
+MHFuJMpPfb">> = iolist_to_binary(re:replace("a
+xb","(?!\\A)x","MHFuJ\\1MpPf",[multiline,global])),
<<"a
xb">> = iolist_to_binary(re:replace("a
-xb","(?!^)x","jRLFoYEov&K",[multiline])),
+xb","(?!^)x","\\1&MUUB\\1&cvVsiXTO",[multiline])),
<<"a
xb">> = iolist_to_binary(re:replace("a
-xb","(?!^)x","jRLFoYEov&K",[multiline,global])),
- <<"JVoGaFQQ">> = iolist_to_binary(re:replace("abcabcabc","abc\\Qabc\\Eabc","JVoGaFQQ",[])),
- <<"JVoGaFQQ">> = iolist_to_binary(re:replace("abcabcabc","abc\\Qabc\\Eabc","JVoGaFQQ",[global])),
- <<"DSeVu">> = iolist_to_binary(re:replace("abc(*+|abc","abc\\Q(*+|\\Eabc","DSeVu",[])),
- <<"DSeVu">> = iolist_to_binary(re:replace("abc(*+|abc","abc\\Q(*+|\\Eabc","DSeVu",[global])),
+xb","(?!^)x","\\1&MUUB\\1&cvVsiXTO",[multiline,global])),
+ <<"ACPKQHic">> = iolist_to_binary(re:replace("abcabcabc","abc\\Qabc\\Eabc","ACPKQHic",[])),
+ <<"ACPKQHic">> = iolist_to_binary(re:replace("abcabcabc","abc\\Qabc\\Eabc","ACPKQHic",[global])),
+ <<"egYBIabc(*+|abciLq">> = iolist_to_binary(re:replace("abc(*+|abc","abc\\Q(*+|\\Eabc","\\1\\1e\\1gYBI&iLq",[])),
+ <<"egYBIabc(*+|abciLq">> = iolist_to_binary(re:replace("abc(*+|abc","abc\\Q(*+|\\Eabc","\\1\\1e\\1gYBI&iLq",[global])),
ok.
run33() ->
- <<"Li">> = iolist_to_binary(re:replace("abc abcabc"," abc\\Q abc\\Eabc","Li",[extended])),
- <<"Li">> = iolist_to_binary(re:replace("abc abcabc"," abc\\Q abc\\Eabc","Li",[extended,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers"," abc\\Q abc\\Eabc","njPc\\1Go\\1Mf&&HbU\\1&",[extended])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers"," abc\\Q abc\\Eabc","njPc\\1Go\\1Mf&&HbU\\1&",[extended,
- global])),
- <<"abcabcabc">> = iolist_to_binary(re:replace("abcabcabc"," abc\\Q abc\\Eabc","&xP&fFtGb&mNes\\1GI\\1",[extended])),
- <<"abcabcabc">> = iolist_to_binary(re:replace("abcabcabc"," abc\\Q abc\\Eabc","&xP&fFtGb&mNes\\1GI\\1",[extended,
- global])),
- <<"gKHkeQRUc">> = iolist_to_binary(re:replace("abc#not comment
+ <<"AbfsJWLabc abcabcptMOXYup">> = iolist_to_binary(re:replace("abc abcabc"," abc\\Q abc\\Eabc","AbfsJWL\\1&ptMOXYup",[extended])),
+ <<"AbfsJWLabc abcabcptMOXYup">> = iolist_to_binary(re:replace("abc abcabc"," abc\\Q abc\\Eabc","AbfsJWL\\1&ptMOXYup",[extended,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers"," abc\\Q abc\\Eabc","GICvX&n",[extended])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers"," abc\\Q abc\\Eabc","GICvX&n",[extended,
+ global])),
+ <<"abcabcabc">> = iolist_to_binary(re:replace("abcabcabc"," abc\\Q abc\\Eabc","BJk\\1",[extended])),
+ <<"abcabcabc">> = iolist_to_binary(re:replace("abcabcabc"," abc\\Q abc\\Eabc","BJk\\1",[extended,
+ global])),
+ <<"mabc#not comment
+ literalBadWyqAUwNabc#not comment
+ literalabc#not comment
+ literalC">> = iolist_to_binary(re:replace("abc#not comment
literal","abc#comment
\\Q#not comment
- literal\\E","gKHkeQRUc",[extended])),
- <<"gKHkeQRUc">> = iolist_to_binary(re:replace("abc#not comment
+ literal\\E","m\\1&BadWyqAUwN&&C",[extended])),
+ <<"mabc#not comment
+ literalBadWyqAUwNabc#not comment
+ literalabc#not comment
+ literalC">> = iolist_to_binary(re:replace("abc#not comment
literal","abc#comment
\\Q#not comment
- literal\\E","gKHkeQRUc",[extended,global])),
- <<"gmgWrrxBneXj">> = iolist_to_binary(re:replace("abc#not comment
+ literal\\E","m\\1&BadWyqAUwN&&C",[extended,global])),
+ <<"Ywruhyabc#not comment
+ literal">> = iolist_to_binary(re:replace("abc#not comment
literal","abc#comment
\\Q#not comment
- literal","gmgWrrxBneXj",[extended])),
- <<"gmgWrrxBneXj">> = iolist_to_binary(re:replace("abc#not comment
+ literal","Ywr\\1uh\\1y&",[extended])),
+ <<"Ywruhyabc#not comment
+ literal">> = iolist_to_binary(re:replace("abc#not comment
literal","abc#comment
\\Q#not comment
- literal","gmgWrrxBneXj",[extended,global])),
- <<"JetiXL">> = iolist_to_binary(re:replace("abc#not comment
+ literal","Ywr\\1uh\\1y&",[extended,global])),
+ <<"FWoMpwmabc#not comment
+ literalabc#not comment
+ literalAabc#not comment
+ literalpnsNM">> = iolist_to_binary(re:replace("abc#not comment
literal","abc#comment
\\Q#not comment
literal\\E #more comment
- ","J\\1etiX\\1L",[extended])),
- <<"JetiXL">> = iolist_to_binary(re:replace("abc#not comment
+ ","FW\\1oMpwm&&A&pnsNM",[extended])),
+ <<"FWoMpwmabc#not comment
+ literalabc#not comment
+ literalAabc#not comment
+ literalpnsNM">> = iolist_to_binary(re:replace("abc#not comment
literal","abc#comment
\\Q#not comment
literal\\E #more comment
- ","J\\1etiX\\1L",[extended,global])),
- <<"nxvXs">> = iolist_to_binary(re:replace("abc#not comment
+ ","FW\\1oMpwm&&A&pnsNM",[extended,global])),
+ <<"j">> = iolist_to_binary(re:replace("abc#not comment
literal","abc#comment
\\Q#not comment
- literal\\E #more comment","\\1nxvXs",[extended])),
- <<"nxvXs">> = iolist_to_binary(re:replace("abc#not comment
+ literal\\E #more comment","j",[extended])),
+ <<"j">> = iolist_to_binary(re:replace("abc#not comment
literal","abc#comment
\\Q#not comment
- literal\\E #more comment","\\1nxvXs",[extended,global])),
- <<"NHOqEFFabc\\$xyzj">> = iolist_to_binary(re:replace("abc\\$xyz","\\Qabc\\$xyz\\E","NHOqEFF&j",[])),
- <<"NHOqEFFabc\\$xyzj">> = iolist_to_binary(re:replace("abc\\$xyz","\\Qabc\\$xyz\\E","NHOqEFF&j",[global])),
- <<"DjW">> = iolist_to_binary(re:replace("abc$xyz","\\Qabc\\E\\$\\Qxyz\\E","DjW",[])),
- <<"DjW">> = iolist_to_binary(re:replace("abc$xyz","\\Qabc\\E\\$\\Qxyz\\E","DjW",[global])),
- <<"WAnMpAVfX">> = iolist_to_binary(re:replace("abc","\\Gabc","W\\1AnMpAV\\1f\\1X",[])),
- <<"WAnMpAVfX">> = iolist_to_binary(re:replace("abc","\\Gabc","W\\1AnMpAV\\1f\\1X",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Gabc","rW&&AVMSknoPI&&w",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Gabc","rW&&AVMSknoPI&&w",[global])),
- <<"xyzabc">> = iolist_to_binary(re:replace("xyzabc","\\Gabc","DFp\\1NhU&",[])),
- <<"xyzabc">> = iolist_to_binary(re:replace("xyzabc","\\Gabc","DFp\\1NhU&",[global])),
- <<"abc1ifEabc1hgAabc2xyzabc3">> = iolist_to_binary(re:replace("abc1abc2xyzabc3","\\Gabc.","\\1&ifE&hgA",[])),
- <<"abc1ifEabc1hgAabc2ifEabc2hgAxyzabc3">> = iolist_to_binary(re:replace("abc1abc2xyzabc3","\\Gabc.","\\1&ifE&hgA",[global])),
- <<"QCUPbyyjrEabc2xyzabc3">> = iolist_to_binary(re:replace("abc1abc2xyzabc3","abc.","QC\\1\\1UPbyyj\\1rE",[])),
- <<"QCUPbyyjrEQCUPbyyjrExyzQCUPbyyjrE">> = iolist_to_binary(re:replace("abc1abc2xyzabc3","abc.","QC\\1\\1UPbyyj\\1rE",[global])),
- <<"XJIJfY">> = iolist_to_binary(re:replace("XabcdY","a(?x: b c )d","JIJf",[])),
- <<"XJIJfY">> = iolist_to_binary(re:replace("XabcdY","a(?x: b c )d","JIJf",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?x: b c )d","i&J&NwHJGVUFHoXlLB",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?x: b c )d","i&J&NwHJGVUFHoXlLB",[global])),
- <<"Xa b c d Y">> = iolist_to_binary(re:replace("Xa b c d Y","a(?x: b c )d","y&kXPnw&sN&&BHba",[])),
- <<"Xa b c d Y">> = iolist_to_binary(re:replace("Xa b c d Y","a(?x: b c )d","y&kXPnw&sN&&BHba",[global])),
- <<"XUQRabcabcUrY">> = iolist_to_binary(re:replace("XabcY","((?x)x y z | a b c)","UQR&\\1Ur",[])),
- <<"XUQRabcabcUrY">> = iolist_to_binary(re:replace("XabcY","((?x)x y z | a b c)","UQR&\\1Ur",[global])),
- <<"AgqfObHxyztxyzMXSCB">> = iolist_to_binary(re:replace("AxyzB","((?x)x y z | a b c)","gqfObH\\1t&MXSC",[])),
- <<"AgqfObHxyztxyzMXSCB">> = iolist_to_binary(re:replace("AxyzB","((?x)x y z | a b c)","gqfObH\\1t&MXSC",[global])),
- <<"XAAvVabCAjGTsabCPBY">> = iolist_to_binary(re:replace("XabCY","(?i)AB(?-i)C","AAvV&AjGTs&\\1PB",[])),
- <<"XAAvVabCAjGTsabCPBY">> = iolist_to_binary(re:replace("XabCY","(?i)AB(?-i)C","AAvV&AjGTs&\\1PB",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?i)AB(?-i)C","UmCr&Vrv",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?i)AB(?-i)C","UmCr&Vrv",[global])),
- <<"XabcY">> = iolist_to_binary(re:replace("XabcY","(?i)AB(?-i)C","qxteX",[])),
- <<"XabcY">> = iolist_to_binary(re:replace("XabcY","(?i)AB(?-i)C","qxteX",[global])),
- <<"ai">> = iolist_to_binary(re:replace("abCE","((?i)AB(?-i)C|D)E","ai",[])),
- <<"ai">> = iolist_to_binary(re:replace("abCE","((?i)AB(?-i)C|D)E","ai",[global])),
- <<"qRLDKtDtqTDE">> = iolist_to_binary(re:replace("DE","((?i)AB(?-i)C|D)E","qRL\\1Kt\\1tqT&",[])),
- <<"qRLDKtDtqTDE">> = iolist_to_binary(re:replace("DE","((?i)AB(?-i)C|D)E","qRL\\1Kt\\1tqT&",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?i)AB(?-i)C|D)E","tJGWHuAQJuV\\1ohL",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?i)AB(?-i)C|D)E","tJGWHuAQJuV\\1ohL",[global])),
- <<"abcE">> = iolist_to_binary(re:replace("abcE","((?i)AB(?-i)C|D)E","SL",[])),
- <<"abcE">> = iolist_to_binary(re:replace("abcE","((?i)AB(?-i)C|D)E","SL",[global])),
- <<"abCe">> = iolist_to_binary(re:replace("abCe","((?i)AB(?-i)C|D)E","INyHgcjBTk",[])),
- <<"abCe">> = iolist_to_binary(re:replace("abCe","((?i)AB(?-i)C|D)E","INyHgcjBTk",[global])),
- <<"dE">> = iolist_to_binary(re:replace("dE","((?i)AB(?-i)C|D)E","x\\1",[])),
- <<"dE">> = iolist_to_binary(re:replace("dE","((?i)AB(?-i)C|D)E","x\\1",[global])),
- <<"De">> = iolist_to_binary(re:replace("De","((?i)AB(?-i)C|D)E","pgmpT&v&DORqu&",[])),
- <<"De">> = iolist_to_binary(re:replace("De","((?i)AB(?-i)C|D)E","pgmpT&v&DORqu&",[global])),
- <<"abcpy">> = iolist_to_binary(re:replace("abc123abc","(.*)\\d+\\1","\\1py",[])),
- <<"abcpy">> = iolist_to_binary(re:replace("abc123abc","(.*)\\d+\\1","\\1py",[global])),
- <<"aeCYXPUlXbcjXWbcK">> = iolist_to_binary(re:replace("abc123bc","(.*)\\d+\\1","eCYXPUlX\\1jXW\\1K",[])),
- <<"aeCYXPUlXbcjXWbcK">> = iolist_to_binary(re:replace("abc123bc","(.*)\\d+\\1","eCYXPUlX\\1jXW\\1K",[global])),
- <<"hxyLlgCxwsHwpLlIYe">> = iolist_to_binary(re:replace("abc123abc","(.*)\\d+\\1","hxyLlgCxwsHwpLlIYe",[dotall])),
- <<"hxyLlgCxwsHwpLlIYe">> = iolist_to_binary(re:replace("abc123abc","(.*)\\d+\\1","hxyLlgCxwsHwpLlIYe",[dotall,
- global])),
- <<"aubcbcBbcJobcFXYl">> = iolist_to_binary(re:replace("abc123bc","(.*)\\d+\\1","u\\1\\1B\\1Jo\\1FXYl",[dotall])),
- <<"aubcbcBbcJobcFXYl">> = iolist_to_binary(re:replace("abc123bc","(.*)\\d+\\1","u\\1\\1B\\1Jo\\1FXYl",[dotall,
- global])),
- <<"BSBMIqq">> = iolist_to_binary(re:replace("abc123abc","((.*))\\d+\\1","BSBMIqq",[])),
- <<"BSBMIqq">> = iolist_to_binary(re:replace("abc123abc","((.*))\\d+\\1","BSBMIqq",[global])),
- <<"aWbc123bcnWkNJItYcGAvsDNYbW">> = iolist_to_binary(re:replace("abc123bc","((.*))\\d+\\1","W&nWkNJItYcGAvsDNYbW",[])),
- <<"aWbc123bcnWkNJItYcGAvsDNYbW">> = iolist_to_binary(re:replace("abc123bc","((.*))\\d+\\1","W&nWkNJItYcGAvsDNYbW",[global])),
- <<"kDSa123::a123Tp">> = iolist_to_binary(re:replace("a123::a123","^(?!:) # colon disallowed at start
+ literal\\E #more comment","j",[extended,global])),
+ <<"ChAMNBQIJQHq">> = iolist_to_binary(re:replace("abc\\$xyz","\\Qabc\\$xyz\\E","ChAMNBQIJQHq",[])),
+ <<"ChAMNBQIJQHq">> = iolist_to_binary(re:replace("abc\\$xyz","\\Qabc\\$xyz\\E","ChAMNBQIJQHq",[global])),
+ <<"Qabc$xyzKpQ">> = iolist_to_binary(re:replace("abc$xyz","\\Qabc\\E\\$\\Qxyz\\E","Q&KpQ",[])),
+ <<"Qabc$xyzKpQ">> = iolist_to_binary(re:replace("abc$xyz","\\Qabc\\E\\$\\Qxyz\\E","Q&KpQ",[global])),
+ <<"iDjabcXpqUmXasnjCabc">> = iolist_to_binary(re:replace("abc","\\Gabc","\\1i\\1Dj&XpqUmXasnj\\1C\\1&",[])),
+ <<"iDjabcXpqUmXasnjCabc">> = iolist_to_binary(re:replace("abc","\\Gabc","\\1i\\1Dj&XpqUmXasnj\\1C\\1&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Gabc","i\\1joBu\\1ebM",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\Gabc","i\\1joBu\\1ebM",[global])),
+ <<"xyzabc">> = iolist_to_binary(re:replace("xyzabc","\\Gabc","pJK&la&\\1NSiseJOytL",[])),
+ <<"xyzabc">> = iolist_to_binary(re:replace("xyzabc","\\Gabc","pJK&la&\\1NSiseJOytL",[global])),
+ <<"ohvLabc2xyzabc3">> = iolist_to_binary(re:replace("abc1abc2xyzabc3","\\Gabc.","ohvL",[])),
+ <<"ohvLohvLxyzabc3">> = iolist_to_binary(re:replace("abc1abc2xyzabc3","\\Gabc.","ohvL",[global])),
+ <<"HJiFabc1Chbjabc2xyzabc3">> = iolist_to_binary(re:replace("abc1abc2xyzabc3","abc.","HJiF&Chbj",[])),
+ <<"HJiFabc1ChbjHJiFabc2ChbjxyzHJiFabc3Chbj">> = iolist_to_binary(re:replace("abc1abc2xyzabc3","abc.","HJiF&Chbj",[global])),
+ <<"XxabcdrWcHPabcdKQabcdY">> = iolist_to_binary(re:replace("XabcdY","a(?x: b c )d","\\1x&rWcH\\1P&KQ&",[])),
+ <<"XxabcdrWcHPabcdKQabcdY">> = iolist_to_binary(re:replace("XabcdY","a(?x: b c )d","\\1x&rWcH\\1P&KQ&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?x: b c )d","yTwKPU\\1&NhlmWO",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","a(?x: b c )d","yTwKPU\\1&NhlmWO",[global])),
+ <<"Xa b c d Y">> = iolist_to_binary(re:replace("Xa b c d Y","a(?x: b c )d","psI",[])),
+ <<"Xa b c d Y">> = iolist_to_binary(re:replace("Xa b c d Y","a(?x: b c )d","psI",[global])),
+ <<"XOabccFXabcgY">> = iolist_to_binary(re:replace("XabcY","((?x)x y z | a b c)","O&cFX\\1g",[])),
+ <<"XOabccFXabcgY">> = iolist_to_binary(re:replace("XabcY","((?x)x y z | a b c)","O&cFX\\1g",[global])),
+ <<"AxyzaoxyzB">> = iolist_to_binary(re:replace("AxyzB","((?x)x y z | a b c)","\\1ao&",[])),
+ <<"AxyzaoxyzB">> = iolist_to_binary(re:replace("AxyzB","((?x)x y z | a b c)","\\1ao&",[global])),
+ <<"XibY">> = iolist_to_binary(re:replace("XabCY","(?i)AB(?-i)C","ib",[])),
+ <<"XibY">> = iolist_to_binary(re:replace("XabCY","(?i)AB(?-i)C","ib",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?i)AB(?-i)C","wYYUWrmo",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(?i)AB(?-i)C","wYYUWrmo",[global])),
+ <<"XabcY">> = iolist_to_binary(re:replace("XabcY","(?i)AB(?-i)C","o&CXr&jJvHyaNHQ",[])),
+ <<"XabcY">> = iolist_to_binary(re:replace("XabcY","(?i)AB(?-i)C","o&CXr&jJvHyaNHQ",[global])),
+ <<"ouJo">> = iolist_to_binary(re:replace("abCE","((?i)AB(?-i)C|D)E","ouJo",[])),
+ <<"ouJo">> = iolist_to_binary(re:replace("abCE","((?i)AB(?-i)C|D)E","ouJo",[global])),
+ <<"OcHODINyYSDEpUbBfxDEGM">> = iolist_to_binary(re:replace("DE","((?i)AB(?-i)C|D)E","OcHO\\1INyYS&pUbBfx&GM",[])),
+ <<"OcHODINyYSDEpUbBfxDEGM">> = iolist_to_binary(re:replace("DE","((?i)AB(?-i)C|D)E","OcHO\\1INyYS&pUbBfx&GM",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?i)AB(?-i)C|D)E","BYe",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((?i)AB(?-i)C|D)E","BYe",[global])),
+ <<"abcE">> = iolist_to_binary(re:replace("abcE","((?i)AB(?-i)C|D)E","&rB\\1CAA",[])),
+ <<"abcE">> = iolist_to_binary(re:replace("abcE","((?i)AB(?-i)C|D)E","&rB\\1CAA",[global])),
+ <<"abCe">> = iolist_to_binary(re:replace("abCe","((?i)AB(?-i)C|D)E","a&LpvMhr",[])),
+ <<"abCe">> = iolist_to_binary(re:replace("abCe","((?i)AB(?-i)C|D)E","a&LpvMhr",[global])),
+ <<"dE">> = iolist_to_binary(re:replace("dE","((?i)AB(?-i)C|D)E","dS",[])),
+ <<"dE">> = iolist_to_binary(re:replace("dE","((?i)AB(?-i)C|D)E","dS",[global])),
+ <<"De">> = iolist_to_binary(re:replace("De","((?i)AB(?-i)C|D)E","cCfly&",[])),
+ <<"De">> = iolist_to_binary(re:replace("De","((?i)AB(?-i)C|D)E","cCfly&",[global])),
+ <<"Qabc123abcabcLBDabcXabca">> = iolist_to_binary(re:replace("abc123abc","(.*)\\d+\\1","Q&\\1LBD\\1X\\1a",[])),
+ <<"Qabc123abcabcLBDabcXabca">> = iolist_to_binary(re:replace("abc123abc","(.*)\\d+\\1","Q&\\1LBD\\1X\\1a",[global])),
+ <<"anTeSdybc123bcHldppbc123bcDx">> = iolist_to_binary(re:replace("abc123bc","(.*)\\d+\\1","nTeSdy&Hldpp&Dx",[])),
+ <<"anTeSdybc123bcHldppbc123bcDx">> = iolist_to_binary(re:replace("abc123bc","(.*)\\d+\\1","nTeSdy&Hldpp&Dx",[global])),
+ <<"pGabcabcabcabc123abcabc123abcawKG">> = iolist_to_binary(re:replace("abc123abc","(.*)\\d+\\1","pG\\1\\1\\1&&awKG",[dotall])),
+ <<"pGabcabcabcabc123abcabc123abcawKG">> = iolist_to_binary(re:replace("abc123abc","(.*)\\d+\\1","pG\\1\\1\\1&&awKG",[dotall,
+ global])),
+ <<"aMMJMXbc123bcGqwwAbc123bcEnL">> = iolist_to_binary(re:replace("abc123bc","(.*)\\d+\\1","MMJMX&GqwwA&EnL",[dotall])),
+ <<"aMMJMXbc123bcGqwwAbc123bcEnL">> = iolist_to_binary(re:replace("abc123bc","(.*)\\d+\\1","MMJMX&GqwwA&EnL",[dotall,
+ global])),
+ <<"qrVVkabc123abcwTosM">> = iolist_to_binary(re:replace("abc123abc","((.*))\\d+\\1","qrVVk&wTosM",[])),
+ <<"qrVVkabc123abcwTosM">> = iolist_to_binary(re:replace("abc123abc","((.*))\\d+\\1","qrVVk&wTosM",[global])),
+ <<"ayYbc123bcbcPPbcCodRbc123bcKbcVM">> = iolist_to_binary(re:replace("abc123bc","((.*))\\d+\\1","yY&\\1PP\\1CodR&K\\1VM",[])),
+ <<"ayYbc123bcbcPPbcCodRbc123bcKbcVM">> = iolist_to_binary(re:replace("abc123bc","((.*))\\d+\\1","yY&\\1PP\\1CodR&K\\1VM",[global])),
+ <<"LwcvndSdaPKHex">> = iolist_to_binary(re:replace("a123::a123","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18142,8 +18137,8 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","kDS&T\\1p",[extended,caseless])),
- <<"kDSa123::a123Tp">> = iolist_to_binary(re:replace("a123::a123","^(?!:) # colon disallowed at start
+ ","LwcvndSdaPKHex",[extended,caseless])),
+ <<"LwcvndSdaPKHex">> = iolist_to_binary(re:replace("a123::a123","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18151,8 +18146,8 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","kDS&T\\1p",[extended,caseless,global])),
- <<"r">> = iolist_to_binary(re:replace("a123:b342::abcd","^(?!:) # colon disallowed at start
+ ","LwcvndSdaPKHex",[extended,caseless,global])),
+ <<"RfGpa123:b342::abcdjkWGiWxPCIAx">> = iolist_to_binary(re:replace("a123:b342::abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18160,8 +18155,8 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","r",[extended,caseless])),
- <<"r">> = iolist_to_binary(re:replace("a123:b342::abcd","^(?!:) # colon disallowed at start
+ ","R\\1fGp&\\1jkWGiWxPCIAx",[extended,caseless])),
+ <<"RfGpa123:b342::abcdjkWGiWxPCIAx">> = iolist_to_binary(re:replace("a123:b342::abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18169,8 +18164,8 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","r",[extended,caseless,global])),
- <<"ia123:b342::324e:abcd">> = iolist_to_binary(re:replace("a123:b342::324e:abcd","^(?!:) # colon disallowed at start
+ ","R\\1fGp&\\1jkWGiWxPCIAx",[extended,caseless,global])),
+ <<"FBOvYuiruXBa123:b342::324e:abcdaag">> = iolist_to_binary(re:replace("a123:b342::324e:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18178,8 +18173,8 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","i&",[extended,caseless])),
- <<"ia123:b342::324e:abcd">> = iolist_to_binary(re:replace("a123:b342::324e:abcd","^(?!:) # colon disallowed at start
+ ","FBOvYuir\\1uXB&aag",[extended,caseless])),
+ <<"FBOvYuiruXBa123:b342::324e:abcdaag">> = iolist_to_binary(re:replace("a123:b342::324e:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18187,8 +18182,8 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","i&",[extended,caseless,global])),
- <<"eYuTiBYPtHa123:ddde:b342::324e:abcdJHIw">> = iolist_to_binary(re:replace("a123:ddde:b342::324e:abcd","^(?!:) # colon disallowed at start
+ ","FBOvYuir\\1uXB&aag",[extended,caseless,global])),
+ <<"krOa123:ddde:b342::324e:abcdnoa123:ddde:b342::324e:abcdAqWa123:ddde:b342::324e:abcdLa123:ddde:b342::324e:abcdkpysY">> = iolist_to_binary(re:replace("a123:ddde:b342::324e:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18196,8 +18191,8 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","eYuTiBYPtH&J\\1HIw",[extended,caseless])),
- <<"eYuTiBYPtHa123:ddde:b342::324e:abcdJHIw">> = iolist_to_binary(re:replace("a123:ddde:b342::324e:abcd","^(?!:) # colon disallowed at start
+ ","krO&no&\\1Aq\\1W&L&kpysY",[extended,caseless])),
+ <<"krOa123:ddde:b342::324e:abcdnoa123:ddde:b342::324e:abcdAqWa123:ddde:b342::324e:abcdLa123:ddde:b342::324e:abcdkpysY">> = iolist_to_binary(re:replace("a123:ddde:b342::324e:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18205,8 +18200,8 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","eYuTiBYPtH&J\\1HIw",[extended,caseless,global])),
- <<"">> = iolist_to_binary(re:replace("a123:ddde:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
+ ","krO&no&\\1Aq\\1W&L&kpysY",[extended,caseless,global])),
+ <<"DkvAQa123:ddde:b342::324e:dcba:abcdJw">> = iolist_to_binary(re:replace("a123:ddde:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18214,8 +18209,8 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","\\1",[extended,caseless])),
- <<"">> = iolist_to_binary(re:replace("a123:ddde:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
+ ","Dk\\1vAQ&J\\1w",[extended,caseless])),
+ <<"DkvAQa123:ddde:b342::324e:dcba:abcdJw">> = iolist_to_binary(re:replace("a123:ddde:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18223,8 +18218,8 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","\\1",[extended,caseless,global])),
- <<"a123:ddde:9999:b342::324e:dcba:abcdoLIelBa123:ddde:9999:b342::324e:dcba:abcd">> = iolist_to_binary(re:replace("a123:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
+ ","Dk\\1vAQ&J\\1w",[extended,caseless,global])),
+ <<"peonyvOkMFYpa123:ddde:9999:b342::324e:dcba:abcdp">> = iolist_to_binary(re:replace("a123:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18232,8 +18227,8 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","&oLIelB&",[extended,caseless])),
- <<"a123:ddde:9999:b342::324e:dcba:abcdoLIelBa123:ddde:9999:b342::324e:dcba:abcd">> = iolist_to_binary(re:replace("a123:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
+ ","peo\\1n\\1yvOkMFY\\1\\1p&p",[extended,caseless])),
+ <<"peonyvOkMFYpa123:ddde:9999:b342::324e:dcba:abcdp">> = iolist_to_binary(re:replace("a123:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
(?(1)0 | () ) ) # if null previously matched, fail; else null
@@ -18241,7 +18236,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","&oLIelB&",[extended,caseless,global])),
+ ","peo\\1n\\1yvOkMFY\\1\\1p&p",[extended,caseless,global])),
<<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18250,7 +18245,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","&f\\1I",[extended,caseless])),
+ ","qiY&iLNeXJ",[extended,caseless])),
<<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18259,7 +18254,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","&f\\1I",[extended,caseless,global])),
+ ","qiY&iLNeXJ",[extended,caseless,global])),
<<"1:2:3:4:5:6:7:8">> = iolist_to_binary(re:replace("1:2:3:4:5:6:7:8","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18268,7 +18263,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","yUIYbm&\\1qdJb",[extended,caseless])),
+ ","O\\1E\\1yvbw\\1G&eF",[extended,caseless])),
<<"1:2:3:4:5:6:7:8">> = iolist_to_binary(re:replace("1:2:3:4:5:6:7:8","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18277,7 +18272,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","yUIYbm&\\1qdJb",[extended,caseless,global])),
+ ","O\\1E\\1yvbw\\1G&eF",[extended,caseless,global])),
<<"a123:bce:ddde:9999:b342::324e:dcba:abcd">> = iolist_to_binary(re:replace("a123:bce:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18286,7 +18281,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","Xhy\\1&M",[extended,caseless])),
+ ","dLaiU",[extended,caseless])),
<<"a123:bce:ddde:9999:b342::324e:dcba:abcd">> = iolist_to_binary(re:replace("a123:bce:ddde:9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18295,7 +18290,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","Xhy\\1&M",[extended,caseless,global])),
+ ","dLaiU",[extended,caseless,global])),
<<"a123::9999:b342::324e:dcba:abcd">> = iolist_to_binary(re:replace("a123::9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18304,7 +18299,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","sw",[extended,caseless])),
+ ","wLFUSYFg&aIH\\1g&V",[extended,caseless])),
<<"a123::9999:b342::324e:dcba:abcd">> = iolist_to_binary(re:replace("a123::9999:b342::324e:dcba:abcd","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18313,7 +18308,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","sw",[extended,caseless,global])),
+ ","wLFUSYFg&aIH\\1g&V",[extended,caseless,global])),
<<"abcde:2:3:4:5:6:7:8">> = iolist_to_binary(re:replace("abcde:2:3:4:5:6:7:8","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18322,7 +18317,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","pCUAeIjhQXp\\1K",[extended,caseless])),
+ ","giXrPJTSn\\1MX\\1C",[extended,caseless])),
<<"abcde:2:3:4:5:6:7:8">> = iolist_to_binary(re:replace("abcde:2:3:4:5:6:7:8","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18331,7 +18326,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","pCUAeIjhQXp\\1K",[extended,caseless,global])),
+ ","giXrPJTSn\\1MX\\1C",[extended,caseless,global])),
<<"::1">> = iolist_to_binary(re:replace("::1","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18340,7 +18335,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","rN\\1Dti&",[extended,caseless])),
+ ","vQ&R&",[extended,caseless])),
<<"::1">> = iolist_to_binary(re:replace("::1","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18349,7 +18344,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","rN\\1Dti&",[extended,caseless,global])),
+ ","vQ&R&",[extended,caseless,global])),
<<"abcd:fee0:123::">> = iolist_to_binary(re:replace("abcd:fee0:123::","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18358,7 +18353,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","eRNkqHK\\1RXNGFgu",[extended,caseless])),
+ ","wNB\\1C\\1T&k&vkfjS",[extended,caseless])),
<<"abcd:fee0:123::">> = iolist_to_binary(re:replace("abcd:fee0:123::","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18367,7 +18362,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","eRNkqHK\\1RXNGFgu",[extended,caseless,global])),
+ ","wNB\\1C\\1T&k&vkfjS",[extended,caseless,global])),
<<":1">> = iolist_to_binary(re:replace(":1","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18376,7 +18371,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","mbx",[extended,caseless])),
+ ","akxV\\1iHF&SgDPd&",[extended,caseless])),
<<":1">> = iolist_to_binary(re:replace(":1","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18385,7 +18380,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","mbx",[extended,caseless,global])),
+ ","akxV\\1iHF&SgDPd&",[extended,caseless,global])),
<<"1:">> = iolist_to_binary(re:replace("1:","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18394,7 +18389,7 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","WJB",[extended,caseless])),
+ ","QtJG\\1",[extended,caseless])),
<<"1:">> = iolist_to_binary(re:replace("1:","^(?!:) # colon disallowed at start
(?: # start of item
(?: [0-9a-f]{1,4} | # 1-4 hex digits or
@@ -18403,1557 +18398,1620 @@ run33() ->
){1,7} # end item; 1-7 of them required
[0-9a-f]{1,4} $ # final hex number at end of string
(?(1)|.) # check that there was an empty component
- ","WJB",[extended,caseless,global])),
- <<"NdcuJzCbxTd">> = iolist_to_binary(re:replace("z","[z\\Qa-d]\\E]","NdcuJ\\1&CbxTd",[])),
- <<"NdcuJzCbxTd">> = iolist_to_binary(re:replace("z","[z\\Qa-d]\\E]","NdcuJ\\1&CbxTd",[global])),
- <<"VLxNqfjwruLh">> = iolist_to_binary(re:replace("a","[z\\Qa-d]\\E]","VL\\1xNqfj\\1wruLh",[])),
- <<"VLxNqfjwruLh">> = iolist_to_binary(re:replace("a","[z\\Qa-d]\\E]","VL\\1xNqfj\\1wruLh",[global])),
- <<"jX">> = iolist_to_binary(re:replace("-","[z\\Qa-d]\\E]","jX",[])),
- <<"jX">> = iolist_to_binary(re:replace("-","[z\\Qa-d]\\E]","jX",[global])),
- <<"XRHLEUuwPyRxGJEv">> = iolist_to_binary(re:replace("d","[z\\Qa-d]\\E]","X\\1RHLEUuwP\\1yRxGJEv",[])),
- <<"XRHLEUuwPyRxGJEv">> = iolist_to_binary(re:replace("d","[z\\Qa-d]\\E]","X\\1RHLEUuwP\\1yRxGJEv",[global])),
- <<"Gtcd">> = iolist_to_binary(re:replace("]","[z\\Qa-d]\\E]","Gt\\1cd",[])),
- <<"Gtcd">> = iolist_to_binary(re:replace("]","[z\\Qa-d]\\E]","Gt\\1cd",[global])),
- <<"*** FCaQDFtaYgknvailers">> = iolist_to_binary(re:replace("*** Failers","[z\\Qa-d]\\E]","C&Q\\1\\1\\1DF\\1t&Ygknv&\\1",[])),
- <<"*** FCaQDFtaYgknvailers">> = iolist_to_binary(re:replace("*** Failers","[z\\Qa-d]\\E]","C&Q\\1\\1\\1DF\\1t&Ygknv&\\1",[global])),
- <<"b">> = iolist_to_binary(re:replace("b","[z\\Qa-d]\\E]","rUhPPBvokQvYvRC",[])),
- <<"b">> = iolist_to_binary(re:replace("b","[z\\Qa-d]\\E]","rUhPPBvokQvYvRC",[global])),
+ ","QtJG\\1",[extended,caseless,global])),
+ <<"thCzKtzX">> = iolist_to_binary(re:replace("z","[z\\Qa-d]\\E]","thC&Kt&X",[])),
+ <<"thCzKtzX">> = iolist_to_binary(re:replace("z","[z\\Qa-d]\\E]","thC&Kt&X",[global])),
+ <<"OWpbwPvaaDXmmr">> = iolist_to_binary(re:replace("a","[z\\Qa-d]\\E]","OWpbwPv&&DXmmr",[])),
+ <<"OWpbwPvaaDXmmr">> = iolist_to_binary(re:replace("a","[z\\Qa-d]\\E]","OWpbwPv&&DXmmr",[global])),
+ <<"vRf--tS-JWPTPl">> = iolist_to_binary(re:replace("-","[z\\Qa-d]\\E]","vR\\1\\1\\1f&&tS&JWPTPl",[])),
+ <<"vRf--tS-JWPTPl">> = iolist_to_binary(re:replace("-","[z\\Qa-d]\\E]","vR\\1\\1\\1f&&tS&JWPTPl",[global])),
+ <<"jExdDgrsjrfGMEAj">> = iolist_to_binary(re:replace("d","[z\\Qa-d]\\E]","j\\1Ex&Dgrsjrf\\1GMEA\\1j",[])),
+ <<"jExdDgrsjrfGMEAj">> = iolist_to_binary(re:replace("d","[z\\Qa-d]\\E]","j\\1Ex&Dgrsjrf\\1GMEA\\1j",[global])),
+ <<"BvV]Aqf">> = iolist_to_binary(re:replace("]","[z\\Qa-d]\\E]","BvV&Aqf",[])),
+ <<"BvV]Aqf">> = iolist_to_binary(re:replace("]","[z\\Qa-d]\\E]","BvV&Aqf",[global])),
+ <<"*** FhQsGEilers">> = iolist_to_binary(re:replace("*** Failers","[z\\Qa-d]\\E]","hQsG\\1E",[])),
+ <<"*** FhQsGEilers">> = iolist_to_binary(re:replace("*** Failers","[z\\Qa-d]\\E]","hQsG\\1E",[global])),
+ <<"b">> = iolist_to_binary(re:replace("b","[z\\Qa-d]\\E]","W\\1Au",[])),
+ <<"b">> = iolist_to_binary(re:replace("b","[z\\Qa-d]\\E]","W\\1Au",[global])),
ok.
run34() ->
- <<"jOKAO">> = iolist_to_binary(re:replace("z","[\\z\\C]","jOKAO",[])),
- <<"jOKAO">> = iolist_to_binary(re:replace("z","[\\z\\C]","jOKAO",[global])),
- <<"UIfGQohtPCcNiR">> = iolist_to_binary(re:replace("C","[\\z\\C]","\\1UIfGQohtP&c\\1\\1NiR",[])),
- <<"UIfGQohtPCcNiR">> = iolist_to_binary(re:replace("C","[\\z\\C]","\\1UIfGQohtP&c\\1\\1NiR",[global])),
- <<"xjHNUJliwGsC">> = iolist_to_binary(re:replace("M","\\M","xjHNUJ\\1liwGsC",[])),
- <<"xjHNUJliwGsC">> = iolist_to_binary(re:replace("M","\\M","xjHNUJ\\1liwGsC",[global])),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b","ss\\1vxH\\1fmwG",[])),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b","ss\\1vxH\\1fmwG",[global])),
- <<"„XAZXS">> = iolist_to_binary(re:replace("„XAZXB","(?<=Z)X.","XS",[])),
- <<"„XAZXS">> = iolist_to_binary(re:replace("„XAZXB","(?<=Z)X.","XS",[global])),
- <<"fU">> = iolist_to_binary(re:replace("ab cd defg","ab cd (?x) de fg","fU",[])),
- <<"fU">> = iolist_to_binary(re:replace("ab cd defg","ab cd (?x) de fg","fU",[global])),
- <<"ditab cddefg">> = iolist_to_binary(re:replace("ab cddefg","ab cd(?x) de fg","\\1dit&",[])),
- <<"ditab cddefg">> = iolist_to_binary(re:replace("ab cddefg","ab cd(?x) de fg","\\1dit&",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","ab cd(?x) de fg","&Kr&\\1EgsvGfRsKlm",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","ab cd(?x) de fg","&Kr&\\1EgsvGfRsKlm",[global])),
- <<"abcddefg">> = iolist_to_binary(re:replace("abcddefg","ab cd(?x) de fg","\\1",[])),
- <<"abcddefg">> = iolist_to_binary(re:replace("abcddefg","ab cd(?x) de fg","\\1",[global])),
- <<"fooXSbarrbNX">> = iolist_to_binary(re:replace("foobarX","(?<![^f]oo)(bar)","XS\\1rbN",[])),
- <<"fooXSbarrbNX">> = iolist_to_binary(re:replace("foobarX","(?<![^f]oo)(bar)","XS\\1rbN",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<![^f]oo)(bar)","P\\1\\1\\1&C\\1N\\1DLnhU&T",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<![^f]oo)(bar)","P\\1\\1\\1&C\\1N\\1DLnhU&T",[global])),
- <<"boobarX">> = iolist_to_binary(re:replace("boobarX","(?<![^f]oo)(bar)","S&HuDj&pl&\\1K",[])),
- <<"boobarX">> = iolist_to_binary(re:replace("boobarX","(?<![^f]oo)(bar)","S&HuDj&pl&\\1K",[global])),
- <<"offAWvYjHsJodXLI">> = iolist_to_binary(re:replace("offX","(?<![^f])X","AWvYjHs\\1J\\1od&LI",[])),
- <<"offAWvYjHsJodXLI">> = iolist_to_binary(re:replace("offX","(?<![^f])X","AWvYjHs\\1J\\1od&LI",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<![^f])X","\\1on",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<![^f])X","\\1on",[global])),
- <<"onyX">> = iolist_to_binary(re:replace("onyX","(?<![^f])X","&f&D",[])),
- <<"onyX">> = iolist_to_binary(re:replace("onyX","(?<![^f])X","&f&D",[global])),
- <<"onyE">> = iolist_to_binary(re:replace("onyX","(?<=[^f])X","E",[])),
- <<"onyE">> = iolist_to_binary(re:replace("onyX","(?<=[^f])X","E",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^f])X","lEuucWp\\1&m",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^f])X","lEuucWp\\1&m",[global])),
- <<"offX">> = iolist_to_binary(re:replace("offX","(?<=[^f])X","QNevBRs\\1&OKqB&\\1\\1H",[])),
- <<"offX">> = iolist_to_binary(re:replace("offX","(?<=[^f])X","QNevBRs\\1&OKqB&\\1\\1H",[global])),
- <<"lHqgba
+ <<"KdrNqNfSzzqidyBChn">> = iolist_to_binary(re:replace("z","[\\z\\C]","KdrNqNfS\\1&&qidyBChn",[])),
+ <<"KdrNqNfSzzqidyBChn">> = iolist_to_binary(re:replace("z","[\\z\\C]","KdrNqNfS\\1&&qidyBChn",[global])),
+ <<"FWM">> = iolist_to_binary(re:replace("C","[\\z\\C]","FW\\1M",[])),
+ <<"FWM">> = iolist_to_binary(re:replace("C","[\\z\\C]","FW\\1M",[global])),
+ <<"FxjIeXxjLM">> = iolist_to_binary(re:replace("M","\\M","FxjIeXxjL&",[])),
+ <<"FxjIeXxjLM">> = iolist_to_binary(re:replace("M","\\M","FxjIeXxjL&",[global])),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b","\\1AGI&o&owvv&Ew",[])),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b","\\1AGI&o&owvv&Ew",[global])),
+ <<"„XAZidYPfGETo">> = iolist_to_binary(re:replace("„XAZXB","(?<=Z)X.","\\1\\1\\1idYPfGETo",[])),
+ <<"„XAZidYPfGETo">> = iolist_to_binary(re:replace("„XAZXB","(?<=Z)X.","\\1\\1\\1idYPfGETo",[global])),
+ <<"bNQDHCQab cd defgab cd defgLqxKPLt">> = iolist_to_binary(re:replace("ab cd defg","ab cd (?x) de fg","bNQDHCQ&&LqxKPLt",[])),
+ <<"bNQDHCQab cd defgab cd defgLqxKPLt">> = iolist_to_binary(re:replace("ab cd defg","ab cd (?x) de fg","bNQDHCQ&&LqxKPLt",[global])),
+ <<"kPHqOwBhoab cddefgWcAxPfqs">> = iolist_to_binary(re:replace("ab cddefg","ab cd(?x) de fg","k\\1PHqOwBho&WcAxP\\1fqs",[])),
+ <<"kPHqOwBhoab cddefgWcAxPfqs">> = iolist_to_binary(re:replace("ab cddefg","ab cd(?x) de fg","k\\1PHqOwBho&WcAxP\\1fqs",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","ab cd(?x) de fg","puhITHF\\1GmjJlsK",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","ab cd(?x) de fg","puhITHF\\1GmjJlsK",[global])),
+ <<"abcddefg">> = iolist_to_binary(re:replace("abcddefg","ab cd(?x) de fg","\\1UHa&nN\\1cm",[])),
+ <<"abcddefg">> = iolist_to_binary(re:replace("abcddefg","ab cd(?x) de fg","\\1UHa&nN\\1cm",[global])),
+ <<"foobarX">> = iolist_to_binary(re:replace("foobarX","(?<![^f]oo)(bar)","&",[])),
+ <<"foobarX">> = iolist_to_binary(re:replace("foobarX","(?<![^f]oo)(bar)","&",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<![^f]oo)(bar)","\\1Mu\\1yADtGr",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<![^f]oo)(bar)","\\1Mu\\1yADtGr",[global])),
+ <<"boobarX">> = iolist_to_binary(re:replace("boobarX","(?<![^f]oo)(bar)","xE&\\1\\1\\1oKH",[])),
+ <<"boobarX">> = iolist_to_binary(re:replace("boobarX","(?<![^f]oo)(bar)","xE&\\1\\1\\1oKH",[global])),
+ <<"offYXXLgEkUWX">> = iolist_to_binary(re:replace("offX","(?<![^f])X","Y&&L\\1gEkUW&",[])),
+ <<"offYXXLgEkUWX">> = iolist_to_binary(re:replace("offX","(?<![^f])X","Y&&L\\1gEkUW&",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<![^f])X","WPlO&&XQQJOC&\\1SLu&I\\1",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<![^f])X","WPlO&&XQQJOC&\\1SLu&I\\1",[global])),
+ <<"onyX">> = iolist_to_binary(re:replace("onyX","(?<![^f])X","&&",[])),
+ <<"onyX">> = iolist_to_binary(re:replace("onyX","(?<![^f])X","&&",[global])),
+ <<"onyGaqXoXBMVBEXtSYRHR">> = iolist_to_binary(re:replace("onyX","(?<=[^f])X","Gaq&oXBMVBE&tSYRHR",[])),
+ <<"onyGaqXoXBMVBEXtSYRHR">> = iolist_to_binary(re:replace("onyX","(?<=[^f])X","Gaq&oXBMVBE&tSYRHR",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^f])X","Djt&",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^f])X","Djt&",[global])),
+ <<"offX">> = iolist_to_binary(re:replace("offX","(?<=[^f])X","GvvcQ\\1\\1&lBxPYfk&",[])),
+ <<"offX">> = iolist_to_binary(re:replace("offX","(?<=[^f])X","GvvcQ\\1\\1&lBxPYfk&",[global])),
+ <<"CrHVKxYsa
b
c">> = iolist_to_binary(re:replace("a
b
-c","^","lHqg&b&",[multiline])),
- <<"lHqgba
-lHqgbb
-lHqgbc">> = iolist_to_binary(re:replace("a
+c","^","\\1CrHVKxYs",[multiline])),
+ <<"CrHVKxYsa
+CrHVKxYsb
+CrHVKxYsc">> = iolist_to_binary(re:replace("a
b
-c","^","lHqg&b&",[multiline,global])),
- <<"VDMcObuOyb">> = iolist_to_binary(re:replace("","^","VDM&cObuOy\\1b",[multiline])),
- <<"VDMcObuOyb">> = iolist_to_binary(re:replace("","^","VDM&cObuOy\\1b",[multiline,
- global])),
+c","^","\\1CrHVKxYs",[multiline,global])),
+ <<"tQATKgVWcvM">> = iolist_to_binary(re:replace("","^","tQATKgVW&cvM",[multiline])),
+ <<"tQATKgVWcvM">> = iolist_to_binary(re:replace("","^","tQATKgVW&cvM",[multiline,
+ global])),
<<"A
C
-luYGJMVrKYIkybC">> = iolist_to_binary(re:replace("A
+mnoJCDrViHC">> = iolist_to_binary(re:replace("A
C
-C","(?<=C\\n)^","lu\\1Y&GJM\\1VrKY&Ikyb\\1",[multiline])),
+C","(?<=C\\n)^","&mnoJCD&rV&iH",[multiline])),
<<"A
C
-luYGJMVrKYIkybC">> = iolist_to_binary(re:replace("A
+mnoJCDrViHC">> = iolist_to_binary(re:replace("A
C
-C","(?<=C\\n)^","lu\\1Y&GJM\\1VrKY&Ikyb\\1",[multiline,global])),
- <<"siXpqbXaXURhpboidbXaXRg">> = iolist_to_binary(re:replace("bXaX","(?:(?(1)a|b)(X))+","si\\1pq&URhpboid&Rg",[])),
- <<"siXpqbXaXURhpboidbXaXRg">> = iolist_to_binary(re:replace("bXaX","(?:(?(1)a|b)(X))+","si\\1pq&URhpboid&Rg",[global])),
- <<"AmhmmmbXXaYYaYAOkoG">> = iolist_to_binary(re:replace("bXXaYYaY","(?:(?(1)\\1a|b)(X|Y))+","Amhmmm&AOkoG",[])),
- <<"AmhmmmbXXaYYaYAOkoG">> = iolist_to_binary(re:replace("bXXaYYaY","(?:(?(1)\\1a|b)(X|Y))+","Amhmmm&AOkoG",[global])),
- <<"PtXQXEwjfhYaXXaX">> = iolist_to_binary(re:replace("bXYaXXaX","(?:(?(1)\\1a|b)(X|Y))+","PtXQ\\1Ewjfh",[])),
- <<"PtXQXEwjfhYaXXaX">> = iolist_to_binary(re:replace("bXYaXXaX","(?:(?(1)\\1a|b)(X|Y))+","PtXQ\\1Ewjfh",[global])),
- <<"qpflyycYXuQXaYYaY">> = iolist_to_binary(re:replace("bXXaYYaY","()()()()()()()()()(?:(?(10)\\10a|b)(X|Y))+","q\\1pflyycY\\1XuQ",[])),
- <<"qpflyycYXuQXaYYaY">> = iolist_to_binary(re:replace("bXXaYYaY","()()()()()()()()()(?:(?(10)\\10a|b)(X|Y))+","q\\1pflyycY\\1XuQ",[global])),
- <<"abc]GgJESKfdixjabc]">> = iolist_to_binary(re:replace("abc]","[[,abc,]+]","&GgJESKf\\1di\\1xj&",[])),
- <<"abc]GgJESKfdixjabc]">> = iolist_to_binary(re:replace("abc]","[[,abc,]+]","&GgJESKf\\1di\\1xj&",[global])),
- <<"wa,b]a,b]hta,b]NQ">> = iolist_to_binary(re:replace("a,b]","[[,abc,]+]","w&&ht&N\\1Q",[])),
- <<"wa,b]a,b]hta,b]NQ">> = iolist_to_binary(re:replace("a,b]","[[,abc,]+]","w&&ht&N\\1Q",[global])),
- <<"aDIlRnUPE[a,b,c]VAaV[a,b,c]V">> = iolist_to_binary(re:replace("[a,b,c]","[[,abc,]+]","aDIlRnU\\1PE&VAaV&V",[])),
- <<"aDIlRnUPE[a,b,c]VAaV[a,b,c]V">> = iolist_to_binary(re:replace("[a,b,c]","[[,abc,]+]","aDIlRnU\\1PE&VAaV&V",[global])),
- <<"AVNFmY XbCfJ B">> = iolist_to_binary(re:replace("A B","(?-x: )","V\\1NFmY\\1&X\\1bC\\1fJ&",[extended])),
- <<"AVNFmY XbCfJ B">> = iolist_to_binary(re:replace("A B","(?-x: )","V\\1NFmY\\1&X\\1bC\\1fJ&",[extended,
- global])),
- <<"ABB">> = iolist_to_binary(re:replace("A # B","(?x)(?-x: \\s*#\\s*)","B",[])),
- <<"ABB">> = iolist_to_binary(re:replace("A # B","(?x)(?-x: \\s*#\\s*)","B",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?x)(?-x: \\s*#\\s*)","&CgSC",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?x)(?-x: \\s*#\\s*)","&CgSC",[global])),
- <<"#">> = iolist_to_binary(re:replace("#","(?x)(?-x: \\s*#\\s*)","&&VXAaYSEf",[])),
- <<"#">> = iolist_to_binary(re:replace("#","(?x)(?-x: \\s*#\\s*)","&&VXAaYSEf",[global])),
- <<"A #includeu">> = iolist_to_binary(re:replace("A #include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","&u",[])),
- <<"A #includeu">> = iolist_to_binary(re:replace("A #include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","&u",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?x-is)(?:(?-ixs) \\s*#\\s*) include","KyMhf",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?x-is)(?:(?-ixs) \\s*#\\s*) include","KyMhf",[global])),
- <<"A#include">> = iolist_to_binary(re:replace("A#include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","PFlBaBuo\\1\\1\\1&Uu",[])),
- <<"A#include">> = iolist_to_binary(re:replace("A#include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","PFlBaBuo\\1\\1\\1&Uu",[global])),
- <<"A #Include">> = iolist_to_binary(re:replace("A #Include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","D\\1SrsbvVOeg\\1OC&Wy",[])),
- <<"A #Include">> = iolist_to_binary(re:replace("A #Include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","D\\1SrsbvVOeg\\1OC&Wy",[global])),
+C","(?<=C\\n)^","&mnoJCD&rV&iH",[multiline,global])),
+ <<"sybXaXBDYtXeaMXPXnbXaXbXaXC">> = iolist_to_binary(re:replace("bXaX","(?:(?(1)a|b)(X))+","sy&BDYt\\1eaM\\1P\\1n&&C",[])),
+ <<"sybXaXBDYtXeaMXPXnbXaXbXaXC">> = iolist_to_binary(re:replace("bXaX","(?:(?(1)a|b)(X))+","sy&BDYt\\1eaM\\1P\\1n&&C",[global])),
+ <<"KbXXaYYaYufAhHxbYRbXXaYYaYEGpjWY">> = iolist_to_binary(re:replace("bXXaYYaY","(?:(?(1)\\1a|b)(X|Y))+","K&ufAhHxb\\1R&EGpjW\\1",[])),
+ <<"KbXXaYYaYufAhHxbYRbXXaYYaYEGpjWY">> = iolist_to_binary(re:replace("bXXaYYaY","(?:(?(1)\\1a|b)(X|Y))+","K&ufAhHxb\\1R&EGpjW\\1",[global])),
+ <<"bXsOgbTHbXCbXuonYaXXaX">> = iolist_to_binary(re:replace("bXYaXXaX","(?:(?(1)\\1a|b)(X|Y))+","&sOgbTH&C&uon",[])),
+ <<"bXsOgbTHbXCbXuonYaXXaX">> = iolist_to_binary(re:replace("bXYaXXaX","(?:(?(1)\\1a|b)(X|Y))+","&sOgbTH&C&uon",[global])),
+ <<"JneobXbXBXXaYYaY">> = iolist_to_binary(re:replace("bXXaYYaY","()()()()()()()()()(?:(?(10)\\10a|b)(X|Y))+","Jn\\1eo&&BX\\1\\1",[])),
+ <<"JneobXbXBXXaYYaY">> = iolist_to_binary(re:replace("bXXaYYaY","()()()()()()()()()(?:(?(10)\\10a|b)(X|Y))+","Jn\\1eo&&BX\\1\\1",[global])),
+ <<"MGXaAc">> = iolist_to_binary(re:replace("abc]","[[,abc,]+]","MGXaAc",[])),
+ <<"MGXaAc">> = iolist_to_binary(re:replace("abc]","[[,abc,]+]","MGXaAc",[global])),
+ <<"QLdwhNFO">> = iolist_to_binary(re:replace("a,b]","[[,abc,]+]","QLdw\\1hNFO",[])),
+ <<"QLdwhNFO">> = iolist_to_binary(re:replace("a,b]","[[,abc,]+]","QLdw\\1hNFO",[global])),
+ <<"mrAsBve[a,b,c]UksE[a,b,c]">> = iolist_to_binary(re:replace("[a,b,c]","[[,abc,]+]","mrAsBve&U\\1k\\1sE&",[])),
+ <<"mrAsBve[a,b,c]UksE[a,b,c]">> = iolist_to_binary(re:replace("[a,b,c]","[[,abc,]+]","mrAsBve&U\\1k\\1sE&",[global])),
+ <<"AiIoucpHiJtVB">> = iolist_to_binary(re:replace("A B","(?-x: )","iI\\1oucpHiJtV",[extended])),
+ <<"AiIoucpHiJtVB">> = iolist_to_binary(re:replace("A B","(?-x: )","iI\\1oucpHiJtV",[extended,
+ global])),
+ <<"AfRWj # PetBdVWqyB">> = iolist_to_binary(re:replace("A # B","(?x)(?-x: \\s*#\\s*)","fRWj\\1&Pe\\1\\1tBdVW\\1qy",[])),
+ <<"AfRWj # PetBdVWqyB">> = iolist_to_binary(re:replace("A # B","(?x)(?-x: \\s*#\\s*)","fRWj\\1&Pe\\1\\1tBdVW\\1qy",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?x)(?-x: \\s*#\\s*)","thjvygK\\1p&pYs\\1uBr",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?x)(?-x: \\s*#\\s*)","thjvygK\\1p&pYs\\1uBr",[global])),
+ <<"#">> = iolist_to_binary(re:replace("#","(?x)(?-x: \\s*#\\s*)","tbFvq\\1IQg\\1RTAxEph",[])),
+ <<"#">> = iolist_to_binary(re:replace("#","(?x)(?-x: \\s*#\\s*)","tbFvq\\1IQg\\1RTAxEph",[global])),
+ <<"AVTpQN #includeS">> = iolist_to_binary(re:replace("A #include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","V\\1TpQN&S",[])),
+ <<"AVTpQN #includeS">> = iolist_to_binary(re:replace("A #include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","V\\1TpQN&S",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?x-is)(?:(?-ixs) \\s*#\\s*) include","wlsB\\1O",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?x-is)(?:(?-ixs) \\s*#\\s*) include","wlsB\\1O",[global])),
+ <<"A#include">> = iolist_to_binary(re:replace("A#include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","Yo\\1qtePMHamKUo&",[])),
+ <<"A#include">> = iolist_to_binary(re:replace("A#include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","Yo\\1qtePMHamKUo&",[global])),
+ <<"A #Include">> = iolist_to_binary(re:replace("A #Include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","\\1e&&X&vW",[])),
+ <<"A #Include">> = iolist_to_binary(re:replace("A #Include","(?x-is)(?:(?-ixs) \\s*#\\s*) include","\\1e&&X&vW",[global])),
ok.
run35() ->
- <<"AYafQSUNhFRibaaabbbbT">> = iolist_to_binary(re:replace("aaabbbb","a*b*\\w","AYafQSUNhFRib&T",[])),
- <<"AYafQSUNhFRibaaabbbbT">> = iolist_to_binary(re:replace("aaabbbb","a*b*\\w","AYafQSUNhFRib&T",[global])),
- <<"vKBXMQS">> = iolist_to_binary(re:replace("aaaa","a*b*\\w","vKBXMQS\\1",[])),
- <<"vKBXMQS">> = iolist_to_binary(re:replace("aaaa","a*b*\\w","vKBXMQS\\1",[global])),
- <<"atbBVaRw">> = iolist_to_binary(re:replace("a","a*b*\\w","&tbBV&Rw",[])),
- <<"atbBVaRw">> = iolist_to_binary(re:replace("a","a*b*\\w","&tbBV&Rw",[global])),
- <<"QDXPfbb">> = iolist_to_binary(re:replace("aaabbbb","a*b?\\w","QDXPf\\1",[])),
- <<"QDXPfQDXPf">> = iolist_to_binary(re:replace("aaabbbb","a*b?\\w","QDXPf\\1",[global])),
- <<"qIIJaaaafyqkXQdN">> = iolist_to_binary(re:replace("aaaa","a*b?\\w","qIIJ&fyqkXQ\\1dN",[])),
- <<"qIIJaaaafyqkXQdN">> = iolist_to_binary(re:replace("aaaa","a*b?\\w","qIIJ&fyqkXQ\\1dN",[global])),
- <<"aqAJFQ">> = iolist_to_binary(re:replace("a","a*b?\\w","&qAJFQ",[])),
- <<"aqAJFQ">> = iolist_to_binary(re:replace("a","a*b?\\w","&qAJFQ",[global])),
- <<"qVNjOTqaaabbbbQfis">> = iolist_to_binary(re:replace("aaabbbb","a*b{0,4}\\w","qV\\1NjOTq\\1&Qf\\1is\\1",[])),
- <<"qVNjOTqaaabbbbQfis">> = iolist_to_binary(re:replace("aaabbbb","a*b{0,4}\\w","qV\\1NjOTq\\1&Qf\\1is\\1",[global])),
- <<"caaaaIqaaaa">> = iolist_to_binary(re:replace("aaaa","a*b{0,4}\\w","c&I\\1q&",[])),
- <<"caaaaIqaaaa">> = iolist_to_binary(re:replace("aaaa","a*b{0,4}\\w","c&I\\1q&",[global])),
- <<"MJLlapba">> = iolist_to_binary(re:replace("a","a*b{0,4}\\w","MJLl&\\1pb&",[])),
- <<"MJLlapba">> = iolist_to_binary(re:replace("a","a*b{0,4}\\w","MJLl&\\1pb&",[global])),
- <<"Uxbbm">> = iolist_to_binary(re:replace("aaabbbb","a*b{0,}\\w","Uxbbm\\1",[])),
- <<"Uxbbm">> = iolist_to_binary(re:replace("aaabbbb","a*b{0,}\\w","Uxbbm\\1",[global])),
- <<"fHXfIxomDIMBKtdig">> = iolist_to_binary(re:replace("aaaa","a*b{0,}\\w","f\\1HXfIxomD\\1\\1IMBKtdig",[])),
- <<"fHXfIxomDIMBKtdig">> = iolist_to_binary(re:replace("aaaa","a*b{0,}\\w","f\\1HXfIxomD\\1\\1IMBKtdig",[global])),
- <<"hdaYrYD">> = iolist_to_binary(re:replace("a","a*b{0,}\\w","\\1hd&YrYD\\1",[])),
- <<"hdaYrYD">> = iolist_to_binary(re:replace("a","a*b{0,}\\w","\\1hd&YrYD\\1",[global])),
- <<"xIjjbHXKSKRKUhwCer">> = iolist_to_binary(re:replace("0a","a*\\d*\\w","xIjjbHXKSKRKUhwCer",[])),
- <<"xIjjbHXKSKRKUhwCer">> = iolist_to_binary(re:replace("0a","a*\\d*\\w","xIjjbHXKSKRKUhwCer",[global])),
- <<"aklRHKO">> = iolist_to_binary(re:replace("a","a*\\d*\\w","&klRHK\\1O",[])),
- <<"aklRHKO">> = iolist_to_binary(re:replace("a","a*\\d*\\w","&klRHK\\1O",[global])),
- <<"aaaTxVbkRpu">> = iolist_to_binary(re:replace("a","a*b *\\w","&&&TxVbk\\1Rpu",[extended])),
- <<"aaaTxVbkRpu">> = iolist_to_binary(re:replace("a","a*b *\\w","&&&TxVbk\\1Rpu",[extended,
- global])),
- <<"ekWkPj">> = iolist_to_binary(re:replace("a","a*b#comment
- *\\w","ekWkPj",[extended])),
- <<"ekWkPj">> = iolist_to_binary(re:replace("a","a*b#comment
- *\\w","ekWkPj",[extended,global])),
- <<"XxA">> = iolist_to_binary(re:replace("a","a* b *\\w","XxA",[extended])),
- <<"XxA">> = iolist_to_binary(re:replace("a","a* b *\\w","XxA",[extended,
- global])),
- <<"FL
+ <<"bKrRGsoSckoSG">> = iolist_to_binary(re:replace("aaabbbb","a*b*\\w","bKrRGsoSckoSG",[])),
+ <<"bKrRGsoSckoSG">> = iolist_to_binary(re:replace("aaabbbb","a*b*\\w","bKrRGsoSckoSG",[global])),
+ <<"xc">> = iolist_to_binary(re:replace("aaaa","a*b*\\w","\\1xc",[])),
+ <<"xc">> = iolist_to_binary(re:replace("aaaa","a*b*\\w","\\1xc",[global])),
+ <<"DiagFR">> = iolist_to_binary(re:replace("a","a*b*\\w","Di&\\1gFR",[])),
+ <<"DiagFR">> = iolist_to_binary(re:replace("a","a*b*\\w","Di&\\1gFR",[global])),
+ <<"xSaaabbESTgXbkTtoCbb">> = iolist_to_binary(re:replace("aaabbbb","a*b?\\w","\\1xS&E\\1STgXb\\1kTtoC",[])),
+ <<"xSaaabbESTgXbkTtoCxSbbESTgXbkTtoC">> = iolist_to_binary(re:replace("aaabbbb","a*b?\\w","\\1xS&E\\1STgXb\\1kTtoC",[global])),
+ <<"NFFaaaaAMaaaakpmD">> = iolist_to_binary(re:replace("aaaa","a*b?\\w","NFF&AM&kp\\1mD",[])),
+ <<"NFFaaaaAMaaaakpmD">> = iolist_to_binary(re:replace("aaaa","a*b?\\w","NFF&AM&kp\\1mD",[global])),
+ <<"KCaDnJouY">> = iolist_to_binary(re:replace("a","a*b?\\w","\\1KC&DnJouY",[])),
+ <<"KCaDnJouY">> = iolist_to_binary(re:replace("a","a*b?\\w","\\1KC&DnJouY",[global])),
+ <<"ItNl">> = iolist_to_binary(re:replace("aaabbbb","a*b{0,4}\\w","ItNl",[])),
+ <<"ItNl">> = iolist_to_binary(re:replace("aaabbbb","a*b{0,4}\\w","ItNl",[global])),
+ <<"SpCeqD">> = iolist_to_binary(re:replace("aaaa","a*b{0,4}\\w","SpCeqD",[])),
+ <<"SpCeqD">> = iolist_to_binary(re:replace("aaaa","a*b{0,4}\\w","SpCeqD",[global])),
+ <<"VwueYyNFc">> = iolist_to_binary(re:replace("a","a*b{0,4}\\w","Vwu\\1eYyN\\1Fc",[])),
+ <<"VwueYyNFc">> = iolist_to_binary(re:replace("a","a*b{0,4}\\w","Vwu\\1eYyN\\1Fc",[global])),
+ <<"KjgaaabbbbAaaabbbbJXahPyE">> = iolist_to_binary(re:replace("aaabbbb","a*b{0,}\\w","Kjg&A&JXahP\\1yE",[])),
+ <<"KjgaaabbbbAaaabbbbJXahPyE">> = iolist_to_binary(re:replace("aaabbbb","a*b{0,}\\w","Kjg&A&JXahP\\1yE",[global])),
+ <<"ngvFLRPw">> = iolist_to_binary(re:replace("aaaa","a*b{0,}\\w","ngvFLRPw",[])),
+ <<"ngvFLRPw">> = iolist_to_binary(re:replace("aaaa","a*b{0,}\\w","ngvFLRPw",[global])),
+ <<"DnucmfFKuYp">> = iolist_to_binary(re:replace("a","a*b{0,}\\w","Dn\\1ucm\\1\\1fFKuYp",[])),
+ <<"DnucmfFKuYp">> = iolist_to_binary(re:replace("a","a*b{0,}\\w","Dn\\1ucm\\1\\1fFKuYp",[global])),
+ <<"0aY">> = iolist_to_binary(re:replace("0a","a*\\d*\\w","&Y",[])),
+ <<"0aY">> = iolist_to_binary(re:replace("0a","a*\\d*\\w","&Y",[global])),
+ <<"xanCBUCkGaPAtML">> = iolist_to_binary(re:replace("a","a*\\d*\\w","x&nCBUCkG&PAt\\1ML",[])),
+ <<"xanCBUCkGaPAtML">> = iolist_to_binary(re:replace("a","a*\\d*\\w","x&nCBUCkG&PAt\\1ML",[global])),
+ <<"ii">> = iolist_to_binary(re:replace("a","a*b *\\w","ii",[extended])),
+ <<"ii">> = iolist_to_binary(re:replace("a","a*b *\\w","ii",[extended,
+ global])),
+ <<"VaGxIwMeaq">> = iolist_to_binary(re:replace("a","a*b#comment
+ *\\w","V&GxIwMeaq",[extended])),
+ <<"VaGxIwMeaq">> = iolist_to_binary(re:replace("a","a*b#comment
+ *\\w","V&GxIwMeaq",[extended,global])),
+ <<"AaapTXaPHaekH">> = iolist_to_binary(re:replace("a","a* b *\\w","Aa&pTX&PHaekH",[extended])),
+ <<"AaapTXaPHaekH">> = iolist_to_binary(re:replace("a","a* b *\\w","Aa&pTX&PHaekH",[extended,
+ global])),
+ <<"abc=xyz\\vmPNciE
pqr">> = iolist_to_binary(re:replace("abc=xyz\\
-pqr","^\\w+=.*(\\\\\\n.*)*","FL",[])),
- <<"FL
+pqr","^\\w+=.*(\\\\\\n.*)*","&vmPNciE",[])),
+ <<"abc=xyz\\vmPNciE
pqr">> = iolist_to_binary(re:replace("abc=xyz\\
-pqr","^\\w+=.*(\\\\\\n.*)*","FL",[global])),
- <<"KDabcd:abcdSabcd:">> = iolist_to_binary(re:replace("abcd:","(?=(\\w+))\\1:","KD&\\1S&",[])),
- <<"KDabcd:abcdSabcd:">> = iolist_to_binary(re:replace("abcd:","(?=(\\w+))\\1:","KD&\\1S&",[global])),
- <<"CFNabcd:xwKNSfsabcd">> = iolist_to_binary(re:replace("abcd:","^(?=(\\w+))\\1:","CFN&xwKNSfs\\1",[])),
- <<"CFNabcd:xwKNSfsabcd">> = iolist_to_binary(re:replace("abcd:","^(?=(\\w+))\\1:","CFN&xwKNSfs\\1",[global])),
- <<"UabcWq">> = iolist_to_binary(re:replace("abc","^\\Eabc","U&Wq",[])),
- <<"UabcWq">> = iolist_to_binary(re:replace("abc","^\\Eabc","U&Wq",[global])),
- <<"yamyDjNjvdapUq">> = iolist_to_binary(re:replace("a","^[\\Eabc]","y&myDjNjvd&pUq\\1",[])),
- <<"yamyDjNjvdapUq">> = iolist_to_binary(re:replace("a","^[\\Eabc]","y&myDjNjvd&pUq\\1",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\Eabc]","YWGNdA&XaWp\\1",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\Eabc]","YWGNdA&XaWp\\1",[global])),
- <<"E">> = iolist_to_binary(re:replace("E","^[\\Eabc]","qtud&GONs\\1W\\1I",[])),
- <<"E">> = iolist_to_binary(re:replace("E","^[\\Eabc]","qtud&GONs\\1W\\1I",[global])),
- <<"kj">> = iolist_to_binary(re:replace("b","^[a-\\Ec]","kj",[])),
- <<"kj">> = iolist_to_binary(re:replace("b","^[a-\\Ec]","kj",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[a-\\Ec]","U\\1",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[a-\\Ec]","U\\1",[global])),
- <<"-">> = iolist_to_binary(re:replace("-","^[a-\\Ec]","dluKDBOTsxDtQKaGXQn",[])),
- <<"-">> = iolist_to_binary(re:replace("-","^[a-\\Ec]","dluKDBOTsxDtQKaGXQn",[global])),
- <<"E">> = iolist_to_binary(re:replace("E","^[a-\\Ec]","j\\1KKHVDRF&\\1hBX\\1nerh",[])),
- <<"E">> = iolist_to_binary(re:replace("E","^[a-\\Ec]","j\\1KKHVDRF&\\1hBX\\1nerh",[global])),
- <<"eU">> = iolist_to_binary(re:replace("b","^[a\\E\\E-\\Ec]","\\1eU",[])),
- <<"eU">> = iolist_to_binary(re:replace("b","^[a\\E\\E-\\Ec]","\\1eU",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[a\\E\\E-\\Ec]","Gp\\1hoe\\1ft",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[a\\E\\E-\\Ec]","Gp\\1hoe\\1ft",[global])),
- <<"-">> = iolist_to_binary(re:replace("-","^[a\\E\\E-\\Ec]","&\\1&\\1dsAR\\1R&kfYLY&Nx",[])),
- <<"-">> = iolist_to_binary(re:replace("-","^[a\\E\\E-\\Ec]","&\\1&\\1dsAR\\1R&kfYLY&Nx",[global])),
- <<"E">> = iolist_to_binary(re:replace("E","^[a\\E\\E-\\Ec]","OmwiowAjJ&dB",[])),
- <<"E">> = iolist_to_binary(re:replace("E","^[a\\E\\E-\\Ec]","OmwiowAjJ&dB",[global])),
- <<"bLBVEBlTbNy">> = iolist_to_binary(re:replace("b","^[\\E\\Qa\\E-\\Qz\\E]+","&LBVEBlT&Ny",[])),
- <<"bLBVEBlTbNy">> = iolist_to_binary(re:replace("b","^[\\E\\Qa\\E-\\Qz\\E]+","&LBVEBlT&Ny",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\E\\Qa\\E-\\Qz\\E]+","&DGXW&\\1G",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\E\\Qa\\E-\\Qz\\E]+","&DGXW&\\1G",[global])),
- <<"-">> = iolist_to_binary(re:replace("-","^[\\E\\Qa\\E-\\Qz\\E]+","uh&tV&",[])),
- <<"-">> = iolist_to_binary(re:replace("-","^[\\E\\Qa\\E-\\Qz\\E]+","uh&tV&",[global])),
- <<"IgYyaXYfkYHvCal">> = iolist_to_binary(re:replace("a","^[a\\Q]bc\\E]","IgYy&XYf\\1kYH\\1vC&\\1l",[])),
- <<"IgYyaXYfkYHvCal">> = iolist_to_binary(re:replace("a","^[a\\Q]bc\\E]","IgYy&XYf\\1kYH\\1vC&\\1l",[global])),
- <<"DGTyeUFsoeifQI">> = iolist_to_binary(re:replace("]","^[a\\Q]bc\\E]","DGTyeUFsoeifQI",[])),
- <<"DGTyeUFsoeifQI">> = iolist_to_binary(re:replace("]","^[a\\Q]bc\\E]","DGTyeUFsoeifQI",[global])),
- <<"cdPJxbdO">> = iolist_to_binary(re:replace("c","^[a\\Q]bc\\E]","&dPJxb\\1dO",[])),
- <<"cdPJxbdO">> = iolist_to_binary(re:replace("c","^[a\\Q]bc\\E]","&dPJxb\\1dO",[global])),
- <<"achHbHOkynhnR">> = iolist_to_binary(re:replace("a","^[a-\\Q\\E]","&chHbHOkynhnR",[])),
- <<"achHbHOkynhnR">> = iolist_to_binary(re:replace("a","^[a-\\Q\\E]","&chHbHOkynhnR",[global])),
- <<"uu-MgaUIMliYd--">> = iolist_to_binary(re:replace("-","^[a-\\Q\\E]","uu\\1&MgaU\\1IMliYd&&",[])),
- <<"uu-MgaUIMliYd--">> = iolist_to_binary(re:replace("-","^[a-\\Q\\E]","uu\\1&MgaU\\1IMliYd&&",[global])),
- <<"CP">> = iolist_to_binary(re:replace("aaaa","^(a()*)*","CP",[])),
- <<"CP">> = iolist_to_binary(re:replace("aaaa","^(a()*)*","CP",[global])),
- <<"wQTHtaaaakYek">> = iolist_to_binary(re:replace("aaaa","^(?:a(?:(?:))*)*","w\\1QTH\\1\\1t&kYe\\1k",[])),
- <<"wQTHtaaaakYek">> = iolist_to_binary(re:replace("aaaa","^(?:a(?:(?:))*)*","w\\1QTH\\1\\1t&kYe\\1k",[global])),
+pqr","^\\w+=.*(\\\\\\n.*)*","&vmPNciE",[global])),
+ <<"oabcd:pabcd:qOabcdGfIeV">> = iolist_to_binary(re:replace("abcd:","(?=(\\w+))\\1:","o&p&qO\\1GfIeV",[])),
+ <<"oabcd:pabcd:qOabcdGfIeV">> = iolist_to_binary(re:replace("abcd:","(?=(\\w+))\\1:","o&p&qO\\1GfIeV",[global])),
+ <<"LTrSmxIPabcdOKMqwVAA">> = iolist_to_binary(re:replace("abcd:","^(?=(\\w+))\\1:","LTrSmxIP\\1OKMqwVAA",[])),
+ <<"LTrSmxIPabcdOKMqwVAA">> = iolist_to_binary(re:replace("abcd:","^(?=(\\w+))\\1:","LTrSmxIP\\1OKMqwVAA",[global])),
+ <<"aKjwwmYIpW">> = iolist_to_binary(re:replace("abc","^\\Eabc","aKj\\1w\\1wmY\\1Ip\\1W",[])),
+ <<"aKjwwmYIpW">> = iolist_to_binary(re:replace("abc","^\\Eabc","aKj\\1w\\1wmY\\1Ip\\1W",[global])),
+ <<"l">> = iolist_to_binary(re:replace("a","^[\\Eabc]","l",[])),
+ <<"l">> = iolist_to_binary(re:replace("a","^[\\Eabc]","l",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\Eabc]","bQ&mb\\1I&",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\Eabc]","bQ&mb\\1I&",[global])),
+ <<"E">> = iolist_to_binary(re:replace("E","^[\\Eabc]","&qof&K&",[])),
+ <<"E">> = iolist_to_binary(re:replace("E","^[\\Eabc]","&qof&K&",[global])),
+ <<"LbOibbFEALmTbt">> = iolist_to_binary(re:replace("b","^[a-\\Ec]","Lb\\1Oi&\\1\\1&FEA\\1Lm\\1T&t",[])),
+ <<"LbOibbFEALmTbt">> = iolist_to_binary(re:replace("b","^[a-\\Ec]","Lb\\1Oi&\\1\\1&FEA\\1Lm\\1T&t",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[a-\\Ec]","PtF&e\\1KFwR&E",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[a-\\Ec]","PtF&e\\1KFwR&E",[global])),
+ <<"-">> = iolist_to_binary(re:replace("-","^[a-\\Ec]","N&Vuwq\\1D&\\1PXO&qg&Y",[])),
+ <<"-">> = iolist_to_binary(re:replace("-","^[a-\\Ec]","N&Vuwq\\1D&\\1PXO&qg&Y",[global])),
+ <<"E">> = iolist_to_binary(re:replace("E","^[a-\\Ec]","gfw",[])),
+ <<"E">> = iolist_to_binary(re:replace("E","^[a-\\Ec]","gfw",[global])),
+ <<"m">> = iolist_to_binary(re:replace("b","^[a\\E\\E-\\Ec]","m",[])),
+ <<"m">> = iolist_to_binary(re:replace("b","^[a\\E\\E-\\Ec]","m",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[a\\E\\E-\\Ec]","pr\\1hSV&a\\1Tq\\1uk\\1lGQn",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[a\\E\\E-\\Ec]","pr\\1hSV&a\\1Tq\\1uk\\1lGQn",[global])),
+ <<"-">> = iolist_to_binary(re:replace("-","^[a\\E\\E-\\Ec]","PLu\\1jRBxH&j",[])),
+ <<"-">> = iolist_to_binary(re:replace("-","^[a\\E\\E-\\Ec]","PLu\\1jRBxH&j",[global])),
+ <<"E">> = iolist_to_binary(re:replace("E","^[a\\E\\E-\\Ec]","\\1RonyFdbw&\\1UT",[])),
+ <<"E">> = iolist_to_binary(re:replace("E","^[a\\E\\E-\\Ec]","\\1RonyFdbw&\\1UT",[global])),
+ <<"LtmFeEubbhDoqNG">> = iolist_to_binary(re:replace("b","^[\\E\\Qa\\E-\\Qz\\E]+","L\\1tmF\\1eEu&&hDoqNG",[])),
+ <<"LtmFeEubbhDoqNG">> = iolist_to_binary(re:replace("b","^[\\E\\Qa\\E-\\Qz\\E]+","L\\1tmF\\1eEu&&hDoqNG",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\E\\Qa\\E-\\Qz\\E]+","ks\\1",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\E\\Qa\\E-\\Qz\\E]+","ks\\1",[global])),
+ <<"-">> = iolist_to_binary(re:replace("-","^[\\E\\Qa\\E-\\Qz\\E]+","DNi",[])),
+ <<"-">> = iolist_to_binary(re:replace("-","^[\\E\\Qa\\E-\\Qz\\E]+","DNi",[global])),
+ <<"UoqHQfFfbONSGdk">> = iolist_to_binary(re:replace("a","^[a\\Q]bc\\E]","\\1UoqHQfFf\\1bONSGd\\1k",[])),
+ <<"UoqHQfFfbONSGdk">> = iolist_to_binary(re:replace("a","^[a\\Q]bc\\E]","\\1UoqHQfFf\\1bONSGd\\1k",[global])),
+ <<"eMWv]QMxjJL]v">> = iolist_to_binary(re:replace("]","^[a\\Q]bc\\E]","eMWv&QMxjJL&v",[])),
+ <<"eMWv]QMxjJL]v">> = iolist_to_binary(re:replace("]","^[a\\Q]bc\\E]","eMWv&QMxjJL&v",[global])),
+ <<"sDtJKXcbIVQesK">> = iolist_to_binary(re:replace("c","^[a\\Q]bc\\E]","sD\\1tJKX&bI\\1V\\1QesK",[])),
+ <<"sDtJKXcbIVQesK">> = iolist_to_binary(re:replace("c","^[a\\Q]bc\\E]","sD\\1tJKX&bI\\1V\\1QesK",[global])),
+ <<"phuiWK">> = iolist_to_binary(re:replace("a","^[a-\\Q\\E]","phuiWK",[])),
+ <<"phuiWK">> = iolist_to_binary(re:replace("a","^[a-\\Q\\E]","phuiWK",[global])),
+ <<"e-EpaKAPD-M-">> = iolist_to_binary(re:replace("-","^[a-\\Q\\E]","e&Epa\\1KAPD\\1&M&",[])),
+ <<"e-EpaKAPD-M-">> = iolist_to_binary(re:replace("-","^[a-\\Q\\E]","e&Epa\\1KAPD\\1&M&",[global])),
+ <<"VKXawWoyOhQtKatma">> = iolist_to_binary(re:replace("aaaa","^(a()*)*","VKX\\1wWoyOhQtK\\1tm\\1",[])),
+ <<"VKXawWoyOhQtKatma">> = iolist_to_binary(re:replace("aaaa","^(a()*)*","VKX\\1wWoyOhQtK\\1tm\\1",[global])),
+ <<"tPRweiQ">> = iolist_to_binary(re:replace("aaaa","^(?:a(?:(?:))*)*","tPRweiQ",[])),
+ <<"tPRweiQ">> = iolist_to_binary(re:replace("aaaa","^(?:a(?:(?:))*)*","tPRweiQ",[global])),
ok.
run36() ->
- <<"RGaXfvItI">> = iolist_to_binary(re:replace("aaaa","^(a()+)+","RG\\1XfvItI",[])),
- <<"RGaXfvItI">> = iolist_to_binary(re:replace("aaaa","^(a()+)+","RG\\1XfvItI",[global])),
- <<"dMSiHuvxupxlcaaaax">> = iolist_to_binary(re:replace("aaaa","^(?:a(?:(?:))+)+","dMSiHuvxupxl\\1c&x",[])),
- <<"dMSiHuvxupxlcaaaax">> = iolist_to_binary(re:replace("aaaa","^(?:a(?:(?:))+)+","dMSiHuvxupxl\\1c&x",[global])),
- <<"iP">> = iolist_to_binary(re:replace("abbD","(a){0,3}(?(1)b|(c|))*D","iP",[])),
- <<"iP">> = iolist_to_binary(re:replace("abbD","(a){0,3}(?(1)b|(c|))*D","iP",[global])),
- <<"ccccDXbTvQpvdoaW">> = iolist_to_binary(re:replace("ccccD","(a){0,3}(?(1)b|(c|))*D","&XbTvQ\\1p\\1vd\\1o\\1\\1\\1aW",[])),
- <<"ccccDXbTvQpvdoaW">> = iolist_to_binary(re:replace("ccccD","(a){0,3}(?(1)b|(c|))*D","&XbTvQ\\1p\\1vd\\1o\\1\\1\\1aW",[global])),
- <<"RVoDDTkMDjhW">> = iolist_to_binary(re:replace("D","(a){0,3}(?(1)b|(c|))*D","RVo&&TkM&jhW",[])),
- <<"RVoDDTkMDjhW">> = iolist_to_binary(re:replace("D","(a){0,3}(?(1)b|(c|))*D","RVo&&TkM&jhW",[global])),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a|)*\\d","&\\1DGFkfxXGJ\\1yJ",[])),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a|)*\\d","&\\1DGFkfxXGJ\\1yJ",[global])),
- <<"Kaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4GiaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4jWNATt">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(a|)*\\d","K&GiaQ&jWNATt",[])),
- <<"Kaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4GiaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4jWNATt">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(a|)*\\d","K&GiaQ&jWNATt",[global])),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?>a|)*\\d","qHVMyR\\1g\\1",[])),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?>a|)*\\d","qHVMyR\\1g\\1",[global])),
- <<"kGFBeTsPIf">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?>a|)*\\d","kGFBeTsPI\\1f",[])),
- <<"kGFBeTsPIf">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?>a|)*\\d","kGFBeTsPI\\1f",[global])),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?:a|)*\\d","Yx",[])),
- <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?:a|)*\\d","Yx",[global])),
- <<"wkl">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?:a|)*\\d","wkl",[])),
- <<"wkl">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?:a|)*\\d","wkl",[global])),
- <<"abcqXmkEhjC">> = iolist_to_binary(re:replace("abc","\\Z","qXmkEhjC",[])),
- <<"abcqXmkEhjC">> = iolist_to_binary(re:replace("abc","\\Z","qXmkEhjC",[global])),
- <<"RdSYAact">> = iolist_to_binary(re:replace("abc","^(?s)(?>.*)(?<!\\n)","RdSYAact",[])),
- <<"RdSYAact">> = iolist_to_binary(re:replace("abc","^(?s)(?>.*)(?<!\\n)","RdSYAact",[global])),
- <<"JvTabcqFTcnkmyFJ">> = iolist_to_binary(re:replace("abc","^(?s)(?>.*)(?<!\\n)","\\1JvT&qFTcnk\\1my\\1FJ",[])),
- <<"JvTabcqFTcnkmyFJ">> = iolist_to_binary(re:replace("abc","^(?s)(?>.*)(?<!\\n)","\\1JvT&qFTcnk\\1my\\1FJ",[global])),
- <<"cqXXOeFFGVUWkMabc">> = iolist_to_binary(re:replace("abc","^(?![^\\n]*\\n\\z)","cqXXOeFF\\1GVUW\\1kM",[])),
- <<"cqXXOeFFGVUWkMabc">> = iolist_to_binary(re:replace("abc","^(?![^\\n]*\\n\\z)","cqXXOeFF\\1GVUW\\1kM",[global])),
- <<"JbxrWfegLobSfGKabc">> = iolist_to_binary(re:replace("abc","^(?![^\\n]*\\n\\z)","\\1Jbx&rWfe&gLobSfGK",[])),
- <<"JbxrWfegLobSfGKabc">> = iolist_to_binary(re:replace("abc","^(?![^\\n]*\\n\\z)","\\1Jbx&rWfe&gLobSfGK",[global])),
- <<"abceDUDjJoFtrgMYDo">> = iolist_to_binary(re:replace("abc","\\z(?<!\\n)","eDUDjJoFtrgMYD&o",[])),
- <<"abceDUDjJoFtrgMYDo">> = iolist_to_binary(re:replace("abc","\\z(?<!\\n)","eDUDjJoFtrgMYD&o",[global])),
- <<"abcL">> = iolist_to_binary(re:replace("abc","\\z(?<!\\n)","L",[])),
- <<"abcL">> = iolist_to_binary(re:replace("abc","\\z(?<!\\n)","L",[global])),
- <<"abcdddXku">> = iolist_to_binary(re:replace("abcd","(.*(.)?)*","&dd\\1\\1Xku",[])),
- <<"abcdddXkuddXku">> = iolist_to_binary(re:replace("abcd","(.*(.)?)*","&dd\\1\\1Xku",[global])),
- <<"pkdLVDscUDDEBUBabcd">> = iolist_to_binary(re:replace("abcd","( (A | (?(1)0|) )* )","pkd&L&VD&scUDDEBUB",[extended])),
- <<"pkdLVDscUDDEBUBapkdLVDscUDDEBUBbpkdLVDscUDDEBUBcpkdLVDscUDDEBUBdpkdLVDscUDDEBUB">> = iolist_to_binary(re:replace("abcd","( (A | (?(1)0|) )* )","pkd&L&VD&scUDDEBUB",[extended,
- global])),
- <<"AuDgWsdmnqYhabcd">> = iolist_to_binary(re:replace("abcd","( ( (?(1)0|) )* )","AuDgW&s&dm&nqYh",[extended])),
- <<"AuDgWsdmnqYhaAuDgWsdmnqYhbAuDgWsdmnqYhcAuDgWsdmnqYhdAuDgWsdmnqYh">> = iolist_to_binary(re:replace("abcd","( ( (?(1)0|) )* )","AuDgW&s&dm&nqYh",[extended,
- global])),
- <<"efinTcnmBlVFabcd">> = iolist_to_binary(re:replace("abcd","( (?(1)0|)* )","efinTc&nmB&\\1lV\\1F",[extended])),
- <<"efinTcnmBlVFaefinTcnmBlVFbefinTcnmBlVFcefinTcnmBlVFdefinTcnmBlVF">> = iolist_to_binary(re:replace("abcd","( (?(1)0|)* )","efinTc&nmB&\\1lV\\1F",[extended,
- global])),
- <<"EDiUXiAlYBAmCeNc">> = iolist_to_binary(re:replace("a]","[[:abcd:xyz]]","EDiUXiAlYBA\\1mCeNc",[])),
- <<"EDiUXiAlYBAmCeNc">> = iolist_to_binary(re:replace("a]","[[:abcd:xyz]]","EDiUXiAlYBA\\1mCeNc",[global])),
- <<"k:]h">> = iolist_to_binary(re:replace(":]","[[:abcd:xyz]]","k&h",[])),
- <<"k:]h">> = iolist_to_binary(re:replace(":]","[[:abcd:xyz]]","k&h",[global])),
- <<"hwNfUgfOoCtFayhAXX">> = iolist_to_binary(re:replace("a","[abc[:x\\]pqr]","hwNfUgfOo\\1CtF&yhA\\1XX",[])),
- <<"hwNfUgfOoCtFayhAXX">> = iolist_to_binary(re:replace("a","[abc[:x\\]pqr]","hwNfUgfOo\\1CtF&yhA\\1XX",[global])),
- <<"">> = iolist_to_binary(re:replace("[","[abc[:x\\]pqr]","\\1\\1",[])),
- <<"">> = iolist_to_binary(re:replace("[","[abc[:x\\]pqr]","\\1\\1",[global])),
- <<"fWMiJLaBnsaYQ">> = iolist_to_binary(re:replace(":","[abc[:x\\]pqr]","fWMiJLaBns\\1aYQ",[])),
- <<"fWMiJLaBnsaYQ">> = iolist_to_binary(re:replace(":","[abc[:x\\]pqr]","fWMiJLaBns\\1aYQ",[global])),
- <<"IlPjDF">> = iolist_to_binary(re:replace("]","[abc[:x\\]pqr]","IlPjDF\\1",[])),
- <<"IlPjDF">> = iolist_to_binary(re:replace("]","[abc[:x\\]pqr]","IlPjDF\\1",[global])),
- <<"jXFpSOncoxfPi">> = iolist_to_binary(re:replace("p","[abc[:x\\]pqr]","\\1jX\\1F&SOncoxf\\1Pi",[])),
- <<"jXFpSOncoxfPi">> = iolist_to_binary(re:replace("p","[abc[:x\\]pqr]","\\1jX\\1F&SOncoxf\\1Pi",[global])),
- <<"fooabcfoo">> = iolist_to_binary(re:replace("fooabcfoo",".*[op][xyz]","rU&wHuSyHLW\\1WUJxg\\1",[])),
- <<"fooabcfoo">> = iolist_to_binary(re:replace("fooabcfoo",".*[op][xyz]","rU&wHuSyHLW\\1WUJxg\\1",[global])),
- <<"Yadc">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)","\\1\\1Y",[])),
- <<"Yadc">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)","\\1\\1Y",[global])),
- <<"asQWunbuTsJvhIUbTxKxbc">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)","sQWun&uTsJvhIU&TxKx&",[])),
- <<"asQWunbuTsJvhIUbTxKxbc">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)","sQWun&uTsJvhIU&TxKx&",[global])),
- <<"WsShpCMbadc">> = iolist_to_binary(re:replace("adc","(?(?=^.*b)b|^)","WsShp\\1\\1C\\1Mb",[])),
- <<"WsShpCMbadc">> = iolist_to_binary(re:replace("adc","(?(?=^.*b)b|^)","WsShp\\1\\1C\\1Mb",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(?(?=^.*b)b|^)","PkFnM\\1TJjij\\1s",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(?(?=^.*b)b|^)","PkFnM\\1TJjij\\1s",[global])),
- <<"QgracuqfskDadc">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)*","Qg\\1r\\1\\1acuqfskD\\1&",[])),
- <<"QgracuqfskDaQgracuqfskDdQgracuqfskDcQgracuqfskD">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)*","Qg\\1r\\1\\1acuqfskD\\1&",[global])),
- <<"NOaxcgWJQdJabc">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)*","NOaxc\\1\\1gWJQdJ&",[])),
- <<"NOaxcgWJQdJaNOaxcgWJQdJbNOaxcgWJQdJcNOaxcgWJQdJ">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)*","NOaxc\\1\\1gWJQdJ&",[global])),
+ <<"n">> = iolist_to_binary(re:replace("aaaa","^(a()+)+","n",[])),
+ <<"n">> = iolist_to_binary(re:replace("aaaa","^(a()+)+","n",[global])),
+ <<"bI">> = iolist_to_binary(re:replace("aaaa","^(?:a(?:(?:))+)+","bI",[])),
+ <<"bI">> = iolist_to_binary(re:replace("aaaa","^(?:a(?:(?:))+)+","bI",[global])),
+ <<"GabbDDae">> = iolist_to_binary(re:replace("abbD","(a){0,3}(?(1)b|(c|))*D","G&D\\1e",[])),
+ <<"GabbDDae">> = iolist_to_binary(re:replace("abbD","(a){0,3}(?(1)b|(c|))*D","G&D\\1e",[global])),
+ <<"OV">> = iolist_to_binary(re:replace("ccccD","(a){0,3}(?(1)b|(c|))*D","OV",[])),
+ <<"OV">> = iolist_to_binary(re:replace("ccccD","(a){0,3}(?(1)b|(c|))*D","OV",[global])),
+ <<"XhjfKDReHaDNMSf">> = iolist_to_binary(re:replace("D","(a){0,3}(?(1)b|(c|))*D","Xhjf\\1K&ReHa&NM\\1Sf",[])),
+ <<"XhjfKDReHaDNMSf">> = iolist_to_binary(re:replace("D","(a){0,3}(?(1)b|(c|))*D","Xhjf\\1K&ReHa&NM\\1Sf",[global])),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a|)*\\d","SbOGt&K",[])),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a|)*\\d","SbOGt&K",[global])),
+ <<"xJrtco">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(a|)*\\d","\\1x\\1Jrtco",[])),
+ <<"xJrtco">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(a|)*\\d","\\1x\\1Jrtco",[global])),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?>a|)*\\d","Y\\1\\1Fq&&Lb&&T&\\1&\\1\\1T",[])),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?>a|)*\\d","Y\\1\\1Fq&&Lb&&T&\\1&\\1\\1T",[global])),
+ <<"ucWrNuavax">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?>a|)*\\d","ucWrNuavax",[])),
+ <<"ucWrNuavax">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?>a|)*\\d","ucWrNuavax",[global])),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?:a|)*\\d","i\\1cf\\1CEE&\\1itOwcw&BF",[])),
+ <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(?:a|)*\\d","i\\1cf\\1CEE&\\1itOwcw&BF",[global])),
+ <<"WvhbrstiFWO">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?:a|)*\\d","Wv\\1hbrstiFWO",[])),
+ <<"WvhbrstiFWO">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4","(?:a|)*\\d","Wv\\1hbrstiFWO",[global])),
+ <<"abcUhNS">> = iolist_to_binary(re:replace("abc","\\Z","UhNS&\\1\\1",[])),
+ <<"abcUhNS">> = iolist_to_binary(re:replace("abc","\\Z","UhNS&\\1\\1",[global])),
+ <<"FEgUNUkGWxyqopsabc">> = iolist_to_binary(re:replace("abc","^(?s)(?>.*)(?<!\\n)","\\1FEgUNUkGWxyqops&\\1",[])),
+ <<"FEgUNUkGWxyqopsabc">> = iolist_to_binary(re:replace("abc","^(?s)(?>.*)(?<!\\n)","\\1FEgUNUkGWxyqops&\\1",[global])),
+ <<"O">> = iolist_to_binary(re:replace("abc","^(?s)(?>.*)(?<!\\n)","O\\1",[])),
+ <<"O">> = iolist_to_binary(re:replace("abc","^(?s)(?>.*)(?<!\\n)","O\\1",[global])),
+ <<"xSVoQWsKeMpGQabc">> = iolist_to_binary(re:replace("abc","^(?![^\\n]*\\n\\z)","xSV&oQWsKe&MpG&Q",[])),
+ <<"xSVoQWsKeMpGQabc">> = iolist_to_binary(re:replace("abc","^(?![^\\n]*\\n\\z)","xSV&oQWsKe&MpG&Q",[global])),
+ <<"hAqynOabc">> = iolist_to_binary(re:replace("abc","^(?![^\\n]*\\n\\z)","hA&qy\\1nO",[])),
+ <<"hAqynOabc">> = iolist_to_binary(re:replace("abc","^(?![^\\n]*\\n\\z)","hA&qy\\1nO",[global])),
+ <<"abcbboJlolQwgwa">> = iolist_to_binary(re:replace("abc","\\z(?<!\\n)","bbo\\1JlolQ\\1\\1wgwa",[])),
+ <<"abcbboJlolQwgwa">> = iolist_to_binary(re:replace("abc","\\z(?<!\\n)","bbo\\1JlolQ\\1\\1wgwa",[global])),
+ <<"abcSrDg">> = iolist_to_binary(re:replace("abc","\\z(?<!\\n)","SrDg&",[])),
+ <<"abcSrDg">> = iolist_to_binary(re:replace("abc","\\z(?<!\\n)","SrDg&",[global])),
+ <<"aabcdiFPR">> = iolist_to_binary(re:replace("abcd","(.*(.)?)*","\\1a&iFPR\\1",[])),
+ <<"aabcdiFPRaiFPR">> = iolist_to_binary(re:replace("abcd","(.*(.)?)*","\\1a&iFPR\\1",[global])),
+ <<"uQWHjmFmJgqpvabcd">> = iolist_to_binary(re:replace("abcd","( (A | (?(1)0|) )* )","u&QWHjmFmJgq\\1pv",[extended])),
+ <<"uQWHjmFmJgqpvauQWHjmFmJgqpvbuQWHjmFmJgqpvcuQWHjmFmJgqpvduQWHjmFmJgqpv">> = iolist_to_binary(re:replace("abcd","( (A | (?(1)0|) )* )","u&QWHjmFmJgq\\1pv",[extended,
+ global])),
+ <<"tgtbuAeydNDbQksBabcd">> = iolist_to_binary(re:replace("abcd","( ( (?(1)0|) )* )","tg\\1tbuAe\\1ydNDbQksB\\1",[extended])),
+ <<"tgtbuAeydNDbQksBatgtbuAeydNDbQksBbtgtbuAeydNDbQksBctgtbuAeydNDbQksBdtgtbuAeydNDbQksB">> = iolist_to_binary(re:replace("abcd","( ( (?(1)0|) )* )","tg\\1tbuAe\\1ydNDbQksB\\1",[extended,
+ global])),
+ <<"geoFaKtBOldabcd">> = iolist_to_binary(re:replace("abcd","( (?(1)0|)* )","geoFa\\1K\\1\\1tBOld",[extended])),
+ <<"geoFaKtBOldageoFaKtBOldbgeoFaKtBOldcgeoFaKtBOlddgeoFaKtBOld">> = iolist_to_binary(re:replace("abcd","( (?(1)0|)* )","geoFa\\1K\\1\\1tBOld",[extended,
+ global])),
+ <<"a]FIQJiJK">> = iolist_to_binary(re:replace("a]","[[:abcd:xyz]]","&F\\1IQJiJK",[])),
+ <<"a]FIQJiJK">> = iolist_to_binary(re:replace("a]","[[:abcd:xyz]]","&F\\1IQJiJK",[global])),
+ <<"WWYQ:]Cfo:]">> = iolist_to_binary(re:replace(":]","[[:abcd:xyz]]","WWYQ&Cfo&\\1",[])),
+ <<"WWYQ:]Cfo:]">> = iolist_to_binary(re:replace(":]","[[:abcd:xyz]]","WWYQ&Cfo&\\1",[global])),
+ <<"qDnjOTLaOgtwATf">> = iolist_to_binary(re:replace("a","[abc[:x\\]pqr]","q\\1DnjOTL\\1&Og\\1twATf",[])),
+ <<"qDnjOTLaOgtwATf">> = iolist_to_binary(re:replace("a","[abc[:x\\]pqr]","q\\1DnjOTL\\1&Og\\1twATf",[global])),
+ <<"[">> = iolist_to_binary(re:replace("[","[abc[:x\\]pqr]","&\\1",[])),
+ <<"[">> = iolist_to_binary(re:replace("[","[abc[:x\\]pqr]","&\\1",[global])),
+ <<"mcQylXKI">> = iolist_to_binary(re:replace(":","[abc[:x\\]pqr]","\\1mcQy\\1\\1\\1lXKI",[])),
+ <<"mcQylXKI">> = iolist_to_binary(re:replace(":","[abc[:x\\]pqr]","\\1mcQy\\1\\1\\1lXKI",[global])),
+ <<"yLoVOOvX]MsmpqoJL">> = iolist_to_binary(re:replace("]","[abc[:x\\]pqr]","yLoVOOvX&MsmpqoJ\\1L",[])),
+ <<"yLoVOOvX]MsmpqoJL">> = iolist_to_binary(re:replace("]","[abc[:x\\]pqr]","yLoVOOvX&MsmpqoJ\\1L",[global])),
+ <<"X">> = iolist_to_binary(re:replace("p","[abc[:x\\]pqr]","\\1\\1X",[])),
+ <<"X">> = iolist_to_binary(re:replace("p","[abc[:x\\]pqr]","\\1\\1X",[global])),
+ <<"fooabcfoo">> = iolist_to_binary(re:replace("fooabcfoo",".*[op][xyz]","U&xA\\1PsdeOWUae&&Yna",[])),
+ <<"fooabcfoo">> = iolist_to_binary(re:replace("fooabcfoo",".*[op][xyz]","U&xA\\1PsdeOWUae&&Yna",[global])),
+ <<"QIBuirGXrnadc">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)","QIBuirGXrn",[])),
+ <<"QIBuirGXrnadc">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)","QIBuirGXrn",[global])),
+ <<"awbDHBgVdwqBlbic">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)","\\1w&DHBgVdwqBl&i",[])),
+ <<"awbDHBgVdwqBlbic">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)","\\1w&DHBgVdwqBl&i",[global])),
+ <<"bMxcDhNdGOtJIJBuCaadc">> = iolist_to_binary(re:replace("adc","(?(?=^.*b)b|^)","bMx\\1cDhNdGOtJIJBuCa&",[])),
+ <<"bMxcDhNdGOtJIJBuCaadc">> = iolist_to_binary(re:replace("adc","(?(?=^.*b)b|^)","bMx\\1cDhNdGOtJIJBuCa&",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(?(?=^.*b)b|^)","nnHoU&\\1CMWtr",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(?(?=^.*b)b|^)","nnHoU&\\1CMWtr",[global])),
+ <<"PXRohlVadc">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)*","PX\\1\\1RohlV",[])),
+ <<"PXRohlVaPXRohlVdPXRohlVcPXRohlV">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)*","PX\\1\\1RohlV",[global])),
+ <<"qnabc">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)*","&&qn",[])),
+ <<"qnabbqnqncqn">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)*","&&qn",[global])),
ok.
run37() ->
- <<"egMccJuvVmsJadc">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)+","egMccJu&\\1vVmsJ",[])),
- <<"egMccJuvVmsJadc">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)+","egMccJu&\\1vVmsJ",[global])),
- <<"awbKLc">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)+","wbKL",[])),
- <<"awbKLc">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)+","wbKL",[global])),
- <<"aaOKbMsgbwbYMvqpaKc">> = iolist_to_binary(re:replace("abc","(?(?=b).*b|^d)","aOK\\1&Msg&w&YMvqpaK",[])),
- <<"aaOKbMsgbwbYMvqpaKc">> = iolist_to_binary(re:replace("abc","(?(?=b).*b|^d)","aOK\\1&Msg&w&YMvqpaK",[global])),
- <<"deMQjInIpkdMc">> = iolist_to_binary(re:replace("abc","(?(?=.*b).*b|^d)","deMQjInI\\1\\1pk\\1dM",[])),
- <<"deMQjInIpkdMc">> = iolist_to_binary(re:replace("abc","(?(?=.*b).*b|^d)","deMQjInI\\1\\1pk\\1dM",[global])),
- <<"xONBt%ab%fkt">> = iolist_to_binary(re:replace("%ab%","^%((?(?=[a])[^%])|b)*%$","xONBt\\1&fkt",[])),
- <<"xONBt%ab%fkt">> = iolist_to_binary(re:replace("%ab%","^%((?(?=[a])[^%])|b)*%$","xONBt\\1&fkt",[global])),
- <<"XtGNvTytylTOX">> = iolist_to_binary(re:replace("XabX","(?i)a(?-i)b|c","tGN\\1\\1vT\\1yty\\1lTO",[])),
- <<"XtGNvTytylTOX">> = iolist_to_binary(re:replace("XabX","(?i)a(?-i)b|c","tGN\\1\\1vT\\1yty\\1lTO",[global])),
- <<"XAbMBAbVAbatgNrMNMDX">> = iolist_to_binary(re:replace("XAbX","(?i)a(?-i)b|c","&MB\\1&V&\\1atgNrMNMD",[])),
- <<"XAbMBAbVAbatgNrMNMDX">> = iolist_to_binary(re:replace("XAbX","(?i)a(?-i)b|c","&MB\\1&V&\\1atgNrMNMD",[global])),
- <<"CIeFFRMtpcC">> = iolist_to_binary(re:replace("CcC","(?i)a(?-i)b|c","IeFFRMtp&",[])),
- <<"CIeFFRMtpcC">> = iolist_to_binary(re:replace("CcC","(?i)a(?-i)b|c","IeFFRMtp&",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?i)a(?-i)b|c","sJoTR\\1agT&QVpj&oo",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?i)a(?-i)b|c","sJoTR\\1agT&QVpj&oo",[global])),
- <<"XABX">> = iolist_to_binary(re:replace("XABX","(?i)a(?-i)b|c","Bx\\1L&vYQ&o",[])),
- <<"XABX">> = iolist_to_binary(re:replace("XABX","(?i)a(?-i)b|c","Bx\\1L&vYQ&o",[global])),
- <<"bPwO">> = iolist_to_binary(re:replace("
- ","[\\x00-\\xff\\s]+","bPwO",[])),
- <<"bPwO">> = iolist_to_binary(re:replace("
- ","[\\x00-\\xff\\s]+","bPwO",[global])),
- <<"tNnUXVoKd">> = iolist_to_binary(re:replace("?","^\\c","tNnUXVoKd\\1",[])),
- <<"tNnUXVoKd">> = iolist_to_binary(re:replace("?","^\\c","tNnUXVoKd\\1",[global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1","Xcx",[caseless])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1","Xcx",[caseless,
- global])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1","yV\\1&bIy&bf",[])),
- <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1","yV\\1&bIy&bf",[global])),
- <<"12llNQ12abc">> = iolist_to_binary(re:replace("12abc","[^a]*","&llNQ\\1&\\1",[caseless])),
- <<"12llNQ12llNQabcllNQbcllNQ">> = iolist_to_binary(re:replace("12abc","[^a]*","&llNQ\\1&\\1",[caseless,
- global])),
- <<"gDpABC">> = iolist_to_binary(re:replace("12ABC","[^a]*","gDp",[caseless])),
- <<"gDpgDpAgDpgDp">> = iolist_to_binary(re:replace("12ABC","[^a]*","gDp",[caseless,
- global])),
- <<"DTxabc">> = iolist_to_binary(re:replace("12abc","[^a]*+","D\\1T\\1x",[caseless])),
- <<"DTxDTxaDTxDTx">> = iolist_to_binary(re:replace("12abc","[^a]*+","D\\1T\\1x",[caseless,
- global])),
- <<"KJ12jqgNXmTv12lyEP12SABC">> = iolist_to_binary(re:replace("12ABC","[^a]*+","KJ&jqgNXm\\1Tv&lyE\\1P&S",[caseless])),
- <<"KJ12jqgNXmTv12lyEP12SKJjqgNXmTvlyEPSAKJBCjqgNXmTvBClyEPBCSKJjqgNXmTvlyEPS">> = iolist_to_binary(re:replace("12ABC","[^a]*+","KJ&jqgNXm\\1Tv&lyE\\1P&S",[caseless,
+ <<"rFmutNbLVErIdadc">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)+","rFmutN\\1bLVE\\1r&Id",[])),
+ <<"rFmutNbLVErIdadc">> = iolist_to_binary(re:replace("adc","(?(?=.*b)b|^)+","rFmutN\\1bLVE\\1r&Id",[global])),
+ <<"auGFbmOYWc">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)+","uGF&mOYW",[])),
+ <<"auGFbmOYWc">> = iolist_to_binary(re:replace("abc","(?(?=.*b)b|^)+","uGF&mOYW",[global])),
+ <<"aLwwyNOhXnbPc">> = iolist_to_binary(re:replace("abc","(?(?=b).*b|^d)","L\\1wwyNOhXn&P",[])),
+ <<"aLwwyNOhXnbPc">> = iolist_to_binary(re:replace("abc","(?(?=b).*b|^d)","L\\1wwyNOhXn&P",[global])),
+ <<"asLUhduQyBc">> = iolist_to_binary(re:replace("abc","(?(?=.*b).*b|^d)","asLUhdu\\1Q\\1yB",[])),
+ <<"asLUhduQyBc">> = iolist_to_binary(re:replace("abc","(?(?=.*b).*b|^d)","asLUhdu\\1Q\\1yB",[global])),
+ <<"fiC%ab%h%ab%TxFpRPHS">> = iolist_to_binary(re:replace("%ab%","^%((?(?=[a])[^%])|b)*%$","fiC\\1&h&\\1TxFpRPHS",[])),
+ <<"fiC%ab%h%ab%TxFpRPHS">> = iolist_to_binary(re:replace("%ab%","^%((?(?=[a])[^%])|b)*%$","fiC\\1&h&\\1TxFpRPHS",[global])),
+ <<"XRMNILOabxXkxRwpX">> = iolist_to_binary(re:replace("XabX","(?i)a(?-i)b|c","\\1RMNILO&xX\\1kxRwp\\1",[])),
+ <<"XRMNILOabxXkxRwpX">> = iolist_to_binary(re:replace("XabX","(?i)a(?-i)b|c","\\1RMNILO&xX\\1kxRwp\\1",[global])),
+ <<"XvAGipJAbWX">> = iolist_to_binary(re:replace("XAbX","(?i)a(?-i)b|c","vAGipJ&W",[])),
+ <<"XvAGipJAbWX">> = iolist_to_binary(re:replace("XAbX","(?i)a(?-i)b|c","vAGipJ&W",[global])),
+ <<"CecknrhbVOUlbPhcC">> = iolist_to_binary(re:replace("CcC","(?i)a(?-i)b|c","e&knr\\1hbV\\1O\\1\\1UlbPh&",[])),
+ <<"CecknrhbVOUlbPhcC">> = iolist_to_binary(re:replace("CcC","(?i)a(?-i)b|c","e&knr\\1hbV\\1O\\1\\1UlbPh&",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?i)a(?-i)b|c","oY\\1",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?i)a(?-i)b|c","oY\\1",[global])),
+ <<"XABX">> = iolist_to_binary(re:replace("XABX","(?i)a(?-i)b|c","nMN",[])),
+ <<"XABX">> = iolist_to_binary(re:replace("XABX","(?i)a(?-i)b|c","nMN",[global])),
+ <<"
+ uhYqCJYVNVkjTafan">> = iolist_to_binary(re:replace("
+ ","[\\x00-\\xff\\s]+","&uhY\\1qCJYVNVkj\\1Tafan",[])),
+ <<"
+ uhYqCJYVNVkjTafan">> = iolist_to_binary(re:replace("
+ ","[\\x00-\\xff\\s]+","&uhY\\1qCJYVNVkj\\1Tafan",[global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1","kAbCkN\\1XOTPWkPh",[caseless])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1","kAbCkN\\1XOTPWkPh",[caseless,
+ global])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1","&LHRW\\1vSiG&pKPe",[])),
+ <<"abc">> = iolist_to_binary(re:replace("abc","(abc)\\1","&LHRW\\1vSiG&pKPe",[global])),
+ <<"FPw12SGgbdRnHYs12Gabc">> = iolist_to_binary(re:replace("12abc","[^a]*","FPw&\\1SGgbdRnHYs&\\1G\\1",[caseless])),
+ <<"FPw12SGgbdRnHYs12GFPwSGgbdRnHYsGaFPwbcSGgbdRnHYsbcGFPwSGgbdRnHYsG">> = iolist_to_binary(re:replace("12abc","[^a]*","FPw&\\1SGgbdRnHYs&\\1G\\1",[caseless,
global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","[^a]*?X","Px&vXsBEFCysfMhDqV\\1P",[caseless])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","[^a]*?X","Px&vXsBEFCysfMhDqV\\1P",[caseless,
- global])),
- <<"12abc">> = iolist_to_binary(re:replace("12abc","[^a]*?X","q\\1a\\1jtOoCrLWAYsie",[caseless])),
- <<"12abc">> = iolist_to_binary(re:replace("12abc","[^a]*?X","q\\1a\\1jtOoCrLWAYsie",[caseless,
- global])),
- <<"12ABC">> = iolist_to_binary(re:replace("12ABC","[^a]*?X","LCDXsQB\\1&fP&vNDlCH\\1",[caseless])),
- <<"12ABC">> = iolist_to_binary(re:replace("12ABC","[^a]*?X","LCDXsQB\\1&fP&vNDlCH\\1",[caseless,
- global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","[^a]+?X","g&\\1\\1wRCp",[caseless])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","[^a]+?X","g&\\1\\1wRCp",[caseless,
- global])),
- <<"12abc">> = iolist_to_binary(re:replace("12abc","[^a]+?X","PO&\\1NINrfwP&\\1AcHiEa",[caseless])),
- <<"12abc">> = iolist_to_binary(re:replace("12abc","[^a]+?X","PO&\\1NINrfwP&\\1AcHiEa",[caseless,
+ <<"ABC">> = iolist_to_binary(re:replace("12ABC","[^a]*","\\1",[caseless])),
+ <<"A">> = iolist_to_binary(re:replace("12ABC","[^a]*","\\1",[caseless,
+ global])),
+ <<"rwrXcjPYabc">> = iolist_to_binary(re:replace("12abc","[^a]*+","rw\\1r\\1XcjPY",[caseless])),
+ <<"rwrXcjPYrwrXcjPYarwrXcjPYrwrXcjPY">> = iolist_to_binary(re:replace("12abc","[^a]*+","rw\\1r\\1XcjPY",[caseless,
+ global])),
+ <<"12Ebhb12ABC">> = iolist_to_binary(re:replace("12ABC","[^a]*+","&Ebhb\\1&",[caseless])),
+ <<"12Ebhb12EbhbABCEbhbBCEbhb">> = iolist_to_binary(re:replace("12ABC","[^a]*+","&Ebhb\\1&",[caseless,
+ global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","[^a]*?X","vUGseV",[caseless])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","[^a]*?X","vUGseV",[caseless,
+ global])),
+ <<"12abc">> = iolist_to_binary(re:replace("12abc","[^a]*?X","p\\1\\1IMIKml&O&E",[caseless])),
+ <<"12abc">> = iolist_to_binary(re:replace("12abc","[^a]*?X","p\\1\\1IMIKml&O&E",[caseless,
+ global])),
+ <<"12ABC">> = iolist_to_binary(re:replace("12ABC","[^a]*?X","x\\1",[caseless])),
+ <<"12ABC">> = iolist_to_binary(re:replace("12ABC","[^a]*?X","x\\1",[caseless,
+ global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","[^a]+?X","Y\\1KYtfghC",[caseless])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","[^a]+?X","Y\\1KYtfghC",[caseless,
+ global])),
+ <<"12abc">> = iolist_to_binary(re:replace("12abc","[^a]+?X","CjJxtxeRkNqWb",[caseless])),
+ <<"12abc">> = iolist_to_binary(re:replace("12abc","[^a]+?X","CjJxtxeRkNqWb",[caseless,
+ global])),
+ <<"12ABC">> = iolist_to_binary(re:replace("12ABC","[^a]+?X","\\1T&I\\1\\1UFIhN&\\1a",[caseless])),
+ <<"12ABC">> = iolist_to_binary(re:replace("12ABC","[^a]+?X","\\1T&I\\1\\1UFIhN&\\1a",[caseless,
global])),
- <<"12ABC">> = iolist_to_binary(re:replace("12ABC","[^a]+?X","LesucI&TIspq&O\\1AkOp",[caseless])),
- <<"12ABC">> = iolist_to_binary(re:replace("12ABC","[^a]+?X","LesucI&TIspq&O\\1AkOp",[caseless,
+ <<"12aTtXNbcX">> = iolist_to_binary(re:replace("12aXbcX","[^a]?X","Tt&N",[caseless])),
+ <<"12aTtXNbTtcXN">> = iolist_to_binary(re:replace("12aXbcX","[^a]?X","Tt&N",[caseless,
+ global])),
+ <<"12AXkPyHlRCnbcTxXoIkgXPBCX">> = iolist_to_binary(re:replace("12AXBCX","[^a]?X","&kPyHlRCnbcTx&oIkg&P",[caseless])),
+ <<"12AXkPyHlRCnbcTxXoIkgXPBCXkPyHlRCnbcTxCXoIkgCXP">> = iolist_to_binary(re:replace("12AXBCX","[^a]?X","&kPyHlRCnbcTx&oIkg&P",[caseless,
global])),
- <<"12arSestlSfXbcX">> = iolist_to_binary(re:replace("12aXbcX","[^a]?X","\\1rSestlSf\\1&",[caseless])),
- <<"12arSestlSfXbrSestlSfcX">> = iolist_to_binary(re:replace("12aXbcX","[^a]?X","\\1rSestlSf\\1&",[caseless,
- global])),
- <<"12AVBtPBCX">> = iolist_to_binary(re:replace("12AXBCX","[^a]?X","VBtP",[caseless])),
- <<"12AVBtPBVBtP">> = iolist_to_binary(re:replace("12AXBCX","[^a]?X","VBtP",[caseless,
+ <<"BCXABigfWDnwCXJ">> = iolist_to_binary(re:replace("BCX","[^a]?X","&ABigfWDnw&J",[caseless])),
+ <<"BCXABigfWDnwCXJ">> = iolist_to_binary(re:replace("BCX","[^a]?X","&ABigfWDnw&J",[caseless,
+ global])),
+ <<"12aYXWbgOvNcDMXVYThubcX">> = iolist_to_binary(re:replace("12aXbcX","[^a]??X","YX\\1\\1WbgOvNcDM&VYTh\\1u",[caseless])),
+ <<"12aYXWbgOvNcDMXVYThubYXWbgOvNcDMcXVYThu">> = iolist_to_binary(re:replace("12aXbcX","[^a]??X","YX\\1\\1WbgOvNcDM&VYTh\\1u",[caseless,
+ global])),
+ <<"12AEpmXPCouNXdKStKXBCX">> = iolist_to_binary(re:replace("12AXBCX","[^a]??X","Epm&PCouN&dKStK&",[caseless])),
+ <<"12AEpmXPCouNXdKStKXBEpmCXPCouNCXdKStKCX">> = iolist_to_binary(re:replace("12AXBCX","[^a]??X","Epm&PCouN&dKStK&",[caseless,
+ global])),
+ <<"BaCXpoxfpseXfNhG">> = iolist_to_binary(re:replace("BCX","[^a]??X","a\\1&po\\1x\\1fps\\1eXfNhG",[caseless])),
+ <<"BaCXpoxfpseXfNhG">> = iolist_to_binary(re:replace("BCX","[^a]??X","a\\1&po\\1x\\1fps\\1eXfNhG",[caseless,
+ global])),
+ <<"12aXbgfcXfFQYBVbwm">> = iolist_to_binary(re:replace("12aXbcX","[^a]?+X","gf&fFQYBVbwm",[caseless])),
+ <<"12aXbgfcXfFQYBVbwm">> = iolist_to_binary(re:replace("12aXbcX","[^a]?+X","gf&fFQYBVbwm",[caseless,
+ global])),
+ <<"12AXBehBuhCXqmVsCXWtCXg">> = iolist_to_binary(re:replace("12AXBCX","[^a]?+X","ehBuh&q\\1\\1mV\\1s\\1&Wt&g",[caseless])),
+ <<"12AXBehBuhCXqmVsCXWtCXg">> = iolist_to_binary(re:replace("12AXBCX","[^a]?+X","ehBuh&q\\1\\1mV\\1s\\1&Wt&g",[caseless,
+ global])),
+ <<"BQ">> = iolist_to_binary(re:replace("BCX","[^a]?+X","Q",[caseless])),
+ <<"BQ">> = iolist_to_binary(re:replace("BCX","[^a]?+X","Q",[caseless,
+ global])),
+ <<"ayFHgvqLgSIvMef">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}","\\1yFHgvq\\1LgSIvM",[caseless])),
+ <<"ayFHgvqLgSIvMyFHgvqLgSIvM">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}","\\1yFHgvq\\1LgSIvM",[caseless,
+ global])),
+ <<"ADLEECoGfLBCDtOKBYRuEPEF">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}","\\1DLEECoGfL&tOKBYRuEP",[caseless])),
+ <<"ADLEECoGfLBCDtOKBYRuEPDLEECoGfLEFtOKBYRuEP">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}","\\1DLEECoGfL&tOKBYRuEP",[caseless,
+ global])),
+ <<"aUeRruprbcLyGdbcOBlHdef">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}?","UeRrup\\1r\\1&Ly\\1Gd&OBlH",[caseless])),
+ <<"aUeRruprbcLyGdbcOBlHUeRruprdeLyGddeOBlHf">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}?","UeRrup\\1r\\1&Ly\\1Gd&OBlH",[caseless,
+ global])),
+ <<"AmqfmUDEF">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}?","mqfmU",[caseless])),
+ <<"AmqfmUmqfmUF">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}?","mqfmU",[caseless,
+ global])),
+ <<"ajef">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}+","j",[caseless])),
+ <<"ajj">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}+","j",[caseless,
global])),
- <<"BCXcYCXS">> = iolist_to_binary(re:replace("BCX","[^a]?X","&cY&S\\1",[caseless])),
- <<"BCXcYCXS">> = iolist_to_binary(re:replace("BCX","[^a]?X","&cY&S\\1",[caseless,
- global])),
- <<"12aMPavbiGCbcX">> = iolist_to_binary(re:replace("12aXbcX","[^a]??X","MPavbi\\1GC",[caseless])),
- <<"12aMPavbiGCbMPavbiGC">> = iolist_to_binary(re:replace("12aXbcX","[^a]??X","MPavbi\\1GC",[caseless,
- global])),
- <<"12AOTaIyfCCPBCX">> = iolist_to_binary(re:replace("12AXBCX","[^a]??X","OTaIy\\1fC\\1CP",[caseless])),
- <<"12AOTaIyfCCPBOTaIyfCCP">> = iolist_to_binary(re:replace("12AXBCX","[^a]??X","OTaIy\\1fC\\1CP",[caseless,
- global])),
- <<"BCXlQqcJ">> = iolist_to_binary(re:replace("BCX","[^a]??X","&\\1l\\1QqcJ",[caseless])),
- <<"BCXlQqcJ">> = iolist_to_binary(re:replace("BCX","[^a]??X","&\\1l\\1QqcJ",[caseless,
- global])),
- <<"12aXbEPWWBEweltvRcX">> = iolist_to_binary(re:replace("12aXbcX","[^a]?+X","EPWWBEweltvR&",[caseless])),
- <<"12aXbEPWWBEweltvRcX">> = iolist_to_binary(re:replace("12aXbcX","[^a]?+X","EPWWBEweltvR&",[caseless,
- global])),
- <<"12AXBLDKxRfr">> = iolist_to_binary(re:replace("12AXBCX","[^a]?+X","LD\\1KxRfr",[caseless])),
- <<"12AXBLDKxRfr">> = iolist_to_binary(re:replace("12AXBCX","[^a]?+X","LD\\1KxRfr",[caseless,
- global])),
- <<"BaWkje">> = iolist_to_binary(re:replace("BCX","[^a]?+X","aWkje",[caseless])),
- <<"BaWkje">> = iolist_to_binary(re:replace("BCX","[^a]?+X","aWkje",[caseless,
- global])),
- <<"alsDrlAVvgef">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}","lsDrlAVvg",[caseless])),
- <<"alsDrlAVvglsDrlAVvg">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}","lsDrlAVvg",[caseless,
+ <<"AmBCDGmEF">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}+","m\\1&Gm",[caseless])),
+ <<"AmBCDGmmEFGm">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}+","m\\1&Gm",[caseless,
global])),
- <<"AWnBBhxrEF">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}","WnBBhxr\\1",[caseless])),
- <<"AWnBBhxrWnBBhxr">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}","WnBBhxr\\1",[caseless,
- global])),
- <<"aQlBRWDWodef">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}?","QlBRWDWo",[caseless])),
- <<"aQlBRWDWoQlBRWDWof">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}?","QlBRWDWo",[caseless,
- global])),
- <<"ADysgJSywfPBCKKUUWYDEF">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}?","DysgJSywfP\\1&KKUUWY",[caseless])),
- <<"ADysgJSywfPBCKKUUWYDysgJSywfPDEKKUUWYF">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}?","DysgJSywfP\\1&KKUUWY",[caseless,
- global])),
- <<"aWjgnJGWef">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}+","WjgnJ\\1GW",[caseless])),
- <<"aWjgnJGWWjgnJGW">> = iolist_to_binary(re:replace("abcdef","[^a]{2,3}+","WjgnJ\\1GW",[caseless,
- global])),
- <<"ArlhBCDwHgMHHwjEiAEF">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}+","rlh&wHgMHHwjEiA",[caseless])),
- <<"ArlhBCDwHgMHHwjEiArlhEFwHgMHHwjEiA">> = iolist_to_binary(re:replace("ABCDEF","[^a]{2,3}+","rlh&wHgMHHwjEiA",[caseless,
- global])),
- <<"JdTSxtdMYhvAoaO">> = iolist_to_binary(re:replace("Z","((a|)+)+Z","JdTSxtdMYhv\\1AoaO",[])),
- <<"JdTSxtdMYhvAoaO">> = iolist_to_binary(re:replace("Z","((a|)+)+Z","JdTSxtdMYhv\\1AoaO",[global])),
+ <<"VQZqc">> = iolist_to_binary(re:replace("Z","((a|)+)+Z","VQ&qc",[])),
+ <<"VQZqc">> = iolist_to_binary(re:replace("Z","((a|)+)+Z","VQ&qc",[global])),
ok.
run38() ->
- <<"dAWFejmOJacpU">> = iolist_to_binary(re:replace("ac","(a)b|(a)c","dA\\1\\1WFejmOJ&pU",[])),
- <<"dAWFejmOJacpU">> = iolist_to_binary(re:replace("ac","(a)b|(a)c","dA\\1\\1WFejmOJ&pU",[global])),
- <<"XacWp">> = iolist_to_binary(re:replace("ac","(?>(a))b|(a)c","X&Wp",[])),
- <<"XacWp">> = iolist_to_binary(re:replace("ac","(?>(a))b|(a)c","X&Wp",[global])),
- <<"VypacbfdlXdCGJofacdRt">> = iolist_to_binary(re:replace("ac","(?=(a))ab|(a)c","Vyp&bfdlXdCGJo\\1f&dRt",[])),
- <<"VypacbfdlXdCGJofacdRt">> = iolist_to_binary(re:replace("ac","(?=(a))ab|(a)c","Vyp&bfdlXdCGJo\\1f&dRt",[global])),
- <<"soXacAL">> = iolist_to_binary(re:replace("ac","((?>(a))b|(a)c)","soX&AL",[])),
- <<"soXacAL">> = iolist_to_binary(re:replace("ac","((?>(a))b|(a)c)","soX&AL",[global])),
- <<"ackacTacsYVlYVjKacCEL">> = iolist_to_binary(re:replace("ac","((?>(a))b|(a)c)++","&k\\1T&sYVlYVjK&CEL",[])),
- <<"ackacTacsYVlYVjKacCEL">> = iolist_to_binary(re:replace("ac","((?>(a))b|(a)c)++","&k\\1T&sYVlYVjK&CEL",[global])),
- <<"qiUiactJ">> = iolist_to_binary(re:replace("ac","(?:(?>(a))b|(a)c)++","qiUi&tJ\\1",[])),
- <<"qiUiactJ">> = iolist_to_binary(re:replace("ac","(?:(?>(a))b|(a)c)++","qiUi&tJ\\1",[global])),
- <<"KkacqeX">> = iolist_to_binary(re:replace("ac","(?=(?>(a))b|(a)c)(..)","Kk&qeX",[])),
- <<"KkacqeX">> = iolist_to_binary(re:replace("ac","(?=(?>(a))b|(a)c)(..)","Kk&qeX",[global])),
- <<"dtNNac">> = iolist_to_binary(re:replace("ac","(?>(?>(a))b|(a)c)","dtNN&",[])),
- <<"dtNNac">> = iolist_to_binary(re:replace("ac","(?>(?>(a))b|(a)c)","dtNN&",[global])),
- <<"maaaabaaabaababGEUEgWaaaabaaabaababRaaaabaaabaababYtLSDKaaaabaaabaababA">> = iolist_to_binary(re:replace("aaaabaaabaabab","((?>(a+)b)+(aabab))","m&GEUEgW\\1R&YtLSDK\\1A",[])),
- <<"maaaabaaabaababGEUEgWaaaabaaabaababRaaaabaaabaababYtLSDKaaaabaaabaababA">> = iolist_to_binary(re:replace("aaaabaaabaabab","((?>(a+)b)+(aabab))","m&GEUEgW\\1R&YtLSDK\\1A",[global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","(?>a+|ab)+?c","hd\\1shPpIuFmAa\\1aJk&q",[])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","(?>a+|ab)+?c","hd\\1shPpIuFmAa\\1aJk&q",[global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","(?>a+|ab)+c","ekKjsw&",[])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","(?>a+|ab)+c","ekKjsw&",[global])),
- <<"KRQcpPbvHhi">> = iolist_to_binary(re:replace("aabc","(?:a+|ab)+c","KRQcpPbvHhi",[])),
- <<"KRQcpPbvHhi">> = iolist_to_binary(re:replace("aabc","(?:a+|ab)+c","KRQcpPbvHhi",[global])),
- <<"iamaarURhafOTI">> = iolist_to_binary(re:replace("a","(?(?=(a))a)","i&m&&rURh\\1fOTI",[])),
- <<"iamaarURhafOTIimrURhfOTI">> = iolist_to_binary(re:replace("a","(?(?=(a))a)","i&m&&rURh\\1fOTI",[global])),
- <<"aba">> = iolist_to_binary(re:replace("ab","(?(?=(a))a)(b)","&a",[])),
- <<"aba">> = iolist_to_binary(re:replace("ab","(?(?=(a))a)(b)","&a",[global])),
- <<"aaaabc">> = iolist_to_binary(re:replace("aaaabc","^(?:a|ab)++c","Siik\\1BdqOkNdp\\1",[])),
- <<"aaaabc">> = iolist_to_binary(re:replace("aaaabc","^(?:a|ab)++c","Siik\\1BdqOkNdp\\1",[global])),
- <<"aaaabc">> = iolist_to_binary(re:replace("aaaabc","^(?>a|ab)++c","LpFM&EcaXt\\1b\\1",[])),
- <<"aaaabc">> = iolist_to_binary(re:replace("aaaabc","^(?>a|ab)++c","LpFM&EcaXt\\1b\\1",[global])),
- <<"FNLSSaaaabcr">> = iolist_to_binary(re:replace("aaaabc","^(?:a|ab)+c","FNLSS&r",[])),
- <<"FNLSSaaaabcr">> = iolist_to_binary(re:replace("aaaabc","^(?:a|ab)+c","FNLSS&r",[global])),
- <<"TxGxyzQbpeqVTpoEkrYqxyz">> = iolist_to_binary(re:replace("xyz","(?=abc){0}xyz","TxG\\1&QbpeqVTpoEkrYq&",[])),
- <<"TxGxyzQbpeqVTpoEkrYqxyz">> = iolist_to_binary(re:replace("xyz","(?=abc){0}xyz","TxG\\1&QbpeqVTpoEkrYq&",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?=abc){1}xyz","cR\\1y\\1Q\\1&okEra\\1h",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?=abc){1}xyz","cR\\1y\\1Q\\1&okEra\\1h",[global])),
- <<"xyz">> = iolist_to_binary(re:replace("xyz","(?=abc){1}xyz","reg\\1lU\\1RfQVPuOHJA\\1Cq",[])),
- <<"xyz">> = iolist_to_binary(re:replace("xyz","(?=abc){1}xyz","reg\\1lU\\1RfQVPuOHJA\\1Cq",[global])),
- <<"xcPaaLxpkaXVHb">> = iolist_to_binary(re:replace("ab","(?=(a))?.","xcP\\1aLxpkaXVH",[])),
- <<"xcPaaLxpkaXVHxcPaLxpkaXVH">> = iolist_to_binary(re:replace("ab","(?=(a))?.","xcP\\1aLxpkaXVH",[global])),
- <<"sOiVGLUSbixjsOGc">> = iolist_to_binary(re:replace("bc","(?=(a))?.","s\\1OiVGLUS&ixjsOG",[])),
- <<"sOiVGLUSbixjsOGsOiVGLUScixjsOG">> = iolist_to_binary(re:replace("bc","(?=(a))?.","s\\1OiVGLUS&ixjsOG",[global])),
+ <<"PuyLdacsxAquacIQeUSo">> = iolist_to_binary(re:replace("ac","(a)b|(a)c","PuyLd&sxAqu&IQ\\1\\1eUSo",[])),
+ <<"PuyLdacsxAquacIQeUSo">> = iolist_to_binary(re:replace("ac","(a)b|(a)c","PuyLd&sxAqu&IQ\\1\\1eUSo",[global])),
+ <<"PfacaR">> = iolist_to_binary(re:replace("ac","(?>(a))b|(a)c","Pf&aR",[])),
+ <<"PfacaR">> = iolist_to_binary(re:replace("ac","(?>(a))b|(a)c","Pf&aR",[global])),
+ <<"acFJaBfLkqacLOtea">> = iolist_to_binary(re:replace("ac","(?=(a))ab|(a)c","&FJaBfLkq&LOtea",[])),
+ <<"acFJaBfLkqacLOtea">> = iolist_to_binary(re:replace("ac","(?=(a))ab|(a)c","&FJaBfLkq&LOtea",[global])),
+ <<"acGacsLawsVtbac">> = iolist_to_binary(re:replace("ac","((?>(a))b|(a)c)","\\1G&sLawsVtb\\1",[])),
+ <<"acGacsLawsVtbac">> = iolist_to_binary(re:replace("ac","((?>(a))b|(a)c)","\\1G&sLawsVtb\\1",[global])),
+ <<"acacoiIuacXacacraccbxYvQLU">> = iolist_to_binary(re:replace("ac","((?>(a))b|(a)c)++","&&oiIu&X\\1&r\\1cbxYvQLU",[])),
+ <<"acacoiIuacXacacraccbxYvQLU">> = iolist_to_binary(re:replace("ac","((?>(a))b|(a)c)++","&&oiIu&X\\1&r\\1cbxYvQLU",[global])),
+ <<"Gg">> = iolist_to_binary(re:replace("ac","(?:(?>(a))b|(a)c)++","\\1Gg",[])),
+ <<"Gg">> = iolist_to_binary(re:replace("ac","(?:(?>(a))b|(a)c)++","\\1Gg",[global])),
+ <<"unjEacjaceFacYac">> = iolist_to_binary(re:replace("ac","(?=(?>(a))b|(a)c)(..)","\\1u\\1njE&\\1j\\1&e\\1F&Y&\\1",[])),
+ <<"unjEacjaceFacYac">> = iolist_to_binary(re:replace("ac","(?=(?>(a))b|(a)c)(..)","\\1u\\1njE&\\1j\\1&e\\1F&Y&\\1",[global])),
+ <<"vacJbYTacPQOPmacrKp">> = iolist_to_binary(re:replace("ac","(?>(?>(a))b|(a)c)","v&JbYT&PQOPm&rKp",[])),
+ <<"vacJbYTacPQOPmacrKp">> = iolist_to_binary(re:replace("ac","(?>(?>(a))b|(a)c)","v&JbYT&PQOPm&rKp",[global])),
+ <<"n">> = iolist_to_binary(re:replace("aaaabaaabaabab","((?>(a+)b)+(aabab))","n",[])),
+ <<"n">> = iolist_to_binary(re:replace("aaaabaaabaabab","((?>(a+)b)+(aabab))","n",[global])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","(?>a+|ab)+?c","wTE",[])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","(?>a+|ab)+?c","wTE",[global])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","(?>a+|ab)+c","IcRpe",[])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","(?>a+|ab)+c","IcRpe",[global])),
+ <<"DJtCudRWwbqgG">> = iolist_to_binary(re:replace("aabc","(?:a+|ab)+c","DJtCudRWwbqgG",[])),
+ <<"DJtCudRWwbqgG">> = iolist_to_binary(re:replace("aabc","(?:a+|ab)+c","DJtCudRWwbqgG",[global])),
+ <<"aaaSoBtHaacWirPkada">> = iolist_to_binary(re:replace("a","(?(?=(a))a)","\\1\\1&SoBtH&&cWirPk&da",[])),
+ <<"aaaSoBtHaacWirPkadaSoBtHcWirPkda">> = iolist_to_binary(re:replace("a","(?(?=(a))a)","\\1\\1&SoBtH&&cWirPk&da",[global])),
+ <<"xSIuiabsLIGaaPOY">> = iolist_to_binary(re:replace("ab","(?(?=(a))a)(b)","xSIui\\1bsLIG\\1\\1POY",[])),
+ <<"xSIuiabsLIGaaPOY">> = iolist_to_binary(re:replace("ab","(?(?=(a))a)(b)","xSIui\\1bsLIG\\1\\1POY",[global])),
+ <<"aaaabc">> = iolist_to_binary(re:replace("aaaabc","^(?:a|ab)++c","G",[])),
+ <<"aaaabc">> = iolist_to_binary(re:replace("aaaabc","^(?:a|ab)++c","G",[global])),
+ <<"aaaabc">> = iolist_to_binary(re:replace("aaaabc","^(?>a|ab)++c","DPoYmBjVu",[])),
+ <<"aaaabc">> = iolist_to_binary(re:replace("aaaabc","^(?>a|ab)++c","DPoYmBjVu",[global])),
+ <<"Khaaaabc">> = iolist_to_binary(re:replace("aaaabc","^(?:a|ab)+c","Kh&\\1",[])),
+ <<"Khaaaabc">> = iolist_to_binary(re:replace("aaaabc","^(?:a|ab)+c","Kh&\\1",[global])),
+ <<"hxyzMPAlxyzbeeMvcxyzFnYVJ">> = iolist_to_binary(re:replace("xyz","(?=abc){0}xyz","h&MPAl&beeMvc&FnYVJ",[])),
+ <<"hxyzMPAlxyzbeeMvcxyzFnYVJ">> = iolist_to_binary(re:replace("xyz","(?=abc){0}xyz","h&MPAl&beeMvc&FnYVJ",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?=abc){1}xyz","pskDi\\1Vp\\1\\1KjCOoy&",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?=abc){1}xyz","pskDi\\1Vp\\1\\1KjCOoy&",[global])),
+ <<"xyz">> = iolist_to_binary(re:replace("xyz","(?=abc){1}xyz","\\1P\\1h&aRQ",[])),
+ <<"xyz">> = iolist_to_binary(re:replace("xyz","(?=abc){1}xyz","\\1P\\1h&aRQ",[global])),
+ <<"aaPvGqLaOcNadob">> = iolist_to_binary(re:replace("ab","(?=(a))?.","a\\1PvGqL&OcN&do",[])),
+ <<"aaPvGqLaOcNadoaPvGqLbOcNbdo">> = iolist_to_binary(re:replace("ab","(?=(a))?.","a\\1PvGqL&OcN&do",[global])),
+ <<"nEGDfiQkQbbc">> = iolist_to_binary(re:replace("bc","(?=(a))?.","nEGDfiQkQ&&",[])),
+ <<"nEGDfiQkQbbnEGDfiQkQcc">> = iolist_to_binary(re:replace("bc","(?=(a))?.","nEGDfiQkQ&&",[global])),
ok.
run39() ->
- <<"VDuEPkfWcTxyeUaBWb">> = iolist_to_binary(re:replace("ab","(?=(a))??.","VDuEPkfWcTxyeU&BW",[])),
- <<"VDuEPkfWcTxyeUaBWVDuEPkfWcTxyeUbBW">> = iolist_to_binary(re:replace("ab","(?=(a))??.","VDuEPkfWcTxyeU&BW",[global])),
- <<"mbbCUVsGVbqKPXic">> = iolist_to_binary(re:replace("bc","(?=(a))??.","m&bCUVsGVbqKPXi",[])),
- <<"mbbCUVsGVbqKPXimcbCUVsGVbqKPXi">> = iolist_to_binary(re:replace("bc","(?=(a))??.","m&bCUVsGVbqKPXi",[global])),
- <<"vckgammon">> = iolist_to_binary(re:replace("backgammon","^(?=(a)){0}b(?1)","v",[])),
- <<"vckgammon">> = iolist_to_binary(re:replace("backgammon","^(?=(a)){0}b(?1)","v",[global])),
- <<"jwhBBBtpN">> = iolist_to_binary(re:replace("abd","^(?=(?1))?[az]([abc])d","jwhBBBtpN",[])),
- <<"jwhBBBtpN">> = iolist_to_binary(re:replace("abd","^(?=(?1))?[az]([abc])d","jwhBBBtpN",[global])),
- <<"zcdBcKYPcEyoXnxVFxx">> = iolist_to_binary(re:replace("zcdxx","^(?=(?1))?[az]([abc])d","&B\\1KYPcEyoXnxVF",[])),
- <<"zcdBcKYPcEyoXnxVFxx">> = iolist_to_binary(re:replace("zcdxx","^(?=(?1))?[az]([abc])d","&B\\1KYPcEyoXnxVF",[global])),
- <<"eaaaaacuRrwVlw">> = iolist_to_binary(re:replace("aaaaa","^(?!a){0}\\w+","e&cuR\\1rwVlw",[])),
- <<"eaaaaacuRrwVlw">> = iolist_to_binary(re:replace("aaaaa","^(?!a){0}\\w+","e&cuR\\1rwVlw",[global])),
- <<"abcrjCWbwUOujlotBJKabcTxyz">> = iolist_to_binary(re:replace("abcxyz","(?<=(abc))?xyz","rjCWbwUOujlotBJK\\1T&",[])),
- <<"abcrjCWbwUOujlotBJKabcTxyz">> = iolist_to_binary(re:replace("abcxyz","(?<=(abc))?xyz","rjCWbwUOujlotBJK\\1T&",[global])),
- <<"pqrMKeGrgiv">> = iolist_to_binary(re:replace("pqrxyz","(?<=(abc))?xyz","MKeGrgi\\1v",[])),
- <<"pqrMKeGrgiv">> = iolist_to_binary(re:replace("pqrxyz","(?<=(abc))?xyz","MKeGrgi\\1v",[global])),
- <<"RxQ">> = iolist_to_binary(re:replace("ggg<<<aaa>>>","^[\\g<a>]+","\\1RxQ",[])),
- <<"RxQ">> = iolist_to_binary(re:replace("ggg<<<aaa>>>","^[\\g<a>]+","\\1RxQ",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\g<a>]+","dH",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\g<a>]+","dH",[global])),
- <<"\\ga">> = iolist_to_binary(re:replace("\\ga","^[\\g<a>]+","Uga",[])),
- <<"\\ga">> = iolist_to_binary(re:replace("\\ga","^[\\g<a>]+","Uga",[global])),
- <<"kGIjWAmWxlixyz">> = iolist_to_binary(re:replace("gggagagaxyz","^[\\ga]+","kGIjWAmWxli",[])),
- <<"kGIjWAmWxlixyz">> = iolist_to_binary(re:replace("gggagagaxyz","^[\\ga]+","kGIjWAmWxli",[global])),
- <<"aaaa444:::osjAfaaaa444:::myeRjZ">> = iolist_to_binary(re:replace("aaaa444:::Z","^[:a[:digit:]]+","&\\1osjAf&my\\1e\\1Rj",[])),
- <<"aaaa444:::osjAfaaaa444:::myeRjZ">> = iolist_to_binary(re:replace("aaaa444:::Z","^[:a[:digit:]]+","&\\1osjAf&my\\1e\\1Rj",[global])),
- <<"qSUaaaa444:::bbbthaaaa444:::bbboRHpyZ">> = iolist_to_binary(re:replace("aaaa444:::bbbZ","^[:a[:digit:]:b]+","qSU&th&oR\\1Hpy",[])),
- <<"qSUaaaa444:::bbbthaaaa444:::bbboRHpyZ">> = iolist_to_binary(re:replace("aaaa444:::bbbZ","^[:a[:digit:]:b]+","qSU&th&oR\\1Hpy",[global])),
- <<"mxfweUe">> = iolist_to_binary(re:replace(":xxx:","[:a]xxx[b:]","mxf\\1weUe",[])),
- <<"mxfweUe">> = iolist_to_binary(re:replace(":xxx:","[:a]xxx[b:]","mxf\\1weUe",[global])),
- <<"xaaVrvSafReLAbLfQXc">> = iolist_to_binary(re:replace("xaabc","(?<=a{2})b","Vr\\1vSafReLA&\\1LfQX",[caseless])),
- <<"xaaVrvSafReLAbLfQXc">> = iolist_to_binary(re:replace("xaabc","(?<=a{2})b","Vr\\1vSafReLA&\\1LfQX",[caseless,
+ <<"pHaPSTCOlNb">> = iolist_to_binary(re:replace("ab","(?=(a))??.","pH&PSTC\\1OlN",[])),
+ <<"pHaPSTCOlNpHbPSTCOlN">> = iolist_to_binary(re:replace("ab","(?=(a))??.","pH&PSTC\\1OlN",[global])),
+ <<"jnEANc">> = iolist_to_binary(re:replace("bc","(?=(a))??.","j\\1nEA\\1N",[])),
+ <<"jnEANjnEAN">> = iolist_to_binary(re:replace("bc","(?=(a))??.","j\\1nEA\\1N",[global])),
+ <<"abdKPLVefHPcQ">> = iolist_to_binary(re:replace("abd","^(?=(?1))?[az]([abc])d","&KPLVefHPcQ",[])),
+ <<"abdKPLVefHPcQ">> = iolist_to_binary(re:replace("abd","^(?=(?1))?[az]([abc])d","&KPLVefHPcQ",[global])),
+ <<"kdvlzcdSEgEzcdiczcdrnUyHFzcdxx">> = iolist_to_binary(re:replace("zcdxx","^(?=(?1))?[az]([abc])d","kdvl&SEgE&i\\1&rnUyHF&",[])),
+ <<"kdvlzcdSEgEzcdiczcdrnUyHFzcdxx">> = iolist_to_binary(re:replace("zcdxx","^(?=(?1))?[az]([abc])d","kdvl&SEgE&i\\1&rnUyHF&",[global])),
+ <<"WusspaaaaaeVjGLaaaaanwQKJ">> = iolist_to_binary(re:replace("aaaaa","^(?!a){0}\\w+","Wussp\\1&eVjGL&nwQKJ",[])),
+ <<"WusspaaaaaeVjGLaaaaanwQKJ">> = iolist_to_binary(re:replace("aaaaa","^(?!a){0}\\w+","Wussp\\1&eVjGL&nwQKJ",[global])),
+ <<"abcKabcxyz">> = iolist_to_binary(re:replace("abcxyz","(?<=(abc))?xyz","K\\1&",[])),
+ <<"abcKabcxyz">> = iolist_to_binary(re:replace("abcxyz","(?<=(abc))?xyz","K\\1&",[global])),
+ <<"pqrFntxyzt">> = iolist_to_binary(re:replace("pqrxyz","(?<=(abc))?xyz","F\\1nt&t",[])),
+ <<"pqrFntxyzt">> = iolist_to_binary(re:replace("pqrxyz","(?<=(abc))?xyz","F\\1nt&t",[global])),
+ <<"ggg<<<aaa>>>OCbsBdbMyTuvtAF">> = iolist_to_binary(re:replace("ggg<<<aaa>>>","^[\\g<a>]+","\\1\\1&OCbsBdbM\\1yTuvtAF",[])),
+ <<"ggg<<<aaa>>>OCbsBdbMyTuvtAF">> = iolist_to_binary(re:replace("ggg<<<aaa>>>","^[\\g<a>]+","\\1\\1&OCbsBdbM\\1yTuvtAF",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\g<a>]+","emX&&&\\1S&&uUtF",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^[\\g<a>]+","emX&&&\\1S&&uUtF",[global])),
+ <<"\\ga">> = iolist_to_binary(re:replace("\\ga","^[\\g<a>]+","d&uwF&X",[])),
+ <<"\\ga">> = iolist_to_binary(re:replace("\\ga","^[\\g<a>]+","d&uwF&X",[global])),
+ <<"gggagagaaEPEjNmgggagagaxCdmimaxyz">> = iolist_to_binary(re:replace("gggagagaxyz","^[\\ga]+","&aEP\\1EjNm&xCdm\\1\\1ima",[])),
+ <<"gggagagaaEPEjNmgggagagaxCdmimaxyz">> = iolist_to_binary(re:replace("gggagagaxyz","^[\\ga]+","&aEP\\1EjNm&xCdm\\1\\1ima",[global])),
+ <<"LqguCZ">> = iolist_to_binary(re:replace("aaaa444:::Z","^[:a[:digit:]]+","LqguC",[])),
+ <<"LqguCZ">> = iolist_to_binary(re:replace("aaaa444:::Z","^[:a[:digit:]]+","LqguC",[global])),
+ <<"Yaaaa444:::bbbnaaaa444:::bbbOuZ">> = iolist_to_binary(re:replace("aaaa444:::bbbZ","^[:a[:digit:]:b]+","Y&n&Ou",[])),
+ <<"Yaaaa444:::bbbnaaaa444:::bbbOuZ">> = iolist_to_binary(re:replace("aaaa444:::bbbZ","^[:a[:digit:]:b]+","Y&n&Ou",[global])),
+ <<"n:xxx::xxx:H:xxx:u:xxx:EQfs">> = iolist_to_binary(re:replace(":xxx:","[:a]xxx[b:]","n&&H&\\1u&EQf\\1s",[])),
+ <<"n:xxx::xxx:H:xxx:u:xxx:EQfs">> = iolist_to_binary(re:replace(":xxx:","[:a]xxx[b:]","n&&H&\\1u&EQf\\1s",[global])),
+ <<"xaabErbtiYvhBJbTRc">> = iolist_to_binary(re:replace("xaabc","(?<=a{2})b","&Er&tiYv\\1hB\\1J&TR",[caseless])),
+ <<"xaabErbtiYvhBJbTRc">> = iolist_to_binary(re:replace("xaabc","(?<=a{2})b","&Er&tiYv\\1hB\\1J&TR",[caseless,
global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=a{2})b","fcR",[caseless])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=a{2})b","fcR",[caseless,
- global])),
- <<"xabc">> = iolist_to_binary(re:replace("xabc","(?<=a{2})b","BoRyoqeTXWscX",[caseless])),
- <<"xabc">> = iolist_to_binary(re:replace("xabc","(?<=a{2})b","BoRyoqeTXWscX",[caseless,
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=a{2})b","sIKbikA",[caseless])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=a{2})b","sIKbikA",[caseless,
global])),
- <<"xabc">> = iolist_to_binary(re:replace("xabc","(?<!a{2})b","&",[caseless])),
- <<"xabc">> = iolist_to_binary(re:replace("xabc","(?<!a{2})b","&",[caseless,
- global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<!a{2})b","\\1o\\1eK\\1cENK\\1&djd",[caseless])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<!a{2})b","\\1o\\1eK\\1cENK\\1&djd",[caseless,
- global])),
- <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<!a{2})b","&&o&KwHJm",[caseless])),
- <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<!a{2})b","&&o&KwHJm",[caseless,
+ <<"xabc">> = iolist_to_binary(re:replace("xabc","(?<=a{2})b","v\\1WGLw&Aj\\1&P&yFV\\1oME",[caseless])),
+ <<"xabc">> = iolist_to_binary(re:replace("xabc","(?<=a{2})b","v\\1WGLw&Aj\\1&P&yFV\\1oME",[caseless,
+ global])),
+ <<"xaOLJBdVsbrNnobNc">> = iolist_to_binary(re:replace("xabc","(?<!a{2})b","OL\\1\\1JBdVs&rNno\\1bN",[caseless])),
+ <<"xaOLJBdVsbrNnobNc">> = iolist_to_binary(re:replace("xabc","(?<!a{2})b","OL\\1\\1JBdVs&rNno\\1bN",[caseless,
+ global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<!a{2})b","b\\1U",[caseless])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<!a{2})b","b\\1U",[caseless,
global])),
- <<"xa ccEEJTcFn">> = iolist_to_binary(re:replace("xa c","(?<=a\\h)c","&&EEJ\\1T&F\\1n",[])),
- <<"xa ccEEJTcFn">> = iolist_to_binary(re:replace("xa c","(?<=a\\h)c","&&EEJ\\1T&F\\1n",[global])),
- <<"axxYHmPRLyCdYeBCTMFc">> = iolist_to_binary(re:replace("axxbc","(?<=[^a]{2})b","YHmPRLyCdYeBCTMF",[])),
- <<"axxYHmPRLyCdYeBCTMFc">> = iolist_to_binary(re:replace("axxbc","(?<=[^a]{2})b","YHmPRLyCdYeBCTMF",[global])),
- <<"aAAIbac">> = iolist_to_binary(re:replace("aAAbc","(?<=[^a]{2})b","I&a",[])),
- <<"aAAIbac">> = iolist_to_binary(re:replace("aAAbc","(?<=[^a]{2})b","I&a",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^a]{2})b","Qosgls",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^a]{2})b","Qosgls",[global])),
- <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<=[^a]{2})b","Iry\\1",[])),
- <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<=[^a]{2})b","Iry\\1",[global])),
- <<"axxbbc">> = iolist_to_binary(re:replace("axxbc","(?<=[^a]{2})b","&&",[caseless])),
- <<"axxbbc">> = iolist_to_binary(re:replace("axxbc","(?<=[^a]{2})b","&&",[caseless,
- global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^a]{2})b","oNddUdB\\1XA",[caseless])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^a]{2})b","oNddUdB\\1XA",[caseless,
- global])),
- <<"aAAbc">> = iolist_to_binary(re:replace("aAAbc","(?<=[^a]{2})b","boNOPUMfK&\\1",[caseless])),
- <<"aAAbc">> = iolist_to_binary(re:replace("aAAbc","(?<=[^a]{2})b","boNOPUMfK&\\1",[caseless,
- global])),
- <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<=[^a]{2})b","W&iffNoQ\\1",[caseless])),
- <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<=[^a]{2})b","W&iffNoQ\\1",[caseless,
- global])),
- <<"abKnqCjyP">> = iolist_to_binary(re:replace("abc","(?<=a\\H)c","KnqCjyP",[])),
- <<"abKnqCjyP">> = iolist_to_binary(re:replace("abc","(?<=a\\H)c","KnqCjyP",[global])),
- <<"abTxeCfVaOhSYo">> = iolist_to_binary(re:replace("abc","(?<=a\\V)c","TxeCfV\\1aOhSYo",[])),
- <<"abTxeCfVaOhSYo">> = iolist_to_binary(re:replace("abc","(?<=a\\V)c","TxeCfV\\1aOhSYo",[global])),
+ <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<!a{2})b","o",[caseless])),
+ <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<!a{2})b","o",[caseless,
+ global])),
+ <<"xa is">> = iolist_to_binary(re:replace("xa c","(?<=a\\h)c","is",[])),
+ <<"xa is">> = iolist_to_binary(re:replace("xa c","(?<=a\\h)c","is",[global])),
+ <<"axxDuvhoTEpKLbLbc">> = iolist_to_binary(re:replace("axxbc","(?<=[^a]{2})b","DuvhoTEpKLbL&",[])),
+ <<"axxDuvhoTEpKLbLbc">> = iolist_to_binary(re:replace("axxbc","(?<=[^a]{2})b","DuvhoTEpKLbL&",[global])),
+ <<"aAAxbbbGc">> = iolist_to_binary(re:replace("aAAbc","(?<=[^a]{2})b","\\1\\1x&\\1&&G",[])),
+ <<"aAAxbbbGc">> = iolist_to_binary(re:replace("aAAbc","(?<=[^a]{2})b","\\1\\1x&\\1&&G",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^a]{2})b","Nt&ll\\1w",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^a]{2})b","Nt&ll\\1w",[global])),
+ <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<=[^a]{2})b","R",[])),
+ <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<=[^a]{2})b","R",[global])),
+ <<"axxCbPYhXc">> = iolist_to_binary(re:replace("axxbc","(?<=[^a]{2})b","C&PYhX",[caseless])),
+ <<"axxCbPYhXc">> = iolist_to_binary(re:replace("axxbc","(?<=[^a]{2})b","C&PYhX",[caseless,
+ global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^a]{2})b","d\\1jkBrqR&X&Fc\\1vd",[caseless])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=[^a]{2})b","d\\1jkBrqR&X&Fc\\1vd",[caseless,
+ global])),
+ <<"aAAbc">> = iolist_to_binary(re:replace("aAAbc","(?<=[^a]{2})b","KNABa\\1\\1wON\\1S",[caseless])),
+ <<"aAAbc">> = iolist_to_binary(re:replace("aAAbc","(?<=[^a]{2})b","KNABa\\1\\1wON\\1S",[caseless,
+ global])),
+ <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<=[^a]{2})b","CQ&DXxjEdVkGvk\\1",[caseless])),
+ <<"xaabc">> = iolist_to_binary(re:replace("xaabc","(?<=[^a]{2})b","CQ&DXxjEdVkGvk\\1",[caseless,
+ global])),
+ <<"abcdTXqBlsLHncSPA">> = iolist_to_binary(re:replace("abc","(?<=a\\H)c","&dTXqBlsLH\\1n&SPA\\1",[])),
+ <<"abcdTXqBlsLHncSPA">> = iolist_to_binary(re:replace("abc","(?<=a\\H)c","&dTXqBlsLH\\1n&SPA\\1",[global])),
+ <<"abjV">> = iolist_to_binary(re:replace("abc","(?<=a\\V)c","jV",[])),
+ <<"abjV">> = iolist_to_binary(re:replace("abc","(?<=a\\V)c","jV",[global])),
<<"a
-gxsYrXgNx">> = iolist_to_binary(re:replace("a
-c","(?<=a\\v)c","g\\1\\1xs\\1Yr\\1XgN\\1x",[])),
+oscmdgX">> = iolist_to_binary(re:replace("a
+c","(?<=a\\v)c","os&mdgX",[])),
<<"a
-gxsYrXgNx">> = iolist_to_binary(re:replace("a
-c","(?<=a\\v)c","g\\1\\1xs\\1Yr\\1XgN\\1x",[global])),
- <<"XcccddYLX">> = iolist_to_binary(re:replace("XcccddYX","(?(?=c)c|d)++Y","&L",[])),
- <<"XcccddYLX">> = iolist_to_binary(re:replace("XcccddYX","(?(?=c)c|d)++Y","&L",[global])),
- <<"XjcccddYxcccddYymX">> = iolist_to_binary(re:replace("XcccddYX","(?(?=c)c|d)*+Y","j&x\\1&\\1\\1ym",[])),
- <<"XjcccddYxcccddYymX">> = iolist_to_binary(re:replace("XcccddYX","(?(?=c)c|d)*+Y","j&x\\1&\\1\\1ym",[global])),
+oscmdgX">> = iolist_to_binary(re:replace("a
+c","(?<=a\\v)c","os&mdgX",[global])),
+ <<"XYpwLicvrdWdBXRX">> = iolist_to_binary(re:replace("XcccddYX","(?(?=c)c|d)++Y","YpwL\\1icvrdWdBXR",[])),
+ <<"XYpwLicvrdWdBXRX">> = iolist_to_binary(re:replace("XcccddYX","(?(?=c)c|d)++Y","YpwL\\1icvrdWdBXR",[global])),
+ <<"XialhPX">> = iolist_to_binary(re:replace("XcccddYX","(?(?=c)c|d)*+Y","ia\\1lhP\\1",[])),
+ <<"XialhPX">> = iolist_to_binary(re:replace("XcccddYX","(?(?=c)c|d)*+Y","ia\\1lhP\\1",[global])),
+ <<"aaaaaaaBYHaBaaaaaaaaaajJ">> = iolist_to_binary(re:replace("aaaaaaa","^(a{2,3}){2,}+a","&BYHaB\\1&jJ",[])),
+ <<"aaaaaaaBYHaBaaaaaaaaaajJ">> = iolist_to_binary(re:replace("aaaaaaa","^(a{2,3}){2,}+a","&BYHaB\\1&jJ",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3}){2,}+a","BVB",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3}){2,}+a","BVB",[global])),
+ <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3}){2,}+a","&cSk&xmMuHJpt\\1&VoP",[])),
+ <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3}){2,}+a","&cSk&xmMuHJpt\\1&VoP",[global])),
+ <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a{2,3}){2,}+a","c",[])),
+ <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a{2,3}){2,}+a","c",[global])),
ok.
run40() ->
- <<"P">> = iolist_to_binary(re:replace("aaaaaaa","^(a{2,3}){2,}+a","P",[])),
- <<"P">> = iolist_to_binary(re:replace("aaaaaaa","^(a{2,3}){2,}+a","P",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3}){2,}+a","&AJ",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3}){2,}+a","&AJ",[global])),
- <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3}){2,}+a","bT&aphetNw&xcisR",[])),
- <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3}){2,}+a","bT&aphetNw&xcisR",[global])),
- <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a{2,3}){2,}+a","g",[])),
- <<"aaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaa","^(a{2,3}){2,}+a","g",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3})++a","U",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3})++a","U",[global])),
- <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3})++a","CjQf&BIE\\1m&vHKyV",[])),
- <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3})++a","CjQf&BIE\\1m&vHKyV",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3})*+a","jEe&kL&\\1Wd",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3})*+a","jEe&kL&\\1Wd",[global])),
- <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3})*+a","&VFXL\\1JOa\\1dHl&Yw",[])),
- <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3})*+a","&VFXL\\1JOa\\1dHl&Yw",[global])),
- <<"fByANGarQU">> = iolist_to_binary(re:replace("abXde","ab\\Cde","\\1fByANGarQ\\1U",[])),
- <<"fByANGarQU">> = iolist_to_binary(re:replace("abXde","ab\\Cde","\\1fByANGarQ\\1U",[global])),
- <<"abZdeXdDJIltBeDyobKXo">> = iolist_to_binary(re:replace("abZdeX","(?<=ab\\Cde)X","&dDJIltBeDyobK&o",[])),
- <<"abZdeXdDJIltBeDyobKXo">> = iolist_to_binary(re:replace("abZdeX","(?<=ab\\Cde)X","&dDJIltBeDyobK&o",[global])),
- <<"hv">> = iolist_to_binary(re:replace("aCb","a[\\CD]b","h\\1v",[])),
- <<"hv">> = iolist_to_binary(re:replace("aCb","a[\\CD]b","h\\1v",[global])),
- <<"waDbEkr">> = iolist_to_binary(re:replace("aDb","a[\\CD]b","w&Ekr",[])),
- <<"waDbEkr">> = iolist_to_binary(re:replace("aDb","a[\\CD]b","w&Ekr",[global])),
- <<"RCcE">> = iolist_to_binary(re:replace("aJb","a[\\C-X]b","R\\1CcE",[])),
- <<"RCcE">> = iolist_to_binary(re:replace("aJb","a[\\C-X]b","R\\1CcE",[global])),
- <<"X X">> = iolist_to_binary(re:replace("X X","\\H\\h\\V\\v","B&pquMp\\1NBcoPfQTdr\\1o",[])),
- <<"X X">> = iolist_to_binary(re:replace("X X","\\H\\h\\V\\v","B&pquMp\\1NBcoPfQTdr\\1o",[global])),
- <<"bjVX X X X OAvV">> = iolist_to_binary(re:replace("X X ","\\H\\h\\V\\v","bjV&&OAv\\1V",[])),
- <<"bjVX X X X OAvV">> = iolist_to_binary(re:replace("X X ","\\H\\h\\V\\v","bjV&&OAv\\1V",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\H\\h\\V\\v","Y",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\H\\h\\V\\v","Y",[global])),
- <<"  X">> = iolist_to_binary(re:replace("  X","\\H\\h\\V\\v","VrvLpiABSBWYG",[])),
- <<"  X">> = iolist_to_binary(re:replace("  X","\\H\\h\\V\\v","VrvLpiABSBWYG",[global])),
- <<"UibLPUMxnHgluPEcwP">> = iolist_to_binary(re:replace("  X
- ","\\H*\\h+\\V?\\v{3,4}","Ui\\1bLPUMxnHgluPEcwP",[])),
- <<"UibLPUMxnHgluPEcwP">> = iolist_to_binary(re:replace("  X
- ","\\H*\\h+\\V?\\v{3,4}","Ui\\1bLPUMxnHgluPEcwP",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3})++a","GeKmc\\1WhXfk\\1TBYDb&Ca",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3})++a","GeKmc\\1WhXfk\\1TBYDb&Ca",[global])),
+ <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3})++a","MMBt&lb\\1&jbxk",[])),
+ <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3})++a","MMBt&lb\\1&jbxk",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3})*+a","pwt&tvQ&X\\1uUUqymOuO",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a{2,3})*+a","pwt&tvQ&X\\1uUUqymOuO",[global])),
+ <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3})*+a","\\1",[])),
+ <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(a{2,3})*+a","\\1",[global])),
+ <<"ODb">> = iolist_to_binary(re:replace("abXde","ab\\Cde","ODb",[])),
+ <<"ODb">> = iolist_to_binary(re:replace("abXde","ab\\Cde","ODb",[global])),
+ <<"abZdeOUSVkwkXixHSXuXh">> = iolist_to_binary(re:replace("abZdeX","(?<=ab\\Cde)X","OUSVkw\\1k&ixHS\\1&u\\1&h",[])),
+ <<"abZdeOUSVkwkXixHSXuXh">> = iolist_to_binary(re:replace("abZdeX","(?<=ab\\Cde)X","OUSVkw\\1k&ixHS\\1&u\\1&h",[global])),
+ <<"wcl">> = iolist_to_binary(re:replace("aCb","a[\\CD]b","wcl",[])),
+ <<"wcl">> = iolist_to_binary(re:replace("aCb","a[\\CD]b","wcl",[global])),
+ <<"R">> = iolist_to_binary(re:replace("aDb","a[\\CD]b","R",[])),
+ <<"R">> = iolist_to_binary(re:replace("aDb","a[\\CD]b","R",[global])),
+ <<"aJbUeGhRaJb">> = iolist_to_binary(re:replace("aJb","a[\\C-X]b","&UeGhR&",[])),
+ <<"aJbUeGhRaJb">> = iolist_to_binary(re:replace("aJb","a[\\C-X]b","&UeGhR&",[global])),
+ <<"X X">> = iolist_to_binary(re:replace("X X","\\H\\h\\V\\v","&e&aKbUC&nHH\\1qy\\1",[])),
+ <<"X X">> = iolist_to_binary(re:replace("X X","\\H\\h\\V\\v","&e&aKbUC&nHH\\1qy\\1",[global])),
+ <<"JqKpfdXTX X MbyX X X X ">> = iolist_to_binary(re:replace("X X ","\\H\\h\\V\\v","JqKpfdXT&Mby&\\1&",[])),
+ <<"JqKpfdXTX X MbyX X X X ">> = iolist_to_binary(re:replace("X X ","\\H\\h\\V\\v","JqKpfdXT&Mby&\\1&",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\H\\h\\V\\v","FAmVe\\1O",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\H\\h\\V\\v","FAmVe\\1O",[global])),
+ <<"  X">> = iolist_to_binary(re:replace("  X","\\H\\h\\V\\v","\\1mSDSJp",[])),
+ <<"  X">> = iolist_to_binary(re:replace("  X","\\H\\h\\V\\v","\\1mSDSJp",[global])),
+ <<"JagFUGCxoJ  X
+ SMGCK">> = iolist_to_binary(re:replace("  X
+ ","\\H*\\h+\\V?\\v{3,4}","JagFUGCxoJ&\\1SMGCK",[])),
+ <<"JagFUGCxoJ  X
+ SMGCK">> = iolist_to_binary(re:replace("  X
+ ","\\H*\\h+\\V?\\v{3,4}","JagFUGCxoJ&\\1SMGCK",[global])),
+ <<"  
+ an  
+ uIjsv">> = iolist_to_binary(re:replace("  
+ ","\\H*\\h+\\V?\\v{3,4}","&an&\\1uIjsv\\1",[])),
<<"  
-  
- YOgvhC">> = iolist_to_binary(re:replace("  
- ","\\H*\\h+\\V?\\v{3,4}","&&YOgvhC\\1\\1",[])),
+ an  
+ uIjsv">> = iolist_to_binary(re:replace("  
+ ","\\H*\\h+\\V?\\v{3,4}","&an&\\1uIjsv\\1",[global])),
<<"  
-  
- YOgvhC">> = iolist_to_binary(re:replace("  
- ","\\H*\\h+\\V?\\v{3,4}","&&YOgvhC\\1\\1",[global])),
- <<"o  
- aixbY  
- BtbY">> = iolist_to_binary(re:replace("  
- ","\\H*\\h+\\V?\\v{3,4}","o&aixbY&BtbY\\1",[])),
- <<"o  
- aixbY  
- BtbY">> = iolist_to_binary(re:replace("  
- ","\\H*\\h+\\V?\\v{3,4}","o&aixbY&BtbY\\1",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\H*\\h+\\V?\\v{3,4}","orCME\\1H",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\H*\\h+\\V?\\v{3,4}","orCME\\1H",[global])),
+ Cnyt  
+ sJWoCUIsrr">> = iolist_to_binary(re:replace("  
+ ","\\H*\\h+\\V?\\v{3,4}","&C\\1nyt\\1\\1&\\1sJWoCUIsrr",[])),
+ <<"  
+ Cnyt  
+ sJWoCUIsrr">> = iolist_to_binary(re:replace("  
+ ","\\H*\\h+\\V?\\v{3,4}","&C\\1nyt\\1\\1&\\1sJWoCUIsrr",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\H*\\h+\\V?\\v{3,4}","heJfENVeR\\1TJ\\1&&Dvf",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\H*\\h+\\V?\\v{3,4}","heJfENVeR\\1TJ\\1&&Dvf",[global])),
<<"  
">> = iolist_to_binary(re:replace("  
- ","\\H*\\h+\\V?\\v{3,4}","h&L\\1\\1wk\\1",[])),
+ ","\\H*\\h+\\V?\\v{3,4}","g&",[])),
<<"  
">> = iolist_to_binary(re:replace("  
- ","\\H*\\h+\\V?\\v{3,4}","h&L\\1\\1wk\\1",[global])),
- <<"XY aeVjRE">> = iolist_to_binary(re:replace("XY ABCDE","\\H{3,4}","aeVjR",[])),
- <<"XY aeVjRE">> = iolist_to_binary(re:replace("XY ABCDE","\\H{3,4}","aeVjR",[global])),
- <<"XY inwBHwGPQRKvfoDb ST">> = iolist_to_binary(re:replace("XY PQR ST","\\H{3,4}","in\\1wBHw\\1G&KvfoDb\\1",[])),
- <<"XY inwBHwGPQRKvfoDb ST">> = iolist_to_binary(re:replace("XY PQR ST","\\H{3,4}","in\\1wBHw\\1G&KvfoDb\\1",[global])),
- <<"XY AcCVYFB PYkLB PHB PFIQRB PBeQRS">> = iolist_to_binary(re:replace("XY AB PQRS",".\\h{3,4}.","\\1cCVYF&YkL&H&FIQR&Be",[])),
- <<"XY AcCVYFB PYkLB PHB PFIQRB PBeQRS">> = iolist_to_binary(re:replace("XY AB PQRS",".\\h{3,4}.","\\1cCVYF&YkL&H&FIQR&Be",[global])),
- <<">XNNNYZEbXNNNYZXNNNYZQsKnuk">> = iolist_to_binary(re:replace(">XNNNYZ","\\h*X\\h?\\H+Y\\H?Z","&E\\1b&&QsKnuk",[])),
- <<">XNNNYZEbXNNNYZXNNNYZQsKnuk">> = iolist_to_binary(re:replace(">XNNNYZ","\\h*X\\h?\\H+Y\\H?Z","&E\\1b&&QsKnuk",[global])),
- <<">m">> = iolist_to_binary(re:replace("> X NYQZ","\\h*X\\h?\\H+Y\\H?Z","m",[])),
- <<">m">> = iolist_to_binary(re:replace("> X NYQZ","\\h*X\\h?\\H+Y\\H?Z","m",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\h*X\\h?\\H+Y\\H?Z","W\\1BBQbt&HF\\1KkXwm\\1Vdn",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\h*X\\h?\\H+Y\\H?Z","W\\1BBQbt&HF\\1KkXwm\\1Vdn",[global])),
- <<">XYZ">> = iolist_to_binary(re:replace(">XYZ","\\h*X\\h?\\H+Y\\H?Z","&GW",[])),
- <<">XYZ">> = iolist_to_binary(re:replace(">XYZ","\\h*X\\h?\\H+Y\\H?Z","&GW",[global])),
- <<"> X NY Z">> = iolist_to_binary(re:replace("> X NY Z","\\h*X\\h?\\H+Y\\H?Z","JIYAqmdtuCSO",[])),
- <<"> X NY Z">> = iolist_to_binary(re:replace("> X NY Z","\\h*X\\h?\\H+Y\\H?Z","JIYAqmdtuCSO",[global])),
- <<">vctAlOgcGXY
+ ","\\H*\\h+\\V?\\v{3,4}","g&",[global])),
+ <<"XY bvHE">> = iolist_to_binary(re:replace("XY ABCDE","\\H{3,4}","bvH",[])),
+ <<"XY bvHE">> = iolist_to_binary(re:replace("XY ABCDE","\\H{3,4}","bvH",[global])),
+ <<"XY PQRGrQwU ST">> = iolist_to_binary(re:replace("XY PQR ST","\\H{3,4}","&GrQw\\1U",[])),
+ <<"XY PQRGrQwU ST">> = iolist_to_binary(re:replace("XY PQR ST","\\H{3,4}","&GrQw\\1U",[global])),
+ <<"XY AxeQRS">> = iolist_to_binary(re:replace("XY AB PQRS",".\\h{3,4}.","xe",[])),
+ <<"XY AxeQRS">> = iolist_to_binary(re:replace("XY AB PQRS",".\\h{3,4}.","xe",[global])),
+ <<">PvFpXNNNYZpueukCvxXNNNYZUJ">> = iolist_to_binary(re:replace(">XNNNYZ","\\h*X\\h?\\H+Y\\H?Z","PvFp&pueukCv\\1\\1\\1x&UJ",[])),
+ <<">PvFpXNNNYZpueukCvxXNNNYZUJ">> = iolist_to_binary(re:replace(">XNNNYZ","\\h*X\\h?\\H+Y\\H?Z","PvFp&pueukCv\\1\\1\\1x&UJ",[global])),
+ <<">enigqoQeBUc X NYQZFyFLjg">> = iolist_to_binary(re:replace("> X NYQZ","\\h*X\\h?\\H+Y\\H?Z","\\1enigqo\\1QeBUc&FyFLjg",[])),
+ <<">enigqoQeBUc X NYQZFyFLjg">> = iolist_to_binary(re:replace("> X NYQZ","\\h*X\\h?\\H+Y\\H?Z","\\1enigqo\\1QeBUc&FyFLjg",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\h*X\\h?\\H+Y\\H?Z","X",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\h*X\\h?\\H+Y\\H?Z","X",[global])),
+ <<">XYZ">> = iolist_to_binary(re:replace(">XYZ","\\h*X\\h?\\H+Y\\H?Z","CSYvJMwNrX\\1",[])),
+ <<">XYZ">> = iolist_to_binary(re:replace(">XYZ","\\h*X\\h?\\H+Y\\H?Z","CSYvJMwNrX\\1",[global])),
+ <<"> X NY Z">> = iolist_to_binary(re:replace("> X NY Z","\\h*X\\h?\\H+Y\\H?Z","WVcuLyAOpQ&",[])),
+ <<"> X NY Z">> = iolist_to_binary(re:replace("> X NY Z","\\h*X\\h?\\H+Y\\H?Z","WVcuLyAOpQ&",[global])),
+ <<">EXY
Z
-A NN h">> = iolist_to_binary(re:replace(">XY
+A NN PIMXY
Z
-A NN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c","vc\\1tAl\\1O\\1gcG&h\\1",[])),
- <<">vctAlOgcGXY
+A NN Evk">> = iolist_to_binary(re:replace(">XY
Z
-A NN h">> = iolist_to_binary(re:replace(">XY
+A NN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c","E&PIM\\1&E\\1vk",[])),
+ <<">EXY
Z
-A NN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c","vc\\1tAl\\1O\\1gcG&h\\1",[global])),
- <<">bm
- X
-Y
- ZZZ
-AAA NNN uAMN">> = iolist_to_binary(re:replace(">
- X
-Y
- ZZZ
-AAA NNN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c","bm&\\1uAMN",[])),
- <<">bm
+A NN PIMXY
+Z
+A NN Evk">> = iolist_to_binary(re:replace(">XY
+Z
+A NN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c","E&PIM\\1&E\\1vk",[global])),
+ <<">ux">> = iolist_to_binary(re:replace(">
X
Y
ZZZ
-AAA NNN uAMN">> = iolist_to_binary(re:replace(">
+AAA NNN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c","\\1ux",[])),
+ <<">ux">> = iolist_to_binary(re:replace(">
X
Y
ZZZ
-AAA NNN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c","bm&\\1uAMN",[global])),
- <<"foojypfoojma">> = iolist_to_binary(re:replace("foobar","(foo)\\Kbar","jyp\\1jma",[])),
- <<"foojypfoojma">> = iolist_to_binary(re:replace("foobar","(foo)\\Kbar","jyp\\1jma",[global])),
- <<"fooUcOiqwyxvfoobar">> = iolist_to_binary(re:replace("foobar","(foo)(\\Kbar|baz)","UcOiqwyxv\\1&",[])),
- <<"fooUcOiqwyxvfoobar">> = iolist_to_binary(re:replace("foobar","(foo)(\\Kbar|baz)","UcOiqwyxv\\1&",[global])),
- <<"xXfoobazTfoobazneSQcxWfooBA">> = iolist_to_binary(re:replace("foobaz","(foo)(\\Kbar|baz)","xX&T&neSQcxW\\1BA",[])),
- <<"xXfoobazTfoobazneSQcxWfooBA">> = iolist_to_binary(re:replace("foobaz","(foo)(\\Kbar|baz)","xX&T&neSQcxW\\1BA",[global])),
- <<"foovYnKbarbazVqfoobarheyiy">> = iolist_to_binary(re:replace("foobarbaz","(foo\\Kbar)baz","vYnK&Vq\\1heyiy",[])),
- <<"foovYnKbarbazVqfoobarheyiy">> = iolist_to_binary(re:replace("foobarbaz","(foo\\Kbar)baz","vYnK&Vq\\1heyiy",[global])),
- <<"wYDabPababababbbabZygQUbMBoQiXXXX">> = iolist_to_binary(re:replace("ababababbbabZXXXX","^(a(b))\\1\\g1\\g{1}\\g-1\\g{-1}\\g{-02}Z","wYD\\1P&ygQUbMBoQi",[])),
- <<"wYDabPababababbbabZygQUbMBoQiXXXX">> = iolist_to_binary(re:replace("ababababbbabZXXXX","^(a(b))\\1\\g1\\g{1}\\g-1\\g{-1}\\g{-02}Z","wYD\\1P&ygQUbMBoQi",[global])),
- <<"QJyUVPxY">> = iolist_to_binary(re:replace("tom-tom","(?<A>tom|bon)-\\g{A}","QJyUVPxY",[])),
- <<"QJyUVPxY">> = iolist_to_binary(re:replace("tom-tom","(?<A>tom|bon)-\\g{A}","QJyUVPxY",[global])),
- <<"bonvRbon-bonECJDijVbonbon-bonnbonYtaYv">> = iolist_to_binary(re:replace("bon-bon","(?<A>tom|bon)-\\g{A}","\\1vR&ECJDijV\\1&n\\1YtaYv",[])),
- <<"bonvRbon-bonECJDijVbonbon-bonnbonYtaYv">> = iolist_to_binary(re:replace("bon-bon","(?<A>tom|bon)-\\g{A}","\\1vR&ECJDijV\\1&n\\1YtaYv",[global])),
- <<"bacxxx">> = iolist_to_binary(re:replace("bacxxx","(^(a|b\\g{-1}))","B",[])),
- <<"bacxxx">> = iolist_to_binary(re:replace("bacxxx","(^(a|b\\g{-1}))","B",[global])),
- <<"abcHN">> = iolist_to_binary(re:replace("abcabc","(?|(abc)|(xyz))\\1","\\1HN",[])),
- <<"abcHN">> = iolist_to_binary(re:replace("abcabc","(?|(abc)|(xyz))\\1","\\1HN",[global])),
- <<"i">> = iolist_to_binary(re:replace("xyzxyz","(?|(abc)|(xyz))\\1","i",[])),
- <<"i">> = iolist_to_binary(re:replace("xyzxyz","(?|(abc)|(xyz))\\1","i",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?|(abc)|(xyz))\\1","&RDdXS\\1",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?|(abc)|(xyz))\\1","&RDdXS\\1",[global])),
- <<"abcxyz">> = iolist_to_binary(re:replace("abcxyz","(?|(abc)|(xyz))\\1","xvrTYMBEX",[])),
- <<"abcxyz">> = iolist_to_binary(re:replace("abcxyz","(?|(abc)|(xyz))\\1","xvrTYMBEX",[global])),
- <<"xyzabc">> = iolist_to_binary(re:replace("xyzabc","(?|(abc)|(xyz))\\1","gkljK\\1CR\\1BykWHcqqC&G",[])),
- <<"xyzabc">> = iolist_to_binary(re:replace("xyzabc","(?|(abc)|(xyz))\\1","gkljK\\1CR\\1BykWHcqqC&G",[global])),
+AAA NNN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c","\\1ux",[global])),
+ <<"fooIlI">> = iolist_to_binary(re:replace("foobar","(foo)\\Kbar","IlI",[])),
+ <<"fooIlI">> = iolist_to_binary(re:replace("foobar","(foo)\\Kbar","IlI",[global])),
+ <<"fooMAfoowltkWfEDP">> = iolist_to_binary(re:replace("foobar","(foo)(\\Kbar|baz)","MA\\1wltkWfEDP",[])),
+ <<"fooMAfoowltkWfEDP">> = iolist_to_binary(re:replace("foobar","(foo)(\\Kbar|baz)","MA\\1wltkWfEDP",[global])),
+ <<"foobazhoMQ">> = iolist_to_binary(re:replace("foobaz","(foo)(\\Kbar|baz)","&hoMQ",[])),
+ <<"foobazhoMQ">> = iolist_to_binary(re:replace("foobaz","(foo)(\\Kbar|baz)","&hoMQ",[global])),
+ <<"fooenlbarbazfoobarOskJvtabarbazfoobarePBU">> = iolist_to_binary(re:replace("foobarbaz","(foo\\Kbar)baz","enl&\\1OskJvta&\\1ePBU",[])),
+ <<"fooenlbarbazfoobarOskJvtabarbazfoobarePBU">> = iolist_to_binary(re:replace("foobarbaz","(foo\\Kbar)baz","enl&\\1OskJvta&\\1ePBU",[global])),
+ <<"BDWEtomstom-tomtom-tom">> = iolist_to_binary(re:replace("tom-tom","(?<A>tom|bon)-\\g{A}","BDWE\\1s&&",[])),
+ <<"BDWEtomstom-tomtom-tom">> = iolist_to_binary(re:replace("tom-tom","(?<A>tom|bon)-\\g{A}","BDWE\\1s&&",[global])),
+ <<"wjbonFbon-bon">> = iolist_to_binary(re:replace("bon-bon","(?<A>tom|bon)-\\g{A}","wj\\1F&",[])),
+ <<"wjbonFbon-bon">> = iolist_to_binary(re:replace("bon-bon","(?<A>tom|bon)-\\g{A}","wj\\1F&",[global])),
+ <<"bacxxx">> = iolist_to_binary(re:replace("bacxxx","(^(a|b\\g{-1}))","Sx",[])),
+ <<"bacxxx">> = iolist_to_binary(re:replace("bacxxx","(^(a|b\\g{-1}))","Sx",[global])),
+ <<"H">> = iolist_to_binary(re:replace("abcabc","(?|(abc)|(xyz))\\1","H",[])),
+ <<"H">> = iolist_to_binary(re:replace("abcabc","(?|(abc)|(xyz))\\1","H",[global])),
+ <<"yxyzWcxyzxyzduabfPinElhSxyzxyzxyzxyz">> = iolist_to_binary(re:replace("xyzxyz","(?|(abc)|(xyz))\\1","y\\1Wc&duabfPinElhS&&",[])),
+ <<"yxyzWcxyzxyzduabfPinElhSxyzxyzxyzxyz">> = iolist_to_binary(re:replace("xyzxyz","(?|(abc)|(xyz))\\1","y\\1Wc&duabfPinElhS&&",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?|(abc)|(xyz))\\1","b\\1&layoQ",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?|(abc)|(xyz))\\1","b\\1&layoQ",[global])),
+ <<"abcxyz">> = iolist_to_binary(re:replace("abcxyz","(?|(abc)|(xyz))\\1","pF",[])),
+ <<"abcxyz">> = iolist_to_binary(re:replace("abcxyz","(?|(abc)|(xyz))\\1","pF",[global])),
+ <<"xyzabc">> = iolist_to_binary(re:replace("xyzabc","(?|(abc)|(xyz))\\1","GblOAJxEl",[])),
+ <<"xyzabc">> = iolist_to_binary(re:replace("xyzabc","(?|(abc)|(xyz))\\1","GblOAJxEl",[global])),
+ <<"wDMUaJIhLW">> = iolist_to_binary(re:replace("abcabc","(?|(abc)|(xyz))(?1)","wDMUaJIhLW",[])),
+ <<"wDMUaJIhLW">> = iolist_to_binary(re:replace("abcabc","(?|(abc)|(xyz))(?1)","wDMUaJIhLW",[global])),
+ <<"uhDuxyzJEuDDxyzabcJKaxyzabcvdX">> = iolist_to_binary(re:replace("xyzabc","(?|(abc)|(xyz))(?1)","uhDu\\1JEuDD&JKa&vdX",[])),
+ <<"uhDuxyzJEuDDxyzabcJKaxyzabcvdX">> = iolist_to_binary(re:replace("xyzabc","(?|(abc)|(xyz))(?1)","uhDu\\1JEuDD&JKa&vdX",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?|(abc)|(xyz))(?1)","oUFI&utTyJ",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?|(abc)|(xyz))(?1)","oUFI&utTyJ",[global])),
+ <<"xyzxyz">> = iolist_to_binary(re:replace("xyzxyz","(?|(abc)|(xyz))(?1)","ib\\1&erlkw&wuHdHNtS",[])),
+ <<"xyzxyz">> = iolist_to_binary(re:replace("xyzxyz","(?|(abc)|(xyz))(?1)","ib\\1&erlkw&wuHdHNtS",[global])),
ok.
run41() ->
- <<"EaIdWBoabck">> = iolist_to_binary(re:replace("abcabc","(?|(abc)|(xyz))(?1)","EaIdWBo\\1k",[])),
- <<"EaIdWBoabck">> = iolist_to_binary(re:replace("abcabc","(?|(abc)|(xyz))(?1)","EaIdWBo\\1k",[global])),
- <<"xyzabcxyzxyzMvxyzjgRaou">> = iolist_to_binary(re:replace("xyzabc","(?|(abc)|(xyz))(?1)","&\\1\\1Mv\\1jgRaou",[])),
- <<"xyzabcxyzxyzMvxyzjgRaou">> = iolist_to_binary(re:replace("xyzabc","(?|(abc)|(xyz))(?1)","&\\1\\1Mv\\1jgRaou",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?|(abc)|(xyz))(?1)","&vqt\\1Hv",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?|(abc)|(xyz))(?1)","&vqt\\1Hv",[global])),
- <<"xyzxyz">> = iolist_to_binary(re:replace("xyzxyz","(?|(abc)|(xyz))(?1)","LyN",[])),
- <<"xyzxyz">> = iolist_to_binary(re:replace("xyzxyz","(?|(abc)|(xyz))(?1)","LyN",[global])),
- <<"XYabcdYvXYabcdYXYabcdYXYabcdYjw">> = iolist_to_binary(re:replace("XYabcdY","^X(?5)(a)(?|(b)|(q))(c)(d)(Y)","&v&&&jw",[])),
- <<"XYabcdYvXYabcdYXYabcdYXYabcdYjw">> = iolist_to_binary(re:replace("XYabcdY","^X(?5)(a)(?|(b)|(q))(c)(d)(Y)","&v&&&jw",[global])),
- <<"uqndDBXYabcdYGahfmNcwsERUk">> = iolist_to_binary(re:replace("XYabcdY","^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)","uqndDB&G\\1hfmNcwsERUk",[])),
- <<"uqndDBXYabcdYGahfmNcwsERUk">> = iolist_to_binary(re:replace("XYabcdY","^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)","uqndDB&G\\1hfmNcwsERUk",[global])),
- <<"XYabcdYtahaNIsaeGvkDDLOQ">> = iolist_to_binary(re:replace("XYabcdY","^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)","&tah\\1NIs\\1eGvkDDLOQ",[])),
- <<"XYabcdYtahaNIsaeGvkDDLOQ">> = iolist_to_binary(re:replace("XYabcdY","^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)","&tah\\1NIs\\1eGvkDDLOQ",[global])),
- <<"boxyz">> = iolist_to_binary(re:replace("a:aaxyz","(?'abc'\\w+):\\k<abc>{2}","bo",[])),
- <<"boxyz">> = iolist_to_binary(re:replace("a:aaxyz","(?'abc'\\w+):\\k<abc>{2}","bo",[global])),
- <<"sqNrwMWMcRUxyz">> = iolist_to_binary(re:replace("ab:ababxyz","(?'abc'\\w+):\\k<abc>{2}","sqNrwMWMcRU",[])),
- <<"sqNrwMWMcRUxyz">> = iolist_to_binary(re:replace("ab:ababxyz","(?'abc'\\w+):\\k<abc>{2}","sqNrwMWMcRU",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?'abc'\\w+):\\k<abc>{2}","Ahbk",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?'abc'\\w+):\\k<abc>{2}","Ahbk",[global])),
- <<"a:axyz">> = iolist_to_binary(re:replace("a:axyz","(?'abc'\\w+):\\k<abc>{2}","yr&SM&HjpyRb",[])),
- <<"a:axyz">> = iolist_to_binary(re:replace("a:axyz","(?'abc'\\w+):\\k<abc>{2}","yr&SM&HjpyRb",[global])),
- <<"ab:abxyz">> = iolist_to_binary(re:replace("ab:abxyz","(?'abc'\\w+):\\k<abc>{2}","BQwV",[])),
- <<"ab:abxyz">> = iolist_to_binary(re:replace("ab:abxyz","(?'abc'\\w+):\\k<abc>{2}","BQwV",[global])),
- <<"a:aaxnnUMItwyNa:aamCRBaixyz">> = iolist_to_binary(re:replace("a:aaxyz","(?'abc'\\w+):\\g{abc}{2}","&xnnUMItwyN&mCRB\\1i",[])),
- <<"a:aaxnnUMItwyNa:aamCRBaixyz">> = iolist_to_binary(re:replace("a:aaxyz","(?'abc'\\w+):\\g{abc}{2}","&xnnUMItwyN&mCRB\\1i",[global])),
- <<"Labjab:ababqxyz">> = iolist_to_binary(re:replace("ab:ababxyz","(?'abc'\\w+):\\g{abc}{2}","L\\1j&q",[])),
- <<"Labjab:ababqxyz">> = iolist_to_binary(re:replace("ab:ababxyz","(?'abc'\\w+):\\g{abc}{2}","L\\1j&q",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?'abc'\\w+):\\g{abc}{2}","dLG\\1",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?'abc'\\w+):\\g{abc}{2}","dLG\\1",[global])),
- <<"a:axyz">> = iolist_to_binary(re:replace("a:axyz","(?'abc'\\w+):\\g{abc}{2}","MKB",[])),
- <<"a:axyz">> = iolist_to_binary(re:replace("a:axyz","(?'abc'\\w+):\\g{abc}{2}","MKB",[global])),
- <<"ab:abxyz">> = iolist_to_binary(re:replace("ab:abxyz","(?'abc'\\w+):\\g{abc}{2}","BwHek&EFhbw",[])),
- <<"ab:abxyz">> = iolist_to_binary(re:replace("ab:abxyz","(?'abc'\\w+):\\g{abc}{2}","BwHek&EFhbw",[global])),
- <<"abdqUabdFaabdtmIkaf">> = iolist_to_binary(re:replace("abd","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)","&qU&Fa&tmIk\\1f",[extended])),
- <<"abdqUabdFaabdtmIkaf">> = iolist_to_binary(re:replace("abd","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)","&qU&Fa&tmIk\\1f",[extended,
- global])),
- <<"haacettwdUtIv">> = iolist_to_binary(re:replace("ce","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)","haa&ttwdU\\1tIv",[extended])),
- <<"haacettwdUtIv">> = iolist_to_binary(re:replace("ce","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)","haa&ttwdU\\1tIv",[extended,
- global])),
- <<"uaXaXZYWULYgJXaXaXaXZg">> = iolist_to_binary(re:replace("aXaXZ","^(a.)\\g-1Z","u&YWULYgJX\\1&g",[])),
- <<"uaXaXZYWULYgJXaXaXaXZg">> = iolist_to_binary(re:replace("aXaXZ","^(a.)\\g-1Z","u&YWULYgJX\\1&g",[global])),
- <<"TpaXaXZmaXaXZQhnJ">> = iolist_to_binary(re:replace("aXaXZ","^(a.)\\g{-1}Z","Tp&m&QhnJ",[])),
- <<"TpaXaXZmaXaXZQhnJ">> = iolist_to_binary(re:replace("aXaXZ","^(a.)\\g{-1}Z","Tp&m&QhnJ",[global])),
- <<"cNcd">> = iolist_to_binary(re:replace("abcd","^(?(DEFINE) (?<A> a) (?<B> b) ) (?&A) (?&B) ","cN",[extended])),
- <<"cNcd">> = iolist_to_binary(re:replace("abcd","^(?(DEFINE) (?<A> a) (?<B> b) ) (?&A) (?&B) ","cN",[extended,
- global])),
- <<"S">> = iolist_to_binary(re:replace("metcalfe 33","(?<NAME>(?&NAME_PAT))\\s+(?<ADDR>(?&ADDRESS_PAT))
+ <<"UAyUXYabcdYapHaoXYabcdYOaaHkXYabcdY">> = iolist_to_binary(re:replace("XYabcdY","^X(?5)(a)(?|(b)|(q))(c)(d)(Y)","UAyU&\\1pH\\1o&O\\1\\1Hk&",[])),
+ <<"UAyUXYabcdYapHaoXYabcdYOaaHkXYabcdY">> = iolist_to_binary(re:replace("XYabcdY","^X(?5)(a)(?|(b)|(q))(c)(d)(Y)","UAyU&\\1pH\\1o&O\\1\\1Hk&",[global])),
+ <<"UlXYabcdYmKaP">> = iolist_to_binary(re:replace("XYabcdY","^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)","Ul&mKaP",[])),
+ <<"UlXYabcdYmKaP">> = iolist_to_binary(re:replace("XYabcdY","^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)","Ul&mKaP",[global])),
+ <<"mOVIXYabcdYkbaNflC">> = iolist_to_binary(re:replace("XYabcdY","^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)","mOVI&kb\\1NflC",[])),
+ <<"mOVIXYabcdYkbaNflC">> = iolist_to_binary(re:replace("XYabcdY","^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)","mOVI&kb\\1NflC",[global])),
+ <<"a:aaaua:aaaa:aacaKjjSkMSaLxyz">> = iolist_to_binary(re:replace("a:aaxyz","(?'abc'\\w+):\\k<abc>{2}","&\\1u&a&caKjjSkMS\\1L",[])),
+ <<"a:aaaua:aaaa:aacaKjjSkMSaLxyz">> = iolist_to_binary(re:replace("a:aaxyz","(?'abc'\\w+):\\k<abc>{2}","&\\1u&a&caKjjSkMS\\1L",[global])),
+ <<"ab:ababDababxyz">> = iolist_to_binary(re:replace("ab:ababxyz","(?'abc'\\w+):\\k<abc>{2}","&D\\1\\1",[])),
+ <<"ab:ababDababxyz">> = iolist_to_binary(re:replace("ab:ababxyz","(?'abc'\\w+):\\k<abc>{2}","&D\\1\\1",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?'abc'\\w+):\\k<abc>{2}","NhofxbK\\1smLiNJ\\1YyrV",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?'abc'\\w+):\\k<abc>{2}","NhofxbK\\1smLiNJ\\1YyrV",[global])),
+ <<"a:axyz">> = iolist_to_binary(re:replace("a:axyz","(?'abc'\\w+):\\k<abc>{2}","&R&&m&&",[])),
+ <<"a:axyz">> = iolist_to_binary(re:replace("a:axyz","(?'abc'\\w+):\\k<abc>{2}","&R&&m&&",[global])),
+ <<"ab:abxyz">> = iolist_to_binary(re:replace("ab:abxyz","(?'abc'\\w+):\\k<abc>{2}","cxccnpYwqQ",[])),
+ <<"ab:abxyz">> = iolist_to_binary(re:replace("ab:abxyz","(?'abc'\\w+):\\k<abc>{2}","cxccnpYwqQ",[global])),
+ <<"waYQqa:aalJrcNa:aaQujaFa:aanxyz">> = iolist_to_binary(re:replace("a:aaxyz","(?'abc'\\w+):\\g{abc}{2}","w\\1YQq&lJrcN&Quj\\1F&n",[])),
+ <<"waYQqa:aalJrcNa:aaQujaFa:aanxyz">> = iolist_to_binary(re:replace("a:aaxyz","(?'abc'\\w+):\\g{abc}{2}","w\\1YQq&lJrcN&Quj\\1F&n",[global])),
+ <<"SSNdab:ababnWnnujabab:ababab:ababxyz">> = iolist_to_binary(re:replace("ab:ababxyz","(?'abc'\\w+):\\g{abc}{2}","SSNd&nWnnuj\\1&&",[])),
+ <<"SSNdab:ababnWnnujabab:ababab:ababxyz">> = iolist_to_binary(re:replace("ab:ababxyz","(?'abc'\\w+):\\g{abc}{2}","SSNd&nWnnuj\\1&&",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?'abc'\\w+):\\g{abc}{2}","sC\\1",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?'abc'\\w+):\\g{abc}{2}","sC\\1",[global])),
+ <<"a:axyz">> = iolist_to_binary(re:replace("a:axyz","(?'abc'\\w+):\\g{abc}{2}","\\1&KtbPW\\1jI",[])),
+ <<"a:axyz">> = iolist_to_binary(re:replace("a:axyz","(?'abc'\\w+):\\g{abc}{2}","\\1&KtbPW\\1jI",[global])),
+ <<"ab:abxyz">> = iolist_to_binary(re:replace("ab:abxyz","(?'abc'\\w+):\\g{abc}{2}","&Dh",[])),
+ <<"ab:abxyz">> = iolist_to_binary(re:replace("ab:abxyz","(?'abc'\\w+):\\g{abc}{2}","&Dh",[global])),
+ <<"HX">> = iolist_to_binary(re:replace("abd","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)","HX",[extended])),
+ <<"HX">> = iolist_to_binary(re:replace("abd","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)","HX",[extended,
+ global])),
+ <<"BlTxckgd">> = iolist_to_binary(re:replace("ce","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)","BlTx\\1ckgd",[extended])),
+ <<"BlTxckgd">> = iolist_to_binary(re:replace("ce","^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)","BlTx\\1ckgd",[extended,
+ global])),
+ <<"WbqaXaXZ">> = iolist_to_binary(re:replace("aXaXZ","^(a.)\\g-1Z","Wbq&",[])),
+ <<"WbqaXaXZ">> = iolist_to_binary(re:replace("aXaXZ","^(a.)\\g-1Z","Wbq&",[global])),
+ <<"xLqaXYaXouuKkaXU">> = iolist_to_binary(re:replace("aXaXZ","^(a.)\\g{-1}Z","xLq\\1Y\\1ouuKk\\1U",[])),
+ <<"xLqaXYaXouuKkaXU">> = iolist_to_binary(re:replace("aXaXZ","^(a.)\\g{-1}Z","xLq\\1Y\\1ouuKk\\1U",[global])),
+ <<"uADabXiwJcd">> = iolist_to_binary(re:replace("abcd","^(?(DEFINE) (?<A> a) (?<B> b) ) (?&A) (?&B) ","uAD&XiwJ",[extended])),
+ <<"uADabXiwJcd">> = iolist_to_binary(re:replace("abcd","^(?(DEFINE) (?<A> a) (?<B> b) ) (?&A) (?&B) ","uAD&XiwJ",[extended,
+ global])),
+ <<"metcalfe 33yCmetcalfe 33jQmetcalfemetcalfe 33metcalfe 33E">> = iolist_to_binary(re:replace("metcalfe 33","(?<NAME>(?&NAME_PAT))\\s+(?<ADDR>(?&ADDRESS_PAT))
(?(DEFINE)
(?<NAME_PAT>[a-z]+)
(?<ADDRESS_PAT>\\d+)
- )","S",[extended])),
- <<"S">> = iolist_to_binary(re:replace("metcalfe 33","(?<NAME>(?&NAME_PAT))\\s+(?<ADDR>(?&ADDRESS_PAT))
+ )","&yC&jQ\\1&&E",[extended])),
+ <<"metcalfe 33yCmetcalfe 33jQmetcalfemetcalfe 33metcalfe 33E">> = iolist_to_binary(re:replace("metcalfe 33","(?<NAME>(?&NAME_PAT))\\s+(?<ADDR>(?&ADDRESS_PAT))
(?(DEFINE)
(?<NAME_PAT>[a-z]+)
(?<ADDRESS_PAT>\\d+)
- )","S",[extended,global])),
- <<"m1.2.3.4CNSbdi">> = iolist_to_binary(re:replace("1.2.3.4","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","m&CNSbd\\1i",[])),
- <<"m1.2.3.4CNSbdi">> = iolist_to_binary(re:replace("1.2.3.4","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","m&CNSbd\\1i",[global])),
- <<"131.111.10.206131.111.10.206DPiNTNK131.111.10.206grPeyEu">> = iolist_to_binary(re:replace("131.111.10.206","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","&&DPiNTN\\1\\1K&grPey\\1Eu",[])),
- <<"131.111.10.206131.111.10.206DPiNTNK131.111.10.206grPeyEu">> = iolist_to_binary(re:replace("131.111.10.206","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","&&DPiNTN\\1\\1K&grPey\\1Eu",[global])),
- <<"uBfPy10.0.0.010.0.0.0svWuRdbVVmys">> = iolist_to_binary(re:replace("10.0.0.0","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","u\\1BfPy&&svWuRdbVVmys",[])),
- <<"uBfPy10.0.0.010.0.0.0svWuRdbVVmys">> = iolist_to_binary(re:replace("10.0.0.0","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","u\\1BfPy&&svWuRdbVVmys",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","jVYSCLvb\\1Rm\\1Vn&",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","jVYSCLvb\\1Rm\\1Vn&",[global])),
- <<"10.6">> = iolist_to_binary(re:replace("10.6","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","dECob\\1\\1yakWA",[])),
- <<"10.6">> = iolist_to_binary(re:replace("10.6","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","dECob\\1\\1yakWA",[global])),
- <<"455.3.4.5">> = iolist_to_binary(re:replace("455.3.4.5","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","r",[])),
- <<"455.3.4.5">> = iolist_to_binary(re:replace("455.3.4.5","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","r",[global])),
- <<"VjWQp">> = iolist_to_binary(re:replace("1.2.3.4","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","VjWQp",[])),
- <<"VjWQp">> = iolist_to_binary(re:replace("1.2.3.4","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","VjWQp",[global])),
- <<"VQs131.111.10.206131.111.10.206r.206.206">> = iolist_to_binary(re:replace("131.111.10.206","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","VQs&&r\\1\\1",[])),
- <<"VQs131.111.10.206131.111.10.206r.206.206">> = iolist_to_binary(re:replace("131.111.10.206","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","VQs&&r\\1\\1",[global])),
- <<"mebNTtCd10.0.0.010.0.0.010.0.0.010.0.0.0S.0">> = iolist_to_binary(re:replace("10.0.0.0","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","mebNTtCd&&&&S\\1",[])),
- <<"mebNTtCd10.0.0.010.0.0.010.0.0.010.0.0.0S.0">> = iolist_to_binary(re:replace("10.0.0.0","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","mebNTtCd&&&&S\\1",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","uvmK&GcQ&\\1u\\1",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","uvmK&GcQ&\\1u\\1",[global])),
- <<"10.6">> = iolist_to_binary(re:replace("10.6","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","TH\\1bkRaOVXKAGH&Wq\\1",[])),
- <<"10.6">> = iolist_to_binary(re:replace("10.6","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","TH\\1bkRaOVXKAGH&Wq\\1",[global])),
- <<"455.3.4.5">> = iolist_to_binary(re:replace("455.3.4.5","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","flY&",[])),
- <<"455.3.4.5">> = iolist_to_binary(re:replace("455.3.4.5","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","flY&",[global])),
- <<"XIXOpartynow is the time for all good men to come to the aid of the partyenW">> = iolist_to_binary(re:replace("now is the time for all good men to come to the aid of the party","^(\\w++|\\s++)*$","XIXO\\1&enW",[])),
- <<"XIXOpartynow is the time for all good men to come to the aid of the partyenW">> = iolist_to_binary(re:replace("now is the time for all good men to come to the aid of the party","^(\\w++|\\s++)*$","XIXO\\1&enW",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\w++|\\s++)*$","bwiYg",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\w++|\\s++)*$","bwiYg",[global])),
- <<"this is not a line with only words and spaces!">> = iolist_to_binary(re:replace("this is not a line with only words and spaces!","^(\\w++|\\s++)*$","d\\1",[])),
- <<"this is not a line with only words and spaces!">> = iolist_to_binary(re:replace("this is not a line with only words and spaces!","^(\\w++|\\s++)*$","d\\1",[global])),
- <<"m12345sdTXRM1234512345a">> = iolist_to_binary(re:replace("12345a","(\\d++)(\\w)","m\\1sdTXRM\\1&",[])),
- <<"m12345sdTXRM1234512345a">> = iolist_to_binary(re:replace("12345a","(\\d++)(\\w)","m\\1sdTXRM\\1&",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(\\d++)(\\w)","eFU&\\1cQE\\1\\1grkNJ&Ad\\1f",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(\\d++)(\\w)","eFU&\\1cQE\\1\\1grkNJ&Ad\\1f",[global])),
- <<"12345+">> = iolist_to_binary(re:replace("12345+","(\\d++)(\\w)","i&hvp\\1XhCAs&VRh",[])),
- <<"12345+">> = iolist_to_binary(re:replace("12345+","(\\d++)(\\w)","i&hvp\\1XhCAs&VRh",[global])),
- <<"NaaabIg">> = iolist_to_binary(re:replace("aaab","a++b","\\1N&Ig",[])),
- <<"NaaabIg">> = iolist_to_binary(re:replace("aaab","a++b","\\1N&Ig",[global])),
- <<"maaabaaabgBJFEHXaaabaaabaaabkAaaab">> = iolist_to_binary(re:replace("aaab","(a++b)","m&\\1gBJFEHX&&\\1kA&",[])),
- <<"maaabaaabgBJFEHXaaabaaabaaabkAaaab">> = iolist_to_binary(re:replace("aaab","(a++b)","m&\\1gBJFEHX&&\\1kA&",[global])),
- <<"TaaabRaaaaaaeBTpaaaTi">> = iolist_to_binary(re:replace("aaab","(a++)b","T&R\\1\\1eBTp\\1Ti",[])),
- <<"TaaabRaaaaaaeBTpaaaTi">> = iolist_to_binary(re:replace("aaab","(a++)b","T&R\\1\\1eBTp\\1Ti",[global])),
- <<"((PwxkrBxNdabc(ade)ufh()()xYBkxEabc(ade)ufh()()xFkxx">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","([^()]++|\\([^()]*\\))+","Pw\\1krB\\1Nd&YBk\\1E&Fk\\1\\1",[])),
- <<"((PwxkrBxNdabc(ade)ufh()()xYBkxEabc(ade)ufh()()xFkxx">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","([^()]++|\\([^()]*\\))+","Pw\\1krB\\1Nd&YBk\\1E&Fk\\1\\1",[global])),
- <<"F(abc)sMN">> = iolist_to_binary(re:replace("(abc)","\\(([^()]++|\\([^()]+\\))+\\)","F&sMN",[])),
- <<"F(abc)sMN">> = iolist_to_binary(re:replace("(abc)","\\(([^()]++|\\([^()]+\\))+\\)","F&sMN",[global])),
- <<"SMUJyftxyzxyz(abc(def)xyz)RpnMnA">> = iolist_to_binary(re:replace("(abc(def)xyz)","\\(([^()]++|\\([^()]+\\))+\\)","SMUJyft\\1\\1&RpnMnA",[])),
- <<"SMUJyftxyzxyz(abc(def)xyz)RpnMnA">> = iolist_to_binary(re:replace("(abc(def)xyz)","\\(([^()]++|\\([^()]+\\))+\\)","SMUJyft\\1\\1&RpnMnA",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\(([^()]++|\\([^()]+\\))+\\)","p",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\(([^()]++|\\([^()]+\\))+\\)","p",[global])),
- <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(([^()]++|\\([^()]+\\))+\\)","gVbYV&vnkHNjeK",[])),
- <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(([^()]++|\\([^()]+\\))+\\)","gVbYV&vnkHNjeK",[global])),
+ )","&yC&jQ\\1&&E",[extended,global])),
+ <<"csUt">> = iolist_to_binary(re:replace("1.2.3.4","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","csUt",[])),
+ <<"csUt">> = iolist_to_binary(re:replace("1.2.3.4","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","csUt",[global])),
+ <<"131.111.10.206CEy131.111.10.206iDmGa131.111.10.206Dl">> = iolist_to_binary(re:replace("131.111.10.206","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","&CEy&iDmGa&\\1Dl",[])),
+ <<"131.111.10.206CEy131.111.10.206iDmGa131.111.10.206Dl">> = iolist_to_binary(re:replace("131.111.10.206","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","&CEy&iDmGa&\\1Dl",[global])),
+ <<"YQqPs10.0.0.0DQgo10.0.0.0Nnyi10.0.0.0Ny">> = iolist_to_binary(re:replace("10.0.0.0","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","YQqPs&DQgo\\1\\1&Nnyi&Ny",[])),
+ <<"YQqPs10.0.0.0DQgo10.0.0.0Nnyi10.0.0.0Ny">> = iolist_to_binary(re:replace("10.0.0.0","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","YQqPs&DQgo\\1\\1&Nnyi&Ny",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","o\\1\\1&&Ds&F&",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","o\\1\\1&&Ds&F&",[global])),
+ <<"10.6">> = iolist_to_binary(re:replace("10.6","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","s&\\1BXWRj\\1rQXiOeLx",[])),
+ <<"10.6">> = iolist_to_binary(re:replace("10.6","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","s&\\1BXWRj\\1rQXiOeLx",[global])),
+ <<"455.3.4.5">> = iolist_to_binary(re:replace("455.3.4.5","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","Y",[])),
+ <<"455.3.4.5">> = iolist_to_binary(re:replace("455.3.4.5","(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}","Y",[global])),
+ <<"DaLYYtnY">> = iolist_to_binary(re:replace("1.2.3.4","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","DaLYYtnY",[])),
+ <<"DaLYYtnY">> = iolist_to_binary(re:replace("1.2.3.4","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","DaLYYtnY",[global])),
+ <<"MBU.206M">> = iolist_to_binary(re:replace("131.111.10.206","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","MBU\\1M",[])),
+ <<"MBU.206M">> = iolist_to_binary(re:replace("131.111.10.206","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","MBU\\1M",[global])),
+ <<"10.0.0.0Lp">> = iolist_to_binary(re:replace("10.0.0.0","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","&Lp",[])),
+ <<"10.0.0.0Lp">> = iolist_to_binary(re:replace("10.0.0.0","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","&Lp",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","hr&USJrD",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","hr&USJrD",[global])),
+ <<"10.6">> = iolist_to_binary(re:replace("10.6","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","BbfgCNDo&\\1C\\1",[])),
+ <<"10.6">> = iolist_to_binary(re:replace("10.6","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","BbfgCNDo&\\1C\\1",[global])),
+ <<"455.3.4.5">> = iolist_to_binary(re:replace("455.3.4.5","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","w&Yt",[])),
+ <<"455.3.4.5">> = iolist_to_binary(re:replace("455.3.4.5","\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))","w&Yt",[global])),
+ <<"Agnow is the time for all good men to come to the aid of the partyV">> = iolist_to_binary(re:replace("now is the time for all good men to come to the aid of the party","^(\\w++|\\s++)*$","Ag&V",[])),
+ <<"Agnow is the time for all good men to come to the aid of the partyV">> = iolist_to_binary(re:replace("now is the time for all good men to come to the aid of the party","^(\\w++|\\s++)*$","Ag&V",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\w++|\\s++)*$","VxnH\\1OwDhnQQemGf&IJ",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\w++|\\s++)*$","VxnH\\1OwDhnQQemGf&IJ",[global])),
+ <<"this is not a line with only words and spaces!">> = iolist_to_binary(re:replace("this is not a line with only words and spaces!","^(\\w++|\\s++)*$","OmS\\1W&&yOcff\\1pn",[])),
+ <<"this is not a line with only words and spaces!">> = iolist_to_binary(re:replace("this is not a line with only words and spaces!","^(\\w++|\\s++)*$","OmS\\1W&&yOcff\\1pn",[global])),
+ <<"X12345aM">> = iolist_to_binary(re:replace("12345a","(\\d++)(\\w)","X&M",[])),
+ <<"X12345aM">> = iolist_to_binary(re:replace("12345a","(\\d++)(\\w)","X&M",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(\\d++)(\\w)","G&QA&qhihaMMrQ",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","(\\d++)(\\w)","G&QA&qhihaMMrQ",[global])),
+ <<"12345+">> = iolist_to_binary(re:replace("12345+","(\\d++)(\\w)","kIxM\\1rD\\1B\\1a",[])),
+ <<"12345+">> = iolist_to_binary(re:replace("12345+","(\\d++)(\\w)","kIxM\\1rD\\1B\\1a",[global])),
+ <<"tkeKIY">> = iolist_to_binary(re:replace("aaab","a++b","tkeKIY",[])),
+ <<"tkeKIY">> = iolist_to_binary(re:replace("aaab","a++b","tkeKIY",[global])),
+ <<"aaabIaaab">> = iolist_to_binary(re:replace("aaab","(a++b)","\\1I\\1",[])),
+ <<"aaabIaaab">> = iolist_to_binary(re:replace("aaab","(a++b)","\\1I\\1",[global])),
+ <<"rOaaabYBnR">> = iolist_to_binary(re:replace("aaab","(a++)b","rO&YBnR",[])),
+ <<"rOaaabYBnR">> = iolist_to_binary(re:replace("aaab","(a++)b","rO&YBnR",[global])),
+ <<"((uwsqruwBU">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","([^()]++|\\([^()]*\\))+","uwsqruwBU",[])),
+ <<"((uwsqruwBU">> = iolist_to_binary(re:replace("((abc(ade)ufh()()x","([^()]++|\\([^()]*\\))+","uwsqruwBU",[global])),
+ <<"(abc)GFFGlEEaBgxgufwp">> = iolist_to_binary(re:replace("(abc)","\\(([^()]++|\\([^()]+\\))+\\)","&GFFGlEEaBgxgufwp",[])),
+ <<"(abc)GFFGlEEaBgxgufwp">> = iolist_to_binary(re:replace("(abc)","\\(([^()]++|\\([^()]+\\))+\\)","&GFFGlEEaBgxgufwp",[global])),
+ <<"x(abc(def)xyz)(abc(def)xyz)Jvx(abc(def)xyz)xyzd(abc(def)xyz)(abc(def)xyz)">> = iolist_to_binary(re:replace("(abc(def)xyz)","\\(([^()]++|\\([^()]+\\))+\\)","x&&Jvx&\\1d&&",[])),
+ <<"x(abc(def)xyz)(abc(def)xyz)Jvx(abc(def)xyz)xyzd(abc(def)xyz)(abc(def)xyz)">> = iolist_to_binary(re:replace("(abc(def)xyz)","\\(([^()]++|\\([^()]+\\))+\\)","x&&Jvx&\\1d&&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\(([^()]++|\\([^()]+\\))+\\)","ieL\\1IsedxuM",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","\\(([^()]++|\\([^()]+\\))+\\)","ieL\\1IsedxuM",[global])),
+ <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(([^()]++|\\([^()]+\\))+\\)","&\\1fqeu\\1",[])),
+ <<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(([^()]++|\\([^()]+\\))+\\)","&\\1fqeu\\1",[global])),
+ <<"kqQTCl">> = iolist_to_binary(re:replace("abc","^([^()]|\\((?1)*\\))*$","kqQTCl",[])),
+ <<"kqQTCl">> = iolist_to_binary(re:replace("abc","^([^()]|\\((?1)*\\))*$","kqQTCl",[global])),
+ <<"cRla(b)cGc">> = iolist_to_binary(re:replace("a(b)c","^([^()]|\\((?1)*\\))*$","\\1Rl&G\\1",[])),
+ <<"cRla(b)cGc">> = iolist_to_binary(re:replace("a(b)c","^([^()]|\\((?1)*\\))*$","\\1Rl&G\\1",[global])),
+ <<"dKa(b(c))dfGndCr">> = iolist_to_binary(re:replace("a(b(c))d","^([^()]|\\((?1)*\\))*$","\\1K&fGn\\1Cr",[])),
+ <<"dKa(b(c))dfGndCr">> = iolist_to_binary(re:replace("a(b(c))d","^([^()]|\\((?1)*\\))*$","\\1K&fGn\\1Cr",[global])),
+ <<"*** Failers)">> = iolist_to_binary(re:replace("*** Failers)","^([^()]|\\((?1)*\\))*$","\\1n\\1&umpF&",[])),
+ <<"*** Failers)">> = iolist_to_binary(re:replace("*** Failers)","^([^()]|\\((?1)*\\))*$","\\1n\\1&umpF&",[global])),
+ <<"a(b(c)d">> = iolist_to_binary(re:replace("a(b(c)d","^([^()]|\\((?1)*\\))*$","\\1JTc",[])),
+ <<"a(b(c)d">> = iolist_to_binary(re:replace("a(b(c)d","^([^()]|\\((?1)*\\))*$","\\1JTc",[global])),
ok.
run42() ->
- <<"YHcxHwcJHhabcabcyqOabcio">> = iolist_to_binary(re:replace("abc","^([^()]|\\((?1)*\\))*$","YH\\1xHw\\1JHh&&yqO&io",[])),
- <<"YHcxHwcJHhabcabcyqOabcio">> = iolist_to_binary(re:replace("abc","^([^()]|\\((?1)*\\))*$","YH\\1xHw\\1JHh&&yqO&io",[global])),
- <<"Xua(b)ccOqkxg">> = iolist_to_binary(re:replace("a(b)c","^([^()]|\\((?1)*\\))*$","Xu&\\1Oqkxg",[])),
- <<"Xua(b)ccOqkxg">> = iolist_to_binary(re:replace("a(b)c","^([^()]|\\((?1)*\\))*$","Xu&\\1Oqkxg",[global])),
- <<"pHOdcaLUi">> = iolist_to_binary(re:replace("a(b(c))d","^([^()]|\\((?1)*\\))*$","pHO\\1caLUi",[])),
- <<"pHOdcaLUi">> = iolist_to_binary(re:replace("a(b(c))d","^([^()]|\\((?1)*\\))*$","pHO\\1caLUi",[global])),
- <<"*** Failers)">> = iolist_to_binary(re:replace("*** Failers)","^([^()]|\\((?1)*\\))*$","&YxG",[])),
- <<"*** Failers)">> = iolist_to_binary(re:replace("*** Failers)","^([^()]|\\((?1)*\\))*$","&YxG",[global])),
- <<"a(b(c)d">> = iolist_to_binary(re:replace("a(b(c)d","^([^()]|\\((?1)*\\))*$","s\\1BLqc",[])),
- <<"a(b(c)d">> = iolist_to_binary(re:replace("a(b(c)d","^([^()]|\\((?1)*\\))*$","s\\1BLqc",[global])),
- <<"puAth">> = iolist_to_binary(re:replace(">abc>123<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","puAth",[])),
- <<"puAth">> = iolist_to_binary(re:replace(">abc>123<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","puAth",[global])),
- <<"QVYB>abc>1(2)3<xyz<cFhyH">> = iolist_to_binary(re:replace(">abc>1(2)3<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","QVYB&cFhyH",[])),
- <<"QVYB>abc>1(2)3<xyz<cFhyH">> = iolist_to_binary(re:replace(">abc>1(2)3<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","QVYB&cFhyH",[global])),
- <<"(1(2)3)">> = iolist_to_binary(re:replace(">abc>(1(2)3)<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","\\1",[])),
- <<"(1(2)3)">> = iolist_to_binary(re:replace(">abc>(1(2)3)<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","\\1",[global])),
- <<"fb1221w122112211221Q1221yL1221d">> = iolist_to_binary(re:replace("1221","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","fb\\1w\\1&&Q&yL&d",[caseless])),
- <<"fb1221w122112211221Q1221yL1221d">> = iolist_to_binary(re:replace("1221","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","fb\\1w\\1&&Q&yL&d",[caseless,
- global])),
- <<"yadakp">> = iolist_to_binary(re:replace("Satanoscillatemymetallicsonatas","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","ya\\1dakp\\1",[caseless])),
- <<"yadakp">> = iolist_to_binary(re:replace("Satanoscillatemymetallicsonatas","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","ya\\1dakp\\1",[caseless,
- global])),
- <<"aAmanaplanacanalPanamalDAmanaplanacanalPanamaiqyAmanaplanacanalPanamaOSvaJYbQ">> = iolist_to_binary(re:replace("AmanaplanacanalPanama","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","a&lD&i\\1qy&OSv\\1aJYbQ",[caseless])),
- <<"aAmanaplanacanalPanamalDAmanaplanacanalPanamaiqyAmanaplanacanalPanamaOSvaJYbQ">> = iolist_to_binary(re:replace("AmanaplanacanalPanama","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","a&lD&i\\1qy&OSv\\1aJYbQ",[caseless,
- global])),
- <<"UcSlDNWgAva">> = iolist_to_binary(re:replace("AblewasIereIsawElba","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","UcSlD\\1NWgAva\\1",[caseless])),
- <<"UcSlDNWgAva">> = iolist_to_binary(re:replace("AblewasIereIsawElba","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","UcSlD\\1NWgAva\\1",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","n",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","n",[caseless,
- global])),
- <<"Thequickbrownfox">> = iolist_to_binary(re:replace("Thequickbrownfox","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","MuY&Y&DfSiG&KPnRRGOO",[caseless])),
- <<"Thequickbrownfox">> = iolist_to_binary(re:replace("Thequickbrownfox","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","MuY&Y&DfSiG&KPnRRGOO",[caseless,
- global])),
- <<"Dlcq12uvNpwj">> = iolist_to_binary(re:replace("12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","Dlcq\\1uvNpwj",[])),
- <<"Dlcq12uvNpwj">> = iolist_to_binary(re:replace("12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","Dlcq\\1uvNpwj",[global])),
- <<"(((2+2)*-3)-7)Hq(((2+2)*-3)-7)nwjc(((2+2)*-3)-7)OCxTARr">> = iolist_to_binary(re:replace("(((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","&Hq&nwjc\\1OCxTARr",[])),
- <<"(((2+2)*-3)-7)Hq(((2+2)*-3)-7)nwjc(((2+2)*-3)-7)OCxTARr">> = iolist_to_binary(re:replace("(((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","&Hq&nwjc\\1OCxTARr",[global])),
- <<"EjPI-12tsA-12ux-12-12-12MfkO">> = iolist_to_binary(re:replace("-12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","EjPI&tsA&ux&\\1\\1MfkO",[])),
- <<"EjPI-12tsA-12ux-12-12-12MfkO">> = iolist_to_binary(re:replace("-12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","EjPI&tsA&ux&\\1\\1MfkO",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","sxA&v\\1L\\1Q\\1FFDAm\\1hOOv",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","sxA&v\\1L\\1Q\\1FFDAm\\1hOOv",[global])),
- <<"((2+2)*-3)-7)">> = iolist_to_binary(re:replace("((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","el\\1La",[])),
- <<"((2+2)*-3)-7)">> = iolist_to_binary(re:replace("((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","el\\1La",[global])),
- <<"vRxyzxyzrJYxyzxyzjNtdExyzSxeWm">> = iolist_to_binary(re:replace("xyz","^(x(y|(?1){2})z)","vR\\1\\1rJY&\\1jNtdE&SxeWm",[])),
- <<"vRxyzxyzrJYxyzxyzjNtdExyzSxeWm">> = iolist_to_binary(re:replace("xyz","^(x(y|(?1){2})z)","vR\\1\\1rJY&\\1jNtdE&SxeWm",[global])),
- <<"CRxxyzxyzzkQsxxyzxyzzHmiGvxxyzxyzzy">> = iolist_to_binary(re:replace("xxyzxyzz","^(x(y|(?1){2})z)","CR\\1kQs\\1HmiGv\\1y",[])),
- <<"CRxxyzxyzzkQsxxyzxyzzHmiGvxxyzxyzzy">> = iolist_to_binary(re:replace("xxyzxyzz","^(x(y|(?1){2})z)","CR\\1kQs\\1HmiGv\\1y",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(x(y|(?1){2})z)","qTfvW\\1q\\1&UXxp\\1b",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(x(y|(?1){2})z)","qTfvW\\1q\\1&UXxp\\1b",[global])),
- <<"xxyzz">> = iolist_to_binary(re:replace("xxyzz","^(x(y|(?1){2})z)","WRW&Ky",[])),
- <<"xxyzz">> = iolist_to_binary(re:replace("xxyzz","^(x(y|(?1){2})z)","WRW&Ky",[global])),
- <<"xxyzxyzxyzz">> = iolist_to_binary(re:replace("xxyzxyzxyzz","^(x(y|(?1){2})z)","SgB&TOTaVTG\\1\\1Sy",[])),
- <<"xxyzxyzxyzz">> = iolist_to_binary(re:replace("xxyzxyzxyzz","^(x(y|(?1){2})z)","SgB&TOTaVTG\\1\\1Sy",[global])),
+ <<">abc>123<xyz<Po3Pcn3tBnXovXUUqId">> = iolist_to_binary(re:replace(">abc>123<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","&Po\\1Pcn\\1tBnXovXUUqId",[])),
+ <<">abc>123<xyz<Po3Pcn3tBnXovXUUqId">> = iolist_to_binary(re:replace(">abc>123<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","&Po\\1Pcn\\1tBnXovXUUqId",[global])),
+ <<"P3KXinsyIho">> = iolist_to_binary(re:replace(">abc>1(2)3<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","P\\1KXinsyIho",[])),
+ <<"P3KXinsyIho">> = iolist_to_binary(re:replace(">abc>1(2)3<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","P\\1KXinsyIho",[global])),
+ <<"dQI(1(2)3)Ox>abc>(1(2)3)<xyz<MgB(1(2)3)(1(2)3)m(1(2)3)i>abc>(1(2)3)<xyz<SNVV">> = iolist_to_binary(re:replace(">abc>(1(2)3)<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","dQI\\1Ox&MgB\\1\\1m\\1i&SNVV",[])),
+ <<"dQI(1(2)3)Ox>abc>(1(2)3)<xyz<MgB(1(2)3)(1(2)3)m(1(2)3)i>abc>(1(2)3)<xyz<SNVV">> = iolist_to_binary(re:replace(">abc>(1(2)3)<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$","dQI\\1Ox&MgB\\1\\1m\\1i&SNVV",[global])),
+ <<"fjn">> = iolist_to_binary(re:replace("1221","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","fjn",[caseless])),
+ <<"fjn">> = iolist_to_binary(re:replace("1221","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","fjn",[caseless,
+ global])),
+ <<"EWyIbgb">> = iolist_to_binary(re:replace("Satanoscillatemymetallicsonatas","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","EW\\1yIbgb",[caseless])),
+ <<"EWyIbgb">> = iolist_to_binary(re:replace("Satanoscillatemymetallicsonatas","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","EW\\1yIbgb",[caseless,
+ global])),
+ <<"aAmanaplanacanalPanamayDfAmanaplanacanalPanamaanKSCjCr">> = iolist_to_binary(re:replace("AmanaplanacanalPanama","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","a&yDf&anKS\\1CjCr",[caseless])),
+ <<"aAmanaplanacanalPanamayDfAmanaplanacanalPanamaanKSCjCr">> = iolist_to_binary(re:replace("AmanaplanacanalPanama","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","a&yDf&anKS\\1CjCr",[caseless,
+ global])),
+ <<"hTo">> = iolist_to_binary(re:replace("AblewasIereIsawElba","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","\\1h\\1To",[caseless])),
+ <<"hTo">> = iolist_to_binary(re:replace("AblewasIereIsawElba","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","\\1h\\1To",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","SQq",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","SQq",[caseless,
+ global])),
+ <<"Thequickbrownfox">> = iolist_to_binary(re:replace("Thequickbrownfox","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","m&\\1ypjt",[caseless])),
+ <<"Thequickbrownfox">> = iolist_to_binary(re:replace("Thequickbrownfox","^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$","m&\\1ypjt",[caseless,
+ global])),
+ <<"vmtlvgrhXoIVUjuxCJ">> = iolist_to_binary(re:replace("12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","vmtlvgrhXoIVUjuxCJ",[])),
+ <<"vmtlvgrhXoIVUjuxCJ">> = iolist_to_binary(re:replace("12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","vmtlvgrhXoIVUjuxCJ",[global])),
+ <<"S(((2+2)*-3)-7)hoEGuxAELDlwIpN">> = iolist_to_binary(re:replace("(((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","S\\1hoEGuxAELDlwIpN",[])),
+ <<"S(((2+2)*-3)-7)hoEGuxAELDlwIpN">> = iolist_to_binary(re:replace("(((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","S\\1hoEGuxAELDlwIpN",[global])),
+ <<"fn-12K">> = iolist_to_binary(re:replace("-12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","fn&K",[])),
+ <<"fn-12K">> = iolist_to_binary(re:replace("-12","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","fn&K",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","kbKqwY\\1dbLnM",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","kbKqwY\\1dbLnM",[global])),
+ <<"((2+2)*-3)-7)">> = iolist_to_binary(re:replace("((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","&aHqiP",[])),
+ <<"((2+2)*-3)-7)">> = iolist_to_binary(re:replace("((2+2)*-3)-7)","^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$","&aHqiP",[global])),
+ <<"qxyzCk">> = iolist_to_binary(re:replace("xyz","^(x(y|(?1){2})z)","q&Ck",[])),
+ <<"qxyzCk">> = iolist_to_binary(re:replace("xyz","^(x(y|(?1){2})z)","q&Ck",[global])),
+ <<"LxxyzxyzzSIxxyzxyzzHmXxxyzxyzzmxxyzxyzzxxyzxyzzQaGiQRxxyzxyzz">> = iolist_to_binary(re:replace("xxyzxyzz","^(x(y|(?1){2})z)","L&SI\\1HmX\\1m&&QaGiQR&",[])),
+ <<"LxxyzxyzzSIxxyzxyzzHmXxxyzxyzzmxxyzxyzzxxyzxyzzQaGiQRxxyzxyzz">> = iolist_to_binary(re:replace("xxyzxyzz","^(x(y|(?1){2})z)","L&SI\\1HmX\\1m&&QaGiQR&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(x(y|(?1){2})z)","JDpAfO\\1cLFC",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(x(y|(?1){2})z)","JDpAfO\\1cLFC",[global])),
+ <<"xxyzz">> = iolist_to_binary(re:replace("xxyzz","^(x(y|(?1){2})z)","iy\\1e\\1b",[])),
+ <<"xxyzz">> = iolist_to_binary(re:replace("xxyzz","^(x(y|(?1){2})z)","iy\\1e\\1b",[global])),
+ <<"xxyzxyzxyzz">> = iolist_to_binary(re:replace("xxyzxyzxyzz","^(x(y|(?1){2})z)","xpghdaVtJ\\1PnXNv\\1ALV",[])),
+ <<"xxyzxyzxyzz">> = iolist_to_binary(re:replace("xxyzxyzxyzz","^(x(y|(?1){2})z)","xpghdaVtJ\\1PnXNv\\1ALV",[global])),
<<"p">> = iolist_to_binary(re:replace("<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","p",[extended])),
<<"p">> = iolist_to_binary(re:replace("<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","p",[extended,
global])),
- <<"<abcd>oQy<abcd><abcd>UhI<abcd>g">> = iolist_to_binary(re:replace("<abcd>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","\\1oQy\\1&UhI&g",[extended])),
- <<"<abcd>oQy<abcd><abcd>UhI<abcd>g">> = iolist_to_binary(re:replace("<abcd>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","\\1oQy\\1&UhI&g",[extended,
- global])),
- <<"NymkAa">> = iolist_to_binary(re:replace("<abc <123> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","NymkAa",[extended])),
- <<"NymkAa">> = iolist_to_binary(re:replace("<abc <123> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","NymkAa",[extended,
- global])),
- <<"<abc i<def>g<def>fMHHlJ<def><def> hij>">> = iolist_to_binary(re:replace("<abc <def> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","i&g\\1fMHHlJ\\1\\1",[extended])),
- <<"<abc i<def>g<def>fMHHlJ<def><def> hij>">> = iolist_to_binary(re:replace("<abc <def> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","i&g\\1fMHHlJ\\1\\1",[extended,
- global])),
- <<"yJJ<abc<>def>yo<abc<>def>X">> = iolist_to_binary(re:replace("<abc<>def>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","yJJ&yo\\1X",[extended])),
- <<"yJJ<abc<>def>yo<abc<>def>X">> = iolist_to_binary(re:replace("<abc<>def>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","yJJ&yo\\1X",[extended,
- global])),
- <<"<abcn<>LhiK<>ufT<>q<><>SodEfM">> = iolist_to_binary(re:replace("<abc<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","n\\1LhiK&ufT&q&&SodEfM",[extended])),
- <<"<abcn<>LhiK<>ufT<>q<><>SodEfM">> = iolist_to_binary(re:replace("<abc<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","n\\1LhiK&ufT&q&&SodEfM",[extended,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","R&",[extended])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","R&",[extended,
- global])),
- <<"<abc">> = iolist_to_binary(re:replace("<abc","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","l",[extended])),
- <<"<abc">> = iolist_to_binary(re:replace("<abc","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","l",[extended,
- global])),
- <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^a+(*FAIL)","oWDClek&Nwt&&aMO\\1",[])),
- <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^a+(*FAIL)","oWDClek&Nwt&&aMO\\1",[global])),
- <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?c+(*FAIL)","L\\1&&fllctiK\\1WqBCUQ",[])),
- <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?c+(*FAIL)","L\\1&&fllctiK\\1WqBCUQ",[global])),
- <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*PRUNE)c+(*FAIL)","Jpy\\1FAL",[])),
- <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*PRUNE)c+(*FAIL)","Jpy\\1FAL",[global])),
- <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*COMMIT)c+(*FAIL)","I",[])),
- <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*COMMIT)c+(*FAIL)","I",[global])),
- <<"aaabcccaaabccc">> = iolist_to_binary(re:replace("aaabcccaaabccc","a+b?(*SKIP)c+(*FAIL)","cRBQ\\1mL",[])),
- <<"aaabcccaaabccc">> = iolist_to_binary(re:replace("aaabcccaaabccc","a+b?(*SKIP)c+(*FAIL)","cRBQ\\1mL",[global])),
- <<"JRWgePSUsExfJfHo">> = iolist_to_binary(re:replace("aaaxxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","\\1JRWgePSUsExfJf\\1Ho",[])),
- <<"JRWgePSUsExfJfHo">> = iolist_to_binary(re:replace("aaaxxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","\\1JRWgePSUsExfJf\\1Ho",[global])),
- <<"AlHMdrRl++++++">> = iolist_to_binary(re:replace("aaa++++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","AlHMdrRl",[])),
- <<"AlHMdrRl++++++">> = iolist_to_binary(re:replace("aaa++++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","AlHMdrRl",[global])),
- <<"bKH">> = iolist_to_binary(re:replace("bbbxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","bKH",[])),
- <<"bKH">> = iolist_to_binary(re:replace("bbbxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","bKH",[global])),
- <<"AyqLHpWSaFmaN+++++">> = iolist_to_binary(re:replace("bbb+++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","AyqLHpWSaFma\\1N",[])),
- <<"AyqLHpWSaFmaN+++++">> = iolist_to_binary(re:replace("bbb+++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","AyqLHpWSaFma\\1N",[global])),
- <<"bvYRps">> = iolist_to_binary(re:replace("cccxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","bvYR\\1ps",[])),
- <<"bvYRps">> = iolist_to_binary(re:replace("cccxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","bvYR\\1ps",[global])),
- <<"KPYMvODtuotXNIo++++">> = iolist_to_binary(re:replace("ccc++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","KPYMv\\1\\1ODtuotXNIo",[])),
- <<"KPYMvODtuotXNIo++++">> = iolist_to_binary(re:replace("ccc++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","KPYMv\\1\\1ODtuotXNIo",[global])),
- <<"kddddd">> = iolist_to_binary(re:replace("dddddddd","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","k",[])),
- <<"kddddd">> = iolist_to_binary(re:replace("dddddddd","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","k",[global])),
- <<"kaaaxxxxxxrQaRFqL">> = iolist_to_binary(re:replace("aaaxxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","k\\1rQaRFqL",[])),
- <<"kaaaxxxxxxrQaRFqL">> = iolist_to_binary(re:replace("aaaxxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","k\\1rQaRFqL",[global])),
- <<"aaaw++++++">> = iolist_to_binary(re:replace("aaa++++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","\\1w",[])),
- <<"aaaw++++++">> = iolist_to_binary(re:replace("aaa++++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","\\1w",[global])),
- <<"JyQqJIbbbxxxxxBAVHEvuuRsYpC">> = iolist_to_binary(re:replace("bbbxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","JyQqJI&BAVHEvuuRsYpC",[])),
- <<"JyQqJIbbbxxxxxBAVHEvuuRsYpC">> = iolist_to_binary(re:replace("bbbxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","JyQqJI&BAVHEvuuRsYpC",[global])),
- <<"dBwHTombbbccbbbR+++++">> = iolist_to_binary(re:replace("bbb+++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","dBwHTom&cc&R",[])),
- <<"dBwHTombbbccbbbR+++++">> = iolist_to_binary(re:replace("bbb+++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","dBwHTom&cc&R",[global])),
- <<"OcccxxxxeA">> = iolist_to_binary(re:replace("cccxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","O&eA",[])),
- <<"OcccxxxxeA">> = iolist_to_binary(re:replace("cccxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","O&eA",[global])),
- <<"DyFCQsccclWCcccy++++">> = iolist_to_binary(re:replace("ccc++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","DyFCQs&lWC&y",[])),
- <<"DyFCQsccclWCcccy++++">> = iolist_to_binary(re:replace("ccc++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","DyFCQs&lWC&y",[global])),
- <<"cdddvddddd">> = iolist_to_binary(re:replace("dddddddd","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","c&v",[])),
- <<"cdddvddddd">> = iolist_to_binary(re:replace("dddddddd","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","c&v",[global])),
- <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*THEN)c+(*FAIL)","PV&\\1x\\1vsUDLpYB\\1\\1t",[])),
- <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*THEN)c+(*FAIL)","PV&\\1x\\1vsUDLpYB\\1\\1t",[global])),
- <<"FhiABxmOfR">> = iolist_to_binary(re:replace("AB","(A (A|B(*ACCEPT)|C) D)(E)","Fhi\\1xmOfR",[extended])),
- <<"FhiABxmOfR">> = iolist_to_binary(re:replace("AB","(A (A|B(*ACCEPT)|C) D)(E)","Fhi\\1xmOfR",[extended,
- global])),
- <<"BHulABQjABrLtABEnSX">> = iolist_to_binary(re:replace("ABX","(A (A|B(*ACCEPT)|C) D)(E)","BHul&Qj&rLt\\1EnS",[extended])),
- <<"BHulABQjABrLtABEnSX">> = iolist_to_binary(re:replace("ABX","(A (A|B(*ACCEPT)|C) D)(E)","BHul&Qj&rLt\\1EnS",[extended,
- global])),
- <<"fwi">> = iolist_to_binary(re:replace("AADE","(A (A|B(*ACCEPT)|C) D)(E)","fwi",[extended])),
- <<"fwi">> = iolist_to_binary(re:replace("AADE","(A (A|B(*ACCEPT)|C) D)(E)","fwi",[extended,
- global])),
- <<"vpACDe">> = iolist_to_binary(re:replace("ACDE","(A (A|B(*ACCEPT)|C) D)(E)","vp\\1e",[extended])),
- <<"vpACDe">> = iolist_to_binary(re:replace("ACDE","(A (A|B(*ACCEPT)|C) D)(E)","vp\\1e",[extended,
- global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(A (A|B(*ACCEPT)|C) D)(E)","YJgvKXOIgucMHsvWUdgN",[extended])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(A (A|B(*ACCEPT)|C) D)(E)","YJgvKXOIgucMHsvWUdgN",[extended,
- global])),
- <<"AD">> = iolist_to_binary(re:replace("AD","(A (A|B(*ACCEPT)|C) D)(E)","ssJb&\\1nwuF&t",[extended])),
- <<"AD">> = iolist_to_binary(re:replace("AD","(A (A|B(*ACCEPT)|C) D)(E)","ssJb&\\1nwuF&t",[extended,
- global])),
- <<"AjVOUn">> = iolist_to_binary(re:replace("1221","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","AjVOUn",[caseless])),
- <<"AjVOUn">> = iolist_to_binary(re:replace("1221","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","AjVOUn",[caseless,
- global])),
- <<"BDdMi">> = iolist_to_binary(re:replace("Satan, oscillate my metallic sonatas!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","B\\1DdMi",[caseless])),
- <<"BDdMi">> = iolist_to_binary(re:replace("Satan, oscillate my metallic sonatas!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","B\\1DdMi",[caseless,
- global])),
- <<"YfFtA man, a plan, a canal: Panama!pwRSbpA man, a plan, a canal: Panama!">> = iolist_to_binary(re:replace("A man, a plan, a canal: Panama!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","YfFt\\1&\\1pwRSb\\1p&",[caseless])),
- <<"YfFtA man, a plan, a canal: Panama!pwRSbpA man, a plan, a canal: Panama!">> = iolist_to_binary(re:replace("A man, a plan, a canal: Panama!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","YfFt\\1&\\1pwRSb\\1p&",[caseless,
- global])),
- <<"xvAble was I ere I saw Elba.HqjQAble was I ere I saw Elba.vR">> = iolist_to_binary(re:replace("Able was I ere I saw Elba.","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","x\\1v&HqjQ&vR",[caseless])),
- <<"xvAble was I ere I saw Elba.HqjQAble was I ere I saw Elba.vR">> = iolist_to_binary(re:replace("Able was I ere I saw Elba.","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","x\\1v&HqjQ&vR",[caseless,
- global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","\\1JH",[caseless])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","\\1JH",[caseless,
- global])),
- <<"The quick brown fox">> = iolist_to_binary(re:replace("The quick brown fox","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","GCnEOe&\\1HfW&",[caseless])),
- <<"The quick brown fox">> = iolist_to_binary(re:replace("The quick brown fox","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","GCnEOe&\\1HfW&",[caseless,
- global])),
- <<"EEBtpaXa">> = iolist_to_binary(re:replace("a","^((.)(?1)\\2|.)$","EEBtpaX\\1",[])),
- <<"EEBtpaXa">> = iolist_to_binary(re:replace("a","^((.)(?1)\\2|.)$","EEBtpaX\\1",[global])),
- <<"qXEWopOY">> = iolist_to_binary(re:replace("aba","^((.)(?1)\\2|.)$","qXEWopOY",[])),
- <<"qXEWopOY">> = iolist_to_binary(re:replace("aba","^((.)(?1)\\2|.)$","qXEWopOY",[global])),
- <<"fQRaabaaaabaaaabaavgdtLaabaaijxUaabaaV">> = iolist_to_binary(re:replace("aabaa","^((.)(?1)\\2|.)$","fQR\\1\\1&vgdtL\\1ijxU\\1V",[])),
- <<"fQRaabaaaabaaaabaavgdtLaabaaijxUaabaaV">> = iolist_to_binary(re:replace("aabaa","^((.)(?1)\\2|.)$","fQR\\1\\1&vgdtL\\1ijxU\\1V",[global])),
- <<"rfIabcdcbaQmGUaQxwnGtIhc">> = iolist_to_binary(re:replace("abcdcba","^((.)(?1)\\2|.)$","rfI&QmGUaQxwnGtIhc",[])),
- <<"rfIabcdcbaQmGUaQxwnGtIhc">> = iolist_to_binary(re:replace("abcdcba","^((.)(?1)\\2|.)$","rfI&QmGUaQxwnGtIhc",[global])),
- <<"QEpqaabaaqpcpqaabaaqpmxcBpqaabaaqpfErt">> = iolist_to_binary(re:replace("pqaabaaqp","^((.)(?1)\\2|.)$","QE\\1c\\1mxcB&fErt",[])),
- <<"QEpqaabaaqpcpqaabaaqpmxcBpqaabaaqpfErt">> = iolist_to_binary(re:replace("pqaabaaqp","^((.)(?1)\\2|.)$","QE\\1c\\1mxcB&fErt",[global])),
- <<"KLFablewasiereisawelbaablewasiereisawelbaIablewasiereisawelbarjablewasiereisawelbasD">> = iolist_to_binary(re:replace("ablewasiereisawelba","^((.)(?1)\\2|.)$","KLF\\1&I&rj&sD",[])),
- <<"KLFablewasiereisawelbaablewasiereisawelbaIablewasiereisawelbarjablewasiereisawelbasD">> = iolist_to_binary(re:replace("ablewasiereisawelba","^((.)(?1)\\2|.)$","KLF\\1&I&rj&sD",[global])),
- <<"rhubarb">> = iolist_to_binary(re:replace("rhubarb","^((.)(?1)\\2|.)$","g\\1WKOnON\\1\\1YO\\1\\1Uj\\1F",[])),
- <<"rhubarb">> = iolist_to_binary(re:replace("rhubarb","^((.)(?1)\\2|.)$","g\\1WKOnON\\1\\1YO\\1\\1Uj\\1F",[global])),
- <<"the quick brown fox">> = iolist_to_binary(re:replace("the quick brown fox","^((.)(?1)\\2|.)$","JgofHErdXPIu\\1&",[])),
- <<"the quick brown fox">> = iolist_to_binary(re:replace("the quick brown fox","^((.)(?1)\\2|.)$","JgofHErdXPIu\\1&",[global])),
- <<"bKFgOfuwLfpxaHaJaz">> = iolist_to_binary(re:replace("baz","(a)(?<=b(?1))","KFgOfuwLfpx&H\\1J\\1",[])),
- <<"bKFgOfuwLfpxaHaJaz">> = iolist_to_binary(re:replace("baz","(a)(?<=b(?1))","KFgOfuwLfpx&H\\1J\\1",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)(?<=b(?1))","i\\1&j&",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)(?<=b(?1))","i\\1&j&",[global])),
- <<"caz">> = iolist_to_binary(re:replace("caz","(a)(?<=b(?1))","l&U&&H&t&",[])),
- <<"caz">> = iolist_to_binary(re:replace("caz","(a)(?<=b(?1))","l&U&&H&t&",[global])),
- <<"zbaakOqTqMsiTyaSGadz">> = iolist_to_binary(re:replace("zbaaz","(?<=b(?1))(a)","\\1kOqTqMsiTy\\1SG&d",[])),
- <<"zbaakOqTqMsiTyaSGadz">> = iolist_to_binary(re:replace("zbaaz","(?<=b(?1))(a)","\\1kOqTqMsiTy\\1SG&d",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=b(?1))(a)","\\1osY\\1treCMjxk&Af",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=b(?1))(a)","\\1osY\\1treCMjxk&Af",[global])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","(?<=b(?1))(a)","ykA&qS&nno",[])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","(?<=b(?1))(a)","ykA&qS&nno",[global])),
- <<"baOKaGPxYz">> = iolist_to_binary(re:replace("baz","(?<X>a)(?<=b(?&X))","\\1OK&GPxY",[])),
- <<"baOKaGPxYz">> = iolist_to_binary(re:replace("baz","(?<X>a)(?<=b(?&X))","\\1OK&GPxY",[global])),
+ <<"YRKO">> = iolist_to_binary(re:replace("<abcd>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","YRKO",[extended])),
+ <<"YRKO">> = iolist_to_binary(re:replace("<abcd>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","YRKO",[extended,
+ global])),
+ <<"BraUcvnkvGpATS<abc <123> hij>jqC">> = iolist_to_binary(re:replace("<abc <123> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","BraUcvnkvGpATS&jqC",[extended])),
+ <<"BraUcvnkvGpATS<abc <123> hij>jqC">> = iolist_to_binary(re:replace("<abc <123> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","BraUcvnkvGpATS&jqC",[extended,
+ global])),
+ <<"<abc SvwukU<def>xY<def>tL<def>WM<def>johX hij>">> = iolist_to_binary(re:replace("<abc <def> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","SvwukU&xY&tL&WM\\1johX",[extended])),
+ <<"<abc SvwukU<def>xY<def>tL<def>WM<def>johX hij>">> = iolist_to_binary(re:replace("<abc <def> hij>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","SvwukU&xY&tL&WM\\1johX",[extended,
+ global])),
+ <<"nrGC<abc<>def>R">> = iolist_to_binary(re:replace("<abc<>def>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","nrGC&R",[extended])),
+ <<"nrGC<abc<>def>R">> = iolist_to_binary(re:replace("<abc<>def>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","nrGC&R",[extended,
+ global])),
+ <<"<abcqCRcTne<>iv<>sCXFrnd">> = iolist_to_binary(re:replace("<abc<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","qCRcTne&iv&sCXFrnd",[extended])),
+ <<"<abcqCRcTne<>iv<>sCXFrnd">> = iolist_to_binary(re:replace("<abc<>","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","qCRcTne&iv&sCXFrnd",[extended,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","\\1b&ult&hg\\1P",[extended])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","\\1b&ult&hg\\1P",[extended,
+ global])),
+ <<"<abc">> = iolist_to_binary(re:replace("<abc","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","tRwOvxXk\\1pyskS\\1n",[extended])),
+ <<"<abc">> = iolist_to_binary(re:replace("<abc","((< (?: (?(R) \\d++ | [^<>]*+) | (?2)) * >))","tRwOvxXk\\1pyskS\\1n",[extended,
+ global])),
+ <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^a+(*FAIL)","gLGD",[])),
+ <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^a+(*FAIL)","gLGD",[global])),
+ <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?c+(*FAIL)","e\\1SW&\\1gEu\\1WBl",[])),
+ <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?c+(*FAIL)","e\\1SW&\\1gEu\\1WBl",[global])),
+ <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*PRUNE)c+(*FAIL)","Cy",[])),
+ <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*PRUNE)c+(*FAIL)","Cy",[global])),
+ <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*COMMIT)c+(*FAIL)","lCKqNoFrmqk",[])),
+ <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*COMMIT)c+(*FAIL)","lCKqNoFrmqk",[global])),
+ <<"aaabcccaaabccc">> = iolist_to_binary(re:replace("aaabcccaaabccc","a+b?(*SKIP)c+(*FAIL)","gh\\1A&NTPGyR\\1C&",[])),
+ <<"aaabcccaaabccc">> = iolist_to_binary(re:replace("aaabcccaaabccc","a+b?(*SKIP)c+(*FAIL)","gh\\1A&NTPGyR\\1C&",[global])),
+ <<"IUaaaxxxxxxP">> = iolist_to_binary(re:replace("aaaxxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","IU&P",[])),
+ <<"IUaaaxxxxxxP">> = iolist_to_binary(re:replace("aaaxxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","IU&P",[global])),
+ <<"hdKDpy++++++">> = iolist_to_binary(re:replace("aaa++++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","hdKDpy",[])),
+ <<"hdKDpy++++++">> = iolist_to_binary(re:replace("aaa++++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","hdKDpy",[global])),
+ <<"nAXgVEbbbxxxxxhYFcyFVwuV">> = iolist_to_binary(re:replace("bbbxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","nAX\\1gVE&hYF\\1cy\\1FVwuV",[])),
+ <<"nAXgVEbbbxxxxxhYFcyFVwuV">> = iolist_to_binary(re:replace("bbbxxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","nAX\\1gVE&hYF\\1cy\\1FVwuV",[global])),
+ <<"jM+++++">> = iolist_to_binary(re:replace("bbb+++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","jM",[])),
+ <<"jM+++++">> = iolist_to_binary(re:replace("bbb+++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","jM",[global])),
+ <<"xqHG">> = iolist_to_binary(re:replace("cccxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","xqHG",[])),
+ <<"xqHG">> = iolist_to_binary(re:replace("cccxxxx","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","xqHG",[global])),
+ <<"GeWPQyGcccAhlBccccx++++">> = iolist_to_binary(re:replace("ccc++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","GeWPQyG&Ahl\\1Bc&x",[])),
+ <<"GeWPQyGcccAhlBccccx++++">> = iolist_to_binary(re:replace("ccc++++","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","GeWPQyG&Ahl\\1Bc&x",[global])),
+ <<"dNWERdddBmdddlSrdddddd">> = iolist_to_binary(re:replace("dddddddd","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","dNWE\\1R&Bm&\\1lSrd",[])),
+ <<"dNWERdddBmdddlSrdddddd">> = iolist_to_binary(re:replace("dddddddd","^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","dNWE\\1R&Bm&\\1lSrd",[global])),
+ <<"aaaxxxxxxaaaxxxxxxaaaxxxxxxXAFhdfF">> = iolist_to_binary(re:replace("aaaxxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","&\\1&XAFhdfF",[])),
+ <<"aaaxxxxxxaaaxxxxxxaaaxxxxxxXAFhdfF">> = iolist_to_binary(re:replace("aaaxxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","&\\1&XAFhdfF",[global])),
+ <<"BADWi++++++">> = iolist_to_binary(re:replace("aaa++++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","BADWi",[])),
+ <<"BADWi++++++">> = iolist_to_binary(re:replace("aaa++++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","BADWi",[global])),
+ <<"iGhbbbxxxxxY">> = iolist_to_binary(re:replace("bbbxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","iGh&Y",[])),
+ <<"iGhbbbxxxxxY">> = iolist_to_binary(re:replace("bbbxxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","iGh&Y",[global])),
+ <<"o+++++">> = iolist_to_binary(re:replace("bbb+++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","o",[])),
+ <<"o+++++">> = iolist_to_binary(re:replace("bbb+++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","o",[global])),
+ <<"cccxxxxYEHecccxxxxcccxxxxIOtAN">> = iolist_to_binary(re:replace("cccxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","\\1YEHe\\1\\1IOtAN",[])),
+ <<"cccxxxxYEHecccxxxxcccxxxxIOtAN">> = iolist_to_binary(re:replace("cccxxxx","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","\\1YEHe\\1\\1IOtAN",[global])),
+ <<"RgcccpccccCrLGccccccGS++++">> = iolist_to_binary(re:replace("ccc++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","Rg\\1p&cCrLG\\1\\1GS",[])),
+ <<"RgcccpccccCrLGccccccGS++++">> = iolist_to_binary(re:replace("ccc++++","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","Rg\\1p&cCrLG\\1\\1GS",[global])),
+ <<"aJddddd">> = iolist_to_binary(re:replace("dddddddd","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","aJ",[])),
+ <<"aJddddd">> = iolist_to_binary(re:replace("dddddddd","^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})","aJ",[global])),
+ <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*THEN)c+(*FAIL)","O&n",[])),
+ <<"aaabccc">> = iolist_to_binary(re:replace("aaabccc","a+b?(*THEN)c+(*FAIL)","O&n",[global])),
+ <<"TxOFuVua">> = iolist_to_binary(re:replace("AB","(A (A|B(*ACCEPT)|C) D)(E)","TxOFuVua",[extended])),
+ <<"TxOFuVua">> = iolist_to_binary(re:replace("AB","(A (A|B(*ACCEPT)|C) D)(E)","TxOFuVua",[extended,
+ global])),
+ <<"SUX">> = iolist_to_binary(re:replace("ABX","(A (A|B(*ACCEPT)|C) D)(E)","SU",[extended])),
+ <<"SUX">> = iolist_to_binary(re:replace("ABX","(A (A|B(*ACCEPT)|C) D)(E)","SU",[extended,
+ global])),
+ <<"AADAADAADELrNAADnAADEnGvAADEaNIaWn">> = iolist_to_binary(re:replace("AADE","(A (A|B(*ACCEPT)|C) D)(E)","\\1\\1&LrN\\1n&nGv&aNIaWn",[extended])),
+ <<"AADAADAADELrNAADnAADEnGvAADEaNIaWn">> = iolist_to_binary(re:replace("AADE","(A (A|B(*ACCEPT)|C) D)(E)","\\1\\1&LrN\\1n&nGv&aNIaWn",[extended,
+ global])),
+ <<"ACDYODJodgCmmfKwfACD">> = iolist_to_binary(re:replace("ACDE","(A (A|B(*ACCEPT)|C) D)(E)","\\1YODJodgCmmfKwf\\1",[extended])),
+ <<"ACDYODJodgCmmfKwfACD">> = iolist_to_binary(re:replace("ACDE","(A (A|B(*ACCEPT)|C) D)(E)","\\1YODJodgCmmfKwf\\1",[extended,
+ global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(A (A|B(*ACCEPT)|C) D)(E)","N\\1FtqpFbrL\\1Uwr&u",[extended])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(A (A|B(*ACCEPT)|C) D)(E)","N\\1FtqpFbrL\\1Uwr&u",[extended,
+ global])),
+ <<"AD">> = iolist_to_binary(re:replace("AD","(A (A|B(*ACCEPT)|C) D)(E)","\\1A\\1QPFrGi",[extended])),
+ <<"AD">> = iolist_to_binary(re:replace("AD","(A (A|B(*ACCEPT)|C) D)(E)","\\1A\\1QPFrGi",[extended,
+ global])),
+ <<"xw1221OijBNT1221R12211221">> = iolist_to_binary(re:replace("1221","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","xw\\1OijBNT\\1R\\1\\1",[caseless])),
+ <<"xw1221OijBNT1221R12211221">> = iolist_to_binary(re:replace("1221","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","xw\\1OijBNT\\1R\\1\\1",[caseless,
+ global])),
+ <<"Satan, oscillate my metallic sonatas!lqABSOBSatan, oscillate my metallic sonatas!">> = iolist_to_binary(re:replace("Satan, oscillate my metallic sonatas!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","&\\1lqABSOB&",[caseless])),
+ <<"Satan, oscillate my metallic sonatas!lqABSOBSatan, oscillate my metallic sonatas!">> = iolist_to_binary(re:replace("Satan, oscillate my metallic sonatas!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","&\\1lqABSOB&",[caseless,
+ global])),
+ <<"fUpPJGcmtHgPTjp">> = iolist_to_binary(re:replace("A man, a plan, a canal: Panama!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","fUpPJGc\\1mtHgP\\1Tjp",[caseless])),
+ <<"fUpPJGcmtHgPTjp">> = iolist_to_binary(re:replace("A man, a plan, a canal: Panama!","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","fUpPJGc\\1mtHgP\\1Tjp",[caseless,
+ global])),
+ <<"Able was I ere I saw Elba.pQyfPUbHSt">> = iolist_to_binary(re:replace("Able was I ere I saw Elba.","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","&pQyfPUb\\1HSt",[caseless])),
+ <<"Able was I ere I saw Elba.pQyfPUbHSt">> = iolist_to_binary(re:replace("Able was I ere I saw Elba.","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","&pQyfPUb\\1HSt",[caseless,
+ global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","QItD\\1t&XKbLqmp",[caseless])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","QItD\\1t&XKbLqmp",[caseless,
+ global])),
+ <<"The quick brown fox">> = iolist_to_binary(re:replace("The quick brown fox","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","HyrL&",[caseless])),
+ <<"The quick brown fox">> = iolist_to_binary(re:replace("The quick brown fox","^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$","HyrL&",[caseless,
+ global])),
+ <<"MUxDTa">> = iolist_to_binary(re:replace("a","^((.)(?1)\\2|.)$","MUxDT&",[])),
+ <<"MUxDTa">> = iolist_to_binary(re:replace("a","^((.)(?1)\\2|.)$","MUxDT&",[global])),
+ <<"sdabaq">> = iolist_to_binary(re:replace("aba","^((.)(?1)\\2|.)$","sd\\1q",[])),
+ <<"sdabaq">> = iolist_to_binary(re:replace("aba","^((.)(?1)\\2|.)$","sd\\1q",[global])),
+ <<"FQLjaabaaHLRNaabaaaabaat">> = iolist_to_binary(re:replace("aabaa","^((.)(?1)\\2|.)$","FQLj&HLRN\\1\\1t",[])),
+ <<"FQLjaabaaHLRNaabaaaabaat">> = iolist_to_binary(re:replace("aabaa","^((.)(?1)\\2|.)$","FQLj&HLRN\\1\\1t",[global])),
+ <<"dAayeabcdcbaBfabcdcbaUNI">> = iolist_to_binary(re:replace("abcdcba","^((.)(?1)\\2|.)$","dAaye\\1Bf&UNI",[])),
+ <<"dAayeabcdcbaBfabcdcbaUNI">> = iolist_to_binary(re:replace("abcdcba","^((.)(?1)\\2|.)$","dAaye\\1Bf&UNI",[global])),
+ <<"OpqaabaaqpQpqaabaaqpfkfGJxwpqaabaaqpxkmrGMpqaabaaqp">> = iolist_to_binary(re:replace("pqaabaaqp","^((.)(?1)\\2|.)$","O&Q\\1fkfGJxw&xkmrGM&",[])),
+ <<"OpqaabaaqpQpqaabaaqpfkfGJxwpqaabaaqpxkmrGMpqaabaaqp">> = iolist_to_binary(re:replace("pqaabaaqp","^((.)(?1)\\2|.)$","O&Q\\1fkfGJxw&xkmrGM&",[global])),
+ <<"bdVxablewasiereisawelbaYcoMDjqablewasiereisawelbafdablewasiereisawelbatinE">> = iolist_to_binary(re:replace("ablewasiereisawelba","^((.)(?1)\\2|.)$","bdVx&YcoMDjq&fd\\1tinE",[])),
+ <<"bdVxablewasiereisawelbaYcoMDjqablewasiereisawelbafdablewasiereisawelbatinE">> = iolist_to_binary(re:replace("ablewasiereisawelba","^((.)(?1)\\2|.)$","bdVx&YcoMDjq&fd\\1tinE",[global])),
+ <<"rhubarb">> = iolist_to_binary(re:replace("rhubarb","^((.)(?1)\\2|.)$","XD\\1&vY\\1SvD&NK&AfJ",[])),
+ <<"rhubarb">> = iolist_to_binary(re:replace("rhubarb","^((.)(?1)\\2|.)$","XD\\1&vY\\1SvD&NK&AfJ",[global])),
+ <<"the quick brown fox">> = iolist_to_binary(re:replace("the quick brown fox","^((.)(?1)\\2|.)$","MnEjDLxqRfD\\1dksvBNU",[])),
+ <<"the quick brown fox">> = iolist_to_binary(re:replace("the quick brown fox","^((.)(?1)\\2|.)$","MnEjDLxqRfD\\1dksvBNU",[global])),
+ <<"bSanz">> = iolist_to_binary(re:replace("baz","(a)(?<=b(?1))","S\\1n",[])),
+ <<"bSanz">> = iolist_to_binary(re:replace("baz","(a)(?<=b(?1))","S\\1n",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)(?<=b(?1))","I\\1&BaUakXjhOFhQy\\1kv",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)(?<=b(?1))","I\\1&BaUakXjhOFhQy\\1kv",[global])),
+ <<"caz">> = iolist_to_binary(re:replace("caz","(a)(?<=b(?1))","&x&&&cABhoecjW&D",[])),
+ <<"caz">> = iolist_to_binary(re:replace("caz","(a)(?<=b(?1))","&x&&&cABhoecjW&D",[global])),
+ <<"zbamBPamYeGJasagajz">> = iolist_to_binary(re:replace("zbaaz","(?<=b(?1))(a)","mBP\\1mYeGJ\\1s&g&j",[])),
+ <<"zbamBPamYeGJasagajz">> = iolist_to_binary(re:replace("zbaaz","(?<=b(?1))(a)","mBP\\1mYeGJ\\1s&g&j",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=b(?1))(a)","&y&R&ANqnrUXsC",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=b(?1))(a)","&y&R&ANqnrUXsC",[global])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","(?<=b(?1))(a)","F&&lb\\1OEkErh\\1&s\\1T",[])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","(?<=b(?1))(a)","F&&lb\\1OEkErh\\1&s\\1T",[global])),
+ <<"basaBtugJSalfoIoaaz">> = iolist_to_binary(re:replace("baz","(?<X>a)(?<=b(?&X))","\\1s&BtugJS\\1lfoIo\\1a",[])),
+ <<"basaBtugJSalfoIoaaz">> = iolist_to_binary(re:replace("baz","(?<X>a)(?<=b(?&X))","\\1s&BtugJS\\1lfoIo\\1a",[global])),
+ <<"abcabcdfYwAHcFyJUBIKabcabcabcabcabcabc">> = iolist_to_binary(re:replace("abcabc","^(?|(abc)|(def))\\1","&dfYwAHcFyJUBIK&&&",[])),
+ <<"abcabcdfYwAHcFyJUBIKabcabcabcabcabcabc">> = iolist_to_binary(re:replace("abcabc","^(?|(abc)|(def))\\1","&dfYwAHcFyJUBIK&&&",[global])),
+ <<"defdefewRuSdefdefb">> = iolist_to_binary(re:replace("defdef","^(?|(abc)|(def))\\1","&ewRuS&b",[])),
+ <<"defdefewRuSdefdefb">> = iolist_to_binary(re:replace("defdef","^(?|(abc)|(def))\\1","&ewRuS&b",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?|(abc)|(def))\\1","iOiPewDMrMw&Iy",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?|(abc)|(def))\\1","iOiPewDMrMw&Iy",[global])),
+ <<"abcdef">> = iolist_to_binary(re:replace("abcdef","^(?|(abc)|(def))\\1","rkSqOQ",[])),
+ <<"abcdef">> = iolist_to_binary(re:replace("abcdef","^(?|(abc)|(def))\\1","rkSqOQ",[global])),
+ <<"defabc">> = iolist_to_binary(re:replace("defabc","^(?|(abc)|(def))\\1","V",[])),
+ <<"defabc">> = iolist_to_binary(re:replace("defabc","^(?|(abc)|(def))\\1","V",[global])),
ok.
run43() ->
- <<"abckIo">> = iolist_to_binary(re:replace("abcabc","^(?|(abc)|(def))\\1","\\1kIo",[])),
- <<"abckIo">> = iolist_to_binary(re:replace("abcabc","^(?|(abc)|(def))\\1","\\1kIo",[global])),
- <<"sdefdefUbl">> = iolist_to_binary(re:replace("defdef","^(?|(abc)|(def))\\1","s&Ubl",[])),
- <<"sdefdefUbl">> = iolist_to_binary(re:replace("defdef","^(?|(abc)|(def))\\1","s&Ubl",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?|(abc)|(def))\\1","&m&bWQpRl",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?|(abc)|(def))\\1","&m&bWQpRl",[global])),
- <<"abcdef">> = iolist_to_binary(re:replace("abcdef","^(?|(abc)|(def))\\1","qwUmfoHo&tN",[])),
- <<"abcdef">> = iolist_to_binary(re:replace("abcdef","^(?|(abc)|(def))\\1","qwUmfoHo&tN",[global])),
- <<"defabc">> = iolist_to_binary(re:replace("defabc","^(?|(abc)|(def))\\1","KGoYhhlYddcruQ&k",[])),
- <<"defabc">> = iolist_to_binary(re:replace("defabc","^(?|(abc)|(def))\\1","KGoYhhlYddcruQ&k",[global])),
- <<"PdYfAnnabcPxabcabcHvAQabcabcabcabcabcls">> = iolist_to_binary(re:replace("abcabc","^(?|(abc)|(def))(?1)","PdYfAnn\\1Px&HvAQ&&\\1ls",[])),
- <<"PdYfAnnabcPxabcabcHvAQabcabcabcabcabcls">> = iolist_to_binary(re:replace("abcabc","^(?|(abc)|(def))(?1)","PdYfAnn\\1Px&HvAQ&&\\1ls",[global])),
- <<"PAdefabc">> = iolist_to_binary(re:replace("defabc","^(?|(abc)|(def))(?1)","PA&",[])),
- <<"PAdefabc">> = iolist_to_binary(re:replace("defabc","^(?|(abc)|(def))(?1)","PA&",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?|(abc)|(def))(?1)","Fqig",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?|(abc)|(def))(?1)","Fqig",[global])),
- <<"defdef">> = iolist_to_binary(re:replace("defdef","^(?|(abc)|(def))(?1)","e&yLb\\1&\\1D\\1q\\1UcBtn&",[])),
- <<"defdef">> = iolist_to_binary(re:replace("defdef","^(?|(abc)|(def))(?1)","e&yLb\\1&\\1D\\1q\\1UcBtn&",[global])),
- <<"abcdef">> = iolist_to_binary(re:replace("abcdef","^(?|(abc)|(def))(?1)","&\\1\\1\\1atTuOfcyl\\1RO&y",[])),
- <<"abcdef">> = iolist_to_binary(re:replace("abcdef","^(?|(abc)|(def))(?1)","&\\1\\1\\1atTuOfcyl\\1RO&y",[global])),
- <<"ACBCSBCTCMoOD">> = iolist_to_binary(re:replace("ABCD","(?:(?1)|B)(A(*F)|C)","C&S&T\\1MoO",[])),
- <<"ACBCSBCTCMoOD">> = iolist_to_binary(re:replace("ABCD","(?:(?1)|B)(A(*F)|C)","C&S&T\\1MoO",[global])),
- <<"bD">> = iolist_to_binary(re:replace("CCD","(?:(?1)|B)(A(*F)|C)","b",[])),
- <<"bD">> = iolist_to_binary(re:replace("CCD","(?:(?1)|B)(A(*F)|C)","b",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?:(?1)|B)(A(*F)|C)","u&dbYn\\1jVvV&V\\1XC",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?:(?1)|B)(A(*F)|C)","u&dbYn\\1jVvV&V\\1XC",[global])),
- <<"CAD">> = iolist_to_binary(re:replace("CAD","(?:(?1)|B)(A(*F)|C)","UbDT\\1DjcdPh",[])),
- <<"CAD">> = iolist_to_binary(re:replace("CAD","(?:(?1)|B)(A(*F)|C)","UbDT\\1DjcdPh",[global])),
- <<"CCahPD">> = iolist_to_binary(re:replace("CCD","^(?:(?1)|B)(A(*F)|C)","&ahP",[])),
- <<"CCahPD">> = iolist_to_binary(re:replace("CCD","^(?:(?1)|B)(A(*F)|C)","&ahP",[global])),
- <<"IYJaGD">> = iolist_to_binary(re:replace("BCD","^(?:(?1)|B)(A(*F)|C)","IYJaG",[])),
- <<"IYJaGD">> = iolist_to_binary(re:replace("BCD","^(?:(?1)|B)(A(*F)|C)","IYJaG",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:(?1)|B)(A(*F)|C)","uckGWWHQG&ocJD\\1l\\1T",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:(?1)|B)(A(*F)|C)","uckGWWHQG&ocJD\\1l\\1T",[global])),
- <<"ABCD">> = iolist_to_binary(re:replace("ABCD","^(?:(?1)|B)(A(*F)|C)","qbEQn",[])),
- <<"ABCD">> = iolist_to_binary(re:replace("ABCD","^(?:(?1)|B)(A(*F)|C)","qbEQn",[global])),
- <<"CAD">> = iolist_to_binary(re:replace("CAD","^(?:(?1)|B)(A(*F)|C)","kVqFM&D",[])),
- <<"CAD">> = iolist_to_binary(re:replace("CAD","^(?:(?1)|B)(A(*F)|C)","kVqFM&D",[global])),
- <<"BAD">> = iolist_to_binary(re:replace("BAD","^(?:(?1)|B)(A(*F)|C)","nKcCWd\\1",[])),
- <<"BAD">> = iolist_to_binary(re:replace("BAD","^(?:(?1)|B)(A(*F)|C)","nKcCWd\\1",[global])),
- <<"mCJFixrmAAAPiiNWHD">> = iolist_to_binary(re:replace("AAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","mCJFixrm&APiiNWH",[])),
- <<"mCJFixrmAAAPiiNWHD">> = iolist_to_binary(re:replace("AAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","mCJFixrm&APiiNWH",[global])),
- <<"fjOtIXCc">> = iolist_to_binary(re:replace("ACD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","fjOtIXCc",[])),
- <<"fjOtIXCc">> = iolist_to_binary(re:replace("ACD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","fjOtIXCc",[global])),
- <<"KSgQhFSAnBABD">> = iolist_to_binary(re:replace("BAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","KSgQhFS\\1n&B",[])),
- <<"KSgQhFSAnBABD">> = iolist_to_binary(re:replace("BAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","KSgQhFS\\1n&B",[global])),
- <<"KdBHaAwVPBCDCGCsRCBCD">> = iolist_to_binary(re:replace("BCD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","KdBHaAwVP&\\1G\\1sRC&",[])),
- <<"KdBHaAwVPBCDCGCsRCBCD">> = iolist_to_binary(re:replace("BCD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","KdBHaAwVP&\\1G\\1sRC&",[global])),
- <<"iaomqEcFWGhoDBAAnBAiCX">> = iolist_to_binary(re:replace("BAX","(?:(?1)|B)(A(*ACCEPT)XX|C)D","iaomqEcFWGhoD&\\1n&iC",[])),
- <<"iaomqEcFWGhoDBAAnBAiCX">> = iolist_to_binary(re:replace("BAX","(?:(?1)|B)(A(*ACCEPT)XX|C)D","iaomqEcFWGhoD&\\1n&iC",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?:(?1)|B)(A(*ACCEPT)XX|C)D","S\\1&OO",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?:(?1)|B)(A(*ACCEPT)XX|C)D","S\\1&OO",[global])),
- <<"ACX">> = iolist_to_binary(re:replace("ACX","(?:(?1)|B)(A(*ACCEPT)XX|C)D","F\\1&dqt",[])),
- <<"ACX">> = iolist_to_binary(re:replace("ACX","(?:(?1)|B)(A(*ACCEPT)XX|C)D","F\\1&dqt",[global])),
- <<"ABC">> = iolist_to_binary(re:replace("ABC","(?:(?1)|B)(A(*ACCEPT)XX|C)D","bL\\1I",[])),
- <<"ABC">> = iolist_to_binary(re:replace("ABC","(?:(?1)|B)(A(*ACCEPT)XX|C)D","bL\\1I",[global])),
- <<"h">> = iolist_to_binary(re:replace("BAC","(?(DEFINE)(A))B(?1)C","\\1h",[])),
- <<"h">> = iolist_to_binary(re:replace("BAC","(?(DEFINE)(A))B(?1)C","\\1h",[global])),
- <<"EiDCVEGlgEGIr">> = iolist_to_binary(re:replace("BAAC","(?(DEFINE)((A)\\2))B(?1)C","E\\1iD\\1C\\1V\\1EG\\1lgEGIr",[])),
- <<"EiDCVEGlgEGIr">> = iolist_to_binary(re:replace("BAAC","(?(DEFINE)((A)\\2))B(?1)C","E\\1iD\\1C\\1V\\1EG\\1lgEGIr",[global])),
- <<"u(ab(cd)ef)(ab(cd)ef)v(ab(cd)ef)M">> = iolist_to_binary(re:replace("(ab(cd)ef)","(?<pn> \\( ( [^()]++ | (?&pn) )* \\) )","u&\\1v&M",[extended])),
- <<"u(ab(cd)ef)(ab(cd)ef)v(ab(cd)ef)M">> = iolist_to_binary(re:replace("(ab(cd)ef)","(?<pn> \\( ( [^()]++ | (?&pn) )* \\) )","u&\\1v&M",[extended,
- global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?=a(*SKIP)b|ac)","EhJBenWdk&&",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?=a(*SKIP)b|ac)","EhJBenWdk&&",[global])),
- <<"ac">> = iolist_to_binary(re:replace("ac","^(?=a(*SKIP)b|ac)","DVmcudRK&vBXmqcVY",[])),
- <<"ac">> = iolist_to_binary(re:replace("ac","^(?=a(*SKIP)b|ac)","DVmcudRK&vBXmqcVY",[global])),
- <<"qxyHbdqjab">> = iolist_to_binary(re:replace("ab","^(?=a(*PRUNE)b)","qxyH&bdqj",[])),
- <<"qxyHbdqjab">> = iolist_to_binary(re:replace("ab","^(?=a(*PRUNE)b)","qxyH&bdqj",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?=a(*PRUNE)b)","qDd\\1UHvpsMvHI\\1gEx&d",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?=a(*PRUNE)b)","qDd\\1UHvpsMvHI\\1gEx&d",[global])),
- <<"ac">> = iolist_to_binary(re:replace("ac","^(?=a(*PRUNE)b)","mB\\1\\1R&\\1Ax",[])),
- <<"ac">> = iolist_to_binary(re:replace("ac","^(?=a(*PRUNE)b)","mB\\1\\1R&\\1Ax",[global])),
- <<"FpGwac">> = iolist_to_binary(re:replace("ac","^(?=a(*ACCEPT)b)","Fp\\1Gw",[])),
- <<"FpGwac">> = iolist_to_binary(re:replace("ac","^(?=a(*ACCEPT)b)","Fp\\1Gw",[global])),
- <<"abCqbtkqunCIvDxbdMM">> = iolist_to_binary(re:replace("ab","(?>a\\Kb)","&Cq&t\\1kqunCIvDx&dMM",[])),
- <<"abCqbtkqunCIvDxbdMM">> = iolist_to_binary(re:replace("ab","(?>a\\Kb)","&Cq&t\\1kqunCIvDx&dMM",[global])),
- <<"aAk">> = iolist_to_binary(re:replace("ab","((?>a\\Kb))","Ak",[])),
- <<"aAk">> = iolist_to_binary(re:replace("ab","((?>a\\Kb))","Ak",[global])),
- <<"anKUUUFwaxNFjPabNJd">> = iolist_to_binary(re:replace("ab","(a\\Kb)","nKUUUFwaxNFjP\\1NJd",[])),
- <<"anKUUUFwaxNFjPabNJd">> = iolist_to_binary(re:replace("ab","(a\\Kb)","nKUUUFwaxNFjP\\1NJd",[global])),
- <<"acuYfxPcxoRKaceSXk">> = iolist_to_binary(re:replace("ac","^a\\Kcz|ac","&uYfxPcxoRK\\1\\1&eSXk",[])),
- <<"acuYfxPcxoRKaceSXk">> = iolist_to_binary(re:replace("ac","^a\\Kcz|ac","&uYfxPcxoRK\\1\\1&eSXk",[global])),
- <<"abCSFabuababvPlR">> = iolist_to_binary(re:replace("ab","(?>a\\Kbz|ab)","\\1&CSF&u&&vPlR",[])),
- <<"abCSFabuababvPlR">> = iolist_to_binary(re:replace("ab","(?>a\\Kbz|ab)","\\1&CSF&u&&vPlR",[global])),
- <<"aomXuCuVpjjUFcrWQIR">> = iolist_to_binary(re:replace("ab","^(?&t)(?(DEFINE)(?<t>a\\Kb))$","omXuCuVpjjUFcrW\\1QIR",[])),
- <<"aomXuCuVpjjUFcrWQIR">> = iolist_to_binary(re:replace("ab","^(?&t)(?(DEFINE)(?<t>a\\Kb))$","omXuCuVpjjUFcrW\\1QIR",[global])),
- <<"a(b)clxcg">> = iolist_to_binary(re:replace("a(b)c","^([^()]|\\((?1)*\\))*$","&lx\\1g",[])),
- <<"a(b)clxcg">> = iolist_to_binary(re:replace("a(b)c","^([^()]|\\((?1)*\\))*$","&lx\\1g",[global])),
- <<"dUeBGa(b(c)d)emKya(b(c)d)e">> = iolist_to_binary(re:replace("a(b(c)d)e","^([^()]|\\((?1)*\\))*$","dU\\1BG&mKy&",[])),
- <<"dUeBGa(b(c)d)emKya(b(c)d)e">> = iolist_to_binary(re:replace("a(b(c)d)e","^([^()]|\\((?1)*\\))*$","dU\\1BG&mKy&",[global])),
- <<"cP00f0uN">> = iolist_to_binary(re:replace("0","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","cP&\\1f&uN",[])),
- <<"cP00f0uN">> = iolist_to_binary(re:replace("0","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","cP&\\1f&uN",[global])),
- <<"pV00MD00p00haFc00MG00qG">> = iolist_to_binary(re:replace("00","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","pV\\1MD\\1p\\1haFc&MG&qG",[])),
- <<"pV00MD00p00haFc00MG00qG">> = iolist_to_binary(re:replace("00","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","pV\\1MD\\1p\\1haFc&MG&qG",[global])),
- <<"GdBC0000INu00000000Y0000">> = iolist_to_binary(re:replace("0000","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","GdBC&INu&&Y&",[])),
- <<"GdBC0000INu00000000Y0000">> = iolist_to_binary(re:replace("0000","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","GdBC&INu&&Y&",[global])),
+ <<"LfjQyR">> = iolist_to_binary(re:replace("abcabc","^(?|(abc)|(def))(?1)","LfjQyR",[])),
+ <<"LfjQyR">> = iolist_to_binary(re:replace("abcabc","^(?|(abc)|(def))(?1)","LfjQyR",[global])),
+ <<"tWpTOWdefabcdefkdefabcYBc">> = iolist_to_binary(re:replace("defabc","^(?|(abc)|(def))(?1)","tWpTOW&\\1k&YBc",[])),
+ <<"tWpTOWdefabcdefkdefabcYBc">> = iolist_to_binary(re:replace("defabc","^(?|(abc)|(def))(?1)","tWpTOW&\\1k&YBc",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?|(abc)|(def))(?1)","&XvMpW",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?|(abc)|(def))(?1)","&XvMpW",[global])),
+ <<"defdef">> = iolist_to_binary(re:replace("defdef","^(?|(abc)|(def))(?1)","JS\\1AJl&S",[])),
+ <<"defdef">> = iolist_to_binary(re:replace("defdef","^(?|(abc)|(def))(?1)","JS\\1AJl&S",[global])),
+ <<"abcdef">> = iolist_to_binary(re:replace("abcdef","^(?|(abc)|(def))(?1)","s&",[])),
+ <<"abcdef">> = iolist_to_binary(re:replace("abcdef","^(?|(abc)|(def))(?1)","s&",[global])),
+ <<"ACIMaBCCCrtBCLBSuRcqDCrD">> = iolist_to_binary(re:replace("ABCD","(?:(?1)|B)(A(*F)|C)","\\1IMa&\\1\\1rt&LBSuRcqDCr",[])),
+ <<"ACIMaBCCCrtBCLBSuRcqDCrD">> = iolist_to_binary(re:replace("ABCD","(?:(?1)|B)(A(*F)|C)","\\1IMa&\\1\\1rt&LBSuRcqDCr",[global])),
+ <<"oCCiCCCkCfarCUTFD">> = iolist_to_binary(re:replace("CCD","(?:(?1)|B)(A(*F)|C)","o&i&\\1k\\1far\\1UTF",[])),
+ <<"oCCiCCCkCfarCUTFD">> = iolist_to_binary(re:replace("CCD","(?:(?1)|B)(A(*F)|C)","o&i&\\1k\\1far\\1UTF",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?:(?1)|B)(A(*F)|C)","fR\\1POKy&h\\1tsX",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?:(?1)|B)(A(*F)|C)","fR\\1POKy&h\\1tsX",[global])),
+ <<"CAD">> = iolist_to_binary(re:replace("CAD","(?:(?1)|B)(A(*F)|C)","&hH\\1XGD\\1tfghlx\\1",[])),
+ <<"CAD">> = iolist_to_binary(re:replace("CAD","(?:(?1)|B)(A(*F)|C)","&hH\\1XGD\\1tfghlx\\1",[global])),
+ <<"CCePUJnkSD">> = iolist_to_binary(re:replace("CCD","^(?:(?1)|B)(A(*F)|C)","&ePUJnkS",[])),
+ <<"CCePUJnkSD">> = iolist_to_binary(re:replace("CCD","^(?:(?1)|B)(A(*F)|C)","&ePUJnkS",[global])),
+ <<"HDSBCbcCRNYiEPlVoYXD">> = iolist_to_binary(re:replace("BCD","^(?:(?1)|B)(A(*F)|C)","HDS&bc\\1RNYiEPlVoYX",[])),
+ <<"HDSBCbcCRNYiEPlVoYXD">> = iolist_to_binary(re:replace("BCD","^(?:(?1)|B)(A(*F)|C)","HDS&bc\\1RNYiEPlVoYX",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:(?1)|B)(A(*F)|C)","S",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:(?1)|B)(A(*F)|C)","S",[global])),
+ <<"ABCD">> = iolist_to_binary(re:replace("ABCD","^(?:(?1)|B)(A(*F)|C)","jMfVoww\\1ses&oWOL&yd",[])),
+ <<"ABCD">> = iolist_to_binary(re:replace("ABCD","^(?:(?1)|B)(A(*F)|C)","jMfVoww\\1ses&oWOL&yd",[global])),
+ <<"CAD">> = iolist_to_binary(re:replace("CAD","^(?:(?1)|B)(A(*F)|C)","QqHTIgCo\\1&\\1\\1iIlqX&O",[])),
+ <<"CAD">> = iolist_to_binary(re:replace("CAD","^(?:(?1)|B)(A(*F)|C)","QqHTIgCo\\1&\\1\\1iIlqX&O",[global])),
+ <<"BAD">> = iolist_to_binary(re:replace("BAD","^(?:(?1)|B)(A(*F)|C)","fBLv",[])),
+ <<"BAD">> = iolist_to_binary(re:replace("BAD","^(?:(?1)|B)(A(*F)|C)","fBLv",[global])),
+ <<"lyLDABYgvAD">> = iolist_to_binary(re:replace("AAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","lyLD\\1BYgv\\1",[])),
+ <<"lyLDABYgvAD">> = iolist_to_binary(re:replace("AAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","lyLD\\1BYgv\\1",[global])),
+ <<"RyACDCXACDqsCvwyCACDkyHc">> = iolist_to_binary(re:replace("ACD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","Ry&\\1X&qs\\1vwy\\1&kyHc",[])),
+ <<"RyACDCXACDqsCvwyCACDkyHc">> = iolist_to_binary(re:replace("ACD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","Ry&\\1X&qs\\1vwy\\1&kyHc",[global])),
+ <<"AuXMduD">> = iolist_to_binary(re:replace("BAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","\\1uXMdu",[])),
+ <<"AuXMduD">> = iolist_to_binary(re:replace("BAD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","\\1uXMdu",[global])),
+ <<"oTbEDv">> = iolist_to_binary(re:replace("BCD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","oTbEDv",[])),
+ <<"oTbEDv">> = iolist_to_binary(re:replace("BCD","(?:(?1)|B)(A(*ACCEPT)XX|C)D","oTbEDv",[global])),
+ <<"RBAelTeYBABAAX">> = iolist_to_binary(re:replace("BAX","(?:(?1)|B)(A(*ACCEPT)XX|C)D","R&elTeY&&\\1",[])),
+ <<"RBAelTeYBABAAX">> = iolist_to_binary(re:replace("BAX","(?:(?1)|B)(A(*ACCEPT)XX|C)D","R&elTeY&&\\1",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?:(?1)|B)(A(*ACCEPT)XX|C)D","&&X\\1",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?:(?1)|B)(A(*ACCEPT)XX|C)D","&&X\\1",[global])),
+ <<"ACX">> = iolist_to_binary(re:replace("ACX","(?:(?1)|B)(A(*ACCEPT)XX|C)D","\\1YnMw&&&\\1Nxi&Wfb",[])),
+ <<"ACX">> = iolist_to_binary(re:replace("ACX","(?:(?1)|B)(A(*ACCEPT)XX|C)D","\\1YnMw&&&\\1Nxi&Wfb",[global])),
+ <<"ABC">> = iolist_to_binary(re:replace("ABC","(?:(?1)|B)(A(*ACCEPT)XX|C)D","eX\\1YNXkcuaal",[])),
+ <<"ABC">> = iolist_to_binary(re:replace("ABC","(?:(?1)|B)(A(*ACCEPT)XX|C)D","eX\\1YNXkcuaal",[global])),
+ <<"cpDBACdDivSoeWp">> = iolist_to_binary(re:replace("BAC","(?(DEFINE)(A))B(?1)C","cpD&dD\\1i\\1vSoeWp",[])),
+ <<"cpDBACdDivSoeWp">> = iolist_to_binary(re:replace("BAC","(?(DEFINE)(A))B(?1)C","cpD&dD\\1i\\1vSoeWp",[global])),
+ <<"HTBAAC">> = iolist_to_binary(re:replace("BAAC","(?(DEFINE)((A)\\2))B(?1)C","H\\1T&",[])),
+ <<"HTBAAC">> = iolist_to_binary(re:replace("BAAC","(?(DEFINE)((A)\\2))B(?1)C","H\\1T&",[global])),
+ <<"U(ab(cd)ef)Wy">> = iolist_to_binary(re:replace("(ab(cd)ef)","(?<pn> \\( ( [^()]++ | (?&pn) )* \\) )","U\\1Wy",[extended])),
+ <<"U(ab(cd)ef)Wy">> = iolist_to_binary(re:replace("(ab(cd)ef)","(?<pn> \\( ( [^()]++ | (?&pn) )* \\) )","U\\1Wy",[extended,
+ global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?=a(*SKIP)b|ac)","rGTH&RVHejd&k",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?=a(*SKIP)b|ac)","rGTH&RVHejd&k",[global])),
+ <<"ac">> = iolist_to_binary(re:replace("ac","^(?=a(*SKIP)b|ac)","\\1&GCt&D&Lja",[])),
+ <<"ac">> = iolist_to_binary(re:replace("ac","^(?=a(*SKIP)b|ac)","\\1&GCt&D&Lja",[global])),
+ <<"fQfwLkab">> = iolist_to_binary(re:replace("ab","^(?=a(*PRUNE)b)","f\\1QfwLk",[])),
+ <<"fQfwLkab">> = iolist_to_binary(re:replace("ab","^(?=a(*PRUNE)b)","f\\1QfwLk",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?=a(*PRUNE)b)","\\1yjrFT&QU\\1QP\\1&u",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?=a(*PRUNE)b)","\\1yjrFT&QU\\1QP\\1&u",[global])),
+ <<"ac">> = iolist_to_binary(re:replace("ac","^(?=a(*PRUNE)b)","&gpi\\1",[])),
+ <<"ac">> = iolist_to_binary(re:replace("ac","^(?=a(*PRUNE)b)","&gpi\\1",[global])),
+ <<"kQac">> = iolist_to_binary(re:replace("ac","^(?=a(*ACCEPT)b)","kQ",[])),
+ <<"kQac">> = iolist_to_binary(re:replace("ac","^(?=a(*ACCEPT)b)","kQ",[global])),
+ <<"ajbIblt">> = iolist_to_binary(re:replace("ab","(?>a\\Kb)","j&I&lt",[])),
+ <<"ajbIblt">> = iolist_to_binary(re:replace("ab","(?>a\\Kb)","j&I&lt",[global])),
+ <<"ajOfKabMbvu">> = iolist_to_binary(re:replace("ab","((?>a\\Kb))","jOfK\\1M&vu",[])),
+ <<"ajOfKabMbvu">> = iolist_to_binary(re:replace("ab","((?>a\\Kb))","jOfK\\1M&vu",[global])),
+ <<"aWbQSVababHodUgHSHnt">> = iolist_to_binary(re:replace("ab","(a\\Kb)","W&QSV\\1\\1HodUgHSHnt",[])),
+ <<"aWbQSVababHodUgHSHnt">> = iolist_to_binary(re:replace("ab","(a\\Kb)","W&QSV\\1\\1HodUgHSHnt",[global])),
+ <<"oyDWsqkcnuracWk">> = iolist_to_binary(re:replace("ac","^a\\Kcz|ac","oyDWsqkc\\1nur&\\1Wk",[])),
+ <<"oyDWsqkcnuracWk">> = iolist_to_binary(re:replace("ac","^a\\Kcz|ac","oyDWsqkc\\1nur&\\1Wk",[global])),
+ <<"drmFabyB">> = iolist_to_binary(re:replace("ab","(?>a\\Kbz|ab)","dr\\1mF&yB",[])),
+ <<"drmFabyB">> = iolist_to_binary(re:replace("ab","(?>a\\Kbz|ab)","dr\\1mF&yB",[global])),
+ <<"ajbVLbJkkPEEGEA">> = iolist_to_binary(re:replace("ab","^(?&t)(?(DEFINE)(?<t>a\\Kb))$","j\\1&VL&Jk\\1kPEE\\1G\\1E\\1A",[])),
+ <<"ajbVLbJkkPEEGEA">> = iolist_to_binary(re:replace("ab","^(?&t)(?(DEFINE)(?<t>a\\Kb))$","j\\1&VL&Jk\\1kPEE\\1G\\1E\\1A",[global])),
+ <<"Ua(b)c">> = iolist_to_binary(re:replace("a(b)c","^([^()]|\\((?1)*\\))*$","U&",[])),
+ <<"Ua(b)c">> = iolist_to_binary(re:replace("a(b)c","^([^()]|\\((?1)*\\))*$","U&",[global])),
+ <<"a(b(c)d)eU">> = iolist_to_binary(re:replace("a(b(c)d)e","^([^()]|\\((?1)*\\))*$","&U",[])),
+ <<"a(b(c)d)eU">> = iolist_to_binary(re:replace("a(b(c)d)e","^([^()]|\\((?1)*\\))*$","&U",[global])),
+ <<"Wc00ens">> = iolist_to_binary(re:replace("0","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","Wc&\\1ens",[])),
+ <<"Wc00ens">> = iolist_to_binary(re:replace("0","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","Wc&\\1ens",[global])),
+ <<"ot">> = iolist_to_binary(re:replace("00","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","ot",[])),
+ <<"ot">> = iolist_to_binary(re:replace("00","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","ot",[global])),
+ <<"TKKhmnqB0000j0000hwMe000000000000">> = iolist_to_binary(re:replace("0000","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","TKKhmnqB&j\\1hwMe&&&",[])),
+ <<"TKKhmnqB0000j0000hwMe000000000000">> = iolist_to_binary(re:replace("0000","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))","TKKhmnqB&j\\1hwMe&&&",[global])),
+ <<"A0FKEFFLo0gFNc0ISDNV">> = iolist_to_binary(re:replace("0","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","A&FKEFFLo&gFNc&ISDNV",[])),
+ <<"A0FKEFFLo0gFNc0ISDNV">> = iolist_to_binary(re:replace("0","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","A&FKEFFLo&gFNc&ISDNV",[global])),
+ <<"gbEHUma0JEum0t0TGBi0">> = iolist_to_binary(re:replace("00","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","gbEHUma\\1JEum\\1t\\1TGBi",[])),
+ <<"gbEHUma0JEum0t0TGBigbEHUma0JEum0t0TGBi">> = iolist_to_binary(re:replace("00","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","gbEHUma\\1JEum\\1t\\1TGBi",[global])),
+ <<"Mfh0OrMhJ0C00sj0000">> = iolist_to_binary(re:replace("0000","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","Mfh&OrMhJ&C&\\1sj&",[])),
+ <<"Mfh0OrMhJ0C00sj0Mfh0OrMhJ0C00sj0Mfh0OrMhJ0C00sj0Mfh0OrMhJ0C00sj0">> = iolist_to_binary(re:replace("0000","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","Mfh&OrMhJ&C&\\1sj&",[global])),
ok.
run44() ->
- <<"00RwFP">> = iolist_to_binary(re:replace("0","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","&&RwFP",[])),
- <<"00RwFP">> = iolist_to_binary(re:replace("0","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","&&RwFP",[global])),
- <<"TIRVuPlNk0">> = iolist_to_binary(re:replace("00","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","TIRVuPlNk",[])),
- <<"TIRVuPlNkTIRVuPlNk">> = iolist_to_binary(re:replace("00","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","TIRVuPlNk",[global])),
- <<"0IxIBm0KbqqiO000">> = iolist_to_binary(re:replace("0000","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","&IxIBm&KbqqiO",[])),
- <<"0IxIBm0KbqqiO0IxIBm0KbqqiO0IxIBm0KbqqiO0IxIBm0KbqqiO">> = iolist_to_binary(re:replace("0000","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))","&IxIBm&KbqqiO",[global])),
- <<"ACABX">> = iolist_to_binary(re:replace("ACABX","A(*COMMIT)(B|D)","\\1&&\\1KWXWa",[])),
- <<"ACABX">> = iolist_to_binary(re:replace("ACABX","A(*COMMIT)(B|D)","\\1&&\\1KWXWa",[global])),
- <<"ABCgPYRRqRBOrABCABCAHBQDEFG">> = iolist_to_binary(re:replace("ABCDEFG","(*COMMIT)(A|P)(B|P)(C|P)","&gPYRRqRBOr&&\\1HBQ",[])),
- <<"ABCgPYRRqRBOrABCABCAHBQDEFG">> = iolist_to_binary(re:replace("ABCDEFG","(*COMMIT)(A|P)(B|P)(C|P)","&gPYRRqRBOr&&\\1HBQ",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(*COMMIT)(A|P)(B|P)(C|P)","awq\\1dexeIK&rKgbPrqk",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(*COMMIT)(A|P)(B|P)(C|P)","awq\\1dexeIK&rKgbPrqk",[global])),
- <<"DEFGABC">> = iolist_to_binary(re:replace("DEFGABC","(*COMMIT)(A|P)(B|P)(C|P)","NRfdYIv\\1HtrT",[])),
- <<"DEFGABC">> = iolist_to_binary(re:replace("DEFGABC","(*COMMIT)(A|P)(B|P)(C|P)","NRfdYIv\\1HtrT",[global])),
- <<"jYabbbAGmvaabbbXabbbTAaixGp">> = iolist_to_binary(re:replace("abbb","(\\w+)(?>b(*COMMIT))\\w{2}","jY&AGmv\\1&X&TA\\1ixGp",[])),
- <<"jYabbbAGmvaabbbXabbbTAaixGp">> = iolist_to_binary(re:replace("abbb","(\\w+)(?>b(*COMMIT))\\w{2}","jY&AGmv\\1&X&TA\\1ixGp",[global])),
- <<"abbb">> = iolist_to_binary(re:replace("abbb","(\\w+)b(*COMMIT)\\w{2}","\\1mM",[])),
- <<"abbb">> = iolist_to_binary(re:replace("abbb","(\\w+)b(*COMMIT)\\w{2}","\\1mM",[global])),
- <<"bofPRc">> = iolist_to_binary(re:replace("bac","(?&t)(?#()(?(DEFINE)(?<t>a))","ofPR",[])),
- <<"bofPRc">> = iolist_to_binary(re:replace("bac","(?&t)(?#()(?(DEFINE)(?<t>a))","ofPR",[global])),
- <<"yes">> = iolist_to_binary(re:replace("yes","(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?","&ItXS\\1Uh&ueLGo\\1AKJxK",[])),
- <<"yes">> = iolist_to_binary(re:replace("yes","(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?","&ItXS\\1Uh&ueLGo\\1AKJxK",[global])),
- <<"yes">> = iolist_to_binary(re:replace("yes","(?>(*COMMIT)(yes|no)(*THEN)(*F))?","VnOG&\\1W",[])),
- <<"yes">> = iolist_to_binary(re:replace("yes","(?>(*COMMIT)(yes|no)(*THEN)(*F))?","VnOG&\\1W",[global])),
+ <<"ACABX">> = iolist_to_binary(re:replace("ACABX","A(*COMMIT)(B|D)","RuGESUvQDVqs",[])),
+ <<"ACABX">> = iolist_to_binary(re:replace("ACABX","A(*COMMIT)(B|D)","RuGESUvQDVqs",[global])),
+ <<"AABCQYABCchASpSgMsjmJDEFG">> = iolist_to_binary(re:replace("ABCDEFG","(*COMMIT)(A|P)(B|P)(C|P)","\\1&QY&ch\\1SpSgMsjmJ",[])),
+ <<"AABCQYABCchASpSgMsjmJDEFG">> = iolist_to_binary(re:replace("ABCDEFG","(*COMMIT)(A|P)(B|P)(C|P)","\\1&QY&ch\\1SpSgMsjmJ",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(*COMMIT)(A|P)(B|P)(C|P)","OnYL&y&\\1\\1YaeL&Rp&Bh",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(*COMMIT)(A|P)(B|P)(C|P)","OnYL&y&\\1\\1YaeL&Rp&Bh",[global])),
+ <<"DEFGABC">> = iolist_to_binary(re:replace("DEFGABC","(*COMMIT)(A|P)(B|P)(C|P)","oeob&",[])),
+ <<"DEFGABC">> = iolist_to_binary(re:replace("DEFGABC","(*COMMIT)(A|P)(B|P)(C|P)","oeob&",[global])),
+ <<"axGkabbbGcWn">> = iolist_to_binary(re:replace("abbb","(\\w+)(?>b(*COMMIT))\\w{2}","axGk&GcWn",[])),
+ <<"axGkabbbGcWn">> = iolist_to_binary(re:replace("abbb","(\\w+)(?>b(*COMMIT))\\w{2}","axGk&GcWn",[global])),
+ <<"abbb">> = iolist_to_binary(re:replace("abbb","(\\w+)b(*COMMIT)\\w{2}","lC\\1",[])),
+ <<"abbb">> = iolist_to_binary(re:replace("abbb","(\\w+)b(*COMMIT)\\w{2}","lC\\1",[global])),
+ <<"bRbYbpaRdHcFNHavc">> = iolist_to_binary(re:replace("bac","(?&t)(?#()(?(DEFINE)(?<t>a))","\\1RbYbp\\1&\\1R\\1dHcFNH&v\\1",[])),
+ <<"bRbYbpaRdHcFNHavc">> = iolist_to_binary(re:replace("bac","(?&t)(?#()(?(DEFINE)(?<t>a))","\\1RbYbp\\1&\\1R\\1dHcFNH&v\\1",[global])),
+ <<"yes">> = iolist_to_binary(re:replace("yes","(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?","C\\1&LrSNg",[])),
+ <<"yes">> = iolist_to_binary(re:replace("yes","(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?","C\\1&LrSNg",[global])),
+ <<"yes">> = iolist_to_binary(re:replace("yes","(?>(*COMMIT)(yes|no)(*THEN)(*F))?","nLsXq",[])),
+ <<"yes">> = iolist_to_binary(re:replace("yes","(?>(*COMMIT)(yes|no)(*THEN)(*F))?","nLsXq",[global])),
+ <<"ifJxMRlgahWwjbcUG">> = iolist_to_binary(re:replace("bc","b?(*SKIP)c","ifJxMRlgah\\1Wwj&U\\1G",[])),
+ <<"ifJxMRlgahWwjbcUG">> = iolist_to_binary(re:replace("bc","b?(*SKIP)c","ifJxMRlgah\\1Wwj&U\\1G",[global])),
+ <<"aFcoMMtM">> = iolist_to_binary(re:replace("abc","b?(*SKIP)c","FcoMMtM",[])),
+ <<"aFcoMMtM">> = iolist_to_binary(re:replace("abc","b?(*SKIP)c","FcoMMtM",[global])),
ok.
run45() ->
- <<"LVLUbcejbciMOvVvY">> = iolist_to_binary(re:replace("bc","b?(*SKIP)c","LV\\1LU&ej&iMOvVvY",[])),
- <<"LVLUbcejbciMOvVvY">> = iolist_to_binary(re:replace("bc","b?(*SKIP)c","LV\\1LU&ej&iMOvVvY",[global])),
- <<"aHUUUhKBfPpjU">> = iolist_to_binary(re:replace("abc","b?(*SKIP)c","\\1HUUUhKBf\\1P\\1pjU",[])),
- <<"aHUUUhKBfPpjU">> = iolist_to_binary(re:replace("abc","b?(*SKIP)c","\\1HUUUhKBf\\1P\\1pjU",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","(*SKIP)bc","\\1F&mJF",[])),
- <<"a">> = iolist_to_binary(re:replace("a","(*SKIP)bc","\\1F&mJF",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","(*SKIP)b","P\\1EF",[])),
- <<"a">> = iolist_to_binary(re:replace("a","(*SKIP)b","P\\1EF",[global])),
- <<"EiQojDQBehRidDoNAxxx">> = iolist_to_binary(re:replace("xxx","(?P<abn>(?P=abn)xxx|)+","EiQojDQBehRidDoNA",[])),
- <<"EiQojDQBehRidDoNAxEiQojDQBehRidDoNAxEiQojDQBehRidDoNAxEiQojDQBehRidDoNA">> = iolist_to_binary(re:replace("xxx","(?P<abn>(?P=abn)xxx|)+","EiQojDQBehRidDoNA",[global])),
- <<"akmvYT">> = iolist_to_binary(re:replace("aa","(?i:([^b]))(?1)","akmvYT",[])),
- <<"akmvYT">> = iolist_to_binary(re:replace("aa","(?i:([^b]))(?1)","akmvYT",[global])),
- <<"alaAraWMaaaAKIgQdaAOaF">> = iolist_to_binary(re:replace("aA","(?i:([^b]))(?1)","\\1l&r\\1WM\\1\\1&KIgQd&O\\1F",[])),
- <<"alaAraWMaaaAKIgQdaAOaF">> = iolist_to_binary(re:replace("aA","(?i:([^b]))(?1)","\\1l&r\\1WM\\1\\1&KIgQd&O\\1F",[global])),
- <<"*XAfh**hlh Failers">> = iolist_to_binary(re:replace("** Failers","(?i:([^b]))(?1)","\\1XAfh&hlh",[])),
- <<"*XAfh**hlh XAfh FhlhaXAfhaihlhlXAfhlehlhrXAfhrshlh">> = iolist_to_binary(re:replace("** Failers","(?i:([^b]))(?1)","\\1XAfh&hlh",[global])),
- <<"ab">> = iolist_to_binary(re:replace("ab","(?i:([^b]))(?1)","e\\1eCmoSn",[])),
- <<"ab">> = iolist_to_binary(re:replace("ab","(?i:([^b]))(?1)","e\\1eCmoSn",[global])),
- <<"aB">> = iolist_to_binary(re:replace("aB","(?i:([^b]))(?1)","hiocPQeyl&&Nx\\1",[])),
- <<"aB">> = iolist_to_binary(re:replace("aB","(?i:([^b]))(?1)","hiocPQeyl&&Nx\\1",[global])),
- <<"Ba">> = iolist_to_binary(re:replace("Ba","(?i:([^b]))(?1)","Q\\1ImC\\1ihLTYkO",[])),
- <<"Ba">> = iolist_to_binary(re:replace("Ba","(?i:([^b]))(?1)","Q\\1ImC\\1ihLTYkO",[global])),
- <<"ba">> = iolist_to_binary(re:replace("ba","(?i:([^b]))(?1)","R\\1bTV\\1\\1",[])),
- <<"ba">> = iolist_to_binary(re:replace("ba","(?i:([^b]))(?1)","R\\1bTV\\1\\1",[global])),
- <<"mwO">> = iolist_to_binary(re:replace("aaaaaaX","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","mwO",[])),
- <<"mwO">> = iolist_to_binary(re:replace("aaaaaaX","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","mwO",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","EQl\\1AR",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","EQl\\1AR",[global])),
- <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","&yy\\1GJaXojFYo",[])),
- <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","&yy\\1GJaXojFYo",[global])),
- <<"WMarOaaaaaaXebFIbQKdmm">> = iolist_to_binary(re:replace("aaaaaaX","^(?&t)*(?(DEFINE)(?<t>a))\\w$","\\1W\\1MarO&ebFIbQKdm\\1\\1m",[])),
- <<"WMarOaaaaaaXebFIbQKdmm">> = iolist_to_binary(re:replace("aaaaaaX","^(?&t)*(?(DEFINE)(?<t>a))\\w$","\\1W\\1MarO&ebFIbQKdm\\1\\1m",[global])),
- <<"lWw">> = iolist_to_binary(re:replace("aaaaaa","^(?&t)*(?(DEFINE)(?<t>a))\\w$","lWw\\1",[])),
- <<"lWw">> = iolist_to_binary(re:replace("aaaaaa","^(?&t)*(?(DEFINE)(?<t>a))\\w$","lWw\\1",[global])),
- <<"IpraaaaXkaKXqwTNFSEgDP">> = iolist_to_binary(re:replace("aaaaX","^(a)*+(\\w)","Ipr&k\\1KXqwTNFSEgDP",[])),
- <<"IpraaaaXkaKXqwTNFSEgDP">> = iolist_to_binary(re:replace("aaaaX","^(a)*+(\\w)","Ipr&k\\1KXqwTNFSEgDP",[global])),
- <<"jnYLYhYZ">> = iolist_to_binary(re:replace("YZ","^(a)*+(\\w)","jn&L&\\1\\1hY",[])),
- <<"jnYLYhYZ">> = iolist_to_binary(re:replace("YZ","^(a)*+(\\w)","jn&L&\\1\\1hY",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a)*+(\\w)","d\\1&ohvven\\1&P\\1\\1exSs",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a)*+(\\w)","d\\1&ohvven\\1&P\\1\\1exSs",[global])),
- <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(a)*+(\\w)","biv&rxkne",[])),
- <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(a)*+(\\w)","biv&rxkne",[global])),
- <<"FVSRXhsNXQwYCX">> = iolist_to_binary(re:replace("aaaaX","^(?:a)*+(\\w)","FVSR\\1hsN\\1QwYC\\1",[])),
- <<"FVSRXhsNXQwYCX">> = iolist_to_binary(re:replace("aaaaX","^(?:a)*+(\\w)","FVSR\\1hsN\\1QwYC\\1",[global])),
- <<"MiyTnbYYLxIYkYvmDUZ">> = iolist_to_binary(re:replace("YZ","^(?:a)*+(\\w)","MiyTnb&&LxI\\1k\\1vmDU",[])),
- <<"MiyTnbYYLxIYkYvmDUZ">> = iolist_to_binary(re:replace("YZ","^(?:a)*+(\\w)","MiyTnb&&LxI\\1k\\1vmDU",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a)*+(\\w)","&Ugr\\1y",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a)*+(\\w)","&Ugr\\1y",[global])),
- <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(?:a)*+(\\w)","\\1\\1&Qbd\\1SyY&u",[])),
- <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(?:a)*+(\\w)","\\1\\1&Qbd\\1SyY&u",[global])),
- <<"uQsoweaaaaXLoVaaaaaXmpAeu">> = iolist_to_binary(re:replace("aaaaX","^(a)++(\\w)","uQsowe&LoVa&mpAeu",[])),
- <<"uQsoweaaaaXLoVaaaaaXmpAeu">> = iolist_to_binary(re:replace("aaaaX","^(a)++(\\w)","uQsowe&LoVa&mpAeu",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a)++(\\w)","Nqxlkpdpkdkbt",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a)++(\\w)","Nqxlkpdpkdkbt",[global])),
- <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(a)++(\\w)","rKpJsjRH&q",[])),
- <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(a)++(\\w)","rKpJsjRH&q",[global])),
- <<"YZ">> = iolist_to_binary(re:replace("YZ","^(a)++(\\w)","\\1kUJik\\1c\\1d\\1wcEQVl",[])),
- <<"YZ">> = iolist_to_binary(re:replace("YZ","^(a)++(\\w)","\\1kUJik\\1c\\1d\\1wcEQVl",[global])),
- <<"aaaaXaaaaX">> = iolist_to_binary(re:replace("aaaaX","^(?:a)++(\\w)","&&",[])),
- <<"aaaaXaaaaX">> = iolist_to_binary(re:replace("aaaaX","^(?:a)++(\\w)","&&",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a)++(\\w)","qJF",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a)++(\\w)","qJF",[global])),
- <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(?:a)++(\\w)","Myqjwdc&SqVjwe\\1ab\\1x",[])),
- <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(?:a)++(\\w)","Myqjwdc&SqVjwe\\1ab\\1x",[global])),
- <<"YZ">> = iolist_to_binary(re:replace("YZ","^(?:a)++(\\w)","pXmu",[])),
- <<"YZ">> = iolist_to_binary(re:replace("YZ","^(?:a)++(\\w)","pXmu",[global])),
- <<"dKaaX">> = iolist_to_binary(re:replace("aaaaX","^(a)?+(\\w)","dK",[])),
- <<"dKaaX">> = iolist_to_binary(re:replace("aaaaX","^(a)?+(\\w)","dK",[global])),
- <<"QtZ">> = iolist_to_binary(re:replace("YZ","^(a)?+(\\w)","Qt",[])),
- <<"QtZ">> = iolist_to_binary(re:replace("YZ","^(a)?+(\\w)","Qt",[global])),
- <<"yaaX">> = iolist_to_binary(re:replace("aaaaX","^(?:a)?+(\\w)","y",[])),
- <<"yaaX">> = iolist_to_binary(re:replace("aaaaX","^(?:a)?+(\\w)","y",[global])),
- <<"knhrTYKYCYLYLHYZ">> = iolist_to_binary(re:replace("YZ","^(?:a)?+(\\w)","knhrT\\1K&C&L\\1LH\\1",[])),
- <<"knhrTYKYCYLYLHYZ">> = iolist_to_binary(re:replace("YZ","^(?:a)?+(\\w)","knhrT\\1K&C&L\\1LH\\1",[global])),
- <<"qaFxAasVdrHD">> = iolist_to_binary(re:replace("aaaaX","^(a){2,}+(\\w)","q\\1FxAasVdrHD",[])),
- <<"qaFxAasVdrHD">> = iolist_to_binary(re:replace("aaaaX","^(a){2,}+(\\w)","q\\1FxAasVdrHD",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a){2,}+(\\w)","Ce",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a){2,}+(\\w)","Ce",[global])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a){2,}+(\\w)","Pr\\1pRjfic",[])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a){2,}+(\\w)","Pr\\1pRjfic",[global])),
- <<"YZ">> = iolist_to_binary(re:replace("YZ","^(a){2,}+(\\w)","\\1qc&A\\1p\\1Ce",[])),
- <<"YZ">> = iolist_to_binary(re:replace("YZ","^(a){2,}+(\\w)","\\1qc&A\\1p\\1Ce",[global])),
- <<"TomaaaaXfexyXrPgPChaaaaXUaaaaX">> = iolist_to_binary(re:replace("aaaaX","^(?:a){2,}+(\\w)","Tom&fexy\\1rPgPCh&U&",[])),
- <<"TomaaaaXfexyXrPgPChaaaaXUaaaaX">> = iolist_to_binary(re:replace("aaaaX","^(?:a){2,}+(\\w)","Tom&fexy\\1rPgPCh&U&",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a){2,}+(\\w)","QxuQNyMAkLj\\1N",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a){2,}+(\\w)","QxuQNyMAkLj\\1N",[global])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^(?:a){2,}+(\\w)","qs&d\\1p&DFpaHv",[])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^(?:a){2,}+(\\w)","qs&d\\1p&DFpaHv",[global])),
- <<"YZ">> = iolist_to_binary(re:replace("YZ","^(?:a){2,}+(\\w)","&YUGUUNV&jklvBQ",[])),
- <<"YZ">> = iolist_to_binary(re:replace("YZ","^(?:a){2,}+(\\w)","&YUGUUNV&jklvBQ",[global])),
- <<"kRhvBb">> = iolist_to_binary(re:replace("b","(a|)*(?1)b","kRhvB&",[])),
- <<"kRhvBb">> = iolist_to_binary(re:replace("b","(a|)*(?1)b","kRhvB&",[global])),
- <<"UabqY">> = iolist_to_binary(re:replace("ab","(a|)*(?1)b","U&qY",[])),
- <<"UabqY">> = iolist_to_binary(re:replace("ab","(a|)*(?1)b","U&qY",[global])),
- <<"vmyFiqvLaabXSeOYAObD">> = iolist_to_binary(re:replace("aab","(a|)*(?1)b","vmyFiqvL&XSeOYAObD",[])),
- <<"vmyFiqvLaabXSeOYAObD">> = iolist_to_binary(re:replace("aab","(a|)*(?1)b","vmyFiqvL&XSeOYAObD",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)++(?1)b","aYXyIdVfFghDXyBuUsnK",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)++(?1)b","aYXyIdVfFghDXyBuUsnK",[global])),
- <<"ab">> = iolist_to_binary(re:replace("ab","(a)++(?1)b","mJgf&UxblrhCqYENY",[])),
- <<"ab">> = iolist_to_binary(re:replace("ab","(a)++(?1)b","mJgf&UxblrhCqYENY",[global])),
- <<"aab">> = iolist_to_binary(re:replace("aab","(a)++(?1)b","Nji&a",[])),
- <<"aab">> = iolist_to_binary(re:replace("aab","(a)++(?1)b","Nji&a",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)*+(?1)b","oFCeDPwP&kYedB",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)*+(?1)b","oFCeDPwP&kYedB",[global])),
- <<"ab">> = iolist_to_binary(re:replace("ab","(a)*+(?1)b","&ws\\1adQnsr\\1NinVGyRsh",[])),
- <<"ab">> = iolist_to_binary(re:replace("ab","(a)*+(?1)b","&ws\\1adQnsr\\1NinVGyRsh",[global])),
- <<"aab">> = iolist_to_binary(re:replace("aab","(a)*+(?1)b","Sb&x&",[])),
- <<"aab">> = iolist_to_binary(re:replace("aab","(a)*+(?1)b","Sb&x&",[global])),
- <<"bQNe">> = iolist_to_binary(re:replace("b","(?1)(?:(b)){0}","&QNe",[])),
- <<"bQNe">> = iolist_to_binary(re:replace("b","(?1)(?:(b)){0}","&QNe",[global])),
- <<"KRfoo(bar(baz)+baz(bop))yTvP">> = iolist_to_binary(re:replace("foo(bar(baz)+baz(bop))","(foo ( \\( ((?:(?> [^()]+ )|(?2))*) \\) ) )","KR\\1yTvP",[extended])),
- <<"KRfoo(bar(baz)+baz(bop))yTvP">> = iolist_to_binary(re:replace("foo(bar(baz)+baz(bop))","(foo ( \\( ((?:(?> [^()]+ )|(?2))*) \\) ) )","KR\\1yTvP",[extended,
- global])),
+ <<"a">> = iolist_to_binary(re:replace("a","(*SKIP)bc","K&KkIb\\1J\\1ADN\\1y",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","(*SKIP)bc","K&KkIb\\1J\\1ADN\\1y",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","(*SKIP)b","ug",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","(*SKIP)b","ug",[global])),
+ <<"IByJwJUuLMjxxx">> = iolist_to_binary(re:replace("xxx","(?P<abn>(?P=abn)xxx|)+","IByJwJUuLMj",[])),
+ <<"IByJwJUuLMjxIByJwJUuLMjxIByJwJUuLMjxIByJwJUuLMj">> = iolist_to_binary(re:replace("xxx","(?P<abn>(?P=abn)xxx|)+","IByJwJUuLMj",[global])),
+ <<"VPSaaaabCaadQCaaLaaBy">> = iolist_to_binary(re:replace("aa","(?i:([^b]))(?1)","VPS\\1&\\1bC&dQC&L&By",[])),
+ <<"VPSaaaabCaadQCaaLaaBy">> = iolist_to_binary(re:replace("aa","(?i:([^b]))(?1)","VPS\\1&\\1bC&dQC&L&By",[global])),
+ <<"yafgfEXSPbNaAHn">> = iolist_to_binary(re:replace("aA","(?i:([^b]))(?1)","y\\1fgfEXSPbN&Hn",[])),
+ <<"yafgfEXSPbNaAHn">> = iolist_to_binary(re:replace("aA","(?i:([^b]))(?1)","y\\1fgfEXSPbN&Hn",[global])),
+ <<"jtvi*CH**b Failers">> = iolist_to_binary(re:replace("** Failers","(?i:([^b]))(?1)","jtvi\\1CH&b",[])),
+ <<"jtvi*CH**bjtvi CH FbjtviaCHaibjtvilCHlebjtvirCHrsb">> = iolist_to_binary(re:replace("** Failers","(?i:([^b]))(?1)","jtvi\\1CH&b",[global])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","(?i:([^b]))(?1)","ufawxH&",[])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","(?i:([^b]))(?1)","ufawxH&",[global])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","(?i:([^b]))(?1)","kJi\\1Q",[])),
+ <<"aB">> = iolist_to_binary(re:replace("aB","(?i:([^b]))(?1)","kJi\\1Q",[global])),
+ <<"Ba">> = iolist_to_binary(re:replace("Ba","(?i:([^b]))(?1)","JMtj&Suu\\1jXYqQqQYj",[])),
+ <<"Ba">> = iolist_to_binary(re:replace("Ba","(?i:([^b]))(?1)","JMtj&Suu\\1jXYqQqQYj",[global])),
+ <<"ba">> = iolist_to_binary(re:replace("ba","(?i:([^b]))(?1)","T\\1Qayl\\1T",[])),
+ <<"ba">> = iolist_to_binary(re:replace("ba","(?i:([^b]))(?1)","T\\1Qayl\\1T",[global])),
+ <<"lxmLDk">> = iolist_to_binary(re:replace("aaaaaaX","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","lxmLDk",[])),
+ <<"lxmLDk">> = iolist_to_binary(re:replace("aaaaaaX","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","lxmLDk",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","aFfF",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","aFfF",[global])),
+ <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","QEtPA&\\1OwM",[])),
+ <<"aaaaaa">> = iolist_to_binary(re:replace("aaaaaa","^(?&t)*+(?(DEFINE)(?<t>a))\\w$","QEtPA&\\1OwM",[global])),
+ <<"SmAoeEyBaaaaaaXbwguE">> = iolist_to_binary(re:replace("aaaaaaX","^(?&t)*(?(DEFINE)(?<t>a))\\w$","SmAoeEyB&bwguE",[])),
+ <<"SmAoeEyBaaaaaaXbwguE">> = iolist_to_binary(re:replace("aaaaaaX","^(?&t)*(?(DEFINE)(?<t>a))\\w$","SmAoeEyB&bwguE",[global])),
+ <<"Uaaaaaaxaaaaaaafp">> = iolist_to_binary(re:replace("aaaaaa","^(?&t)*(?(DEFINE)(?<t>a))\\w$","U&x&afp",[])),
+ <<"Uaaaaaaxaaaaaaafp">> = iolist_to_binary(re:replace("aaaaaa","^(?&t)*(?(DEFINE)(?<t>a))\\w$","U&x&afp",[global])),
+ <<"HaaaaXaaaaXadaaaaXaaaaXareQQQkMYOa">> = iolist_to_binary(re:replace("aaaaX","^(a)*+(\\w)","H&&\\1d&&\\1reQQQkMYO\\1",[])),
+ <<"HaaaaXaaaaXadaaaaXaaaaXareQQQkMYOa">> = iolist_to_binary(re:replace("aaaaX","^(a)*+(\\w)","H&&\\1d&&\\1reQQQkMYO\\1",[global])),
+ <<"bRpsdEYGFIGPlQJJvLZ">> = iolist_to_binary(re:replace("YZ","^(a)*+(\\w)","bRpsdE&GFIG\\1PlQJ\\1JvL",[])),
+ <<"bRpsdEYGFIGPlQJJvLZ">> = iolist_to_binary(re:replace("YZ","^(a)*+(\\w)","bRpsdE&GFIG\\1PlQJ\\1JvL",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a)*+(\\w)","TEN&fs\\1AcOopKHNR&j",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a)*+(\\w)","TEN&fs\\1AcOopKHNR&j",[global])),
+ <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(a)*+(\\w)","mRufNYP&WdWMD",[])),
+ <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(a)*+(\\w)","mRufNYP&WdWMD",[global])),
+ <<"TFRaaaaXfHXTvXEuMCNthKV">> = iolist_to_binary(re:replace("aaaaX","^(?:a)*+(\\w)","TFR&fH\\1Tv\\1EuMCNthKV",[])),
+ <<"TFRaaaaXfHXTvXEuMCNthKV">> = iolist_to_binary(re:replace("aaaaX","^(?:a)*+(\\w)","TFR&fH\\1Tv\\1EuMCNthKV",[global])),
+ <<"tkYFkuQZ">> = iolist_to_binary(re:replace("YZ","^(?:a)*+(\\w)","tk\\1FkuQ",[])),
+ <<"tkYFkuQZ">> = iolist_to_binary(re:replace("YZ","^(?:a)*+(\\w)","tk\\1FkuQ",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a)*+(\\w)","kd\\1PEKSAAL&xu",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a)*+(\\w)","kd\\1PEKSAAL&xu",[global])),
+ <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(?:a)*+(\\w)","Lf",[])),
+ <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(?:a)*+(\\w)","Lf",[global])),
+ <<"oaFjagULdV">> = iolist_to_binary(re:replace("aaaaX","^(a)++(\\w)","o\\1Fj\\1gULdV",[])),
+ <<"oaFjagULdV">> = iolist_to_binary(re:replace("aaaaX","^(a)++(\\w)","o\\1Fj\\1gULdV",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a)++(\\w)","vpc",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a)++(\\w)","vpc",[global])),
+ <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(a)++(\\w)","Bl",[])),
+ <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(a)++(\\w)","Bl",[global])),
+ <<"YZ">> = iolist_to_binary(re:replace("YZ","^(a)++(\\w)","pW\\1&FBWdWw&np",[])),
+ <<"YZ">> = iolist_to_binary(re:replace("YZ","^(a)++(\\w)","pW\\1&FBWdWw&np",[global])),
+ <<"XGTXnaaaaXXYlwcXc">> = iolist_to_binary(re:replace("aaaaX","^(?:a)++(\\w)","\\1GT\\1n&\\1Ylwc\\1c",[])),
+ <<"XGTXnaaaaXXYlwcXc">> = iolist_to_binary(re:replace("aaaaX","^(?:a)++(\\w)","\\1GT\\1n&\\1Ylwc\\1c",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a)++(\\w)","knydJYg\\1",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a)++(\\w)","knydJYg\\1",[global])),
+ <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(?:a)++(\\w)","BY",[])),
+ <<"aaaa">> = iolist_to_binary(re:replace("aaaa","^(?:a)++(\\w)","BY",[global])),
+ <<"YZ">> = iolist_to_binary(re:replace("YZ","^(?:a)++(\\w)","&WnuGAP&RVIb\\1&g&",[])),
+ <<"YZ">> = iolist_to_binary(re:replace("YZ","^(?:a)++(\\w)","&WnuGAP&RVIb\\1&g&",[global])),
+ <<"abOaagwaaX">> = iolist_to_binary(re:replace("aaaaX","^(a)?+(\\w)","\\1bO&gw",[])),
+ <<"abOaagwaaX">> = iolist_to_binary(re:replace("aaaaX","^(a)?+(\\w)","\\1bO&gw",[global])),
+ <<"vfWlFqvTQcSsMBueZ">> = iolist_to_binary(re:replace("YZ","^(a)?+(\\w)","vfWlFqvTQcSsMBue",[])),
+ <<"vfWlFqvTQcSsMBueZ">> = iolist_to_binary(re:replace("YZ","^(a)?+(\\w)","vfWlFqvTQcSsMBue",[global])),
+ <<"gcDaaX">> = iolist_to_binary(re:replace("aaaaX","^(?:a)?+(\\w)","gcD",[])),
+ <<"gcDaaX">> = iolist_to_binary(re:replace("aaaaX","^(?:a)?+(\\w)","gcD",[global])),
+ <<"AXYrLumLDPdeYhsZ">> = iolist_to_binary(re:replace("YZ","^(?:a)?+(\\w)","AX\\1rLumLDPde&hs",[])),
+ <<"AXYrLumLDPdeYhsZ">> = iolist_to_binary(re:replace("YZ","^(?:a)?+(\\w)","AX\\1rLumLDPde&hs",[global])),
+ <<"GbIoTYfSk">> = iolist_to_binary(re:replace("aaaaX","^(a){2,}+(\\w)","GbIoTYfSk",[])),
+ <<"GbIoTYfSk">> = iolist_to_binary(re:replace("aaaaX","^(a){2,}+(\\w)","GbIoTYfSk",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a){2,}+(\\w)","XIW&php\\1D&&uKhDB\\1fhy",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(a){2,}+(\\w)","XIW&php\\1D&&uKhDB\\1fhy",[global])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a){2,}+(\\w)","eqY\\1Dr\\1luTHwQ",[])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^(a){2,}+(\\w)","eqY\\1Dr\\1luTHwQ",[global])),
+ <<"YZ">> = iolist_to_binary(re:replace("YZ","^(a){2,}+(\\w)","DCSsYSA",[])),
+ <<"YZ">> = iolist_to_binary(re:replace("YZ","^(a){2,}+(\\w)","DCSsYSA",[global])),
+ <<"sXOEXqrXNLjeIpAFEqS">> = iolist_to_binary(re:replace("aaaaX","^(?:a){2,}+(\\w)","sXOEXqr\\1NLjeIpAFEqS",[])),
+ <<"sXOEXqrXNLjeIpAFEqS">> = iolist_to_binary(re:replace("aaaaX","^(?:a){2,}+(\\w)","sXOEXqr\\1NLjeIpAFEqS",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a){2,}+(\\w)","RhG&SVJRvrSbFfks",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","^(?:a){2,}+(\\w)","RhG&SVJRvrSbFfks",[global])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^(?:a){2,}+(\\w)","VMSsQq&x",[])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^(?:a){2,}+(\\w)","VMSsQq&x",[global])),
+ <<"YZ">> = iolist_to_binary(re:replace("YZ","^(?:a){2,}+(\\w)","I&ofEGK\\1gk&y",[])),
+ <<"YZ">> = iolist_to_binary(re:replace("YZ","^(?:a){2,}+(\\w)","I&ofEGK\\1gk&y",[global])),
+ <<"bRSn">> = iolist_to_binary(re:replace("b","(a|)*(?1)b","\\1&RSn",[])),
+ <<"bRSn">> = iolist_to_binary(re:replace("b","(a|)*(?1)b","\\1&RSn",[global])),
+ <<"kOQDBCniDmabX">> = iolist_to_binary(re:replace("ab","(a|)*(?1)b","k\\1OQD\\1BCniDm&X",[])),
+ <<"kOQDBCniDmabX">> = iolist_to_binary(re:replace("ab","(a|)*(?1)b","k\\1OQD\\1BCniDm&X",[global])),
+ <<"DxcDd">> = iolist_to_binary(re:replace("aab","(a|)*(?1)b","DxcDd",[])),
+ <<"DxcDd">> = iolist_to_binary(re:replace("aab","(a|)*(?1)b","DxcDd",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)++(?1)b","VTtm\\1&qWBwH&TFG",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)++(?1)b","VTtm\\1&qWBwH&TFG",[global])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","(a)++(?1)b","cVqmxH",[])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","(a)++(?1)b","cVqmxH",[global])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","(a)++(?1)b","VPevb\\1Il",[])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","(a)++(?1)b","VPevb\\1Il",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)*+(?1)b","\\1KCKqqqW&OhQmC&c",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(a)*+(?1)b","\\1KCKqqqW&OhQmC&c",[global])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","(a)*+(?1)b","\\1\\1AofrA\\1",[])),
+ <<"ab">> = iolist_to_binary(re:replace("ab","(a)*+(?1)b","\\1\\1AofrA\\1",[global])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","(a)*+(?1)b","YU&W&&&br&b&&T\\1&",[])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","(a)*+(?1)b","YU&W&&&br&b&&T\\1&",[global])),
+ <<"ylblrGgeOFdq">> = iolist_to_binary(re:replace("b","(?1)(?:(b)){0}","yl&lrGgeOFdq",[])),
+ <<"ylblrGgeOFdq">> = iolist_to_binary(re:replace("b","(?1)(?:(b)){0}","yl&lrGgeOFdq",[global])),
+ <<"RVQfoo(bar(baz)+baz(bop))nWTFmuu">> = iolist_to_binary(re:replace("foo(bar(baz)+baz(bop))","(foo ( \\( ((?:(?> [^()]+ )|(?2))*) \\) ) )","RVQ&nWTFmuu",[extended])),
+ <<"RVQfoo(bar(baz)+baz(bop))nWTFmuu">> = iolist_to_binary(re:replace("foo(bar(baz)+baz(bop))","(foo ( \\( ((?:(?> [^()]+ )|(?2))*) \\) ) )","RVQ&nWTFmuu",[extended,
+ global])),
+ <<"SsABnABjAABWrFxABNxTAB">> = iolist_to_binary(re:replace("AB","(A (A|B(*ACCEPT)|C) D)(E)","Ss&n&jA&WrFx\\1NxT\\1",[extended])),
+ <<"SsABnABjAABWrFxABNxTAB">> = iolist_to_binary(re:replace("AB","(A (A|B(*ACCEPT)|C) D)(E)","Ss&n&jA&WrFx\\1NxT\\1",[extended,
+ global])),
ok.
run46() ->
- <<"Cfqx">> = iolist_to_binary(re:replace("AB","(A (A|B(*ACCEPT)|C) D)(E)","Cfqx",[extended])),
- <<"Cfqx">> = iolist_to_binary(re:replace("AB","(A (A|B(*ACCEPT)|C) D)(E)","Cfqx",[extended,
- global])),
- <<"abaaHraVohxea">> = iolist_to_binary(re:replace("ba","\\A.*?(a|bc)","a&\\1Hr\\1Vohxe\\1",[])),
- <<"abaaHraVohxea">> = iolist_to_binary(re:replace("ba","\\A.*?(a|bc)","a&\\1Hr\\1Vohxe\\1",[global])),
- <<"hEyjnxKIbWTujTtR">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc)++","hEyjnxKIbWT\\1ujT\\1tR",[])),
- <<"hEyjnxKIbWTujTtR">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc)++","hEyjnxKIbWT\\1ujT\\1tR",[global])),
- <<"oTgqSlaOSViBsWdYFa">> = iolist_to_binary(re:replace("ba","\\A.*?(a|bc)++","oTgqSl\\1OSViBsWdYF\\1",[])),
- <<"oTgqSlaOSViBsWdYFa">> = iolist_to_binary(re:replace("ba","\\A.*?(a|bc)++","oTgqSl\\1OSViBsWdYF\\1",[global])),
- <<"pATfIbaqPbaaOQbaSG">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc|d)","pATfI\\1&qP&aOQ&SG\\1",[])),
- <<"pATfIbaqPbaaOQbaSG">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc|d)","pATfI\\1&qP&aOQ&SG\\1",[global])),
- <<"bJYJaBVjnbvSceetle">> = iolist_to_binary(re:replace("beetle","(?:(b))++","bJYJaBVjn\\1vSc",[])),
- <<"bJYJaBVjnbvSceetle">> = iolist_to_binary(re:replace("beetle","(?:(b))++","bJYJaBVjn\\1vSc",[global])),
- <<"MEbqeMaqej">> = iolist_to_binary(re:replace("a","(?(?=(a(*ACCEPT)z))a)","MEbqeM\\1qej",[])),
- <<"MEbqeMaqejMEbqeMqej">> = iolist_to_binary(re:replace("a","(?(?=(a(*ACCEPT)z))a)","MEbqeM\\1qej",[global])),
- <<"aaaab">> = iolist_to_binary(re:replace("aaaab","^(a)(?1)+ab","&",[])),
- <<"aaaab">> = iolist_to_binary(re:replace("aaaab","^(a)(?1)+ab","&",[global])),
- <<"aaaab">> = iolist_to_binary(re:replace("aaaab","^(a)(?1)++ab","O&\\1shXpvDpv&VVC",[])),
- <<"aaaab">> = iolist_to_binary(re:replace("aaaab","^(a)(?1)++ab","O&\\1shXpvDpv&VVC",[global])),
- <<"RARockgammon">> = iolist_to_binary(re:replace("backgammon","(?(DEFINE)(a))?b(?1)","RARo\\1",[])),
- <<"RARockgammon">> = iolist_to_binary(re:replace("backgammon","(?(DEFINE)(a))?b(?1)","RARo\\1",[global])),
- <<"wlgVxP
+ <<"oykaGJTnwyJ">> = iolist_to_binary(re:replace("ba","\\A.*?(a|bc)","oyk\\1GJTnwyJ",[])),
+ <<"oykaGJTnwyJ">> = iolist_to_binary(re:replace("ba","\\A.*?(a|bc)","oyk\\1GJTnwyJ",[global])),
+ <<"rP">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc)++","r\\1P",[])),
+ <<"rP">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc)++","r\\1P",[global])),
+ <<"mVYabaiTtvcE">> = iolist_to_binary(re:replace("ba","\\A.*?(a|bc)++","mVY\\1&iTtvcE",[])),
+ <<"mVYabaiTtvcE">> = iolist_to_binary(re:replace("ba","\\A.*?(a|bc)++","mVY\\1&iTtvcE",[global])),
+ <<"LbassxlIODjbanukQ">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc|d)","L&ssxlIODj&n\\1\\1ukQ",[])),
+ <<"LbassxlIODjbanukQ">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc|d)","L&ssxlIODj&n\\1\\1ukQ",[global])),
+ <<"aPbcQmbYueetle">> = iolist_to_binary(re:replace("beetle","(?:(b))++","aPbcQm&Yu",[])),
+ <<"aPbcQmbYueetle">> = iolist_to_binary(re:replace("beetle","(?:(b))++","aPbcQm&Yu",[global])),
+ <<"Gaqa">> = iolist_to_binary(re:replace("a","(?(?=(a(*ACCEPT)z))a)","G\\1q&",[])),
+ <<"GaqaGq">> = iolist_to_binary(re:replace("a","(?(?=(a(*ACCEPT)z))a)","G\\1q&",[global])),
+ <<"aaaabjQnJbiaaaabtUxBujcSC">> = iolist_to_binary(re:replace("aaaab","^(a)(?1)+ab","&jQnJbi&tUxBujcSC",[])),
+ <<"aaaabjQnJbiaaaabtUxBujcSC">> = iolist_to_binary(re:replace("aaaab","^(a)(?1)+ab","&jQnJbi&tUxBujcSC",[global])),
+ <<"aaaab">> = iolist_to_binary(re:replace("aaaab","^(a)(?1)++ab","DNWp&\\1",[])),
+ <<"aaaab">> = iolist_to_binary(re:replace("aaaab","^(a)(?1)++ab","DNWp&\\1",[global])),
+ <<"FbaUCbajUSvbabLskbVFDSRckgammon">> = iolist_to_binary(re:replace("backgammon","(?(DEFINE)(a))?b(?1)","F&UC&jUSv&bLskbVFDSR",[])),
+ <<"FbaUCbajUSvbabLskbVFDSRckgammon">> = iolist_to_binary(re:replace("backgammon","(?(DEFINE)(a))?b(?1)","F&UC&jUSv&bLskbVFDSR",[global])),
+ <<"x
def">> = iolist_to_binary(re:replace("abc
-def","^\\N+","wlgVxP",[])),
- <<"wlgVxP
+def","^\\N+","x",[])),
+ <<"x
def">> = iolist_to_binary(re:replace("abc
-def","^\\N+","wlgVxP",[global])),
- <<"G
+def","^\\N+","x",[global])),
+ <<"uvwVXabc
def">> = iolist_to_binary(re:replace("abc
-def","^\\N{1,}","G",[])),
- <<"G
+def","^\\N{1,}","uv\\1wVX\\1&",[])),
+ <<"uvwVXabc
def">> = iolist_to_binary(re:replace("abc
-def","^\\N{1,}","G",[global])),
- <<"Iocde">> = iolist_to_binary(re:replace("aaaabcde","(?(R)a+|(?R)b)","Io",[])),
- <<"Iocde">> = iolist_to_binary(re:replace("aaaabcde","(?(R)a+|(?R)b)","Io",[global])),
- <<"kXRsqrvOjaaaaanNXFFUcde">> = iolist_to_binary(re:replace("aaaabcde","(?(R)a+|((?R))b)","kXRsqrvOja\\1nNXFFU",[])),
- <<"kXRsqrvOjaaaaanNXFFUcde">> = iolist_to_binary(re:replace("aaaabcde","(?(R)a+|((?R))b)","kXRsqrvOja\\1nNXFFU",[global])),
- <<"QNpwCPcde">> = iolist_to_binary(re:replace("aaaabcde","((?(R)a+|(?1)b))","QNpwCP",[])),
- <<"QNpwCPcde">> = iolist_to_binary(re:replace("aaaabcde","((?(R)a+|(?1)b))","QNpwCP",[global])),
- <<"QcDpPOcde">> = iolist_to_binary(re:replace("aaaabcde","((?(R1)a+|(?1)b))","QcDpPO",[])),
- <<"QcDpPOcde">> = iolist_to_binary(re:replace("aaaabcde","((?(R1)a+|(?1)b))","QcDpPO",[global])),
- <<"hIv">> = iolist_to_binary(re:replace("a","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","\\1hIv",[])),
- <<"hIv">> = iolist_to_binary(re:replace("a","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","\\1hIv",[global])),
- <<"bHaeaxaaAF">> = iolist_to_binary(re:replace("ba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","H&\\1eax&&AF",[])),
- <<"bHaeaxaaAF">> = iolist_to_binary(re:replace("ba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","H&\\1eax&&AF",[global])),
- <<"bbyaRYN">> = iolist_to_binary(re:replace("bba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","y&RYN",[])),
- <<"bbyaRYN">> = iolist_to_binary(re:replace("bba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","y&RYN",[global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b) c","y\\1YaiS",[extended])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b) c","y\\1YaiS",[extended,
- global])),
+def","^\\N{1,}","uv\\1wVX\\1&",[global])),
+ <<"aXqaaaabqcaaaabhUBcde">> = iolist_to_binary(re:replace("aaaabcde","(?(R)a+|(?R)b)","aXq&qc&hUB",[])),
+ <<"aXqaaaabqcaaaabhUBcde">> = iolist_to_binary(re:replace("aaaabcde","(?(R)a+|(?R)b)","aXq&qc&hUB",[global])),
+ <<"aaaabdaaaaBaaaabXbaaaaefaaaaOwsSNUSdKcde">> = iolist_to_binary(re:replace("aaaabcde","(?(R)a+|((?R))b)","&d\\1B&Xb\\1ef\\1OwsSNUSdK",[])),
+ <<"aaaabdaaaaBaaaabXbaaaaefaaaaOwsSNUSdKcde">> = iolist_to_binary(re:replace("aaaabcde","(?(R)a+|((?R))b)","&d\\1B&Xb\\1ef\\1OwsSNUSdK",[global])),
+ <<"YRaaaabaaaabaVaaaabaaaabjPdaaaabaaaabjaaaabmaaaabKMmcde">> = iolist_to_binary(re:replace("aaaabcde","((?(R)a+|(?1)b))","YR&\\1aV\\1\\1jPd\\1\\1j&m&KMm",[])),
+ <<"YRaaaabaaaabaVaaaabaaaabjPdaaaabaaaabjaaaabmaaaabKMmcde">> = iolist_to_binary(re:replace("aaaabcde","((?(R)a+|(?1)b))","YR&\\1aV\\1\\1jPd\\1\\1j&m&KMm",[global])),
+ <<"CKJwaLFaaaabMsaaaabaaaabaaaabLrcde">> = iolist_to_binary(re:replace("aaaabcde","((?(R1)a+|(?1)b))","CKJwaLF&Ms&\\1\\1Lr",[])),
+ <<"CKJwaLFaaaabMsaaaabaaaabaaaabLrcde">> = iolist_to_binary(re:replace("aaaabcde","((?(R1)a+|(?1)b))","CKJwaLF&Ms&\\1\\1Lr",[global])),
+ <<"eaMVQRJEeaaaVaBfXaaa">> = iolist_to_binary(re:replace("aaa","((?(R)a|(?1)))*","e\\1MVQRJEe&V\\1BfX&",[])),
+ <<"eaMVQRJEeaaaVaBfXaaaeMVQRJEeVBfX">> = iolist_to_binary(re:replace("aaa","((?(R)a|(?1)))*","e\\1MVQRJEe&V\\1BfX&",[global])),
+ <<"MakJwuACGqDMaaaaaUnx">> = iolist_to_binary(re:replace("aaa","((?(R)a|(?1)))+","M\\1kJwuACGqDM\\1&aUnx",[])),
+ <<"MakJwuACGqDMaaaaaUnx">> = iolist_to_binary(re:replace("aaa","((?(R)a|(?1)))+","M\\1kJwuACGqDM\\1&aUnx",[global])),
+ <<"h">> = iolist_to_binary(re:replace("a","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","h",[])),
+ <<"h">> = iolist_to_binary(re:replace("a","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","h",[global])),
+ <<"bRCaBnaanS">> = iolist_to_binary(re:replace("ba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","RC&Bn&\\1\\1&nS",[])),
+ <<"bRCaBnaanS">> = iolist_to_binary(re:replace("ba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","RC&Bn&\\1\\1&nS",[global])),
+ <<"bbaagaaxOODdgKqaOJ">> = iolist_to_binary(re:replace("bba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","a\\1&g&&xOODd\\1g\\1Kq&\\1OJ",[])),
+ <<"bbaagaaxOODdgKqaOJ">> = iolist_to_binary(re:replace("bba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))","a\\1&g&&xOODd\\1g\\1Kq&\\1OJ",[global])),
ok.
run47() ->
- <<"LababMabJVX">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b|(*F)) c","L\\1\\1M\\1JVX",[extended])),
- <<"LababMabJVX">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b|(*F)) c","L\\1\\1M\\1JVX",[extended,
- global])),
- <<"jBPevabLaabcWNWjnnaabcpgwaabc">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b) | (*F) ) c","jBPev\\1L&WNWjnn&pgw&",[extended])),
- <<"jBPevabLaabcWNWjnnaabcpgwaabc">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b) | (*F) ) c","jBPev\\1L&WNWjnn&pgw&",[extended,
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b) c","TsVxnH\\1",[extended])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b) c","TsVxnH\\1",[extended,
+ global])),
+ <<"aknaabcabababsabaabcxIQjWA">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b|(*F)) c","akn&\\1\\1\\1s\\1&xIQjWA",[extended])),
+ <<"aknaabcabababsabaabcxIQjWA">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b|(*F)) c","akn&\\1\\1\\1s\\1&xIQjWA",[extended,
+ global])),
+ <<"F">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b) | (*F) ) c","F",[extended])),
+ <<"F">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b) | (*F) ) c","F",[extended,
+ global])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b) ) c","bITLs\\1MJKk\\1\\1m",[extended])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b) ) c","bITLs\\1MJKk\\1\\1m",[extended,
+ global])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b) c","u&IJDM\\1WAKII&G\\1hn",[extended])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b) c","u&IJDM\\1WAKII&G\\1hn",[extended,
+ global])),
+ <<"KPwyWqtephaabccFNSg">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b|(*F)) c","KPwy\\1Wqteph&cFN\\1Sg\\1",[extended])),
+ <<"KPwyWqtephaabccFNSg">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b|(*F)) c","KPwy\\1Wqteph&cFN\\1Sg\\1",[extended,
global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b) ) c","GOxmfDqgi",[extended])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b) ) c","GOxmfDqgi",[extended,
- global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b) c","H\\1mWytdK\\1",[extended])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b) c","H\\1mWytdK\\1",[extended,
+ <<"HHvvo">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b) | (*F) ) c","HHvvo",[extended])),
+ <<"HHvvo">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b) | (*F) ) c","HHvvo",[extended,
+ global])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b) ) c","QVIA\\1d",[extended])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b) ) c","QVIA\\1d",[extended,
+ global])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?>a(*THEN)b) c","qjrOI&&nRtGbf",[extended])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?>a(*THEN)b) c","qjrOI&&nRtGbf",[extended,
+ global])),
+ <<"w">> = iolist_to_binary(re:replace("aabc","^.*? (?>a(*THEN)b|(*F)) c","w",[extended])),
+ <<"w">> = iolist_to_binary(re:replace("aabc","^.*? (?>a(*THEN)b|(*F)) c","w",[extended,
+ global])),
+ <<"keXPouTAhaabcXevPvyjQT">> = iolist_to_binary(re:replace("aabc","^.*? (?> (?>a(*THEN)b) | (*F) ) c","keXPouTAh&XevPvyjQT",[extended])),
+ <<"keXPouTAhaabcXevPvyjQT">> = iolist_to_binary(re:replace("aabc","^.*? (?> (?>a(*THEN)b) | (*F) ) c","keXPouTAh&XevPvyjQT",[extended,
+ global])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?> (?>a(*THEN)b) ) c","&Rj&sfrR",[extended])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?> (?>a(*THEN)b) ) c","&Rj&sfrR",[extended,
+ global])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b)++ c","\\1prYdoWF\\1MgrcQIUdFSO",[extended])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b)++ c","\\1prYdoWF\\1MgrcQIUdFSO",[extended,
+ global])),
+ <<"MOaabcnbyBabtGHNao">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b|(*F))++ c","MO&nbyB\\1tGHNao",[extended])),
+ <<"MOaabcnbyBabtGHNao">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b|(*F))++ c","MO&nbyB\\1tGHNao",[extended,
+ global])),
+ <<"yxJFsgWaabchb">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b)++ | (*F) )++ c","yxJFsgW&hb",[extended])),
+ <<"yxJFsgWaabchb">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b)++ | (*F) )++ c","yxJFsgW&hb",[extended,
+ global])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b)++ )++ c","EmmhY&&",[extended])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b)++ )++ c","EmmhY&&",[extended,
global])),
- <<"bpmBlFODKYLa">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b|(*F)) c","bpmBlFO\\1DKYLa",[extended])),
- <<"bpmBlFODKYLa">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b|(*F)) c","bpmBlFO\\1DKYLa",[extended,
- global])),
- <<"JjdAaabcVAKJYnJUNmb">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b) | (*F) ) c","JjdA&VAKJYnJUN\\1mb",[extended])),
- <<"JjdAaabcVAKJYnJUNmb">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b) | (*F) ) c","JjdA&VAKJYnJUN\\1mb",[extended,
- global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b) ) c","th\\1Srp\\1LGEBK",[extended])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b) ) c","th\\1Srp\\1LGEBK",[extended,
- global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?>a(*THEN)b) c","ukgQQVa\\1qLglPHKE",[extended])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?>a(*THEN)b) c","ukgQQVa\\1qLglPHKE",[extended,
- global])),
- <<"PVXXt">> = iolist_to_binary(re:replace("aabc","^.*? (?>a(*THEN)b|(*F)) c","PVXXt",[extended])),
- <<"PVXXt">> = iolist_to_binary(re:replace("aabc","^.*? (?>a(*THEN)b|(*F)) c","PVXXt",[extended,
- global])),
- <<"XNnaabcsJeaabciijbma">> = iolist_to_binary(re:replace("aabc","^.*? (?> (?>a(*THEN)b) | (*F) ) c","XNn&sJe&iijbma",[extended])),
- <<"XNnaabcsJeaabciijbma">> = iolist_to_binary(re:replace("aabc","^.*? (?> (?>a(*THEN)b) | (*F) ) c","XNn&sJe&iijbma",[extended,
- global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?> (?>a(*THEN)b) ) c","CtO\\1VdQgHMA&JMp",[extended])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?> (?>a(*THEN)b) ) c","CtO\\1VdQgHMA&JMp",[extended,
- global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b)++ c","AAl\\1s\\1MAOnKUxaX",[extended])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b)++ c","AAl\\1s\\1MAOnKUxaX",[extended,
- global])),
- <<"iaabcpWabNRGraabct">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b|(*F))++ c","i&pW\\1NRGr&t",[extended])),
- <<"iaabcpWabNRGraabct">> = iolist_to_binary(re:replace("aabc","^.*? (a(*THEN)b|(*F))++ c","i&pW\\1NRGr&t",[extended,
- global])),
- <<"aabcqfVFpeSPlabMdablfKabP">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b)++ | (*F) )++ c","&qfVFpeSPl\\1Md\\1lfK\\1P",[extended])),
- <<"aabcqfVFpeSPlabMdablfKabP">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b)++ | (*F) )++ c","&qfVFpeSPl\\1Md\\1lfK\\1P",[extended,
- global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b)++ )++ c","b\\1de\\1",[extended])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? ( (a(*THEN)b)++ )++ c","b\\1de\\1",[extended,
- global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b)++ c","&\\1&MQR\\1u\\1SGG&\\1SpJ",[extended])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b)++ c","&\\1&MQR\\1u\\1SGG&\\1SpJ",[extended,
- global])),
ok.
run48() ->
- <<"SaabcjaKGAOmOgHE">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b|(*F))++ c","S&\\1jaKGAOmOgHE",[extended])),
- <<"SaabcjaKGAOmOgHE">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b|(*F))++ c","S&\\1jaKGAOmOgHE",[extended,
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b)++ c","RD",[extended])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b)++ c","RD",[extended,
+ global])),
+ <<"HVPtJaabckhaabcTDNQFaabc">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b|(*F))++ c","HVPtJ&k\\1\\1h&TDNQ\\1F&",[extended])),
+ <<"HVPtJaabckhaabcTDNQFaabc">> = iolist_to_binary(re:replace("aabc","^.*? (?:a(*THEN)b|(*F))++ c","HVPtJ&k\\1\\1h&TDNQ\\1F&",[extended,
+ global])),
+ <<"GYWUPwD">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c","GYWUPwD",[extended])),
+ <<"GYWUPwD">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c","GYWUPwD",[extended,
global])),
- <<"VvLaabclAtFq">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c","VvL&lAtFq",[extended])),
- <<"VvLaabclAtFq">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c","VvL&lAtFq",[extended,
- global])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b)++ )++ c","Mg&",[extended])),
- <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b)++ )++ c","Mg&",[extended,
- global])),
- <<"prdTVmJacpUmv">> = iolist_to_binary(re:replace("ac","^(?(?=a(*THEN)b)ab|ac)","prdT\\1VmJ&pUmv",[])),
- <<"prdTVmJacpUmv">> = iolist_to_binary(re:replace("ac","^(?(?=a(*THEN)b)ab|ac)","prdT\\1VmJ&pUmv",[global])),
- <<"ba">> = iolist_to_binary(re:replace("ba","^.*?(?(?=a)a|b(*THEN)c)","wa",[])),
- <<"ba">> = iolist_to_binary(re:replace("ba","^.*?(?(?=a)a|b(*THEN)c)","wa",[global])),
- <<"JLcpcbaPX">> = iolist_to_binary(re:replace("ba","^.*?(?:(?(?=a)a|b(*THEN)c)|d)","JLcpc&PX",[])),
- <<"JLcpcbaPX">> = iolist_to_binary(re:replace("ba","^.*?(?:(?(?=a)a|b(*THEN)c)|d)","JLcpc&PX",[global])),
- <<"ac">> = iolist_to_binary(re:replace("ac","^.*?(?(?=a)a(*THEN)b|c)","P\\1eLsoy&h",[])),
- <<"ac">> = iolist_to_binary(re:replace("ac","^.*?(?(?=a)a(*THEN)b|c)","P\\1eLsoy&h",[global])),
- <<"aaQkbjSmrabIabc">> = iolist_to_binary(re:replace("aabc","^.*(?=a(*THEN)b)","&&Q\\1kbjSmr&\\1bI",[])),
- <<"aaQkbjSmrabIabc">> = iolist_to_binary(re:replace("aabc","^.*(?=a(*THEN)b)","&&Q\\1kbjSmr&\\1bI",[global])),
- <<"xascDcHDAWsCEkjCgcd">> = iolist_to_binary(re:replace("xacd","(?<=a(*ACCEPT)b)c","s\\1&D&HDAWsCEkjC\\1g&",[])),
- <<"xascDcHDAWsCEkjCgcd">> = iolist_to_binary(re:replace("xacd","(?<=a(*ACCEPT)b)c","s\\1&D&HDAWsCEkjC\\1g&",[global])),
- <<"xaTcalxCpPaREWFWqwSqLed">> = iolist_to_binary(re:replace("xacd","(?<=(a(*ACCEPT)b))c","T&\\1lxCpP\\1REWFWqwSqLe",[])),
- <<"xaTcalxCpPaREWFWqwSqLed">> = iolist_to_binary(re:replace("xacd","(?<=(a(*ACCEPT)b))c","T&\\1lxCpP\\1REWFWqwSqLe",[global])),
- <<"xababKJXd">> = iolist_to_binary(re:replace("xabcd","(?<=(a(*COMMIT)b))c","\\1KJX",[])),
- <<"xababKJXd">> = iolist_to_binary(re:replace("xabcd","(?<=(a(*COMMIT)b))c","\\1KJX",[global])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=(a(*COMMIT)b))c","caxcMW&&uQRuH",[])),
- <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=(a(*COMMIT)b))c","caxcMW&&uQRuH",[global])),
- <<"xacd">> = iolist_to_binary(re:replace("xacd","(?<=(a(*COMMIT)b))c","FOAJ",[])),
- <<"xacd">> = iolist_to_binary(re:replace("xacd","(?<=(a(*COMMIT)b))c","FOAJ",[global])),
- <<"xkklXcAWOSApWPhcsCd">> = iolist_to_binary(re:replace("xcd","(?<!a(*FAIL)b)c","kklX&AWOSApWPhcsC",[])),
- <<"xkklXcAWOSApWPhcsCd">> = iolist_to_binary(re:replace("xcd","(?<!a(*FAIL)b)c","kklX&AWOSApWPhcsC",[global])),
- <<"aEd">> = iolist_to_binary(re:replace("acd","(?<!a(*FAIL)b)c","E",[])),
- <<"aEd">> = iolist_to_binary(re:replace("acd","(?<!a(*FAIL)b)c","E",[global])),
- <<"xabXbpgbspePmyaYAcaQfd">> = iolist_to_binary(re:replace("xabcd","(?<=a(*PRUNE)b)c","XbpgbspePmyaYA&a\\1Qf\\1",[])),
- <<"xabXbpgbspePmyaYAcaQfd">> = iolist_to_binary(re:replace("xabcd","(?<=a(*PRUNE)b)c","XbpgbspePmyaYA&a\\1Qf\\1",[global])),
- <<"xabLEAOaSIPRfaaJd">> = iolist_to_binary(re:replace("xabcd","(?<=a(*SKIP)b)c","LEAO\\1a\\1SIPRfaaJ",[])),
- <<"xabLEAOaSIPRfaaJd">> = iolist_to_binary(re:replace("xabcd","(?<=a(*SKIP)b)c","LEAO\\1a\\1SIPRfaaJ",[global])),
- <<"xabaUocAdcnXoUlbd">> = iolist_to_binary(re:replace("xabcd","(?<=a(*THEN)b)c","aUocAdcnXoUlb",[])),
- <<"xabaUocAdcnXoUlbd">> = iolist_to_binary(re:replace("xabcd","(?<=a(*THEN)b)c","aUocAdcnXoUlb",[global])),
- <<"nkbGaaSijewUabcdnMG">> = iolist_to_binary(re:replace("abcd","(a)(?2){2}(.)","nkbG\\1aSijewU&nMG",[])),
- <<"nkbGaaSijewUabcdnMG">> = iolist_to_binary(re:replace("abcd","(a)(?2){2}(.)","nkbG\\1aSijewU&nMG",[global])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b)++ )++ c","f\\1\\1Ek&r\\1\\1&",[extended])),
+ <<"aabc">> = iolist_to_binary(re:replace("aabc","^.*? (?: (?:a(*THEN)b)++ )++ c","f\\1\\1Ek&r\\1\\1&",[extended,
+ global])),
+ <<"taclqoaJUC">> = iolist_to_binary(re:replace("ac","^(?(?=a(*THEN)b)ab|ac)","t&lqoaJUC",[])),
+ <<"taclqoaJUC">> = iolist_to_binary(re:replace("ac","^(?(?=a(*THEN)b)ab|ac)","t&lqoaJUC",[global])),
+ <<"ba">> = iolist_to_binary(re:replace("ba","^.*?(?(?=a)a|b(*THEN)c)","Vh\\1CaWxBWkPj&",[])),
+ <<"ba">> = iolist_to_binary(re:replace("ba","^.*?(?(?=a)a|b(*THEN)c)","Vh\\1CaWxBWkPj&",[global])),
+ <<"keB">> = iolist_to_binary(re:replace("ba","^.*?(?:(?(?=a)a|b(*THEN)c)|d)","keB",[])),
+ <<"keB">> = iolist_to_binary(re:replace("ba","^.*?(?:(?(?=a)a|b(*THEN)c)|d)","keB",[global])),
+ <<"ac">> = iolist_to_binary(re:replace("ac","^.*?(?(?=a)a(*THEN)b|c)","&hGHyUT",[])),
+ <<"ac">> = iolist_to_binary(re:replace("ac","^.*?(?(?=a)a(*THEN)b|c)","&hGHyUT",[global])),
+ <<"aalwRkdRudOgViabc">> = iolist_to_binary(re:replace("aabc","^.*(?=a(*THEN)b)","\\1\\1&al\\1\\1wRkdRudO\\1gVi",[])),
+ <<"aalwRkdRudOgViabc">> = iolist_to_binary(re:replace("aabc","^.*(?=a(*THEN)b)","\\1\\1&al\\1\\1wRkdRudO\\1gVi",[global])),
+ <<"xaBjvlyeNRakKKdd">> = iolist_to_binary(re:replace("xacd","(?<=a(*ACCEPT)b)c","Bj\\1vlyeNRa\\1kKKd",[])),
+ <<"xaBjvlyeNRakKKdd">> = iolist_to_binary(re:replace("xacd","(?<=a(*ACCEPT)b)c","Bj\\1vlyeNRa\\1kKKd",[global])),
+ <<"xahwEupkaeaicd">> = iolist_to_binary(re:replace("xacd","(?<=(a(*ACCEPT)b))c","hwEupk\\1e\\1i&",[])),
+ <<"xahwEupkaeaicd">> = iolist_to_binary(re:replace("xacd","(?<=(a(*ACCEPT)b))c","hwEupk\\1e\\1i&",[global])),
+ <<"xabTIskAGiopxbaboXHqhd">> = iolist_to_binary(re:replace("xabcd","(?<=(a(*COMMIT)b))c","TIskAGiopxb\\1oXHqh",[])),
+ <<"xabTIskAGiopxbaboXHqhd">> = iolist_to_binary(re:replace("xabcd","(?<=(a(*COMMIT)b))c","TIskAGiopxb\\1oXHqh",[global])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=(a(*COMMIT)b))c","&kSi\\1u\\1nbm",[])),
+ <<"** Failers">> = iolist_to_binary(re:replace("** Failers","(?<=(a(*COMMIT)b))c","&kSi\\1u\\1nbm",[global])),
+ <<"xacd">> = iolist_to_binary(re:replace("xacd","(?<=(a(*COMMIT)b))c","W\\1\\1kCqBlt&Hi\\1YuyKE",[])),
+ <<"xacd">> = iolist_to_binary(re:replace("xacd","(?<=(a(*COMMIT)b))c","W\\1\\1kCqBlt&Hi\\1YuyKE",[global])),
+ <<"xlBhbKjcSd">> = iolist_to_binary(re:replace("xcd","(?<!a(*FAIL)b)c","l\\1\\1\\1Bhb\\1Kj&S",[])),
+ <<"xlBhbKjcSd">> = iolist_to_binary(re:replace("xcd","(?<!a(*FAIL)b)c","l\\1\\1\\1Bhb\\1Kj&S",[global])),
+ <<"aTnbXLTid">> = iolist_to_binary(re:replace("acd","(?<!a(*FAIL)b)c","Tn\\1bXLTi\\1",[])),
+ <<"aTnbXLTid">> = iolist_to_binary(re:replace("acd","(?<!a(*FAIL)b)c","Tn\\1bXLTi\\1",[global])),
+ <<"xabiSd">> = iolist_to_binary(re:replace("xabcd","(?<=a(*PRUNE)b)c","i\\1\\1S",[])),
+ <<"xabiSd">> = iolist_to_binary(re:replace("xabcd","(?<=a(*PRUNE)b)c","i\\1\\1S",[global])),
+ <<"xabPPMbccnlcFnbcFteud">> = iolist_to_binary(re:replace("xabcd","(?<=a(*SKIP)b)c","PPMb&&nl&FnbcFteu",[])),
+ <<"xabPPMbccnlcFnbcFteud">> = iolist_to_binary(re:replace("xabcd","(?<=a(*SKIP)b)c","PPMb&&nl&FnbcFteu",[global])),
+ <<"xabVUmuVjd">> = iolist_to_binary(re:replace("xabcd","(?<=a(*THEN)b)c","V\\1UmuVj",[])),
+ <<"xabVUmuVjd">> = iolist_to_binary(re:replace("xabcd","(?<=a(*THEN)b)c","V\\1UmuVj",[global])),
ok.
run49() ->
- <<"hello world SintestMnKXO">> = iolist_to_binary(re:replace("hello world test","(another)?(\\1?)test","Sin&MnKXO",[])),
- <<"hello world SintestMnKXO">> = iolist_to_binary(re:replace("hello world test","(another)?(\\1?)test","Sin&MnKXO",[global])),
- <<"hello world test">> = iolist_to_binary(re:replace("hello world test","(another)?(\\1+)test","EqY&e&Np",[])),
- <<"hello world test">> = iolist_to_binary(re:replace("hello world test","(another)?(\\1+)test","EqY&e&Np",[global])),
- <<"aacnRTVpYnGmPcIyAaacWH">> = iolist_to_binary(re:replace("aac","(a(*COMMIT)b){0}a(?1)|aac","\\1&n\\1RTVpYnGmPcIyA&WH",[])),
- <<"aacnRTVpYnGmPcIyAaacWH">> = iolist_to_binary(re:replace("aac","(a(*COMMIT)b){0}a(?1)|aac","\\1&n\\1RTVpYnGmPcIyA&WH",[global])),
- <<"saacAdlboHVPY">> = iolist_to_binary(re:replace("aac","((?:a?)*)*c","s&\\1Adlb\\1oHVPY",[])),
- <<"saacAdlboHVPY">> = iolist_to_binary(re:replace("aac","((?:a?)*)*c","s&\\1Adlb\\1oHVPY",[global])),
- <<"PQFQipl">> = iolist_to_binary(re:replace("aac","((?>a?)*)*c","\\1PQF\\1Qipl",[])),
- <<"PQFQipl">> = iolist_to_binary(re:replace("aac","((?>a?)*)*c","\\1PQF\\1Qipl",[global])),
- <<"aOSwgH">> = iolist_to_binary(re:replace("aba","(?>.*?a)(?<=ba)","OSwg\\1H",[])),
- <<"aOSwgH">> = iolist_to_binary(re:replace("aba","(?>.*?a)(?<=ba)","OSwg\\1H",[global])),
- <<"UL">> = iolist_to_binary(re:replace("aba","(?:.*?a)(?<=ba)","UL",[])),
- <<"UL">> = iolist_to_binary(re:replace("aba","(?:.*?a)(?<=ba)","UL",[global])),
- <<"akGFFqTULiWlebdQv">> = iolist_to_binary(re:replace("aab",".*?a(*PRUNE)b","kGFFqTU\\1Li\\1\\1Wl\\1ebdQv",[])),
- <<"akGFFqTULiWlebdQv">> = iolist_to_binary(re:replace("aab",".*?a(*PRUNE)b","kGFFqTU\\1Li\\1\\1Wl\\1ebdQv",[global])),
- <<"aXPTFWMMabnvLRLXcgs">> = iolist_to_binary(re:replace("aab",".*?a(*PRUNE)b","XP\\1T\\1FWMM&nvLRL\\1Xcgs",[dotall])),
- <<"aXPTFWMMabnvLRLXcgs">> = iolist_to_binary(re:replace("aab",".*?a(*PRUNE)b","XP\\1T\\1FWMM&nvLRL\\1Xcgs",[dotall,
- global])),
- <<"aab">> = iolist_to_binary(re:replace("aab","^a(*PRUNE)b","kTbd&d\\1IUxwe",[dotall])),
- <<"aab">> = iolist_to_binary(re:replace("aab","^a(*PRUNE)b","kTbd&d\\1IUxwe",[dotall,
- global])),
- <<"atVababo">> = iolist_to_binary(re:replace("aab",".*?a(*SKIP)b","\\1tV&&o",[])),
- <<"atVababo">> = iolist_to_binary(re:replace("aab",".*?a(*SKIP)b","\\1tV&&o",[global])),
- <<"aWeRyiVpKsDiabnl">> = iolist_to_binary(re:replace("aab","(?>.*?a)b","WeR\\1yiVpKsDi&nl\\1",[dotall])),
- <<"aWeRyiVpKsDiabnl">> = iolist_to_binary(re:replace("aab","(?>.*?a)b","WeR\\1yiVpKsDi&nl\\1",[dotall,
- global])),
- <<"aUabbhWWOF">> = iolist_to_binary(re:replace("aab","(?>.*?a)b","U&bhWWOF\\1",[])),
- <<"aUabbhWWOF">> = iolist_to_binary(re:replace("aab","(?>.*?a)b","U&bhWWOF\\1",[global])),
+ <<"fQabcdabcdjOmbrqfabcdAbBVYaRO">> = iolist_to_binary(re:replace("abcd","(a)(?2){2}(.)","fQ&&jOmbrqf&AbBVY\\1RO",[])),
+ <<"fQabcdabcdjOmbrqfabcdAbBVYaRO">> = iolist_to_binary(re:replace("abcd","(a)(?2){2}(.)","fQ&&jOmbrqf&AbBVY\\1RO",[global])),
+ <<"hello world yxxigMcOStestrk">> = iolist_to_binary(re:replace("hello world test","(another)?(\\1?)test","yxxigMcOS&rk",[])),
+ <<"hello world yxxigMcOStestrk">> = iolist_to_binary(re:replace("hello world test","(another)?(\\1?)test","yxxigMcOS&rk",[global])),
+ <<"hello world test">> = iolist_to_binary(re:replace("hello world test","(another)?(\\1+)test","dx\\1giHSx&BeV&E",[])),
+ <<"hello world test">> = iolist_to_binary(re:replace("hello world test","(another)?(\\1+)test","dx\\1giHSx&BeV&E",[global])),
+ <<"DwfaacPJXaacSN">> = iolist_to_binary(re:replace("aac","(a(*COMMIT)b){0}a(?1)|aac","Dwf&PJX\\1\\1&SN",[])),
+ <<"DwfaacPJXaacSN">> = iolist_to_binary(re:replace("aac","(a(*COMMIT)b){0}a(?1)|aac","Dwf&PJX\\1\\1&SN",[global])),
+ <<"lQ">> = iolist_to_binary(re:replace("aac","((?:a?)*)*c","l\\1Q",[])),
+ <<"lQ">> = iolist_to_binary(re:replace("aac","((?:a?)*)*c","l\\1Q",[global])),
+ <<"mytQYMtByQalFhPaqAF">> = iolist_to_binary(re:replace("aac","((?>a?)*)*c","\\1mytQYMtByQalFhPaqAF",[])),
+ <<"mytQYMtByQalFhPaqAF">> = iolist_to_binary(re:replace("aac","((?>a?)*)*c","\\1mytQYMtByQalFhPaqAF",[global])),
+ <<"aJcbatLdoGHtuOHxJ">> = iolist_to_binary(re:replace("aba","(?>.*?a)(?<=ba)","Jc&tLdoGHt\\1uOHxJ",[])),
+ <<"aJcbatLdoGHtuOHxJ">> = iolist_to_binary(re:replace("aba","(?>.*?a)(?<=ba)","Jc&tLdoGHt\\1uOHxJ",[global])),
+ <<"jnJTr">> = iolist_to_binary(re:replace("aba","(?:.*?a)(?<=ba)","jnJTr",[])),
+ <<"jnJTr">> = iolist_to_binary(re:replace("aba","(?:.*?a)(?<=ba)","jnJTr",[global])),
+ <<"aSSoEg">> = iolist_to_binary(re:replace("aab",".*?a(*PRUNE)b","SS\\1\\1oE\\1g",[])),
+ <<"aSSoEg">> = iolist_to_binary(re:replace("aab",".*?a(*PRUNE)b","SS\\1\\1oE\\1g",[global])),
+ <<"aOdJuWtvQ">> = iolist_to_binary(re:replace("aab",".*?a(*PRUNE)b","OdJuWtvQ",[dotall])),
+ <<"aOdJuWtvQ">> = iolist_to_binary(re:replace("aab",".*?a(*PRUNE)b","OdJuWtvQ",[dotall,
+ global])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","^a(*PRUNE)b","u\\1oO\\1B\\1\\1",[dotall])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","^a(*PRUNE)b","u\\1oO\\1B\\1\\1",[dotall,
+ global])),
+ <<"aUtmYVcabmqfPDm">> = iolist_to_binary(re:replace("aab",".*?a(*SKIP)b","\\1UtmYVc\\1&mq\\1fPDm",[])),
+ <<"aUtmYVcabmqfPDm">> = iolist_to_binary(re:replace("aab",".*?a(*SKIP)b","\\1UtmYVc\\1&mq\\1fPDm",[global])),
+ <<"amg">> = iolist_to_binary(re:replace("aab","(?>.*?a)b","m\\1g",[dotall])),
+ <<"amg">> = iolist_to_binary(re:replace("aab","(?>.*?a)b","m\\1g",[dotall,
+ global])),
ok.
run50() ->
- <<"aab">> = iolist_to_binary(re:replace("aab","(?>^a)b","l",[dotall])),
- <<"aab">> = iolist_to_binary(re:replace("aab","(?>^a)b","l",[dotall,
- global])),
- <<"alphabetabcdeY">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*?)(?<=(abcd)|(wxyz))","eY",[])),
- <<"alphabetabcdeY">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*?)(?<=(abcd)|(wxyz))","eY",[global])),
- <<"endingwxyzmUXcfh">> = iolist_to_binary(re:replace("endingwxyz","(?>.*?)(?<=(abcd)|(wxyz))","mUX&cf\\1\\1h",[])),
- <<"endingwxyzmUXcfh">> = iolist_to_binary(re:replace("endingwxyz","(?>.*?)(?<=(abcd)|(wxyz))","mUX&cf\\1\\1h",[global])),
- <<"alphabetabcddalphabetabcdHPabcdycalphabetabcdalphabetabcdabcdAsalphabetabcdnalphabetabcd">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*)(?<=(abcd)|(wxyz))","&d&HP\\1yc&&\\1As&n&",[])),
- <<"alphabetabcddalphabetabcdHPabcdycalphabetabcdalphabetabcdabcdAsalphabetabcdnalphabetabcddHPabcdycabcdAsn">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*)(?<=(abcd)|(wxyz))","&d&HP\\1yc&&\\1As&n&",[global])),
- <<"nuJausendingwxyzRQmendingwxyzxY">> = iolist_to_binary(re:replace("endingwxyz","(?>.*)(?<=(abcd)|(wxyz))","nuJaus&RQm&xY",[])),
- <<"nuJausendingwxyzRQmendingwxyzxYnuJausRQmxY">> = iolist_to_binary(re:replace("endingwxyz","(?>.*)(?<=(abcd)|(wxyz))","nuJaus&RQm&xY",[global])),
- <<"abcdfooxyz">> = iolist_to_binary(re:replace("abcdfooxyz","(?>.*)foo","tW\\1",[])),
- <<"abcdfooxyz">> = iolist_to_binary(re:replace("abcdfooxyz","(?>.*)foo","tW\\1",[global])),
- <<"abcdfooVDUixyz">> = iolist_to_binary(re:replace("abcdfooxyz","(?>.*?)foo","&VDUi",[])),
- <<"abcdfooVDUixyz">> = iolist_to_binary(re:replace("abcdfooxyz","(?>.*?)foo","&VDUi",[global])),
- <<"acxmMn">> = iolist_to_binary(re:replace("ac","(?:(a(*PRUNE)b)){0}(?:(?1)|ac)","&\\1xmMn",[])),
- <<"acxmMn">> = iolist_to_binary(re:replace("ac","(?:(a(*PRUNE)b)){0}(?:(?1)|ac)","&\\1xmMn",[global])),
- <<"PvKHsAacacQ">> = iolist_to_binary(re:replace("ac","(?:(a(*SKIP)b)){0}(?:(?1)|ac)","P\\1vKHsA&&Q",[])),
- <<"PvKHsAacacQ">> = iolist_to_binary(re:replace("ac","(?:(a(*SKIP)b)){0}(?:(?1)|ac)","P\\1vKHsA&&Q",[global])),
- <<"aa">> = iolist_to_binary(re:replace("aa","(?<=(*SKIP)ac)a","g",[])),
- <<"aa">> = iolist_to_binary(re:replace("aa","(?<=(*SKIP)ac)a","g",[global])),
- <<"aakcebaaaacgyaaaaceWGsoCOKKn">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)b|a+c","kceb&gy&eWG\\1soCOKKn",[])),
- <<"aakcebaaaacgyaaaaceWGsoCOKKn">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)b|a+c","kceb&gy&eWG\\1soCOKKn",[global])),
- <<"aaMwmkmaaaacTVDJaaaacSHIqUKYU">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)(*PRUNE)b|a+c","Mwmk\\1m&TVDJ&SHIqUKYU",[])),
- <<"aaMwmkmaaaacTVDJaaaacSHIqUKYU">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)(*PRUNE)b|a+c","Mwmk\\1m&TVDJ&SHIqUKYU",[global])),
- <<"aaaaaacWXE">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP:N)(*PRUNE)b|a+c","&WXE",[])),
- <<"aaaaaacWXE">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP:N)(*PRUNE)b|a+c","&WXE",[global])),
- <<"aalIbneaaaac">> = iolist_to_binary(re:replace("aaaaaac","aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c","\\1lI\\1b\\1ne&",[])),
- <<"aalIbneaaaac">> = iolist_to_binary(re:replace("aaaaaac","aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c","\\1lI\\1b\\1ne&",[global])),
- <<"aauaaaacUCgqIctaaaacOCUYF">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)(*PRUNE)b|a+c","u&UCg\\1qIct&O\\1CU\\1\\1YF",[])),
- <<"aauaaaacUCgqIctaaaacOCUYF">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)(*PRUNE)b|a+c","u&UCg\\1qIct&O\\1CU\\1\\1YF",[global])),
+ <<"aPabRwBtwCmcabVfNbs">> = iolist_to_binary(re:replace("aab","(?>.*?a)b","P&RwBtwCmc&VfNb\\1\\1s",[])),
+ <<"aPabRwBtwCmcabVfNbs">> = iolist_to_binary(re:replace("aab","(?>.*?a)b","P&RwBtwCmc&VfNb\\1\\1s",[global])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","(?>^a)b","a\\1a",[dotall])),
+ <<"aab">> = iolist_to_binary(re:replace("aab","(?>^a)b","a\\1a",[dotall,
+ global])),
+ <<"alphabetabcdQVHlseDxWoyVop">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*?)(?<=(abcd)|(wxyz))","QVHlseDxWoyVop",[])),
+ <<"alphabetabcdQVHlseDxWoyVop">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*?)(?<=(abcd)|(wxyz))","QVHlseDxWoyVop",[global])),
+ <<"endingwxyzvOEVceUN">> = iolist_to_binary(re:replace("endingwxyz","(?>.*?)(?<=(abcd)|(wxyz))","vOE\\1VceUN&",[])),
+ <<"endingwxyzvOEVceUN">> = iolist_to_binary(re:replace("endingwxyz","(?>.*?)(?<=(abcd)|(wxyz))","vOE\\1VceUN&",[global])),
+ <<"VaQAuabcdDRalphabetabcdGQKSabcdMbhX">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*)(?<=(abcd)|(wxyz))","VaQAu\\1DR&GQKS\\1MbhX",[])),
+ <<"VaQAuabcdDRalphabetabcdGQKSabcdMbhXVaQAuabcdDRGQKSabcdMbhX">> = iolist_to_binary(re:replace("alphabetabcd","(?>.*)(?<=(abcd)|(wxyz))","VaQAu\\1DR&GQKS\\1MbhX",[global])),
+ <<"Lendingwxyz">> = iolist_to_binary(re:replace("endingwxyz","(?>.*)(?<=(abcd)|(wxyz))","L\\1&",[])),
+ <<"LendingwxyzL">> = iolist_to_binary(re:replace("endingwxyz","(?>.*)(?<=(abcd)|(wxyz))","L\\1&",[global])),
+ <<"abcdfooxyz">> = iolist_to_binary(re:replace("abcdfooxyz","(?>.*)foo","O\\1",[])),
+ <<"abcdfooxyz">> = iolist_to_binary(re:replace("abcdfooxyz","(?>.*)foo","O\\1",[global])),
+ <<"abcdEDLXMxyz">> = iolist_to_binary(re:replace("abcdfooxyz","(?>.*?)foo","EDLXM",[])),
+ <<"abcdEDLXMxyz">> = iolist_to_binary(re:replace("abcdfooxyz","(?>.*?)foo","EDLXM",[global])),
+ <<"KacvfWficUMXYUhCR">> = iolist_to_binary(re:replace("ac","(?:(a(*PRUNE)b)){0}(?:(?1)|ac)","K&vfWficUMXYUhCR",[])),
+ <<"KacvfWficUMXYUhCR">> = iolist_to_binary(re:replace("ac","(?:(a(*PRUNE)b)){0}(?:(?1)|ac)","K&vfWficUMXYUhCR",[global])),
+ <<"lVNcLhkqs">> = iolist_to_binary(re:replace("ac","(?:(a(*SKIP)b)){0}(?:(?1)|ac)","lVNcLhkqs",[])),
+ <<"lVNcLhkqs">> = iolist_to_binary(re:replace("ac","(?:(a(*SKIP)b)){0}(?:(?1)|ac)","lVNcLhkqs",[global])),
+ <<"aa">> = iolist_to_binary(re:replace("aa","(?<=(*SKIP)ac)a","WA\\1ysWU",[])),
+ <<"aa">> = iolist_to_binary(re:replace("aa","(?<=(*SKIP)ac)a","WA\\1ysWU",[global])),
+ <<"aaHvYt">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)b|a+c","Hv\\1Yt",[])),
+ <<"aaHvYt">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)b|a+c","Hv\\1Yt",[global])),
+ <<"aamkEaaaaclOsMTmDx">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)(*PRUNE)b|a+c","mkE&lOsM\\1TmDx",[])),
+ <<"aamkEaaaaclOsMTmDx">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)(*PRUNE)b|a+c","mkE&lOsM\\1TmDx",[global])),
+ <<"aarTnFhwuaaaacOCC">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP:N)(*PRUNE)b|a+c","rTn\\1Fhwu\\1&OCC",[])),
+ <<"aarTnFhwuaaaacOCC">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP:N)(*PRUNE)b|a+c","rTn\\1Fhwu\\1&OCC",[global])),
+ <<"aaWgwMatYijEPVVhET">> = iolist_to_binary(re:replace("aaaaaac","aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c","WgwMatYijEPVVhET",[])),
+ <<"aaWgwMatYijEPVVhET">> = iolist_to_binary(re:replace("aaaaaac","aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c","WgwMatYijEPVVhET",[global])),
+ <<"aaDFldiXfsqAoaaaacgyaaaacaaaac">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)(*PRUNE)b|a+c","DFl\\1diXfsqAo&gy&&",[])),
+ <<"aaDFldiXfsqAoaaaacgyaaaacaaaac">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)(*PRUNE)b|a+c","DFl\\1diXfsqAo&gy&&",[global])),
ok.
run51() ->
- <<"aaaaaKQacStnP">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)b|a+c","K\\1Q&St\\1nP",[])),
- <<"aaaaaKQacStnP">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)b|a+c","K\\1Q&St\\1nP",[global])),
- <<"aaaaaYggUuQGacfRtKLJ">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)(*SKIP)b|a+c","YggUu\\1QG&\\1fRtKL\\1\\1J\\1",[])),
- <<"aaaaaYggUuQGacfRtKLJ">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)(*SKIP)b|a+c","YggUu\\1QG&\\1fRtKL\\1\\1J\\1",[global])),
- <<"aaaaa">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)(*SKIP)b|a+c","\\1",[])),
- <<"aaaaa">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)(*SKIP)b|a+c","\\1",[global])),
- <<"aaaaaU">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)(*SKIP)b|a+c","U",[])),
- <<"aaaaaU">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)(*SKIP)b|a+c","U",[global])),
- <<"aaaaaac">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)b|a+c","kAM",[])),
- <<"aaaaaac">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)b|a+c","kAM",[global])),
- <<"VvCwaaaaaacLKWgIbVKGB">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)b|a+c","VvCw&LKWgIbVKGB",[])),
- <<"VvCwaaaaaacLKWgIbVKGB">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)b|a+c","VvCw&LKWgIbVKGB",[global])),
- <<"abvTAmJ">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)(*THEN)b|a+c","abvTA\\1mJ",[])),
- <<"abvTAmJ">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)(*THEN)b|a+c","abvTA\\1mJ",[global])),
- <<"phVmoxx">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)(*THEN)b|a+c","phVm\\1oxx",[])),
- <<"phVmoxx">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)(*THEN)b|a+c","phVm\\1oxx",[global])),
- <<"GdHapg">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)(*THEN)b|a+c","Gd\\1Hapg",[])),
- <<"GdHapg">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)(*THEN)b|a+c","Gd\\1Hapg",[global])),
+ <<"aaaaaacacLQGPDsBacWqi">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)b|a+c","&&LQG\\1\\1PDsB&W\\1qi",[])),
+ <<"aaaaaacacLQGPDsBacWqi">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)b|a+c","&&LQG\\1\\1PDsB&W\\1qi",[global])),
+ <<"aaaaaqFvS">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)(*SKIP)b|a+c","qFvS",[])),
+ <<"aaaaaqFvS">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)(*SKIP)b|a+c","qFvS",[global])),
+ <<"aaaaaxduXkuthyKkfDvdGK">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)(*SKIP)b|a+c","xduXkuthyK\\1kfDvdGK",[])),
+ <<"aaaaaxduXkuthyKkfDvdGK">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)(*SKIP)b|a+c","xduXkuthyK\\1kfDvdGK",[global])),
+ <<"aaaaaT">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)(*SKIP)b|a+c","T",[])),
+ <<"aaaaaT">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)(*SKIP)b|a+c","T",[global])),
+ <<"aaaaaac">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)b|a+c","tK\\1X\\1ycVaGLc\\1RU\\1&",[])),
+ <<"aaaaaac">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)b|a+c","tK\\1X\\1ycVaGLc\\1RU\\1&",[global])),
+ <<"iVaaaaaackkBjFkaaaaaacmlfslVAM">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)b|a+c","iV&kkBjFk&mlfslVAM",[])),
+ <<"iVaaaaaackkBjFkaaaaaacmlfslVAM">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*THEN)b|a+c","iV&kkBjFk&mlfslVAM",[global])),
+ <<"o">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)(*THEN)b|a+c","o",[])),
+ <<"o">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*SKIP)(*THEN)b|a+c","o",[global])),
+ <<"wLxnFkaaaaaacAX">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)(*THEN)b|a+c","wLxnF\\1k&AX",[])),
+ <<"wLxnFkaaaaaacAX">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*PRUNE)(*THEN)b|a+c","wLxnF\\1k&AX",[global])),
+ <<"RkcioItaaaaaacT">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)(*THEN)b|a+c","Rk\\1cioI\\1t&T",[])),
+ <<"RkcioItaaaaaacT">> = iolist_to_binary(re:replace("aaaaaac","aaaaa(*COMMIT)(*THEN)b|a+c","Rk\\1cioI\\1t&T",[global])),
ok.
run52() ->
- <<"aaaaa">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+","\\1",[])),
- <<"aaaaa">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+","\\1",[global])),
- <<"aaaaaQvaOuCaBoHYMapab">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+","\\1Qv&\\1OuC&BoHYM&pab",[])),
- <<"aaaaaQvaOuCaBoHYMapab">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+","\\1Qv&\\1OuC&BoHYM&pab",[global])),
- <<"aauaaaa">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+","u&",[])),
- <<"aauaaaa">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+","u&",[global])),
- <<"aaaaaTLn">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+","TLn\\1",[])),
- <<"aaaaaTLn">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+","TLn\\1",[global])),
- <<"aaaacEITBRXepyL">> = iolist_to_binary(re:replace("aaaac","a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c","&EITBRXepyL\\1",[])),
- <<"aaaacEITBRXepyL">> = iolist_to_binary(re:replace("aaaac","a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c","&EITBRXepyL\\1",[global])),
- <<"aaaMSacMdGgSm">> = iolist_to_binary(re:replace("aaaac","a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c","\\1MS&MdGg\\1Sm",[])),
- <<"aaaMSacMdGgSm">> = iolist_to_binary(re:replace("aaaac","a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c","\\1MS&MdGg\\1Sm",[global])),
- <<"aaKCBrjuDaackaactRB">> = iolist_to_binary(re:replace("aaaac","aaa(*PRUNE:A)a(*SKIP:A)b|a+c","KCBrjuD&k&t\\1RB",[])),
- <<"aaKCBrjuDaackaactRB">> = iolist_to_binary(re:replace("aaaac","aaa(*PRUNE:A)a(*SKIP:A)b|a+c","KCBrjuD&k&t\\1RB",[global])),
- <<"aaaKWuEddO">> = iolist_to_binary(re:replace("aaaac","aaa(*MARK:A)a(*SKIP:A)b|a+c","KWuEddO",[])),
- <<"aaaKWuEddO">> = iolist_to_binary(re:replace("aaaac","aaa(*MARK:A)a(*SKIP:A)b|a+c","KWuEddO",[global])),
- <<"QSDGhNmLAsnYtCIuka">> = iolist_to_binary(re:replace("ba",".?(a|b(*THEN)c)","QSDGhNmLAsnYtCIuka",[])),
- <<"QSDGhNmLAsnYtCIuka">> = iolist_to_binary(re:replace("ba",".?(a|b(*THEN)c)","QSDGhNmLAsnYtCIuka",[global])),
- <<"tARW">> = iolist_to_binary(re:replace("abc","(a(*COMMIT)b)c|abd","tARW",[])),
- <<"tARW">> = iolist_to_binary(re:replace("abc","(a(*COMMIT)b)c|abd","tARW",[global])),
- <<"abd">> = iolist_to_binary(re:replace("abd","(a(*COMMIT)b)c|abd","THra\\1QsHhH&NqVcHjK\\1",[])),
- <<"abd">> = iolist_to_binary(re:replace("abd","(a(*COMMIT)b)c|abd","THra\\1QsHhH&NqVcHjK\\1",[global])),
- <<"eJabcbgg">> = iolist_to_binary(re:replace("abc","(?=a(*COMMIT)b)abc|abd","\\1eJ&\\1bgg",[])),
- <<"eJabcbgg">> = iolist_to_binary(re:replace("abc","(?=a(*COMMIT)b)abc|abd","\\1eJ&\\1bgg",[global])),
- <<"abd">> = iolist_to_binary(re:replace("abd","(?=a(*COMMIT)b)abc|abd","&",[])),
- <<"abd">> = iolist_to_binary(re:replace("abd","(?=a(*COMMIT)b)abc|abd","&",[global])),
- <<"SJjtxKabcE">> = iolist_to_binary(re:replace("abc","(?>a(*COMMIT)b)c|abd","SJjt\\1xK&E",[])),
- <<"SJjtxKabcE">> = iolist_to_binary(re:replace("abc","(?>a(*COMMIT)b)c|abd","SJjt\\1xK&E",[global])),
- <<"nCO">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)b)c|abd","\\1nCO",[])),
- <<"nCO">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)b)c|abd","\\1nCO",[global])),
- <<"abd">> = iolist_to_binary(re:replace("abd","a(?=b(*COMMIT)c)[^d]|abd","sicBOgC",[])),
- <<"abd">> = iolist_to_binary(re:replace("abd","a(?=b(*COMMIT)c)[^d]|abd","sicBOgC",[global])),
- <<"OIc">> = iolist_to_binary(re:replace("abc","a(?=b(*COMMIT)c)[^d]|abd","OI",[])),
- <<"OIc">> = iolist_to_binary(re:replace("abc","a(?=b(*COMMIT)c)[^d]|abd","OI",[global])),
- <<"cBnM">> = iolist_to_binary(re:replace("abd","a(?=bc).|abd","cBnM",[])),
- <<"cBnM">> = iolist_to_binary(re:replace("abd","a(?=bc).|abd","cBnM",[global])),
- <<"uwVabvc">> = iolist_to_binary(re:replace("abc","a(?=bc).|abd","\\1uwV&v",[])),
- <<"uwVabvc">> = iolist_to_binary(re:replace("abc","a(?=bc).|abd","\\1uwV&v",[global])),
- <<"abceabd">> = iolist_to_binary(re:replace("abceabd","a(?>b(*COMMIT)c)d|abd","ON\\1oJApWbhJ&h\\1SDD",[])),
- <<"abceabd">> = iolist_to_binary(re:replace("abceabd","a(?>b(*COMMIT)c)d|abd","ON\\1oJApWbhJ&h\\1SDD",[global])),
- <<"abceabdFDcsKjWRPJwG">> = iolist_to_binary(re:replace("abceabd","a(?>bc)d|abd","&FDcsK\\1jWRPJwG",[])),
- <<"abceabdFDcsKjWRPJwG">> = iolist_to_binary(re:replace("abceabd","a(?>bc)d|abd","&FDcsK\\1jWRPJwG",[global])),
- <<"fTabdENuYeMabdK">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)b)c|abd","fT&ENuY\\1eM&K",[])),
- <<"fTabdENuYeMabdK">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)b)c|abd","fT&ENuY\\1eM&K",[global])),
- <<"abd">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)c)d|abd","vbE",[])),
- <<"abd">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)c)d|abd","vbE",[global])),
- <<"iKqJ">> = iolist_to_binary(re:replace("ac","((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))","iKq\\1J",[])),
- <<"iKqJ">> = iolist_to_binary(re:replace("ac","((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))","iKq\\1J",[global])),
+ <<"aaaaaWSYDaO">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+","WSYDaO",[])),
+ <<"aaaaaWSYDaO">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+","WSYDaO",[global])),
+ <<"aaaaaWAaddaTedlmqyrPY">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+","WA\\1&dd\\1&TedlmqyrPY",[])),
+ <<"aaaaaWAaddaTedlmqyrPY">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+","WA\\1&dd\\1&TedlmqyrPY",[global])),
+ <<"aaJwaaaataaaaaaaaJ">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+","Jw&t&&J",[])),
+ <<"aaJwaaaataaaaaaaaJ">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+","Jw&t&&J",[global])),
+ <<"aaaaawaeihCejEsBaGR">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+","wae\\1ih\\1Ce\\1jEsBaG\\1R",[])),
+ <<"aaaaawaeihCejEsBaGR">> = iolist_to_binary(re:replace("aaaaaa","aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+","wae\\1ih\\1Ce\\1jEsBaG\\1R",[global])),
+ <<"aavaacNX">> = iolist_to_binary(re:replace("aaaac","a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c","v&\\1NX",[])),
+ <<"aavaacNX">> = iolist_to_binary(re:replace("aaaac","a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c","v&\\1NX",[global])),
+ <<"aaapmNFtwlMXJwfQ">> = iolist_to_binary(re:replace("aaaac","a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c","pmNFtwlMXJ\\1wfQ",[])),
+ <<"aaapmNFtwlMXJwfQ">> = iolist_to_binary(re:replace("aaaac","a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c","pmNFtwlMXJ\\1wfQ",[global])),
+ <<"aaEaacnKG">> = iolist_to_binary(re:replace("aaaac","aaa(*PRUNE:A)a(*SKIP:A)b|a+c","E&nKG",[])),
+ <<"aaEaacnKG">> = iolist_to_binary(re:replace("aaaac","aaa(*PRUNE:A)a(*SKIP:A)b|a+c","E&nKG",[global])),
+ <<"aaaEmXmYyXMvMPacsIUnacb">> = iolist_to_binary(re:replace("aaaac","aaa(*MARK:A)a(*SKIP:A)b|a+c","E\\1mXmY\\1yXMvMP&sIUn&b",[])),
+ <<"aaaEmXmYyXMvMPacsIUnacb">> = iolist_to_binary(re:replace("aaaac","aaa(*MARK:A)a(*SKIP:A)b|a+c","E\\1mXmY\\1yXMvMP&sIUn&b",[global])),
+ <<"sctyVa">> = iolist_to_binary(re:replace("ba",".?(a|b(*THEN)c)","sctyV\\1",[])),
+ <<"sctyVa">> = iolist_to_binary(re:replace("ba",".?(a|b(*THEN)c)","sctyV\\1",[global])),
+ <<"abcEabcyEabLepBwabcDne">> = iolist_to_binary(re:replace("abc","(a(*COMMIT)b)c|abd","&E&yE\\1LepBw&Dne",[])),
+ <<"abcEabcyEabLepBwabcDne">> = iolist_to_binary(re:replace("abc","(a(*COMMIT)b)c|abd","&E&yE\\1LepBw&Dne",[global])),
+ <<"abd">> = iolist_to_binary(re:replace("abd","(a(*COMMIT)b)c|abd","EnmKFsm&",[])),
+ <<"abd">> = iolist_to_binary(re:replace("abd","(a(*COMMIT)b)c|abd","EnmKFsm&",[global])),
+ <<"pXGcB">> = iolist_to_binary(re:replace("abc","(?=a(*COMMIT)b)abc|abd","pXGcB",[])),
+ <<"pXGcB">> = iolist_to_binary(re:replace("abc","(?=a(*COMMIT)b)abc|abd","pXGcB",[global])),
+ <<"yqRflvWfdabd">> = iolist_to_binary(re:replace("abd","(?=a(*COMMIT)b)abc|abd","yqR\\1flvW\\1fd&",[])),
+ <<"yqRflvWfdabd">> = iolist_to_binary(re:replace("abd","(?=a(*COMMIT)b)abc|abd","yqR\\1flvW\\1fd&",[global])),
+ <<"caqabcfAabcVd">> = iolist_to_binary(re:replace("abc","(?>a(*COMMIT)b)c|abd","caq&fA&Vd",[])),
+ <<"caqabcfAabcVd">> = iolist_to_binary(re:replace("abc","(?>a(*COMMIT)b)c|abd","caq&fA&Vd",[global])),
+ <<"BYnSX">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)b)c|abd","BY\\1nSX",[])),
+ <<"BYnSX">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)b)c|abd","BY\\1nSX",[global])),
+ <<"abd">> = iolist_to_binary(re:replace("abd","a(?=b(*COMMIT)c)[^d]|abd","d\\1h\\1&",[])),
+ <<"abd">> = iolist_to_binary(re:replace("abd","a(?=b(*COMMIT)c)[^d]|abd","d\\1h\\1&",[global])),
+ <<"rYJdMtasqc">> = iolist_to_binary(re:replace("abc","a(?=b(*COMMIT)c)[^d]|abd","rYJd\\1Mtasq\\1",[])),
+ <<"rYJdMtasqc">> = iolist_to_binary(re:replace("abc","a(?=b(*COMMIT)c)[^d]|abd","rYJd\\1Mtasq\\1",[global])),
+ <<"o">> = iolist_to_binary(re:replace("abd","a(?=bc).|abd","o\\1",[])),
+ <<"o">> = iolist_to_binary(re:replace("abd","a(?=bc).|abd","o\\1",[global])),
+ <<"WSUNxSjyjPQXxic">> = iolist_to_binary(re:replace("abc","a(?=bc).|abd","W\\1SUNxSjyjPQXxi",[])),
+ <<"WSUNxSjyjPQXxic">> = iolist_to_binary(re:replace("abc","a(?=bc).|abd","W\\1SUNxSjyjPQXxi",[global])),
+ <<"abceabd">> = iolist_to_binary(re:replace("abceabd","a(?>b(*COMMIT)c)d|abd","iF",[])),
+ <<"abceabd">> = iolist_to_binary(re:replace("abceabd","a(?>b(*COMMIT)c)d|abd","iF",[global])),
+ <<"abceoxabdvpqchabdcfPpHmTC">> = iolist_to_binary(re:replace("abceabd","a(?>bc)d|abd","ox&vpq\\1ch&cfPpHmTC",[])),
+ <<"abceoxabdvpqchabdcfPpHmTC">> = iolist_to_binary(re:replace("abceabd","a(?>bc)d|abd","ox&vpq\\1ch&cfPpHmTC",[global])),
+ <<"EPsAiuAXGag">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)b)c|abd","EPsAiuAXGag",[])),
+ <<"EPsAiuAXGag">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)b)c|abd","EPsAiuAXGag",[global])),
+ <<"abd">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)c)d|abd","iTR\\1KirHaAm\\1u&L",[])),
+ <<"abd">> = iolist_to_binary(re:replace("abd","(?>a(*COMMIT)c)d|abd","iTR\\1KirHaAm\\1u&L",[global])),
+ <<"hopmrj">> = iolist_to_binary(re:replace("ac","((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))","hopm\\1\\1\\1rj",[])),
+ <<"hopmrj">> = iolist_to_binary(re:replace("ac","((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))","hopm\\1\\1\\1rj",[global])),
ok.
run53() ->
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a)?(?(1)a|b)+$","YQRU&",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a)?(?(1)a|b)+$","YQRU&",[global])),
- <<"a">> = iolist_to_binary(re:replace("a","^(a)?(?(1)a|b)+$","SLSciT&&F",[])),
- <<"a">> = iolist_to_binary(re:replace("a","^(a)?(?(1)a|b)+$","SLSciT&&F",[global])),
- <<"aIbCe">> = iolist_to_binary(re:replace("ab","(?=a\\Kb)ab","IbCe",[])),
- <<"aIbCe">> = iolist_to_binary(re:replace("ab","(?=a\\Kb)ab","IbCe",[global])),
- <<"KWEhxbu">> = iolist_to_binary(re:replace("ac","(?!a\\Kb)ac","KWEhxbu",[])),
- <<"KWEhxbu">> = iolist_to_binary(re:replace("ac","(?!a\\Kb)ac","KWEhxbu",[global])),
- <<"abObpVTjlSnifUCddjn">> = iolist_to_binary(re:replace("abcd","^abc(?<=b\\Kc)d","ObpV\\1TjlSnifUCddjn",[])),
- <<"abObpVTjlSnifUCddjn">> = iolist_to_binary(re:replace("abcd","^abc(?<=b\\Kc)d","ObpV\\1TjlSnifUCddjn",[global])),
- <<"lljlodkrbhYabcdXWQwLIT">> = iolist_to_binary(re:replace("abcd","^abc(?<!b\\Kq)d","llj\\1lodkrbhY&XWQwLIT",[])),
- <<"lljlodkrbhYabcdXWQwLIT">> = iolist_to_binary(re:replace("abcd","^abc(?<!b\\Kq)d","llj\\1lodkrbhY&XWQwLIT",[global])),
- <<"abcdabcdabcdHLqtQeabcdEabcdJHiabcdP">> = iolist_to_binary(re:replace("abcd","^((abc|abcx)(*THEN)y|abcd)","&&\\1HLqtQe&E\\1JHi\\1P",[])),
- <<"abcdabcdabcdHLqtQeabcdEabcdJHiabcdP">> = iolist_to_binary(re:replace("abcd","^((abc|abcx)(*THEN)y|abcd)","&&\\1HLqtQe&E\\1JHi\\1P",[global])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^((abc|abcx)(*THEN)y|abcd)","NtVKEpoSj\\1\\1o\\1ESK",[])),
- <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^((abc|abcx)(*THEN)y|abcd)","NtVKEpoSj\\1\\1o\\1ESK",[global])),
- <<"abcxy">> = iolist_to_binary(re:replace("abcxy","^((abc|abcx)(*THEN)y|abcd)","Jj\\1XL&TAaD",[])),
- <<"abcxy">> = iolist_to_binary(re:replace("abcxy","^((abc|abcx)(*THEN)y|abcd)","Jj\\1XL&TAaD",[global])),
- <<"yes">> = iolist_to_binary(re:replace("yes","^((yes|no)(*THEN)(*F))?","fA&L\\1bxmA\\1bu\\1w\\1Lh",[])),
- <<"yes">> = iolist_to_binary(re:replace("yes","^((yes|no)(*THEN)(*F))?","fA&L\\1bxmA\\1bu\\1w\\1Lh",[global])),
- <<"ac">> = iolist_to_binary(re:replace("ac","(?=a(*COMMIT)b|ac)ac|ac","uuCjDlLQYP",[])),
- <<"ac">> = iolist_to_binary(re:replace("ac","(?=a(*COMMIT)b|ac)ac|ac","uuCjDlLQYP",[global])),
- <<"ac">> = iolist_to_binary(re:replace("ac","(?=a(*COMMIT)b|(ac)) ac | (a)c","\\1W&y&PeDCK\\1cDLtO",[extended])),
- <<"ac">> = iolist_to_binary(re:replace("ac","(?=a(*COMMIT)b|(ac)) ac | (a)c","\\1W&y&PeDCK\\1cDLtO",[extended,
- global])),
- <<"bnWqWn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*THEN)a)bn|bnn)","&WqW",[])),
- <<"bnWqWn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*THEN)a)bn|bnn)","&WqW",[global])),
- <<"PGnTXLBnIbnbnbnePKbnn">> = iolist_to_binary(re:replace("bnn","(?!b(*SKIP)a)bn|bnn","PGnTXLBnI&&&e\\1PK&",[])),
- <<"PGnTXLBnIbnbnbnePKbnn">> = iolist_to_binary(re:replace("bnn","(?!b(*SKIP)a)bn|bnn","PGnTXLBnI&&&e\\1PK&",[global])),
- <<"iMn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*SKIP)a)bn|bnn)","\\1iM",[])),
- <<"iMn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*SKIP)a)bn|bnn)","\\1iM",[global])),
- <<"gcbnaxAn">> = iolist_to_binary(re:replace("bnn","(?!b(*PRUNE)a)bn|bnn","\\1gc&ax\\1\\1A",[])),
- <<"gcbnaxAn">> = iolist_to_binary(re:replace("bnn","(?!b(*PRUNE)a)bn|bnn","\\1gc&ax\\1\\1A",[global])),
- <<"dAtbnrKybneTLNeBcn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*PRUNE)a)bn|bnn)","dAt&rKy&eTLNeBc",[])),
- <<"dAtbnrKybneTLNeBcn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*PRUNE)a)bn|bnn)","dAt&rKy&eTLNeBc",[global])),
- <<"vXn">> = iolist_to_binary(re:replace("bnn","(?!b(*COMMIT)a)bn|bnn","vX",[])),
- <<"vXn">> = iolist_to_binary(re:replace("bnn","(?!b(*COMMIT)a)bn|bnn","vX",[global])),
- <<"EUadjhULxavkwOtGbnqrPn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*COMMIT)a)bn|bnn)","EUadjhULxavkwOtG&qrP",[])),
- <<"EUadjhULxavkwOtGbnqrPn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*COMMIT)a)bn|bnn)","EUadjhULxavkwOtG&qrP",[global])),
- <<"bnn">> = iolist_to_binary(re:replace("bnn","(?=b(*SKIP)a)bn|bnn","Fw",[])),
- <<"bnn">> = iolist_to_binary(re:replace("bnn","(?=b(*SKIP)a)bn|bnn","Fw",[global])),
- <<"JgfYWGl">> = iolist_to_binary(re:replace("bnn","(?=b(*THEN)a)bn|bnn","Jgf\\1Y\\1W\\1Gl\\1",[])),
- <<"JgfYWGl">> = iolist_to_binary(re:replace("bnn","(?=b(*THEN)a)bn|bnn","Jgf\\1Y\\1W\\1Gl\\1",[global])),
- <<"SacJCiWoykVpvXacd">> = iolist_to_binary(re:replace("acd","(?!a(*SKIP)b)..","S&JCiWoykVpvX\\1&",[])),
- <<"SacJCiWoykVpvXacd">> = iolist_to_binary(re:replace("acd","(?!a(*SKIP)b)..","S&JCiWoykVpvX\\1&",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a)?(?(1)a|b)+$","G&aHbV\\1y&\\1&KV\\1\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^(a)?(?(1)a|b)+$","G&aHbV\\1y&\\1&KV\\1\\1",[global])),
+ <<"a">> = iolist_to_binary(re:replace("a","^(a)?(?(1)a|b)+$","vJmS\\1lM\\1yq\\1F&T",[])),
+ <<"a">> = iolist_to_binary(re:replace("a","^(a)?(?(1)a|b)+$","vJmS\\1lM\\1yq\\1F&T",[global])),
+ <<"abROgE">> = iolist_to_binary(re:replace("ab","(?=a\\Kb)ab","&RO\\1gE",[])),
+ <<"abROgE">> = iolist_to_binary(re:replace("ab","(?=a\\Kb)ab","&RO\\1gE",[global])),
+ <<"AVraX">> = iolist_to_binary(re:replace("ac","(?!a\\Kb)ac","AVraX",[])),
+ <<"AVraX">> = iolist_to_binary(re:replace("ac","(?!a\\Kb)ac","AVraX",[global])),
+ <<"abrftocdgfVofMMeQcd">> = iolist_to_binary(re:replace("abcd","^abc(?<=b\\Kc)d","rfto&gfVofMM\\1eQ&",[])),
+ <<"abrftocdgfVofMMeQcd">> = iolist_to_binary(re:replace("abcd","^abc(?<=b\\Kc)d","rfto&gfVofMM\\1eQ&",[global])),
+ <<"NHQVjk">> = iolist_to_binary(re:replace("abcd","^abc(?<!b\\Kq)d","N\\1HQVjk",[])),
+ <<"NHQVjk">> = iolist_to_binary(re:replace("abcd","^abc(?<!b\\Kq)d","N\\1HQVjk",[global])),
+ <<"GLeLtFYabcdabcdgLpecJf">> = iolist_to_binary(re:replace("abcd","^((abc|abcx)(*THEN)y|abcd)","GLeLtFY\\1\\1gLpecJf",[])),
+ <<"GLeLtFYabcdabcdgLpecJf">> = iolist_to_binary(re:replace("abcd","^((abc|abcx)(*THEN)y|abcd)","GLeLtFY\\1\\1gLpecJf",[global])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^((abc|abcx)(*THEN)y|abcd)","wcL\\1",[])),
+ <<"*** Failers">> = iolist_to_binary(re:replace("*** Failers","^((abc|abcx)(*THEN)y|abcd)","wcL\\1",[global])),
+ <<"abcxy">> = iolist_to_binary(re:replace("abcxy","^((abc|abcx)(*THEN)y|abcd)","RUVUoonAhCsbWrFjwfb",[])),
+ <<"abcxy">> = iolist_to_binary(re:replace("abcxy","^((abc|abcx)(*THEN)y|abcd)","RUVUoonAhCsbWrFjwfb",[global])),
+ <<"yes">> = iolist_to_binary(re:replace("yes","^((yes|no)(*THEN)(*F))?","&ymEfDG&",[])),
+ <<"yes">> = iolist_to_binary(re:replace("yes","^((yes|no)(*THEN)(*F))?","&ymEfDG&",[global])),
+ <<"ac">> = iolist_to_binary(re:replace("ac","(?=a(*COMMIT)b|ac)ac|ac","VWaTi",[])),
+ <<"ac">> = iolist_to_binary(re:replace("ac","(?=a(*COMMIT)b|ac)ac|ac","VWaTi",[global])),
+ <<"ac">> = iolist_to_binary(re:replace("ac","(?=a(*COMMIT)b|(ac)) ac | (a)c","QYq&",[extended])),
+ <<"ac">> = iolist_to_binary(re:replace("ac","(?=a(*COMMIT)b|(ac)) ac | (a)c","QYq&",[extended,
+ global])),
+ <<"CRAbnGGrAbnXLfMKFAn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*THEN)a)bn|bnn)","CRA&G\\1G\\1r\\1A&XLfMKFA",[])),
+ <<"CRAbnGGrAbnXLfMKFAn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*THEN)a)bn|bnn)","CRA&G\\1G\\1r\\1A&XLfMKFA",[global])),
+ <<"pn">> = iolist_to_binary(re:replace("bnn","(?!b(*SKIP)a)bn|bnn","p",[])),
+ <<"pn">> = iolist_to_binary(re:replace("bnn","(?!b(*SKIP)a)bn|bnn","p",[global])),
+ <<"avnuwGVQnbbnMn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*SKIP)a)bn|bnn)","avnuw\\1\\1GVQ\\1nb&M",[])),
+ <<"avnuwGVQnbbnMn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*SKIP)a)bn|bnn)","avnuw\\1\\1GVQ\\1nb&M",[global])),
+ <<"dbJHbnQmNvUjn">> = iolist_to_binary(re:replace("bnn","(?!b(*PRUNE)a)bn|bnn","dbJH&QmNvU\\1j",[])),
+ <<"dbJHbnQmNvUjn">> = iolist_to_binary(re:replace("bnn","(?!b(*PRUNE)a)bn|bnn","dbJH&QmNvU\\1j",[global])),
+ <<"CjOjn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*PRUNE)a)bn|bnn)","\\1CjOj",[])),
+ <<"CjOjn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*PRUNE)a)bn|bnn)","\\1CjOj",[global])),
+ <<"KpYyerFiCpuOn">> = iolist_to_binary(re:replace("bnn","(?!b(*COMMIT)a)bn|bnn","KpYyerF\\1iCpuO",[])),
+ <<"KpYyerFiCpuOn">> = iolist_to_binary(re:replace("bnn","(?!b(*COMMIT)a)bn|bnn","KpYyerF\\1iCpuO",[global])),
+ <<"YmcadBbnnCCREKHHXlMoHn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*COMMIT)a)bn|bnn)","YmcadB&nCCREKHHXlMoH",[])),
+ <<"YmcadBbnnCCREKHHXlMoHn">> = iolist_to_binary(re:replace("bnn","(?(?!b(*COMMIT)a)bn|bnn)","YmcadB&nCCREKHHXlMoH",[global])),
+ <<"bnn">> = iolist_to_binary(re:replace("bnn","(?=b(*SKIP)a)bn|bnn","OvTfjYJC\\1XmGdYVUwWCW",[])),
+ <<"bnn">> = iolist_to_binary(re:replace("bnn","(?=b(*SKIP)a)bn|bnn","OvTfjYJC\\1XmGdYVUwWCW",[global])),
+ <<"FDbNbagbnngDbDDd">> = iolist_to_binary(re:replace("bnn","(?=b(*THEN)a)bn|bnn","FDbNbag&gDbDDd",[])),
+ <<"FDbNbagbnngDbDDd">> = iolist_to_binary(re:replace("bnn","(?=b(*THEN)a)bn|bnn","FDbNbag&gDbDDd",[global])),
ok.
run54() ->
- <<"CxbMac">> = iolist_to_binary(re:replace("ac","^(?(?!a(*SKIP)b))","&Cxb&M",[])),
- <<"CxbMac">> = iolist_to_binary(re:replace("ac","^(?(?!a(*SKIP)b))","&Cxb&M",[global])),
- <<"OceGNacoaFRboacPKd">> = iolist_to_binary(re:replace("acd","^(?!a(*PRUNE)b)..","OceGN&o\\1aF\\1Rb\\1o&PK",[])),
- <<"OceGNacoaFRboacPKd">> = iolist_to_binary(re:replace("acd","^(?!a(*PRUNE)b)..","OceGN&o\\1aF\\1Rb\\1o&PK",[global])),
- <<"ysd">> = iolist_to_binary(re:replace("acd","(?!a(*PRUNE)b)..","ys",[])),
- <<"ysd">> = iolist_to_binary(re:replace("acd","(?!a(*PRUNE)b)..","ys",[global])),
- <<"nba">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc)","n\\1\\1&",[])),
- <<"nba">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc)","n\\1\\1&",[global])),
- <<"CDEeCDYuCDCDb">> = iolist_to_binary(re:replace("CD","^(A(*THEN)B|C(*THEN)D)","&Ee\\1Yu\\1\\1b",[])),
- <<"CDEeCDYuCDCDb">> = iolist_to_binary(re:replace("CD","^(A(*THEN)B|C(*THEN)D)","&Ee\\1Yu\\1\\1b",[global])),
- <<"AYtnukv">> = iolist_to_binary(re:replace("1234","^\\d*\\w{4}","AYtn\\1ukv",[])),
- <<"AYtnukv">> = iolist_to_binary(re:replace("1234","^\\d*\\w{4}","AYtn\\1ukv",[global])),
- <<"123">> = iolist_to_binary(re:replace("123","^\\d*\\w{4}","oGBqK\\1EWY&VbHw\\1ue&",[])),
- <<"123">> = iolist_to_binary(re:replace("123","^\\d*\\w{4}","oGBqK\\1EWY&VbHw\\1ue&",[global])),
- <<"LhHvlYGR">> = iolist_to_binary(re:replace("aaaa","^[^b]*\\w{4}","\\1LhHvlYGR",[])),
- <<"LhHvlYGR">> = iolist_to_binary(re:replace("aaaa","^[^b]*\\w{4}","\\1LhHvlYGR",[global])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^[^b]*\\w{4}","S\\1wy&o\\1v&ST",[])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^[^b]*\\w{4}","S\\1wy&o\\1v&ST",[global])),
- <<"aaaagQaaaalwFSxFUL">> = iolist_to_binary(re:replace("aaaa","^[^b]*\\w{4}","\\1\\1\\1&gQ&lwFSxFU\\1L",[caseless])),
- <<"aaaagQaaaalwFSxFUL">> = iolist_to_binary(re:replace("aaaa","^[^b]*\\w{4}","\\1\\1\\1&gQ&lwFSxFU\\1L",[caseless,
+ <<"sachjxkMNacCQoCXVcd">> = iolist_to_binary(re:replace("acd","(?!a(*SKIP)b)..","s&hjxkMN&CQoCXVc",[])),
+ <<"sachjxkMNacCQoCXVcd">> = iolist_to_binary(re:replace("acd","(?!a(*SKIP)b)..","s&hjxkMN&CQoCXVc",[global])),
+ <<"RdrPCVLRILnac">> = iolist_to_binary(re:replace("ac","^(?(?!a(*SKIP)b))","RdrPCVLR&ILn\\1",[])),
+ <<"RdrPCVLRILnac">> = iolist_to_binary(re:replace("ac","^(?(?!a(*SKIP)b))","RdrPCVLR&ILn\\1",[global])),
+ <<"bKbacacMacacHkactlacTd">> = iolist_to_binary(re:replace("acd","^(?!a(*PRUNE)b)..","bKb\\1&&M&&Hk&tl&T",[])),
+ <<"bKbacacMacacHkactlacTd">> = iolist_to_binary(re:replace("acd","^(?!a(*PRUNE)b)..","bKb\\1&&M&&Hk&tl&T",[global])),
+ <<"acgUOdBxWpud">> = iolist_to_binary(re:replace("acd","(?!a(*PRUNE)b)..","&gUO\\1dB\\1\\1x\\1\\1\\1Wpu",[])),
+ <<"acgUOdBxWpud">> = iolist_to_binary(re:replace("acd","(?!a(*PRUNE)b)..","&gUO\\1dB\\1\\1x\\1\\1\\1Wpu",[global])),
+ <<"CbaXhvafbabaFbadgban">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc)","C&Xhvaf&\\1&\\1\\1F&dg&n",[])),
+ <<"CbaXhvafbabaFbadgban">> = iolist_to_binary(re:replace("ba","\\A.*?(?:a|bc)","C&Xhvaf&\\1&\\1\\1F&dg&n",[global])),
+ <<"VCDF">> = iolist_to_binary(re:replace("CD","^(A(*THEN)B|C(*THEN)D)","V\\1F",[])),
+ <<"VCDF">> = iolist_to_binary(re:replace("CD","^(A(*THEN)B|C(*THEN)D)","V\\1F",[global])),
+ <<"TN1234">> = iolist_to_binary(re:replace("1234","^\\d*\\w{4}","\\1TN&\\1",[])),
+ <<"TN1234">> = iolist_to_binary(re:replace("1234","^\\d*\\w{4}","\\1TN&\\1",[global])),
+ <<"123">> = iolist_to_binary(re:replace("123","^\\d*\\w{4}","A\\1oHKKl\\1\\1OsT\\1Q",[])),
+ <<"123">> = iolist_to_binary(re:replace("123","^\\d*\\w{4}","A\\1oHKKl\\1\\1OsT\\1Q",[global])),
+ <<"nVISfRINBaChaaaaaaaaaaaaiab">> = iolist_to_binary(re:replace("aaaa","^[^b]*\\w{4}","nVISfRI\\1NBaC\\1h&&&iab",[])),
+ <<"nVISfRINBaChaaaaaaaaaaaaiab">> = iolist_to_binary(re:replace("aaaa","^[^b]*\\w{4}","nVISfRI\\1NBaC\\1h&&&iab",[global])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^[^b]*\\w{4}","u&ip\\1ip\\1\\1yi&\\1b&V",[])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^[^b]*\\w{4}","u&ip\\1ip\\1\\1yi&\\1b&V",[global])),
+ <<"wAjTGXoySgBSd">> = iolist_to_binary(re:replace("aaaa","^[^b]*\\w{4}","wAjTGXoySgBSd",[caseless])),
+ <<"wAjTGXoySgBSd">> = iolist_to_binary(re:replace("aaaa","^[^b]*\\w{4}","wAjTGXoySgBSd",[caseless,
+ global])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^[^b]*\\w{4}","cHIJOeNBWAOX",[caseless])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^[^b]*\\w{4}","cHIJOeNBWAOX",[caseless,
+ global])),
+ <<"aaaawbaaaaaaaagaaaa">> = iolist_to_binary(re:replace("aaaa","^a*\\w{4}","&wb&&g&",[])),
+ <<"aaaawbaaaaaaaagaaaa">> = iolist_to_binary(re:replace("aaaa","^a*\\w{4}","&wb&&g&",[global])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^a*\\w{4}","XSEM&",[])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^a*\\w{4}","XSEM&",[global])),
+ <<"QmAqwBScoVE">> = iolist_to_binary(re:replace("aaaa","^a*\\w{4}","QmAqwBScoV\\1\\1E",[caseless])),
+ <<"QmAqwBScoVE">> = iolist_to_binary(re:replace("aaaa","^a*\\w{4}","QmAqwBScoV\\1\\1E",[caseless,
+ global])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^a*\\w{4}","OMTiwdqw",[caseless])),
+ <<"aaa">> = iolist_to_binary(re:replace("aaa","^a*\\w{4}","OMTiwdqw",[caseless,
+ global])),
+ <<"1 IN SOA non-sp1 non-sp2(ITgBp1 IN SOA non-sp1 non-sp2(BJFr1PT1">> = iolist_to_binary(re:replace("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","&ITgBp&BJFr\\1PT\\1",[])),
+ <<"1 IN SOA non-sp1 non-sp2(ITgBp1 IN SOA non-sp1 non-sp2(BJFr1PT1">> = iolist_to_binary(re:replace("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$","&ITgBp&BJFr\\1PT\\1",[global])),
+ <<"AZ">> = iolist_to_binary(re:replace("AZ","^A\\xZ","SV\\1ASuT\\1",[])),
+ <<"AZ">> = iolist_to_binary(re:replace("AZ","^A\\xZ","SV\\1ASuT\\1",[global])),
+ <<"eTO">> = iolist_to_binary(re:replace("ASB","^A\\o{123}B","eTO",[])),
+ <<"eTO">> = iolist_to_binary(re:replace("ASB","^A\\o{123}B","eTO",[global])),
+ <<"HAJaaaabw">> = iolist_to_binary(re:replace("aaaab"," ^ a + + b $ ","HAJ&w\\1",[extended])),
+ <<"HAJaaaabw">> = iolist_to_binary(re:replace("aaaab"," ^ a + + b $ ","HAJ&w\\1",[extended,
+ global])),
+ <<"EMvXhBG">> = iolist_to_binary(re:replace("aaaab"," ^ a + #comment
+ + b $ ","EMvXhBG",[extended])),
+ <<"EMvXhBG">> = iolist_to_binary(re:replace("aaaab"," ^ a + #comment
+ + b $ ","EMvXhBG",[extended,global])),
+ <<"rWaaaablOQEcegVcvQpr">> = iolist_to_binary(re:replace("aaaab"," ^ a + #comment
+ #comment
+ + b $ ","r\\1W&lOQEcegVcvQp\\1r",[extended])),
+ <<"rWaaaablOQEcegVcvQpr">> = iolist_to_binary(re:replace("aaaab"," ^ a + #comment
+ #comment
+ + b $ ","r\\1W&lOQEcegVcvQp\\1r",[extended,global])),
+ ok.
+run55() ->
+ <<"JABcaaaabT">> = iolist_to_binary(re:replace("aaaab"," ^ (?> a + ) b $ ","JABc&T",[extended])),
+ <<"JABcaaaabT">> = iolist_to_binary(re:replace("aaaab"," ^ (?> a + ) b $ ","JABc&T",[extended,
+ global])),
+ <<"aaaanEIdwsaaaabaaaaYo">> = iolist_to_binary(re:replace("aaaab"," ^ ( a + ) + + \\w $ ","\\1nEIdws&\\1Yo",[extended])),
+ <<"aaaanEIdwsaaaabaaaaYo">> = iolist_to_binary(re:replace("aaaab"," ^ ( a + ) + + \\w $ ","\\1nEIdws&\\1Yo",[extended,
global])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^[^b]*\\w{4}","SfymhPOH",[caseless])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^[^b]*\\w{4}","SfymhPOH",[caseless,
- global])),
- <<"HTMLYQhAQNJHaaaaJKAva">> = iolist_to_binary(re:replace("aaaa","^a*\\w{4}","HTM\\1L\\1YQhAQNJH&JKAva",[])),
- <<"HTMLYQhAQNJHaaaaJKAva">> = iolist_to_binary(re:replace("aaaa","^a*\\w{4}","HTM\\1L\\1YQhAQNJH&JKAva",[global])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^a*\\w{4}","bfScQRcKYl&\\1&\\1&Aq&C",[])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^a*\\w{4}","bfScQRcKYl&\\1&\\1&Aq&C",[global])),
- <<"aaaadgKVePEaaaaqdlcK">> = iolist_to_binary(re:replace("aaaa","^a*\\w{4}","&dgKVePE&qdl\\1cK",[caseless])),
- <<"aaaadgKVePEaaaaqdlcK">> = iolist_to_binary(re:replace("aaaa","^a*\\w{4}","&dgKVePE&qdl\\1cK",[caseless,
- global])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^a*\\w{4}","ncXKavCFttF",[caseless])),
- <<"aaa">> = iolist_to_binary(re:replace("aaa","^a*\\w{4}","ncXKavCFttF",[caseless,
- global])),
+ <<"acb">> = iolist_to_binary(re:replace("acb","(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc","w&d",[])),
+ <<"acb">> = iolist_to_binary(re:replace("acb","(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc","w&d",[global])),
+ <<"sprnh\"NOT MATCHED">> = iolist_to_binary(re:replace("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]*+|\\\"\\\")*+\\\")++","sp\\1rnh",[])),
+ <<"sprnh\"NOT MATCHED">> = iolist_to_binary(re:replace("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]*+|\\\"\\\")*+\\\")++","sp\\1rnh",[global])),
+ <<"NON QUOTED \"QUOT\"\"ED\" AFTER hDhrDNON QUOTED \"QUOT\"\"ED\" AFTER Lif\"NOT MATCHED">> = iolist_to_binary(re:replace("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")*+\\\")++","&h\\1DhrD&\\1Lif",[])),
+ <<"NON QUOTED \"QUOT\"\"ED\" AFTER hDhrDNON QUOTED \"QUOT\"\"ED\" AFTER Lif\"NOT MATCHED">> = iolist_to_binary(re:replace("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")*+\\\")++","&h\\1DhrD&\\1Lif",[global])),
+ <<"FFjeNON QUOTED \"QUOT\"\"ED\" AFTER FNON QUOTED \"QUOT\"\"ED\" AFTER evYb\"NOT MATCHED">> = iolist_to_binary(re:replace("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")++\\\")++","FF\\1je&F&ev\\1Yb",[])),
+ <<"FFjeNON QUOTED \"QUOT\"\"ED\" AFTER FNON QUOTED \"QUOT\"\"ED\" AFTER evYb\"NOT MATCHED">> = iolist_to_binary(re:replace("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")++\\\")++","FF\\1je&F&ev\\1Yb",[global])),
+ <<"lkNON QUOTED \"QUOT\"\"ED\" AFTER NON QUOTED \"QUOT\"\"ED\" AFTER ep\"NOT MATCHED">> = iolist_to_binary(re:replace("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A([^\\\"1]++|[\\\"2]([^\\\"3]*+|[\\\"4][\\\"5])*+[\\\"6])++","lk&&ep",[])),
+ <<"lkNON QUOTED \"QUOT\"\"ED\" AFTER NON QUOTED \"QUOT\"\"ED\" AFTER ep\"NOT MATCHED">> = iolist_to_binary(re:replace("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A([^\\\"1]++|[\\\"2]([^\\\"3]*+|[\\\"4][\\\"5])*+[\\\"6])++","lk&&ep",[global])),
+ <<"QwrEsgmHnPVatesUBtesNt test">> = iolist_to_binary(re:replace("test test","^\\w+(?>\\s*)(?<=\\w)","QwrEs\\1g\\1m\\1HnPVa&UB&N",[])),
+ <<"QwrEsgmHnPVatesUBtesNt test">> = iolist_to_binary(re:replace("test test","^\\w+(?>\\s*)(?<=\\w)","QwrEs\\1g\\1m\\1HnPVa&UB&N",[global])),
+ <<"QnwXYs">> = iolist_to_binary(re:replace("acl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l","QnwXYs",[])),
+ <<"QnwXYs">> = iolist_to_binary(re:replace("acl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l","QnwXYs",[global])),
+ <<"pJjRpVdTtnNitYwRL">> = iolist_to_binary(re:replace("bdl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l","pJjRp\\1VdTtnNitYw\\1RL",[])),
+ <<"pJjRpVdTtnNitYwRL">> = iolist_to_binary(re:replace("bdl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l","pJjRp\\1VdTtnNitYw\\1RL",[global])),
+ <<"atdlHdlPdlUHuXIoBk">> = iolist_to_binary(re:replace("adl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l","t&H&P&UHuXIoBk",[])),
+ <<"atdlHdlPdlUHuXIoBk">> = iolist_to_binary(re:replace("adl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l","t&H&P&UHuXIoBk",[global])),
+ <<"bcpmlSoBl">> = iolist_to_binary(re:replace("bcl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l","pm&SoB&",[])),
+ <<"bcpmlSoBl">> = iolist_to_binary(re:replace("bcl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l","pm&SoB&",[global])),
+ <<"vbIJ abcy">> = iolist_to_binary(re:replace(" abc","\\sabc","vbIJ&y",[])),
+ <<"vbIJ abcy">> = iolist_to_binary(re:replace(" abc","\\sabc","vbIJ&y",[global])),
+ <<"wY">> = iolist_to_binary(re:replace("aa]]","[\\Qa]\\E]+","wY",[])),
+ <<"wY">> = iolist_to_binary(re:replace("aa]]","[\\Qa]\\E]+","wY",[global])),
+ <<"y">> = iolist_to_binary(re:replace("aa]]","[\\Q]a\\E]+","y",[])),
+ <<"y">> = iolist_to_binary(re:replace("aa]]","[\\Q]a\\E]+","y",[global])),
+ <<"iaARIM1234abcd">> = iolist_to_binary(re:replace("1234abcd","(?:((abcd))|(((?:(?:(?:(?:abc|(?:abcdef))))b)abcdefghi)abc)|((*ACCEPT)))","iaARIM",[])),
+ <<"iaARIM1iaARIM2iaARIM3iaARIM4iaARIMiaARIM">> = iolist_to_binary(re:replace("1234abcd","(?:((abcd))|(((?:(?:(?:(?:abc|(?:abcdef))))b)abcdefghi)abc)|((*ACCEPT)))","iaARIM",[global])),
+ ok.
+run56() ->
+ <<"bGBRdcc">> = iolist_to_binary(re:replace("baaaaaaaaac","(?1)(?#?'){8}(a)","GBRdc",[])),
+ <<"bGBRdcc">> = iolist_to_binary(re:replace("baaaaaaaaac","(?1)(?#?'){8}(a)","GBRdc",[global])),
+ <<"PqUuuXKRgsccvHSabcd">> = iolist_to_binary(re:replace("abcd","(?|(\\k'Pm')|(?'Pm'))","PqUuuXKRgsc&\\1cvHS\\1",[])),
+ <<"PqUuuXKRgsccvHSaPqUuuXKRgsccvHSbPqUuuXKRgsccvHScPqUuuXKRgsccvHSdPqUuuXKRgsccvHS">> = iolist_to_binary(re:replace("abcd","(?|(\\k'Pm')|(?'Pm'))","PqUuuXKRgsc&\\1cvHS\\1",[global])),
+ <<" MumdPEeFred:099">> = iolist_to_binary(re:replace(" Fred:099","(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\\s])","\\1&M&umdPE&e",[])),
+ <<" MumdPEeFred:099">> = iolist_to_binary(re:replace(" Fred:099","(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\\s])","\\1&M&umdPE&e",[global])),
+ <<" ugxGKrBXEcHyG">> = iolist_to_binary(re:replace(" X","(?=.*X)X$","ugxGKrB&EcHyG",[])),
+ <<" ugxGKrBXEcHyG">> = iolist_to_binary(re:replace(" X","(?=.*X)X$","ugxGKrB&EcHyG",[global])),
ok.
diff --git a/lib/stdlib/test/re_testoutput1_split_test.erl b/lib/stdlib/test/re_testoutput1_split_test.erl
index 02987971fa..8218cd9bd2 100644
--- a/lib/stdlib/test/re_testoutput1_split_test.erl
+++ b/lib/stdlib/test/re_testoutput1_split_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
%% %CopyrightEnd%
%%
-module(re_testoutput1_split_test).
--compile(export_all).
+-export([run/0]).
-compile(no_native).
%% This file is generated by running run_pcre_tests:gen_split_test("re_SUITE_data/testoutput1")
join([]) -> [];
@@ -80,6 +80,8 @@ run() ->
run52(),
run53(),
run54(),
+ run55(),
+ run56(),
ok.
run0() ->
<<"">> = iolist_to_binary(join(re:split("the quick brown fox","the quick brown fox",[trim]))),
@@ -441,10 +443,10 @@ run0() ->
<<"babababc">> = iolist_to_binary(join(re:split("babababc","^(ba|b*){1,2}?bc",[{parts,
2}]))),
<<"babababc">> = iolist_to_binary(join(re:split("babababc","^(ba|b*){1,2}?bc",[]))),
- <<"">> = iolist_to_binary(join(re:split(";z","^\\ca\\cA\\c[\\c{\\c:",[trim]))),
- <<":">> = iolist_to_binary(join(re:split(";z","^\\ca\\cA\\c[\\c{\\c:",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split(";z","^\\ca\\cA\\c[\\c{\\c:",[]))),
+ <<"">> = iolist_to_binary(join(re:split(";z","^\\ca\\cA\\c[;\\c:",[trim]))),
+ <<":">> = iolist_to_binary(join(re:split(";z","^\\ca\\cA\\c[;\\c:",[{parts,
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split(";z","^\\ca\\cA\\c[;\\c:",[]))),
<<":thing">> = iolist_to_binary(join(re:split("athing","^[ab\\]cde]",[trim]))),
<<":thing">> = iolist_to_binary(join(re:split("athing","^[ab\\]cde]",[{parts,
2}]))),
@@ -22978,24 +22980,24 @@ def","abc$",[]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[{parts,
2}]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1000",[]))),
- <<"abc81">> = iolist_to_binary(join(re:split("abc81","abc\\81",[trim]))),
- <<"abc81">> = iolist_to_binary(join(re:split("abc81","abc\\81",[{parts,
- 2}]))),
- <<"abc81">> = iolist_to_binary(join(re:split("abc81","abc\\81",[]))),
- <<"abc81">> = iolist_to_binary(join(re:split("abc81","abc\\81",[trim]))),
- <<"abc81">> = iolist_to_binary(join(re:split("abc81","abc\\81",[{parts,
- 2}]))),
- <<"abc81">> = iolist_to_binary(join(re:split("abc81","abc\\81",[]))),
- <<"abc91">> = iolist_to_binary(join(re:split("abc91","abc\\91",[trim]))),
- <<"abc91">> = iolist_to_binary(join(re:split("abc91","abc\\91",[{parts,
- 2}]))),
- <<"abc91">> = iolist_to_binary(join(re:split("abc91","abc\\91",[]))),
- <<"abc91">> = iolist_to_binary(join(re:split("abc91","abc\\91",[trim]))),
- <<"abc91">> = iolist_to_binary(join(re:split("abc91","abc\\91",[{parts,
- 2}]))),
- <<"abc91">> = iolist_to_binary(join(re:split("abc91","abc\\91",[]))),
+ <<":A:B:C:D:E:F:G:H:I">> = iolist_to_binary(join(re:split("ABCDEFGHIHI","^(A)(B)(C)(D)(E)(F)(G)(H)(I)\\8\\9$",[trim]))),
+ <<":A:B:C:D:E:F:G:H:I:">> = iolist_to_binary(join(re:split("ABCDEFGHIHI","^(A)(B)(C)(D)(E)(F)(G)(H)(I)\\8\\9$",[{parts,
+ 2}]))),
+ <<":A:B:C:D:E:F:G:H:I:">> = iolist_to_binary(join(re:split("ABCDEFGHIHI","^(A)(B)(C)(D)(E)(F)(G)(H)(I)\\8\\9$",[]))),
ok.
run6() ->
+ <<"">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[trim]))),
+ <<":">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[{parts,
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[A\\8B\\9C]+$",[trim]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[A\\8B\\9C]+$",[{parts,
+ 2}]))),
+ <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[A\\8B\\9C]+$",[]))),
+ <<"">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[trim]))),
+ <<":">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[{parts,
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("A8B9C","^[A\\8B\\9C]+$",[]))),
<<":a:b:c:d:e:f:g:h:i:j:k:l">> = iolist_to_binary(join(re:split("abcdefghijkllS","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123",[trim]))),
<<":a:b:c:d:e:f:g:h:i:j:k:l:">> = iolist_to_binary(join(re:split("abcdefghijkllS","(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\\123",[{parts,
2}]))),
@@ -23170,6 +23172,8 @@ ccc","[^a]+",[]))),
<<"aaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaa","(a)\\1{8,}",[{parts,
2}]))),
<<"aaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaa","(a)\\1{8,}",[]))),
+ ok.
+run7() ->
<<"aaaa">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[trim]))),
<<"aaaa:cd">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[{parts,
2}]))),
@@ -23178,8 +23182,6 @@ ccc","[^a]+",[]))),
<<"aa:abcd">> = iolist_to_binary(join(re:split("aaAabcd","[^a]",[{parts,
2}]))),
<<"aa:a:::">> = iolist_to_binary(join(re:split("aaAabcd","[^a]",[]))),
- ok.
-run7() ->
<<"aaaa">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[caseless,
trim]))),
<<"aaaa:cd">> = iolist_to_binary(join(re:split("aaaabcd","[^a]",[caseless,
@@ -23294,12 +23296,12 @@ run7() ->
<<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)\\b(\\d+)$",[{parts,
2}]))),
<<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*)\\b(\\d+)$",[]))),
+ ok.
+run8() ->
<<":I have 2 numbers: :53147">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*\\D)(\\d+)$",[trim]))),
<<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*\\D)(\\d+)$",[{parts,
2}]))),
<<":I have 2 numbers: :53147:">> = iolist_to_binary(join(re:split("I have 2 numbers: 53147","(.*\\D)(\\d+)$",[]))),
- ok.
-run8() ->
<<":C123">> = iolist_to_binary(join(re:split("ABC123","^\\D*(?!123)",[trim]))),
<<":C123">> = iolist_to_binary(join(re:split("ABC123","^\\D*(?!123)",[{parts,
2}]))),
@@ -23581,6 +23583,8 @@ no",".*\\.gif",[multiline,{parts,2}]))),
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
no",".*\\.gif",[multiline]))),
+ ok.
+run9() ->
<<":
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
@@ -23593,8 +23597,6 @@ no",".*\\.gif",[dotall,{parts,2}]))),
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
no",".*\\.gif",[dotall]))),
- ok.
-run9() ->
<<":
no">> = iolist_to_binary(join(re:split("borfle
bib.gif
@@ -23893,6 +23895,8 @@ B","(?ms)^.*B",[trim]))),
B","(?ms)^.*B",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("abc
B","(?ms)^.*B",[]))),
+ ok.
+run10() ->
<<"abc
">> = iolist_to_binary(join(re:split("abc
B","(?ms)^B",[trim]))),
@@ -23902,8 +23906,6 @@ B","(?ms)^B",[{parts,2}]))),
<<"abc
:">> = iolist_to_binary(join(re:split("abc
B","(?ms)^B",[]))),
- ok.
-run10() ->
<<"">> = iolist_to_binary(join(re:split("B","(?s)B$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("B","(?s)B$",[{parts,
2}]))),
@@ -24063,6 +24065,8 @@ b","a[^a]b",[dotall,trim]))),
b","a[^a]b",[dotall,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("a
b","a[^a]b",[dotall]))),
+ ok.
+run11() ->
<<"">> = iolist_to_binary(join(re:split("acb","a.b",[dotall,
trim]))),
<<":">> = iolist_to_binary(join(re:split("acb","a.b",[dotall,
@@ -24075,8 +24079,6 @@ b","a.b",[dotall,trim]))),
b","a.b",[dotall,{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("a
b","a.b",[dotall]))),
- ok.
-run11() ->
<<":a">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("bac","^(b+?|a){1,2}?c",[{parts,
2}]))),
@@ -24319,12 +24321,12 @@ zzz","\\Aabc\\z",[multiline]))),
<<":">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("aaab","(?>a+)b",[]))),
+ ok.
+run12() ->
<<":aaab">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[trim]))),
<<":aaab:">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[{parts,
2}]))),
<<":aaab:">> = iolist_to_binary(join(re:split("aaab","((?>a+)b)",[]))),
- ok.
-run12() ->
<<":aaa">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[trim]))),
<<":aaa:">> = iolist_to_binary(join(re:split("aaab","(?>(a+))b",[{parts,
2}]))),
@@ -24725,6 +24727,8 @@ run12() ->
<<"ab">> = iolist_to_binary(join(re:split("ab","^(a)?(?(1)a|b)+$",[{parts,
2}]))),
<<"ab">> = iolist_to_binary(join(re:split("ab","^(a)?(?(1)a|b)+$",[]))),
+ ok.
+run13() ->
<<"">> = iolist_to_binary(join(re:split("abc:","^(?(?=abc)\\w{3}:|\\d\\d)$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc:","^(?(?=abc)\\w{3}:|\\d\\d)$",[{parts,
2}]))),
@@ -24745,8 +24749,6 @@ run12() ->
<<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?=abc)\\w{3}:|\\d\\d)$",[{parts,
2}]))),
<<"xyz">> = iolist_to_binary(join(re:split("xyz","^(?(?=abc)\\w{3}:|\\d\\d)$",[]))),
- ok.
-run13() ->
<<"">> = iolist_to_binary(join(re:split("abc:","^(?(?!abc)\\d\\d|\\w{3}:)$",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abc:","^(?(?!abc)\\d\\d|\\w{3}:)$",[{parts,
2}]))),
@@ -25075,6 +25077,8 @@ run13() ->
<<":bcde">> = iolist_to_binary(join(re:split("aaabcde","(?>a*)*",[{parts,
2}]))),
<<":b:c:d:e:">> = iolist_to_binary(join(re:split("aaabcde","(?>a*)*",[]))),
+ ok.
+run14() ->
<<"">> = iolist_to_binary(join(re:split("aaaaa","((?>a*))*",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("aaaaa","((?>a*))*",[{parts,
2}]))),
@@ -25083,8 +25087,6 @@ run13() ->
<<"::bbaa">> = iolist_to_binary(join(re:split("aabbaa","((?>a*))*",[{parts,
2}]))),
<<"::b::b::">> = iolist_to_binary(join(re:split("aabbaa","((?>a*))*",[]))),
- ok.
-run14() ->
<<"a::a::a::a::a">> = iolist_to_binary(join(re:split("aaaaa","((?>a*?))*",[trim]))),
<<"a::aaaa">> = iolist_to_binary(join(re:split("aaaaa","((?>a*?))*",[{parts,
2}]))),
@@ -25519,12 +25521,12 @@ bar","(?<=foo\\n)^bar",[multiline]))),
<<"abq">> = iolist_to_binary(join(re:split("abq","ab+bc",[{parts,
2}]))),
<<"abq">> = iolist_to_binary(join(re:split("abq","ab+bc",[]))),
+ ok.
+run15() ->
<<"">> = iolist_to_binary(join(re:split("abbbbc","ab+bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbbbc","ab+bc",[{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("abbbbc","ab+bc",[]))),
- ok.
-run15() ->
<<"">> = iolist_to_binary(join(re:split("abbbbc","ab{1,}bc",[trim]))),
<<":">> = iolist_to_binary(join(re:split("abbbbc","ab{1,}bc",[{parts,
2}]))),
@@ -25645,12 +25647,12 @@ run15() ->
<<":">> = iolist_to_binary(join(re:split("ace","a[b-d]e",[{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("ace","a[b-d]e",[]))),
+ ok.
+run16() ->
<<"a">> = iolist_to_binary(join(re:split("aac","a[b-d]",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("aac","a[b-d]",[{parts,
2}]))),
<<"a:">> = iolist_to_binary(join(re:split("aac","a[b-d]",[]))),
- ok.
-run16() ->
<<"">> = iolist_to_binary(join(re:split("a-","a[-b]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a-","a[-b]",[{parts,
2}]))),
@@ -25819,12 +25821,12 @@ run16() ->
<<"1">> = iolist_to_binary(join(re:split("1","\\D",[{parts,
2}]))),
<<"1">> = iolist_to_binary(join(re:split("1","\\D",[]))),
+ ok.
+run17() ->
<<"">> = iolist_to_binary(join(re:split("a","[\\w]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("a","[\\w]",[{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("a","[\\w]",[]))),
- ok.
-run17() ->
<<"">> = iolist_to_binary(join(re:split("-","[\\W]",[trim]))),
<<":">> = iolist_to_binary(join(re:split("-","[\\W]",[{parts,
2}]))),
@@ -25941,12 +25943,12 @@ run17() ->
<<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b)+",[{parts,
2}]))),
<<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b)+",[]))),
+ ok.
+run18() ->
<<":b">> = iolist_to_binary(join(re:split("ab","(a+|b){1,}",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b){1,}",[{parts,
2}]))),
<<":b:">> = iolist_to_binary(join(re:split("ab","(a+|b){1,}",[]))),
- ok.
-run18() ->
<<":a::b">> = iolist_to_binary(join(re:split("ab","(a+|b)?",[trim]))),
<<":a:b">> = iolist_to_binary(join(re:split("ab","(a+|b)?",[{parts,
2}]))),
@@ -26023,12 +26025,12 @@ run18() ->
<<":bc:d:">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c*d)",[{parts,
2}]))),
<<":bc:d:">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c*d)",[]))),
+ ok.
+run19() ->
<<":bc:d">> = iolist_to_binary(join(re:split("abcd","a([bc]+)(c*d)",[trim]))),
<<":bc:d:">> = iolist_to_binary(join(re:split("abcd","a([bc]+)(c*d)",[{parts,
2}]))),
<<":bc:d:">> = iolist_to_binary(join(re:split("abcd","a([bc]+)(c*d)",[]))),
- ok.
-run19() ->
<<":b:cd">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c+d)",[trim]))),
<<":b:cd:">> = iolist_to_binary(join(re:split("abcd","a([bc]*)(c+d)",[{parts,
2}]))),
@@ -26137,12 +26139,12 @@ run19() ->
<<":">> = iolist_to_binary(join(re:split("ac","a[-]?c",[{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("ac","a[-]?c",[]))),
+ ok.
+run20() ->
<<":abc">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[{parts,
2}]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","(abc)\\1",[]))),
- ok.
-run20() ->
<<":abc">> = iolist_to_binary(join(re:split("abcabc","([a-c]*)\\1",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","([a-c]*)\\1",[{parts,
2}]))),
@@ -26323,6 +26325,8 @@ run20() ->
{parts,
2}]))),
<<"ABBBBC">> = iolist_to_binary(join(re:split("ABBBBC","ab{4,5}?bc",[caseless]))),
+ ok.
+run21() ->
<<"">> = iolist_to_binary(join(re:split("ABBC","ab??bc",[caseless,
trim]))),
<<":">> = iolist_to_binary(join(re:split("ABBC","ab??bc",[caseless,
@@ -26335,8 +26339,6 @@ run20() ->
{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("ABC","ab??bc",[caseless]))),
- ok.
-run21() ->
<<"">> = iolist_to_binary(join(re:split("ABC","ab{0,1}?bc",[caseless,
trim]))),
<<":">> = iolist_to_binary(join(re:split("ABC","ab{0,1}?bc",[caseless,
@@ -26493,14 +26495,14 @@ run21() ->
{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("A]","a]",[caseless]))),
+ ok.
+run22() ->
<<"">> = iolist_to_binary(join(re:split("A]B","a[]]b",[caseless,
trim]))),
<<":">> = iolist_to_binary(join(re:split("A]B","a[]]b",[caseless,
{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("A]B","a[]]b",[caseless]))),
- ok.
-run22() ->
<<"">> = iolist_to_binary(join(re:split("AED","a[^bc]d",[caseless,
trim]))),
<<":">> = iolist_to_binary(join(re:split("AED","a[^bc]d",[caseless,
@@ -26660,14 +26662,14 @@ run22() ->
{parts,
2}]))),
<<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b)+",[caseless]))),
+ ok.
+run23() ->
<<":B">> = iolist_to_binary(join(re:split("AB","(a+|b){1,}",[caseless,
trim]))),
<<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b){1,}",[caseless,
{parts,
2}]))),
<<":B:">> = iolist_to_binary(join(re:split("AB","(a+|b){1,}",[caseless]))),
- ok.
-run23() ->
<<":A::B">> = iolist_to_binary(join(re:split("AB","(a+|b)?",[caseless,
trim]))),
<<":A:B">> = iolist_to_binary(join(re:split("AB","(a+|b)?",[caseless,
@@ -26776,14 +26778,14 @@ run23() ->
{parts,
2}]))),
<<":BC:">> = iolist_to_binary(join(re:split("ABC","a([bc]*)c*",[caseless]))),
+ ok.
+run24() ->
<<":BC:D">> = iolist_to_binary(join(re:split("ABCD","a([bc]*)(c*d)",[caseless,
trim]))),
<<":BC:D:">> = iolist_to_binary(join(re:split("ABCD","a([bc]*)(c*d)",[caseless,
{parts,
2}]))),
<<":BC:D:">> = iolist_to_binary(join(re:split("ABCD","a([bc]*)(c*d)",[caseless]))),
- ok.
-run24() ->
<<":BC:D">> = iolist_to_binary(join(re:split("ABCD","a([bc]+)(c*d)",[caseless,
trim]))),
<<":BC:D:">> = iolist_to_binary(join(re:split("ABCD","a([bc]+)(c*d)",[caseless,
@@ -26934,14 +26936,14 @@ run24() ->
{parts,
2}]))),
<<":A:B:">> = iolist_to_binary(join(re:split("(A, B)","\\((.*), (.*)\\)",[caseless]))),
+ ok.
+run25() ->
<<"">> = iolist_to_binary(join(re:split("ABCD","abcd",[caseless,
trim]))),
<<":">> = iolist_to_binary(join(re:split("ABCD","abcd",[caseless,
{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("ABCD","abcd",[caseless]))),
- ok.
-run25() ->
<<":BC">> = iolist_to_binary(join(re:split("ABCD","a(bc)d",[caseless,
trim]))),
<<":BC:">> = iolist_to_binary(join(re:split("ABCD","a(bc)d",[caseless,
@@ -27030,12 +27032,12 @@ run25() ->
<<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}?(.)",[{parts,
2}]))),
<<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,6}?(.)",[]))),
+ ok.
+run26() ->
<<":e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}(.)",[trim]))),
<<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}(.)",[{parts,
2}]))),
<<":e:">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}(.)",[]))),
- ok.
-run26() ->
<<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}?(.)",[trim]))),
<<":b:e">> = iolist_to_binary(join(re:split("acdbcdbe","a(?:b|c|d){5,7}?(.)",[{parts,
2}]))),
@@ -27160,12 +27162,12 @@ run26() ->
<<"c::">> = iolist_to_binary(join(re:split("cab","(a)*ab",[{parts,
2}]))),
<<"c::">> = iolist_to_binary(join(re:split("cab","(a)*ab",[]))),
+ ok.
+run27() ->
<<"">> = iolist_to_binary(join(re:split("ab","(?:(?i)a)b",[trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","(?:(?i)a)b",[{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("ab","(?:(?i)a)b",[]))),
- ok.
-run27() ->
<<":a">> = iolist_to_binary(join(re:split("ab","((?i)a)b",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("ab","((?i)a)b",[{parts,
2}]))),
@@ -27272,6 +27274,8 @@ run27() ->
{parts,
2}]))),
<<":a:">> = iolist_to_binary(join(re:split("aB","((?-i)a)b",[caseless]))),
+ ok.
+run28() ->
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?-i)a)b",[caseless,
trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?:(?-i)a)b",[caseless,
@@ -27290,8 +27294,6 @@ run27() ->
{parts,
2}]))),
<<"AB">> = iolist_to_binary(join(re:split("AB","(?:(?-i)a)b",[caseless]))),
- ok.
-run28() ->
<<"">> = iolist_to_binary(join(re:split("ab","(?-i:a)b",[caseless,
trim]))),
<<":">> = iolist_to_binary(join(re:split("ab","(?-i:a)b",[caseless,
@@ -27426,14 +27428,14 @@ B","((?s-i:a.))b",[caseless]))),
<<":">> = iolist_to_binary(join(re:split("aaac","^a(?#xxx){3}c",[{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("aaac","^a(?#xxx){3}c",[]))),
+ ok.
+run29() ->
<<"">> = iolist_to_binary(join(re:split("aaac","^a (?#xxx) (?#yyy) {3}c",[extended,
trim]))),
<<":">> = iolist_to_binary(join(re:split("aaac","^a (?#xxx) (?#yyy) {3}c",[extended,
{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("aaac","^a (?#xxx) (?#yyy) {3}c",[extended]))),
- ok.
-run29() ->
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<![cd])b",[trim]))),
<<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","(?<![cd])b",[{parts,
2}]))),
@@ -27686,12 +27688,12 @@ c","((?m)^b)",[]))),
<<"::">> = iolist_to_binary(join(re:split("a","(x)?(?(1)b|a)",[{parts,
2}]))),
<<"::">> = iolist_to_binary(join(re:split("a","(x)?(?(1)b|a)",[]))),
+ ok.
+run30() ->
<<"">> = iolist_to_binary(join(re:split("a","()?(?(1)b|a)",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","()?(?(1)b|a)",[{parts,
2}]))),
<<"::">> = iolist_to_binary(join(re:split("a","()?(?(1)b|a)",[]))),
- ok.
-run30() ->
<<"">> = iolist_to_binary(join(re:split("a","()?(?(1)a|b)",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","()?(?(1)a|b)",[{parts,
2}]))),
@@ -28074,6 +28076,8 @@ b","b\\z",[]))),
<<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999)...)foo",[{parts,
2}]))),
<<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}(?!999)...)foo",[]))),
+ ok.
+run32() ->
<<"123abc">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}...)(?<!999)foo",[trim]))),
<<"123abc:">> = iolist_to_binary(join(re:split("123abcfoo","(?<=\\d{3}...)(?<!999)foo",[{parts,
2}]))),
@@ -28090,8 +28094,6 @@ b","b\\z",[]))),
<<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}...)(?<!999)foo",[{parts,
2}]))),
<<"123999foo">> = iolist_to_binary(join(re:split("123999foo","(?<=\\d{3}...)(?<!999)foo",[]))),
- ok.
-run32() ->
<<":::abcd: xyz">> = iolist_to_binary(join(re:split("<a href=abcd xyz","<a[\\s]+href[\\s]*=[\\s]* # find <a href=
([\\\"\\'])? # find single or double quote
(?(1) (.*?)\\1 | ([^\\s]+)) # if quote found, match up to next matching
@@ -28305,26 +28307,6 @@ run32() ->
<<":bbab">> = iolist_to_binary(join(re:split("abbab","a*",[{parts,
2}]))),
<<":b:b:b:">> = iolist_to_binary(join(re:split("abbab","a*",[]))),
- <<":bcde">> = iolist_to_binary(join(re:split("abcde","^[a-\\d]",[trim]))),
- <<":bcde">> = iolist_to_binary(join(re:split("abcde","^[a-\\d]",[{parts,
- 2}]))),
- <<":bcde">> = iolist_to_binary(join(re:split("abcde","^[a-\\d]",[]))),
- <<":things">> = iolist_to_binary(join(re:split("-things","^[a-\\d]",[trim]))),
- <<":things">> = iolist_to_binary(join(re:split("-things","^[a-\\d]",[{parts,
- 2}]))),
- <<":things">> = iolist_to_binary(join(re:split("-things","^[a-\\d]",[]))),
- <<":digit">> = iolist_to_binary(join(re:split("0digit","^[a-\\d]",[trim]))),
- <<":digit">> = iolist_to_binary(join(re:split("0digit","^[a-\\d]",[{parts,
- 2}]))),
- <<":digit">> = iolist_to_binary(join(re:split("0digit","^[a-\\d]",[]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[a-\\d]",[trim]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[a-\\d]",[{parts,
- 2}]))),
- <<"*** Failers">> = iolist_to_binary(join(re:split("*** Failers","^[a-\\d]",[]))),
- <<"bcdef">> = iolist_to_binary(join(re:split("bcdef","^[a-\\d]",[trim]))),
- <<"bcdef">> = iolist_to_binary(join(re:split("bcdef","^[a-\\d]",[{parts,
- 2}]))),
- <<"bcdef">> = iolist_to_binary(join(re:split("bcdef","^[a-\\d]",[]))),
<<":bcde">> = iolist_to_binary(join(re:split("abcde","^[\\d-a]",[trim]))),
<<":bcde">> = iolist_to_binary(join(re:split("abcde","^[\\d-a]",[{parts,
2}]))),
@@ -28360,24 +28342,24 @@ run32() ->
<<">:
<">> = iolist_to_binary(join(re:split(">
<","[[:blank:]]+",[]))),
- <<">: <">> = iolist_to_binary(join(re:split(">
+ <<">:<">> = iolist_to_binary(join(re:split(">
<","[\\s]+",[trim]))),
- <<">: <">> = iolist_to_binary(join(re:split(">
+ <<">:<">> = iolist_to_binary(join(re:split(">
<","[\\s]+",[{parts,2}]))),
- <<">: <">> = iolist_to_binary(join(re:split(">
+ <<">:<">> = iolist_to_binary(join(re:split(">
<","[\\s]+",[]))),
- <<">: <">> = iolist_to_binary(join(re:split(">
+ <<">:<">> = iolist_to_binary(join(re:split(">
<","\\s+",[trim]))),
- <<">: <">> = iolist_to_binary(join(re:split(">
+ <<">:<">> = iolist_to_binary(join(re:split(">
<","\\s+",[{parts,2}]))),
- <<">: <">> = iolist_to_binary(join(re:split(">
+ <<">:<">> = iolist_to_binary(join(re:split(">
<","\\s+",[]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","a b",[extended,
+ <<"">> = iolist_to_binary(join(re:split("ab","a b",[extended,
trim]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","a b",[extended,
+ <<":">> = iolist_to_binary(join(re:split("ab","a b",[extended,
{parts,
2}]))),
- <<"ab">> = iolist_to_binary(join(re:split("ab","a b",[extended]))),
+ <<":">> = iolist_to_binary(join(re:split("ab","a b",[extended]))),
<<"a
:b">> = iolist_to_binary(join(re:split("a
xb","(?!\\A)x",[multiline,trim]))),
@@ -29577,10 +29559,6 @@ run37() ->
","[\\x00-\\xff\\s]+",[{parts,2}]))),
<<":">> = iolist_to_binary(join(re:split("
","[\\x00-\\xff\\s]+",[]))),
- <<"">> = iolist_to_binary(join(re:split("?","^\\c",[trim]))),
- <<":">> = iolist_to_binary(join(re:split("?","^\\c",[{parts,
- 2}]))),
- <<":">> = iolist_to_binary(join(re:split("?","^\\c",[]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1",[caseless,
trim]))),
<<"abc">> = iolist_to_binary(join(re:split("abc","(abc)\\1",[caseless,
@@ -29845,10 +29823,6 @@ run39() ->
<<"::c">> = iolist_to_binary(join(re:split("bc","(?=(a))??.",[{parts,
2}]))),
<<"::::">> = iolist_to_binary(join(re:split("bc","(?=(a))??.",[]))),
- <<"::ckgammon">> = iolist_to_binary(join(re:split("backgammon","^(?=(a)){0}b(?1)",[trim]))),
- <<"::ckgammon">> = iolist_to_binary(join(re:split("backgammon","^(?=(a)){0}b(?1)",[{parts,
- 2}]))),
- <<"::ckgammon">> = iolist_to_binary(join(re:split("backgammon","^(?=(a)){0}b(?1)",[]))),
<<":b">> = iolist_to_binary(join(re:split("abd","^(?=(?1))?[az]([abc])d",[trim]))),
<<":b:">> = iolist_to_binary(join(re:split("abd","^(?=(?1))?[az]([abc])d",[{parts,
2}]))),
@@ -30002,8 +29976,6 @@ c","(?<=a\\v)c",[]))),
<<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)*+Y",[{parts,
2}]))),
<<"X:X">> = iolist_to_binary(join(re:split("XcccddYX","(?(?=c)c|d)*+Y",[]))),
- ok.
-run40() ->
<<":aaa">> = iolist_to_binary(join(re:split("aaaaaaa","^(a{2,3}){2,}+a",[trim]))),
<<":aaa:">> = iolist_to_binary(join(re:split("aaaaaaa","^(a{2,3}){2,}+a",[{parts,
2}]))),
@@ -30020,6 +29992,8 @@ run40() ->
<<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a{2,3}){2,}+a",[{parts,
2}]))),
<<"aaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaa","^(a{2,3}){2,}+a",[]))),
+ ok.
+run40() ->
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})++a",[trim]))),
<<"** Failers">> = iolist_to_binary(join(re:split("** Failers","^(a{2,3})++a",[{parts,
2}]))),
@@ -30177,10 +30151,6 @@ AAA NNN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[]))),
<<"foo:foobar:">> = iolist_to_binary(join(re:split("foobarbaz","(foo\\Kbar)baz",[{parts,
2}]))),
<<"foo:foobar:">> = iolist_to_binary(join(re:split("foobarbaz","(foo\\Kbar)baz",[]))),
- <<":ab:b:XXXX">> = iolist_to_binary(join(re:split("ababababbbabZXXXX","^(a(b))\\1\\g1\\g{1}\\g-1\\g{-1}\\g{-02}Z",[trim]))),
- <<":ab:b:XXXX">> = iolist_to_binary(join(re:split("ababababbbabZXXXX","^(a(b))\\1\\g1\\g{1}\\g-1\\g{-1}\\g{-02}Z",[{parts,
- 2}]))),
- <<":ab:b:XXXX">> = iolist_to_binary(join(re:split("ababababbbabZXXXX","^(a(b))\\1\\g1\\g{1}\\g-1\\g{-1}\\g{-02}Z",[]))),
<<":tom">> = iolist_to_binary(join(re:split("tom-tom","(?<A>tom|bon)-\\g{A}",[trim]))),
<<":tom:">> = iolist_to_binary(join(re:split("tom-tom","(?<A>tom|bon)-\\g{A}",[{parts,
2}]))),
@@ -30213,8 +30183,6 @@ AAA NNN ","\\v*X\\v?Y\\v+Z\\V*\\x0a\\V+\\x0b\\V{2,3}\\x0c",[]))),
<<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))\\1",[{parts,
2}]))),
<<"xyzabc">> = iolist_to_binary(join(re:split("xyzabc","(?|(abc)|(xyz))\\1",[]))),
- ok.
-run41() ->
<<":abc">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))(?1)",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","(?|(abc)|(xyz))(?1)",[{parts,
2}]))),
@@ -30231,6 +30199,8 @@ run41() ->
<<"xyzxyz">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))(?1)",[{parts,
2}]))),
<<"xyzxyz">> = iolist_to_binary(join(re:split("xyzxyz","(?|(abc)|(xyz))(?1)",[]))),
+ ok.
+run41() ->
<<":a:b:c:d:Y">> = iolist_to_binary(join(re:split("XYabcdY","^X(?5)(a)(?|(b)|(q))(c)(d)(Y)",[trim]))),
<<":a:b:c:d:Y:">> = iolist_to_binary(join(re:split("XYabcdY","^X(?5)(a)(?|(b)|(q))(c)(d)(Y)",[{parts,
2}]))),
@@ -30428,8 +30398,6 @@ run41() ->
<<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(([^()]++|\\([^()]+\\))+\\)",[{parts,
2}]))),
<<"((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","\\(([^()]++|\\([^()]+\\))+\\)",[]))),
- ok.
-run42() ->
<<":c">> = iolist_to_binary(join(re:split("abc","^([^()]|\\((?1)*\\))*$",[trim]))),
<<":c:">> = iolist_to_binary(join(re:split("abc","^([^()]|\\((?1)*\\))*$",[{parts,
2}]))),
@@ -30450,6 +30418,8 @@ run42() ->
<<"a(b(c)d">> = iolist_to_binary(join(re:split("a(b(c)d","^([^()]|\\((?1)*\\))*$",[{parts,
2}]))),
<<"a(b(c)d">> = iolist_to_binary(join(re:split("a(b(c)d","^([^()]|\\((?1)*\\))*$",[]))),
+ ok.
+run42() ->
<<":3">> = iolist_to_binary(join(re:split(">abc>123<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[trim]))),
<<":3:">> = iolist_to_binary(join(re:split(">abc>123<xyz<","^>abc>([^()]|\\((?1)*\\))*<xyz<$",[{parts,
2}]))),
@@ -30798,8 +30768,6 @@ run42() ->
<<"b:a:z">> = iolist_to_binary(join(re:split("baz","(?<X>a)(?<=b(?&X))",[{parts,
2}]))),
<<"b:a:z">> = iolist_to_binary(join(re:split("baz","(?<X>a)(?<=b(?&X))",[]))),
- ok.
-run43() ->
<<":abc">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))\\1",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))\\1",[{parts,
2}]))),
@@ -30820,6 +30788,8 @@ run43() ->
<<"defabc">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))\\1",[{parts,
2}]))),
<<"defabc">> = iolist_to_binary(join(re:split("defabc","^(?|(abc)|(def))\\1",[]))),
+ ok.
+run43() ->
<<":abc">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))(?1)",[trim]))),
<<":abc:">> = iolist_to_binary(join(re:split("abcabc","^(?|(abc)|(def))(?1)",[{parts,
2}]))),
@@ -30994,8 +30964,6 @@ run43() ->
<<":0000:0:">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[{parts,
2}]))),
<<":0000:0:">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)(?P>L1)|(?P>L2))",[]))),
- ok.
-run44() ->
<<":0:0">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[trim]))),
<<":0:0:">> = iolist_to_binary(join(re:split("0","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[{parts,
2}]))),
@@ -31008,6 +30976,8 @@ run44() ->
<<":0:0:000">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[{parts,
2}]))),
<<":0:0::0:0::0:0::0:0:">> = iolist_to_binary(join(re:split("0000","(?P<L1>(?P<L2>0)|(?P>L2)(?P>L1))",[]))),
+ ok.
+run44() ->
<<"ACABX">> = iolist_to_binary(join(re:split("ACABX","A(*COMMIT)(B|D)",[trim]))),
<<"ACABX">> = iolist_to_binary(join(re:split("ACABX","A(*COMMIT)(B|D)",[{parts,
2}]))),
@@ -31044,8 +31014,6 @@ run44() ->
<<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(yes|no)(*THEN)(*F))?",[{parts,
2}]))),
<<"yes">> = iolist_to_binary(join(re:split("yes","(?>(*COMMIT)(yes|no)(*THEN)(*F))?",[]))),
- ok.
-run45() ->
<<"">> = iolist_to_binary(join(re:split("bc","b?(*SKIP)c",[trim]))),
<<":">> = iolist_to_binary(join(re:split("bc","b?(*SKIP)c",[{parts,
2}]))),
@@ -31054,6 +31022,8 @@ run45() ->
<<"a:">> = iolist_to_binary(join(re:split("abc","b?(*SKIP)c",[{parts,
2}]))),
<<"a:">> = iolist_to_binary(join(re:split("abc","b?(*SKIP)c",[]))),
+ ok.
+run45() ->
<<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)bc",[trim]))),
<<"a">> = iolist_to_binary(join(re:split("a","(*SKIP)bc",[{parts,
2}]))),
@@ -31272,14 +31242,14 @@ run45() ->
{parts,
2}]))),
<<":foo(bar(baz)+baz(bop)):(bar(baz)+baz(bop)):bar(baz)+baz(bop):">> = iolist_to_binary(join(re:split("foo(bar(baz)+baz(bop))","(foo ( \\( ((?:(?> [^()]+ )|(?2))*) \\) ) )",[extended]))),
- ok.
-run46() ->
<<":AB:B">> = iolist_to_binary(join(re:split("AB","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
trim]))),
<<":AB:B::">> = iolist_to_binary(join(re:split("AB","(A (A|B(*ACCEPT)|C) D)(E)",[extended,
{parts,
2}]))),
<<":AB:B::">> = iolist_to_binary(join(re:split("AB","(A (A|B(*ACCEPT)|C) D)(E)",[extended]))),
+ ok.
+run46() ->
<<":a">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)",[trim]))),
<<":a:">> = iolist_to_binary(join(re:split("ba","\\A.*?(a|bc)",[{parts,
2}]))),
@@ -31350,6 +31320,14 @@ def","^\\N{1,}",[]))),
<<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R1)a+|(?1)b))",[{parts,
2}]))),
<<":aaaab:cde">> = iolist_to_binary(join(re:split("aaaabcde","((?(R1)a+|(?1)b))",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))*",[trim]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))*",[{parts,
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))*",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))+",[trim]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))+",[{parts,
+ 2}]))),
+ <<":a:">> = iolist_to_binary(join(re:split("aaa","((?(R)a|(?1)))+",[]))),
<<"">> = iolist_to_binary(join(re:split("a","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[trim]))),
<<"::">> = iolist_to_binary(join(re:split("a","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[{parts,
2}]))),
@@ -31362,14 +31340,14 @@ def","^\\N{1,}",[]))),
<<"bb::">> = iolist_to_binary(join(re:split("bba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[{parts,
2}]))),
<<"bb::">> = iolist_to_binary(join(re:split("bba","(?>(?&t)c|(?&t))(?(DEFINE)(?<t>a|b(*PRUNE)c))",[]))),
+ ok.
+run47() ->
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b) c",[extended,
trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b) c",[extended,
{parts,
2}]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b) c",[extended]))),
- ok.
-run47() ->
<<":ab">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b|(*F)) c",[extended,
trim]))),
<<":ab:">> = iolist_to_binary(join(re:split("aabc","^.*? (a(*THEN)b|(*F)) c",[extended,
@@ -31460,14 +31438,14 @@ run47() ->
{parts,
2}]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? ( (a(*THEN)b)++ )++ c",[extended]))),
+ ok.
+run48() ->
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b)++ c",[extended,
trim]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b)++ c",[extended,
{parts,
2}]))),
<<"aabc">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b)++ c",[extended]))),
- ok.
-run48() ->
<<"">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b|(*F))++ c",[extended,
trim]))),
<<":">> = iolist_to_binary(join(re:split("aabc","^.*? (?:a(*THEN)b|(*F))++ c",[extended,
@@ -31546,12 +31524,12 @@ run48() ->
<<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*THEN)b)c",[{parts,
2}]))),
<<"xab:d">> = iolist_to_binary(join(re:split("xabcd","(?<=a(*THEN)b)c",[]))),
+ ok.
+run49() ->
<<":a:d">> = iolist_to_binary(join(re:split("abcd","(a)(?2){2}(.)",[trim]))),
<<":a:d:">> = iolist_to_binary(join(re:split("abcd","(a)(?2){2}(.)",[{parts,
2}]))),
<<":a:d:">> = iolist_to_binary(join(re:split("abcd","(a)(?2){2}(.)",[]))),
- ok.
-run49() ->
<<"hello world ">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1?)test",[trim]))),
<<"hello world :::">> = iolist_to_binary(join(re:split("hello world test","(another)?(\\1?)test",[{parts,
2}]))),
@@ -31606,12 +31584,12 @@ run49() ->
{parts,
2}]))),
<<"a:">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[dotall]))),
+ ok.
+run50() ->
<<"a">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[trim]))),
<<"a:">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[{parts,
2}]))),
<<"a:">> = iolist_to_binary(join(re:split("aab","(?>.*?a)b",[]))),
- ok.
-run50() ->
<<"aab">> = iolist_to_binary(join(re:split("aab","(?>^a)b",[dotall,
trim]))),
<<"aab">> = iolist_to_binary(join(re:split("aab","(?>^a)b",[dotall,
@@ -31898,12 +31876,12 @@ run53() ->
<<":">> = iolist_to_binary(join(re:split("bnn","(?=b(*THEN)a)bn|bnn",[{parts,
2}]))),
<<":">> = iolist_to_binary(join(re:split("bnn","(?=b(*THEN)a)bn|bnn",[]))),
+ ok.
+run54() ->
<<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*SKIP)b)..",[trim]))),
<<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*SKIP)b)..",[{parts,
2}]))),
<<":d">> = iolist_to_binary(join(re:split("acd","(?!a(*SKIP)b)..",[]))),
- ok.
-run54() ->
<<"ac">> = iolist_to_binary(join(re:split("ac","^(?(?!a(*SKIP)b))",[trim]))),
<<"ac">> = iolist_to_binary(join(re:split("ac","^(?(?!a(*SKIP)b))",[{parts,
2}]))),
@@ -31972,4 +31950,125 @@ run54() ->
{parts,
2}]))),
<<"aaa">> = iolist_to_binary(join(re:split("aaa","^a*\\w{4}",[caseless]))),
+ <<":1:non-sp1:non-sp2">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[trim]))),
+ <<":1:non-sp1:non-sp2:">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[{parts,
+ 2}]))),
+ <<":1:non-sp1:non-sp2:">> = iolist_to_binary(join(re:split("1 IN SOA non-sp1 non-sp2(","^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$",[]))),
+ <<"AZ">> = iolist_to_binary(join(re:split("AZ","^A\\xZ",[trim]))),
+ <<"AZ">> = iolist_to_binary(join(re:split("AZ","^A\\xZ",[{parts,
+ 2}]))),
+ <<"AZ">> = iolist_to_binary(join(re:split("AZ","^A\\xZ",[]))),
+ <<"">> = iolist_to_binary(join(re:split("ASB","^A\\o{123}B",[trim]))),
+ <<":">> = iolist_to_binary(join(re:split("ASB","^A\\o{123}B",[{parts,
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("ASB","^A\\o{123}B",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaab"," ^ a + + b $ ",[extended,
+ trim]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + + b $ ",[extended,
+ {parts,
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + + b $ ",[extended]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
+ + b $ ",[extended,trim]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
+ + b $ ",[extended,{parts,2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
+ + b $ ",[extended]))),
+ <<"">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
+ #comment
+ + b $ ",[extended,trim]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
+ #comment
+ + b $ ",[extended,{parts,2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ a + #comment
+ #comment
+ + b $ ",[extended]))),
+ ok.
+run55() ->
+ <<"">> = iolist_to_binary(join(re:split("aaaab"," ^ (?> a + ) b $ ",[extended,
+ trim]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ (?> a + ) b $ ",[extended,
+ {parts,
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aaaab"," ^ (?> a + ) b $ ",[extended]))),
+ <<":aaaa">> = iolist_to_binary(join(re:split("aaaab"," ^ ( a + ) + + \\w $ ",[extended,
+ trim]))),
+ <<":aaaa:">> = iolist_to_binary(join(re:split("aaaab"," ^ ( a + ) + + \\w $ ",[extended,
+ {parts,
+ 2}]))),
+ <<":aaaa:">> = iolist_to_binary(join(re:split("aaaab"," ^ ( a + ) + + \\w $ ",[extended]))),
+ <<"acb">> = iolist_to_binary(join(re:split("acb","(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc",[trim]))),
+ <<"acb">> = iolist_to_binary(join(re:split("acb","(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc",[{parts,
+ 2}]))),
+ <<"acb">> = iolist_to_binary(join(re:split("acb","(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc",[]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]*+|\\\"\\\")*+\\\")++",[trim]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]*+|\\\"\\\")*+\\\")++",[{parts,
+ 2}]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]*+|\\\"\\\")*+\\\")++",[]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")*+\\\")++",[trim]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")*+\\\")++",[{parts,
+ 2}]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")*+\\\")++",[]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")++\\\")++",[trim]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")++\\\")++",[{parts,
+ 2}]))),
+ <<":\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A(?:[^\\\"]++|\\\"(?:[^\\\"]++|\\\"\\\")++\\\")++",[]))),
+ <<": AFTER ::\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A([^\\\"1]++|[\\\"2]([^\\\"3]*+|[\\\"4][\\\"5])*+[\\\"6])++",[trim]))),
+ <<": AFTER ::\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A([^\\\"1]++|[\\\"2]([^\\\"3]*+|[\\\"4][\\\"5])*+[\\\"6])++",[{parts,
+ 2}]))),
+ <<": AFTER ::\"NOT MATCHED">> = iolist_to_binary(join(re:split("NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED","\\A([^\\\"1]++|[\\\"2]([^\\\"3]*+|[\\\"4][\\\"5])*+[\\\"6])++",[]))),
+ <<":t test">> = iolist_to_binary(join(re:split("test test","^\\w+(?>\\s*)(?<=\\w)",[trim]))),
+ <<":t test">> = iolist_to_binary(join(re:split("test test","^\\w+(?>\\s*)(?<=\\w)",[{parts,
+ 2}]))),
+ <<":t test">> = iolist_to_binary(join(re:split("test test","^\\w+(?>\\s*)(?<=\\w)",[]))),
+ <<":a">> = iolist_to_binary(join(re:split("acl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
+ <<":a::">> = iolist_to_binary(join(re:split("acl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[{parts,
+ 2}]))),
+ <<":a::">> = iolist_to_binary(join(re:split("acl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
+ <<"::b">> = iolist_to_binary(join(re:split("bdl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
+ <<"::b:">> = iolist_to_binary(join(re:split("bdl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[{parts,
+ 2}]))),
+ <<"::b:">> = iolist_to_binary(join(re:split("bdl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
+ <<"a">> = iolist_to_binary(join(re:split("adl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
+ <<"a:::">> = iolist_to_binary(join(re:split("adl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[{parts,
+ 2}]))),
+ <<"a:::">> = iolist_to_binary(join(re:split("adl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
+ <<"bc">> = iolist_to_binary(join(re:split("bcl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[trim]))),
+ <<"bc:::">> = iolist_to_binary(join(re:split("bcl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[{parts,
+ 2}]))),
+ <<"bc:::">> = iolist_to_binary(join(re:split("bcl","(?P<Name>a)?(?P<Name2>b)?(?(<Name>)c|d)*l",[]))),
+ <<"">> = iolist_to_binary(join(re:split(" abc","\\sabc",[trim]))),
+ <<":">> = iolist_to_binary(join(re:split(" abc","\\sabc",[{parts,
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split(" abc","\\sabc",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aa]]","[\\Qa]\\E]+",[trim]))),
+ <<":">> = iolist_to_binary(join(re:split("aa]]","[\\Qa]\\E]+",[{parts,
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aa]]","[\\Qa]\\E]+",[]))),
+ <<"">> = iolist_to_binary(join(re:split("aa]]","[\\Q]a\\E]+",[trim]))),
+ <<":">> = iolist_to_binary(join(re:split("aa]]","[\\Q]a\\E]+",[{parts,
+ 2}]))),
+ <<":">> = iolist_to_binary(join(re:split("aa]]","[\\Q]a\\E]+",[]))),
+ <<"1::::::2::::::3::::::4:abcd:abcd">> = iolist_to_binary(join(re:split("1234abcd","(?:((abcd))|(((?:(?:(?:(?:abc|(?:abcdef))))b)abcdefghi)abc)|((*ACCEPT)))",[trim]))),
+ <<"1::::::234abcd">> = iolist_to_binary(join(re:split("1234abcd","(?:((abcd))|(((?:(?:(?:(?:abc|(?:abcdef))))b)abcdefghi)abc)|((*ACCEPT)))",[{parts,
+ 2}]))),
+ <<"1::::::2::::::3::::::4:abcd:abcd::::">> = iolist_to_binary(join(re:split("1234abcd","(?:((abcd))|(((?:(?:(?:(?:abc|(?:abcdef))))b)abcdefghi)abc)|((*ACCEPT)))",[]))),
+ ok.
+run56() ->
+ <<"b:a:c">> = iolist_to_binary(join(re:split("baaaaaaaaac","(?1)(?#?'){8}(a)",[trim]))),
+ <<"b:a:c">> = iolist_to_binary(join(re:split("baaaaaaaaac","(?1)(?#?'){8}(a)",[{parts,
+ 2}]))),
+ <<"b:a:c">> = iolist_to_binary(join(re:split("baaaaaaaaac","(?1)(?#?'){8}(a)",[]))),
+ <<"a::b::c::d">> = iolist_to_binary(join(re:split("abcd","(?|(\\k'Pm')|(?'Pm'))",[trim]))),
+ <<"a::bcd">> = iolist_to_binary(join(re:split("abcd","(?|(\\k'Pm')|(?'Pm'))",[{parts,
+ 2}]))),
+ <<"a::b::c::d::">> = iolist_to_binary(join(re:split("abcd","(?|(\\k'Pm')|(?'Pm'))",[]))),
+ <<" :Fred:099">> = iolist_to_binary(join(re:split(" Fred:099","(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\\s])",[trim]))),
+ <<" :Fred:099">> = iolist_to_binary(join(re:split(" Fred:099","(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\\s])",[{parts,
+ 2}]))),
+ <<" :Fred:099">> = iolist_to_binary(join(re:split(" Fred:099","(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\\s])",[]))),
+ <<" ">> = iolist_to_binary(join(re:split(" X","(?=.*X)X$",[trim]))),
+ <<" :">> = iolist_to_binary(join(re:split(" X","(?=.*X)X$",[{parts,
+ 2}]))),
+ <<" :">> = iolist_to_binary(join(re:split(" X","(?=.*X)X$",[]))),
ok.
diff --git a/lib/stdlib/test/run_pcre_tests.erl b/lib/stdlib/test/run_pcre_tests.erl
index ae56db59d6..570a43f667 100644
--- a/lib/stdlib/test/run_pcre_tests.erl
+++ b/lib/stdlib/test/run_pcre_tests.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -18,8 +18,7 @@
%% %CopyrightEnd%
%%
-module(run_pcre_tests).
-
--compile(export_all).
+-export([test/1,gen_split_test/1,gen_repl_test/1]).
test(RootDir) ->
put(verbose,false),
@@ -119,49 +118,6 @@ test([{RE0,Line,Options0,Tests}|T],PreCompile,XMode,REAsList) ->
end
end.
-loopexec(_,_,X,Y,_,_) when X > Y ->
- {match,[]};
-loopexec(P,Chal,X,Y,Unicode,Xopt) ->
- case re:run(Chal,P,[{offset,X}]++Xopt) of
- nomatch ->
- {match,[]};
- {match,[{A,B}|More]} ->
- {match,Rest} =
- case B>0 of
- true ->
- loopexec(P,Chal,A+B,Y,Unicode,Xopt);
- false ->
- {match,M} = case re:run(Chal,P,[{offset,X},notempty,anchored]++Xopt) of
- nomatch ->
- {match,[]};
- {match,Other} ->
- {match,fixup(Chal,Other,0)}
- end,
- NewA = forward(Chal,A,1,Unicode),
- {match,MM} = loopexec(P,Chal,NewA,Y,Unicode,Xopt),
- {match,M ++ MM}
- end,
- {match,fixup(Chal,[{A,B}|More],0)++Rest}
- end.
-
-forward(_Chal,A,0,_) ->
- A;
-forward(_Chal,A,N,false) ->
- A+N;
-forward(Chal,A,N,true) ->
- <<_:A/binary,Tl/binary>> = Chal,
- Forw = case Tl of
- <<1:1,1:1,0:1,_:5,_/binary>> ->
- 2;
- <<1:1,1:1,1:1,0:1,_:4,_/binary>> ->
- 3;
- <<1:1,1:1,1:1,1:1,0:1,_:3,_/binary>> ->
- 4;
- _ ->
- 1
- end,
- forward(Chal,A+Forw,N-1,true).
-
contains_eightbit(<<>>) ->
false;
contains_eightbit(<<X:8,_/binary>>) when X >= 128 ->
@@ -201,23 +157,6 @@ clean_duplicates([X|T],L) ->
end.
-global_fixup(_,nomatch) ->
- nomatch;
-global_fixup(P,{match,M}) ->
- {match,lists:flatten(global_fixup2(P,M))}.
-
-global_fixup2(_,[]) ->
- [];
-global_fixup2(P,[H|T]) ->
- [gfixup_one(P,0,H)|global_fixup2(P,T)].
-
-gfixup_one(_,_,[]) ->
- [];
-gfixup_one(P,I,[{Start,Len}|T]) ->
- <<_:Start/binary,R:Len/binary,_/binary>> = P,
- [{I,R}|gfixup_one(P,I+1,T)].
-
-
press([]) ->
[];
press([H|T]) ->
@@ -450,6 +389,9 @@ stru([]) ->
[];
stru([{_,<<>>}|T]) ->
stru(T);
+stru([{_Line,<<"< forbid ", _Rest/binary>>}|T0]) ->
+ %% We do not handle lockout of modifiers from the tests...
+ stru(T0);
stru([{Line,<<Ch,Re0/binary>>}|T0]) ->
{T,Re} = find_rest_re(Ch,[{Line,Re0}|T0]),
{NewRe,<< Ch, Options/binary >>} = end_of_re(Ch,Re),
@@ -981,7 +923,7 @@ gen_split_test(OneFile) ->
ErlFileName = ErlModule++".erl",
{ok,F}= file:open(ErlFileName,[write]),
io:format(F,"-module(~s).~n",[ErlModule]),
- io:format(F,"-compile(export_all).~n",[]),
+ io:format(F,"-export([run/0]).~n",[]),
io:format(F,"-compile(no_native).~n",[]),
io:format(F,"%% This file is generated by running ~w:gen_split_test(~p)~n",
[?MODULE,OneFile]),
@@ -1024,7 +966,7 @@ dumponesplit(F,{RE,Line,O,TS}) ->
"$x =~~ s/\\\\/\\\\\\\\/g; $x =~~ s/\\\"/\\\\\"/g; "
"print \" <<\\\"$x\\\">> = "
"iolist_to_binary(join(re:split(\\\"~s\\\","
- "\\\"~s\\\",~p))), \\n\";'~n",
+ "\\\"~s\\\",~p))),\\n\";'~n",
[zsafe(safe(RE)),
SSS,
ysafe(safe(Str)),
@@ -1035,7 +977,7 @@ dumponesplit(F,{RE,Line,O,TS}) ->
"$x =~~ s/\\\\/\\\\\\\\/g; $x =~~ s/\\\"/\\\\\"/g; "
"print \" <<\\\"$x\\\">> = "
"iolist_to_binary(join(re:split(\\\"~s\\\","
- "\\\"~s\\\",~p))), \\n\";'~n",
+ "\\\"~s\\\",~p))),\\n\";'~n",
[zsafe(safe(RE)),
SSS,
ysafe(safe(Str)),
@@ -1046,7 +988,7 @@ dumponesplit(F,{RE,Line,O,TS}) ->
"$x =~~ s/\\\\/\\\\\\\\/g; $x =~~ s/\\\"/\\\\\"/g; "
"print \" <<\\\"$x\\\">> = "
"iolist_to_binary(join(re:split(\\\"~s\\\","
- "\\\"~s\\\",~p))), \\n\";'~n",
+ "\\\"~s\\\",~p))),\\n\";'~n",
[zsafe(safe(RE)),
SSS,
ysafe(safe(Str)),
@@ -1071,7 +1013,7 @@ gen_repl_test(OneFile) ->
ErlFileName = ErlModule++".erl",
{ok,F}= file:open(ErlFileName,[write]),
io:format(F,"-module(~s).~n",[ErlModule]),
- io:format(F,"-compile(export_all).~n",[]),
+ io:format(F,"-export([run/0]).~n",[]),
io:format(F,"-compile(no_native).~n",[]),
io:format(F,"%% This file is generated by running ~w:gen_repl_test(~p)~n",
[?MODULE,OneFile]),
diff --git a/lib/stdlib/test/shell_SUITE.erl b/lib/stdlib/test/shell_SUITE.erl
index dc82e92876..4f0fdc4c6a 100644
--- a/lib/stdlib/test/shell_SUITE.erl
+++ b/lib/stdlib/test/shell_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -30,7 +30,8 @@
progex_bit_syntax/1, progex_records/1,
progex_lc/1, progex_funs/1,
otp_5990/1, otp_6166/1, otp_6554/1,
- otp_7184/1, otp_7232/1, otp_8393/1, otp_10302/1]).
+ otp_7184/1, otp_7232/1, otp_8393/1, otp_10302/1, otp_13719/1,
+ otp_14285/1, otp_14296/1]).
-export([ start_restricted_from_shell/1,
start_restricted_on_command_line/1,restricted_local/1]).
@@ -91,7 +92,7 @@ groups() ->
progex_funs]},
{tickets, [],
[otp_5990, otp_6166, otp_6554, otp_7184,
- otp_7232, otp_8393, otp_10302]}].
+ otp_7232, otp_8393, otp_10302, otp_13719, otp_14285, otp_14296]}].
init_per_suite(Config) ->
Config.
@@ -282,7 +283,7 @@ restricted_local(Config) when is_list(Config) ->
comm_err(<<"begin F=fun() -> hello end, foo(F) end.">>),
"exception error: undefined shell command banan/1" =
comm_err(<<"begin F=fun() -> hello end, banan(F) end.">>),
- "{error,"++_ = t(<<"begin F=fun() -> hello end, c(F) end.">>),
+ "Recompiling "++_ = t(<<"c(shell_SUITE).">>),
"exception exit: restricted shell does not allow l(" ++ _ =
comm_err(<<"begin F=fun() -> hello end, l(F) end.">>),
"exception error: variable 'F' is unbound" =
@@ -375,6 +376,9 @@ records(Config) when is_list(Config) ->
[[state]] = scan(RR4),
Test = filename:join(proplists:get_value(priv_dir, Config), "test.erl"),
+ BeamDir = filename:join(proplists:get_value(priv_dir, Config), "beam"),
+ BeamFile = filename:join(BeamDir, "test"),
+ ok = file:make_dir(BeamDir),
Contents = <<"-module(test).
-record(state, {bin :: binary(),
reply = no,
@@ -386,8 +390,10 @@ records(Config) when is_list(Config) ->
-ifdef(test2).
-record(test2, {g}).
- -endif.">>,
+ -endif.
+ ">>,
ok = file:write_file(Test, Contents),
+ {ok, test} = compile:file(Test, [{outdir, BeamDir}]),
RR5 = "rr(\"" ++ Test ++ "\", '_', {d,test1}), rl([test1,test2]).",
A1 = erl_anno:new(1),
@@ -403,7 +409,11 @@ records(Config) when is_list(Config) ->
Dir = filename:join(proplists:get_value(priv_dir, Config), "*.erl"),
RR8 = "rp(rr(\"" ++ Dir ++ "\")).",
[_,ok] = scan(RR8),
+
+ {module, test} = code:load_abs(BeamFile),
+ [[state]] = scan(<<"rr(test).">>),
file:delete(Test),
+ file:delete(BeamFile++".beam"),
RR1000 = "begin rr(" ++ MS ++ ") end.",
[_] = scan(RR1000),
@@ -573,7 +583,7 @@ otp_5327(Config) when is_list(Config) ->
(catch evaluate(<<"<<32/unit:8>>.">>, [])),
ok.
-%% OTP-5435. sys_pre_expand not in the path.
+%% OTP-5435. compiler application not in the path.
otp_5435(Config) when is_list(Config) ->
true = <<103133:64/float>> =:=
evaluate(<<"<<103133:64/float>> = <<103133:64/float>>.">>, []),
@@ -591,8 +601,9 @@ start_node(Name) ->
otp_5435_2() ->
true = code:del_path(compiler),
- %% sys_pre_expand can no longer be found
- %% OTP-5876. But erl_expand_records can!
+ %% Make sure record evaluation is not dependent on the compiler
+ %% application being in the path.
+ %% OTP-5876.
[{attribute,_,record,{bar,_}},ok] =
scan(<<"rd(foo,{bar}),
rd(bar,{foo = (#foo{})#foo.bar}),
@@ -1793,7 +1804,7 @@ Test1_shell =
Test2 =
<<"-module(recs).
-record(person, {name, age, phone = [], dict = []}).
--compile(export_all).
+-export([t/0]).
t() -> ok.
@@ -1960,7 +1971,7 @@ ok.
progex_funs(Config) when is_list(Config) ->
Test1 =
<<"-module(funs).
- -compile(export_all).
+ -export([t/0]).
double([H|T]) -> [2*H|double(T)];
double([]) -> [].
@@ -2325,7 +2336,7 @@ otp_6554(Config) when is_list(Config) ->
"[unproper | list]).">>),
%% Cheating:
"exception error: no function clause matching "
- "erl_eval:do_apply(4)" ++ _ =
+ "shell:apply_fun(4)" ++ _ =
comm_err(<<"erlang:error(function_clause, [4]).">>),
"exception error: no function clause matching "
"lists:reverse(" ++ _ =
@@ -2669,7 +2680,7 @@ prompt_err(B) ->
S = string:strip(S2, both, $"),
string:strip(S, right, $.).
-%% OTP-10302. Unicode.
+%% OTP-10302. Unicode. Also OTP-14285, Unicode atoms.
otp_10302(Config) when is_list(Config) ->
{ok,Node} = start_node(shell_suite_helper_2,
"-pa "++proplists:get_value(priv_dir,Config)++
@@ -2807,9 +2818,143 @@ otp_10302(Config) when is_list(Config) ->
" erl_eval:'-inside-an-interpreted-fun-'(65,\"\x{441}\")"
" .\n" = t({Node,Test13}),
+ %% Unicode atoms.
+ Test14 = <<"'\\x{447}\\x{435}'().">>,
+ "** exception error: undefined shell command '\\x{447}\\x{435}'/0.\n" =
+ t(Test14),
+ Test15 = <<"io:setopts([{encoding,utf8}]).
+ '\\x{447}\\x{435}'().">>,
+ "ok.\n** exception error: undefined shell command '\x{447}\x{435}'/0.\n" =
+ t({Node,Test15}),
+ Test16 = <<"shell_SUITE:'\\x{447}\\x{435}'().">>,
+ "** exception error: undefined function "
+ "shell_SUITE:'\\x{447}\\x{435}'/0.\n" = t(Test16),
+ Test17 = <<"io:setopts([{encoding,utf8}]).
+ shell_SUITE:'\\x{447}\\x{435}'().">>,
+ "ok.\n** exception error: undefined function "
+ "shell_SUITE:'\x{447}\x{435}'/0.\n" =
+ t({Node,Test17}),
test_server:stop_node(Node),
ok.
+otp_13719(Config) when is_list(Config) ->
+ Test = <<"-module(otp_13719).
+ -record(bar, {}).
+ -record(foo, {bar :: #bar{}}).">>,
+ File = filename("otp_13719.erl", Config),
+ Beam = filename("otp_13719.beam", Config),
+ ok = compile_file(Config, File, Test, []),
+ RR = "rr(\"" ++ Beam ++ "\"). #foo{}.",
+ "[bar,foo]\n#foo{bar = undefined}.\n" = t(RR),
+ file:delete(filename("test.beam", Config)),
+ file:delete(File),
+ ok.
+
+otp_14285(Config) ->
+ {ok,Node} = start_node(shell_suite_helper_4,
+ "-pa "++proplists:get_value(priv_dir,Config)++
+ " +pc unicode"),
+ Test1 =
+ <<"begin
+ io:setopts([{encoding,utf8}]),
+ [1024] = atom_to_list('\\x{400}'),
+ rd('\\x{400}', {'\\x{400}' = '\\x{400}'}),
+ ok = rl('\\x{400}')
+ end.">>,
+ "-record('\x{400}',{'\x{400}' = '\x{400}'}).\nok.\n" =
+ t({Node,Test1}),
+ test_server:stop_node(Node),
+ ok.
+
+otp_14296(Config) when is_list(Config) ->
+ fun() ->
+ F = fun() -> a end,
+ LocalFun = term_to_string(F),
+ S = LocalFun ++ ".",
+ "1: syntax error before: Fun" = comm_err(S)
+ end(),
+
+ fun() ->
+ F = fun mod:func/1,
+ ExternalFun = term_to_string(F),
+ S = ExternalFun ++ ".",
+ R = ExternalFun ++ ".\n",
+ R = t(S)
+ end(),
+
+ fun() ->
+ UnknownPid = "<100000.0.0>",
+ S = UnknownPid ++ ".",
+ "1: syntax error before: '<'" = comm_err(S)
+ end(),
+
+ fun() ->
+ KnownPid = term_to_string(self()),
+ S = KnownPid ++ ".",
+ R = KnownPid ++ ".\n",
+ R = t(S)
+ end(),
+
+ fun() ->
+ Port = open_port({spawn, "ls"}, [line]),
+ KnownPort = erlang:port_to_list(Port),
+ S = KnownPort ++ ".",
+ R = KnownPort ++ ".\n",
+ R = t(S)
+ end(),
+
+ fun() ->
+ UnknownPort = "#Port<100000.0>",
+ S = UnknownPort ++ ".",
+ "1: syntax error before: Port" = comm_err(S)
+ end(),
+
+ fun() ->
+ UnknownRef = "#Ref<100000.0.0.0>",
+ S = UnknownRef ++ ".",
+ "1: syntax error before: Ref" = comm_err(S)
+ end(),
+
+ fun() ->
+ KnownRef = term_to_string(make_ref()),
+ S = KnownRef ++ ".",
+ R = KnownRef ++ ".\n",
+ R = t(S)
+ end(),
+
+ %% Test lib:extended_parse_term/1
+ TF = fun(S) ->
+ {ok, Ts, _} = erl_scan:string(S++".", 1, [text]),
+ case lib:extended_parse_term(Ts) of
+ {ok, Term} -> Term;
+ {error, _}=Error -> Error
+ end
+ end,
+ Fun = fun m:f/1,
+ Fun = TF(term_to_string(Fun)),
+ Fun = TF("fun m:f/1"),
+ Pid = self(),
+ Pid = TF(term_to_string(Pid)),
+ Ref = make_ref(),
+ Ref = TF(term_to_string(Ref)),
+ Term = {[10, a], {"foo", []}, #{x => <<"bar">>}},
+ Term = TF(lists:flatten(io_lib:format("~p", [Term]))),
+ {$a, F1, "foo"} = TF("{$a, 1.0, \"foo\"}"),
+ true = is_float(F1),
+ 3 = TF("+3"),
+ $a = TF("+$a"),
+ true = is_float(TF("+1.0")),
+ true = -3 =:= TF("-3"),
+ true = -$a =:= TF("-$a"),
+ true = is_float(TF("-1.0")),
+ {error, {_, _, ["syntax error"++_|_]}} = TF("{1"),
+ {error, {_,_,"bad term"}} = TF("fun() -> foo end"),
+ {error, {_,_,"bad term"}} = TF("1, 2"),
+ ok.
+
+term_to_string(T) ->
+ lists:flatten(io_lib:format("~w", [T])).
+
scan(B) ->
F = fun(Ts) ->
case erl_parse:parse_term(Ts) of
@@ -3017,7 +3162,7 @@ run_file(Config, Module, Test) ->
ok.
compile_file(Config, File, Test, Opts0) ->
- Opts = [export_all,return,{outdir,proplists:get_value(priv_dir, Config)}|Opts0],
+ Opts = [export_all,nowarn_export_all,return,{outdir,proplists:get_value(priv_dir, Config)}|Opts0],
ok = file:write_file(File, Test),
case compile:file(File, Opts) of
{ok, _M, _Ws} -> ok;
diff --git a/lib/stdlib/test/sofs_SUITE.erl b/lib/stdlib/test/sofs_SUITE.erl
index 13c12ad2f2..39e56c6df6 100644
--- a/lib/stdlib/test/sofs_SUITE.erl
+++ b/lib/stdlib/test/sofs_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1783,7 +1783,7 @@ multiple_relative_product(Conf) when is_list(Conf) ->
ok.
digraph(Conf) when is_list(Conf) ->
- T0 = ets:all(),
+ T0 = lists:sort(ets:all()),
E = empty_set(),
R = relation([{a,b},{b,c},{c,d},{d,a}]),
F = relation_to_family(R),
@@ -1833,15 +1833,12 @@ digraph(Conf) when is_list(Conf) ->
true -> ok
end,
- true = T0 == ets:all(),
+ true = T0 == lists:sort(ets:all()),
ok.
digraph_fail(ExitReason, Fail) ->
- {'EXIT', {ExitReason, [{sofs,family_to_digraph,A,_}|_]}} = Fail,
- case {test_server:is_native(sofs),A} of
- {false,[_,_]} -> ok;
- {true,2} -> ok
- end.
+ {'EXIT', {ExitReason, [{sofs,family_to_digraph,2,_}|_]}} = Fail,
+ ok.
constant_function(Conf) when is_list(Conf) ->
E = empty_set(),
diff --git a/lib/stdlib/test/string_SUITE.erl b/lib/stdlib/test/string_SUITE.erl
index 836f9e5142..90f980c0e5 100644
--- a/lib/stdlib/test/string_SUITE.erl
+++ b/lib/stdlib/test/string_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,25 +29,48 @@
-export([init_per_testcase/2, end_per_testcase/2]).
%% Test cases must be exported.
--export([len/1,equal/1,concat/1,chr_rchr/1,str_rstr/1]).
--export([span_cspan/1,substr/1,tokens/1,chars/1]).
+-export([is_empty/1, length/1, to_graphemes/1,
+ reverse/1, slice/1,
+ equal/1,
+ pad/1, trim/1, chomp/1, take/1,
+ uppercase/1, lowercase/1, titlecase/1, casefold/1,
+ to_integer/1,to_float/1,
+ prefix/1, split/1, replace/1, find/1,
+ lexemes/1, nth_lexeme/1, cd_gc/1, meas/1
+ ]).
+
+-export([len/1,old_equal/1,old_concat/1,chr_rchr/1,str_rstr/1]).
+-export([span_cspan/1,substr/1,old_tokens/1,chars/1]).
-export([copies/1,words/1,strip/1,sub_word/1,left_right/1]).
-export([sub_string/1,centre/1, join/1]).
--export([to_integer/1,to_float/1]).
+-export([old_to_integer/1,old_to_float/1]).
-export([to_upper_to_lower/1]).
+%% Run tests when debugging them
+-export([debug/0]).
+
suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap,{minutes,1}}].
-all() ->
- [len, equal, concat, chr_rchr, str_rstr, span_cspan,
- substr, tokens, chars, copies, words, strip, sub_word,
- left_right, sub_string, centre, join, to_integer,
- to_float, to_upper_to_lower].
+all() ->
+ [{group, chardata}, {group, list_string}].
-groups() ->
- [].
+groups() ->
+ [{chardata,
+ [is_empty, length, to_graphemes,
+ equal, reverse, slice,
+ pad, trim, chomp, take,
+ lexemes, nth_lexeme,
+ to_integer, to_float,
+ uppercase, lowercase, titlecase, casefold,
+ prefix, find, split, replace, cd_gc,
+ meas]},
+ {list_string,
+ [len, old_equal, old_concat, chr_rchr, str_rstr, span_cspan,
+ substr, old_tokens, chars, copies, words, strip, sub_word,
+ left_right, sub_string, centre, join, old_to_integer,
+ old_to_float, to_upper_to_lower]}].
init_per_suite(Config) ->
Config.
@@ -68,8 +91,875 @@ init_per_testcase(_Case, Config) ->
end_per_testcase(_Case, _Config) ->
ok.
+debug() ->
+ Config = [{data_dir, ?MODULE_STRING++"_data"}],
+ [io:format("~p:~p~n",[Test,?MODULE:Test(Config)]) ||
+ {_,Tests} <- groups(), Test <- Tests].
+
+-define(TEST(B,C,D), test(?LINE,?FUNCTION_NAME,B,C,D, true)).
+-define(TEST_EQ(B,C,D),
+ test(?LINE,?FUNCTION_NAME,B,C,D, true),
+ test(?LINE,?FUNCTION_NAME,hd(C),[B|tl(C),D, true)).
+
+-define(TEST_NN(B,C,D),
+ test(?LINE,?FUNCTION_NAME,B,C,D, false),
+ test(?LINE,?FUNCTION_NAME,hd(C),[B|tl(C)],D, false)).
+
+
+is_empty(_) ->
+ ?TEST("", [], true),
+ ?TEST([""|<<>>], [], true),
+ ?TEST("a", [], false),
+ ?TEST([""|<<$a>>], [], false),
+ ?TEST(["",[<<>>]], [], true),
+ ok.
+
+length(_) ->
+ %% invalid arg type
+ {'EXIT',_} = (catch string:length({})),
+ {'EXIT',_} = (catch string:length(foo)),
+ %% Valid signs
+ ?TEST("", [], 0),
+ ?TEST([""|<<>>], [], 0),
+ L = tuple_size(list_to_tuple(atom_to_list(?MODULE))),
+ ?TEST(atom_to_list(?MODULE), [], L),
+ ?TEST("Hello", [], 5),
+ ?TEST("UC Ω ßð", [], 7),
+ ?TEST(["abc"|<<"abc">>], [], 6),
+ ?TEST(["abc",["def"]], [], 6),
+ ?TEST([<<97/utf8, 778/utf8, 98/utf8>>, [776,111,776]], [], 3), %% åäö in nfd
+ ok.
+
+equal(_) ->
+ %% invalid arg type
+ {'EXIT',_} = (catch string:equal(1, 2)),
+ {'EXIT',_} = (catch string:equal(1, 2, foo)),
+ {'EXIT',_} = (catch string:equal(1, 2, true, foo)),
+
+ ?TEST("", [<<"">>], true),
+ ?TEST("Hello", ["Hello"], true),
+ ?TEST("Hello", ["Hell"], false),
+ ?TEST("Hello", ["Hello!"], false),
+ ?TEST("Hello", [<<"Hello"/utf8>>], true),
+ ?TEST("Hello", [<<"Mello"/utf8>>], false),
+ ?TEST("Hello", [<<"Hello!"/utf8>>], false),
+ ?TEST(["Hello",[" deep"]], ["Hello deep"], true),
+ ?TEST(["Hello",[<<" deep"/utf8>>]], ["Hello deep"], true),
+ ?TEST("Hello deep", [["Hello", [" deep"]]], true),
+ ?TEST("Hello deep", [["Hello", [" d!eep"]]], false),
+ ?TEST("Hello deep", [["Hello", [<<" deep"/utf8>>]]], true),
+ false = string:equal("Åäö", [<<97/utf8, 778/utf8, 98/utf8>>, [776,111,776]]), %% nfc vs nfd
+
+ %% case_insensitive_equal()
+ ?TEST("", ["", true], true),
+ ?TEST("a", ["b", true], false),
+ ?TEST("", [<<>>, true], true),
+ ?TEST("", [[<<>>,[]], true], true),
+ ?TEST("", [[<<>>,[$a]], true], false),
+ ?TEST("123", ["123", true], true),
+ ?TEST("abc", ["abc", true], true),
+ ?TEST([[],<<>>,"ABC"|<<>>], [["abc",[]], true], true),
+ ?TEST("ABCa", ["abcå", true], false),
+ ?TEST("åäö", [{norm,"åäö"}, true], true),
+ ?TEST("ÅÄÖ", [{norm,"åäö"}, true], true),
+ ?TEST("MICHAŁ", ["michał", true], true),
+ ?TEST(["Mic",<<"HAŁ"/utf8>>], ["michał", true], true),
+ ?TEST("ß SHARP S", ["ss sharp s", true], true),
+ ?TEST("ẞ SHARP S", [[<<$ß/utf8, $\s>>,"SHARP S"], true], true),
+ ?TEST("ẞ SHARP ß", ["ss sharp s", true], false),
+ ?TEST(<<"İ I WITH DOT ABOVE"/utf8>>, ["i̇ i with dot above", true], true),
+ %% These should be equivalent with the above
+ true = string:equal(string:casefold(["Mic",<<"HAŁ"/utf8>>]), string:casefold("michał")),
+ true = string:equal(string:casefold("ẞ SHARP S"), string:casefold([<<$ß/utf8, $\s>>,"SHARP S"])),
+ false = string:equal(string:casefold("ẞ SHARP ß"), string:casefold("ss sharp s")),
+
+ %% Normalization
+ ?TEST_NN("", ["", true, none], true),
+ ?TEST_NN("a", ["b", true, nfc], false),
+ ?TEST_NN("a", ["b", true, nfd], false),
+ ?TEST_NN("a", ["b", true, nfkc], false),
+ ?TEST_NN("a", ["b", true, nfkd], false),
+
+ ?TEST_NN("a", ["A", false, nfc], false),
+ ?TEST_NN("a", ["A", false, nfd], false),
+ ?TEST_NN([<<>>,"a"|<<>>], ["A", true, nfkc], true),
+ ?TEST_NN(<<"a">>, ["A", true, nfkd], true),
+
+ ?TEST_NN([$a, <<$b>>, [97,776]], ["abä", false, none], false),
+ ?TEST_NN([$a, <<$b>>, [97,776]], ["abä", false, nfc], true),
+ ?TEST_NN([$a, <<$b>>, [97,776]], ["abä", false, nfd], true),
+ ?TEST_NN([$a, <<$b>>, [97,776]], ["abä", false, nfkc], true),
+ ?TEST_NN([$a, <<$b>>, [97,776]], ["abä", false, nfkd], true),
+
+ ?TEST_NN([$a, <<$b>>, [97,776]], ["abÄ", true, none], false),
+ ?TEST_NN([$a, <<$b>>, [97,776]], ["abÄ", false, nfc], false),
+ ?TEST_NN([$a, <<$b>>, [97,776]], ["abÄ", true, nfc], true),
+ ?TEST_NN([$a, <<$b>>, [97,776]], ["abÄ", true, nfd], true),
+ ?TEST_NN([$a, <<$b>>, [97,776]], ["abÄ", true, nfkc], true),
+ ?TEST_NN([$a, <<$b>>, [97,776]], ["abÄ", true, nfkd], true),
+
+ ?TEST_NN([$a, <<$b>>, "ホンダ"], ["abホンダ", true, none], false),
+ ?TEST_NN([$a, <<$b>>, "ホンダ"], ["abホンダ", true, nfc], false),
+ ?TEST_NN([$a, <<$b>>, "ホンダ"], ["abホンダ", true, nfd], false),
+ ?TEST_NN([$a, <<$b>>, "ホンダ"], ["abホンダ", true, nfkc], true),
+ ?TEST_NN([$a, <<$b>>, "ホンダ"], ["abホンダ", true, nfkd], true),
+
+ ?TEST_NN([$a, <<$b>>, "32"], ["ab32", true, none], false),
+ ?TEST_NN([$a, <<$b>>, "32"], ["ab32", true, nfc], false),
+ ?TEST_NN([$a, <<$b>>, "32"], ["ab32", true, nfd], false),
+ ?TEST_NN([$a, <<$b>>, "32"], ["ab32", true, nfkc], true),
+ ?TEST_NN([$a, <<$b>>, "32"], ["ab32", true, nfkd], true),
+
+ %% Coverage.
+ ?TEST("", [<<"">>, false, nfc], true),
+ ?TEST("", [<<"">>, true, nfc], true),
+
+ ok.
+
+to_graphemes(_) ->
+ %% More tests are in unicode_util_SUITE.erl
+ {'EXIT', _} = (catch unicode:characters_to_nfd_binary(["asdåäö", an_atom])),
+ String = ["abc..åäö", $e, 788, <<"Ωµe`è"/utf8>>, "œŒþæÆħ§ß"],
+ NFD = unicode:characters_to_nfd_list(String),
+ [] = string:to_graphemes([]),
+ [] = string:to_graphemes(<<>>),
+ GCs = string:to_graphemes(String),
+ true = erlang:length(GCs) =:= string:length(String),
+ true = erlang:length(GCs) =:= erlang:length(string:to_graphemes(NFD)),
+ true = erlang:length(GCs) =:=
+ erlang:length(string:to_graphemes(unicode:characters_to_nfc_list(String))),
+ ok.
+
+reverse(_) ->
+ {'EXIT',_} = (catch string:reverse(2)),
+ Str1 = "Hello ",
+ Str2 = "Ω ßð",
+ Str3 = "åäö",
+ ?TEST("", [], ""),
+ ?TEST(Str1, [], lists:reverse(Str1)),
+ ?TEST(Str2, [], lists:reverse(Str2)),
+ ?TEST(Str3, [], lists:reverse(Str3)),
+ true = string:reverse(Str3) =:= lists:reverse(string:to_graphemes(Str3)),
+ ok.
+
+slice(_) ->
+ {'EXIT',_} = (catch string:slice(2, 2, 2)),
+ {'EXIT',_} = (catch string:slice("asd", foo, 2)),
+ {'EXIT',_} = (catch string:slice("asd", 2, -1)),
+ ?TEST("", [3], ""),
+ ?TEST("aåä", [1, 0], ""),
+ ?TEST("aåä", [3], ""),
+ ?TEST("aåäöbcd", [3], "öbcd"),
+ ?TEST([<<"aå"/utf8>>,"äöbcd"], [3], "öbcd"),
+ ?TEST([<<"aåä"/utf8>>,"öbcd"], [3], "öbcd"),
+ ?TEST([<<"aåä"/utf8>>,"öbcd"], [3, infinity], "öbcd"),
+
+ ?TEST("", [3, 2], ""),
+ ?TEST("aåä", [3, 2], ""),
+ ?TEST("aåäöbcd", [3,2], "öb"),
+ ?TEST([<<"aå"/utf8>>,"äöbcd"], [3,3], "öbc"),
+ ?TEST([<<"aåä"/utf8>>,"öbcd"], [3,10], "öbcd"),
+
+ ok.
+
+pad(_) ->
+ Str = "Hallå",
+ ?TEST(Str, [7], "Hallå "),
+ ?TEST(Str, [7, leading], " Hallå"),
+ ?TEST(Str, [4, both, $.], "Hallå"),
+ ?TEST(Str, [10, both, $.], "..Hallå..."),
+ ?TEST(Str, [10, leading, $.], ".....Hallå"),
+ ?TEST(Str, [10, trailing, $.], "Hallå....."),
+ ?TEST(Str++["f"], [10, trailing, $.], "Hallåf...."),
+ ?TEST(Str++[" flåwer"], [10, trailing, $.], "Hallå flåwer"),
+ ok.
+
+trim(_) ->
+ Str = "\t\s..Ha\s.llå..\t\n\r",
+ ?TEST("", [], ""),
+ ?TEST(Str, [both, "x"], Str),
+ ?TEST(Str, [leading], "..Ha\s.llå..\t\n\r"),
+ ?TEST(Str, [trailing], "\t\s..Ha\s.llå.."),
+ ?TEST(Str, [], "..Ha .llå.."),
+ ?TEST(".. ", [both, ""], ".. "),
+ ?TEST([<<".. ">>], [both, ". "], ""),
+ ?TEST(".. h.ej ..", [leading, ". "], "h.ej .."),
+ ?TEST(".. h.ej ..", [trailing, ". "], ".. h.ej"),
+ ?TEST(".. h.ej ..", [both, ". "], "h.ej"),
+ ?TEST(["..", <<"h.ej">>, ".."], [both, ". "], "h.ej"),
+ ?TEST([[], "..", " h.ej ", <<"..">>], [both, ". "], "h.ej"),
+ ?TEST([<<>>,<<"..">>, " h.ej", <<" ..">>], [both, ". "], "h.ej"),
+ ?TEST([<<>>,<<"..">>, " h.ej", <<" ..">>], [trailing, ". "], ".. h.ej"),
+ ?TEST([<<".. h.ej .">>, <<"..">>], [both, ". "], "h.ej"),
+ ?TEST(["..h", ".e", <<"j..">>], [both, ". "], "h.ej"),
+ ?TEST(["..h", <<".ejsa"/utf8>>, "n.."], [both, ". "], "h.ejsan"),
+ %% Test that it behaves with graphemes (i.e. nfd tests are the hard part)
+ ?TEST("aaåaa", [both, "a"], "å"),
+ ?TEST(["aaa",778,"äöoo"], [both, "ao"], "åäö"),
+ ?TEST([<<"aaa">>,778,"äöoo"], [both, "ao"], "åäö"),
+ ?TEST([<<"e">>,778,"åäöe", <<778/utf8>>], [both, [[$e,778]]], "åäö"),
+ ?TEST([[<<"!v">>|<<204,128,$v,204,129>>]],[trailing, [[$v,769]]], [$!,$v,768]),
+ ?TEST([[[<<"v">>|<<204,129,118,204,128,118>>],769,118,769]], [trailing, [[118,769]]], [$v,769,$v,768]),
+ ?TEST([<<"vv">>|<<204,128,118,204,128>>], [trailing, [[118,768]]], "v"),
+ ok.
+
+chomp(_) ->
+ Str = "åäö\na\r\nsd\n",
+ Res = "åäö\na\r\nsd",
+ ?TEST("", [], ""),
+ ?TEST("\n", [], ""),
+ ?TEST("str \t", [], "str \t"),
+ ?TEST("str \t\n\r", [], "str \t\n\r"),
+ ?TEST(Str, [], Res),
+ ?TEST([Str,$\n], [], Res),
+ ?TEST([Str|"\n"], [], Res),
+ ?TEST([Str|<<"\n">>], [], Res),
+ ?TEST([Str,$\r|<<"\n">>], [], Res),
+ ?TEST([Str, <<$\r>>|"\n"], [], Res),
+ ?TEST([<<$a,$\r>>,"\na\n"], [], "a\r\na"),
+ ok.
+
+take(_) ->
+ Str = "\t\s..Ha\s.llå..\t\n\r",
+ WS = "\t\s\n\r",
+ Chars = lists:seq($a,$z)++lists:seq($A,$Z),
+ %% complement=false, dir=leading
+ ?TEST("", ["abc"], {"",""}),
+ ?TEST(Str, ["x"], {[], Str}),
+ ?TEST(Str, [WS], {"\t\s","..Ha\s.llå..\t\n\r"}),
+ ?TEST(".. ", ["", false], {"", ".. "}),
+ ?TEST([<<".. ">>], [". ", false, leading], {".. ", ""}),
+ ?TEST(".. h.ej ..", [". ", false, leading], {".. ", "h.ej .."}),
+ ?TEST(["..", <<"h.ej">>, ".."], [". ", false, leading], {"..", "h.ej.."}),
+ ?TEST([[], "..", " h.ej ", <<"..">>], [". ", false, leading], {".. ","h.ej .."}),
+ ?TEST([<<>>,<<"..">>, " h.ej", <<" ..">>], [". ", false, leading], {".. ", "h.ej .."}),
+ ?TEST(["..h", <<".ejsa"/utf8>>, "n.."], [". ", false, leading], {"..", "h.ejsan.."}),
+ ?TEST([[<<101,204,138,33>>]], [[[$e,778]]], {[$e,778], "!"}),
+ %% Test that it behaves with graphemes (i.e. nfd tests are the hard part)
+ ?TEST("aaåaa", ["a", false, leading], {"aa", "åaa"}),
+ ?TEST(["aaa",778,"äöoo"], ["ao", false, leading], {"aa", "åäöoo"}),
+ ?TEST([<<"aaa">>,778,"äöoo"], ["ao",false,leading], {"aa", "åäöoo"}),
+ ?TEST([<<"e">>,778,"åäöe", <<778/utf8>>], [[[$e,778]], false, leading], {[$e,778],"åäöe"++[778]}),
+
+ %% complement=true, dir=leading
+ ?TEST("", ["abc", true], {"",""}),
+ ?TEST(Str, ["x", true], {Str, []}),
+ ?TEST(Str, [Chars, true], {"\t\s..","Ha\s.llå..\t\n\r"}),
+ ?TEST(".. ", ["",true], {".. ", ""}),
+ ?TEST([<<".. ">>], [Chars, true, leading], {".. ", ""}),
+ ?TEST(".. h.ej ..", [Chars, true, leading], {".. ", "h.ej .."}),
+ ?TEST(["..", <<"h.ej">>, ".."], [Chars, true, leading], {"..", "h.ej.."}),
+ ?TEST([[], "..", " h.ej ", <<"..">>], [Chars, true, leading], {".. ","h.ej .."}),
+ ?TEST([<<>>,<<"..">>, " h.ej", <<" ..">>], [Chars, true, leading], {".. ", "h.ej .."}),
+ ?TEST(["..h", <<".ejsa"/utf8>>, "n.."], [Chars, true, leading], {"..", "h.ejsan.."}),
+ %% Test that it behaves with graphemes (i.e. nfd tests are the hard part)
+ ?TEST(["aaee",778,"äöoo"], [[[$e,778]], true, leading], {"aae", [$e,778|"äöoo"]}),
+ ?TEST([<<"aae">>,778,"äöoo"], [[[$e,778]],true,leading], {"aa", [$e,778|"äöoo"]}),
+ ?TEST([<<"e">>,778,"åäöe", <<778/utf8>>], [[[$e,778]], true, leading], {[], [$e,778]++"åäöe"++[778]}),
+
+ %% complement=false, dir=trailing
+ ?TEST(Str, ["", false, trailing], {Str, []}),
+ ?TEST(Str, ["x", false, trailing], {Str, []}),
+ ?TEST(Str, [WS, false,trailing], {"\t\s..Ha\s.llå..", "\t\n\r"}),
+ ?TEST(".. h.ej ..", [". ", false, trailing], {".. h.ej", " .."}),
+ ?TEST(["..", <<"h.ej">>, ".."], [". ", false, trailing], {"..h.ej", ".."}),
+ ?TEST([[], "..", " h.ej ", <<"..">>], [". ", false, trailing], {".. h.ej", " .."}),
+ ?TEST([<<>>,<<"..">>, " h.ej", <<" ..">>], [". ", false, trailing], {".. h.ej", " .."}),
+ ?TEST(["..h", <<".ejsa"/utf8>>, "n.."], [". ", false, trailing], {"..h.ejsan", ".."}),
+ ?TEST("aaåaa", ["a", false, trailing], {"aaå", "aa"}),
+ ?TEST([<<"KMШ"/utf8>>], [[1064], false, trailing], {"KMШ",[]}),
+ ?TEST([[<<"!\"">>|<<"\"">>]], ["\"", false, trailing], {"!", "\"\""}),
+ ?TEST([<<$v>>, 769], [[[$v,769]], false, trailing], {"", [$v,769]}),
+ ?TEST(["aaa",778,"äöoo"], ["ao", false, trailing], {"aaåäö", "oo"}),
+ ?TEST([<<"aaa">>,778,"äöoo"], ["ao", false, trailing], {"aaåäö", "oo"}),
+ ?TEST([<<"e">>,778,"åäöee", <<778/utf8>>], [[[$e,778]], false, trailing], {[$e,778|"åäöe"], [$e,778]}),
+
+ %% complement=true, dir=trailing
+ ?TEST("", ["abc", true, trailing], {"",""}),
+ ?TEST(Str, ["x", true, trailing], {[], Str}),
+ %?TEST(Str, [{norm,Chars}, true, trailing], {"\t\s..Ha\s.ll","å..\t\n\r"}),
+ ?TEST(".. ", ["", true, trailing], {"", ".. "}),
+ ?TEST([<<".. ">>], [Chars, true, trailing], {"", ".. "}),
+ ?TEST(".. h.ej ..", [Chars, true, trailing], {".. h.ej", " .."}),
+ ?TEST(["..", <<"h.ej">>, ".."], [Chars, true, trailing], {"..h.ej", ".."}),
+ ?TEST([[], "..", " h.ej ", <<"..">>], [Chars, true, trailing], {".. h.ej"," .."}),
+ ?TEST([<<>>,<<"..">>, " h.ej", <<" ..">>], [Chars, true, trailing], {".. h.ej"," .."}),
+ ?TEST(["..h", <<".ejsa"/utf8>>, "n.."], [Chars, true, trailing], {"..h.ejsan", ".."}),
+ ?TEST([[<<101,204,138,33>>]], [[[$e,778]], true, trailing], {[$e,778], "!"}),
+ ?TEST([<<"Fa">>], [[$F], true, trailing], {"F", "a"}),
+ ?TEST([[<<101,101,204,138>>,1045,778]], ["e", true, trailing], {"e", [101,778,1045,778]}),
+ ?TEST([[<<101,101,204,138>>,<<1045/utf8,778/utf8>>]], ["e", true, trailing], {"e", [101,778,1045,778]}),
+ ?TEST([[[118,769,118],<<204,129,118,204,129,120,204,128,118>>,768,120,768]],
+ [[[118,769]], true, trailing], {[118,769,118,769,118,769],[120,768,118,768,120,768]}),
+ ?TEST([[<<118,204,128,118>>|<<204,128,118,204,128,118,204,128,206,132,204,129,206,132,204,129>>]],
+ [[[118,768]], true, trailing], {[118,768,118,768,118,768,118,768], [900,769,900,769]}),
+ %% Test that it behaves with graphemes (i.e. nfd tests are the hard part)
+ ?TEST(["aaee",778,"äöoo"], [[[$e,778]], true, trailing], {"aae"++[$e,778], "äöoo"}),
+ ?TEST([<<"aae">>,778,"äöoo"], [[[$e,778]],true,trailing], {"aa"++[$e,778], "äöoo"}),
+ ?TEST([<<"e">>,778,"åäöe", <<778/utf8>>], [[[$e,778]], true, trailing], {[$e,778]++"åäöe"++[778], []}),
+ ?TEST([<<"e">>,778,"åäöe", <<778/utf8>>, $e, 779], [[[$e,778]], true, trailing],
+ {[$e,778]++"åäöe"++[778], [$e,779]}),
+
+ ok.
+
+
+uppercase(_) ->
+ ?TEST("", [], ""),
+ ?TEST("123", [], "123"),
+ ?TEST("abc", [], "ABC"),
+ ?TEST("ABC", [], "ABC"),
+ ?TEST("abcdefghiljklmnopqrstvxyzåäö",[], "ABCDEFGHILJKLMNOPQRSTVXYZÅÄÖ"),
+ ?TEST("åäö", [], "ÅÄÖ"),
+ ?TEST("ÅÄÖ", [], "ÅÄÖ"),
+ ?TEST("Michał", [], "MICHAŁ"),
+ ?TEST(["Mic",<<"hał"/utf8>>], [], "MICHAŁ"),
+ ?TEST("ljLJ", [], "LJLJ"),
+ ?TEST("LJlj", [], "LJLJ"),
+ ?TEST("ß sharp s", [], "SS SHARP S"),
+ ok.
+
+lowercase(_) ->
+ ?TEST("", [], ""),
+ ?TEST("123", [], "123"),
+ ?TEST("abc", [], "abc"),
+ ?TEST("ABC", [], "abc"),
+ ?TEST("åäö", [], "åäö"),
+ ?TEST("ÅÄÖ", [], "åäö"),
+ ?TEST("MICHAŁ", [], "michał"),
+ ?TEST(["Mic",<<"HAŁ"/utf8>>], [], "michał"),
+ ?TEST("ß SHARP S", [], "ß sharp s"),
+ ?TEST("İ I WITH DOT ABOVE", [], "i̇ i with dot above"),
+ ok.
+
+titlecase(_) ->
+ ?TEST("", [], ""),
+ ?TEST("123", [], "123"),
+ %% Titlecase is the same as uppercase for most chars
+ [?TEST([C,$x], [], string:uppercase([C])++[$x]) ||
+ C <-"abcdefghiljklmnopqrstvxyzåäö"],
+ %% Example of a different mapping
+ ?TEST("ljusad", [],"Ljusad"),
+ ?TEST("ljLJ", [], "LjLJ"),
+ ?TEST("LJlj", [], "Ljlj"),
+ ?TEST("ß sharp s", [], "Ss sharp s"),
+ ok.
+
+casefold(_) ->
+ ?TEST("", [], ""),
+ ?TEST("123", [], "123"),
+ ?TEST("abc", [], "abc"),
+ ?TEST("ABC", [], "abc"),
+ ?TEST("åäö", [], "åäö"),
+ ?TEST("ÅÄÖ", [], "åäö"),
+ ?TEST("MICHAŁ", [], "michał"),
+ ?TEST(["Mic",<<"HAŁ"/utf8>>], [], "michał"),
+ ?TEST("ß SHARP S", [], "ss sharp s"),
+ ?TEST("ẞ SHARP S", [], "ss sharp s"),
+ ?TEST("İ I WITH DOT ABOVE", [], "i̇ i with dot above"),
+ ok.
+
+
+to_integer(_) ->
+ ?TEST("", [], {error, no_integer}),
+ ?TEST("-", [], {error, no_integer}),
+ ?TEST("01", [], {1, ""}),
+ ?TEST("1.53", [], {1, ".53"}),
+ ?TEST("+01.53", [], {1, ".53"}),
+ ?TEST("-1.53", [], {-1, ".53"}),
+ ?TEST("-13#16FF", [], {-13, "#16FF"}),
+ ?TEST("13xFF", [], {13, "xFF"}),
+ ?TEST(["234", <<"3+4-234">>], [], {2343, "+4-234"}),
+ ok.
+
+to_float(_) ->
+ ?TEST("", [], {error, no_float}),
+ ?TEST("1.53", [], {1.53, ""}),
+ ?TEST("+01.53foo", [], {1.53, "foo"}),
+ ?TEST("-1.53foo", [], {-1.53, "foo"}),
+ ?TEST("-1,53foo", [], {-1.53, "foo"}),
+ ?TEST("-1,53e1foo", [], {-15.3, "foo"}),
+ ?TEST("-1,53e-1", [], {-0.153, ""}),
+ ?TEST("-1,53E-1+2", [], {-0.153, "+2"}),
+ ?TEST(["-1,53", <<"E-1+2">>], [], {-0.153, "+2"}),
+ ok.
+
+prefix(_) ->
+ ?TEST("", ["a"], nomatch),
+ ?TEST("a", [""], "a"),
+ ?TEST("b", ["a"], nomatch),
+ ?TEST("a", ["a"], ""),
+ ?TEST("å", ["a"], nomatch),
+ ?TEST(["a",<<778/utf8>>], ["a"], nomatch),
+ ?TEST([<<"a"/utf8>>,778], ["a"], nomatch),
+ ?TEST("hejsan", [""], "hejsan"),
+ ?TEST("hejsan", ["hej"], "san"),
+ ?TEST("hejsan", ["hes"], nomatch),
+ ?TEST(["h", "ejsan"], ["hej"], "san"),
+ ?TEST(["h", "e", "jsan"], ["hej"], "san"),
+ ?TEST(["h", "e", "san"], ["hej"], nomatch),
+ ?TEST(["h", <<"ejsan">>], ["hej"], "san"),
+ ?TEST(["h", <<"e">>, "jsan"], ["hej"], "san"),
+ ?TEST(["h", "e", <<"jsan">>], ["hej"], "san"),
+ ok.
+
+split(_) ->
+ Mod = fun(Res) ->
+ [lists:flatten(unicode:characters_to_nfc_list(io_lib:format("~ts", [Str])))
+ || Str <- Res] end,
+ ?TEST("..", ["", leading], {Mod, [".."]}),
+ ?TEST("..", ["..", leading], {Mod, [[],[]]}),
+ ?TEST("abcd", ["..", leading], {Mod, ["abcd"]}),
+ ?TEST("ab..bc", ["..", leading], {Mod, ["ab","bc"]}),
+ ?TEST("ab..bc..cd", ["..", leading], {Mod, ["ab","bc..cd"]}),
+ ?TEST("..ab", [".."], {Mod, [[],"ab"]}),
+ ?TEST("ab..", ["..", leading], {Mod, ["ab",[]]}),
+ ?TEST(["ab..bc..cd"], ["..", leading], {Mod, ["ab","bc..cd"]}),
+ ?TEST(["ab","..bc..cd"], ["..", leading], {Mod, ["ab","bc..cd"]}),
+ ?TEST(["ab",<<"..bc..cd">>], ["..", leading], {Mod, ["ab","bc..cd"]}),
+ ?TEST(["ab.",".bc..cd"], ["..", leading], {Mod, ["ab","bc..cd"]}),
+ ?TEST(["ab.",<<".bc..cd">>], ["..", leading], {Mod, ["ab","bc..cd"]}),
+ ?TEST(["ab..","bc..cd"], ["..", leading], {Mod, ["ab","bc..cd"]}),
+ ?TEST(["ab..",<<"bc..cd">>], ["..", leading], {Mod, ["ab","bc..cd"]}),
+ ?TEST(["ab.","bc..cd"], ["..", leading], {Mod, ["ab.bc","cd"]}),
+ ?TEST("ab...bc", ["..", leading], {Mod, ["ab",".bc"]}),
+
+ ?TEST("..", ["", trailing], {Mod, [".."]}),
+ ?TEST("..", ["..", trailing], {Mod, [[],[]]}),
+ ?TEST("abcd", ["..", trailing], {Mod, ["abcd"]}),
+ ?TEST("ab..bc", ["..", trailing], {Mod, ["ab","bc"]}),
+ ?TEST("ab..bc..cd", ["..", trailing], {Mod, ["ab..bc","cd"]}),
+ ?TEST("..ab", ["..", trailing], {Mod, [[],"ab"]}),
+ ?TEST("ab..", ["..", trailing], {Mod, ["ab",[]]}),
+ ?TEST(["ab..bc..cd"], ["..", trailing], {Mod, ["ab..bc","cd"]}),
+ ?TEST(["ab","..bc..cd"], ["..", trailing], {Mod, ["ab..bc","cd"]}),
+ ?TEST(["ab"|<<"a">>], ["a", trailing], {Mod, ["ab",[]]}),
+ ?TEST(["ab",<<"..bc..cd">>], ["..", trailing], {Mod, ["ab..bc","cd"]}),
+ ?TEST([<<"ab.">>,".bc..cd"], ["..", trailing], {Mod, ["ab..bc","cd"]}),
+ ?TEST(["ab.",<<".bc..cd">>], ["..", trailing], {Mod, ["ab..bc","cd"]}),
+ ?TEST(["ab..","bc..cd"], ["..", trailing], {Mod, ["ab..bc","cd"]}),
+ ?TEST(["ab..",<<"bc..cd">>], ["..", trailing], {Mod, ["ab..bc","cd"]}),
+ ?TEST(["ab.","bc..cd"], ["..", trailing], {Mod, ["ab.bc","cd"]}),
+ ?TEST("ab...bc", ["..", trailing], {Mod, ["ab.","bc"]}),
+
+ ?TEST("..", ["..", all], {Mod, [[],[]]}),
+ ?TEST("abcd", ["..", all], {Mod, ["abcd"]}),
+ ?TEST("a..b", ["..", all], {Mod, ["a","b"]}),
+ ?TEST("a..b..c", ["..", all], {Mod, ["a","b","c"]}),
+ ?TEST("a..", ["..", all], {Mod, ["a",[]]}),
+ ?TEST(["a..b..c"], ["..", all], {Mod, ["a","b","c"]}),
+ ?TEST(["a","..b..c"], ["..", all], {Mod, ["a","b","c"]}),
+ ?TEST(["a",<<"..b..c">>], ["..", all], {Mod, ["a","b","c"]}),
+ ?TEST(["a.",".b..c"], ["..", all], {Mod, ["a","b","c"]}),
+ ?TEST(["a.",<<".b..c">>], ["..", all], {Mod, ["a","b","c"]}),
+ ?TEST(["a..","b..c"], ["..", all], {Mod, ["a","b","c"]}),
+ ?TEST(["a..",<<"b..c">>], ["..", all], {Mod, ["a","b","c"]}),
+ ?TEST(["a.","b..c"], ["..", all], {Mod, ["a.b","c"]}),
+ ?TEST("a...b", ["..", all], {Mod, ["a",".b"]}),
+
+ %% Grapheme (split) tests
+ ?TEST("aΩΩb", ["Ω", all], {Mod, ["a","","b"]}),
+ ?TEST([<<"aae">>,778,"äöoo"], [[$e,778], leading], {Mod, ["aa","äöoo"]}),
+ ?TEST([<<"aae">>,778,"äöoo"], [[$e,778], trailing], {Mod, ["aa","äöoo"]}),
+ ?TEST([<<"aae">>,778,"äöoo"], [[$e,778], all], {Mod, ["aa","äöoo"]}),
+ ?TEST([<<"aae">>,778,"öeeåäö"], ["e", leading], {Mod, [[$a, $a, $e,778,$ö],"eåäö"]}),
+ ?TEST([<<"aae">>,778,"öeeåäö"], ["e", trailing], {Mod, [[$a, $a, $e,778,$ö, $e],"åäö"]}),
+ ?TEST([<<"aae">>,778,"öeeåäö"], ["e", all], {Mod, [[$a, $a, $e,778,$ö],"", "åäö"]}),
+
+ ok.
+
+replace(_) ->
+ ?TEST(["a..b.", [".c"]], ["xxx", "::"], "a..b..c"),
+ ?TEST(["a..b.", [".c"]], ["..", "::"], "a::b..c"),
+ ?TEST([<<"a..b.">>, [".c"]], ["..", "::", trailing], "a..b::c"),
+ ?TEST(["a..b.", [".c"]], ["..", "::", all], "a::b::c"),
+ ok.
+
+cd_gc(_) ->
+ [] = string:next_codepoint(""),
+ [] = string:next_codepoint(<<>>),
+ [] = string:next_codepoint([<<>>]),
+ "abcd" = string:next_codepoint("abcd"),
+ [$e,778] = string:next_codepoint([$e,778]),
+ [$e|<<204,138>>] = string:next_codepoint(<<$e,778/utf8>>),
+ [778|_] = string:next_codepoint(tl(string:next_codepoint(<<$e,778/utf8>>))),
+ [0|<<128,1>>] = string:next_codepoint(<<0,128,1>>),
+ {error,<<128,1>>} = string:next_codepoint(<<128,1>>),
+
+ [] = string:next_grapheme(""),
+ [] = string:next_grapheme(<<>>),
+ [] = string:next_grapheme([<<>>]),
+ "abcd" = string:next_grapheme("abcd"),
+ [[$e,778]] = string:next_grapheme([$e,778]),
+ [[$e,778]] = string:next_grapheme(<<$e,778/utf8>>),
+ [0|<<128,1>>] = string:next_grapheme(<<0,128,1>>),
+ {error,<<128,1>>} = string:next_grapheme(<<128,1>>),
+
+ ok.
+
+
+find(_) ->
+ ?TEST(["h", "ejsan"], [""], "hejsan"),
+ ?TEST(["h", "ejsan"], [<<>>], "hejsan"),
+ ?TEST([], [""], ""),
+ ?TEST([], ["hej"], nomatch),
+ ?TEST(["h", "ejsan"], ["hej"], "hejsan"),
+ ?TEST(["h", "e", "jsan"], ["hej"], "hejsan"),
+ ?TEST(["xh", "e", "san"], ["hej"], nomatch),
+ ?TEST([<<"xh">>, <<"ejsan">>], ["hej"], "hejsan"),
+ ?TEST(["xh", <<"ejsan">>], ["hej"], "hejsan"),
+ ?TEST(["xh", <<"e">>, "jsan"], ["hej"], "hejsan"),
+ ?TEST(["xh", "e", <<"jsan">>], ["hej"], "hejsan"),
+ ?TEST(["xh", "er", <<"ljsane">>, "rlang"], ["erl", leading], "erljsanerlang"),
+ ?TEST("aΩΩb", ["Ω", leading], "ΩΩb"),
+ ?TEST([<<"aae">>,778,"äöoo"], [[$e,778], leading], [$e,778]++"äöoo"),
+ ?TEST([<<"aae">>,778,"öeeåäö"], ["e", leading], "eeåäö"),
+
+ ?TEST(["h", "ejsan"], ["", trailing], "hejsan"),
+ ?TEST([], ["", trailing], ""),
+ ?TEST([], ["hej", trailing], nomatch),
+ ?TEST(["h", "ejsan"], ["hej", trailing], "hejsan"),
+ ?TEST(["h", "e", "jsan"], ["hej", trailing], "hejsan"),
+ ?TEST(["xh", "e", "san"], ["hej", trailing], nomatch),
+ ?TEST([<<"xh">>, <<"ejsan">>], ["hej", trailing], "hejsan"),
+ ?TEST(["xh", <<"ejsan">>], ["hej", trailing], "hejsan"),
+ ?TEST(["xh", <<"e">>, "jsan"], ["hej", trailing], "hejsan"),
+ ?TEST(["xh", "e", <<"jsan">>], ["hej", trailing], "hejsan"),
+ ?TEST(["xh", "er", <<"ljsane">>, "rlang"], ["erl", trailing], "erlang"),
+ ?TEST("aΩΩb", ["Ω", trailing], "Ωb"),
+ ?TEST([<<"aae">>,778,"äöoo"], [[$e,778], trailing], [$e,778]++"äöoo"),
+ ?TEST([<<"aeae">>,778,"äö"], ["e", trailing], "eae"++[778,$ä,$ö]),
+
+ ok.
+
+lexemes(_) ->
+ Mod = fun(Res) ->
+ [unicode:characters_to_nfc_list(io_lib:format("~ts", [Str]))|| Str <- Res]
+ end,
+ Res = ["Hej", "san", "Hopp", "san"],
+ ?TEST("", [" ,."], {Mod, []}),
+ ?TEST("Hej san", [""], {Mod, ["Hej san"]}),
+ ?TEST(" ,., ", [" ,."], {Mod, []}),
+ ?TEST( "Hej san Hopp san", [" ,."], {Mod, Res}),
+ ?TEST(" Hej san Hopp san ", [" ,."], {Mod, Res}),
+ ?TEST(" Hej san, .Hopp san ", [" ,."], {Mod, Res}),
+
+ ?TEST([" Hej san",", .Hopp san "], [" ,."], {Mod, Res}),
+ ?TEST([" Hej sa","n, .Hopp san "], [" ,."], {Mod, Res}),
+ ?TEST([" Hej san,"," .Hopp san "], [" ,."], {Mod, Res}),
+
+ ?TEST([" Hej san",[", .Hopp san "]], [" ,."], {Mod, Res}),
+ ?TEST([" Hej sa",["n, .Hopp san "]], [" ,."], {Mod, Res}),
+ ?TEST([" Hej san,",[" .Hopp san "]], [" ,."], {Mod, Res}),
+
+ ?TEST([" H",<<"ej san, .Hopp "/utf8>>, "san"], [" ,."], {Mod, Res}),
+ ?TEST([" Hej san",<<", .Hopp "/utf8>>, "san"], [" ,."], {Mod, Res}),
+ ?TEST([" Hej sa",<<"n, .Hopp"/utf8>>, " san"], [" ,."], {Mod, Res}),
+ ?TEST([" Hej san,",<<" .Hopp s"/utf8>>, "an"], [" ,."], {Mod, Res}),
+ ?TEST([" Hej san",[<<", .Hopp san "/utf8>>]], [" ,."], {Mod, Res}),
+ ?TEST([" Hej sa",[<<"n, .Hopp san "/utf8>>]], [" ,."], {Mod, Res}),
+ ?TEST([" Hej san,",[<<" .Hopp san "/utf8>>], <<" ">>], [" ,."], {Mod, Res}),
+
+ ?TEST(" Hej\r\nsan\nnl", ["\r\n\s"], {Mod, ["Hej\r\nsan", "nl"]}),
+
+ ?TEST(["b1ec1e",778,"äöo21"], ["eo"], {Mod, ["b1",[$c,$1,$e,778,$ä,$ö],"21"]}),
+ ?TEST([<<"b1ec1e">>,778,"äöo21"], ["eo"], {Mod, ["b1",[$c,$1,$e,778,$ä,$ö],"21"]}),
+ %% Grapheme (split) tests
+ Str10 = [[[<<"÷"/utf8>>,1101],<<"ë"/utf8>>|<<"\"">>]],
+ ?TEST(Str10, [[1076]], {Mod, [unicode:characters_to_nfc_list(Str10)]}),
+ ?TEST("a1Ωb1Ωc1", ["Ω"], {Mod, ["a1","b1","c1"]}),
+ ?TEST([<<"aae">>,778,"äöoo"], [[[$e,778]]], {Mod, ["aa","äöoo"]}),
+ ?TEST([<<"aae">>,778,"äöo21"], [[[$e,778],$o]], {Mod, ["aa","äö","21"]}),
+ ?TEST([<<"aae">>,778,"öeeåäö"], ["e"], {Mod, [[$a, $a, $e,778,$ö],"åäö"]}),
+ ok.
+
+nth_lexeme(_) ->
+ {'EXIT', _} = (catch string:nth_lexeme("test test", 0, [])),
+ {'EXIT', _} = (catch string:nth_lexeme(<<"test test">>, 0, [])),
+ ?TEST( "", [1, " ,."], []),
+ ?TEST( "Hej san", [1, ""], "Hej san"),
+ ?TEST( " ,., ", [1, " ,."], []),
+ ?TEST( " ,., ", [3, " ,."], []),
+ ?TEST("Hej san Hopp san", [1, " ,."], "Hej"),
+ ?TEST("...Hej san Hopp san", [1, " ,."], "Hej"),
+ ?TEST("Hej san Hopp san", [3, " ,."], "Hopp"),
+ ?TEST(" Hej san Hopp san ", [3, " ,."], "Hopp"),
+ ?TEST(" Hej san, .Hopp san ", [3, " ,."], "Hopp"),
+ ?TEST("ab cd", [3, " "], ""),
+
+ ?TEST([" Hej san",", .Hopp san "], [3, " ,."], "Hopp"),
+ ?TEST([" Hej sa","n, .Hopp san "], [3, " ,."], "Hopp"),
+ ?TEST([" Hej san,"," .Hopp san "], [3, " ,."], "Hopp"),
+
+ ?TEST([" Hej san",[", .Hopp san "]], [3," ,."], "Hopp"),
+ ?TEST([" Hej sa",["n, .Hopp san "]], [3, " ,."], "Hopp"),
+ ?TEST([" Hej san,",[" .Hopp san "]], [3, " ,."], "Hopp"),
+
+ ?TEST([" Hej san",<<", .Hopp "/utf8>>, "san"], [3, " ,."], "Hopp"),
+ ?TEST([" Hej sa",<<"n, .Hopp"/utf8>>, " san"], [3, " ,."], "Hopp"),
+ ?TEST([" Hej san,",<<" .Hopp s"/utf8>>, "an"], [3, " ,."], "Hopp"),
+ ?TEST([" Hej san,",<<" .Hopp s"/utf8>>, "an"], [4, " ,."], "san"),
+ ?TEST([" Hej san",[<<", .Hopp san "/utf8>>]], [3, " ,."], "Hopp"),
+ ?TEST([" Hej sa",[<<"n, .Hopp san "/utf8>>]], [3, " ,."], "Hopp"),
+ ?TEST([" Hej san,",[<<" .Hopp san "/utf8>>], <<" ">>], [3, " ,."], "Hopp"),
+
+ ?TEST(["b1ec1e",778,"äöo21"], [3,"eo"], "21"),
+ ?TEST([<<"b1ec1e">>,778,"äöo21"], [3, "eo"], "21"),
+ %% Grapheme (split) tests
+ ?TEST("a1Ωb1Ωc1", [1, "Ω"], "a1"),
+ ?TEST([<<"aae">>,778,"äöoo"], [2,[[$e,778]]], "äöoo"),
+ ?TEST([<<"aae">>,778,"äöo21"], [2,[[$e,778],$o]], "äö"),
+ ?TEST([<<"aae">>,778,"öeeåäö"], [2,"e"], "åäö"),
+ ok.
+
+
+meas(Config) ->
+ case ct:get_timetrap_info() of
+ {_,{_,Scale}} when Scale > 1 ->
+ {skip,{will_not_run_in_debug,Scale}};
+ _ -> % No scaling
+ DataDir = proplists:get_value(data_dir, Config),
+ TestDir = filename:dirname(string:trim(DataDir, trailing, "/")),
+ do_measure(TestDir)
+ end.
+
+do_measure(TestDir) ->
+ File = filename:join(TestDir, ?MODULE_STRING ++ ".erl"),
+ io:format("File ~s ",[File]),
+ {ok, Bin} = file:read_file(File),
+ io:format("~p~n",[byte_size(Bin)]),
+ Do = fun(Name, Func, Mode) ->
+ {N, Mean, Stddev, _} = time_func(Func, Mode, Bin),
+ io:format("~10w ~6w ~6.2fms ±~4.2fms #~.2w gc included~n",
+ [Name, Mode, Mean/1000, Stddev/1000, N])
+ end,
+ io:format("----------------------~n"),
+ Do(tokens, fun(Str) -> string:tokens(Str, [$\n,$\r]) end, list),
+ Tokens = {lexemes, fun(Str) -> string:lexemes(Str, [$\n,$\r]) end},
+ [Do(Name,Fun,Mode) || {Name,Fun} <- [Tokens], Mode <- [list, binary]],
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% internal functions
+
+test(Line, Func, Str, Args, Res, Norm) ->
+ %%io:format("~p: ~p ~w ~w~n",[Line, Func, Str, Args]),
+ test_1(Line, Func, Str, [Str|norm(none,Args)], Res),
+ %%io:format("~p: ~p bin ",[Line, Func]),
+ test_1({Line,list}, Func, Str,
+ [unicode:characters_to_list(Str)|norm(none,Args)], Res),
+ Norm andalso
+ test_1({Line,clist}, Func, Str,
+ [unicode:characters_to_nfc_list(Str)|norm(nfc,Args)], Res),
+ Norm andalso
+ test_1({Line,dlist}, Func, Str,
+ [unicode:characters_to_nfd_list(Str)|norm(nfd,Args)], Res),
+ test_1({Line,bin}, Func, Str,
+ [unicode:characters_to_binary(Str)|norm(none, Args)], Res),
+ Norm andalso
+ test_1({Line,cbin}, Func, Str,
+ [unicode:characters_to_nfc_binary(Str)|norm(nfc,Args)], Res),
+ Norm andalso
+ test_1({Line,dbin}, Func, Str,
+ [unicode:characters_to_nfd_binary(Str)|norm(nfd,Args)], Res),
+ %%io:format("~n",[]),
+ ok.
+
+test_1(Line, Func, Str, Args, Exp) ->
+ try
+ Res = apply(string, Func, Args),
+ check_types(Line, Func, Args, Res),
+ case res(Res, Exp) of
+ true -> ok;
+ {Res1,Exp1} when is_tuple(Exp1) ->
+ io:format("~p~n",[Args]),
+ io:format("~p:~p: ~ts~w =>~n :~w:~w~n",
+ [Func,Line, Str,Str,Res1,Exp1]),
+ exit({error, Func});
+ {Res1,Exp1} ->
+ io:format("~p:~p: ~ts~w =>~n :~ts~w:~ts~w~n",
+ [Func,Line, Str,Str, Res1,Res1, Exp1,Exp1]),
+ exit({error, Func})
+ end
+ catch
+ error:Exp ->
+ ok;
+ error:Reason ->
+ io:format("~p:~p: Crash ~p ~p~n",
+ [?MODULE,Line, Reason, erlang:get_stacktrace()]),
+ exit({error, Func})
+ end.
+
+norm(Type, Args) ->
+ Norm = case Type of
+ nfc -> fun unicode:characters_to_nfc_list/1;
+ nfd -> fun unicode:characters_to_nfd_list/1;
+ none -> fun(Str) -> Str end
+ end,
+ lists:map(fun({norm,Str}) -> Norm(Str);
+ (Other) -> Other
+ end, Args).
+
+res(Str, Str) -> true;
+res(Str, Exp) when is_list(Str), is_list(Exp) ->
+ A = unicode:characters_to_nfc_list(Str),
+ A==Exp orelse {A,Exp};
+res(Str, Exp) when is_binary(Str), is_list(Exp) ->
+ A = unicode:characters_to_nfc_list(Str),
+ A==Exp orelse {A,Exp};
+res(What, {Fun, Exp}) when is_function(Fun) ->
+ Fun(What) == Exp orelse {Fun(What), Exp};
+res({S1,S2}=S, {Exp1,Exp2}=E) -> %% For take
+ case {res(S1,Exp1), res(S2,Exp2)} of
+ {true, true} -> true;
+ _ -> {S, E}
+ end;
+res(Int, Exp) ->
+ Int == Exp orelse {Int, Exp}.
+
+
+check_types(_Line, _Func, _Str, Res)
+ when is_integer(Res); is_boolean(Res); Res =:= nomatch ->
+ %% length or equal
+ ok;
+check_types(Line, Func, [S1,S2], Res)
+ when Func =:= concat ->
+ case check_types_1(type(S1),type(S2)) of
+ ok ->
+ case check_types_1(type(S1),type(Res)) of
+ ok -> ok;
+ {T1,T2} ->
+ io:format("Failed: ~p ~p ~p ~p~n",[Line, Func, T1, T2]),
+ io:format(" ~p ~p => ~p~n", [S1, S2, Res]),
+ error
+ end;
+ _ -> ok
+ end;
+check_types(Line, Func, [Str|_], Res) ->
+ AddList = fun(mixed) -> mixed;
+ ({list,{list,_}}) -> {list, deep};
+ (R) ->
+ case lists:member(Func, [lexemes, tokens, split]) of
+ true -> {list, R};
+ false -> R
+ end
+ end,
+ try needs_check(Func) andalso (ok = check_types_1(AddList(type(Str)), type(Res))) of
+ ok -> ok;
+ false -> ok
+ catch _:{badmatch, {T1,T2}} ->
+ io:format("Failed: ~p ~p: ~p ~p~n",[Line, Func, T1, T2]),
+ io:format(" ~p => ~p~n", [Str, Res]),
+ error;
+ _:Reason ->
+ io:format("Crash: ~p in~n ~p~n",[Reason, erlang:get_stacktrace()]),
+ io:format("Failed: ~p ~p: ~p => ~p~n", [Line, Func, Str, Res]),
+ exit({Reason, erlang:get_stacktrace()})
+ end.
+
+check_types_1(T, T) ->
+ ok;
+check_types_1(Str, Res)
+ when is_binary(Str), is_binary(Res) ->
+ ok;
+check_types_1({list, _},{list, undefined}) ->
+ ok;
+check_types_1({list, _},{list, codepoints}) ->
+ ok;
+check_types_1({list, _},{list, {list, codepoints}}) ->
+ ok;
+check_types_1({list, {list, _}},{list, {list, codepoints}}) ->
+ ok;
+check_types_1(mixed,_) ->
+ ok;
+check_types_1({list, binary}, binary) ->
+ ok;
+check_types_1({list, binary}, {other, _, _}) -> %% take
+ ok;
+check_types_1({list, deep}, _) ->
+ ok;
+check_types_1({list, {list, deep}}, _) ->
+ ok;
+check_types_1(_, {error,_}) ->
+ ok;
+check_types_1(T1,T2) ->
+ {T1,T2}.
+
+type(Bin) when is_binary(Bin) ->
+ binary;
+type([]) ->
+ {list, undefined};
+type(List) when is_list(List) ->
+ Deep = fun(L) when is_list(L) ->
+ lists:any(fun(C) -> is_list(C) orelse is_binary(C) end, L);
+ (_) -> false
+ end,
+ case all(fun(C) -> not is_binary(C) end, List) of
+ true ->
+ case all(fun(C) -> is_integer(C) end, List) of
+ true -> {list, codepoints};
+ false ->
+ case [deep || L <- List, Deep(L)] of
+ [] -> {list, {list, codepoints}};
+ _ -> {list, deep}
+ end
+ end;
+ false ->
+ case all(fun(C) -> is_binary(C) end, List) of
+ true -> {list, binary};
+ false -> mixed
+ end
+ end;
+type({Number, String}) when is_number(Number) ->
+ %% to_integer or to_float
+ type(String);
+type({Atom, _}=What) when is_atom(Atom) ->
+ What;
+type({R1,R2}) ->
+ case {type(R1),type(R2)} of
+ {T,T} -> T;
+ {{list,undefined}, {list,codepoints}} -> {list,codepoints};
+ {{list,codepoints}, {list,undefined}} -> {list,codepoints};
+ {T1,T2} -> {other, T1,T2}
+ end;
+type(Other) ->
+ {other, Other}.
+
+all(_Check, []) ->
+ true;
+all(Check, [H|T]) ->
+ Check(H) andalso all(Check,T);
+all(Check, Bin) when is_binary(Bin) ->
+ Check(Bin).
+
+needs_check(reverse) -> false;
+needs_check(pad) -> false;
+needs_check(replace) -> false;
+needs_check(_) -> true.
+
+%%%% Timer stuff
+
+time_func(Fun, Mode, Bin) ->
+ timer:sleep(100), %% Let emulator catch up and clean things before test runs
+ Self = self(),
+ Pid = spawn_link(fun() ->
+ Str = mode(Mode, Bin),
+ Self ! {self(),time_func(0,0,0, Fun, Str, undefined)}
+ end),
+ receive {Pid,Msg} -> Msg end.
+
+time_func(N,Sum,SumSq, Fun, Str, _) when N < 50 ->
+ {Time, Res} = timer:tc(fun() -> Fun(Str) end),
+ time_func(N+1,Sum+Time,SumSq+Time*Time, Fun, Str, Res);
+time_func(N,Sum,SumSq, _, _, Res) ->
+ Mean = round(Sum / N),
+ Stdev = round(math:sqrt((SumSq - (Sum*Sum/N))/(N - 1))),
+ {N, Mean, Stdev, Res}.
+
+mode(binary, Bin) -> Bin;
+mode(list, Bin) -> unicode:characters_to_list(Bin).
+
%%
-%% Test cases starts here.
+%% Old string lists Test cases starts here.
%%
len(Config) when is_list(Config) ->
@@ -80,16 +970,14 @@ len(Config) when is_list(Config) ->
{'EXIT',_} = (catch string:len({})),
ok.
-equal(Config) when is_list(Config) ->
+old_equal(Config) when is_list(Config) ->
true = string:equal("", ""),
false = string:equal("", " "),
true = string:equal("laban", "laban"),
false = string:equal("skvimp", "skvump"),
- %% invalid arg type
- true = string:equal(2, 2), % not good, should crash
ok.
-concat(Config) when is_list(Config) ->
+old_concat(Config) when is_list(Config) ->
"erlang rules" = string:concat("erlang ", "rules"),
"" = string:concat("", ""),
"x" = string:concat("x", ""),
@@ -130,6 +1018,7 @@ str_rstr(Config) when is_list(Config) ->
3 = string:rstr("xxxx", "xx"),
3 = string:str("xy z yx", " z"),
3 = string:rstr("xy z yx", " z"),
+ 3 = string:str("aaab", "ab"),
%% invalid arg type
{'EXIT',_} = (catch string:str(hello, "he")),
%% invalid arg type
@@ -184,7 +1073,7 @@ substr(Config) when is_list(Config) ->
{'EXIT',_} = (catch string:substr("1234", "1")),
ok.
-tokens(Config) when is_list(Config) ->
+old_tokens(Config) when is_list(Config) ->
[] = string:tokens("",""),
[] = string:tokens("abc","abc"),
["abc"] = string:tokens("abc", ""),
@@ -221,7 +1110,7 @@ replace_sep(C, Seps, New) ->
chars(Config) when is_list(Config) ->
[] = string:chars($., 0),
[] = string:chars($., 0, []),
- 10 = length(string:chars(32, 10, [])),
+ 10 = erlang:length(string:chars(32, 10, [])),
"aaargh" = string:chars($a, 3, "rgh"),
%% invalid arg type
{'EXIT',_} = (catch string:chars($x, [])),
@@ -231,7 +1120,7 @@ copies(Config) when is_list(Config) ->
"" = string:copies("", 10),
"" = string:copies(".", 0),
"." = string:copies(".", 1),
- 30 = length(string:copies("123", 10)),
+ 30 = erlang:length(string:copies("123", 10)),
%% invalid arg type
{'EXIT',_} = (catch string:copies("hej", -1)),
{'EXIT',_} = (catch string:copies("hej", 2.0)),
@@ -341,7 +1230,7 @@ centre(Config) when is_list(Config) ->
{'EXIT',_} = (catch string:centre(hello, 10)),
ok.
-to_integer(Config) when is_list(Config) ->
+old_to_integer(Config) when is_list(Config) ->
{1,""} = test_to_integer("1"),
{1,""} = test_to_integer("+1"),
{-1,""} = test_to_integer("-1"),
@@ -354,13 +1243,14 @@ to_integer(Config) when is_list(Config) ->
{error,no_integer} = test_to_integer(""),
{error,no_integer} = test_to_integer("!1"),
{error,no_integer} = test_to_integer("F1"),
- {error,not_a_list} = test_to_integer('23'),
- {3,[[]]} = test_to_integer([$3,[]]),
- {3,[hello]} = test_to_integer([$3,hello]),
+ {error,badarg} = test_to_integer('23'),
+ %% {3,[[]]} = test_to_integer([$3,[]]),
+ %% {3,[hello]} = test_to_integer([$3,hello]),
+ {error,badarg} = test_to_integer([$3,hello]),
ok.
test_to_integer(Str) ->
- io:format("Checking ~p~n", [Str]),
+ %% io:format("Checking ~p~n", [Str]),
case string:to_integer(Str) of
{error,_Reason} = Bad ->
{'EXIT',_} = (catch list_to_integer(Str)),
@@ -370,7 +1260,7 @@ test_to_integer(Str) ->
Res
end.
-to_float(Config) when is_list(Config) ->
+old_to_float(Config) when is_list(Config) ->
{1.2,""} = test_to_float("1.2"),
{1.2,""} = test_to_float("1,2"),
{120.0,""} = test_to_float("1.2e2"),
@@ -397,13 +1287,15 @@ to_float(Config) when is_list(Config) ->
{error,no_float} = test_to_float("1"),
{error,no_float} = test_to_float("1e"),
{error,no_float} = test_to_float("2."),
- {error,not_a_list} = test_to_float('2.3'),
- {2.3,[[]]} = test_to_float([$2,$.,$3,[]]),
- {2.3,[hello]} = test_to_float([$2,$.,$3,hello]),
+ {error,badarg} = test_to_float('2.3'),
+ %{2.3,[[]]} = test_to_float([$2,$.,$3,[]]),
+ {2.3,[]} = test_to_float([$2,$.,$3,[]]),
+ %%{2.3,[hello]} = test_to_float([$2,$.,$3,hello]),
+ {error, badarg} = test_to_float([$2,$.,$3,hello]),
ok.
test_to_float(Str) ->
- io:format("Checking ~p~n", [Str]),
+ %% io:format("Checking ~p~n", [Str]),
case string:to_float(Str) of
{error,_Reason} = Bad ->
{'EXIT',_} = (catch list_to_float(Str)),
@@ -414,23 +1306,32 @@ test_to_float(Str) ->
end.
to_upper_to_lower(Config) when is_list(Config) ->
- "1234ABCDEFÅÄÖ=" = string:to_upper("1234abcdefåäö="),
- "éèíúùòóåäöabc()" = string:to_lower("ÉÈÍÚÙÒÓÅÄÖabc()"),
+ "1234ABCDEFÅÄÖ=" = string_to_upper("1234abcdefåäö="),
+ "éèíúùòóåäöabc()" = string_to_lower("ÉÈÍÚÙÒÓÅÄÖabc()"),
All = lists:seq(0, 255),
- UC = string:to_upper(All),
- 256 = length(UC),
+ UC = string_to_upper(All),
+ 256 = erlang:length(UC),
all_upper_latin1(UC, 0),
- LC = string:to_lower(All),
+ LC = string_to_lower(All),
all_lower_latin1(LC, 0),
- LC = string:to_lower(string:to_upper(LC)),
- LC = string:to_lower(string:to_upper(UC)),
- UC = string:to_upper(string:to_lower(LC)),
- UC = string:to_upper(string:to_lower(UC)),
+ LC = string_to_lower(string_to_upper(LC)),
+ LC = string_to_lower(string_to_upper(UC)),
+ UC = string_to_upper(string_to_lower(LC)),
+ UC = string_to_upper(string_to_lower(UC)),
+
ok.
+string_to_lower(Str) ->
+ Res = string:to_lower(Str),
+ Res = [string:to_lower(C) || C <- Str].
+
+string_to_upper(Str) ->
+ Res = string:to_upper(Str),
+ Res = [string:to_upper(C) || C <- Str].
+
all_upper_latin1([C|T], C) when 0 =< C, C < $a;
$z < C, C < 16#E0;
C =:= 16#F7; C =:= 16#FF ->
@@ -450,7 +1351,7 @@ all_lower_latin1([C|T], C) when 0 =< C, C < $A;
all_lower_latin1([H|T], C) when $A =< C, C =< $Z;
16#C0 =< C, C =< 16#F6;
16#C8 =< C, C =< 16#DE ->
- io:format("~p\n", [{H,C}]),
+ % io:format("~p\n", [{H,C}]),
H = C + 32,
all_lower_latin1(T, C+1);
all_lower_latin1([], 256) -> ok.
diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl
index 64dd41e75a..4061008812 100644
--- a/lib/stdlib/test/tar_SUITE.erl
+++ b/lib/stdlib/test/tar_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,11 +20,15 @@
-module(tar_SUITE).
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2, borderline/1, atomic/1, long_names/1,
+ init_per_group/2, end_per_group/2,
+ init_per_testcase/2,
+ borderline/1, atomic/1, long_names/1,
create_long_names/1, bad_tar/1, errors/1, extract_from_binary/1,
- extract_from_binary_compressed/1,
+ extract_from_binary_compressed/1, extract_filtered/1,
extract_from_open_file/1, symlinks/1, open_add_close/1, cooked_compressed/1,
- memory/1,unicode/1]).
+ memory/1,unicode/1,read_other_implementations/1,
+ sparse/1, init/1, leading_slash/1, dotdot/1,
+ roundtrip_metadata/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("kernel/include/file.hrl").
@@ -35,7 +39,10 @@ all() ->
[borderline, atomic, long_names, create_long_names,
bad_tar, errors, extract_from_binary,
extract_from_binary_compressed, extract_from_open_file,
- symlinks, open_add_close, cooked_compressed, memory, unicode].
+ extract_filtered,
+ symlinks, open_add_close, cooked_compressed, memory, unicode,
+ read_other_implementations,
+ sparse,init,leading_slash,dotdot,roundtrip_metadata].
groups() ->
[].
@@ -52,6 +59,9 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
+init_per_testcase(_Case, Config) ->
+ Ports = ordsets:from_list(erlang:ports()),
+ [{ports,Ports}|Config].
%% Test creating, listing and extracting one file from an archive,
%% multiple times with different file sizes. Also check that the file
@@ -81,20 +91,33 @@ borderline(Config) when is_list(Config) ->
%% Clean up.
delete_files([TempDir]),
- ok.
+ verify_ports(Config).
borderline_test(Size, TempDir) ->
- Archive = filename:join(TempDir, "ar_"++integer_to_list(Size)++".tar"),
- Name = filename:join(TempDir, "file_"++integer_to_list(Size)),
io:format("Testing size ~p", [Size]),
+ borderline_test(Size, TempDir, true),
+ borderline_test(Size, TempDir, false),
+ ok.
+
+borderline_test(Size, TempDir, IsUstar) ->
+ Prefix = case IsUstar of
+ true ->
+ "file_";
+ false ->
+ lists:duplicate(100, $f) ++ "ile_"
+ end,
+ SizeList = integer_to_list(Size),
+ Archive = filename:join(TempDir, "ar_"++ SizeList ++".tar"),
+ Name = filename:join(TempDir, Prefix++SizeList),
%% Create a file and archive it.
X0 = erlang:monotonic_time(),
- file:write_file(Name, random_byte_list(X0, Size)),
+ ok = file:write_file(Name, random_byte_list(X0, Size)),
ok = erl_tar:create(Archive, [Name]),
ok = file:delete(Name),
%% Verify listing and extracting.
+ IsUstar = is_ustar(Archive),
{ok, [Name]} = erl_tar:table(Archive),
ok = erl_tar:extract(Archive, [verbose]),
@@ -103,7 +126,12 @@ borderline_test(Size, TempDir) ->
true = match_byte_list(X0, binary_to_list(Bin)),
%% Verify that Unix tar can read it.
- tar_tf(Archive, Name),
+ case IsUstar of
+ true ->
+ tar_tf(Archive, Name);
+ false ->
+ ok
+ end,
ok.
@@ -248,7 +276,7 @@ atomic(Config) when is_list(Config) ->
%% Clean up.
delete_files([Tar1,Tar2,Tar3,Tar4|Names]),
- ok.
+ verify_ports(Config).
%% Returns a sequence of characters.
@@ -282,7 +310,9 @@ long_names(Config) when is_list(Config) ->
DataDir = proplists:get_value(data_dir, Config),
Long = filename:join(DataDir, "long_names.tar"),
run_in_short_tempdir(Config,
- fun() -> do_long_names(Long) end).
+ fun() -> do_long_names(Long) end),
+ verify_ports(Config).
+
do_long_names(Long) ->
%% Try table/2 and extract/2.
@@ -314,7 +344,8 @@ do_long_names(Long) ->
%% Creates a tar file from a deep directory structure (filenames are
%% longer than 100 characters).
create_long_names(Config) when is_list(Config) ->
- run_in_short_tempdir(Config, fun create_long_names/0).
+ run_in_short_tempdir(Config, fun create_long_names/0),
+ verify_ports(Config).
create_long_names() ->
{ok,Dir} = file:get_cwd(),
@@ -336,6 +367,7 @@ create_long_names() ->
ok = erl_tar:tt(TarName),
%% Extract and verify.
+ true = is_ustar(TarName),
ExtractDir = "extract_dir",
ok = file:make_dir(ExtractDir),
ok = erl_tar:extract(TarName, [{cwd,ExtractDir}]),
@@ -357,10 +389,10 @@ make_dirs([], Dir) ->
%% Try erl_tar:table/2 and erl_tar:extract/2 on some corrupted tar files.
bad_tar(Config) when is_list(Config) ->
try_bad("bad_checksum", bad_header, Config),
- try_bad("bad_octal", bad_header, Config),
+ try_bad("bad_octal", invalid_tar_checksum, Config),
try_bad("bad_too_short", eof, Config),
try_bad("bad_even_shorter", eof, Config),
- ok.
+ verify_ports(Config).
try_bad(Name0, Reason, Config) ->
%% Intentionally no macros here.
@@ -370,8 +402,10 @@ try_bad(Name0, Reason, Config) ->
Name = Name0 ++ ".tar",
io:format("~nTrying ~s", [Name]),
Full = filename:join(DataDir, Name),
- Opts = [verbose, {cwd, PrivDir}],
+ Dest = filename:join(PrivDir, Name0),
+ Opts = [verbose, {cwd, Dest}],
Expected = {error, Reason},
+ io:fwrite("Expected: ~p\n", [Expected]),
case {erl_tar:table(Full, Opts), erl_tar:extract(Full, Opts)} of
{Expected, Expected} ->
io:format("Result: ~p", [Expected]),
@@ -408,7 +442,7 @@ errors(Config) when is_list(Config) ->
%% Clean up.
delete_files([GoodTar,BadTar]),
- ok.
+ verify_ports(Config).
try_error(M, F, A, Error) ->
io:format("Trying ~p:~p(~p)", [M, F, A]),
@@ -458,7 +492,7 @@ extract_from_binary(Config) when is_list(Config) ->
%% Clean up.
delete_files([ExtractDir]),
- ok.
+ verify_ports(Config).
extract_from_binary_compressed(Config) when is_list(Config) ->
%% Test extracting a compressed tar archive from a binary.
@@ -491,7 +525,28 @@ extract_from_binary_compressed(Config) when is_list(Config) ->
%% Clean up the rest.
delete_files([ExtractDir]),
- ok.
+ verify_ports(Config).
+
+%% Test extracting a tar archive from a binary.
+extract_filtered(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Long = filename:join(DataDir, "no_fancy_stuff.tar"),
+ ExtractDir = filename:join(PrivDir, "extract_from_binary"),
+ ok = file:make_dir(ExtractDir),
+
+ ok = erl_tar:extract(Long, [{cwd,ExtractDir},{files,["no_fancy_stuff/EPLICENCE"]}]),
+
+ %% Verify.
+ Dir = filename:join(ExtractDir, "no_fancy_stuff"),
+ true = filelib:is_dir(Dir),
+ false = filelib:is_file(filename:join(Dir, "a_dir_list")),
+ true = filelib:is_file(filename:join(Dir, "EPLICENCE")),
+
+ %% Clean up.
+ delete_files([ExtractDir]),
+
+ verify_ports(Config).
%% Test extracting a tar archive from an open file.
extract_from_open_file(Config) when is_list(Config) ->
@@ -516,7 +571,7 @@ extract_from_open_file(Config) when is_list(Config) ->
%% Clean up.
delete_files([ExtractDir]),
- ok.
+ verify_ports(Config).
%% Test that archives containing symlinks can be created and extracted.
symlinks(Config) when is_list(Config) ->
@@ -535,6 +590,7 @@ symlinks(Config) when is_list(Config) ->
%% Clean up.
delete_files([Dir]),
+ verify_ports(Config),
Res.
make_symlink(Path, Link) ->
@@ -573,6 +629,7 @@ symlinks(Dir, BadSymlink, PointsTo) ->
ok = file:write_file(AFile, ALine),
ok = file:make_symlink(AFile, GoodSymlink),
ok = erl_tar:create(Tar, [BadSymlink, GoodSymlink, AFile], [verbose]),
+ true = is_ustar(Tar),
%% List contents of tar file.
@@ -581,6 +638,7 @@ symlinks(Dir, BadSymlink, PointsTo) ->
%% Also create another archive with the dereference flag.
ok = erl_tar:create(DerefTar, [AFile, GoodSymlink], [dereference, verbose]),
+ true = is_ustar(DerefTar),
%% Extract files to a new directory.
@@ -619,13 +677,51 @@ long_symlink(Dir) ->
ok = file:set_cwd(Dir),
AFile = "long_symlink",
- FarTooLong = "/tmp/aarrghh/this/path/is/far/longer/than/one/hundred/characters/which/is/the/maximum/number/of/characters/allowed",
- ok = file:make_symlink(FarTooLong, AFile),
- {error,Error} = erl_tar:create(Tar, [AFile], [verbose]),
- io:format("Error: ~s\n", [erl_tar:format_error(Error)]),
- {FarTooLong,symbolic_link_too_long} = Error,
+ RequiresPAX = "/tmp/aarrghh/this/path/is/far/longer/than/one/hundred/characters/which/is/the/maximum/number/of/characters/allowed",
+ ok = file:make_symlink(RequiresPAX, AFile),
+ ok = erl_tar:create(Tar, [AFile], [verbose]),
+ false = is_ustar(Tar),
+ NewDir = filename:join(Dir, "extracted"),
+ _ = file:make_dir(NewDir),
+ ok = erl_tar:extract(Tar, [{cwd, NewDir}, verbose]),
+ ok = file:set_cwd(NewDir),
+ {ok, #file_info{type=symlink}} = file:read_link_info(AFile),
+ {ok, RequiresPAX} = file:read_link(AFile),
ok.
+init(Config) when is_list(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ ok = file:set_cwd(PrivDir),
+ Dir = filename:join(PrivDir, "init"),
+ ok = file:make_dir(Dir),
+
+ [{FileOne,_,_}|_] = oac_files(),
+ TarOne = filename:join(Dir, "archive1.tar"),
+ {ok,Fd} = file:open(TarOne, [write]),
+
+ %% If the arity of the fun is wrong, badarg should be returned
+ {error, badarg} = erl_tar:init(Fd, write, fun file_op_bad/1),
+
+ %% Otherwise we should be good to go
+ {ok, Tar} = erl_tar:init(Fd, write, fun file_op/2),
+ ok = erl_tar:add(Tar, FileOne, []),
+ ok = erl_tar:close(Tar),
+ {ok, [FileOne]} = erl_tar:table(TarOne),
+
+ verify_ports(Config).
+
+file_op_bad(_) ->
+ throw({error, should_never_be_called}).
+
+file_op(write, {Fd, Data}) ->
+ file:write(Fd, Data);
+file_op(position, {Fd, Pos}) ->
+ file:position(Fd, Pos);
+file_op(read2, {Fd, Size}) ->
+ file:read(Fd, Size);
+file_op(close, Fd) ->
+ file:close(Fd).
+
open_add_close(Config) when is_list(Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
ok = file:set_cwd(PrivDir),
@@ -643,21 +739,30 @@ open_add_close(Config) when is_list(Config) ->
TarOne = filename:join(Dir, "archive1.tar"),
{ok,AD} = erl_tar:open(TarOne, [write]),
ok = erl_tar:add(AD, FileOne, []),
- ok = erl_tar:add(AD, FileTwo, "second file", []),
- ok = erl_tar:add(AD, FileThree, [verbose]),
+
+ %% Add with {NameInArchive,Name}
+ ok = erl_tar:add(AD, {"second file", FileTwo}, []),
+
+ %% Add with {binary, Bin}
+ {ok,FileThreeBin} = file:read_file(FileThree),
+ ok = erl_tar:add(AD, {FileThree, FileThreeBin}, [verbose]),
+
+ %% Add with Name
ok = erl_tar:add(AD, FileThree, "chunked", [{chunks,11411},verbose]),
ok = erl_tar:add(AD, ADir, [verbose]),
ok = erl_tar:add(AD, AnotherDir, [verbose]),
ok = erl_tar:close(AD),
+ true = is_ustar(TarOne),
ok = erl_tar:t(TarOne),
ok = erl_tar:tt(TarOne),
- {ok,[FileOne,"second file",FileThree,"chunked",ADir,SomeContent]} = erl_tar:table(TarOne),
+ Expected = {ok,[FileOne,"second file",FileThree,"chunked",ADir,SomeContent]},
+ Expected = erl_tar:table(TarOne),
delete_files(["oac_file","oac_small","oac_big",Dir,AnotherDir,ADir]),
- ok.
+ verify_ports(Config).
oac_files() ->
Files = [{"oac_file", 1459, $x},
@@ -688,7 +793,8 @@ cooked_compressed(Config) when is_list(Config) ->
%% Clean up.
delete_files([filename:join(PrivDir, "ddll_SUITE_data")]),
- ok.
+
+ verify_ports(Config).
%% Test that an archive can be created directly from binaries and
%% that an archive can be extracted into binaries.
@@ -716,24 +822,67 @@ memory(Config) when is_list(Config) ->
%% Clean up.
ok = delete_files([Name1,Name2]),
- ok.
+
+ verify_ports(Config).
+
+read_other_implementations(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ Files = ["v7.tar", "gnu.tar", "bsd.tar",
+ "star.tar", "pax_mtime.tar"],
+ do_read_other_implementations(Files, DataDir),
+ verify_ports(Config).
+
+do_read_other_implementations([], _DataDir) ->
+ ok;
+do_read_other_implementations([File|Rest], DataDir) ->
+ io:format("~nTrying ~s", [File]),
+ Full = filename:join(DataDir, File),
+ {ok, _} = erl_tar:table(Full),
+ {ok, _} = erl_tar:extract(Full, [memory]),
+ do_read_other_implementations(Rest, DataDir).
+
+
+%% Test handling of sparse files
+sparse(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Sparse01Empty = "sparse01_empty.tar",
+ Sparse01 = "sparse01.tar",
+ Sparse10Empty = "sparse10_empty.tar",
+ Sparse10 = "sparse10.tar",
+ do_sparse([Sparse01Empty, Sparse01, Sparse10Empty, Sparse10], DataDir, PrivDir),
+ verify_ports(Config).
+
+do_sparse([], _DataDir, _PrivDir) ->
+ ok;
+do_sparse([Name|Rest], DataDir, PrivDir) ->
+ io:format("~nTrying sparse file ~s", [Name]),
+ Full = filename:join(DataDir, Name),
+ {ok, [_]} = erl_tar:table(Full),
+ {ok, _} = erl_tar:extract(Full, [memory]),
+ do_sparse(Rest, DataDir, PrivDir).
%% Test filenames with characters outside the US ASCII range.
unicode(Config) when is_list(Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- do_unicode(PrivDir),
+ run_unicode_node(Config, "+fnu"),
case has_transparent_naming() of
true ->
- Pa = filename:dirname(code:which(?MODULE)),
- Node = start_node(unicode, "+fnl -pa "++Pa),
- ok = rpc:call(Node, erlang, apply,
- [fun() -> do_unicode(PrivDir) end,[]]),
- true = test_server:stop_node(Node),
- ok;
+ run_unicode_node(Config, "+fnl");
false ->
ok
end.
+run_unicode_node(Config, Option) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Pa = filename:dirname(code:which(?MODULE)),
+ Args = Option ++ " -pa "++Pa,
+ io:format("~s\n", [Args]),
+ Node = start_node(unicode, Args),
+ ok = rpc:call(Node, erlang, apply,
+ [fun() -> do_unicode(PrivDir) end,[]]),
+ true = test_server:stop_node(Node),
+ ok.
+
has_transparent_naming() ->
case os:type() of
{unix,darwin} -> false;
@@ -745,10 +894,14 @@ do_unicode(PrivDir) ->
ok = file:set_cwd(PrivDir),
ok = file:make_dir("unicöde"),
- Names = unicode_create_files(),
+ Names = lists:sort(unicode_create_files()),
Tar = "unicöde.tar",
ok = erl_tar:create(Tar, ["unicöde"], []),
- {ok,Names} = erl_tar:table(Tar, []),
+
+ %% Unicode filenames require PAX format.
+ false = is_ustar(Tar),
+ {ok,Names0} = erl_tar:table(Tar, []),
+ Names = lists:sort(Names0),
_ = [ok = file:delete(Name) || Name <- Names],
ok = erl_tar:extract(Tar),
_ = [{ok,_} = file:read_file(Name) || Name <- Names],
@@ -768,6 +921,75 @@ unicode_create_files() ->
[]
end].
+leading_slash(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Dir = filename:join(PrivDir, ?FUNCTION_NAME),
+ TarFile = filename:join(Dir, "leading_slash.tar"),
+ ok = filelib:ensure_dir(TarFile),
+ {ok,Fd} = erl_tar:open(TarFile, [write]),
+ TarMemberName = "e/d/c/b/a_member",
+ TarMemberNameAbs = "/" ++ TarMemberName,
+ Contents = <<"contents\n">>,
+ ok = erl_tar:add(Fd, Contents, TarMemberNameAbs, [verbose]),
+ ok = erl_tar:close(Fd),
+
+ ok = erl_tar:extract(TarFile, [{cwd,Dir}]),
+
+ {ok,Contents} = file:read_file(filename:join(Dir, TarMemberName)),
+ ok.
+
+dotdot(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Dir = filename:join(PrivDir, ?FUNCTION_NAME),
+ ok = file:make_dir(Dir),
+ Tar = filename:join(Dir, "dotdot.tar"),
+ {ok,Fd} = erl_tar:open(Tar, [write]),
+ BeamFile = code:which(?MODULE),
+ ok = erl_tar:add(Fd, BeamFile, "a/./../../some_file", []),
+ ok = erl_tar:close(Fd),
+
+ {error,{_,unsafe_path=Error}} = erl_tar:extract(Tar, [{cwd,Dir}]),
+ false = filelib:is_regular(filename:join(PrivDir, "some_file")),
+ io:format("~s\n", [erl_tar:format_error(Error)]),
+
+ ok.
+
+roundtrip_metadata(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Dir = filename:join(PrivDir, ?FUNCTION_NAME),
+ ok = file:make_dir(Dir),
+
+ do_roundtrip_metadata(Dir, "name-does-not-matter"),
+ ok.
+
+do_roundtrip_metadata(Dir, File) ->
+ Tar = filename:join(Dir, atom_to_list(?FUNCTION_NAME)++".tar"),
+ BeamFile = code:which(compile),
+ {ok,Fd} = erl_tar:open(Tar, [write]),
+ ok = erl_tar:add(Fd, BeamFile, File, []),
+ ok = erl_tar:close(Fd),
+
+ ok = erl_tar:extract(Tar, [{cwd,Dir}]),
+
+ %% Make sure that size and modification times are the same
+ %% on all platforms.
+ {ok,OrigInfo} = file:read_file_info(BeamFile),
+ ExtractedFile = filename:join(Dir, File),
+ {ok,ExtractedInfo} = file:read_file_info(ExtractedFile),
+ #file_info{size=Size,mtime=Mtime,type=regular} = OrigInfo,
+ #file_info{size=Size,mtime=Mtime,type=regular} = ExtractedInfo,
+
+ %% On Unix platforms more fields are expected to be the same.
+ case os:type() of
+ {unix,_} ->
+ #file_info{access=Access,mode=Mode} = OrigInfo,
+ #file_info{access=Access,mode=Mode} = ExtractedInfo,
+ ok;
+ _ ->
+ ok
+ end.
+
+
%% Delete the given list of files.
delete_files([]) -> ok;
delete_files([Item|Rest]) ->
@@ -844,3 +1066,26 @@ start_node(Name, Args) ->
ct:log("Node ~p started~n", [Node]),
Node
end.
+
+%% Test that the given tar file is a plain USTAR archive,
+%% without any PAX extensions.
+is_ustar(File) ->
+ {ok,Bin} = file:read_file(File),
+ <<_:257/binary,"ustar",0,_/binary>> = Bin,
+ <<_:156/binary,Type:8,_/binary>> = Bin,
+ case Type of
+ $x -> false;
+ $g -> false;
+ _ -> true
+ end.
+
+
+verify_ports(Config) ->
+ PortsBefore = proplists:get_value(ports, Config),
+ PortsAfter = ordsets:from_list(erlang:ports()),
+ case ordsets:subtract(PortsAfter, PortsBefore) of
+ [] ->
+ ok;
+ [_|_]=Rem ->
+ error({leaked_ports,Rem})
+ end.
diff --git a/lib/stdlib/test/tar_SUITE_data/bsd.tar b/lib/stdlib/test/tar_SUITE_data/bsd.tar
new file mode 100644
index 0000000000..8c31864be0
--- /dev/null
+++ b/lib/stdlib/test/tar_SUITE_data/bsd.tar
Binary files differ
diff --git a/lib/stdlib/test/tar_SUITE_data/gnu.tar b/lib/stdlib/test/tar_SUITE_data/gnu.tar
new file mode 100644
index 0000000000..60268065c1
--- /dev/null
+++ b/lib/stdlib/test/tar_SUITE_data/gnu.tar
Binary files differ
diff --git a/lib/stdlib/test/tar_SUITE_data/pax_mtime.tar b/lib/stdlib/test/tar_SUITE_data/pax_mtime.tar
new file mode 100644
index 0000000000..1b6e80ffac
--- /dev/null
+++ b/lib/stdlib/test/tar_SUITE_data/pax_mtime.tar
Binary files differ
diff --git a/lib/stdlib/test/dets_SUITE_data/version_r3b02.dets b/lib/stdlib/test/tar_SUITE_data/sparse00.tar
index 058cd15b31..61a04de90b 100644
--- a/lib/stdlib/test/dets_SUITE_data/version_r3b02.dets
+++ b/lib/stdlib/test/tar_SUITE_data/sparse00.tar
Binary files differ
diff --git a/lib/stdlib/test/dets_SUITE_data/dets_test_v8b_little_endian.dets b/lib/stdlib/test/tar_SUITE_data/sparse01.tar
index bf490afa1a..61a04de90b 100644
--- a/lib/stdlib/test/dets_SUITE_data/dets_test_v8b_little_endian.dets
+++ b/lib/stdlib/test/tar_SUITE_data/sparse01.tar
Binary files differ
diff --git a/lib/stdlib/test/tar_SUITE_data/sparse01_empty.tar b/lib/stdlib/test/tar_SUITE_data/sparse01_empty.tar
new file mode 100644
index 0000000000..efa6d060f4
--- /dev/null
+++ b/lib/stdlib/test/tar_SUITE_data/sparse01_empty.tar
Binary files differ
diff --git a/lib/stdlib/test/dets_SUITE_data/dets_test_v8b.dets b/lib/stdlib/test/tar_SUITE_data/sparse10.tar
index d0aa20fe06..61a04de90b 100644
--- a/lib/stdlib/test/dets_SUITE_data/dets_test_v8b.dets
+++ b/lib/stdlib/test/tar_SUITE_data/sparse10.tar
Binary files differ
diff --git a/lib/stdlib/test/tar_SUITE_data/sparse10_empty.tar b/lib/stdlib/test/tar_SUITE_data/sparse10_empty.tar
new file mode 100644
index 0000000000..efa6d060f4
--- /dev/null
+++ b/lib/stdlib/test/tar_SUITE_data/sparse10_empty.tar
Binary files differ
diff --git a/lib/stdlib/test/tar_SUITE_data/star.tar b/lib/stdlib/test/tar_SUITE_data/star.tar
new file mode 100644
index 0000000000..b0631e3b13
--- /dev/null
+++ b/lib/stdlib/test/tar_SUITE_data/star.tar
Binary files differ
diff --git a/lib/stdlib/test/tar_SUITE_data/v7.tar b/lib/stdlib/test/tar_SUITE_data/v7.tar
new file mode 100644
index 0000000000..9918e006bb
--- /dev/null
+++ b/lib/stdlib/test/tar_SUITE_data/v7.tar
Binary files differ
diff --git a/lib/stdlib/test/timer_SUITE.erl b/lib/stdlib/test/timer_SUITE.erl
index 5fc95b16a6..9062cbae80 100644
--- a/lib/stdlib/test/timer_SUITE.erl
+++ b/lib/stdlib/test/timer_SUITE.erl
@@ -353,7 +353,7 @@ res_combine({error,Es}, [{error,E}|T]) ->
system_time() ->
- erlang:monotonic_time(milli_seconds).
+ erlang:monotonic_time(millisecond).
%% ------------------------------------------------------- %%
diff --git a/lib/stdlib/test/timer_simple_SUITE.erl b/lib/stdlib/test/timer_simple_SUITE.erl
index ff5116b8b6..1a582ae95a 100644
--- a/lib/stdlib/test/timer_simple_SUITE.erl
+++ b/lib/stdlib/test/timer_simple_SUITE.erl
@@ -457,7 +457,7 @@ append([],X) ->
X.
system_time() ->
- erlang:monotonic_time(micro_seconds).
+ erlang:monotonic_time(microsecond).
%% ------------------------------------------------------- %%
diff --git a/lib/stdlib/test/unicode_SUITE.erl b/lib/stdlib/test/unicode_SUITE.erl
index 07d63bdf22..e01ba3fbb0 100644
--- a/lib/stdlib/test/unicode_SUITE.erl
+++ b/lib/stdlib/test/unicode_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,7 +33,9 @@
ex_binaries_errors_utf16_little/1,
ex_binaries_errors_utf16_big/1,
ex_binaries_errors_utf32_little/1,
- ex_binaries_errors_utf32_big/1]).
+ ex_binaries_errors_utf32_big/1,
+ normalize/1
+ ]).
suite() ->
[{ct_hooks,[ts_install_cth]},
@@ -44,6 +46,7 @@ all() ->
utf16_illegal_sequences_bif, random_lists, roundtrips,
latin1, exceptions,
binaries_errors_limit,
+ normalize,
{group,binaries_errors}].
groups() ->
@@ -920,6 +923,108 @@ fail_bif_1(Bin,Coding) ->
ok
end.
+
+normalize(_) ->
+ %% More tests are in unicode_util_SUITE.erl and str_SUITE.erl
+ {'EXIT', _} = (catch unicode:characters_to_nfc_list({tuple})),
+ {'EXIT', _} = (catch unicode:characters_to_nfd_list({tuple})),
+ {'EXIT', _} = (catch unicode:characters_to_nfkc_list({tuple})),
+ {'EXIT', _} = (catch unicode:characters_to_nfkd_list({tuple})),
+ {'EXIT', _} = (catch unicode:characters_to_nfc_binary({tuple})),
+ {'EXIT', _} = (catch unicode:characters_to_nfd_binary({tuple})),
+ {'EXIT', _} = (catch unicode:characters_to_nfkc_binary({tuple})),
+ {'EXIT', _} = (catch unicode:characters_to_nfkd_binary({tuple})),
+ String = ["abc..åäö", <<"Ωµe`è"/utf8>>, "œŒþæÆħ§ß ホンダ"],
+ NFD_l = unicode:characters_to_nfd_list(String),
+ NFD_b = unicode:characters_to_nfd_binary(String),
+ NFC_l = unicode:characters_to_nfc_list(String),
+ NFC_b = unicode:characters_to_nfc_binary(String),
+
+ NFD_l = unicode:characters_to_nfd_list(NFD_l),
+ NFD_l = unicode:characters_to_nfd_list(NFD_b),
+ NFD_l = unicode:characters_to_nfd_list(NFC_l),
+ NFD_l = unicode:characters_to_nfd_list(NFC_b),
+
+ NFD_b = unicode:characters_to_nfd_binary(NFD_b),
+ NFD_b = unicode:characters_to_nfd_binary(NFD_l),
+ NFD_b = unicode:characters_to_nfd_binary(NFC_b),
+ NFD_b = unicode:characters_to_nfd_binary(NFC_l),
+
+ NFC_l = unicode:characters_to_nfc_list(NFD_l),
+ NFC_l = unicode:characters_to_nfc_list(NFD_b),
+ NFC_l = unicode:characters_to_nfc_list(NFC_l),
+ NFC_l = unicode:characters_to_nfc_list(NFC_b),
+
+ NFC_b = unicode:characters_to_nfc_binary(NFD_b),
+ NFC_b = unicode:characters_to_nfc_binary(NFD_l),
+ NFC_b = unicode:characters_to_nfc_binary(NFC_b),
+ NFC_b = unicode:characters_to_nfc_binary(NFC_l),
+
+ Str = [lists:duplicate(20,lists:seq($a, $q))|String],
+ StrD_bin = unicode:characters_to_binary(unicode:characters_to_nfd_list(Str)),
+ StrD_bin = unicode:characters_to_nfd_binary(Str),
+ StrC_bin = unicode:characters_to_binary(unicode:characters_to_nfc_list(StrD_bin)),
+ StrC_bin = unicode:characters_to_nfc_binary(Str),
+
+ NFKD_l = unicode:characters_to_nfkd_list(String),
+ NFKD_b = unicode:characters_to_nfkd_binary(String),
+ NFKC_l = unicode:characters_to_nfkc_list(String),
+ NFKC_b = unicode:characters_to_nfkc_binary(String),
+
+ NFKD_l = unicode:characters_to_nfkd_list(NFKD_l),
+ NFKD_l = unicode:characters_to_nfkd_list(NFKD_b),
+ NFKD_l = unicode:characters_to_nfkd_list(NFKC_l),
+ NFKD_l = unicode:characters_to_nfkd_list(NFKC_b),
+
+ NFKD_b = unicode:characters_to_nfd_binary(NFKD_b),
+ NFKD_b = unicode:characters_to_nfd_binary(NFKD_l),
+ NFKD_b = unicode:characters_to_nfd_binary(NFKC_b),
+ NFKD_b = unicode:characters_to_nfd_binary(NFKC_l),
+
+ NFKC_l = unicode:characters_to_nfc_list(NFKD_l),
+ NFKC_l = unicode:characters_to_nfc_list(NFKD_b),
+ NFKC_l = unicode:characters_to_nfc_list(NFKC_l),
+ NFKC_l = unicode:characters_to_nfc_list(NFKC_b),
+
+ NFKC_b = unicode:characters_to_nfc_binary(NFKD_b),
+ NFKC_b = unicode:characters_to_nfc_binary(NFKD_l),
+ NFKC_b = unicode:characters_to_nfc_binary(NFKC_b),
+ NFKC_b = unicode:characters_to_nfc_binary(NFKC_l),
+
+ StrKD_bin = unicode:characters_to_binary(unicode:characters_to_nfkd_list(Str)),
+ StrKD_bin = unicode:characters_to_nfkd_binary(Str),
+ StrKC_bin = unicode:characters_to_binary(unicode:characters_to_nfkc_list(StrD_bin)),
+ StrKC_bin = unicode:characters_to_nfkc_binary(Str),
+
+ true = unicode:characters_to_nfkc_list("ホンダ") =:= unicode:characters_to_nfkc_list("ホンダ"),
+ true = unicode:characters_to_nfkd_list("32") =:= unicode:characters_to_nfkd_list("32"),
+
+ {error, [0], <<128>>} = unicode:characters_to_nfc_list(<<0, 128>>),
+ {error, [0], <<128>>} = unicode:characters_to_nfkc_list(<<0, 128>>),
+ {error, [0], <<128>>} = unicode:characters_to_nfd_list(<<0, 128>>),
+ {error, [0], <<128>>} = unicode:characters_to_nfkd_list(<<0, 128>>),
+
+ {error, <<0>>, <<128>>} = unicode:characters_to_nfc_binary(<<0, 128>>),
+ {error, <<0>>, <<128>>} = unicode:characters_to_nfkc_binary(<<0, 128>>),
+ {error, <<0>>, <<128>>} = unicode:characters_to_nfd_binary(<<0, 128>>),
+ {error, <<0>>, <<128>>} = unicode:characters_to_nfkd_binary(<<0, 128>>),
+
+ LargeBin = binary:copy(<<"abcde">>, 50),
+ LargeList = binary_to_list(LargeBin),
+
+ {error, LargeList, <<128>>} = unicode:characters_to_nfc_list(<<LargeBin/binary, 128>>),
+ {error, LargeList, <<128>>} = unicode:characters_to_nfkc_list(<<LargeBin/binary, 128>>),
+ {error, LargeList, <<128>>} = unicode:characters_to_nfd_list(<<LargeBin/binary, 128>>),
+ {error, LargeList, <<128>>} = unicode:characters_to_nfkd_list(<<LargeBin/binary, 128>>),
+
+ {error, LargeBin, <<128>>} = unicode:characters_to_nfc_binary(<<LargeBin/binary, 128>>),
+ {error, LargeBin, <<128>>} = unicode:characters_to_nfkc_binary(<<LargeBin/binary, 128>>),
+ {error, LargeBin, <<128>>} = unicode:characters_to_nfd_binary(<<LargeBin/binary, 128>>),
+ {error, LargeBin, <<128>>} = unicode:characters_to_nfkd_binary(<<LargeBin/binary, 128>>),
+
+ ok.
+
+
%%
%% Diverse utilities
%%
diff --git a/lib/stdlib/test/unicode_util_SUITE.erl b/lib/stdlib/test/unicode_util_SUITE.erl
new file mode 100644
index 0000000000..03c24c7027
--- /dev/null
+++ b/lib/stdlib/test/unicode_util_SUITE.erl
@@ -0,0 +1,433 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(unicode_util_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+
+-export([all/0, suite/0, extra/1,
+ uppercase/1, lowercase/1, titlecase/1, casefold/1,
+ cp/1, gc/1,
+ nfd/1, nfc/1, nfkd/1, nfkc/1,
+ whitespace/1,
+ get/1,
+ count/1]).
+
+-export([debug/0, id/1, bin_split/1, uc_loaded_size/0]).
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,20}}].
+
+all() ->
+ [
+ extra,
+ uppercase, lowercase, titlecase, casefold,
+ cp, gc,
+ nfd, nfc, nfkd, nfkc,
+ whitespace,
+ get,
+ count
+ ].
+
+debug() ->
+ Config = [{data_dir, ?MODULE_STRING++"_data"}],
+ [io:format("~p:~p~n",[Test,?MODULE:Test(Config)]) || Test <- all()].
+
+extra(_) ->
+ {_, _} = unicode_util:spec_version(),
+ #{ccc:=0, compat:=[], canon:=[_,_]} = unicode_util:lookup($å),
+ #{fold:=229,lower:=229,title:=197,upper:=197} = unicode_util:get_case($å),
+ #{fold:="ss",lower:=223,title:="Ss",upper:="SS"} = unicode_util:get_case($ß),
+ ok.
+
+uppercase(_) ->
+ [$H] = unicode_util:uppercase([$H]),
+ [$H] = unicode_util:uppercase([$h]),
+ [$1] = unicode_util:uppercase([$1]),
+ ok.
+
+titlecase(_) ->
+ [$H] = unicode_util:titlecase([$H]),
+ [$H] = unicode_util:titlecase([$h]),
+ [$1] = unicode_util:titlecase([$1]),
+ ok.
+
+lowercase(_) ->
+ [$h] = unicode_util:lowercase([$H]),
+ [$h] = unicode_util:lowercase([$h]),
+ [$1] = unicode_util:lowercase([$1]),
+ [$i] = unicode_util:casefold([$I]), %% no Turkish
+ ok.
+
+casefold(_) ->
+ [$h] = unicode_util:casefold([$H]),
+ [$h] = unicode_util:casefold([$h]),
+ [$1] = unicode_util:casefold([$1]),
+ [$i] = unicode_util:casefold([$I]),%% no Turkish
+ [[$s,$s]|"abC"] = unicode_util:casefold([$ß,$a,$b,$C]),
+ [[$s,$s]] = unicode_util:casefold([$ẞ]),
+ ok.
+
+whitespace(_) ->
+ WS = unicode_util:whitespace(),
+ WS = lists:filter(fun unicode_util:is_whitespace/1, WS),
+ %% TODO add more tests
+ ok.
+
+cp(_) ->
+ Get = fun unicode_util:cp/1,
+ "hejsan" = fetch("hejsan", Get),
+ "hejsan" = fetch(<<"hejsan">>, Get),
+ "hejsan" = fetch(["hej",<<"san">>], Get),
+ "hejsan" = fetch(["hej"|<<"san">>], Get),
+ {error, <<128>>} = Get(<<128>>),
+ {error, [<<128>>, 0]} = Get([<<128>>, 0]),
+ ok.
+
+gc(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ Get = fun unicode_util:gc/1,
+ "hejsan" = fetch("hejsan", Get),
+ "hejsan" = fetch(<<"hejsan">>, Get),
+ "hejsan" = fetch(["hej",<<"san">>], Get),
+ "hejsan" = fetch(["hej"|<<"san">>], Get),
+ {error, <<128>>} = Get(<<128>>),
+ {error, [<<128>>, 0]} = Get([<<128>>, 0]),
+
+ 0 = fold(fun verify_gc/3, 0, DataDir ++ "/GraphemeBreakTest.txt"),
+ ok.
+
+verify_gc(Line0, N, Acc) ->
+ Line = unicode:characters_to_list(Line0),
+ Line = fetch(Line0,fun unicode_util:cp/1), %% Test cp
+ LineGC = fetch(Line0,fun unicode_util:gc/1), %% Test gc
+ LineGC = fetch(Line,fun unicode_util:gc/1), %% Test gc
+ LineGC = fetch(LineGC,fun unicode_util:gc/1), %% Test gc
+ LineGC = fetch(LineGC,fun unicode_util:cp/1), %% Test cp
+
+ %io:format("Line: ~s~n",[Line]),
+ [Data|_Comments] = string:tokens(Line, "#"),
+ %io:format("Data: ~w~n",[string:tokens(Data, " \t")]),
+ {Str,Res} = gc_test_data(string:tokens(Data, " \t"), [], [[]]),
+ try
+ Res = fetch(Str, fun unicode_util:gc/1),
+ Acc
+ catch _Cl:{badmatch, Other} ->
+ io:format("Failed: ~p~nInput: ~ts~n\t=> ~w |~ts|~n",[N, Line, Str, Str]),
+ io:format("Expected: ~p~n", [Res]),
+ io:format("Got: ~w~n", [Other]),
+ Acc+1;
+ Cl:R ->
+ io:format("~p: ~ts => |~tp|~n",[N, Line, Str]),
+ io:format("Expected: ~p~n", [Res]),
+ erlang:raise(Cl,R,erlang:get_stacktrace())
+ end.
+
+gc_test_data([[247]|Rest], Str, [First|GCs]) ->
+ case First of
+ [] -> gc_test_data(Rest, Str, [[]|GCs]);
+ [CP] -> gc_test_data(Rest, Str, [[],CP|GCs]);
+ _ -> gc_test_data(Rest, Str, [[],lists:reverse(First)|GCs])
+ end;
+gc_test_data([[215]|Rest], Str, GCs) ->
+ gc_test_data(Rest, Str, GCs);
+gc_test_data([Hex|Rest], Str, [First|GCs]) ->
+ CP = hex_to_int(Hex),
+ gc_test_data(Rest, [CP|Str], [[CP|First]|GCs]);
+gc_test_data([], Str, [[]|GCs]) ->
+ {lists:reverse(Str), lists:reverse(GCs)};
+gc_test_data([], Str, GCs) ->
+ {lists:reverse(Str), lists:reverse(GCs)}.
+
+nfd(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ ok = fold(fun verify_nfd/3, 0, DataDir ++ "/NormalizationTest.txt"),
+ ok.
+
+verify_nfd(<<"@Part", _/binary>>, _LineNo, _Acc) -> ok;
+verify_nfd(Data0, LineNo, _Acc) ->
+ Data1 = unicode:characters_to_list(Data0),
+ [Data2|_Comments] = string:tokens(Data1, "#"),
+ Columns = string:tokens(Data2, ";"),
+ [C1,C2,C3,C4,C5|_] = [[hex_to_int(CP) || CP <- string:tokens(C, " ")] ||
+ C <- Columns],
+ C3GC = fetch(C3, fun unicode_util:gc/1),
+ try
+ C3GC = fetch(C1, fun unicode_util:nfd/1),
+ C3GC = fetch(C2, fun unicode_util:nfd/1),
+ C3GC = fetch(C3, fun unicode_util:nfd/1)
+ catch _Cl:{badmatch, Other} = _R->
+ io:format("Failed: ~p~nInput: ~ts~n\t=> ~w |~ts|~n",[LineNo, Data1, C1, C1]),
+ io:format("Expected: ~ts ~w~n", [C3GC, C3GC]),
+ io:format("Got: ~ts ~w~n", [Other, Other]),
+ erlang:raise(_Cl,_R,erlang:get_stacktrace());
+ Cl:R ->
+ io:format("~p: ~ts => |~tp|~n",[LineNo, Data1, C1]),
+ io:format("Expected: ~p~n", [C3]),
+ erlang:raise(Cl,R,erlang:get_stacktrace())
+ end,
+ C5GC = fetch(C5, fun unicode_util:gc/1),
+ try
+ C5GC = fetch(C4, fun unicode_util:nfd/1),
+ C5GC = fetch(C5, fun unicode_util:nfd/1)
+ catch _Cl2:{badmatch, Other2} = _R2->
+ io:format("Failed: ~p~nInput: ~ts~n\t=> ~w |~ts|~n",[LineNo, Data1, C1, C1]),
+ io:format("Expected: ~ts ~w~n", [C5GC, C5GC]),
+ io:format("Got: ~ts ~w~n", [Other2, Other2]),
+ erlang:raise(_Cl2,_R2,erlang:get_stacktrace());
+ Cl2:R2 ->
+ io:format("~p: ~ts => |~tp|~n",[LineNo, Data1, C1]),
+ io:format("Expected: ~p~n", [C5]),
+ erlang:raise(Cl2,R2,erlang:get_stacktrace())
+ end,
+ ok.
+
+nfc(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ ok = fold(fun verify_nfc/3, 0, DataDir ++ "/NormalizationTest.txt"),
+ ok.
+
+verify_nfc(<<"@Part", _/binary>>, _LineNo, _Acc) -> ok;
+verify_nfc(Data0, LineNo, _Acc) ->
+ Data1 = unicode:characters_to_list(Data0),
+ [Data2|_Comments] = string:tokens(Data1, "#"),
+ Columns = string:tokens(Data2, ";"),
+ [C1,C2,C3,C4,C5|_] = [[hex_to_int(CP) || CP <- string:tokens(C, " ")] ||
+ C <- Columns],
+ C2GC = fetch(C2, fun unicode_util:gc/1),
+ try
+ C2GC = fetch(C1, fun unicode_util:nfc/1),
+ C2GC = fetch(C2, fun unicode_util:nfc/1),
+ C2GC = fetch(C3, fun unicode_util:nfc/1)
+ catch _Cl:{badmatch, Other} = _R->
+ io:format("Failed: ~p~nInput: ~ts~n\t=> ~w |~ts|~n",[LineNo, Data1, C1, C1]),
+ io:format("Expected: ~ts ~w~n", [C2GC, C2GC]),
+ io:format("Got: ~ts ~w~n", [Other, Other]),
+ erlang:raise(_Cl,_R,erlang:get_stacktrace());
+ Cl:R ->
+ io:format("~p: ~ts => |~tp|~n",[LineNo, Data1, C1]),
+ io:format("Expected: ~p~n", [C3]),
+ erlang:raise(Cl,R,erlang:get_stacktrace())
+ end,
+ C4GC = fetch(C4, fun unicode_util:gc/1),
+ try
+ C4GC = fetch(C4, fun unicode_util:nfc/1),
+ C4GC = fetch(C5, fun unicode_util:nfc/1)
+ catch _Cl2:{badmatch, Other2} = _R2->
+ io:format("Failed: ~p~nInput: ~ts~n\t=> ~w |~ts|~n",[LineNo, Data1, C1, C1]),
+ io:format("Expected: ~ts ~w~n", [C4GC, C4GC]),
+ io:format("Got: ~ts ~w~n", [Other2, Other2]),
+ erlang:raise(_Cl2,_R2,erlang:get_stacktrace());
+ Cl2:R2 ->
+ io:format("~p: ~ts => |~tp|~n",[LineNo, Data1, C1]),
+ io:format("Expected: ~p~n", [C5]),
+ erlang:raise(Cl2,R2,erlang:get_stacktrace())
+ end,
+ ok.
+
+nfkd(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ ok = fold(fun verify_nfkd/3, 0, DataDir ++ "/NormalizationTest.txt"),
+ ok.
+
+verify_nfkd(<<"@Part", _/binary>>, _LineNo, _Acc) -> ok;
+verify_nfkd(Data0, LineNo, _Acc) ->
+ Data1 = unicode:characters_to_list(Data0),
+ [Data2|_Comments] = string:tokens(Data1, "#"),
+ Columns = string:tokens(Data2, ";"),
+ [C1,C2,C3,C4,C5|_] = [[hex_to_int(CP) || CP <- string:tokens(C, " ")] ||
+ C <- Columns],
+ C5GC = lists:flatten(fetch(C5, fun unicode_util:gc/1)),
+ try
+ C5GC = lists:flatten(fetch(C1, fun unicode_util:nfkd/1)),
+ C5GC = lists:flatten(fetch(C2, fun unicode_util:nfkd/1)),
+ C5GC = lists:flatten(fetch(C3, fun unicode_util:nfkd/1)),
+ C5GC = lists:flatten(fetch(C4, fun unicode_util:nfkd/1)),
+ C5GC = lists:flatten(fetch(C5, fun unicode_util:nfkd/1))
+ catch _Cl:{badmatch, Other} = _R->
+ io:format("Failed: ~p~nInput: ~ts~n\t=> ~w |~ts|~n",[LineNo, Data1, C5, C5]),
+ io:format("Expected: ~ts ~w~n", [C5GC, C5GC]),
+ io:format("Got: ~ts ~w~n", [Other, Other]),
+ erlang:raise(_Cl,_R,erlang:get_stacktrace());
+ Cl:R ->
+ io:format("~p: ~ts => |~tp|~n",[LineNo, Data1, C1]),
+ io:format("Expected: ~p~n", [C3]),
+ erlang:raise(Cl,R,erlang:get_stacktrace())
+ end,
+ ok.
+
+
+nfkc(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ ok = fold(fun verify_nfkc/3, 0, DataDir ++ "/NormalizationTest.txt"),
+ ok.
+
+verify_nfkc(<<"@Part", _/binary>>, _LineNo, _Acc) -> ok;
+verify_nfkc(Data0, LineNo, _Acc) ->
+ Data1 = unicode:characters_to_list(Data0),
+ [Data2|_Comments] = string:tokens(Data1, "#"),
+ Columns = string:tokens(Data2, ";"),
+ [C1,C2,C3,C4,C5|_] = [[hex_to_int(CP) || CP <- string:tokens(C, " ")] ||
+ C <- Columns],
+ C4GC = lists:flatten(fetch(C4, fun unicode_util:gc/1)),
+ try
+ C4GC = lists:flatten(fetch(C1, fun unicode_util:nfkc/1)),
+ C4GC = lists:flatten(fetch(C2, fun unicode_util:nfkc/1)),
+ C4GC = lists:flatten(fetch(C3, fun unicode_util:nfkc/1)),
+ C4GC = lists:flatten(fetch(C4, fun unicode_util:nfkc/1)),
+ C4GC = lists:flatten(fetch(C5, fun unicode_util:nfkc/1))
+
+ catch _Cl:{badmatch, Other} = _R->
+ io:format("Failed: ~p~nInput: ~ts~n\t=> ~w |~ts|~n",[LineNo, Data1, C4, C4]),
+ io:format("Expected: ~ts ~w~n", [C4GC, C4GC]),
+ io:format("Got: ~ts ~w~n", [Other, Other]),
+ erlang:raise(_Cl,_R,erlang:get_stacktrace());
+ Cl:R ->
+ io:format("~p: ~ts => |~tp|~n",[LineNo, Data1, C1]),
+ io:format("Expected: ~p~n", [C3]),
+ erlang:raise(Cl,R,erlang:get_stacktrace())
+ end,
+ ok.
+
+get(_) ->
+ add_get_tests.
+
+count(Config) ->
+ ct:timetrap({minutes,5}),
+ case ct:get_timetrap_info() of
+ {_,{_,Scale}} ->
+ {skip,{measurments_skipped_debug,Scale}};
+ _ -> % No scaling
+ do_measure(Config)
+ end.
+
+do_measure(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ File = DataDir ++ "/NormalizationTest.txt",
+ {ok, Bin} = file:read_file(File),
+ Do = fun(Func, Mode) ->
+ {N, Mean, Stddev, Res} = time_count(Func, Mode, Bin),
+ io:format("~4w ~6w ~.10w ~.6wms ±~.2wms #~.2w~n",
+ [Func, Mode, Res, Mean div 1000, Stddev div 1000, N])
+ end,
+ Do(lref, list),
+ Do(bref, binary),
+ io:format("----------------------~n"),
+ [Do(What,Mode) || What <- [cp, gc, nfd, nfc, nfkd, nfkc], Mode <- [list, deep_l, binary, deep_b]],
+ io:format("Size of unicode_util: ~pkB~n",[uc_loaded_size() div 1024]),
+ ok.
+
+uc_loaded_size() ->
+ uc_loaded_size(binary:split(erlang:system_info(loaded), <<$\n>>, [global])).
+
+uc_loaded_size([<<"unicode_util ", Rest/binary>>|_]) ->
+ [StrSize|_] = binary:split(Rest, <<$\s>>),
+ binary_to_integer(StrSize);
+uc_loaded_size([_|Rest]) ->
+ uc_loaded_size(Rest).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+time_count(Fun, Mode, Bin) ->
+ timer:sleep(100), %% Let emulator catch up and clean things before test runs
+ Self = self(),
+ Pid = spawn_link(fun() ->
+ Str = mode(Mode, Bin),
+ Self ! {self(),do_count(0,0,0, Fun, Str, undefined)}
+ end),
+ receive {Pid,Msg} -> Msg end.
+
+do_count(N,Sum,SumSq, Fun, Str, _) when N < 10 ->
+ {Time, Res} = do_count(Fun, Str),
+ do_count(N+1,Sum+Time,SumSq+Time*Time, Fun, Str, Res);
+do_count(N,Sum,SumSq, _, _, Res) ->
+ Mean = round(Sum / N),
+ Stdev = round(math:sqrt((SumSq - (Sum*Sum/N))/(N - 1))),
+ {N, Mean, Stdev, Res}.
+
+do_count(Fun, Str) ->
+ Count = fun Count(Str0, N) ->
+ case unicode_util:Fun(Str0) of
+ [] -> N;
+ [_|Str1] -> Count(Str1,N+1)
+ end
+ end,
+
+ if Fun =/= lref, Fun =/= bref ->
+ timer:tc(fun() -> Count(Str, 0) end);
+ true ->
+ Pick = case Fun of
+ lref -> id(id);
+ bref -> id(bin_split)
+ end,
+ Ref = fun LR(Str0, N) ->
+ case ?MODULE:Pick(Str0) of
+ [] -> N;
+ [_|Str1] -> LR(Str1,N+1)
+ end
+ end,
+ timer:tc(fun() -> Ref(Str, 0) end)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+id(Op) -> Op.
+
+bin_split(<<>>) -> [];
+bin_split(<<CP/utf8,R/binary>>) -> [CP|R].
+
+mode(binary, Bin) -> Bin;
+mode(list, Bin) -> unicode:characters_to_list(Bin);
+mode(deep_b, Bin) -> [Bin];
+mode(deep_l, Bin) -> [unicode:characters_to_list(Bin)].
+
+fetch(Str, F) ->
+ case F(Str) of
+ [] -> [];
+ [CP|R] -> [CP|fetch(R,F)]
+ end.
+
+%% *Test.txt file helpers
+
+hex_to_int([]) -> [];
+hex_to_int(HexStr) ->
+ list_to_integer(string:strip(HexStr, both), 16).
+
+fold(Fun, Acc, File) ->
+ io:format("Processing ~s~n",[File]),
+ {ok, Fd} = file:open(File, [read, raw, binary, {read_ahead, 100000}]),
+ Get = fun() -> file:read_line(Fd) end,
+ try
+ fold_1(Fun, 1, Acc, Get)
+ after
+ ok = file:close(Fd)
+ end.
+
+fold_1(Fun, Line, Acc, Get) ->
+ case Get() of
+ eof -> Acc;
+ {ok, <<"#",_/binary>>} -> %% Ignore comments
+ fold_1(Fun, Line+1, Acc, Get);
+ {ok, <<"\n">>} -> %% Ignore empty lines
+ fold_1(Fun, Line+1, Acc, Get);
+ {ok, Data} ->
+ fold_1(Fun, Line+1, Fun(Data, Line, Acc), Get)
+ end.
diff --git a/lib/stdlib/test/unicode_util_SUITE_data/GraphemeBreakTest.txt b/lib/stdlib/test/unicode_util_SUITE_data/GraphemeBreakTest.txt
new file mode 100644
index 0000000000..4bb4b1369b
--- /dev/null
+++ b/lib/stdlib/test/unicode_util_SUITE_data/GraphemeBreakTest.txt
@@ -0,0 +1,849 @@
+# GraphemeBreakTest-9.0.0.txt
+# Date: 2016-06-02, 18:28:17 GMT
+# © 2016 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see http://www.unicode.org/reports/tr44/
+#
+# Default Grapheme Break Test
+#
+# Format:
+# <string> (# <comment>)?
+# <string> contains hex Unicode code points, with
+# ÷ wherever there is a break opportunity, and
+# × wherever there is not.
+# <comment> the format can change, but currently it shows:
+# - the sample character name
+# - (x) the Grapheme_Cluster_Break property value for the sample character
+# - [x] the rule that determines whether there is a break or not
+#
+# These samples may be extended or changed in the future.
+#
+÷ 0020 ÷ 0020 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0020 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0020 ÷ 000D ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0020 × 0308 ÷ 000D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0020 ÷ 000A ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0020 × 0308 ÷ 000A ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0020 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0020 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0020 × 0308 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0020 ÷ 0600 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0600 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0020 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0020 × 0308 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0020 ÷ 1100 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0020 × 0308 ÷ 1100 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0020 ÷ 1160 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0020 × 0308 ÷ 1160 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0020 ÷ 11A8 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0020 × 0308 ÷ 11A8 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0020 ÷ AC00 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0020 × 0308 ÷ AC00 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0020 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0020 × 0308 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0020 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0020 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0020 ÷ 261D ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0020 × 0308 ÷ 261D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0020 ÷ 1F3FB ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0020 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0020 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0020 × 0308 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0020 ÷ 2764 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0020 × 0308 ÷ 2764 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0020 ÷ 1F466 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 0020 × 0308 ÷ 1F466 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 0020 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0020 ÷ D800 ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 0020 × 0308 ÷ D800 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 000D ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] SPACE (Other) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 000D ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000D × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000D ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 000D ÷ 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 000D ÷ 0600 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 000D ÷ 0903 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 000D ÷ 0308 × 0903 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 000D ÷ 1100 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 000D ÷ 1160 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 000D ÷ 11A8 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 000D ÷ AC00 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 000D ÷ AC01 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 000D ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000D ÷ 261D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 261D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 000D ÷ 1F3FB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 1F3FB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 000D ÷ 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 000D ÷ 0308 × 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 000D ÷ 2764 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 2764 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 000D ÷ 1F466 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] BOY (EBG) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 1F466 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 000D ÷ 0378 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 000D ÷ D800 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 000A ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] SPACE (Other) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 000A ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000A ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000A ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 000A ÷ 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 000A ÷ 0600 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 000A ÷ 0903 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 000A ÷ 0308 × 0903 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 000A ÷ 1100 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 000A ÷ 1160 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 000A ÷ 11A8 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 000A ÷ AC00 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 000A ÷ AC01 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 000A ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000A ÷ 261D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 261D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 000A ÷ 1F3FB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 1F3FB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 000A ÷ 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 000A ÷ 0308 × 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 000A ÷ 2764 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 2764 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 000A ÷ 1F466 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] BOY (EBG) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 1F466 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 000A ÷ 0378 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 000A ÷ D800 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 0001 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] SPACE (Other) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0001 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0001 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0001 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0001 ÷ 0300 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0001 ÷ 0308 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0001 ÷ 0600 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0001 ÷ 0903 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0001 ÷ 0308 × 0903 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0001 ÷ 1100 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0001 ÷ 1160 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0001 ÷ 11A8 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0001 ÷ AC00 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0001 ÷ AC01 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0001 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0001 ÷ 261D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 261D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0001 ÷ 1F3FB ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 1F3FB ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0001 ÷ 200D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0001 ÷ 0308 × 200D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0001 ÷ 2764 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 2764 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0001 ÷ 1F466 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] BOY (EBG) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 1F466 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 0001 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0001 ÷ D800 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 0300 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0300 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0300 × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0300 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0300 × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0300 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0300 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0300 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0300 × 0308 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0300 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0300 × 0308 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0300 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0300 × 0308 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0300 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0300 × 0308 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0300 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0300 × 0308 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0300 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0300 × 0308 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0300 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0300 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0300 ÷ 261D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0300 × 0308 ÷ 261D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0300 ÷ 1F3FB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0300 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0300 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0300 × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0300 ÷ 2764 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0300 × 0308 ÷ 2764 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0300 ÷ 1F466 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 0300 × 0308 ÷ 1F466 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 0300 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0300 ÷ D800 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 0300 × 0308 ÷ D800 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 0600 × 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] SPACE (Other) ÷ [0.3]
+÷ 0600 × 0308 ÷ 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0600 ÷ 000D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0600 × 0308 ÷ 000D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0600 ÷ 000A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0600 × 0308 ÷ 000A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0600 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0600 × 0308 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0600 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0600 × 0308 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0600 × 0600 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0600 × 0308 ÷ 0600 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0600 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0600 × 0308 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0600 × 1100 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0600 × 0308 ÷ 1100 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0600 × 1160 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0600 × 0308 ÷ 1160 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0600 × 11A8 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0600 × 0308 ÷ 11A8 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0600 × AC00 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0600 × 0308 ÷ AC00 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0600 × AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0600 × 0308 ÷ AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0600 × 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0600 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0600 × 261D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0600 × 0308 ÷ 261D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0600 × 1F3FB ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0600 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0600 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0600 × 0308 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0600 × 2764 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0600 × 0308 ÷ 2764 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0600 × 1F466 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] BOY (EBG) ÷ [0.3]
+÷ 0600 × 0308 ÷ 1F466 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 0600 × 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] <reserved-0378> (Other) ÷ [0.3]
+÷ 0600 × 0308 ÷ 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0600 ÷ D800 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 0600 × 0308 ÷ D800 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 0903 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0903 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0903 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0903 × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0903 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0903 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0903 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0903 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0903 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0903 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0903 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0903 × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0903 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0903 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0903 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0903 × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0903 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0903 × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0903 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0903 × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0903 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0903 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0903 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0903 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0903 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0903 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0903 ÷ 261D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0903 × 0308 ÷ 261D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0903 ÷ 1F3FB ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0903 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0903 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0903 × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0903 ÷ 2764 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0903 × 0308 ÷ 2764 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0903 ÷ 1F466 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 0903 × 0308 ÷ 1F466 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 0903 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0903 × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0903 ÷ D800 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 0903 × 0308 ÷ D800 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 1100 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1100 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1100 ÷ 000D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1100 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1100 ÷ 000A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1100 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1100 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1100 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1100 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 1100 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 1100 ÷ 0600 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1100 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1100 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1100 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1100 × 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1100 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1100 × 1160 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1100 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1100 ÷ 11A8 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1100 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1100 × AC00 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1100 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1100 × AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1100 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1100 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1100 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1100 ÷ 261D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 1100 × 0308 ÷ 261D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 1100 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 1100 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 1100 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 1100 × 0308 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 1100 ÷ 2764 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 1100 × 0308 ÷ 2764 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 1100 ÷ 1F466 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 1100 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 1100 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1100 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1100 ÷ D800 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 1100 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 1160 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1160 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1160 ÷ 000D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1160 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1160 ÷ 000A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1160 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1160 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1160 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1160 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 1160 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 1160 ÷ 0600 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1160 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1160 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1160 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1160 ÷ 1100 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1160 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1160 × 1160 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [7.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1160 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1160 × 11A8 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1160 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1160 ÷ AC00 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1160 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1160 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1160 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1160 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1160 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1160 ÷ 261D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 1160 × 0308 ÷ 261D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 1160 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 1160 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 1160 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 1160 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 1160 ÷ 2764 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 1160 × 0308 ÷ 2764 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 1160 ÷ 1F466 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 1160 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 1160 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1160 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1160 ÷ D800 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 1160 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 11A8 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 11A8 ÷ 000D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 11A8 ÷ 000A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 11A8 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 11A8 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 11A8 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 11A8 ÷ 0600 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 11A8 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 11A8 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 11A8 ÷ 1160 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 11A8 × 11A8 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 11A8 ÷ AC00 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 11A8 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 11A8 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 11A8 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 11A8 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 11A8 ÷ 261D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 261D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 11A8 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 11A8 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 11A8 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 11A8 ÷ 2764 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 2764 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 11A8 ÷ 1F466 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 11A8 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 11A8 ÷ D800 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 11A8 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ AC00 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ AC00 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ AC00 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ AC00 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ AC00 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ AC00 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ AC00 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ AC00 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ AC00 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ AC00 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ AC00 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ AC00 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ AC00 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ AC00 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ AC00 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC00 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC00 × 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ AC00 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ AC00 × 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ AC00 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ AC00 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ AC00 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ AC00 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ AC00 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ AC00 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ AC00 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ AC00 ÷ 261D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ AC00 × 0308 ÷ 261D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ AC00 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ AC00 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ AC00 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ AC00 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ AC00 ÷ 2764 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ AC00 × 0308 ÷ 2764 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ AC00 ÷ 1F466 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ AC00 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ AC00 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ AC00 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ AC00 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ AC00 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ AC01 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ AC01 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ AC01 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ AC01 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ AC01 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ AC01 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ AC01 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ AC01 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ AC01 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ AC01 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ AC01 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ AC01 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ AC01 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ AC01 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ AC01 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC01 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC01 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ AC01 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ AC01 × 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ AC01 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ AC01 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ AC01 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ AC01 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ AC01 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ AC01 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ AC01 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ AC01 ÷ 261D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ AC01 × 0308 ÷ 261D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ AC01 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ AC01 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ AC01 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ AC01 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ AC01 ÷ 2764 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ AC01 × 0308 ÷ 2764 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ AC01 ÷ 1F466 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ AC01 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ AC01 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ AC01 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ AC01 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ AC01 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 1F1E6 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1F1E6 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1F1E6 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1F1E6 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1F1E6 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 1F1E6 × 0308 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 1F1E6 ÷ 0600 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0600 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1F1E6 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1F1E6 × 0308 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1F1E6 ÷ 1100 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 1100 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1F1E6 ÷ 1160 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 1160 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1F1E6 ÷ 11A8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 11A8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1F1E6 ÷ AC00 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ AC00 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1F1E6 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1F1E6 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1F1E6 ÷ 261D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 261D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 1F1E6 ÷ 1F3FB ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 1F1E6 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 1F1E6 × 0308 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 1F1E6 ÷ 2764 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 2764 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 1F1E6 ÷ 1F466 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 1F466 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 1F1E6 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1F1E6 ÷ D800 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ D800 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 261D ÷ 0020 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 261D × 0308 ÷ 0020 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 261D ÷ 000D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 261D × 0308 ÷ 000D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 261D ÷ 000A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 261D × 0308 ÷ 000A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 261D ÷ 0001 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 261D × 0308 ÷ 0001 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 261D × 0300 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 261D × 0308 × 0300 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 261D ÷ 0600 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 261D × 0308 ÷ 0600 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 261D × 0903 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 261D × 0308 × 0903 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 261D ÷ 1100 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 261D × 0308 ÷ 1100 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 261D ÷ 1160 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 261D × 0308 ÷ 1160 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 261D ÷ 11A8 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 261D × 0308 ÷ 11A8 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 261D ÷ AC00 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 261D × 0308 ÷ AC00 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 261D ÷ AC01 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 261D × 0308 ÷ AC01 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 261D ÷ 1F1E6 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 261D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 261D ÷ 261D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 261D × 0308 ÷ 261D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 261D × 1F3FB ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 261D × 0308 × 1F3FB ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 261D × 200D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 261D × 0308 × 200D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 261D ÷ 2764 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 261D × 0308 ÷ 2764 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 261D ÷ 1F466 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 261D × 0308 ÷ 1F466 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 261D ÷ 0378 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 261D × 0308 ÷ 0378 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 261D ÷ D800 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 261D × 0308 ÷ D800 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 1F3FB ÷ 0020 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 0020 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1F3FB ÷ 000D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 000D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1F3FB ÷ 000A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 000A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1F3FB ÷ 0001 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 0001 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1F3FB × 0300 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 1F3FB × 0308 × 0300 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 1F3FB ÷ 0600 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 0600 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1F3FB × 0903 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1F3FB × 0308 × 0903 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1F3FB ÷ 1100 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 1100 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1F3FB ÷ 1160 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 1160 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1F3FB ÷ 11A8 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 11A8 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1F3FB ÷ AC00 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ AC00 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1F3FB ÷ AC01 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ AC01 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1F3FB ÷ 1F1E6 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1F3FB ÷ 261D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 261D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 1F3FB ÷ 1F3FB ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 1F3FB ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 1F3FB × 200D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 1F3FB × 0308 × 200D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 1F3FB ÷ 2764 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 2764 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 1F3FB ÷ 1F466 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 1F466 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 1F3FB ÷ 0378 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ 0378 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1F3FB ÷ D800 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 1F3FB × 0308 ÷ D800 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 200D ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 200D × 0308 ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 200D ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 200D × 0308 ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 200D ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 200D × 0308 ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 200D ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 200D × 0308 ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 200D × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 200D × 0308 × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 200D ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 200D × 0308 ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 200D × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 200D × 0308 × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 200D ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 200D × 0308 ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 200D ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 200D × 0308 ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 200D ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 200D × 0308 ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 200D ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 200D × 0308 ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 200D ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 200D × 0308 ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 200D ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 200D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 200D ÷ 261D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 200D × 0308 ÷ 261D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 200D ÷ 1F3FB ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 200D × 0308 ÷ 1F3FB ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 200D × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 200D × 0308 × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 200D × 2764 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [11.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 200D × 0308 ÷ 2764 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 200D × 1F466 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [11.0] BOY (EBG) ÷ [0.3]
+÷ 200D × 0308 ÷ 1F466 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 200D ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 200D × 0308 ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 200D ÷ D800 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 200D × 0308 ÷ D800 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 2764 ÷ 0020 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 2764 × 0308 ÷ 0020 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 2764 ÷ 000D ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 2764 × 0308 ÷ 000D ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 2764 ÷ 000A ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 2764 × 0308 ÷ 000A ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 2764 ÷ 0001 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 2764 × 0308 ÷ 0001 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 2764 × 0300 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 2764 × 0308 × 0300 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 2764 ÷ 0600 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 2764 × 0308 ÷ 0600 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 2764 × 0903 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 2764 × 0308 × 0903 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 2764 ÷ 1100 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 2764 × 0308 ÷ 1100 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 2764 ÷ 1160 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 2764 × 0308 ÷ 1160 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 2764 ÷ 11A8 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 2764 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 2764 ÷ AC00 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 2764 × 0308 ÷ AC00 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 2764 ÷ AC01 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 2764 × 0308 ÷ AC01 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 2764 ÷ 1F1E6 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 2764 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 2764 ÷ 261D ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 2764 × 0308 ÷ 261D ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 2764 ÷ 1F3FB ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 2764 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 2764 × 200D ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 2764 × 0308 × 200D ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 2764 ÷ 2764 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 2764 × 0308 ÷ 2764 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 2764 ÷ 1F466 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 2764 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 2764 ÷ 0378 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 2764 × 0308 ÷ 0378 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 2764 ÷ D800 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 2764 × 0308 ÷ D800 ÷ # ÷ [0.2] HEAVY BLACK HEART (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 1F466 ÷ 0020 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 0020 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1F466 ÷ 000D ÷ # ÷ [0.2] BOY (EBG) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 000D ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1F466 ÷ 000A ÷ # ÷ [0.2] BOY (EBG) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 000A ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1F466 ÷ 0001 ÷ # ÷ [0.2] BOY (EBG) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 0001 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1F466 × 0300 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 1F466 × 0308 × 0300 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 1F466 ÷ 0600 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 0600 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1F466 × 0903 ÷ # ÷ [0.2] BOY (EBG) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1F466 × 0308 × 0903 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1F466 ÷ 1100 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 1100 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1F466 ÷ 1160 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 1160 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1F466 ÷ 11A8 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 11A8 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1F466 ÷ AC00 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1F466 × 0308 ÷ AC00 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1F466 ÷ AC01 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1F466 × 0308 ÷ AC01 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1F466 ÷ 1F1E6 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1F466 ÷ 261D ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 261D ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 1F466 × 1F3FB ÷ # ÷ [0.2] BOY (EBG) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 1F466 × 0308 × 1F3FB ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 1F466 × 200D ÷ # ÷ [0.2] BOY (EBG) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 1F466 × 0308 × 200D ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 1F466 ÷ 2764 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 2764 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 1F466 ÷ 1F466 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 1F466 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 1F466 ÷ 0378 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1F466 × 0308 ÷ 0378 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1F466 ÷ D800 ÷ # ÷ [0.2] BOY (EBG) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 1F466 × 0308 ÷ D800 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 0378 ÷ 0020 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0378 × 0308 ÷ 0020 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0378 ÷ 000D ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0378 × 0308 ÷ 000D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0378 ÷ 000A ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0378 × 0308 ÷ 000A ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0378 ÷ 0001 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0378 × 0308 ÷ 0001 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0378 × 0300 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0378 × 0308 × 0300 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ 0378 ÷ 0600 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0378 × 0308 ÷ 0600 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0378 × 0903 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0378 × 0308 × 0903 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0378 ÷ 1100 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0378 × 0308 ÷ 1100 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0378 ÷ 1160 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0378 × 0308 ÷ 1160 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0378 ÷ 11A8 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0378 × 0308 ÷ 11A8 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0378 ÷ AC00 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0378 × 0308 ÷ AC00 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0378 ÷ AC01 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0378 × 0308 ÷ AC01 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0378 ÷ 1F1E6 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0378 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0378 ÷ 261D ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0378 × 0308 ÷ 261D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 0378 ÷ 1F3FB ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0378 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 0378 × 200D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0378 × 0308 × 200D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0378 ÷ 2764 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0378 × 0308 ÷ 2764 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 0378 ÷ 1F466 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 0378 × 0308 ÷ 1F466 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ 0378 ÷ 0378 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0378 × 0308 ÷ 0378 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0378 ÷ D800 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 0378 × 0308 ÷ D800 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ D800 ÷ 0020 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] SPACE (Other) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ D800 ÷ 000D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ D800 ÷ 000A ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ D800 ÷ 0001 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ D800 ÷ 0300 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ D800 ÷ 0308 × 0300 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
+÷ D800 ÷ 0600 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ D800 ÷ 0903 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ D800 ÷ 0308 × 0903 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ D800 ÷ 1100 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ D800 ÷ 1160 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ D800 ÷ 11A8 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ D800 ÷ AC00 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ D800 ÷ AC01 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ D800 ÷ 1F1E6 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ D800 ÷ 261D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 261D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ D800 ÷ 1F3FB ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 1F3FB ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ D800 ÷ 200D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ D800 ÷ 0308 × 200D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ D800 ÷ 2764 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 2764 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ D800 ÷ 1F466 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] BOY (EBG) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 1F466 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
+÷ D800 ÷ 0378 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ D800 ÷ D800 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ D800 ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
+÷ 000D × 000A ÷ 0061 ÷ 000A ÷ 0308 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [0.3]
+÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [0.3]
+÷ 0020 × 200D ÷ 0646 ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] ARABIC LETTER NOON (Other) ÷ [0.3]
+÷ 0646 × 200D ÷ 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (Other) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1100 × 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC00 × 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC01 × 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 1F1E7 × 200D ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 200D ÷ 1F1E7 × 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 × 1F1E9 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER D (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
+÷ 0061 × 0308 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 × 0903 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 ÷ 0600 × 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) × [9.2] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 261D × 1F3FB ÷ 261D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
+÷ 1F466 × 1F3FB ÷ # ÷ [0.2] BOY (EBG) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 200D × 1F466 × 1F3FB ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [11.0] BOY (EBG) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
+÷ 200D × 2764 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [11.0] HEAVY BLACK HEART (Glue_After_Zwj) ÷ [0.3]
+÷ 200D × 1F466 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [11.0] BOY (EBG) ÷ [0.3]
+÷ 1F466 ÷ 1F466 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] BOY (EBG) ÷ [0.3]
+#
+# Lines: 822
+#
+# EOF
diff --git a/lib/stdlib/test/unicode_util_SUITE_data/LineBreakTest.txt b/lib/stdlib/test/unicode_util_SUITE_data/LineBreakTest.txt
new file mode 100644
index 0000000000..05efcf5a44
--- /dev/null
+++ b/lib/stdlib/test/unicode_util_SUITE_data/LineBreakTest.txt
@@ -0,0 +1,7341 @@
+# LineBreakTest-9.0.0.txt
+# Date: 2016-06-18, 00:42:06 GMT
+# © 2016 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see http://www.unicode.org/reports/tr44/
+#
+# Default Line Break Test
+#
+# Format:
+# <string> (# <comment>)?
+# <string> contains hex Unicode code points, with
+# ÷ wherever there is a break opportunity, and
+# × wherever there is not.
+# <comment> the format can change, but currently it shows:
+# - the sample character name
+# - (x) the Line_Break property value for the sample character
+# - [x] the rule that determines whether there is a break or not
+# Note: The Line Break tests use tailoring of numbers described in Example 7 of Section 8.2 Examples of Customization.
+# They also differ from the results produced by a pair table implementation in sequences like: ZW SP CL.
+#
+# These samples may be extended or changed in the future.
+#
+× 0023 × 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0023 × 0020 ÷ 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0023 × 0308 × 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0023 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0023 × 0020 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0023 × 0308 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0023 × 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0023 × 0020 ÷ 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0023 × 0308 × 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0023 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0023 × 0020 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0023 × 0308 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0023 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0023 × 0020 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0023 × 0308 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0023 × 0308 × 0020 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0023 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0023 × 0020 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0023 × 0308 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0023 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0023 × 0020 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0023 × 0308 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0023 × 0308 × 0020 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0023 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0023 × 0020 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0023 × 0308 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0023 × 0308 × 0020 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0023 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0023 × 0020 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0023 × 0308 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0023 × 0308 × 0020 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0023 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0023 × 0020 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0023 × 0308 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0023 × 0308 × 0020 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0023 × 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0023 × 0020 ÷ 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0023 × 0308 × 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0023 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0023 × 0020 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0023 × 0308 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0023 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0023 × 0020 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0023 × 0308 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0023 × 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0023 × 0020 ÷ 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0023 × 0308 × 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0023 × 002D ÷ # × [0.3] NUMBER SIGN (AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0023 × 0020 ÷ 002D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0023 × 0308 × 002D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 002D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0023 ÷ 231A ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0023 × 0020 ÷ 231A ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0023 × 0308 ÷ 231A ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 231A ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0023 × 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 0023 × 0020 ÷ 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0023 × 0308 × 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0023 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] COMMA (IS) ÷ [0.3]
+× 0023 × 0020 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0023 × 0308 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0023 × 0308 × 0020 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0023 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0023 × 0020 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0023 × 0308 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0023 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0023 × 0020 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0023 × 0308 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0023 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0023 × 0020 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0023 × 0308 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0023 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0023 × 0020 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0023 × 0308 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0023 × 0308 × 0020 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0023 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0023 × 0020 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0023 × 0308 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0023 × 0308 × 0020 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0023 × 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0023 × 0020 ÷ 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0023 × 0308 × 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0023 × 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0023 × 0020 ÷ 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0023 × 0308 × 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0023 × 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0023 × 0020 ÷ 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0023 × 0308 × 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0023 × 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0023 × 0020 ÷ 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0023 × 0308 × 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0023 × 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0023 × 0020 ÷ 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0023 × 0308 × 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0023 × 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0023 × 0020 ÷ 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0023 × 0308 × 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0023 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 0023 × 0020 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0023 × 0308 × 0020 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0023 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0023 × 0020 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0023 × 0308 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0023 × 0308 × 0020 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0023 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0023 × 0020 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0023 × 0308 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0023 × 0308 × 0020 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0023 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0023 × 0020 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0023 × 0308 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0023 × 0308 × 0020 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0023 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0023 × 0020 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0023 × 0308 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0023 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0023 × 0020 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0023 × 0308 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0023 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0023 × 0020 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0023 × 0308 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0023 × 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0023 × 0020 ÷ 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0023 × 0308 × 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0023 × 200D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0023 × 0020 ÷ 200D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0023 × 0308 × 200D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 200D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0023 × 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0023 × 0020 ÷ 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0023 × 0308 × 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0023 × 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0023 × 0020 ÷ 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0023 × 0308 × 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0023 × 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0023 × 0020 ÷ 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0023 × 0308 × 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0023 × 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0023 × 0020 ÷ 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0023 × 0308 × 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2014 ÷ 0023 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2014 × 0020 ÷ 0023 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2014 × 0308 ÷ 0023 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2014 × 2014 ÷ # × [0.3] EM DASH (B2) × [17.0] EM DASH (B2) ÷ [0.3]
+× 2014 × 0020 × 2014 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [17.0] EM DASH (B2) ÷ [0.3]
+× 2014 × 0308 × 2014 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [17.0] EM DASH (B2) ÷ [0.3]
+× 2014 × 0308 × 0020 × 2014 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [17.0] EM DASH (B2) ÷ [0.3]
+× 2014 × 0009 ÷ # × [0.3] EM DASH (B2) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2014 × 0020 ÷ 0009 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2014 × 0308 × 0009 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2014 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2014 × 0020 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2014 × 0308 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2014 × 000B ÷ # × [0.3] EM DASH (B2) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2014 × 0020 × 000B ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2014 × 0308 × 000B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2014 × 0308 × 0020 × 000B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2014 ÷ FFFC ÷ # × [0.3] EM DASH (B2) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2014 × 0020 ÷ FFFC ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2014 × 0308 ÷ FFFC ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2014 × 007D ÷ # × [0.3] EM DASH (B2) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2014 × 0020 × 007D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2014 × 0308 × 007D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2014 × 0308 × 0020 × 007D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2014 × 0029 ÷ # × [0.3] EM DASH (B2) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2014 × 0020 × 0029 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2014 × 0308 × 0029 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2014 × 0308 × 0020 × 0029 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2014 × 000D ÷ # × [0.3] EM DASH (B2) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2014 × 0020 × 000D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2014 × 0308 × 000D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2014 × 0308 × 0020 × 000D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2014 × 0021 ÷ # × [0.3] EM DASH (B2) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2014 × 0020 × 0021 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2014 × 0308 × 0021 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2014 × 0308 × 0020 × 0021 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2014 × 00A0 ÷ # × [0.3] EM DASH (B2) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2014 × 0020 ÷ 00A0 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2014 × 0308 × 00A0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2014 ÷ AC00 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2014 × 0020 ÷ AC00 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2014 × 0308 ÷ AC00 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2014 ÷ AC01 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2014 × 0020 ÷ AC01 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2014 × 0308 ÷ AC01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2014 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2014 × 0020 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2014 × 0308 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2014 × 002D ÷ # × [0.3] EM DASH (B2) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2014 × 0020 ÷ 002D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2014 × 0308 × 002D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 002D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2014 ÷ 231A ÷ # × [0.3] EM DASH (B2) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 2014 × 0020 ÷ 231A ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 2014 × 0308 ÷ 231A ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 231A ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 2014 ÷ 2024 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2014 × 0020 ÷ 2024 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2014 × 0308 ÷ 2024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2014 × 002C ÷ # × [0.3] EM DASH (B2) × [13.02] COMMA (IS) ÷ [0.3]
+× 2014 × 0020 × 002C ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2014 × 0308 × 002C ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 2014 × 0308 × 0020 × 002C ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2014 ÷ 1100 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2014 × 0020 ÷ 1100 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2014 × 0308 ÷ 1100 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2014 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2014 × 0020 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2014 × 0308 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2014 ÷ 1160 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2014 × 0020 ÷ 1160 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2014 × 0308 ÷ 1160 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2014 × 000A ÷ # × [0.3] EM DASH (B2) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2014 × 0020 × 000A ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2014 × 0308 × 000A ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2014 × 0308 × 0020 × 000A ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2014 × 0085 ÷ # × [0.3] EM DASH (B2) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2014 × 0020 × 0085 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2014 × 0308 × 0085 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2014 × 0308 × 0020 × 0085 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2014 × 17D6 ÷ # × [0.3] EM DASH (B2) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2014 × 0020 ÷ 17D6 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2014 × 0308 × 17D6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2014 ÷ 0030 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2014 × 0020 ÷ 0030 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2014 × 0308 ÷ 0030 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2014 ÷ 0028 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2014 × 0020 ÷ 0028 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2014 × 0308 ÷ 0028 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2014 ÷ 0025 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2014 × 0020 ÷ 0025 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2014 × 0308 ÷ 0025 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2014 ÷ 0024 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2014 × 0020 ÷ 0024 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2014 × 0308 ÷ 0024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2014 × 0022 ÷ # × [0.3] EM DASH (B2) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 2014 × 0020 ÷ 0022 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2014 × 0308 × 0022 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2014 × 0020 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [0.3]
+× 2014 × 0020 × 0020 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 2014 × 0308 × 0020 × 0020 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2014 × 002F ÷ # × [0.3] EM DASH (B2) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2014 × 0020 × 002F ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2014 × 0308 × 002F ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 2014 × 0308 × 0020 × 002F ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2014 × 2060 ÷ # × [0.3] EM DASH (B2) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2014 × 0020 × 2060 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2014 × 0308 × 2060 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2014 × 0308 × 0020 × 2060 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2014 × 200B ÷ # × [0.3] EM DASH (B2) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2014 × 0020 × 200B ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2014 × 0308 × 200B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2014 × 0308 × 0020 × 200B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2014 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2014 × 0020 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2014 × 0308 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2014 ÷ 261D ÷ # × [0.3] EM DASH (B2) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2014 × 0020 ÷ 261D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2014 × 0308 ÷ 261D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 261D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2014 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2014 × 0020 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2014 × 0308 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2014 × 0001 ÷ # × [0.3] EM DASH (B2) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2014 × 0020 ÷ 0001 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2014 × 0308 × 0001 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2014 × 200D ÷ # × [0.3] EM DASH (B2) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2014 × 0020 ÷ 200D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2014 × 0308 × 200D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 200D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2014 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2014 × 0020 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2014 × 0308 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2014 ÷ 50005 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2014 × 0020 ÷ 50005 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2014 × 0308 ÷ 50005 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2014 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2014 × 0020 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2014 × 0308 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2014 × 3041 ÷ # × [0.3] EM DASH (B2) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2014 × 0020 ÷ 3041 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2014 × 0308 × 3041 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0009 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0009 × 0020 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0009 × 0308 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0009 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0009 × 0020 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0009 × 0308 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0009 × 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0009 × 0020 ÷ 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0009 × 0308 × 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0009 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0009 × 0020 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0009 × 0308 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0009 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0009 × 0020 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0009 × 0308 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0009 × 0308 × 0020 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0009 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0009 × 0020 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0009 × 0308 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0009 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0009 × 0020 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0009 × 0308 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0009 × 0308 × 0020 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0009 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0009 × 0020 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0009 × 0308 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0009 × 0308 × 0020 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0009 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0009 × 0020 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0009 × 0308 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0009 × 0308 × 0020 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0009 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0009 × 0020 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0009 × 0308 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0009 × 0308 × 0020 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0009 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0009 × 0020 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0009 × 0308 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0009 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0009 × 0020 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0009 × 0308 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0009 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0009 × 0020 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0009 × 0308 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0009 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0009 × 0020 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0009 × 0308 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0009 × 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0009 × 0020 ÷ 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0009 × 0308 × 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0009 ÷ 231A ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0009 × 0020 ÷ 231A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0009 × 0308 ÷ 231A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 231A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0009 ÷ 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0009 × 0020 ÷ 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0009 × 0308 ÷ 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0009 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] COMMA (IS) ÷ [0.3]
+× 0009 × 0020 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0009 × 0308 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0009 × 0308 × 0020 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0009 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0009 × 0020 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0009 × 0308 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0009 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0009 × 0020 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0009 × 0308 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0009 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0009 × 0020 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0009 × 0308 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0009 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0009 × 0020 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0009 × 0308 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0009 × 0308 × 0020 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0009 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0009 × 0020 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0009 × 0308 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0009 × 0308 × 0020 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0009 × 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0009 × 0020 ÷ 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0009 × 0308 × 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0009 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0009 × 0020 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0009 × 0308 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0009 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0009 × 0020 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0009 × 0308 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0009 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0009 × 0020 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0009 × 0308 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0009 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0009 × 0020 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0009 × 0308 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0009 × 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0009 × 0020 ÷ 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0009 × 0308 × 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0009 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [0.3]
+× 0009 × 0020 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0009 × 0308 × 0020 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0009 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0009 × 0020 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0009 × 0308 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0009 × 0308 × 0020 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0009 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0009 × 0020 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0009 × 0308 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0009 × 0308 × 0020 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0009 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0009 × 0020 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0009 × 0308 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0009 × 0308 × 0020 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0009 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0009 × 0020 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0009 × 0308 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0009 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0009 × 0020 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0009 × 0308 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0009 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0009 × 0020 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0009 × 0308 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0009 × 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0009 × 0020 ÷ 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0009 × 0308 × 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0009 × 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0009 × 0020 ÷ 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0009 × 0308 × 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0009 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0009 × 0020 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0009 × 0308 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0009 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0009 × 0020 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0009 × 0308 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0009 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0009 × 0020 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0009 × 0308 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0009 × 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0009 × 0020 ÷ 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0009 × 0308 × 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00B4 × 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] NUMBER SIGN (AL) ÷ [0.3]
+× 00B4 × 0020 ÷ 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00B4 × 0308 × 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] NUMBER SIGN (AL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00B4 × 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] EM DASH (B2) ÷ [0.3]
+× 00B4 × 0020 ÷ 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00B4 × 0308 × 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] EM DASH (B2) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00B4 × 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00B4 × 0020 ÷ 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00B4 × 0308 × 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00B4 × 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] ACUTE ACCENT (BB) ÷ [0.3]
+× 00B4 × 0020 ÷ 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00B4 × 0308 × 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] ACUTE ACCENT (BB) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00B4 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00B4 × 0020 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00B4 × 0308 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00B4 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00B4 × 0020 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00B4 × 0308 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00B4 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00B4 × 0020 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00B4 × 0308 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00B4 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00B4 × 0020 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00B4 × 0308 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00B4 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00B4 × 0020 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00B4 × 0308 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00B4 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00B4 × 0020 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00B4 × 0308 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00B4 × 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00B4 × 0020 ÷ 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00B4 × 0308 × 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00B4 × AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00B4 × 0020 ÷ AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00B4 × 0308 × AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00B4 × AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00B4 × 0020 ÷ AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00B4 × 0308 × AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00B4 × 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00B4 × 0020 ÷ 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00B4 × 0308 × 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00B4 × 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00B4 × 0020 ÷ 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00B4 × 0308 × 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00B4 × 231A ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] WATCH (ID) ÷ [0.3]
+× 00B4 × 0020 ÷ 231A ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 00B4 × 0308 × 231A ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] WATCH (ID) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 231A ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 00B4 × 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] ONE DOT LEADER (IN) ÷ [0.3]
+× 00B4 × 0020 ÷ 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00B4 × 0308 × 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] ONE DOT LEADER (IN) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00B4 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] COMMA (IS) ÷ [0.3]
+× 00B4 × 0020 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00B4 × 0308 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00B4 × 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00B4 × 0020 ÷ 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00B4 × 0308 × 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00B4 × 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00B4 × 0020 ÷ 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00B4 × 0308 × 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00B4 × 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00B4 × 0020 ÷ 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00B4 × 0308 × 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00B4 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00B4 × 0020 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00B4 × 0308 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00B4 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00B4 × 0020 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00B4 × 0308 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00B4 × 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00B4 × 0020 ÷ 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00B4 × 0308 × 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00B4 × 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] DIGIT ZERO (NU) ÷ [0.3]
+× 00B4 × 0020 ÷ 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00B4 × 0308 × 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] DIGIT ZERO (NU) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00B4 × 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00B4 × 0020 ÷ 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00B4 × 0308 × 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00B4 × 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] PERCENT SIGN (PO) ÷ [0.3]
+× 00B4 × 0020 ÷ 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00B4 × 0308 × 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] PERCENT SIGN (PO) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00B4 × 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] DOLLAR SIGN (PR) ÷ [0.3]
+× 00B4 × 0020 ÷ 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00B4 × 0308 × 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] DOLLAR SIGN (PR) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00B4 × 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 00B4 × 0020 ÷ 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00B4 × 0308 × 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00B4 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [0.3]
+× 00B4 × 0020 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00B4 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00B4 × 0020 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00B4 × 0308 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00B4 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00B4 × 0020 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00B4 × 0308 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00B4 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00B4 × 0020 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00B4 × 0308 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00B4 × 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00B4 × 0020 ÷ 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00B4 × 0308 × 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00B4 × 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00B4 × 0020 ÷ 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00B4 × 0308 × 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00B4 × 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00B4 × 0020 ÷ 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00B4 × 0308 × 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00B4 × 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00B4 × 0020 ÷ 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00B4 × 0308 × 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00B4 × 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00B4 × 0020 ÷ 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00B4 × 0308 × 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00B4 × 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00B4 × 0020 ÷ 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00B4 × 0308 × 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00B4 × 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00B4 × 0020 ÷ 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00B4 × 0308 × 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00B4 × 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00B4 × 0020 ÷ 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00B4 × 0308 × 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00B4 × 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00B4 × 0020 ÷ 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00B4 × 0308 × 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000B ÷ 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000B ÷ 0308 × 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000B ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] EM DASH (B2) ÷ [0.3]
+× 000B ÷ 0020 ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000B ÷ 0308 ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000B ÷ 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000B ÷ 0308 × 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000B ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000B ÷ 0020 ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000B ÷ 0308 ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000B ÷ 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000B ÷ 0020 × 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000B ÷ 0308 × 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000B ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000B ÷ 0020 ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000B ÷ 0308 ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000B ÷ 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000B ÷ 0020 × 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000B ÷ 0308 × 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000B ÷ 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000B ÷ 0020 × 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000B ÷ 0308 × 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000B ÷ 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000B ÷ 0020 × 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000B ÷ 0308 × 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000B ÷ 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000B ÷ 0020 × 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000B ÷ 0308 × 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000B ÷ 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000B ÷ 0308 × 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000B ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000B ÷ 0020 ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000B ÷ 0308 ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000B ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000B ÷ 0020 ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000B ÷ 0308 ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000B ÷ 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000B ÷ 0308 × 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000B ÷ 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000B ÷ 0020 ÷ 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000B ÷ 0308 × 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000B ÷ 231A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] WATCH (ID) ÷ [0.3]
+× 000B ÷ 0020 ÷ 231A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 000B ÷ 0308 ÷ 231A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 000B ÷ 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000B ÷ 0020 ÷ 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000B ÷ 0308 × 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000B ÷ 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMMA (IS) ÷ [0.3]
+× 000B ÷ 0020 × 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000B ÷ 0308 × 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000B ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000B ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000B ÷ 0020 ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000B ÷ 0308 ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000B ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000B ÷ 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000B ÷ 0020 × 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000B ÷ 0308 × 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000B ÷ 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000B ÷ 0020 × 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000B ÷ 0308 × 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000B ÷ 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000B ÷ 0020 ÷ 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000B ÷ 0308 × 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000B ÷ 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000B ÷ 0308 × 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000B ÷ 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000B ÷ 0308 × 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000B ÷ 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000B ÷ 0308 × 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000B ÷ 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000B ÷ 0308 × 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000B ÷ 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000B ÷ 0308 × 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000B ÷ 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [0.3]
+× 000B ÷ 0020 × 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000B ÷ 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SOLIDUS (SY) ÷ [0.3]
+× 000B ÷ 0020 × 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000B ÷ 0308 × 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000B ÷ 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] WORD JOINER (WJ) ÷ [0.3]
+× 000B ÷ 0020 × 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000B ÷ 0308 × 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000B ÷ 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000B ÷ 0020 × 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000B ÷ 0308 × 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000B ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000B ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000B ÷ 0020 ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000B ÷ 0308 ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000B ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000B ÷ 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000B ÷ 0308 × 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000B ÷ 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000B ÷ 0020 ÷ 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000B ÷ 0308 × 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000B ÷ 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000B ÷ 0308 × 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000B ÷ 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000B ÷ 0308 × 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000B ÷ 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000B ÷ 0308 × 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000B ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000B ÷ 0020 ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000B ÷ 0308 × 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× FFFC ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] NUMBER SIGN (AL) ÷ [0.3]
+× FFFC × 0020 ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× FFFC × 0308 ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] NUMBER SIGN (AL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× FFFC ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] EM DASH (B2) ÷ [0.3]
+× FFFC × 0020 ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× FFFC × 0308 ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] EM DASH (B2) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× FFFC ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× FFFC × 0020 ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× FFFC × 0308 ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× FFFC ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] ACUTE ACCENT (BB) ÷ [0.3]
+× FFFC × 0020 ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× FFFC × 0308 ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] ACUTE ACCENT (BB) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× FFFC × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× FFFC × 0020 × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× FFFC × 0308 × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× FFFC × 0308 × 0020 × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× FFFC ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× FFFC × 0020 ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× FFFC × 0308 ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× FFFC × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× FFFC × 0020 × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× FFFC × 0308 × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× FFFC × 0308 × 0020 × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× FFFC × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× FFFC × 0020 × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× FFFC × 0308 × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× FFFC × 0308 × 0020 × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× FFFC × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× FFFC × 0020 × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× FFFC × 0308 × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× FFFC × 0308 × 0020 × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× FFFC × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× FFFC × 0020 × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× FFFC × 0308 × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× FFFC × 0308 × 0020 × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× FFFC × 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× FFFC × 0020 ÷ 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× FFFC × 0308 × 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× FFFC ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× FFFC × 0020 ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× FFFC × 0308 ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× FFFC ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× FFFC × 0020 ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× FFFC × 0308 ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× FFFC ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× FFFC × 0020 ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× FFFC × 0308 ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× FFFC ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× FFFC × 0020 ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× FFFC × 0308 ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× FFFC ÷ 231A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] WATCH (ID) ÷ [0.3]
+× FFFC × 0020 ÷ 231A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× FFFC × 0308 ÷ 231A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] WATCH (ID) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 231A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× FFFC ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] ONE DOT LEADER (IN) ÷ [0.3]
+× FFFC × 0020 ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× FFFC × 0308 ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] ONE DOT LEADER (IN) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× FFFC × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] COMMA (IS) ÷ [0.3]
+× FFFC × 0020 × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× FFFC × 0308 × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× FFFC × 0308 × 0020 × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× FFFC ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× FFFC × 0020 ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× FFFC × 0308 ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× FFFC ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× FFFC × 0020 ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× FFFC × 0308 ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× FFFC ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× FFFC × 0020 ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× FFFC × 0308 ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× FFFC × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× FFFC × 0020 × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× FFFC × 0308 × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× FFFC × 0308 × 0020 × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× FFFC × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× FFFC × 0020 × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× FFFC × 0308 × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× FFFC × 0308 × 0020 × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× FFFC ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× FFFC × 0020 ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× FFFC × 0308 ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× FFFC ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] DIGIT ZERO (NU) ÷ [0.3]
+× FFFC × 0020 ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× FFFC × 0308 ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] DIGIT ZERO (NU) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× FFFC ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] LEFT PARENTHESIS (OP) ÷ [0.3]
+× FFFC × 0020 ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× FFFC × 0308 ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] LEFT PARENTHESIS (OP) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× FFFC ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] PERCENT SIGN (PO) ÷ [0.3]
+× FFFC × 0020 ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× FFFC × 0308 ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] PERCENT SIGN (PO) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× FFFC ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] DOLLAR SIGN (PR) ÷ [0.3]
+× FFFC × 0020 ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× FFFC × 0308 ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] DOLLAR SIGN (PR) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× FFFC × 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× FFFC × 0020 ÷ 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× FFFC × 0308 × 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× FFFC × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [0.3]
+× FFFC × 0020 × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× FFFC × 0308 × 0020 × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× FFFC × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× FFFC × 0020 × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× FFFC × 0308 × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× FFFC × 0308 × 0020 × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× FFFC × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× FFFC × 0020 × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× FFFC × 0308 × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× FFFC × 0308 × 0020 × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× FFFC × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× FFFC × 0020 × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× FFFC × 0308 × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× FFFC × 0308 × 0020 × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× FFFC ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× FFFC × 0020 ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× FFFC × 0308 ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× FFFC ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× FFFC × 0020 ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× FFFC × 0308 ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× FFFC ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× FFFC × 0020 ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× FFFC × 0308 ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× FFFC × 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× FFFC × 0020 ÷ 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× FFFC × 0308 × 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× FFFC × 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× FFFC × 0020 ÷ 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× FFFC × 0308 × 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× FFFC ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× FFFC × 0020 ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× FFFC × 0308 ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× FFFC ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× FFFC × 0020 ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× FFFC × 0308 ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× FFFC ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× FFFC × 0020 ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× FFFC × 0308 ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× FFFC ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× FFFC × 0020 ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× FFFC × 0308 ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 007D ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 007D × 0020 ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 007D × 0308 ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 007D ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 007D × 0020 ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 007D × 0308 ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 007D × 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 007D × 0020 ÷ 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 007D × 0308 × 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 007D ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 007D × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 007D × 0308 ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 007D × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 007D × 0020 × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 007D × 0308 × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 007D × 0308 × 0020 × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 007D ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 007D × 0020 ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 007D × 0308 ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 007D × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 007D × 0020 × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 007D × 0308 × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 007D × 0308 × 0020 × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 007D × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 007D × 0020 × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 007D × 0308 × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 007D × 0308 × 0020 × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 007D × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 007D × 0020 × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 007D × 0308 × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 007D × 0308 × 0020 × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 007D × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 007D × 0020 × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 007D × 0308 × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 007D × 0308 × 0020 × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 007D × 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 007D × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 007D × 0308 × 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 007D ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 007D × 0020 ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 007D × 0308 ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 007D ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 007D × 0020 ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 007D × 0308 ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 007D ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 007D × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 007D × 0308 ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 007D × 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 007D × 0020 ÷ 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 007D × 0308 × 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 007D ÷ 231A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 007D × 0020 ÷ 231A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 007D × 0308 ÷ 231A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 231A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 007D ÷ 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 007D × 0020 ÷ 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 007D × 0308 ÷ 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 007D × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] COMMA (IS) ÷ [0.3]
+× 007D × 0020 × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 007D × 0308 × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 007D × 0308 × 0020 × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 007D ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 007D × 0020 ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 007D × 0308 ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 007D ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 007D × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 007D × 0308 ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 007D ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 007D × 0020 ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 007D × 0308 ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 007D × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 007D × 0020 × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 007D × 0308 × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 007D × 0308 × 0020 × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 007D × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 007D × 0020 × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 007D × 0308 × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 007D × 0308 × 0020 × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 007D × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 007D × 0020 × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 007D × 0308 × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 007D × 0308 × 0020 × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 007D ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 007D × 0020 ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 007D × 0308 ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 007D ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 007D × 0020 ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 007D × 0308 ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 007D ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 007D × 0020 ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 007D × 0308 ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 007D ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 007D × 0020 ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 007D × 0308 ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 007D × 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 007D × 0020 ÷ 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 007D × 0308 × 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 007D × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [0.3]
+× 007D × 0020 × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 007D × 0308 × 0020 × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 007D × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 007D × 0020 × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 007D × 0308 × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 007D × 0308 × 0020 × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 007D × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 007D × 0020 × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 007D × 0308 × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 007D × 0308 × 0020 × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 007D × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 007D × 0020 × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 007D × 0308 × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 007D × 0308 × 0020 × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 007D ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 007D × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 007D × 0308 ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 007D ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 007D × 0020 ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 007D × 0308 ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 007D ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 007D × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 007D × 0308 ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 007D × 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 007D × 0020 ÷ 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 007D × 0308 × 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 007D × 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 007D × 0020 ÷ 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 007D × 0308 × 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 007D ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 007D × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 007D × 0308 ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 007D ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 007D × 0020 ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 007D × 0308 ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 007D ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 007D × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 007D × 0308 ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 007D × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 007D × 0020 × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 007D × 0308 × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 007D × 0308 × 0020 × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0029 × 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0029 × 0020 ÷ 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0029 × 0308 × 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0029 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0029 × 0020 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0029 × 0308 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0029 × 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0029 × 0020 ÷ 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0029 × 0308 × 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0029 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0029 × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0029 × 0308 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0029 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0029 × 0020 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0029 × 0308 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0029 × 0308 × 0020 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0029 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0029 × 0020 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0029 × 0308 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0029 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0029 × 0020 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0029 × 0308 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0029 × 0308 × 0020 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0029 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0029 × 0020 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0029 × 0308 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0029 × 0308 × 0020 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0029 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0029 × 0020 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0029 × 0308 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0029 × 0308 × 0020 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0029 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0029 × 0020 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0029 × 0308 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0029 × 0308 × 0020 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0029 × 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0029 × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0029 × 0308 × 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0029 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0029 × 0020 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0029 × 0308 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0029 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0029 × 0020 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0029 × 0308 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0029 × 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0029 × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0029 × 0308 × 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0029 × 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0029 × 0020 ÷ 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0029 × 0308 × 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0029 ÷ 231A ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0029 × 0020 ÷ 231A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0029 × 0308 ÷ 231A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 231A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0029 ÷ 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0029 × 0020 ÷ 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0029 × 0308 ÷ 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0029 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0029 × 0020 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0029 × 0308 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0029 × 0308 × 0020 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0029 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0029 × 0020 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0029 × 0308 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0029 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0029 × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0029 × 0308 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0029 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0029 × 0020 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0029 × 0308 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0029 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0029 × 0020 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0029 × 0308 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0029 × 0308 × 0020 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0029 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0029 × 0020 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0029 × 0308 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0029 × 0308 × 0020 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0029 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0029 × 0020 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0029 × 0308 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0029 × 0308 × 0020 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0029 × 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0029 × 0020 ÷ 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0029 × 0308 × 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0029 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0029 × 0020 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0029 × 0308 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0029 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0029 × 0020 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0029 × 0308 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0029 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0029 × 0020 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0029 × 0308 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0029 × 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0029 × 0020 ÷ 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0029 × 0308 × 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0029 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0029 × 0020 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0029 × 0308 × 0020 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0029 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0029 × 0020 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0029 × 0308 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0029 × 0308 × 0020 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0029 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0029 × 0020 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0029 × 0308 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0029 × 0308 × 0020 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0029 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0029 × 0020 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0029 × 0308 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0029 × 0308 × 0020 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0029 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0029 × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0029 × 0308 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0029 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0029 × 0020 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0029 × 0308 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0029 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0029 × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0029 × 0308 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0029 × 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0029 × 0020 ÷ 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0029 × 0308 × 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0029 × 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0029 × 0020 ÷ 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0029 × 0308 × 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0029 × 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0029 × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0029 × 0308 × 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0029 × 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0029 × 0020 ÷ 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0029 × 0308 × 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0029 × 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0029 × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0029 × 0308 × 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0029 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0029 × 0020 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0029 × 0308 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0029 × 0308 × 0020 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D ÷ 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] NUMBER SIGN (AL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000D ÷ 0308 × 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000D ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] EM DASH (B2) ÷ [0.3]
+× 000D ÷ 0020 ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000D ÷ 0308 ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000D ÷ 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000D ÷ 0308 × 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000D ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 000D ÷ 0020 ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000D ÷ 0308 ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000D ÷ 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <LINE TABULATION> (BK) ÷ [0.3]
+× 000D ÷ 0020 × 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000D ÷ 0308 × 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000D ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000D ÷ 0020 ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000D ÷ 0308 ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000D ÷ 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000D ÷ 0020 × 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000D ÷ 0308 × 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000D ÷ 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000D ÷ 0020 × 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000D ÷ 0308 × 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000D ÷ 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000D ÷ 0020 × 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000D ÷ 0308 × 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000D ÷ 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000D ÷ 0020 × 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000D ÷ 0308 × 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000D ÷ 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000D ÷ 0308 × 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000D ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000D ÷ 0020 ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000D ÷ 0308 ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000D ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000D ÷ 0020 ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000D ÷ 0308 ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000D ÷ 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000D ÷ 0308 × 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000D ÷ 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000D ÷ 0020 ÷ 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000D ÷ 0308 × 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000D ÷ 231A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] WATCH (ID) ÷ [0.3]
+× 000D ÷ 0020 ÷ 231A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 000D ÷ 0308 ÷ 231A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 000D ÷ 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 000D ÷ 0020 ÷ 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000D ÷ 0308 × 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000D ÷ 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMMA (IS) ÷ [0.3]
+× 000D ÷ 0020 × 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000D ÷ 0308 × 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000D ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000D ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000D ÷ 0020 ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000D ÷ 0308 ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000D ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000D × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) × [5.01] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000D ÷ 0020 × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000D ÷ 0308 × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000D ÷ 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000D ÷ 0020 × 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000D ÷ 0308 × 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000D ÷ 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000D ÷ 0020 ÷ 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000D ÷ 0308 × 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000D ÷ 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] DIGIT ZERO (NU) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000D ÷ 0308 × 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000D ÷ 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000D ÷ 0308 × 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000D ÷ 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] PERCENT SIGN (PO) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000D ÷ 0308 × 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000D ÷ 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000D ÷ 0308 × 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000D ÷ 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] QUOTATION MARK (QU) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000D ÷ 0308 × 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000D ÷ 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [0.3]
+× 000D ÷ 0020 × 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000D ÷ 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SOLIDUS (SY) ÷ [0.3]
+× 000D ÷ 0020 × 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000D ÷ 0308 × 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000D ÷ 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] WORD JOINER (WJ) ÷ [0.3]
+× 000D ÷ 0020 × 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000D ÷ 0308 × 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000D ÷ 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000D ÷ 0020 × 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000D ÷ 0308 × 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000D ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000D ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000D ÷ 0020 ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000D ÷ 0308 ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000D ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000D ÷ 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000D ÷ 0308 × 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000D ÷ 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000D ÷ 0020 ÷ 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000D ÷ 0308 × 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000D ÷ 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000D ÷ 0308 × 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000D ÷ 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000D ÷ 0308 × 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000D ÷ 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000D ÷ 0308 × 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000D ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D ÷ 0020 ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D ÷ 0308 × 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0021 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0021 × 0020 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0021 × 0308 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0021 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0021 × 0020 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0021 × 0308 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0021 × 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0021 × 0020 ÷ 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0021 × 0308 × 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0021 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0021 × 0020 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0021 × 0308 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0021 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0021 × 0020 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0021 × 0308 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0021 × 0308 × 0020 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0021 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0021 × 0020 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0021 × 0308 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0021 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0021 × 0020 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0021 × 0308 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0021 × 0308 × 0020 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0021 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0021 × 0020 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0021 × 0308 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0021 × 0308 × 0020 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0021 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0021 × 0020 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0021 × 0308 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0021 × 0308 × 0020 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0021 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0021 × 0020 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0021 × 0308 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0021 × 0308 × 0020 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0021 × 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0021 × 0020 ÷ 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0021 × 0308 × 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0021 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0021 × 0020 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0021 × 0308 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0021 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0021 × 0020 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0021 × 0308 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0021 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0021 × 0020 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0021 × 0308 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0021 × 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0021 × 0020 ÷ 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0021 × 0308 × 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0021 ÷ 231A ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0021 × 0020 ÷ 231A ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0021 × 0308 ÷ 231A ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 231A ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0021 × 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [22.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 0021 × 0020 ÷ 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0021 × 0308 × 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0021 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] COMMA (IS) ÷ [0.3]
+× 0021 × 0020 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0021 × 0308 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0021 × 0308 × 0020 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0021 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0021 × 0020 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0021 × 0308 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0021 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0021 × 0020 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0021 × 0308 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0021 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0021 × 0020 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0021 × 0308 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0021 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0021 × 0020 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0021 × 0308 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0021 × 0308 × 0020 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0021 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0021 × 0020 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0021 × 0308 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0021 × 0308 × 0020 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0021 × 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0021 × 0020 ÷ 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0021 × 0308 × 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0021 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0021 × 0020 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0021 × 0308 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0021 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0021 × 0020 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0021 × 0308 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0021 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0021 × 0020 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0021 × 0308 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0021 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0021 × 0020 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0021 × 0308 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0021 × 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0021 × 0020 ÷ 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0021 × 0308 × 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0021 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [0.3]
+× 0021 × 0020 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0021 × 0308 × 0020 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0021 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0021 × 0020 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0021 × 0308 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0021 × 0308 × 0020 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0021 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0021 × 0020 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0021 × 0308 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0021 × 0308 × 0020 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0021 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0021 × 0020 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0021 × 0308 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0021 × 0308 × 0020 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0021 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0021 × 0020 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0021 × 0308 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0021 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0021 × 0020 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0021 × 0308 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0021 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0021 × 0020 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0021 × 0308 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0021 × 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0021 × 0020 ÷ 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0021 × 0308 × 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0021 × 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0021 × 0020 ÷ 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0021 × 0308 × 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0021 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0021 × 0020 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0021 × 0308 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0021 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0021 × 0020 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0021 × 0308 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0021 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0021 × 0020 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0021 × 0308 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0021 × 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0021 × 0020 ÷ 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0021 × 0308 × 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A0 × 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A0 × 0020 ÷ 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A0 × 0308 × 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A0 × 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] EM DASH (B2) ÷ [0.3]
+× 00A0 × 0020 ÷ 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00A0 × 0308 × 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] EM DASH (B2) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00A0 × 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A0 × 0020 ÷ 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A0 × 0308 × 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A0 × 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A0 × 0020 ÷ 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A0 × 0308 × 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A0 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A0 × 0020 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A0 × 0308 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A0 × FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A0 × 0020 ÷ FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A0 × 0308 × FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A0 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A0 × 0020 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A0 × 0308 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A0 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00A0 × 0020 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00A0 × 0308 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00A0 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A0 × 0020 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A0 × 0308 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A0 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A0 × 0020 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A0 × 0308 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A0 × 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A0 × 0020 ÷ 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A0 × 0308 × 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A0 × AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A0 × 0020 ÷ AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A0 × 0308 × AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A0 × AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A0 × 0020 ÷ AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A0 × 0308 × AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A0 × 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A0 × 0020 ÷ 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A0 × 0308 × 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A0 × 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A0 × 0020 ÷ 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A0 × 0308 × 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A0 × 231A ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] WATCH (ID) ÷ [0.3]
+× 00A0 × 0020 ÷ 231A ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 00A0 × 0308 × 231A ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] WATCH (ID) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 231A ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 00A0 × 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A0 × 0020 ÷ 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A0 × 0308 × 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A0 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] COMMA (IS) ÷ [0.3]
+× 00A0 × 0020 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00A0 × 0308 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] COMMA (IS) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00A0 × 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A0 × 0020 ÷ 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A0 × 0308 × 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A0 × 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A0 × 0020 ÷ 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A0 × 0308 × 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A0 × 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A0 × 0020 ÷ 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A0 × 0308 × 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A0 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A0 × 0020 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A0 × 0308 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A0 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A0 × 0020 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A0 × 0308 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A0 × 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A0 × 0020 ÷ 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A0 × 0308 × 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A0 × 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A0 × 0020 ÷ 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A0 × 0308 × 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A0 × 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00A0 × 0020 ÷ 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00A0 × 0308 × 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00A0 × 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A0 × 0020 ÷ 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A0 × 0308 × 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A0 × 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A0 × 0020 ÷ 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A0 × 0308 × 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A0 × 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A0 × 0020 ÷ 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A0 × 0308 × 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A0 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A0 × 0020 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A0 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] SOLIDUS (SY) ÷ [0.3]
+× 00A0 × 0020 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00A0 × 0308 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] SOLIDUS (SY) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00A0 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A0 × 0020 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A0 × 0308 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A0 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A0 × 0020 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A0 × 0308 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A0 × 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A0 × 0020 ÷ 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A0 × 0308 × 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A0 × 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A0 × 0020 ÷ 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A0 × 0308 × 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A0 × 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A0 × 0020 ÷ 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A0 × 0308 × 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A0 × 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A0 × 0020 ÷ 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A0 × 0308 × 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A0 × 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A0 × 0020 ÷ 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A0 × 0308 × 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A0 × 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A0 × 0020 ÷ 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A0 × 0308 × 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A0 × 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A0 × 0020 ÷ 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A0 × 0308 × 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A0 × 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A0 × 0020 ÷ 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A0 × 0308 × 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A0 × 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A0 × 0020 ÷ 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A0 × 0308 × 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC00 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC00 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC00 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC00 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× AC00 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× AC00 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× AC00 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC00 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC00 × 0308 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC00 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC00 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC00 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC00 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC00 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC00 × 0308 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC00 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC00 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC00 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC00 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC00 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC00 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC00 × 0308 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC00 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC00 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× AC00 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× AC00 × 0308 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× AC00 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× AC00 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC00 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC00 × 0308 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC00 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC00 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC00 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC00 × 0308 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC00 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC00 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC00 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC00 × 0308 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC00 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC00 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC00 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC00 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC00 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC00 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC00 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC00 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC00 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC00 × 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC00 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC00 × 0308 × 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC00 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× AC00 × 0020 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× AC00 × 0308 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× AC00 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
+× AC00 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC00 × 0308 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC00 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] COMMA (IS) ÷ [0.3]
+× AC00 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× AC00 × 0308 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× AC00 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× AC00 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC00 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC00 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC00 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC00 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC00 × 0308 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC00 × 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC00 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC00 × 0308 × 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC00 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC00 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC00 × 0308 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC00 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC00 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC00 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC00 × 0308 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC00 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC00 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC00 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC00 × 0308 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC00 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC00 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC00 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC00 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× AC00 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× AC00 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× AC00 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
+× AC00 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× AC00 × 0308 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× AC00 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC00 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC00 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC00 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× AC00 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× AC00 × 0308 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× AC00 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [0.3]
+× AC00 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× AC00 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× AC00 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC00 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC00 × 0308 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× AC00 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC00 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC00 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC00 × 0308 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC00 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC00 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC00 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC00 × 0308 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC00 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC00 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC00 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC00 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC00 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC00 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC00 × 0308 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC00 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC00 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC00 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC00 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC00 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC00 × 0308 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC00 × 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC00 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC00 × 0308 × 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC00 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC00 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC00 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC00 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC00 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC00 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC00 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC00 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC00 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC00 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC00 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC00 × 0308 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC01 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC01 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC01 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC01 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× AC01 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× AC01 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× AC01 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC01 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC01 × 0308 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC01 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC01 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC01 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC01 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC01 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC01 × 0308 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC01 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC01 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC01 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC01 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC01 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC01 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC01 × 0308 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC01 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC01 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× AC01 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× AC01 × 0308 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× AC01 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× AC01 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC01 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC01 × 0308 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC01 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC01 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC01 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC01 × 0308 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC01 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC01 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC01 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC01 × 0308 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC01 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC01 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC01 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC01 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC01 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC01 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC01 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC01 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC01 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC01 × 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC01 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC01 × 0308 × 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC01 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× AC01 × 0020 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× AC01 × 0308 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× AC01 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
+× AC01 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC01 × 0308 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC01 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] COMMA (IS) ÷ [0.3]
+× AC01 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× AC01 × 0308 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× AC01 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× AC01 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC01 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC01 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC01 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC01 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC01 × 0308 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC01 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC01 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC01 × 0308 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC01 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC01 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC01 × 0308 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC01 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC01 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC01 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC01 × 0308 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC01 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC01 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC01 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC01 × 0308 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC01 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC01 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC01 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC01 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× AC01 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× AC01 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× AC01 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
+× AC01 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× AC01 × 0308 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× AC01 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC01 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC01 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC01 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× AC01 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× AC01 × 0308 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× AC01 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [0.3]
+× AC01 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× AC01 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× AC01 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC01 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC01 × 0308 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× AC01 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC01 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC01 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC01 × 0308 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC01 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC01 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC01 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC01 × 0308 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC01 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC01 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC01 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC01 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC01 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC01 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC01 × 0308 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC01 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC01 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC01 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC01 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC01 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC01 × 0308 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC01 × 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC01 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC01 × 0308 × 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC01 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC01 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC01 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC01 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC01 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC01 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC01 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC01 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC01 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC01 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC01 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC01 × 0308 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 05D0 × 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 05D0 × 0020 ÷ 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 05D0 × 0308 × 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 05D0 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 05D0 × 0020 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 05D0 × 0308 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 05D0 × 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 05D0 × 0020 ÷ 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 05D0 × 0308 × 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 05D0 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 05D0 × 0020 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 05D0 × 0308 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 05D0 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 05D0 × 0020 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 05D0 × 0308 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 05D0 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 05D0 × 0020 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 05D0 × 0308 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 05D0 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 05D0 × 0020 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 05D0 × 0308 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 05D0 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 05D0 × 0020 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 05D0 × 0308 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 05D0 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 05D0 × 0020 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 05D0 × 0308 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 05D0 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 05D0 × 0020 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 05D0 × 0308 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 05D0 × 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 05D0 × 0020 ÷ 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 05D0 × 0308 × 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 05D0 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 05D0 × 0020 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 05D0 × 0308 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 05D0 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 05D0 × 0020 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 05D0 × 0308 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 05D0 × 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 05D0 × 0020 ÷ 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 05D0 × 0308 × 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 05D0 × 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 05D0 × 0020 ÷ 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 05D0 × 0308 × 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 05D0 ÷ 231A ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 05D0 × 0020 ÷ 231A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 05D0 × 0308 ÷ 231A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 05D0 × 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 05D0 × 0020 ÷ 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 05D0 × 0308 × 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 05D0 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] COMMA (IS) ÷ [0.3]
+× 05D0 × 0020 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 05D0 × 0308 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 05D0 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 05D0 × 0020 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 05D0 × 0308 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 05D0 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 05D0 × 0020 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 05D0 × 0308 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 05D0 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 05D0 × 0020 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 05D0 × 0308 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 05D0 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 05D0 × 0020 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 05D0 × 0308 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 05D0 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 05D0 × 0020 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 05D0 × 0308 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 05D0 × 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 05D0 × 0020 ÷ 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 05D0 × 0308 × 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 05D0 × 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 05D0 × 0020 ÷ 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 05D0 × 0308 × 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 05D0 × 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 05D0 × 0020 ÷ 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 05D0 × 0308 × 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 05D0 × 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 05D0 × 0020 ÷ 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 05D0 × 0308 × 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 05D0 × 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 05D0 × 0020 ÷ 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 05D0 × 0308 × 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 05D0 × 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 05D0 × 0020 ÷ 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 05D0 × 0308 × 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 05D0 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [0.3]
+× 05D0 × 0020 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 05D0 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 05D0 × 0020 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 05D0 × 0308 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 05D0 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 05D0 × 0020 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 05D0 × 0308 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 05D0 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 05D0 × 0020 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 05D0 × 0308 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 05D0 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 05D0 × 0020 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 05D0 × 0308 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 05D0 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 05D0 × 0020 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 05D0 × 0308 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 05D0 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 05D0 × 0020 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 05D0 × 0308 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 05D0 × 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 05D0 × 0020 ÷ 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 05D0 × 0308 × 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 05D0 × 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 05D0 × 0020 ÷ 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 05D0 × 0308 × 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 05D0 × 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 05D0 × 0020 ÷ 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 05D0 × 0308 × 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 05D0 × 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 05D0 × 0020 ÷ 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 05D0 × 0308 × 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 05D0 × 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 05D0 × 0020 ÷ 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 05D0 × 0308 × 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 05D0 × 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 05D0 × 0020 ÷ 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 05D0 × 0308 × 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002D ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002D × 0020 ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002D × 0308 ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002D ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002D × 0020 ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002D × 0308 ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002D × 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002D × 0020 ÷ 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002D × 0308 × 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002D ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002D × 0020 ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002D × 0308 ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002D × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002D × 0020 × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002D × 0308 × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002D × 0308 × 0020 × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002D ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002D × 0020 ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002D × 0308 ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002D × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002D × 0020 × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002D × 0308 × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002D × 0308 × 0020 × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002D × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002D × 0020 × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002D × 0308 × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002D × 0308 × 0020 × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002D × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002D × 0020 × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002D × 0308 × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002D × 0308 × 0020 × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002D × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002D × 0020 × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002D × 0308 × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002D × 0308 × 0020 × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002D ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002D × 0020 ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002D × 0308 ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002D ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002D × 0020 ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002D × 0308 ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002D ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002D × 0020 ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002D × 0308 ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002D ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002D × 0020 ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002D × 0308 ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002D × 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002D × 0020 ÷ 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002D × 0308 × 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002D ÷ 231A ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 002D × 0020 ÷ 231A ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 002D × 0308 ÷ 231A ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 231A ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 002D ÷ 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002D × 0020 ÷ 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002D × 0308 ÷ 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002D × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] COMMA (IS) ÷ [0.3]
+× 002D × 0020 × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002D × 0308 × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 002D × 0308 × 0020 × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002D ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002D × 0020 ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002D × 0308 ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002D ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002D × 0020 ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002D × 0308 ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002D ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002D × 0020 ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002D × 0308 ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002D × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002D × 0020 × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002D × 0308 × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002D × 0308 × 0020 × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002D × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002D × 0020 × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002D × 0308 × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002D × 0308 × 0020 × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002D × 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002D × 0020 ÷ 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002D × 0308 × 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002D × 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [25.02] DIGIT ZERO (NU) ÷ [0.3]
+× 002D × 0020 ÷ 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002D × 0308 × 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.02] DIGIT ZERO (NU) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002D ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002D × 0020 ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002D × 0308 ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002D ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002D × 0020 ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002D × 0308 ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002D ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002D × 0020 ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002D × 0308 ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002D × 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002D × 0020 ÷ 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002D × 0308 × 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002D × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [0.3]
+× 002D × 0020 × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 002D × 0308 × 0020 × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002D × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002D × 0020 × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002D × 0308 × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 002D × 0308 × 0020 × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002D × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002D × 0020 × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002D × 0308 × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002D × 0308 × 0020 × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002D × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002D × 0020 × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002D × 0308 × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002D × 0308 × 0020 × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002D ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002D × 0020 ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002D × 0308 ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002D ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002D × 0020 ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002D × 0308 ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002D ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002D × 0020 ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002D × 0308 ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002D × 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002D × 0020 ÷ 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002D × 0308 × 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002D × 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002D × 0020 ÷ 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002D × 0308 × 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002D ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002D × 0020 ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002D × 0308 ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002D ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002D × 0020 ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002D × 0308 ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002D ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002D × 0020 ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002D × 0308 ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002D × 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002D × 0020 ÷ 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002D × 0308 × 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 231A ÷ 0023 ÷ # × [0.3] WATCH (ID) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 231A × 0020 ÷ 0023 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 231A × 0308 ÷ 0023 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 0023 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 231A ÷ 2014 ÷ # × [0.3] WATCH (ID) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 231A × 0020 ÷ 2014 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 231A × 0308 ÷ 2014 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 2014 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 231A × 0009 ÷ # × [0.3] WATCH (ID) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 231A × 0020 ÷ 0009 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 231A × 0308 × 0009 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 0009 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 231A ÷ 00B4 ÷ # × [0.3] WATCH (ID) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 231A × 0020 ÷ 00B4 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 231A × 0308 ÷ 00B4 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 231A × 000B ÷ # × [0.3] WATCH (ID) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 231A × 0020 × 000B ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 231A × 0308 × 000B ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 231A × 0308 × 0020 × 000B ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 231A ÷ FFFC ÷ # × [0.3] WATCH (ID) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 231A × 0020 ÷ FFFC ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 231A × 0308 ÷ FFFC ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ FFFC ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 231A × 007D ÷ # × [0.3] WATCH (ID) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 231A × 0020 × 007D ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 231A × 0308 × 007D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 231A × 0308 × 0020 × 007D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 231A × 0029 ÷ # × [0.3] WATCH (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 231A × 0020 × 0029 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 231A × 0308 × 0029 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 231A × 0308 × 0020 × 0029 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 231A × 000D ÷ # × [0.3] WATCH (ID) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 231A × 0020 × 000D ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 231A × 0308 × 000D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 231A × 0308 × 0020 × 000D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 231A × 0021 ÷ # × [0.3] WATCH (ID) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 231A × 0020 × 0021 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 231A × 0308 × 0021 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 231A × 0308 × 0020 × 0021 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 231A × 00A0 ÷ # × [0.3] WATCH (ID) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 231A × 0020 ÷ 00A0 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 231A × 0308 × 00A0 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 231A ÷ AC00 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 231A × 0020 ÷ AC00 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 231A × 0308 ÷ AC00 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ AC00 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 231A ÷ AC01 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 231A × 0020 ÷ AC01 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 231A × 0308 ÷ AC01 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ AC01 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 231A ÷ 05D0 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 231A × 0020 ÷ 05D0 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 231A × 0308 ÷ 05D0 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 231A × 002D ÷ # × [0.3] WATCH (ID) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 231A × 0020 ÷ 002D ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 231A × 0308 × 002D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 002D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 231A ÷ 231A ÷ # × [0.3] WATCH (ID) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 231A × 0020 ÷ 231A ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 231A × 0308 ÷ 231A ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 231A ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 231A × 2024 ÷ # × [0.3] WATCH (ID) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
+× 231A × 0020 ÷ 2024 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 231A × 0308 × 2024 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 2024 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 231A × 002C ÷ # × [0.3] WATCH (ID) × [13.02] COMMA (IS) ÷ [0.3]
+× 231A × 0020 × 002C ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 231A × 0308 × 002C ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 231A × 0308 × 0020 × 002C ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 231A ÷ 1100 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 231A × 0020 ÷ 1100 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 231A × 0308 ÷ 1100 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 1100 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 231A ÷ 11A8 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 231A × 0020 ÷ 11A8 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 231A × 0308 ÷ 11A8 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 231A ÷ 1160 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 231A × 0020 ÷ 1160 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 231A × 0308 ÷ 1160 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 1160 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 231A × 000A ÷ # × [0.3] WATCH (ID) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 231A × 0020 × 000A ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 231A × 0308 × 000A ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 231A × 0308 × 0020 × 000A ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 231A × 0085 ÷ # × [0.3] WATCH (ID) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 231A × 0020 × 0085 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 231A × 0308 × 0085 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 231A × 0308 × 0020 × 0085 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 231A × 17D6 ÷ # × [0.3] WATCH (ID) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 231A × 0020 ÷ 17D6 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 231A × 0308 × 17D6 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 231A ÷ 0030 ÷ # × [0.3] WATCH (ID) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 231A × 0020 ÷ 0030 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 231A × 0308 ÷ 0030 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 0030 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 231A ÷ 0028 ÷ # × [0.3] WATCH (ID) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 231A × 0020 ÷ 0028 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 231A × 0308 ÷ 0028 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 0028 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 231A × 0025 ÷ # × [0.3] WATCH (ID) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 231A × 0020 ÷ 0025 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 231A × 0308 × 0025 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 0025 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 231A ÷ 0024 ÷ # × [0.3] WATCH (ID) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 231A × 0020 ÷ 0024 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 231A × 0308 ÷ 0024 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 0024 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 231A × 0022 ÷ # × [0.3] WATCH (ID) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 231A × 0020 ÷ 0022 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 231A × 0308 × 0022 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 0022 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 231A × 0020 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [0.3]
+× 231A × 0020 × 0020 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 231A × 0308 × 0020 × 0020 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 231A × 002F ÷ # × [0.3] WATCH (ID) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 231A × 0020 × 002F ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 231A × 0308 × 002F ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 231A × 0308 × 0020 × 002F ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 231A × 2060 ÷ # × [0.3] WATCH (ID) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 231A × 0020 × 2060 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 231A × 0308 × 2060 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 231A × 0308 × 0020 × 2060 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 231A × 200B ÷ # × [0.3] WATCH (ID) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 231A × 0020 × 200B ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 231A × 0308 × 200B ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 231A × 0308 × 0020 × 200B ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 231A ÷ 1F1E6 ÷ # × [0.3] WATCH (ID) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 231A × 0020 ÷ 1F1E6 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 231A × 0308 ÷ 1F1E6 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 231A ÷ 261D ÷ # × [0.3] WATCH (ID) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 231A × 0020 ÷ 261D ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 231A × 0308 ÷ 261D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 261D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 231A ÷ 1F3FB ÷ # × [0.3] WATCH (ID) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 231A × 0020 ÷ 1F3FB ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 231A × 0308 ÷ 1F3FB ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 231A × 0001 ÷ # × [0.3] WATCH (ID) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 231A × 0020 ÷ 0001 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 231A × 0308 × 0001 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 0001 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 231A × 200D ÷ # × [0.3] WATCH (ID) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 231A × 0020 ÷ 200D ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 231A × 0308 × 200D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 200D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 231A ÷ 00A7 ÷ # × [0.3] WATCH (ID) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 231A × 0020 ÷ 00A7 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 231A × 0308 ÷ 00A7 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 231A ÷ 50005 ÷ # × [0.3] WATCH (ID) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 231A × 0020 ÷ 50005 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 231A × 0308 ÷ 50005 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 50005 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 231A ÷ 0E01 ÷ # × [0.3] WATCH (ID) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 231A × 0020 ÷ 0E01 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 231A × 0308 ÷ 0E01 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 231A × 3041 ÷ # × [0.3] WATCH (ID) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 231A × 0020 ÷ 3041 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 231A × 0308 × 3041 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 231A × 0308 × 0020 ÷ 3041 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2024 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2024 × 0020 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2024 × 0308 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2024 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 2024 × 0020 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 2024 × 0308 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 2024 × 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2024 × 0020 ÷ 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2024 × 0308 × 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2024 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2024 × 0020 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2024 × 0308 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2024 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2024 × 0020 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2024 × 0308 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2024 × 0308 × 0020 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2024 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2024 × 0020 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2024 × 0308 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2024 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2024 × 0020 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2024 × 0308 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2024 × 0308 × 0020 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2024 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2024 × 0020 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2024 × 0308 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2024 × 0308 × 0020 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2024 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2024 × 0020 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2024 × 0308 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2024 × 0308 × 0020 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2024 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2024 × 0020 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2024 × 0308 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2024 × 0308 × 0020 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2024 × 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2024 × 0020 ÷ 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2024 × 0308 × 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2024 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2024 × 0020 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2024 × 0308 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2024 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2024 × 0020 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2024 × 0308 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2024 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2024 × 0020 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2024 × 0308 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2024 × 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2024 × 0020 ÷ 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2024 × 0308 × 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2024 ÷ 231A ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 2024 × 0020 ÷ 231A ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 2024 × 0308 ÷ 231A ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 231A ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 2024 × 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [22.04] ONE DOT LEADER (IN) ÷ [0.3]
+× 2024 × 0020 ÷ 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2024 × 0308 × 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.04] ONE DOT LEADER (IN) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2024 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] COMMA (IS) ÷ [0.3]
+× 2024 × 0020 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2024 × 0308 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 2024 × 0308 × 0020 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2024 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2024 × 0020 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2024 × 0308 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2024 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2024 × 0020 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2024 × 0308 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2024 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2024 × 0020 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2024 × 0308 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2024 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2024 × 0020 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2024 × 0308 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2024 × 0308 × 0020 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2024 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2024 × 0020 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2024 × 0308 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2024 × 0308 × 0020 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2024 × 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2024 × 0020 ÷ 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2024 × 0308 × 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2024 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2024 × 0020 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2024 × 0308 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2024 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2024 × 0020 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2024 × 0308 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2024 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2024 × 0020 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2024 × 0308 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2024 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2024 × 0020 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2024 × 0308 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2024 × 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 2024 × 0020 ÷ 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2024 × 0308 × 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2024 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [0.3]
+× 2024 × 0020 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 2024 × 0308 × 0020 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2024 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2024 × 0020 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2024 × 0308 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 2024 × 0308 × 0020 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2024 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2024 × 0020 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2024 × 0308 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2024 × 0308 × 0020 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2024 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2024 × 0020 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2024 × 0308 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2024 × 0308 × 0020 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2024 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2024 × 0020 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2024 × 0308 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2024 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2024 × 0020 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2024 × 0308 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2024 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2024 × 0020 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2024 × 0308 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2024 × 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2024 × 0020 ÷ 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2024 × 0308 × 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2024 × 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2024 × 0020 ÷ 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2024 × 0308 × 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2024 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2024 × 0020 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2024 × 0308 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2024 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2024 × 0020 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2024 × 0308 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2024 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2024 × 0020 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2024 × 0308 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2024 × 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2024 × 0020 ÷ 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2024 × 0308 × 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002C × 0023 ÷ # × [0.3] COMMA (IS) × [29.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002C × 0020 ÷ 0023 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002C × 0308 × 0023 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0023 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002C ÷ 2014 ÷ # × [0.3] COMMA (IS) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002C × 0020 ÷ 2014 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002C × 0308 ÷ 2014 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 2014 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002C × 0009 ÷ # × [0.3] COMMA (IS) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002C × 0020 ÷ 0009 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002C × 0308 × 0009 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0009 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002C ÷ 00B4 ÷ # × [0.3] COMMA (IS) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002C × 0020 ÷ 00B4 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002C × 0308 ÷ 00B4 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002C × 000B ÷ # × [0.3] COMMA (IS) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002C × 0020 × 000B ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002C × 0308 × 000B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002C × 0308 × 0020 × 000B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002C ÷ FFFC ÷ # × [0.3] COMMA (IS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002C × 0020 ÷ FFFC ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002C × 0308 ÷ FFFC ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ FFFC ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002C × 007D ÷ # × [0.3] COMMA (IS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002C × 0020 × 007D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002C × 0308 × 007D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002C × 0308 × 0020 × 007D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002C × 0029 ÷ # × [0.3] COMMA (IS) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002C × 0020 × 0029 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002C × 0308 × 0029 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002C × 0308 × 0020 × 0029 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002C × 000D ÷ # × [0.3] COMMA (IS) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002C × 0020 × 000D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002C × 0308 × 000D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002C × 0308 × 0020 × 000D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002C × 0021 ÷ # × [0.3] COMMA (IS) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002C × 0020 × 0021 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002C × 0308 × 0021 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002C × 0308 × 0020 × 0021 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002C × 00A0 ÷ # × [0.3] COMMA (IS) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002C × 0020 ÷ 00A0 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002C × 0308 × 00A0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002C ÷ AC00 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002C × 0020 ÷ AC00 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002C × 0308 ÷ AC00 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ AC00 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002C ÷ AC01 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002C × 0020 ÷ AC01 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002C × 0308 ÷ AC01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ AC01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002C × 05D0 ÷ # × [0.3] COMMA (IS) × [29.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002C × 0020 ÷ 05D0 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002C × 0308 × 05D0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002C × 002D ÷ # × [0.3] COMMA (IS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002C × 0020 ÷ 002D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002C × 0308 × 002D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 002D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002C ÷ 231A ÷ # × [0.3] COMMA (IS) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 002C × 0020 ÷ 231A ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 002C × 0308 ÷ 231A ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 231A ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 002C ÷ 2024 ÷ # × [0.3] COMMA (IS) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002C × 0020 ÷ 2024 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002C × 0308 ÷ 2024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 2024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002C × 002C ÷ # × [0.3] COMMA (IS) × [13.02] COMMA (IS) ÷ [0.3]
+× 002C × 0020 × 002C ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002C × 0308 × 002C ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 002C × 0308 × 0020 × 002C ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002C ÷ 1100 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002C × 0020 ÷ 1100 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002C × 0308 ÷ 1100 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1100 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002C ÷ 11A8 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002C × 0020 ÷ 11A8 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002C × 0308 ÷ 11A8 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002C ÷ 1160 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002C × 0020 ÷ 1160 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002C × 0308 ÷ 1160 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1160 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002C × 000A ÷ # × [0.3] COMMA (IS) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002C × 0020 × 000A ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002C × 0308 × 000A ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002C × 0308 × 0020 × 000A ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002C × 0085 ÷ # × [0.3] COMMA (IS) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002C × 0020 × 0085 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002C × 0308 × 0085 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002C × 0308 × 0020 × 0085 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002C × 17D6 ÷ # × [0.3] COMMA (IS) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002C × 0020 ÷ 17D6 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002C × 0308 × 17D6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002C ÷ 0030 ÷ # × [0.3] COMMA (IS) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002C × 0020 ÷ 0030 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002C × 0308 ÷ 0030 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0030 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002C ÷ 0028 ÷ # × [0.3] COMMA (IS) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002C × 0020 ÷ 0028 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002C × 0308 ÷ 0028 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0028 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002C ÷ 0025 ÷ # × [0.3] COMMA (IS) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002C × 0020 ÷ 0025 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002C × 0308 ÷ 0025 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0025 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002C ÷ 0024 ÷ # × [0.3] COMMA (IS) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002C × 0020 ÷ 0024 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002C × 0308 ÷ 0024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002C × 0022 ÷ # × [0.3] COMMA (IS) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002C × 0020 ÷ 0022 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002C × 0308 × 0022 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0022 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002C × 0020 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [0.3]
+× 002C × 0020 × 0020 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 002C × 0308 × 0020 × 0020 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002C × 002F ÷ # × [0.3] COMMA (IS) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002C × 0020 × 002F ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002C × 0308 × 002F ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 002C × 0308 × 0020 × 002F ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002C × 2060 ÷ # × [0.3] COMMA (IS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002C × 0020 × 2060 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002C × 0308 × 2060 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002C × 0308 × 0020 × 2060 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002C × 200B ÷ # × [0.3] COMMA (IS) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002C × 0020 × 200B ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002C × 0308 × 200B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002C × 0308 × 0020 × 200B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002C ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002C × 0020 ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002C × 0308 ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002C ÷ 261D ÷ # × [0.3] COMMA (IS) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002C × 0020 ÷ 261D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002C × 0308 ÷ 261D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 261D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002C ÷ 1F3FB ÷ # × [0.3] COMMA (IS) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002C × 0020 ÷ 1F3FB ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002C × 0308 ÷ 1F3FB ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002C × 0001 ÷ # × [0.3] COMMA (IS) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002C × 0020 ÷ 0001 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002C × 0308 × 0001 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0001 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002C × 200D ÷ # × [0.3] COMMA (IS) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002C × 0020 ÷ 200D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002C × 0308 × 200D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 200D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002C × 00A7 ÷ # × [0.3] COMMA (IS) × [29.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002C × 0020 ÷ 00A7 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002C × 0308 × 00A7 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002C × 50005 ÷ # × [0.3] COMMA (IS) × [29.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002C × 0020 ÷ 50005 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002C × 0308 × 50005 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 50005 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002C × 0E01 ÷ # × [0.3] COMMA (IS) × [29.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002C × 0020 ÷ 0E01 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002C × 0308 × 0E01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002C × 3041 ÷ # × [0.3] COMMA (IS) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002C × 0020 ÷ 3041 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002C × 0308 × 3041 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 3041 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1100 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1100 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1100 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1100 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1100 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1100 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1100 × 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1100 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1100 × 0308 × 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1100 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1100 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1100 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1100 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1100 × 0020 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1100 × 0308 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1100 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1100 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1100 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1100 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1100 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1100 × 0020 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1100 × 0308 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1100 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1100 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1100 × 0020 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1100 × 0308 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1100 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1100 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1100 × 0020 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1100 × 0308 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1100 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1100 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1100 × 0020 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1100 × 0308 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1100 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1100 × 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1100 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1100 × 0308 × 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1100 × AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1100 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1100 × 0308 × AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1100 × AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1100 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1100 × 0308 × AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1100 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1100 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1100 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1100 × 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1100 × 0020 ÷ 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1100 × 0308 × 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1100 ÷ 231A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 1100 × 0020 ÷ 231A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 1100 × 0308 ÷ 231A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 1100 × 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 1100 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1100 × 0308 × 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1100 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] COMMA (IS) ÷ [0.3]
+× 1100 × 0020 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1100 × 0308 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1100 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1100 × 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1100 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1100 × 0308 × 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1100 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1100 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1100 × 0308 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1100 × 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1100 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1100 × 0308 × 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1100 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1100 × 0020 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1100 × 0308 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1100 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1100 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1100 × 0020 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1100 × 0308 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1100 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1100 × 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1100 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1100 × 0308 × 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1100 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1100 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1100 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1100 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1100 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1100 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1100 × 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
+× 1100 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1100 × 0308 × 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1100 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1100 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1100 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1100 × 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1100 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1100 × 0308 × 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1100 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [0.3]
+× 1100 × 0020 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1100 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1100 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1100 × 0020 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1100 × 0308 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1100 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1100 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1100 × 0020 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1100 × 0308 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1100 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1100 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1100 × 0020 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1100 × 0308 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1100 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1100 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1100 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1100 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1100 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1100 × 0020 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1100 × 0308 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1100 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1100 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1100 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1100 × 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1100 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1100 × 0308 × 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1100 × 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1100 × 0020 ÷ 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1100 × 0308 × 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1100 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1100 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1100 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1100 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1100 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1100 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1100 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1100 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1100 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1100 × 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1100 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1100 × 0308 × 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11A8 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11A8 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11A8 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11A8 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 11A8 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 11A8 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 11A8 × 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11A8 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11A8 × 0308 × 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11A8 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11A8 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11A8 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11A8 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11A8 × 0020 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11A8 × 0308 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11A8 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11A8 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11A8 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11A8 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11A8 × 0020 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11A8 × 0308 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11A8 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 11A8 × 0020 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 11A8 × 0308 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 11A8 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11A8 × 0020 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11A8 × 0308 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11A8 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11A8 × 0020 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11A8 × 0308 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11A8 × 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11A8 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11A8 × 0308 × 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11A8 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11A8 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11A8 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11A8 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11A8 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11A8 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11A8 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11A8 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11A8 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11A8 × 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11A8 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11A8 × 0308 × 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11A8 ÷ 231A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 11A8 × 0020 ÷ 231A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 11A8 × 0308 ÷ 231A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 11A8 × 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 11A8 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 11A8 × 0308 × 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 11A8 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] COMMA (IS) ÷ [0.3]
+× 11A8 × 0020 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 11A8 × 0308 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 11A8 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11A8 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11A8 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11A8 × 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11A8 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11A8 × 0308 × 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11A8 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11A8 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11A8 × 0308 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11A8 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11A8 × 0020 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11A8 × 0308 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11A8 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11A8 × 0020 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11A8 × 0308 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11A8 × 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11A8 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11A8 × 0308 × 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11A8 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11A8 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11A8 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11A8 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 11A8 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 11A8 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 11A8 × 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
+× 11A8 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 11A8 × 0308 × 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 11A8 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11A8 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11A8 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11A8 × 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 11A8 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 11A8 × 0308 × 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 11A8 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [0.3]
+× 11A8 × 0020 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 11A8 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 11A8 × 0020 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 11A8 × 0308 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 11A8 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11A8 × 0020 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11A8 × 0308 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11A8 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11A8 × 0020 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11A8 × 0308 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11A8 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11A8 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11A8 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11A8 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11A8 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11A8 × 0308 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11A8 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11A8 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11A8 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11A8 × 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11A8 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11A8 × 0308 × 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11A8 × 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11A8 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11A8 × 0308 × 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11A8 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11A8 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11A8 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11A8 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11A8 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11A8 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11A8 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11A8 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11A8 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11A8 × 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11A8 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11A8 × 0308 × 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1160 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1160 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1160 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1160 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1160 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1160 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1160 × 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1160 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1160 × 0308 × 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1160 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1160 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1160 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1160 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1160 × 0020 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1160 × 0308 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1160 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1160 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1160 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1160 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1160 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1160 × 0020 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1160 × 0308 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1160 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1160 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1160 × 0020 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1160 × 0308 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1160 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1160 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1160 × 0020 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1160 × 0308 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1160 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1160 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1160 × 0020 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1160 × 0308 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1160 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1160 × 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1160 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1160 × 0308 × 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1160 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1160 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1160 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1160 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1160 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1160 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1160 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1160 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1160 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1160 × 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1160 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1160 × 0308 × 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1160 ÷ 231A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 1160 × 0020 ÷ 231A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 1160 × 0308 ÷ 231A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 1160 × 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 1160 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1160 × 0308 × 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1160 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] COMMA (IS) ÷ [0.3]
+× 1160 × 0020 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1160 × 0308 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1160 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1160 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1160 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1160 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1160 × 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1160 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1160 × 0308 × 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1160 × 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1160 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1160 × 0308 × 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1160 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1160 × 0020 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1160 × 0308 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1160 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1160 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1160 × 0020 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1160 × 0308 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1160 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1160 × 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1160 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1160 × 0308 × 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1160 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1160 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1160 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1160 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1160 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1160 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1160 × 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
+× 1160 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1160 × 0308 × 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1160 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1160 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1160 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1160 × 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1160 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1160 × 0308 × 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1160 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [0.3]
+× 1160 × 0020 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1160 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1160 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1160 × 0020 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1160 × 0308 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1160 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1160 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1160 × 0020 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1160 × 0308 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1160 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1160 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1160 × 0020 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1160 × 0308 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1160 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1160 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1160 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1160 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1160 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1160 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1160 × 0308 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1160 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1160 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1160 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1160 × 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1160 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1160 × 0308 × 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1160 × 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1160 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1160 × 0308 × 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1160 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1160 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1160 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1160 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1160 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1160 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1160 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1160 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1160 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1160 × 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1160 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1160 × 0308 × 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000A ÷ 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] NUMBER SIGN (AL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000A ÷ 0308 × 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000A ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] EM DASH (B2) ÷ [0.3]
+× 000A ÷ 0020 ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000A ÷ 0308 ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000A ÷ 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000A ÷ 0308 × 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000A ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ACUTE ACCENT (BB) ÷ [0.3]
+× 000A ÷ 0020 ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000A ÷ 0308 ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000A ÷ 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <LINE TABULATION> (BK) ÷ [0.3]
+× 000A ÷ 0020 × 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000A ÷ 0308 × 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000A ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000A ÷ 0020 ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000A ÷ 0308 ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000A ÷ 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000A ÷ 0020 × 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000A ÷ 0308 × 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000A ÷ 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000A ÷ 0020 × 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000A ÷ 0308 × 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 000A ÷ 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000A ÷ 0020 × 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000A ÷ 0308 × 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000A ÷ 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000A ÷ 0020 × 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000A ÷ 0308 × 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000A ÷ 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000A ÷ 0308 × 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000A ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000A ÷ 0020 ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000A ÷ 0308 ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000A ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000A ÷ 0020 ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000A ÷ 0308 ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000A ÷ 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000A ÷ 0308 × 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000A ÷ 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000A ÷ 0020 ÷ 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000A ÷ 0308 × 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000A ÷ 231A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] WATCH (ID) ÷ [0.3]
+× 000A ÷ 0020 ÷ 231A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 000A ÷ 0308 ÷ 231A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 000A ÷ 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ONE DOT LEADER (IN) ÷ [0.3]
+× 000A ÷ 0020 ÷ 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000A ÷ 0308 × 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000A ÷ 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMMA (IS) ÷ [0.3]
+× 000A ÷ 0020 × 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000A ÷ 0308 × 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000A ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000A ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000A ÷ 0020 ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000A ÷ 0308 ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000A ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000A ÷ 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000A ÷ 0020 × 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000A ÷ 0308 × 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000A ÷ 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000A ÷ 0020 × 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000A ÷ 0308 × 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000A ÷ 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000A ÷ 0020 ÷ 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000A ÷ 0308 × 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000A ÷ 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] DIGIT ZERO (NU) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000A ÷ 0308 × 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000A ÷ 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000A ÷ 0308 × 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 000A ÷ 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] PERCENT SIGN (PO) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000A ÷ 0308 × 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000A ÷ 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000A ÷ 0308 × 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000A ÷ 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] QUOTATION MARK (QU) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000A ÷ 0308 × 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000A ÷ 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [0.3]
+× 000A ÷ 0020 × 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000A ÷ 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SOLIDUS (SY) ÷ [0.3]
+× 000A ÷ 0020 × 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000A ÷ 0308 × 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000A ÷ 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] WORD JOINER (WJ) ÷ [0.3]
+× 000A ÷ 0020 × 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000A ÷ 0308 × 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000A ÷ 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000A ÷ 0020 × 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000A ÷ 0308 × 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000A ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000A ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000A ÷ 0020 ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000A ÷ 0308 ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000A ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000A ÷ 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000A ÷ 0308 × 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000A ÷ 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000A ÷ 0020 ÷ 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000A ÷ 0308 × 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000A ÷ 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000A ÷ 0308 × 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000A ÷ 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000A ÷ 0308 × 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000A ÷ 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000A ÷ 0308 × 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000A ÷ 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000A ÷ 0020 ÷ 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000A ÷ 0308 × 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0085 ÷ 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] NUMBER SIGN (AL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0085 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] EM DASH (B2) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0085 ÷ 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0085 ÷ 0308 × 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0085 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ACUTE ACCENT (BB) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0085 ÷ 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <LINE TABULATION> (BK) ÷ [0.3]
+× 0085 ÷ 0020 × 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0085 ÷ 0308 × 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0085 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0085 ÷ 0020 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0085 ÷ 0308 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0085 ÷ 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0085 ÷ 0020 × 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0085 ÷ 0308 × 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0085 ÷ 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0085 ÷ 0020 × 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0085 ÷ 0308 × 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0085 ÷ 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0085 ÷ 0020 × 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0085 ÷ 0308 × 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0085 ÷ 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0085 ÷ 0020 × 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0085 ÷ 0308 × 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0085 ÷ 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0085 ÷ 0308 × 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0085 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0085 ÷ 0020 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0085 ÷ 0308 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0085 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0085 ÷ 0020 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0085 ÷ 0308 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0085 ÷ 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0085 ÷ 0308 × 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0085 ÷ 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0085 ÷ 0308 × 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0085 ÷ 231A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] WATCH (ID) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 231A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 231A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0085 ÷ 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ONE DOT LEADER (IN) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0085 ÷ 0308 × 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0085 ÷ 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMMA (IS) ÷ [0.3]
+× 0085 ÷ 0020 × 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0085 ÷ 0308 × 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0085 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0085 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0085 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0085 ÷ 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0085 ÷ 0020 × 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0085 ÷ 0308 × 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0085 ÷ 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0085 ÷ 0020 × 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0085 ÷ 0308 × 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0085 ÷ 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0085 ÷ 0308 × 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0085 ÷ 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] DIGIT ZERO (NU) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0085 ÷ 0308 × 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0085 ÷ 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0085 ÷ 0308 × 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0085 ÷ 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] PERCENT SIGN (PO) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0085 ÷ 0308 × 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0085 ÷ 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] DOLLAR SIGN (PR) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0085 ÷ 0308 × 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0085 ÷ 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] QUOTATION MARK (QU) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0085 ÷ 0308 × 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0085 ÷ 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [0.3]
+× 0085 ÷ 0020 × 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0085 ÷ 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SOLIDUS (SY) ÷ [0.3]
+× 0085 ÷ 0020 × 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0085 ÷ 0308 × 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0085 ÷ 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] WORD JOINER (WJ) ÷ [0.3]
+× 0085 ÷ 0020 × 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0085 ÷ 0308 × 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0085 ÷ 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0085 ÷ 0020 × 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0085 ÷ 0308 × 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0085 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0085 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0085 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0085 ÷ 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0085 ÷ 0308 × 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0085 ÷ 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0085 ÷ 0308 × 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0085 ÷ 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0085 ÷ 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0085 ÷ 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0085 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0085 ÷ 0308 × 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 17D6 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 17D6 × 0020 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 17D6 × 0308 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 17D6 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 17D6 × 0020 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 17D6 × 0308 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 17D6 × 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 17D6 × 0020 ÷ 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 17D6 × 0308 × 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 17D6 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 17D6 × 0020 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 17D6 × 0308 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 17D6 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 17D6 × 0020 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 17D6 × 0308 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 17D6 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 17D6 × 0020 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 17D6 × 0308 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 17D6 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 17D6 × 0020 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 17D6 × 0308 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 17D6 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 17D6 × 0020 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 17D6 × 0308 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 17D6 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 17D6 × 0020 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 17D6 × 0308 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 17D6 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 17D6 × 0020 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 17D6 × 0308 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 17D6 × 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 17D6 × 0020 ÷ 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 17D6 × 0308 × 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 17D6 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 17D6 × 0020 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 17D6 × 0308 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 17D6 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 17D6 × 0020 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 17D6 × 0308 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 17D6 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 17D6 × 0020 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 17D6 × 0308 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 17D6 × 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 17D6 × 0020 ÷ 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 17D6 × 0308 × 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 17D6 ÷ 231A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 17D6 × 0020 ÷ 231A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 17D6 × 0308 ÷ 231A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 231A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 17D6 ÷ 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 17D6 × 0020 ÷ 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 17D6 × 0308 ÷ 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 17D6 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] COMMA (IS) ÷ [0.3]
+× 17D6 × 0020 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 17D6 × 0308 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 17D6 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 17D6 × 0020 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 17D6 × 0308 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 17D6 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 17D6 × 0020 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 17D6 × 0308 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 17D6 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 17D6 × 0020 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 17D6 × 0308 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 17D6 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 17D6 × 0020 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 17D6 × 0308 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 17D6 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 17D6 × 0020 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 17D6 × 0308 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 17D6 × 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 17D6 × 0020 ÷ 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 17D6 × 0308 × 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 17D6 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 17D6 × 0020 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 17D6 × 0308 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 17D6 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 17D6 × 0020 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 17D6 × 0308 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 17D6 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 17D6 × 0020 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 17D6 × 0308 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 17D6 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 17D6 × 0020 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 17D6 × 0308 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 17D6 × 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 17D6 × 0020 ÷ 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 17D6 × 0308 × 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 17D6 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [0.3]
+× 17D6 × 0020 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 17D6 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 17D6 × 0020 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 17D6 × 0308 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 17D6 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 17D6 × 0020 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 17D6 × 0308 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 17D6 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 17D6 × 0020 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 17D6 × 0308 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 17D6 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 17D6 × 0020 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 17D6 × 0308 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 17D6 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 17D6 × 0020 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 17D6 × 0308 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 17D6 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 17D6 × 0020 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 17D6 × 0308 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 17D6 × 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 17D6 × 0020 ÷ 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 17D6 × 0308 × 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 17D6 × 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 17D6 × 0020 ÷ 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 17D6 × 0308 × 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 17D6 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 17D6 × 0020 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 17D6 × 0308 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 17D6 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 17D6 × 0020 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 17D6 × 0308 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 17D6 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 17D6 × 0020 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 17D6 × 0308 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 17D6 × 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 17D6 × 0020 ÷ 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 17D6 × 0308 × 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0030 × 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] NUMBER SIGN (AL) ÷ [0.3]
+× 0030 × 0020 ÷ 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0030 × 0308 × 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] NUMBER SIGN (AL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0030 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0030 × 0020 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0030 × 0308 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0030 × 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0030 × 0020 ÷ 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0030 × 0308 × 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0030 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0030 × 0020 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0030 × 0308 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0030 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0030 × 0020 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0030 × 0308 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0030 × 0308 × 0020 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0030 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0030 × 0020 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0030 × 0308 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0030 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0030 × 0020 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0030 × 0308 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0030 × 0308 × 0020 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0030 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [25.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0030 × 0020 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0030 × 0308 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0030 × 0308 × 0020 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0030 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0030 × 0020 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0030 × 0308 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0030 × 0308 × 0020 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0030 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0030 × 0020 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0030 × 0308 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0030 × 0308 × 0020 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0030 × 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0030 × 0020 ÷ 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0030 × 0308 × 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0030 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0030 × 0020 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0030 × 0308 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0030 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0030 × 0020 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0030 × 0308 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0030 × 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0030 × 0020 ÷ 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0030 × 0308 × 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0030 × 002D ÷ # × [0.3] DIGIT ZERO (NU) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0030 × 0020 ÷ 002D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0030 × 0308 × 002D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 002D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0030 ÷ 231A ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0030 × 0020 ÷ 231A ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0030 × 0308 ÷ 231A ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 231A ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0030 × 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [22.05] ONE DOT LEADER (IN) ÷ [0.3]
+× 0030 × 0020 ÷ 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0030 × 0308 × 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.05] ONE DOT LEADER (IN) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0030 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [25.03] COMMA (IS) ÷ [0.3]
+× 0030 × 0020 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0030 × 0308 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.03] COMMA (IS) ÷ [0.3]
+× 0030 × 0308 × 0020 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0030 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0030 × 0020 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0030 × 0308 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0030 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0030 × 0020 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0030 × 0308 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0030 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0030 × 0020 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0030 × 0308 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0030 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0030 × 0020 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0030 × 0308 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0030 × 0308 × 0020 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0030 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0030 × 0020 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0030 × 0308 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0030 × 0308 × 0020 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0030 × 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0030 × 0020 ÷ 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0030 × 0308 × 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0030 × 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [25.03] DIGIT ZERO (NU) ÷ [0.3]
+× 0030 × 0020 ÷ 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0030 × 0308 × 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.03] DIGIT ZERO (NU) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0030 × 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0030 × 0020 ÷ 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0030 × 0308 × 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0030 × 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [25.05] PERCENT SIGN (PO) ÷ [0.3]
+× 0030 × 0020 ÷ 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0030 × 0308 × 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.05] PERCENT SIGN (PO) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0030 × 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [25.05] DOLLAR SIGN (PR) ÷ [0.3]
+× 0030 × 0020 ÷ 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0030 × 0308 × 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.05] DOLLAR SIGN (PR) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0030 × 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0030 × 0020 ÷ 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0030 × 0308 × 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0030 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [0.3]
+× 0030 × 0020 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0030 × 0308 × 0020 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0030 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [25.03] SOLIDUS (SY) ÷ [0.3]
+× 0030 × 0020 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0030 × 0308 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.03] SOLIDUS (SY) ÷ [0.3]
+× 0030 × 0308 × 0020 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0030 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0030 × 0020 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0030 × 0308 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0030 × 0308 × 0020 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0030 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0030 × 0020 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0030 × 0308 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0030 × 0308 × 0020 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0030 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0030 × 0020 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0030 × 0308 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0030 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0030 × 0020 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0030 × 0308 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0030 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0030 × 0020 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0030 × 0308 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0030 × 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0030 × 0020 ÷ 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0030 × 0308 × 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0030 × 200D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0030 × 0020 ÷ 200D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0030 × 0308 × 200D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 200D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0030 × 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0030 × 0020 ÷ 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0030 × 0308 × 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0030 × 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0030 × 0020 ÷ 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0030 × 0308 × 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0030 × 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0030 × 0020 ÷ 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0030 × 0308 × 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0030 × 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0030 × 0020 ÷ 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0030 × 0308 × 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0028 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0028 × 0020 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0028 × 0308 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0028 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] EM DASH (B2) ÷ [0.3]
+× 0028 × 0020 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] EM DASH (B2) ÷ [0.3]
+× 0028 × 0308 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] EM DASH (B2) ÷ [0.3]
+× 0028 × 0308 × 0020 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] EM DASH (B2) ÷ [0.3]
+× 0028 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0028 × 0020 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0028 × 0308 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0028 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0028 × 0020 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0028 × 0308 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0028 × 0308 × 0020 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0028 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0028 × 0020 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0028 × 0308 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0028 × 0308 × 0020 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0028 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0028 × 0020 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0028 × 0308 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0028 × 0308 × 0020 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0028 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0028 × 0020 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0028 × 0308 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0028 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0028 × 0020 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0028 × 0308 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0028 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0028 × 0020 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0028 × 0308 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0028 × 0308 × 0020 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0028 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0028 × 0020 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0028 × 0308 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0028 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0028 × 0020 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0028 × 0308 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0028 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0028 × 0020 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0028 × 0308 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0028 × 0308 × 0020 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0028 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0028 × 0020 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0028 × 0308 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0028 × 0308 × 0020 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0028 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0028 × 0020 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0028 × 0308 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0028 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0028 × 0020 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0028 × 0308 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0028 × 0308 × 0020 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0028 × 231A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] WATCH (ID) ÷ [0.3]
+× 0028 × 0020 × 231A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] WATCH (ID) ÷ [0.3]
+× 0028 × 0308 × 231A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] WATCH (ID) ÷ [0.3]
+× 0028 × 0308 × 0020 × 231A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] WATCH (ID) ÷ [0.3]
+× 0028 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0028 × 0020 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0028 × 0308 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0028 × 0308 × 0020 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0028 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0028 × 0020 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0028 × 0308 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0028 × 0308 × 0020 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0028 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0028 × 0020 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0028 × 0308 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0028 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0028 × 0020 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0028 × 0308 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0028 × 0308 × 0020 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0028 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0028 × 0020 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0028 × 0308 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0028 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0028 × 0020 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0028 × 0308 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0028 × 0308 × 0020 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0028 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0028 × 0020 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0028 × 0308 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0028 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0028 × 0020 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0028 × 0308 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0028 × 0308 × 0020 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0028 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0028 × 0020 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0028 × 0308 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0028 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0028 × 0020 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0028 × 0308 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0028 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0028 × 0020 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0028 × 0308 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0028 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0028 × 0020 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0028 × 0308 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0028 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0028 × 0020 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0028 × 0308 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0028 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0028 × 0020 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0028 × 0308 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0028 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0028 × 0020 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0028 × 0308 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0028 × 0308 × 0020 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0028 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0028 × 0020 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0028 × 0308 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0028 × 0308 × 0020 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0028 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0028 × 0020 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0028 × 0308 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0028 × 0308 × 0020 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0028 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0028 × 0020 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0028 × 0308 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0028 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0028 × 0020 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0028 × 0308 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0028 × 0308 × 0020 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0028 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0028 × 0020 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0028 × 0308 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0028 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0028 × 0020 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0028 × 0308 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0028 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0028 × 0020 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0028 × 0308 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0028 × 0308 × 0020 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0028 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0028 × 0020 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0028 × 0308 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0028 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0028 × 0020 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0028 × 0308 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0028 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0028 × 0020 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0028 × 0308 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0028 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0028 × 0020 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0028 × 0308 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0028 × 0308 × 0020 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0025 × 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0025 × 0020 ÷ 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0025 × 0308 × 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0025 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0025 × 0020 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0025 × 0308 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0025 × 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0025 × 0020 ÷ 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0025 × 0308 × 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0025 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0025 × 0020 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0025 × 0308 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0025 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0025 × 0020 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0025 × 0308 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0025 × 0308 × 0020 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0025 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0025 × 0020 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0025 × 0308 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0025 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0025 × 0020 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0025 × 0308 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0025 × 0308 × 0020 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0025 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0025 × 0020 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0025 × 0308 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0025 × 0308 × 0020 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0025 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0025 × 0020 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0025 × 0308 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0025 × 0308 × 0020 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0025 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0025 × 0020 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0025 × 0308 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0025 × 0308 × 0020 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0025 × 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0025 × 0020 ÷ 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0025 × 0308 × 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0025 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0025 × 0020 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0025 × 0308 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0025 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0025 × 0020 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0025 × 0308 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0025 × 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0025 × 0020 ÷ 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0025 × 0308 × 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0025 × 002D ÷ # × [0.3] PERCENT SIGN (PO) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0025 × 0020 ÷ 002D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0025 × 0308 × 002D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 002D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0025 ÷ 231A ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0025 × 0020 ÷ 231A ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0025 × 0308 ÷ 231A ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 231A ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0025 ÷ 2024 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0025 × 0020 ÷ 2024 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0025 × 0308 ÷ 2024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0025 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] COMMA (IS) ÷ [0.3]
+× 0025 × 0020 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0025 × 0308 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0025 × 0308 × 0020 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0025 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0025 × 0020 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0025 × 0308 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0025 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0025 × 0020 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0025 × 0308 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0025 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0025 × 0020 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0025 × 0308 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0025 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0025 × 0020 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0025 × 0308 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0025 × 0308 × 0020 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0025 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0025 × 0020 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0025 × 0308 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0025 × 0308 × 0020 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0025 × 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0025 × 0020 ÷ 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0025 × 0308 × 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0025 × 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
+× 0025 × 0020 ÷ 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0025 × 0308 × 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0025 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0025 × 0020 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0025 × 0308 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0025 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0025 × 0020 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0025 × 0308 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0025 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0025 × 0020 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0025 × 0308 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0025 × 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0025 × 0020 ÷ 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0025 × 0308 × 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0025 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [0.3]
+× 0025 × 0020 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0025 × 0308 × 0020 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0025 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0025 × 0020 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0025 × 0308 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0025 × 0308 × 0020 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0025 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0025 × 0020 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0025 × 0308 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0025 × 0308 × 0020 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0025 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0025 × 0020 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0025 × 0308 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0025 × 0308 × 0020 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0025 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0025 × 0020 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0025 × 0308 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0025 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0025 × 0020 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0025 × 0308 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0025 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0025 × 0020 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0025 × 0308 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0025 × 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0025 × 0020 ÷ 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0025 × 0308 × 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0025 × 200D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0025 × 0020 ÷ 200D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0025 × 0308 × 200D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 200D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0025 × 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0025 × 0020 ÷ 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0025 × 0308 × 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0025 × 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0025 × 0020 ÷ 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0025 × 0308 × 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0025 × 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0025 × 0020 ÷ 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0025 × 0308 × 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0025 × 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0025 × 0020 ÷ 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0025 × 0308 × 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0024 × 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0024 × 0020 ÷ 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0024 × 0308 × 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0024 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0024 × 0020 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0024 × 0308 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0024 × 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0024 × 0020 ÷ 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0024 × 0308 × 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0024 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0024 × 0020 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0024 × 0308 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0024 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0024 × 0020 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0024 × 0308 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0024 × 0308 × 0020 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0024 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0024 × 0020 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0024 × 0308 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0024 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0024 × 0020 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0024 × 0308 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0024 × 0308 × 0020 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0024 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0024 × 0020 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0024 × 0308 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0024 × 0308 × 0020 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0024 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0024 × 0020 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0024 × 0308 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0024 × 0308 × 0020 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0024 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0024 × 0020 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0024 × 0308 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0024 × 0308 × 0020 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0024 × 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0024 × 0020 ÷ 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0024 × 0308 × 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0024 × AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0024 × 0020 ÷ AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0024 × 0308 × AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.03] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0024 × AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0024 × 0020 ÷ AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0024 × 0308 × AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.03] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0024 × 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0024 × 0020 ÷ 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0024 × 0308 × 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0024 × 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0024 × 0020 ÷ 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0024 × 0308 × 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0024 × 231A ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] WATCH (ID) ÷ [0.3]
+× 0024 × 0020 ÷ 231A ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0024 × 0308 × 231A ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.12] WATCH (ID) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 231A ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0024 ÷ 2024 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0024 × 0020 ÷ 2024 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0024 × 0308 ÷ 2024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0024 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] COMMA (IS) ÷ [0.3]
+× 0024 × 0020 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0024 × 0308 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0024 × 0308 × 0020 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0024 × 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0024 × 0020 ÷ 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0024 × 0308 × 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.03] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0024 × 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0024 × 0020 ÷ 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0024 × 0308 × 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0024 × 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0024 × 0020 ÷ 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0024 × 0308 × 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.03] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0024 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0024 × 0020 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0024 × 0308 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0024 × 0308 × 0020 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0024 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0024 × 0020 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0024 × 0308 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0024 × 0308 × 0020 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0024 × 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0024 × 0020 ÷ 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0024 × 0308 × 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0024 × 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
+× 0024 × 0020 ÷ 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0024 × 0308 × 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0024 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0024 × 0020 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0024 × 0308 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0024 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0024 × 0020 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0024 × 0308 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0024 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0024 × 0020 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0024 × 0308 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0024 × 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0024 × 0020 ÷ 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0024 × 0308 × 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0024 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [0.3]
+× 0024 × 0020 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0024 × 0308 × 0020 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0024 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0024 × 0020 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0024 × 0308 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0024 × 0308 × 0020 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0024 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0024 × 0020 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0024 × 0308 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0024 × 0308 × 0020 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0024 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0024 × 0020 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0024 × 0308 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0024 × 0308 × 0020 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0024 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0024 × 0020 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0024 × 0308 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0024 × 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0024 × 0020 ÷ 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0024 × 0308 × 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.12] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0024 × 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0024 × 0020 ÷ 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0024 × 0308 × 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.12] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0024 × 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0024 × 0020 ÷ 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0024 × 0308 × 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0024 × 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0024 × 0020 ÷ 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0024 × 0308 × 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0024 × 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0024 × 0020 ÷ 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0024 × 0308 × 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0024 × 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0024 × 0020 ÷ 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0024 × 0308 × 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0024 × 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0024 × 0020 ÷ 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0024 × 0308 × 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0024 × 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0024 × 0020 ÷ 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0024 × 0308 × 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0022 × 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0022 × 0020 ÷ 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0022 × 0308 × 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0022 × 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] EM DASH (B2) ÷ [0.3]
+× 0022 × 0020 ÷ 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0022 × 0308 × 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] EM DASH (B2) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0022 × 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0022 × 0020 ÷ 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0022 × 0308 × 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0022 × 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 0022 × 0020 ÷ 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0022 × 0308 × 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0022 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0022 × 0020 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0022 × 0308 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0022 × 0308 × 0020 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0022 × FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0022 × 0020 ÷ FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0022 × 0308 × FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0022 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0022 × 0020 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0022 × 0308 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0022 × 0308 × 0020 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0022 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0022 × 0020 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0022 × 0308 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0022 × 0308 × 0020 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0022 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0022 × 0020 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0022 × 0308 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0022 × 0308 × 0020 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0022 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0022 × 0020 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0022 × 0308 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0022 × 0308 × 0020 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0022 × 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0022 × 0020 ÷ 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0022 × 0308 × 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0022 × AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0022 × 0020 ÷ AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0022 × 0308 × AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0022 × AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0022 × 0020 ÷ AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0022 × 0308 × AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0022 × 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0022 × 0020 ÷ 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0022 × 0308 × 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0022 × 002D ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0022 × 0020 ÷ 002D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0022 × 0308 × 002D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 002D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0022 × 231A ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] WATCH (ID) ÷ [0.3]
+× 0022 × 0020 ÷ 231A ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0022 × 0308 × 231A ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] WATCH (ID) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 231A ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0022 × 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 0022 × 0020 ÷ 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0022 × 0308 × 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0022 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] COMMA (IS) ÷ [0.3]
+× 0022 × 0020 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0022 × 0308 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0022 × 0308 × 0020 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0022 × 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0022 × 0020 ÷ 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0022 × 0308 × 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0022 × 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0022 × 0020 ÷ 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0022 × 0308 × 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0022 × 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0022 × 0020 ÷ 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0022 × 0308 × 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0022 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0022 × 0020 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0022 × 0308 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0022 × 0308 × 0020 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0022 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0022 × 0020 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0022 × 0308 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0022 × 0308 × 0020 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0022 × 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0022 × 0020 ÷ 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0022 × 0308 × 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0022 × 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0022 × 0020 ÷ 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0022 × 0308 × 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0022 × 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [15.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0022 × 0020 × 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [15.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0022 × 0308 × 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0022 × 0308 × 0020 × 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0022 × 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] PERCENT SIGN (PO) ÷ [0.3]
+× 0022 × 0020 ÷ 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0022 × 0308 × 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] PERCENT SIGN (PO) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0022 × 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 0022 × 0020 ÷ 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0022 × 0308 × 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0022 × 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0022 × 0020 ÷ 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0022 × 0308 × 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0022 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [0.3]
+× 0022 × 0020 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0022 × 0308 × 0020 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0022 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0022 × 0020 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0022 × 0308 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0022 × 0308 × 0020 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0022 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0022 × 0020 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0022 × 0308 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0022 × 0308 × 0020 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0022 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0022 × 0020 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0022 × 0308 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0022 × 0308 × 0020 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0022 × 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0022 × 0020 ÷ 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0022 × 0308 × 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0022 × 261D ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0022 × 0020 ÷ 261D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0022 × 0308 × 261D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 261D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0022 × 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0022 × 0020 ÷ 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0022 × 0308 × 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0022 × 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0022 × 0020 ÷ 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0022 × 0308 × 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0022 × 200D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0022 × 0020 ÷ 200D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0022 × 0308 × 200D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 200D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0022 × 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0022 × 0020 ÷ 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0022 × 0308 × 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0022 × 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0022 × 0020 ÷ 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0022 × 0308 × 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0022 × 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0022 × 0020 ÷ 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0022 × 0308 × 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0022 × 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0022 × 0020 ÷ 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0022 × 0308 × 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0020 ÷ 0023 ÷ # × [0.3] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0020 × 0020 ÷ 0023 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0023 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0020 ÷ 2014 ÷ # × [0.3] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0020 × 0020 ÷ 2014 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 2014 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0020 ÷ 0009 ÷ # × [0.3] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0020 × 0020 ÷ 0009 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0020 ÷ 0308 × 0009 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0020 ÷ 00B4 ÷ # × [0.3] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0020 × 0020 ÷ 00B4 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 00B4 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0020 × 000B ÷ # × [0.3] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0020 × 0020 × 000B ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0020 ÷ 0308 × 000B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 000B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0020 ÷ FFFC ÷ # × [0.3] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0020 × 0020 ÷ FFFC ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0020 ÷ 0308 ÷ FFFC ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0020 × 007D ÷ # × [0.3] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0020 × 0020 × 007D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0020 ÷ 0308 × 007D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 007D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0020 × 0029 ÷ # × [0.3] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0020 × 0020 × 0029 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0020 ÷ 0308 × 0029 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 0029 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0020 × 000D ÷ # × [0.3] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0020 × 0020 × 000D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0020 ÷ 0308 × 000D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 000D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0020 × 0021 ÷ # × [0.3] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0020 × 0020 × 0021 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0020 ÷ 0308 × 0021 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 0021 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0020 ÷ 00A0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0020 × 0020 ÷ 00A0 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0020 ÷ 0308 × 00A0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0020 ÷ AC00 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0020 × 0020 ÷ AC00 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0020 ÷ 0308 ÷ AC00 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0020 ÷ AC01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0020 × 0020 ÷ AC01 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0020 ÷ 0308 ÷ AC01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0020 ÷ 05D0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0020 × 0020 ÷ 05D0 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0020 ÷ 0308 × 05D0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0020 ÷ 002D ÷ # × [0.3] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0020 × 0020 ÷ 002D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0020 ÷ 0308 × 002D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0020 ÷ 231A ÷ # × [0.3] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0020 × 0020 ÷ 231A ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 231A ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0020 ÷ 2024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0020 × 0020 ÷ 2024 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0020 ÷ 0308 × 2024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0020 × 002C ÷ # × [0.3] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0020 × 0020 × 002C ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0020 ÷ 0308 × 002C ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 002C ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0020 ÷ 1100 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0020 × 0020 ÷ 1100 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1100 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0020 ÷ 11A8 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0020 × 0020 ÷ 11A8 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 11A8 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0020 ÷ 1160 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0020 × 0020 ÷ 1160 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1160 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0020 × 000A ÷ # × [0.3] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0020 × 0020 × 000A ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0020 ÷ 0308 × 000A ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 000A ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0020 × 0085 ÷ # × [0.3] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0020 × 0020 × 0085 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0020 ÷ 0308 × 0085 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 0085 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0020 ÷ 17D6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0020 × 0020 ÷ 17D6 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0020 ÷ 0308 × 17D6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0020 ÷ 0030 ÷ # × [0.3] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0020 × 0020 ÷ 0030 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0020 ÷ 0308 × 0030 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0020 ÷ 0028 ÷ # × [0.3] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0020 × 0020 ÷ 0028 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0020 ÷ 0308 × 0028 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0020 ÷ 0025 ÷ # × [0.3] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0020 × 0020 ÷ 0025 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0020 ÷ 0308 × 0025 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0020 ÷ 0024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0020 × 0020 ÷ 0024 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0020 ÷ 0308 × 0024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0020 ÷ 0022 ÷ # × [0.3] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0020 × 0020 ÷ 0022 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0020 ÷ 0308 × 0022 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0020 × 0020 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0020 × 0020 × 0020 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 0020 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0020 × 002F ÷ # × [0.3] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0020 × 0020 × 002F ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0020 ÷ 0308 × 002F ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 002F ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0020 × 2060 ÷ # × [0.3] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0020 × 0020 × 2060 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0020 ÷ 0308 × 2060 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 2060 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0020 × 200B ÷ # × [0.3] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0020 × 0020 × 200B ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0020 ÷ 0308 × 200B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 200B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0020 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0020 × 0020 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0020 ÷ 261D ÷ # × [0.3] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0020 × 0020 ÷ 261D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 261D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0020 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0020 × 0020 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0020 ÷ 0001 ÷ # × [0.3] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0020 × 0020 ÷ 0001 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0020 ÷ 0308 × 0001 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0020 ÷ 200D ÷ # × [0.3] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0020 × 0020 ÷ 200D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0020 ÷ 0308 × 200D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0020 ÷ 00A7 ÷ # × [0.3] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0020 × 0020 ÷ 00A7 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 00A7 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0020 ÷ 50005 ÷ # × [0.3] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0020 × 0020 ÷ 50005 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 50005 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0020 ÷ 0E01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0020 × 0020 ÷ 0E01 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0E01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0020 ÷ 3041 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0020 × 0020 ÷ 3041 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0020 ÷ 0308 × 3041 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002F ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002F × 0020 ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002F × 0308 ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002F ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002F × 0020 ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002F × 0308 ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002F × 0009 ÷ # × [0.3] SOLIDUS (SY) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002F × 0020 ÷ 0009 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002F × 0308 × 0009 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0009 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002F ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002F × 0020 ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002F × 0308 ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002F × 000B ÷ # × [0.3] SOLIDUS (SY) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002F × 0020 × 000B ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002F × 0308 × 000B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002F × 0308 × 0020 × 000B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002F ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002F × 0020 ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002F × 0308 ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002F × 007D ÷ # × [0.3] SOLIDUS (SY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002F × 0020 × 007D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002F × 0308 × 007D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002F × 0308 × 0020 × 007D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002F × 0029 ÷ # × [0.3] SOLIDUS (SY) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002F × 0020 × 0029 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002F × 0308 × 0029 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002F × 0308 × 0020 × 0029 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 002F × 000D ÷ # × [0.3] SOLIDUS (SY) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002F × 0020 × 000D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002F × 0308 × 000D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002F × 0308 × 0020 × 000D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002F × 0021 ÷ # × [0.3] SOLIDUS (SY) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002F × 0020 × 0021 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002F × 0308 × 0021 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002F × 0308 × 0020 × 0021 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002F × 00A0 ÷ # × [0.3] SOLIDUS (SY) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002F × 0020 ÷ 00A0 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002F × 0308 × 00A0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002F ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002F × 0020 ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002F × 0308 ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002F ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002F × 0020 ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002F × 0308 ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002F × 05D0 ÷ # × [0.3] SOLIDUS (SY) × [21.2] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002F × 0020 ÷ 05D0 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002F × 0308 × 05D0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.2] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002F × 002D ÷ # × [0.3] SOLIDUS (SY) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002F × 0020 ÷ 002D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002F × 0308 × 002D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 002D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002F ÷ 231A ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 002F × 0020 ÷ 231A ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 002F × 0308 ÷ 231A ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 231A ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 002F ÷ 2024 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002F × 0020 ÷ 2024 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002F × 0308 ÷ 2024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 2024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002F × 002C ÷ # × [0.3] SOLIDUS (SY) × [13.02] COMMA (IS) ÷ [0.3]
+× 002F × 0020 × 002C ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002F × 0308 × 002C ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 002F × 0308 × 0020 × 002C ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002F ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002F × 0020 ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002F × 0308 ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002F ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002F × 0020 ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002F × 0308 ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002F ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002F × 0020 ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002F × 0308 ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002F × 000A ÷ # × [0.3] SOLIDUS (SY) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002F × 0020 × 000A ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002F × 0308 × 000A ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002F × 0308 × 0020 × 000A ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002F × 0085 ÷ # × [0.3] SOLIDUS (SY) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002F × 0020 × 0085 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002F × 0308 × 0085 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002F × 0308 × 0020 × 0085 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002F × 17D6 ÷ # × [0.3] SOLIDUS (SY) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002F × 0020 ÷ 17D6 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002F × 0308 × 17D6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002F ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002F × 0020 ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002F × 0308 ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002F ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002F × 0020 ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002F × 0308 ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 002F ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002F × 0020 ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002F × 0308 ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002F ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002F × 0020 ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002F × 0308 ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002F × 0022 ÷ # × [0.3] SOLIDUS (SY) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002F × 0020 ÷ 0022 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002F × 0308 × 0022 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0022 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002F × 0020 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [0.3]
+× 002F × 0020 × 0020 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 002F × 0308 × 0020 × 0020 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002F × 002F ÷ # × [0.3] SOLIDUS (SY) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002F × 0020 × 002F ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002F × 0308 × 002F ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 002F × 0308 × 0020 × 002F ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002F × 2060 ÷ # × [0.3] SOLIDUS (SY) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002F × 0020 × 2060 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002F × 0308 × 2060 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002F × 0308 × 0020 × 2060 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002F × 200B ÷ # × [0.3] SOLIDUS (SY) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002F × 0020 × 200B ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002F × 0308 × 200B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002F × 0308 × 0020 × 200B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002F ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002F × 0020 ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002F × 0308 ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002F ÷ 261D ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002F × 0020 ÷ 261D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002F × 0308 ÷ 261D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 261D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002F ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002F × 0020 ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002F × 0308 ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002F × 0001 ÷ # × [0.3] SOLIDUS (SY) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002F × 0020 ÷ 0001 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002F × 0308 × 0001 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0001 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002F × 200D ÷ # × [0.3] SOLIDUS (SY) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002F × 0020 ÷ 200D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002F × 0308 × 200D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 200D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002F ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002F × 0020 ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002F × 0308 ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002F ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002F × 0020 ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002F × 0308 ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002F ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002F × 0020 ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002F × 0308 ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002F × 3041 ÷ # × [0.3] SOLIDUS (SY) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002F × 0020 ÷ 3041 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002F × 0308 × 3041 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 3041 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2060 × 0023 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] NUMBER SIGN (AL) ÷ [0.3]
+× 2060 × 0020 ÷ 0023 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2060 × 0308 × 0023 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] NUMBER SIGN (AL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2060 × 2014 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] EM DASH (B2) ÷ [0.3]
+× 2060 × 0020 ÷ 2014 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 2060 × 0308 × 2014 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] EM DASH (B2) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 2060 × 0009 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2060 × 0020 ÷ 0009 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2060 × 0308 × 0009 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2060 × 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 2060 × 0020 ÷ 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2060 × 0308 × 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2060 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2060 × 0020 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2060 × 0308 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2060 × 0308 × 0020 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2060 × FFFC ÷ # × [0.3] WORD JOINER (WJ) × [11.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2060 × 0020 ÷ FFFC ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2060 × 0308 × FFFC ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2060 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [11.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2060 × 0020 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2060 × 0308 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2060 × 0308 × 0020 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2060 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2060 × 0020 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2060 × 0308 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2060 × 0308 × 0020 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 2060 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2060 × 0020 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2060 × 0308 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2060 × 0308 × 0020 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2060 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2060 × 0020 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2060 × 0308 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2060 × 0308 × 0020 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2060 × 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2060 × 0020 ÷ 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2060 × 0308 × 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2060 × AC00 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2060 × 0020 ÷ AC00 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2060 × 0308 × AC00 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2060 × AC01 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2060 × 0020 ÷ AC01 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2060 × 0308 × AC01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2060 × 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2060 × 0020 ÷ 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2060 × 0308 × 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2060 × 002D ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2060 × 0020 ÷ 002D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2060 × 0308 × 002D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 002D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2060 × 231A ÷ # × [0.3] WORD JOINER (WJ) × [11.02] WATCH (ID) ÷ [0.3]
+× 2060 × 0020 ÷ 231A ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 2060 × 0308 × 231A ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] WATCH (ID) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 231A ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 2060 × 2024 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 2060 × 0020 ÷ 2024 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2060 × 0308 × 2024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2060 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [11.02] COMMA (IS) ÷ [0.3]
+× 2060 × 0020 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2060 × 0308 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] COMMA (IS) ÷ [0.3]
+× 2060 × 0308 × 0020 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2060 × 1100 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2060 × 0020 ÷ 1100 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2060 × 0308 × 1100 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2060 × 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2060 × 0020 ÷ 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2060 × 0308 × 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2060 × 1160 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2060 × 0020 ÷ 1160 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2060 × 0308 × 1160 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2060 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2060 × 0020 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2060 × 0308 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2060 × 0308 × 0020 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2060 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2060 × 0020 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2060 × 0308 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2060 × 0308 × 0020 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2060 × 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2060 × 0020 ÷ 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2060 × 0308 × 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2060 × 0030 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] DIGIT ZERO (NU) ÷ [0.3]
+× 2060 × 0020 ÷ 0030 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2060 × 0308 × 0030 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] DIGIT ZERO (NU) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2060 × 0028 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2060 × 0020 ÷ 0028 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2060 × 0308 × 0028 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 2060 × 0025 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] PERCENT SIGN (PO) ÷ [0.3]
+× 2060 × 0020 ÷ 0025 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2060 × 0308 × 0025 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] PERCENT SIGN (PO) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2060 × 0024 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 2060 × 0020 ÷ 0024 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2060 × 0308 × 0024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2060 × 0022 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] QUOTATION MARK (QU) ÷ [0.3]
+× 2060 × 0020 ÷ 0022 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2060 × 0308 × 0022 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] QUOTATION MARK (QU) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2060 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [0.3]
+× 2060 × 0020 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 2060 × 0308 × 0020 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2060 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [11.02] SOLIDUS (SY) ÷ [0.3]
+× 2060 × 0020 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2060 × 0308 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] SOLIDUS (SY) ÷ [0.3]
+× 2060 × 0308 × 0020 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2060 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2060 × 0020 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2060 × 0308 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2060 × 0308 × 0020 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2060 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2060 × 0020 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2060 × 0308 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2060 × 0308 × 0020 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2060 × 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2060 × 0020 ÷ 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2060 × 0308 × 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2060 × 261D ÷ # × [0.3] WORD JOINER (WJ) × [11.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2060 × 0020 ÷ 261D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2060 × 0308 × 261D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 261D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2060 × 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [11.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2060 × 0020 ÷ 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2060 × 0308 × 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2060 × 0001 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2060 × 0020 ÷ 0001 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2060 × 0308 × 0001 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2060 × 200D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2060 × 0020 ÷ 200D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2060 × 0308 × 200D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 200D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2060 × 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2060 × 0020 ÷ 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2060 × 0308 × 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2060 × 50005 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2060 × 0020 ÷ 50005 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2060 × 0308 × 50005 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2060 × 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2060 × 0020 ÷ 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2060 × 0308 × 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2060 × 3041 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2060 × 0020 ÷ 3041 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2060 × 0308 × 3041 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200B ÷ 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200B × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200B ÷ 0308 × 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200B ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] EM DASH (B2) ÷ [0.3]
+× 200B × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] EM DASH (B2) ÷ [0.3]
+× 200B ÷ 0308 ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 200B ÷ 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200B × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200B ÷ 0308 × 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200B ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200B × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200B ÷ 0308 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200B × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200B × 0020 × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200B ÷ 0308 × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200B ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200B × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200B ÷ 0308 ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200B ÷ 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200B × 0020 ÷ 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200B ÷ 0308 × 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200B ÷ 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 200B × 0020 ÷ 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 200B ÷ 0308 × 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 200B × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200B × 0020 × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200B ÷ 0308 × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200B ÷ 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200B × 0020 ÷ 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200B ÷ 0308 × 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200B ÷ 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200B × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200B ÷ 0308 × 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200B ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200B × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200B ÷ 0308 ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200B ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200B × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200B ÷ 0308 ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200B ÷ 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200B × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200B ÷ 0308 × 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200B ÷ 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200B × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200B ÷ 0308 × 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200B ÷ 231A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] WATCH (ID) ÷ [0.3]
+× 200B × 0020 ÷ 231A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] WATCH (ID) ÷ [0.3]
+× 200B ÷ 0308 ÷ 231A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 200B ÷ 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200B × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200B ÷ 0308 × 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200B ÷ 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMMA (IS) ÷ [0.3]
+× 200B × 0020 ÷ 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] COMMA (IS) ÷ [0.3]
+× 200B ÷ 0308 × 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 200B ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200B × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200B ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200B × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200B ÷ 0308 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200B ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200B × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200B × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200B × 0020 × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200B ÷ 0308 × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200B × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200B × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200B ÷ 0308 × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200B ÷ 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200B × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200B ÷ 0308 × 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200B ÷ 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] DIGIT ZERO (NU) ÷ [0.3]
+× 200B × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] DIGIT ZERO (NU) ÷ [0.3]
+× 200B ÷ 0308 × 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 200B ÷ 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 200B × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 200B ÷ 0308 × 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 200B ÷ 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] PERCENT SIGN (PO) ÷ [0.3]
+× 200B × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] PERCENT SIGN (PO) ÷ [0.3]
+× 200B ÷ 0308 × 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 200B ÷ 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 200B × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 200B ÷ 0308 × 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 200B ÷ 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] QUOTATION MARK (QU) ÷ [0.3]
+× 200B × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] QUOTATION MARK (QU) ÷ [0.3]
+× 200B ÷ 0308 × 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 200B × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [0.3]
+× 200B × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 200B ÷ 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] SOLIDUS (SY) ÷ [0.3]
+× 200B × 0020 ÷ 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] SOLIDUS (SY) ÷ [0.3]
+× 200B ÷ 0308 × 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 200B ÷ 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] WORD JOINER (WJ) ÷ [0.3]
+× 200B × 0020 ÷ 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] WORD JOINER (WJ) ÷ [0.3]
+× 200B ÷ 0308 × 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 200B × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200B × 0020 × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200B ÷ 0308 × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200B ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200B × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200B ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200B × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200B ÷ 0308 ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200B ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200B × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200B ÷ 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200B × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200B ÷ 0308 × 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200B ÷ 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200B × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200B ÷ 0308 × 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200B ÷ 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200B × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200B ÷ 0308 × 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200B ÷ 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200B × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200B ÷ 0308 × 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200B ÷ 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200B × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200B ÷ 0308 × 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200B ÷ 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200B × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200B ÷ 0308 × 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F1E6 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F1E6 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1F1E6 × 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F1E6 × 0308 × 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F1E6 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F1E6 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F1E6 × 0020 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F1E6 × 0308 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F1E6 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F1E6 × 0020 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F1E6 × 0308 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F1E6 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F1E6 × 0020 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F1E6 × 0308 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F1E6 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1F1E6 × 0020 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1F1E6 × 0308 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1F1E6 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F1E6 × 0020 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F1E6 × 0308 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F1E6 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F1E6 × 0020 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F1E6 × 0308 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F1E6 × 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F1E6 × 0308 × 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F1E6 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F1E6 × 0020 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F1E6 × 0308 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F1E6 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F1E6 × 0020 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F1E6 × 0308 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F1E6 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F1E6 × 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F1E6 × 0308 × 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F1E6 ÷ 231A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 231A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 231A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 231A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 1F1E6 ÷ 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F1E6 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F1E6 × 0020 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F1E6 × 0308 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F1E6 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F1E6 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F1E6 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F1E6 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F1E6 × 0020 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F1E6 × 0308 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F1E6 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F1E6 × 0020 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F1E6 × 0308 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F1E6 × 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F1E6 × 0308 × 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F1E6 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F1E6 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1F1E6 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F1E6 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F1E6 × 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1F1E6 × 0308 × 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1F1E6 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F1E6 × 0020 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F1E6 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F1E6 × 0020 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F1E6 × 0308 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F1E6 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F1E6 × 0020 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F1E6 × 0308 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F1E6 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F1E6 × 0020 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F1E6 × 0308 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F1E6 × 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F1E6 × 0308 × 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.11] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F1E6 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F1E6 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F1E6 × 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F1E6 × 0308 × 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F1E6 × 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F1E6 × 0308 × 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F1E6 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F1E6 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F1E6 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F1E6 × 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F1E6 × 0308 × 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 261D ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 261D × 0020 ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 261D × 0308 ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 261D ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 261D × 0020 ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 261D × 0308 ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 261D × 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 261D × 0020 ÷ 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 261D × 0308 × 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 261D ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 261D × 0020 ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 261D × 0308 ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 261D × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 261D × 0020 × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 261D × 0308 × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 261D × 0308 × 0020 × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 261D ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 261D × 0020 ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 261D × 0308 ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 261D × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 261D × 0020 × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 261D × 0308 × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 261D × 0308 × 0020 × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 261D × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 261D × 0020 × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 261D × 0308 × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 261D × 0308 × 0020 × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 261D × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 261D × 0020 × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 261D × 0308 × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 261D × 0308 × 0020 × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 261D × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 261D × 0020 × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 261D × 0308 × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 261D × 0308 × 0020 × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 261D × 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 261D × 0020 ÷ 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 261D × 0308 × 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 261D ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 261D × 0020 ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 261D × 0308 ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 261D ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 261D × 0020 ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 261D × 0308 ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 261D ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 261D × 0020 ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 261D × 0308 ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 261D × 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 261D × 0020 ÷ 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 261D × 0308 × 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 261D ÷ 231A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 261D × 0020 ÷ 231A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 261D × 0308 ÷ 231A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 231A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 261D × 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
+× 261D × 0020 ÷ 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 261D × 0308 × 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 261D × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] COMMA (IS) ÷ [0.3]
+× 261D × 0020 × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 261D × 0308 × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 261D × 0308 × 0020 × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 261D ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 261D × 0020 ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 261D × 0308 ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 261D ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 261D × 0020 ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 261D × 0308 ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 261D ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 261D × 0020 ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 261D × 0308 ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 261D × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 261D × 0020 × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 261D × 0308 × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 261D × 0308 × 0020 × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 261D × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 261D × 0020 × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 261D × 0308 × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 261D × 0308 × 0020 × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 261D × 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 261D × 0020 ÷ 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 261D × 0308 × 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 261D ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 261D × 0020 ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 261D × 0308 ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 261D ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 261D × 0020 ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 261D × 0308 ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 261D × 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 261D × 0020 ÷ 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 261D × 0308 × 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 261D ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 261D × 0020 ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 261D × 0308 ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 261D × 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 261D × 0020 ÷ 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 261D × 0308 × 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 261D × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [0.3]
+× 261D × 0020 × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 261D × 0308 × 0020 × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 261D × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 261D × 0020 × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 261D × 0308 × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 261D × 0308 × 0020 × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 261D × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 261D × 0020 × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 261D × 0308 × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 261D × 0308 × 0020 × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 261D × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 261D × 0020 × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 261D × 0308 × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 261D × 0308 × 0020 × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 261D ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 261D × 0020 ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 261D × 0308 ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 261D ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 261D × 0020 ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 261D × 0308 ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 261D × 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [30.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 261D × 0020 ÷ 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 261D × 0308 × 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 261D × 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 261D × 0020 ÷ 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 261D × 0308 × 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 261D × 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 261D × 0020 ÷ 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 261D × 0308 × 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 261D ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 261D × 0020 ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 261D × 0308 ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 261D ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 261D × 0020 ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 261D × 0308 ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 261D ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 261D × 0020 ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 261D × 0308 ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 261D × 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 261D × 0020 ÷ 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 261D × 0308 × 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F3FB ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F3FB ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1F3FB × 0020 ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1F3FB × 0308 ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1F3FB × 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F3FB × 0308 × 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F3FB ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F3FB × 0020 ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F3FB × 0308 ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F3FB × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F3FB × 0020 × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F3FB × 0308 × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F3FB ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F3FB × 0020 ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F3FB × 0308 ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F3FB × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F3FB × 0020 × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F3FB × 0308 × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F3FB × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1F3FB × 0020 × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1F3FB × 0308 × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 1F3FB × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F3FB × 0020 × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F3FB × 0308 × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F3FB × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F3FB × 0020 × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F3FB × 0308 × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F3FB × 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F3FB × 0308 × 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F3FB ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F3FB × 0020 ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F3FB × 0308 ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F3FB ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F3FB × 0020 ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F3FB × 0308 ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F3FB ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F3FB × 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F3FB × 0020 ÷ 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F3FB × 0308 × 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F3FB ÷ 231A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 1F3FB × 0020 ÷ 231A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 1F3FB × 0308 ÷ 231A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 231A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 1F3FB × 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F3FB × 0020 ÷ 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F3FB × 0308 × 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F3FB × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F3FB × 0020 × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F3FB × 0308 × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F3FB ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F3FB ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F3FB × 0020 ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F3FB × 0308 ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F3FB ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F3FB × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F3FB × 0020 × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F3FB × 0308 × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F3FB × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F3FB × 0020 × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F3FB × 0308 × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F3FB × 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F3FB × 0020 ÷ 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F3FB × 0308 × 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F3FB ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F3FB × 0308 ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F3FB ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1F3FB × 0308 ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 1F3FB × 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F3FB × 0308 × 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F3FB ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F3FB × 0308 ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F3FB × 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1F3FB × 0308 × 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1F3FB × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F3FB × 0020 × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F3FB × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F3FB × 0020 × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F3FB × 0308 × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F3FB × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F3FB × 0020 × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F3FB × 0308 × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F3FB × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F3FB × 0020 × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F3FB × 0308 × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F3FB ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F3FB ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F3FB × 0020 ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F3FB × 0308 ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F3FB ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F3FB × 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F3FB × 0308 × 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F3FB × 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F3FB × 0020 ÷ 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F3FB × 0308 × 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F3FB ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F3FB ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F3FB ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F3FB × 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F3FB × 0020 ÷ 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F3FB × 0308 × 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0001 × 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0001 × 0020 ÷ 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0001 × 0308 × 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0001 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0001 × 0020 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0001 × 0308 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0001 × 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0001 × 0020 ÷ 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0001 × 0308 × 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0001 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0001 × 0020 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0001 × 0308 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0001 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0001 × 0020 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0001 × 0308 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0001 × 0308 × 0020 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0001 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0001 × 0020 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0001 × 0308 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0001 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0001 × 0020 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0001 × 0308 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0001 × 0308 × 0020 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0001 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0001 × 0020 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0001 × 0308 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0001 × 0308 × 0020 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0001 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0001 × 0020 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0001 × 0308 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0001 × 0308 × 0020 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0001 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0001 × 0020 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0001 × 0308 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0001 × 0308 × 0020 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0001 × 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0001 × 0020 ÷ 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0001 × 0308 × 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0001 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0001 × 0020 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0001 × 0308 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0001 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0001 × 0020 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0001 × 0308 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0001 × 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0001 × 0020 ÷ 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0001 × 0308 × 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0001 × 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0001 × 0020 ÷ 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0001 × 0308 × 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0001 ÷ 231A ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0001 × 0020 ÷ 231A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0001 × 0308 ÷ 231A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 231A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0001 × 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 0001 × 0020 ÷ 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0001 × 0308 × 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0001 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] COMMA (IS) ÷ [0.3]
+× 0001 × 0020 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0001 × 0308 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] COMMA (IS) ÷ [0.3]
+× 0001 × 0308 × 0020 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0001 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0001 × 0020 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0001 × 0308 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0001 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0001 × 0020 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0001 × 0308 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0001 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0001 × 0020 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0001 × 0308 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0001 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0001 × 0020 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0001 × 0308 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0001 × 0308 × 0020 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0001 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0001 × 0020 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0001 × 0308 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0001 × 0308 × 0020 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0001 × 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0001 × 0020 ÷ 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0001 × 0308 × 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0001 × 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0001 × 0020 ÷ 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0001 × 0308 × 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0001 × 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0001 × 0020 ÷ 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0001 × 0308 × 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0001 × 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0001 × 0020 ÷ 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0001 × 0308 × 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0001 × 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0001 × 0020 ÷ 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0001 × 0308 × 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0001 × 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0001 × 0020 ÷ 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0001 × 0308 × 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0001 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0001 × 0020 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0001 × 0308 × 0020 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0001 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
+× 0001 × 0020 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0001 × 0308 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
+× 0001 × 0308 × 0020 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0001 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0001 × 0020 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0001 × 0308 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0001 × 0308 × 0020 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0001 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0001 × 0020 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0001 × 0308 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0001 × 0308 × 0020 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0001 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0001 × 0020 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0001 × 0308 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0001 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0001 × 0020 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0001 × 0308 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0001 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0001 × 0020 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0001 × 0308 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0001 × 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0001 × 0020 ÷ 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0001 × 0308 × 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0001 × 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0001 × 0020 ÷ 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0001 × 0308 × 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0001 × 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0001 × 0020 ÷ 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0001 × 0308 × 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0001 × 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0001 × 0020 ÷ 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0001 × 0308 × 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0001 × 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0001 × 0020 ÷ 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0001 × 0308 × 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0001 × 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0001 × 0020 ÷ 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0001 × 0308 × 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200D × 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200D × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200D × 0308 × 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200D ÷ 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 200D × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 200D × 0308 ÷ 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 200D × 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200D × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200D × 0308 × 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200D ÷ 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200D × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200D × 0308 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200D × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200D × 0020 × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200D × 0308 × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200D × 0308 × 0020 × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200D ÷ FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200D × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200D × 0308 ÷ FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200D × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200D × 0020 × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200D × 0308 × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200D × 0308 × 0020 × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200D × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 200D × 0020 × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 200D × 0308 × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 200D × 0308 × 0020 × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 200D × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200D × 0020 × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200D × 0308 × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200D × 0308 × 0020 × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200D × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200D × 0020 × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200D × 0308 × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200D × 0308 × 0020 × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200D × 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D × 0308 × 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D ÷ AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200D × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200D × 0308 ÷ AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200D ÷ AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200D × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200D × 0308 ÷ AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200D × 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200D × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200D × 0308 × 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200D × 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200D × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200D × 0308 × 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200D × 231A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] WATCH (ID) ÷ [0.3]
+× 200D × 0020 ÷ 231A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 200D × 0308 ÷ 231A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 231A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 200D × 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 200D × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200D × 0308 × 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200D × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.04] COMMA (IS) ÷ [0.3]
+× 200D × 0020 × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 200D × 0308 × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] COMMA (IS) ÷ [0.3]
+× 200D × 0308 × 0020 × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 200D ÷ 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200D × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200D × 0308 ÷ 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200D ÷ 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200D × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200D × 0308 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200D ÷ 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200D × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200D × 0308 ÷ 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200D × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200D × 0020 × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200D × 0308 × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200D × 0308 × 0020 × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200D × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200D × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200D × 0308 × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200D × 0308 × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200D × 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200D × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200D × 0308 × 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200D × 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 200D × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 200D × 0308 × 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 200D × 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 200D × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 200D × 0308 × 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 200D × 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 200D × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 200D × 0308 × 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 200D × 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 200D × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 200D × 0308 × 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 200D × 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 200D × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 200D × 0308 × 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 200D × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 200D × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 200D × 0308 × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 200D × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
+× 200D × 0020 × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 200D × 0308 × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
+× 200D × 0308 × 0020 × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 200D × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 200D × 0020 × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 200D × 0308 × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 200D × 0308 × 0020 × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 200D × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200D × 0020 × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200D × 0308 × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200D × 0308 × 0020 × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200D ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200D × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200D × 0308 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200D × 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200D × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200D × 0308 ÷ 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200D × 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200D × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200D × 0308 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200D × 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200D × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200D × 0308 × 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200D × 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200D × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200D × 0308 × 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200D × 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200D × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200D × 0308 × 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200D × 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200D × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200D × 0308 × 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200D × 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200D × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200D × 0308 × 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200D × 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200D × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200D × 0308 × 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A7 × 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A7 × 0020 ÷ 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A7 × 0308 × 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A7 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 00A7 × 0020 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00A7 × 0308 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00A7 × 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A7 × 0020 ÷ 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A7 × 0308 × 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A7 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A7 × 0020 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A7 × 0308 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A7 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A7 × 0020 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A7 × 0308 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A7 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A7 × 0020 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A7 × 0308 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A7 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A7 × 0020 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A7 × 0308 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A7 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00A7 × 0020 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00A7 × 0308 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 00A7 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A7 × 0020 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A7 × 0308 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A7 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A7 × 0020 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A7 × 0308 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A7 × 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A7 × 0020 ÷ 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A7 × 0308 × 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A7 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A7 × 0020 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A7 × 0308 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A7 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A7 × 0020 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A7 × 0308 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A7 × 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A7 × 0020 ÷ 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A7 × 0308 × 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A7 × 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A7 × 0020 ÷ 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A7 × 0308 × 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A7 ÷ 231A ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 00A7 × 0020 ÷ 231A ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 00A7 × 0308 ÷ 231A ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 231A ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 00A7 × 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A7 × 0020 ÷ 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A7 × 0308 × 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A7 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] COMMA (IS) ÷ [0.3]
+× 00A7 × 0020 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00A7 × 0308 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00A7 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A7 × 0020 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A7 × 0308 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A7 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A7 × 0020 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A7 × 0308 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A7 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A7 × 0020 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A7 × 0308 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A7 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A7 × 0020 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A7 × 0308 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A7 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A7 × 0020 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A7 × 0308 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A7 × 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A7 × 0020 ÷ 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A7 × 0308 × 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A7 × 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 00A7 × 0020 ÷ 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A7 × 0308 × 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A7 × 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00A7 × 0020 ÷ 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00A7 × 0308 × 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 00A7 × 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 00A7 × 0020 ÷ 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A7 × 0308 × 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A7 × 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A7 × 0020 ÷ 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A7 × 0308 × 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A7 × 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 00A7 × 0020 ÷ 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A7 × 0308 × 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A7 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A7 × 0020 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A7 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00A7 × 0020 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00A7 × 0308 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00A7 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A7 × 0020 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A7 × 0308 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A7 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A7 × 0020 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A7 × 0308 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A7 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A7 × 0020 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A7 × 0308 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A7 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A7 × 0020 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A7 × 0308 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A7 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A7 × 0020 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A7 × 0308 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A7 × 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A7 × 0020 ÷ 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A7 × 0308 × 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A7 × 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A7 × 0020 ÷ 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A7 × 0308 × 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A7 × 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A7 × 0020 ÷ 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A7 × 0308 × 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A7 × 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A7 × 0020 ÷ 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A7 × 0308 × 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A7 × 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A7 × 0020 ÷ 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A7 × 0308 × 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A7 × 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A7 × 0020 ÷ 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A7 × 0308 × 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 50005 × 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 50005 × 0020 ÷ 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 50005 × 0308 × 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 50005 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 50005 × 0020 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 50005 × 0308 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 50005 × 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 50005 × 0020 ÷ 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 50005 × 0308 × 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 50005 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 50005 × 0020 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 50005 × 0308 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 50005 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 50005 × 0020 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 50005 × 0308 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 50005 × 0308 × 0020 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 50005 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 50005 × 0020 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 50005 × 0308 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 50005 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 50005 × 0020 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 50005 × 0308 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 50005 × 0308 × 0020 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 50005 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 50005 × 0020 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 50005 × 0308 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 50005 × 0308 × 0020 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 50005 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 50005 × 0020 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 50005 × 0308 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 50005 × 0308 × 0020 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 50005 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 50005 × 0020 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 50005 × 0308 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 50005 × 0308 × 0020 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 50005 × 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 50005 × 0020 ÷ 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 50005 × 0308 × 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 50005 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 50005 × 0020 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 50005 × 0308 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 50005 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 50005 × 0020 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 50005 × 0308 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 50005 × 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 50005 × 0020 ÷ 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 50005 × 0308 × 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 50005 × 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 50005 × 0020 ÷ 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 50005 × 0308 × 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 50005 ÷ 231A ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 50005 × 0020 ÷ 231A ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 50005 × 0308 ÷ 231A ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 231A ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 50005 × 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 50005 × 0020 ÷ 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 50005 × 0308 × 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 50005 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] COMMA (IS) ÷ [0.3]
+× 50005 × 0020 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 50005 × 0308 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 50005 × 0308 × 0020 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 50005 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 50005 × 0020 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 50005 × 0308 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 50005 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 50005 × 0020 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 50005 × 0308 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 50005 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 50005 × 0020 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 50005 × 0308 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 50005 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 50005 × 0020 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 50005 × 0308 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 50005 × 0308 × 0020 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 50005 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 50005 × 0020 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 50005 × 0308 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 50005 × 0308 × 0020 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 50005 × 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 50005 × 0020 ÷ 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 50005 × 0308 × 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 50005 × 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 50005 × 0020 ÷ 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 50005 × 0308 × 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 50005 × 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 50005 × 0020 ÷ 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 50005 × 0308 × 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 50005 × 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 50005 × 0020 ÷ 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 50005 × 0308 × 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 50005 × 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 50005 × 0020 ÷ 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 50005 × 0308 × 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 50005 × 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 50005 × 0020 ÷ 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 50005 × 0308 × 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 50005 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 50005 × 0020 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 50005 × 0308 × 0020 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 50005 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 50005 × 0020 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 50005 × 0308 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 50005 × 0308 × 0020 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 50005 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 50005 × 0020 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 50005 × 0308 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 50005 × 0308 × 0020 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 50005 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 50005 × 0020 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 50005 × 0308 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 50005 × 0308 × 0020 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 50005 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 50005 × 0020 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 50005 × 0308 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 50005 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 50005 × 0020 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 50005 × 0308 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 50005 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 50005 × 0020 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 50005 × 0308 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 50005 × 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 50005 × 0020 ÷ 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 50005 × 0308 × 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 50005 × 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 50005 × 0020 ÷ 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 50005 × 0308 × 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 50005 × 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 50005 × 0020 ÷ 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 50005 × 0308 × 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 50005 × 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 50005 × 0020 ÷ 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 50005 × 0308 × 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 50005 × 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 50005 × 0020 ÷ 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 50005 × 0308 × 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 50005 × 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 50005 × 0020 ÷ 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 50005 × 0308 × 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0E01 × 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0E01 × 0020 ÷ 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0E01 × 0308 × 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0E01 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0E01 × 0020 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0E01 × 0308 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0E01 × 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0E01 × 0020 ÷ 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0E01 × 0308 × 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0E01 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0E01 × 0020 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0E01 × 0308 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0E01 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0E01 × 0020 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0E01 × 0308 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0E01 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0E01 × 0020 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0E01 × 0308 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0E01 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0E01 × 0020 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0E01 × 0308 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0E01 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0E01 × 0020 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0E01 × 0308 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0E01 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0E01 × 0020 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0E01 × 0308 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0E01 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0E01 × 0020 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0E01 × 0308 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0E01 × 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0E01 × 0020 ÷ 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0E01 × 0308 × 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0E01 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0E01 × 0020 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0E01 × 0308 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0E01 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0E01 × 0020 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0E01 × 0308 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0E01 × 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0E01 × 0020 ÷ 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0E01 × 0308 × 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0E01 × 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0E01 × 0020 ÷ 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0E01 × 0308 × 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0E01 ÷ 231A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0E01 × 0020 ÷ 231A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0E01 × 0308 ÷ 231A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 231A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 0E01 × 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 0E01 × 0020 ÷ 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0E01 × 0308 × 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0E01 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] COMMA (IS) ÷ [0.3]
+× 0E01 × 0020 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0E01 × 0308 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0E01 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0E01 × 0020 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0E01 × 0308 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0E01 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0E01 × 0020 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0E01 × 0308 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0E01 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0E01 × 0020 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0E01 × 0308 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0E01 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0E01 × 0020 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0E01 × 0308 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0E01 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0E01 × 0020 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0E01 × 0308 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0E01 × 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0E01 × 0020 ÷ 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0E01 × 0308 × 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0E01 × 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0E01 × 0020 ÷ 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0E01 × 0308 × 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0E01 × 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0E01 × 0020 ÷ 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0E01 × 0308 × 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 0E01 × 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0E01 × 0020 ÷ 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0E01 × 0308 × 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0E01 × 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0E01 × 0020 ÷ 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0E01 × 0308 × 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0E01 × 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0E01 × 0020 ÷ 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0E01 × 0308 × 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0E01 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 0E01 × 0020 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0E01 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0E01 × 0020 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0E01 × 0308 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0E01 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0E01 × 0020 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0E01 × 0308 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0E01 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0E01 × 0020 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0E01 × 0308 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0E01 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0E01 × 0020 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0E01 × 0308 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0E01 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0E01 × 0020 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0E01 × 0308 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0E01 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0E01 × 0020 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0E01 × 0308 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0E01 × 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0E01 × 0020 ÷ 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0E01 × 0308 × 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0E01 × 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0E01 × 0020 ÷ 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0E01 × 0308 × 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0E01 × 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0E01 × 0020 ÷ 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0E01 × 0308 × 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0E01 × 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0E01 × 0020 ÷ 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0E01 × 0308 × 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0E01 × 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0E01 × 0020 ÷ 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0E01 × 0308 × 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0E01 × 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0E01 × 0020 ÷ 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0E01 × 0308 × 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 3041 × 0020 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 3041 × 0308 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 3041 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 3041 × 0020 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 3041 × 0308 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 3041 × 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 3041 × 0020 ÷ 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 3041 × 0308 × 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 3041 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 3041 × 0020 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 3041 × 0308 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 3041 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 3041 × 0020 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 3041 × 0308 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 3041 × 0308 × 0020 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 3041 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 3041 × 0020 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 3041 × 0308 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 3041 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 3041 × 0020 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 3041 × 0308 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 3041 × 0308 × 0020 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 3041 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 3041 × 0020 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 3041 × 0308 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 3041 × 0308 × 0020 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 3041 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 3041 × 0020 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 3041 × 0308 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 3041 × 0308 × 0020 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 3041 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 3041 × 0020 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 3041 × 0308 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 3041 × 0308 × 0020 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 3041 × 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 3041 × 0020 ÷ 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 3041 × 0308 × 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 3041 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 3041 × 0020 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 3041 × 0308 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 3041 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 3041 × 0020 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 3041 × 0308 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 3041 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 3041 × 0020 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 3041 × 0308 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 3041 × 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 3041 × 0020 ÷ 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 3041 × 0308 × 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 3041 ÷ 231A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 3041 × 0020 ÷ 231A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 3041 × 0308 ÷ 231A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
+× 3041 ÷ 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 3041 × 0020 ÷ 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 3041 × 0308 ÷ 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 3041 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] COMMA (IS) ÷ [0.3]
+× 3041 × 0020 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 3041 × 0308 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 3041 × 0308 × 0020 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 3041 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 3041 × 0020 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 3041 × 0308 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 3041 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 3041 × 0020 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 3041 × 0308 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 3041 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 3041 × 0020 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 3041 × 0308 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 3041 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 3041 × 0020 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 3041 × 0308 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 3041 × 0308 × 0020 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 3041 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 3041 × 0020 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 3041 × 0308 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 3041 × 0308 × 0020 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 3041 × 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 3041 × 0020 ÷ 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 3041 × 0308 × 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 3041 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 3041 × 0020 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 3041 × 0308 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 3041 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 3041 × 0020 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 3041 × 0308 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
+× 3041 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 3041 × 0020 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 3041 × 0308 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 3041 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 3041 × 0020 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 3041 × 0308 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 3041 × 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 3041 × 0020 ÷ 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 3041 × 0308 × 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 3041 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [0.3]
+× 3041 × 0020 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 3041 × 0308 × 0020 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 3041 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 3041 × 0020 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 3041 × 0308 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 3041 × 0308 × 0020 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 3041 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 3041 × 0020 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 3041 × 0308 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 3041 × 0308 × 0020 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 3041 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 3041 × 0020 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 3041 × 0308 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 3041 × 0308 × 0020 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 3041 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 3041 × 0020 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 3041 × 0308 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 3041 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 3041 × 0020 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 3041 × 0308 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 3041 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 3041 × 0020 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 3041 × 0308 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 3041 × 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 3041 × 0020 ÷ 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 3041 × 0308 × 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 3041 × 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 3041 × 0020 ÷ 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 3041 × 0308 × 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 3041 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 3041 × 0020 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 3041 × 0308 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 3041 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 3041 × 0020 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 3041 × 0308 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 3041 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 3041 × 0020 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 3041 × 0308 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 3041 × 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 × 0020 ÷ 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 × 0308 × 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D × 000A ÷ 0061 × 000A ÷ 0308 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) × [5.01] <LINE FEED (LF)> (LF) ÷ [5.03] LATIN SMALL LETTER A (AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [0.3]
+× 0061 × 0308 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [0.3]
+× 0020 ÷ 200D × 0646 ÷ # × [0.3] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] ARABIC LETTER NOON (AL) ÷ [0.3]
+× 0646 × 200D × 0020 ÷ # × [0.3] ARABIC LETTER NOON (AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 000B ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0085 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200D × 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 3041 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2060 × 3041 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 × 0308 × 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D × 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
+× 2014 × 2014 ÷ # × [0.3] EM DASH (B2) × [17.0] EM DASH (B2) ÷ [0.3]
+× 3041 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× FFFC ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 × 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0E01 × 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 0021 × 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [22.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 2024 × 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [22.04] ONE DOT LEADER (IN) ÷ [0.3]
+× 0030 × 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [22.05] ONE DOT LEADER (IN) ÷ [0.3]
+× 261D × 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 0E01 × 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0024 × 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0024 × 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0025 × 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1100 × 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1160 × 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11A8 × 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1160 × 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
+× 1160 × 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
+× 0024 × 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 261D × 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [30.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0066 × 0069 × 006E × 0061 × 006C ÷ # × [0.3] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER L (AL) ÷ [0.3]
+× 0063 × 0061 × 006E × 0027 × 0074 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [19.01] APOSTROPHE (QU) × [19.02] LATIN SMALL LETTER T (AL) ÷ [0.3]
+× 0063 × 0061 × 006E × 2019 × 0074 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [19.01] RIGHT SINGLE QUOTATION MARK (QU) × [19.02] LATIN SMALL LETTER T (AL) ÷ [0.3]
+× 0027 × 0063 × 0061 × 006E × 0027 × 0020 ÷ 006E × 006F × 0074 ÷ # × [0.3] APOSTROPHE (QU) × [19.02] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [19.01] APOSTROPHE (QU) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER T (AL) ÷ [0.3]
+× 0063 × 0061 × 006E × 0020 ÷ 0027 × 006E × 006F × 0074 × 0027 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] APOSTROPHE (QU) × [19.02] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER T (AL) × [19.01] APOSTROPHE (QU) ÷ [0.3]
+× 0062 × 0075 × 0067 × 0028 × 0073 × 0029 × 0020 × 0020 × 0020 × 0020 × 0020 ÷ # × [0.3] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER G (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0062 × 0075 × 0067 × 0028 × 0073 × 0029 × 00A0 × 0020 × 0020 × 0020 × 0020 × 0020 ÷ # × [0.3] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER G (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [12.1] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002E × 002E ÷ 307E ÷ 3059 × 3002 ÷ 0058 × 004D × 004C ÷ 306E × 002E × 002E ÷ # × [0.3] FULL STOP (IS) × [13.02] FULL STOP (IS) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [999.0] HIRAGANA LETTER SU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN CAPITAL LETTER X (AL) × [28.0] LATIN CAPITAL LETTER M (AL) × [28.0] LATIN CAPITAL LETTER L (AL) ÷ [999.0] HIRAGANA LETTER NO (ID) × [13.02] FULL STOP (IS) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 0061 × 0062 × 00AD ÷ 0062 × 0079 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER Y (AL) ÷ [0.3]
+× 002D × 0033 ÷ # × [0.3] HYPHEN-MINUS (HY) × [25.02] DIGIT THREE (NU) ÷ [0.3]
+× 0065 × 002E × 0067 × 002E ÷ # × [0.3] LATIN SMALL LETTER E (AL) × [13.02] FULL STOP (IS) × [29.0] LATIN SMALL LETTER G (AL) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 4E00 × 002E ÷ 4E00 × 002E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4E00 (ID) × [13.02] FULL STOP (IS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4E00 (ID) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 0061 × 0020 × 0020 ÷ 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
+× 0061 × 0020 × 0020 × 200B ÷ 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [8.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
+× 0061 × 0020 ÷ 0308 × 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
+× 0031 × 0308 × 0062 × 0028 × 0061 × 0029 × 002D ÷ 0028 × 0062 × 0029 ÷ # × [0.3] DIGIT ONE (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] LATIN SMALL LETTER B (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER A (AL) × [13.02] RIGHT PARENTHESIS (CP) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER B (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0067 × 0069 × 0076 × 0065 × 0020 ÷ 0062 × 006F × 006F × 006B × 0028 × 0073 × 0029 × 002E ÷ # × [0.3] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER K (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 307E ÷ 0028 × 3059 × 0029 ÷ # × [0.3] HIRAGANA LETTER MA (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER SU (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0066 × 0069 × 006E × 0064 × 0020 × 002E × 0063 × 006F × 006D ÷ # × [0.3] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER D (AL) × [7.01] SPACE (SP) × [13.02] FULL STOP (IS) × [29.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER M (AL) ÷ [0.3]
+× 0065 × 0071 × 0075 × 0061 × 006C × 0073 × 0020 × 002E ÷ 0033 × 0035 × 0020 ÷ 0063 × 0065 × 006E × 0074 × 0073 ÷ # × [0.3] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER Q (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT THREE (NU) × [25.03] DIGIT FIVE (NU) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER S (AL) ÷ [0.3]
+× 0028 × 0073 × 0029 × 0068 × 0065 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E (AL) ÷ [0.3]
+× 007B × 0073 × 007D ÷ 0068 × 0065 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E (AL) ÷ [0.3]
+× 02C8 × 0073 × 0049 × 006C × 0259 × 0062 × 0028 × 0259 × 0029 × 006C ÷ # × [0.3] MODIFIER LETTER VERTICAL LINE (BB) × [21.04] LATIN SMALL LETTER S (AL) × [28.0] LATIN CAPITAL LETTER I (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER SCHWA (AL) × [28.0] LATIN SMALL LETTER B (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER SCHWA (AL) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER L (AL) ÷ [0.3]
+× 02C8 × 0073 × 0049 × 006C × 0259 × 0062 × 007B × 0259 × 007D ÷ 006C ÷ # × [0.3] MODIFIER LETTER VERTICAL LINE (BB) × [21.04] LATIN SMALL LETTER S (AL) × [28.0] LATIN CAPITAL LETTER I (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER SCHWA (AL) × [28.0] LATIN SMALL LETTER B (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER SCHWA (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 0029 × 002E ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 002E × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] FULL STOP (IS) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 0029 × 0021 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 0021 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.01] EXCLAMATION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 005C ÷ 0028 × 0073 × 005C × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [24.03] REVERSE SOLIDUS (PR) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [24.03] REVERSE SOLIDUS (PR) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 0028 × 0020 × 0073 × 0020 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 007B × 0073 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 007B × 0073 × 007D × 002E ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 007B × 0073 × 007D × 0021 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 005C ÷ 007B × 0073 × 005C × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [24.03] REVERSE SOLIDUS (PR) ÷ [999.0] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [24.03] REVERSE SOLIDUS (PR) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 007B × 0020 × 0073 × 0020 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP) × [7.01] SPACE (SP) × [14.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0063 × 006F × 0064 × 0028 × 0065 × 0029 ÷ 2026 ÷ 0028 × 0073 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HORIZONTAL ELLIPSIS (IN) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0028 × 0063 × 006F × 0064 × 0028 × 0065 × 0029 ÷ 2026 × 0029 × 0073 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HORIZONTAL ELLIPSIS (IN) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER S (AL) ÷ [0.3]
+× 0063 × 006F × 0064 × 007B × 0065 × 007D ÷ 2026 ÷ 007B × 0073 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] HORIZONTAL ELLIPSIS (IN) ÷ [999.0] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 007B × 0063 × 006F × 0064 × 007B × 0065 × 007D ÷ 2026 × 007D ÷ 0073 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] HORIZONTAL ELLIPSIS (IN) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER S (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 002D × 0029 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 00AD × 0029 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 2011 × 0029 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 0029 × 002D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT PARENTHESIS (CP) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 0029 × 00AD ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT PARENTHESIS (CP) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 0029 × 2011 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT PARENTHESIS (CP) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 002D × 007D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 00AD × 007D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 2011 × 007D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 007D × 002D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 007D × 00AD ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 007D × 2011 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0063 × 0072 × 0065 × 0301 × 0028 × 0065 × 0301 × 0029 ÷ 0028 × 0065 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0063 × 0072 × 0065 × 0301 × 005B × 0065 × 0072 × 007C ÷ 0065 × 0301 × 0028 × 0065 × 0029 ÷ 0028 × 0073 × 0029 × 005D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT SQUARE BRACKET (OP) × [14.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [21.01] VERTICAL LINE (BA) ÷ [999.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT SQUARE BRACKET (CP) ÷ [0.3]
+× 0063 × 0072 × 0065 × 0301 × 007B × 0065 × 0072 × 007C ÷ 0065 × 0301 × 0028 × 0065 × 0029 ÷ 0028 × 0073 × 0029 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [21.01] VERTICAL LINE (BA) ÷ [999.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 0028 × 0308 × 0029 ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 0028 × 00AB × 0308 × 00BB × 0029 ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 0028 × 00AB × 0020 ÷ 0308 × 0020 ÷ 00BB × 0029 ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 0020 × 0028 × 0020 × 0308 × 0020 × 0029 × 0020 ÷ 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [7.01] SPACE (SP) × [15.0] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [15.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 202F × 0028 × 0020 × 0308 × 0020 × 0029 × 202F × 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [15.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 007B × 0308 × 007D ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT CURLY BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 007B × 00AB × 0308 × 00BB × 007D ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 007B × 00AB × 0020 ÷ 0308 × 0020 ÷ 00BB × 007D ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 0020 × 007B × 0020 × 0308 × 0020 × 007D × 0020 ÷ 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [7.01] SPACE (SP) × [15.0] LEFT CURLY BRACKET (OP) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [15.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 202F × 007B × 0020 × 0308 × 0020 × 007D × 202F × 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] LEFT CURLY BRACKET (OP) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [15.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 0028 × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD ÷ 2011 × 0029 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 0028 × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD × 0029 × 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT PARENTHESIS (CP) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 0028 × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 0029 × 00AD ÷ 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [13.02] RIGHT PARENTHESIS (CP) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 007B × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD ÷ 2011 × 007D ÷ 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 007B × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD × 007D × 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT CURLY BRACKET (CL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 007B × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 007D × 00AD ÷ 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 006F × 0070 × 0065 × 0072 × 0061 × 0074 × 006F × 0072 × 005B × 005D ÷ 0028 × 0030 × 0029 × 003B ÷ # × [0.3] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [30.01] LEFT SQUARE BRACKET (OP) × [13.02] RIGHT SQUARE BRACKET (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] DIGIT ZERO (NU) × [25.04] RIGHT PARENTHESIS (CP) × [13.02] SEMICOLON (IS) ÷ [0.3]
+× 006F × 0070 × 0065 × 0072 × 0061 × 0074 × 006F × 0072 × 005B × 005D ÷ 0028 × 0029 ÷ 007B × 007D ÷ # × [0.3] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [30.01] LEFT SQUARE BRACKET (OP) × [13.02] RIGHT SQUARE BRACKET (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT CURLY BRACKET (OP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 672C ÷ 0028 × 3092 × 0029 ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 672C ÷ 0028 × 300C × 3092 × 300D × 0029 ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 672C ÷ 300C × 0028 × 3092 × 0029 × 300D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 672C ÷ 007B × 3092 × 007D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT CURLY BRACKET (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 672C ÷ 007B × 300C × 3092 × 300D × 007D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT CURLY BRACKET (OP) × [14.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 672C ÷ 005B × 0028 × 3092 × 0029 × 005D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT SQUARE BRACKET (OP) × [14.0] LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT SQUARE BRACKET (CP) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 0028 × 30CB × 30E5 × 30FC × 30FB × 0029 ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 0028 × 30CB × 30E5 × 30FC × 0029 × 30FB ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [13.02] RIGHT PARENTHESIS (CP) × [16.0] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 007B × 30CB × 30E5 × 30FC × 30FB × 007D ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 007B × 30CB × 30E5 × 30FC × 007D × 30FB ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [13.02] RIGHT CURLY BRACKET (CL) × [16.0] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 0028 × 1850 × 1846 × 1851 × 1846 ÷ 1806 × 0029 × 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
+× 0028 × 1850 × 1846 × 1851 × 1846 × 0029 ÷ 1806 × 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [21.04] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
+× 007B × 1850 × 1846 × 1851 × 1846 ÷ 1806 × 007D ÷ 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
+× 007B × 1850 × 1846 × 1851 × 1846 × 007D ÷ 1806 × 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [21.04] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
+× 0028 × 0068 × 0074 × 0074 × 0070 × 003A × 002F × 002F × 0029 × 0078 × 006E × 002D × 002D ÷ 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER P (AL) × [13.02] COLON (IS) × [13.02] SOLIDUS (SY) × [13.02] SOLIDUS (SY) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER X (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 007B × 0068 × 0074 × 0074 × 0070 × 003A × 002F × 002F × 007D ÷ 0078 × 006E × 002D × 002D ÷ 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER P (AL) × [13.02] COLON (IS) × [13.02] SOLIDUS (SY) × [13.02] SOLIDUS (SY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER X (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 0028 × 0030 × 002C × 0031 × 0029 × 002B × 0028 × 0032 × 002C × 0033 × 0029 × 2295 × 0028 × 2212 × 0034 × 002C × 0035 × 0029 × 2296 × 0028 × 0036 × 002C × 0037 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] DIGIT ZERO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT ONE (NU) × [25.04] RIGHT PARENTHESIS (CP) × [25.05] PLUS SIGN (PR) × [25.01] LEFT PARENTHESIS (OP) × [14.0] DIGIT TWO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT THREE (NU) × [25.04] RIGHT PARENTHESIS (CP) × [30.02] CIRCLED PLUS (AI_AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] MINUS SIGN (PR) × [25.01] DIGIT FOUR (NU) × [25.03] COMMA (IS) × [25.04] DIGIT FIVE (NU) × [25.04] RIGHT PARENTHESIS (CP) × [30.02] CIRCLED MINUS (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] DIGIT SIX (NU) × [25.03] COMMA (IS) × [25.04] DIGIT SEVEN (NU) × [25.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 007B × 0030 × 002C × 0031 × 007D × 002B × 007B × 0032 × 002C × 0033 × 007D ÷ 2295 × 007B × 2212 × 0034 × 002C × 0035 × 007D ÷ 2296 × 007B × 0036 × 002C × 0037 × 007D ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] DIGIT ZERO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT ONE (NU) × [25.04] RIGHT CURLY BRACKET (CL) × [25.05] PLUS SIGN (PR) × [25.01] LEFT CURLY BRACKET (OP) × [14.0] DIGIT TWO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT THREE (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [999.0] CIRCLED PLUS (AI_AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] MINUS SIGN (PR) × [25.01] DIGIT FOUR (NU) × [25.03] COMMA (IS) × [25.04] DIGIT FIVE (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [999.0] CIRCLED MINUS (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] DIGIT SIX (NU) × [25.03] COMMA (IS) × [25.04] DIGIT SEVEN (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0061 × 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
+× 0061 × 0062 × 0020 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 0061 × 0062 × 0020 ÷ 0063 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) ÷ [0.3]
+× 0061 ÷ 307E ÷ # × [0.3] LATIN SMALL LETTER A (AL) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 0939 × 093F × 0928 × 094D × 0926 × 0940 × 0020 ÷ # × [0.3] DEVANAGARI LETTER HA (AL) × [9.0] DEVANAGARI VOWEL SIGN I (CM1_CM) × [28.0] DEVANAGARI LETTER NA (AL) × [9.0] DEVANAGARI SIGN VIRAMA (CM1_CM) × [28.0] DEVANAGARI LETTER DA (AL) × [9.0] DEVANAGARI VOWEL SIGN II (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 092F × 0938 × 0917 × 0941 × 091A × 093F × 0924 × 0940 × 092F × 0938 × 093E × 0020 ÷ # × [0.3] DEVANAGARI LETTER YA (AL) × [28.0] DEVANAGARI LETTER SA (AL) × [28.0] DEVANAGARI LETTER GA (AL) × [9.0] DEVANAGARI VOWEL SIGN U (CM1_CM) × [28.0] DEVANAGARI LETTER CA (AL) × [9.0] DEVANAGARI VOWEL SIGN I (CM1_CM) × [28.0] DEVANAGARI LETTER TA (AL) × [9.0] DEVANAGARI VOWEL SIGN II (CM1_CM) × [28.0] DEVANAGARI LETTER YA (AL) × [28.0] DEVANAGARI LETTER SA (AL) × [9.0] DEVANAGARI VOWEL SIGN AA (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 5370 ÷ 672C ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5370 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 5165 ÷ 529B ÷ 3057 ÷ 30A8 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5165 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-529B (ID) ÷ [999.0] HIRAGANA LETTER SI (ID) ÷ [999.0] KATAKANA LETTER E (ID) ÷ [0.3]
+× 4F4D × 3002 ÷ 8A18 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4F4D (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8A18 (ID) ÷ [0.3]
+× 672C × 3002 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
+× 967A × 300D ÷ 306E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-967A (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [0.3]
+× 3057 × 3087 ÷ 3046 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [21.03] HIRAGANA LETTER SMALL YO (CJ_NS) ÷ [999.0] HIRAGANA LETTER U (ID) ÷ [0.3]
+× 307E ÷ 0061 ÷ 672C ÷ # × [0.3] HIRAGANA LETTER MA (ID) ÷ [999.0] LATIN SMALL LETTER A (AL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× C5C6 ÷ C5B4 ÷ C694 × 0020 ÷ 006F × 0072 × 0020 ÷ BABB ÷ # × [0.3] HANGUL SYLLABLE EOBS (H3) ÷ [999.0] HANGUL SYLLABLE EO (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
+× 307E ÷ 0061 × 0062 × 0020 ÷ # × [0.3] HIRAGANA LETTER MA (ID) ÷ [999.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 3067 ÷ 4F7F ÷ # × [0.3] HIRAGANA LETTER DE (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4F7F (ID) ÷ [0.3]
+× 3059 ÷ 308B ÷ # × [0.3] HIRAGANA LETTER SU (ID) ÷ [999.0] HIRAGANA LETTER RU (ID) ÷ [0.3]
+× 306E ÷ 30D1 ÷ 30F3 ÷ # × [0.3] HIRAGANA LETTER NO (ID) ÷ [999.0] KATAKANA LETTER PA (ID) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [0.3]
+× 3046 × 3000 ÷ 3048 × 3000 ÷ 304A × 300D ÷ # × [0.3] HIRAGANA LETTER U (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER E (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER O (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [0.3]
+× 308B × 0020 ÷ C740 ÷ C601 × 0020 ÷ 306B ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE EUN (H3) ÷ [999.0] HANGUL SYLLABLE YEONG (H3) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER NI (ID) ÷ [0.3]
+× 3057 × 3087 ÷ 3046 × 3002 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [21.03] HIRAGANA LETTER SMALL YO (CJ_NS) ÷ [999.0] HIRAGANA LETTER U (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
+× 30E0 ÷ 306E ÷ 4E00 ÷ # × [0.3] KATAKANA LETTER MU (ID) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4E00 (ID) ÷ [0.3]
+× 30D5 ÷ 30EA ÷ # × [0.3] KATAKANA LETTER HU (ID) ÷ [999.0] KATAKANA LETTER RI (ID) ÷ [0.3]
+× 30D5 ÷ 30EA × 30FC ÷ 767E ÷ # × [0.3] KATAKANA LETTER HU (ID) ÷ [999.0] KATAKANA LETTER RI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-767E (ID) ÷ [0.3]
+× 30D4 × 30E5 × 30FC ÷ 30BF ÷ 3067 ÷ 4F7F ÷ 7528 ÷ 3059 ÷ 308B ÷ # × [0.3] KATAKANA LETTER PI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER TA (ID) ÷ [999.0] HIRAGANA LETTER DE (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4F7F (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-7528 (ID) ÷ [999.0] HIRAGANA LETTER SU (ID) ÷ [999.0] HIRAGANA LETTER RU (ID) ÷ [0.3]
+× 30BF × 30FC ÷ 30AD × 30FC ÷ 3092 ÷ 62BC ÷ # × [0.3] KATAKANA LETTER TA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-62BC (ID) ÷ [0.3]
+× 30B7 × 30E7 ÷ 30F3 ÷ # × [0.3] KATAKANA LETTER SI (ID) × [21.03] KATAKANA LETTER SMALL YO (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 0020 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 0020 ÷ 0915 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] DEVANAGARI LETTER KA (AL) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 0020 ÷ 672C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 672C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 307E ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 0033 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] DIGIT THREE (NU) ÷ [0.3]
+× 0061 × 0062 × 002E × 0020 ÷ 0032 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT TWO (NU) ÷ [0.3]
+× 0041 × 002E ÷ 0031 × 0020 ÷ BABB ÷ # × [0.3] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT ONE (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
+× BD24 ÷ C5B4 × 002E × 0020 ÷ 0041 × 002E ÷ 0032 × 0020 ÷ BCFC ÷ # × [0.3] HANGUL SYLLABLE BWASS (H3) ÷ [999.0] HANGUL SYLLABLE EO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE BOL (H3) ÷ [0.3]
+× BD10 ÷ C694 × 002E × 0020 ÷ 0041 × 002E ÷ 0033 × 0020 ÷ BABB ÷ # × [0.3] HANGUL SYLLABLE BWA (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT THREE (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
+× C694 × 002E × 0020 ÷ 0041 × 002E ÷ 0034 × 0020 ÷ BABB ÷ # × [0.3] HANGUL SYLLABLE YO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT FOUR (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 300C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] LEFT CORNER BRACKET (OP) ÷ [0.3]
+× 306B ÷ 300C × 30D0 ÷ 0028 × 0062 × 0061 × 0029 × 300D ÷ 3084 ÷ 300C × 30B9 ÷ # × [0.3] HIRAGANA LETTER NI (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER BA (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER A (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER YA (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER SU (ID) ÷ [0.3]
+× 308B ÷ 300C × 0055 × 004B ÷ 30DD ÷ 30F3 ÷ 30C9 × 300D × FF09 × 3001 ÷ 30A8 ÷ # × [0.3] HIRAGANA LETTER RU (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] LATIN CAPITAL LETTER U (AL) × [28.0] LATIN CAPITAL LETTER K (AL) ÷ [999.0] KATAKANA LETTER PO (ID) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [999.0] KATAKANA LETTER DO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER E (ID) ÷ [0.3]
+× 306F × 3001 ÷ 300C × 003D × 0072 × 0061 × 006E × 0064 × 0028 × 0029 × 300D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] EQUALS SIGN (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT PARENTHESIS (OP) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 3067 × 3001 ÷ 300C × 0021 × 300D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER DE (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LEFT CORNER BRACKET (OP) × [13.01] EXCLAMATION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 8A33 ÷ 300C × 3059 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8A33 (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER SU (ID) ÷ [0.3]
+× 3066 ÷ 300C × BD24 ÷ C5B4 × 003F × 300D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER TE (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE BWASS (H3) ÷ [999.0] HANGUL SYLLABLE EO (H2) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 306E ÷ 300C × 305D ÷ # × [0.3] HIRAGANA LETTER NO (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER SO (ID) ÷ [0.3]
+× 306F ÷ 300C × 30A8 ÷ # × [0.3] HIRAGANA LETTER HA (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER E (ID) ÷ [0.3]
+× 4F8B × FF1A ÷ 300C × 3042 × 3000 ÷ 3044 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4F8B (ID) × [21.03] FULLWIDTH COLON (NS) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER A (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER I (ID) ÷ [0.3]
+× 304F × 3001 ÷ 300C × D3C9 ÷ C591 ÷ C740 ÷ # × [0.3] HIRAGANA LETTER KU (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE PYEONG (H3) ÷ [999.0] HANGUL SYLLABLE YANG (H3) ÷ [999.0] HANGUL SYLLABLE EUN (H3) ÷ [0.3]
+× 306B ÷ 300C × C81C ÷ BAA9 ÷ 0028 × 984C ÷ 540D × 0029 ÷ C740 ÷ # × [0.3] HIRAGANA LETTER NI (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE JE (H2) ÷ [999.0] HANGUL SYLLABLE MOG (H3) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] CJK UNIFIED IDEOGRAPH-984C (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-540D (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL SYLLABLE EUN (H3) ÷ [0.3]
+× 5178 ÷ 300E × 30A6 × 30A3 ÷ 30AD ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5178 (ID) ÷ [999.0] LEFT WHITE CORNER BRACKET (OP) × [14.0] KATAKANA LETTER U (ID) × [21.03] KATAKANA LETTER SMALL I (CJ_NS) ÷ [999.0] KATAKANA LETTER KI (ID) ÷ [0.3]
+× 3067 ÷ 300E × 82F1 ÷ 8A9E ÷ # × [0.3] HIRAGANA LETTER DE (ID) ÷ [999.0] LEFT WHITE CORNER BRACKET (OP) × [14.0] CJK UNIFIED IDEOGRAPH-82F1 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8A9E (ID) ÷ [0.3]
+× 0028 × 0073 × 0029 × 0020 ÷ 672C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 0028 × 0073 × 0029 × 0020 ÷ 307E ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 0028 × 0073 × 0029 × 0020 ÷ 30AF ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 308B × 3002 ÷ 0064 × 006F × 0067 × FF08 × 72AC × FF09 ÷ 3092 ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER G (AL) × [30.01] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] CJK UNIFIED IDEOGRAPH-72AC (ID) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
+× 672C ÷ FF08 × 307E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 672C × 0020 ÷ 0028 × 0061 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 70B9 × 0020 ÷ 005B × 7DE8 ÷ 96C6 × 005D ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-70B9 (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT SQUARE BRACKET (OP) × [14.0] CJK UNIFIED IDEOGRAPH-7DE8 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-96C6 (ID) × [13.02] RIGHT SQUARE BRACKET (CP) ÷ [0.3]
+× 0061 × 0028 × 0073 × 0029 × 0020 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [0.3]
+× FF08 × 30B6 × 30FB ÷ 30AF ÷ 30A4 × 30C3 ÷ 30AF × 30FB ÷ 30D6 ÷ # × [0.3] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER ZA (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [999.0] KATAKANA LETTER I (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER BU (ID) ÷ [0.3]
+× 0070 × FF08 × 30AF ÷ 30A4 × 30C3 ÷ 30AF × 30FB ÷ 30D6 ÷ # × [0.3] LATIN SMALL LETTER P (AL) × [30.01] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER KU (ID) ÷ [999.0] KATAKANA LETTER I (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER BU (ID) ÷ [0.3]
+× 0061 × 0062 × FF08 × 30AF ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [30.01] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 0028 × 5370 ÷ 672C × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] CJK UNIFIED IDEOGRAPH-5370 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
+× 30B9 ÷ FF08 × 3044 ÷ # × [0.3] KATAKANA LETTER SU (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER I (ID) ÷ [0.3]
+× 30C9 ÷ FF08 × 30DD ÷ # × [0.3] KATAKANA LETTER DO (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER PO (ID) ÷ [0.3]
+× 30C9 × 0020 ÷ 0028 × 8CEA ÷ # × [0.3] KATAKANA LETTER DO (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) × [14.0] CJK UNIFIED IDEOGRAPH-8CEA (ID) ÷ [0.3]
+× 0073 × 0029 × 300D ÷ 307E ÷ # × [0.3] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 0061 × FF09 × 300F ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] RIGHT WHITE CORNER BRACKET (CL) ÷ [0.3]
+× 308B × 300D × FF09 ÷ 306F ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) ÷ [999.0] HIRAGANA LETTER HA (ID) ÷ [0.3]
+× 30C9 × 300D × FF09 × 3001 ÷ 30A8 ÷ # × [0.3] KATAKANA LETTER DO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER E (ID) ÷ [0.3]
+× 0072 × 006B × 0029 × 300D ÷ 3082 ÷ # × [0.3] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER K (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MO (ID) ÷ [0.3]
+× 30AF ÷ 0028 × 0061 × 0062 × 0020 ÷ 0063 × 0064 × 0029 × 300D ÷ 3082 ÷ # × [0.3] KATAKANA LETTER KU (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER D (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MO (ID) ÷ [0.3]
+× 30F3 × 30FB ÷ 30DE × 30FC ÷ 30AF ÷ 0028 × 0065 × 0078 ÷ # × [0.3] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER MA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER X (AL) ÷ [0.3]
+× 30DE × 30FC ÷ 0028 × 006D × 0061 × 0029 × 300D ÷ 306A ÷ # × [0.3] KATAKANA LETTER MA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER A (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER NA (ID) ÷ [0.3]
+× 30AC ÷ 30EF × 300D × 3002 ÷ 3053 ÷ # × [0.3] KATAKANA LETTER GA (ID) ÷ [999.0] KATAKANA LETTER WA (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [0.3]
+× 30AF × 300D ÷ 307E ÷ # × [0.3] KATAKANA LETTER KU (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 30EF × 300D × 3002 ÷ 3053 ÷ # × [0.3] KATAKANA LETTER WA (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [0.3]
+× 30AF × 300D ÷ 307E × 3001 ÷ 672C ÷ # × [0.3] KATAKANA LETTER KU (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 30AF × 300D × 3001 ÷ 30AF ÷ # × [0.3] KATAKANA LETTER KU (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 30C7 × 30A3 ÷ 30A2 ÷ FF08 × 0061 × 0062 × FF09 × 300F ÷ # × [0.3] KATAKANA LETTER DE (ID) × [21.03] KATAKANA LETTER SMALL I (CJ_NS) ÷ [999.0] KATAKANA LETTER A (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] RIGHT WHITE CORNER BRACKET (CL) ÷ [0.3]
+× CABD ÷ C774 ÷ C5D0 ÷ C694 × 003F × 300D ÷ 3068 ÷ 805E ÷ # × [0.3] HANGUL SYLLABLE JJOG (H3) ÷ [999.0] HANGUL SYLLABLE I (H2) ÷ [999.0] HANGUL SYLLABLE E (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-805E (ID) ÷ [0.3]
+× 540D × 0029 ÷ C740 × 0020 ÷ C54C ÷ C544 ÷ C694 × 003F × 300D ÷ 3068 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-540D (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL SYLLABLE EUN (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE AL (H3) ÷ [999.0] HANGUL SYLLABLE A (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 8CA8 × 0029 × 0020 ÷ 002D × 0020 ÷ 0028 × 0070 × 006F ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8CA8 (ID) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER O (AL) ÷ [0.3]
+× 91CF × 0029 × 0020 × 301C × 0020 ÷ 0028 × 0070 × 006F ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-91CF (ID) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [16.0] WAVE DASH (NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER O (AL) ÷ [0.3]
+× 30C9 ÷ 91CD × FF09 × 0020 × 301C × 0020 ÷ 529B × 30FB ÷ 91CD ÷ # × [0.3] KATAKANA LETTER DO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-91CD (ID) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [7.01] SPACE (SP) × [16.0] WAVE DASH (NS) × [7.01] SPACE (SP) ÷ [18.0] CJK UNIFIED IDEOGRAPH-529B (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-91CD (ID) ÷ [0.3]
+× 0061 × 0062 × 0022 × FF08 × 307E ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [19.01] QUOTATION MARK (QU) × [15.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 306F × 0020 ÷ 0022 × 0073 × 0022 × 0020 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) × [19.02] LATIN SMALL LETTER S (AL) × [19.01] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [0.3]
+× 306F × 3001 × 0022 × 0054 × 0068 × 0065 × 0020 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [19.01] QUOTATION MARK (QU) × [19.02] LATIN CAPITAL LETTER T (AL) × [28.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 0064 × 006F × 0067 × 0022 × 0020 ÷ 3092 ÷ # × [0.3] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER G (AL) × [19.01] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
+× 0039 × 0030 × 0022 × 0020 ÷ 3068 ÷ # × [0.3] DIGIT NINE (NU) × [25.03] DIGIT ZERO (NU) × [19.01] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 30B9 × 30FB ÷ 30AA × 30FC ÷ 30D0 × 30FC × 30FB ÷ 30B6 × 30FB ÷ 30EC ÷ # × [0.3] KATAKANA LETTER SU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER O (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER BA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER ZA (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER RE (ID) ÷ [0.3]
+× 30B9 × 30FB ÷ 30B8 × 30E3 ÷ 30F3 ÷ # × [0.3] KATAKANA LETTER SU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER ZI (ID) × [21.03] KATAKANA LETTER SMALL YA (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [0.3]
+× 30F3 × 30FB ÷ 30D5 × 30A9 × 30C3 ÷ 30AF ÷ # × [0.3] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER HU (ID) × [21.03] KATAKANA LETTER SMALL O (CJ_NS) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 30A4 ÷ 30B8 × 30FC × 30FB ÷ 30C9 × 30C3 ÷ 30B0 × 3001 ÷ 548C ÷ # × [0.3] KATAKANA LETTER I (ID) ÷ [999.0] KATAKANA LETTER ZI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER DO (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER GU (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-548C (ID) ÷ [0.3]
+× 30E1 × 30FC ÷ 30B7 × 30E7 ÷ 30F3 × 30FB ÷ 30DE × 30FC ÷ 30AF ÷ # × [0.3] KATAKANA LETTER ME (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER SI (ID) × [21.03] KATAKANA LETTER SMALL YO (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER MA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 30F3 × 30FB ÷ 30AF ÷ 0028 × 0061 ÷ # × [0.3] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 30B7 × 30E7 ÷ 30F3 × 30FB ÷ 30DE ÷ # × [0.3] KATAKANA LETTER SI (ID) × [21.03] KATAKANA LETTER SMALL YO (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER MA (ID) ÷ [0.3]
+× 672C × 003A × 0020 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [0.3]
+× 672C × 003A × 0020 ÷ 30AF ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [18.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 51FA ÷ 5178 × 003A × 0020 ÷ 30D5 ÷ 30EA × 30FC ÷ 767E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-51FA (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5178 (ID) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [18.0] KATAKANA LETTER HU (ID) ÷ [999.0] KATAKANA LETTER RI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-767E (ID) ÷ [0.3]
+× 5F8C × 2026 ÷ 306B ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5F8C (ID) × [22.03] HORIZONTAL ELLIPSIS (IN) ÷ [999.0] HIRAGANA LETTER NI (ID) ÷ [0.3]
+× 3057 × 3087 ÷ 3046 × 3002 × 3002 × 3002 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [21.03] HIRAGANA LETTER SMALL YO (CJ_NS) ÷ [999.0] HIRAGANA LETTER U (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
+× 304D × 3001 × 0021 × 0021 × 3001 × 0021 × 0021 × 0021 ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER KI (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [13.01] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) × [13.02] IDEOGRAPHIC COMMA (CL) × [13.01] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 306F × 3001 × 003F ÷ 3068 × 0021 ÷ 3092 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [13.01] QUESTION MARK (EX) ÷ [999.0] HIRAGANA LETTER TO (ID) × [13.01] EXCLAMATION MARK (EX) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
+× 305F × 3001 × 2049 ÷ 0028 × 0021 × 003F × 0029 ÷ 306E ÷ # × [0.3] HIRAGANA LETTER TA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [16.0] EXCLAMATION QUESTION MARK (NS) ÷ [999.0] LEFT PARENTHESIS (OP) × [13.01] EXCLAMATION MARK (EX) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [0.3]
+× 3084 × 3001 × 2048 ÷ 0028 × 003F × 0021 × 0029 ÷ 306E ÷ # × [0.3] HIRAGANA LETTER YA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [16.0] QUESTION EXCLAMATION MARK (NS) ÷ [999.0] LEFT PARENTHESIS (OP) × [13.01] QUESTION MARK (EX) × [13.01] EXCLAMATION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [0.3]
+× 305F × 0020 ÷ 203D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER TA (ID) × [7.01] SPACE (SP) ÷ [18.0] INTERROBANG (NS) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 305B × FF01 ÷ 0031 × 0030 × 0030 × 0025 ÷ 306E ÷ 5B8C ÷ # × [0.3] HIRAGANA LETTER SE (ID) × [13.01] FULLWIDTH EXCLAMATION MARK (EX) ÷ [999.0] DIGIT ONE (NU) × [25.03] DIGIT ZERO (NU) × [25.03] DIGIT ZERO (NU) × [25.05] PERCENT SIGN (PO) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5B8C (ID) ÷ [0.3]
+× 0032 × 0033 ÷ 672C ÷ # × [0.3] DIGIT TWO (NU) × [25.03] DIGIT THREE (NU) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 30A1 ÷ 30D9 × 30C3 ÷ 30C8 ÷ 0032 × 0036 ÷ 5B57 ÷ 3092 ÷ # × [0.3] KATAKANA LETTER SMALL A (CJ_NS) ÷ [999.0] KATAKANA LETTER BE (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER TO (ID) ÷ [999.0] DIGIT TWO (NU) × [25.03] DIGIT SIX (NU) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5B57 (ID) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
+× 4F8B × FF1A ÷ 00A3 × 0032 × 0033 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4F8B (ID) × [21.03] FULLWIDTH COLON (NS) ÷ [999.0] POUND SIGN (PR) × [25.01] DIGIT TWO (NU) × [25.03] DIGIT THREE (NU) ÷ [0.3]
+× 8A18 ÷ 53F7 × 0020 ÷ 00A3 × 3002 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8A18 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-53F7 (ID) × [7.01] SPACE (SP) ÷ [18.0] POUND SIGN (PR) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
+× 308C ÷ 308B × 3002 ÷ 0071 × 0075 ÷ # × [0.3] HIRAGANA LETTER RE (ID) ÷ [999.0] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN SMALL LETTER Q (AL) × [28.0] LATIN SMALL LETTER U (AL) ÷ [0.3]
+× 307E × 3002 ÷ # × [0.3] HIRAGANA LETTER MA (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
+× 307E × 3002 ÷ 0061 × 0062 × 0020 ÷ # × [0.3] HIRAGANA LETTER MA (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 308B × 3002 ÷ 6570 ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-6570 (ID) ÷ [0.3]
+× 308B × 3002 ÷ 3053 ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [0.3]
+× 3044 × 3002 ÷ 30D1 ÷ # × [0.3] HIRAGANA LETTER I (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] KATAKANA LETTER PA (ID) ÷ [0.3]
+× 30AC ÷ 30EF × 300D × 3002 ÷ 3053 ÷ 308C ÷ # × [0.3] KATAKANA LETTER GA (ID) ÷ [999.0] KATAKANA LETTER WA (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [999.0] HIRAGANA LETTER RE (ID) ÷ [0.3]
+× 8A9E ÷ 306E ÷ 0069 × 006F ÷ 306E × 3001 ÷ 0032 ÷ 5B57 ÷ 3092 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8A9E (ID) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [999.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER O (AL) ÷ [999.0] HIRAGANA LETTER NO (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] DIGIT TWO (NU) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5B57 (ID) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
+× 3001 ÷ 548C ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-548C (ID) ÷ [0.3]
+× 3001 ÷ 30BF ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER TA (ID) ÷ [0.3]
+× 3001 ÷ 304B ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] HIRAGANA LETTER KA (ID) ÷ [0.3]
+× 3001 ÷ 3053 ÷ 308C ÷ 3067 ÷ 306F × 0020 ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [999.0] HIRAGANA LETTER RE (ID) ÷ [999.0] HIRAGANA LETTER DE (ID) ÷ [999.0] HIRAGANA LETTER HA (ID) × [7.01] SPACE (SP) ÷ [0.3]
+× 3057 × 3001 ÷ 0061 × 0062 ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 0061 ÷ 1F1E6 ÷ 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
+× 1F1F7 × 1F1FA ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) ÷ [0.3]
+× 1F1F7 × 1F1FA ÷ 1F1F8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) ÷ [30.13] REGIONAL INDICATOR SYMBOL LETTER S (RI) ÷ [0.3]
+× 1F1F7 × 1F1FA ÷ 1F1F8 × 1F1EA ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) ÷ [30.13] REGIONAL INDICATOR SYMBOL LETTER S (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER E (RI) ÷ [0.3]
+× 1F1F7 × 1F1FA × 200B ÷ 1F1F8 × 1F1EA ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [8.0] REGIONAL INDICATOR SYMBOL LETTER S (RI) × [30.12] REGIONAL INDICATOR SYMBOL LETTER E (RI) ÷ [0.3]
+× 05D0 × 002D × 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.02] HYPHEN-MINUS (HY) × [21.1] HEBREW LETTER ALEF (HL) ÷ [0.3]
+#
+# Lines: 7312
+#
+# EOF
diff --git a/lib/stdlib/test/unicode_util_SUITE_data/NormalizationTest.txt b/lib/stdlib/test/unicode_util_SUITE_data/NormalizationTest.txt
new file mode 100644
index 0000000000..e133fa8a78
--- /dev/null
+++ b/lib/stdlib/test/unicode_util_SUITE_data/NormalizationTest.txt
@@ -0,0 +1,18777 @@
+# NormalizationTest-9.0.0.txt
+# Date: 2016-04-04, 11:41:55 GMT
+# © 2016 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see http://www.unicode.org/reports/tr44/
+#
+# Normalization Test Suite
+# Format:
+#
+# Columns (c1, c2,...) are separated by semicolons
+# They have the following meaning:
+# source; NFC; NFD; NFKC; NFKD
+# Comments are indicated with hash marks
+# Each of the columns may have one or more code points.
+#
+# CONFORMANCE:
+# 1. The following invariants must be true for all conformant implementations
+#
+# NFC
+# c2 == toNFC(c1) == toNFC(c2) == toNFC(c3)
+# c4 == toNFC(c4) == toNFC(c5)
+#
+# NFD
+# c3 == toNFD(c1) == toNFD(c2) == toNFD(c3)
+# c5 == toNFD(c4) == toNFD(c5)
+#
+# NFKC
+# c4 == toNFKC(c1) == toNFKC(c2) == toNFKC(c3) == toNFKC(c4) == toNFKC(c5)
+#
+# NFKD
+# c5 == toNFKD(c1) == toNFKD(c2) == toNFKD(c3) == toNFKD(c4) == toNFKD(c5)
+#
+# 2. For every code point X assigned in this version of Unicode that is not specifically
+# listed in Part 1, the following invariants must be true for all conformant
+# implementations:
+#
+# X == toNFC(X) == toNFD(X) == toNFKC(X) == toNFKD(X)
+#
+@Part0 # Specific cases
+#
+1E0A;1E0A;0044 0307;1E0A;0044 0307; # (Ḋ; Ḋ; D◌̇; Ḋ; D◌̇; ) LATIN CAPITAL LETTER D WITH DOT ABOVE
+1E0C;1E0C;0044 0323;1E0C;0044 0323; # (Ḍ; Ḍ; D◌̣; Ḍ; D◌̣; ) LATIN CAPITAL LETTER D WITH DOT BELOW
+1E0A 0323;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; # (Ḋ◌̣; Ḍ◌̇; D◌̣◌̇; Ḍ◌̇; D◌̣◌̇; ) LATIN CAPITAL LETTER D WITH DOT ABOVE, COMBINING DOT BELOW
+1E0C 0307;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; # (Ḍ◌̇; Ḍ◌̇; D◌̣◌̇; Ḍ◌̇; D◌̣◌̇; ) LATIN CAPITAL LETTER D WITH DOT BELOW, COMBINING DOT ABOVE
+0044 0307 0323;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; # (D◌̇◌̣; Ḍ◌̇; D◌̣◌̇; Ḍ◌̇; D◌̣◌̇; ) LATIN CAPITAL LETTER D, COMBINING DOT ABOVE, COMBINING DOT BELOW
+0044 0323 0307;1E0C 0307;0044 0323 0307;1E0C 0307;0044 0323 0307; # (D◌̣◌̇; Ḍ◌̇; D◌̣◌̇; Ḍ◌̇; D◌̣◌̇; ) LATIN CAPITAL LETTER D, COMBINING DOT BELOW, COMBINING DOT ABOVE
+1E0A 031B;1E0A 031B;0044 031B 0307;1E0A 031B;0044 031B 0307; # (Ḋ◌̛; Ḋ◌̛; D◌̛◌̇; Ḋ◌̛; D◌̛◌̇; ) LATIN CAPITAL LETTER D WITH DOT ABOVE, COMBINING HORN
+1E0C 031B;1E0C 031B;0044 031B 0323;1E0C 031B;0044 031B 0323; # (Ḍ◌̛; Ḍ◌̛; D◌̛◌̣; Ḍ◌̛; D◌̛◌̣; ) LATIN CAPITAL LETTER D WITH DOT BELOW, COMBINING HORN
+1E0A 031B 0323;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; # (Ḋ◌̛◌̣; Ḍ◌̛◌̇; D◌̛◌̣◌̇; Ḍ◌̛◌̇; D◌̛◌̣◌̇; ) LATIN CAPITAL LETTER D WITH DOT ABOVE, COMBINING HORN, COMBINING DOT BELOW
+1E0C 031B 0307;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; # (Ḍ◌̛◌̇; Ḍ◌̛◌̇; D◌̛◌̣◌̇; Ḍ◌̛◌̇; D◌̛◌̣◌̇; ) LATIN CAPITAL LETTER D WITH DOT BELOW, COMBINING HORN, COMBINING DOT ABOVE
+0044 031B 0307 0323;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; # (D◌̛◌̇◌̣; Ḍ◌̛◌̇; D◌̛◌̣◌̇; Ḍ◌̛◌̇; D◌̛◌̣◌̇; ) LATIN CAPITAL LETTER D, COMBINING HORN, COMBINING DOT ABOVE, COMBINING DOT BELOW
+0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307;1E0C 031B 0307;0044 031B 0323 0307; # (D◌̛◌̣◌̇; Ḍ◌̛◌̇; D◌̛◌̣◌̇; Ḍ◌̛◌̇; D◌̛◌̣◌̇; ) LATIN CAPITAL LETTER D, COMBINING HORN, COMBINING DOT BELOW, COMBINING DOT ABOVE
+00C8;00C8;0045 0300;00C8;0045 0300; # (È; È; E◌̀; È; E◌̀; ) LATIN CAPITAL LETTER E WITH GRAVE
+0112;0112;0045 0304;0112;0045 0304; # (Ē; Ē; E◌̄; Ē; E◌̄; ) LATIN CAPITAL LETTER E WITH MACRON
+0045 0300;00C8;0045 0300;00C8;0045 0300; # (E◌̀; È; E◌̀; È; E◌̀; ) LATIN CAPITAL LETTER E, COMBINING GRAVE ACCENT
+0045 0304;0112;0045 0304;0112;0045 0304; # (E◌̄; Ē; E◌̄; Ē; E◌̄; ) LATIN CAPITAL LETTER E, COMBINING MACRON
+1E14;1E14;0045 0304 0300;1E14;0045 0304 0300; # (Ḕ; Ḕ; E◌̄◌̀; Ḕ; E◌̄◌̀; ) LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
+0112 0300;1E14;0045 0304 0300;1E14;0045 0304 0300; # (Ē◌̀; Ḕ; E◌̄◌̀; Ḕ; E◌̄◌̀; ) LATIN CAPITAL LETTER E WITH MACRON, COMBINING GRAVE ACCENT
+1E14 0304;1E14 0304;0045 0304 0300 0304;1E14 0304;0045 0304 0300 0304; # (Ḕ◌̄; Ḕ◌̄; E◌̄◌̀◌̄; Ḕ◌̄; E◌̄◌̀◌̄; ) LATIN CAPITAL LETTER E WITH MACRON AND GRAVE, COMBINING MACRON
+0045 0304 0300;1E14;0045 0304 0300;1E14;0045 0304 0300; # (E◌̄◌̀; Ḕ; E◌̄◌̀; Ḕ; E◌̄◌̀; ) LATIN CAPITAL LETTER E, COMBINING MACRON, COMBINING GRAVE ACCENT
+0045 0300 0304;00C8 0304;0045 0300 0304;00C8 0304;0045 0300 0304; # (E◌̀◌̄; È◌̄; E◌̀◌̄; È◌̄; E◌̀◌̄; ) LATIN CAPITAL LETTER E, COMBINING GRAVE ACCENT, COMBINING MACRON
+05B8 05B9 05B1 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F;05B1 05B8 05B9 0591 05C3 05B0 05AC 059F; # (◌ָ◌ֹ◌ֱ◌֑׃◌ְ◌֬◌֟; ◌ֱ◌ָ◌ֹ◌֑׃◌ְ◌֬◌֟; ◌ֱ◌ָ◌ֹ◌֑׃◌ְ◌֬◌֟; ◌ֱ◌ָ◌ֹ◌֑׃◌ְ◌֬◌֟; ◌ֱ◌ָ◌ֹ◌֑׃◌ְ◌֬◌֟; ) HEBREW POINT QAMATS, HEBREW POINT HOLAM, HEBREW POINT HATAF SEGOL, HEBREW ACCENT ETNAHTA, HEBREW PUNCTUATION SOF PASUQ, HEBREW POINT SHEVA, HEBREW ACCENT ILUY, HEBREW ACCENT QARNEY PARA
+0592 05B7 05BC 05A5 05B0 05C0 05C4 05AD;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4; # (◌֒◌ַ◌ּ◌֥◌ְ׀◌ׄ◌֭; ◌ְ◌ַ◌ּ◌֥◌֒׀◌֭◌ׄ; ◌ְ◌ַ◌ּ◌֥◌֒׀◌֭◌ׄ; ◌ְ◌ַ◌ּ◌֥◌֒׀◌֭◌ׄ; ◌ְ◌ַ◌ּ◌֥◌֒׀◌֭◌ׄ; ) HEBREW ACCENT SEGOL, HEBREW POINT PATAH, HEBREW POINT DAGESH OR MAPIQ, HEBREW ACCENT MERKHA, HEBREW POINT SHEVA, HEBREW PUNCTUATION PASEQ, HEBREW MARK UPPER DOT, HEBREW ACCENT DEHI
+1100 AC00 11A8;1100 AC01;1100 1100 1161 11A8;1100 AC01;1100 1100 1161 11A8; # (ᄀ각; ᄀ각; ᄀ각; ᄀ각; ᄀ각; ) HANGUL CHOSEONG KIYEOK, HANGUL SYLLABLE GA, HANGUL JONGSEONG KIYEOK
+1100 AC00 11A8 11A8;1100 AC01 11A8;1100 1100 1161 11A8 11A8;1100 AC01 11A8;1100 1100 1161 11A8 11A8; # (ᄀ각ᆨ; ᄀ각ᆨ; ᄀ각ᆨ; ᄀ각ᆨ; ᄀ각ᆨ; ) HANGUL CHOSEONG KIYEOK, HANGUL SYLLABLE GA, HANGUL JONGSEONG KIYEOK, HANGUL JONGSEONG KIYEOK
+#
+@Part1 # Character by character test
+# All characters not explicitly occurring in c1 of Part 1 have identical NFC, D, KC, KD forms.
+#
+00A0;00A0;00A0;0020;0020; # ( ;  ;  ; ; ; ) NO-BREAK SPACE
+00A8;00A8;00A8;0020 0308;0020 0308; # (¨; ¨; ¨; ◌̈; ◌̈; ) DIAERESIS
+00AA;00AA;00AA;0061;0061; # (ª; ª; ª; a; a; ) FEMININE ORDINAL INDICATOR
+00AF;00AF;00AF;0020 0304;0020 0304; # (¯; ¯; ¯; ◌̄; ◌̄; ) MACRON
+00B2;00B2;00B2;0032;0032; # (²; ²; ²; 2; 2; ) SUPERSCRIPT TWO
+00B3;00B3;00B3;0033;0033; # (³; ³; ³; 3; 3; ) SUPERSCRIPT THREE
+00B4;00B4;00B4;0020 0301;0020 0301; # (´; ´; ´; ◌́; ◌́; ) ACUTE ACCENT
+00B5;00B5;00B5;03BC;03BC; # (µ; µ; µ; μ; μ; ) MICRO SIGN
+00B8;00B8;00B8;0020 0327;0020 0327; # (¸; ¸; ¸; ◌̧; ◌̧; ) CEDILLA
+00B9;00B9;00B9;0031;0031; # (¹; ¹; ¹; 1; 1; ) SUPERSCRIPT ONE
+00BA;00BA;00BA;006F;006F; # (º; º; º; o; o; ) MASCULINE ORDINAL INDICATOR
+00BC;00BC;00BC;0031 2044 0034;0031 2044 0034; # (¼; ¼; ¼; 1⁄4; 1⁄4; ) VULGAR FRACTION ONE QUARTER
+00BD;00BD;00BD;0031 2044 0032;0031 2044 0032; # (½; ½; ½; 1⁄2; 1⁄2; ) VULGAR FRACTION ONE HALF
+00BE;00BE;00BE;0033 2044 0034;0033 2044 0034; # (¾; ¾; ¾; 3⁄4; 3⁄4; ) VULGAR FRACTION THREE QUARTERS
+00C0;00C0;0041 0300;00C0;0041 0300; # (À; À; A◌̀; À; A◌̀; ) LATIN CAPITAL LETTER A WITH GRAVE
+00C1;00C1;0041 0301;00C1;0041 0301; # (Á; Á; A◌́; Á; A◌́; ) LATIN CAPITAL LETTER A WITH ACUTE
+00C2;00C2;0041 0302;00C2;0041 0302; # (Â; Â; A◌̂; Â; A◌̂; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+00C3;00C3;0041 0303;00C3;0041 0303; # (Ã; Ã; A◌̃; Ã; A◌̃; ) LATIN CAPITAL LETTER A WITH TILDE
+00C4;00C4;0041 0308;00C4;0041 0308; # (Ä; Ä; A◌̈; Ä; A◌̈; ) LATIN CAPITAL LETTER A WITH DIAERESIS
+00C5;00C5;0041 030A;00C5;0041 030A; # (Å; Å; A◌̊; Å; A◌̊; ) LATIN CAPITAL LETTER A WITH RING ABOVE
+00C7;00C7;0043 0327;00C7;0043 0327; # (Ç; Ç; C◌̧; Ç; C◌̧; ) LATIN CAPITAL LETTER C WITH CEDILLA
+00C8;00C8;0045 0300;00C8;0045 0300; # (È; È; E◌̀; È; E◌̀; ) LATIN CAPITAL LETTER E WITH GRAVE
+00C9;00C9;0045 0301;00C9;0045 0301; # (É; É; E◌́; É; E◌́; ) LATIN CAPITAL LETTER E WITH ACUTE
+00CA;00CA;0045 0302;00CA;0045 0302; # (Ê; Ê; E◌̂; Ê; E◌̂; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+00CB;00CB;0045 0308;00CB;0045 0308; # (Ë; Ë; E◌̈; Ë; E◌̈; ) LATIN CAPITAL LETTER E WITH DIAERESIS
+00CC;00CC;0049 0300;00CC;0049 0300; # (Ì; Ì; I◌̀; Ì; I◌̀; ) LATIN CAPITAL LETTER I WITH GRAVE
+00CD;00CD;0049 0301;00CD;0049 0301; # (Í; Í; I◌́; Í; I◌́; ) LATIN CAPITAL LETTER I WITH ACUTE
+00CE;00CE;0049 0302;00CE;0049 0302; # (Î; Î; I◌̂; Î; I◌̂; ) LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+00CF;00CF;0049 0308;00CF;0049 0308; # (Ï; Ï; I◌̈; Ï; I◌̈; ) LATIN CAPITAL LETTER I WITH DIAERESIS
+00D1;00D1;004E 0303;00D1;004E 0303; # (Ñ; Ñ; N◌̃; Ñ; N◌̃; ) LATIN CAPITAL LETTER N WITH TILDE
+00D2;00D2;004F 0300;00D2;004F 0300; # (Ò; Ò; O◌̀; Ò; O◌̀; ) LATIN CAPITAL LETTER O WITH GRAVE
+00D3;00D3;004F 0301;00D3;004F 0301; # (Ó; Ó; O◌́; Ó; O◌́; ) LATIN CAPITAL LETTER O WITH ACUTE
+00D4;00D4;004F 0302;00D4;004F 0302; # (Ô; Ô; O◌̂; Ô; O◌̂; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+00D5;00D5;004F 0303;00D5;004F 0303; # (Õ; Õ; O◌̃; Õ; O◌̃; ) LATIN CAPITAL LETTER O WITH TILDE
+00D6;00D6;004F 0308;00D6;004F 0308; # (Ö; Ö; O◌̈; Ö; O◌̈; ) LATIN CAPITAL LETTER O WITH DIAERESIS
+00D9;00D9;0055 0300;00D9;0055 0300; # (Ù; Ù; U◌̀; Ù; U◌̀; ) LATIN CAPITAL LETTER U WITH GRAVE
+00DA;00DA;0055 0301;00DA;0055 0301; # (Ú; Ú; U◌́; Ú; U◌́; ) LATIN CAPITAL LETTER U WITH ACUTE
+00DB;00DB;0055 0302;00DB;0055 0302; # (Û; Û; U◌̂; Û; U◌̂; ) LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+00DC;00DC;0055 0308;00DC;0055 0308; # (Ü; Ü; U◌̈; Ü; U◌̈; ) LATIN CAPITAL LETTER U WITH DIAERESIS
+00DD;00DD;0059 0301;00DD;0059 0301; # (Ý; Ý; Y◌́; Ý; Y◌́; ) LATIN CAPITAL LETTER Y WITH ACUTE
+00E0;00E0;0061 0300;00E0;0061 0300; # (à; à; a◌̀; à; a◌̀; ) LATIN SMALL LETTER A WITH GRAVE
+00E1;00E1;0061 0301;00E1;0061 0301; # (á; á; a◌́; á; a◌́; ) LATIN SMALL LETTER A WITH ACUTE
+00E2;00E2;0061 0302;00E2;0061 0302; # (â; â; a◌̂; â; a◌̂; ) LATIN SMALL LETTER A WITH CIRCUMFLEX
+00E3;00E3;0061 0303;00E3;0061 0303; # (ã; ã; a◌̃; ã; a◌̃; ) LATIN SMALL LETTER A WITH TILDE
+00E4;00E4;0061 0308;00E4;0061 0308; # (ä; ä; a◌̈; ä; a◌̈; ) LATIN SMALL LETTER A WITH DIAERESIS
+00E5;00E5;0061 030A;00E5;0061 030A; # (å; å; a◌̊; å; a◌̊; ) LATIN SMALL LETTER A WITH RING ABOVE
+00E7;00E7;0063 0327;00E7;0063 0327; # (ç; ç; c◌̧; ç; c◌̧; ) LATIN SMALL LETTER C WITH CEDILLA
+00E8;00E8;0065 0300;00E8;0065 0300; # (è; è; e◌̀; è; e◌̀; ) LATIN SMALL LETTER E WITH GRAVE
+00E9;00E9;0065 0301;00E9;0065 0301; # (é; é; e◌́; é; e◌́; ) LATIN SMALL LETTER E WITH ACUTE
+00EA;00EA;0065 0302;00EA;0065 0302; # (ê; ê; e◌̂; ê; e◌̂; ) LATIN SMALL LETTER E WITH CIRCUMFLEX
+00EB;00EB;0065 0308;00EB;0065 0308; # (ë; ë; e◌̈; ë; e◌̈; ) LATIN SMALL LETTER E WITH DIAERESIS
+00EC;00EC;0069 0300;00EC;0069 0300; # (ì; ì; i◌̀; ì; i◌̀; ) LATIN SMALL LETTER I WITH GRAVE
+00ED;00ED;0069 0301;00ED;0069 0301; # (í; í; i◌́; í; i◌́; ) LATIN SMALL LETTER I WITH ACUTE
+00EE;00EE;0069 0302;00EE;0069 0302; # (î; î; i◌̂; î; i◌̂; ) LATIN SMALL LETTER I WITH CIRCUMFLEX
+00EF;00EF;0069 0308;00EF;0069 0308; # (ï; ï; i◌̈; ï; i◌̈; ) LATIN SMALL LETTER I WITH DIAERESIS
+00F1;00F1;006E 0303;00F1;006E 0303; # (ñ; ñ; n◌̃; ñ; n◌̃; ) LATIN SMALL LETTER N WITH TILDE
+00F2;00F2;006F 0300;00F2;006F 0300; # (ò; ò; o◌̀; ò; o◌̀; ) LATIN SMALL LETTER O WITH GRAVE
+00F3;00F3;006F 0301;00F3;006F 0301; # (ó; ó; o◌́; ó; o◌́; ) LATIN SMALL LETTER O WITH ACUTE
+00F4;00F4;006F 0302;00F4;006F 0302; # (ô; ô; o◌̂; ô; o◌̂; ) LATIN SMALL LETTER O WITH CIRCUMFLEX
+00F5;00F5;006F 0303;00F5;006F 0303; # (õ; õ; o◌̃; õ; o◌̃; ) LATIN SMALL LETTER O WITH TILDE
+00F6;00F6;006F 0308;00F6;006F 0308; # (ö; ö; o◌̈; ö; o◌̈; ) LATIN SMALL LETTER O WITH DIAERESIS
+00F9;00F9;0075 0300;00F9;0075 0300; # (ù; ù; u◌̀; ù; u◌̀; ) LATIN SMALL LETTER U WITH GRAVE
+00FA;00FA;0075 0301;00FA;0075 0301; # (ú; ú; u◌́; ú; u◌́; ) LATIN SMALL LETTER U WITH ACUTE
+00FB;00FB;0075 0302;00FB;0075 0302; # (û; û; u◌̂; û; u◌̂; ) LATIN SMALL LETTER U WITH CIRCUMFLEX
+00FC;00FC;0075 0308;00FC;0075 0308; # (ü; ü; u◌̈; ü; u◌̈; ) LATIN SMALL LETTER U WITH DIAERESIS
+00FD;00FD;0079 0301;00FD;0079 0301; # (ý; ý; y◌́; ý; y◌́; ) LATIN SMALL LETTER Y WITH ACUTE
+00FF;00FF;0079 0308;00FF;0079 0308; # (ÿ; ÿ; y◌̈; ÿ; y◌̈; ) LATIN SMALL LETTER Y WITH DIAERESIS
+0100;0100;0041 0304;0100;0041 0304; # (Ā; Ā; A◌̄; Ā; A◌̄; ) LATIN CAPITAL LETTER A WITH MACRON
+0101;0101;0061 0304;0101;0061 0304; # (ā; ā; a◌̄; ā; a◌̄; ) LATIN SMALL LETTER A WITH MACRON
+0102;0102;0041 0306;0102;0041 0306; # (Ă; Ă; A◌̆; Ă; A◌̆; ) LATIN CAPITAL LETTER A WITH BREVE
+0103;0103;0061 0306;0103;0061 0306; # (ă; ă; a◌̆; ă; a◌̆; ) LATIN SMALL LETTER A WITH BREVE
+0104;0104;0041 0328;0104;0041 0328; # (Ą; Ą; A◌̨; Ą; A◌̨; ) LATIN CAPITAL LETTER A WITH OGONEK
+0105;0105;0061 0328;0105;0061 0328; # (ą; ą; a◌̨; ą; a◌̨; ) LATIN SMALL LETTER A WITH OGONEK
+0106;0106;0043 0301;0106;0043 0301; # (Ć; Ć; C◌́; Ć; C◌́; ) LATIN CAPITAL LETTER C WITH ACUTE
+0107;0107;0063 0301;0107;0063 0301; # (ć; ć; c◌́; ć; c◌́; ) LATIN SMALL LETTER C WITH ACUTE
+0108;0108;0043 0302;0108;0043 0302; # (Ĉ; Ĉ; C◌̂; Ĉ; C◌̂; ) LATIN CAPITAL LETTER C WITH CIRCUMFLEX
+0109;0109;0063 0302;0109;0063 0302; # (ĉ; ĉ; c◌̂; ĉ; c◌̂; ) LATIN SMALL LETTER C WITH CIRCUMFLEX
+010A;010A;0043 0307;010A;0043 0307; # (Ċ; Ċ; C◌̇; Ċ; C◌̇; ) LATIN CAPITAL LETTER C WITH DOT ABOVE
+010B;010B;0063 0307;010B;0063 0307; # (ċ; ċ; c◌̇; ċ; c◌̇; ) LATIN SMALL LETTER C WITH DOT ABOVE
+010C;010C;0043 030C;010C;0043 030C; # (Č; Č; C◌̌; Č; C◌̌; ) LATIN CAPITAL LETTER C WITH CARON
+010D;010D;0063 030C;010D;0063 030C; # (č; č; c◌̌; č; c◌̌; ) LATIN SMALL LETTER C WITH CARON
+010E;010E;0044 030C;010E;0044 030C; # (Ď; Ď; D◌̌; Ď; D◌̌; ) LATIN CAPITAL LETTER D WITH CARON
+010F;010F;0064 030C;010F;0064 030C; # (ď; ď; d◌̌; ď; d◌̌; ) LATIN SMALL LETTER D WITH CARON
+0112;0112;0045 0304;0112;0045 0304; # (Ē; Ē; E◌̄; Ē; E◌̄; ) LATIN CAPITAL LETTER E WITH MACRON
+0113;0113;0065 0304;0113;0065 0304; # (ē; ē; e◌̄; ē; e◌̄; ) LATIN SMALL LETTER E WITH MACRON
+0114;0114;0045 0306;0114;0045 0306; # (Ĕ; Ĕ; E◌̆; Ĕ; E◌̆; ) LATIN CAPITAL LETTER E WITH BREVE
+0115;0115;0065 0306;0115;0065 0306; # (ĕ; ĕ; e◌̆; ĕ; e◌̆; ) LATIN SMALL LETTER E WITH BREVE
+0116;0116;0045 0307;0116;0045 0307; # (Ė; Ė; E◌̇; Ė; E◌̇; ) LATIN CAPITAL LETTER E WITH DOT ABOVE
+0117;0117;0065 0307;0117;0065 0307; # (ė; ė; e◌̇; ė; e◌̇; ) LATIN SMALL LETTER E WITH DOT ABOVE
+0118;0118;0045 0328;0118;0045 0328; # (Ę; Ę; E◌̨; Ę; E◌̨; ) LATIN CAPITAL LETTER E WITH OGONEK
+0119;0119;0065 0328;0119;0065 0328; # (ę; ę; e◌̨; ę; e◌̨; ) LATIN SMALL LETTER E WITH OGONEK
+011A;011A;0045 030C;011A;0045 030C; # (Ě; Ě; E◌̌; Ě; E◌̌; ) LATIN CAPITAL LETTER E WITH CARON
+011B;011B;0065 030C;011B;0065 030C; # (ě; ě; e◌̌; ě; e◌̌; ) LATIN SMALL LETTER E WITH CARON
+011C;011C;0047 0302;011C;0047 0302; # (Ĝ; Ĝ; G◌̂; Ĝ; G◌̂; ) LATIN CAPITAL LETTER G WITH CIRCUMFLEX
+011D;011D;0067 0302;011D;0067 0302; # (ĝ; ĝ; g◌̂; ĝ; g◌̂; ) LATIN SMALL LETTER G WITH CIRCUMFLEX
+011E;011E;0047 0306;011E;0047 0306; # (Ğ; Ğ; G◌̆; Ğ; G◌̆; ) LATIN CAPITAL LETTER G WITH BREVE
+011F;011F;0067 0306;011F;0067 0306; # (ğ; ğ; g◌̆; ğ; g◌̆; ) LATIN SMALL LETTER G WITH BREVE
+0120;0120;0047 0307;0120;0047 0307; # (Ġ; Ġ; G◌̇; Ġ; G◌̇; ) LATIN CAPITAL LETTER G WITH DOT ABOVE
+0121;0121;0067 0307;0121;0067 0307; # (ġ; ġ; g◌̇; ġ; g◌̇; ) LATIN SMALL LETTER G WITH DOT ABOVE
+0122;0122;0047 0327;0122;0047 0327; # (Ģ; Ģ; G◌̧; Ģ; G◌̧; ) LATIN CAPITAL LETTER G WITH CEDILLA
+0123;0123;0067 0327;0123;0067 0327; # (ģ; ģ; g◌̧; ģ; g◌̧; ) LATIN SMALL LETTER G WITH CEDILLA
+0124;0124;0048 0302;0124;0048 0302; # (Ĥ; Ĥ; H◌̂; Ĥ; H◌̂; ) LATIN CAPITAL LETTER H WITH CIRCUMFLEX
+0125;0125;0068 0302;0125;0068 0302; # (ĥ; ĥ; h◌̂; ĥ; h◌̂; ) LATIN SMALL LETTER H WITH CIRCUMFLEX
+0128;0128;0049 0303;0128;0049 0303; # (Ĩ; Ĩ; I◌̃; Ĩ; I◌̃; ) LATIN CAPITAL LETTER I WITH TILDE
+0129;0129;0069 0303;0129;0069 0303; # (ĩ; ĩ; i◌̃; ĩ; i◌̃; ) LATIN SMALL LETTER I WITH TILDE
+012A;012A;0049 0304;012A;0049 0304; # (Ī; Ī; I◌̄; Ī; I◌̄; ) LATIN CAPITAL LETTER I WITH MACRON
+012B;012B;0069 0304;012B;0069 0304; # (ī; ī; i◌̄; ī; i◌̄; ) LATIN SMALL LETTER I WITH MACRON
+012C;012C;0049 0306;012C;0049 0306; # (Ĭ; Ĭ; I◌̆; Ĭ; I◌̆; ) LATIN CAPITAL LETTER I WITH BREVE
+012D;012D;0069 0306;012D;0069 0306; # (ĭ; ĭ; i◌̆; ĭ; i◌̆; ) LATIN SMALL LETTER I WITH BREVE
+012E;012E;0049 0328;012E;0049 0328; # (Į; Į; I◌̨; Į; I◌̨; ) LATIN CAPITAL LETTER I WITH OGONEK
+012F;012F;0069 0328;012F;0069 0328; # (į; į; i◌̨; į; i◌̨; ) LATIN SMALL LETTER I WITH OGONEK
+0130;0130;0049 0307;0130;0049 0307; # (İ; İ; I◌̇; İ; I◌̇; ) LATIN CAPITAL LETTER I WITH DOT ABOVE
+0132;0132;0132;0049 004A;0049 004A; # (IJ; IJ; IJ; IJ; IJ; ) LATIN CAPITAL LIGATURE IJ
+0133;0133;0133;0069 006A;0069 006A; # (ij; ij; ij; ij; ij; ) LATIN SMALL LIGATURE IJ
+0134;0134;004A 0302;0134;004A 0302; # (Ĵ; Ĵ; J◌̂; Ĵ; J◌̂; ) LATIN CAPITAL LETTER J WITH CIRCUMFLEX
+0135;0135;006A 0302;0135;006A 0302; # (ĵ; ĵ; j◌̂; ĵ; j◌̂; ) LATIN SMALL LETTER J WITH CIRCUMFLEX
+0136;0136;004B 0327;0136;004B 0327; # (Ķ; Ķ; K◌̧; Ķ; K◌̧; ) LATIN CAPITAL LETTER K WITH CEDILLA
+0137;0137;006B 0327;0137;006B 0327; # (ķ; ķ; k◌̧; ķ; k◌̧; ) LATIN SMALL LETTER K WITH CEDILLA
+0139;0139;004C 0301;0139;004C 0301; # (Ĺ; Ĺ; L◌́; Ĺ; L◌́; ) LATIN CAPITAL LETTER L WITH ACUTE
+013A;013A;006C 0301;013A;006C 0301; # (ĺ; ĺ; l◌́; ĺ; l◌́; ) LATIN SMALL LETTER L WITH ACUTE
+013B;013B;004C 0327;013B;004C 0327; # (Ļ; Ļ; L◌̧; Ļ; L◌̧; ) LATIN CAPITAL LETTER L WITH CEDILLA
+013C;013C;006C 0327;013C;006C 0327; # (ļ; ļ; l◌̧; ļ; l◌̧; ) LATIN SMALL LETTER L WITH CEDILLA
+013D;013D;004C 030C;013D;004C 030C; # (Ľ; Ľ; L◌̌; Ľ; L◌̌; ) LATIN CAPITAL LETTER L WITH CARON
+013E;013E;006C 030C;013E;006C 030C; # (ľ; ľ; l◌̌; ľ; l◌̌; ) LATIN SMALL LETTER L WITH CARON
+013F;013F;013F;004C 00B7;004C 00B7; # (Ŀ; Ŀ; Ŀ; L·; L·; ) LATIN CAPITAL LETTER L WITH MIDDLE DOT
+0140;0140;0140;006C 00B7;006C 00B7; # (ŀ; ŀ; ŀ; l·; l·; ) LATIN SMALL LETTER L WITH MIDDLE DOT
+0143;0143;004E 0301;0143;004E 0301; # (Ń; Ń; N◌́; Ń; N◌́; ) LATIN CAPITAL LETTER N WITH ACUTE
+0144;0144;006E 0301;0144;006E 0301; # (ń; ń; n◌́; ń; n◌́; ) LATIN SMALL LETTER N WITH ACUTE
+0145;0145;004E 0327;0145;004E 0327; # (Ņ; Ņ; N◌̧; Ņ; N◌̧; ) LATIN CAPITAL LETTER N WITH CEDILLA
+0146;0146;006E 0327;0146;006E 0327; # (ņ; ņ; n◌̧; ņ; n◌̧; ) LATIN SMALL LETTER N WITH CEDILLA
+0147;0147;004E 030C;0147;004E 030C; # (Ň; Ň; N◌̌; Ň; N◌̌; ) LATIN CAPITAL LETTER N WITH CARON
+0148;0148;006E 030C;0148;006E 030C; # (ň; ň; n◌̌; ň; n◌̌; ) LATIN SMALL LETTER N WITH CARON
+0149;0149;0149;02BC 006E;02BC 006E; # (ʼn; ʼn; ʼn; ʼn; ʼn; ) LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+014C;014C;004F 0304;014C;004F 0304; # (Ō; Ō; O◌̄; Ō; O◌̄; ) LATIN CAPITAL LETTER O WITH MACRON
+014D;014D;006F 0304;014D;006F 0304; # (ō; ō; o◌̄; ō; o◌̄; ) LATIN SMALL LETTER O WITH MACRON
+014E;014E;004F 0306;014E;004F 0306; # (Ŏ; Ŏ; O◌̆; Ŏ; O◌̆; ) LATIN CAPITAL LETTER O WITH BREVE
+014F;014F;006F 0306;014F;006F 0306; # (ŏ; ŏ; o◌̆; ŏ; o◌̆; ) LATIN SMALL LETTER O WITH BREVE
+0150;0150;004F 030B;0150;004F 030B; # (Ő; Ő; O◌̋; Ő; O◌̋; ) LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+0151;0151;006F 030B;0151;006F 030B; # (ő; ő; o◌̋; ő; o◌̋; ) LATIN SMALL LETTER O WITH DOUBLE ACUTE
+0154;0154;0052 0301;0154;0052 0301; # (Ŕ; Ŕ; R◌́; Ŕ; R◌́; ) LATIN CAPITAL LETTER R WITH ACUTE
+0155;0155;0072 0301;0155;0072 0301; # (ŕ; ŕ; r◌́; ŕ; r◌́; ) LATIN SMALL LETTER R WITH ACUTE
+0156;0156;0052 0327;0156;0052 0327; # (Ŗ; Ŗ; R◌̧; Ŗ; R◌̧; ) LATIN CAPITAL LETTER R WITH CEDILLA
+0157;0157;0072 0327;0157;0072 0327; # (ŗ; ŗ; r◌̧; ŗ; r◌̧; ) LATIN SMALL LETTER R WITH CEDILLA
+0158;0158;0052 030C;0158;0052 030C; # (Ř; Ř; R◌̌; Ř; R◌̌; ) LATIN CAPITAL LETTER R WITH CARON
+0159;0159;0072 030C;0159;0072 030C; # (ř; ř; r◌̌; ř; r◌̌; ) LATIN SMALL LETTER R WITH CARON
+015A;015A;0053 0301;015A;0053 0301; # (Ś; Ś; S◌́; Ś; S◌́; ) LATIN CAPITAL LETTER S WITH ACUTE
+015B;015B;0073 0301;015B;0073 0301; # (ś; ś; s◌́; ś; s◌́; ) LATIN SMALL LETTER S WITH ACUTE
+015C;015C;0053 0302;015C;0053 0302; # (Ŝ; Ŝ; S◌̂; Ŝ; S◌̂; ) LATIN CAPITAL LETTER S WITH CIRCUMFLEX
+015D;015D;0073 0302;015D;0073 0302; # (ŝ; ŝ; s◌̂; ŝ; s◌̂; ) LATIN SMALL LETTER S WITH CIRCUMFLEX
+015E;015E;0053 0327;015E;0053 0327; # (Ş; Ş; S◌̧; Ş; S◌̧; ) LATIN CAPITAL LETTER S WITH CEDILLA
+015F;015F;0073 0327;015F;0073 0327; # (ş; ş; s◌̧; ş; s◌̧; ) LATIN SMALL LETTER S WITH CEDILLA
+0160;0160;0053 030C;0160;0053 030C; # (Š; Š; S◌̌; Š; S◌̌; ) LATIN CAPITAL LETTER S WITH CARON
+0161;0161;0073 030C;0161;0073 030C; # (š; š; s◌̌; š; s◌̌; ) LATIN SMALL LETTER S WITH CARON
+0162;0162;0054 0327;0162;0054 0327; # (Ţ; Ţ; T◌̧; Ţ; T◌̧; ) LATIN CAPITAL LETTER T WITH CEDILLA
+0163;0163;0074 0327;0163;0074 0327; # (ţ; ţ; t◌̧; ţ; t◌̧; ) LATIN SMALL LETTER T WITH CEDILLA
+0164;0164;0054 030C;0164;0054 030C; # (Ť; Ť; T◌̌; Ť; T◌̌; ) LATIN CAPITAL LETTER T WITH CARON
+0165;0165;0074 030C;0165;0074 030C; # (ť; ť; t◌̌; ť; t◌̌; ) LATIN SMALL LETTER T WITH CARON
+0168;0168;0055 0303;0168;0055 0303; # (Ũ; Ũ; U◌̃; Ũ; U◌̃; ) LATIN CAPITAL LETTER U WITH TILDE
+0169;0169;0075 0303;0169;0075 0303; # (ũ; ũ; u◌̃; ũ; u◌̃; ) LATIN SMALL LETTER U WITH TILDE
+016A;016A;0055 0304;016A;0055 0304; # (Ū; Ū; U◌̄; Ū; U◌̄; ) LATIN CAPITAL LETTER U WITH MACRON
+016B;016B;0075 0304;016B;0075 0304; # (ū; ū; u◌̄; ū; u◌̄; ) LATIN SMALL LETTER U WITH MACRON
+016C;016C;0055 0306;016C;0055 0306; # (Ŭ; Ŭ; U◌̆; Ŭ; U◌̆; ) LATIN CAPITAL LETTER U WITH BREVE
+016D;016D;0075 0306;016D;0075 0306; # (ŭ; ŭ; u◌̆; ŭ; u◌̆; ) LATIN SMALL LETTER U WITH BREVE
+016E;016E;0055 030A;016E;0055 030A; # (Ů; Ů; U◌̊; Ů; U◌̊; ) LATIN CAPITAL LETTER U WITH RING ABOVE
+016F;016F;0075 030A;016F;0075 030A; # (ů; ů; u◌̊; ů; u◌̊; ) LATIN SMALL LETTER U WITH RING ABOVE
+0170;0170;0055 030B;0170;0055 030B; # (Ű; Ű; U◌̋; Ű; U◌̋; ) LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+0171;0171;0075 030B;0171;0075 030B; # (ű; ű; u◌̋; ű; u◌̋; ) LATIN SMALL LETTER U WITH DOUBLE ACUTE
+0172;0172;0055 0328;0172;0055 0328; # (Ų; Ų; U◌̨; Ų; U◌̨; ) LATIN CAPITAL LETTER U WITH OGONEK
+0173;0173;0075 0328;0173;0075 0328; # (ų; ų; u◌̨; ų; u◌̨; ) LATIN SMALL LETTER U WITH OGONEK
+0174;0174;0057 0302;0174;0057 0302; # (Ŵ; Ŵ; W◌̂; Ŵ; W◌̂; ) LATIN CAPITAL LETTER W WITH CIRCUMFLEX
+0175;0175;0077 0302;0175;0077 0302; # (ŵ; ŵ; w◌̂; ŵ; w◌̂; ) LATIN SMALL LETTER W WITH CIRCUMFLEX
+0176;0176;0059 0302;0176;0059 0302; # (Ŷ; Ŷ; Y◌̂; Ŷ; Y◌̂; ) LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
+0177;0177;0079 0302;0177;0079 0302; # (ŷ; ŷ; y◌̂; ŷ; y◌̂; ) LATIN SMALL LETTER Y WITH CIRCUMFLEX
+0178;0178;0059 0308;0178;0059 0308; # (Ÿ; Ÿ; Y◌̈; Ÿ; Y◌̈; ) LATIN CAPITAL LETTER Y WITH DIAERESIS
+0179;0179;005A 0301;0179;005A 0301; # (Ź; Ź; Z◌́; Ź; Z◌́; ) LATIN CAPITAL LETTER Z WITH ACUTE
+017A;017A;007A 0301;017A;007A 0301; # (ź; ź; z◌́; ź; z◌́; ) LATIN SMALL LETTER Z WITH ACUTE
+017B;017B;005A 0307;017B;005A 0307; # (Ż; Ż; Z◌̇; Ż; Z◌̇; ) LATIN CAPITAL LETTER Z WITH DOT ABOVE
+017C;017C;007A 0307;017C;007A 0307; # (ż; ż; z◌̇; ż; z◌̇; ) LATIN SMALL LETTER Z WITH DOT ABOVE
+017D;017D;005A 030C;017D;005A 030C; # (Ž; Ž; Z◌̌; Ž; Z◌̌; ) LATIN CAPITAL LETTER Z WITH CARON
+017E;017E;007A 030C;017E;007A 030C; # (ž; ž; z◌̌; ž; z◌̌; ) LATIN SMALL LETTER Z WITH CARON
+017F;017F;017F;0073;0073; # (ſ; ſ; ſ; s; s; ) LATIN SMALL LETTER LONG S
+01A0;01A0;004F 031B;01A0;004F 031B; # (Ơ; Ơ; O◌̛; Ơ; O◌̛; ) LATIN CAPITAL LETTER O WITH HORN
+01A1;01A1;006F 031B;01A1;006F 031B; # (ơ; ơ; o◌̛; ơ; o◌̛; ) LATIN SMALL LETTER O WITH HORN
+01AF;01AF;0055 031B;01AF;0055 031B; # (Ư; Ư; U◌̛; Ư; U◌̛; ) LATIN CAPITAL LETTER U WITH HORN
+01B0;01B0;0075 031B;01B0;0075 031B; # (ư; ư; u◌̛; ư; u◌̛; ) LATIN SMALL LETTER U WITH HORN
+01C4;01C4;01C4;0044 017D;0044 005A 030C; # (DŽ; DŽ; DŽ; DŽ; DZ◌̌; ) LATIN CAPITAL LETTER DZ WITH CARON
+01C5;01C5;01C5;0044 017E;0044 007A 030C; # (Dž; Dž; Dž; Dž; Dz◌̌; ) LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
+01C6;01C6;01C6;0064 017E;0064 007A 030C; # (dž; dž; dž; dž; dz◌̌; ) LATIN SMALL LETTER DZ WITH CARON
+01C7;01C7;01C7;004C 004A;004C 004A; # (LJ; LJ; LJ; LJ; LJ; ) LATIN CAPITAL LETTER LJ
+01C8;01C8;01C8;004C 006A;004C 006A; # (Lj; Lj; Lj; Lj; Lj; ) LATIN CAPITAL LETTER L WITH SMALL LETTER J
+01C9;01C9;01C9;006C 006A;006C 006A; # (lj; lj; lj; lj; lj; ) LATIN SMALL LETTER LJ
+01CA;01CA;01CA;004E 004A;004E 004A; # (NJ; NJ; NJ; NJ; NJ; ) LATIN CAPITAL LETTER NJ
+01CB;01CB;01CB;004E 006A;004E 006A; # (Nj; Nj; Nj; Nj; Nj; ) LATIN CAPITAL LETTER N WITH SMALL LETTER J
+01CC;01CC;01CC;006E 006A;006E 006A; # (nj; nj; nj; nj; nj; ) LATIN SMALL LETTER NJ
+01CD;01CD;0041 030C;01CD;0041 030C; # (Ǎ; Ǎ; A◌̌; Ǎ; A◌̌; ) LATIN CAPITAL LETTER A WITH CARON
+01CE;01CE;0061 030C;01CE;0061 030C; # (ǎ; ǎ; a◌̌; ǎ; a◌̌; ) LATIN SMALL LETTER A WITH CARON
+01CF;01CF;0049 030C;01CF;0049 030C; # (Ǐ; Ǐ; I◌̌; Ǐ; I◌̌; ) LATIN CAPITAL LETTER I WITH CARON
+01D0;01D0;0069 030C;01D0;0069 030C; # (ǐ; ǐ; i◌̌; ǐ; i◌̌; ) LATIN SMALL LETTER I WITH CARON
+01D1;01D1;004F 030C;01D1;004F 030C; # (Ǒ; Ǒ; O◌̌; Ǒ; O◌̌; ) LATIN CAPITAL LETTER O WITH CARON
+01D2;01D2;006F 030C;01D2;006F 030C; # (ǒ; ǒ; o◌̌; ǒ; o◌̌; ) LATIN SMALL LETTER O WITH CARON
+01D3;01D3;0055 030C;01D3;0055 030C; # (Ǔ; Ǔ; U◌̌; Ǔ; U◌̌; ) LATIN CAPITAL LETTER U WITH CARON
+01D4;01D4;0075 030C;01D4;0075 030C; # (ǔ; ǔ; u◌̌; ǔ; u◌̌; ) LATIN SMALL LETTER U WITH CARON
+01D5;01D5;0055 0308 0304;01D5;0055 0308 0304; # (Ǖ; Ǖ; U◌̈◌̄; Ǖ; U◌̈◌̄; ) LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
+01D6;01D6;0075 0308 0304;01D6;0075 0308 0304; # (ǖ; ǖ; u◌̈◌̄; ǖ; u◌̈◌̄; ) LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+01D7;01D7;0055 0308 0301;01D7;0055 0308 0301; # (Ǘ; Ǘ; U◌̈◌́; Ǘ; U◌̈◌́; ) LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
+01D8;01D8;0075 0308 0301;01D8;0075 0308 0301; # (ǘ; ǘ; u◌̈◌́; ǘ; u◌̈◌́; ) LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+01D9;01D9;0055 0308 030C;01D9;0055 0308 030C; # (Ǚ; Ǚ; U◌̈◌̌; Ǚ; U◌̈◌̌; ) LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
+01DA;01DA;0075 0308 030C;01DA;0075 0308 030C; # (ǚ; ǚ; u◌̈◌̌; ǚ; u◌̈◌̌; ) LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+01DB;01DB;0055 0308 0300;01DB;0055 0308 0300; # (Ǜ; Ǜ; U◌̈◌̀; Ǜ; U◌̈◌̀; ) LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
+01DC;01DC;0075 0308 0300;01DC;0075 0308 0300; # (ǜ; ǜ; u◌̈◌̀; ǜ; u◌̈◌̀; ) LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+01DE;01DE;0041 0308 0304;01DE;0041 0308 0304; # (Ǟ; Ǟ; A◌̈◌̄; Ǟ; A◌̈◌̄; ) LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
+01DF;01DF;0061 0308 0304;01DF;0061 0308 0304; # (ǟ; ǟ; a◌̈◌̄; ǟ; a◌̈◌̄; ) LATIN SMALL LETTER A WITH DIAERESIS AND MACRON
+01E0;01E0;0041 0307 0304;01E0;0041 0307 0304; # (Ǡ; Ǡ; A◌̇◌̄; Ǡ; A◌̇◌̄; ) LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
+01E1;01E1;0061 0307 0304;01E1;0061 0307 0304; # (ǡ; ǡ; a◌̇◌̄; ǡ; a◌̇◌̄; ) LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON
+01E2;01E2;00C6 0304;01E2;00C6 0304; # (Ǣ; Ǣ; Æ◌̄; Ǣ; Æ◌̄; ) LATIN CAPITAL LETTER AE WITH MACRON
+01E3;01E3;00E6 0304;01E3;00E6 0304; # (ǣ; ǣ; æ◌̄; ǣ; æ◌̄; ) LATIN SMALL LETTER AE WITH MACRON
+01E6;01E6;0047 030C;01E6;0047 030C; # (Ǧ; Ǧ; G◌̌; Ǧ; G◌̌; ) LATIN CAPITAL LETTER G WITH CARON
+01E7;01E7;0067 030C;01E7;0067 030C; # (ǧ; ǧ; g◌̌; ǧ; g◌̌; ) LATIN SMALL LETTER G WITH CARON
+01E8;01E8;004B 030C;01E8;004B 030C; # (Ǩ; Ǩ; K◌̌; Ǩ; K◌̌; ) LATIN CAPITAL LETTER K WITH CARON
+01E9;01E9;006B 030C;01E9;006B 030C; # (ǩ; ǩ; k◌̌; ǩ; k◌̌; ) LATIN SMALL LETTER K WITH CARON
+01EA;01EA;004F 0328;01EA;004F 0328; # (Ǫ; Ǫ; O◌̨; Ǫ; O◌̨; ) LATIN CAPITAL LETTER O WITH OGONEK
+01EB;01EB;006F 0328;01EB;006F 0328; # (ǫ; ǫ; o◌̨; ǫ; o◌̨; ) LATIN SMALL LETTER O WITH OGONEK
+01EC;01EC;004F 0328 0304;01EC;004F 0328 0304; # (Ǭ; Ǭ; O◌̨◌̄; Ǭ; O◌̨◌̄; ) LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
+01ED;01ED;006F 0328 0304;01ED;006F 0328 0304; # (ǭ; ǭ; o◌̨◌̄; ǭ; o◌̨◌̄; ) LATIN SMALL LETTER O WITH OGONEK AND MACRON
+01EE;01EE;01B7 030C;01EE;01B7 030C; # (Ǯ; Ǯ; Ʒ◌̌; Ǯ; Ʒ◌̌; ) LATIN CAPITAL LETTER EZH WITH CARON
+01EF;01EF;0292 030C;01EF;0292 030C; # (ǯ; ǯ; ʒ◌̌; ǯ; ʒ◌̌; ) LATIN SMALL LETTER EZH WITH CARON
+01F0;01F0;006A 030C;01F0;006A 030C; # (ǰ; ǰ; j◌̌; ǰ; j◌̌; ) LATIN SMALL LETTER J WITH CARON
+01F1;01F1;01F1;0044 005A;0044 005A; # (DZ; DZ; DZ; DZ; DZ; ) LATIN CAPITAL LETTER DZ
+01F2;01F2;01F2;0044 007A;0044 007A; # (Dz; Dz; Dz; Dz; Dz; ) LATIN CAPITAL LETTER D WITH SMALL LETTER Z
+01F3;01F3;01F3;0064 007A;0064 007A; # (dz; dz; dz; dz; dz; ) LATIN SMALL LETTER DZ
+01F4;01F4;0047 0301;01F4;0047 0301; # (Ǵ; Ǵ; G◌́; Ǵ; G◌́; ) LATIN CAPITAL LETTER G WITH ACUTE
+01F5;01F5;0067 0301;01F5;0067 0301; # (ǵ; ǵ; g◌́; ǵ; g◌́; ) LATIN SMALL LETTER G WITH ACUTE
+01F8;01F8;004E 0300;01F8;004E 0300; # (Ǹ; Ǹ; N◌̀; Ǹ; N◌̀; ) LATIN CAPITAL LETTER N WITH GRAVE
+01F9;01F9;006E 0300;01F9;006E 0300; # (ǹ; ǹ; n◌̀; ǹ; n◌̀; ) LATIN SMALL LETTER N WITH GRAVE
+01FA;01FA;0041 030A 0301;01FA;0041 030A 0301; # (Ǻ; Ǻ; A◌̊◌́; Ǻ; A◌̊◌́; ) LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
+01FB;01FB;0061 030A 0301;01FB;0061 030A 0301; # (ǻ; ǻ; a◌̊◌́; ǻ; a◌̊◌́; ) LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE
+01FC;01FC;00C6 0301;01FC;00C6 0301; # (Ǽ; Ǽ; Æ◌́; Ǽ; Æ◌́; ) LATIN CAPITAL LETTER AE WITH ACUTE
+01FD;01FD;00E6 0301;01FD;00E6 0301; # (ǽ; ǽ; æ◌́; ǽ; æ◌́; ) LATIN SMALL LETTER AE WITH ACUTE
+01FE;01FE;00D8 0301;01FE;00D8 0301; # (Ǿ; Ǿ; Ø◌́; Ǿ; Ø◌́; ) LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
+01FF;01FF;00F8 0301;01FF;00F8 0301; # (ǿ; ǿ; ø◌́; ǿ; ø◌́; ) LATIN SMALL LETTER O WITH STROKE AND ACUTE
+0200;0200;0041 030F;0200;0041 030F; # (Ȁ; Ȁ; A◌̏; Ȁ; A◌̏; ) LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
+0201;0201;0061 030F;0201;0061 030F; # (ȁ; ȁ; a◌̏; ȁ; a◌̏; ) LATIN SMALL LETTER A WITH DOUBLE GRAVE
+0202;0202;0041 0311;0202;0041 0311; # (Ȃ; Ȃ; A◌̑; Ȃ; A◌̑; ) LATIN CAPITAL LETTER A WITH INVERTED BREVE
+0203;0203;0061 0311;0203;0061 0311; # (ȃ; ȃ; a◌̑; ȃ; a◌̑; ) LATIN SMALL LETTER A WITH INVERTED BREVE
+0204;0204;0045 030F;0204;0045 030F; # (Ȅ; Ȅ; E◌̏; Ȅ; E◌̏; ) LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
+0205;0205;0065 030F;0205;0065 030F; # (ȅ; ȅ; e◌̏; ȅ; e◌̏; ) LATIN SMALL LETTER E WITH DOUBLE GRAVE
+0206;0206;0045 0311;0206;0045 0311; # (Ȇ; Ȇ; E◌̑; Ȇ; E◌̑; ) LATIN CAPITAL LETTER E WITH INVERTED BREVE
+0207;0207;0065 0311;0207;0065 0311; # (ȇ; ȇ; e◌̑; ȇ; e◌̑; ) LATIN SMALL LETTER E WITH INVERTED BREVE
+0208;0208;0049 030F;0208;0049 030F; # (Ȉ; Ȉ; I◌̏; Ȉ; I◌̏; ) LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
+0209;0209;0069 030F;0209;0069 030F; # (ȉ; ȉ; i◌̏; ȉ; i◌̏; ) LATIN SMALL LETTER I WITH DOUBLE GRAVE
+020A;020A;0049 0311;020A;0049 0311; # (Ȋ; Ȋ; I◌̑; Ȋ; I◌̑; ) LATIN CAPITAL LETTER I WITH INVERTED BREVE
+020B;020B;0069 0311;020B;0069 0311; # (ȋ; ȋ; i◌̑; ȋ; i◌̑; ) LATIN SMALL LETTER I WITH INVERTED BREVE
+020C;020C;004F 030F;020C;004F 030F; # (Ȍ; Ȍ; O◌̏; Ȍ; O◌̏; ) LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
+020D;020D;006F 030F;020D;006F 030F; # (ȍ; ȍ; o◌̏; ȍ; o◌̏; ) LATIN SMALL LETTER O WITH DOUBLE GRAVE
+020E;020E;004F 0311;020E;004F 0311; # (Ȏ; Ȏ; O◌̑; Ȏ; O◌̑; ) LATIN CAPITAL LETTER O WITH INVERTED BREVE
+020F;020F;006F 0311;020F;006F 0311; # (ȏ; ȏ; o◌̑; ȏ; o◌̑; ) LATIN SMALL LETTER O WITH INVERTED BREVE
+0210;0210;0052 030F;0210;0052 030F; # (Ȑ; Ȑ; R◌̏; Ȑ; R◌̏; ) LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
+0211;0211;0072 030F;0211;0072 030F; # (ȑ; ȑ; r◌̏; ȑ; r◌̏; ) LATIN SMALL LETTER R WITH DOUBLE GRAVE
+0212;0212;0052 0311;0212;0052 0311; # (Ȓ; Ȓ; R◌̑; Ȓ; R◌̑; ) LATIN CAPITAL LETTER R WITH INVERTED BREVE
+0213;0213;0072 0311;0213;0072 0311; # (ȓ; ȓ; r◌̑; ȓ; r◌̑; ) LATIN SMALL LETTER R WITH INVERTED BREVE
+0214;0214;0055 030F;0214;0055 030F; # (Ȕ; Ȕ; U◌̏; Ȕ; U◌̏; ) LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
+0215;0215;0075 030F;0215;0075 030F; # (ȕ; ȕ; u◌̏; ȕ; u◌̏; ) LATIN SMALL LETTER U WITH DOUBLE GRAVE
+0216;0216;0055 0311;0216;0055 0311; # (Ȗ; Ȗ; U◌̑; Ȗ; U◌̑; ) LATIN CAPITAL LETTER U WITH INVERTED BREVE
+0217;0217;0075 0311;0217;0075 0311; # (ȗ; ȗ; u◌̑; ȗ; u◌̑; ) LATIN SMALL LETTER U WITH INVERTED BREVE
+0218;0218;0053 0326;0218;0053 0326; # (Ș; Ș; S◌̦; Ș; S◌̦; ) LATIN CAPITAL LETTER S WITH COMMA BELOW
+0219;0219;0073 0326;0219;0073 0326; # (ș; ș; s◌̦; ș; s◌̦; ) LATIN SMALL LETTER S WITH COMMA BELOW
+021A;021A;0054 0326;021A;0054 0326; # (Ț; Ț; T◌̦; Ț; T◌̦; ) LATIN CAPITAL LETTER T WITH COMMA BELOW
+021B;021B;0074 0326;021B;0074 0326; # (ț; ț; t◌̦; ț; t◌̦; ) LATIN SMALL LETTER T WITH COMMA BELOW
+021E;021E;0048 030C;021E;0048 030C; # (Ȟ; Ȟ; H◌̌; Ȟ; H◌̌; ) LATIN CAPITAL LETTER H WITH CARON
+021F;021F;0068 030C;021F;0068 030C; # (ȟ; ȟ; h◌̌; ȟ; h◌̌; ) LATIN SMALL LETTER H WITH CARON
+0226;0226;0041 0307;0226;0041 0307; # (Ȧ; Ȧ; A◌̇; Ȧ; A◌̇; ) LATIN CAPITAL LETTER A WITH DOT ABOVE
+0227;0227;0061 0307;0227;0061 0307; # (ȧ; ȧ; a◌̇; ȧ; a◌̇; ) LATIN SMALL LETTER A WITH DOT ABOVE
+0228;0228;0045 0327;0228;0045 0327; # (Ȩ; Ȩ; E◌̧; Ȩ; E◌̧; ) LATIN CAPITAL LETTER E WITH CEDILLA
+0229;0229;0065 0327;0229;0065 0327; # (ȩ; ȩ; e◌̧; ȩ; e◌̧; ) LATIN SMALL LETTER E WITH CEDILLA
+022A;022A;004F 0308 0304;022A;004F 0308 0304; # (Ȫ; Ȫ; O◌̈◌̄; Ȫ; O◌̈◌̄; ) LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
+022B;022B;006F 0308 0304;022B;006F 0308 0304; # (ȫ; ȫ; o◌̈◌̄; ȫ; o◌̈◌̄; ) LATIN SMALL LETTER O WITH DIAERESIS AND MACRON
+022C;022C;004F 0303 0304;022C;004F 0303 0304; # (Ȭ; Ȭ; O◌̃◌̄; Ȭ; O◌̃◌̄; ) LATIN CAPITAL LETTER O WITH TILDE AND MACRON
+022D;022D;006F 0303 0304;022D;006F 0303 0304; # (ȭ; ȭ; o◌̃◌̄; ȭ; o◌̃◌̄; ) LATIN SMALL LETTER O WITH TILDE AND MACRON
+022E;022E;004F 0307;022E;004F 0307; # (Ȯ; Ȯ; O◌̇; Ȯ; O◌̇; ) LATIN CAPITAL LETTER O WITH DOT ABOVE
+022F;022F;006F 0307;022F;006F 0307; # (ȯ; ȯ; o◌̇; ȯ; o◌̇; ) LATIN SMALL LETTER O WITH DOT ABOVE
+0230;0230;004F 0307 0304;0230;004F 0307 0304; # (Ȱ; Ȱ; O◌̇◌̄; Ȱ; O◌̇◌̄; ) LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
+0231;0231;006F 0307 0304;0231;006F 0307 0304; # (ȱ; ȱ; o◌̇◌̄; ȱ; o◌̇◌̄; ) LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON
+0232;0232;0059 0304;0232;0059 0304; # (Ȳ; Ȳ; Y◌̄; Ȳ; Y◌̄; ) LATIN CAPITAL LETTER Y WITH MACRON
+0233;0233;0079 0304;0233;0079 0304; # (ȳ; ȳ; y◌̄; ȳ; y◌̄; ) LATIN SMALL LETTER Y WITH MACRON
+02B0;02B0;02B0;0068;0068; # (ʰ; ʰ; ʰ; h; h; ) MODIFIER LETTER SMALL H
+02B1;02B1;02B1;0266;0266; # (ʱ; ʱ; ʱ; ɦ; ɦ; ) MODIFIER LETTER SMALL H WITH HOOK
+02B2;02B2;02B2;006A;006A; # (ʲ; ʲ; ʲ; j; j; ) MODIFIER LETTER SMALL J
+02B3;02B3;02B3;0072;0072; # (ʳ; ʳ; ʳ; r; r; ) MODIFIER LETTER SMALL R
+02B4;02B4;02B4;0279;0279; # (ʴ; ʴ; ʴ; ɹ; ɹ; ) MODIFIER LETTER SMALL TURNED R
+02B5;02B5;02B5;027B;027B; # (ʵ; ʵ; ʵ; ɻ; ɻ; ) MODIFIER LETTER SMALL TURNED R WITH HOOK
+02B6;02B6;02B6;0281;0281; # (ʶ; ʶ; ʶ; ʁ; ʁ; ) MODIFIER LETTER SMALL CAPITAL INVERTED R
+02B7;02B7;02B7;0077;0077; # (ʷ; ʷ; ʷ; w; w; ) MODIFIER LETTER SMALL W
+02B8;02B8;02B8;0079;0079; # (ʸ; ʸ; ʸ; y; y; ) MODIFIER LETTER SMALL Y
+02D8;02D8;02D8;0020 0306;0020 0306; # (˘; ˘; ˘; ◌̆; ◌̆; ) BREVE
+02D9;02D9;02D9;0020 0307;0020 0307; # (˙; ˙; ˙; ◌̇; ◌̇; ) DOT ABOVE
+02DA;02DA;02DA;0020 030A;0020 030A; # (˚; ˚; ˚; ◌̊; ◌̊; ) RING ABOVE
+02DB;02DB;02DB;0020 0328;0020 0328; # (˛; ˛; ˛; ◌̨; ◌̨; ) OGONEK
+02DC;02DC;02DC;0020 0303;0020 0303; # (˜; ˜; ˜; ◌̃; ◌̃; ) SMALL TILDE
+02DD;02DD;02DD;0020 030B;0020 030B; # (˝; ˝; ˝; ◌̋; ◌̋; ) DOUBLE ACUTE ACCENT
+02E0;02E0;02E0;0263;0263; # (ˠ; ˠ; ˠ; ɣ; ɣ; ) MODIFIER LETTER SMALL GAMMA
+02E1;02E1;02E1;006C;006C; # (ˡ; ˡ; ˡ; l; l; ) MODIFIER LETTER SMALL L
+02E2;02E2;02E2;0073;0073; # (ˢ; ˢ; ˢ; s; s; ) MODIFIER LETTER SMALL S
+02E3;02E3;02E3;0078;0078; # (ˣ; ˣ; ˣ; x; x; ) MODIFIER LETTER SMALL X
+02E4;02E4;02E4;0295;0295; # (ˤ; ˤ; ˤ; ʕ; ʕ; ) MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
+0340;0300;0300;0300;0300; # (◌̀; ◌̀; ◌̀; ◌̀; ◌̀; ) COMBINING GRAVE TONE MARK
+0341;0301;0301;0301;0301; # (◌́; ◌́; ◌́; ◌́; ◌́; ) COMBINING ACUTE TONE MARK
+0343;0313;0313;0313;0313; # (◌̓; ◌̓; ◌̓; ◌̓; ◌̓; ) COMBINING GREEK KORONIS
+0344;0308 0301;0308 0301;0308 0301;0308 0301; # (◌̈́; ◌̈◌́; ◌̈◌́; ◌̈◌́; ◌̈◌́; ) COMBINING GREEK DIALYTIKA TONOS
+0374;02B9;02B9;02B9;02B9; # (ʹ; ʹ; ʹ; ʹ; ʹ; ) GREEK NUMERAL SIGN
+037A;037A;037A;0020 0345;0020 0345; # (ͺ; ͺ; ͺ; ◌ͅ; ◌ͅ; ) GREEK YPOGEGRAMMENI
+037E;003B;003B;003B;003B; # (;; ;; ;; ;; ;; ) GREEK QUESTION MARK
+0384;0384;0384;0020 0301;0020 0301; # (΄; ΄; ΄; ◌́; ◌́; ) GREEK TONOS
+0385;0385;00A8 0301;0020 0308 0301;0020 0308 0301; # (΅; ΅; ¨◌́; ◌̈◌́; ◌̈◌́; ) GREEK DIALYTIKA TONOS
+0386;0386;0391 0301;0386;0391 0301; # (Ά; Ά; Α◌́; Ά; Α◌́; ) GREEK CAPITAL LETTER ALPHA WITH TONOS
+0387;00B7;00B7;00B7;00B7; # (·; ·; ·; ·; ·; ) GREEK ANO TELEIA
+0388;0388;0395 0301;0388;0395 0301; # (Έ; Έ; Ε◌́; Έ; Ε◌́; ) GREEK CAPITAL LETTER EPSILON WITH TONOS
+0389;0389;0397 0301;0389;0397 0301; # (Ή; Ή; Η◌́; Ή; Η◌́; ) GREEK CAPITAL LETTER ETA WITH TONOS
+038A;038A;0399 0301;038A;0399 0301; # (Ί; Ί; Ι◌́; Ί; Ι◌́; ) GREEK CAPITAL LETTER IOTA WITH TONOS
+038C;038C;039F 0301;038C;039F 0301; # (Ό; Ό; Ο◌́; Ό; Ο◌́; ) GREEK CAPITAL LETTER OMICRON WITH TONOS
+038E;038E;03A5 0301;038E;03A5 0301; # (Ύ; Ύ; Υ◌́; Ύ; Υ◌́; ) GREEK CAPITAL LETTER UPSILON WITH TONOS
+038F;038F;03A9 0301;038F;03A9 0301; # (Ώ; Ώ; Ω◌́; Ώ; Ω◌́; ) GREEK CAPITAL LETTER OMEGA WITH TONOS
+0390;0390;03B9 0308 0301;0390;03B9 0308 0301; # (ΐ; ΐ; ι◌̈◌́; ΐ; ι◌̈◌́; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+03AA;03AA;0399 0308;03AA;0399 0308; # (Ϊ; Ϊ; Ι◌̈; Ϊ; Ι◌̈; ) GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+03AB;03AB;03A5 0308;03AB;03A5 0308; # (Ϋ; Ϋ; Υ◌̈; Ϋ; Υ◌̈; ) GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+03AC;03AC;03B1 0301;03AC;03B1 0301; # (ά; ά; α◌́; ά; α◌́; ) GREEK SMALL LETTER ALPHA WITH TONOS
+03AD;03AD;03B5 0301;03AD;03B5 0301; # (έ; έ; ε◌́; έ; ε◌́; ) GREEK SMALL LETTER EPSILON WITH TONOS
+03AE;03AE;03B7 0301;03AE;03B7 0301; # (ή; ή; η◌́; ή; η◌́; ) GREEK SMALL LETTER ETA WITH TONOS
+03AF;03AF;03B9 0301;03AF;03B9 0301; # (ί; ί; ι◌́; ί; ι◌́; ) GREEK SMALL LETTER IOTA WITH TONOS
+03B0;03B0;03C5 0308 0301;03B0;03C5 0308 0301; # (ΰ; ΰ; υ◌̈◌́; ΰ; υ◌̈◌́; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+03CA;03CA;03B9 0308;03CA;03B9 0308; # (ϊ; ϊ; ι◌̈; ϊ; ι◌̈; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA
+03CB;03CB;03C5 0308;03CB;03C5 0308; # (ϋ; ϋ; υ◌̈; ϋ; υ◌̈; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+03CC;03CC;03BF 0301;03CC;03BF 0301; # (ό; ό; ο◌́; ό; ο◌́; ) GREEK SMALL LETTER OMICRON WITH TONOS
+03CD;03CD;03C5 0301;03CD;03C5 0301; # (ύ; ύ; υ◌́; ύ; υ◌́; ) GREEK SMALL LETTER UPSILON WITH TONOS
+03CE;03CE;03C9 0301;03CE;03C9 0301; # (ώ; ώ; ω◌́; ώ; ω◌́; ) GREEK SMALL LETTER OMEGA WITH TONOS
+03D0;03D0;03D0;03B2;03B2; # (ϐ; ϐ; ϐ; β; β; ) GREEK BETA SYMBOL
+03D1;03D1;03D1;03B8;03B8; # (ϑ; ϑ; ϑ; θ; θ; ) GREEK THETA SYMBOL
+03D2;03D2;03D2;03A5;03A5; # (ϒ; ϒ; ϒ; Υ; Υ; ) GREEK UPSILON WITH HOOK SYMBOL
+03D3;03D3;03D2 0301;038E;03A5 0301; # (ϓ; ϓ; ϒ◌́; Ύ; Υ◌́; ) GREEK UPSILON WITH ACUTE AND HOOK SYMBOL
+03D4;03D4;03D2 0308;03AB;03A5 0308; # (ϔ; ϔ; ϒ◌̈; Ϋ; Υ◌̈; ) GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL
+03D5;03D5;03D5;03C6;03C6; # (ϕ; ϕ; ϕ; φ; φ; ) GREEK PHI SYMBOL
+03D6;03D6;03D6;03C0;03C0; # (ϖ; ϖ; ϖ; π; π; ) GREEK PI SYMBOL
+03F0;03F0;03F0;03BA;03BA; # (ϰ; ϰ; ϰ; κ; κ; ) GREEK KAPPA SYMBOL
+03F1;03F1;03F1;03C1;03C1; # (ϱ; ϱ; ϱ; ρ; ρ; ) GREEK RHO SYMBOL
+03F2;03F2;03F2;03C2;03C2; # (ϲ; ϲ; ϲ; ς; ς; ) GREEK LUNATE SIGMA SYMBOL
+03F4;03F4;03F4;0398;0398; # (ϴ; ϴ; ϴ; Θ; Θ; ) GREEK CAPITAL THETA SYMBOL
+03F5;03F5;03F5;03B5;03B5; # (ϵ; ϵ; ϵ; ε; ε; ) GREEK LUNATE EPSILON SYMBOL
+03F9;03F9;03F9;03A3;03A3; # (Ϲ; Ϲ; Ϲ; Σ; Σ; ) GREEK CAPITAL LUNATE SIGMA SYMBOL
+0400;0400;0415 0300;0400;0415 0300; # (Ѐ; Ѐ; Е◌̀; Ѐ; Е◌̀; ) CYRILLIC CAPITAL LETTER IE WITH GRAVE
+0401;0401;0415 0308;0401;0415 0308; # (Ё; Ё; Е◌̈; Ё; Е◌̈; ) CYRILLIC CAPITAL LETTER IO
+0403;0403;0413 0301;0403;0413 0301; # (Ѓ; Ѓ; Г◌́; Ѓ; Г◌́; ) CYRILLIC CAPITAL LETTER GJE
+0407;0407;0406 0308;0407;0406 0308; # (Ї; Ї; І◌̈; Ї; І◌̈; ) CYRILLIC CAPITAL LETTER YI
+040C;040C;041A 0301;040C;041A 0301; # (Ќ; Ќ; К◌́; Ќ; К◌́; ) CYRILLIC CAPITAL LETTER KJE
+040D;040D;0418 0300;040D;0418 0300; # (Ѝ; Ѝ; И◌̀; Ѝ; И◌̀; ) CYRILLIC CAPITAL LETTER I WITH GRAVE
+040E;040E;0423 0306;040E;0423 0306; # (Ў; Ў; У◌̆; Ў; У◌̆; ) CYRILLIC CAPITAL LETTER SHORT U
+0419;0419;0418 0306;0419;0418 0306; # (Й; Й; И◌̆; Й; И◌̆; ) CYRILLIC CAPITAL LETTER SHORT I
+0439;0439;0438 0306;0439;0438 0306; # (й; й; и◌̆; й; и◌̆; ) CYRILLIC SMALL LETTER SHORT I
+0450;0450;0435 0300;0450;0435 0300; # (ѐ; ѐ; е◌̀; ѐ; е◌̀; ) CYRILLIC SMALL LETTER IE WITH GRAVE
+0451;0451;0435 0308;0451;0435 0308; # (ё; ё; е◌̈; ё; е◌̈; ) CYRILLIC SMALL LETTER IO
+0453;0453;0433 0301;0453;0433 0301; # (ѓ; ѓ; г◌́; ѓ; г◌́; ) CYRILLIC SMALL LETTER GJE
+0457;0457;0456 0308;0457;0456 0308; # (ї; ї; і◌̈; ї; і◌̈; ) CYRILLIC SMALL LETTER YI
+045C;045C;043A 0301;045C;043A 0301; # (ќ; ќ; к◌́; ќ; к◌́; ) CYRILLIC SMALL LETTER KJE
+045D;045D;0438 0300;045D;0438 0300; # (ѝ; ѝ; и◌̀; ѝ; и◌̀; ) CYRILLIC SMALL LETTER I WITH GRAVE
+045E;045E;0443 0306;045E;0443 0306; # (ў; ў; у◌̆; ў; у◌̆; ) CYRILLIC SMALL LETTER SHORT U
+0476;0476;0474 030F;0476;0474 030F; # (Ѷ; Ѷ; Ѵ◌̏; Ѷ; Ѵ◌̏; ) CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
+0477;0477;0475 030F;0477;0475 030F; # (ѷ; ѷ; ѵ◌̏; ѷ; ѵ◌̏; ) CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
+04C1;04C1;0416 0306;04C1;0416 0306; # (Ӂ; Ӂ; Ж◌̆; Ӂ; Ж◌̆; ) CYRILLIC CAPITAL LETTER ZHE WITH BREVE
+04C2;04C2;0436 0306;04C2;0436 0306; # (ӂ; ӂ; ж◌̆; ӂ; ж◌̆; ) CYRILLIC SMALL LETTER ZHE WITH BREVE
+04D0;04D0;0410 0306;04D0;0410 0306; # (Ӑ; Ӑ; А◌̆; Ӑ; А◌̆; ) CYRILLIC CAPITAL LETTER A WITH BREVE
+04D1;04D1;0430 0306;04D1;0430 0306; # (ӑ; ӑ; а◌̆; ӑ; а◌̆; ) CYRILLIC SMALL LETTER A WITH BREVE
+04D2;04D2;0410 0308;04D2;0410 0308; # (Ӓ; Ӓ; А◌̈; Ӓ; А◌̈; ) CYRILLIC CAPITAL LETTER A WITH DIAERESIS
+04D3;04D3;0430 0308;04D3;0430 0308; # (ӓ; ӓ; а◌̈; ӓ; а◌̈; ) CYRILLIC SMALL LETTER A WITH DIAERESIS
+04D6;04D6;0415 0306;04D6;0415 0306; # (Ӗ; Ӗ; Е◌̆; Ӗ; Е◌̆; ) CYRILLIC CAPITAL LETTER IE WITH BREVE
+04D7;04D7;0435 0306;04D7;0435 0306; # (ӗ; ӗ; е◌̆; ӗ; е◌̆; ) CYRILLIC SMALL LETTER IE WITH BREVE
+04DA;04DA;04D8 0308;04DA;04D8 0308; # (Ӛ; Ӛ; Ә◌̈; Ӛ; Ә◌̈; ) CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS
+04DB;04DB;04D9 0308;04DB;04D9 0308; # (ӛ; ӛ; ә◌̈; ӛ; ә◌̈; ) CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS
+04DC;04DC;0416 0308;04DC;0416 0308; # (Ӝ; Ӝ; Ж◌̈; Ӝ; Ж◌̈; ) CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS
+04DD;04DD;0436 0308;04DD;0436 0308; # (ӝ; ӝ; ж◌̈; ӝ; ж◌̈; ) CYRILLIC SMALL LETTER ZHE WITH DIAERESIS
+04DE;04DE;0417 0308;04DE;0417 0308; # (Ӟ; Ӟ; З◌̈; Ӟ; З◌̈; ) CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS
+04DF;04DF;0437 0308;04DF;0437 0308; # (ӟ; ӟ; з◌̈; ӟ; з◌̈; ) CYRILLIC SMALL LETTER ZE WITH DIAERESIS
+04E2;04E2;0418 0304;04E2;0418 0304; # (Ӣ; Ӣ; И◌̄; Ӣ; И◌̄; ) CYRILLIC CAPITAL LETTER I WITH MACRON
+04E3;04E3;0438 0304;04E3;0438 0304; # (ӣ; ӣ; и◌̄; ӣ; и◌̄; ) CYRILLIC SMALL LETTER I WITH MACRON
+04E4;04E4;0418 0308;04E4;0418 0308; # (Ӥ; Ӥ; И◌̈; Ӥ; И◌̈; ) CYRILLIC CAPITAL LETTER I WITH DIAERESIS
+04E5;04E5;0438 0308;04E5;0438 0308; # (ӥ; ӥ; и◌̈; ӥ; и◌̈; ) CYRILLIC SMALL LETTER I WITH DIAERESIS
+04E6;04E6;041E 0308;04E6;041E 0308; # (Ӧ; Ӧ; О◌̈; Ӧ; О◌̈; ) CYRILLIC CAPITAL LETTER O WITH DIAERESIS
+04E7;04E7;043E 0308;04E7;043E 0308; # (ӧ; ӧ; о◌̈; ӧ; о◌̈; ) CYRILLIC SMALL LETTER O WITH DIAERESIS
+04EA;04EA;04E8 0308;04EA;04E8 0308; # (Ӫ; Ӫ; Ө◌̈; Ӫ; Ө◌̈; ) CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS
+04EB;04EB;04E9 0308;04EB;04E9 0308; # (ӫ; ӫ; ө◌̈; ӫ; ө◌̈; ) CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS
+04EC;04EC;042D 0308;04EC;042D 0308; # (Ӭ; Ӭ; Э◌̈; Ӭ; Э◌̈; ) CYRILLIC CAPITAL LETTER E WITH DIAERESIS
+04ED;04ED;044D 0308;04ED;044D 0308; # (ӭ; ӭ; э◌̈; ӭ; э◌̈; ) CYRILLIC SMALL LETTER E WITH DIAERESIS
+04EE;04EE;0423 0304;04EE;0423 0304; # (Ӯ; Ӯ; У◌̄; Ӯ; У◌̄; ) CYRILLIC CAPITAL LETTER U WITH MACRON
+04EF;04EF;0443 0304;04EF;0443 0304; # (ӯ; ӯ; у◌̄; ӯ; у◌̄; ) CYRILLIC SMALL LETTER U WITH MACRON
+04F0;04F0;0423 0308;04F0;0423 0308; # (Ӱ; Ӱ; У◌̈; Ӱ; У◌̈; ) CYRILLIC CAPITAL LETTER U WITH DIAERESIS
+04F1;04F1;0443 0308;04F1;0443 0308; # (ӱ; ӱ; у◌̈; ӱ; у◌̈; ) CYRILLIC SMALL LETTER U WITH DIAERESIS
+04F2;04F2;0423 030B;04F2;0423 030B; # (Ӳ; Ӳ; У◌̋; Ӳ; У◌̋; ) CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE
+04F3;04F3;0443 030B;04F3;0443 030B; # (ӳ; ӳ; у◌̋; ӳ; у◌̋; ) CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE
+04F4;04F4;0427 0308;04F4;0427 0308; # (Ӵ; Ӵ; Ч◌̈; Ӵ; Ч◌̈; ) CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS
+04F5;04F5;0447 0308;04F5;0447 0308; # (ӵ; ӵ; ч◌̈; ӵ; ч◌̈; ) CYRILLIC SMALL LETTER CHE WITH DIAERESIS
+04F8;04F8;042B 0308;04F8;042B 0308; # (Ӹ; Ӹ; Ы◌̈; Ӹ; Ы◌̈; ) CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS
+04F9;04F9;044B 0308;04F9;044B 0308; # (ӹ; ӹ; ы◌̈; ӹ; ы◌̈; ) CYRILLIC SMALL LETTER YERU WITH DIAERESIS
+0587;0587;0587;0565 0582;0565 0582; # (և; և; և; եւ; եւ; ) ARMENIAN SMALL LIGATURE ECH YIWN
+0622;0622;0627 0653;0622;0627 0653; # (آ; آ; ا◌ٓ; آ; ا◌ٓ; ) ARABIC LETTER ALEF WITH MADDA ABOVE
+0623;0623;0627 0654;0623;0627 0654; # (أ; أ; ا◌ٔ; أ; ا◌ٔ; ) ARABIC LETTER ALEF WITH HAMZA ABOVE
+0624;0624;0648 0654;0624;0648 0654; # (ؤ; ؤ; و◌ٔ; ؤ; و◌ٔ; ) ARABIC LETTER WAW WITH HAMZA ABOVE
+0625;0625;0627 0655;0625;0627 0655; # (إ; إ; ا◌ٕ; إ; ا◌ٕ; ) ARABIC LETTER ALEF WITH HAMZA BELOW
+0626;0626;064A 0654;0626;064A 0654; # (ئ; ئ; ي◌ٔ; ئ; ي◌ٔ; ) ARABIC LETTER YEH WITH HAMZA ABOVE
+0675;0675;0675;0627 0674;0627 0674; # (ٵ; ٵ; ٵ; اٴ; اٴ; ) ARABIC LETTER HIGH HAMZA ALEF
+0676;0676;0676;0648 0674;0648 0674; # (ٶ; ٶ; ٶ; وٴ; وٴ; ) ARABIC LETTER HIGH HAMZA WAW
+0677;0677;0677;06C7 0674;06C7 0674; # (ٷ; ٷ; ٷ; ۇٴ; ۇٴ; ) ARABIC LETTER U WITH HAMZA ABOVE
+0678;0678;0678;064A 0674;064A 0674; # (ٸ; ٸ; ٸ; يٴ; يٴ; ) ARABIC LETTER HIGH HAMZA YEH
+06C0;06C0;06D5 0654;06C0;06D5 0654; # (ۀ; ۀ; ە◌ٔ; ۀ; ە◌ٔ; ) ARABIC LETTER HEH WITH YEH ABOVE
+06C2;06C2;06C1 0654;06C2;06C1 0654; # (ۂ; ۂ; ہ◌ٔ; ۂ; ہ◌ٔ; ) ARABIC LETTER HEH GOAL WITH HAMZA ABOVE
+06D3;06D3;06D2 0654;06D3;06D2 0654; # (ۓ; ۓ; ے◌ٔ; ۓ; ے◌ٔ; ) ARABIC LETTER YEH BARREE WITH HAMZA ABOVE
+0929;0929;0928 093C;0929;0928 093C; # (ऩ; ऩ; न◌़; ऩ; न◌़; ) DEVANAGARI LETTER NNNA
+0931;0931;0930 093C;0931;0930 093C; # (ऱ; ऱ; र◌़; ऱ; र◌़; ) DEVANAGARI LETTER RRA
+0934;0934;0933 093C;0934;0933 093C; # (ऴ; ऴ; ळ◌़; ऴ; ळ◌़; ) DEVANAGARI LETTER LLLA
+0958;0915 093C;0915 093C;0915 093C;0915 093C; # (क़; क◌़; क◌़; क◌़; क◌़; ) DEVANAGARI LETTER QA
+0959;0916 093C;0916 093C;0916 093C;0916 093C; # (ख़; ख◌़; ख◌़; ख◌़; ख◌़; ) DEVANAGARI LETTER KHHA
+095A;0917 093C;0917 093C;0917 093C;0917 093C; # (ग़; ग◌़; ग◌़; ग◌़; ग◌़; ) DEVANAGARI LETTER GHHA
+095B;091C 093C;091C 093C;091C 093C;091C 093C; # (ज़; ज◌़; ज◌़; ज◌़; ज◌़; ) DEVANAGARI LETTER ZA
+095C;0921 093C;0921 093C;0921 093C;0921 093C; # (ड़; ड◌़; ड◌़; ड◌़; ड◌़; ) DEVANAGARI LETTER DDDHA
+095D;0922 093C;0922 093C;0922 093C;0922 093C; # (ढ़; ढ◌़; ढ◌़; ढ◌़; ढ◌़; ) DEVANAGARI LETTER RHA
+095E;092B 093C;092B 093C;092B 093C;092B 093C; # (फ़; फ◌़; फ◌़; फ◌़; फ◌़; ) DEVANAGARI LETTER FA
+095F;092F 093C;092F 093C;092F 093C;092F 093C; # (य़; य◌़; य◌़; य◌़; य◌़; ) DEVANAGARI LETTER YYA
+09CB;09CB;09C7 09BE;09CB;09C7 09BE; # (ো; ো; ো; ো; ো; ) BENGALI VOWEL SIGN O
+09CC;09CC;09C7 09D7;09CC;09C7 09D7; # (ৌ; ৌ; ৌ; ৌ; ৌ; ) BENGALI VOWEL SIGN AU
+09DC;09A1 09BC;09A1 09BC;09A1 09BC;09A1 09BC; # (ড়; ড◌়; ড◌়; ড◌়; ড◌়; ) BENGALI LETTER RRA
+09DD;09A2 09BC;09A2 09BC;09A2 09BC;09A2 09BC; # (ঢ়; ঢ◌়; ঢ◌়; ঢ◌়; ঢ◌়; ) BENGALI LETTER RHA
+09DF;09AF 09BC;09AF 09BC;09AF 09BC;09AF 09BC; # (য়; য◌়; য◌়; য◌়; য◌়; ) BENGALI LETTER YYA
+0A33;0A32 0A3C;0A32 0A3C;0A32 0A3C;0A32 0A3C; # (ਲ਼; ਲ◌਼; ਲ◌਼; ਲ◌਼; ਲ◌਼; ) GURMUKHI LETTER LLA
+0A36;0A38 0A3C;0A38 0A3C;0A38 0A3C;0A38 0A3C; # (ਸ਼; ਸ◌਼; ਸ◌਼; ਸ◌਼; ਸ◌਼; ) GURMUKHI LETTER SHA
+0A59;0A16 0A3C;0A16 0A3C;0A16 0A3C;0A16 0A3C; # (ਖ਼; ਖ◌਼; ਖ◌਼; ਖ◌਼; ਖ◌਼; ) GURMUKHI LETTER KHHA
+0A5A;0A17 0A3C;0A17 0A3C;0A17 0A3C;0A17 0A3C; # (ਗ਼; ਗ◌਼; ਗ◌਼; ਗ◌਼; ਗ◌਼; ) GURMUKHI LETTER GHHA
+0A5B;0A1C 0A3C;0A1C 0A3C;0A1C 0A3C;0A1C 0A3C; # (ਜ਼; ਜ◌਼; ਜ◌਼; ਜ◌਼; ਜ◌਼; ) GURMUKHI LETTER ZA
+0A5E;0A2B 0A3C;0A2B 0A3C;0A2B 0A3C;0A2B 0A3C; # (ਫ਼; ਫ◌਼; ਫ◌਼; ਫ◌਼; ਫ◌਼; ) GURMUKHI LETTER FA
+0B48;0B48;0B47 0B56;0B48;0B47 0B56; # (ୈ; ୈ; େ◌ୖ; ୈ; େ◌ୖ; ) ORIYA VOWEL SIGN AI
+0B4B;0B4B;0B47 0B3E;0B4B;0B47 0B3E; # (ୋ; ୋ; ୋ; ୋ; ୋ; ) ORIYA VOWEL SIGN O
+0B4C;0B4C;0B47 0B57;0B4C;0B47 0B57; # (ୌ; ୌ; ୌ; ୌ; ୌ; ) ORIYA VOWEL SIGN AU
+0B5C;0B21 0B3C;0B21 0B3C;0B21 0B3C;0B21 0B3C; # (ଡ଼; ଡ◌଼; ଡ◌଼; ଡ◌଼; ଡ◌଼; ) ORIYA LETTER RRA
+0B5D;0B22 0B3C;0B22 0B3C;0B22 0B3C;0B22 0B3C; # (ଢ଼; ଢ◌଼; ଢ◌଼; ଢ◌଼; ଢ◌଼; ) ORIYA LETTER RHA
+0B94;0B94;0B92 0BD7;0B94;0B92 0BD7; # (ஔ; ஔ; ஔ; ஔ; ஔ; ) TAMIL LETTER AU
+0BCA;0BCA;0BC6 0BBE;0BCA;0BC6 0BBE; # (ொ; ொ; ொ; ொ; ொ; ) TAMIL VOWEL SIGN O
+0BCB;0BCB;0BC7 0BBE;0BCB;0BC7 0BBE; # (ோ; ோ; ோ; ோ; ோ; ) TAMIL VOWEL SIGN OO
+0BCC;0BCC;0BC6 0BD7;0BCC;0BC6 0BD7; # (ௌ; ௌ; ௌ; ௌ; ௌ; ) TAMIL VOWEL SIGN AU
+0C48;0C48;0C46 0C56;0C48;0C46 0C56; # (◌ై; ◌ై; ◌ె◌ౖ; ◌ై; ◌ె◌ౖ; ) TELUGU VOWEL SIGN AI
+0CC0;0CC0;0CBF 0CD5;0CC0;0CBF 0CD5; # (ೀ; ೀ; ◌ೀ; ೀ; ◌ೀ; ) KANNADA VOWEL SIGN II
+0CC7;0CC7;0CC6 0CD5;0CC7;0CC6 0CD5; # (ೇ; ೇ; ◌ೇ; ೇ; ◌ೇ; ) KANNADA VOWEL SIGN EE
+0CC8;0CC8;0CC6 0CD6;0CC8;0CC6 0CD6; # (ೈ; ೈ; ◌ೈ; ೈ; ◌ೈ; ) KANNADA VOWEL SIGN AI
+0CCA;0CCA;0CC6 0CC2;0CCA;0CC6 0CC2; # (ೊ; ೊ; ◌ೊ; ೊ; ◌ೊ; ) KANNADA VOWEL SIGN O
+0CCB;0CCB;0CC6 0CC2 0CD5;0CCB;0CC6 0CC2 0CD5; # (ೋ; ೋ; ◌ೋ; ೋ; ◌ೋ; ) KANNADA VOWEL SIGN OO
+0D4A;0D4A;0D46 0D3E;0D4A;0D46 0D3E; # (ൊ; ൊ; ൊ; ൊ; ൊ; ) MALAYALAM VOWEL SIGN O
+0D4B;0D4B;0D47 0D3E;0D4B;0D47 0D3E; # (ോ; ോ; ോ; ോ; ോ; ) MALAYALAM VOWEL SIGN OO
+0D4C;0D4C;0D46 0D57;0D4C;0D46 0D57; # (ൌ; ൌ; ൌ; ൌ; ൌ; ) MALAYALAM VOWEL SIGN AU
+0DDA;0DDA;0DD9 0DCA;0DDA;0DD9 0DCA; # (ේ; ේ; ෙ◌්; ේ; ෙ◌්; ) SINHALA VOWEL SIGN DIGA KOMBUVA
+0DDC;0DDC;0DD9 0DCF;0DDC;0DD9 0DCF; # (ො; ො; ො; ො; ො; ) SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA
+0DDD;0DDD;0DD9 0DCF 0DCA;0DDD;0DD9 0DCF 0DCA; # (ෝ; ෝ; ො◌්; ෝ; ො◌්; ) SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA
+0DDE;0DDE;0DD9 0DDF;0DDE;0DD9 0DDF; # (ෞ; ෞ; ෞ; ෞ; ෞ; ) SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA
+0E33;0E33;0E33;0E4D 0E32;0E4D 0E32; # (ำ; ำ; ำ; ◌ํา; ◌ํา; ) THAI CHARACTER SARA AM
+0EB3;0EB3;0EB3;0ECD 0EB2;0ECD 0EB2; # (ຳ; ຳ; ຳ; ◌ໍາ; ◌ໍາ; ) LAO VOWEL SIGN AM
+0EDC;0EDC;0EDC;0EAB 0E99;0EAB 0E99; # (ໜ; ໜ; ໜ; ຫນ; ຫນ; ) LAO HO NO
+0EDD;0EDD;0EDD;0EAB 0EA1;0EAB 0EA1; # (ໝ; ໝ; ໝ; ຫມ; ຫມ; ) LAO HO MO
+0F0C;0F0C;0F0C;0F0B;0F0B; # (༌; ༌; ༌; ་; ་; ) TIBETAN MARK DELIMITER TSHEG BSTAR
+0F43;0F42 0FB7;0F42 0FB7;0F42 0FB7;0F42 0FB7; # (གྷ; ག◌ྷ; ག◌ྷ; ག◌ྷ; ག◌ྷ; ) TIBETAN LETTER GHA
+0F4D;0F4C 0FB7;0F4C 0FB7;0F4C 0FB7;0F4C 0FB7; # (ཌྷ; ཌ◌ྷ; ཌ◌ྷ; ཌ◌ྷ; ཌ◌ྷ; ) TIBETAN LETTER DDHA
+0F52;0F51 0FB7;0F51 0FB7;0F51 0FB7;0F51 0FB7; # (དྷ; ད◌ྷ; ད◌ྷ; ད◌ྷ; ད◌ྷ; ) TIBETAN LETTER DHA
+0F57;0F56 0FB7;0F56 0FB7;0F56 0FB7;0F56 0FB7; # (བྷ; བ◌ྷ; བ◌ྷ; བ◌ྷ; བ◌ྷ; ) TIBETAN LETTER BHA
+0F5C;0F5B 0FB7;0F5B 0FB7;0F5B 0FB7;0F5B 0FB7; # (ཛྷ; ཛ◌ྷ; ཛ◌ྷ; ཛ◌ྷ; ཛ◌ྷ; ) TIBETAN LETTER DZHA
+0F69;0F40 0FB5;0F40 0FB5;0F40 0FB5;0F40 0FB5; # (ཀྵ; ཀ◌ྵ; ཀ◌ྵ; ཀ◌ྵ; ཀ◌ྵ; ) TIBETAN LETTER KSSA
+0F73;0F71 0F72;0F71 0F72;0F71 0F72;0F71 0F72; # (◌ཱི; ◌ཱ◌ི; ◌ཱ◌ི; ◌ཱ◌ི; ◌ཱ◌ི; ) TIBETAN VOWEL SIGN II
+0F75;0F71 0F74;0F71 0F74;0F71 0F74;0F71 0F74; # (◌ཱུ; ◌ཱ◌ུ; ◌ཱ◌ུ; ◌ཱ◌ུ; ◌ཱ◌ུ; ) TIBETAN VOWEL SIGN UU
+0F76;0FB2 0F80;0FB2 0F80;0FB2 0F80;0FB2 0F80; # (◌ྲྀ; ◌ྲ◌ྀ; ◌ྲ◌ྀ; ◌ྲ◌ྀ; ◌ྲ◌ྀ; ) TIBETAN VOWEL SIGN VOCALIC R
+0F77;0F77;0F77;0FB2 0F71 0F80;0FB2 0F71 0F80; # (◌ཷ; ◌ཷ; ◌ཷ; ◌ྲ◌ཱ◌ྀ; ◌ྲ◌ཱ◌ྀ; ) TIBETAN VOWEL SIGN VOCALIC RR
+0F78;0FB3 0F80;0FB3 0F80;0FB3 0F80;0FB3 0F80; # (◌ླྀ; ◌ླ◌ྀ; ◌ླ◌ྀ; ◌ླ◌ྀ; ◌ླ◌ྀ; ) TIBETAN VOWEL SIGN VOCALIC L
+0F79;0F79;0F79;0FB3 0F71 0F80;0FB3 0F71 0F80; # (◌ཹ; ◌ཹ; ◌ཹ; ◌ླ◌ཱ◌ྀ; ◌ླ◌ཱ◌ྀ; ) TIBETAN VOWEL SIGN VOCALIC LL
+0F81;0F71 0F80;0F71 0F80;0F71 0F80;0F71 0F80; # (◌ཱྀ; ◌ཱ◌ྀ; ◌ཱ◌ྀ; ◌ཱ◌ྀ; ◌ཱ◌ྀ; ) TIBETAN VOWEL SIGN REVERSED II
+0F93;0F92 0FB7;0F92 0FB7;0F92 0FB7;0F92 0FB7; # (◌ྒྷ; ◌ྒ◌ྷ; ◌ྒ◌ྷ; ◌ྒ◌ྷ; ◌ྒ◌ྷ; ) TIBETAN SUBJOINED LETTER GHA
+0F9D;0F9C 0FB7;0F9C 0FB7;0F9C 0FB7;0F9C 0FB7; # (◌ྜྷ; ◌ྜ◌ྷ; ◌ྜ◌ྷ; ◌ྜ◌ྷ; ◌ྜ◌ྷ; ) TIBETAN SUBJOINED LETTER DDHA
+0FA2;0FA1 0FB7;0FA1 0FB7;0FA1 0FB7;0FA1 0FB7; # (◌ྡྷ; ◌ྡ◌ྷ; ◌ྡ◌ྷ; ◌ྡ◌ྷ; ◌ྡ◌ྷ; ) TIBETAN SUBJOINED LETTER DHA
+0FA7;0FA6 0FB7;0FA6 0FB7;0FA6 0FB7;0FA6 0FB7; # (◌ྦྷ; ◌ྦ◌ྷ; ◌ྦ◌ྷ; ◌ྦ◌ྷ; ◌ྦ◌ྷ; ) TIBETAN SUBJOINED LETTER BHA
+0FAC;0FAB 0FB7;0FAB 0FB7;0FAB 0FB7;0FAB 0FB7; # (◌ྫྷ; ◌ྫ◌ྷ; ◌ྫ◌ྷ; ◌ྫ◌ྷ; ◌ྫ◌ྷ; ) TIBETAN SUBJOINED LETTER DZHA
+0FB9;0F90 0FB5;0F90 0FB5;0F90 0FB5;0F90 0FB5; # (◌ྐྵ; ◌ྐ◌ྵ; ◌ྐ◌ྵ; ◌ྐ◌ྵ; ◌ྐ◌ྵ; ) TIBETAN SUBJOINED LETTER KSSA
+1026;1026;1025 102E;1026;1025 102E; # (ဦ; ဦ; ဥ◌ီ; ဦ; ဥ◌ီ; ) MYANMAR LETTER UU
+10FC;10FC;10FC;10DC;10DC; # (ჼ; ჼ; ჼ; ნ; ნ; ) MODIFIER LETTER GEORGIAN NAR
+1B06;1B06;1B05 1B35;1B06;1B05 1B35; # (ᬆ; ᬆ; ᬆ; ᬆ; ᬆ; ) BALINESE LETTER AKARA TEDUNG
+1B08;1B08;1B07 1B35;1B08;1B07 1B35; # (ᬈ; ᬈ; ᬈ; ᬈ; ᬈ; ) BALINESE LETTER IKARA TEDUNG
+1B0A;1B0A;1B09 1B35;1B0A;1B09 1B35; # (ᬊ; ᬊ; ᬊ; ᬊ; ᬊ; ) BALINESE LETTER UKARA TEDUNG
+1B0C;1B0C;1B0B 1B35;1B0C;1B0B 1B35; # (ᬌ; ᬌ; ᬌ; ᬌ; ᬌ; ) BALINESE LETTER RA REPA TEDUNG
+1B0E;1B0E;1B0D 1B35;1B0E;1B0D 1B35; # (ᬎ; ᬎ; ᬎ; ᬎ; ᬎ; ) BALINESE LETTER LA LENGA TEDUNG
+1B12;1B12;1B11 1B35;1B12;1B11 1B35; # (ᬒ; ᬒ; ᬒ; ᬒ; ᬒ; ) BALINESE LETTER OKARA TEDUNG
+1B3B;1B3B;1B3A 1B35;1B3B;1B3A 1B35; # (ᬻ; ᬻ; ◌ᬻ; ᬻ; ◌ᬻ; ) BALINESE VOWEL SIGN RA REPA TEDUNG
+1B3D;1B3D;1B3C 1B35;1B3D;1B3C 1B35; # (ᬽ; ᬽ; ◌ᬽ; ᬽ; ◌ᬽ; ) BALINESE VOWEL SIGN LA LENGA TEDUNG
+1B40;1B40;1B3E 1B35;1B40;1B3E 1B35; # (ᭀ; ᭀ; ᭀ; ᭀ; ᭀ; ) BALINESE VOWEL SIGN TALING TEDUNG
+1B41;1B41;1B3F 1B35;1B41;1B3F 1B35; # (ᭁ; ᭁ; ᭁ; ᭁ; ᭁ; ) BALINESE VOWEL SIGN TALING REPA TEDUNG
+1B43;1B43;1B42 1B35;1B43;1B42 1B35; # (ᭃ; ᭃ; ◌ᭃ; ᭃ; ◌ᭃ; ) BALINESE VOWEL SIGN PEPET TEDUNG
+1D2C;1D2C;1D2C;0041;0041; # (ᴬ; ᴬ; ᴬ; A; A; ) MODIFIER LETTER CAPITAL A
+1D2D;1D2D;1D2D;00C6;00C6; # (ᴭ; ᴭ; ᴭ; Æ; Æ; ) MODIFIER LETTER CAPITAL AE
+1D2E;1D2E;1D2E;0042;0042; # (ᴮ; ᴮ; ᴮ; B; B; ) MODIFIER LETTER CAPITAL B
+1D30;1D30;1D30;0044;0044; # (ᴰ; ᴰ; ᴰ; D; D; ) MODIFIER LETTER CAPITAL D
+1D31;1D31;1D31;0045;0045; # (ᴱ; ᴱ; ᴱ; E; E; ) MODIFIER LETTER CAPITAL E
+1D32;1D32;1D32;018E;018E; # (ᴲ; ᴲ; ᴲ; Ǝ; Ǝ; ) MODIFIER LETTER CAPITAL REVERSED E
+1D33;1D33;1D33;0047;0047; # (ᴳ; ᴳ; ᴳ; G; G; ) MODIFIER LETTER CAPITAL G
+1D34;1D34;1D34;0048;0048; # (ᴴ; ᴴ; ᴴ; H; H; ) MODIFIER LETTER CAPITAL H
+1D35;1D35;1D35;0049;0049; # (ᴵ; ᴵ; ᴵ; I; I; ) MODIFIER LETTER CAPITAL I
+1D36;1D36;1D36;004A;004A; # (ᴶ; ᴶ; ᴶ; J; J; ) MODIFIER LETTER CAPITAL J
+1D37;1D37;1D37;004B;004B; # (ᴷ; ᴷ; ᴷ; K; K; ) MODIFIER LETTER CAPITAL K
+1D38;1D38;1D38;004C;004C; # (ᴸ; ᴸ; ᴸ; L; L; ) MODIFIER LETTER CAPITAL L
+1D39;1D39;1D39;004D;004D; # (ᴹ; ᴹ; ᴹ; M; M; ) MODIFIER LETTER CAPITAL M
+1D3A;1D3A;1D3A;004E;004E; # (ᴺ; ᴺ; ᴺ; N; N; ) MODIFIER LETTER CAPITAL N
+1D3C;1D3C;1D3C;004F;004F; # (ᴼ; ᴼ; ᴼ; O; O; ) MODIFIER LETTER CAPITAL O
+1D3D;1D3D;1D3D;0222;0222; # (ᴽ; ᴽ; ᴽ; Ȣ; Ȣ; ) MODIFIER LETTER CAPITAL OU
+1D3E;1D3E;1D3E;0050;0050; # (ᴾ; ᴾ; ᴾ; P; P; ) MODIFIER LETTER CAPITAL P
+1D3F;1D3F;1D3F;0052;0052; # (ᴿ; ᴿ; ᴿ; R; R; ) MODIFIER LETTER CAPITAL R
+1D40;1D40;1D40;0054;0054; # (ᵀ; ᵀ; ᵀ; T; T; ) MODIFIER LETTER CAPITAL T
+1D41;1D41;1D41;0055;0055; # (ᵁ; ᵁ; ᵁ; U; U; ) MODIFIER LETTER CAPITAL U
+1D42;1D42;1D42;0057;0057; # (ᵂ; ᵂ; ᵂ; W; W; ) MODIFIER LETTER CAPITAL W
+1D43;1D43;1D43;0061;0061; # (ᵃ; ᵃ; ᵃ; a; a; ) MODIFIER LETTER SMALL A
+1D44;1D44;1D44;0250;0250; # (ᵄ; ᵄ; ᵄ; ɐ; ɐ; ) MODIFIER LETTER SMALL TURNED A
+1D45;1D45;1D45;0251;0251; # (ᵅ; ᵅ; ᵅ; ɑ; ɑ; ) MODIFIER LETTER SMALL ALPHA
+1D46;1D46;1D46;1D02;1D02; # (ᵆ; ᵆ; ᵆ; ᴂ; ᴂ; ) MODIFIER LETTER SMALL TURNED AE
+1D47;1D47;1D47;0062;0062; # (ᵇ; ᵇ; ᵇ; b; b; ) MODIFIER LETTER SMALL B
+1D48;1D48;1D48;0064;0064; # (ᵈ; ᵈ; ᵈ; d; d; ) MODIFIER LETTER SMALL D
+1D49;1D49;1D49;0065;0065; # (ᵉ; ᵉ; ᵉ; e; e; ) MODIFIER LETTER SMALL E
+1D4A;1D4A;1D4A;0259;0259; # (ᵊ; ᵊ; ᵊ; ə; ə; ) MODIFIER LETTER SMALL SCHWA
+1D4B;1D4B;1D4B;025B;025B; # (ᵋ; ᵋ; ᵋ; ɛ; ɛ; ) MODIFIER LETTER SMALL OPEN E
+1D4C;1D4C;1D4C;025C;025C; # (ᵌ; ᵌ; ᵌ; ɜ; ɜ; ) MODIFIER LETTER SMALL TURNED OPEN E
+1D4D;1D4D;1D4D;0067;0067; # (ᵍ; ᵍ; ᵍ; g; g; ) MODIFIER LETTER SMALL G
+1D4F;1D4F;1D4F;006B;006B; # (ᵏ; ᵏ; ᵏ; k; k; ) MODIFIER LETTER SMALL K
+1D50;1D50;1D50;006D;006D; # (ᵐ; ᵐ; ᵐ; m; m; ) MODIFIER LETTER SMALL M
+1D51;1D51;1D51;014B;014B; # (ᵑ; ᵑ; ᵑ; ŋ; ŋ; ) MODIFIER LETTER SMALL ENG
+1D52;1D52;1D52;006F;006F; # (ᵒ; ᵒ; ᵒ; o; o; ) MODIFIER LETTER SMALL O
+1D53;1D53;1D53;0254;0254; # (ᵓ; ᵓ; ᵓ; ɔ; ɔ; ) MODIFIER LETTER SMALL OPEN O
+1D54;1D54;1D54;1D16;1D16; # (ᵔ; ᵔ; ᵔ; ᴖ; ᴖ; ) MODIFIER LETTER SMALL TOP HALF O
+1D55;1D55;1D55;1D17;1D17; # (ᵕ; ᵕ; ᵕ; ᴗ; ᴗ; ) MODIFIER LETTER SMALL BOTTOM HALF O
+1D56;1D56;1D56;0070;0070; # (ᵖ; ᵖ; ᵖ; p; p; ) MODIFIER LETTER SMALL P
+1D57;1D57;1D57;0074;0074; # (ᵗ; ᵗ; ᵗ; t; t; ) MODIFIER LETTER SMALL T
+1D58;1D58;1D58;0075;0075; # (ᵘ; ᵘ; ᵘ; u; u; ) MODIFIER LETTER SMALL U
+1D59;1D59;1D59;1D1D;1D1D; # (ᵙ; ᵙ; ᵙ; ᴝ; ᴝ; ) MODIFIER LETTER SMALL SIDEWAYS U
+1D5A;1D5A;1D5A;026F;026F; # (ᵚ; ᵚ; ᵚ; ɯ; ɯ; ) MODIFIER LETTER SMALL TURNED M
+1D5B;1D5B;1D5B;0076;0076; # (ᵛ; ᵛ; ᵛ; v; v; ) MODIFIER LETTER SMALL V
+1D5C;1D5C;1D5C;1D25;1D25; # (ᵜ; ᵜ; ᵜ; ᴥ; ᴥ; ) MODIFIER LETTER SMALL AIN
+1D5D;1D5D;1D5D;03B2;03B2; # (ᵝ; ᵝ; ᵝ; β; β; ) MODIFIER LETTER SMALL BETA
+1D5E;1D5E;1D5E;03B3;03B3; # (ᵞ; ᵞ; ᵞ; γ; γ; ) MODIFIER LETTER SMALL GREEK GAMMA
+1D5F;1D5F;1D5F;03B4;03B4; # (ᵟ; ᵟ; ᵟ; δ; δ; ) MODIFIER LETTER SMALL DELTA
+1D60;1D60;1D60;03C6;03C6; # (ᵠ; ᵠ; ᵠ; φ; φ; ) MODIFIER LETTER SMALL GREEK PHI
+1D61;1D61;1D61;03C7;03C7; # (ᵡ; ᵡ; ᵡ; χ; χ; ) MODIFIER LETTER SMALL CHI
+1D62;1D62;1D62;0069;0069; # (ᵢ; ᵢ; ᵢ; i; i; ) LATIN SUBSCRIPT SMALL LETTER I
+1D63;1D63;1D63;0072;0072; # (ᵣ; ᵣ; ᵣ; r; r; ) LATIN SUBSCRIPT SMALL LETTER R
+1D64;1D64;1D64;0075;0075; # (ᵤ; ᵤ; ᵤ; u; u; ) LATIN SUBSCRIPT SMALL LETTER U
+1D65;1D65;1D65;0076;0076; # (ᵥ; ᵥ; ᵥ; v; v; ) LATIN SUBSCRIPT SMALL LETTER V
+1D66;1D66;1D66;03B2;03B2; # (ᵦ; ᵦ; ᵦ; β; β; ) GREEK SUBSCRIPT SMALL LETTER BETA
+1D67;1D67;1D67;03B3;03B3; # (ᵧ; ᵧ; ᵧ; γ; γ; ) GREEK SUBSCRIPT SMALL LETTER GAMMA
+1D68;1D68;1D68;03C1;03C1; # (ᵨ; ᵨ; ᵨ; ρ; ρ; ) GREEK SUBSCRIPT SMALL LETTER RHO
+1D69;1D69;1D69;03C6;03C6; # (ᵩ; ᵩ; ᵩ; φ; φ; ) GREEK SUBSCRIPT SMALL LETTER PHI
+1D6A;1D6A;1D6A;03C7;03C7; # (ᵪ; ᵪ; ᵪ; χ; χ; ) GREEK SUBSCRIPT SMALL LETTER CHI
+1D78;1D78;1D78;043D;043D; # (ᵸ; ᵸ; ᵸ; н; н; ) MODIFIER LETTER CYRILLIC EN
+1D9B;1D9B;1D9B;0252;0252; # (ᶛ; ᶛ; ᶛ; ɒ; ɒ; ) MODIFIER LETTER SMALL TURNED ALPHA
+1D9C;1D9C;1D9C;0063;0063; # (ᶜ; ᶜ; ᶜ; c; c; ) MODIFIER LETTER SMALL C
+1D9D;1D9D;1D9D;0255;0255; # (ᶝ; ᶝ; ᶝ; ɕ; ɕ; ) MODIFIER LETTER SMALL C WITH CURL
+1D9E;1D9E;1D9E;00F0;00F0; # (ᶞ; ᶞ; ᶞ; ð; ð; ) MODIFIER LETTER SMALL ETH
+1D9F;1D9F;1D9F;025C;025C; # (ᶟ; ᶟ; ᶟ; ɜ; ɜ; ) MODIFIER LETTER SMALL REVERSED OPEN E
+1DA0;1DA0;1DA0;0066;0066; # (ᶠ; ᶠ; ᶠ; f; f; ) MODIFIER LETTER SMALL F
+1DA1;1DA1;1DA1;025F;025F; # (ᶡ; ᶡ; ᶡ; ɟ; ɟ; ) MODIFIER LETTER SMALL DOTLESS J WITH STROKE
+1DA2;1DA2;1DA2;0261;0261; # (ᶢ; ᶢ; ᶢ; ɡ; ɡ; ) MODIFIER LETTER SMALL SCRIPT G
+1DA3;1DA3;1DA3;0265;0265; # (ᶣ; ᶣ; ᶣ; ɥ; ɥ; ) MODIFIER LETTER SMALL TURNED H
+1DA4;1DA4;1DA4;0268;0268; # (ᶤ; ᶤ; ᶤ; ɨ; ɨ; ) MODIFIER LETTER SMALL I WITH STROKE
+1DA5;1DA5;1DA5;0269;0269; # (ᶥ; ᶥ; ᶥ; ɩ; ɩ; ) MODIFIER LETTER SMALL IOTA
+1DA6;1DA6;1DA6;026A;026A; # (ᶦ; ᶦ; ᶦ; ɪ; ɪ; ) MODIFIER LETTER SMALL CAPITAL I
+1DA7;1DA7;1DA7;1D7B;1D7B; # (ᶧ; ᶧ; ᶧ; ᵻ; ᵻ; ) MODIFIER LETTER SMALL CAPITAL I WITH STROKE
+1DA8;1DA8;1DA8;029D;029D; # (ᶨ; ᶨ; ᶨ; ʝ; ʝ; ) MODIFIER LETTER SMALL J WITH CROSSED-TAIL
+1DA9;1DA9;1DA9;026D;026D; # (ᶩ; ᶩ; ᶩ; ɭ; ɭ; ) MODIFIER LETTER SMALL L WITH RETROFLEX HOOK
+1DAA;1DAA;1DAA;1D85;1D85; # (ᶪ; ᶪ; ᶪ; ᶅ; ᶅ; ) MODIFIER LETTER SMALL L WITH PALATAL HOOK
+1DAB;1DAB;1DAB;029F;029F; # (ᶫ; ᶫ; ᶫ; ʟ; ʟ; ) MODIFIER LETTER SMALL CAPITAL L
+1DAC;1DAC;1DAC;0271;0271; # (ᶬ; ᶬ; ᶬ; ɱ; ɱ; ) MODIFIER LETTER SMALL M WITH HOOK
+1DAD;1DAD;1DAD;0270;0270; # (ᶭ; ᶭ; ᶭ; ɰ; ɰ; ) MODIFIER LETTER SMALL TURNED M WITH LONG LEG
+1DAE;1DAE;1DAE;0272;0272; # (ᶮ; ᶮ; ᶮ; ɲ; ɲ; ) MODIFIER LETTER SMALL N WITH LEFT HOOK
+1DAF;1DAF;1DAF;0273;0273; # (ᶯ; ᶯ; ᶯ; ɳ; ɳ; ) MODIFIER LETTER SMALL N WITH RETROFLEX HOOK
+1DB0;1DB0;1DB0;0274;0274; # (ᶰ; ᶰ; ᶰ; ɴ; ɴ; ) MODIFIER LETTER SMALL CAPITAL N
+1DB1;1DB1;1DB1;0275;0275; # (ᶱ; ᶱ; ᶱ; ɵ; ɵ; ) MODIFIER LETTER SMALL BARRED O
+1DB2;1DB2;1DB2;0278;0278; # (ᶲ; ᶲ; ᶲ; ɸ; ɸ; ) MODIFIER LETTER SMALL PHI
+1DB3;1DB3;1DB3;0282;0282; # (ᶳ; ᶳ; ᶳ; ʂ; ʂ; ) MODIFIER LETTER SMALL S WITH HOOK
+1DB4;1DB4;1DB4;0283;0283; # (ᶴ; ᶴ; ᶴ; ʃ; ʃ; ) MODIFIER LETTER SMALL ESH
+1DB5;1DB5;1DB5;01AB;01AB; # (ᶵ; ᶵ; ᶵ; ƫ; ƫ; ) MODIFIER LETTER SMALL T WITH PALATAL HOOK
+1DB6;1DB6;1DB6;0289;0289; # (ᶶ; ᶶ; ᶶ; ʉ; ʉ; ) MODIFIER LETTER SMALL U BAR
+1DB7;1DB7;1DB7;028A;028A; # (ᶷ; ᶷ; ᶷ; ʊ; ʊ; ) MODIFIER LETTER SMALL UPSILON
+1DB8;1DB8;1DB8;1D1C;1D1C; # (ᶸ; ᶸ; ᶸ; ᴜ; ᴜ; ) MODIFIER LETTER SMALL CAPITAL U
+1DB9;1DB9;1DB9;028B;028B; # (ᶹ; ᶹ; ᶹ; ʋ; ʋ; ) MODIFIER LETTER SMALL V WITH HOOK
+1DBA;1DBA;1DBA;028C;028C; # (ᶺ; ᶺ; ᶺ; ʌ; ʌ; ) MODIFIER LETTER SMALL TURNED V
+1DBB;1DBB;1DBB;007A;007A; # (ᶻ; ᶻ; ᶻ; z; z; ) MODIFIER LETTER SMALL Z
+1DBC;1DBC;1DBC;0290;0290; # (ᶼ; ᶼ; ᶼ; ʐ; ʐ; ) MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK
+1DBD;1DBD;1DBD;0291;0291; # (ᶽ; ᶽ; ᶽ; ʑ; ʑ; ) MODIFIER LETTER SMALL Z WITH CURL
+1DBE;1DBE;1DBE;0292;0292; # (ᶾ; ᶾ; ᶾ; ʒ; ʒ; ) MODIFIER LETTER SMALL EZH
+1DBF;1DBF;1DBF;03B8;03B8; # (ᶿ; ᶿ; ᶿ; θ; θ; ) MODIFIER LETTER SMALL THETA
+1E00;1E00;0041 0325;1E00;0041 0325; # (Ḁ; Ḁ; A◌̥; Ḁ; A◌̥; ) LATIN CAPITAL LETTER A WITH RING BELOW
+1E01;1E01;0061 0325;1E01;0061 0325; # (ḁ; ḁ; a◌̥; ḁ; a◌̥; ) LATIN SMALL LETTER A WITH RING BELOW
+1E02;1E02;0042 0307;1E02;0042 0307; # (Ḃ; Ḃ; B◌̇; Ḃ; B◌̇; ) LATIN CAPITAL LETTER B WITH DOT ABOVE
+1E03;1E03;0062 0307;1E03;0062 0307; # (ḃ; ḃ; b◌̇; ḃ; b◌̇; ) LATIN SMALL LETTER B WITH DOT ABOVE
+1E04;1E04;0042 0323;1E04;0042 0323; # (Ḅ; Ḅ; B◌̣; Ḅ; B◌̣; ) LATIN CAPITAL LETTER B WITH DOT BELOW
+1E05;1E05;0062 0323;1E05;0062 0323; # (ḅ; ḅ; b◌̣; ḅ; b◌̣; ) LATIN SMALL LETTER B WITH DOT BELOW
+1E06;1E06;0042 0331;1E06;0042 0331; # (Ḇ; Ḇ; B◌̱; Ḇ; B◌̱; ) LATIN CAPITAL LETTER B WITH LINE BELOW
+1E07;1E07;0062 0331;1E07;0062 0331; # (ḇ; ḇ; b◌̱; ḇ; b◌̱; ) LATIN SMALL LETTER B WITH LINE BELOW
+1E08;1E08;0043 0327 0301;1E08;0043 0327 0301; # (Ḉ; Ḉ; C◌̧◌́; Ḉ; C◌̧◌́; ) LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
+1E09;1E09;0063 0327 0301;1E09;0063 0327 0301; # (ḉ; ḉ; c◌̧◌́; ḉ; c◌̧◌́; ) LATIN SMALL LETTER C WITH CEDILLA AND ACUTE
+1E0A;1E0A;0044 0307;1E0A;0044 0307; # (Ḋ; Ḋ; D◌̇; Ḋ; D◌̇; ) LATIN CAPITAL LETTER D WITH DOT ABOVE
+1E0B;1E0B;0064 0307;1E0B;0064 0307; # (ḋ; ḋ; d◌̇; ḋ; d◌̇; ) LATIN SMALL LETTER D WITH DOT ABOVE
+1E0C;1E0C;0044 0323;1E0C;0044 0323; # (Ḍ; Ḍ; D◌̣; Ḍ; D◌̣; ) LATIN CAPITAL LETTER D WITH DOT BELOW
+1E0D;1E0D;0064 0323;1E0D;0064 0323; # (ḍ; ḍ; d◌̣; ḍ; d◌̣; ) LATIN SMALL LETTER D WITH DOT BELOW
+1E0E;1E0E;0044 0331;1E0E;0044 0331; # (Ḏ; Ḏ; D◌̱; Ḏ; D◌̱; ) LATIN CAPITAL LETTER D WITH LINE BELOW
+1E0F;1E0F;0064 0331;1E0F;0064 0331; # (ḏ; ḏ; d◌̱; ḏ; d◌̱; ) LATIN SMALL LETTER D WITH LINE BELOW
+1E10;1E10;0044 0327;1E10;0044 0327; # (Ḑ; Ḑ; D◌̧; Ḑ; D◌̧; ) LATIN CAPITAL LETTER D WITH CEDILLA
+1E11;1E11;0064 0327;1E11;0064 0327; # (ḑ; ḑ; d◌̧; ḑ; d◌̧; ) LATIN SMALL LETTER D WITH CEDILLA
+1E12;1E12;0044 032D;1E12;0044 032D; # (Ḓ; Ḓ; D◌̭; Ḓ; D◌̭; ) LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
+1E13;1E13;0064 032D;1E13;0064 032D; # (ḓ; ḓ; d◌̭; ḓ; d◌̭; ) LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW
+1E14;1E14;0045 0304 0300;1E14;0045 0304 0300; # (Ḕ; Ḕ; E◌̄◌̀; Ḕ; E◌̄◌̀; ) LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
+1E15;1E15;0065 0304 0300;1E15;0065 0304 0300; # (ḕ; ḕ; e◌̄◌̀; ḕ; e◌̄◌̀; ) LATIN SMALL LETTER E WITH MACRON AND GRAVE
+1E16;1E16;0045 0304 0301;1E16;0045 0304 0301; # (Ḗ; Ḗ; E◌̄◌́; Ḗ; E◌̄◌́; ) LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
+1E17;1E17;0065 0304 0301;1E17;0065 0304 0301; # (ḗ; ḗ; e◌̄◌́; ḗ; e◌̄◌́; ) LATIN SMALL LETTER E WITH MACRON AND ACUTE
+1E18;1E18;0045 032D;1E18;0045 032D; # (Ḙ; Ḙ; E◌̭; Ḙ; E◌̭; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
+1E19;1E19;0065 032D;1E19;0065 032D; # (ḙ; ḙ; e◌̭; ḙ; e◌̭; ) LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW
+1E1A;1E1A;0045 0330;1E1A;0045 0330; # (Ḛ; Ḛ; E◌̰; Ḛ; E◌̰; ) LATIN CAPITAL LETTER E WITH TILDE BELOW
+1E1B;1E1B;0065 0330;1E1B;0065 0330; # (ḛ; ḛ; e◌̰; ḛ; e◌̰; ) LATIN SMALL LETTER E WITH TILDE BELOW
+1E1C;1E1C;0045 0327 0306;1E1C;0045 0327 0306; # (Ḝ; Ḝ; E◌̧◌̆; Ḝ; E◌̧◌̆; ) LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
+1E1D;1E1D;0065 0327 0306;1E1D;0065 0327 0306; # (ḝ; ḝ; e◌̧◌̆; ḝ; e◌̧◌̆; ) LATIN SMALL LETTER E WITH CEDILLA AND BREVE
+1E1E;1E1E;0046 0307;1E1E;0046 0307; # (Ḟ; Ḟ; F◌̇; Ḟ; F◌̇; ) LATIN CAPITAL LETTER F WITH DOT ABOVE
+1E1F;1E1F;0066 0307;1E1F;0066 0307; # (ḟ; ḟ; f◌̇; ḟ; f◌̇; ) LATIN SMALL LETTER F WITH DOT ABOVE
+1E20;1E20;0047 0304;1E20;0047 0304; # (Ḡ; Ḡ; G◌̄; Ḡ; G◌̄; ) LATIN CAPITAL LETTER G WITH MACRON
+1E21;1E21;0067 0304;1E21;0067 0304; # (ḡ; ḡ; g◌̄; ḡ; g◌̄; ) LATIN SMALL LETTER G WITH MACRON
+1E22;1E22;0048 0307;1E22;0048 0307; # (Ḣ; Ḣ; H◌̇; Ḣ; H◌̇; ) LATIN CAPITAL LETTER H WITH DOT ABOVE
+1E23;1E23;0068 0307;1E23;0068 0307; # (ḣ; ḣ; h◌̇; ḣ; h◌̇; ) LATIN SMALL LETTER H WITH DOT ABOVE
+1E24;1E24;0048 0323;1E24;0048 0323; # (Ḥ; Ḥ; H◌̣; Ḥ; H◌̣; ) LATIN CAPITAL LETTER H WITH DOT BELOW
+1E25;1E25;0068 0323;1E25;0068 0323; # (ḥ; ḥ; h◌̣; ḥ; h◌̣; ) LATIN SMALL LETTER H WITH DOT BELOW
+1E26;1E26;0048 0308;1E26;0048 0308; # (Ḧ; Ḧ; H◌̈; Ḧ; H◌̈; ) LATIN CAPITAL LETTER H WITH DIAERESIS
+1E27;1E27;0068 0308;1E27;0068 0308; # (ḧ; ḧ; h◌̈; ḧ; h◌̈; ) LATIN SMALL LETTER H WITH DIAERESIS
+1E28;1E28;0048 0327;1E28;0048 0327; # (Ḩ; Ḩ; H◌̧; Ḩ; H◌̧; ) LATIN CAPITAL LETTER H WITH CEDILLA
+1E29;1E29;0068 0327;1E29;0068 0327; # (ḩ; ḩ; h◌̧; ḩ; h◌̧; ) LATIN SMALL LETTER H WITH CEDILLA
+1E2A;1E2A;0048 032E;1E2A;0048 032E; # (Ḫ; Ḫ; H◌̮; Ḫ; H◌̮; ) LATIN CAPITAL LETTER H WITH BREVE BELOW
+1E2B;1E2B;0068 032E;1E2B;0068 032E; # (ḫ; ḫ; h◌̮; ḫ; h◌̮; ) LATIN SMALL LETTER H WITH BREVE BELOW
+1E2C;1E2C;0049 0330;1E2C;0049 0330; # (Ḭ; Ḭ; I◌̰; Ḭ; I◌̰; ) LATIN CAPITAL LETTER I WITH TILDE BELOW
+1E2D;1E2D;0069 0330;1E2D;0069 0330; # (ḭ; ḭ; i◌̰; ḭ; i◌̰; ) LATIN SMALL LETTER I WITH TILDE BELOW
+1E2E;1E2E;0049 0308 0301;1E2E;0049 0308 0301; # (Ḯ; Ḯ; I◌̈◌́; Ḯ; I◌̈◌́; ) LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
+1E2F;1E2F;0069 0308 0301;1E2F;0069 0308 0301; # (ḯ; ḯ; i◌̈◌́; ḯ; i◌̈◌́; ) LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE
+1E30;1E30;004B 0301;1E30;004B 0301; # (Ḱ; Ḱ; K◌́; Ḱ; K◌́; ) LATIN CAPITAL LETTER K WITH ACUTE
+1E31;1E31;006B 0301;1E31;006B 0301; # (ḱ; ḱ; k◌́; ḱ; k◌́; ) LATIN SMALL LETTER K WITH ACUTE
+1E32;1E32;004B 0323;1E32;004B 0323; # (Ḳ; Ḳ; K◌̣; Ḳ; K◌̣; ) LATIN CAPITAL LETTER K WITH DOT BELOW
+1E33;1E33;006B 0323;1E33;006B 0323; # (ḳ; ḳ; k◌̣; ḳ; k◌̣; ) LATIN SMALL LETTER K WITH DOT BELOW
+1E34;1E34;004B 0331;1E34;004B 0331; # (Ḵ; Ḵ; K◌̱; Ḵ; K◌̱; ) LATIN CAPITAL LETTER K WITH LINE BELOW
+1E35;1E35;006B 0331;1E35;006B 0331; # (ḵ; ḵ; k◌̱; ḵ; k◌̱; ) LATIN SMALL LETTER K WITH LINE BELOW
+1E36;1E36;004C 0323;1E36;004C 0323; # (Ḷ; Ḷ; L◌̣; Ḷ; L◌̣; ) LATIN CAPITAL LETTER L WITH DOT BELOW
+1E37;1E37;006C 0323;1E37;006C 0323; # (ḷ; ḷ; l◌̣; ḷ; l◌̣; ) LATIN SMALL LETTER L WITH DOT BELOW
+1E38;1E38;004C 0323 0304;1E38;004C 0323 0304; # (Ḹ; Ḹ; L◌̣◌̄; Ḹ; L◌̣◌̄; ) LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
+1E39;1E39;006C 0323 0304;1E39;006C 0323 0304; # (ḹ; ḹ; l◌̣◌̄; ḹ; l◌̣◌̄; ) LATIN SMALL LETTER L WITH DOT BELOW AND MACRON
+1E3A;1E3A;004C 0331;1E3A;004C 0331; # (Ḻ; Ḻ; L◌̱; Ḻ; L◌̱; ) LATIN CAPITAL LETTER L WITH LINE BELOW
+1E3B;1E3B;006C 0331;1E3B;006C 0331; # (ḻ; ḻ; l◌̱; ḻ; l◌̱; ) LATIN SMALL LETTER L WITH LINE BELOW
+1E3C;1E3C;004C 032D;1E3C;004C 032D; # (Ḽ; Ḽ; L◌̭; Ḽ; L◌̭; ) LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
+1E3D;1E3D;006C 032D;1E3D;006C 032D; # (ḽ; ḽ; l◌̭; ḽ; l◌̭; ) LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW
+1E3E;1E3E;004D 0301;1E3E;004D 0301; # (Ḿ; Ḿ; M◌́; Ḿ; M◌́; ) LATIN CAPITAL LETTER M WITH ACUTE
+1E3F;1E3F;006D 0301;1E3F;006D 0301; # (ḿ; ḿ; m◌́; ḿ; m◌́; ) LATIN SMALL LETTER M WITH ACUTE
+1E40;1E40;004D 0307;1E40;004D 0307; # (Ṁ; Ṁ; M◌̇; Ṁ; M◌̇; ) LATIN CAPITAL LETTER M WITH DOT ABOVE
+1E41;1E41;006D 0307;1E41;006D 0307; # (ṁ; ṁ; m◌̇; ṁ; m◌̇; ) LATIN SMALL LETTER M WITH DOT ABOVE
+1E42;1E42;004D 0323;1E42;004D 0323; # (Ṃ; Ṃ; M◌̣; Ṃ; M◌̣; ) LATIN CAPITAL LETTER M WITH DOT BELOW
+1E43;1E43;006D 0323;1E43;006D 0323; # (ṃ; ṃ; m◌̣; ṃ; m◌̣; ) LATIN SMALL LETTER M WITH DOT BELOW
+1E44;1E44;004E 0307;1E44;004E 0307; # (Ṅ; Ṅ; N◌̇; Ṅ; N◌̇; ) LATIN CAPITAL LETTER N WITH DOT ABOVE
+1E45;1E45;006E 0307;1E45;006E 0307; # (ṅ; ṅ; n◌̇; ṅ; n◌̇; ) LATIN SMALL LETTER N WITH DOT ABOVE
+1E46;1E46;004E 0323;1E46;004E 0323; # (Ṇ; Ṇ; N◌̣; Ṇ; N◌̣; ) LATIN CAPITAL LETTER N WITH DOT BELOW
+1E47;1E47;006E 0323;1E47;006E 0323; # (ṇ; ṇ; n◌̣; ṇ; n◌̣; ) LATIN SMALL LETTER N WITH DOT BELOW
+1E48;1E48;004E 0331;1E48;004E 0331; # (Ṉ; Ṉ; N◌̱; Ṉ; N◌̱; ) LATIN CAPITAL LETTER N WITH LINE BELOW
+1E49;1E49;006E 0331;1E49;006E 0331; # (ṉ; ṉ; n◌̱; ṉ; n◌̱; ) LATIN SMALL LETTER N WITH LINE BELOW
+1E4A;1E4A;004E 032D;1E4A;004E 032D; # (Ṋ; Ṋ; N◌̭; Ṋ; N◌̭; ) LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
+1E4B;1E4B;006E 032D;1E4B;006E 032D; # (ṋ; ṋ; n◌̭; ṋ; n◌̭; ) LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW
+1E4C;1E4C;004F 0303 0301;1E4C;004F 0303 0301; # (Ṍ; Ṍ; O◌̃◌́; Ṍ; O◌̃◌́; ) LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
+1E4D;1E4D;006F 0303 0301;1E4D;006F 0303 0301; # (ṍ; ṍ; o◌̃◌́; ṍ; o◌̃◌́; ) LATIN SMALL LETTER O WITH TILDE AND ACUTE
+1E4E;1E4E;004F 0303 0308;1E4E;004F 0303 0308; # (Ṏ; Ṏ; O◌̃◌̈; Ṏ; O◌̃◌̈; ) LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
+1E4F;1E4F;006F 0303 0308;1E4F;006F 0303 0308; # (ṏ; ṏ; o◌̃◌̈; ṏ; o◌̃◌̈; ) LATIN SMALL LETTER O WITH TILDE AND DIAERESIS
+1E50;1E50;004F 0304 0300;1E50;004F 0304 0300; # (Ṑ; Ṑ; O◌̄◌̀; Ṑ; O◌̄◌̀; ) LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
+1E51;1E51;006F 0304 0300;1E51;006F 0304 0300; # (ṑ; ṑ; o◌̄◌̀; ṑ; o◌̄◌̀; ) LATIN SMALL LETTER O WITH MACRON AND GRAVE
+1E52;1E52;004F 0304 0301;1E52;004F 0304 0301; # (Ṓ; Ṓ; O◌̄◌́; Ṓ; O◌̄◌́; ) LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
+1E53;1E53;006F 0304 0301;1E53;006F 0304 0301; # (ṓ; ṓ; o◌̄◌́; ṓ; o◌̄◌́; ) LATIN SMALL LETTER O WITH MACRON AND ACUTE
+1E54;1E54;0050 0301;1E54;0050 0301; # (Ṕ; Ṕ; P◌́; Ṕ; P◌́; ) LATIN CAPITAL LETTER P WITH ACUTE
+1E55;1E55;0070 0301;1E55;0070 0301; # (ṕ; ṕ; p◌́; ṕ; p◌́; ) LATIN SMALL LETTER P WITH ACUTE
+1E56;1E56;0050 0307;1E56;0050 0307; # (Ṗ; Ṗ; P◌̇; Ṗ; P◌̇; ) LATIN CAPITAL LETTER P WITH DOT ABOVE
+1E57;1E57;0070 0307;1E57;0070 0307; # (ṗ; ṗ; p◌̇; ṗ; p◌̇; ) LATIN SMALL LETTER P WITH DOT ABOVE
+1E58;1E58;0052 0307;1E58;0052 0307; # (Ṙ; Ṙ; R◌̇; Ṙ; R◌̇; ) LATIN CAPITAL LETTER R WITH DOT ABOVE
+1E59;1E59;0072 0307;1E59;0072 0307; # (ṙ; ṙ; r◌̇; ṙ; r◌̇; ) LATIN SMALL LETTER R WITH DOT ABOVE
+1E5A;1E5A;0052 0323;1E5A;0052 0323; # (Ṛ; Ṛ; R◌̣; Ṛ; R◌̣; ) LATIN CAPITAL LETTER R WITH DOT BELOW
+1E5B;1E5B;0072 0323;1E5B;0072 0323; # (ṛ; ṛ; r◌̣; ṛ; r◌̣; ) LATIN SMALL LETTER R WITH DOT BELOW
+1E5C;1E5C;0052 0323 0304;1E5C;0052 0323 0304; # (Ṝ; Ṝ; R◌̣◌̄; Ṝ; R◌̣◌̄; ) LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
+1E5D;1E5D;0072 0323 0304;1E5D;0072 0323 0304; # (ṝ; ṝ; r◌̣◌̄; ṝ; r◌̣◌̄; ) LATIN SMALL LETTER R WITH DOT BELOW AND MACRON
+1E5E;1E5E;0052 0331;1E5E;0052 0331; # (Ṟ; Ṟ; R◌̱; Ṟ; R◌̱; ) LATIN CAPITAL LETTER R WITH LINE BELOW
+1E5F;1E5F;0072 0331;1E5F;0072 0331; # (ṟ; ṟ; r◌̱; ṟ; r◌̱; ) LATIN SMALL LETTER R WITH LINE BELOW
+1E60;1E60;0053 0307;1E60;0053 0307; # (Ṡ; Ṡ; S◌̇; Ṡ; S◌̇; ) LATIN CAPITAL LETTER S WITH DOT ABOVE
+1E61;1E61;0073 0307;1E61;0073 0307; # (ṡ; ṡ; s◌̇; ṡ; s◌̇; ) LATIN SMALL LETTER S WITH DOT ABOVE
+1E62;1E62;0053 0323;1E62;0053 0323; # (Ṣ; Ṣ; S◌̣; Ṣ; S◌̣; ) LATIN CAPITAL LETTER S WITH DOT BELOW
+1E63;1E63;0073 0323;1E63;0073 0323; # (ṣ; ṣ; s◌̣; ṣ; s◌̣; ) LATIN SMALL LETTER S WITH DOT BELOW
+1E64;1E64;0053 0301 0307;1E64;0053 0301 0307; # (Ṥ; Ṥ; S◌́◌̇; Ṥ; S◌́◌̇; ) LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
+1E65;1E65;0073 0301 0307;1E65;0073 0301 0307; # (ṥ; ṥ; s◌́◌̇; ṥ; s◌́◌̇; ) LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE
+1E66;1E66;0053 030C 0307;1E66;0053 030C 0307; # (Ṧ; Ṧ; S◌̌◌̇; Ṧ; S◌̌◌̇; ) LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
+1E67;1E67;0073 030C 0307;1E67;0073 030C 0307; # (ṧ; ṧ; s◌̌◌̇; ṧ; s◌̌◌̇; ) LATIN SMALL LETTER S WITH CARON AND DOT ABOVE
+1E68;1E68;0053 0323 0307;1E68;0053 0323 0307; # (Ṩ; Ṩ; S◌̣◌̇; Ṩ; S◌̣◌̇; ) LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
+1E69;1E69;0073 0323 0307;1E69;0073 0323 0307; # (ṩ; ṩ; s◌̣◌̇; ṩ; s◌̣◌̇; ) LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
+1E6A;1E6A;0054 0307;1E6A;0054 0307; # (Ṫ; Ṫ; T◌̇; Ṫ; T◌̇; ) LATIN CAPITAL LETTER T WITH DOT ABOVE
+1E6B;1E6B;0074 0307;1E6B;0074 0307; # (ṫ; ṫ; t◌̇; ṫ; t◌̇; ) LATIN SMALL LETTER T WITH DOT ABOVE
+1E6C;1E6C;0054 0323;1E6C;0054 0323; # (Ṭ; Ṭ; T◌̣; Ṭ; T◌̣; ) LATIN CAPITAL LETTER T WITH DOT BELOW
+1E6D;1E6D;0074 0323;1E6D;0074 0323; # (ṭ; ṭ; t◌̣; ṭ; t◌̣; ) LATIN SMALL LETTER T WITH DOT BELOW
+1E6E;1E6E;0054 0331;1E6E;0054 0331; # (Ṯ; Ṯ; T◌̱; Ṯ; T◌̱; ) LATIN CAPITAL LETTER T WITH LINE BELOW
+1E6F;1E6F;0074 0331;1E6F;0074 0331; # (ṯ; ṯ; t◌̱; ṯ; t◌̱; ) LATIN SMALL LETTER T WITH LINE BELOW
+1E70;1E70;0054 032D;1E70;0054 032D; # (Ṱ; Ṱ; T◌̭; Ṱ; T◌̭; ) LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
+1E71;1E71;0074 032D;1E71;0074 032D; # (ṱ; ṱ; t◌̭; ṱ; t◌̭; ) LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW
+1E72;1E72;0055 0324;1E72;0055 0324; # (Ṳ; Ṳ; U◌̤; Ṳ; U◌̤; ) LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
+1E73;1E73;0075 0324;1E73;0075 0324; # (ṳ; ṳ; u◌̤; ṳ; u◌̤; ) LATIN SMALL LETTER U WITH DIAERESIS BELOW
+1E74;1E74;0055 0330;1E74;0055 0330; # (Ṵ; Ṵ; U◌̰; Ṵ; U◌̰; ) LATIN CAPITAL LETTER U WITH TILDE BELOW
+1E75;1E75;0075 0330;1E75;0075 0330; # (ṵ; ṵ; u◌̰; ṵ; u◌̰; ) LATIN SMALL LETTER U WITH TILDE BELOW
+1E76;1E76;0055 032D;1E76;0055 032D; # (Ṷ; Ṷ; U◌̭; Ṷ; U◌̭; ) LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
+1E77;1E77;0075 032D;1E77;0075 032D; # (ṷ; ṷ; u◌̭; ṷ; u◌̭; ) LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW
+1E78;1E78;0055 0303 0301;1E78;0055 0303 0301; # (Ṹ; Ṹ; U◌̃◌́; Ṹ; U◌̃◌́; ) LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
+1E79;1E79;0075 0303 0301;1E79;0075 0303 0301; # (ṹ; ṹ; u◌̃◌́; ṹ; u◌̃◌́; ) LATIN SMALL LETTER U WITH TILDE AND ACUTE
+1E7A;1E7A;0055 0304 0308;1E7A;0055 0304 0308; # (Ṻ; Ṻ; U◌̄◌̈; Ṻ; U◌̄◌̈; ) LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
+1E7B;1E7B;0075 0304 0308;1E7B;0075 0304 0308; # (ṻ; ṻ; u◌̄◌̈; ṻ; u◌̄◌̈; ) LATIN SMALL LETTER U WITH MACRON AND DIAERESIS
+1E7C;1E7C;0056 0303;1E7C;0056 0303; # (Ṽ; Ṽ; V◌̃; Ṽ; V◌̃; ) LATIN CAPITAL LETTER V WITH TILDE
+1E7D;1E7D;0076 0303;1E7D;0076 0303; # (ṽ; ṽ; v◌̃; ṽ; v◌̃; ) LATIN SMALL LETTER V WITH TILDE
+1E7E;1E7E;0056 0323;1E7E;0056 0323; # (Ṿ; Ṿ; V◌̣; Ṿ; V◌̣; ) LATIN CAPITAL LETTER V WITH DOT BELOW
+1E7F;1E7F;0076 0323;1E7F;0076 0323; # (ṿ; ṿ; v◌̣; ṿ; v◌̣; ) LATIN SMALL LETTER V WITH DOT BELOW
+1E80;1E80;0057 0300;1E80;0057 0300; # (Ẁ; Ẁ; W◌̀; Ẁ; W◌̀; ) LATIN CAPITAL LETTER W WITH GRAVE
+1E81;1E81;0077 0300;1E81;0077 0300; # (ẁ; ẁ; w◌̀; ẁ; w◌̀; ) LATIN SMALL LETTER W WITH GRAVE
+1E82;1E82;0057 0301;1E82;0057 0301; # (Ẃ; Ẃ; W◌́; Ẃ; W◌́; ) LATIN CAPITAL LETTER W WITH ACUTE
+1E83;1E83;0077 0301;1E83;0077 0301; # (ẃ; ẃ; w◌́; ẃ; w◌́; ) LATIN SMALL LETTER W WITH ACUTE
+1E84;1E84;0057 0308;1E84;0057 0308; # (Ẅ; Ẅ; W◌̈; Ẅ; W◌̈; ) LATIN CAPITAL LETTER W WITH DIAERESIS
+1E85;1E85;0077 0308;1E85;0077 0308; # (ẅ; ẅ; w◌̈; ẅ; w◌̈; ) LATIN SMALL LETTER W WITH DIAERESIS
+1E86;1E86;0057 0307;1E86;0057 0307; # (Ẇ; Ẇ; W◌̇; Ẇ; W◌̇; ) LATIN CAPITAL LETTER W WITH DOT ABOVE
+1E87;1E87;0077 0307;1E87;0077 0307; # (ẇ; ẇ; w◌̇; ẇ; w◌̇; ) LATIN SMALL LETTER W WITH DOT ABOVE
+1E88;1E88;0057 0323;1E88;0057 0323; # (Ẉ; Ẉ; W◌̣; Ẉ; W◌̣; ) LATIN CAPITAL LETTER W WITH DOT BELOW
+1E89;1E89;0077 0323;1E89;0077 0323; # (ẉ; ẉ; w◌̣; ẉ; w◌̣; ) LATIN SMALL LETTER W WITH DOT BELOW
+1E8A;1E8A;0058 0307;1E8A;0058 0307; # (Ẋ; Ẋ; X◌̇; Ẋ; X◌̇; ) LATIN CAPITAL LETTER X WITH DOT ABOVE
+1E8B;1E8B;0078 0307;1E8B;0078 0307; # (ẋ; ẋ; x◌̇; ẋ; x◌̇; ) LATIN SMALL LETTER X WITH DOT ABOVE
+1E8C;1E8C;0058 0308;1E8C;0058 0308; # (Ẍ; Ẍ; X◌̈; Ẍ; X◌̈; ) LATIN CAPITAL LETTER X WITH DIAERESIS
+1E8D;1E8D;0078 0308;1E8D;0078 0308; # (ẍ; ẍ; x◌̈; ẍ; x◌̈; ) LATIN SMALL LETTER X WITH DIAERESIS
+1E8E;1E8E;0059 0307;1E8E;0059 0307; # (Ẏ; Ẏ; Y◌̇; Ẏ; Y◌̇; ) LATIN CAPITAL LETTER Y WITH DOT ABOVE
+1E8F;1E8F;0079 0307;1E8F;0079 0307; # (ẏ; ẏ; y◌̇; ẏ; y◌̇; ) LATIN SMALL LETTER Y WITH DOT ABOVE
+1E90;1E90;005A 0302;1E90;005A 0302; # (Ẑ; Ẑ; Z◌̂; Ẑ; Z◌̂; ) LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
+1E91;1E91;007A 0302;1E91;007A 0302; # (ẑ; ẑ; z◌̂; ẑ; z◌̂; ) LATIN SMALL LETTER Z WITH CIRCUMFLEX
+1E92;1E92;005A 0323;1E92;005A 0323; # (Ẓ; Ẓ; Z◌̣; Ẓ; Z◌̣; ) LATIN CAPITAL LETTER Z WITH DOT BELOW
+1E93;1E93;007A 0323;1E93;007A 0323; # (ẓ; ẓ; z◌̣; ẓ; z◌̣; ) LATIN SMALL LETTER Z WITH DOT BELOW
+1E94;1E94;005A 0331;1E94;005A 0331; # (Ẕ; Ẕ; Z◌̱; Ẕ; Z◌̱; ) LATIN CAPITAL LETTER Z WITH LINE BELOW
+1E95;1E95;007A 0331;1E95;007A 0331; # (ẕ; ẕ; z◌̱; ẕ; z◌̱; ) LATIN SMALL LETTER Z WITH LINE BELOW
+1E96;1E96;0068 0331;1E96;0068 0331; # (ẖ; ẖ; h◌̱; ẖ; h◌̱; ) LATIN SMALL LETTER H WITH LINE BELOW
+1E97;1E97;0074 0308;1E97;0074 0308; # (ẗ; ẗ; t◌̈; ẗ; t◌̈; ) LATIN SMALL LETTER T WITH DIAERESIS
+1E98;1E98;0077 030A;1E98;0077 030A; # (ẘ; ẘ; w◌̊; ẘ; w◌̊; ) LATIN SMALL LETTER W WITH RING ABOVE
+1E99;1E99;0079 030A;1E99;0079 030A; # (ẙ; ẙ; y◌̊; ẙ; y◌̊; ) LATIN SMALL LETTER Y WITH RING ABOVE
+1E9A;1E9A;1E9A;0061 02BE;0061 02BE; # (ẚ; ẚ; ẚ; aʾ; aʾ; ) LATIN SMALL LETTER A WITH RIGHT HALF RING
+1E9B;1E9B;017F 0307;1E61;0073 0307; # (ẛ; ẛ; ſ◌̇; ṡ; s◌̇; ) LATIN SMALL LETTER LONG S WITH DOT ABOVE
+1EA0;1EA0;0041 0323;1EA0;0041 0323; # (Ạ; Ạ; A◌̣; Ạ; A◌̣; ) LATIN CAPITAL LETTER A WITH DOT BELOW
+1EA1;1EA1;0061 0323;1EA1;0061 0323; # (ạ; ạ; a◌̣; ạ; a◌̣; ) LATIN SMALL LETTER A WITH DOT BELOW
+1EA2;1EA2;0041 0309;1EA2;0041 0309; # (Ả; Ả; A◌̉; Ả; A◌̉; ) LATIN CAPITAL LETTER A WITH HOOK ABOVE
+1EA3;1EA3;0061 0309;1EA3;0061 0309; # (ả; ả; a◌̉; ả; a◌̉; ) LATIN SMALL LETTER A WITH HOOK ABOVE
+1EA4;1EA4;0041 0302 0301;1EA4;0041 0302 0301; # (Ấ; Ấ; A◌̂◌́; Ấ; A◌̂◌́; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
+1EA5;1EA5;0061 0302 0301;1EA5;0061 0302 0301; # (ấ; ấ; a◌̂◌́; ấ; a◌̂◌́; ) LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
+1EA6;1EA6;0041 0302 0300;1EA6;0041 0302 0300; # (Ầ; Ầ; A◌̂◌̀; Ầ; A◌̂◌̀; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
+1EA7;1EA7;0061 0302 0300;1EA7;0061 0302 0300; # (ầ; ầ; a◌̂◌̀; ầ; a◌̂◌̀; ) LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE
+1EA8;1EA8;0041 0302 0309;1EA8;0041 0302 0309; # (Ẩ; Ẩ; A◌̂◌̉; Ẩ; A◌̂◌̉; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
+1EA9;1EA9;0061 0302 0309;1EA9;0061 0302 0309; # (ẩ; ẩ; a◌̂◌̉; ẩ; a◌̂◌̉; ) LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
+1EAA;1EAA;0041 0302 0303;1EAA;0041 0302 0303; # (Ẫ; Ẫ; A◌̂◌̃; Ẫ; A◌̂◌̃; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
+1EAB;1EAB;0061 0302 0303;1EAB;0061 0302 0303; # (ẫ; ẫ; a◌̂◌̃; ẫ; a◌̂◌̃; ) LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE
+1EAC;1EAC;0041 0323 0302;1EAC;0041 0323 0302; # (Ậ; Ậ; A◌̣◌̂; Ậ; A◌̣◌̂; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
+1EAD;1EAD;0061 0323 0302;1EAD;0061 0323 0302; # (ậ; ậ; a◌̣◌̂; ậ; a◌̣◌̂; ) LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW
+1EAE;1EAE;0041 0306 0301;1EAE;0041 0306 0301; # (Ắ; Ắ; A◌̆◌́; Ắ; A◌̆◌́; ) LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
+1EAF;1EAF;0061 0306 0301;1EAF;0061 0306 0301; # (ắ; ắ; a◌̆◌́; ắ; a◌̆◌́; ) LATIN SMALL LETTER A WITH BREVE AND ACUTE
+1EB0;1EB0;0041 0306 0300;1EB0;0041 0306 0300; # (Ằ; Ằ; A◌̆◌̀; Ằ; A◌̆◌̀; ) LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
+1EB1;1EB1;0061 0306 0300;1EB1;0061 0306 0300; # (ằ; ằ; a◌̆◌̀; ằ; a◌̆◌̀; ) LATIN SMALL LETTER A WITH BREVE AND GRAVE
+1EB2;1EB2;0041 0306 0309;1EB2;0041 0306 0309; # (Ẳ; Ẳ; A◌̆◌̉; Ẳ; A◌̆◌̉; ) LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
+1EB3;1EB3;0061 0306 0309;1EB3;0061 0306 0309; # (ẳ; ẳ; a◌̆◌̉; ẳ; a◌̆◌̉; ) LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE
+1EB4;1EB4;0041 0306 0303;1EB4;0041 0306 0303; # (Ẵ; Ẵ; A◌̆◌̃; Ẵ; A◌̆◌̃; ) LATIN CAPITAL LETTER A WITH BREVE AND TILDE
+1EB5;1EB5;0061 0306 0303;1EB5;0061 0306 0303; # (ẵ; ẵ; a◌̆◌̃; ẵ; a◌̆◌̃; ) LATIN SMALL LETTER A WITH BREVE AND TILDE
+1EB6;1EB6;0041 0323 0306;1EB6;0041 0323 0306; # (Ặ; Ặ; A◌̣◌̆; Ặ; A◌̣◌̆; ) LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
+1EB7;1EB7;0061 0323 0306;1EB7;0061 0323 0306; # (ặ; ặ; a◌̣◌̆; ặ; a◌̣◌̆; ) LATIN SMALL LETTER A WITH BREVE AND DOT BELOW
+1EB8;1EB8;0045 0323;1EB8;0045 0323; # (Ẹ; Ẹ; E◌̣; Ẹ; E◌̣; ) LATIN CAPITAL LETTER E WITH DOT BELOW
+1EB9;1EB9;0065 0323;1EB9;0065 0323; # (ẹ; ẹ; e◌̣; ẹ; e◌̣; ) LATIN SMALL LETTER E WITH DOT BELOW
+1EBA;1EBA;0045 0309;1EBA;0045 0309; # (Ẻ; Ẻ; E◌̉; Ẻ; E◌̉; ) LATIN CAPITAL LETTER E WITH HOOK ABOVE
+1EBB;1EBB;0065 0309;1EBB;0065 0309; # (ẻ; ẻ; e◌̉; ẻ; e◌̉; ) LATIN SMALL LETTER E WITH HOOK ABOVE
+1EBC;1EBC;0045 0303;1EBC;0045 0303; # (Ẽ; Ẽ; E◌̃; Ẽ; E◌̃; ) LATIN CAPITAL LETTER E WITH TILDE
+1EBD;1EBD;0065 0303;1EBD;0065 0303; # (ẽ; ẽ; e◌̃; ẽ; e◌̃; ) LATIN SMALL LETTER E WITH TILDE
+1EBE;1EBE;0045 0302 0301;1EBE;0045 0302 0301; # (Ế; Ế; E◌̂◌́; Ế; E◌̂◌́; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
+1EBF;1EBF;0065 0302 0301;1EBF;0065 0302 0301; # (ế; ế; e◌̂◌́; ế; e◌̂◌́; ) LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE
+1EC0;1EC0;0045 0302 0300;1EC0;0045 0302 0300; # (Ề; Ề; E◌̂◌̀; Ề; E◌̂◌̀; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
+1EC1;1EC1;0065 0302 0300;1EC1;0065 0302 0300; # (ề; ề; e◌̂◌̀; ề; e◌̂◌̀; ) LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE
+1EC2;1EC2;0045 0302 0309;1EC2;0045 0302 0309; # (Ể; Ể; E◌̂◌̉; Ể; E◌̂◌̉; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
+1EC3;1EC3;0065 0302 0309;1EC3;0065 0302 0309; # (ể; ể; e◌̂◌̉; ể; e◌̂◌̉; ) LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
+1EC4;1EC4;0045 0302 0303;1EC4;0045 0302 0303; # (Ễ; Ễ; E◌̂◌̃; Ễ; E◌̂◌̃; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
+1EC5;1EC5;0065 0302 0303;1EC5;0065 0302 0303; # (ễ; ễ; e◌̂◌̃; ễ; e◌̂◌̃; ) LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE
+1EC6;1EC6;0045 0323 0302;1EC6;0045 0323 0302; # (Ệ; Ệ; E◌̣◌̂; Ệ; E◌̣◌̂; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
+1EC7;1EC7;0065 0323 0302;1EC7;0065 0323 0302; # (ệ; ệ; e◌̣◌̂; ệ; e◌̣◌̂; ) LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW
+1EC8;1EC8;0049 0309;1EC8;0049 0309; # (Ỉ; Ỉ; I◌̉; Ỉ; I◌̉; ) LATIN CAPITAL LETTER I WITH HOOK ABOVE
+1EC9;1EC9;0069 0309;1EC9;0069 0309; # (ỉ; ỉ; i◌̉; ỉ; i◌̉; ) LATIN SMALL LETTER I WITH HOOK ABOVE
+1ECA;1ECA;0049 0323;1ECA;0049 0323; # (Ị; Ị; I◌̣; Ị; I◌̣; ) LATIN CAPITAL LETTER I WITH DOT BELOW
+1ECB;1ECB;0069 0323;1ECB;0069 0323; # (ị; ị; i◌̣; ị; i◌̣; ) LATIN SMALL LETTER I WITH DOT BELOW
+1ECC;1ECC;004F 0323;1ECC;004F 0323; # (Ọ; Ọ; O◌̣; Ọ; O◌̣; ) LATIN CAPITAL LETTER O WITH DOT BELOW
+1ECD;1ECD;006F 0323;1ECD;006F 0323; # (ọ; ọ; o◌̣; ọ; o◌̣; ) LATIN SMALL LETTER O WITH DOT BELOW
+1ECE;1ECE;004F 0309;1ECE;004F 0309; # (Ỏ; Ỏ; O◌̉; Ỏ; O◌̉; ) LATIN CAPITAL LETTER O WITH HOOK ABOVE
+1ECF;1ECF;006F 0309;1ECF;006F 0309; # (ỏ; ỏ; o◌̉; ỏ; o◌̉; ) LATIN SMALL LETTER O WITH HOOK ABOVE
+1ED0;1ED0;004F 0302 0301;1ED0;004F 0302 0301; # (Ố; Ố; O◌̂◌́; Ố; O◌̂◌́; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
+1ED1;1ED1;006F 0302 0301;1ED1;006F 0302 0301; # (ố; ố; o◌̂◌́; ố; o◌̂◌́; ) LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE
+1ED2;1ED2;004F 0302 0300;1ED2;004F 0302 0300; # (Ồ; Ồ; O◌̂◌̀; Ồ; O◌̂◌̀; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
+1ED3;1ED3;006F 0302 0300;1ED3;006F 0302 0300; # (ồ; ồ; o◌̂◌̀; ồ; o◌̂◌̀; ) LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE
+1ED4;1ED4;004F 0302 0309;1ED4;004F 0302 0309; # (Ổ; Ổ; O◌̂◌̉; Ổ; O◌̂◌̉; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
+1ED5;1ED5;006F 0302 0309;1ED5;006F 0302 0309; # (ổ; ổ; o◌̂◌̉; ổ; o◌̂◌̉; ) LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
+1ED6;1ED6;004F 0302 0303;1ED6;004F 0302 0303; # (Ỗ; Ỗ; O◌̂◌̃; Ỗ; O◌̂◌̃; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
+1ED7;1ED7;006F 0302 0303;1ED7;006F 0302 0303; # (ỗ; ỗ; o◌̂◌̃; ỗ; o◌̂◌̃; ) LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE
+1ED8;1ED8;004F 0323 0302;1ED8;004F 0323 0302; # (Ộ; Ộ; O◌̣◌̂; Ộ; O◌̣◌̂; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
+1ED9;1ED9;006F 0323 0302;1ED9;006F 0323 0302; # (ộ; ộ; o◌̣◌̂; ộ; o◌̣◌̂; ) LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW
+1EDA;1EDA;004F 031B 0301;1EDA;004F 031B 0301; # (Ớ; Ớ; O◌̛◌́; Ớ; O◌̛◌́; ) LATIN CAPITAL LETTER O WITH HORN AND ACUTE
+1EDB;1EDB;006F 031B 0301;1EDB;006F 031B 0301; # (ớ; ớ; o◌̛◌́; ớ; o◌̛◌́; ) LATIN SMALL LETTER O WITH HORN AND ACUTE
+1EDC;1EDC;004F 031B 0300;1EDC;004F 031B 0300; # (Ờ; Ờ; O◌̛◌̀; Ờ; O◌̛◌̀; ) LATIN CAPITAL LETTER O WITH HORN AND GRAVE
+1EDD;1EDD;006F 031B 0300;1EDD;006F 031B 0300; # (ờ; ờ; o◌̛◌̀; ờ; o◌̛◌̀; ) LATIN SMALL LETTER O WITH HORN AND GRAVE
+1EDE;1EDE;004F 031B 0309;1EDE;004F 031B 0309; # (Ở; Ở; O◌̛◌̉; Ở; O◌̛◌̉; ) LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
+1EDF;1EDF;006F 031B 0309;1EDF;006F 031B 0309; # (ở; ở; o◌̛◌̉; ở; o◌̛◌̉; ) LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE
+1EE0;1EE0;004F 031B 0303;1EE0;004F 031B 0303; # (Ỡ; Ỡ; O◌̛◌̃; Ỡ; O◌̛◌̃; ) LATIN CAPITAL LETTER O WITH HORN AND TILDE
+1EE1;1EE1;006F 031B 0303;1EE1;006F 031B 0303; # (ỡ; ỡ; o◌̛◌̃; ỡ; o◌̛◌̃; ) LATIN SMALL LETTER O WITH HORN AND TILDE
+1EE2;1EE2;004F 031B 0323;1EE2;004F 031B 0323; # (Ợ; Ợ; O◌̛◌̣; Ợ; O◌̛◌̣; ) LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
+1EE3;1EE3;006F 031B 0323;1EE3;006F 031B 0323; # (ợ; ợ; o◌̛◌̣; ợ; o◌̛◌̣; ) LATIN SMALL LETTER O WITH HORN AND DOT BELOW
+1EE4;1EE4;0055 0323;1EE4;0055 0323; # (Ụ; Ụ; U◌̣; Ụ; U◌̣; ) LATIN CAPITAL LETTER U WITH DOT BELOW
+1EE5;1EE5;0075 0323;1EE5;0075 0323; # (ụ; ụ; u◌̣; ụ; u◌̣; ) LATIN SMALL LETTER U WITH DOT BELOW
+1EE6;1EE6;0055 0309;1EE6;0055 0309; # (Ủ; Ủ; U◌̉; Ủ; U◌̉; ) LATIN CAPITAL LETTER U WITH HOOK ABOVE
+1EE7;1EE7;0075 0309;1EE7;0075 0309; # (ủ; ủ; u◌̉; ủ; u◌̉; ) LATIN SMALL LETTER U WITH HOOK ABOVE
+1EE8;1EE8;0055 031B 0301;1EE8;0055 031B 0301; # (Ứ; Ứ; U◌̛◌́; Ứ; U◌̛◌́; ) LATIN CAPITAL LETTER U WITH HORN AND ACUTE
+1EE9;1EE9;0075 031B 0301;1EE9;0075 031B 0301; # (ứ; ứ; u◌̛◌́; ứ; u◌̛◌́; ) LATIN SMALL LETTER U WITH HORN AND ACUTE
+1EEA;1EEA;0055 031B 0300;1EEA;0055 031B 0300; # (Ừ; Ừ; U◌̛◌̀; Ừ; U◌̛◌̀; ) LATIN CAPITAL LETTER U WITH HORN AND GRAVE
+1EEB;1EEB;0075 031B 0300;1EEB;0075 031B 0300; # (ừ; ừ; u◌̛◌̀; ừ; u◌̛◌̀; ) LATIN SMALL LETTER U WITH HORN AND GRAVE
+1EEC;1EEC;0055 031B 0309;1EEC;0055 031B 0309; # (Ử; Ử; U◌̛◌̉; Ử; U◌̛◌̉; ) LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
+1EED;1EED;0075 031B 0309;1EED;0075 031B 0309; # (ử; ử; u◌̛◌̉; ử; u◌̛◌̉; ) LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE
+1EEE;1EEE;0055 031B 0303;1EEE;0055 031B 0303; # (Ữ; Ữ; U◌̛◌̃; Ữ; U◌̛◌̃; ) LATIN CAPITAL LETTER U WITH HORN AND TILDE
+1EEF;1EEF;0075 031B 0303;1EEF;0075 031B 0303; # (ữ; ữ; u◌̛◌̃; ữ; u◌̛◌̃; ) LATIN SMALL LETTER U WITH HORN AND TILDE
+1EF0;1EF0;0055 031B 0323;1EF0;0055 031B 0323; # (Ự; Ự; U◌̛◌̣; Ự; U◌̛◌̣; ) LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
+1EF1;1EF1;0075 031B 0323;1EF1;0075 031B 0323; # (ự; ự; u◌̛◌̣; ự; u◌̛◌̣; ) LATIN SMALL LETTER U WITH HORN AND DOT BELOW
+1EF2;1EF2;0059 0300;1EF2;0059 0300; # (Ỳ; Ỳ; Y◌̀; Ỳ; Y◌̀; ) LATIN CAPITAL LETTER Y WITH GRAVE
+1EF3;1EF3;0079 0300;1EF3;0079 0300; # (ỳ; ỳ; y◌̀; ỳ; y◌̀; ) LATIN SMALL LETTER Y WITH GRAVE
+1EF4;1EF4;0059 0323;1EF4;0059 0323; # (Ỵ; Ỵ; Y◌̣; Ỵ; Y◌̣; ) LATIN CAPITAL LETTER Y WITH DOT BELOW
+1EF5;1EF5;0079 0323;1EF5;0079 0323; # (ỵ; ỵ; y◌̣; ỵ; y◌̣; ) LATIN SMALL LETTER Y WITH DOT BELOW
+1EF6;1EF6;0059 0309;1EF6;0059 0309; # (Ỷ; Ỷ; Y◌̉; Ỷ; Y◌̉; ) LATIN CAPITAL LETTER Y WITH HOOK ABOVE
+1EF7;1EF7;0079 0309;1EF7;0079 0309; # (ỷ; ỷ; y◌̉; ỷ; y◌̉; ) LATIN SMALL LETTER Y WITH HOOK ABOVE
+1EF8;1EF8;0059 0303;1EF8;0059 0303; # (Ỹ; Ỹ; Y◌̃; Ỹ; Y◌̃; ) LATIN CAPITAL LETTER Y WITH TILDE
+1EF9;1EF9;0079 0303;1EF9;0079 0303; # (ỹ; ỹ; y◌̃; ỹ; y◌̃; ) LATIN SMALL LETTER Y WITH TILDE
+1F00;1F00;03B1 0313;1F00;03B1 0313; # (ἀ; ἀ; α◌̓; ἀ; α◌̓; ) GREEK SMALL LETTER ALPHA WITH PSILI
+1F01;1F01;03B1 0314;1F01;03B1 0314; # (ἁ; ἁ; α◌̔; ἁ; α◌̔; ) GREEK SMALL LETTER ALPHA WITH DASIA
+1F02;1F02;03B1 0313 0300;1F02;03B1 0313 0300; # (ἂ; ἂ; α◌̓◌̀; ἂ; α◌̓◌̀; ) GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA
+1F03;1F03;03B1 0314 0300;1F03;03B1 0314 0300; # (ἃ; ἃ; α◌̔◌̀; ἃ; α◌̔◌̀; ) GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA
+1F04;1F04;03B1 0313 0301;1F04;03B1 0313 0301; # (ἄ; ἄ; α◌̓◌́; ἄ; α◌̓◌́; ) GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA
+1F05;1F05;03B1 0314 0301;1F05;03B1 0314 0301; # (ἅ; ἅ; α◌̔◌́; ἅ; α◌̔◌́; ) GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA
+1F06;1F06;03B1 0313 0342;1F06;03B1 0313 0342; # (ἆ; ἆ; α◌̓◌͂; ἆ; α◌̓◌͂; ) GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI
+1F07;1F07;03B1 0314 0342;1F07;03B1 0314 0342; # (ἇ; ἇ; α◌̔◌͂; ἇ; α◌̔◌͂; ) GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI
+1F08;1F08;0391 0313;1F08;0391 0313; # (Ἀ; Ἀ; Α◌̓; Ἀ; Α◌̓; ) GREEK CAPITAL LETTER ALPHA WITH PSILI
+1F09;1F09;0391 0314;1F09;0391 0314; # (Ἁ; Ἁ; Α◌̔; Ἁ; Α◌̔; ) GREEK CAPITAL LETTER ALPHA WITH DASIA
+1F0A;1F0A;0391 0313 0300;1F0A;0391 0313 0300; # (Ἂ; Ἂ; Α◌̓◌̀; Ἂ; Α◌̓◌̀; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
+1F0B;1F0B;0391 0314 0300;1F0B;0391 0314 0300; # (Ἃ; Ἃ; Α◌̔◌̀; Ἃ; Α◌̔◌̀; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
+1F0C;1F0C;0391 0313 0301;1F0C;0391 0313 0301; # (Ἄ; Ἄ; Α◌̓◌́; Ἄ; Α◌̓◌́; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
+1F0D;1F0D;0391 0314 0301;1F0D;0391 0314 0301; # (Ἅ; Ἅ; Α◌̔◌́; Ἅ; Α◌̔◌́; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
+1F0E;1F0E;0391 0313 0342;1F0E;0391 0313 0342; # (Ἆ; Ἆ; Α◌̓◌͂; Ἆ; Α◌̓◌͂; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
+1F0F;1F0F;0391 0314 0342;1F0F;0391 0314 0342; # (Ἇ; Ἇ; Α◌̔◌͂; Ἇ; Α◌̔◌͂; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
+1F10;1F10;03B5 0313;1F10;03B5 0313; # (ἐ; ἐ; ε◌̓; ἐ; ε◌̓; ) GREEK SMALL LETTER EPSILON WITH PSILI
+1F11;1F11;03B5 0314;1F11;03B5 0314; # (ἑ; ἑ; ε◌̔; ἑ; ε◌̔; ) GREEK SMALL LETTER EPSILON WITH DASIA
+1F12;1F12;03B5 0313 0300;1F12;03B5 0313 0300; # (ἒ; ἒ; ε◌̓◌̀; ἒ; ε◌̓◌̀; ) GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA
+1F13;1F13;03B5 0314 0300;1F13;03B5 0314 0300; # (ἓ; ἓ; ε◌̔◌̀; ἓ; ε◌̔◌̀; ) GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA
+1F14;1F14;03B5 0313 0301;1F14;03B5 0313 0301; # (ἔ; ἔ; ε◌̓◌́; ἔ; ε◌̓◌́; ) GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA
+1F15;1F15;03B5 0314 0301;1F15;03B5 0314 0301; # (ἕ; ἕ; ε◌̔◌́; ἕ; ε◌̔◌́; ) GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
+1F18;1F18;0395 0313;1F18;0395 0313; # (Ἐ; Ἐ; Ε◌̓; Ἐ; Ε◌̓; ) GREEK CAPITAL LETTER EPSILON WITH PSILI
+1F19;1F19;0395 0314;1F19;0395 0314; # (Ἑ; Ἑ; Ε◌̔; Ἑ; Ε◌̔; ) GREEK CAPITAL LETTER EPSILON WITH DASIA
+1F1A;1F1A;0395 0313 0300;1F1A;0395 0313 0300; # (Ἒ; Ἒ; Ε◌̓◌̀; Ἒ; Ε◌̓◌̀; ) GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
+1F1B;1F1B;0395 0314 0300;1F1B;0395 0314 0300; # (Ἓ; Ἓ; Ε◌̔◌̀; Ἓ; Ε◌̔◌̀; ) GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
+1F1C;1F1C;0395 0313 0301;1F1C;0395 0313 0301; # (Ἔ; Ἔ; Ε◌̓◌́; Ἔ; Ε◌̓◌́; ) GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
+1F1D;1F1D;0395 0314 0301;1F1D;0395 0314 0301; # (Ἕ; Ἕ; Ε◌̔◌́; Ἕ; Ε◌̔◌́; ) GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
+1F20;1F20;03B7 0313;1F20;03B7 0313; # (ἠ; ἠ; η◌̓; ἠ; η◌̓; ) GREEK SMALL LETTER ETA WITH PSILI
+1F21;1F21;03B7 0314;1F21;03B7 0314; # (ἡ; ἡ; η◌̔; ἡ; η◌̔; ) GREEK SMALL LETTER ETA WITH DASIA
+1F22;1F22;03B7 0313 0300;1F22;03B7 0313 0300; # (ἢ; ἢ; η◌̓◌̀; ἢ; η◌̓◌̀; ) GREEK SMALL LETTER ETA WITH PSILI AND VARIA
+1F23;1F23;03B7 0314 0300;1F23;03B7 0314 0300; # (ἣ; ἣ; η◌̔◌̀; ἣ; η◌̔◌̀; ) GREEK SMALL LETTER ETA WITH DASIA AND VARIA
+1F24;1F24;03B7 0313 0301;1F24;03B7 0313 0301; # (ἤ; ἤ; η◌̓◌́; ἤ; η◌̓◌́; ) GREEK SMALL LETTER ETA WITH PSILI AND OXIA
+1F25;1F25;03B7 0314 0301;1F25;03B7 0314 0301; # (ἥ; ἥ; η◌̔◌́; ἥ; η◌̔◌́; ) GREEK SMALL LETTER ETA WITH DASIA AND OXIA
+1F26;1F26;03B7 0313 0342;1F26;03B7 0313 0342; # (ἦ; ἦ; η◌̓◌͂; ἦ; η◌̓◌͂; ) GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI
+1F27;1F27;03B7 0314 0342;1F27;03B7 0314 0342; # (ἧ; ἧ; η◌̔◌͂; ἧ; η◌̔◌͂; ) GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI
+1F28;1F28;0397 0313;1F28;0397 0313; # (Ἠ; Ἠ; Η◌̓; Ἠ; Η◌̓; ) GREEK CAPITAL LETTER ETA WITH PSILI
+1F29;1F29;0397 0314;1F29;0397 0314; # (Ἡ; Ἡ; Η◌̔; Ἡ; Η◌̔; ) GREEK CAPITAL LETTER ETA WITH DASIA
+1F2A;1F2A;0397 0313 0300;1F2A;0397 0313 0300; # (Ἢ; Ἢ; Η◌̓◌̀; Ἢ; Η◌̓◌̀; ) GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
+1F2B;1F2B;0397 0314 0300;1F2B;0397 0314 0300; # (Ἣ; Ἣ; Η◌̔◌̀; Ἣ; Η◌̔◌̀; ) GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
+1F2C;1F2C;0397 0313 0301;1F2C;0397 0313 0301; # (Ἤ; Ἤ; Η◌̓◌́; Ἤ; Η◌̓◌́; ) GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
+1F2D;1F2D;0397 0314 0301;1F2D;0397 0314 0301; # (Ἥ; Ἥ; Η◌̔◌́; Ἥ; Η◌̔◌́; ) GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
+1F2E;1F2E;0397 0313 0342;1F2E;0397 0313 0342; # (Ἦ; Ἦ; Η◌̓◌͂; Ἦ; Η◌̓◌͂; ) GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
+1F2F;1F2F;0397 0314 0342;1F2F;0397 0314 0342; # (Ἧ; Ἧ; Η◌̔◌͂; Ἧ; Η◌̔◌͂; ) GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
+1F30;1F30;03B9 0313;1F30;03B9 0313; # (ἰ; ἰ; ι◌̓; ἰ; ι◌̓; ) GREEK SMALL LETTER IOTA WITH PSILI
+1F31;1F31;03B9 0314;1F31;03B9 0314; # (ἱ; ἱ; ι◌̔; ἱ; ι◌̔; ) GREEK SMALL LETTER IOTA WITH DASIA
+1F32;1F32;03B9 0313 0300;1F32;03B9 0313 0300; # (ἲ; ἲ; ι◌̓◌̀; ἲ; ι◌̓◌̀; ) GREEK SMALL LETTER IOTA WITH PSILI AND VARIA
+1F33;1F33;03B9 0314 0300;1F33;03B9 0314 0300; # (ἳ; ἳ; ι◌̔◌̀; ἳ; ι◌̔◌̀; ) GREEK SMALL LETTER IOTA WITH DASIA AND VARIA
+1F34;1F34;03B9 0313 0301;1F34;03B9 0313 0301; # (ἴ; ἴ; ι◌̓◌́; ἴ; ι◌̓◌́; ) GREEK SMALL LETTER IOTA WITH PSILI AND OXIA
+1F35;1F35;03B9 0314 0301;1F35;03B9 0314 0301; # (ἵ; ἵ; ι◌̔◌́; ἵ; ι◌̔◌́; ) GREEK SMALL LETTER IOTA WITH DASIA AND OXIA
+1F36;1F36;03B9 0313 0342;1F36;03B9 0313 0342; # (ἶ; ἶ; ι◌̓◌͂; ἶ; ι◌̓◌͂; ) GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI
+1F37;1F37;03B9 0314 0342;1F37;03B9 0314 0342; # (ἷ; ἷ; ι◌̔◌͂; ἷ; ι◌̔◌͂; ) GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI
+1F38;1F38;0399 0313;1F38;0399 0313; # (Ἰ; Ἰ; Ι◌̓; Ἰ; Ι◌̓; ) GREEK CAPITAL LETTER IOTA WITH PSILI
+1F39;1F39;0399 0314;1F39;0399 0314; # (Ἱ; Ἱ; Ι◌̔; Ἱ; Ι◌̔; ) GREEK CAPITAL LETTER IOTA WITH DASIA
+1F3A;1F3A;0399 0313 0300;1F3A;0399 0313 0300; # (Ἲ; Ἲ; Ι◌̓◌̀; Ἲ; Ι◌̓◌̀; ) GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
+1F3B;1F3B;0399 0314 0300;1F3B;0399 0314 0300; # (Ἳ; Ἳ; Ι◌̔◌̀; Ἳ; Ι◌̔◌̀; ) GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
+1F3C;1F3C;0399 0313 0301;1F3C;0399 0313 0301; # (Ἴ; Ἴ; Ι◌̓◌́; Ἴ; Ι◌̓◌́; ) GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
+1F3D;1F3D;0399 0314 0301;1F3D;0399 0314 0301; # (Ἵ; Ἵ; Ι◌̔◌́; Ἵ; Ι◌̔◌́; ) GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
+1F3E;1F3E;0399 0313 0342;1F3E;0399 0313 0342; # (Ἶ; Ἶ; Ι◌̓◌͂; Ἶ; Ι◌̓◌͂; ) GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
+1F3F;1F3F;0399 0314 0342;1F3F;0399 0314 0342; # (Ἷ; Ἷ; Ι◌̔◌͂; Ἷ; Ι◌̔◌͂; ) GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
+1F40;1F40;03BF 0313;1F40;03BF 0313; # (ὀ; ὀ; ο◌̓; ὀ; ο◌̓; ) GREEK SMALL LETTER OMICRON WITH PSILI
+1F41;1F41;03BF 0314;1F41;03BF 0314; # (ὁ; ὁ; ο◌̔; ὁ; ο◌̔; ) GREEK SMALL LETTER OMICRON WITH DASIA
+1F42;1F42;03BF 0313 0300;1F42;03BF 0313 0300; # (ὂ; ὂ; ο◌̓◌̀; ὂ; ο◌̓◌̀; ) GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA
+1F43;1F43;03BF 0314 0300;1F43;03BF 0314 0300; # (ὃ; ὃ; ο◌̔◌̀; ὃ; ο◌̔◌̀; ) GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA
+1F44;1F44;03BF 0313 0301;1F44;03BF 0313 0301; # (ὄ; ὄ; ο◌̓◌́; ὄ; ο◌̓◌́; ) GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA
+1F45;1F45;03BF 0314 0301;1F45;03BF 0314 0301; # (ὅ; ὅ; ο◌̔◌́; ὅ; ο◌̔◌́; ) GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
+1F48;1F48;039F 0313;1F48;039F 0313; # (Ὀ; Ὀ; Ο◌̓; Ὀ; Ο◌̓; ) GREEK CAPITAL LETTER OMICRON WITH PSILI
+1F49;1F49;039F 0314;1F49;039F 0314; # (Ὁ; Ὁ; Ο◌̔; Ὁ; Ο◌̔; ) GREEK CAPITAL LETTER OMICRON WITH DASIA
+1F4A;1F4A;039F 0313 0300;1F4A;039F 0313 0300; # (Ὂ; Ὂ; Ο◌̓◌̀; Ὂ; Ο◌̓◌̀; ) GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
+1F4B;1F4B;039F 0314 0300;1F4B;039F 0314 0300; # (Ὃ; Ὃ; Ο◌̔◌̀; Ὃ; Ο◌̔◌̀; ) GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
+1F4C;1F4C;039F 0313 0301;1F4C;039F 0313 0301; # (Ὄ; Ὄ; Ο◌̓◌́; Ὄ; Ο◌̓◌́; ) GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
+1F4D;1F4D;039F 0314 0301;1F4D;039F 0314 0301; # (Ὅ; Ὅ; Ο◌̔◌́; Ὅ; Ο◌̔◌́; ) GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
+1F50;1F50;03C5 0313;1F50;03C5 0313; # (ὐ; ὐ; υ◌̓; ὐ; υ◌̓; ) GREEK SMALL LETTER UPSILON WITH PSILI
+1F51;1F51;03C5 0314;1F51;03C5 0314; # (ὑ; ὑ; υ◌̔; ὑ; υ◌̔; ) GREEK SMALL LETTER UPSILON WITH DASIA
+1F52;1F52;03C5 0313 0300;1F52;03C5 0313 0300; # (ὒ; ὒ; υ◌̓◌̀; ὒ; υ◌̓◌̀; ) GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
+1F53;1F53;03C5 0314 0300;1F53;03C5 0314 0300; # (ὓ; ὓ; υ◌̔◌̀; ὓ; υ◌̔◌̀; ) GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA
+1F54;1F54;03C5 0313 0301;1F54;03C5 0313 0301; # (ὔ; ὔ; υ◌̓◌́; ὔ; υ◌̓◌́; ) GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
+1F55;1F55;03C5 0314 0301;1F55;03C5 0314 0301; # (ὕ; ὕ; υ◌̔◌́; ὕ; υ◌̔◌́; ) GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA
+1F56;1F56;03C5 0313 0342;1F56;03C5 0313 0342; # (ὖ; ὖ; υ◌̓◌͂; ὖ; υ◌̓◌͂; ) GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
+1F57;1F57;03C5 0314 0342;1F57;03C5 0314 0342; # (ὗ; ὗ; υ◌̔◌͂; ὗ; υ◌̔◌͂; ) GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
+1F59;1F59;03A5 0314;1F59;03A5 0314; # (Ὑ; Ὑ; Υ◌̔; Ὑ; Υ◌̔; ) GREEK CAPITAL LETTER UPSILON WITH DASIA
+1F5B;1F5B;03A5 0314 0300;1F5B;03A5 0314 0300; # (Ὓ; Ὓ; Υ◌̔◌̀; Ὓ; Υ◌̔◌̀; ) GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
+1F5D;1F5D;03A5 0314 0301;1F5D;03A5 0314 0301; # (Ὕ; Ὕ; Υ◌̔◌́; Ὕ; Υ◌̔◌́; ) GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
+1F5F;1F5F;03A5 0314 0342;1F5F;03A5 0314 0342; # (Ὗ; Ὗ; Υ◌̔◌͂; Ὗ; Υ◌̔◌͂; ) GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
+1F60;1F60;03C9 0313;1F60;03C9 0313; # (ὠ; ὠ; ω◌̓; ὠ; ω◌̓; ) GREEK SMALL LETTER OMEGA WITH PSILI
+1F61;1F61;03C9 0314;1F61;03C9 0314; # (ὡ; ὡ; ω◌̔; ὡ; ω◌̔; ) GREEK SMALL LETTER OMEGA WITH DASIA
+1F62;1F62;03C9 0313 0300;1F62;03C9 0313 0300; # (ὢ; ὢ; ω◌̓◌̀; ὢ; ω◌̓◌̀; ) GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA
+1F63;1F63;03C9 0314 0300;1F63;03C9 0314 0300; # (ὣ; ὣ; ω◌̔◌̀; ὣ; ω◌̔◌̀; ) GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA
+1F64;1F64;03C9 0313 0301;1F64;03C9 0313 0301; # (ὤ; ὤ; ω◌̓◌́; ὤ; ω◌̓◌́; ) GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA
+1F65;1F65;03C9 0314 0301;1F65;03C9 0314 0301; # (ὥ; ὥ; ω◌̔◌́; ὥ; ω◌̔◌́; ) GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA
+1F66;1F66;03C9 0313 0342;1F66;03C9 0313 0342; # (ὦ; ὦ; ω◌̓◌͂; ὦ; ω◌̓◌͂; ) GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI
+1F67;1F67;03C9 0314 0342;1F67;03C9 0314 0342; # (ὧ; ὧ; ω◌̔◌͂; ὧ; ω◌̔◌͂; ) GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI
+1F68;1F68;03A9 0313;1F68;03A9 0313; # (Ὠ; Ὠ; Ω◌̓; Ὠ; Ω◌̓; ) GREEK CAPITAL LETTER OMEGA WITH PSILI
+1F69;1F69;03A9 0314;1F69;03A9 0314; # (Ὡ; Ὡ; Ω◌̔; Ὡ; Ω◌̔; ) GREEK CAPITAL LETTER OMEGA WITH DASIA
+1F6A;1F6A;03A9 0313 0300;1F6A;03A9 0313 0300; # (Ὢ; Ὢ; Ω◌̓◌̀; Ὢ; Ω◌̓◌̀; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
+1F6B;1F6B;03A9 0314 0300;1F6B;03A9 0314 0300; # (Ὣ; Ὣ; Ω◌̔◌̀; Ὣ; Ω◌̔◌̀; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
+1F6C;1F6C;03A9 0313 0301;1F6C;03A9 0313 0301; # (Ὤ; Ὤ; Ω◌̓◌́; Ὤ; Ω◌̓◌́; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
+1F6D;1F6D;03A9 0314 0301;1F6D;03A9 0314 0301; # (Ὥ; Ὥ; Ω◌̔◌́; Ὥ; Ω◌̔◌́; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
+1F6E;1F6E;03A9 0313 0342;1F6E;03A9 0313 0342; # (Ὦ; Ὦ; Ω◌̓◌͂; Ὦ; Ω◌̓◌͂; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
+1F6F;1F6F;03A9 0314 0342;1F6F;03A9 0314 0342; # (Ὧ; Ὧ; Ω◌̔◌͂; Ὧ; Ω◌̔◌͂; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
+1F70;1F70;03B1 0300;1F70;03B1 0300; # (ὰ; ὰ; α◌̀; ὰ; α◌̀; ) GREEK SMALL LETTER ALPHA WITH VARIA
+1F71;03AC;03B1 0301;03AC;03B1 0301; # (ά; ά; α◌́; ά; α◌́; ) GREEK SMALL LETTER ALPHA WITH OXIA
+1F72;1F72;03B5 0300;1F72;03B5 0300; # (ὲ; ὲ; ε◌̀; ὲ; ε◌̀; ) GREEK SMALL LETTER EPSILON WITH VARIA
+1F73;03AD;03B5 0301;03AD;03B5 0301; # (έ; έ; ε◌́; έ; ε◌́; ) GREEK SMALL LETTER EPSILON WITH OXIA
+1F74;1F74;03B7 0300;1F74;03B7 0300; # (ὴ; ὴ; η◌̀; ὴ; η◌̀; ) GREEK SMALL LETTER ETA WITH VARIA
+1F75;03AE;03B7 0301;03AE;03B7 0301; # (ή; ή; η◌́; ή; η◌́; ) GREEK SMALL LETTER ETA WITH OXIA
+1F76;1F76;03B9 0300;1F76;03B9 0300; # (ὶ; ὶ; ι◌̀; ὶ; ι◌̀; ) GREEK SMALL LETTER IOTA WITH VARIA
+1F77;03AF;03B9 0301;03AF;03B9 0301; # (ί; ί; ι◌́; ί; ι◌́; ) GREEK SMALL LETTER IOTA WITH OXIA
+1F78;1F78;03BF 0300;1F78;03BF 0300; # (ὸ; ὸ; ο◌̀; ὸ; ο◌̀; ) GREEK SMALL LETTER OMICRON WITH VARIA
+1F79;03CC;03BF 0301;03CC;03BF 0301; # (ό; ό; ο◌́; ό; ο◌́; ) GREEK SMALL LETTER OMICRON WITH OXIA
+1F7A;1F7A;03C5 0300;1F7A;03C5 0300; # (ὺ; ὺ; υ◌̀; ὺ; υ◌̀; ) GREEK SMALL LETTER UPSILON WITH VARIA
+1F7B;03CD;03C5 0301;03CD;03C5 0301; # (ύ; ύ; υ◌́; ύ; υ◌́; ) GREEK SMALL LETTER UPSILON WITH OXIA
+1F7C;1F7C;03C9 0300;1F7C;03C9 0300; # (ὼ; ὼ; ω◌̀; ὼ; ω◌̀; ) GREEK SMALL LETTER OMEGA WITH VARIA
+1F7D;03CE;03C9 0301;03CE;03C9 0301; # (ώ; ώ; ω◌́; ώ; ω◌́; ) GREEK SMALL LETTER OMEGA WITH OXIA
+1F80;1F80;03B1 0313 0345;1F80;03B1 0313 0345; # (ᾀ; ᾀ; α◌̓◌ͅ; ᾀ; α◌̓◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
+1F81;1F81;03B1 0314 0345;1F81;03B1 0314 0345; # (ᾁ; ᾁ; α◌̔◌ͅ; ᾁ; α◌̔◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
+1F82;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ᾂ; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1F83;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; # (ᾃ; ᾃ; α◌̔◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1F84;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ᾄ; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1F85;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; # (ᾅ; ᾅ; α◌̔◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1F86;1F86;03B1 0313 0342 0345;1F86;03B1 0313 0342 0345; # (ᾆ; ᾆ; α◌̓◌͂◌ͅ; ᾆ; α◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1F87;1F87;03B1 0314 0342 0345;1F87;03B1 0314 0342 0345; # (ᾇ; ᾇ; α◌̔◌͂◌ͅ; ᾇ; α◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1F88;1F88;0391 0313 0345;1F88;0391 0313 0345; # (ᾈ; ᾈ; Α◌̓◌ͅ; ᾈ; Α◌̓◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
+1F89;1F89;0391 0314 0345;1F89;0391 0314 0345; # (ᾉ; ᾉ; Α◌̔◌ͅ; ᾉ; Α◌̔◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
+1F8A;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (ᾊ; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F8B;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; # (ᾋ; ᾋ; Α◌̔◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F8C;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (ᾌ; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F8D;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; # (ᾍ; ᾍ; Α◌̔◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F8E;1F8E;0391 0313 0342 0345;1F8E;0391 0313 0342 0345; # (ᾎ; ᾎ; Α◌̓◌͂◌ͅ; ᾎ; Α◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F8F;1F8F;0391 0314 0342 0345;1F8F;0391 0314 0342 0345; # (ᾏ; ᾏ; Α◌̔◌͂◌ͅ; ᾏ; Α◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1F90;1F90;03B7 0313 0345;1F90;03B7 0313 0345; # (ᾐ; ᾐ; η◌̓◌ͅ; ᾐ; η◌̓◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
+1F91;1F91;03B7 0314 0345;1F91;03B7 0314 0345; # (ᾑ; ᾑ; η◌̔◌ͅ; ᾑ; η◌̔◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
+1F92;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ᾒ; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1F93;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; # (ᾓ; ᾓ; η◌̔◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1F94;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ᾔ; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1F95;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; # (ᾕ; ᾕ; η◌̔◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1F96;1F96;03B7 0313 0342 0345;1F96;03B7 0313 0342 0345; # (ᾖ; ᾖ; η◌̓◌͂◌ͅ; ᾖ; η◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1F97;1F97;03B7 0314 0342 0345;1F97;03B7 0314 0342 0345; # (ᾗ; ᾗ; η◌̔◌͂◌ͅ; ᾗ; η◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1F98;1F98;0397 0313 0345;1F98;0397 0313 0345; # (ᾘ; ᾘ; Η◌̓◌ͅ; ᾘ; Η◌̓◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
+1F99;1F99;0397 0314 0345;1F99;0397 0314 0345; # (ᾙ; ᾙ; Η◌̔◌ͅ; ᾙ; Η◌̔◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
+1F9A;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (ᾚ; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F9B;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; # (ᾛ; ᾛ; Η◌̔◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F9C;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (ᾜ; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F9D;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; # (ᾝ; ᾝ; Η◌̔◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F9E;1F9E;0397 0313 0342 0345;1F9E;0397 0313 0342 0345; # (ᾞ; ᾞ; Η◌̓◌͂◌ͅ; ᾞ; Η◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F9F;1F9F;0397 0314 0342 0345;1F9F;0397 0314 0342 0345; # (ᾟ; ᾟ; Η◌̔◌͂◌ͅ; ᾟ; Η◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1FA0;1FA0;03C9 0313 0345;1FA0;03C9 0313 0345; # (ᾠ; ᾠ; ω◌̓◌ͅ; ᾠ; ω◌̓◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
+1FA1;1FA1;03C9 0314 0345;1FA1;03C9 0314 0345; # (ᾡ; ᾡ; ω◌̔◌ͅ; ᾡ; ω◌̔◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
+1FA2;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ᾢ; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1FA3;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; # (ᾣ; ᾣ; ω◌̔◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1FA4;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ᾤ; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1FA5;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; # (ᾥ; ᾥ; ω◌̔◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1FA6;1FA6;03C9 0313 0342 0345;1FA6;03C9 0313 0342 0345; # (ᾦ; ᾦ; ω◌̓◌͂◌ͅ; ᾦ; ω◌̓◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1FA7;1FA7;03C9 0314 0342 0345;1FA7;03C9 0314 0342 0345; # (ᾧ; ᾧ; ω◌̔◌͂◌ͅ; ᾧ; ω◌̔◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1FA8;1FA8;03A9 0313 0345;1FA8;03A9 0313 0345; # (ᾨ; ᾨ; Ω◌̓◌ͅ; ᾨ; Ω◌̓◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
+1FA9;1FA9;03A9 0314 0345;1FA9;03A9 0314 0345; # (ᾩ; ᾩ; Ω◌̔◌ͅ; ᾩ; Ω◌̔◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
+1FAA;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (ᾪ; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1FAB;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; # (ᾫ; ᾫ; Ω◌̔◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1FAC;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (ᾬ; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1FAD;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; # (ᾭ; ᾭ; Ω◌̔◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1FAE;1FAE;03A9 0313 0342 0345;1FAE;03A9 0313 0342 0345; # (ᾮ; ᾮ; Ω◌̓◌͂◌ͅ; ᾮ; Ω◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1FAF;1FAF;03A9 0314 0342 0345;1FAF;03A9 0314 0342 0345; # (ᾯ; ᾯ; Ω◌̔◌͂◌ͅ; ᾯ; Ω◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1FB0;1FB0;03B1 0306;1FB0;03B1 0306; # (ᾰ; ᾰ; α◌̆; ᾰ; α◌̆; ) GREEK SMALL LETTER ALPHA WITH VRACHY
+1FB1;1FB1;03B1 0304;1FB1;03B1 0304; # (ᾱ; ᾱ; α◌̄; ᾱ; α◌̄; ) GREEK SMALL LETTER ALPHA WITH MACRON
+1FB2;1FB2;03B1 0300 0345;1FB2;03B1 0300 0345; # (ᾲ; ᾲ; α◌̀◌ͅ; ᾲ; α◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
+1FB3;1FB3;03B1 0345;1FB3;03B1 0345; # (ᾳ; ᾳ; α◌ͅ; ᾳ; α◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
+1FB4;1FB4;03B1 0301 0345;1FB4;03B1 0301 0345; # (ᾴ; ᾴ; α◌́◌ͅ; ᾴ; α◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
+1FB6;1FB6;03B1 0342;1FB6;03B1 0342; # (ᾶ; ᾶ; α◌͂; ᾶ; α◌͂; ) GREEK SMALL LETTER ALPHA WITH PERISPOMENI
+1FB7;1FB7;03B1 0342 0345;1FB7;03B1 0342 0345; # (ᾷ; ᾷ; α◌͂◌ͅ; ᾷ; α◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
+1FB8;1FB8;0391 0306;1FB8;0391 0306; # (Ᾰ; Ᾰ; Α◌̆; Ᾰ; Α◌̆; ) GREEK CAPITAL LETTER ALPHA WITH VRACHY
+1FB9;1FB9;0391 0304;1FB9;0391 0304; # (Ᾱ; Ᾱ; Α◌̄; Ᾱ; Α◌̄; ) GREEK CAPITAL LETTER ALPHA WITH MACRON
+1FBA;1FBA;0391 0300;1FBA;0391 0300; # (Ὰ; Ὰ; Α◌̀; Ὰ; Α◌̀; ) GREEK CAPITAL LETTER ALPHA WITH VARIA
+1FBB;0386;0391 0301;0386;0391 0301; # (Ά; Ά; Α◌́; Ά; Α◌́; ) GREEK CAPITAL LETTER ALPHA WITH OXIA
+1FBC;1FBC;0391 0345;1FBC;0391 0345; # (ᾼ; ᾼ; Α◌ͅ; ᾼ; Α◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+1FBD;1FBD;1FBD;0020 0313;0020 0313; # (᾽; ᾽; ᾽; ◌̓; ◌̓; ) GREEK KORONIS
+1FBE;03B9;03B9;03B9;03B9; # (ι; ι; ι; ι; ι; ) GREEK PROSGEGRAMMENI
+1FBF;1FBF;1FBF;0020 0313;0020 0313; # (᾿; ᾿; ᾿; ◌̓; ◌̓; ) GREEK PSILI
+1FC0;1FC0;1FC0;0020 0342;0020 0342; # (῀; ῀; ῀; ◌͂; ◌͂; ) GREEK PERISPOMENI
+1FC1;1FC1;00A8 0342;0020 0308 0342;0020 0308 0342; # (῁; ῁; ¨◌͂; ◌̈◌͂; ◌̈◌͂; ) GREEK DIALYTIKA AND PERISPOMENI
+1FC2;1FC2;03B7 0300 0345;1FC2;03B7 0300 0345; # (ῂ; ῂ; η◌̀◌ͅ; ῂ; η◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
+1FC3;1FC3;03B7 0345;1FC3;03B7 0345; # (ῃ; ῃ; η◌ͅ; ῃ; η◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
+1FC4;1FC4;03B7 0301 0345;1FC4;03B7 0301 0345; # (ῄ; ῄ; η◌́◌ͅ; ῄ; η◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
+1FC6;1FC6;03B7 0342;1FC6;03B7 0342; # (ῆ; ῆ; η◌͂; ῆ; η◌͂; ) GREEK SMALL LETTER ETA WITH PERISPOMENI
+1FC7;1FC7;03B7 0342 0345;1FC7;03B7 0342 0345; # (ῇ; ῇ; η◌͂◌ͅ; ῇ; η◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
+1FC8;1FC8;0395 0300;1FC8;0395 0300; # (Ὲ; Ὲ; Ε◌̀; Ὲ; Ε◌̀; ) GREEK CAPITAL LETTER EPSILON WITH VARIA
+1FC9;0388;0395 0301;0388;0395 0301; # (Έ; Έ; Ε◌́; Έ; Ε◌́; ) GREEK CAPITAL LETTER EPSILON WITH OXIA
+1FCA;1FCA;0397 0300;1FCA;0397 0300; # (Ὴ; Ὴ; Η◌̀; Ὴ; Η◌̀; ) GREEK CAPITAL LETTER ETA WITH VARIA
+1FCB;0389;0397 0301;0389;0397 0301; # (Ή; Ή; Η◌́; Ή; Η◌́; ) GREEK CAPITAL LETTER ETA WITH OXIA
+1FCC;1FCC;0397 0345;1FCC;0397 0345; # (ῌ; ῌ; Η◌ͅ; ῌ; Η◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+1FCD;1FCD;1FBF 0300;0020 0313 0300;0020 0313 0300; # (῍; ῍; ᾿◌̀; ◌̓◌̀; ◌̓◌̀; ) GREEK PSILI AND VARIA
+1FCE;1FCE;1FBF 0301;0020 0313 0301;0020 0313 0301; # (῎; ῎; ᾿◌́; ◌̓◌́; ◌̓◌́; ) GREEK PSILI AND OXIA
+1FCF;1FCF;1FBF 0342;0020 0313 0342;0020 0313 0342; # (῏; ῏; ᾿◌͂; ◌̓◌͂; ◌̓◌͂; ) GREEK PSILI AND PERISPOMENI
+1FD0;1FD0;03B9 0306;1FD0;03B9 0306; # (ῐ; ῐ; ι◌̆; ῐ; ι◌̆; ) GREEK SMALL LETTER IOTA WITH VRACHY
+1FD1;1FD1;03B9 0304;1FD1;03B9 0304; # (ῑ; ῑ; ι◌̄; ῑ; ι◌̄; ) GREEK SMALL LETTER IOTA WITH MACRON
+1FD2;1FD2;03B9 0308 0300;1FD2;03B9 0308 0300; # (ῒ; ῒ; ι◌̈◌̀; ῒ; ι◌̈◌̀; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
+1FD3;0390;03B9 0308 0301;0390;03B9 0308 0301; # (ΐ; ΐ; ι◌̈◌́; ΐ; ι◌̈◌́; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
+1FD6;1FD6;03B9 0342;1FD6;03B9 0342; # (ῖ; ῖ; ι◌͂; ῖ; ι◌͂; ) GREEK SMALL LETTER IOTA WITH PERISPOMENI
+1FD7;1FD7;03B9 0308 0342;1FD7;03B9 0308 0342; # (ῗ; ῗ; ι◌̈◌͂; ῗ; ι◌̈◌͂; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
+1FD8;1FD8;0399 0306;1FD8;0399 0306; # (Ῐ; Ῐ; Ι◌̆; Ῐ; Ι◌̆; ) GREEK CAPITAL LETTER IOTA WITH VRACHY
+1FD9;1FD9;0399 0304;1FD9;0399 0304; # (Ῑ; Ῑ; Ι◌̄; Ῑ; Ι◌̄; ) GREEK CAPITAL LETTER IOTA WITH MACRON
+1FDA;1FDA;0399 0300;1FDA;0399 0300; # (Ὶ; Ὶ; Ι◌̀; Ὶ; Ι◌̀; ) GREEK CAPITAL LETTER IOTA WITH VARIA
+1FDB;038A;0399 0301;038A;0399 0301; # (Ί; Ί; Ι◌́; Ί; Ι◌́; ) GREEK CAPITAL LETTER IOTA WITH OXIA
+1FDD;1FDD;1FFE 0300;0020 0314 0300;0020 0314 0300; # (῝; ῝; ῾◌̀; ◌̔◌̀; ◌̔◌̀; ) GREEK DASIA AND VARIA
+1FDE;1FDE;1FFE 0301;0020 0314 0301;0020 0314 0301; # (῞; ῞; ῾◌́; ◌̔◌́; ◌̔◌́; ) GREEK DASIA AND OXIA
+1FDF;1FDF;1FFE 0342;0020 0314 0342;0020 0314 0342; # (῟; ῟; ῾◌͂; ◌̔◌͂; ◌̔◌͂; ) GREEK DASIA AND PERISPOMENI
+1FE0;1FE0;03C5 0306;1FE0;03C5 0306; # (ῠ; ῠ; υ◌̆; ῠ; υ◌̆; ) GREEK SMALL LETTER UPSILON WITH VRACHY
+1FE1;1FE1;03C5 0304;1FE1;03C5 0304; # (ῡ; ῡ; υ◌̄; ῡ; υ◌̄; ) GREEK SMALL LETTER UPSILON WITH MACRON
+1FE2;1FE2;03C5 0308 0300;1FE2;03C5 0308 0300; # (ῢ; ῢ; υ◌̈◌̀; ῢ; υ◌̈◌̀; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
+1FE3;03B0;03C5 0308 0301;03B0;03C5 0308 0301; # (ΰ; ΰ; υ◌̈◌́; ΰ; υ◌̈◌́; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
+1FE4;1FE4;03C1 0313;1FE4;03C1 0313; # (ῤ; ῤ; ρ◌̓; ῤ; ρ◌̓; ) GREEK SMALL LETTER RHO WITH PSILI
+1FE5;1FE5;03C1 0314;1FE5;03C1 0314; # (ῥ; ῥ; ρ◌̔; ῥ; ρ◌̔; ) GREEK SMALL LETTER RHO WITH DASIA
+1FE6;1FE6;03C5 0342;1FE6;03C5 0342; # (ῦ; ῦ; υ◌͂; ῦ; υ◌͂; ) GREEK SMALL LETTER UPSILON WITH PERISPOMENI
+1FE7;1FE7;03C5 0308 0342;1FE7;03C5 0308 0342; # (ῧ; ῧ; υ◌̈◌͂; ῧ; υ◌̈◌͂; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
+1FE8;1FE8;03A5 0306;1FE8;03A5 0306; # (Ῠ; Ῠ; Υ◌̆; Ῠ; Υ◌̆; ) GREEK CAPITAL LETTER UPSILON WITH VRACHY
+1FE9;1FE9;03A5 0304;1FE9;03A5 0304; # (Ῡ; Ῡ; Υ◌̄; Ῡ; Υ◌̄; ) GREEK CAPITAL LETTER UPSILON WITH MACRON
+1FEA;1FEA;03A5 0300;1FEA;03A5 0300; # (Ὺ; Ὺ; Υ◌̀; Ὺ; Υ◌̀; ) GREEK CAPITAL LETTER UPSILON WITH VARIA
+1FEB;038E;03A5 0301;038E;03A5 0301; # (Ύ; Ύ; Υ◌́; Ύ; Υ◌́; ) GREEK CAPITAL LETTER UPSILON WITH OXIA
+1FEC;1FEC;03A1 0314;1FEC;03A1 0314; # (Ῥ; Ῥ; Ρ◌̔; Ῥ; Ρ◌̔; ) GREEK CAPITAL LETTER RHO WITH DASIA
+1FED;1FED;00A8 0300;0020 0308 0300;0020 0308 0300; # (῭; ῭; ¨◌̀; ◌̈◌̀; ◌̈◌̀; ) GREEK DIALYTIKA AND VARIA
+1FEE;0385;00A8 0301;0020 0308 0301;0020 0308 0301; # (΅; ΅; ¨◌́; ◌̈◌́; ◌̈◌́; ) GREEK DIALYTIKA AND OXIA
+1FEF;0060;0060;0060;0060; # (`; `; `; `; `; ) GREEK VARIA
+1FF2;1FF2;03C9 0300 0345;1FF2;03C9 0300 0345; # (ῲ; ῲ; ω◌̀◌ͅ; ῲ; ω◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
+1FF3;1FF3;03C9 0345;1FF3;03C9 0345; # (ῳ; ῳ; ω◌ͅ; ῳ; ω◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
+1FF4;1FF4;03C9 0301 0345;1FF4;03C9 0301 0345; # (ῴ; ῴ; ω◌́◌ͅ; ῴ; ω◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
+1FF6;1FF6;03C9 0342;1FF6;03C9 0342; # (ῶ; ῶ; ω◌͂; ῶ; ω◌͂; ) GREEK SMALL LETTER OMEGA WITH PERISPOMENI
+1FF7;1FF7;03C9 0342 0345;1FF7;03C9 0342 0345; # (ῷ; ῷ; ω◌͂◌ͅ; ῷ; ω◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
+1FF8;1FF8;039F 0300;1FF8;039F 0300; # (Ὸ; Ὸ; Ο◌̀; Ὸ; Ο◌̀; ) GREEK CAPITAL LETTER OMICRON WITH VARIA
+1FF9;038C;039F 0301;038C;039F 0301; # (Ό; Ό; Ο◌́; Ό; Ο◌́; ) GREEK CAPITAL LETTER OMICRON WITH OXIA
+1FFA;1FFA;03A9 0300;1FFA;03A9 0300; # (Ὼ; Ὼ; Ω◌̀; Ὼ; Ω◌̀; ) GREEK CAPITAL LETTER OMEGA WITH VARIA
+1FFB;038F;03A9 0301;038F;03A9 0301; # (Ώ; Ώ; Ω◌́; Ώ; Ω◌́; ) GREEK CAPITAL LETTER OMEGA WITH OXIA
+1FFC;1FFC;03A9 0345;1FFC;03A9 0345; # (ῼ; ῼ; Ω◌ͅ; ῼ; Ω◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+1FFD;00B4;00B4;0020 0301;0020 0301; # (´; ´; ´; ◌́; ◌́; ) GREEK OXIA
+1FFE;1FFE;1FFE;0020 0314;0020 0314; # (῾; ῾; ῾; ◌̔; ◌̔; ) GREEK DASIA
+2000;2002;2002;0020;0020; # ( ;  ;  ; ; ; ) EN QUAD
+2001;2003;2003;0020;0020; # ( ;  ;  ; ; ; ) EM QUAD
+2002;2002;2002;0020;0020; # ( ;  ;  ; ; ; ) EN SPACE
+2003;2003;2003;0020;0020; # ( ;  ;  ; ; ; ) EM SPACE
+2004;2004;2004;0020;0020; # ( ;  ;  ; ; ; ) THREE-PER-EM SPACE
+2005;2005;2005;0020;0020; # ( ;  ;  ; ; ; ) FOUR-PER-EM SPACE
+2006;2006;2006;0020;0020; # ( ;  ;  ; ; ; ) SIX-PER-EM SPACE
+2007;2007;2007;0020;0020; # ( ;  ;  ; ; ; ) FIGURE SPACE
+2008;2008;2008;0020;0020; # ( ;  ;  ; ; ; ) PUNCTUATION SPACE
+2009;2009;2009;0020;0020; # ( ;  ;  ; ; ; ) THIN SPACE
+200A;200A;200A;0020;0020; # ( ;  ;  ; ; ; ) HAIR SPACE
+2011;2011;2011;2010;2010; # (‑; ‑; ‑; ‐; ‐; ) NON-BREAKING HYPHEN
+2017;2017;2017;0020 0333;0020 0333; # (‗; ‗; ‗; ◌̳; ◌̳; ) DOUBLE LOW LINE
+2024;2024;2024;002E;002E; # (․; ․; ․; .; .; ) ONE DOT LEADER
+2025;2025;2025;002E 002E;002E 002E; # (‥; ‥; ‥; ..; ..; ) TWO DOT LEADER
+2026;2026;2026;002E 002E 002E;002E 002E 002E; # (…; …; …; ...; ...; ) HORIZONTAL ELLIPSIS
+202F;202F;202F;0020;0020; # ( ;  ;  ; ; ; ) NARROW NO-BREAK SPACE
+2033;2033;2033;2032 2032;2032 2032; # (″; ″; ″; ′′; ′′; ) DOUBLE PRIME
+2034;2034;2034;2032 2032 2032;2032 2032 2032; # (‴; ‴; ‴; ′′′; ′′′; ) TRIPLE PRIME
+2036;2036;2036;2035 2035;2035 2035; # (‶; ‶; ‶; ‵‵; ‵‵; ) REVERSED DOUBLE PRIME
+2037;2037;2037;2035 2035 2035;2035 2035 2035; # (‷; ‷; ‷; ‵‵‵; ‵‵‵; ) REVERSED TRIPLE PRIME
+203C;203C;203C;0021 0021;0021 0021; # (‼; ‼; ‼; !!; !!; ) DOUBLE EXCLAMATION MARK
+203E;203E;203E;0020 0305;0020 0305; # (‾; ‾; ‾; ◌̅; ◌̅; ) OVERLINE
+2047;2047;2047;003F 003F;003F 003F; # (⁇; ⁇; ⁇; ??; ??; ) DOUBLE QUESTION MARK
+2048;2048;2048;003F 0021;003F 0021; # (⁈; ⁈; ⁈; ?!; ?!; ) QUESTION EXCLAMATION MARK
+2049;2049;2049;0021 003F;0021 003F; # (⁉; ⁉; ⁉; !?; !?; ) EXCLAMATION QUESTION MARK
+2057;2057;2057;2032 2032 2032 2032;2032 2032 2032 2032; # (⁗; ⁗; ⁗; ′′′′; ′′′′; ) QUADRUPLE PRIME
+205F;205F;205F;0020;0020; # ( ;  ;  ; ; ; ) MEDIUM MATHEMATICAL SPACE
+2070;2070;2070;0030;0030; # (⁰; ⁰; ⁰; 0; 0; ) SUPERSCRIPT ZERO
+2071;2071;2071;0069;0069; # (ⁱ; ⁱ; ⁱ; i; i; ) SUPERSCRIPT LATIN SMALL LETTER I
+2074;2074;2074;0034;0034; # (⁴; ⁴; ⁴; 4; 4; ) SUPERSCRIPT FOUR
+2075;2075;2075;0035;0035; # (⁵; ⁵; ⁵; 5; 5; ) SUPERSCRIPT FIVE
+2076;2076;2076;0036;0036; # (⁶; ⁶; ⁶; 6; 6; ) SUPERSCRIPT SIX
+2077;2077;2077;0037;0037; # (⁷; ⁷; ⁷; 7; 7; ) SUPERSCRIPT SEVEN
+2078;2078;2078;0038;0038; # (⁸; ⁸; ⁸; 8; 8; ) SUPERSCRIPT EIGHT
+2079;2079;2079;0039;0039; # (⁹; ⁹; ⁹; 9; 9; ) SUPERSCRIPT NINE
+207A;207A;207A;002B;002B; # (⁺; ⁺; ⁺; +; +; ) SUPERSCRIPT PLUS SIGN
+207B;207B;207B;2212;2212; # (⁻; ⁻; ⁻; −; −; ) SUPERSCRIPT MINUS
+207C;207C;207C;003D;003D; # (⁼; ⁼; ⁼; =; =; ) SUPERSCRIPT EQUALS SIGN
+207D;207D;207D;0028;0028; # (⁽; ⁽; ⁽; (; (; ) SUPERSCRIPT LEFT PARENTHESIS
+207E;207E;207E;0029;0029; # (⁾; ⁾; ⁾; ); ); ) SUPERSCRIPT RIGHT PARENTHESIS
+207F;207F;207F;006E;006E; # (ⁿ; ⁿ; ⁿ; n; n; ) SUPERSCRIPT LATIN SMALL LETTER N
+2080;2080;2080;0030;0030; # (₀; ₀; ₀; 0; 0; ) SUBSCRIPT ZERO
+2081;2081;2081;0031;0031; # (₁; ₁; ₁; 1; 1; ) SUBSCRIPT ONE
+2082;2082;2082;0032;0032; # (₂; ₂; ₂; 2; 2; ) SUBSCRIPT TWO
+2083;2083;2083;0033;0033; # (₃; ₃; ₃; 3; 3; ) SUBSCRIPT THREE
+2084;2084;2084;0034;0034; # (₄; ₄; ₄; 4; 4; ) SUBSCRIPT FOUR
+2085;2085;2085;0035;0035; # (₅; ₅; ₅; 5; 5; ) SUBSCRIPT FIVE
+2086;2086;2086;0036;0036; # (₆; ₆; ₆; 6; 6; ) SUBSCRIPT SIX
+2087;2087;2087;0037;0037; # (₇; ₇; ₇; 7; 7; ) SUBSCRIPT SEVEN
+2088;2088;2088;0038;0038; # (₈; ₈; ₈; 8; 8; ) SUBSCRIPT EIGHT
+2089;2089;2089;0039;0039; # (₉; ₉; ₉; 9; 9; ) SUBSCRIPT NINE
+208A;208A;208A;002B;002B; # (₊; ₊; ₊; +; +; ) SUBSCRIPT PLUS SIGN
+208B;208B;208B;2212;2212; # (₋; ₋; ₋; −; −; ) SUBSCRIPT MINUS
+208C;208C;208C;003D;003D; # (₌; ₌; ₌; =; =; ) SUBSCRIPT EQUALS SIGN
+208D;208D;208D;0028;0028; # (₍; ₍; ₍; (; (; ) SUBSCRIPT LEFT PARENTHESIS
+208E;208E;208E;0029;0029; # (₎; ₎; ₎; ); ); ) SUBSCRIPT RIGHT PARENTHESIS
+2090;2090;2090;0061;0061; # (ₐ; ₐ; ₐ; a; a; ) LATIN SUBSCRIPT SMALL LETTER A
+2091;2091;2091;0065;0065; # (ₑ; ₑ; ₑ; e; e; ) LATIN SUBSCRIPT SMALL LETTER E
+2092;2092;2092;006F;006F; # (ₒ; ₒ; ₒ; o; o; ) LATIN SUBSCRIPT SMALL LETTER O
+2093;2093;2093;0078;0078; # (ₓ; ₓ; ₓ; x; x; ) LATIN SUBSCRIPT SMALL LETTER X
+2094;2094;2094;0259;0259; # (ₔ; ₔ; ₔ; ə; ə; ) LATIN SUBSCRIPT SMALL LETTER SCHWA
+2095;2095;2095;0068;0068; # (ₕ; ₕ; ₕ; h; h; ) LATIN SUBSCRIPT SMALL LETTER H
+2096;2096;2096;006B;006B; # (ₖ; ₖ; ₖ; k; k; ) LATIN SUBSCRIPT SMALL LETTER K
+2097;2097;2097;006C;006C; # (ₗ; ₗ; ₗ; l; l; ) LATIN SUBSCRIPT SMALL LETTER L
+2098;2098;2098;006D;006D; # (ₘ; ₘ; ₘ; m; m; ) LATIN SUBSCRIPT SMALL LETTER M
+2099;2099;2099;006E;006E; # (ₙ; ₙ; ₙ; n; n; ) LATIN SUBSCRIPT SMALL LETTER N
+209A;209A;209A;0070;0070; # (ₚ; ₚ; ₚ; p; p; ) LATIN SUBSCRIPT SMALL LETTER P
+209B;209B;209B;0073;0073; # (ₛ; ₛ; ₛ; s; s; ) LATIN SUBSCRIPT SMALL LETTER S
+209C;209C;209C;0074;0074; # (ₜ; ₜ; ₜ; t; t; ) LATIN SUBSCRIPT SMALL LETTER T
+20A8;20A8;20A8;0052 0073;0052 0073; # (₨; ₨; ₨; Rs; Rs; ) RUPEE SIGN
+2100;2100;2100;0061 002F 0063;0061 002F 0063; # (℀; ℀; ℀; a/c; a/c; ) ACCOUNT OF
+2101;2101;2101;0061 002F 0073;0061 002F 0073; # (℁; ℁; ℁; a/s; a/s; ) ADDRESSED TO THE SUBJECT
+2102;2102;2102;0043;0043; # (ℂ; ℂ; ℂ; C; C; ) DOUBLE-STRUCK CAPITAL C
+2103;2103;2103;00B0 0043;00B0 0043; # (℃; ℃; ℃; °C; °C; ) DEGREE CELSIUS
+2105;2105;2105;0063 002F 006F;0063 002F 006F; # (℅; ℅; ℅; c/o; c/o; ) CARE OF
+2106;2106;2106;0063 002F 0075;0063 002F 0075; # (℆; ℆; ℆; c/u; c/u; ) CADA UNA
+2107;2107;2107;0190;0190; # (ℇ; ℇ; ℇ; Ɛ; Ɛ; ) EULER CONSTANT
+2109;2109;2109;00B0 0046;00B0 0046; # (℉; ℉; ℉; °F; °F; ) DEGREE FAHRENHEIT
+210A;210A;210A;0067;0067; # (ℊ; ℊ; ℊ; g; g; ) SCRIPT SMALL G
+210B;210B;210B;0048;0048; # (ℋ; ℋ; ℋ; H; H; ) SCRIPT CAPITAL H
+210C;210C;210C;0048;0048; # (ℌ; ℌ; ℌ; H; H; ) BLACK-LETTER CAPITAL H
+210D;210D;210D;0048;0048; # (ℍ; ℍ; ℍ; H; H; ) DOUBLE-STRUCK CAPITAL H
+210E;210E;210E;0068;0068; # (ℎ; ℎ; ℎ; h; h; ) PLANCK CONSTANT
+210F;210F;210F;0127;0127; # (ℏ; ℏ; ℏ; ħ; ħ; ) PLANCK CONSTANT OVER TWO PI
+2110;2110;2110;0049;0049; # (ℐ; ℐ; ℐ; I; I; ) SCRIPT CAPITAL I
+2111;2111;2111;0049;0049; # (ℑ; ℑ; ℑ; I; I; ) BLACK-LETTER CAPITAL I
+2112;2112;2112;004C;004C; # (ℒ; ℒ; ℒ; L; L; ) SCRIPT CAPITAL L
+2113;2113;2113;006C;006C; # (ℓ; ℓ; ℓ; l; l; ) SCRIPT SMALL L
+2115;2115;2115;004E;004E; # (ℕ; ℕ; ℕ; N; N; ) DOUBLE-STRUCK CAPITAL N
+2116;2116;2116;004E 006F;004E 006F; # (№; №; №; No; No; ) NUMERO SIGN
+2119;2119;2119;0050;0050; # (ℙ; ℙ; ℙ; P; P; ) DOUBLE-STRUCK CAPITAL P
+211A;211A;211A;0051;0051; # (ℚ; ℚ; ℚ; Q; Q; ) DOUBLE-STRUCK CAPITAL Q
+211B;211B;211B;0052;0052; # (ℛ; ℛ; ℛ; R; R; ) SCRIPT CAPITAL R
+211C;211C;211C;0052;0052; # (ℜ; ℜ; ℜ; R; R; ) BLACK-LETTER CAPITAL R
+211D;211D;211D;0052;0052; # (ℝ; ℝ; ℝ; R; R; ) DOUBLE-STRUCK CAPITAL R
+2120;2120;2120;0053 004D;0053 004D; # (℠; ℠; ℠; SM; SM; ) SERVICE MARK
+2121;2121;2121;0054 0045 004C;0054 0045 004C; # (℡; ℡; ℡; TEL; TEL; ) TELEPHONE SIGN
+2122;2122;2122;0054 004D;0054 004D; # (™; ™; ™; TM; TM; ) TRADE MARK SIGN
+2124;2124;2124;005A;005A; # (ℤ; ℤ; ℤ; Z; Z; ) DOUBLE-STRUCK CAPITAL Z
+2126;03A9;03A9;03A9;03A9; # (Ω; Ω; Ω; Ω; Ω; ) OHM SIGN
+2128;2128;2128;005A;005A; # (ℨ; ℨ; ℨ; Z; Z; ) BLACK-LETTER CAPITAL Z
+212A;004B;004B;004B;004B; # (K; K; K; K; K; ) KELVIN SIGN
+212B;00C5;0041 030A;00C5;0041 030A; # (Å; Å; A◌̊; Å; A◌̊; ) ANGSTROM SIGN
+212C;212C;212C;0042;0042; # (ℬ; ℬ; ℬ; B; B; ) SCRIPT CAPITAL B
+212D;212D;212D;0043;0043; # (ℭ; ℭ; ℭ; C; C; ) BLACK-LETTER CAPITAL C
+212F;212F;212F;0065;0065; # (ℯ; ℯ; ℯ; e; e; ) SCRIPT SMALL E
+2130;2130;2130;0045;0045; # (ℰ; ℰ; ℰ; E; E; ) SCRIPT CAPITAL E
+2131;2131;2131;0046;0046; # (ℱ; ℱ; ℱ; F; F; ) SCRIPT CAPITAL F
+2133;2133;2133;004D;004D; # (ℳ; ℳ; ℳ; M; M; ) SCRIPT CAPITAL M
+2134;2134;2134;006F;006F; # (ℴ; ℴ; ℴ; o; o; ) SCRIPT SMALL O
+2135;2135;2135;05D0;05D0; # (ℵ; ℵ; ℵ; א; א; ) ALEF SYMBOL
+2136;2136;2136;05D1;05D1; # (ℶ; ℶ; ℶ; ב; ב; ) BET SYMBOL
+2137;2137;2137;05D2;05D2; # (ℷ; ℷ; ℷ; ג; ג; ) GIMEL SYMBOL
+2138;2138;2138;05D3;05D3; # (ℸ; ℸ; ℸ; ד; ד; ) DALET SYMBOL
+2139;2139;2139;0069;0069; # (ℹ; ℹ; ℹ; i; i; ) INFORMATION SOURCE
+213B;213B;213B;0046 0041 0058;0046 0041 0058; # (℻; ℻; ℻; FAX; FAX; ) FACSIMILE SIGN
+213C;213C;213C;03C0;03C0; # (ℼ; ℼ; ℼ; π; π; ) DOUBLE-STRUCK SMALL PI
+213D;213D;213D;03B3;03B3; # (ℽ; ℽ; ℽ; γ; γ; ) DOUBLE-STRUCK SMALL GAMMA
+213E;213E;213E;0393;0393; # (ℾ; ℾ; ℾ; Γ; Γ; ) DOUBLE-STRUCK CAPITAL GAMMA
+213F;213F;213F;03A0;03A0; # (ℿ; ℿ; ℿ; Π; Π; ) DOUBLE-STRUCK CAPITAL PI
+2140;2140;2140;2211;2211; # (⅀; ⅀; ⅀; ∑; ∑; ) DOUBLE-STRUCK N-ARY SUMMATION
+2145;2145;2145;0044;0044; # (ⅅ; ⅅ; ⅅ; D; D; ) DOUBLE-STRUCK ITALIC CAPITAL D
+2146;2146;2146;0064;0064; # (ⅆ; ⅆ; ⅆ; d; d; ) DOUBLE-STRUCK ITALIC SMALL D
+2147;2147;2147;0065;0065; # (ⅇ; ⅇ; ⅇ; e; e; ) DOUBLE-STRUCK ITALIC SMALL E
+2148;2148;2148;0069;0069; # (ⅈ; ⅈ; ⅈ; i; i; ) DOUBLE-STRUCK ITALIC SMALL I
+2149;2149;2149;006A;006A; # (ⅉ; ⅉ; ⅉ; j; j; ) DOUBLE-STRUCK ITALIC SMALL J
+2150;2150;2150;0031 2044 0037;0031 2044 0037; # (⅐; ⅐; ⅐; 1⁄7; 1⁄7; ) VULGAR FRACTION ONE SEVENTH
+2151;2151;2151;0031 2044 0039;0031 2044 0039; # (⅑; ⅑; ⅑; 1⁄9; 1⁄9; ) VULGAR FRACTION ONE NINTH
+2152;2152;2152;0031 2044 0031 0030;0031 2044 0031 0030; # (⅒; ⅒; ⅒; 1⁄10; 1⁄10; ) VULGAR FRACTION ONE TENTH
+2153;2153;2153;0031 2044 0033;0031 2044 0033; # (⅓; ⅓; ⅓; 1⁄3; 1⁄3; ) VULGAR FRACTION ONE THIRD
+2154;2154;2154;0032 2044 0033;0032 2044 0033; # (⅔; ⅔; ⅔; 2⁄3; 2⁄3; ) VULGAR FRACTION TWO THIRDS
+2155;2155;2155;0031 2044 0035;0031 2044 0035; # (⅕; ⅕; ⅕; 1⁄5; 1⁄5; ) VULGAR FRACTION ONE FIFTH
+2156;2156;2156;0032 2044 0035;0032 2044 0035; # (⅖; ⅖; ⅖; 2⁄5; 2⁄5; ) VULGAR FRACTION TWO FIFTHS
+2157;2157;2157;0033 2044 0035;0033 2044 0035; # (⅗; ⅗; ⅗; 3⁄5; 3⁄5; ) VULGAR FRACTION THREE FIFTHS
+2158;2158;2158;0034 2044 0035;0034 2044 0035; # (⅘; ⅘; ⅘; 4⁄5; 4⁄5; ) VULGAR FRACTION FOUR FIFTHS
+2159;2159;2159;0031 2044 0036;0031 2044 0036; # (⅙; ⅙; ⅙; 1⁄6; 1⁄6; ) VULGAR FRACTION ONE SIXTH
+215A;215A;215A;0035 2044 0036;0035 2044 0036; # (⅚; ⅚; ⅚; 5⁄6; 5⁄6; ) VULGAR FRACTION FIVE SIXTHS
+215B;215B;215B;0031 2044 0038;0031 2044 0038; # (⅛; ⅛; ⅛; 1⁄8; 1⁄8; ) VULGAR FRACTION ONE EIGHTH
+215C;215C;215C;0033 2044 0038;0033 2044 0038; # (⅜; ⅜; ⅜; 3⁄8; 3⁄8; ) VULGAR FRACTION THREE EIGHTHS
+215D;215D;215D;0035 2044 0038;0035 2044 0038; # (⅝; ⅝; ⅝; 5⁄8; 5⁄8; ) VULGAR FRACTION FIVE EIGHTHS
+215E;215E;215E;0037 2044 0038;0037 2044 0038; # (⅞; ⅞; ⅞; 7⁄8; 7⁄8; ) VULGAR FRACTION SEVEN EIGHTHS
+215F;215F;215F;0031 2044;0031 2044; # (⅟; ⅟; ⅟; 1⁄; 1⁄; ) FRACTION NUMERATOR ONE
+2160;2160;2160;0049;0049; # (Ⅰ; Ⅰ; Ⅰ; I; I; ) ROMAN NUMERAL ONE
+2161;2161;2161;0049 0049;0049 0049; # (Ⅱ; Ⅱ; Ⅱ; II; II; ) ROMAN NUMERAL TWO
+2162;2162;2162;0049 0049 0049;0049 0049 0049; # (Ⅲ; Ⅲ; Ⅲ; III; III; ) ROMAN NUMERAL THREE
+2163;2163;2163;0049 0056;0049 0056; # (Ⅳ; Ⅳ; Ⅳ; IV; IV; ) ROMAN NUMERAL FOUR
+2164;2164;2164;0056;0056; # (Ⅴ; Ⅴ; Ⅴ; V; V; ) ROMAN NUMERAL FIVE
+2165;2165;2165;0056 0049;0056 0049; # (Ⅵ; Ⅵ; Ⅵ; VI; VI; ) ROMAN NUMERAL SIX
+2166;2166;2166;0056 0049 0049;0056 0049 0049; # (Ⅶ; Ⅶ; Ⅶ; VII; VII; ) ROMAN NUMERAL SEVEN
+2167;2167;2167;0056 0049 0049 0049;0056 0049 0049 0049; # (Ⅷ; Ⅷ; Ⅷ; VIII; VIII; ) ROMAN NUMERAL EIGHT
+2168;2168;2168;0049 0058;0049 0058; # (Ⅸ; Ⅸ; Ⅸ; IX; IX; ) ROMAN NUMERAL NINE
+2169;2169;2169;0058;0058; # (Ⅹ; Ⅹ; Ⅹ; X; X; ) ROMAN NUMERAL TEN
+216A;216A;216A;0058 0049;0058 0049; # (Ⅺ; Ⅺ; Ⅺ; XI; XI; ) ROMAN NUMERAL ELEVEN
+216B;216B;216B;0058 0049 0049;0058 0049 0049; # (Ⅻ; Ⅻ; Ⅻ; XII; XII; ) ROMAN NUMERAL TWELVE
+216C;216C;216C;004C;004C; # (Ⅼ; Ⅼ; Ⅼ; L; L; ) ROMAN NUMERAL FIFTY
+216D;216D;216D;0043;0043; # (Ⅽ; Ⅽ; Ⅽ; C; C; ) ROMAN NUMERAL ONE HUNDRED
+216E;216E;216E;0044;0044; # (Ⅾ; Ⅾ; Ⅾ; D; D; ) ROMAN NUMERAL FIVE HUNDRED
+216F;216F;216F;004D;004D; # (Ⅿ; Ⅿ; Ⅿ; M; M; ) ROMAN NUMERAL ONE THOUSAND
+2170;2170;2170;0069;0069; # (ⅰ; ⅰ; ⅰ; i; i; ) SMALL ROMAN NUMERAL ONE
+2171;2171;2171;0069 0069;0069 0069; # (ⅱ; ⅱ; ⅱ; ii; ii; ) SMALL ROMAN NUMERAL TWO
+2172;2172;2172;0069 0069 0069;0069 0069 0069; # (ⅲ; ⅲ; ⅲ; iii; iii; ) SMALL ROMAN NUMERAL THREE
+2173;2173;2173;0069 0076;0069 0076; # (ⅳ; ⅳ; ⅳ; iv; iv; ) SMALL ROMAN NUMERAL FOUR
+2174;2174;2174;0076;0076; # (ⅴ; ⅴ; ⅴ; v; v; ) SMALL ROMAN NUMERAL FIVE
+2175;2175;2175;0076 0069;0076 0069; # (ⅵ; ⅵ; ⅵ; vi; vi; ) SMALL ROMAN NUMERAL SIX
+2176;2176;2176;0076 0069 0069;0076 0069 0069; # (ⅶ; ⅶ; ⅶ; vii; vii; ) SMALL ROMAN NUMERAL SEVEN
+2177;2177;2177;0076 0069 0069 0069;0076 0069 0069 0069; # (ⅷ; ⅷ; ⅷ; viii; viii; ) SMALL ROMAN NUMERAL EIGHT
+2178;2178;2178;0069 0078;0069 0078; # (ⅸ; ⅸ; ⅸ; ix; ix; ) SMALL ROMAN NUMERAL NINE
+2179;2179;2179;0078;0078; # (ⅹ; ⅹ; ⅹ; x; x; ) SMALL ROMAN NUMERAL TEN
+217A;217A;217A;0078 0069;0078 0069; # (ⅺ; ⅺ; ⅺ; xi; xi; ) SMALL ROMAN NUMERAL ELEVEN
+217B;217B;217B;0078 0069 0069;0078 0069 0069; # (ⅻ; ⅻ; ⅻ; xii; xii; ) SMALL ROMAN NUMERAL TWELVE
+217C;217C;217C;006C;006C; # (ⅼ; ⅼ; ⅼ; l; l; ) SMALL ROMAN NUMERAL FIFTY
+217D;217D;217D;0063;0063; # (ⅽ; ⅽ; ⅽ; c; c; ) SMALL ROMAN NUMERAL ONE HUNDRED
+217E;217E;217E;0064;0064; # (ⅾ; ⅾ; ⅾ; d; d; ) SMALL ROMAN NUMERAL FIVE HUNDRED
+217F;217F;217F;006D;006D; # (ⅿ; ⅿ; ⅿ; m; m; ) SMALL ROMAN NUMERAL ONE THOUSAND
+2189;2189;2189;0030 2044 0033;0030 2044 0033; # (↉; ↉; ↉; 0⁄3; 0⁄3; ) VULGAR FRACTION ZERO THIRDS
+219A;219A;2190 0338;219A;2190 0338; # (↚; ↚; ←◌̸; ↚; ←◌̸; ) LEFTWARDS ARROW WITH STROKE
+219B;219B;2192 0338;219B;2192 0338; # (↛; ↛; →◌̸; ↛; →◌̸; ) RIGHTWARDS ARROW WITH STROKE
+21AE;21AE;2194 0338;21AE;2194 0338; # (↮; ↮; ↔◌̸; ↮; ↔◌̸; ) LEFT RIGHT ARROW WITH STROKE
+21CD;21CD;21D0 0338;21CD;21D0 0338; # (⇍; ⇍; ⇐◌̸; ⇍; ⇐◌̸; ) LEFTWARDS DOUBLE ARROW WITH STROKE
+21CE;21CE;21D4 0338;21CE;21D4 0338; # (⇎; ⇎; ⇔◌̸; ⇎; ⇔◌̸; ) LEFT RIGHT DOUBLE ARROW WITH STROKE
+21CF;21CF;21D2 0338;21CF;21D2 0338; # (⇏; ⇏; ⇒◌̸; ⇏; ⇒◌̸; ) RIGHTWARDS DOUBLE ARROW WITH STROKE
+2204;2204;2203 0338;2204;2203 0338; # (∄; ∄; ∃◌̸; ∄; ∃◌̸; ) THERE DOES NOT EXIST
+2209;2209;2208 0338;2209;2208 0338; # (∉; ∉; ∈◌̸; ∉; ∈◌̸; ) NOT AN ELEMENT OF
+220C;220C;220B 0338;220C;220B 0338; # (∌; ∌; ∋◌̸; ∌; ∋◌̸; ) DOES NOT CONTAIN AS MEMBER
+2224;2224;2223 0338;2224;2223 0338; # (∤; ∤; ∣◌̸; ∤; ∣◌̸; ) DOES NOT DIVIDE
+2226;2226;2225 0338;2226;2225 0338; # (∦; ∦; ∥◌̸; ∦; ∥◌̸; ) NOT PARALLEL TO
+222C;222C;222C;222B 222B;222B 222B; # (∬; ∬; ∬; ∫∫; ∫∫; ) DOUBLE INTEGRAL
+222D;222D;222D;222B 222B 222B;222B 222B 222B; # (∭; ∭; ∭; ∫∫∫; ∫∫∫; ) TRIPLE INTEGRAL
+222F;222F;222F;222E 222E;222E 222E; # (∯; ∯; ∯; ∮∮; ∮∮; ) SURFACE INTEGRAL
+2230;2230;2230;222E 222E 222E;222E 222E 222E; # (∰; ∰; ∰; ∮∮∮; ∮∮∮; ) VOLUME INTEGRAL
+2241;2241;223C 0338;2241;223C 0338; # (≁; ≁; ∼◌̸; ≁; ∼◌̸; ) NOT TILDE
+2244;2244;2243 0338;2244;2243 0338; # (≄; ≄; ≃◌̸; ≄; ≃◌̸; ) NOT ASYMPTOTICALLY EQUAL TO
+2247;2247;2245 0338;2247;2245 0338; # (≇; ≇; ≅◌̸; ≇; ≅◌̸; ) NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO
+2249;2249;2248 0338;2249;2248 0338; # (≉; ≉; ≈◌̸; ≉; ≈◌̸; ) NOT ALMOST EQUAL TO
+2260;2260;003D 0338;2260;003D 0338; # (≠; ≠; =◌̸; ≠; =◌̸; ) NOT EQUAL TO
+2262;2262;2261 0338;2262;2261 0338; # (≢; ≢; ≡◌̸; ≢; ≡◌̸; ) NOT IDENTICAL TO
+226D;226D;224D 0338;226D;224D 0338; # (≭; ≭; ≍◌̸; ≭; ≍◌̸; ) NOT EQUIVALENT TO
+226E;226E;003C 0338;226E;003C 0338; # (≮; ≮; <◌̸; ≮; <◌̸; ) NOT LESS-THAN
+226F;226F;003E 0338;226F;003E 0338; # (≯; ≯; >◌̸; ≯; >◌̸; ) NOT GREATER-THAN
+2270;2270;2264 0338;2270;2264 0338; # (≰; ≰; ≤◌̸; ≰; ≤◌̸; ) NEITHER LESS-THAN NOR EQUAL TO
+2271;2271;2265 0338;2271;2265 0338; # (≱; ≱; ≥◌̸; ≱; ≥◌̸; ) NEITHER GREATER-THAN NOR EQUAL TO
+2274;2274;2272 0338;2274;2272 0338; # (≴; ≴; ≲◌̸; ≴; ≲◌̸; ) NEITHER LESS-THAN NOR EQUIVALENT TO
+2275;2275;2273 0338;2275;2273 0338; # (≵; ≵; ≳◌̸; ≵; ≳◌̸; ) NEITHER GREATER-THAN NOR EQUIVALENT TO
+2278;2278;2276 0338;2278;2276 0338; # (≸; ≸; ≶◌̸; ≸; ≶◌̸; ) NEITHER LESS-THAN NOR GREATER-THAN
+2279;2279;2277 0338;2279;2277 0338; # (≹; ≹; ≷◌̸; ≹; ≷◌̸; ) NEITHER GREATER-THAN NOR LESS-THAN
+2280;2280;227A 0338;2280;227A 0338; # (⊀; ⊀; ≺◌̸; ⊀; ≺◌̸; ) DOES NOT PRECEDE
+2281;2281;227B 0338;2281;227B 0338; # (⊁; ⊁; ≻◌̸; ⊁; ≻◌̸; ) DOES NOT SUCCEED
+2284;2284;2282 0338;2284;2282 0338; # (⊄; ⊄; ⊂◌̸; ⊄; ⊂◌̸; ) NOT A SUBSET OF
+2285;2285;2283 0338;2285;2283 0338; # (⊅; ⊅; ⊃◌̸; ⊅; ⊃◌̸; ) NOT A SUPERSET OF
+2288;2288;2286 0338;2288;2286 0338; # (⊈; ⊈; ⊆◌̸; ⊈; ⊆◌̸; ) NEITHER A SUBSET OF NOR EQUAL TO
+2289;2289;2287 0338;2289;2287 0338; # (⊉; ⊉; ⊇◌̸; ⊉; ⊇◌̸; ) NEITHER A SUPERSET OF NOR EQUAL TO
+22AC;22AC;22A2 0338;22AC;22A2 0338; # (⊬; ⊬; ⊢◌̸; ⊬; ⊢◌̸; ) DOES NOT PROVE
+22AD;22AD;22A8 0338;22AD;22A8 0338; # (⊭; ⊭; ⊨◌̸; ⊭; ⊨◌̸; ) NOT TRUE
+22AE;22AE;22A9 0338;22AE;22A9 0338; # (⊮; ⊮; ⊩◌̸; ⊮; ⊩◌̸; ) DOES NOT FORCE
+22AF;22AF;22AB 0338;22AF;22AB 0338; # (⊯; ⊯; ⊫◌̸; ⊯; ⊫◌̸; ) NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
+22E0;22E0;227C 0338;22E0;227C 0338; # (⋠; ⋠; ≼◌̸; ⋠; ≼◌̸; ) DOES NOT PRECEDE OR EQUAL
+22E1;22E1;227D 0338;22E1;227D 0338; # (⋡; ⋡; ≽◌̸; ⋡; ≽◌̸; ) DOES NOT SUCCEED OR EQUAL
+22E2;22E2;2291 0338;22E2;2291 0338; # (⋢; ⋢; ⊑◌̸; ⋢; ⊑◌̸; ) NOT SQUARE IMAGE OF OR EQUAL TO
+22E3;22E3;2292 0338;22E3;2292 0338; # (⋣; ⋣; ⊒◌̸; ⋣; ⊒◌̸; ) NOT SQUARE ORIGINAL OF OR EQUAL TO
+22EA;22EA;22B2 0338;22EA;22B2 0338; # (⋪; ⋪; ⊲◌̸; ⋪; ⊲◌̸; ) NOT NORMAL SUBGROUP OF
+22EB;22EB;22B3 0338;22EB;22B3 0338; # (⋫; ⋫; ⊳◌̸; ⋫; ⊳◌̸; ) DOES NOT CONTAIN AS NORMAL SUBGROUP
+22EC;22EC;22B4 0338;22EC;22B4 0338; # (⋬; ⋬; ⊴◌̸; ⋬; ⊴◌̸; ) NOT NORMAL SUBGROUP OF OR EQUAL TO
+22ED;22ED;22B5 0338;22ED;22B5 0338; # (⋭; ⋭; ⊵◌̸; ⋭; ⊵◌̸; ) DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL
+2329;3008;3008;3008;3008; # (〈; 〈; 〈; 〈; 〈; ) LEFT-POINTING ANGLE BRACKET
+232A;3009;3009;3009;3009; # (〉; 〉; 〉; 〉; 〉; ) RIGHT-POINTING ANGLE BRACKET
+2460;2460;2460;0031;0031; # (①; ①; ①; 1; 1; ) CIRCLED DIGIT ONE
+2461;2461;2461;0032;0032; # (②; ②; ②; 2; 2; ) CIRCLED DIGIT TWO
+2462;2462;2462;0033;0033; # (③; ③; ③; 3; 3; ) CIRCLED DIGIT THREE
+2463;2463;2463;0034;0034; # (④; ④; ④; 4; 4; ) CIRCLED DIGIT FOUR
+2464;2464;2464;0035;0035; # (⑤; ⑤; ⑤; 5; 5; ) CIRCLED DIGIT FIVE
+2465;2465;2465;0036;0036; # (⑥; ⑥; ⑥; 6; 6; ) CIRCLED DIGIT SIX
+2466;2466;2466;0037;0037; # (⑦; ⑦; ⑦; 7; 7; ) CIRCLED DIGIT SEVEN
+2467;2467;2467;0038;0038; # (⑧; ⑧; ⑧; 8; 8; ) CIRCLED DIGIT EIGHT
+2468;2468;2468;0039;0039; # (⑨; ⑨; ⑨; 9; 9; ) CIRCLED DIGIT NINE
+2469;2469;2469;0031 0030;0031 0030; # (⑩; ⑩; ⑩; 10; 10; ) CIRCLED NUMBER TEN
+246A;246A;246A;0031 0031;0031 0031; # (⑪; ⑪; ⑪; 11; 11; ) CIRCLED NUMBER ELEVEN
+246B;246B;246B;0031 0032;0031 0032; # (⑫; ⑫; ⑫; 12; 12; ) CIRCLED NUMBER TWELVE
+246C;246C;246C;0031 0033;0031 0033; # (⑬; ⑬; ⑬; 13; 13; ) CIRCLED NUMBER THIRTEEN
+246D;246D;246D;0031 0034;0031 0034; # (⑭; ⑭; ⑭; 14; 14; ) CIRCLED NUMBER FOURTEEN
+246E;246E;246E;0031 0035;0031 0035; # (⑮; ⑮; ⑮; 15; 15; ) CIRCLED NUMBER FIFTEEN
+246F;246F;246F;0031 0036;0031 0036; # (⑯; ⑯; ⑯; 16; 16; ) CIRCLED NUMBER SIXTEEN
+2470;2470;2470;0031 0037;0031 0037; # (⑰; ⑰; ⑰; 17; 17; ) CIRCLED NUMBER SEVENTEEN
+2471;2471;2471;0031 0038;0031 0038; # (⑱; ⑱; ⑱; 18; 18; ) CIRCLED NUMBER EIGHTEEN
+2472;2472;2472;0031 0039;0031 0039; # (⑲; ⑲; ⑲; 19; 19; ) CIRCLED NUMBER NINETEEN
+2473;2473;2473;0032 0030;0032 0030; # (⑳; ⑳; ⑳; 20; 20; ) CIRCLED NUMBER TWENTY
+2474;2474;2474;0028 0031 0029;0028 0031 0029; # (⑴; ⑴; ⑴; (1); (1); ) PARENTHESIZED DIGIT ONE
+2475;2475;2475;0028 0032 0029;0028 0032 0029; # (⑵; ⑵; ⑵; (2); (2); ) PARENTHESIZED DIGIT TWO
+2476;2476;2476;0028 0033 0029;0028 0033 0029; # (⑶; ⑶; ⑶; (3); (3); ) PARENTHESIZED DIGIT THREE
+2477;2477;2477;0028 0034 0029;0028 0034 0029; # (⑷; ⑷; ⑷; (4); (4); ) PARENTHESIZED DIGIT FOUR
+2478;2478;2478;0028 0035 0029;0028 0035 0029; # (⑸; ⑸; ⑸; (5); (5); ) PARENTHESIZED DIGIT FIVE
+2479;2479;2479;0028 0036 0029;0028 0036 0029; # (⑹; ⑹; ⑹; (6); (6); ) PARENTHESIZED DIGIT SIX
+247A;247A;247A;0028 0037 0029;0028 0037 0029; # (⑺; ⑺; ⑺; (7); (7); ) PARENTHESIZED DIGIT SEVEN
+247B;247B;247B;0028 0038 0029;0028 0038 0029; # (⑻; ⑻; ⑻; (8); (8); ) PARENTHESIZED DIGIT EIGHT
+247C;247C;247C;0028 0039 0029;0028 0039 0029; # (⑼; ⑼; ⑼; (9); (9); ) PARENTHESIZED DIGIT NINE
+247D;247D;247D;0028 0031 0030 0029;0028 0031 0030 0029; # (⑽; ⑽; ⑽; (10); (10); ) PARENTHESIZED NUMBER TEN
+247E;247E;247E;0028 0031 0031 0029;0028 0031 0031 0029; # (⑾; ⑾; ⑾; (11); (11); ) PARENTHESIZED NUMBER ELEVEN
+247F;247F;247F;0028 0031 0032 0029;0028 0031 0032 0029; # (⑿; ⑿; ⑿; (12); (12); ) PARENTHESIZED NUMBER TWELVE
+2480;2480;2480;0028 0031 0033 0029;0028 0031 0033 0029; # (⒀; ⒀; ⒀; (13); (13); ) PARENTHESIZED NUMBER THIRTEEN
+2481;2481;2481;0028 0031 0034 0029;0028 0031 0034 0029; # (⒁; ⒁; ⒁; (14); (14); ) PARENTHESIZED NUMBER FOURTEEN
+2482;2482;2482;0028 0031 0035 0029;0028 0031 0035 0029; # (⒂; ⒂; ⒂; (15); (15); ) PARENTHESIZED NUMBER FIFTEEN
+2483;2483;2483;0028 0031 0036 0029;0028 0031 0036 0029; # (⒃; ⒃; ⒃; (16); (16); ) PARENTHESIZED NUMBER SIXTEEN
+2484;2484;2484;0028 0031 0037 0029;0028 0031 0037 0029; # (⒄; ⒄; ⒄; (17); (17); ) PARENTHESIZED NUMBER SEVENTEEN
+2485;2485;2485;0028 0031 0038 0029;0028 0031 0038 0029; # (⒅; ⒅; ⒅; (18); (18); ) PARENTHESIZED NUMBER EIGHTEEN
+2486;2486;2486;0028 0031 0039 0029;0028 0031 0039 0029; # (⒆; ⒆; ⒆; (19); (19); ) PARENTHESIZED NUMBER NINETEEN
+2487;2487;2487;0028 0032 0030 0029;0028 0032 0030 0029; # (⒇; ⒇; ⒇; (20); (20); ) PARENTHESIZED NUMBER TWENTY
+2488;2488;2488;0031 002E;0031 002E; # (⒈; ⒈; ⒈; 1.; 1.; ) DIGIT ONE FULL STOP
+2489;2489;2489;0032 002E;0032 002E; # (⒉; ⒉; ⒉; 2.; 2.; ) DIGIT TWO FULL STOP
+248A;248A;248A;0033 002E;0033 002E; # (⒊; ⒊; ⒊; 3.; 3.; ) DIGIT THREE FULL STOP
+248B;248B;248B;0034 002E;0034 002E; # (⒋; ⒋; ⒋; 4.; 4.; ) DIGIT FOUR FULL STOP
+248C;248C;248C;0035 002E;0035 002E; # (⒌; ⒌; ⒌; 5.; 5.; ) DIGIT FIVE FULL STOP
+248D;248D;248D;0036 002E;0036 002E; # (⒍; ⒍; ⒍; 6.; 6.; ) DIGIT SIX FULL STOP
+248E;248E;248E;0037 002E;0037 002E; # (⒎; ⒎; ⒎; 7.; 7.; ) DIGIT SEVEN FULL STOP
+248F;248F;248F;0038 002E;0038 002E; # (⒏; ⒏; ⒏; 8.; 8.; ) DIGIT EIGHT FULL STOP
+2490;2490;2490;0039 002E;0039 002E; # (⒐; ⒐; ⒐; 9.; 9.; ) DIGIT NINE FULL STOP
+2491;2491;2491;0031 0030 002E;0031 0030 002E; # (⒑; ⒑; ⒑; 10.; 10.; ) NUMBER TEN FULL STOP
+2492;2492;2492;0031 0031 002E;0031 0031 002E; # (⒒; ⒒; ⒒; 11.; 11.; ) NUMBER ELEVEN FULL STOP
+2493;2493;2493;0031 0032 002E;0031 0032 002E; # (⒓; ⒓; ⒓; 12.; 12.; ) NUMBER TWELVE FULL STOP
+2494;2494;2494;0031 0033 002E;0031 0033 002E; # (⒔; ⒔; ⒔; 13.; 13.; ) NUMBER THIRTEEN FULL STOP
+2495;2495;2495;0031 0034 002E;0031 0034 002E; # (⒕; ⒕; ⒕; 14.; 14.; ) NUMBER FOURTEEN FULL STOP
+2496;2496;2496;0031 0035 002E;0031 0035 002E; # (⒖; ⒖; ⒖; 15.; 15.; ) NUMBER FIFTEEN FULL STOP
+2497;2497;2497;0031 0036 002E;0031 0036 002E; # (⒗; ⒗; ⒗; 16.; 16.; ) NUMBER SIXTEEN FULL STOP
+2498;2498;2498;0031 0037 002E;0031 0037 002E; # (⒘; ⒘; ⒘; 17.; 17.; ) NUMBER SEVENTEEN FULL STOP
+2499;2499;2499;0031 0038 002E;0031 0038 002E; # (⒙; ⒙; ⒙; 18.; 18.; ) NUMBER EIGHTEEN FULL STOP
+249A;249A;249A;0031 0039 002E;0031 0039 002E; # (⒚; ⒚; ⒚; 19.; 19.; ) NUMBER NINETEEN FULL STOP
+249B;249B;249B;0032 0030 002E;0032 0030 002E; # (⒛; ⒛; ⒛; 20.; 20.; ) NUMBER TWENTY FULL STOP
+249C;249C;249C;0028 0061 0029;0028 0061 0029; # (⒜; ⒜; ⒜; (a); (a); ) PARENTHESIZED LATIN SMALL LETTER A
+249D;249D;249D;0028 0062 0029;0028 0062 0029; # (⒝; ⒝; ⒝; (b); (b); ) PARENTHESIZED LATIN SMALL LETTER B
+249E;249E;249E;0028 0063 0029;0028 0063 0029; # (⒞; ⒞; ⒞; (c); (c); ) PARENTHESIZED LATIN SMALL LETTER C
+249F;249F;249F;0028 0064 0029;0028 0064 0029; # (⒟; ⒟; ⒟; (d); (d); ) PARENTHESIZED LATIN SMALL LETTER D
+24A0;24A0;24A0;0028 0065 0029;0028 0065 0029; # (⒠; ⒠; ⒠; (e); (e); ) PARENTHESIZED LATIN SMALL LETTER E
+24A1;24A1;24A1;0028 0066 0029;0028 0066 0029; # (⒡; ⒡; ⒡; (f); (f); ) PARENTHESIZED LATIN SMALL LETTER F
+24A2;24A2;24A2;0028 0067 0029;0028 0067 0029; # (⒢; ⒢; ⒢; (g); (g); ) PARENTHESIZED LATIN SMALL LETTER G
+24A3;24A3;24A3;0028 0068 0029;0028 0068 0029; # (⒣; ⒣; ⒣; (h); (h); ) PARENTHESIZED LATIN SMALL LETTER H
+24A4;24A4;24A4;0028 0069 0029;0028 0069 0029; # (⒤; ⒤; ⒤; (i); (i); ) PARENTHESIZED LATIN SMALL LETTER I
+24A5;24A5;24A5;0028 006A 0029;0028 006A 0029; # (⒥; ⒥; ⒥; (j); (j); ) PARENTHESIZED LATIN SMALL LETTER J
+24A6;24A6;24A6;0028 006B 0029;0028 006B 0029; # (⒦; ⒦; ⒦; (k); (k); ) PARENTHESIZED LATIN SMALL LETTER K
+24A7;24A7;24A7;0028 006C 0029;0028 006C 0029; # (⒧; ⒧; ⒧; (l); (l); ) PARENTHESIZED LATIN SMALL LETTER L
+24A8;24A8;24A8;0028 006D 0029;0028 006D 0029; # (⒨; ⒨; ⒨; (m); (m); ) PARENTHESIZED LATIN SMALL LETTER M
+24A9;24A9;24A9;0028 006E 0029;0028 006E 0029; # (⒩; ⒩; ⒩; (n); (n); ) PARENTHESIZED LATIN SMALL LETTER N
+24AA;24AA;24AA;0028 006F 0029;0028 006F 0029; # (⒪; ⒪; ⒪; (o); (o); ) PARENTHESIZED LATIN SMALL LETTER O
+24AB;24AB;24AB;0028 0070 0029;0028 0070 0029; # (⒫; ⒫; ⒫; (p); (p); ) PARENTHESIZED LATIN SMALL LETTER P
+24AC;24AC;24AC;0028 0071 0029;0028 0071 0029; # (⒬; ⒬; ⒬; (q); (q); ) PARENTHESIZED LATIN SMALL LETTER Q
+24AD;24AD;24AD;0028 0072 0029;0028 0072 0029; # (⒭; ⒭; ⒭; (r); (r); ) PARENTHESIZED LATIN SMALL LETTER R
+24AE;24AE;24AE;0028 0073 0029;0028 0073 0029; # (⒮; ⒮; ⒮; (s); (s); ) PARENTHESIZED LATIN SMALL LETTER S
+24AF;24AF;24AF;0028 0074 0029;0028 0074 0029; # (⒯; ⒯; ⒯; (t); (t); ) PARENTHESIZED LATIN SMALL LETTER T
+24B0;24B0;24B0;0028 0075 0029;0028 0075 0029; # (⒰; ⒰; ⒰; (u); (u); ) PARENTHESIZED LATIN SMALL LETTER U
+24B1;24B1;24B1;0028 0076 0029;0028 0076 0029; # (⒱; ⒱; ⒱; (v); (v); ) PARENTHESIZED LATIN SMALL LETTER V
+24B2;24B2;24B2;0028 0077 0029;0028 0077 0029; # (⒲; ⒲; ⒲; (w); (w); ) PARENTHESIZED LATIN SMALL LETTER W
+24B3;24B3;24B3;0028 0078 0029;0028 0078 0029; # (⒳; ⒳; ⒳; (x); (x); ) PARENTHESIZED LATIN SMALL LETTER X
+24B4;24B4;24B4;0028 0079 0029;0028 0079 0029; # (⒴; ⒴; ⒴; (y); (y); ) PARENTHESIZED LATIN SMALL LETTER Y
+24B5;24B5;24B5;0028 007A 0029;0028 007A 0029; # (⒵; ⒵; ⒵; (z); (z); ) PARENTHESIZED LATIN SMALL LETTER Z
+24B6;24B6;24B6;0041;0041; # (Ⓐ; Ⓐ; Ⓐ; A; A; ) CIRCLED LATIN CAPITAL LETTER A
+24B7;24B7;24B7;0042;0042; # (Ⓑ; Ⓑ; Ⓑ; B; B; ) CIRCLED LATIN CAPITAL LETTER B
+24B8;24B8;24B8;0043;0043; # (Ⓒ; Ⓒ; Ⓒ; C; C; ) CIRCLED LATIN CAPITAL LETTER C
+24B9;24B9;24B9;0044;0044; # (Ⓓ; Ⓓ; Ⓓ; D; D; ) CIRCLED LATIN CAPITAL LETTER D
+24BA;24BA;24BA;0045;0045; # (Ⓔ; Ⓔ; Ⓔ; E; E; ) CIRCLED LATIN CAPITAL LETTER E
+24BB;24BB;24BB;0046;0046; # (Ⓕ; Ⓕ; Ⓕ; F; F; ) CIRCLED LATIN CAPITAL LETTER F
+24BC;24BC;24BC;0047;0047; # (Ⓖ; Ⓖ; Ⓖ; G; G; ) CIRCLED LATIN CAPITAL LETTER G
+24BD;24BD;24BD;0048;0048; # (Ⓗ; Ⓗ; Ⓗ; H; H; ) CIRCLED LATIN CAPITAL LETTER H
+24BE;24BE;24BE;0049;0049; # (Ⓘ; Ⓘ; Ⓘ; I; I; ) CIRCLED LATIN CAPITAL LETTER I
+24BF;24BF;24BF;004A;004A; # (Ⓙ; Ⓙ; Ⓙ; J; J; ) CIRCLED LATIN CAPITAL LETTER J
+24C0;24C0;24C0;004B;004B; # (Ⓚ; Ⓚ; Ⓚ; K; K; ) CIRCLED LATIN CAPITAL LETTER K
+24C1;24C1;24C1;004C;004C; # (Ⓛ; Ⓛ; Ⓛ; L; L; ) CIRCLED LATIN CAPITAL LETTER L
+24C2;24C2;24C2;004D;004D; # (Ⓜ; Ⓜ; Ⓜ; M; M; ) CIRCLED LATIN CAPITAL LETTER M
+24C3;24C3;24C3;004E;004E; # (Ⓝ; Ⓝ; Ⓝ; N; N; ) CIRCLED LATIN CAPITAL LETTER N
+24C4;24C4;24C4;004F;004F; # (Ⓞ; Ⓞ; Ⓞ; O; O; ) CIRCLED LATIN CAPITAL LETTER O
+24C5;24C5;24C5;0050;0050; # (Ⓟ; Ⓟ; Ⓟ; P; P; ) CIRCLED LATIN CAPITAL LETTER P
+24C6;24C6;24C6;0051;0051; # (Ⓠ; Ⓠ; Ⓠ; Q; Q; ) CIRCLED LATIN CAPITAL LETTER Q
+24C7;24C7;24C7;0052;0052; # (Ⓡ; Ⓡ; Ⓡ; R; R; ) CIRCLED LATIN CAPITAL LETTER R
+24C8;24C8;24C8;0053;0053; # (Ⓢ; Ⓢ; Ⓢ; S; S; ) CIRCLED LATIN CAPITAL LETTER S
+24C9;24C9;24C9;0054;0054; # (Ⓣ; Ⓣ; Ⓣ; T; T; ) CIRCLED LATIN CAPITAL LETTER T
+24CA;24CA;24CA;0055;0055; # (Ⓤ; Ⓤ; Ⓤ; U; U; ) CIRCLED LATIN CAPITAL LETTER U
+24CB;24CB;24CB;0056;0056; # (Ⓥ; Ⓥ; Ⓥ; V; V; ) CIRCLED LATIN CAPITAL LETTER V
+24CC;24CC;24CC;0057;0057; # (Ⓦ; Ⓦ; Ⓦ; W; W; ) CIRCLED LATIN CAPITAL LETTER W
+24CD;24CD;24CD;0058;0058; # (Ⓧ; Ⓧ; Ⓧ; X; X; ) CIRCLED LATIN CAPITAL LETTER X
+24CE;24CE;24CE;0059;0059; # (Ⓨ; Ⓨ; Ⓨ; Y; Y; ) CIRCLED LATIN CAPITAL LETTER Y
+24CF;24CF;24CF;005A;005A; # (Ⓩ; Ⓩ; Ⓩ; Z; Z; ) CIRCLED LATIN CAPITAL LETTER Z
+24D0;24D0;24D0;0061;0061; # (ⓐ; ⓐ; ⓐ; a; a; ) CIRCLED LATIN SMALL LETTER A
+24D1;24D1;24D1;0062;0062; # (ⓑ; ⓑ; ⓑ; b; b; ) CIRCLED LATIN SMALL LETTER B
+24D2;24D2;24D2;0063;0063; # (ⓒ; ⓒ; ⓒ; c; c; ) CIRCLED LATIN SMALL LETTER C
+24D3;24D3;24D3;0064;0064; # (ⓓ; ⓓ; ⓓ; d; d; ) CIRCLED LATIN SMALL LETTER D
+24D4;24D4;24D4;0065;0065; # (ⓔ; ⓔ; ⓔ; e; e; ) CIRCLED LATIN SMALL LETTER E
+24D5;24D5;24D5;0066;0066; # (ⓕ; ⓕ; ⓕ; f; f; ) CIRCLED LATIN SMALL LETTER F
+24D6;24D6;24D6;0067;0067; # (ⓖ; ⓖ; ⓖ; g; g; ) CIRCLED LATIN SMALL LETTER G
+24D7;24D7;24D7;0068;0068; # (ⓗ; ⓗ; ⓗ; h; h; ) CIRCLED LATIN SMALL LETTER H
+24D8;24D8;24D8;0069;0069; # (ⓘ; ⓘ; ⓘ; i; i; ) CIRCLED LATIN SMALL LETTER I
+24D9;24D9;24D9;006A;006A; # (ⓙ; ⓙ; ⓙ; j; j; ) CIRCLED LATIN SMALL LETTER J
+24DA;24DA;24DA;006B;006B; # (ⓚ; ⓚ; ⓚ; k; k; ) CIRCLED LATIN SMALL LETTER K
+24DB;24DB;24DB;006C;006C; # (ⓛ; ⓛ; ⓛ; l; l; ) CIRCLED LATIN SMALL LETTER L
+24DC;24DC;24DC;006D;006D; # (ⓜ; ⓜ; ⓜ; m; m; ) CIRCLED LATIN SMALL LETTER M
+24DD;24DD;24DD;006E;006E; # (ⓝ; ⓝ; ⓝ; n; n; ) CIRCLED LATIN SMALL LETTER N
+24DE;24DE;24DE;006F;006F; # (ⓞ; ⓞ; ⓞ; o; o; ) CIRCLED LATIN SMALL LETTER O
+24DF;24DF;24DF;0070;0070; # (ⓟ; ⓟ; ⓟ; p; p; ) CIRCLED LATIN SMALL LETTER P
+24E0;24E0;24E0;0071;0071; # (ⓠ; ⓠ; ⓠ; q; q; ) CIRCLED LATIN SMALL LETTER Q
+24E1;24E1;24E1;0072;0072; # (ⓡ; ⓡ; ⓡ; r; r; ) CIRCLED LATIN SMALL LETTER R
+24E2;24E2;24E2;0073;0073; # (ⓢ; ⓢ; ⓢ; s; s; ) CIRCLED LATIN SMALL LETTER S
+24E3;24E3;24E3;0074;0074; # (ⓣ; ⓣ; ⓣ; t; t; ) CIRCLED LATIN SMALL LETTER T
+24E4;24E4;24E4;0075;0075; # (ⓤ; ⓤ; ⓤ; u; u; ) CIRCLED LATIN SMALL LETTER U
+24E5;24E5;24E5;0076;0076; # (ⓥ; ⓥ; ⓥ; v; v; ) CIRCLED LATIN SMALL LETTER V
+24E6;24E6;24E6;0077;0077; # (ⓦ; ⓦ; ⓦ; w; w; ) CIRCLED LATIN SMALL LETTER W
+24E7;24E7;24E7;0078;0078; # (ⓧ; ⓧ; ⓧ; x; x; ) CIRCLED LATIN SMALL LETTER X
+24E8;24E8;24E8;0079;0079; # (ⓨ; ⓨ; ⓨ; y; y; ) CIRCLED LATIN SMALL LETTER Y
+24E9;24E9;24E9;007A;007A; # (ⓩ; ⓩ; ⓩ; z; z; ) CIRCLED LATIN SMALL LETTER Z
+24EA;24EA;24EA;0030;0030; # (⓪; ⓪; ⓪; 0; 0; ) CIRCLED DIGIT ZERO
+2A0C;2A0C;2A0C;222B 222B 222B 222B;222B 222B 222B 222B; # (⨌; ⨌; ⨌; ∫∫∫∫; ∫∫∫∫; ) QUADRUPLE INTEGRAL OPERATOR
+2A74;2A74;2A74;003A 003A 003D;003A 003A 003D; # (⩴; ⩴; ⩴; ::=; ::=; ) DOUBLE COLON EQUAL
+2A75;2A75;2A75;003D 003D;003D 003D; # (⩵; ⩵; ⩵; ==; ==; ) TWO CONSECUTIVE EQUALS SIGNS
+2A76;2A76;2A76;003D 003D 003D;003D 003D 003D; # (⩶; ⩶; ⩶; ===; ===; ) THREE CONSECUTIVE EQUALS SIGNS
+2ADC;2ADD 0338;2ADD 0338;2ADD 0338;2ADD 0338; # (⫝̸; ⫝◌̸; ⫝◌̸; ⫝◌̸; ⫝◌̸; ) FORKING
+2C7C;2C7C;2C7C;006A;006A; # (ⱼ; ⱼ; ⱼ; j; j; ) LATIN SUBSCRIPT SMALL LETTER J
+2C7D;2C7D;2C7D;0056;0056; # (ⱽ; ⱽ; ⱽ; V; V; ) MODIFIER LETTER CAPITAL V
+2D6F;2D6F;2D6F;2D61;2D61; # (ⵯ; ⵯ; ⵯ; ⵡ; ⵡ; ) TIFINAGH MODIFIER LETTER LABIALIZATION MARK
+2E9F;2E9F;2E9F;6BCD;6BCD; # (⺟; ⺟; ⺟; 母; 母; ) CJK RADICAL MOTHER
+2EF3;2EF3;2EF3;9F9F;9F9F; # (⻳; ⻳; ⻳; 龟; 龟; ) CJK RADICAL C-SIMPLIFIED TURTLE
+2F00;2F00;2F00;4E00;4E00; # (⼀; ⼀; ⼀; 一; 一; ) KANGXI RADICAL ONE
+2F01;2F01;2F01;4E28;4E28; # (⼁; ⼁; ⼁; 丨; 丨; ) KANGXI RADICAL LINE
+2F02;2F02;2F02;4E36;4E36; # (⼂; ⼂; ⼂; 丶; 丶; ) KANGXI RADICAL DOT
+2F03;2F03;2F03;4E3F;4E3F; # (⼃; ⼃; ⼃; 丿; 丿; ) KANGXI RADICAL SLASH
+2F04;2F04;2F04;4E59;4E59; # (⼄; ⼄; ⼄; 乙; 乙; ) KANGXI RADICAL SECOND
+2F05;2F05;2F05;4E85;4E85; # (⼅; ⼅; ⼅; 亅; 亅; ) KANGXI RADICAL HOOK
+2F06;2F06;2F06;4E8C;4E8C; # (⼆; ⼆; ⼆; 二; 二; ) KANGXI RADICAL TWO
+2F07;2F07;2F07;4EA0;4EA0; # (⼇; ⼇; ⼇; 亠; 亠; ) KANGXI RADICAL LID
+2F08;2F08;2F08;4EBA;4EBA; # (⼈; ⼈; ⼈; 人; 人; ) KANGXI RADICAL MAN
+2F09;2F09;2F09;513F;513F; # (⼉; ⼉; ⼉; 儿; 儿; ) KANGXI RADICAL LEGS
+2F0A;2F0A;2F0A;5165;5165; # (⼊; ⼊; ⼊; 入; 入; ) KANGXI RADICAL ENTER
+2F0B;2F0B;2F0B;516B;516B; # (⼋; ⼋; ⼋; 八; 八; ) KANGXI RADICAL EIGHT
+2F0C;2F0C;2F0C;5182;5182; # (⼌; ⼌; ⼌; 冂; 冂; ) KANGXI RADICAL DOWN BOX
+2F0D;2F0D;2F0D;5196;5196; # (⼍; ⼍; ⼍; 冖; 冖; ) KANGXI RADICAL COVER
+2F0E;2F0E;2F0E;51AB;51AB; # (⼎; ⼎; ⼎; 冫; 冫; ) KANGXI RADICAL ICE
+2F0F;2F0F;2F0F;51E0;51E0; # (⼏; ⼏; ⼏; 几; 几; ) KANGXI RADICAL TABLE
+2F10;2F10;2F10;51F5;51F5; # (⼐; ⼐; ⼐; 凵; 凵; ) KANGXI RADICAL OPEN BOX
+2F11;2F11;2F11;5200;5200; # (⼑; ⼑; ⼑; 刀; 刀; ) KANGXI RADICAL KNIFE
+2F12;2F12;2F12;529B;529B; # (⼒; ⼒; ⼒; 力; 力; ) KANGXI RADICAL POWER
+2F13;2F13;2F13;52F9;52F9; # (⼓; ⼓; ⼓; 勹; 勹; ) KANGXI RADICAL WRAP
+2F14;2F14;2F14;5315;5315; # (⼔; ⼔; ⼔; 匕; 匕; ) KANGXI RADICAL SPOON
+2F15;2F15;2F15;531A;531A; # (⼕; ⼕; ⼕; 匚; 匚; ) KANGXI RADICAL RIGHT OPEN BOX
+2F16;2F16;2F16;5338;5338; # (⼖; ⼖; ⼖; 匸; 匸; ) KANGXI RADICAL HIDING ENCLOSURE
+2F17;2F17;2F17;5341;5341; # (⼗; ⼗; ⼗; 十; 十; ) KANGXI RADICAL TEN
+2F18;2F18;2F18;535C;535C; # (⼘; ⼘; ⼘; 卜; 卜; ) KANGXI RADICAL DIVINATION
+2F19;2F19;2F19;5369;5369; # (⼙; ⼙; ⼙; 卩; 卩; ) KANGXI RADICAL SEAL
+2F1A;2F1A;2F1A;5382;5382; # (⼚; ⼚; ⼚; 厂; 厂; ) KANGXI RADICAL CLIFF
+2F1B;2F1B;2F1B;53B6;53B6; # (⼛; ⼛; ⼛; 厶; 厶; ) KANGXI RADICAL PRIVATE
+2F1C;2F1C;2F1C;53C8;53C8; # (⼜; ⼜; ⼜; 又; 又; ) KANGXI RADICAL AGAIN
+2F1D;2F1D;2F1D;53E3;53E3; # (⼝; ⼝; ⼝; 口; 口; ) KANGXI RADICAL MOUTH
+2F1E;2F1E;2F1E;56D7;56D7; # (⼞; ⼞; ⼞; 囗; 囗; ) KANGXI RADICAL ENCLOSURE
+2F1F;2F1F;2F1F;571F;571F; # (⼟; ⼟; ⼟; 土; 土; ) KANGXI RADICAL EARTH
+2F20;2F20;2F20;58EB;58EB; # (⼠; ⼠; ⼠; 士; 士; ) KANGXI RADICAL SCHOLAR
+2F21;2F21;2F21;5902;5902; # (⼡; ⼡; ⼡; 夂; 夂; ) KANGXI RADICAL GO
+2F22;2F22;2F22;590A;590A; # (⼢; ⼢; ⼢; 夊; 夊; ) KANGXI RADICAL GO SLOWLY
+2F23;2F23;2F23;5915;5915; # (⼣; ⼣; ⼣; 夕; 夕; ) KANGXI RADICAL EVENING
+2F24;2F24;2F24;5927;5927; # (⼤; ⼤; ⼤; 大; 大; ) KANGXI RADICAL BIG
+2F25;2F25;2F25;5973;5973; # (⼥; ⼥; ⼥; 女; 女; ) KANGXI RADICAL WOMAN
+2F26;2F26;2F26;5B50;5B50; # (⼦; ⼦; ⼦; 子; 子; ) KANGXI RADICAL CHILD
+2F27;2F27;2F27;5B80;5B80; # (⼧; ⼧; ⼧; 宀; 宀; ) KANGXI RADICAL ROOF
+2F28;2F28;2F28;5BF8;5BF8; # (⼨; ⼨; ⼨; 寸; 寸; ) KANGXI RADICAL INCH
+2F29;2F29;2F29;5C0F;5C0F; # (⼩; ⼩; ⼩; 小; 小; ) KANGXI RADICAL SMALL
+2F2A;2F2A;2F2A;5C22;5C22; # (⼪; ⼪; ⼪; 尢; 尢; ) KANGXI RADICAL LAME
+2F2B;2F2B;2F2B;5C38;5C38; # (⼫; ⼫; ⼫; 尸; 尸; ) KANGXI RADICAL CORPSE
+2F2C;2F2C;2F2C;5C6E;5C6E; # (⼬; ⼬; ⼬; 屮; 屮; ) KANGXI RADICAL SPROUT
+2F2D;2F2D;2F2D;5C71;5C71; # (⼭; ⼭; ⼭; 山; 山; ) KANGXI RADICAL MOUNTAIN
+2F2E;2F2E;2F2E;5DDB;5DDB; # (⼮; ⼮; ⼮; 巛; 巛; ) KANGXI RADICAL RIVER
+2F2F;2F2F;2F2F;5DE5;5DE5; # (⼯; ⼯; ⼯; 工; 工; ) KANGXI RADICAL WORK
+2F30;2F30;2F30;5DF1;5DF1; # (⼰; ⼰; ⼰; 己; 己; ) KANGXI RADICAL ONESELF
+2F31;2F31;2F31;5DFE;5DFE; # (⼱; ⼱; ⼱; 巾; 巾; ) KANGXI RADICAL TURBAN
+2F32;2F32;2F32;5E72;5E72; # (⼲; ⼲; ⼲; 干; 干; ) KANGXI RADICAL DRY
+2F33;2F33;2F33;5E7A;5E7A; # (⼳; ⼳; ⼳; 幺; 幺; ) KANGXI RADICAL SHORT THREAD
+2F34;2F34;2F34;5E7F;5E7F; # (⼴; ⼴; ⼴; 广; 广; ) KANGXI RADICAL DOTTED CLIFF
+2F35;2F35;2F35;5EF4;5EF4; # (⼵; ⼵; ⼵; 廴; 廴; ) KANGXI RADICAL LONG STRIDE
+2F36;2F36;2F36;5EFE;5EFE; # (⼶; ⼶; ⼶; 廾; 廾; ) KANGXI RADICAL TWO HANDS
+2F37;2F37;2F37;5F0B;5F0B; # (⼷; ⼷; ⼷; 弋; 弋; ) KANGXI RADICAL SHOOT
+2F38;2F38;2F38;5F13;5F13; # (⼸; ⼸; ⼸; 弓; 弓; ) KANGXI RADICAL BOW
+2F39;2F39;2F39;5F50;5F50; # (⼹; ⼹; ⼹; 彐; 彐; ) KANGXI RADICAL SNOUT
+2F3A;2F3A;2F3A;5F61;5F61; # (⼺; ⼺; ⼺; 彡; 彡; ) KANGXI RADICAL BRISTLE
+2F3B;2F3B;2F3B;5F73;5F73; # (⼻; ⼻; ⼻; 彳; 彳; ) KANGXI RADICAL STEP
+2F3C;2F3C;2F3C;5FC3;5FC3; # (⼼; ⼼; ⼼; 心; 心; ) KANGXI RADICAL HEART
+2F3D;2F3D;2F3D;6208;6208; # (⼽; ⼽; ⼽; 戈; 戈; ) KANGXI RADICAL HALBERD
+2F3E;2F3E;2F3E;6236;6236; # (⼾; ⼾; ⼾; 戶; 戶; ) KANGXI RADICAL DOOR
+2F3F;2F3F;2F3F;624B;624B; # (⼿; ⼿; ⼿; 手; 手; ) KANGXI RADICAL HAND
+2F40;2F40;2F40;652F;652F; # (⽀; ⽀; ⽀; 支; 支; ) KANGXI RADICAL BRANCH
+2F41;2F41;2F41;6534;6534; # (⽁; ⽁; ⽁; 攴; 攴; ) KANGXI RADICAL RAP
+2F42;2F42;2F42;6587;6587; # (⽂; ⽂; ⽂; 文; 文; ) KANGXI RADICAL SCRIPT
+2F43;2F43;2F43;6597;6597; # (⽃; ⽃; ⽃; 斗; 斗; ) KANGXI RADICAL DIPPER
+2F44;2F44;2F44;65A4;65A4; # (⽄; ⽄; ⽄; 斤; 斤; ) KANGXI RADICAL AXE
+2F45;2F45;2F45;65B9;65B9; # (⽅; ⽅; ⽅; 方; 方; ) KANGXI RADICAL SQUARE
+2F46;2F46;2F46;65E0;65E0; # (⽆; ⽆; ⽆; 无; 无; ) KANGXI RADICAL NOT
+2F47;2F47;2F47;65E5;65E5; # (⽇; ⽇; ⽇; 日; 日; ) KANGXI RADICAL SUN
+2F48;2F48;2F48;66F0;66F0; # (⽈; ⽈; ⽈; 曰; 曰; ) KANGXI RADICAL SAY
+2F49;2F49;2F49;6708;6708; # (⽉; ⽉; ⽉; 月; 月; ) KANGXI RADICAL MOON
+2F4A;2F4A;2F4A;6728;6728; # (⽊; ⽊; ⽊; 木; 木; ) KANGXI RADICAL TREE
+2F4B;2F4B;2F4B;6B20;6B20; # (⽋; ⽋; ⽋; 欠; 欠; ) KANGXI RADICAL LACK
+2F4C;2F4C;2F4C;6B62;6B62; # (⽌; ⽌; ⽌; 止; 止; ) KANGXI RADICAL STOP
+2F4D;2F4D;2F4D;6B79;6B79; # (⽍; ⽍; ⽍; 歹; 歹; ) KANGXI RADICAL DEATH
+2F4E;2F4E;2F4E;6BB3;6BB3; # (⽎; ⽎; ⽎; 殳; 殳; ) KANGXI RADICAL WEAPON
+2F4F;2F4F;2F4F;6BCB;6BCB; # (⽏; ⽏; ⽏; 毋; 毋; ) KANGXI RADICAL DO NOT
+2F50;2F50;2F50;6BD4;6BD4; # (⽐; ⽐; ⽐; 比; 比; ) KANGXI RADICAL COMPARE
+2F51;2F51;2F51;6BDB;6BDB; # (⽑; ⽑; ⽑; 毛; 毛; ) KANGXI RADICAL FUR
+2F52;2F52;2F52;6C0F;6C0F; # (⽒; ⽒; ⽒; 氏; 氏; ) KANGXI RADICAL CLAN
+2F53;2F53;2F53;6C14;6C14; # (⽓; ⽓; ⽓; 气; 气; ) KANGXI RADICAL STEAM
+2F54;2F54;2F54;6C34;6C34; # (⽔; ⽔; ⽔; 水; 水; ) KANGXI RADICAL WATER
+2F55;2F55;2F55;706B;706B; # (⽕; ⽕; ⽕; 火; 火; ) KANGXI RADICAL FIRE
+2F56;2F56;2F56;722A;722A; # (⽖; ⽖; ⽖; 爪; 爪; ) KANGXI RADICAL CLAW
+2F57;2F57;2F57;7236;7236; # (⽗; ⽗; ⽗; 父; 父; ) KANGXI RADICAL FATHER
+2F58;2F58;2F58;723B;723B; # (⽘; ⽘; ⽘; 爻; 爻; ) KANGXI RADICAL DOUBLE X
+2F59;2F59;2F59;723F;723F; # (⽙; ⽙; ⽙; 爿; 爿; ) KANGXI RADICAL HALF TREE TRUNK
+2F5A;2F5A;2F5A;7247;7247; # (⽚; ⽚; ⽚; 片; 片; ) KANGXI RADICAL SLICE
+2F5B;2F5B;2F5B;7259;7259; # (⽛; ⽛; ⽛; 牙; 牙; ) KANGXI RADICAL FANG
+2F5C;2F5C;2F5C;725B;725B; # (⽜; ⽜; ⽜; 牛; 牛; ) KANGXI RADICAL COW
+2F5D;2F5D;2F5D;72AC;72AC; # (⽝; ⽝; ⽝; 犬; 犬; ) KANGXI RADICAL DOG
+2F5E;2F5E;2F5E;7384;7384; # (⽞; ⽞; ⽞; 玄; 玄; ) KANGXI RADICAL PROFOUND
+2F5F;2F5F;2F5F;7389;7389; # (⽟; ⽟; ⽟; 玉; 玉; ) KANGXI RADICAL JADE
+2F60;2F60;2F60;74DC;74DC; # (⽠; ⽠; ⽠; 瓜; 瓜; ) KANGXI RADICAL MELON
+2F61;2F61;2F61;74E6;74E6; # (⽡; ⽡; ⽡; 瓦; 瓦; ) KANGXI RADICAL TILE
+2F62;2F62;2F62;7518;7518; # (⽢; ⽢; ⽢; 甘; 甘; ) KANGXI RADICAL SWEET
+2F63;2F63;2F63;751F;751F; # (⽣; ⽣; ⽣; 生; 生; ) KANGXI RADICAL LIFE
+2F64;2F64;2F64;7528;7528; # (⽤; ⽤; ⽤; 用; 用; ) KANGXI RADICAL USE
+2F65;2F65;2F65;7530;7530; # (⽥; ⽥; ⽥; 田; 田; ) KANGXI RADICAL FIELD
+2F66;2F66;2F66;758B;758B; # (⽦; ⽦; ⽦; 疋; 疋; ) KANGXI RADICAL BOLT OF CLOTH
+2F67;2F67;2F67;7592;7592; # (⽧; ⽧; ⽧; 疒; 疒; ) KANGXI RADICAL SICKNESS
+2F68;2F68;2F68;7676;7676; # (⽨; ⽨; ⽨; 癶; 癶; ) KANGXI RADICAL DOTTED TENT
+2F69;2F69;2F69;767D;767D; # (⽩; ⽩; ⽩; 白; 白; ) KANGXI RADICAL WHITE
+2F6A;2F6A;2F6A;76AE;76AE; # (⽪; ⽪; ⽪; 皮; 皮; ) KANGXI RADICAL SKIN
+2F6B;2F6B;2F6B;76BF;76BF; # (⽫; ⽫; ⽫; 皿; 皿; ) KANGXI RADICAL DISH
+2F6C;2F6C;2F6C;76EE;76EE; # (⽬; ⽬; ⽬; 目; 目; ) KANGXI RADICAL EYE
+2F6D;2F6D;2F6D;77DB;77DB; # (⽭; ⽭; ⽭; 矛; 矛; ) KANGXI RADICAL SPEAR
+2F6E;2F6E;2F6E;77E2;77E2; # (⽮; ⽮; ⽮; 矢; 矢; ) KANGXI RADICAL ARROW
+2F6F;2F6F;2F6F;77F3;77F3; # (⽯; ⽯; ⽯; 石; 石; ) KANGXI RADICAL STONE
+2F70;2F70;2F70;793A;793A; # (⽰; ⽰; ⽰; 示; 示; ) KANGXI RADICAL SPIRIT
+2F71;2F71;2F71;79B8;79B8; # (⽱; ⽱; ⽱; 禸; 禸; ) KANGXI RADICAL TRACK
+2F72;2F72;2F72;79BE;79BE; # (⽲; ⽲; ⽲; 禾; 禾; ) KANGXI RADICAL GRAIN
+2F73;2F73;2F73;7A74;7A74; # (⽳; ⽳; ⽳; 穴; 穴; ) KANGXI RADICAL CAVE
+2F74;2F74;2F74;7ACB;7ACB; # (⽴; ⽴; ⽴; 立; 立; ) KANGXI RADICAL STAND
+2F75;2F75;2F75;7AF9;7AF9; # (⽵; ⽵; ⽵; 竹; 竹; ) KANGXI RADICAL BAMBOO
+2F76;2F76;2F76;7C73;7C73; # (⽶; ⽶; ⽶; 米; 米; ) KANGXI RADICAL RICE
+2F77;2F77;2F77;7CF8;7CF8; # (⽷; ⽷; ⽷; 糸; 糸; ) KANGXI RADICAL SILK
+2F78;2F78;2F78;7F36;7F36; # (⽸; ⽸; ⽸; 缶; 缶; ) KANGXI RADICAL JAR
+2F79;2F79;2F79;7F51;7F51; # (⽹; ⽹; ⽹; 网; 网; ) KANGXI RADICAL NET
+2F7A;2F7A;2F7A;7F8A;7F8A; # (⽺; ⽺; ⽺; 羊; 羊; ) KANGXI RADICAL SHEEP
+2F7B;2F7B;2F7B;7FBD;7FBD; # (⽻; ⽻; ⽻; 羽; 羽; ) KANGXI RADICAL FEATHER
+2F7C;2F7C;2F7C;8001;8001; # (⽼; ⽼; ⽼; 老; 老; ) KANGXI RADICAL OLD
+2F7D;2F7D;2F7D;800C;800C; # (⽽; ⽽; ⽽; 而; 而; ) KANGXI RADICAL AND
+2F7E;2F7E;2F7E;8012;8012; # (⽾; ⽾; ⽾; 耒; 耒; ) KANGXI RADICAL PLOW
+2F7F;2F7F;2F7F;8033;8033; # (⽿; ⽿; ⽿; 耳; 耳; ) KANGXI RADICAL EAR
+2F80;2F80;2F80;807F;807F; # (⾀; ⾀; ⾀; 聿; 聿; ) KANGXI RADICAL BRUSH
+2F81;2F81;2F81;8089;8089; # (⾁; ⾁; ⾁; 肉; 肉; ) KANGXI RADICAL MEAT
+2F82;2F82;2F82;81E3;81E3; # (⾂; ⾂; ⾂; 臣; 臣; ) KANGXI RADICAL MINISTER
+2F83;2F83;2F83;81EA;81EA; # (⾃; ⾃; ⾃; 自; 自; ) KANGXI RADICAL SELF
+2F84;2F84;2F84;81F3;81F3; # (⾄; ⾄; ⾄; 至; 至; ) KANGXI RADICAL ARRIVE
+2F85;2F85;2F85;81FC;81FC; # (⾅; ⾅; ⾅; 臼; 臼; ) KANGXI RADICAL MORTAR
+2F86;2F86;2F86;820C;820C; # (⾆; ⾆; ⾆; 舌; 舌; ) KANGXI RADICAL TONGUE
+2F87;2F87;2F87;821B;821B; # (⾇; ⾇; ⾇; 舛; 舛; ) KANGXI RADICAL OPPOSE
+2F88;2F88;2F88;821F;821F; # (⾈; ⾈; ⾈; 舟; 舟; ) KANGXI RADICAL BOAT
+2F89;2F89;2F89;826E;826E; # (⾉; ⾉; ⾉; 艮; 艮; ) KANGXI RADICAL STOPPING
+2F8A;2F8A;2F8A;8272;8272; # (⾊; ⾊; ⾊; 色; 色; ) KANGXI RADICAL COLOR
+2F8B;2F8B;2F8B;8278;8278; # (⾋; ⾋; ⾋; 艸; 艸; ) KANGXI RADICAL GRASS
+2F8C;2F8C;2F8C;864D;864D; # (⾌; ⾌; ⾌; 虍; 虍; ) KANGXI RADICAL TIGER
+2F8D;2F8D;2F8D;866B;866B; # (⾍; ⾍; ⾍; 虫; 虫; ) KANGXI RADICAL INSECT
+2F8E;2F8E;2F8E;8840;8840; # (⾎; ⾎; ⾎; 血; 血; ) KANGXI RADICAL BLOOD
+2F8F;2F8F;2F8F;884C;884C; # (⾏; ⾏; ⾏; 行; 行; ) KANGXI RADICAL WALK ENCLOSURE
+2F90;2F90;2F90;8863;8863; # (⾐; ⾐; ⾐; 衣; 衣; ) KANGXI RADICAL CLOTHES
+2F91;2F91;2F91;897E;897E; # (⾑; ⾑; ⾑; 襾; 襾; ) KANGXI RADICAL WEST
+2F92;2F92;2F92;898B;898B; # (⾒; ⾒; ⾒; 見; 見; ) KANGXI RADICAL SEE
+2F93;2F93;2F93;89D2;89D2; # (⾓; ⾓; ⾓; 角; 角; ) KANGXI RADICAL HORN
+2F94;2F94;2F94;8A00;8A00; # (⾔; ⾔; ⾔; 言; 言; ) KANGXI RADICAL SPEECH
+2F95;2F95;2F95;8C37;8C37; # (⾕; ⾕; ⾕; 谷; 谷; ) KANGXI RADICAL VALLEY
+2F96;2F96;2F96;8C46;8C46; # (⾖; ⾖; ⾖; 豆; 豆; ) KANGXI RADICAL BEAN
+2F97;2F97;2F97;8C55;8C55; # (⾗; ⾗; ⾗; 豕; 豕; ) KANGXI RADICAL PIG
+2F98;2F98;2F98;8C78;8C78; # (⾘; ⾘; ⾘; 豸; 豸; ) KANGXI RADICAL BADGER
+2F99;2F99;2F99;8C9D;8C9D; # (⾙; ⾙; ⾙; 貝; 貝; ) KANGXI RADICAL SHELL
+2F9A;2F9A;2F9A;8D64;8D64; # (⾚; ⾚; ⾚; 赤; 赤; ) KANGXI RADICAL RED
+2F9B;2F9B;2F9B;8D70;8D70; # (⾛; ⾛; ⾛; 走; 走; ) KANGXI RADICAL RUN
+2F9C;2F9C;2F9C;8DB3;8DB3; # (⾜; ⾜; ⾜; 足; 足; ) KANGXI RADICAL FOOT
+2F9D;2F9D;2F9D;8EAB;8EAB; # (⾝; ⾝; ⾝; 身; 身; ) KANGXI RADICAL BODY
+2F9E;2F9E;2F9E;8ECA;8ECA; # (⾞; ⾞; ⾞; 車; 車; ) KANGXI RADICAL CART
+2F9F;2F9F;2F9F;8F9B;8F9B; # (⾟; ⾟; ⾟; 辛; 辛; ) KANGXI RADICAL BITTER
+2FA0;2FA0;2FA0;8FB0;8FB0; # (⾠; ⾠; ⾠; 辰; 辰; ) KANGXI RADICAL MORNING
+2FA1;2FA1;2FA1;8FB5;8FB5; # (⾡; ⾡; ⾡; 辵; 辵; ) KANGXI RADICAL WALK
+2FA2;2FA2;2FA2;9091;9091; # (⾢; ⾢; ⾢; 邑; 邑; ) KANGXI RADICAL CITY
+2FA3;2FA3;2FA3;9149;9149; # (⾣; ⾣; ⾣; 酉; 酉; ) KANGXI RADICAL WINE
+2FA4;2FA4;2FA4;91C6;91C6; # (⾤; ⾤; ⾤; 釆; 釆; ) KANGXI RADICAL DISTINGUISH
+2FA5;2FA5;2FA5;91CC;91CC; # (⾥; ⾥; ⾥; 里; 里; ) KANGXI RADICAL VILLAGE
+2FA6;2FA6;2FA6;91D1;91D1; # (⾦; ⾦; ⾦; 金; 金; ) KANGXI RADICAL GOLD
+2FA7;2FA7;2FA7;9577;9577; # (⾧; ⾧; ⾧; 長; 長; ) KANGXI RADICAL LONG
+2FA8;2FA8;2FA8;9580;9580; # (⾨; ⾨; ⾨; 門; 門; ) KANGXI RADICAL GATE
+2FA9;2FA9;2FA9;961C;961C; # (⾩; ⾩; ⾩; 阜; 阜; ) KANGXI RADICAL MOUND
+2FAA;2FAA;2FAA;96B6;96B6; # (⾪; ⾪; ⾪; 隶; 隶; ) KANGXI RADICAL SLAVE
+2FAB;2FAB;2FAB;96B9;96B9; # (⾫; ⾫; ⾫; 隹; 隹; ) KANGXI RADICAL SHORT TAILED BIRD
+2FAC;2FAC;2FAC;96E8;96E8; # (⾬; ⾬; ⾬; 雨; 雨; ) KANGXI RADICAL RAIN
+2FAD;2FAD;2FAD;9751;9751; # (⾭; ⾭; ⾭; 靑; 靑; ) KANGXI RADICAL BLUE
+2FAE;2FAE;2FAE;975E;975E; # (⾮; ⾮; ⾮; 非; 非; ) KANGXI RADICAL WRONG
+2FAF;2FAF;2FAF;9762;9762; # (⾯; ⾯; ⾯; 面; 面; ) KANGXI RADICAL FACE
+2FB0;2FB0;2FB0;9769;9769; # (⾰; ⾰; ⾰; 革; 革; ) KANGXI RADICAL LEATHER
+2FB1;2FB1;2FB1;97CB;97CB; # (⾱; ⾱; ⾱; 韋; 韋; ) KANGXI RADICAL TANNED LEATHER
+2FB2;2FB2;2FB2;97ED;97ED; # (⾲; ⾲; ⾲; 韭; 韭; ) KANGXI RADICAL LEEK
+2FB3;2FB3;2FB3;97F3;97F3; # (⾳; ⾳; ⾳; 音; 音; ) KANGXI RADICAL SOUND
+2FB4;2FB4;2FB4;9801;9801; # (⾴; ⾴; ⾴; 頁; 頁; ) KANGXI RADICAL LEAF
+2FB5;2FB5;2FB5;98A8;98A8; # (⾵; ⾵; ⾵; 風; 風; ) KANGXI RADICAL WIND
+2FB6;2FB6;2FB6;98DB;98DB; # (⾶; ⾶; ⾶; 飛; 飛; ) KANGXI RADICAL FLY
+2FB7;2FB7;2FB7;98DF;98DF; # (⾷; ⾷; ⾷; 食; 食; ) KANGXI RADICAL EAT
+2FB8;2FB8;2FB8;9996;9996; # (⾸; ⾸; ⾸; 首; 首; ) KANGXI RADICAL HEAD
+2FB9;2FB9;2FB9;9999;9999; # (⾹; ⾹; ⾹; 香; 香; ) KANGXI RADICAL FRAGRANT
+2FBA;2FBA;2FBA;99AC;99AC; # (⾺; ⾺; ⾺; 馬; 馬; ) KANGXI RADICAL HORSE
+2FBB;2FBB;2FBB;9AA8;9AA8; # (⾻; ⾻; ⾻; 骨; 骨; ) KANGXI RADICAL BONE
+2FBC;2FBC;2FBC;9AD8;9AD8; # (⾼; ⾼; ⾼; 高; 高; ) KANGXI RADICAL TALL
+2FBD;2FBD;2FBD;9ADF;9ADF; # (⾽; ⾽; ⾽; 髟; 髟; ) KANGXI RADICAL HAIR
+2FBE;2FBE;2FBE;9B25;9B25; # (⾾; ⾾; ⾾; 鬥; 鬥; ) KANGXI RADICAL FIGHT
+2FBF;2FBF;2FBF;9B2F;9B2F; # (⾿; ⾿; ⾿; 鬯; 鬯; ) KANGXI RADICAL SACRIFICIAL WINE
+2FC0;2FC0;2FC0;9B32;9B32; # (⿀; ⿀; ⿀; 鬲; 鬲; ) KANGXI RADICAL CAULDRON
+2FC1;2FC1;2FC1;9B3C;9B3C; # (⿁; ⿁; ⿁; 鬼; 鬼; ) KANGXI RADICAL GHOST
+2FC2;2FC2;2FC2;9B5A;9B5A; # (⿂; ⿂; ⿂; 魚; 魚; ) KANGXI RADICAL FISH
+2FC3;2FC3;2FC3;9CE5;9CE5; # (⿃; ⿃; ⿃; 鳥; 鳥; ) KANGXI RADICAL BIRD
+2FC4;2FC4;2FC4;9E75;9E75; # (⿄; ⿄; ⿄; 鹵; 鹵; ) KANGXI RADICAL SALT
+2FC5;2FC5;2FC5;9E7F;9E7F; # (⿅; ⿅; ⿅; 鹿; 鹿; ) KANGXI RADICAL DEER
+2FC6;2FC6;2FC6;9EA5;9EA5; # (⿆; ⿆; ⿆; 麥; 麥; ) KANGXI RADICAL WHEAT
+2FC7;2FC7;2FC7;9EBB;9EBB; # (⿇; ⿇; ⿇; 麻; 麻; ) KANGXI RADICAL HEMP
+2FC8;2FC8;2FC8;9EC3;9EC3; # (⿈; ⿈; ⿈; 黃; 黃; ) KANGXI RADICAL YELLOW
+2FC9;2FC9;2FC9;9ECD;9ECD; # (⿉; ⿉; ⿉; 黍; 黍; ) KANGXI RADICAL MILLET
+2FCA;2FCA;2FCA;9ED1;9ED1; # (⿊; ⿊; ⿊; 黑; 黑; ) KANGXI RADICAL BLACK
+2FCB;2FCB;2FCB;9EF9;9EF9; # (⿋; ⿋; ⿋; 黹; 黹; ) KANGXI RADICAL EMBROIDERY
+2FCC;2FCC;2FCC;9EFD;9EFD; # (⿌; ⿌; ⿌; 黽; 黽; ) KANGXI RADICAL FROG
+2FCD;2FCD;2FCD;9F0E;9F0E; # (⿍; ⿍; ⿍; 鼎; 鼎; ) KANGXI RADICAL TRIPOD
+2FCE;2FCE;2FCE;9F13;9F13; # (⿎; ⿎; ⿎; 鼓; 鼓; ) KANGXI RADICAL DRUM
+2FCF;2FCF;2FCF;9F20;9F20; # (⿏; ⿏; ⿏; 鼠; 鼠; ) KANGXI RADICAL RAT
+2FD0;2FD0;2FD0;9F3B;9F3B; # (⿐; ⿐; ⿐; 鼻; 鼻; ) KANGXI RADICAL NOSE
+2FD1;2FD1;2FD1;9F4A;9F4A; # (⿑; ⿑; ⿑; 齊; 齊; ) KANGXI RADICAL EVEN
+2FD2;2FD2;2FD2;9F52;9F52; # (⿒; ⿒; ⿒; 齒; 齒; ) KANGXI RADICAL TOOTH
+2FD3;2FD3;2FD3;9F8D;9F8D; # (⿓; ⿓; ⿓; 龍; 龍; ) KANGXI RADICAL DRAGON
+2FD4;2FD4;2FD4;9F9C;9F9C; # (⿔; ⿔; ⿔; 龜; 龜; ) KANGXI RADICAL TURTLE
+2FD5;2FD5;2FD5;9FA0;9FA0; # (⿕; ⿕; ⿕; 龠; 龠; ) KANGXI RADICAL FLUTE
+3000;3000;3000;0020;0020; # ( ;  ;  ; ; ; ) IDEOGRAPHIC SPACE
+3036;3036;3036;3012;3012; # (〶; 〶; 〶; 〒; 〒; ) CIRCLED POSTAL MARK
+3038;3038;3038;5341;5341; # (〸; 〸; 〸; 十; 十; ) HANGZHOU NUMERAL TEN
+3039;3039;3039;5344;5344; # (〹; 〹; 〹; 卄; 卄; ) HANGZHOU NUMERAL TWENTY
+303A;303A;303A;5345;5345; # (〺; 〺; 〺; 卅; 卅; ) HANGZHOU NUMERAL THIRTY
+304C;304C;304B 3099;304C;304B 3099; # (が; が; か◌゙; が; か◌゙; ) HIRAGANA LETTER GA
+304E;304E;304D 3099;304E;304D 3099; # (ぎ; ぎ; き◌゙; ぎ; き◌゙; ) HIRAGANA LETTER GI
+3050;3050;304F 3099;3050;304F 3099; # (ぐ; ぐ; く◌゙; ぐ; く◌゙; ) HIRAGANA LETTER GU
+3052;3052;3051 3099;3052;3051 3099; # (げ; げ; け◌゙; げ; け◌゙; ) HIRAGANA LETTER GE
+3054;3054;3053 3099;3054;3053 3099; # (ご; ご; こ◌゙; ご; こ◌゙; ) HIRAGANA LETTER GO
+3056;3056;3055 3099;3056;3055 3099; # (ざ; ざ; さ◌゙; ざ; さ◌゙; ) HIRAGANA LETTER ZA
+3058;3058;3057 3099;3058;3057 3099; # (じ; じ; し◌゙; じ; し◌゙; ) HIRAGANA LETTER ZI
+305A;305A;3059 3099;305A;3059 3099; # (ず; ず; す◌゙; ず; す◌゙; ) HIRAGANA LETTER ZU
+305C;305C;305B 3099;305C;305B 3099; # (ぜ; ぜ; せ◌゙; ぜ; せ◌゙; ) HIRAGANA LETTER ZE
+305E;305E;305D 3099;305E;305D 3099; # (ぞ; ぞ; そ◌゙; ぞ; そ◌゙; ) HIRAGANA LETTER ZO
+3060;3060;305F 3099;3060;305F 3099; # (だ; だ; た◌゙; だ; た◌゙; ) HIRAGANA LETTER DA
+3062;3062;3061 3099;3062;3061 3099; # (ぢ; ぢ; ち◌゙; ぢ; ち◌゙; ) HIRAGANA LETTER DI
+3065;3065;3064 3099;3065;3064 3099; # (づ; づ; つ◌゙; づ; つ◌゙; ) HIRAGANA LETTER DU
+3067;3067;3066 3099;3067;3066 3099; # (で; で; て◌゙; で; て◌゙; ) HIRAGANA LETTER DE
+3069;3069;3068 3099;3069;3068 3099; # (ど; ど; と◌゙; ど; と◌゙; ) HIRAGANA LETTER DO
+3070;3070;306F 3099;3070;306F 3099; # (ば; ば; は◌゙; ば; は◌゙; ) HIRAGANA LETTER BA
+3071;3071;306F 309A;3071;306F 309A; # (ぱ; ぱ; は◌゚; ぱ; は◌゚; ) HIRAGANA LETTER PA
+3073;3073;3072 3099;3073;3072 3099; # (び; び; ひ◌゙; び; ひ◌゙; ) HIRAGANA LETTER BI
+3074;3074;3072 309A;3074;3072 309A; # (ぴ; ぴ; ひ◌゚; ぴ; ひ◌゚; ) HIRAGANA LETTER PI
+3076;3076;3075 3099;3076;3075 3099; # (ぶ; ぶ; ふ◌゙; ぶ; ふ◌゙; ) HIRAGANA LETTER BU
+3077;3077;3075 309A;3077;3075 309A; # (ぷ; ぷ; ふ◌゚; ぷ; ふ◌゚; ) HIRAGANA LETTER PU
+3079;3079;3078 3099;3079;3078 3099; # (べ; べ; へ◌゙; べ; へ◌゙; ) HIRAGANA LETTER BE
+307A;307A;3078 309A;307A;3078 309A; # (ぺ; ぺ; へ◌゚; ぺ; へ◌゚; ) HIRAGANA LETTER PE
+307C;307C;307B 3099;307C;307B 3099; # (ぼ; ぼ; ほ◌゙; ぼ; ほ◌゙; ) HIRAGANA LETTER BO
+307D;307D;307B 309A;307D;307B 309A; # (ぽ; ぽ; ほ◌゚; ぽ; ほ◌゚; ) HIRAGANA LETTER PO
+3094;3094;3046 3099;3094;3046 3099; # (ゔ; ゔ; う◌゙; ゔ; う◌゙; ) HIRAGANA LETTER VU
+309B;309B;309B;0020 3099;0020 3099; # (゛; ゛; ゛; ◌゙; ◌゙; ) KATAKANA-HIRAGANA VOICED SOUND MARK
+309C;309C;309C;0020 309A;0020 309A; # (゜; ゜; ゜; ◌゚; ◌゚; ) KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+309E;309E;309D 3099;309E;309D 3099; # (ゞ; ゞ; ゝ◌゙; ゞ; ゝ◌゙; ) HIRAGANA VOICED ITERATION MARK
+309F;309F;309F;3088 308A;3088 308A; # (ゟ; ゟ; ゟ; より; より; ) HIRAGANA DIGRAPH YORI
+30AC;30AC;30AB 3099;30AC;30AB 3099; # (ガ; ガ; カ◌゙; ガ; カ◌゙; ) KATAKANA LETTER GA
+30AE;30AE;30AD 3099;30AE;30AD 3099; # (ギ; ギ; キ◌゙; ギ; キ◌゙; ) KATAKANA LETTER GI
+30B0;30B0;30AF 3099;30B0;30AF 3099; # (グ; グ; ク◌゙; グ; ク◌゙; ) KATAKANA LETTER GU
+30B2;30B2;30B1 3099;30B2;30B1 3099; # (ゲ; ゲ; ケ◌゙; ゲ; ケ◌゙; ) KATAKANA LETTER GE
+30B4;30B4;30B3 3099;30B4;30B3 3099; # (ゴ; ゴ; コ◌゙; ゴ; コ◌゙; ) KATAKANA LETTER GO
+30B6;30B6;30B5 3099;30B6;30B5 3099; # (ザ; ザ; サ◌゙; ザ; サ◌゙; ) KATAKANA LETTER ZA
+30B8;30B8;30B7 3099;30B8;30B7 3099; # (ジ; ジ; シ◌゙; ジ; シ◌゙; ) KATAKANA LETTER ZI
+30BA;30BA;30B9 3099;30BA;30B9 3099; # (ズ; ズ; ス◌゙; ズ; ス◌゙; ) KATAKANA LETTER ZU
+30BC;30BC;30BB 3099;30BC;30BB 3099; # (ゼ; ゼ; セ◌゙; ゼ; セ◌゙; ) KATAKANA LETTER ZE
+30BE;30BE;30BD 3099;30BE;30BD 3099; # (ゾ; ゾ; ソ◌゙; ゾ; ソ◌゙; ) KATAKANA LETTER ZO
+30C0;30C0;30BF 3099;30C0;30BF 3099; # (ダ; ダ; タ◌゙; ダ; タ◌゙; ) KATAKANA LETTER DA
+30C2;30C2;30C1 3099;30C2;30C1 3099; # (ヂ; ヂ; チ◌゙; ヂ; チ◌゙; ) KATAKANA LETTER DI
+30C5;30C5;30C4 3099;30C5;30C4 3099; # (ヅ; ヅ; ツ◌゙; ヅ; ツ◌゙; ) KATAKANA LETTER DU
+30C7;30C7;30C6 3099;30C7;30C6 3099; # (デ; デ; テ◌゙; デ; テ◌゙; ) KATAKANA LETTER DE
+30C9;30C9;30C8 3099;30C9;30C8 3099; # (ド; ド; ト◌゙; ド; ト◌゙; ) KATAKANA LETTER DO
+30D0;30D0;30CF 3099;30D0;30CF 3099; # (バ; バ; ハ◌゙; バ; ハ◌゙; ) KATAKANA LETTER BA
+30D1;30D1;30CF 309A;30D1;30CF 309A; # (パ; パ; ハ◌゚; パ; ハ◌゚; ) KATAKANA LETTER PA
+30D3;30D3;30D2 3099;30D3;30D2 3099; # (ビ; ビ; ヒ◌゙; ビ; ヒ◌゙; ) KATAKANA LETTER BI
+30D4;30D4;30D2 309A;30D4;30D2 309A; # (ピ; ピ; ヒ◌゚; ピ; ヒ◌゚; ) KATAKANA LETTER PI
+30D6;30D6;30D5 3099;30D6;30D5 3099; # (ブ; ブ; フ◌゙; ブ; フ◌゙; ) KATAKANA LETTER BU
+30D7;30D7;30D5 309A;30D7;30D5 309A; # (プ; プ; フ◌゚; プ; フ◌゚; ) KATAKANA LETTER PU
+30D9;30D9;30D8 3099;30D9;30D8 3099; # (ベ; ベ; ヘ◌゙; ベ; ヘ◌゙; ) KATAKANA LETTER BE
+30DA;30DA;30D8 309A;30DA;30D8 309A; # (ペ; ペ; ヘ◌゚; ペ; ヘ◌゚; ) KATAKANA LETTER PE
+30DC;30DC;30DB 3099;30DC;30DB 3099; # (ボ; ボ; ホ◌゙; ボ; ホ◌゙; ) KATAKANA LETTER BO
+30DD;30DD;30DB 309A;30DD;30DB 309A; # (ポ; ポ; ホ◌゚; ポ; ホ◌゚; ) KATAKANA LETTER PO
+30F4;30F4;30A6 3099;30F4;30A6 3099; # (ヴ; ヴ; ウ◌゙; ヴ; ウ◌゙; ) KATAKANA LETTER VU
+30F7;30F7;30EF 3099;30F7;30EF 3099; # (ヷ; ヷ; ワ◌゙; ヷ; ワ◌゙; ) KATAKANA LETTER VA
+30F8;30F8;30F0 3099;30F8;30F0 3099; # (ヸ; ヸ; ヰ◌゙; ヸ; ヰ◌゙; ) KATAKANA LETTER VI
+30F9;30F9;30F1 3099;30F9;30F1 3099; # (ヹ; ヹ; ヱ◌゙; ヹ; ヱ◌゙; ) KATAKANA LETTER VE
+30FA;30FA;30F2 3099;30FA;30F2 3099; # (ヺ; ヺ; ヲ◌゙; ヺ; ヲ◌゙; ) KATAKANA LETTER VO
+30FE;30FE;30FD 3099;30FE;30FD 3099; # (ヾ; ヾ; ヽ◌゙; ヾ; ヽ◌゙; ) KATAKANA VOICED ITERATION MARK
+30FF;30FF;30FF;30B3 30C8;30B3 30C8; # (ヿ; ヿ; ヿ; コト; コト; ) KATAKANA DIGRAPH KOTO
+3131;3131;3131;1100;1100; # (ㄱ; ㄱ; ㄱ; ᄀ; ᄀ; ) HANGUL LETTER KIYEOK
+3132;3132;3132;1101;1101; # (ㄲ; ㄲ; ㄲ; ᄁ; ᄁ; ) HANGUL LETTER SSANGKIYEOK
+3133;3133;3133;11AA;11AA; # (ㄳ; ㄳ; ㄳ; ᆪ; ᆪ; ) HANGUL LETTER KIYEOK-SIOS
+3134;3134;3134;1102;1102; # (ㄴ; ㄴ; ㄴ; ᄂ; ᄂ; ) HANGUL LETTER NIEUN
+3135;3135;3135;11AC;11AC; # (ㄵ; ㄵ; ㄵ; ᆬ; ᆬ; ) HANGUL LETTER NIEUN-CIEUC
+3136;3136;3136;11AD;11AD; # (ㄶ; ㄶ; ㄶ; ᆭ; ᆭ; ) HANGUL LETTER NIEUN-HIEUH
+3137;3137;3137;1103;1103; # (ㄷ; ㄷ; ㄷ; ᄃ; ᄃ; ) HANGUL LETTER TIKEUT
+3138;3138;3138;1104;1104; # (ㄸ; ㄸ; ㄸ; ᄄ; ᄄ; ) HANGUL LETTER SSANGTIKEUT
+3139;3139;3139;1105;1105; # (ㄹ; ㄹ; ㄹ; ᄅ; ᄅ; ) HANGUL LETTER RIEUL
+313A;313A;313A;11B0;11B0; # (ㄺ; ㄺ; ㄺ; ᆰ; ᆰ; ) HANGUL LETTER RIEUL-KIYEOK
+313B;313B;313B;11B1;11B1; # (ㄻ; ㄻ; ㄻ; ᆱ; ᆱ; ) HANGUL LETTER RIEUL-MIEUM
+313C;313C;313C;11B2;11B2; # (ㄼ; ㄼ; ㄼ; ᆲ; ᆲ; ) HANGUL LETTER RIEUL-PIEUP
+313D;313D;313D;11B3;11B3; # (ㄽ; ㄽ; ㄽ; ᆳ; ᆳ; ) HANGUL LETTER RIEUL-SIOS
+313E;313E;313E;11B4;11B4; # (ㄾ; ㄾ; ㄾ; ᆴ; ᆴ; ) HANGUL LETTER RIEUL-THIEUTH
+313F;313F;313F;11B5;11B5; # (ㄿ; ㄿ; ㄿ; ᆵ; ᆵ; ) HANGUL LETTER RIEUL-PHIEUPH
+3140;3140;3140;111A;111A; # (ㅀ; ㅀ; ㅀ; ᄚ; ᄚ; ) HANGUL LETTER RIEUL-HIEUH
+3141;3141;3141;1106;1106; # (ㅁ; ㅁ; ㅁ; ᄆ; ᄆ; ) HANGUL LETTER MIEUM
+3142;3142;3142;1107;1107; # (ㅂ; ㅂ; ㅂ; ᄇ; ᄇ; ) HANGUL LETTER PIEUP
+3143;3143;3143;1108;1108; # (ㅃ; ㅃ; ㅃ; ᄈ; ᄈ; ) HANGUL LETTER SSANGPIEUP
+3144;3144;3144;1121;1121; # (ㅄ; ㅄ; ㅄ; ᄡ; ᄡ; ) HANGUL LETTER PIEUP-SIOS
+3145;3145;3145;1109;1109; # (ㅅ; ㅅ; ㅅ; ᄉ; ᄉ; ) HANGUL LETTER SIOS
+3146;3146;3146;110A;110A; # (ㅆ; ㅆ; ㅆ; ᄊ; ᄊ; ) HANGUL LETTER SSANGSIOS
+3147;3147;3147;110B;110B; # (ㅇ; ㅇ; ㅇ; ᄋ; ᄋ; ) HANGUL LETTER IEUNG
+3148;3148;3148;110C;110C; # (ㅈ; ㅈ; ㅈ; ᄌ; ᄌ; ) HANGUL LETTER CIEUC
+3149;3149;3149;110D;110D; # (ㅉ; ㅉ; ㅉ; ᄍ; ᄍ; ) HANGUL LETTER SSANGCIEUC
+314A;314A;314A;110E;110E; # (ㅊ; ㅊ; ㅊ; ᄎ; ᄎ; ) HANGUL LETTER CHIEUCH
+314B;314B;314B;110F;110F; # (ㅋ; ㅋ; ㅋ; ᄏ; ᄏ; ) HANGUL LETTER KHIEUKH
+314C;314C;314C;1110;1110; # (ㅌ; ㅌ; ㅌ; ᄐ; ᄐ; ) HANGUL LETTER THIEUTH
+314D;314D;314D;1111;1111; # (ㅍ; ㅍ; ㅍ; ᄑ; ᄑ; ) HANGUL LETTER PHIEUPH
+314E;314E;314E;1112;1112; # (ㅎ; ㅎ; ㅎ; ᄒ; ᄒ; ) HANGUL LETTER HIEUH
+314F;314F;314F;1161;1161; # (ㅏ; ㅏ; ㅏ; ᅡ; ᅡ; ) HANGUL LETTER A
+3150;3150;3150;1162;1162; # (ㅐ; ㅐ; ㅐ; ᅢ; ᅢ; ) HANGUL LETTER AE
+3151;3151;3151;1163;1163; # (ㅑ; ㅑ; ㅑ; ᅣ; ᅣ; ) HANGUL LETTER YA
+3152;3152;3152;1164;1164; # (ㅒ; ㅒ; ㅒ; ᅤ; ᅤ; ) HANGUL LETTER YAE
+3153;3153;3153;1165;1165; # (ㅓ; ㅓ; ㅓ; ᅥ; ᅥ; ) HANGUL LETTER EO
+3154;3154;3154;1166;1166; # (ㅔ; ㅔ; ㅔ; ᅦ; ᅦ; ) HANGUL LETTER E
+3155;3155;3155;1167;1167; # (ㅕ; ㅕ; ㅕ; ᅧ; ᅧ; ) HANGUL LETTER YEO
+3156;3156;3156;1168;1168; # (ㅖ; ㅖ; ㅖ; ᅨ; ᅨ; ) HANGUL LETTER YE
+3157;3157;3157;1169;1169; # (ㅗ; ㅗ; ㅗ; ᅩ; ᅩ; ) HANGUL LETTER O
+3158;3158;3158;116A;116A; # (ㅘ; ㅘ; ㅘ; ᅪ; ᅪ; ) HANGUL LETTER WA
+3159;3159;3159;116B;116B; # (ㅙ; ㅙ; ㅙ; ᅫ; ᅫ; ) HANGUL LETTER WAE
+315A;315A;315A;116C;116C; # (ㅚ; ㅚ; ㅚ; ᅬ; ᅬ; ) HANGUL LETTER OE
+315B;315B;315B;116D;116D; # (ㅛ; ㅛ; ㅛ; ᅭ; ᅭ; ) HANGUL LETTER YO
+315C;315C;315C;116E;116E; # (ㅜ; ㅜ; ㅜ; ᅮ; ᅮ; ) HANGUL LETTER U
+315D;315D;315D;116F;116F; # (ㅝ; ㅝ; ㅝ; ᅯ; ᅯ; ) HANGUL LETTER WEO
+315E;315E;315E;1170;1170; # (ㅞ; ㅞ; ㅞ; ᅰ; ᅰ; ) HANGUL LETTER WE
+315F;315F;315F;1171;1171; # (ㅟ; ㅟ; ㅟ; ᅱ; ᅱ; ) HANGUL LETTER WI
+3160;3160;3160;1172;1172; # (ㅠ; ㅠ; ㅠ; ᅲ; ᅲ; ) HANGUL LETTER YU
+3161;3161;3161;1173;1173; # (ㅡ; ㅡ; ㅡ; ᅳ; ᅳ; ) HANGUL LETTER EU
+3162;3162;3162;1174;1174; # (ㅢ; ㅢ; ㅢ; ᅴ; ᅴ; ) HANGUL LETTER YI
+3163;3163;3163;1175;1175; # (ㅣ; ㅣ; ㅣ; ᅵ; ᅵ; ) HANGUL LETTER I
+3164;3164;3164;1160;1160; # (ㅤ; ㅤ; ㅤ; ᅠ; ᅠ; ) HANGUL FILLER
+3165;3165;3165;1114;1114; # (ㅥ; ㅥ; ㅥ; ᄔ; ᄔ; ) HANGUL LETTER SSANGNIEUN
+3166;3166;3166;1115;1115; # (ㅦ; ㅦ; ㅦ; ᄕ; ᄕ; ) HANGUL LETTER NIEUN-TIKEUT
+3167;3167;3167;11C7;11C7; # (ㅧ; ㅧ; ㅧ; ᇇ; ᇇ; ) HANGUL LETTER NIEUN-SIOS
+3168;3168;3168;11C8;11C8; # (ㅨ; ㅨ; ㅨ; ᇈ; ᇈ; ) HANGUL LETTER NIEUN-PANSIOS
+3169;3169;3169;11CC;11CC; # (ㅩ; ㅩ; ㅩ; ᇌ; ᇌ; ) HANGUL LETTER RIEUL-KIYEOK-SIOS
+316A;316A;316A;11CE;11CE; # (ㅪ; ㅪ; ㅪ; ᇎ; ᇎ; ) HANGUL LETTER RIEUL-TIKEUT
+316B;316B;316B;11D3;11D3; # (ㅫ; ㅫ; ㅫ; ᇓ; ᇓ; ) HANGUL LETTER RIEUL-PIEUP-SIOS
+316C;316C;316C;11D7;11D7; # (ㅬ; ㅬ; ㅬ; ᇗ; ᇗ; ) HANGUL LETTER RIEUL-PANSIOS
+316D;316D;316D;11D9;11D9; # (ㅭ; ㅭ; ㅭ; ᇙ; ᇙ; ) HANGUL LETTER RIEUL-YEORINHIEUH
+316E;316E;316E;111C;111C; # (ㅮ; ㅮ; ㅮ; ᄜ; ᄜ; ) HANGUL LETTER MIEUM-PIEUP
+316F;316F;316F;11DD;11DD; # (ㅯ; ㅯ; ㅯ; ᇝ; ᇝ; ) HANGUL LETTER MIEUM-SIOS
+3170;3170;3170;11DF;11DF; # (ㅰ; ㅰ; ㅰ; ᇟ; ᇟ; ) HANGUL LETTER MIEUM-PANSIOS
+3171;3171;3171;111D;111D; # (ㅱ; ㅱ; ㅱ; ᄝ; ᄝ; ) HANGUL LETTER KAPYEOUNMIEUM
+3172;3172;3172;111E;111E; # (ㅲ; ㅲ; ㅲ; ᄞ; ᄞ; ) HANGUL LETTER PIEUP-KIYEOK
+3173;3173;3173;1120;1120; # (ㅳ; ㅳ; ㅳ; ᄠ; ᄠ; ) HANGUL LETTER PIEUP-TIKEUT
+3174;3174;3174;1122;1122; # (ㅴ; ㅴ; ㅴ; ᄢ; ᄢ; ) HANGUL LETTER PIEUP-SIOS-KIYEOK
+3175;3175;3175;1123;1123; # (ㅵ; ㅵ; ㅵ; ᄣ; ᄣ; ) HANGUL LETTER PIEUP-SIOS-TIKEUT
+3176;3176;3176;1127;1127; # (ㅶ; ㅶ; ㅶ; ᄧ; ᄧ; ) HANGUL LETTER PIEUP-CIEUC
+3177;3177;3177;1129;1129; # (ㅷ; ㅷ; ㅷ; ᄩ; ᄩ; ) HANGUL LETTER PIEUP-THIEUTH
+3178;3178;3178;112B;112B; # (ㅸ; ㅸ; ㅸ; ᄫ; ᄫ; ) HANGUL LETTER KAPYEOUNPIEUP
+3179;3179;3179;112C;112C; # (ㅹ; ㅹ; ㅹ; ᄬ; ᄬ; ) HANGUL LETTER KAPYEOUNSSANGPIEUP
+317A;317A;317A;112D;112D; # (ㅺ; ㅺ; ㅺ; ᄭ; ᄭ; ) HANGUL LETTER SIOS-KIYEOK
+317B;317B;317B;112E;112E; # (ㅻ; ㅻ; ㅻ; ᄮ; ᄮ; ) HANGUL LETTER SIOS-NIEUN
+317C;317C;317C;112F;112F; # (ㅼ; ㅼ; ㅼ; ᄯ; ᄯ; ) HANGUL LETTER SIOS-TIKEUT
+317D;317D;317D;1132;1132; # (ㅽ; ㅽ; ㅽ; ᄲ; ᄲ; ) HANGUL LETTER SIOS-PIEUP
+317E;317E;317E;1136;1136; # (ㅾ; ㅾ; ㅾ; ᄶ; ᄶ; ) HANGUL LETTER SIOS-CIEUC
+317F;317F;317F;1140;1140; # (ㅿ; ㅿ; ㅿ; ᅀ; ᅀ; ) HANGUL LETTER PANSIOS
+3180;3180;3180;1147;1147; # (ㆀ; ㆀ; ㆀ; ᅇ; ᅇ; ) HANGUL LETTER SSANGIEUNG
+3181;3181;3181;114C;114C; # (ㆁ; ㆁ; ㆁ; ᅌ; ᅌ; ) HANGUL LETTER YESIEUNG
+3182;3182;3182;11F1;11F1; # (ㆂ; ㆂ; ㆂ; ᇱ; ᇱ; ) HANGUL LETTER YESIEUNG-SIOS
+3183;3183;3183;11F2;11F2; # (ㆃ; ㆃ; ㆃ; ᇲ; ᇲ; ) HANGUL LETTER YESIEUNG-PANSIOS
+3184;3184;3184;1157;1157; # (ㆄ; ㆄ; ㆄ; ᅗ; ᅗ; ) HANGUL LETTER KAPYEOUNPHIEUPH
+3185;3185;3185;1158;1158; # (ㆅ; ㆅ; ㆅ; ᅘ; ᅘ; ) HANGUL LETTER SSANGHIEUH
+3186;3186;3186;1159;1159; # (ㆆ; ㆆ; ㆆ; ᅙ; ᅙ; ) HANGUL LETTER YEORINHIEUH
+3187;3187;3187;1184;1184; # (ㆇ; ㆇ; ㆇ; ᆄ; ᆄ; ) HANGUL LETTER YO-YA
+3188;3188;3188;1185;1185; # (ㆈ; ㆈ; ㆈ; ᆅ; ᆅ; ) HANGUL LETTER YO-YAE
+3189;3189;3189;1188;1188; # (ㆉ; ㆉ; ㆉ; ᆈ; ᆈ; ) HANGUL LETTER YO-I
+318A;318A;318A;1191;1191; # (ㆊ; ㆊ; ㆊ; ᆑ; ᆑ; ) HANGUL LETTER YU-YEO
+318B;318B;318B;1192;1192; # (ㆋ; ㆋ; ㆋ; ᆒ; ᆒ; ) HANGUL LETTER YU-YE
+318C;318C;318C;1194;1194; # (ㆌ; ㆌ; ㆌ; ᆔ; ᆔ; ) HANGUL LETTER YU-I
+318D;318D;318D;119E;119E; # (ㆍ; ㆍ; ㆍ; ᆞ; ᆞ; ) HANGUL LETTER ARAEA
+318E;318E;318E;11A1;11A1; # (ㆎ; ㆎ; ㆎ; ᆡ; ᆡ; ) HANGUL LETTER ARAEAE
+3192;3192;3192;4E00;4E00; # (㆒; ㆒; ㆒; 一; 一; ) IDEOGRAPHIC ANNOTATION ONE MARK
+3193;3193;3193;4E8C;4E8C; # (㆓; ㆓; ㆓; 二; 二; ) IDEOGRAPHIC ANNOTATION TWO MARK
+3194;3194;3194;4E09;4E09; # (㆔; ㆔; ㆔; 三; 三; ) IDEOGRAPHIC ANNOTATION THREE MARK
+3195;3195;3195;56DB;56DB; # (㆕; ㆕; ㆕; 四; 四; ) IDEOGRAPHIC ANNOTATION FOUR MARK
+3196;3196;3196;4E0A;4E0A; # (㆖; ㆖; ㆖; 上; 上; ) IDEOGRAPHIC ANNOTATION TOP MARK
+3197;3197;3197;4E2D;4E2D; # (㆗; ㆗; ㆗; 中; 中; ) IDEOGRAPHIC ANNOTATION MIDDLE MARK
+3198;3198;3198;4E0B;4E0B; # (㆘; ㆘; ㆘; 下; 下; ) IDEOGRAPHIC ANNOTATION BOTTOM MARK
+3199;3199;3199;7532;7532; # (㆙; ㆙; ㆙; 甲; 甲; ) IDEOGRAPHIC ANNOTATION FIRST MARK
+319A;319A;319A;4E59;4E59; # (㆚; ㆚; ㆚; 乙; 乙; ) IDEOGRAPHIC ANNOTATION SECOND MARK
+319B;319B;319B;4E19;4E19; # (㆛; ㆛; ㆛; 丙; 丙; ) IDEOGRAPHIC ANNOTATION THIRD MARK
+319C;319C;319C;4E01;4E01; # (㆜; ㆜; ㆜; 丁; 丁; ) IDEOGRAPHIC ANNOTATION FOURTH MARK
+319D;319D;319D;5929;5929; # (㆝; ㆝; ㆝; 天; 天; ) IDEOGRAPHIC ANNOTATION HEAVEN MARK
+319E;319E;319E;5730;5730; # (㆞; ㆞; ㆞; 地; 地; ) IDEOGRAPHIC ANNOTATION EARTH MARK
+319F;319F;319F;4EBA;4EBA; # (㆟; ㆟; ㆟; 人; 人; ) IDEOGRAPHIC ANNOTATION MAN MARK
+3200;3200;3200;0028 1100 0029;0028 1100 0029; # (㈀; ㈀; ㈀; (ᄀ); (ᄀ); ) PARENTHESIZED HANGUL KIYEOK
+3201;3201;3201;0028 1102 0029;0028 1102 0029; # (㈁; ㈁; ㈁; (ᄂ); (ᄂ); ) PARENTHESIZED HANGUL NIEUN
+3202;3202;3202;0028 1103 0029;0028 1103 0029; # (㈂; ㈂; ㈂; (ᄃ); (ᄃ); ) PARENTHESIZED HANGUL TIKEUT
+3203;3203;3203;0028 1105 0029;0028 1105 0029; # (㈃; ㈃; ㈃; (ᄅ); (ᄅ); ) PARENTHESIZED HANGUL RIEUL
+3204;3204;3204;0028 1106 0029;0028 1106 0029; # (㈄; ㈄; ㈄; (ᄆ); (ᄆ); ) PARENTHESIZED HANGUL MIEUM
+3205;3205;3205;0028 1107 0029;0028 1107 0029; # (㈅; ㈅; ㈅; (ᄇ); (ᄇ); ) PARENTHESIZED HANGUL PIEUP
+3206;3206;3206;0028 1109 0029;0028 1109 0029; # (㈆; ㈆; ㈆; (ᄉ); (ᄉ); ) PARENTHESIZED HANGUL SIOS
+3207;3207;3207;0028 110B 0029;0028 110B 0029; # (㈇; ㈇; ㈇; (ᄋ); (ᄋ); ) PARENTHESIZED HANGUL IEUNG
+3208;3208;3208;0028 110C 0029;0028 110C 0029; # (㈈; ㈈; ㈈; (ᄌ); (ᄌ); ) PARENTHESIZED HANGUL CIEUC
+3209;3209;3209;0028 110E 0029;0028 110E 0029; # (㈉; ㈉; ㈉; (ᄎ); (ᄎ); ) PARENTHESIZED HANGUL CHIEUCH
+320A;320A;320A;0028 110F 0029;0028 110F 0029; # (㈊; ㈊; ㈊; (ᄏ); (ᄏ); ) PARENTHESIZED HANGUL KHIEUKH
+320B;320B;320B;0028 1110 0029;0028 1110 0029; # (㈋; ㈋; ㈋; (ᄐ); (ᄐ); ) PARENTHESIZED HANGUL THIEUTH
+320C;320C;320C;0028 1111 0029;0028 1111 0029; # (㈌; ㈌; ㈌; (ᄑ); (ᄑ); ) PARENTHESIZED HANGUL PHIEUPH
+320D;320D;320D;0028 1112 0029;0028 1112 0029; # (㈍; ㈍; ㈍; (ᄒ); (ᄒ); ) PARENTHESIZED HANGUL HIEUH
+320E;320E;320E;0028 AC00 0029;0028 1100 1161 0029; # (㈎; ㈎; ㈎; (가); (가); ) PARENTHESIZED HANGUL KIYEOK A
+320F;320F;320F;0028 B098 0029;0028 1102 1161 0029; # (㈏; ㈏; ㈏; (나); (나); ) PARENTHESIZED HANGUL NIEUN A
+3210;3210;3210;0028 B2E4 0029;0028 1103 1161 0029; # (㈐; ㈐; ㈐; (다); (다); ) PARENTHESIZED HANGUL TIKEUT A
+3211;3211;3211;0028 B77C 0029;0028 1105 1161 0029; # (㈑; ㈑; ㈑; (라); (라); ) PARENTHESIZED HANGUL RIEUL A
+3212;3212;3212;0028 B9C8 0029;0028 1106 1161 0029; # (㈒; ㈒; ㈒; (마); (마); ) PARENTHESIZED HANGUL MIEUM A
+3213;3213;3213;0028 BC14 0029;0028 1107 1161 0029; # (㈓; ㈓; ㈓; (바); (바); ) PARENTHESIZED HANGUL PIEUP A
+3214;3214;3214;0028 C0AC 0029;0028 1109 1161 0029; # (㈔; ㈔; ㈔; (사); (사); ) PARENTHESIZED HANGUL SIOS A
+3215;3215;3215;0028 C544 0029;0028 110B 1161 0029; # (㈕; ㈕; ㈕; (아); (아); ) PARENTHESIZED HANGUL IEUNG A
+3216;3216;3216;0028 C790 0029;0028 110C 1161 0029; # (㈖; ㈖; ㈖; (자); (자); ) PARENTHESIZED HANGUL CIEUC A
+3217;3217;3217;0028 CC28 0029;0028 110E 1161 0029; # (㈗; ㈗; ㈗; (차); (차); ) PARENTHESIZED HANGUL CHIEUCH A
+3218;3218;3218;0028 CE74 0029;0028 110F 1161 0029; # (㈘; ㈘; ㈘; (카); (카); ) PARENTHESIZED HANGUL KHIEUKH A
+3219;3219;3219;0028 D0C0 0029;0028 1110 1161 0029; # (㈙; ㈙; ㈙; (타); (타); ) PARENTHESIZED HANGUL THIEUTH A
+321A;321A;321A;0028 D30C 0029;0028 1111 1161 0029; # (㈚; ㈚; ㈚; (파); (파); ) PARENTHESIZED HANGUL PHIEUPH A
+321B;321B;321B;0028 D558 0029;0028 1112 1161 0029; # (㈛; ㈛; ㈛; (하); (하); ) PARENTHESIZED HANGUL HIEUH A
+321C;321C;321C;0028 C8FC 0029;0028 110C 116E 0029; # (㈜; ㈜; ㈜; (주); (주); ) PARENTHESIZED HANGUL CIEUC U
+321D;321D;321D;0028 C624 C804 0029;0028 110B 1169 110C 1165 11AB 0029; # (㈝; ㈝; ㈝; (오전); (오전); ) PARENTHESIZED KOREAN CHARACTER OJEON
+321E;321E;321E;0028 C624 D6C4 0029;0028 110B 1169 1112 116E 0029; # (㈞; ㈞; ㈞; (오후); (오후); ) PARENTHESIZED KOREAN CHARACTER O HU
+3220;3220;3220;0028 4E00 0029;0028 4E00 0029; # (㈠; ㈠; ㈠; (一); (一); ) PARENTHESIZED IDEOGRAPH ONE
+3221;3221;3221;0028 4E8C 0029;0028 4E8C 0029; # (㈡; ㈡; ㈡; (二); (二); ) PARENTHESIZED IDEOGRAPH TWO
+3222;3222;3222;0028 4E09 0029;0028 4E09 0029; # (㈢; ㈢; ㈢; (三); (三); ) PARENTHESIZED IDEOGRAPH THREE
+3223;3223;3223;0028 56DB 0029;0028 56DB 0029; # (㈣; ㈣; ㈣; (四); (四); ) PARENTHESIZED IDEOGRAPH FOUR
+3224;3224;3224;0028 4E94 0029;0028 4E94 0029; # (㈤; ㈤; ㈤; (五); (五); ) PARENTHESIZED IDEOGRAPH FIVE
+3225;3225;3225;0028 516D 0029;0028 516D 0029; # (㈥; ㈥; ㈥; (六); (六); ) PARENTHESIZED IDEOGRAPH SIX
+3226;3226;3226;0028 4E03 0029;0028 4E03 0029; # (㈦; ㈦; ㈦; (七); (七); ) PARENTHESIZED IDEOGRAPH SEVEN
+3227;3227;3227;0028 516B 0029;0028 516B 0029; # (㈧; ㈧; ㈧; (八); (八); ) PARENTHESIZED IDEOGRAPH EIGHT
+3228;3228;3228;0028 4E5D 0029;0028 4E5D 0029; # (㈨; ㈨; ㈨; (九); (九); ) PARENTHESIZED IDEOGRAPH NINE
+3229;3229;3229;0028 5341 0029;0028 5341 0029; # (㈩; ㈩; ㈩; (十); (十); ) PARENTHESIZED IDEOGRAPH TEN
+322A;322A;322A;0028 6708 0029;0028 6708 0029; # (㈪; ㈪; ㈪; (月); (月); ) PARENTHESIZED IDEOGRAPH MOON
+322B;322B;322B;0028 706B 0029;0028 706B 0029; # (㈫; ㈫; ㈫; (火); (火); ) PARENTHESIZED IDEOGRAPH FIRE
+322C;322C;322C;0028 6C34 0029;0028 6C34 0029; # (㈬; ㈬; ㈬; (水); (水); ) PARENTHESIZED IDEOGRAPH WATER
+322D;322D;322D;0028 6728 0029;0028 6728 0029; # (㈭; ㈭; ㈭; (木); (木); ) PARENTHESIZED IDEOGRAPH WOOD
+322E;322E;322E;0028 91D1 0029;0028 91D1 0029; # (㈮; ㈮; ㈮; (金); (金); ) PARENTHESIZED IDEOGRAPH METAL
+322F;322F;322F;0028 571F 0029;0028 571F 0029; # (㈯; ㈯; ㈯; (土); (土); ) PARENTHESIZED IDEOGRAPH EARTH
+3230;3230;3230;0028 65E5 0029;0028 65E5 0029; # (㈰; ㈰; ㈰; (日); (日); ) PARENTHESIZED IDEOGRAPH SUN
+3231;3231;3231;0028 682A 0029;0028 682A 0029; # (㈱; ㈱; ㈱; (株); (株); ) PARENTHESIZED IDEOGRAPH STOCK
+3232;3232;3232;0028 6709 0029;0028 6709 0029; # (㈲; ㈲; ㈲; (有); (有); ) PARENTHESIZED IDEOGRAPH HAVE
+3233;3233;3233;0028 793E 0029;0028 793E 0029; # (㈳; ㈳; ㈳; (社); (社); ) PARENTHESIZED IDEOGRAPH SOCIETY
+3234;3234;3234;0028 540D 0029;0028 540D 0029; # (㈴; ㈴; ㈴; (名); (名); ) PARENTHESIZED IDEOGRAPH NAME
+3235;3235;3235;0028 7279 0029;0028 7279 0029; # (㈵; ㈵; ㈵; (特); (特); ) PARENTHESIZED IDEOGRAPH SPECIAL
+3236;3236;3236;0028 8CA1 0029;0028 8CA1 0029; # (㈶; ㈶; ㈶; (財); (財); ) PARENTHESIZED IDEOGRAPH FINANCIAL
+3237;3237;3237;0028 795D 0029;0028 795D 0029; # (㈷; ㈷; ㈷; (祝); (祝); ) PARENTHESIZED IDEOGRAPH CONGRATULATION
+3238;3238;3238;0028 52B4 0029;0028 52B4 0029; # (㈸; ㈸; ㈸; (労); (労); ) PARENTHESIZED IDEOGRAPH LABOR
+3239;3239;3239;0028 4EE3 0029;0028 4EE3 0029; # (㈹; ㈹; ㈹; (代); (代); ) PARENTHESIZED IDEOGRAPH REPRESENT
+323A;323A;323A;0028 547C 0029;0028 547C 0029; # (㈺; ㈺; ㈺; (呼); (呼); ) PARENTHESIZED IDEOGRAPH CALL
+323B;323B;323B;0028 5B66 0029;0028 5B66 0029; # (㈻; ㈻; ㈻; (学); (学); ) PARENTHESIZED IDEOGRAPH STUDY
+323C;323C;323C;0028 76E3 0029;0028 76E3 0029; # (㈼; ㈼; ㈼; (監); (監); ) PARENTHESIZED IDEOGRAPH SUPERVISE
+323D;323D;323D;0028 4F01 0029;0028 4F01 0029; # (㈽; ㈽; ㈽; (企); (企); ) PARENTHESIZED IDEOGRAPH ENTERPRISE
+323E;323E;323E;0028 8CC7 0029;0028 8CC7 0029; # (㈾; ㈾; ㈾; (資); (資); ) PARENTHESIZED IDEOGRAPH RESOURCE
+323F;323F;323F;0028 5354 0029;0028 5354 0029; # (㈿; ㈿; ㈿; (協); (協); ) PARENTHESIZED IDEOGRAPH ALLIANCE
+3240;3240;3240;0028 796D 0029;0028 796D 0029; # (㉀; ㉀; ㉀; (祭); (祭); ) PARENTHESIZED IDEOGRAPH FESTIVAL
+3241;3241;3241;0028 4F11 0029;0028 4F11 0029; # (㉁; ㉁; ㉁; (休); (休); ) PARENTHESIZED IDEOGRAPH REST
+3242;3242;3242;0028 81EA 0029;0028 81EA 0029; # (㉂; ㉂; ㉂; (自); (自); ) PARENTHESIZED IDEOGRAPH SELF
+3243;3243;3243;0028 81F3 0029;0028 81F3 0029; # (㉃; ㉃; ㉃; (至); (至); ) PARENTHESIZED IDEOGRAPH REACH
+3244;3244;3244;554F;554F; # (㉄; ㉄; ㉄; 問; 問; ) CIRCLED IDEOGRAPH QUESTION
+3245;3245;3245;5E7C;5E7C; # (㉅; ㉅; ㉅; 幼; 幼; ) CIRCLED IDEOGRAPH KINDERGARTEN
+3246;3246;3246;6587;6587; # (㉆; ㉆; ㉆; 文; 文; ) CIRCLED IDEOGRAPH SCHOOL
+3247;3247;3247;7B8F;7B8F; # (㉇; ㉇; ㉇; 箏; 箏; ) CIRCLED IDEOGRAPH KOTO
+3250;3250;3250;0050 0054 0045;0050 0054 0045; # (㉐; ㉐; ㉐; PTE; PTE; ) PARTNERSHIP SIGN
+3251;3251;3251;0032 0031;0032 0031; # (㉑; ㉑; ㉑; 21; 21; ) CIRCLED NUMBER TWENTY ONE
+3252;3252;3252;0032 0032;0032 0032; # (㉒; ㉒; ㉒; 22; 22; ) CIRCLED NUMBER TWENTY TWO
+3253;3253;3253;0032 0033;0032 0033; # (㉓; ㉓; ㉓; 23; 23; ) CIRCLED NUMBER TWENTY THREE
+3254;3254;3254;0032 0034;0032 0034; # (㉔; ㉔; ㉔; 24; 24; ) CIRCLED NUMBER TWENTY FOUR
+3255;3255;3255;0032 0035;0032 0035; # (㉕; ㉕; ㉕; 25; 25; ) CIRCLED NUMBER TWENTY FIVE
+3256;3256;3256;0032 0036;0032 0036; # (㉖; ㉖; ㉖; 26; 26; ) CIRCLED NUMBER TWENTY SIX
+3257;3257;3257;0032 0037;0032 0037; # (㉗; ㉗; ㉗; 27; 27; ) CIRCLED NUMBER TWENTY SEVEN
+3258;3258;3258;0032 0038;0032 0038; # (㉘; ㉘; ㉘; 28; 28; ) CIRCLED NUMBER TWENTY EIGHT
+3259;3259;3259;0032 0039;0032 0039; # (㉙; ㉙; ㉙; 29; 29; ) CIRCLED NUMBER TWENTY NINE
+325A;325A;325A;0033 0030;0033 0030; # (㉚; ㉚; ㉚; 30; 30; ) CIRCLED NUMBER THIRTY
+325B;325B;325B;0033 0031;0033 0031; # (㉛; ㉛; ㉛; 31; 31; ) CIRCLED NUMBER THIRTY ONE
+325C;325C;325C;0033 0032;0033 0032; # (㉜; ㉜; ㉜; 32; 32; ) CIRCLED NUMBER THIRTY TWO
+325D;325D;325D;0033 0033;0033 0033; # (㉝; ㉝; ㉝; 33; 33; ) CIRCLED NUMBER THIRTY THREE
+325E;325E;325E;0033 0034;0033 0034; # (㉞; ㉞; ㉞; 34; 34; ) CIRCLED NUMBER THIRTY FOUR
+325F;325F;325F;0033 0035;0033 0035; # (㉟; ㉟; ㉟; 35; 35; ) CIRCLED NUMBER THIRTY FIVE
+3260;3260;3260;1100;1100; # (㉠; ㉠; ㉠; ᄀ; ᄀ; ) CIRCLED HANGUL KIYEOK
+3261;3261;3261;1102;1102; # (㉡; ㉡; ㉡; ᄂ; ᄂ; ) CIRCLED HANGUL NIEUN
+3262;3262;3262;1103;1103; # (㉢; ㉢; ㉢; ᄃ; ᄃ; ) CIRCLED HANGUL TIKEUT
+3263;3263;3263;1105;1105; # (㉣; ㉣; ㉣; ᄅ; ᄅ; ) CIRCLED HANGUL RIEUL
+3264;3264;3264;1106;1106; # (㉤; ㉤; ㉤; ᄆ; ᄆ; ) CIRCLED HANGUL MIEUM
+3265;3265;3265;1107;1107; # (㉥; ㉥; ㉥; ᄇ; ᄇ; ) CIRCLED HANGUL PIEUP
+3266;3266;3266;1109;1109; # (㉦; ㉦; ㉦; ᄉ; ᄉ; ) CIRCLED HANGUL SIOS
+3267;3267;3267;110B;110B; # (㉧; ㉧; ㉧; ᄋ; ᄋ; ) CIRCLED HANGUL IEUNG
+3268;3268;3268;110C;110C; # (㉨; ㉨; ㉨; ᄌ; ᄌ; ) CIRCLED HANGUL CIEUC
+3269;3269;3269;110E;110E; # (㉩; ㉩; ㉩; ᄎ; ᄎ; ) CIRCLED HANGUL CHIEUCH
+326A;326A;326A;110F;110F; # (㉪; ㉪; ㉪; ᄏ; ᄏ; ) CIRCLED HANGUL KHIEUKH
+326B;326B;326B;1110;1110; # (㉫; ㉫; ㉫; ᄐ; ᄐ; ) CIRCLED HANGUL THIEUTH
+326C;326C;326C;1111;1111; # (㉬; ㉬; ㉬; ᄑ; ᄑ; ) CIRCLED HANGUL PHIEUPH
+326D;326D;326D;1112;1112; # (㉭; ㉭; ㉭; ᄒ; ᄒ; ) CIRCLED HANGUL HIEUH
+326E;326E;326E;AC00;1100 1161; # (㉮; ㉮; ㉮; 가; 가; ) CIRCLED HANGUL KIYEOK A
+326F;326F;326F;B098;1102 1161; # (㉯; ㉯; ㉯; 나; 나; ) CIRCLED HANGUL NIEUN A
+3270;3270;3270;B2E4;1103 1161; # (㉰; ㉰; ㉰; 다; 다; ) CIRCLED HANGUL TIKEUT A
+3271;3271;3271;B77C;1105 1161; # (㉱; ㉱; ㉱; 라; 라; ) CIRCLED HANGUL RIEUL A
+3272;3272;3272;B9C8;1106 1161; # (㉲; ㉲; ㉲; 마; 마; ) CIRCLED HANGUL MIEUM A
+3273;3273;3273;BC14;1107 1161; # (㉳; ㉳; ㉳; 바; 바; ) CIRCLED HANGUL PIEUP A
+3274;3274;3274;C0AC;1109 1161; # (㉴; ㉴; ㉴; 사; 사; ) CIRCLED HANGUL SIOS A
+3275;3275;3275;C544;110B 1161; # (㉵; ㉵; ㉵; 아; 아; ) CIRCLED HANGUL IEUNG A
+3276;3276;3276;C790;110C 1161; # (㉶; ㉶; ㉶; 자; 자; ) CIRCLED HANGUL CIEUC A
+3277;3277;3277;CC28;110E 1161; # (㉷; ㉷; ㉷; 차; 차; ) CIRCLED HANGUL CHIEUCH A
+3278;3278;3278;CE74;110F 1161; # (㉸; ㉸; ㉸; 카; 카; ) CIRCLED HANGUL KHIEUKH A
+3279;3279;3279;D0C0;1110 1161; # (㉹; ㉹; ㉹; 타; 타; ) CIRCLED HANGUL THIEUTH A
+327A;327A;327A;D30C;1111 1161; # (㉺; ㉺; ㉺; 파; 파; ) CIRCLED HANGUL PHIEUPH A
+327B;327B;327B;D558;1112 1161; # (㉻; ㉻; ㉻; 하; 하; ) CIRCLED HANGUL HIEUH A
+327C;327C;327C;CC38 ACE0;110E 1161 11B7 1100 1169; # (㉼; ㉼; ㉼; 참고; 참고; ) CIRCLED KOREAN CHARACTER CHAMKO
+327D;327D;327D;C8FC C758;110C 116E 110B 1174; # (㉽; ㉽; ㉽; 주의; 주의; ) CIRCLED KOREAN CHARACTER JUEUI
+327E;327E;327E;C6B0;110B 116E; # (㉾; ㉾; ㉾; 우; 우; ) CIRCLED HANGUL IEUNG U
+3280;3280;3280;4E00;4E00; # (㊀; ㊀; ㊀; 一; 一; ) CIRCLED IDEOGRAPH ONE
+3281;3281;3281;4E8C;4E8C; # (㊁; ㊁; ㊁; 二; 二; ) CIRCLED IDEOGRAPH TWO
+3282;3282;3282;4E09;4E09; # (㊂; ㊂; ㊂; 三; 三; ) CIRCLED IDEOGRAPH THREE
+3283;3283;3283;56DB;56DB; # (㊃; ㊃; ㊃; 四; 四; ) CIRCLED IDEOGRAPH FOUR
+3284;3284;3284;4E94;4E94; # (㊄; ㊄; ㊄; 五; 五; ) CIRCLED IDEOGRAPH FIVE
+3285;3285;3285;516D;516D; # (㊅; ㊅; ㊅; 六; 六; ) CIRCLED IDEOGRAPH SIX
+3286;3286;3286;4E03;4E03; # (㊆; ㊆; ㊆; 七; 七; ) CIRCLED IDEOGRAPH SEVEN
+3287;3287;3287;516B;516B; # (㊇; ㊇; ㊇; 八; 八; ) CIRCLED IDEOGRAPH EIGHT
+3288;3288;3288;4E5D;4E5D; # (㊈; ㊈; ㊈; 九; 九; ) CIRCLED IDEOGRAPH NINE
+3289;3289;3289;5341;5341; # (㊉; ㊉; ㊉; 十; 十; ) CIRCLED IDEOGRAPH TEN
+328A;328A;328A;6708;6708; # (㊊; ㊊; ㊊; 月; 月; ) CIRCLED IDEOGRAPH MOON
+328B;328B;328B;706B;706B; # (㊋; ㊋; ㊋; 火; 火; ) CIRCLED IDEOGRAPH FIRE
+328C;328C;328C;6C34;6C34; # (㊌; ㊌; ㊌; 水; 水; ) CIRCLED IDEOGRAPH WATER
+328D;328D;328D;6728;6728; # (㊍; ㊍; ㊍; 木; 木; ) CIRCLED IDEOGRAPH WOOD
+328E;328E;328E;91D1;91D1; # (㊎; ㊎; ㊎; 金; 金; ) CIRCLED IDEOGRAPH METAL
+328F;328F;328F;571F;571F; # (㊏; ㊏; ㊏; 土; 土; ) CIRCLED IDEOGRAPH EARTH
+3290;3290;3290;65E5;65E5; # (㊐; ㊐; ㊐; 日; 日; ) CIRCLED IDEOGRAPH SUN
+3291;3291;3291;682A;682A; # (㊑; ㊑; ㊑; 株; 株; ) CIRCLED IDEOGRAPH STOCK
+3292;3292;3292;6709;6709; # (㊒; ㊒; ㊒; 有; 有; ) CIRCLED IDEOGRAPH HAVE
+3293;3293;3293;793E;793E; # (㊓; ㊓; ㊓; 社; 社; ) CIRCLED IDEOGRAPH SOCIETY
+3294;3294;3294;540D;540D; # (㊔; ㊔; ㊔; 名; 名; ) CIRCLED IDEOGRAPH NAME
+3295;3295;3295;7279;7279; # (㊕; ㊕; ㊕; 特; 特; ) CIRCLED IDEOGRAPH SPECIAL
+3296;3296;3296;8CA1;8CA1; # (㊖; ㊖; ㊖; 財; 財; ) CIRCLED IDEOGRAPH FINANCIAL
+3297;3297;3297;795D;795D; # (㊗; ㊗; ㊗; 祝; 祝; ) CIRCLED IDEOGRAPH CONGRATULATION
+3298;3298;3298;52B4;52B4; # (㊘; ㊘; ㊘; 労; 労; ) CIRCLED IDEOGRAPH LABOR
+3299;3299;3299;79D8;79D8; # (㊙; ㊙; ㊙; 秘; 秘; ) CIRCLED IDEOGRAPH SECRET
+329A;329A;329A;7537;7537; # (㊚; ㊚; ㊚; 男; 男; ) CIRCLED IDEOGRAPH MALE
+329B;329B;329B;5973;5973; # (㊛; ㊛; ㊛; 女; 女; ) CIRCLED IDEOGRAPH FEMALE
+329C;329C;329C;9069;9069; # (㊜; ㊜; ㊜; 適; 適; ) CIRCLED IDEOGRAPH SUITABLE
+329D;329D;329D;512A;512A; # (㊝; ㊝; ㊝; 優; 優; ) CIRCLED IDEOGRAPH EXCELLENT
+329E;329E;329E;5370;5370; # (㊞; ㊞; ㊞; 印; 印; ) CIRCLED IDEOGRAPH PRINT
+329F;329F;329F;6CE8;6CE8; # (㊟; ㊟; ㊟; 注; 注; ) CIRCLED IDEOGRAPH ATTENTION
+32A0;32A0;32A0;9805;9805; # (㊠; ㊠; ㊠; 項; 項; ) CIRCLED IDEOGRAPH ITEM
+32A1;32A1;32A1;4F11;4F11; # (㊡; ㊡; ㊡; 休; 休; ) CIRCLED IDEOGRAPH REST
+32A2;32A2;32A2;5199;5199; # (㊢; ㊢; ㊢; 写; 写; ) CIRCLED IDEOGRAPH COPY
+32A3;32A3;32A3;6B63;6B63; # (㊣; ㊣; ㊣; 正; 正; ) CIRCLED IDEOGRAPH CORRECT
+32A4;32A4;32A4;4E0A;4E0A; # (㊤; ㊤; ㊤; 上; 上; ) CIRCLED IDEOGRAPH HIGH
+32A5;32A5;32A5;4E2D;4E2D; # (㊥; ㊥; ㊥; 中; 中; ) CIRCLED IDEOGRAPH CENTRE
+32A6;32A6;32A6;4E0B;4E0B; # (㊦; ㊦; ㊦; 下; 下; ) CIRCLED IDEOGRAPH LOW
+32A7;32A7;32A7;5DE6;5DE6; # (㊧; ㊧; ㊧; 左; 左; ) CIRCLED IDEOGRAPH LEFT
+32A8;32A8;32A8;53F3;53F3; # (㊨; ㊨; ㊨; 右; 右; ) CIRCLED IDEOGRAPH RIGHT
+32A9;32A9;32A9;533B;533B; # (㊩; ㊩; ㊩; 医; 医; ) CIRCLED IDEOGRAPH MEDICINE
+32AA;32AA;32AA;5B97;5B97; # (㊪; ㊪; ㊪; 宗; 宗; ) CIRCLED IDEOGRAPH RELIGION
+32AB;32AB;32AB;5B66;5B66; # (㊫; ㊫; ㊫; 学; 学; ) CIRCLED IDEOGRAPH STUDY
+32AC;32AC;32AC;76E3;76E3; # (㊬; ㊬; ㊬; 監; 監; ) CIRCLED IDEOGRAPH SUPERVISE
+32AD;32AD;32AD;4F01;4F01; # (㊭; ㊭; ㊭; 企; 企; ) CIRCLED IDEOGRAPH ENTERPRISE
+32AE;32AE;32AE;8CC7;8CC7; # (㊮; ㊮; ㊮; 資; 資; ) CIRCLED IDEOGRAPH RESOURCE
+32AF;32AF;32AF;5354;5354; # (㊯; ㊯; ㊯; 協; 協; ) CIRCLED IDEOGRAPH ALLIANCE
+32B0;32B0;32B0;591C;591C; # (㊰; ㊰; ㊰; 夜; 夜; ) CIRCLED IDEOGRAPH NIGHT
+32B1;32B1;32B1;0033 0036;0033 0036; # (㊱; ㊱; ㊱; 36; 36; ) CIRCLED NUMBER THIRTY SIX
+32B2;32B2;32B2;0033 0037;0033 0037; # (㊲; ㊲; ㊲; 37; 37; ) CIRCLED NUMBER THIRTY SEVEN
+32B3;32B3;32B3;0033 0038;0033 0038; # (㊳; ㊳; ㊳; 38; 38; ) CIRCLED NUMBER THIRTY EIGHT
+32B4;32B4;32B4;0033 0039;0033 0039; # (㊴; ㊴; ㊴; 39; 39; ) CIRCLED NUMBER THIRTY NINE
+32B5;32B5;32B5;0034 0030;0034 0030; # (㊵; ㊵; ㊵; 40; 40; ) CIRCLED NUMBER FORTY
+32B6;32B6;32B6;0034 0031;0034 0031; # (㊶; ㊶; ㊶; 41; 41; ) CIRCLED NUMBER FORTY ONE
+32B7;32B7;32B7;0034 0032;0034 0032; # (㊷; ㊷; ㊷; 42; 42; ) CIRCLED NUMBER FORTY TWO
+32B8;32B8;32B8;0034 0033;0034 0033; # (㊸; ㊸; ㊸; 43; 43; ) CIRCLED NUMBER FORTY THREE
+32B9;32B9;32B9;0034 0034;0034 0034; # (㊹; ㊹; ㊹; 44; 44; ) CIRCLED NUMBER FORTY FOUR
+32BA;32BA;32BA;0034 0035;0034 0035; # (㊺; ㊺; ㊺; 45; 45; ) CIRCLED NUMBER FORTY FIVE
+32BB;32BB;32BB;0034 0036;0034 0036; # (㊻; ㊻; ㊻; 46; 46; ) CIRCLED NUMBER FORTY SIX
+32BC;32BC;32BC;0034 0037;0034 0037; # (㊼; ㊼; ㊼; 47; 47; ) CIRCLED NUMBER FORTY SEVEN
+32BD;32BD;32BD;0034 0038;0034 0038; # (㊽; ㊽; ㊽; 48; 48; ) CIRCLED NUMBER FORTY EIGHT
+32BE;32BE;32BE;0034 0039;0034 0039; # (㊾; ㊾; ㊾; 49; 49; ) CIRCLED NUMBER FORTY NINE
+32BF;32BF;32BF;0035 0030;0035 0030; # (㊿; ㊿; ㊿; 50; 50; ) CIRCLED NUMBER FIFTY
+32C0;32C0;32C0;0031 6708;0031 6708; # (㋀; ㋀; ㋀; 1月; 1月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY
+32C1;32C1;32C1;0032 6708;0032 6708; # (㋁; ㋁; ㋁; 2月; 2月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY
+32C2;32C2;32C2;0033 6708;0033 6708; # (㋂; ㋂; ㋂; 3月; 3月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH
+32C3;32C3;32C3;0034 6708;0034 6708; # (㋃; ㋃; ㋃; 4月; 4月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL
+32C4;32C4;32C4;0035 6708;0035 6708; # (㋄; ㋄; ㋄; 5月; 5月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY
+32C5;32C5;32C5;0036 6708;0036 6708; # (㋅; ㋅; ㋅; 6月; 6月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE
+32C6;32C6;32C6;0037 6708;0037 6708; # (㋆; ㋆; ㋆; 7月; 7月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY
+32C7;32C7;32C7;0038 6708;0038 6708; # (㋇; ㋇; ㋇; 8月; 8月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST
+32C8;32C8;32C8;0039 6708;0039 6708; # (㋈; ㋈; ㋈; 9月; 9月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER
+32C9;32C9;32C9;0031 0030 6708;0031 0030 6708; # (㋉; ㋉; ㋉; 10月; 10月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER
+32CA;32CA;32CA;0031 0031 6708;0031 0031 6708; # (㋊; ㋊; ㋊; 11月; 11月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER
+32CB;32CB;32CB;0031 0032 6708;0031 0032 6708; # (㋋; ㋋; ㋋; 12月; 12月; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER
+32CC;32CC;32CC;0048 0067;0048 0067; # (㋌; ㋌; ㋌; Hg; Hg; ) SQUARE HG
+32CD;32CD;32CD;0065 0072 0067;0065 0072 0067; # (㋍; ㋍; ㋍; erg; erg; ) SQUARE ERG
+32CE;32CE;32CE;0065 0056;0065 0056; # (㋎; ㋎; ㋎; eV; eV; ) SQUARE EV
+32CF;32CF;32CF;004C 0054 0044;004C 0054 0044; # (㋏; ㋏; ㋏; LTD; LTD; ) LIMITED LIABILITY SIGN
+32D0;32D0;32D0;30A2;30A2; # (㋐; ㋐; ㋐; ア; ア; ) CIRCLED KATAKANA A
+32D1;32D1;32D1;30A4;30A4; # (㋑; ㋑; ㋑; イ; イ; ) CIRCLED KATAKANA I
+32D2;32D2;32D2;30A6;30A6; # (㋒; ㋒; ㋒; ウ; ウ; ) CIRCLED KATAKANA U
+32D3;32D3;32D3;30A8;30A8; # (㋓; ㋓; ㋓; エ; エ; ) CIRCLED KATAKANA E
+32D4;32D4;32D4;30AA;30AA; # (㋔; ㋔; ㋔; オ; オ; ) CIRCLED KATAKANA O
+32D5;32D5;32D5;30AB;30AB; # (㋕; ㋕; ㋕; カ; カ; ) CIRCLED KATAKANA KA
+32D6;32D6;32D6;30AD;30AD; # (㋖; ㋖; ㋖; キ; キ; ) CIRCLED KATAKANA KI
+32D7;32D7;32D7;30AF;30AF; # (㋗; ㋗; ㋗; ク; ク; ) CIRCLED KATAKANA KU
+32D8;32D8;32D8;30B1;30B1; # (㋘; ㋘; ㋘; ケ; ケ; ) CIRCLED KATAKANA KE
+32D9;32D9;32D9;30B3;30B3; # (㋙; ㋙; ㋙; コ; コ; ) CIRCLED KATAKANA KO
+32DA;32DA;32DA;30B5;30B5; # (㋚; ㋚; ㋚; サ; サ; ) CIRCLED KATAKANA SA
+32DB;32DB;32DB;30B7;30B7; # (㋛; ㋛; ㋛; シ; シ; ) CIRCLED KATAKANA SI
+32DC;32DC;32DC;30B9;30B9; # (㋜; ㋜; ㋜; ス; ス; ) CIRCLED KATAKANA SU
+32DD;32DD;32DD;30BB;30BB; # (㋝; ㋝; ㋝; セ; セ; ) CIRCLED KATAKANA SE
+32DE;32DE;32DE;30BD;30BD; # (㋞; ㋞; ㋞; ソ; ソ; ) CIRCLED KATAKANA SO
+32DF;32DF;32DF;30BF;30BF; # (㋟; ㋟; ㋟; タ; タ; ) CIRCLED KATAKANA TA
+32E0;32E0;32E0;30C1;30C1; # (㋠; ㋠; ㋠; チ; チ; ) CIRCLED KATAKANA TI
+32E1;32E1;32E1;30C4;30C4; # (㋡; ㋡; ㋡; ツ; ツ; ) CIRCLED KATAKANA TU
+32E2;32E2;32E2;30C6;30C6; # (㋢; ㋢; ㋢; テ; テ; ) CIRCLED KATAKANA TE
+32E3;32E3;32E3;30C8;30C8; # (㋣; ㋣; ㋣; ト; ト; ) CIRCLED KATAKANA TO
+32E4;32E4;32E4;30CA;30CA; # (㋤; ㋤; ㋤; ナ; ナ; ) CIRCLED KATAKANA NA
+32E5;32E5;32E5;30CB;30CB; # (㋥; ㋥; ㋥; ニ; ニ; ) CIRCLED KATAKANA NI
+32E6;32E6;32E6;30CC;30CC; # (㋦; ㋦; ㋦; ヌ; ヌ; ) CIRCLED KATAKANA NU
+32E7;32E7;32E7;30CD;30CD; # (㋧; ㋧; ㋧; ネ; ネ; ) CIRCLED KATAKANA NE
+32E8;32E8;32E8;30CE;30CE; # (㋨; ㋨; ㋨; ノ; ノ; ) CIRCLED KATAKANA NO
+32E9;32E9;32E9;30CF;30CF; # (㋩; ㋩; ㋩; ハ; ハ; ) CIRCLED KATAKANA HA
+32EA;32EA;32EA;30D2;30D2; # (㋪; ㋪; ㋪; ヒ; ヒ; ) CIRCLED KATAKANA HI
+32EB;32EB;32EB;30D5;30D5; # (㋫; ㋫; ㋫; フ; フ; ) CIRCLED KATAKANA HU
+32EC;32EC;32EC;30D8;30D8; # (㋬; ㋬; ㋬; ヘ; ヘ; ) CIRCLED KATAKANA HE
+32ED;32ED;32ED;30DB;30DB; # (㋭; ㋭; ㋭; ホ; ホ; ) CIRCLED KATAKANA HO
+32EE;32EE;32EE;30DE;30DE; # (㋮; ㋮; ㋮; マ; マ; ) CIRCLED KATAKANA MA
+32EF;32EF;32EF;30DF;30DF; # (㋯; ㋯; ㋯; ミ; ミ; ) CIRCLED KATAKANA MI
+32F0;32F0;32F0;30E0;30E0; # (㋰; ㋰; ㋰; ム; ム; ) CIRCLED KATAKANA MU
+32F1;32F1;32F1;30E1;30E1; # (㋱; ㋱; ㋱; メ; メ; ) CIRCLED KATAKANA ME
+32F2;32F2;32F2;30E2;30E2; # (㋲; ㋲; ㋲; モ; モ; ) CIRCLED KATAKANA MO
+32F3;32F3;32F3;30E4;30E4; # (㋳; ㋳; ㋳; ヤ; ヤ; ) CIRCLED KATAKANA YA
+32F4;32F4;32F4;30E6;30E6; # (㋴; ㋴; ㋴; ユ; ユ; ) CIRCLED KATAKANA YU
+32F5;32F5;32F5;30E8;30E8; # (㋵; ㋵; ㋵; ヨ; ヨ; ) CIRCLED KATAKANA YO
+32F6;32F6;32F6;30E9;30E9; # (㋶; ㋶; ㋶; ラ; ラ; ) CIRCLED KATAKANA RA
+32F7;32F7;32F7;30EA;30EA; # (㋷; ㋷; ㋷; リ; リ; ) CIRCLED KATAKANA RI
+32F8;32F8;32F8;30EB;30EB; # (㋸; ㋸; ㋸; ル; ル; ) CIRCLED KATAKANA RU
+32F9;32F9;32F9;30EC;30EC; # (㋹; ㋹; ㋹; レ; レ; ) CIRCLED KATAKANA RE
+32FA;32FA;32FA;30ED;30ED; # (㋺; ㋺; ㋺; ロ; ロ; ) CIRCLED KATAKANA RO
+32FB;32FB;32FB;30EF;30EF; # (㋻; ㋻; ㋻; ワ; ワ; ) CIRCLED KATAKANA WA
+32FC;32FC;32FC;30F0;30F0; # (㋼; ㋼; ㋼; ヰ; ヰ; ) CIRCLED KATAKANA WI
+32FD;32FD;32FD;30F1;30F1; # (㋽; ㋽; ㋽; ヱ; ヱ; ) CIRCLED KATAKANA WE
+32FE;32FE;32FE;30F2;30F2; # (㋾; ㋾; ㋾; ヲ; ヲ; ) CIRCLED KATAKANA WO
+3300;3300;3300;30A2 30D1 30FC 30C8;30A2 30CF 309A 30FC 30C8; # (㌀; ㌀; ㌀; アパート; アハ◌゚ート; ) SQUARE APAATO
+3301;3301;3301;30A2 30EB 30D5 30A1;30A2 30EB 30D5 30A1; # (㌁; ㌁; ㌁; アルファ; アルファ; ) SQUARE ARUHUA
+3302;3302;3302;30A2 30F3 30DA 30A2;30A2 30F3 30D8 309A 30A2; # (㌂; ㌂; ㌂; アンペア; アンヘ◌゚ア; ) SQUARE ANPEA
+3303;3303;3303;30A2 30FC 30EB;30A2 30FC 30EB; # (㌃; ㌃; ㌃; アール; アール; ) SQUARE AARU
+3304;3304;3304;30A4 30CB 30F3 30B0;30A4 30CB 30F3 30AF 3099; # (㌄; ㌄; ㌄; イニング; イニンク◌゙; ) SQUARE ININGU
+3305;3305;3305;30A4 30F3 30C1;30A4 30F3 30C1; # (㌅; ㌅; ㌅; インチ; インチ; ) SQUARE INTI
+3306;3306;3306;30A6 30A9 30F3;30A6 30A9 30F3; # (㌆; ㌆; ㌆; ウォン; ウォン; ) SQUARE UON
+3307;3307;3307;30A8 30B9 30AF 30FC 30C9;30A8 30B9 30AF 30FC 30C8 3099; # (㌇; ㌇; ㌇; エスクード; エスクート◌゙; ) SQUARE ESUKUUDO
+3308;3308;3308;30A8 30FC 30AB 30FC;30A8 30FC 30AB 30FC; # (㌈; ㌈; ㌈; エーカー; エーカー; ) SQUARE EEKAA
+3309;3309;3309;30AA 30F3 30B9;30AA 30F3 30B9; # (㌉; ㌉; ㌉; オンス; オンス; ) SQUARE ONSU
+330A;330A;330A;30AA 30FC 30E0;30AA 30FC 30E0; # (㌊; ㌊; ㌊; オーム; オーム; ) SQUARE OOMU
+330B;330B;330B;30AB 30A4 30EA;30AB 30A4 30EA; # (㌋; ㌋; ㌋; カイリ; カイリ; ) SQUARE KAIRI
+330C;330C;330C;30AB 30E9 30C3 30C8;30AB 30E9 30C3 30C8; # (㌌; ㌌; ㌌; カラット; カラット; ) SQUARE KARATTO
+330D;330D;330D;30AB 30ED 30EA 30FC;30AB 30ED 30EA 30FC; # (㌍; ㌍; ㌍; カロリー; カロリー; ) SQUARE KARORII
+330E;330E;330E;30AC 30ED 30F3;30AB 3099 30ED 30F3; # (㌎; ㌎; ㌎; ガロン; カ◌゙ロン; ) SQUARE GARON
+330F;330F;330F;30AC 30F3 30DE;30AB 3099 30F3 30DE; # (㌏; ㌏; ㌏; ガンマ; カ◌゙ンマ; ) SQUARE GANMA
+3310;3310;3310;30AE 30AC;30AD 3099 30AB 3099; # (㌐; ㌐; ㌐; ギガ; キ◌゙カ◌゙; ) SQUARE GIGA
+3311;3311;3311;30AE 30CB 30FC;30AD 3099 30CB 30FC; # (㌑; ㌑; ㌑; ギニー; キ◌゙ニー; ) SQUARE GINII
+3312;3312;3312;30AD 30E5 30EA 30FC;30AD 30E5 30EA 30FC; # (㌒; ㌒; ㌒; キュリー; キュリー; ) SQUARE KYURII
+3313;3313;3313;30AE 30EB 30C0 30FC;30AD 3099 30EB 30BF 3099 30FC; # (㌓; ㌓; ㌓; ギルダー; キ◌゙ルタ◌゙ー; ) SQUARE GIRUDAA
+3314;3314;3314;30AD 30ED;30AD 30ED; # (㌔; ㌔; ㌔; キロ; キロ; ) SQUARE KIRO
+3315;3315;3315;30AD 30ED 30B0 30E9 30E0;30AD 30ED 30AF 3099 30E9 30E0; # (㌕; ㌕; ㌕; キログラム; キロク◌゙ラム; ) SQUARE KIROGURAMU
+3316;3316;3316;30AD 30ED 30E1 30FC 30C8 30EB;30AD 30ED 30E1 30FC 30C8 30EB; # (㌖; ㌖; ㌖; キロメートル; キロメートル; ) SQUARE KIROMEETORU
+3317;3317;3317;30AD 30ED 30EF 30C3 30C8;30AD 30ED 30EF 30C3 30C8; # (㌗; ㌗; ㌗; キロワット; キロワット; ) SQUARE KIROWATTO
+3318;3318;3318;30B0 30E9 30E0;30AF 3099 30E9 30E0; # (㌘; ㌘; ㌘; グラム; ク◌゙ラム; ) SQUARE GURAMU
+3319;3319;3319;30B0 30E9 30E0 30C8 30F3;30AF 3099 30E9 30E0 30C8 30F3; # (㌙; ㌙; ㌙; グラムトン; ク◌゙ラムトン; ) SQUARE GURAMUTON
+331A;331A;331A;30AF 30EB 30BC 30A4 30ED;30AF 30EB 30BB 3099 30A4 30ED; # (㌚; ㌚; ㌚; クルゼイロ; クルセ◌゙イロ; ) SQUARE KURUZEIRO
+331B;331B;331B;30AF 30ED 30FC 30CD;30AF 30ED 30FC 30CD; # (㌛; ㌛; ㌛; クローネ; クローネ; ) SQUARE KUROONE
+331C;331C;331C;30B1 30FC 30B9;30B1 30FC 30B9; # (㌜; ㌜; ㌜; ケース; ケース; ) SQUARE KEESU
+331D;331D;331D;30B3 30EB 30CA;30B3 30EB 30CA; # (㌝; ㌝; ㌝; コルナ; コルナ; ) SQUARE KORUNA
+331E;331E;331E;30B3 30FC 30DD;30B3 30FC 30DB 309A; # (㌞; ㌞; ㌞; コーポ; コーホ◌゚; ) SQUARE KOOPO
+331F;331F;331F;30B5 30A4 30AF 30EB;30B5 30A4 30AF 30EB; # (㌟; ㌟; ㌟; サイクル; サイクル; ) SQUARE SAIKURU
+3320;3320;3320;30B5 30F3 30C1 30FC 30E0;30B5 30F3 30C1 30FC 30E0; # (㌠; ㌠; ㌠; サンチーム; サンチーム; ) SQUARE SANTIIMU
+3321;3321;3321;30B7 30EA 30F3 30B0;30B7 30EA 30F3 30AF 3099; # (㌡; ㌡; ㌡; シリング; シリンク◌゙; ) SQUARE SIRINGU
+3322;3322;3322;30BB 30F3 30C1;30BB 30F3 30C1; # (㌢; ㌢; ㌢; センチ; センチ; ) SQUARE SENTI
+3323;3323;3323;30BB 30F3 30C8;30BB 30F3 30C8; # (㌣; ㌣; ㌣; セント; セント; ) SQUARE SENTO
+3324;3324;3324;30C0 30FC 30B9;30BF 3099 30FC 30B9; # (㌤; ㌤; ㌤; ダース; タ◌゙ース; ) SQUARE DAASU
+3325;3325;3325;30C7 30B7;30C6 3099 30B7; # (㌥; ㌥; ㌥; デシ; テ◌゙シ; ) SQUARE DESI
+3326;3326;3326;30C9 30EB;30C8 3099 30EB; # (㌦; ㌦; ㌦; ドル; ト◌゙ル; ) SQUARE DORU
+3327;3327;3327;30C8 30F3;30C8 30F3; # (㌧; ㌧; ㌧; トン; トン; ) SQUARE TON
+3328;3328;3328;30CA 30CE;30CA 30CE; # (㌨; ㌨; ㌨; ナノ; ナノ; ) SQUARE NANO
+3329;3329;3329;30CE 30C3 30C8;30CE 30C3 30C8; # (㌩; ㌩; ㌩; ノット; ノット; ) SQUARE NOTTO
+332A;332A;332A;30CF 30A4 30C4;30CF 30A4 30C4; # (㌪; ㌪; ㌪; ハイツ; ハイツ; ) SQUARE HAITU
+332B;332B;332B;30D1 30FC 30BB 30F3 30C8;30CF 309A 30FC 30BB 30F3 30C8; # (㌫; ㌫; ㌫; パーセント; ハ◌゚ーセント; ) SQUARE PAASENTO
+332C;332C;332C;30D1 30FC 30C4;30CF 309A 30FC 30C4; # (㌬; ㌬; ㌬; パーツ; ハ◌゚ーツ; ) SQUARE PAATU
+332D;332D;332D;30D0 30FC 30EC 30EB;30CF 3099 30FC 30EC 30EB; # (㌭; ㌭; ㌭; バーレル; ハ◌゙ーレル; ) SQUARE BAARERU
+332E;332E;332E;30D4 30A2 30B9 30C8 30EB;30D2 309A 30A2 30B9 30C8 30EB; # (㌮; ㌮; ㌮; ピアストル; ヒ◌゚アストル; ) SQUARE PIASUTORU
+332F;332F;332F;30D4 30AF 30EB;30D2 309A 30AF 30EB; # (㌯; ㌯; ㌯; ピクル; ヒ◌゚クル; ) SQUARE PIKURU
+3330;3330;3330;30D4 30B3;30D2 309A 30B3; # (㌰; ㌰; ㌰; ピコ; ヒ◌゚コ; ) SQUARE PIKO
+3331;3331;3331;30D3 30EB;30D2 3099 30EB; # (㌱; ㌱; ㌱; ビル; ヒ◌゙ル; ) SQUARE BIRU
+3332;3332;3332;30D5 30A1 30E9 30C3 30C9;30D5 30A1 30E9 30C3 30C8 3099; # (㌲; ㌲; ㌲; ファラッド; ファラット◌゙; ) SQUARE HUARADDO
+3333;3333;3333;30D5 30A3 30FC 30C8;30D5 30A3 30FC 30C8; # (㌳; ㌳; ㌳; フィート; フィート; ) SQUARE HUIITO
+3334;3334;3334;30D6 30C3 30B7 30A7 30EB;30D5 3099 30C3 30B7 30A7 30EB; # (㌴; ㌴; ㌴; ブッシェル; フ◌゙ッシェル; ) SQUARE BUSSYERU
+3335;3335;3335;30D5 30E9 30F3;30D5 30E9 30F3; # (㌵; ㌵; ㌵; フラン; フラン; ) SQUARE HURAN
+3336;3336;3336;30D8 30AF 30BF 30FC 30EB;30D8 30AF 30BF 30FC 30EB; # (㌶; ㌶; ㌶; ヘクタール; ヘクタール; ) SQUARE HEKUTAARU
+3337;3337;3337;30DA 30BD;30D8 309A 30BD; # (㌷; ㌷; ㌷; ペソ; ヘ◌゚ソ; ) SQUARE PESO
+3338;3338;3338;30DA 30CB 30D2;30D8 309A 30CB 30D2; # (㌸; ㌸; ㌸; ペニヒ; ヘ◌゚ニヒ; ) SQUARE PENIHI
+3339;3339;3339;30D8 30EB 30C4;30D8 30EB 30C4; # (㌹; ㌹; ㌹; ヘルツ; ヘルツ; ) SQUARE HERUTU
+333A;333A;333A;30DA 30F3 30B9;30D8 309A 30F3 30B9; # (㌺; ㌺; ㌺; ペンス; ヘ◌゚ンス; ) SQUARE PENSU
+333B;333B;333B;30DA 30FC 30B8;30D8 309A 30FC 30B7 3099; # (㌻; ㌻; ㌻; ページ; ヘ◌゚ーシ◌゙; ) SQUARE PEEZI
+333C;333C;333C;30D9 30FC 30BF;30D8 3099 30FC 30BF; # (㌼; ㌼; ㌼; ベータ; ヘ◌゙ータ; ) SQUARE BEETA
+333D;333D;333D;30DD 30A4 30F3 30C8;30DB 309A 30A4 30F3 30C8; # (㌽; ㌽; ㌽; ポイント; ホ◌゚イント; ) SQUARE POINTO
+333E;333E;333E;30DC 30EB 30C8;30DB 3099 30EB 30C8; # (㌾; ㌾; ㌾; ボルト; ホ◌゙ルト; ) SQUARE BORUTO
+333F;333F;333F;30DB 30F3;30DB 30F3; # (㌿; ㌿; ㌿; ホン; ホン; ) SQUARE HON
+3340;3340;3340;30DD 30F3 30C9;30DB 309A 30F3 30C8 3099; # (㍀; ㍀; ㍀; ポンド; ホ◌゚ント◌゙; ) SQUARE PONDO
+3341;3341;3341;30DB 30FC 30EB;30DB 30FC 30EB; # (㍁; ㍁; ㍁; ホール; ホール; ) SQUARE HOORU
+3342;3342;3342;30DB 30FC 30F3;30DB 30FC 30F3; # (㍂; ㍂; ㍂; ホーン; ホーン; ) SQUARE HOON
+3343;3343;3343;30DE 30A4 30AF 30ED;30DE 30A4 30AF 30ED; # (㍃; ㍃; ㍃; マイクロ; マイクロ; ) SQUARE MAIKURO
+3344;3344;3344;30DE 30A4 30EB;30DE 30A4 30EB; # (㍄; ㍄; ㍄; マイル; マイル; ) SQUARE MAIRU
+3345;3345;3345;30DE 30C3 30CF;30DE 30C3 30CF; # (㍅; ㍅; ㍅; マッハ; マッハ; ) SQUARE MAHHA
+3346;3346;3346;30DE 30EB 30AF;30DE 30EB 30AF; # (㍆; ㍆; ㍆; マルク; マルク; ) SQUARE MARUKU
+3347;3347;3347;30DE 30F3 30B7 30E7 30F3;30DE 30F3 30B7 30E7 30F3; # (㍇; ㍇; ㍇; マンション; マンション; ) SQUARE MANSYON
+3348;3348;3348;30DF 30AF 30ED 30F3;30DF 30AF 30ED 30F3; # (㍈; ㍈; ㍈; ミクロン; ミクロン; ) SQUARE MIKURON
+3349;3349;3349;30DF 30EA;30DF 30EA; # (㍉; ㍉; ㍉; ミリ; ミリ; ) SQUARE MIRI
+334A;334A;334A;30DF 30EA 30D0 30FC 30EB;30DF 30EA 30CF 3099 30FC 30EB; # (㍊; ㍊; ㍊; ミリバール; ミリハ◌゙ール; ) SQUARE MIRIBAARU
+334B;334B;334B;30E1 30AC;30E1 30AB 3099; # (㍋; ㍋; ㍋; メガ; メカ◌゙; ) SQUARE MEGA
+334C;334C;334C;30E1 30AC 30C8 30F3;30E1 30AB 3099 30C8 30F3; # (㍌; ㍌; ㍌; メガトン; メカ◌゙トン; ) SQUARE MEGATON
+334D;334D;334D;30E1 30FC 30C8 30EB;30E1 30FC 30C8 30EB; # (㍍; ㍍; ㍍; メートル; メートル; ) SQUARE MEETORU
+334E;334E;334E;30E4 30FC 30C9;30E4 30FC 30C8 3099; # (㍎; ㍎; ㍎; ヤード; ヤート◌゙; ) SQUARE YAADO
+334F;334F;334F;30E4 30FC 30EB;30E4 30FC 30EB; # (㍏; ㍏; ㍏; ヤール; ヤール; ) SQUARE YAARU
+3350;3350;3350;30E6 30A2 30F3;30E6 30A2 30F3; # (㍐; ㍐; ㍐; ユアン; ユアン; ) SQUARE YUAN
+3351;3351;3351;30EA 30C3 30C8 30EB;30EA 30C3 30C8 30EB; # (㍑; ㍑; ㍑; リットル; リットル; ) SQUARE RITTORU
+3352;3352;3352;30EA 30E9;30EA 30E9; # (㍒; ㍒; ㍒; リラ; リラ; ) SQUARE RIRA
+3353;3353;3353;30EB 30D4 30FC;30EB 30D2 309A 30FC; # (㍓; ㍓; ㍓; ルピー; ルヒ◌゚ー; ) SQUARE RUPII
+3354;3354;3354;30EB 30FC 30D6 30EB;30EB 30FC 30D5 3099 30EB; # (㍔; ㍔; ㍔; ルーブル; ルーフ◌゙ル; ) SQUARE RUUBURU
+3355;3355;3355;30EC 30E0;30EC 30E0; # (㍕; ㍕; ㍕; レム; レム; ) SQUARE REMU
+3356;3356;3356;30EC 30F3 30C8 30B2 30F3;30EC 30F3 30C8 30B1 3099 30F3; # (㍖; ㍖; ㍖; レントゲン; レントケ◌゙ン; ) SQUARE RENTOGEN
+3357;3357;3357;30EF 30C3 30C8;30EF 30C3 30C8; # (㍗; ㍗; ㍗; ワット; ワット; ) SQUARE WATTO
+3358;3358;3358;0030 70B9;0030 70B9; # (㍘; ㍘; ㍘; 0点; 0点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO
+3359;3359;3359;0031 70B9;0031 70B9; # (㍙; ㍙; ㍙; 1点; 1点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE
+335A;335A;335A;0032 70B9;0032 70B9; # (㍚; ㍚; ㍚; 2点; 2点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO
+335B;335B;335B;0033 70B9;0033 70B9; # (㍛; ㍛; ㍛; 3点; 3点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE
+335C;335C;335C;0034 70B9;0034 70B9; # (㍜; ㍜; ㍜; 4点; 4点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR
+335D;335D;335D;0035 70B9;0035 70B9; # (㍝; ㍝; ㍝; 5点; 5点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE
+335E;335E;335E;0036 70B9;0036 70B9; # (㍞; ㍞; ㍞; 6点; 6点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX
+335F;335F;335F;0037 70B9;0037 70B9; # (㍟; ㍟; ㍟; 7点; 7点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN
+3360;3360;3360;0038 70B9;0038 70B9; # (㍠; ㍠; ㍠; 8点; 8点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT
+3361;3361;3361;0039 70B9;0039 70B9; # (㍡; ㍡; ㍡; 9点; 9点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE
+3362;3362;3362;0031 0030 70B9;0031 0030 70B9; # (㍢; ㍢; ㍢; 10点; 10点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN
+3363;3363;3363;0031 0031 70B9;0031 0031 70B9; # (㍣; ㍣; ㍣; 11点; 11点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN
+3364;3364;3364;0031 0032 70B9;0031 0032 70B9; # (㍤; ㍤; ㍤; 12点; 12点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE
+3365;3365;3365;0031 0033 70B9;0031 0033 70B9; # (㍥; ㍥; ㍥; 13点; 13点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN
+3366;3366;3366;0031 0034 70B9;0031 0034 70B9; # (㍦; ㍦; ㍦; 14点; 14点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN
+3367;3367;3367;0031 0035 70B9;0031 0035 70B9; # (㍧; ㍧; ㍧; 15点; 15点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN
+3368;3368;3368;0031 0036 70B9;0031 0036 70B9; # (㍨; ㍨; ㍨; 16点; 16点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN
+3369;3369;3369;0031 0037 70B9;0031 0037 70B9; # (㍩; ㍩; ㍩; 17点; 17点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN
+336A;336A;336A;0031 0038 70B9;0031 0038 70B9; # (㍪; ㍪; ㍪; 18点; 18点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN
+336B;336B;336B;0031 0039 70B9;0031 0039 70B9; # (㍫; ㍫; ㍫; 19点; 19点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN
+336C;336C;336C;0032 0030 70B9;0032 0030 70B9; # (㍬; ㍬; ㍬; 20点; 20点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY
+336D;336D;336D;0032 0031 70B9;0032 0031 70B9; # (㍭; ㍭; ㍭; 21点; 21点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE
+336E;336E;336E;0032 0032 70B9;0032 0032 70B9; # (㍮; ㍮; ㍮; 22点; 22点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO
+336F;336F;336F;0032 0033 70B9;0032 0033 70B9; # (㍯; ㍯; ㍯; 23点; 23点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE
+3370;3370;3370;0032 0034 70B9;0032 0034 70B9; # (㍰; ㍰; ㍰; 24点; 24点; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR
+3371;3371;3371;0068 0050 0061;0068 0050 0061; # (㍱; ㍱; ㍱; hPa; hPa; ) SQUARE HPA
+3372;3372;3372;0064 0061;0064 0061; # (㍲; ㍲; ㍲; da; da; ) SQUARE DA
+3373;3373;3373;0041 0055;0041 0055; # (㍳; ㍳; ㍳; AU; AU; ) SQUARE AU
+3374;3374;3374;0062 0061 0072;0062 0061 0072; # (㍴; ㍴; ㍴; bar; bar; ) SQUARE BAR
+3375;3375;3375;006F 0056;006F 0056; # (㍵; ㍵; ㍵; oV; oV; ) SQUARE OV
+3376;3376;3376;0070 0063;0070 0063; # (㍶; ㍶; ㍶; pc; pc; ) SQUARE PC
+3377;3377;3377;0064 006D;0064 006D; # (㍷; ㍷; ㍷; dm; dm; ) SQUARE DM
+3378;3378;3378;0064 006D 0032;0064 006D 0032; # (㍸; ㍸; ㍸; dm2; dm2; ) SQUARE DM SQUARED
+3379;3379;3379;0064 006D 0033;0064 006D 0033; # (㍹; ㍹; ㍹; dm3; dm3; ) SQUARE DM CUBED
+337A;337A;337A;0049 0055;0049 0055; # (㍺; ㍺; ㍺; IU; IU; ) SQUARE IU
+337B;337B;337B;5E73 6210;5E73 6210; # (㍻; ㍻; ㍻; 平成; 平成; ) SQUARE ERA NAME HEISEI
+337C;337C;337C;662D 548C;662D 548C; # (㍼; ㍼; ㍼; 昭和; 昭和; ) SQUARE ERA NAME SYOUWA
+337D;337D;337D;5927 6B63;5927 6B63; # (㍽; ㍽; ㍽; 大正; 大正; ) SQUARE ERA NAME TAISYOU
+337E;337E;337E;660E 6CBB;660E 6CBB; # (㍾; ㍾; ㍾; 明治; 明治; ) SQUARE ERA NAME MEIZI
+337F;337F;337F;682A 5F0F 4F1A 793E;682A 5F0F 4F1A 793E; # (㍿; ㍿; ㍿; 株式会社; 株式会社; ) SQUARE CORPORATION
+3380;3380;3380;0070 0041;0070 0041; # (㎀; ㎀; ㎀; pA; pA; ) SQUARE PA AMPS
+3381;3381;3381;006E 0041;006E 0041; # (㎁; ㎁; ㎁; nA; nA; ) SQUARE NA
+3382;3382;3382;03BC 0041;03BC 0041; # (㎂; ㎂; ㎂; μA; μA; ) SQUARE MU A
+3383;3383;3383;006D 0041;006D 0041; # (㎃; ㎃; ㎃; mA; mA; ) SQUARE MA
+3384;3384;3384;006B 0041;006B 0041; # (㎄; ㎄; ㎄; kA; kA; ) SQUARE KA
+3385;3385;3385;004B 0042;004B 0042; # (㎅; ㎅; ㎅; KB; KB; ) SQUARE KB
+3386;3386;3386;004D 0042;004D 0042; # (㎆; ㎆; ㎆; MB; MB; ) SQUARE MB
+3387;3387;3387;0047 0042;0047 0042; # (㎇; ㎇; ㎇; GB; GB; ) SQUARE GB
+3388;3388;3388;0063 0061 006C;0063 0061 006C; # (㎈; ㎈; ㎈; cal; cal; ) SQUARE CAL
+3389;3389;3389;006B 0063 0061 006C;006B 0063 0061 006C; # (㎉; ㎉; ㎉; kcal; kcal; ) SQUARE KCAL
+338A;338A;338A;0070 0046;0070 0046; # (㎊; ㎊; ㎊; pF; pF; ) SQUARE PF
+338B;338B;338B;006E 0046;006E 0046; # (㎋; ㎋; ㎋; nF; nF; ) SQUARE NF
+338C;338C;338C;03BC 0046;03BC 0046; # (㎌; ㎌; ㎌; μF; μF; ) SQUARE MU F
+338D;338D;338D;03BC 0067;03BC 0067; # (㎍; ㎍; ㎍; μg; μg; ) SQUARE MU G
+338E;338E;338E;006D 0067;006D 0067; # (㎎; ㎎; ㎎; mg; mg; ) SQUARE MG
+338F;338F;338F;006B 0067;006B 0067; # (㎏; ㎏; ㎏; kg; kg; ) SQUARE KG
+3390;3390;3390;0048 007A;0048 007A; # (㎐; ㎐; ㎐; Hz; Hz; ) SQUARE HZ
+3391;3391;3391;006B 0048 007A;006B 0048 007A; # (㎑; ㎑; ㎑; kHz; kHz; ) SQUARE KHZ
+3392;3392;3392;004D 0048 007A;004D 0048 007A; # (㎒; ㎒; ㎒; MHz; MHz; ) SQUARE MHZ
+3393;3393;3393;0047 0048 007A;0047 0048 007A; # (㎓; ㎓; ㎓; GHz; GHz; ) SQUARE GHZ
+3394;3394;3394;0054 0048 007A;0054 0048 007A; # (㎔; ㎔; ㎔; THz; THz; ) SQUARE THZ
+3395;3395;3395;03BC 006C;03BC 006C; # (㎕; ㎕; ㎕; μl; μl; ) SQUARE MU L
+3396;3396;3396;006D 006C;006D 006C; # (㎖; ㎖; ㎖; ml; ml; ) SQUARE ML
+3397;3397;3397;0064 006C;0064 006C; # (㎗; ㎗; ㎗; dl; dl; ) SQUARE DL
+3398;3398;3398;006B 006C;006B 006C; # (㎘; ㎘; ㎘; kl; kl; ) SQUARE KL
+3399;3399;3399;0066 006D;0066 006D; # (㎙; ㎙; ㎙; fm; fm; ) SQUARE FM
+339A;339A;339A;006E 006D;006E 006D; # (㎚; ㎚; ㎚; nm; nm; ) SQUARE NM
+339B;339B;339B;03BC 006D;03BC 006D; # (㎛; ㎛; ㎛; μm; μm; ) SQUARE MU M
+339C;339C;339C;006D 006D;006D 006D; # (㎜; ㎜; ㎜; mm; mm; ) SQUARE MM
+339D;339D;339D;0063 006D;0063 006D; # (㎝; ㎝; ㎝; cm; cm; ) SQUARE CM
+339E;339E;339E;006B 006D;006B 006D; # (㎞; ㎞; ㎞; km; km; ) SQUARE KM
+339F;339F;339F;006D 006D 0032;006D 006D 0032; # (㎟; ㎟; ㎟; mm2; mm2; ) SQUARE MM SQUARED
+33A0;33A0;33A0;0063 006D 0032;0063 006D 0032; # (㎠; ㎠; ㎠; cm2; cm2; ) SQUARE CM SQUARED
+33A1;33A1;33A1;006D 0032;006D 0032; # (㎡; ㎡; ㎡; m2; m2; ) SQUARE M SQUARED
+33A2;33A2;33A2;006B 006D 0032;006B 006D 0032; # (㎢; ㎢; ㎢; km2; km2; ) SQUARE KM SQUARED
+33A3;33A3;33A3;006D 006D 0033;006D 006D 0033; # (㎣; ㎣; ㎣; mm3; mm3; ) SQUARE MM CUBED
+33A4;33A4;33A4;0063 006D 0033;0063 006D 0033; # (㎤; ㎤; ㎤; cm3; cm3; ) SQUARE CM CUBED
+33A5;33A5;33A5;006D 0033;006D 0033; # (㎥; ㎥; ㎥; m3; m3; ) SQUARE M CUBED
+33A6;33A6;33A6;006B 006D 0033;006B 006D 0033; # (㎦; ㎦; ㎦; km3; km3; ) SQUARE KM CUBED
+33A7;33A7;33A7;006D 2215 0073;006D 2215 0073; # (㎧; ㎧; ㎧; m∕s; m∕s; ) SQUARE M OVER S
+33A8;33A8;33A8;006D 2215 0073 0032;006D 2215 0073 0032; # (㎨; ㎨; ㎨; m∕s2; m∕s2; ) SQUARE M OVER S SQUARED
+33A9;33A9;33A9;0050 0061;0050 0061; # (㎩; ㎩; ㎩; Pa; Pa; ) SQUARE PA
+33AA;33AA;33AA;006B 0050 0061;006B 0050 0061; # (㎪; ㎪; ㎪; kPa; kPa; ) SQUARE KPA
+33AB;33AB;33AB;004D 0050 0061;004D 0050 0061; # (㎫; ㎫; ㎫; MPa; MPa; ) SQUARE MPA
+33AC;33AC;33AC;0047 0050 0061;0047 0050 0061; # (㎬; ㎬; ㎬; GPa; GPa; ) SQUARE GPA
+33AD;33AD;33AD;0072 0061 0064;0072 0061 0064; # (㎭; ㎭; ㎭; rad; rad; ) SQUARE RAD
+33AE;33AE;33AE;0072 0061 0064 2215 0073;0072 0061 0064 2215 0073; # (㎮; ㎮; ㎮; rad∕s; rad∕s; ) SQUARE RAD OVER S
+33AF;33AF;33AF;0072 0061 0064 2215 0073 0032;0072 0061 0064 2215 0073 0032; # (㎯; ㎯; ㎯; rad∕s2; rad∕s2; ) SQUARE RAD OVER S SQUARED
+33B0;33B0;33B0;0070 0073;0070 0073; # (㎰; ㎰; ㎰; ps; ps; ) SQUARE PS
+33B1;33B1;33B1;006E 0073;006E 0073; # (㎱; ㎱; ㎱; ns; ns; ) SQUARE NS
+33B2;33B2;33B2;03BC 0073;03BC 0073; # (㎲; ㎲; ㎲; μs; μs; ) SQUARE MU S
+33B3;33B3;33B3;006D 0073;006D 0073; # (㎳; ㎳; ㎳; ms; ms; ) SQUARE MS
+33B4;33B4;33B4;0070 0056;0070 0056; # (㎴; ㎴; ㎴; pV; pV; ) SQUARE PV
+33B5;33B5;33B5;006E 0056;006E 0056; # (㎵; ㎵; ㎵; nV; nV; ) SQUARE NV
+33B6;33B6;33B6;03BC 0056;03BC 0056; # (㎶; ㎶; ㎶; μV; μV; ) SQUARE MU V
+33B7;33B7;33B7;006D 0056;006D 0056; # (㎷; ㎷; ㎷; mV; mV; ) SQUARE MV
+33B8;33B8;33B8;006B 0056;006B 0056; # (㎸; ㎸; ㎸; kV; kV; ) SQUARE KV
+33B9;33B9;33B9;004D 0056;004D 0056; # (㎹; ㎹; ㎹; MV; MV; ) SQUARE MV MEGA
+33BA;33BA;33BA;0070 0057;0070 0057; # (㎺; ㎺; ㎺; pW; pW; ) SQUARE PW
+33BB;33BB;33BB;006E 0057;006E 0057; # (㎻; ㎻; ㎻; nW; nW; ) SQUARE NW
+33BC;33BC;33BC;03BC 0057;03BC 0057; # (㎼; ㎼; ㎼; μW; μW; ) SQUARE MU W
+33BD;33BD;33BD;006D 0057;006D 0057; # (㎽; ㎽; ㎽; mW; mW; ) SQUARE MW
+33BE;33BE;33BE;006B 0057;006B 0057; # (㎾; ㎾; ㎾; kW; kW; ) SQUARE KW
+33BF;33BF;33BF;004D 0057;004D 0057; # (㎿; ㎿; ㎿; MW; MW; ) SQUARE MW MEGA
+33C0;33C0;33C0;006B 03A9;006B 03A9; # (㏀; ㏀; ㏀; kΩ; kΩ; ) SQUARE K OHM
+33C1;33C1;33C1;004D 03A9;004D 03A9; # (㏁; ㏁; ㏁; MΩ; MΩ; ) SQUARE M OHM
+33C2;33C2;33C2;0061 002E 006D 002E;0061 002E 006D 002E; # (㏂; ㏂; ㏂; a.m.; a.m.; ) SQUARE AM
+33C3;33C3;33C3;0042 0071;0042 0071; # (㏃; ㏃; ㏃; Bq; Bq; ) SQUARE BQ
+33C4;33C4;33C4;0063 0063;0063 0063; # (㏄; ㏄; ㏄; cc; cc; ) SQUARE CC
+33C5;33C5;33C5;0063 0064;0063 0064; # (㏅; ㏅; ㏅; cd; cd; ) SQUARE CD
+33C6;33C6;33C6;0043 2215 006B 0067;0043 2215 006B 0067; # (㏆; ㏆; ㏆; C∕kg; C∕kg; ) SQUARE C OVER KG
+33C7;33C7;33C7;0043 006F 002E;0043 006F 002E; # (㏇; ㏇; ㏇; Co.; Co.; ) SQUARE CO
+33C8;33C8;33C8;0064 0042;0064 0042; # (㏈; ㏈; ㏈; dB; dB; ) SQUARE DB
+33C9;33C9;33C9;0047 0079;0047 0079; # (㏉; ㏉; ㏉; Gy; Gy; ) SQUARE GY
+33CA;33CA;33CA;0068 0061;0068 0061; # (㏊; ㏊; ㏊; ha; ha; ) SQUARE HA
+33CB;33CB;33CB;0048 0050;0048 0050; # (㏋; ㏋; ㏋; HP; HP; ) SQUARE HP
+33CC;33CC;33CC;0069 006E;0069 006E; # (㏌; ㏌; ㏌; in; in; ) SQUARE IN
+33CD;33CD;33CD;004B 004B;004B 004B; # (㏍; ㏍; ㏍; KK; KK; ) SQUARE KK
+33CE;33CE;33CE;004B 004D;004B 004D; # (㏎; ㏎; ㏎; KM; KM; ) SQUARE KM CAPITAL
+33CF;33CF;33CF;006B 0074;006B 0074; # (㏏; ㏏; ㏏; kt; kt; ) SQUARE KT
+33D0;33D0;33D0;006C 006D;006C 006D; # (㏐; ㏐; ㏐; lm; lm; ) SQUARE LM
+33D1;33D1;33D1;006C 006E;006C 006E; # (㏑; ㏑; ㏑; ln; ln; ) SQUARE LN
+33D2;33D2;33D2;006C 006F 0067;006C 006F 0067; # (㏒; ㏒; ㏒; log; log; ) SQUARE LOG
+33D3;33D3;33D3;006C 0078;006C 0078; # (㏓; ㏓; ㏓; lx; lx; ) SQUARE LX
+33D4;33D4;33D4;006D 0062;006D 0062; # (㏔; ㏔; ㏔; mb; mb; ) SQUARE MB SMALL
+33D5;33D5;33D5;006D 0069 006C;006D 0069 006C; # (㏕; ㏕; ㏕; mil; mil; ) SQUARE MIL
+33D6;33D6;33D6;006D 006F 006C;006D 006F 006C; # (㏖; ㏖; ㏖; mol; mol; ) SQUARE MOL
+33D7;33D7;33D7;0050 0048;0050 0048; # (㏗; ㏗; ㏗; PH; PH; ) SQUARE PH
+33D8;33D8;33D8;0070 002E 006D 002E;0070 002E 006D 002E; # (㏘; ㏘; ㏘; p.m.; p.m.; ) SQUARE PM
+33D9;33D9;33D9;0050 0050 004D;0050 0050 004D; # (㏙; ㏙; ㏙; PPM; PPM; ) SQUARE PPM
+33DA;33DA;33DA;0050 0052;0050 0052; # (㏚; ㏚; ㏚; PR; PR; ) SQUARE PR
+33DB;33DB;33DB;0073 0072;0073 0072; # (㏛; ㏛; ㏛; sr; sr; ) SQUARE SR
+33DC;33DC;33DC;0053 0076;0053 0076; # (㏜; ㏜; ㏜; Sv; Sv; ) SQUARE SV
+33DD;33DD;33DD;0057 0062;0057 0062; # (㏝; ㏝; ㏝; Wb; Wb; ) SQUARE WB
+33DE;33DE;33DE;0056 2215 006D;0056 2215 006D; # (㏞; ㏞; ㏞; V∕m; V∕m; ) SQUARE V OVER M
+33DF;33DF;33DF;0041 2215 006D;0041 2215 006D; # (㏟; ㏟; ㏟; A∕m; A∕m; ) SQUARE A OVER M
+33E0;33E0;33E0;0031 65E5;0031 65E5; # (㏠; ㏠; ㏠; 1日; 1日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE
+33E1;33E1;33E1;0032 65E5;0032 65E5; # (㏡; ㏡; ㏡; 2日; 2日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO
+33E2;33E2;33E2;0033 65E5;0033 65E5; # (㏢; ㏢; ㏢; 3日; 3日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE
+33E3;33E3;33E3;0034 65E5;0034 65E5; # (㏣; ㏣; ㏣; 4日; 4日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR
+33E4;33E4;33E4;0035 65E5;0035 65E5; # (㏤; ㏤; ㏤; 5日; 5日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE
+33E5;33E5;33E5;0036 65E5;0036 65E5; # (㏥; ㏥; ㏥; 6日; 6日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX
+33E6;33E6;33E6;0037 65E5;0037 65E5; # (㏦; ㏦; ㏦; 7日; 7日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN
+33E7;33E7;33E7;0038 65E5;0038 65E5; # (㏧; ㏧; ㏧; 8日; 8日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT
+33E8;33E8;33E8;0039 65E5;0039 65E5; # (㏨; ㏨; ㏨; 9日; 9日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE
+33E9;33E9;33E9;0031 0030 65E5;0031 0030 65E5; # (㏩; ㏩; ㏩; 10日; 10日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN
+33EA;33EA;33EA;0031 0031 65E5;0031 0031 65E5; # (㏪; ㏪; ㏪; 11日; 11日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN
+33EB;33EB;33EB;0031 0032 65E5;0031 0032 65E5; # (㏫; ㏫; ㏫; 12日; 12日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE
+33EC;33EC;33EC;0031 0033 65E5;0031 0033 65E5; # (㏬; ㏬; ㏬; 13日; 13日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN
+33ED;33ED;33ED;0031 0034 65E5;0031 0034 65E5; # (㏭; ㏭; ㏭; 14日; 14日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN
+33EE;33EE;33EE;0031 0035 65E5;0031 0035 65E5; # (㏮; ㏮; ㏮; 15日; 15日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN
+33EF;33EF;33EF;0031 0036 65E5;0031 0036 65E5; # (㏯; ㏯; ㏯; 16日; 16日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN
+33F0;33F0;33F0;0031 0037 65E5;0031 0037 65E5; # (㏰; ㏰; ㏰; 17日; 17日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN
+33F1;33F1;33F1;0031 0038 65E5;0031 0038 65E5; # (㏱; ㏱; ㏱; 18日; 18日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN
+33F2;33F2;33F2;0031 0039 65E5;0031 0039 65E5; # (㏲; ㏲; ㏲; 19日; 19日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN
+33F3;33F3;33F3;0032 0030 65E5;0032 0030 65E5; # (㏳; ㏳; ㏳; 20日; 20日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY
+33F4;33F4;33F4;0032 0031 65E5;0032 0031 65E5; # (㏴; ㏴; ㏴; 21日; 21日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE
+33F5;33F5;33F5;0032 0032 65E5;0032 0032 65E5; # (㏵; ㏵; ㏵; 22日; 22日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO
+33F6;33F6;33F6;0032 0033 65E5;0032 0033 65E5; # (㏶; ㏶; ㏶; 23日; 23日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE
+33F7;33F7;33F7;0032 0034 65E5;0032 0034 65E5; # (㏷; ㏷; ㏷; 24日; 24日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR
+33F8;33F8;33F8;0032 0035 65E5;0032 0035 65E5; # (㏸; ㏸; ㏸; 25日; 25日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE
+33F9;33F9;33F9;0032 0036 65E5;0032 0036 65E5; # (㏹; ㏹; ㏹; 26日; 26日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX
+33FA;33FA;33FA;0032 0037 65E5;0032 0037 65E5; # (㏺; ㏺; ㏺; 27日; 27日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN
+33FB;33FB;33FB;0032 0038 65E5;0032 0038 65E5; # (㏻; ㏻; ㏻; 28日; 28日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT
+33FC;33FC;33FC;0032 0039 65E5;0032 0039 65E5; # (㏼; ㏼; ㏼; 29日; 29日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE
+33FD;33FD;33FD;0033 0030 65E5;0033 0030 65E5; # (㏽; ㏽; ㏽; 30日; 30日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY
+33FE;33FE;33FE;0033 0031 65E5;0033 0031 65E5; # (㏾; ㏾; ㏾; 31日; 31日; ) IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE
+33FF;33FF;33FF;0067 0061 006C;0067 0061 006C; # (㏿; ㏿; ㏿; gal; gal; ) SQUARE GAL
+A69C;A69C;A69C;044A;044A; # (ꚜ; ꚜ; ꚜ; ъ; ъ; ) MODIFIER LETTER CYRILLIC HARD SIGN
+A69D;A69D;A69D;044C;044C; # (ꚝ; ꚝ; ꚝ; ь; ь; ) MODIFIER LETTER CYRILLIC SOFT SIGN
+A770;A770;A770;A76F;A76F; # (ꝰ; ꝰ; ꝰ; ꝯ; ꝯ; ) MODIFIER LETTER US
+A7F8;A7F8;A7F8;0126;0126; # (ꟸ; ꟸ; ꟸ; Ħ; Ħ; ) MODIFIER LETTER CAPITAL H WITH STROKE
+A7F9;A7F9;A7F9;0153;0153; # (ꟹ; ꟹ; ꟹ; œ; œ; ) MODIFIER LETTER SMALL LIGATURE OE
+AB5C;AB5C;AB5C;A727;A727; # (ꭜ; ꭜ; ꭜ; ꜧ; ꜧ; ) MODIFIER LETTER SMALL HENG
+AB5D;AB5D;AB5D;AB37;AB37; # (ꭝ; ꭝ; ꭝ; ꬷ; ꬷ; ) MODIFIER LETTER SMALL L WITH INVERTED LAZY S
+AB5E;AB5E;AB5E;026B;026B; # (ꭞ; ꭞ; ꭞ; ɫ; ɫ; ) MODIFIER LETTER SMALL L WITH MIDDLE TILDE
+AB5F;AB5F;AB5F;AB52;AB52; # (ꭟ; ꭟ; ꭟ; ꭒ; ꭒ; ) MODIFIER LETTER SMALL U WITH LEFT HOOK
+AC00;AC00;1100 1161;AC00;1100 1161; # (가; 가; 가; 가; 가; ) HANGUL SYLLABLE GA
+AC01;AC01;1100 1161 11A8;AC01;1100 1161 11A8; # (각; 각; 각; 각; 각; ) HANGUL SYLLABLE GAG
+AC02;AC02;1100 1161 11A9;AC02;1100 1161 11A9; # (갂; 갂; 갂; 갂; 갂; ) HANGUL SYLLABLE GAGG
+AC03;AC03;1100 1161 11AA;AC03;1100 1161 11AA; # (갃; 갃; 갃; 갃; 갃; ) HANGUL SYLLABLE GAGS
+AC04;AC04;1100 1161 11AB;AC04;1100 1161 11AB; # (간; 간; 간; 간; 간; ) HANGUL SYLLABLE GAN
+AC05;AC05;1100 1161 11AC;AC05;1100 1161 11AC; # (갅; 갅; 갅; 갅; 갅; ) HANGUL SYLLABLE GANJ
+AC06;AC06;1100 1161 11AD;AC06;1100 1161 11AD; # (갆; 갆; 갆; 갆; 갆; ) HANGUL SYLLABLE GANH
+AC07;AC07;1100 1161 11AE;AC07;1100 1161 11AE; # (갇; 갇; 갇; 갇; 갇; ) HANGUL SYLLABLE GAD
+AC08;AC08;1100 1161 11AF;AC08;1100 1161 11AF; # (갈; 갈; 갈; 갈; 갈; ) HANGUL SYLLABLE GAL
+AC09;AC09;1100 1161 11B0;AC09;1100 1161 11B0; # (갉; 갉; 갉; 갉; 갉; ) HANGUL SYLLABLE GALG
+AC0A;AC0A;1100 1161 11B1;AC0A;1100 1161 11B1; # (갊; 갊; 갊; 갊; 갊; ) HANGUL SYLLABLE GALM
+AC0B;AC0B;1100 1161 11B2;AC0B;1100 1161 11B2; # (갋; 갋; 갋; 갋; 갋; ) HANGUL SYLLABLE GALB
+AC0C;AC0C;1100 1161 11B3;AC0C;1100 1161 11B3; # (갌; 갌; 갌; 갌; 갌; ) HANGUL SYLLABLE GALS
+AC0D;AC0D;1100 1161 11B4;AC0D;1100 1161 11B4; # (갍; 갍; 갍; 갍; 갍; ) HANGUL SYLLABLE GALT
+AC0E;AC0E;1100 1161 11B5;AC0E;1100 1161 11B5; # (갎; 갎; 갎; 갎; 갎; ) HANGUL SYLLABLE GALP
+AC0F;AC0F;1100 1161 11B6;AC0F;1100 1161 11B6; # (갏; 갏; 갏; 갏; 갏; ) HANGUL SYLLABLE GALH
+AC10;AC10;1100 1161 11B7;AC10;1100 1161 11B7; # (감; 감; 감; 감; 감; ) HANGUL SYLLABLE GAM
+AC11;AC11;1100 1161 11B8;AC11;1100 1161 11B8; # (갑; 갑; 갑; 갑; 갑; ) HANGUL SYLLABLE GAB
+AC12;AC12;1100 1161 11B9;AC12;1100 1161 11B9; # (값; 값; 값; 값; 값; ) HANGUL SYLLABLE GABS
+AC13;AC13;1100 1161 11BA;AC13;1100 1161 11BA; # (갓; 갓; 갓; 갓; 갓; ) HANGUL SYLLABLE GAS
+AC14;AC14;1100 1161 11BB;AC14;1100 1161 11BB; # (갔; 갔; 갔; 갔; 갔; ) HANGUL SYLLABLE GASS
+AC15;AC15;1100 1161 11BC;AC15;1100 1161 11BC; # (강; 강; 강; 강; 강; ) HANGUL SYLLABLE GANG
+AC16;AC16;1100 1161 11BD;AC16;1100 1161 11BD; # (갖; 갖; 갖; 갖; 갖; ) HANGUL SYLLABLE GAJ
+AC17;AC17;1100 1161 11BE;AC17;1100 1161 11BE; # (갗; 갗; 갗; 갗; 갗; ) HANGUL SYLLABLE GAC
+AC18;AC18;1100 1161 11BF;AC18;1100 1161 11BF; # (갘; 갘; 갘; 갘; 갘; ) HANGUL SYLLABLE GAK
+AC19;AC19;1100 1161 11C0;AC19;1100 1161 11C0; # (같; 같; 같; 같; 같; ) HANGUL SYLLABLE GAT
+AC1A;AC1A;1100 1161 11C1;AC1A;1100 1161 11C1; # (갚; 갚; 갚; 갚; 갚; ) HANGUL SYLLABLE GAP
+AC1B;AC1B;1100 1161 11C2;AC1B;1100 1161 11C2; # (갛; 갛; 갛; 갛; 갛; ) HANGUL SYLLABLE GAH
+AC1C;AC1C;1100 1162;AC1C;1100 1162; # (개; 개; 개; 개; 개; ) HANGUL SYLLABLE GAE
+AC1D;AC1D;1100 1162 11A8;AC1D;1100 1162 11A8; # (객; 객; 객; 객; 객; ) HANGUL SYLLABLE GAEG
+AC1E;AC1E;1100 1162 11A9;AC1E;1100 1162 11A9; # (갞; 갞; 갞; 갞; 갞; ) HANGUL SYLLABLE GAEGG
+AC1F;AC1F;1100 1162 11AA;AC1F;1100 1162 11AA; # (갟; 갟; 갟; 갟; 갟; ) HANGUL SYLLABLE GAEGS
+AC20;AC20;1100 1162 11AB;AC20;1100 1162 11AB; # (갠; 갠; 갠; 갠; 갠; ) HANGUL SYLLABLE GAEN
+AC21;AC21;1100 1162 11AC;AC21;1100 1162 11AC; # (갡; 갡; 갡; 갡; 갡; ) HANGUL SYLLABLE GAENJ
+AC22;AC22;1100 1162 11AD;AC22;1100 1162 11AD; # (갢; 갢; 갢; 갢; 갢; ) HANGUL SYLLABLE GAENH
+AC23;AC23;1100 1162 11AE;AC23;1100 1162 11AE; # (갣; 갣; 갣; 갣; 갣; ) HANGUL SYLLABLE GAED
+AC24;AC24;1100 1162 11AF;AC24;1100 1162 11AF; # (갤; 갤; 갤; 갤; 갤; ) HANGUL SYLLABLE GAEL
+AC25;AC25;1100 1162 11B0;AC25;1100 1162 11B0; # (갥; 갥; 갥; 갥; 갥; ) HANGUL SYLLABLE GAELG
+AC26;AC26;1100 1162 11B1;AC26;1100 1162 11B1; # (갦; 갦; 갦; 갦; 갦; ) HANGUL SYLLABLE GAELM
+AC27;AC27;1100 1162 11B2;AC27;1100 1162 11B2; # (갧; 갧; 갧; 갧; 갧; ) HANGUL SYLLABLE GAELB
+AC28;AC28;1100 1162 11B3;AC28;1100 1162 11B3; # (갨; 갨; 갨; 갨; 갨; ) HANGUL SYLLABLE GAELS
+AC29;AC29;1100 1162 11B4;AC29;1100 1162 11B4; # (갩; 갩; 갩; 갩; 갩; ) HANGUL SYLLABLE GAELT
+AC2A;AC2A;1100 1162 11B5;AC2A;1100 1162 11B5; # (갪; 갪; 갪; 갪; 갪; ) HANGUL SYLLABLE GAELP
+AC2B;AC2B;1100 1162 11B6;AC2B;1100 1162 11B6; # (갫; 갫; 갫; 갫; 갫; ) HANGUL SYLLABLE GAELH
+AC2C;AC2C;1100 1162 11B7;AC2C;1100 1162 11B7; # (갬; 갬; 갬; 갬; 갬; ) HANGUL SYLLABLE GAEM
+AC2D;AC2D;1100 1162 11B8;AC2D;1100 1162 11B8; # (갭; 갭; 갭; 갭; 갭; ) HANGUL SYLLABLE GAEB
+AC2E;AC2E;1100 1162 11B9;AC2E;1100 1162 11B9; # (갮; 갮; 갮; 갮; 갮; ) HANGUL SYLLABLE GAEBS
+AC2F;AC2F;1100 1162 11BA;AC2F;1100 1162 11BA; # (갯; 갯; 갯; 갯; 갯; ) HANGUL SYLLABLE GAES
+AC30;AC30;1100 1162 11BB;AC30;1100 1162 11BB; # (갰; 갰; 갰; 갰; 갰; ) HANGUL SYLLABLE GAESS
+AC31;AC31;1100 1162 11BC;AC31;1100 1162 11BC; # (갱; 갱; 갱; 갱; 갱; ) HANGUL SYLLABLE GAENG
+AC32;AC32;1100 1162 11BD;AC32;1100 1162 11BD; # (갲; 갲; 갲; 갲; 갲; ) HANGUL SYLLABLE GAEJ
+AC33;AC33;1100 1162 11BE;AC33;1100 1162 11BE; # (갳; 갳; 갳; 갳; 갳; ) HANGUL SYLLABLE GAEC
+AC34;AC34;1100 1162 11BF;AC34;1100 1162 11BF; # (갴; 갴; 갴; 갴; 갴; ) HANGUL SYLLABLE GAEK
+AC35;AC35;1100 1162 11C0;AC35;1100 1162 11C0; # (갵; 갵; 갵; 갵; 갵; ) HANGUL SYLLABLE GAET
+AC36;AC36;1100 1162 11C1;AC36;1100 1162 11C1; # (갶; 갶; 갶; 갶; 갶; ) HANGUL SYLLABLE GAEP
+AC37;AC37;1100 1162 11C2;AC37;1100 1162 11C2; # (갷; 갷; 갷; 갷; 갷; ) HANGUL SYLLABLE GAEH
+AC38;AC38;1100 1163;AC38;1100 1163; # (갸; 갸; 갸; 갸; 갸; ) HANGUL SYLLABLE GYA
+AC39;AC39;1100 1163 11A8;AC39;1100 1163 11A8; # (갹; 갹; 갹; 갹; 갹; ) HANGUL SYLLABLE GYAG
+AC3A;AC3A;1100 1163 11A9;AC3A;1100 1163 11A9; # (갺; 갺; 갺; 갺; 갺; ) HANGUL SYLLABLE GYAGG
+AC3B;AC3B;1100 1163 11AA;AC3B;1100 1163 11AA; # (갻; 갻; 갻; 갻; 갻; ) HANGUL SYLLABLE GYAGS
+AC3C;AC3C;1100 1163 11AB;AC3C;1100 1163 11AB; # (갼; 갼; 갼; 갼; 갼; ) HANGUL SYLLABLE GYAN
+AC3D;AC3D;1100 1163 11AC;AC3D;1100 1163 11AC; # (갽; 갽; 갽; 갽; 갽; ) HANGUL SYLLABLE GYANJ
+AC3E;AC3E;1100 1163 11AD;AC3E;1100 1163 11AD; # (갾; 갾; 갾; 갾; 갾; ) HANGUL SYLLABLE GYANH
+AC3F;AC3F;1100 1163 11AE;AC3F;1100 1163 11AE; # (갿; 갿; 갿; 갿; 갿; ) HANGUL SYLLABLE GYAD
+AC40;AC40;1100 1163 11AF;AC40;1100 1163 11AF; # (걀; 걀; 걀; 걀; 걀; ) HANGUL SYLLABLE GYAL
+AC41;AC41;1100 1163 11B0;AC41;1100 1163 11B0; # (걁; 걁; 걁; 걁; 걁; ) HANGUL SYLLABLE GYALG
+AC42;AC42;1100 1163 11B1;AC42;1100 1163 11B1; # (걂; 걂; 걂; 걂; 걂; ) HANGUL SYLLABLE GYALM
+AC43;AC43;1100 1163 11B2;AC43;1100 1163 11B2; # (걃; 걃; 걃; 걃; 걃; ) HANGUL SYLLABLE GYALB
+AC44;AC44;1100 1163 11B3;AC44;1100 1163 11B3; # (걄; 걄; 걄; 걄; 걄; ) HANGUL SYLLABLE GYALS
+AC45;AC45;1100 1163 11B4;AC45;1100 1163 11B4; # (걅; 걅; 걅; 걅; 걅; ) HANGUL SYLLABLE GYALT
+AC46;AC46;1100 1163 11B5;AC46;1100 1163 11B5; # (걆; 걆; 걆; 걆; 걆; ) HANGUL SYLLABLE GYALP
+AC47;AC47;1100 1163 11B6;AC47;1100 1163 11B6; # (걇; 걇; 걇; 걇; 걇; ) HANGUL SYLLABLE GYALH
+AC48;AC48;1100 1163 11B7;AC48;1100 1163 11B7; # (걈; 걈; 걈; 걈; 걈; ) HANGUL SYLLABLE GYAM
+AC49;AC49;1100 1163 11B8;AC49;1100 1163 11B8; # (걉; 걉; 걉; 걉; 걉; ) HANGUL SYLLABLE GYAB
+AC4A;AC4A;1100 1163 11B9;AC4A;1100 1163 11B9; # (걊; 걊; 걊; 걊; 걊; ) HANGUL SYLLABLE GYABS
+AC4B;AC4B;1100 1163 11BA;AC4B;1100 1163 11BA; # (걋; 걋; 걋; 걋; 걋; ) HANGUL SYLLABLE GYAS
+AC4C;AC4C;1100 1163 11BB;AC4C;1100 1163 11BB; # (걌; 걌; 걌; 걌; 걌; ) HANGUL SYLLABLE GYASS
+AC4D;AC4D;1100 1163 11BC;AC4D;1100 1163 11BC; # (걍; 걍; 걍; 걍; 걍; ) HANGUL SYLLABLE GYANG
+AC4E;AC4E;1100 1163 11BD;AC4E;1100 1163 11BD; # (걎; 걎; 걎; 걎; 걎; ) HANGUL SYLLABLE GYAJ
+AC4F;AC4F;1100 1163 11BE;AC4F;1100 1163 11BE; # (걏; 걏; 걏; 걏; 걏; ) HANGUL SYLLABLE GYAC
+AC50;AC50;1100 1163 11BF;AC50;1100 1163 11BF; # (걐; 걐; 걐; 걐; 걐; ) HANGUL SYLLABLE GYAK
+AC51;AC51;1100 1163 11C0;AC51;1100 1163 11C0; # (걑; 걑; 걑; 걑; 걑; ) HANGUL SYLLABLE GYAT
+AC52;AC52;1100 1163 11C1;AC52;1100 1163 11C1; # (걒; 걒; 걒; 걒; 걒; ) HANGUL SYLLABLE GYAP
+AC53;AC53;1100 1163 11C2;AC53;1100 1163 11C2; # (걓; 걓; 걓; 걓; 걓; ) HANGUL SYLLABLE GYAH
+AC54;AC54;1100 1164;AC54;1100 1164; # (걔; 걔; 걔; 걔; 걔; ) HANGUL SYLLABLE GYAE
+AC55;AC55;1100 1164 11A8;AC55;1100 1164 11A8; # (걕; 걕; 걕; 걕; 걕; ) HANGUL SYLLABLE GYAEG
+AC56;AC56;1100 1164 11A9;AC56;1100 1164 11A9; # (걖; 걖; 걖; 걖; 걖; ) HANGUL SYLLABLE GYAEGG
+AC57;AC57;1100 1164 11AA;AC57;1100 1164 11AA; # (걗; 걗; 걗; 걗; 걗; ) HANGUL SYLLABLE GYAEGS
+AC58;AC58;1100 1164 11AB;AC58;1100 1164 11AB; # (걘; 걘; 걘; 걘; 걘; ) HANGUL SYLLABLE GYAEN
+AC59;AC59;1100 1164 11AC;AC59;1100 1164 11AC; # (걙; 걙; 걙; 걙; 걙; ) HANGUL SYLLABLE GYAENJ
+AC5A;AC5A;1100 1164 11AD;AC5A;1100 1164 11AD; # (걚; 걚; 걚; 걚; 걚; ) HANGUL SYLLABLE GYAENH
+AC5B;AC5B;1100 1164 11AE;AC5B;1100 1164 11AE; # (걛; 걛; 걛; 걛; 걛; ) HANGUL SYLLABLE GYAED
+AC5C;AC5C;1100 1164 11AF;AC5C;1100 1164 11AF; # (걜; 걜; 걜; 걜; 걜; ) HANGUL SYLLABLE GYAEL
+AC5D;AC5D;1100 1164 11B0;AC5D;1100 1164 11B0; # (걝; 걝; 걝; 걝; 걝; ) HANGUL SYLLABLE GYAELG
+AC5E;AC5E;1100 1164 11B1;AC5E;1100 1164 11B1; # (걞; 걞; 걞; 걞; 걞; ) HANGUL SYLLABLE GYAELM
+AC5F;AC5F;1100 1164 11B2;AC5F;1100 1164 11B2; # (걟; 걟; 걟; 걟; 걟; ) HANGUL SYLLABLE GYAELB
+AC60;AC60;1100 1164 11B3;AC60;1100 1164 11B3; # (걠; 걠; 걠; 걠; 걠; ) HANGUL SYLLABLE GYAELS
+AC61;AC61;1100 1164 11B4;AC61;1100 1164 11B4; # (걡; 걡; 걡; 걡; 걡; ) HANGUL SYLLABLE GYAELT
+AC62;AC62;1100 1164 11B5;AC62;1100 1164 11B5; # (걢; 걢; 걢; 걢; 걢; ) HANGUL SYLLABLE GYAELP
+AC63;AC63;1100 1164 11B6;AC63;1100 1164 11B6; # (걣; 걣; 걣; 걣; 걣; ) HANGUL SYLLABLE GYAELH
+AC64;AC64;1100 1164 11B7;AC64;1100 1164 11B7; # (걤; 걤; 걤; 걤; 걤; ) HANGUL SYLLABLE GYAEM
+AC65;AC65;1100 1164 11B8;AC65;1100 1164 11B8; # (걥; 걥; 걥; 걥; 걥; ) HANGUL SYLLABLE GYAEB
+AC66;AC66;1100 1164 11B9;AC66;1100 1164 11B9; # (걦; 걦; 걦; 걦; 걦; ) HANGUL SYLLABLE GYAEBS
+AC67;AC67;1100 1164 11BA;AC67;1100 1164 11BA; # (걧; 걧; 걧; 걧; 걧; ) HANGUL SYLLABLE GYAES
+AC68;AC68;1100 1164 11BB;AC68;1100 1164 11BB; # (걨; 걨; 걨; 걨; 걨; ) HANGUL SYLLABLE GYAESS
+AC69;AC69;1100 1164 11BC;AC69;1100 1164 11BC; # (걩; 걩; 걩; 걩; 걩; ) HANGUL SYLLABLE GYAENG
+AC6A;AC6A;1100 1164 11BD;AC6A;1100 1164 11BD; # (걪; 걪; 걪; 걪; 걪; ) HANGUL SYLLABLE GYAEJ
+AC6B;AC6B;1100 1164 11BE;AC6B;1100 1164 11BE; # (걫; 걫; 걫; 걫; 걫; ) HANGUL SYLLABLE GYAEC
+AC6C;AC6C;1100 1164 11BF;AC6C;1100 1164 11BF; # (걬; 걬; 걬; 걬; 걬; ) HANGUL SYLLABLE GYAEK
+AC6D;AC6D;1100 1164 11C0;AC6D;1100 1164 11C0; # (걭; 걭; 걭; 걭; 걭; ) HANGUL SYLLABLE GYAET
+AC6E;AC6E;1100 1164 11C1;AC6E;1100 1164 11C1; # (걮; 걮; 걮; 걮; 걮; ) HANGUL SYLLABLE GYAEP
+AC6F;AC6F;1100 1164 11C2;AC6F;1100 1164 11C2; # (걯; 걯; 걯; 걯; 걯; ) HANGUL SYLLABLE GYAEH
+AC70;AC70;1100 1165;AC70;1100 1165; # (거; 거; 거; 거; 거; ) HANGUL SYLLABLE GEO
+AC71;AC71;1100 1165 11A8;AC71;1100 1165 11A8; # (걱; 걱; 걱; 걱; 걱; ) HANGUL SYLLABLE GEOG
+AC72;AC72;1100 1165 11A9;AC72;1100 1165 11A9; # (걲; 걲; 걲; 걲; 걲; ) HANGUL SYLLABLE GEOGG
+AC73;AC73;1100 1165 11AA;AC73;1100 1165 11AA; # (걳; 걳; 걳; 걳; 걳; ) HANGUL SYLLABLE GEOGS
+AC74;AC74;1100 1165 11AB;AC74;1100 1165 11AB; # (건; 건; 건; 건; 건; ) HANGUL SYLLABLE GEON
+AC75;AC75;1100 1165 11AC;AC75;1100 1165 11AC; # (걵; 걵; 걵; 걵; 걵; ) HANGUL SYLLABLE GEONJ
+AC76;AC76;1100 1165 11AD;AC76;1100 1165 11AD; # (걶; 걶; 걶; 걶; 걶; ) HANGUL SYLLABLE GEONH
+AC77;AC77;1100 1165 11AE;AC77;1100 1165 11AE; # (걷; 걷; 걷; 걷; 걷; ) HANGUL SYLLABLE GEOD
+AC78;AC78;1100 1165 11AF;AC78;1100 1165 11AF; # (걸; 걸; 걸; 걸; 걸; ) HANGUL SYLLABLE GEOL
+AC79;AC79;1100 1165 11B0;AC79;1100 1165 11B0; # (걹; 걹; 걹; 걹; 걹; ) HANGUL SYLLABLE GEOLG
+AC7A;AC7A;1100 1165 11B1;AC7A;1100 1165 11B1; # (걺; 걺; 걺; 걺; 걺; ) HANGUL SYLLABLE GEOLM
+AC7B;AC7B;1100 1165 11B2;AC7B;1100 1165 11B2; # (걻; 걻; 걻; 걻; 걻; ) HANGUL SYLLABLE GEOLB
+AC7C;AC7C;1100 1165 11B3;AC7C;1100 1165 11B3; # (걼; 걼; 걼; 걼; 걼; ) HANGUL SYLLABLE GEOLS
+AC7D;AC7D;1100 1165 11B4;AC7D;1100 1165 11B4; # (걽; 걽; 걽; 걽; 걽; ) HANGUL SYLLABLE GEOLT
+AC7E;AC7E;1100 1165 11B5;AC7E;1100 1165 11B5; # (걾; 걾; 걾; 걾; 걾; ) HANGUL SYLLABLE GEOLP
+AC7F;AC7F;1100 1165 11B6;AC7F;1100 1165 11B6; # (걿; 걿; 걿; 걿; 걿; ) HANGUL SYLLABLE GEOLH
+AC80;AC80;1100 1165 11B7;AC80;1100 1165 11B7; # (검; 검; 검; 검; 검; ) HANGUL SYLLABLE GEOM
+AC81;AC81;1100 1165 11B8;AC81;1100 1165 11B8; # (겁; 겁; 겁; 겁; 겁; ) HANGUL SYLLABLE GEOB
+AC82;AC82;1100 1165 11B9;AC82;1100 1165 11B9; # (겂; 겂; 겂; 겂; 겂; ) HANGUL SYLLABLE GEOBS
+AC83;AC83;1100 1165 11BA;AC83;1100 1165 11BA; # (것; 것; 것; 것; 것; ) HANGUL SYLLABLE GEOS
+AC84;AC84;1100 1165 11BB;AC84;1100 1165 11BB; # (겄; 겄; 겄; 겄; 겄; ) HANGUL SYLLABLE GEOSS
+AC85;AC85;1100 1165 11BC;AC85;1100 1165 11BC; # (겅; 겅; 겅; 겅; 겅; ) HANGUL SYLLABLE GEONG
+AC86;AC86;1100 1165 11BD;AC86;1100 1165 11BD; # (겆; 겆; 겆; 겆; 겆; ) HANGUL SYLLABLE GEOJ
+AC87;AC87;1100 1165 11BE;AC87;1100 1165 11BE; # (겇; 겇; 겇; 겇; 겇; ) HANGUL SYLLABLE GEOC
+AC88;AC88;1100 1165 11BF;AC88;1100 1165 11BF; # (겈; 겈; 겈; 겈; 겈; ) HANGUL SYLLABLE GEOK
+AC89;AC89;1100 1165 11C0;AC89;1100 1165 11C0; # (겉; 겉; 겉; 겉; 겉; ) HANGUL SYLLABLE GEOT
+AC8A;AC8A;1100 1165 11C1;AC8A;1100 1165 11C1; # (겊; 겊; 겊; 겊; 겊; ) HANGUL SYLLABLE GEOP
+AC8B;AC8B;1100 1165 11C2;AC8B;1100 1165 11C2; # (겋; 겋; 겋; 겋; 겋; ) HANGUL SYLLABLE GEOH
+AC8C;AC8C;1100 1166;AC8C;1100 1166; # (게; 게; 게; 게; 게; ) HANGUL SYLLABLE GE
+AC8D;AC8D;1100 1166 11A8;AC8D;1100 1166 11A8; # (겍; 겍; 겍; 겍; 겍; ) HANGUL SYLLABLE GEG
+AC8E;AC8E;1100 1166 11A9;AC8E;1100 1166 11A9; # (겎; 겎; 겎; 겎; 겎; ) HANGUL SYLLABLE GEGG
+AC8F;AC8F;1100 1166 11AA;AC8F;1100 1166 11AA; # (겏; 겏; 겏; 겏; 겏; ) HANGUL SYLLABLE GEGS
+AC90;AC90;1100 1166 11AB;AC90;1100 1166 11AB; # (겐; 겐; 겐; 겐; 겐; ) HANGUL SYLLABLE GEN
+AC91;AC91;1100 1166 11AC;AC91;1100 1166 11AC; # (겑; 겑; 겑; 겑; 겑; ) HANGUL SYLLABLE GENJ
+AC92;AC92;1100 1166 11AD;AC92;1100 1166 11AD; # (겒; 겒; 겒; 겒; 겒; ) HANGUL SYLLABLE GENH
+AC93;AC93;1100 1166 11AE;AC93;1100 1166 11AE; # (겓; 겓; 겓; 겓; 겓; ) HANGUL SYLLABLE GED
+AC94;AC94;1100 1166 11AF;AC94;1100 1166 11AF; # (겔; 겔; 겔; 겔; 겔; ) HANGUL SYLLABLE GEL
+AC95;AC95;1100 1166 11B0;AC95;1100 1166 11B0; # (겕; 겕; 겕; 겕; 겕; ) HANGUL SYLLABLE GELG
+AC96;AC96;1100 1166 11B1;AC96;1100 1166 11B1; # (겖; 겖; 겖; 겖; 겖; ) HANGUL SYLLABLE GELM
+AC97;AC97;1100 1166 11B2;AC97;1100 1166 11B2; # (겗; 겗; 겗; 겗; 겗; ) HANGUL SYLLABLE GELB
+AC98;AC98;1100 1166 11B3;AC98;1100 1166 11B3; # (겘; 겘; 겘; 겘; 겘; ) HANGUL SYLLABLE GELS
+AC99;AC99;1100 1166 11B4;AC99;1100 1166 11B4; # (겙; 겙; 겙; 겙; 겙; ) HANGUL SYLLABLE GELT
+AC9A;AC9A;1100 1166 11B5;AC9A;1100 1166 11B5; # (겚; 겚; 겚; 겚; 겚; ) HANGUL SYLLABLE GELP
+AC9B;AC9B;1100 1166 11B6;AC9B;1100 1166 11B6; # (겛; 겛; 겛; 겛; 겛; ) HANGUL SYLLABLE GELH
+AC9C;AC9C;1100 1166 11B7;AC9C;1100 1166 11B7; # (겜; 겜; 겜; 겜; 겜; ) HANGUL SYLLABLE GEM
+AC9D;AC9D;1100 1166 11B8;AC9D;1100 1166 11B8; # (겝; 겝; 겝; 겝; 겝; ) HANGUL SYLLABLE GEB
+AC9E;AC9E;1100 1166 11B9;AC9E;1100 1166 11B9; # (겞; 겞; 겞; 겞; 겞; ) HANGUL SYLLABLE GEBS
+AC9F;AC9F;1100 1166 11BA;AC9F;1100 1166 11BA; # (겟; 겟; 겟; 겟; 겟; ) HANGUL SYLLABLE GES
+ACA0;ACA0;1100 1166 11BB;ACA0;1100 1166 11BB; # (겠; 겠; 겠; 겠; 겠; ) HANGUL SYLLABLE GESS
+ACA1;ACA1;1100 1166 11BC;ACA1;1100 1166 11BC; # (겡; 겡; 겡; 겡; 겡; ) HANGUL SYLLABLE GENG
+ACA2;ACA2;1100 1166 11BD;ACA2;1100 1166 11BD; # (겢; 겢; 겢; 겢; 겢; ) HANGUL SYLLABLE GEJ
+ACA3;ACA3;1100 1166 11BE;ACA3;1100 1166 11BE; # (겣; 겣; 겣; 겣; 겣; ) HANGUL SYLLABLE GEC
+ACA4;ACA4;1100 1166 11BF;ACA4;1100 1166 11BF; # (겤; 겤; 겤; 겤; 겤; ) HANGUL SYLLABLE GEK
+ACA5;ACA5;1100 1166 11C0;ACA5;1100 1166 11C0; # (겥; 겥; 겥; 겥; 겥; ) HANGUL SYLLABLE GET
+ACA6;ACA6;1100 1166 11C1;ACA6;1100 1166 11C1; # (겦; 겦; 겦; 겦; 겦; ) HANGUL SYLLABLE GEP
+ACA7;ACA7;1100 1166 11C2;ACA7;1100 1166 11C2; # (겧; 겧; 겧; 겧; 겧; ) HANGUL SYLLABLE GEH
+ACA8;ACA8;1100 1167;ACA8;1100 1167; # (겨; 겨; 겨; 겨; 겨; ) HANGUL SYLLABLE GYEO
+ACA9;ACA9;1100 1167 11A8;ACA9;1100 1167 11A8; # (격; 격; 격; 격; 격; ) HANGUL SYLLABLE GYEOG
+ACAA;ACAA;1100 1167 11A9;ACAA;1100 1167 11A9; # (겪; 겪; 겪; 겪; 겪; ) HANGUL SYLLABLE GYEOGG
+ACAB;ACAB;1100 1167 11AA;ACAB;1100 1167 11AA; # (겫; 겫; 겫; 겫; 겫; ) HANGUL SYLLABLE GYEOGS
+ACAC;ACAC;1100 1167 11AB;ACAC;1100 1167 11AB; # (견; 견; 견; 견; 견; ) HANGUL SYLLABLE GYEON
+ACAD;ACAD;1100 1167 11AC;ACAD;1100 1167 11AC; # (겭; 겭; 겭; 겭; 겭; ) HANGUL SYLLABLE GYEONJ
+ACAE;ACAE;1100 1167 11AD;ACAE;1100 1167 11AD; # (겮; 겮; 겮; 겮; 겮; ) HANGUL SYLLABLE GYEONH
+ACAF;ACAF;1100 1167 11AE;ACAF;1100 1167 11AE; # (겯; 겯; 겯; 겯; 겯; ) HANGUL SYLLABLE GYEOD
+ACB0;ACB0;1100 1167 11AF;ACB0;1100 1167 11AF; # (결; 결; 결; 결; 결; ) HANGUL SYLLABLE GYEOL
+ACB1;ACB1;1100 1167 11B0;ACB1;1100 1167 11B0; # (겱; 겱; 겱; 겱; 겱; ) HANGUL SYLLABLE GYEOLG
+ACB2;ACB2;1100 1167 11B1;ACB2;1100 1167 11B1; # (겲; 겲; 겲; 겲; 겲; ) HANGUL SYLLABLE GYEOLM
+ACB3;ACB3;1100 1167 11B2;ACB3;1100 1167 11B2; # (겳; 겳; 겳; 겳; 겳; ) HANGUL SYLLABLE GYEOLB
+ACB4;ACB4;1100 1167 11B3;ACB4;1100 1167 11B3; # (겴; 겴; 겴; 겴; 겴; ) HANGUL SYLLABLE GYEOLS
+ACB5;ACB5;1100 1167 11B4;ACB5;1100 1167 11B4; # (겵; 겵; 겵; 겵; 겵; ) HANGUL SYLLABLE GYEOLT
+ACB6;ACB6;1100 1167 11B5;ACB6;1100 1167 11B5; # (겶; 겶; 겶; 겶; 겶; ) HANGUL SYLLABLE GYEOLP
+ACB7;ACB7;1100 1167 11B6;ACB7;1100 1167 11B6; # (겷; 겷; 겷; 겷; 겷; ) HANGUL SYLLABLE GYEOLH
+ACB8;ACB8;1100 1167 11B7;ACB8;1100 1167 11B7; # (겸; 겸; 겸; 겸; 겸; ) HANGUL SYLLABLE GYEOM
+ACB9;ACB9;1100 1167 11B8;ACB9;1100 1167 11B8; # (겹; 겹; 겹; 겹; 겹; ) HANGUL SYLLABLE GYEOB
+ACBA;ACBA;1100 1167 11B9;ACBA;1100 1167 11B9; # (겺; 겺; 겺; 겺; 겺; ) HANGUL SYLLABLE GYEOBS
+ACBB;ACBB;1100 1167 11BA;ACBB;1100 1167 11BA; # (겻; 겻; 겻; 겻; 겻; ) HANGUL SYLLABLE GYEOS
+ACBC;ACBC;1100 1167 11BB;ACBC;1100 1167 11BB; # (겼; 겼; 겼; 겼; 겼; ) HANGUL SYLLABLE GYEOSS
+ACBD;ACBD;1100 1167 11BC;ACBD;1100 1167 11BC; # (경; 경; 경; 경; 경; ) HANGUL SYLLABLE GYEONG
+ACBE;ACBE;1100 1167 11BD;ACBE;1100 1167 11BD; # (겾; 겾; 겾; 겾; 겾; ) HANGUL SYLLABLE GYEOJ
+ACBF;ACBF;1100 1167 11BE;ACBF;1100 1167 11BE; # (겿; 겿; 겿; 겿; 겿; ) HANGUL SYLLABLE GYEOC
+ACC0;ACC0;1100 1167 11BF;ACC0;1100 1167 11BF; # (곀; 곀; 곀; 곀; 곀; ) HANGUL SYLLABLE GYEOK
+ACC1;ACC1;1100 1167 11C0;ACC1;1100 1167 11C0; # (곁; 곁; 곁; 곁; 곁; ) HANGUL SYLLABLE GYEOT
+ACC2;ACC2;1100 1167 11C1;ACC2;1100 1167 11C1; # (곂; 곂; 곂; 곂; 곂; ) HANGUL SYLLABLE GYEOP
+ACC3;ACC3;1100 1167 11C2;ACC3;1100 1167 11C2; # (곃; 곃; 곃; 곃; 곃; ) HANGUL SYLLABLE GYEOH
+ACC4;ACC4;1100 1168;ACC4;1100 1168; # (계; 계; 계; 계; 계; ) HANGUL SYLLABLE GYE
+ACC5;ACC5;1100 1168 11A8;ACC5;1100 1168 11A8; # (곅; 곅; 곅; 곅; 곅; ) HANGUL SYLLABLE GYEG
+ACC6;ACC6;1100 1168 11A9;ACC6;1100 1168 11A9; # (곆; 곆; 곆; 곆; 곆; ) HANGUL SYLLABLE GYEGG
+ACC7;ACC7;1100 1168 11AA;ACC7;1100 1168 11AA; # (곇; 곇; 곇; 곇; 곇; ) HANGUL SYLLABLE GYEGS
+ACC8;ACC8;1100 1168 11AB;ACC8;1100 1168 11AB; # (곈; 곈; 곈; 곈; 곈; ) HANGUL SYLLABLE GYEN
+ACC9;ACC9;1100 1168 11AC;ACC9;1100 1168 11AC; # (곉; 곉; 곉; 곉; 곉; ) HANGUL SYLLABLE GYENJ
+ACCA;ACCA;1100 1168 11AD;ACCA;1100 1168 11AD; # (곊; 곊; 곊; 곊; 곊; ) HANGUL SYLLABLE GYENH
+ACCB;ACCB;1100 1168 11AE;ACCB;1100 1168 11AE; # (곋; 곋; 곋; 곋; 곋; ) HANGUL SYLLABLE GYED
+ACCC;ACCC;1100 1168 11AF;ACCC;1100 1168 11AF; # (곌; 곌; 곌; 곌; 곌; ) HANGUL SYLLABLE GYEL
+ACCD;ACCD;1100 1168 11B0;ACCD;1100 1168 11B0; # (곍; 곍; 곍; 곍; 곍; ) HANGUL SYLLABLE GYELG
+ACCE;ACCE;1100 1168 11B1;ACCE;1100 1168 11B1; # (곎; 곎; 곎; 곎; 곎; ) HANGUL SYLLABLE GYELM
+ACCF;ACCF;1100 1168 11B2;ACCF;1100 1168 11B2; # (곏; 곏; 곏; 곏; 곏; ) HANGUL SYLLABLE GYELB
+ACD0;ACD0;1100 1168 11B3;ACD0;1100 1168 11B3; # (곐; 곐; 곐; 곐; 곐; ) HANGUL SYLLABLE GYELS
+ACD1;ACD1;1100 1168 11B4;ACD1;1100 1168 11B4; # (곑; 곑; 곑; 곑; 곑; ) HANGUL SYLLABLE GYELT
+ACD2;ACD2;1100 1168 11B5;ACD2;1100 1168 11B5; # (곒; 곒; 곒; 곒; 곒; ) HANGUL SYLLABLE GYELP
+ACD3;ACD3;1100 1168 11B6;ACD3;1100 1168 11B6; # (곓; 곓; 곓; 곓; 곓; ) HANGUL SYLLABLE GYELH
+ACD4;ACD4;1100 1168 11B7;ACD4;1100 1168 11B7; # (곔; 곔; 곔; 곔; 곔; ) HANGUL SYLLABLE GYEM
+ACD5;ACD5;1100 1168 11B8;ACD5;1100 1168 11B8; # (곕; 곕; 곕; 곕; 곕; ) HANGUL SYLLABLE GYEB
+ACD6;ACD6;1100 1168 11B9;ACD6;1100 1168 11B9; # (곖; 곖; 곖; 곖; 곖; ) HANGUL SYLLABLE GYEBS
+ACD7;ACD7;1100 1168 11BA;ACD7;1100 1168 11BA; # (곗; 곗; 곗; 곗; 곗; ) HANGUL SYLLABLE GYES
+ACD8;ACD8;1100 1168 11BB;ACD8;1100 1168 11BB; # (곘; 곘; 곘; 곘; 곘; ) HANGUL SYLLABLE GYESS
+ACD9;ACD9;1100 1168 11BC;ACD9;1100 1168 11BC; # (곙; 곙; 곙; 곙; 곙; ) HANGUL SYLLABLE GYENG
+ACDA;ACDA;1100 1168 11BD;ACDA;1100 1168 11BD; # (곚; 곚; 곚; 곚; 곚; ) HANGUL SYLLABLE GYEJ
+ACDB;ACDB;1100 1168 11BE;ACDB;1100 1168 11BE; # (곛; 곛; 곛; 곛; 곛; ) HANGUL SYLLABLE GYEC
+ACDC;ACDC;1100 1168 11BF;ACDC;1100 1168 11BF; # (곜; 곜; 곜; 곜; 곜; ) HANGUL SYLLABLE GYEK
+ACDD;ACDD;1100 1168 11C0;ACDD;1100 1168 11C0; # (곝; 곝; 곝; 곝; 곝; ) HANGUL SYLLABLE GYET
+ACDE;ACDE;1100 1168 11C1;ACDE;1100 1168 11C1; # (곞; 곞; 곞; 곞; 곞; ) HANGUL SYLLABLE GYEP
+ACDF;ACDF;1100 1168 11C2;ACDF;1100 1168 11C2; # (곟; 곟; 곟; 곟; 곟; ) HANGUL SYLLABLE GYEH
+ACE0;ACE0;1100 1169;ACE0;1100 1169; # (고; 고; 고; 고; 고; ) HANGUL SYLLABLE GO
+ACE1;ACE1;1100 1169 11A8;ACE1;1100 1169 11A8; # (곡; 곡; 곡; 곡; 곡; ) HANGUL SYLLABLE GOG
+ACE2;ACE2;1100 1169 11A9;ACE2;1100 1169 11A9; # (곢; 곢; 곢; 곢; 곢; ) HANGUL SYLLABLE GOGG
+ACE3;ACE3;1100 1169 11AA;ACE3;1100 1169 11AA; # (곣; 곣; 곣; 곣; 곣; ) HANGUL SYLLABLE GOGS
+ACE4;ACE4;1100 1169 11AB;ACE4;1100 1169 11AB; # (곤; 곤; 곤; 곤; 곤; ) HANGUL SYLLABLE GON
+ACE5;ACE5;1100 1169 11AC;ACE5;1100 1169 11AC; # (곥; 곥; 곥; 곥; 곥; ) HANGUL SYLLABLE GONJ
+ACE6;ACE6;1100 1169 11AD;ACE6;1100 1169 11AD; # (곦; 곦; 곦; 곦; 곦; ) HANGUL SYLLABLE GONH
+ACE7;ACE7;1100 1169 11AE;ACE7;1100 1169 11AE; # (곧; 곧; 곧; 곧; 곧; ) HANGUL SYLLABLE GOD
+ACE8;ACE8;1100 1169 11AF;ACE8;1100 1169 11AF; # (골; 골; 골; 골; 골; ) HANGUL SYLLABLE GOL
+ACE9;ACE9;1100 1169 11B0;ACE9;1100 1169 11B0; # (곩; 곩; 곩; 곩; 곩; ) HANGUL SYLLABLE GOLG
+ACEA;ACEA;1100 1169 11B1;ACEA;1100 1169 11B1; # (곪; 곪; 곪; 곪; 곪; ) HANGUL SYLLABLE GOLM
+ACEB;ACEB;1100 1169 11B2;ACEB;1100 1169 11B2; # (곫; 곫; 곫; 곫; 곫; ) HANGUL SYLLABLE GOLB
+ACEC;ACEC;1100 1169 11B3;ACEC;1100 1169 11B3; # (곬; 곬; 곬; 곬; 곬; ) HANGUL SYLLABLE GOLS
+ACED;ACED;1100 1169 11B4;ACED;1100 1169 11B4; # (곭; 곭; 곭; 곭; 곭; ) HANGUL SYLLABLE GOLT
+ACEE;ACEE;1100 1169 11B5;ACEE;1100 1169 11B5; # (곮; 곮; 곮; 곮; 곮; ) HANGUL SYLLABLE GOLP
+ACEF;ACEF;1100 1169 11B6;ACEF;1100 1169 11B6; # (곯; 곯; 곯; 곯; 곯; ) HANGUL SYLLABLE GOLH
+ACF0;ACF0;1100 1169 11B7;ACF0;1100 1169 11B7; # (곰; 곰; 곰; 곰; 곰; ) HANGUL SYLLABLE GOM
+ACF1;ACF1;1100 1169 11B8;ACF1;1100 1169 11B8; # (곱; 곱; 곱; 곱; 곱; ) HANGUL SYLLABLE GOB
+ACF2;ACF2;1100 1169 11B9;ACF2;1100 1169 11B9; # (곲; 곲; 곲; 곲; 곲; ) HANGUL SYLLABLE GOBS
+ACF3;ACF3;1100 1169 11BA;ACF3;1100 1169 11BA; # (곳; 곳; 곳; 곳; 곳; ) HANGUL SYLLABLE GOS
+ACF4;ACF4;1100 1169 11BB;ACF4;1100 1169 11BB; # (곴; 곴; 곴; 곴; 곴; ) HANGUL SYLLABLE GOSS
+ACF5;ACF5;1100 1169 11BC;ACF5;1100 1169 11BC; # (공; 공; 공; 공; 공; ) HANGUL SYLLABLE GONG
+ACF6;ACF6;1100 1169 11BD;ACF6;1100 1169 11BD; # (곶; 곶; 곶; 곶; 곶; ) HANGUL SYLLABLE GOJ
+ACF7;ACF7;1100 1169 11BE;ACF7;1100 1169 11BE; # (곷; 곷; 곷; 곷; 곷; ) HANGUL SYLLABLE GOC
+ACF8;ACF8;1100 1169 11BF;ACF8;1100 1169 11BF; # (곸; 곸; 곸; 곸; 곸; ) HANGUL SYLLABLE GOK
+ACF9;ACF9;1100 1169 11C0;ACF9;1100 1169 11C0; # (곹; 곹; 곹; 곹; 곹; ) HANGUL SYLLABLE GOT
+ACFA;ACFA;1100 1169 11C1;ACFA;1100 1169 11C1; # (곺; 곺; 곺; 곺; 곺; ) HANGUL SYLLABLE GOP
+ACFB;ACFB;1100 1169 11C2;ACFB;1100 1169 11C2; # (곻; 곻; 곻; 곻; 곻; ) HANGUL SYLLABLE GOH
+ACFC;ACFC;1100 116A;ACFC;1100 116A; # (과; 과; 과; 과; 과; ) HANGUL SYLLABLE GWA
+ACFD;ACFD;1100 116A 11A8;ACFD;1100 116A 11A8; # (곽; 곽; 곽; 곽; 곽; ) HANGUL SYLLABLE GWAG
+ACFE;ACFE;1100 116A 11A9;ACFE;1100 116A 11A9; # (곾; 곾; 곾; 곾; 곾; ) HANGUL SYLLABLE GWAGG
+ACFF;ACFF;1100 116A 11AA;ACFF;1100 116A 11AA; # (곿; 곿; 곿; 곿; 곿; ) HANGUL SYLLABLE GWAGS
+AD00;AD00;1100 116A 11AB;AD00;1100 116A 11AB; # (관; 관; 관; 관; 관; ) HANGUL SYLLABLE GWAN
+AD01;AD01;1100 116A 11AC;AD01;1100 116A 11AC; # (괁; 괁; 괁; 괁; 괁; ) HANGUL SYLLABLE GWANJ
+AD02;AD02;1100 116A 11AD;AD02;1100 116A 11AD; # (괂; 괂; 괂; 괂; 괂; ) HANGUL SYLLABLE GWANH
+AD03;AD03;1100 116A 11AE;AD03;1100 116A 11AE; # (괃; 괃; 괃; 괃; 괃; ) HANGUL SYLLABLE GWAD
+AD04;AD04;1100 116A 11AF;AD04;1100 116A 11AF; # (괄; 괄; 괄; 괄; 괄; ) HANGUL SYLLABLE GWAL
+AD05;AD05;1100 116A 11B0;AD05;1100 116A 11B0; # (괅; 괅; 괅; 괅; 괅; ) HANGUL SYLLABLE GWALG
+AD06;AD06;1100 116A 11B1;AD06;1100 116A 11B1; # (괆; 괆; 괆; 괆; 괆; ) HANGUL SYLLABLE GWALM
+AD07;AD07;1100 116A 11B2;AD07;1100 116A 11B2; # (괇; 괇; 괇; 괇; 괇; ) HANGUL SYLLABLE GWALB
+AD08;AD08;1100 116A 11B3;AD08;1100 116A 11B3; # (괈; 괈; 괈; 괈; 괈; ) HANGUL SYLLABLE GWALS
+AD09;AD09;1100 116A 11B4;AD09;1100 116A 11B4; # (괉; 괉; 괉; 괉; 괉; ) HANGUL SYLLABLE GWALT
+AD0A;AD0A;1100 116A 11B5;AD0A;1100 116A 11B5; # (괊; 괊; 괊; 괊; 괊; ) HANGUL SYLLABLE GWALP
+AD0B;AD0B;1100 116A 11B6;AD0B;1100 116A 11B6; # (괋; 괋; 괋; 괋; 괋; ) HANGUL SYLLABLE GWALH
+AD0C;AD0C;1100 116A 11B7;AD0C;1100 116A 11B7; # (괌; 괌; 괌; 괌; 괌; ) HANGUL SYLLABLE GWAM
+AD0D;AD0D;1100 116A 11B8;AD0D;1100 116A 11B8; # (괍; 괍; 괍; 괍; 괍; ) HANGUL SYLLABLE GWAB
+AD0E;AD0E;1100 116A 11B9;AD0E;1100 116A 11B9; # (괎; 괎; 괎; 괎; 괎; ) HANGUL SYLLABLE GWABS
+AD0F;AD0F;1100 116A 11BA;AD0F;1100 116A 11BA; # (괏; 괏; 괏; 괏; 괏; ) HANGUL SYLLABLE GWAS
+AD10;AD10;1100 116A 11BB;AD10;1100 116A 11BB; # (괐; 괐; 괐; 괐; 괐; ) HANGUL SYLLABLE GWASS
+AD11;AD11;1100 116A 11BC;AD11;1100 116A 11BC; # (광; 광; 광; 광; 광; ) HANGUL SYLLABLE GWANG
+AD12;AD12;1100 116A 11BD;AD12;1100 116A 11BD; # (괒; 괒; 괒; 괒; 괒; ) HANGUL SYLLABLE GWAJ
+AD13;AD13;1100 116A 11BE;AD13;1100 116A 11BE; # (괓; 괓; 괓; 괓; 괓; ) HANGUL SYLLABLE GWAC
+AD14;AD14;1100 116A 11BF;AD14;1100 116A 11BF; # (괔; 괔; 괔; 괔; 괔; ) HANGUL SYLLABLE GWAK
+AD15;AD15;1100 116A 11C0;AD15;1100 116A 11C0; # (괕; 괕; 괕; 괕; 괕; ) HANGUL SYLLABLE GWAT
+AD16;AD16;1100 116A 11C1;AD16;1100 116A 11C1; # (괖; 괖; 괖; 괖; 괖; ) HANGUL SYLLABLE GWAP
+AD17;AD17;1100 116A 11C2;AD17;1100 116A 11C2; # (괗; 괗; 괗; 괗; 괗; ) HANGUL SYLLABLE GWAH
+AD18;AD18;1100 116B;AD18;1100 116B; # (괘; 괘; 괘; 괘; 괘; ) HANGUL SYLLABLE GWAE
+AD19;AD19;1100 116B 11A8;AD19;1100 116B 11A8; # (괙; 괙; 괙; 괙; 괙; ) HANGUL SYLLABLE GWAEG
+AD1A;AD1A;1100 116B 11A9;AD1A;1100 116B 11A9; # (괚; 괚; 괚; 괚; 괚; ) HANGUL SYLLABLE GWAEGG
+AD1B;AD1B;1100 116B 11AA;AD1B;1100 116B 11AA; # (괛; 괛; 괛; 괛; 괛; ) HANGUL SYLLABLE GWAEGS
+AD1C;AD1C;1100 116B 11AB;AD1C;1100 116B 11AB; # (괜; 괜; 괜; 괜; 괜; ) HANGUL SYLLABLE GWAEN
+AD1D;AD1D;1100 116B 11AC;AD1D;1100 116B 11AC; # (괝; 괝; 괝; 괝; 괝; ) HANGUL SYLLABLE GWAENJ
+AD1E;AD1E;1100 116B 11AD;AD1E;1100 116B 11AD; # (괞; 괞; 괞; 괞; 괞; ) HANGUL SYLLABLE GWAENH
+AD1F;AD1F;1100 116B 11AE;AD1F;1100 116B 11AE; # (괟; 괟; 괟; 괟; 괟; ) HANGUL SYLLABLE GWAED
+AD20;AD20;1100 116B 11AF;AD20;1100 116B 11AF; # (괠; 괠; 괠; 괠; 괠; ) HANGUL SYLLABLE GWAEL
+AD21;AD21;1100 116B 11B0;AD21;1100 116B 11B0; # (괡; 괡; 괡; 괡; 괡; ) HANGUL SYLLABLE GWAELG
+AD22;AD22;1100 116B 11B1;AD22;1100 116B 11B1; # (괢; 괢; 괢; 괢; 괢; ) HANGUL SYLLABLE GWAELM
+AD23;AD23;1100 116B 11B2;AD23;1100 116B 11B2; # (괣; 괣; 괣; 괣; 괣; ) HANGUL SYLLABLE GWAELB
+AD24;AD24;1100 116B 11B3;AD24;1100 116B 11B3; # (괤; 괤; 괤; 괤; 괤; ) HANGUL SYLLABLE GWAELS
+AD25;AD25;1100 116B 11B4;AD25;1100 116B 11B4; # (괥; 괥; 괥; 괥; 괥; ) HANGUL SYLLABLE GWAELT
+AD26;AD26;1100 116B 11B5;AD26;1100 116B 11B5; # (괦; 괦; 괦; 괦; 괦; ) HANGUL SYLLABLE GWAELP
+AD27;AD27;1100 116B 11B6;AD27;1100 116B 11B6; # (괧; 괧; 괧; 괧; 괧; ) HANGUL SYLLABLE GWAELH
+AD28;AD28;1100 116B 11B7;AD28;1100 116B 11B7; # (괨; 괨; 괨; 괨; 괨; ) HANGUL SYLLABLE GWAEM
+AD29;AD29;1100 116B 11B8;AD29;1100 116B 11B8; # (괩; 괩; 괩; 괩; 괩; ) HANGUL SYLLABLE GWAEB
+AD2A;AD2A;1100 116B 11B9;AD2A;1100 116B 11B9; # (괪; 괪; 괪; 괪; 괪; ) HANGUL SYLLABLE GWAEBS
+AD2B;AD2B;1100 116B 11BA;AD2B;1100 116B 11BA; # (괫; 괫; 괫; 괫; 괫; ) HANGUL SYLLABLE GWAES
+AD2C;AD2C;1100 116B 11BB;AD2C;1100 116B 11BB; # (괬; 괬; 괬; 괬; 괬; ) HANGUL SYLLABLE GWAESS
+AD2D;AD2D;1100 116B 11BC;AD2D;1100 116B 11BC; # (괭; 괭; 괭; 괭; 괭; ) HANGUL SYLLABLE GWAENG
+AD2E;AD2E;1100 116B 11BD;AD2E;1100 116B 11BD; # (괮; 괮; 괮; 괮; 괮; ) HANGUL SYLLABLE GWAEJ
+AD2F;AD2F;1100 116B 11BE;AD2F;1100 116B 11BE; # (괯; 괯; 괯; 괯; 괯; ) HANGUL SYLLABLE GWAEC
+AD30;AD30;1100 116B 11BF;AD30;1100 116B 11BF; # (괰; 괰; 괰; 괰; 괰; ) HANGUL SYLLABLE GWAEK
+AD31;AD31;1100 116B 11C0;AD31;1100 116B 11C0; # (괱; 괱; 괱; 괱; 괱; ) HANGUL SYLLABLE GWAET
+AD32;AD32;1100 116B 11C1;AD32;1100 116B 11C1; # (괲; 괲; 괲; 괲; 괲; ) HANGUL SYLLABLE GWAEP
+AD33;AD33;1100 116B 11C2;AD33;1100 116B 11C2; # (괳; 괳; 괳; 괳; 괳; ) HANGUL SYLLABLE GWAEH
+AD34;AD34;1100 116C;AD34;1100 116C; # (괴; 괴; 괴; 괴; 괴; ) HANGUL SYLLABLE GOE
+AD35;AD35;1100 116C 11A8;AD35;1100 116C 11A8; # (괵; 괵; 괵; 괵; 괵; ) HANGUL SYLLABLE GOEG
+AD36;AD36;1100 116C 11A9;AD36;1100 116C 11A9; # (괶; 괶; 괶; 괶; 괶; ) HANGUL SYLLABLE GOEGG
+AD37;AD37;1100 116C 11AA;AD37;1100 116C 11AA; # (괷; 괷; 괷; 괷; 괷; ) HANGUL SYLLABLE GOEGS
+AD38;AD38;1100 116C 11AB;AD38;1100 116C 11AB; # (괸; 괸; 괸; 괸; 괸; ) HANGUL SYLLABLE GOEN
+AD39;AD39;1100 116C 11AC;AD39;1100 116C 11AC; # (괹; 괹; 괹; 괹; 괹; ) HANGUL SYLLABLE GOENJ
+AD3A;AD3A;1100 116C 11AD;AD3A;1100 116C 11AD; # (괺; 괺; 괺; 괺; 괺; ) HANGUL SYLLABLE GOENH
+AD3B;AD3B;1100 116C 11AE;AD3B;1100 116C 11AE; # (괻; 괻; 괻; 괻; 괻; ) HANGUL SYLLABLE GOED
+AD3C;AD3C;1100 116C 11AF;AD3C;1100 116C 11AF; # (괼; 괼; 괼; 괼; 괼; ) HANGUL SYLLABLE GOEL
+AD3D;AD3D;1100 116C 11B0;AD3D;1100 116C 11B0; # (괽; 괽; 괽; 괽; 괽; ) HANGUL SYLLABLE GOELG
+AD3E;AD3E;1100 116C 11B1;AD3E;1100 116C 11B1; # (괾; 괾; 괾; 괾; 괾; ) HANGUL SYLLABLE GOELM
+AD3F;AD3F;1100 116C 11B2;AD3F;1100 116C 11B2; # (괿; 괿; 괿; 괿; 괿; ) HANGUL SYLLABLE GOELB
+AD40;AD40;1100 116C 11B3;AD40;1100 116C 11B3; # (굀; 굀; 굀; 굀; 굀; ) HANGUL SYLLABLE GOELS
+AD41;AD41;1100 116C 11B4;AD41;1100 116C 11B4; # (굁; 굁; 굁; 굁; 굁; ) HANGUL SYLLABLE GOELT
+AD42;AD42;1100 116C 11B5;AD42;1100 116C 11B5; # (굂; 굂; 굂; 굂; 굂; ) HANGUL SYLLABLE GOELP
+AD43;AD43;1100 116C 11B6;AD43;1100 116C 11B6; # (굃; 굃; 굃; 굃; 굃; ) HANGUL SYLLABLE GOELH
+AD44;AD44;1100 116C 11B7;AD44;1100 116C 11B7; # (굄; 굄; 굄; 굄; 굄; ) HANGUL SYLLABLE GOEM
+AD45;AD45;1100 116C 11B8;AD45;1100 116C 11B8; # (굅; 굅; 굅; 굅; 굅; ) HANGUL SYLLABLE GOEB
+AD46;AD46;1100 116C 11B9;AD46;1100 116C 11B9; # (굆; 굆; 굆; 굆; 굆; ) HANGUL SYLLABLE GOEBS
+AD47;AD47;1100 116C 11BA;AD47;1100 116C 11BA; # (굇; 굇; 굇; 굇; 굇; ) HANGUL SYLLABLE GOES
+AD48;AD48;1100 116C 11BB;AD48;1100 116C 11BB; # (굈; 굈; 굈; 굈; 굈; ) HANGUL SYLLABLE GOESS
+AD49;AD49;1100 116C 11BC;AD49;1100 116C 11BC; # (굉; 굉; 굉; 굉; 굉; ) HANGUL SYLLABLE GOENG
+AD4A;AD4A;1100 116C 11BD;AD4A;1100 116C 11BD; # (굊; 굊; 굊; 굊; 굊; ) HANGUL SYLLABLE GOEJ
+AD4B;AD4B;1100 116C 11BE;AD4B;1100 116C 11BE; # (굋; 굋; 굋; 굋; 굋; ) HANGUL SYLLABLE GOEC
+AD4C;AD4C;1100 116C 11BF;AD4C;1100 116C 11BF; # (굌; 굌; 굌; 굌; 굌; ) HANGUL SYLLABLE GOEK
+AD4D;AD4D;1100 116C 11C0;AD4D;1100 116C 11C0; # (굍; 굍; 굍; 굍; 굍; ) HANGUL SYLLABLE GOET
+AD4E;AD4E;1100 116C 11C1;AD4E;1100 116C 11C1; # (굎; 굎; 굎; 굎; 굎; ) HANGUL SYLLABLE GOEP
+AD4F;AD4F;1100 116C 11C2;AD4F;1100 116C 11C2; # (굏; 굏; 굏; 굏; 굏; ) HANGUL SYLLABLE GOEH
+AD50;AD50;1100 116D;AD50;1100 116D; # (교; 교; 교; 교; 교; ) HANGUL SYLLABLE GYO
+AD51;AD51;1100 116D 11A8;AD51;1100 116D 11A8; # (굑; 굑; 굑; 굑; 굑; ) HANGUL SYLLABLE GYOG
+AD52;AD52;1100 116D 11A9;AD52;1100 116D 11A9; # (굒; 굒; 굒; 굒; 굒; ) HANGUL SYLLABLE GYOGG
+AD53;AD53;1100 116D 11AA;AD53;1100 116D 11AA; # (굓; 굓; 굓; 굓; 굓; ) HANGUL SYLLABLE GYOGS
+AD54;AD54;1100 116D 11AB;AD54;1100 116D 11AB; # (굔; 굔; 굔; 굔; 굔; ) HANGUL SYLLABLE GYON
+AD55;AD55;1100 116D 11AC;AD55;1100 116D 11AC; # (굕; 굕; 굕; 굕; 굕; ) HANGUL SYLLABLE GYONJ
+AD56;AD56;1100 116D 11AD;AD56;1100 116D 11AD; # (굖; 굖; 굖; 굖; 굖; ) HANGUL SYLLABLE GYONH
+AD57;AD57;1100 116D 11AE;AD57;1100 116D 11AE; # (굗; 굗; 굗; 굗; 굗; ) HANGUL SYLLABLE GYOD
+AD58;AD58;1100 116D 11AF;AD58;1100 116D 11AF; # (굘; 굘; 굘; 굘; 굘; ) HANGUL SYLLABLE GYOL
+AD59;AD59;1100 116D 11B0;AD59;1100 116D 11B0; # (굙; 굙; 굙; 굙; 굙; ) HANGUL SYLLABLE GYOLG
+AD5A;AD5A;1100 116D 11B1;AD5A;1100 116D 11B1; # (굚; 굚; 굚; 굚; 굚; ) HANGUL SYLLABLE GYOLM
+AD5B;AD5B;1100 116D 11B2;AD5B;1100 116D 11B2; # (굛; 굛; 굛; 굛; 굛; ) HANGUL SYLLABLE GYOLB
+AD5C;AD5C;1100 116D 11B3;AD5C;1100 116D 11B3; # (굜; 굜; 굜; 굜; 굜; ) HANGUL SYLLABLE GYOLS
+AD5D;AD5D;1100 116D 11B4;AD5D;1100 116D 11B4; # (굝; 굝; 굝; 굝; 굝; ) HANGUL SYLLABLE GYOLT
+AD5E;AD5E;1100 116D 11B5;AD5E;1100 116D 11B5; # (굞; 굞; 굞; 굞; 굞; ) HANGUL SYLLABLE GYOLP
+AD5F;AD5F;1100 116D 11B6;AD5F;1100 116D 11B6; # (굟; 굟; 굟; 굟; 굟; ) HANGUL SYLLABLE GYOLH
+AD60;AD60;1100 116D 11B7;AD60;1100 116D 11B7; # (굠; 굠; 굠; 굠; 굠; ) HANGUL SYLLABLE GYOM
+AD61;AD61;1100 116D 11B8;AD61;1100 116D 11B8; # (굡; 굡; 굡; 굡; 굡; ) HANGUL SYLLABLE GYOB
+AD62;AD62;1100 116D 11B9;AD62;1100 116D 11B9; # (굢; 굢; 굢; 굢; 굢; ) HANGUL SYLLABLE GYOBS
+AD63;AD63;1100 116D 11BA;AD63;1100 116D 11BA; # (굣; 굣; 굣; 굣; 굣; ) HANGUL SYLLABLE GYOS
+AD64;AD64;1100 116D 11BB;AD64;1100 116D 11BB; # (굤; 굤; 굤; 굤; 굤; ) HANGUL SYLLABLE GYOSS
+AD65;AD65;1100 116D 11BC;AD65;1100 116D 11BC; # (굥; 굥; 굥; 굥; 굥; ) HANGUL SYLLABLE GYONG
+AD66;AD66;1100 116D 11BD;AD66;1100 116D 11BD; # (굦; 굦; 굦; 굦; 굦; ) HANGUL SYLLABLE GYOJ
+AD67;AD67;1100 116D 11BE;AD67;1100 116D 11BE; # (굧; 굧; 굧; 굧; 굧; ) HANGUL SYLLABLE GYOC
+AD68;AD68;1100 116D 11BF;AD68;1100 116D 11BF; # (굨; 굨; 굨; 굨; 굨; ) HANGUL SYLLABLE GYOK
+AD69;AD69;1100 116D 11C0;AD69;1100 116D 11C0; # (굩; 굩; 굩; 굩; 굩; ) HANGUL SYLLABLE GYOT
+AD6A;AD6A;1100 116D 11C1;AD6A;1100 116D 11C1; # (굪; 굪; 굪; 굪; 굪; ) HANGUL SYLLABLE GYOP
+AD6B;AD6B;1100 116D 11C2;AD6B;1100 116D 11C2; # (굫; 굫; 굫; 굫; 굫; ) HANGUL SYLLABLE GYOH
+AD6C;AD6C;1100 116E;AD6C;1100 116E; # (구; 구; 구; 구; 구; ) HANGUL SYLLABLE GU
+AD6D;AD6D;1100 116E 11A8;AD6D;1100 116E 11A8; # (국; 국; 국; 국; 국; ) HANGUL SYLLABLE GUG
+AD6E;AD6E;1100 116E 11A9;AD6E;1100 116E 11A9; # (굮; 굮; 굮; 굮; 굮; ) HANGUL SYLLABLE GUGG
+AD6F;AD6F;1100 116E 11AA;AD6F;1100 116E 11AA; # (굯; 굯; 굯; 굯; 굯; ) HANGUL SYLLABLE GUGS
+AD70;AD70;1100 116E 11AB;AD70;1100 116E 11AB; # (군; 군; 군; 군; 군; ) HANGUL SYLLABLE GUN
+AD71;AD71;1100 116E 11AC;AD71;1100 116E 11AC; # (굱; 굱; 굱; 굱; 굱; ) HANGUL SYLLABLE GUNJ
+AD72;AD72;1100 116E 11AD;AD72;1100 116E 11AD; # (굲; 굲; 굲; 굲; 굲; ) HANGUL SYLLABLE GUNH
+AD73;AD73;1100 116E 11AE;AD73;1100 116E 11AE; # (굳; 굳; 굳; 굳; 굳; ) HANGUL SYLLABLE GUD
+AD74;AD74;1100 116E 11AF;AD74;1100 116E 11AF; # (굴; 굴; 굴; 굴; 굴; ) HANGUL SYLLABLE GUL
+AD75;AD75;1100 116E 11B0;AD75;1100 116E 11B0; # (굵; 굵; 굵; 굵; 굵; ) HANGUL SYLLABLE GULG
+AD76;AD76;1100 116E 11B1;AD76;1100 116E 11B1; # (굶; 굶; 굶; 굶; 굶; ) HANGUL SYLLABLE GULM
+AD77;AD77;1100 116E 11B2;AD77;1100 116E 11B2; # (굷; 굷; 굷; 굷; 굷; ) HANGUL SYLLABLE GULB
+AD78;AD78;1100 116E 11B3;AD78;1100 116E 11B3; # (굸; 굸; 굸; 굸; 굸; ) HANGUL SYLLABLE GULS
+AD79;AD79;1100 116E 11B4;AD79;1100 116E 11B4; # (굹; 굹; 굹; 굹; 굹; ) HANGUL SYLLABLE GULT
+AD7A;AD7A;1100 116E 11B5;AD7A;1100 116E 11B5; # (굺; 굺; 굺; 굺; 굺; ) HANGUL SYLLABLE GULP
+AD7B;AD7B;1100 116E 11B6;AD7B;1100 116E 11B6; # (굻; 굻; 굻; 굻; 굻; ) HANGUL SYLLABLE GULH
+AD7C;AD7C;1100 116E 11B7;AD7C;1100 116E 11B7; # (굼; 굼; 굼; 굼; 굼; ) HANGUL SYLLABLE GUM
+AD7D;AD7D;1100 116E 11B8;AD7D;1100 116E 11B8; # (굽; 굽; 굽; 굽; 굽; ) HANGUL SYLLABLE GUB
+AD7E;AD7E;1100 116E 11B9;AD7E;1100 116E 11B9; # (굾; 굾; 굾; 굾; 굾; ) HANGUL SYLLABLE GUBS
+AD7F;AD7F;1100 116E 11BA;AD7F;1100 116E 11BA; # (굿; 굿; 굿; 굿; 굿; ) HANGUL SYLLABLE GUS
+AD80;AD80;1100 116E 11BB;AD80;1100 116E 11BB; # (궀; 궀; 궀; 궀; 궀; ) HANGUL SYLLABLE GUSS
+AD81;AD81;1100 116E 11BC;AD81;1100 116E 11BC; # (궁; 궁; 궁; 궁; 궁; ) HANGUL SYLLABLE GUNG
+AD82;AD82;1100 116E 11BD;AD82;1100 116E 11BD; # (궂; 궂; 궂; 궂; 궂; ) HANGUL SYLLABLE GUJ
+AD83;AD83;1100 116E 11BE;AD83;1100 116E 11BE; # (궃; 궃; 궃; 궃; 궃; ) HANGUL SYLLABLE GUC
+AD84;AD84;1100 116E 11BF;AD84;1100 116E 11BF; # (궄; 궄; 궄; 궄; 궄; ) HANGUL SYLLABLE GUK
+AD85;AD85;1100 116E 11C0;AD85;1100 116E 11C0; # (궅; 궅; 궅; 궅; 궅; ) HANGUL SYLLABLE GUT
+AD86;AD86;1100 116E 11C1;AD86;1100 116E 11C1; # (궆; 궆; 궆; 궆; 궆; ) HANGUL SYLLABLE GUP
+AD87;AD87;1100 116E 11C2;AD87;1100 116E 11C2; # (궇; 궇; 궇; 궇; 궇; ) HANGUL SYLLABLE GUH
+AD88;AD88;1100 116F;AD88;1100 116F; # (궈; 궈; 궈; 궈; 궈; ) HANGUL SYLLABLE GWEO
+AD89;AD89;1100 116F 11A8;AD89;1100 116F 11A8; # (궉; 궉; 궉; 궉; 궉; ) HANGUL SYLLABLE GWEOG
+AD8A;AD8A;1100 116F 11A9;AD8A;1100 116F 11A9; # (궊; 궊; 궊; 궊; 궊; ) HANGUL SYLLABLE GWEOGG
+AD8B;AD8B;1100 116F 11AA;AD8B;1100 116F 11AA; # (궋; 궋; 궋; 궋; 궋; ) HANGUL SYLLABLE GWEOGS
+AD8C;AD8C;1100 116F 11AB;AD8C;1100 116F 11AB; # (권; 권; 권; 권; 권; ) HANGUL SYLLABLE GWEON
+AD8D;AD8D;1100 116F 11AC;AD8D;1100 116F 11AC; # (궍; 궍; 궍; 궍; 궍; ) HANGUL SYLLABLE GWEONJ
+AD8E;AD8E;1100 116F 11AD;AD8E;1100 116F 11AD; # (궎; 궎; 궎; 궎; 궎; ) HANGUL SYLLABLE GWEONH
+AD8F;AD8F;1100 116F 11AE;AD8F;1100 116F 11AE; # (궏; 궏; 궏; 궏; 궏; ) HANGUL SYLLABLE GWEOD
+AD90;AD90;1100 116F 11AF;AD90;1100 116F 11AF; # (궐; 궐; 궐; 궐; 궐; ) HANGUL SYLLABLE GWEOL
+AD91;AD91;1100 116F 11B0;AD91;1100 116F 11B0; # (궑; 궑; 궑; 궑; 궑; ) HANGUL SYLLABLE GWEOLG
+AD92;AD92;1100 116F 11B1;AD92;1100 116F 11B1; # (궒; 궒; 궒; 궒; 궒; ) HANGUL SYLLABLE GWEOLM
+AD93;AD93;1100 116F 11B2;AD93;1100 116F 11B2; # (궓; 궓; 궓; 궓; 궓; ) HANGUL SYLLABLE GWEOLB
+AD94;AD94;1100 116F 11B3;AD94;1100 116F 11B3; # (궔; 궔; 궔; 궔; 궔; ) HANGUL SYLLABLE GWEOLS
+AD95;AD95;1100 116F 11B4;AD95;1100 116F 11B4; # (궕; 궕; 궕; 궕; 궕; ) HANGUL SYLLABLE GWEOLT
+AD96;AD96;1100 116F 11B5;AD96;1100 116F 11B5; # (궖; 궖; 궖; 궖; 궖; ) HANGUL SYLLABLE GWEOLP
+AD97;AD97;1100 116F 11B6;AD97;1100 116F 11B6; # (궗; 궗; 궗; 궗; 궗; ) HANGUL SYLLABLE GWEOLH
+AD98;AD98;1100 116F 11B7;AD98;1100 116F 11B7; # (궘; 궘; 궘; 궘; 궘; ) HANGUL SYLLABLE GWEOM
+AD99;AD99;1100 116F 11B8;AD99;1100 116F 11B8; # (궙; 궙; 궙; 궙; 궙; ) HANGUL SYLLABLE GWEOB
+AD9A;AD9A;1100 116F 11B9;AD9A;1100 116F 11B9; # (궚; 궚; 궚; 궚; 궚; ) HANGUL SYLLABLE GWEOBS
+AD9B;AD9B;1100 116F 11BA;AD9B;1100 116F 11BA; # (궛; 궛; 궛; 궛; 궛; ) HANGUL SYLLABLE GWEOS
+AD9C;AD9C;1100 116F 11BB;AD9C;1100 116F 11BB; # (궜; 궜; 궜; 궜; 궜; ) HANGUL SYLLABLE GWEOSS
+AD9D;AD9D;1100 116F 11BC;AD9D;1100 116F 11BC; # (궝; 궝; 궝; 궝; 궝; ) HANGUL SYLLABLE GWEONG
+AD9E;AD9E;1100 116F 11BD;AD9E;1100 116F 11BD; # (궞; 궞; 궞; 궞; 궞; ) HANGUL SYLLABLE GWEOJ
+AD9F;AD9F;1100 116F 11BE;AD9F;1100 116F 11BE; # (궟; 궟; 궟; 궟; 궟; ) HANGUL SYLLABLE GWEOC
+ADA0;ADA0;1100 116F 11BF;ADA0;1100 116F 11BF; # (궠; 궠; 궠; 궠; 궠; ) HANGUL SYLLABLE GWEOK
+ADA1;ADA1;1100 116F 11C0;ADA1;1100 116F 11C0; # (궡; 궡; 궡; 궡; 궡; ) HANGUL SYLLABLE GWEOT
+ADA2;ADA2;1100 116F 11C1;ADA2;1100 116F 11C1; # (궢; 궢; 궢; 궢; 궢; ) HANGUL SYLLABLE GWEOP
+ADA3;ADA3;1100 116F 11C2;ADA3;1100 116F 11C2; # (궣; 궣; 궣; 궣; 궣; ) HANGUL SYLLABLE GWEOH
+ADA4;ADA4;1100 1170;ADA4;1100 1170; # (궤; 궤; 궤; 궤; 궤; ) HANGUL SYLLABLE GWE
+ADA5;ADA5;1100 1170 11A8;ADA5;1100 1170 11A8; # (궥; 궥; 궥; 궥; 궥; ) HANGUL SYLLABLE GWEG
+ADA6;ADA6;1100 1170 11A9;ADA6;1100 1170 11A9; # (궦; 궦; 궦; 궦; 궦; ) HANGUL SYLLABLE GWEGG
+ADA7;ADA7;1100 1170 11AA;ADA7;1100 1170 11AA; # (궧; 궧; 궧; 궧; 궧; ) HANGUL SYLLABLE GWEGS
+ADA8;ADA8;1100 1170 11AB;ADA8;1100 1170 11AB; # (궨; 궨; 궨; 궨; 궨; ) HANGUL SYLLABLE GWEN
+ADA9;ADA9;1100 1170 11AC;ADA9;1100 1170 11AC; # (궩; 궩; 궩; 궩; 궩; ) HANGUL SYLLABLE GWENJ
+ADAA;ADAA;1100 1170 11AD;ADAA;1100 1170 11AD; # (궪; 궪; 궪; 궪; 궪; ) HANGUL SYLLABLE GWENH
+ADAB;ADAB;1100 1170 11AE;ADAB;1100 1170 11AE; # (궫; 궫; 궫; 궫; 궫; ) HANGUL SYLLABLE GWED
+ADAC;ADAC;1100 1170 11AF;ADAC;1100 1170 11AF; # (궬; 궬; 궬; 궬; 궬; ) HANGUL SYLLABLE GWEL
+ADAD;ADAD;1100 1170 11B0;ADAD;1100 1170 11B0; # (궭; 궭; 궭; 궭; 궭; ) HANGUL SYLLABLE GWELG
+ADAE;ADAE;1100 1170 11B1;ADAE;1100 1170 11B1; # (궮; 궮; 궮; 궮; 궮; ) HANGUL SYLLABLE GWELM
+ADAF;ADAF;1100 1170 11B2;ADAF;1100 1170 11B2; # (궯; 궯; 궯; 궯; 궯; ) HANGUL SYLLABLE GWELB
+ADB0;ADB0;1100 1170 11B3;ADB0;1100 1170 11B3; # (궰; 궰; 궰; 궰; 궰; ) HANGUL SYLLABLE GWELS
+ADB1;ADB1;1100 1170 11B4;ADB1;1100 1170 11B4; # (궱; 궱; 궱; 궱; 궱; ) HANGUL SYLLABLE GWELT
+ADB2;ADB2;1100 1170 11B5;ADB2;1100 1170 11B5; # (궲; 궲; 궲; 궲; 궲; ) HANGUL SYLLABLE GWELP
+ADB3;ADB3;1100 1170 11B6;ADB3;1100 1170 11B6; # (궳; 궳; 궳; 궳; 궳; ) HANGUL SYLLABLE GWELH
+ADB4;ADB4;1100 1170 11B7;ADB4;1100 1170 11B7; # (궴; 궴; 궴; 궴; 궴; ) HANGUL SYLLABLE GWEM
+ADB5;ADB5;1100 1170 11B8;ADB5;1100 1170 11B8; # (궵; 궵; 궵; 궵; 궵; ) HANGUL SYLLABLE GWEB
+ADB6;ADB6;1100 1170 11B9;ADB6;1100 1170 11B9; # (궶; 궶; 궶; 궶; 궶; ) HANGUL SYLLABLE GWEBS
+ADB7;ADB7;1100 1170 11BA;ADB7;1100 1170 11BA; # (궷; 궷; 궷; 궷; 궷; ) HANGUL SYLLABLE GWES
+ADB8;ADB8;1100 1170 11BB;ADB8;1100 1170 11BB; # (궸; 궸; 궸; 궸; 궸; ) HANGUL SYLLABLE GWESS
+ADB9;ADB9;1100 1170 11BC;ADB9;1100 1170 11BC; # (궹; 궹; 궹; 궹; 궹; ) HANGUL SYLLABLE GWENG
+ADBA;ADBA;1100 1170 11BD;ADBA;1100 1170 11BD; # (궺; 궺; 궺; 궺; 궺; ) HANGUL SYLLABLE GWEJ
+ADBB;ADBB;1100 1170 11BE;ADBB;1100 1170 11BE; # (궻; 궻; 궻; 궻; 궻; ) HANGUL SYLLABLE GWEC
+ADBC;ADBC;1100 1170 11BF;ADBC;1100 1170 11BF; # (궼; 궼; 궼; 궼; 궼; ) HANGUL SYLLABLE GWEK
+ADBD;ADBD;1100 1170 11C0;ADBD;1100 1170 11C0; # (궽; 궽; 궽; 궽; 궽; ) HANGUL SYLLABLE GWET
+ADBE;ADBE;1100 1170 11C1;ADBE;1100 1170 11C1; # (궾; 궾; 궾; 궾; 궾; ) HANGUL SYLLABLE GWEP
+ADBF;ADBF;1100 1170 11C2;ADBF;1100 1170 11C2; # (궿; 궿; 궿; 궿; 궿; ) HANGUL SYLLABLE GWEH
+ADC0;ADC0;1100 1171;ADC0;1100 1171; # (귀; 귀; 귀; 귀; 귀; ) HANGUL SYLLABLE GWI
+ADC1;ADC1;1100 1171 11A8;ADC1;1100 1171 11A8; # (귁; 귁; 귁; 귁; 귁; ) HANGUL SYLLABLE GWIG
+ADC2;ADC2;1100 1171 11A9;ADC2;1100 1171 11A9; # (귂; 귂; 귂; 귂; 귂; ) HANGUL SYLLABLE GWIGG
+ADC3;ADC3;1100 1171 11AA;ADC3;1100 1171 11AA; # (귃; 귃; 귃; 귃; 귃; ) HANGUL SYLLABLE GWIGS
+ADC4;ADC4;1100 1171 11AB;ADC4;1100 1171 11AB; # (귄; 귄; 귄; 귄; 귄; ) HANGUL SYLLABLE GWIN
+ADC5;ADC5;1100 1171 11AC;ADC5;1100 1171 11AC; # (귅; 귅; 귅; 귅; 귅; ) HANGUL SYLLABLE GWINJ
+ADC6;ADC6;1100 1171 11AD;ADC6;1100 1171 11AD; # (귆; 귆; 귆; 귆; 귆; ) HANGUL SYLLABLE GWINH
+ADC7;ADC7;1100 1171 11AE;ADC7;1100 1171 11AE; # (귇; 귇; 귇; 귇; 귇; ) HANGUL SYLLABLE GWID
+ADC8;ADC8;1100 1171 11AF;ADC8;1100 1171 11AF; # (귈; 귈; 귈; 귈; 귈; ) HANGUL SYLLABLE GWIL
+ADC9;ADC9;1100 1171 11B0;ADC9;1100 1171 11B0; # (귉; 귉; 귉; 귉; 귉; ) HANGUL SYLLABLE GWILG
+ADCA;ADCA;1100 1171 11B1;ADCA;1100 1171 11B1; # (귊; 귊; 귊; 귊; 귊; ) HANGUL SYLLABLE GWILM
+ADCB;ADCB;1100 1171 11B2;ADCB;1100 1171 11B2; # (귋; 귋; 귋; 귋; 귋; ) HANGUL SYLLABLE GWILB
+ADCC;ADCC;1100 1171 11B3;ADCC;1100 1171 11B3; # (귌; 귌; 귌; 귌; 귌; ) HANGUL SYLLABLE GWILS
+ADCD;ADCD;1100 1171 11B4;ADCD;1100 1171 11B4; # (귍; 귍; 귍; 귍; 귍; ) HANGUL SYLLABLE GWILT
+ADCE;ADCE;1100 1171 11B5;ADCE;1100 1171 11B5; # (귎; 귎; 귎; 귎; 귎; ) HANGUL SYLLABLE GWILP
+ADCF;ADCF;1100 1171 11B6;ADCF;1100 1171 11B6; # (귏; 귏; 귏; 귏; 귏; ) HANGUL SYLLABLE GWILH
+ADD0;ADD0;1100 1171 11B7;ADD0;1100 1171 11B7; # (귐; 귐; 귐; 귐; 귐; ) HANGUL SYLLABLE GWIM
+ADD1;ADD1;1100 1171 11B8;ADD1;1100 1171 11B8; # (귑; 귑; 귑; 귑; 귑; ) HANGUL SYLLABLE GWIB
+ADD2;ADD2;1100 1171 11B9;ADD2;1100 1171 11B9; # (귒; 귒; 귒; 귒; 귒; ) HANGUL SYLLABLE GWIBS
+ADD3;ADD3;1100 1171 11BA;ADD3;1100 1171 11BA; # (귓; 귓; 귓; 귓; 귓; ) HANGUL SYLLABLE GWIS
+ADD4;ADD4;1100 1171 11BB;ADD4;1100 1171 11BB; # (귔; 귔; 귔; 귔; 귔; ) HANGUL SYLLABLE GWISS
+ADD5;ADD5;1100 1171 11BC;ADD5;1100 1171 11BC; # (귕; 귕; 귕; 귕; 귕; ) HANGUL SYLLABLE GWING
+ADD6;ADD6;1100 1171 11BD;ADD6;1100 1171 11BD; # (귖; 귖; 귖; 귖; 귖; ) HANGUL SYLLABLE GWIJ
+ADD7;ADD7;1100 1171 11BE;ADD7;1100 1171 11BE; # (귗; 귗; 귗; 귗; 귗; ) HANGUL SYLLABLE GWIC
+ADD8;ADD8;1100 1171 11BF;ADD8;1100 1171 11BF; # (귘; 귘; 귘; 귘; 귘; ) HANGUL SYLLABLE GWIK
+ADD9;ADD9;1100 1171 11C0;ADD9;1100 1171 11C0; # (귙; 귙; 귙; 귙; 귙; ) HANGUL SYLLABLE GWIT
+ADDA;ADDA;1100 1171 11C1;ADDA;1100 1171 11C1; # (귚; 귚; 귚; 귚; 귚; ) HANGUL SYLLABLE GWIP
+ADDB;ADDB;1100 1171 11C2;ADDB;1100 1171 11C2; # (귛; 귛; 귛; 귛; 귛; ) HANGUL SYLLABLE GWIH
+ADDC;ADDC;1100 1172;ADDC;1100 1172; # (규; 규; 규; 규; 규; ) HANGUL SYLLABLE GYU
+ADDD;ADDD;1100 1172 11A8;ADDD;1100 1172 11A8; # (귝; 귝; 귝; 귝; 귝; ) HANGUL SYLLABLE GYUG
+ADDE;ADDE;1100 1172 11A9;ADDE;1100 1172 11A9; # (귞; 귞; 귞; 귞; 귞; ) HANGUL SYLLABLE GYUGG
+ADDF;ADDF;1100 1172 11AA;ADDF;1100 1172 11AA; # (귟; 귟; 귟; 귟; 귟; ) HANGUL SYLLABLE GYUGS
+ADE0;ADE0;1100 1172 11AB;ADE0;1100 1172 11AB; # (균; 균; 균; 균; 균; ) HANGUL SYLLABLE GYUN
+ADE1;ADE1;1100 1172 11AC;ADE1;1100 1172 11AC; # (귡; 귡; 귡; 귡; 귡; ) HANGUL SYLLABLE GYUNJ
+ADE2;ADE2;1100 1172 11AD;ADE2;1100 1172 11AD; # (귢; 귢; 귢; 귢; 귢; ) HANGUL SYLLABLE GYUNH
+ADE3;ADE3;1100 1172 11AE;ADE3;1100 1172 11AE; # (귣; 귣; 귣; 귣; 귣; ) HANGUL SYLLABLE GYUD
+ADE4;ADE4;1100 1172 11AF;ADE4;1100 1172 11AF; # (귤; 귤; 귤; 귤; 귤; ) HANGUL SYLLABLE GYUL
+ADE5;ADE5;1100 1172 11B0;ADE5;1100 1172 11B0; # (귥; 귥; 귥; 귥; 귥; ) HANGUL SYLLABLE GYULG
+ADE6;ADE6;1100 1172 11B1;ADE6;1100 1172 11B1; # (귦; 귦; 귦; 귦; 귦; ) HANGUL SYLLABLE GYULM
+ADE7;ADE7;1100 1172 11B2;ADE7;1100 1172 11B2; # (귧; 귧; 귧; 귧; 귧; ) HANGUL SYLLABLE GYULB
+ADE8;ADE8;1100 1172 11B3;ADE8;1100 1172 11B3; # (귨; 귨; 귨; 귨; 귨; ) HANGUL SYLLABLE GYULS
+ADE9;ADE9;1100 1172 11B4;ADE9;1100 1172 11B4; # (귩; 귩; 귩; 귩; 귩; ) HANGUL SYLLABLE GYULT
+ADEA;ADEA;1100 1172 11B5;ADEA;1100 1172 11B5; # (귪; 귪; 귪; 귪; 귪; ) HANGUL SYLLABLE GYULP
+ADEB;ADEB;1100 1172 11B6;ADEB;1100 1172 11B6; # (귫; 귫; 귫; 귫; 귫; ) HANGUL SYLLABLE GYULH
+ADEC;ADEC;1100 1172 11B7;ADEC;1100 1172 11B7; # (귬; 귬; 귬; 귬; 귬; ) HANGUL SYLLABLE GYUM
+ADED;ADED;1100 1172 11B8;ADED;1100 1172 11B8; # (귭; 귭; 귭; 귭; 귭; ) HANGUL SYLLABLE GYUB
+ADEE;ADEE;1100 1172 11B9;ADEE;1100 1172 11B9; # (귮; 귮; 귮; 귮; 귮; ) HANGUL SYLLABLE GYUBS
+ADEF;ADEF;1100 1172 11BA;ADEF;1100 1172 11BA; # (귯; 귯; 귯; 귯; 귯; ) HANGUL SYLLABLE GYUS
+ADF0;ADF0;1100 1172 11BB;ADF0;1100 1172 11BB; # (귰; 귰; 귰; 귰; 귰; ) HANGUL SYLLABLE GYUSS
+ADF1;ADF1;1100 1172 11BC;ADF1;1100 1172 11BC; # (귱; 귱; 귱; 귱; 귱; ) HANGUL SYLLABLE GYUNG
+ADF2;ADF2;1100 1172 11BD;ADF2;1100 1172 11BD; # (귲; 귲; 귲; 귲; 귲; ) HANGUL SYLLABLE GYUJ
+ADF3;ADF3;1100 1172 11BE;ADF3;1100 1172 11BE; # (귳; 귳; 귳; 귳; 귳; ) HANGUL SYLLABLE GYUC
+ADF4;ADF4;1100 1172 11BF;ADF4;1100 1172 11BF; # (귴; 귴; 귴; 귴; 귴; ) HANGUL SYLLABLE GYUK
+ADF5;ADF5;1100 1172 11C0;ADF5;1100 1172 11C0; # (귵; 귵; 귵; 귵; 귵; ) HANGUL SYLLABLE GYUT
+ADF6;ADF6;1100 1172 11C1;ADF6;1100 1172 11C1; # (귶; 귶; 귶; 귶; 귶; ) HANGUL SYLLABLE GYUP
+ADF7;ADF7;1100 1172 11C2;ADF7;1100 1172 11C2; # (귷; 귷; 귷; 귷; 귷; ) HANGUL SYLLABLE GYUH
+ADF8;ADF8;1100 1173;ADF8;1100 1173; # (그; 그; 그; 그; 그; ) HANGUL SYLLABLE GEU
+ADF9;ADF9;1100 1173 11A8;ADF9;1100 1173 11A8; # (극; 극; 극; 극; 극; ) HANGUL SYLLABLE GEUG
+ADFA;ADFA;1100 1173 11A9;ADFA;1100 1173 11A9; # (귺; 귺; 귺; 귺; 귺; ) HANGUL SYLLABLE GEUGG
+ADFB;ADFB;1100 1173 11AA;ADFB;1100 1173 11AA; # (귻; 귻; 귻; 귻; 귻; ) HANGUL SYLLABLE GEUGS
+ADFC;ADFC;1100 1173 11AB;ADFC;1100 1173 11AB; # (근; 근; 근; 근; 근; ) HANGUL SYLLABLE GEUN
+ADFD;ADFD;1100 1173 11AC;ADFD;1100 1173 11AC; # (귽; 귽; 귽; 귽; 귽; ) HANGUL SYLLABLE GEUNJ
+ADFE;ADFE;1100 1173 11AD;ADFE;1100 1173 11AD; # (귾; 귾; 귾; 귾; 귾; ) HANGUL SYLLABLE GEUNH
+ADFF;ADFF;1100 1173 11AE;ADFF;1100 1173 11AE; # (귿; 귿; 귿; 귿; 귿; ) HANGUL SYLLABLE GEUD
+AE00;AE00;1100 1173 11AF;AE00;1100 1173 11AF; # (글; 글; 글; 글; 글; ) HANGUL SYLLABLE GEUL
+AE01;AE01;1100 1173 11B0;AE01;1100 1173 11B0; # (긁; 긁; 긁; 긁; 긁; ) HANGUL SYLLABLE GEULG
+AE02;AE02;1100 1173 11B1;AE02;1100 1173 11B1; # (긂; 긂; 긂; 긂; 긂; ) HANGUL SYLLABLE GEULM
+AE03;AE03;1100 1173 11B2;AE03;1100 1173 11B2; # (긃; 긃; 긃; 긃; 긃; ) HANGUL SYLLABLE GEULB
+AE04;AE04;1100 1173 11B3;AE04;1100 1173 11B3; # (긄; 긄; 긄; 긄; 긄; ) HANGUL SYLLABLE GEULS
+AE05;AE05;1100 1173 11B4;AE05;1100 1173 11B4; # (긅; 긅; 긅; 긅; 긅; ) HANGUL SYLLABLE GEULT
+AE06;AE06;1100 1173 11B5;AE06;1100 1173 11B5; # (긆; 긆; 긆; 긆; 긆; ) HANGUL SYLLABLE GEULP
+AE07;AE07;1100 1173 11B6;AE07;1100 1173 11B6; # (긇; 긇; 긇; 긇; 긇; ) HANGUL SYLLABLE GEULH
+AE08;AE08;1100 1173 11B7;AE08;1100 1173 11B7; # (금; 금; 금; 금; 금; ) HANGUL SYLLABLE GEUM
+AE09;AE09;1100 1173 11B8;AE09;1100 1173 11B8; # (급; 급; 급; 급; 급; ) HANGUL SYLLABLE GEUB
+AE0A;AE0A;1100 1173 11B9;AE0A;1100 1173 11B9; # (긊; 긊; 긊; 긊; 긊; ) HANGUL SYLLABLE GEUBS
+AE0B;AE0B;1100 1173 11BA;AE0B;1100 1173 11BA; # (긋; 긋; 긋; 긋; 긋; ) HANGUL SYLLABLE GEUS
+AE0C;AE0C;1100 1173 11BB;AE0C;1100 1173 11BB; # (긌; 긌; 긌; 긌; 긌; ) HANGUL SYLLABLE GEUSS
+AE0D;AE0D;1100 1173 11BC;AE0D;1100 1173 11BC; # (긍; 긍; 긍; 긍; 긍; ) HANGUL SYLLABLE GEUNG
+AE0E;AE0E;1100 1173 11BD;AE0E;1100 1173 11BD; # (긎; 긎; 긎; 긎; 긎; ) HANGUL SYLLABLE GEUJ
+AE0F;AE0F;1100 1173 11BE;AE0F;1100 1173 11BE; # (긏; 긏; 긏; 긏; 긏; ) HANGUL SYLLABLE GEUC
+AE10;AE10;1100 1173 11BF;AE10;1100 1173 11BF; # (긐; 긐; 긐; 긐; 긐; ) HANGUL SYLLABLE GEUK
+AE11;AE11;1100 1173 11C0;AE11;1100 1173 11C0; # (긑; 긑; 긑; 긑; 긑; ) HANGUL SYLLABLE GEUT
+AE12;AE12;1100 1173 11C1;AE12;1100 1173 11C1; # (긒; 긒; 긒; 긒; 긒; ) HANGUL SYLLABLE GEUP
+AE13;AE13;1100 1173 11C2;AE13;1100 1173 11C2; # (긓; 긓; 긓; 긓; 긓; ) HANGUL SYLLABLE GEUH
+AE14;AE14;1100 1174;AE14;1100 1174; # (긔; 긔; 긔; 긔; 긔; ) HANGUL SYLLABLE GYI
+AE15;AE15;1100 1174 11A8;AE15;1100 1174 11A8; # (긕; 긕; 긕; 긕; 긕; ) HANGUL SYLLABLE GYIG
+AE16;AE16;1100 1174 11A9;AE16;1100 1174 11A9; # (긖; 긖; 긖; 긖; 긖; ) HANGUL SYLLABLE GYIGG
+AE17;AE17;1100 1174 11AA;AE17;1100 1174 11AA; # (긗; 긗; 긗; 긗; 긗; ) HANGUL SYLLABLE GYIGS
+AE18;AE18;1100 1174 11AB;AE18;1100 1174 11AB; # (긘; 긘; 긘; 긘; 긘; ) HANGUL SYLLABLE GYIN
+AE19;AE19;1100 1174 11AC;AE19;1100 1174 11AC; # (긙; 긙; 긙; 긙; 긙; ) HANGUL SYLLABLE GYINJ
+AE1A;AE1A;1100 1174 11AD;AE1A;1100 1174 11AD; # (긚; 긚; 긚; 긚; 긚; ) HANGUL SYLLABLE GYINH
+AE1B;AE1B;1100 1174 11AE;AE1B;1100 1174 11AE; # (긛; 긛; 긛; 긛; 긛; ) HANGUL SYLLABLE GYID
+AE1C;AE1C;1100 1174 11AF;AE1C;1100 1174 11AF; # (긜; 긜; 긜; 긜; 긜; ) HANGUL SYLLABLE GYIL
+AE1D;AE1D;1100 1174 11B0;AE1D;1100 1174 11B0; # (긝; 긝; 긝; 긝; 긝; ) HANGUL SYLLABLE GYILG
+AE1E;AE1E;1100 1174 11B1;AE1E;1100 1174 11B1; # (긞; 긞; 긞; 긞; 긞; ) HANGUL SYLLABLE GYILM
+AE1F;AE1F;1100 1174 11B2;AE1F;1100 1174 11B2; # (긟; 긟; 긟; 긟; 긟; ) HANGUL SYLLABLE GYILB
+AE20;AE20;1100 1174 11B3;AE20;1100 1174 11B3; # (긠; 긠; 긠; 긠; 긠; ) HANGUL SYLLABLE GYILS
+AE21;AE21;1100 1174 11B4;AE21;1100 1174 11B4; # (긡; 긡; 긡; 긡; 긡; ) HANGUL SYLLABLE GYILT
+AE22;AE22;1100 1174 11B5;AE22;1100 1174 11B5; # (긢; 긢; 긢; 긢; 긢; ) HANGUL SYLLABLE GYILP
+AE23;AE23;1100 1174 11B6;AE23;1100 1174 11B6; # (긣; 긣; 긣; 긣; 긣; ) HANGUL SYLLABLE GYILH
+AE24;AE24;1100 1174 11B7;AE24;1100 1174 11B7; # (긤; 긤; 긤; 긤; 긤; ) HANGUL SYLLABLE GYIM
+AE25;AE25;1100 1174 11B8;AE25;1100 1174 11B8; # (긥; 긥; 긥; 긥; 긥; ) HANGUL SYLLABLE GYIB
+AE26;AE26;1100 1174 11B9;AE26;1100 1174 11B9; # (긦; 긦; 긦; 긦; 긦; ) HANGUL SYLLABLE GYIBS
+AE27;AE27;1100 1174 11BA;AE27;1100 1174 11BA; # (긧; 긧; 긧; 긧; 긧; ) HANGUL SYLLABLE GYIS
+AE28;AE28;1100 1174 11BB;AE28;1100 1174 11BB; # (긨; 긨; 긨; 긨; 긨; ) HANGUL SYLLABLE GYISS
+AE29;AE29;1100 1174 11BC;AE29;1100 1174 11BC; # (긩; 긩; 긩; 긩; 긩; ) HANGUL SYLLABLE GYING
+AE2A;AE2A;1100 1174 11BD;AE2A;1100 1174 11BD; # (긪; 긪; 긪; 긪; 긪; ) HANGUL SYLLABLE GYIJ
+AE2B;AE2B;1100 1174 11BE;AE2B;1100 1174 11BE; # (긫; 긫; 긫; 긫; 긫; ) HANGUL SYLLABLE GYIC
+AE2C;AE2C;1100 1174 11BF;AE2C;1100 1174 11BF; # (긬; 긬; 긬; 긬; 긬; ) HANGUL SYLLABLE GYIK
+AE2D;AE2D;1100 1174 11C0;AE2D;1100 1174 11C0; # (긭; 긭; 긭; 긭; 긭; ) HANGUL SYLLABLE GYIT
+AE2E;AE2E;1100 1174 11C1;AE2E;1100 1174 11C1; # (긮; 긮; 긮; 긮; 긮; ) HANGUL SYLLABLE GYIP
+AE2F;AE2F;1100 1174 11C2;AE2F;1100 1174 11C2; # (긯; 긯; 긯; 긯; 긯; ) HANGUL SYLLABLE GYIH
+AE30;AE30;1100 1175;AE30;1100 1175; # (기; 기; 기; 기; 기; ) HANGUL SYLLABLE GI
+AE31;AE31;1100 1175 11A8;AE31;1100 1175 11A8; # (긱; 긱; 긱; 긱; 긱; ) HANGUL SYLLABLE GIG
+AE32;AE32;1100 1175 11A9;AE32;1100 1175 11A9; # (긲; 긲; 긲; 긲; 긲; ) HANGUL SYLLABLE GIGG
+AE33;AE33;1100 1175 11AA;AE33;1100 1175 11AA; # (긳; 긳; 긳; 긳; 긳; ) HANGUL SYLLABLE GIGS
+AE34;AE34;1100 1175 11AB;AE34;1100 1175 11AB; # (긴; 긴; 긴; 긴; 긴; ) HANGUL SYLLABLE GIN
+AE35;AE35;1100 1175 11AC;AE35;1100 1175 11AC; # (긵; 긵; 긵; 긵; 긵; ) HANGUL SYLLABLE GINJ
+AE36;AE36;1100 1175 11AD;AE36;1100 1175 11AD; # (긶; 긶; 긶; 긶; 긶; ) HANGUL SYLLABLE GINH
+AE37;AE37;1100 1175 11AE;AE37;1100 1175 11AE; # (긷; 긷; 긷; 긷; 긷; ) HANGUL SYLLABLE GID
+AE38;AE38;1100 1175 11AF;AE38;1100 1175 11AF; # (길; 길; 길; 길; 길; ) HANGUL SYLLABLE GIL
+AE39;AE39;1100 1175 11B0;AE39;1100 1175 11B0; # (긹; 긹; 긹; 긹; 긹; ) HANGUL SYLLABLE GILG
+AE3A;AE3A;1100 1175 11B1;AE3A;1100 1175 11B1; # (긺; 긺; 긺; 긺; 긺; ) HANGUL SYLLABLE GILM
+AE3B;AE3B;1100 1175 11B2;AE3B;1100 1175 11B2; # (긻; 긻; 긻; 긻; 긻; ) HANGUL SYLLABLE GILB
+AE3C;AE3C;1100 1175 11B3;AE3C;1100 1175 11B3; # (긼; 긼; 긼; 긼; 긼; ) HANGUL SYLLABLE GILS
+AE3D;AE3D;1100 1175 11B4;AE3D;1100 1175 11B4; # (긽; 긽; 긽; 긽; 긽; ) HANGUL SYLLABLE GILT
+AE3E;AE3E;1100 1175 11B5;AE3E;1100 1175 11B5; # (긾; 긾; 긾; 긾; 긾; ) HANGUL SYLLABLE GILP
+AE3F;AE3F;1100 1175 11B6;AE3F;1100 1175 11B6; # (긿; 긿; 긿; 긿; 긿; ) HANGUL SYLLABLE GILH
+AE40;AE40;1100 1175 11B7;AE40;1100 1175 11B7; # (김; 김; 김; 김; 김; ) HANGUL SYLLABLE GIM
+AE41;AE41;1100 1175 11B8;AE41;1100 1175 11B8; # (깁; 깁; 깁; 깁; 깁; ) HANGUL SYLLABLE GIB
+AE42;AE42;1100 1175 11B9;AE42;1100 1175 11B9; # (깂; 깂; 깂; 깂; 깂; ) HANGUL SYLLABLE GIBS
+AE43;AE43;1100 1175 11BA;AE43;1100 1175 11BA; # (깃; 깃; 깃; 깃; 깃; ) HANGUL SYLLABLE GIS
+AE44;AE44;1100 1175 11BB;AE44;1100 1175 11BB; # (깄; 깄; 깄; 깄; 깄; ) HANGUL SYLLABLE GISS
+AE45;AE45;1100 1175 11BC;AE45;1100 1175 11BC; # (깅; 깅; 깅; 깅; 깅; ) HANGUL SYLLABLE GING
+AE46;AE46;1100 1175 11BD;AE46;1100 1175 11BD; # (깆; 깆; 깆; 깆; 깆; ) HANGUL SYLLABLE GIJ
+AE47;AE47;1100 1175 11BE;AE47;1100 1175 11BE; # (깇; 깇; 깇; 깇; 깇; ) HANGUL SYLLABLE GIC
+AE48;AE48;1100 1175 11BF;AE48;1100 1175 11BF; # (깈; 깈; 깈; 깈; 깈; ) HANGUL SYLLABLE GIK
+AE49;AE49;1100 1175 11C0;AE49;1100 1175 11C0; # (깉; 깉; 깉; 깉; 깉; ) HANGUL SYLLABLE GIT
+AE4A;AE4A;1100 1175 11C1;AE4A;1100 1175 11C1; # (깊; 깊; 깊; 깊; 깊; ) HANGUL SYLLABLE GIP
+AE4B;AE4B;1100 1175 11C2;AE4B;1100 1175 11C2; # (깋; 깋; 깋; 깋; 깋; ) HANGUL SYLLABLE GIH
+AE4C;AE4C;1101 1161;AE4C;1101 1161; # (까; 까; 까; 까; 까; ) HANGUL SYLLABLE GGA
+AE4D;AE4D;1101 1161 11A8;AE4D;1101 1161 11A8; # (깍; 깍; 깍; 깍; 깍; ) HANGUL SYLLABLE GGAG
+AE4E;AE4E;1101 1161 11A9;AE4E;1101 1161 11A9; # (깎; 깎; 깎; 깎; 깎; ) HANGUL SYLLABLE GGAGG
+AE4F;AE4F;1101 1161 11AA;AE4F;1101 1161 11AA; # (깏; 깏; 깏; 깏; 깏; ) HANGUL SYLLABLE GGAGS
+AE50;AE50;1101 1161 11AB;AE50;1101 1161 11AB; # (깐; 깐; 깐; 깐; 깐; ) HANGUL SYLLABLE GGAN
+AE51;AE51;1101 1161 11AC;AE51;1101 1161 11AC; # (깑; 깑; 깑; 깑; 깑; ) HANGUL SYLLABLE GGANJ
+AE52;AE52;1101 1161 11AD;AE52;1101 1161 11AD; # (깒; 깒; 깒; 깒; 깒; ) HANGUL SYLLABLE GGANH
+AE53;AE53;1101 1161 11AE;AE53;1101 1161 11AE; # (깓; 깓; 깓; 깓; 깓; ) HANGUL SYLLABLE GGAD
+AE54;AE54;1101 1161 11AF;AE54;1101 1161 11AF; # (깔; 깔; 깔; 깔; 깔; ) HANGUL SYLLABLE GGAL
+AE55;AE55;1101 1161 11B0;AE55;1101 1161 11B0; # (깕; 깕; 깕; 깕; 깕; ) HANGUL SYLLABLE GGALG
+AE56;AE56;1101 1161 11B1;AE56;1101 1161 11B1; # (깖; 깖; 깖; 깖; 깖; ) HANGUL SYLLABLE GGALM
+AE57;AE57;1101 1161 11B2;AE57;1101 1161 11B2; # (깗; 깗; 깗; 깗; 깗; ) HANGUL SYLLABLE GGALB
+AE58;AE58;1101 1161 11B3;AE58;1101 1161 11B3; # (깘; 깘; 깘; 깘; 깘; ) HANGUL SYLLABLE GGALS
+AE59;AE59;1101 1161 11B4;AE59;1101 1161 11B4; # (깙; 깙; 깙; 깙; 깙; ) HANGUL SYLLABLE GGALT
+AE5A;AE5A;1101 1161 11B5;AE5A;1101 1161 11B5; # (깚; 깚; 깚; 깚; 깚; ) HANGUL SYLLABLE GGALP
+AE5B;AE5B;1101 1161 11B6;AE5B;1101 1161 11B6; # (깛; 깛; 깛; 깛; 깛; ) HANGUL SYLLABLE GGALH
+AE5C;AE5C;1101 1161 11B7;AE5C;1101 1161 11B7; # (깜; 깜; 깜; 깜; 깜; ) HANGUL SYLLABLE GGAM
+AE5D;AE5D;1101 1161 11B8;AE5D;1101 1161 11B8; # (깝; 깝; 깝; 깝; 깝; ) HANGUL SYLLABLE GGAB
+AE5E;AE5E;1101 1161 11B9;AE5E;1101 1161 11B9; # (깞; 깞; 깞; 깞; 깞; ) HANGUL SYLLABLE GGABS
+AE5F;AE5F;1101 1161 11BA;AE5F;1101 1161 11BA; # (깟; 깟; 깟; 깟; 깟; ) HANGUL SYLLABLE GGAS
+AE60;AE60;1101 1161 11BB;AE60;1101 1161 11BB; # (깠; 깠; 깠; 깠; 깠; ) HANGUL SYLLABLE GGASS
+AE61;AE61;1101 1161 11BC;AE61;1101 1161 11BC; # (깡; 깡; 깡; 깡; 깡; ) HANGUL SYLLABLE GGANG
+AE62;AE62;1101 1161 11BD;AE62;1101 1161 11BD; # (깢; 깢; 깢; 깢; 깢; ) HANGUL SYLLABLE GGAJ
+AE63;AE63;1101 1161 11BE;AE63;1101 1161 11BE; # (깣; 깣; 깣; 깣; 깣; ) HANGUL SYLLABLE GGAC
+AE64;AE64;1101 1161 11BF;AE64;1101 1161 11BF; # (깤; 깤; 깤; 깤; 깤; ) HANGUL SYLLABLE GGAK
+AE65;AE65;1101 1161 11C0;AE65;1101 1161 11C0; # (깥; 깥; 깥; 깥; 깥; ) HANGUL SYLLABLE GGAT
+AE66;AE66;1101 1161 11C1;AE66;1101 1161 11C1; # (깦; 깦; 깦; 깦; 깦; ) HANGUL SYLLABLE GGAP
+AE67;AE67;1101 1161 11C2;AE67;1101 1161 11C2; # (깧; 깧; 깧; 깧; 깧; ) HANGUL SYLLABLE GGAH
+AE68;AE68;1101 1162;AE68;1101 1162; # (깨; 깨; 깨; 깨; 깨; ) HANGUL SYLLABLE GGAE
+AE69;AE69;1101 1162 11A8;AE69;1101 1162 11A8; # (깩; 깩; 깩; 깩; 깩; ) HANGUL SYLLABLE GGAEG
+AE6A;AE6A;1101 1162 11A9;AE6A;1101 1162 11A9; # (깪; 깪; 깪; 깪; 깪; ) HANGUL SYLLABLE GGAEGG
+AE6B;AE6B;1101 1162 11AA;AE6B;1101 1162 11AA; # (깫; 깫; 깫; 깫; 깫; ) HANGUL SYLLABLE GGAEGS
+AE6C;AE6C;1101 1162 11AB;AE6C;1101 1162 11AB; # (깬; 깬; 깬; 깬; 깬; ) HANGUL SYLLABLE GGAEN
+AE6D;AE6D;1101 1162 11AC;AE6D;1101 1162 11AC; # (깭; 깭; 깭; 깭; 깭; ) HANGUL SYLLABLE GGAENJ
+AE6E;AE6E;1101 1162 11AD;AE6E;1101 1162 11AD; # (깮; 깮; 깮; 깮; 깮; ) HANGUL SYLLABLE GGAENH
+AE6F;AE6F;1101 1162 11AE;AE6F;1101 1162 11AE; # (깯; 깯; 깯; 깯; 깯; ) HANGUL SYLLABLE GGAED
+AE70;AE70;1101 1162 11AF;AE70;1101 1162 11AF; # (깰; 깰; 깰; 깰; 깰; ) HANGUL SYLLABLE GGAEL
+AE71;AE71;1101 1162 11B0;AE71;1101 1162 11B0; # (깱; 깱; 깱; 깱; 깱; ) HANGUL SYLLABLE GGAELG
+AE72;AE72;1101 1162 11B1;AE72;1101 1162 11B1; # (깲; 깲; 깲; 깲; 깲; ) HANGUL SYLLABLE GGAELM
+AE73;AE73;1101 1162 11B2;AE73;1101 1162 11B2; # (깳; 깳; 깳; 깳; 깳; ) HANGUL SYLLABLE GGAELB
+AE74;AE74;1101 1162 11B3;AE74;1101 1162 11B3; # (깴; 깴; 깴; 깴; 깴; ) HANGUL SYLLABLE GGAELS
+AE75;AE75;1101 1162 11B4;AE75;1101 1162 11B4; # (깵; 깵; 깵; 깵; 깵; ) HANGUL SYLLABLE GGAELT
+AE76;AE76;1101 1162 11B5;AE76;1101 1162 11B5; # (깶; 깶; 깶; 깶; 깶; ) HANGUL SYLLABLE GGAELP
+AE77;AE77;1101 1162 11B6;AE77;1101 1162 11B6; # (깷; 깷; 깷; 깷; 깷; ) HANGUL SYLLABLE GGAELH
+AE78;AE78;1101 1162 11B7;AE78;1101 1162 11B7; # (깸; 깸; 깸; 깸; 깸; ) HANGUL SYLLABLE GGAEM
+AE79;AE79;1101 1162 11B8;AE79;1101 1162 11B8; # (깹; 깹; 깹; 깹; 깹; ) HANGUL SYLLABLE GGAEB
+AE7A;AE7A;1101 1162 11B9;AE7A;1101 1162 11B9; # (깺; 깺; 깺; 깺; 깺; ) HANGUL SYLLABLE GGAEBS
+AE7B;AE7B;1101 1162 11BA;AE7B;1101 1162 11BA; # (깻; 깻; 깻; 깻; 깻; ) HANGUL SYLLABLE GGAES
+AE7C;AE7C;1101 1162 11BB;AE7C;1101 1162 11BB; # (깼; 깼; 깼; 깼; 깼; ) HANGUL SYLLABLE GGAESS
+AE7D;AE7D;1101 1162 11BC;AE7D;1101 1162 11BC; # (깽; 깽; 깽; 깽; 깽; ) HANGUL SYLLABLE GGAENG
+AE7E;AE7E;1101 1162 11BD;AE7E;1101 1162 11BD; # (깾; 깾; 깾; 깾; 깾; ) HANGUL SYLLABLE GGAEJ
+AE7F;AE7F;1101 1162 11BE;AE7F;1101 1162 11BE; # (깿; 깿; 깿; 깿; 깿; ) HANGUL SYLLABLE GGAEC
+AE80;AE80;1101 1162 11BF;AE80;1101 1162 11BF; # (꺀; 꺀; 꺀; 꺀; 꺀; ) HANGUL SYLLABLE GGAEK
+AE81;AE81;1101 1162 11C0;AE81;1101 1162 11C0; # (꺁; 꺁; 꺁; 꺁; 꺁; ) HANGUL SYLLABLE GGAET
+AE82;AE82;1101 1162 11C1;AE82;1101 1162 11C1; # (꺂; 꺂; 꺂; 꺂; 꺂; ) HANGUL SYLLABLE GGAEP
+AE83;AE83;1101 1162 11C2;AE83;1101 1162 11C2; # (꺃; 꺃; 꺃; 꺃; 꺃; ) HANGUL SYLLABLE GGAEH
+AE84;AE84;1101 1163;AE84;1101 1163; # (꺄; 꺄; 꺄; 꺄; 꺄; ) HANGUL SYLLABLE GGYA
+AE85;AE85;1101 1163 11A8;AE85;1101 1163 11A8; # (꺅; 꺅; 꺅; 꺅; 꺅; ) HANGUL SYLLABLE GGYAG
+AE86;AE86;1101 1163 11A9;AE86;1101 1163 11A9; # (꺆; 꺆; 꺆; 꺆; 꺆; ) HANGUL SYLLABLE GGYAGG
+AE87;AE87;1101 1163 11AA;AE87;1101 1163 11AA; # (꺇; 꺇; 꺇; 꺇; 꺇; ) HANGUL SYLLABLE GGYAGS
+AE88;AE88;1101 1163 11AB;AE88;1101 1163 11AB; # (꺈; 꺈; 꺈; 꺈; 꺈; ) HANGUL SYLLABLE GGYAN
+AE89;AE89;1101 1163 11AC;AE89;1101 1163 11AC; # (꺉; 꺉; 꺉; 꺉; 꺉; ) HANGUL SYLLABLE GGYANJ
+AE8A;AE8A;1101 1163 11AD;AE8A;1101 1163 11AD; # (꺊; 꺊; 꺊; 꺊; 꺊; ) HANGUL SYLLABLE GGYANH
+AE8B;AE8B;1101 1163 11AE;AE8B;1101 1163 11AE; # (꺋; 꺋; 꺋; 꺋; 꺋; ) HANGUL SYLLABLE GGYAD
+AE8C;AE8C;1101 1163 11AF;AE8C;1101 1163 11AF; # (꺌; 꺌; 꺌; 꺌; 꺌; ) HANGUL SYLLABLE GGYAL
+AE8D;AE8D;1101 1163 11B0;AE8D;1101 1163 11B0; # (꺍; 꺍; 꺍; 꺍; 꺍; ) HANGUL SYLLABLE GGYALG
+AE8E;AE8E;1101 1163 11B1;AE8E;1101 1163 11B1; # (꺎; 꺎; 꺎; 꺎; 꺎; ) HANGUL SYLLABLE GGYALM
+AE8F;AE8F;1101 1163 11B2;AE8F;1101 1163 11B2; # (꺏; 꺏; 꺏; 꺏; 꺏; ) HANGUL SYLLABLE GGYALB
+AE90;AE90;1101 1163 11B3;AE90;1101 1163 11B3; # (꺐; 꺐; 꺐; 꺐; 꺐; ) HANGUL SYLLABLE GGYALS
+AE91;AE91;1101 1163 11B4;AE91;1101 1163 11B4; # (꺑; 꺑; 꺑; 꺑; 꺑; ) HANGUL SYLLABLE GGYALT
+AE92;AE92;1101 1163 11B5;AE92;1101 1163 11B5; # (꺒; 꺒; 꺒; 꺒; 꺒; ) HANGUL SYLLABLE GGYALP
+AE93;AE93;1101 1163 11B6;AE93;1101 1163 11B6; # (꺓; 꺓; 꺓; 꺓; 꺓; ) HANGUL SYLLABLE GGYALH
+AE94;AE94;1101 1163 11B7;AE94;1101 1163 11B7; # (꺔; 꺔; 꺔; 꺔; 꺔; ) HANGUL SYLLABLE GGYAM
+AE95;AE95;1101 1163 11B8;AE95;1101 1163 11B8; # (꺕; 꺕; 꺕; 꺕; 꺕; ) HANGUL SYLLABLE GGYAB
+AE96;AE96;1101 1163 11B9;AE96;1101 1163 11B9; # (꺖; 꺖; 꺖; 꺖; 꺖; ) HANGUL SYLLABLE GGYABS
+AE97;AE97;1101 1163 11BA;AE97;1101 1163 11BA; # (꺗; 꺗; 꺗; 꺗; 꺗; ) HANGUL SYLLABLE GGYAS
+AE98;AE98;1101 1163 11BB;AE98;1101 1163 11BB; # (꺘; 꺘; 꺘; 꺘; 꺘; ) HANGUL SYLLABLE GGYASS
+AE99;AE99;1101 1163 11BC;AE99;1101 1163 11BC; # (꺙; 꺙; 꺙; 꺙; 꺙; ) HANGUL SYLLABLE GGYANG
+AE9A;AE9A;1101 1163 11BD;AE9A;1101 1163 11BD; # (꺚; 꺚; 꺚; 꺚; 꺚; ) HANGUL SYLLABLE GGYAJ
+AE9B;AE9B;1101 1163 11BE;AE9B;1101 1163 11BE; # (꺛; 꺛; 꺛; 꺛; 꺛; ) HANGUL SYLLABLE GGYAC
+AE9C;AE9C;1101 1163 11BF;AE9C;1101 1163 11BF; # (꺜; 꺜; 꺜; 꺜; 꺜; ) HANGUL SYLLABLE GGYAK
+AE9D;AE9D;1101 1163 11C0;AE9D;1101 1163 11C0; # (꺝; 꺝; 꺝; 꺝; 꺝; ) HANGUL SYLLABLE GGYAT
+AE9E;AE9E;1101 1163 11C1;AE9E;1101 1163 11C1; # (꺞; 꺞; 꺞; 꺞; 꺞; ) HANGUL SYLLABLE GGYAP
+AE9F;AE9F;1101 1163 11C2;AE9F;1101 1163 11C2; # (꺟; 꺟; 꺟; 꺟; 꺟; ) HANGUL SYLLABLE GGYAH
+AEA0;AEA0;1101 1164;AEA0;1101 1164; # (꺠; 꺠; 꺠; 꺠; 꺠; ) HANGUL SYLLABLE GGYAE
+AEA1;AEA1;1101 1164 11A8;AEA1;1101 1164 11A8; # (꺡; 꺡; 꺡; 꺡; 꺡; ) HANGUL SYLLABLE GGYAEG
+AEA2;AEA2;1101 1164 11A9;AEA2;1101 1164 11A9; # (꺢; 꺢; 꺢; 꺢; 꺢; ) HANGUL SYLLABLE GGYAEGG
+AEA3;AEA3;1101 1164 11AA;AEA3;1101 1164 11AA; # (꺣; 꺣; 꺣; 꺣; 꺣; ) HANGUL SYLLABLE GGYAEGS
+AEA4;AEA4;1101 1164 11AB;AEA4;1101 1164 11AB; # (꺤; 꺤; 꺤; 꺤; 꺤; ) HANGUL SYLLABLE GGYAEN
+AEA5;AEA5;1101 1164 11AC;AEA5;1101 1164 11AC; # (꺥; 꺥; 꺥; 꺥; 꺥; ) HANGUL SYLLABLE GGYAENJ
+AEA6;AEA6;1101 1164 11AD;AEA6;1101 1164 11AD; # (꺦; 꺦; 꺦; 꺦; 꺦; ) HANGUL SYLLABLE GGYAENH
+AEA7;AEA7;1101 1164 11AE;AEA7;1101 1164 11AE; # (꺧; 꺧; 꺧; 꺧; 꺧; ) HANGUL SYLLABLE GGYAED
+AEA8;AEA8;1101 1164 11AF;AEA8;1101 1164 11AF; # (꺨; 꺨; 꺨; 꺨; 꺨; ) HANGUL SYLLABLE GGYAEL
+AEA9;AEA9;1101 1164 11B0;AEA9;1101 1164 11B0; # (꺩; 꺩; 꺩; 꺩; 꺩; ) HANGUL SYLLABLE GGYAELG
+AEAA;AEAA;1101 1164 11B1;AEAA;1101 1164 11B1; # (꺪; 꺪; 꺪; 꺪; 꺪; ) HANGUL SYLLABLE GGYAELM
+AEAB;AEAB;1101 1164 11B2;AEAB;1101 1164 11B2; # (꺫; 꺫; 꺫; 꺫; 꺫; ) HANGUL SYLLABLE GGYAELB
+AEAC;AEAC;1101 1164 11B3;AEAC;1101 1164 11B3; # (꺬; 꺬; 꺬; 꺬; 꺬; ) HANGUL SYLLABLE GGYAELS
+AEAD;AEAD;1101 1164 11B4;AEAD;1101 1164 11B4; # (꺭; 꺭; 꺭; 꺭; 꺭; ) HANGUL SYLLABLE GGYAELT
+AEAE;AEAE;1101 1164 11B5;AEAE;1101 1164 11B5; # (꺮; 꺮; 꺮; 꺮; 꺮; ) HANGUL SYLLABLE GGYAELP
+AEAF;AEAF;1101 1164 11B6;AEAF;1101 1164 11B6; # (꺯; 꺯; 꺯; 꺯; 꺯; ) HANGUL SYLLABLE GGYAELH
+AEB0;AEB0;1101 1164 11B7;AEB0;1101 1164 11B7; # (꺰; 꺰; 꺰; 꺰; 꺰; ) HANGUL SYLLABLE GGYAEM
+AEB1;AEB1;1101 1164 11B8;AEB1;1101 1164 11B8; # (꺱; 꺱; 꺱; 꺱; 꺱; ) HANGUL SYLLABLE GGYAEB
+AEB2;AEB2;1101 1164 11B9;AEB2;1101 1164 11B9; # (꺲; 꺲; 꺲; 꺲; 꺲; ) HANGUL SYLLABLE GGYAEBS
+AEB3;AEB3;1101 1164 11BA;AEB3;1101 1164 11BA; # (꺳; 꺳; 꺳; 꺳; 꺳; ) HANGUL SYLLABLE GGYAES
+AEB4;AEB4;1101 1164 11BB;AEB4;1101 1164 11BB; # (꺴; 꺴; 꺴; 꺴; 꺴; ) HANGUL SYLLABLE GGYAESS
+AEB5;AEB5;1101 1164 11BC;AEB5;1101 1164 11BC; # (꺵; 꺵; 꺵; 꺵; 꺵; ) HANGUL SYLLABLE GGYAENG
+AEB6;AEB6;1101 1164 11BD;AEB6;1101 1164 11BD; # (꺶; 꺶; 꺶; 꺶; 꺶; ) HANGUL SYLLABLE GGYAEJ
+AEB7;AEB7;1101 1164 11BE;AEB7;1101 1164 11BE; # (꺷; 꺷; 꺷; 꺷; 꺷; ) HANGUL SYLLABLE GGYAEC
+AEB8;AEB8;1101 1164 11BF;AEB8;1101 1164 11BF; # (꺸; 꺸; 꺸; 꺸; 꺸; ) HANGUL SYLLABLE GGYAEK
+AEB9;AEB9;1101 1164 11C0;AEB9;1101 1164 11C0; # (꺹; 꺹; 꺹; 꺹; 꺹; ) HANGUL SYLLABLE GGYAET
+AEBA;AEBA;1101 1164 11C1;AEBA;1101 1164 11C1; # (꺺; 꺺; 꺺; 꺺; 꺺; ) HANGUL SYLLABLE GGYAEP
+AEBB;AEBB;1101 1164 11C2;AEBB;1101 1164 11C2; # (꺻; 꺻; 꺻; 꺻; 꺻; ) HANGUL SYLLABLE GGYAEH
+AEBC;AEBC;1101 1165;AEBC;1101 1165; # (꺼; 꺼; 꺼; 꺼; 꺼; ) HANGUL SYLLABLE GGEO
+AEBD;AEBD;1101 1165 11A8;AEBD;1101 1165 11A8; # (꺽; 꺽; 꺽; 꺽; 꺽; ) HANGUL SYLLABLE GGEOG
+AEBE;AEBE;1101 1165 11A9;AEBE;1101 1165 11A9; # (꺾; 꺾; 꺾; 꺾; 꺾; ) HANGUL SYLLABLE GGEOGG
+AEBF;AEBF;1101 1165 11AA;AEBF;1101 1165 11AA; # (꺿; 꺿; 꺿; 꺿; 꺿; ) HANGUL SYLLABLE GGEOGS
+AEC0;AEC0;1101 1165 11AB;AEC0;1101 1165 11AB; # (껀; 껀; 껀; 껀; 껀; ) HANGUL SYLLABLE GGEON
+AEC1;AEC1;1101 1165 11AC;AEC1;1101 1165 11AC; # (껁; 껁; 껁; 껁; 껁; ) HANGUL SYLLABLE GGEONJ
+AEC2;AEC2;1101 1165 11AD;AEC2;1101 1165 11AD; # (껂; 껂; 껂; 껂; 껂; ) HANGUL SYLLABLE GGEONH
+AEC3;AEC3;1101 1165 11AE;AEC3;1101 1165 11AE; # (껃; 껃; 껃; 껃; 껃; ) HANGUL SYLLABLE GGEOD
+AEC4;AEC4;1101 1165 11AF;AEC4;1101 1165 11AF; # (껄; 껄; 껄; 껄; 껄; ) HANGUL SYLLABLE GGEOL
+AEC5;AEC5;1101 1165 11B0;AEC5;1101 1165 11B0; # (껅; 껅; 껅; 껅; 껅; ) HANGUL SYLLABLE GGEOLG
+AEC6;AEC6;1101 1165 11B1;AEC6;1101 1165 11B1; # (껆; 껆; 껆; 껆; 껆; ) HANGUL SYLLABLE GGEOLM
+AEC7;AEC7;1101 1165 11B2;AEC7;1101 1165 11B2; # (껇; 껇; 껇; 껇; 껇; ) HANGUL SYLLABLE GGEOLB
+AEC8;AEC8;1101 1165 11B3;AEC8;1101 1165 11B3; # (껈; 껈; 껈; 껈; 껈; ) HANGUL SYLLABLE GGEOLS
+AEC9;AEC9;1101 1165 11B4;AEC9;1101 1165 11B4; # (껉; 껉; 껉; 껉; 껉; ) HANGUL SYLLABLE GGEOLT
+AECA;AECA;1101 1165 11B5;AECA;1101 1165 11B5; # (껊; 껊; 껊; 껊; 껊; ) HANGUL SYLLABLE GGEOLP
+AECB;AECB;1101 1165 11B6;AECB;1101 1165 11B6; # (껋; 껋; 껋; 껋; 껋; ) HANGUL SYLLABLE GGEOLH
+AECC;AECC;1101 1165 11B7;AECC;1101 1165 11B7; # (껌; 껌; 껌; 껌; 껌; ) HANGUL SYLLABLE GGEOM
+AECD;AECD;1101 1165 11B8;AECD;1101 1165 11B8; # (껍; 껍; 껍; 껍; 껍; ) HANGUL SYLLABLE GGEOB
+AECE;AECE;1101 1165 11B9;AECE;1101 1165 11B9; # (껎; 껎; 껎; 껎; 껎; ) HANGUL SYLLABLE GGEOBS
+AECF;AECF;1101 1165 11BA;AECF;1101 1165 11BA; # (껏; 껏; 껏; 껏; 껏; ) HANGUL SYLLABLE GGEOS
+AED0;AED0;1101 1165 11BB;AED0;1101 1165 11BB; # (껐; 껐; 껐; 껐; 껐; ) HANGUL SYLLABLE GGEOSS
+AED1;AED1;1101 1165 11BC;AED1;1101 1165 11BC; # (껑; 껑; 껑; 껑; 껑; ) HANGUL SYLLABLE GGEONG
+AED2;AED2;1101 1165 11BD;AED2;1101 1165 11BD; # (껒; 껒; 껒; 껒; 껒; ) HANGUL SYLLABLE GGEOJ
+AED3;AED3;1101 1165 11BE;AED3;1101 1165 11BE; # (껓; 껓; 껓; 껓; 껓; ) HANGUL SYLLABLE GGEOC
+AED4;AED4;1101 1165 11BF;AED4;1101 1165 11BF; # (껔; 껔; 껔; 껔; 껔; ) HANGUL SYLLABLE GGEOK
+AED5;AED5;1101 1165 11C0;AED5;1101 1165 11C0; # (껕; 껕; 껕; 껕; 껕; ) HANGUL SYLLABLE GGEOT
+AED6;AED6;1101 1165 11C1;AED6;1101 1165 11C1; # (껖; 껖; 껖; 껖; 껖; ) HANGUL SYLLABLE GGEOP
+AED7;AED7;1101 1165 11C2;AED7;1101 1165 11C2; # (껗; 껗; 껗; 껗; 껗; ) HANGUL SYLLABLE GGEOH
+AED8;AED8;1101 1166;AED8;1101 1166; # (께; 께; 께; 께; 께; ) HANGUL SYLLABLE GGE
+AED9;AED9;1101 1166 11A8;AED9;1101 1166 11A8; # (껙; 껙; 껙; 껙; 껙; ) HANGUL SYLLABLE GGEG
+AEDA;AEDA;1101 1166 11A9;AEDA;1101 1166 11A9; # (껚; 껚; 껚; 껚; 껚; ) HANGUL SYLLABLE GGEGG
+AEDB;AEDB;1101 1166 11AA;AEDB;1101 1166 11AA; # (껛; 껛; 껛; 껛; 껛; ) HANGUL SYLLABLE GGEGS
+AEDC;AEDC;1101 1166 11AB;AEDC;1101 1166 11AB; # (껜; 껜; 껜; 껜; 껜; ) HANGUL SYLLABLE GGEN
+AEDD;AEDD;1101 1166 11AC;AEDD;1101 1166 11AC; # (껝; 껝; 껝; 껝; 껝; ) HANGUL SYLLABLE GGENJ
+AEDE;AEDE;1101 1166 11AD;AEDE;1101 1166 11AD; # (껞; 껞; 껞; 껞; 껞; ) HANGUL SYLLABLE GGENH
+AEDF;AEDF;1101 1166 11AE;AEDF;1101 1166 11AE; # (껟; 껟; 껟; 껟; 껟; ) HANGUL SYLLABLE GGED
+AEE0;AEE0;1101 1166 11AF;AEE0;1101 1166 11AF; # (껠; 껠; 껠; 껠; 껠; ) HANGUL SYLLABLE GGEL
+AEE1;AEE1;1101 1166 11B0;AEE1;1101 1166 11B0; # (껡; 껡; 껡; 껡; 껡; ) HANGUL SYLLABLE GGELG
+AEE2;AEE2;1101 1166 11B1;AEE2;1101 1166 11B1; # (껢; 껢; 껢; 껢; 껢; ) HANGUL SYLLABLE GGELM
+AEE3;AEE3;1101 1166 11B2;AEE3;1101 1166 11B2; # (껣; 껣; 껣; 껣; 껣; ) HANGUL SYLLABLE GGELB
+AEE4;AEE4;1101 1166 11B3;AEE4;1101 1166 11B3; # (껤; 껤; 껤; 껤; 껤; ) HANGUL SYLLABLE GGELS
+AEE5;AEE5;1101 1166 11B4;AEE5;1101 1166 11B4; # (껥; 껥; 껥; 껥; 껥; ) HANGUL SYLLABLE GGELT
+AEE6;AEE6;1101 1166 11B5;AEE6;1101 1166 11B5; # (껦; 껦; 껦; 껦; 껦; ) HANGUL SYLLABLE GGELP
+AEE7;AEE7;1101 1166 11B6;AEE7;1101 1166 11B6; # (껧; 껧; 껧; 껧; 껧; ) HANGUL SYLLABLE GGELH
+AEE8;AEE8;1101 1166 11B7;AEE8;1101 1166 11B7; # (껨; 껨; 껨; 껨; 껨; ) HANGUL SYLLABLE GGEM
+AEE9;AEE9;1101 1166 11B8;AEE9;1101 1166 11B8; # (껩; 껩; 껩; 껩; 껩; ) HANGUL SYLLABLE GGEB
+AEEA;AEEA;1101 1166 11B9;AEEA;1101 1166 11B9; # (껪; 껪; 껪; 껪; 껪; ) HANGUL SYLLABLE GGEBS
+AEEB;AEEB;1101 1166 11BA;AEEB;1101 1166 11BA; # (껫; 껫; 껫; 껫; 껫; ) HANGUL SYLLABLE GGES
+AEEC;AEEC;1101 1166 11BB;AEEC;1101 1166 11BB; # (껬; 껬; 껬; 껬; 껬; ) HANGUL SYLLABLE GGESS
+AEED;AEED;1101 1166 11BC;AEED;1101 1166 11BC; # (껭; 껭; 껭; 껭; 껭; ) HANGUL SYLLABLE GGENG
+AEEE;AEEE;1101 1166 11BD;AEEE;1101 1166 11BD; # (껮; 껮; 껮; 껮; 껮; ) HANGUL SYLLABLE GGEJ
+AEEF;AEEF;1101 1166 11BE;AEEF;1101 1166 11BE; # (껯; 껯; 껯; 껯; 껯; ) HANGUL SYLLABLE GGEC
+AEF0;AEF0;1101 1166 11BF;AEF0;1101 1166 11BF; # (껰; 껰; 껰; 껰; 껰; ) HANGUL SYLLABLE GGEK
+AEF1;AEF1;1101 1166 11C0;AEF1;1101 1166 11C0; # (껱; 껱; 껱; 껱; 껱; ) HANGUL SYLLABLE GGET
+AEF2;AEF2;1101 1166 11C1;AEF2;1101 1166 11C1; # (껲; 껲; 껲; 껲; 껲; ) HANGUL SYLLABLE GGEP
+AEF3;AEF3;1101 1166 11C2;AEF3;1101 1166 11C2; # (껳; 껳; 껳; 껳; 껳; ) HANGUL SYLLABLE GGEH
+AEF4;AEF4;1101 1167;AEF4;1101 1167; # (껴; 껴; 껴; 껴; 껴; ) HANGUL SYLLABLE GGYEO
+AEF5;AEF5;1101 1167 11A8;AEF5;1101 1167 11A8; # (껵; 껵; 껵; 껵; 껵; ) HANGUL SYLLABLE GGYEOG
+AEF6;AEF6;1101 1167 11A9;AEF6;1101 1167 11A9; # (껶; 껶; 껶; 껶; 껶; ) HANGUL SYLLABLE GGYEOGG
+AEF7;AEF7;1101 1167 11AA;AEF7;1101 1167 11AA; # (껷; 껷; 껷; 껷; 껷; ) HANGUL SYLLABLE GGYEOGS
+AEF8;AEF8;1101 1167 11AB;AEF8;1101 1167 11AB; # (껸; 껸; 껸; 껸; 껸; ) HANGUL SYLLABLE GGYEON
+AEF9;AEF9;1101 1167 11AC;AEF9;1101 1167 11AC; # (껹; 껹; 껹; 껹; 껹; ) HANGUL SYLLABLE GGYEONJ
+AEFA;AEFA;1101 1167 11AD;AEFA;1101 1167 11AD; # (껺; 껺; 껺; 껺; 껺; ) HANGUL SYLLABLE GGYEONH
+AEFB;AEFB;1101 1167 11AE;AEFB;1101 1167 11AE; # (껻; 껻; 껻; 껻; 껻; ) HANGUL SYLLABLE GGYEOD
+AEFC;AEFC;1101 1167 11AF;AEFC;1101 1167 11AF; # (껼; 껼; 껼; 껼; 껼; ) HANGUL SYLLABLE GGYEOL
+AEFD;AEFD;1101 1167 11B0;AEFD;1101 1167 11B0; # (껽; 껽; 껽; 껽; 껽; ) HANGUL SYLLABLE GGYEOLG
+AEFE;AEFE;1101 1167 11B1;AEFE;1101 1167 11B1; # (껾; 껾; 껾; 껾; 껾; ) HANGUL SYLLABLE GGYEOLM
+AEFF;AEFF;1101 1167 11B2;AEFF;1101 1167 11B2; # (껿; 껿; 껿; 껿; 껿; ) HANGUL SYLLABLE GGYEOLB
+AF00;AF00;1101 1167 11B3;AF00;1101 1167 11B3; # (꼀; 꼀; 꼀; 꼀; 꼀; ) HANGUL SYLLABLE GGYEOLS
+AF01;AF01;1101 1167 11B4;AF01;1101 1167 11B4; # (꼁; 꼁; 꼁; 꼁; 꼁; ) HANGUL SYLLABLE GGYEOLT
+AF02;AF02;1101 1167 11B5;AF02;1101 1167 11B5; # (꼂; 꼂; 꼂; 꼂; 꼂; ) HANGUL SYLLABLE GGYEOLP
+AF03;AF03;1101 1167 11B6;AF03;1101 1167 11B6; # (꼃; 꼃; 꼃; 꼃; 꼃; ) HANGUL SYLLABLE GGYEOLH
+AF04;AF04;1101 1167 11B7;AF04;1101 1167 11B7; # (꼄; 꼄; 꼄; 꼄; 꼄; ) HANGUL SYLLABLE GGYEOM
+AF05;AF05;1101 1167 11B8;AF05;1101 1167 11B8; # (꼅; 꼅; 꼅; 꼅; 꼅; ) HANGUL SYLLABLE GGYEOB
+AF06;AF06;1101 1167 11B9;AF06;1101 1167 11B9; # (꼆; 꼆; 꼆; 꼆; 꼆; ) HANGUL SYLLABLE GGYEOBS
+AF07;AF07;1101 1167 11BA;AF07;1101 1167 11BA; # (꼇; 꼇; 꼇; 꼇; 꼇; ) HANGUL SYLLABLE GGYEOS
+AF08;AF08;1101 1167 11BB;AF08;1101 1167 11BB; # (꼈; 꼈; 꼈; 꼈; 꼈; ) HANGUL SYLLABLE GGYEOSS
+AF09;AF09;1101 1167 11BC;AF09;1101 1167 11BC; # (꼉; 꼉; 꼉; 꼉; 꼉; ) HANGUL SYLLABLE GGYEONG
+AF0A;AF0A;1101 1167 11BD;AF0A;1101 1167 11BD; # (꼊; 꼊; 꼊; 꼊; 꼊; ) HANGUL SYLLABLE GGYEOJ
+AF0B;AF0B;1101 1167 11BE;AF0B;1101 1167 11BE; # (꼋; 꼋; 꼋; 꼋; 꼋; ) HANGUL SYLLABLE GGYEOC
+AF0C;AF0C;1101 1167 11BF;AF0C;1101 1167 11BF; # (꼌; 꼌; 꼌; 꼌; 꼌; ) HANGUL SYLLABLE GGYEOK
+AF0D;AF0D;1101 1167 11C0;AF0D;1101 1167 11C0; # (꼍; 꼍; 꼍; 꼍; 꼍; ) HANGUL SYLLABLE GGYEOT
+AF0E;AF0E;1101 1167 11C1;AF0E;1101 1167 11C1; # (꼎; 꼎; 꼎; 꼎; 꼎; ) HANGUL SYLLABLE GGYEOP
+AF0F;AF0F;1101 1167 11C2;AF0F;1101 1167 11C2; # (꼏; 꼏; 꼏; 꼏; 꼏; ) HANGUL SYLLABLE GGYEOH
+AF10;AF10;1101 1168;AF10;1101 1168; # (꼐; 꼐; 꼐; 꼐; 꼐; ) HANGUL SYLLABLE GGYE
+AF11;AF11;1101 1168 11A8;AF11;1101 1168 11A8; # (꼑; 꼑; 꼑; 꼑; 꼑; ) HANGUL SYLLABLE GGYEG
+AF12;AF12;1101 1168 11A9;AF12;1101 1168 11A9; # (꼒; 꼒; 꼒; 꼒; 꼒; ) HANGUL SYLLABLE GGYEGG
+AF13;AF13;1101 1168 11AA;AF13;1101 1168 11AA; # (꼓; 꼓; 꼓; 꼓; 꼓; ) HANGUL SYLLABLE GGYEGS
+AF14;AF14;1101 1168 11AB;AF14;1101 1168 11AB; # (꼔; 꼔; 꼔; 꼔; 꼔; ) HANGUL SYLLABLE GGYEN
+AF15;AF15;1101 1168 11AC;AF15;1101 1168 11AC; # (꼕; 꼕; 꼕; 꼕; 꼕; ) HANGUL SYLLABLE GGYENJ
+AF16;AF16;1101 1168 11AD;AF16;1101 1168 11AD; # (꼖; 꼖; 꼖; 꼖; 꼖; ) HANGUL SYLLABLE GGYENH
+AF17;AF17;1101 1168 11AE;AF17;1101 1168 11AE; # (꼗; 꼗; 꼗; 꼗; 꼗; ) HANGUL SYLLABLE GGYED
+AF18;AF18;1101 1168 11AF;AF18;1101 1168 11AF; # (꼘; 꼘; 꼘; 꼘; 꼘; ) HANGUL SYLLABLE GGYEL
+AF19;AF19;1101 1168 11B0;AF19;1101 1168 11B0; # (꼙; 꼙; 꼙; 꼙; 꼙; ) HANGUL SYLLABLE GGYELG
+AF1A;AF1A;1101 1168 11B1;AF1A;1101 1168 11B1; # (꼚; 꼚; 꼚; 꼚; 꼚; ) HANGUL SYLLABLE GGYELM
+AF1B;AF1B;1101 1168 11B2;AF1B;1101 1168 11B2; # (꼛; 꼛; 꼛; 꼛; 꼛; ) HANGUL SYLLABLE GGYELB
+AF1C;AF1C;1101 1168 11B3;AF1C;1101 1168 11B3; # (꼜; 꼜; 꼜; 꼜; 꼜; ) HANGUL SYLLABLE GGYELS
+AF1D;AF1D;1101 1168 11B4;AF1D;1101 1168 11B4; # (꼝; 꼝; 꼝; 꼝; 꼝; ) HANGUL SYLLABLE GGYELT
+AF1E;AF1E;1101 1168 11B5;AF1E;1101 1168 11B5; # (꼞; 꼞; 꼞; 꼞; 꼞; ) HANGUL SYLLABLE GGYELP
+AF1F;AF1F;1101 1168 11B6;AF1F;1101 1168 11B6; # (꼟; 꼟; 꼟; 꼟; 꼟; ) HANGUL SYLLABLE GGYELH
+AF20;AF20;1101 1168 11B7;AF20;1101 1168 11B7; # (꼠; 꼠; 꼠; 꼠; 꼠; ) HANGUL SYLLABLE GGYEM
+AF21;AF21;1101 1168 11B8;AF21;1101 1168 11B8; # (꼡; 꼡; 꼡; 꼡; 꼡; ) HANGUL SYLLABLE GGYEB
+AF22;AF22;1101 1168 11B9;AF22;1101 1168 11B9; # (꼢; 꼢; 꼢; 꼢; 꼢; ) HANGUL SYLLABLE GGYEBS
+AF23;AF23;1101 1168 11BA;AF23;1101 1168 11BA; # (꼣; 꼣; 꼣; 꼣; 꼣; ) HANGUL SYLLABLE GGYES
+AF24;AF24;1101 1168 11BB;AF24;1101 1168 11BB; # (꼤; 꼤; 꼤; 꼤; 꼤; ) HANGUL SYLLABLE GGYESS
+AF25;AF25;1101 1168 11BC;AF25;1101 1168 11BC; # (꼥; 꼥; 꼥; 꼥; 꼥; ) HANGUL SYLLABLE GGYENG
+AF26;AF26;1101 1168 11BD;AF26;1101 1168 11BD; # (꼦; 꼦; 꼦; 꼦; 꼦; ) HANGUL SYLLABLE GGYEJ
+AF27;AF27;1101 1168 11BE;AF27;1101 1168 11BE; # (꼧; 꼧; 꼧; 꼧; 꼧; ) HANGUL SYLLABLE GGYEC
+AF28;AF28;1101 1168 11BF;AF28;1101 1168 11BF; # (꼨; 꼨; 꼨; 꼨; 꼨; ) HANGUL SYLLABLE GGYEK
+AF29;AF29;1101 1168 11C0;AF29;1101 1168 11C0; # (꼩; 꼩; 꼩; 꼩; 꼩; ) HANGUL SYLLABLE GGYET
+AF2A;AF2A;1101 1168 11C1;AF2A;1101 1168 11C1; # (꼪; 꼪; 꼪; 꼪; 꼪; ) HANGUL SYLLABLE GGYEP
+AF2B;AF2B;1101 1168 11C2;AF2B;1101 1168 11C2; # (꼫; 꼫; 꼫; 꼫; 꼫; ) HANGUL SYLLABLE GGYEH
+AF2C;AF2C;1101 1169;AF2C;1101 1169; # (꼬; 꼬; 꼬; 꼬; 꼬; ) HANGUL SYLLABLE GGO
+AF2D;AF2D;1101 1169 11A8;AF2D;1101 1169 11A8; # (꼭; 꼭; 꼭; 꼭; 꼭; ) HANGUL SYLLABLE GGOG
+AF2E;AF2E;1101 1169 11A9;AF2E;1101 1169 11A9; # (꼮; 꼮; 꼮; 꼮; 꼮; ) HANGUL SYLLABLE GGOGG
+AF2F;AF2F;1101 1169 11AA;AF2F;1101 1169 11AA; # (꼯; 꼯; 꼯; 꼯; 꼯; ) HANGUL SYLLABLE GGOGS
+AF30;AF30;1101 1169 11AB;AF30;1101 1169 11AB; # (꼰; 꼰; 꼰; 꼰; 꼰; ) HANGUL SYLLABLE GGON
+AF31;AF31;1101 1169 11AC;AF31;1101 1169 11AC; # (꼱; 꼱; 꼱; 꼱; 꼱; ) HANGUL SYLLABLE GGONJ
+AF32;AF32;1101 1169 11AD;AF32;1101 1169 11AD; # (꼲; 꼲; 꼲; 꼲; 꼲; ) HANGUL SYLLABLE GGONH
+AF33;AF33;1101 1169 11AE;AF33;1101 1169 11AE; # (꼳; 꼳; 꼳; 꼳; 꼳; ) HANGUL SYLLABLE GGOD
+AF34;AF34;1101 1169 11AF;AF34;1101 1169 11AF; # (꼴; 꼴; 꼴; 꼴; 꼴; ) HANGUL SYLLABLE GGOL
+AF35;AF35;1101 1169 11B0;AF35;1101 1169 11B0; # (꼵; 꼵; 꼵; 꼵; 꼵; ) HANGUL SYLLABLE GGOLG
+AF36;AF36;1101 1169 11B1;AF36;1101 1169 11B1; # (꼶; 꼶; 꼶; 꼶; 꼶; ) HANGUL SYLLABLE GGOLM
+AF37;AF37;1101 1169 11B2;AF37;1101 1169 11B2; # (꼷; 꼷; 꼷; 꼷; 꼷; ) HANGUL SYLLABLE GGOLB
+AF38;AF38;1101 1169 11B3;AF38;1101 1169 11B3; # (꼸; 꼸; 꼸; 꼸; 꼸; ) HANGUL SYLLABLE GGOLS
+AF39;AF39;1101 1169 11B4;AF39;1101 1169 11B4; # (꼹; 꼹; 꼹; 꼹; 꼹; ) HANGUL SYLLABLE GGOLT
+AF3A;AF3A;1101 1169 11B5;AF3A;1101 1169 11B5; # (꼺; 꼺; 꼺; 꼺; 꼺; ) HANGUL SYLLABLE GGOLP
+AF3B;AF3B;1101 1169 11B6;AF3B;1101 1169 11B6; # (꼻; 꼻; 꼻; 꼻; 꼻; ) HANGUL SYLLABLE GGOLH
+AF3C;AF3C;1101 1169 11B7;AF3C;1101 1169 11B7; # (꼼; 꼼; 꼼; 꼼; 꼼; ) HANGUL SYLLABLE GGOM
+AF3D;AF3D;1101 1169 11B8;AF3D;1101 1169 11B8; # (꼽; 꼽; 꼽; 꼽; 꼽; ) HANGUL SYLLABLE GGOB
+AF3E;AF3E;1101 1169 11B9;AF3E;1101 1169 11B9; # (꼾; 꼾; 꼾; 꼾; 꼾; ) HANGUL SYLLABLE GGOBS
+AF3F;AF3F;1101 1169 11BA;AF3F;1101 1169 11BA; # (꼿; 꼿; 꼿; 꼿; 꼿; ) HANGUL SYLLABLE GGOS
+AF40;AF40;1101 1169 11BB;AF40;1101 1169 11BB; # (꽀; 꽀; 꽀; 꽀; 꽀; ) HANGUL SYLLABLE GGOSS
+AF41;AF41;1101 1169 11BC;AF41;1101 1169 11BC; # (꽁; 꽁; 꽁; 꽁; 꽁; ) HANGUL SYLLABLE GGONG
+AF42;AF42;1101 1169 11BD;AF42;1101 1169 11BD; # (꽂; 꽂; 꽂; 꽂; 꽂; ) HANGUL SYLLABLE GGOJ
+AF43;AF43;1101 1169 11BE;AF43;1101 1169 11BE; # (꽃; 꽃; 꽃; 꽃; 꽃; ) HANGUL SYLLABLE GGOC
+AF44;AF44;1101 1169 11BF;AF44;1101 1169 11BF; # (꽄; 꽄; 꽄; 꽄; 꽄; ) HANGUL SYLLABLE GGOK
+AF45;AF45;1101 1169 11C0;AF45;1101 1169 11C0; # (꽅; 꽅; 꽅; 꽅; 꽅; ) HANGUL SYLLABLE GGOT
+AF46;AF46;1101 1169 11C1;AF46;1101 1169 11C1; # (꽆; 꽆; 꽆; 꽆; 꽆; ) HANGUL SYLLABLE GGOP
+AF47;AF47;1101 1169 11C2;AF47;1101 1169 11C2; # (꽇; 꽇; 꽇; 꽇; 꽇; ) HANGUL SYLLABLE GGOH
+AF48;AF48;1101 116A;AF48;1101 116A; # (꽈; 꽈; 꽈; 꽈; 꽈; ) HANGUL SYLLABLE GGWA
+AF49;AF49;1101 116A 11A8;AF49;1101 116A 11A8; # (꽉; 꽉; 꽉; 꽉; 꽉; ) HANGUL SYLLABLE GGWAG
+AF4A;AF4A;1101 116A 11A9;AF4A;1101 116A 11A9; # (꽊; 꽊; 꽊; 꽊; 꽊; ) HANGUL SYLLABLE GGWAGG
+AF4B;AF4B;1101 116A 11AA;AF4B;1101 116A 11AA; # (꽋; 꽋; 꽋; 꽋; 꽋; ) HANGUL SYLLABLE GGWAGS
+AF4C;AF4C;1101 116A 11AB;AF4C;1101 116A 11AB; # (꽌; 꽌; 꽌; 꽌; 꽌; ) HANGUL SYLLABLE GGWAN
+AF4D;AF4D;1101 116A 11AC;AF4D;1101 116A 11AC; # (꽍; 꽍; 꽍; 꽍; 꽍; ) HANGUL SYLLABLE GGWANJ
+AF4E;AF4E;1101 116A 11AD;AF4E;1101 116A 11AD; # (꽎; 꽎; 꽎; 꽎; 꽎; ) HANGUL SYLLABLE GGWANH
+AF4F;AF4F;1101 116A 11AE;AF4F;1101 116A 11AE; # (꽏; 꽏; 꽏; 꽏; 꽏; ) HANGUL SYLLABLE GGWAD
+AF50;AF50;1101 116A 11AF;AF50;1101 116A 11AF; # (꽐; 꽐; 꽐; 꽐; 꽐; ) HANGUL SYLLABLE GGWAL
+AF51;AF51;1101 116A 11B0;AF51;1101 116A 11B0; # (꽑; 꽑; 꽑; 꽑; 꽑; ) HANGUL SYLLABLE GGWALG
+AF52;AF52;1101 116A 11B1;AF52;1101 116A 11B1; # (꽒; 꽒; 꽒; 꽒; 꽒; ) HANGUL SYLLABLE GGWALM
+AF53;AF53;1101 116A 11B2;AF53;1101 116A 11B2; # (꽓; 꽓; 꽓; 꽓; 꽓; ) HANGUL SYLLABLE GGWALB
+AF54;AF54;1101 116A 11B3;AF54;1101 116A 11B3; # (꽔; 꽔; 꽔; 꽔; 꽔; ) HANGUL SYLLABLE GGWALS
+AF55;AF55;1101 116A 11B4;AF55;1101 116A 11B4; # (꽕; 꽕; 꽕; 꽕; 꽕; ) HANGUL SYLLABLE GGWALT
+AF56;AF56;1101 116A 11B5;AF56;1101 116A 11B5; # (꽖; 꽖; 꽖; 꽖; 꽖; ) HANGUL SYLLABLE GGWALP
+AF57;AF57;1101 116A 11B6;AF57;1101 116A 11B6; # (꽗; 꽗; 꽗; 꽗; 꽗; ) HANGUL SYLLABLE GGWALH
+AF58;AF58;1101 116A 11B7;AF58;1101 116A 11B7; # (꽘; 꽘; 꽘; 꽘; 꽘; ) HANGUL SYLLABLE GGWAM
+AF59;AF59;1101 116A 11B8;AF59;1101 116A 11B8; # (꽙; 꽙; 꽙; 꽙; 꽙; ) HANGUL SYLLABLE GGWAB
+AF5A;AF5A;1101 116A 11B9;AF5A;1101 116A 11B9; # (꽚; 꽚; 꽚; 꽚; 꽚; ) HANGUL SYLLABLE GGWABS
+AF5B;AF5B;1101 116A 11BA;AF5B;1101 116A 11BA; # (꽛; 꽛; 꽛; 꽛; 꽛; ) HANGUL SYLLABLE GGWAS
+AF5C;AF5C;1101 116A 11BB;AF5C;1101 116A 11BB; # (꽜; 꽜; 꽜; 꽜; 꽜; ) HANGUL SYLLABLE GGWASS
+AF5D;AF5D;1101 116A 11BC;AF5D;1101 116A 11BC; # (꽝; 꽝; 꽝; 꽝; 꽝; ) HANGUL SYLLABLE GGWANG
+AF5E;AF5E;1101 116A 11BD;AF5E;1101 116A 11BD; # (꽞; 꽞; 꽞; 꽞; 꽞; ) HANGUL SYLLABLE GGWAJ
+AF5F;AF5F;1101 116A 11BE;AF5F;1101 116A 11BE; # (꽟; 꽟; 꽟; 꽟; 꽟; ) HANGUL SYLLABLE GGWAC
+AF60;AF60;1101 116A 11BF;AF60;1101 116A 11BF; # (꽠; 꽠; 꽠; 꽠; 꽠; ) HANGUL SYLLABLE GGWAK
+AF61;AF61;1101 116A 11C0;AF61;1101 116A 11C0; # (꽡; 꽡; 꽡; 꽡; 꽡; ) HANGUL SYLLABLE GGWAT
+AF62;AF62;1101 116A 11C1;AF62;1101 116A 11C1; # (꽢; 꽢; 꽢; 꽢; 꽢; ) HANGUL SYLLABLE GGWAP
+AF63;AF63;1101 116A 11C2;AF63;1101 116A 11C2; # (꽣; 꽣; 꽣; 꽣; 꽣; ) HANGUL SYLLABLE GGWAH
+AF64;AF64;1101 116B;AF64;1101 116B; # (꽤; 꽤; 꽤; 꽤; 꽤; ) HANGUL SYLLABLE GGWAE
+AF65;AF65;1101 116B 11A8;AF65;1101 116B 11A8; # (꽥; 꽥; 꽥; 꽥; 꽥; ) HANGUL SYLLABLE GGWAEG
+AF66;AF66;1101 116B 11A9;AF66;1101 116B 11A9; # (꽦; 꽦; 꽦; 꽦; 꽦; ) HANGUL SYLLABLE GGWAEGG
+AF67;AF67;1101 116B 11AA;AF67;1101 116B 11AA; # (꽧; 꽧; 꽧; 꽧; 꽧; ) HANGUL SYLLABLE GGWAEGS
+AF68;AF68;1101 116B 11AB;AF68;1101 116B 11AB; # (꽨; 꽨; 꽨; 꽨; 꽨; ) HANGUL SYLLABLE GGWAEN
+AF69;AF69;1101 116B 11AC;AF69;1101 116B 11AC; # (꽩; 꽩; 꽩; 꽩; 꽩; ) HANGUL SYLLABLE GGWAENJ
+AF6A;AF6A;1101 116B 11AD;AF6A;1101 116B 11AD; # (꽪; 꽪; 꽪; 꽪; 꽪; ) HANGUL SYLLABLE GGWAENH
+AF6B;AF6B;1101 116B 11AE;AF6B;1101 116B 11AE; # (꽫; 꽫; 꽫; 꽫; 꽫; ) HANGUL SYLLABLE GGWAED
+AF6C;AF6C;1101 116B 11AF;AF6C;1101 116B 11AF; # (꽬; 꽬; 꽬; 꽬; 꽬; ) HANGUL SYLLABLE GGWAEL
+AF6D;AF6D;1101 116B 11B0;AF6D;1101 116B 11B0; # (꽭; 꽭; 꽭; 꽭; 꽭; ) HANGUL SYLLABLE GGWAELG
+AF6E;AF6E;1101 116B 11B1;AF6E;1101 116B 11B1; # (꽮; 꽮; 꽮; 꽮; 꽮; ) HANGUL SYLLABLE GGWAELM
+AF6F;AF6F;1101 116B 11B2;AF6F;1101 116B 11B2; # (꽯; 꽯; 꽯; 꽯; 꽯; ) HANGUL SYLLABLE GGWAELB
+AF70;AF70;1101 116B 11B3;AF70;1101 116B 11B3; # (꽰; 꽰; 꽰; 꽰; 꽰; ) HANGUL SYLLABLE GGWAELS
+AF71;AF71;1101 116B 11B4;AF71;1101 116B 11B4; # (꽱; 꽱; 꽱; 꽱; 꽱; ) HANGUL SYLLABLE GGWAELT
+AF72;AF72;1101 116B 11B5;AF72;1101 116B 11B5; # (꽲; 꽲; 꽲; 꽲; 꽲; ) HANGUL SYLLABLE GGWAELP
+AF73;AF73;1101 116B 11B6;AF73;1101 116B 11B6; # (꽳; 꽳; 꽳; 꽳; 꽳; ) HANGUL SYLLABLE GGWAELH
+AF74;AF74;1101 116B 11B7;AF74;1101 116B 11B7; # (꽴; 꽴; 꽴; 꽴; 꽴; ) HANGUL SYLLABLE GGWAEM
+AF75;AF75;1101 116B 11B8;AF75;1101 116B 11B8; # (꽵; 꽵; 꽵; 꽵; 꽵; ) HANGUL SYLLABLE GGWAEB
+AF76;AF76;1101 116B 11B9;AF76;1101 116B 11B9; # (꽶; 꽶; 꽶; 꽶; 꽶; ) HANGUL SYLLABLE GGWAEBS
+AF77;AF77;1101 116B 11BA;AF77;1101 116B 11BA; # (꽷; 꽷; 꽷; 꽷; 꽷; ) HANGUL SYLLABLE GGWAES
+AF78;AF78;1101 116B 11BB;AF78;1101 116B 11BB; # (꽸; 꽸; 꽸; 꽸; 꽸; ) HANGUL SYLLABLE GGWAESS
+AF79;AF79;1101 116B 11BC;AF79;1101 116B 11BC; # (꽹; 꽹; 꽹; 꽹; 꽹; ) HANGUL SYLLABLE GGWAENG
+AF7A;AF7A;1101 116B 11BD;AF7A;1101 116B 11BD; # (꽺; 꽺; 꽺; 꽺; 꽺; ) HANGUL SYLLABLE GGWAEJ
+AF7B;AF7B;1101 116B 11BE;AF7B;1101 116B 11BE; # (꽻; 꽻; 꽻; 꽻; 꽻; ) HANGUL SYLLABLE GGWAEC
+AF7C;AF7C;1101 116B 11BF;AF7C;1101 116B 11BF; # (꽼; 꽼; 꽼; 꽼; 꽼; ) HANGUL SYLLABLE GGWAEK
+AF7D;AF7D;1101 116B 11C0;AF7D;1101 116B 11C0; # (꽽; 꽽; 꽽; 꽽; 꽽; ) HANGUL SYLLABLE GGWAET
+AF7E;AF7E;1101 116B 11C1;AF7E;1101 116B 11C1; # (꽾; 꽾; 꽾; 꽾; 꽾; ) HANGUL SYLLABLE GGWAEP
+AF7F;AF7F;1101 116B 11C2;AF7F;1101 116B 11C2; # (꽿; 꽿; 꽿; 꽿; 꽿; ) HANGUL SYLLABLE GGWAEH
+AF80;AF80;1101 116C;AF80;1101 116C; # (꾀; 꾀; 꾀; 꾀; 꾀; ) HANGUL SYLLABLE GGOE
+AF81;AF81;1101 116C 11A8;AF81;1101 116C 11A8; # (꾁; 꾁; 꾁; 꾁; 꾁; ) HANGUL SYLLABLE GGOEG
+AF82;AF82;1101 116C 11A9;AF82;1101 116C 11A9; # (꾂; 꾂; 꾂; 꾂; 꾂; ) HANGUL SYLLABLE GGOEGG
+AF83;AF83;1101 116C 11AA;AF83;1101 116C 11AA; # (꾃; 꾃; 꾃; 꾃; 꾃; ) HANGUL SYLLABLE GGOEGS
+AF84;AF84;1101 116C 11AB;AF84;1101 116C 11AB; # (꾄; 꾄; 꾄; 꾄; 꾄; ) HANGUL SYLLABLE GGOEN
+AF85;AF85;1101 116C 11AC;AF85;1101 116C 11AC; # (꾅; 꾅; 꾅; 꾅; 꾅; ) HANGUL SYLLABLE GGOENJ
+AF86;AF86;1101 116C 11AD;AF86;1101 116C 11AD; # (꾆; 꾆; 꾆; 꾆; 꾆; ) HANGUL SYLLABLE GGOENH
+AF87;AF87;1101 116C 11AE;AF87;1101 116C 11AE; # (꾇; 꾇; 꾇; 꾇; 꾇; ) HANGUL SYLLABLE GGOED
+AF88;AF88;1101 116C 11AF;AF88;1101 116C 11AF; # (꾈; 꾈; 꾈; 꾈; 꾈; ) HANGUL SYLLABLE GGOEL
+AF89;AF89;1101 116C 11B0;AF89;1101 116C 11B0; # (꾉; 꾉; 꾉; 꾉; 꾉; ) HANGUL SYLLABLE GGOELG
+AF8A;AF8A;1101 116C 11B1;AF8A;1101 116C 11B1; # (꾊; 꾊; 꾊; 꾊; 꾊; ) HANGUL SYLLABLE GGOELM
+AF8B;AF8B;1101 116C 11B2;AF8B;1101 116C 11B2; # (꾋; 꾋; 꾋; 꾋; 꾋; ) HANGUL SYLLABLE GGOELB
+AF8C;AF8C;1101 116C 11B3;AF8C;1101 116C 11B3; # (꾌; 꾌; 꾌; 꾌; 꾌; ) HANGUL SYLLABLE GGOELS
+AF8D;AF8D;1101 116C 11B4;AF8D;1101 116C 11B4; # (꾍; 꾍; 꾍; 꾍; 꾍; ) HANGUL SYLLABLE GGOELT
+AF8E;AF8E;1101 116C 11B5;AF8E;1101 116C 11B5; # (꾎; 꾎; 꾎; 꾎; 꾎; ) HANGUL SYLLABLE GGOELP
+AF8F;AF8F;1101 116C 11B6;AF8F;1101 116C 11B6; # (꾏; 꾏; 꾏; 꾏; 꾏; ) HANGUL SYLLABLE GGOELH
+AF90;AF90;1101 116C 11B7;AF90;1101 116C 11B7; # (꾐; 꾐; 꾐; 꾐; 꾐; ) HANGUL SYLLABLE GGOEM
+AF91;AF91;1101 116C 11B8;AF91;1101 116C 11B8; # (꾑; 꾑; 꾑; 꾑; 꾑; ) HANGUL SYLLABLE GGOEB
+AF92;AF92;1101 116C 11B9;AF92;1101 116C 11B9; # (꾒; 꾒; 꾒; 꾒; 꾒; ) HANGUL SYLLABLE GGOEBS
+AF93;AF93;1101 116C 11BA;AF93;1101 116C 11BA; # (꾓; 꾓; 꾓; 꾓; 꾓; ) HANGUL SYLLABLE GGOES
+AF94;AF94;1101 116C 11BB;AF94;1101 116C 11BB; # (꾔; 꾔; 꾔; 꾔; 꾔; ) HANGUL SYLLABLE GGOESS
+AF95;AF95;1101 116C 11BC;AF95;1101 116C 11BC; # (꾕; 꾕; 꾕; 꾕; 꾕; ) HANGUL SYLLABLE GGOENG
+AF96;AF96;1101 116C 11BD;AF96;1101 116C 11BD; # (꾖; 꾖; 꾖; 꾖; 꾖; ) HANGUL SYLLABLE GGOEJ
+AF97;AF97;1101 116C 11BE;AF97;1101 116C 11BE; # (꾗; 꾗; 꾗; 꾗; 꾗; ) HANGUL SYLLABLE GGOEC
+AF98;AF98;1101 116C 11BF;AF98;1101 116C 11BF; # (꾘; 꾘; 꾘; 꾘; 꾘; ) HANGUL SYLLABLE GGOEK
+AF99;AF99;1101 116C 11C0;AF99;1101 116C 11C0; # (꾙; 꾙; 꾙; 꾙; 꾙; ) HANGUL SYLLABLE GGOET
+AF9A;AF9A;1101 116C 11C1;AF9A;1101 116C 11C1; # (꾚; 꾚; 꾚; 꾚; 꾚; ) HANGUL SYLLABLE GGOEP
+AF9B;AF9B;1101 116C 11C2;AF9B;1101 116C 11C2; # (꾛; 꾛; 꾛; 꾛; 꾛; ) HANGUL SYLLABLE GGOEH
+AF9C;AF9C;1101 116D;AF9C;1101 116D; # (꾜; 꾜; 꾜; 꾜; 꾜; ) HANGUL SYLLABLE GGYO
+AF9D;AF9D;1101 116D 11A8;AF9D;1101 116D 11A8; # (꾝; 꾝; 꾝; 꾝; 꾝; ) HANGUL SYLLABLE GGYOG
+AF9E;AF9E;1101 116D 11A9;AF9E;1101 116D 11A9; # (꾞; 꾞; 꾞; 꾞; 꾞; ) HANGUL SYLLABLE GGYOGG
+AF9F;AF9F;1101 116D 11AA;AF9F;1101 116D 11AA; # (꾟; 꾟; 꾟; 꾟; 꾟; ) HANGUL SYLLABLE GGYOGS
+AFA0;AFA0;1101 116D 11AB;AFA0;1101 116D 11AB; # (꾠; 꾠; 꾠; 꾠; 꾠; ) HANGUL SYLLABLE GGYON
+AFA1;AFA1;1101 116D 11AC;AFA1;1101 116D 11AC; # (꾡; 꾡; 꾡; 꾡; 꾡; ) HANGUL SYLLABLE GGYONJ
+AFA2;AFA2;1101 116D 11AD;AFA2;1101 116D 11AD; # (꾢; 꾢; 꾢; 꾢; 꾢; ) HANGUL SYLLABLE GGYONH
+AFA3;AFA3;1101 116D 11AE;AFA3;1101 116D 11AE; # (꾣; 꾣; 꾣; 꾣; 꾣; ) HANGUL SYLLABLE GGYOD
+AFA4;AFA4;1101 116D 11AF;AFA4;1101 116D 11AF; # (꾤; 꾤; 꾤; 꾤; 꾤; ) HANGUL SYLLABLE GGYOL
+AFA5;AFA5;1101 116D 11B0;AFA5;1101 116D 11B0; # (꾥; 꾥; 꾥; 꾥; 꾥; ) HANGUL SYLLABLE GGYOLG
+AFA6;AFA6;1101 116D 11B1;AFA6;1101 116D 11B1; # (꾦; 꾦; 꾦; 꾦; 꾦; ) HANGUL SYLLABLE GGYOLM
+AFA7;AFA7;1101 116D 11B2;AFA7;1101 116D 11B2; # (꾧; 꾧; 꾧; 꾧; 꾧; ) HANGUL SYLLABLE GGYOLB
+AFA8;AFA8;1101 116D 11B3;AFA8;1101 116D 11B3; # (꾨; 꾨; 꾨; 꾨; 꾨; ) HANGUL SYLLABLE GGYOLS
+AFA9;AFA9;1101 116D 11B4;AFA9;1101 116D 11B4; # (꾩; 꾩; 꾩; 꾩; 꾩; ) HANGUL SYLLABLE GGYOLT
+AFAA;AFAA;1101 116D 11B5;AFAA;1101 116D 11B5; # (꾪; 꾪; 꾪; 꾪; 꾪; ) HANGUL SYLLABLE GGYOLP
+AFAB;AFAB;1101 116D 11B6;AFAB;1101 116D 11B6; # (꾫; 꾫; 꾫; 꾫; 꾫; ) HANGUL SYLLABLE GGYOLH
+AFAC;AFAC;1101 116D 11B7;AFAC;1101 116D 11B7; # (꾬; 꾬; 꾬; 꾬; 꾬; ) HANGUL SYLLABLE GGYOM
+AFAD;AFAD;1101 116D 11B8;AFAD;1101 116D 11B8; # (꾭; 꾭; 꾭; 꾭; 꾭; ) HANGUL SYLLABLE GGYOB
+AFAE;AFAE;1101 116D 11B9;AFAE;1101 116D 11B9; # (꾮; 꾮; 꾮; 꾮; 꾮; ) HANGUL SYLLABLE GGYOBS
+AFAF;AFAF;1101 116D 11BA;AFAF;1101 116D 11BA; # (꾯; 꾯; 꾯; 꾯; 꾯; ) HANGUL SYLLABLE GGYOS
+AFB0;AFB0;1101 116D 11BB;AFB0;1101 116D 11BB; # (꾰; 꾰; 꾰; 꾰; 꾰; ) HANGUL SYLLABLE GGYOSS
+AFB1;AFB1;1101 116D 11BC;AFB1;1101 116D 11BC; # (꾱; 꾱; 꾱; 꾱; 꾱; ) HANGUL SYLLABLE GGYONG
+AFB2;AFB2;1101 116D 11BD;AFB2;1101 116D 11BD; # (꾲; 꾲; 꾲; 꾲; 꾲; ) HANGUL SYLLABLE GGYOJ
+AFB3;AFB3;1101 116D 11BE;AFB3;1101 116D 11BE; # (꾳; 꾳; 꾳; 꾳; 꾳; ) HANGUL SYLLABLE GGYOC
+AFB4;AFB4;1101 116D 11BF;AFB4;1101 116D 11BF; # (꾴; 꾴; 꾴; 꾴; 꾴; ) HANGUL SYLLABLE GGYOK
+AFB5;AFB5;1101 116D 11C0;AFB5;1101 116D 11C0; # (꾵; 꾵; 꾵; 꾵; 꾵; ) HANGUL SYLLABLE GGYOT
+AFB6;AFB6;1101 116D 11C1;AFB6;1101 116D 11C1; # (꾶; 꾶; 꾶; 꾶; 꾶; ) HANGUL SYLLABLE GGYOP
+AFB7;AFB7;1101 116D 11C2;AFB7;1101 116D 11C2; # (꾷; 꾷; 꾷; 꾷; 꾷; ) HANGUL SYLLABLE GGYOH
+AFB8;AFB8;1101 116E;AFB8;1101 116E; # (꾸; 꾸; 꾸; 꾸; 꾸; ) HANGUL SYLLABLE GGU
+AFB9;AFB9;1101 116E 11A8;AFB9;1101 116E 11A8; # (꾹; 꾹; 꾹; 꾹; 꾹; ) HANGUL SYLLABLE GGUG
+AFBA;AFBA;1101 116E 11A9;AFBA;1101 116E 11A9; # (꾺; 꾺; 꾺; 꾺; 꾺; ) HANGUL SYLLABLE GGUGG
+AFBB;AFBB;1101 116E 11AA;AFBB;1101 116E 11AA; # (꾻; 꾻; 꾻; 꾻; 꾻; ) HANGUL SYLLABLE GGUGS
+AFBC;AFBC;1101 116E 11AB;AFBC;1101 116E 11AB; # (꾼; 꾼; 꾼; 꾼; 꾼; ) HANGUL SYLLABLE GGUN
+AFBD;AFBD;1101 116E 11AC;AFBD;1101 116E 11AC; # (꾽; 꾽; 꾽; 꾽; 꾽; ) HANGUL SYLLABLE GGUNJ
+AFBE;AFBE;1101 116E 11AD;AFBE;1101 116E 11AD; # (꾾; 꾾; 꾾; 꾾; 꾾; ) HANGUL SYLLABLE GGUNH
+AFBF;AFBF;1101 116E 11AE;AFBF;1101 116E 11AE; # (꾿; 꾿; 꾿; 꾿; 꾿; ) HANGUL SYLLABLE GGUD
+AFC0;AFC0;1101 116E 11AF;AFC0;1101 116E 11AF; # (꿀; 꿀; 꿀; 꿀; 꿀; ) HANGUL SYLLABLE GGUL
+AFC1;AFC1;1101 116E 11B0;AFC1;1101 116E 11B0; # (꿁; 꿁; 꿁; 꿁; 꿁; ) HANGUL SYLLABLE GGULG
+AFC2;AFC2;1101 116E 11B1;AFC2;1101 116E 11B1; # (꿂; 꿂; 꿂; 꿂; 꿂; ) HANGUL SYLLABLE GGULM
+AFC3;AFC3;1101 116E 11B2;AFC3;1101 116E 11B2; # (꿃; 꿃; 꿃; 꿃; 꿃; ) HANGUL SYLLABLE GGULB
+AFC4;AFC4;1101 116E 11B3;AFC4;1101 116E 11B3; # (꿄; 꿄; 꿄; 꿄; 꿄; ) HANGUL SYLLABLE GGULS
+AFC5;AFC5;1101 116E 11B4;AFC5;1101 116E 11B4; # (꿅; 꿅; 꿅; 꿅; 꿅; ) HANGUL SYLLABLE GGULT
+AFC6;AFC6;1101 116E 11B5;AFC6;1101 116E 11B5; # (꿆; 꿆; 꿆; 꿆; 꿆; ) HANGUL SYLLABLE GGULP
+AFC7;AFC7;1101 116E 11B6;AFC7;1101 116E 11B6; # (꿇; 꿇; 꿇; 꿇; 꿇; ) HANGUL SYLLABLE GGULH
+AFC8;AFC8;1101 116E 11B7;AFC8;1101 116E 11B7; # (꿈; 꿈; 꿈; 꿈; 꿈; ) HANGUL SYLLABLE GGUM
+AFC9;AFC9;1101 116E 11B8;AFC9;1101 116E 11B8; # (꿉; 꿉; 꿉; 꿉; 꿉; ) HANGUL SYLLABLE GGUB
+AFCA;AFCA;1101 116E 11B9;AFCA;1101 116E 11B9; # (꿊; 꿊; 꿊; 꿊; 꿊; ) HANGUL SYLLABLE GGUBS
+AFCB;AFCB;1101 116E 11BA;AFCB;1101 116E 11BA; # (꿋; 꿋; 꿋; 꿋; 꿋; ) HANGUL SYLLABLE GGUS
+AFCC;AFCC;1101 116E 11BB;AFCC;1101 116E 11BB; # (꿌; 꿌; 꿌; 꿌; 꿌; ) HANGUL SYLLABLE GGUSS
+AFCD;AFCD;1101 116E 11BC;AFCD;1101 116E 11BC; # (꿍; 꿍; 꿍; 꿍; 꿍; ) HANGUL SYLLABLE GGUNG
+AFCE;AFCE;1101 116E 11BD;AFCE;1101 116E 11BD; # (꿎; 꿎; 꿎; 꿎; 꿎; ) HANGUL SYLLABLE GGUJ
+AFCF;AFCF;1101 116E 11BE;AFCF;1101 116E 11BE; # (꿏; 꿏; 꿏; 꿏; 꿏; ) HANGUL SYLLABLE GGUC
+AFD0;AFD0;1101 116E 11BF;AFD0;1101 116E 11BF; # (꿐; 꿐; 꿐; 꿐; 꿐; ) HANGUL SYLLABLE GGUK
+AFD1;AFD1;1101 116E 11C0;AFD1;1101 116E 11C0; # (꿑; 꿑; 꿑; 꿑; 꿑; ) HANGUL SYLLABLE GGUT
+AFD2;AFD2;1101 116E 11C1;AFD2;1101 116E 11C1; # (꿒; 꿒; 꿒; 꿒; 꿒; ) HANGUL SYLLABLE GGUP
+AFD3;AFD3;1101 116E 11C2;AFD3;1101 116E 11C2; # (꿓; 꿓; 꿓; 꿓; 꿓; ) HANGUL SYLLABLE GGUH
+AFD4;AFD4;1101 116F;AFD4;1101 116F; # (꿔; 꿔; 꿔; 꿔; 꿔; ) HANGUL SYLLABLE GGWEO
+AFD5;AFD5;1101 116F 11A8;AFD5;1101 116F 11A8; # (꿕; 꿕; 꿕; 꿕; 꿕; ) HANGUL SYLLABLE GGWEOG
+AFD6;AFD6;1101 116F 11A9;AFD6;1101 116F 11A9; # (꿖; 꿖; 꿖; 꿖; 꿖; ) HANGUL SYLLABLE GGWEOGG
+AFD7;AFD7;1101 116F 11AA;AFD7;1101 116F 11AA; # (꿗; 꿗; 꿗; 꿗; 꿗; ) HANGUL SYLLABLE GGWEOGS
+AFD8;AFD8;1101 116F 11AB;AFD8;1101 116F 11AB; # (꿘; 꿘; 꿘; 꿘; 꿘; ) HANGUL SYLLABLE GGWEON
+AFD9;AFD9;1101 116F 11AC;AFD9;1101 116F 11AC; # (꿙; 꿙; 꿙; 꿙; 꿙; ) HANGUL SYLLABLE GGWEONJ
+AFDA;AFDA;1101 116F 11AD;AFDA;1101 116F 11AD; # (꿚; 꿚; 꿚; 꿚; 꿚; ) HANGUL SYLLABLE GGWEONH
+AFDB;AFDB;1101 116F 11AE;AFDB;1101 116F 11AE; # (꿛; 꿛; 꿛; 꿛; 꿛; ) HANGUL SYLLABLE GGWEOD
+AFDC;AFDC;1101 116F 11AF;AFDC;1101 116F 11AF; # (꿜; 꿜; 꿜; 꿜; 꿜; ) HANGUL SYLLABLE GGWEOL
+AFDD;AFDD;1101 116F 11B0;AFDD;1101 116F 11B0; # (꿝; 꿝; 꿝; 꿝; 꿝; ) HANGUL SYLLABLE GGWEOLG
+AFDE;AFDE;1101 116F 11B1;AFDE;1101 116F 11B1; # (꿞; 꿞; 꿞; 꿞; 꿞; ) HANGUL SYLLABLE GGWEOLM
+AFDF;AFDF;1101 116F 11B2;AFDF;1101 116F 11B2; # (꿟; 꿟; 꿟; 꿟; 꿟; ) HANGUL SYLLABLE GGWEOLB
+AFE0;AFE0;1101 116F 11B3;AFE0;1101 116F 11B3; # (꿠; 꿠; 꿠; 꿠; 꿠; ) HANGUL SYLLABLE GGWEOLS
+AFE1;AFE1;1101 116F 11B4;AFE1;1101 116F 11B4; # (꿡; 꿡; 꿡; 꿡; 꿡; ) HANGUL SYLLABLE GGWEOLT
+AFE2;AFE2;1101 116F 11B5;AFE2;1101 116F 11B5; # (꿢; 꿢; 꿢; 꿢; 꿢; ) HANGUL SYLLABLE GGWEOLP
+AFE3;AFE3;1101 116F 11B6;AFE3;1101 116F 11B6; # (꿣; 꿣; 꿣; 꿣; 꿣; ) HANGUL SYLLABLE GGWEOLH
+AFE4;AFE4;1101 116F 11B7;AFE4;1101 116F 11B7; # (꿤; 꿤; 꿤; 꿤; 꿤; ) HANGUL SYLLABLE GGWEOM
+AFE5;AFE5;1101 116F 11B8;AFE5;1101 116F 11B8; # (꿥; 꿥; 꿥; 꿥; 꿥; ) HANGUL SYLLABLE GGWEOB
+AFE6;AFE6;1101 116F 11B9;AFE6;1101 116F 11B9; # (꿦; 꿦; 꿦; 꿦; 꿦; ) HANGUL SYLLABLE GGWEOBS
+AFE7;AFE7;1101 116F 11BA;AFE7;1101 116F 11BA; # (꿧; 꿧; 꿧; 꿧; 꿧; ) HANGUL SYLLABLE GGWEOS
+AFE8;AFE8;1101 116F 11BB;AFE8;1101 116F 11BB; # (꿨; 꿨; 꿨; 꿨; 꿨; ) HANGUL SYLLABLE GGWEOSS
+AFE9;AFE9;1101 116F 11BC;AFE9;1101 116F 11BC; # (꿩; 꿩; 꿩; 꿩; 꿩; ) HANGUL SYLLABLE GGWEONG
+AFEA;AFEA;1101 116F 11BD;AFEA;1101 116F 11BD; # (꿪; 꿪; 꿪; 꿪; 꿪; ) HANGUL SYLLABLE GGWEOJ
+AFEB;AFEB;1101 116F 11BE;AFEB;1101 116F 11BE; # (꿫; 꿫; 꿫; 꿫; 꿫; ) HANGUL SYLLABLE GGWEOC
+AFEC;AFEC;1101 116F 11BF;AFEC;1101 116F 11BF; # (꿬; 꿬; 꿬; 꿬; 꿬; ) HANGUL SYLLABLE GGWEOK
+AFED;AFED;1101 116F 11C0;AFED;1101 116F 11C0; # (꿭; 꿭; 꿭; 꿭; 꿭; ) HANGUL SYLLABLE GGWEOT
+AFEE;AFEE;1101 116F 11C1;AFEE;1101 116F 11C1; # (꿮; 꿮; 꿮; 꿮; 꿮; ) HANGUL SYLLABLE GGWEOP
+AFEF;AFEF;1101 116F 11C2;AFEF;1101 116F 11C2; # (꿯; 꿯; 꿯; 꿯; 꿯; ) HANGUL SYLLABLE GGWEOH
+AFF0;AFF0;1101 1170;AFF0;1101 1170; # (꿰; 꿰; 꿰; 꿰; 꿰; ) HANGUL SYLLABLE GGWE
+AFF1;AFF1;1101 1170 11A8;AFF1;1101 1170 11A8; # (꿱; 꿱; 꿱; 꿱; 꿱; ) HANGUL SYLLABLE GGWEG
+AFF2;AFF2;1101 1170 11A9;AFF2;1101 1170 11A9; # (꿲; 꿲; 꿲; 꿲; 꿲; ) HANGUL SYLLABLE GGWEGG
+AFF3;AFF3;1101 1170 11AA;AFF3;1101 1170 11AA; # (꿳; 꿳; 꿳; 꿳; 꿳; ) HANGUL SYLLABLE GGWEGS
+AFF4;AFF4;1101 1170 11AB;AFF4;1101 1170 11AB; # (꿴; 꿴; 꿴; 꿴; 꿴; ) HANGUL SYLLABLE GGWEN
+AFF5;AFF5;1101 1170 11AC;AFF5;1101 1170 11AC; # (꿵; 꿵; 꿵; 꿵; 꿵; ) HANGUL SYLLABLE GGWENJ
+AFF6;AFF6;1101 1170 11AD;AFF6;1101 1170 11AD; # (꿶; 꿶; 꿶; 꿶; 꿶; ) HANGUL SYLLABLE GGWENH
+AFF7;AFF7;1101 1170 11AE;AFF7;1101 1170 11AE; # (꿷; 꿷; 꿷; 꿷; 꿷; ) HANGUL SYLLABLE GGWED
+AFF8;AFF8;1101 1170 11AF;AFF8;1101 1170 11AF; # (꿸; 꿸; 꿸; 꿸; 꿸; ) HANGUL SYLLABLE GGWEL
+AFF9;AFF9;1101 1170 11B0;AFF9;1101 1170 11B0; # (꿹; 꿹; 꿹; 꿹; 꿹; ) HANGUL SYLLABLE GGWELG
+AFFA;AFFA;1101 1170 11B1;AFFA;1101 1170 11B1; # (꿺; 꿺; 꿺; 꿺; 꿺; ) HANGUL SYLLABLE GGWELM
+AFFB;AFFB;1101 1170 11B2;AFFB;1101 1170 11B2; # (꿻; 꿻; 꿻; 꿻; 꿻; ) HANGUL SYLLABLE GGWELB
+AFFC;AFFC;1101 1170 11B3;AFFC;1101 1170 11B3; # (꿼; 꿼; 꿼; 꿼; 꿼; ) HANGUL SYLLABLE GGWELS
+AFFD;AFFD;1101 1170 11B4;AFFD;1101 1170 11B4; # (꿽; 꿽; 꿽; 꿽; 꿽; ) HANGUL SYLLABLE GGWELT
+AFFE;AFFE;1101 1170 11B5;AFFE;1101 1170 11B5; # (꿾; 꿾; 꿾; 꿾; 꿾; ) HANGUL SYLLABLE GGWELP
+AFFF;AFFF;1101 1170 11B6;AFFF;1101 1170 11B6; # (꿿; 꿿; 꿿; 꿿; 꿿; ) HANGUL SYLLABLE GGWELH
+B000;B000;1101 1170 11B7;B000;1101 1170 11B7; # (뀀; 뀀; 뀀; 뀀; 뀀; ) HANGUL SYLLABLE GGWEM
+B001;B001;1101 1170 11B8;B001;1101 1170 11B8; # (뀁; 뀁; 뀁; 뀁; 뀁; ) HANGUL SYLLABLE GGWEB
+B002;B002;1101 1170 11B9;B002;1101 1170 11B9; # (뀂; 뀂; 뀂; 뀂; 뀂; ) HANGUL SYLLABLE GGWEBS
+B003;B003;1101 1170 11BA;B003;1101 1170 11BA; # (뀃; 뀃; 뀃; 뀃; 뀃; ) HANGUL SYLLABLE GGWES
+B004;B004;1101 1170 11BB;B004;1101 1170 11BB; # (뀄; 뀄; 뀄; 뀄; 뀄; ) HANGUL SYLLABLE GGWESS
+B005;B005;1101 1170 11BC;B005;1101 1170 11BC; # (뀅; 뀅; 뀅; 뀅; 뀅; ) HANGUL SYLLABLE GGWENG
+B006;B006;1101 1170 11BD;B006;1101 1170 11BD; # (뀆; 뀆; 뀆; 뀆; 뀆; ) HANGUL SYLLABLE GGWEJ
+B007;B007;1101 1170 11BE;B007;1101 1170 11BE; # (뀇; 뀇; 뀇; 뀇; 뀇; ) HANGUL SYLLABLE GGWEC
+B008;B008;1101 1170 11BF;B008;1101 1170 11BF; # (뀈; 뀈; 뀈; 뀈; 뀈; ) HANGUL SYLLABLE GGWEK
+B009;B009;1101 1170 11C0;B009;1101 1170 11C0; # (뀉; 뀉; 뀉; 뀉; 뀉; ) HANGUL SYLLABLE GGWET
+B00A;B00A;1101 1170 11C1;B00A;1101 1170 11C1; # (뀊; 뀊; 뀊; 뀊; 뀊; ) HANGUL SYLLABLE GGWEP
+B00B;B00B;1101 1170 11C2;B00B;1101 1170 11C2; # (뀋; 뀋; 뀋; 뀋; 뀋; ) HANGUL SYLLABLE GGWEH
+B00C;B00C;1101 1171;B00C;1101 1171; # (뀌; 뀌; 뀌; 뀌; 뀌; ) HANGUL SYLLABLE GGWI
+B00D;B00D;1101 1171 11A8;B00D;1101 1171 11A8; # (뀍; 뀍; 뀍; 뀍; 뀍; ) HANGUL SYLLABLE GGWIG
+B00E;B00E;1101 1171 11A9;B00E;1101 1171 11A9; # (뀎; 뀎; 뀎; 뀎; 뀎; ) HANGUL SYLLABLE GGWIGG
+B00F;B00F;1101 1171 11AA;B00F;1101 1171 11AA; # (뀏; 뀏; 뀏; 뀏; 뀏; ) HANGUL SYLLABLE GGWIGS
+B010;B010;1101 1171 11AB;B010;1101 1171 11AB; # (뀐; 뀐; 뀐; 뀐; 뀐; ) HANGUL SYLLABLE GGWIN
+B011;B011;1101 1171 11AC;B011;1101 1171 11AC; # (뀑; 뀑; 뀑; 뀑; 뀑; ) HANGUL SYLLABLE GGWINJ
+B012;B012;1101 1171 11AD;B012;1101 1171 11AD; # (뀒; 뀒; 뀒; 뀒; 뀒; ) HANGUL SYLLABLE GGWINH
+B013;B013;1101 1171 11AE;B013;1101 1171 11AE; # (뀓; 뀓; 뀓; 뀓; 뀓; ) HANGUL SYLLABLE GGWID
+B014;B014;1101 1171 11AF;B014;1101 1171 11AF; # (뀔; 뀔; 뀔; 뀔; 뀔; ) HANGUL SYLLABLE GGWIL
+B015;B015;1101 1171 11B0;B015;1101 1171 11B0; # (뀕; 뀕; 뀕; 뀕; 뀕; ) HANGUL SYLLABLE GGWILG
+B016;B016;1101 1171 11B1;B016;1101 1171 11B1; # (뀖; 뀖; 뀖; 뀖; 뀖; ) HANGUL SYLLABLE GGWILM
+B017;B017;1101 1171 11B2;B017;1101 1171 11B2; # (뀗; 뀗; 뀗; 뀗; 뀗; ) HANGUL SYLLABLE GGWILB
+B018;B018;1101 1171 11B3;B018;1101 1171 11B3; # (뀘; 뀘; 뀘; 뀘; 뀘; ) HANGUL SYLLABLE GGWILS
+B019;B019;1101 1171 11B4;B019;1101 1171 11B4; # (뀙; 뀙; 뀙; 뀙; 뀙; ) HANGUL SYLLABLE GGWILT
+B01A;B01A;1101 1171 11B5;B01A;1101 1171 11B5; # (뀚; 뀚; 뀚; 뀚; 뀚; ) HANGUL SYLLABLE GGWILP
+B01B;B01B;1101 1171 11B6;B01B;1101 1171 11B6; # (뀛; 뀛; 뀛; 뀛; 뀛; ) HANGUL SYLLABLE GGWILH
+B01C;B01C;1101 1171 11B7;B01C;1101 1171 11B7; # (뀜; 뀜; 뀜; 뀜; 뀜; ) HANGUL SYLLABLE GGWIM
+B01D;B01D;1101 1171 11B8;B01D;1101 1171 11B8; # (뀝; 뀝; 뀝; 뀝; 뀝; ) HANGUL SYLLABLE GGWIB
+B01E;B01E;1101 1171 11B9;B01E;1101 1171 11B9; # (뀞; 뀞; 뀞; 뀞; 뀞; ) HANGUL SYLLABLE GGWIBS
+B01F;B01F;1101 1171 11BA;B01F;1101 1171 11BA; # (뀟; 뀟; 뀟; 뀟; 뀟; ) HANGUL SYLLABLE GGWIS
+B020;B020;1101 1171 11BB;B020;1101 1171 11BB; # (뀠; 뀠; 뀠; 뀠; 뀠; ) HANGUL SYLLABLE GGWISS
+B021;B021;1101 1171 11BC;B021;1101 1171 11BC; # (뀡; 뀡; 뀡; 뀡; 뀡; ) HANGUL SYLLABLE GGWING
+B022;B022;1101 1171 11BD;B022;1101 1171 11BD; # (뀢; 뀢; 뀢; 뀢; 뀢; ) HANGUL SYLLABLE GGWIJ
+B023;B023;1101 1171 11BE;B023;1101 1171 11BE; # (뀣; 뀣; 뀣; 뀣; 뀣; ) HANGUL SYLLABLE GGWIC
+B024;B024;1101 1171 11BF;B024;1101 1171 11BF; # (뀤; 뀤; 뀤; 뀤; 뀤; ) HANGUL SYLLABLE GGWIK
+B025;B025;1101 1171 11C0;B025;1101 1171 11C0; # (뀥; 뀥; 뀥; 뀥; 뀥; ) HANGUL SYLLABLE GGWIT
+B026;B026;1101 1171 11C1;B026;1101 1171 11C1; # (뀦; 뀦; 뀦; 뀦; 뀦; ) HANGUL SYLLABLE GGWIP
+B027;B027;1101 1171 11C2;B027;1101 1171 11C2; # (뀧; 뀧; 뀧; 뀧; 뀧; ) HANGUL SYLLABLE GGWIH
+B028;B028;1101 1172;B028;1101 1172; # (뀨; 뀨; 뀨; 뀨; 뀨; ) HANGUL SYLLABLE GGYU
+B029;B029;1101 1172 11A8;B029;1101 1172 11A8; # (뀩; 뀩; 뀩; 뀩; 뀩; ) HANGUL SYLLABLE GGYUG
+B02A;B02A;1101 1172 11A9;B02A;1101 1172 11A9; # (뀪; 뀪; 뀪; 뀪; 뀪; ) HANGUL SYLLABLE GGYUGG
+B02B;B02B;1101 1172 11AA;B02B;1101 1172 11AA; # (뀫; 뀫; 뀫; 뀫; 뀫; ) HANGUL SYLLABLE GGYUGS
+B02C;B02C;1101 1172 11AB;B02C;1101 1172 11AB; # (뀬; 뀬; 뀬; 뀬; 뀬; ) HANGUL SYLLABLE GGYUN
+B02D;B02D;1101 1172 11AC;B02D;1101 1172 11AC; # (뀭; 뀭; 뀭; 뀭; 뀭; ) HANGUL SYLLABLE GGYUNJ
+B02E;B02E;1101 1172 11AD;B02E;1101 1172 11AD; # (뀮; 뀮; 뀮; 뀮; 뀮; ) HANGUL SYLLABLE GGYUNH
+B02F;B02F;1101 1172 11AE;B02F;1101 1172 11AE; # (뀯; 뀯; 뀯; 뀯; 뀯; ) HANGUL SYLLABLE GGYUD
+B030;B030;1101 1172 11AF;B030;1101 1172 11AF; # (뀰; 뀰; 뀰; 뀰; 뀰; ) HANGUL SYLLABLE GGYUL
+B031;B031;1101 1172 11B0;B031;1101 1172 11B0; # (뀱; 뀱; 뀱; 뀱; 뀱; ) HANGUL SYLLABLE GGYULG
+B032;B032;1101 1172 11B1;B032;1101 1172 11B1; # (뀲; 뀲; 뀲; 뀲; 뀲; ) HANGUL SYLLABLE GGYULM
+B033;B033;1101 1172 11B2;B033;1101 1172 11B2; # (뀳; 뀳; 뀳; 뀳; 뀳; ) HANGUL SYLLABLE GGYULB
+B034;B034;1101 1172 11B3;B034;1101 1172 11B3; # (뀴; 뀴; 뀴; 뀴; 뀴; ) HANGUL SYLLABLE GGYULS
+B035;B035;1101 1172 11B4;B035;1101 1172 11B4; # (뀵; 뀵; 뀵; 뀵; 뀵; ) HANGUL SYLLABLE GGYULT
+B036;B036;1101 1172 11B5;B036;1101 1172 11B5; # (뀶; 뀶; 뀶; 뀶; 뀶; ) HANGUL SYLLABLE GGYULP
+B037;B037;1101 1172 11B6;B037;1101 1172 11B6; # (뀷; 뀷; 뀷; 뀷; 뀷; ) HANGUL SYLLABLE GGYULH
+B038;B038;1101 1172 11B7;B038;1101 1172 11B7; # (뀸; 뀸; 뀸; 뀸; 뀸; ) HANGUL SYLLABLE GGYUM
+B039;B039;1101 1172 11B8;B039;1101 1172 11B8; # (뀹; 뀹; 뀹; 뀹; 뀹; ) HANGUL SYLLABLE GGYUB
+B03A;B03A;1101 1172 11B9;B03A;1101 1172 11B9; # (뀺; 뀺; 뀺; 뀺; 뀺; ) HANGUL SYLLABLE GGYUBS
+B03B;B03B;1101 1172 11BA;B03B;1101 1172 11BA; # (뀻; 뀻; 뀻; 뀻; 뀻; ) HANGUL SYLLABLE GGYUS
+B03C;B03C;1101 1172 11BB;B03C;1101 1172 11BB; # (뀼; 뀼; 뀼; 뀼; 뀼; ) HANGUL SYLLABLE GGYUSS
+B03D;B03D;1101 1172 11BC;B03D;1101 1172 11BC; # (뀽; 뀽; 뀽; 뀽; 뀽; ) HANGUL SYLLABLE GGYUNG
+B03E;B03E;1101 1172 11BD;B03E;1101 1172 11BD; # (뀾; 뀾; 뀾; 뀾; 뀾; ) HANGUL SYLLABLE GGYUJ
+B03F;B03F;1101 1172 11BE;B03F;1101 1172 11BE; # (뀿; 뀿; 뀿; 뀿; 뀿; ) HANGUL SYLLABLE GGYUC
+B040;B040;1101 1172 11BF;B040;1101 1172 11BF; # (끀; 끀; 끀; 끀; 끀; ) HANGUL SYLLABLE GGYUK
+B041;B041;1101 1172 11C0;B041;1101 1172 11C0; # (끁; 끁; 끁; 끁; 끁; ) HANGUL SYLLABLE GGYUT
+B042;B042;1101 1172 11C1;B042;1101 1172 11C1; # (끂; 끂; 끂; 끂; 끂; ) HANGUL SYLLABLE GGYUP
+B043;B043;1101 1172 11C2;B043;1101 1172 11C2; # (끃; 끃; 끃; 끃; 끃; ) HANGUL SYLLABLE GGYUH
+B044;B044;1101 1173;B044;1101 1173; # (끄; 끄; 끄; 끄; 끄; ) HANGUL SYLLABLE GGEU
+B045;B045;1101 1173 11A8;B045;1101 1173 11A8; # (끅; 끅; 끅; 끅; 끅; ) HANGUL SYLLABLE GGEUG
+B046;B046;1101 1173 11A9;B046;1101 1173 11A9; # (끆; 끆; 끆; 끆; 끆; ) HANGUL SYLLABLE GGEUGG
+B047;B047;1101 1173 11AA;B047;1101 1173 11AA; # (끇; 끇; 끇; 끇; 끇; ) HANGUL SYLLABLE GGEUGS
+B048;B048;1101 1173 11AB;B048;1101 1173 11AB; # (끈; 끈; 끈; 끈; 끈; ) HANGUL SYLLABLE GGEUN
+B049;B049;1101 1173 11AC;B049;1101 1173 11AC; # (끉; 끉; 끉; 끉; 끉; ) HANGUL SYLLABLE GGEUNJ
+B04A;B04A;1101 1173 11AD;B04A;1101 1173 11AD; # (끊; 끊; 끊; 끊; 끊; ) HANGUL SYLLABLE GGEUNH
+B04B;B04B;1101 1173 11AE;B04B;1101 1173 11AE; # (끋; 끋; 끋; 끋; 끋; ) HANGUL SYLLABLE GGEUD
+B04C;B04C;1101 1173 11AF;B04C;1101 1173 11AF; # (끌; 끌; 끌; 끌; 끌; ) HANGUL SYLLABLE GGEUL
+B04D;B04D;1101 1173 11B0;B04D;1101 1173 11B0; # (끍; 끍; 끍; 끍; 끍; ) HANGUL SYLLABLE GGEULG
+B04E;B04E;1101 1173 11B1;B04E;1101 1173 11B1; # (끎; 끎; 끎; 끎; 끎; ) HANGUL SYLLABLE GGEULM
+B04F;B04F;1101 1173 11B2;B04F;1101 1173 11B2; # (끏; 끏; 끏; 끏; 끏; ) HANGUL SYLLABLE GGEULB
+B050;B050;1101 1173 11B3;B050;1101 1173 11B3; # (끐; 끐; 끐; 끐; 끐; ) HANGUL SYLLABLE GGEULS
+B051;B051;1101 1173 11B4;B051;1101 1173 11B4; # (끑; 끑; 끑; 끑; 끑; ) HANGUL SYLLABLE GGEULT
+B052;B052;1101 1173 11B5;B052;1101 1173 11B5; # (끒; 끒; 끒; 끒; 끒; ) HANGUL SYLLABLE GGEULP
+B053;B053;1101 1173 11B6;B053;1101 1173 11B6; # (끓; 끓; 끓; 끓; 끓; ) HANGUL SYLLABLE GGEULH
+B054;B054;1101 1173 11B7;B054;1101 1173 11B7; # (끔; 끔; 끔; 끔; 끔; ) HANGUL SYLLABLE GGEUM
+B055;B055;1101 1173 11B8;B055;1101 1173 11B8; # (끕; 끕; 끕; 끕; 끕; ) HANGUL SYLLABLE GGEUB
+B056;B056;1101 1173 11B9;B056;1101 1173 11B9; # (끖; 끖; 끖; 끖; 끖; ) HANGUL SYLLABLE GGEUBS
+B057;B057;1101 1173 11BA;B057;1101 1173 11BA; # (끗; 끗; 끗; 끗; 끗; ) HANGUL SYLLABLE GGEUS
+B058;B058;1101 1173 11BB;B058;1101 1173 11BB; # (끘; 끘; 끘; 끘; 끘; ) HANGUL SYLLABLE GGEUSS
+B059;B059;1101 1173 11BC;B059;1101 1173 11BC; # (끙; 끙; 끙; 끙; 끙; ) HANGUL SYLLABLE GGEUNG
+B05A;B05A;1101 1173 11BD;B05A;1101 1173 11BD; # (끚; 끚; 끚; 끚; 끚; ) HANGUL SYLLABLE GGEUJ
+B05B;B05B;1101 1173 11BE;B05B;1101 1173 11BE; # (끛; 끛; 끛; 끛; 끛; ) HANGUL SYLLABLE GGEUC
+B05C;B05C;1101 1173 11BF;B05C;1101 1173 11BF; # (끜; 끜; 끜; 끜; 끜; ) HANGUL SYLLABLE GGEUK
+B05D;B05D;1101 1173 11C0;B05D;1101 1173 11C0; # (끝; 끝; 끝; 끝; 끝; ) HANGUL SYLLABLE GGEUT
+B05E;B05E;1101 1173 11C1;B05E;1101 1173 11C1; # (끞; 끞; 끞; 끞; 끞; ) HANGUL SYLLABLE GGEUP
+B05F;B05F;1101 1173 11C2;B05F;1101 1173 11C2; # (끟; 끟; 끟; 끟; 끟; ) HANGUL SYLLABLE GGEUH
+B060;B060;1101 1174;B060;1101 1174; # (끠; 끠; 끠; 끠; 끠; ) HANGUL SYLLABLE GGYI
+B061;B061;1101 1174 11A8;B061;1101 1174 11A8; # (끡; 끡; 끡; 끡; 끡; ) HANGUL SYLLABLE GGYIG
+B062;B062;1101 1174 11A9;B062;1101 1174 11A9; # (끢; 끢; 끢; 끢; 끢; ) HANGUL SYLLABLE GGYIGG
+B063;B063;1101 1174 11AA;B063;1101 1174 11AA; # (끣; 끣; 끣; 끣; 끣; ) HANGUL SYLLABLE GGYIGS
+B064;B064;1101 1174 11AB;B064;1101 1174 11AB; # (끤; 끤; 끤; 끤; 끤; ) HANGUL SYLLABLE GGYIN
+B065;B065;1101 1174 11AC;B065;1101 1174 11AC; # (끥; 끥; 끥; 끥; 끥; ) HANGUL SYLLABLE GGYINJ
+B066;B066;1101 1174 11AD;B066;1101 1174 11AD; # (끦; 끦; 끦; 끦; 끦; ) HANGUL SYLLABLE GGYINH
+B067;B067;1101 1174 11AE;B067;1101 1174 11AE; # (끧; 끧; 끧; 끧; 끧; ) HANGUL SYLLABLE GGYID
+B068;B068;1101 1174 11AF;B068;1101 1174 11AF; # (끨; 끨; 끨; 끨; 끨; ) HANGUL SYLLABLE GGYIL
+B069;B069;1101 1174 11B0;B069;1101 1174 11B0; # (끩; 끩; 끩; 끩; 끩; ) HANGUL SYLLABLE GGYILG
+B06A;B06A;1101 1174 11B1;B06A;1101 1174 11B1; # (끪; 끪; 끪; 끪; 끪; ) HANGUL SYLLABLE GGYILM
+B06B;B06B;1101 1174 11B2;B06B;1101 1174 11B2; # (끫; 끫; 끫; 끫; 끫; ) HANGUL SYLLABLE GGYILB
+B06C;B06C;1101 1174 11B3;B06C;1101 1174 11B3; # (끬; 끬; 끬; 끬; 끬; ) HANGUL SYLLABLE GGYILS
+B06D;B06D;1101 1174 11B4;B06D;1101 1174 11B4; # (끭; 끭; 끭; 끭; 끭; ) HANGUL SYLLABLE GGYILT
+B06E;B06E;1101 1174 11B5;B06E;1101 1174 11B5; # (끮; 끮; 끮; 끮; 끮; ) HANGUL SYLLABLE GGYILP
+B06F;B06F;1101 1174 11B6;B06F;1101 1174 11B6; # (끯; 끯; 끯; 끯; 끯; ) HANGUL SYLLABLE GGYILH
+B070;B070;1101 1174 11B7;B070;1101 1174 11B7; # (끰; 끰; 끰; 끰; 끰; ) HANGUL SYLLABLE GGYIM
+B071;B071;1101 1174 11B8;B071;1101 1174 11B8; # (끱; 끱; 끱; 끱; 끱; ) HANGUL SYLLABLE GGYIB
+B072;B072;1101 1174 11B9;B072;1101 1174 11B9; # (끲; 끲; 끲; 끲; 끲; ) HANGUL SYLLABLE GGYIBS
+B073;B073;1101 1174 11BA;B073;1101 1174 11BA; # (끳; 끳; 끳; 끳; 끳; ) HANGUL SYLLABLE GGYIS
+B074;B074;1101 1174 11BB;B074;1101 1174 11BB; # (끴; 끴; 끴; 끴; 끴; ) HANGUL SYLLABLE GGYISS
+B075;B075;1101 1174 11BC;B075;1101 1174 11BC; # (끵; 끵; 끵; 끵; 끵; ) HANGUL SYLLABLE GGYING
+B076;B076;1101 1174 11BD;B076;1101 1174 11BD; # (끶; 끶; 끶; 끶; 끶; ) HANGUL SYLLABLE GGYIJ
+B077;B077;1101 1174 11BE;B077;1101 1174 11BE; # (끷; 끷; 끷; 끷; 끷; ) HANGUL SYLLABLE GGYIC
+B078;B078;1101 1174 11BF;B078;1101 1174 11BF; # (끸; 끸; 끸; 끸; 끸; ) HANGUL SYLLABLE GGYIK
+B079;B079;1101 1174 11C0;B079;1101 1174 11C0; # (끹; 끹; 끹; 끹; 끹; ) HANGUL SYLLABLE GGYIT
+B07A;B07A;1101 1174 11C1;B07A;1101 1174 11C1; # (끺; 끺; 끺; 끺; 끺; ) HANGUL SYLLABLE GGYIP
+B07B;B07B;1101 1174 11C2;B07B;1101 1174 11C2; # (끻; 끻; 끻; 끻; 끻; ) HANGUL SYLLABLE GGYIH
+B07C;B07C;1101 1175;B07C;1101 1175; # (끼; 끼; 끼; 끼; 끼; ) HANGUL SYLLABLE GGI
+B07D;B07D;1101 1175 11A8;B07D;1101 1175 11A8; # (끽; 끽; 끽; 끽; 끽; ) HANGUL SYLLABLE GGIG
+B07E;B07E;1101 1175 11A9;B07E;1101 1175 11A9; # (끾; 끾; 끾; 끾; 끾; ) HANGUL SYLLABLE GGIGG
+B07F;B07F;1101 1175 11AA;B07F;1101 1175 11AA; # (끿; 끿; 끿; 끿; 끿; ) HANGUL SYLLABLE GGIGS
+B080;B080;1101 1175 11AB;B080;1101 1175 11AB; # (낀; 낀; 낀; 낀; 낀; ) HANGUL SYLLABLE GGIN
+B081;B081;1101 1175 11AC;B081;1101 1175 11AC; # (낁; 낁; 낁; 낁; 낁; ) HANGUL SYLLABLE GGINJ
+B082;B082;1101 1175 11AD;B082;1101 1175 11AD; # (낂; 낂; 낂; 낂; 낂; ) HANGUL SYLLABLE GGINH
+B083;B083;1101 1175 11AE;B083;1101 1175 11AE; # (낃; 낃; 낃; 낃; 낃; ) HANGUL SYLLABLE GGID
+B084;B084;1101 1175 11AF;B084;1101 1175 11AF; # (낄; 낄; 낄; 낄; 낄; ) HANGUL SYLLABLE GGIL
+B085;B085;1101 1175 11B0;B085;1101 1175 11B0; # (낅; 낅; 낅; 낅; 낅; ) HANGUL SYLLABLE GGILG
+B086;B086;1101 1175 11B1;B086;1101 1175 11B1; # (낆; 낆; 낆; 낆; 낆; ) HANGUL SYLLABLE GGILM
+B087;B087;1101 1175 11B2;B087;1101 1175 11B2; # (낇; 낇; 낇; 낇; 낇; ) HANGUL SYLLABLE GGILB
+B088;B088;1101 1175 11B3;B088;1101 1175 11B3; # (낈; 낈; 낈; 낈; 낈; ) HANGUL SYLLABLE GGILS
+B089;B089;1101 1175 11B4;B089;1101 1175 11B4; # (낉; 낉; 낉; 낉; 낉; ) HANGUL SYLLABLE GGILT
+B08A;B08A;1101 1175 11B5;B08A;1101 1175 11B5; # (낊; 낊; 낊; 낊; 낊; ) HANGUL SYLLABLE GGILP
+B08B;B08B;1101 1175 11B6;B08B;1101 1175 11B6; # (낋; 낋; 낋; 낋; 낋; ) HANGUL SYLLABLE GGILH
+B08C;B08C;1101 1175 11B7;B08C;1101 1175 11B7; # (낌; 낌; 낌; 낌; 낌; ) HANGUL SYLLABLE GGIM
+B08D;B08D;1101 1175 11B8;B08D;1101 1175 11B8; # (낍; 낍; 낍; 낍; 낍; ) HANGUL SYLLABLE GGIB
+B08E;B08E;1101 1175 11B9;B08E;1101 1175 11B9; # (낎; 낎; 낎; 낎; 낎; ) HANGUL SYLLABLE GGIBS
+B08F;B08F;1101 1175 11BA;B08F;1101 1175 11BA; # (낏; 낏; 낏; 낏; 낏; ) HANGUL SYLLABLE GGIS
+B090;B090;1101 1175 11BB;B090;1101 1175 11BB; # (낐; 낐; 낐; 낐; 낐; ) HANGUL SYLLABLE GGISS
+B091;B091;1101 1175 11BC;B091;1101 1175 11BC; # (낑; 낑; 낑; 낑; 낑; ) HANGUL SYLLABLE GGING
+B092;B092;1101 1175 11BD;B092;1101 1175 11BD; # (낒; 낒; 낒; 낒; 낒; ) HANGUL SYLLABLE GGIJ
+B093;B093;1101 1175 11BE;B093;1101 1175 11BE; # (낓; 낓; 낓; 낓; 낓; ) HANGUL SYLLABLE GGIC
+B094;B094;1101 1175 11BF;B094;1101 1175 11BF; # (낔; 낔; 낔; 낔; 낔; ) HANGUL SYLLABLE GGIK
+B095;B095;1101 1175 11C0;B095;1101 1175 11C0; # (낕; 낕; 낕; 낕; 낕; ) HANGUL SYLLABLE GGIT
+B096;B096;1101 1175 11C1;B096;1101 1175 11C1; # (낖; 낖; 낖; 낖; 낖; ) HANGUL SYLLABLE GGIP
+B097;B097;1101 1175 11C2;B097;1101 1175 11C2; # (낗; 낗; 낗; 낗; 낗; ) HANGUL SYLLABLE GGIH
+B098;B098;1102 1161;B098;1102 1161; # (나; 나; 나; 나; 나; ) HANGUL SYLLABLE NA
+B099;B099;1102 1161 11A8;B099;1102 1161 11A8; # (낙; 낙; 낙; 낙; 낙; ) HANGUL SYLLABLE NAG
+B09A;B09A;1102 1161 11A9;B09A;1102 1161 11A9; # (낚; 낚; 낚; 낚; 낚; ) HANGUL SYLLABLE NAGG
+B09B;B09B;1102 1161 11AA;B09B;1102 1161 11AA; # (낛; 낛; 낛; 낛; 낛; ) HANGUL SYLLABLE NAGS
+B09C;B09C;1102 1161 11AB;B09C;1102 1161 11AB; # (난; 난; 난; 난; 난; ) HANGUL SYLLABLE NAN
+B09D;B09D;1102 1161 11AC;B09D;1102 1161 11AC; # (낝; 낝; 낝; 낝; 낝; ) HANGUL SYLLABLE NANJ
+B09E;B09E;1102 1161 11AD;B09E;1102 1161 11AD; # (낞; 낞; 낞; 낞; 낞; ) HANGUL SYLLABLE NANH
+B09F;B09F;1102 1161 11AE;B09F;1102 1161 11AE; # (낟; 낟; 낟; 낟; 낟; ) HANGUL SYLLABLE NAD
+B0A0;B0A0;1102 1161 11AF;B0A0;1102 1161 11AF; # (날; 날; 날; 날; 날; ) HANGUL SYLLABLE NAL
+B0A1;B0A1;1102 1161 11B0;B0A1;1102 1161 11B0; # (낡; 낡; 낡; 낡; 낡; ) HANGUL SYLLABLE NALG
+B0A2;B0A2;1102 1161 11B1;B0A2;1102 1161 11B1; # (낢; 낢; 낢; 낢; 낢; ) HANGUL SYLLABLE NALM
+B0A3;B0A3;1102 1161 11B2;B0A3;1102 1161 11B2; # (낣; 낣; 낣; 낣; 낣; ) HANGUL SYLLABLE NALB
+B0A4;B0A4;1102 1161 11B3;B0A4;1102 1161 11B3; # (낤; 낤; 낤; 낤; 낤; ) HANGUL SYLLABLE NALS
+B0A5;B0A5;1102 1161 11B4;B0A5;1102 1161 11B4; # (낥; 낥; 낥; 낥; 낥; ) HANGUL SYLLABLE NALT
+B0A6;B0A6;1102 1161 11B5;B0A6;1102 1161 11B5; # (낦; 낦; 낦; 낦; 낦; ) HANGUL SYLLABLE NALP
+B0A7;B0A7;1102 1161 11B6;B0A7;1102 1161 11B6; # (낧; 낧; 낧; 낧; 낧; ) HANGUL SYLLABLE NALH
+B0A8;B0A8;1102 1161 11B7;B0A8;1102 1161 11B7; # (남; 남; 남; 남; 남; ) HANGUL SYLLABLE NAM
+B0A9;B0A9;1102 1161 11B8;B0A9;1102 1161 11B8; # (납; 납; 납; 납; 납; ) HANGUL SYLLABLE NAB
+B0AA;B0AA;1102 1161 11B9;B0AA;1102 1161 11B9; # (낪; 낪; 낪; 낪; 낪; ) HANGUL SYLLABLE NABS
+B0AB;B0AB;1102 1161 11BA;B0AB;1102 1161 11BA; # (낫; 낫; 낫; 낫; 낫; ) HANGUL SYLLABLE NAS
+B0AC;B0AC;1102 1161 11BB;B0AC;1102 1161 11BB; # (났; 났; 났; 났; 났; ) HANGUL SYLLABLE NASS
+B0AD;B0AD;1102 1161 11BC;B0AD;1102 1161 11BC; # (낭; 낭; 낭; 낭; 낭; ) HANGUL SYLLABLE NANG
+B0AE;B0AE;1102 1161 11BD;B0AE;1102 1161 11BD; # (낮; 낮; 낮; 낮; 낮; ) HANGUL SYLLABLE NAJ
+B0AF;B0AF;1102 1161 11BE;B0AF;1102 1161 11BE; # (낯; 낯; 낯; 낯; 낯; ) HANGUL SYLLABLE NAC
+B0B0;B0B0;1102 1161 11BF;B0B0;1102 1161 11BF; # (낰; 낰; 낰; 낰; 낰; ) HANGUL SYLLABLE NAK
+B0B1;B0B1;1102 1161 11C0;B0B1;1102 1161 11C0; # (낱; 낱; 낱; 낱; 낱; ) HANGUL SYLLABLE NAT
+B0B2;B0B2;1102 1161 11C1;B0B2;1102 1161 11C1; # (낲; 낲; 낲; 낲; 낲; ) HANGUL SYLLABLE NAP
+B0B3;B0B3;1102 1161 11C2;B0B3;1102 1161 11C2; # (낳; 낳; 낳; 낳; 낳; ) HANGUL SYLLABLE NAH
+B0B4;B0B4;1102 1162;B0B4;1102 1162; # (내; 내; 내; 내; 내; ) HANGUL SYLLABLE NAE
+B0B5;B0B5;1102 1162 11A8;B0B5;1102 1162 11A8; # (낵; 낵; 낵; 낵; 낵; ) HANGUL SYLLABLE NAEG
+B0B6;B0B6;1102 1162 11A9;B0B6;1102 1162 11A9; # (낶; 낶; 낶; 낶; 낶; ) HANGUL SYLLABLE NAEGG
+B0B7;B0B7;1102 1162 11AA;B0B7;1102 1162 11AA; # (낷; 낷; 낷; 낷; 낷; ) HANGUL SYLLABLE NAEGS
+B0B8;B0B8;1102 1162 11AB;B0B8;1102 1162 11AB; # (낸; 낸; 낸; 낸; 낸; ) HANGUL SYLLABLE NAEN
+B0B9;B0B9;1102 1162 11AC;B0B9;1102 1162 11AC; # (낹; 낹; 낹; 낹; 낹; ) HANGUL SYLLABLE NAENJ
+B0BA;B0BA;1102 1162 11AD;B0BA;1102 1162 11AD; # (낺; 낺; 낺; 낺; 낺; ) HANGUL SYLLABLE NAENH
+B0BB;B0BB;1102 1162 11AE;B0BB;1102 1162 11AE; # (낻; 낻; 낻; 낻; 낻; ) HANGUL SYLLABLE NAED
+B0BC;B0BC;1102 1162 11AF;B0BC;1102 1162 11AF; # (낼; 낼; 낼; 낼; 낼; ) HANGUL SYLLABLE NAEL
+B0BD;B0BD;1102 1162 11B0;B0BD;1102 1162 11B0; # (낽; 낽; 낽; 낽; 낽; ) HANGUL SYLLABLE NAELG
+B0BE;B0BE;1102 1162 11B1;B0BE;1102 1162 11B1; # (낾; 낾; 낾; 낾; 낾; ) HANGUL SYLLABLE NAELM
+B0BF;B0BF;1102 1162 11B2;B0BF;1102 1162 11B2; # (낿; 낿; 낿; 낿; 낿; ) HANGUL SYLLABLE NAELB
+B0C0;B0C0;1102 1162 11B3;B0C0;1102 1162 11B3; # (냀; 냀; 냀; 냀; 냀; ) HANGUL SYLLABLE NAELS
+B0C1;B0C1;1102 1162 11B4;B0C1;1102 1162 11B4; # (냁; 냁; 냁; 냁; 냁; ) HANGUL SYLLABLE NAELT
+B0C2;B0C2;1102 1162 11B5;B0C2;1102 1162 11B5; # (냂; 냂; 냂; 냂; 냂; ) HANGUL SYLLABLE NAELP
+B0C3;B0C3;1102 1162 11B6;B0C3;1102 1162 11B6; # (냃; 냃; 냃; 냃; 냃; ) HANGUL SYLLABLE NAELH
+B0C4;B0C4;1102 1162 11B7;B0C4;1102 1162 11B7; # (냄; 냄; 냄; 냄; 냄; ) HANGUL SYLLABLE NAEM
+B0C5;B0C5;1102 1162 11B8;B0C5;1102 1162 11B8; # (냅; 냅; 냅; 냅; 냅; ) HANGUL SYLLABLE NAEB
+B0C6;B0C6;1102 1162 11B9;B0C6;1102 1162 11B9; # (냆; 냆; 냆; 냆; 냆; ) HANGUL SYLLABLE NAEBS
+B0C7;B0C7;1102 1162 11BA;B0C7;1102 1162 11BA; # (냇; 냇; 냇; 냇; 냇; ) HANGUL SYLLABLE NAES
+B0C8;B0C8;1102 1162 11BB;B0C8;1102 1162 11BB; # (냈; 냈; 냈; 냈; 냈; ) HANGUL SYLLABLE NAESS
+B0C9;B0C9;1102 1162 11BC;B0C9;1102 1162 11BC; # (냉; 냉; 냉; 냉; 냉; ) HANGUL SYLLABLE NAENG
+B0CA;B0CA;1102 1162 11BD;B0CA;1102 1162 11BD; # (냊; 냊; 냊; 냊; 냊; ) HANGUL SYLLABLE NAEJ
+B0CB;B0CB;1102 1162 11BE;B0CB;1102 1162 11BE; # (냋; 냋; 냋; 냋; 냋; ) HANGUL SYLLABLE NAEC
+B0CC;B0CC;1102 1162 11BF;B0CC;1102 1162 11BF; # (냌; 냌; 냌; 냌; 냌; ) HANGUL SYLLABLE NAEK
+B0CD;B0CD;1102 1162 11C0;B0CD;1102 1162 11C0; # (냍; 냍; 냍; 냍; 냍; ) HANGUL SYLLABLE NAET
+B0CE;B0CE;1102 1162 11C1;B0CE;1102 1162 11C1; # (냎; 냎; 냎; 냎; 냎; ) HANGUL SYLLABLE NAEP
+B0CF;B0CF;1102 1162 11C2;B0CF;1102 1162 11C2; # (냏; 냏; 냏; 냏; 냏; ) HANGUL SYLLABLE NAEH
+B0D0;B0D0;1102 1163;B0D0;1102 1163; # (냐; 냐; 냐; 냐; 냐; ) HANGUL SYLLABLE NYA
+B0D1;B0D1;1102 1163 11A8;B0D1;1102 1163 11A8; # (냑; 냑; 냑; 냑; 냑; ) HANGUL SYLLABLE NYAG
+B0D2;B0D2;1102 1163 11A9;B0D2;1102 1163 11A9; # (냒; 냒; 냒; 냒; 냒; ) HANGUL SYLLABLE NYAGG
+B0D3;B0D3;1102 1163 11AA;B0D3;1102 1163 11AA; # (냓; 냓; 냓; 냓; 냓; ) HANGUL SYLLABLE NYAGS
+B0D4;B0D4;1102 1163 11AB;B0D4;1102 1163 11AB; # (냔; 냔; 냔; 냔; 냔; ) HANGUL SYLLABLE NYAN
+B0D5;B0D5;1102 1163 11AC;B0D5;1102 1163 11AC; # (냕; 냕; 냕; 냕; 냕; ) HANGUL SYLLABLE NYANJ
+B0D6;B0D6;1102 1163 11AD;B0D6;1102 1163 11AD; # (냖; 냖; 냖; 냖; 냖; ) HANGUL SYLLABLE NYANH
+B0D7;B0D7;1102 1163 11AE;B0D7;1102 1163 11AE; # (냗; 냗; 냗; 냗; 냗; ) HANGUL SYLLABLE NYAD
+B0D8;B0D8;1102 1163 11AF;B0D8;1102 1163 11AF; # (냘; 냘; 냘; 냘; 냘; ) HANGUL SYLLABLE NYAL
+B0D9;B0D9;1102 1163 11B0;B0D9;1102 1163 11B0; # (냙; 냙; 냙; 냙; 냙; ) HANGUL SYLLABLE NYALG
+B0DA;B0DA;1102 1163 11B1;B0DA;1102 1163 11B1; # (냚; 냚; 냚; 냚; 냚; ) HANGUL SYLLABLE NYALM
+B0DB;B0DB;1102 1163 11B2;B0DB;1102 1163 11B2; # (냛; 냛; 냛; 냛; 냛; ) HANGUL SYLLABLE NYALB
+B0DC;B0DC;1102 1163 11B3;B0DC;1102 1163 11B3; # (냜; 냜; 냜; 냜; 냜; ) HANGUL SYLLABLE NYALS
+B0DD;B0DD;1102 1163 11B4;B0DD;1102 1163 11B4; # (냝; 냝; 냝; 냝; 냝; ) HANGUL SYLLABLE NYALT
+B0DE;B0DE;1102 1163 11B5;B0DE;1102 1163 11B5; # (냞; 냞; 냞; 냞; 냞; ) HANGUL SYLLABLE NYALP
+B0DF;B0DF;1102 1163 11B6;B0DF;1102 1163 11B6; # (냟; 냟; 냟; 냟; 냟; ) HANGUL SYLLABLE NYALH
+B0E0;B0E0;1102 1163 11B7;B0E0;1102 1163 11B7; # (냠; 냠; 냠; 냠; 냠; ) HANGUL SYLLABLE NYAM
+B0E1;B0E1;1102 1163 11B8;B0E1;1102 1163 11B8; # (냡; 냡; 냡; 냡; 냡; ) HANGUL SYLLABLE NYAB
+B0E2;B0E2;1102 1163 11B9;B0E2;1102 1163 11B9; # (냢; 냢; 냢; 냢; 냢; ) HANGUL SYLLABLE NYABS
+B0E3;B0E3;1102 1163 11BA;B0E3;1102 1163 11BA; # (냣; 냣; 냣; 냣; 냣; ) HANGUL SYLLABLE NYAS
+B0E4;B0E4;1102 1163 11BB;B0E4;1102 1163 11BB; # (냤; 냤; 냤; 냤; 냤; ) HANGUL SYLLABLE NYASS
+B0E5;B0E5;1102 1163 11BC;B0E5;1102 1163 11BC; # (냥; 냥; 냥; 냥; 냥; ) HANGUL SYLLABLE NYANG
+B0E6;B0E6;1102 1163 11BD;B0E6;1102 1163 11BD; # (냦; 냦; 냦; 냦; 냦; ) HANGUL SYLLABLE NYAJ
+B0E7;B0E7;1102 1163 11BE;B0E7;1102 1163 11BE; # (냧; 냧; 냧; 냧; 냧; ) HANGUL SYLLABLE NYAC
+B0E8;B0E8;1102 1163 11BF;B0E8;1102 1163 11BF; # (냨; 냨; 냨; 냨; 냨; ) HANGUL SYLLABLE NYAK
+B0E9;B0E9;1102 1163 11C0;B0E9;1102 1163 11C0; # (냩; 냩; 냩; 냩; 냩; ) HANGUL SYLLABLE NYAT
+B0EA;B0EA;1102 1163 11C1;B0EA;1102 1163 11C1; # (냪; 냪; 냪; 냪; 냪; ) HANGUL SYLLABLE NYAP
+B0EB;B0EB;1102 1163 11C2;B0EB;1102 1163 11C2; # (냫; 냫; 냫; 냫; 냫; ) HANGUL SYLLABLE NYAH
+B0EC;B0EC;1102 1164;B0EC;1102 1164; # (냬; 냬; 냬; 냬; 냬; ) HANGUL SYLLABLE NYAE
+B0ED;B0ED;1102 1164 11A8;B0ED;1102 1164 11A8; # (냭; 냭; 냭; 냭; 냭; ) HANGUL SYLLABLE NYAEG
+B0EE;B0EE;1102 1164 11A9;B0EE;1102 1164 11A9; # (냮; 냮; 냮; 냮; 냮; ) HANGUL SYLLABLE NYAEGG
+B0EF;B0EF;1102 1164 11AA;B0EF;1102 1164 11AA; # (냯; 냯; 냯; 냯; 냯; ) HANGUL SYLLABLE NYAEGS
+B0F0;B0F0;1102 1164 11AB;B0F0;1102 1164 11AB; # (냰; 냰; 냰; 냰; 냰; ) HANGUL SYLLABLE NYAEN
+B0F1;B0F1;1102 1164 11AC;B0F1;1102 1164 11AC; # (냱; 냱; 냱; 냱; 냱; ) HANGUL SYLLABLE NYAENJ
+B0F2;B0F2;1102 1164 11AD;B0F2;1102 1164 11AD; # (냲; 냲; 냲; 냲; 냲; ) HANGUL SYLLABLE NYAENH
+B0F3;B0F3;1102 1164 11AE;B0F3;1102 1164 11AE; # (냳; 냳; 냳; 냳; 냳; ) HANGUL SYLLABLE NYAED
+B0F4;B0F4;1102 1164 11AF;B0F4;1102 1164 11AF; # (냴; 냴; 냴; 냴; 냴; ) HANGUL SYLLABLE NYAEL
+B0F5;B0F5;1102 1164 11B0;B0F5;1102 1164 11B0; # (냵; 냵; 냵; 냵; 냵; ) HANGUL SYLLABLE NYAELG
+B0F6;B0F6;1102 1164 11B1;B0F6;1102 1164 11B1; # (냶; 냶; 냶; 냶; 냶; ) HANGUL SYLLABLE NYAELM
+B0F7;B0F7;1102 1164 11B2;B0F7;1102 1164 11B2; # (냷; 냷; 냷; 냷; 냷; ) HANGUL SYLLABLE NYAELB
+B0F8;B0F8;1102 1164 11B3;B0F8;1102 1164 11B3; # (냸; 냸; 냸; 냸; 냸; ) HANGUL SYLLABLE NYAELS
+B0F9;B0F9;1102 1164 11B4;B0F9;1102 1164 11B4; # (냹; 냹; 냹; 냹; 냹; ) HANGUL SYLLABLE NYAELT
+B0FA;B0FA;1102 1164 11B5;B0FA;1102 1164 11B5; # (냺; 냺; 냺; 냺; 냺; ) HANGUL SYLLABLE NYAELP
+B0FB;B0FB;1102 1164 11B6;B0FB;1102 1164 11B6; # (냻; 냻; 냻; 냻; 냻; ) HANGUL SYLLABLE NYAELH
+B0FC;B0FC;1102 1164 11B7;B0FC;1102 1164 11B7; # (냼; 냼; 냼; 냼; 냼; ) HANGUL SYLLABLE NYAEM
+B0FD;B0FD;1102 1164 11B8;B0FD;1102 1164 11B8; # (냽; 냽; 냽; 냽; 냽; ) HANGUL SYLLABLE NYAEB
+B0FE;B0FE;1102 1164 11B9;B0FE;1102 1164 11B9; # (냾; 냾; 냾; 냾; 냾; ) HANGUL SYLLABLE NYAEBS
+B0FF;B0FF;1102 1164 11BA;B0FF;1102 1164 11BA; # (냿; 냿; 냿; 냿; 냿; ) HANGUL SYLLABLE NYAES
+B100;B100;1102 1164 11BB;B100;1102 1164 11BB; # (넀; 넀; 넀; 넀; 넀; ) HANGUL SYLLABLE NYAESS
+B101;B101;1102 1164 11BC;B101;1102 1164 11BC; # (넁; 넁; 넁; 넁; 넁; ) HANGUL SYLLABLE NYAENG
+B102;B102;1102 1164 11BD;B102;1102 1164 11BD; # (넂; 넂; 넂; 넂; 넂; ) HANGUL SYLLABLE NYAEJ
+B103;B103;1102 1164 11BE;B103;1102 1164 11BE; # (넃; 넃; 넃; 넃; 넃; ) HANGUL SYLLABLE NYAEC
+B104;B104;1102 1164 11BF;B104;1102 1164 11BF; # (넄; 넄; 넄; 넄; 넄; ) HANGUL SYLLABLE NYAEK
+B105;B105;1102 1164 11C0;B105;1102 1164 11C0; # (넅; 넅; 넅; 넅; 넅; ) HANGUL SYLLABLE NYAET
+B106;B106;1102 1164 11C1;B106;1102 1164 11C1; # (넆; 넆; 넆; 넆; 넆; ) HANGUL SYLLABLE NYAEP
+B107;B107;1102 1164 11C2;B107;1102 1164 11C2; # (넇; 넇; 넇; 넇; 넇; ) HANGUL SYLLABLE NYAEH
+B108;B108;1102 1165;B108;1102 1165; # (너; 너; 너; 너; 너; ) HANGUL SYLLABLE NEO
+B109;B109;1102 1165 11A8;B109;1102 1165 11A8; # (넉; 넉; 넉; 넉; 넉; ) HANGUL SYLLABLE NEOG
+B10A;B10A;1102 1165 11A9;B10A;1102 1165 11A9; # (넊; 넊; 넊; 넊; 넊; ) HANGUL SYLLABLE NEOGG
+B10B;B10B;1102 1165 11AA;B10B;1102 1165 11AA; # (넋; 넋; 넋; 넋; 넋; ) HANGUL SYLLABLE NEOGS
+B10C;B10C;1102 1165 11AB;B10C;1102 1165 11AB; # (넌; 넌; 넌; 넌; 넌; ) HANGUL SYLLABLE NEON
+B10D;B10D;1102 1165 11AC;B10D;1102 1165 11AC; # (넍; 넍; 넍; 넍; 넍; ) HANGUL SYLLABLE NEONJ
+B10E;B10E;1102 1165 11AD;B10E;1102 1165 11AD; # (넎; 넎; 넎; 넎; 넎; ) HANGUL SYLLABLE NEONH
+B10F;B10F;1102 1165 11AE;B10F;1102 1165 11AE; # (넏; 넏; 넏; 넏; 넏; ) HANGUL SYLLABLE NEOD
+B110;B110;1102 1165 11AF;B110;1102 1165 11AF; # (널; 널; 널; 널; 널; ) HANGUL SYLLABLE NEOL
+B111;B111;1102 1165 11B0;B111;1102 1165 11B0; # (넑; 넑; 넑; 넑; 넑; ) HANGUL SYLLABLE NEOLG
+B112;B112;1102 1165 11B1;B112;1102 1165 11B1; # (넒; 넒; 넒; 넒; 넒; ) HANGUL SYLLABLE NEOLM
+B113;B113;1102 1165 11B2;B113;1102 1165 11B2; # (넓; 넓; 넓; 넓; 넓; ) HANGUL SYLLABLE NEOLB
+B114;B114;1102 1165 11B3;B114;1102 1165 11B3; # (넔; 넔; 넔; 넔; 넔; ) HANGUL SYLLABLE NEOLS
+B115;B115;1102 1165 11B4;B115;1102 1165 11B4; # (넕; 넕; 넕; 넕; 넕; ) HANGUL SYLLABLE NEOLT
+B116;B116;1102 1165 11B5;B116;1102 1165 11B5; # (넖; 넖; 넖; 넖; 넖; ) HANGUL SYLLABLE NEOLP
+B117;B117;1102 1165 11B6;B117;1102 1165 11B6; # (넗; 넗; 넗; 넗; 넗; ) HANGUL SYLLABLE NEOLH
+B118;B118;1102 1165 11B7;B118;1102 1165 11B7; # (넘; 넘; 넘; 넘; 넘; ) HANGUL SYLLABLE NEOM
+B119;B119;1102 1165 11B8;B119;1102 1165 11B8; # (넙; 넙; 넙; 넙; 넙; ) HANGUL SYLLABLE NEOB
+B11A;B11A;1102 1165 11B9;B11A;1102 1165 11B9; # (넚; 넚; 넚; 넚; 넚; ) HANGUL SYLLABLE NEOBS
+B11B;B11B;1102 1165 11BA;B11B;1102 1165 11BA; # (넛; 넛; 넛; 넛; 넛; ) HANGUL SYLLABLE NEOS
+B11C;B11C;1102 1165 11BB;B11C;1102 1165 11BB; # (넜; 넜; 넜; 넜; 넜; ) HANGUL SYLLABLE NEOSS
+B11D;B11D;1102 1165 11BC;B11D;1102 1165 11BC; # (넝; 넝; 넝; 넝; 넝; ) HANGUL SYLLABLE NEONG
+B11E;B11E;1102 1165 11BD;B11E;1102 1165 11BD; # (넞; 넞; 넞; 넞; 넞; ) HANGUL SYLLABLE NEOJ
+B11F;B11F;1102 1165 11BE;B11F;1102 1165 11BE; # (넟; 넟; 넟; 넟; 넟; ) HANGUL SYLLABLE NEOC
+B120;B120;1102 1165 11BF;B120;1102 1165 11BF; # (넠; 넠; 넠; 넠; 넠; ) HANGUL SYLLABLE NEOK
+B121;B121;1102 1165 11C0;B121;1102 1165 11C0; # (넡; 넡; 넡; 넡; 넡; ) HANGUL SYLLABLE NEOT
+B122;B122;1102 1165 11C1;B122;1102 1165 11C1; # (넢; 넢; 넢; 넢; 넢; ) HANGUL SYLLABLE NEOP
+B123;B123;1102 1165 11C2;B123;1102 1165 11C2; # (넣; 넣; 넣; 넣; 넣; ) HANGUL SYLLABLE NEOH
+B124;B124;1102 1166;B124;1102 1166; # (네; 네; 네; 네; 네; ) HANGUL SYLLABLE NE
+B125;B125;1102 1166 11A8;B125;1102 1166 11A8; # (넥; 넥; 넥; 넥; 넥; ) HANGUL SYLLABLE NEG
+B126;B126;1102 1166 11A9;B126;1102 1166 11A9; # (넦; 넦; 넦; 넦; 넦; ) HANGUL SYLLABLE NEGG
+B127;B127;1102 1166 11AA;B127;1102 1166 11AA; # (넧; 넧; 넧; 넧; 넧; ) HANGUL SYLLABLE NEGS
+B128;B128;1102 1166 11AB;B128;1102 1166 11AB; # (넨; 넨; 넨; 넨; 넨; ) HANGUL SYLLABLE NEN
+B129;B129;1102 1166 11AC;B129;1102 1166 11AC; # (넩; 넩; 넩; 넩; 넩; ) HANGUL SYLLABLE NENJ
+B12A;B12A;1102 1166 11AD;B12A;1102 1166 11AD; # (넪; 넪; 넪; 넪; 넪; ) HANGUL SYLLABLE NENH
+B12B;B12B;1102 1166 11AE;B12B;1102 1166 11AE; # (넫; 넫; 넫; 넫; 넫; ) HANGUL SYLLABLE NED
+B12C;B12C;1102 1166 11AF;B12C;1102 1166 11AF; # (넬; 넬; 넬; 넬; 넬; ) HANGUL SYLLABLE NEL
+B12D;B12D;1102 1166 11B0;B12D;1102 1166 11B0; # (넭; 넭; 넭; 넭; 넭; ) HANGUL SYLLABLE NELG
+B12E;B12E;1102 1166 11B1;B12E;1102 1166 11B1; # (넮; 넮; 넮; 넮; 넮; ) HANGUL SYLLABLE NELM
+B12F;B12F;1102 1166 11B2;B12F;1102 1166 11B2; # (넯; 넯; 넯; 넯; 넯; ) HANGUL SYLLABLE NELB
+B130;B130;1102 1166 11B3;B130;1102 1166 11B3; # (넰; 넰; 넰; 넰; 넰; ) HANGUL SYLLABLE NELS
+B131;B131;1102 1166 11B4;B131;1102 1166 11B4; # (넱; 넱; 넱; 넱; 넱; ) HANGUL SYLLABLE NELT
+B132;B132;1102 1166 11B5;B132;1102 1166 11B5; # (넲; 넲; 넲; 넲; 넲; ) HANGUL SYLLABLE NELP
+B133;B133;1102 1166 11B6;B133;1102 1166 11B6; # (넳; 넳; 넳; 넳; 넳; ) HANGUL SYLLABLE NELH
+B134;B134;1102 1166 11B7;B134;1102 1166 11B7; # (넴; 넴; 넴; 넴; 넴; ) HANGUL SYLLABLE NEM
+B135;B135;1102 1166 11B8;B135;1102 1166 11B8; # (넵; 넵; 넵; 넵; 넵; ) HANGUL SYLLABLE NEB
+B136;B136;1102 1166 11B9;B136;1102 1166 11B9; # (넶; 넶; 넶; 넶; 넶; ) HANGUL SYLLABLE NEBS
+B137;B137;1102 1166 11BA;B137;1102 1166 11BA; # (넷; 넷; 넷; 넷; 넷; ) HANGUL SYLLABLE NES
+B138;B138;1102 1166 11BB;B138;1102 1166 11BB; # (넸; 넸; 넸; 넸; 넸; ) HANGUL SYLLABLE NESS
+B139;B139;1102 1166 11BC;B139;1102 1166 11BC; # (넹; 넹; 넹; 넹; 넹; ) HANGUL SYLLABLE NENG
+B13A;B13A;1102 1166 11BD;B13A;1102 1166 11BD; # (넺; 넺; 넺; 넺; 넺; ) HANGUL SYLLABLE NEJ
+B13B;B13B;1102 1166 11BE;B13B;1102 1166 11BE; # (넻; 넻; 넻; 넻; 넻; ) HANGUL SYLLABLE NEC
+B13C;B13C;1102 1166 11BF;B13C;1102 1166 11BF; # (넼; 넼; 넼; 넼; 넼; ) HANGUL SYLLABLE NEK
+B13D;B13D;1102 1166 11C0;B13D;1102 1166 11C0; # (넽; 넽; 넽; 넽; 넽; ) HANGUL SYLLABLE NET
+B13E;B13E;1102 1166 11C1;B13E;1102 1166 11C1; # (넾; 넾; 넾; 넾; 넾; ) HANGUL SYLLABLE NEP
+B13F;B13F;1102 1166 11C2;B13F;1102 1166 11C2; # (넿; 넿; 넿; 넿; 넿; ) HANGUL SYLLABLE NEH
+B140;B140;1102 1167;B140;1102 1167; # (녀; 녀; 녀; 녀; 녀; ) HANGUL SYLLABLE NYEO
+B141;B141;1102 1167 11A8;B141;1102 1167 11A8; # (녁; 녁; 녁; 녁; 녁; ) HANGUL SYLLABLE NYEOG
+B142;B142;1102 1167 11A9;B142;1102 1167 11A9; # (녂; 녂; 녂; 녂; 녂; ) HANGUL SYLLABLE NYEOGG
+B143;B143;1102 1167 11AA;B143;1102 1167 11AA; # (녃; 녃; 녃; 녃; 녃; ) HANGUL SYLLABLE NYEOGS
+B144;B144;1102 1167 11AB;B144;1102 1167 11AB; # (년; 년; 년; 년; 년; ) HANGUL SYLLABLE NYEON
+B145;B145;1102 1167 11AC;B145;1102 1167 11AC; # (녅; 녅; 녅; 녅; 녅; ) HANGUL SYLLABLE NYEONJ
+B146;B146;1102 1167 11AD;B146;1102 1167 11AD; # (녆; 녆; 녆; 녆; 녆; ) HANGUL SYLLABLE NYEONH
+B147;B147;1102 1167 11AE;B147;1102 1167 11AE; # (녇; 녇; 녇; 녇; 녇; ) HANGUL SYLLABLE NYEOD
+B148;B148;1102 1167 11AF;B148;1102 1167 11AF; # (녈; 녈; 녈; 녈; 녈; ) HANGUL SYLLABLE NYEOL
+B149;B149;1102 1167 11B0;B149;1102 1167 11B0; # (녉; 녉; 녉; 녉; 녉; ) HANGUL SYLLABLE NYEOLG
+B14A;B14A;1102 1167 11B1;B14A;1102 1167 11B1; # (녊; 녊; 녊; 녊; 녊; ) HANGUL SYLLABLE NYEOLM
+B14B;B14B;1102 1167 11B2;B14B;1102 1167 11B2; # (녋; 녋; 녋; 녋; 녋; ) HANGUL SYLLABLE NYEOLB
+B14C;B14C;1102 1167 11B3;B14C;1102 1167 11B3; # (녌; 녌; 녌; 녌; 녌; ) HANGUL SYLLABLE NYEOLS
+B14D;B14D;1102 1167 11B4;B14D;1102 1167 11B4; # (녍; 녍; 녍; 녍; 녍; ) HANGUL SYLLABLE NYEOLT
+B14E;B14E;1102 1167 11B5;B14E;1102 1167 11B5; # (녎; 녎; 녎; 녎; 녎; ) HANGUL SYLLABLE NYEOLP
+B14F;B14F;1102 1167 11B6;B14F;1102 1167 11B6; # (녏; 녏; 녏; 녏; 녏; ) HANGUL SYLLABLE NYEOLH
+B150;B150;1102 1167 11B7;B150;1102 1167 11B7; # (념; 념; 념; 념; 념; ) HANGUL SYLLABLE NYEOM
+B151;B151;1102 1167 11B8;B151;1102 1167 11B8; # (녑; 녑; 녑; 녑; 녑; ) HANGUL SYLLABLE NYEOB
+B152;B152;1102 1167 11B9;B152;1102 1167 11B9; # (녒; 녒; 녒; 녒; 녒; ) HANGUL SYLLABLE NYEOBS
+B153;B153;1102 1167 11BA;B153;1102 1167 11BA; # (녓; 녓; 녓; 녓; 녓; ) HANGUL SYLLABLE NYEOS
+B154;B154;1102 1167 11BB;B154;1102 1167 11BB; # (녔; 녔; 녔; 녔; 녔; ) HANGUL SYLLABLE NYEOSS
+B155;B155;1102 1167 11BC;B155;1102 1167 11BC; # (녕; 녕; 녕; 녕; 녕; ) HANGUL SYLLABLE NYEONG
+B156;B156;1102 1167 11BD;B156;1102 1167 11BD; # (녖; 녖; 녖; 녖; 녖; ) HANGUL SYLLABLE NYEOJ
+B157;B157;1102 1167 11BE;B157;1102 1167 11BE; # (녗; 녗; 녗; 녗; 녗; ) HANGUL SYLLABLE NYEOC
+B158;B158;1102 1167 11BF;B158;1102 1167 11BF; # (녘; 녘; 녘; 녘; 녘; ) HANGUL SYLLABLE NYEOK
+B159;B159;1102 1167 11C0;B159;1102 1167 11C0; # (녙; 녙; 녙; 녙; 녙; ) HANGUL SYLLABLE NYEOT
+B15A;B15A;1102 1167 11C1;B15A;1102 1167 11C1; # (녚; 녚; 녚; 녚; 녚; ) HANGUL SYLLABLE NYEOP
+B15B;B15B;1102 1167 11C2;B15B;1102 1167 11C2; # (녛; 녛; 녛; 녛; 녛; ) HANGUL SYLLABLE NYEOH
+B15C;B15C;1102 1168;B15C;1102 1168; # (녜; 녜; 녜; 녜; 녜; ) HANGUL SYLLABLE NYE
+B15D;B15D;1102 1168 11A8;B15D;1102 1168 11A8; # (녝; 녝; 녝; 녝; 녝; ) HANGUL SYLLABLE NYEG
+B15E;B15E;1102 1168 11A9;B15E;1102 1168 11A9; # (녞; 녞; 녞; 녞; 녞; ) HANGUL SYLLABLE NYEGG
+B15F;B15F;1102 1168 11AA;B15F;1102 1168 11AA; # (녟; 녟; 녟; 녟; 녟; ) HANGUL SYLLABLE NYEGS
+B160;B160;1102 1168 11AB;B160;1102 1168 11AB; # (녠; 녠; 녠; 녠; 녠; ) HANGUL SYLLABLE NYEN
+B161;B161;1102 1168 11AC;B161;1102 1168 11AC; # (녡; 녡; 녡; 녡; 녡; ) HANGUL SYLLABLE NYENJ
+B162;B162;1102 1168 11AD;B162;1102 1168 11AD; # (녢; 녢; 녢; 녢; 녢; ) HANGUL SYLLABLE NYENH
+B163;B163;1102 1168 11AE;B163;1102 1168 11AE; # (녣; 녣; 녣; 녣; 녣; ) HANGUL SYLLABLE NYED
+B164;B164;1102 1168 11AF;B164;1102 1168 11AF; # (녤; 녤; 녤; 녤; 녤; ) HANGUL SYLLABLE NYEL
+B165;B165;1102 1168 11B0;B165;1102 1168 11B0; # (녥; 녥; 녥; 녥; 녥; ) HANGUL SYLLABLE NYELG
+B166;B166;1102 1168 11B1;B166;1102 1168 11B1; # (녦; 녦; 녦; 녦; 녦; ) HANGUL SYLLABLE NYELM
+B167;B167;1102 1168 11B2;B167;1102 1168 11B2; # (녧; 녧; 녧; 녧; 녧; ) HANGUL SYLLABLE NYELB
+B168;B168;1102 1168 11B3;B168;1102 1168 11B3; # (녨; 녨; 녨; 녨; 녨; ) HANGUL SYLLABLE NYELS
+B169;B169;1102 1168 11B4;B169;1102 1168 11B4; # (녩; 녩; 녩; 녩; 녩; ) HANGUL SYLLABLE NYELT
+B16A;B16A;1102 1168 11B5;B16A;1102 1168 11B5; # (녪; 녪; 녪; 녪; 녪; ) HANGUL SYLLABLE NYELP
+B16B;B16B;1102 1168 11B6;B16B;1102 1168 11B6; # (녫; 녫; 녫; 녫; 녫; ) HANGUL SYLLABLE NYELH
+B16C;B16C;1102 1168 11B7;B16C;1102 1168 11B7; # (녬; 녬; 녬; 녬; 녬; ) HANGUL SYLLABLE NYEM
+B16D;B16D;1102 1168 11B8;B16D;1102 1168 11B8; # (녭; 녭; 녭; 녭; 녭; ) HANGUL SYLLABLE NYEB
+B16E;B16E;1102 1168 11B9;B16E;1102 1168 11B9; # (녮; 녮; 녮; 녮; 녮; ) HANGUL SYLLABLE NYEBS
+B16F;B16F;1102 1168 11BA;B16F;1102 1168 11BA; # (녯; 녯; 녯; 녯; 녯; ) HANGUL SYLLABLE NYES
+B170;B170;1102 1168 11BB;B170;1102 1168 11BB; # (녰; 녰; 녰; 녰; 녰; ) HANGUL SYLLABLE NYESS
+B171;B171;1102 1168 11BC;B171;1102 1168 11BC; # (녱; 녱; 녱; 녱; 녱; ) HANGUL SYLLABLE NYENG
+B172;B172;1102 1168 11BD;B172;1102 1168 11BD; # (녲; 녲; 녲; 녲; 녲; ) HANGUL SYLLABLE NYEJ
+B173;B173;1102 1168 11BE;B173;1102 1168 11BE; # (녳; 녳; 녳; 녳; 녳; ) HANGUL SYLLABLE NYEC
+B174;B174;1102 1168 11BF;B174;1102 1168 11BF; # (녴; 녴; 녴; 녴; 녴; ) HANGUL SYLLABLE NYEK
+B175;B175;1102 1168 11C0;B175;1102 1168 11C0; # (녵; 녵; 녵; 녵; 녵; ) HANGUL SYLLABLE NYET
+B176;B176;1102 1168 11C1;B176;1102 1168 11C1; # (녶; 녶; 녶; 녶; 녶; ) HANGUL SYLLABLE NYEP
+B177;B177;1102 1168 11C2;B177;1102 1168 11C2; # (녷; 녷; 녷; 녷; 녷; ) HANGUL SYLLABLE NYEH
+B178;B178;1102 1169;B178;1102 1169; # (노; 노; 노; 노; 노; ) HANGUL SYLLABLE NO
+B179;B179;1102 1169 11A8;B179;1102 1169 11A8; # (녹; 녹; 녹; 녹; 녹; ) HANGUL SYLLABLE NOG
+B17A;B17A;1102 1169 11A9;B17A;1102 1169 11A9; # (녺; 녺; 녺; 녺; 녺; ) HANGUL SYLLABLE NOGG
+B17B;B17B;1102 1169 11AA;B17B;1102 1169 11AA; # (녻; 녻; 녻; 녻; 녻; ) HANGUL SYLLABLE NOGS
+B17C;B17C;1102 1169 11AB;B17C;1102 1169 11AB; # (논; 논; 논; 논; 논; ) HANGUL SYLLABLE NON
+B17D;B17D;1102 1169 11AC;B17D;1102 1169 11AC; # (녽; 녽; 녽; 녽; 녽; ) HANGUL SYLLABLE NONJ
+B17E;B17E;1102 1169 11AD;B17E;1102 1169 11AD; # (녾; 녾; 녾; 녾; 녾; ) HANGUL SYLLABLE NONH
+B17F;B17F;1102 1169 11AE;B17F;1102 1169 11AE; # (녿; 녿; 녿; 녿; 녿; ) HANGUL SYLLABLE NOD
+B180;B180;1102 1169 11AF;B180;1102 1169 11AF; # (놀; 놀; 놀; 놀; 놀; ) HANGUL SYLLABLE NOL
+B181;B181;1102 1169 11B0;B181;1102 1169 11B0; # (놁; 놁; 놁; 놁; 놁; ) HANGUL SYLLABLE NOLG
+B182;B182;1102 1169 11B1;B182;1102 1169 11B1; # (놂; 놂; 놂; 놂; 놂; ) HANGUL SYLLABLE NOLM
+B183;B183;1102 1169 11B2;B183;1102 1169 11B2; # (놃; 놃; 놃; 놃; 놃; ) HANGUL SYLLABLE NOLB
+B184;B184;1102 1169 11B3;B184;1102 1169 11B3; # (놄; 놄; 놄; 놄; 놄; ) HANGUL SYLLABLE NOLS
+B185;B185;1102 1169 11B4;B185;1102 1169 11B4; # (놅; 놅; 놅; 놅; 놅; ) HANGUL SYLLABLE NOLT
+B186;B186;1102 1169 11B5;B186;1102 1169 11B5; # (놆; 놆; 놆; 놆; 놆; ) HANGUL SYLLABLE NOLP
+B187;B187;1102 1169 11B6;B187;1102 1169 11B6; # (놇; 놇; 놇; 놇; 놇; ) HANGUL SYLLABLE NOLH
+B188;B188;1102 1169 11B7;B188;1102 1169 11B7; # (놈; 놈; 놈; 놈; 놈; ) HANGUL SYLLABLE NOM
+B189;B189;1102 1169 11B8;B189;1102 1169 11B8; # (놉; 놉; 놉; 놉; 놉; ) HANGUL SYLLABLE NOB
+B18A;B18A;1102 1169 11B9;B18A;1102 1169 11B9; # (놊; 놊; 놊; 놊; 놊; ) HANGUL SYLLABLE NOBS
+B18B;B18B;1102 1169 11BA;B18B;1102 1169 11BA; # (놋; 놋; 놋; 놋; 놋; ) HANGUL SYLLABLE NOS
+B18C;B18C;1102 1169 11BB;B18C;1102 1169 11BB; # (놌; 놌; 놌; 놌; 놌; ) HANGUL SYLLABLE NOSS
+B18D;B18D;1102 1169 11BC;B18D;1102 1169 11BC; # (농; 농; 농; 농; 농; ) HANGUL SYLLABLE NONG
+B18E;B18E;1102 1169 11BD;B18E;1102 1169 11BD; # (놎; 놎; 놎; 놎; 놎; ) HANGUL SYLLABLE NOJ
+B18F;B18F;1102 1169 11BE;B18F;1102 1169 11BE; # (놏; 놏; 놏; 놏; 놏; ) HANGUL SYLLABLE NOC
+B190;B190;1102 1169 11BF;B190;1102 1169 11BF; # (놐; 놐; 놐; 놐; 놐; ) HANGUL SYLLABLE NOK
+B191;B191;1102 1169 11C0;B191;1102 1169 11C0; # (놑; 놑; 놑; 놑; 놑; ) HANGUL SYLLABLE NOT
+B192;B192;1102 1169 11C1;B192;1102 1169 11C1; # (높; 높; 높; 높; 높; ) HANGUL SYLLABLE NOP
+B193;B193;1102 1169 11C2;B193;1102 1169 11C2; # (놓; 놓; 놓; 놓; 놓; ) HANGUL SYLLABLE NOH
+B194;B194;1102 116A;B194;1102 116A; # (놔; 놔; 놔; 놔; 놔; ) HANGUL SYLLABLE NWA
+B195;B195;1102 116A 11A8;B195;1102 116A 11A8; # (놕; 놕; 놕; 놕; 놕; ) HANGUL SYLLABLE NWAG
+B196;B196;1102 116A 11A9;B196;1102 116A 11A9; # (놖; 놖; 놖; 놖; 놖; ) HANGUL SYLLABLE NWAGG
+B197;B197;1102 116A 11AA;B197;1102 116A 11AA; # (놗; 놗; 놗; 놗; 놗; ) HANGUL SYLLABLE NWAGS
+B198;B198;1102 116A 11AB;B198;1102 116A 11AB; # (놘; 놘; 놘; 놘; 놘; ) HANGUL SYLLABLE NWAN
+B199;B199;1102 116A 11AC;B199;1102 116A 11AC; # (놙; 놙; 놙; 놙; 놙; ) HANGUL SYLLABLE NWANJ
+B19A;B19A;1102 116A 11AD;B19A;1102 116A 11AD; # (놚; 놚; 놚; 놚; 놚; ) HANGUL SYLLABLE NWANH
+B19B;B19B;1102 116A 11AE;B19B;1102 116A 11AE; # (놛; 놛; 놛; 놛; 놛; ) HANGUL SYLLABLE NWAD
+B19C;B19C;1102 116A 11AF;B19C;1102 116A 11AF; # (놜; 놜; 놜; 놜; 놜; ) HANGUL SYLLABLE NWAL
+B19D;B19D;1102 116A 11B0;B19D;1102 116A 11B0; # (놝; 놝; 놝; 놝; 놝; ) HANGUL SYLLABLE NWALG
+B19E;B19E;1102 116A 11B1;B19E;1102 116A 11B1; # (놞; 놞; 놞; 놞; 놞; ) HANGUL SYLLABLE NWALM
+B19F;B19F;1102 116A 11B2;B19F;1102 116A 11B2; # (놟; 놟; 놟; 놟; 놟; ) HANGUL SYLLABLE NWALB
+B1A0;B1A0;1102 116A 11B3;B1A0;1102 116A 11B3; # (놠; 놠; 놠; 놠; 놠; ) HANGUL SYLLABLE NWALS
+B1A1;B1A1;1102 116A 11B4;B1A1;1102 116A 11B4; # (놡; 놡; 놡; 놡; 놡; ) HANGUL SYLLABLE NWALT
+B1A2;B1A2;1102 116A 11B5;B1A2;1102 116A 11B5; # (놢; 놢; 놢; 놢; 놢; ) HANGUL SYLLABLE NWALP
+B1A3;B1A3;1102 116A 11B6;B1A3;1102 116A 11B6; # (놣; 놣; 놣; 놣; 놣; ) HANGUL SYLLABLE NWALH
+B1A4;B1A4;1102 116A 11B7;B1A4;1102 116A 11B7; # (놤; 놤; 놤; 놤; 놤; ) HANGUL SYLLABLE NWAM
+B1A5;B1A5;1102 116A 11B8;B1A5;1102 116A 11B8; # (놥; 놥; 놥; 놥; 놥; ) HANGUL SYLLABLE NWAB
+B1A6;B1A6;1102 116A 11B9;B1A6;1102 116A 11B9; # (놦; 놦; 놦; 놦; 놦; ) HANGUL SYLLABLE NWABS
+B1A7;B1A7;1102 116A 11BA;B1A7;1102 116A 11BA; # (놧; 놧; 놧; 놧; 놧; ) HANGUL SYLLABLE NWAS
+B1A8;B1A8;1102 116A 11BB;B1A8;1102 116A 11BB; # (놨; 놨; 놨; 놨; 놨; ) HANGUL SYLLABLE NWASS
+B1A9;B1A9;1102 116A 11BC;B1A9;1102 116A 11BC; # (놩; 놩; 놩; 놩; 놩; ) HANGUL SYLLABLE NWANG
+B1AA;B1AA;1102 116A 11BD;B1AA;1102 116A 11BD; # (놪; 놪; 놪; 놪; 놪; ) HANGUL SYLLABLE NWAJ
+B1AB;B1AB;1102 116A 11BE;B1AB;1102 116A 11BE; # (놫; 놫; 놫; 놫; 놫; ) HANGUL SYLLABLE NWAC
+B1AC;B1AC;1102 116A 11BF;B1AC;1102 116A 11BF; # (놬; 놬; 놬; 놬; 놬; ) HANGUL SYLLABLE NWAK
+B1AD;B1AD;1102 116A 11C0;B1AD;1102 116A 11C0; # (놭; 놭; 놭; 놭; 놭; ) HANGUL SYLLABLE NWAT
+B1AE;B1AE;1102 116A 11C1;B1AE;1102 116A 11C1; # (놮; 놮; 놮; 놮; 놮; ) HANGUL SYLLABLE NWAP
+B1AF;B1AF;1102 116A 11C2;B1AF;1102 116A 11C2; # (놯; 놯; 놯; 놯; 놯; ) HANGUL SYLLABLE NWAH
+B1B0;B1B0;1102 116B;B1B0;1102 116B; # (놰; 놰; 놰; 놰; 놰; ) HANGUL SYLLABLE NWAE
+B1B1;B1B1;1102 116B 11A8;B1B1;1102 116B 11A8; # (놱; 놱; 놱; 놱; 놱; ) HANGUL SYLLABLE NWAEG
+B1B2;B1B2;1102 116B 11A9;B1B2;1102 116B 11A9; # (놲; 놲; 놲; 놲; 놲; ) HANGUL SYLLABLE NWAEGG
+B1B3;B1B3;1102 116B 11AA;B1B3;1102 116B 11AA; # (놳; 놳; 놳; 놳; 놳; ) HANGUL SYLLABLE NWAEGS
+B1B4;B1B4;1102 116B 11AB;B1B4;1102 116B 11AB; # (놴; 놴; 놴; 놴; 놴; ) HANGUL SYLLABLE NWAEN
+B1B5;B1B5;1102 116B 11AC;B1B5;1102 116B 11AC; # (놵; 놵; 놵; 놵; 놵; ) HANGUL SYLLABLE NWAENJ
+B1B6;B1B6;1102 116B 11AD;B1B6;1102 116B 11AD; # (놶; 놶; 놶; 놶; 놶; ) HANGUL SYLLABLE NWAENH
+B1B7;B1B7;1102 116B 11AE;B1B7;1102 116B 11AE; # (놷; 놷; 놷; 놷; 놷; ) HANGUL SYLLABLE NWAED
+B1B8;B1B8;1102 116B 11AF;B1B8;1102 116B 11AF; # (놸; 놸; 놸; 놸; 놸; ) HANGUL SYLLABLE NWAEL
+B1B9;B1B9;1102 116B 11B0;B1B9;1102 116B 11B0; # (놹; 놹; 놹; 놹; 놹; ) HANGUL SYLLABLE NWAELG
+B1BA;B1BA;1102 116B 11B1;B1BA;1102 116B 11B1; # (놺; 놺; 놺; 놺; 놺; ) HANGUL SYLLABLE NWAELM
+B1BB;B1BB;1102 116B 11B2;B1BB;1102 116B 11B2; # (놻; 놻; 놻; 놻; 놻; ) HANGUL SYLLABLE NWAELB
+B1BC;B1BC;1102 116B 11B3;B1BC;1102 116B 11B3; # (놼; 놼; 놼; 놼; 놼; ) HANGUL SYLLABLE NWAELS
+B1BD;B1BD;1102 116B 11B4;B1BD;1102 116B 11B4; # (놽; 놽; 놽; 놽; 놽; ) HANGUL SYLLABLE NWAELT
+B1BE;B1BE;1102 116B 11B5;B1BE;1102 116B 11B5; # (놾; 놾; 놾; 놾; 놾; ) HANGUL SYLLABLE NWAELP
+B1BF;B1BF;1102 116B 11B6;B1BF;1102 116B 11B6; # (놿; 놿; 놿; 놿; 놿; ) HANGUL SYLLABLE NWAELH
+B1C0;B1C0;1102 116B 11B7;B1C0;1102 116B 11B7; # (뇀; 뇀; 뇀; 뇀; 뇀; ) HANGUL SYLLABLE NWAEM
+B1C1;B1C1;1102 116B 11B8;B1C1;1102 116B 11B8; # (뇁; 뇁; 뇁; 뇁; 뇁; ) HANGUL SYLLABLE NWAEB
+B1C2;B1C2;1102 116B 11B9;B1C2;1102 116B 11B9; # (뇂; 뇂; 뇂; 뇂; 뇂; ) HANGUL SYLLABLE NWAEBS
+B1C3;B1C3;1102 116B 11BA;B1C3;1102 116B 11BA; # (뇃; 뇃; 뇃; 뇃; 뇃; ) HANGUL SYLLABLE NWAES
+B1C4;B1C4;1102 116B 11BB;B1C4;1102 116B 11BB; # (뇄; 뇄; 뇄; 뇄; 뇄; ) HANGUL SYLLABLE NWAESS
+B1C5;B1C5;1102 116B 11BC;B1C5;1102 116B 11BC; # (뇅; 뇅; 뇅; 뇅; 뇅; ) HANGUL SYLLABLE NWAENG
+B1C6;B1C6;1102 116B 11BD;B1C6;1102 116B 11BD; # (뇆; 뇆; 뇆; 뇆; 뇆; ) HANGUL SYLLABLE NWAEJ
+B1C7;B1C7;1102 116B 11BE;B1C7;1102 116B 11BE; # (뇇; 뇇; 뇇; 뇇; 뇇; ) HANGUL SYLLABLE NWAEC
+B1C8;B1C8;1102 116B 11BF;B1C8;1102 116B 11BF; # (뇈; 뇈; 뇈; 뇈; 뇈; ) HANGUL SYLLABLE NWAEK
+B1C9;B1C9;1102 116B 11C0;B1C9;1102 116B 11C0; # (뇉; 뇉; 뇉; 뇉; 뇉; ) HANGUL SYLLABLE NWAET
+B1CA;B1CA;1102 116B 11C1;B1CA;1102 116B 11C1; # (뇊; 뇊; 뇊; 뇊; 뇊; ) HANGUL SYLLABLE NWAEP
+B1CB;B1CB;1102 116B 11C2;B1CB;1102 116B 11C2; # (뇋; 뇋; 뇋; 뇋; 뇋; ) HANGUL SYLLABLE NWAEH
+B1CC;B1CC;1102 116C;B1CC;1102 116C; # (뇌; 뇌; 뇌; 뇌; 뇌; ) HANGUL SYLLABLE NOE
+B1CD;B1CD;1102 116C 11A8;B1CD;1102 116C 11A8; # (뇍; 뇍; 뇍; 뇍; 뇍; ) HANGUL SYLLABLE NOEG
+B1CE;B1CE;1102 116C 11A9;B1CE;1102 116C 11A9; # (뇎; 뇎; 뇎; 뇎; 뇎; ) HANGUL SYLLABLE NOEGG
+B1CF;B1CF;1102 116C 11AA;B1CF;1102 116C 11AA; # (뇏; 뇏; 뇏; 뇏; 뇏; ) HANGUL SYLLABLE NOEGS
+B1D0;B1D0;1102 116C 11AB;B1D0;1102 116C 11AB; # (뇐; 뇐; 뇐; 뇐; 뇐; ) HANGUL SYLLABLE NOEN
+B1D1;B1D1;1102 116C 11AC;B1D1;1102 116C 11AC; # (뇑; 뇑; 뇑; 뇑; 뇑; ) HANGUL SYLLABLE NOENJ
+B1D2;B1D2;1102 116C 11AD;B1D2;1102 116C 11AD; # (뇒; 뇒; 뇒; 뇒; 뇒; ) HANGUL SYLLABLE NOENH
+B1D3;B1D3;1102 116C 11AE;B1D3;1102 116C 11AE; # (뇓; 뇓; 뇓; 뇓; 뇓; ) HANGUL SYLLABLE NOED
+B1D4;B1D4;1102 116C 11AF;B1D4;1102 116C 11AF; # (뇔; 뇔; 뇔; 뇔; 뇔; ) HANGUL SYLLABLE NOEL
+B1D5;B1D5;1102 116C 11B0;B1D5;1102 116C 11B0; # (뇕; 뇕; 뇕; 뇕; 뇕; ) HANGUL SYLLABLE NOELG
+B1D6;B1D6;1102 116C 11B1;B1D6;1102 116C 11B1; # (뇖; 뇖; 뇖; 뇖; 뇖; ) HANGUL SYLLABLE NOELM
+B1D7;B1D7;1102 116C 11B2;B1D7;1102 116C 11B2; # (뇗; 뇗; 뇗; 뇗; 뇗; ) HANGUL SYLLABLE NOELB
+B1D8;B1D8;1102 116C 11B3;B1D8;1102 116C 11B3; # (뇘; 뇘; 뇘; 뇘; 뇘; ) HANGUL SYLLABLE NOELS
+B1D9;B1D9;1102 116C 11B4;B1D9;1102 116C 11B4; # (뇙; 뇙; 뇙; 뇙; 뇙; ) HANGUL SYLLABLE NOELT
+B1DA;B1DA;1102 116C 11B5;B1DA;1102 116C 11B5; # (뇚; 뇚; 뇚; 뇚; 뇚; ) HANGUL SYLLABLE NOELP
+B1DB;B1DB;1102 116C 11B6;B1DB;1102 116C 11B6; # (뇛; 뇛; 뇛; 뇛; 뇛; ) HANGUL SYLLABLE NOELH
+B1DC;B1DC;1102 116C 11B7;B1DC;1102 116C 11B7; # (뇜; 뇜; 뇜; 뇜; 뇜; ) HANGUL SYLLABLE NOEM
+B1DD;B1DD;1102 116C 11B8;B1DD;1102 116C 11B8; # (뇝; 뇝; 뇝; 뇝; 뇝; ) HANGUL SYLLABLE NOEB
+B1DE;B1DE;1102 116C 11B9;B1DE;1102 116C 11B9; # (뇞; 뇞; 뇞; 뇞; 뇞; ) HANGUL SYLLABLE NOEBS
+B1DF;B1DF;1102 116C 11BA;B1DF;1102 116C 11BA; # (뇟; 뇟; 뇟; 뇟; 뇟; ) HANGUL SYLLABLE NOES
+B1E0;B1E0;1102 116C 11BB;B1E0;1102 116C 11BB; # (뇠; 뇠; 뇠; 뇠; 뇠; ) HANGUL SYLLABLE NOESS
+B1E1;B1E1;1102 116C 11BC;B1E1;1102 116C 11BC; # (뇡; 뇡; 뇡; 뇡; 뇡; ) HANGUL SYLLABLE NOENG
+B1E2;B1E2;1102 116C 11BD;B1E2;1102 116C 11BD; # (뇢; 뇢; 뇢; 뇢; 뇢; ) HANGUL SYLLABLE NOEJ
+B1E3;B1E3;1102 116C 11BE;B1E3;1102 116C 11BE; # (뇣; 뇣; 뇣; 뇣; 뇣; ) HANGUL SYLLABLE NOEC
+B1E4;B1E4;1102 116C 11BF;B1E4;1102 116C 11BF; # (뇤; 뇤; 뇤; 뇤; 뇤; ) HANGUL SYLLABLE NOEK
+B1E5;B1E5;1102 116C 11C0;B1E5;1102 116C 11C0; # (뇥; 뇥; 뇥; 뇥; 뇥; ) HANGUL SYLLABLE NOET
+B1E6;B1E6;1102 116C 11C1;B1E6;1102 116C 11C1; # (뇦; 뇦; 뇦; 뇦; 뇦; ) HANGUL SYLLABLE NOEP
+B1E7;B1E7;1102 116C 11C2;B1E7;1102 116C 11C2; # (뇧; 뇧; 뇧; 뇧; 뇧; ) HANGUL SYLLABLE NOEH
+B1E8;B1E8;1102 116D;B1E8;1102 116D; # (뇨; 뇨; 뇨; 뇨; 뇨; ) HANGUL SYLLABLE NYO
+B1E9;B1E9;1102 116D 11A8;B1E9;1102 116D 11A8; # (뇩; 뇩; 뇩; 뇩; 뇩; ) HANGUL SYLLABLE NYOG
+B1EA;B1EA;1102 116D 11A9;B1EA;1102 116D 11A9; # (뇪; 뇪; 뇪; 뇪; 뇪; ) HANGUL SYLLABLE NYOGG
+B1EB;B1EB;1102 116D 11AA;B1EB;1102 116D 11AA; # (뇫; 뇫; 뇫; 뇫; 뇫; ) HANGUL SYLLABLE NYOGS
+B1EC;B1EC;1102 116D 11AB;B1EC;1102 116D 11AB; # (뇬; 뇬; 뇬; 뇬; 뇬; ) HANGUL SYLLABLE NYON
+B1ED;B1ED;1102 116D 11AC;B1ED;1102 116D 11AC; # (뇭; 뇭; 뇭; 뇭; 뇭; ) HANGUL SYLLABLE NYONJ
+B1EE;B1EE;1102 116D 11AD;B1EE;1102 116D 11AD; # (뇮; 뇮; 뇮; 뇮; 뇮; ) HANGUL SYLLABLE NYONH
+B1EF;B1EF;1102 116D 11AE;B1EF;1102 116D 11AE; # (뇯; 뇯; 뇯; 뇯; 뇯; ) HANGUL SYLLABLE NYOD
+B1F0;B1F0;1102 116D 11AF;B1F0;1102 116D 11AF; # (뇰; 뇰; 뇰; 뇰; 뇰; ) HANGUL SYLLABLE NYOL
+B1F1;B1F1;1102 116D 11B0;B1F1;1102 116D 11B0; # (뇱; 뇱; 뇱; 뇱; 뇱; ) HANGUL SYLLABLE NYOLG
+B1F2;B1F2;1102 116D 11B1;B1F2;1102 116D 11B1; # (뇲; 뇲; 뇲; 뇲; 뇲; ) HANGUL SYLLABLE NYOLM
+B1F3;B1F3;1102 116D 11B2;B1F3;1102 116D 11B2; # (뇳; 뇳; 뇳; 뇳; 뇳; ) HANGUL SYLLABLE NYOLB
+B1F4;B1F4;1102 116D 11B3;B1F4;1102 116D 11B3; # (뇴; 뇴; 뇴; 뇴; 뇴; ) HANGUL SYLLABLE NYOLS
+B1F5;B1F5;1102 116D 11B4;B1F5;1102 116D 11B4; # (뇵; 뇵; 뇵; 뇵; 뇵; ) HANGUL SYLLABLE NYOLT
+B1F6;B1F6;1102 116D 11B5;B1F6;1102 116D 11B5; # (뇶; 뇶; 뇶; 뇶; 뇶; ) HANGUL SYLLABLE NYOLP
+B1F7;B1F7;1102 116D 11B6;B1F7;1102 116D 11B6; # (뇷; 뇷; 뇷; 뇷; 뇷; ) HANGUL SYLLABLE NYOLH
+B1F8;B1F8;1102 116D 11B7;B1F8;1102 116D 11B7; # (뇸; 뇸; 뇸; 뇸; 뇸; ) HANGUL SYLLABLE NYOM
+B1F9;B1F9;1102 116D 11B8;B1F9;1102 116D 11B8; # (뇹; 뇹; 뇹; 뇹; 뇹; ) HANGUL SYLLABLE NYOB
+B1FA;B1FA;1102 116D 11B9;B1FA;1102 116D 11B9; # (뇺; 뇺; 뇺; 뇺; 뇺; ) HANGUL SYLLABLE NYOBS
+B1FB;B1FB;1102 116D 11BA;B1FB;1102 116D 11BA; # (뇻; 뇻; 뇻; 뇻; 뇻; ) HANGUL SYLLABLE NYOS
+B1FC;B1FC;1102 116D 11BB;B1FC;1102 116D 11BB; # (뇼; 뇼; 뇼; 뇼; 뇼; ) HANGUL SYLLABLE NYOSS
+B1FD;B1FD;1102 116D 11BC;B1FD;1102 116D 11BC; # (뇽; 뇽; 뇽; 뇽; 뇽; ) HANGUL SYLLABLE NYONG
+B1FE;B1FE;1102 116D 11BD;B1FE;1102 116D 11BD; # (뇾; 뇾; 뇾; 뇾; 뇾; ) HANGUL SYLLABLE NYOJ
+B1FF;B1FF;1102 116D 11BE;B1FF;1102 116D 11BE; # (뇿; 뇿; 뇿; 뇿; 뇿; ) HANGUL SYLLABLE NYOC
+B200;B200;1102 116D 11BF;B200;1102 116D 11BF; # (눀; 눀; 눀; 눀; 눀; ) HANGUL SYLLABLE NYOK
+B201;B201;1102 116D 11C0;B201;1102 116D 11C0; # (눁; 눁; 눁; 눁; 눁; ) HANGUL SYLLABLE NYOT
+B202;B202;1102 116D 11C1;B202;1102 116D 11C1; # (눂; 눂; 눂; 눂; 눂; ) HANGUL SYLLABLE NYOP
+B203;B203;1102 116D 11C2;B203;1102 116D 11C2; # (눃; 눃; 눃; 눃; 눃; ) HANGUL SYLLABLE NYOH
+B204;B204;1102 116E;B204;1102 116E; # (누; 누; 누; 누; 누; ) HANGUL SYLLABLE NU
+B205;B205;1102 116E 11A8;B205;1102 116E 11A8; # (눅; 눅; 눅; 눅; 눅; ) HANGUL SYLLABLE NUG
+B206;B206;1102 116E 11A9;B206;1102 116E 11A9; # (눆; 눆; 눆; 눆; 눆; ) HANGUL SYLLABLE NUGG
+B207;B207;1102 116E 11AA;B207;1102 116E 11AA; # (눇; 눇; 눇; 눇; 눇; ) HANGUL SYLLABLE NUGS
+B208;B208;1102 116E 11AB;B208;1102 116E 11AB; # (눈; 눈; 눈; 눈; 눈; ) HANGUL SYLLABLE NUN
+B209;B209;1102 116E 11AC;B209;1102 116E 11AC; # (눉; 눉; 눉; 눉; 눉; ) HANGUL SYLLABLE NUNJ
+B20A;B20A;1102 116E 11AD;B20A;1102 116E 11AD; # (눊; 눊; 눊; 눊; 눊; ) HANGUL SYLLABLE NUNH
+B20B;B20B;1102 116E 11AE;B20B;1102 116E 11AE; # (눋; 눋; 눋; 눋; 눋; ) HANGUL SYLLABLE NUD
+B20C;B20C;1102 116E 11AF;B20C;1102 116E 11AF; # (눌; 눌; 눌; 눌; 눌; ) HANGUL SYLLABLE NUL
+B20D;B20D;1102 116E 11B0;B20D;1102 116E 11B0; # (눍; 눍; 눍; 눍; 눍; ) HANGUL SYLLABLE NULG
+B20E;B20E;1102 116E 11B1;B20E;1102 116E 11B1; # (눎; 눎; 눎; 눎; 눎; ) HANGUL SYLLABLE NULM
+B20F;B20F;1102 116E 11B2;B20F;1102 116E 11B2; # (눏; 눏; 눏; 눏; 눏; ) HANGUL SYLLABLE NULB
+B210;B210;1102 116E 11B3;B210;1102 116E 11B3; # (눐; 눐; 눐; 눐; 눐; ) HANGUL SYLLABLE NULS
+B211;B211;1102 116E 11B4;B211;1102 116E 11B4; # (눑; 눑; 눑; 눑; 눑; ) HANGUL SYLLABLE NULT
+B212;B212;1102 116E 11B5;B212;1102 116E 11B5; # (눒; 눒; 눒; 눒; 눒; ) HANGUL SYLLABLE NULP
+B213;B213;1102 116E 11B6;B213;1102 116E 11B6; # (눓; 눓; 눓; 눓; 눓; ) HANGUL SYLLABLE NULH
+B214;B214;1102 116E 11B7;B214;1102 116E 11B7; # (눔; 눔; 눔; 눔; 눔; ) HANGUL SYLLABLE NUM
+B215;B215;1102 116E 11B8;B215;1102 116E 11B8; # (눕; 눕; 눕; 눕; 눕; ) HANGUL SYLLABLE NUB
+B216;B216;1102 116E 11B9;B216;1102 116E 11B9; # (눖; 눖; 눖; 눖; 눖; ) HANGUL SYLLABLE NUBS
+B217;B217;1102 116E 11BA;B217;1102 116E 11BA; # (눗; 눗; 눗; 눗; 눗; ) HANGUL SYLLABLE NUS
+B218;B218;1102 116E 11BB;B218;1102 116E 11BB; # (눘; 눘; 눘; 눘; 눘; ) HANGUL SYLLABLE NUSS
+B219;B219;1102 116E 11BC;B219;1102 116E 11BC; # (눙; 눙; 눙; 눙; 눙; ) HANGUL SYLLABLE NUNG
+B21A;B21A;1102 116E 11BD;B21A;1102 116E 11BD; # (눚; 눚; 눚; 눚; 눚; ) HANGUL SYLLABLE NUJ
+B21B;B21B;1102 116E 11BE;B21B;1102 116E 11BE; # (눛; 눛; 눛; 눛; 눛; ) HANGUL SYLLABLE NUC
+B21C;B21C;1102 116E 11BF;B21C;1102 116E 11BF; # (눜; 눜; 눜; 눜; 눜; ) HANGUL SYLLABLE NUK
+B21D;B21D;1102 116E 11C0;B21D;1102 116E 11C0; # (눝; 눝; 눝; 눝; 눝; ) HANGUL SYLLABLE NUT
+B21E;B21E;1102 116E 11C1;B21E;1102 116E 11C1; # (눞; 눞; 눞; 눞; 눞; ) HANGUL SYLLABLE NUP
+B21F;B21F;1102 116E 11C2;B21F;1102 116E 11C2; # (눟; 눟; 눟; 눟; 눟; ) HANGUL SYLLABLE NUH
+B220;B220;1102 116F;B220;1102 116F; # (눠; 눠; 눠; 눠; 눠; ) HANGUL SYLLABLE NWEO
+B221;B221;1102 116F 11A8;B221;1102 116F 11A8; # (눡; 눡; 눡; 눡; 눡; ) HANGUL SYLLABLE NWEOG
+B222;B222;1102 116F 11A9;B222;1102 116F 11A9; # (눢; 눢; 눢; 눢; 눢; ) HANGUL SYLLABLE NWEOGG
+B223;B223;1102 116F 11AA;B223;1102 116F 11AA; # (눣; 눣; 눣; 눣; 눣; ) HANGUL SYLLABLE NWEOGS
+B224;B224;1102 116F 11AB;B224;1102 116F 11AB; # (눤; 눤; 눤; 눤; 눤; ) HANGUL SYLLABLE NWEON
+B225;B225;1102 116F 11AC;B225;1102 116F 11AC; # (눥; 눥; 눥; 눥; 눥; ) HANGUL SYLLABLE NWEONJ
+B226;B226;1102 116F 11AD;B226;1102 116F 11AD; # (눦; 눦; 눦; 눦; 눦; ) HANGUL SYLLABLE NWEONH
+B227;B227;1102 116F 11AE;B227;1102 116F 11AE; # (눧; 눧; 눧; 눧; 눧; ) HANGUL SYLLABLE NWEOD
+B228;B228;1102 116F 11AF;B228;1102 116F 11AF; # (눨; 눨; 눨; 눨; 눨; ) HANGUL SYLLABLE NWEOL
+B229;B229;1102 116F 11B0;B229;1102 116F 11B0; # (눩; 눩; 눩; 눩; 눩; ) HANGUL SYLLABLE NWEOLG
+B22A;B22A;1102 116F 11B1;B22A;1102 116F 11B1; # (눪; 눪; 눪; 눪; 눪; ) HANGUL SYLLABLE NWEOLM
+B22B;B22B;1102 116F 11B2;B22B;1102 116F 11B2; # (눫; 눫; 눫; 눫; 눫; ) HANGUL SYLLABLE NWEOLB
+B22C;B22C;1102 116F 11B3;B22C;1102 116F 11B3; # (눬; 눬; 눬; 눬; 눬; ) HANGUL SYLLABLE NWEOLS
+B22D;B22D;1102 116F 11B4;B22D;1102 116F 11B4; # (눭; 눭; 눭; 눭; 눭; ) HANGUL SYLLABLE NWEOLT
+B22E;B22E;1102 116F 11B5;B22E;1102 116F 11B5; # (눮; 눮; 눮; 눮; 눮; ) HANGUL SYLLABLE NWEOLP
+B22F;B22F;1102 116F 11B6;B22F;1102 116F 11B6; # (눯; 눯; 눯; 눯; 눯; ) HANGUL SYLLABLE NWEOLH
+B230;B230;1102 116F 11B7;B230;1102 116F 11B7; # (눰; 눰; 눰; 눰; 눰; ) HANGUL SYLLABLE NWEOM
+B231;B231;1102 116F 11B8;B231;1102 116F 11B8; # (눱; 눱; 눱; 눱; 눱; ) HANGUL SYLLABLE NWEOB
+B232;B232;1102 116F 11B9;B232;1102 116F 11B9; # (눲; 눲; 눲; 눲; 눲; ) HANGUL SYLLABLE NWEOBS
+B233;B233;1102 116F 11BA;B233;1102 116F 11BA; # (눳; 눳; 눳; 눳; 눳; ) HANGUL SYLLABLE NWEOS
+B234;B234;1102 116F 11BB;B234;1102 116F 11BB; # (눴; 눴; 눴; 눴; 눴; ) HANGUL SYLLABLE NWEOSS
+B235;B235;1102 116F 11BC;B235;1102 116F 11BC; # (눵; 눵; 눵; 눵; 눵; ) HANGUL SYLLABLE NWEONG
+B236;B236;1102 116F 11BD;B236;1102 116F 11BD; # (눶; 눶; 눶; 눶; 눶; ) HANGUL SYLLABLE NWEOJ
+B237;B237;1102 116F 11BE;B237;1102 116F 11BE; # (눷; 눷; 눷; 눷; 눷; ) HANGUL SYLLABLE NWEOC
+B238;B238;1102 116F 11BF;B238;1102 116F 11BF; # (눸; 눸; 눸; 눸; 눸; ) HANGUL SYLLABLE NWEOK
+B239;B239;1102 116F 11C0;B239;1102 116F 11C0; # (눹; 눹; 눹; 눹; 눹; ) HANGUL SYLLABLE NWEOT
+B23A;B23A;1102 116F 11C1;B23A;1102 116F 11C1; # (눺; 눺; 눺; 눺; 눺; ) HANGUL SYLLABLE NWEOP
+B23B;B23B;1102 116F 11C2;B23B;1102 116F 11C2; # (눻; 눻; 눻; 눻; 눻; ) HANGUL SYLLABLE NWEOH
+B23C;B23C;1102 1170;B23C;1102 1170; # (눼; 눼; 눼; 눼; 눼; ) HANGUL SYLLABLE NWE
+B23D;B23D;1102 1170 11A8;B23D;1102 1170 11A8; # (눽; 눽; 눽; 눽; 눽; ) HANGUL SYLLABLE NWEG
+B23E;B23E;1102 1170 11A9;B23E;1102 1170 11A9; # (눾; 눾; 눾; 눾; 눾; ) HANGUL SYLLABLE NWEGG
+B23F;B23F;1102 1170 11AA;B23F;1102 1170 11AA; # (눿; 눿; 눿; 눿; 눿; ) HANGUL SYLLABLE NWEGS
+B240;B240;1102 1170 11AB;B240;1102 1170 11AB; # (뉀; 뉀; 뉀; 뉀; 뉀; ) HANGUL SYLLABLE NWEN
+B241;B241;1102 1170 11AC;B241;1102 1170 11AC; # (뉁; 뉁; 뉁; 뉁; 뉁; ) HANGUL SYLLABLE NWENJ
+B242;B242;1102 1170 11AD;B242;1102 1170 11AD; # (뉂; 뉂; 뉂; 뉂; 뉂; ) HANGUL SYLLABLE NWENH
+B243;B243;1102 1170 11AE;B243;1102 1170 11AE; # (뉃; 뉃; 뉃; 뉃; 뉃; ) HANGUL SYLLABLE NWED
+B244;B244;1102 1170 11AF;B244;1102 1170 11AF; # (뉄; 뉄; 뉄; 뉄; 뉄; ) HANGUL SYLLABLE NWEL
+B245;B245;1102 1170 11B0;B245;1102 1170 11B0; # (뉅; 뉅; 뉅; 뉅; 뉅; ) HANGUL SYLLABLE NWELG
+B246;B246;1102 1170 11B1;B246;1102 1170 11B1; # (뉆; 뉆; 뉆; 뉆; 뉆; ) HANGUL SYLLABLE NWELM
+B247;B247;1102 1170 11B2;B247;1102 1170 11B2; # (뉇; 뉇; 뉇; 뉇; 뉇; ) HANGUL SYLLABLE NWELB
+B248;B248;1102 1170 11B3;B248;1102 1170 11B3; # (뉈; 뉈; 뉈; 뉈; 뉈; ) HANGUL SYLLABLE NWELS
+B249;B249;1102 1170 11B4;B249;1102 1170 11B4; # (뉉; 뉉; 뉉; 뉉; 뉉; ) HANGUL SYLLABLE NWELT
+B24A;B24A;1102 1170 11B5;B24A;1102 1170 11B5; # (뉊; 뉊; 뉊; 뉊; 뉊; ) HANGUL SYLLABLE NWELP
+B24B;B24B;1102 1170 11B6;B24B;1102 1170 11B6; # (뉋; 뉋; 뉋; 뉋; 뉋; ) HANGUL SYLLABLE NWELH
+B24C;B24C;1102 1170 11B7;B24C;1102 1170 11B7; # (뉌; 뉌; 뉌; 뉌; 뉌; ) HANGUL SYLLABLE NWEM
+B24D;B24D;1102 1170 11B8;B24D;1102 1170 11B8; # (뉍; 뉍; 뉍; 뉍; 뉍; ) HANGUL SYLLABLE NWEB
+B24E;B24E;1102 1170 11B9;B24E;1102 1170 11B9; # (뉎; 뉎; 뉎; 뉎; 뉎; ) HANGUL SYLLABLE NWEBS
+B24F;B24F;1102 1170 11BA;B24F;1102 1170 11BA; # (뉏; 뉏; 뉏; 뉏; 뉏; ) HANGUL SYLLABLE NWES
+B250;B250;1102 1170 11BB;B250;1102 1170 11BB; # (뉐; 뉐; 뉐; 뉐; 뉐; ) HANGUL SYLLABLE NWESS
+B251;B251;1102 1170 11BC;B251;1102 1170 11BC; # (뉑; 뉑; 뉑; 뉑; 뉑; ) HANGUL SYLLABLE NWENG
+B252;B252;1102 1170 11BD;B252;1102 1170 11BD; # (뉒; 뉒; 뉒; 뉒; 뉒; ) HANGUL SYLLABLE NWEJ
+B253;B253;1102 1170 11BE;B253;1102 1170 11BE; # (뉓; 뉓; 뉓; 뉓; 뉓; ) HANGUL SYLLABLE NWEC
+B254;B254;1102 1170 11BF;B254;1102 1170 11BF; # (뉔; 뉔; 뉔; 뉔; 뉔; ) HANGUL SYLLABLE NWEK
+B255;B255;1102 1170 11C0;B255;1102 1170 11C0; # (뉕; 뉕; 뉕; 뉕; 뉕; ) HANGUL SYLLABLE NWET
+B256;B256;1102 1170 11C1;B256;1102 1170 11C1; # (뉖; 뉖; 뉖; 뉖; 뉖; ) HANGUL SYLLABLE NWEP
+B257;B257;1102 1170 11C2;B257;1102 1170 11C2; # (뉗; 뉗; 뉗; 뉗; 뉗; ) HANGUL SYLLABLE NWEH
+B258;B258;1102 1171;B258;1102 1171; # (뉘; 뉘; 뉘; 뉘; 뉘; ) HANGUL SYLLABLE NWI
+B259;B259;1102 1171 11A8;B259;1102 1171 11A8; # (뉙; 뉙; 뉙; 뉙; 뉙; ) HANGUL SYLLABLE NWIG
+B25A;B25A;1102 1171 11A9;B25A;1102 1171 11A9; # (뉚; 뉚; 뉚; 뉚; 뉚; ) HANGUL SYLLABLE NWIGG
+B25B;B25B;1102 1171 11AA;B25B;1102 1171 11AA; # (뉛; 뉛; 뉛; 뉛; 뉛; ) HANGUL SYLLABLE NWIGS
+B25C;B25C;1102 1171 11AB;B25C;1102 1171 11AB; # (뉜; 뉜; 뉜; 뉜; 뉜; ) HANGUL SYLLABLE NWIN
+B25D;B25D;1102 1171 11AC;B25D;1102 1171 11AC; # (뉝; 뉝; 뉝; 뉝; 뉝; ) HANGUL SYLLABLE NWINJ
+B25E;B25E;1102 1171 11AD;B25E;1102 1171 11AD; # (뉞; 뉞; 뉞; 뉞; 뉞; ) HANGUL SYLLABLE NWINH
+B25F;B25F;1102 1171 11AE;B25F;1102 1171 11AE; # (뉟; 뉟; 뉟; 뉟; 뉟; ) HANGUL SYLLABLE NWID
+B260;B260;1102 1171 11AF;B260;1102 1171 11AF; # (뉠; 뉠; 뉠; 뉠; 뉠; ) HANGUL SYLLABLE NWIL
+B261;B261;1102 1171 11B0;B261;1102 1171 11B0; # (뉡; 뉡; 뉡; 뉡; 뉡; ) HANGUL SYLLABLE NWILG
+B262;B262;1102 1171 11B1;B262;1102 1171 11B1; # (뉢; 뉢; 뉢; 뉢; 뉢; ) HANGUL SYLLABLE NWILM
+B263;B263;1102 1171 11B2;B263;1102 1171 11B2; # (뉣; 뉣; 뉣; 뉣; 뉣; ) HANGUL SYLLABLE NWILB
+B264;B264;1102 1171 11B3;B264;1102 1171 11B3; # (뉤; 뉤; 뉤; 뉤; 뉤; ) HANGUL SYLLABLE NWILS
+B265;B265;1102 1171 11B4;B265;1102 1171 11B4; # (뉥; 뉥; 뉥; 뉥; 뉥; ) HANGUL SYLLABLE NWILT
+B266;B266;1102 1171 11B5;B266;1102 1171 11B5; # (뉦; 뉦; 뉦; 뉦; 뉦; ) HANGUL SYLLABLE NWILP
+B267;B267;1102 1171 11B6;B267;1102 1171 11B6; # (뉧; 뉧; 뉧; 뉧; 뉧; ) HANGUL SYLLABLE NWILH
+B268;B268;1102 1171 11B7;B268;1102 1171 11B7; # (뉨; 뉨; 뉨; 뉨; 뉨; ) HANGUL SYLLABLE NWIM
+B269;B269;1102 1171 11B8;B269;1102 1171 11B8; # (뉩; 뉩; 뉩; 뉩; 뉩; ) HANGUL SYLLABLE NWIB
+B26A;B26A;1102 1171 11B9;B26A;1102 1171 11B9; # (뉪; 뉪; 뉪; 뉪; 뉪; ) HANGUL SYLLABLE NWIBS
+B26B;B26B;1102 1171 11BA;B26B;1102 1171 11BA; # (뉫; 뉫; 뉫; 뉫; 뉫; ) HANGUL SYLLABLE NWIS
+B26C;B26C;1102 1171 11BB;B26C;1102 1171 11BB; # (뉬; 뉬; 뉬; 뉬; 뉬; ) HANGUL SYLLABLE NWISS
+B26D;B26D;1102 1171 11BC;B26D;1102 1171 11BC; # (뉭; 뉭; 뉭; 뉭; 뉭; ) HANGUL SYLLABLE NWING
+B26E;B26E;1102 1171 11BD;B26E;1102 1171 11BD; # (뉮; 뉮; 뉮; 뉮; 뉮; ) HANGUL SYLLABLE NWIJ
+B26F;B26F;1102 1171 11BE;B26F;1102 1171 11BE; # (뉯; 뉯; 뉯; 뉯; 뉯; ) HANGUL SYLLABLE NWIC
+B270;B270;1102 1171 11BF;B270;1102 1171 11BF; # (뉰; 뉰; 뉰; 뉰; 뉰; ) HANGUL SYLLABLE NWIK
+B271;B271;1102 1171 11C0;B271;1102 1171 11C0; # (뉱; 뉱; 뉱; 뉱; 뉱; ) HANGUL SYLLABLE NWIT
+B272;B272;1102 1171 11C1;B272;1102 1171 11C1; # (뉲; 뉲; 뉲; 뉲; 뉲; ) HANGUL SYLLABLE NWIP
+B273;B273;1102 1171 11C2;B273;1102 1171 11C2; # (뉳; 뉳; 뉳; 뉳; 뉳; ) HANGUL SYLLABLE NWIH
+B274;B274;1102 1172;B274;1102 1172; # (뉴; 뉴; 뉴; 뉴; 뉴; ) HANGUL SYLLABLE NYU
+B275;B275;1102 1172 11A8;B275;1102 1172 11A8; # (뉵; 뉵; 뉵; 뉵; 뉵; ) HANGUL SYLLABLE NYUG
+B276;B276;1102 1172 11A9;B276;1102 1172 11A9; # (뉶; 뉶; 뉶; 뉶; 뉶; ) HANGUL SYLLABLE NYUGG
+B277;B277;1102 1172 11AA;B277;1102 1172 11AA; # (뉷; 뉷; 뉷; 뉷; 뉷; ) HANGUL SYLLABLE NYUGS
+B278;B278;1102 1172 11AB;B278;1102 1172 11AB; # (뉸; 뉸; 뉸; 뉸; 뉸; ) HANGUL SYLLABLE NYUN
+B279;B279;1102 1172 11AC;B279;1102 1172 11AC; # (뉹; 뉹; 뉹; 뉹; 뉹; ) HANGUL SYLLABLE NYUNJ
+B27A;B27A;1102 1172 11AD;B27A;1102 1172 11AD; # (뉺; 뉺; 뉺; 뉺; 뉺; ) HANGUL SYLLABLE NYUNH
+B27B;B27B;1102 1172 11AE;B27B;1102 1172 11AE; # (뉻; 뉻; 뉻; 뉻; 뉻; ) HANGUL SYLLABLE NYUD
+B27C;B27C;1102 1172 11AF;B27C;1102 1172 11AF; # (뉼; 뉼; 뉼; 뉼; 뉼; ) HANGUL SYLLABLE NYUL
+B27D;B27D;1102 1172 11B0;B27D;1102 1172 11B0; # (뉽; 뉽; 뉽; 뉽; 뉽; ) HANGUL SYLLABLE NYULG
+B27E;B27E;1102 1172 11B1;B27E;1102 1172 11B1; # (뉾; 뉾; 뉾; 뉾; 뉾; ) HANGUL SYLLABLE NYULM
+B27F;B27F;1102 1172 11B2;B27F;1102 1172 11B2; # (뉿; 뉿; 뉿; 뉿; 뉿; ) HANGUL SYLLABLE NYULB
+B280;B280;1102 1172 11B3;B280;1102 1172 11B3; # (늀; 늀; 늀; 늀; 늀; ) HANGUL SYLLABLE NYULS
+B281;B281;1102 1172 11B4;B281;1102 1172 11B4; # (늁; 늁; 늁; 늁; 늁; ) HANGUL SYLLABLE NYULT
+B282;B282;1102 1172 11B5;B282;1102 1172 11B5; # (늂; 늂; 늂; 늂; 늂; ) HANGUL SYLLABLE NYULP
+B283;B283;1102 1172 11B6;B283;1102 1172 11B6; # (늃; 늃; 늃; 늃; 늃; ) HANGUL SYLLABLE NYULH
+B284;B284;1102 1172 11B7;B284;1102 1172 11B7; # (늄; 늄; 늄; 늄; 늄; ) HANGUL SYLLABLE NYUM
+B285;B285;1102 1172 11B8;B285;1102 1172 11B8; # (늅; 늅; 늅; 늅; 늅; ) HANGUL SYLLABLE NYUB
+B286;B286;1102 1172 11B9;B286;1102 1172 11B9; # (늆; 늆; 늆; 늆; 늆; ) HANGUL SYLLABLE NYUBS
+B287;B287;1102 1172 11BA;B287;1102 1172 11BA; # (늇; 늇; 늇; 늇; 늇; ) HANGUL SYLLABLE NYUS
+B288;B288;1102 1172 11BB;B288;1102 1172 11BB; # (늈; 늈; 늈; 늈; 늈; ) HANGUL SYLLABLE NYUSS
+B289;B289;1102 1172 11BC;B289;1102 1172 11BC; # (늉; 늉; 늉; 늉; 늉; ) HANGUL SYLLABLE NYUNG
+B28A;B28A;1102 1172 11BD;B28A;1102 1172 11BD; # (늊; 늊; 늊; 늊; 늊; ) HANGUL SYLLABLE NYUJ
+B28B;B28B;1102 1172 11BE;B28B;1102 1172 11BE; # (늋; 늋; 늋; 늋; 늋; ) HANGUL SYLLABLE NYUC
+B28C;B28C;1102 1172 11BF;B28C;1102 1172 11BF; # (늌; 늌; 늌; 늌; 늌; ) HANGUL SYLLABLE NYUK
+B28D;B28D;1102 1172 11C0;B28D;1102 1172 11C0; # (늍; 늍; 늍; 늍; 늍; ) HANGUL SYLLABLE NYUT
+B28E;B28E;1102 1172 11C1;B28E;1102 1172 11C1; # (늎; 늎; 늎; 늎; 늎; ) HANGUL SYLLABLE NYUP
+B28F;B28F;1102 1172 11C2;B28F;1102 1172 11C2; # (늏; 늏; 늏; 늏; 늏; ) HANGUL SYLLABLE NYUH
+B290;B290;1102 1173;B290;1102 1173; # (느; 느; 느; 느; 느; ) HANGUL SYLLABLE NEU
+B291;B291;1102 1173 11A8;B291;1102 1173 11A8; # (늑; 늑; 늑; 늑; 늑; ) HANGUL SYLLABLE NEUG
+B292;B292;1102 1173 11A9;B292;1102 1173 11A9; # (늒; 늒; 늒; 늒; 늒; ) HANGUL SYLLABLE NEUGG
+B293;B293;1102 1173 11AA;B293;1102 1173 11AA; # (늓; 늓; 늓; 늓; 늓; ) HANGUL SYLLABLE NEUGS
+B294;B294;1102 1173 11AB;B294;1102 1173 11AB; # (는; 는; 는; 는; 는; ) HANGUL SYLLABLE NEUN
+B295;B295;1102 1173 11AC;B295;1102 1173 11AC; # (늕; 늕; 늕; 늕; 늕; ) HANGUL SYLLABLE NEUNJ
+B296;B296;1102 1173 11AD;B296;1102 1173 11AD; # (늖; 늖; 늖; 늖; 늖; ) HANGUL SYLLABLE NEUNH
+B297;B297;1102 1173 11AE;B297;1102 1173 11AE; # (늗; 늗; 늗; 늗; 늗; ) HANGUL SYLLABLE NEUD
+B298;B298;1102 1173 11AF;B298;1102 1173 11AF; # (늘; 늘; 늘; 늘; 늘; ) HANGUL SYLLABLE NEUL
+B299;B299;1102 1173 11B0;B299;1102 1173 11B0; # (늙; 늙; 늙; 늙; 늙; ) HANGUL SYLLABLE NEULG
+B29A;B29A;1102 1173 11B1;B29A;1102 1173 11B1; # (늚; 늚; 늚; 늚; 늚; ) HANGUL SYLLABLE NEULM
+B29B;B29B;1102 1173 11B2;B29B;1102 1173 11B2; # (늛; 늛; 늛; 늛; 늛; ) HANGUL SYLLABLE NEULB
+B29C;B29C;1102 1173 11B3;B29C;1102 1173 11B3; # (늜; 늜; 늜; 늜; 늜; ) HANGUL SYLLABLE NEULS
+B29D;B29D;1102 1173 11B4;B29D;1102 1173 11B4; # (늝; 늝; 늝; 늝; 늝; ) HANGUL SYLLABLE NEULT
+B29E;B29E;1102 1173 11B5;B29E;1102 1173 11B5; # (늞; 늞; 늞; 늞; 늞; ) HANGUL SYLLABLE NEULP
+B29F;B29F;1102 1173 11B6;B29F;1102 1173 11B6; # (늟; 늟; 늟; 늟; 늟; ) HANGUL SYLLABLE NEULH
+B2A0;B2A0;1102 1173 11B7;B2A0;1102 1173 11B7; # (늠; 늠; 늠; 늠; 늠; ) HANGUL SYLLABLE NEUM
+B2A1;B2A1;1102 1173 11B8;B2A1;1102 1173 11B8; # (늡; 늡; 늡; 늡; 늡; ) HANGUL SYLLABLE NEUB
+B2A2;B2A2;1102 1173 11B9;B2A2;1102 1173 11B9; # (늢; 늢; 늢; 늢; 늢; ) HANGUL SYLLABLE NEUBS
+B2A3;B2A3;1102 1173 11BA;B2A3;1102 1173 11BA; # (늣; 늣; 늣; 늣; 늣; ) HANGUL SYLLABLE NEUS
+B2A4;B2A4;1102 1173 11BB;B2A4;1102 1173 11BB; # (늤; 늤; 늤; 늤; 늤; ) HANGUL SYLLABLE NEUSS
+B2A5;B2A5;1102 1173 11BC;B2A5;1102 1173 11BC; # (능; 능; 능; 능; 능; ) HANGUL SYLLABLE NEUNG
+B2A6;B2A6;1102 1173 11BD;B2A6;1102 1173 11BD; # (늦; 늦; 늦; 늦; 늦; ) HANGUL SYLLABLE NEUJ
+B2A7;B2A7;1102 1173 11BE;B2A7;1102 1173 11BE; # (늧; 늧; 늧; 늧; 늧; ) HANGUL SYLLABLE NEUC
+B2A8;B2A8;1102 1173 11BF;B2A8;1102 1173 11BF; # (늨; 늨; 늨; 늨; 늨; ) HANGUL SYLLABLE NEUK
+B2A9;B2A9;1102 1173 11C0;B2A9;1102 1173 11C0; # (늩; 늩; 늩; 늩; 늩; ) HANGUL SYLLABLE NEUT
+B2AA;B2AA;1102 1173 11C1;B2AA;1102 1173 11C1; # (늪; 늪; 늪; 늪; 늪; ) HANGUL SYLLABLE NEUP
+B2AB;B2AB;1102 1173 11C2;B2AB;1102 1173 11C2; # (늫; 늫; 늫; 늫; 늫; ) HANGUL SYLLABLE NEUH
+B2AC;B2AC;1102 1174;B2AC;1102 1174; # (늬; 늬; 늬; 늬; 늬; ) HANGUL SYLLABLE NYI
+B2AD;B2AD;1102 1174 11A8;B2AD;1102 1174 11A8; # (늭; 늭; 늭; 늭; 늭; ) HANGUL SYLLABLE NYIG
+B2AE;B2AE;1102 1174 11A9;B2AE;1102 1174 11A9; # (늮; 늮; 늮; 늮; 늮; ) HANGUL SYLLABLE NYIGG
+B2AF;B2AF;1102 1174 11AA;B2AF;1102 1174 11AA; # (늯; 늯; 늯; 늯; 늯; ) HANGUL SYLLABLE NYIGS
+B2B0;B2B0;1102 1174 11AB;B2B0;1102 1174 11AB; # (늰; 늰; 늰; 늰; 늰; ) HANGUL SYLLABLE NYIN
+B2B1;B2B1;1102 1174 11AC;B2B1;1102 1174 11AC; # (늱; 늱; 늱; 늱; 늱; ) HANGUL SYLLABLE NYINJ
+B2B2;B2B2;1102 1174 11AD;B2B2;1102 1174 11AD; # (늲; 늲; 늲; 늲; 늲; ) HANGUL SYLLABLE NYINH
+B2B3;B2B3;1102 1174 11AE;B2B3;1102 1174 11AE; # (늳; 늳; 늳; 늳; 늳; ) HANGUL SYLLABLE NYID
+B2B4;B2B4;1102 1174 11AF;B2B4;1102 1174 11AF; # (늴; 늴; 늴; 늴; 늴; ) HANGUL SYLLABLE NYIL
+B2B5;B2B5;1102 1174 11B0;B2B5;1102 1174 11B0; # (늵; 늵; 늵; 늵; 늵; ) HANGUL SYLLABLE NYILG
+B2B6;B2B6;1102 1174 11B1;B2B6;1102 1174 11B1; # (늶; 늶; 늶; 늶; 늶; ) HANGUL SYLLABLE NYILM
+B2B7;B2B7;1102 1174 11B2;B2B7;1102 1174 11B2; # (늷; 늷; 늷; 늷; 늷; ) HANGUL SYLLABLE NYILB
+B2B8;B2B8;1102 1174 11B3;B2B8;1102 1174 11B3; # (늸; 늸; 늸; 늸; 늸; ) HANGUL SYLLABLE NYILS
+B2B9;B2B9;1102 1174 11B4;B2B9;1102 1174 11B4; # (늹; 늹; 늹; 늹; 늹; ) HANGUL SYLLABLE NYILT
+B2BA;B2BA;1102 1174 11B5;B2BA;1102 1174 11B5; # (늺; 늺; 늺; 늺; 늺; ) HANGUL SYLLABLE NYILP
+B2BB;B2BB;1102 1174 11B6;B2BB;1102 1174 11B6; # (늻; 늻; 늻; 늻; 늻; ) HANGUL SYLLABLE NYILH
+B2BC;B2BC;1102 1174 11B7;B2BC;1102 1174 11B7; # (늼; 늼; 늼; 늼; 늼; ) HANGUL SYLLABLE NYIM
+B2BD;B2BD;1102 1174 11B8;B2BD;1102 1174 11B8; # (늽; 늽; 늽; 늽; 늽; ) HANGUL SYLLABLE NYIB
+B2BE;B2BE;1102 1174 11B9;B2BE;1102 1174 11B9; # (늾; 늾; 늾; 늾; 늾; ) HANGUL SYLLABLE NYIBS
+B2BF;B2BF;1102 1174 11BA;B2BF;1102 1174 11BA; # (늿; 늿; 늿; 늿; 늿; ) HANGUL SYLLABLE NYIS
+B2C0;B2C0;1102 1174 11BB;B2C0;1102 1174 11BB; # (닀; 닀; 닀; 닀; 닀; ) HANGUL SYLLABLE NYISS
+B2C1;B2C1;1102 1174 11BC;B2C1;1102 1174 11BC; # (닁; 닁; 닁; 닁; 닁; ) HANGUL SYLLABLE NYING
+B2C2;B2C2;1102 1174 11BD;B2C2;1102 1174 11BD; # (닂; 닂; 닂; 닂; 닂; ) HANGUL SYLLABLE NYIJ
+B2C3;B2C3;1102 1174 11BE;B2C3;1102 1174 11BE; # (닃; 닃; 닃; 닃; 닃; ) HANGUL SYLLABLE NYIC
+B2C4;B2C4;1102 1174 11BF;B2C4;1102 1174 11BF; # (닄; 닄; 닄; 닄; 닄; ) HANGUL SYLLABLE NYIK
+B2C5;B2C5;1102 1174 11C0;B2C5;1102 1174 11C0; # (닅; 닅; 닅; 닅; 닅; ) HANGUL SYLLABLE NYIT
+B2C6;B2C6;1102 1174 11C1;B2C6;1102 1174 11C1; # (닆; 닆; 닆; 닆; 닆; ) HANGUL SYLLABLE NYIP
+B2C7;B2C7;1102 1174 11C2;B2C7;1102 1174 11C2; # (닇; 닇; 닇; 닇; 닇; ) HANGUL SYLLABLE NYIH
+B2C8;B2C8;1102 1175;B2C8;1102 1175; # (니; 니; 니; 니; 니; ) HANGUL SYLLABLE NI
+B2C9;B2C9;1102 1175 11A8;B2C9;1102 1175 11A8; # (닉; 닉; 닉; 닉; 닉; ) HANGUL SYLLABLE NIG
+B2CA;B2CA;1102 1175 11A9;B2CA;1102 1175 11A9; # (닊; 닊; 닊; 닊; 닊; ) HANGUL SYLLABLE NIGG
+B2CB;B2CB;1102 1175 11AA;B2CB;1102 1175 11AA; # (닋; 닋; 닋; 닋; 닋; ) HANGUL SYLLABLE NIGS
+B2CC;B2CC;1102 1175 11AB;B2CC;1102 1175 11AB; # (닌; 닌; 닌; 닌; 닌; ) HANGUL SYLLABLE NIN
+B2CD;B2CD;1102 1175 11AC;B2CD;1102 1175 11AC; # (닍; 닍; 닍; 닍; 닍; ) HANGUL SYLLABLE NINJ
+B2CE;B2CE;1102 1175 11AD;B2CE;1102 1175 11AD; # (닎; 닎; 닎; 닎; 닎; ) HANGUL SYLLABLE NINH
+B2CF;B2CF;1102 1175 11AE;B2CF;1102 1175 11AE; # (닏; 닏; 닏; 닏; 닏; ) HANGUL SYLLABLE NID
+B2D0;B2D0;1102 1175 11AF;B2D0;1102 1175 11AF; # (닐; 닐; 닐; 닐; 닐; ) HANGUL SYLLABLE NIL
+B2D1;B2D1;1102 1175 11B0;B2D1;1102 1175 11B0; # (닑; 닑; 닑; 닑; 닑; ) HANGUL SYLLABLE NILG
+B2D2;B2D2;1102 1175 11B1;B2D2;1102 1175 11B1; # (닒; 닒; 닒; 닒; 닒; ) HANGUL SYLLABLE NILM
+B2D3;B2D3;1102 1175 11B2;B2D3;1102 1175 11B2; # (닓; 닓; 닓; 닓; 닓; ) HANGUL SYLLABLE NILB
+B2D4;B2D4;1102 1175 11B3;B2D4;1102 1175 11B3; # (닔; 닔; 닔; 닔; 닔; ) HANGUL SYLLABLE NILS
+B2D5;B2D5;1102 1175 11B4;B2D5;1102 1175 11B4; # (닕; 닕; 닕; 닕; 닕; ) HANGUL SYLLABLE NILT
+B2D6;B2D6;1102 1175 11B5;B2D6;1102 1175 11B5; # (닖; 닖; 닖; 닖; 닖; ) HANGUL SYLLABLE NILP
+B2D7;B2D7;1102 1175 11B6;B2D7;1102 1175 11B6; # (닗; 닗; 닗; 닗; 닗; ) HANGUL SYLLABLE NILH
+B2D8;B2D8;1102 1175 11B7;B2D8;1102 1175 11B7; # (님; 님; 님; 님; 님; ) HANGUL SYLLABLE NIM
+B2D9;B2D9;1102 1175 11B8;B2D9;1102 1175 11B8; # (닙; 닙; 닙; 닙; 닙; ) HANGUL SYLLABLE NIB
+B2DA;B2DA;1102 1175 11B9;B2DA;1102 1175 11B9; # (닚; 닚; 닚; 닚; 닚; ) HANGUL SYLLABLE NIBS
+B2DB;B2DB;1102 1175 11BA;B2DB;1102 1175 11BA; # (닛; 닛; 닛; 닛; 닛; ) HANGUL SYLLABLE NIS
+B2DC;B2DC;1102 1175 11BB;B2DC;1102 1175 11BB; # (닜; 닜; 닜; 닜; 닜; ) HANGUL SYLLABLE NISS
+B2DD;B2DD;1102 1175 11BC;B2DD;1102 1175 11BC; # (닝; 닝; 닝; 닝; 닝; ) HANGUL SYLLABLE NING
+B2DE;B2DE;1102 1175 11BD;B2DE;1102 1175 11BD; # (닞; 닞; 닞; 닞; 닞; ) HANGUL SYLLABLE NIJ
+B2DF;B2DF;1102 1175 11BE;B2DF;1102 1175 11BE; # (닟; 닟; 닟; 닟; 닟; ) HANGUL SYLLABLE NIC
+B2E0;B2E0;1102 1175 11BF;B2E0;1102 1175 11BF; # (닠; 닠; 닠; 닠; 닠; ) HANGUL SYLLABLE NIK
+B2E1;B2E1;1102 1175 11C0;B2E1;1102 1175 11C0; # (닡; 닡; 닡; 닡; 닡; ) HANGUL SYLLABLE NIT
+B2E2;B2E2;1102 1175 11C1;B2E2;1102 1175 11C1; # (닢; 닢; 닢; 닢; 닢; ) HANGUL SYLLABLE NIP
+B2E3;B2E3;1102 1175 11C2;B2E3;1102 1175 11C2; # (닣; 닣; 닣; 닣; 닣; ) HANGUL SYLLABLE NIH
+B2E4;B2E4;1103 1161;B2E4;1103 1161; # (다; 다; 다; 다; 다; ) HANGUL SYLLABLE DA
+B2E5;B2E5;1103 1161 11A8;B2E5;1103 1161 11A8; # (닥; 닥; 닥; 닥; 닥; ) HANGUL SYLLABLE DAG
+B2E6;B2E6;1103 1161 11A9;B2E6;1103 1161 11A9; # (닦; 닦; 닦; 닦; 닦; ) HANGUL SYLLABLE DAGG
+B2E7;B2E7;1103 1161 11AA;B2E7;1103 1161 11AA; # (닧; 닧; 닧; 닧; 닧; ) HANGUL SYLLABLE DAGS
+B2E8;B2E8;1103 1161 11AB;B2E8;1103 1161 11AB; # (단; 단; 단; 단; 단; ) HANGUL SYLLABLE DAN
+B2E9;B2E9;1103 1161 11AC;B2E9;1103 1161 11AC; # (닩; 닩; 닩; 닩; 닩; ) HANGUL SYLLABLE DANJ
+B2EA;B2EA;1103 1161 11AD;B2EA;1103 1161 11AD; # (닪; 닪; 닪; 닪; 닪; ) HANGUL SYLLABLE DANH
+B2EB;B2EB;1103 1161 11AE;B2EB;1103 1161 11AE; # (닫; 닫; 닫; 닫; 닫; ) HANGUL SYLLABLE DAD
+B2EC;B2EC;1103 1161 11AF;B2EC;1103 1161 11AF; # (달; 달; 달; 달; 달; ) HANGUL SYLLABLE DAL
+B2ED;B2ED;1103 1161 11B0;B2ED;1103 1161 11B0; # (닭; 닭; 닭; 닭; 닭; ) HANGUL SYLLABLE DALG
+B2EE;B2EE;1103 1161 11B1;B2EE;1103 1161 11B1; # (닮; 닮; 닮; 닮; 닮; ) HANGUL SYLLABLE DALM
+B2EF;B2EF;1103 1161 11B2;B2EF;1103 1161 11B2; # (닯; 닯; 닯; 닯; 닯; ) HANGUL SYLLABLE DALB
+B2F0;B2F0;1103 1161 11B3;B2F0;1103 1161 11B3; # (닰; 닰; 닰; 닰; 닰; ) HANGUL SYLLABLE DALS
+B2F1;B2F1;1103 1161 11B4;B2F1;1103 1161 11B4; # (닱; 닱; 닱; 닱; 닱; ) HANGUL SYLLABLE DALT
+B2F2;B2F2;1103 1161 11B5;B2F2;1103 1161 11B5; # (닲; 닲; 닲; 닲; 닲; ) HANGUL SYLLABLE DALP
+B2F3;B2F3;1103 1161 11B6;B2F3;1103 1161 11B6; # (닳; 닳; 닳; 닳; 닳; ) HANGUL SYLLABLE DALH
+B2F4;B2F4;1103 1161 11B7;B2F4;1103 1161 11B7; # (담; 담; 담; 담; 담; ) HANGUL SYLLABLE DAM
+B2F5;B2F5;1103 1161 11B8;B2F5;1103 1161 11B8; # (답; 답; 답; 답; 답; ) HANGUL SYLLABLE DAB
+B2F6;B2F6;1103 1161 11B9;B2F6;1103 1161 11B9; # (닶; 닶; 닶; 닶; 닶; ) HANGUL SYLLABLE DABS
+B2F7;B2F7;1103 1161 11BA;B2F7;1103 1161 11BA; # (닷; 닷; 닷; 닷; 닷; ) HANGUL SYLLABLE DAS
+B2F8;B2F8;1103 1161 11BB;B2F8;1103 1161 11BB; # (닸; 닸; 닸; 닸; 닸; ) HANGUL SYLLABLE DASS
+B2F9;B2F9;1103 1161 11BC;B2F9;1103 1161 11BC; # (당; 당; 당; 당; 당; ) HANGUL SYLLABLE DANG
+B2FA;B2FA;1103 1161 11BD;B2FA;1103 1161 11BD; # (닺; 닺; 닺; 닺; 닺; ) HANGUL SYLLABLE DAJ
+B2FB;B2FB;1103 1161 11BE;B2FB;1103 1161 11BE; # (닻; 닻; 닻; 닻; 닻; ) HANGUL SYLLABLE DAC
+B2FC;B2FC;1103 1161 11BF;B2FC;1103 1161 11BF; # (닼; 닼; 닼; 닼; 닼; ) HANGUL SYLLABLE DAK
+B2FD;B2FD;1103 1161 11C0;B2FD;1103 1161 11C0; # (닽; 닽; 닽; 닽; 닽; ) HANGUL SYLLABLE DAT
+B2FE;B2FE;1103 1161 11C1;B2FE;1103 1161 11C1; # (닾; 닾; 닾; 닾; 닾; ) HANGUL SYLLABLE DAP
+B2FF;B2FF;1103 1161 11C2;B2FF;1103 1161 11C2; # (닿; 닿; 닿; 닿; 닿; ) HANGUL SYLLABLE DAH
+B300;B300;1103 1162;B300;1103 1162; # (대; 대; 대; 대; 대; ) HANGUL SYLLABLE DAE
+B301;B301;1103 1162 11A8;B301;1103 1162 11A8; # (댁; 댁; 댁; 댁; 댁; ) HANGUL SYLLABLE DAEG
+B302;B302;1103 1162 11A9;B302;1103 1162 11A9; # (댂; 댂; 댂; 댂; 댂; ) HANGUL SYLLABLE DAEGG
+B303;B303;1103 1162 11AA;B303;1103 1162 11AA; # (댃; 댃; 댃; 댃; 댃; ) HANGUL SYLLABLE DAEGS
+B304;B304;1103 1162 11AB;B304;1103 1162 11AB; # (댄; 댄; 댄; 댄; 댄; ) HANGUL SYLLABLE DAEN
+B305;B305;1103 1162 11AC;B305;1103 1162 11AC; # (댅; 댅; 댅; 댅; 댅; ) HANGUL SYLLABLE DAENJ
+B306;B306;1103 1162 11AD;B306;1103 1162 11AD; # (댆; 댆; 댆; 댆; 댆; ) HANGUL SYLLABLE DAENH
+B307;B307;1103 1162 11AE;B307;1103 1162 11AE; # (댇; 댇; 댇; 댇; 댇; ) HANGUL SYLLABLE DAED
+B308;B308;1103 1162 11AF;B308;1103 1162 11AF; # (댈; 댈; 댈; 댈; 댈; ) HANGUL SYLLABLE DAEL
+B309;B309;1103 1162 11B0;B309;1103 1162 11B0; # (댉; 댉; 댉; 댉; 댉; ) HANGUL SYLLABLE DAELG
+B30A;B30A;1103 1162 11B1;B30A;1103 1162 11B1; # (댊; 댊; 댊; 댊; 댊; ) HANGUL SYLLABLE DAELM
+B30B;B30B;1103 1162 11B2;B30B;1103 1162 11B2; # (댋; 댋; 댋; 댋; 댋; ) HANGUL SYLLABLE DAELB
+B30C;B30C;1103 1162 11B3;B30C;1103 1162 11B3; # (댌; 댌; 댌; 댌; 댌; ) HANGUL SYLLABLE DAELS
+B30D;B30D;1103 1162 11B4;B30D;1103 1162 11B4; # (댍; 댍; 댍; 댍; 댍; ) HANGUL SYLLABLE DAELT
+B30E;B30E;1103 1162 11B5;B30E;1103 1162 11B5; # (댎; 댎; 댎; 댎; 댎; ) HANGUL SYLLABLE DAELP
+B30F;B30F;1103 1162 11B6;B30F;1103 1162 11B6; # (댏; 댏; 댏; 댏; 댏; ) HANGUL SYLLABLE DAELH
+B310;B310;1103 1162 11B7;B310;1103 1162 11B7; # (댐; 댐; 댐; 댐; 댐; ) HANGUL SYLLABLE DAEM
+B311;B311;1103 1162 11B8;B311;1103 1162 11B8; # (댑; 댑; 댑; 댑; 댑; ) HANGUL SYLLABLE DAEB
+B312;B312;1103 1162 11B9;B312;1103 1162 11B9; # (댒; 댒; 댒; 댒; 댒; ) HANGUL SYLLABLE DAEBS
+B313;B313;1103 1162 11BA;B313;1103 1162 11BA; # (댓; 댓; 댓; 댓; 댓; ) HANGUL SYLLABLE DAES
+B314;B314;1103 1162 11BB;B314;1103 1162 11BB; # (댔; 댔; 댔; 댔; 댔; ) HANGUL SYLLABLE DAESS
+B315;B315;1103 1162 11BC;B315;1103 1162 11BC; # (댕; 댕; 댕; 댕; 댕; ) HANGUL SYLLABLE DAENG
+B316;B316;1103 1162 11BD;B316;1103 1162 11BD; # (댖; 댖; 댖; 댖; 댖; ) HANGUL SYLLABLE DAEJ
+B317;B317;1103 1162 11BE;B317;1103 1162 11BE; # (댗; 댗; 댗; 댗; 댗; ) HANGUL SYLLABLE DAEC
+B318;B318;1103 1162 11BF;B318;1103 1162 11BF; # (댘; 댘; 댘; 댘; 댘; ) HANGUL SYLLABLE DAEK
+B319;B319;1103 1162 11C0;B319;1103 1162 11C0; # (댙; 댙; 댙; 댙; 댙; ) HANGUL SYLLABLE DAET
+B31A;B31A;1103 1162 11C1;B31A;1103 1162 11C1; # (댚; 댚; 댚; 댚; 댚; ) HANGUL SYLLABLE DAEP
+B31B;B31B;1103 1162 11C2;B31B;1103 1162 11C2; # (댛; 댛; 댛; 댛; 댛; ) HANGUL SYLLABLE DAEH
+B31C;B31C;1103 1163;B31C;1103 1163; # (댜; 댜; 댜; 댜; 댜; ) HANGUL SYLLABLE DYA
+B31D;B31D;1103 1163 11A8;B31D;1103 1163 11A8; # (댝; 댝; 댝; 댝; 댝; ) HANGUL SYLLABLE DYAG
+B31E;B31E;1103 1163 11A9;B31E;1103 1163 11A9; # (댞; 댞; 댞; 댞; 댞; ) HANGUL SYLLABLE DYAGG
+B31F;B31F;1103 1163 11AA;B31F;1103 1163 11AA; # (댟; 댟; 댟; 댟; 댟; ) HANGUL SYLLABLE DYAGS
+B320;B320;1103 1163 11AB;B320;1103 1163 11AB; # (댠; 댠; 댠; 댠; 댠; ) HANGUL SYLLABLE DYAN
+B321;B321;1103 1163 11AC;B321;1103 1163 11AC; # (댡; 댡; 댡; 댡; 댡; ) HANGUL SYLLABLE DYANJ
+B322;B322;1103 1163 11AD;B322;1103 1163 11AD; # (댢; 댢; 댢; 댢; 댢; ) HANGUL SYLLABLE DYANH
+B323;B323;1103 1163 11AE;B323;1103 1163 11AE; # (댣; 댣; 댣; 댣; 댣; ) HANGUL SYLLABLE DYAD
+B324;B324;1103 1163 11AF;B324;1103 1163 11AF; # (댤; 댤; 댤; 댤; 댤; ) HANGUL SYLLABLE DYAL
+B325;B325;1103 1163 11B0;B325;1103 1163 11B0; # (댥; 댥; 댥; 댥; 댥; ) HANGUL SYLLABLE DYALG
+B326;B326;1103 1163 11B1;B326;1103 1163 11B1; # (댦; 댦; 댦; 댦; 댦; ) HANGUL SYLLABLE DYALM
+B327;B327;1103 1163 11B2;B327;1103 1163 11B2; # (댧; 댧; 댧; 댧; 댧; ) HANGUL SYLLABLE DYALB
+B328;B328;1103 1163 11B3;B328;1103 1163 11B3; # (댨; 댨; 댨; 댨; 댨; ) HANGUL SYLLABLE DYALS
+B329;B329;1103 1163 11B4;B329;1103 1163 11B4; # (댩; 댩; 댩; 댩; 댩; ) HANGUL SYLLABLE DYALT
+B32A;B32A;1103 1163 11B5;B32A;1103 1163 11B5; # (댪; 댪; 댪; 댪; 댪; ) HANGUL SYLLABLE DYALP
+B32B;B32B;1103 1163 11B6;B32B;1103 1163 11B6; # (댫; 댫; 댫; 댫; 댫; ) HANGUL SYLLABLE DYALH
+B32C;B32C;1103 1163 11B7;B32C;1103 1163 11B7; # (댬; 댬; 댬; 댬; 댬; ) HANGUL SYLLABLE DYAM
+B32D;B32D;1103 1163 11B8;B32D;1103 1163 11B8; # (댭; 댭; 댭; 댭; 댭; ) HANGUL SYLLABLE DYAB
+B32E;B32E;1103 1163 11B9;B32E;1103 1163 11B9; # (댮; 댮; 댮; 댮; 댮; ) HANGUL SYLLABLE DYABS
+B32F;B32F;1103 1163 11BA;B32F;1103 1163 11BA; # (댯; 댯; 댯; 댯; 댯; ) HANGUL SYLLABLE DYAS
+B330;B330;1103 1163 11BB;B330;1103 1163 11BB; # (댰; 댰; 댰; 댰; 댰; ) HANGUL SYLLABLE DYASS
+B331;B331;1103 1163 11BC;B331;1103 1163 11BC; # (댱; 댱; 댱; 댱; 댱; ) HANGUL SYLLABLE DYANG
+B332;B332;1103 1163 11BD;B332;1103 1163 11BD; # (댲; 댲; 댲; 댲; 댲; ) HANGUL SYLLABLE DYAJ
+B333;B333;1103 1163 11BE;B333;1103 1163 11BE; # (댳; 댳; 댳; 댳; 댳; ) HANGUL SYLLABLE DYAC
+B334;B334;1103 1163 11BF;B334;1103 1163 11BF; # (댴; 댴; 댴; 댴; 댴; ) HANGUL SYLLABLE DYAK
+B335;B335;1103 1163 11C0;B335;1103 1163 11C0; # (댵; 댵; 댵; 댵; 댵; ) HANGUL SYLLABLE DYAT
+B336;B336;1103 1163 11C1;B336;1103 1163 11C1; # (댶; 댶; 댶; 댶; 댶; ) HANGUL SYLLABLE DYAP
+B337;B337;1103 1163 11C2;B337;1103 1163 11C2; # (댷; 댷; 댷; 댷; 댷; ) HANGUL SYLLABLE DYAH
+B338;B338;1103 1164;B338;1103 1164; # (댸; 댸; 댸; 댸; 댸; ) HANGUL SYLLABLE DYAE
+B339;B339;1103 1164 11A8;B339;1103 1164 11A8; # (댹; 댹; 댹; 댹; 댹; ) HANGUL SYLLABLE DYAEG
+B33A;B33A;1103 1164 11A9;B33A;1103 1164 11A9; # (댺; 댺; 댺; 댺; 댺; ) HANGUL SYLLABLE DYAEGG
+B33B;B33B;1103 1164 11AA;B33B;1103 1164 11AA; # (댻; 댻; 댻; 댻; 댻; ) HANGUL SYLLABLE DYAEGS
+B33C;B33C;1103 1164 11AB;B33C;1103 1164 11AB; # (댼; 댼; 댼; 댼; 댼; ) HANGUL SYLLABLE DYAEN
+B33D;B33D;1103 1164 11AC;B33D;1103 1164 11AC; # (댽; 댽; 댽; 댽; 댽; ) HANGUL SYLLABLE DYAENJ
+B33E;B33E;1103 1164 11AD;B33E;1103 1164 11AD; # (댾; 댾; 댾; 댾; 댾; ) HANGUL SYLLABLE DYAENH
+B33F;B33F;1103 1164 11AE;B33F;1103 1164 11AE; # (댿; 댿; 댿; 댿; 댿; ) HANGUL SYLLABLE DYAED
+B340;B340;1103 1164 11AF;B340;1103 1164 11AF; # (덀; 덀; 덀; 덀; 덀; ) HANGUL SYLLABLE DYAEL
+B341;B341;1103 1164 11B0;B341;1103 1164 11B0; # (덁; 덁; 덁; 덁; 덁; ) HANGUL SYLLABLE DYAELG
+B342;B342;1103 1164 11B1;B342;1103 1164 11B1; # (덂; 덂; 덂; 덂; 덂; ) HANGUL SYLLABLE DYAELM
+B343;B343;1103 1164 11B2;B343;1103 1164 11B2; # (덃; 덃; 덃; 덃; 덃; ) HANGUL SYLLABLE DYAELB
+B344;B344;1103 1164 11B3;B344;1103 1164 11B3; # (덄; 덄; 덄; 덄; 덄; ) HANGUL SYLLABLE DYAELS
+B345;B345;1103 1164 11B4;B345;1103 1164 11B4; # (덅; 덅; 덅; 덅; 덅; ) HANGUL SYLLABLE DYAELT
+B346;B346;1103 1164 11B5;B346;1103 1164 11B5; # (덆; 덆; 덆; 덆; 덆; ) HANGUL SYLLABLE DYAELP
+B347;B347;1103 1164 11B6;B347;1103 1164 11B6; # (덇; 덇; 덇; 덇; 덇; ) HANGUL SYLLABLE DYAELH
+B348;B348;1103 1164 11B7;B348;1103 1164 11B7; # (덈; 덈; 덈; 덈; 덈; ) HANGUL SYLLABLE DYAEM
+B349;B349;1103 1164 11B8;B349;1103 1164 11B8; # (덉; 덉; 덉; 덉; 덉; ) HANGUL SYLLABLE DYAEB
+B34A;B34A;1103 1164 11B9;B34A;1103 1164 11B9; # (덊; 덊; 덊; 덊; 덊; ) HANGUL SYLLABLE DYAEBS
+B34B;B34B;1103 1164 11BA;B34B;1103 1164 11BA; # (덋; 덋; 덋; 덋; 덋; ) HANGUL SYLLABLE DYAES
+B34C;B34C;1103 1164 11BB;B34C;1103 1164 11BB; # (덌; 덌; 덌; 덌; 덌; ) HANGUL SYLLABLE DYAESS
+B34D;B34D;1103 1164 11BC;B34D;1103 1164 11BC; # (덍; 덍; 덍; 덍; 덍; ) HANGUL SYLLABLE DYAENG
+B34E;B34E;1103 1164 11BD;B34E;1103 1164 11BD; # (덎; 덎; 덎; 덎; 덎; ) HANGUL SYLLABLE DYAEJ
+B34F;B34F;1103 1164 11BE;B34F;1103 1164 11BE; # (덏; 덏; 덏; 덏; 덏; ) HANGUL SYLLABLE DYAEC
+B350;B350;1103 1164 11BF;B350;1103 1164 11BF; # (덐; 덐; 덐; 덐; 덐; ) HANGUL SYLLABLE DYAEK
+B351;B351;1103 1164 11C0;B351;1103 1164 11C0; # (덑; 덑; 덑; 덑; 덑; ) HANGUL SYLLABLE DYAET
+B352;B352;1103 1164 11C1;B352;1103 1164 11C1; # (덒; 덒; 덒; 덒; 덒; ) HANGUL SYLLABLE DYAEP
+B353;B353;1103 1164 11C2;B353;1103 1164 11C2; # (덓; 덓; 덓; 덓; 덓; ) HANGUL SYLLABLE DYAEH
+B354;B354;1103 1165;B354;1103 1165; # (더; 더; 더; 더; 더; ) HANGUL SYLLABLE DEO
+B355;B355;1103 1165 11A8;B355;1103 1165 11A8; # (덕; 덕; 덕; 덕; 덕; ) HANGUL SYLLABLE DEOG
+B356;B356;1103 1165 11A9;B356;1103 1165 11A9; # (덖; 덖; 덖; 덖; 덖; ) HANGUL SYLLABLE DEOGG
+B357;B357;1103 1165 11AA;B357;1103 1165 11AA; # (덗; 덗; 덗; 덗; 덗; ) HANGUL SYLLABLE DEOGS
+B358;B358;1103 1165 11AB;B358;1103 1165 11AB; # (던; 던; 던; 던; 던; ) HANGUL SYLLABLE DEON
+B359;B359;1103 1165 11AC;B359;1103 1165 11AC; # (덙; 덙; 덙; 덙; 덙; ) HANGUL SYLLABLE DEONJ
+B35A;B35A;1103 1165 11AD;B35A;1103 1165 11AD; # (덚; 덚; 덚; 덚; 덚; ) HANGUL SYLLABLE DEONH
+B35B;B35B;1103 1165 11AE;B35B;1103 1165 11AE; # (덛; 덛; 덛; 덛; 덛; ) HANGUL SYLLABLE DEOD
+B35C;B35C;1103 1165 11AF;B35C;1103 1165 11AF; # (덜; 덜; 덜; 덜; 덜; ) HANGUL SYLLABLE DEOL
+B35D;B35D;1103 1165 11B0;B35D;1103 1165 11B0; # (덝; 덝; 덝; 덝; 덝; ) HANGUL SYLLABLE DEOLG
+B35E;B35E;1103 1165 11B1;B35E;1103 1165 11B1; # (덞; 덞; 덞; 덞; 덞; ) HANGUL SYLLABLE DEOLM
+B35F;B35F;1103 1165 11B2;B35F;1103 1165 11B2; # (덟; 덟; 덟; 덟; 덟; ) HANGUL SYLLABLE DEOLB
+B360;B360;1103 1165 11B3;B360;1103 1165 11B3; # (덠; 덠; 덠; 덠; 덠; ) HANGUL SYLLABLE DEOLS
+B361;B361;1103 1165 11B4;B361;1103 1165 11B4; # (덡; 덡; 덡; 덡; 덡; ) HANGUL SYLLABLE DEOLT
+B362;B362;1103 1165 11B5;B362;1103 1165 11B5; # (덢; 덢; 덢; 덢; 덢; ) HANGUL SYLLABLE DEOLP
+B363;B363;1103 1165 11B6;B363;1103 1165 11B6; # (덣; 덣; 덣; 덣; 덣; ) HANGUL SYLLABLE DEOLH
+B364;B364;1103 1165 11B7;B364;1103 1165 11B7; # (덤; 덤; 덤; 덤; 덤; ) HANGUL SYLLABLE DEOM
+B365;B365;1103 1165 11B8;B365;1103 1165 11B8; # (덥; 덥; 덥; 덥; 덥; ) HANGUL SYLLABLE DEOB
+B366;B366;1103 1165 11B9;B366;1103 1165 11B9; # (덦; 덦; 덦; 덦; 덦; ) HANGUL SYLLABLE DEOBS
+B367;B367;1103 1165 11BA;B367;1103 1165 11BA; # (덧; 덧; 덧; 덧; 덧; ) HANGUL SYLLABLE DEOS
+B368;B368;1103 1165 11BB;B368;1103 1165 11BB; # (덨; 덨; 덨; 덨; 덨; ) HANGUL SYLLABLE DEOSS
+B369;B369;1103 1165 11BC;B369;1103 1165 11BC; # (덩; 덩; 덩; 덩; 덩; ) HANGUL SYLLABLE DEONG
+B36A;B36A;1103 1165 11BD;B36A;1103 1165 11BD; # (덪; 덪; 덪; 덪; 덪; ) HANGUL SYLLABLE DEOJ
+B36B;B36B;1103 1165 11BE;B36B;1103 1165 11BE; # (덫; 덫; 덫; 덫; 덫; ) HANGUL SYLLABLE DEOC
+B36C;B36C;1103 1165 11BF;B36C;1103 1165 11BF; # (덬; 덬; 덬; 덬; 덬; ) HANGUL SYLLABLE DEOK
+B36D;B36D;1103 1165 11C0;B36D;1103 1165 11C0; # (덭; 덭; 덭; 덭; 덭; ) HANGUL SYLLABLE DEOT
+B36E;B36E;1103 1165 11C1;B36E;1103 1165 11C1; # (덮; 덮; 덮; 덮; 덮; ) HANGUL SYLLABLE DEOP
+B36F;B36F;1103 1165 11C2;B36F;1103 1165 11C2; # (덯; 덯; 덯; 덯; 덯; ) HANGUL SYLLABLE DEOH
+B370;B370;1103 1166;B370;1103 1166; # (데; 데; 데; 데; 데; ) HANGUL SYLLABLE DE
+B371;B371;1103 1166 11A8;B371;1103 1166 11A8; # (덱; 덱; 덱; 덱; 덱; ) HANGUL SYLLABLE DEG
+B372;B372;1103 1166 11A9;B372;1103 1166 11A9; # (덲; 덲; 덲; 덲; 덲; ) HANGUL SYLLABLE DEGG
+B373;B373;1103 1166 11AA;B373;1103 1166 11AA; # (덳; 덳; 덳; 덳; 덳; ) HANGUL SYLLABLE DEGS
+B374;B374;1103 1166 11AB;B374;1103 1166 11AB; # (덴; 덴; 덴; 덴; 덴; ) HANGUL SYLLABLE DEN
+B375;B375;1103 1166 11AC;B375;1103 1166 11AC; # (덵; 덵; 덵; 덵; 덵; ) HANGUL SYLLABLE DENJ
+B376;B376;1103 1166 11AD;B376;1103 1166 11AD; # (덶; 덶; 덶; 덶; 덶; ) HANGUL SYLLABLE DENH
+B377;B377;1103 1166 11AE;B377;1103 1166 11AE; # (덷; 덷; 덷; 덷; 덷; ) HANGUL SYLLABLE DED
+B378;B378;1103 1166 11AF;B378;1103 1166 11AF; # (델; 델; 델; 델; 델; ) HANGUL SYLLABLE DEL
+B379;B379;1103 1166 11B0;B379;1103 1166 11B0; # (덹; 덹; 덹; 덹; 덹; ) HANGUL SYLLABLE DELG
+B37A;B37A;1103 1166 11B1;B37A;1103 1166 11B1; # (덺; 덺; 덺; 덺; 덺; ) HANGUL SYLLABLE DELM
+B37B;B37B;1103 1166 11B2;B37B;1103 1166 11B2; # (덻; 덻; 덻; 덻; 덻; ) HANGUL SYLLABLE DELB
+B37C;B37C;1103 1166 11B3;B37C;1103 1166 11B3; # (덼; 덼; 덼; 덼; 덼; ) HANGUL SYLLABLE DELS
+B37D;B37D;1103 1166 11B4;B37D;1103 1166 11B4; # (덽; 덽; 덽; 덽; 덽; ) HANGUL SYLLABLE DELT
+B37E;B37E;1103 1166 11B5;B37E;1103 1166 11B5; # (덾; 덾; 덾; 덾; 덾; ) HANGUL SYLLABLE DELP
+B37F;B37F;1103 1166 11B6;B37F;1103 1166 11B6; # (덿; 덿; 덿; 덿; 덿; ) HANGUL SYLLABLE DELH
+B380;B380;1103 1166 11B7;B380;1103 1166 11B7; # (뎀; 뎀; 뎀; 뎀; 뎀; ) HANGUL SYLLABLE DEM
+B381;B381;1103 1166 11B8;B381;1103 1166 11B8; # (뎁; 뎁; 뎁; 뎁; 뎁; ) HANGUL SYLLABLE DEB
+B382;B382;1103 1166 11B9;B382;1103 1166 11B9; # (뎂; 뎂; 뎂; 뎂; 뎂; ) HANGUL SYLLABLE DEBS
+B383;B383;1103 1166 11BA;B383;1103 1166 11BA; # (뎃; 뎃; 뎃; 뎃; 뎃; ) HANGUL SYLLABLE DES
+B384;B384;1103 1166 11BB;B384;1103 1166 11BB; # (뎄; 뎄; 뎄; 뎄; 뎄; ) HANGUL SYLLABLE DESS
+B385;B385;1103 1166 11BC;B385;1103 1166 11BC; # (뎅; 뎅; 뎅; 뎅; 뎅; ) HANGUL SYLLABLE DENG
+B386;B386;1103 1166 11BD;B386;1103 1166 11BD; # (뎆; 뎆; 뎆; 뎆; 뎆; ) HANGUL SYLLABLE DEJ
+B387;B387;1103 1166 11BE;B387;1103 1166 11BE; # (뎇; 뎇; 뎇; 뎇; 뎇; ) HANGUL SYLLABLE DEC
+B388;B388;1103 1166 11BF;B388;1103 1166 11BF; # (뎈; 뎈; 뎈; 뎈; 뎈; ) HANGUL SYLLABLE DEK
+B389;B389;1103 1166 11C0;B389;1103 1166 11C0; # (뎉; 뎉; 뎉; 뎉; 뎉; ) HANGUL SYLLABLE DET
+B38A;B38A;1103 1166 11C1;B38A;1103 1166 11C1; # (뎊; 뎊; 뎊; 뎊; 뎊; ) HANGUL SYLLABLE DEP
+B38B;B38B;1103 1166 11C2;B38B;1103 1166 11C2; # (뎋; 뎋; 뎋; 뎋; 뎋; ) HANGUL SYLLABLE DEH
+B38C;B38C;1103 1167;B38C;1103 1167; # (뎌; 뎌; 뎌; 뎌; 뎌; ) HANGUL SYLLABLE DYEO
+B38D;B38D;1103 1167 11A8;B38D;1103 1167 11A8; # (뎍; 뎍; 뎍; 뎍; 뎍; ) HANGUL SYLLABLE DYEOG
+B38E;B38E;1103 1167 11A9;B38E;1103 1167 11A9; # (뎎; 뎎; 뎎; 뎎; 뎎; ) HANGUL SYLLABLE DYEOGG
+B38F;B38F;1103 1167 11AA;B38F;1103 1167 11AA; # (뎏; 뎏; 뎏; 뎏; 뎏; ) HANGUL SYLLABLE DYEOGS
+B390;B390;1103 1167 11AB;B390;1103 1167 11AB; # (뎐; 뎐; 뎐; 뎐; 뎐; ) HANGUL SYLLABLE DYEON
+B391;B391;1103 1167 11AC;B391;1103 1167 11AC; # (뎑; 뎑; 뎑; 뎑; 뎑; ) HANGUL SYLLABLE DYEONJ
+B392;B392;1103 1167 11AD;B392;1103 1167 11AD; # (뎒; 뎒; 뎒; 뎒; 뎒; ) HANGUL SYLLABLE DYEONH
+B393;B393;1103 1167 11AE;B393;1103 1167 11AE; # (뎓; 뎓; 뎓; 뎓; 뎓; ) HANGUL SYLLABLE DYEOD
+B394;B394;1103 1167 11AF;B394;1103 1167 11AF; # (뎔; 뎔; 뎔; 뎔; 뎔; ) HANGUL SYLLABLE DYEOL
+B395;B395;1103 1167 11B0;B395;1103 1167 11B0; # (뎕; 뎕; 뎕; 뎕; 뎕; ) HANGUL SYLLABLE DYEOLG
+B396;B396;1103 1167 11B1;B396;1103 1167 11B1; # (뎖; 뎖; 뎖; 뎖; 뎖; ) HANGUL SYLLABLE DYEOLM
+B397;B397;1103 1167 11B2;B397;1103 1167 11B2; # (뎗; 뎗; 뎗; 뎗; 뎗; ) HANGUL SYLLABLE DYEOLB
+B398;B398;1103 1167 11B3;B398;1103 1167 11B3; # (뎘; 뎘; 뎘; 뎘; 뎘; ) HANGUL SYLLABLE DYEOLS
+B399;B399;1103 1167 11B4;B399;1103 1167 11B4; # (뎙; 뎙; 뎙; 뎙; 뎙; ) HANGUL SYLLABLE DYEOLT
+B39A;B39A;1103 1167 11B5;B39A;1103 1167 11B5; # (뎚; 뎚; 뎚; 뎚; 뎚; ) HANGUL SYLLABLE DYEOLP
+B39B;B39B;1103 1167 11B6;B39B;1103 1167 11B6; # (뎛; 뎛; 뎛; 뎛; 뎛; ) HANGUL SYLLABLE DYEOLH
+B39C;B39C;1103 1167 11B7;B39C;1103 1167 11B7; # (뎜; 뎜; 뎜; 뎜; 뎜; ) HANGUL SYLLABLE DYEOM
+B39D;B39D;1103 1167 11B8;B39D;1103 1167 11B8; # (뎝; 뎝; 뎝; 뎝; 뎝; ) HANGUL SYLLABLE DYEOB
+B39E;B39E;1103 1167 11B9;B39E;1103 1167 11B9; # (뎞; 뎞; 뎞; 뎞; 뎞; ) HANGUL SYLLABLE DYEOBS
+B39F;B39F;1103 1167 11BA;B39F;1103 1167 11BA; # (뎟; 뎟; 뎟; 뎟; 뎟; ) HANGUL SYLLABLE DYEOS
+B3A0;B3A0;1103 1167 11BB;B3A0;1103 1167 11BB; # (뎠; 뎠; 뎠; 뎠; 뎠; ) HANGUL SYLLABLE DYEOSS
+B3A1;B3A1;1103 1167 11BC;B3A1;1103 1167 11BC; # (뎡; 뎡; 뎡; 뎡; 뎡; ) HANGUL SYLLABLE DYEONG
+B3A2;B3A2;1103 1167 11BD;B3A2;1103 1167 11BD; # (뎢; 뎢; 뎢; 뎢; 뎢; ) HANGUL SYLLABLE DYEOJ
+B3A3;B3A3;1103 1167 11BE;B3A3;1103 1167 11BE; # (뎣; 뎣; 뎣; 뎣; 뎣; ) HANGUL SYLLABLE DYEOC
+B3A4;B3A4;1103 1167 11BF;B3A4;1103 1167 11BF; # (뎤; 뎤; 뎤; 뎤; 뎤; ) HANGUL SYLLABLE DYEOK
+B3A5;B3A5;1103 1167 11C0;B3A5;1103 1167 11C0; # (뎥; 뎥; 뎥; 뎥; 뎥; ) HANGUL SYLLABLE DYEOT
+B3A6;B3A6;1103 1167 11C1;B3A6;1103 1167 11C1; # (뎦; 뎦; 뎦; 뎦; 뎦; ) HANGUL SYLLABLE DYEOP
+B3A7;B3A7;1103 1167 11C2;B3A7;1103 1167 11C2; # (뎧; 뎧; 뎧; 뎧; 뎧; ) HANGUL SYLLABLE DYEOH
+B3A8;B3A8;1103 1168;B3A8;1103 1168; # (뎨; 뎨; 뎨; 뎨; 뎨; ) HANGUL SYLLABLE DYE
+B3A9;B3A9;1103 1168 11A8;B3A9;1103 1168 11A8; # (뎩; 뎩; 뎩; 뎩; 뎩; ) HANGUL SYLLABLE DYEG
+B3AA;B3AA;1103 1168 11A9;B3AA;1103 1168 11A9; # (뎪; 뎪; 뎪; 뎪; 뎪; ) HANGUL SYLLABLE DYEGG
+B3AB;B3AB;1103 1168 11AA;B3AB;1103 1168 11AA; # (뎫; 뎫; 뎫; 뎫; 뎫; ) HANGUL SYLLABLE DYEGS
+B3AC;B3AC;1103 1168 11AB;B3AC;1103 1168 11AB; # (뎬; 뎬; 뎬; 뎬; 뎬; ) HANGUL SYLLABLE DYEN
+B3AD;B3AD;1103 1168 11AC;B3AD;1103 1168 11AC; # (뎭; 뎭; 뎭; 뎭; 뎭; ) HANGUL SYLLABLE DYENJ
+B3AE;B3AE;1103 1168 11AD;B3AE;1103 1168 11AD; # (뎮; 뎮; 뎮; 뎮; 뎮; ) HANGUL SYLLABLE DYENH
+B3AF;B3AF;1103 1168 11AE;B3AF;1103 1168 11AE; # (뎯; 뎯; 뎯; 뎯; 뎯; ) HANGUL SYLLABLE DYED
+B3B0;B3B0;1103 1168 11AF;B3B0;1103 1168 11AF; # (뎰; 뎰; 뎰; 뎰; 뎰; ) HANGUL SYLLABLE DYEL
+B3B1;B3B1;1103 1168 11B0;B3B1;1103 1168 11B0; # (뎱; 뎱; 뎱; 뎱; 뎱; ) HANGUL SYLLABLE DYELG
+B3B2;B3B2;1103 1168 11B1;B3B2;1103 1168 11B1; # (뎲; 뎲; 뎲; 뎲; 뎲; ) HANGUL SYLLABLE DYELM
+B3B3;B3B3;1103 1168 11B2;B3B3;1103 1168 11B2; # (뎳; 뎳; 뎳; 뎳; 뎳; ) HANGUL SYLLABLE DYELB
+B3B4;B3B4;1103 1168 11B3;B3B4;1103 1168 11B3; # (뎴; 뎴; 뎴; 뎴; 뎴; ) HANGUL SYLLABLE DYELS
+B3B5;B3B5;1103 1168 11B4;B3B5;1103 1168 11B4; # (뎵; 뎵; 뎵; 뎵; 뎵; ) HANGUL SYLLABLE DYELT
+B3B6;B3B6;1103 1168 11B5;B3B6;1103 1168 11B5; # (뎶; 뎶; 뎶; 뎶; 뎶; ) HANGUL SYLLABLE DYELP
+B3B7;B3B7;1103 1168 11B6;B3B7;1103 1168 11B6; # (뎷; 뎷; 뎷; 뎷; 뎷; ) HANGUL SYLLABLE DYELH
+B3B8;B3B8;1103 1168 11B7;B3B8;1103 1168 11B7; # (뎸; 뎸; 뎸; 뎸; 뎸; ) HANGUL SYLLABLE DYEM
+B3B9;B3B9;1103 1168 11B8;B3B9;1103 1168 11B8; # (뎹; 뎹; 뎹; 뎹; 뎹; ) HANGUL SYLLABLE DYEB
+B3BA;B3BA;1103 1168 11B9;B3BA;1103 1168 11B9; # (뎺; 뎺; 뎺; 뎺; 뎺; ) HANGUL SYLLABLE DYEBS
+B3BB;B3BB;1103 1168 11BA;B3BB;1103 1168 11BA; # (뎻; 뎻; 뎻; 뎻; 뎻; ) HANGUL SYLLABLE DYES
+B3BC;B3BC;1103 1168 11BB;B3BC;1103 1168 11BB; # (뎼; 뎼; 뎼; 뎼; 뎼; ) HANGUL SYLLABLE DYESS
+B3BD;B3BD;1103 1168 11BC;B3BD;1103 1168 11BC; # (뎽; 뎽; 뎽; 뎽; 뎽; ) HANGUL SYLLABLE DYENG
+B3BE;B3BE;1103 1168 11BD;B3BE;1103 1168 11BD; # (뎾; 뎾; 뎾; 뎾; 뎾; ) HANGUL SYLLABLE DYEJ
+B3BF;B3BF;1103 1168 11BE;B3BF;1103 1168 11BE; # (뎿; 뎿; 뎿; 뎿; 뎿; ) HANGUL SYLLABLE DYEC
+B3C0;B3C0;1103 1168 11BF;B3C0;1103 1168 11BF; # (돀; 돀; 돀; 돀; 돀; ) HANGUL SYLLABLE DYEK
+B3C1;B3C1;1103 1168 11C0;B3C1;1103 1168 11C0; # (돁; 돁; 돁; 돁; 돁; ) HANGUL SYLLABLE DYET
+B3C2;B3C2;1103 1168 11C1;B3C2;1103 1168 11C1; # (돂; 돂; 돂; 돂; 돂; ) HANGUL SYLLABLE DYEP
+B3C3;B3C3;1103 1168 11C2;B3C3;1103 1168 11C2; # (돃; 돃; 돃; 돃; 돃; ) HANGUL SYLLABLE DYEH
+B3C4;B3C4;1103 1169;B3C4;1103 1169; # (도; 도; 도; 도; 도; ) HANGUL SYLLABLE DO
+B3C5;B3C5;1103 1169 11A8;B3C5;1103 1169 11A8; # (독; 독; 독; 독; 독; ) HANGUL SYLLABLE DOG
+B3C6;B3C6;1103 1169 11A9;B3C6;1103 1169 11A9; # (돆; 돆; 돆; 돆; 돆; ) HANGUL SYLLABLE DOGG
+B3C7;B3C7;1103 1169 11AA;B3C7;1103 1169 11AA; # (돇; 돇; 돇; 돇; 돇; ) HANGUL SYLLABLE DOGS
+B3C8;B3C8;1103 1169 11AB;B3C8;1103 1169 11AB; # (돈; 돈; 돈; 돈; 돈; ) HANGUL SYLLABLE DON
+B3C9;B3C9;1103 1169 11AC;B3C9;1103 1169 11AC; # (돉; 돉; 돉; 돉; 돉; ) HANGUL SYLLABLE DONJ
+B3CA;B3CA;1103 1169 11AD;B3CA;1103 1169 11AD; # (돊; 돊; 돊; 돊; 돊; ) HANGUL SYLLABLE DONH
+B3CB;B3CB;1103 1169 11AE;B3CB;1103 1169 11AE; # (돋; 돋; 돋; 돋; 돋; ) HANGUL SYLLABLE DOD
+B3CC;B3CC;1103 1169 11AF;B3CC;1103 1169 11AF; # (돌; 돌; 돌; 돌; 돌; ) HANGUL SYLLABLE DOL
+B3CD;B3CD;1103 1169 11B0;B3CD;1103 1169 11B0; # (돍; 돍; 돍; 돍; 돍; ) HANGUL SYLLABLE DOLG
+B3CE;B3CE;1103 1169 11B1;B3CE;1103 1169 11B1; # (돎; 돎; 돎; 돎; 돎; ) HANGUL SYLLABLE DOLM
+B3CF;B3CF;1103 1169 11B2;B3CF;1103 1169 11B2; # (돏; 돏; 돏; 돏; 돏; ) HANGUL SYLLABLE DOLB
+B3D0;B3D0;1103 1169 11B3;B3D0;1103 1169 11B3; # (돐; 돐; 돐; 돐; 돐; ) HANGUL SYLLABLE DOLS
+B3D1;B3D1;1103 1169 11B4;B3D1;1103 1169 11B4; # (돑; 돑; 돑; 돑; 돑; ) HANGUL SYLLABLE DOLT
+B3D2;B3D2;1103 1169 11B5;B3D2;1103 1169 11B5; # (돒; 돒; 돒; 돒; 돒; ) HANGUL SYLLABLE DOLP
+B3D3;B3D3;1103 1169 11B6;B3D3;1103 1169 11B6; # (돓; 돓; 돓; 돓; 돓; ) HANGUL SYLLABLE DOLH
+B3D4;B3D4;1103 1169 11B7;B3D4;1103 1169 11B7; # (돔; 돔; 돔; 돔; 돔; ) HANGUL SYLLABLE DOM
+B3D5;B3D5;1103 1169 11B8;B3D5;1103 1169 11B8; # (돕; 돕; 돕; 돕; 돕; ) HANGUL SYLLABLE DOB
+B3D6;B3D6;1103 1169 11B9;B3D6;1103 1169 11B9; # (돖; 돖; 돖; 돖; 돖; ) HANGUL SYLLABLE DOBS
+B3D7;B3D7;1103 1169 11BA;B3D7;1103 1169 11BA; # (돗; 돗; 돗; 돗; 돗; ) HANGUL SYLLABLE DOS
+B3D8;B3D8;1103 1169 11BB;B3D8;1103 1169 11BB; # (돘; 돘; 돘; 돘; 돘; ) HANGUL SYLLABLE DOSS
+B3D9;B3D9;1103 1169 11BC;B3D9;1103 1169 11BC; # (동; 동; 동; 동; 동; ) HANGUL SYLLABLE DONG
+B3DA;B3DA;1103 1169 11BD;B3DA;1103 1169 11BD; # (돚; 돚; 돚; 돚; 돚; ) HANGUL SYLLABLE DOJ
+B3DB;B3DB;1103 1169 11BE;B3DB;1103 1169 11BE; # (돛; 돛; 돛; 돛; 돛; ) HANGUL SYLLABLE DOC
+B3DC;B3DC;1103 1169 11BF;B3DC;1103 1169 11BF; # (돜; 돜; 돜; 돜; 돜; ) HANGUL SYLLABLE DOK
+B3DD;B3DD;1103 1169 11C0;B3DD;1103 1169 11C0; # (돝; 돝; 돝; 돝; 돝; ) HANGUL SYLLABLE DOT
+B3DE;B3DE;1103 1169 11C1;B3DE;1103 1169 11C1; # (돞; 돞; 돞; 돞; 돞; ) HANGUL SYLLABLE DOP
+B3DF;B3DF;1103 1169 11C2;B3DF;1103 1169 11C2; # (돟; 돟; 돟; 돟; 돟; ) HANGUL SYLLABLE DOH
+B3E0;B3E0;1103 116A;B3E0;1103 116A; # (돠; 돠; 돠; 돠; 돠; ) HANGUL SYLLABLE DWA
+B3E1;B3E1;1103 116A 11A8;B3E1;1103 116A 11A8; # (돡; 돡; 돡; 돡; 돡; ) HANGUL SYLLABLE DWAG
+B3E2;B3E2;1103 116A 11A9;B3E2;1103 116A 11A9; # (돢; 돢; 돢; 돢; 돢; ) HANGUL SYLLABLE DWAGG
+B3E3;B3E3;1103 116A 11AA;B3E3;1103 116A 11AA; # (돣; 돣; 돣; 돣; 돣; ) HANGUL SYLLABLE DWAGS
+B3E4;B3E4;1103 116A 11AB;B3E4;1103 116A 11AB; # (돤; 돤; 돤; 돤; 돤; ) HANGUL SYLLABLE DWAN
+B3E5;B3E5;1103 116A 11AC;B3E5;1103 116A 11AC; # (돥; 돥; 돥; 돥; 돥; ) HANGUL SYLLABLE DWANJ
+B3E6;B3E6;1103 116A 11AD;B3E6;1103 116A 11AD; # (돦; 돦; 돦; 돦; 돦; ) HANGUL SYLLABLE DWANH
+B3E7;B3E7;1103 116A 11AE;B3E7;1103 116A 11AE; # (돧; 돧; 돧; 돧; 돧; ) HANGUL SYLLABLE DWAD
+B3E8;B3E8;1103 116A 11AF;B3E8;1103 116A 11AF; # (돨; 돨; 돨; 돨; 돨; ) HANGUL SYLLABLE DWAL
+B3E9;B3E9;1103 116A 11B0;B3E9;1103 116A 11B0; # (돩; 돩; 돩; 돩; 돩; ) HANGUL SYLLABLE DWALG
+B3EA;B3EA;1103 116A 11B1;B3EA;1103 116A 11B1; # (돪; 돪; 돪; 돪; 돪; ) HANGUL SYLLABLE DWALM
+B3EB;B3EB;1103 116A 11B2;B3EB;1103 116A 11B2; # (돫; 돫; 돫; 돫; 돫; ) HANGUL SYLLABLE DWALB
+B3EC;B3EC;1103 116A 11B3;B3EC;1103 116A 11B3; # (돬; 돬; 돬; 돬; 돬; ) HANGUL SYLLABLE DWALS
+B3ED;B3ED;1103 116A 11B4;B3ED;1103 116A 11B4; # (돭; 돭; 돭; 돭; 돭; ) HANGUL SYLLABLE DWALT
+B3EE;B3EE;1103 116A 11B5;B3EE;1103 116A 11B5; # (돮; 돮; 돮; 돮; 돮; ) HANGUL SYLLABLE DWALP
+B3EF;B3EF;1103 116A 11B6;B3EF;1103 116A 11B6; # (돯; 돯; 돯; 돯; 돯; ) HANGUL SYLLABLE DWALH
+B3F0;B3F0;1103 116A 11B7;B3F0;1103 116A 11B7; # (돰; 돰; 돰; 돰; 돰; ) HANGUL SYLLABLE DWAM
+B3F1;B3F1;1103 116A 11B8;B3F1;1103 116A 11B8; # (돱; 돱; 돱; 돱; 돱; ) HANGUL SYLLABLE DWAB
+B3F2;B3F2;1103 116A 11B9;B3F2;1103 116A 11B9; # (돲; 돲; 돲; 돲; 돲; ) HANGUL SYLLABLE DWABS
+B3F3;B3F3;1103 116A 11BA;B3F3;1103 116A 11BA; # (돳; 돳; 돳; 돳; 돳; ) HANGUL SYLLABLE DWAS
+B3F4;B3F4;1103 116A 11BB;B3F4;1103 116A 11BB; # (돴; 돴; 돴; 돴; 돴; ) HANGUL SYLLABLE DWASS
+B3F5;B3F5;1103 116A 11BC;B3F5;1103 116A 11BC; # (돵; 돵; 돵; 돵; 돵; ) HANGUL SYLLABLE DWANG
+B3F6;B3F6;1103 116A 11BD;B3F6;1103 116A 11BD; # (돶; 돶; 돶; 돶; 돶; ) HANGUL SYLLABLE DWAJ
+B3F7;B3F7;1103 116A 11BE;B3F7;1103 116A 11BE; # (돷; 돷; 돷; 돷; 돷; ) HANGUL SYLLABLE DWAC
+B3F8;B3F8;1103 116A 11BF;B3F8;1103 116A 11BF; # (돸; 돸; 돸; 돸; 돸; ) HANGUL SYLLABLE DWAK
+B3F9;B3F9;1103 116A 11C0;B3F9;1103 116A 11C0; # (돹; 돹; 돹; 돹; 돹; ) HANGUL SYLLABLE DWAT
+B3FA;B3FA;1103 116A 11C1;B3FA;1103 116A 11C1; # (돺; 돺; 돺; 돺; 돺; ) HANGUL SYLLABLE DWAP
+B3FB;B3FB;1103 116A 11C2;B3FB;1103 116A 11C2; # (돻; 돻; 돻; 돻; 돻; ) HANGUL SYLLABLE DWAH
+B3FC;B3FC;1103 116B;B3FC;1103 116B; # (돼; 돼; 돼; 돼; 돼; ) HANGUL SYLLABLE DWAE
+B3FD;B3FD;1103 116B 11A8;B3FD;1103 116B 11A8; # (돽; 돽; 돽; 돽; 돽; ) HANGUL SYLLABLE DWAEG
+B3FE;B3FE;1103 116B 11A9;B3FE;1103 116B 11A9; # (돾; 돾; 돾; 돾; 돾; ) HANGUL SYLLABLE DWAEGG
+B3FF;B3FF;1103 116B 11AA;B3FF;1103 116B 11AA; # (돿; 돿; 돿; 돿; 돿; ) HANGUL SYLLABLE DWAEGS
+B400;B400;1103 116B 11AB;B400;1103 116B 11AB; # (됀; 됀; 됀; 됀; 됀; ) HANGUL SYLLABLE DWAEN
+B401;B401;1103 116B 11AC;B401;1103 116B 11AC; # (됁; 됁; 됁; 됁; 됁; ) HANGUL SYLLABLE DWAENJ
+B402;B402;1103 116B 11AD;B402;1103 116B 11AD; # (됂; 됂; 됂; 됂; 됂; ) HANGUL SYLLABLE DWAENH
+B403;B403;1103 116B 11AE;B403;1103 116B 11AE; # (됃; 됃; 됃; 됃; 됃; ) HANGUL SYLLABLE DWAED
+B404;B404;1103 116B 11AF;B404;1103 116B 11AF; # (됄; 됄; 됄; 됄; 됄; ) HANGUL SYLLABLE DWAEL
+B405;B405;1103 116B 11B0;B405;1103 116B 11B0; # (됅; 됅; 됅; 됅; 됅; ) HANGUL SYLLABLE DWAELG
+B406;B406;1103 116B 11B1;B406;1103 116B 11B1; # (됆; 됆; 됆; 됆; 됆; ) HANGUL SYLLABLE DWAELM
+B407;B407;1103 116B 11B2;B407;1103 116B 11B2; # (됇; 됇; 됇; 됇; 됇; ) HANGUL SYLLABLE DWAELB
+B408;B408;1103 116B 11B3;B408;1103 116B 11B3; # (됈; 됈; 됈; 됈; 됈; ) HANGUL SYLLABLE DWAELS
+B409;B409;1103 116B 11B4;B409;1103 116B 11B4; # (됉; 됉; 됉; 됉; 됉; ) HANGUL SYLLABLE DWAELT
+B40A;B40A;1103 116B 11B5;B40A;1103 116B 11B5; # (됊; 됊; 됊; 됊; 됊; ) HANGUL SYLLABLE DWAELP
+B40B;B40B;1103 116B 11B6;B40B;1103 116B 11B6; # (됋; 됋; 됋; 됋; 됋; ) HANGUL SYLLABLE DWAELH
+B40C;B40C;1103 116B 11B7;B40C;1103 116B 11B7; # (됌; 됌; 됌; 됌; 됌; ) HANGUL SYLLABLE DWAEM
+B40D;B40D;1103 116B 11B8;B40D;1103 116B 11B8; # (됍; 됍; 됍; 됍; 됍; ) HANGUL SYLLABLE DWAEB
+B40E;B40E;1103 116B 11B9;B40E;1103 116B 11B9; # (됎; 됎; 됎; 됎; 됎; ) HANGUL SYLLABLE DWAEBS
+B40F;B40F;1103 116B 11BA;B40F;1103 116B 11BA; # (됏; 됏; 됏; 됏; 됏; ) HANGUL SYLLABLE DWAES
+B410;B410;1103 116B 11BB;B410;1103 116B 11BB; # (됐; 됐; 됐; 됐; 됐; ) HANGUL SYLLABLE DWAESS
+B411;B411;1103 116B 11BC;B411;1103 116B 11BC; # (됑; 됑; 됑; 됑; 됑; ) HANGUL SYLLABLE DWAENG
+B412;B412;1103 116B 11BD;B412;1103 116B 11BD; # (됒; 됒; 됒; 됒; 됒; ) HANGUL SYLLABLE DWAEJ
+B413;B413;1103 116B 11BE;B413;1103 116B 11BE; # (됓; 됓; 됓; 됓; 됓; ) HANGUL SYLLABLE DWAEC
+B414;B414;1103 116B 11BF;B414;1103 116B 11BF; # (됔; 됔; 됔; 됔; 됔; ) HANGUL SYLLABLE DWAEK
+B415;B415;1103 116B 11C0;B415;1103 116B 11C0; # (됕; 됕; 됕; 됕; 됕; ) HANGUL SYLLABLE DWAET
+B416;B416;1103 116B 11C1;B416;1103 116B 11C1; # (됖; 됖; 됖; 됖; 됖; ) HANGUL SYLLABLE DWAEP
+B417;B417;1103 116B 11C2;B417;1103 116B 11C2; # (됗; 됗; 됗; 됗; 됗; ) HANGUL SYLLABLE DWAEH
+B418;B418;1103 116C;B418;1103 116C; # (되; 되; 되; 되; 되; ) HANGUL SYLLABLE DOE
+B419;B419;1103 116C 11A8;B419;1103 116C 11A8; # (됙; 됙; 됙; 됙; 됙; ) HANGUL SYLLABLE DOEG
+B41A;B41A;1103 116C 11A9;B41A;1103 116C 11A9; # (됚; 됚; 됚; 됚; 됚; ) HANGUL SYLLABLE DOEGG
+B41B;B41B;1103 116C 11AA;B41B;1103 116C 11AA; # (됛; 됛; 됛; 됛; 됛; ) HANGUL SYLLABLE DOEGS
+B41C;B41C;1103 116C 11AB;B41C;1103 116C 11AB; # (된; 된; 된; 된; 된; ) HANGUL SYLLABLE DOEN
+B41D;B41D;1103 116C 11AC;B41D;1103 116C 11AC; # (됝; 됝; 됝; 됝; 됝; ) HANGUL SYLLABLE DOENJ
+B41E;B41E;1103 116C 11AD;B41E;1103 116C 11AD; # (됞; 됞; 됞; 됞; 됞; ) HANGUL SYLLABLE DOENH
+B41F;B41F;1103 116C 11AE;B41F;1103 116C 11AE; # (됟; 됟; 됟; 됟; 됟; ) HANGUL SYLLABLE DOED
+B420;B420;1103 116C 11AF;B420;1103 116C 11AF; # (될; 될; 될; 될; 될; ) HANGUL SYLLABLE DOEL
+B421;B421;1103 116C 11B0;B421;1103 116C 11B0; # (됡; 됡; 됡; 됡; 됡; ) HANGUL SYLLABLE DOELG
+B422;B422;1103 116C 11B1;B422;1103 116C 11B1; # (됢; 됢; 됢; 됢; 됢; ) HANGUL SYLLABLE DOELM
+B423;B423;1103 116C 11B2;B423;1103 116C 11B2; # (됣; 됣; 됣; 됣; 됣; ) HANGUL SYLLABLE DOELB
+B424;B424;1103 116C 11B3;B424;1103 116C 11B3; # (됤; 됤; 됤; 됤; 됤; ) HANGUL SYLLABLE DOELS
+B425;B425;1103 116C 11B4;B425;1103 116C 11B4; # (됥; 됥; 됥; 됥; 됥; ) HANGUL SYLLABLE DOELT
+B426;B426;1103 116C 11B5;B426;1103 116C 11B5; # (됦; 됦; 됦; 됦; 됦; ) HANGUL SYLLABLE DOELP
+B427;B427;1103 116C 11B6;B427;1103 116C 11B6; # (됧; 됧; 됧; 됧; 됧; ) HANGUL SYLLABLE DOELH
+B428;B428;1103 116C 11B7;B428;1103 116C 11B7; # (됨; 됨; 됨; 됨; 됨; ) HANGUL SYLLABLE DOEM
+B429;B429;1103 116C 11B8;B429;1103 116C 11B8; # (됩; 됩; 됩; 됩; 됩; ) HANGUL SYLLABLE DOEB
+B42A;B42A;1103 116C 11B9;B42A;1103 116C 11B9; # (됪; 됪; 됪; 됪; 됪; ) HANGUL SYLLABLE DOEBS
+B42B;B42B;1103 116C 11BA;B42B;1103 116C 11BA; # (됫; 됫; 됫; 됫; 됫; ) HANGUL SYLLABLE DOES
+B42C;B42C;1103 116C 11BB;B42C;1103 116C 11BB; # (됬; 됬; 됬; 됬; 됬; ) HANGUL SYLLABLE DOESS
+B42D;B42D;1103 116C 11BC;B42D;1103 116C 11BC; # (됭; 됭; 됭; 됭; 됭; ) HANGUL SYLLABLE DOENG
+B42E;B42E;1103 116C 11BD;B42E;1103 116C 11BD; # (됮; 됮; 됮; 됮; 됮; ) HANGUL SYLLABLE DOEJ
+B42F;B42F;1103 116C 11BE;B42F;1103 116C 11BE; # (됯; 됯; 됯; 됯; 됯; ) HANGUL SYLLABLE DOEC
+B430;B430;1103 116C 11BF;B430;1103 116C 11BF; # (됰; 됰; 됰; 됰; 됰; ) HANGUL SYLLABLE DOEK
+B431;B431;1103 116C 11C0;B431;1103 116C 11C0; # (됱; 됱; 됱; 됱; 됱; ) HANGUL SYLLABLE DOET
+B432;B432;1103 116C 11C1;B432;1103 116C 11C1; # (됲; 됲; 됲; 됲; 됲; ) HANGUL SYLLABLE DOEP
+B433;B433;1103 116C 11C2;B433;1103 116C 11C2; # (됳; 됳; 됳; 됳; 됳; ) HANGUL SYLLABLE DOEH
+B434;B434;1103 116D;B434;1103 116D; # (됴; 됴; 됴; 됴; 됴; ) HANGUL SYLLABLE DYO
+B435;B435;1103 116D 11A8;B435;1103 116D 11A8; # (됵; 됵; 됵; 됵; 됵; ) HANGUL SYLLABLE DYOG
+B436;B436;1103 116D 11A9;B436;1103 116D 11A9; # (됶; 됶; 됶; 됶; 됶; ) HANGUL SYLLABLE DYOGG
+B437;B437;1103 116D 11AA;B437;1103 116D 11AA; # (됷; 됷; 됷; 됷; 됷; ) HANGUL SYLLABLE DYOGS
+B438;B438;1103 116D 11AB;B438;1103 116D 11AB; # (됸; 됸; 됸; 됸; 됸; ) HANGUL SYLLABLE DYON
+B439;B439;1103 116D 11AC;B439;1103 116D 11AC; # (됹; 됹; 됹; 됹; 됹; ) HANGUL SYLLABLE DYONJ
+B43A;B43A;1103 116D 11AD;B43A;1103 116D 11AD; # (됺; 됺; 됺; 됺; 됺; ) HANGUL SYLLABLE DYONH
+B43B;B43B;1103 116D 11AE;B43B;1103 116D 11AE; # (됻; 됻; 됻; 됻; 됻; ) HANGUL SYLLABLE DYOD
+B43C;B43C;1103 116D 11AF;B43C;1103 116D 11AF; # (됼; 됼; 됼; 됼; 됼; ) HANGUL SYLLABLE DYOL
+B43D;B43D;1103 116D 11B0;B43D;1103 116D 11B0; # (됽; 됽; 됽; 됽; 됽; ) HANGUL SYLLABLE DYOLG
+B43E;B43E;1103 116D 11B1;B43E;1103 116D 11B1; # (됾; 됾; 됾; 됾; 됾; ) HANGUL SYLLABLE DYOLM
+B43F;B43F;1103 116D 11B2;B43F;1103 116D 11B2; # (됿; 됿; 됿; 됿; 됿; ) HANGUL SYLLABLE DYOLB
+B440;B440;1103 116D 11B3;B440;1103 116D 11B3; # (둀; 둀; 둀; 둀; 둀; ) HANGUL SYLLABLE DYOLS
+B441;B441;1103 116D 11B4;B441;1103 116D 11B4; # (둁; 둁; 둁; 둁; 둁; ) HANGUL SYLLABLE DYOLT
+B442;B442;1103 116D 11B5;B442;1103 116D 11B5; # (둂; 둂; 둂; 둂; 둂; ) HANGUL SYLLABLE DYOLP
+B443;B443;1103 116D 11B6;B443;1103 116D 11B6; # (둃; 둃; 둃; 둃; 둃; ) HANGUL SYLLABLE DYOLH
+B444;B444;1103 116D 11B7;B444;1103 116D 11B7; # (둄; 둄; 둄; 둄; 둄; ) HANGUL SYLLABLE DYOM
+B445;B445;1103 116D 11B8;B445;1103 116D 11B8; # (둅; 둅; 둅; 둅; 둅; ) HANGUL SYLLABLE DYOB
+B446;B446;1103 116D 11B9;B446;1103 116D 11B9; # (둆; 둆; 둆; 둆; 둆; ) HANGUL SYLLABLE DYOBS
+B447;B447;1103 116D 11BA;B447;1103 116D 11BA; # (둇; 둇; 둇; 둇; 둇; ) HANGUL SYLLABLE DYOS
+B448;B448;1103 116D 11BB;B448;1103 116D 11BB; # (둈; 둈; 둈; 둈; 둈; ) HANGUL SYLLABLE DYOSS
+B449;B449;1103 116D 11BC;B449;1103 116D 11BC; # (둉; 둉; 둉; 둉; 둉; ) HANGUL SYLLABLE DYONG
+B44A;B44A;1103 116D 11BD;B44A;1103 116D 11BD; # (둊; 둊; 둊; 둊; 둊; ) HANGUL SYLLABLE DYOJ
+B44B;B44B;1103 116D 11BE;B44B;1103 116D 11BE; # (둋; 둋; 둋; 둋; 둋; ) HANGUL SYLLABLE DYOC
+B44C;B44C;1103 116D 11BF;B44C;1103 116D 11BF; # (둌; 둌; 둌; 둌; 둌; ) HANGUL SYLLABLE DYOK
+B44D;B44D;1103 116D 11C0;B44D;1103 116D 11C0; # (둍; 둍; 둍; 둍; 둍; ) HANGUL SYLLABLE DYOT
+B44E;B44E;1103 116D 11C1;B44E;1103 116D 11C1; # (둎; 둎; 둎; 둎; 둎; ) HANGUL SYLLABLE DYOP
+B44F;B44F;1103 116D 11C2;B44F;1103 116D 11C2; # (둏; 둏; 둏; 둏; 둏; ) HANGUL SYLLABLE DYOH
+B450;B450;1103 116E;B450;1103 116E; # (두; 두; 두; 두; 두; ) HANGUL SYLLABLE DU
+B451;B451;1103 116E 11A8;B451;1103 116E 11A8; # (둑; 둑; 둑; 둑; 둑; ) HANGUL SYLLABLE DUG
+B452;B452;1103 116E 11A9;B452;1103 116E 11A9; # (둒; 둒; 둒; 둒; 둒; ) HANGUL SYLLABLE DUGG
+B453;B453;1103 116E 11AA;B453;1103 116E 11AA; # (둓; 둓; 둓; 둓; 둓; ) HANGUL SYLLABLE DUGS
+B454;B454;1103 116E 11AB;B454;1103 116E 11AB; # (둔; 둔; 둔; 둔; 둔; ) HANGUL SYLLABLE DUN
+B455;B455;1103 116E 11AC;B455;1103 116E 11AC; # (둕; 둕; 둕; 둕; 둕; ) HANGUL SYLLABLE DUNJ
+B456;B456;1103 116E 11AD;B456;1103 116E 11AD; # (둖; 둖; 둖; 둖; 둖; ) HANGUL SYLLABLE DUNH
+B457;B457;1103 116E 11AE;B457;1103 116E 11AE; # (둗; 둗; 둗; 둗; 둗; ) HANGUL SYLLABLE DUD
+B458;B458;1103 116E 11AF;B458;1103 116E 11AF; # (둘; 둘; 둘; 둘; 둘; ) HANGUL SYLLABLE DUL
+B459;B459;1103 116E 11B0;B459;1103 116E 11B0; # (둙; 둙; 둙; 둙; 둙; ) HANGUL SYLLABLE DULG
+B45A;B45A;1103 116E 11B1;B45A;1103 116E 11B1; # (둚; 둚; 둚; 둚; 둚; ) HANGUL SYLLABLE DULM
+B45B;B45B;1103 116E 11B2;B45B;1103 116E 11B2; # (둛; 둛; 둛; 둛; 둛; ) HANGUL SYLLABLE DULB
+B45C;B45C;1103 116E 11B3;B45C;1103 116E 11B3; # (둜; 둜; 둜; 둜; 둜; ) HANGUL SYLLABLE DULS
+B45D;B45D;1103 116E 11B4;B45D;1103 116E 11B4; # (둝; 둝; 둝; 둝; 둝; ) HANGUL SYLLABLE DULT
+B45E;B45E;1103 116E 11B5;B45E;1103 116E 11B5; # (둞; 둞; 둞; 둞; 둞; ) HANGUL SYLLABLE DULP
+B45F;B45F;1103 116E 11B6;B45F;1103 116E 11B6; # (둟; 둟; 둟; 둟; 둟; ) HANGUL SYLLABLE DULH
+B460;B460;1103 116E 11B7;B460;1103 116E 11B7; # (둠; 둠; 둠; 둠; 둠; ) HANGUL SYLLABLE DUM
+B461;B461;1103 116E 11B8;B461;1103 116E 11B8; # (둡; 둡; 둡; 둡; 둡; ) HANGUL SYLLABLE DUB
+B462;B462;1103 116E 11B9;B462;1103 116E 11B9; # (둢; 둢; 둢; 둢; 둢; ) HANGUL SYLLABLE DUBS
+B463;B463;1103 116E 11BA;B463;1103 116E 11BA; # (둣; 둣; 둣; 둣; 둣; ) HANGUL SYLLABLE DUS
+B464;B464;1103 116E 11BB;B464;1103 116E 11BB; # (둤; 둤; 둤; 둤; 둤; ) HANGUL SYLLABLE DUSS
+B465;B465;1103 116E 11BC;B465;1103 116E 11BC; # (둥; 둥; 둥; 둥; 둥; ) HANGUL SYLLABLE DUNG
+B466;B466;1103 116E 11BD;B466;1103 116E 11BD; # (둦; 둦; 둦; 둦; 둦; ) HANGUL SYLLABLE DUJ
+B467;B467;1103 116E 11BE;B467;1103 116E 11BE; # (둧; 둧; 둧; 둧; 둧; ) HANGUL SYLLABLE DUC
+B468;B468;1103 116E 11BF;B468;1103 116E 11BF; # (둨; 둨; 둨; 둨; 둨; ) HANGUL SYLLABLE DUK
+B469;B469;1103 116E 11C0;B469;1103 116E 11C0; # (둩; 둩; 둩; 둩; 둩; ) HANGUL SYLLABLE DUT
+B46A;B46A;1103 116E 11C1;B46A;1103 116E 11C1; # (둪; 둪; 둪; 둪; 둪; ) HANGUL SYLLABLE DUP
+B46B;B46B;1103 116E 11C2;B46B;1103 116E 11C2; # (둫; 둫; 둫; 둫; 둫; ) HANGUL SYLLABLE DUH
+B46C;B46C;1103 116F;B46C;1103 116F; # (둬; 둬; 둬; 둬; 둬; ) HANGUL SYLLABLE DWEO
+B46D;B46D;1103 116F 11A8;B46D;1103 116F 11A8; # (둭; 둭; 둭; 둭; 둭; ) HANGUL SYLLABLE DWEOG
+B46E;B46E;1103 116F 11A9;B46E;1103 116F 11A9; # (둮; 둮; 둮; 둮; 둮; ) HANGUL SYLLABLE DWEOGG
+B46F;B46F;1103 116F 11AA;B46F;1103 116F 11AA; # (둯; 둯; 둯; 둯; 둯; ) HANGUL SYLLABLE DWEOGS
+B470;B470;1103 116F 11AB;B470;1103 116F 11AB; # (둰; 둰; 둰; 둰; 둰; ) HANGUL SYLLABLE DWEON
+B471;B471;1103 116F 11AC;B471;1103 116F 11AC; # (둱; 둱; 둱; 둱; 둱; ) HANGUL SYLLABLE DWEONJ
+B472;B472;1103 116F 11AD;B472;1103 116F 11AD; # (둲; 둲; 둲; 둲; 둲; ) HANGUL SYLLABLE DWEONH
+B473;B473;1103 116F 11AE;B473;1103 116F 11AE; # (둳; 둳; 둳; 둳; 둳; ) HANGUL SYLLABLE DWEOD
+B474;B474;1103 116F 11AF;B474;1103 116F 11AF; # (둴; 둴; 둴; 둴; 둴; ) HANGUL SYLLABLE DWEOL
+B475;B475;1103 116F 11B0;B475;1103 116F 11B0; # (둵; 둵; 둵; 둵; 둵; ) HANGUL SYLLABLE DWEOLG
+B476;B476;1103 116F 11B1;B476;1103 116F 11B1; # (둶; 둶; 둶; 둶; 둶; ) HANGUL SYLLABLE DWEOLM
+B477;B477;1103 116F 11B2;B477;1103 116F 11B2; # (둷; 둷; 둷; 둷; 둷; ) HANGUL SYLLABLE DWEOLB
+B478;B478;1103 116F 11B3;B478;1103 116F 11B3; # (둸; 둸; 둸; 둸; 둸; ) HANGUL SYLLABLE DWEOLS
+B479;B479;1103 116F 11B4;B479;1103 116F 11B4; # (둹; 둹; 둹; 둹; 둹; ) HANGUL SYLLABLE DWEOLT
+B47A;B47A;1103 116F 11B5;B47A;1103 116F 11B5; # (둺; 둺; 둺; 둺; 둺; ) HANGUL SYLLABLE DWEOLP
+B47B;B47B;1103 116F 11B6;B47B;1103 116F 11B6; # (둻; 둻; 둻; 둻; 둻; ) HANGUL SYLLABLE DWEOLH
+B47C;B47C;1103 116F 11B7;B47C;1103 116F 11B7; # (둼; 둼; 둼; 둼; 둼; ) HANGUL SYLLABLE DWEOM
+B47D;B47D;1103 116F 11B8;B47D;1103 116F 11B8; # (둽; 둽; 둽; 둽; 둽; ) HANGUL SYLLABLE DWEOB
+B47E;B47E;1103 116F 11B9;B47E;1103 116F 11B9; # (둾; 둾; 둾; 둾; 둾; ) HANGUL SYLLABLE DWEOBS
+B47F;B47F;1103 116F 11BA;B47F;1103 116F 11BA; # (둿; 둿; 둿; 둿; 둿; ) HANGUL SYLLABLE DWEOS
+B480;B480;1103 116F 11BB;B480;1103 116F 11BB; # (뒀; 뒀; 뒀; 뒀; 뒀; ) HANGUL SYLLABLE DWEOSS
+B481;B481;1103 116F 11BC;B481;1103 116F 11BC; # (뒁; 뒁; 뒁; 뒁; 뒁; ) HANGUL SYLLABLE DWEONG
+B482;B482;1103 116F 11BD;B482;1103 116F 11BD; # (뒂; 뒂; 뒂; 뒂; 뒂; ) HANGUL SYLLABLE DWEOJ
+B483;B483;1103 116F 11BE;B483;1103 116F 11BE; # (뒃; 뒃; 뒃; 뒃; 뒃; ) HANGUL SYLLABLE DWEOC
+B484;B484;1103 116F 11BF;B484;1103 116F 11BF; # (뒄; 뒄; 뒄; 뒄; 뒄; ) HANGUL SYLLABLE DWEOK
+B485;B485;1103 116F 11C0;B485;1103 116F 11C0; # (뒅; 뒅; 뒅; 뒅; 뒅; ) HANGUL SYLLABLE DWEOT
+B486;B486;1103 116F 11C1;B486;1103 116F 11C1; # (뒆; 뒆; 뒆; 뒆; 뒆; ) HANGUL SYLLABLE DWEOP
+B487;B487;1103 116F 11C2;B487;1103 116F 11C2; # (뒇; 뒇; 뒇; 뒇; 뒇; ) HANGUL SYLLABLE DWEOH
+B488;B488;1103 1170;B488;1103 1170; # (뒈; 뒈; 뒈; 뒈; 뒈; ) HANGUL SYLLABLE DWE
+B489;B489;1103 1170 11A8;B489;1103 1170 11A8; # (뒉; 뒉; 뒉; 뒉; 뒉; ) HANGUL SYLLABLE DWEG
+B48A;B48A;1103 1170 11A9;B48A;1103 1170 11A9; # (뒊; 뒊; 뒊; 뒊; 뒊; ) HANGUL SYLLABLE DWEGG
+B48B;B48B;1103 1170 11AA;B48B;1103 1170 11AA; # (뒋; 뒋; 뒋; 뒋; 뒋; ) HANGUL SYLLABLE DWEGS
+B48C;B48C;1103 1170 11AB;B48C;1103 1170 11AB; # (뒌; 뒌; 뒌; 뒌; 뒌; ) HANGUL SYLLABLE DWEN
+B48D;B48D;1103 1170 11AC;B48D;1103 1170 11AC; # (뒍; 뒍; 뒍; 뒍; 뒍; ) HANGUL SYLLABLE DWENJ
+B48E;B48E;1103 1170 11AD;B48E;1103 1170 11AD; # (뒎; 뒎; 뒎; 뒎; 뒎; ) HANGUL SYLLABLE DWENH
+B48F;B48F;1103 1170 11AE;B48F;1103 1170 11AE; # (뒏; 뒏; 뒏; 뒏; 뒏; ) HANGUL SYLLABLE DWED
+B490;B490;1103 1170 11AF;B490;1103 1170 11AF; # (뒐; 뒐; 뒐; 뒐; 뒐; ) HANGUL SYLLABLE DWEL
+B491;B491;1103 1170 11B0;B491;1103 1170 11B0; # (뒑; 뒑; 뒑; 뒑; 뒑; ) HANGUL SYLLABLE DWELG
+B492;B492;1103 1170 11B1;B492;1103 1170 11B1; # (뒒; 뒒; 뒒; 뒒; 뒒; ) HANGUL SYLLABLE DWELM
+B493;B493;1103 1170 11B2;B493;1103 1170 11B2; # (뒓; 뒓; 뒓; 뒓; 뒓; ) HANGUL SYLLABLE DWELB
+B494;B494;1103 1170 11B3;B494;1103 1170 11B3; # (뒔; 뒔; 뒔; 뒔; 뒔; ) HANGUL SYLLABLE DWELS
+B495;B495;1103 1170 11B4;B495;1103 1170 11B4; # (뒕; 뒕; 뒕; 뒕; 뒕; ) HANGUL SYLLABLE DWELT
+B496;B496;1103 1170 11B5;B496;1103 1170 11B5; # (뒖; 뒖; 뒖; 뒖; 뒖; ) HANGUL SYLLABLE DWELP
+B497;B497;1103 1170 11B6;B497;1103 1170 11B6; # (뒗; 뒗; 뒗; 뒗; 뒗; ) HANGUL SYLLABLE DWELH
+B498;B498;1103 1170 11B7;B498;1103 1170 11B7; # (뒘; 뒘; 뒘; 뒘; 뒘; ) HANGUL SYLLABLE DWEM
+B499;B499;1103 1170 11B8;B499;1103 1170 11B8; # (뒙; 뒙; 뒙; 뒙; 뒙; ) HANGUL SYLLABLE DWEB
+B49A;B49A;1103 1170 11B9;B49A;1103 1170 11B9; # (뒚; 뒚; 뒚; 뒚; 뒚; ) HANGUL SYLLABLE DWEBS
+B49B;B49B;1103 1170 11BA;B49B;1103 1170 11BA; # (뒛; 뒛; 뒛; 뒛; 뒛; ) HANGUL SYLLABLE DWES
+B49C;B49C;1103 1170 11BB;B49C;1103 1170 11BB; # (뒜; 뒜; 뒜; 뒜; 뒜; ) HANGUL SYLLABLE DWESS
+B49D;B49D;1103 1170 11BC;B49D;1103 1170 11BC; # (뒝; 뒝; 뒝; 뒝; 뒝; ) HANGUL SYLLABLE DWENG
+B49E;B49E;1103 1170 11BD;B49E;1103 1170 11BD; # (뒞; 뒞; 뒞; 뒞; 뒞; ) HANGUL SYLLABLE DWEJ
+B49F;B49F;1103 1170 11BE;B49F;1103 1170 11BE; # (뒟; 뒟; 뒟; 뒟; 뒟; ) HANGUL SYLLABLE DWEC
+B4A0;B4A0;1103 1170 11BF;B4A0;1103 1170 11BF; # (뒠; 뒠; 뒠; 뒠; 뒠; ) HANGUL SYLLABLE DWEK
+B4A1;B4A1;1103 1170 11C0;B4A1;1103 1170 11C0; # (뒡; 뒡; 뒡; 뒡; 뒡; ) HANGUL SYLLABLE DWET
+B4A2;B4A2;1103 1170 11C1;B4A2;1103 1170 11C1; # (뒢; 뒢; 뒢; 뒢; 뒢; ) HANGUL SYLLABLE DWEP
+B4A3;B4A3;1103 1170 11C2;B4A3;1103 1170 11C2; # (뒣; 뒣; 뒣; 뒣; 뒣; ) HANGUL SYLLABLE DWEH
+B4A4;B4A4;1103 1171;B4A4;1103 1171; # (뒤; 뒤; 뒤; 뒤; 뒤; ) HANGUL SYLLABLE DWI
+B4A5;B4A5;1103 1171 11A8;B4A5;1103 1171 11A8; # (뒥; 뒥; 뒥; 뒥; 뒥; ) HANGUL SYLLABLE DWIG
+B4A6;B4A6;1103 1171 11A9;B4A6;1103 1171 11A9; # (뒦; 뒦; 뒦; 뒦; 뒦; ) HANGUL SYLLABLE DWIGG
+B4A7;B4A7;1103 1171 11AA;B4A7;1103 1171 11AA; # (뒧; 뒧; 뒧; 뒧; 뒧; ) HANGUL SYLLABLE DWIGS
+B4A8;B4A8;1103 1171 11AB;B4A8;1103 1171 11AB; # (뒨; 뒨; 뒨; 뒨; 뒨; ) HANGUL SYLLABLE DWIN
+B4A9;B4A9;1103 1171 11AC;B4A9;1103 1171 11AC; # (뒩; 뒩; 뒩; 뒩; 뒩; ) HANGUL SYLLABLE DWINJ
+B4AA;B4AA;1103 1171 11AD;B4AA;1103 1171 11AD; # (뒪; 뒪; 뒪; 뒪; 뒪; ) HANGUL SYLLABLE DWINH
+B4AB;B4AB;1103 1171 11AE;B4AB;1103 1171 11AE; # (뒫; 뒫; 뒫; 뒫; 뒫; ) HANGUL SYLLABLE DWID
+B4AC;B4AC;1103 1171 11AF;B4AC;1103 1171 11AF; # (뒬; 뒬; 뒬; 뒬; 뒬; ) HANGUL SYLLABLE DWIL
+B4AD;B4AD;1103 1171 11B0;B4AD;1103 1171 11B0; # (뒭; 뒭; 뒭; 뒭; 뒭; ) HANGUL SYLLABLE DWILG
+B4AE;B4AE;1103 1171 11B1;B4AE;1103 1171 11B1; # (뒮; 뒮; 뒮; 뒮; 뒮; ) HANGUL SYLLABLE DWILM
+B4AF;B4AF;1103 1171 11B2;B4AF;1103 1171 11B2; # (뒯; 뒯; 뒯; 뒯; 뒯; ) HANGUL SYLLABLE DWILB
+B4B0;B4B0;1103 1171 11B3;B4B0;1103 1171 11B3; # (뒰; 뒰; 뒰; 뒰; 뒰; ) HANGUL SYLLABLE DWILS
+B4B1;B4B1;1103 1171 11B4;B4B1;1103 1171 11B4; # (뒱; 뒱; 뒱; 뒱; 뒱; ) HANGUL SYLLABLE DWILT
+B4B2;B4B2;1103 1171 11B5;B4B2;1103 1171 11B5; # (뒲; 뒲; 뒲; 뒲; 뒲; ) HANGUL SYLLABLE DWILP
+B4B3;B4B3;1103 1171 11B6;B4B3;1103 1171 11B6; # (뒳; 뒳; 뒳; 뒳; 뒳; ) HANGUL SYLLABLE DWILH
+B4B4;B4B4;1103 1171 11B7;B4B4;1103 1171 11B7; # (뒴; 뒴; 뒴; 뒴; 뒴; ) HANGUL SYLLABLE DWIM
+B4B5;B4B5;1103 1171 11B8;B4B5;1103 1171 11B8; # (뒵; 뒵; 뒵; 뒵; 뒵; ) HANGUL SYLLABLE DWIB
+B4B6;B4B6;1103 1171 11B9;B4B6;1103 1171 11B9; # (뒶; 뒶; 뒶; 뒶; 뒶; ) HANGUL SYLLABLE DWIBS
+B4B7;B4B7;1103 1171 11BA;B4B7;1103 1171 11BA; # (뒷; 뒷; 뒷; 뒷; 뒷; ) HANGUL SYLLABLE DWIS
+B4B8;B4B8;1103 1171 11BB;B4B8;1103 1171 11BB; # (뒸; 뒸; 뒸; 뒸; 뒸; ) HANGUL SYLLABLE DWISS
+B4B9;B4B9;1103 1171 11BC;B4B9;1103 1171 11BC; # (뒹; 뒹; 뒹; 뒹; 뒹; ) HANGUL SYLLABLE DWING
+B4BA;B4BA;1103 1171 11BD;B4BA;1103 1171 11BD; # (뒺; 뒺; 뒺; 뒺; 뒺; ) HANGUL SYLLABLE DWIJ
+B4BB;B4BB;1103 1171 11BE;B4BB;1103 1171 11BE; # (뒻; 뒻; 뒻; 뒻; 뒻; ) HANGUL SYLLABLE DWIC
+B4BC;B4BC;1103 1171 11BF;B4BC;1103 1171 11BF; # (뒼; 뒼; 뒼; 뒼; 뒼; ) HANGUL SYLLABLE DWIK
+B4BD;B4BD;1103 1171 11C0;B4BD;1103 1171 11C0; # (뒽; 뒽; 뒽; 뒽; 뒽; ) HANGUL SYLLABLE DWIT
+B4BE;B4BE;1103 1171 11C1;B4BE;1103 1171 11C1; # (뒾; 뒾; 뒾; 뒾; 뒾; ) HANGUL SYLLABLE DWIP
+B4BF;B4BF;1103 1171 11C2;B4BF;1103 1171 11C2; # (뒿; 뒿; 뒿; 뒿; 뒿; ) HANGUL SYLLABLE DWIH
+B4C0;B4C0;1103 1172;B4C0;1103 1172; # (듀; 듀; 듀; 듀; 듀; ) HANGUL SYLLABLE DYU
+B4C1;B4C1;1103 1172 11A8;B4C1;1103 1172 11A8; # (듁; 듁; 듁; 듁; 듁; ) HANGUL SYLLABLE DYUG
+B4C2;B4C2;1103 1172 11A9;B4C2;1103 1172 11A9; # (듂; 듂; 듂; 듂; 듂; ) HANGUL SYLLABLE DYUGG
+B4C3;B4C3;1103 1172 11AA;B4C3;1103 1172 11AA; # (듃; 듃; 듃; 듃; 듃; ) HANGUL SYLLABLE DYUGS
+B4C4;B4C4;1103 1172 11AB;B4C4;1103 1172 11AB; # (듄; 듄; 듄; 듄; 듄; ) HANGUL SYLLABLE DYUN
+B4C5;B4C5;1103 1172 11AC;B4C5;1103 1172 11AC; # (듅; 듅; 듅; 듅; 듅; ) HANGUL SYLLABLE DYUNJ
+B4C6;B4C6;1103 1172 11AD;B4C6;1103 1172 11AD; # (듆; 듆; 듆; 듆; 듆; ) HANGUL SYLLABLE DYUNH
+B4C7;B4C7;1103 1172 11AE;B4C7;1103 1172 11AE; # (듇; 듇; 듇; 듇; 듇; ) HANGUL SYLLABLE DYUD
+B4C8;B4C8;1103 1172 11AF;B4C8;1103 1172 11AF; # (듈; 듈; 듈; 듈; 듈; ) HANGUL SYLLABLE DYUL
+B4C9;B4C9;1103 1172 11B0;B4C9;1103 1172 11B0; # (듉; 듉; 듉; 듉; 듉; ) HANGUL SYLLABLE DYULG
+B4CA;B4CA;1103 1172 11B1;B4CA;1103 1172 11B1; # (듊; 듊; 듊; 듊; 듊; ) HANGUL SYLLABLE DYULM
+B4CB;B4CB;1103 1172 11B2;B4CB;1103 1172 11B2; # (듋; 듋; 듋; 듋; 듋; ) HANGUL SYLLABLE DYULB
+B4CC;B4CC;1103 1172 11B3;B4CC;1103 1172 11B3; # (듌; 듌; 듌; 듌; 듌; ) HANGUL SYLLABLE DYULS
+B4CD;B4CD;1103 1172 11B4;B4CD;1103 1172 11B4; # (듍; 듍; 듍; 듍; 듍; ) HANGUL SYLLABLE DYULT
+B4CE;B4CE;1103 1172 11B5;B4CE;1103 1172 11B5; # (듎; 듎; 듎; 듎; 듎; ) HANGUL SYLLABLE DYULP
+B4CF;B4CF;1103 1172 11B6;B4CF;1103 1172 11B6; # (듏; 듏; 듏; 듏; 듏; ) HANGUL SYLLABLE DYULH
+B4D0;B4D0;1103 1172 11B7;B4D0;1103 1172 11B7; # (듐; 듐; 듐; 듐; 듐; ) HANGUL SYLLABLE DYUM
+B4D1;B4D1;1103 1172 11B8;B4D1;1103 1172 11B8; # (듑; 듑; 듑; 듑; 듑; ) HANGUL SYLLABLE DYUB
+B4D2;B4D2;1103 1172 11B9;B4D2;1103 1172 11B9; # (듒; 듒; 듒; 듒; 듒; ) HANGUL SYLLABLE DYUBS
+B4D3;B4D3;1103 1172 11BA;B4D3;1103 1172 11BA; # (듓; 듓; 듓; 듓; 듓; ) HANGUL SYLLABLE DYUS
+B4D4;B4D4;1103 1172 11BB;B4D4;1103 1172 11BB; # (듔; 듔; 듔; 듔; 듔; ) HANGUL SYLLABLE DYUSS
+B4D5;B4D5;1103 1172 11BC;B4D5;1103 1172 11BC; # (듕; 듕; 듕; 듕; 듕; ) HANGUL SYLLABLE DYUNG
+B4D6;B4D6;1103 1172 11BD;B4D6;1103 1172 11BD; # (듖; 듖; 듖; 듖; 듖; ) HANGUL SYLLABLE DYUJ
+B4D7;B4D7;1103 1172 11BE;B4D7;1103 1172 11BE; # (듗; 듗; 듗; 듗; 듗; ) HANGUL SYLLABLE DYUC
+B4D8;B4D8;1103 1172 11BF;B4D8;1103 1172 11BF; # (듘; 듘; 듘; 듘; 듘; ) HANGUL SYLLABLE DYUK
+B4D9;B4D9;1103 1172 11C0;B4D9;1103 1172 11C0; # (듙; 듙; 듙; 듙; 듙; ) HANGUL SYLLABLE DYUT
+B4DA;B4DA;1103 1172 11C1;B4DA;1103 1172 11C1; # (듚; 듚; 듚; 듚; 듚; ) HANGUL SYLLABLE DYUP
+B4DB;B4DB;1103 1172 11C2;B4DB;1103 1172 11C2; # (듛; 듛; 듛; 듛; 듛; ) HANGUL SYLLABLE DYUH
+B4DC;B4DC;1103 1173;B4DC;1103 1173; # (드; 드; 드; 드; 드; ) HANGUL SYLLABLE DEU
+B4DD;B4DD;1103 1173 11A8;B4DD;1103 1173 11A8; # (득; 득; 득; 득; 득; ) HANGUL SYLLABLE DEUG
+B4DE;B4DE;1103 1173 11A9;B4DE;1103 1173 11A9; # (듞; 듞; 듞; 듞; 듞; ) HANGUL SYLLABLE DEUGG
+B4DF;B4DF;1103 1173 11AA;B4DF;1103 1173 11AA; # (듟; 듟; 듟; 듟; 듟; ) HANGUL SYLLABLE DEUGS
+B4E0;B4E0;1103 1173 11AB;B4E0;1103 1173 11AB; # (든; 든; 든; 든; 든; ) HANGUL SYLLABLE DEUN
+B4E1;B4E1;1103 1173 11AC;B4E1;1103 1173 11AC; # (듡; 듡; 듡; 듡; 듡; ) HANGUL SYLLABLE DEUNJ
+B4E2;B4E2;1103 1173 11AD;B4E2;1103 1173 11AD; # (듢; 듢; 듢; 듢; 듢; ) HANGUL SYLLABLE DEUNH
+B4E3;B4E3;1103 1173 11AE;B4E3;1103 1173 11AE; # (듣; 듣; 듣; 듣; 듣; ) HANGUL SYLLABLE DEUD
+B4E4;B4E4;1103 1173 11AF;B4E4;1103 1173 11AF; # (들; 들; 들; 들; 들; ) HANGUL SYLLABLE DEUL
+B4E5;B4E5;1103 1173 11B0;B4E5;1103 1173 11B0; # (듥; 듥; 듥; 듥; 듥; ) HANGUL SYLLABLE DEULG
+B4E6;B4E6;1103 1173 11B1;B4E6;1103 1173 11B1; # (듦; 듦; 듦; 듦; 듦; ) HANGUL SYLLABLE DEULM
+B4E7;B4E7;1103 1173 11B2;B4E7;1103 1173 11B2; # (듧; 듧; 듧; 듧; 듧; ) HANGUL SYLLABLE DEULB
+B4E8;B4E8;1103 1173 11B3;B4E8;1103 1173 11B3; # (듨; 듨; 듨; 듨; 듨; ) HANGUL SYLLABLE DEULS
+B4E9;B4E9;1103 1173 11B4;B4E9;1103 1173 11B4; # (듩; 듩; 듩; 듩; 듩; ) HANGUL SYLLABLE DEULT
+B4EA;B4EA;1103 1173 11B5;B4EA;1103 1173 11B5; # (듪; 듪; 듪; 듪; 듪; ) HANGUL SYLLABLE DEULP
+B4EB;B4EB;1103 1173 11B6;B4EB;1103 1173 11B6; # (듫; 듫; 듫; 듫; 듫; ) HANGUL SYLLABLE DEULH
+B4EC;B4EC;1103 1173 11B7;B4EC;1103 1173 11B7; # (듬; 듬; 듬; 듬; 듬; ) HANGUL SYLLABLE DEUM
+B4ED;B4ED;1103 1173 11B8;B4ED;1103 1173 11B8; # (듭; 듭; 듭; 듭; 듭; ) HANGUL SYLLABLE DEUB
+B4EE;B4EE;1103 1173 11B9;B4EE;1103 1173 11B9; # (듮; 듮; 듮; 듮; 듮; ) HANGUL SYLLABLE DEUBS
+B4EF;B4EF;1103 1173 11BA;B4EF;1103 1173 11BA; # (듯; 듯; 듯; 듯; 듯; ) HANGUL SYLLABLE DEUS
+B4F0;B4F0;1103 1173 11BB;B4F0;1103 1173 11BB; # (듰; 듰; 듰; 듰; 듰; ) HANGUL SYLLABLE DEUSS
+B4F1;B4F1;1103 1173 11BC;B4F1;1103 1173 11BC; # (등; 등; 등; 등; 등; ) HANGUL SYLLABLE DEUNG
+B4F2;B4F2;1103 1173 11BD;B4F2;1103 1173 11BD; # (듲; 듲; 듲; 듲; 듲; ) HANGUL SYLLABLE DEUJ
+B4F3;B4F3;1103 1173 11BE;B4F3;1103 1173 11BE; # (듳; 듳; 듳; 듳; 듳; ) HANGUL SYLLABLE DEUC
+B4F4;B4F4;1103 1173 11BF;B4F4;1103 1173 11BF; # (듴; 듴; 듴; 듴; 듴; ) HANGUL SYLLABLE DEUK
+B4F5;B4F5;1103 1173 11C0;B4F5;1103 1173 11C0; # (듵; 듵; 듵; 듵; 듵; ) HANGUL SYLLABLE DEUT
+B4F6;B4F6;1103 1173 11C1;B4F6;1103 1173 11C1; # (듶; 듶; 듶; 듶; 듶; ) HANGUL SYLLABLE DEUP
+B4F7;B4F7;1103 1173 11C2;B4F7;1103 1173 11C2; # (듷; 듷; 듷; 듷; 듷; ) HANGUL SYLLABLE DEUH
+B4F8;B4F8;1103 1174;B4F8;1103 1174; # (듸; 듸; 듸; 듸; 듸; ) HANGUL SYLLABLE DYI
+B4F9;B4F9;1103 1174 11A8;B4F9;1103 1174 11A8; # (듹; 듹; 듹; 듹; 듹; ) HANGUL SYLLABLE DYIG
+B4FA;B4FA;1103 1174 11A9;B4FA;1103 1174 11A9; # (듺; 듺; 듺; 듺; 듺; ) HANGUL SYLLABLE DYIGG
+B4FB;B4FB;1103 1174 11AA;B4FB;1103 1174 11AA; # (듻; 듻; 듻; 듻; 듻; ) HANGUL SYLLABLE DYIGS
+B4FC;B4FC;1103 1174 11AB;B4FC;1103 1174 11AB; # (듼; 듼; 듼; 듼; 듼; ) HANGUL SYLLABLE DYIN
+B4FD;B4FD;1103 1174 11AC;B4FD;1103 1174 11AC; # (듽; 듽; 듽; 듽; 듽; ) HANGUL SYLLABLE DYINJ
+B4FE;B4FE;1103 1174 11AD;B4FE;1103 1174 11AD; # (듾; 듾; 듾; 듾; 듾; ) HANGUL SYLLABLE DYINH
+B4FF;B4FF;1103 1174 11AE;B4FF;1103 1174 11AE; # (듿; 듿; 듿; 듿; 듿; ) HANGUL SYLLABLE DYID
+B500;B500;1103 1174 11AF;B500;1103 1174 11AF; # (딀; 딀; 딀; 딀; 딀; ) HANGUL SYLLABLE DYIL
+B501;B501;1103 1174 11B0;B501;1103 1174 11B0; # (딁; 딁; 딁; 딁; 딁; ) HANGUL SYLLABLE DYILG
+B502;B502;1103 1174 11B1;B502;1103 1174 11B1; # (딂; 딂; 딂; 딂; 딂; ) HANGUL SYLLABLE DYILM
+B503;B503;1103 1174 11B2;B503;1103 1174 11B2; # (딃; 딃; 딃; 딃; 딃; ) HANGUL SYLLABLE DYILB
+B504;B504;1103 1174 11B3;B504;1103 1174 11B3; # (딄; 딄; 딄; 딄; 딄; ) HANGUL SYLLABLE DYILS
+B505;B505;1103 1174 11B4;B505;1103 1174 11B4; # (딅; 딅; 딅; 딅; 딅; ) HANGUL SYLLABLE DYILT
+B506;B506;1103 1174 11B5;B506;1103 1174 11B5; # (딆; 딆; 딆; 딆; 딆; ) HANGUL SYLLABLE DYILP
+B507;B507;1103 1174 11B6;B507;1103 1174 11B6; # (딇; 딇; 딇; 딇; 딇; ) HANGUL SYLLABLE DYILH
+B508;B508;1103 1174 11B7;B508;1103 1174 11B7; # (딈; 딈; 딈; 딈; 딈; ) HANGUL SYLLABLE DYIM
+B509;B509;1103 1174 11B8;B509;1103 1174 11B8; # (딉; 딉; 딉; 딉; 딉; ) HANGUL SYLLABLE DYIB
+B50A;B50A;1103 1174 11B9;B50A;1103 1174 11B9; # (딊; 딊; 딊; 딊; 딊; ) HANGUL SYLLABLE DYIBS
+B50B;B50B;1103 1174 11BA;B50B;1103 1174 11BA; # (딋; 딋; 딋; 딋; 딋; ) HANGUL SYLLABLE DYIS
+B50C;B50C;1103 1174 11BB;B50C;1103 1174 11BB; # (딌; 딌; 딌; 딌; 딌; ) HANGUL SYLLABLE DYISS
+B50D;B50D;1103 1174 11BC;B50D;1103 1174 11BC; # (딍; 딍; 딍; 딍; 딍; ) HANGUL SYLLABLE DYING
+B50E;B50E;1103 1174 11BD;B50E;1103 1174 11BD; # (딎; 딎; 딎; 딎; 딎; ) HANGUL SYLLABLE DYIJ
+B50F;B50F;1103 1174 11BE;B50F;1103 1174 11BE; # (딏; 딏; 딏; 딏; 딏; ) HANGUL SYLLABLE DYIC
+B510;B510;1103 1174 11BF;B510;1103 1174 11BF; # (딐; 딐; 딐; 딐; 딐; ) HANGUL SYLLABLE DYIK
+B511;B511;1103 1174 11C0;B511;1103 1174 11C0; # (딑; 딑; 딑; 딑; 딑; ) HANGUL SYLLABLE DYIT
+B512;B512;1103 1174 11C1;B512;1103 1174 11C1; # (딒; 딒; 딒; 딒; 딒; ) HANGUL SYLLABLE DYIP
+B513;B513;1103 1174 11C2;B513;1103 1174 11C2; # (딓; 딓; 딓; 딓; 딓; ) HANGUL SYLLABLE DYIH
+B514;B514;1103 1175;B514;1103 1175; # (디; 디; 디; 디; 디; ) HANGUL SYLLABLE DI
+B515;B515;1103 1175 11A8;B515;1103 1175 11A8; # (딕; 딕; 딕; 딕; 딕; ) HANGUL SYLLABLE DIG
+B516;B516;1103 1175 11A9;B516;1103 1175 11A9; # (딖; 딖; 딖; 딖; 딖; ) HANGUL SYLLABLE DIGG
+B517;B517;1103 1175 11AA;B517;1103 1175 11AA; # (딗; 딗; 딗; 딗; 딗; ) HANGUL SYLLABLE DIGS
+B518;B518;1103 1175 11AB;B518;1103 1175 11AB; # (딘; 딘; 딘; 딘; 딘; ) HANGUL SYLLABLE DIN
+B519;B519;1103 1175 11AC;B519;1103 1175 11AC; # (딙; 딙; 딙; 딙; 딙; ) HANGUL SYLLABLE DINJ
+B51A;B51A;1103 1175 11AD;B51A;1103 1175 11AD; # (딚; 딚; 딚; 딚; 딚; ) HANGUL SYLLABLE DINH
+B51B;B51B;1103 1175 11AE;B51B;1103 1175 11AE; # (딛; 딛; 딛; 딛; 딛; ) HANGUL SYLLABLE DID
+B51C;B51C;1103 1175 11AF;B51C;1103 1175 11AF; # (딜; 딜; 딜; 딜; 딜; ) HANGUL SYLLABLE DIL
+B51D;B51D;1103 1175 11B0;B51D;1103 1175 11B0; # (딝; 딝; 딝; 딝; 딝; ) HANGUL SYLLABLE DILG
+B51E;B51E;1103 1175 11B1;B51E;1103 1175 11B1; # (딞; 딞; 딞; 딞; 딞; ) HANGUL SYLLABLE DILM
+B51F;B51F;1103 1175 11B2;B51F;1103 1175 11B2; # (딟; 딟; 딟; 딟; 딟; ) HANGUL SYLLABLE DILB
+B520;B520;1103 1175 11B3;B520;1103 1175 11B3; # (딠; 딠; 딠; 딠; 딠; ) HANGUL SYLLABLE DILS
+B521;B521;1103 1175 11B4;B521;1103 1175 11B4; # (딡; 딡; 딡; 딡; 딡; ) HANGUL SYLLABLE DILT
+B522;B522;1103 1175 11B5;B522;1103 1175 11B5; # (딢; 딢; 딢; 딢; 딢; ) HANGUL SYLLABLE DILP
+B523;B523;1103 1175 11B6;B523;1103 1175 11B6; # (딣; 딣; 딣; 딣; 딣; ) HANGUL SYLLABLE DILH
+B524;B524;1103 1175 11B7;B524;1103 1175 11B7; # (딤; 딤; 딤; 딤; 딤; ) HANGUL SYLLABLE DIM
+B525;B525;1103 1175 11B8;B525;1103 1175 11B8; # (딥; 딥; 딥; 딥; 딥; ) HANGUL SYLLABLE DIB
+B526;B526;1103 1175 11B9;B526;1103 1175 11B9; # (딦; 딦; 딦; 딦; 딦; ) HANGUL SYLLABLE DIBS
+B527;B527;1103 1175 11BA;B527;1103 1175 11BA; # (딧; 딧; 딧; 딧; 딧; ) HANGUL SYLLABLE DIS
+B528;B528;1103 1175 11BB;B528;1103 1175 11BB; # (딨; 딨; 딨; 딨; 딨; ) HANGUL SYLLABLE DISS
+B529;B529;1103 1175 11BC;B529;1103 1175 11BC; # (딩; 딩; 딩; 딩; 딩; ) HANGUL SYLLABLE DING
+B52A;B52A;1103 1175 11BD;B52A;1103 1175 11BD; # (딪; 딪; 딪; 딪; 딪; ) HANGUL SYLLABLE DIJ
+B52B;B52B;1103 1175 11BE;B52B;1103 1175 11BE; # (딫; 딫; 딫; 딫; 딫; ) HANGUL SYLLABLE DIC
+B52C;B52C;1103 1175 11BF;B52C;1103 1175 11BF; # (딬; 딬; 딬; 딬; 딬; ) HANGUL SYLLABLE DIK
+B52D;B52D;1103 1175 11C0;B52D;1103 1175 11C0; # (딭; 딭; 딭; 딭; 딭; ) HANGUL SYLLABLE DIT
+B52E;B52E;1103 1175 11C1;B52E;1103 1175 11C1; # (딮; 딮; 딮; 딮; 딮; ) HANGUL SYLLABLE DIP
+B52F;B52F;1103 1175 11C2;B52F;1103 1175 11C2; # (딯; 딯; 딯; 딯; 딯; ) HANGUL SYLLABLE DIH
+B530;B530;1104 1161;B530;1104 1161; # (따; 따; 따; 따; 따; ) HANGUL SYLLABLE DDA
+B531;B531;1104 1161 11A8;B531;1104 1161 11A8; # (딱; 딱; 딱; 딱; 딱; ) HANGUL SYLLABLE DDAG
+B532;B532;1104 1161 11A9;B532;1104 1161 11A9; # (딲; 딲; 딲; 딲; 딲; ) HANGUL SYLLABLE DDAGG
+B533;B533;1104 1161 11AA;B533;1104 1161 11AA; # (딳; 딳; 딳; 딳; 딳; ) HANGUL SYLLABLE DDAGS
+B534;B534;1104 1161 11AB;B534;1104 1161 11AB; # (딴; 딴; 딴; 딴; 딴; ) HANGUL SYLLABLE DDAN
+B535;B535;1104 1161 11AC;B535;1104 1161 11AC; # (딵; 딵; 딵; 딵; 딵; ) HANGUL SYLLABLE DDANJ
+B536;B536;1104 1161 11AD;B536;1104 1161 11AD; # (딶; 딶; 딶; 딶; 딶; ) HANGUL SYLLABLE DDANH
+B537;B537;1104 1161 11AE;B537;1104 1161 11AE; # (딷; 딷; 딷; 딷; 딷; ) HANGUL SYLLABLE DDAD
+B538;B538;1104 1161 11AF;B538;1104 1161 11AF; # (딸; 딸; 딸; 딸; 딸; ) HANGUL SYLLABLE DDAL
+B539;B539;1104 1161 11B0;B539;1104 1161 11B0; # (딹; 딹; 딹; 딹; 딹; ) HANGUL SYLLABLE DDALG
+B53A;B53A;1104 1161 11B1;B53A;1104 1161 11B1; # (딺; 딺; 딺; 딺; 딺; ) HANGUL SYLLABLE DDALM
+B53B;B53B;1104 1161 11B2;B53B;1104 1161 11B2; # (딻; 딻; 딻; 딻; 딻; ) HANGUL SYLLABLE DDALB
+B53C;B53C;1104 1161 11B3;B53C;1104 1161 11B3; # (딼; 딼; 딼; 딼; 딼; ) HANGUL SYLLABLE DDALS
+B53D;B53D;1104 1161 11B4;B53D;1104 1161 11B4; # (딽; 딽; 딽; 딽; 딽; ) HANGUL SYLLABLE DDALT
+B53E;B53E;1104 1161 11B5;B53E;1104 1161 11B5; # (딾; 딾; 딾; 딾; 딾; ) HANGUL SYLLABLE DDALP
+B53F;B53F;1104 1161 11B6;B53F;1104 1161 11B6; # (딿; 딿; 딿; 딿; 딿; ) HANGUL SYLLABLE DDALH
+B540;B540;1104 1161 11B7;B540;1104 1161 11B7; # (땀; 땀; 땀; 땀; 땀; ) HANGUL SYLLABLE DDAM
+B541;B541;1104 1161 11B8;B541;1104 1161 11B8; # (땁; 땁; 땁; 땁; 땁; ) HANGUL SYLLABLE DDAB
+B542;B542;1104 1161 11B9;B542;1104 1161 11B9; # (땂; 땂; 땂; 땂; 땂; ) HANGUL SYLLABLE DDABS
+B543;B543;1104 1161 11BA;B543;1104 1161 11BA; # (땃; 땃; 땃; 땃; 땃; ) HANGUL SYLLABLE DDAS
+B544;B544;1104 1161 11BB;B544;1104 1161 11BB; # (땄; 땄; 땄; 땄; 땄; ) HANGUL SYLLABLE DDASS
+B545;B545;1104 1161 11BC;B545;1104 1161 11BC; # (땅; 땅; 땅; 땅; 땅; ) HANGUL SYLLABLE DDANG
+B546;B546;1104 1161 11BD;B546;1104 1161 11BD; # (땆; 땆; 땆; 땆; 땆; ) HANGUL SYLLABLE DDAJ
+B547;B547;1104 1161 11BE;B547;1104 1161 11BE; # (땇; 땇; 땇; 땇; 땇; ) HANGUL SYLLABLE DDAC
+B548;B548;1104 1161 11BF;B548;1104 1161 11BF; # (땈; 땈; 땈; 땈; 땈; ) HANGUL SYLLABLE DDAK
+B549;B549;1104 1161 11C0;B549;1104 1161 11C0; # (땉; 땉; 땉; 땉; 땉; ) HANGUL SYLLABLE DDAT
+B54A;B54A;1104 1161 11C1;B54A;1104 1161 11C1; # (땊; 땊; 땊; 땊; 땊; ) HANGUL SYLLABLE DDAP
+B54B;B54B;1104 1161 11C2;B54B;1104 1161 11C2; # (땋; 땋; 땋; 땋; 땋; ) HANGUL SYLLABLE DDAH
+B54C;B54C;1104 1162;B54C;1104 1162; # (때; 때; 때; 때; 때; ) HANGUL SYLLABLE DDAE
+B54D;B54D;1104 1162 11A8;B54D;1104 1162 11A8; # (땍; 땍; 땍; 땍; 땍; ) HANGUL SYLLABLE DDAEG
+B54E;B54E;1104 1162 11A9;B54E;1104 1162 11A9; # (땎; 땎; 땎; 땎; 땎; ) HANGUL SYLLABLE DDAEGG
+B54F;B54F;1104 1162 11AA;B54F;1104 1162 11AA; # (땏; 땏; 땏; 땏; 땏; ) HANGUL SYLLABLE DDAEGS
+B550;B550;1104 1162 11AB;B550;1104 1162 11AB; # (땐; 땐; 땐; 땐; 땐; ) HANGUL SYLLABLE DDAEN
+B551;B551;1104 1162 11AC;B551;1104 1162 11AC; # (땑; 땑; 땑; 땑; 땑; ) HANGUL SYLLABLE DDAENJ
+B552;B552;1104 1162 11AD;B552;1104 1162 11AD; # (땒; 땒; 땒; 땒; 땒; ) HANGUL SYLLABLE DDAENH
+B553;B553;1104 1162 11AE;B553;1104 1162 11AE; # (땓; 땓; 땓; 땓; 땓; ) HANGUL SYLLABLE DDAED
+B554;B554;1104 1162 11AF;B554;1104 1162 11AF; # (땔; 땔; 땔; 땔; 땔; ) HANGUL SYLLABLE DDAEL
+B555;B555;1104 1162 11B0;B555;1104 1162 11B0; # (땕; 땕; 땕; 땕; 땕; ) HANGUL SYLLABLE DDAELG
+B556;B556;1104 1162 11B1;B556;1104 1162 11B1; # (땖; 땖; 땖; 땖; 땖; ) HANGUL SYLLABLE DDAELM
+B557;B557;1104 1162 11B2;B557;1104 1162 11B2; # (땗; 땗; 땗; 땗; 땗; ) HANGUL SYLLABLE DDAELB
+B558;B558;1104 1162 11B3;B558;1104 1162 11B3; # (땘; 땘; 땘; 땘; 땘; ) HANGUL SYLLABLE DDAELS
+B559;B559;1104 1162 11B4;B559;1104 1162 11B4; # (땙; 땙; 땙; 땙; 땙; ) HANGUL SYLLABLE DDAELT
+B55A;B55A;1104 1162 11B5;B55A;1104 1162 11B5; # (땚; 땚; 땚; 땚; 땚; ) HANGUL SYLLABLE DDAELP
+B55B;B55B;1104 1162 11B6;B55B;1104 1162 11B6; # (땛; 땛; 땛; 땛; 땛; ) HANGUL SYLLABLE DDAELH
+B55C;B55C;1104 1162 11B7;B55C;1104 1162 11B7; # (땜; 땜; 땜; 땜; 땜; ) HANGUL SYLLABLE DDAEM
+B55D;B55D;1104 1162 11B8;B55D;1104 1162 11B8; # (땝; 땝; 땝; 땝; 땝; ) HANGUL SYLLABLE DDAEB
+B55E;B55E;1104 1162 11B9;B55E;1104 1162 11B9; # (땞; 땞; 땞; 땞; 땞; ) HANGUL SYLLABLE DDAEBS
+B55F;B55F;1104 1162 11BA;B55F;1104 1162 11BA; # (땟; 땟; 땟; 땟; 땟; ) HANGUL SYLLABLE DDAES
+B560;B560;1104 1162 11BB;B560;1104 1162 11BB; # (땠; 땠; 땠; 땠; 땠; ) HANGUL SYLLABLE DDAESS
+B561;B561;1104 1162 11BC;B561;1104 1162 11BC; # (땡; 땡; 땡; 땡; 땡; ) HANGUL SYLLABLE DDAENG
+B562;B562;1104 1162 11BD;B562;1104 1162 11BD; # (땢; 땢; 땢; 땢; 땢; ) HANGUL SYLLABLE DDAEJ
+B563;B563;1104 1162 11BE;B563;1104 1162 11BE; # (땣; 땣; 땣; 땣; 땣; ) HANGUL SYLLABLE DDAEC
+B564;B564;1104 1162 11BF;B564;1104 1162 11BF; # (땤; 땤; 땤; 땤; 땤; ) HANGUL SYLLABLE DDAEK
+B565;B565;1104 1162 11C0;B565;1104 1162 11C0; # (땥; 땥; 땥; 땥; 땥; ) HANGUL SYLLABLE DDAET
+B566;B566;1104 1162 11C1;B566;1104 1162 11C1; # (땦; 땦; 땦; 땦; 땦; ) HANGUL SYLLABLE DDAEP
+B567;B567;1104 1162 11C2;B567;1104 1162 11C2; # (땧; 땧; 땧; 땧; 땧; ) HANGUL SYLLABLE DDAEH
+B568;B568;1104 1163;B568;1104 1163; # (땨; 땨; 땨; 땨; 땨; ) HANGUL SYLLABLE DDYA
+B569;B569;1104 1163 11A8;B569;1104 1163 11A8; # (땩; 땩; 땩; 땩; 땩; ) HANGUL SYLLABLE DDYAG
+B56A;B56A;1104 1163 11A9;B56A;1104 1163 11A9; # (땪; 땪; 땪; 땪; 땪; ) HANGUL SYLLABLE DDYAGG
+B56B;B56B;1104 1163 11AA;B56B;1104 1163 11AA; # (땫; 땫; 땫; 땫; 땫; ) HANGUL SYLLABLE DDYAGS
+B56C;B56C;1104 1163 11AB;B56C;1104 1163 11AB; # (땬; 땬; 땬; 땬; 땬; ) HANGUL SYLLABLE DDYAN
+B56D;B56D;1104 1163 11AC;B56D;1104 1163 11AC; # (땭; 땭; 땭; 땭; 땭; ) HANGUL SYLLABLE DDYANJ
+B56E;B56E;1104 1163 11AD;B56E;1104 1163 11AD; # (땮; 땮; 땮; 땮; 땮; ) HANGUL SYLLABLE DDYANH
+B56F;B56F;1104 1163 11AE;B56F;1104 1163 11AE; # (땯; 땯; 땯; 땯; 땯; ) HANGUL SYLLABLE DDYAD
+B570;B570;1104 1163 11AF;B570;1104 1163 11AF; # (땰; 땰; 땰; 땰; 땰; ) HANGUL SYLLABLE DDYAL
+B571;B571;1104 1163 11B0;B571;1104 1163 11B0; # (땱; 땱; 땱; 땱; 땱; ) HANGUL SYLLABLE DDYALG
+B572;B572;1104 1163 11B1;B572;1104 1163 11B1; # (땲; 땲; 땲; 땲; 땲; ) HANGUL SYLLABLE DDYALM
+B573;B573;1104 1163 11B2;B573;1104 1163 11B2; # (땳; 땳; 땳; 땳; 땳; ) HANGUL SYLLABLE DDYALB
+B574;B574;1104 1163 11B3;B574;1104 1163 11B3; # (땴; 땴; 땴; 땴; 땴; ) HANGUL SYLLABLE DDYALS
+B575;B575;1104 1163 11B4;B575;1104 1163 11B4; # (땵; 땵; 땵; 땵; 땵; ) HANGUL SYLLABLE DDYALT
+B576;B576;1104 1163 11B5;B576;1104 1163 11B5; # (땶; 땶; 땶; 땶; 땶; ) HANGUL SYLLABLE DDYALP
+B577;B577;1104 1163 11B6;B577;1104 1163 11B6; # (땷; 땷; 땷; 땷; 땷; ) HANGUL SYLLABLE DDYALH
+B578;B578;1104 1163 11B7;B578;1104 1163 11B7; # (땸; 땸; 땸; 땸; 땸; ) HANGUL SYLLABLE DDYAM
+B579;B579;1104 1163 11B8;B579;1104 1163 11B8; # (땹; 땹; 땹; 땹; 땹; ) HANGUL SYLLABLE DDYAB
+B57A;B57A;1104 1163 11B9;B57A;1104 1163 11B9; # (땺; 땺; 땺; 땺; 땺; ) HANGUL SYLLABLE DDYABS
+B57B;B57B;1104 1163 11BA;B57B;1104 1163 11BA; # (땻; 땻; 땻; 땻; 땻; ) HANGUL SYLLABLE DDYAS
+B57C;B57C;1104 1163 11BB;B57C;1104 1163 11BB; # (땼; 땼; 땼; 땼; 땼; ) HANGUL SYLLABLE DDYASS
+B57D;B57D;1104 1163 11BC;B57D;1104 1163 11BC; # (땽; 땽; 땽; 땽; 땽; ) HANGUL SYLLABLE DDYANG
+B57E;B57E;1104 1163 11BD;B57E;1104 1163 11BD; # (땾; 땾; 땾; 땾; 땾; ) HANGUL SYLLABLE DDYAJ
+B57F;B57F;1104 1163 11BE;B57F;1104 1163 11BE; # (땿; 땿; 땿; 땿; 땿; ) HANGUL SYLLABLE DDYAC
+B580;B580;1104 1163 11BF;B580;1104 1163 11BF; # (떀; 떀; 떀; 떀; 떀; ) HANGUL SYLLABLE DDYAK
+B581;B581;1104 1163 11C0;B581;1104 1163 11C0; # (떁; 떁; 떁; 떁; 떁; ) HANGUL SYLLABLE DDYAT
+B582;B582;1104 1163 11C1;B582;1104 1163 11C1; # (떂; 떂; 떂; 떂; 떂; ) HANGUL SYLLABLE DDYAP
+B583;B583;1104 1163 11C2;B583;1104 1163 11C2; # (떃; 떃; 떃; 떃; 떃; ) HANGUL SYLLABLE DDYAH
+B584;B584;1104 1164;B584;1104 1164; # (떄; 떄; 떄; 떄; 떄; ) HANGUL SYLLABLE DDYAE
+B585;B585;1104 1164 11A8;B585;1104 1164 11A8; # (떅; 떅; 떅; 떅; 떅; ) HANGUL SYLLABLE DDYAEG
+B586;B586;1104 1164 11A9;B586;1104 1164 11A9; # (떆; 떆; 떆; 떆; 떆; ) HANGUL SYLLABLE DDYAEGG
+B587;B587;1104 1164 11AA;B587;1104 1164 11AA; # (떇; 떇; 떇; 떇; 떇; ) HANGUL SYLLABLE DDYAEGS
+B588;B588;1104 1164 11AB;B588;1104 1164 11AB; # (떈; 떈; 떈; 떈; 떈; ) HANGUL SYLLABLE DDYAEN
+B589;B589;1104 1164 11AC;B589;1104 1164 11AC; # (떉; 떉; 떉; 떉; 떉; ) HANGUL SYLLABLE DDYAENJ
+B58A;B58A;1104 1164 11AD;B58A;1104 1164 11AD; # (떊; 떊; 떊; 떊; 떊; ) HANGUL SYLLABLE DDYAENH
+B58B;B58B;1104 1164 11AE;B58B;1104 1164 11AE; # (떋; 떋; 떋; 떋; 떋; ) HANGUL SYLLABLE DDYAED
+B58C;B58C;1104 1164 11AF;B58C;1104 1164 11AF; # (떌; 떌; 떌; 떌; 떌; ) HANGUL SYLLABLE DDYAEL
+B58D;B58D;1104 1164 11B0;B58D;1104 1164 11B0; # (떍; 떍; 떍; 떍; 떍; ) HANGUL SYLLABLE DDYAELG
+B58E;B58E;1104 1164 11B1;B58E;1104 1164 11B1; # (떎; 떎; 떎; 떎; 떎; ) HANGUL SYLLABLE DDYAELM
+B58F;B58F;1104 1164 11B2;B58F;1104 1164 11B2; # (떏; 떏; 떏; 떏; 떏; ) HANGUL SYLLABLE DDYAELB
+B590;B590;1104 1164 11B3;B590;1104 1164 11B3; # (떐; 떐; 떐; 떐; 떐; ) HANGUL SYLLABLE DDYAELS
+B591;B591;1104 1164 11B4;B591;1104 1164 11B4; # (떑; 떑; 떑; 떑; 떑; ) HANGUL SYLLABLE DDYAELT
+B592;B592;1104 1164 11B5;B592;1104 1164 11B5; # (떒; 떒; 떒; 떒; 떒; ) HANGUL SYLLABLE DDYAELP
+B593;B593;1104 1164 11B6;B593;1104 1164 11B6; # (떓; 떓; 떓; 떓; 떓; ) HANGUL SYLLABLE DDYAELH
+B594;B594;1104 1164 11B7;B594;1104 1164 11B7; # (떔; 떔; 떔; 떔; 떔; ) HANGUL SYLLABLE DDYAEM
+B595;B595;1104 1164 11B8;B595;1104 1164 11B8; # (떕; 떕; 떕; 떕; 떕; ) HANGUL SYLLABLE DDYAEB
+B596;B596;1104 1164 11B9;B596;1104 1164 11B9; # (떖; 떖; 떖; 떖; 떖; ) HANGUL SYLLABLE DDYAEBS
+B597;B597;1104 1164 11BA;B597;1104 1164 11BA; # (떗; 떗; 떗; 떗; 떗; ) HANGUL SYLLABLE DDYAES
+B598;B598;1104 1164 11BB;B598;1104 1164 11BB; # (떘; 떘; 떘; 떘; 떘; ) HANGUL SYLLABLE DDYAESS
+B599;B599;1104 1164 11BC;B599;1104 1164 11BC; # (떙; 떙; 떙; 떙; 떙; ) HANGUL SYLLABLE DDYAENG
+B59A;B59A;1104 1164 11BD;B59A;1104 1164 11BD; # (떚; 떚; 떚; 떚; 떚; ) HANGUL SYLLABLE DDYAEJ
+B59B;B59B;1104 1164 11BE;B59B;1104 1164 11BE; # (떛; 떛; 떛; 떛; 떛; ) HANGUL SYLLABLE DDYAEC
+B59C;B59C;1104 1164 11BF;B59C;1104 1164 11BF; # (떜; 떜; 떜; 떜; 떜; ) HANGUL SYLLABLE DDYAEK
+B59D;B59D;1104 1164 11C0;B59D;1104 1164 11C0; # (떝; 떝; 떝; 떝; 떝; ) HANGUL SYLLABLE DDYAET
+B59E;B59E;1104 1164 11C1;B59E;1104 1164 11C1; # (떞; 떞; 떞; 떞; 떞; ) HANGUL SYLLABLE DDYAEP
+B59F;B59F;1104 1164 11C2;B59F;1104 1164 11C2; # (떟; 떟; 떟; 떟; 떟; ) HANGUL SYLLABLE DDYAEH
+B5A0;B5A0;1104 1165;B5A0;1104 1165; # (떠; 떠; 떠; 떠; 떠; ) HANGUL SYLLABLE DDEO
+B5A1;B5A1;1104 1165 11A8;B5A1;1104 1165 11A8; # (떡; 떡; 떡; 떡; 떡; ) HANGUL SYLLABLE DDEOG
+B5A2;B5A2;1104 1165 11A9;B5A2;1104 1165 11A9; # (떢; 떢; 떢; 떢; 떢; ) HANGUL SYLLABLE DDEOGG
+B5A3;B5A3;1104 1165 11AA;B5A3;1104 1165 11AA; # (떣; 떣; 떣; 떣; 떣; ) HANGUL SYLLABLE DDEOGS
+B5A4;B5A4;1104 1165 11AB;B5A4;1104 1165 11AB; # (떤; 떤; 떤; 떤; 떤; ) HANGUL SYLLABLE DDEON
+B5A5;B5A5;1104 1165 11AC;B5A5;1104 1165 11AC; # (떥; 떥; 떥; 떥; 떥; ) HANGUL SYLLABLE DDEONJ
+B5A6;B5A6;1104 1165 11AD;B5A6;1104 1165 11AD; # (떦; 떦; 떦; 떦; 떦; ) HANGUL SYLLABLE DDEONH
+B5A7;B5A7;1104 1165 11AE;B5A7;1104 1165 11AE; # (떧; 떧; 떧; 떧; 떧; ) HANGUL SYLLABLE DDEOD
+B5A8;B5A8;1104 1165 11AF;B5A8;1104 1165 11AF; # (떨; 떨; 떨; 떨; 떨; ) HANGUL SYLLABLE DDEOL
+B5A9;B5A9;1104 1165 11B0;B5A9;1104 1165 11B0; # (떩; 떩; 떩; 떩; 떩; ) HANGUL SYLLABLE DDEOLG
+B5AA;B5AA;1104 1165 11B1;B5AA;1104 1165 11B1; # (떪; 떪; 떪; 떪; 떪; ) HANGUL SYLLABLE DDEOLM
+B5AB;B5AB;1104 1165 11B2;B5AB;1104 1165 11B2; # (떫; 떫; 떫; 떫; 떫; ) HANGUL SYLLABLE DDEOLB
+B5AC;B5AC;1104 1165 11B3;B5AC;1104 1165 11B3; # (떬; 떬; 떬; 떬; 떬; ) HANGUL SYLLABLE DDEOLS
+B5AD;B5AD;1104 1165 11B4;B5AD;1104 1165 11B4; # (떭; 떭; 떭; 떭; 떭; ) HANGUL SYLLABLE DDEOLT
+B5AE;B5AE;1104 1165 11B5;B5AE;1104 1165 11B5; # (떮; 떮; 떮; 떮; 떮; ) HANGUL SYLLABLE DDEOLP
+B5AF;B5AF;1104 1165 11B6;B5AF;1104 1165 11B6; # (떯; 떯; 떯; 떯; 떯; ) HANGUL SYLLABLE DDEOLH
+B5B0;B5B0;1104 1165 11B7;B5B0;1104 1165 11B7; # (떰; 떰; 떰; 떰; 떰; ) HANGUL SYLLABLE DDEOM
+B5B1;B5B1;1104 1165 11B8;B5B1;1104 1165 11B8; # (떱; 떱; 떱; 떱; 떱; ) HANGUL SYLLABLE DDEOB
+B5B2;B5B2;1104 1165 11B9;B5B2;1104 1165 11B9; # (떲; 떲; 떲; 떲; 떲; ) HANGUL SYLLABLE DDEOBS
+B5B3;B5B3;1104 1165 11BA;B5B3;1104 1165 11BA; # (떳; 떳; 떳; 떳; 떳; ) HANGUL SYLLABLE DDEOS
+B5B4;B5B4;1104 1165 11BB;B5B4;1104 1165 11BB; # (떴; 떴; 떴; 떴; 떴; ) HANGUL SYLLABLE DDEOSS
+B5B5;B5B5;1104 1165 11BC;B5B5;1104 1165 11BC; # (떵; 떵; 떵; 떵; 떵; ) HANGUL SYLLABLE DDEONG
+B5B6;B5B6;1104 1165 11BD;B5B6;1104 1165 11BD; # (떶; 떶; 떶; 떶; 떶; ) HANGUL SYLLABLE DDEOJ
+B5B7;B5B7;1104 1165 11BE;B5B7;1104 1165 11BE; # (떷; 떷; 떷; 떷; 떷; ) HANGUL SYLLABLE DDEOC
+B5B8;B5B8;1104 1165 11BF;B5B8;1104 1165 11BF; # (떸; 떸; 떸; 떸; 떸; ) HANGUL SYLLABLE DDEOK
+B5B9;B5B9;1104 1165 11C0;B5B9;1104 1165 11C0; # (떹; 떹; 떹; 떹; 떹; ) HANGUL SYLLABLE DDEOT
+B5BA;B5BA;1104 1165 11C1;B5BA;1104 1165 11C1; # (떺; 떺; 떺; 떺; 떺; ) HANGUL SYLLABLE DDEOP
+B5BB;B5BB;1104 1165 11C2;B5BB;1104 1165 11C2; # (떻; 떻; 떻; 떻; 떻; ) HANGUL SYLLABLE DDEOH
+B5BC;B5BC;1104 1166;B5BC;1104 1166; # (떼; 떼; 떼; 떼; 떼; ) HANGUL SYLLABLE DDE
+B5BD;B5BD;1104 1166 11A8;B5BD;1104 1166 11A8; # (떽; 떽; 떽; 떽; 떽; ) HANGUL SYLLABLE DDEG
+B5BE;B5BE;1104 1166 11A9;B5BE;1104 1166 11A9; # (떾; 떾; 떾; 떾; 떾; ) HANGUL SYLLABLE DDEGG
+B5BF;B5BF;1104 1166 11AA;B5BF;1104 1166 11AA; # (떿; 떿; 떿; 떿; 떿; ) HANGUL SYLLABLE DDEGS
+B5C0;B5C0;1104 1166 11AB;B5C0;1104 1166 11AB; # (뗀; 뗀; 뗀; 뗀; 뗀; ) HANGUL SYLLABLE DDEN
+B5C1;B5C1;1104 1166 11AC;B5C1;1104 1166 11AC; # (뗁; 뗁; 뗁; 뗁; 뗁; ) HANGUL SYLLABLE DDENJ
+B5C2;B5C2;1104 1166 11AD;B5C2;1104 1166 11AD; # (뗂; 뗂; 뗂; 뗂; 뗂; ) HANGUL SYLLABLE DDENH
+B5C3;B5C3;1104 1166 11AE;B5C3;1104 1166 11AE; # (뗃; 뗃; 뗃; 뗃; 뗃; ) HANGUL SYLLABLE DDED
+B5C4;B5C4;1104 1166 11AF;B5C4;1104 1166 11AF; # (뗄; 뗄; 뗄; 뗄; 뗄; ) HANGUL SYLLABLE DDEL
+B5C5;B5C5;1104 1166 11B0;B5C5;1104 1166 11B0; # (뗅; 뗅; 뗅; 뗅; 뗅; ) HANGUL SYLLABLE DDELG
+B5C6;B5C6;1104 1166 11B1;B5C6;1104 1166 11B1; # (뗆; 뗆; 뗆; 뗆; 뗆; ) HANGUL SYLLABLE DDELM
+B5C7;B5C7;1104 1166 11B2;B5C7;1104 1166 11B2; # (뗇; 뗇; 뗇; 뗇; 뗇; ) HANGUL SYLLABLE DDELB
+B5C8;B5C8;1104 1166 11B3;B5C8;1104 1166 11B3; # (뗈; 뗈; 뗈; 뗈; 뗈; ) HANGUL SYLLABLE DDELS
+B5C9;B5C9;1104 1166 11B4;B5C9;1104 1166 11B4; # (뗉; 뗉; 뗉; 뗉; 뗉; ) HANGUL SYLLABLE DDELT
+B5CA;B5CA;1104 1166 11B5;B5CA;1104 1166 11B5; # (뗊; 뗊; 뗊; 뗊; 뗊; ) HANGUL SYLLABLE DDELP
+B5CB;B5CB;1104 1166 11B6;B5CB;1104 1166 11B6; # (뗋; 뗋; 뗋; 뗋; 뗋; ) HANGUL SYLLABLE DDELH
+B5CC;B5CC;1104 1166 11B7;B5CC;1104 1166 11B7; # (뗌; 뗌; 뗌; 뗌; 뗌; ) HANGUL SYLLABLE DDEM
+B5CD;B5CD;1104 1166 11B8;B5CD;1104 1166 11B8; # (뗍; 뗍; 뗍; 뗍; 뗍; ) HANGUL SYLLABLE DDEB
+B5CE;B5CE;1104 1166 11B9;B5CE;1104 1166 11B9; # (뗎; 뗎; 뗎; 뗎; 뗎; ) HANGUL SYLLABLE DDEBS
+B5CF;B5CF;1104 1166 11BA;B5CF;1104 1166 11BA; # (뗏; 뗏; 뗏; 뗏; 뗏; ) HANGUL SYLLABLE DDES
+B5D0;B5D0;1104 1166 11BB;B5D0;1104 1166 11BB; # (뗐; 뗐; 뗐; 뗐; 뗐; ) HANGUL SYLLABLE DDESS
+B5D1;B5D1;1104 1166 11BC;B5D1;1104 1166 11BC; # (뗑; 뗑; 뗑; 뗑; 뗑; ) HANGUL SYLLABLE DDENG
+B5D2;B5D2;1104 1166 11BD;B5D2;1104 1166 11BD; # (뗒; 뗒; 뗒; 뗒; 뗒; ) HANGUL SYLLABLE DDEJ
+B5D3;B5D3;1104 1166 11BE;B5D3;1104 1166 11BE; # (뗓; 뗓; 뗓; 뗓; 뗓; ) HANGUL SYLLABLE DDEC
+B5D4;B5D4;1104 1166 11BF;B5D4;1104 1166 11BF; # (뗔; 뗔; 뗔; 뗔; 뗔; ) HANGUL SYLLABLE DDEK
+B5D5;B5D5;1104 1166 11C0;B5D5;1104 1166 11C0; # (뗕; 뗕; 뗕; 뗕; 뗕; ) HANGUL SYLLABLE DDET
+B5D6;B5D6;1104 1166 11C1;B5D6;1104 1166 11C1; # (뗖; 뗖; 뗖; 뗖; 뗖; ) HANGUL SYLLABLE DDEP
+B5D7;B5D7;1104 1166 11C2;B5D7;1104 1166 11C2; # (뗗; 뗗; 뗗; 뗗; 뗗; ) HANGUL SYLLABLE DDEH
+B5D8;B5D8;1104 1167;B5D8;1104 1167; # (뗘; 뗘; 뗘; 뗘; 뗘; ) HANGUL SYLLABLE DDYEO
+B5D9;B5D9;1104 1167 11A8;B5D9;1104 1167 11A8; # (뗙; 뗙; 뗙; 뗙; 뗙; ) HANGUL SYLLABLE DDYEOG
+B5DA;B5DA;1104 1167 11A9;B5DA;1104 1167 11A9; # (뗚; 뗚; 뗚; 뗚; 뗚; ) HANGUL SYLLABLE DDYEOGG
+B5DB;B5DB;1104 1167 11AA;B5DB;1104 1167 11AA; # (뗛; 뗛; 뗛; 뗛; 뗛; ) HANGUL SYLLABLE DDYEOGS
+B5DC;B5DC;1104 1167 11AB;B5DC;1104 1167 11AB; # (뗜; 뗜; 뗜; 뗜; 뗜; ) HANGUL SYLLABLE DDYEON
+B5DD;B5DD;1104 1167 11AC;B5DD;1104 1167 11AC; # (뗝; 뗝; 뗝; 뗝; 뗝; ) HANGUL SYLLABLE DDYEONJ
+B5DE;B5DE;1104 1167 11AD;B5DE;1104 1167 11AD; # (뗞; 뗞; 뗞; 뗞; 뗞; ) HANGUL SYLLABLE DDYEONH
+B5DF;B5DF;1104 1167 11AE;B5DF;1104 1167 11AE; # (뗟; 뗟; 뗟; 뗟; 뗟; ) HANGUL SYLLABLE DDYEOD
+B5E0;B5E0;1104 1167 11AF;B5E0;1104 1167 11AF; # (뗠; 뗠; 뗠; 뗠; 뗠; ) HANGUL SYLLABLE DDYEOL
+B5E1;B5E1;1104 1167 11B0;B5E1;1104 1167 11B0; # (뗡; 뗡; 뗡; 뗡; 뗡; ) HANGUL SYLLABLE DDYEOLG
+B5E2;B5E2;1104 1167 11B1;B5E2;1104 1167 11B1; # (뗢; 뗢; 뗢; 뗢; 뗢; ) HANGUL SYLLABLE DDYEOLM
+B5E3;B5E3;1104 1167 11B2;B5E3;1104 1167 11B2; # (뗣; 뗣; 뗣; 뗣; 뗣; ) HANGUL SYLLABLE DDYEOLB
+B5E4;B5E4;1104 1167 11B3;B5E4;1104 1167 11B3; # (뗤; 뗤; 뗤; 뗤; 뗤; ) HANGUL SYLLABLE DDYEOLS
+B5E5;B5E5;1104 1167 11B4;B5E5;1104 1167 11B4; # (뗥; 뗥; 뗥; 뗥; 뗥; ) HANGUL SYLLABLE DDYEOLT
+B5E6;B5E6;1104 1167 11B5;B5E6;1104 1167 11B5; # (뗦; 뗦; 뗦; 뗦; 뗦; ) HANGUL SYLLABLE DDYEOLP
+B5E7;B5E7;1104 1167 11B6;B5E7;1104 1167 11B6; # (뗧; 뗧; 뗧; 뗧; 뗧; ) HANGUL SYLLABLE DDYEOLH
+B5E8;B5E8;1104 1167 11B7;B5E8;1104 1167 11B7; # (뗨; 뗨; 뗨; 뗨; 뗨; ) HANGUL SYLLABLE DDYEOM
+B5E9;B5E9;1104 1167 11B8;B5E9;1104 1167 11B8; # (뗩; 뗩; 뗩; 뗩; 뗩; ) HANGUL SYLLABLE DDYEOB
+B5EA;B5EA;1104 1167 11B9;B5EA;1104 1167 11B9; # (뗪; 뗪; 뗪; 뗪; 뗪; ) HANGUL SYLLABLE DDYEOBS
+B5EB;B5EB;1104 1167 11BA;B5EB;1104 1167 11BA; # (뗫; 뗫; 뗫; 뗫; 뗫; ) HANGUL SYLLABLE DDYEOS
+B5EC;B5EC;1104 1167 11BB;B5EC;1104 1167 11BB; # (뗬; 뗬; 뗬; 뗬; 뗬; ) HANGUL SYLLABLE DDYEOSS
+B5ED;B5ED;1104 1167 11BC;B5ED;1104 1167 11BC; # (뗭; 뗭; 뗭; 뗭; 뗭; ) HANGUL SYLLABLE DDYEONG
+B5EE;B5EE;1104 1167 11BD;B5EE;1104 1167 11BD; # (뗮; 뗮; 뗮; 뗮; 뗮; ) HANGUL SYLLABLE DDYEOJ
+B5EF;B5EF;1104 1167 11BE;B5EF;1104 1167 11BE; # (뗯; 뗯; 뗯; 뗯; 뗯; ) HANGUL SYLLABLE DDYEOC
+B5F0;B5F0;1104 1167 11BF;B5F0;1104 1167 11BF; # (뗰; 뗰; 뗰; 뗰; 뗰; ) HANGUL SYLLABLE DDYEOK
+B5F1;B5F1;1104 1167 11C0;B5F1;1104 1167 11C0; # (뗱; 뗱; 뗱; 뗱; 뗱; ) HANGUL SYLLABLE DDYEOT
+B5F2;B5F2;1104 1167 11C1;B5F2;1104 1167 11C1; # (뗲; 뗲; 뗲; 뗲; 뗲; ) HANGUL SYLLABLE DDYEOP
+B5F3;B5F3;1104 1167 11C2;B5F3;1104 1167 11C2; # (뗳; 뗳; 뗳; 뗳; 뗳; ) HANGUL SYLLABLE DDYEOH
+B5F4;B5F4;1104 1168;B5F4;1104 1168; # (뗴; 뗴; 뗴; 뗴; 뗴; ) HANGUL SYLLABLE DDYE
+B5F5;B5F5;1104 1168 11A8;B5F5;1104 1168 11A8; # (뗵; 뗵; 뗵; 뗵; 뗵; ) HANGUL SYLLABLE DDYEG
+B5F6;B5F6;1104 1168 11A9;B5F6;1104 1168 11A9; # (뗶; 뗶; 뗶; 뗶; 뗶; ) HANGUL SYLLABLE DDYEGG
+B5F7;B5F7;1104 1168 11AA;B5F7;1104 1168 11AA; # (뗷; 뗷; 뗷; 뗷; 뗷; ) HANGUL SYLLABLE DDYEGS
+B5F8;B5F8;1104 1168 11AB;B5F8;1104 1168 11AB; # (뗸; 뗸; 뗸; 뗸; 뗸; ) HANGUL SYLLABLE DDYEN
+B5F9;B5F9;1104 1168 11AC;B5F9;1104 1168 11AC; # (뗹; 뗹; 뗹; 뗹; 뗹; ) HANGUL SYLLABLE DDYENJ
+B5FA;B5FA;1104 1168 11AD;B5FA;1104 1168 11AD; # (뗺; 뗺; 뗺; 뗺; 뗺; ) HANGUL SYLLABLE DDYENH
+B5FB;B5FB;1104 1168 11AE;B5FB;1104 1168 11AE; # (뗻; 뗻; 뗻; 뗻; 뗻; ) HANGUL SYLLABLE DDYED
+B5FC;B5FC;1104 1168 11AF;B5FC;1104 1168 11AF; # (뗼; 뗼; 뗼; 뗼; 뗼; ) HANGUL SYLLABLE DDYEL
+B5FD;B5FD;1104 1168 11B0;B5FD;1104 1168 11B0; # (뗽; 뗽; 뗽; 뗽; 뗽; ) HANGUL SYLLABLE DDYELG
+B5FE;B5FE;1104 1168 11B1;B5FE;1104 1168 11B1; # (뗾; 뗾; 뗾; 뗾; 뗾; ) HANGUL SYLLABLE DDYELM
+B5FF;B5FF;1104 1168 11B2;B5FF;1104 1168 11B2; # (뗿; 뗿; 뗿; 뗿; 뗿; ) HANGUL SYLLABLE DDYELB
+B600;B600;1104 1168 11B3;B600;1104 1168 11B3; # (똀; 똀; 똀; 똀; 똀; ) HANGUL SYLLABLE DDYELS
+B601;B601;1104 1168 11B4;B601;1104 1168 11B4; # (똁; 똁; 똁; 똁; 똁; ) HANGUL SYLLABLE DDYELT
+B602;B602;1104 1168 11B5;B602;1104 1168 11B5; # (똂; 똂; 똂; 똂; 똂; ) HANGUL SYLLABLE DDYELP
+B603;B603;1104 1168 11B6;B603;1104 1168 11B6; # (똃; 똃; 똃; 똃; 똃; ) HANGUL SYLLABLE DDYELH
+B604;B604;1104 1168 11B7;B604;1104 1168 11B7; # (똄; 똄; 똄; 똄; 똄; ) HANGUL SYLLABLE DDYEM
+B605;B605;1104 1168 11B8;B605;1104 1168 11B8; # (똅; 똅; 똅; 똅; 똅; ) HANGUL SYLLABLE DDYEB
+B606;B606;1104 1168 11B9;B606;1104 1168 11B9; # (똆; 똆; 똆; 똆; 똆; ) HANGUL SYLLABLE DDYEBS
+B607;B607;1104 1168 11BA;B607;1104 1168 11BA; # (똇; 똇; 똇; 똇; 똇; ) HANGUL SYLLABLE DDYES
+B608;B608;1104 1168 11BB;B608;1104 1168 11BB; # (똈; 똈; 똈; 똈; 똈; ) HANGUL SYLLABLE DDYESS
+B609;B609;1104 1168 11BC;B609;1104 1168 11BC; # (똉; 똉; 똉; 똉; 똉; ) HANGUL SYLLABLE DDYENG
+B60A;B60A;1104 1168 11BD;B60A;1104 1168 11BD; # (똊; 똊; 똊; 똊; 똊; ) HANGUL SYLLABLE DDYEJ
+B60B;B60B;1104 1168 11BE;B60B;1104 1168 11BE; # (똋; 똋; 똋; 똋; 똋; ) HANGUL SYLLABLE DDYEC
+B60C;B60C;1104 1168 11BF;B60C;1104 1168 11BF; # (똌; 똌; 똌; 똌; 똌; ) HANGUL SYLLABLE DDYEK
+B60D;B60D;1104 1168 11C0;B60D;1104 1168 11C0; # (똍; 똍; 똍; 똍; 똍; ) HANGUL SYLLABLE DDYET
+B60E;B60E;1104 1168 11C1;B60E;1104 1168 11C1; # (똎; 똎; 똎; 똎; 똎; ) HANGUL SYLLABLE DDYEP
+B60F;B60F;1104 1168 11C2;B60F;1104 1168 11C2; # (똏; 똏; 똏; 똏; 똏; ) HANGUL SYLLABLE DDYEH
+B610;B610;1104 1169;B610;1104 1169; # (또; 또; 또; 또; 또; ) HANGUL SYLLABLE DDO
+B611;B611;1104 1169 11A8;B611;1104 1169 11A8; # (똑; 똑; 똑; 똑; 똑; ) HANGUL SYLLABLE DDOG
+B612;B612;1104 1169 11A9;B612;1104 1169 11A9; # (똒; 똒; 똒; 똒; 똒; ) HANGUL SYLLABLE DDOGG
+B613;B613;1104 1169 11AA;B613;1104 1169 11AA; # (똓; 똓; 똓; 똓; 똓; ) HANGUL SYLLABLE DDOGS
+B614;B614;1104 1169 11AB;B614;1104 1169 11AB; # (똔; 똔; 똔; 똔; 똔; ) HANGUL SYLLABLE DDON
+B615;B615;1104 1169 11AC;B615;1104 1169 11AC; # (똕; 똕; 똕; 똕; 똕; ) HANGUL SYLLABLE DDONJ
+B616;B616;1104 1169 11AD;B616;1104 1169 11AD; # (똖; 똖; 똖; 똖; 똖; ) HANGUL SYLLABLE DDONH
+B617;B617;1104 1169 11AE;B617;1104 1169 11AE; # (똗; 똗; 똗; 똗; 똗; ) HANGUL SYLLABLE DDOD
+B618;B618;1104 1169 11AF;B618;1104 1169 11AF; # (똘; 똘; 똘; 똘; 똘; ) HANGUL SYLLABLE DDOL
+B619;B619;1104 1169 11B0;B619;1104 1169 11B0; # (똙; 똙; 똙; 똙; 똙; ) HANGUL SYLLABLE DDOLG
+B61A;B61A;1104 1169 11B1;B61A;1104 1169 11B1; # (똚; 똚; 똚; 똚; 똚; ) HANGUL SYLLABLE DDOLM
+B61B;B61B;1104 1169 11B2;B61B;1104 1169 11B2; # (똛; 똛; 똛; 똛; 똛; ) HANGUL SYLLABLE DDOLB
+B61C;B61C;1104 1169 11B3;B61C;1104 1169 11B3; # (똜; 똜; 똜; 똜; 똜; ) HANGUL SYLLABLE DDOLS
+B61D;B61D;1104 1169 11B4;B61D;1104 1169 11B4; # (똝; 똝; 똝; 똝; 똝; ) HANGUL SYLLABLE DDOLT
+B61E;B61E;1104 1169 11B5;B61E;1104 1169 11B5; # (똞; 똞; 똞; 똞; 똞; ) HANGUL SYLLABLE DDOLP
+B61F;B61F;1104 1169 11B6;B61F;1104 1169 11B6; # (똟; 똟; 똟; 똟; 똟; ) HANGUL SYLLABLE DDOLH
+B620;B620;1104 1169 11B7;B620;1104 1169 11B7; # (똠; 똠; 똠; 똠; 똠; ) HANGUL SYLLABLE DDOM
+B621;B621;1104 1169 11B8;B621;1104 1169 11B8; # (똡; 똡; 똡; 똡; 똡; ) HANGUL SYLLABLE DDOB
+B622;B622;1104 1169 11B9;B622;1104 1169 11B9; # (똢; 똢; 똢; 똢; 똢; ) HANGUL SYLLABLE DDOBS
+B623;B623;1104 1169 11BA;B623;1104 1169 11BA; # (똣; 똣; 똣; 똣; 똣; ) HANGUL SYLLABLE DDOS
+B624;B624;1104 1169 11BB;B624;1104 1169 11BB; # (똤; 똤; 똤; 똤; 똤; ) HANGUL SYLLABLE DDOSS
+B625;B625;1104 1169 11BC;B625;1104 1169 11BC; # (똥; 똥; 똥; 똥; 똥; ) HANGUL SYLLABLE DDONG
+B626;B626;1104 1169 11BD;B626;1104 1169 11BD; # (똦; 똦; 똦; 똦; 똦; ) HANGUL SYLLABLE DDOJ
+B627;B627;1104 1169 11BE;B627;1104 1169 11BE; # (똧; 똧; 똧; 똧; 똧; ) HANGUL SYLLABLE DDOC
+B628;B628;1104 1169 11BF;B628;1104 1169 11BF; # (똨; 똨; 똨; 똨; 똨; ) HANGUL SYLLABLE DDOK
+B629;B629;1104 1169 11C0;B629;1104 1169 11C0; # (똩; 똩; 똩; 똩; 똩; ) HANGUL SYLLABLE DDOT
+B62A;B62A;1104 1169 11C1;B62A;1104 1169 11C1; # (똪; 똪; 똪; 똪; 똪; ) HANGUL SYLLABLE DDOP
+B62B;B62B;1104 1169 11C2;B62B;1104 1169 11C2; # (똫; 똫; 똫; 똫; 똫; ) HANGUL SYLLABLE DDOH
+B62C;B62C;1104 116A;B62C;1104 116A; # (똬; 똬; 똬; 똬; 똬; ) HANGUL SYLLABLE DDWA
+B62D;B62D;1104 116A 11A8;B62D;1104 116A 11A8; # (똭; 똭; 똭; 똭; 똭; ) HANGUL SYLLABLE DDWAG
+B62E;B62E;1104 116A 11A9;B62E;1104 116A 11A9; # (똮; 똮; 똮; 똮; 똮; ) HANGUL SYLLABLE DDWAGG
+B62F;B62F;1104 116A 11AA;B62F;1104 116A 11AA; # (똯; 똯; 똯; 똯; 똯; ) HANGUL SYLLABLE DDWAGS
+B630;B630;1104 116A 11AB;B630;1104 116A 11AB; # (똰; 똰; 똰; 똰; 똰; ) HANGUL SYLLABLE DDWAN
+B631;B631;1104 116A 11AC;B631;1104 116A 11AC; # (똱; 똱; 똱; 똱; 똱; ) HANGUL SYLLABLE DDWANJ
+B632;B632;1104 116A 11AD;B632;1104 116A 11AD; # (똲; 똲; 똲; 똲; 똲; ) HANGUL SYLLABLE DDWANH
+B633;B633;1104 116A 11AE;B633;1104 116A 11AE; # (똳; 똳; 똳; 똳; 똳; ) HANGUL SYLLABLE DDWAD
+B634;B634;1104 116A 11AF;B634;1104 116A 11AF; # (똴; 똴; 똴; 똴; 똴; ) HANGUL SYLLABLE DDWAL
+B635;B635;1104 116A 11B0;B635;1104 116A 11B0; # (똵; 똵; 똵; 똵; 똵; ) HANGUL SYLLABLE DDWALG
+B636;B636;1104 116A 11B1;B636;1104 116A 11B1; # (똶; 똶; 똶; 똶; 똶; ) HANGUL SYLLABLE DDWALM
+B637;B637;1104 116A 11B2;B637;1104 116A 11B2; # (똷; 똷; 똷; 똷; 똷; ) HANGUL SYLLABLE DDWALB
+B638;B638;1104 116A 11B3;B638;1104 116A 11B3; # (똸; 똸; 똸; 똸; 똸; ) HANGUL SYLLABLE DDWALS
+B639;B639;1104 116A 11B4;B639;1104 116A 11B4; # (똹; 똹; 똹; 똹; 똹; ) HANGUL SYLLABLE DDWALT
+B63A;B63A;1104 116A 11B5;B63A;1104 116A 11B5; # (똺; 똺; 똺; 똺; 똺; ) HANGUL SYLLABLE DDWALP
+B63B;B63B;1104 116A 11B6;B63B;1104 116A 11B6; # (똻; 똻; 똻; 똻; 똻; ) HANGUL SYLLABLE DDWALH
+B63C;B63C;1104 116A 11B7;B63C;1104 116A 11B7; # (똼; 똼; 똼; 똼; 똼; ) HANGUL SYLLABLE DDWAM
+B63D;B63D;1104 116A 11B8;B63D;1104 116A 11B8; # (똽; 똽; 똽; 똽; 똽; ) HANGUL SYLLABLE DDWAB
+B63E;B63E;1104 116A 11B9;B63E;1104 116A 11B9; # (똾; 똾; 똾; 똾; 똾; ) HANGUL SYLLABLE DDWABS
+B63F;B63F;1104 116A 11BA;B63F;1104 116A 11BA; # (똿; 똿; 똿; 똿; 똿; ) HANGUL SYLLABLE DDWAS
+B640;B640;1104 116A 11BB;B640;1104 116A 11BB; # (뙀; 뙀; 뙀; 뙀; 뙀; ) HANGUL SYLLABLE DDWASS
+B641;B641;1104 116A 11BC;B641;1104 116A 11BC; # (뙁; 뙁; 뙁; 뙁; 뙁; ) HANGUL SYLLABLE DDWANG
+B642;B642;1104 116A 11BD;B642;1104 116A 11BD; # (뙂; 뙂; 뙂; 뙂; 뙂; ) HANGUL SYLLABLE DDWAJ
+B643;B643;1104 116A 11BE;B643;1104 116A 11BE; # (뙃; 뙃; 뙃; 뙃; 뙃; ) HANGUL SYLLABLE DDWAC
+B644;B644;1104 116A 11BF;B644;1104 116A 11BF; # (뙄; 뙄; 뙄; 뙄; 뙄; ) HANGUL SYLLABLE DDWAK
+B645;B645;1104 116A 11C0;B645;1104 116A 11C0; # (뙅; 뙅; 뙅; 뙅; 뙅; ) HANGUL SYLLABLE DDWAT
+B646;B646;1104 116A 11C1;B646;1104 116A 11C1; # (뙆; 뙆; 뙆; 뙆; 뙆; ) HANGUL SYLLABLE DDWAP
+B647;B647;1104 116A 11C2;B647;1104 116A 11C2; # (뙇; 뙇; 뙇; 뙇; 뙇; ) HANGUL SYLLABLE DDWAH
+B648;B648;1104 116B;B648;1104 116B; # (뙈; 뙈; 뙈; 뙈; 뙈; ) HANGUL SYLLABLE DDWAE
+B649;B649;1104 116B 11A8;B649;1104 116B 11A8; # (뙉; 뙉; 뙉; 뙉; 뙉; ) HANGUL SYLLABLE DDWAEG
+B64A;B64A;1104 116B 11A9;B64A;1104 116B 11A9; # (뙊; 뙊; 뙊; 뙊; 뙊; ) HANGUL SYLLABLE DDWAEGG
+B64B;B64B;1104 116B 11AA;B64B;1104 116B 11AA; # (뙋; 뙋; 뙋; 뙋; 뙋; ) HANGUL SYLLABLE DDWAEGS
+B64C;B64C;1104 116B 11AB;B64C;1104 116B 11AB; # (뙌; 뙌; 뙌; 뙌; 뙌; ) HANGUL SYLLABLE DDWAEN
+B64D;B64D;1104 116B 11AC;B64D;1104 116B 11AC; # (뙍; 뙍; 뙍; 뙍; 뙍; ) HANGUL SYLLABLE DDWAENJ
+B64E;B64E;1104 116B 11AD;B64E;1104 116B 11AD; # (뙎; 뙎; 뙎; 뙎; 뙎; ) HANGUL SYLLABLE DDWAENH
+B64F;B64F;1104 116B 11AE;B64F;1104 116B 11AE; # (뙏; 뙏; 뙏; 뙏; 뙏; ) HANGUL SYLLABLE DDWAED
+B650;B650;1104 116B 11AF;B650;1104 116B 11AF; # (뙐; 뙐; 뙐; 뙐; 뙐; ) HANGUL SYLLABLE DDWAEL
+B651;B651;1104 116B 11B0;B651;1104 116B 11B0; # (뙑; 뙑; 뙑; 뙑; 뙑; ) HANGUL SYLLABLE DDWAELG
+B652;B652;1104 116B 11B1;B652;1104 116B 11B1; # (뙒; 뙒; 뙒; 뙒; 뙒; ) HANGUL SYLLABLE DDWAELM
+B653;B653;1104 116B 11B2;B653;1104 116B 11B2; # (뙓; 뙓; 뙓; 뙓; 뙓; ) HANGUL SYLLABLE DDWAELB
+B654;B654;1104 116B 11B3;B654;1104 116B 11B3; # (뙔; 뙔; 뙔; 뙔; 뙔; ) HANGUL SYLLABLE DDWAELS
+B655;B655;1104 116B 11B4;B655;1104 116B 11B4; # (뙕; 뙕; 뙕; 뙕; 뙕; ) HANGUL SYLLABLE DDWAELT
+B656;B656;1104 116B 11B5;B656;1104 116B 11B5; # (뙖; 뙖; 뙖; 뙖; 뙖; ) HANGUL SYLLABLE DDWAELP
+B657;B657;1104 116B 11B6;B657;1104 116B 11B6; # (뙗; 뙗; 뙗; 뙗; 뙗; ) HANGUL SYLLABLE DDWAELH
+B658;B658;1104 116B 11B7;B658;1104 116B 11B7; # (뙘; 뙘; 뙘; 뙘; 뙘; ) HANGUL SYLLABLE DDWAEM
+B659;B659;1104 116B 11B8;B659;1104 116B 11B8; # (뙙; 뙙; 뙙; 뙙; 뙙; ) HANGUL SYLLABLE DDWAEB
+B65A;B65A;1104 116B 11B9;B65A;1104 116B 11B9; # (뙚; 뙚; 뙚; 뙚; 뙚; ) HANGUL SYLLABLE DDWAEBS
+B65B;B65B;1104 116B 11BA;B65B;1104 116B 11BA; # (뙛; 뙛; 뙛; 뙛; 뙛; ) HANGUL SYLLABLE DDWAES
+B65C;B65C;1104 116B 11BB;B65C;1104 116B 11BB; # (뙜; 뙜; 뙜; 뙜; 뙜; ) HANGUL SYLLABLE DDWAESS
+B65D;B65D;1104 116B 11BC;B65D;1104 116B 11BC; # (뙝; 뙝; 뙝; 뙝; 뙝; ) HANGUL SYLLABLE DDWAENG
+B65E;B65E;1104 116B 11BD;B65E;1104 116B 11BD; # (뙞; 뙞; 뙞; 뙞; 뙞; ) HANGUL SYLLABLE DDWAEJ
+B65F;B65F;1104 116B 11BE;B65F;1104 116B 11BE; # (뙟; 뙟; 뙟; 뙟; 뙟; ) HANGUL SYLLABLE DDWAEC
+B660;B660;1104 116B 11BF;B660;1104 116B 11BF; # (뙠; 뙠; 뙠; 뙠; 뙠; ) HANGUL SYLLABLE DDWAEK
+B661;B661;1104 116B 11C0;B661;1104 116B 11C0; # (뙡; 뙡; 뙡; 뙡; 뙡; ) HANGUL SYLLABLE DDWAET
+B662;B662;1104 116B 11C1;B662;1104 116B 11C1; # (뙢; 뙢; 뙢; 뙢; 뙢; ) HANGUL SYLLABLE DDWAEP
+B663;B663;1104 116B 11C2;B663;1104 116B 11C2; # (뙣; 뙣; 뙣; 뙣; 뙣; ) HANGUL SYLLABLE DDWAEH
+B664;B664;1104 116C;B664;1104 116C; # (뙤; 뙤; 뙤; 뙤; 뙤; ) HANGUL SYLLABLE DDOE
+B665;B665;1104 116C 11A8;B665;1104 116C 11A8; # (뙥; 뙥; 뙥; 뙥; 뙥; ) HANGUL SYLLABLE DDOEG
+B666;B666;1104 116C 11A9;B666;1104 116C 11A9; # (뙦; 뙦; 뙦; 뙦; 뙦; ) HANGUL SYLLABLE DDOEGG
+B667;B667;1104 116C 11AA;B667;1104 116C 11AA; # (뙧; 뙧; 뙧; 뙧; 뙧; ) HANGUL SYLLABLE DDOEGS
+B668;B668;1104 116C 11AB;B668;1104 116C 11AB; # (뙨; 뙨; 뙨; 뙨; 뙨; ) HANGUL SYLLABLE DDOEN
+B669;B669;1104 116C 11AC;B669;1104 116C 11AC; # (뙩; 뙩; 뙩; 뙩; 뙩; ) HANGUL SYLLABLE DDOENJ
+B66A;B66A;1104 116C 11AD;B66A;1104 116C 11AD; # (뙪; 뙪; 뙪; 뙪; 뙪; ) HANGUL SYLLABLE DDOENH
+B66B;B66B;1104 116C 11AE;B66B;1104 116C 11AE; # (뙫; 뙫; 뙫; 뙫; 뙫; ) HANGUL SYLLABLE DDOED
+B66C;B66C;1104 116C 11AF;B66C;1104 116C 11AF; # (뙬; 뙬; 뙬; 뙬; 뙬; ) HANGUL SYLLABLE DDOEL
+B66D;B66D;1104 116C 11B0;B66D;1104 116C 11B0; # (뙭; 뙭; 뙭; 뙭; 뙭; ) HANGUL SYLLABLE DDOELG
+B66E;B66E;1104 116C 11B1;B66E;1104 116C 11B1; # (뙮; 뙮; 뙮; 뙮; 뙮; ) HANGUL SYLLABLE DDOELM
+B66F;B66F;1104 116C 11B2;B66F;1104 116C 11B2; # (뙯; 뙯; 뙯; 뙯; 뙯; ) HANGUL SYLLABLE DDOELB
+B670;B670;1104 116C 11B3;B670;1104 116C 11B3; # (뙰; 뙰; 뙰; 뙰; 뙰; ) HANGUL SYLLABLE DDOELS
+B671;B671;1104 116C 11B4;B671;1104 116C 11B4; # (뙱; 뙱; 뙱; 뙱; 뙱; ) HANGUL SYLLABLE DDOELT
+B672;B672;1104 116C 11B5;B672;1104 116C 11B5; # (뙲; 뙲; 뙲; 뙲; 뙲; ) HANGUL SYLLABLE DDOELP
+B673;B673;1104 116C 11B6;B673;1104 116C 11B6; # (뙳; 뙳; 뙳; 뙳; 뙳; ) HANGUL SYLLABLE DDOELH
+B674;B674;1104 116C 11B7;B674;1104 116C 11B7; # (뙴; 뙴; 뙴; 뙴; 뙴; ) HANGUL SYLLABLE DDOEM
+B675;B675;1104 116C 11B8;B675;1104 116C 11B8; # (뙵; 뙵; 뙵; 뙵; 뙵; ) HANGUL SYLLABLE DDOEB
+B676;B676;1104 116C 11B9;B676;1104 116C 11B9; # (뙶; 뙶; 뙶; 뙶; 뙶; ) HANGUL SYLLABLE DDOEBS
+B677;B677;1104 116C 11BA;B677;1104 116C 11BA; # (뙷; 뙷; 뙷; 뙷; 뙷; ) HANGUL SYLLABLE DDOES
+B678;B678;1104 116C 11BB;B678;1104 116C 11BB; # (뙸; 뙸; 뙸; 뙸; 뙸; ) HANGUL SYLLABLE DDOESS
+B679;B679;1104 116C 11BC;B679;1104 116C 11BC; # (뙹; 뙹; 뙹; 뙹; 뙹; ) HANGUL SYLLABLE DDOENG
+B67A;B67A;1104 116C 11BD;B67A;1104 116C 11BD; # (뙺; 뙺; 뙺; 뙺; 뙺; ) HANGUL SYLLABLE DDOEJ
+B67B;B67B;1104 116C 11BE;B67B;1104 116C 11BE; # (뙻; 뙻; 뙻; 뙻; 뙻; ) HANGUL SYLLABLE DDOEC
+B67C;B67C;1104 116C 11BF;B67C;1104 116C 11BF; # (뙼; 뙼; 뙼; 뙼; 뙼; ) HANGUL SYLLABLE DDOEK
+B67D;B67D;1104 116C 11C0;B67D;1104 116C 11C0; # (뙽; 뙽; 뙽; 뙽; 뙽; ) HANGUL SYLLABLE DDOET
+B67E;B67E;1104 116C 11C1;B67E;1104 116C 11C1; # (뙾; 뙾; 뙾; 뙾; 뙾; ) HANGUL SYLLABLE DDOEP
+B67F;B67F;1104 116C 11C2;B67F;1104 116C 11C2; # (뙿; 뙿; 뙿; 뙿; 뙿; ) HANGUL SYLLABLE DDOEH
+B680;B680;1104 116D;B680;1104 116D; # (뚀; 뚀; 뚀; 뚀; 뚀; ) HANGUL SYLLABLE DDYO
+B681;B681;1104 116D 11A8;B681;1104 116D 11A8; # (뚁; 뚁; 뚁; 뚁; 뚁; ) HANGUL SYLLABLE DDYOG
+B682;B682;1104 116D 11A9;B682;1104 116D 11A9; # (뚂; 뚂; 뚂; 뚂; 뚂; ) HANGUL SYLLABLE DDYOGG
+B683;B683;1104 116D 11AA;B683;1104 116D 11AA; # (뚃; 뚃; 뚃; 뚃; 뚃; ) HANGUL SYLLABLE DDYOGS
+B684;B684;1104 116D 11AB;B684;1104 116D 11AB; # (뚄; 뚄; 뚄; 뚄; 뚄; ) HANGUL SYLLABLE DDYON
+B685;B685;1104 116D 11AC;B685;1104 116D 11AC; # (뚅; 뚅; 뚅; 뚅; 뚅; ) HANGUL SYLLABLE DDYONJ
+B686;B686;1104 116D 11AD;B686;1104 116D 11AD; # (뚆; 뚆; 뚆; 뚆; 뚆; ) HANGUL SYLLABLE DDYONH
+B687;B687;1104 116D 11AE;B687;1104 116D 11AE; # (뚇; 뚇; 뚇; 뚇; 뚇; ) HANGUL SYLLABLE DDYOD
+B688;B688;1104 116D 11AF;B688;1104 116D 11AF; # (뚈; 뚈; 뚈; 뚈; 뚈; ) HANGUL SYLLABLE DDYOL
+B689;B689;1104 116D 11B0;B689;1104 116D 11B0; # (뚉; 뚉; 뚉; 뚉; 뚉; ) HANGUL SYLLABLE DDYOLG
+B68A;B68A;1104 116D 11B1;B68A;1104 116D 11B1; # (뚊; 뚊; 뚊; 뚊; 뚊; ) HANGUL SYLLABLE DDYOLM
+B68B;B68B;1104 116D 11B2;B68B;1104 116D 11B2; # (뚋; 뚋; 뚋; 뚋; 뚋; ) HANGUL SYLLABLE DDYOLB
+B68C;B68C;1104 116D 11B3;B68C;1104 116D 11B3; # (뚌; 뚌; 뚌; 뚌; 뚌; ) HANGUL SYLLABLE DDYOLS
+B68D;B68D;1104 116D 11B4;B68D;1104 116D 11B4; # (뚍; 뚍; 뚍; 뚍; 뚍; ) HANGUL SYLLABLE DDYOLT
+B68E;B68E;1104 116D 11B5;B68E;1104 116D 11B5; # (뚎; 뚎; 뚎; 뚎; 뚎; ) HANGUL SYLLABLE DDYOLP
+B68F;B68F;1104 116D 11B6;B68F;1104 116D 11B6; # (뚏; 뚏; 뚏; 뚏; 뚏; ) HANGUL SYLLABLE DDYOLH
+B690;B690;1104 116D 11B7;B690;1104 116D 11B7; # (뚐; 뚐; 뚐; 뚐; 뚐; ) HANGUL SYLLABLE DDYOM
+B691;B691;1104 116D 11B8;B691;1104 116D 11B8; # (뚑; 뚑; 뚑; 뚑; 뚑; ) HANGUL SYLLABLE DDYOB
+B692;B692;1104 116D 11B9;B692;1104 116D 11B9; # (뚒; 뚒; 뚒; 뚒; 뚒; ) HANGUL SYLLABLE DDYOBS
+B693;B693;1104 116D 11BA;B693;1104 116D 11BA; # (뚓; 뚓; 뚓; 뚓; 뚓; ) HANGUL SYLLABLE DDYOS
+B694;B694;1104 116D 11BB;B694;1104 116D 11BB; # (뚔; 뚔; 뚔; 뚔; 뚔; ) HANGUL SYLLABLE DDYOSS
+B695;B695;1104 116D 11BC;B695;1104 116D 11BC; # (뚕; 뚕; 뚕; 뚕; 뚕; ) HANGUL SYLLABLE DDYONG
+B696;B696;1104 116D 11BD;B696;1104 116D 11BD; # (뚖; 뚖; 뚖; 뚖; 뚖; ) HANGUL SYLLABLE DDYOJ
+B697;B697;1104 116D 11BE;B697;1104 116D 11BE; # (뚗; 뚗; 뚗; 뚗; 뚗; ) HANGUL SYLLABLE DDYOC
+B698;B698;1104 116D 11BF;B698;1104 116D 11BF; # (뚘; 뚘; 뚘; 뚘; 뚘; ) HANGUL SYLLABLE DDYOK
+B699;B699;1104 116D 11C0;B699;1104 116D 11C0; # (뚙; 뚙; 뚙; 뚙; 뚙; ) HANGUL SYLLABLE DDYOT
+B69A;B69A;1104 116D 11C1;B69A;1104 116D 11C1; # (뚚; 뚚; 뚚; 뚚; 뚚; ) HANGUL SYLLABLE DDYOP
+B69B;B69B;1104 116D 11C2;B69B;1104 116D 11C2; # (뚛; 뚛; 뚛; 뚛; 뚛; ) HANGUL SYLLABLE DDYOH
+B69C;B69C;1104 116E;B69C;1104 116E; # (뚜; 뚜; 뚜; 뚜; 뚜; ) HANGUL SYLLABLE DDU
+B69D;B69D;1104 116E 11A8;B69D;1104 116E 11A8; # (뚝; 뚝; 뚝; 뚝; 뚝; ) HANGUL SYLLABLE DDUG
+B69E;B69E;1104 116E 11A9;B69E;1104 116E 11A9; # (뚞; 뚞; 뚞; 뚞; 뚞; ) HANGUL SYLLABLE DDUGG
+B69F;B69F;1104 116E 11AA;B69F;1104 116E 11AA; # (뚟; 뚟; 뚟; 뚟; 뚟; ) HANGUL SYLLABLE DDUGS
+B6A0;B6A0;1104 116E 11AB;B6A0;1104 116E 11AB; # (뚠; 뚠; 뚠; 뚠; 뚠; ) HANGUL SYLLABLE DDUN
+B6A1;B6A1;1104 116E 11AC;B6A1;1104 116E 11AC; # (뚡; 뚡; 뚡; 뚡; 뚡; ) HANGUL SYLLABLE DDUNJ
+B6A2;B6A2;1104 116E 11AD;B6A2;1104 116E 11AD; # (뚢; 뚢; 뚢; 뚢; 뚢; ) HANGUL SYLLABLE DDUNH
+B6A3;B6A3;1104 116E 11AE;B6A3;1104 116E 11AE; # (뚣; 뚣; 뚣; 뚣; 뚣; ) HANGUL SYLLABLE DDUD
+B6A4;B6A4;1104 116E 11AF;B6A4;1104 116E 11AF; # (뚤; 뚤; 뚤; 뚤; 뚤; ) HANGUL SYLLABLE DDUL
+B6A5;B6A5;1104 116E 11B0;B6A5;1104 116E 11B0; # (뚥; 뚥; 뚥; 뚥; 뚥; ) HANGUL SYLLABLE DDULG
+B6A6;B6A6;1104 116E 11B1;B6A6;1104 116E 11B1; # (뚦; 뚦; 뚦; 뚦; 뚦; ) HANGUL SYLLABLE DDULM
+B6A7;B6A7;1104 116E 11B2;B6A7;1104 116E 11B2; # (뚧; 뚧; 뚧; 뚧; 뚧; ) HANGUL SYLLABLE DDULB
+B6A8;B6A8;1104 116E 11B3;B6A8;1104 116E 11B3; # (뚨; 뚨; 뚨; 뚨; 뚨; ) HANGUL SYLLABLE DDULS
+B6A9;B6A9;1104 116E 11B4;B6A9;1104 116E 11B4; # (뚩; 뚩; 뚩; 뚩; 뚩; ) HANGUL SYLLABLE DDULT
+B6AA;B6AA;1104 116E 11B5;B6AA;1104 116E 11B5; # (뚪; 뚪; 뚪; 뚪; 뚪; ) HANGUL SYLLABLE DDULP
+B6AB;B6AB;1104 116E 11B6;B6AB;1104 116E 11B6; # (뚫; 뚫; 뚫; 뚫; 뚫; ) HANGUL SYLLABLE DDULH
+B6AC;B6AC;1104 116E 11B7;B6AC;1104 116E 11B7; # (뚬; 뚬; 뚬; 뚬; 뚬; ) HANGUL SYLLABLE DDUM
+B6AD;B6AD;1104 116E 11B8;B6AD;1104 116E 11B8; # (뚭; 뚭; 뚭; 뚭; 뚭; ) HANGUL SYLLABLE DDUB
+B6AE;B6AE;1104 116E 11B9;B6AE;1104 116E 11B9; # (뚮; 뚮; 뚮; 뚮; 뚮; ) HANGUL SYLLABLE DDUBS
+B6AF;B6AF;1104 116E 11BA;B6AF;1104 116E 11BA; # (뚯; 뚯; 뚯; 뚯; 뚯; ) HANGUL SYLLABLE DDUS
+B6B0;B6B0;1104 116E 11BB;B6B0;1104 116E 11BB; # (뚰; 뚰; 뚰; 뚰; 뚰; ) HANGUL SYLLABLE DDUSS
+B6B1;B6B1;1104 116E 11BC;B6B1;1104 116E 11BC; # (뚱; 뚱; 뚱; 뚱; 뚱; ) HANGUL SYLLABLE DDUNG
+B6B2;B6B2;1104 116E 11BD;B6B2;1104 116E 11BD; # (뚲; 뚲; 뚲; 뚲; 뚲; ) HANGUL SYLLABLE DDUJ
+B6B3;B6B3;1104 116E 11BE;B6B3;1104 116E 11BE; # (뚳; 뚳; 뚳; 뚳; 뚳; ) HANGUL SYLLABLE DDUC
+B6B4;B6B4;1104 116E 11BF;B6B4;1104 116E 11BF; # (뚴; 뚴; 뚴; 뚴; 뚴; ) HANGUL SYLLABLE DDUK
+B6B5;B6B5;1104 116E 11C0;B6B5;1104 116E 11C0; # (뚵; 뚵; 뚵; 뚵; 뚵; ) HANGUL SYLLABLE DDUT
+B6B6;B6B6;1104 116E 11C1;B6B6;1104 116E 11C1; # (뚶; 뚶; 뚶; 뚶; 뚶; ) HANGUL SYLLABLE DDUP
+B6B7;B6B7;1104 116E 11C2;B6B7;1104 116E 11C2; # (뚷; 뚷; 뚷; 뚷; 뚷; ) HANGUL SYLLABLE DDUH
+B6B8;B6B8;1104 116F;B6B8;1104 116F; # (뚸; 뚸; 뚸; 뚸; 뚸; ) HANGUL SYLLABLE DDWEO
+B6B9;B6B9;1104 116F 11A8;B6B9;1104 116F 11A8; # (뚹; 뚹; 뚹; 뚹; 뚹; ) HANGUL SYLLABLE DDWEOG
+B6BA;B6BA;1104 116F 11A9;B6BA;1104 116F 11A9; # (뚺; 뚺; 뚺; 뚺; 뚺; ) HANGUL SYLLABLE DDWEOGG
+B6BB;B6BB;1104 116F 11AA;B6BB;1104 116F 11AA; # (뚻; 뚻; 뚻; 뚻; 뚻; ) HANGUL SYLLABLE DDWEOGS
+B6BC;B6BC;1104 116F 11AB;B6BC;1104 116F 11AB; # (뚼; 뚼; 뚼; 뚼; 뚼; ) HANGUL SYLLABLE DDWEON
+B6BD;B6BD;1104 116F 11AC;B6BD;1104 116F 11AC; # (뚽; 뚽; 뚽; 뚽; 뚽; ) HANGUL SYLLABLE DDWEONJ
+B6BE;B6BE;1104 116F 11AD;B6BE;1104 116F 11AD; # (뚾; 뚾; 뚾; 뚾; 뚾; ) HANGUL SYLLABLE DDWEONH
+B6BF;B6BF;1104 116F 11AE;B6BF;1104 116F 11AE; # (뚿; 뚿; 뚿; 뚿; 뚿; ) HANGUL SYLLABLE DDWEOD
+B6C0;B6C0;1104 116F 11AF;B6C0;1104 116F 11AF; # (뛀; 뛀; 뛀; 뛀; 뛀; ) HANGUL SYLLABLE DDWEOL
+B6C1;B6C1;1104 116F 11B0;B6C1;1104 116F 11B0; # (뛁; 뛁; 뛁; 뛁; 뛁; ) HANGUL SYLLABLE DDWEOLG
+B6C2;B6C2;1104 116F 11B1;B6C2;1104 116F 11B1; # (뛂; 뛂; 뛂; 뛂; 뛂; ) HANGUL SYLLABLE DDWEOLM
+B6C3;B6C3;1104 116F 11B2;B6C3;1104 116F 11B2; # (뛃; 뛃; 뛃; 뛃; 뛃; ) HANGUL SYLLABLE DDWEOLB
+B6C4;B6C4;1104 116F 11B3;B6C4;1104 116F 11B3; # (뛄; 뛄; 뛄; 뛄; 뛄; ) HANGUL SYLLABLE DDWEOLS
+B6C5;B6C5;1104 116F 11B4;B6C5;1104 116F 11B4; # (뛅; 뛅; 뛅; 뛅; 뛅; ) HANGUL SYLLABLE DDWEOLT
+B6C6;B6C6;1104 116F 11B5;B6C6;1104 116F 11B5; # (뛆; 뛆; 뛆; 뛆; 뛆; ) HANGUL SYLLABLE DDWEOLP
+B6C7;B6C7;1104 116F 11B6;B6C7;1104 116F 11B6; # (뛇; 뛇; 뛇; 뛇; 뛇; ) HANGUL SYLLABLE DDWEOLH
+B6C8;B6C8;1104 116F 11B7;B6C8;1104 116F 11B7; # (뛈; 뛈; 뛈; 뛈; 뛈; ) HANGUL SYLLABLE DDWEOM
+B6C9;B6C9;1104 116F 11B8;B6C9;1104 116F 11B8; # (뛉; 뛉; 뛉; 뛉; 뛉; ) HANGUL SYLLABLE DDWEOB
+B6CA;B6CA;1104 116F 11B9;B6CA;1104 116F 11B9; # (뛊; 뛊; 뛊; 뛊; 뛊; ) HANGUL SYLLABLE DDWEOBS
+B6CB;B6CB;1104 116F 11BA;B6CB;1104 116F 11BA; # (뛋; 뛋; 뛋; 뛋; 뛋; ) HANGUL SYLLABLE DDWEOS
+B6CC;B6CC;1104 116F 11BB;B6CC;1104 116F 11BB; # (뛌; 뛌; 뛌; 뛌; 뛌; ) HANGUL SYLLABLE DDWEOSS
+B6CD;B6CD;1104 116F 11BC;B6CD;1104 116F 11BC; # (뛍; 뛍; 뛍; 뛍; 뛍; ) HANGUL SYLLABLE DDWEONG
+B6CE;B6CE;1104 116F 11BD;B6CE;1104 116F 11BD; # (뛎; 뛎; 뛎; 뛎; 뛎; ) HANGUL SYLLABLE DDWEOJ
+B6CF;B6CF;1104 116F 11BE;B6CF;1104 116F 11BE; # (뛏; 뛏; 뛏; 뛏; 뛏; ) HANGUL SYLLABLE DDWEOC
+B6D0;B6D0;1104 116F 11BF;B6D0;1104 116F 11BF; # (뛐; 뛐; 뛐; 뛐; 뛐; ) HANGUL SYLLABLE DDWEOK
+B6D1;B6D1;1104 116F 11C0;B6D1;1104 116F 11C0; # (뛑; 뛑; 뛑; 뛑; 뛑; ) HANGUL SYLLABLE DDWEOT
+B6D2;B6D2;1104 116F 11C1;B6D2;1104 116F 11C1; # (뛒; 뛒; 뛒; 뛒; 뛒; ) HANGUL SYLLABLE DDWEOP
+B6D3;B6D3;1104 116F 11C2;B6D3;1104 116F 11C2; # (뛓; 뛓; 뛓; 뛓; 뛓; ) HANGUL SYLLABLE DDWEOH
+B6D4;B6D4;1104 1170;B6D4;1104 1170; # (뛔; 뛔; 뛔; 뛔; 뛔; ) HANGUL SYLLABLE DDWE
+B6D5;B6D5;1104 1170 11A8;B6D5;1104 1170 11A8; # (뛕; 뛕; 뛕; 뛕; 뛕; ) HANGUL SYLLABLE DDWEG
+B6D6;B6D6;1104 1170 11A9;B6D6;1104 1170 11A9; # (뛖; 뛖; 뛖; 뛖; 뛖; ) HANGUL SYLLABLE DDWEGG
+B6D7;B6D7;1104 1170 11AA;B6D7;1104 1170 11AA; # (뛗; 뛗; 뛗; 뛗; 뛗; ) HANGUL SYLLABLE DDWEGS
+B6D8;B6D8;1104 1170 11AB;B6D8;1104 1170 11AB; # (뛘; 뛘; 뛘; 뛘; 뛘; ) HANGUL SYLLABLE DDWEN
+B6D9;B6D9;1104 1170 11AC;B6D9;1104 1170 11AC; # (뛙; 뛙; 뛙; 뛙; 뛙; ) HANGUL SYLLABLE DDWENJ
+B6DA;B6DA;1104 1170 11AD;B6DA;1104 1170 11AD; # (뛚; 뛚; 뛚; 뛚; 뛚; ) HANGUL SYLLABLE DDWENH
+B6DB;B6DB;1104 1170 11AE;B6DB;1104 1170 11AE; # (뛛; 뛛; 뛛; 뛛; 뛛; ) HANGUL SYLLABLE DDWED
+B6DC;B6DC;1104 1170 11AF;B6DC;1104 1170 11AF; # (뛜; 뛜; 뛜; 뛜; 뛜; ) HANGUL SYLLABLE DDWEL
+B6DD;B6DD;1104 1170 11B0;B6DD;1104 1170 11B0; # (뛝; 뛝; 뛝; 뛝; 뛝; ) HANGUL SYLLABLE DDWELG
+B6DE;B6DE;1104 1170 11B1;B6DE;1104 1170 11B1; # (뛞; 뛞; 뛞; 뛞; 뛞; ) HANGUL SYLLABLE DDWELM
+B6DF;B6DF;1104 1170 11B2;B6DF;1104 1170 11B2; # (뛟; 뛟; 뛟; 뛟; 뛟; ) HANGUL SYLLABLE DDWELB
+B6E0;B6E0;1104 1170 11B3;B6E0;1104 1170 11B3; # (뛠; 뛠; 뛠; 뛠; 뛠; ) HANGUL SYLLABLE DDWELS
+B6E1;B6E1;1104 1170 11B4;B6E1;1104 1170 11B4; # (뛡; 뛡; 뛡; 뛡; 뛡; ) HANGUL SYLLABLE DDWELT
+B6E2;B6E2;1104 1170 11B5;B6E2;1104 1170 11B5; # (뛢; 뛢; 뛢; 뛢; 뛢; ) HANGUL SYLLABLE DDWELP
+B6E3;B6E3;1104 1170 11B6;B6E3;1104 1170 11B6; # (뛣; 뛣; 뛣; 뛣; 뛣; ) HANGUL SYLLABLE DDWELH
+B6E4;B6E4;1104 1170 11B7;B6E4;1104 1170 11B7; # (뛤; 뛤; 뛤; 뛤; 뛤; ) HANGUL SYLLABLE DDWEM
+B6E5;B6E5;1104 1170 11B8;B6E5;1104 1170 11B8; # (뛥; 뛥; 뛥; 뛥; 뛥; ) HANGUL SYLLABLE DDWEB
+B6E6;B6E6;1104 1170 11B9;B6E6;1104 1170 11B9; # (뛦; 뛦; 뛦; 뛦; 뛦; ) HANGUL SYLLABLE DDWEBS
+B6E7;B6E7;1104 1170 11BA;B6E7;1104 1170 11BA; # (뛧; 뛧; 뛧; 뛧; 뛧; ) HANGUL SYLLABLE DDWES
+B6E8;B6E8;1104 1170 11BB;B6E8;1104 1170 11BB; # (뛨; 뛨; 뛨; 뛨; 뛨; ) HANGUL SYLLABLE DDWESS
+B6E9;B6E9;1104 1170 11BC;B6E9;1104 1170 11BC; # (뛩; 뛩; 뛩; 뛩; 뛩; ) HANGUL SYLLABLE DDWENG
+B6EA;B6EA;1104 1170 11BD;B6EA;1104 1170 11BD; # (뛪; 뛪; 뛪; 뛪; 뛪; ) HANGUL SYLLABLE DDWEJ
+B6EB;B6EB;1104 1170 11BE;B6EB;1104 1170 11BE; # (뛫; 뛫; 뛫; 뛫; 뛫; ) HANGUL SYLLABLE DDWEC
+B6EC;B6EC;1104 1170 11BF;B6EC;1104 1170 11BF; # (뛬; 뛬; 뛬; 뛬; 뛬; ) HANGUL SYLLABLE DDWEK
+B6ED;B6ED;1104 1170 11C0;B6ED;1104 1170 11C0; # (뛭; 뛭; 뛭; 뛭; 뛭; ) HANGUL SYLLABLE DDWET
+B6EE;B6EE;1104 1170 11C1;B6EE;1104 1170 11C1; # (뛮; 뛮; 뛮; 뛮; 뛮; ) HANGUL SYLLABLE DDWEP
+B6EF;B6EF;1104 1170 11C2;B6EF;1104 1170 11C2; # (뛯; 뛯; 뛯; 뛯; 뛯; ) HANGUL SYLLABLE DDWEH
+B6F0;B6F0;1104 1171;B6F0;1104 1171; # (뛰; 뛰; 뛰; 뛰; 뛰; ) HANGUL SYLLABLE DDWI
+B6F1;B6F1;1104 1171 11A8;B6F1;1104 1171 11A8; # (뛱; 뛱; 뛱; 뛱; 뛱; ) HANGUL SYLLABLE DDWIG
+B6F2;B6F2;1104 1171 11A9;B6F2;1104 1171 11A9; # (뛲; 뛲; 뛲; 뛲; 뛲; ) HANGUL SYLLABLE DDWIGG
+B6F3;B6F3;1104 1171 11AA;B6F3;1104 1171 11AA; # (뛳; 뛳; 뛳; 뛳; 뛳; ) HANGUL SYLLABLE DDWIGS
+B6F4;B6F4;1104 1171 11AB;B6F4;1104 1171 11AB; # (뛴; 뛴; 뛴; 뛴; 뛴; ) HANGUL SYLLABLE DDWIN
+B6F5;B6F5;1104 1171 11AC;B6F5;1104 1171 11AC; # (뛵; 뛵; 뛵; 뛵; 뛵; ) HANGUL SYLLABLE DDWINJ
+B6F6;B6F6;1104 1171 11AD;B6F6;1104 1171 11AD; # (뛶; 뛶; 뛶; 뛶; 뛶; ) HANGUL SYLLABLE DDWINH
+B6F7;B6F7;1104 1171 11AE;B6F7;1104 1171 11AE; # (뛷; 뛷; 뛷; 뛷; 뛷; ) HANGUL SYLLABLE DDWID
+B6F8;B6F8;1104 1171 11AF;B6F8;1104 1171 11AF; # (뛸; 뛸; 뛸; 뛸; 뛸; ) HANGUL SYLLABLE DDWIL
+B6F9;B6F9;1104 1171 11B0;B6F9;1104 1171 11B0; # (뛹; 뛹; 뛹; 뛹; 뛹; ) HANGUL SYLLABLE DDWILG
+B6FA;B6FA;1104 1171 11B1;B6FA;1104 1171 11B1; # (뛺; 뛺; 뛺; 뛺; 뛺; ) HANGUL SYLLABLE DDWILM
+B6FB;B6FB;1104 1171 11B2;B6FB;1104 1171 11B2; # (뛻; 뛻; 뛻; 뛻; 뛻; ) HANGUL SYLLABLE DDWILB
+B6FC;B6FC;1104 1171 11B3;B6FC;1104 1171 11B3; # (뛼; 뛼; 뛼; 뛼; 뛼; ) HANGUL SYLLABLE DDWILS
+B6FD;B6FD;1104 1171 11B4;B6FD;1104 1171 11B4; # (뛽; 뛽; 뛽; 뛽; 뛽; ) HANGUL SYLLABLE DDWILT
+B6FE;B6FE;1104 1171 11B5;B6FE;1104 1171 11B5; # (뛾; 뛾; 뛾; 뛾; 뛾; ) HANGUL SYLLABLE DDWILP
+B6FF;B6FF;1104 1171 11B6;B6FF;1104 1171 11B6; # (뛿; 뛿; 뛿; 뛿; 뛿; ) HANGUL SYLLABLE DDWILH
+B700;B700;1104 1171 11B7;B700;1104 1171 11B7; # (뜀; 뜀; 뜀; 뜀; 뜀; ) HANGUL SYLLABLE DDWIM
+B701;B701;1104 1171 11B8;B701;1104 1171 11B8; # (뜁; 뜁; 뜁; 뜁; 뜁; ) HANGUL SYLLABLE DDWIB
+B702;B702;1104 1171 11B9;B702;1104 1171 11B9; # (뜂; 뜂; 뜂; 뜂; 뜂; ) HANGUL SYLLABLE DDWIBS
+B703;B703;1104 1171 11BA;B703;1104 1171 11BA; # (뜃; 뜃; 뜃; 뜃; 뜃; ) HANGUL SYLLABLE DDWIS
+B704;B704;1104 1171 11BB;B704;1104 1171 11BB; # (뜄; 뜄; 뜄; 뜄; 뜄; ) HANGUL SYLLABLE DDWISS
+B705;B705;1104 1171 11BC;B705;1104 1171 11BC; # (뜅; 뜅; 뜅; 뜅; 뜅; ) HANGUL SYLLABLE DDWING
+B706;B706;1104 1171 11BD;B706;1104 1171 11BD; # (뜆; 뜆; 뜆; 뜆; 뜆; ) HANGUL SYLLABLE DDWIJ
+B707;B707;1104 1171 11BE;B707;1104 1171 11BE; # (뜇; 뜇; 뜇; 뜇; 뜇; ) HANGUL SYLLABLE DDWIC
+B708;B708;1104 1171 11BF;B708;1104 1171 11BF; # (뜈; 뜈; 뜈; 뜈; 뜈; ) HANGUL SYLLABLE DDWIK
+B709;B709;1104 1171 11C0;B709;1104 1171 11C0; # (뜉; 뜉; 뜉; 뜉; 뜉; ) HANGUL SYLLABLE DDWIT
+B70A;B70A;1104 1171 11C1;B70A;1104 1171 11C1; # (뜊; 뜊; 뜊; 뜊; 뜊; ) HANGUL SYLLABLE DDWIP
+B70B;B70B;1104 1171 11C2;B70B;1104 1171 11C2; # (뜋; 뜋; 뜋; 뜋; 뜋; ) HANGUL SYLLABLE DDWIH
+B70C;B70C;1104 1172;B70C;1104 1172; # (뜌; 뜌; 뜌; 뜌; 뜌; ) HANGUL SYLLABLE DDYU
+B70D;B70D;1104 1172 11A8;B70D;1104 1172 11A8; # (뜍; 뜍; 뜍; 뜍; 뜍; ) HANGUL SYLLABLE DDYUG
+B70E;B70E;1104 1172 11A9;B70E;1104 1172 11A9; # (뜎; 뜎; 뜎; 뜎; 뜎; ) HANGUL SYLLABLE DDYUGG
+B70F;B70F;1104 1172 11AA;B70F;1104 1172 11AA; # (뜏; 뜏; 뜏; 뜏; 뜏; ) HANGUL SYLLABLE DDYUGS
+B710;B710;1104 1172 11AB;B710;1104 1172 11AB; # (뜐; 뜐; 뜐; 뜐; 뜐; ) HANGUL SYLLABLE DDYUN
+B711;B711;1104 1172 11AC;B711;1104 1172 11AC; # (뜑; 뜑; 뜑; 뜑; 뜑; ) HANGUL SYLLABLE DDYUNJ
+B712;B712;1104 1172 11AD;B712;1104 1172 11AD; # (뜒; 뜒; 뜒; 뜒; 뜒; ) HANGUL SYLLABLE DDYUNH
+B713;B713;1104 1172 11AE;B713;1104 1172 11AE; # (뜓; 뜓; 뜓; 뜓; 뜓; ) HANGUL SYLLABLE DDYUD
+B714;B714;1104 1172 11AF;B714;1104 1172 11AF; # (뜔; 뜔; 뜔; 뜔; 뜔; ) HANGUL SYLLABLE DDYUL
+B715;B715;1104 1172 11B0;B715;1104 1172 11B0; # (뜕; 뜕; 뜕; 뜕; 뜕; ) HANGUL SYLLABLE DDYULG
+B716;B716;1104 1172 11B1;B716;1104 1172 11B1; # (뜖; 뜖; 뜖; 뜖; 뜖; ) HANGUL SYLLABLE DDYULM
+B717;B717;1104 1172 11B2;B717;1104 1172 11B2; # (뜗; 뜗; 뜗; 뜗; 뜗; ) HANGUL SYLLABLE DDYULB
+B718;B718;1104 1172 11B3;B718;1104 1172 11B3; # (뜘; 뜘; 뜘; 뜘; 뜘; ) HANGUL SYLLABLE DDYULS
+B719;B719;1104 1172 11B4;B719;1104 1172 11B4; # (뜙; 뜙; 뜙; 뜙; 뜙; ) HANGUL SYLLABLE DDYULT
+B71A;B71A;1104 1172 11B5;B71A;1104 1172 11B5; # (뜚; 뜚; 뜚; 뜚; 뜚; ) HANGUL SYLLABLE DDYULP
+B71B;B71B;1104 1172 11B6;B71B;1104 1172 11B6; # (뜛; 뜛; 뜛; 뜛; 뜛; ) HANGUL SYLLABLE DDYULH
+B71C;B71C;1104 1172 11B7;B71C;1104 1172 11B7; # (뜜; 뜜; 뜜; 뜜; 뜜; ) HANGUL SYLLABLE DDYUM
+B71D;B71D;1104 1172 11B8;B71D;1104 1172 11B8; # (뜝; 뜝; 뜝; 뜝; 뜝; ) HANGUL SYLLABLE DDYUB
+B71E;B71E;1104 1172 11B9;B71E;1104 1172 11B9; # (뜞; 뜞; 뜞; 뜞; 뜞; ) HANGUL SYLLABLE DDYUBS
+B71F;B71F;1104 1172 11BA;B71F;1104 1172 11BA; # (뜟; 뜟; 뜟; 뜟; 뜟; ) HANGUL SYLLABLE DDYUS
+B720;B720;1104 1172 11BB;B720;1104 1172 11BB; # (뜠; 뜠; 뜠; 뜠; 뜠; ) HANGUL SYLLABLE DDYUSS
+B721;B721;1104 1172 11BC;B721;1104 1172 11BC; # (뜡; 뜡; 뜡; 뜡; 뜡; ) HANGUL SYLLABLE DDYUNG
+B722;B722;1104 1172 11BD;B722;1104 1172 11BD; # (뜢; 뜢; 뜢; 뜢; 뜢; ) HANGUL SYLLABLE DDYUJ
+B723;B723;1104 1172 11BE;B723;1104 1172 11BE; # (뜣; 뜣; 뜣; 뜣; 뜣; ) HANGUL SYLLABLE DDYUC
+B724;B724;1104 1172 11BF;B724;1104 1172 11BF; # (뜤; 뜤; 뜤; 뜤; 뜤; ) HANGUL SYLLABLE DDYUK
+B725;B725;1104 1172 11C0;B725;1104 1172 11C0; # (뜥; 뜥; 뜥; 뜥; 뜥; ) HANGUL SYLLABLE DDYUT
+B726;B726;1104 1172 11C1;B726;1104 1172 11C1; # (뜦; 뜦; 뜦; 뜦; 뜦; ) HANGUL SYLLABLE DDYUP
+B727;B727;1104 1172 11C2;B727;1104 1172 11C2; # (뜧; 뜧; 뜧; 뜧; 뜧; ) HANGUL SYLLABLE DDYUH
+B728;B728;1104 1173;B728;1104 1173; # (뜨; 뜨; 뜨; 뜨; 뜨; ) HANGUL SYLLABLE DDEU
+B729;B729;1104 1173 11A8;B729;1104 1173 11A8; # (뜩; 뜩; 뜩; 뜩; 뜩; ) HANGUL SYLLABLE DDEUG
+B72A;B72A;1104 1173 11A9;B72A;1104 1173 11A9; # (뜪; 뜪; 뜪; 뜪; 뜪; ) HANGUL SYLLABLE DDEUGG
+B72B;B72B;1104 1173 11AA;B72B;1104 1173 11AA; # (뜫; 뜫; 뜫; 뜫; 뜫; ) HANGUL SYLLABLE DDEUGS
+B72C;B72C;1104 1173 11AB;B72C;1104 1173 11AB; # (뜬; 뜬; 뜬; 뜬; 뜬; ) HANGUL SYLLABLE DDEUN
+B72D;B72D;1104 1173 11AC;B72D;1104 1173 11AC; # (뜭; 뜭; 뜭; 뜭; 뜭; ) HANGUL SYLLABLE DDEUNJ
+B72E;B72E;1104 1173 11AD;B72E;1104 1173 11AD; # (뜮; 뜮; 뜮; 뜮; 뜮; ) HANGUL SYLLABLE DDEUNH
+B72F;B72F;1104 1173 11AE;B72F;1104 1173 11AE; # (뜯; 뜯; 뜯; 뜯; 뜯; ) HANGUL SYLLABLE DDEUD
+B730;B730;1104 1173 11AF;B730;1104 1173 11AF; # (뜰; 뜰; 뜰; 뜰; 뜰; ) HANGUL SYLLABLE DDEUL
+B731;B731;1104 1173 11B0;B731;1104 1173 11B0; # (뜱; 뜱; 뜱; 뜱; 뜱; ) HANGUL SYLLABLE DDEULG
+B732;B732;1104 1173 11B1;B732;1104 1173 11B1; # (뜲; 뜲; 뜲; 뜲; 뜲; ) HANGUL SYLLABLE DDEULM
+B733;B733;1104 1173 11B2;B733;1104 1173 11B2; # (뜳; 뜳; 뜳; 뜳; 뜳; ) HANGUL SYLLABLE DDEULB
+B734;B734;1104 1173 11B3;B734;1104 1173 11B3; # (뜴; 뜴; 뜴; 뜴; 뜴; ) HANGUL SYLLABLE DDEULS
+B735;B735;1104 1173 11B4;B735;1104 1173 11B4; # (뜵; 뜵; 뜵; 뜵; 뜵; ) HANGUL SYLLABLE DDEULT
+B736;B736;1104 1173 11B5;B736;1104 1173 11B5; # (뜶; 뜶; 뜶; 뜶; 뜶; ) HANGUL SYLLABLE DDEULP
+B737;B737;1104 1173 11B6;B737;1104 1173 11B6; # (뜷; 뜷; 뜷; 뜷; 뜷; ) HANGUL SYLLABLE DDEULH
+B738;B738;1104 1173 11B7;B738;1104 1173 11B7; # (뜸; 뜸; 뜸; 뜸; 뜸; ) HANGUL SYLLABLE DDEUM
+B739;B739;1104 1173 11B8;B739;1104 1173 11B8; # (뜹; 뜹; 뜹; 뜹; 뜹; ) HANGUL SYLLABLE DDEUB
+B73A;B73A;1104 1173 11B9;B73A;1104 1173 11B9; # (뜺; 뜺; 뜺; 뜺; 뜺; ) HANGUL SYLLABLE DDEUBS
+B73B;B73B;1104 1173 11BA;B73B;1104 1173 11BA; # (뜻; 뜻; 뜻; 뜻; 뜻; ) HANGUL SYLLABLE DDEUS
+B73C;B73C;1104 1173 11BB;B73C;1104 1173 11BB; # (뜼; 뜼; 뜼; 뜼; 뜼; ) HANGUL SYLLABLE DDEUSS
+B73D;B73D;1104 1173 11BC;B73D;1104 1173 11BC; # (뜽; 뜽; 뜽; 뜽; 뜽; ) HANGUL SYLLABLE DDEUNG
+B73E;B73E;1104 1173 11BD;B73E;1104 1173 11BD; # (뜾; 뜾; 뜾; 뜾; 뜾; ) HANGUL SYLLABLE DDEUJ
+B73F;B73F;1104 1173 11BE;B73F;1104 1173 11BE; # (뜿; 뜿; 뜿; 뜿; 뜿; ) HANGUL SYLLABLE DDEUC
+B740;B740;1104 1173 11BF;B740;1104 1173 11BF; # (띀; 띀; 띀; 띀; 띀; ) HANGUL SYLLABLE DDEUK
+B741;B741;1104 1173 11C0;B741;1104 1173 11C0; # (띁; 띁; 띁; 띁; 띁; ) HANGUL SYLLABLE DDEUT
+B742;B742;1104 1173 11C1;B742;1104 1173 11C1; # (띂; 띂; 띂; 띂; 띂; ) HANGUL SYLLABLE DDEUP
+B743;B743;1104 1173 11C2;B743;1104 1173 11C2; # (띃; 띃; 띃; 띃; 띃; ) HANGUL SYLLABLE DDEUH
+B744;B744;1104 1174;B744;1104 1174; # (띄; 띄; 띄; 띄; 띄; ) HANGUL SYLLABLE DDYI
+B745;B745;1104 1174 11A8;B745;1104 1174 11A8; # (띅; 띅; 띅; 띅; 띅; ) HANGUL SYLLABLE DDYIG
+B746;B746;1104 1174 11A9;B746;1104 1174 11A9; # (띆; 띆; 띆; 띆; 띆; ) HANGUL SYLLABLE DDYIGG
+B747;B747;1104 1174 11AA;B747;1104 1174 11AA; # (띇; 띇; 띇; 띇; 띇; ) HANGUL SYLLABLE DDYIGS
+B748;B748;1104 1174 11AB;B748;1104 1174 11AB; # (띈; 띈; 띈; 띈; 띈; ) HANGUL SYLLABLE DDYIN
+B749;B749;1104 1174 11AC;B749;1104 1174 11AC; # (띉; 띉; 띉; 띉; 띉; ) HANGUL SYLLABLE DDYINJ
+B74A;B74A;1104 1174 11AD;B74A;1104 1174 11AD; # (띊; 띊; 띊; 띊; 띊; ) HANGUL SYLLABLE DDYINH
+B74B;B74B;1104 1174 11AE;B74B;1104 1174 11AE; # (띋; 띋; 띋; 띋; 띋; ) HANGUL SYLLABLE DDYID
+B74C;B74C;1104 1174 11AF;B74C;1104 1174 11AF; # (띌; 띌; 띌; 띌; 띌; ) HANGUL SYLLABLE DDYIL
+B74D;B74D;1104 1174 11B0;B74D;1104 1174 11B0; # (띍; 띍; 띍; 띍; 띍; ) HANGUL SYLLABLE DDYILG
+B74E;B74E;1104 1174 11B1;B74E;1104 1174 11B1; # (띎; 띎; 띎; 띎; 띎; ) HANGUL SYLLABLE DDYILM
+B74F;B74F;1104 1174 11B2;B74F;1104 1174 11B2; # (띏; 띏; 띏; 띏; 띏; ) HANGUL SYLLABLE DDYILB
+B750;B750;1104 1174 11B3;B750;1104 1174 11B3; # (띐; 띐; 띐; 띐; 띐; ) HANGUL SYLLABLE DDYILS
+B751;B751;1104 1174 11B4;B751;1104 1174 11B4; # (띑; 띑; 띑; 띑; 띑; ) HANGUL SYLLABLE DDYILT
+B752;B752;1104 1174 11B5;B752;1104 1174 11B5; # (띒; 띒; 띒; 띒; 띒; ) HANGUL SYLLABLE DDYILP
+B753;B753;1104 1174 11B6;B753;1104 1174 11B6; # (띓; 띓; 띓; 띓; 띓; ) HANGUL SYLLABLE DDYILH
+B754;B754;1104 1174 11B7;B754;1104 1174 11B7; # (띔; 띔; 띔; 띔; 띔; ) HANGUL SYLLABLE DDYIM
+B755;B755;1104 1174 11B8;B755;1104 1174 11B8; # (띕; 띕; 띕; 띕; 띕; ) HANGUL SYLLABLE DDYIB
+B756;B756;1104 1174 11B9;B756;1104 1174 11B9; # (띖; 띖; 띖; 띖; 띖; ) HANGUL SYLLABLE DDYIBS
+B757;B757;1104 1174 11BA;B757;1104 1174 11BA; # (띗; 띗; 띗; 띗; 띗; ) HANGUL SYLLABLE DDYIS
+B758;B758;1104 1174 11BB;B758;1104 1174 11BB; # (띘; 띘; 띘; 띘; 띘; ) HANGUL SYLLABLE DDYISS
+B759;B759;1104 1174 11BC;B759;1104 1174 11BC; # (띙; 띙; 띙; 띙; 띙; ) HANGUL SYLLABLE DDYING
+B75A;B75A;1104 1174 11BD;B75A;1104 1174 11BD; # (띚; 띚; 띚; 띚; 띚; ) HANGUL SYLLABLE DDYIJ
+B75B;B75B;1104 1174 11BE;B75B;1104 1174 11BE; # (띛; 띛; 띛; 띛; 띛; ) HANGUL SYLLABLE DDYIC
+B75C;B75C;1104 1174 11BF;B75C;1104 1174 11BF; # (띜; 띜; 띜; 띜; 띜; ) HANGUL SYLLABLE DDYIK
+B75D;B75D;1104 1174 11C0;B75D;1104 1174 11C0; # (띝; 띝; 띝; 띝; 띝; ) HANGUL SYLLABLE DDYIT
+B75E;B75E;1104 1174 11C1;B75E;1104 1174 11C1; # (띞; 띞; 띞; 띞; 띞; ) HANGUL SYLLABLE DDYIP
+B75F;B75F;1104 1174 11C2;B75F;1104 1174 11C2; # (띟; 띟; 띟; 띟; 띟; ) HANGUL SYLLABLE DDYIH
+B760;B760;1104 1175;B760;1104 1175; # (띠; 띠; 띠; 띠; 띠; ) HANGUL SYLLABLE DDI
+B761;B761;1104 1175 11A8;B761;1104 1175 11A8; # (띡; 띡; 띡; 띡; 띡; ) HANGUL SYLLABLE DDIG
+B762;B762;1104 1175 11A9;B762;1104 1175 11A9; # (띢; 띢; 띢; 띢; 띢; ) HANGUL SYLLABLE DDIGG
+B763;B763;1104 1175 11AA;B763;1104 1175 11AA; # (띣; 띣; 띣; 띣; 띣; ) HANGUL SYLLABLE DDIGS
+B764;B764;1104 1175 11AB;B764;1104 1175 11AB; # (띤; 띤; 띤; 띤; 띤; ) HANGUL SYLLABLE DDIN
+B765;B765;1104 1175 11AC;B765;1104 1175 11AC; # (띥; 띥; 띥; 띥; 띥; ) HANGUL SYLLABLE DDINJ
+B766;B766;1104 1175 11AD;B766;1104 1175 11AD; # (띦; 띦; 띦; 띦; 띦; ) HANGUL SYLLABLE DDINH
+B767;B767;1104 1175 11AE;B767;1104 1175 11AE; # (띧; 띧; 띧; 띧; 띧; ) HANGUL SYLLABLE DDID
+B768;B768;1104 1175 11AF;B768;1104 1175 11AF; # (띨; 띨; 띨; 띨; 띨; ) HANGUL SYLLABLE DDIL
+B769;B769;1104 1175 11B0;B769;1104 1175 11B0; # (띩; 띩; 띩; 띩; 띩; ) HANGUL SYLLABLE DDILG
+B76A;B76A;1104 1175 11B1;B76A;1104 1175 11B1; # (띪; 띪; 띪; 띪; 띪; ) HANGUL SYLLABLE DDILM
+B76B;B76B;1104 1175 11B2;B76B;1104 1175 11B2; # (띫; 띫; 띫; 띫; 띫; ) HANGUL SYLLABLE DDILB
+B76C;B76C;1104 1175 11B3;B76C;1104 1175 11B3; # (띬; 띬; 띬; 띬; 띬; ) HANGUL SYLLABLE DDILS
+B76D;B76D;1104 1175 11B4;B76D;1104 1175 11B4; # (띭; 띭; 띭; 띭; 띭; ) HANGUL SYLLABLE DDILT
+B76E;B76E;1104 1175 11B5;B76E;1104 1175 11B5; # (띮; 띮; 띮; 띮; 띮; ) HANGUL SYLLABLE DDILP
+B76F;B76F;1104 1175 11B6;B76F;1104 1175 11B6; # (띯; 띯; 띯; 띯; 띯; ) HANGUL SYLLABLE DDILH
+B770;B770;1104 1175 11B7;B770;1104 1175 11B7; # (띰; 띰; 띰; 띰; 띰; ) HANGUL SYLLABLE DDIM
+B771;B771;1104 1175 11B8;B771;1104 1175 11B8; # (띱; 띱; 띱; 띱; 띱; ) HANGUL SYLLABLE DDIB
+B772;B772;1104 1175 11B9;B772;1104 1175 11B9; # (띲; 띲; 띲; 띲; 띲; ) HANGUL SYLLABLE DDIBS
+B773;B773;1104 1175 11BA;B773;1104 1175 11BA; # (띳; 띳; 띳; 띳; 띳; ) HANGUL SYLLABLE DDIS
+B774;B774;1104 1175 11BB;B774;1104 1175 11BB; # (띴; 띴; 띴; 띴; 띴; ) HANGUL SYLLABLE DDISS
+B775;B775;1104 1175 11BC;B775;1104 1175 11BC; # (띵; 띵; 띵; 띵; 띵; ) HANGUL SYLLABLE DDING
+B776;B776;1104 1175 11BD;B776;1104 1175 11BD; # (띶; 띶; 띶; 띶; 띶; ) HANGUL SYLLABLE DDIJ
+B777;B777;1104 1175 11BE;B777;1104 1175 11BE; # (띷; 띷; 띷; 띷; 띷; ) HANGUL SYLLABLE DDIC
+B778;B778;1104 1175 11BF;B778;1104 1175 11BF; # (띸; 띸; 띸; 띸; 띸; ) HANGUL SYLLABLE DDIK
+B779;B779;1104 1175 11C0;B779;1104 1175 11C0; # (띹; 띹; 띹; 띹; 띹; ) HANGUL SYLLABLE DDIT
+B77A;B77A;1104 1175 11C1;B77A;1104 1175 11C1; # (띺; 띺; 띺; 띺; 띺; ) HANGUL SYLLABLE DDIP
+B77B;B77B;1104 1175 11C2;B77B;1104 1175 11C2; # (띻; 띻; 띻; 띻; 띻; ) HANGUL SYLLABLE DDIH
+B77C;B77C;1105 1161;B77C;1105 1161; # (라; 라; 라; 라; 라; ) HANGUL SYLLABLE RA
+B77D;B77D;1105 1161 11A8;B77D;1105 1161 11A8; # (락; 락; 락; 락; 락; ) HANGUL SYLLABLE RAG
+B77E;B77E;1105 1161 11A9;B77E;1105 1161 11A9; # (띾; 띾; 띾; 띾; 띾; ) HANGUL SYLLABLE RAGG
+B77F;B77F;1105 1161 11AA;B77F;1105 1161 11AA; # (띿; 띿; 띿; 띿; 띿; ) HANGUL SYLLABLE RAGS
+B780;B780;1105 1161 11AB;B780;1105 1161 11AB; # (란; 란; 란; 란; 란; ) HANGUL SYLLABLE RAN
+B781;B781;1105 1161 11AC;B781;1105 1161 11AC; # (랁; 랁; 랁; 랁; 랁; ) HANGUL SYLLABLE RANJ
+B782;B782;1105 1161 11AD;B782;1105 1161 11AD; # (랂; 랂; 랂; 랂; 랂; ) HANGUL SYLLABLE RANH
+B783;B783;1105 1161 11AE;B783;1105 1161 11AE; # (랃; 랃; 랃; 랃; 랃; ) HANGUL SYLLABLE RAD
+B784;B784;1105 1161 11AF;B784;1105 1161 11AF; # (랄; 랄; 랄; 랄; 랄; ) HANGUL SYLLABLE RAL
+B785;B785;1105 1161 11B0;B785;1105 1161 11B0; # (랅; 랅; 랅; 랅; 랅; ) HANGUL SYLLABLE RALG
+B786;B786;1105 1161 11B1;B786;1105 1161 11B1; # (랆; 랆; 랆; 랆; 랆; ) HANGUL SYLLABLE RALM
+B787;B787;1105 1161 11B2;B787;1105 1161 11B2; # (랇; 랇; 랇; 랇; 랇; ) HANGUL SYLLABLE RALB
+B788;B788;1105 1161 11B3;B788;1105 1161 11B3; # (랈; 랈; 랈; 랈; 랈; ) HANGUL SYLLABLE RALS
+B789;B789;1105 1161 11B4;B789;1105 1161 11B4; # (랉; 랉; 랉; 랉; 랉; ) HANGUL SYLLABLE RALT
+B78A;B78A;1105 1161 11B5;B78A;1105 1161 11B5; # (랊; 랊; 랊; 랊; 랊; ) HANGUL SYLLABLE RALP
+B78B;B78B;1105 1161 11B6;B78B;1105 1161 11B6; # (랋; 랋; 랋; 랋; 랋; ) HANGUL SYLLABLE RALH
+B78C;B78C;1105 1161 11B7;B78C;1105 1161 11B7; # (람; 람; 람; 람; 람; ) HANGUL SYLLABLE RAM
+B78D;B78D;1105 1161 11B8;B78D;1105 1161 11B8; # (랍; 랍; 랍; 랍; 랍; ) HANGUL SYLLABLE RAB
+B78E;B78E;1105 1161 11B9;B78E;1105 1161 11B9; # (랎; 랎; 랎; 랎; 랎; ) HANGUL SYLLABLE RABS
+B78F;B78F;1105 1161 11BA;B78F;1105 1161 11BA; # (랏; 랏; 랏; 랏; 랏; ) HANGUL SYLLABLE RAS
+B790;B790;1105 1161 11BB;B790;1105 1161 11BB; # (랐; 랐; 랐; 랐; 랐; ) HANGUL SYLLABLE RASS
+B791;B791;1105 1161 11BC;B791;1105 1161 11BC; # (랑; 랑; 랑; 랑; 랑; ) HANGUL SYLLABLE RANG
+B792;B792;1105 1161 11BD;B792;1105 1161 11BD; # (랒; 랒; 랒; 랒; 랒; ) HANGUL SYLLABLE RAJ
+B793;B793;1105 1161 11BE;B793;1105 1161 11BE; # (랓; 랓; 랓; 랓; 랓; ) HANGUL SYLLABLE RAC
+B794;B794;1105 1161 11BF;B794;1105 1161 11BF; # (랔; 랔; 랔; 랔; 랔; ) HANGUL SYLLABLE RAK
+B795;B795;1105 1161 11C0;B795;1105 1161 11C0; # (랕; 랕; 랕; 랕; 랕; ) HANGUL SYLLABLE RAT
+B796;B796;1105 1161 11C1;B796;1105 1161 11C1; # (랖; 랖; 랖; 랖; 랖; ) HANGUL SYLLABLE RAP
+B797;B797;1105 1161 11C2;B797;1105 1161 11C2; # (랗; 랗; 랗; 랗; 랗; ) HANGUL SYLLABLE RAH
+B798;B798;1105 1162;B798;1105 1162; # (래; 래; 래; 래; 래; ) HANGUL SYLLABLE RAE
+B799;B799;1105 1162 11A8;B799;1105 1162 11A8; # (랙; 랙; 랙; 랙; 랙; ) HANGUL SYLLABLE RAEG
+B79A;B79A;1105 1162 11A9;B79A;1105 1162 11A9; # (랚; 랚; 랚; 랚; 랚; ) HANGUL SYLLABLE RAEGG
+B79B;B79B;1105 1162 11AA;B79B;1105 1162 11AA; # (랛; 랛; 랛; 랛; 랛; ) HANGUL SYLLABLE RAEGS
+B79C;B79C;1105 1162 11AB;B79C;1105 1162 11AB; # (랜; 랜; 랜; 랜; 랜; ) HANGUL SYLLABLE RAEN
+B79D;B79D;1105 1162 11AC;B79D;1105 1162 11AC; # (랝; 랝; 랝; 랝; 랝; ) HANGUL SYLLABLE RAENJ
+B79E;B79E;1105 1162 11AD;B79E;1105 1162 11AD; # (랞; 랞; 랞; 랞; 랞; ) HANGUL SYLLABLE RAENH
+B79F;B79F;1105 1162 11AE;B79F;1105 1162 11AE; # (랟; 랟; 랟; 랟; 랟; ) HANGUL SYLLABLE RAED
+B7A0;B7A0;1105 1162 11AF;B7A0;1105 1162 11AF; # (랠; 랠; 랠; 랠; 랠; ) HANGUL SYLLABLE RAEL
+B7A1;B7A1;1105 1162 11B0;B7A1;1105 1162 11B0; # (랡; 랡; 랡; 랡; 랡; ) HANGUL SYLLABLE RAELG
+B7A2;B7A2;1105 1162 11B1;B7A2;1105 1162 11B1; # (랢; 랢; 랢; 랢; 랢; ) HANGUL SYLLABLE RAELM
+B7A3;B7A3;1105 1162 11B2;B7A3;1105 1162 11B2; # (랣; 랣; 랣; 랣; 랣; ) HANGUL SYLLABLE RAELB
+B7A4;B7A4;1105 1162 11B3;B7A4;1105 1162 11B3; # (랤; 랤; 랤; 랤; 랤; ) HANGUL SYLLABLE RAELS
+B7A5;B7A5;1105 1162 11B4;B7A5;1105 1162 11B4; # (랥; 랥; 랥; 랥; 랥; ) HANGUL SYLLABLE RAELT
+B7A6;B7A6;1105 1162 11B5;B7A6;1105 1162 11B5; # (랦; 랦; 랦; 랦; 랦; ) HANGUL SYLLABLE RAELP
+B7A7;B7A7;1105 1162 11B6;B7A7;1105 1162 11B6; # (랧; 랧; 랧; 랧; 랧; ) HANGUL SYLLABLE RAELH
+B7A8;B7A8;1105 1162 11B7;B7A8;1105 1162 11B7; # (램; 램; 램; 램; 램; ) HANGUL SYLLABLE RAEM
+B7A9;B7A9;1105 1162 11B8;B7A9;1105 1162 11B8; # (랩; 랩; 랩; 랩; 랩; ) HANGUL SYLLABLE RAEB
+B7AA;B7AA;1105 1162 11B9;B7AA;1105 1162 11B9; # (랪; 랪; 랪; 랪; 랪; ) HANGUL SYLLABLE RAEBS
+B7AB;B7AB;1105 1162 11BA;B7AB;1105 1162 11BA; # (랫; 랫; 랫; 랫; 랫; ) HANGUL SYLLABLE RAES
+B7AC;B7AC;1105 1162 11BB;B7AC;1105 1162 11BB; # (랬; 랬; 랬; 랬; 랬; ) HANGUL SYLLABLE RAESS
+B7AD;B7AD;1105 1162 11BC;B7AD;1105 1162 11BC; # (랭; 랭; 랭; 랭; 랭; ) HANGUL SYLLABLE RAENG
+B7AE;B7AE;1105 1162 11BD;B7AE;1105 1162 11BD; # (랮; 랮; 랮; 랮; 랮; ) HANGUL SYLLABLE RAEJ
+B7AF;B7AF;1105 1162 11BE;B7AF;1105 1162 11BE; # (랯; 랯; 랯; 랯; 랯; ) HANGUL SYLLABLE RAEC
+B7B0;B7B0;1105 1162 11BF;B7B0;1105 1162 11BF; # (랰; 랰; 랰; 랰; 랰; ) HANGUL SYLLABLE RAEK
+B7B1;B7B1;1105 1162 11C0;B7B1;1105 1162 11C0; # (랱; 랱; 랱; 랱; 랱; ) HANGUL SYLLABLE RAET
+B7B2;B7B2;1105 1162 11C1;B7B2;1105 1162 11C1; # (랲; 랲; 랲; 랲; 랲; ) HANGUL SYLLABLE RAEP
+B7B3;B7B3;1105 1162 11C2;B7B3;1105 1162 11C2; # (랳; 랳; 랳; 랳; 랳; ) HANGUL SYLLABLE RAEH
+B7B4;B7B4;1105 1163;B7B4;1105 1163; # (랴; 랴; 랴; 랴; 랴; ) HANGUL SYLLABLE RYA
+B7B5;B7B5;1105 1163 11A8;B7B5;1105 1163 11A8; # (략; 략; 략; 략; 략; ) HANGUL SYLLABLE RYAG
+B7B6;B7B6;1105 1163 11A9;B7B6;1105 1163 11A9; # (랶; 랶; 랶; 랶; 랶; ) HANGUL SYLLABLE RYAGG
+B7B7;B7B7;1105 1163 11AA;B7B7;1105 1163 11AA; # (랷; 랷; 랷; 랷; 랷; ) HANGUL SYLLABLE RYAGS
+B7B8;B7B8;1105 1163 11AB;B7B8;1105 1163 11AB; # (랸; 랸; 랸; 랸; 랸; ) HANGUL SYLLABLE RYAN
+B7B9;B7B9;1105 1163 11AC;B7B9;1105 1163 11AC; # (랹; 랹; 랹; 랹; 랹; ) HANGUL SYLLABLE RYANJ
+B7BA;B7BA;1105 1163 11AD;B7BA;1105 1163 11AD; # (랺; 랺; 랺; 랺; 랺; ) HANGUL SYLLABLE RYANH
+B7BB;B7BB;1105 1163 11AE;B7BB;1105 1163 11AE; # (랻; 랻; 랻; 랻; 랻; ) HANGUL SYLLABLE RYAD
+B7BC;B7BC;1105 1163 11AF;B7BC;1105 1163 11AF; # (랼; 랼; 랼; 랼; 랼; ) HANGUL SYLLABLE RYAL
+B7BD;B7BD;1105 1163 11B0;B7BD;1105 1163 11B0; # (랽; 랽; 랽; 랽; 랽; ) HANGUL SYLLABLE RYALG
+B7BE;B7BE;1105 1163 11B1;B7BE;1105 1163 11B1; # (랾; 랾; 랾; 랾; 랾; ) HANGUL SYLLABLE RYALM
+B7BF;B7BF;1105 1163 11B2;B7BF;1105 1163 11B2; # (랿; 랿; 랿; 랿; 랿; ) HANGUL SYLLABLE RYALB
+B7C0;B7C0;1105 1163 11B3;B7C0;1105 1163 11B3; # (럀; 럀; 럀; 럀; 럀; ) HANGUL SYLLABLE RYALS
+B7C1;B7C1;1105 1163 11B4;B7C1;1105 1163 11B4; # (럁; 럁; 럁; 럁; 럁; ) HANGUL SYLLABLE RYALT
+B7C2;B7C2;1105 1163 11B5;B7C2;1105 1163 11B5; # (럂; 럂; 럂; 럂; 럂; ) HANGUL SYLLABLE RYALP
+B7C3;B7C3;1105 1163 11B6;B7C3;1105 1163 11B6; # (럃; 럃; 럃; 럃; 럃; ) HANGUL SYLLABLE RYALH
+B7C4;B7C4;1105 1163 11B7;B7C4;1105 1163 11B7; # (럄; 럄; 럄; 럄; 럄; ) HANGUL SYLLABLE RYAM
+B7C5;B7C5;1105 1163 11B8;B7C5;1105 1163 11B8; # (럅; 럅; 럅; 럅; 럅; ) HANGUL SYLLABLE RYAB
+B7C6;B7C6;1105 1163 11B9;B7C6;1105 1163 11B9; # (럆; 럆; 럆; 럆; 럆; ) HANGUL SYLLABLE RYABS
+B7C7;B7C7;1105 1163 11BA;B7C7;1105 1163 11BA; # (럇; 럇; 럇; 럇; 럇; ) HANGUL SYLLABLE RYAS
+B7C8;B7C8;1105 1163 11BB;B7C8;1105 1163 11BB; # (럈; 럈; 럈; 럈; 럈; ) HANGUL SYLLABLE RYASS
+B7C9;B7C9;1105 1163 11BC;B7C9;1105 1163 11BC; # (량; 량; 량; 량; 량; ) HANGUL SYLLABLE RYANG
+B7CA;B7CA;1105 1163 11BD;B7CA;1105 1163 11BD; # (럊; 럊; 럊; 럊; 럊; ) HANGUL SYLLABLE RYAJ
+B7CB;B7CB;1105 1163 11BE;B7CB;1105 1163 11BE; # (럋; 럋; 럋; 럋; 럋; ) HANGUL SYLLABLE RYAC
+B7CC;B7CC;1105 1163 11BF;B7CC;1105 1163 11BF; # (럌; 럌; 럌; 럌; 럌; ) HANGUL SYLLABLE RYAK
+B7CD;B7CD;1105 1163 11C0;B7CD;1105 1163 11C0; # (럍; 럍; 럍; 럍; 럍; ) HANGUL SYLLABLE RYAT
+B7CE;B7CE;1105 1163 11C1;B7CE;1105 1163 11C1; # (럎; 럎; 럎; 럎; 럎; ) HANGUL SYLLABLE RYAP
+B7CF;B7CF;1105 1163 11C2;B7CF;1105 1163 11C2; # (럏; 럏; 럏; 럏; 럏; ) HANGUL SYLLABLE RYAH
+B7D0;B7D0;1105 1164;B7D0;1105 1164; # (럐; 럐; 럐; 럐; 럐; ) HANGUL SYLLABLE RYAE
+B7D1;B7D1;1105 1164 11A8;B7D1;1105 1164 11A8; # (럑; 럑; 럑; 럑; 럑; ) HANGUL SYLLABLE RYAEG
+B7D2;B7D2;1105 1164 11A9;B7D2;1105 1164 11A9; # (럒; 럒; 럒; 럒; 럒; ) HANGUL SYLLABLE RYAEGG
+B7D3;B7D3;1105 1164 11AA;B7D3;1105 1164 11AA; # (럓; 럓; 럓; 럓; 럓; ) HANGUL SYLLABLE RYAEGS
+B7D4;B7D4;1105 1164 11AB;B7D4;1105 1164 11AB; # (럔; 럔; 럔; 럔; 럔; ) HANGUL SYLLABLE RYAEN
+B7D5;B7D5;1105 1164 11AC;B7D5;1105 1164 11AC; # (럕; 럕; 럕; 럕; 럕; ) HANGUL SYLLABLE RYAENJ
+B7D6;B7D6;1105 1164 11AD;B7D6;1105 1164 11AD; # (럖; 럖; 럖; 럖; 럖; ) HANGUL SYLLABLE RYAENH
+B7D7;B7D7;1105 1164 11AE;B7D7;1105 1164 11AE; # (럗; 럗; 럗; 럗; 럗; ) HANGUL SYLLABLE RYAED
+B7D8;B7D8;1105 1164 11AF;B7D8;1105 1164 11AF; # (럘; 럘; 럘; 럘; 럘; ) HANGUL SYLLABLE RYAEL
+B7D9;B7D9;1105 1164 11B0;B7D9;1105 1164 11B0; # (럙; 럙; 럙; 럙; 럙; ) HANGUL SYLLABLE RYAELG
+B7DA;B7DA;1105 1164 11B1;B7DA;1105 1164 11B1; # (럚; 럚; 럚; 럚; 럚; ) HANGUL SYLLABLE RYAELM
+B7DB;B7DB;1105 1164 11B2;B7DB;1105 1164 11B2; # (럛; 럛; 럛; 럛; 럛; ) HANGUL SYLLABLE RYAELB
+B7DC;B7DC;1105 1164 11B3;B7DC;1105 1164 11B3; # (럜; 럜; 럜; 럜; 럜; ) HANGUL SYLLABLE RYAELS
+B7DD;B7DD;1105 1164 11B4;B7DD;1105 1164 11B4; # (럝; 럝; 럝; 럝; 럝; ) HANGUL SYLLABLE RYAELT
+B7DE;B7DE;1105 1164 11B5;B7DE;1105 1164 11B5; # (럞; 럞; 럞; 럞; 럞; ) HANGUL SYLLABLE RYAELP
+B7DF;B7DF;1105 1164 11B6;B7DF;1105 1164 11B6; # (럟; 럟; 럟; 럟; 럟; ) HANGUL SYLLABLE RYAELH
+B7E0;B7E0;1105 1164 11B7;B7E0;1105 1164 11B7; # (럠; 럠; 럠; 럠; 럠; ) HANGUL SYLLABLE RYAEM
+B7E1;B7E1;1105 1164 11B8;B7E1;1105 1164 11B8; # (럡; 럡; 럡; 럡; 럡; ) HANGUL SYLLABLE RYAEB
+B7E2;B7E2;1105 1164 11B9;B7E2;1105 1164 11B9; # (럢; 럢; 럢; 럢; 럢; ) HANGUL SYLLABLE RYAEBS
+B7E3;B7E3;1105 1164 11BA;B7E3;1105 1164 11BA; # (럣; 럣; 럣; 럣; 럣; ) HANGUL SYLLABLE RYAES
+B7E4;B7E4;1105 1164 11BB;B7E4;1105 1164 11BB; # (럤; 럤; 럤; 럤; 럤; ) HANGUL SYLLABLE RYAESS
+B7E5;B7E5;1105 1164 11BC;B7E5;1105 1164 11BC; # (럥; 럥; 럥; 럥; 럥; ) HANGUL SYLLABLE RYAENG
+B7E6;B7E6;1105 1164 11BD;B7E6;1105 1164 11BD; # (럦; 럦; 럦; 럦; 럦; ) HANGUL SYLLABLE RYAEJ
+B7E7;B7E7;1105 1164 11BE;B7E7;1105 1164 11BE; # (럧; 럧; 럧; 럧; 럧; ) HANGUL SYLLABLE RYAEC
+B7E8;B7E8;1105 1164 11BF;B7E8;1105 1164 11BF; # (럨; 럨; 럨; 럨; 럨; ) HANGUL SYLLABLE RYAEK
+B7E9;B7E9;1105 1164 11C0;B7E9;1105 1164 11C0; # (럩; 럩; 럩; 럩; 럩; ) HANGUL SYLLABLE RYAET
+B7EA;B7EA;1105 1164 11C1;B7EA;1105 1164 11C1; # (럪; 럪; 럪; 럪; 럪; ) HANGUL SYLLABLE RYAEP
+B7EB;B7EB;1105 1164 11C2;B7EB;1105 1164 11C2; # (럫; 럫; 럫; 럫; 럫; ) HANGUL SYLLABLE RYAEH
+B7EC;B7EC;1105 1165;B7EC;1105 1165; # (러; 러; 러; 러; 러; ) HANGUL SYLLABLE REO
+B7ED;B7ED;1105 1165 11A8;B7ED;1105 1165 11A8; # (럭; 럭; 럭; 럭; 럭; ) HANGUL SYLLABLE REOG
+B7EE;B7EE;1105 1165 11A9;B7EE;1105 1165 11A9; # (럮; 럮; 럮; 럮; 럮; ) HANGUL SYLLABLE REOGG
+B7EF;B7EF;1105 1165 11AA;B7EF;1105 1165 11AA; # (럯; 럯; 럯; 럯; 럯; ) HANGUL SYLLABLE REOGS
+B7F0;B7F0;1105 1165 11AB;B7F0;1105 1165 11AB; # (런; 런; 런; 런; 런; ) HANGUL SYLLABLE REON
+B7F1;B7F1;1105 1165 11AC;B7F1;1105 1165 11AC; # (럱; 럱; 럱; 럱; 럱; ) HANGUL SYLLABLE REONJ
+B7F2;B7F2;1105 1165 11AD;B7F2;1105 1165 11AD; # (럲; 럲; 럲; 럲; 럲; ) HANGUL SYLLABLE REONH
+B7F3;B7F3;1105 1165 11AE;B7F3;1105 1165 11AE; # (럳; 럳; 럳; 럳; 럳; ) HANGUL SYLLABLE REOD
+B7F4;B7F4;1105 1165 11AF;B7F4;1105 1165 11AF; # (럴; 럴; 럴; 럴; 럴; ) HANGUL SYLLABLE REOL
+B7F5;B7F5;1105 1165 11B0;B7F5;1105 1165 11B0; # (럵; 럵; 럵; 럵; 럵; ) HANGUL SYLLABLE REOLG
+B7F6;B7F6;1105 1165 11B1;B7F6;1105 1165 11B1; # (럶; 럶; 럶; 럶; 럶; ) HANGUL SYLLABLE REOLM
+B7F7;B7F7;1105 1165 11B2;B7F7;1105 1165 11B2; # (럷; 럷; 럷; 럷; 럷; ) HANGUL SYLLABLE REOLB
+B7F8;B7F8;1105 1165 11B3;B7F8;1105 1165 11B3; # (럸; 럸; 럸; 럸; 럸; ) HANGUL SYLLABLE REOLS
+B7F9;B7F9;1105 1165 11B4;B7F9;1105 1165 11B4; # (럹; 럹; 럹; 럹; 럹; ) HANGUL SYLLABLE REOLT
+B7FA;B7FA;1105 1165 11B5;B7FA;1105 1165 11B5; # (럺; 럺; 럺; 럺; 럺; ) HANGUL SYLLABLE REOLP
+B7FB;B7FB;1105 1165 11B6;B7FB;1105 1165 11B6; # (럻; 럻; 럻; 럻; 럻; ) HANGUL SYLLABLE REOLH
+B7FC;B7FC;1105 1165 11B7;B7FC;1105 1165 11B7; # (럼; 럼; 럼; 럼; 럼; ) HANGUL SYLLABLE REOM
+B7FD;B7FD;1105 1165 11B8;B7FD;1105 1165 11B8; # (럽; 럽; 럽; 럽; 럽; ) HANGUL SYLLABLE REOB
+B7FE;B7FE;1105 1165 11B9;B7FE;1105 1165 11B9; # (럾; 럾; 럾; 럾; 럾; ) HANGUL SYLLABLE REOBS
+B7FF;B7FF;1105 1165 11BA;B7FF;1105 1165 11BA; # (럿; 럿; 럿; 럿; 럿; ) HANGUL SYLLABLE REOS
+B800;B800;1105 1165 11BB;B800;1105 1165 11BB; # (렀; 렀; 렀; 렀; 렀; ) HANGUL SYLLABLE REOSS
+B801;B801;1105 1165 11BC;B801;1105 1165 11BC; # (렁; 렁; 렁; 렁; 렁; ) HANGUL SYLLABLE REONG
+B802;B802;1105 1165 11BD;B802;1105 1165 11BD; # (렂; 렂; 렂; 렂; 렂; ) HANGUL SYLLABLE REOJ
+B803;B803;1105 1165 11BE;B803;1105 1165 11BE; # (렃; 렃; 렃; 렃; 렃; ) HANGUL SYLLABLE REOC
+B804;B804;1105 1165 11BF;B804;1105 1165 11BF; # (렄; 렄; 렄; 렄; 렄; ) HANGUL SYLLABLE REOK
+B805;B805;1105 1165 11C0;B805;1105 1165 11C0; # (렅; 렅; 렅; 렅; 렅; ) HANGUL SYLLABLE REOT
+B806;B806;1105 1165 11C1;B806;1105 1165 11C1; # (렆; 렆; 렆; 렆; 렆; ) HANGUL SYLLABLE REOP
+B807;B807;1105 1165 11C2;B807;1105 1165 11C2; # (렇; 렇; 렇; 렇; 렇; ) HANGUL SYLLABLE REOH
+B808;B808;1105 1166;B808;1105 1166; # (레; 레; 레; 레; 레; ) HANGUL SYLLABLE RE
+B809;B809;1105 1166 11A8;B809;1105 1166 11A8; # (렉; 렉; 렉; 렉; 렉; ) HANGUL SYLLABLE REG
+B80A;B80A;1105 1166 11A9;B80A;1105 1166 11A9; # (렊; 렊; 렊; 렊; 렊; ) HANGUL SYLLABLE REGG
+B80B;B80B;1105 1166 11AA;B80B;1105 1166 11AA; # (렋; 렋; 렋; 렋; 렋; ) HANGUL SYLLABLE REGS
+B80C;B80C;1105 1166 11AB;B80C;1105 1166 11AB; # (렌; 렌; 렌; 렌; 렌; ) HANGUL SYLLABLE REN
+B80D;B80D;1105 1166 11AC;B80D;1105 1166 11AC; # (렍; 렍; 렍; 렍; 렍; ) HANGUL SYLLABLE RENJ
+B80E;B80E;1105 1166 11AD;B80E;1105 1166 11AD; # (렎; 렎; 렎; 렎; 렎; ) HANGUL SYLLABLE RENH
+B80F;B80F;1105 1166 11AE;B80F;1105 1166 11AE; # (렏; 렏; 렏; 렏; 렏; ) HANGUL SYLLABLE RED
+B810;B810;1105 1166 11AF;B810;1105 1166 11AF; # (렐; 렐; 렐; 렐; 렐; ) HANGUL SYLLABLE REL
+B811;B811;1105 1166 11B0;B811;1105 1166 11B0; # (렑; 렑; 렑; 렑; 렑; ) HANGUL SYLLABLE RELG
+B812;B812;1105 1166 11B1;B812;1105 1166 11B1; # (렒; 렒; 렒; 렒; 렒; ) HANGUL SYLLABLE RELM
+B813;B813;1105 1166 11B2;B813;1105 1166 11B2; # (렓; 렓; 렓; 렓; 렓; ) HANGUL SYLLABLE RELB
+B814;B814;1105 1166 11B3;B814;1105 1166 11B3; # (렔; 렔; 렔; 렔; 렔; ) HANGUL SYLLABLE RELS
+B815;B815;1105 1166 11B4;B815;1105 1166 11B4; # (렕; 렕; 렕; 렕; 렕; ) HANGUL SYLLABLE RELT
+B816;B816;1105 1166 11B5;B816;1105 1166 11B5; # (렖; 렖; 렖; 렖; 렖; ) HANGUL SYLLABLE RELP
+B817;B817;1105 1166 11B6;B817;1105 1166 11B6; # (렗; 렗; 렗; 렗; 렗; ) HANGUL SYLLABLE RELH
+B818;B818;1105 1166 11B7;B818;1105 1166 11B7; # (렘; 렘; 렘; 렘; 렘; ) HANGUL SYLLABLE REM
+B819;B819;1105 1166 11B8;B819;1105 1166 11B8; # (렙; 렙; 렙; 렙; 렙; ) HANGUL SYLLABLE REB
+B81A;B81A;1105 1166 11B9;B81A;1105 1166 11B9; # (렚; 렚; 렚; 렚; 렚; ) HANGUL SYLLABLE REBS
+B81B;B81B;1105 1166 11BA;B81B;1105 1166 11BA; # (렛; 렛; 렛; 렛; 렛; ) HANGUL SYLLABLE RES
+B81C;B81C;1105 1166 11BB;B81C;1105 1166 11BB; # (렜; 렜; 렜; 렜; 렜; ) HANGUL SYLLABLE RESS
+B81D;B81D;1105 1166 11BC;B81D;1105 1166 11BC; # (렝; 렝; 렝; 렝; 렝; ) HANGUL SYLLABLE RENG
+B81E;B81E;1105 1166 11BD;B81E;1105 1166 11BD; # (렞; 렞; 렞; 렞; 렞; ) HANGUL SYLLABLE REJ
+B81F;B81F;1105 1166 11BE;B81F;1105 1166 11BE; # (렟; 렟; 렟; 렟; 렟; ) HANGUL SYLLABLE REC
+B820;B820;1105 1166 11BF;B820;1105 1166 11BF; # (렠; 렠; 렠; 렠; 렠; ) HANGUL SYLLABLE REK
+B821;B821;1105 1166 11C0;B821;1105 1166 11C0; # (렡; 렡; 렡; 렡; 렡; ) HANGUL SYLLABLE RET
+B822;B822;1105 1166 11C1;B822;1105 1166 11C1; # (렢; 렢; 렢; 렢; 렢; ) HANGUL SYLLABLE REP
+B823;B823;1105 1166 11C2;B823;1105 1166 11C2; # (렣; 렣; 렣; 렣; 렣; ) HANGUL SYLLABLE REH
+B824;B824;1105 1167;B824;1105 1167; # (려; 려; 려; 려; 려; ) HANGUL SYLLABLE RYEO
+B825;B825;1105 1167 11A8;B825;1105 1167 11A8; # (력; 력; 력; 력; 력; ) HANGUL SYLLABLE RYEOG
+B826;B826;1105 1167 11A9;B826;1105 1167 11A9; # (렦; 렦; 렦; 렦; 렦; ) HANGUL SYLLABLE RYEOGG
+B827;B827;1105 1167 11AA;B827;1105 1167 11AA; # (렧; 렧; 렧; 렧; 렧; ) HANGUL SYLLABLE RYEOGS
+B828;B828;1105 1167 11AB;B828;1105 1167 11AB; # (련; 련; 련; 련; 련; ) HANGUL SYLLABLE RYEON
+B829;B829;1105 1167 11AC;B829;1105 1167 11AC; # (렩; 렩; 렩; 렩; 렩; ) HANGUL SYLLABLE RYEONJ
+B82A;B82A;1105 1167 11AD;B82A;1105 1167 11AD; # (렪; 렪; 렪; 렪; 렪; ) HANGUL SYLLABLE RYEONH
+B82B;B82B;1105 1167 11AE;B82B;1105 1167 11AE; # (렫; 렫; 렫; 렫; 렫; ) HANGUL SYLLABLE RYEOD
+B82C;B82C;1105 1167 11AF;B82C;1105 1167 11AF; # (렬; 렬; 렬; 렬; 렬; ) HANGUL SYLLABLE RYEOL
+B82D;B82D;1105 1167 11B0;B82D;1105 1167 11B0; # (렭; 렭; 렭; 렭; 렭; ) HANGUL SYLLABLE RYEOLG
+B82E;B82E;1105 1167 11B1;B82E;1105 1167 11B1; # (렮; 렮; 렮; 렮; 렮; ) HANGUL SYLLABLE RYEOLM
+B82F;B82F;1105 1167 11B2;B82F;1105 1167 11B2; # (렯; 렯; 렯; 렯; 렯; ) HANGUL SYLLABLE RYEOLB
+B830;B830;1105 1167 11B3;B830;1105 1167 11B3; # (렰; 렰; 렰; 렰; 렰; ) HANGUL SYLLABLE RYEOLS
+B831;B831;1105 1167 11B4;B831;1105 1167 11B4; # (렱; 렱; 렱; 렱; 렱; ) HANGUL SYLLABLE RYEOLT
+B832;B832;1105 1167 11B5;B832;1105 1167 11B5; # (렲; 렲; 렲; 렲; 렲; ) HANGUL SYLLABLE RYEOLP
+B833;B833;1105 1167 11B6;B833;1105 1167 11B6; # (렳; 렳; 렳; 렳; 렳; ) HANGUL SYLLABLE RYEOLH
+B834;B834;1105 1167 11B7;B834;1105 1167 11B7; # (렴; 렴; 렴; 렴; 렴; ) HANGUL SYLLABLE RYEOM
+B835;B835;1105 1167 11B8;B835;1105 1167 11B8; # (렵; 렵; 렵; 렵; 렵; ) HANGUL SYLLABLE RYEOB
+B836;B836;1105 1167 11B9;B836;1105 1167 11B9; # (렶; 렶; 렶; 렶; 렶; ) HANGUL SYLLABLE RYEOBS
+B837;B837;1105 1167 11BA;B837;1105 1167 11BA; # (렷; 렷; 렷; 렷; 렷; ) HANGUL SYLLABLE RYEOS
+B838;B838;1105 1167 11BB;B838;1105 1167 11BB; # (렸; 렸; 렸; 렸; 렸; ) HANGUL SYLLABLE RYEOSS
+B839;B839;1105 1167 11BC;B839;1105 1167 11BC; # (령; 령; 령; 령; 령; ) HANGUL SYLLABLE RYEONG
+B83A;B83A;1105 1167 11BD;B83A;1105 1167 11BD; # (렺; 렺; 렺; 렺; 렺; ) HANGUL SYLLABLE RYEOJ
+B83B;B83B;1105 1167 11BE;B83B;1105 1167 11BE; # (렻; 렻; 렻; 렻; 렻; ) HANGUL SYLLABLE RYEOC
+B83C;B83C;1105 1167 11BF;B83C;1105 1167 11BF; # (렼; 렼; 렼; 렼; 렼; ) HANGUL SYLLABLE RYEOK
+B83D;B83D;1105 1167 11C0;B83D;1105 1167 11C0; # (렽; 렽; 렽; 렽; 렽; ) HANGUL SYLLABLE RYEOT
+B83E;B83E;1105 1167 11C1;B83E;1105 1167 11C1; # (렾; 렾; 렾; 렾; 렾; ) HANGUL SYLLABLE RYEOP
+B83F;B83F;1105 1167 11C2;B83F;1105 1167 11C2; # (렿; 렿; 렿; 렿; 렿; ) HANGUL SYLLABLE RYEOH
+B840;B840;1105 1168;B840;1105 1168; # (례; 례; 례; 례; 례; ) HANGUL SYLLABLE RYE
+B841;B841;1105 1168 11A8;B841;1105 1168 11A8; # (롁; 롁; 롁; 롁; 롁; ) HANGUL SYLLABLE RYEG
+B842;B842;1105 1168 11A9;B842;1105 1168 11A9; # (롂; 롂; 롂; 롂; 롂; ) HANGUL SYLLABLE RYEGG
+B843;B843;1105 1168 11AA;B843;1105 1168 11AA; # (롃; 롃; 롃; 롃; 롃; ) HANGUL SYLLABLE RYEGS
+B844;B844;1105 1168 11AB;B844;1105 1168 11AB; # (롄; 롄; 롄; 롄; 롄; ) HANGUL SYLLABLE RYEN
+B845;B845;1105 1168 11AC;B845;1105 1168 11AC; # (롅; 롅; 롅; 롅; 롅; ) HANGUL SYLLABLE RYENJ
+B846;B846;1105 1168 11AD;B846;1105 1168 11AD; # (롆; 롆; 롆; 롆; 롆; ) HANGUL SYLLABLE RYENH
+B847;B847;1105 1168 11AE;B847;1105 1168 11AE; # (롇; 롇; 롇; 롇; 롇; ) HANGUL SYLLABLE RYED
+B848;B848;1105 1168 11AF;B848;1105 1168 11AF; # (롈; 롈; 롈; 롈; 롈; ) HANGUL SYLLABLE RYEL
+B849;B849;1105 1168 11B0;B849;1105 1168 11B0; # (롉; 롉; 롉; 롉; 롉; ) HANGUL SYLLABLE RYELG
+B84A;B84A;1105 1168 11B1;B84A;1105 1168 11B1; # (롊; 롊; 롊; 롊; 롊; ) HANGUL SYLLABLE RYELM
+B84B;B84B;1105 1168 11B2;B84B;1105 1168 11B2; # (롋; 롋; 롋; 롋; 롋; ) HANGUL SYLLABLE RYELB
+B84C;B84C;1105 1168 11B3;B84C;1105 1168 11B3; # (롌; 롌; 롌; 롌; 롌; ) HANGUL SYLLABLE RYELS
+B84D;B84D;1105 1168 11B4;B84D;1105 1168 11B4; # (롍; 롍; 롍; 롍; 롍; ) HANGUL SYLLABLE RYELT
+B84E;B84E;1105 1168 11B5;B84E;1105 1168 11B5; # (롎; 롎; 롎; 롎; 롎; ) HANGUL SYLLABLE RYELP
+B84F;B84F;1105 1168 11B6;B84F;1105 1168 11B6; # (롏; 롏; 롏; 롏; 롏; ) HANGUL SYLLABLE RYELH
+B850;B850;1105 1168 11B7;B850;1105 1168 11B7; # (롐; 롐; 롐; 롐; 롐; ) HANGUL SYLLABLE RYEM
+B851;B851;1105 1168 11B8;B851;1105 1168 11B8; # (롑; 롑; 롑; 롑; 롑; ) HANGUL SYLLABLE RYEB
+B852;B852;1105 1168 11B9;B852;1105 1168 11B9; # (롒; 롒; 롒; 롒; 롒; ) HANGUL SYLLABLE RYEBS
+B853;B853;1105 1168 11BA;B853;1105 1168 11BA; # (롓; 롓; 롓; 롓; 롓; ) HANGUL SYLLABLE RYES
+B854;B854;1105 1168 11BB;B854;1105 1168 11BB; # (롔; 롔; 롔; 롔; 롔; ) HANGUL SYLLABLE RYESS
+B855;B855;1105 1168 11BC;B855;1105 1168 11BC; # (롕; 롕; 롕; 롕; 롕; ) HANGUL SYLLABLE RYENG
+B856;B856;1105 1168 11BD;B856;1105 1168 11BD; # (롖; 롖; 롖; 롖; 롖; ) HANGUL SYLLABLE RYEJ
+B857;B857;1105 1168 11BE;B857;1105 1168 11BE; # (롗; 롗; 롗; 롗; 롗; ) HANGUL SYLLABLE RYEC
+B858;B858;1105 1168 11BF;B858;1105 1168 11BF; # (롘; 롘; 롘; 롘; 롘; ) HANGUL SYLLABLE RYEK
+B859;B859;1105 1168 11C0;B859;1105 1168 11C0; # (롙; 롙; 롙; 롙; 롙; ) HANGUL SYLLABLE RYET
+B85A;B85A;1105 1168 11C1;B85A;1105 1168 11C1; # (롚; 롚; 롚; 롚; 롚; ) HANGUL SYLLABLE RYEP
+B85B;B85B;1105 1168 11C2;B85B;1105 1168 11C2; # (롛; 롛; 롛; 롛; 롛; ) HANGUL SYLLABLE RYEH
+B85C;B85C;1105 1169;B85C;1105 1169; # (로; 로; 로; 로; 로; ) HANGUL SYLLABLE RO
+B85D;B85D;1105 1169 11A8;B85D;1105 1169 11A8; # (록; 록; 록; 록; 록; ) HANGUL SYLLABLE ROG
+B85E;B85E;1105 1169 11A9;B85E;1105 1169 11A9; # (롞; 롞; 롞; 롞; 롞; ) HANGUL SYLLABLE ROGG
+B85F;B85F;1105 1169 11AA;B85F;1105 1169 11AA; # (롟; 롟; 롟; 롟; 롟; ) HANGUL SYLLABLE ROGS
+B860;B860;1105 1169 11AB;B860;1105 1169 11AB; # (론; 론; 론; 론; 론; ) HANGUL SYLLABLE RON
+B861;B861;1105 1169 11AC;B861;1105 1169 11AC; # (롡; 롡; 롡; 롡; 롡; ) HANGUL SYLLABLE RONJ
+B862;B862;1105 1169 11AD;B862;1105 1169 11AD; # (롢; 롢; 롢; 롢; 롢; ) HANGUL SYLLABLE RONH
+B863;B863;1105 1169 11AE;B863;1105 1169 11AE; # (롣; 롣; 롣; 롣; 롣; ) HANGUL SYLLABLE ROD
+B864;B864;1105 1169 11AF;B864;1105 1169 11AF; # (롤; 롤; 롤; 롤; 롤; ) HANGUL SYLLABLE ROL
+B865;B865;1105 1169 11B0;B865;1105 1169 11B0; # (롥; 롥; 롥; 롥; 롥; ) HANGUL SYLLABLE ROLG
+B866;B866;1105 1169 11B1;B866;1105 1169 11B1; # (롦; 롦; 롦; 롦; 롦; ) HANGUL SYLLABLE ROLM
+B867;B867;1105 1169 11B2;B867;1105 1169 11B2; # (롧; 롧; 롧; 롧; 롧; ) HANGUL SYLLABLE ROLB
+B868;B868;1105 1169 11B3;B868;1105 1169 11B3; # (롨; 롨; 롨; 롨; 롨; ) HANGUL SYLLABLE ROLS
+B869;B869;1105 1169 11B4;B869;1105 1169 11B4; # (롩; 롩; 롩; 롩; 롩; ) HANGUL SYLLABLE ROLT
+B86A;B86A;1105 1169 11B5;B86A;1105 1169 11B5; # (롪; 롪; 롪; 롪; 롪; ) HANGUL SYLLABLE ROLP
+B86B;B86B;1105 1169 11B6;B86B;1105 1169 11B6; # (롫; 롫; 롫; 롫; 롫; ) HANGUL SYLLABLE ROLH
+B86C;B86C;1105 1169 11B7;B86C;1105 1169 11B7; # (롬; 롬; 롬; 롬; 롬; ) HANGUL SYLLABLE ROM
+B86D;B86D;1105 1169 11B8;B86D;1105 1169 11B8; # (롭; 롭; 롭; 롭; 롭; ) HANGUL SYLLABLE ROB
+B86E;B86E;1105 1169 11B9;B86E;1105 1169 11B9; # (롮; 롮; 롮; 롮; 롮; ) HANGUL SYLLABLE ROBS
+B86F;B86F;1105 1169 11BA;B86F;1105 1169 11BA; # (롯; 롯; 롯; 롯; 롯; ) HANGUL SYLLABLE ROS
+B870;B870;1105 1169 11BB;B870;1105 1169 11BB; # (롰; 롰; 롰; 롰; 롰; ) HANGUL SYLLABLE ROSS
+B871;B871;1105 1169 11BC;B871;1105 1169 11BC; # (롱; 롱; 롱; 롱; 롱; ) HANGUL SYLLABLE RONG
+B872;B872;1105 1169 11BD;B872;1105 1169 11BD; # (롲; 롲; 롲; 롲; 롲; ) HANGUL SYLLABLE ROJ
+B873;B873;1105 1169 11BE;B873;1105 1169 11BE; # (롳; 롳; 롳; 롳; 롳; ) HANGUL SYLLABLE ROC
+B874;B874;1105 1169 11BF;B874;1105 1169 11BF; # (롴; 롴; 롴; 롴; 롴; ) HANGUL SYLLABLE ROK
+B875;B875;1105 1169 11C0;B875;1105 1169 11C0; # (롵; 롵; 롵; 롵; 롵; ) HANGUL SYLLABLE ROT
+B876;B876;1105 1169 11C1;B876;1105 1169 11C1; # (롶; 롶; 롶; 롶; 롶; ) HANGUL SYLLABLE ROP
+B877;B877;1105 1169 11C2;B877;1105 1169 11C2; # (롷; 롷; 롷; 롷; 롷; ) HANGUL SYLLABLE ROH
+B878;B878;1105 116A;B878;1105 116A; # (롸; 롸; 롸; 롸; 롸; ) HANGUL SYLLABLE RWA
+B879;B879;1105 116A 11A8;B879;1105 116A 11A8; # (롹; 롹; 롹; 롹; 롹; ) HANGUL SYLLABLE RWAG
+B87A;B87A;1105 116A 11A9;B87A;1105 116A 11A9; # (롺; 롺; 롺; 롺; 롺; ) HANGUL SYLLABLE RWAGG
+B87B;B87B;1105 116A 11AA;B87B;1105 116A 11AA; # (롻; 롻; 롻; 롻; 롻; ) HANGUL SYLLABLE RWAGS
+B87C;B87C;1105 116A 11AB;B87C;1105 116A 11AB; # (롼; 롼; 롼; 롼; 롼; ) HANGUL SYLLABLE RWAN
+B87D;B87D;1105 116A 11AC;B87D;1105 116A 11AC; # (롽; 롽; 롽; 롽; 롽; ) HANGUL SYLLABLE RWANJ
+B87E;B87E;1105 116A 11AD;B87E;1105 116A 11AD; # (롾; 롾; 롾; 롾; 롾; ) HANGUL SYLLABLE RWANH
+B87F;B87F;1105 116A 11AE;B87F;1105 116A 11AE; # (롿; 롿; 롿; 롿; 롿; ) HANGUL SYLLABLE RWAD
+B880;B880;1105 116A 11AF;B880;1105 116A 11AF; # (뢀; 뢀; 뢀; 뢀; 뢀; ) HANGUL SYLLABLE RWAL
+B881;B881;1105 116A 11B0;B881;1105 116A 11B0; # (뢁; 뢁; 뢁; 뢁; 뢁; ) HANGUL SYLLABLE RWALG
+B882;B882;1105 116A 11B1;B882;1105 116A 11B1; # (뢂; 뢂; 뢂; 뢂; 뢂; ) HANGUL SYLLABLE RWALM
+B883;B883;1105 116A 11B2;B883;1105 116A 11B2; # (뢃; 뢃; 뢃; 뢃; 뢃; ) HANGUL SYLLABLE RWALB
+B884;B884;1105 116A 11B3;B884;1105 116A 11B3; # (뢄; 뢄; 뢄; 뢄; 뢄; ) HANGUL SYLLABLE RWALS
+B885;B885;1105 116A 11B4;B885;1105 116A 11B4; # (뢅; 뢅; 뢅; 뢅; 뢅; ) HANGUL SYLLABLE RWALT
+B886;B886;1105 116A 11B5;B886;1105 116A 11B5; # (뢆; 뢆; 뢆; 뢆; 뢆; ) HANGUL SYLLABLE RWALP
+B887;B887;1105 116A 11B6;B887;1105 116A 11B6; # (뢇; 뢇; 뢇; 뢇; 뢇; ) HANGUL SYLLABLE RWALH
+B888;B888;1105 116A 11B7;B888;1105 116A 11B7; # (뢈; 뢈; 뢈; 뢈; 뢈; ) HANGUL SYLLABLE RWAM
+B889;B889;1105 116A 11B8;B889;1105 116A 11B8; # (뢉; 뢉; 뢉; 뢉; 뢉; ) HANGUL SYLLABLE RWAB
+B88A;B88A;1105 116A 11B9;B88A;1105 116A 11B9; # (뢊; 뢊; 뢊; 뢊; 뢊; ) HANGUL SYLLABLE RWABS
+B88B;B88B;1105 116A 11BA;B88B;1105 116A 11BA; # (뢋; 뢋; 뢋; 뢋; 뢋; ) HANGUL SYLLABLE RWAS
+B88C;B88C;1105 116A 11BB;B88C;1105 116A 11BB; # (뢌; 뢌; 뢌; 뢌; 뢌; ) HANGUL SYLLABLE RWASS
+B88D;B88D;1105 116A 11BC;B88D;1105 116A 11BC; # (뢍; 뢍; 뢍; 뢍; 뢍; ) HANGUL SYLLABLE RWANG
+B88E;B88E;1105 116A 11BD;B88E;1105 116A 11BD; # (뢎; 뢎; 뢎; 뢎; 뢎; ) HANGUL SYLLABLE RWAJ
+B88F;B88F;1105 116A 11BE;B88F;1105 116A 11BE; # (뢏; 뢏; 뢏; 뢏; 뢏; ) HANGUL SYLLABLE RWAC
+B890;B890;1105 116A 11BF;B890;1105 116A 11BF; # (뢐; 뢐; 뢐; 뢐; 뢐; ) HANGUL SYLLABLE RWAK
+B891;B891;1105 116A 11C0;B891;1105 116A 11C0; # (뢑; 뢑; 뢑; 뢑; 뢑; ) HANGUL SYLLABLE RWAT
+B892;B892;1105 116A 11C1;B892;1105 116A 11C1; # (뢒; 뢒; 뢒; 뢒; 뢒; ) HANGUL SYLLABLE RWAP
+B893;B893;1105 116A 11C2;B893;1105 116A 11C2; # (뢓; 뢓; 뢓; 뢓; 뢓; ) HANGUL SYLLABLE RWAH
+B894;B894;1105 116B;B894;1105 116B; # (뢔; 뢔; 뢔; 뢔; 뢔; ) HANGUL SYLLABLE RWAE
+B895;B895;1105 116B 11A8;B895;1105 116B 11A8; # (뢕; 뢕; 뢕; 뢕; 뢕; ) HANGUL SYLLABLE RWAEG
+B896;B896;1105 116B 11A9;B896;1105 116B 11A9; # (뢖; 뢖; 뢖; 뢖; 뢖; ) HANGUL SYLLABLE RWAEGG
+B897;B897;1105 116B 11AA;B897;1105 116B 11AA; # (뢗; 뢗; 뢗; 뢗; 뢗; ) HANGUL SYLLABLE RWAEGS
+B898;B898;1105 116B 11AB;B898;1105 116B 11AB; # (뢘; 뢘; 뢘; 뢘; 뢘; ) HANGUL SYLLABLE RWAEN
+B899;B899;1105 116B 11AC;B899;1105 116B 11AC; # (뢙; 뢙; 뢙; 뢙; 뢙; ) HANGUL SYLLABLE RWAENJ
+B89A;B89A;1105 116B 11AD;B89A;1105 116B 11AD; # (뢚; 뢚; 뢚; 뢚; 뢚; ) HANGUL SYLLABLE RWAENH
+B89B;B89B;1105 116B 11AE;B89B;1105 116B 11AE; # (뢛; 뢛; 뢛; 뢛; 뢛; ) HANGUL SYLLABLE RWAED
+B89C;B89C;1105 116B 11AF;B89C;1105 116B 11AF; # (뢜; 뢜; 뢜; 뢜; 뢜; ) HANGUL SYLLABLE RWAEL
+B89D;B89D;1105 116B 11B0;B89D;1105 116B 11B0; # (뢝; 뢝; 뢝; 뢝; 뢝; ) HANGUL SYLLABLE RWAELG
+B89E;B89E;1105 116B 11B1;B89E;1105 116B 11B1; # (뢞; 뢞; 뢞; 뢞; 뢞; ) HANGUL SYLLABLE RWAELM
+B89F;B89F;1105 116B 11B2;B89F;1105 116B 11B2; # (뢟; 뢟; 뢟; 뢟; 뢟; ) HANGUL SYLLABLE RWAELB
+B8A0;B8A0;1105 116B 11B3;B8A0;1105 116B 11B3; # (뢠; 뢠; 뢠; 뢠; 뢠; ) HANGUL SYLLABLE RWAELS
+B8A1;B8A1;1105 116B 11B4;B8A1;1105 116B 11B4; # (뢡; 뢡; 뢡; 뢡; 뢡; ) HANGUL SYLLABLE RWAELT
+B8A2;B8A2;1105 116B 11B5;B8A2;1105 116B 11B5; # (뢢; 뢢; 뢢; 뢢; 뢢; ) HANGUL SYLLABLE RWAELP
+B8A3;B8A3;1105 116B 11B6;B8A3;1105 116B 11B6; # (뢣; 뢣; 뢣; 뢣; 뢣; ) HANGUL SYLLABLE RWAELH
+B8A4;B8A4;1105 116B 11B7;B8A4;1105 116B 11B7; # (뢤; 뢤; 뢤; 뢤; 뢤; ) HANGUL SYLLABLE RWAEM
+B8A5;B8A5;1105 116B 11B8;B8A5;1105 116B 11B8; # (뢥; 뢥; 뢥; 뢥; 뢥; ) HANGUL SYLLABLE RWAEB
+B8A6;B8A6;1105 116B 11B9;B8A6;1105 116B 11B9; # (뢦; 뢦; 뢦; 뢦; 뢦; ) HANGUL SYLLABLE RWAEBS
+B8A7;B8A7;1105 116B 11BA;B8A7;1105 116B 11BA; # (뢧; 뢧; 뢧; 뢧; 뢧; ) HANGUL SYLLABLE RWAES
+B8A8;B8A8;1105 116B 11BB;B8A8;1105 116B 11BB; # (뢨; 뢨; 뢨; 뢨; 뢨; ) HANGUL SYLLABLE RWAESS
+B8A9;B8A9;1105 116B 11BC;B8A9;1105 116B 11BC; # (뢩; 뢩; 뢩; 뢩; 뢩; ) HANGUL SYLLABLE RWAENG
+B8AA;B8AA;1105 116B 11BD;B8AA;1105 116B 11BD; # (뢪; 뢪; 뢪; 뢪; 뢪; ) HANGUL SYLLABLE RWAEJ
+B8AB;B8AB;1105 116B 11BE;B8AB;1105 116B 11BE; # (뢫; 뢫; 뢫; 뢫; 뢫; ) HANGUL SYLLABLE RWAEC
+B8AC;B8AC;1105 116B 11BF;B8AC;1105 116B 11BF; # (뢬; 뢬; 뢬; 뢬; 뢬; ) HANGUL SYLLABLE RWAEK
+B8AD;B8AD;1105 116B 11C0;B8AD;1105 116B 11C0; # (뢭; 뢭; 뢭; 뢭; 뢭; ) HANGUL SYLLABLE RWAET
+B8AE;B8AE;1105 116B 11C1;B8AE;1105 116B 11C1; # (뢮; 뢮; 뢮; 뢮; 뢮; ) HANGUL SYLLABLE RWAEP
+B8AF;B8AF;1105 116B 11C2;B8AF;1105 116B 11C2; # (뢯; 뢯; 뢯; 뢯; 뢯; ) HANGUL SYLLABLE RWAEH
+B8B0;B8B0;1105 116C;B8B0;1105 116C; # (뢰; 뢰; 뢰; 뢰; 뢰; ) HANGUL SYLLABLE ROE
+B8B1;B8B1;1105 116C 11A8;B8B1;1105 116C 11A8; # (뢱; 뢱; 뢱; 뢱; 뢱; ) HANGUL SYLLABLE ROEG
+B8B2;B8B2;1105 116C 11A9;B8B2;1105 116C 11A9; # (뢲; 뢲; 뢲; 뢲; 뢲; ) HANGUL SYLLABLE ROEGG
+B8B3;B8B3;1105 116C 11AA;B8B3;1105 116C 11AA; # (뢳; 뢳; 뢳; 뢳; 뢳; ) HANGUL SYLLABLE ROEGS
+B8B4;B8B4;1105 116C 11AB;B8B4;1105 116C 11AB; # (뢴; 뢴; 뢴; 뢴; 뢴; ) HANGUL SYLLABLE ROEN
+B8B5;B8B5;1105 116C 11AC;B8B5;1105 116C 11AC; # (뢵; 뢵; 뢵; 뢵; 뢵; ) HANGUL SYLLABLE ROENJ
+B8B6;B8B6;1105 116C 11AD;B8B6;1105 116C 11AD; # (뢶; 뢶; 뢶; 뢶; 뢶; ) HANGUL SYLLABLE ROENH
+B8B7;B8B7;1105 116C 11AE;B8B7;1105 116C 11AE; # (뢷; 뢷; 뢷; 뢷; 뢷; ) HANGUL SYLLABLE ROED
+B8B8;B8B8;1105 116C 11AF;B8B8;1105 116C 11AF; # (뢸; 뢸; 뢸; 뢸; 뢸; ) HANGUL SYLLABLE ROEL
+B8B9;B8B9;1105 116C 11B0;B8B9;1105 116C 11B0; # (뢹; 뢹; 뢹; 뢹; 뢹; ) HANGUL SYLLABLE ROELG
+B8BA;B8BA;1105 116C 11B1;B8BA;1105 116C 11B1; # (뢺; 뢺; 뢺; 뢺; 뢺; ) HANGUL SYLLABLE ROELM
+B8BB;B8BB;1105 116C 11B2;B8BB;1105 116C 11B2; # (뢻; 뢻; 뢻; 뢻; 뢻; ) HANGUL SYLLABLE ROELB
+B8BC;B8BC;1105 116C 11B3;B8BC;1105 116C 11B3; # (뢼; 뢼; 뢼; 뢼; 뢼; ) HANGUL SYLLABLE ROELS
+B8BD;B8BD;1105 116C 11B4;B8BD;1105 116C 11B4; # (뢽; 뢽; 뢽; 뢽; 뢽; ) HANGUL SYLLABLE ROELT
+B8BE;B8BE;1105 116C 11B5;B8BE;1105 116C 11B5; # (뢾; 뢾; 뢾; 뢾; 뢾; ) HANGUL SYLLABLE ROELP
+B8BF;B8BF;1105 116C 11B6;B8BF;1105 116C 11B6; # (뢿; 뢿; 뢿; 뢿; 뢿; ) HANGUL SYLLABLE ROELH
+B8C0;B8C0;1105 116C 11B7;B8C0;1105 116C 11B7; # (룀; 룀; 룀; 룀; 룀; ) HANGUL SYLLABLE ROEM
+B8C1;B8C1;1105 116C 11B8;B8C1;1105 116C 11B8; # (룁; 룁; 룁; 룁; 룁; ) HANGUL SYLLABLE ROEB
+B8C2;B8C2;1105 116C 11B9;B8C2;1105 116C 11B9; # (룂; 룂; 룂; 룂; 룂; ) HANGUL SYLLABLE ROEBS
+B8C3;B8C3;1105 116C 11BA;B8C3;1105 116C 11BA; # (룃; 룃; 룃; 룃; 룃; ) HANGUL SYLLABLE ROES
+B8C4;B8C4;1105 116C 11BB;B8C4;1105 116C 11BB; # (룄; 룄; 룄; 룄; 룄; ) HANGUL SYLLABLE ROESS
+B8C5;B8C5;1105 116C 11BC;B8C5;1105 116C 11BC; # (룅; 룅; 룅; 룅; 룅; ) HANGUL SYLLABLE ROENG
+B8C6;B8C6;1105 116C 11BD;B8C6;1105 116C 11BD; # (룆; 룆; 룆; 룆; 룆; ) HANGUL SYLLABLE ROEJ
+B8C7;B8C7;1105 116C 11BE;B8C7;1105 116C 11BE; # (룇; 룇; 룇; 룇; 룇; ) HANGUL SYLLABLE ROEC
+B8C8;B8C8;1105 116C 11BF;B8C8;1105 116C 11BF; # (룈; 룈; 룈; 룈; 룈; ) HANGUL SYLLABLE ROEK
+B8C9;B8C9;1105 116C 11C0;B8C9;1105 116C 11C0; # (룉; 룉; 룉; 룉; 룉; ) HANGUL SYLLABLE ROET
+B8CA;B8CA;1105 116C 11C1;B8CA;1105 116C 11C1; # (룊; 룊; 룊; 룊; 룊; ) HANGUL SYLLABLE ROEP
+B8CB;B8CB;1105 116C 11C2;B8CB;1105 116C 11C2; # (룋; 룋; 룋; 룋; 룋; ) HANGUL SYLLABLE ROEH
+B8CC;B8CC;1105 116D;B8CC;1105 116D; # (료; 료; 료; 료; 료; ) HANGUL SYLLABLE RYO
+B8CD;B8CD;1105 116D 11A8;B8CD;1105 116D 11A8; # (룍; 룍; 룍; 룍; 룍; ) HANGUL SYLLABLE RYOG
+B8CE;B8CE;1105 116D 11A9;B8CE;1105 116D 11A9; # (룎; 룎; 룎; 룎; 룎; ) HANGUL SYLLABLE RYOGG
+B8CF;B8CF;1105 116D 11AA;B8CF;1105 116D 11AA; # (룏; 룏; 룏; 룏; 룏; ) HANGUL SYLLABLE RYOGS
+B8D0;B8D0;1105 116D 11AB;B8D0;1105 116D 11AB; # (룐; 룐; 룐; 룐; 룐; ) HANGUL SYLLABLE RYON
+B8D1;B8D1;1105 116D 11AC;B8D1;1105 116D 11AC; # (룑; 룑; 룑; 룑; 룑; ) HANGUL SYLLABLE RYONJ
+B8D2;B8D2;1105 116D 11AD;B8D2;1105 116D 11AD; # (룒; 룒; 룒; 룒; 룒; ) HANGUL SYLLABLE RYONH
+B8D3;B8D3;1105 116D 11AE;B8D3;1105 116D 11AE; # (룓; 룓; 룓; 룓; 룓; ) HANGUL SYLLABLE RYOD
+B8D4;B8D4;1105 116D 11AF;B8D4;1105 116D 11AF; # (룔; 룔; 룔; 룔; 룔; ) HANGUL SYLLABLE RYOL
+B8D5;B8D5;1105 116D 11B0;B8D5;1105 116D 11B0; # (룕; 룕; 룕; 룕; 룕; ) HANGUL SYLLABLE RYOLG
+B8D6;B8D6;1105 116D 11B1;B8D6;1105 116D 11B1; # (룖; 룖; 룖; 룖; 룖; ) HANGUL SYLLABLE RYOLM
+B8D7;B8D7;1105 116D 11B2;B8D7;1105 116D 11B2; # (룗; 룗; 룗; 룗; 룗; ) HANGUL SYLLABLE RYOLB
+B8D8;B8D8;1105 116D 11B3;B8D8;1105 116D 11B3; # (룘; 룘; 룘; 룘; 룘; ) HANGUL SYLLABLE RYOLS
+B8D9;B8D9;1105 116D 11B4;B8D9;1105 116D 11B4; # (룙; 룙; 룙; 룙; 룙; ) HANGUL SYLLABLE RYOLT
+B8DA;B8DA;1105 116D 11B5;B8DA;1105 116D 11B5; # (룚; 룚; 룚; 룚; 룚; ) HANGUL SYLLABLE RYOLP
+B8DB;B8DB;1105 116D 11B6;B8DB;1105 116D 11B6; # (룛; 룛; 룛; 룛; 룛; ) HANGUL SYLLABLE RYOLH
+B8DC;B8DC;1105 116D 11B7;B8DC;1105 116D 11B7; # (룜; 룜; 룜; 룜; 룜; ) HANGUL SYLLABLE RYOM
+B8DD;B8DD;1105 116D 11B8;B8DD;1105 116D 11B8; # (룝; 룝; 룝; 룝; 룝; ) HANGUL SYLLABLE RYOB
+B8DE;B8DE;1105 116D 11B9;B8DE;1105 116D 11B9; # (룞; 룞; 룞; 룞; 룞; ) HANGUL SYLLABLE RYOBS
+B8DF;B8DF;1105 116D 11BA;B8DF;1105 116D 11BA; # (룟; 룟; 룟; 룟; 룟; ) HANGUL SYLLABLE RYOS
+B8E0;B8E0;1105 116D 11BB;B8E0;1105 116D 11BB; # (룠; 룠; 룠; 룠; 룠; ) HANGUL SYLLABLE RYOSS
+B8E1;B8E1;1105 116D 11BC;B8E1;1105 116D 11BC; # (룡; 룡; 룡; 룡; 룡; ) HANGUL SYLLABLE RYONG
+B8E2;B8E2;1105 116D 11BD;B8E2;1105 116D 11BD; # (룢; 룢; 룢; 룢; 룢; ) HANGUL SYLLABLE RYOJ
+B8E3;B8E3;1105 116D 11BE;B8E3;1105 116D 11BE; # (룣; 룣; 룣; 룣; 룣; ) HANGUL SYLLABLE RYOC
+B8E4;B8E4;1105 116D 11BF;B8E4;1105 116D 11BF; # (룤; 룤; 룤; 룤; 룤; ) HANGUL SYLLABLE RYOK
+B8E5;B8E5;1105 116D 11C0;B8E5;1105 116D 11C0; # (룥; 룥; 룥; 룥; 룥; ) HANGUL SYLLABLE RYOT
+B8E6;B8E6;1105 116D 11C1;B8E6;1105 116D 11C1; # (룦; 룦; 룦; 룦; 룦; ) HANGUL SYLLABLE RYOP
+B8E7;B8E7;1105 116D 11C2;B8E7;1105 116D 11C2; # (룧; 룧; 룧; 룧; 룧; ) HANGUL SYLLABLE RYOH
+B8E8;B8E8;1105 116E;B8E8;1105 116E; # (루; 루; 루; 루; 루; ) HANGUL SYLLABLE RU
+B8E9;B8E9;1105 116E 11A8;B8E9;1105 116E 11A8; # (룩; 룩; 룩; 룩; 룩; ) HANGUL SYLLABLE RUG
+B8EA;B8EA;1105 116E 11A9;B8EA;1105 116E 11A9; # (룪; 룪; 룪; 룪; 룪; ) HANGUL SYLLABLE RUGG
+B8EB;B8EB;1105 116E 11AA;B8EB;1105 116E 11AA; # (룫; 룫; 룫; 룫; 룫; ) HANGUL SYLLABLE RUGS
+B8EC;B8EC;1105 116E 11AB;B8EC;1105 116E 11AB; # (룬; 룬; 룬; 룬; 룬; ) HANGUL SYLLABLE RUN
+B8ED;B8ED;1105 116E 11AC;B8ED;1105 116E 11AC; # (룭; 룭; 룭; 룭; 룭; ) HANGUL SYLLABLE RUNJ
+B8EE;B8EE;1105 116E 11AD;B8EE;1105 116E 11AD; # (룮; 룮; 룮; 룮; 룮; ) HANGUL SYLLABLE RUNH
+B8EF;B8EF;1105 116E 11AE;B8EF;1105 116E 11AE; # (룯; 룯; 룯; 룯; 룯; ) HANGUL SYLLABLE RUD
+B8F0;B8F0;1105 116E 11AF;B8F0;1105 116E 11AF; # (룰; 룰; 룰; 룰; 룰; ) HANGUL SYLLABLE RUL
+B8F1;B8F1;1105 116E 11B0;B8F1;1105 116E 11B0; # (룱; 룱; 룱; 룱; 룱; ) HANGUL SYLLABLE RULG
+B8F2;B8F2;1105 116E 11B1;B8F2;1105 116E 11B1; # (룲; 룲; 룲; 룲; 룲; ) HANGUL SYLLABLE RULM
+B8F3;B8F3;1105 116E 11B2;B8F3;1105 116E 11B2; # (룳; 룳; 룳; 룳; 룳; ) HANGUL SYLLABLE RULB
+B8F4;B8F4;1105 116E 11B3;B8F4;1105 116E 11B3; # (룴; 룴; 룴; 룴; 룴; ) HANGUL SYLLABLE RULS
+B8F5;B8F5;1105 116E 11B4;B8F5;1105 116E 11B4; # (룵; 룵; 룵; 룵; 룵; ) HANGUL SYLLABLE RULT
+B8F6;B8F6;1105 116E 11B5;B8F6;1105 116E 11B5; # (룶; 룶; 룶; 룶; 룶; ) HANGUL SYLLABLE RULP
+B8F7;B8F7;1105 116E 11B6;B8F7;1105 116E 11B6; # (룷; 룷; 룷; 룷; 룷; ) HANGUL SYLLABLE RULH
+B8F8;B8F8;1105 116E 11B7;B8F8;1105 116E 11B7; # (룸; 룸; 룸; 룸; 룸; ) HANGUL SYLLABLE RUM
+B8F9;B8F9;1105 116E 11B8;B8F9;1105 116E 11B8; # (룹; 룹; 룹; 룹; 룹; ) HANGUL SYLLABLE RUB
+B8FA;B8FA;1105 116E 11B9;B8FA;1105 116E 11B9; # (룺; 룺; 룺; 룺; 룺; ) HANGUL SYLLABLE RUBS
+B8FB;B8FB;1105 116E 11BA;B8FB;1105 116E 11BA; # (룻; 룻; 룻; 룻; 룻; ) HANGUL SYLLABLE RUS
+B8FC;B8FC;1105 116E 11BB;B8FC;1105 116E 11BB; # (룼; 룼; 룼; 룼; 룼; ) HANGUL SYLLABLE RUSS
+B8FD;B8FD;1105 116E 11BC;B8FD;1105 116E 11BC; # (룽; 룽; 룽; 룽; 룽; ) HANGUL SYLLABLE RUNG
+B8FE;B8FE;1105 116E 11BD;B8FE;1105 116E 11BD; # (룾; 룾; 룾; 룾; 룾; ) HANGUL SYLLABLE RUJ
+B8FF;B8FF;1105 116E 11BE;B8FF;1105 116E 11BE; # (룿; 룿; 룿; 룿; 룿; ) HANGUL SYLLABLE RUC
+B900;B900;1105 116E 11BF;B900;1105 116E 11BF; # (뤀; 뤀; 뤀; 뤀; 뤀; ) HANGUL SYLLABLE RUK
+B901;B901;1105 116E 11C0;B901;1105 116E 11C0; # (뤁; 뤁; 뤁; 뤁; 뤁; ) HANGUL SYLLABLE RUT
+B902;B902;1105 116E 11C1;B902;1105 116E 11C1; # (뤂; 뤂; 뤂; 뤂; 뤂; ) HANGUL SYLLABLE RUP
+B903;B903;1105 116E 11C2;B903;1105 116E 11C2; # (뤃; 뤃; 뤃; 뤃; 뤃; ) HANGUL SYLLABLE RUH
+B904;B904;1105 116F;B904;1105 116F; # (뤄; 뤄; 뤄; 뤄; 뤄; ) HANGUL SYLLABLE RWEO
+B905;B905;1105 116F 11A8;B905;1105 116F 11A8; # (뤅; 뤅; 뤅; 뤅; 뤅; ) HANGUL SYLLABLE RWEOG
+B906;B906;1105 116F 11A9;B906;1105 116F 11A9; # (뤆; 뤆; 뤆; 뤆; 뤆; ) HANGUL SYLLABLE RWEOGG
+B907;B907;1105 116F 11AA;B907;1105 116F 11AA; # (뤇; 뤇; 뤇; 뤇; 뤇; ) HANGUL SYLLABLE RWEOGS
+B908;B908;1105 116F 11AB;B908;1105 116F 11AB; # (뤈; 뤈; 뤈; 뤈; 뤈; ) HANGUL SYLLABLE RWEON
+B909;B909;1105 116F 11AC;B909;1105 116F 11AC; # (뤉; 뤉; 뤉; 뤉; 뤉; ) HANGUL SYLLABLE RWEONJ
+B90A;B90A;1105 116F 11AD;B90A;1105 116F 11AD; # (뤊; 뤊; 뤊; 뤊; 뤊; ) HANGUL SYLLABLE RWEONH
+B90B;B90B;1105 116F 11AE;B90B;1105 116F 11AE; # (뤋; 뤋; 뤋; 뤋; 뤋; ) HANGUL SYLLABLE RWEOD
+B90C;B90C;1105 116F 11AF;B90C;1105 116F 11AF; # (뤌; 뤌; 뤌; 뤌; 뤌; ) HANGUL SYLLABLE RWEOL
+B90D;B90D;1105 116F 11B0;B90D;1105 116F 11B0; # (뤍; 뤍; 뤍; 뤍; 뤍; ) HANGUL SYLLABLE RWEOLG
+B90E;B90E;1105 116F 11B1;B90E;1105 116F 11B1; # (뤎; 뤎; 뤎; 뤎; 뤎; ) HANGUL SYLLABLE RWEOLM
+B90F;B90F;1105 116F 11B2;B90F;1105 116F 11B2; # (뤏; 뤏; 뤏; 뤏; 뤏; ) HANGUL SYLLABLE RWEOLB
+B910;B910;1105 116F 11B3;B910;1105 116F 11B3; # (뤐; 뤐; 뤐; 뤐; 뤐; ) HANGUL SYLLABLE RWEOLS
+B911;B911;1105 116F 11B4;B911;1105 116F 11B4; # (뤑; 뤑; 뤑; 뤑; 뤑; ) HANGUL SYLLABLE RWEOLT
+B912;B912;1105 116F 11B5;B912;1105 116F 11B5; # (뤒; 뤒; 뤒; 뤒; 뤒; ) HANGUL SYLLABLE RWEOLP
+B913;B913;1105 116F 11B6;B913;1105 116F 11B6; # (뤓; 뤓; 뤓; 뤓; 뤓; ) HANGUL SYLLABLE RWEOLH
+B914;B914;1105 116F 11B7;B914;1105 116F 11B7; # (뤔; 뤔; 뤔; 뤔; 뤔; ) HANGUL SYLLABLE RWEOM
+B915;B915;1105 116F 11B8;B915;1105 116F 11B8; # (뤕; 뤕; 뤕; 뤕; 뤕; ) HANGUL SYLLABLE RWEOB
+B916;B916;1105 116F 11B9;B916;1105 116F 11B9; # (뤖; 뤖; 뤖; 뤖; 뤖; ) HANGUL SYLLABLE RWEOBS
+B917;B917;1105 116F 11BA;B917;1105 116F 11BA; # (뤗; 뤗; 뤗; 뤗; 뤗; ) HANGUL SYLLABLE RWEOS
+B918;B918;1105 116F 11BB;B918;1105 116F 11BB; # (뤘; 뤘; 뤘; 뤘; 뤘; ) HANGUL SYLLABLE RWEOSS
+B919;B919;1105 116F 11BC;B919;1105 116F 11BC; # (뤙; 뤙; 뤙; 뤙; 뤙; ) HANGUL SYLLABLE RWEONG
+B91A;B91A;1105 116F 11BD;B91A;1105 116F 11BD; # (뤚; 뤚; 뤚; 뤚; 뤚; ) HANGUL SYLLABLE RWEOJ
+B91B;B91B;1105 116F 11BE;B91B;1105 116F 11BE; # (뤛; 뤛; 뤛; 뤛; 뤛; ) HANGUL SYLLABLE RWEOC
+B91C;B91C;1105 116F 11BF;B91C;1105 116F 11BF; # (뤜; 뤜; 뤜; 뤜; 뤜; ) HANGUL SYLLABLE RWEOK
+B91D;B91D;1105 116F 11C0;B91D;1105 116F 11C0; # (뤝; 뤝; 뤝; 뤝; 뤝; ) HANGUL SYLLABLE RWEOT
+B91E;B91E;1105 116F 11C1;B91E;1105 116F 11C1; # (뤞; 뤞; 뤞; 뤞; 뤞; ) HANGUL SYLLABLE RWEOP
+B91F;B91F;1105 116F 11C2;B91F;1105 116F 11C2; # (뤟; 뤟; 뤟; 뤟; 뤟; ) HANGUL SYLLABLE RWEOH
+B920;B920;1105 1170;B920;1105 1170; # (뤠; 뤠; 뤠; 뤠; 뤠; ) HANGUL SYLLABLE RWE
+B921;B921;1105 1170 11A8;B921;1105 1170 11A8; # (뤡; 뤡; 뤡; 뤡; 뤡; ) HANGUL SYLLABLE RWEG
+B922;B922;1105 1170 11A9;B922;1105 1170 11A9; # (뤢; 뤢; 뤢; 뤢; 뤢; ) HANGUL SYLLABLE RWEGG
+B923;B923;1105 1170 11AA;B923;1105 1170 11AA; # (뤣; 뤣; 뤣; 뤣; 뤣; ) HANGUL SYLLABLE RWEGS
+B924;B924;1105 1170 11AB;B924;1105 1170 11AB; # (뤤; 뤤; 뤤; 뤤; 뤤; ) HANGUL SYLLABLE RWEN
+B925;B925;1105 1170 11AC;B925;1105 1170 11AC; # (뤥; 뤥; 뤥; 뤥; 뤥; ) HANGUL SYLLABLE RWENJ
+B926;B926;1105 1170 11AD;B926;1105 1170 11AD; # (뤦; 뤦; 뤦; 뤦; 뤦; ) HANGUL SYLLABLE RWENH
+B927;B927;1105 1170 11AE;B927;1105 1170 11AE; # (뤧; 뤧; 뤧; 뤧; 뤧; ) HANGUL SYLLABLE RWED
+B928;B928;1105 1170 11AF;B928;1105 1170 11AF; # (뤨; 뤨; 뤨; 뤨; 뤨; ) HANGUL SYLLABLE RWEL
+B929;B929;1105 1170 11B0;B929;1105 1170 11B0; # (뤩; 뤩; 뤩; 뤩; 뤩; ) HANGUL SYLLABLE RWELG
+B92A;B92A;1105 1170 11B1;B92A;1105 1170 11B1; # (뤪; 뤪; 뤪; 뤪; 뤪; ) HANGUL SYLLABLE RWELM
+B92B;B92B;1105 1170 11B2;B92B;1105 1170 11B2; # (뤫; 뤫; 뤫; 뤫; 뤫; ) HANGUL SYLLABLE RWELB
+B92C;B92C;1105 1170 11B3;B92C;1105 1170 11B3; # (뤬; 뤬; 뤬; 뤬; 뤬; ) HANGUL SYLLABLE RWELS
+B92D;B92D;1105 1170 11B4;B92D;1105 1170 11B4; # (뤭; 뤭; 뤭; 뤭; 뤭; ) HANGUL SYLLABLE RWELT
+B92E;B92E;1105 1170 11B5;B92E;1105 1170 11B5; # (뤮; 뤮; 뤮; 뤮; 뤮; ) HANGUL SYLLABLE RWELP
+B92F;B92F;1105 1170 11B6;B92F;1105 1170 11B6; # (뤯; 뤯; 뤯; 뤯; 뤯; ) HANGUL SYLLABLE RWELH
+B930;B930;1105 1170 11B7;B930;1105 1170 11B7; # (뤰; 뤰; 뤰; 뤰; 뤰; ) HANGUL SYLLABLE RWEM
+B931;B931;1105 1170 11B8;B931;1105 1170 11B8; # (뤱; 뤱; 뤱; 뤱; 뤱; ) HANGUL SYLLABLE RWEB
+B932;B932;1105 1170 11B9;B932;1105 1170 11B9; # (뤲; 뤲; 뤲; 뤲; 뤲; ) HANGUL SYLLABLE RWEBS
+B933;B933;1105 1170 11BA;B933;1105 1170 11BA; # (뤳; 뤳; 뤳; 뤳; 뤳; ) HANGUL SYLLABLE RWES
+B934;B934;1105 1170 11BB;B934;1105 1170 11BB; # (뤴; 뤴; 뤴; 뤴; 뤴; ) HANGUL SYLLABLE RWESS
+B935;B935;1105 1170 11BC;B935;1105 1170 11BC; # (뤵; 뤵; 뤵; 뤵; 뤵; ) HANGUL SYLLABLE RWENG
+B936;B936;1105 1170 11BD;B936;1105 1170 11BD; # (뤶; 뤶; 뤶; 뤶; 뤶; ) HANGUL SYLLABLE RWEJ
+B937;B937;1105 1170 11BE;B937;1105 1170 11BE; # (뤷; 뤷; 뤷; 뤷; 뤷; ) HANGUL SYLLABLE RWEC
+B938;B938;1105 1170 11BF;B938;1105 1170 11BF; # (뤸; 뤸; 뤸; 뤸; 뤸; ) HANGUL SYLLABLE RWEK
+B939;B939;1105 1170 11C0;B939;1105 1170 11C0; # (뤹; 뤹; 뤹; 뤹; 뤹; ) HANGUL SYLLABLE RWET
+B93A;B93A;1105 1170 11C1;B93A;1105 1170 11C1; # (뤺; 뤺; 뤺; 뤺; 뤺; ) HANGUL SYLLABLE RWEP
+B93B;B93B;1105 1170 11C2;B93B;1105 1170 11C2; # (뤻; 뤻; 뤻; 뤻; 뤻; ) HANGUL SYLLABLE RWEH
+B93C;B93C;1105 1171;B93C;1105 1171; # (뤼; 뤼; 뤼; 뤼; 뤼; ) HANGUL SYLLABLE RWI
+B93D;B93D;1105 1171 11A8;B93D;1105 1171 11A8; # (뤽; 뤽; 뤽; 뤽; 뤽; ) HANGUL SYLLABLE RWIG
+B93E;B93E;1105 1171 11A9;B93E;1105 1171 11A9; # (뤾; 뤾; 뤾; 뤾; 뤾; ) HANGUL SYLLABLE RWIGG
+B93F;B93F;1105 1171 11AA;B93F;1105 1171 11AA; # (뤿; 뤿; 뤿; 뤿; 뤿; ) HANGUL SYLLABLE RWIGS
+B940;B940;1105 1171 11AB;B940;1105 1171 11AB; # (륀; 륀; 륀; 륀; 륀; ) HANGUL SYLLABLE RWIN
+B941;B941;1105 1171 11AC;B941;1105 1171 11AC; # (륁; 륁; 륁; 륁; 륁; ) HANGUL SYLLABLE RWINJ
+B942;B942;1105 1171 11AD;B942;1105 1171 11AD; # (륂; 륂; 륂; 륂; 륂; ) HANGUL SYLLABLE RWINH
+B943;B943;1105 1171 11AE;B943;1105 1171 11AE; # (륃; 륃; 륃; 륃; 륃; ) HANGUL SYLLABLE RWID
+B944;B944;1105 1171 11AF;B944;1105 1171 11AF; # (륄; 륄; 륄; 륄; 륄; ) HANGUL SYLLABLE RWIL
+B945;B945;1105 1171 11B0;B945;1105 1171 11B0; # (륅; 륅; 륅; 륅; 륅; ) HANGUL SYLLABLE RWILG
+B946;B946;1105 1171 11B1;B946;1105 1171 11B1; # (륆; 륆; 륆; 륆; 륆; ) HANGUL SYLLABLE RWILM
+B947;B947;1105 1171 11B2;B947;1105 1171 11B2; # (륇; 륇; 륇; 륇; 륇; ) HANGUL SYLLABLE RWILB
+B948;B948;1105 1171 11B3;B948;1105 1171 11B3; # (륈; 륈; 륈; 륈; 륈; ) HANGUL SYLLABLE RWILS
+B949;B949;1105 1171 11B4;B949;1105 1171 11B4; # (륉; 륉; 륉; 륉; 륉; ) HANGUL SYLLABLE RWILT
+B94A;B94A;1105 1171 11B5;B94A;1105 1171 11B5; # (륊; 륊; 륊; 륊; 륊; ) HANGUL SYLLABLE RWILP
+B94B;B94B;1105 1171 11B6;B94B;1105 1171 11B6; # (륋; 륋; 륋; 륋; 륋; ) HANGUL SYLLABLE RWILH
+B94C;B94C;1105 1171 11B7;B94C;1105 1171 11B7; # (륌; 륌; 륌; 륌; 륌; ) HANGUL SYLLABLE RWIM
+B94D;B94D;1105 1171 11B8;B94D;1105 1171 11B8; # (륍; 륍; 륍; 륍; 륍; ) HANGUL SYLLABLE RWIB
+B94E;B94E;1105 1171 11B9;B94E;1105 1171 11B9; # (륎; 륎; 륎; 륎; 륎; ) HANGUL SYLLABLE RWIBS
+B94F;B94F;1105 1171 11BA;B94F;1105 1171 11BA; # (륏; 륏; 륏; 륏; 륏; ) HANGUL SYLLABLE RWIS
+B950;B950;1105 1171 11BB;B950;1105 1171 11BB; # (륐; 륐; 륐; 륐; 륐; ) HANGUL SYLLABLE RWISS
+B951;B951;1105 1171 11BC;B951;1105 1171 11BC; # (륑; 륑; 륑; 륑; 륑; ) HANGUL SYLLABLE RWING
+B952;B952;1105 1171 11BD;B952;1105 1171 11BD; # (륒; 륒; 륒; 륒; 륒; ) HANGUL SYLLABLE RWIJ
+B953;B953;1105 1171 11BE;B953;1105 1171 11BE; # (륓; 륓; 륓; 륓; 륓; ) HANGUL SYLLABLE RWIC
+B954;B954;1105 1171 11BF;B954;1105 1171 11BF; # (륔; 륔; 륔; 륔; 륔; ) HANGUL SYLLABLE RWIK
+B955;B955;1105 1171 11C0;B955;1105 1171 11C0; # (륕; 륕; 륕; 륕; 륕; ) HANGUL SYLLABLE RWIT
+B956;B956;1105 1171 11C1;B956;1105 1171 11C1; # (륖; 륖; 륖; 륖; 륖; ) HANGUL SYLLABLE RWIP
+B957;B957;1105 1171 11C2;B957;1105 1171 11C2; # (륗; 륗; 륗; 륗; 륗; ) HANGUL SYLLABLE RWIH
+B958;B958;1105 1172;B958;1105 1172; # (류; 류; 류; 류; 류; ) HANGUL SYLLABLE RYU
+B959;B959;1105 1172 11A8;B959;1105 1172 11A8; # (륙; 륙; 륙; 륙; 륙; ) HANGUL SYLLABLE RYUG
+B95A;B95A;1105 1172 11A9;B95A;1105 1172 11A9; # (륚; 륚; 륚; 륚; 륚; ) HANGUL SYLLABLE RYUGG
+B95B;B95B;1105 1172 11AA;B95B;1105 1172 11AA; # (륛; 륛; 륛; 륛; 륛; ) HANGUL SYLLABLE RYUGS
+B95C;B95C;1105 1172 11AB;B95C;1105 1172 11AB; # (륜; 륜; 륜; 륜; 륜; ) HANGUL SYLLABLE RYUN
+B95D;B95D;1105 1172 11AC;B95D;1105 1172 11AC; # (륝; 륝; 륝; 륝; 륝; ) HANGUL SYLLABLE RYUNJ
+B95E;B95E;1105 1172 11AD;B95E;1105 1172 11AD; # (륞; 륞; 륞; 륞; 륞; ) HANGUL SYLLABLE RYUNH
+B95F;B95F;1105 1172 11AE;B95F;1105 1172 11AE; # (륟; 륟; 륟; 륟; 륟; ) HANGUL SYLLABLE RYUD
+B960;B960;1105 1172 11AF;B960;1105 1172 11AF; # (률; 률; 률; 률; 률; ) HANGUL SYLLABLE RYUL
+B961;B961;1105 1172 11B0;B961;1105 1172 11B0; # (륡; 륡; 륡; 륡; 륡; ) HANGUL SYLLABLE RYULG
+B962;B962;1105 1172 11B1;B962;1105 1172 11B1; # (륢; 륢; 륢; 륢; 륢; ) HANGUL SYLLABLE RYULM
+B963;B963;1105 1172 11B2;B963;1105 1172 11B2; # (륣; 륣; 륣; 륣; 륣; ) HANGUL SYLLABLE RYULB
+B964;B964;1105 1172 11B3;B964;1105 1172 11B3; # (륤; 륤; 륤; 륤; 륤; ) HANGUL SYLLABLE RYULS
+B965;B965;1105 1172 11B4;B965;1105 1172 11B4; # (륥; 륥; 륥; 륥; 륥; ) HANGUL SYLLABLE RYULT
+B966;B966;1105 1172 11B5;B966;1105 1172 11B5; # (륦; 륦; 륦; 륦; 륦; ) HANGUL SYLLABLE RYULP
+B967;B967;1105 1172 11B6;B967;1105 1172 11B6; # (륧; 륧; 륧; 륧; 륧; ) HANGUL SYLLABLE RYULH
+B968;B968;1105 1172 11B7;B968;1105 1172 11B7; # (륨; 륨; 륨; 륨; 륨; ) HANGUL SYLLABLE RYUM
+B969;B969;1105 1172 11B8;B969;1105 1172 11B8; # (륩; 륩; 륩; 륩; 륩; ) HANGUL SYLLABLE RYUB
+B96A;B96A;1105 1172 11B9;B96A;1105 1172 11B9; # (륪; 륪; 륪; 륪; 륪; ) HANGUL SYLLABLE RYUBS
+B96B;B96B;1105 1172 11BA;B96B;1105 1172 11BA; # (륫; 륫; 륫; 륫; 륫; ) HANGUL SYLLABLE RYUS
+B96C;B96C;1105 1172 11BB;B96C;1105 1172 11BB; # (륬; 륬; 륬; 륬; 륬; ) HANGUL SYLLABLE RYUSS
+B96D;B96D;1105 1172 11BC;B96D;1105 1172 11BC; # (륭; 륭; 륭; 륭; 륭; ) HANGUL SYLLABLE RYUNG
+B96E;B96E;1105 1172 11BD;B96E;1105 1172 11BD; # (륮; 륮; 륮; 륮; 륮; ) HANGUL SYLLABLE RYUJ
+B96F;B96F;1105 1172 11BE;B96F;1105 1172 11BE; # (륯; 륯; 륯; 륯; 륯; ) HANGUL SYLLABLE RYUC
+B970;B970;1105 1172 11BF;B970;1105 1172 11BF; # (륰; 륰; 륰; 륰; 륰; ) HANGUL SYLLABLE RYUK
+B971;B971;1105 1172 11C0;B971;1105 1172 11C0; # (륱; 륱; 륱; 륱; 륱; ) HANGUL SYLLABLE RYUT
+B972;B972;1105 1172 11C1;B972;1105 1172 11C1; # (륲; 륲; 륲; 륲; 륲; ) HANGUL SYLLABLE RYUP
+B973;B973;1105 1172 11C2;B973;1105 1172 11C2; # (륳; 륳; 륳; 륳; 륳; ) HANGUL SYLLABLE RYUH
+B974;B974;1105 1173;B974;1105 1173; # (르; 르; 르; 르; 르; ) HANGUL SYLLABLE REU
+B975;B975;1105 1173 11A8;B975;1105 1173 11A8; # (륵; 륵; 륵; 륵; 륵; ) HANGUL SYLLABLE REUG
+B976;B976;1105 1173 11A9;B976;1105 1173 11A9; # (륶; 륶; 륶; 륶; 륶; ) HANGUL SYLLABLE REUGG
+B977;B977;1105 1173 11AA;B977;1105 1173 11AA; # (륷; 륷; 륷; 륷; 륷; ) HANGUL SYLLABLE REUGS
+B978;B978;1105 1173 11AB;B978;1105 1173 11AB; # (른; 른; 른; 른; 른; ) HANGUL SYLLABLE REUN
+B979;B979;1105 1173 11AC;B979;1105 1173 11AC; # (륹; 륹; 륹; 륹; 륹; ) HANGUL SYLLABLE REUNJ
+B97A;B97A;1105 1173 11AD;B97A;1105 1173 11AD; # (륺; 륺; 륺; 륺; 륺; ) HANGUL SYLLABLE REUNH
+B97B;B97B;1105 1173 11AE;B97B;1105 1173 11AE; # (륻; 륻; 륻; 륻; 륻; ) HANGUL SYLLABLE REUD
+B97C;B97C;1105 1173 11AF;B97C;1105 1173 11AF; # (를; 를; 를; 를; 를; ) HANGUL SYLLABLE REUL
+B97D;B97D;1105 1173 11B0;B97D;1105 1173 11B0; # (륽; 륽; 륽; 륽; 륽; ) HANGUL SYLLABLE REULG
+B97E;B97E;1105 1173 11B1;B97E;1105 1173 11B1; # (륾; 륾; 륾; 륾; 륾; ) HANGUL SYLLABLE REULM
+B97F;B97F;1105 1173 11B2;B97F;1105 1173 11B2; # (륿; 륿; 륿; 륿; 륿; ) HANGUL SYLLABLE REULB
+B980;B980;1105 1173 11B3;B980;1105 1173 11B3; # (릀; 릀; 릀; 릀; 릀; ) HANGUL SYLLABLE REULS
+B981;B981;1105 1173 11B4;B981;1105 1173 11B4; # (릁; 릁; 릁; 릁; 릁; ) HANGUL SYLLABLE REULT
+B982;B982;1105 1173 11B5;B982;1105 1173 11B5; # (릂; 릂; 릂; 릂; 릂; ) HANGUL SYLLABLE REULP
+B983;B983;1105 1173 11B6;B983;1105 1173 11B6; # (릃; 릃; 릃; 릃; 릃; ) HANGUL SYLLABLE REULH
+B984;B984;1105 1173 11B7;B984;1105 1173 11B7; # (름; 름; 름; 름; 름; ) HANGUL SYLLABLE REUM
+B985;B985;1105 1173 11B8;B985;1105 1173 11B8; # (릅; 릅; 릅; 릅; 릅; ) HANGUL SYLLABLE REUB
+B986;B986;1105 1173 11B9;B986;1105 1173 11B9; # (릆; 릆; 릆; 릆; 릆; ) HANGUL SYLLABLE REUBS
+B987;B987;1105 1173 11BA;B987;1105 1173 11BA; # (릇; 릇; 릇; 릇; 릇; ) HANGUL SYLLABLE REUS
+B988;B988;1105 1173 11BB;B988;1105 1173 11BB; # (릈; 릈; 릈; 릈; 릈; ) HANGUL SYLLABLE REUSS
+B989;B989;1105 1173 11BC;B989;1105 1173 11BC; # (릉; 릉; 릉; 릉; 릉; ) HANGUL SYLLABLE REUNG
+B98A;B98A;1105 1173 11BD;B98A;1105 1173 11BD; # (릊; 릊; 릊; 릊; 릊; ) HANGUL SYLLABLE REUJ
+B98B;B98B;1105 1173 11BE;B98B;1105 1173 11BE; # (릋; 릋; 릋; 릋; 릋; ) HANGUL SYLLABLE REUC
+B98C;B98C;1105 1173 11BF;B98C;1105 1173 11BF; # (릌; 릌; 릌; 릌; 릌; ) HANGUL SYLLABLE REUK
+B98D;B98D;1105 1173 11C0;B98D;1105 1173 11C0; # (릍; 릍; 릍; 릍; 릍; ) HANGUL SYLLABLE REUT
+B98E;B98E;1105 1173 11C1;B98E;1105 1173 11C1; # (릎; 릎; 릎; 릎; 릎; ) HANGUL SYLLABLE REUP
+B98F;B98F;1105 1173 11C2;B98F;1105 1173 11C2; # (릏; 릏; 릏; 릏; 릏; ) HANGUL SYLLABLE REUH
+B990;B990;1105 1174;B990;1105 1174; # (릐; 릐; 릐; 릐; 릐; ) HANGUL SYLLABLE RYI
+B991;B991;1105 1174 11A8;B991;1105 1174 11A8; # (릑; 릑; 릑; 릑; 릑; ) HANGUL SYLLABLE RYIG
+B992;B992;1105 1174 11A9;B992;1105 1174 11A9; # (릒; 릒; 릒; 릒; 릒; ) HANGUL SYLLABLE RYIGG
+B993;B993;1105 1174 11AA;B993;1105 1174 11AA; # (릓; 릓; 릓; 릓; 릓; ) HANGUL SYLLABLE RYIGS
+B994;B994;1105 1174 11AB;B994;1105 1174 11AB; # (릔; 릔; 릔; 릔; 릔; ) HANGUL SYLLABLE RYIN
+B995;B995;1105 1174 11AC;B995;1105 1174 11AC; # (릕; 릕; 릕; 릕; 릕; ) HANGUL SYLLABLE RYINJ
+B996;B996;1105 1174 11AD;B996;1105 1174 11AD; # (릖; 릖; 릖; 릖; 릖; ) HANGUL SYLLABLE RYINH
+B997;B997;1105 1174 11AE;B997;1105 1174 11AE; # (릗; 릗; 릗; 릗; 릗; ) HANGUL SYLLABLE RYID
+B998;B998;1105 1174 11AF;B998;1105 1174 11AF; # (릘; 릘; 릘; 릘; 릘; ) HANGUL SYLLABLE RYIL
+B999;B999;1105 1174 11B0;B999;1105 1174 11B0; # (릙; 릙; 릙; 릙; 릙; ) HANGUL SYLLABLE RYILG
+B99A;B99A;1105 1174 11B1;B99A;1105 1174 11B1; # (릚; 릚; 릚; 릚; 릚; ) HANGUL SYLLABLE RYILM
+B99B;B99B;1105 1174 11B2;B99B;1105 1174 11B2; # (릛; 릛; 릛; 릛; 릛; ) HANGUL SYLLABLE RYILB
+B99C;B99C;1105 1174 11B3;B99C;1105 1174 11B3; # (릜; 릜; 릜; 릜; 릜; ) HANGUL SYLLABLE RYILS
+B99D;B99D;1105 1174 11B4;B99D;1105 1174 11B4; # (릝; 릝; 릝; 릝; 릝; ) HANGUL SYLLABLE RYILT
+B99E;B99E;1105 1174 11B5;B99E;1105 1174 11B5; # (릞; 릞; 릞; 릞; 릞; ) HANGUL SYLLABLE RYILP
+B99F;B99F;1105 1174 11B6;B99F;1105 1174 11B6; # (릟; 릟; 릟; 릟; 릟; ) HANGUL SYLLABLE RYILH
+B9A0;B9A0;1105 1174 11B7;B9A0;1105 1174 11B7; # (릠; 릠; 릠; 릠; 릠; ) HANGUL SYLLABLE RYIM
+B9A1;B9A1;1105 1174 11B8;B9A1;1105 1174 11B8; # (릡; 릡; 릡; 릡; 릡; ) HANGUL SYLLABLE RYIB
+B9A2;B9A2;1105 1174 11B9;B9A2;1105 1174 11B9; # (릢; 릢; 릢; 릢; 릢; ) HANGUL SYLLABLE RYIBS
+B9A3;B9A3;1105 1174 11BA;B9A3;1105 1174 11BA; # (릣; 릣; 릣; 릣; 릣; ) HANGUL SYLLABLE RYIS
+B9A4;B9A4;1105 1174 11BB;B9A4;1105 1174 11BB; # (릤; 릤; 릤; 릤; 릤; ) HANGUL SYLLABLE RYISS
+B9A5;B9A5;1105 1174 11BC;B9A5;1105 1174 11BC; # (릥; 릥; 릥; 릥; 릥; ) HANGUL SYLLABLE RYING
+B9A6;B9A6;1105 1174 11BD;B9A6;1105 1174 11BD; # (릦; 릦; 릦; 릦; 릦; ) HANGUL SYLLABLE RYIJ
+B9A7;B9A7;1105 1174 11BE;B9A7;1105 1174 11BE; # (릧; 릧; 릧; 릧; 릧; ) HANGUL SYLLABLE RYIC
+B9A8;B9A8;1105 1174 11BF;B9A8;1105 1174 11BF; # (릨; 릨; 릨; 릨; 릨; ) HANGUL SYLLABLE RYIK
+B9A9;B9A9;1105 1174 11C0;B9A9;1105 1174 11C0; # (릩; 릩; 릩; 릩; 릩; ) HANGUL SYLLABLE RYIT
+B9AA;B9AA;1105 1174 11C1;B9AA;1105 1174 11C1; # (릪; 릪; 릪; 릪; 릪; ) HANGUL SYLLABLE RYIP
+B9AB;B9AB;1105 1174 11C2;B9AB;1105 1174 11C2; # (릫; 릫; 릫; 릫; 릫; ) HANGUL SYLLABLE RYIH
+B9AC;B9AC;1105 1175;B9AC;1105 1175; # (리; 리; 리; 리; 리; ) HANGUL SYLLABLE RI
+B9AD;B9AD;1105 1175 11A8;B9AD;1105 1175 11A8; # (릭; 릭; 릭; 릭; 릭; ) HANGUL SYLLABLE RIG
+B9AE;B9AE;1105 1175 11A9;B9AE;1105 1175 11A9; # (릮; 릮; 릮; 릮; 릮; ) HANGUL SYLLABLE RIGG
+B9AF;B9AF;1105 1175 11AA;B9AF;1105 1175 11AA; # (릯; 릯; 릯; 릯; 릯; ) HANGUL SYLLABLE RIGS
+B9B0;B9B0;1105 1175 11AB;B9B0;1105 1175 11AB; # (린; 린; 린; 린; 린; ) HANGUL SYLLABLE RIN
+B9B1;B9B1;1105 1175 11AC;B9B1;1105 1175 11AC; # (릱; 릱; 릱; 릱; 릱; ) HANGUL SYLLABLE RINJ
+B9B2;B9B2;1105 1175 11AD;B9B2;1105 1175 11AD; # (릲; 릲; 릲; 릲; 릲; ) HANGUL SYLLABLE RINH
+B9B3;B9B3;1105 1175 11AE;B9B3;1105 1175 11AE; # (릳; 릳; 릳; 릳; 릳; ) HANGUL SYLLABLE RID
+B9B4;B9B4;1105 1175 11AF;B9B4;1105 1175 11AF; # (릴; 릴; 릴; 릴; 릴; ) HANGUL SYLLABLE RIL
+B9B5;B9B5;1105 1175 11B0;B9B5;1105 1175 11B0; # (릵; 릵; 릵; 릵; 릵; ) HANGUL SYLLABLE RILG
+B9B6;B9B6;1105 1175 11B1;B9B6;1105 1175 11B1; # (릶; 릶; 릶; 릶; 릶; ) HANGUL SYLLABLE RILM
+B9B7;B9B7;1105 1175 11B2;B9B7;1105 1175 11B2; # (릷; 릷; 릷; 릷; 릷; ) HANGUL SYLLABLE RILB
+B9B8;B9B8;1105 1175 11B3;B9B8;1105 1175 11B3; # (릸; 릸; 릸; 릸; 릸; ) HANGUL SYLLABLE RILS
+B9B9;B9B9;1105 1175 11B4;B9B9;1105 1175 11B4; # (릹; 릹; 릹; 릹; 릹; ) HANGUL SYLLABLE RILT
+B9BA;B9BA;1105 1175 11B5;B9BA;1105 1175 11B5; # (릺; 릺; 릺; 릺; 릺; ) HANGUL SYLLABLE RILP
+B9BB;B9BB;1105 1175 11B6;B9BB;1105 1175 11B6; # (릻; 릻; 릻; 릻; 릻; ) HANGUL SYLLABLE RILH
+B9BC;B9BC;1105 1175 11B7;B9BC;1105 1175 11B7; # (림; 림; 림; 림; 림; ) HANGUL SYLLABLE RIM
+B9BD;B9BD;1105 1175 11B8;B9BD;1105 1175 11B8; # (립; 립; 립; 립; 립; ) HANGUL SYLLABLE RIB
+B9BE;B9BE;1105 1175 11B9;B9BE;1105 1175 11B9; # (릾; 릾; 릾; 릾; 릾; ) HANGUL SYLLABLE RIBS
+B9BF;B9BF;1105 1175 11BA;B9BF;1105 1175 11BA; # (릿; 릿; 릿; 릿; 릿; ) HANGUL SYLLABLE RIS
+B9C0;B9C0;1105 1175 11BB;B9C0;1105 1175 11BB; # (맀; 맀; 맀; 맀; 맀; ) HANGUL SYLLABLE RISS
+B9C1;B9C1;1105 1175 11BC;B9C1;1105 1175 11BC; # (링; 링; 링; 링; 링; ) HANGUL SYLLABLE RING
+B9C2;B9C2;1105 1175 11BD;B9C2;1105 1175 11BD; # (맂; 맂; 맂; 맂; 맂; ) HANGUL SYLLABLE RIJ
+B9C3;B9C3;1105 1175 11BE;B9C3;1105 1175 11BE; # (맃; 맃; 맃; 맃; 맃; ) HANGUL SYLLABLE RIC
+B9C4;B9C4;1105 1175 11BF;B9C4;1105 1175 11BF; # (맄; 맄; 맄; 맄; 맄; ) HANGUL SYLLABLE RIK
+B9C5;B9C5;1105 1175 11C0;B9C5;1105 1175 11C0; # (맅; 맅; 맅; 맅; 맅; ) HANGUL SYLLABLE RIT
+B9C6;B9C6;1105 1175 11C1;B9C6;1105 1175 11C1; # (맆; 맆; 맆; 맆; 맆; ) HANGUL SYLLABLE RIP
+B9C7;B9C7;1105 1175 11C2;B9C7;1105 1175 11C2; # (맇; 맇; 맇; 맇; 맇; ) HANGUL SYLLABLE RIH
+B9C8;B9C8;1106 1161;B9C8;1106 1161; # (마; 마; 마; 마; 마; ) HANGUL SYLLABLE MA
+B9C9;B9C9;1106 1161 11A8;B9C9;1106 1161 11A8; # (막; 막; 막; 막; 막; ) HANGUL SYLLABLE MAG
+B9CA;B9CA;1106 1161 11A9;B9CA;1106 1161 11A9; # (맊; 맊; 맊; 맊; 맊; ) HANGUL SYLLABLE MAGG
+B9CB;B9CB;1106 1161 11AA;B9CB;1106 1161 11AA; # (맋; 맋; 맋; 맋; 맋; ) HANGUL SYLLABLE MAGS
+B9CC;B9CC;1106 1161 11AB;B9CC;1106 1161 11AB; # (만; 만; 만; 만; 만; ) HANGUL SYLLABLE MAN
+B9CD;B9CD;1106 1161 11AC;B9CD;1106 1161 11AC; # (맍; 맍; 맍; 맍; 맍; ) HANGUL SYLLABLE MANJ
+B9CE;B9CE;1106 1161 11AD;B9CE;1106 1161 11AD; # (많; 많; 많; 많; 많; ) HANGUL SYLLABLE MANH
+B9CF;B9CF;1106 1161 11AE;B9CF;1106 1161 11AE; # (맏; 맏; 맏; 맏; 맏; ) HANGUL SYLLABLE MAD
+B9D0;B9D0;1106 1161 11AF;B9D0;1106 1161 11AF; # (말; 말; 말; 말; 말; ) HANGUL SYLLABLE MAL
+B9D1;B9D1;1106 1161 11B0;B9D1;1106 1161 11B0; # (맑; 맑; 맑; 맑; 맑; ) HANGUL SYLLABLE MALG
+B9D2;B9D2;1106 1161 11B1;B9D2;1106 1161 11B1; # (맒; 맒; 맒; 맒; 맒; ) HANGUL SYLLABLE MALM
+B9D3;B9D3;1106 1161 11B2;B9D3;1106 1161 11B2; # (맓; 맓; 맓; 맓; 맓; ) HANGUL SYLLABLE MALB
+B9D4;B9D4;1106 1161 11B3;B9D4;1106 1161 11B3; # (맔; 맔; 맔; 맔; 맔; ) HANGUL SYLLABLE MALS
+B9D5;B9D5;1106 1161 11B4;B9D5;1106 1161 11B4; # (맕; 맕; 맕; 맕; 맕; ) HANGUL SYLLABLE MALT
+B9D6;B9D6;1106 1161 11B5;B9D6;1106 1161 11B5; # (맖; 맖; 맖; 맖; 맖; ) HANGUL SYLLABLE MALP
+B9D7;B9D7;1106 1161 11B6;B9D7;1106 1161 11B6; # (맗; 맗; 맗; 맗; 맗; ) HANGUL SYLLABLE MALH
+B9D8;B9D8;1106 1161 11B7;B9D8;1106 1161 11B7; # (맘; 맘; 맘; 맘; 맘; ) HANGUL SYLLABLE MAM
+B9D9;B9D9;1106 1161 11B8;B9D9;1106 1161 11B8; # (맙; 맙; 맙; 맙; 맙; ) HANGUL SYLLABLE MAB
+B9DA;B9DA;1106 1161 11B9;B9DA;1106 1161 11B9; # (맚; 맚; 맚; 맚; 맚; ) HANGUL SYLLABLE MABS
+B9DB;B9DB;1106 1161 11BA;B9DB;1106 1161 11BA; # (맛; 맛; 맛; 맛; 맛; ) HANGUL SYLLABLE MAS
+B9DC;B9DC;1106 1161 11BB;B9DC;1106 1161 11BB; # (맜; 맜; 맜; 맜; 맜; ) HANGUL SYLLABLE MASS
+B9DD;B9DD;1106 1161 11BC;B9DD;1106 1161 11BC; # (망; 망; 망; 망; 망; ) HANGUL SYLLABLE MANG
+B9DE;B9DE;1106 1161 11BD;B9DE;1106 1161 11BD; # (맞; 맞; 맞; 맞; 맞; ) HANGUL SYLLABLE MAJ
+B9DF;B9DF;1106 1161 11BE;B9DF;1106 1161 11BE; # (맟; 맟; 맟; 맟; 맟; ) HANGUL SYLLABLE MAC
+B9E0;B9E0;1106 1161 11BF;B9E0;1106 1161 11BF; # (맠; 맠; 맠; 맠; 맠; ) HANGUL SYLLABLE MAK
+B9E1;B9E1;1106 1161 11C0;B9E1;1106 1161 11C0; # (맡; 맡; 맡; 맡; 맡; ) HANGUL SYLLABLE MAT
+B9E2;B9E2;1106 1161 11C1;B9E2;1106 1161 11C1; # (맢; 맢; 맢; 맢; 맢; ) HANGUL SYLLABLE MAP
+B9E3;B9E3;1106 1161 11C2;B9E3;1106 1161 11C2; # (맣; 맣; 맣; 맣; 맣; ) HANGUL SYLLABLE MAH
+B9E4;B9E4;1106 1162;B9E4;1106 1162; # (매; 매; 매; 매; 매; ) HANGUL SYLLABLE MAE
+B9E5;B9E5;1106 1162 11A8;B9E5;1106 1162 11A8; # (맥; 맥; 맥; 맥; 맥; ) HANGUL SYLLABLE MAEG
+B9E6;B9E6;1106 1162 11A9;B9E6;1106 1162 11A9; # (맦; 맦; 맦; 맦; 맦; ) HANGUL SYLLABLE MAEGG
+B9E7;B9E7;1106 1162 11AA;B9E7;1106 1162 11AA; # (맧; 맧; 맧; 맧; 맧; ) HANGUL SYLLABLE MAEGS
+B9E8;B9E8;1106 1162 11AB;B9E8;1106 1162 11AB; # (맨; 맨; 맨; 맨; 맨; ) HANGUL SYLLABLE MAEN
+B9E9;B9E9;1106 1162 11AC;B9E9;1106 1162 11AC; # (맩; 맩; 맩; 맩; 맩; ) HANGUL SYLLABLE MAENJ
+B9EA;B9EA;1106 1162 11AD;B9EA;1106 1162 11AD; # (맪; 맪; 맪; 맪; 맪; ) HANGUL SYLLABLE MAENH
+B9EB;B9EB;1106 1162 11AE;B9EB;1106 1162 11AE; # (맫; 맫; 맫; 맫; 맫; ) HANGUL SYLLABLE MAED
+B9EC;B9EC;1106 1162 11AF;B9EC;1106 1162 11AF; # (맬; 맬; 맬; 맬; 맬; ) HANGUL SYLLABLE MAEL
+B9ED;B9ED;1106 1162 11B0;B9ED;1106 1162 11B0; # (맭; 맭; 맭; 맭; 맭; ) HANGUL SYLLABLE MAELG
+B9EE;B9EE;1106 1162 11B1;B9EE;1106 1162 11B1; # (맮; 맮; 맮; 맮; 맮; ) HANGUL SYLLABLE MAELM
+B9EF;B9EF;1106 1162 11B2;B9EF;1106 1162 11B2; # (맯; 맯; 맯; 맯; 맯; ) HANGUL SYLLABLE MAELB
+B9F0;B9F0;1106 1162 11B3;B9F0;1106 1162 11B3; # (맰; 맰; 맰; 맰; 맰; ) HANGUL SYLLABLE MAELS
+B9F1;B9F1;1106 1162 11B4;B9F1;1106 1162 11B4; # (맱; 맱; 맱; 맱; 맱; ) HANGUL SYLLABLE MAELT
+B9F2;B9F2;1106 1162 11B5;B9F2;1106 1162 11B5; # (맲; 맲; 맲; 맲; 맲; ) HANGUL SYLLABLE MAELP
+B9F3;B9F3;1106 1162 11B6;B9F3;1106 1162 11B6; # (맳; 맳; 맳; 맳; 맳; ) HANGUL SYLLABLE MAELH
+B9F4;B9F4;1106 1162 11B7;B9F4;1106 1162 11B7; # (맴; 맴; 맴; 맴; 맴; ) HANGUL SYLLABLE MAEM
+B9F5;B9F5;1106 1162 11B8;B9F5;1106 1162 11B8; # (맵; 맵; 맵; 맵; 맵; ) HANGUL SYLLABLE MAEB
+B9F6;B9F6;1106 1162 11B9;B9F6;1106 1162 11B9; # (맶; 맶; 맶; 맶; 맶; ) HANGUL SYLLABLE MAEBS
+B9F7;B9F7;1106 1162 11BA;B9F7;1106 1162 11BA; # (맷; 맷; 맷; 맷; 맷; ) HANGUL SYLLABLE MAES
+B9F8;B9F8;1106 1162 11BB;B9F8;1106 1162 11BB; # (맸; 맸; 맸; 맸; 맸; ) HANGUL SYLLABLE MAESS
+B9F9;B9F9;1106 1162 11BC;B9F9;1106 1162 11BC; # (맹; 맹; 맹; 맹; 맹; ) HANGUL SYLLABLE MAENG
+B9FA;B9FA;1106 1162 11BD;B9FA;1106 1162 11BD; # (맺; 맺; 맺; 맺; 맺; ) HANGUL SYLLABLE MAEJ
+B9FB;B9FB;1106 1162 11BE;B9FB;1106 1162 11BE; # (맻; 맻; 맻; 맻; 맻; ) HANGUL SYLLABLE MAEC
+B9FC;B9FC;1106 1162 11BF;B9FC;1106 1162 11BF; # (맼; 맼; 맼; 맼; 맼; ) HANGUL SYLLABLE MAEK
+B9FD;B9FD;1106 1162 11C0;B9FD;1106 1162 11C0; # (맽; 맽; 맽; 맽; 맽; ) HANGUL SYLLABLE MAET
+B9FE;B9FE;1106 1162 11C1;B9FE;1106 1162 11C1; # (맾; 맾; 맾; 맾; 맾; ) HANGUL SYLLABLE MAEP
+B9FF;B9FF;1106 1162 11C2;B9FF;1106 1162 11C2; # (맿; 맿; 맿; 맿; 맿; ) HANGUL SYLLABLE MAEH
+BA00;BA00;1106 1163;BA00;1106 1163; # (먀; 먀; 먀; 먀; 먀; ) HANGUL SYLLABLE MYA
+BA01;BA01;1106 1163 11A8;BA01;1106 1163 11A8; # (먁; 먁; 먁; 먁; 먁; ) HANGUL SYLLABLE MYAG
+BA02;BA02;1106 1163 11A9;BA02;1106 1163 11A9; # (먂; 먂; 먂; 먂; 먂; ) HANGUL SYLLABLE MYAGG
+BA03;BA03;1106 1163 11AA;BA03;1106 1163 11AA; # (먃; 먃; 먃; 먃; 먃; ) HANGUL SYLLABLE MYAGS
+BA04;BA04;1106 1163 11AB;BA04;1106 1163 11AB; # (먄; 먄; 먄; 먄; 먄; ) HANGUL SYLLABLE MYAN
+BA05;BA05;1106 1163 11AC;BA05;1106 1163 11AC; # (먅; 먅; 먅; 먅; 먅; ) HANGUL SYLLABLE MYANJ
+BA06;BA06;1106 1163 11AD;BA06;1106 1163 11AD; # (먆; 먆; 먆; 먆; 먆; ) HANGUL SYLLABLE MYANH
+BA07;BA07;1106 1163 11AE;BA07;1106 1163 11AE; # (먇; 먇; 먇; 먇; 먇; ) HANGUL SYLLABLE MYAD
+BA08;BA08;1106 1163 11AF;BA08;1106 1163 11AF; # (먈; 먈; 먈; 먈; 먈; ) HANGUL SYLLABLE MYAL
+BA09;BA09;1106 1163 11B0;BA09;1106 1163 11B0; # (먉; 먉; 먉; 먉; 먉; ) HANGUL SYLLABLE MYALG
+BA0A;BA0A;1106 1163 11B1;BA0A;1106 1163 11B1; # (먊; 먊; 먊; 먊; 먊; ) HANGUL SYLLABLE MYALM
+BA0B;BA0B;1106 1163 11B2;BA0B;1106 1163 11B2; # (먋; 먋; 먋; 먋; 먋; ) HANGUL SYLLABLE MYALB
+BA0C;BA0C;1106 1163 11B3;BA0C;1106 1163 11B3; # (먌; 먌; 먌; 먌; 먌; ) HANGUL SYLLABLE MYALS
+BA0D;BA0D;1106 1163 11B4;BA0D;1106 1163 11B4; # (먍; 먍; 먍; 먍; 먍; ) HANGUL SYLLABLE MYALT
+BA0E;BA0E;1106 1163 11B5;BA0E;1106 1163 11B5; # (먎; 먎; 먎; 먎; 먎; ) HANGUL SYLLABLE MYALP
+BA0F;BA0F;1106 1163 11B6;BA0F;1106 1163 11B6; # (먏; 먏; 먏; 먏; 먏; ) HANGUL SYLLABLE MYALH
+BA10;BA10;1106 1163 11B7;BA10;1106 1163 11B7; # (먐; 먐; 먐; 먐; 먐; ) HANGUL SYLLABLE MYAM
+BA11;BA11;1106 1163 11B8;BA11;1106 1163 11B8; # (먑; 먑; 먑; 먑; 먑; ) HANGUL SYLLABLE MYAB
+BA12;BA12;1106 1163 11B9;BA12;1106 1163 11B9; # (먒; 먒; 먒; 먒; 먒; ) HANGUL SYLLABLE MYABS
+BA13;BA13;1106 1163 11BA;BA13;1106 1163 11BA; # (먓; 먓; 먓; 먓; 먓; ) HANGUL SYLLABLE MYAS
+BA14;BA14;1106 1163 11BB;BA14;1106 1163 11BB; # (먔; 먔; 먔; 먔; 먔; ) HANGUL SYLLABLE MYASS
+BA15;BA15;1106 1163 11BC;BA15;1106 1163 11BC; # (먕; 먕; 먕; 먕; 먕; ) HANGUL SYLLABLE MYANG
+BA16;BA16;1106 1163 11BD;BA16;1106 1163 11BD; # (먖; 먖; 먖; 먖; 먖; ) HANGUL SYLLABLE MYAJ
+BA17;BA17;1106 1163 11BE;BA17;1106 1163 11BE; # (먗; 먗; 먗; 먗; 먗; ) HANGUL SYLLABLE MYAC
+BA18;BA18;1106 1163 11BF;BA18;1106 1163 11BF; # (먘; 먘; 먘; 먘; 먘; ) HANGUL SYLLABLE MYAK
+BA19;BA19;1106 1163 11C0;BA19;1106 1163 11C0; # (먙; 먙; 먙; 먙; 먙; ) HANGUL SYLLABLE MYAT
+BA1A;BA1A;1106 1163 11C1;BA1A;1106 1163 11C1; # (먚; 먚; 먚; 먚; 먚; ) HANGUL SYLLABLE MYAP
+BA1B;BA1B;1106 1163 11C2;BA1B;1106 1163 11C2; # (먛; 먛; 먛; 먛; 먛; ) HANGUL SYLLABLE MYAH
+BA1C;BA1C;1106 1164;BA1C;1106 1164; # (먜; 먜; 먜; 먜; 먜; ) HANGUL SYLLABLE MYAE
+BA1D;BA1D;1106 1164 11A8;BA1D;1106 1164 11A8; # (먝; 먝; 먝; 먝; 먝; ) HANGUL SYLLABLE MYAEG
+BA1E;BA1E;1106 1164 11A9;BA1E;1106 1164 11A9; # (먞; 먞; 먞; 먞; 먞; ) HANGUL SYLLABLE MYAEGG
+BA1F;BA1F;1106 1164 11AA;BA1F;1106 1164 11AA; # (먟; 먟; 먟; 먟; 먟; ) HANGUL SYLLABLE MYAEGS
+BA20;BA20;1106 1164 11AB;BA20;1106 1164 11AB; # (먠; 먠; 먠; 먠; 먠; ) HANGUL SYLLABLE MYAEN
+BA21;BA21;1106 1164 11AC;BA21;1106 1164 11AC; # (먡; 먡; 먡; 먡; 먡; ) HANGUL SYLLABLE MYAENJ
+BA22;BA22;1106 1164 11AD;BA22;1106 1164 11AD; # (먢; 먢; 먢; 먢; 먢; ) HANGUL SYLLABLE MYAENH
+BA23;BA23;1106 1164 11AE;BA23;1106 1164 11AE; # (먣; 먣; 먣; 먣; 먣; ) HANGUL SYLLABLE MYAED
+BA24;BA24;1106 1164 11AF;BA24;1106 1164 11AF; # (먤; 먤; 먤; 먤; 먤; ) HANGUL SYLLABLE MYAEL
+BA25;BA25;1106 1164 11B0;BA25;1106 1164 11B0; # (먥; 먥; 먥; 먥; 먥; ) HANGUL SYLLABLE MYAELG
+BA26;BA26;1106 1164 11B1;BA26;1106 1164 11B1; # (먦; 먦; 먦; 먦; 먦; ) HANGUL SYLLABLE MYAELM
+BA27;BA27;1106 1164 11B2;BA27;1106 1164 11B2; # (먧; 먧; 먧; 먧; 먧; ) HANGUL SYLLABLE MYAELB
+BA28;BA28;1106 1164 11B3;BA28;1106 1164 11B3; # (먨; 먨; 먨; 먨; 먨; ) HANGUL SYLLABLE MYAELS
+BA29;BA29;1106 1164 11B4;BA29;1106 1164 11B4; # (먩; 먩; 먩; 먩; 먩; ) HANGUL SYLLABLE MYAELT
+BA2A;BA2A;1106 1164 11B5;BA2A;1106 1164 11B5; # (먪; 먪; 먪; 먪; 먪; ) HANGUL SYLLABLE MYAELP
+BA2B;BA2B;1106 1164 11B6;BA2B;1106 1164 11B6; # (먫; 먫; 먫; 먫; 먫; ) HANGUL SYLLABLE MYAELH
+BA2C;BA2C;1106 1164 11B7;BA2C;1106 1164 11B7; # (먬; 먬; 먬; 먬; 먬; ) HANGUL SYLLABLE MYAEM
+BA2D;BA2D;1106 1164 11B8;BA2D;1106 1164 11B8; # (먭; 먭; 먭; 먭; 먭; ) HANGUL SYLLABLE MYAEB
+BA2E;BA2E;1106 1164 11B9;BA2E;1106 1164 11B9; # (먮; 먮; 먮; 먮; 먮; ) HANGUL SYLLABLE MYAEBS
+BA2F;BA2F;1106 1164 11BA;BA2F;1106 1164 11BA; # (먯; 먯; 먯; 먯; 먯; ) HANGUL SYLLABLE MYAES
+BA30;BA30;1106 1164 11BB;BA30;1106 1164 11BB; # (먰; 먰; 먰; 먰; 먰; ) HANGUL SYLLABLE MYAESS
+BA31;BA31;1106 1164 11BC;BA31;1106 1164 11BC; # (먱; 먱; 먱; 먱; 먱; ) HANGUL SYLLABLE MYAENG
+BA32;BA32;1106 1164 11BD;BA32;1106 1164 11BD; # (먲; 먲; 먲; 먲; 먲; ) HANGUL SYLLABLE MYAEJ
+BA33;BA33;1106 1164 11BE;BA33;1106 1164 11BE; # (먳; 먳; 먳; 먳; 먳; ) HANGUL SYLLABLE MYAEC
+BA34;BA34;1106 1164 11BF;BA34;1106 1164 11BF; # (먴; 먴; 먴; 먴; 먴; ) HANGUL SYLLABLE MYAEK
+BA35;BA35;1106 1164 11C0;BA35;1106 1164 11C0; # (먵; 먵; 먵; 먵; 먵; ) HANGUL SYLLABLE MYAET
+BA36;BA36;1106 1164 11C1;BA36;1106 1164 11C1; # (먶; 먶; 먶; 먶; 먶; ) HANGUL SYLLABLE MYAEP
+BA37;BA37;1106 1164 11C2;BA37;1106 1164 11C2; # (먷; 먷; 먷; 먷; 먷; ) HANGUL SYLLABLE MYAEH
+BA38;BA38;1106 1165;BA38;1106 1165; # (머; 머; 머; 머; 머; ) HANGUL SYLLABLE MEO
+BA39;BA39;1106 1165 11A8;BA39;1106 1165 11A8; # (먹; 먹; 먹; 먹; 먹; ) HANGUL SYLLABLE MEOG
+BA3A;BA3A;1106 1165 11A9;BA3A;1106 1165 11A9; # (먺; 먺; 먺; 먺; 먺; ) HANGUL SYLLABLE MEOGG
+BA3B;BA3B;1106 1165 11AA;BA3B;1106 1165 11AA; # (먻; 먻; 먻; 먻; 먻; ) HANGUL SYLLABLE MEOGS
+BA3C;BA3C;1106 1165 11AB;BA3C;1106 1165 11AB; # (먼; 먼; 먼; 먼; 먼; ) HANGUL SYLLABLE MEON
+BA3D;BA3D;1106 1165 11AC;BA3D;1106 1165 11AC; # (먽; 먽; 먽; 먽; 먽; ) HANGUL SYLLABLE MEONJ
+BA3E;BA3E;1106 1165 11AD;BA3E;1106 1165 11AD; # (먾; 먾; 먾; 먾; 먾; ) HANGUL SYLLABLE MEONH
+BA3F;BA3F;1106 1165 11AE;BA3F;1106 1165 11AE; # (먿; 먿; 먿; 먿; 먿; ) HANGUL SYLLABLE MEOD
+BA40;BA40;1106 1165 11AF;BA40;1106 1165 11AF; # (멀; 멀; 멀; 멀; 멀; ) HANGUL SYLLABLE MEOL
+BA41;BA41;1106 1165 11B0;BA41;1106 1165 11B0; # (멁; 멁; 멁; 멁; 멁; ) HANGUL SYLLABLE MEOLG
+BA42;BA42;1106 1165 11B1;BA42;1106 1165 11B1; # (멂; 멂; 멂; 멂; 멂; ) HANGUL SYLLABLE MEOLM
+BA43;BA43;1106 1165 11B2;BA43;1106 1165 11B2; # (멃; 멃; 멃; 멃; 멃; ) HANGUL SYLLABLE MEOLB
+BA44;BA44;1106 1165 11B3;BA44;1106 1165 11B3; # (멄; 멄; 멄; 멄; 멄; ) HANGUL SYLLABLE MEOLS
+BA45;BA45;1106 1165 11B4;BA45;1106 1165 11B4; # (멅; 멅; 멅; 멅; 멅; ) HANGUL SYLLABLE MEOLT
+BA46;BA46;1106 1165 11B5;BA46;1106 1165 11B5; # (멆; 멆; 멆; 멆; 멆; ) HANGUL SYLLABLE MEOLP
+BA47;BA47;1106 1165 11B6;BA47;1106 1165 11B6; # (멇; 멇; 멇; 멇; 멇; ) HANGUL SYLLABLE MEOLH
+BA48;BA48;1106 1165 11B7;BA48;1106 1165 11B7; # (멈; 멈; 멈; 멈; 멈; ) HANGUL SYLLABLE MEOM
+BA49;BA49;1106 1165 11B8;BA49;1106 1165 11B8; # (멉; 멉; 멉; 멉; 멉; ) HANGUL SYLLABLE MEOB
+BA4A;BA4A;1106 1165 11B9;BA4A;1106 1165 11B9; # (멊; 멊; 멊; 멊; 멊; ) HANGUL SYLLABLE MEOBS
+BA4B;BA4B;1106 1165 11BA;BA4B;1106 1165 11BA; # (멋; 멋; 멋; 멋; 멋; ) HANGUL SYLLABLE MEOS
+BA4C;BA4C;1106 1165 11BB;BA4C;1106 1165 11BB; # (멌; 멌; 멌; 멌; 멌; ) HANGUL SYLLABLE MEOSS
+BA4D;BA4D;1106 1165 11BC;BA4D;1106 1165 11BC; # (멍; 멍; 멍; 멍; 멍; ) HANGUL SYLLABLE MEONG
+BA4E;BA4E;1106 1165 11BD;BA4E;1106 1165 11BD; # (멎; 멎; 멎; 멎; 멎; ) HANGUL SYLLABLE MEOJ
+BA4F;BA4F;1106 1165 11BE;BA4F;1106 1165 11BE; # (멏; 멏; 멏; 멏; 멏; ) HANGUL SYLLABLE MEOC
+BA50;BA50;1106 1165 11BF;BA50;1106 1165 11BF; # (멐; 멐; 멐; 멐; 멐; ) HANGUL SYLLABLE MEOK
+BA51;BA51;1106 1165 11C0;BA51;1106 1165 11C0; # (멑; 멑; 멑; 멑; 멑; ) HANGUL SYLLABLE MEOT
+BA52;BA52;1106 1165 11C1;BA52;1106 1165 11C1; # (멒; 멒; 멒; 멒; 멒; ) HANGUL SYLLABLE MEOP
+BA53;BA53;1106 1165 11C2;BA53;1106 1165 11C2; # (멓; 멓; 멓; 멓; 멓; ) HANGUL SYLLABLE MEOH
+BA54;BA54;1106 1166;BA54;1106 1166; # (메; 메; 메; 메; 메; ) HANGUL SYLLABLE ME
+BA55;BA55;1106 1166 11A8;BA55;1106 1166 11A8; # (멕; 멕; 멕; 멕; 멕; ) HANGUL SYLLABLE MEG
+BA56;BA56;1106 1166 11A9;BA56;1106 1166 11A9; # (멖; 멖; 멖; 멖; 멖; ) HANGUL SYLLABLE MEGG
+BA57;BA57;1106 1166 11AA;BA57;1106 1166 11AA; # (멗; 멗; 멗; 멗; 멗; ) HANGUL SYLLABLE MEGS
+BA58;BA58;1106 1166 11AB;BA58;1106 1166 11AB; # (멘; 멘; 멘; 멘; 멘; ) HANGUL SYLLABLE MEN
+BA59;BA59;1106 1166 11AC;BA59;1106 1166 11AC; # (멙; 멙; 멙; 멙; 멙; ) HANGUL SYLLABLE MENJ
+BA5A;BA5A;1106 1166 11AD;BA5A;1106 1166 11AD; # (멚; 멚; 멚; 멚; 멚; ) HANGUL SYLLABLE MENH
+BA5B;BA5B;1106 1166 11AE;BA5B;1106 1166 11AE; # (멛; 멛; 멛; 멛; 멛; ) HANGUL SYLLABLE MED
+BA5C;BA5C;1106 1166 11AF;BA5C;1106 1166 11AF; # (멜; 멜; 멜; 멜; 멜; ) HANGUL SYLLABLE MEL
+BA5D;BA5D;1106 1166 11B0;BA5D;1106 1166 11B0; # (멝; 멝; 멝; 멝; 멝; ) HANGUL SYLLABLE MELG
+BA5E;BA5E;1106 1166 11B1;BA5E;1106 1166 11B1; # (멞; 멞; 멞; 멞; 멞; ) HANGUL SYLLABLE MELM
+BA5F;BA5F;1106 1166 11B2;BA5F;1106 1166 11B2; # (멟; 멟; 멟; 멟; 멟; ) HANGUL SYLLABLE MELB
+BA60;BA60;1106 1166 11B3;BA60;1106 1166 11B3; # (멠; 멠; 멠; 멠; 멠; ) HANGUL SYLLABLE MELS
+BA61;BA61;1106 1166 11B4;BA61;1106 1166 11B4; # (멡; 멡; 멡; 멡; 멡; ) HANGUL SYLLABLE MELT
+BA62;BA62;1106 1166 11B5;BA62;1106 1166 11B5; # (멢; 멢; 멢; 멢; 멢; ) HANGUL SYLLABLE MELP
+BA63;BA63;1106 1166 11B6;BA63;1106 1166 11B6; # (멣; 멣; 멣; 멣; 멣; ) HANGUL SYLLABLE MELH
+BA64;BA64;1106 1166 11B7;BA64;1106 1166 11B7; # (멤; 멤; 멤; 멤; 멤; ) HANGUL SYLLABLE MEM
+BA65;BA65;1106 1166 11B8;BA65;1106 1166 11B8; # (멥; 멥; 멥; 멥; 멥; ) HANGUL SYLLABLE MEB
+BA66;BA66;1106 1166 11B9;BA66;1106 1166 11B9; # (멦; 멦; 멦; 멦; 멦; ) HANGUL SYLLABLE MEBS
+BA67;BA67;1106 1166 11BA;BA67;1106 1166 11BA; # (멧; 멧; 멧; 멧; 멧; ) HANGUL SYLLABLE MES
+BA68;BA68;1106 1166 11BB;BA68;1106 1166 11BB; # (멨; 멨; 멨; 멨; 멨; ) HANGUL SYLLABLE MESS
+BA69;BA69;1106 1166 11BC;BA69;1106 1166 11BC; # (멩; 멩; 멩; 멩; 멩; ) HANGUL SYLLABLE MENG
+BA6A;BA6A;1106 1166 11BD;BA6A;1106 1166 11BD; # (멪; 멪; 멪; 멪; 멪; ) HANGUL SYLLABLE MEJ
+BA6B;BA6B;1106 1166 11BE;BA6B;1106 1166 11BE; # (멫; 멫; 멫; 멫; 멫; ) HANGUL SYLLABLE MEC
+BA6C;BA6C;1106 1166 11BF;BA6C;1106 1166 11BF; # (멬; 멬; 멬; 멬; 멬; ) HANGUL SYLLABLE MEK
+BA6D;BA6D;1106 1166 11C0;BA6D;1106 1166 11C0; # (멭; 멭; 멭; 멭; 멭; ) HANGUL SYLLABLE MET
+BA6E;BA6E;1106 1166 11C1;BA6E;1106 1166 11C1; # (멮; 멮; 멮; 멮; 멮; ) HANGUL SYLLABLE MEP
+BA6F;BA6F;1106 1166 11C2;BA6F;1106 1166 11C2; # (멯; 멯; 멯; 멯; 멯; ) HANGUL SYLLABLE MEH
+BA70;BA70;1106 1167;BA70;1106 1167; # (며; 며; 며; 며; 며; ) HANGUL SYLLABLE MYEO
+BA71;BA71;1106 1167 11A8;BA71;1106 1167 11A8; # (멱; 멱; 멱; 멱; 멱; ) HANGUL SYLLABLE MYEOG
+BA72;BA72;1106 1167 11A9;BA72;1106 1167 11A9; # (멲; 멲; 멲; 멲; 멲; ) HANGUL SYLLABLE MYEOGG
+BA73;BA73;1106 1167 11AA;BA73;1106 1167 11AA; # (멳; 멳; 멳; 멳; 멳; ) HANGUL SYLLABLE MYEOGS
+BA74;BA74;1106 1167 11AB;BA74;1106 1167 11AB; # (면; 면; 면; 면; 면; ) HANGUL SYLLABLE MYEON
+BA75;BA75;1106 1167 11AC;BA75;1106 1167 11AC; # (멵; 멵; 멵; 멵; 멵; ) HANGUL SYLLABLE MYEONJ
+BA76;BA76;1106 1167 11AD;BA76;1106 1167 11AD; # (멶; 멶; 멶; 멶; 멶; ) HANGUL SYLLABLE MYEONH
+BA77;BA77;1106 1167 11AE;BA77;1106 1167 11AE; # (멷; 멷; 멷; 멷; 멷; ) HANGUL SYLLABLE MYEOD
+BA78;BA78;1106 1167 11AF;BA78;1106 1167 11AF; # (멸; 멸; 멸; 멸; 멸; ) HANGUL SYLLABLE MYEOL
+BA79;BA79;1106 1167 11B0;BA79;1106 1167 11B0; # (멹; 멹; 멹; 멹; 멹; ) HANGUL SYLLABLE MYEOLG
+BA7A;BA7A;1106 1167 11B1;BA7A;1106 1167 11B1; # (멺; 멺; 멺; 멺; 멺; ) HANGUL SYLLABLE MYEOLM
+BA7B;BA7B;1106 1167 11B2;BA7B;1106 1167 11B2; # (멻; 멻; 멻; 멻; 멻; ) HANGUL SYLLABLE MYEOLB
+BA7C;BA7C;1106 1167 11B3;BA7C;1106 1167 11B3; # (멼; 멼; 멼; 멼; 멼; ) HANGUL SYLLABLE MYEOLS
+BA7D;BA7D;1106 1167 11B4;BA7D;1106 1167 11B4; # (멽; 멽; 멽; 멽; 멽; ) HANGUL SYLLABLE MYEOLT
+BA7E;BA7E;1106 1167 11B5;BA7E;1106 1167 11B5; # (멾; 멾; 멾; 멾; 멾; ) HANGUL SYLLABLE MYEOLP
+BA7F;BA7F;1106 1167 11B6;BA7F;1106 1167 11B6; # (멿; 멿; 멿; 멿; 멿; ) HANGUL SYLLABLE MYEOLH
+BA80;BA80;1106 1167 11B7;BA80;1106 1167 11B7; # (몀; 몀; 몀; 몀; 몀; ) HANGUL SYLLABLE MYEOM
+BA81;BA81;1106 1167 11B8;BA81;1106 1167 11B8; # (몁; 몁; 몁; 몁; 몁; ) HANGUL SYLLABLE MYEOB
+BA82;BA82;1106 1167 11B9;BA82;1106 1167 11B9; # (몂; 몂; 몂; 몂; 몂; ) HANGUL SYLLABLE MYEOBS
+BA83;BA83;1106 1167 11BA;BA83;1106 1167 11BA; # (몃; 몃; 몃; 몃; 몃; ) HANGUL SYLLABLE MYEOS
+BA84;BA84;1106 1167 11BB;BA84;1106 1167 11BB; # (몄; 몄; 몄; 몄; 몄; ) HANGUL SYLLABLE MYEOSS
+BA85;BA85;1106 1167 11BC;BA85;1106 1167 11BC; # (명; 명; 명; 명; 명; ) HANGUL SYLLABLE MYEONG
+BA86;BA86;1106 1167 11BD;BA86;1106 1167 11BD; # (몆; 몆; 몆; 몆; 몆; ) HANGUL SYLLABLE MYEOJ
+BA87;BA87;1106 1167 11BE;BA87;1106 1167 11BE; # (몇; 몇; 몇; 몇; 몇; ) HANGUL SYLLABLE MYEOC
+BA88;BA88;1106 1167 11BF;BA88;1106 1167 11BF; # (몈; 몈; 몈; 몈; 몈; ) HANGUL SYLLABLE MYEOK
+BA89;BA89;1106 1167 11C0;BA89;1106 1167 11C0; # (몉; 몉; 몉; 몉; 몉; ) HANGUL SYLLABLE MYEOT
+BA8A;BA8A;1106 1167 11C1;BA8A;1106 1167 11C1; # (몊; 몊; 몊; 몊; 몊; ) HANGUL SYLLABLE MYEOP
+BA8B;BA8B;1106 1167 11C2;BA8B;1106 1167 11C2; # (몋; 몋; 몋; 몋; 몋; ) HANGUL SYLLABLE MYEOH
+BA8C;BA8C;1106 1168;BA8C;1106 1168; # (몌; 몌; 몌; 몌; 몌; ) HANGUL SYLLABLE MYE
+BA8D;BA8D;1106 1168 11A8;BA8D;1106 1168 11A8; # (몍; 몍; 몍; 몍; 몍; ) HANGUL SYLLABLE MYEG
+BA8E;BA8E;1106 1168 11A9;BA8E;1106 1168 11A9; # (몎; 몎; 몎; 몎; 몎; ) HANGUL SYLLABLE MYEGG
+BA8F;BA8F;1106 1168 11AA;BA8F;1106 1168 11AA; # (몏; 몏; 몏; 몏; 몏; ) HANGUL SYLLABLE MYEGS
+BA90;BA90;1106 1168 11AB;BA90;1106 1168 11AB; # (몐; 몐; 몐; 몐; 몐; ) HANGUL SYLLABLE MYEN
+BA91;BA91;1106 1168 11AC;BA91;1106 1168 11AC; # (몑; 몑; 몑; 몑; 몑; ) HANGUL SYLLABLE MYENJ
+BA92;BA92;1106 1168 11AD;BA92;1106 1168 11AD; # (몒; 몒; 몒; 몒; 몒; ) HANGUL SYLLABLE MYENH
+BA93;BA93;1106 1168 11AE;BA93;1106 1168 11AE; # (몓; 몓; 몓; 몓; 몓; ) HANGUL SYLLABLE MYED
+BA94;BA94;1106 1168 11AF;BA94;1106 1168 11AF; # (몔; 몔; 몔; 몔; 몔; ) HANGUL SYLLABLE MYEL
+BA95;BA95;1106 1168 11B0;BA95;1106 1168 11B0; # (몕; 몕; 몕; 몕; 몕; ) HANGUL SYLLABLE MYELG
+BA96;BA96;1106 1168 11B1;BA96;1106 1168 11B1; # (몖; 몖; 몖; 몖; 몖; ) HANGUL SYLLABLE MYELM
+BA97;BA97;1106 1168 11B2;BA97;1106 1168 11B2; # (몗; 몗; 몗; 몗; 몗; ) HANGUL SYLLABLE MYELB
+BA98;BA98;1106 1168 11B3;BA98;1106 1168 11B3; # (몘; 몘; 몘; 몘; 몘; ) HANGUL SYLLABLE MYELS
+BA99;BA99;1106 1168 11B4;BA99;1106 1168 11B4; # (몙; 몙; 몙; 몙; 몙; ) HANGUL SYLLABLE MYELT
+BA9A;BA9A;1106 1168 11B5;BA9A;1106 1168 11B5; # (몚; 몚; 몚; 몚; 몚; ) HANGUL SYLLABLE MYELP
+BA9B;BA9B;1106 1168 11B6;BA9B;1106 1168 11B6; # (몛; 몛; 몛; 몛; 몛; ) HANGUL SYLLABLE MYELH
+BA9C;BA9C;1106 1168 11B7;BA9C;1106 1168 11B7; # (몜; 몜; 몜; 몜; 몜; ) HANGUL SYLLABLE MYEM
+BA9D;BA9D;1106 1168 11B8;BA9D;1106 1168 11B8; # (몝; 몝; 몝; 몝; 몝; ) HANGUL SYLLABLE MYEB
+BA9E;BA9E;1106 1168 11B9;BA9E;1106 1168 11B9; # (몞; 몞; 몞; 몞; 몞; ) HANGUL SYLLABLE MYEBS
+BA9F;BA9F;1106 1168 11BA;BA9F;1106 1168 11BA; # (몟; 몟; 몟; 몟; 몟; ) HANGUL SYLLABLE MYES
+BAA0;BAA0;1106 1168 11BB;BAA0;1106 1168 11BB; # (몠; 몠; 몠; 몠; 몠; ) HANGUL SYLLABLE MYESS
+BAA1;BAA1;1106 1168 11BC;BAA1;1106 1168 11BC; # (몡; 몡; 몡; 몡; 몡; ) HANGUL SYLLABLE MYENG
+BAA2;BAA2;1106 1168 11BD;BAA2;1106 1168 11BD; # (몢; 몢; 몢; 몢; 몢; ) HANGUL SYLLABLE MYEJ
+BAA3;BAA3;1106 1168 11BE;BAA3;1106 1168 11BE; # (몣; 몣; 몣; 몣; 몣; ) HANGUL SYLLABLE MYEC
+BAA4;BAA4;1106 1168 11BF;BAA4;1106 1168 11BF; # (몤; 몤; 몤; 몤; 몤; ) HANGUL SYLLABLE MYEK
+BAA5;BAA5;1106 1168 11C0;BAA5;1106 1168 11C0; # (몥; 몥; 몥; 몥; 몥; ) HANGUL SYLLABLE MYET
+BAA6;BAA6;1106 1168 11C1;BAA6;1106 1168 11C1; # (몦; 몦; 몦; 몦; 몦; ) HANGUL SYLLABLE MYEP
+BAA7;BAA7;1106 1168 11C2;BAA7;1106 1168 11C2; # (몧; 몧; 몧; 몧; 몧; ) HANGUL SYLLABLE MYEH
+BAA8;BAA8;1106 1169;BAA8;1106 1169; # (모; 모; 모; 모; 모; ) HANGUL SYLLABLE MO
+BAA9;BAA9;1106 1169 11A8;BAA9;1106 1169 11A8; # (목; 목; 목; 목; 목; ) HANGUL SYLLABLE MOG
+BAAA;BAAA;1106 1169 11A9;BAAA;1106 1169 11A9; # (몪; 몪; 몪; 몪; 몪; ) HANGUL SYLLABLE MOGG
+BAAB;BAAB;1106 1169 11AA;BAAB;1106 1169 11AA; # (몫; 몫; 몫; 몫; 몫; ) HANGUL SYLLABLE MOGS
+BAAC;BAAC;1106 1169 11AB;BAAC;1106 1169 11AB; # (몬; 몬; 몬; 몬; 몬; ) HANGUL SYLLABLE MON
+BAAD;BAAD;1106 1169 11AC;BAAD;1106 1169 11AC; # (몭; 몭; 몭; 몭; 몭; ) HANGUL SYLLABLE MONJ
+BAAE;BAAE;1106 1169 11AD;BAAE;1106 1169 11AD; # (몮; 몮; 몮; 몮; 몮; ) HANGUL SYLLABLE MONH
+BAAF;BAAF;1106 1169 11AE;BAAF;1106 1169 11AE; # (몯; 몯; 몯; 몯; 몯; ) HANGUL SYLLABLE MOD
+BAB0;BAB0;1106 1169 11AF;BAB0;1106 1169 11AF; # (몰; 몰; 몰; 몰; 몰; ) HANGUL SYLLABLE MOL
+BAB1;BAB1;1106 1169 11B0;BAB1;1106 1169 11B0; # (몱; 몱; 몱; 몱; 몱; ) HANGUL SYLLABLE MOLG
+BAB2;BAB2;1106 1169 11B1;BAB2;1106 1169 11B1; # (몲; 몲; 몲; 몲; 몲; ) HANGUL SYLLABLE MOLM
+BAB3;BAB3;1106 1169 11B2;BAB3;1106 1169 11B2; # (몳; 몳; 몳; 몳; 몳; ) HANGUL SYLLABLE MOLB
+BAB4;BAB4;1106 1169 11B3;BAB4;1106 1169 11B3; # (몴; 몴; 몴; 몴; 몴; ) HANGUL SYLLABLE MOLS
+BAB5;BAB5;1106 1169 11B4;BAB5;1106 1169 11B4; # (몵; 몵; 몵; 몵; 몵; ) HANGUL SYLLABLE MOLT
+BAB6;BAB6;1106 1169 11B5;BAB6;1106 1169 11B5; # (몶; 몶; 몶; 몶; 몶; ) HANGUL SYLLABLE MOLP
+BAB7;BAB7;1106 1169 11B6;BAB7;1106 1169 11B6; # (몷; 몷; 몷; 몷; 몷; ) HANGUL SYLLABLE MOLH
+BAB8;BAB8;1106 1169 11B7;BAB8;1106 1169 11B7; # (몸; 몸; 몸; 몸; 몸; ) HANGUL SYLLABLE MOM
+BAB9;BAB9;1106 1169 11B8;BAB9;1106 1169 11B8; # (몹; 몹; 몹; 몹; 몹; ) HANGUL SYLLABLE MOB
+BABA;BABA;1106 1169 11B9;BABA;1106 1169 11B9; # (몺; 몺; 몺; 몺; 몺; ) HANGUL SYLLABLE MOBS
+BABB;BABB;1106 1169 11BA;BABB;1106 1169 11BA; # (못; 못; 못; 못; 못; ) HANGUL SYLLABLE MOS
+BABC;BABC;1106 1169 11BB;BABC;1106 1169 11BB; # (몼; 몼; 몼; 몼; 몼; ) HANGUL SYLLABLE MOSS
+BABD;BABD;1106 1169 11BC;BABD;1106 1169 11BC; # (몽; 몽; 몽; 몽; 몽; ) HANGUL SYLLABLE MONG
+BABE;BABE;1106 1169 11BD;BABE;1106 1169 11BD; # (몾; 몾; 몾; 몾; 몾; ) HANGUL SYLLABLE MOJ
+BABF;BABF;1106 1169 11BE;BABF;1106 1169 11BE; # (몿; 몿; 몿; 몿; 몿; ) HANGUL SYLLABLE MOC
+BAC0;BAC0;1106 1169 11BF;BAC0;1106 1169 11BF; # (뫀; 뫀; 뫀; 뫀; 뫀; ) HANGUL SYLLABLE MOK
+BAC1;BAC1;1106 1169 11C0;BAC1;1106 1169 11C0; # (뫁; 뫁; 뫁; 뫁; 뫁; ) HANGUL SYLLABLE MOT
+BAC2;BAC2;1106 1169 11C1;BAC2;1106 1169 11C1; # (뫂; 뫂; 뫂; 뫂; 뫂; ) HANGUL SYLLABLE MOP
+BAC3;BAC3;1106 1169 11C2;BAC3;1106 1169 11C2; # (뫃; 뫃; 뫃; 뫃; 뫃; ) HANGUL SYLLABLE MOH
+BAC4;BAC4;1106 116A;BAC4;1106 116A; # (뫄; 뫄; 뫄; 뫄; 뫄; ) HANGUL SYLLABLE MWA
+BAC5;BAC5;1106 116A 11A8;BAC5;1106 116A 11A8; # (뫅; 뫅; 뫅; 뫅; 뫅; ) HANGUL SYLLABLE MWAG
+BAC6;BAC6;1106 116A 11A9;BAC6;1106 116A 11A9; # (뫆; 뫆; 뫆; 뫆; 뫆; ) HANGUL SYLLABLE MWAGG
+BAC7;BAC7;1106 116A 11AA;BAC7;1106 116A 11AA; # (뫇; 뫇; 뫇; 뫇; 뫇; ) HANGUL SYLLABLE MWAGS
+BAC8;BAC8;1106 116A 11AB;BAC8;1106 116A 11AB; # (뫈; 뫈; 뫈; 뫈; 뫈; ) HANGUL SYLLABLE MWAN
+BAC9;BAC9;1106 116A 11AC;BAC9;1106 116A 11AC; # (뫉; 뫉; 뫉; 뫉; 뫉; ) HANGUL SYLLABLE MWANJ
+BACA;BACA;1106 116A 11AD;BACA;1106 116A 11AD; # (뫊; 뫊; 뫊; 뫊; 뫊; ) HANGUL SYLLABLE MWANH
+BACB;BACB;1106 116A 11AE;BACB;1106 116A 11AE; # (뫋; 뫋; 뫋; 뫋; 뫋; ) HANGUL SYLLABLE MWAD
+BACC;BACC;1106 116A 11AF;BACC;1106 116A 11AF; # (뫌; 뫌; 뫌; 뫌; 뫌; ) HANGUL SYLLABLE MWAL
+BACD;BACD;1106 116A 11B0;BACD;1106 116A 11B0; # (뫍; 뫍; 뫍; 뫍; 뫍; ) HANGUL SYLLABLE MWALG
+BACE;BACE;1106 116A 11B1;BACE;1106 116A 11B1; # (뫎; 뫎; 뫎; 뫎; 뫎; ) HANGUL SYLLABLE MWALM
+BACF;BACF;1106 116A 11B2;BACF;1106 116A 11B2; # (뫏; 뫏; 뫏; 뫏; 뫏; ) HANGUL SYLLABLE MWALB
+BAD0;BAD0;1106 116A 11B3;BAD0;1106 116A 11B3; # (뫐; 뫐; 뫐; 뫐; 뫐; ) HANGUL SYLLABLE MWALS
+BAD1;BAD1;1106 116A 11B4;BAD1;1106 116A 11B4; # (뫑; 뫑; 뫑; 뫑; 뫑; ) HANGUL SYLLABLE MWALT
+BAD2;BAD2;1106 116A 11B5;BAD2;1106 116A 11B5; # (뫒; 뫒; 뫒; 뫒; 뫒; ) HANGUL SYLLABLE MWALP
+BAD3;BAD3;1106 116A 11B6;BAD3;1106 116A 11B6; # (뫓; 뫓; 뫓; 뫓; 뫓; ) HANGUL SYLLABLE MWALH
+BAD4;BAD4;1106 116A 11B7;BAD4;1106 116A 11B7; # (뫔; 뫔; 뫔; 뫔; 뫔; ) HANGUL SYLLABLE MWAM
+BAD5;BAD5;1106 116A 11B8;BAD5;1106 116A 11B8; # (뫕; 뫕; 뫕; 뫕; 뫕; ) HANGUL SYLLABLE MWAB
+BAD6;BAD6;1106 116A 11B9;BAD6;1106 116A 11B9; # (뫖; 뫖; 뫖; 뫖; 뫖; ) HANGUL SYLLABLE MWABS
+BAD7;BAD7;1106 116A 11BA;BAD7;1106 116A 11BA; # (뫗; 뫗; 뫗; 뫗; 뫗; ) HANGUL SYLLABLE MWAS
+BAD8;BAD8;1106 116A 11BB;BAD8;1106 116A 11BB; # (뫘; 뫘; 뫘; 뫘; 뫘; ) HANGUL SYLLABLE MWASS
+BAD9;BAD9;1106 116A 11BC;BAD9;1106 116A 11BC; # (뫙; 뫙; 뫙; 뫙; 뫙; ) HANGUL SYLLABLE MWANG
+BADA;BADA;1106 116A 11BD;BADA;1106 116A 11BD; # (뫚; 뫚; 뫚; 뫚; 뫚; ) HANGUL SYLLABLE MWAJ
+BADB;BADB;1106 116A 11BE;BADB;1106 116A 11BE; # (뫛; 뫛; 뫛; 뫛; 뫛; ) HANGUL SYLLABLE MWAC
+BADC;BADC;1106 116A 11BF;BADC;1106 116A 11BF; # (뫜; 뫜; 뫜; 뫜; 뫜; ) HANGUL SYLLABLE MWAK
+BADD;BADD;1106 116A 11C0;BADD;1106 116A 11C0; # (뫝; 뫝; 뫝; 뫝; 뫝; ) HANGUL SYLLABLE MWAT
+BADE;BADE;1106 116A 11C1;BADE;1106 116A 11C1; # (뫞; 뫞; 뫞; 뫞; 뫞; ) HANGUL SYLLABLE MWAP
+BADF;BADF;1106 116A 11C2;BADF;1106 116A 11C2; # (뫟; 뫟; 뫟; 뫟; 뫟; ) HANGUL SYLLABLE MWAH
+BAE0;BAE0;1106 116B;BAE0;1106 116B; # (뫠; 뫠; 뫠; 뫠; 뫠; ) HANGUL SYLLABLE MWAE
+BAE1;BAE1;1106 116B 11A8;BAE1;1106 116B 11A8; # (뫡; 뫡; 뫡; 뫡; 뫡; ) HANGUL SYLLABLE MWAEG
+BAE2;BAE2;1106 116B 11A9;BAE2;1106 116B 11A9; # (뫢; 뫢; 뫢; 뫢; 뫢; ) HANGUL SYLLABLE MWAEGG
+BAE3;BAE3;1106 116B 11AA;BAE3;1106 116B 11AA; # (뫣; 뫣; 뫣; 뫣; 뫣; ) HANGUL SYLLABLE MWAEGS
+BAE4;BAE4;1106 116B 11AB;BAE4;1106 116B 11AB; # (뫤; 뫤; 뫤; 뫤; 뫤; ) HANGUL SYLLABLE MWAEN
+BAE5;BAE5;1106 116B 11AC;BAE5;1106 116B 11AC; # (뫥; 뫥; 뫥; 뫥; 뫥; ) HANGUL SYLLABLE MWAENJ
+BAE6;BAE6;1106 116B 11AD;BAE6;1106 116B 11AD; # (뫦; 뫦; 뫦; 뫦; 뫦; ) HANGUL SYLLABLE MWAENH
+BAE7;BAE7;1106 116B 11AE;BAE7;1106 116B 11AE; # (뫧; 뫧; 뫧; 뫧; 뫧; ) HANGUL SYLLABLE MWAED
+BAE8;BAE8;1106 116B 11AF;BAE8;1106 116B 11AF; # (뫨; 뫨; 뫨; 뫨; 뫨; ) HANGUL SYLLABLE MWAEL
+BAE9;BAE9;1106 116B 11B0;BAE9;1106 116B 11B0; # (뫩; 뫩; 뫩; 뫩; 뫩; ) HANGUL SYLLABLE MWAELG
+BAEA;BAEA;1106 116B 11B1;BAEA;1106 116B 11B1; # (뫪; 뫪; 뫪; 뫪; 뫪; ) HANGUL SYLLABLE MWAELM
+BAEB;BAEB;1106 116B 11B2;BAEB;1106 116B 11B2; # (뫫; 뫫; 뫫; 뫫; 뫫; ) HANGUL SYLLABLE MWAELB
+BAEC;BAEC;1106 116B 11B3;BAEC;1106 116B 11B3; # (뫬; 뫬; 뫬; 뫬; 뫬; ) HANGUL SYLLABLE MWAELS
+BAED;BAED;1106 116B 11B4;BAED;1106 116B 11B4; # (뫭; 뫭; 뫭; 뫭; 뫭; ) HANGUL SYLLABLE MWAELT
+BAEE;BAEE;1106 116B 11B5;BAEE;1106 116B 11B5; # (뫮; 뫮; 뫮; 뫮; 뫮; ) HANGUL SYLLABLE MWAELP
+BAEF;BAEF;1106 116B 11B6;BAEF;1106 116B 11B6; # (뫯; 뫯; 뫯; 뫯; 뫯; ) HANGUL SYLLABLE MWAELH
+BAF0;BAF0;1106 116B 11B7;BAF0;1106 116B 11B7; # (뫰; 뫰; 뫰; 뫰; 뫰; ) HANGUL SYLLABLE MWAEM
+BAF1;BAF1;1106 116B 11B8;BAF1;1106 116B 11B8; # (뫱; 뫱; 뫱; 뫱; 뫱; ) HANGUL SYLLABLE MWAEB
+BAF2;BAF2;1106 116B 11B9;BAF2;1106 116B 11B9; # (뫲; 뫲; 뫲; 뫲; 뫲; ) HANGUL SYLLABLE MWAEBS
+BAF3;BAF3;1106 116B 11BA;BAF3;1106 116B 11BA; # (뫳; 뫳; 뫳; 뫳; 뫳; ) HANGUL SYLLABLE MWAES
+BAF4;BAF4;1106 116B 11BB;BAF4;1106 116B 11BB; # (뫴; 뫴; 뫴; 뫴; 뫴; ) HANGUL SYLLABLE MWAESS
+BAF5;BAF5;1106 116B 11BC;BAF5;1106 116B 11BC; # (뫵; 뫵; 뫵; 뫵; 뫵; ) HANGUL SYLLABLE MWAENG
+BAF6;BAF6;1106 116B 11BD;BAF6;1106 116B 11BD; # (뫶; 뫶; 뫶; 뫶; 뫶; ) HANGUL SYLLABLE MWAEJ
+BAF7;BAF7;1106 116B 11BE;BAF7;1106 116B 11BE; # (뫷; 뫷; 뫷; 뫷; 뫷; ) HANGUL SYLLABLE MWAEC
+BAF8;BAF8;1106 116B 11BF;BAF8;1106 116B 11BF; # (뫸; 뫸; 뫸; 뫸; 뫸; ) HANGUL SYLLABLE MWAEK
+BAF9;BAF9;1106 116B 11C0;BAF9;1106 116B 11C0; # (뫹; 뫹; 뫹; 뫹; 뫹; ) HANGUL SYLLABLE MWAET
+BAFA;BAFA;1106 116B 11C1;BAFA;1106 116B 11C1; # (뫺; 뫺; 뫺; 뫺; 뫺; ) HANGUL SYLLABLE MWAEP
+BAFB;BAFB;1106 116B 11C2;BAFB;1106 116B 11C2; # (뫻; 뫻; 뫻; 뫻; 뫻; ) HANGUL SYLLABLE MWAEH
+BAFC;BAFC;1106 116C;BAFC;1106 116C; # (뫼; 뫼; 뫼; 뫼; 뫼; ) HANGUL SYLLABLE MOE
+BAFD;BAFD;1106 116C 11A8;BAFD;1106 116C 11A8; # (뫽; 뫽; 뫽; 뫽; 뫽; ) HANGUL SYLLABLE MOEG
+BAFE;BAFE;1106 116C 11A9;BAFE;1106 116C 11A9; # (뫾; 뫾; 뫾; 뫾; 뫾; ) HANGUL SYLLABLE MOEGG
+BAFF;BAFF;1106 116C 11AA;BAFF;1106 116C 11AA; # (뫿; 뫿; 뫿; 뫿; 뫿; ) HANGUL SYLLABLE MOEGS
+BB00;BB00;1106 116C 11AB;BB00;1106 116C 11AB; # (묀; 묀; 묀; 묀; 묀; ) HANGUL SYLLABLE MOEN
+BB01;BB01;1106 116C 11AC;BB01;1106 116C 11AC; # (묁; 묁; 묁; 묁; 묁; ) HANGUL SYLLABLE MOENJ
+BB02;BB02;1106 116C 11AD;BB02;1106 116C 11AD; # (묂; 묂; 묂; 묂; 묂; ) HANGUL SYLLABLE MOENH
+BB03;BB03;1106 116C 11AE;BB03;1106 116C 11AE; # (묃; 묃; 묃; 묃; 묃; ) HANGUL SYLLABLE MOED
+BB04;BB04;1106 116C 11AF;BB04;1106 116C 11AF; # (묄; 묄; 묄; 묄; 묄; ) HANGUL SYLLABLE MOEL
+BB05;BB05;1106 116C 11B0;BB05;1106 116C 11B0; # (묅; 묅; 묅; 묅; 묅; ) HANGUL SYLLABLE MOELG
+BB06;BB06;1106 116C 11B1;BB06;1106 116C 11B1; # (묆; 묆; 묆; 묆; 묆; ) HANGUL SYLLABLE MOELM
+BB07;BB07;1106 116C 11B2;BB07;1106 116C 11B2; # (묇; 묇; 묇; 묇; 묇; ) HANGUL SYLLABLE MOELB
+BB08;BB08;1106 116C 11B3;BB08;1106 116C 11B3; # (묈; 묈; 묈; 묈; 묈; ) HANGUL SYLLABLE MOELS
+BB09;BB09;1106 116C 11B4;BB09;1106 116C 11B4; # (묉; 묉; 묉; 묉; 묉; ) HANGUL SYLLABLE MOELT
+BB0A;BB0A;1106 116C 11B5;BB0A;1106 116C 11B5; # (묊; 묊; 묊; 묊; 묊; ) HANGUL SYLLABLE MOELP
+BB0B;BB0B;1106 116C 11B6;BB0B;1106 116C 11B6; # (묋; 묋; 묋; 묋; 묋; ) HANGUL SYLLABLE MOELH
+BB0C;BB0C;1106 116C 11B7;BB0C;1106 116C 11B7; # (묌; 묌; 묌; 묌; 묌; ) HANGUL SYLLABLE MOEM
+BB0D;BB0D;1106 116C 11B8;BB0D;1106 116C 11B8; # (묍; 묍; 묍; 묍; 묍; ) HANGUL SYLLABLE MOEB
+BB0E;BB0E;1106 116C 11B9;BB0E;1106 116C 11B9; # (묎; 묎; 묎; 묎; 묎; ) HANGUL SYLLABLE MOEBS
+BB0F;BB0F;1106 116C 11BA;BB0F;1106 116C 11BA; # (묏; 묏; 묏; 묏; 묏; ) HANGUL SYLLABLE MOES
+BB10;BB10;1106 116C 11BB;BB10;1106 116C 11BB; # (묐; 묐; 묐; 묐; 묐; ) HANGUL SYLLABLE MOESS
+BB11;BB11;1106 116C 11BC;BB11;1106 116C 11BC; # (묑; 묑; 묑; 묑; 묑; ) HANGUL SYLLABLE MOENG
+BB12;BB12;1106 116C 11BD;BB12;1106 116C 11BD; # (묒; 묒; 묒; 묒; 묒; ) HANGUL SYLLABLE MOEJ
+BB13;BB13;1106 116C 11BE;BB13;1106 116C 11BE; # (묓; 묓; 묓; 묓; 묓; ) HANGUL SYLLABLE MOEC
+BB14;BB14;1106 116C 11BF;BB14;1106 116C 11BF; # (묔; 묔; 묔; 묔; 묔; ) HANGUL SYLLABLE MOEK
+BB15;BB15;1106 116C 11C0;BB15;1106 116C 11C0; # (묕; 묕; 묕; 묕; 묕; ) HANGUL SYLLABLE MOET
+BB16;BB16;1106 116C 11C1;BB16;1106 116C 11C1; # (묖; 묖; 묖; 묖; 묖; ) HANGUL SYLLABLE MOEP
+BB17;BB17;1106 116C 11C2;BB17;1106 116C 11C2; # (묗; 묗; 묗; 묗; 묗; ) HANGUL SYLLABLE MOEH
+BB18;BB18;1106 116D;BB18;1106 116D; # (묘; 묘; 묘; 묘; 묘; ) HANGUL SYLLABLE MYO
+BB19;BB19;1106 116D 11A8;BB19;1106 116D 11A8; # (묙; 묙; 묙; 묙; 묙; ) HANGUL SYLLABLE MYOG
+BB1A;BB1A;1106 116D 11A9;BB1A;1106 116D 11A9; # (묚; 묚; 묚; 묚; 묚; ) HANGUL SYLLABLE MYOGG
+BB1B;BB1B;1106 116D 11AA;BB1B;1106 116D 11AA; # (묛; 묛; 묛; 묛; 묛; ) HANGUL SYLLABLE MYOGS
+BB1C;BB1C;1106 116D 11AB;BB1C;1106 116D 11AB; # (묜; 묜; 묜; 묜; 묜; ) HANGUL SYLLABLE MYON
+BB1D;BB1D;1106 116D 11AC;BB1D;1106 116D 11AC; # (묝; 묝; 묝; 묝; 묝; ) HANGUL SYLLABLE MYONJ
+BB1E;BB1E;1106 116D 11AD;BB1E;1106 116D 11AD; # (묞; 묞; 묞; 묞; 묞; ) HANGUL SYLLABLE MYONH
+BB1F;BB1F;1106 116D 11AE;BB1F;1106 116D 11AE; # (묟; 묟; 묟; 묟; 묟; ) HANGUL SYLLABLE MYOD
+BB20;BB20;1106 116D 11AF;BB20;1106 116D 11AF; # (묠; 묠; 묠; 묠; 묠; ) HANGUL SYLLABLE MYOL
+BB21;BB21;1106 116D 11B0;BB21;1106 116D 11B0; # (묡; 묡; 묡; 묡; 묡; ) HANGUL SYLLABLE MYOLG
+BB22;BB22;1106 116D 11B1;BB22;1106 116D 11B1; # (묢; 묢; 묢; 묢; 묢; ) HANGUL SYLLABLE MYOLM
+BB23;BB23;1106 116D 11B2;BB23;1106 116D 11B2; # (묣; 묣; 묣; 묣; 묣; ) HANGUL SYLLABLE MYOLB
+BB24;BB24;1106 116D 11B3;BB24;1106 116D 11B3; # (묤; 묤; 묤; 묤; 묤; ) HANGUL SYLLABLE MYOLS
+BB25;BB25;1106 116D 11B4;BB25;1106 116D 11B4; # (묥; 묥; 묥; 묥; 묥; ) HANGUL SYLLABLE MYOLT
+BB26;BB26;1106 116D 11B5;BB26;1106 116D 11B5; # (묦; 묦; 묦; 묦; 묦; ) HANGUL SYLLABLE MYOLP
+BB27;BB27;1106 116D 11B6;BB27;1106 116D 11B6; # (묧; 묧; 묧; 묧; 묧; ) HANGUL SYLLABLE MYOLH
+BB28;BB28;1106 116D 11B7;BB28;1106 116D 11B7; # (묨; 묨; 묨; 묨; 묨; ) HANGUL SYLLABLE MYOM
+BB29;BB29;1106 116D 11B8;BB29;1106 116D 11B8; # (묩; 묩; 묩; 묩; 묩; ) HANGUL SYLLABLE MYOB
+BB2A;BB2A;1106 116D 11B9;BB2A;1106 116D 11B9; # (묪; 묪; 묪; 묪; 묪; ) HANGUL SYLLABLE MYOBS
+BB2B;BB2B;1106 116D 11BA;BB2B;1106 116D 11BA; # (묫; 묫; 묫; 묫; 묫; ) HANGUL SYLLABLE MYOS
+BB2C;BB2C;1106 116D 11BB;BB2C;1106 116D 11BB; # (묬; 묬; 묬; 묬; 묬; ) HANGUL SYLLABLE MYOSS
+BB2D;BB2D;1106 116D 11BC;BB2D;1106 116D 11BC; # (묭; 묭; 묭; 묭; 묭; ) HANGUL SYLLABLE MYONG
+BB2E;BB2E;1106 116D 11BD;BB2E;1106 116D 11BD; # (묮; 묮; 묮; 묮; 묮; ) HANGUL SYLLABLE MYOJ
+BB2F;BB2F;1106 116D 11BE;BB2F;1106 116D 11BE; # (묯; 묯; 묯; 묯; 묯; ) HANGUL SYLLABLE MYOC
+BB30;BB30;1106 116D 11BF;BB30;1106 116D 11BF; # (묰; 묰; 묰; 묰; 묰; ) HANGUL SYLLABLE MYOK
+BB31;BB31;1106 116D 11C0;BB31;1106 116D 11C0; # (묱; 묱; 묱; 묱; 묱; ) HANGUL SYLLABLE MYOT
+BB32;BB32;1106 116D 11C1;BB32;1106 116D 11C1; # (묲; 묲; 묲; 묲; 묲; ) HANGUL SYLLABLE MYOP
+BB33;BB33;1106 116D 11C2;BB33;1106 116D 11C2; # (묳; 묳; 묳; 묳; 묳; ) HANGUL SYLLABLE MYOH
+BB34;BB34;1106 116E;BB34;1106 116E; # (무; 무; 무; 무; 무; ) HANGUL SYLLABLE MU
+BB35;BB35;1106 116E 11A8;BB35;1106 116E 11A8; # (묵; 묵; 묵; 묵; 묵; ) HANGUL SYLLABLE MUG
+BB36;BB36;1106 116E 11A9;BB36;1106 116E 11A9; # (묶; 묶; 묶; 묶; 묶; ) HANGUL SYLLABLE MUGG
+BB37;BB37;1106 116E 11AA;BB37;1106 116E 11AA; # (묷; 묷; 묷; 묷; 묷; ) HANGUL SYLLABLE MUGS
+BB38;BB38;1106 116E 11AB;BB38;1106 116E 11AB; # (문; 문; 문; 문; 문; ) HANGUL SYLLABLE MUN
+BB39;BB39;1106 116E 11AC;BB39;1106 116E 11AC; # (묹; 묹; 묹; 묹; 묹; ) HANGUL SYLLABLE MUNJ
+BB3A;BB3A;1106 116E 11AD;BB3A;1106 116E 11AD; # (묺; 묺; 묺; 묺; 묺; ) HANGUL SYLLABLE MUNH
+BB3B;BB3B;1106 116E 11AE;BB3B;1106 116E 11AE; # (묻; 묻; 묻; 묻; 묻; ) HANGUL SYLLABLE MUD
+BB3C;BB3C;1106 116E 11AF;BB3C;1106 116E 11AF; # (물; 물; 물; 물; 물; ) HANGUL SYLLABLE MUL
+BB3D;BB3D;1106 116E 11B0;BB3D;1106 116E 11B0; # (묽; 묽; 묽; 묽; 묽; ) HANGUL SYLLABLE MULG
+BB3E;BB3E;1106 116E 11B1;BB3E;1106 116E 11B1; # (묾; 묾; 묾; 묾; 묾; ) HANGUL SYLLABLE MULM
+BB3F;BB3F;1106 116E 11B2;BB3F;1106 116E 11B2; # (묿; 묿; 묿; 묿; 묿; ) HANGUL SYLLABLE MULB
+BB40;BB40;1106 116E 11B3;BB40;1106 116E 11B3; # (뭀; 뭀; 뭀; 뭀; 뭀; ) HANGUL SYLLABLE MULS
+BB41;BB41;1106 116E 11B4;BB41;1106 116E 11B4; # (뭁; 뭁; 뭁; 뭁; 뭁; ) HANGUL SYLLABLE MULT
+BB42;BB42;1106 116E 11B5;BB42;1106 116E 11B5; # (뭂; 뭂; 뭂; 뭂; 뭂; ) HANGUL SYLLABLE MULP
+BB43;BB43;1106 116E 11B6;BB43;1106 116E 11B6; # (뭃; 뭃; 뭃; 뭃; 뭃; ) HANGUL SYLLABLE MULH
+BB44;BB44;1106 116E 11B7;BB44;1106 116E 11B7; # (뭄; 뭄; 뭄; 뭄; 뭄; ) HANGUL SYLLABLE MUM
+BB45;BB45;1106 116E 11B8;BB45;1106 116E 11B8; # (뭅; 뭅; 뭅; 뭅; 뭅; ) HANGUL SYLLABLE MUB
+BB46;BB46;1106 116E 11B9;BB46;1106 116E 11B9; # (뭆; 뭆; 뭆; 뭆; 뭆; ) HANGUL SYLLABLE MUBS
+BB47;BB47;1106 116E 11BA;BB47;1106 116E 11BA; # (뭇; 뭇; 뭇; 뭇; 뭇; ) HANGUL SYLLABLE MUS
+BB48;BB48;1106 116E 11BB;BB48;1106 116E 11BB; # (뭈; 뭈; 뭈; 뭈; 뭈; ) HANGUL SYLLABLE MUSS
+BB49;BB49;1106 116E 11BC;BB49;1106 116E 11BC; # (뭉; 뭉; 뭉; 뭉; 뭉; ) HANGUL SYLLABLE MUNG
+BB4A;BB4A;1106 116E 11BD;BB4A;1106 116E 11BD; # (뭊; 뭊; 뭊; 뭊; 뭊; ) HANGUL SYLLABLE MUJ
+BB4B;BB4B;1106 116E 11BE;BB4B;1106 116E 11BE; # (뭋; 뭋; 뭋; 뭋; 뭋; ) HANGUL SYLLABLE MUC
+BB4C;BB4C;1106 116E 11BF;BB4C;1106 116E 11BF; # (뭌; 뭌; 뭌; 뭌; 뭌; ) HANGUL SYLLABLE MUK
+BB4D;BB4D;1106 116E 11C0;BB4D;1106 116E 11C0; # (뭍; 뭍; 뭍; 뭍; 뭍; ) HANGUL SYLLABLE MUT
+BB4E;BB4E;1106 116E 11C1;BB4E;1106 116E 11C1; # (뭎; 뭎; 뭎; 뭎; 뭎; ) HANGUL SYLLABLE MUP
+BB4F;BB4F;1106 116E 11C2;BB4F;1106 116E 11C2; # (뭏; 뭏; 뭏; 뭏; 뭏; ) HANGUL SYLLABLE MUH
+BB50;BB50;1106 116F;BB50;1106 116F; # (뭐; 뭐; 뭐; 뭐; 뭐; ) HANGUL SYLLABLE MWEO
+BB51;BB51;1106 116F 11A8;BB51;1106 116F 11A8; # (뭑; 뭑; 뭑; 뭑; 뭑; ) HANGUL SYLLABLE MWEOG
+BB52;BB52;1106 116F 11A9;BB52;1106 116F 11A9; # (뭒; 뭒; 뭒; 뭒; 뭒; ) HANGUL SYLLABLE MWEOGG
+BB53;BB53;1106 116F 11AA;BB53;1106 116F 11AA; # (뭓; 뭓; 뭓; 뭓; 뭓; ) HANGUL SYLLABLE MWEOGS
+BB54;BB54;1106 116F 11AB;BB54;1106 116F 11AB; # (뭔; 뭔; 뭔; 뭔; 뭔; ) HANGUL SYLLABLE MWEON
+BB55;BB55;1106 116F 11AC;BB55;1106 116F 11AC; # (뭕; 뭕; 뭕; 뭕; 뭕; ) HANGUL SYLLABLE MWEONJ
+BB56;BB56;1106 116F 11AD;BB56;1106 116F 11AD; # (뭖; 뭖; 뭖; 뭖; 뭖; ) HANGUL SYLLABLE MWEONH
+BB57;BB57;1106 116F 11AE;BB57;1106 116F 11AE; # (뭗; 뭗; 뭗; 뭗; 뭗; ) HANGUL SYLLABLE MWEOD
+BB58;BB58;1106 116F 11AF;BB58;1106 116F 11AF; # (뭘; 뭘; 뭘; 뭘; 뭘; ) HANGUL SYLLABLE MWEOL
+BB59;BB59;1106 116F 11B0;BB59;1106 116F 11B0; # (뭙; 뭙; 뭙; 뭙; 뭙; ) HANGUL SYLLABLE MWEOLG
+BB5A;BB5A;1106 116F 11B1;BB5A;1106 116F 11B1; # (뭚; 뭚; 뭚; 뭚; 뭚; ) HANGUL SYLLABLE MWEOLM
+BB5B;BB5B;1106 116F 11B2;BB5B;1106 116F 11B2; # (뭛; 뭛; 뭛; 뭛; 뭛; ) HANGUL SYLLABLE MWEOLB
+BB5C;BB5C;1106 116F 11B3;BB5C;1106 116F 11B3; # (뭜; 뭜; 뭜; 뭜; 뭜; ) HANGUL SYLLABLE MWEOLS
+BB5D;BB5D;1106 116F 11B4;BB5D;1106 116F 11B4; # (뭝; 뭝; 뭝; 뭝; 뭝; ) HANGUL SYLLABLE MWEOLT
+BB5E;BB5E;1106 116F 11B5;BB5E;1106 116F 11B5; # (뭞; 뭞; 뭞; 뭞; 뭞; ) HANGUL SYLLABLE MWEOLP
+BB5F;BB5F;1106 116F 11B6;BB5F;1106 116F 11B6; # (뭟; 뭟; 뭟; 뭟; 뭟; ) HANGUL SYLLABLE MWEOLH
+BB60;BB60;1106 116F 11B7;BB60;1106 116F 11B7; # (뭠; 뭠; 뭠; 뭠; 뭠; ) HANGUL SYLLABLE MWEOM
+BB61;BB61;1106 116F 11B8;BB61;1106 116F 11B8; # (뭡; 뭡; 뭡; 뭡; 뭡; ) HANGUL SYLLABLE MWEOB
+BB62;BB62;1106 116F 11B9;BB62;1106 116F 11B9; # (뭢; 뭢; 뭢; 뭢; 뭢; ) HANGUL SYLLABLE MWEOBS
+BB63;BB63;1106 116F 11BA;BB63;1106 116F 11BA; # (뭣; 뭣; 뭣; 뭣; 뭣; ) HANGUL SYLLABLE MWEOS
+BB64;BB64;1106 116F 11BB;BB64;1106 116F 11BB; # (뭤; 뭤; 뭤; 뭤; 뭤; ) HANGUL SYLLABLE MWEOSS
+BB65;BB65;1106 116F 11BC;BB65;1106 116F 11BC; # (뭥; 뭥; 뭥; 뭥; 뭥; ) HANGUL SYLLABLE MWEONG
+BB66;BB66;1106 116F 11BD;BB66;1106 116F 11BD; # (뭦; 뭦; 뭦; 뭦; 뭦; ) HANGUL SYLLABLE MWEOJ
+BB67;BB67;1106 116F 11BE;BB67;1106 116F 11BE; # (뭧; 뭧; 뭧; 뭧; 뭧; ) HANGUL SYLLABLE MWEOC
+BB68;BB68;1106 116F 11BF;BB68;1106 116F 11BF; # (뭨; 뭨; 뭨; 뭨; 뭨; ) HANGUL SYLLABLE MWEOK
+BB69;BB69;1106 116F 11C0;BB69;1106 116F 11C0; # (뭩; 뭩; 뭩; 뭩; 뭩; ) HANGUL SYLLABLE MWEOT
+BB6A;BB6A;1106 116F 11C1;BB6A;1106 116F 11C1; # (뭪; 뭪; 뭪; 뭪; 뭪; ) HANGUL SYLLABLE MWEOP
+BB6B;BB6B;1106 116F 11C2;BB6B;1106 116F 11C2; # (뭫; 뭫; 뭫; 뭫; 뭫; ) HANGUL SYLLABLE MWEOH
+BB6C;BB6C;1106 1170;BB6C;1106 1170; # (뭬; 뭬; 뭬; 뭬; 뭬; ) HANGUL SYLLABLE MWE
+BB6D;BB6D;1106 1170 11A8;BB6D;1106 1170 11A8; # (뭭; 뭭; 뭭; 뭭; 뭭; ) HANGUL SYLLABLE MWEG
+BB6E;BB6E;1106 1170 11A9;BB6E;1106 1170 11A9; # (뭮; 뭮; 뭮; 뭮; 뭮; ) HANGUL SYLLABLE MWEGG
+BB6F;BB6F;1106 1170 11AA;BB6F;1106 1170 11AA; # (뭯; 뭯; 뭯; 뭯; 뭯; ) HANGUL SYLLABLE MWEGS
+BB70;BB70;1106 1170 11AB;BB70;1106 1170 11AB; # (뭰; 뭰; 뭰; 뭰; 뭰; ) HANGUL SYLLABLE MWEN
+BB71;BB71;1106 1170 11AC;BB71;1106 1170 11AC; # (뭱; 뭱; 뭱; 뭱; 뭱; ) HANGUL SYLLABLE MWENJ
+BB72;BB72;1106 1170 11AD;BB72;1106 1170 11AD; # (뭲; 뭲; 뭲; 뭲; 뭲; ) HANGUL SYLLABLE MWENH
+BB73;BB73;1106 1170 11AE;BB73;1106 1170 11AE; # (뭳; 뭳; 뭳; 뭳; 뭳; ) HANGUL SYLLABLE MWED
+BB74;BB74;1106 1170 11AF;BB74;1106 1170 11AF; # (뭴; 뭴; 뭴; 뭴; 뭴; ) HANGUL SYLLABLE MWEL
+BB75;BB75;1106 1170 11B0;BB75;1106 1170 11B0; # (뭵; 뭵; 뭵; 뭵; 뭵; ) HANGUL SYLLABLE MWELG
+BB76;BB76;1106 1170 11B1;BB76;1106 1170 11B1; # (뭶; 뭶; 뭶; 뭶; 뭶; ) HANGUL SYLLABLE MWELM
+BB77;BB77;1106 1170 11B2;BB77;1106 1170 11B2; # (뭷; 뭷; 뭷; 뭷; 뭷; ) HANGUL SYLLABLE MWELB
+BB78;BB78;1106 1170 11B3;BB78;1106 1170 11B3; # (뭸; 뭸; 뭸; 뭸; 뭸; ) HANGUL SYLLABLE MWELS
+BB79;BB79;1106 1170 11B4;BB79;1106 1170 11B4; # (뭹; 뭹; 뭹; 뭹; 뭹; ) HANGUL SYLLABLE MWELT
+BB7A;BB7A;1106 1170 11B5;BB7A;1106 1170 11B5; # (뭺; 뭺; 뭺; 뭺; 뭺; ) HANGUL SYLLABLE MWELP
+BB7B;BB7B;1106 1170 11B6;BB7B;1106 1170 11B6; # (뭻; 뭻; 뭻; 뭻; 뭻; ) HANGUL SYLLABLE MWELH
+BB7C;BB7C;1106 1170 11B7;BB7C;1106 1170 11B7; # (뭼; 뭼; 뭼; 뭼; 뭼; ) HANGUL SYLLABLE MWEM
+BB7D;BB7D;1106 1170 11B8;BB7D;1106 1170 11B8; # (뭽; 뭽; 뭽; 뭽; 뭽; ) HANGUL SYLLABLE MWEB
+BB7E;BB7E;1106 1170 11B9;BB7E;1106 1170 11B9; # (뭾; 뭾; 뭾; 뭾; 뭾; ) HANGUL SYLLABLE MWEBS
+BB7F;BB7F;1106 1170 11BA;BB7F;1106 1170 11BA; # (뭿; 뭿; 뭿; 뭿; 뭿; ) HANGUL SYLLABLE MWES
+BB80;BB80;1106 1170 11BB;BB80;1106 1170 11BB; # (뮀; 뮀; 뮀; 뮀; 뮀; ) HANGUL SYLLABLE MWESS
+BB81;BB81;1106 1170 11BC;BB81;1106 1170 11BC; # (뮁; 뮁; 뮁; 뮁; 뮁; ) HANGUL SYLLABLE MWENG
+BB82;BB82;1106 1170 11BD;BB82;1106 1170 11BD; # (뮂; 뮂; 뮂; 뮂; 뮂; ) HANGUL SYLLABLE MWEJ
+BB83;BB83;1106 1170 11BE;BB83;1106 1170 11BE; # (뮃; 뮃; 뮃; 뮃; 뮃; ) HANGUL SYLLABLE MWEC
+BB84;BB84;1106 1170 11BF;BB84;1106 1170 11BF; # (뮄; 뮄; 뮄; 뮄; 뮄; ) HANGUL SYLLABLE MWEK
+BB85;BB85;1106 1170 11C0;BB85;1106 1170 11C0; # (뮅; 뮅; 뮅; 뮅; 뮅; ) HANGUL SYLLABLE MWET
+BB86;BB86;1106 1170 11C1;BB86;1106 1170 11C1; # (뮆; 뮆; 뮆; 뮆; 뮆; ) HANGUL SYLLABLE MWEP
+BB87;BB87;1106 1170 11C2;BB87;1106 1170 11C2; # (뮇; 뮇; 뮇; 뮇; 뮇; ) HANGUL SYLLABLE MWEH
+BB88;BB88;1106 1171;BB88;1106 1171; # (뮈; 뮈; 뮈; 뮈; 뮈; ) HANGUL SYLLABLE MWI
+BB89;BB89;1106 1171 11A8;BB89;1106 1171 11A8; # (뮉; 뮉; 뮉; 뮉; 뮉; ) HANGUL SYLLABLE MWIG
+BB8A;BB8A;1106 1171 11A9;BB8A;1106 1171 11A9; # (뮊; 뮊; 뮊; 뮊; 뮊; ) HANGUL SYLLABLE MWIGG
+BB8B;BB8B;1106 1171 11AA;BB8B;1106 1171 11AA; # (뮋; 뮋; 뮋; 뮋; 뮋; ) HANGUL SYLLABLE MWIGS
+BB8C;BB8C;1106 1171 11AB;BB8C;1106 1171 11AB; # (뮌; 뮌; 뮌; 뮌; 뮌; ) HANGUL SYLLABLE MWIN
+BB8D;BB8D;1106 1171 11AC;BB8D;1106 1171 11AC; # (뮍; 뮍; 뮍; 뮍; 뮍; ) HANGUL SYLLABLE MWINJ
+BB8E;BB8E;1106 1171 11AD;BB8E;1106 1171 11AD; # (뮎; 뮎; 뮎; 뮎; 뮎; ) HANGUL SYLLABLE MWINH
+BB8F;BB8F;1106 1171 11AE;BB8F;1106 1171 11AE; # (뮏; 뮏; 뮏; 뮏; 뮏; ) HANGUL SYLLABLE MWID
+BB90;BB90;1106 1171 11AF;BB90;1106 1171 11AF; # (뮐; 뮐; 뮐; 뮐; 뮐; ) HANGUL SYLLABLE MWIL
+BB91;BB91;1106 1171 11B0;BB91;1106 1171 11B0; # (뮑; 뮑; 뮑; 뮑; 뮑; ) HANGUL SYLLABLE MWILG
+BB92;BB92;1106 1171 11B1;BB92;1106 1171 11B1; # (뮒; 뮒; 뮒; 뮒; 뮒; ) HANGUL SYLLABLE MWILM
+BB93;BB93;1106 1171 11B2;BB93;1106 1171 11B2; # (뮓; 뮓; 뮓; 뮓; 뮓; ) HANGUL SYLLABLE MWILB
+BB94;BB94;1106 1171 11B3;BB94;1106 1171 11B3; # (뮔; 뮔; 뮔; 뮔; 뮔; ) HANGUL SYLLABLE MWILS
+BB95;BB95;1106 1171 11B4;BB95;1106 1171 11B4; # (뮕; 뮕; 뮕; 뮕; 뮕; ) HANGUL SYLLABLE MWILT
+BB96;BB96;1106 1171 11B5;BB96;1106 1171 11B5; # (뮖; 뮖; 뮖; 뮖; 뮖; ) HANGUL SYLLABLE MWILP
+BB97;BB97;1106 1171 11B6;BB97;1106 1171 11B6; # (뮗; 뮗; 뮗; 뮗; 뮗; ) HANGUL SYLLABLE MWILH
+BB98;BB98;1106 1171 11B7;BB98;1106 1171 11B7; # (뮘; 뮘; 뮘; 뮘; 뮘; ) HANGUL SYLLABLE MWIM
+BB99;BB99;1106 1171 11B8;BB99;1106 1171 11B8; # (뮙; 뮙; 뮙; 뮙; 뮙; ) HANGUL SYLLABLE MWIB
+BB9A;BB9A;1106 1171 11B9;BB9A;1106 1171 11B9; # (뮚; 뮚; 뮚; 뮚; 뮚; ) HANGUL SYLLABLE MWIBS
+BB9B;BB9B;1106 1171 11BA;BB9B;1106 1171 11BA; # (뮛; 뮛; 뮛; 뮛; 뮛; ) HANGUL SYLLABLE MWIS
+BB9C;BB9C;1106 1171 11BB;BB9C;1106 1171 11BB; # (뮜; 뮜; 뮜; 뮜; 뮜; ) HANGUL SYLLABLE MWISS
+BB9D;BB9D;1106 1171 11BC;BB9D;1106 1171 11BC; # (뮝; 뮝; 뮝; 뮝; 뮝; ) HANGUL SYLLABLE MWING
+BB9E;BB9E;1106 1171 11BD;BB9E;1106 1171 11BD; # (뮞; 뮞; 뮞; 뮞; 뮞; ) HANGUL SYLLABLE MWIJ
+BB9F;BB9F;1106 1171 11BE;BB9F;1106 1171 11BE; # (뮟; 뮟; 뮟; 뮟; 뮟; ) HANGUL SYLLABLE MWIC
+BBA0;BBA0;1106 1171 11BF;BBA0;1106 1171 11BF; # (뮠; 뮠; 뮠; 뮠; 뮠; ) HANGUL SYLLABLE MWIK
+BBA1;BBA1;1106 1171 11C0;BBA1;1106 1171 11C0; # (뮡; 뮡; 뮡; 뮡; 뮡; ) HANGUL SYLLABLE MWIT
+BBA2;BBA2;1106 1171 11C1;BBA2;1106 1171 11C1; # (뮢; 뮢; 뮢; 뮢; 뮢; ) HANGUL SYLLABLE MWIP
+BBA3;BBA3;1106 1171 11C2;BBA3;1106 1171 11C2; # (뮣; 뮣; 뮣; 뮣; 뮣; ) HANGUL SYLLABLE MWIH
+BBA4;BBA4;1106 1172;BBA4;1106 1172; # (뮤; 뮤; 뮤; 뮤; 뮤; ) HANGUL SYLLABLE MYU
+BBA5;BBA5;1106 1172 11A8;BBA5;1106 1172 11A8; # (뮥; 뮥; 뮥; 뮥; 뮥; ) HANGUL SYLLABLE MYUG
+BBA6;BBA6;1106 1172 11A9;BBA6;1106 1172 11A9; # (뮦; 뮦; 뮦; 뮦; 뮦; ) HANGUL SYLLABLE MYUGG
+BBA7;BBA7;1106 1172 11AA;BBA7;1106 1172 11AA; # (뮧; 뮧; 뮧; 뮧; 뮧; ) HANGUL SYLLABLE MYUGS
+BBA8;BBA8;1106 1172 11AB;BBA8;1106 1172 11AB; # (뮨; 뮨; 뮨; 뮨; 뮨; ) HANGUL SYLLABLE MYUN
+BBA9;BBA9;1106 1172 11AC;BBA9;1106 1172 11AC; # (뮩; 뮩; 뮩; 뮩; 뮩; ) HANGUL SYLLABLE MYUNJ
+BBAA;BBAA;1106 1172 11AD;BBAA;1106 1172 11AD; # (뮪; 뮪; 뮪; 뮪; 뮪; ) HANGUL SYLLABLE MYUNH
+BBAB;BBAB;1106 1172 11AE;BBAB;1106 1172 11AE; # (뮫; 뮫; 뮫; 뮫; 뮫; ) HANGUL SYLLABLE MYUD
+BBAC;BBAC;1106 1172 11AF;BBAC;1106 1172 11AF; # (뮬; 뮬; 뮬; 뮬; 뮬; ) HANGUL SYLLABLE MYUL
+BBAD;BBAD;1106 1172 11B0;BBAD;1106 1172 11B0; # (뮭; 뮭; 뮭; 뮭; 뮭; ) HANGUL SYLLABLE MYULG
+BBAE;BBAE;1106 1172 11B1;BBAE;1106 1172 11B1; # (뮮; 뮮; 뮮; 뮮; 뮮; ) HANGUL SYLLABLE MYULM
+BBAF;BBAF;1106 1172 11B2;BBAF;1106 1172 11B2; # (뮯; 뮯; 뮯; 뮯; 뮯; ) HANGUL SYLLABLE MYULB
+BBB0;BBB0;1106 1172 11B3;BBB0;1106 1172 11B3; # (뮰; 뮰; 뮰; 뮰; 뮰; ) HANGUL SYLLABLE MYULS
+BBB1;BBB1;1106 1172 11B4;BBB1;1106 1172 11B4; # (뮱; 뮱; 뮱; 뮱; 뮱; ) HANGUL SYLLABLE MYULT
+BBB2;BBB2;1106 1172 11B5;BBB2;1106 1172 11B5; # (뮲; 뮲; 뮲; 뮲; 뮲; ) HANGUL SYLLABLE MYULP
+BBB3;BBB3;1106 1172 11B6;BBB3;1106 1172 11B6; # (뮳; 뮳; 뮳; 뮳; 뮳; ) HANGUL SYLLABLE MYULH
+BBB4;BBB4;1106 1172 11B7;BBB4;1106 1172 11B7; # (뮴; 뮴; 뮴; 뮴; 뮴; ) HANGUL SYLLABLE MYUM
+BBB5;BBB5;1106 1172 11B8;BBB5;1106 1172 11B8; # (뮵; 뮵; 뮵; 뮵; 뮵; ) HANGUL SYLLABLE MYUB
+BBB6;BBB6;1106 1172 11B9;BBB6;1106 1172 11B9; # (뮶; 뮶; 뮶; 뮶; 뮶; ) HANGUL SYLLABLE MYUBS
+BBB7;BBB7;1106 1172 11BA;BBB7;1106 1172 11BA; # (뮷; 뮷; 뮷; 뮷; 뮷; ) HANGUL SYLLABLE MYUS
+BBB8;BBB8;1106 1172 11BB;BBB8;1106 1172 11BB; # (뮸; 뮸; 뮸; 뮸; 뮸; ) HANGUL SYLLABLE MYUSS
+BBB9;BBB9;1106 1172 11BC;BBB9;1106 1172 11BC; # (뮹; 뮹; 뮹; 뮹; 뮹; ) HANGUL SYLLABLE MYUNG
+BBBA;BBBA;1106 1172 11BD;BBBA;1106 1172 11BD; # (뮺; 뮺; 뮺; 뮺; 뮺; ) HANGUL SYLLABLE MYUJ
+BBBB;BBBB;1106 1172 11BE;BBBB;1106 1172 11BE; # (뮻; 뮻; 뮻; 뮻; 뮻; ) HANGUL SYLLABLE MYUC
+BBBC;BBBC;1106 1172 11BF;BBBC;1106 1172 11BF; # (뮼; 뮼; 뮼; 뮼; 뮼; ) HANGUL SYLLABLE MYUK
+BBBD;BBBD;1106 1172 11C0;BBBD;1106 1172 11C0; # (뮽; 뮽; 뮽; 뮽; 뮽; ) HANGUL SYLLABLE MYUT
+BBBE;BBBE;1106 1172 11C1;BBBE;1106 1172 11C1; # (뮾; 뮾; 뮾; 뮾; 뮾; ) HANGUL SYLLABLE MYUP
+BBBF;BBBF;1106 1172 11C2;BBBF;1106 1172 11C2; # (뮿; 뮿; 뮿; 뮿; 뮿; ) HANGUL SYLLABLE MYUH
+BBC0;BBC0;1106 1173;BBC0;1106 1173; # (므; 므; 므; 므; 므; ) HANGUL SYLLABLE MEU
+BBC1;BBC1;1106 1173 11A8;BBC1;1106 1173 11A8; # (믁; 믁; 믁; 믁; 믁; ) HANGUL SYLLABLE MEUG
+BBC2;BBC2;1106 1173 11A9;BBC2;1106 1173 11A9; # (믂; 믂; 믂; 믂; 믂; ) HANGUL SYLLABLE MEUGG
+BBC3;BBC3;1106 1173 11AA;BBC3;1106 1173 11AA; # (믃; 믃; 믃; 믃; 믃; ) HANGUL SYLLABLE MEUGS
+BBC4;BBC4;1106 1173 11AB;BBC4;1106 1173 11AB; # (믄; 믄; 믄; 믄; 믄; ) HANGUL SYLLABLE MEUN
+BBC5;BBC5;1106 1173 11AC;BBC5;1106 1173 11AC; # (믅; 믅; 믅; 믅; 믅; ) HANGUL SYLLABLE MEUNJ
+BBC6;BBC6;1106 1173 11AD;BBC6;1106 1173 11AD; # (믆; 믆; 믆; 믆; 믆; ) HANGUL SYLLABLE MEUNH
+BBC7;BBC7;1106 1173 11AE;BBC7;1106 1173 11AE; # (믇; 믇; 믇; 믇; 믇; ) HANGUL SYLLABLE MEUD
+BBC8;BBC8;1106 1173 11AF;BBC8;1106 1173 11AF; # (믈; 믈; 믈; 믈; 믈; ) HANGUL SYLLABLE MEUL
+BBC9;BBC9;1106 1173 11B0;BBC9;1106 1173 11B0; # (믉; 믉; 믉; 믉; 믉; ) HANGUL SYLLABLE MEULG
+BBCA;BBCA;1106 1173 11B1;BBCA;1106 1173 11B1; # (믊; 믊; 믊; 믊; 믊; ) HANGUL SYLLABLE MEULM
+BBCB;BBCB;1106 1173 11B2;BBCB;1106 1173 11B2; # (믋; 믋; 믋; 믋; 믋; ) HANGUL SYLLABLE MEULB
+BBCC;BBCC;1106 1173 11B3;BBCC;1106 1173 11B3; # (믌; 믌; 믌; 믌; 믌; ) HANGUL SYLLABLE MEULS
+BBCD;BBCD;1106 1173 11B4;BBCD;1106 1173 11B4; # (믍; 믍; 믍; 믍; 믍; ) HANGUL SYLLABLE MEULT
+BBCE;BBCE;1106 1173 11B5;BBCE;1106 1173 11B5; # (믎; 믎; 믎; 믎; 믎; ) HANGUL SYLLABLE MEULP
+BBCF;BBCF;1106 1173 11B6;BBCF;1106 1173 11B6; # (믏; 믏; 믏; 믏; 믏; ) HANGUL SYLLABLE MEULH
+BBD0;BBD0;1106 1173 11B7;BBD0;1106 1173 11B7; # (믐; 믐; 믐; 믐; 믐; ) HANGUL SYLLABLE MEUM
+BBD1;BBD1;1106 1173 11B8;BBD1;1106 1173 11B8; # (믑; 믑; 믑; 믑; 믑; ) HANGUL SYLLABLE MEUB
+BBD2;BBD2;1106 1173 11B9;BBD2;1106 1173 11B9; # (믒; 믒; 믒; 믒; 믒; ) HANGUL SYLLABLE MEUBS
+BBD3;BBD3;1106 1173 11BA;BBD3;1106 1173 11BA; # (믓; 믓; 믓; 믓; 믓; ) HANGUL SYLLABLE MEUS
+BBD4;BBD4;1106 1173 11BB;BBD4;1106 1173 11BB; # (믔; 믔; 믔; 믔; 믔; ) HANGUL SYLLABLE MEUSS
+BBD5;BBD5;1106 1173 11BC;BBD5;1106 1173 11BC; # (믕; 믕; 믕; 믕; 믕; ) HANGUL SYLLABLE MEUNG
+BBD6;BBD6;1106 1173 11BD;BBD6;1106 1173 11BD; # (믖; 믖; 믖; 믖; 믖; ) HANGUL SYLLABLE MEUJ
+BBD7;BBD7;1106 1173 11BE;BBD7;1106 1173 11BE; # (믗; 믗; 믗; 믗; 믗; ) HANGUL SYLLABLE MEUC
+BBD8;BBD8;1106 1173 11BF;BBD8;1106 1173 11BF; # (믘; 믘; 믘; 믘; 믘; ) HANGUL SYLLABLE MEUK
+BBD9;BBD9;1106 1173 11C0;BBD9;1106 1173 11C0; # (믙; 믙; 믙; 믙; 믙; ) HANGUL SYLLABLE MEUT
+BBDA;BBDA;1106 1173 11C1;BBDA;1106 1173 11C1; # (믚; 믚; 믚; 믚; 믚; ) HANGUL SYLLABLE MEUP
+BBDB;BBDB;1106 1173 11C2;BBDB;1106 1173 11C2; # (믛; 믛; 믛; 믛; 믛; ) HANGUL SYLLABLE MEUH
+BBDC;BBDC;1106 1174;BBDC;1106 1174; # (믜; 믜; 믜; 믜; 믜; ) HANGUL SYLLABLE MYI
+BBDD;BBDD;1106 1174 11A8;BBDD;1106 1174 11A8; # (믝; 믝; 믝; 믝; 믝; ) HANGUL SYLLABLE MYIG
+BBDE;BBDE;1106 1174 11A9;BBDE;1106 1174 11A9; # (믞; 믞; 믞; 믞; 믞; ) HANGUL SYLLABLE MYIGG
+BBDF;BBDF;1106 1174 11AA;BBDF;1106 1174 11AA; # (믟; 믟; 믟; 믟; 믟; ) HANGUL SYLLABLE MYIGS
+BBE0;BBE0;1106 1174 11AB;BBE0;1106 1174 11AB; # (믠; 믠; 믠; 믠; 믠; ) HANGUL SYLLABLE MYIN
+BBE1;BBE1;1106 1174 11AC;BBE1;1106 1174 11AC; # (믡; 믡; 믡; 믡; 믡; ) HANGUL SYLLABLE MYINJ
+BBE2;BBE2;1106 1174 11AD;BBE2;1106 1174 11AD; # (믢; 믢; 믢; 믢; 믢; ) HANGUL SYLLABLE MYINH
+BBE3;BBE3;1106 1174 11AE;BBE3;1106 1174 11AE; # (믣; 믣; 믣; 믣; 믣; ) HANGUL SYLLABLE MYID
+BBE4;BBE4;1106 1174 11AF;BBE4;1106 1174 11AF; # (믤; 믤; 믤; 믤; 믤; ) HANGUL SYLLABLE MYIL
+BBE5;BBE5;1106 1174 11B0;BBE5;1106 1174 11B0; # (믥; 믥; 믥; 믥; 믥; ) HANGUL SYLLABLE MYILG
+BBE6;BBE6;1106 1174 11B1;BBE6;1106 1174 11B1; # (믦; 믦; 믦; 믦; 믦; ) HANGUL SYLLABLE MYILM
+BBE7;BBE7;1106 1174 11B2;BBE7;1106 1174 11B2; # (믧; 믧; 믧; 믧; 믧; ) HANGUL SYLLABLE MYILB
+BBE8;BBE8;1106 1174 11B3;BBE8;1106 1174 11B3; # (믨; 믨; 믨; 믨; 믨; ) HANGUL SYLLABLE MYILS
+BBE9;BBE9;1106 1174 11B4;BBE9;1106 1174 11B4; # (믩; 믩; 믩; 믩; 믩; ) HANGUL SYLLABLE MYILT
+BBEA;BBEA;1106 1174 11B5;BBEA;1106 1174 11B5; # (믪; 믪; 믪; 믪; 믪; ) HANGUL SYLLABLE MYILP
+BBEB;BBEB;1106 1174 11B6;BBEB;1106 1174 11B6; # (믫; 믫; 믫; 믫; 믫; ) HANGUL SYLLABLE MYILH
+BBEC;BBEC;1106 1174 11B7;BBEC;1106 1174 11B7; # (믬; 믬; 믬; 믬; 믬; ) HANGUL SYLLABLE MYIM
+BBED;BBED;1106 1174 11B8;BBED;1106 1174 11B8; # (믭; 믭; 믭; 믭; 믭; ) HANGUL SYLLABLE MYIB
+BBEE;BBEE;1106 1174 11B9;BBEE;1106 1174 11B9; # (믮; 믮; 믮; 믮; 믮; ) HANGUL SYLLABLE MYIBS
+BBEF;BBEF;1106 1174 11BA;BBEF;1106 1174 11BA; # (믯; 믯; 믯; 믯; 믯; ) HANGUL SYLLABLE MYIS
+BBF0;BBF0;1106 1174 11BB;BBF0;1106 1174 11BB; # (믰; 믰; 믰; 믰; 믰; ) HANGUL SYLLABLE MYISS
+BBF1;BBF1;1106 1174 11BC;BBF1;1106 1174 11BC; # (믱; 믱; 믱; 믱; 믱; ) HANGUL SYLLABLE MYING
+BBF2;BBF2;1106 1174 11BD;BBF2;1106 1174 11BD; # (믲; 믲; 믲; 믲; 믲; ) HANGUL SYLLABLE MYIJ
+BBF3;BBF3;1106 1174 11BE;BBF3;1106 1174 11BE; # (믳; 믳; 믳; 믳; 믳; ) HANGUL SYLLABLE MYIC
+BBF4;BBF4;1106 1174 11BF;BBF4;1106 1174 11BF; # (믴; 믴; 믴; 믴; 믴; ) HANGUL SYLLABLE MYIK
+BBF5;BBF5;1106 1174 11C0;BBF5;1106 1174 11C0; # (믵; 믵; 믵; 믵; 믵; ) HANGUL SYLLABLE MYIT
+BBF6;BBF6;1106 1174 11C1;BBF6;1106 1174 11C1; # (믶; 믶; 믶; 믶; 믶; ) HANGUL SYLLABLE MYIP
+BBF7;BBF7;1106 1174 11C2;BBF7;1106 1174 11C2; # (믷; 믷; 믷; 믷; 믷; ) HANGUL SYLLABLE MYIH
+BBF8;BBF8;1106 1175;BBF8;1106 1175; # (미; 미; 미; 미; 미; ) HANGUL SYLLABLE MI
+BBF9;BBF9;1106 1175 11A8;BBF9;1106 1175 11A8; # (믹; 믹; 믹; 믹; 믹; ) HANGUL SYLLABLE MIG
+BBFA;BBFA;1106 1175 11A9;BBFA;1106 1175 11A9; # (믺; 믺; 믺; 믺; 믺; ) HANGUL SYLLABLE MIGG
+BBFB;BBFB;1106 1175 11AA;BBFB;1106 1175 11AA; # (믻; 믻; 믻; 믻; 믻; ) HANGUL SYLLABLE MIGS
+BBFC;BBFC;1106 1175 11AB;BBFC;1106 1175 11AB; # (민; 민; 민; 민; 민; ) HANGUL SYLLABLE MIN
+BBFD;BBFD;1106 1175 11AC;BBFD;1106 1175 11AC; # (믽; 믽; 믽; 믽; 믽; ) HANGUL SYLLABLE MINJ
+BBFE;BBFE;1106 1175 11AD;BBFE;1106 1175 11AD; # (믾; 믾; 믾; 믾; 믾; ) HANGUL SYLLABLE MINH
+BBFF;BBFF;1106 1175 11AE;BBFF;1106 1175 11AE; # (믿; 믿; 믿; 믿; 믿; ) HANGUL SYLLABLE MID
+BC00;BC00;1106 1175 11AF;BC00;1106 1175 11AF; # (밀; 밀; 밀; 밀; 밀; ) HANGUL SYLLABLE MIL
+BC01;BC01;1106 1175 11B0;BC01;1106 1175 11B0; # (밁; 밁; 밁; 밁; 밁; ) HANGUL SYLLABLE MILG
+BC02;BC02;1106 1175 11B1;BC02;1106 1175 11B1; # (밂; 밂; 밂; 밂; 밂; ) HANGUL SYLLABLE MILM
+BC03;BC03;1106 1175 11B2;BC03;1106 1175 11B2; # (밃; 밃; 밃; 밃; 밃; ) HANGUL SYLLABLE MILB
+BC04;BC04;1106 1175 11B3;BC04;1106 1175 11B3; # (밄; 밄; 밄; 밄; 밄; ) HANGUL SYLLABLE MILS
+BC05;BC05;1106 1175 11B4;BC05;1106 1175 11B4; # (밅; 밅; 밅; 밅; 밅; ) HANGUL SYLLABLE MILT
+BC06;BC06;1106 1175 11B5;BC06;1106 1175 11B5; # (밆; 밆; 밆; 밆; 밆; ) HANGUL SYLLABLE MILP
+BC07;BC07;1106 1175 11B6;BC07;1106 1175 11B6; # (밇; 밇; 밇; 밇; 밇; ) HANGUL SYLLABLE MILH
+BC08;BC08;1106 1175 11B7;BC08;1106 1175 11B7; # (밈; 밈; 밈; 밈; 밈; ) HANGUL SYLLABLE MIM
+BC09;BC09;1106 1175 11B8;BC09;1106 1175 11B8; # (밉; 밉; 밉; 밉; 밉; ) HANGUL SYLLABLE MIB
+BC0A;BC0A;1106 1175 11B9;BC0A;1106 1175 11B9; # (밊; 밊; 밊; 밊; 밊; ) HANGUL SYLLABLE MIBS
+BC0B;BC0B;1106 1175 11BA;BC0B;1106 1175 11BA; # (밋; 밋; 밋; 밋; 밋; ) HANGUL SYLLABLE MIS
+BC0C;BC0C;1106 1175 11BB;BC0C;1106 1175 11BB; # (밌; 밌; 밌; 밌; 밌; ) HANGUL SYLLABLE MISS
+BC0D;BC0D;1106 1175 11BC;BC0D;1106 1175 11BC; # (밍; 밍; 밍; 밍; 밍; ) HANGUL SYLLABLE MING
+BC0E;BC0E;1106 1175 11BD;BC0E;1106 1175 11BD; # (밎; 밎; 밎; 밎; 밎; ) HANGUL SYLLABLE MIJ
+BC0F;BC0F;1106 1175 11BE;BC0F;1106 1175 11BE; # (및; 및; 및; 및; 및; ) HANGUL SYLLABLE MIC
+BC10;BC10;1106 1175 11BF;BC10;1106 1175 11BF; # (밐; 밐; 밐; 밐; 밐; ) HANGUL SYLLABLE MIK
+BC11;BC11;1106 1175 11C0;BC11;1106 1175 11C0; # (밑; 밑; 밑; 밑; 밑; ) HANGUL SYLLABLE MIT
+BC12;BC12;1106 1175 11C1;BC12;1106 1175 11C1; # (밒; 밒; 밒; 밒; 밒; ) HANGUL SYLLABLE MIP
+BC13;BC13;1106 1175 11C2;BC13;1106 1175 11C2; # (밓; 밓; 밓; 밓; 밓; ) HANGUL SYLLABLE MIH
+BC14;BC14;1107 1161;BC14;1107 1161; # (바; 바; 바; 바; 바; ) HANGUL SYLLABLE BA
+BC15;BC15;1107 1161 11A8;BC15;1107 1161 11A8; # (박; 박; 박; 박; 박; ) HANGUL SYLLABLE BAG
+BC16;BC16;1107 1161 11A9;BC16;1107 1161 11A9; # (밖; 밖; 밖; 밖; 밖; ) HANGUL SYLLABLE BAGG
+BC17;BC17;1107 1161 11AA;BC17;1107 1161 11AA; # (밗; 밗; 밗; 밗; 밗; ) HANGUL SYLLABLE BAGS
+BC18;BC18;1107 1161 11AB;BC18;1107 1161 11AB; # (반; 반; 반; 반; 반; ) HANGUL SYLLABLE BAN
+BC19;BC19;1107 1161 11AC;BC19;1107 1161 11AC; # (밙; 밙; 밙; 밙; 밙; ) HANGUL SYLLABLE BANJ
+BC1A;BC1A;1107 1161 11AD;BC1A;1107 1161 11AD; # (밚; 밚; 밚; 밚; 밚; ) HANGUL SYLLABLE BANH
+BC1B;BC1B;1107 1161 11AE;BC1B;1107 1161 11AE; # (받; 받; 받; 받; 받; ) HANGUL SYLLABLE BAD
+BC1C;BC1C;1107 1161 11AF;BC1C;1107 1161 11AF; # (발; 발; 발; 발; 발; ) HANGUL SYLLABLE BAL
+BC1D;BC1D;1107 1161 11B0;BC1D;1107 1161 11B0; # (밝; 밝; 밝; 밝; 밝; ) HANGUL SYLLABLE BALG
+BC1E;BC1E;1107 1161 11B1;BC1E;1107 1161 11B1; # (밞; 밞; 밞; 밞; 밞; ) HANGUL SYLLABLE BALM
+BC1F;BC1F;1107 1161 11B2;BC1F;1107 1161 11B2; # (밟; 밟; 밟; 밟; 밟; ) HANGUL SYLLABLE BALB
+BC20;BC20;1107 1161 11B3;BC20;1107 1161 11B3; # (밠; 밠; 밠; 밠; 밠; ) HANGUL SYLLABLE BALS
+BC21;BC21;1107 1161 11B4;BC21;1107 1161 11B4; # (밡; 밡; 밡; 밡; 밡; ) HANGUL SYLLABLE BALT
+BC22;BC22;1107 1161 11B5;BC22;1107 1161 11B5; # (밢; 밢; 밢; 밢; 밢; ) HANGUL SYLLABLE BALP
+BC23;BC23;1107 1161 11B6;BC23;1107 1161 11B6; # (밣; 밣; 밣; 밣; 밣; ) HANGUL SYLLABLE BALH
+BC24;BC24;1107 1161 11B7;BC24;1107 1161 11B7; # (밤; 밤; 밤; 밤; 밤; ) HANGUL SYLLABLE BAM
+BC25;BC25;1107 1161 11B8;BC25;1107 1161 11B8; # (밥; 밥; 밥; 밥; 밥; ) HANGUL SYLLABLE BAB
+BC26;BC26;1107 1161 11B9;BC26;1107 1161 11B9; # (밦; 밦; 밦; 밦; 밦; ) HANGUL SYLLABLE BABS
+BC27;BC27;1107 1161 11BA;BC27;1107 1161 11BA; # (밧; 밧; 밧; 밧; 밧; ) HANGUL SYLLABLE BAS
+BC28;BC28;1107 1161 11BB;BC28;1107 1161 11BB; # (밨; 밨; 밨; 밨; 밨; ) HANGUL SYLLABLE BASS
+BC29;BC29;1107 1161 11BC;BC29;1107 1161 11BC; # (방; 방; 방; 방; 방; ) HANGUL SYLLABLE BANG
+BC2A;BC2A;1107 1161 11BD;BC2A;1107 1161 11BD; # (밪; 밪; 밪; 밪; 밪; ) HANGUL SYLLABLE BAJ
+BC2B;BC2B;1107 1161 11BE;BC2B;1107 1161 11BE; # (밫; 밫; 밫; 밫; 밫; ) HANGUL SYLLABLE BAC
+BC2C;BC2C;1107 1161 11BF;BC2C;1107 1161 11BF; # (밬; 밬; 밬; 밬; 밬; ) HANGUL SYLLABLE BAK
+BC2D;BC2D;1107 1161 11C0;BC2D;1107 1161 11C0; # (밭; 밭; 밭; 밭; 밭; ) HANGUL SYLLABLE BAT
+BC2E;BC2E;1107 1161 11C1;BC2E;1107 1161 11C1; # (밮; 밮; 밮; 밮; 밮; ) HANGUL SYLLABLE BAP
+BC2F;BC2F;1107 1161 11C2;BC2F;1107 1161 11C2; # (밯; 밯; 밯; 밯; 밯; ) HANGUL SYLLABLE BAH
+BC30;BC30;1107 1162;BC30;1107 1162; # (배; 배; 배; 배; 배; ) HANGUL SYLLABLE BAE
+BC31;BC31;1107 1162 11A8;BC31;1107 1162 11A8; # (백; 백; 백; 백; 백; ) HANGUL SYLLABLE BAEG
+BC32;BC32;1107 1162 11A9;BC32;1107 1162 11A9; # (밲; 밲; 밲; 밲; 밲; ) HANGUL SYLLABLE BAEGG
+BC33;BC33;1107 1162 11AA;BC33;1107 1162 11AA; # (밳; 밳; 밳; 밳; 밳; ) HANGUL SYLLABLE BAEGS
+BC34;BC34;1107 1162 11AB;BC34;1107 1162 11AB; # (밴; 밴; 밴; 밴; 밴; ) HANGUL SYLLABLE BAEN
+BC35;BC35;1107 1162 11AC;BC35;1107 1162 11AC; # (밵; 밵; 밵; 밵; 밵; ) HANGUL SYLLABLE BAENJ
+BC36;BC36;1107 1162 11AD;BC36;1107 1162 11AD; # (밶; 밶; 밶; 밶; 밶; ) HANGUL SYLLABLE BAENH
+BC37;BC37;1107 1162 11AE;BC37;1107 1162 11AE; # (밷; 밷; 밷; 밷; 밷; ) HANGUL SYLLABLE BAED
+BC38;BC38;1107 1162 11AF;BC38;1107 1162 11AF; # (밸; 밸; 밸; 밸; 밸; ) HANGUL SYLLABLE BAEL
+BC39;BC39;1107 1162 11B0;BC39;1107 1162 11B0; # (밹; 밹; 밹; 밹; 밹; ) HANGUL SYLLABLE BAELG
+BC3A;BC3A;1107 1162 11B1;BC3A;1107 1162 11B1; # (밺; 밺; 밺; 밺; 밺; ) HANGUL SYLLABLE BAELM
+BC3B;BC3B;1107 1162 11B2;BC3B;1107 1162 11B2; # (밻; 밻; 밻; 밻; 밻; ) HANGUL SYLLABLE BAELB
+BC3C;BC3C;1107 1162 11B3;BC3C;1107 1162 11B3; # (밼; 밼; 밼; 밼; 밼; ) HANGUL SYLLABLE BAELS
+BC3D;BC3D;1107 1162 11B4;BC3D;1107 1162 11B4; # (밽; 밽; 밽; 밽; 밽; ) HANGUL SYLLABLE BAELT
+BC3E;BC3E;1107 1162 11B5;BC3E;1107 1162 11B5; # (밾; 밾; 밾; 밾; 밾; ) HANGUL SYLLABLE BAELP
+BC3F;BC3F;1107 1162 11B6;BC3F;1107 1162 11B6; # (밿; 밿; 밿; 밿; 밿; ) HANGUL SYLLABLE BAELH
+BC40;BC40;1107 1162 11B7;BC40;1107 1162 11B7; # (뱀; 뱀; 뱀; 뱀; 뱀; ) HANGUL SYLLABLE BAEM
+BC41;BC41;1107 1162 11B8;BC41;1107 1162 11B8; # (뱁; 뱁; 뱁; 뱁; 뱁; ) HANGUL SYLLABLE BAEB
+BC42;BC42;1107 1162 11B9;BC42;1107 1162 11B9; # (뱂; 뱂; 뱂; 뱂; 뱂; ) HANGUL SYLLABLE BAEBS
+BC43;BC43;1107 1162 11BA;BC43;1107 1162 11BA; # (뱃; 뱃; 뱃; 뱃; 뱃; ) HANGUL SYLLABLE BAES
+BC44;BC44;1107 1162 11BB;BC44;1107 1162 11BB; # (뱄; 뱄; 뱄; 뱄; 뱄; ) HANGUL SYLLABLE BAESS
+BC45;BC45;1107 1162 11BC;BC45;1107 1162 11BC; # (뱅; 뱅; 뱅; 뱅; 뱅; ) HANGUL SYLLABLE BAENG
+BC46;BC46;1107 1162 11BD;BC46;1107 1162 11BD; # (뱆; 뱆; 뱆; 뱆; 뱆; ) HANGUL SYLLABLE BAEJ
+BC47;BC47;1107 1162 11BE;BC47;1107 1162 11BE; # (뱇; 뱇; 뱇; 뱇; 뱇; ) HANGUL SYLLABLE BAEC
+BC48;BC48;1107 1162 11BF;BC48;1107 1162 11BF; # (뱈; 뱈; 뱈; 뱈; 뱈; ) HANGUL SYLLABLE BAEK
+BC49;BC49;1107 1162 11C0;BC49;1107 1162 11C0; # (뱉; 뱉; 뱉; 뱉; 뱉; ) HANGUL SYLLABLE BAET
+BC4A;BC4A;1107 1162 11C1;BC4A;1107 1162 11C1; # (뱊; 뱊; 뱊; 뱊; 뱊; ) HANGUL SYLLABLE BAEP
+BC4B;BC4B;1107 1162 11C2;BC4B;1107 1162 11C2; # (뱋; 뱋; 뱋; 뱋; 뱋; ) HANGUL SYLLABLE BAEH
+BC4C;BC4C;1107 1163;BC4C;1107 1163; # (뱌; 뱌; 뱌; 뱌; 뱌; ) HANGUL SYLLABLE BYA
+BC4D;BC4D;1107 1163 11A8;BC4D;1107 1163 11A8; # (뱍; 뱍; 뱍; 뱍; 뱍; ) HANGUL SYLLABLE BYAG
+BC4E;BC4E;1107 1163 11A9;BC4E;1107 1163 11A9; # (뱎; 뱎; 뱎; 뱎; 뱎; ) HANGUL SYLLABLE BYAGG
+BC4F;BC4F;1107 1163 11AA;BC4F;1107 1163 11AA; # (뱏; 뱏; 뱏; 뱏; 뱏; ) HANGUL SYLLABLE BYAGS
+BC50;BC50;1107 1163 11AB;BC50;1107 1163 11AB; # (뱐; 뱐; 뱐; 뱐; 뱐; ) HANGUL SYLLABLE BYAN
+BC51;BC51;1107 1163 11AC;BC51;1107 1163 11AC; # (뱑; 뱑; 뱑; 뱑; 뱑; ) HANGUL SYLLABLE BYANJ
+BC52;BC52;1107 1163 11AD;BC52;1107 1163 11AD; # (뱒; 뱒; 뱒; 뱒; 뱒; ) HANGUL SYLLABLE BYANH
+BC53;BC53;1107 1163 11AE;BC53;1107 1163 11AE; # (뱓; 뱓; 뱓; 뱓; 뱓; ) HANGUL SYLLABLE BYAD
+BC54;BC54;1107 1163 11AF;BC54;1107 1163 11AF; # (뱔; 뱔; 뱔; 뱔; 뱔; ) HANGUL SYLLABLE BYAL
+BC55;BC55;1107 1163 11B0;BC55;1107 1163 11B0; # (뱕; 뱕; 뱕; 뱕; 뱕; ) HANGUL SYLLABLE BYALG
+BC56;BC56;1107 1163 11B1;BC56;1107 1163 11B1; # (뱖; 뱖; 뱖; 뱖; 뱖; ) HANGUL SYLLABLE BYALM
+BC57;BC57;1107 1163 11B2;BC57;1107 1163 11B2; # (뱗; 뱗; 뱗; 뱗; 뱗; ) HANGUL SYLLABLE BYALB
+BC58;BC58;1107 1163 11B3;BC58;1107 1163 11B3; # (뱘; 뱘; 뱘; 뱘; 뱘; ) HANGUL SYLLABLE BYALS
+BC59;BC59;1107 1163 11B4;BC59;1107 1163 11B4; # (뱙; 뱙; 뱙; 뱙; 뱙; ) HANGUL SYLLABLE BYALT
+BC5A;BC5A;1107 1163 11B5;BC5A;1107 1163 11B5; # (뱚; 뱚; 뱚; 뱚; 뱚; ) HANGUL SYLLABLE BYALP
+BC5B;BC5B;1107 1163 11B6;BC5B;1107 1163 11B6; # (뱛; 뱛; 뱛; 뱛; 뱛; ) HANGUL SYLLABLE BYALH
+BC5C;BC5C;1107 1163 11B7;BC5C;1107 1163 11B7; # (뱜; 뱜; 뱜; 뱜; 뱜; ) HANGUL SYLLABLE BYAM
+BC5D;BC5D;1107 1163 11B8;BC5D;1107 1163 11B8; # (뱝; 뱝; 뱝; 뱝; 뱝; ) HANGUL SYLLABLE BYAB
+BC5E;BC5E;1107 1163 11B9;BC5E;1107 1163 11B9; # (뱞; 뱞; 뱞; 뱞; 뱞; ) HANGUL SYLLABLE BYABS
+BC5F;BC5F;1107 1163 11BA;BC5F;1107 1163 11BA; # (뱟; 뱟; 뱟; 뱟; 뱟; ) HANGUL SYLLABLE BYAS
+BC60;BC60;1107 1163 11BB;BC60;1107 1163 11BB; # (뱠; 뱠; 뱠; 뱠; 뱠; ) HANGUL SYLLABLE BYASS
+BC61;BC61;1107 1163 11BC;BC61;1107 1163 11BC; # (뱡; 뱡; 뱡; 뱡; 뱡; ) HANGUL SYLLABLE BYANG
+BC62;BC62;1107 1163 11BD;BC62;1107 1163 11BD; # (뱢; 뱢; 뱢; 뱢; 뱢; ) HANGUL SYLLABLE BYAJ
+BC63;BC63;1107 1163 11BE;BC63;1107 1163 11BE; # (뱣; 뱣; 뱣; 뱣; 뱣; ) HANGUL SYLLABLE BYAC
+BC64;BC64;1107 1163 11BF;BC64;1107 1163 11BF; # (뱤; 뱤; 뱤; 뱤; 뱤; ) HANGUL SYLLABLE BYAK
+BC65;BC65;1107 1163 11C0;BC65;1107 1163 11C0; # (뱥; 뱥; 뱥; 뱥; 뱥; ) HANGUL SYLLABLE BYAT
+BC66;BC66;1107 1163 11C1;BC66;1107 1163 11C1; # (뱦; 뱦; 뱦; 뱦; 뱦; ) HANGUL SYLLABLE BYAP
+BC67;BC67;1107 1163 11C2;BC67;1107 1163 11C2; # (뱧; 뱧; 뱧; 뱧; 뱧; ) HANGUL SYLLABLE BYAH
+BC68;BC68;1107 1164;BC68;1107 1164; # (뱨; 뱨; 뱨; 뱨; 뱨; ) HANGUL SYLLABLE BYAE
+BC69;BC69;1107 1164 11A8;BC69;1107 1164 11A8; # (뱩; 뱩; 뱩; 뱩; 뱩; ) HANGUL SYLLABLE BYAEG
+BC6A;BC6A;1107 1164 11A9;BC6A;1107 1164 11A9; # (뱪; 뱪; 뱪; 뱪; 뱪; ) HANGUL SYLLABLE BYAEGG
+BC6B;BC6B;1107 1164 11AA;BC6B;1107 1164 11AA; # (뱫; 뱫; 뱫; 뱫; 뱫; ) HANGUL SYLLABLE BYAEGS
+BC6C;BC6C;1107 1164 11AB;BC6C;1107 1164 11AB; # (뱬; 뱬; 뱬; 뱬; 뱬; ) HANGUL SYLLABLE BYAEN
+BC6D;BC6D;1107 1164 11AC;BC6D;1107 1164 11AC; # (뱭; 뱭; 뱭; 뱭; 뱭; ) HANGUL SYLLABLE BYAENJ
+BC6E;BC6E;1107 1164 11AD;BC6E;1107 1164 11AD; # (뱮; 뱮; 뱮; 뱮; 뱮; ) HANGUL SYLLABLE BYAENH
+BC6F;BC6F;1107 1164 11AE;BC6F;1107 1164 11AE; # (뱯; 뱯; 뱯; 뱯; 뱯; ) HANGUL SYLLABLE BYAED
+BC70;BC70;1107 1164 11AF;BC70;1107 1164 11AF; # (뱰; 뱰; 뱰; 뱰; 뱰; ) HANGUL SYLLABLE BYAEL
+BC71;BC71;1107 1164 11B0;BC71;1107 1164 11B0; # (뱱; 뱱; 뱱; 뱱; 뱱; ) HANGUL SYLLABLE BYAELG
+BC72;BC72;1107 1164 11B1;BC72;1107 1164 11B1; # (뱲; 뱲; 뱲; 뱲; 뱲; ) HANGUL SYLLABLE BYAELM
+BC73;BC73;1107 1164 11B2;BC73;1107 1164 11B2; # (뱳; 뱳; 뱳; 뱳; 뱳; ) HANGUL SYLLABLE BYAELB
+BC74;BC74;1107 1164 11B3;BC74;1107 1164 11B3; # (뱴; 뱴; 뱴; 뱴; 뱴; ) HANGUL SYLLABLE BYAELS
+BC75;BC75;1107 1164 11B4;BC75;1107 1164 11B4; # (뱵; 뱵; 뱵; 뱵; 뱵; ) HANGUL SYLLABLE BYAELT
+BC76;BC76;1107 1164 11B5;BC76;1107 1164 11B5; # (뱶; 뱶; 뱶; 뱶; 뱶; ) HANGUL SYLLABLE BYAELP
+BC77;BC77;1107 1164 11B6;BC77;1107 1164 11B6; # (뱷; 뱷; 뱷; 뱷; 뱷; ) HANGUL SYLLABLE BYAELH
+BC78;BC78;1107 1164 11B7;BC78;1107 1164 11B7; # (뱸; 뱸; 뱸; 뱸; 뱸; ) HANGUL SYLLABLE BYAEM
+BC79;BC79;1107 1164 11B8;BC79;1107 1164 11B8; # (뱹; 뱹; 뱹; 뱹; 뱹; ) HANGUL SYLLABLE BYAEB
+BC7A;BC7A;1107 1164 11B9;BC7A;1107 1164 11B9; # (뱺; 뱺; 뱺; 뱺; 뱺; ) HANGUL SYLLABLE BYAEBS
+BC7B;BC7B;1107 1164 11BA;BC7B;1107 1164 11BA; # (뱻; 뱻; 뱻; 뱻; 뱻; ) HANGUL SYLLABLE BYAES
+BC7C;BC7C;1107 1164 11BB;BC7C;1107 1164 11BB; # (뱼; 뱼; 뱼; 뱼; 뱼; ) HANGUL SYLLABLE BYAESS
+BC7D;BC7D;1107 1164 11BC;BC7D;1107 1164 11BC; # (뱽; 뱽; 뱽; 뱽; 뱽; ) HANGUL SYLLABLE BYAENG
+BC7E;BC7E;1107 1164 11BD;BC7E;1107 1164 11BD; # (뱾; 뱾; 뱾; 뱾; 뱾; ) HANGUL SYLLABLE BYAEJ
+BC7F;BC7F;1107 1164 11BE;BC7F;1107 1164 11BE; # (뱿; 뱿; 뱿; 뱿; 뱿; ) HANGUL SYLLABLE BYAEC
+BC80;BC80;1107 1164 11BF;BC80;1107 1164 11BF; # (벀; 벀; 벀; 벀; 벀; ) HANGUL SYLLABLE BYAEK
+BC81;BC81;1107 1164 11C0;BC81;1107 1164 11C0; # (벁; 벁; 벁; 벁; 벁; ) HANGUL SYLLABLE BYAET
+BC82;BC82;1107 1164 11C1;BC82;1107 1164 11C1; # (벂; 벂; 벂; 벂; 벂; ) HANGUL SYLLABLE BYAEP
+BC83;BC83;1107 1164 11C2;BC83;1107 1164 11C2; # (벃; 벃; 벃; 벃; 벃; ) HANGUL SYLLABLE BYAEH
+BC84;BC84;1107 1165;BC84;1107 1165; # (버; 버; 버; 버; 버; ) HANGUL SYLLABLE BEO
+BC85;BC85;1107 1165 11A8;BC85;1107 1165 11A8; # (벅; 벅; 벅; 벅; 벅; ) HANGUL SYLLABLE BEOG
+BC86;BC86;1107 1165 11A9;BC86;1107 1165 11A9; # (벆; 벆; 벆; 벆; 벆; ) HANGUL SYLLABLE BEOGG
+BC87;BC87;1107 1165 11AA;BC87;1107 1165 11AA; # (벇; 벇; 벇; 벇; 벇; ) HANGUL SYLLABLE BEOGS
+BC88;BC88;1107 1165 11AB;BC88;1107 1165 11AB; # (번; 번; 번; 번; 번; ) HANGUL SYLLABLE BEON
+BC89;BC89;1107 1165 11AC;BC89;1107 1165 11AC; # (벉; 벉; 벉; 벉; 벉; ) HANGUL SYLLABLE BEONJ
+BC8A;BC8A;1107 1165 11AD;BC8A;1107 1165 11AD; # (벊; 벊; 벊; 벊; 벊; ) HANGUL SYLLABLE BEONH
+BC8B;BC8B;1107 1165 11AE;BC8B;1107 1165 11AE; # (벋; 벋; 벋; 벋; 벋; ) HANGUL SYLLABLE BEOD
+BC8C;BC8C;1107 1165 11AF;BC8C;1107 1165 11AF; # (벌; 벌; 벌; 벌; 벌; ) HANGUL SYLLABLE BEOL
+BC8D;BC8D;1107 1165 11B0;BC8D;1107 1165 11B0; # (벍; 벍; 벍; 벍; 벍; ) HANGUL SYLLABLE BEOLG
+BC8E;BC8E;1107 1165 11B1;BC8E;1107 1165 11B1; # (벎; 벎; 벎; 벎; 벎; ) HANGUL SYLLABLE BEOLM
+BC8F;BC8F;1107 1165 11B2;BC8F;1107 1165 11B2; # (벏; 벏; 벏; 벏; 벏; ) HANGUL SYLLABLE BEOLB
+BC90;BC90;1107 1165 11B3;BC90;1107 1165 11B3; # (벐; 벐; 벐; 벐; 벐; ) HANGUL SYLLABLE BEOLS
+BC91;BC91;1107 1165 11B4;BC91;1107 1165 11B4; # (벑; 벑; 벑; 벑; 벑; ) HANGUL SYLLABLE BEOLT
+BC92;BC92;1107 1165 11B5;BC92;1107 1165 11B5; # (벒; 벒; 벒; 벒; 벒; ) HANGUL SYLLABLE BEOLP
+BC93;BC93;1107 1165 11B6;BC93;1107 1165 11B6; # (벓; 벓; 벓; 벓; 벓; ) HANGUL SYLLABLE BEOLH
+BC94;BC94;1107 1165 11B7;BC94;1107 1165 11B7; # (범; 범; 범; 범; 범; ) HANGUL SYLLABLE BEOM
+BC95;BC95;1107 1165 11B8;BC95;1107 1165 11B8; # (법; 법; 법; 법; 법; ) HANGUL SYLLABLE BEOB
+BC96;BC96;1107 1165 11B9;BC96;1107 1165 11B9; # (벖; 벖; 벖; 벖; 벖; ) HANGUL SYLLABLE BEOBS
+BC97;BC97;1107 1165 11BA;BC97;1107 1165 11BA; # (벗; 벗; 벗; 벗; 벗; ) HANGUL SYLLABLE BEOS
+BC98;BC98;1107 1165 11BB;BC98;1107 1165 11BB; # (벘; 벘; 벘; 벘; 벘; ) HANGUL SYLLABLE BEOSS
+BC99;BC99;1107 1165 11BC;BC99;1107 1165 11BC; # (벙; 벙; 벙; 벙; 벙; ) HANGUL SYLLABLE BEONG
+BC9A;BC9A;1107 1165 11BD;BC9A;1107 1165 11BD; # (벚; 벚; 벚; 벚; 벚; ) HANGUL SYLLABLE BEOJ
+BC9B;BC9B;1107 1165 11BE;BC9B;1107 1165 11BE; # (벛; 벛; 벛; 벛; 벛; ) HANGUL SYLLABLE BEOC
+BC9C;BC9C;1107 1165 11BF;BC9C;1107 1165 11BF; # (벜; 벜; 벜; 벜; 벜; ) HANGUL SYLLABLE BEOK
+BC9D;BC9D;1107 1165 11C0;BC9D;1107 1165 11C0; # (벝; 벝; 벝; 벝; 벝; ) HANGUL SYLLABLE BEOT
+BC9E;BC9E;1107 1165 11C1;BC9E;1107 1165 11C1; # (벞; 벞; 벞; 벞; 벞; ) HANGUL SYLLABLE BEOP
+BC9F;BC9F;1107 1165 11C2;BC9F;1107 1165 11C2; # (벟; 벟; 벟; 벟; 벟; ) HANGUL SYLLABLE BEOH
+BCA0;BCA0;1107 1166;BCA0;1107 1166; # (베; 베; 베; 베; 베; ) HANGUL SYLLABLE BE
+BCA1;BCA1;1107 1166 11A8;BCA1;1107 1166 11A8; # (벡; 벡; 벡; 벡; 벡; ) HANGUL SYLLABLE BEG
+BCA2;BCA2;1107 1166 11A9;BCA2;1107 1166 11A9; # (벢; 벢; 벢; 벢; 벢; ) HANGUL SYLLABLE BEGG
+BCA3;BCA3;1107 1166 11AA;BCA3;1107 1166 11AA; # (벣; 벣; 벣; 벣; 벣; ) HANGUL SYLLABLE BEGS
+BCA4;BCA4;1107 1166 11AB;BCA4;1107 1166 11AB; # (벤; 벤; 벤; 벤; 벤; ) HANGUL SYLLABLE BEN
+BCA5;BCA5;1107 1166 11AC;BCA5;1107 1166 11AC; # (벥; 벥; 벥; 벥; 벥; ) HANGUL SYLLABLE BENJ
+BCA6;BCA6;1107 1166 11AD;BCA6;1107 1166 11AD; # (벦; 벦; 벦; 벦; 벦; ) HANGUL SYLLABLE BENH
+BCA7;BCA7;1107 1166 11AE;BCA7;1107 1166 11AE; # (벧; 벧; 벧; 벧; 벧; ) HANGUL SYLLABLE BED
+BCA8;BCA8;1107 1166 11AF;BCA8;1107 1166 11AF; # (벨; 벨; 벨; 벨; 벨; ) HANGUL SYLLABLE BEL
+BCA9;BCA9;1107 1166 11B0;BCA9;1107 1166 11B0; # (벩; 벩; 벩; 벩; 벩; ) HANGUL SYLLABLE BELG
+BCAA;BCAA;1107 1166 11B1;BCAA;1107 1166 11B1; # (벪; 벪; 벪; 벪; 벪; ) HANGUL SYLLABLE BELM
+BCAB;BCAB;1107 1166 11B2;BCAB;1107 1166 11B2; # (벫; 벫; 벫; 벫; 벫; ) HANGUL SYLLABLE BELB
+BCAC;BCAC;1107 1166 11B3;BCAC;1107 1166 11B3; # (벬; 벬; 벬; 벬; 벬; ) HANGUL SYLLABLE BELS
+BCAD;BCAD;1107 1166 11B4;BCAD;1107 1166 11B4; # (벭; 벭; 벭; 벭; 벭; ) HANGUL SYLLABLE BELT
+BCAE;BCAE;1107 1166 11B5;BCAE;1107 1166 11B5; # (벮; 벮; 벮; 벮; 벮; ) HANGUL SYLLABLE BELP
+BCAF;BCAF;1107 1166 11B6;BCAF;1107 1166 11B6; # (벯; 벯; 벯; 벯; 벯; ) HANGUL SYLLABLE BELH
+BCB0;BCB0;1107 1166 11B7;BCB0;1107 1166 11B7; # (벰; 벰; 벰; 벰; 벰; ) HANGUL SYLLABLE BEM
+BCB1;BCB1;1107 1166 11B8;BCB1;1107 1166 11B8; # (벱; 벱; 벱; 벱; 벱; ) HANGUL SYLLABLE BEB
+BCB2;BCB2;1107 1166 11B9;BCB2;1107 1166 11B9; # (벲; 벲; 벲; 벲; 벲; ) HANGUL SYLLABLE BEBS
+BCB3;BCB3;1107 1166 11BA;BCB3;1107 1166 11BA; # (벳; 벳; 벳; 벳; 벳; ) HANGUL SYLLABLE BES
+BCB4;BCB4;1107 1166 11BB;BCB4;1107 1166 11BB; # (벴; 벴; 벴; 벴; 벴; ) HANGUL SYLLABLE BESS
+BCB5;BCB5;1107 1166 11BC;BCB5;1107 1166 11BC; # (벵; 벵; 벵; 벵; 벵; ) HANGUL SYLLABLE BENG
+BCB6;BCB6;1107 1166 11BD;BCB6;1107 1166 11BD; # (벶; 벶; 벶; 벶; 벶; ) HANGUL SYLLABLE BEJ
+BCB7;BCB7;1107 1166 11BE;BCB7;1107 1166 11BE; # (벷; 벷; 벷; 벷; 벷; ) HANGUL SYLLABLE BEC
+BCB8;BCB8;1107 1166 11BF;BCB8;1107 1166 11BF; # (벸; 벸; 벸; 벸; 벸; ) HANGUL SYLLABLE BEK
+BCB9;BCB9;1107 1166 11C0;BCB9;1107 1166 11C0; # (벹; 벹; 벹; 벹; 벹; ) HANGUL SYLLABLE BET
+BCBA;BCBA;1107 1166 11C1;BCBA;1107 1166 11C1; # (벺; 벺; 벺; 벺; 벺; ) HANGUL SYLLABLE BEP
+BCBB;BCBB;1107 1166 11C2;BCBB;1107 1166 11C2; # (벻; 벻; 벻; 벻; 벻; ) HANGUL SYLLABLE BEH
+BCBC;BCBC;1107 1167;BCBC;1107 1167; # (벼; 벼; 벼; 벼; 벼; ) HANGUL SYLLABLE BYEO
+BCBD;BCBD;1107 1167 11A8;BCBD;1107 1167 11A8; # (벽; 벽; 벽; 벽; 벽; ) HANGUL SYLLABLE BYEOG
+BCBE;BCBE;1107 1167 11A9;BCBE;1107 1167 11A9; # (벾; 벾; 벾; 벾; 벾; ) HANGUL SYLLABLE BYEOGG
+BCBF;BCBF;1107 1167 11AA;BCBF;1107 1167 11AA; # (벿; 벿; 벿; 벿; 벿; ) HANGUL SYLLABLE BYEOGS
+BCC0;BCC0;1107 1167 11AB;BCC0;1107 1167 11AB; # (변; 변; 변; 변; 변; ) HANGUL SYLLABLE BYEON
+BCC1;BCC1;1107 1167 11AC;BCC1;1107 1167 11AC; # (볁; 볁; 볁; 볁; 볁; ) HANGUL SYLLABLE BYEONJ
+BCC2;BCC2;1107 1167 11AD;BCC2;1107 1167 11AD; # (볂; 볂; 볂; 볂; 볂; ) HANGUL SYLLABLE BYEONH
+BCC3;BCC3;1107 1167 11AE;BCC3;1107 1167 11AE; # (볃; 볃; 볃; 볃; 볃; ) HANGUL SYLLABLE BYEOD
+BCC4;BCC4;1107 1167 11AF;BCC4;1107 1167 11AF; # (별; 별; 별; 별; 별; ) HANGUL SYLLABLE BYEOL
+BCC5;BCC5;1107 1167 11B0;BCC5;1107 1167 11B0; # (볅; 볅; 볅; 볅; 볅; ) HANGUL SYLLABLE BYEOLG
+BCC6;BCC6;1107 1167 11B1;BCC6;1107 1167 11B1; # (볆; 볆; 볆; 볆; 볆; ) HANGUL SYLLABLE BYEOLM
+BCC7;BCC7;1107 1167 11B2;BCC7;1107 1167 11B2; # (볇; 볇; 볇; 볇; 볇; ) HANGUL SYLLABLE BYEOLB
+BCC8;BCC8;1107 1167 11B3;BCC8;1107 1167 11B3; # (볈; 볈; 볈; 볈; 볈; ) HANGUL SYLLABLE BYEOLS
+BCC9;BCC9;1107 1167 11B4;BCC9;1107 1167 11B4; # (볉; 볉; 볉; 볉; 볉; ) HANGUL SYLLABLE BYEOLT
+BCCA;BCCA;1107 1167 11B5;BCCA;1107 1167 11B5; # (볊; 볊; 볊; 볊; 볊; ) HANGUL SYLLABLE BYEOLP
+BCCB;BCCB;1107 1167 11B6;BCCB;1107 1167 11B6; # (볋; 볋; 볋; 볋; 볋; ) HANGUL SYLLABLE BYEOLH
+BCCC;BCCC;1107 1167 11B7;BCCC;1107 1167 11B7; # (볌; 볌; 볌; 볌; 볌; ) HANGUL SYLLABLE BYEOM
+BCCD;BCCD;1107 1167 11B8;BCCD;1107 1167 11B8; # (볍; 볍; 볍; 볍; 볍; ) HANGUL SYLLABLE BYEOB
+BCCE;BCCE;1107 1167 11B9;BCCE;1107 1167 11B9; # (볎; 볎; 볎; 볎; 볎; ) HANGUL SYLLABLE BYEOBS
+BCCF;BCCF;1107 1167 11BA;BCCF;1107 1167 11BA; # (볏; 볏; 볏; 볏; 볏; ) HANGUL SYLLABLE BYEOS
+BCD0;BCD0;1107 1167 11BB;BCD0;1107 1167 11BB; # (볐; 볐; 볐; 볐; 볐; ) HANGUL SYLLABLE BYEOSS
+BCD1;BCD1;1107 1167 11BC;BCD1;1107 1167 11BC; # (병; 병; 병; 병; 병; ) HANGUL SYLLABLE BYEONG
+BCD2;BCD2;1107 1167 11BD;BCD2;1107 1167 11BD; # (볒; 볒; 볒; 볒; 볒; ) HANGUL SYLLABLE BYEOJ
+BCD3;BCD3;1107 1167 11BE;BCD3;1107 1167 11BE; # (볓; 볓; 볓; 볓; 볓; ) HANGUL SYLLABLE BYEOC
+BCD4;BCD4;1107 1167 11BF;BCD4;1107 1167 11BF; # (볔; 볔; 볔; 볔; 볔; ) HANGUL SYLLABLE BYEOK
+BCD5;BCD5;1107 1167 11C0;BCD5;1107 1167 11C0; # (볕; 볕; 볕; 볕; 볕; ) HANGUL SYLLABLE BYEOT
+BCD6;BCD6;1107 1167 11C1;BCD6;1107 1167 11C1; # (볖; 볖; 볖; 볖; 볖; ) HANGUL SYLLABLE BYEOP
+BCD7;BCD7;1107 1167 11C2;BCD7;1107 1167 11C2; # (볗; 볗; 볗; 볗; 볗; ) HANGUL SYLLABLE BYEOH
+BCD8;BCD8;1107 1168;BCD8;1107 1168; # (볘; 볘; 볘; 볘; 볘; ) HANGUL SYLLABLE BYE
+BCD9;BCD9;1107 1168 11A8;BCD9;1107 1168 11A8; # (볙; 볙; 볙; 볙; 볙; ) HANGUL SYLLABLE BYEG
+BCDA;BCDA;1107 1168 11A9;BCDA;1107 1168 11A9; # (볚; 볚; 볚; 볚; 볚; ) HANGUL SYLLABLE BYEGG
+BCDB;BCDB;1107 1168 11AA;BCDB;1107 1168 11AA; # (볛; 볛; 볛; 볛; 볛; ) HANGUL SYLLABLE BYEGS
+BCDC;BCDC;1107 1168 11AB;BCDC;1107 1168 11AB; # (볜; 볜; 볜; 볜; 볜; ) HANGUL SYLLABLE BYEN
+BCDD;BCDD;1107 1168 11AC;BCDD;1107 1168 11AC; # (볝; 볝; 볝; 볝; 볝; ) HANGUL SYLLABLE BYENJ
+BCDE;BCDE;1107 1168 11AD;BCDE;1107 1168 11AD; # (볞; 볞; 볞; 볞; 볞; ) HANGUL SYLLABLE BYENH
+BCDF;BCDF;1107 1168 11AE;BCDF;1107 1168 11AE; # (볟; 볟; 볟; 볟; 볟; ) HANGUL SYLLABLE BYED
+BCE0;BCE0;1107 1168 11AF;BCE0;1107 1168 11AF; # (볠; 볠; 볠; 볠; 볠; ) HANGUL SYLLABLE BYEL
+BCE1;BCE1;1107 1168 11B0;BCE1;1107 1168 11B0; # (볡; 볡; 볡; 볡; 볡; ) HANGUL SYLLABLE BYELG
+BCE2;BCE2;1107 1168 11B1;BCE2;1107 1168 11B1; # (볢; 볢; 볢; 볢; 볢; ) HANGUL SYLLABLE BYELM
+BCE3;BCE3;1107 1168 11B2;BCE3;1107 1168 11B2; # (볣; 볣; 볣; 볣; 볣; ) HANGUL SYLLABLE BYELB
+BCE4;BCE4;1107 1168 11B3;BCE4;1107 1168 11B3; # (볤; 볤; 볤; 볤; 볤; ) HANGUL SYLLABLE BYELS
+BCE5;BCE5;1107 1168 11B4;BCE5;1107 1168 11B4; # (볥; 볥; 볥; 볥; 볥; ) HANGUL SYLLABLE BYELT
+BCE6;BCE6;1107 1168 11B5;BCE6;1107 1168 11B5; # (볦; 볦; 볦; 볦; 볦; ) HANGUL SYLLABLE BYELP
+BCE7;BCE7;1107 1168 11B6;BCE7;1107 1168 11B6; # (볧; 볧; 볧; 볧; 볧; ) HANGUL SYLLABLE BYELH
+BCE8;BCE8;1107 1168 11B7;BCE8;1107 1168 11B7; # (볨; 볨; 볨; 볨; 볨; ) HANGUL SYLLABLE BYEM
+BCE9;BCE9;1107 1168 11B8;BCE9;1107 1168 11B8; # (볩; 볩; 볩; 볩; 볩; ) HANGUL SYLLABLE BYEB
+BCEA;BCEA;1107 1168 11B9;BCEA;1107 1168 11B9; # (볪; 볪; 볪; 볪; 볪; ) HANGUL SYLLABLE BYEBS
+BCEB;BCEB;1107 1168 11BA;BCEB;1107 1168 11BA; # (볫; 볫; 볫; 볫; 볫; ) HANGUL SYLLABLE BYES
+BCEC;BCEC;1107 1168 11BB;BCEC;1107 1168 11BB; # (볬; 볬; 볬; 볬; 볬; ) HANGUL SYLLABLE BYESS
+BCED;BCED;1107 1168 11BC;BCED;1107 1168 11BC; # (볭; 볭; 볭; 볭; 볭; ) HANGUL SYLLABLE BYENG
+BCEE;BCEE;1107 1168 11BD;BCEE;1107 1168 11BD; # (볮; 볮; 볮; 볮; 볮; ) HANGUL SYLLABLE BYEJ
+BCEF;BCEF;1107 1168 11BE;BCEF;1107 1168 11BE; # (볯; 볯; 볯; 볯; 볯; ) HANGUL SYLLABLE BYEC
+BCF0;BCF0;1107 1168 11BF;BCF0;1107 1168 11BF; # (볰; 볰; 볰; 볰; 볰; ) HANGUL SYLLABLE BYEK
+BCF1;BCF1;1107 1168 11C0;BCF1;1107 1168 11C0; # (볱; 볱; 볱; 볱; 볱; ) HANGUL SYLLABLE BYET
+BCF2;BCF2;1107 1168 11C1;BCF2;1107 1168 11C1; # (볲; 볲; 볲; 볲; 볲; ) HANGUL SYLLABLE BYEP
+BCF3;BCF3;1107 1168 11C2;BCF3;1107 1168 11C2; # (볳; 볳; 볳; 볳; 볳; ) HANGUL SYLLABLE BYEH
+BCF4;BCF4;1107 1169;BCF4;1107 1169; # (보; 보; 보; 보; 보; ) HANGUL SYLLABLE BO
+BCF5;BCF5;1107 1169 11A8;BCF5;1107 1169 11A8; # (복; 복; 복; 복; 복; ) HANGUL SYLLABLE BOG
+BCF6;BCF6;1107 1169 11A9;BCF6;1107 1169 11A9; # (볶; 볶; 볶; 볶; 볶; ) HANGUL SYLLABLE BOGG
+BCF7;BCF7;1107 1169 11AA;BCF7;1107 1169 11AA; # (볷; 볷; 볷; 볷; 볷; ) HANGUL SYLLABLE BOGS
+BCF8;BCF8;1107 1169 11AB;BCF8;1107 1169 11AB; # (본; 본; 본; 본; 본; ) HANGUL SYLLABLE BON
+BCF9;BCF9;1107 1169 11AC;BCF9;1107 1169 11AC; # (볹; 볹; 볹; 볹; 볹; ) HANGUL SYLLABLE BONJ
+BCFA;BCFA;1107 1169 11AD;BCFA;1107 1169 11AD; # (볺; 볺; 볺; 볺; 볺; ) HANGUL SYLLABLE BONH
+BCFB;BCFB;1107 1169 11AE;BCFB;1107 1169 11AE; # (볻; 볻; 볻; 볻; 볻; ) HANGUL SYLLABLE BOD
+BCFC;BCFC;1107 1169 11AF;BCFC;1107 1169 11AF; # (볼; 볼; 볼; 볼; 볼; ) HANGUL SYLLABLE BOL
+BCFD;BCFD;1107 1169 11B0;BCFD;1107 1169 11B0; # (볽; 볽; 볽; 볽; 볽; ) HANGUL SYLLABLE BOLG
+BCFE;BCFE;1107 1169 11B1;BCFE;1107 1169 11B1; # (볾; 볾; 볾; 볾; 볾; ) HANGUL SYLLABLE BOLM
+BCFF;BCFF;1107 1169 11B2;BCFF;1107 1169 11B2; # (볿; 볿; 볿; 볿; 볿; ) HANGUL SYLLABLE BOLB
+BD00;BD00;1107 1169 11B3;BD00;1107 1169 11B3; # (봀; 봀; 봀; 봀; 봀; ) HANGUL SYLLABLE BOLS
+BD01;BD01;1107 1169 11B4;BD01;1107 1169 11B4; # (봁; 봁; 봁; 봁; 봁; ) HANGUL SYLLABLE BOLT
+BD02;BD02;1107 1169 11B5;BD02;1107 1169 11B5; # (봂; 봂; 봂; 봂; 봂; ) HANGUL SYLLABLE BOLP
+BD03;BD03;1107 1169 11B6;BD03;1107 1169 11B6; # (봃; 봃; 봃; 봃; 봃; ) HANGUL SYLLABLE BOLH
+BD04;BD04;1107 1169 11B7;BD04;1107 1169 11B7; # (봄; 봄; 봄; 봄; 봄; ) HANGUL SYLLABLE BOM
+BD05;BD05;1107 1169 11B8;BD05;1107 1169 11B8; # (봅; 봅; 봅; 봅; 봅; ) HANGUL SYLLABLE BOB
+BD06;BD06;1107 1169 11B9;BD06;1107 1169 11B9; # (봆; 봆; 봆; 봆; 봆; ) HANGUL SYLLABLE BOBS
+BD07;BD07;1107 1169 11BA;BD07;1107 1169 11BA; # (봇; 봇; 봇; 봇; 봇; ) HANGUL SYLLABLE BOS
+BD08;BD08;1107 1169 11BB;BD08;1107 1169 11BB; # (봈; 봈; 봈; 봈; 봈; ) HANGUL SYLLABLE BOSS
+BD09;BD09;1107 1169 11BC;BD09;1107 1169 11BC; # (봉; 봉; 봉; 봉; 봉; ) HANGUL SYLLABLE BONG
+BD0A;BD0A;1107 1169 11BD;BD0A;1107 1169 11BD; # (봊; 봊; 봊; 봊; 봊; ) HANGUL SYLLABLE BOJ
+BD0B;BD0B;1107 1169 11BE;BD0B;1107 1169 11BE; # (봋; 봋; 봋; 봋; 봋; ) HANGUL SYLLABLE BOC
+BD0C;BD0C;1107 1169 11BF;BD0C;1107 1169 11BF; # (봌; 봌; 봌; 봌; 봌; ) HANGUL SYLLABLE BOK
+BD0D;BD0D;1107 1169 11C0;BD0D;1107 1169 11C0; # (봍; 봍; 봍; 봍; 봍; ) HANGUL SYLLABLE BOT
+BD0E;BD0E;1107 1169 11C1;BD0E;1107 1169 11C1; # (봎; 봎; 봎; 봎; 봎; ) HANGUL SYLLABLE BOP
+BD0F;BD0F;1107 1169 11C2;BD0F;1107 1169 11C2; # (봏; 봏; 봏; 봏; 봏; ) HANGUL SYLLABLE BOH
+BD10;BD10;1107 116A;BD10;1107 116A; # (봐; 봐; 봐; 봐; 봐; ) HANGUL SYLLABLE BWA
+BD11;BD11;1107 116A 11A8;BD11;1107 116A 11A8; # (봑; 봑; 봑; 봑; 봑; ) HANGUL SYLLABLE BWAG
+BD12;BD12;1107 116A 11A9;BD12;1107 116A 11A9; # (봒; 봒; 봒; 봒; 봒; ) HANGUL SYLLABLE BWAGG
+BD13;BD13;1107 116A 11AA;BD13;1107 116A 11AA; # (봓; 봓; 봓; 봓; 봓; ) HANGUL SYLLABLE BWAGS
+BD14;BD14;1107 116A 11AB;BD14;1107 116A 11AB; # (봔; 봔; 봔; 봔; 봔; ) HANGUL SYLLABLE BWAN
+BD15;BD15;1107 116A 11AC;BD15;1107 116A 11AC; # (봕; 봕; 봕; 봕; 봕; ) HANGUL SYLLABLE BWANJ
+BD16;BD16;1107 116A 11AD;BD16;1107 116A 11AD; # (봖; 봖; 봖; 봖; 봖; ) HANGUL SYLLABLE BWANH
+BD17;BD17;1107 116A 11AE;BD17;1107 116A 11AE; # (봗; 봗; 봗; 봗; 봗; ) HANGUL SYLLABLE BWAD
+BD18;BD18;1107 116A 11AF;BD18;1107 116A 11AF; # (봘; 봘; 봘; 봘; 봘; ) HANGUL SYLLABLE BWAL
+BD19;BD19;1107 116A 11B0;BD19;1107 116A 11B0; # (봙; 봙; 봙; 봙; 봙; ) HANGUL SYLLABLE BWALG
+BD1A;BD1A;1107 116A 11B1;BD1A;1107 116A 11B1; # (봚; 봚; 봚; 봚; 봚; ) HANGUL SYLLABLE BWALM
+BD1B;BD1B;1107 116A 11B2;BD1B;1107 116A 11B2; # (봛; 봛; 봛; 봛; 봛; ) HANGUL SYLLABLE BWALB
+BD1C;BD1C;1107 116A 11B3;BD1C;1107 116A 11B3; # (봜; 봜; 봜; 봜; 봜; ) HANGUL SYLLABLE BWALS
+BD1D;BD1D;1107 116A 11B4;BD1D;1107 116A 11B4; # (봝; 봝; 봝; 봝; 봝; ) HANGUL SYLLABLE BWALT
+BD1E;BD1E;1107 116A 11B5;BD1E;1107 116A 11B5; # (봞; 봞; 봞; 봞; 봞; ) HANGUL SYLLABLE BWALP
+BD1F;BD1F;1107 116A 11B6;BD1F;1107 116A 11B6; # (봟; 봟; 봟; 봟; 봟; ) HANGUL SYLLABLE BWALH
+BD20;BD20;1107 116A 11B7;BD20;1107 116A 11B7; # (봠; 봠; 봠; 봠; 봠; ) HANGUL SYLLABLE BWAM
+BD21;BD21;1107 116A 11B8;BD21;1107 116A 11B8; # (봡; 봡; 봡; 봡; 봡; ) HANGUL SYLLABLE BWAB
+BD22;BD22;1107 116A 11B9;BD22;1107 116A 11B9; # (봢; 봢; 봢; 봢; 봢; ) HANGUL SYLLABLE BWABS
+BD23;BD23;1107 116A 11BA;BD23;1107 116A 11BA; # (봣; 봣; 봣; 봣; 봣; ) HANGUL SYLLABLE BWAS
+BD24;BD24;1107 116A 11BB;BD24;1107 116A 11BB; # (봤; 봤; 봤; 봤; 봤; ) HANGUL SYLLABLE BWASS
+BD25;BD25;1107 116A 11BC;BD25;1107 116A 11BC; # (봥; 봥; 봥; 봥; 봥; ) HANGUL SYLLABLE BWANG
+BD26;BD26;1107 116A 11BD;BD26;1107 116A 11BD; # (봦; 봦; 봦; 봦; 봦; ) HANGUL SYLLABLE BWAJ
+BD27;BD27;1107 116A 11BE;BD27;1107 116A 11BE; # (봧; 봧; 봧; 봧; 봧; ) HANGUL SYLLABLE BWAC
+BD28;BD28;1107 116A 11BF;BD28;1107 116A 11BF; # (봨; 봨; 봨; 봨; 봨; ) HANGUL SYLLABLE BWAK
+BD29;BD29;1107 116A 11C0;BD29;1107 116A 11C0; # (봩; 봩; 봩; 봩; 봩; ) HANGUL SYLLABLE BWAT
+BD2A;BD2A;1107 116A 11C1;BD2A;1107 116A 11C1; # (봪; 봪; 봪; 봪; 봪; ) HANGUL SYLLABLE BWAP
+BD2B;BD2B;1107 116A 11C2;BD2B;1107 116A 11C2; # (봫; 봫; 봫; 봫; 봫; ) HANGUL SYLLABLE BWAH
+BD2C;BD2C;1107 116B;BD2C;1107 116B; # (봬; 봬; 봬; 봬; 봬; ) HANGUL SYLLABLE BWAE
+BD2D;BD2D;1107 116B 11A8;BD2D;1107 116B 11A8; # (봭; 봭; 봭; 봭; 봭; ) HANGUL SYLLABLE BWAEG
+BD2E;BD2E;1107 116B 11A9;BD2E;1107 116B 11A9; # (봮; 봮; 봮; 봮; 봮; ) HANGUL SYLLABLE BWAEGG
+BD2F;BD2F;1107 116B 11AA;BD2F;1107 116B 11AA; # (봯; 봯; 봯; 봯; 봯; ) HANGUL SYLLABLE BWAEGS
+BD30;BD30;1107 116B 11AB;BD30;1107 116B 11AB; # (봰; 봰; 봰; 봰; 봰; ) HANGUL SYLLABLE BWAEN
+BD31;BD31;1107 116B 11AC;BD31;1107 116B 11AC; # (봱; 봱; 봱; 봱; 봱; ) HANGUL SYLLABLE BWAENJ
+BD32;BD32;1107 116B 11AD;BD32;1107 116B 11AD; # (봲; 봲; 봲; 봲; 봲; ) HANGUL SYLLABLE BWAENH
+BD33;BD33;1107 116B 11AE;BD33;1107 116B 11AE; # (봳; 봳; 봳; 봳; 봳; ) HANGUL SYLLABLE BWAED
+BD34;BD34;1107 116B 11AF;BD34;1107 116B 11AF; # (봴; 봴; 봴; 봴; 봴; ) HANGUL SYLLABLE BWAEL
+BD35;BD35;1107 116B 11B0;BD35;1107 116B 11B0; # (봵; 봵; 봵; 봵; 봵; ) HANGUL SYLLABLE BWAELG
+BD36;BD36;1107 116B 11B1;BD36;1107 116B 11B1; # (봶; 봶; 봶; 봶; 봶; ) HANGUL SYLLABLE BWAELM
+BD37;BD37;1107 116B 11B2;BD37;1107 116B 11B2; # (봷; 봷; 봷; 봷; 봷; ) HANGUL SYLLABLE BWAELB
+BD38;BD38;1107 116B 11B3;BD38;1107 116B 11B3; # (봸; 봸; 봸; 봸; 봸; ) HANGUL SYLLABLE BWAELS
+BD39;BD39;1107 116B 11B4;BD39;1107 116B 11B4; # (봹; 봹; 봹; 봹; 봹; ) HANGUL SYLLABLE BWAELT
+BD3A;BD3A;1107 116B 11B5;BD3A;1107 116B 11B5; # (봺; 봺; 봺; 봺; 봺; ) HANGUL SYLLABLE BWAELP
+BD3B;BD3B;1107 116B 11B6;BD3B;1107 116B 11B6; # (봻; 봻; 봻; 봻; 봻; ) HANGUL SYLLABLE BWAELH
+BD3C;BD3C;1107 116B 11B7;BD3C;1107 116B 11B7; # (봼; 봼; 봼; 봼; 봼; ) HANGUL SYLLABLE BWAEM
+BD3D;BD3D;1107 116B 11B8;BD3D;1107 116B 11B8; # (봽; 봽; 봽; 봽; 봽; ) HANGUL SYLLABLE BWAEB
+BD3E;BD3E;1107 116B 11B9;BD3E;1107 116B 11B9; # (봾; 봾; 봾; 봾; 봾; ) HANGUL SYLLABLE BWAEBS
+BD3F;BD3F;1107 116B 11BA;BD3F;1107 116B 11BA; # (봿; 봿; 봿; 봿; 봿; ) HANGUL SYLLABLE BWAES
+BD40;BD40;1107 116B 11BB;BD40;1107 116B 11BB; # (뵀; 뵀; 뵀; 뵀; 뵀; ) HANGUL SYLLABLE BWAESS
+BD41;BD41;1107 116B 11BC;BD41;1107 116B 11BC; # (뵁; 뵁; 뵁; 뵁; 뵁; ) HANGUL SYLLABLE BWAENG
+BD42;BD42;1107 116B 11BD;BD42;1107 116B 11BD; # (뵂; 뵂; 뵂; 뵂; 뵂; ) HANGUL SYLLABLE BWAEJ
+BD43;BD43;1107 116B 11BE;BD43;1107 116B 11BE; # (뵃; 뵃; 뵃; 뵃; 뵃; ) HANGUL SYLLABLE BWAEC
+BD44;BD44;1107 116B 11BF;BD44;1107 116B 11BF; # (뵄; 뵄; 뵄; 뵄; 뵄; ) HANGUL SYLLABLE BWAEK
+BD45;BD45;1107 116B 11C0;BD45;1107 116B 11C0; # (뵅; 뵅; 뵅; 뵅; 뵅; ) HANGUL SYLLABLE BWAET
+BD46;BD46;1107 116B 11C1;BD46;1107 116B 11C1; # (뵆; 뵆; 뵆; 뵆; 뵆; ) HANGUL SYLLABLE BWAEP
+BD47;BD47;1107 116B 11C2;BD47;1107 116B 11C2; # (뵇; 뵇; 뵇; 뵇; 뵇; ) HANGUL SYLLABLE BWAEH
+BD48;BD48;1107 116C;BD48;1107 116C; # (뵈; 뵈; 뵈; 뵈; 뵈; ) HANGUL SYLLABLE BOE
+BD49;BD49;1107 116C 11A8;BD49;1107 116C 11A8; # (뵉; 뵉; 뵉; 뵉; 뵉; ) HANGUL SYLLABLE BOEG
+BD4A;BD4A;1107 116C 11A9;BD4A;1107 116C 11A9; # (뵊; 뵊; 뵊; 뵊; 뵊; ) HANGUL SYLLABLE BOEGG
+BD4B;BD4B;1107 116C 11AA;BD4B;1107 116C 11AA; # (뵋; 뵋; 뵋; 뵋; 뵋; ) HANGUL SYLLABLE BOEGS
+BD4C;BD4C;1107 116C 11AB;BD4C;1107 116C 11AB; # (뵌; 뵌; 뵌; 뵌; 뵌; ) HANGUL SYLLABLE BOEN
+BD4D;BD4D;1107 116C 11AC;BD4D;1107 116C 11AC; # (뵍; 뵍; 뵍; 뵍; 뵍; ) HANGUL SYLLABLE BOENJ
+BD4E;BD4E;1107 116C 11AD;BD4E;1107 116C 11AD; # (뵎; 뵎; 뵎; 뵎; 뵎; ) HANGUL SYLLABLE BOENH
+BD4F;BD4F;1107 116C 11AE;BD4F;1107 116C 11AE; # (뵏; 뵏; 뵏; 뵏; 뵏; ) HANGUL SYLLABLE BOED
+BD50;BD50;1107 116C 11AF;BD50;1107 116C 11AF; # (뵐; 뵐; 뵐; 뵐; 뵐; ) HANGUL SYLLABLE BOEL
+BD51;BD51;1107 116C 11B0;BD51;1107 116C 11B0; # (뵑; 뵑; 뵑; 뵑; 뵑; ) HANGUL SYLLABLE BOELG
+BD52;BD52;1107 116C 11B1;BD52;1107 116C 11B1; # (뵒; 뵒; 뵒; 뵒; 뵒; ) HANGUL SYLLABLE BOELM
+BD53;BD53;1107 116C 11B2;BD53;1107 116C 11B2; # (뵓; 뵓; 뵓; 뵓; 뵓; ) HANGUL SYLLABLE BOELB
+BD54;BD54;1107 116C 11B3;BD54;1107 116C 11B3; # (뵔; 뵔; 뵔; 뵔; 뵔; ) HANGUL SYLLABLE BOELS
+BD55;BD55;1107 116C 11B4;BD55;1107 116C 11B4; # (뵕; 뵕; 뵕; 뵕; 뵕; ) HANGUL SYLLABLE BOELT
+BD56;BD56;1107 116C 11B5;BD56;1107 116C 11B5; # (뵖; 뵖; 뵖; 뵖; 뵖; ) HANGUL SYLLABLE BOELP
+BD57;BD57;1107 116C 11B6;BD57;1107 116C 11B6; # (뵗; 뵗; 뵗; 뵗; 뵗; ) HANGUL SYLLABLE BOELH
+BD58;BD58;1107 116C 11B7;BD58;1107 116C 11B7; # (뵘; 뵘; 뵘; 뵘; 뵘; ) HANGUL SYLLABLE BOEM
+BD59;BD59;1107 116C 11B8;BD59;1107 116C 11B8; # (뵙; 뵙; 뵙; 뵙; 뵙; ) HANGUL SYLLABLE BOEB
+BD5A;BD5A;1107 116C 11B9;BD5A;1107 116C 11B9; # (뵚; 뵚; 뵚; 뵚; 뵚; ) HANGUL SYLLABLE BOEBS
+BD5B;BD5B;1107 116C 11BA;BD5B;1107 116C 11BA; # (뵛; 뵛; 뵛; 뵛; 뵛; ) HANGUL SYLLABLE BOES
+BD5C;BD5C;1107 116C 11BB;BD5C;1107 116C 11BB; # (뵜; 뵜; 뵜; 뵜; 뵜; ) HANGUL SYLLABLE BOESS
+BD5D;BD5D;1107 116C 11BC;BD5D;1107 116C 11BC; # (뵝; 뵝; 뵝; 뵝; 뵝; ) HANGUL SYLLABLE BOENG
+BD5E;BD5E;1107 116C 11BD;BD5E;1107 116C 11BD; # (뵞; 뵞; 뵞; 뵞; 뵞; ) HANGUL SYLLABLE BOEJ
+BD5F;BD5F;1107 116C 11BE;BD5F;1107 116C 11BE; # (뵟; 뵟; 뵟; 뵟; 뵟; ) HANGUL SYLLABLE BOEC
+BD60;BD60;1107 116C 11BF;BD60;1107 116C 11BF; # (뵠; 뵠; 뵠; 뵠; 뵠; ) HANGUL SYLLABLE BOEK
+BD61;BD61;1107 116C 11C0;BD61;1107 116C 11C0; # (뵡; 뵡; 뵡; 뵡; 뵡; ) HANGUL SYLLABLE BOET
+BD62;BD62;1107 116C 11C1;BD62;1107 116C 11C1; # (뵢; 뵢; 뵢; 뵢; 뵢; ) HANGUL SYLLABLE BOEP
+BD63;BD63;1107 116C 11C2;BD63;1107 116C 11C2; # (뵣; 뵣; 뵣; 뵣; 뵣; ) HANGUL SYLLABLE BOEH
+BD64;BD64;1107 116D;BD64;1107 116D; # (뵤; 뵤; 뵤; 뵤; 뵤; ) HANGUL SYLLABLE BYO
+BD65;BD65;1107 116D 11A8;BD65;1107 116D 11A8; # (뵥; 뵥; 뵥; 뵥; 뵥; ) HANGUL SYLLABLE BYOG
+BD66;BD66;1107 116D 11A9;BD66;1107 116D 11A9; # (뵦; 뵦; 뵦; 뵦; 뵦; ) HANGUL SYLLABLE BYOGG
+BD67;BD67;1107 116D 11AA;BD67;1107 116D 11AA; # (뵧; 뵧; 뵧; 뵧; 뵧; ) HANGUL SYLLABLE BYOGS
+BD68;BD68;1107 116D 11AB;BD68;1107 116D 11AB; # (뵨; 뵨; 뵨; 뵨; 뵨; ) HANGUL SYLLABLE BYON
+BD69;BD69;1107 116D 11AC;BD69;1107 116D 11AC; # (뵩; 뵩; 뵩; 뵩; 뵩; ) HANGUL SYLLABLE BYONJ
+BD6A;BD6A;1107 116D 11AD;BD6A;1107 116D 11AD; # (뵪; 뵪; 뵪; 뵪; 뵪; ) HANGUL SYLLABLE BYONH
+BD6B;BD6B;1107 116D 11AE;BD6B;1107 116D 11AE; # (뵫; 뵫; 뵫; 뵫; 뵫; ) HANGUL SYLLABLE BYOD
+BD6C;BD6C;1107 116D 11AF;BD6C;1107 116D 11AF; # (뵬; 뵬; 뵬; 뵬; 뵬; ) HANGUL SYLLABLE BYOL
+BD6D;BD6D;1107 116D 11B0;BD6D;1107 116D 11B0; # (뵭; 뵭; 뵭; 뵭; 뵭; ) HANGUL SYLLABLE BYOLG
+BD6E;BD6E;1107 116D 11B1;BD6E;1107 116D 11B1; # (뵮; 뵮; 뵮; 뵮; 뵮; ) HANGUL SYLLABLE BYOLM
+BD6F;BD6F;1107 116D 11B2;BD6F;1107 116D 11B2; # (뵯; 뵯; 뵯; 뵯; 뵯; ) HANGUL SYLLABLE BYOLB
+BD70;BD70;1107 116D 11B3;BD70;1107 116D 11B3; # (뵰; 뵰; 뵰; 뵰; 뵰; ) HANGUL SYLLABLE BYOLS
+BD71;BD71;1107 116D 11B4;BD71;1107 116D 11B4; # (뵱; 뵱; 뵱; 뵱; 뵱; ) HANGUL SYLLABLE BYOLT
+BD72;BD72;1107 116D 11B5;BD72;1107 116D 11B5; # (뵲; 뵲; 뵲; 뵲; 뵲; ) HANGUL SYLLABLE BYOLP
+BD73;BD73;1107 116D 11B6;BD73;1107 116D 11B6; # (뵳; 뵳; 뵳; 뵳; 뵳; ) HANGUL SYLLABLE BYOLH
+BD74;BD74;1107 116D 11B7;BD74;1107 116D 11B7; # (뵴; 뵴; 뵴; 뵴; 뵴; ) HANGUL SYLLABLE BYOM
+BD75;BD75;1107 116D 11B8;BD75;1107 116D 11B8; # (뵵; 뵵; 뵵; 뵵; 뵵; ) HANGUL SYLLABLE BYOB
+BD76;BD76;1107 116D 11B9;BD76;1107 116D 11B9; # (뵶; 뵶; 뵶; 뵶; 뵶; ) HANGUL SYLLABLE BYOBS
+BD77;BD77;1107 116D 11BA;BD77;1107 116D 11BA; # (뵷; 뵷; 뵷; 뵷; 뵷; ) HANGUL SYLLABLE BYOS
+BD78;BD78;1107 116D 11BB;BD78;1107 116D 11BB; # (뵸; 뵸; 뵸; 뵸; 뵸; ) HANGUL SYLLABLE BYOSS
+BD79;BD79;1107 116D 11BC;BD79;1107 116D 11BC; # (뵹; 뵹; 뵹; 뵹; 뵹; ) HANGUL SYLLABLE BYONG
+BD7A;BD7A;1107 116D 11BD;BD7A;1107 116D 11BD; # (뵺; 뵺; 뵺; 뵺; 뵺; ) HANGUL SYLLABLE BYOJ
+BD7B;BD7B;1107 116D 11BE;BD7B;1107 116D 11BE; # (뵻; 뵻; 뵻; 뵻; 뵻; ) HANGUL SYLLABLE BYOC
+BD7C;BD7C;1107 116D 11BF;BD7C;1107 116D 11BF; # (뵼; 뵼; 뵼; 뵼; 뵼; ) HANGUL SYLLABLE BYOK
+BD7D;BD7D;1107 116D 11C0;BD7D;1107 116D 11C0; # (뵽; 뵽; 뵽; 뵽; 뵽; ) HANGUL SYLLABLE BYOT
+BD7E;BD7E;1107 116D 11C1;BD7E;1107 116D 11C1; # (뵾; 뵾; 뵾; 뵾; 뵾; ) HANGUL SYLLABLE BYOP
+BD7F;BD7F;1107 116D 11C2;BD7F;1107 116D 11C2; # (뵿; 뵿; 뵿; 뵿; 뵿; ) HANGUL SYLLABLE BYOH
+BD80;BD80;1107 116E;BD80;1107 116E; # (부; 부; 부; 부; 부; ) HANGUL SYLLABLE BU
+BD81;BD81;1107 116E 11A8;BD81;1107 116E 11A8; # (북; 북; 북; 북; 북; ) HANGUL SYLLABLE BUG
+BD82;BD82;1107 116E 11A9;BD82;1107 116E 11A9; # (붂; 붂; 붂; 붂; 붂; ) HANGUL SYLLABLE BUGG
+BD83;BD83;1107 116E 11AA;BD83;1107 116E 11AA; # (붃; 붃; 붃; 붃; 붃; ) HANGUL SYLLABLE BUGS
+BD84;BD84;1107 116E 11AB;BD84;1107 116E 11AB; # (분; 분; 분; 분; 분; ) HANGUL SYLLABLE BUN
+BD85;BD85;1107 116E 11AC;BD85;1107 116E 11AC; # (붅; 붅; 붅; 붅; 붅; ) HANGUL SYLLABLE BUNJ
+BD86;BD86;1107 116E 11AD;BD86;1107 116E 11AD; # (붆; 붆; 붆; 붆; 붆; ) HANGUL SYLLABLE BUNH
+BD87;BD87;1107 116E 11AE;BD87;1107 116E 11AE; # (붇; 붇; 붇; 붇; 붇; ) HANGUL SYLLABLE BUD
+BD88;BD88;1107 116E 11AF;BD88;1107 116E 11AF; # (불; 불; 불; 불; 불; ) HANGUL SYLLABLE BUL
+BD89;BD89;1107 116E 11B0;BD89;1107 116E 11B0; # (붉; 붉; 붉; 붉; 붉; ) HANGUL SYLLABLE BULG
+BD8A;BD8A;1107 116E 11B1;BD8A;1107 116E 11B1; # (붊; 붊; 붊; 붊; 붊; ) HANGUL SYLLABLE BULM
+BD8B;BD8B;1107 116E 11B2;BD8B;1107 116E 11B2; # (붋; 붋; 붋; 붋; 붋; ) HANGUL SYLLABLE BULB
+BD8C;BD8C;1107 116E 11B3;BD8C;1107 116E 11B3; # (붌; 붌; 붌; 붌; 붌; ) HANGUL SYLLABLE BULS
+BD8D;BD8D;1107 116E 11B4;BD8D;1107 116E 11B4; # (붍; 붍; 붍; 붍; 붍; ) HANGUL SYLLABLE BULT
+BD8E;BD8E;1107 116E 11B5;BD8E;1107 116E 11B5; # (붎; 붎; 붎; 붎; 붎; ) HANGUL SYLLABLE BULP
+BD8F;BD8F;1107 116E 11B6;BD8F;1107 116E 11B6; # (붏; 붏; 붏; 붏; 붏; ) HANGUL SYLLABLE BULH
+BD90;BD90;1107 116E 11B7;BD90;1107 116E 11B7; # (붐; 붐; 붐; 붐; 붐; ) HANGUL SYLLABLE BUM
+BD91;BD91;1107 116E 11B8;BD91;1107 116E 11B8; # (붑; 붑; 붑; 붑; 붑; ) HANGUL SYLLABLE BUB
+BD92;BD92;1107 116E 11B9;BD92;1107 116E 11B9; # (붒; 붒; 붒; 붒; 붒; ) HANGUL SYLLABLE BUBS
+BD93;BD93;1107 116E 11BA;BD93;1107 116E 11BA; # (붓; 붓; 붓; 붓; 붓; ) HANGUL SYLLABLE BUS
+BD94;BD94;1107 116E 11BB;BD94;1107 116E 11BB; # (붔; 붔; 붔; 붔; 붔; ) HANGUL SYLLABLE BUSS
+BD95;BD95;1107 116E 11BC;BD95;1107 116E 11BC; # (붕; 붕; 붕; 붕; 붕; ) HANGUL SYLLABLE BUNG
+BD96;BD96;1107 116E 11BD;BD96;1107 116E 11BD; # (붖; 붖; 붖; 붖; 붖; ) HANGUL SYLLABLE BUJ
+BD97;BD97;1107 116E 11BE;BD97;1107 116E 11BE; # (붗; 붗; 붗; 붗; 붗; ) HANGUL SYLLABLE BUC
+BD98;BD98;1107 116E 11BF;BD98;1107 116E 11BF; # (붘; 붘; 붘; 붘; 붘; ) HANGUL SYLLABLE BUK
+BD99;BD99;1107 116E 11C0;BD99;1107 116E 11C0; # (붙; 붙; 붙; 붙; 붙; ) HANGUL SYLLABLE BUT
+BD9A;BD9A;1107 116E 11C1;BD9A;1107 116E 11C1; # (붚; 붚; 붚; 붚; 붚; ) HANGUL SYLLABLE BUP
+BD9B;BD9B;1107 116E 11C2;BD9B;1107 116E 11C2; # (붛; 붛; 붛; 붛; 붛; ) HANGUL SYLLABLE BUH
+BD9C;BD9C;1107 116F;BD9C;1107 116F; # (붜; 붜; 붜; 붜; 붜; ) HANGUL SYLLABLE BWEO
+BD9D;BD9D;1107 116F 11A8;BD9D;1107 116F 11A8; # (붝; 붝; 붝; 붝; 붝; ) HANGUL SYLLABLE BWEOG
+BD9E;BD9E;1107 116F 11A9;BD9E;1107 116F 11A9; # (붞; 붞; 붞; 붞; 붞; ) HANGUL SYLLABLE BWEOGG
+BD9F;BD9F;1107 116F 11AA;BD9F;1107 116F 11AA; # (붟; 붟; 붟; 붟; 붟; ) HANGUL SYLLABLE BWEOGS
+BDA0;BDA0;1107 116F 11AB;BDA0;1107 116F 11AB; # (붠; 붠; 붠; 붠; 붠; ) HANGUL SYLLABLE BWEON
+BDA1;BDA1;1107 116F 11AC;BDA1;1107 116F 11AC; # (붡; 붡; 붡; 붡; 붡; ) HANGUL SYLLABLE BWEONJ
+BDA2;BDA2;1107 116F 11AD;BDA2;1107 116F 11AD; # (붢; 붢; 붢; 붢; 붢; ) HANGUL SYLLABLE BWEONH
+BDA3;BDA3;1107 116F 11AE;BDA3;1107 116F 11AE; # (붣; 붣; 붣; 붣; 붣; ) HANGUL SYLLABLE BWEOD
+BDA4;BDA4;1107 116F 11AF;BDA4;1107 116F 11AF; # (붤; 붤; 붤; 붤; 붤; ) HANGUL SYLLABLE BWEOL
+BDA5;BDA5;1107 116F 11B0;BDA5;1107 116F 11B0; # (붥; 붥; 붥; 붥; 붥; ) HANGUL SYLLABLE BWEOLG
+BDA6;BDA6;1107 116F 11B1;BDA6;1107 116F 11B1; # (붦; 붦; 붦; 붦; 붦; ) HANGUL SYLLABLE BWEOLM
+BDA7;BDA7;1107 116F 11B2;BDA7;1107 116F 11B2; # (붧; 붧; 붧; 붧; 붧; ) HANGUL SYLLABLE BWEOLB
+BDA8;BDA8;1107 116F 11B3;BDA8;1107 116F 11B3; # (붨; 붨; 붨; 붨; 붨; ) HANGUL SYLLABLE BWEOLS
+BDA9;BDA9;1107 116F 11B4;BDA9;1107 116F 11B4; # (붩; 붩; 붩; 붩; 붩; ) HANGUL SYLLABLE BWEOLT
+BDAA;BDAA;1107 116F 11B5;BDAA;1107 116F 11B5; # (붪; 붪; 붪; 붪; 붪; ) HANGUL SYLLABLE BWEOLP
+BDAB;BDAB;1107 116F 11B6;BDAB;1107 116F 11B6; # (붫; 붫; 붫; 붫; 붫; ) HANGUL SYLLABLE BWEOLH
+BDAC;BDAC;1107 116F 11B7;BDAC;1107 116F 11B7; # (붬; 붬; 붬; 붬; 붬; ) HANGUL SYLLABLE BWEOM
+BDAD;BDAD;1107 116F 11B8;BDAD;1107 116F 11B8; # (붭; 붭; 붭; 붭; 붭; ) HANGUL SYLLABLE BWEOB
+BDAE;BDAE;1107 116F 11B9;BDAE;1107 116F 11B9; # (붮; 붮; 붮; 붮; 붮; ) HANGUL SYLLABLE BWEOBS
+BDAF;BDAF;1107 116F 11BA;BDAF;1107 116F 11BA; # (붯; 붯; 붯; 붯; 붯; ) HANGUL SYLLABLE BWEOS
+BDB0;BDB0;1107 116F 11BB;BDB0;1107 116F 11BB; # (붰; 붰; 붰; 붰; 붰; ) HANGUL SYLLABLE BWEOSS
+BDB1;BDB1;1107 116F 11BC;BDB1;1107 116F 11BC; # (붱; 붱; 붱; 붱; 붱; ) HANGUL SYLLABLE BWEONG
+BDB2;BDB2;1107 116F 11BD;BDB2;1107 116F 11BD; # (붲; 붲; 붲; 붲; 붲; ) HANGUL SYLLABLE BWEOJ
+BDB3;BDB3;1107 116F 11BE;BDB3;1107 116F 11BE; # (붳; 붳; 붳; 붳; 붳; ) HANGUL SYLLABLE BWEOC
+BDB4;BDB4;1107 116F 11BF;BDB4;1107 116F 11BF; # (붴; 붴; 붴; 붴; 붴; ) HANGUL SYLLABLE BWEOK
+BDB5;BDB5;1107 116F 11C0;BDB5;1107 116F 11C0; # (붵; 붵; 붵; 붵; 붵; ) HANGUL SYLLABLE BWEOT
+BDB6;BDB6;1107 116F 11C1;BDB6;1107 116F 11C1; # (붶; 붶; 붶; 붶; 붶; ) HANGUL SYLLABLE BWEOP
+BDB7;BDB7;1107 116F 11C2;BDB7;1107 116F 11C2; # (붷; 붷; 붷; 붷; 붷; ) HANGUL SYLLABLE BWEOH
+BDB8;BDB8;1107 1170;BDB8;1107 1170; # (붸; 붸; 붸; 붸; 붸; ) HANGUL SYLLABLE BWE
+BDB9;BDB9;1107 1170 11A8;BDB9;1107 1170 11A8; # (붹; 붹; 붹; 붹; 붹; ) HANGUL SYLLABLE BWEG
+BDBA;BDBA;1107 1170 11A9;BDBA;1107 1170 11A9; # (붺; 붺; 붺; 붺; 붺; ) HANGUL SYLLABLE BWEGG
+BDBB;BDBB;1107 1170 11AA;BDBB;1107 1170 11AA; # (붻; 붻; 붻; 붻; 붻; ) HANGUL SYLLABLE BWEGS
+BDBC;BDBC;1107 1170 11AB;BDBC;1107 1170 11AB; # (붼; 붼; 붼; 붼; 붼; ) HANGUL SYLLABLE BWEN
+BDBD;BDBD;1107 1170 11AC;BDBD;1107 1170 11AC; # (붽; 붽; 붽; 붽; 붽; ) HANGUL SYLLABLE BWENJ
+BDBE;BDBE;1107 1170 11AD;BDBE;1107 1170 11AD; # (붾; 붾; 붾; 붾; 붾; ) HANGUL SYLLABLE BWENH
+BDBF;BDBF;1107 1170 11AE;BDBF;1107 1170 11AE; # (붿; 붿; 붿; 붿; 붿; ) HANGUL SYLLABLE BWED
+BDC0;BDC0;1107 1170 11AF;BDC0;1107 1170 11AF; # (뷀; 뷀; 뷀; 뷀; 뷀; ) HANGUL SYLLABLE BWEL
+BDC1;BDC1;1107 1170 11B0;BDC1;1107 1170 11B0; # (뷁; 뷁; 뷁; 뷁; 뷁; ) HANGUL SYLLABLE BWELG
+BDC2;BDC2;1107 1170 11B1;BDC2;1107 1170 11B1; # (뷂; 뷂; 뷂; 뷂; 뷂; ) HANGUL SYLLABLE BWELM
+BDC3;BDC3;1107 1170 11B2;BDC3;1107 1170 11B2; # (뷃; 뷃; 뷃; 뷃; 뷃; ) HANGUL SYLLABLE BWELB
+BDC4;BDC4;1107 1170 11B3;BDC4;1107 1170 11B3; # (뷄; 뷄; 뷄; 뷄; 뷄; ) HANGUL SYLLABLE BWELS
+BDC5;BDC5;1107 1170 11B4;BDC5;1107 1170 11B4; # (뷅; 뷅; 뷅; 뷅; 뷅; ) HANGUL SYLLABLE BWELT
+BDC6;BDC6;1107 1170 11B5;BDC6;1107 1170 11B5; # (뷆; 뷆; 뷆; 뷆; 뷆; ) HANGUL SYLLABLE BWELP
+BDC7;BDC7;1107 1170 11B6;BDC7;1107 1170 11B6; # (뷇; 뷇; 뷇; 뷇; 뷇; ) HANGUL SYLLABLE BWELH
+BDC8;BDC8;1107 1170 11B7;BDC8;1107 1170 11B7; # (뷈; 뷈; 뷈; 뷈; 뷈; ) HANGUL SYLLABLE BWEM
+BDC9;BDC9;1107 1170 11B8;BDC9;1107 1170 11B8; # (뷉; 뷉; 뷉; 뷉; 뷉; ) HANGUL SYLLABLE BWEB
+BDCA;BDCA;1107 1170 11B9;BDCA;1107 1170 11B9; # (뷊; 뷊; 뷊; 뷊; 뷊; ) HANGUL SYLLABLE BWEBS
+BDCB;BDCB;1107 1170 11BA;BDCB;1107 1170 11BA; # (뷋; 뷋; 뷋; 뷋; 뷋; ) HANGUL SYLLABLE BWES
+BDCC;BDCC;1107 1170 11BB;BDCC;1107 1170 11BB; # (뷌; 뷌; 뷌; 뷌; 뷌; ) HANGUL SYLLABLE BWESS
+BDCD;BDCD;1107 1170 11BC;BDCD;1107 1170 11BC; # (뷍; 뷍; 뷍; 뷍; 뷍; ) HANGUL SYLLABLE BWENG
+BDCE;BDCE;1107 1170 11BD;BDCE;1107 1170 11BD; # (뷎; 뷎; 뷎; 뷎; 뷎; ) HANGUL SYLLABLE BWEJ
+BDCF;BDCF;1107 1170 11BE;BDCF;1107 1170 11BE; # (뷏; 뷏; 뷏; 뷏; 뷏; ) HANGUL SYLLABLE BWEC
+BDD0;BDD0;1107 1170 11BF;BDD0;1107 1170 11BF; # (뷐; 뷐; 뷐; 뷐; 뷐; ) HANGUL SYLLABLE BWEK
+BDD1;BDD1;1107 1170 11C0;BDD1;1107 1170 11C0; # (뷑; 뷑; 뷑; 뷑; 뷑; ) HANGUL SYLLABLE BWET
+BDD2;BDD2;1107 1170 11C1;BDD2;1107 1170 11C1; # (뷒; 뷒; 뷒; 뷒; 뷒; ) HANGUL SYLLABLE BWEP
+BDD3;BDD3;1107 1170 11C2;BDD3;1107 1170 11C2; # (뷓; 뷓; 뷓; 뷓; 뷓; ) HANGUL SYLLABLE BWEH
+BDD4;BDD4;1107 1171;BDD4;1107 1171; # (뷔; 뷔; 뷔; 뷔; 뷔; ) HANGUL SYLLABLE BWI
+BDD5;BDD5;1107 1171 11A8;BDD5;1107 1171 11A8; # (뷕; 뷕; 뷕; 뷕; 뷕; ) HANGUL SYLLABLE BWIG
+BDD6;BDD6;1107 1171 11A9;BDD6;1107 1171 11A9; # (뷖; 뷖; 뷖; 뷖; 뷖; ) HANGUL SYLLABLE BWIGG
+BDD7;BDD7;1107 1171 11AA;BDD7;1107 1171 11AA; # (뷗; 뷗; 뷗; 뷗; 뷗; ) HANGUL SYLLABLE BWIGS
+BDD8;BDD8;1107 1171 11AB;BDD8;1107 1171 11AB; # (뷘; 뷘; 뷘; 뷘; 뷘; ) HANGUL SYLLABLE BWIN
+BDD9;BDD9;1107 1171 11AC;BDD9;1107 1171 11AC; # (뷙; 뷙; 뷙; 뷙; 뷙; ) HANGUL SYLLABLE BWINJ
+BDDA;BDDA;1107 1171 11AD;BDDA;1107 1171 11AD; # (뷚; 뷚; 뷚; 뷚; 뷚; ) HANGUL SYLLABLE BWINH
+BDDB;BDDB;1107 1171 11AE;BDDB;1107 1171 11AE; # (뷛; 뷛; 뷛; 뷛; 뷛; ) HANGUL SYLLABLE BWID
+BDDC;BDDC;1107 1171 11AF;BDDC;1107 1171 11AF; # (뷜; 뷜; 뷜; 뷜; 뷜; ) HANGUL SYLLABLE BWIL
+BDDD;BDDD;1107 1171 11B0;BDDD;1107 1171 11B0; # (뷝; 뷝; 뷝; 뷝; 뷝; ) HANGUL SYLLABLE BWILG
+BDDE;BDDE;1107 1171 11B1;BDDE;1107 1171 11B1; # (뷞; 뷞; 뷞; 뷞; 뷞; ) HANGUL SYLLABLE BWILM
+BDDF;BDDF;1107 1171 11B2;BDDF;1107 1171 11B2; # (뷟; 뷟; 뷟; 뷟; 뷟; ) HANGUL SYLLABLE BWILB
+BDE0;BDE0;1107 1171 11B3;BDE0;1107 1171 11B3; # (뷠; 뷠; 뷠; 뷠; 뷠; ) HANGUL SYLLABLE BWILS
+BDE1;BDE1;1107 1171 11B4;BDE1;1107 1171 11B4; # (뷡; 뷡; 뷡; 뷡; 뷡; ) HANGUL SYLLABLE BWILT
+BDE2;BDE2;1107 1171 11B5;BDE2;1107 1171 11B5; # (뷢; 뷢; 뷢; 뷢; 뷢; ) HANGUL SYLLABLE BWILP
+BDE3;BDE3;1107 1171 11B6;BDE3;1107 1171 11B6; # (뷣; 뷣; 뷣; 뷣; 뷣; ) HANGUL SYLLABLE BWILH
+BDE4;BDE4;1107 1171 11B7;BDE4;1107 1171 11B7; # (뷤; 뷤; 뷤; 뷤; 뷤; ) HANGUL SYLLABLE BWIM
+BDE5;BDE5;1107 1171 11B8;BDE5;1107 1171 11B8; # (뷥; 뷥; 뷥; 뷥; 뷥; ) HANGUL SYLLABLE BWIB
+BDE6;BDE6;1107 1171 11B9;BDE6;1107 1171 11B9; # (뷦; 뷦; 뷦; 뷦; 뷦; ) HANGUL SYLLABLE BWIBS
+BDE7;BDE7;1107 1171 11BA;BDE7;1107 1171 11BA; # (뷧; 뷧; 뷧; 뷧; 뷧; ) HANGUL SYLLABLE BWIS
+BDE8;BDE8;1107 1171 11BB;BDE8;1107 1171 11BB; # (뷨; 뷨; 뷨; 뷨; 뷨; ) HANGUL SYLLABLE BWISS
+BDE9;BDE9;1107 1171 11BC;BDE9;1107 1171 11BC; # (뷩; 뷩; 뷩; 뷩; 뷩; ) HANGUL SYLLABLE BWING
+BDEA;BDEA;1107 1171 11BD;BDEA;1107 1171 11BD; # (뷪; 뷪; 뷪; 뷪; 뷪; ) HANGUL SYLLABLE BWIJ
+BDEB;BDEB;1107 1171 11BE;BDEB;1107 1171 11BE; # (뷫; 뷫; 뷫; 뷫; 뷫; ) HANGUL SYLLABLE BWIC
+BDEC;BDEC;1107 1171 11BF;BDEC;1107 1171 11BF; # (뷬; 뷬; 뷬; 뷬; 뷬; ) HANGUL SYLLABLE BWIK
+BDED;BDED;1107 1171 11C0;BDED;1107 1171 11C0; # (뷭; 뷭; 뷭; 뷭; 뷭; ) HANGUL SYLLABLE BWIT
+BDEE;BDEE;1107 1171 11C1;BDEE;1107 1171 11C1; # (뷮; 뷮; 뷮; 뷮; 뷮; ) HANGUL SYLLABLE BWIP
+BDEF;BDEF;1107 1171 11C2;BDEF;1107 1171 11C2; # (뷯; 뷯; 뷯; 뷯; 뷯; ) HANGUL SYLLABLE BWIH
+BDF0;BDF0;1107 1172;BDF0;1107 1172; # (뷰; 뷰; 뷰; 뷰; 뷰; ) HANGUL SYLLABLE BYU
+BDF1;BDF1;1107 1172 11A8;BDF1;1107 1172 11A8; # (뷱; 뷱; 뷱; 뷱; 뷱; ) HANGUL SYLLABLE BYUG
+BDF2;BDF2;1107 1172 11A9;BDF2;1107 1172 11A9; # (뷲; 뷲; 뷲; 뷲; 뷲; ) HANGUL SYLLABLE BYUGG
+BDF3;BDF3;1107 1172 11AA;BDF3;1107 1172 11AA; # (뷳; 뷳; 뷳; 뷳; 뷳; ) HANGUL SYLLABLE BYUGS
+BDF4;BDF4;1107 1172 11AB;BDF4;1107 1172 11AB; # (뷴; 뷴; 뷴; 뷴; 뷴; ) HANGUL SYLLABLE BYUN
+BDF5;BDF5;1107 1172 11AC;BDF5;1107 1172 11AC; # (뷵; 뷵; 뷵; 뷵; 뷵; ) HANGUL SYLLABLE BYUNJ
+BDF6;BDF6;1107 1172 11AD;BDF6;1107 1172 11AD; # (뷶; 뷶; 뷶; 뷶; 뷶; ) HANGUL SYLLABLE BYUNH
+BDF7;BDF7;1107 1172 11AE;BDF7;1107 1172 11AE; # (뷷; 뷷; 뷷; 뷷; 뷷; ) HANGUL SYLLABLE BYUD
+BDF8;BDF8;1107 1172 11AF;BDF8;1107 1172 11AF; # (뷸; 뷸; 뷸; 뷸; 뷸; ) HANGUL SYLLABLE BYUL
+BDF9;BDF9;1107 1172 11B0;BDF9;1107 1172 11B0; # (뷹; 뷹; 뷹; 뷹; 뷹; ) HANGUL SYLLABLE BYULG
+BDFA;BDFA;1107 1172 11B1;BDFA;1107 1172 11B1; # (뷺; 뷺; 뷺; 뷺; 뷺; ) HANGUL SYLLABLE BYULM
+BDFB;BDFB;1107 1172 11B2;BDFB;1107 1172 11B2; # (뷻; 뷻; 뷻; 뷻; 뷻; ) HANGUL SYLLABLE BYULB
+BDFC;BDFC;1107 1172 11B3;BDFC;1107 1172 11B3; # (뷼; 뷼; 뷼; 뷼; 뷼; ) HANGUL SYLLABLE BYULS
+BDFD;BDFD;1107 1172 11B4;BDFD;1107 1172 11B4; # (뷽; 뷽; 뷽; 뷽; 뷽; ) HANGUL SYLLABLE BYULT
+BDFE;BDFE;1107 1172 11B5;BDFE;1107 1172 11B5; # (뷾; 뷾; 뷾; 뷾; 뷾; ) HANGUL SYLLABLE BYULP
+BDFF;BDFF;1107 1172 11B6;BDFF;1107 1172 11B6; # (뷿; 뷿; 뷿; 뷿; 뷿; ) HANGUL SYLLABLE BYULH
+BE00;BE00;1107 1172 11B7;BE00;1107 1172 11B7; # (븀; 븀; 븀; 븀; 븀; ) HANGUL SYLLABLE BYUM
+BE01;BE01;1107 1172 11B8;BE01;1107 1172 11B8; # (븁; 븁; 븁; 븁; 븁; ) HANGUL SYLLABLE BYUB
+BE02;BE02;1107 1172 11B9;BE02;1107 1172 11B9; # (븂; 븂; 븂; 븂; 븂; ) HANGUL SYLLABLE BYUBS
+BE03;BE03;1107 1172 11BA;BE03;1107 1172 11BA; # (븃; 븃; 븃; 븃; 븃; ) HANGUL SYLLABLE BYUS
+BE04;BE04;1107 1172 11BB;BE04;1107 1172 11BB; # (븄; 븄; 븄; 븄; 븄; ) HANGUL SYLLABLE BYUSS
+BE05;BE05;1107 1172 11BC;BE05;1107 1172 11BC; # (븅; 븅; 븅; 븅; 븅; ) HANGUL SYLLABLE BYUNG
+BE06;BE06;1107 1172 11BD;BE06;1107 1172 11BD; # (븆; 븆; 븆; 븆; 븆; ) HANGUL SYLLABLE BYUJ
+BE07;BE07;1107 1172 11BE;BE07;1107 1172 11BE; # (븇; 븇; 븇; 븇; 븇; ) HANGUL SYLLABLE BYUC
+BE08;BE08;1107 1172 11BF;BE08;1107 1172 11BF; # (븈; 븈; 븈; 븈; 븈; ) HANGUL SYLLABLE BYUK
+BE09;BE09;1107 1172 11C0;BE09;1107 1172 11C0; # (븉; 븉; 븉; 븉; 븉; ) HANGUL SYLLABLE BYUT
+BE0A;BE0A;1107 1172 11C1;BE0A;1107 1172 11C1; # (븊; 븊; 븊; 븊; 븊; ) HANGUL SYLLABLE BYUP
+BE0B;BE0B;1107 1172 11C2;BE0B;1107 1172 11C2; # (븋; 븋; 븋; 븋; 븋; ) HANGUL SYLLABLE BYUH
+BE0C;BE0C;1107 1173;BE0C;1107 1173; # (브; 브; 브; 브; 브; ) HANGUL SYLLABLE BEU
+BE0D;BE0D;1107 1173 11A8;BE0D;1107 1173 11A8; # (븍; 븍; 븍; 븍; 븍; ) HANGUL SYLLABLE BEUG
+BE0E;BE0E;1107 1173 11A9;BE0E;1107 1173 11A9; # (븎; 븎; 븎; 븎; 븎; ) HANGUL SYLLABLE BEUGG
+BE0F;BE0F;1107 1173 11AA;BE0F;1107 1173 11AA; # (븏; 븏; 븏; 븏; 븏; ) HANGUL SYLLABLE BEUGS
+BE10;BE10;1107 1173 11AB;BE10;1107 1173 11AB; # (븐; 븐; 븐; 븐; 븐; ) HANGUL SYLLABLE BEUN
+BE11;BE11;1107 1173 11AC;BE11;1107 1173 11AC; # (븑; 븑; 븑; 븑; 븑; ) HANGUL SYLLABLE BEUNJ
+BE12;BE12;1107 1173 11AD;BE12;1107 1173 11AD; # (븒; 븒; 븒; 븒; 븒; ) HANGUL SYLLABLE BEUNH
+BE13;BE13;1107 1173 11AE;BE13;1107 1173 11AE; # (븓; 븓; 븓; 븓; 븓; ) HANGUL SYLLABLE BEUD
+BE14;BE14;1107 1173 11AF;BE14;1107 1173 11AF; # (블; 블; 블; 블; 블; ) HANGUL SYLLABLE BEUL
+BE15;BE15;1107 1173 11B0;BE15;1107 1173 11B0; # (븕; 븕; 븕; 븕; 븕; ) HANGUL SYLLABLE BEULG
+BE16;BE16;1107 1173 11B1;BE16;1107 1173 11B1; # (븖; 븖; 븖; 븖; 븖; ) HANGUL SYLLABLE BEULM
+BE17;BE17;1107 1173 11B2;BE17;1107 1173 11B2; # (븗; 븗; 븗; 븗; 븗; ) HANGUL SYLLABLE BEULB
+BE18;BE18;1107 1173 11B3;BE18;1107 1173 11B3; # (븘; 븘; 븘; 븘; 븘; ) HANGUL SYLLABLE BEULS
+BE19;BE19;1107 1173 11B4;BE19;1107 1173 11B4; # (븙; 븙; 븙; 븙; 븙; ) HANGUL SYLLABLE BEULT
+BE1A;BE1A;1107 1173 11B5;BE1A;1107 1173 11B5; # (븚; 븚; 븚; 븚; 븚; ) HANGUL SYLLABLE BEULP
+BE1B;BE1B;1107 1173 11B6;BE1B;1107 1173 11B6; # (븛; 븛; 븛; 븛; 븛; ) HANGUL SYLLABLE BEULH
+BE1C;BE1C;1107 1173 11B7;BE1C;1107 1173 11B7; # (븜; 븜; 븜; 븜; 븜; ) HANGUL SYLLABLE BEUM
+BE1D;BE1D;1107 1173 11B8;BE1D;1107 1173 11B8; # (븝; 븝; 븝; 븝; 븝; ) HANGUL SYLLABLE BEUB
+BE1E;BE1E;1107 1173 11B9;BE1E;1107 1173 11B9; # (븞; 븞; 븞; 븞; 븞; ) HANGUL SYLLABLE BEUBS
+BE1F;BE1F;1107 1173 11BA;BE1F;1107 1173 11BA; # (븟; 븟; 븟; 븟; 븟; ) HANGUL SYLLABLE BEUS
+BE20;BE20;1107 1173 11BB;BE20;1107 1173 11BB; # (븠; 븠; 븠; 븠; 븠; ) HANGUL SYLLABLE BEUSS
+BE21;BE21;1107 1173 11BC;BE21;1107 1173 11BC; # (븡; 븡; 븡; 븡; 븡; ) HANGUL SYLLABLE BEUNG
+BE22;BE22;1107 1173 11BD;BE22;1107 1173 11BD; # (븢; 븢; 븢; 븢; 븢; ) HANGUL SYLLABLE BEUJ
+BE23;BE23;1107 1173 11BE;BE23;1107 1173 11BE; # (븣; 븣; 븣; 븣; 븣; ) HANGUL SYLLABLE BEUC
+BE24;BE24;1107 1173 11BF;BE24;1107 1173 11BF; # (븤; 븤; 븤; 븤; 븤; ) HANGUL SYLLABLE BEUK
+BE25;BE25;1107 1173 11C0;BE25;1107 1173 11C0; # (븥; 븥; 븥; 븥; 븥; ) HANGUL SYLLABLE BEUT
+BE26;BE26;1107 1173 11C1;BE26;1107 1173 11C1; # (븦; 븦; 븦; 븦; 븦; ) HANGUL SYLLABLE BEUP
+BE27;BE27;1107 1173 11C2;BE27;1107 1173 11C2; # (븧; 븧; 븧; 븧; 븧; ) HANGUL SYLLABLE BEUH
+BE28;BE28;1107 1174;BE28;1107 1174; # (븨; 븨; 븨; 븨; 븨; ) HANGUL SYLLABLE BYI
+BE29;BE29;1107 1174 11A8;BE29;1107 1174 11A8; # (븩; 븩; 븩; 븩; 븩; ) HANGUL SYLLABLE BYIG
+BE2A;BE2A;1107 1174 11A9;BE2A;1107 1174 11A9; # (븪; 븪; 븪; 븪; 븪; ) HANGUL SYLLABLE BYIGG
+BE2B;BE2B;1107 1174 11AA;BE2B;1107 1174 11AA; # (븫; 븫; 븫; 븫; 븫; ) HANGUL SYLLABLE BYIGS
+BE2C;BE2C;1107 1174 11AB;BE2C;1107 1174 11AB; # (븬; 븬; 븬; 븬; 븬; ) HANGUL SYLLABLE BYIN
+BE2D;BE2D;1107 1174 11AC;BE2D;1107 1174 11AC; # (븭; 븭; 븭; 븭; 븭; ) HANGUL SYLLABLE BYINJ
+BE2E;BE2E;1107 1174 11AD;BE2E;1107 1174 11AD; # (븮; 븮; 븮; 븮; 븮; ) HANGUL SYLLABLE BYINH
+BE2F;BE2F;1107 1174 11AE;BE2F;1107 1174 11AE; # (븯; 븯; 븯; 븯; 븯; ) HANGUL SYLLABLE BYID
+BE30;BE30;1107 1174 11AF;BE30;1107 1174 11AF; # (븰; 븰; 븰; 븰; 븰; ) HANGUL SYLLABLE BYIL
+BE31;BE31;1107 1174 11B0;BE31;1107 1174 11B0; # (븱; 븱; 븱; 븱; 븱; ) HANGUL SYLLABLE BYILG
+BE32;BE32;1107 1174 11B1;BE32;1107 1174 11B1; # (븲; 븲; 븲; 븲; 븲; ) HANGUL SYLLABLE BYILM
+BE33;BE33;1107 1174 11B2;BE33;1107 1174 11B2; # (븳; 븳; 븳; 븳; 븳; ) HANGUL SYLLABLE BYILB
+BE34;BE34;1107 1174 11B3;BE34;1107 1174 11B3; # (븴; 븴; 븴; 븴; 븴; ) HANGUL SYLLABLE BYILS
+BE35;BE35;1107 1174 11B4;BE35;1107 1174 11B4; # (븵; 븵; 븵; 븵; 븵; ) HANGUL SYLLABLE BYILT
+BE36;BE36;1107 1174 11B5;BE36;1107 1174 11B5; # (븶; 븶; 븶; 븶; 븶; ) HANGUL SYLLABLE BYILP
+BE37;BE37;1107 1174 11B6;BE37;1107 1174 11B6; # (븷; 븷; 븷; 븷; 븷; ) HANGUL SYLLABLE BYILH
+BE38;BE38;1107 1174 11B7;BE38;1107 1174 11B7; # (븸; 븸; 븸; 븸; 븸; ) HANGUL SYLLABLE BYIM
+BE39;BE39;1107 1174 11B8;BE39;1107 1174 11B8; # (븹; 븹; 븹; 븹; 븹; ) HANGUL SYLLABLE BYIB
+BE3A;BE3A;1107 1174 11B9;BE3A;1107 1174 11B9; # (븺; 븺; 븺; 븺; 븺; ) HANGUL SYLLABLE BYIBS
+BE3B;BE3B;1107 1174 11BA;BE3B;1107 1174 11BA; # (븻; 븻; 븻; 븻; 븻; ) HANGUL SYLLABLE BYIS
+BE3C;BE3C;1107 1174 11BB;BE3C;1107 1174 11BB; # (븼; 븼; 븼; 븼; 븼; ) HANGUL SYLLABLE BYISS
+BE3D;BE3D;1107 1174 11BC;BE3D;1107 1174 11BC; # (븽; 븽; 븽; 븽; 븽; ) HANGUL SYLLABLE BYING
+BE3E;BE3E;1107 1174 11BD;BE3E;1107 1174 11BD; # (븾; 븾; 븾; 븾; 븾; ) HANGUL SYLLABLE BYIJ
+BE3F;BE3F;1107 1174 11BE;BE3F;1107 1174 11BE; # (븿; 븿; 븿; 븿; 븿; ) HANGUL SYLLABLE BYIC
+BE40;BE40;1107 1174 11BF;BE40;1107 1174 11BF; # (빀; 빀; 빀; 빀; 빀; ) HANGUL SYLLABLE BYIK
+BE41;BE41;1107 1174 11C0;BE41;1107 1174 11C0; # (빁; 빁; 빁; 빁; 빁; ) HANGUL SYLLABLE BYIT
+BE42;BE42;1107 1174 11C1;BE42;1107 1174 11C1; # (빂; 빂; 빂; 빂; 빂; ) HANGUL SYLLABLE BYIP
+BE43;BE43;1107 1174 11C2;BE43;1107 1174 11C2; # (빃; 빃; 빃; 빃; 빃; ) HANGUL SYLLABLE BYIH
+BE44;BE44;1107 1175;BE44;1107 1175; # (비; 비; 비; 비; 비; ) HANGUL SYLLABLE BI
+BE45;BE45;1107 1175 11A8;BE45;1107 1175 11A8; # (빅; 빅; 빅; 빅; 빅; ) HANGUL SYLLABLE BIG
+BE46;BE46;1107 1175 11A9;BE46;1107 1175 11A9; # (빆; 빆; 빆; 빆; 빆; ) HANGUL SYLLABLE BIGG
+BE47;BE47;1107 1175 11AA;BE47;1107 1175 11AA; # (빇; 빇; 빇; 빇; 빇; ) HANGUL SYLLABLE BIGS
+BE48;BE48;1107 1175 11AB;BE48;1107 1175 11AB; # (빈; 빈; 빈; 빈; 빈; ) HANGUL SYLLABLE BIN
+BE49;BE49;1107 1175 11AC;BE49;1107 1175 11AC; # (빉; 빉; 빉; 빉; 빉; ) HANGUL SYLLABLE BINJ
+BE4A;BE4A;1107 1175 11AD;BE4A;1107 1175 11AD; # (빊; 빊; 빊; 빊; 빊; ) HANGUL SYLLABLE BINH
+BE4B;BE4B;1107 1175 11AE;BE4B;1107 1175 11AE; # (빋; 빋; 빋; 빋; 빋; ) HANGUL SYLLABLE BID
+BE4C;BE4C;1107 1175 11AF;BE4C;1107 1175 11AF; # (빌; 빌; 빌; 빌; 빌; ) HANGUL SYLLABLE BIL
+BE4D;BE4D;1107 1175 11B0;BE4D;1107 1175 11B0; # (빍; 빍; 빍; 빍; 빍; ) HANGUL SYLLABLE BILG
+BE4E;BE4E;1107 1175 11B1;BE4E;1107 1175 11B1; # (빎; 빎; 빎; 빎; 빎; ) HANGUL SYLLABLE BILM
+BE4F;BE4F;1107 1175 11B2;BE4F;1107 1175 11B2; # (빏; 빏; 빏; 빏; 빏; ) HANGUL SYLLABLE BILB
+BE50;BE50;1107 1175 11B3;BE50;1107 1175 11B3; # (빐; 빐; 빐; 빐; 빐; ) HANGUL SYLLABLE BILS
+BE51;BE51;1107 1175 11B4;BE51;1107 1175 11B4; # (빑; 빑; 빑; 빑; 빑; ) HANGUL SYLLABLE BILT
+BE52;BE52;1107 1175 11B5;BE52;1107 1175 11B5; # (빒; 빒; 빒; 빒; 빒; ) HANGUL SYLLABLE BILP
+BE53;BE53;1107 1175 11B6;BE53;1107 1175 11B6; # (빓; 빓; 빓; 빓; 빓; ) HANGUL SYLLABLE BILH
+BE54;BE54;1107 1175 11B7;BE54;1107 1175 11B7; # (빔; 빔; 빔; 빔; 빔; ) HANGUL SYLLABLE BIM
+BE55;BE55;1107 1175 11B8;BE55;1107 1175 11B8; # (빕; 빕; 빕; 빕; 빕; ) HANGUL SYLLABLE BIB
+BE56;BE56;1107 1175 11B9;BE56;1107 1175 11B9; # (빖; 빖; 빖; 빖; 빖; ) HANGUL SYLLABLE BIBS
+BE57;BE57;1107 1175 11BA;BE57;1107 1175 11BA; # (빗; 빗; 빗; 빗; 빗; ) HANGUL SYLLABLE BIS
+BE58;BE58;1107 1175 11BB;BE58;1107 1175 11BB; # (빘; 빘; 빘; 빘; 빘; ) HANGUL SYLLABLE BISS
+BE59;BE59;1107 1175 11BC;BE59;1107 1175 11BC; # (빙; 빙; 빙; 빙; 빙; ) HANGUL SYLLABLE BING
+BE5A;BE5A;1107 1175 11BD;BE5A;1107 1175 11BD; # (빚; 빚; 빚; 빚; 빚; ) HANGUL SYLLABLE BIJ
+BE5B;BE5B;1107 1175 11BE;BE5B;1107 1175 11BE; # (빛; 빛; 빛; 빛; 빛; ) HANGUL SYLLABLE BIC
+BE5C;BE5C;1107 1175 11BF;BE5C;1107 1175 11BF; # (빜; 빜; 빜; 빜; 빜; ) HANGUL SYLLABLE BIK
+BE5D;BE5D;1107 1175 11C0;BE5D;1107 1175 11C0; # (빝; 빝; 빝; 빝; 빝; ) HANGUL SYLLABLE BIT
+BE5E;BE5E;1107 1175 11C1;BE5E;1107 1175 11C1; # (빞; 빞; 빞; 빞; 빞; ) HANGUL SYLLABLE BIP
+BE5F;BE5F;1107 1175 11C2;BE5F;1107 1175 11C2; # (빟; 빟; 빟; 빟; 빟; ) HANGUL SYLLABLE BIH
+BE60;BE60;1108 1161;BE60;1108 1161; # (빠; 빠; 빠; 빠; 빠; ) HANGUL SYLLABLE BBA
+BE61;BE61;1108 1161 11A8;BE61;1108 1161 11A8; # (빡; 빡; 빡; 빡; 빡; ) HANGUL SYLLABLE BBAG
+BE62;BE62;1108 1161 11A9;BE62;1108 1161 11A9; # (빢; 빢; 빢; 빢; 빢; ) HANGUL SYLLABLE BBAGG
+BE63;BE63;1108 1161 11AA;BE63;1108 1161 11AA; # (빣; 빣; 빣; 빣; 빣; ) HANGUL SYLLABLE BBAGS
+BE64;BE64;1108 1161 11AB;BE64;1108 1161 11AB; # (빤; 빤; 빤; 빤; 빤; ) HANGUL SYLLABLE BBAN
+BE65;BE65;1108 1161 11AC;BE65;1108 1161 11AC; # (빥; 빥; 빥; 빥; 빥; ) HANGUL SYLLABLE BBANJ
+BE66;BE66;1108 1161 11AD;BE66;1108 1161 11AD; # (빦; 빦; 빦; 빦; 빦; ) HANGUL SYLLABLE BBANH
+BE67;BE67;1108 1161 11AE;BE67;1108 1161 11AE; # (빧; 빧; 빧; 빧; 빧; ) HANGUL SYLLABLE BBAD
+BE68;BE68;1108 1161 11AF;BE68;1108 1161 11AF; # (빨; 빨; 빨; 빨; 빨; ) HANGUL SYLLABLE BBAL
+BE69;BE69;1108 1161 11B0;BE69;1108 1161 11B0; # (빩; 빩; 빩; 빩; 빩; ) HANGUL SYLLABLE BBALG
+BE6A;BE6A;1108 1161 11B1;BE6A;1108 1161 11B1; # (빪; 빪; 빪; 빪; 빪; ) HANGUL SYLLABLE BBALM
+BE6B;BE6B;1108 1161 11B2;BE6B;1108 1161 11B2; # (빫; 빫; 빫; 빫; 빫; ) HANGUL SYLLABLE BBALB
+BE6C;BE6C;1108 1161 11B3;BE6C;1108 1161 11B3; # (빬; 빬; 빬; 빬; 빬; ) HANGUL SYLLABLE BBALS
+BE6D;BE6D;1108 1161 11B4;BE6D;1108 1161 11B4; # (빭; 빭; 빭; 빭; 빭; ) HANGUL SYLLABLE BBALT
+BE6E;BE6E;1108 1161 11B5;BE6E;1108 1161 11B5; # (빮; 빮; 빮; 빮; 빮; ) HANGUL SYLLABLE BBALP
+BE6F;BE6F;1108 1161 11B6;BE6F;1108 1161 11B6; # (빯; 빯; 빯; 빯; 빯; ) HANGUL SYLLABLE BBALH
+BE70;BE70;1108 1161 11B7;BE70;1108 1161 11B7; # (빰; 빰; 빰; 빰; 빰; ) HANGUL SYLLABLE BBAM
+BE71;BE71;1108 1161 11B8;BE71;1108 1161 11B8; # (빱; 빱; 빱; 빱; 빱; ) HANGUL SYLLABLE BBAB
+BE72;BE72;1108 1161 11B9;BE72;1108 1161 11B9; # (빲; 빲; 빲; 빲; 빲; ) HANGUL SYLLABLE BBABS
+BE73;BE73;1108 1161 11BA;BE73;1108 1161 11BA; # (빳; 빳; 빳; 빳; 빳; ) HANGUL SYLLABLE BBAS
+BE74;BE74;1108 1161 11BB;BE74;1108 1161 11BB; # (빴; 빴; 빴; 빴; 빴; ) HANGUL SYLLABLE BBASS
+BE75;BE75;1108 1161 11BC;BE75;1108 1161 11BC; # (빵; 빵; 빵; 빵; 빵; ) HANGUL SYLLABLE BBANG
+BE76;BE76;1108 1161 11BD;BE76;1108 1161 11BD; # (빶; 빶; 빶; 빶; 빶; ) HANGUL SYLLABLE BBAJ
+BE77;BE77;1108 1161 11BE;BE77;1108 1161 11BE; # (빷; 빷; 빷; 빷; 빷; ) HANGUL SYLLABLE BBAC
+BE78;BE78;1108 1161 11BF;BE78;1108 1161 11BF; # (빸; 빸; 빸; 빸; 빸; ) HANGUL SYLLABLE BBAK
+BE79;BE79;1108 1161 11C0;BE79;1108 1161 11C0; # (빹; 빹; 빹; 빹; 빹; ) HANGUL SYLLABLE BBAT
+BE7A;BE7A;1108 1161 11C1;BE7A;1108 1161 11C1; # (빺; 빺; 빺; 빺; 빺; ) HANGUL SYLLABLE BBAP
+BE7B;BE7B;1108 1161 11C2;BE7B;1108 1161 11C2; # (빻; 빻; 빻; 빻; 빻; ) HANGUL SYLLABLE BBAH
+BE7C;BE7C;1108 1162;BE7C;1108 1162; # (빼; 빼; 빼; 빼; 빼; ) HANGUL SYLLABLE BBAE
+BE7D;BE7D;1108 1162 11A8;BE7D;1108 1162 11A8; # (빽; 빽; 빽; 빽; 빽; ) HANGUL SYLLABLE BBAEG
+BE7E;BE7E;1108 1162 11A9;BE7E;1108 1162 11A9; # (빾; 빾; 빾; 빾; 빾; ) HANGUL SYLLABLE BBAEGG
+BE7F;BE7F;1108 1162 11AA;BE7F;1108 1162 11AA; # (빿; 빿; 빿; 빿; 빿; ) HANGUL SYLLABLE BBAEGS
+BE80;BE80;1108 1162 11AB;BE80;1108 1162 11AB; # (뺀; 뺀; 뺀; 뺀; 뺀; ) HANGUL SYLLABLE BBAEN
+BE81;BE81;1108 1162 11AC;BE81;1108 1162 11AC; # (뺁; 뺁; 뺁; 뺁; 뺁; ) HANGUL SYLLABLE BBAENJ
+BE82;BE82;1108 1162 11AD;BE82;1108 1162 11AD; # (뺂; 뺂; 뺂; 뺂; 뺂; ) HANGUL SYLLABLE BBAENH
+BE83;BE83;1108 1162 11AE;BE83;1108 1162 11AE; # (뺃; 뺃; 뺃; 뺃; 뺃; ) HANGUL SYLLABLE BBAED
+BE84;BE84;1108 1162 11AF;BE84;1108 1162 11AF; # (뺄; 뺄; 뺄; 뺄; 뺄; ) HANGUL SYLLABLE BBAEL
+BE85;BE85;1108 1162 11B0;BE85;1108 1162 11B0; # (뺅; 뺅; 뺅; 뺅; 뺅; ) HANGUL SYLLABLE BBAELG
+BE86;BE86;1108 1162 11B1;BE86;1108 1162 11B1; # (뺆; 뺆; 뺆; 뺆; 뺆; ) HANGUL SYLLABLE BBAELM
+BE87;BE87;1108 1162 11B2;BE87;1108 1162 11B2; # (뺇; 뺇; 뺇; 뺇; 뺇; ) HANGUL SYLLABLE BBAELB
+BE88;BE88;1108 1162 11B3;BE88;1108 1162 11B3; # (뺈; 뺈; 뺈; 뺈; 뺈; ) HANGUL SYLLABLE BBAELS
+BE89;BE89;1108 1162 11B4;BE89;1108 1162 11B4; # (뺉; 뺉; 뺉; 뺉; 뺉; ) HANGUL SYLLABLE BBAELT
+BE8A;BE8A;1108 1162 11B5;BE8A;1108 1162 11B5; # (뺊; 뺊; 뺊; 뺊; 뺊; ) HANGUL SYLLABLE BBAELP
+BE8B;BE8B;1108 1162 11B6;BE8B;1108 1162 11B6; # (뺋; 뺋; 뺋; 뺋; 뺋; ) HANGUL SYLLABLE BBAELH
+BE8C;BE8C;1108 1162 11B7;BE8C;1108 1162 11B7; # (뺌; 뺌; 뺌; 뺌; 뺌; ) HANGUL SYLLABLE BBAEM
+BE8D;BE8D;1108 1162 11B8;BE8D;1108 1162 11B8; # (뺍; 뺍; 뺍; 뺍; 뺍; ) HANGUL SYLLABLE BBAEB
+BE8E;BE8E;1108 1162 11B9;BE8E;1108 1162 11B9; # (뺎; 뺎; 뺎; 뺎; 뺎; ) HANGUL SYLLABLE BBAEBS
+BE8F;BE8F;1108 1162 11BA;BE8F;1108 1162 11BA; # (뺏; 뺏; 뺏; 뺏; 뺏; ) HANGUL SYLLABLE BBAES
+BE90;BE90;1108 1162 11BB;BE90;1108 1162 11BB; # (뺐; 뺐; 뺐; 뺐; 뺐; ) HANGUL SYLLABLE BBAESS
+BE91;BE91;1108 1162 11BC;BE91;1108 1162 11BC; # (뺑; 뺑; 뺑; 뺑; 뺑; ) HANGUL SYLLABLE BBAENG
+BE92;BE92;1108 1162 11BD;BE92;1108 1162 11BD; # (뺒; 뺒; 뺒; 뺒; 뺒; ) HANGUL SYLLABLE BBAEJ
+BE93;BE93;1108 1162 11BE;BE93;1108 1162 11BE; # (뺓; 뺓; 뺓; 뺓; 뺓; ) HANGUL SYLLABLE BBAEC
+BE94;BE94;1108 1162 11BF;BE94;1108 1162 11BF; # (뺔; 뺔; 뺔; 뺔; 뺔; ) HANGUL SYLLABLE BBAEK
+BE95;BE95;1108 1162 11C0;BE95;1108 1162 11C0; # (뺕; 뺕; 뺕; 뺕; 뺕; ) HANGUL SYLLABLE BBAET
+BE96;BE96;1108 1162 11C1;BE96;1108 1162 11C1; # (뺖; 뺖; 뺖; 뺖; 뺖; ) HANGUL SYLLABLE BBAEP
+BE97;BE97;1108 1162 11C2;BE97;1108 1162 11C2; # (뺗; 뺗; 뺗; 뺗; 뺗; ) HANGUL SYLLABLE BBAEH
+BE98;BE98;1108 1163;BE98;1108 1163; # (뺘; 뺘; 뺘; 뺘; 뺘; ) HANGUL SYLLABLE BBYA
+BE99;BE99;1108 1163 11A8;BE99;1108 1163 11A8; # (뺙; 뺙; 뺙; 뺙; 뺙; ) HANGUL SYLLABLE BBYAG
+BE9A;BE9A;1108 1163 11A9;BE9A;1108 1163 11A9; # (뺚; 뺚; 뺚; 뺚; 뺚; ) HANGUL SYLLABLE BBYAGG
+BE9B;BE9B;1108 1163 11AA;BE9B;1108 1163 11AA; # (뺛; 뺛; 뺛; 뺛; 뺛; ) HANGUL SYLLABLE BBYAGS
+BE9C;BE9C;1108 1163 11AB;BE9C;1108 1163 11AB; # (뺜; 뺜; 뺜; 뺜; 뺜; ) HANGUL SYLLABLE BBYAN
+BE9D;BE9D;1108 1163 11AC;BE9D;1108 1163 11AC; # (뺝; 뺝; 뺝; 뺝; 뺝; ) HANGUL SYLLABLE BBYANJ
+BE9E;BE9E;1108 1163 11AD;BE9E;1108 1163 11AD; # (뺞; 뺞; 뺞; 뺞; 뺞; ) HANGUL SYLLABLE BBYANH
+BE9F;BE9F;1108 1163 11AE;BE9F;1108 1163 11AE; # (뺟; 뺟; 뺟; 뺟; 뺟; ) HANGUL SYLLABLE BBYAD
+BEA0;BEA0;1108 1163 11AF;BEA0;1108 1163 11AF; # (뺠; 뺠; 뺠; 뺠; 뺠; ) HANGUL SYLLABLE BBYAL
+BEA1;BEA1;1108 1163 11B0;BEA1;1108 1163 11B0; # (뺡; 뺡; 뺡; 뺡; 뺡; ) HANGUL SYLLABLE BBYALG
+BEA2;BEA2;1108 1163 11B1;BEA2;1108 1163 11B1; # (뺢; 뺢; 뺢; 뺢; 뺢; ) HANGUL SYLLABLE BBYALM
+BEA3;BEA3;1108 1163 11B2;BEA3;1108 1163 11B2; # (뺣; 뺣; 뺣; 뺣; 뺣; ) HANGUL SYLLABLE BBYALB
+BEA4;BEA4;1108 1163 11B3;BEA4;1108 1163 11B3; # (뺤; 뺤; 뺤; 뺤; 뺤; ) HANGUL SYLLABLE BBYALS
+BEA5;BEA5;1108 1163 11B4;BEA5;1108 1163 11B4; # (뺥; 뺥; 뺥; 뺥; 뺥; ) HANGUL SYLLABLE BBYALT
+BEA6;BEA6;1108 1163 11B5;BEA6;1108 1163 11B5; # (뺦; 뺦; 뺦; 뺦; 뺦; ) HANGUL SYLLABLE BBYALP
+BEA7;BEA7;1108 1163 11B6;BEA7;1108 1163 11B6; # (뺧; 뺧; 뺧; 뺧; 뺧; ) HANGUL SYLLABLE BBYALH
+BEA8;BEA8;1108 1163 11B7;BEA8;1108 1163 11B7; # (뺨; 뺨; 뺨; 뺨; 뺨; ) HANGUL SYLLABLE BBYAM
+BEA9;BEA9;1108 1163 11B8;BEA9;1108 1163 11B8; # (뺩; 뺩; 뺩; 뺩; 뺩; ) HANGUL SYLLABLE BBYAB
+BEAA;BEAA;1108 1163 11B9;BEAA;1108 1163 11B9; # (뺪; 뺪; 뺪; 뺪; 뺪; ) HANGUL SYLLABLE BBYABS
+BEAB;BEAB;1108 1163 11BA;BEAB;1108 1163 11BA; # (뺫; 뺫; 뺫; 뺫; 뺫; ) HANGUL SYLLABLE BBYAS
+BEAC;BEAC;1108 1163 11BB;BEAC;1108 1163 11BB; # (뺬; 뺬; 뺬; 뺬; 뺬; ) HANGUL SYLLABLE BBYASS
+BEAD;BEAD;1108 1163 11BC;BEAD;1108 1163 11BC; # (뺭; 뺭; 뺭; 뺭; 뺭; ) HANGUL SYLLABLE BBYANG
+BEAE;BEAE;1108 1163 11BD;BEAE;1108 1163 11BD; # (뺮; 뺮; 뺮; 뺮; 뺮; ) HANGUL SYLLABLE BBYAJ
+BEAF;BEAF;1108 1163 11BE;BEAF;1108 1163 11BE; # (뺯; 뺯; 뺯; 뺯; 뺯; ) HANGUL SYLLABLE BBYAC
+BEB0;BEB0;1108 1163 11BF;BEB0;1108 1163 11BF; # (뺰; 뺰; 뺰; 뺰; 뺰; ) HANGUL SYLLABLE BBYAK
+BEB1;BEB1;1108 1163 11C0;BEB1;1108 1163 11C0; # (뺱; 뺱; 뺱; 뺱; 뺱; ) HANGUL SYLLABLE BBYAT
+BEB2;BEB2;1108 1163 11C1;BEB2;1108 1163 11C1; # (뺲; 뺲; 뺲; 뺲; 뺲; ) HANGUL SYLLABLE BBYAP
+BEB3;BEB3;1108 1163 11C2;BEB3;1108 1163 11C2; # (뺳; 뺳; 뺳; 뺳; 뺳; ) HANGUL SYLLABLE BBYAH
+BEB4;BEB4;1108 1164;BEB4;1108 1164; # (뺴; 뺴; 뺴; 뺴; 뺴; ) HANGUL SYLLABLE BBYAE
+BEB5;BEB5;1108 1164 11A8;BEB5;1108 1164 11A8; # (뺵; 뺵; 뺵; 뺵; 뺵; ) HANGUL SYLLABLE BBYAEG
+BEB6;BEB6;1108 1164 11A9;BEB6;1108 1164 11A9; # (뺶; 뺶; 뺶; 뺶; 뺶; ) HANGUL SYLLABLE BBYAEGG
+BEB7;BEB7;1108 1164 11AA;BEB7;1108 1164 11AA; # (뺷; 뺷; 뺷; 뺷; 뺷; ) HANGUL SYLLABLE BBYAEGS
+BEB8;BEB8;1108 1164 11AB;BEB8;1108 1164 11AB; # (뺸; 뺸; 뺸; 뺸; 뺸; ) HANGUL SYLLABLE BBYAEN
+BEB9;BEB9;1108 1164 11AC;BEB9;1108 1164 11AC; # (뺹; 뺹; 뺹; 뺹; 뺹; ) HANGUL SYLLABLE BBYAENJ
+BEBA;BEBA;1108 1164 11AD;BEBA;1108 1164 11AD; # (뺺; 뺺; 뺺; 뺺; 뺺; ) HANGUL SYLLABLE BBYAENH
+BEBB;BEBB;1108 1164 11AE;BEBB;1108 1164 11AE; # (뺻; 뺻; 뺻; 뺻; 뺻; ) HANGUL SYLLABLE BBYAED
+BEBC;BEBC;1108 1164 11AF;BEBC;1108 1164 11AF; # (뺼; 뺼; 뺼; 뺼; 뺼; ) HANGUL SYLLABLE BBYAEL
+BEBD;BEBD;1108 1164 11B0;BEBD;1108 1164 11B0; # (뺽; 뺽; 뺽; 뺽; 뺽; ) HANGUL SYLLABLE BBYAELG
+BEBE;BEBE;1108 1164 11B1;BEBE;1108 1164 11B1; # (뺾; 뺾; 뺾; 뺾; 뺾; ) HANGUL SYLLABLE BBYAELM
+BEBF;BEBF;1108 1164 11B2;BEBF;1108 1164 11B2; # (뺿; 뺿; 뺿; 뺿; 뺿; ) HANGUL SYLLABLE BBYAELB
+BEC0;BEC0;1108 1164 11B3;BEC0;1108 1164 11B3; # (뻀; 뻀; 뻀; 뻀; 뻀; ) HANGUL SYLLABLE BBYAELS
+BEC1;BEC1;1108 1164 11B4;BEC1;1108 1164 11B4; # (뻁; 뻁; 뻁; 뻁; 뻁; ) HANGUL SYLLABLE BBYAELT
+BEC2;BEC2;1108 1164 11B5;BEC2;1108 1164 11B5; # (뻂; 뻂; 뻂; 뻂; 뻂; ) HANGUL SYLLABLE BBYAELP
+BEC3;BEC3;1108 1164 11B6;BEC3;1108 1164 11B6; # (뻃; 뻃; 뻃; 뻃; 뻃; ) HANGUL SYLLABLE BBYAELH
+BEC4;BEC4;1108 1164 11B7;BEC4;1108 1164 11B7; # (뻄; 뻄; 뻄; 뻄; 뻄; ) HANGUL SYLLABLE BBYAEM
+BEC5;BEC5;1108 1164 11B8;BEC5;1108 1164 11B8; # (뻅; 뻅; 뻅; 뻅; 뻅; ) HANGUL SYLLABLE BBYAEB
+BEC6;BEC6;1108 1164 11B9;BEC6;1108 1164 11B9; # (뻆; 뻆; 뻆; 뻆; 뻆; ) HANGUL SYLLABLE BBYAEBS
+BEC7;BEC7;1108 1164 11BA;BEC7;1108 1164 11BA; # (뻇; 뻇; 뻇; 뻇; 뻇; ) HANGUL SYLLABLE BBYAES
+BEC8;BEC8;1108 1164 11BB;BEC8;1108 1164 11BB; # (뻈; 뻈; 뻈; 뻈; 뻈; ) HANGUL SYLLABLE BBYAESS
+BEC9;BEC9;1108 1164 11BC;BEC9;1108 1164 11BC; # (뻉; 뻉; 뻉; 뻉; 뻉; ) HANGUL SYLLABLE BBYAENG
+BECA;BECA;1108 1164 11BD;BECA;1108 1164 11BD; # (뻊; 뻊; 뻊; 뻊; 뻊; ) HANGUL SYLLABLE BBYAEJ
+BECB;BECB;1108 1164 11BE;BECB;1108 1164 11BE; # (뻋; 뻋; 뻋; 뻋; 뻋; ) HANGUL SYLLABLE BBYAEC
+BECC;BECC;1108 1164 11BF;BECC;1108 1164 11BF; # (뻌; 뻌; 뻌; 뻌; 뻌; ) HANGUL SYLLABLE BBYAEK
+BECD;BECD;1108 1164 11C0;BECD;1108 1164 11C0; # (뻍; 뻍; 뻍; 뻍; 뻍; ) HANGUL SYLLABLE BBYAET
+BECE;BECE;1108 1164 11C1;BECE;1108 1164 11C1; # (뻎; 뻎; 뻎; 뻎; 뻎; ) HANGUL SYLLABLE BBYAEP
+BECF;BECF;1108 1164 11C2;BECF;1108 1164 11C2; # (뻏; 뻏; 뻏; 뻏; 뻏; ) HANGUL SYLLABLE BBYAEH
+BED0;BED0;1108 1165;BED0;1108 1165; # (뻐; 뻐; 뻐; 뻐; 뻐; ) HANGUL SYLLABLE BBEO
+BED1;BED1;1108 1165 11A8;BED1;1108 1165 11A8; # (뻑; 뻑; 뻑; 뻑; 뻑; ) HANGUL SYLLABLE BBEOG
+BED2;BED2;1108 1165 11A9;BED2;1108 1165 11A9; # (뻒; 뻒; 뻒; 뻒; 뻒; ) HANGUL SYLLABLE BBEOGG
+BED3;BED3;1108 1165 11AA;BED3;1108 1165 11AA; # (뻓; 뻓; 뻓; 뻓; 뻓; ) HANGUL SYLLABLE BBEOGS
+BED4;BED4;1108 1165 11AB;BED4;1108 1165 11AB; # (뻔; 뻔; 뻔; 뻔; 뻔; ) HANGUL SYLLABLE BBEON
+BED5;BED5;1108 1165 11AC;BED5;1108 1165 11AC; # (뻕; 뻕; 뻕; 뻕; 뻕; ) HANGUL SYLLABLE BBEONJ
+BED6;BED6;1108 1165 11AD;BED6;1108 1165 11AD; # (뻖; 뻖; 뻖; 뻖; 뻖; ) HANGUL SYLLABLE BBEONH
+BED7;BED7;1108 1165 11AE;BED7;1108 1165 11AE; # (뻗; 뻗; 뻗; 뻗; 뻗; ) HANGUL SYLLABLE BBEOD
+BED8;BED8;1108 1165 11AF;BED8;1108 1165 11AF; # (뻘; 뻘; 뻘; 뻘; 뻘; ) HANGUL SYLLABLE BBEOL
+BED9;BED9;1108 1165 11B0;BED9;1108 1165 11B0; # (뻙; 뻙; 뻙; 뻙; 뻙; ) HANGUL SYLLABLE BBEOLG
+BEDA;BEDA;1108 1165 11B1;BEDA;1108 1165 11B1; # (뻚; 뻚; 뻚; 뻚; 뻚; ) HANGUL SYLLABLE BBEOLM
+BEDB;BEDB;1108 1165 11B2;BEDB;1108 1165 11B2; # (뻛; 뻛; 뻛; 뻛; 뻛; ) HANGUL SYLLABLE BBEOLB
+BEDC;BEDC;1108 1165 11B3;BEDC;1108 1165 11B3; # (뻜; 뻜; 뻜; 뻜; 뻜; ) HANGUL SYLLABLE BBEOLS
+BEDD;BEDD;1108 1165 11B4;BEDD;1108 1165 11B4; # (뻝; 뻝; 뻝; 뻝; 뻝; ) HANGUL SYLLABLE BBEOLT
+BEDE;BEDE;1108 1165 11B5;BEDE;1108 1165 11B5; # (뻞; 뻞; 뻞; 뻞; 뻞; ) HANGUL SYLLABLE BBEOLP
+BEDF;BEDF;1108 1165 11B6;BEDF;1108 1165 11B6; # (뻟; 뻟; 뻟; 뻟; 뻟; ) HANGUL SYLLABLE BBEOLH
+BEE0;BEE0;1108 1165 11B7;BEE0;1108 1165 11B7; # (뻠; 뻠; 뻠; 뻠; 뻠; ) HANGUL SYLLABLE BBEOM
+BEE1;BEE1;1108 1165 11B8;BEE1;1108 1165 11B8; # (뻡; 뻡; 뻡; 뻡; 뻡; ) HANGUL SYLLABLE BBEOB
+BEE2;BEE2;1108 1165 11B9;BEE2;1108 1165 11B9; # (뻢; 뻢; 뻢; 뻢; 뻢; ) HANGUL SYLLABLE BBEOBS
+BEE3;BEE3;1108 1165 11BA;BEE3;1108 1165 11BA; # (뻣; 뻣; 뻣; 뻣; 뻣; ) HANGUL SYLLABLE BBEOS
+BEE4;BEE4;1108 1165 11BB;BEE4;1108 1165 11BB; # (뻤; 뻤; 뻤; 뻤; 뻤; ) HANGUL SYLLABLE BBEOSS
+BEE5;BEE5;1108 1165 11BC;BEE5;1108 1165 11BC; # (뻥; 뻥; 뻥; 뻥; 뻥; ) HANGUL SYLLABLE BBEONG
+BEE6;BEE6;1108 1165 11BD;BEE6;1108 1165 11BD; # (뻦; 뻦; 뻦; 뻦; 뻦; ) HANGUL SYLLABLE BBEOJ
+BEE7;BEE7;1108 1165 11BE;BEE7;1108 1165 11BE; # (뻧; 뻧; 뻧; 뻧; 뻧; ) HANGUL SYLLABLE BBEOC
+BEE8;BEE8;1108 1165 11BF;BEE8;1108 1165 11BF; # (뻨; 뻨; 뻨; 뻨; 뻨; ) HANGUL SYLLABLE BBEOK
+BEE9;BEE9;1108 1165 11C0;BEE9;1108 1165 11C0; # (뻩; 뻩; 뻩; 뻩; 뻩; ) HANGUL SYLLABLE BBEOT
+BEEA;BEEA;1108 1165 11C1;BEEA;1108 1165 11C1; # (뻪; 뻪; 뻪; 뻪; 뻪; ) HANGUL SYLLABLE BBEOP
+BEEB;BEEB;1108 1165 11C2;BEEB;1108 1165 11C2; # (뻫; 뻫; 뻫; 뻫; 뻫; ) HANGUL SYLLABLE BBEOH
+BEEC;BEEC;1108 1166;BEEC;1108 1166; # (뻬; 뻬; 뻬; 뻬; 뻬; ) HANGUL SYLLABLE BBE
+BEED;BEED;1108 1166 11A8;BEED;1108 1166 11A8; # (뻭; 뻭; 뻭; 뻭; 뻭; ) HANGUL SYLLABLE BBEG
+BEEE;BEEE;1108 1166 11A9;BEEE;1108 1166 11A9; # (뻮; 뻮; 뻮; 뻮; 뻮; ) HANGUL SYLLABLE BBEGG
+BEEF;BEEF;1108 1166 11AA;BEEF;1108 1166 11AA; # (뻯; 뻯; 뻯; 뻯; 뻯; ) HANGUL SYLLABLE BBEGS
+BEF0;BEF0;1108 1166 11AB;BEF0;1108 1166 11AB; # (뻰; 뻰; 뻰; 뻰; 뻰; ) HANGUL SYLLABLE BBEN
+BEF1;BEF1;1108 1166 11AC;BEF1;1108 1166 11AC; # (뻱; 뻱; 뻱; 뻱; 뻱; ) HANGUL SYLLABLE BBENJ
+BEF2;BEF2;1108 1166 11AD;BEF2;1108 1166 11AD; # (뻲; 뻲; 뻲; 뻲; 뻲; ) HANGUL SYLLABLE BBENH
+BEF3;BEF3;1108 1166 11AE;BEF3;1108 1166 11AE; # (뻳; 뻳; 뻳; 뻳; 뻳; ) HANGUL SYLLABLE BBED
+BEF4;BEF4;1108 1166 11AF;BEF4;1108 1166 11AF; # (뻴; 뻴; 뻴; 뻴; 뻴; ) HANGUL SYLLABLE BBEL
+BEF5;BEF5;1108 1166 11B0;BEF5;1108 1166 11B0; # (뻵; 뻵; 뻵; 뻵; 뻵; ) HANGUL SYLLABLE BBELG
+BEF6;BEF6;1108 1166 11B1;BEF6;1108 1166 11B1; # (뻶; 뻶; 뻶; 뻶; 뻶; ) HANGUL SYLLABLE BBELM
+BEF7;BEF7;1108 1166 11B2;BEF7;1108 1166 11B2; # (뻷; 뻷; 뻷; 뻷; 뻷; ) HANGUL SYLLABLE BBELB
+BEF8;BEF8;1108 1166 11B3;BEF8;1108 1166 11B3; # (뻸; 뻸; 뻸; 뻸; 뻸; ) HANGUL SYLLABLE BBELS
+BEF9;BEF9;1108 1166 11B4;BEF9;1108 1166 11B4; # (뻹; 뻹; 뻹; 뻹; 뻹; ) HANGUL SYLLABLE BBELT
+BEFA;BEFA;1108 1166 11B5;BEFA;1108 1166 11B5; # (뻺; 뻺; 뻺; 뻺; 뻺; ) HANGUL SYLLABLE BBELP
+BEFB;BEFB;1108 1166 11B6;BEFB;1108 1166 11B6; # (뻻; 뻻; 뻻; 뻻; 뻻; ) HANGUL SYLLABLE BBELH
+BEFC;BEFC;1108 1166 11B7;BEFC;1108 1166 11B7; # (뻼; 뻼; 뻼; 뻼; 뻼; ) HANGUL SYLLABLE BBEM
+BEFD;BEFD;1108 1166 11B8;BEFD;1108 1166 11B8; # (뻽; 뻽; 뻽; 뻽; 뻽; ) HANGUL SYLLABLE BBEB
+BEFE;BEFE;1108 1166 11B9;BEFE;1108 1166 11B9; # (뻾; 뻾; 뻾; 뻾; 뻾; ) HANGUL SYLLABLE BBEBS
+BEFF;BEFF;1108 1166 11BA;BEFF;1108 1166 11BA; # (뻿; 뻿; 뻿; 뻿; 뻿; ) HANGUL SYLLABLE BBES
+BF00;BF00;1108 1166 11BB;BF00;1108 1166 11BB; # (뼀; 뼀; 뼀; 뼀; 뼀; ) HANGUL SYLLABLE BBESS
+BF01;BF01;1108 1166 11BC;BF01;1108 1166 11BC; # (뼁; 뼁; 뼁; 뼁; 뼁; ) HANGUL SYLLABLE BBENG
+BF02;BF02;1108 1166 11BD;BF02;1108 1166 11BD; # (뼂; 뼂; 뼂; 뼂; 뼂; ) HANGUL SYLLABLE BBEJ
+BF03;BF03;1108 1166 11BE;BF03;1108 1166 11BE; # (뼃; 뼃; 뼃; 뼃; 뼃; ) HANGUL SYLLABLE BBEC
+BF04;BF04;1108 1166 11BF;BF04;1108 1166 11BF; # (뼄; 뼄; 뼄; 뼄; 뼄; ) HANGUL SYLLABLE BBEK
+BF05;BF05;1108 1166 11C0;BF05;1108 1166 11C0; # (뼅; 뼅; 뼅; 뼅; 뼅; ) HANGUL SYLLABLE BBET
+BF06;BF06;1108 1166 11C1;BF06;1108 1166 11C1; # (뼆; 뼆; 뼆; 뼆; 뼆; ) HANGUL SYLLABLE BBEP
+BF07;BF07;1108 1166 11C2;BF07;1108 1166 11C2; # (뼇; 뼇; 뼇; 뼇; 뼇; ) HANGUL SYLLABLE BBEH
+BF08;BF08;1108 1167;BF08;1108 1167; # (뼈; 뼈; 뼈; 뼈; 뼈; ) HANGUL SYLLABLE BBYEO
+BF09;BF09;1108 1167 11A8;BF09;1108 1167 11A8; # (뼉; 뼉; 뼉; 뼉; 뼉; ) HANGUL SYLLABLE BBYEOG
+BF0A;BF0A;1108 1167 11A9;BF0A;1108 1167 11A9; # (뼊; 뼊; 뼊; 뼊; 뼊; ) HANGUL SYLLABLE BBYEOGG
+BF0B;BF0B;1108 1167 11AA;BF0B;1108 1167 11AA; # (뼋; 뼋; 뼋; 뼋; 뼋; ) HANGUL SYLLABLE BBYEOGS
+BF0C;BF0C;1108 1167 11AB;BF0C;1108 1167 11AB; # (뼌; 뼌; 뼌; 뼌; 뼌; ) HANGUL SYLLABLE BBYEON
+BF0D;BF0D;1108 1167 11AC;BF0D;1108 1167 11AC; # (뼍; 뼍; 뼍; 뼍; 뼍; ) HANGUL SYLLABLE BBYEONJ
+BF0E;BF0E;1108 1167 11AD;BF0E;1108 1167 11AD; # (뼎; 뼎; 뼎; 뼎; 뼎; ) HANGUL SYLLABLE BBYEONH
+BF0F;BF0F;1108 1167 11AE;BF0F;1108 1167 11AE; # (뼏; 뼏; 뼏; 뼏; 뼏; ) HANGUL SYLLABLE BBYEOD
+BF10;BF10;1108 1167 11AF;BF10;1108 1167 11AF; # (뼐; 뼐; 뼐; 뼐; 뼐; ) HANGUL SYLLABLE BBYEOL
+BF11;BF11;1108 1167 11B0;BF11;1108 1167 11B0; # (뼑; 뼑; 뼑; 뼑; 뼑; ) HANGUL SYLLABLE BBYEOLG
+BF12;BF12;1108 1167 11B1;BF12;1108 1167 11B1; # (뼒; 뼒; 뼒; 뼒; 뼒; ) HANGUL SYLLABLE BBYEOLM
+BF13;BF13;1108 1167 11B2;BF13;1108 1167 11B2; # (뼓; 뼓; 뼓; 뼓; 뼓; ) HANGUL SYLLABLE BBYEOLB
+BF14;BF14;1108 1167 11B3;BF14;1108 1167 11B3; # (뼔; 뼔; 뼔; 뼔; 뼔; ) HANGUL SYLLABLE BBYEOLS
+BF15;BF15;1108 1167 11B4;BF15;1108 1167 11B4; # (뼕; 뼕; 뼕; 뼕; 뼕; ) HANGUL SYLLABLE BBYEOLT
+BF16;BF16;1108 1167 11B5;BF16;1108 1167 11B5; # (뼖; 뼖; 뼖; 뼖; 뼖; ) HANGUL SYLLABLE BBYEOLP
+BF17;BF17;1108 1167 11B6;BF17;1108 1167 11B6; # (뼗; 뼗; 뼗; 뼗; 뼗; ) HANGUL SYLLABLE BBYEOLH
+BF18;BF18;1108 1167 11B7;BF18;1108 1167 11B7; # (뼘; 뼘; 뼘; 뼘; 뼘; ) HANGUL SYLLABLE BBYEOM
+BF19;BF19;1108 1167 11B8;BF19;1108 1167 11B8; # (뼙; 뼙; 뼙; 뼙; 뼙; ) HANGUL SYLLABLE BBYEOB
+BF1A;BF1A;1108 1167 11B9;BF1A;1108 1167 11B9; # (뼚; 뼚; 뼚; 뼚; 뼚; ) HANGUL SYLLABLE BBYEOBS
+BF1B;BF1B;1108 1167 11BA;BF1B;1108 1167 11BA; # (뼛; 뼛; 뼛; 뼛; 뼛; ) HANGUL SYLLABLE BBYEOS
+BF1C;BF1C;1108 1167 11BB;BF1C;1108 1167 11BB; # (뼜; 뼜; 뼜; 뼜; 뼜; ) HANGUL SYLLABLE BBYEOSS
+BF1D;BF1D;1108 1167 11BC;BF1D;1108 1167 11BC; # (뼝; 뼝; 뼝; 뼝; 뼝; ) HANGUL SYLLABLE BBYEONG
+BF1E;BF1E;1108 1167 11BD;BF1E;1108 1167 11BD; # (뼞; 뼞; 뼞; 뼞; 뼞; ) HANGUL SYLLABLE BBYEOJ
+BF1F;BF1F;1108 1167 11BE;BF1F;1108 1167 11BE; # (뼟; 뼟; 뼟; 뼟; 뼟; ) HANGUL SYLLABLE BBYEOC
+BF20;BF20;1108 1167 11BF;BF20;1108 1167 11BF; # (뼠; 뼠; 뼠; 뼠; 뼠; ) HANGUL SYLLABLE BBYEOK
+BF21;BF21;1108 1167 11C0;BF21;1108 1167 11C0; # (뼡; 뼡; 뼡; 뼡; 뼡; ) HANGUL SYLLABLE BBYEOT
+BF22;BF22;1108 1167 11C1;BF22;1108 1167 11C1; # (뼢; 뼢; 뼢; 뼢; 뼢; ) HANGUL SYLLABLE BBYEOP
+BF23;BF23;1108 1167 11C2;BF23;1108 1167 11C2; # (뼣; 뼣; 뼣; 뼣; 뼣; ) HANGUL SYLLABLE BBYEOH
+BF24;BF24;1108 1168;BF24;1108 1168; # (뼤; 뼤; 뼤; 뼤; 뼤; ) HANGUL SYLLABLE BBYE
+BF25;BF25;1108 1168 11A8;BF25;1108 1168 11A8; # (뼥; 뼥; 뼥; 뼥; 뼥; ) HANGUL SYLLABLE BBYEG
+BF26;BF26;1108 1168 11A9;BF26;1108 1168 11A9; # (뼦; 뼦; 뼦; 뼦; 뼦; ) HANGUL SYLLABLE BBYEGG
+BF27;BF27;1108 1168 11AA;BF27;1108 1168 11AA; # (뼧; 뼧; 뼧; 뼧; 뼧; ) HANGUL SYLLABLE BBYEGS
+BF28;BF28;1108 1168 11AB;BF28;1108 1168 11AB; # (뼨; 뼨; 뼨; 뼨; 뼨; ) HANGUL SYLLABLE BBYEN
+BF29;BF29;1108 1168 11AC;BF29;1108 1168 11AC; # (뼩; 뼩; 뼩; 뼩; 뼩; ) HANGUL SYLLABLE BBYENJ
+BF2A;BF2A;1108 1168 11AD;BF2A;1108 1168 11AD; # (뼪; 뼪; 뼪; 뼪; 뼪; ) HANGUL SYLLABLE BBYENH
+BF2B;BF2B;1108 1168 11AE;BF2B;1108 1168 11AE; # (뼫; 뼫; 뼫; 뼫; 뼫; ) HANGUL SYLLABLE BBYED
+BF2C;BF2C;1108 1168 11AF;BF2C;1108 1168 11AF; # (뼬; 뼬; 뼬; 뼬; 뼬; ) HANGUL SYLLABLE BBYEL
+BF2D;BF2D;1108 1168 11B0;BF2D;1108 1168 11B0; # (뼭; 뼭; 뼭; 뼭; 뼭; ) HANGUL SYLLABLE BBYELG
+BF2E;BF2E;1108 1168 11B1;BF2E;1108 1168 11B1; # (뼮; 뼮; 뼮; 뼮; 뼮; ) HANGUL SYLLABLE BBYELM
+BF2F;BF2F;1108 1168 11B2;BF2F;1108 1168 11B2; # (뼯; 뼯; 뼯; 뼯; 뼯; ) HANGUL SYLLABLE BBYELB
+BF30;BF30;1108 1168 11B3;BF30;1108 1168 11B3; # (뼰; 뼰; 뼰; 뼰; 뼰; ) HANGUL SYLLABLE BBYELS
+BF31;BF31;1108 1168 11B4;BF31;1108 1168 11B4; # (뼱; 뼱; 뼱; 뼱; 뼱; ) HANGUL SYLLABLE BBYELT
+BF32;BF32;1108 1168 11B5;BF32;1108 1168 11B5; # (뼲; 뼲; 뼲; 뼲; 뼲; ) HANGUL SYLLABLE BBYELP
+BF33;BF33;1108 1168 11B6;BF33;1108 1168 11B6; # (뼳; 뼳; 뼳; 뼳; 뼳; ) HANGUL SYLLABLE BBYELH
+BF34;BF34;1108 1168 11B7;BF34;1108 1168 11B7; # (뼴; 뼴; 뼴; 뼴; 뼴; ) HANGUL SYLLABLE BBYEM
+BF35;BF35;1108 1168 11B8;BF35;1108 1168 11B8; # (뼵; 뼵; 뼵; 뼵; 뼵; ) HANGUL SYLLABLE BBYEB
+BF36;BF36;1108 1168 11B9;BF36;1108 1168 11B9; # (뼶; 뼶; 뼶; 뼶; 뼶; ) HANGUL SYLLABLE BBYEBS
+BF37;BF37;1108 1168 11BA;BF37;1108 1168 11BA; # (뼷; 뼷; 뼷; 뼷; 뼷; ) HANGUL SYLLABLE BBYES
+BF38;BF38;1108 1168 11BB;BF38;1108 1168 11BB; # (뼸; 뼸; 뼸; 뼸; 뼸; ) HANGUL SYLLABLE BBYESS
+BF39;BF39;1108 1168 11BC;BF39;1108 1168 11BC; # (뼹; 뼹; 뼹; 뼹; 뼹; ) HANGUL SYLLABLE BBYENG
+BF3A;BF3A;1108 1168 11BD;BF3A;1108 1168 11BD; # (뼺; 뼺; 뼺; 뼺; 뼺; ) HANGUL SYLLABLE BBYEJ
+BF3B;BF3B;1108 1168 11BE;BF3B;1108 1168 11BE; # (뼻; 뼻; 뼻; 뼻; 뼻; ) HANGUL SYLLABLE BBYEC
+BF3C;BF3C;1108 1168 11BF;BF3C;1108 1168 11BF; # (뼼; 뼼; 뼼; 뼼; 뼼; ) HANGUL SYLLABLE BBYEK
+BF3D;BF3D;1108 1168 11C0;BF3D;1108 1168 11C0; # (뼽; 뼽; 뼽; 뼽; 뼽; ) HANGUL SYLLABLE BBYET
+BF3E;BF3E;1108 1168 11C1;BF3E;1108 1168 11C1; # (뼾; 뼾; 뼾; 뼾; 뼾; ) HANGUL SYLLABLE BBYEP
+BF3F;BF3F;1108 1168 11C2;BF3F;1108 1168 11C2; # (뼿; 뼿; 뼿; 뼿; 뼿; ) HANGUL SYLLABLE BBYEH
+BF40;BF40;1108 1169;BF40;1108 1169; # (뽀; 뽀; 뽀; 뽀; 뽀; ) HANGUL SYLLABLE BBO
+BF41;BF41;1108 1169 11A8;BF41;1108 1169 11A8; # (뽁; 뽁; 뽁; 뽁; 뽁; ) HANGUL SYLLABLE BBOG
+BF42;BF42;1108 1169 11A9;BF42;1108 1169 11A9; # (뽂; 뽂; 뽂; 뽂; 뽂; ) HANGUL SYLLABLE BBOGG
+BF43;BF43;1108 1169 11AA;BF43;1108 1169 11AA; # (뽃; 뽃; 뽃; 뽃; 뽃; ) HANGUL SYLLABLE BBOGS
+BF44;BF44;1108 1169 11AB;BF44;1108 1169 11AB; # (뽄; 뽄; 뽄; 뽄; 뽄; ) HANGUL SYLLABLE BBON
+BF45;BF45;1108 1169 11AC;BF45;1108 1169 11AC; # (뽅; 뽅; 뽅; 뽅; 뽅; ) HANGUL SYLLABLE BBONJ
+BF46;BF46;1108 1169 11AD;BF46;1108 1169 11AD; # (뽆; 뽆; 뽆; 뽆; 뽆; ) HANGUL SYLLABLE BBONH
+BF47;BF47;1108 1169 11AE;BF47;1108 1169 11AE; # (뽇; 뽇; 뽇; 뽇; 뽇; ) HANGUL SYLLABLE BBOD
+BF48;BF48;1108 1169 11AF;BF48;1108 1169 11AF; # (뽈; 뽈; 뽈; 뽈; 뽈; ) HANGUL SYLLABLE BBOL
+BF49;BF49;1108 1169 11B0;BF49;1108 1169 11B0; # (뽉; 뽉; 뽉; 뽉; 뽉; ) HANGUL SYLLABLE BBOLG
+BF4A;BF4A;1108 1169 11B1;BF4A;1108 1169 11B1; # (뽊; 뽊; 뽊; 뽊; 뽊; ) HANGUL SYLLABLE BBOLM
+BF4B;BF4B;1108 1169 11B2;BF4B;1108 1169 11B2; # (뽋; 뽋; 뽋; 뽋; 뽋; ) HANGUL SYLLABLE BBOLB
+BF4C;BF4C;1108 1169 11B3;BF4C;1108 1169 11B3; # (뽌; 뽌; 뽌; 뽌; 뽌; ) HANGUL SYLLABLE BBOLS
+BF4D;BF4D;1108 1169 11B4;BF4D;1108 1169 11B4; # (뽍; 뽍; 뽍; 뽍; 뽍; ) HANGUL SYLLABLE BBOLT
+BF4E;BF4E;1108 1169 11B5;BF4E;1108 1169 11B5; # (뽎; 뽎; 뽎; 뽎; 뽎; ) HANGUL SYLLABLE BBOLP
+BF4F;BF4F;1108 1169 11B6;BF4F;1108 1169 11B6; # (뽏; 뽏; 뽏; 뽏; 뽏; ) HANGUL SYLLABLE BBOLH
+BF50;BF50;1108 1169 11B7;BF50;1108 1169 11B7; # (뽐; 뽐; 뽐; 뽐; 뽐; ) HANGUL SYLLABLE BBOM
+BF51;BF51;1108 1169 11B8;BF51;1108 1169 11B8; # (뽑; 뽑; 뽑; 뽑; 뽑; ) HANGUL SYLLABLE BBOB
+BF52;BF52;1108 1169 11B9;BF52;1108 1169 11B9; # (뽒; 뽒; 뽒; 뽒; 뽒; ) HANGUL SYLLABLE BBOBS
+BF53;BF53;1108 1169 11BA;BF53;1108 1169 11BA; # (뽓; 뽓; 뽓; 뽓; 뽓; ) HANGUL SYLLABLE BBOS
+BF54;BF54;1108 1169 11BB;BF54;1108 1169 11BB; # (뽔; 뽔; 뽔; 뽔; 뽔; ) HANGUL SYLLABLE BBOSS
+BF55;BF55;1108 1169 11BC;BF55;1108 1169 11BC; # (뽕; 뽕; 뽕; 뽕; 뽕; ) HANGUL SYLLABLE BBONG
+BF56;BF56;1108 1169 11BD;BF56;1108 1169 11BD; # (뽖; 뽖; 뽖; 뽖; 뽖; ) HANGUL SYLLABLE BBOJ
+BF57;BF57;1108 1169 11BE;BF57;1108 1169 11BE; # (뽗; 뽗; 뽗; 뽗; 뽗; ) HANGUL SYLLABLE BBOC
+BF58;BF58;1108 1169 11BF;BF58;1108 1169 11BF; # (뽘; 뽘; 뽘; 뽘; 뽘; ) HANGUL SYLLABLE BBOK
+BF59;BF59;1108 1169 11C0;BF59;1108 1169 11C0; # (뽙; 뽙; 뽙; 뽙; 뽙; ) HANGUL SYLLABLE BBOT
+BF5A;BF5A;1108 1169 11C1;BF5A;1108 1169 11C1; # (뽚; 뽚; 뽚; 뽚; 뽚; ) HANGUL SYLLABLE BBOP
+BF5B;BF5B;1108 1169 11C2;BF5B;1108 1169 11C2; # (뽛; 뽛; 뽛; 뽛; 뽛; ) HANGUL SYLLABLE BBOH
+BF5C;BF5C;1108 116A;BF5C;1108 116A; # (뽜; 뽜; 뽜; 뽜; 뽜; ) HANGUL SYLLABLE BBWA
+BF5D;BF5D;1108 116A 11A8;BF5D;1108 116A 11A8; # (뽝; 뽝; 뽝; 뽝; 뽝; ) HANGUL SYLLABLE BBWAG
+BF5E;BF5E;1108 116A 11A9;BF5E;1108 116A 11A9; # (뽞; 뽞; 뽞; 뽞; 뽞; ) HANGUL SYLLABLE BBWAGG
+BF5F;BF5F;1108 116A 11AA;BF5F;1108 116A 11AA; # (뽟; 뽟; 뽟; 뽟; 뽟; ) HANGUL SYLLABLE BBWAGS
+BF60;BF60;1108 116A 11AB;BF60;1108 116A 11AB; # (뽠; 뽠; 뽠; 뽠; 뽠; ) HANGUL SYLLABLE BBWAN
+BF61;BF61;1108 116A 11AC;BF61;1108 116A 11AC; # (뽡; 뽡; 뽡; 뽡; 뽡; ) HANGUL SYLLABLE BBWANJ
+BF62;BF62;1108 116A 11AD;BF62;1108 116A 11AD; # (뽢; 뽢; 뽢; 뽢; 뽢; ) HANGUL SYLLABLE BBWANH
+BF63;BF63;1108 116A 11AE;BF63;1108 116A 11AE; # (뽣; 뽣; 뽣; 뽣; 뽣; ) HANGUL SYLLABLE BBWAD
+BF64;BF64;1108 116A 11AF;BF64;1108 116A 11AF; # (뽤; 뽤; 뽤; 뽤; 뽤; ) HANGUL SYLLABLE BBWAL
+BF65;BF65;1108 116A 11B0;BF65;1108 116A 11B0; # (뽥; 뽥; 뽥; 뽥; 뽥; ) HANGUL SYLLABLE BBWALG
+BF66;BF66;1108 116A 11B1;BF66;1108 116A 11B1; # (뽦; 뽦; 뽦; 뽦; 뽦; ) HANGUL SYLLABLE BBWALM
+BF67;BF67;1108 116A 11B2;BF67;1108 116A 11B2; # (뽧; 뽧; 뽧; 뽧; 뽧; ) HANGUL SYLLABLE BBWALB
+BF68;BF68;1108 116A 11B3;BF68;1108 116A 11B3; # (뽨; 뽨; 뽨; 뽨; 뽨; ) HANGUL SYLLABLE BBWALS
+BF69;BF69;1108 116A 11B4;BF69;1108 116A 11B4; # (뽩; 뽩; 뽩; 뽩; 뽩; ) HANGUL SYLLABLE BBWALT
+BF6A;BF6A;1108 116A 11B5;BF6A;1108 116A 11B5; # (뽪; 뽪; 뽪; 뽪; 뽪; ) HANGUL SYLLABLE BBWALP
+BF6B;BF6B;1108 116A 11B6;BF6B;1108 116A 11B6; # (뽫; 뽫; 뽫; 뽫; 뽫; ) HANGUL SYLLABLE BBWALH
+BF6C;BF6C;1108 116A 11B7;BF6C;1108 116A 11B7; # (뽬; 뽬; 뽬; 뽬; 뽬; ) HANGUL SYLLABLE BBWAM
+BF6D;BF6D;1108 116A 11B8;BF6D;1108 116A 11B8; # (뽭; 뽭; 뽭; 뽭; 뽭; ) HANGUL SYLLABLE BBWAB
+BF6E;BF6E;1108 116A 11B9;BF6E;1108 116A 11B9; # (뽮; 뽮; 뽮; 뽮; 뽮; ) HANGUL SYLLABLE BBWABS
+BF6F;BF6F;1108 116A 11BA;BF6F;1108 116A 11BA; # (뽯; 뽯; 뽯; 뽯; 뽯; ) HANGUL SYLLABLE BBWAS
+BF70;BF70;1108 116A 11BB;BF70;1108 116A 11BB; # (뽰; 뽰; 뽰; 뽰; 뽰; ) HANGUL SYLLABLE BBWASS
+BF71;BF71;1108 116A 11BC;BF71;1108 116A 11BC; # (뽱; 뽱; 뽱; 뽱; 뽱; ) HANGUL SYLLABLE BBWANG
+BF72;BF72;1108 116A 11BD;BF72;1108 116A 11BD; # (뽲; 뽲; 뽲; 뽲; 뽲; ) HANGUL SYLLABLE BBWAJ
+BF73;BF73;1108 116A 11BE;BF73;1108 116A 11BE; # (뽳; 뽳; 뽳; 뽳; 뽳; ) HANGUL SYLLABLE BBWAC
+BF74;BF74;1108 116A 11BF;BF74;1108 116A 11BF; # (뽴; 뽴; 뽴; 뽴; 뽴; ) HANGUL SYLLABLE BBWAK
+BF75;BF75;1108 116A 11C0;BF75;1108 116A 11C0; # (뽵; 뽵; 뽵; 뽵; 뽵; ) HANGUL SYLLABLE BBWAT
+BF76;BF76;1108 116A 11C1;BF76;1108 116A 11C1; # (뽶; 뽶; 뽶; 뽶; 뽶; ) HANGUL SYLLABLE BBWAP
+BF77;BF77;1108 116A 11C2;BF77;1108 116A 11C2; # (뽷; 뽷; 뽷; 뽷; 뽷; ) HANGUL SYLLABLE BBWAH
+BF78;BF78;1108 116B;BF78;1108 116B; # (뽸; 뽸; 뽸; 뽸; 뽸; ) HANGUL SYLLABLE BBWAE
+BF79;BF79;1108 116B 11A8;BF79;1108 116B 11A8; # (뽹; 뽹; 뽹; 뽹; 뽹; ) HANGUL SYLLABLE BBWAEG
+BF7A;BF7A;1108 116B 11A9;BF7A;1108 116B 11A9; # (뽺; 뽺; 뽺; 뽺; 뽺; ) HANGUL SYLLABLE BBWAEGG
+BF7B;BF7B;1108 116B 11AA;BF7B;1108 116B 11AA; # (뽻; 뽻; 뽻; 뽻; 뽻; ) HANGUL SYLLABLE BBWAEGS
+BF7C;BF7C;1108 116B 11AB;BF7C;1108 116B 11AB; # (뽼; 뽼; 뽼; 뽼; 뽼; ) HANGUL SYLLABLE BBWAEN
+BF7D;BF7D;1108 116B 11AC;BF7D;1108 116B 11AC; # (뽽; 뽽; 뽽; 뽽; 뽽; ) HANGUL SYLLABLE BBWAENJ
+BF7E;BF7E;1108 116B 11AD;BF7E;1108 116B 11AD; # (뽾; 뽾; 뽾; 뽾; 뽾; ) HANGUL SYLLABLE BBWAENH
+BF7F;BF7F;1108 116B 11AE;BF7F;1108 116B 11AE; # (뽿; 뽿; 뽿; 뽿; 뽿; ) HANGUL SYLLABLE BBWAED
+BF80;BF80;1108 116B 11AF;BF80;1108 116B 11AF; # (뾀; 뾀; 뾀; 뾀; 뾀; ) HANGUL SYLLABLE BBWAEL
+BF81;BF81;1108 116B 11B0;BF81;1108 116B 11B0; # (뾁; 뾁; 뾁; 뾁; 뾁; ) HANGUL SYLLABLE BBWAELG
+BF82;BF82;1108 116B 11B1;BF82;1108 116B 11B1; # (뾂; 뾂; 뾂; 뾂; 뾂; ) HANGUL SYLLABLE BBWAELM
+BF83;BF83;1108 116B 11B2;BF83;1108 116B 11B2; # (뾃; 뾃; 뾃; 뾃; 뾃; ) HANGUL SYLLABLE BBWAELB
+BF84;BF84;1108 116B 11B3;BF84;1108 116B 11B3; # (뾄; 뾄; 뾄; 뾄; 뾄; ) HANGUL SYLLABLE BBWAELS
+BF85;BF85;1108 116B 11B4;BF85;1108 116B 11B4; # (뾅; 뾅; 뾅; 뾅; 뾅; ) HANGUL SYLLABLE BBWAELT
+BF86;BF86;1108 116B 11B5;BF86;1108 116B 11B5; # (뾆; 뾆; 뾆; 뾆; 뾆; ) HANGUL SYLLABLE BBWAELP
+BF87;BF87;1108 116B 11B6;BF87;1108 116B 11B6; # (뾇; 뾇; 뾇; 뾇; 뾇; ) HANGUL SYLLABLE BBWAELH
+BF88;BF88;1108 116B 11B7;BF88;1108 116B 11B7; # (뾈; 뾈; 뾈; 뾈; 뾈; ) HANGUL SYLLABLE BBWAEM
+BF89;BF89;1108 116B 11B8;BF89;1108 116B 11B8; # (뾉; 뾉; 뾉; 뾉; 뾉; ) HANGUL SYLLABLE BBWAEB
+BF8A;BF8A;1108 116B 11B9;BF8A;1108 116B 11B9; # (뾊; 뾊; 뾊; 뾊; 뾊; ) HANGUL SYLLABLE BBWAEBS
+BF8B;BF8B;1108 116B 11BA;BF8B;1108 116B 11BA; # (뾋; 뾋; 뾋; 뾋; 뾋; ) HANGUL SYLLABLE BBWAES
+BF8C;BF8C;1108 116B 11BB;BF8C;1108 116B 11BB; # (뾌; 뾌; 뾌; 뾌; 뾌; ) HANGUL SYLLABLE BBWAESS
+BF8D;BF8D;1108 116B 11BC;BF8D;1108 116B 11BC; # (뾍; 뾍; 뾍; 뾍; 뾍; ) HANGUL SYLLABLE BBWAENG
+BF8E;BF8E;1108 116B 11BD;BF8E;1108 116B 11BD; # (뾎; 뾎; 뾎; 뾎; 뾎; ) HANGUL SYLLABLE BBWAEJ
+BF8F;BF8F;1108 116B 11BE;BF8F;1108 116B 11BE; # (뾏; 뾏; 뾏; 뾏; 뾏; ) HANGUL SYLLABLE BBWAEC
+BF90;BF90;1108 116B 11BF;BF90;1108 116B 11BF; # (뾐; 뾐; 뾐; 뾐; 뾐; ) HANGUL SYLLABLE BBWAEK
+BF91;BF91;1108 116B 11C0;BF91;1108 116B 11C0; # (뾑; 뾑; 뾑; 뾑; 뾑; ) HANGUL SYLLABLE BBWAET
+BF92;BF92;1108 116B 11C1;BF92;1108 116B 11C1; # (뾒; 뾒; 뾒; 뾒; 뾒; ) HANGUL SYLLABLE BBWAEP
+BF93;BF93;1108 116B 11C2;BF93;1108 116B 11C2; # (뾓; 뾓; 뾓; 뾓; 뾓; ) HANGUL SYLLABLE BBWAEH
+BF94;BF94;1108 116C;BF94;1108 116C; # (뾔; 뾔; 뾔; 뾔; 뾔; ) HANGUL SYLLABLE BBOE
+BF95;BF95;1108 116C 11A8;BF95;1108 116C 11A8; # (뾕; 뾕; 뾕; 뾕; 뾕; ) HANGUL SYLLABLE BBOEG
+BF96;BF96;1108 116C 11A9;BF96;1108 116C 11A9; # (뾖; 뾖; 뾖; 뾖; 뾖; ) HANGUL SYLLABLE BBOEGG
+BF97;BF97;1108 116C 11AA;BF97;1108 116C 11AA; # (뾗; 뾗; 뾗; 뾗; 뾗; ) HANGUL SYLLABLE BBOEGS
+BF98;BF98;1108 116C 11AB;BF98;1108 116C 11AB; # (뾘; 뾘; 뾘; 뾘; 뾘; ) HANGUL SYLLABLE BBOEN
+BF99;BF99;1108 116C 11AC;BF99;1108 116C 11AC; # (뾙; 뾙; 뾙; 뾙; 뾙; ) HANGUL SYLLABLE BBOENJ
+BF9A;BF9A;1108 116C 11AD;BF9A;1108 116C 11AD; # (뾚; 뾚; 뾚; 뾚; 뾚; ) HANGUL SYLLABLE BBOENH
+BF9B;BF9B;1108 116C 11AE;BF9B;1108 116C 11AE; # (뾛; 뾛; 뾛; 뾛; 뾛; ) HANGUL SYLLABLE BBOED
+BF9C;BF9C;1108 116C 11AF;BF9C;1108 116C 11AF; # (뾜; 뾜; 뾜; 뾜; 뾜; ) HANGUL SYLLABLE BBOEL
+BF9D;BF9D;1108 116C 11B0;BF9D;1108 116C 11B0; # (뾝; 뾝; 뾝; 뾝; 뾝; ) HANGUL SYLLABLE BBOELG
+BF9E;BF9E;1108 116C 11B1;BF9E;1108 116C 11B1; # (뾞; 뾞; 뾞; 뾞; 뾞; ) HANGUL SYLLABLE BBOELM
+BF9F;BF9F;1108 116C 11B2;BF9F;1108 116C 11B2; # (뾟; 뾟; 뾟; 뾟; 뾟; ) HANGUL SYLLABLE BBOELB
+BFA0;BFA0;1108 116C 11B3;BFA0;1108 116C 11B3; # (뾠; 뾠; 뾠; 뾠; 뾠; ) HANGUL SYLLABLE BBOELS
+BFA1;BFA1;1108 116C 11B4;BFA1;1108 116C 11B4; # (뾡; 뾡; 뾡; 뾡; 뾡; ) HANGUL SYLLABLE BBOELT
+BFA2;BFA2;1108 116C 11B5;BFA2;1108 116C 11B5; # (뾢; 뾢; 뾢; 뾢; 뾢; ) HANGUL SYLLABLE BBOELP
+BFA3;BFA3;1108 116C 11B6;BFA3;1108 116C 11B6; # (뾣; 뾣; 뾣; 뾣; 뾣; ) HANGUL SYLLABLE BBOELH
+BFA4;BFA4;1108 116C 11B7;BFA4;1108 116C 11B7; # (뾤; 뾤; 뾤; 뾤; 뾤; ) HANGUL SYLLABLE BBOEM
+BFA5;BFA5;1108 116C 11B8;BFA5;1108 116C 11B8; # (뾥; 뾥; 뾥; 뾥; 뾥; ) HANGUL SYLLABLE BBOEB
+BFA6;BFA6;1108 116C 11B9;BFA6;1108 116C 11B9; # (뾦; 뾦; 뾦; 뾦; 뾦; ) HANGUL SYLLABLE BBOEBS
+BFA7;BFA7;1108 116C 11BA;BFA7;1108 116C 11BA; # (뾧; 뾧; 뾧; 뾧; 뾧; ) HANGUL SYLLABLE BBOES
+BFA8;BFA8;1108 116C 11BB;BFA8;1108 116C 11BB; # (뾨; 뾨; 뾨; 뾨; 뾨; ) HANGUL SYLLABLE BBOESS
+BFA9;BFA9;1108 116C 11BC;BFA9;1108 116C 11BC; # (뾩; 뾩; 뾩; 뾩; 뾩; ) HANGUL SYLLABLE BBOENG
+BFAA;BFAA;1108 116C 11BD;BFAA;1108 116C 11BD; # (뾪; 뾪; 뾪; 뾪; 뾪; ) HANGUL SYLLABLE BBOEJ
+BFAB;BFAB;1108 116C 11BE;BFAB;1108 116C 11BE; # (뾫; 뾫; 뾫; 뾫; 뾫; ) HANGUL SYLLABLE BBOEC
+BFAC;BFAC;1108 116C 11BF;BFAC;1108 116C 11BF; # (뾬; 뾬; 뾬; 뾬; 뾬; ) HANGUL SYLLABLE BBOEK
+BFAD;BFAD;1108 116C 11C0;BFAD;1108 116C 11C0; # (뾭; 뾭; 뾭; 뾭; 뾭; ) HANGUL SYLLABLE BBOET
+BFAE;BFAE;1108 116C 11C1;BFAE;1108 116C 11C1; # (뾮; 뾮; 뾮; 뾮; 뾮; ) HANGUL SYLLABLE BBOEP
+BFAF;BFAF;1108 116C 11C2;BFAF;1108 116C 11C2; # (뾯; 뾯; 뾯; 뾯; 뾯; ) HANGUL SYLLABLE BBOEH
+BFB0;BFB0;1108 116D;BFB0;1108 116D; # (뾰; 뾰; 뾰; 뾰; 뾰; ) HANGUL SYLLABLE BBYO
+BFB1;BFB1;1108 116D 11A8;BFB1;1108 116D 11A8; # (뾱; 뾱; 뾱; 뾱; 뾱; ) HANGUL SYLLABLE BBYOG
+BFB2;BFB2;1108 116D 11A9;BFB2;1108 116D 11A9; # (뾲; 뾲; 뾲; 뾲; 뾲; ) HANGUL SYLLABLE BBYOGG
+BFB3;BFB3;1108 116D 11AA;BFB3;1108 116D 11AA; # (뾳; 뾳; 뾳; 뾳; 뾳; ) HANGUL SYLLABLE BBYOGS
+BFB4;BFB4;1108 116D 11AB;BFB4;1108 116D 11AB; # (뾴; 뾴; 뾴; 뾴; 뾴; ) HANGUL SYLLABLE BBYON
+BFB5;BFB5;1108 116D 11AC;BFB5;1108 116D 11AC; # (뾵; 뾵; 뾵; 뾵; 뾵; ) HANGUL SYLLABLE BBYONJ
+BFB6;BFB6;1108 116D 11AD;BFB6;1108 116D 11AD; # (뾶; 뾶; 뾶; 뾶; 뾶; ) HANGUL SYLLABLE BBYONH
+BFB7;BFB7;1108 116D 11AE;BFB7;1108 116D 11AE; # (뾷; 뾷; 뾷; 뾷; 뾷; ) HANGUL SYLLABLE BBYOD
+BFB8;BFB8;1108 116D 11AF;BFB8;1108 116D 11AF; # (뾸; 뾸; 뾸; 뾸; 뾸; ) HANGUL SYLLABLE BBYOL
+BFB9;BFB9;1108 116D 11B0;BFB9;1108 116D 11B0; # (뾹; 뾹; 뾹; 뾹; 뾹; ) HANGUL SYLLABLE BBYOLG
+BFBA;BFBA;1108 116D 11B1;BFBA;1108 116D 11B1; # (뾺; 뾺; 뾺; 뾺; 뾺; ) HANGUL SYLLABLE BBYOLM
+BFBB;BFBB;1108 116D 11B2;BFBB;1108 116D 11B2; # (뾻; 뾻; 뾻; 뾻; 뾻; ) HANGUL SYLLABLE BBYOLB
+BFBC;BFBC;1108 116D 11B3;BFBC;1108 116D 11B3; # (뾼; 뾼; 뾼; 뾼; 뾼; ) HANGUL SYLLABLE BBYOLS
+BFBD;BFBD;1108 116D 11B4;BFBD;1108 116D 11B4; # (뾽; 뾽; 뾽; 뾽; 뾽; ) HANGUL SYLLABLE BBYOLT
+BFBE;BFBE;1108 116D 11B5;BFBE;1108 116D 11B5; # (뾾; 뾾; 뾾; 뾾; 뾾; ) HANGUL SYLLABLE BBYOLP
+BFBF;BFBF;1108 116D 11B6;BFBF;1108 116D 11B6; # (뾿; 뾿; 뾿; 뾿; 뾿; ) HANGUL SYLLABLE BBYOLH
+BFC0;BFC0;1108 116D 11B7;BFC0;1108 116D 11B7; # (뿀; 뿀; 뿀; 뿀; 뿀; ) HANGUL SYLLABLE BBYOM
+BFC1;BFC1;1108 116D 11B8;BFC1;1108 116D 11B8; # (뿁; 뿁; 뿁; 뿁; 뿁; ) HANGUL SYLLABLE BBYOB
+BFC2;BFC2;1108 116D 11B9;BFC2;1108 116D 11B9; # (뿂; 뿂; 뿂; 뿂; 뿂; ) HANGUL SYLLABLE BBYOBS
+BFC3;BFC3;1108 116D 11BA;BFC3;1108 116D 11BA; # (뿃; 뿃; 뿃; 뿃; 뿃; ) HANGUL SYLLABLE BBYOS
+BFC4;BFC4;1108 116D 11BB;BFC4;1108 116D 11BB; # (뿄; 뿄; 뿄; 뿄; 뿄; ) HANGUL SYLLABLE BBYOSS
+BFC5;BFC5;1108 116D 11BC;BFC5;1108 116D 11BC; # (뿅; 뿅; 뿅; 뿅; 뿅; ) HANGUL SYLLABLE BBYONG
+BFC6;BFC6;1108 116D 11BD;BFC6;1108 116D 11BD; # (뿆; 뿆; 뿆; 뿆; 뿆; ) HANGUL SYLLABLE BBYOJ
+BFC7;BFC7;1108 116D 11BE;BFC7;1108 116D 11BE; # (뿇; 뿇; 뿇; 뿇; 뿇; ) HANGUL SYLLABLE BBYOC
+BFC8;BFC8;1108 116D 11BF;BFC8;1108 116D 11BF; # (뿈; 뿈; 뿈; 뿈; 뿈; ) HANGUL SYLLABLE BBYOK
+BFC9;BFC9;1108 116D 11C0;BFC9;1108 116D 11C0; # (뿉; 뿉; 뿉; 뿉; 뿉; ) HANGUL SYLLABLE BBYOT
+BFCA;BFCA;1108 116D 11C1;BFCA;1108 116D 11C1; # (뿊; 뿊; 뿊; 뿊; 뿊; ) HANGUL SYLLABLE BBYOP
+BFCB;BFCB;1108 116D 11C2;BFCB;1108 116D 11C2; # (뿋; 뿋; 뿋; 뿋; 뿋; ) HANGUL SYLLABLE BBYOH
+BFCC;BFCC;1108 116E;BFCC;1108 116E; # (뿌; 뿌; 뿌; 뿌; 뿌; ) HANGUL SYLLABLE BBU
+BFCD;BFCD;1108 116E 11A8;BFCD;1108 116E 11A8; # (뿍; 뿍; 뿍; 뿍; 뿍; ) HANGUL SYLLABLE BBUG
+BFCE;BFCE;1108 116E 11A9;BFCE;1108 116E 11A9; # (뿎; 뿎; 뿎; 뿎; 뿎; ) HANGUL SYLLABLE BBUGG
+BFCF;BFCF;1108 116E 11AA;BFCF;1108 116E 11AA; # (뿏; 뿏; 뿏; 뿏; 뿏; ) HANGUL SYLLABLE BBUGS
+BFD0;BFD0;1108 116E 11AB;BFD0;1108 116E 11AB; # (뿐; 뿐; 뿐; 뿐; 뿐; ) HANGUL SYLLABLE BBUN
+BFD1;BFD1;1108 116E 11AC;BFD1;1108 116E 11AC; # (뿑; 뿑; 뿑; 뿑; 뿑; ) HANGUL SYLLABLE BBUNJ
+BFD2;BFD2;1108 116E 11AD;BFD2;1108 116E 11AD; # (뿒; 뿒; 뿒; 뿒; 뿒; ) HANGUL SYLLABLE BBUNH
+BFD3;BFD3;1108 116E 11AE;BFD3;1108 116E 11AE; # (뿓; 뿓; 뿓; 뿓; 뿓; ) HANGUL SYLLABLE BBUD
+BFD4;BFD4;1108 116E 11AF;BFD4;1108 116E 11AF; # (뿔; 뿔; 뿔; 뿔; 뿔; ) HANGUL SYLLABLE BBUL
+BFD5;BFD5;1108 116E 11B0;BFD5;1108 116E 11B0; # (뿕; 뿕; 뿕; 뿕; 뿕; ) HANGUL SYLLABLE BBULG
+BFD6;BFD6;1108 116E 11B1;BFD6;1108 116E 11B1; # (뿖; 뿖; 뿖; 뿖; 뿖; ) HANGUL SYLLABLE BBULM
+BFD7;BFD7;1108 116E 11B2;BFD7;1108 116E 11B2; # (뿗; 뿗; 뿗; 뿗; 뿗; ) HANGUL SYLLABLE BBULB
+BFD8;BFD8;1108 116E 11B3;BFD8;1108 116E 11B3; # (뿘; 뿘; 뿘; 뿘; 뿘; ) HANGUL SYLLABLE BBULS
+BFD9;BFD9;1108 116E 11B4;BFD9;1108 116E 11B4; # (뿙; 뿙; 뿙; 뿙; 뿙; ) HANGUL SYLLABLE BBULT
+BFDA;BFDA;1108 116E 11B5;BFDA;1108 116E 11B5; # (뿚; 뿚; 뿚; 뿚; 뿚; ) HANGUL SYLLABLE BBULP
+BFDB;BFDB;1108 116E 11B6;BFDB;1108 116E 11B6; # (뿛; 뿛; 뿛; 뿛; 뿛; ) HANGUL SYLLABLE BBULH
+BFDC;BFDC;1108 116E 11B7;BFDC;1108 116E 11B7; # (뿜; 뿜; 뿜; 뿜; 뿜; ) HANGUL SYLLABLE BBUM
+BFDD;BFDD;1108 116E 11B8;BFDD;1108 116E 11B8; # (뿝; 뿝; 뿝; 뿝; 뿝; ) HANGUL SYLLABLE BBUB
+BFDE;BFDE;1108 116E 11B9;BFDE;1108 116E 11B9; # (뿞; 뿞; 뿞; 뿞; 뿞; ) HANGUL SYLLABLE BBUBS
+BFDF;BFDF;1108 116E 11BA;BFDF;1108 116E 11BA; # (뿟; 뿟; 뿟; 뿟; 뿟; ) HANGUL SYLLABLE BBUS
+BFE0;BFE0;1108 116E 11BB;BFE0;1108 116E 11BB; # (뿠; 뿠; 뿠; 뿠; 뿠; ) HANGUL SYLLABLE BBUSS
+BFE1;BFE1;1108 116E 11BC;BFE1;1108 116E 11BC; # (뿡; 뿡; 뿡; 뿡; 뿡; ) HANGUL SYLLABLE BBUNG
+BFE2;BFE2;1108 116E 11BD;BFE2;1108 116E 11BD; # (뿢; 뿢; 뿢; 뿢; 뿢; ) HANGUL SYLLABLE BBUJ
+BFE3;BFE3;1108 116E 11BE;BFE3;1108 116E 11BE; # (뿣; 뿣; 뿣; 뿣; 뿣; ) HANGUL SYLLABLE BBUC
+BFE4;BFE4;1108 116E 11BF;BFE4;1108 116E 11BF; # (뿤; 뿤; 뿤; 뿤; 뿤; ) HANGUL SYLLABLE BBUK
+BFE5;BFE5;1108 116E 11C0;BFE5;1108 116E 11C0; # (뿥; 뿥; 뿥; 뿥; 뿥; ) HANGUL SYLLABLE BBUT
+BFE6;BFE6;1108 116E 11C1;BFE6;1108 116E 11C1; # (뿦; 뿦; 뿦; 뿦; 뿦; ) HANGUL SYLLABLE BBUP
+BFE7;BFE7;1108 116E 11C2;BFE7;1108 116E 11C2; # (뿧; 뿧; 뿧; 뿧; 뿧; ) HANGUL SYLLABLE BBUH
+BFE8;BFE8;1108 116F;BFE8;1108 116F; # (뿨; 뿨; 뿨; 뿨; 뿨; ) HANGUL SYLLABLE BBWEO
+BFE9;BFE9;1108 116F 11A8;BFE9;1108 116F 11A8; # (뿩; 뿩; 뿩; 뿩; 뿩; ) HANGUL SYLLABLE BBWEOG
+BFEA;BFEA;1108 116F 11A9;BFEA;1108 116F 11A9; # (뿪; 뿪; 뿪; 뿪; 뿪; ) HANGUL SYLLABLE BBWEOGG
+BFEB;BFEB;1108 116F 11AA;BFEB;1108 116F 11AA; # (뿫; 뿫; 뿫; 뿫; 뿫; ) HANGUL SYLLABLE BBWEOGS
+BFEC;BFEC;1108 116F 11AB;BFEC;1108 116F 11AB; # (뿬; 뿬; 뿬; 뿬; 뿬; ) HANGUL SYLLABLE BBWEON
+BFED;BFED;1108 116F 11AC;BFED;1108 116F 11AC; # (뿭; 뿭; 뿭; 뿭; 뿭; ) HANGUL SYLLABLE BBWEONJ
+BFEE;BFEE;1108 116F 11AD;BFEE;1108 116F 11AD; # (뿮; 뿮; 뿮; 뿮; 뿮; ) HANGUL SYLLABLE BBWEONH
+BFEF;BFEF;1108 116F 11AE;BFEF;1108 116F 11AE; # (뿯; 뿯; 뿯; 뿯; 뿯; ) HANGUL SYLLABLE BBWEOD
+BFF0;BFF0;1108 116F 11AF;BFF0;1108 116F 11AF; # (뿰; 뿰; 뿰; 뿰; 뿰; ) HANGUL SYLLABLE BBWEOL
+BFF1;BFF1;1108 116F 11B0;BFF1;1108 116F 11B0; # (뿱; 뿱; 뿱; 뿱; 뿱; ) HANGUL SYLLABLE BBWEOLG
+BFF2;BFF2;1108 116F 11B1;BFF2;1108 116F 11B1; # (뿲; 뿲; 뿲; 뿲; 뿲; ) HANGUL SYLLABLE BBWEOLM
+BFF3;BFF3;1108 116F 11B2;BFF3;1108 116F 11B2; # (뿳; 뿳; 뿳; 뿳; 뿳; ) HANGUL SYLLABLE BBWEOLB
+BFF4;BFF4;1108 116F 11B3;BFF4;1108 116F 11B3; # (뿴; 뿴; 뿴; 뿴; 뿴; ) HANGUL SYLLABLE BBWEOLS
+BFF5;BFF5;1108 116F 11B4;BFF5;1108 116F 11B4; # (뿵; 뿵; 뿵; 뿵; 뿵; ) HANGUL SYLLABLE BBWEOLT
+BFF6;BFF6;1108 116F 11B5;BFF6;1108 116F 11B5; # (뿶; 뿶; 뿶; 뿶; 뿶; ) HANGUL SYLLABLE BBWEOLP
+BFF7;BFF7;1108 116F 11B6;BFF7;1108 116F 11B6; # (뿷; 뿷; 뿷; 뿷; 뿷; ) HANGUL SYLLABLE BBWEOLH
+BFF8;BFF8;1108 116F 11B7;BFF8;1108 116F 11B7; # (뿸; 뿸; 뿸; 뿸; 뿸; ) HANGUL SYLLABLE BBWEOM
+BFF9;BFF9;1108 116F 11B8;BFF9;1108 116F 11B8; # (뿹; 뿹; 뿹; 뿹; 뿹; ) HANGUL SYLLABLE BBWEOB
+BFFA;BFFA;1108 116F 11B9;BFFA;1108 116F 11B9; # (뿺; 뿺; 뿺; 뿺; 뿺; ) HANGUL SYLLABLE BBWEOBS
+BFFB;BFFB;1108 116F 11BA;BFFB;1108 116F 11BA; # (뿻; 뿻; 뿻; 뿻; 뿻; ) HANGUL SYLLABLE BBWEOS
+BFFC;BFFC;1108 116F 11BB;BFFC;1108 116F 11BB; # (뿼; 뿼; 뿼; 뿼; 뿼; ) HANGUL SYLLABLE BBWEOSS
+BFFD;BFFD;1108 116F 11BC;BFFD;1108 116F 11BC; # (뿽; 뿽; 뿽; 뿽; 뿽; ) HANGUL SYLLABLE BBWEONG
+BFFE;BFFE;1108 116F 11BD;BFFE;1108 116F 11BD; # (뿾; 뿾; 뿾; 뿾; 뿾; ) HANGUL SYLLABLE BBWEOJ
+BFFF;BFFF;1108 116F 11BE;BFFF;1108 116F 11BE; # (뿿; 뿿; 뿿; 뿿; 뿿; ) HANGUL SYLLABLE BBWEOC
+C000;C000;1108 116F 11BF;C000;1108 116F 11BF; # (쀀; 쀀; 쀀; 쀀; 쀀; ) HANGUL SYLLABLE BBWEOK
+C001;C001;1108 116F 11C0;C001;1108 116F 11C0; # (쀁; 쀁; 쀁; 쀁; 쀁; ) HANGUL SYLLABLE BBWEOT
+C002;C002;1108 116F 11C1;C002;1108 116F 11C1; # (쀂; 쀂; 쀂; 쀂; 쀂; ) HANGUL SYLLABLE BBWEOP
+C003;C003;1108 116F 11C2;C003;1108 116F 11C2; # (쀃; 쀃; 쀃; 쀃; 쀃; ) HANGUL SYLLABLE BBWEOH
+C004;C004;1108 1170;C004;1108 1170; # (쀄; 쀄; 쀄; 쀄; 쀄; ) HANGUL SYLLABLE BBWE
+C005;C005;1108 1170 11A8;C005;1108 1170 11A8; # (쀅; 쀅; 쀅; 쀅; 쀅; ) HANGUL SYLLABLE BBWEG
+C006;C006;1108 1170 11A9;C006;1108 1170 11A9; # (쀆; 쀆; 쀆; 쀆; 쀆; ) HANGUL SYLLABLE BBWEGG
+C007;C007;1108 1170 11AA;C007;1108 1170 11AA; # (쀇; 쀇; 쀇; 쀇; 쀇; ) HANGUL SYLLABLE BBWEGS
+C008;C008;1108 1170 11AB;C008;1108 1170 11AB; # (쀈; 쀈; 쀈; 쀈; 쀈; ) HANGUL SYLLABLE BBWEN
+C009;C009;1108 1170 11AC;C009;1108 1170 11AC; # (쀉; 쀉; 쀉; 쀉; 쀉; ) HANGUL SYLLABLE BBWENJ
+C00A;C00A;1108 1170 11AD;C00A;1108 1170 11AD; # (쀊; 쀊; 쀊; 쀊; 쀊; ) HANGUL SYLLABLE BBWENH
+C00B;C00B;1108 1170 11AE;C00B;1108 1170 11AE; # (쀋; 쀋; 쀋; 쀋; 쀋; ) HANGUL SYLLABLE BBWED
+C00C;C00C;1108 1170 11AF;C00C;1108 1170 11AF; # (쀌; 쀌; 쀌; 쀌; 쀌; ) HANGUL SYLLABLE BBWEL
+C00D;C00D;1108 1170 11B0;C00D;1108 1170 11B0; # (쀍; 쀍; 쀍; 쀍; 쀍; ) HANGUL SYLLABLE BBWELG
+C00E;C00E;1108 1170 11B1;C00E;1108 1170 11B1; # (쀎; 쀎; 쀎; 쀎; 쀎; ) HANGUL SYLLABLE BBWELM
+C00F;C00F;1108 1170 11B2;C00F;1108 1170 11B2; # (쀏; 쀏; 쀏; 쀏; 쀏; ) HANGUL SYLLABLE BBWELB
+C010;C010;1108 1170 11B3;C010;1108 1170 11B3; # (쀐; 쀐; 쀐; 쀐; 쀐; ) HANGUL SYLLABLE BBWELS
+C011;C011;1108 1170 11B4;C011;1108 1170 11B4; # (쀑; 쀑; 쀑; 쀑; 쀑; ) HANGUL SYLLABLE BBWELT
+C012;C012;1108 1170 11B5;C012;1108 1170 11B5; # (쀒; 쀒; 쀒; 쀒; 쀒; ) HANGUL SYLLABLE BBWELP
+C013;C013;1108 1170 11B6;C013;1108 1170 11B6; # (쀓; 쀓; 쀓; 쀓; 쀓; ) HANGUL SYLLABLE BBWELH
+C014;C014;1108 1170 11B7;C014;1108 1170 11B7; # (쀔; 쀔; 쀔; 쀔; 쀔; ) HANGUL SYLLABLE BBWEM
+C015;C015;1108 1170 11B8;C015;1108 1170 11B8; # (쀕; 쀕; 쀕; 쀕; 쀕; ) HANGUL SYLLABLE BBWEB
+C016;C016;1108 1170 11B9;C016;1108 1170 11B9; # (쀖; 쀖; 쀖; 쀖; 쀖; ) HANGUL SYLLABLE BBWEBS
+C017;C017;1108 1170 11BA;C017;1108 1170 11BA; # (쀗; 쀗; 쀗; 쀗; 쀗; ) HANGUL SYLLABLE BBWES
+C018;C018;1108 1170 11BB;C018;1108 1170 11BB; # (쀘; 쀘; 쀘; 쀘; 쀘; ) HANGUL SYLLABLE BBWESS
+C019;C019;1108 1170 11BC;C019;1108 1170 11BC; # (쀙; 쀙; 쀙; 쀙; 쀙; ) HANGUL SYLLABLE BBWENG
+C01A;C01A;1108 1170 11BD;C01A;1108 1170 11BD; # (쀚; 쀚; 쀚; 쀚; 쀚; ) HANGUL SYLLABLE BBWEJ
+C01B;C01B;1108 1170 11BE;C01B;1108 1170 11BE; # (쀛; 쀛; 쀛; 쀛; 쀛; ) HANGUL SYLLABLE BBWEC
+C01C;C01C;1108 1170 11BF;C01C;1108 1170 11BF; # (쀜; 쀜; 쀜; 쀜; 쀜; ) HANGUL SYLLABLE BBWEK
+C01D;C01D;1108 1170 11C0;C01D;1108 1170 11C0; # (쀝; 쀝; 쀝; 쀝; 쀝; ) HANGUL SYLLABLE BBWET
+C01E;C01E;1108 1170 11C1;C01E;1108 1170 11C1; # (쀞; 쀞; 쀞; 쀞; 쀞; ) HANGUL SYLLABLE BBWEP
+C01F;C01F;1108 1170 11C2;C01F;1108 1170 11C2; # (쀟; 쀟; 쀟; 쀟; 쀟; ) HANGUL SYLLABLE BBWEH
+C020;C020;1108 1171;C020;1108 1171; # (쀠; 쀠; 쀠; 쀠; 쀠; ) HANGUL SYLLABLE BBWI
+C021;C021;1108 1171 11A8;C021;1108 1171 11A8; # (쀡; 쀡; 쀡; 쀡; 쀡; ) HANGUL SYLLABLE BBWIG
+C022;C022;1108 1171 11A9;C022;1108 1171 11A9; # (쀢; 쀢; 쀢; 쀢; 쀢; ) HANGUL SYLLABLE BBWIGG
+C023;C023;1108 1171 11AA;C023;1108 1171 11AA; # (쀣; 쀣; 쀣; 쀣; 쀣; ) HANGUL SYLLABLE BBWIGS
+C024;C024;1108 1171 11AB;C024;1108 1171 11AB; # (쀤; 쀤; 쀤; 쀤; 쀤; ) HANGUL SYLLABLE BBWIN
+C025;C025;1108 1171 11AC;C025;1108 1171 11AC; # (쀥; 쀥; 쀥; 쀥; 쀥; ) HANGUL SYLLABLE BBWINJ
+C026;C026;1108 1171 11AD;C026;1108 1171 11AD; # (쀦; 쀦; 쀦; 쀦; 쀦; ) HANGUL SYLLABLE BBWINH
+C027;C027;1108 1171 11AE;C027;1108 1171 11AE; # (쀧; 쀧; 쀧; 쀧; 쀧; ) HANGUL SYLLABLE BBWID
+C028;C028;1108 1171 11AF;C028;1108 1171 11AF; # (쀨; 쀨; 쀨; 쀨; 쀨; ) HANGUL SYLLABLE BBWIL
+C029;C029;1108 1171 11B0;C029;1108 1171 11B0; # (쀩; 쀩; 쀩; 쀩; 쀩; ) HANGUL SYLLABLE BBWILG
+C02A;C02A;1108 1171 11B1;C02A;1108 1171 11B1; # (쀪; 쀪; 쀪; 쀪; 쀪; ) HANGUL SYLLABLE BBWILM
+C02B;C02B;1108 1171 11B2;C02B;1108 1171 11B2; # (쀫; 쀫; 쀫; 쀫; 쀫; ) HANGUL SYLLABLE BBWILB
+C02C;C02C;1108 1171 11B3;C02C;1108 1171 11B3; # (쀬; 쀬; 쀬; 쀬; 쀬; ) HANGUL SYLLABLE BBWILS
+C02D;C02D;1108 1171 11B4;C02D;1108 1171 11B4; # (쀭; 쀭; 쀭; 쀭; 쀭; ) HANGUL SYLLABLE BBWILT
+C02E;C02E;1108 1171 11B5;C02E;1108 1171 11B5; # (쀮; 쀮; 쀮; 쀮; 쀮; ) HANGUL SYLLABLE BBWILP
+C02F;C02F;1108 1171 11B6;C02F;1108 1171 11B6; # (쀯; 쀯; 쀯; 쀯; 쀯; ) HANGUL SYLLABLE BBWILH
+C030;C030;1108 1171 11B7;C030;1108 1171 11B7; # (쀰; 쀰; 쀰; 쀰; 쀰; ) HANGUL SYLLABLE BBWIM
+C031;C031;1108 1171 11B8;C031;1108 1171 11B8; # (쀱; 쀱; 쀱; 쀱; 쀱; ) HANGUL SYLLABLE BBWIB
+C032;C032;1108 1171 11B9;C032;1108 1171 11B9; # (쀲; 쀲; 쀲; 쀲; 쀲; ) HANGUL SYLLABLE BBWIBS
+C033;C033;1108 1171 11BA;C033;1108 1171 11BA; # (쀳; 쀳; 쀳; 쀳; 쀳; ) HANGUL SYLLABLE BBWIS
+C034;C034;1108 1171 11BB;C034;1108 1171 11BB; # (쀴; 쀴; 쀴; 쀴; 쀴; ) HANGUL SYLLABLE BBWISS
+C035;C035;1108 1171 11BC;C035;1108 1171 11BC; # (쀵; 쀵; 쀵; 쀵; 쀵; ) HANGUL SYLLABLE BBWING
+C036;C036;1108 1171 11BD;C036;1108 1171 11BD; # (쀶; 쀶; 쀶; 쀶; 쀶; ) HANGUL SYLLABLE BBWIJ
+C037;C037;1108 1171 11BE;C037;1108 1171 11BE; # (쀷; 쀷; 쀷; 쀷; 쀷; ) HANGUL SYLLABLE BBWIC
+C038;C038;1108 1171 11BF;C038;1108 1171 11BF; # (쀸; 쀸; 쀸; 쀸; 쀸; ) HANGUL SYLLABLE BBWIK
+C039;C039;1108 1171 11C0;C039;1108 1171 11C0; # (쀹; 쀹; 쀹; 쀹; 쀹; ) HANGUL SYLLABLE BBWIT
+C03A;C03A;1108 1171 11C1;C03A;1108 1171 11C1; # (쀺; 쀺; 쀺; 쀺; 쀺; ) HANGUL SYLLABLE BBWIP
+C03B;C03B;1108 1171 11C2;C03B;1108 1171 11C2; # (쀻; 쀻; 쀻; 쀻; 쀻; ) HANGUL SYLLABLE BBWIH
+C03C;C03C;1108 1172;C03C;1108 1172; # (쀼; 쀼; 쀼; 쀼; 쀼; ) HANGUL SYLLABLE BBYU
+C03D;C03D;1108 1172 11A8;C03D;1108 1172 11A8; # (쀽; 쀽; 쀽; 쀽; 쀽; ) HANGUL SYLLABLE BBYUG
+C03E;C03E;1108 1172 11A9;C03E;1108 1172 11A9; # (쀾; 쀾; 쀾; 쀾; 쀾; ) HANGUL SYLLABLE BBYUGG
+C03F;C03F;1108 1172 11AA;C03F;1108 1172 11AA; # (쀿; 쀿; 쀿; 쀿; 쀿; ) HANGUL SYLLABLE BBYUGS
+C040;C040;1108 1172 11AB;C040;1108 1172 11AB; # (쁀; 쁀; 쁀; 쁀; 쁀; ) HANGUL SYLLABLE BBYUN
+C041;C041;1108 1172 11AC;C041;1108 1172 11AC; # (쁁; 쁁; 쁁; 쁁; 쁁; ) HANGUL SYLLABLE BBYUNJ
+C042;C042;1108 1172 11AD;C042;1108 1172 11AD; # (쁂; 쁂; 쁂; 쁂; 쁂; ) HANGUL SYLLABLE BBYUNH
+C043;C043;1108 1172 11AE;C043;1108 1172 11AE; # (쁃; 쁃; 쁃; 쁃; 쁃; ) HANGUL SYLLABLE BBYUD
+C044;C044;1108 1172 11AF;C044;1108 1172 11AF; # (쁄; 쁄; 쁄; 쁄; 쁄; ) HANGUL SYLLABLE BBYUL
+C045;C045;1108 1172 11B0;C045;1108 1172 11B0; # (쁅; 쁅; 쁅; 쁅; 쁅; ) HANGUL SYLLABLE BBYULG
+C046;C046;1108 1172 11B1;C046;1108 1172 11B1; # (쁆; 쁆; 쁆; 쁆; 쁆; ) HANGUL SYLLABLE BBYULM
+C047;C047;1108 1172 11B2;C047;1108 1172 11B2; # (쁇; 쁇; 쁇; 쁇; 쁇; ) HANGUL SYLLABLE BBYULB
+C048;C048;1108 1172 11B3;C048;1108 1172 11B3; # (쁈; 쁈; 쁈; 쁈; 쁈; ) HANGUL SYLLABLE BBYULS
+C049;C049;1108 1172 11B4;C049;1108 1172 11B4; # (쁉; 쁉; 쁉; 쁉; 쁉; ) HANGUL SYLLABLE BBYULT
+C04A;C04A;1108 1172 11B5;C04A;1108 1172 11B5; # (쁊; 쁊; 쁊; 쁊; 쁊; ) HANGUL SYLLABLE BBYULP
+C04B;C04B;1108 1172 11B6;C04B;1108 1172 11B6; # (쁋; 쁋; 쁋; 쁋; 쁋; ) HANGUL SYLLABLE BBYULH
+C04C;C04C;1108 1172 11B7;C04C;1108 1172 11B7; # (쁌; 쁌; 쁌; 쁌; 쁌; ) HANGUL SYLLABLE BBYUM
+C04D;C04D;1108 1172 11B8;C04D;1108 1172 11B8; # (쁍; 쁍; 쁍; 쁍; 쁍; ) HANGUL SYLLABLE BBYUB
+C04E;C04E;1108 1172 11B9;C04E;1108 1172 11B9; # (쁎; 쁎; 쁎; 쁎; 쁎; ) HANGUL SYLLABLE BBYUBS
+C04F;C04F;1108 1172 11BA;C04F;1108 1172 11BA; # (쁏; 쁏; 쁏; 쁏; 쁏; ) HANGUL SYLLABLE BBYUS
+C050;C050;1108 1172 11BB;C050;1108 1172 11BB; # (쁐; 쁐; 쁐; 쁐; 쁐; ) HANGUL SYLLABLE BBYUSS
+C051;C051;1108 1172 11BC;C051;1108 1172 11BC; # (쁑; 쁑; 쁑; 쁑; 쁑; ) HANGUL SYLLABLE BBYUNG
+C052;C052;1108 1172 11BD;C052;1108 1172 11BD; # (쁒; 쁒; 쁒; 쁒; 쁒; ) HANGUL SYLLABLE BBYUJ
+C053;C053;1108 1172 11BE;C053;1108 1172 11BE; # (쁓; 쁓; 쁓; 쁓; 쁓; ) HANGUL SYLLABLE BBYUC
+C054;C054;1108 1172 11BF;C054;1108 1172 11BF; # (쁔; 쁔; 쁔; 쁔; 쁔; ) HANGUL SYLLABLE BBYUK
+C055;C055;1108 1172 11C0;C055;1108 1172 11C0; # (쁕; 쁕; 쁕; 쁕; 쁕; ) HANGUL SYLLABLE BBYUT
+C056;C056;1108 1172 11C1;C056;1108 1172 11C1; # (쁖; 쁖; 쁖; 쁖; 쁖; ) HANGUL SYLLABLE BBYUP
+C057;C057;1108 1172 11C2;C057;1108 1172 11C2; # (쁗; 쁗; 쁗; 쁗; 쁗; ) HANGUL SYLLABLE BBYUH
+C058;C058;1108 1173;C058;1108 1173; # (쁘; 쁘; 쁘; 쁘; 쁘; ) HANGUL SYLLABLE BBEU
+C059;C059;1108 1173 11A8;C059;1108 1173 11A8; # (쁙; 쁙; 쁙; 쁙; 쁙; ) HANGUL SYLLABLE BBEUG
+C05A;C05A;1108 1173 11A9;C05A;1108 1173 11A9; # (쁚; 쁚; 쁚; 쁚; 쁚; ) HANGUL SYLLABLE BBEUGG
+C05B;C05B;1108 1173 11AA;C05B;1108 1173 11AA; # (쁛; 쁛; 쁛; 쁛; 쁛; ) HANGUL SYLLABLE BBEUGS
+C05C;C05C;1108 1173 11AB;C05C;1108 1173 11AB; # (쁜; 쁜; 쁜; 쁜; 쁜; ) HANGUL SYLLABLE BBEUN
+C05D;C05D;1108 1173 11AC;C05D;1108 1173 11AC; # (쁝; 쁝; 쁝; 쁝; 쁝; ) HANGUL SYLLABLE BBEUNJ
+C05E;C05E;1108 1173 11AD;C05E;1108 1173 11AD; # (쁞; 쁞; 쁞; 쁞; 쁞; ) HANGUL SYLLABLE BBEUNH
+C05F;C05F;1108 1173 11AE;C05F;1108 1173 11AE; # (쁟; 쁟; 쁟; 쁟; 쁟; ) HANGUL SYLLABLE BBEUD
+C060;C060;1108 1173 11AF;C060;1108 1173 11AF; # (쁠; 쁠; 쁠; 쁠; 쁠; ) HANGUL SYLLABLE BBEUL
+C061;C061;1108 1173 11B0;C061;1108 1173 11B0; # (쁡; 쁡; 쁡; 쁡; 쁡; ) HANGUL SYLLABLE BBEULG
+C062;C062;1108 1173 11B1;C062;1108 1173 11B1; # (쁢; 쁢; 쁢; 쁢; 쁢; ) HANGUL SYLLABLE BBEULM
+C063;C063;1108 1173 11B2;C063;1108 1173 11B2; # (쁣; 쁣; 쁣; 쁣; 쁣; ) HANGUL SYLLABLE BBEULB
+C064;C064;1108 1173 11B3;C064;1108 1173 11B3; # (쁤; 쁤; 쁤; 쁤; 쁤; ) HANGUL SYLLABLE BBEULS
+C065;C065;1108 1173 11B4;C065;1108 1173 11B4; # (쁥; 쁥; 쁥; 쁥; 쁥; ) HANGUL SYLLABLE BBEULT
+C066;C066;1108 1173 11B5;C066;1108 1173 11B5; # (쁦; 쁦; 쁦; 쁦; 쁦; ) HANGUL SYLLABLE BBEULP
+C067;C067;1108 1173 11B6;C067;1108 1173 11B6; # (쁧; 쁧; 쁧; 쁧; 쁧; ) HANGUL SYLLABLE BBEULH
+C068;C068;1108 1173 11B7;C068;1108 1173 11B7; # (쁨; 쁨; 쁨; 쁨; 쁨; ) HANGUL SYLLABLE BBEUM
+C069;C069;1108 1173 11B8;C069;1108 1173 11B8; # (쁩; 쁩; 쁩; 쁩; 쁩; ) HANGUL SYLLABLE BBEUB
+C06A;C06A;1108 1173 11B9;C06A;1108 1173 11B9; # (쁪; 쁪; 쁪; 쁪; 쁪; ) HANGUL SYLLABLE BBEUBS
+C06B;C06B;1108 1173 11BA;C06B;1108 1173 11BA; # (쁫; 쁫; 쁫; 쁫; 쁫; ) HANGUL SYLLABLE BBEUS
+C06C;C06C;1108 1173 11BB;C06C;1108 1173 11BB; # (쁬; 쁬; 쁬; 쁬; 쁬; ) HANGUL SYLLABLE BBEUSS
+C06D;C06D;1108 1173 11BC;C06D;1108 1173 11BC; # (쁭; 쁭; 쁭; 쁭; 쁭; ) HANGUL SYLLABLE BBEUNG
+C06E;C06E;1108 1173 11BD;C06E;1108 1173 11BD; # (쁮; 쁮; 쁮; 쁮; 쁮; ) HANGUL SYLLABLE BBEUJ
+C06F;C06F;1108 1173 11BE;C06F;1108 1173 11BE; # (쁯; 쁯; 쁯; 쁯; 쁯; ) HANGUL SYLLABLE BBEUC
+C070;C070;1108 1173 11BF;C070;1108 1173 11BF; # (쁰; 쁰; 쁰; 쁰; 쁰; ) HANGUL SYLLABLE BBEUK
+C071;C071;1108 1173 11C0;C071;1108 1173 11C0; # (쁱; 쁱; 쁱; 쁱; 쁱; ) HANGUL SYLLABLE BBEUT
+C072;C072;1108 1173 11C1;C072;1108 1173 11C1; # (쁲; 쁲; 쁲; 쁲; 쁲; ) HANGUL SYLLABLE BBEUP
+C073;C073;1108 1173 11C2;C073;1108 1173 11C2; # (쁳; 쁳; 쁳; 쁳; 쁳; ) HANGUL SYLLABLE BBEUH
+C074;C074;1108 1174;C074;1108 1174; # (쁴; 쁴; 쁴; 쁴; 쁴; ) HANGUL SYLLABLE BBYI
+C075;C075;1108 1174 11A8;C075;1108 1174 11A8; # (쁵; 쁵; 쁵; 쁵; 쁵; ) HANGUL SYLLABLE BBYIG
+C076;C076;1108 1174 11A9;C076;1108 1174 11A9; # (쁶; 쁶; 쁶; 쁶; 쁶; ) HANGUL SYLLABLE BBYIGG
+C077;C077;1108 1174 11AA;C077;1108 1174 11AA; # (쁷; 쁷; 쁷; 쁷; 쁷; ) HANGUL SYLLABLE BBYIGS
+C078;C078;1108 1174 11AB;C078;1108 1174 11AB; # (쁸; 쁸; 쁸; 쁸; 쁸; ) HANGUL SYLLABLE BBYIN
+C079;C079;1108 1174 11AC;C079;1108 1174 11AC; # (쁹; 쁹; 쁹; 쁹; 쁹; ) HANGUL SYLLABLE BBYINJ
+C07A;C07A;1108 1174 11AD;C07A;1108 1174 11AD; # (쁺; 쁺; 쁺; 쁺; 쁺; ) HANGUL SYLLABLE BBYINH
+C07B;C07B;1108 1174 11AE;C07B;1108 1174 11AE; # (쁻; 쁻; 쁻; 쁻; 쁻; ) HANGUL SYLLABLE BBYID
+C07C;C07C;1108 1174 11AF;C07C;1108 1174 11AF; # (쁼; 쁼; 쁼; 쁼; 쁼; ) HANGUL SYLLABLE BBYIL
+C07D;C07D;1108 1174 11B0;C07D;1108 1174 11B0; # (쁽; 쁽; 쁽; 쁽; 쁽; ) HANGUL SYLLABLE BBYILG
+C07E;C07E;1108 1174 11B1;C07E;1108 1174 11B1; # (쁾; 쁾; 쁾; 쁾; 쁾; ) HANGUL SYLLABLE BBYILM
+C07F;C07F;1108 1174 11B2;C07F;1108 1174 11B2; # (쁿; 쁿; 쁿; 쁿; 쁿; ) HANGUL SYLLABLE BBYILB
+C080;C080;1108 1174 11B3;C080;1108 1174 11B3; # (삀; 삀; 삀; 삀; 삀; ) HANGUL SYLLABLE BBYILS
+C081;C081;1108 1174 11B4;C081;1108 1174 11B4; # (삁; 삁; 삁; 삁; 삁; ) HANGUL SYLLABLE BBYILT
+C082;C082;1108 1174 11B5;C082;1108 1174 11B5; # (삂; 삂; 삂; 삂; 삂; ) HANGUL SYLLABLE BBYILP
+C083;C083;1108 1174 11B6;C083;1108 1174 11B6; # (삃; 삃; 삃; 삃; 삃; ) HANGUL SYLLABLE BBYILH
+C084;C084;1108 1174 11B7;C084;1108 1174 11B7; # (삄; 삄; 삄; 삄; 삄; ) HANGUL SYLLABLE BBYIM
+C085;C085;1108 1174 11B8;C085;1108 1174 11B8; # (삅; 삅; 삅; 삅; 삅; ) HANGUL SYLLABLE BBYIB
+C086;C086;1108 1174 11B9;C086;1108 1174 11B9; # (삆; 삆; 삆; 삆; 삆; ) HANGUL SYLLABLE BBYIBS
+C087;C087;1108 1174 11BA;C087;1108 1174 11BA; # (삇; 삇; 삇; 삇; 삇; ) HANGUL SYLLABLE BBYIS
+C088;C088;1108 1174 11BB;C088;1108 1174 11BB; # (삈; 삈; 삈; 삈; 삈; ) HANGUL SYLLABLE BBYISS
+C089;C089;1108 1174 11BC;C089;1108 1174 11BC; # (삉; 삉; 삉; 삉; 삉; ) HANGUL SYLLABLE BBYING
+C08A;C08A;1108 1174 11BD;C08A;1108 1174 11BD; # (삊; 삊; 삊; 삊; 삊; ) HANGUL SYLLABLE BBYIJ
+C08B;C08B;1108 1174 11BE;C08B;1108 1174 11BE; # (삋; 삋; 삋; 삋; 삋; ) HANGUL SYLLABLE BBYIC
+C08C;C08C;1108 1174 11BF;C08C;1108 1174 11BF; # (삌; 삌; 삌; 삌; 삌; ) HANGUL SYLLABLE BBYIK
+C08D;C08D;1108 1174 11C0;C08D;1108 1174 11C0; # (삍; 삍; 삍; 삍; 삍; ) HANGUL SYLLABLE BBYIT
+C08E;C08E;1108 1174 11C1;C08E;1108 1174 11C1; # (삎; 삎; 삎; 삎; 삎; ) HANGUL SYLLABLE BBYIP
+C08F;C08F;1108 1174 11C2;C08F;1108 1174 11C2; # (삏; 삏; 삏; 삏; 삏; ) HANGUL SYLLABLE BBYIH
+C090;C090;1108 1175;C090;1108 1175; # (삐; 삐; 삐; 삐; 삐; ) HANGUL SYLLABLE BBI
+C091;C091;1108 1175 11A8;C091;1108 1175 11A8; # (삑; 삑; 삑; 삑; 삑; ) HANGUL SYLLABLE BBIG
+C092;C092;1108 1175 11A9;C092;1108 1175 11A9; # (삒; 삒; 삒; 삒; 삒; ) HANGUL SYLLABLE BBIGG
+C093;C093;1108 1175 11AA;C093;1108 1175 11AA; # (삓; 삓; 삓; 삓; 삓; ) HANGUL SYLLABLE BBIGS
+C094;C094;1108 1175 11AB;C094;1108 1175 11AB; # (삔; 삔; 삔; 삔; 삔; ) HANGUL SYLLABLE BBIN
+C095;C095;1108 1175 11AC;C095;1108 1175 11AC; # (삕; 삕; 삕; 삕; 삕; ) HANGUL SYLLABLE BBINJ
+C096;C096;1108 1175 11AD;C096;1108 1175 11AD; # (삖; 삖; 삖; 삖; 삖; ) HANGUL SYLLABLE BBINH
+C097;C097;1108 1175 11AE;C097;1108 1175 11AE; # (삗; 삗; 삗; 삗; 삗; ) HANGUL SYLLABLE BBID
+C098;C098;1108 1175 11AF;C098;1108 1175 11AF; # (삘; 삘; 삘; 삘; 삘; ) HANGUL SYLLABLE BBIL
+C099;C099;1108 1175 11B0;C099;1108 1175 11B0; # (삙; 삙; 삙; 삙; 삙; ) HANGUL SYLLABLE BBILG
+C09A;C09A;1108 1175 11B1;C09A;1108 1175 11B1; # (삚; 삚; 삚; 삚; 삚; ) HANGUL SYLLABLE BBILM
+C09B;C09B;1108 1175 11B2;C09B;1108 1175 11B2; # (삛; 삛; 삛; 삛; 삛; ) HANGUL SYLLABLE BBILB
+C09C;C09C;1108 1175 11B3;C09C;1108 1175 11B3; # (삜; 삜; 삜; 삜; 삜; ) HANGUL SYLLABLE BBILS
+C09D;C09D;1108 1175 11B4;C09D;1108 1175 11B4; # (삝; 삝; 삝; 삝; 삝; ) HANGUL SYLLABLE BBILT
+C09E;C09E;1108 1175 11B5;C09E;1108 1175 11B5; # (삞; 삞; 삞; 삞; 삞; ) HANGUL SYLLABLE BBILP
+C09F;C09F;1108 1175 11B6;C09F;1108 1175 11B6; # (삟; 삟; 삟; 삟; 삟; ) HANGUL SYLLABLE BBILH
+C0A0;C0A0;1108 1175 11B7;C0A0;1108 1175 11B7; # (삠; 삠; 삠; 삠; 삠; ) HANGUL SYLLABLE BBIM
+C0A1;C0A1;1108 1175 11B8;C0A1;1108 1175 11B8; # (삡; 삡; 삡; 삡; 삡; ) HANGUL SYLLABLE BBIB
+C0A2;C0A2;1108 1175 11B9;C0A2;1108 1175 11B9; # (삢; 삢; 삢; 삢; 삢; ) HANGUL SYLLABLE BBIBS
+C0A3;C0A3;1108 1175 11BA;C0A3;1108 1175 11BA; # (삣; 삣; 삣; 삣; 삣; ) HANGUL SYLLABLE BBIS
+C0A4;C0A4;1108 1175 11BB;C0A4;1108 1175 11BB; # (삤; 삤; 삤; 삤; 삤; ) HANGUL SYLLABLE BBISS
+C0A5;C0A5;1108 1175 11BC;C0A5;1108 1175 11BC; # (삥; 삥; 삥; 삥; 삥; ) HANGUL SYLLABLE BBING
+C0A6;C0A6;1108 1175 11BD;C0A6;1108 1175 11BD; # (삦; 삦; 삦; 삦; 삦; ) HANGUL SYLLABLE BBIJ
+C0A7;C0A7;1108 1175 11BE;C0A7;1108 1175 11BE; # (삧; 삧; 삧; 삧; 삧; ) HANGUL SYLLABLE BBIC
+C0A8;C0A8;1108 1175 11BF;C0A8;1108 1175 11BF; # (삨; 삨; 삨; 삨; 삨; ) HANGUL SYLLABLE BBIK
+C0A9;C0A9;1108 1175 11C0;C0A9;1108 1175 11C0; # (삩; 삩; 삩; 삩; 삩; ) HANGUL SYLLABLE BBIT
+C0AA;C0AA;1108 1175 11C1;C0AA;1108 1175 11C1; # (삪; 삪; 삪; 삪; 삪; ) HANGUL SYLLABLE BBIP
+C0AB;C0AB;1108 1175 11C2;C0AB;1108 1175 11C2; # (삫; 삫; 삫; 삫; 삫; ) HANGUL SYLLABLE BBIH
+C0AC;C0AC;1109 1161;C0AC;1109 1161; # (사; 사; 사; 사; 사; ) HANGUL SYLLABLE SA
+C0AD;C0AD;1109 1161 11A8;C0AD;1109 1161 11A8; # (삭; 삭; 삭; 삭; 삭; ) HANGUL SYLLABLE SAG
+C0AE;C0AE;1109 1161 11A9;C0AE;1109 1161 11A9; # (삮; 삮; 삮; 삮; 삮; ) HANGUL SYLLABLE SAGG
+C0AF;C0AF;1109 1161 11AA;C0AF;1109 1161 11AA; # (삯; 삯; 삯; 삯; 삯; ) HANGUL SYLLABLE SAGS
+C0B0;C0B0;1109 1161 11AB;C0B0;1109 1161 11AB; # (산; 산; 산; 산; 산; ) HANGUL SYLLABLE SAN
+C0B1;C0B1;1109 1161 11AC;C0B1;1109 1161 11AC; # (삱; 삱; 삱; 삱; 삱; ) HANGUL SYLLABLE SANJ
+C0B2;C0B2;1109 1161 11AD;C0B2;1109 1161 11AD; # (삲; 삲; 삲; 삲; 삲; ) HANGUL SYLLABLE SANH
+C0B3;C0B3;1109 1161 11AE;C0B3;1109 1161 11AE; # (삳; 삳; 삳; 삳; 삳; ) HANGUL SYLLABLE SAD
+C0B4;C0B4;1109 1161 11AF;C0B4;1109 1161 11AF; # (살; 살; 살; 살; 살; ) HANGUL SYLLABLE SAL
+C0B5;C0B5;1109 1161 11B0;C0B5;1109 1161 11B0; # (삵; 삵; 삵; 삵; 삵; ) HANGUL SYLLABLE SALG
+C0B6;C0B6;1109 1161 11B1;C0B6;1109 1161 11B1; # (삶; 삶; 삶; 삶; 삶; ) HANGUL SYLLABLE SALM
+C0B7;C0B7;1109 1161 11B2;C0B7;1109 1161 11B2; # (삷; 삷; 삷; 삷; 삷; ) HANGUL SYLLABLE SALB
+C0B8;C0B8;1109 1161 11B3;C0B8;1109 1161 11B3; # (삸; 삸; 삸; 삸; 삸; ) HANGUL SYLLABLE SALS
+C0B9;C0B9;1109 1161 11B4;C0B9;1109 1161 11B4; # (삹; 삹; 삹; 삹; 삹; ) HANGUL SYLLABLE SALT
+C0BA;C0BA;1109 1161 11B5;C0BA;1109 1161 11B5; # (삺; 삺; 삺; 삺; 삺; ) HANGUL SYLLABLE SALP
+C0BB;C0BB;1109 1161 11B6;C0BB;1109 1161 11B6; # (삻; 삻; 삻; 삻; 삻; ) HANGUL SYLLABLE SALH
+C0BC;C0BC;1109 1161 11B7;C0BC;1109 1161 11B7; # (삼; 삼; 삼; 삼; 삼; ) HANGUL SYLLABLE SAM
+C0BD;C0BD;1109 1161 11B8;C0BD;1109 1161 11B8; # (삽; 삽; 삽; 삽; 삽; ) HANGUL SYLLABLE SAB
+C0BE;C0BE;1109 1161 11B9;C0BE;1109 1161 11B9; # (삾; 삾; 삾; 삾; 삾; ) HANGUL SYLLABLE SABS
+C0BF;C0BF;1109 1161 11BA;C0BF;1109 1161 11BA; # (삿; 삿; 삿; 삿; 삿; ) HANGUL SYLLABLE SAS
+C0C0;C0C0;1109 1161 11BB;C0C0;1109 1161 11BB; # (샀; 샀; 샀; 샀; 샀; ) HANGUL SYLLABLE SASS
+C0C1;C0C1;1109 1161 11BC;C0C1;1109 1161 11BC; # (상; 상; 상; 상; 상; ) HANGUL SYLLABLE SANG
+C0C2;C0C2;1109 1161 11BD;C0C2;1109 1161 11BD; # (샂; 샂; 샂; 샂; 샂; ) HANGUL SYLLABLE SAJ
+C0C3;C0C3;1109 1161 11BE;C0C3;1109 1161 11BE; # (샃; 샃; 샃; 샃; 샃; ) HANGUL SYLLABLE SAC
+C0C4;C0C4;1109 1161 11BF;C0C4;1109 1161 11BF; # (샄; 샄; 샄; 샄; 샄; ) HANGUL SYLLABLE SAK
+C0C5;C0C5;1109 1161 11C0;C0C5;1109 1161 11C0; # (샅; 샅; 샅; 샅; 샅; ) HANGUL SYLLABLE SAT
+C0C6;C0C6;1109 1161 11C1;C0C6;1109 1161 11C1; # (샆; 샆; 샆; 샆; 샆; ) HANGUL SYLLABLE SAP
+C0C7;C0C7;1109 1161 11C2;C0C7;1109 1161 11C2; # (샇; 샇; 샇; 샇; 샇; ) HANGUL SYLLABLE SAH
+C0C8;C0C8;1109 1162;C0C8;1109 1162; # (새; 새; 새; 새; 새; ) HANGUL SYLLABLE SAE
+C0C9;C0C9;1109 1162 11A8;C0C9;1109 1162 11A8; # (색; 색; 색; 색; 색; ) HANGUL SYLLABLE SAEG
+C0CA;C0CA;1109 1162 11A9;C0CA;1109 1162 11A9; # (샊; 샊; 샊; 샊; 샊; ) HANGUL SYLLABLE SAEGG
+C0CB;C0CB;1109 1162 11AA;C0CB;1109 1162 11AA; # (샋; 샋; 샋; 샋; 샋; ) HANGUL SYLLABLE SAEGS
+C0CC;C0CC;1109 1162 11AB;C0CC;1109 1162 11AB; # (샌; 샌; 샌; 샌; 샌; ) HANGUL SYLLABLE SAEN
+C0CD;C0CD;1109 1162 11AC;C0CD;1109 1162 11AC; # (샍; 샍; 샍; 샍; 샍; ) HANGUL SYLLABLE SAENJ
+C0CE;C0CE;1109 1162 11AD;C0CE;1109 1162 11AD; # (샎; 샎; 샎; 샎; 샎; ) HANGUL SYLLABLE SAENH
+C0CF;C0CF;1109 1162 11AE;C0CF;1109 1162 11AE; # (샏; 샏; 샏; 샏; 샏; ) HANGUL SYLLABLE SAED
+C0D0;C0D0;1109 1162 11AF;C0D0;1109 1162 11AF; # (샐; 샐; 샐; 샐; 샐; ) HANGUL SYLLABLE SAEL
+C0D1;C0D1;1109 1162 11B0;C0D1;1109 1162 11B0; # (샑; 샑; 샑; 샑; 샑; ) HANGUL SYLLABLE SAELG
+C0D2;C0D2;1109 1162 11B1;C0D2;1109 1162 11B1; # (샒; 샒; 샒; 샒; 샒; ) HANGUL SYLLABLE SAELM
+C0D3;C0D3;1109 1162 11B2;C0D3;1109 1162 11B2; # (샓; 샓; 샓; 샓; 샓; ) HANGUL SYLLABLE SAELB
+C0D4;C0D4;1109 1162 11B3;C0D4;1109 1162 11B3; # (샔; 샔; 샔; 샔; 샔; ) HANGUL SYLLABLE SAELS
+C0D5;C0D5;1109 1162 11B4;C0D5;1109 1162 11B4; # (샕; 샕; 샕; 샕; 샕; ) HANGUL SYLLABLE SAELT
+C0D6;C0D6;1109 1162 11B5;C0D6;1109 1162 11B5; # (샖; 샖; 샖; 샖; 샖; ) HANGUL SYLLABLE SAELP
+C0D7;C0D7;1109 1162 11B6;C0D7;1109 1162 11B6; # (샗; 샗; 샗; 샗; 샗; ) HANGUL SYLLABLE SAELH
+C0D8;C0D8;1109 1162 11B7;C0D8;1109 1162 11B7; # (샘; 샘; 샘; 샘; 샘; ) HANGUL SYLLABLE SAEM
+C0D9;C0D9;1109 1162 11B8;C0D9;1109 1162 11B8; # (샙; 샙; 샙; 샙; 샙; ) HANGUL SYLLABLE SAEB
+C0DA;C0DA;1109 1162 11B9;C0DA;1109 1162 11B9; # (샚; 샚; 샚; 샚; 샚; ) HANGUL SYLLABLE SAEBS
+C0DB;C0DB;1109 1162 11BA;C0DB;1109 1162 11BA; # (샛; 샛; 샛; 샛; 샛; ) HANGUL SYLLABLE SAES
+C0DC;C0DC;1109 1162 11BB;C0DC;1109 1162 11BB; # (샜; 샜; 샜; 샜; 샜; ) HANGUL SYLLABLE SAESS
+C0DD;C0DD;1109 1162 11BC;C0DD;1109 1162 11BC; # (생; 생; 생; 생; 생; ) HANGUL SYLLABLE SAENG
+C0DE;C0DE;1109 1162 11BD;C0DE;1109 1162 11BD; # (샞; 샞; 샞; 샞; 샞; ) HANGUL SYLLABLE SAEJ
+C0DF;C0DF;1109 1162 11BE;C0DF;1109 1162 11BE; # (샟; 샟; 샟; 샟; 샟; ) HANGUL SYLLABLE SAEC
+C0E0;C0E0;1109 1162 11BF;C0E0;1109 1162 11BF; # (샠; 샠; 샠; 샠; 샠; ) HANGUL SYLLABLE SAEK
+C0E1;C0E1;1109 1162 11C0;C0E1;1109 1162 11C0; # (샡; 샡; 샡; 샡; 샡; ) HANGUL SYLLABLE SAET
+C0E2;C0E2;1109 1162 11C1;C0E2;1109 1162 11C1; # (샢; 샢; 샢; 샢; 샢; ) HANGUL SYLLABLE SAEP
+C0E3;C0E3;1109 1162 11C2;C0E3;1109 1162 11C2; # (샣; 샣; 샣; 샣; 샣; ) HANGUL SYLLABLE SAEH
+C0E4;C0E4;1109 1163;C0E4;1109 1163; # (샤; 샤; 샤; 샤; 샤; ) HANGUL SYLLABLE SYA
+C0E5;C0E5;1109 1163 11A8;C0E5;1109 1163 11A8; # (샥; 샥; 샥; 샥; 샥; ) HANGUL SYLLABLE SYAG
+C0E6;C0E6;1109 1163 11A9;C0E6;1109 1163 11A9; # (샦; 샦; 샦; 샦; 샦; ) HANGUL SYLLABLE SYAGG
+C0E7;C0E7;1109 1163 11AA;C0E7;1109 1163 11AA; # (샧; 샧; 샧; 샧; 샧; ) HANGUL SYLLABLE SYAGS
+C0E8;C0E8;1109 1163 11AB;C0E8;1109 1163 11AB; # (샨; 샨; 샨; 샨; 샨; ) HANGUL SYLLABLE SYAN
+C0E9;C0E9;1109 1163 11AC;C0E9;1109 1163 11AC; # (샩; 샩; 샩; 샩; 샩; ) HANGUL SYLLABLE SYANJ
+C0EA;C0EA;1109 1163 11AD;C0EA;1109 1163 11AD; # (샪; 샪; 샪; 샪; 샪; ) HANGUL SYLLABLE SYANH
+C0EB;C0EB;1109 1163 11AE;C0EB;1109 1163 11AE; # (샫; 샫; 샫; 샫; 샫; ) HANGUL SYLLABLE SYAD
+C0EC;C0EC;1109 1163 11AF;C0EC;1109 1163 11AF; # (샬; 샬; 샬; 샬; 샬; ) HANGUL SYLLABLE SYAL
+C0ED;C0ED;1109 1163 11B0;C0ED;1109 1163 11B0; # (샭; 샭; 샭; 샭; 샭; ) HANGUL SYLLABLE SYALG
+C0EE;C0EE;1109 1163 11B1;C0EE;1109 1163 11B1; # (샮; 샮; 샮; 샮; 샮; ) HANGUL SYLLABLE SYALM
+C0EF;C0EF;1109 1163 11B2;C0EF;1109 1163 11B2; # (샯; 샯; 샯; 샯; 샯; ) HANGUL SYLLABLE SYALB
+C0F0;C0F0;1109 1163 11B3;C0F0;1109 1163 11B3; # (샰; 샰; 샰; 샰; 샰; ) HANGUL SYLLABLE SYALS
+C0F1;C0F1;1109 1163 11B4;C0F1;1109 1163 11B4; # (샱; 샱; 샱; 샱; 샱; ) HANGUL SYLLABLE SYALT
+C0F2;C0F2;1109 1163 11B5;C0F2;1109 1163 11B5; # (샲; 샲; 샲; 샲; 샲; ) HANGUL SYLLABLE SYALP
+C0F3;C0F3;1109 1163 11B6;C0F3;1109 1163 11B6; # (샳; 샳; 샳; 샳; 샳; ) HANGUL SYLLABLE SYALH
+C0F4;C0F4;1109 1163 11B7;C0F4;1109 1163 11B7; # (샴; 샴; 샴; 샴; 샴; ) HANGUL SYLLABLE SYAM
+C0F5;C0F5;1109 1163 11B8;C0F5;1109 1163 11B8; # (샵; 샵; 샵; 샵; 샵; ) HANGUL SYLLABLE SYAB
+C0F6;C0F6;1109 1163 11B9;C0F6;1109 1163 11B9; # (샶; 샶; 샶; 샶; 샶; ) HANGUL SYLLABLE SYABS
+C0F7;C0F7;1109 1163 11BA;C0F7;1109 1163 11BA; # (샷; 샷; 샷; 샷; 샷; ) HANGUL SYLLABLE SYAS
+C0F8;C0F8;1109 1163 11BB;C0F8;1109 1163 11BB; # (샸; 샸; 샸; 샸; 샸; ) HANGUL SYLLABLE SYASS
+C0F9;C0F9;1109 1163 11BC;C0F9;1109 1163 11BC; # (샹; 샹; 샹; 샹; 샹; ) HANGUL SYLLABLE SYANG
+C0FA;C0FA;1109 1163 11BD;C0FA;1109 1163 11BD; # (샺; 샺; 샺; 샺; 샺; ) HANGUL SYLLABLE SYAJ
+C0FB;C0FB;1109 1163 11BE;C0FB;1109 1163 11BE; # (샻; 샻; 샻; 샻; 샻; ) HANGUL SYLLABLE SYAC
+C0FC;C0FC;1109 1163 11BF;C0FC;1109 1163 11BF; # (샼; 샼; 샼; 샼; 샼; ) HANGUL SYLLABLE SYAK
+C0FD;C0FD;1109 1163 11C0;C0FD;1109 1163 11C0; # (샽; 샽; 샽; 샽; 샽; ) HANGUL SYLLABLE SYAT
+C0FE;C0FE;1109 1163 11C1;C0FE;1109 1163 11C1; # (샾; 샾; 샾; 샾; 샾; ) HANGUL SYLLABLE SYAP
+C0FF;C0FF;1109 1163 11C2;C0FF;1109 1163 11C2; # (샿; 샿; 샿; 샿; 샿; ) HANGUL SYLLABLE SYAH
+C100;C100;1109 1164;C100;1109 1164; # (섀; 섀; 섀; 섀; 섀; ) HANGUL SYLLABLE SYAE
+C101;C101;1109 1164 11A8;C101;1109 1164 11A8; # (섁; 섁; 섁; 섁; 섁; ) HANGUL SYLLABLE SYAEG
+C102;C102;1109 1164 11A9;C102;1109 1164 11A9; # (섂; 섂; 섂; 섂; 섂; ) HANGUL SYLLABLE SYAEGG
+C103;C103;1109 1164 11AA;C103;1109 1164 11AA; # (섃; 섃; 섃; 섃; 섃; ) HANGUL SYLLABLE SYAEGS
+C104;C104;1109 1164 11AB;C104;1109 1164 11AB; # (섄; 섄; 섄; 섄; 섄; ) HANGUL SYLLABLE SYAEN
+C105;C105;1109 1164 11AC;C105;1109 1164 11AC; # (섅; 섅; 섅; 섅; 섅; ) HANGUL SYLLABLE SYAENJ
+C106;C106;1109 1164 11AD;C106;1109 1164 11AD; # (섆; 섆; 섆; 섆; 섆; ) HANGUL SYLLABLE SYAENH
+C107;C107;1109 1164 11AE;C107;1109 1164 11AE; # (섇; 섇; 섇; 섇; 섇; ) HANGUL SYLLABLE SYAED
+C108;C108;1109 1164 11AF;C108;1109 1164 11AF; # (섈; 섈; 섈; 섈; 섈; ) HANGUL SYLLABLE SYAEL
+C109;C109;1109 1164 11B0;C109;1109 1164 11B0; # (섉; 섉; 섉; 섉; 섉; ) HANGUL SYLLABLE SYAELG
+C10A;C10A;1109 1164 11B1;C10A;1109 1164 11B1; # (섊; 섊; 섊; 섊; 섊; ) HANGUL SYLLABLE SYAELM
+C10B;C10B;1109 1164 11B2;C10B;1109 1164 11B2; # (섋; 섋; 섋; 섋; 섋; ) HANGUL SYLLABLE SYAELB
+C10C;C10C;1109 1164 11B3;C10C;1109 1164 11B3; # (섌; 섌; 섌; 섌; 섌; ) HANGUL SYLLABLE SYAELS
+C10D;C10D;1109 1164 11B4;C10D;1109 1164 11B4; # (섍; 섍; 섍; 섍; 섍; ) HANGUL SYLLABLE SYAELT
+C10E;C10E;1109 1164 11B5;C10E;1109 1164 11B5; # (섎; 섎; 섎; 섎; 섎; ) HANGUL SYLLABLE SYAELP
+C10F;C10F;1109 1164 11B6;C10F;1109 1164 11B6; # (섏; 섏; 섏; 섏; 섏; ) HANGUL SYLLABLE SYAELH
+C110;C110;1109 1164 11B7;C110;1109 1164 11B7; # (섐; 섐; 섐; 섐; 섐; ) HANGUL SYLLABLE SYAEM
+C111;C111;1109 1164 11B8;C111;1109 1164 11B8; # (섑; 섑; 섑; 섑; 섑; ) HANGUL SYLLABLE SYAEB
+C112;C112;1109 1164 11B9;C112;1109 1164 11B9; # (섒; 섒; 섒; 섒; 섒; ) HANGUL SYLLABLE SYAEBS
+C113;C113;1109 1164 11BA;C113;1109 1164 11BA; # (섓; 섓; 섓; 섓; 섓; ) HANGUL SYLLABLE SYAES
+C114;C114;1109 1164 11BB;C114;1109 1164 11BB; # (섔; 섔; 섔; 섔; 섔; ) HANGUL SYLLABLE SYAESS
+C115;C115;1109 1164 11BC;C115;1109 1164 11BC; # (섕; 섕; 섕; 섕; 섕; ) HANGUL SYLLABLE SYAENG
+C116;C116;1109 1164 11BD;C116;1109 1164 11BD; # (섖; 섖; 섖; 섖; 섖; ) HANGUL SYLLABLE SYAEJ
+C117;C117;1109 1164 11BE;C117;1109 1164 11BE; # (섗; 섗; 섗; 섗; 섗; ) HANGUL SYLLABLE SYAEC
+C118;C118;1109 1164 11BF;C118;1109 1164 11BF; # (섘; 섘; 섘; 섘; 섘; ) HANGUL SYLLABLE SYAEK
+C119;C119;1109 1164 11C0;C119;1109 1164 11C0; # (섙; 섙; 섙; 섙; 섙; ) HANGUL SYLLABLE SYAET
+C11A;C11A;1109 1164 11C1;C11A;1109 1164 11C1; # (섚; 섚; 섚; 섚; 섚; ) HANGUL SYLLABLE SYAEP
+C11B;C11B;1109 1164 11C2;C11B;1109 1164 11C2; # (섛; 섛; 섛; 섛; 섛; ) HANGUL SYLLABLE SYAEH
+C11C;C11C;1109 1165;C11C;1109 1165; # (서; 서; 서; 서; 서; ) HANGUL SYLLABLE SEO
+C11D;C11D;1109 1165 11A8;C11D;1109 1165 11A8; # (석; 석; 석; 석; 석; ) HANGUL SYLLABLE SEOG
+C11E;C11E;1109 1165 11A9;C11E;1109 1165 11A9; # (섞; 섞; 섞; 섞; 섞; ) HANGUL SYLLABLE SEOGG
+C11F;C11F;1109 1165 11AA;C11F;1109 1165 11AA; # (섟; 섟; 섟; 섟; 섟; ) HANGUL SYLLABLE SEOGS
+C120;C120;1109 1165 11AB;C120;1109 1165 11AB; # (선; 선; 선; 선; 선; ) HANGUL SYLLABLE SEON
+C121;C121;1109 1165 11AC;C121;1109 1165 11AC; # (섡; 섡; 섡; 섡; 섡; ) HANGUL SYLLABLE SEONJ
+C122;C122;1109 1165 11AD;C122;1109 1165 11AD; # (섢; 섢; 섢; 섢; 섢; ) HANGUL SYLLABLE SEONH
+C123;C123;1109 1165 11AE;C123;1109 1165 11AE; # (섣; 섣; 섣; 섣; 섣; ) HANGUL SYLLABLE SEOD
+C124;C124;1109 1165 11AF;C124;1109 1165 11AF; # (설; 설; 설; 설; 설; ) HANGUL SYLLABLE SEOL
+C125;C125;1109 1165 11B0;C125;1109 1165 11B0; # (섥; 섥; 섥; 섥; 섥; ) HANGUL SYLLABLE SEOLG
+C126;C126;1109 1165 11B1;C126;1109 1165 11B1; # (섦; 섦; 섦; 섦; 섦; ) HANGUL SYLLABLE SEOLM
+C127;C127;1109 1165 11B2;C127;1109 1165 11B2; # (섧; 섧; 섧; 섧; 섧; ) HANGUL SYLLABLE SEOLB
+C128;C128;1109 1165 11B3;C128;1109 1165 11B3; # (섨; 섨; 섨; 섨; 섨; ) HANGUL SYLLABLE SEOLS
+C129;C129;1109 1165 11B4;C129;1109 1165 11B4; # (섩; 섩; 섩; 섩; 섩; ) HANGUL SYLLABLE SEOLT
+C12A;C12A;1109 1165 11B5;C12A;1109 1165 11B5; # (섪; 섪; 섪; 섪; 섪; ) HANGUL SYLLABLE SEOLP
+C12B;C12B;1109 1165 11B6;C12B;1109 1165 11B6; # (섫; 섫; 섫; 섫; 섫; ) HANGUL SYLLABLE SEOLH
+C12C;C12C;1109 1165 11B7;C12C;1109 1165 11B7; # (섬; 섬; 섬; 섬; 섬; ) HANGUL SYLLABLE SEOM
+C12D;C12D;1109 1165 11B8;C12D;1109 1165 11B8; # (섭; 섭; 섭; 섭; 섭; ) HANGUL SYLLABLE SEOB
+C12E;C12E;1109 1165 11B9;C12E;1109 1165 11B9; # (섮; 섮; 섮; 섮; 섮; ) HANGUL SYLLABLE SEOBS
+C12F;C12F;1109 1165 11BA;C12F;1109 1165 11BA; # (섯; 섯; 섯; 섯; 섯; ) HANGUL SYLLABLE SEOS
+C130;C130;1109 1165 11BB;C130;1109 1165 11BB; # (섰; 섰; 섰; 섰; 섰; ) HANGUL SYLLABLE SEOSS
+C131;C131;1109 1165 11BC;C131;1109 1165 11BC; # (성; 성; 성; 성; 성; ) HANGUL SYLLABLE SEONG
+C132;C132;1109 1165 11BD;C132;1109 1165 11BD; # (섲; 섲; 섲; 섲; 섲; ) HANGUL SYLLABLE SEOJ
+C133;C133;1109 1165 11BE;C133;1109 1165 11BE; # (섳; 섳; 섳; 섳; 섳; ) HANGUL SYLLABLE SEOC
+C134;C134;1109 1165 11BF;C134;1109 1165 11BF; # (섴; 섴; 섴; 섴; 섴; ) HANGUL SYLLABLE SEOK
+C135;C135;1109 1165 11C0;C135;1109 1165 11C0; # (섵; 섵; 섵; 섵; 섵; ) HANGUL SYLLABLE SEOT
+C136;C136;1109 1165 11C1;C136;1109 1165 11C1; # (섶; 섶; 섶; 섶; 섶; ) HANGUL SYLLABLE SEOP
+C137;C137;1109 1165 11C2;C137;1109 1165 11C2; # (섷; 섷; 섷; 섷; 섷; ) HANGUL SYLLABLE SEOH
+C138;C138;1109 1166;C138;1109 1166; # (세; 세; 세; 세; 세; ) HANGUL SYLLABLE SE
+C139;C139;1109 1166 11A8;C139;1109 1166 11A8; # (섹; 섹; 섹; 섹; 섹; ) HANGUL SYLLABLE SEG
+C13A;C13A;1109 1166 11A9;C13A;1109 1166 11A9; # (섺; 섺; 섺; 섺; 섺; ) HANGUL SYLLABLE SEGG
+C13B;C13B;1109 1166 11AA;C13B;1109 1166 11AA; # (섻; 섻; 섻; 섻; 섻; ) HANGUL SYLLABLE SEGS
+C13C;C13C;1109 1166 11AB;C13C;1109 1166 11AB; # (센; 센; 센; 센; 센; ) HANGUL SYLLABLE SEN
+C13D;C13D;1109 1166 11AC;C13D;1109 1166 11AC; # (섽; 섽; 섽; 섽; 섽; ) HANGUL SYLLABLE SENJ
+C13E;C13E;1109 1166 11AD;C13E;1109 1166 11AD; # (섾; 섾; 섾; 섾; 섾; ) HANGUL SYLLABLE SENH
+C13F;C13F;1109 1166 11AE;C13F;1109 1166 11AE; # (섿; 섿; 섿; 섿; 섿; ) HANGUL SYLLABLE SED
+C140;C140;1109 1166 11AF;C140;1109 1166 11AF; # (셀; 셀; 셀; 셀; 셀; ) HANGUL SYLLABLE SEL
+C141;C141;1109 1166 11B0;C141;1109 1166 11B0; # (셁; 셁; 셁; 셁; 셁; ) HANGUL SYLLABLE SELG
+C142;C142;1109 1166 11B1;C142;1109 1166 11B1; # (셂; 셂; 셂; 셂; 셂; ) HANGUL SYLLABLE SELM
+C143;C143;1109 1166 11B2;C143;1109 1166 11B2; # (셃; 셃; 셃; 셃; 셃; ) HANGUL SYLLABLE SELB
+C144;C144;1109 1166 11B3;C144;1109 1166 11B3; # (셄; 셄; 셄; 셄; 셄; ) HANGUL SYLLABLE SELS
+C145;C145;1109 1166 11B4;C145;1109 1166 11B4; # (셅; 셅; 셅; 셅; 셅; ) HANGUL SYLLABLE SELT
+C146;C146;1109 1166 11B5;C146;1109 1166 11B5; # (셆; 셆; 셆; 셆; 셆; ) HANGUL SYLLABLE SELP
+C147;C147;1109 1166 11B6;C147;1109 1166 11B6; # (셇; 셇; 셇; 셇; 셇; ) HANGUL SYLLABLE SELH
+C148;C148;1109 1166 11B7;C148;1109 1166 11B7; # (셈; 셈; 셈; 셈; 셈; ) HANGUL SYLLABLE SEM
+C149;C149;1109 1166 11B8;C149;1109 1166 11B8; # (셉; 셉; 셉; 셉; 셉; ) HANGUL SYLLABLE SEB
+C14A;C14A;1109 1166 11B9;C14A;1109 1166 11B9; # (셊; 셊; 셊; 셊; 셊; ) HANGUL SYLLABLE SEBS
+C14B;C14B;1109 1166 11BA;C14B;1109 1166 11BA; # (셋; 셋; 셋; 셋; 셋; ) HANGUL SYLLABLE SES
+C14C;C14C;1109 1166 11BB;C14C;1109 1166 11BB; # (셌; 셌; 셌; 셌; 셌; ) HANGUL SYLLABLE SESS
+C14D;C14D;1109 1166 11BC;C14D;1109 1166 11BC; # (셍; 셍; 셍; 셍; 셍; ) HANGUL SYLLABLE SENG
+C14E;C14E;1109 1166 11BD;C14E;1109 1166 11BD; # (셎; 셎; 셎; 셎; 셎; ) HANGUL SYLLABLE SEJ
+C14F;C14F;1109 1166 11BE;C14F;1109 1166 11BE; # (셏; 셏; 셏; 셏; 셏; ) HANGUL SYLLABLE SEC
+C150;C150;1109 1166 11BF;C150;1109 1166 11BF; # (셐; 셐; 셐; 셐; 셐; ) HANGUL SYLLABLE SEK
+C151;C151;1109 1166 11C0;C151;1109 1166 11C0; # (셑; 셑; 셑; 셑; 셑; ) HANGUL SYLLABLE SET
+C152;C152;1109 1166 11C1;C152;1109 1166 11C1; # (셒; 셒; 셒; 셒; 셒; ) HANGUL SYLLABLE SEP
+C153;C153;1109 1166 11C2;C153;1109 1166 11C2; # (셓; 셓; 셓; 셓; 셓; ) HANGUL SYLLABLE SEH
+C154;C154;1109 1167;C154;1109 1167; # (셔; 셔; 셔; 셔; 셔; ) HANGUL SYLLABLE SYEO
+C155;C155;1109 1167 11A8;C155;1109 1167 11A8; # (셕; 셕; 셕; 셕; 셕; ) HANGUL SYLLABLE SYEOG
+C156;C156;1109 1167 11A9;C156;1109 1167 11A9; # (셖; 셖; 셖; 셖; 셖; ) HANGUL SYLLABLE SYEOGG
+C157;C157;1109 1167 11AA;C157;1109 1167 11AA; # (셗; 셗; 셗; 셗; 셗; ) HANGUL SYLLABLE SYEOGS
+C158;C158;1109 1167 11AB;C158;1109 1167 11AB; # (션; 션; 션; 션; 션; ) HANGUL SYLLABLE SYEON
+C159;C159;1109 1167 11AC;C159;1109 1167 11AC; # (셙; 셙; 셙; 셙; 셙; ) HANGUL SYLLABLE SYEONJ
+C15A;C15A;1109 1167 11AD;C15A;1109 1167 11AD; # (셚; 셚; 셚; 셚; 셚; ) HANGUL SYLLABLE SYEONH
+C15B;C15B;1109 1167 11AE;C15B;1109 1167 11AE; # (셛; 셛; 셛; 셛; 셛; ) HANGUL SYLLABLE SYEOD
+C15C;C15C;1109 1167 11AF;C15C;1109 1167 11AF; # (셜; 셜; 셜; 셜; 셜; ) HANGUL SYLLABLE SYEOL
+C15D;C15D;1109 1167 11B0;C15D;1109 1167 11B0; # (셝; 셝; 셝; 셝; 셝; ) HANGUL SYLLABLE SYEOLG
+C15E;C15E;1109 1167 11B1;C15E;1109 1167 11B1; # (셞; 셞; 셞; 셞; 셞; ) HANGUL SYLLABLE SYEOLM
+C15F;C15F;1109 1167 11B2;C15F;1109 1167 11B2; # (셟; 셟; 셟; 셟; 셟; ) HANGUL SYLLABLE SYEOLB
+C160;C160;1109 1167 11B3;C160;1109 1167 11B3; # (셠; 셠; 셠; 셠; 셠; ) HANGUL SYLLABLE SYEOLS
+C161;C161;1109 1167 11B4;C161;1109 1167 11B4; # (셡; 셡; 셡; 셡; 셡; ) HANGUL SYLLABLE SYEOLT
+C162;C162;1109 1167 11B5;C162;1109 1167 11B5; # (셢; 셢; 셢; 셢; 셢; ) HANGUL SYLLABLE SYEOLP
+C163;C163;1109 1167 11B6;C163;1109 1167 11B6; # (셣; 셣; 셣; 셣; 셣; ) HANGUL SYLLABLE SYEOLH
+C164;C164;1109 1167 11B7;C164;1109 1167 11B7; # (셤; 셤; 셤; 셤; 셤; ) HANGUL SYLLABLE SYEOM
+C165;C165;1109 1167 11B8;C165;1109 1167 11B8; # (셥; 셥; 셥; 셥; 셥; ) HANGUL SYLLABLE SYEOB
+C166;C166;1109 1167 11B9;C166;1109 1167 11B9; # (셦; 셦; 셦; 셦; 셦; ) HANGUL SYLLABLE SYEOBS
+C167;C167;1109 1167 11BA;C167;1109 1167 11BA; # (셧; 셧; 셧; 셧; 셧; ) HANGUL SYLLABLE SYEOS
+C168;C168;1109 1167 11BB;C168;1109 1167 11BB; # (셨; 셨; 셨; 셨; 셨; ) HANGUL SYLLABLE SYEOSS
+C169;C169;1109 1167 11BC;C169;1109 1167 11BC; # (셩; 셩; 셩; 셩; 셩; ) HANGUL SYLLABLE SYEONG
+C16A;C16A;1109 1167 11BD;C16A;1109 1167 11BD; # (셪; 셪; 셪; 셪; 셪; ) HANGUL SYLLABLE SYEOJ
+C16B;C16B;1109 1167 11BE;C16B;1109 1167 11BE; # (셫; 셫; 셫; 셫; 셫; ) HANGUL SYLLABLE SYEOC
+C16C;C16C;1109 1167 11BF;C16C;1109 1167 11BF; # (셬; 셬; 셬; 셬; 셬; ) HANGUL SYLLABLE SYEOK
+C16D;C16D;1109 1167 11C0;C16D;1109 1167 11C0; # (셭; 셭; 셭; 셭; 셭; ) HANGUL SYLLABLE SYEOT
+C16E;C16E;1109 1167 11C1;C16E;1109 1167 11C1; # (셮; 셮; 셮; 셮; 셮; ) HANGUL SYLLABLE SYEOP
+C16F;C16F;1109 1167 11C2;C16F;1109 1167 11C2; # (셯; 셯; 셯; 셯; 셯; ) HANGUL SYLLABLE SYEOH
+C170;C170;1109 1168;C170;1109 1168; # (셰; 셰; 셰; 셰; 셰; ) HANGUL SYLLABLE SYE
+C171;C171;1109 1168 11A8;C171;1109 1168 11A8; # (셱; 셱; 셱; 셱; 셱; ) HANGUL SYLLABLE SYEG
+C172;C172;1109 1168 11A9;C172;1109 1168 11A9; # (셲; 셲; 셲; 셲; 셲; ) HANGUL SYLLABLE SYEGG
+C173;C173;1109 1168 11AA;C173;1109 1168 11AA; # (셳; 셳; 셳; 셳; 셳; ) HANGUL SYLLABLE SYEGS
+C174;C174;1109 1168 11AB;C174;1109 1168 11AB; # (셴; 셴; 셴; 셴; 셴; ) HANGUL SYLLABLE SYEN
+C175;C175;1109 1168 11AC;C175;1109 1168 11AC; # (셵; 셵; 셵; 셵; 셵; ) HANGUL SYLLABLE SYENJ
+C176;C176;1109 1168 11AD;C176;1109 1168 11AD; # (셶; 셶; 셶; 셶; 셶; ) HANGUL SYLLABLE SYENH
+C177;C177;1109 1168 11AE;C177;1109 1168 11AE; # (셷; 셷; 셷; 셷; 셷; ) HANGUL SYLLABLE SYED
+C178;C178;1109 1168 11AF;C178;1109 1168 11AF; # (셸; 셸; 셸; 셸; 셸; ) HANGUL SYLLABLE SYEL
+C179;C179;1109 1168 11B0;C179;1109 1168 11B0; # (셹; 셹; 셹; 셹; 셹; ) HANGUL SYLLABLE SYELG
+C17A;C17A;1109 1168 11B1;C17A;1109 1168 11B1; # (셺; 셺; 셺; 셺; 셺; ) HANGUL SYLLABLE SYELM
+C17B;C17B;1109 1168 11B2;C17B;1109 1168 11B2; # (셻; 셻; 셻; 셻; 셻; ) HANGUL SYLLABLE SYELB
+C17C;C17C;1109 1168 11B3;C17C;1109 1168 11B3; # (셼; 셼; 셼; 셼; 셼; ) HANGUL SYLLABLE SYELS
+C17D;C17D;1109 1168 11B4;C17D;1109 1168 11B4; # (셽; 셽; 셽; 셽; 셽; ) HANGUL SYLLABLE SYELT
+C17E;C17E;1109 1168 11B5;C17E;1109 1168 11B5; # (셾; 셾; 셾; 셾; 셾; ) HANGUL SYLLABLE SYELP
+C17F;C17F;1109 1168 11B6;C17F;1109 1168 11B6; # (셿; 셿; 셿; 셿; 셿; ) HANGUL SYLLABLE SYELH
+C180;C180;1109 1168 11B7;C180;1109 1168 11B7; # (솀; 솀; 솀; 솀; 솀; ) HANGUL SYLLABLE SYEM
+C181;C181;1109 1168 11B8;C181;1109 1168 11B8; # (솁; 솁; 솁; 솁; 솁; ) HANGUL SYLLABLE SYEB
+C182;C182;1109 1168 11B9;C182;1109 1168 11B9; # (솂; 솂; 솂; 솂; 솂; ) HANGUL SYLLABLE SYEBS
+C183;C183;1109 1168 11BA;C183;1109 1168 11BA; # (솃; 솃; 솃; 솃; 솃; ) HANGUL SYLLABLE SYES
+C184;C184;1109 1168 11BB;C184;1109 1168 11BB; # (솄; 솄; 솄; 솄; 솄; ) HANGUL SYLLABLE SYESS
+C185;C185;1109 1168 11BC;C185;1109 1168 11BC; # (솅; 솅; 솅; 솅; 솅; ) HANGUL SYLLABLE SYENG
+C186;C186;1109 1168 11BD;C186;1109 1168 11BD; # (솆; 솆; 솆; 솆; 솆; ) HANGUL SYLLABLE SYEJ
+C187;C187;1109 1168 11BE;C187;1109 1168 11BE; # (솇; 솇; 솇; 솇; 솇; ) HANGUL SYLLABLE SYEC
+C188;C188;1109 1168 11BF;C188;1109 1168 11BF; # (솈; 솈; 솈; 솈; 솈; ) HANGUL SYLLABLE SYEK
+C189;C189;1109 1168 11C0;C189;1109 1168 11C0; # (솉; 솉; 솉; 솉; 솉; ) HANGUL SYLLABLE SYET
+C18A;C18A;1109 1168 11C1;C18A;1109 1168 11C1; # (솊; 솊; 솊; 솊; 솊; ) HANGUL SYLLABLE SYEP
+C18B;C18B;1109 1168 11C2;C18B;1109 1168 11C2; # (솋; 솋; 솋; 솋; 솋; ) HANGUL SYLLABLE SYEH
+C18C;C18C;1109 1169;C18C;1109 1169; # (소; 소; 소; 소; 소; ) HANGUL SYLLABLE SO
+C18D;C18D;1109 1169 11A8;C18D;1109 1169 11A8; # (속; 속; 속; 속; 속; ) HANGUL SYLLABLE SOG
+C18E;C18E;1109 1169 11A9;C18E;1109 1169 11A9; # (솎; 솎; 솎; 솎; 솎; ) HANGUL SYLLABLE SOGG
+C18F;C18F;1109 1169 11AA;C18F;1109 1169 11AA; # (솏; 솏; 솏; 솏; 솏; ) HANGUL SYLLABLE SOGS
+C190;C190;1109 1169 11AB;C190;1109 1169 11AB; # (손; 손; 손; 손; 손; ) HANGUL SYLLABLE SON
+C191;C191;1109 1169 11AC;C191;1109 1169 11AC; # (솑; 솑; 솑; 솑; 솑; ) HANGUL SYLLABLE SONJ
+C192;C192;1109 1169 11AD;C192;1109 1169 11AD; # (솒; 솒; 솒; 솒; 솒; ) HANGUL SYLLABLE SONH
+C193;C193;1109 1169 11AE;C193;1109 1169 11AE; # (솓; 솓; 솓; 솓; 솓; ) HANGUL SYLLABLE SOD
+C194;C194;1109 1169 11AF;C194;1109 1169 11AF; # (솔; 솔; 솔; 솔; 솔; ) HANGUL SYLLABLE SOL
+C195;C195;1109 1169 11B0;C195;1109 1169 11B0; # (솕; 솕; 솕; 솕; 솕; ) HANGUL SYLLABLE SOLG
+C196;C196;1109 1169 11B1;C196;1109 1169 11B1; # (솖; 솖; 솖; 솖; 솖; ) HANGUL SYLLABLE SOLM
+C197;C197;1109 1169 11B2;C197;1109 1169 11B2; # (솗; 솗; 솗; 솗; 솗; ) HANGUL SYLLABLE SOLB
+C198;C198;1109 1169 11B3;C198;1109 1169 11B3; # (솘; 솘; 솘; 솘; 솘; ) HANGUL SYLLABLE SOLS
+C199;C199;1109 1169 11B4;C199;1109 1169 11B4; # (솙; 솙; 솙; 솙; 솙; ) HANGUL SYLLABLE SOLT
+C19A;C19A;1109 1169 11B5;C19A;1109 1169 11B5; # (솚; 솚; 솚; 솚; 솚; ) HANGUL SYLLABLE SOLP
+C19B;C19B;1109 1169 11B6;C19B;1109 1169 11B6; # (솛; 솛; 솛; 솛; 솛; ) HANGUL SYLLABLE SOLH
+C19C;C19C;1109 1169 11B7;C19C;1109 1169 11B7; # (솜; 솜; 솜; 솜; 솜; ) HANGUL SYLLABLE SOM
+C19D;C19D;1109 1169 11B8;C19D;1109 1169 11B8; # (솝; 솝; 솝; 솝; 솝; ) HANGUL SYLLABLE SOB
+C19E;C19E;1109 1169 11B9;C19E;1109 1169 11B9; # (솞; 솞; 솞; 솞; 솞; ) HANGUL SYLLABLE SOBS
+C19F;C19F;1109 1169 11BA;C19F;1109 1169 11BA; # (솟; 솟; 솟; 솟; 솟; ) HANGUL SYLLABLE SOS
+C1A0;C1A0;1109 1169 11BB;C1A0;1109 1169 11BB; # (솠; 솠; 솠; 솠; 솠; ) HANGUL SYLLABLE SOSS
+C1A1;C1A1;1109 1169 11BC;C1A1;1109 1169 11BC; # (송; 송; 송; 송; 송; ) HANGUL SYLLABLE SONG
+C1A2;C1A2;1109 1169 11BD;C1A2;1109 1169 11BD; # (솢; 솢; 솢; 솢; 솢; ) HANGUL SYLLABLE SOJ
+C1A3;C1A3;1109 1169 11BE;C1A3;1109 1169 11BE; # (솣; 솣; 솣; 솣; 솣; ) HANGUL SYLLABLE SOC
+C1A4;C1A4;1109 1169 11BF;C1A4;1109 1169 11BF; # (솤; 솤; 솤; 솤; 솤; ) HANGUL SYLLABLE SOK
+C1A5;C1A5;1109 1169 11C0;C1A5;1109 1169 11C0; # (솥; 솥; 솥; 솥; 솥; ) HANGUL SYLLABLE SOT
+C1A6;C1A6;1109 1169 11C1;C1A6;1109 1169 11C1; # (솦; 솦; 솦; 솦; 솦; ) HANGUL SYLLABLE SOP
+C1A7;C1A7;1109 1169 11C2;C1A7;1109 1169 11C2; # (솧; 솧; 솧; 솧; 솧; ) HANGUL SYLLABLE SOH
+C1A8;C1A8;1109 116A;C1A8;1109 116A; # (솨; 솨; 솨; 솨; 솨; ) HANGUL SYLLABLE SWA
+C1A9;C1A9;1109 116A 11A8;C1A9;1109 116A 11A8; # (솩; 솩; 솩; 솩; 솩; ) HANGUL SYLLABLE SWAG
+C1AA;C1AA;1109 116A 11A9;C1AA;1109 116A 11A9; # (솪; 솪; 솪; 솪; 솪; ) HANGUL SYLLABLE SWAGG
+C1AB;C1AB;1109 116A 11AA;C1AB;1109 116A 11AA; # (솫; 솫; 솫; 솫; 솫; ) HANGUL SYLLABLE SWAGS
+C1AC;C1AC;1109 116A 11AB;C1AC;1109 116A 11AB; # (솬; 솬; 솬; 솬; 솬; ) HANGUL SYLLABLE SWAN
+C1AD;C1AD;1109 116A 11AC;C1AD;1109 116A 11AC; # (솭; 솭; 솭; 솭; 솭; ) HANGUL SYLLABLE SWANJ
+C1AE;C1AE;1109 116A 11AD;C1AE;1109 116A 11AD; # (솮; 솮; 솮; 솮; 솮; ) HANGUL SYLLABLE SWANH
+C1AF;C1AF;1109 116A 11AE;C1AF;1109 116A 11AE; # (솯; 솯; 솯; 솯; 솯; ) HANGUL SYLLABLE SWAD
+C1B0;C1B0;1109 116A 11AF;C1B0;1109 116A 11AF; # (솰; 솰; 솰; 솰; 솰; ) HANGUL SYLLABLE SWAL
+C1B1;C1B1;1109 116A 11B0;C1B1;1109 116A 11B0; # (솱; 솱; 솱; 솱; 솱; ) HANGUL SYLLABLE SWALG
+C1B2;C1B2;1109 116A 11B1;C1B2;1109 116A 11B1; # (솲; 솲; 솲; 솲; 솲; ) HANGUL SYLLABLE SWALM
+C1B3;C1B3;1109 116A 11B2;C1B3;1109 116A 11B2; # (솳; 솳; 솳; 솳; 솳; ) HANGUL SYLLABLE SWALB
+C1B4;C1B4;1109 116A 11B3;C1B4;1109 116A 11B3; # (솴; 솴; 솴; 솴; 솴; ) HANGUL SYLLABLE SWALS
+C1B5;C1B5;1109 116A 11B4;C1B5;1109 116A 11B4; # (솵; 솵; 솵; 솵; 솵; ) HANGUL SYLLABLE SWALT
+C1B6;C1B6;1109 116A 11B5;C1B6;1109 116A 11B5; # (솶; 솶; 솶; 솶; 솶; ) HANGUL SYLLABLE SWALP
+C1B7;C1B7;1109 116A 11B6;C1B7;1109 116A 11B6; # (솷; 솷; 솷; 솷; 솷; ) HANGUL SYLLABLE SWALH
+C1B8;C1B8;1109 116A 11B7;C1B8;1109 116A 11B7; # (솸; 솸; 솸; 솸; 솸; ) HANGUL SYLLABLE SWAM
+C1B9;C1B9;1109 116A 11B8;C1B9;1109 116A 11B8; # (솹; 솹; 솹; 솹; 솹; ) HANGUL SYLLABLE SWAB
+C1BA;C1BA;1109 116A 11B9;C1BA;1109 116A 11B9; # (솺; 솺; 솺; 솺; 솺; ) HANGUL SYLLABLE SWABS
+C1BB;C1BB;1109 116A 11BA;C1BB;1109 116A 11BA; # (솻; 솻; 솻; 솻; 솻; ) HANGUL SYLLABLE SWAS
+C1BC;C1BC;1109 116A 11BB;C1BC;1109 116A 11BB; # (솼; 솼; 솼; 솼; 솼; ) HANGUL SYLLABLE SWASS
+C1BD;C1BD;1109 116A 11BC;C1BD;1109 116A 11BC; # (솽; 솽; 솽; 솽; 솽; ) HANGUL SYLLABLE SWANG
+C1BE;C1BE;1109 116A 11BD;C1BE;1109 116A 11BD; # (솾; 솾; 솾; 솾; 솾; ) HANGUL SYLLABLE SWAJ
+C1BF;C1BF;1109 116A 11BE;C1BF;1109 116A 11BE; # (솿; 솿; 솿; 솿; 솿; ) HANGUL SYLLABLE SWAC
+C1C0;C1C0;1109 116A 11BF;C1C0;1109 116A 11BF; # (쇀; 쇀; 쇀; 쇀; 쇀; ) HANGUL SYLLABLE SWAK
+C1C1;C1C1;1109 116A 11C0;C1C1;1109 116A 11C0; # (쇁; 쇁; 쇁; 쇁; 쇁; ) HANGUL SYLLABLE SWAT
+C1C2;C1C2;1109 116A 11C1;C1C2;1109 116A 11C1; # (쇂; 쇂; 쇂; 쇂; 쇂; ) HANGUL SYLLABLE SWAP
+C1C3;C1C3;1109 116A 11C2;C1C3;1109 116A 11C2; # (쇃; 쇃; 쇃; 쇃; 쇃; ) HANGUL SYLLABLE SWAH
+C1C4;C1C4;1109 116B;C1C4;1109 116B; # (쇄; 쇄; 쇄; 쇄; 쇄; ) HANGUL SYLLABLE SWAE
+C1C5;C1C5;1109 116B 11A8;C1C5;1109 116B 11A8; # (쇅; 쇅; 쇅; 쇅; 쇅; ) HANGUL SYLLABLE SWAEG
+C1C6;C1C6;1109 116B 11A9;C1C6;1109 116B 11A9; # (쇆; 쇆; 쇆; 쇆; 쇆; ) HANGUL SYLLABLE SWAEGG
+C1C7;C1C7;1109 116B 11AA;C1C7;1109 116B 11AA; # (쇇; 쇇; 쇇; 쇇; 쇇; ) HANGUL SYLLABLE SWAEGS
+C1C8;C1C8;1109 116B 11AB;C1C8;1109 116B 11AB; # (쇈; 쇈; 쇈; 쇈; 쇈; ) HANGUL SYLLABLE SWAEN
+C1C9;C1C9;1109 116B 11AC;C1C9;1109 116B 11AC; # (쇉; 쇉; 쇉; 쇉; 쇉; ) HANGUL SYLLABLE SWAENJ
+C1CA;C1CA;1109 116B 11AD;C1CA;1109 116B 11AD; # (쇊; 쇊; 쇊; 쇊; 쇊; ) HANGUL SYLLABLE SWAENH
+C1CB;C1CB;1109 116B 11AE;C1CB;1109 116B 11AE; # (쇋; 쇋; 쇋; 쇋; 쇋; ) HANGUL SYLLABLE SWAED
+C1CC;C1CC;1109 116B 11AF;C1CC;1109 116B 11AF; # (쇌; 쇌; 쇌; 쇌; 쇌; ) HANGUL SYLLABLE SWAEL
+C1CD;C1CD;1109 116B 11B0;C1CD;1109 116B 11B0; # (쇍; 쇍; 쇍; 쇍; 쇍; ) HANGUL SYLLABLE SWAELG
+C1CE;C1CE;1109 116B 11B1;C1CE;1109 116B 11B1; # (쇎; 쇎; 쇎; 쇎; 쇎; ) HANGUL SYLLABLE SWAELM
+C1CF;C1CF;1109 116B 11B2;C1CF;1109 116B 11B2; # (쇏; 쇏; 쇏; 쇏; 쇏; ) HANGUL SYLLABLE SWAELB
+C1D0;C1D0;1109 116B 11B3;C1D0;1109 116B 11B3; # (쇐; 쇐; 쇐; 쇐; 쇐; ) HANGUL SYLLABLE SWAELS
+C1D1;C1D1;1109 116B 11B4;C1D1;1109 116B 11B4; # (쇑; 쇑; 쇑; 쇑; 쇑; ) HANGUL SYLLABLE SWAELT
+C1D2;C1D2;1109 116B 11B5;C1D2;1109 116B 11B5; # (쇒; 쇒; 쇒; 쇒; 쇒; ) HANGUL SYLLABLE SWAELP
+C1D3;C1D3;1109 116B 11B6;C1D3;1109 116B 11B6; # (쇓; 쇓; 쇓; 쇓; 쇓; ) HANGUL SYLLABLE SWAELH
+C1D4;C1D4;1109 116B 11B7;C1D4;1109 116B 11B7; # (쇔; 쇔; 쇔; 쇔; 쇔; ) HANGUL SYLLABLE SWAEM
+C1D5;C1D5;1109 116B 11B8;C1D5;1109 116B 11B8; # (쇕; 쇕; 쇕; 쇕; 쇕; ) HANGUL SYLLABLE SWAEB
+C1D6;C1D6;1109 116B 11B9;C1D6;1109 116B 11B9; # (쇖; 쇖; 쇖; 쇖; 쇖; ) HANGUL SYLLABLE SWAEBS
+C1D7;C1D7;1109 116B 11BA;C1D7;1109 116B 11BA; # (쇗; 쇗; 쇗; 쇗; 쇗; ) HANGUL SYLLABLE SWAES
+C1D8;C1D8;1109 116B 11BB;C1D8;1109 116B 11BB; # (쇘; 쇘; 쇘; 쇘; 쇘; ) HANGUL SYLLABLE SWAESS
+C1D9;C1D9;1109 116B 11BC;C1D9;1109 116B 11BC; # (쇙; 쇙; 쇙; 쇙; 쇙; ) HANGUL SYLLABLE SWAENG
+C1DA;C1DA;1109 116B 11BD;C1DA;1109 116B 11BD; # (쇚; 쇚; 쇚; 쇚; 쇚; ) HANGUL SYLLABLE SWAEJ
+C1DB;C1DB;1109 116B 11BE;C1DB;1109 116B 11BE; # (쇛; 쇛; 쇛; 쇛; 쇛; ) HANGUL SYLLABLE SWAEC
+C1DC;C1DC;1109 116B 11BF;C1DC;1109 116B 11BF; # (쇜; 쇜; 쇜; 쇜; 쇜; ) HANGUL SYLLABLE SWAEK
+C1DD;C1DD;1109 116B 11C0;C1DD;1109 116B 11C0; # (쇝; 쇝; 쇝; 쇝; 쇝; ) HANGUL SYLLABLE SWAET
+C1DE;C1DE;1109 116B 11C1;C1DE;1109 116B 11C1; # (쇞; 쇞; 쇞; 쇞; 쇞; ) HANGUL SYLLABLE SWAEP
+C1DF;C1DF;1109 116B 11C2;C1DF;1109 116B 11C2; # (쇟; 쇟; 쇟; 쇟; 쇟; ) HANGUL SYLLABLE SWAEH
+C1E0;C1E0;1109 116C;C1E0;1109 116C; # (쇠; 쇠; 쇠; 쇠; 쇠; ) HANGUL SYLLABLE SOE
+C1E1;C1E1;1109 116C 11A8;C1E1;1109 116C 11A8; # (쇡; 쇡; 쇡; 쇡; 쇡; ) HANGUL SYLLABLE SOEG
+C1E2;C1E2;1109 116C 11A9;C1E2;1109 116C 11A9; # (쇢; 쇢; 쇢; 쇢; 쇢; ) HANGUL SYLLABLE SOEGG
+C1E3;C1E3;1109 116C 11AA;C1E3;1109 116C 11AA; # (쇣; 쇣; 쇣; 쇣; 쇣; ) HANGUL SYLLABLE SOEGS
+C1E4;C1E4;1109 116C 11AB;C1E4;1109 116C 11AB; # (쇤; 쇤; 쇤; 쇤; 쇤; ) HANGUL SYLLABLE SOEN
+C1E5;C1E5;1109 116C 11AC;C1E5;1109 116C 11AC; # (쇥; 쇥; 쇥; 쇥; 쇥; ) HANGUL SYLLABLE SOENJ
+C1E6;C1E6;1109 116C 11AD;C1E6;1109 116C 11AD; # (쇦; 쇦; 쇦; 쇦; 쇦; ) HANGUL SYLLABLE SOENH
+C1E7;C1E7;1109 116C 11AE;C1E7;1109 116C 11AE; # (쇧; 쇧; 쇧; 쇧; 쇧; ) HANGUL SYLLABLE SOED
+C1E8;C1E8;1109 116C 11AF;C1E8;1109 116C 11AF; # (쇨; 쇨; 쇨; 쇨; 쇨; ) HANGUL SYLLABLE SOEL
+C1E9;C1E9;1109 116C 11B0;C1E9;1109 116C 11B0; # (쇩; 쇩; 쇩; 쇩; 쇩; ) HANGUL SYLLABLE SOELG
+C1EA;C1EA;1109 116C 11B1;C1EA;1109 116C 11B1; # (쇪; 쇪; 쇪; 쇪; 쇪; ) HANGUL SYLLABLE SOELM
+C1EB;C1EB;1109 116C 11B2;C1EB;1109 116C 11B2; # (쇫; 쇫; 쇫; 쇫; 쇫; ) HANGUL SYLLABLE SOELB
+C1EC;C1EC;1109 116C 11B3;C1EC;1109 116C 11B3; # (쇬; 쇬; 쇬; 쇬; 쇬; ) HANGUL SYLLABLE SOELS
+C1ED;C1ED;1109 116C 11B4;C1ED;1109 116C 11B4; # (쇭; 쇭; 쇭; 쇭; 쇭; ) HANGUL SYLLABLE SOELT
+C1EE;C1EE;1109 116C 11B5;C1EE;1109 116C 11B5; # (쇮; 쇮; 쇮; 쇮; 쇮; ) HANGUL SYLLABLE SOELP
+C1EF;C1EF;1109 116C 11B6;C1EF;1109 116C 11B6; # (쇯; 쇯; 쇯; 쇯; 쇯; ) HANGUL SYLLABLE SOELH
+C1F0;C1F0;1109 116C 11B7;C1F0;1109 116C 11B7; # (쇰; 쇰; 쇰; 쇰; 쇰; ) HANGUL SYLLABLE SOEM
+C1F1;C1F1;1109 116C 11B8;C1F1;1109 116C 11B8; # (쇱; 쇱; 쇱; 쇱; 쇱; ) HANGUL SYLLABLE SOEB
+C1F2;C1F2;1109 116C 11B9;C1F2;1109 116C 11B9; # (쇲; 쇲; 쇲; 쇲; 쇲; ) HANGUL SYLLABLE SOEBS
+C1F3;C1F3;1109 116C 11BA;C1F3;1109 116C 11BA; # (쇳; 쇳; 쇳; 쇳; 쇳; ) HANGUL SYLLABLE SOES
+C1F4;C1F4;1109 116C 11BB;C1F4;1109 116C 11BB; # (쇴; 쇴; 쇴; 쇴; 쇴; ) HANGUL SYLLABLE SOESS
+C1F5;C1F5;1109 116C 11BC;C1F5;1109 116C 11BC; # (쇵; 쇵; 쇵; 쇵; 쇵; ) HANGUL SYLLABLE SOENG
+C1F6;C1F6;1109 116C 11BD;C1F6;1109 116C 11BD; # (쇶; 쇶; 쇶; 쇶; 쇶; ) HANGUL SYLLABLE SOEJ
+C1F7;C1F7;1109 116C 11BE;C1F7;1109 116C 11BE; # (쇷; 쇷; 쇷; 쇷; 쇷; ) HANGUL SYLLABLE SOEC
+C1F8;C1F8;1109 116C 11BF;C1F8;1109 116C 11BF; # (쇸; 쇸; 쇸; 쇸; 쇸; ) HANGUL SYLLABLE SOEK
+C1F9;C1F9;1109 116C 11C0;C1F9;1109 116C 11C0; # (쇹; 쇹; 쇹; 쇹; 쇹; ) HANGUL SYLLABLE SOET
+C1FA;C1FA;1109 116C 11C1;C1FA;1109 116C 11C1; # (쇺; 쇺; 쇺; 쇺; 쇺; ) HANGUL SYLLABLE SOEP
+C1FB;C1FB;1109 116C 11C2;C1FB;1109 116C 11C2; # (쇻; 쇻; 쇻; 쇻; 쇻; ) HANGUL SYLLABLE SOEH
+C1FC;C1FC;1109 116D;C1FC;1109 116D; # (쇼; 쇼; 쇼; 쇼; 쇼; ) HANGUL SYLLABLE SYO
+C1FD;C1FD;1109 116D 11A8;C1FD;1109 116D 11A8; # (쇽; 쇽; 쇽; 쇽; 쇽; ) HANGUL SYLLABLE SYOG
+C1FE;C1FE;1109 116D 11A9;C1FE;1109 116D 11A9; # (쇾; 쇾; 쇾; 쇾; 쇾; ) HANGUL SYLLABLE SYOGG
+C1FF;C1FF;1109 116D 11AA;C1FF;1109 116D 11AA; # (쇿; 쇿; 쇿; 쇿; 쇿; ) HANGUL SYLLABLE SYOGS
+C200;C200;1109 116D 11AB;C200;1109 116D 11AB; # (숀; 숀; 숀; 숀; 숀; ) HANGUL SYLLABLE SYON
+C201;C201;1109 116D 11AC;C201;1109 116D 11AC; # (숁; 숁; 숁; 숁; 숁; ) HANGUL SYLLABLE SYONJ
+C202;C202;1109 116D 11AD;C202;1109 116D 11AD; # (숂; 숂; 숂; 숂; 숂; ) HANGUL SYLLABLE SYONH
+C203;C203;1109 116D 11AE;C203;1109 116D 11AE; # (숃; 숃; 숃; 숃; 숃; ) HANGUL SYLLABLE SYOD
+C204;C204;1109 116D 11AF;C204;1109 116D 11AF; # (숄; 숄; 숄; 숄; 숄; ) HANGUL SYLLABLE SYOL
+C205;C205;1109 116D 11B0;C205;1109 116D 11B0; # (숅; 숅; 숅; 숅; 숅; ) HANGUL SYLLABLE SYOLG
+C206;C206;1109 116D 11B1;C206;1109 116D 11B1; # (숆; 숆; 숆; 숆; 숆; ) HANGUL SYLLABLE SYOLM
+C207;C207;1109 116D 11B2;C207;1109 116D 11B2; # (숇; 숇; 숇; 숇; 숇; ) HANGUL SYLLABLE SYOLB
+C208;C208;1109 116D 11B3;C208;1109 116D 11B3; # (숈; 숈; 숈; 숈; 숈; ) HANGUL SYLLABLE SYOLS
+C209;C209;1109 116D 11B4;C209;1109 116D 11B4; # (숉; 숉; 숉; 숉; 숉; ) HANGUL SYLLABLE SYOLT
+C20A;C20A;1109 116D 11B5;C20A;1109 116D 11B5; # (숊; 숊; 숊; 숊; 숊; ) HANGUL SYLLABLE SYOLP
+C20B;C20B;1109 116D 11B6;C20B;1109 116D 11B6; # (숋; 숋; 숋; 숋; 숋; ) HANGUL SYLLABLE SYOLH
+C20C;C20C;1109 116D 11B7;C20C;1109 116D 11B7; # (숌; 숌; 숌; 숌; 숌; ) HANGUL SYLLABLE SYOM
+C20D;C20D;1109 116D 11B8;C20D;1109 116D 11B8; # (숍; 숍; 숍; 숍; 숍; ) HANGUL SYLLABLE SYOB
+C20E;C20E;1109 116D 11B9;C20E;1109 116D 11B9; # (숎; 숎; 숎; 숎; 숎; ) HANGUL SYLLABLE SYOBS
+C20F;C20F;1109 116D 11BA;C20F;1109 116D 11BA; # (숏; 숏; 숏; 숏; 숏; ) HANGUL SYLLABLE SYOS
+C210;C210;1109 116D 11BB;C210;1109 116D 11BB; # (숐; 숐; 숐; 숐; 숐; ) HANGUL SYLLABLE SYOSS
+C211;C211;1109 116D 11BC;C211;1109 116D 11BC; # (숑; 숑; 숑; 숑; 숑; ) HANGUL SYLLABLE SYONG
+C212;C212;1109 116D 11BD;C212;1109 116D 11BD; # (숒; 숒; 숒; 숒; 숒; ) HANGUL SYLLABLE SYOJ
+C213;C213;1109 116D 11BE;C213;1109 116D 11BE; # (숓; 숓; 숓; 숓; 숓; ) HANGUL SYLLABLE SYOC
+C214;C214;1109 116D 11BF;C214;1109 116D 11BF; # (숔; 숔; 숔; 숔; 숔; ) HANGUL SYLLABLE SYOK
+C215;C215;1109 116D 11C0;C215;1109 116D 11C0; # (숕; 숕; 숕; 숕; 숕; ) HANGUL SYLLABLE SYOT
+C216;C216;1109 116D 11C1;C216;1109 116D 11C1; # (숖; 숖; 숖; 숖; 숖; ) HANGUL SYLLABLE SYOP
+C217;C217;1109 116D 11C2;C217;1109 116D 11C2; # (숗; 숗; 숗; 숗; 숗; ) HANGUL SYLLABLE SYOH
+C218;C218;1109 116E;C218;1109 116E; # (수; 수; 수; 수; 수; ) HANGUL SYLLABLE SU
+C219;C219;1109 116E 11A8;C219;1109 116E 11A8; # (숙; 숙; 숙; 숙; 숙; ) HANGUL SYLLABLE SUG
+C21A;C21A;1109 116E 11A9;C21A;1109 116E 11A9; # (숚; 숚; 숚; 숚; 숚; ) HANGUL SYLLABLE SUGG
+C21B;C21B;1109 116E 11AA;C21B;1109 116E 11AA; # (숛; 숛; 숛; 숛; 숛; ) HANGUL SYLLABLE SUGS
+C21C;C21C;1109 116E 11AB;C21C;1109 116E 11AB; # (순; 순; 순; 순; 순; ) HANGUL SYLLABLE SUN
+C21D;C21D;1109 116E 11AC;C21D;1109 116E 11AC; # (숝; 숝; 숝; 숝; 숝; ) HANGUL SYLLABLE SUNJ
+C21E;C21E;1109 116E 11AD;C21E;1109 116E 11AD; # (숞; 숞; 숞; 숞; 숞; ) HANGUL SYLLABLE SUNH
+C21F;C21F;1109 116E 11AE;C21F;1109 116E 11AE; # (숟; 숟; 숟; 숟; 숟; ) HANGUL SYLLABLE SUD
+C220;C220;1109 116E 11AF;C220;1109 116E 11AF; # (술; 술; 술; 술; 술; ) HANGUL SYLLABLE SUL
+C221;C221;1109 116E 11B0;C221;1109 116E 11B0; # (숡; 숡; 숡; 숡; 숡; ) HANGUL SYLLABLE SULG
+C222;C222;1109 116E 11B1;C222;1109 116E 11B1; # (숢; 숢; 숢; 숢; 숢; ) HANGUL SYLLABLE SULM
+C223;C223;1109 116E 11B2;C223;1109 116E 11B2; # (숣; 숣; 숣; 숣; 숣; ) HANGUL SYLLABLE SULB
+C224;C224;1109 116E 11B3;C224;1109 116E 11B3; # (숤; 숤; 숤; 숤; 숤; ) HANGUL SYLLABLE SULS
+C225;C225;1109 116E 11B4;C225;1109 116E 11B4; # (숥; 숥; 숥; 숥; 숥; ) HANGUL SYLLABLE SULT
+C226;C226;1109 116E 11B5;C226;1109 116E 11B5; # (숦; 숦; 숦; 숦; 숦; ) HANGUL SYLLABLE SULP
+C227;C227;1109 116E 11B6;C227;1109 116E 11B6; # (숧; 숧; 숧; 숧; 숧; ) HANGUL SYLLABLE SULH
+C228;C228;1109 116E 11B7;C228;1109 116E 11B7; # (숨; 숨; 숨; 숨; 숨; ) HANGUL SYLLABLE SUM
+C229;C229;1109 116E 11B8;C229;1109 116E 11B8; # (숩; 숩; 숩; 숩; 숩; ) HANGUL SYLLABLE SUB
+C22A;C22A;1109 116E 11B9;C22A;1109 116E 11B9; # (숪; 숪; 숪; 숪; 숪; ) HANGUL SYLLABLE SUBS
+C22B;C22B;1109 116E 11BA;C22B;1109 116E 11BA; # (숫; 숫; 숫; 숫; 숫; ) HANGUL SYLLABLE SUS
+C22C;C22C;1109 116E 11BB;C22C;1109 116E 11BB; # (숬; 숬; 숬; 숬; 숬; ) HANGUL SYLLABLE SUSS
+C22D;C22D;1109 116E 11BC;C22D;1109 116E 11BC; # (숭; 숭; 숭; 숭; 숭; ) HANGUL SYLLABLE SUNG
+C22E;C22E;1109 116E 11BD;C22E;1109 116E 11BD; # (숮; 숮; 숮; 숮; 숮; ) HANGUL SYLLABLE SUJ
+C22F;C22F;1109 116E 11BE;C22F;1109 116E 11BE; # (숯; 숯; 숯; 숯; 숯; ) HANGUL SYLLABLE SUC
+C230;C230;1109 116E 11BF;C230;1109 116E 11BF; # (숰; 숰; 숰; 숰; 숰; ) HANGUL SYLLABLE SUK
+C231;C231;1109 116E 11C0;C231;1109 116E 11C0; # (숱; 숱; 숱; 숱; 숱; ) HANGUL SYLLABLE SUT
+C232;C232;1109 116E 11C1;C232;1109 116E 11C1; # (숲; 숲; 숲; 숲; 숲; ) HANGUL SYLLABLE SUP
+C233;C233;1109 116E 11C2;C233;1109 116E 11C2; # (숳; 숳; 숳; 숳; 숳; ) HANGUL SYLLABLE SUH
+C234;C234;1109 116F;C234;1109 116F; # (숴; 숴; 숴; 숴; 숴; ) HANGUL SYLLABLE SWEO
+C235;C235;1109 116F 11A8;C235;1109 116F 11A8; # (숵; 숵; 숵; 숵; 숵; ) HANGUL SYLLABLE SWEOG
+C236;C236;1109 116F 11A9;C236;1109 116F 11A9; # (숶; 숶; 숶; 숶; 숶; ) HANGUL SYLLABLE SWEOGG
+C237;C237;1109 116F 11AA;C237;1109 116F 11AA; # (숷; 숷; 숷; 숷; 숷; ) HANGUL SYLLABLE SWEOGS
+C238;C238;1109 116F 11AB;C238;1109 116F 11AB; # (숸; 숸; 숸; 숸; 숸; ) HANGUL SYLLABLE SWEON
+C239;C239;1109 116F 11AC;C239;1109 116F 11AC; # (숹; 숹; 숹; 숹; 숹; ) HANGUL SYLLABLE SWEONJ
+C23A;C23A;1109 116F 11AD;C23A;1109 116F 11AD; # (숺; 숺; 숺; 숺; 숺; ) HANGUL SYLLABLE SWEONH
+C23B;C23B;1109 116F 11AE;C23B;1109 116F 11AE; # (숻; 숻; 숻; 숻; 숻; ) HANGUL SYLLABLE SWEOD
+C23C;C23C;1109 116F 11AF;C23C;1109 116F 11AF; # (숼; 숼; 숼; 숼; 숼; ) HANGUL SYLLABLE SWEOL
+C23D;C23D;1109 116F 11B0;C23D;1109 116F 11B0; # (숽; 숽; 숽; 숽; 숽; ) HANGUL SYLLABLE SWEOLG
+C23E;C23E;1109 116F 11B1;C23E;1109 116F 11B1; # (숾; 숾; 숾; 숾; 숾; ) HANGUL SYLLABLE SWEOLM
+C23F;C23F;1109 116F 11B2;C23F;1109 116F 11B2; # (숿; 숿; 숿; 숿; 숿; ) HANGUL SYLLABLE SWEOLB
+C240;C240;1109 116F 11B3;C240;1109 116F 11B3; # (쉀; 쉀; 쉀; 쉀; 쉀; ) HANGUL SYLLABLE SWEOLS
+C241;C241;1109 116F 11B4;C241;1109 116F 11B4; # (쉁; 쉁; 쉁; 쉁; 쉁; ) HANGUL SYLLABLE SWEOLT
+C242;C242;1109 116F 11B5;C242;1109 116F 11B5; # (쉂; 쉂; 쉂; 쉂; 쉂; ) HANGUL SYLLABLE SWEOLP
+C243;C243;1109 116F 11B6;C243;1109 116F 11B6; # (쉃; 쉃; 쉃; 쉃; 쉃; ) HANGUL SYLLABLE SWEOLH
+C244;C244;1109 116F 11B7;C244;1109 116F 11B7; # (쉄; 쉄; 쉄; 쉄; 쉄; ) HANGUL SYLLABLE SWEOM
+C245;C245;1109 116F 11B8;C245;1109 116F 11B8; # (쉅; 쉅; 쉅; 쉅; 쉅; ) HANGUL SYLLABLE SWEOB
+C246;C246;1109 116F 11B9;C246;1109 116F 11B9; # (쉆; 쉆; 쉆; 쉆; 쉆; ) HANGUL SYLLABLE SWEOBS
+C247;C247;1109 116F 11BA;C247;1109 116F 11BA; # (쉇; 쉇; 쉇; 쉇; 쉇; ) HANGUL SYLLABLE SWEOS
+C248;C248;1109 116F 11BB;C248;1109 116F 11BB; # (쉈; 쉈; 쉈; 쉈; 쉈; ) HANGUL SYLLABLE SWEOSS
+C249;C249;1109 116F 11BC;C249;1109 116F 11BC; # (쉉; 쉉; 쉉; 쉉; 쉉; ) HANGUL SYLLABLE SWEONG
+C24A;C24A;1109 116F 11BD;C24A;1109 116F 11BD; # (쉊; 쉊; 쉊; 쉊; 쉊; ) HANGUL SYLLABLE SWEOJ
+C24B;C24B;1109 116F 11BE;C24B;1109 116F 11BE; # (쉋; 쉋; 쉋; 쉋; 쉋; ) HANGUL SYLLABLE SWEOC
+C24C;C24C;1109 116F 11BF;C24C;1109 116F 11BF; # (쉌; 쉌; 쉌; 쉌; 쉌; ) HANGUL SYLLABLE SWEOK
+C24D;C24D;1109 116F 11C0;C24D;1109 116F 11C0; # (쉍; 쉍; 쉍; 쉍; 쉍; ) HANGUL SYLLABLE SWEOT
+C24E;C24E;1109 116F 11C1;C24E;1109 116F 11C1; # (쉎; 쉎; 쉎; 쉎; 쉎; ) HANGUL SYLLABLE SWEOP
+C24F;C24F;1109 116F 11C2;C24F;1109 116F 11C2; # (쉏; 쉏; 쉏; 쉏; 쉏; ) HANGUL SYLLABLE SWEOH
+C250;C250;1109 1170;C250;1109 1170; # (쉐; 쉐; 쉐; 쉐; 쉐; ) HANGUL SYLLABLE SWE
+C251;C251;1109 1170 11A8;C251;1109 1170 11A8; # (쉑; 쉑; 쉑; 쉑; 쉑; ) HANGUL SYLLABLE SWEG
+C252;C252;1109 1170 11A9;C252;1109 1170 11A9; # (쉒; 쉒; 쉒; 쉒; 쉒; ) HANGUL SYLLABLE SWEGG
+C253;C253;1109 1170 11AA;C253;1109 1170 11AA; # (쉓; 쉓; 쉓; 쉓; 쉓; ) HANGUL SYLLABLE SWEGS
+C254;C254;1109 1170 11AB;C254;1109 1170 11AB; # (쉔; 쉔; 쉔; 쉔; 쉔; ) HANGUL SYLLABLE SWEN
+C255;C255;1109 1170 11AC;C255;1109 1170 11AC; # (쉕; 쉕; 쉕; 쉕; 쉕; ) HANGUL SYLLABLE SWENJ
+C256;C256;1109 1170 11AD;C256;1109 1170 11AD; # (쉖; 쉖; 쉖; 쉖; 쉖; ) HANGUL SYLLABLE SWENH
+C257;C257;1109 1170 11AE;C257;1109 1170 11AE; # (쉗; 쉗; 쉗; 쉗; 쉗; ) HANGUL SYLLABLE SWED
+C258;C258;1109 1170 11AF;C258;1109 1170 11AF; # (쉘; 쉘; 쉘; 쉘; 쉘; ) HANGUL SYLLABLE SWEL
+C259;C259;1109 1170 11B0;C259;1109 1170 11B0; # (쉙; 쉙; 쉙; 쉙; 쉙; ) HANGUL SYLLABLE SWELG
+C25A;C25A;1109 1170 11B1;C25A;1109 1170 11B1; # (쉚; 쉚; 쉚; 쉚; 쉚; ) HANGUL SYLLABLE SWELM
+C25B;C25B;1109 1170 11B2;C25B;1109 1170 11B2; # (쉛; 쉛; 쉛; 쉛; 쉛; ) HANGUL SYLLABLE SWELB
+C25C;C25C;1109 1170 11B3;C25C;1109 1170 11B3; # (쉜; 쉜; 쉜; 쉜; 쉜; ) HANGUL SYLLABLE SWELS
+C25D;C25D;1109 1170 11B4;C25D;1109 1170 11B4; # (쉝; 쉝; 쉝; 쉝; 쉝; ) HANGUL SYLLABLE SWELT
+C25E;C25E;1109 1170 11B5;C25E;1109 1170 11B5; # (쉞; 쉞; 쉞; 쉞; 쉞; ) HANGUL SYLLABLE SWELP
+C25F;C25F;1109 1170 11B6;C25F;1109 1170 11B6; # (쉟; 쉟; 쉟; 쉟; 쉟; ) HANGUL SYLLABLE SWELH
+C260;C260;1109 1170 11B7;C260;1109 1170 11B7; # (쉠; 쉠; 쉠; 쉠; 쉠; ) HANGUL SYLLABLE SWEM
+C261;C261;1109 1170 11B8;C261;1109 1170 11B8; # (쉡; 쉡; 쉡; 쉡; 쉡; ) HANGUL SYLLABLE SWEB
+C262;C262;1109 1170 11B9;C262;1109 1170 11B9; # (쉢; 쉢; 쉢; 쉢; 쉢; ) HANGUL SYLLABLE SWEBS
+C263;C263;1109 1170 11BA;C263;1109 1170 11BA; # (쉣; 쉣; 쉣; 쉣; 쉣; ) HANGUL SYLLABLE SWES
+C264;C264;1109 1170 11BB;C264;1109 1170 11BB; # (쉤; 쉤; 쉤; 쉤; 쉤; ) HANGUL SYLLABLE SWESS
+C265;C265;1109 1170 11BC;C265;1109 1170 11BC; # (쉥; 쉥; 쉥; 쉥; 쉥; ) HANGUL SYLLABLE SWENG
+C266;C266;1109 1170 11BD;C266;1109 1170 11BD; # (쉦; 쉦; 쉦; 쉦; 쉦; ) HANGUL SYLLABLE SWEJ
+C267;C267;1109 1170 11BE;C267;1109 1170 11BE; # (쉧; 쉧; 쉧; 쉧; 쉧; ) HANGUL SYLLABLE SWEC
+C268;C268;1109 1170 11BF;C268;1109 1170 11BF; # (쉨; 쉨; 쉨; 쉨; 쉨; ) HANGUL SYLLABLE SWEK
+C269;C269;1109 1170 11C0;C269;1109 1170 11C0; # (쉩; 쉩; 쉩; 쉩; 쉩; ) HANGUL SYLLABLE SWET
+C26A;C26A;1109 1170 11C1;C26A;1109 1170 11C1; # (쉪; 쉪; 쉪; 쉪; 쉪; ) HANGUL SYLLABLE SWEP
+C26B;C26B;1109 1170 11C2;C26B;1109 1170 11C2; # (쉫; 쉫; 쉫; 쉫; 쉫; ) HANGUL SYLLABLE SWEH
+C26C;C26C;1109 1171;C26C;1109 1171; # (쉬; 쉬; 쉬; 쉬; 쉬; ) HANGUL SYLLABLE SWI
+C26D;C26D;1109 1171 11A8;C26D;1109 1171 11A8; # (쉭; 쉭; 쉭; 쉭; 쉭; ) HANGUL SYLLABLE SWIG
+C26E;C26E;1109 1171 11A9;C26E;1109 1171 11A9; # (쉮; 쉮; 쉮; 쉮; 쉮; ) HANGUL SYLLABLE SWIGG
+C26F;C26F;1109 1171 11AA;C26F;1109 1171 11AA; # (쉯; 쉯; 쉯; 쉯; 쉯; ) HANGUL SYLLABLE SWIGS
+C270;C270;1109 1171 11AB;C270;1109 1171 11AB; # (쉰; 쉰; 쉰; 쉰; 쉰; ) HANGUL SYLLABLE SWIN
+C271;C271;1109 1171 11AC;C271;1109 1171 11AC; # (쉱; 쉱; 쉱; 쉱; 쉱; ) HANGUL SYLLABLE SWINJ
+C272;C272;1109 1171 11AD;C272;1109 1171 11AD; # (쉲; 쉲; 쉲; 쉲; 쉲; ) HANGUL SYLLABLE SWINH
+C273;C273;1109 1171 11AE;C273;1109 1171 11AE; # (쉳; 쉳; 쉳; 쉳; 쉳; ) HANGUL SYLLABLE SWID
+C274;C274;1109 1171 11AF;C274;1109 1171 11AF; # (쉴; 쉴; 쉴; 쉴; 쉴; ) HANGUL SYLLABLE SWIL
+C275;C275;1109 1171 11B0;C275;1109 1171 11B0; # (쉵; 쉵; 쉵; 쉵; 쉵; ) HANGUL SYLLABLE SWILG
+C276;C276;1109 1171 11B1;C276;1109 1171 11B1; # (쉶; 쉶; 쉶; 쉶; 쉶; ) HANGUL SYLLABLE SWILM
+C277;C277;1109 1171 11B2;C277;1109 1171 11B2; # (쉷; 쉷; 쉷; 쉷; 쉷; ) HANGUL SYLLABLE SWILB
+C278;C278;1109 1171 11B3;C278;1109 1171 11B3; # (쉸; 쉸; 쉸; 쉸; 쉸; ) HANGUL SYLLABLE SWILS
+C279;C279;1109 1171 11B4;C279;1109 1171 11B4; # (쉹; 쉹; 쉹; 쉹; 쉹; ) HANGUL SYLLABLE SWILT
+C27A;C27A;1109 1171 11B5;C27A;1109 1171 11B5; # (쉺; 쉺; 쉺; 쉺; 쉺; ) HANGUL SYLLABLE SWILP
+C27B;C27B;1109 1171 11B6;C27B;1109 1171 11B6; # (쉻; 쉻; 쉻; 쉻; 쉻; ) HANGUL SYLLABLE SWILH
+C27C;C27C;1109 1171 11B7;C27C;1109 1171 11B7; # (쉼; 쉼; 쉼; 쉼; 쉼; ) HANGUL SYLLABLE SWIM
+C27D;C27D;1109 1171 11B8;C27D;1109 1171 11B8; # (쉽; 쉽; 쉽; 쉽; 쉽; ) HANGUL SYLLABLE SWIB
+C27E;C27E;1109 1171 11B9;C27E;1109 1171 11B9; # (쉾; 쉾; 쉾; 쉾; 쉾; ) HANGUL SYLLABLE SWIBS
+C27F;C27F;1109 1171 11BA;C27F;1109 1171 11BA; # (쉿; 쉿; 쉿; 쉿; 쉿; ) HANGUL SYLLABLE SWIS
+C280;C280;1109 1171 11BB;C280;1109 1171 11BB; # (슀; 슀; 슀; 슀; 슀; ) HANGUL SYLLABLE SWISS
+C281;C281;1109 1171 11BC;C281;1109 1171 11BC; # (슁; 슁; 슁; 슁; 슁; ) HANGUL SYLLABLE SWING
+C282;C282;1109 1171 11BD;C282;1109 1171 11BD; # (슂; 슂; 슂; 슂; 슂; ) HANGUL SYLLABLE SWIJ
+C283;C283;1109 1171 11BE;C283;1109 1171 11BE; # (슃; 슃; 슃; 슃; 슃; ) HANGUL SYLLABLE SWIC
+C284;C284;1109 1171 11BF;C284;1109 1171 11BF; # (슄; 슄; 슄; 슄; 슄; ) HANGUL SYLLABLE SWIK
+C285;C285;1109 1171 11C0;C285;1109 1171 11C0; # (슅; 슅; 슅; 슅; 슅; ) HANGUL SYLLABLE SWIT
+C286;C286;1109 1171 11C1;C286;1109 1171 11C1; # (슆; 슆; 슆; 슆; 슆; ) HANGUL SYLLABLE SWIP
+C287;C287;1109 1171 11C2;C287;1109 1171 11C2; # (슇; 슇; 슇; 슇; 슇; ) HANGUL SYLLABLE SWIH
+C288;C288;1109 1172;C288;1109 1172; # (슈; 슈; 슈; 슈; 슈; ) HANGUL SYLLABLE SYU
+C289;C289;1109 1172 11A8;C289;1109 1172 11A8; # (슉; 슉; 슉; 슉; 슉; ) HANGUL SYLLABLE SYUG
+C28A;C28A;1109 1172 11A9;C28A;1109 1172 11A9; # (슊; 슊; 슊; 슊; 슊; ) HANGUL SYLLABLE SYUGG
+C28B;C28B;1109 1172 11AA;C28B;1109 1172 11AA; # (슋; 슋; 슋; 슋; 슋; ) HANGUL SYLLABLE SYUGS
+C28C;C28C;1109 1172 11AB;C28C;1109 1172 11AB; # (슌; 슌; 슌; 슌; 슌; ) HANGUL SYLLABLE SYUN
+C28D;C28D;1109 1172 11AC;C28D;1109 1172 11AC; # (슍; 슍; 슍; 슍; 슍; ) HANGUL SYLLABLE SYUNJ
+C28E;C28E;1109 1172 11AD;C28E;1109 1172 11AD; # (슎; 슎; 슎; 슎; 슎; ) HANGUL SYLLABLE SYUNH
+C28F;C28F;1109 1172 11AE;C28F;1109 1172 11AE; # (슏; 슏; 슏; 슏; 슏; ) HANGUL SYLLABLE SYUD
+C290;C290;1109 1172 11AF;C290;1109 1172 11AF; # (슐; 슐; 슐; 슐; 슐; ) HANGUL SYLLABLE SYUL
+C291;C291;1109 1172 11B0;C291;1109 1172 11B0; # (슑; 슑; 슑; 슑; 슑; ) HANGUL SYLLABLE SYULG
+C292;C292;1109 1172 11B1;C292;1109 1172 11B1; # (슒; 슒; 슒; 슒; 슒; ) HANGUL SYLLABLE SYULM
+C293;C293;1109 1172 11B2;C293;1109 1172 11B2; # (슓; 슓; 슓; 슓; 슓; ) HANGUL SYLLABLE SYULB
+C294;C294;1109 1172 11B3;C294;1109 1172 11B3; # (슔; 슔; 슔; 슔; 슔; ) HANGUL SYLLABLE SYULS
+C295;C295;1109 1172 11B4;C295;1109 1172 11B4; # (슕; 슕; 슕; 슕; 슕; ) HANGUL SYLLABLE SYULT
+C296;C296;1109 1172 11B5;C296;1109 1172 11B5; # (슖; 슖; 슖; 슖; 슖; ) HANGUL SYLLABLE SYULP
+C297;C297;1109 1172 11B6;C297;1109 1172 11B6; # (슗; 슗; 슗; 슗; 슗; ) HANGUL SYLLABLE SYULH
+C298;C298;1109 1172 11B7;C298;1109 1172 11B7; # (슘; 슘; 슘; 슘; 슘; ) HANGUL SYLLABLE SYUM
+C299;C299;1109 1172 11B8;C299;1109 1172 11B8; # (슙; 슙; 슙; 슙; 슙; ) HANGUL SYLLABLE SYUB
+C29A;C29A;1109 1172 11B9;C29A;1109 1172 11B9; # (슚; 슚; 슚; 슚; 슚; ) HANGUL SYLLABLE SYUBS
+C29B;C29B;1109 1172 11BA;C29B;1109 1172 11BA; # (슛; 슛; 슛; 슛; 슛; ) HANGUL SYLLABLE SYUS
+C29C;C29C;1109 1172 11BB;C29C;1109 1172 11BB; # (슜; 슜; 슜; 슜; 슜; ) HANGUL SYLLABLE SYUSS
+C29D;C29D;1109 1172 11BC;C29D;1109 1172 11BC; # (슝; 슝; 슝; 슝; 슝; ) HANGUL SYLLABLE SYUNG
+C29E;C29E;1109 1172 11BD;C29E;1109 1172 11BD; # (슞; 슞; 슞; 슞; 슞; ) HANGUL SYLLABLE SYUJ
+C29F;C29F;1109 1172 11BE;C29F;1109 1172 11BE; # (슟; 슟; 슟; 슟; 슟; ) HANGUL SYLLABLE SYUC
+C2A0;C2A0;1109 1172 11BF;C2A0;1109 1172 11BF; # (슠; 슠; 슠; 슠; 슠; ) HANGUL SYLLABLE SYUK
+C2A1;C2A1;1109 1172 11C0;C2A1;1109 1172 11C0; # (슡; 슡; 슡; 슡; 슡; ) HANGUL SYLLABLE SYUT
+C2A2;C2A2;1109 1172 11C1;C2A2;1109 1172 11C1; # (슢; 슢; 슢; 슢; 슢; ) HANGUL SYLLABLE SYUP
+C2A3;C2A3;1109 1172 11C2;C2A3;1109 1172 11C2; # (슣; 슣; 슣; 슣; 슣; ) HANGUL SYLLABLE SYUH
+C2A4;C2A4;1109 1173;C2A4;1109 1173; # (스; 스; 스; 스; 스; ) HANGUL SYLLABLE SEU
+C2A5;C2A5;1109 1173 11A8;C2A5;1109 1173 11A8; # (슥; 슥; 슥; 슥; 슥; ) HANGUL SYLLABLE SEUG
+C2A6;C2A6;1109 1173 11A9;C2A6;1109 1173 11A9; # (슦; 슦; 슦; 슦; 슦; ) HANGUL SYLLABLE SEUGG
+C2A7;C2A7;1109 1173 11AA;C2A7;1109 1173 11AA; # (슧; 슧; 슧; 슧; 슧; ) HANGUL SYLLABLE SEUGS
+C2A8;C2A8;1109 1173 11AB;C2A8;1109 1173 11AB; # (슨; 슨; 슨; 슨; 슨; ) HANGUL SYLLABLE SEUN
+C2A9;C2A9;1109 1173 11AC;C2A9;1109 1173 11AC; # (슩; 슩; 슩; 슩; 슩; ) HANGUL SYLLABLE SEUNJ
+C2AA;C2AA;1109 1173 11AD;C2AA;1109 1173 11AD; # (슪; 슪; 슪; 슪; 슪; ) HANGUL SYLLABLE SEUNH
+C2AB;C2AB;1109 1173 11AE;C2AB;1109 1173 11AE; # (슫; 슫; 슫; 슫; 슫; ) HANGUL SYLLABLE SEUD
+C2AC;C2AC;1109 1173 11AF;C2AC;1109 1173 11AF; # (슬; 슬; 슬; 슬; 슬; ) HANGUL SYLLABLE SEUL
+C2AD;C2AD;1109 1173 11B0;C2AD;1109 1173 11B0; # (슭; 슭; 슭; 슭; 슭; ) HANGUL SYLLABLE SEULG
+C2AE;C2AE;1109 1173 11B1;C2AE;1109 1173 11B1; # (슮; 슮; 슮; 슮; 슮; ) HANGUL SYLLABLE SEULM
+C2AF;C2AF;1109 1173 11B2;C2AF;1109 1173 11B2; # (슯; 슯; 슯; 슯; 슯; ) HANGUL SYLLABLE SEULB
+C2B0;C2B0;1109 1173 11B3;C2B0;1109 1173 11B3; # (슰; 슰; 슰; 슰; 슰; ) HANGUL SYLLABLE SEULS
+C2B1;C2B1;1109 1173 11B4;C2B1;1109 1173 11B4; # (슱; 슱; 슱; 슱; 슱; ) HANGUL SYLLABLE SEULT
+C2B2;C2B2;1109 1173 11B5;C2B2;1109 1173 11B5; # (슲; 슲; 슲; 슲; 슲; ) HANGUL SYLLABLE SEULP
+C2B3;C2B3;1109 1173 11B6;C2B3;1109 1173 11B6; # (슳; 슳; 슳; 슳; 슳; ) HANGUL SYLLABLE SEULH
+C2B4;C2B4;1109 1173 11B7;C2B4;1109 1173 11B7; # (슴; 슴; 슴; 슴; 슴; ) HANGUL SYLLABLE SEUM
+C2B5;C2B5;1109 1173 11B8;C2B5;1109 1173 11B8; # (습; 습; 습; 습; 습; ) HANGUL SYLLABLE SEUB
+C2B6;C2B6;1109 1173 11B9;C2B6;1109 1173 11B9; # (슶; 슶; 슶; 슶; 슶; ) HANGUL SYLLABLE SEUBS
+C2B7;C2B7;1109 1173 11BA;C2B7;1109 1173 11BA; # (슷; 슷; 슷; 슷; 슷; ) HANGUL SYLLABLE SEUS
+C2B8;C2B8;1109 1173 11BB;C2B8;1109 1173 11BB; # (슸; 슸; 슸; 슸; 슸; ) HANGUL SYLLABLE SEUSS
+C2B9;C2B9;1109 1173 11BC;C2B9;1109 1173 11BC; # (승; 승; 승; 승; 승; ) HANGUL SYLLABLE SEUNG
+C2BA;C2BA;1109 1173 11BD;C2BA;1109 1173 11BD; # (슺; 슺; 슺; 슺; 슺; ) HANGUL SYLLABLE SEUJ
+C2BB;C2BB;1109 1173 11BE;C2BB;1109 1173 11BE; # (슻; 슻; 슻; 슻; 슻; ) HANGUL SYLLABLE SEUC
+C2BC;C2BC;1109 1173 11BF;C2BC;1109 1173 11BF; # (슼; 슼; 슼; 슼; 슼; ) HANGUL SYLLABLE SEUK
+C2BD;C2BD;1109 1173 11C0;C2BD;1109 1173 11C0; # (슽; 슽; 슽; 슽; 슽; ) HANGUL SYLLABLE SEUT
+C2BE;C2BE;1109 1173 11C1;C2BE;1109 1173 11C1; # (슾; 슾; 슾; 슾; 슾; ) HANGUL SYLLABLE SEUP
+C2BF;C2BF;1109 1173 11C2;C2BF;1109 1173 11C2; # (슿; 슿; 슿; 슿; 슿; ) HANGUL SYLLABLE SEUH
+C2C0;C2C0;1109 1174;C2C0;1109 1174; # (싀; 싀; 싀; 싀; 싀; ) HANGUL SYLLABLE SYI
+C2C1;C2C1;1109 1174 11A8;C2C1;1109 1174 11A8; # (싁; 싁; 싁; 싁; 싁; ) HANGUL SYLLABLE SYIG
+C2C2;C2C2;1109 1174 11A9;C2C2;1109 1174 11A9; # (싂; 싂; 싂; 싂; 싂; ) HANGUL SYLLABLE SYIGG
+C2C3;C2C3;1109 1174 11AA;C2C3;1109 1174 11AA; # (싃; 싃; 싃; 싃; 싃; ) HANGUL SYLLABLE SYIGS
+C2C4;C2C4;1109 1174 11AB;C2C4;1109 1174 11AB; # (싄; 싄; 싄; 싄; 싄; ) HANGUL SYLLABLE SYIN
+C2C5;C2C5;1109 1174 11AC;C2C5;1109 1174 11AC; # (싅; 싅; 싅; 싅; 싅; ) HANGUL SYLLABLE SYINJ
+C2C6;C2C6;1109 1174 11AD;C2C6;1109 1174 11AD; # (싆; 싆; 싆; 싆; 싆; ) HANGUL SYLLABLE SYINH
+C2C7;C2C7;1109 1174 11AE;C2C7;1109 1174 11AE; # (싇; 싇; 싇; 싇; 싇; ) HANGUL SYLLABLE SYID
+C2C8;C2C8;1109 1174 11AF;C2C8;1109 1174 11AF; # (싈; 싈; 싈; 싈; 싈; ) HANGUL SYLLABLE SYIL
+C2C9;C2C9;1109 1174 11B0;C2C9;1109 1174 11B0; # (싉; 싉; 싉; 싉; 싉; ) HANGUL SYLLABLE SYILG
+C2CA;C2CA;1109 1174 11B1;C2CA;1109 1174 11B1; # (싊; 싊; 싊; 싊; 싊; ) HANGUL SYLLABLE SYILM
+C2CB;C2CB;1109 1174 11B2;C2CB;1109 1174 11B2; # (싋; 싋; 싋; 싋; 싋; ) HANGUL SYLLABLE SYILB
+C2CC;C2CC;1109 1174 11B3;C2CC;1109 1174 11B3; # (싌; 싌; 싌; 싌; 싌; ) HANGUL SYLLABLE SYILS
+C2CD;C2CD;1109 1174 11B4;C2CD;1109 1174 11B4; # (싍; 싍; 싍; 싍; 싍; ) HANGUL SYLLABLE SYILT
+C2CE;C2CE;1109 1174 11B5;C2CE;1109 1174 11B5; # (싎; 싎; 싎; 싎; 싎; ) HANGUL SYLLABLE SYILP
+C2CF;C2CF;1109 1174 11B6;C2CF;1109 1174 11B6; # (싏; 싏; 싏; 싏; 싏; ) HANGUL SYLLABLE SYILH
+C2D0;C2D0;1109 1174 11B7;C2D0;1109 1174 11B7; # (싐; 싐; 싐; 싐; 싐; ) HANGUL SYLLABLE SYIM
+C2D1;C2D1;1109 1174 11B8;C2D1;1109 1174 11B8; # (싑; 싑; 싑; 싑; 싑; ) HANGUL SYLLABLE SYIB
+C2D2;C2D2;1109 1174 11B9;C2D2;1109 1174 11B9; # (싒; 싒; 싒; 싒; 싒; ) HANGUL SYLLABLE SYIBS
+C2D3;C2D3;1109 1174 11BA;C2D3;1109 1174 11BA; # (싓; 싓; 싓; 싓; 싓; ) HANGUL SYLLABLE SYIS
+C2D4;C2D4;1109 1174 11BB;C2D4;1109 1174 11BB; # (싔; 싔; 싔; 싔; 싔; ) HANGUL SYLLABLE SYISS
+C2D5;C2D5;1109 1174 11BC;C2D5;1109 1174 11BC; # (싕; 싕; 싕; 싕; 싕; ) HANGUL SYLLABLE SYING
+C2D6;C2D6;1109 1174 11BD;C2D6;1109 1174 11BD; # (싖; 싖; 싖; 싖; 싖; ) HANGUL SYLLABLE SYIJ
+C2D7;C2D7;1109 1174 11BE;C2D7;1109 1174 11BE; # (싗; 싗; 싗; 싗; 싗; ) HANGUL SYLLABLE SYIC
+C2D8;C2D8;1109 1174 11BF;C2D8;1109 1174 11BF; # (싘; 싘; 싘; 싘; 싘; ) HANGUL SYLLABLE SYIK
+C2D9;C2D9;1109 1174 11C0;C2D9;1109 1174 11C0; # (싙; 싙; 싙; 싙; 싙; ) HANGUL SYLLABLE SYIT
+C2DA;C2DA;1109 1174 11C1;C2DA;1109 1174 11C1; # (싚; 싚; 싚; 싚; 싚; ) HANGUL SYLLABLE SYIP
+C2DB;C2DB;1109 1174 11C2;C2DB;1109 1174 11C2; # (싛; 싛; 싛; 싛; 싛; ) HANGUL SYLLABLE SYIH
+C2DC;C2DC;1109 1175;C2DC;1109 1175; # (시; 시; 시; 시; 시; ) HANGUL SYLLABLE SI
+C2DD;C2DD;1109 1175 11A8;C2DD;1109 1175 11A8; # (식; 식; 식; 식; 식; ) HANGUL SYLLABLE SIG
+C2DE;C2DE;1109 1175 11A9;C2DE;1109 1175 11A9; # (싞; 싞; 싞; 싞; 싞; ) HANGUL SYLLABLE SIGG
+C2DF;C2DF;1109 1175 11AA;C2DF;1109 1175 11AA; # (싟; 싟; 싟; 싟; 싟; ) HANGUL SYLLABLE SIGS
+C2E0;C2E0;1109 1175 11AB;C2E0;1109 1175 11AB; # (신; 신; 신; 신; 신; ) HANGUL SYLLABLE SIN
+C2E1;C2E1;1109 1175 11AC;C2E1;1109 1175 11AC; # (싡; 싡; 싡; 싡; 싡; ) HANGUL SYLLABLE SINJ
+C2E2;C2E2;1109 1175 11AD;C2E2;1109 1175 11AD; # (싢; 싢; 싢; 싢; 싢; ) HANGUL SYLLABLE SINH
+C2E3;C2E3;1109 1175 11AE;C2E3;1109 1175 11AE; # (싣; 싣; 싣; 싣; 싣; ) HANGUL SYLLABLE SID
+C2E4;C2E4;1109 1175 11AF;C2E4;1109 1175 11AF; # (실; 실; 실; 실; 실; ) HANGUL SYLLABLE SIL
+C2E5;C2E5;1109 1175 11B0;C2E5;1109 1175 11B0; # (싥; 싥; 싥; 싥; 싥; ) HANGUL SYLLABLE SILG
+C2E6;C2E6;1109 1175 11B1;C2E6;1109 1175 11B1; # (싦; 싦; 싦; 싦; 싦; ) HANGUL SYLLABLE SILM
+C2E7;C2E7;1109 1175 11B2;C2E7;1109 1175 11B2; # (싧; 싧; 싧; 싧; 싧; ) HANGUL SYLLABLE SILB
+C2E8;C2E8;1109 1175 11B3;C2E8;1109 1175 11B3; # (싨; 싨; 싨; 싨; 싨; ) HANGUL SYLLABLE SILS
+C2E9;C2E9;1109 1175 11B4;C2E9;1109 1175 11B4; # (싩; 싩; 싩; 싩; 싩; ) HANGUL SYLLABLE SILT
+C2EA;C2EA;1109 1175 11B5;C2EA;1109 1175 11B5; # (싪; 싪; 싪; 싪; 싪; ) HANGUL SYLLABLE SILP
+C2EB;C2EB;1109 1175 11B6;C2EB;1109 1175 11B6; # (싫; 싫; 싫; 싫; 싫; ) HANGUL SYLLABLE SILH
+C2EC;C2EC;1109 1175 11B7;C2EC;1109 1175 11B7; # (심; 심; 심; 심; 심; ) HANGUL SYLLABLE SIM
+C2ED;C2ED;1109 1175 11B8;C2ED;1109 1175 11B8; # (십; 십; 십; 십; 십; ) HANGUL SYLLABLE SIB
+C2EE;C2EE;1109 1175 11B9;C2EE;1109 1175 11B9; # (싮; 싮; 싮; 싮; 싮; ) HANGUL SYLLABLE SIBS
+C2EF;C2EF;1109 1175 11BA;C2EF;1109 1175 11BA; # (싯; 싯; 싯; 싯; 싯; ) HANGUL SYLLABLE SIS
+C2F0;C2F0;1109 1175 11BB;C2F0;1109 1175 11BB; # (싰; 싰; 싰; 싰; 싰; ) HANGUL SYLLABLE SISS
+C2F1;C2F1;1109 1175 11BC;C2F1;1109 1175 11BC; # (싱; 싱; 싱; 싱; 싱; ) HANGUL SYLLABLE SING
+C2F2;C2F2;1109 1175 11BD;C2F2;1109 1175 11BD; # (싲; 싲; 싲; 싲; 싲; ) HANGUL SYLLABLE SIJ
+C2F3;C2F3;1109 1175 11BE;C2F3;1109 1175 11BE; # (싳; 싳; 싳; 싳; 싳; ) HANGUL SYLLABLE SIC
+C2F4;C2F4;1109 1175 11BF;C2F4;1109 1175 11BF; # (싴; 싴; 싴; 싴; 싴; ) HANGUL SYLLABLE SIK
+C2F5;C2F5;1109 1175 11C0;C2F5;1109 1175 11C0; # (싵; 싵; 싵; 싵; 싵; ) HANGUL SYLLABLE SIT
+C2F6;C2F6;1109 1175 11C1;C2F6;1109 1175 11C1; # (싶; 싶; 싶; 싶; 싶; ) HANGUL SYLLABLE SIP
+C2F7;C2F7;1109 1175 11C2;C2F7;1109 1175 11C2; # (싷; 싷; 싷; 싷; 싷; ) HANGUL SYLLABLE SIH
+C2F8;C2F8;110A 1161;C2F8;110A 1161; # (싸; 싸; 싸; 싸; 싸; ) HANGUL SYLLABLE SSA
+C2F9;C2F9;110A 1161 11A8;C2F9;110A 1161 11A8; # (싹; 싹; 싹; 싹; 싹; ) HANGUL SYLLABLE SSAG
+C2FA;C2FA;110A 1161 11A9;C2FA;110A 1161 11A9; # (싺; 싺; 싺; 싺; 싺; ) HANGUL SYLLABLE SSAGG
+C2FB;C2FB;110A 1161 11AA;C2FB;110A 1161 11AA; # (싻; 싻; 싻; 싻; 싻; ) HANGUL SYLLABLE SSAGS
+C2FC;C2FC;110A 1161 11AB;C2FC;110A 1161 11AB; # (싼; 싼; 싼; 싼; 싼; ) HANGUL SYLLABLE SSAN
+C2FD;C2FD;110A 1161 11AC;C2FD;110A 1161 11AC; # (싽; 싽; 싽; 싽; 싽; ) HANGUL SYLLABLE SSANJ
+C2FE;C2FE;110A 1161 11AD;C2FE;110A 1161 11AD; # (싾; 싾; 싾; 싾; 싾; ) HANGUL SYLLABLE SSANH
+C2FF;C2FF;110A 1161 11AE;C2FF;110A 1161 11AE; # (싿; 싿; 싿; 싿; 싿; ) HANGUL SYLLABLE SSAD
+C300;C300;110A 1161 11AF;C300;110A 1161 11AF; # (쌀; 쌀; 쌀; 쌀; 쌀; ) HANGUL SYLLABLE SSAL
+C301;C301;110A 1161 11B0;C301;110A 1161 11B0; # (쌁; 쌁; 쌁; 쌁; 쌁; ) HANGUL SYLLABLE SSALG
+C302;C302;110A 1161 11B1;C302;110A 1161 11B1; # (쌂; 쌂; 쌂; 쌂; 쌂; ) HANGUL SYLLABLE SSALM
+C303;C303;110A 1161 11B2;C303;110A 1161 11B2; # (쌃; 쌃; 쌃; 쌃; 쌃; ) HANGUL SYLLABLE SSALB
+C304;C304;110A 1161 11B3;C304;110A 1161 11B3; # (쌄; 쌄; 쌄; 쌄; 쌄; ) HANGUL SYLLABLE SSALS
+C305;C305;110A 1161 11B4;C305;110A 1161 11B4; # (쌅; 쌅; 쌅; 쌅; 쌅; ) HANGUL SYLLABLE SSALT
+C306;C306;110A 1161 11B5;C306;110A 1161 11B5; # (쌆; 쌆; 쌆; 쌆; 쌆; ) HANGUL SYLLABLE SSALP
+C307;C307;110A 1161 11B6;C307;110A 1161 11B6; # (쌇; 쌇; 쌇; 쌇; 쌇; ) HANGUL SYLLABLE SSALH
+C308;C308;110A 1161 11B7;C308;110A 1161 11B7; # (쌈; 쌈; 쌈; 쌈; 쌈; ) HANGUL SYLLABLE SSAM
+C309;C309;110A 1161 11B8;C309;110A 1161 11B8; # (쌉; 쌉; 쌉; 쌉; 쌉; ) HANGUL SYLLABLE SSAB
+C30A;C30A;110A 1161 11B9;C30A;110A 1161 11B9; # (쌊; 쌊; 쌊; 쌊; 쌊; ) HANGUL SYLLABLE SSABS
+C30B;C30B;110A 1161 11BA;C30B;110A 1161 11BA; # (쌋; 쌋; 쌋; 쌋; 쌋; ) HANGUL SYLLABLE SSAS
+C30C;C30C;110A 1161 11BB;C30C;110A 1161 11BB; # (쌌; 쌌; 쌌; 쌌; 쌌; ) HANGUL SYLLABLE SSASS
+C30D;C30D;110A 1161 11BC;C30D;110A 1161 11BC; # (쌍; 쌍; 쌍; 쌍; 쌍; ) HANGUL SYLLABLE SSANG
+C30E;C30E;110A 1161 11BD;C30E;110A 1161 11BD; # (쌎; 쌎; 쌎; 쌎; 쌎; ) HANGUL SYLLABLE SSAJ
+C30F;C30F;110A 1161 11BE;C30F;110A 1161 11BE; # (쌏; 쌏; 쌏; 쌏; 쌏; ) HANGUL SYLLABLE SSAC
+C310;C310;110A 1161 11BF;C310;110A 1161 11BF; # (쌐; 쌐; 쌐; 쌐; 쌐; ) HANGUL SYLLABLE SSAK
+C311;C311;110A 1161 11C0;C311;110A 1161 11C0; # (쌑; 쌑; 쌑; 쌑; 쌑; ) HANGUL SYLLABLE SSAT
+C312;C312;110A 1161 11C1;C312;110A 1161 11C1; # (쌒; 쌒; 쌒; 쌒; 쌒; ) HANGUL SYLLABLE SSAP
+C313;C313;110A 1161 11C2;C313;110A 1161 11C2; # (쌓; 쌓; 쌓; 쌓; 쌓; ) HANGUL SYLLABLE SSAH
+C314;C314;110A 1162;C314;110A 1162; # (쌔; 쌔; 쌔; 쌔; 쌔; ) HANGUL SYLLABLE SSAE
+C315;C315;110A 1162 11A8;C315;110A 1162 11A8; # (쌕; 쌕; 쌕; 쌕; 쌕; ) HANGUL SYLLABLE SSAEG
+C316;C316;110A 1162 11A9;C316;110A 1162 11A9; # (쌖; 쌖; 쌖; 쌖; 쌖; ) HANGUL SYLLABLE SSAEGG
+C317;C317;110A 1162 11AA;C317;110A 1162 11AA; # (쌗; 쌗; 쌗; 쌗; 쌗; ) HANGUL SYLLABLE SSAEGS
+C318;C318;110A 1162 11AB;C318;110A 1162 11AB; # (쌘; 쌘; 쌘; 쌘; 쌘; ) HANGUL SYLLABLE SSAEN
+C319;C319;110A 1162 11AC;C319;110A 1162 11AC; # (쌙; 쌙; 쌙; 쌙; 쌙; ) HANGUL SYLLABLE SSAENJ
+C31A;C31A;110A 1162 11AD;C31A;110A 1162 11AD; # (쌚; 쌚; 쌚; 쌚; 쌚; ) HANGUL SYLLABLE SSAENH
+C31B;C31B;110A 1162 11AE;C31B;110A 1162 11AE; # (쌛; 쌛; 쌛; 쌛; 쌛; ) HANGUL SYLLABLE SSAED
+C31C;C31C;110A 1162 11AF;C31C;110A 1162 11AF; # (쌜; 쌜; 쌜; 쌜; 쌜; ) HANGUL SYLLABLE SSAEL
+C31D;C31D;110A 1162 11B0;C31D;110A 1162 11B0; # (쌝; 쌝; 쌝; 쌝; 쌝; ) HANGUL SYLLABLE SSAELG
+C31E;C31E;110A 1162 11B1;C31E;110A 1162 11B1; # (쌞; 쌞; 쌞; 쌞; 쌞; ) HANGUL SYLLABLE SSAELM
+C31F;C31F;110A 1162 11B2;C31F;110A 1162 11B2; # (쌟; 쌟; 쌟; 쌟; 쌟; ) HANGUL SYLLABLE SSAELB
+C320;C320;110A 1162 11B3;C320;110A 1162 11B3; # (쌠; 쌠; 쌠; 쌠; 쌠; ) HANGUL SYLLABLE SSAELS
+C321;C321;110A 1162 11B4;C321;110A 1162 11B4; # (쌡; 쌡; 쌡; 쌡; 쌡; ) HANGUL SYLLABLE SSAELT
+C322;C322;110A 1162 11B5;C322;110A 1162 11B5; # (쌢; 쌢; 쌢; 쌢; 쌢; ) HANGUL SYLLABLE SSAELP
+C323;C323;110A 1162 11B6;C323;110A 1162 11B6; # (쌣; 쌣; 쌣; 쌣; 쌣; ) HANGUL SYLLABLE SSAELH
+C324;C324;110A 1162 11B7;C324;110A 1162 11B7; # (쌤; 쌤; 쌤; 쌤; 쌤; ) HANGUL SYLLABLE SSAEM
+C325;C325;110A 1162 11B8;C325;110A 1162 11B8; # (쌥; 쌥; 쌥; 쌥; 쌥; ) HANGUL SYLLABLE SSAEB
+C326;C326;110A 1162 11B9;C326;110A 1162 11B9; # (쌦; 쌦; 쌦; 쌦; 쌦; ) HANGUL SYLLABLE SSAEBS
+C327;C327;110A 1162 11BA;C327;110A 1162 11BA; # (쌧; 쌧; 쌧; 쌧; 쌧; ) HANGUL SYLLABLE SSAES
+C328;C328;110A 1162 11BB;C328;110A 1162 11BB; # (쌨; 쌨; 쌨; 쌨; 쌨; ) HANGUL SYLLABLE SSAESS
+C329;C329;110A 1162 11BC;C329;110A 1162 11BC; # (쌩; 쌩; 쌩; 쌩; 쌩; ) HANGUL SYLLABLE SSAENG
+C32A;C32A;110A 1162 11BD;C32A;110A 1162 11BD; # (쌪; 쌪; 쌪; 쌪; 쌪; ) HANGUL SYLLABLE SSAEJ
+C32B;C32B;110A 1162 11BE;C32B;110A 1162 11BE; # (쌫; 쌫; 쌫; 쌫; 쌫; ) HANGUL SYLLABLE SSAEC
+C32C;C32C;110A 1162 11BF;C32C;110A 1162 11BF; # (쌬; 쌬; 쌬; 쌬; 쌬; ) HANGUL SYLLABLE SSAEK
+C32D;C32D;110A 1162 11C0;C32D;110A 1162 11C0; # (쌭; 쌭; 쌭; 쌭; 쌭; ) HANGUL SYLLABLE SSAET
+C32E;C32E;110A 1162 11C1;C32E;110A 1162 11C1; # (쌮; 쌮; 쌮; 쌮; 쌮; ) HANGUL SYLLABLE SSAEP
+C32F;C32F;110A 1162 11C2;C32F;110A 1162 11C2; # (쌯; 쌯; 쌯; 쌯; 쌯; ) HANGUL SYLLABLE SSAEH
+C330;C330;110A 1163;C330;110A 1163; # (쌰; 쌰; 쌰; 쌰; 쌰; ) HANGUL SYLLABLE SSYA
+C331;C331;110A 1163 11A8;C331;110A 1163 11A8; # (쌱; 쌱; 쌱; 쌱; 쌱; ) HANGUL SYLLABLE SSYAG
+C332;C332;110A 1163 11A9;C332;110A 1163 11A9; # (쌲; 쌲; 쌲; 쌲; 쌲; ) HANGUL SYLLABLE SSYAGG
+C333;C333;110A 1163 11AA;C333;110A 1163 11AA; # (쌳; 쌳; 쌳; 쌳; 쌳; ) HANGUL SYLLABLE SSYAGS
+C334;C334;110A 1163 11AB;C334;110A 1163 11AB; # (쌴; 쌴; 쌴; 쌴; 쌴; ) HANGUL SYLLABLE SSYAN
+C335;C335;110A 1163 11AC;C335;110A 1163 11AC; # (쌵; 쌵; 쌵; 쌵; 쌵; ) HANGUL SYLLABLE SSYANJ
+C336;C336;110A 1163 11AD;C336;110A 1163 11AD; # (쌶; 쌶; 쌶; 쌶; 쌶; ) HANGUL SYLLABLE SSYANH
+C337;C337;110A 1163 11AE;C337;110A 1163 11AE; # (쌷; 쌷; 쌷; 쌷; 쌷; ) HANGUL SYLLABLE SSYAD
+C338;C338;110A 1163 11AF;C338;110A 1163 11AF; # (쌸; 쌸; 쌸; 쌸; 쌸; ) HANGUL SYLLABLE SSYAL
+C339;C339;110A 1163 11B0;C339;110A 1163 11B0; # (쌹; 쌹; 쌹; 쌹; 쌹; ) HANGUL SYLLABLE SSYALG
+C33A;C33A;110A 1163 11B1;C33A;110A 1163 11B1; # (쌺; 쌺; 쌺; 쌺; 쌺; ) HANGUL SYLLABLE SSYALM
+C33B;C33B;110A 1163 11B2;C33B;110A 1163 11B2; # (쌻; 쌻; 쌻; 쌻; 쌻; ) HANGUL SYLLABLE SSYALB
+C33C;C33C;110A 1163 11B3;C33C;110A 1163 11B3; # (쌼; 쌼; 쌼; 쌼; 쌼; ) HANGUL SYLLABLE SSYALS
+C33D;C33D;110A 1163 11B4;C33D;110A 1163 11B4; # (쌽; 쌽; 쌽; 쌽; 쌽; ) HANGUL SYLLABLE SSYALT
+C33E;C33E;110A 1163 11B5;C33E;110A 1163 11B5; # (쌾; 쌾; 쌾; 쌾; 쌾; ) HANGUL SYLLABLE SSYALP
+C33F;C33F;110A 1163 11B6;C33F;110A 1163 11B6; # (쌿; 쌿; 쌿; 쌿; 쌿; ) HANGUL SYLLABLE SSYALH
+C340;C340;110A 1163 11B7;C340;110A 1163 11B7; # (썀; 썀; 썀; 썀; 썀; ) HANGUL SYLLABLE SSYAM
+C341;C341;110A 1163 11B8;C341;110A 1163 11B8; # (썁; 썁; 썁; 썁; 썁; ) HANGUL SYLLABLE SSYAB
+C342;C342;110A 1163 11B9;C342;110A 1163 11B9; # (썂; 썂; 썂; 썂; 썂; ) HANGUL SYLLABLE SSYABS
+C343;C343;110A 1163 11BA;C343;110A 1163 11BA; # (썃; 썃; 썃; 썃; 썃; ) HANGUL SYLLABLE SSYAS
+C344;C344;110A 1163 11BB;C344;110A 1163 11BB; # (썄; 썄; 썄; 썄; 썄; ) HANGUL SYLLABLE SSYASS
+C345;C345;110A 1163 11BC;C345;110A 1163 11BC; # (썅; 썅; 썅; 썅; 썅; ) HANGUL SYLLABLE SSYANG
+C346;C346;110A 1163 11BD;C346;110A 1163 11BD; # (썆; 썆; 썆; 썆; 썆; ) HANGUL SYLLABLE SSYAJ
+C347;C347;110A 1163 11BE;C347;110A 1163 11BE; # (썇; 썇; 썇; 썇; 썇; ) HANGUL SYLLABLE SSYAC
+C348;C348;110A 1163 11BF;C348;110A 1163 11BF; # (썈; 썈; 썈; 썈; 썈; ) HANGUL SYLLABLE SSYAK
+C349;C349;110A 1163 11C0;C349;110A 1163 11C0; # (썉; 썉; 썉; 썉; 썉; ) HANGUL SYLLABLE SSYAT
+C34A;C34A;110A 1163 11C1;C34A;110A 1163 11C1; # (썊; 썊; 썊; 썊; 썊; ) HANGUL SYLLABLE SSYAP
+C34B;C34B;110A 1163 11C2;C34B;110A 1163 11C2; # (썋; 썋; 썋; 썋; 썋; ) HANGUL SYLLABLE SSYAH
+C34C;C34C;110A 1164;C34C;110A 1164; # (썌; 썌; 썌; 썌; 썌; ) HANGUL SYLLABLE SSYAE
+C34D;C34D;110A 1164 11A8;C34D;110A 1164 11A8; # (썍; 썍; 썍; 썍; 썍; ) HANGUL SYLLABLE SSYAEG
+C34E;C34E;110A 1164 11A9;C34E;110A 1164 11A9; # (썎; 썎; 썎; 썎; 썎; ) HANGUL SYLLABLE SSYAEGG
+C34F;C34F;110A 1164 11AA;C34F;110A 1164 11AA; # (썏; 썏; 썏; 썏; 썏; ) HANGUL SYLLABLE SSYAEGS
+C350;C350;110A 1164 11AB;C350;110A 1164 11AB; # (썐; 썐; 썐; 썐; 썐; ) HANGUL SYLLABLE SSYAEN
+C351;C351;110A 1164 11AC;C351;110A 1164 11AC; # (썑; 썑; 썑; 썑; 썑; ) HANGUL SYLLABLE SSYAENJ
+C352;C352;110A 1164 11AD;C352;110A 1164 11AD; # (썒; 썒; 썒; 썒; 썒; ) HANGUL SYLLABLE SSYAENH
+C353;C353;110A 1164 11AE;C353;110A 1164 11AE; # (썓; 썓; 썓; 썓; 썓; ) HANGUL SYLLABLE SSYAED
+C354;C354;110A 1164 11AF;C354;110A 1164 11AF; # (썔; 썔; 썔; 썔; 썔; ) HANGUL SYLLABLE SSYAEL
+C355;C355;110A 1164 11B0;C355;110A 1164 11B0; # (썕; 썕; 썕; 썕; 썕; ) HANGUL SYLLABLE SSYAELG
+C356;C356;110A 1164 11B1;C356;110A 1164 11B1; # (썖; 썖; 썖; 썖; 썖; ) HANGUL SYLLABLE SSYAELM
+C357;C357;110A 1164 11B2;C357;110A 1164 11B2; # (썗; 썗; 썗; 썗; 썗; ) HANGUL SYLLABLE SSYAELB
+C358;C358;110A 1164 11B3;C358;110A 1164 11B3; # (썘; 썘; 썘; 썘; 썘; ) HANGUL SYLLABLE SSYAELS
+C359;C359;110A 1164 11B4;C359;110A 1164 11B4; # (썙; 썙; 썙; 썙; 썙; ) HANGUL SYLLABLE SSYAELT
+C35A;C35A;110A 1164 11B5;C35A;110A 1164 11B5; # (썚; 썚; 썚; 썚; 썚; ) HANGUL SYLLABLE SSYAELP
+C35B;C35B;110A 1164 11B6;C35B;110A 1164 11B6; # (썛; 썛; 썛; 썛; 썛; ) HANGUL SYLLABLE SSYAELH
+C35C;C35C;110A 1164 11B7;C35C;110A 1164 11B7; # (썜; 썜; 썜; 썜; 썜; ) HANGUL SYLLABLE SSYAEM
+C35D;C35D;110A 1164 11B8;C35D;110A 1164 11B8; # (썝; 썝; 썝; 썝; 썝; ) HANGUL SYLLABLE SSYAEB
+C35E;C35E;110A 1164 11B9;C35E;110A 1164 11B9; # (썞; 썞; 썞; 썞; 썞; ) HANGUL SYLLABLE SSYAEBS
+C35F;C35F;110A 1164 11BA;C35F;110A 1164 11BA; # (썟; 썟; 썟; 썟; 썟; ) HANGUL SYLLABLE SSYAES
+C360;C360;110A 1164 11BB;C360;110A 1164 11BB; # (썠; 썠; 썠; 썠; 썠; ) HANGUL SYLLABLE SSYAESS
+C361;C361;110A 1164 11BC;C361;110A 1164 11BC; # (썡; 썡; 썡; 썡; 썡; ) HANGUL SYLLABLE SSYAENG
+C362;C362;110A 1164 11BD;C362;110A 1164 11BD; # (썢; 썢; 썢; 썢; 썢; ) HANGUL SYLLABLE SSYAEJ
+C363;C363;110A 1164 11BE;C363;110A 1164 11BE; # (썣; 썣; 썣; 썣; 썣; ) HANGUL SYLLABLE SSYAEC
+C364;C364;110A 1164 11BF;C364;110A 1164 11BF; # (썤; 썤; 썤; 썤; 썤; ) HANGUL SYLLABLE SSYAEK
+C365;C365;110A 1164 11C0;C365;110A 1164 11C0; # (썥; 썥; 썥; 썥; 썥; ) HANGUL SYLLABLE SSYAET
+C366;C366;110A 1164 11C1;C366;110A 1164 11C1; # (썦; 썦; 썦; 썦; 썦; ) HANGUL SYLLABLE SSYAEP
+C367;C367;110A 1164 11C2;C367;110A 1164 11C2; # (썧; 썧; 썧; 썧; 썧; ) HANGUL SYLLABLE SSYAEH
+C368;C368;110A 1165;C368;110A 1165; # (써; 써; 써; 써; 써; ) HANGUL SYLLABLE SSEO
+C369;C369;110A 1165 11A8;C369;110A 1165 11A8; # (썩; 썩; 썩; 썩; 썩; ) HANGUL SYLLABLE SSEOG
+C36A;C36A;110A 1165 11A9;C36A;110A 1165 11A9; # (썪; 썪; 썪; 썪; 썪; ) HANGUL SYLLABLE SSEOGG
+C36B;C36B;110A 1165 11AA;C36B;110A 1165 11AA; # (썫; 썫; 썫; 썫; 썫; ) HANGUL SYLLABLE SSEOGS
+C36C;C36C;110A 1165 11AB;C36C;110A 1165 11AB; # (썬; 썬; 썬; 썬; 썬; ) HANGUL SYLLABLE SSEON
+C36D;C36D;110A 1165 11AC;C36D;110A 1165 11AC; # (썭; 썭; 썭; 썭; 썭; ) HANGUL SYLLABLE SSEONJ
+C36E;C36E;110A 1165 11AD;C36E;110A 1165 11AD; # (썮; 썮; 썮; 썮; 썮; ) HANGUL SYLLABLE SSEONH
+C36F;C36F;110A 1165 11AE;C36F;110A 1165 11AE; # (썯; 썯; 썯; 썯; 썯; ) HANGUL SYLLABLE SSEOD
+C370;C370;110A 1165 11AF;C370;110A 1165 11AF; # (썰; 썰; 썰; 썰; 썰; ) HANGUL SYLLABLE SSEOL
+C371;C371;110A 1165 11B0;C371;110A 1165 11B0; # (썱; 썱; 썱; 썱; 썱; ) HANGUL SYLLABLE SSEOLG
+C372;C372;110A 1165 11B1;C372;110A 1165 11B1; # (썲; 썲; 썲; 썲; 썲; ) HANGUL SYLLABLE SSEOLM
+C373;C373;110A 1165 11B2;C373;110A 1165 11B2; # (썳; 썳; 썳; 썳; 썳; ) HANGUL SYLLABLE SSEOLB
+C374;C374;110A 1165 11B3;C374;110A 1165 11B3; # (썴; 썴; 썴; 썴; 썴; ) HANGUL SYLLABLE SSEOLS
+C375;C375;110A 1165 11B4;C375;110A 1165 11B4; # (썵; 썵; 썵; 썵; 썵; ) HANGUL SYLLABLE SSEOLT
+C376;C376;110A 1165 11B5;C376;110A 1165 11B5; # (썶; 썶; 썶; 썶; 썶; ) HANGUL SYLLABLE SSEOLP
+C377;C377;110A 1165 11B6;C377;110A 1165 11B6; # (썷; 썷; 썷; 썷; 썷; ) HANGUL SYLLABLE SSEOLH
+C378;C378;110A 1165 11B7;C378;110A 1165 11B7; # (썸; 썸; 썸; 썸; 썸; ) HANGUL SYLLABLE SSEOM
+C379;C379;110A 1165 11B8;C379;110A 1165 11B8; # (썹; 썹; 썹; 썹; 썹; ) HANGUL SYLLABLE SSEOB
+C37A;C37A;110A 1165 11B9;C37A;110A 1165 11B9; # (썺; 썺; 썺; 썺; 썺; ) HANGUL SYLLABLE SSEOBS
+C37B;C37B;110A 1165 11BA;C37B;110A 1165 11BA; # (썻; 썻; 썻; 썻; 썻; ) HANGUL SYLLABLE SSEOS
+C37C;C37C;110A 1165 11BB;C37C;110A 1165 11BB; # (썼; 썼; 썼; 썼; 썼; ) HANGUL SYLLABLE SSEOSS
+C37D;C37D;110A 1165 11BC;C37D;110A 1165 11BC; # (썽; 썽; 썽; 썽; 썽; ) HANGUL SYLLABLE SSEONG
+C37E;C37E;110A 1165 11BD;C37E;110A 1165 11BD; # (썾; 썾; 썾; 썾; 썾; ) HANGUL SYLLABLE SSEOJ
+C37F;C37F;110A 1165 11BE;C37F;110A 1165 11BE; # (썿; 썿; 썿; 썿; 썿; ) HANGUL SYLLABLE SSEOC
+C380;C380;110A 1165 11BF;C380;110A 1165 11BF; # (쎀; 쎀; 쎀; 쎀; 쎀; ) HANGUL SYLLABLE SSEOK
+C381;C381;110A 1165 11C0;C381;110A 1165 11C0; # (쎁; 쎁; 쎁; 쎁; 쎁; ) HANGUL SYLLABLE SSEOT
+C382;C382;110A 1165 11C1;C382;110A 1165 11C1; # (쎂; 쎂; 쎂; 쎂; 쎂; ) HANGUL SYLLABLE SSEOP
+C383;C383;110A 1165 11C2;C383;110A 1165 11C2; # (쎃; 쎃; 쎃; 쎃; 쎃; ) HANGUL SYLLABLE SSEOH
+C384;C384;110A 1166;C384;110A 1166; # (쎄; 쎄; 쎄; 쎄; 쎄; ) HANGUL SYLLABLE SSE
+C385;C385;110A 1166 11A8;C385;110A 1166 11A8; # (쎅; 쎅; 쎅; 쎅; 쎅; ) HANGUL SYLLABLE SSEG
+C386;C386;110A 1166 11A9;C386;110A 1166 11A9; # (쎆; 쎆; 쎆; 쎆; 쎆; ) HANGUL SYLLABLE SSEGG
+C387;C387;110A 1166 11AA;C387;110A 1166 11AA; # (쎇; 쎇; 쎇; 쎇; 쎇; ) HANGUL SYLLABLE SSEGS
+C388;C388;110A 1166 11AB;C388;110A 1166 11AB; # (쎈; 쎈; 쎈; 쎈; 쎈; ) HANGUL SYLLABLE SSEN
+C389;C389;110A 1166 11AC;C389;110A 1166 11AC; # (쎉; 쎉; 쎉; 쎉; 쎉; ) HANGUL SYLLABLE SSENJ
+C38A;C38A;110A 1166 11AD;C38A;110A 1166 11AD; # (쎊; 쎊; 쎊; 쎊; 쎊; ) HANGUL SYLLABLE SSENH
+C38B;C38B;110A 1166 11AE;C38B;110A 1166 11AE; # (쎋; 쎋; 쎋; 쎋; 쎋; ) HANGUL SYLLABLE SSED
+C38C;C38C;110A 1166 11AF;C38C;110A 1166 11AF; # (쎌; 쎌; 쎌; 쎌; 쎌; ) HANGUL SYLLABLE SSEL
+C38D;C38D;110A 1166 11B0;C38D;110A 1166 11B0; # (쎍; 쎍; 쎍; 쎍; 쎍; ) HANGUL SYLLABLE SSELG
+C38E;C38E;110A 1166 11B1;C38E;110A 1166 11B1; # (쎎; 쎎; 쎎; 쎎; 쎎; ) HANGUL SYLLABLE SSELM
+C38F;C38F;110A 1166 11B2;C38F;110A 1166 11B2; # (쎏; 쎏; 쎏; 쎏; 쎏; ) HANGUL SYLLABLE SSELB
+C390;C390;110A 1166 11B3;C390;110A 1166 11B3; # (쎐; 쎐; 쎐; 쎐; 쎐; ) HANGUL SYLLABLE SSELS
+C391;C391;110A 1166 11B4;C391;110A 1166 11B4; # (쎑; 쎑; 쎑; 쎑; 쎑; ) HANGUL SYLLABLE SSELT
+C392;C392;110A 1166 11B5;C392;110A 1166 11B5; # (쎒; 쎒; 쎒; 쎒; 쎒; ) HANGUL SYLLABLE SSELP
+C393;C393;110A 1166 11B6;C393;110A 1166 11B6; # (쎓; 쎓; 쎓; 쎓; 쎓; ) HANGUL SYLLABLE SSELH
+C394;C394;110A 1166 11B7;C394;110A 1166 11B7; # (쎔; 쎔; 쎔; 쎔; 쎔; ) HANGUL SYLLABLE SSEM
+C395;C395;110A 1166 11B8;C395;110A 1166 11B8; # (쎕; 쎕; 쎕; 쎕; 쎕; ) HANGUL SYLLABLE SSEB
+C396;C396;110A 1166 11B9;C396;110A 1166 11B9; # (쎖; 쎖; 쎖; 쎖; 쎖; ) HANGUL SYLLABLE SSEBS
+C397;C397;110A 1166 11BA;C397;110A 1166 11BA; # (쎗; 쎗; 쎗; 쎗; 쎗; ) HANGUL SYLLABLE SSES
+C398;C398;110A 1166 11BB;C398;110A 1166 11BB; # (쎘; 쎘; 쎘; 쎘; 쎘; ) HANGUL SYLLABLE SSESS
+C399;C399;110A 1166 11BC;C399;110A 1166 11BC; # (쎙; 쎙; 쎙; 쎙; 쎙; ) HANGUL SYLLABLE SSENG
+C39A;C39A;110A 1166 11BD;C39A;110A 1166 11BD; # (쎚; 쎚; 쎚; 쎚; 쎚; ) HANGUL SYLLABLE SSEJ
+C39B;C39B;110A 1166 11BE;C39B;110A 1166 11BE; # (쎛; 쎛; 쎛; 쎛; 쎛; ) HANGUL SYLLABLE SSEC
+C39C;C39C;110A 1166 11BF;C39C;110A 1166 11BF; # (쎜; 쎜; 쎜; 쎜; 쎜; ) HANGUL SYLLABLE SSEK
+C39D;C39D;110A 1166 11C0;C39D;110A 1166 11C0; # (쎝; 쎝; 쎝; 쎝; 쎝; ) HANGUL SYLLABLE SSET
+C39E;C39E;110A 1166 11C1;C39E;110A 1166 11C1; # (쎞; 쎞; 쎞; 쎞; 쎞; ) HANGUL SYLLABLE SSEP
+C39F;C39F;110A 1166 11C2;C39F;110A 1166 11C2; # (쎟; 쎟; 쎟; 쎟; 쎟; ) HANGUL SYLLABLE SSEH
+C3A0;C3A0;110A 1167;C3A0;110A 1167; # (쎠; 쎠; 쎠; 쎠; 쎠; ) HANGUL SYLLABLE SSYEO
+C3A1;C3A1;110A 1167 11A8;C3A1;110A 1167 11A8; # (쎡; 쎡; 쎡; 쎡; 쎡; ) HANGUL SYLLABLE SSYEOG
+C3A2;C3A2;110A 1167 11A9;C3A2;110A 1167 11A9; # (쎢; 쎢; 쎢; 쎢; 쎢; ) HANGUL SYLLABLE SSYEOGG
+C3A3;C3A3;110A 1167 11AA;C3A3;110A 1167 11AA; # (쎣; 쎣; 쎣; 쎣; 쎣; ) HANGUL SYLLABLE SSYEOGS
+C3A4;C3A4;110A 1167 11AB;C3A4;110A 1167 11AB; # (쎤; 쎤; 쎤; 쎤; 쎤; ) HANGUL SYLLABLE SSYEON
+C3A5;C3A5;110A 1167 11AC;C3A5;110A 1167 11AC; # (쎥; 쎥; 쎥; 쎥; 쎥; ) HANGUL SYLLABLE SSYEONJ
+C3A6;C3A6;110A 1167 11AD;C3A6;110A 1167 11AD; # (쎦; 쎦; 쎦; 쎦; 쎦; ) HANGUL SYLLABLE SSYEONH
+C3A7;C3A7;110A 1167 11AE;C3A7;110A 1167 11AE; # (쎧; 쎧; 쎧; 쎧; 쎧; ) HANGUL SYLLABLE SSYEOD
+C3A8;C3A8;110A 1167 11AF;C3A8;110A 1167 11AF; # (쎨; 쎨; 쎨; 쎨; 쎨; ) HANGUL SYLLABLE SSYEOL
+C3A9;C3A9;110A 1167 11B0;C3A9;110A 1167 11B0; # (쎩; 쎩; 쎩; 쎩; 쎩; ) HANGUL SYLLABLE SSYEOLG
+C3AA;C3AA;110A 1167 11B1;C3AA;110A 1167 11B1; # (쎪; 쎪; 쎪; 쎪; 쎪; ) HANGUL SYLLABLE SSYEOLM
+C3AB;C3AB;110A 1167 11B2;C3AB;110A 1167 11B2; # (쎫; 쎫; 쎫; 쎫; 쎫; ) HANGUL SYLLABLE SSYEOLB
+C3AC;C3AC;110A 1167 11B3;C3AC;110A 1167 11B3; # (쎬; 쎬; 쎬; 쎬; 쎬; ) HANGUL SYLLABLE SSYEOLS
+C3AD;C3AD;110A 1167 11B4;C3AD;110A 1167 11B4; # (쎭; 쎭; 쎭; 쎭; 쎭; ) HANGUL SYLLABLE SSYEOLT
+C3AE;C3AE;110A 1167 11B5;C3AE;110A 1167 11B5; # (쎮; 쎮; 쎮; 쎮; 쎮; ) HANGUL SYLLABLE SSYEOLP
+C3AF;C3AF;110A 1167 11B6;C3AF;110A 1167 11B6; # (쎯; 쎯; 쎯; 쎯; 쎯; ) HANGUL SYLLABLE SSYEOLH
+C3B0;C3B0;110A 1167 11B7;C3B0;110A 1167 11B7; # (쎰; 쎰; 쎰; 쎰; 쎰; ) HANGUL SYLLABLE SSYEOM
+C3B1;C3B1;110A 1167 11B8;C3B1;110A 1167 11B8; # (쎱; 쎱; 쎱; 쎱; 쎱; ) HANGUL SYLLABLE SSYEOB
+C3B2;C3B2;110A 1167 11B9;C3B2;110A 1167 11B9; # (쎲; 쎲; 쎲; 쎲; 쎲; ) HANGUL SYLLABLE SSYEOBS
+C3B3;C3B3;110A 1167 11BA;C3B3;110A 1167 11BA; # (쎳; 쎳; 쎳; 쎳; 쎳; ) HANGUL SYLLABLE SSYEOS
+C3B4;C3B4;110A 1167 11BB;C3B4;110A 1167 11BB; # (쎴; 쎴; 쎴; 쎴; 쎴; ) HANGUL SYLLABLE SSYEOSS
+C3B5;C3B5;110A 1167 11BC;C3B5;110A 1167 11BC; # (쎵; 쎵; 쎵; 쎵; 쎵; ) HANGUL SYLLABLE SSYEONG
+C3B6;C3B6;110A 1167 11BD;C3B6;110A 1167 11BD; # (쎶; 쎶; 쎶; 쎶; 쎶; ) HANGUL SYLLABLE SSYEOJ
+C3B7;C3B7;110A 1167 11BE;C3B7;110A 1167 11BE; # (쎷; 쎷; 쎷; 쎷; 쎷; ) HANGUL SYLLABLE SSYEOC
+C3B8;C3B8;110A 1167 11BF;C3B8;110A 1167 11BF; # (쎸; 쎸; 쎸; 쎸; 쎸; ) HANGUL SYLLABLE SSYEOK
+C3B9;C3B9;110A 1167 11C0;C3B9;110A 1167 11C0; # (쎹; 쎹; 쎹; 쎹; 쎹; ) HANGUL SYLLABLE SSYEOT
+C3BA;C3BA;110A 1167 11C1;C3BA;110A 1167 11C1; # (쎺; 쎺; 쎺; 쎺; 쎺; ) HANGUL SYLLABLE SSYEOP
+C3BB;C3BB;110A 1167 11C2;C3BB;110A 1167 11C2; # (쎻; 쎻; 쎻; 쎻; 쎻; ) HANGUL SYLLABLE SSYEOH
+C3BC;C3BC;110A 1168;C3BC;110A 1168; # (쎼; 쎼; 쎼; 쎼; 쎼; ) HANGUL SYLLABLE SSYE
+C3BD;C3BD;110A 1168 11A8;C3BD;110A 1168 11A8; # (쎽; 쎽; 쎽; 쎽; 쎽; ) HANGUL SYLLABLE SSYEG
+C3BE;C3BE;110A 1168 11A9;C3BE;110A 1168 11A9; # (쎾; 쎾; 쎾; 쎾; 쎾; ) HANGUL SYLLABLE SSYEGG
+C3BF;C3BF;110A 1168 11AA;C3BF;110A 1168 11AA; # (쎿; 쎿; 쎿; 쎿; 쎿; ) HANGUL SYLLABLE SSYEGS
+C3C0;C3C0;110A 1168 11AB;C3C0;110A 1168 11AB; # (쏀; 쏀; 쏀; 쏀; 쏀; ) HANGUL SYLLABLE SSYEN
+C3C1;C3C1;110A 1168 11AC;C3C1;110A 1168 11AC; # (쏁; 쏁; 쏁; 쏁; 쏁; ) HANGUL SYLLABLE SSYENJ
+C3C2;C3C2;110A 1168 11AD;C3C2;110A 1168 11AD; # (쏂; 쏂; 쏂; 쏂; 쏂; ) HANGUL SYLLABLE SSYENH
+C3C3;C3C3;110A 1168 11AE;C3C3;110A 1168 11AE; # (쏃; 쏃; 쏃; 쏃; 쏃; ) HANGUL SYLLABLE SSYED
+C3C4;C3C4;110A 1168 11AF;C3C4;110A 1168 11AF; # (쏄; 쏄; 쏄; 쏄; 쏄; ) HANGUL SYLLABLE SSYEL
+C3C5;C3C5;110A 1168 11B0;C3C5;110A 1168 11B0; # (쏅; 쏅; 쏅; 쏅; 쏅; ) HANGUL SYLLABLE SSYELG
+C3C6;C3C6;110A 1168 11B1;C3C6;110A 1168 11B1; # (쏆; 쏆; 쏆; 쏆; 쏆; ) HANGUL SYLLABLE SSYELM
+C3C7;C3C7;110A 1168 11B2;C3C7;110A 1168 11B2; # (쏇; 쏇; 쏇; 쏇; 쏇; ) HANGUL SYLLABLE SSYELB
+C3C8;C3C8;110A 1168 11B3;C3C8;110A 1168 11B3; # (쏈; 쏈; 쏈; 쏈; 쏈; ) HANGUL SYLLABLE SSYELS
+C3C9;C3C9;110A 1168 11B4;C3C9;110A 1168 11B4; # (쏉; 쏉; 쏉; 쏉; 쏉; ) HANGUL SYLLABLE SSYELT
+C3CA;C3CA;110A 1168 11B5;C3CA;110A 1168 11B5; # (쏊; 쏊; 쏊; 쏊; 쏊; ) HANGUL SYLLABLE SSYELP
+C3CB;C3CB;110A 1168 11B6;C3CB;110A 1168 11B6; # (쏋; 쏋; 쏋; 쏋; 쏋; ) HANGUL SYLLABLE SSYELH
+C3CC;C3CC;110A 1168 11B7;C3CC;110A 1168 11B7; # (쏌; 쏌; 쏌; 쏌; 쏌; ) HANGUL SYLLABLE SSYEM
+C3CD;C3CD;110A 1168 11B8;C3CD;110A 1168 11B8; # (쏍; 쏍; 쏍; 쏍; 쏍; ) HANGUL SYLLABLE SSYEB
+C3CE;C3CE;110A 1168 11B9;C3CE;110A 1168 11B9; # (쏎; 쏎; 쏎; 쏎; 쏎; ) HANGUL SYLLABLE SSYEBS
+C3CF;C3CF;110A 1168 11BA;C3CF;110A 1168 11BA; # (쏏; 쏏; 쏏; 쏏; 쏏; ) HANGUL SYLLABLE SSYES
+C3D0;C3D0;110A 1168 11BB;C3D0;110A 1168 11BB; # (쏐; 쏐; 쏐; 쏐; 쏐; ) HANGUL SYLLABLE SSYESS
+C3D1;C3D1;110A 1168 11BC;C3D1;110A 1168 11BC; # (쏑; 쏑; 쏑; 쏑; 쏑; ) HANGUL SYLLABLE SSYENG
+C3D2;C3D2;110A 1168 11BD;C3D2;110A 1168 11BD; # (쏒; 쏒; 쏒; 쏒; 쏒; ) HANGUL SYLLABLE SSYEJ
+C3D3;C3D3;110A 1168 11BE;C3D3;110A 1168 11BE; # (쏓; 쏓; 쏓; 쏓; 쏓; ) HANGUL SYLLABLE SSYEC
+C3D4;C3D4;110A 1168 11BF;C3D4;110A 1168 11BF; # (쏔; 쏔; 쏔; 쏔; 쏔; ) HANGUL SYLLABLE SSYEK
+C3D5;C3D5;110A 1168 11C0;C3D5;110A 1168 11C0; # (쏕; 쏕; 쏕; 쏕; 쏕; ) HANGUL SYLLABLE SSYET
+C3D6;C3D6;110A 1168 11C1;C3D6;110A 1168 11C1; # (쏖; 쏖; 쏖; 쏖; 쏖; ) HANGUL SYLLABLE SSYEP
+C3D7;C3D7;110A 1168 11C2;C3D7;110A 1168 11C2; # (쏗; 쏗; 쏗; 쏗; 쏗; ) HANGUL SYLLABLE SSYEH
+C3D8;C3D8;110A 1169;C3D8;110A 1169; # (쏘; 쏘; 쏘; 쏘; 쏘; ) HANGUL SYLLABLE SSO
+C3D9;C3D9;110A 1169 11A8;C3D9;110A 1169 11A8; # (쏙; 쏙; 쏙; 쏙; 쏙; ) HANGUL SYLLABLE SSOG
+C3DA;C3DA;110A 1169 11A9;C3DA;110A 1169 11A9; # (쏚; 쏚; 쏚; 쏚; 쏚; ) HANGUL SYLLABLE SSOGG
+C3DB;C3DB;110A 1169 11AA;C3DB;110A 1169 11AA; # (쏛; 쏛; 쏛; 쏛; 쏛; ) HANGUL SYLLABLE SSOGS
+C3DC;C3DC;110A 1169 11AB;C3DC;110A 1169 11AB; # (쏜; 쏜; 쏜; 쏜; 쏜; ) HANGUL SYLLABLE SSON
+C3DD;C3DD;110A 1169 11AC;C3DD;110A 1169 11AC; # (쏝; 쏝; 쏝; 쏝; 쏝; ) HANGUL SYLLABLE SSONJ
+C3DE;C3DE;110A 1169 11AD;C3DE;110A 1169 11AD; # (쏞; 쏞; 쏞; 쏞; 쏞; ) HANGUL SYLLABLE SSONH
+C3DF;C3DF;110A 1169 11AE;C3DF;110A 1169 11AE; # (쏟; 쏟; 쏟; 쏟; 쏟; ) HANGUL SYLLABLE SSOD
+C3E0;C3E0;110A 1169 11AF;C3E0;110A 1169 11AF; # (쏠; 쏠; 쏠; 쏠; 쏠; ) HANGUL SYLLABLE SSOL
+C3E1;C3E1;110A 1169 11B0;C3E1;110A 1169 11B0; # (쏡; 쏡; 쏡; 쏡; 쏡; ) HANGUL SYLLABLE SSOLG
+C3E2;C3E2;110A 1169 11B1;C3E2;110A 1169 11B1; # (쏢; 쏢; 쏢; 쏢; 쏢; ) HANGUL SYLLABLE SSOLM
+C3E3;C3E3;110A 1169 11B2;C3E3;110A 1169 11B2; # (쏣; 쏣; 쏣; 쏣; 쏣; ) HANGUL SYLLABLE SSOLB
+C3E4;C3E4;110A 1169 11B3;C3E4;110A 1169 11B3; # (쏤; 쏤; 쏤; 쏤; 쏤; ) HANGUL SYLLABLE SSOLS
+C3E5;C3E5;110A 1169 11B4;C3E5;110A 1169 11B4; # (쏥; 쏥; 쏥; 쏥; 쏥; ) HANGUL SYLLABLE SSOLT
+C3E6;C3E6;110A 1169 11B5;C3E6;110A 1169 11B5; # (쏦; 쏦; 쏦; 쏦; 쏦; ) HANGUL SYLLABLE SSOLP
+C3E7;C3E7;110A 1169 11B6;C3E7;110A 1169 11B6; # (쏧; 쏧; 쏧; 쏧; 쏧; ) HANGUL SYLLABLE SSOLH
+C3E8;C3E8;110A 1169 11B7;C3E8;110A 1169 11B7; # (쏨; 쏨; 쏨; 쏨; 쏨; ) HANGUL SYLLABLE SSOM
+C3E9;C3E9;110A 1169 11B8;C3E9;110A 1169 11B8; # (쏩; 쏩; 쏩; 쏩; 쏩; ) HANGUL SYLLABLE SSOB
+C3EA;C3EA;110A 1169 11B9;C3EA;110A 1169 11B9; # (쏪; 쏪; 쏪; 쏪; 쏪; ) HANGUL SYLLABLE SSOBS
+C3EB;C3EB;110A 1169 11BA;C3EB;110A 1169 11BA; # (쏫; 쏫; 쏫; 쏫; 쏫; ) HANGUL SYLLABLE SSOS
+C3EC;C3EC;110A 1169 11BB;C3EC;110A 1169 11BB; # (쏬; 쏬; 쏬; 쏬; 쏬; ) HANGUL SYLLABLE SSOSS
+C3ED;C3ED;110A 1169 11BC;C3ED;110A 1169 11BC; # (쏭; 쏭; 쏭; 쏭; 쏭; ) HANGUL SYLLABLE SSONG
+C3EE;C3EE;110A 1169 11BD;C3EE;110A 1169 11BD; # (쏮; 쏮; 쏮; 쏮; 쏮; ) HANGUL SYLLABLE SSOJ
+C3EF;C3EF;110A 1169 11BE;C3EF;110A 1169 11BE; # (쏯; 쏯; 쏯; 쏯; 쏯; ) HANGUL SYLLABLE SSOC
+C3F0;C3F0;110A 1169 11BF;C3F0;110A 1169 11BF; # (쏰; 쏰; 쏰; 쏰; 쏰; ) HANGUL SYLLABLE SSOK
+C3F1;C3F1;110A 1169 11C0;C3F1;110A 1169 11C0; # (쏱; 쏱; 쏱; 쏱; 쏱; ) HANGUL SYLLABLE SSOT
+C3F2;C3F2;110A 1169 11C1;C3F2;110A 1169 11C1; # (쏲; 쏲; 쏲; 쏲; 쏲; ) HANGUL SYLLABLE SSOP
+C3F3;C3F3;110A 1169 11C2;C3F3;110A 1169 11C2; # (쏳; 쏳; 쏳; 쏳; 쏳; ) HANGUL SYLLABLE SSOH
+C3F4;C3F4;110A 116A;C3F4;110A 116A; # (쏴; 쏴; 쏴; 쏴; 쏴; ) HANGUL SYLLABLE SSWA
+C3F5;C3F5;110A 116A 11A8;C3F5;110A 116A 11A8; # (쏵; 쏵; 쏵; 쏵; 쏵; ) HANGUL SYLLABLE SSWAG
+C3F6;C3F6;110A 116A 11A9;C3F6;110A 116A 11A9; # (쏶; 쏶; 쏶; 쏶; 쏶; ) HANGUL SYLLABLE SSWAGG
+C3F7;C3F7;110A 116A 11AA;C3F7;110A 116A 11AA; # (쏷; 쏷; 쏷; 쏷; 쏷; ) HANGUL SYLLABLE SSWAGS
+C3F8;C3F8;110A 116A 11AB;C3F8;110A 116A 11AB; # (쏸; 쏸; 쏸; 쏸; 쏸; ) HANGUL SYLLABLE SSWAN
+C3F9;C3F9;110A 116A 11AC;C3F9;110A 116A 11AC; # (쏹; 쏹; 쏹; 쏹; 쏹; ) HANGUL SYLLABLE SSWANJ
+C3FA;C3FA;110A 116A 11AD;C3FA;110A 116A 11AD; # (쏺; 쏺; 쏺; 쏺; 쏺; ) HANGUL SYLLABLE SSWANH
+C3FB;C3FB;110A 116A 11AE;C3FB;110A 116A 11AE; # (쏻; 쏻; 쏻; 쏻; 쏻; ) HANGUL SYLLABLE SSWAD
+C3FC;C3FC;110A 116A 11AF;C3FC;110A 116A 11AF; # (쏼; 쏼; 쏼; 쏼; 쏼; ) HANGUL SYLLABLE SSWAL
+C3FD;C3FD;110A 116A 11B0;C3FD;110A 116A 11B0; # (쏽; 쏽; 쏽; 쏽; 쏽; ) HANGUL SYLLABLE SSWALG
+C3FE;C3FE;110A 116A 11B1;C3FE;110A 116A 11B1; # (쏾; 쏾; 쏾; 쏾; 쏾; ) HANGUL SYLLABLE SSWALM
+C3FF;C3FF;110A 116A 11B2;C3FF;110A 116A 11B2; # (쏿; 쏿; 쏿; 쏿; 쏿; ) HANGUL SYLLABLE SSWALB
+C400;C400;110A 116A 11B3;C400;110A 116A 11B3; # (쐀; 쐀; 쐀; 쐀; 쐀; ) HANGUL SYLLABLE SSWALS
+C401;C401;110A 116A 11B4;C401;110A 116A 11B4; # (쐁; 쐁; 쐁; 쐁; 쐁; ) HANGUL SYLLABLE SSWALT
+C402;C402;110A 116A 11B5;C402;110A 116A 11B5; # (쐂; 쐂; 쐂; 쐂; 쐂; ) HANGUL SYLLABLE SSWALP
+C403;C403;110A 116A 11B6;C403;110A 116A 11B6; # (쐃; 쐃; 쐃; 쐃; 쐃; ) HANGUL SYLLABLE SSWALH
+C404;C404;110A 116A 11B7;C404;110A 116A 11B7; # (쐄; 쐄; 쐄; 쐄; 쐄; ) HANGUL SYLLABLE SSWAM
+C405;C405;110A 116A 11B8;C405;110A 116A 11B8; # (쐅; 쐅; 쐅; 쐅; 쐅; ) HANGUL SYLLABLE SSWAB
+C406;C406;110A 116A 11B9;C406;110A 116A 11B9; # (쐆; 쐆; 쐆; 쐆; 쐆; ) HANGUL SYLLABLE SSWABS
+C407;C407;110A 116A 11BA;C407;110A 116A 11BA; # (쐇; 쐇; 쐇; 쐇; 쐇; ) HANGUL SYLLABLE SSWAS
+C408;C408;110A 116A 11BB;C408;110A 116A 11BB; # (쐈; 쐈; 쐈; 쐈; 쐈; ) HANGUL SYLLABLE SSWASS
+C409;C409;110A 116A 11BC;C409;110A 116A 11BC; # (쐉; 쐉; 쐉; 쐉; 쐉; ) HANGUL SYLLABLE SSWANG
+C40A;C40A;110A 116A 11BD;C40A;110A 116A 11BD; # (쐊; 쐊; 쐊; 쐊; 쐊; ) HANGUL SYLLABLE SSWAJ
+C40B;C40B;110A 116A 11BE;C40B;110A 116A 11BE; # (쐋; 쐋; 쐋; 쐋; 쐋; ) HANGUL SYLLABLE SSWAC
+C40C;C40C;110A 116A 11BF;C40C;110A 116A 11BF; # (쐌; 쐌; 쐌; 쐌; 쐌; ) HANGUL SYLLABLE SSWAK
+C40D;C40D;110A 116A 11C0;C40D;110A 116A 11C0; # (쐍; 쐍; 쐍; 쐍; 쐍; ) HANGUL SYLLABLE SSWAT
+C40E;C40E;110A 116A 11C1;C40E;110A 116A 11C1; # (쐎; 쐎; 쐎; 쐎; 쐎; ) HANGUL SYLLABLE SSWAP
+C40F;C40F;110A 116A 11C2;C40F;110A 116A 11C2; # (쐏; 쐏; 쐏; 쐏; 쐏; ) HANGUL SYLLABLE SSWAH
+C410;C410;110A 116B;C410;110A 116B; # (쐐; 쐐; 쐐; 쐐; 쐐; ) HANGUL SYLLABLE SSWAE
+C411;C411;110A 116B 11A8;C411;110A 116B 11A8; # (쐑; 쐑; 쐑; 쐑; 쐑; ) HANGUL SYLLABLE SSWAEG
+C412;C412;110A 116B 11A9;C412;110A 116B 11A9; # (쐒; 쐒; 쐒; 쐒; 쐒; ) HANGUL SYLLABLE SSWAEGG
+C413;C413;110A 116B 11AA;C413;110A 116B 11AA; # (쐓; 쐓; 쐓; 쐓; 쐓; ) HANGUL SYLLABLE SSWAEGS
+C414;C414;110A 116B 11AB;C414;110A 116B 11AB; # (쐔; 쐔; 쐔; 쐔; 쐔; ) HANGUL SYLLABLE SSWAEN
+C415;C415;110A 116B 11AC;C415;110A 116B 11AC; # (쐕; 쐕; 쐕; 쐕; 쐕; ) HANGUL SYLLABLE SSWAENJ
+C416;C416;110A 116B 11AD;C416;110A 116B 11AD; # (쐖; 쐖; 쐖; 쐖; 쐖; ) HANGUL SYLLABLE SSWAENH
+C417;C417;110A 116B 11AE;C417;110A 116B 11AE; # (쐗; 쐗; 쐗; 쐗; 쐗; ) HANGUL SYLLABLE SSWAED
+C418;C418;110A 116B 11AF;C418;110A 116B 11AF; # (쐘; 쐘; 쐘; 쐘; 쐘; ) HANGUL SYLLABLE SSWAEL
+C419;C419;110A 116B 11B0;C419;110A 116B 11B0; # (쐙; 쐙; 쐙; 쐙; 쐙; ) HANGUL SYLLABLE SSWAELG
+C41A;C41A;110A 116B 11B1;C41A;110A 116B 11B1; # (쐚; 쐚; 쐚; 쐚; 쐚; ) HANGUL SYLLABLE SSWAELM
+C41B;C41B;110A 116B 11B2;C41B;110A 116B 11B2; # (쐛; 쐛; 쐛; 쐛; 쐛; ) HANGUL SYLLABLE SSWAELB
+C41C;C41C;110A 116B 11B3;C41C;110A 116B 11B3; # (쐜; 쐜; 쐜; 쐜; 쐜; ) HANGUL SYLLABLE SSWAELS
+C41D;C41D;110A 116B 11B4;C41D;110A 116B 11B4; # (쐝; 쐝; 쐝; 쐝; 쐝; ) HANGUL SYLLABLE SSWAELT
+C41E;C41E;110A 116B 11B5;C41E;110A 116B 11B5; # (쐞; 쐞; 쐞; 쐞; 쐞; ) HANGUL SYLLABLE SSWAELP
+C41F;C41F;110A 116B 11B6;C41F;110A 116B 11B6; # (쐟; 쐟; 쐟; 쐟; 쐟; ) HANGUL SYLLABLE SSWAELH
+C420;C420;110A 116B 11B7;C420;110A 116B 11B7; # (쐠; 쐠; 쐠; 쐠; 쐠; ) HANGUL SYLLABLE SSWAEM
+C421;C421;110A 116B 11B8;C421;110A 116B 11B8; # (쐡; 쐡; 쐡; 쐡; 쐡; ) HANGUL SYLLABLE SSWAEB
+C422;C422;110A 116B 11B9;C422;110A 116B 11B9; # (쐢; 쐢; 쐢; 쐢; 쐢; ) HANGUL SYLLABLE SSWAEBS
+C423;C423;110A 116B 11BA;C423;110A 116B 11BA; # (쐣; 쐣; 쐣; 쐣; 쐣; ) HANGUL SYLLABLE SSWAES
+C424;C424;110A 116B 11BB;C424;110A 116B 11BB; # (쐤; 쐤; 쐤; 쐤; 쐤; ) HANGUL SYLLABLE SSWAESS
+C425;C425;110A 116B 11BC;C425;110A 116B 11BC; # (쐥; 쐥; 쐥; 쐥; 쐥; ) HANGUL SYLLABLE SSWAENG
+C426;C426;110A 116B 11BD;C426;110A 116B 11BD; # (쐦; 쐦; 쐦; 쐦; 쐦; ) HANGUL SYLLABLE SSWAEJ
+C427;C427;110A 116B 11BE;C427;110A 116B 11BE; # (쐧; 쐧; 쐧; 쐧; 쐧; ) HANGUL SYLLABLE SSWAEC
+C428;C428;110A 116B 11BF;C428;110A 116B 11BF; # (쐨; 쐨; 쐨; 쐨; 쐨; ) HANGUL SYLLABLE SSWAEK
+C429;C429;110A 116B 11C0;C429;110A 116B 11C0; # (쐩; 쐩; 쐩; 쐩; 쐩; ) HANGUL SYLLABLE SSWAET
+C42A;C42A;110A 116B 11C1;C42A;110A 116B 11C1; # (쐪; 쐪; 쐪; 쐪; 쐪; ) HANGUL SYLLABLE SSWAEP
+C42B;C42B;110A 116B 11C2;C42B;110A 116B 11C2; # (쐫; 쐫; 쐫; 쐫; 쐫; ) HANGUL SYLLABLE SSWAEH
+C42C;C42C;110A 116C;C42C;110A 116C; # (쐬; 쐬; 쐬; 쐬; 쐬; ) HANGUL SYLLABLE SSOE
+C42D;C42D;110A 116C 11A8;C42D;110A 116C 11A8; # (쐭; 쐭; 쐭; 쐭; 쐭; ) HANGUL SYLLABLE SSOEG
+C42E;C42E;110A 116C 11A9;C42E;110A 116C 11A9; # (쐮; 쐮; 쐮; 쐮; 쐮; ) HANGUL SYLLABLE SSOEGG
+C42F;C42F;110A 116C 11AA;C42F;110A 116C 11AA; # (쐯; 쐯; 쐯; 쐯; 쐯; ) HANGUL SYLLABLE SSOEGS
+C430;C430;110A 116C 11AB;C430;110A 116C 11AB; # (쐰; 쐰; 쐰; 쐰; 쐰; ) HANGUL SYLLABLE SSOEN
+C431;C431;110A 116C 11AC;C431;110A 116C 11AC; # (쐱; 쐱; 쐱; 쐱; 쐱; ) HANGUL SYLLABLE SSOENJ
+C432;C432;110A 116C 11AD;C432;110A 116C 11AD; # (쐲; 쐲; 쐲; 쐲; 쐲; ) HANGUL SYLLABLE SSOENH
+C433;C433;110A 116C 11AE;C433;110A 116C 11AE; # (쐳; 쐳; 쐳; 쐳; 쐳; ) HANGUL SYLLABLE SSOED
+C434;C434;110A 116C 11AF;C434;110A 116C 11AF; # (쐴; 쐴; 쐴; 쐴; 쐴; ) HANGUL SYLLABLE SSOEL
+C435;C435;110A 116C 11B0;C435;110A 116C 11B0; # (쐵; 쐵; 쐵; 쐵; 쐵; ) HANGUL SYLLABLE SSOELG
+C436;C436;110A 116C 11B1;C436;110A 116C 11B1; # (쐶; 쐶; 쐶; 쐶; 쐶; ) HANGUL SYLLABLE SSOELM
+C437;C437;110A 116C 11B2;C437;110A 116C 11B2; # (쐷; 쐷; 쐷; 쐷; 쐷; ) HANGUL SYLLABLE SSOELB
+C438;C438;110A 116C 11B3;C438;110A 116C 11B3; # (쐸; 쐸; 쐸; 쐸; 쐸; ) HANGUL SYLLABLE SSOELS
+C439;C439;110A 116C 11B4;C439;110A 116C 11B4; # (쐹; 쐹; 쐹; 쐹; 쐹; ) HANGUL SYLLABLE SSOELT
+C43A;C43A;110A 116C 11B5;C43A;110A 116C 11B5; # (쐺; 쐺; 쐺; 쐺; 쐺; ) HANGUL SYLLABLE SSOELP
+C43B;C43B;110A 116C 11B6;C43B;110A 116C 11B6; # (쐻; 쐻; 쐻; 쐻; 쐻; ) HANGUL SYLLABLE SSOELH
+C43C;C43C;110A 116C 11B7;C43C;110A 116C 11B7; # (쐼; 쐼; 쐼; 쐼; 쐼; ) HANGUL SYLLABLE SSOEM
+C43D;C43D;110A 116C 11B8;C43D;110A 116C 11B8; # (쐽; 쐽; 쐽; 쐽; 쐽; ) HANGUL SYLLABLE SSOEB
+C43E;C43E;110A 116C 11B9;C43E;110A 116C 11B9; # (쐾; 쐾; 쐾; 쐾; 쐾; ) HANGUL SYLLABLE SSOEBS
+C43F;C43F;110A 116C 11BA;C43F;110A 116C 11BA; # (쐿; 쐿; 쐿; 쐿; 쐿; ) HANGUL SYLLABLE SSOES
+C440;C440;110A 116C 11BB;C440;110A 116C 11BB; # (쑀; 쑀; 쑀; 쑀; 쑀; ) HANGUL SYLLABLE SSOESS
+C441;C441;110A 116C 11BC;C441;110A 116C 11BC; # (쑁; 쑁; 쑁; 쑁; 쑁; ) HANGUL SYLLABLE SSOENG
+C442;C442;110A 116C 11BD;C442;110A 116C 11BD; # (쑂; 쑂; 쑂; 쑂; 쑂; ) HANGUL SYLLABLE SSOEJ
+C443;C443;110A 116C 11BE;C443;110A 116C 11BE; # (쑃; 쑃; 쑃; 쑃; 쑃; ) HANGUL SYLLABLE SSOEC
+C444;C444;110A 116C 11BF;C444;110A 116C 11BF; # (쑄; 쑄; 쑄; 쑄; 쑄; ) HANGUL SYLLABLE SSOEK
+C445;C445;110A 116C 11C0;C445;110A 116C 11C0; # (쑅; 쑅; 쑅; 쑅; 쑅; ) HANGUL SYLLABLE SSOET
+C446;C446;110A 116C 11C1;C446;110A 116C 11C1; # (쑆; 쑆; 쑆; 쑆; 쑆; ) HANGUL SYLLABLE SSOEP
+C447;C447;110A 116C 11C2;C447;110A 116C 11C2; # (쑇; 쑇; 쑇; 쑇; 쑇; ) HANGUL SYLLABLE SSOEH
+C448;C448;110A 116D;C448;110A 116D; # (쑈; 쑈; 쑈; 쑈; 쑈; ) HANGUL SYLLABLE SSYO
+C449;C449;110A 116D 11A8;C449;110A 116D 11A8; # (쑉; 쑉; 쑉; 쑉; 쑉; ) HANGUL SYLLABLE SSYOG
+C44A;C44A;110A 116D 11A9;C44A;110A 116D 11A9; # (쑊; 쑊; 쑊; 쑊; 쑊; ) HANGUL SYLLABLE SSYOGG
+C44B;C44B;110A 116D 11AA;C44B;110A 116D 11AA; # (쑋; 쑋; 쑋; 쑋; 쑋; ) HANGUL SYLLABLE SSYOGS
+C44C;C44C;110A 116D 11AB;C44C;110A 116D 11AB; # (쑌; 쑌; 쑌; 쑌; 쑌; ) HANGUL SYLLABLE SSYON
+C44D;C44D;110A 116D 11AC;C44D;110A 116D 11AC; # (쑍; 쑍; 쑍; 쑍; 쑍; ) HANGUL SYLLABLE SSYONJ
+C44E;C44E;110A 116D 11AD;C44E;110A 116D 11AD; # (쑎; 쑎; 쑎; 쑎; 쑎; ) HANGUL SYLLABLE SSYONH
+C44F;C44F;110A 116D 11AE;C44F;110A 116D 11AE; # (쑏; 쑏; 쑏; 쑏; 쑏; ) HANGUL SYLLABLE SSYOD
+C450;C450;110A 116D 11AF;C450;110A 116D 11AF; # (쑐; 쑐; 쑐; 쑐; 쑐; ) HANGUL SYLLABLE SSYOL
+C451;C451;110A 116D 11B0;C451;110A 116D 11B0; # (쑑; 쑑; 쑑; 쑑; 쑑; ) HANGUL SYLLABLE SSYOLG
+C452;C452;110A 116D 11B1;C452;110A 116D 11B1; # (쑒; 쑒; 쑒; 쑒; 쑒; ) HANGUL SYLLABLE SSYOLM
+C453;C453;110A 116D 11B2;C453;110A 116D 11B2; # (쑓; 쑓; 쑓; 쑓; 쑓; ) HANGUL SYLLABLE SSYOLB
+C454;C454;110A 116D 11B3;C454;110A 116D 11B3; # (쑔; 쑔; 쑔; 쑔; 쑔; ) HANGUL SYLLABLE SSYOLS
+C455;C455;110A 116D 11B4;C455;110A 116D 11B4; # (쑕; 쑕; 쑕; 쑕; 쑕; ) HANGUL SYLLABLE SSYOLT
+C456;C456;110A 116D 11B5;C456;110A 116D 11B5; # (쑖; 쑖; 쑖; 쑖; 쑖; ) HANGUL SYLLABLE SSYOLP
+C457;C457;110A 116D 11B6;C457;110A 116D 11B6; # (쑗; 쑗; 쑗; 쑗; 쑗; ) HANGUL SYLLABLE SSYOLH
+C458;C458;110A 116D 11B7;C458;110A 116D 11B7; # (쑘; 쑘; 쑘; 쑘; 쑘; ) HANGUL SYLLABLE SSYOM
+C459;C459;110A 116D 11B8;C459;110A 116D 11B8; # (쑙; 쑙; 쑙; 쑙; 쑙; ) HANGUL SYLLABLE SSYOB
+C45A;C45A;110A 116D 11B9;C45A;110A 116D 11B9; # (쑚; 쑚; 쑚; 쑚; 쑚; ) HANGUL SYLLABLE SSYOBS
+C45B;C45B;110A 116D 11BA;C45B;110A 116D 11BA; # (쑛; 쑛; 쑛; 쑛; 쑛; ) HANGUL SYLLABLE SSYOS
+C45C;C45C;110A 116D 11BB;C45C;110A 116D 11BB; # (쑜; 쑜; 쑜; 쑜; 쑜; ) HANGUL SYLLABLE SSYOSS
+C45D;C45D;110A 116D 11BC;C45D;110A 116D 11BC; # (쑝; 쑝; 쑝; 쑝; 쑝; ) HANGUL SYLLABLE SSYONG
+C45E;C45E;110A 116D 11BD;C45E;110A 116D 11BD; # (쑞; 쑞; 쑞; 쑞; 쑞; ) HANGUL SYLLABLE SSYOJ
+C45F;C45F;110A 116D 11BE;C45F;110A 116D 11BE; # (쑟; 쑟; 쑟; 쑟; 쑟; ) HANGUL SYLLABLE SSYOC
+C460;C460;110A 116D 11BF;C460;110A 116D 11BF; # (쑠; 쑠; 쑠; 쑠; 쑠; ) HANGUL SYLLABLE SSYOK
+C461;C461;110A 116D 11C0;C461;110A 116D 11C0; # (쑡; 쑡; 쑡; 쑡; 쑡; ) HANGUL SYLLABLE SSYOT
+C462;C462;110A 116D 11C1;C462;110A 116D 11C1; # (쑢; 쑢; 쑢; 쑢; 쑢; ) HANGUL SYLLABLE SSYOP
+C463;C463;110A 116D 11C2;C463;110A 116D 11C2; # (쑣; 쑣; 쑣; 쑣; 쑣; ) HANGUL SYLLABLE SSYOH
+C464;C464;110A 116E;C464;110A 116E; # (쑤; 쑤; 쑤; 쑤; 쑤; ) HANGUL SYLLABLE SSU
+C465;C465;110A 116E 11A8;C465;110A 116E 11A8; # (쑥; 쑥; 쑥; 쑥; 쑥; ) HANGUL SYLLABLE SSUG
+C466;C466;110A 116E 11A9;C466;110A 116E 11A9; # (쑦; 쑦; 쑦; 쑦; 쑦; ) HANGUL SYLLABLE SSUGG
+C467;C467;110A 116E 11AA;C467;110A 116E 11AA; # (쑧; 쑧; 쑧; 쑧; 쑧; ) HANGUL SYLLABLE SSUGS
+C468;C468;110A 116E 11AB;C468;110A 116E 11AB; # (쑨; 쑨; 쑨; 쑨; 쑨; ) HANGUL SYLLABLE SSUN
+C469;C469;110A 116E 11AC;C469;110A 116E 11AC; # (쑩; 쑩; 쑩; 쑩; 쑩; ) HANGUL SYLLABLE SSUNJ
+C46A;C46A;110A 116E 11AD;C46A;110A 116E 11AD; # (쑪; 쑪; 쑪; 쑪; 쑪; ) HANGUL SYLLABLE SSUNH
+C46B;C46B;110A 116E 11AE;C46B;110A 116E 11AE; # (쑫; 쑫; 쑫; 쑫; 쑫; ) HANGUL SYLLABLE SSUD
+C46C;C46C;110A 116E 11AF;C46C;110A 116E 11AF; # (쑬; 쑬; 쑬; 쑬; 쑬; ) HANGUL SYLLABLE SSUL
+C46D;C46D;110A 116E 11B0;C46D;110A 116E 11B0; # (쑭; 쑭; 쑭; 쑭; 쑭; ) HANGUL SYLLABLE SSULG
+C46E;C46E;110A 116E 11B1;C46E;110A 116E 11B1; # (쑮; 쑮; 쑮; 쑮; 쑮; ) HANGUL SYLLABLE SSULM
+C46F;C46F;110A 116E 11B2;C46F;110A 116E 11B2; # (쑯; 쑯; 쑯; 쑯; 쑯; ) HANGUL SYLLABLE SSULB
+C470;C470;110A 116E 11B3;C470;110A 116E 11B3; # (쑰; 쑰; 쑰; 쑰; 쑰; ) HANGUL SYLLABLE SSULS
+C471;C471;110A 116E 11B4;C471;110A 116E 11B4; # (쑱; 쑱; 쑱; 쑱; 쑱; ) HANGUL SYLLABLE SSULT
+C472;C472;110A 116E 11B5;C472;110A 116E 11B5; # (쑲; 쑲; 쑲; 쑲; 쑲; ) HANGUL SYLLABLE SSULP
+C473;C473;110A 116E 11B6;C473;110A 116E 11B6; # (쑳; 쑳; 쑳; 쑳; 쑳; ) HANGUL SYLLABLE SSULH
+C474;C474;110A 116E 11B7;C474;110A 116E 11B7; # (쑴; 쑴; 쑴; 쑴; 쑴; ) HANGUL SYLLABLE SSUM
+C475;C475;110A 116E 11B8;C475;110A 116E 11B8; # (쑵; 쑵; 쑵; 쑵; 쑵; ) HANGUL SYLLABLE SSUB
+C476;C476;110A 116E 11B9;C476;110A 116E 11B9; # (쑶; 쑶; 쑶; 쑶; 쑶; ) HANGUL SYLLABLE SSUBS
+C477;C477;110A 116E 11BA;C477;110A 116E 11BA; # (쑷; 쑷; 쑷; 쑷; 쑷; ) HANGUL SYLLABLE SSUS
+C478;C478;110A 116E 11BB;C478;110A 116E 11BB; # (쑸; 쑸; 쑸; 쑸; 쑸; ) HANGUL SYLLABLE SSUSS
+C479;C479;110A 116E 11BC;C479;110A 116E 11BC; # (쑹; 쑹; 쑹; 쑹; 쑹; ) HANGUL SYLLABLE SSUNG
+C47A;C47A;110A 116E 11BD;C47A;110A 116E 11BD; # (쑺; 쑺; 쑺; 쑺; 쑺; ) HANGUL SYLLABLE SSUJ
+C47B;C47B;110A 116E 11BE;C47B;110A 116E 11BE; # (쑻; 쑻; 쑻; 쑻; 쑻; ) HANGUL SYLLABLE SSUC
+C47C;C47C;110A 116E 11BF;C47C;110A 116E 11BF; # (쑼; 쑼; 쑼; 쑼; 쑼; ) HANGUL SYLLABLE SSUK
+C47D;C47D;110A 116E 11C0;C47D;110A 116E 11C0; # (쑽; 쑽; 쑽; 쑽; 쑽; ) HANGUL SYLLABLE SSUT
+C47E;C47E;110A 116E 11C1;C47E;110A 116E 11C1; # (쑾; 쑾; 쑾; 쑾; 쑾; ) HANGUL SYLLABLE SSUP
+C47F;C47F;110A 116E 11C2;C47F;110A 116E 11C2; # (쑿; 쑿; 쑿; 쑿; 쑿; ) HANGUL SYLLABLE SSUH
+C480;C480;110A 116F;C480;110A 116F; # (쒀; 쒀; 쒀; 쒀; 쒀; ) HANGUL SYLLABLE SSWEO
+C481;C481;110A 116F 11A8;C481;110A 116F 11A8; # (쒁; 쒁; 쒁; 쒁; 쒁; ) HANGUL SYLLABLE SSWEOG
+C482;C482;110A 116F 11A9;C482;110A 116F 11A9; # (쒂; 쒂; 쒂; 쒂; 쒂; ) HANGUL SYLLABLE SSWEOGG
+C483;C483;110A 116F 11AA;C483;110A 116F 11AA; # (쒃; 쒃; 쒃; 쒃; 쒃; ) HANGUL SYLLABLE SSWEOGS
+C484;C484;110A 116F 11AB;C484;110A 116F 11AB; # (쒄; 쒄; 쒄; 쒄; 쒄; ) HANGUL SYLLABLE SSWEON
+C485;C485;110A 116F 11AC;C485;110A 116F 11AC; # (쒅; 쒅; 쒅; 쒅; 쒅; ) HANGUL SYLLABLE SSWEONJ
+C486;C486;110A 116F 11AD;C486;110A 116F 11AD; # (쒆; 쒆; 쒆; 쒆; 쒆; ) HANGUL SYLLABLE SSWEONH
+C487;C487;110A 116F 11AE;C487;110A 116F 11AE; # (쒇; 쒇; 쒇; 쒇; 쒇; ) HANGUL SYLLABLE SSWEOD
+C488;C488;110A 116F 11AF;C488;110A 116F 11AF; # (쒈; 쒈; 쒈; 쒈; 쒈; ) HANGUL SYLLABLE SSWEOL
+C489;C489;110A 116F 11B0;C489;110A 116F 11B0; # (쒉; 쒉; 쒉; 쒉; 쒉; ) HANGUL SYLLABLE SSWEOLG
+C48A;C48A;110A 116F 11B1;C48A;110A 116F 11B1; # (쒊; 쒊; 쒊; 쒊; 쒊; ) HANGUL SYLLABLE SSWEOLM
+C48B;C48B;110A 116F 11B2;C48B;110A 116F 11B2; # (쒋; 쒋; 쒋; 쒋; 쒋; ) HANGUL SYLLABLE SSWEOLB
+C48C;C48C;110A 116F 11B3;C48C;110A 116F 11B3; # (쒌; 쒌; 쒌; 쒌; 쒌; ) HANGUL SYLLABLE SSWEOLS
+C48D;C48D;110A 116F 11B4;C48D;110A 116F 11B4; # (쒍; 쒍; 쒍; 쒍; 쒍; ) HANGUL SYLLABLE SSWEOLT
+C48E;C48E;110A 116F 11B5;C48E;110A 116F 11B5; # (쒎; 쒎; 쒎; 쒎; 쒎; ) HANGUL SYLLABLE SSWEOLP
+C48F;C48F;110A 116F 11B6;C48F;110A 116F 11B6; # (쒏; 쒏; 쒏; 쒏; 쒏; ) HANGUL SYLLABLE SSWEOLH
+C490;C490;110A 116F 11B7;C490;110A 116F 11B7; # (쒐; 쒐; 쒐; 쒐; 쒐; ) HANGUL SYLLABLE SSWEOM
+C491;C491;110A 116F 11B8;C491;110A 116F 11B8; # (쒑; 쒑; 쒑; 쒑; 쒑; ) HANGUL SYLLABLE SSWEOB
+C492;C492;110A 116F 11B9;C492;110A 116F 11B9; # (쒒; 쒒; 쒒; 쒒; 쒒; ) HANGUL SYLLABLE SSWEOBS
+C493;C493;110A 116F 11BA;C493;110A 116F 11BA; # (쒓; 쒓; 쒓; 쒓; 쒓; ) HANGUL SYLLABLE SSWEOS
+C494;C494;110A 116F 11BB;C494;110A 116F 11BB; # (쒔; 쒔; 쒔; 쒔; 쒔; ) HANGUL SYLLABLE SSWEOSS
+C495;C495;110A 116F 11BC;C495;110A 116F 11BC; # (쒕; 쒕; 쒕; 쒕; 쒕; ) HANGUL SYLLABLE SSWEONG
+C496;C496;110A 116F 11BD;C496;110A 116F 11BD; # (쒖; 쒖; 쒖; 쒖; 쒖; ) HANGUL SYLLABLE SSWEOJ
+C497;C497;110A 116F 11BE;C497;110A 116F 11BE; # (쒗; 쒗; 쒗; 쒗; 쒗; ) HANGUL SYLLABLE SSWEOC
+C498;C498;110A 116F 11BF;C498;110A 116F 11BF; # (쒘; 쒘; 쒘; 쒘; 쒘; ) HANGUL SYLLABLE SSWEOK
+C499;C499;110A 116F 11C0;C499;110A 116F 11C0; # (쒙; 쒙; 쒙; 쒙; 쒙; ) HANGUL SYLLABLE SSWEOT
+C49A;C49A;110A 116F 11C1;C49A;110A 116F 11C1; # (쒚; 쒚; 쒚; 쒚; 쒚; ) HANGUL SYLLABLE SSWEOP
+C49B;C49B;110A 116F 11C2;C49B;110A 116F 11C2; # (쒛; 쒛; 쒛; 쒛; 쒛; ) HANGUL SYLLABLE SSWEOH
+C49C;C49C;110A 1170;C49C;110A 1170; # (쒜; 쒜; 쒜; 쒜; 쒜; ) HANGUL SYLLABLE SSWE
+C49D;C49D;110A 1170 11A8;C49D;110A 1170 11A8; # (쒝; 쒝; 쒝; 쒝; 쒝; ) HANGUL SYLLABLE SSWEG
+C49E;C49E;110A 1170 11A9;C49E;110A 1170 11A9; # (쒞; 쒞; 쒞; 쒞; 쒞; ) HANGUL SYLLABLE SSWEGG
+C49F;C49F;110A 1170 11AA;C49F;110A 1170 11AA; # (쒟; 쒟; 쒟; 쒟; 쒟; ) HANGUL SYLLABLE SSWEGS
+C4A0;C4A0;110A 1170 11AB;C4A0;110A 1170 11AB; # (쒠; 쒠; 쒠; 쒠; 쒠; ) HANGUL SYLLABLE SSWEN
+C4A1;C4A1;110A 1170 11AC;C4A1;110A 1170 11AC; # (쒡; 쒡; 쒡; 쒡; 쒡; ) HANGUL SYLLABLE SSWENJ
+C4A2;C4A2;110A 1170 11AD;C4A2;110A 1170 11AD; # (쒢; 쒢; 쒢; 쒢; 쒢; ) HANGUL SYLLABLE SSWENH
+C4A3;C4A3;110A 1170 11AE;C4A3;110A 1170 11AE; # (쒣; 쒣; 쒣; 쒣; 쒣; ) HANGUL SYLLABLE SSWED
+C4A4;C4A4;110A 1170 11AF;C4A4;110A 1170 11AF; # (쒤; 쒤; 쒤; 쒤; 쒤; ) HANGUL SYLLABLE SSWEL
+C4A5;C4A5;110A 1170 11B0;C4A5;110A 1170 11B0; # (쒥; 쒥; 쒥; 쒥; 쒥; ) HANGUL SYLLABLE SSWELG
+C4A6;C4A6;110A 1170 11B1;C4A6;110A 1170 11B1; # (쒦; 쒦; 쒦; 쒦; 쒦; ) HANGUL SYLLABLE SSWELM
+C4A7;C4A7;110A 1170 11B2;C4A7;110A 1170 11B2; # (쒧; 쒧; 쒧; 쒧; 쒧; ) HANGUL SYLLABLE SSWELB
+C4A8;C4A8;110A 1170 11B3;C4A8;110A 1170 11B3; # (쒨; 쒨; 쒨; 쒨; 쒨; ) HANGUL SYLLABLE SSWELS
+C4A9;C4A9;110A 1170 11B4;C4A9;110A 1170 11B4; # (쒩; 쒩; 쒩; 쒩; 쒩; ) HANGUL SYLLABLE SSWELT
+C4AA;C4AA;110A 1170 11B5;C4AA;110A 1170 11B5; # (쒪; 쒪; 쒪; 쒪; 쒪; ) HANGUL SYLLABLE SSWELP
+C4AB;C4AB;110A 1170 11B6;C4AB;110A 1170 11B6; # (쒫; 쒫; 쒫; 쒫; 쒫; ) HANGUL SYLLABLE SSWELH
+C4AC;C4AC;110A 1170 11B7;C4AC;110A 1170 11B7; # (쒬; 쒬; 쒬; 쒬; 쒬; ) HANGUL SYLLABLE SSWEM
+C4AD;C4AD;110A 1170 11B8;C4AD;110A 1170 11B8; # (쒭; 쒭; 쒭; 쒭; 쒭; ) HANGUL SYLLABLE SSWEB
+C4AE;C4AE;110A 1170 11B9;C4AE;110A 1170 11B9; # (쒮; 쒮; 쒮; 쒮; 쒮; ) HANGUL SYLLABLE SSWEBS
+C4AF;C4AF;110A 1170 11BA;C4AF;110A 1170 11BA; # (쒯; 쒯; 쒯; 쒯; 쒯; ) HANGUL SYLLABLE SSWES
+C4B0;C4B0;110A 1170 11BB;C4B0;110A 1170 11BB; # (쒰; 쒰; 쒰; 쒰; 쒰; ) HANGUL SYLLABLE SSWESS
+C4B1;C4B1;110A 1170 11BC;C4B1;110A 1170 11BC; # (쒱; 쒱; 쒱; 쒱; 쒱; ) HANGUL SYLLABLE SSWENG
+C4B2;C4B2;110A 1170 11BD;C4B2;110A 1170 11BD; # (쒲; 쒲; 쒲; 쒲; 쒲; ) HANGUL SYLLABLE SSWEJ
+C4B3;C4B3;110A 1170 11BE;C4B3;110A 1170 11BE; # (쒳; 쒳; 쒳; 쒳; 쒳; ) HANGUL SYLLABLE SSWEC
+C4B4;C4B4;110A 1170 11BF;C4B4;110A 1170 11BF; # (쒴; 쒴; 쒴; 쒴; 쒴; ) HANGUL SYLLABLE SSWEK
+C4B5;C4B5;110A 1170 11C0;C4B5;110A 1170 11C0; # (쒵; 쒵; 쒵; 쒵; 쒵; ) HANGUL SYLLABLE SSWET
+C4B6;C4B6;110A 1170 11C1;C4B6;110A 1170 11C1; # (쒶; 쒶; 쒶; 쒶; 쒶; ) HANGUL SYLLABLE SSWEP
+C4B7;C4B7;110A 1170 11C2;C4B7;110A 1170 11C2; # (쒷; 쒷; 쒷; 쒷; 쒷; ) HANGUL SYLLABLE SSWEH
+C4B8;C4B8;110A 1171;C4B8;110A 1171; # (쒸; 쒸; 쒸; 쒸; 쒸; ) HANGUL SYLLABLE SSWI
+C4B9;C4B9;110A 1171 11A8;C4B9;110A 1171 11A8; # (쒹; 쒹; 쒹; 쒹; 쒹; ) HANGUL SYLLABLE SSWIG
+C4BA;C4BA;110A 1171 11A9;C4BA;110A 1171 11A9; # (쒺; 쒺; 쒺; 쒺; 쒺; ) HANGUL SYLLABLE SSWIGG
+C4BB;C4BB;110A 1171 11AA;C4BB;110A 1171 11AA; # (쒻; 쒻; 쒻; 쒻; 쒻; ) HANGUL SYLLABLE SSWIGS
+C4BC;C4BC;110A 1171 11AB;C4BC;110A 1171 11AB; # (쒼; 쒼; 쒼; 쒼; 쒼; ) HANGUL SYLLABLE SSWIN
+C4BD;C4BD;110A 1171 11AC;C4BD;110A 1171 11AC; # (쒽; 쒽; 쒽; 쒽; 쒽; ) HANGUL SYLLABLE SSWINJ
+C4BE;C4BE;110A 1171 11AD;C4BE;110A 1171 11AD; # (쒾; 쒾; 쒾; 쒾; 쒾; ) HANGUL SYLLABLE SSWINH
+C4BF;C4BF;110A 1171 11AE;C4BF;110A 1171 11AE; # (쒿; 쒿; 쒿; 쒿; 쒿; ) HANGUL SYLLABLE SSWID
+C4C0;C4C0;110A 1171 11AF;C4C0;110A 1171 11AF; # (쓀; 쓀; 쓀; 쓀; 쓀; ) HANGUL SYLLABLE SSWIL
+C4C1;C4C1;110A 1171 11B0;C4C1;110A 1171 11B0; # (쓁; 쓁; 쓁; 쓁; 쓁; ) HANGUL SYLLABLE SSWILG
+C4C2;C4C2;110A 1171 11B1;C4C2;110A 1171 11B1; # (쓂; 쓂; 쓂; 쓂; 쓂; ) HANGUL SYLLABLE SSWILM
+C4C3;C4C3;110A 1171 11B2;C4C3;110A 1171 11B2; # (쓃; 쓃; 쓃; 쓃; 쓃; ) HANGUL SYLLABLE SSWILB
+C4C4;C4C4;110A 1171 11B3;C4C4;110A 1171 11B3; # (쓄; 쓄; 쓄; 쓄; 쓄; ) HANGUL SYLLABLE SSWILS
+C4C5;C4C5;110A 1171 11B4;C4C5;110A 1171 11B4; # (쓅; 쓅; 쓅; 쓅; 쓅; ) HANGUL SYLLABLE SSWILT
+C4C6;C4C6;110A 1171 11B5;C4C6;110A 1171 11B5; # (쓆; 쓆; 쓆; 쓆; 쓆; ) HANGUL SYLLABLE SSWILP
+C4C7;C4C7;110A 1171 11B6;C4C7;110A 1171 11B6; # (쓇; 쓇; 쓇; 쓇; 쓇; ) HANGUL SYLLABLE SSWILH
+C4C8;C4C8;110A 1171 11B7;C4C8;110A 1171 11B7; # (쓈; 쓈; 쓈; 쓈; 쓈; ) HANGUL SYLLABLE SSWIM
+C4C9;C4C9;110A 1171 11B8;C4C9;110A 1171 11B8; # (쓉; 쓉; 쓉; 쓉; 쓉; ) HANGUL SYLLABLE SSWIB
+C4CA;C4CA;110A 1171 11B9;C4CA;110A 1171 11B9; # (쓊; 쓊; 쓊; 쓊; 쓊; ) HANGUL SYLLABLE SSWIBS
+C4CB;C4CB;110A 1171 11BA;C4CB;110A 1171 11BA; # (쓋; 쓋; 쓋; 쓋; 쓋; ) HANGUL SYLLABLE SSWIS
+C4CC;C4CC;110A 1171 11BB;C4CC;110A 1171 11BB; # (쓌; 쓌; 쓌; 쓌; 쓌; ) HANGUL SYLLABLE SSWISS
+C4CD;C4CD;110A 1171 11BC;C4CD;110A 1171 11BC; # (쓍; 쓍; 쓍; 쓍; 쓍; ) HANGUL SYLLABLE SSWING
+C4CE;C4CE;110A 1171 11BD;C4CE;110A 1171 11BD; # (쓎; 쓎; 쓎; 쓎; 쓎; ) HANGUL SYLLABLE SSWIJ
+C4CF;C4CF;110A 1171 11BE;C4CF;110A 1171 11BE; # (쓏; 쓏; 쓏; 쓏; 쓏; ) HANGUL SYLLABLE SSWIC
+C4D0;C4D0;110A 1171 11BF;C4D0;110A 1171 11BF; # (쓐; 쓐; 쓐; 쓐; 쓐; ) HANGUL SYLLABLE SSWIK
+C4D1;C4D1;110A 1171 11C0;C4D1;110A 1171 11C0; # (쓑; 쓑; 쓑; 쓑; 쓑; ) HANGUL SYLLABLE SSWIT
+C4D2;C4D2;110A 1171 11C1;C4D2;110A 1171 11C1; # (쓒; 쓒; 쓒; 쓒; 쓒; ) HANGUL SYLLABLE SSWIP
+C4D3;C4D3;110A 1171 11C2;C4D3;110A 1171 11C2; # (쓓; 쓓; 쓓; 쓓; 쓓; ) HANGUL SYLLABLE SSWIH
+C4D4;C4D4;110A 1172;C4D4;110A 1172; # (쓔; 쓔; 쓔; 쓔; 쓔; ) HANGUL SYLLABLE SSYU
+C4D5;C4D5;110A 1172 11A8;C4D5;110A 1172 11A8; # (쓕; 쓕; 쓕; 쓕; 쓕; ) HANGUL SYLLABLE SSYUG
+C4D6;C4D6;110A 1172 11A9;C4D6;110A 1172 11A9; # (쓖; 쓖; 쓖; 쓖; 쓖; ) HANGUL SYLLABLE SSYUGG
+C4D7;C4D7;110A 1172 11AA;C4D7;110A 1172 11AA; # (쓗; 쓗; 쓗; 쓗; 쓗; ) HANGUL SYLLABLE SSYUGS
+C4D8;C4D8;110A 1172 11AB;C4D8;110A 1172 11AB; # (쓘; 쓘; 쓘; 쓘; 쓘; ) HANGUL SYLLABLE SSYUN
+C4D9;C4D9;110A 1172 11AC;C4D9;110A 1172 11AC; # (쓙; 쓙; 쓙; 쓙; 쓙; ) HANGUL SYLLABLE SSYUNJ
+C4DA;C4DA;110A 1172 11AD;C4DA;110A 1172 11AD; # (쓚; 쓚; 쓚; 쓚; 쓚; ) HANGUL SYLLABLE SSYUNH
+C4DB;C4DB;110A 1172 11AE;C4DB;110A 1172 11AE; # (쓛; 쓛; 쓛; 쓛; 쓛; ) HANGUL SYLLABLE SSYUD
+C4DC;C4DC;110A 1172 11AF;C4DC;110A 1172 11AF; # (쓜; 쓜; 쓜; 쓜; 쓜; ) HANGUL SYLLABLE SSYUL
+C4DD;C4DD;110A 1172 11B0;C4DD;110A 1172 11B0; # (쓝; 쓝; 쓝; 쓝; 쓝; ) HANGUL SYLLABLE SSYULG
+C4DE;C4DE;110A 1172 11B1;C4DE;110A 1172 11B1; # (쓞; 쓞; 쓞; 쓞; 쓞; ) HANGUL SYLLABLE SSYULM
+C4DF;C4DF;110A 1172 11B2;C4DF;110A 1172 11B2; # (쓟; 쓟; 쓟; 쓟; 쓟; ) HANGUL SYLLABLE SSYULB
+C4E0;C4E0;110A 1172 11B3;C4E0;110A 1172 11B3; # (쓠; 쓠; 쓠; 쓠; 쓠; ) HANGUL SYLLABLE SSYULS
+C4E1;C4E1;110A 1172 11B4;C4E1;110A 1172 11B4; # (쓡; 쓡; 쓡; 쓡; 쓡; ) HANGUL SYLLABLE SSYULT
+C4E2;C4E2;110A 1172 11B5;C4E2;110A 1172 11B5; # (쓢; 쓢; 쓢; 쓢; 쓢; ) HANGUL SYLLABLE SSYULP
+C4E3;C4E3;110A 1172 11B6;C4E3;110A 1172 11B6; # (쓣; 쓣; 쓣; 쓣; 쓣; ) HANGUL SYLLABLE SSYULH
+C4E4;C4E4;110A 1172 11B7;C4E4;110A 1172 11B7; # (쓤; 쓤; 쓤; 쓤; 쓤; ) HANGUL SYLLABLE SSYUM
+C4E5;C4E5;110A 1172 11B8;C4E5;110A 1172 11B8; # (쓥; 쓥; 쓥; 쓥; 쓥; ) HANGUL SYLLABLE SSYUB
+C4E6;C4E6;110A 1172 11B9;C4E6;110A 1172 11B9; # (쓦; 쓦; 쓦; 쓦; 쓦; ) HANGUL SYLLABLE SSYUBS
+C4E7;C4E7;110A 1172 11BA;C4E7;110A 1172 11BA; # (쓧; 쓧; 쓧; 쓧; 쓧; ) HANGUL SYLLABLE SSYUS
+C4E8;C4E8;110A 1172 11BB;C4E8;110A 1172 11BB; # (쓨; 쓨; 쓨; 쓨; 쓨; ) HANGUL SYLLABLE SSYUSS
+C4E9;C4E9;110A 1172 11BC;C4E9;110A 1172 11BC; # (쓩; 쓩; 쓩; 쓩; 쓩; ) HANGUL SYLLABLE SSYUNG
+C4EA;C4EA;110A 1172 11BD;C4EA;110A 1172 11BD; # (쓪; 쓪; 쓪; 쓪; 쓪; ) HANGUL SYLLABLE SSYUJ
+C4EB;C4EB;110A 1172 11BE;C4EB;110A 1172 11BE; # (쓫; 쓫; 쓫; 쓫; 쓫; ) HANGUL SYLLABLE SSYUC
+C4EC;C4EC;110A 1172 11BF;C4EC;110A 1172 11BF; # (쓬; 쓬; 쓬; 쓬; 쓬; ) HANGUL SYLLABLE SSYUK
+C4ED;C4ED;110A 1172 11C0;C4ED;110A 1172 11C0; # (쓭; 쓭; 쓭; 쓭; 쓭; ) HANGUL SYLLABLE SSYUT
+C4EE;C4EE;110A 1172 11C1;C4EE;110A 1172 11C1; # (쓮; 쓮; 쓮; 쓮; 쓮; ) HANGUL SYLLABLE SSYUP
+C4EF;C4EF;110A 1172 11C2;C4EF;110A 1172 11C2; # (쓯; 쓯; 쓯; 쓯; 쓯; ) HANGUL SYLLABLE SSYUH
+C4F0;C4F0;110A 1173;C4F0;110A 1173; # (쓰; 쓰; 쓰; 쓰; 쓰; ) HANGUL SYLLABLE SSEU
+C4F1;C4F1;110A 1173 11A8;C4F1;110A 1173 11A8; # (쓱; 쓱; 쓱; 쓱; 쓱; ) HANGUL SYLLABLE SSEUG
+C4F2;C4F2;110A 1173 11A9;C4F2;110A 1173 11A9; # (쓲; 쓲; 쓲; 쓲; 쓲; ) HANGUL SYLLABLE SSEUGG
+C4F3;C4F3;110A 1173 11AA;C4F3;110A 1173 11AA; # (쓳; 쓳; 쓳; 쓳; 쓳; ) HANGUL SYLLABLE SSEUGS
+C4F4;C4F4;110A 1173 11AB;C4F4;110A 1173 11AB; # (쓴; 쓴; 쓴; 쓴; 쓴; ) HANGUL SYLLABLE SSEUN
+C4F5;C4F5;110A 1173 11AC;C4F5;110A 1173 11AC; # (쓵; 쓵; 쓵; 쓵; 쓵; ) HANGUL SYLLABLE SSEUNJ
+C4F6;C4F6;110A 1173 11AD;C4F6;110A 1173 11AD; # (쓶; 쓶; 쓶; 쓶; 쓶; ) HANGUL SYLLABLE SSEUNH
+C4F7;C4F7;110A 1173 11AE;C4F7;110A 1173 11AE; # (쓷; 쓷; 쓷; 쓷; 쓷; ) HANGUL SYLLABLE SSEUD
+C4F8;C4F8;110A 1173 11AF;C4F8;110A 1173 11AF; # (쓸; 쓸; 쓸; 쓸; 쓸; ) HANGUL SYLLABLE SSEUL
+C4F9;C4F9;110A 1173 11B0;C4F9;110A 1173 11B0; # (쓹; 쓹; 쓹; 쓹; 쓹; ) HANGUL SYLLABLE SSEULG
+C4FA;C4FA;110A 1173 11B1;C4FA;110A 1173 11B1; # (쓺; 쓺; 쓺; 쓺; 쓺; ) HANGUL SYLLABLE SSEULM
+C4FB;C4FB;110A 1173 11B2;C4FB;110A 1173 11B2; # (쓻; 쓻; 쓻; 쓻; 쓻; ) HANGUL SYLLABLE SSEULB
+C4FC;C4FC;110A 1173 11B3;C4FC;110A 1173 11B3; # (쓼; 쓼; 쓼; 쓼; 쓼; ) HANGUL SYLLABLE SSEULS
+C4FD;C4FD;110A 1173 11B4;C4FD;110A 1173 11B4; # (쓽; 쓽; 쓽; 쓽; 쓽; ) HANGUL SYLLABLE SSEULT
+C4FE;C4FE;110A 1173 11B5;C4FE;110A 1173 11B5; # (쓾; 쓾; 쓾; 쓾; 쓾; ) HANGUL SYLLABLE SSEULP
+C4FF;C4FF;110A 1173 11B6;C4FF;110A 1173 11B6; # (쓿; 쓿; 쓿; 쓿; 쓿; ) HANGUL SYLLABLE SSEULH
+C500;C500;110A 1173 11B7;C500;110A 1173 11B7; # (씀; 씀; 씀; 씀; 씀; ) HANGUL SYLLABLE SSEUM
+C501;C501;110A 1173 11B8;C501;110A 1173 11B8; # (씁; 씁; 씁; 씁; 씁; ) HANGUL SYLLABLE SSEUB
+C502;C502;110A 1173 11B9;C502;110A 1173 11B9; # (씂; 씂; 씂; 씂; 씂; ) HANGUL SYLLABLE SSEUBS
+C503;C503;110A 1173 11BA;C503;110A 1173 11BA; # (씃; 씃; 씃; 씃; 씃; ) HANGUL SYLLABLE SSEUS
+C504;C504;110A 1173 11BB;C504;110A 1173 11BB; # (씄; 씄; 씄; 씄; 씄; ) HANGUL SYLLABLE SSEUSS
+C505;C505;110A 1173 11BC;C505;110A 1173 11BC; # (씅; 씅; 씅; 씅; 씅; ) HANGUL SYLLABLE SSEUNG
+C506;C506;110A 1173 11BD;C506;110A 1173 11BD; # (씆; 씆; 씆; 씆; 씆; ) HANGUL SYLLABLE SSEUJ
+C507;C507;110A 1173 11BE;C507;110A 1173 11BE; # (씇; 씇; 씇; 씇; 씇; ) HANGUL SYLLABLE SSEUC
+C508;C508;110A 1173 11BF;C508;110A 1173 11BF; # (씈; 씈; 씈; 씈; 씈; ) HANGUL SYLLABLE SSEUK
+C509;C509;110A 1173 11C0;C509;110A 1173 11C0; # (씉; 씉; 씉; 씉; 씉; ) HANGUL SYLLABLE SSEUT
+C50A;C50A;110A 1173 11C1;C50A;110A 1173 11C1; # (씊; 씊; 씊; 씊; 씊; ) HANGUL SYLLABLE SSEUP
+C50B;C50B;110A 1173 11C2;C50B;110A 1173 11C2; # (씋; 씋; 씋; 씋; 씋; ) HANGUL SYLLABLE SSEUH
+C50C;C50C;110A 1174;C50C;110A 1174; # (씌; 씌; 씌; 씌; 씌; ) HANGUL SYLLABLE SSYI
+C50D;C50D;110A 1174 11A8;C50D;110A 1174 11A8; # (씍; 씍; 씍; 씍; 씍; ) HANGUL SYLLABLE SSYIG
+C50E;C50E;110A 1174 11A9;C50E;110A 1174 11A9; # (씎; 씎; 씎; 씎; 씎; ) HANGUL SYLLABLE SSYIGG
+C50F;C50F;110A 1174 11AA;C50F;110A 1174 11AA; # (씏; 씏; 씏; 씏; 씏; ) HANGUL SYLLABLE SSYIGS
+C510;C510;110A 1174 11AB;C510;110A 1174 11AB; # (씐; 씐; 씐; 씐; 씐; ) HANGUL SYLLABLE SSYIN
+C511;C511;110A 1174 11AC;C511;110A 1174 11AC; # (씑; 씑; 씑; 씑; 씑; ) HANGUL SYLLABLE SSYINJ
+C512;C512;110A 1174 11AD;C512;110A 1174 11AD; # (씒; 씒; 씒; 씒; 씒; ) HANGUL SYLLABLE SSYINH
+C513;C513;110A 1174 11AE;C513;110A 1174 11AE; # (씓; 씓; 씓; 씓; 씓; ) HANGUL SYLLABLE SSYID
+C514;C514;110A 1174 11AF;C514;110A 1174 11AF; # (씔; 씔; 씔; 씔; 씔; ) HANGUL SYLLABLE SSYIL
+C515;C515;110A 1174 11B0;C515;110A 1174 11B0; # (씕; 씕; 씕; 씕; 씕; ) HANGUL SYLLABLE SSYILG
+C516;C516;110A 1174 11B1;C516;110A 1174 11B1; # (씖; 씖; 씖; 씖; 씖; ) HANGUL SYLLABLE SSYILM
+C517;C517;110A 1174 11B2;C517;110A 1174 11B2; # (씗; 씗; 씗; 씗; 씗; ) HANGUL SYLLABLE SSYILB
+C518;C518;110A 1174 11B3;C518;110A 1174 11B3; # (씘; 씘; 씘; 씘; 씘; ) HANGUL SYLLABLE SSYILS
+C519;C519;110A 1174 11B4;C519;110A 1174 11B4; # (씙; 씙; 씙; 씙; 씙; ) HANGUL SYLLABLE SSYILT
+C51A;C51A;110A 1174 11B5;C51A;110A 1174 11B5; # (씚; 씚; 씚; 씚; 씚; ) HANGUL SYLLABLE SSYILP
+C51B;C51B;110A 1174 11B6;C51B;110A 1174 11B6; # (씛; 씛; 씛; 씛; 씛; ) HANGUL SYLLABLE SSYILH
+C51C;C51C;110A 1174 11B7;C51C;110A 1174 11B7; # (씜; 씜; 씜; 씜; 씜; ) HANGUL SYLLABLE SSYIM
+C51D;C51D;110A 1174 11B8;C51D;110A 1174 11B8; # (씝; 씝; 씝; 씝; 씝; ) HANGUL SYLLABLE SSYIB
+C51E;C51E;110A 1174 11B9;C51E;110A 1174 11B9; # (씞; 씞; 씞; 씞; 씞; ) HANGUL SYLLABLE SSYIBS
+C51F;C51F;110A 1174 11BA;C51F;110A 1174 11BA; # (씟; 씟; 씟; 씟; 씟; ) HANGUL SYLLABLE SSYIS
+C520;C520;110A 1174 11BB;C520;110A 1174 11BB; # (씠; 씠; 씠; 씠; 씠; ) HANGUL SYLLABLE SSYISS
+C521;C521;110A 1174 11BC;C521;110A 1174 11BC; # (씡; 씡; 씡; 씡; 씡; ) HANGUL SYLLABLE SSYING
+C522;C522;110A 1174 11BD;C522;110A 1174 11BD; # (씢; 씢; 씢; 씢; 씢; ) HANGUL SYLLABLE SSYIJ
+C523;C523;110A 1174 11BE;C523;110A 1174 11BE; # (씣; 씣; 씣; 씣; 씣; ) HANGUL SYLLABLE SSYIC
+C524;C524;110A 1174 11BF;C524;110A 1174 11BF; # (씤; 씤; 씤; 씤; 씤; ) HANGUL SYLLABLE SSYIK
+C525;C525;110A 1174 11C0;C525;110A 1174 11C0; # (씥; 씥; 씥; 씥; 씥; ) HANGUL SYLLABLE SSYIT
+C526;C526;110A 1174 11C1;C526;110A 1174 11C1; # (씦; 씦; 씦; 씦; 씦; ) HANGUL SYLLABLE SSYIP
+C527;C527;110A 1174 11C2;C527;110A 1174 11C2; # (씧; 씧; 씧; 씧; 씧; ) HANGUL SYLLABLE SSYIH
+C528;C528;110A 1175;C528;110A 1175; # (씨; 씨; 씨; 씨; 씨; ) HANGUL SYLLABLE SSI
+C529;C529;110A 1175 11A8;C529;110A 1175 11A8; # (씩; 씩; 씩; 씩; 씩; ) HANGUL SYLLABLE SSIG
+C52A;C52A;110A 1175 11A9;C52A;110A 1175 11A9; # (씪; 씪; 씪; 씪; 씪; ) HANGUL SYLLABLE SSIGG
+C52B;C52B;110A 1175 11AA;C52B;110A 1175 11AA; # (씫; 씫; 씫; 씫; 씫; ) HANGUL SYLLABLE SSIGS
+C52C;C52C;110A 1175 11AB;C52C;110A 1175 11AB; # (씬; 씬; 씬; 씬; 씬; ) HANGUL SYLLABLE SSIN
+C52D;C52D;110A 1175 11AC;C52D;110A 1175 11AC; # (씭; 씭; 씭; 씭; 씭; ) HANGUL SYLLABLE SSINJ
+C52E;C52E;110A 1175 11AD;C52E;110A 1175 11AD; # (씮; 씮; 씮; 씮; 씮; ) HANGUL SYLLABLE SSINH
+C52F;C52F;110A 1175 11AE;C52F;110A 1175 11AE; # (씯; 씯; 씯; 씯; 씯; ) HANGUL SYLLABLE SSID
+C530;C530;110A 1175 11AF;C530;110A 1175 11AF; # (씰; 씰; 씰; 씰; 씰; ) HANGUL SYLLABLE SSIL
+C531;C531;110A 1175 11B0;C531;110A 1175 11B0; # (씱; 씱; 씱; 씱; 씱; ) HANGUL SYLLABLE SSILG
+C532;C532;110A 1175 11B1;C532;110A 1175 11B1; # (씲; 씲; 씲; 씲; 씲; ) HANGUL SYLLABLE SSILM
+C533;C533;110A 1175 11B2;C533;110A 1175 11B2; # (씳; 씳; 씳; 씳; 씳; ) HANGUL SYLLABLE SSILB
+C534;C534;110A 1175 11B3;C534;110A 1175 11B3; # (씴; 씴; 씴; 씴; 씴; ) HANGUL SYLLABLE SSILS
+C535;C535;110A 1175 11B4;C535;110A 1175 11B4; # (씵; 씵; 씵; 씵; 씵; ) HANGUL SYLLABLE SSILT
+C536;C536;110A 1175 11B5;C536;110A 1175 11B5; # (씶; 씶; 씶; 씶; 씶; ) HANGUL SYLLABLE SSILP
+C537;C537;110A 1175 11B6;C537;110A 1175 11B6; # (씷; 씷; 씷; 씷; 씷; ) HANGUL SYLLABLE SSILH
+C538;C538;110A 1175 11B7;C538;110A 1175 11B7; # (씸; 씸; 씸; 씸; 씸; ) HANGUL SYLLABLE SSIM
+C539;C539;110A 1175 11B8;C539;110A 1175 11B8; # (씹; 씹; 씹; 씹; 씹; ) HANGUL SYLLABLE SSIB
+C53A;C53A;110A 1175 11B9;C53A;110A 1175 11B9; # (씺; 씺; 씺; 씺; 씺; ) HANGUL SYLLABLE SSIBS
+C53B;C53B;110A 1175 11BA;C53B;110A 1175 11BA; # (씻; 씻; 씻; 씻; 씻; ) HANGUL SYLLABLE SSIS
+C53C;C53C;110A 1175 11BB;C53C;110A 1175 11BB; # (씼; 씼; 씼; 씼; 씼; ) HANGUL SYLLABLE SSISS
+C53D;C53D;110A 1175 11BC;C53D;110A 1175 11BC; # (씽; 씽; 씽; 씽; 씽; ) HANGUL SYLLABLE SSING
+C53E;C53E;110A 1175 11BD;C53E;110A 1175 11BD; # (씾; 씾; 씾; 씾; 씾; ) HANGUL SYLLABLE SSIJ
+C53F;C53F;110A 1175 11BE;C53F;110A 1175 11BE; # (씿; 씿; 씿; 씿; 씿; ) HANGUL SYLLABLE SSIC
+C540;C540;110A 1175 11BF;C540;110A 1175 11BF; # (앀; 앀; 앀; 앀; 앀; ) HANGUL SYLLABLE SSIK
+C541;C541;110A 1175 11C0;C541;110A 1175 11C0; # (앁; 앁; 앁; 앁; 앁; ) HANGUL SYLLABLE SSIT
+C542;C542;110A 1175 11C1;C542;110A 1175 11C1; # (앂; 앂; 앂; 앂; 앂; ) HANGUL SYLLABLE SSIP
+C543;C543;110A 1175 11C2;C543;110A 1175 11C2; # (앃; 앃; 앃; 앃; 앃; ) HANGUL SYLLABLE SSIH
+C544;C544;110B 1161;C544;110B 1161; # (아; 아; 아; 아; 아; ) HANGUL SYLLABLE A
+C545;C545;110B 1161 11A8;C545;110B 1161 11A8; # (악; 악; 악; 악; 악; ) HANGUL SYLLABLE AG
+C546;C546;110B 1161 11A9;C546;110B 1161 11A9; # (앆; 앆; 앆; 앆; 앆; ) HANGUL SYLLABLE AGG
+C547;C547;110B 1161 11AA;C547;110B 1161 11AA; # (앇; 앇; 앇; 앇; 앇; ) HANGUL SYLLABLE AGS
+C548;C548;110B 1161 11AB;C548;110B 1161 11AB; # (안; 안; 안; 안; 안; ) HANGUL SYLLABLE AN
+C549;C549;110B 1161 11AC;C549;110B 1161 11AC; # (앉; 앉; 앉; 앉; 앉; ) HANGUL SYLLABLE ANJ
+C54A;C54A;110B 1161 11AD;C54A;110B 1161 11AD; # (않; 않; 않; 않; 않; ) HANGUL SYLLABLE ANH
+C54B;C54B;110B 1161 11AE;C54B;110B 1161 11AE; # (앋; 앋; 앋; 앋; 앋; ) HANGUL SYLLABLE AD
+C54C;C54C;110B 1161 11AF;C54C;110B 1161 11AF; # (알; 알; 알; 알; 알; ) HANGUL SYLLABLE AL
+C54D;C54D;110B 1161 11B0;C54D;110B 1161 11B0; # (앍; 앍; 앍; 앍; 앍; ) HANGUL SYLLABLE ALG
+C54E;C54E;110B 1161 11B1;C54E;110B 1161 11B1; # (앎; 앎; 앎; 앎; 앎; ) HANGUL SYLLABLE ALM
+C54F;C54F;110B 1161 11B2;C54F;110B 1161 11B2; # (앏; 앏; 앏; 앏; 앏; ) HANGUL SYLLABLE ALB
+C550;C550;110B 1161 11B3;C550;110B 1161 11B3; # (앐; 앐; 앐; 앐; 앐; ) HANGUL SYLLABLE ALS
+C551;C551;110B 1161 11B4;C551;110B 1161 11B4; # (앑; 앑; 앑; 앑; 앑; ) HANGUL SYLLABLE ALT
+C552;C552;110B 1161 11B5;C552;110B 1161 11B5; # (앒; 앒; 앒; 앒; 앒; ) HANGUL SYLLABLE ALP
+C553;C553;110B 1161 11B6;C553;110B 1161 11B6; # (앓; 앓; 앓; 앓; 앓; ) HANGUL SYLLABLE ALH
+C554;C554;110B 1161 11B7;C554;110B 1161 11B7; # (암; 암; 암; 암; 암; ) HANGUL SYLLABLE AM
+C555;C555;110B 1161 11B8;C555;110B 1161 11B8; # (압; 압; 압; 압; 압; ) HANGUL SYLLABLE AB
+C556;C556;110B 1161 11B9;C556;110B 1161 11B9; # (앖; 앖; 앖; 앖; 앖; ) HANGUL SYLLABLE ABS
+C557;C557;110B 1161 11BA;C557;110B 1161 11BA; # (앗; 앗; 앗; 앗; 앗; ) HANGUL SYLLABLE AS
+C558;C558;110B 1161 11BB;C558;110B 1161 11BB; # (았; 았; 았; 았; 았; ) HANGUL SYLLABLE ASS
+C559;C559;110B 1161 11BC;C559;110B 1161 11BC; # (앙; 앙; 앙; 앙; 앙; ) HANGUL SYLLABLE ANG
+C55A;C55A;110B 1161 11BD;C55A;110B 1161 11BD; # (앚; 앚; 앚; 앚; 앚; ) HANGUL SYLLABLE AJ
+C55B;C55B;110B 1161 11BE;C55B;110B 1161 11BE; # (앛; 앛; 앛; 앛; 앛; ) HANGUL SYLLABLE AC
+C55C;C55C;110B 1161 11BF;C55C;110B 1161 11BF; # (앜; 앜; 앜; 앜; 앜; ) HANGUL SYLLABLE AK
+C55D;C55D;110B 1161 11C0;C55D;110B 1161 11C0; # (앝; 앝; 앝; 앝; 앝; ) HANGUL SYLLABLE AT
+C55E;C55E;110B 1161 11C1;C55E;110B 1161 11C1; # (앞; 앞; 앞; 앞; 앞; ) HANGUL SYLLABLE AP
+C55F;C55F;110B 1161 11C2;C55F;110B 1161 11C2; # (앟; 앟; 앟; 앟; 앟; ) HANGUL SYLLABLE AH
+C560;C560;110B 1162;C560;110B 1162; # (애; 애; 애; 애; 애; ) HANGUL SYLLABLE AE
+C561;C561;110B 1162 11A8;C561;110B 1162 11A8; # (액; 액; 액; 액; 액; ) HANGUL SYLLABLE AEG
+C562;C562;110B 1162 11A9;C562;110B 1162 11A9; # (앢; 앢; 앢; 앢; 앢; ) HANGUL SYLLABLE AEGG
+C563;C563;110B 1162 11AA;C563;110B 1162 11AA; # (앣; 앣; 앣; 앣; 앣; ) HANGUL SYLLABLE AEGS
+C564;C564;110B 1162 11AB;C564;110B 1162 11AB; # (앤; 앤; 앤; 앤; 앤; ) HANGUL SYLLABLE AEN
+C565;C565;110B 1162 11AC;C565;110B 1162 11AC; # (앥; 앥; 앥; 앥; 앥; ) HANGUL SYLLABLE AENJ
+C566;C566;110B 1162 11AD;C566;110B 1162 11AD; # (앦; 앦; 앦; 앦; 앦; ) HANGUL SYLLABLE AENH
+C567;C567;110B 1162 11AE;C567;110B 1162 11AE; # (앧; 앧; 앧; 앧; 앧; ) HANGUL SYLLABLE AED
+C568;C568;110B 1162 11AF;C568;110B 1162 11AF; # (앨; 앨; 앨; 앨; 앨; ) HANGUL SYLLABLE AEL
+C569;C569;110B 1162 11B0;C569;110B 1162 11B0; # (앩; 앩; 앩; 앩; 앩; ) HANGUL SYLLABLE AELG
+C56A;C56A;110B 1162 11B1;C56A;110B 1162 11B1; # (앪; 앪; 앪; 앪; 앪; ) HANGUL SYLLABLE AELM
+C56B;C56B;110B 1162 11B2;C56B;110B 1162 11B2; # (앫; 앫; 앫; 앫; 앫; ) HANGUL SYLLABLE AELB
+C56C;C56C;110B 1162 11B3;C56C;110B 1162 11B3; # (앬; 앬; 앬; 앬; 앬; ) HANGUL SYLLABLE AELS
+C56D;C56D;110B 1162 11B4;C56D;110B 1162 11B4; # (앭; 앭; 앭; 앭; 앭; ) HANGUL SYLLABLE AELT
+C56E;C56E;110B 1162 11B5;C56E;110B 1162 11B5; # (앮; 앮; 앮; 앮; 앮; ) HANGUL SYLLABLE AELP
+C56F;C56F;110B 1162 11B6;C56F;110B 1162 11B6; # (앯; 앯; 앯; 앯; 앯; ) HANGUL SYLLABLE AELH
+C570;C570;110B 1162 11B7;C570;110B 1162 11B7; # (앰; 앰; 앰; 앰; 앰; ) HANGUL SYLLABLE AEM
+C571;C571;110B 1162 11B8;C571;110B 1162 11B8; # (앱; 앱; 앱; 앱; 앱; ) HANGUL SYLLABLE AEB
+C572;C572;110B 1162 11B9;C572;110B 1162 11B9; # (앲; 앲; 앲; 앲; 앲; ) HANGUL SYLLABLE AEBS
+C573;C573;110B 1162 11BA;C573;110B 1162 11BA; # (앳; 앳; 앳; 앳; 앳; ) HANGUL SYLLABLE AES
+C574;C574;110B 1162 11BB;C574;110B 1162 11BB; # (앴; 앴; 앴; 앴; 앴; ) HANGUL SYLLABLE AESS
+C575;C575;110B 1162 11BC;C575;110B 1162 11BC; # (앵; 앵; 앵; 앵; 앵; ) HANGUL SYLLABLE AENG
+C576;C576;110B 1162 11BD;C576;110B 1162 11BD; # (앶; 앶; 앶; 앶; 앶; ) HANGUL SYLLABLE AEJ
+C577;C577;110B 1162 11BE;C577;110B 1162 11BE; # (앷; 앷; 앷; 앷; 앷; ) HANGUL SYLLABLE AEC
+C578;C578;110B 1162 11BF;C578;110B 1162 11BF; # (앸; 앸; 앸; 앸; 앸; ) HANGUL SYLLABLE AEK
+C579;C579;110B 1162 11C0;C579;110B 1162 11C0; # (앹; 앹; 앹; 앹; 앹; ) HANGUL SYLLABLE AET
+C57A;C57A;110B 1162 11C1;C57A;110B 1162 11C1; # (앺; 앺; 앺; 앺; 앺; ) HANGUL SYLLABLE AEP
+C57B;C57B;110B 1162 11C2;C57B;110B 1162 11C2; # (앻; 앻; 앻; 앻; 앻; ) HANGUL SYLLABLE AEH
+C57C;C57C;110B 1163;C57C;110B 1163; # (야; 야; 야; 야; 야; ) HANGUL SYLLABLE YA
+C57D;C57D;110B 1163 11A8;C57D;110B 1163 11A8; # (약; 약; 약; 약; 약; ) HANGUL SYLLABLE YAG
+C57E;C57E;110B 1163 11A9;C57E;110B 1163 11A9; # (앾; 앾; 앾; 앾; 앾; ) HANGUL SYLLABLE YAGG
+C57F;C57F;110B 1163 11AA;C57F;110B 1163 11AA; # (앿; 앿; 앿; 앿; 앿; ) HANGUL SYLLABLE YAGS
+C580;C580;110B 1163 11AB;C580;110B 1163 11AB; # (얀; 얀; 얀; 얀; 얀; ) HANGUL SYLLABLE YAN
+C581;C581;110B 1163 11AC;C581;110B 1163 11AC; # (얁; 얁; 얁; 얁; 얁; ) HANGUL SYLLABLE YANJ
+C582;C582;110B 1163 11AD;C582;110B 1163 11AD; # (얂; 얂; 얂; 얂; 얂; ) HANGUL SYLLABLE YANH
+C583;C583;110B 1163 11AE;C583;110B 1163 11AE; # (얃; 얃; 얃; 얃; 얃; ) HANGUL SYLLABLE YAD
+C584;C584;110B 1163 11AF;C584;110B 1163 11AF; # (얄; 얄; 얄; 얄; 얄; ) HANGUL SYLLABLE YAL
+C585;C585;110B 1163 11B0;C585;110B 1163 11B0; # (얅; 얅; 얅; 얅; 얅; ) HANGUL SYLLABLE YALG
+C586;C586;110B 1163 11B1;C586;110B 1163 11B1; # (얆; 얆; 얆; 얆; 얆; ) HANGUL SYLLABLE YALM
+C587;C587;110B 1163 11B2;C587;110B 1163 11B2; # (얇; 얇; 얇; 얇; 얇; ) HANGUL SYLLABLE YALB
+C588;C588;110B 1163 11B3;C588;110B 1163 11B3; # (얈; 얈; 얈; 얈; 얈; ) HANGUL SYLLABLE YALS
+C589;C589;110B 1163 11B4;C589;110B 1163 11B4; # (얉; 얉; 얉; 얉; 얉; ) HANGUL SYLLABLE YALT
+C58A;C58A;110B 1163 11B5;C58A;110B 1163 11B5; # (얊; 얊; 얊; 얊; 얊; ) HANGUL SYLLABLE YALP
+C58B;C58B;110B 1163 11B6;C58B;110B 1163 11B6; # (얋; 얋; 얋; 얋; 얋; ) HANGUL SYLLABLE YALH
+C58C;C58C;110B 1163 11B7;C58C;110B 1163 11B7; # (얌; 얌; 얌; 얌; 얌; ) HANGUL SYLLABLE YAM
+C58D;C58D;110B 1163 11B8;C58D;110B 1163 11B8; # (얍; 얍; 얍; 얍; 얍; ) HANGUL SYLLABLE YAB
+C58E;C58E;110B 1163 11B9;C58E;110B 1163 11B9; # (얎; 얎; 얎; 얎; 얎; ) HANGUL SYLLABLE YABS
+C58F;C58F;110B 1163 11BA;C58F;110B 1163 11BA; # (얏; 얏; 얏; 얏; 얏; ) HANGUL SYLLABLE YAS
+C590;C590;110B 1163 11BB;C590;110B 1163 11BB; # (얐; 얐; 얐; 얐; 얐; ) HANGUL SYLLABLE YASS
+C591;C591;110B 1163 11BC;C591;110B 1163 11BC; # (양; 양; 양; 양; 양; ) HANGUL SYLLABLE YANG
+C592;C592;110B 1163 11BD;C592;110B 1163 11BD; # (얒; 얒; 얒; 얒; 얒; ) HANGUL SYLLABLE YAJ
+C593;C593;110B 1163 11BE;C593;110B 1163 11BE; # (얓; 얓; 얓; 얓; 얓; ) HANGUL SYLLABLE YAC
+C594;C594;110B 1163 11BF;C594;110B 1163 11BF; # (얔; 얔; 얔; 얔; 얔; ) HANGUL SYLLABLE YAK
+C595;C595;110B 1163 11C0;C595;110B 1163 11C0; # (얕; 얕; 얕; 얕; 얕; ) HANGUL SYLLABLE YAT
+C596;C596;110B 1163 11C1;C596;110B 1163 11C1; # (얖; 얖; 얖; 얖; 얖; ) HANGUL SYLLABLE YAP
+C597;C597;110B 1163 11C2;C597;110B 1163 11C2; # (얗; 얗; 얗; 얗; 얗; ) HANGUL SYLLABLE YAH
+C598;C598;110B 1164;C598;110B 1164; # (얘; 얘; 얘; 얘; 얘; ) HANGUL SYLLABLE YAE
+C599;C599;110B 1164 11A8;C599;110B 1164 11A8; # (얙; 얙; 얙; 얙; 얙; ) HANGUL SYLLABLE YAEG
+C59A;C59A;110B 1164 11A9;C59A;110B 1164 11A9; # (얚; 얚; 얚; 얚; 얚; ) HANGUL SYLLABLE YAEGG
+C59B;C59B;110B 1164 11AA;C59B;110B 1164 11AA; # (얛; 얛; 얛; 얛; 얛; ) HANGUL SYLLABLE YAEGS
+C59C;C59C;110B 1164 11AB;C59C;110B 1164 11AB; # (얜; 얜; 얜; 얜; 얜; ) HANGUL SYLLABLE YAEN
+C59D;C59D;110B 1164 11AC;C59D;110B 1164 11AC; # (얝; 얝; 얝; 얝; 얝; ) HANGUL SYLLABLE YAENJ
+C59E;C59E;110B 1164 11AD;C59E;110B 1164 11AD; # (얞; 얞; 얞; 얞; 얞; ) HANGUL SYLLABLE YAENH
+C59F;C59F;110B 1164 11AE;C59F;110B 1164 11AE; # (얟; 얟; 얟; 얟; 얟; ) HANGUL SYLLABLE YAED
+C5A0;C5A0;110B 1164 11AF;C5A0;110B 1164 11AF; # (얠; 얠; 얠; 얠; 얠; ) HANGUL SYLLABLE YAEL
+C5A1;C5A1;110B 1164 11B0;C5A1;110B 1164 11B0; # (얡; 얡; 얡; 얡; 얡; ) HANGUL SYLLABLE YAELG
+C5A2;C5A2;110B 1164 11B1;C5A2;110B 1164 11B1; # (얢; 얢; 얢; 얢; 얢; ) HANGUL SYLLABLE YAELM
+C5A3;C5A3;110B 1164 11B2;C5A3;110B 1164 11B2; # (얣; 얣; 얣; 얣; 얣; ) HANGUL SYLLABLE YAELB
+C5A4;C5A4;110B 1164 11B3;C5A4;110B 1164 11B3; # (얤; 얤; 얤; 얤; 얤; ) HANGUL SYLLABLE YAELS
+C5A5;C5A5;110B 1164 11B4;C5A5;110B 1164 11B4; # (얥; 얥; 얥; 얥; 얥; ) HANGUL SYLLABLE YAELT
+C5A6;C5A6;110B 1164 11B5;C5A6;110B 1164 11B5; # (얦; 얦; 얦; 얦; 얦; ) HANGUL SYLLABLE YAELP
+C5A7;C5A7;110B 1164 11B6;C5A7;110B 1164 11B6; # (얧; 얧; 얧; 얧; 얧; ) HANGUL SYLLABLE YAELH
+C5A8;C5A8;110B 1164 11B7;C5A8;110B 1164 11B7; # (얨; 얨; 얨; 얨; 얨; ) HANGUL SYLLABLE YAEM
+C5A9;C5A9;110B 1164 11B8;C5A9;110B 1164 11B8; # (얩; 얩; 얩; 얩; 얩; ) HANGUL SYLLABLE YAEB
+C5AA;C5AA;110B 1164 11B9;C5AA;110B 1164 11B9; # (얪; 얪; 얪; 얪; 얪; ) HANGUL SYLLABLE YAEBS
+C5AB;C5AB;110B 1164 11BA;C5AB;110B 1164 11BA; # (얫; 얫; 얫; 얫; 얫; ) HANGUL SYLLABLE YAES
+C5AC;C5AC;110B 1164 11BB;C5AC;110B 1164 11BB; # (얬; 얬; 얬; 얬; 얬; ) HANGUL SYLLABLE YAESS
+C5AD;C5AD;110B 1164 11BC;C5AD;110B 1164 11BC; # (얭; 얭; 얭; 얭; 얭; ) HANGUL SYLLABLE YAENG
+C5AE;C5AE;110B 1164 11BD;C5AE;110B 1164 11BD; # (얮; 얮; 얮; 얮; 얮; ) HANGUL SYLLABLE YAEJ
+C5AF;C5AF;110B 1164 11BE;C5AF;110B 1164 11BE; # (얯; 얯; 얯; 얯; 얯; ) HANGUL SYLLABLE YAEC
+C5B0;C5B0;110B 1164 11BF;C5B0;110B 1164 11BF; # (얰; 얰; 얰; 얰; 얰; ) HANGUL SYLLABLE YAEK
+C5B1;C5B1;110B 1164 11C0;C5B1;110B 1164 11C0; # (얱; 얱; 얱; 얱; 얱; ) HANGUL SYLLABLE YAET
+C5B2;C5B2;110B 1164 11C1;C5B2;110B 1164 11C1; # (얲; 얲; 얲; 얲; 얲; ) HANGUL SYLLABLE YAEP
+C5B3;C5B3;110B 1164 11C2;C5B3;110B 1164 11C2; # (얳; 얳; 얳; 얳; 얳; ) HANGUL SYLLABLE YAEH
+C5B4;C5B4;110B 1165;C5B4;110B 1165; # (어; 어; 어; 어; 어; ) HANGUL SYLLABLE EO
+C5B5;C5B5;110B 1165 11A8;C5B5;110B 1165 11A8; # (억; 억; 억; 억; 억; ) HANGUL SYLLABLE EOG
+C5B6;C5B6;110B 1165 11A9;C5B6;110B 1165 11A9; # (얶; 얶; 얶; 얶; 얶; ) HANGUL SYLLABLE EOGG
+C5B7;C5B7;110B 1165 11AA;C5B7;110B 1165 11AA; # (얷; 얷; 얷; 얷; 얷; ) HANGUL SYLLABLE EOGS
+C5B8;C5B8;110B 1165 11AB;C5B8;110B 1165 11AB; # (언; 언; 언; 언; 언; ) HANGUL SYLLABLE EON
+C5B9;C5B9;110B 1165 11AC;C5B9;110B 1165 11AC; # (얹; 얹; 얹; 얹; 얹; ) HANGUL SYLLABLE EONJ
+C5BA;C5BA;110B 1165 11AD;C5BA;110B 1165 11AD; # (얺; 얺; 얺; 얺; 얺; ) HANGUL SYLLABLE EONH
+C5BB;C5BB;110B 1165 11AE;C5BB;110B 1165 11AE; # (얻; 얻; 얻; 얻; 얻; ) HANGUL SYLLABLE EOD
+C5BC;C5BC;110B 1165 11AF;C5BC;110B 1165 11AF; # (얼; 얼; 얼; 얼; 얼; ) HANGUL SYLLABLE EOL
+C5BD;C5BD;110B 1165 11B0;C5BD;110B 1165 11B0; # (얽; 얽; 얽; 얽; 얽; ) HANGUL SYLLABLE EOLG
+C5BE;C5BE;110B 1165 11B1;C5BE;110B 1165 11B1; # (얾; 얾; 얾; 얾; 얾; ) HANGUL SYLLABLE EOLM
+C5BF;C5BF;110B 1165 11B2;C5BF;110B 1165 11B2; # (얿; 얿; 얿; 얿; 얿; ) HANGUL SYLLABLE EOLB
+C5C0;C5C0;110B 1165 11B3;C5C0;110B 1165 11B3; # (엀; 엀; 엀; 엀; 엀; ) HANGUL SYLLABLE EOLS
+C5C1;C5C1;110B 1165 11B4;C5C1;110B 1165 11B4; # (엁; 엁; 엁; 엁; 엁; ) HANGUL SYLLABLE EOLT
+C5C2;C5C2;110B 1165 11B5;C5C2;110B 1165 11B5; # (엂; 엂; 엂; 엂; 엂; ) HANGUL SYLLABLE EOLP
+C5C3;C5C3;110B 1165 11B6;C5C3;110B 1165 11B6; # (엃; 엃; 엃; 엃; 엃; ) HANGUL SYLLABLE EOLH
+C5C4;C5C4;110B 1165 11B7;C5C4;110B 1165 11B7; # (엄; 엄; 엄; 엄; 엄; ) HANGUL SYLLABLE EOM
+C5C5;C5C5;110B 1165 11B8;C5C5;110B 1165 11B8; # (업; 업; 업; 업; 업; ) HANGUL SYLLABLE EOB
+C5C6;C5C6;110B 1165 11B9;C5C6;110B 1165 11B9; # (없; 없; 없; 없; 없; ) HANGUL SYLLABLE EOBS
+C5C7;C5C7;110B 1165 11BA;C5C7;110B 1165 11BA; # (엇; 엇; 엇; 엇; 엇; ) HANGUL SYLLABLE EOS
+C5C8;C5C8;110B 1165 11BB;C5C8;110B 1165 11BB; # (었; 었; 었; 었; 었; ) HANGUL SYLLABLE EOSS
+C5C9;C5C9;110B 1165 11BC;C5C9;110B 1165 11BC; # (엉; 엉; 엉; 엉; 엉; ) HANGUL SYLLABLE EONG
+C5CA;C5CA;110B 1165 11BD;C5CA;110B 1165 11BD; # (엊; 엊; 엊; 엊; 엊; ) HANGUL SYLLABLE EOJ
+C5CB;C5CB;110B 1165 11BE;C5CB;110B 1165 11BE; # (엋; 엋; 엋; 엋; 엋; ) HANGUL SYLLABLE EOC
+C5CC;C5CC;110B 1165 11BF;C5CC;110B 1165 11BF; # (엌; 엌; 엌; 엌; 엌; ) HANGUL SYLLABLE EOK
+C5CD;C5CD;110B 1165 11C0;C5CD;110B 1165 11C0; # (엍; 엍; 엍; 엍; 엍; ) HANGUL SYLLABLE EOT
+C5CE;C5CE;110B 1165 11C1;C5CE;110B 1165 11C1; # (엎; 엎; 엎; 엎; 엎; ) HANGUL SYLLABLE EOP
+C5CF;C5CF;110B 1165 11C2;C5CF;110B 1165 11C2; # (엏; 엏; 엏; 엏; 엏; ) HANGUL SYLLABLE EOH
+C5D0;C5D0;110B 1166;C5D0;110B 1166; # (에; 에; 에; 에; 에; ) HANGUL SYLLABLE E
+C5D1;C5D1;110B 1166 11A8;C5D1;110B 1166 11A8; # (엑; 엑; 엑; 엑; 엑; ) HANGUL SYLLABLE EG
+C5D2;C5D2;110B 1166 11A9;C5D2;110B 1166 11A9; # (엒; 엒; 엒; 엒; 엒; ) HANGUL SYLLABLE EGG
+C5D3;C5D3;110B 1166 11AA;C5D3;110B 1166 11AA; # (엓; 엓; 엓; 엓; 엓; ) HANGUL SYLLABLE EGS
+C5D4;C5D4;110B 1166 11AB;C5D4;110B 1166 11AB; # (엔; 엔; 엔; 엔; 엔; ) HANGUL SYLLABLE EN
+C5D5;C5D5;110B 1166 11AC;C5D5;110B 1166 11AC; # (엕; 엕; 엕; 엕; 엕; ) HANGUL SYLLABLE ENJ
+C5D6;C5D6;110B 1166 11AD;C5D6;110B 1166 11AD; # (엖; 엖; 엖; 엖; 엖; ) HANGUL SYLLABLE ENH
+C5D7;C5D7;110B 1166 11AE;C5D7;110B 1166 11AE; # (엗; 엗; 엗; 엗; 엗; ) HANGUL SYLLABLE ED
+C5D8;C5D8;110B 1166 11AF;C5D8;110B 1166 11AF; # (엘; 엘; 엘; 엘; 엘; ) HANGUL SYLLABLE EL
+C5D9;C5D9;110B 1166 11B0;C5D9;110B 1166 11B0; # (엙; 엙; 엙; 엙; 엙; ) HANGUL SYLLABLE ELG
+C5DA;C5DA;110B 1166 11B1;C5DA;110B 1166 11B1; # (엚; 엚; 엚; 엚; 엚; ) HANGUL SYLLABLE ELM
+C5DB;C5DB;110B 1166 11B2;C5DB;110B 1166 11B2; # (엛; 엛; 엛; 엛; 엛; ) HANGUL SYLLABLE ELB
+C5DC;C5DC;110B 1166 11B3;C5DC;110B 1166 11B3; # (엜; 엜; 엜; 엜; 엜; ) HANGUL SYLLABLE ELS
+C5DD;C5DD;110B 1166 11B4;C5DD;110B 1166 11B4; # (엝; 엝; 엝; 엝; 엝; ) HANGUL SYLLABLE ELT
+C5DE;C5DE;110B 1166 11B5;C5DE;110B 1166 11B5; # (엞; 엞; 엞; 엞; 엞; ) HANGUL SYLLABLE ELP
+C5DF;C5DF;110B 1166 11B6;C5DF;110B 1166 11B6; # (엟; 엟; 엟; 엟; 엟; ) HANGUL SYLLABLE ELH
+C5E0;C5E0;110B 1166 11B7;C5E0;110B 1166 11B7; # (엠; 엠; 엠; 엠; 엠; ) HANGUL SYLLABLE EM
+C5E1;C5E1;110B 1166 11B8;C5E1;110B 1166 11B8; # (엡; 엡; 엡; 엡; 엡; ) HANGUL SYLLABLE EB
+C5E2;C5E2;110B 1166 11B9;C5E2;110B 1166 11B9; # (엢; 엢; 엢; 엢; 엢; ) HANGUL SYLLABLE EBS
+C5E3;C5E3;110B 1166 11BA;C5E3;110B 1166 11BA; # (엣; 엣; 엣; 엣; 엣; ) HANGUL SYLLABLE ES
+C5E4;C5E4;110B 1166 11BB;C5E4;110B 1166 11BB; # (엤; 엤; 엤; 엤; 엤; ) HANGUL SYLLABLE ESS
+C5E5;C5E5;110B 1166 11BC;C5E5;110B 1166 11BC; # (엥; 엥; 엥; 엥; 엥; ) HANGUL SYLLABLE ENG
+C5E6;C5E6;110B 1166 11BD;C5E6;110B 1166 11BD; # (엦; 엦; 엦; 엦; 엦; ) HANGUL SYLLABLE EJ
+C5E7;C5E7;110B 1166 11BE;C5E7;110B 1166 11BE; # (엧; 엧; 엧; 엧; 엧; ) HANGUL SYLLABLE EC
+C5E8;C5E8;110B 1166 11BF;C5E8;110B 1166 11BF; # (엨; 엨; 엨; 엨; 엨; ) HANGUL SYLLABLE EK
+C5E9;C5E9;110B 1166 11C0;C5E9;110B 1166 11C0; # (엩; 엩; 엩; 엩; 엩; ) HANGUL SYLLABLE ET
+C5EA;C5EA;110B 1166 11C1;C5EA;110B 1166 11C1; # (엪; 엪; 엪; 엪; 엪; ) HANGUL SYLLABLE EP
+C5EB;C5EB;110B 1166 11C2;C5EB;110B 1166 11C2; # (엫; 엫; 엫; 엫; 엫; ) HANGUL SYLLABLE EH
+C5EC;C5EC;110B 1167;C5EC;110B 1167; # (여; 여; 여; 여; 여; ) HANGUL SYLLABLE YEO
+C5ED;C5ED;110B 1167 11A8;C5ED;110B 1167 11A8; # (역; 역; 역; 역; 역; ) HANGUL SYLLABLE YEOG
+C5EE;C5EE;110B 1167 11A9;C5EE;110B 1167 11A9; # (엮; 엮; 엮; 엮; 엮; ) HANGUL SYLLABLE YEOGG
+C5EF;C5EF;110B 1167 11AA;C5EF;110B 1167 11AA; # (엯; 엯; 엯; 엯; 엯; ) HANGUL SYLLABLE YEOGS
+C5F0;C5F0;110B 1167 11AB;C5F0;110B 1167 11AB; # (연; 연; 연; 연; 연; ) HANGUL SYLLABLE YEON
+C5F1;C5F1;110B 1167 11AC;C5F1;110B 1167 11AC; # (엱; 엱; 엱; 엱; 엱; ) HANGUL SYLLABLE YEONJ
+C5F2;C5F2;110B 1167 11AD;C5F2;110B 1167 11AD; # (엲; 엲; 엲; 엲; 엲; ) HANGUL SYLLABLE YEONH
+C5F3;C5F3;110B 1167 11AE;C5F3;110B 1167 11AE; # (엳; 엳; 엳; 엳; 엳; ) HANGUL SYLLABLE YEOD
+C5F4;C5F4;110B 1167 11AF;C5F4;110B 1167 11AF; # (열; 열; 열; 열; 열; ) HANGUL SYLLABLE YEOL
+C5F5;C5F5;110B 1167 11B0;C5F5;110B 1167 11B0; # (엵; 엵; 엵; 엵; 엵; ) HANGUL SYLLABLE YEOLG
+C5F6;C5F6;110B 1167 11B1;C5F6;110B 1167 11B1; # (엶; 엶; 엶; 엶; 엶; ) HANGUL SYLLABLE YEOLM
+C5F7;C5F7;110B 1167 11B2;C5F7;110B 1167 11B2; # (엷; 엷; 엷; 엷; 엷; ) HANGUL SYLLABLE YEOLB
+C5F8;C5F8;110B 1167 11B3;C5F8;110B 1167 11B3; # (엸; 엸; 엸; 엸; 엸; ) HANGUL SYLLABLE YEOLS
+C5F9;C5F9;110B 1167 11B4;C5F9;110B 1167 11B4; # (엹; 엹; 엹; 엹; 엹; ) HANGUL SYLLABLE YEOLT
+C5FA;C5FA;110B 1167 11B5;C5FA;110B 1167 11B5; # (엺; 엺; 엺; 엺; 엺; ) HANGUL SYLLABLE YEOLP
+C5FB;C5FB;110B 1167 11B6;C5FB;110B 1167 11B6; # (엻; 엻; 엻; 엻; 엻; ) HANGUL SYLLABLE YEOLH
+C5FC;C5FC;110B 1167 11B7;C5FC;110B 1167 11B7; # (염; 염; 염; 염; 염; ) HANGUL SYLLABLE YEOM
+C5FD;C5FD;110B 1167 11B8;C5FD;110B 1167 11B8; # (엽; 엽; 엽; 엽; 엽; ) HANGUL SYLLABLE YEOB
+C5FE;C5FE;110B 1167 11B9;C5FE;110B 1167 11B9; # (엾; 엾; 엾; 엾; 엾; ) HANGUL SYLLABLE YEOBS
+C5FF;C5FF;110B 1167 11BA;C5FF;110B 1167 11BA; # (엿; 엿; 엿; 엿; 엿; ) HANGUL SYLLABLE YEOS
+C600;C600;110B 1167 11BB;C600;110B 1167 11BB; # (였; 였; 였; 였; 였; ) HANGUL SYLLABLE YEOSS
+C601;C601;110B 1167 11BC;C601;110B 1167 11BC; # (영; 영; 영; 영; 영; ) HANGUL SYLLABLE YEONG
+C602;C602;110B 1167 11BD;C602;110B 1167 11BD; # (옂; 옂; 옂; 옂; 옂; ) HANGUL SYLLABLE YEOJ
+C603;C603;110B 1167 11BE;C603;110B 1167 11BE; # (옃; 옃; 옃; 옃; 옃; ) HANGUL SYLLABLE YEOC
+C604;C604;110B 1167 11BF;C604;110B 1167 11BF; # (옄; 옄; 옄; 옄; 옄; ) HANGUL SYLLABLE YEOK
+C605;C605;110B 1167 11C0;C605;110B 1167 11C0; # (옅; 옅; 옅; 옅; 옅; ) HANGUL SYLLABLE YEOT
+C606;C606;110B 1167 11C1;C606;110B 1167 11C1; # (옆; 옆; 옆; 옆; 옆; ) HANGUL SYLLABLE YEOP
+C607;C607;110B 1167 11C2;C607;110B 1167 11C2; # (옇; 옇; 옇; 옇; 옇; ) HANGUL SYLLABLE YEOH
+C608;C608;110B 1168;C608;110B 1168; # (예; 예; 예; 예; 예; ) HANGUL SYLLABLE YE
+C609;C609;110B 1168 11A8;C609;110B 1168 11A8; # (옉; 옉; 옉; 옉; 옉; ) HANGUL SYLLABLE YEG
+C60A;C60A;110B 1168 11A9;C60A;110B 1168 11A9; # (옊; 옊; 옊; 옊; 옊; ) HANGUL SYLLABLE YEGG
+C60B;C60B;110B 1168 11AA;C60B;110B 1168 11AA; # (옋; 옋; 옋; 옋; 옋; ) HANGUL SYLLABLE YEGS
+C60C;C60C;110B 1168 11AB;C60C;110B 1168 11AB; # (옌; 옌; 옌; 옌; 옌; ) HANGUL SYLLABLE YEN
+C60D;C60D;110B 1168 11AC;C60D;110B 1168 11AC; # (옍; 옍; 옍; 옍; 옍; ) HANGUL SYLLABLE YENJ
+C60E;C60E;110B 1168 11AD;C60E;110B 1168 11AD; # (옎; 옎; 옎; 옎; 옎; ) HANGUL SYLLABLE YENH
+C60F;C60F;110B 1168 11AE;C60F;110B 1168 11AE; # (옏; 옏; 옏; 옏; 옏; ) HANGUL SYLLABLE YED
+C610;C610;110B 1168 11AF;C610;110B 1168 11AF; # (옐; 옐; 옐; 옐; 옐; ) HANGUL SYLLABLE YEL
+C611;C611;110B 1168 11B0;C611;110B 1168 11B0; # (옑; 옑; 옑; 옑; 옑; ) HANGUL SYLLABLE YELG
+C612;C612;110B 1168 11B1;C612;110B 1168 11B1; # (옒; 옒; 옒; 옒; 옒; ) HANGUL SYLLABLE YELM
+C613;C613;110B 1168 11B2;C613;110B 1168 11B2; # (옓; 옓; 옓; 옓; 옓; ) HANGUL SYLLABLE YELB
+C614;C614;110B 1168 11B3;C614;110B 1168 11B3; # (옔; 옔; 옔; 옔; 옔; ) HANGUL SYLLABLE YELS
+C615;C615;110B 1168 11B4;C615;110B 1168 11B4; # (옕; 옕; 옕; 옕; 옕; ) HANGUL SYLLABLE YELT
+C616;C616;110B 1168 11B5;C616;110B 1168 11B5; # (옖; 옖; 옖; 옖; 옖; ) HANGUL SYLLABLE YELP
+C617;C617;110B 1168 11B6;C617;110B 1168 11B6; # (옗; 옗; 옗; 옗; 옗; ) HANGUL SYLLABLE YELH
+C618;C618;110B 1168 11B7;C618;110B 1168 11B7; # (옘; 옘; 옘; 옘; 옘; ) HANGUL SYLLABLE YEM
+C619;C619;110B 1168 11B8;C619;110B 1168 11B8; # (옙; 옙; 옙; 옙; 옙; ) HANGUL SYLLABLE YEB
+C61A;C61A;110B 1168 11B9;C61A;110B 1168 11B9; # (옚; 옚; 옚; 옚; 옚; ) HANGUL SYLLABLE YEBS
+C61B;C61B;110B 1168 11BA;C61B;110B 1168 11BA; # (옛; 옛; 옛; 옛; 옛; ) HANGUL SYLLABLE YES
+C61C;C61C;110B 1168 11BB;C61C;110B 1168 11BB; # (옜; 옜; 옜; 옜; 옜; ) HANGUL SYLLABLE YESS
+C61D;C61D;110B 1168 11BC;C61D;110B 1168 11BC; # (옝; 옝; 옝; 옝; 옝; ) HANGUL SYLLABLE YENG
+C61E;C61E;110B 1168 11BD;C61E;110B 1168 11BD; # (옞; 옞; 옞; 옞; 옞; ) HANGUL SYLLABLE YEJ
+C61F;C61F;110B 1168 11BE;C61F;110B 1168 11BE; # (옟; 옟; 옟; 옟; 옟; ) HANGUL SYLLABLE YEC
+C620;C620;110B 1168 11BF;C620;110B 1168 11BF; # (옠; 옠; 옠; 옠; 옠; ) HANGUL SYLLABLE YEK
+C621;C621;110B 1168 11C0;C621;110B 1168 11C0; # (옡; 옡; 옡; 옡; 옡; ) HANGUL SYLLABLE YET
+C622;C622;110B 1168 11C1;C622;110B 1168 11C1; # (옢; 옢; 옢; 옢; 옢; ) HANGUL SYLLABLE YEP
+C623;C623;110B 1168 11C2;C623;110B 1168 11C2; # (옣; 옣; 옣; 옣; 옣; ) HANGUL SYLLABLE YEH
+C624;C624;110B 1169;C624;110B 1169; # (오; 오; 오; 오; 오; ) HANGUL SYLLABLE O
+C625;C625;110B 1169 11A8;C625;110B 1169 11A8; # (옥; 옥; 옥; 옥; 옥; ) HANGUL SYLLABLE OG
+C626;C626;110B 1169 11A9;C626;110B 1169 11A9; # (옦; 옦; 옦; 옦; 옦; ) HANGUL SYLLABLE OGG
+C627;C627;110B 1169 11AA;C627;110B 1169 11AA; # (옧; 옧; 옧; 옧; 옧; ) HANGUL SYLLABLE OGS
+C628;C628;110B 1169 11AB;C628;110B 1169 11AB; # (온; 온; 온; 온; 온; ) HANGUL SYLLABLE ON
+C629;C629;110B 1169 11AC;C629;110B 1169 11AC; # (옩; 옩; 옩; 옩; 옩; ) HANGUL SYLLABLE ONJ
+C62A;C62A;110B 1169 11AD;C62A;110B 1169 11AD; # (옪; 옪; 옪; 옪; 옪; ) HANGUL SYLLABLE ONH
+C62B;C62B;110B 1169 11AE;C62B;110B 1169 11AE; # (옫; 옫; 옫; 옫; 옫; ) HANGUL SYLLABLE OD
+C62C;C62C;110B 1169 11AF;C62C;110B 1169 11AF; # (올; 올; 올; 올; 올; ) HANGUL SYLLABLE OL
+C62D;C62D;110B 1169 11B0;C62D;110B 1169 11B0; # (옭; 옭; 옭; 옭; 옭; ) HANGUL SYLLABLE OLG
+C62E;C62E;110B 1169 11B1;C62E;110B 1169 11B1; # (옮; 옮; 옮; 옮; 옮; ) HANGUL SYLLABLE OLM
+C62F;C62F;110B 1169 11B2;C62F;110B 1169 11B2; # (옯; 옯; 옯; 옯; 옯; ) HANGUL SYLLABLE OLB
+C630;C630;110B 1169 11B3;C630;110B 1169 11B3; # (옰; 옰; 옰; 옰; 옰; ) HANGUL SYLLABLE OLS
+C631;C631;110B 1169 11B4;C631;110B 1169 11B4; # (옱; 옱; 옱; 옱; 옱; ) HANGUL SYLLABLE OLT
+C632;C632;110B 1169 11B5;C632;110B 1169 11B5; # (옲; 옲; 옲; 옲; 옲; ) HANGUL SYLLABLE OLP
+C633;C633;110B 1169 11B6;C633;110B 1169 11B6; # (옳; 옳; 옳; 옳; 옳; ) HANGUL SYLLABLE OLH
+C634;C634;110B 1169 11B7;C634;110B 1169 11B7; # (옴; 옴; 옴; 옴; 옴; ) HANGUL SYLLABLE OM
+C635;C635;110B 1169 11B8;C635;110B 1169 11B8; # (옵; 옵; 옵; 옵; 옵; ) HANGUL SYLLABLE OB
+C636;C636;110B 1169 11B9;C636;110B 1169 11B9; # (옶; 옶; 옶; 옶; 옶; ) HANGUL SYLLABLE OBS
+C637;C637;110B 1169 11BA;C637;110B 1169 11BA; # (옷; 옷; 옷; 옷; 옷; ) HANGUL SYLLABLE OS
+C638;C638;110B 1169 11BB;C638;110B 1169 11BB; # (옸; 옸; 옸; 옸; 옸; ) HANGUL SYLLABLE OSS
+C639;C639;110B 1169 11BC;C639;110B 1169 11BC; # (옹; 옹; 옹; 옹; 옹; ) HANGUL SYLLABLE ONG
+C63A;C63A;110B 1169 11BD;C63A;110B 1169 11BD; # (옺; 옺; 옺; 옺; 옺; ) HANGUL SYLLABLE OJ
+C63B;C63B;110B 1169 11BE;C63B;110B 1169 11BE; # (옻; 옻; 옻; 옻; 옻; ) HANGUL SYLLABLE OC
+C63C;C63C;110B 1169 11BF;C63C;110B 1169 11BF; # (옼; 옼; 옼; 옼; 옼; ) HANGUL SYLLABLE OK
+C63D;C63D;110B 1169 11C0;C63D;110B 1169 11C0; # (옽; 옽; 옽; 옽; 옽; ) HANGUL SYLLABLE OT
+C63E;C63E;110B 1169 11C1;C63E;110B 1169 11C1; # (옾; 옾; 옾; 옾; 옾; ) HANGUL SYLLABLE OP
+C63F;C63F;110B 1169 11C2;C63F;110B 1169 11C2; # (옿; 옿; 옿; 옿; 옿; ) HANGUL SYLLABLE OH
+C640;C640;110B 116A;C640;110B 116A; # (와; 와; 와; 와; 와; ) HANGUL SYLLABLE WA
+C641;C641;110B 116A 11A8;C641;110B 116A 11A8; # (왁; 왁; 왁; 왁; 왁; ) HANGUL SYLLABLE WAG
+C642;C642;110B 116A 11A9;C642;110B 116A 11A9; # (왂; 왂; 왂; 왂; 왂; ) HANGUL SYLLABLE WAGG
+C643;C643;110B 116A 11AA;C643;110B 116A 11AA; # (왃; 왃; 왃; 왃; 왃; ) HANGUL SYLLABLE WAGS
+C644;C644;110B 116A 11AB;C644;110B 116A 11AB; # (완; 완; 완; 완; 완; ) HANGUL SYLLABLE WAN
+C645;C645;110B 116A 11AC;C645;110B 116A 11AC; # (왅; 왅; 왅; 왅; 왅; ) HANGUL SYLLABLE WANJ
+C646;C646;110B 116A 11AD;C646;110B 116A 11AD; # (왆; 왆; 왆; 왆; 왆; ) HANGUL SYLLABLE WANH
+C647;C647;110B 116A 11AE;C647;110B 116A 11AE; # (왇; 왇; 왇; 왇; 왇; ) HANGUL SYLLABLE WAD
+C648;C648;110B 116A 11AF;C648;110B 116A 11AF; # (왈; 왈; 왈; 왈; 왈; ) HANGUL SYLLABLE WAL
+C649;C649;110B 116A 11B0;C649;110B 116A 11B0; # (왉; 왉; 왉; 왉; 왉; ) HANGUL SYLLABLE WALG
+C64A;C64A;110B 116A 11B1;C64A;110B 116A 11B1; # (왊; 왊; 왊; 왊; 왊; ) HANGUL SYLLABLE WALM
+C64B;C64B;110B 116A 11B2;C64B;110B 116A 11B2; # (왋; 왋; 왋; 왋; 왋; ) HANGUL SYLLABLE WALB
+C64C;C64C;110B 116A 11B3;C64C;110B 116A 11B3; # (왌; 왌; 왌; 왌; 왌; ) HANGUL SYLLABLE WALS
+C64D;C64D;110B 116A 11B4;C64D;110B 116A 11B4; # (왍; 왍; 왍; 왍; 왍; ) HANGUL SYLLABLE WALT
+C64E;C64E;110B 116A 11B5;C64E;110B 116A 11B5; # (왎; 왎; 왎; 왎; 왎; ) HANGUL SYLLABLE WALP
+C64F;C64F;110B 116A 11B6;C64F;110B 116A 11B6; # (왏; 왏; 왏; 왏; 왏; ) HANGUL SYLLABLE WALH
+C650;C650;110B 116A 11B7;C650;110B 116A 11B7; # (왐; 왐; 왐; 왐; 왐; ) HANGUL SYLLABLE WAM
+C651;C651;110B 116A 11B8;C651;110B 116A 11B8; # (왑; 왑; 왑; 왑; 왑; ) HANGUL SYLLABLE WAB
+C652;C652;110B 116A 11B9;C652;110B 116A 11B9; # (왒; 왒; 왒; 왒; 왒; ) HANGUL SYLLABLE WABS
+C653;C653;110B 116A 11BA;C653;110B 116A 11BA; # (왓; 왓; 왓; 왓; 왓; ) HANGUL SYLLABLE WAS
+C654;C654;110B 116A 11BB;C654;110B 116A 11BB; # (왔; 왔; 왔; 왔; 왔; ) HANGUL SYLLABLE WASS
+C655;C655;110B 116A 11BC;C655;110B 116A 11BC; # (왕; 왕; 왕; 왕; 왕; ) HANGUL SYLLABLE WANG
+C656;C656;110B 116A 11BD;C656;110B 116A 11BD; # (왖; 왖; 왖; 왖; 왖; ) HANGUL SYLLABLE WAJ
+C657;C657;110B 116A 11BE;C657;110B 116A 11BE; # (왗; 왗; 왗; 왗; 왗; ) HANGUL SYLLABLE WAC
+C658;C658;110B 116A 11BF;C658;110B 116A 11BF; # (왘; 왘; 왘; 왘; 왘; ) HANGUL SYLLABLE WAK
+C659;C659;110B 116A 11C0;C659;110B 116A 11C0; # (왙; 왙; 왙; 왙; 왙; ) HANGUL SYLLABLE WAT
+C65A;C65A;110B 116A 11C1;C65A;110B 116A 11C1; # (왚; 왚; 왚; 왚; 왚; ) HANGUL SYLLABLE WAP
+C65B;C65B;110B 116A 11C2;C65B;110B 116A 11C2; # (왛; 왛; 왛; 왛; 왛; ) HANGUL SYLLABLE WAH
+C65C;C65C;110B 116B;C65C;110B 116B; # (왜; 왜; 왜; 왜; 왜; ) HANGUL SYLLABLE WAE
+C65D;C65D;110B 116B 11A8;C65D;110B 116B 11A8; # (왝; 왝; 왝; 왝; 왝; ) HANGUL SYLLABLE WAEG
+C65E;C65E;110B 116B 11A9;C65E;110B 116B 11A9; # (왞; 왞; 왞; 왞; 왞; ) HANGUL SYLLABLE WAEGG
+C65F;C65F;110B 116B 11AA;C65F;110B 116B 11AA; # (왟; 왟; 왟; 왟; 왟; ) HANGUL SYLLABLE WAEGS
+C660;C660;110B 116B 11AB;C660;110B 116B 11AB; # (왠; 왠; 왠; 왠; 왠; ) HANGUL SYLLABLE WAEN
+C661;C661;110B 116B 11AC;C661;110B 116B 11AC; # (왡; 왡; 왡; 왡; 왡; ) HANGUL SYLLABLE WAENJ
+C662;C662;110B 116B 11AD;C662;110B 116B 11AD; # (왢; 왢; 왢; 왢; 왢; ) HANGUL SYLLABLE WAENH
+C663;C663;110B 116B 11AE;C663;110B 116B 11AE; # (왣; 왣; 왣; 왣; 왣; ) HANGUL SYLLABLE WAED
+C664;C664;110B 116B 11AF;C664;110B 116B 11AF; # (왤; 왤; 왤; 왤; 왤; ) HANGUL SYLLABLE WAEL
+C665;C665;110B 116B 11B0;C665;110B 116B 11B0; # (왥; 왥; 왥; 왥; 왥; ) HANGUL SYLLABLE WAELG
+C666;C666;110B 116B 11B1;C666;110B 116B 11B1; # (왦; 왦; 왦; 왦; 왦; ) HANGUL SYLLABLE WAELM
+C667;C667;110B 116B 11B2;C667;110B 116B 11B2; # (왧; 왧; 왧; 왧; 왧; ) HANGUL SYLLABLE WAELB
+C668;C668;110B 116B 11B3;C668;110B 116B 11B3; # (왨; 왨; 왨; 왨; 왨; ) HANGUL SYLLABLE WAELS
+C669;C669;110B 116B 11B4;C669;110B 116B 11B4; # (왩; 왩; 왩; 왩; 왩; ) HANGUL SYLLABLE WAELT
+C66A;C66A;110B 116B 11B5;C66A;110B 116B 11B5; # (왪; 왪; 왪; 왪; 왪; ) HANGUL SYLLABLE WAELP
+C66B;C66B;110B 116B 11B6;C66B;110B 116B 11B6; # (왫; 왫; 왫; 왫; 왫; ) HANGUL SYLLABLE WAELH
+C66C;C66C;110B 116B 11B7;C66C;110B 116B 11B7; # (왬; 왬; 왬; 왬; 왬; ) HANGUL SYLLABLE WAEM
+C66D;C66D;110B 116B 11B8;C66D;110B 116B 11B8; # (왭; 왭; 왭; 왭; 왭; ) HANGUL SYLLABLE WAEB
+C66E;C66E;110B 116B 11B9;C66E;110B 116B 11B9; # (왮; 왮; 왮; 왮; 왮; ) HANGUL SYLLABLE WAEBS
+C66F;C66F;110B 116B 11BA;C66F;110B 116B 11BA; # (왯; 왯; 왯; 왯; 왯; ) HANGUL SYLLABLE WAES
+C670;C670;110B 116B 11BB;C670;110B 116B 11BB; # (왰; 왰; 왰; 왰; 왰; ) HANGUL SYLLABLE WAESS
+C671;C671;110B 116B 11BC;C671;110B 116B 11BC; # (왱; 왱; 왱; 왱; 왱; ) HANGUL SYLLABLE WAENG
+C672;C672;110B 116B 11BD;C672;110B 116B 11BD; # (왲; 왲; 왲; 왲; 왲; ) HANGUL SYLLABLE WAEJ
+C673;C673;110B 116B 11BE;C673;110B 116B 11BE; # (왳; 왳; 왳; 왳; 왳; ) HANGUL SYLLABLE WAEC
+C674;C674;110B 116B 11BF;C674;110B 116B 11BF; # (왴; 왴; 왴; 왴; 왴; ) HANGUL SYLLABLE WAEK
+C675;C675;110B 116B 11C0;C675;110B 116B 11C0; # (왵; 왵; 왵; 왵; 왵; ) HANGUL SYLLABLE WAET
+C676;C676;110B 116B 11C1;C676;110B 116B 11C1; # (왶; 왶; 왶; 왶; 왶; ) HANGUL SYLLABLE WAEP
+C677;C677;110B 116B 11C2;C677;110B 116B 11C2; # (왷; 왷; 왷; 왷; 왷; ) HANGUL SYLLABLE WAEH
+C678;C678;110B 116C;C678;110B 116C; # (외; 외; 외; 외; 외; ) HANGUL SYLLABLE OE
+C679;C679;110B 116C 11A8;C679;110B 116C 11A8; # (왹; 왹; 왹; 왹; 왹; ) HANGUL SYLLABLE OEG
+C67A;C67A;110B 116C 11A9;C67A;110B 116C 11A9; # (왺; 왺; 왺; 왺; 왺; ) HANGUL SYLLABLE OEGG
+C67B;C67B;110B 116C 11AA;C67B;110B 116C 11AA; # (왻; 왻; 왻; 왻; 왻; ) HANGUL SYLLABLE OEGS
+C67C;C67C;110B 116C 11AB;C67C;110B 116C 11AB; # (왼; 왼; 왼; 왼; 왼; ) HANGUL SYLLABLE OEN
+C67D;C67D;110B 116C 11AC;C67D;110B 116C 11AC; # (왽; 왽; 왽; 왽; 왽; ) HANGUL SYLLABLE OENJ
+C67E;C67E;110B 116C 11AD;C67E;110B 116C 11AD; # (왾; 왾; 왾; 왾; 왾; ) HANGUL SYLLABLE OENH
+C67F;C67F;110B 116C 11AE;C67F;110B 116C 11AE; # (왿; 왿; 왿; 왿; 왿; ) HANGUL SYLLABLE OED
+C680;C680;110B 116C 11AF;C680;110B 116C 11AF; # (욀; 욀; 욀; 욀; 욀; ) HANGUL SYLLABLE OEL
+C681;C681;110B 116C 11B0;C681;110B 116C 11B0; # (욁; 욁; 욁; 욁; 욁; ) HANGUL SYLLABLE OELG
+C682;C682;110B 116C 11B1;C682;110B 116C 11B1; # (욂; 욂; 욂; 욂; 욂; ) HANGUL SYLLABLE OELM
+C683;C683;110B 116C 11B2;C683;110B 116C 11B2; # (욃; 욃; 욃; 욃; 욃; ) HANGUL SYLLABLE OELB
+C684;C684;110B 116C 11B3;C684;110B 116C 11B3; # (욄; 욄; 욄; 욄; 욄; ) HANGUL SYLLABLE OELS
+C685;C685;110B 116C 11B4;C685;110B 116C 11B4; # (욅; 욅; 욅; 욅; 욅; ) HANGUL SYLLABLE OELT
+C686;C686;110B 116C 11B5;C686;110B 116C 11B5; # (욆; 욆; 욆; 욆; 욆; ) HANGUL SYLLABLE OELP
+C687;C687;110B 116C 11B6;C687;110B 116C 11B6; # (욇; 욇; 욇; 욇; 욇; ) HANGUL SYLLABLE OELH
+C688;C688;110B 116C 11B7;C688;110B 116C 11B7; # (욈; 욈; 욈; 욈; 욈; ) HANGUL SYLLABLE OEM
+C689;C689;110B 116C 11B8;C689;110B 116C 11B8; # (욉; 욉; 욉; 욉; 욉; ) HANGUL SYLLABLE OEB
+C68A;C68A;110B 116C 11B9;C68A;110B 116C 11B9; # (욊; 욊; 욊; 욊; 욊; ) HANGUL SYLLABLE OEBS
+C68B;C68B;110B 116C 11BA;C68B;110B 116C 11BA; # (욋; 욋; 욋; 욋; 욋; ) HANGUL SYLLABLE OES
+C68C;C68C;110B 116C 11BB;C68C;110B 116C 11BB; # (욌; 욌; 욌; 욌; 욌; ) HANGUL SYLLABLE OESS
+C68D;C68D;110B 116C 11BC;C68D;110B 116C 11BC; # (욍; 욍; 욍; 욍; 욍; ) HANGUL SYLLABLE OENG
+C68E;C68E;110B 116C 11BD;C68E;110B 116C 11BD; # (욎; 욎; 욎; 욎; 욎; ) HANGUL SYLLABLE OEJ
+C68F;C68F;110B 116C 11BE;C68F;110B 116C 11BE; # (욏; 욏; 욏; 욏; 욏; ) HANGUL SYLLABLE OEC
+C690;C690;110B 116C 11BF;C690;110B 116C 11BF; # (욐; 욐; 욐; 욐; 욐; ) HANGUL SYLLABLE OEK
+C691;C691;110B 116C 11C0;C691;110B 116C 11C0; # (욑; 욑; 욑; 욑; 욑; ) HANGUL SYLLABLE OET
+C692;C692;110B 116C 11C1;C692;110B 116C 11C1; # (욒; 욒; 욒; 욒; 욒; ) HANGUL SYLLABLE OEP
+C693;C693;110B 116C 11C2;C693;110B 116C 11C2; # (욓; 욓; 욓; 욓; 욓; ) HANGUL SYLLABLE OEH
+C694;C694;110B 116D;C694;110B 116D; # (요; 요; 요; 요; 요; ) HANGUL SYLLABLE YO
+C695;C695;110B 116D 11A8;C695;110B 116D 11A8; # (욕; 욕; 욕; 욕; 욕; ) HANGUL SYLLABLE YOG
+C696;C696;110B 116D 11A9;C696;110B 116D 11A9; # (욖; 욖; 욖; 욖; 욖; ) HANGUL SYLLABLE YOGG
+C697;C697;110B 116D 11AA;C697;110B 116D 11AA; # (욗; 욗; 욗; 욗; 욗; ) HANGUL SYLLABLE YOGS
+C698;C698;110B 116D 11AB;C698;110B 116D 11AB; # (욘; 욘; 욘; 욘; 욘; ) HANGUL SYLLABLE YON
+C699;C699;110B 116D 11AC;C699;110B 116D 11AC; # (욙; 욙; 욙; 욙; 욙; ) HANGUL SYLLABLE YONJ
+C69A;C69A;110B 116D 11AD;C69A;110B 116D 11AD; # (욚; 욚; 욚; 욚; 욚; ) HANGUL SYLLABLE YONH
+C69B;C69B;110B 116D 11AE;C69B;110B 116D 11AE; # (욛; 욛; 욛; 욛; 욛; ) HANGUL SYLLABLE YOD
+C69C;C69C;110B 116D 11AF;C69C;110B 116D 11AF; # (욜; 욜; 욜; 욜; 욜; ) HANGUL SYLLABLE YOL
+C69D;C69D;110B 116D 11B0;C69D;110B 116D 11B0; # (욝; 욝; 욝; 욝; 욝; ) HANGUL SYLLABLE YOLG
+C69E;C69E;110B 116D 11B1;C69E;110B 116D 11B1; # (욞; 욞; 욞; 욞; 욞; ) HANGUL SYLLABLE YOLM
+C69F;C69F;110B 116D 11B2;C69F;110B 116D 11B2; # (욟; 욟; 욟; 욟; 욟; ) HANGUL SYLLABLE YOLB
+C6A0;C6A0;110B 116D 11B3;C6A0;110B 116D 11B3; # (욠; 욠; 욠; 욠; 욠; ) HANGUL SYLLABLE YOLS
+C6A1;C6A1;110B 116D 11B4;C6A1;110B 116D 11B4; # (욡; 욡; 욡; 욡; 욡; ) HANGUL SYLLABLE YOLT
+C6A2;C6A2;110B 116D 11B5;C6A2;110B 116D 11B5; # (욢; 욢; 욢; 욢; 욢; ) HANGUL SYLLABLE YOLP
+C6A3;C6A3;110B 116D 11B6;C6A3;110B 116D 11B6; # (욣; 욣; 욣; 욣; 욣; ) HANGUL SYLLABLE YOLH
+C6A4;C6A4;110B 116D 11B7;C6A4;110B 116D 11B7; # (욤; 욤; 욤; 욤; 욤; ) HANGUL SYLLABLE YOM
+C6A5;C6A5;110B 116D 11B8;C6A5;110B 116D 11B8; # (욥; 욥; 욥; 욥; 욥; ) HANGUL SYLLABLE YOB
+C6A6;C6A6;110B 116D 11B9;C6A6;110B 116D 11B9; # (욦; 욦; 욦; 욦; 욦; ) HANGUL SYLLABLE YOBS
+C6A7;C6A7;110B 116D 11BA;C6A7;110B 116D 11BA; # (욧; 욧; 욧; 욧; 욧; ) HANGUL SYLLABLE YOS
+C6A8;C6A8;110B 116D 11BB;C6A8;110B 116D 11BB; # (욨; 욨; 욨; 욨; 욨; ) HANGUL SYLLABLE YOSS
+C6A9;C6A9;110B 116D 11BC;C6A9;110B 116D 11BC; # (용; 용; 용; 용; 용; ) HANGUL SYLLABLE YONG
+C6AA;C6AA;110B 116D 11BD;C6AA;110B 116D 11BD; # (욪; 욪; 욪; 욪; 욪; ) HANGUL SYLLABLE YOJ
+C6AB;C6AB;110B 116D 11BE;C6AB;110B 116D 11BE; # (욫; 욫; 욫; 욫; 욫; ) HANGUL SYLLABLE YOC
+C6AC;C6AC;110B 116D 11BF;C6AC;110B 116D 11BF; # (욬; 욬; 욬; 욬; 욬; ) HANGUL SYLLABLE YOK
+C6AD;C6AD;110B 116D 11C0;C6AD;110B 116D 11C0; # (욭; 욭; 욭; 욭; 욭; ) HANGUL SYLLABLE YOT
+C6AE;C6AE;110B 116D 11C1;C6AE;110B 116D 11C1; # (욮; 욮; 욮; 욮; 욮; ) HANGUL SYLLABLE YOP
+C6AF;C6AF;110B 116D 11C2;C6AF;110B 116D 11C2; # (욯; 욯; 욯; 욯; 욯; ) HANGUL SYLLABLE YOH
+C6B0;C6B0;110B 116E;C6B0;110B 116E; # (우; 우; 우; 우; 우; ) HANGUL SYLLABLE U
+C6B1;C6B1;110B 116E 11A8;C6B1;110B 116E 11A8; # (욱; 욱; 욱; 욱; 욱; ) HANGUL SYLLABLE UG
+C6B2;C6B2;110B 116E 11A9;C6B2;110B 116E 11A9; # (욲; 욲; 욲; 욲; 욲; ) HANGUL SYLLABLE UGG
+C6B3;C6B3;110B 116E 11AA;C6B3;110B 116E 11AA; # (욳; 욳; 욳; 욳; 욳; ) HANGUL SYLLABLE UGS
+C6B4;C6B4;110B 116E 11AB;C6B4;110B 116E 11AB; # (운; 운; 운; 운; 운; ) HANGUL SYLLABLE UN
+C6B5;C6B5;110B 116E 11AC;C6B5;110B 116E 11AC; # (욵; 욵; 욵; 욵; 욵; ) HANGUL SYLLABLE UNJ
+C6B6;C6B6;110B 116E 11AD;C6B6;110B 116E 11AD; # (욶; 욶; 욶; 욶; 욶; ) HANGUL SYLLABLE UNH
+C6B7;C6B7;110B 116E 11AE;C6B7;110B 116E 11AE; # (욷; 욷; 욷; 욷; 욷; ) HANGUL SYLLABLE UD
+C6B8;C6B8;110B 116E 11AF;C6B8;110B 116E 11AF; # (울; 울; 울; 울; 울; ) HANGUL SYLLABLE UL
+C6B9;C6B9;110B 116E 11B0;C6B9;110B 116E 11B0; # (욹; 욹; 욹; 욹; 욹; ) HANGUL SYLLABLE ULG
+C6BA;C6BA;110B 116E 11B1;C6BA;110B 116E 11B1; # (욺; 욺; 욺; 욺; 욺; ) HANGUL SYLLABLE ULM
+C6BB;C6BB;110B 116E 11B2;C6BB;110B 116E 11B2; # (욻; 욻; 욻; 욻; 욻; ) HANGUL SYLLABLE ULB
+C6BC;C6BC;110B 116E 11B3;C6BC;110B 116E 11B3; # (욼; 욼; 욼; 욼; 욼; ) HANGUL SYLLABLE ULS
+C6BD;C6BD;110B 116E 11B4;C6BD;110B 116E 11B4; # (욽; 욽; 욽; 욽; 욽; ) HANGUL SYLLABLE ULT
+C6BE;C6BE;110B 116E 11B5;C6BE;110B 116E 11B5; # (욾; 욾; 욾; 욾; 욾; ) HANGUL SYLLABLE ULP
+C6BF;C6BF;110B 116E 11B6;C6BF;110B 116E 11B6; # (욿; 욿; 욿; 욿; 욿; ) HANGUL SYLLABLE ULH
+C6C0;C6C0;110B 116E 11B7;C6C0;110B 116E 11B7; # (움; 움; 움; 움; 움; ) HANGUL SYLLABLE UM
+C6C1;C6C1;110B 116E 11B8;C6C1;110B 116E 11B8; # (웁; 웁; 웁; 웁; 웁; ) HANGUL SYLLABLE UB
+C6C2;C6C2;110B 116E 11B9;C6C2;110B 116E 11B9; # (웂; 웂; 웂; 웂; 웂; ) HANGUL SYLLABLE UBS
+C6C3;C6C3;110B 116E 11BA;C6C3;110B 116E 11BA; # (웃; 웃; 웃; 웃; 웃; ) HANGUL SYLLABLE US
+C6C4;C6C4;110B 116E 11BB;C6C4;110B 116E 11BB; # (웄; 웄; 웄; 웄; 웄; ) HANGUL SYLLABLE USS
+C6C5;C6C5;110B 116E 11BC;C6C5;110B 116E 11BC; # (웅; 웅; 웅; 웅; 웅; ) HANGUL SYLLABLE UNG
+C6C6;C6C6;110B 116E 11BD;C6C6;110B 116E 11BD; # (웆; 웆; 웆; 웆; 웆; ) HANGUL SYLLABLE UJ
+C6C7;C6C7;110B 116E 11BE;C6C7;110B 116E 11BE; # (웇; 웇; 웇; 웇; 웇; ) HANGUL SYLLABLE UC
+C6C8;C6C8;110B 116E 11BF;C6C8;110B 116E 11BF; # (웈; 웈; 웈; 웈; 웈; ) HANGUL SYLLABLE UK
+C6C9;C6C9;110B 116E 11C0;C6C9;110B 116E 11C0; # (웉; 웉; 웉; 웉; 웉; ) HANGUL SYLLABLE UT
+C6CA;C6CA;110B 116E 11C1;C6CA;110B 116E 11C1; # (웊; 웊; 웊; 웊; 웊; ) HANGUL SYLLABLE UP
+C6CB;C6CB;110B 116E 11C2;C6CB;110B 116E 11C2; # (웋; 웋; 웋; 웋; 웋; ) HANGUL SYLLABLE UH
+C6CC;C6CC;110B 116F;C6CC;110B 116F; # (워; 워; 워; 워; 워; ) HANGUL SYLLABLE WEO
+C6CD;C6CD;110B 116F 11A8;C6CD;110B 116F 11A8; # (웍; 웍; 웍; 웍; 웍; ) HANGUL SYLLABLE WEOG
+C6CE;C6CE;110B 116F 11A9;C6CE;110B 116F 11A9; # (웎; 웎; 웎; 웎; 웎; ) HANGUL SYLLABLE WEOGG
+C6CF;C6CF;110B 116F 11AA;C6CF;110B 116F 11AA; # (웏; 웏; 웏; 웏; 웏; ) HANGUL SYLLABLE WEOGS
+C6D0;C6D0;110B 116F 11AB;C6D0;110B 116F 11AB; # (원; 원; 원; 원; 원; ) HANGUL SYLLABLE WEON
+C6D1;C6D1;110B 116F 11AC;C6D1;110B 116F 11AC; # (웑; 웑; 웑; 웑; 웑; ) HANGUL SYLLABLE WEONJ
+C6D2;C6D2;110B 116F 11AD;C6D2;110B 116F 11AD; # (웒; 웒; 웒; 웒; 웒; ) HANGUL SYLLABLE WEONH
+C6D3;C6D3;110B 116F 11AE;C6D3;110B 116F 11AE; # (웓; 웓; 웓; 웓; 웓; ) HANGUL SYLLABLE WEOD
+C6D4;C6D4;110B 116F 11AF;C6D4;110B 116F 11AF; # (월; 월; 월; 월; 월; ) HANGUL SYLLABLE WEOL
+C6D5;C6D5;110B 116F 11B0;C6D5;110B 116F 11B0; # (웕; 웕; 웕; 웕; 웕; ) HANGUL SYLLABLE WEOLG
+C6D6;C6D6;110B 116F 11B1;C6D6;110B 116F 11B1; # (웖; 웖; 웖; 웖; 웖; ) HANGUL SYLLABLE WEOLM
+C6D7;C6D7;110B 116F 11B2;C6D7;110B 116F 11B2; # (웗; 웗; 웗; 웗; 웗; ) HANGUL SYLLABLE WEOLB
+C6D8;C6D8;110B 116F 11B3;C6D8;110B 116F 11B3; # (웘; 웘; 웘; 웘; 웘; ) HANGUL SYLLABLE WEOLS
+C6D9;C6D9;110B 116F 11B4;C6D9;110B 116F 11B4; # (웙; 웙; 웙; 웙; 웙; ) HANGUL SYLLABLE WEOLT
+C6DA;C6DA;110B 116F 11B5;C6DA;110B 116F 11B5; # (웚; 웚; 웚; 웚; 웚; ) HANGUL SYLLABLE WEOLP
+C6DB;C6DB;110B 116F 11B6;C6DB;110B 116F 11B6; # (웛; 웛; 웛; 웛; 웛; ) HANGUL SYLLABLE WEOLH
+C6DC;C6DC;110B 116F 11B7;C6DC;110B 116F 11B7; # (웜; 웜; 웜; 웜; 웜; ) HANGUL SYLLABLE WEOM
+C6DD;C6DD;110B 116F 11B8;C6DD;110B 116F 11B8; # (웝; 웝; 웝; 웝; 웝; ) HANGUL SYLLABLE WEOB
+C6DE;C6DE;110B 116F 11B9;C6DE;110B 116F 11B9; # (웞; 웞; 웞; 웞; 웞; ) HANGUL SYLLABLE WEOBS
+C6DF;C6DF;110B 116F 11BA;C6DF;110B 116F 11BA; # (웟; 웟; 웟; 웟; 웟; ) HANGUL SYLLABLE WEOS
+C6E0;C6E0;110B 116F 11BB;C6E0;110B 116F 11BB; # (웠; 웠; 웠; 웠; 웠; ) HANGUL SYLLABLE WEOSS
+C6E1;C6E1;110B 116F 11BC;C6E1;110B 116F 11BC; # (웡; 웡; 웡; 웡; 웡; ) HANGUL SYLLABLE WEONG
+C6E2;C6E2;110B 116F 11BD;C6E2;110B 116F 11BD; # (웢; 웢; 웢; 웢; 웢; ) HANGUL SYLLABLE WEOJ
+C6E3;C6E3;110B 116F 11BE;C6E3;110B 116F 11BE; # (웣; 웣; 웣; 웣; 웣; ) HANGUL SYLLABLE WEOC
+C6E4;C6E4;110B 116F 11BF;C6E4;110B 116F 11BF; # (웤; 웤; 웤; 웤; 웤; ) HANGUL SYLLABLE WEOK
+C6E5;C6E5;110B 116F 11C0;C6E5;110B 116F 11C0; # (웥; 웥; 웥; 웥; 웥; ) HANGUL SYLLABLE WEOT
+C6E6;C6E6;110B 116F 11C1;C6E6;110B 116F 11C1; # (웦; 웦; 웦; 웦; 웦; ) HANGUL SYLLABLE WEOP
+C6E7;C6E7;110B 116F 11C2;C6E7;110B 116F 11C2; # (웧; 웧; 웧; 웧; 웧; ) HANGUL SYLLABLE WEOH
+C6E8;C6E8;110B 1170;C6E8;110B 1170; # (웨; 웨; 웨; 웨; 웨; ) HANGUL SYLLABLE WE
+C6E9;C6E9;110B 1170 11A8;C6E9;110B 1170 11A8; # (웩; 웩; 웩; 웩; 웩; ) HANGUL SYLLABLE WEG
+C6EA;C6EA;110B 1170 11A9;C6EA;110B 1170 11A9; # (웪; 웪; 웪; 웪; 웪; ) HANGUL SYLLABLE WEGG
+C6EB;C6EB;110B 1170 11AA;C6EB;110B 1170 11AA; # (웫; 웫; 웫; 웫; 웫; ) HANGUL SYLLABLE WEGS
+C6EC;C6EC;110B 1170 11AB;C6EC;110B 1170 11AB; # (웬; 웬; 웬; 웬; 웬; ) HANGUL SYLLABLE WEN
+C6ED;C6ED;110B 1170 11AC;C6ED;110B 1170 11AC; # (웭; 웭; 웭; 웭; 웭; ) HANGUL SYLLABLE WENJ
+C6EE;C6EE;110B 1170 11AD;C6EE;110B 1170 11AD; # (웮; 웮; 웮; 웮; 웮; ) HANGUL SYLLABLE WENH
+C6EF;C6EF;110B 1170 11AE;C6EF;110B 1170 11AE; # (웯; 웯; 웯; 웯; 웯; ) HANGUL SYLLABLE WED
+C6F0;C6F0;110B 1170 11AF;C6F0;110B 1170 11AF; # (웰; 웰; 웰; 웰; 웰; ) HANGUL SYLLABLE WEL
+C6F1;C6F1;110B 1170 11B0;C6F1;110B 1170 11B0; # (웱; 웱; 웱; 웱; 웱; ) HANGUL SYLLABLE WELG
+C6F2;C6F2;110B 1170 11B1;C6F2;110B 1170 11B1; # (웲; 웲; 웲; 웲; 웲; ) HANGUL SYLLABLE WELM
+C6F3;C6F3;110B 1170 11B2;C6F3;110B 1170 11B2; # (웳; 웳; 웳; 웳; 웳; ) HANGUL SYLLABLE WELB
+C6F4;C6F4;110B 1170 11B3;C6F4;110B 1170 11B3; # (웴; 웴; 웴; 웴; 웴; ) HANGUL SYLLABLE WELS
+C6F5;C6F5;110B 1170 11B4;C6F5;110B 1170 11B4; # (웵; 웵; 웵; 웵; 웵; ) HANGUL SYLLABLE WELT
+C6F6;C6F6;110B 1170 11B5;C6F6;110B 1170 11B5; # (웶; 웶; 웶; 웶; 웶; ) HANGUL SYLLABLE WELP
+C6F7;C6F7;110B 1170 11B6;C6F7;110B 1170 11B6; # (웷; 웷; 웷; 웷; 웷; ) HANGUL SYLLABLE WELH
+C6F8;C6F8;110B 1170 11B7;C6F8;110B 1170 11B7; # (웸; 웸; 웸; 웸; 웸; ) HANGUL SYLLABLE WEM
+C6F9;C6F9;110B 1170 11B8;C6F9;110B 1170 11B8; # (웹; 웹; 웹; 웹; 웹; ) HANGUL SYLLABLE WEB
+C6FA;C6FA;110B 1170 11B9;C6FA;110B 1170 11B9; # (웺; 웺; 웺; 웺; 웺; ) HANGUL SYLLABLE WEBS
+C6FB;C6FB;110B 1170 11BA;C6FB;110B 1170 11BA; # (웻; 웻; 웻; 웻; 웻; ) HANGUL SYLLABLE WES
+C6FC;C6FC;110B 1170 11BB;C6FC;110B 1170 11BB; # (웼; 웼; 웼; 웼; 웼; ) HANGUL SYLLABLE WESS
+C6FD;C6FD;110B 1170 11BC;C6FD;110B 1170 11BC; # (웽; 웽; 웽; 웽; 웽; ) HANGUL SYLLABLE WENG
+C6FE;C6FE;110B 1170 11BD;C6FE;110B 1170 11BD; # (웾; 웾; 웾; 웾; 웾; ) HANGUL SYLLABLE WEJ
+C6FF;C6FF;110B 1170 11BE;C6FF;110B 1170 11BE; # (웿; 웿; 웿; 웿; 웿; ) HANGUL SYLLABLE WEC
+C700;C700;110B 1170 11BF;C700;110B 1170 11BF; # (윀; 윀; 윀; 윀; 윀; ) HANGUL SYLLABLE WEK
+C701;C701;110B 1170 11C0;C701;110B 1170 11C0; # (윁; 윁; 윁; 윁; 윁; ) HANGUL SYLLABLE WET
+C702;C702;110B 1170 11C1;C702;110B 1170 11C1; # (윂; 윂; 윂; 윂; 윂; ) HANGUL SYLLABLE WEP
+C703;C703;110B 1170 11C2;C703;110B 1170 11C2; # (윃; 윃; 윃; 윃; 윃; ) HANGUL SYLLABLE WEH
+C704;C704;110B 1171;C704;110B 1171; # (위; 위; 위; 위; 위; ) HANGUL SYLLABLE WI
+C705;C705;110B 1171 11A8;C705;110B 1171 11A8; # (윅; 윅; 윅; 윅; 윅; ) HANGUL SYLLABLE WIG
+C706;C706;110B 1171 11A9;C706;110B 1171 11A9; # (윆; 윆; 윆; 윆; 윆; ) HANGUL SYLLABLE WIGG
+C707;C707;110B 1171 11AA;C707;110B 1171 11AA; # (윇; 윇; 윇; 윇; 윇; ) HANGUL SYLLABLE WIGS
+C708;C708;110B 1171 11AB;C708;110B 1171 11AB; # (윈; 윈; 윈; 윈; 윈; ) HANGUL SYLLABLE WIN
+C709;C709;110B 1171 11AC;C709;110B 1171 11AC; # (윉; 윉; 윉; 윉; 윉; ) HANGUL SYLLABLE WINJ
+C70A;C70A;110B 1171 11AD;C70A;110B 1171 11AD; # (윊; 윊; 윊; 윊; 윊; ) HANGUL SYLLABLE WINH
+C70B;C70B;110B 1171 11AE;C70B;110B 1171 11AE; # (윋; 윋; 윋; 윋; 윋; ) HANGUL SYLLABLE WID
+C70C;C70C;110B 1171 11AF;C70C;110B 1171 11AF; # (윌; 윌; 윌; 윌; 윌; ) HANGUL SYLLABLE WIL
+C70D;C70D;110B 1171 11B0;C70D;110B 1171 11B0; # (윍; 윍; 윍; 윍; 윍; ) HANGUL SYLLABLE WILG
+C70E;C70E;110B 1171 11B1;C70E;110B 1171 11B1; # (윎; 윎; 윎; 윎; 윎; ) HANGUL SYLLABLE WILM
+C70F;C70F;110B 1171 11B2;C70F;110B 1171 11B2; # (윏; 윏; 윏; 윏; 윏; ) HANGUL SYLLABLE WILB
+C710;C710;110B 1171 11B3;C710;110B 1171 11B3; # (윐; 윐; 윐; 윐; 윐; ) HANGUL SYLLABLE WILS
+C711;C711;110B 1171 11B4;C711;110B 1171 11B4; # (윑; 윑; 윑; 윑; 윑; ) HANGUL SYLLABLE WILT
+C712;C712;110B 1171 11B5;C712;110B 1171 11B5; # (윒; 윒; 윒; 윒; 윒; ) HANGUL SYLLABLE WILP
+C713;C713;110B 1171 11B6;C713;110B 1171 11B6; # (윓; 윓; 윓; 윓; 윓; ) HANGUL SYLLABLE WILH
+C714;C714;110B 1171 11B7;C714;110B 1171 11B7; # (윔; 윔; 윔; 윔; 윔; ) HANGUL SYLLABLE WIM
+C715;C715;110B 1171 11B8;C715;110B 1171 11B8; # (윕; 윕; 윕; 윕; 윕; ) HANGUL SYLLABLE WIB
+C716;C716;110B 1171 11B9;C716;110B 1171 11B9; # (윖; 윖; 윖; 윖; 윖; ) HANGUL SYLLABLE WIBS
+C717;C717;110B 1171 11BA;C717;110B 1171 11BA; # (윗; 윗; 윗; 윗; 윗; ) HANGUL SYLLABLE WIS
+C718;C718;110B 1171 11BB;C718;110B 1171 11BB; # (윘; 윘; 윘; 윘; 윘; ) HANGUL SYLLABLE WISS
+C719;C719;110B 1171 11BC;C719;110B 1171 11BC; # (윙; 윙; 윙; 윙; 윙; ) HANGUL SYLLABLE WING
+C71A;C71A;110B 1171 11BD;C71A;110B 1171 11BD; # (윚; 윚; 윚; 윚; 윚; ) HANGUL SYLLABLE WIJ
+C71B;C71B;110B 1171 11BE;C71B;110B 1171 11BE; # (윛; 윛; 윛; 윛; 윛; ) HANGUL SYLLABLE WIC
+C71C;C71C;110B 1171 11BF;C71C;110B 1171 11BF; # (윜; 윜; 윜; 윜; 윜; ) HANGUL SYLLABLE WIK
+C71D;C71D;110B 1171 11C0;C71D;110B 1171 11C0; # (윝; 윝; 윝; 윝; 윝; ) HANGUL SYLLABLE WIT
+C71E;C71E;110B 1171 11C1;C71E;110B 1171 11C1; # (윞; 윞; 윞; 윞; 윞; ) HANGUL SYLLABLE WIP
+C71F;C71F;110B 1171 11C2;C71F;110B 1171 11C2; # (윟; 윟; 윟; 윟; 윟; ) HANGUL SYLLABLE WIH
+C720;C720;110B 1172;C720;110B 1172; # (유; 유; 유; 유; 유; ) HANGUL SYLLABLE YU
+C721;C721;110B 1172 11A8;C721;110B 1172 11A8; # (육; 육; 육; 육; 육; ) HANGUL SYLLABLE YUG
+C722;C722;110B 1172 11A9;C722;110B 1172 11A9; # (윢; 윢; 윢; 윢; 윢; ) HANGUL SYLLABLE YUGG
+C723;C723;110B 1172 11AA;C723;110B 1172 11AA; # (윣; 윣; 윣; 윣; 윣; ) HANGUL SYLLABLE YUGS
+C724;C724;110B 1172 11AB;C724;110B 1172 11AB; # (윤; 윤; 윤; 윤; 윤; ) HANGUL SYLLABLE YUN
+C725;C725;110B 1172 11AC;C725;110B 1172 11AC; # (윥; 윥; 윥; 윥; 윥; ) HANGUL SYLLABLE YUNJ
+C726;C726;110B 1172 11AD;C726;110B 1172 11AD; # (윦; 윦; 윦; 윦; 윦; ) HANGUL SYLLABLE YUNH
+C727;C727;110B 1172 11AE;C727;110B 1172 11AE; # (윧; 윧; 윧; 윧; 윧; ) HANGUL SYLLABLE YUD
+C728;C728;110B 1172 11AF;C728;110B 1172 11AF; # (율; 율; 율; 율; 율; ) HANGUL SYLLABLE YUL
+C729;C729;110B 1172 11B0;C729;110B 1172 11B0; # (윩; 윩; 윩; 윩; 윩; ) HANGUL SYLLABLE YULG
+C72A;C72A;110B 1172 11B1;C72A;110B 1172 11B1; # (윪; 윪; 윪; 윪; 윪; ) HANGUL SYLLABLE YULM
+C72B;C72B;110B 1172 11B2;C72B;110B 1172 11B2; # (윫; 윫; 윫; 윫; 윫; ) HANGUL SYLLABLE YULB
+C72C;C72C;110B 1172 11B3;C72C;110B 1172 11B3; # (윬; 윬; 윬; 윬; 윬; ) HANGUL SYLLABLE YULS
+C72D;C72D;110B 1172 11B4;C72D;110B 1172 11B4; # (윭; 윭; 윭; 윭; 윭; ) HANGUL SYLLABLE YULT
+C72E;C72E;110B 1172 11B5;C72E;110B 1172 11B5; # (윮; 윮; 윮; 윮; 윮; ) HANGUL SYLLABLE YULP
+C72F;C72F;110B 1172 11B6;C72F;110B 1172 11B6; # (윯; 윯; 윯; 윯; 윯; ) HANGUL SYLLABLE YULH
+C730;C730;110B 1172 11B7;C730;110B 1172 11B7; # (윰; 윰; 윰; 윰; 윰; ) HANGUL SYLLABLE YUM
+C731;C731;110B 1172 11B8;C731;110B 1172 11B8; # (윱; 윱; 윱; 윱; 윱; ) HANGUL SYLLABLE YUB
+C732;C732;110B 1172 11B9;C732;110B 1172 11B9; # (윲; 윲; 윲; 윲; 윲; ) HANGUL SYLLABLE YUBS
+C733;C733;110B 1172 11BA;C733;110B 1172 11BA; # (윳; 윳; 윳; 윳; 윳; ) HANGUL SYLLABLE YUS
+C734;C734;110B 1172 11BB;C734;110B 1172 11BB; # (윴; 윴; 윴; 윴; 윴; ) HANGUL SYLLABLE YUSS
+C735;C735;110B 1172 11BC;C735;110B 1172 11BC; # (융; 융; 융; 융; 융; ) HANGUL SYLLABLE YUNG
+C736;C736;110B 1172 11BD;C736;110B 1172 11BD; # (윶; 윶; 윶; 윶; 윶; ) HANGUL SYLLABLE YUJ
+C737;C737;110B 1172 11BE;C737;110B 1172 11BE; # (윷; 윷; 윷; 윷; 윷; ) HANGUL SYLLABLE YUC
+C738;C738;110B 1172 11BF;C738;110B 1172 11BF; # (윸; 윸; 윸; 윸; 윸; ) HANGUL SYLLABLE YUK
+C739;C739;110B 1172 11C0;C739;110B 1172 11C0; # (윹; 윹; 윹; 윹; 윹; ) HANGUL SYLLABLE YUT
+C73A;C73A;110B 1172 11C1;C73A;110B 1172 11C1; # (윺; 윺; 윺; 윺; 윺; ) HANGUL SYLLABLE YUP
+C73B;C73B;110B 1172 11C2;C73B;110B 1172 11C2; # (윻; 윻; 윻; 윻; 윻; ) HANGUL SYLLABLE YUH
+C73C;C73C;110B 1173;C73C;110B 1173; # (으; 으; 으; 으; 으; ) HANGUL SYLLABLE EU
+C73D;C73D;110B 1173 11A8;C73D;110B 1173 11A8; # (윽; 윽; 윽; 윽; 윽; ) HANGUL SYLLABLE EUG
+C73E;C73E;110B 1173 11A9;C73E;110B 1173 11A9; # (윾; 윾; 윾; 윾; 윾; ) HANGUL SYLLABLE EUGG
+C73F;C73F;110B 1173 11AA;C73F;110B 1173 11AA; # (윿; 윿; 윿; 윿; 윿; ) HANGUL SYLLABLE EUGS
+C740;C740;110B 1173 11AB;C740;110B 1173 11AB; # (은; 은; 은; 은; 은; ) HANGUL SYLLABLE EUN
+C741;C741;110B 1173 11AC;C741;110B 1173 11AC; # (읁; 읁; 읁; 읁; 읁; ) HANGUL SYLLABLE EUNJ
+C742;C742;110B 1173 11AD;C742;110B 1173 11AD; # (읂; 읂; 읂; 읂; 읂; ) HANGUL SYLLABLE EUNH
+C743;C743;110B 1173 11AE;C743;110B 1173 11AE; # (읃; 읃; 읃; 읃; 읃; ) HANGUL SYLLABLE EUD
+C744;C744;110B 1173 11AF;C744;110B 1173 11AF; # (을; 을; 을; 을; 을; ) HANGUL SYLLABLE EUL
+C745;C745;110B 1173 11B0;C745;110B 1173 11B0; # (읅; 읅; 읅; 읅; 읅; ) HANGUL SYLLABLE EULG
+C746;C746;110B 1173 11B1;C746;110B 1173 11B1; # (읆; 읆; 읆; 읆; 읆; ) HANGUL SYLLABLE EULM
+C747;C747;110B 1173 11B2;C747;110B 1173 11B2; # (읇; 읇; 읇; 읇; 읇; ) HANGUL SYLLABLE EULB
+C748;C748;110B 1173 11B3;C748;110B 1173 11B3; # (읈; 읈; 읈; 읈; 읈; ) HANGUL SYLLABLE EULS
+C749;C749;110B 1173 11B4;C749;110B 1173 11B4; # (읉; 읉; 읉; 읉; 읉; ) HANGUL SYLLABLE EULT
+C74A;C74A;110B 1173 11B5;C74A;110B 1173 11B5; # (읊; 읊; 읊; 읊; 읊; ) HANGUL SYLLABLE EULP
+C74B;C74B;110B 1173 11B6;C74B;110B 1173 11B6; # (읋; 읋; 읋; 읋; 읋; ) HANGUL SYLLABLE EULH
+C74C;C74C;110B 1173 11B7;C74C;110B 1173 11B7; # (음; 음; 음; 음; 음; ) HANGUL SYLLABLE EUM
+C74D;C74D;110B 1173 11B8;C74D;110B 1173 11B8; # (읍; 읍; 읍; 읍; 읍; ) HANGUL SYLLABLE EUB
+C74E;C74E;110B 1173 11B9;C74E;110B 1173 11B9; # (읎; 읎; 읎; 읎; 읎; ) HANGUL SYLLABLE EUBS
+C74F;C74F;110B 1173 11BA;C74F;110B 1173 11BA; # (읏; 읏; 읏; 읏; 읏; ) HANGUL SYLLABLE EUS
+C750;C750;110B 1173 11BB;C750;110B 1173 11BB; # (읐; 읐; 읐; 읐; 읐; ) HANGUL SYLLABLE EUSS
+C751;C751;110B 1173 11BC;C751;110B 1173 11BC; # (응; 응; 응; 응; 응; ) HANGUL SYLLABLE EUNG
+C752;C752;110B 1173 11BD;C752;110B 1173 11BD; # (읒; 읒; 읒; 읒; 읒; ) HANGUL SYLLABLE EUJ
+C753;C753;110B 1173 11BE;C753;110B 1173 11BE; # (읓; 읓; 읓; 읓; 읓; ) HANGUL SYLLABLE EUC
+C754;C754;110B 1173 11BF;C754;110B 1173 11BF; # (읔; 읔; 읔; 읔; 읔; ) HANGUL SYLLABLE EUK
+C755;C755;110B 1173 11C0;C755;110B 1173 11C0; # (읕; 읕; 읕; 읕; 읕; ) HANGUL SYLLABLE EUT
+C756;C756;110B 1173 11C1;C756;110B 1173 11C1; # (읖; 읖; 읖; 읖; 읖; ) HANGUL SYLLABLE EUP
+C757;C757;110B 1173 11C2;C757;110B 1173 11C2; # (읗; 읗; 읗; 읗; 읗; ) HANGUL SYLLABLE EUH
+C758;C758;110B 1174;C758;110B 1174; # (의; 의; 의; 의; 의; ) HANGUL SYLLABLE YI
+C759;C759;110B 1174 11A8;C759;110B 1174 11A8; # (읙; 읙; 읙; 읙; 읙; ) HANGUL SYLLABLE YIG
+C75A;C75A;110B 1174 11A9;C75A;110B 1174 11A9; # (읚; 읚; 읚; 읚; 읚; ) HANGUL SYLLABLE YIGG
+C75B;C75B;110B 1174 11AA;C75B;110B 1174 11AA; # (읛; 읛; 읛; 읛; 읛; ) HANGUL SYLLABLE YIGS
+C75C;C75C;110B 1174 11AB;C75C;110B 1174 11AB; # (읜; 읜; 읜; 읜; 읜; ) HANGUL SYLLABLE YIN
+C75D;C75D;110B 1174 11AC;C75D;110B 1174 11AC; # (읝; 읝; 읝; 읝; 읝; ) HANGUL SYLLABLE YINJ
+C75E;C75E;110B 1174 11AD;C75E;110B 1174 11AD; # (읞; 읞; 읞; 읞; 읞; ) HANGUL SYLLABLE YINH
+C75F;C75F;110B 1174 11AE;C75F;110B 1174 11AE; # (읟; 읟; 읟; 읟; 읟; ) HANGUL SYLLABLE YID
+C760;C760;110B 1174 11AF;C760;110B 1174 11AF; # (읠; 읠; 읠; 읠; 읠; ) HANGUL SYLLABLE YIL
+C761;C761;110B 1174 11B0;C761;110B 1174 11B0; # (읡; 읡; 읡; 읡; 읡; ) HANGUL SYLLABLE YILG
+C762;C762;110B 1174 11B1;C762;110B 1174 11B1; # (읢; 읢; 읢; 읢; 읢; ) HANGUL SYLLABLE YILM
+C763;C763;110B 1174 11B2;C763;110B 1174 11B2; # (읣; 읣; 읣; 읣; 읣; ) HANGUL SYLLABLE YILB
+C764;C764;110B 1174 11B3;C764;110B 1174 11B3; # (읤; 읤; 읤; 읤; 읤; ) HANGUL SYLLABLE YILS
+C765;C765;110B 1174 11B4;C765;110B 1174 11B4; # (읥; 읥; 읥; 읥; 읥; ) HANGUL SYLLABLE YILT
+C766;C766;110B 1174 11B5;C766;110B 1174 11B5; # (읦; 읦; 읦; 읦; 읦; ) HANGUL SYLLABLE YILP
+C767;C767;110B 1174 11B6;C767;110B 1174 11B6; # (읧; 읧; 읧; 읧; 읧; ) HANGUL SYLLABLE YILH
+C768;C768;110B 1174 11B7;C768;110B 1174 11B7; # (읨; 읨; 읨; 읨; 읨; ) HANGUL SYLLABLE YIM
+C769;C769;110B 1174 11B8;C769;110B 1174 11B8; # (읩; 읩; 읩; 읩; 읩; ) HANGUL SYLLABLE YIB
+C76A;C76A;110B 1174 11B9;C76A;110B 1174 11B9; # (읪; 읪; 읪; 읪; 읪; ) HANGUL SYLLABLE YIBS
+C76B;C76B;110B 1174 11BA;C76B;110B 1174 11BA; # (읫; 읫; 읫; 읫; 읫; ) HANGUL SYLLABLE YIS
+C76C;C76C;110B 1174 11BB;C76C;110B 1174 11BB; # (읬; 읬; 읬; 읬; 읬; ) HANGUL SYLLABLE YISS
+C76D;C76D;110B 1174 11BC;C76D;110B 1174 11BC; # (읭; 읭; 읭; 읭; 읭; ) HANGUL SYLLABLE YING
+C76E;C76E;110B 1174 11BD;C76E;110B 1174 11BD; # (읮; 읮; 읮; 읮; 읮; ) HANGUL SYLLABLE YIJ
+C76F;C76F;110B 1174 11BE;C76F;110B 1174 11BE; # (읯; 읯; 읯; 읯; 읯; ) HANGUL SYLLABLE YIC
+C770;C770;110B 1174 11BF;C770;110B 1174 11BF; # (읰; 읰; 읰; 읰; 읰; ) HANGUL SYLLABLE YIK
+C771;C771;110B 1174 11C0;C771;110B 1174 11C0; # (읱; 읱; 읱; 읱; 읱; ) HANGUL SYLLABLE YIT
+C772;C772;110B 1174 11C1;C772;110B 1174 11C1; # (읲; 읲; 읲; 읲; 읲; ) HANGUL SYLLABLE YIP
+C773;C773;110B 1174 11C2;C773;110B 1174 11C2; # (읳; 읳; 읳; 읳; 읳; ) HANGUL SYLLABLE YIH
+C774;C774;110B 1175;C774;110B 1175; # (이; 이; 이; 이; 이; ) HANGUL SYLLABLE I
+C775;C775;110B 1175 11A8;C775;110B 1175 11A8; # (익; 익; 익; 익; 익; ) HANGUL SYLLABLE IG
+C776;C776;110B 1175 11A9;C776;110B 1175 11A9; # (읶; 읶; 읶; 읶; 읶; ) HANGUL SYLLABLE IGG
+C777;C777;110B 1175 11AA;C777;110B 1175 11AA; # (읷; 읷; 읷; 읷; 읷; ) HANGUL SYLLABLE IGS
+C778;C778;110B 1175 11AB;C778;110B 1175 11AB; # (인; 인; 인; 인; 인; ) HANGUL SYLLABLE IN
+C779;C779;110B 1175 11AC;C779;110B 1175 11AC; # (읹; 읹; 읹; 읹; 읹; ) HANGUL SYLLABLE INJ
+C77A;C77A;110B 1175 11AD;C77A;110B 1175 11AD; # (읺; 읺; 읺; 읺; 읺; ) HANGUL SYLLABLE INH
+C77B;C77B;110B 1175 11AE;C77B;110B 1175 11AE; # (읻; 읻; 읻; 읻; 읻; ) HANGUL SYLLABLE ID
+C77C;C77C;110B 1175 11AF;C77C;110B 1175 11AF; # (일; 일; 일; 일; 일; ) HANGUL SYLLABLE IL
+C77D;C77D;110B 1175 11B0;C77D;110B 1175 11B0; # (읽; 읽; 읽; 읽; 읽; ) HANGUL SYLLABLE ILG
+C77E;C77E;110B 1175 11B1;C77E;110B 1175 11B1; # (읾; 읾; 읾; 읾; 읾; ) HANGUL SYLLABLE ILM
+C77F;C77F;110B 1175 11B2;C77F;110B 1175 11B2; # (읿; 읿; 읿; 읿; 읿; ) HANGUL SYLLABLE ILB
+C780;C780;110B 1175 11B3;C780;110B 1175 11B3; # (잀; 잀; 잀; 잀; 잀; ) HANGUL SYLLABLE ILS
+C781;C781;110B 1175 11B4;C781;110B 1175 11B4; # (잁; 잁; 잁; 잁; 잁; ) HANGUL SYLLABLE ILT
+C782;C782;110B 1175 11B5;C782;110B 1175 11B5; # (잂; 잂; 잂; 잂; 잂; ) HANGUL SYLLABLE ILP
+C783;C783;110B 1175 11B6;C783;110B 1175 11B6; # (잃; 잃; 잃; 잃; 잃; ) HANGUL SYLLABLE ILH
+C784;C784;110B 1175 11B7;C784;110B 1175 11B7; # (임; 임; 임; 임; 임; ) HANGUL SYLLABLE IM
+C785;C785;110B 1175 11B8;C785;110B 1175 11B8; # (입; 입; 입; 입; 입; ) HANGUL SYLLABLE IB
+C786;C786;110B 1175 11B9;C786;110B 1175 11B9; # (잆; 잆; 잆; 잆; 잆; ) HANGUL SYLLABLE IBS
+C787;C787;110B 1175 11BA;C787;110B 1175 11BA; # (잇; 잇; 잇; 잇; 잇; ) HANGUL SYLLABLE IS
+C788;C788;110B 1175 11BB;C788;110B 1175 11BB; # (있; 있; 있; 있; 있; ) HANGUL SYLLABLE ISS
+C789;C789;110B 1175 11BC;C789;110B 1175 11BC; # (잉; 잉; 잉; 잉; 잉; ) HANGUL SYLLABLE ING
+C78A;C78A;110B 1175 11BD;C78A;110B 1175 11BD; # (잊; 잊; 잊; 잊; 잊; ) HANGUL SYLLABLE IJ
+C78B;C78B;110B 1175 11BE;C78B;110B 1175 11BE; # (잋; 잋; 잋; 잋; 잋; ) HANGUL SYLLABLE IC
+C78C;C78C;110B 1175 11BF;C78C;110B 1175 11BF; # (잌; 잌; 잌; 잌; 잌; ) HANGUL SYLLABLE IK
+C78D;C78D;110B 1175 11C0;C78D;110B 1175 11C0; # (잍; 잍; 잍; 잍; 잍; ) HANGUL SYLLABLE IT
+C78E;C78E;110B 1175 11C1;C78E;110B 1175 11C1; # (잎; 잎; 잎; 잎; 잎; ) HANGUL SYLLABLE IP
+C78F;C78F;110B 1175 11C2;C78F;110B 1175 11C2; # (잏; 잏; 잏; 잏; 잏; ) HANGUL SYLLABLE IH
+C790;C790;110C 1161;C790;110C 1161; # (자; 자; 자; 자; 자; ) HANGUL SYLLABLE JA
+C791;C791;110C 1161 11A8;C791;110C 1161 11A8; # (작; 작; 작; 작; 작; ) HANGUL SYLLABLE JAG
+C792;C792;110C 1161 11A9;C792;110C 1161 11A9; # (잒; 잒; 잒; 잒; 잒; ) HANGUL SYLLABLE JAGG
+C793;C793;110C 1161 11AA;C793;110C 1161 11AA; # (잓; 잓; 잓; 잓; 잓; ) HANGUL SYLLABLE JAGS
+C794;C794;110C 1161 11AB;C794;110C 1161 11AB; # (잔; 잔; 잔; 잔; 잔; ) HANGUL SYLLABLE JAN
+C795;C795;110C 1161 11AC;C795;110C 1161 11AC; # (잕; 잕; 잕; 잕; 잕; ) HANGUL SYLLABLE JANJ
+C796;C796;110C 1161 11AD;C796;110C 1161 11AD; # (잖; 잖; 잖; 잖; 잖; ) HANGUL SYLLABLE JANH
+C797;C797;110C 1161 11AE;C797;110C 1161 11AE; # (잗; 잗; 잗; 잗; 잗; ) HANGUL SYLLABLE JAD
+C798;C798;110C 1161 11AF;C798;110C 1161 11AF; # (잘; 잘; 잘; 잘; 잘; ) HANGUL SYLLABLE JAL
+C799;C799;110C 1161 11B0;C799;110C 1161 11B0; # (잙; 잙; 잙; 잙; 잙; ) HANGUL SYLLABLE JALG
+C79A;C79A;110C 1161 11B1;C79A;110C 1161 11B1; # (잚; 잚; 잚; 잚; 잚; ) HANGUL SYLLABLE JALM
+C79B;C79B;110C 1161 11B2;C79B;110C 1161 11B2; # (잛; 잛; 잛; 잛; 잛; ) HANGUL SYLLABLE JALB
+C79C;C79C;110C 1161 11B3;C79C;110C 1161 11B3; # (잜; 잜; 잜; 잜; 잜; ) HANGUL SYLLABLE JALS
+C79D;C79D;110C 1161 11B4;C79D;110C 1161 11B4; # (잝; 잝; 잝; 잝; 잝; ) HANGUL SYLLABLE JALT
+C79E;C79E;110C 1161 11B5;C79E;110C 1161 11B5; # (잞; 잞; 잞; 잞; 잞; ) HANGUL SYLLABLE JALP
+C79F;C79F;110C 1161 11B6;C79F;110C 1161 11B6; # (잟; 잟; 잟; 잟; 잟; ) HANGUL SYLLABLE JALH
+C7A0;C7A0;110C 1161 11B7;C7A0;110C 1161 11B7; # (잠; 잠; 잠; 잠; 잠; ) HANGUL SYLLABLE JAM
+C7A1;C7A1;110C 1161 11B8;C7A1;110C 1161 11B8; # (잡; 잡; 잡; 잡; 잡; ) HANGUL SYLLABLE JAB
+C7A2;C7A2;110C 1161 11B9;C7A2;110C 1161 11B9; # (잢; 잢; 잢; 잢; 잢; ) HANGUL SYLLABLE JABS
+C7A3;C7A3;110C 1161 11BA;C7A3;110C 1161 11BA; # (잣; 잣; 잣; 잣; 잣; ) HANGUL SYLLABLE JAS
+C7A4;C7A4;110C 1161 11BB;C7A4;110C 1161 11BB; # (잤; 잤; 잤; 잤; 잤; ) HANGUL SYLLABLE JASS
+C7A5;C7A5;110C 1161 11BC;C7A5;110C 1161 11BC; # (장; 장; 장; 장; 장; ) HANGUL SYLLABLE JANG
+C7A6;C7A6;110C 1161 11BD;C7A6;110C 1161 11BD; # (잦; 잦; 잦; 잦; 잦; ) HANGUL SYLLABLE JAJ
+C7A7;C7A7;110C 1161 11BE;C7A7;110C 1161 11BE; # (잧; 잧; 잧; 잧; 잧; ) HANGUL SYLLABLE JAC
+C7A8;C7A8;110C 1161 11BF;C7A8;110C 1161 11BF; # (잨; 잨; 잨; 잨; 잨; ) HANGUL SYLLABLE JAK
+C7A9;C7A9;110C 1161 11C0;C7A9;110C 1161 11C0; # (잩; 잩; 잩; 잩; 잩; ) HANGUL SYLLABLE JAT
+C7AA;C7AA;110C 1161 11C1;C7AA;110C 1161 11C1; # (잪; 잪; 잪; 잪; 잪; ) HANGUL SYLLABLE JAP
+C7AB;C7AB;110C 1161 11C2;C7AB;110C 1161 11C2; # (잫; 잫; 잫; 잫; 잫; ) HANGUL SYLLABLE JAH
+C7AC;C7AC;110C 1162;C7AC;110C 1162; # (재; 재; 재; 재; 재; ) HANGUL SYLLABLE JAE
+C7AD;C7AD;110C 1162 11A8;C7AD;110C 1162 11A8; # (잭; 잭; 잭; 잭; 잭; ) HANGUL SYLLABLE JAEG
+C7AE;C7AE;110C 1162 11A9;C7AE;110C 1162 11A9; # (잮; 잮; 잮; 잮; 잮; ) HANGUL SYLLABLE JAEGG
+C7AF;C7AF;110C 1162 11AA;C7AF;110C 1162 11AA; # (잯; 잯; 잯; 잯; 잯; ) HANGUL SYLLABLE JAEGS
+C7B0;C7B0;110C 1162 11AB;C7B0;110C 1162 11AB; # (잰; 잰; 잰; 잰; 잰; ) HANGUL SYLLABLE JAEN
+C7B1;C7B1;110C 1162 11AC;C7B1;110C 1162 11AC; # (잱; 잱; 잱; 잱; 잱; ) HANGUL SYLLABLE JAENJ
+C7B2;C7B2;110C 1162 11AD;C7B2;110C 1162 11AD; # (잲; 잲; 잲; 잲; 잲; ) HANGUL SYLLABLE JAENH
+C7B3;C7B3;110C 1162 11AE;C7B3;110C 1162 11AE; # (잳; 잳; 잳; 잳; 잳; ) HANGUL SYLLABLE JAED
+C7B4;C7B4;110C 1162 11AF;C7B4;110C 1162 11AF; # (잴; 잴; 잴; 잴; 잴; ) HANGUL SYLLABLE JAEL
+C7B5;C7B5;110C 1162 11B0;C7B5;110C 1162 11B0; # (잵; 잵; 잵; 잵; 잵; ) HANGUL SYLLABLE JAELG
+C7B6;C7B6;110C 1162 11B1;C7B6;110C 1162 11B1; # (잶; 잶; 잶; 잶; 잶; ) HANGUL SYLLABLE JAELM
+C7B7;C7B7;110C 1162 11B2;C7B7;110C 1162 11B2; # (잷; 잷; 잷; 잷; 잷; ) HANGUL SYLLABLE JAELB
+C7B8;C7B8;110C 1162 11B3;C7B8;110C 1162 11B3; # (잸; 잸; 잸; 잸; 잸; ) HANGUL SYLLABLE JAELS
+C7B9;C7B9;110C 1162 11B4;C7B9;110C 1162 11B4; # (잹; 잹; 잹; 잹; 잹; ) HANGUL SYLLABLE JAELT
+C7BA;C7BA;110C 1162 11B5;C7BA;110C 1162 11B5; # (잺; 잺; 잺; 잺; 잺; ) HANGUL SYLLABLE JAELP
+C7BB;C7BB;110C 1162 11B6;C7BB;110C 1162 11B6; # (잻; 잻; 잻; 잻; 잻; ) HANGUL SYLLABLE JAELH
+C7BC;C7BC;110C 1162 11B7;C7BC;110C 1162 11B7; # (잼; 잼; 잼; 잼; 잼; ) HANGUL SYLLABLE JAEM
+C7BD;C7BD;110C 1162 11B8;C7BD;110C 1162 11B8; # (잽; 잽; 잽; 잽; 잽; ) HANGUL SYLLABLE JAEB
+C7BE;C7BE;110C 1162 11B9;C7BE;110C 1162 11B9; # (잾; 잾; 잾; 잾; 잾; ) HANGUL SYLLABLE JAEBS
+C7BF;C7BF;110C 1162 11BA;C7BF;110C 1162 11BA; # (잿; 잿; 잿; 잿; 잿; ) HANGUL SYLLABLE JAES
+C7C0;C7C0;110C 1162 11BB;C7C0;110C 1162 11BB; # (쟀; 쟀; 쟀; 쟀; 쟀; ) HANGUL SYLLABLE JAESS
+C7C1;C7C1;110C 1162 11BC;C7C1;110C 1162 11BC; # (쟁; 쟁; 쟁; 쟁; 쟁; ) HANGUL SYLLABLE JAENG
+C7C2;C7C2;110C 1162 11BD;C7C2;110C 1162 11BD; # (쟂; 쟂; 쟂; 쟂; 쟂; ) HANGUL SYLLABLE JAEJ
+C7C3;C7C3;110C 1162 11BE;C7C3;110C 1162 11BE; # (쟃; 쟃; 쟃; 쟃; 쟃; ) HANGUL SYLLABLE JAEC
+C7C4;C7C4;110C 1162 11BF;C7C4;110C 1162 11BF; # (쟄; 쟄; 쟄; 쟄; 쟄; ) HANGUL SYLLABLE JAEK
+C7C5;C7C5;110C 1162 11C0;C7C5;110C 1162 11C0; # (쟅; 쟅; 쟅; 쟅; 쟅; ) HANGUL SYLLABLE JAET
+C7C6;C7C6;110C 1162 11C1;C7C6;110C 1162 11C1; # (쟆; 쟆; 쟆; 쟆; 쟆; ) HANGUL SYLLABLE JAEP
+C7C7;C7C7;110C 1162 11C2;C7C7;110C 1162 11C2; # (쟇; 쟇; 쟇; 쟇; 쟇; ) HANGUL SYLLABLE JAEH
+C7C8;C7C8;110C 1163;C7C8;110C 1163; # (쟈; 쟈; 쟈; 쟈; 쟈; ) HANGUL SYLLABLE JYA
+C7C9;C7C9;110C 1163 11A8;C7C9;110C 1163 11A8; # (쟉; 쟉; 쟉; 쟉; 쟉; ) HANGUL SYLLABLE JYAG
+C7CA;C7CA;110C 1163 11A9;C7CA;110C 1163 11A9; # (쟊; 쟊; 쟊; 쟊; 쟊; ) HANGUL SYLLABLE JYAGG
+C7CB;C7CB;110C 1163 11AA;C7CB;110C 1163 11AA; # (쟋; 쟋; 쟋; 쟋; 쟋; ) HANGUL SYLLABLE JYAGS
+C7CC;C7CC;110C 1163 11AB;C7CC;110C 1163 11AB; # (쟌; 쟌; 쟌; 쟌; 쟌; ) HANGUL SYLLABLE JYAN
+C7CD;C7CD;110C 1163 11AC;C7CD;110C 1163 11AC; # (쟍; 쟍; 쟍; 쟍; 쟍; ) HANGUL SYLLABLE JYANJ
+C7CE;C7CE;110C 1163 11AD;C7CE;110C 1163 11AD; # (쟎; 쟎; 쟎; 쟎; 쟎; ) HANGUL SYLLABLE JYANH
+C7CF;C7CF;110C 1163 11AE;C7CF;110C 1163 11AE; # (쟏; 쟏; 쟏; 쟏; 쟏; ) HANGUL SYLLABLE JYAD
+C7D0;C7D0;110C 1163 11AF;C7D0;110C 1163 11AF; # (쟐; 쟐; 쟐; 쟐; 쟐; ) HANGUL SYLLABLE JYAL
+C7D1;C7D1;110C 1163 11B0;C7D1;110C 1163 11B0; # (쟑; 쟑; 쟑; 쟑; 쟑; ) HANGUL SYLLABLE JYALG
+C7D2;C7D2;110C 1163 11B1;C7D2;110C 1163 11B1; # (쟒; 쟒; 쟒; 쟒; 쟒; ) HANGUL SYLLABLE JYALM
+C7D3;C7D3;110C 1163 11B2;C7D3;110C 1163 11B2; # (쟓; 쟓; 쟓; 쟓; 쟓; ) HANGUL SYLLABLE JYALB
+C7D4;C7D4;110C 1163 11B3;C7D4;110C 1163 11B3; # (쟔; 쟔; 쟔; 쟔; 쟔; ) HANGUL SYLLABLE JYALS
+C7D5;C7D5;110C 1163 11B4;C7D5;110C 1163 11B4; # (쟕; 쟕; 쟕; 쟕; 쟕; ) HANGUL SYLLABLE JYALT
+C7D6;C7D6;110C 1163 11B5;C7D6;110C 1163 11B5; # (쟖; 쟖; 쟖; 쟖; 쟖; ) HANGUL SYLLABLE JYALP
+C7D7;C7D7;110C 1163 11B6;C7D7;110C 1163 11B6; # (쟗; 쟗; 쟗; 쟗; 쟗; ) HANGUL SYLLABLE JYALH
+C7D8;C7D8;110C 1163 11B7;C7D8;110C 1163 11B7; # (쟘; 쟘; 쟘; 쟘; 쟘; ) HANGUL SYLLABLE JYAM
+C7D9;C7D9;110C 1163 11B8;C7D9;110C 1163 11B8; # (쟙; 쟙; 쟙; 쟙; 쟙; ) HANGUL SYLLABLE JYAB
+C7DA;C7DA;110C 1163 11B9;C7DA;110C 1163 11B9; # (쟚; 쟚; 쟚; 쟚; 쟚; ) HANGUL SYLLABLE JYABS
+C7DB;C7DB;110C 1163 11BA;C7DB;110C 1163 11BA; # (쟛; 쟛; 쟛; 쟛; 쟛; ) HANGUL SYLLABLE JYAS
+C7DC;C7DC;110C 1163 11BB;C7DC;110C 1163 11BB; # (쟜; 쟜; 쟜; 쟜; 쟜; ) HANGUL SYLLABLE JYASS
+C7DD;C7DD;110C 1163 11BC;C7DD;110C 1163 11BC; # (쟝; 쟝; 쟝; 쟝; 쟝; ) HANGUL SYLLABLE JYANG
+C7DE;C7DE;110C 1163 11BD;C7DE;110C 1163 11BD; # (쟞; 쟞; 쟞; 쟞; 쟞; ) HANGUL SYLLABLE JYAJ
+C7DF;C7DF;110C 1163 11BE;C7DF;110C 1163 11BE; # (쟟; 쟟; 쟟; 쟟; 쟟; ) HANGUL SYLLABLE JYAC
+C7E0;C7E0;110C 1163 11BF;C7E0;110C 1163 11BF; # (쟠; 쟠; 쟠; 쟠; 쟠; ) HANGUL SYLLABLE JYAK
+C7E1;C7E1;110C 1163 11C0;C7E1;110C 1163 11C0; # (쟡; 쟡; 쟡; 쟡; 쟡; ) HANGUL SYLLABLE JYAT
+C7E2;C7E2;110C 1163 11C1;C7E2;110C 1163 11C1; # (쟢; 쟢; 쟢; 쟢; 쟢; ) HANGUL SYLLABLE JYAP
+C7E3;C7E3;110C 1163 11C2;C7E3;110C 1163 11C2; # (쟣; 쟣; 쟣; 쟣; 쟣; ) HANGUL SYLLABLE JYAH
+C7E4;C7E4;110C 1164;C7E4;110C 1164; # (쟤; 쟤; 쟤; 쟤; 쟤; ) HANGUL SYLLABLE JYAE
+C7E5;C7E5;110C 1164 11A8;C7E5;110C 1164 11A8; # (쟥; 쟥; 쟥; 쟥; 쟥; ) HANGUL SYLLABLE JYAEG
+C7E6;C7E6;110C 1164 11A9;C7E6;110C 1164 11A9; # (쟦; 쟦; 쟦; 쟦; 쟦; ) HANGUL SYLLABLE JYAEGG
+C7E7;C7E7;110C 1164 11AA;C7E7;110C 1164 11AA; # (쟧; 쟧; 쟧; 쟧; 쟧; ) HANGUL SYLLABLE JYAEGS
+C7E8;C7E8;110C 1164 11AB;C7E8;110C 1164 11AB; # (쟨; 쟨; 쟨; 쟨; 쟨; ) HANGUL SYLLABLE JYAEN
+C7E9;C7E9;110C 1164 11AC;C7E9;110C 1164 11AC; # (쟩; 쟩; 쟩; 쟩; 쟩; ) HANGUL SYLLABLE JYAENJ
+C7EA;C7EA;110C 1164 11AD;C7EA;110C 1164 11AD; # (쟪; 쟪; 쟪; 쟪; 쟪; ) HANGUL SYLLABLE JYAENH
+C7EB;C7EB;110C 1164 11AE;C7EB;110C 1164 11AE; # (쟫; 쟫; 쟫; 쟫; 쟫; ) HANGUL SYLLABLE JYAED
+C7EC;C7EC;110C 1164 11AF;C7EC;110C 1164 11AF; # (쟬; 쟬; 쟬; 쟬; 쟬; ) HANGUL SYLLABLE JYAEL
+C7ED;C7ED;110C 1164 11B0;C7ED;110C 1164 11B0; # (쟭; 쟭; 쟭; 쟭; 쟭; ) HANGUL SYLLABLE JYAELG
+C7EE;C7EE;110C 1164 11B1;C7EE;110C 1164 11B1; # (쟮; 쟮; 쟮; 쟮; 쟮; ) HANGUL SYLLABLE JYAELM
+C7EF;C7EF;110C 1164 11B2;C7EF;110C 1164 11B2; # (쟯; 쟯; 쟯; 쟯; 쟯; ) HANGUL SYLLABLE JYAELB
+C7F0;C7F0;110C 1164 11B3;C7F0;110C 1164 11B3; # (쟰; 쟰; 쟰; 쟰; 쟰; ) HANGUL SYLLABLE JYAELS
+C7F1;C7F1;110C 1164 11B4;C7F1;110C 1164 11B4; # (쟱; 쟱; 쟱; 쟱; 쟱; ) HANGUL SYLLABLE JYAELT
+C7F2;C7F2;110C 1164 11B5;C7F2;110C 1164 11B5; # (쟲; 쟲; 쟲; 쟲; 쟲; ) HANGUL SYLLABLE JYAELP
+C7F3;C7F3;110C 1164 11B6;C7F3;110C 1164 11B6; # (쟳; 쟳; 쟳; 쟳; 쟳; ) HANGUL SYLLABLE JYAELH
+C7F4;C7F4;110C 1164 11B7;C7F4;110C 1164 11B7; # (쟴; 쟴; 쟴; 쟴; 쟴; ) HANGUL SYLLABLE JYAEM
+C7F5;C7F5;110C 1164 11B8;C7F5;110C 1164 11B8; # (쟵; 쟵; 쟵; 쟵; 쟵; ) HANGUL SYLLABLE JYAEB
+C7F6;C7F6;110C 1164 11B9;C7F6;110C 1164 11B9; # (쟶; 쟶; 쟶; 쟶; 쟶; ) HANGUL SYLLABLE JYAEBS
+C7F7;C7F7;110C 1164 11BA;C7F7;110C 1164 11BA; # (쟷; 쟷; 쟷; 쟷; 쟷; ) HANGUL SYLLABLE JYAES
+C7F8;C7F8;110C 1164 11BB;C7F8;110C 1164 11BB; # (쟸; 쟸; 쟸; 쟸; 쟸; ) HANGUL SYLLABLE JYAESS
+C7F9;C7F9;110C 1164 11BC;C7F9;110C 1164 11BC; # (쟹; 쟹; 쟹; 쟹; 쟹; ) HANGUL SYLLABLE JYAENG
+C7FA;C7FA;110C 1164 11BD;C7FA;110C 1164 11BD; # (쟺; 쟺; 쟺; 쟺; 쟺; ) HANGUL SYLLABLE JYAEJ
+C7FB;C7FB;110C 1164 11BE;C7FB;110C 1164 11BE; # (쟻; 쟻; 쟻; 쟻; 쟻; ) HANGUL SYLLABLE JYAEC
+C7FC;C7FC;110C 1164 11BF;C7FC;110C 1164 11BF; # (쟼; 쟼; 쟼; 쟼; 쟼; ) HANGUL SYLLABLE JYAEK
+C7FD;C7FD;110C 1164 11C0;C7FD;110C 1164 11C0; # (쟽; 쟽; 쟽; 쟽; 쟽; ) HANGUL SYLLABLE JYAET
+C7FE;C7FE;110C 1164 11C1;C7FE;110C 1164 11C1; # (쟾; 쟾; 쟾; 쟾; 쟾; ) HANGUL SYLLABLE JYAEP
+C7FF;C7FF;110C 1164 11C2;C7FF;110C 1164 11C2; # (쟿; 쟿; 쟿; 쟿; 쟿; ) HANGUL SYLLABLE JYAEH
+C800;C800;110C 1165;C800;110C 1165; # (저; 저; 저; 저; 저; ) HANGUL SYLLABLE JEO
+C801;C801;110C 1165 11A8;C801;110C 1165 11A8; # (적; 적; 적; 적; 적; ) HANGUL SYLLABLE JEOG
+C802;C802;110C 1165 11A9;C802;110C 1165 11A9; # (젂; 젂; 젂; 젂; 젂; ) HANGUL SYLLABLE JEOGG
+C803;C803;110C 1165 11AA;C803;110C 1165 11AA; # (젃; 젃; 젃; 젃; 젃; ) HANGUL SYLLABLE JEOGS
+C804;C804;110C 1165 11AB;C804;110C 1165 11AB; # (전; 전; 전; 전; 전; ) HANGUL SYLLABLE JEON
+C805;C805;110C 1165 11AC;C805;110C 1165 11AC; # (젅; 젅; 젅; 젅; 젅; ) HANGUL SYLLABLE JEONJ
+C806;C806;110C 1165 11AD;C806;110C 1165 11AD; # (젆; 젆; 젆; 젆; 젆; ) HANGUL SYLLABLE JEONH
+C807;C807;110C 1165 11AE;C807;110C 1165 11AE; # (젇; 젇; 젇; 젇; 젇; ) HANGUL SYLLABLE JEOD
+C808;C808;110C 1165 11AF;C808;110C 1165 11AF; # (절; 절; 절; 절; 절; ) HANGUL SYLLABLE JEOL
+C809;C809;110C 1165 11B0;C809;110C 1165 11B0; # (젉; 젉; 젉; 젉; 젉; ) HANGUL SYLLABLE JEOLG
+C80A;C80A;110C 1165 11B1;C80A;110C 1165 11B1; # (젊; 젊; 젊; 젊; 젊; ) HANGUL SYLLABLE JEOLM
+C80B;C80B;110C 1165 11B2;C80B;110C 1165 11B2; # (젋; 젋; 젋; 젋; 젋; ) HANGUL SYLLABLE JEOLB
+C80C;C80C;110C 1165 11B3;C80C;110C 1165 11B3; # (젌; 젌; 젌; 젌; 젌; ) HANGUL SYLLABLE JEOLS
+C80D;C80D;110C 1165 11B4;C80D;110C 1165 11B4; # (젍; 젍; 젍; 젍; 젍; ) HANGUL SYLLABLE JEOLT
+C80E;C80E;110C 1165 11B5;C80E;110C 1165 11B5; # (젎; 젎; 젎; 젎; 젎; ) HANGUL SYLLABLE JEOLP
+C80F;C80F;110C 1165 11B6;C80F;110C 1165 11B6; # (젏; 젏; 젏; 젏; 젏; ) HANGUL SYLLABLE JEOLH
+C810;C810;110C 1165 11B7;C810;110C 1165 11B7; # (점; 점; 점; 점; 점; ) HANGUL SYLLABLE JEOM
+C811;C811;110C 1165 11B8;C811;110C 1165 11B8; # (접; 접; 접; 접; 접; ) HANGUL SYLLABLE JEOB
+C812;C812;110C 1165 11B9;C812;110C 1165 11B9; # (젒; 젒; 젒; 젒; 젒; ) HANGUL SYLLABLE JEOBS
+C813;C813;110C 1165 11BA;C813;110C 1165 11BA; # (젓; 젓; 젓; 젓; 젓; ) HANGUL SYLLABLE JEOS
+C814;C814;110C 1165 11BB;C814;110C 1165 11BB; # (젔; 젔; 젔; 젔; 젔; ) HANGUL SYLLABLE JEOSS
+C815;C815;110C 1165 11BC;C815;110C 1165 11BC; # (정; 정; 정; 정; 정; ) HANGUL SYLLABLE JEONG
+C816;C816;110C 1165 11BD;C816;110C 1165 11BD; # (젖; 젖; 젖; 젖; 젖; ) HANGUL SYLLABLE JEOJ
+C817;C817;110C 1165 11BE;C817;110C 1165 11BE; # (젗; 젗; 젗; 젗; 젗; ) HANGUL SYLLABLE JEOC
+C818;C818;110C 1165 11BF;C818;110C 1165 11BF; # (젘; 젘; 젘; 젘; 젘; ) HANGUL SYLLABLE JEOK
+C819;C819;110C 1165 11C0;C819;110C 1165 11C0; # (젙; 젙; 젙; 젙; 젙; ) HANGUL SYLLABLE JEOT
+C81A;C81A;110C 1165 11C1;C81A;110C 1165 11C1; # (젚; 젚; 젚; 젚; 젚; ) HANGUL SYLLABLE JEOP
+C81B;C81B;110C 1165 11C2;C81B;110C 1165 11C2; # (젛; 젛; 젛; 젛; 젛; ) HANGUL SYLLABLE JEOH
+C81C;C81C;110C 1166;C81C;110C 1166; # (제; 제; 제; 제; 제; ) HANGUL SYLLABLE JE
+C81D;C81D;110C 1166 11A8;C81D;110C 1166 11A8; # (젝; 젝; 젝; 젝; 젝; ) HANGUL SYLLABLE JEG
+C81E;C81E;110C 1166 11A9;C81E;110C 1166 11A9; # (젞; 젞; 젞; 젞; 젞; ) HANGUL SYLLABLE JEGG
+C81F;C81F;110C 1166 11AA;C81F;110C 1166 11AA; # (젟; 젟; 젟; 젟; 젟; ) HANGUL SYLLABLE JEGS
+C820;C820;110C 1166 11AB;C820;110C 1166 11AB; # (젠; 젠; 젠; 젠; 젠; ) HANGUL SYLLABLE JEN
+C821;C821;110C 1166 11AC;C821;110C 1166 11AC; # (젡; 젡; 젡; 젡; 젡; ) HANGUL SYLLABLE JENJ
+C822;C822;110C 1166 11AD;C822;110C 1166 11AD; # (젢; 젢; 젢; 젢; 젢; ) HANGUL SYLLABLE JENH
+C823;C823;110C 1166 11AE;C823;110C 1166 11AE; # (젣; 젣; 젣; 젣; 젣; ) HANGUL SYLLABLE JED
+C824;C824;110C 1166 11AF;C824;110C 1166 11AF; # (젤; 젤; 젤; 젤; 젤; ) HANGUL SYLLABLE JEL
+C825;C825;110C 1166 11B0;C825;110C 1166 11B0; # (젥; 젥; 젥; 젥; 젥; ) HANGUL SYLLABLE JELG
+C826;C826;110C 1166 11B1;C826;110C 1166 11B1; # (젦; 젦; 젦; 젦; 젦; ) HANGUL SYLLABLE JELM
+C827;C827;110C 1166 11B2;C827;110C 1166 11B2; # (젧; 젧; 젧; 젧; 젧; ) HANGUL SYLLABLE JELB
+C828;C828;110C 1166 11B3;C828;110C 1166 11B3; # (젨; 젨; 젨; 젨; 젨; ) HANGUL SYLLABLE JELS
+C829;C829;110C 1166 11B4;C829;110C 1166 11B4; # (젩; 젩; 젩; 젩; 젩; ) HANGUL SYLLABLE JELT
+C82A;C82A;110C 1166 11B5;C82A;110C 1166 11B5; # (젪; 젪; 젪; 젪; 젪; ) HANGUL SYLLABLE JELP
+C82B;C82B;110C 1166 11B6;C82B;110C 1166 11B6; # (젫; 젫; 젫; 젫; 젫; ) HANGUL SYLLABLE JELH
+C82C;C82C;110C 1166 11B7;C82C;110C 1166 11B7; # (젬; 젬; 젬; 젬; 젬; ) HANGUL SYLLABLE JEM
+C82D;C82D;110C 1166 11B8;C82D;110C 1166 11B8; # (젭; 젭; 젭; 젭; 젭; ) HANGUL SYLLABLE JEB
+C82E;C82E;110C 1166 11B9;C82E;110C 1166 11B9; # (젮; 젮; 젮; 젮; 젮; ) HANGUL SYLLABLE JEBS
+C82F;C82F;110C 1166 11BA;C82F;110C 1166 11BA; # (젯; 젯; 젯; 젯; 젯; ) HANGUL SYLLABLE JES
+C830;C830;110C 1166 11BB;C830;110C 1166 11BB; # (젰; 젰; 젰; 젰; 젰; ) HANGUL SYLLABLE JESS
+C831;C831;110C 1166 11BC;C831;110C 1166 11BC; # (젱; 젱; 젱; 젱; 젱; ) HANGUL SYLLABLE JENG
+C832;C832;110C 1166 11BD;C832;110C 1166 11BD; # (젲; 젲; 젲; 젲; 젲; ) HANGUL SYLLABLE JEJ
+C833;C833;110C 1166 11BE;C833;110C 1166 11BE; # (젳; 젳; 젳; 젳; 젳; ) HANGUL SYLLABLE JEC
+C834;C834;110C 1166 11BF;C834;110C 1166 11BF; # (젴; 젴; 젴; 젴; 젴; ) HANGUL SYLLABLE JEK
+C835;C835;110C 1166 11C0;C835;110C 1166 11C0; # (젵; 젵; 젵; 젵; 젵; ) HANGUL SYLLABLE JET
+C836;C836;110C 1166 11C1;C836;110C 1166 11C1; # (젶; 젶; 젶; 젶; 젶; ) HANGUL SYLLABLE JEP
+C837;C837;110C 1166 11C2;C837;110C 1166 11C2; # (젷; 젷; 젷; 젷; 젷; ) HANGUL SYLLABLE JEH
+C838;C838;110C 1167;C838;110C 1167; # (져; 져; 져; 져; 져; ) HANGUL SYLLABLE JYEO
+C839;C839;110C 1167 11A8;C839;110C 1167 11A8; # (젹; 젹; 젹; 젹; 젹; ) HANGUL SYLLABLE JYEOG
+C83A;C83A;110C 1167 11A9;C83A;110C 1167 11A9; # (젺; 젺; 젺; 젺; 젺; ) HANGUL SYLLABLE JYEOGG
+C83B;C83B;110C 1167 11AA;C83B;110C 1167 11AA; # (젻; 젻; 젻; 젻; 젻; ) HANGUL SYLLABLE JYEOGS
+C83C;C83C;110C 1167 11AB;C83C;110C 1167 11AB; # (젼; 젼; 젼; 젼; 젼; ) HANGUL SYLLABLE JYEON
+C83D;C83D;110C 1167 11AC;C83D;110C 1167 11AC; # (젽; 젽; 젽; 젽; 젽; ) HANGUL SYLLABLE JYEONJ
+C83E;C83E;110C 1167 11AD;C83E;110C 1167 11AD; # (젾; 젾; 젾; 젾; 젾; ) HANGUL SYLLABLE JYEONH
+C83F;C83F;110C 1167 11AE;C83F;110C 1167 11AE; # (젿; 젿; 젿; 젿; 젿; ) HANGUL SYLLABLE JYEOD
+C840;C840;110C 1167 11AF;C840;110C 1167 11AF; # (졀; 졀; 졀; 졀; 졀; ) HANGUL SYLLABLE JYEOL
+C841;C841;110C 1167 11B0;C841;110C 1167 11B0; # (졁; 졁; 졁; 졁; 졁; ) HANGUL SYLLABLE JYEOLG
+C842;C842;110C 1167 11B1;C842;110C 1167 11B1; # (졂; 졂; 졂; 졂; 졂; ) HANGUL SYLLABLE JYEOLM
+C843;C843;110C 1167 11B2;C843;110C 1167 11B2; # (졃; 졃; 졃; 졃; 졃; ) HANGUL SYLLABLE JYEOLB
+C844;C844;110C 1167 11B3;C844;110C 1167 11B3; # (졄; 졄; 졄; 졄; 졄; ) HANGUL SYLLABLE JYEOLS
+C845;C845;110C 1167 11B4;C845;110C 1167 11B4; # (졅; 졅; 졅; 졅; 졅; ) HANGUL SYLLABLE JYEOLT
+C846;C846;110C 1167 11B5;C846;110C 1167 11B5; # (졆; 졆; 졆; 졆; 졆; ) HANGUL SYLLABLE JYEOLP
+C847;C847;110C 1167 11B6;C847;110C 1167 11B6; # (졇; 졇; 졇; 졇; 졇; ) HANGUL SYLLABLE JYEOLH
+C848;C848;110C 1167 11B7;C848;110C 1167 11B7; # (졈; 졈; 졈; 졈; 졈; ) HANGUL SYLLABLE JYEOM
+C849;C849;110C 1167 11B8;C849;110C 1167 11B8; # (졉; 졉; 졉; 졉; 졉; ) HANGUL SYLLABLE JYEOB
+C84A;C84A;110C 1167 11B9;C84A;110C 1167 11B9; # (졊; 졊; 졊; 졊; 졊; ) HANGUL SYLLABLE JYEOBS
+C84B;C84B;110C 1167 11BA;C84B;110C 1167 11BA; # (졋; 졋; 졋; 졋; 졋; ) HANGUL SYLLABLE JYEOS
+C84C;C84C;110C 1167 11BB;C84C;110C 1167 11BB; # (졌; 졌; 졌; 졌; 졌; ) HANGUL SYLLABLE JYEOSS
+C84D;C84D;110C 1167 11BC;C84D;110C 1167 11BC; # (졍; 졍; 졍; 졍; 졍; ) HANGUL SYLLABLE JYEONG
+C84E;C84E;110C 1167 11BD;C84E;110C 1167 11BD; # (졎; 졎; 졎; 졎; 졎; ) HANGUL SYLLABLE JYEOJ
+C84F;C84F;110C 1167 11BE;C84F;110C 1167 11BE; # (졏; 졏; 졏; 졏; 졏; ) HANGUL SYLLABLE JYEOC
+C850;C850;110C 1167 11BF;C850;110C 1167 11BF; # (졐; 졐; 졐; 졐; 졐; ) HANGUL SYLLABLE JYEOK
+C851;C851;110C 1167 11C0;C851;110C 1167 11C0; # (졑; 졑; 졑; 졑; 졑; ) HANGUL SYLLABLE JYEOT
+C852;C852;110C 1167 11C1;C852;110C 1167 11C1; # (졒; 졒; 졒; 졒; 졒; ) HANGUL SYLLABLE JYEOP
+C853;C853;110C 1167 11C2;C853;110C 1167 11C2; # (졓; 졓; 졓; 졓; 졓; ) HANGUL SYLLABLE JYEOH
+C854;C854;110C 1168;C854;110C 1168; # (졔; 졔; 졔; 졔; 졔; ) HANGUL SYLLABLE JYE
+C855;C855;110C 1168 11A8;C855;110C 1168 11A8; # (졕; 졕; 졕; 졕; 졕; ) HANGUL SYLLABLE JYEG
+C856;C856;110C 1168 11A9;C856;110C 1168 11A9; # (졖; 졖; 졖; 졖; 졖; ) HANGUL SYLLABLE JYEGG
+C857;C857;110C 1168 11AA;C857;110C 1168 11AA; # (졗; 졗; 졗; 졗; 졗; ) HANGUL SYLLABLE JYEGS
+C858;C858;110C 1168 11AB;C858;110C 1168 11AB; # (졘; 졘; 졘; 졘; 졘; ) HANGUL SYLLABLE JYEN
+C859;C859;110C 1168 11AC;C859;110C 1168 11AC; # (졙; 졙; 졙; 졙; 졙; ) HANGUL SYLLABLE JYENJ
+C85A;C85A;110C 1168 11AD;C85A;110C 1168 11AD; # (졚; 졚; 졚; 졚; 졚; ) HANGUL SYLLABLE JYENH
+C85B;C85B;110C 1168 11AE;C85B;110C 1168 11AE; # (졛; 졛; 졛; 졛; 졛; ) HANGUL SYLLABLE JYED
+C85C;C85C;110C 1168 11AF;C85C;110C 1168 11AF; # (졜; 졜; 졜; 졜; 졜; ) HANGUL SYLLABLE JYEL
+C85D;C85D;110C 1168 11B0;C85D;110C 1168 11B0; # (졝; 졝; 졝; 졝; 졝; ) HANGUL SYLLABLE JYELG
+C85E;C85E;110C 1168 11B1;C85E;110C 1168 11B1; # (졞; 졞; 졞; 졞; 졞; ) HANGUL SYLLABLE JYELM
+C85F;C85F;110C 1168 11B2;C85F;110C 1168 11B2; # (졟; 졟; 졟; 졟; 졟; ) HANGUL SYLLABLE JYELB
+C860;C860;110C 1168 11B3;C860;110C 1168 11B3; # (졠; 졠; 졠; 졠; 졠; ) HANGUL SYLLABLE JYELS
+C861;C861;110C 1168 11B4;C861;110C 1168 11B4; # (졡; 졡; 졡; 졡; 졡; ) HANGUL SYLLABLE JYELT
+C862;C862;110C 1168 11B5;C862;110C 1168 11B5; # (졢; 졢; 졢; 졢; 졢; ) HANGUL SYLLABLE JYELP
+C863;C863;110C 1168 11B6;C863;110C 1168 11B6; # (졣; 졣; 졣; 졣; 졣; ) HANGUL SYLLABLE JYELH
+C864;C864;110C 1168 11B7;C864;110C 1168 11B7; # (졤; 졤; 졤; 졤; 졤; ) HANGUL SYLLABLE JYEM
+C865;C865;110C 1168 11B8;C865;110C 1168 11B8; # (졥; 졥; 졥; 졥; 졥; ) HANGUL SYLLABLE JYEB
+C866;C866;110C 1168 11B9;C866;110C 1168 11B9; # (졦; 졦; 졦; 졦; 졦; ) HANGUL SYLLABLE JYEBS
+C867;C867;110C 1168 11BA;C867;110C 1168 11BA; # (졧; 졧; 졧; 졧; 졧; ) HANGUL SYLLABLE JYES
+C868;C868;110C 1168 11BB;C868;110C 1168 11BB; # (졨; 졨; 졨; 졨; 졨; ) HANGUL SYLLABLE JYESS
+C869;C869;110C 1168 11BC;C869;110C 1168 11BC; # (졩; 졩; 졩; 졩; 졩; ) HANGUL SYLLABLE JYENG
+C86A;C86A;110C 1168 11BD;C86A;110C 1168 11BD; # (졪; 졪; 졪; 졪; 졪; ) HANGUL SYLLABLE JYEJ
+C86B;C86B;110C 1168 11BE;C86B;110C 1168 11BE; # (졫; 졫; 졫; 졫; 졫; ) HANGUL SYLLABLE JYEC
+C86C;C86C;110C 1168 11BF;C86C;110C 1168 11BF; # (졬; 졬; 졬; 졬; 졬; ) HANGUL SYLLABLE JYEK
+C86D;C86D;110C 1168 11C0;C86D;110C 1168 11C0; # (졭; 졭; 졭; 졭; 졭; ) HANGUL SYLLABLE JYET
+C86E;C86E;110C 1168 11C1;C86E;110C 1168 11C1; # (졮; 졮; 졮; 졮; 졮; ) HANGUL SYLLABLE JYEP
+C86F;C86F;110C 1168 11C2;C86F;110C 1168 11C2; # (졯; 졯; 졯; 졯; 졯; ) HANGUL SYLLABLE JYEH
+C870;C870;110C 1169;C870;110C 1169; # (조; 조; 조; 조; 조; ) HANGUL SYLLABLE JO
+C871;C871;110C 1169 11A8;C871;110C 1169 11A8; # (족; 족; 족; 족; 족; ) HANGUL SYLLABLE JOG
+C872;C872;110C 1169 11A9;C872;110C 1169 11A9; # (졲; 졲; 졲; 졲; 졲; ) HANGUL SYLLABLE JOGG
+C873;C873;110C 1169 11AA;C873;110C 1169 11AA; # (졳; 졳; 졳; 졳; 졳; ) HANGUL SYLLABLE JOGS
+C874;C874;110C 1169 11AB;C874;110C 1169 11AB; # (존; 존; 존; 존; 존; ) HANGUL SYLLABLE JON
+C875;C875;110C 1169 11AC;C875;110C 1169 11AC; # (졵; 졵; 졵; 졵; 졵; ) HANGUL SYLLABLE JONJ
+C876;C876;110C 1169 11AD;C876;110C 1169 11AD; # (졶; 졶; 졶; 졶; 졶; ) HANGUL SYLLABLE JONH
+C877;C877;110C 1169 11AE;C877;110C 1169 11AE; # (졷; 졷; 졷; 졷; 졷; ) HANGUL SYLLABLE JOD
+C878;C878;110C 1169 11AF;C878;110C 1169 11AF; # (졸; 졸; 졸; 졸; 졸; ) HANGUL SYLLABLE JOL
+C879;C879;110C 1169 11B0;C879;110C 1169 11B0; # (졹; 졹; 졹; 졹; 졹; ) HANGUL SYLLABLE JOLG
+C87A;C87A;110C 1169 11B1;C87A;110C 1169 11B1; # (졺; 졺; 졺; 졺; 졺; ) HANGUL SYLLABLE JOLM
+C87B;C87B;110C 1169 11B2;C87B;110C 1169 11B2; # (졻; 졻; 졻; 졻; 졻; ) HANGUL SYLLABLE JOLB
+C87C;C87C;110C 1169 11B3;C87C;110C 1169 11B3; # (졼; 졼; 졼; 졼; 졼; ) HANGUL SYLLABLE JOLS
+C87D;C87D;110C 1169 11B4;C87D;110C 1169 11B4; # (졽; 졽; 졽; 졽; 졽; ) HANGUL SYLLABLE JOLT
+C87E;C87E;110C 1169 11B5;C87E;110C 1169 11B5; # (졾; 졾; 졾; 졾; 졾; ) HANGUL SYLLABLE JOLP
+C87F;C87F;110C 1169 11B6;C87F;110C 1169 11B6; # (졿; 졿; 졿; 졿; 졿; ) HANGUL SYLLABLE JOLH
+C880;C880;110C 1169 11B7;C880;110C 1169 11B7; # (좀; 좀; 좀; 좀; 좀; ) HANGUL SYLLABLE JOM
+C881;C881;110C 1169 11B8;C881;110C 1169 11B8; # (좁; 좁; 좁; 좁; 좁; ) HANGUL SYLLABLE JOB
+C882;C882;110C 1169 11B9;C882;110C 1169 11B9; # (좂; 좂; 좂; 좂; 좂; ) HANGUL SYLLABLE JOBS
+C883;C883;110C 1169 11BA;C883;110C 1169 11BA; # (좃; 좃; 좃; 좃; 좃; ) HANGUL SYLLABLE JOS
+C884;C884;110C 1169 11BB;C884;110C 1169 11BB; # (좄; 좄; 좄; 좄; 좄; ) HANGUL SYLLABLE JOSS
+C885;C885;110C 1169 11BC;C885;110C 1169 11BC; # (종; 종; 종; 종; 종; ) HANGUL SYLLABLE JONG
+C886;C886;110C 1169 11BD;C886;110C 1169 11BD; # (좆; 좆; 좆; 좆; 좆; ) HANGUL SYLLABLE JOJ
+C887;C887;110C 1169 11BE;C887;110C 1169 11BE; # (좇; 좇; 좇; 좇; 좇; ) HANGUL SYLLABLE JOC
+C888;C888;110C 1169 11BF;C888;110C 1169 11BF; # (좈; 좈; 좈; 좈; 좈; ) HANGUL SYLLABLE JOK
+C889;C889;110C 1169 11C0;C889;110C 1169 11C0; # (좉; 좉; 좉; 좉; 좉; ) HANGUL SYLLABLE JOT
+C88A;C88A;110C 1169 11C1;C88A;110C 1169 11C1; # (좊; 좊; 좊; 좊; 좊; ) HANGUL SYLLABLE JOP
+C88B;C88B;110C 1169 11C2;C88B;110C 1169 11C2; # (좋; 좋; 좋; 좋; 좋; ) HANGUL SYLLABLE JOH
+C88C;C88C;110C 116A;C88C;110C 116A; # (좌; 좌; 좌; 좌; 좌; ) HANGUL SYLLABLE JWA
+C88D;C88D;110C 116A 11A8;C88D;110C 116A 11A8; # (좍; 좍; 좍; 좍; 좍; ) HANGUL SYLLABLE JWAG
+C88E;C88E;110C 116A 11A9;C88E;110C 116A 11A9; # (좎; 좎; 좎; 좎; 좎; ) HANGUL SYLLABLE JWAGG
+C88F;C88F;110C 116A 11AA;C88F;110C 116A 11AA; # (좏; 좏; 좏; 좏; 좏; ) HANGUL SYLLABLE JWAGS
+C890;C890;110C 116A 11AB;C890;110C 116A 11AB; # (좐; 좐; 좐; 좐; 좐; ) HANGUL SYLLABLE JWAN
+C891;C891;110C 116A 11AC;C891;110C 116A 11AC; # (좑; 좑; 좑; 좑; 좑; ) HANGUL SYLLABLE JWANJ
+C892;C892;110C 116A 11AD;C892;110C 116A 11AD; # (좒; 좒; 좒; 좒; 좒; ) HANGUL SYLLABLE JWANH
+C893;C893;110C 116A 11AE;C893;110C 116A 11AE; # (좓; 좓; 좓; 좓; 좓; ) HANGUL SYLLABLE JWAD
+C894;C894;110C 116A 11AF;C894;110C 116A 11AF; # (좔; 좔; 좔; 좔; 좔; ) HANGUL SYLLABLE JWAL
+C895;C895;110C 116A 11B0;C895;110C 116A 11B0; # (좕; 좕; 좕; 좕; 좕; ) HANGUL SYLLABLE JWALG
+C896;C896;110C 116A 11B1;C896;110C 116A 11B1; # (좖; 좖; 좖; 좖; 좖; ) HANGUL SYLLABLE JWALM
+C897;C897;110C 116A 11B2;C897;110C 116A 11B2; # (좗; 좗; 좗; 좗; 좗; ) HANGUL SYLLABLE JWALB
+C898;C898;110C 116A 11B3;C898;110C 116A 11B3; # (좘; 좘; 좘; 좘; 좘; ) HANGUL SYLLABLE JWALS
+C899;C899;110C 116A 11B4;C899;110C 116A 11B4; # (좙; 좙; 좙; 좙; 좙; ) HANGUL SYLLABLE JWALT
+C89A;C89A;110C 116A 11B5;C89A;110C 116A 11B5; # (좚; 좚; 좚; 좚; 좚; ) HANGUL SYLLABLE JWALP
+C89B;C89B;110C 116A 11B6;C89B;110C 116A 11B6; # (좛; 좛; 좛; 좛; 좛; ) HANGUL SYLLABLE JWALH
+C89C;C89C;110C 116A 11B7;C89C;110C 116A 11B7; # (좜; 좜; 좜; 좜; 좜; ) HANGUL SYLLABLE JWAM
+C89D;C89D;110C 116A 11B8;C89D;110C 116A 11B8; # (좝; 좝; 좝; 좝; 좝; ) HANGUL SYLLABLE JWAB
+C89E;C89E;110C 116A 11B9;C89E;110C 116A 11B9; # (좞; 좞; 좞; 좞; 좞; ) HANGUL SYLLABLE JWABS
+C89F;C89F;110C 116A 11BA;C89F;110C 116A 11BA; # (좟; 좟; 좟; 좟; 좟; ) HANGUL SYLLABLE JWAS
+C8A0;C8A0;110C 116A 11BB;C8A0;110C 116A 11BB; # (좠; 좠; 좠; 좠; 좠; ) HANGUL SYLLABLE JWASS
+C8A1;C8A1;110C 116A 11BC;C8A1;110C 116A 11BC; # (좡; 좡; 좡; 좡; 좡; ) HANGUL SYLLABLE JWANG
+C8A2;C8A2;110C 116A 11BD;C8A2;110C 116A 11BD; # (좢; 좢; 좢; 좢; 좢; ) HANGUL SYLLABLE JWAJ
+C8A3;C8A3;110C 116A 11BE;C8A3;110C 116A 11BE; # (좣; 좣; 좣; 좣; 좣; ) HANGUL SYLLABLE JWAC
+C8A4;C8A4;110C 116A 11BF;C8A4;110C 116A 11BF; # (좤; 좤; 좤; 좤; 좤; ) HANGUL SYLLABLE JWAK
+C8A5;C8A5;110C 116A 11C0;C8A5;110C 116A 11C0; # (좥; 좥; 좥; 좥; 좥; ) HANGUL SYLLABLE JWAT
+C8A6;C8A6;110C 116A 11C1;C8A6;110C 116A 11C1; # (좦; 좦; 좦; 좦; 좦; ) HANGUL SYLLABLE JWAP
+C8A7;C8A7;110C 116A 11C2;C8A7;110C 116A 11C2; # (좧; 좧; 좧; 좧; 좧; ) HANGUL SYLLABLE JWAH
+C8A8;C8A8;110C 116B;C8A8;110C 116B; # (좨; 좨; 좨; 좨; 좨; ) HANGUL SYLLABLE JWAE
+C8A9;C8A9;110C 116B 11A8;C8A9;110C 116B 11A8; # (좩; 좩; 좩; 좩; 좩; ) HANGUL SYLLABLE JWAEG
+C8AA;C8AA;110C 116B 11A9;C8AA;110C 116B 11A9; # (좪; 좪; 좪; 좪; 좪; ) HANGUL SYLLABLE JWAEGG
+C8AB;C8AB;110C 116B 11AA;C8AB;110C 116B 11AA; # (좫; 좫; 좫; 좫; 좫; ) HANGUL SYLLABLE JWAEGS
+C8AC;C8AC;110C 116B 11AB;C8AC;110C 116B 11AB; # (좬; 좬; 좬; 좬; 좬; ) HANGUL SYLLABLE JWAEN
+C8AD;C8AD;110C 116B 11AC;C8AD;110C 116B 11AC; # (좭; 좭; 좭; 좭; 좭; ) HANGUL SYLLABLE JWAENJ
+C8AE;C8AE;110C 116B 11AD;C8AE;110C 116B 11AD; # (좮; 좮; 좮; 좮; 좮; ) HANGUL SYLLABLE JWAENH
+C8AF;C8AF;110C 116B 11AE;C8AF;110C 116B 11AE; # (좯; 좯; 좯; 좯; 좯; ) HANGUL SYLLABLE JWAED
+C8B0;C8B0;110C 116B 11AF;C8B0;110C 116B 11AF; # (좰; 좰; 좰; 좰; 좰; ) HANGUL SYLLABLE JWAEL
+C8B1;C8B1;110C 116B 11B0;C8B1;110C 116B 11B0; # (좱; 좱; 좱; 좱; 좱; ) HANGUL SYLLABLE JWAELG
+C8B2;C8B2;110C 116B 11B1;C8B2;110C 116B 11B1; # (좲; 좲; 좲; 좲; 좲; ) HANGUL SYLLABLE JWAELM
+C8B3;C8B3;110C 116B 11B2;C8B3;110C 116B 11B2; # (좳; 좳; 좳; 좳; 좳; ) HANGUL SYLLABLE JWAELB
+C8B4;C8B4;110C 116B 11B3;C8B4;110C 116B 11B3; # (좴; 좴; 좴; 좴; 좴; ) HANGUL SYLLABLE JWAELS
+C8B5;C8B5;110C 116B 11B4;C8B5;110C 116B 11B4; # (좵; 좵; 좵; 좵; 좵; ) HANGUL SYLLABLE JWAELT
+C8B6;C8B6;110C 116B 11B5;C8B6;110C 116B 11B5; # (좶; 좶; 좶; 좶; 좶; ) HANGUL SYLLABLE JWAELP
+C8B7;C8B7;110C 116B 11B6;C8B7;110C 116B 11B6; # (좷; 좷; 좷; 좷; 좷; ) HANGUL SYLLABLE JWAELH
+C8B8;C8B8;110C 116B 11B7;C8B8;110C 116B 11B7; # (좸; 좸; 좸; 좸; 좸; ) HANGUL SYLLABLE JWAEM
+C8B9;C8B9;110C 116B 11B8;C8B9;110C 116B 11B8; # (좹; 좹; 좹; 좹; 좹; ) HANGUL SYLLABLE JWAEB
+C8BA;C8BA;110C 116B 11B9;C8BA;110C 116B 11B9; # (좺; 좺; 좺; 좺; 좺; ) HANGUL SYLLABLE JWAEBS
+C8BB;C8BB;110C 116B 11BA;C8BB;110C 116B 11BA; # (좻; 좻; 좻; 좻; 좻; ) HANGUL SYLLABLE JWAES
+C8BC;C8BC;110C 116B 11BB;C8BC;110C 116B 11BB; # (좼; 좼; 좼; 좼; 좼; ) HANGUL SYLLABLE JWAESS
+C8BD;C8BD;110C 116B 11BC;C8BD;110C 116B 11BC; # (좽; 좽; 좽; 좽; 좽; ) HANGUL SYLLABLE JWAENG
+C8BE;C8BE;110C 116B 11BD;C8BE;110C 116B 11BD; # (좾; 좾; 좾; 좾; 좾; ) HANGUL SYLLABLE JWAEJ
+C8BF;C8BF;110C 116B 11BE;C8BF;110C 116B 11BE; # (좿; 좿; 좿; 좿; 좿; ) HANGUL SYLLABLE JWAEC
+C8C0;C8C0;110C 116B 11BF;C8C0;110C 116B 11BF; # (죀; 죀; 죀; 죀; 죀; ) HANGUL SYLLABLE JWAEK
+C8C1;C8C1;110C 116B 11C0;C8C1;110C 116B 11C0; # (죁; 죁; 죁; 죁; 죁; ) HANGUL SYLLABLE JWAET
+C8C2;C8C2;110C 116B 11C1;C8C2;110C 116B 11C1; # (죂; 죂; 죂; 죂; 죂; ) HANGUL SYLLABLE JWAEP
+C8C3;C8C3;110C 116B 11C2;C8C3;110C 116B 11C2; # (죃; 죃; 죃; 죃; 죃; ) HANGUL SYLLABLE JWAEH
+C8C4;C8C4;110C 116C;C8C4;110C 116C; # (죄; 죄; 죄; 죄; 죄; ) HANGUL SYLLABLE JOE
+C8C5;C8C5;110C 116C 11A8;C8C5;110C 116C 11A8; # (죅; 죅; 죅; 죅; 죅; ) HANGUL SYLLABLE JOEG
+C8C6;C8C6;110C 116C 11A9;C8C6;110C 116C 11A9; # (죆; 죆; 죆; 죆; 죆; ) HANGUL SYLLABLE JOEGG
+C8C7;C8C7;110C 116C 11AA;C8C7;110C 116C 11AA; # (죇; 죇; 죇; 죇; 죇; ) HANGUL SYLLABLE JOEGS
+C8C8;C8C8;110C 116C 11AB;C8C8;110C 116C 11AB; # (죈; 죈; 죈; 죈; 죈; ) HANGUL SYLLABLE JOEN
+C8C9;C8C9;110C 116C 11AC;C8C9;110C 116C 11AC; # (죉; 죉; 죉; 죉; 죉; ) HANGUL SYLLABLE JOENJ
+C8CA;C8CA;110C 116C 11AD;C8CA;110C 116C 11AD; # (죊; 죊; 죊; 죊; 죊; ) HANGUL SYLLABLE JOENH
+C8CB;C8CB;110C 116C 11AE;C8CB;110C 116C 11AE; # (죋; 죋; 죋; 죋; 죋; ) HANGUL SYLLABLE JOED
+C8CC;C8CC;110C 116C 11AF;C8CC;110C 116C 11AF; # (죌; 죌; 죌; 죌; 죌; ) HANGUL SYLLABLE JOEL
+C8CD;C8CD;110C 116C 11B0;C8CD;110C 116C 11B0; # (죍; 죍; 죍; 죍; 죍; ) HANGUL SYLLABLE JOELG
+C8CE;C8CE;110C 116C 11B1;C8CE;110C 116C 11B1; # (죎; 죎; 죎; 죎; 죎; ) HANGUL SYLLABLE JOELM
+C8CF;C8CF;110C 116C 11B2;C8CF;110C 116C 11B2; # (죏; 죏; 죏; 죏; 죏; ) HANGUL SYLLABLE JOELB
+C8D0;C8D0;110C 116C 11B3;C8D0;110C 116C 11B3; # (죐; 죐; 죐; 죐; 죐; ) HANGUL SYLLABLE JOELS
+C8D1;C8D1;110C 116C 11B4;C8D1;110C 116C 11B4; # (죑; 죑; 죑; 죑; 죑; ) HANGUL SYLLABLE JOELT
+C8D2;C8D2;110C 116C 11B5;C8D2;110C 116C 11B5; # (죒; 죒; 죒; 죒; 죒; ) HANGUL SYLLABLE JOELP
+C8D3;C8D3;110C 116C 11B6;C8D3;110C 116C 11B6; # (죓; 죓; 죓; 죓; 죓; ) HANGUL SYLLABLE JOELH
+C8D4;C8D4;110C 116C 11B7;C8D4;110C 116C 11B7; # (죔; 죔; 죔; 죔; 죔; ) HANGUL SYLLABLE JOEM
+C8D5;C8D5;110C 116C 11B8;C8D5;110C 116C 11B8; # (죕; 죕; 죕; 죕; 죕; ) HANGUL SYLLABLE JOEB
+C8D6;C8D6;110C 116C 11B9;C8D6;110C 116C 11B9; # (죖; 죖; 죖; 죖; 죖; ) HANGUL SYLLABLE JOEBS
+C8D7;C8D7;110C 116C 11BA;C8D7;110C 116C 11BA; # (죗; 죗; 죗; 죗; 죗; ) HANGUL SYLLABLE JOES
+C8D8;C8D8;110C 116C 11BB;C8D8;110C 116C 11BB; # (죘; 죘; 죘; 죘; 죘; ) HANGUL SYLLABLE JOESS
+C8D9;C8D9;110C 116C 11BC;C8D9;110C 116C 11BC; # (죙; 죙; 죙; 죙; 죙; ) HANGUL SYLLABLE JOENG
+C8DA;C8DA;110C 116C 11BD;C8DA;110C 116C 11BD; # (죚; 죚; 죚; 죚; 죚; ) HANGUL SYLLABLE JOEJ
+C8DB;C8DB;110C 116C 11BE;C8DB;110C 116C 11BE; # (죛; 죛; 죛; 죛; 죛; ) HANGUL SYLLABLE JOEC
+C8DC;C8DC;110C 116C 11BF;C8DC;110C 116C 11BF; # (죜; 죜; 죜; 죜; 죜; ) HANGUL SYLLABLE JOEK
+C8DD;C8DD;110C 116C 11C0;C8DD;110C 116C 11C0; # (죝; 죝; 죝; 죝; 죝; ) HANGUL SYLLABLE JOET
+C8DE;C8DE;110C 116C 11C1;C8DE;110C 116C 11C1; # (죞; 죞; 죞; 죞; 죞; ) HANGUL SYLLABLE JOEP
+C8DF;C8DF;110C 116C 11C2;C8DF;110C 116C 11C2; # (죟; 죟; 죟; 죟; 죟; ) HANGUL SYLLABLE JOEH
+C8E0;C8E0;110C 116D;C8E0;110C 116D; # (죠; 죠; 죠; 죠; 죠; ) HANGUL SYLLABLE JYO
+C8E1;C8E1;110C 116D 11A8;C8E1;110C 116D 11A8; # (죡; 죡; 죡; 죡; 죡; ) HANGUL SYLLABLE JYOG
+C8E2;C8E2;110C 116D 11A9;C8E2;110C 116D 11A9; # (죢; 죢; 죢; 죢; 죢; ) HANGUL SYLLABLE JYOGG
+C8E3;C8E3;110C 116D 11AA;C8E3;110C 116D 11AA; # (죣; 죣; 죣; 죣; 죣; ) HANGUL SYLLABLE JYOGS
+C8E4;C8E4;110C 116D 11AB;C8E4;110C 116D 11AB; # (죤; 죤; 죤; 죤; 죤; ) HANGUL SYLLABLE JYON
+C8E5;C8E5;110C 116D 11AC;C8E5;110C 116D 11AC; # (죥; 죥; 죥; 죥; 죥; ) HANGUL SYLLABLE JYONJ
+C8E6;C8E6;110C 116D 11AD;C8E6;110C 116D 11AD; # (죦; 죦; 죦; 죦; 죦; ) HANGUL SYLLABLE JYONH
+C8E7;C8E7;110C 116D 11AE;C8E7;110C 116D 11AE; # (죧; 죧; 죧; 죧; 죧; ) HANGUL SYLLABLE JYOD
+C8E8;C8E8;110C 116D 11AF;C8E8;110C 116D 11AF; # (죨; 죨; 죨; 죨; 죨; ) HANGUL SYLLABLE JYOL
+C8E9;C8E9;110C 116D 11B0;C8E9;110C 116D 11B0; # (죩; 죩; 죩; 죩; 죩; ) HANGUL SYLLABLE JYOLG
+C8EA;C8EA;110C 116D 11B1;C8EA;110C 116D 11B1; # (죪; 죪; 죪; 죪; 죪; ) HANGUL SYLLABLE JYOLM
+C8EB;C8EB;110C 116D 11B2;C8EB;110C 116D 11B2; # (죫; 죫; 죫; 죫; 죫; ) HANGUL SYLLABLE JYOLB
+C8EC;C8EC;110C 116D 11B3;C8EC;110C 116D 11B3; # (죬; 죬; 죬; 죬; 죬; ) HANGUL SYLLABLE JYOLS
+C8ED;C8ED;110C 116D 11B4;C8ED;110C 116D 11B4; # (죭; 죭; 죭; 죭; 죭; ) HANGUL SYLLABLE JYOLT
+C8EE;C8EE;110C 116D 11B5;C8EE;110C 116D 11B5; # (죮; 죮; 죮; 죮; 죮; ) HANGUL SYLLABLE JYOLP
+C8EF;C8EF;110C 116D 11B6;C8EF;110C 116D 11B6; # (죯; 죯; 죯; 죯; 죯; ) HANGUL SYLLABLE JYOLH
+C8F0;C8F0;110C 116D 11B7;C8F0;110C 116D 11B7; # (죰; 죰; 죰; 죰; 죰; ) HANGUL SYLLABLE JYOM
+C8F1;C8F1;110C 116D 11B8;C8F1;110C 116D 11B8; # (죱; 죱; 죱; 죱; 죱; ) HANGUL SYLLABLE JYOB
+C8F2;C8F2;110C 116D 11B9;C8F2;110C 116D 11B9; # (죲; 죲; 죲; 죲; 죲; ) HANGUL SYLLABLE JYOBS
+C8F3;C8F3;110C 116D 11BA;C8F3;110C 116D 11BA; # (죳; 죳; 죳; 죳; 죳; ) HANGUL SYLLABLE JYOS
+C8F4;C8F4;110C 116D 11BB;C8F4;110C 116D 11BB; # (죴; 죴; 죴; 죴; 죴; ) HANGUL SYLLABLE JYOSS
+C8F5;C8F5;110C 116D 11BC;C8F5;110C 116D 11BC; # (죵; 죵; 죵; 죵; 죵; ) HANGUL SYLLABLE JYONG
+C8F6;C8F6;110C 116D 11BD;C8F6;110C 116D 11BD; # (죶; 죶; 죶; 죶; 죶; ) HANGUL SYLLABLE JYOJ
+C8F7;C8F7;110C 116D 11BE;C8F7;110C 116D 11BE; # (죷; 죷; 죷; 죷; 죷; ) HANGUL SYLLABLE JYOC
+C8F8;C8F8;110C 116D 11BF;C8F8;110C 116D 11BF; # (죸; 죸; 죸; 죸; 죸; ) HANGUL SYLLABLE JYOK
+C8F9;C8F9;110C 116D 11C0;C8F9;110C 116D 11C0; # (죹; 죹; 죹; 죹; 죹; ) HANGUL SYLLABLE JYOT
+C8FA;C8FA;110C 116D 11C1;C8FA;110C 116D 11C1; # (죺; 죺; 죺; 죺; 죺; ) HANGUL SYLLABLE JYOP
+C8FB;C8FB;110C 116D 11C2;C8FB;110C 116D 11C2; # (죻; 죻; 죻; 죻; 죻; ) HANGUL SYLLABLE JYOH
+C8FC;C8FC;110C 116E;C8FC;110C 116E; # (주; 주; 주; 주; 주; ) HANGUL SYLLABLE JU
+C8FD;C8FD;110C 116E 11A8;C8FD;110C 116E 11A8; # (죽; 죽; 죽; 죽; 죽; ) HANGUL SYLLABLE JUG
+C8FE;C8FE;110C 116E 11A9;C8FE;110C 116E 11A9; # (죾; 죾; 죾; 죾; 죾; ) HANGUL SYLLABLE JUGG
+C8FF;C8FF;110C 116E 11AA;C8FF;110C 116E 11AA; # (죿; 죿; 죿; 죿; 죿; ) HANGUL SYLLABLE JUGS
+C900;C900;110C 116E 11AB;C900;110C 116E 11AB; # (준; 준; 준; 준; 준; ) HANGUL SYLLABLE JUN
+C901;C901;110C 116E 11AC;C901;110C 116E 11AC; # (줁; 줁; 줁; 줁; 줁; ) HANGUL SYLLABLE JUNJ
+C902;C902;110C 116E 11AD;C902;110C 116E 11AD; # (줂; 줂; 줂; 줂; 줂; ) HANGUL SYLLABLE JUNH
+C903;C903;110C 116E 11AE;C903;110C 116E 11AE; # (줃; 줃; 줃; 줃; 줃; ) HANGUL SYLLABLE JUD
+C904;C904;110C 116E 11AF;C904;110C 116E 11AF; # (줄; 줄; 줄; 줄; 줄; ) HANGUL SYLLABLE JUL
+C905;C905;110C 116E 11B0;C905;110C 116E 11B0; # (줅; 줅; 줅; 줅; 줅; ) HANGUL SYLLABLE JULG
+C906;C906;110C 116E 11B1;C906;110C 116E 11B1; # (줆; 줆; 줆; 줆; 줆; ) HANGUL SYLLABLE JULM
+C907;C907;110C 116E 11B2;C907;110C 116E 11B2; # (줇; 줇; 줇; 줇; 줇; ) HANGUL SYLLABLE JULB
+C908;C908;110C 116E 11B3;C908;110C 116E 11B3; # (줈; 줈; 줈; 줈; 줈; ) HANGUL SYLLABLE JULS
+C909;C909;110C 116E 11B4;C909;110C 116E 11B4; # (줉; 줉; 줉; 줉; 줉; ) HANGUL SYLLABLE JULT
+C90A;C90A;110C 116E 11B5;C90A;110C 116E 11B5; # (줊; 줊; 줊; 줊; 줊; ) HANGUL SYLLABLE JULP
+C90B;C90B;110C 116E 11B6;C90B;110C 116E 11B6; # (줋; 줋; 줋; 줋; 줋; ) HANGUL SYLLABLE JULH
+C90C;C90C;110C 116E 11B7;C90C;110C 116E 11B7; # (줌; 줌; 줌; 줌; 줌; ) HANGUL SYLLABLE JUM
+C90D;C90D;110C 116E 11B8;C90D;110C 116E 11B8; # (줍; 줍; 줍; 줍; 줍; ) HANGUL SYLLABLE JUB
+C90E;C90E;110C 116E 11B9;C90E;110C 116E 11B9; # (줎; 줎; 줎; 줎; 줎; ) HANGUL SYLLABLE JUBS
+C90F;C90F;110C 116E 11BA;C90F;110C 116E 11BA; # (줏; 줏; 줏; 줏; 줏; ) HANGUL SYLLABLE JUS
+C910;C910;110C 116E 11BB;C910;110C 116E 11BB; # (줐; 줐; 줐; 줐; 줐; ) HANGUL SYLLABLE JUSS
+C911;C911;110C 116E 11BC;C911;110C 116E 11BC; # (중; 중; 중; 중; 중; ) HANGUL SYLLABLE JUNG
+C912;C912;110C 116E 11BD;C912;110C 116E 11BD; # (줒; 줒; 줒; 줒; 줒; ) HANGUL SYLLABLE JUJ
+C913;C913;110C 116E 11BE;C913;110C 116E 11BE; # (줓; 줓; 줓; 줓; 줓; ) HANGUL SYLLABLE JUC
+C914;C914;110C 116E 11BF;C914;110C 116E 11BF; # (줔; 줔; 줔; 줔; 줔; ) HANGUL SYLLABLE JUK
+C915;C915;110C 116E 11C0;C915;110C 116E 11C0; # (줕; 줕; 줕; 줕; 줕; ) HANGUL SYLLABLE JUT
+C916;C916;110C 116E 11C1;C916;110C 116E 11C1; # (줖; 줖; 줖; 줖; 줖; ) HANGUL SYLLABLE JUP
+C917;C917;110C 116E 11C2;C917;110C 116E 11C2; # (줗; 줗; 줗; 줗; 줗; ) HANGUL SYLLABLE JUH
+C918;C918;110C 116F;C918;110C 116F; # (줘; 줘; 줘; 줘; 줘; ) HANGUL SYLLABLE JWEO
+C919;C919;110C 116F 11A8;C919;110C 116F 11A8; # (줙; 줙; 줙; 줙; 줙; ) HANGUL SYLLABLE JWEOG
+C91A;C91A;110C 116F 11A9;C91A;110C 116F 11A9; # (줚; 줚; 줚; 줚; 줚; ) HANGUL SYLLABLE JWEOGG
+C91B;C91B;110C 116F 11AA;C91B;110C 116F 11AA; # (줛; 줛; 줛; 줛; 줛; ) HANGUL SYLLABLE JWEOGS
+C91C;C91C;110C 116F 11AB;C91C;110C 116F 11AB; # (줜; 줜; 줜; 줜; 줜; ) HANGUL SYLLABLE JWEON
+C91D;C91D;110C 116F 11AC;C91D;110C 116F 11AC; # (줝; 줝; 줝; 줝; 줝; ) HANGUL SYLLABLE JWEONJ
+C91E;C91E;110C 116F 11AD;C91E;110C 116F 11AD; # (줞; 줞; 줞; 줞; 줞; ) HANGUL SYLLABLE JWEONH
+C91F;C91F;110C 116F 11AE;C91F;110C 116F 11AE; # (줟; 줟; 줟; 줟; 줟; ) HANGUL SYLLABLE JWEOD
+C920;C920;110C 116F 11AF;C920;110C 116F 11AF; # (줠; 줠; 줠; 줠; 줠; ) HANGUL SYLLABLE JWEOL
+C921;C921;110C 116F 11B0;C921;110C 116F 11B0; # (줡; 줡; 줡; 줡; 줡; ) HANGUL SYLLABLE JWEOLG
+C922;C922;110C 116F 11B1;C922;110C 116F 11B1; # (줢; 줢; 줢; 줢; 줢; ) HANGUL SYLLABLE JWEOLM
+C923;C923;110C 116F 11B2;C923;110C 116F 11B2; # (줣; 줣; 줣; 줣; 줣; ) HANGUL SYLLABLE JWEOLB
+C924;C924;110C 116F 11B3;C924;110C 116F 11B3; # (줤; 줤; 줤; 줤; 줤; ) HANGUL SYLLABLE JWEOLS
+C925;C925;110C 116F 11B4;C925;110C 116F 11B4; # (줥; 줥; 줥; 줥; 줥; ) HANGUL SYLLABLE JWEOLT
+C926;C926;110C 116F 11B5;C926;110C 116F 11B5; # (줦; 줦; 줦; 줦; 줦; ) HANGUL SYLLABLE JWEOLP
+C927;C927;110C 116F 11B6;C927;110C 116F 11B6; # (줧; 줧; 줧; 줧; 줧; ) HANGUL SYLLABLE JWEOLH
+C928;C928;110C 116F 11B7;C928;110C 116F 11B7; # (줨; 줨; 줨; 줨; 줨; ) HANGUL SYLLABLE JWEOM
+C929;C929;110C 116F 11B8;C929;110C 116F 11B8; # (줩; 줩; 줩; 줩; 줩; ) HANGUL SYLLABLE JWEOB
+C92A;C92A;110C 116F 11B9;C92A;110C 116F 11B9; # (줪; 줪; 줪; 줪; 줪; ) HANGUL SYLLABLE JWEOBS
+C92B;C92B;110C 116F 11BA;C92B;110C 116F 11BA; # (줫; 줫; 줫; 줫; 줫; ) HANGUL SYLLABLE JWEOS
+C92C;C92C;110C 116F 11BB;C92C;110C 116F 11BB; # (줬; 줬; 줬; 줬; 줬; ) HANGUL SYLLABLE JWEOSS
+C92D;C92D;110C 116F 11BC;C92D;110C 116F 11BC; # (줭; 줭; 줭; 줭; 줭; ) HANGUL SYLLABLE JWEONG
+C92E;C92E;110C 116F 11BD;C92E;110C 116F 11BD; # (줮; 줮; 줮; 줮; 줮; ) HANGUL SYLLABLE JWEOJ
+C92F;C92F;110C 116F 11BE;C92F;110C 116F 11BE; # (줯; 줯; 줯; 줯; 줯; ) HANGUL SYLLABLE JWEOC
+C930;C930;110C 116F 11BF;C930;110C 116F 11BF; # (줰; 줰; 줰; 줰; 줰; ) HANGUL SYLLABLE JWEOK
+C931;C931;110C 116F 11C0;C931;110C 116F 11C0; # (줱; 줱; 줱; 줱; 줱; ) HANGUL SYLLABLE JWEOT
+C932;C932;110C 116F 11C1;C932;110C 116F 11C1; # (줲; 줲; 줲; 줲; 줲; ) HANGUL SYLLABLE JWEOP
+C933;C933;110C 116F 11C2;C933;110C 116F 11C2; # (줳; 줳; 줳; 줳; 줳; ) HANGUL SYLLABLE JWEOH
+C934;C934;110C 1170;C934;110C 1170; # (줴; 줴; 줴; 줴; 줴; ) HANGUL SYLLABLE JWE
+C935;C935;110C 1170 11A8;C935;110C 1170 11A8; # (줵; 줵; 줵; 줵; 줵; ) HANGUL SYLLABLE JWEG
+C936;C936;110C 1170 11A9;C936;110C 1170 11A9; # (줶; 줶; 줶; 줶; 줶; ) HANGUL SYLLABLE JWEGG
+C937;C937;110C 1170 11AA;C937;110C 1170 11AA; # (줷; 줷; 줷; 줷; 줷; ) HANGUL SYLLABLE JWEGS
+C938;C938;110C 1170 11AB;C938;110C 1170 11AB; # (줸; 줸; 줸; 줸; 줸; ) HANGUL SYLLABLE JWEN
+C939;C939;110C 1170 11AC;C939;110C 1170 11AC; # (줹; 줹; 줹; 줹; 줹; ) HANGUL SYLLABLE JWENJ
+C93A;C93A;110C 1170 11AD;C93A;110C 1170 11AD; # (줺; 줺; 줺; 줺; 줺; ) HANGUL SYLLABLE JWENH
+C93B;C93B;110C 1170 11AE;C93B;110C 1170 11AE; # (줻; 줻; 줻; 줻; 줻; ) HANGUL SYLLABLE JWED
+C93C;C93C;110C 1170 11AF;C93C;110C 1170 11AF; # (줼; 줼; 줼; 줼; 줼; ) HANGUL SYLLABLE JWEL
+C93D;C93D;110C 1170 11B0;C93D;110C 1170 11B0; # (줽; 줽; 줽; 줽; 줽; ) HANGUL SYLLABLE JWELG
+C93E;C93E;110C 1170 11B1;C93E;110C 1170 11B1; # (줾; 줾; 줾; 줾; 줾; ) HANGUL SYLLABLE JWELM
+C93F;C93F;110C 1170 11B2;C93F;110C 1170 11B2; # (줿; 줿; 줿; 줿; 줿; ) HANGUL SYLLABLE JWELB
+C940;C940;110C 1170 11B3;C940;110C 1170 11B3; # (쥀; 쥀; 쥀; 쥀; 쥀; ) HANGUL SYLLABLE JWELS
+C941;C941;110C 1170 11B4;C941;110C 1170 11B4; # (쥁; 쥁; 쥁; 쥁; 쥁; ) HANGUL SYLLABLE JWELT
+C942;C942;110C 1170 11B5;C942;110C 1170 11B5; # (쥂; 쥂; 쥂; 쥂; 쥂; ) HANGUL SYLLABLE JWELP
+C943;C943;110C 1170 11B6;C943;110C 1170 11B6; # (쥃; 쥃; 쥃; 쥃; 쥃; ) HANGUL SYLLABLE JWELH
+C944;C944;110C 1170 11B7;C944;110C 1170 11B7; # (쥄; 쥄; 쥄; 쥄; 쥄; ) HANGUL SYLLABLE JWEM
+C945;C945;110C 1170 11B8;C945;110C 1170 11B8; # (쥅; 쥅; 쥅; 쥅; 쥅; ) HANGUL SYLLABLE JWEB
+C946;C946;110C 1170 11B9;C946;110C 1170 11B9; # (쥆; 쥆; 쥆; 쥆; 쥆; ) HANGUL SYLLABLE JWEBS
+C947;C947;110C 1170 11BA;C947;110C 1170 11BA; # (쥇; 쥇; 쥇; 쥇; 쥇; ) HANGUL SYLLABLE JWES
+C948;C948;110C 1170 11BB;C948;110C 1170 11BB; # (쥈; 쥈; 쥈; 쥈; 쥈; ) HANGUL SYLLABLE JWESS
+C949;C949;110C 1170 11BC;C949;110C 1170 11BC; # (쥉; 쥉; 쥉; 쥉; 쥉; ) HANGUL SYLLABLE JWENG
+C94A;C94A;110C 1170 11BD;C94A;110C 1170 11BD; # (쥊; 쥊; 쥊; 쥊; 쥊; ) HANGUL SYLLABLE JWEJ
+C94B;C94B;110C 1170 11BE;C94B;110C 1170 11BE; # (쥋; 쥋; 쥋; 쥋; 쥋; ) HANGUL SYLLABLE JWEC
+C94C;C94C;110C 1170 11BF;C94C;110C 1170 11BF; # (쥌; 쥌; 쥌; 쥌; 쥌; ) HANGUL SYLLABLE JWEK
+C94D;C94D;110C 1170 11C0;C94D;110C 1170 11C0; # (쥍; 쥍; 쥍; 쥍; 쥍; ) HANGUL SYLLABLE JWET
+C94E;C94E;110C 1170 11C1;C94E;110C 1170 11C1; # (쥎; 쥎; 쥎; 쥎; 쥎; ) HANGUL SYLLABLE JWEP
+C94F;C94F;110C 1170 11C2;C94F;110C 1170 11C2; # (쥏; 쥏; 쥏; 쥏; 쥏; ) HANGUL SYLLABLE JWEH
+C950;C950;110C 1171;C950;110C 1171; # (쥐; 쥐; 쥐; 쥐; 쥐; ) HANGUL SYLLABLE JWI
+C951;C951;110C 1171 11A8;C951;110C 1171 11A8; # (쥑; 쥑; 쥑; 쥑; 쥑; ) HANGUL SYLLABLE JWIG
+C952;C952;110C 1171 11A9;C952;110C 1171 11A9; # (쥒; 쥒; 쥒; 쥒; 쥒; ) HANGUL SYLLABLE JWIGG
+C953;C953;110C 1171 11AA;C953;110C 1171 11AA; # (쥓; 쥓; 쥓; 쥓; 쥓; ) HANGUL SYLLABLE JWIGS
+C954;C954;110C 1171 11AB;C954;110C 1171 11AB; # (쥔; 쥔; 쥔; 쥔; 쥔; ) HANGUL SYLLABLE JWIN
+C955;C955;110C 1171 11AC;C955;110C 1171 11AC; # (쥕; 쥕; 쥕; 쥕; 쥕; ) HANGUL SYLLABLE JWINJ
+C956;C956;110C 1171 11AD;C956;110C 1171 11AD; # (쥖; 쥖; 쥖; 쥖; 쥖; ) HANGUL SYLLABLE JWINH
+C957;C957;110C 1171 11AE;C957;110C 1171 11AE; # (쥗; 쥗; 쥗; 쥗; 쥗; ) HANGUL SYLLABLE JWID
+C958;C958;110C 1171 11AF;C958;110C 1171 11AF; # (쥘; 쥘; 쥘; 쥘; 쥘; ) HANGUL SYLLABLE JWIL
+C959;C959;110C 1171 11B0;C959;110C 1171 11B0; # (쥙; 쥙; 쥙; 쥙; 쥙; ) HANGUL SYLLABLE JWILG
+C95A;C95A;110C 1171 11B1;C95A;110C 1171 11B1; # (쥚; 쥚; 쥚; 쥚; 쥚; ) HANGUL SYLLABLE JWILM
+C95B;C95B;110C 1171 11B2;C95B;110C 1171 11B2; # (쥛; 쥛; 쥛; 쥛; 쥛; ) HANGUL SYLLABLE JWILB
+C95C;C95C;110C 1171 11B3;C95C;110C 1171 11B3; # (쥜; 쥜; 쥜; 쥜; 쥜; ) HANGUL SYLLABLE JWILS
+C95D;C95D;110C 1171 11B4;C95D;110C 1171 11B4; # (쥝; 쥝; 쥝; 쥝; 쥝; ) HANGUL SYLLABLE JWILT
+C95E;C95E;110C 1171 11B5;C95E;110C 1171 11B5; # (쥞; 쥞; 쥞; 쥞; 쥞; ) HANGUL SYLLABLE JWILP
+C95F;C95F;110C 1171 11B6;C95F;110C 1171 11B6; # (쥟; 쥟; 쥟; 쥟; 쥟; ) HANGUL SYLLABLE JWILH
+C960;C960;110C 1171 11B7;C960;110C 1171 11B7; # (쥠; 쥠; 쥠; 쥠; 쥠; ) HANGUL SYLLABLE JWIM
+C961;C961;110C 1171 11B8;C961;110C 1171 11B8; # (쥡; 쥡; 쥡; 쥡; 쥡; ) HANGUL SYLLABLE JWIB
+C962;C962;110C 1171 11B9;C962;110C 1171 11B9; # (쥢; 쥢; 쥢; 쥢; 쥢; ) HANGUL SYLLABLE JWIBS
+C963;C963;110C 1171 11BA;C963;110C 1171 11BA; # (쥣; 쥣; 쥣; 쥣; 쥣; ) HANGUL SYLLABLE JWIS
+C964;C964;110C 1171 11BB;C964;110C 1171 11BB; # (쥤; 쥤; 쥤; 쥤; 쥤; ) HANGUL SYLLABLE JWISS
+C965;C965;110C 1171 11BC;C965;110C 1171 11BC; # (쥥; 쥥; 쥥; 쥥; 쥥; ) HANGUL SYLLABLE JWING
+C966;C966;110C 1171 11BD;C966;110C 1171 11BD; # (쥦; 쥦; 쥦; 쥦; 쥦; ) HANGUL SYLLABLE JWIJ
+C967;C967;110C 1171 11BE;C967;110C 1171 11BE; # (쥧; 쥧; 쥧; 쥧; 쥧; ) HANGUL SYLLABLE JWIC
+C968;C968;110C 1171 11BF;C968;110C 1171 11BF; # (쥨; 쥨; 쥨; 쥨; 쥨; ) HANGUL SYLLABLE JWIK
+C969;C969;110C 1171 11C0;C969;110C 1171 11C0; # (쥩; 쥩; 쥩; 쥩; 쥩; ) HANGUL SYLLABLE JWIT
+C96A;C96A;110C 1171 11C1;C96A;110C 1171 11C1; # (쥪; 쥪; 쥪; 쥪; 쥪; ) HANGUL SYLLABLE JWIP
+C96B;C96B;110C 1171 11C2;C96B;110C 1171 11C2; # (쥫; 쥫; 쥫; 쥫; 쥫; ) HANGUL SYLLABLE JWIH
+C96C;C96C;110C 1172;C96C;110C 1172; # (쥬; 쥬; 쥬; 쥬; 쥬; ) HANGUL SYLLABLE JYU
+C96D;C96D;110C 1172 11A8;C96D;110C 1172 11A8; # (쥭; 쥭; 쥭; 쥭; 쥭; ) HANGUL SYLLABLE JYUG
+C96E;C96E;110C 1172 11A9;C96E;110C 1172 11A9; # (쥮; 쥮; 쥮; 쥮; 쥮; ) HANGUL SYLLABLE JYUGG
+C96F;C96F;110C 1172 11AA;C96F;110C 1172 11AA; # (쥯; 쥯; 쥯; 쥯; 쥯; ) HANGUL SYLLABLE JYUGS
+C970;C970;110C 1172 11AB;C970;110C 1172 11AB; # (쥰; 쥰; 쥰; 쥰; 쥰; ) HANGUL SYLLABLE JYUN
+C971;C971;110C 1172 11AC;C971;110C 1172 11AC; # (쥱; 쥱; 쥱; 쥱; 쥱; ) HANGUL SYLLABLE JYUNJ
+C972;C972;110C 1172 11AD;C972;110C 1172 11AD; # (쥲; 쥲; 쥲; 쥲; 쥲; ) HANGUL SYLLABLE JYUNH
+C973;C973;110C 1172 11AE;C973;110C 1172 11AE; # (쥳; 쥳; 쥳; 쥳; 쥳; ) HANGUL SYLLABLE JYUD
+C974;C974;110C 1172 11AF;C974;110C 1172 11AF; # (쥴; 쥴; 쥴; 쥴; 쥴; ) HANGUL SYLLABLE JYUL
+C975;C975;110C 1172 11B0;C975;110C 1172 11B0; # (쥵; 쥵; 쥵; 쥵; 쥵; ) HANGUL SYLLABLE JYULG
+C976;C976;110C 1172 11B1;C976;110C 1172 11B1; # (쥶; 쥶; 쥶; 쥶; 쥶; ) HANGUL SYLLABLE JYULM
+C977;C977;110C 1172 11B2;C977;110C 1172 11B2; # (쥷; 쥷; 쥷; 쥷; 쥷; ) HANGUL SYLLABLE JYULB
+C978;C978;110C 1172 11B3;C978;110C 1172 11B3; # (쥸; 쥸; 쥸; 쥸; 쥸; ) HANGUL SYLLABLE JYULS
+C979;C979;110C 1172 11B4;C979;110C 1172 11B4; # (쥹; 쥹; 쥹; 쥹; 쥹; ) HANGUL SYLLABLE JYULT
+C97A;C97A;110C 1172 11B5;C97A;110C 1172 11B5; # (쥺; 쥺; 쥺; 쥺; 쥺; ) HANGUL SYLLABLE JYULP
+C97B;C97B;110C 1172 11B6;C97B;110C 1172 11B6; # (쥻; 쥻; 쥻; 쥻; 쥻; ) HANGUL SYLLABLE JYULH
+C97C;C97C;110C 1172 11B7;C97C;110C 1172 11B7; # (쥼; 쥼; 쥼; 쥼; 쥼; ) HANGUL SYLLABLE JYUM
+C97D;C97D;110C 1172 11B8;C97D;110C 1172 11B8; # (쥽; 쥽; 쥽; 쥽; 쥽; ) HANGUL SYLLABLE JYUB
+C97E;C97E;110C 1172 11B9;C97E;110C 1172 11B9; # (쥾; 쥾; 쥾; 쥾; 쥾; ) HANGUL SYLLABLE JYUBS
+C97F;C97F;110C 1172 11BA;C97F;110C 1172 11BA; # (쥿; 쥿; 쥿; 쥿; 쥿; ) HANGUL SYLLABLE JYUS
+C980;C980;110C 1172 11BB;C980;110C 1172 11BB; # (즀; 즀; 즀; 즀; 즀; ) HANGUL SYLLABLE JYUSS
+C981;C981;110C 1172 11BC;C981;110C 1172 11BC; # (즁; 즁; 즁; 즁; 즁; ) HANGUL SYLLABLE JYUNG
+C982;C982;110C 1172 11BD;C982;110C 1172 11BD; # (즂; 즂; 즂; 즂; 즂; ) HANGUL SYLLABLE JYUJ
+C983;C983;110C 1172 11BE;C983;110C 1172 11BE; # (즃; 즃; 즃; 즃; 즃; ) HANGUL SYLLABLE JYUC
+C984;C984;110C 1172 11BF;C984;110C 1172 11BF; # (즄; 즄; 즄; 즄; 즄; ) HANGUL SYLLABLE JYUK
+C985;C985;110C 1172 11C0;C985;110C 1172 11C0; # (즅; 즅; 즅; 즅; 즅; ) HANGUL SYLLABLE JYUT
+C986;C986;110C 1172 11C1;C986;110C 1172 11C1; # (즆; 즆; 즆; 즆; 즆; ) HANGUL SYLLABLE JYUP
+C987;C987;110C 1172 11C2;C987;110C 1172 11C2; # (즇; 즇; 즇; 즇; 즇; ) HANGUL SYLLABLE JYUH
+C988;C988;110C 1173;C988;110C 1173; # (즈; 즈; 즈; 즈; 즈; ) HANGUL SYLLABLE JEU
+C989;C989;110C 1173 11A8;C989;110C 1173 11A8; # (즉; 즉; 즉; 즉; 즉; ) HANGUL SYLLABLE JEUG
+C98A;C98A;110C 1173 11A9;C98A;110C 1173 11A9; # (즊; 즊; 즊; 즊; 즊; ) HANGUL SYLLABLE JEUGG
+C98B;C98B;110C 1173 11AA;C98B;110C 1173 11AA; # (즋; 즋; 즋; 즋; 즋; ) HANGUL SYLLABLE JEUGS
+C98C;C98C;110C 1173 11AB;C98C;110C 1173 11AB; # (즌; 즌; 즌; 즌; 즌; ) HANGUL SYLLABLE JEUN
+C98D;C98D;110C 1173 11AC;C98D;110C 1173 11AC; # (즍; 즍; 즍; 즍; 즍; ) HANGUL SYLLABLE JEUNJ
+C98E;C98E;110C 1173 11AD;C98E;110C 1173 11AD; # (즎; 즎; 즎; 즎; 즎; ) HANGUL SYLLABLE JEUNH
+C98F;C98F;110C 1173 11AE;C98F;110C 1173 11AE; # (즏; 즏; 즏; 즏; 즏; ) HANGUL SYLLABLE JEUD
+C990;C990;110C 1173 11AF;C990;110C 1173 11AF; # (즐; 즐; 즐; 즐; 즐; ) HANGUL SYLLABLE JEUL
+C991;C991;110C 1173 11B0;C991;110C 1173 11B0; # (즑; 즑; 즑; 즑; 즑; ) HANGUL SYLLABLE JEULG
+C992;C992;110C 1173 11B1;C992;110C 1173 11B1; # (즒; 즒; 즒; 즒; 즒; ) HANGUL SYLLABLE JEULM
+C993;C993;110C 1173 11B2;C993;110C 1173 11B2; # (즓; 즓; 즓; 즓; 즓; ) HANGUL SYLLABLE JEULB
+C994;C994;110C 1173 11B3;C994;110C 1173 11B3; # (즔; 즔; 즔; 즔; 즔; ) HANGUL SYLLABLE JEULS
+C995;C995;110C 1173 11B4;C995;110C 1173 11B4; # (즕; 즕; 즕; 즕; 즕; ) HANGUL SYLLABLE JEULT
+C996;C996;110C 1173 11B5;C996;110C 1173 11B5; # (즖; 즖; 즖; 즖; 즖; ) HANGUL SYLLABLE JEULP
+C997;C997;110C 1173 11B6;C997;110C 1173 11B6; # (즗; 즗; 즗; 즗; 즗; ) HANGUL SYLLABLE JEULH
+C998;C998;110C 1173 11B7;C998;110C 1173 11B7; # (즘; 즘; 즘; 즘; 즘; ) HANGUL SYLLABLE JEUM
+C999;C999;110C 1173 11B8;C999;110C 1173 11B8; # (즙; 즙; 즙; 즙; 즙; ) HANGUL SYLLABLE JEUB
+C99A;C99A;110C 1173 11B9;C99A;110C 1173 11B9; # (즚; 즚; 즚; 즚; 즚; ) HANGUL SYLLABLE JEUBS
+C99B;C99B;110C 1173 11BA;C99B;110C 1173 11BA; # (즛; 즛; 즛; 즛; 즛; ) HANGUL SYLLABLE JEUS
+C99C;C99C;110C 1173 11BB;C99C;110C 1173 11BB; # (즜; 즜; 즜; 즜; 즜; ) HANGUL SYLLABLE JEUSS
+C99D;C99D;110C 1173 11BC;C99D;110C 1173 11BC; # (증; 증; 증; 증; 증; ) HANGUL SYLLABLE JEUNG
+C99E;C99E;110C 1173 11BD;C99E;110C 1173 11BD; # (즞; 즞; 즞; 즞; 즞; ) HANGUL SYLLABLE JEUJ
+C99F;C99F;110C 1173 11BE;C99F;110C 1173 11BE; # (즟; 즟; 즟; 즟; 즟; ) HANGUL SYLLABLE JEUC
+C9A0;C9A0;110C 1173 11BF;C9A0;110C 1173 11BF; # (즠; 즠; 즠; 즠; 즠; ) HANGUL SYLLABLE JEUK
+C9A1;C9A1;110C 1173 11C0;C9A1;110C 1173 11C0; # (즡; 즡; 즡; 즡; 즡; ) HANGUL SYLLABLE JEUT
+C9A2;C9A2;110C 1173 11C1;C9A2;110C 1173 11C1; # (즢; 즢; 즢; 즢; 즢; ) HANGUL SYLLABLE JEUP
+C9A3;C9A3;110C 1173 11C2;C9A3;110C 1173 11C2; # (즣; 즣; 즣; 즣; 즣; ) HANGUL SYLLABLE JEUH
+C9A4;C9A4;110C 1174;C9A4;110C 1174; # (즤; 즤; 즤; 즤; 즤; ) HANGUL SYLLABLE JYI
+C9A5;C9A5;110C 1174 11A8;C9A5;110C 1174 11A8; # (즥; 즥; 즥; 즥; 즥; ) HANGUL SYLLABLE JYIG
+C9A6;C9A6;110C 1174 11A9;C9A6;110C 1174 11A9; # (즦; 즦; 즦; 즦; 즦; ) HANGUL SYLLABLE JYIGG
+C9A7;C9A7;110C 1174 11AA;C9A7;110C 1174 11AA; # (즧; 즧; 즧; 즧; 즧; ) HANGUL SYLLABLE JYIGS
+C9A8;C9A8;110C 1174 11AB;C9A8;110C 1174 11AB; # (즨; 즨; 즨; 즨; 즨; ) HANGUL SYLLABLE JYIN
+C9A9;C9A9;110C 1174 11AC;C9A9;110C 1174 11AC; # (즩; 즩; 즩; 즩; 즩; ) HANGUL SYLLABLE JYINJ
+C9AA;C9AA;110C 1174 11AD;C9AA;110C 1174 11AD; # (즪; 즪; 즪; 즪; 즪; ) HANGUL SYLLABLE JYINH
+C9AB;C9AB;110C 1174 11AE;C9AB;110C 1174 11AE; # (즫; 즫; 즫; 즫; 즫; ) HANGUL SYLLABLE JYID
+C9AC;C9AC;110C 1174 11AF;C9AC;110C 1174 11AF; # (즬; 즬; 즬; 즬; 즬; ) HANGUL SYLLABLE JYIL
+C9AD;C9AD;110C 1174 11B0;C9AD;110C 1174 11B0; # (즭; 즭; 즭; 즭; 즭; ) HANGUL SYLLABLE JYILG
+C9AE;C9AE;110C 1174 11B1;C9AE;110C 1174 11B1; # (즮; 즮; 즮; 즮; 즮; ) HANGUL SYLLABLE JYILM
+C9AF;C9AF;110C 1174 11B2;C9AF;110C 1174 11B2; # (즯; 즯; 즯; 즯; 즯; ) HANGUL SYLLABLE JYILB
+C9B0;C9B0;110C 1174 11B3;C9B0;110C 1174 11B3; # (즰; 즰; 즰; 즰; 즰; ) HANGUL SYLLABLE JYILS
+C9B1;C9B1;110C 1174 11B4;C9B1;110C 1174 11B4; # (즱; 즱; 즱; 즱; 즱; ) HANGUL SYLLABLE JYILT
+C9B2;C9B2;110C 1174 11B5;C9B2;110C 1174 11B5; # (즲; 즲; 즲; 즲; 즲; ) HANGUL SYLLABLE JYILP
+C9B3;C9B3;110C 1174 11B6;C9B3;110C 1174 11B6; # (즳; 즳; 즳; 즳; 즳; ) HANGUL SYLLABLE JYILH
+C9B4;C9B4;110C 1174 11B7;C9B4;110C 1174 11B7; # (즴; 즴; 즴; 즴; 즴; ) HANGUL SYLLABLE JYIM
+C9B5;C9B5;110C 1174 11B8;C9B5;110C 1174 11B8; # (즵; 즵; 즵; 즵; 즵; ) HANGUL SYLLABLE JYIB
+C9B6;C9B6;110C 1174 11B9;C9B6;110C 1174 11B9; # (즶; 즶; 즶; 즶; 즶; ) HANGUL SYLLABLE JYIBS
+C9B7;C9B7;110C 1174 11BA;C9B7;110C 1174 11BA; # (즷; 즷; 즷; 즷; 즷; ) HANGUL SYLLABLE JYIS
+C9B8;C9B8;110C 1174 11BB;C9B8;110C 1174 11BB; # (즸; 즸; 즸; 즸; 즸; ) HANGUL SYLLABLE JYISS
+C9B9;C9B9;110C 1174 11BC;C9B9;110C 1174 11BC; # (즹; 즹; 즹; 즹; 즹; ) HANGUL SYLLABLE JYING
+C9BA;C9BA;110C 1174 11BD;C9BA;110C 1174 11BD; # (즺; 즺; 즺; 즺; 즺; ) HANGUL SYLLABLE JYIJ
+C9BB;C9BB;110C 1174 11BE;C9BB;110C 1174 11BE; # (즻; 즻; 즻; 즻; 즻; ) HANGUL SYLLABLE JYIC
+C9BC;C9BC;110C 1174 11BF;C9BC;110C 1174 11BF; # (즼; 즼; 즼; 즼; 즼; ) HANGUL SYLLABLE JYIK
+C9BD;C9BD;110C 1174 11C0;C9BD;110C 1174 11C0; # (즽; 즽; 즽; 즽; 즽; ) HANGUL SYLLABLE JYIT
+C9BE;C9BE;110C 1174 11C1;C9BE;110C 1174 11C1; # (즾; 즾; 즾; 즾; 즾; ) HANGUL SYLLABLE JYIP
+C9BF;C9BF;110C 1174 11C2;C9BF;110C 1174 11C2; # (즿; 즿; 즿; 즿; 즿; ) HANGUL SYLLABLE JYIH
+C9C0;C9C0;110C 1175;C9C0;110C 1175; # (지; 지; 지; 지; 지; ) HANGUL SYLLABLE JI
+C9C1;C9C1;110C 1175 11A8;C9C1;110C 1175 11A8; # (직; 직; 직; 직; 직; ) HANGUL SYLLABLE JIG
+C9C2;C9C2;110C 1175 11A9;C9C2;110C 1175 11A9; # (짂; 짂; 짂; 짂; 짂; ) HANGUL SYLLABLE JIGG
+C9C3;C9C3;110C 1175 11AA;C9C3;110C 1175 11AA; # (짃; 짃; 짃; 짃; 짃; ) HANGUL SYLLABLE JIGS
+C9C4;C9C4;110C 1175 11AB;C9C4;110C 1175 11AB; # (진; 진; 진; 진; 진; ) HANGUL SYLLABLE JIN
+C9C5;C9C5;110C 1175 11AC;C9C5;110C 1175 11AC; # (짅; 짅; 짅; 짅; 짅; ) HANGUL SYLLABLE JINJ
+C9C6;C9C6;110C 1175 11AD;C9C6;110C 1175 11AD; # (짆; 짆; 짆; 짆; 짆; ) HANGUL SYLLABLE JINH
+C9C7;C9C7;110C 1175 11AE;C9C7;110C 1175 11AE; # (짇; 짇; 짇; 짇; 짇; ) HANGUL SYLLABLE JID
+C9C8;C9C8;110C 1175 11AF;C9C8;110C 1175 11AF; # (질; 질; 질; 질; 질; ) HANGUL SYLLABLE JIL
+C9C9;C9C9;110C 1175 11B0;C9C9;110C 1175 11B0; # (짉; 짉; 짉; 짉; 짉; ) HANGUL SYLLABLE JILG
+C9CA;C9CA;110C 1175 11B1;C9CA;110C 1175 11B1; # (짊; 짊; 짊; 짊; 짊; ) HANGUL SYLLABLE JILM
+C9CB;C9CB;110C 1175 11B2;C9CB;110C 1175 11B2; # (짋; 짋; 짋; 짋; 짋; ) HANGUL SYLLABLE JILB
+C9CC;C9CC;110C 1175 11B3;C9CC;110C 1175 11B3; # (짌; 짌; 짌; 짌; 짌; ) HANGUL SYLLABLE JILS
+C9CD;C9CD;110C 1175 11B4;C9CD;110C 1175 11B4; # (짍; 짍; 짍; 짍; 짍; ) HANGUL SYLLABLE JILT
+C9CE;C9CE;110C 1175 11B5;C9CE;110C 1175 11B5; # (짎; 짎; 짎; 짎; 짎; ) HANGUL SYLLABLE JILP
+C9CF;C9CF;110C 1175 11B6;C9CF;110C 1175 11B6; # (짏; 짏; 짏; 짏; 짏; ) HANGUL SYLLABLE JILH
+C9D0;C9D0;110C 1175 11B7;C9D0;110C 1175 11B7; # (짐; 짐; 짐; 짐; 짐; ) HANGUL SYLLABLE JIM
+C9D1;C9D1;110C 1175 11B8;C9D1;110C 1175 11B8; # (집; 집; 집; 집; 집; ) HANGUL SYLLABLE JIB
+C9D2;C9D2;110C 1175 11B9;C9D2;110C 1175 11B9; # (짒; 짒; 짒; 짒; 짒; ) HANGUL SYLLABLE JIBS
+C9D3;C9D3;110C 1175 11BA;C9D3;110C 1175 11BA; # (짓; 짓; 짓; 짓; 짓; ) HANGUL SYLLABLE JIS
+C9D4;C9D4;110C 1175 11BB;C9D4;110C 1175 11BB; # (짔; 짔; 짔; 짔; 짔; ) HANGUL SYLLABLE JISS
+C9D5;C9D5;110C 1175 11BC;C9D5;110C 1175 11BC; # (징; 징; 징; 징; 징; ) HANGUL SYLLABLE JING
+C9D6;C9D6;110C 1175 11BD;C9D6;110C 1175 11BD; # (짖; 짖; 짖; 짖; 짖; ) HANGUL SYLLABLE JIJ
+C9D7;C9D7;110C 1175 11BE;C9D7;110C 1175 11BE; # (짗; 짗; 짗; 짗; 짗; ) HANGUL SYLLABLE JIC
+C9D8;C9D8;110C 1175 11BF;C9D8;110C 1175 11BF; # (짘; 짘; 짘; 짘; 짘; ) HANGUL SYLLABLE JIK
+C9D9;C9D9;110C 1175 11C0;C9D9;110C 1175 11C0; # (짙; 짙; 짙; 짙; 짙; ) HANGUL SYLLABLE JIT
+C9DA;C9DA;110C 1175 11C1;C9DA;110C 1175 11C1; # (짚; 짚; 짚; 짚; 짚; ) HANGUL SYLLABLE JIP
+C9DB;C9DB;110C 1175 11C2;C9DB;110C 1175 11C2; # (짛; 짛; 짛; 짛; 짛; ) HANGUL SYLLABLE JIH
+C9DC;C9DC;110D 1161;C9DC;110D 1161; # (짜; 짜; 짜; 짜; 짜; ) HANGUL SYLLABLE JJA
+C9DD;C9DD;110D 1161 11A8;C9DD;110D 1161 11A8; # (짝; 짝; 짝; 짝; 짝; ) HANGUL SYLLABLE JJAG
+C9DE;C9DE;110D 1161 11A9;C9DE;110D 1161 11A9; # (짞; 짞; 짞; 짞; 짞; ) HANGUL SYLLABLE JJAGG
+C9DF;C9DF;110D 1161 11AA;C9DF;110D 1161 11AA; # (짟; 짟; 짟; 짟; 짟; ) HANGUL SYLLABLE JJAGS
+C9E0;C9E0;110D 1161 11AB;C9E0;110D 1161 11AB; # (짠; 짠; 짠; 짠; 짠; ) HANGUL SYLLABLE JJAN
+C9E1;C9E1;110D 1161 11AC;C9E1;110D 1161 11AC; # (짡; 짡; 짡; 짡; 짡; ) HANGUL SYLLABLE JJANJ
+C9E2;C9E2;110D 1161 11AD;C9E2;110D 1161 11AD; # (짢; 짢; 짢; 짢; 짢; ) HANGUL SYLLABLE JJANH
+C9E3;C9E3;110D 1161 11AE;C9E3;110D 1161 11AE; # (짣; 짣; 짣; 짣; 짣; ) HANGUL SYLLABLE JJAD
+C9E4;C9E4;110D 1161 11AF;C9E4;110D 1161 11AF; # (짤; 짤; 짤; 짤; 짤; ) HANGUL SYLLABLE JJAL
+C9E5;C9E5;110D 1161 11B0;C9E5;110D 1161 11B0; # (짥; 짥; 짥; 짥; 짥; ) HANGUL SYLLABLE JJALG
+C9E6;C9E6;110D 1161 11B1;C9E6;110D 1161 11B1; # (짦; 짦; 짦; 짦; 짦; ) HANGUL SYLLABLE JJALM
+C9E7;C9E7;110D 1161 11B2;C9E7;110D 1161 11B2; # (짧; 짧; 짧; 짧; 짧; ) HANGUL SYLLABLE JJALB
+C9E8;C9E8;110D 1161 11B3;C9E8;110D 1161 11B3; # (짨; 짨; 짨; 짨; 짨; ) HANGUL SYLLABLE JJALS
+C9E9;C9E9;110D 1161 11B4;C9E9;110D 1161 11B4; # (짩; 짩; 짩; 짩; 짩; ) HANGUL SYLLABLE JJALT
+C9EA;C9EA;110D 1161 11B5;C9EA;110D 1161 11B5; # (짪; 짪; 짪; 짪; 짪; ) HANGUL SYLLABLE JJALP
+C9EB;C9EB;110D 1161 11B6;C9EB;110D 1161 11B6; # (짫; 짫; 짫; 짫; 짫; ) HANGUL SYLLABLE JJALH
+C9EC;C9EC;110D 1161 11B7;C9EC;110D 1161 11B7; # (짬; 짬; 짬; 짬; 짬; ) HANGUL SYLLABLE JJAM
+C9ED;C9ED;110D 1161 11B8;C9ED;110D 1161 11B8; # (짭; 짭; 짭; 짭; 짭; ) HANGUL SYLLABLE JJAB
+C9EE;C9EE;110D 1161 11B9;C9EE;110D 1161 11B9; # (짮; 짮; 짮; 짮; 짮; ) HANGUL SYLLABLE JJABS
+C9EF;C9EF;110D 1161 11BA;C9EF;110D 1161 11BA; # (짯; 짯; 짯; 짯; 짯; ) HANGUL SYLLABLE JJAS
+C9F0;C9F0;110D 1161 11BB;C9F0;110D 1161 11BB; # (짰; 짰; 짰; 짰; 짰; ) HANGUL SYLLABLE JJASS
+C9F1;C9F1;110D 1161 11BC;C9F1;110D 1161 11BC; # (짱; 짱; 짱; 짱; 짱; ) HANGUL SYLLABLE JJANG
+C9F2;C9F2;110D 1161 11BD;C9F2;110D 1161 11BD; # (짲; 짲; 짲; 짲; 짲; ) HANGUL SYLLABLE JJAJ
+C9F3;C9F3;110D 1161 11BE;C9F3;110D 1161 11BE; # (짳; 짳; 짳; 짳; 짳; ) HANGUL SYLLABLE JJAC
+C9F4;C9F4;110D 1161 11BF;C9F4;110D 1161 11BF; # (짴; 짴; 짴; 짴; 짴; ) HANGUL SYLLABLE JJAK
+C9F5;C9F5;110D 1161 11C0;C9F5;110D 1161 11C0; # (짵; 짵; 짵; 짵; 짵; ) HANGUL SYLLABLE JJAT
+C9F6;C9F6;110D 1161 11C1;C9F6;110D 1161 11C1; # (짶; 짶; 짶; 짶; 짶; ) HANGUL SYLLABLE JJAP
+C9F7;C9F7;110D 1161 11C2;C9F7;110D 1161 11C2; # (짷; 짷; 짷; 짷; 짷; ) HANGUL SYLLABLE JJAH
+C9F8;C9F8;110D 1162;C9F8;110D 1162; # (째; 째; 째; 째; 째; ) HANGUL SYLLABLE JJAE
+C9F9;C9F9;110D 1162 11A8;C9F9;110D 1162 11A8; # (짹; 짹; 짹; 짹; 짹; ) HANGUL SYLLABLE JJAEG
+C9FA;C9FA;110D 1162 11A9;C9FA;110D 1162 11A9; # (짺; 짺; 짺; 짺; 짺; ) HANGUL SYLLABLE JJAEGG
+C9FB;C9FB;110D 1162 11AA;C9FB;110D 1162 11AA; # (짻; 짻; 짻; 짻; 짻; ) HANGUL SYLLABLE JJAEGS
+C9FC;C9FC;110D 1162 11AB;C9FC;110D 1162 11AB; # (짼; 짼; 짼; 짼; 짼; ) HANGUL SYLLABLE JJAEN
+C9FD;C9FD;110D 1162 11AC;C9FD;110D 1162 11AC; # (짽; 짽; 짽; 짽; 짽; ) HANGUL SYLLABLE JJAENJ
+C9FE;C9FE;110D 1162 11AD;C9FE;110D 1162 11AD; # (짾; 짾; 짾; 짾; 짾; ) HANGUL SYLLABLE JJAENH
+C9FF;C9FF;110D 1162 11AE;C9FF;110D 1162 11AE; # (짿; 짿; 짿; 짿; 짿; ) HANGUL SYLLABLE JJAED
+CA00;CA00;110D 1162 11AF;CA00;110D 1162 11AF; # (쨀; 쨀; 쨀; 쨀; 쨀; ) HANGUL SYLLABLE JJAEL
+CA01;CA01;110D 1162 11B0;CA01;110D 1162 11B0; # (쨁; 쨁; 쨁; 쨁; 쨁; ) HANGUL SYLLABLE JJAELG
+CA02;CA02;110D 1162 11B1;CA02;110D 1162 11B1; # (쨂; 쨂; 쨂; 쨂; 쨂; ) HANGUL SYLLABLE JJAELM
+CA03;CA03;110D 1162 11B2;CA03;110D 1162 11B2; # (쨃; 쨃; 쨃; 쨃; 쨃; ) HANGUL SYLLABLE JJAELB
+CA04;CA04;110D 1162 11B3;CA04;110D 1162 11B3; # (쨄; 쨄; 쨄; 쨄; 쨄; ) HANGUL SYLLABLE JJAELS
+CA05;CA05;110D 1162 11B4;CA05;110D 1162 11B4; # (쨅; 쨅; 쨅; 쨅; 쨅; ) HANGUL SYLLABLE JJAELT
+CA06;CA06;110D 1162 11B5;CA06;110D 1162 11B5; # (쨆; 쨆; 쨆; 쨆; 쨆; ) HANGUL SYLLABLE JJAELP
+CA07;CA07;110D 1162 11B6;CA07;110D 1162 11B6; # (쨇; 쨇; 쨇; 쨇; 쨇; ) HANGUL SYLLABLE JJAELH
+CA08;CA08;110D 1162 11B7;CA08;110D 1162 11B7; # (쨈; 쨈; 쨈; 쨈; 쨈; ) HANGUL SYLLABLE JJAEM
+CA09;CA09;110D 1162 11B8;CA09;110D 1162 11B8; # (쨉; 쨉; 쨉; 쨉; 쨉; ) HANGUL SYLLABLE JJAEB
+CA0A;CA0A;110D 1162 11B9;CA0A;110D 1162 11B9; # (쨊; 쨊; 쨊; 쨊; 쨊; ) HANGUL SYLLABLE JJAEBS
+CA0B;CA0B;110D 1162 11BA;CA0B;110D 1162 11BA; # (쨋; 쨋; 쨋; 쨋; 쨋; ) HANGUL SYLLABLE JJAES
+CA0C;CA0C;110D 1162 11BB;CA0C;110D 1162 11BB; # (쨌; 쨌; 쨌; 쨌; 쨌; ) HANGUL SYLLABLE JJAESS
+CA0D;CA0D;110D 1162 11BC;CA0D;110D 1162 11BC; # (쨍; 쨍; 쨍; 쨍; 쨍; ) HANGUL SYLLABLE JJAENG
+CA0E;CA0E;110D 1162 11BD;CA0E;110D 1162 11BD; # (쨎; 쨎; 쨎; 쨎; 쨎; ) HANGUL SYLLABLE JJAEJ
+CA0F;CA0F;110D 1162 11BE;CA0F;110D 1162 11BE; # (쨏; 쨏; 쨏; 쨏; 쨏; ) HANGUL SYLLABLE JJAEC
+CA10;CA10;110D 1162 11BF;CA10;110D 1162 11BF; # (쨐; 쨐; 쨐; 쨐; 쨐; ) HANGUL SYLLABLE JJAEK
+CA11;CA11;110D 1162 11C0;CA11;110D 1162 11C0; # (쨑; 쨑; 쨑; 쨑; 쨑; ) HANGUL SYLLABLE JJAET
+CA12;CA12;110D 1162 11C1;CA12;110D 1162 11C1; # (쨒; 쨒; 쨒; 쨒; 쨒; ) HANGUL SYLLABLE JJAEP
+CA13;CA13;110D 1162 11C2;CA13;110D 1162 11C2; # (쨓; 쨓; 쨓; 쨓; 쨓; ) HANGUL SYLLABLE JJAEH
+CA14;CA14;110D 1163;CA14;110D 1163; # (쨔; 쨔; 쨔; 쨔; 쨔; ) HANGUL SYLLABLE JJYA
+CA15;CA15;110D 1163 11A8;CA15;110D 1163 11A8; # (쨕; 쨕; 쨕; 쨕; 쨕; ) HANGUL SYLLABLE JJYAG
+CA16;CA16;110D 1163 11A9;CA16;110D 1163 11A9; # (쨖; 쨖; 쨖; 쨖; 쨖; ) HANGUL SYLLABLE JJYAGG
+CA17;CA17;110D 1163 11AA;CA17;110D 1163 11AA; # (쨗; 쨗; 쨗; 쨗; 쨗; ) HANGUL SYLLABLE JJYAGS
+CA18;CA18;110D 1163 11AB;CA18;110D 1163 11AB; # (쨘; 쨘; 쨘; 쨘; 쨘; ) HANGUL SYLLABLE JJYAN
+CA19;CA19;110D 1163 11AC;CA19;110D 1163 11AC; # (쨙; 쨙; 쨙; 쨙; 쨙; ) HANGUL SYLLABLE JJYANJ
+CA1A;CA1A;110D 1163 11AD;CA1A;110D 1163 11AD; # (쨚; 쨚; 쨚; 쨚; 쨚; ) HANGUL SYLLABLE JJYANH
+CA1B;CA1B;110D 1163 11AE;CA1B;110D 1163 11AE; # (쨛; 쨛; 쨛; 쨛; 쨛; ) HANGUL SYLLABLE JJYAD
+CA1C;CA1C;110D 1163 11AF;CA1C;110D 1163 11AF; # (쨜; 쨜; 쨜; 쨜; 쨜; ) HANGUL SYLLABLE JJYAL
+CA1D;CA1D;110D 1163 11B0;CA1D;110D 1163 11B0; # (쨝; 쨝; 쨝; 쨝; 쨝; ) HANGUL SYLLABLE JJYALG
+CA1E;CA1E;110D 1163 11B1;CA1E;110D 1163 11B1; # (쨞; 쨞; 쨞; 쨞; 쨞; ) HANGUL SYLLABLE JJYALM
+CA1F;CA1F;110D 1163 11B2;CA1F;110D 1163 11B2; # (쨟; 쨟; 쨟; 쨟; 쨟; ) HANGUL SYLLABLE JJYALB
+CA20;CA20;110D 1163 11B3;CA20;110D 1163 11B3; # (쨠; 쨠; 쨠; 쨠; 쨠; ) HANGUL SYLLABLE JJYALS
+CA21;CA21;110D 1163 11B4;CA21;110D 1163 11B4; # (쨡; 쨡; 쨡; 쨡; 쨡; ) HANGUL SYLLABLE JJYALT
+CA22;CA22;110D 1163 11B5;CA22;110D 1163 11B5; # (쨢; 쨢; 쨢; 쨢; 쨢; ) HANGUL SYLLABLE JJYALP
+CA23;CA23;110D 1163 11B6;CA23;110D 1163 11B6; # (쨣; 쨣; 쨣; 쨣; 쨣; ) HANGUL SYLLABLE JJYALH
+CA24;CA24;110D 1163 11B7;CA24;110D 1163 11B7; # (쨤; 쨤; 쨤; 쨤; 쨤; ) HANGUL SYLLABLE JJYAM
+CA25;CA25;110D 1163 11B8;CA25;110D 1163 11B8; # (쨥; 쨥; 쨥; 쨥; 쨥; ) HANGUL SYLLABLE JJYAB
+CA26;CA26;110D 1163 11B9;CA26;110D 1163 11B9; # (쨦; 쨦; 쨦; 쨦; 쨦; ) HANGUL SYLLABLE JJYABS
+CA27;CA27;110D 1163 11BA;CA27;110D 1163 11BA; # (쨧; 쨧; 쨧; 쨧; 쨧; ) HANGUL SYLLABLE JJYAS
+CA28;CA28;110D 1163 11BB;CA28;110D 1163 11BB; # (쨨; 쨨; 쨨; 쨨; 쨨; ) HANGUL SYLLABLE JJYASS
+CA29;CA29;110D 1163 11BC;CA29;110D 1163 11BC; # (쨩; 쨩; 쨩; 쨩; 쨩; ) HANGUL SYLLABLE JJYANG
+CA2A;CA2A;110D 1163 11BD;CA2A;110D 1163 11BD; # (쨪; 쨪; 쨪; 쨪; 쨪; ) HANGUL SYLLABLE JJYAJ
+CA2B;CA2B;110D 1163 11BE;CA2B;110D 1163 11BE; # (쨫; 쨫; 쨫; 쨫; 쨫; ) HANGUL SYLLABLE JJYAC
+CA2C;CA2C;110D 1163 11BF;CA2C;110D 1163 11BF; # (쨬; 쨬; 쨬; 쨬; 쨬; ) HANGUL SYLLABLE JJYAK
+CA2D;CA2D;110D 1163 11C0;CA2D;110D 1163 11C0; # (쨭; 쨭; 쨭; 쨭; 쨭; ) HANGUL SYLLABLE JJYAT
+CA2E;CA2E;110D 1163 11C1;CA2E;110D 1163 11C1; # (쨮; 쨮; 쨮; 쨮; 쨮; ) HANGUL SYLLABLE JJYAP
+CA2F;CA2F;110D 1163 11C2;CA2F;110D 1163 11C2; # (쨯; 쨯; 쨯; 쨯; 쨯; ) HANGUL SYLLABLE JJYAH
+CA30;CA30;110D 1164;CA30;110D 1164; # (쨰; 쨰; 쨰; 쨰; 쨰; ) HANGUL SYLLABLE JJYAE
+CA31;CA31;110D 1164 11A8;CA31;110D 1164 11A8; # (쨱; 쨱; 쨱; 쨱; 쨱; ) HANGUL SYLLABLE JJYAEG
+CA32;CA32;110D 1164 11A9;CA32;110D 1164 11A9; # (쨲; 쨲; 쨲; 쨲; 쨲; ) HANGUL SYLLABLE JJYAEGG
+CA33;CA33;110D 1164 11AA;CA33;110D 1164 11AA; # (쨳; 쨳; 쨳; 쨳; 쨳; ) HANGUL SYLLABLE JJYAEGS
+CA34;CA34;110D 1164 11AB;CA34;110D 1164 11AB; # (쨴; 쨴; 쨴; 쨴; 쨴; ) HANGUL SYLLABLE JJYAEN
+CA35;CA35;110D 1164 11AC;CA35;110D 1164 11AC; # (쨵; 쨵; 쨵; 쨵; 쨵; ) HANGUL SYLLABLE JJYAENJ
+CA36;CA36;110D 1164 11AD;CA36;110D 1164 11AD; # (쨶; 쨶; 쨶; 쨶; 쨶; ) HANGUL SYLLABLE JJYAENH
+CA37;CA37;110D 1164 11AE;CA37;110D 1164 11AE; # (쨷; 쨷; 쨷; 쨷; 쨷; ) HANGUL SYLLABLE JJYAED
+CA38;CA38;110D 1164 11AF;CA38;110D 1164 11AF; # (쨸; 쨸; 쨸; 쨸; 쨸; ) HANGUL SYLLABLE JJYAEL
+CA39;CA39;110D 1164 11B0;CA39;110D 1164 11B0; # (쨹; 쨹; 쨹; 쨹; 쨹; ) HANGUL SYLLABLE JJYAELG
+CA3A;CA3A;110D 1164 11B1;CA3A;110D 1164 11B1; # (쨺; 쨺; 쨺; 쨺; 쨺; ) HANGUL SYLLABLE JJYAELM
+CA3B;CA3B;110D 1164 11B2;CA3B;110D 1164 11B2; # (쨻; 쨻; 쨻; 쨻; 쨻; ) HANGUL SYLLABLE JJYAELB
+CA3C;CA3C;110D 1164 11B3;CA3C;110D 1164 11B3; # (쨼; 쨼; 쨼; 쨼; 쨼; ) HANGUL SYLLABLE JJYAELS
+CA3D;CA3D;110D 1164 11B4;CA3D;110D 1164 11B4; # (쨽; 쨽; 쨽; 쨽; 쨽; ) HANGUL SYLLABLE JJYAELT
+CA3E;CA3E;110D 1164 11B5;CA3E;110D 1164 11B5; # (쨾; 쨾; 쨾; 쨾; 쨾; ) HANGUL SYLLABLE JJYAELP
+CA3F;CA3F;110D 1164 11B6;CA3F;110D 1164 11B6; # (쨿; 쨿; 쨿; 쨿; 쨿; ) HANGUL SYLLABLE JJYAELH
+CA40;CA40;110D 1164 11B7;CA40;110D 1164 11B7; # (쩀; 쩀; 쩀; 쩀; 쩀; ) HANGUL SYLLABLE JJYAEM
+CA41;CA41;110D 1164 11B8;CA41;110D 1164 11B8; # (쩁; 쩁; 쩁; 쩁; 쩁; ) HANGUL SYLLABLE JJYAEB
+CA42;CA42;110D 1164 11B9;CA42;110D 1164 11B9; # (쩂; 쩂; 쩂; 쩂; 쩂; ) HANGUL SYLLABLE JJYAEBS
+CA43;CA43;110D 1164 11BA;CA43;110D 1164 11BA; # (쩃; 쩃; 쩃; 쩃; 쩃; ) HANGUL SYLLABLE JJYAES
+CA44;CA44;110D 1164 11BB;CA44;110D 1164 11BB; # (쩄; 쩄; 쩄; 쩄; 쩄; ) HANGUL SYLLABLE JJYAESS
+CA45;CA45;110D 1164 11BC;CA45;110D 1164 11BC; # (쩅; 쩅; 쩅; 쩅; 쩅; ) HANGUL SYLLABLE JJYAENG
+CA46;CA46;110D 1164 11BD;CA46;110D 1164 11BD; # (쩆; 쩆; 쩆; 쩆; 쩆; ) HANGUL SYLLABLE JJYAEJ
+CA47;CA47;110D 1164 11BE;CA47;110D 1164 11BE; # (쩇; 쩇; 쩇; 쩇; 쩇; ) HANGUL SYLLABLE JJYAEC
+CA48;CA48;110D 1164 11BF;CA48;110D 1164 11BF; # (쩈; 쩈; 쩈; 쩈; 쩈; ) HANGUL SYLLABLE JJYAEK
+CA49;CA49;110D 1164 11C0;CA49;110D 1164 11C0; # (쩉; 쩉; 쩉; 쩉; 쩉; ) HANGUL SYLLABLE JJYAET
+CA4A;CA4A;110D 1164 11C1;CA4A;110D 1164 11C1; # (쩊; 쩊; 쩊; 쩊; 쩊; ) HANGUL SYLLABLE JJYAEP
+CA4B;CA4B;110D 1164 11C2;CA4B;110D 1164 11C2; # (쩋; 쩋; 쩋; 쩋; 쩋; ) HANGUL SYLLABLE JJYAEH
+CA4C;CA4C;110D 1165;CA4C;110D 1165; # (쩌; 쩌; 쩌; 쩌; 쩌; ) HANGUL SYLLABLE JJEO
+CA4D;CA4D;110D 1165 11A8;CA4D;110D 1165 11A8; # (쩍; 쩍; 쩍; 쩍; 쩍; ) HANGUL SYLLABLE JJEOG
+CA4E;CA4E;110D 1165 11A9;CA4E;110D 1165 11A9; # (쩎; 쩎; 쩎; 쩎; 쩎; ) HANGUL SYLLABLE JJEOGG
+CA4F;CA4F;110D 1165 11AA;CA4F;110D 1165 11AA; # (쩏; 쩏; 쩏; 쩏; 쩏; ) HANGUL SYLLABLE JJEOGS
+CA50;CA50;110D 1165 11AB;CA50;110D 1165 11AB; # (쩐; 쩐; 쩐; 쩐; 쩐; ) HANGUL SYLLABLE JJEON
+CA51;CA51;110D 1165 11AC;CA51;110D 1165 11AC; # (쩑; 쩑; 쩑; 쩑; 쩑; ) HANGUL SYLLABLE JJEONJ
+CA52;CA52;110D 1165 11AD;CA52;110D 1165 11AD; # (쩒; 쩒; 쩒; 쩒; 쩒; ) HANGUL SYLLABLE JJEONH
+CA53;CA53;110D 1165 11AE;CA53;110D 1165 11AE; # (쩓; 쩓; 쩓; 쩓; 쩓; ) HANGUL SYLLABLE JJEOD
+CA54;CA54;110D 1165 11AF;CA54;110D 1165 11AF; # (쩔; 쩔; 쩔; 쩔; 쩔; ) HANGUL SYLLABLE JJEOL
+CA55;CA55;110D 1165 11B0;CA55;110D 1165 11B0; # (쩕; 쩕; 쩕; 쩕; 쩕; ) HANGUL SYLLABLE JJEOLG
+CA56;CA56;110D 1165 11B1;CA56;110D 1165 11B1; # (쩖; 쩖; 쩖; 쩖; 쩖; ) HANGUL SYLLABLE JJEOLM
+CA57;CA57;110D 1165 11B2;CA57;110D 1165 11B2; # (쩗; 쩗; 쩗; 쩗; 쩗; ) HANGUL SYLLABLE JJEOLB
+CA58;CA58;110D 1165 11B3;CA58;110D 1165 11B3; # (쩘; 쩘; 쩘; 쩘; 쩘; ) HANGUL SYLLABLE JJEOLS
+CA59;CA59;110D 1165 11B4;CA59;110D 1165 11B4; # (쩙; 쩙; 쩙; 쩙; 쩙; ) HANGUL SYLLABLE JJEOLT
+CA5A;CA5A;110D 1165 11B5;CA5A;110D 1165 11B5; # (쩚; 쩚; 쩚; 쩚; 쩚; ) HANGUL SYLLABLE JJEOLP
+CA5B;CA5B;110D 1165 11B6;CA5B;110D 1165 11B6; # (쩛; 쩛; 쩛; 쩛; 쩛; ) HANGUL SYLLABLE JJEOLH
+CA5C;CA5C;110D 1165 11B7;CA5C;110D 1165 11B7; # (쩜; 쩜; 쩜; 쩜; 쩜; ) HANGUL SYLLABLE JJEOM
+CA5D;CA5D;110D 1165 11B8;CA5D;110D 1165 11B8; # (쩝; 쩝; 쩝; 쩝; 쩝; ) HANGUL SYLLABLE JJEOB
+CA5E;CA5E;110D 1165 11B9;CA5E;110D 1165 11B9; # (쩞; 쩞; 쩞; 쩞; 쩞; ) HANGUL SYLLABLE JJEOBS
+CA5F;CA5F;110D 1165 11BA;CA5F;110D 1165 11BA; # (쩟; 쩟; 쩟; 쩟; 쩟; ) HANGUL SYLLABLE JJEOS
+CA60;CA60;110D 1165 11BB;CA60;110D 1165 11BB; # (쩠; 쩠; 쩠; 쩠; 쩠; ) HANGUL SYLLABLE JJEOSS
+CA61;CA61;110D 1165 11BC;CA61;110D 1165 11BC; # (쩡; 쩡; 쩡; 쩡; 쩡; ) HANGUL SYLLABLE JJEONG
+CA62;CA62;110D 1165 11BD;CA62;110D 1165 11BD; # (쩢; 쩢; 쩢; 쩢; 쩢; ) HANGUL SYLLABLE JJEOJ
+CA63;CA63;110D 1165 11BE;CA63;110D 1165 11BE; # (쩣; 쩣; 쩣; 쩣; 쩣; ) HANGUL SYLLABLE JJEOC
+CA64;CA64;110D 1165 11BF;CA64;110D 1165 11BF; # (쩤; 쩤; 쩤; 쩤; 쩤; ) HANGUL SYLLABLE JJEOK
+CA65;CA65;110D 1165 11C0;CA65;110D 1165 11C0; # (쩥; 쩥; 쩥; 쩥; 쩥; ) HANGUL SYLLABLE JJEOT
+CA66;CA66;110D 1165 11C1;CA66;110D 1165 11C1; # (쩦; 쩦; 쩦; 쩦; 쩦; ) HANGUL SYLLABLE JJEOP
+CA67;CA67;110D 1165 11C2;CA67;110D 1165 11C2; # (쩧; 쩧; 쩧; 쩧; 쩧; ) HANGUL SYLLABLE JJEOH
+CA68;CA68;110D 1166;CA68;110D 1166; # (쩨; 쩨; 쩨; 쩨; 쩨; ) HANGUL SYLLABLE JJE
+CA69;CA69;110D 1166 11A8;CA69;110D 1166 11A8; # (쩩; 쩩; 쩩; 쩩; 쩩; ) HANGUL SYLLABLE JJEG
+CA6A;CA6A;110D 1166 11A9;CA6A;110D 1166 11A9; # (쩪; 쩪; 쩪; 쩪; 쩪; ) HANGUL SYLLABLE JJEGG
+CA6B;CA6B;110D 1166 11AA;CA6B;110D 1166 11AA; # (쩫; 쩫; 쩫; 쩫; 쩫; ) HANGUL SYLLABLE JJEGS
+CA6C;CA6C;110D 1166 11AB;CA6C;110D 1166 11AB; # (쩬; 쩬; 쩬; 쩬; 쩬; ) HANGUL SYLLABLE JJEN
+CA6D;CA6D;110D 1166 11AC;CA6D;110D 1166 11AC; # (쩭; 쩭; 쩭; 쩭; 쩭; ) HANGUL SYLLABLE JJENJ
+CA6E;CA6E;110D 1166 11AD;CA6E;110D 1166 11AD; # (쩮; 쩮; 쩮; 쩮; 쩮; ) HANGUL SYLLABLE JJENH
+CA6F;CA6F;110D 1166 11AE;CA6F;110D 1166 11AE; # (쩯; 쩯; 쩯; 쩯; 쩯; ) HANGUL SYLLABLE JJED
+CA70;CA70;110D 1166 11AF;CA70;110D 1166 11AF; # (쩰; 쩰; 쩰; 쩰; 쩰; ) HANGUL SYLLABLE JJEL
+CA71;CA71;110D 1166 11B0;CA71;110D 1166 11B0; # (쩱; 쩱; 쩱; 쩱; 쩱; ) HANGUL SYLLABLE JJELG
+CA72;CA72;110D 1166 11B1;CA72;110D 1166 11B1; # (쩲; 쩲; 쩲; 쩲; 쩲; ) HANGUL SYLLABLE JJELM
+CA73;CA73;110D 1166 11B2;CA73;110D 1166 11B2; # (쩳; 쩳; 쩳; 쩳; 쩳; ) HANGUL SYLLABLE JJELB
+CA74;CA74;110D 1166 11B3;CA74;110D 1166 11B3; # (쩴; 쩴; 쩴; 쩴; 쩴; ) HANGUL SYLLABLE JJELS
+CA75;CA75;110D 1166 11B4;CA75;110D 1166 11B4; # (쩵; 쩵; 쩵; 쩵; 쩵; ) HANGUL SYLLABLE JJELT
+CA76;CA76;110D 1166 11B5;CA76;110D 1166 11B5; # (쩶; 쩶; 쩶; 쩶; 쩶; ) HANGUL SYLLABLE JJELP
+CA77;CA77;110D 1166 11B6;CA77;110D 1166 11B6; # (쩷; 쩷; 쩷; 쩷; 쩷; ) HANGUL SYLLABLE JJELH
+CA78;CA78;110D 1166 11B7;CA78;110D 1166 11B7; # (쩸; 쩸; 쩸; 쩸; 쩸; ) HANGUL SYLLABLE JJEM
+CA79;CA79;110D 1166 11B8;CA79;110D 1166 11B8; # (쩹; 쩹; 쩹; 쩹; 쩹; ) HANGUL SYLLABLE JJEB
+CA7A;CA7A;110D 1166 11B9;CA7A;110D 1166 11B9; # (쩺; 쩺; 쩺; 쩺; 쩺; ) HANGUL SYLLABLE JJEBS
+CA7B;CA7B;110D 1166 11BA;CA7B;110D 1166 11BA; # (쩻; 쩻; 쩻; 쩻; 쩻; ) HANGUL SYLLABLE JJES
+CA7C;CA7C;110D 1166 11BB;CA7C;110D 1166 11BB; # (쩼; 쩼; 쩼; 쩼; 쩼; ) HANGUL SYLLABLE JJESS
+CA7D;CA7D;110D 1166 11BC;CA7D;110D 1166 11BC; # (쩽; 쩽; 쩽; 쩽; 쩽; ) HANGUL SYLLABLE JJENG
+CA7E;CA7E;110D 1166 11BD;CA7E;110D 1166 11BD; # (쩾; 쩾; 쩾; 쩾; 쩾; ) HANGUL SYLLABLE JJEJ
+CA7F;CA7F;110D 1166 11BE;CA7F;110D 1166 11BE; # (쩿; 쩿; 쩿; 쩿; 쩿; ) HANGUL SYLLABLE JJEC
+CA80;CA80;110D 1166 11BF;CA80;110D 1166 11BF; # (쪀; 쪀; 쪀; 쪀; 쪀; ) HANGUL SYLLABLE JJEK
+CA81;CA81;110D 1166 11C0;CA81;110D 1166 11C0; # (쪁; 쪁; 쪁; 쪁; 쪁; ) HANGUL SYLLABLE JJET
+CA82;CA82;110D 1166 11C1;CA82;110D 1166 11C1; # (쪂; 쪂; 쪂; 쪂; 쪂; ) HANGUL SYLLABLE JJEP
+CA83;CA83;110D 1166 11C2;CA83;110D 1166 11C2; # (쪃; 쪃; 쪃; 쪃; 쪃; ) HANGUL SYLLABLE JJEH
+CA84;CA84;110D 1167;CA84;110D 1167; # (쪄; 쪄; 쪄; 쪄; 쪄; ) HANGUL SYLLABLE JJYEO
+CA85;CA85;110D 1167 11A8;CA85;110D 1167 11A8; # (쪅; 쪅; 쪅; 쪅; 쪅; ) HANGUL SYLLABLE JJYEOG
+CA86;CA86;110D 1167 11A9;CA86;110D 1167 11A9; # (쪆; 쪆; 쪆; 쪆; 쪆; ) HANGUL SYLLABLE JJYEOGG
+CA87;CA87;110D 1167 11AA;CA87;110D 1167 11AA; # (쪇; 쪇; 쪇; 쪇; 쪇; ) HANGUL SYLLABLE JJYEOGS
+CA88;CA88;110D 1167 11AB;CA88;110D 1167 11AB; # (쪈; 쪈; 쪈; 쪈; 쪈; ) HANGUL SYLLABLE JJYEON
+CA89;CA89;110D 1167 11AC;CA89;110D 1167 11AC; # (쪉; 쪉; 쪉; 쪉; 쪉; ) HANGUL SYLLABLE JJYEONJ
+CA8A;CA8A;110D 1167 11AD;CA8A;110D 1167 11AD; # (쪊; 쪊; 쪊; 쪊; 쪊; ) HANGUL SYLLABLE JJYEONH
+CA8B;CA8B;110D 1167 11AE;CA8B;110D 1167 11AE; # (쪋; 쪋; 쪋; 쪋; 쪋; ) HANGUL SYLLABLE JJYEOD
+CA8C;CA8C;110D 1167 11AF;CA8C;110D 1167 11AF; # (쪌; 쪌; 쪌; 쪌; 쪌; ) HANGUL SYLLABLE JJYEOL
+CA8D;CA8D;110D 1167 11B0;CA8D;110D 1167 11B0; # (쪍; 쪍; 쪍; 쪍; 쪍; ) HANGUL SYLLABLE JJYEOLG
+CA8E;CA8E;110D 1167 11B1;CA8E;110D 1167 11B1; # (쪎; 쪎; 쪎; 쪎; 쪎; ) HANGUL SYLLABLE JJYEOLM
+CA8F;CA8F;110D 1167 11B2;CA8F;110D 1167 11B2; # (쪏; 쪏; 쪏; 쪏; 쪏; ) HANGUL SYLLABLE JJYEOLB
+CA90;CA90;110D 1167 11B3;CA90;110D 1167 11B3; # (쪐; 쪐; 쪐; 쪐; 쪐; ) HANGUL SYLLABLE JJYEOLS
+CA91;CA91;110D 1167 11B4;CA91;110D 1167 11B4; # (쪑; 쪑; 쪑; 쪑; 쪑; ) HANGUL SYLLABLE JJYEOLT
+CA92;CA92;110D 1167 11B5;CA92;110D 1167 11B5; # (쪒; 쪒; 쪒; 쪒; 쪒; ) HANGUL SYLLABLE JJYEOLP
+CA93;CA93;110D 1167 11B6;CA93;110D 1167 11B6; # (쪓; 쪓; 쪓; 쪓; 쪓; ) HANGUL SYLLABLE JJYEOLH
+CA94;CA94;110D 1167 11B7;CA94;110D 1167 11B7; # (쪔; 쪔; 쪔; 쪔; 쪔; ) HANGUL SYLLABLE JJYEOM
+CA95;CA95;110D 1167 11B8;CA95;110D 1167 11B8; # (쪕; 쪕; 쪕; 쪕; 쪕; ) HANGUL SYLLABLE JJYEOB
+CA96;CA96;110D 1167 11B9;CA96;110D 1167 11B9; # (쪖; 쪖; 쪖; 쪖; 쪖; ) HANGUL SYLLABLE JJYEOBS
+CA97;CA97;110D 1167 11BA;CA97;110D 1167 11BA; # (쪗; 쪗; 쪗; 쪗; 쪗; ) HANGUL SYLLABLE JJYEOS
+CA98;CA98;110D 1167 11BB;CA98;110D 1167 11BB; # (쪘; 쪘; 쪘; 쪘; 쪘; ) HANGUL SYLLABLE JJYEOSS
+CA99;CA99;110D 1167 11BC;CA99;110D 1167 11BC; # (쪙; 쪙; 쪙; 쪙; 쪙; ) HANGUL SYLLABLE JJYEONG
+CA9A;CA9A;110D 1167 11BD;CA9A;110D 1167 11BD; # (쪚; 쪚; 쪚; 쪚; 쪚; ) HANGUL SYLLABLE JJYEOJ
+CA9B;CA9B;110D 1167 11BE;CA9B;110D 1167 11BE; # (쪛; 쪛; 쪛; 쪛; 쪛; ) HANGUL SYLLABLE JJYEOC
+CA9C;CA9C;110D 1167 11BF;CA9C;110D 1167 11BF; # (쪜; 쪜; 쪜; 쪜; 쪜; ) HANGUL SYLLABLE JJYEOK
+CA9D;CA9D;110D 1167 11C0;CA9D;110D 1167 11C0; # (쪝; 쪝; 쪝; 쪝; 쪝; ) HANGUL SYLLABLE JJYEOT
+CA9E;CA9E;110D 1167 11C1;CA9E;110D 1167 11C1; # (쪞; 쪞; 쪞; 쪞; 쪞; ) HANGUL SYLLABLE JJYEOP
+CA9F;CA9F;110D 1167 11C2;CA9F;110D 1167 11C2; # (쪟; 쪟; 쪟; 쪟; 쪟; ) HANGUL SYLLABLE JJYEOH
+CAA0;CAA0;110D 1168;CAA0;110D 1168; # (쪠; 쪠; 쪠; 쪠; 쪠; ) HANGUL SYLLABLE JJYE
+CAA1;CAA1;110D 1168 11A8;CAA1;110D 1168 11A8; # (쪡; 쪡; 쪡; 쪡; 쪡; ) HANGUL SYLLABLE JJYEG
+CAA2;CAA2;110D 1168 11A9;CAA2;110D 1168 11A9; # (쪢; 쪢; 쪢; 쪢; 쪢; ) HANGUL SYLLABLE JJYEGG
+CAA3;CAA3;110D 1168 11AA;CAA3;110D 1168 11AA; # (쪣; 쪣; 쪣; 쪣; 쪣; ) HANGUL SYLLABLE JJYEGS
+CAA4;CAA4;110D 1168 11AB;CAA4;110D 1168 11AB; # (쪤; 쪤; 쪤; 쪤; 쪤; ) HANGUL SYLLABLE JJYEN
+CAA5;CAA5;110D 1168 11AC;CAA5;110D 1168 11AC; # (쪥; 쪥; 쪥; 쪥; 쪥; ) HANGUL SYLLABLE JJYENJ
+CAA6;CAA6;110D 1168 11AD;CAA6;110D 1168 11AD; # (쪦; 쪦; 쪦; 쪦; 쪦; ) HANGUL SYLLABLE JJYENH
+CAA7;CAA7;110D 1168 11AE;CAA7;110D 1168 11AE; # (쪧; 쪧; 쪧; 쪧; 쪧; ) HANGUL SYLLABLE JJYED
+CAA8;CAA8;110D 1168 11AF;CAA8;110D 1168 11AF; # (쪨; 쪨; 쪨; 쪨; 쪨; ) HANGUL SYLLABLE JJYEL
+CAA9;CAA9;110D 1168 11B0;CAA9;110D 1168 11B0; # (쪩; 쪩; 쪩; 쪩; 쪩; ) HANGUL SYLLABLE JJYELG
+CAAA;CAAA;110D 1168 11B1;CAAA;110D 1168 11B1; # (쪪; 쪪; 쪪; 쪪; 쪪; ) HANGUL SYLLABLE JJYELM
+CAAB;CAAB;110D 1168 11B2;CAAB;110D 1168 11B2; # (쪫; 쪫; 쪫; 쪫; 쪫; ) HANGUL SYLLABLE JJYELB
+CAAC;CAAC;110D 1168 11B3;CAAC;110D 1168 11B3; # (쪬; 쪬; 쪬; 쪬; 쪬; ) HANGUL SYLLABLE JJYELS
+CAAD;CAAD;110D 1168 11B4;CAAD;110D 1168 11B4; # (쪭; 쪭; 쪭; 쪭; 쪭; ) HANGUL SYLLABLE JJYELT
+CAAE;CAAE;110D 1168 11B5;CAAE;110D 1168 11B5; # (쪮; 쪮; 쪮; 쪮; 쪮; ) HANGUL SYLLABLE JJYELP
+CAAF;CAAF;110D 1168 11B6;CAAF;110D 1168 11B6; # (쪯; 쪯; 쪯; 쪯; 쪯; ) HANGUL SYLLABLE JJYELH
+CAB0;CAB0;110D 1168 11B7;CAB0;110D 1168 11B7; # (쪰; 쪰; 쪰; 쪰; 쪰; ) HANGUL SYLLABLE JJYEM
+CAB1;CAB1;110D 1168 11B8;CAB1;110D 1168 11B8; # (쪱; 쪱; 쪱; 쪱; 쪱; ) HANGUL SYLLABLE JJYEB
+CAB2;CAB2;110D 1168 11B9;CAB2;110D 1168 11B9; # (쪲; 쪲; 쪲; 쪲; 쪲; ) HANGUL SYLLABLE JJYEBS
+CAB3;CAB3;110D 1168 11BA;CAB3;110D 1168 11BA; # (쪳; 쪳; 쪳; 쪳; 쪳; ) HANGUL SYLLABLE JJYES
+CAB4;CAB4;110D 1168 11BB;CAB4;110D 1168 11BB; # (쪴; 쪴; 쪴; 쪴; 쪴; ) HANGUL SYLLABLE JJYESS
+CAB5;CAB5;110D 1168 11BC;CAB5;110D 1168 11BC; # (쪵; 쪵; 쪵; 쪵; 쪵; ) HANGUL SYLLABLE JJYENG
+CAB6;CAB6;110D 1168 11BD;CAB6;110D 1168 11BD; # (쪶; 쪶; 쪶; 쪶; 쪶; ) HANGUL SYLLABLE JJYEJ
+CAB7;CAB7;110D 1168 11BE;CAB7;110D 1168 11BE; # (쪷; 쪷; 쪷; 쪷; 쪷; ) HANGUL SYLLABLE JJYEC
+CAB8;CAB8;110D 1168 11BF;CAB8;110D 1168 11BF; # (쪸; 쪸; 쪸; 쪸; 쪸; ) HANGUL SYLLABLE JJYEK
+CAB9;CAB9;110D 1168 11C0;CAB9;110D 1168 11C0; # (쪹; 쪹; 쪹; 쪹; 쪹; ) HANGUL SYLLABLE JJYET
+CABA;CABA;110D 1168 11C1;CABA;110D 1168 11C1; # (쪺; 쪺; 쪺; 쪺; 쪺; ) HANGUL SYLLABLE JJYEP
+CABB;CABB;110D 1168 11C2;CABB;110D 1168 11C2; # (쪻; 쪻; 쪻; 쪻; 쪻; ) HANGUL SYLLABLE JJYEH
+CABC;CABC;110D 1169;CABC;110D 1169; # (쪼; 쪼; 쪼; 쪼; 쪼; ) HANGUL SYLLABLE JJO
+CABD;CABD;110D 1169 11A8;CABD;110D 1169 11A8; # (쪽; 쪽; 쪽; 쪽; 쪽; ) HANGUL SYLLABLE JJOG
+CABE;CABE;110D 1169 11A9;CABE;110D 1169 11A9; # (쪾; 쪾; 쪾; 쪾; 쪾; ) HANGUL SYLLABLE JJOGG
+CABF;CABF;110D 1169 11AA;CABF;110D 1169 11AA; # (쪿; 쪿; 쪿; 쪿; 쪿; ) HANGUL SYLLABLE JJOGS
+CAC0;CAC0;110D 1169 11AB;CAC0;110D 1169 11AB; # (쫀; 쫀; 쫀; 쫀; 쫀; ) HANGUL SYLLABLE JJON
+CAC1;CAC1;110D 1169 11AC;CAC1;110D 1169 11AC; # (쫁; 쫁; 쫁; 쫁; 쫁; ) HANGUL SYLLABLE JJONJ
+CAC2;CAC2;110D 1169 11AD;CAC2;110D 1169 11AD; # (쫂; 쫂; 쫂; 쫂; 쫂; ) HANGUL SYLLABLE JJONH
+CAC3;CAC3;110D 1169 11AE;CAC3;110D 1169 11AE; # (쫃; 쫃; 쫃; 쫃; 쫃; ) HANGUL SYLLABLE JJOD
+CAC4;CAC4;110D 1169 11AF;CAC4;110D 1169 11AF; # (쫄; 쫄; 쫄; 쫄; 쫄; ) HANGUL SYLLABLE JJOL
+CAC5;CAC5;110D 1169 11B0;CAC5;110D 1169 11B0; # (쫅; 쫅; 쫅; 쫅; 쫅; ) HANGUL SYLLABLE JJOLG
+CAC6;CAC6;110D 1169 11B1;CAC6;110D 1169 11B1; # (쫆; 쫆; 쫆; 쫆; 쫆; ) HANGUL SYLLABLE JJOLM
+CAC7;CAC7;110D 1169 11B2;CAC7;110D 1169 11B2; # (쫇; 쫇; 쫇; 쫇; 쫇; ) HANGUL SYLLABLE JJOLB
+CAC8;CAC8;110D 1169 11B3;CAC8;110D 1169 11B3; # (쫈; 쫈; 쫈; 쫈; 쫈; ) HANGUL SYLLABLE JJOLS
+CAC9;CAC9;110D 1169 11B4;CAC9;110D 1169 11B4; # (쫉; 쫉; 쫉; 쫉; 쫉; ) HANGUL SYLLABLE JJOLT
+CACA;CACA;110D 1169 11B5;CACA;110D 1169 11B5; # (쫊; 쫊; 쫊; 쫊; 쫊; ) HANGUL SYLLABLE JJOLP
+CACB;CACB;110D 1169 11B6;CACB;110D 1169 11B6; # (쫋; 쫋; 쫋; 쫋; 쫋; ) HANGUL SYLLABLE JJOLH
+CACC;CACC;110D 1169 11B7;CACC;110D 1169 11B7; # (쫌; 쫌; 쫌; 쫌; 쫌; ) HANGUL SYLLABLE JJOM
+CACD;CACD;110D 1169 11B8;CACD;110D 1169 11B8; # (쫍; 쫍; 쫍; 쫍; 쫍; ) HANGUL SYLLABLE JJOB
+CACE;CACE;110D 1169 11B9;CACE;110D 1169 11B9; # (쫎; 쫎; 쫎; 쫎; 쫎; ) HANGUL SYLLABLE JJOBS
+CACF;CACF;110D 1169 11BA;CACF;110D 1169 11BA; # (쫏; 쫏; 쫏; 쫏; 쫏; ) HANGUL SYLLABLE JJOS
+CAD0;CAD0;110D 1169 11BB;CAD0;110D 1169 11BB; # (쫐; 쫐; 쫐; 쫐; 쫐; ) HANGUL SYLLABLE JJOSS
+CAD1;CAD1;110D 1169 11BC;CAD1;110D 1169 11BC; # (쫑; 쫑; 쫑; 쫑; 쫑; ) HANGUL SYLLABLE JJONG
+CAD2;CAD2;110D 1169 11BD;CAD2;110D 1169 11BD; # (쫒; 쫒; 쫒; 쫒; 쫒; ) HANGUL SYLLABLE JJOJ
+CAD3;CAD3;110D 1169 11BE;CAD3;110D 1169 11BE; # (쫓; 쫓; 쫓; 쫓; 쫓; ) HANGUL SYLLABLE JJOC
+CAD4;CAD4;110D 1169 11BF;CAD4;110D 1169 11BF; # (쫔; 쫔; 쫔; 쫔; 쫔; ) HANGUL SYLLABLE JJOK
+CAD5;CAD5;110D 1169 11C0;CAD5;110D 1169 11C0; # (쫕; 쫕; 쫕; 쫕; 쫕; ) HANGUL SYLLABLE JJOT
+CAD6;CAD6;110D 1169 11C1;CAD6;110D 1169 11C1; # (쫖; 쫖; 쫖; 쫖; 쫖; ) HANGUL SYLLABLE JJOP
+CAD7;CAD7;110D 1169 11C2;CAD7;110D 1169 11C2; # (쫗; 쫗; 쫗; 쫗; 쫗; ) HANGUL SYLLABLE JJOH
+CAD8;CAD8;110D 116A;CAD8;110D 116A; # (쫘; 쫘; 쫘; 쫘; 쫘; ) HANGUL SYLLABLE JJWA
+CAD9;CAD9;110D 116A 11A8;CAD9;110D 116A 11A8; # (쫙; 쫙; 쫙; 쫙; 쫙; ) HANGUL SYLLABLE JJWAG
+CADA;CADA;110D 116A 11A9;CADA;110D 116A 11A9; # (쫚; 쫚; 쫚; 쫚; 쫚; ) HANGUL SYLLABLE JJWAGG
+CADB;CADB;110D 116A 11AA;CADB;110D 116A 11AA; # (쫛; 쫛; 쫛; 쫛; 쫛; ) HANGUL SYLLABLE JJWAGS
+CADC;CADC;110D 116A 11AB;CADC;110D 116A 11AB; # (쫜; 쫜; 쫜; 쫜; 쫜; ) HANGUL SYLLABLE JJWAN
+CADD;CADD;110D 116A 11AC;CADD;110D 116A 11AC; # (쫝; 쫝; 쫝; 쫝; 쫝; ) HANGUL SYLLABLE JJWANJ
+CADE;CADE;110D 116A 11AD;CADE;110D 116A 11AD; # (쫞; 쫞; 쫞; 쫞; 쫞; ) HANGUL SYLLABLE JJWANH
+CADF;CADF;110D 116A 11AE;CADF;110D 116A 11AE; # (쫟; 쫟; 쫟; 쫟; 쫟; ) HANGUL SYLLABLE JJWAD
+CAE0;CAE0;110D 116A 11AF;CAE0;110D 116A 11AF; # (쫠; 쫠; 쫠; 쫠; 쫠; ) HANGUL SYLLABLE JJWAL
+CAE1;CAE1;110D 116A 11B0;CAE1;110D 116A 11B0; # (쫡; 쫡; 쫡; 쫡; 쫡; ) HANGUL SYLLABLE JJWALG
+CAE2;CAE2;110D 116A 11B1;CAE2;110D 116A 11B1; # (쫢; 쫢; 쫢; 쫢; 쫢; ) HANGUL SYLLABLE JJWALM
+CAE3;CAE3;110D 116A 11B2;CAE3;110D 116A 11B2; # (쫣; 쫣; 쫣; 쫣; 쫣; ) HANGUL SYLLABLE JJWALB
+CAE4;CAE4;110D 116A 11B3;CAE4;110D 116A 11B3; # (쫤; 쫤; 쫤; 쫤; 쫤; ) HANGUL SYLLABLE JJWALS
+CAE5;CAE5;110D 116A 11B4;CAE5;110D 116A 11B4; # (쫥; 쫥; 쫥; 쫥; 쫥; ) HANGUL SYLLABLE JJWALT
+CAE6;CAE6;110D 116A 11B5;CAE6;110D 116A 11B5; # (쫦; 쫦; 쫦; 쫦; 쫦; ) HANGUL SYLLABLE JJWALP
+CAE7;CAE7;110D 116A 11B6;CAE7;110D 116A 11B6; # (쫧; 쫧; 쫧; 쫧; 쫧; ) HANGUL SYLLABLE JJWALH
+CAE8;CAE8;110D 116A 11B7;CAE8;110D 116A 11B7; # (쫨; 쫨; 쫨; 쫨; 쫨; ) HANGUL SYLLABLE JJWAM
+CAE9;CAE9;110D 116A 11B8;CAE9;110D 116A 11B8; # (쫩; 쫩; 쫩; 쫩; 쫩; ) HANGUL SYLLABLE JJWAB
+CAEA;CAEA;110D 116A 11B9;CAEA;110D 116A 11B9; # (쫪; 쫪; 쫪; 쫪; 쫪; ) HANGUL SYLLABLE JJWABS
+CAEB;CAEB;110D 116A 11BA;CAEB;110D 116A 11BA; # (쫫; 쫫; 쫫; 쫫; 쫫; ) HANGUL SYLLABLE JJWAS
+CAEC;CAEC;110D 116A 11BB;CAEC;110D 116A 11BB; # (쫬; 쫬; 쫬; 쫬; 쫬; ) HANGUL SYLLABLE JJWASS
+CAED;CAED;110D 116A 11BC;CAED;110D 116A 11BC; # (쫭; 쫭; 쫭; 쫭; 쫭; ) HANGUL SYLLABLE JJWANG
+CAEE;CAEE;110D 116A 11BD;CAEE;110D 116A 11BD; # (쫮; 쫮; 쫮; 쫮; 쫮; ) HANGUL SYLLABLE JJWAJ
+CAEF;CAEF;110D 116A 11BE;CAEF;110D 116A 11BE; # (쫯; 쫯; 쫯; 쫯; 쫯; ) HANGUL SYLLABLE JJWAC
+CAF0;CAF0;110D 116A 11BF;CAF0;110D 116A 11BF; # (쫰; 쫰; 쫰; 쫰; 쫰; ) HANGUL SYLLABLE JJWAK
+CAF1;CAF1;110D 116A 11C0;CAF1;110D 116A 11C0; # (쫱; 쫱; 쫱; 쫱; 쫱; ) HANGUL SYLLABLE JJWAT
+CAF2;CAF2;110D 116A 11C1;CAF2;110D 116A 11C1; # (쫲; 쫲; 쫲; 쫲; 쫲; ) HANGUL SYLLABLE JJWAP
+CAF3;CAF3;110D 116A 11C2;CAF3;110D 116A 11C2; # (쫳; 쫳; 쫳; 쫳; 쫳; ) HANGUL SYLLABLE JJWAH
+CAF4;CAF4;110D 116B;CAF4;110D 116B; # (쫴; 쫴; 쫴; 쫴; 쫴; ) HANGUL SYLLABLE JJWAE
+CAF5;CAF5;110D 116B 11A8;CAF5;110D 116B 11A8; # (쫵; 쫵; 쫵; 쫵; 쫵; ) HANGUL SYLLABLE JJWAEG
+CAF6;CAF6;110D 116B 11A9;CAF6;110D 116B 11A9; # (쫶; 쫶; 쫶; 쫶; 쫶; ) HANGUL SYLLABLE JJWAEGG
+CAF7;CAF7;110D 116B 11AA;CAF7;110D 116B 11AA; # (쫷; 쫷; 쫷; 쫷; 쫷; ) HANGUL SYLLABLE JJWAEGS
+CAF8;CAF8;110D 116B 11AB;CAF8;110D 116B 11AB; # (쫸; 쫸; 쫸; 쫸; 쫸; ) HANGUL SYLLABLE JJWAEN
+CAF9;CAF9;110D 116B 11AC;CAF9;110D 116B 11AC; # (쫹; 쫹; 쫹; 쫹; 쫹; ) HANGUL SYLLABLE JJWAENJ
+CAFA;CAFA;110D 116B 11AD;CAFA;110D 116B 11AD; # (쫺; 쫺; 쫺; 쫺; 쫺; ) HANGUL SYLLABLE JJWAENH
+CAFB;CAFB;110D 116B 11AE;CAFB;110D 116B 11AE; # (쫻; 쫻; 쫻; 쫻; 쫻; ) HANGUL SYLLABLE JJWAED
+CAFC;CAFC;110D 116B 11AF;CAFC;110D 116B 11AF; # (쫼; 쫼; 쫼; 쫼; 쫼; ) HANGUL SYLLABLE JJWAEL
+CAFD;CAFD;110D 116B 11B0;CAFD;110D 116B 11B0; # (쫽; 쫽; 쫽; 쫽; 쫽; ) HANGUL SYLLABLE JJWAELG
+CAFE;CAFE;110D 116B 11B1;CAFE;110D 116B 11B1; # (쫾; 쫾; 쫾; 쫾; 쫾; ) HANGUL SYLLABLE JJWAELM
+CAFF;CAFF;110D 116B 11B2;CAFF;110D 116B 11B2; # (쫿; 쫿; 쫿; 쫿; 쫿; ) HANGUL SYLLABLE JJWAELB
+CB00;CB00;110D 116B 11B3;CB00;110D 116B 11B3; # (쬀; 쬀; 쬀; 쬀; 쬀; ) HANGUL SYLLABLE JJWAELS
+CB01;CB01;110D 116B 11B4;CB01;110D 116B 11B4; # (쬁; 쬁; 쬁; 쬁; 쬁; ) HANGUL SYLLABLE JJWAELT
+CB02;CB02;110D 116B 11B5;CB02;110D 116B 11B5; # (쬂; 쬂; 쬂; 쬂; 쬂; ) HANGUL SYLLABLE JJWAELP
+CB03;CB03;110D 116B 11B6;CB03;110D 116B 11B6; # (쬃; 쬃; 쬃; 쬃; 쬃; ) HANGUL SYLLABLE JJWAELH
+CB04;CB04;110D 116B 11B7;CB04;110D 116B 11B7; # (쬄; 쬄; 쬄; 쬄; 쬄; ) HANGUL SYLLABLE JJWAEM
+CB05;CB05;110D 116B 11B8;CB05;110D 116B 11B8; # (쬅; 쬅; 쬅; 쬅; 쬅; ) HANGUL SYLLABLE JJWAEB
+CB06;CB06;110D 116B 11B9;CB06;110D 116B 11B9; # (쬆; 쬆; 쬆; 쬆; 쬆; ) HANGUL SYLLABLE JJWAEBS
+CB07;CB07;110D 116B 11BA;CB07;110D 116B 11BA; # (쬇; 쬇; 쬇; 쬇; 쬇; ) HANGUL SYLLABLE JJWAES
+CB08;CB08;110D 116B 11BB;CB08;110D 116B 11BB; # (쬈; 쬈; 쬈; 쬈; 쬈; ) HANGUL SYLLABLE JJWAESS
+CB09;CB09;110D 116B 11BC;CB09;110D 116B 11BC; # (쬉; 쬉; 쬉; 쬉; 쬉; ) HANGUL SYLLABLE JJWAENG
+CB0A;CB0A;110D 116B 11BD;CB0A;110D 116B 11BD; # (쬊; 쬊; 쬊; 쬊; 쬊; ) HANGUL SYLLABLE JJWAEJ
+CB0B;CB0B;110D 116B 11BE;CB0B;110D 116B 11BE; # (쬋; 쬋; 쬋; 쬋; 쬋; ) HANGUL SYLLABLE JJWAEC
+CB0C;CB0C;110D 116B 11BF;CB0C;110D 116B 11BF; # (쬌; 쬌; 쬌; 쬌; 쬌; ) HANGUL SYLLABLE JJWAEK
+CB0D;CB0D;110D 116B 11C0;CB0D;110D 116B 11C0; # (쬍; 쬍; 쬍; 쬍; 쬍; ) HANGUL SYLLABLE JJWAET
+CB0E;CB0E;110D 116B 11C1;CB0E;110D 116B 11C1; # (쬎; 쬎; 쬎; 쬎; 쬎; ) HANGUL SYLLABLE JJWAEP
+CB0F;CB0F;110D 116B 11C2;CB0F;110D 116B 11C2; # (쬏; 쬏; 쬏; 쬏; 쬏; ) HANGUL SYLLABLE JJWAEH
+CB10;CB10;110D 116C;CB10;110D 116C; # (쬐; 쬐; 쬐; 쬐; 쬐; ) HANGUL SYLLABLE JJOE
+CB11;CB11;110D 116C 11A8;CB11;110D 116C 11A8; # (쬑; 쬑; 쬑; 쬑; 쬑; ) HANGUL SYLLABLE JJOEG
+CB12;CB12;110D 116C 11A9;CB12;110D 116C 11A9; # (쬒; 쬒; 쬒; 쬒; 쬒; ) HANGUL SYLLABLE JJOEGG
+CB13;CB13;110D 116C 11AA;CB13;110D 116C 11AA; # (쬓; 쬓; 쬓; 쬓; 쬓; ) HANGUL SYLLABLE JJOEGS
+CB14;CB14;110D 116C 11AB;CB14;110D 116C 11AB; # (쬔; 쬔; 쬔; 쬔; 쬔; ) HANGUL SYLLABLE JJOEN
+CB15;CB15;110D 116C 11AC;CB15;110D 116C 11AC; # (쬕; 쬕; 쬕; 쬕; 쬕; ) HANGUL SYLLABLE JJOENJ
+CB16;CB16;110D 116C 11AD;CB16;110D 116C 11AD; # (쬖; 쬖; 쬖; 쬖; 쬖; ) HANGUL SYLLABLE JJOENH
+CB17;CB17;110D 116C 11AE;CB17;110D 116C 11AE; # (쬗; 쬗; 쬗; 쬗; 쬗; ) HANGUL SYLLABLE JJOED
+CB18;CB18;110D 116C 11AF;CB18;110D 116C 11AF; # (쬘; 쬘; 쬘; 쬘; 쬘; ) HANGUL SYLLABLE JJOEL
+CB19;CB19;110D 116C 11B0;CB19;110D 116C 11B0; # (쬙; 쬙; 쬙; 쬙; 쬙; ) HANGUL SYLLABLE JJOELG
+CB1A;CB1A;110D 116C 11B1;CB1A;110D 116C 11B1; # (쬚; 쬚; 쬚; 쬚; 쬚; ) HANGUL SYLLABLE JJOELM
+CB1B;CB1B;110D 116C 11B2;CB1B;110D 116C 11B2; # (쬛; 쬛; 쬛; 쬛; 쬛; ) HANGUL SYLLABLE JJOELB
+CB1C;CB1C;110D 116C 11B3;CB1C;110D 116C 11B3; # (쬜; 쬜; 쬜; 쬜; 쬜; ) HANGUL SYLLABLE JJOELS
+CB1D;CB1D;110D 116C 11B4;CB1D;110D 116C 11B4; # (쬝; 쬝; 쬝; 쬝; 쬝; ) HANGUL SYLLABLE JJOELT
+CB1E;CB1E;110D 116C 11B5;CB1E;110D 116C 11B5; # (쬞; 쬞; 쬞; 쬞; 쬞; ) HANGUL SYLLABLE JJOELP
+CB1F;CB1F;110D 116C 11B6;CB1F;110D 116C 11B6; # (쬟; 쬟; 쬟; 쬟; 쬟; ) HANGUL SYLLABLE JJOELH
+CB20;CB20;110D 116C 11B7;CB20;110D 116C 11B7; # (쬠; 쬠; 쬠; 쬠; 쬠; ) HANGUL SYLLABLE JJOEM
+CB21;CB21;110D 116C 11B8;CB21;110D 116C 11B8; # (쬡; 쬡; 쬡; 쬡; 쬡; ) HANGUL SYLLABLE JJOEB
+CB22;CB22;110D 116C 11B9;CB22;110D 116C 11B9; # (쬢; 쬢; 쬢; 쬢; 쬢; ) HANGUL SYLLABLE JJOEBS
+CB23;CB23;110D 116C 11BA;CB23;110D 116C 11BA; # (쬣; 쬣; 쬣; 쬣; 쬣; ) HANGUL SYLLABLE JJOES
+CB24;CB24;110D 116C 11BB;CB24;110D 116C 11BB; # (쬤; 쬤; 쬤; 쬤; 쬤; ) HANGUL SYLLABLE JJOESS
+CB25;CB25;110D 116C 11BC;CB25;110D 116C 11BC; # (쬥; 쬥; 쬥; 쬥; 쬥; ) HANGUL SYLLABLE JJOENG
+CB26;CB26;110D 116C 11BD;CB26;110D 116C 11BD; # (쬦; 쬦; 쬦; 쬦; 쬦; ) HANGUL SYLLABLE JJOEJ
+CB27;CB27;110D 116C 11BE;CB27;110D 116C 11BE; # (쬧; 쬧; 쬧; 쬧; 쬧; ) HANGUL SYLLABLE JJOEC
+CB28;CB28;110D 116C 11BF;CB28;110D 116C 11BF; # (쬨; 쬨; 쬨; 쬨; 쬨; ) HANGUL SYLLABLE JJOEK
+CB29;CB29;110D 116C 11C0;CB29;110D 116C 11C0; # (쬩; 쬩; 쬩; 쬩; 쬩; ) HANGUL SYLLABLE JJOET
+CB2A;CB2A;110D 116C 11C1;CB2A;110D 116C 11C1; # (쬪; 쬪; 쬪; 쬪; 쬪; ) HANGUL SYLLABLE JJOEP
+CB2B;CB2B;110D 116C 11C2;CB2B;110D 116C 11C2; # (쬫; 쬫; 쬫; 쬫; 쬫; ) HANGUL SYLLABLE JJOEH
+CB2C;CB2C;110D 116D;CB2C;110D 116D; # (쬬; 쬬; 쬬; 쬬; 쬬; ) HANGUL SYLLABLE JJYO
+CB2D;CB2D;110D 116D 11A8;CB2D;110D 116D 11A8; # (쬭; 쬭; 쬭; 쬭; 쬭; ) HANGUL SYLLABLE JJYOG
+CB2E;CB2E;110D 116D 11A9;CB2E;110D 116D 11A9; # (쬮; 쬮; 쬮; 쬮; 쬮; ) HANGUL SYLLABLE JJYOGG
+CB2F;CB2F;110D 116D 11AA;CB2F;110D 116D 11AA; # (쬯; 쬯; 쬯; 쬯; 쬯; ) HANGUL SYLLABLE JJYOGS
+CB30;CB30;110D 116D 11AB;CB30;110D 116D 11AB; # (쬰; 쬰; 쬰; 쬰; 쬰; ) HANGUL SYLLABLE JJYON
+CB31;CB31;110D 116D 11AC;CB31;110D 116D 11AC; # (쬱; 쬱; 쬱; 쬱; 쬱; ) HANGUL SYLLABLE JJYONJ
+CB32;CB32;110D 116D 11AD;CB32;110D 116D 11AD; # (쬲; 쬲; 쬲; 쬲; 쬲; ) HANGUL SYLLABLE JJYONH
+CB33;CB33;110D 116D 11AE;CB33;110D 116D 11AE; # (쬳; 쬳; 쬳; 쬳; 쬳; ) HANGUL SYLLABLE JJYOD
+CB34;CB34;110D 116D 11AF;CB34;110D 116D 11AF; # (쬴; 쬴; 쬴; 쬴; 쬴; ) HANGUL SYLLABLE JJYOL
+CB35;CB35;110D 116D 11B0;CB35;110D 116D 11B0; # (쬵; 쬵; 쬵; 쬵; 쬵; ) HANGUL SYLLABLE JJYOLG
+CB36;CB36;110D 116D 11B1;CB36;110D 116D 11B1; # (쬶; 쬶; 쬶; 쬶; 쬶; ) HANGUL SYLLABLE JJYOLM
+CB37;CB37;110D 116D 11B2;CB37;110D 116D 11B2; # (쬷; 쬷; 쬷; 쬷; 쬷; ) HANGUL SYLLABLE JJYOLB
+CB38;CB38;110D 116D 11B3;CB38;110D 116D 11B3; # (쬸; 쬸; 쬸; 쬸; 쬸; ) HANGUL SYLLABLE JJYOLS
+CB39;CB39;110D 116D 11B4;CB39;110D 116D 11B4; # (쬹; 쬹; 쬹; 쬹; 쬹; ) HANGUL SYLLABLE JJYOLT
+CB3A;CB3A;110D 116D 11B5;CB3A;110D 116D 11B5; # (쬺; 쬺; 쬺; 쬺; 쬺; ) HANGUL SYLLABLE JJYOLP
+CB3B;CB3B;110D 116D 11B6;CB3B;110D 116D 11B6; # (쬻; 쬻; 쬻; 쬻; 쬻; ) HANGUL SYLLABLE JJYOLH
+CB3C;CB3C;110D 116D 11B7;CB3C;110D 116D 11B7; # (쬼; 쬼; 쬼; 쬼; 쬼; ) HANGUL SYLLABLE JJYOM
+CB3D;CB3D;110D 116D 11B8;CB3D;110D 116D 11B8; # (쬽; 쬽; 쬽; 쬽; 쬽; ) HANGUL SYLLABLE JJYOB
+CB3E;CB3E;110D 116D 11B9;CB3E;110D 116D 11B9; # (쬾; 쬾; 쬾; 쬾; 쬾; ) HANGUL SYLLABLE JJYOBS
+CB3F;CB3F;110D 116D 11BA;CB3F;110D 116D 11BA; # (쬿; 쬿; 쬿; 쬿; 쬿; ) HANGUL SYLLABLE JJYOS
+CB40;CB40;110D 116D 11BB;CB40;110D 116D 11BB; # (쭀; 쭀; 쭀; 쭀; 쭀; ) HANGUL SYLLABLE JJYOSS
+CB41;CB41;110D 116D 11BC;CB41;110D 116D 11BC; # (쭁; 쭁; 쭁; 쭁; 쭁; ) HANGUL SYLLABLE JJYONG
+CB42;CB42;110D 116D 11BD;CB42;110D 116D 11BD; # (쭂; 쭂; 쭂; 쭂; 쭂; ) HANGUL SYLLABLE JJYOJ
+CB43;CB43;110D 116D 11BE;CB43;110D 116D 11BE; # (쭃; 쭃; 쭃; 쭃; 쭃; ) HANGUL SYLLABLE JJYOC
+CB44;CB44;110D 116D 11BF;CB44;110D 116D 11BF; # (쭄; 쭄; 쭄; 쭄; 쭄; ) HANGUL SYLLABLE JJYOK
+CB45;CB45;110D 116D 11C0;CB45;110D 116D 11C0; # (쭅; 쭅; 쭅; 쭅; 쭅; ) HANGUL SYLLABLE JJYOT
+CB46;CB46;110D 116D 11C1;CB46;110D 116D 11C1; # (쭆; 쭆; 쭆; 쭆; 쭆; ) HANGUL SYLLABLE JJYOP
+CB47;CB47;110D 116D 11C2;CB47;110D 116D 11C2; # (쭇; 쭇; 쭇; 쭇; 쭇; ) HANGUL SYLLABLE JJYOH
+CB48;CB48;110D 116E;CB48;110D 116E; # (쭈; 쭈; 쭈; 쭈; 쭈; ) HANGUL SYLLABLE JJU
+CB49;CB49;110D 116E 11A8;CB49;110D 116E 11A8; # (쭉; 쭉; 쭉; 쭉; 쭉; ) HANGUL SYLLABLE JJUG
+CB4A;CB4A;110D 116E 11A9;CB4A;110D 116E 11A9; # (쭊; 쭊; 쭊; 쭊; 쭊; ) HANGUL SYLLABLE JJUGG
+CB4B;CB4B;110D 116E 11AA;CB4B;110D 116E 11AA; # (쭋; 쭋; 쭋; 쭋; 쭋; ) HANGUL SYLLABLE JJUGS
+CB4C;CB4C;110D 116E 11AB;CB4C;110D 116E 11AB; # (쭌; 쭌; 쭌; 쭌; 쭌; ) HANGUL SYLLABLE JJUN
+CB4D;CB4D;110D 116E 11AC;CB4D;110D 116E 11AC; # (쭍; 쭍; 쭍; 쭍; 쭍; ) HANGUL SYLLABLE JJUNJ
+CB4E;CB4E;110D 116E 11AD;CB4E;110D 116E 11AD; # (쭎; 쭎; 쭎; 쭎; 쭎; ) HANGUL SYLLABLE JJUNH
+CB4F;CB4F;110D 116E 11AE;CB4F;110D 116E 11AE; # (쭏; 쭏; 쭏; 쭏; 쭏; ) HANGUL SYLLABLE JJUD
+CB50;CB50;110D 116E 11AF;CB50;110D 116E 11AF; # (쭐; 쭐; 쭐; 쭐; 쭐; ) HANGUL SYLLABLE JJUL
+CB51;CB51;110D 116E 11B0;CB51;110D 116E 11B0; # (쭑; 쭑; 쭑; 쭑; 쭑; ) HANGUL SYLLABLE JJULG
+CB52;CB52;110D 116E 11B1;CB52;110D 116E 11B1; # (쭒; 쭒; 쭒; 쭒; 쭒; ) HANGUL SYLLABLE JJULM
+CB53;CB53;110D 116E 11B2;CB53;110D 116E 11B2; # (쭓; 쭓; 쭓; 쭓; 쭓; ) HANGUL SYLLABLE JJULB
+CB54;CB54;110D 116E 11B3;CB54;110D 116E 11B3; # (쭔; 쭔; 쭔; 쭔; 쭔; ) HANGUL SYLLABLE JJULS
+CB55;CB55;110D 116E 11B4;CB55;110D 116E 11B4; # (쭕; 쭕; 쭕; 쭕; 쭕; ) HANGUL SYLLABLE JJULT
+CB56;CB56;110D 116E 11B5;CB56;110D 116E 11B5; # (쭖; 쭖; 쭖; 쭖; 쭖; ) HANGUL SYLLABLE JJULP
+CB57;CB57;110D 116E 11B6;CB57;110D 116E 11B6; # (쭗; 쭗; 쭗; 쭗; 쭗; ) HANGUL SYLLABLE JJULH
+CB58;CB58;110D 116E 11B7;CB58;110D 116E 11B7; # (쭘; 쭘; 쭘; 쭘; 쭘; ) HANGUL SYLLABLE JJUM
+CB59;CB59;110D 116E 11B8;CB59;110D 116E 11B8; # (쭙; 쭙; 쭙; 쭙; 쭙; ) HANGUL SYLLABLE JJUB
+CB5A;CB5A;110D 116E 11B9;CB5A;110D 116E 11B9; # (쭚; 쭚; 쭚; 쭚; 쭚; ) HANGUL SYLLABLE JJUBS
+CB5B;CB5B;110D 116E 11BA;CB5B;110D 116E 11BA; # (쭛; 쭛; 쭛; 쭛; 쭛; ) HANGUL SYLLABLE JJUS
+CB5C;CB5C;110D 116E 11BB;CB5C;110D 116E 11BB; # (쭜; 쭜; 쭜; 쭜; 쭜; ) HANGUL SYLLABLE JJUSS
+CB5D;CB5D;110D 116E 11BC;CB5D;110D 116E 11BC; # (쭝; 쭝; 쭝; 쭝; 쭝; ) HANGUL SYLLABLE JJUNG
+CB5E;CB5E;110D 116E 11BD;CB5E;110D 116E 11BD; # (쭞; 쭞; 쭞; 쭞; 쭞; ) HANGUL SYLLABLE JJUJ
+CB5F;CB5F;110D 116E 11BE;CB5F;110D 116E 11BE; # (쭟; 쭟; 쭟; 쭟; 쭟; ) HANGUL SYLLABLE JJUC
+CB60;CB60;110D 116E 11BF;CB60;110D 116E 11BF; # (쭠; 쭠; 쭠; 쭠; 쭠; ) HANGUL SYLLABLE JJUK
+CB61;CB61;110D 116E 11C0;CB61;110D 116E 11C0; # (쭡; 쭡; 쭡; 쭡; 쭡; ) HANGUL SYLLABLE JJUT
+CB62;CB62;110D 116E 11C1;CB62;110D 116E 11C1; # (쭢; 쭢; 쭢; 쭢; 쭢; ) HANGUL SYLLABLE JJUP
+CB63;CB63;110D 116E 11C2;CB63;110D 116E 11C2; # (쭣; 쭣; 쭣; 쭣; 쭣; ) HANGUL SYLLABLE JJUH
+CB64;CB64;110D 116F;CB64;110D 116F; # (쭤; 쭤; 쭤; 쭤; 쭤; ) HANGUL SYLLABLE JJWEO
+CB65;CB65;110D 116F 11A8;CB65;110D 116F 11A8; # (쭥; 쭥; 쭥; 쭥; 쭥; ) HANGUL SYLLABLE JJWEOG
+CB66;CB66;110D 116F 11A9;CB66;110D 116F 11A9; # (쭦; 쭦; 쭦; 쭦; 쭦; ) HANGUL SYLLABLE JJWEOGG
+CB67;CB67;110D 116F 11AA;CB67;110D 116F 11AA; # (쭧; 쭧; 쭧; 쭧; 쭧; ) HANGUL SYLLABLE JJWEOGS
+CB68;CB68;110D 116F 11AB;CB68;110D 116F 11AB; # (쭨; 쭨; 쭨; 쭨; 쭨; ) HANGUL SYLLABLE JJWEON
+CB69;CB69;110D 116F 11AC;CB69;110D 116F 11AC; # (쭩; 쭩; 쭩; 쭩; 쭩; ) HANGUL SYLLABLE JJWEONJ
+CB6A;CB6A;110D 116F 11AD;CB6A;110D 116F 11AD; # (쭪; 쭪; 쭪; 쭪; 쭪; ) HANGUL SYLLABLE JJWEONH
+CB6B;CB6B;110D 116F 11AE;CB6B;110D 116F 11AE; # (쭫; 쭫; 쭫; 쭫; 쭫; ) HANGUL SYLLABLE JJWEOD
+CB6C;CB6C;110D 116F 11AF;CB6C;110D 116F 11AF; # (쭬; 쭬; 쭬; 쭬; 쭬; ) HANGUL SYLLABLE JJWEOL
+CB6D;CB6D;110D 116F 11B0;CB6D;110D 116F 11B0; # (쭭; 쭭; 쭭; 쭭; 쭭; ) HANGUL SYLLABLE JJWEOLG
+CB6E;CB6E;110D 116F 11B1;CB6E;110D 116F 11B1; # (쭮; 쭮; 쭮; 쭮; 쭮; ) HANGUL SYLLABLE JJWEOLM
+CB6F;CB6F;110D 116F 11B2;CB6F;110D 116F 11B2; # (쭯; 쭯; 쭯; 쭯; 쭯; ) HANGUL SYLLABLE JJWEOLB
+CB70;CB70;110D 116F 11B3;CB70;110D 116F 11B3; # (쭰; 쭰; 쭰; 쭰; 쭰; ) HANGUL SYLLABLE JJWEOLS
+CB71;CB71;110D 116F 11B4;CB71;110D 116F 11B4; # (쭱; 쭱; 쭱; 쭱; 쭱; ) HANGUL SYLLABLE JJWEOLT
+CB72;CB72;110D 116F 11B5;CB72;110D 116F 11B5; # (쭲; 쭲; 쭲; 쭲; 쭲; ) HANGUL SYLLABLE JJWEOLP
+CB73;CB73;110D 116F 11B6;CB73;110D 116F 11B6; # (쭳; 쭳; 쭳; 쭳; 쭳; ) HANGUL SYLLABLE JJWEOLH
+CB74;CB74;110D 116F 11B7;CB74;110D 116F 11B7; # (쭴; 쭴; 쭴; 쭴; 쭴; ) HANGUL SYLLABLE JJWEOM
+CB75;CB75;110D 116F 11B8;CB75;110D 116F 11B8; # (쭵; 쭵; 쭵; 쭵; 쭵; ) HANGUL SYLLABLE JJWEOB
+CB76;CB76;110D 116F 11B9;CB76;110D 116F 11B9; # (쭶; 쭶; 쭶; 쭶; 쭶; ) HANGUL SYLLABLE JJWEOBS
+CB77;CB77;110D 116F 11BA;CB77;110D 116F 11BA; # (쭷; 쭷; 쭷; 쭷; 쭷; ) HANGUL SYLLABLE JJWEOS
+CB78;CB78;110D 116F 11BB;CB78;110D 116F 11BB; # (쭸; 쭸; 쭸; 쭸; 쭸; ) HANGUL SYLLABLE JJWEOSS
+CB79;CB79;110D 116F 11BC;CB79;110D 116F 11BC; # (쭹; 쭹; 쭹; 쭹; 쭹; ) HANGUL SYLLABLE JJWEONG
+CB7A;CB7A;110D 116F 11BD;CB7A;110D 116F 11BD; # (쭺; 쭺; 쭺; 쭺; 쭺; ) HANGUL SYLLABLE JJWEOJ
+CB7B;CB7B;110D 116F 11BE;CB7B;110D 116F 11BE; # (쭻; 쭻; 쭻; 쭻; 쭻; ) HANGUL SYLLABLE JJWEOC
+CB7C;CB7C;110D 116F 11BF;CB7C;110D 116F 11BF; # (쭼; 쭼; 쭼; 쭼; 쭼; ) HANGUL SYLLABLE JJWEOK
+CB7D;CB7D;110D 116F 11C0;CB7D;110D 116F 11C0; # (쭽; 쭽; 쭽; 쭽; 쭽; ) HANGUL SYLLABLE JJWEOT
+CB7E;CB7E;110D 116F 11C1;CB7E;110D 116F 11C1; # (쭾; 쭾; 쭾; 쭾; 쭾; ) HANGUL SYLLABLE JJWEOP
+CB7F;CB7F;110D 116F 11C2;CB7F;110D 116F 11C2; # (쭿; 쭿; 쭿; 쭿; 쭿; ) HANGUL SYLLABLE JJWEOH
+CB80;CB80;110D 1170;CB80;110D 1170; # (쮀; 쮀; 쮀; 쮀; 쮀; ) HANGUL SYLLABLE JJWE
+CB81;CB81;110D 1170 11A8;CB81;110D 1170 11A8; # (쮁; 쮁; 쮁; 쮁; 쮁; ) HANGUL SYLLABLE JJWEG
+CB82;CB82;110D 1170 11A9;CB82;110D 1170 11A9; # (쮂; 쮂; 쮂; 쮂; 쮂; ) HANGUL SYLLABLE JJWEGG
+CB83;CB83;110D 1170 11AA;CB83;110D 1170 11AA; # (쮃; 쮃; 쮃; 쮃; 쮃; ) HANGUL SYLLABLE JJWEGS
+CB84;CB84;110D 1170 11AB;CB84;110D 1170 11AB; # (쮄; 쮄; 쮄; 쮄; 쮄; ) HANGUL SYLLABLE JJWEN
+CB85;CB85;110D 1170 11AC;CB85;110D 1170 11AC; # (쮅; 쮅; 쮅; 쮅; 쮅; ) HANGUL SYLLABLE JJWENJ
+CB86;CB86;110D 1170 11AD;CB86;110D 1170 11AD; # (쮆; 쮆; 쮆; 쮆; 쮆; ) HANGUL SYLLABLE JJWENH
+CB87;CB87;110D 1170 11AE;CB87;110D 1170 11AE; # (쮇; 쮇; 쮇; 쮇; 쮇; ) HANGUL SYLLABLE JJWED
+CB88;CB88;110D 1170 11AF;CB88;110D 1170 11AF; # (쮈; 쮈; 쮈; 쮈; 쮈; ) HANGUL SYLLABLE JJWEL
+CB89;CB89;110D 1170 11B0;CB89;110D 1170 11B0; # (쮉; 쮉; 쮉; 쮉; 쮉; ) HANGUL SYLLABLE JJWELG
+CB8A;CB8A;110D 1170 11B1;CB8A;110D 1170 11B1; # (쮊; 쮊; 쮊; 쮊; 쮊; ) HANGUL SYLLABLE JJWELM
+CB8B;CB8B;110D 1170 11B2;CB8B;110D 1170 11B2; # (쮋; 쮋; 쮋; 쮋; 쮋; ) HANGUL SYLLABLE JJWELB
+CB8C;CB8C;110D 1170 11B3;CB8C;110D 1170 11B3; # (쮌; 쮌; 쮌; 쮌; 쮌; ) HANGUL SYLLABLE JJWELS
+CB8D;CB8D;110D 1170 11B4;CB8D;110D 1170 11B4; # (쮍; 쮍; 쮍; 쮍; 쮍; ) HANGUL SYLLABLE JJWELT
+CB8E;CB8E;110D 1170 11B5;CB8E;110D 1170 11B5; # (쮎; 쮎; 쮎; 쮎; 쮎; ) HANGUL SYLLABLE JJWELP
+CB8F;CB8F;110D 1170 11B6;CB8F;110D 1170 11B6; # (쮏; 쮏; 쮏; 쮏; 쮏; ) HANGUL SYLLABLE JJWELH
+CB90;CB90;110D 1170 11B7;CB90;110D 1170 11B7; # (쮐; 쮐; 쮐; 쮐; 쮐; ) HANGUL SYLLABLE JJWEM
+CB91;CB91;110D 1170 11B8;CB91;110D 1170 11B8; # (쮑; 쮑; 쮑; 쮑; 쮑; ) HANGUL SYLLABLE JJWEB
+CB92;CB92;110D 1170 11B9;CB92;110D 1170 11B9; # (쮒; 쮒; 쮒; 쮒; 쮒; ) HANGUL SYLLABLE JJWEBS
+CB93;CB93;110D 1170 11BA;CB93;110D 1170 11BA; # (쮓; 쮓; 쮓; 쮓; 쮓; ) HANGUL SYLLABLE JJWES
+CB94;CB94;110D 1170 11BB;CB94;110D 1170 11BB; # (쮔; 쮔; 쮔; 쮔; 쮔; ) HANGUL SYLLABLE JJWESS
+CB95;CB95;110D 1170 11BC;CB95;110D 1170 11BC; # (쮕; 쮕; 쮕; 쮕; 쮕; ) HANGUL SYLLABLE JJWENG
+CB96;CB96;110D 1170 11BD;CB96;110D 1170 11BD; # (쮖; 쮖; 쮖; 쮖; 쮖; ) HANGUL SYLLABLE JJWEJ
+CB97;CB97;110D 1170 11BE;CB97;110D 1170 11BE; # (쮗; 쮗; 쮗; 쮗; 쮗; ) HANGUL SYLLABLE JJWEC
+CB98;CB98;110D 1170 11BF;CB98;110D 1170 11BF; # (쮘; 쮘; 쮘; 쮘; 쮘; ) HANGUL SYLLABLE JJWEK
+CB99;CB99;110D 1170 11C0;CB99;110D 1170 11C0; # (쮙; 쮙; 쮙; 쮙; 쮙; ) HANGUL SYLLABLE JJWET
+CB9A;CB9A;110D 1170 11C1;CB9A;110D 1170 11C1; # (쮚; 쮚; 쮚; 쮚; 쮚; ) HANGUL SYLLABLE JJWEP
+CB9B;CB9B;110D 1170 11C2;CB9B;110D 1170 11C2; # (쮛; 쮛; 쮛; 쮛; 쮛; ) HANGUL SYLLABLE JJWEH
+CB9C;CB9C;110D 1171;CB9C;110D 1171; # (쮜; 쮜; 쮜; 쮜; 쮜; ) HANGUL SYLLABLE JJWI
+CB9D;CB9D;110D 1171 11A8;CB9D;110D 1171 11A8; # (쮝; 쮝; 쮝; 쮝; 쮝; ) HANGUL SYLLABLE JJWIG
+CB9E;CB9E;110D 1171 11A9;CB9E;110D 1171 11A9; # (쮞; 쮞; 쮞; 쮞; 쮞; ) HANGUL SYLLABLE JJWIGG
+CB9F;CB9F;110D 1171 11AA;CB9F;110D 1171 11AA; # (쮟; 쮟; 쮟; 쮟; 쮟; ) HANGUL SYLLABLE JJWIGS
+CBA0;CBA0;110D 1171 11AB;CBA0;110D 1171 11AB; # (쮠; 쮠; 쮠; 쮠; 쮠; ) HANGUL SYLLABLE JJWIN
+CBA1;CBA1;110D 1171 11AC;CBA1;110D 1171 11AC; # (쮡; 쮡; 쮡; 쮡; 쮡; ) HANGUL SYLLABLE JJWINJ
+CBA2;CBA2;110D 1171 11AD;CBA2;110D 1171 11AD; # (쮢; 쮢; 쮢; 쮢; 쮢; ) HANGUL SYLLABLE JJWINH
+CBA3;CBA3;110D 1171 11AE;CBA3;110D 1171 11AE; # (쮣; 쮣; 쮣; 쮣; 쮣; ) HANGUL SYLLABLE JJWID
+CBA4;CBA4;110D 1171 11AF;CBA4;110D 1171 11AF; # (쮤; 쮤; 쮤; 쮤; 쮤; ) HANGUL SYLLABLE JJWIL
+CBA5;CBA5;110D 1171 11B0;CBA5;110D 1171 11B0; # (쮥; 쮥; 쮥; 쮥; 쮥; ) HANGUL SYLLABLE JJWILG
+CBA6;CBA6;110D 1171 11B1;CBA6;110D 1171 11B1; # (쮦; 쮦; 쮦; 쮦; 쮦; ) HANGUL SYLLABLE JJWILM
+CBA7;CBA7;110D 1171 11B2;CBA7;110D 1171 11B2; # (쮧; 쮧; 쮧; 쮧; 쮧; ) HANGUL SYLLABLE JJWILB
+CBA8;CBA8;110D 1171 11B3;CBA8;110D 1171 11B3; # (쮨; 쮨; 쮨; 쮨; 쮨; ) HANGUL SYLLABLE JJWILS
+CBA9;CBA9;110D 1171 11B4;CBA9;110D 1171 11B4; # (쮩; 쮩; 쮩; 쮩; 쮩; ) HANGUL SYLLABLE JJWILT
+CBAA;CBAA;110D 1171 11B5;CBAA;110D 1171 11B5; # (쮪; 쮪; 쮪; 쮪; 쮪; ) HANGUL SYLLABLE JJWILP
+CBAB;CBAB;110D 1171 11B6;CBAB;110D 1171 11B6; # (쮫; 쮫; 쮫; 쮫; 쮫; ) HANGUL SYLLABLE JJWILH
+CBAC;CBAC;110D 1171 11B7;CBAC;110D 1171 11B7; # (쮬; 쮬; 쮬; 쮬; 쮬; ) HANGUL SYLLABLE JJWIM
+CBAD;CBAD;110D 1171 11B8;CBAD;110D 1171 11B8; # (쮭; 쮭; 쮭; 쮭; 쮭; ) HANGUL SYLLABLE JJWIB
+CBAE;CBAE;110D 1171 11B9;CBAE;110D 1171 11B9; # (쮮; 쮮; 쮮; 쮮; 쮮; ) HANGUL SYLLABLE JJWIBS
+CBAF;CBAF;110D 1171 11BA;CBAF;110D 1171 11BA; # (쮯; 쮯; 쮯; 쮯; 쮯; ) HANGUL SYLLABLE JJWIS
+CBB0;CBB0;110D 1171 11BB;CBB0;110D 1171 11BB; # (쮰; 쮰; 쮰; 쮰; 쮰; ) HANGUL SYLLABLE JJWISS
+CBB1;CBB1;110D 1171 11BC;CBB1;110D 1171 11BC; # (쮱; 쮱; 쮱; 쮱; 쮱; ) HANGUL SYLLABLE JJWING
+CBB2;CBB2;110D 1171 11BD;CBB2;110D 1171 11BD; # (쮲; 쮲; 쮲; 쮲; 쮲; ) HANGUL SYLLABLE JJWIJ
+CBB3;CBB3;110D 1171 11BE;CBB3;110D 1171 11BE; # (쮳; 쮳; 쮳; 쮳; 쮳; ) HANGUL SYLLABLE JJWIC
+CBB4;CBB4;110D 1171 11BF;CBB4;110D 1171 11BF; # (쮴; 쮴; 쮴; 쮴; 쮴; ) HANGUL SYLLABLE JJWIK
+CBB5;CBB5;110D 1171 11C0;CBB5;110D 1171 11C0; # (쮵; 쮵; 쮵; 쮵; 쮵; ) HANGUL SYLLABLE JJWIT
+CBB6;CBB6;110D 1171 11C1;CBB6;110D 1171 11C1; # (쮶; 쮶; 쮶; 쮶; 쮶; ) HANGUL SYLLABLE JJWIP
+CBB7;CBB7;110D 1171 11C2;CBB7;110D 1171 11C2; # (쮷; 쮷; 쮷; 쮷; 쮷; ) HANGUL SYLLABLE JJWIH
+CBB8;CBB8;110D 1172;CBB8;110D 1172; # (쮸; 쮸; 쮸; 쮸; 쮸; ) HANGUL SYLLABLE JJYU
+CBB9;CBB9;110D 1172 11A8;CBB9;110D 1172 11A8; # (쮹; 쮹; 쮹; 쮹; 쮹; ) HANGUL SYLLABLE JJYUG
+CBBA;CBBA;110D 1172 11A9;CBBA;110D 1172 11A9; # (쮺; 쮺; 쮺; 쮺; 쮺; ) HANGUL SYLLABLE JJYUGG
+CBBB;CBBB;110D 1172 11AA;CBBB;110D 1172 11AA; # (쮻; 쮻; 쮻; 쮻; 쮻; ) HANGUL SYLLABLE JJYUGS
+CBBC;CBBC;110D 1172 11AB;CBBC;110D 1172 11AB; # (쮼; 쮼; 쮼; 쮼; 쮼; ) HANGUL SYLLABLE JJYUN
+CBBD;CBBD;110D 1172 11AC;CBBD;110D 1172 11AC; # (쮽; 쮽; 쮽; 쮽; 쮽; ) HANGUL SYLLABLE JJYUNJ
+CBBE;CBBE;110D 1172 11AD;CBBE;110D 1172 11AD; # (쮾; 쮾; 쮾; 쮾; 쮾; ) HANGUL SYLLABLE JJYUNH
+CBBF;CBBF;110D 1172 11AE;CBBF;110D 1172 11AE; # (쮿; 쮿; 쮿; 쮿; 쮿; ) HANGUL SYLLABLE JJYUD
+CBC0;CBC0;110D 1172 11AF;CBC0;110D 1172 11AF; # (쯀; 쯀; 쯀; 쯀; 쯀; ) HANGUL SYLLABLE JJYUL
+CBC1;CBC1;110D 1172 11B0;CBC1;110D 1172 11B0; # (쯁; 쯁; 쯁; 쯁; 쯁; ) HANGUL SYLLABLE JJYULG
+CBC2;CBC2;110D 1172 11B1;CBC2;110D 1172 11B1; # (쯂; 쯂; 쯂; 쯂; 쯂; ) HANGUL SYLLABLE JJYULM
+CBC3;CBC3;110D 1172 11B2;CBC3;110D 1172 11B2; # (쯃; 쯃; 쯃; 쯃; 쯃; ) HANGUL SYLLABLE JJYULB
+CBC4;CBC4;110D 1172 11B3;CBC4;110D 1172 11B3; # (쯄; 쯄; 쯄; 쯄; 쯄; ) HANGUL SYLLABLE JJYULS
+CBC5;CBC5;110D 1172 11B4;CBC5;110D 1172 11B4; # (쯅; 쯅; 쯅; 쯅; 쯅; ) HANGUL SYLLABLE JJYULT
+CBC6;CBC6;110D 1172 11B5;CBC6;110D 1172 11B5; # (쯆; 쯆; 쯆; 쯆; 쯆; ) HANGUL SYLLABLE JJYULP
+CBC7;CBC7;110D 1172 11B6;CBC7;110D 1172 11B6; # (쯇; 쯇; 쯇; 쯇; 쯇; ) HANGUL SYLLABLE JJYULH
+CBC8;CBC8;110D 1172 11B7;CBC8;110D 1172 11B7; # (쯈; 쯈; 쯈; 쯈; 쯈; ) HANGUL SYLLABLE JJYUM
+CBC9;CBC9;110D 1172 11B8;CBC9;110D 1172 11B8; # (쯉; 쯉; 쯉; 쯉; 쯉; ) HANGUL SYLLABLE JJYUB
+CBCA;CBCA;110D 1172 11B9;CBCA;110D 1172 11B9; # (쯊; 쯊; 쯊; 쯊; 쯊; ) HANGUL SYLLABLE JJYUBS
+CBCB;CBCB;110D 1172 11BA;CBCB;110D 1172 11BA; # (쯋; 쯋; 쯋; 쯋; 쯋; ) HANGUL SYLLABLE JJYUS
+CBCC;CBCC;110D 1172 11BB;CBCC;110D 1172 11BB; # (쯌; 쯌; 쯌; 쯌; 쯌; ) HANGUL SYLLABLE JJYUSS
+CBCD;CBCD;110D 1172 11BC;CBCD;110D 1172 11BC; # (쯍; 쯍; 쯍; 쯍; 쯍; ) HANGUL SYLLABLE JJYUNG
+CBCE;CBCE;110D 1172 11BD;CBCE;110D 1172 11BD; # (쯎; 쯎; 쯎; 쯎; 쯎; ) HANGUL SYLLABLE JJYUJ
+CBCF;CBCF;110D 1172 11BE;CBCF;110D 1172 11BE; # (쯏; 쯏; 쯏; 쯏; 쯏; ) HANGUL SYLLABLE JJYUC
+CBD0;CBD0;110D 1172 11BF;CBD0;110D 1172 11BF; # (쯐; 쯐; 쯐; 쯐; 쯐; ) HANGUL SYLLABLE JJYUK
+CBD1;CBD1;110D 1172 11C0;CBD1;110D 1172 11C0; # (쯑; 쯑; 쯑; 쯑; 쯑; ) HANGUL SYLLABLE JJYUT
+CBD2;CBD2;110D 1172 11C1;CBD2;110D 1172 11C1; # (쯒; 쯒; 쯒; 쯒; 쯒; ) HANGUL SYLLABLE JJYUP
+CBD3;CBD3;110D 1172 11C2;CBD3;110D 1172 11C2; # (쯓; 쯓; 쯓; 쯓; 쯓; ) HANGUL SYLLABLE JJYUH
+CBD4;CBD4;110D 1173;CBD4;110D 1173; # (쯔; 쯔; 쯔; 쯔; 쯔; ) HANGUL SYLLABLE JJEU
+CBD5;CBD5;110D 1173 11A8;CBD5;110D 1173 11A8; # (쯕; 쯕; 쯕; 쯕; 쯕; ) HANGUL SYLLABLE JJEUG
+CBD6;CBD6;110D 1173 11A9;CBD6;110D 1173 11A9; # (쯖; 쯖; 쯖; 쯖; 쯖; ) HANGUL SYLLABLE JJEUGG
+CBD7;CBD7;110D 1173 11AA;CBD7;110D 1173 11AA; # (쯗; 쯗; 쯗; 쯗; 쯗; ) HANGUL SYLLABLE JJEUGS
+CBD8;CBD8;110D 1173 11AB;CBD8;110D 1173 11AB; # (쯘; 쯘; 쯘; 쯘; 쯘; ) HANGUL SYLLABLE JJEUN
+CBD9;CBD9;110D 1173 11AC;CBD9;110D 1173 11AC; # (쯙; 쯙; 쯙; 쯙; 쯙; ) HANGUL SYLLABLE JJEUNJ
+CBDA;CBDA;110D 1173 11AD;CBDA;110D 1173 11AD; # (쯚; 쯚; 쯚; 쯚; 쯚; ) HANGUL SYLLABLE JJEUNH
+CBDB;CBDB;110D 1173 11AE;CBDB;110D 1173 11AE; # (쯛; 쯛; 쯛; 쯛; 쯛; ) HANGUL SYLLABLE JJEUD
+CBDC;CBDC;110D 1173 11AF;CBDC;110D 1173 11AF; # (쯜; 쯜; 쯜; 쯜; 쯜; ) HANGUL SYLLABLE JJEUL
+CBDD;CBDD;110D 1173 11B0;CBDD;110D 1173 11B0; # (쯝; 쯝; 쯝; 쯝; 쯝; ) HANGUL SYLLABLE JJEULG
+CBDE;CBDE;110D 1173 11B1;CBDE;110D 1173 11B1; # (쯞; 쯞; 쯞; 쯞; 쯞; ) HANGUL SYLLABLE JJEULM
+CBDF;CBDF;110D 1173 11B2;CBDF;110D 1173 11B2; # (쯟; 쯟; 쯟; 쯟; 쯟; ) HANGUL SYLLABLE JJEULB
+CBE0;CBE0;110D 1173 11B3;CBE0;110D 1173 11B3; # (쯠; 쯠; 쯠; 쯠; 쯠; ) HANGUL SYLLABLE JJEULS
+CBE1;CBE1;110D 1173 11B4;CBE1;110D 1173 11B4; # (쯡; 쯡; 쯡; 쯡; 쯡; ) HANGUL SYLLABLE JJEULT
+CBE2;CBE2;110D 1173 11B5;CBE2;110D 1173 11B5; # (쯢; 쯢; 쯢; 쯢; 쯢; ) HANGUL SYLLABLE JJEULP
+CBE3;CBE3;110D 1173 11B6;CBE3;110D 1173 11B6; # (쯣; 쯣; 쯣; 쯣; 쯣; ) HANGUL SYLLABLE JJEULH
+CBE4;CBE4;110D 1173 11B7;CBE4;110D 1173 11B7; # (쯤; 쯤; 쯤; 쯤; 쯤; ) HANGUL SYLLABLE JJEUM
+CBE5;CBE5;110D 1173 11B8;CBE5;110D 1173 11B8; # (쯥; 쯥; 쯥; 쯥; 쯥; ) HANGUL SYLLABLE JJEUB
+CBE6;CBE6;110D 1173 11B9;CBE6;110D 1173 11B9; # (쯦; 쯦; 쯦; 쯦; 쯦; ) HANGUL SYLLABLE JJEUBS
+CBE7;CBE7;110D 1173 11BA;CBE7;110D 1173 11BA; # (쯧; 쯧; 쯧; 쯧; 쯧; ) HANGUL SYLLABLE JJEUS
+CBE8;CBE8;110D 1173 11BB;CBE8;110D 1173 11BB; # (쯨; 쯨; 쯨; 쯨; 쯨; ) HANGUL SYLLABLE JJEUSS
+CBE9;CBE9;110D 1173 11BC;CBE9;110D 1173 11BC; # (쯩; 쯩; 쯩; 쯩; 쯩; ) HANGUL SYLLABLE JJEUNG
+CBEA;CBEA;110D 1173 11BD;CBEA;110D 1173 11BD; # (쯪; 쯪; 쯪; 쯪; 쯪; ) HANGUL SYLLABLE JJEUJ
+CBEB;CBEB;110D 1173 11BE;CBEB;110D 1173 11BE; # (쯫; 쯫; 쯫; 쯫; 쯫; ) HANGUL SYLLABLE JJEUC
+CBEC;CBEC;110D 1173 11BF;CBEC;110D 1173 11BF; # (쯬; 쯬; 쯬; 쯬; 쯬; ) HANGUL SYLLABLE JJEUK
+CBED;CBED;110D 1173 11C0;CBED;110D 1173 11C0; # (쯭; 쯭; 쯭; 쯭; 쯭; ) HANGUL SYLLABLE JJEUT
+CBEE;CBEE;110D 1173 11C1;CBEE;110D 1173 11C1; # (쯮; 쯮; 쯮; 쯮; 쯮; ) HANGUL SYLLABLE JJEUP
+CBEF;CBEF;110D 1173 11C2;CBEF;110D 1173 11C2; # (쯯; 쯯; 쯯; 쯯; 쯯; ) HANGUL SYLLABLE JJEUH
+CBF0;CBF0;110D 1174;CBF0;110D 1174; # (쯰; 쯰; 쯰; 쯰; 쯰; ) HANGUL SYLLABLE JJYI
+CBF1;CBF1;110D 1174 11A8;CBF1;110D 1174 11A8; # (쯱; 쯱; 쯱; 쯱; 쯱; ) HANGUL SYLLABLE JJYIG
+CBF2;CBF2;110D 1174 11A9;CBF2;110D 1174 11A9; # (쯲; 쯲; 쯲; 쯲; 쯲; ) HANGUL SYLLABLE JJYIGG
+CBF3;CBF3;110D 1174 11AA;CBF3;110D 1174 11AA; # (쯳; 쯳; 쯳; 쯳; 쯳; ) HANGUL SYLLABLE JJYIGS
+CBF4;CBF4;110D 1174 11AB;CBF4;110D 1174 11AB; # (쯴; 쯴; 쯴; 쯴; 쯴; ) HANGUL SYLLABLE JJYIN
+CBF5;CBF5;110D 1174 11AC;CBF5;110D 1174 11AC; # (쯵; 쯵; 쯵; 쯵; 쯵; ) HANGUL SYLLABLE JJYINJ
+CBF6;CBF6;110D 1174 11AD;CBF6;110D 1174 11AD; # (쯶; 쯶; 쯶; 쯶; 쯶; ) HANGUL SYLLABLE JJYINH
+CBF7;CBF7;110D 1174 11AE;CBF7;110D 1174 11AE; # (쯷; 쯷; 쯷; 쯷; 쯷; ) HANGUL SYLLABLE JJYID
+CBF8;CBF8;110D 1174 11AF;CBF8;110D 1174 11AF; # (쯸; 쯸; 쯸; 쯸; 쯸; ) HANGUL SYLLABLE JJYIL
+CBF9;CBF9;110D 1174 11B0;CBF9;110D 1174 11B0; # (쯹; 쯹; 쯹; 쯹; 쯹; ) HANGUL SYLLABLE JJYILG
+CBFA;CBFA;110D 1174 11B1;CBFA;110D 1174 11B1; # (쯺; 쯺; 쯺; 쯺; 쯺; ) HANGUL SYLLABLE JJYILM
+CBFB;CBFB;110D 1174 11B2;CBFB;110D 1174 11B2; # (쯻; 쯻; 쯻; 쯻; 쯻; ) HANGUL SYLLABLE JJYILB
+CBFC;CBFC;110D 1174 11B3;CBFC;110D 1174 11B3; # (쯼; 쯼; 쯼; 쯼; 쯼; ) HANGUL SYLLABLE JJYILS
+CBFD;CBFD;110D 1174 11B4;CBFD;110D 1174 11B4; # (쯽; 쯽; 쯽; 쯽; 쯽; ) HANGUL SYLLABLE JJYILT
+CBFE;CBFE;110D 1174 11B5;CBFE;110D 1174 11B5; # (쯾; 쯾; 쯾; 쯾; 쯾; ) HANGUL SYLLABLE JJYILP
+CBFF;CBFF;110D 1174 11B6;CBFF;110D 1174 11B6; # (쯿; 쯿; 쯿; 쯿; 쯿; ) HANGUL SYLLABLE JJYILH
+CC00;CC00;110D 1174 11B7;CC00;110D 1174 11B7; # (찀; 찀; 찀; 찀; 찀; ) HANGUL SYLLABLE JJYIM
+CC01;CC01;110D 1174 11B8;CC01;110D 1174 11B8; # (찁; 찁; 찁; 찁; 찁; ) HANGUL SYLLABLE JJYIB
+CC02;CC02;110D 1174 11B9;CC02;110D 1174 11B9; # (찂; 찂; 찂; 찂; 찂; ) HANGUL SYLLABLE JJYIBS
+CC03;CC03;110D 1174 11BA;CC03;110D 1174 11BA; # (찃; 찃; 찃; 찃; 찃; ) HANGUL SYLLABLE JJYIS
+CC04;CC04;110D 1174 11BB;CC04;110D 1174 11BB; # (찄; 찄; 찄; 찄; 찄; ) HANGUL SYLLABLE JJYISS
+CC05;CC05;110D 1174 11BC;CC05;110D 1174 11BC; # (찅; 찅; 찅; 찅; 찅; ) HANGUL SYLLABLE JJYING
+CC06;CC06;110D 1174 11BD;CC06;110D 1174 11BD; # (찆; 찆; 찆; 찆; 찆; ) HANGUL SYLLABLE JJYIJ
+CC07;CC07;110D 1174 11BE;CC07;110D 1174 11BE; # (찇; 찇; 찇; 찇; 찇; ) HANGUL SYLLABLE JJYIC
+CC08;CC08;110D 1174 11BF;CC08;110D 1174 11BF; # (찈; 찈; 찈; 찈; 찈; ) HANGUL SYLLABLE JJYIK
+CC09;CC09;110D 1174 11C0;CC09;110D 1174 11C0; # (찉; 찉; 찉; 찉; 찉; ) HANGUL SYLLABLE JJYIT
+CC0A;CC0A;110D 1174 11C1;CC0A;110D 1174 11C1; # (찊; 찊; 찊; 찊; 찊; ) HANGUL SYLLABLE JJYIP
+CC0B;CC0B;110D 1174 11C2;CC0B;110D 1174 11C2; # (찋; 찋; 찋; 찋; 찋; ) HANGUL SYLLABLE JJYIH
+CC0C;CC0C;110D 1175;CC0C;110D 1175; # (찌; 찌; 찌; 찌; 찌; ) HANGUL SYLLABLE JJI
+CC0D;CC0D;110D 1175 11A8;CC0D;110D 1175 11A8; # (찍; 찍; 찍; 찍; 찍; ) HANGUL SYLLABLE JJIG
+CC0E;CC0E;110D 1175 11A9;CC0E;110D 1175 11A9; # (찎; 찎; 찎; 찎; 찎; ) HANGUL SYLLABLE JJIGG
+CC0F;CC0F;110D 1175 11AA;CC0F;110D 1175 11AA; # (찏; 찏; 찏; 찏; 찏; ) HANGUL SYLLABLE JJIGS
+CC10;CC10;110D 1175 11AB;CC10;110D 1175 11AB; # (찐; 찐; 찐; 찐; 찐; ) HANGUL SYLLABLE JJIN
+CC11;CC11;110D 1175 11AC;CC11;110D 1175 11AC; # (찑; 찑; 찑; 찑; 찑; ) HANGUL SYLLABLE JJINJ
+CC12;CC12;110D 1175 11AD;CC12;110D 1175 11AD; # (찒; 찒; 찒; 찒; 찒; ) HANGUL SYLLABLE JJINH
+CC13;CC13;110D 1175 11AE;CC13;110D 1175 11AE; # (찓; 찓; 찓; 찓; 찓; ) HANGUL SYLLABLE JJID
+CC14;CC14;110D 1175 11AF;CC14;110D 1175 11AF; # (찔; 찔; 찔; 찔; 찔; ) HANGUL SYLLABLE JJIL
+CC15;CC15;110D 1175 11B0;CC15;110D 1175 11B0; # (찕; 찕; 찕; 찕; 찕; ) HANGUL SYLLABLE JJILG
+CC16;CC16;110D 1175 11B1;CC16;110D 1175 11B1; # (찖; 찖; 찖; 찖; 찖; ) HANGUL SYLLABLE JJILM
+CC17;CC17;110D 1175 11B2;CC17;110D 1175 11B2; # (찗; 찗; 찗; 찗; 찗; ) HANGUL SYLLABLE JJILB
+CC18;CC18;110D 1175 11B3;CC18;110D 1175 11B3; # (찘; 찘; 찘; 찘; 찘; ) HANGUL SYLLABLE JJILS
+CC19;CC19;110D 1175 11B4;CC19;110D 1175 11B4; # (찙; 찙; 찙; 찙; 찙; ) HANGUL SYLLABLE JJILT
+CC1A;CC1A;110D 1175 11B5;CC1A;110D 1175 11B5; # (찚; 찚; 찚; 찚; 찚; ) HANGUL SYLLABLE JJILP
+CC1B;CC1B;110D 1175 11B6;CC1B;110D 1175 11B6; # (찛; 찛; 찛; 찛; 찛; ) HANGUL SYLLABLE JJILH
+CC1C;CC1C;110D 1175 11B7;CC1C;110D 1175 11B7; # (찜; 찜; 찜; 찜; 찜; ) HANGUL SYLLABLE JJIM
+CC1D;CC1D;110D 1175 11B8;CC1D;110D 1175 11B8; # (찝; 찝; 찝; 찝; 찝; ) HANGUL SYLLABLE JJIB
+CC1E;CC1E;110D 1175 11B9;CC1E;110D 1175 11B9; # (찞; 찞; 찞; 찞; 찞; ) HANGUL SYLLABLE JJIBS
+CC1F;CC1F;110D 1175 11BA;CC1F;110D 1175 11BA; # (찟; 찟; 찟; 찟; 찟; ) HANGUL SYLLABLE JJIS
+CC20;CC20;110D 1175 11BB;CC20;110D 1175 11BB; # (찠; 찠; 찠; 찠; 찠; ) HANGUL SYLLABLE JJISS
+CC21;CC21;110D 1175 11BC;CC21;110D 1175 11BC; # (찡; 찡; 찡; 찡; 찡; ) HANGUL SYLLABLE JJING
+CC22;CC22;110D 1175 11BD;CC22;110D 1175 11BD; # (찢; 찢; 찢; 찢; 찢; ) HANGUL SYLLABLE JJIJ
+CC23;CC23;110D 1175 11BE;CC23;110D 1175 11BE; # (찣; 찣; 찣; 찣; 찣; ) HANGUL SYLLABLE JJIC
+CC24;CC24;110D 1175 11BF;CC24;110D 1175 11BF; # (찤; 찤; 찤; 찤; 찤; ) HANGUL SYLLABLE JJIK
+CC25;CC25;110D 1175 11C0;CC25;110D 1175 11C0; # (찥; 찥; 찥; 찥; 찥; ) HANGUL SYLLABLE JJIT
+CC26;CC26;110D 1175 11C1;CC26;110D 1175 11C1; # (찦; 찦; 찦; 찦; 찦; ) HANGUL SYLLABLE JJIP
+CC27;CC27;110D 1175 11C2;CC27;110D 1175 11C2; # (찧; 찧; 찧; 찧; 찧; ) HANGUL SYLLABLE JJIH
+CC28;CC28;110E 1161;CC28;110E 1161; # (차; 차; 차; 차; 차; ) HANGUL SYLLABLE CA
+CC29;CC29;110E 1161 11A8;CC29;110E 1161 11A8; # (착; 착; 착; 착; 착; ) HANGUL SYLLABLE CAG
+CC2A;CC2A;110E 1161 11A9;CC2A;110E 1161 11A9; # (찪; 찪; 찪; 찪; 찪; ) HANGUL SYLLABLE CAGG
+CC2B;CC2B;110E 1161 11AA;CC2B;110E 1161 11AA; # (찫; 찫; 찫; 찫; 찫; ) HANGUL SYLLABLE CAGS
+CC2C;CC2C;110E 1161 11AB;CC2C;110E 1161 11AB; # (찬; 찬; 찬; 찬; 찬; ) HANGUL SYLLABLE CAN
+CC2D;CC2D;110E 1161 11AC;CC2D;110E 1161 11AC; # (찭; 찭; 찭; 찭; 찭; ) HANGUL SYLLABLE CANJ
+CC2E;CC2E;110E 1161 11AD;CC2E;110E 1161 11AD; # (찮; 찮; 찮; 찮; 찮; ) HANGUL SYLLABLE CANH
+CC2F;CC2F;110E 1161 11AE;CC2F;110E 1161 11AE; # (찯; 찯; 찯; 찯; 찯; ) HANGUL SYLLABLE CAD
+CC30;CC30;110E 1161 11AF;CC30;110E 1161 11AF; # (찰; 찰; 찰; 찰; 찰; ) HANGUL SYLLABLE CAL
+CC31;CC31;110E 1161 11B0;CC31;110E 1161 11B0; # (찱; 찱; 찱; 찱; 찱; ) HANGUL SYLLABLE CALG
+CC32;CC32;110E 1161 11B1;CC32;110E 1161 11B1; # (찲; 찲; 찲; 찲; 찲; ) HANGUL SYLLABLE CALM
+CC33;CC33;110E 1161 11B2;CC33;110E 1161 11B2; # (찳; 찳; 찳; 찳; 찳; ) HANGUL SYLLABLE CALB
+CC34;CC34;110E 1161 11B3;CC34;110E 1161 11B3; # (찴; 찴; 찴; 찴; 찴; ) HANGUL SYLLABLE CALS
+CC35;CC35;110E 1161 11B4;CC35;110E 1161 11B4; # (찵; 찵; 찵; 찵; 찵; ) HANGUL SYLLABLE CALT
+CC36;CC36;110E 1161 11B5;CC36;110E 1161 11B5; # (찶; 찶; 찶; 찶; 찶; ) HANGUL SYLLABLE CALP
+CC37;CC37;110E 1161 11B6;CC37;110E 1161 11B6; # (찷; 찷; 찷; 찷; 찷; ) HANGUL SYLLABLE CALH
+CC38;CC38;110E 1161 11B7;CC38;110E 1161 11B7; # (참; 참; 참; 참; 참; ) HANGUL SYLLABLE CAM
+CC39;CC39;110E 1161 11B8;CC39;110E 1161 11B8; # (찹; 찹; 찹; 찹; 찹; ) HANGUL SYLLABLE CAB
+CC3A;CC3A;110E 1161 11B9;CC3A;110E 1161 11B9; # (찺; 찺; 찺; 찺; 찺; ) HANGUL SYLLABLE CABS
+CC3B;CC3B;110E 1161 11BA;CC3B;110E 1161 11BA; # (찻; 찻; 찻; 찻; 찻; ) HANGUL SYLLABLE CAS
+CC3C;CC3C;110E 1161 11BB;CC3C;110E 1161 11BB; # (찼; 찼; 찼; 찼; 찼; ) HANGUL SYLLABLE CASS
+CC3D;CC3D;110E 1161 11BC;CC3D;110E 1161 11BC; # (창; 창; 창; 창; 창; ) HANGUL SYLLABLE CANG
+CC3E;CC3E;110E 1161 11BD;CC3E;110E 1161 11BD; # (찾; 찾; 찾; 찾; 찾; ) HANGUL SYLLABLE CAJ
+CC3F;CC3F;110E 1161 11BE;CC3F;110E 1161 11BE; # (찿; 찿; 찿; 찿; 찿; ) HANGUL SYLLABLE CAC
+CC40;CC40;110E 1161 11BF;CC40;110E 1161 11BF; # (챀; 챀; 챀; 챀; 챀; ) HANGUL SYLLABLE CAK
+CC41;CC41;110E 1161 11C0;CC41;110E 1161 11C0; # (챁; 챁; 챁; 챁; 챁; ) HANGUL SYLLABLE CAT
+CC42;CC42;110E 1161 11C1;CC42;110E 1161 11C1; # (챂; 챂; 챂; 챂; 챂; ) HANGUL SYLLABLE CAP
+CC43;CC43;110E 1161 11C2;CC43;110E 1161 11C2; # (챃; 챃; 챃; 챃; 챃; ) HANGUL SYLLABLE CAH
+CC44;CC44;110E 1162;CC44;110E 1162; # (채; 채; 채; 채; 채; ) HANGUL SYLLABLE CAE
+CC45;CC45;110E 1162 11A8;CC45;110E 1162 11A8; # (책; 책; 책; 책; 책; ) HANGUL SYLLABLE CAEG
+CC46;CC46;110E 1162 11A9;CC46;110E 1162 11A9; # (챆; 챆; 챆; 챆; 챆; ) HANGUL SYLLABLE CAEGG
+CC47;CC47;110E 1162 11AA;CC47;110E 1162 11AA; # (챇; 챇; 챇; 챇; 챇; ) HANGUL SYLLABLE CAEGS
+CC48;CC48;110E 1162 11AB;CC48;110E 1162 11AB; # (챈; 챈; 챈; 챈; 챈; ) HANGUL SYLLABLE CAEN
+CC49;CC49;110E 1162 11AC;CC49;110E 1162 11AC; # (챉; 챉; 챉; 챉; 챉; ) HANGUL SYLLABLE CAENJ
+CC4A;CC4A;110E 1162 11AD;CC4A;110E 1162 11AD; # (챊; 챊; 챊; 챊; 챊; ) HANGUL SYLLABLE CAENH
+CC4B;CC4B;110E 1162 11AE;CC4B;110E 1162 11AE; # (챋; 챋; 챋; 챋; 챋; ) HANGUL SYLLABLE CAED
+CC4C;CC4C;110E 1162 11AF;CC4C;110E 1162 11AF; # (챌; 챌; 챌; 챌; 챌; ) HANGUL SYLLABLE CAEL
+CC4D;CC4D;110E 1162 11B0;CC4D;110E 1162 11B0; # (챍; 챍; 챍; 챍; 챍; ) HANGUL SYLLABLE CAELG
+CC4E;CC4E;110E 1162 11B1;CC4E;110E 1162 11B1; # (챎; 챎; 챎; 챎; 챎; ) HANGUL SYLLABLE CAELM
+CC4F;CC4F;110E 1162 11B2;CC4F;110E 1162 11B2; # (챏; 챏; 챏; 챏; 챏; ) HANGUL SYLLABLE CAELB
+CC50;CC50;110E 1162 11B3;CC50;110E 1162 11B3; # (챐; 챐; 챐; 챐; 챐; ) HANGUL SYLLABLE CAELS
+CC51;CC51;110E 1162 11B4;CC51;110E 1162 11B4; # (챑; 챑; 챑; 챑; 챑; ) HANGUL SYLLABLE CAELT
+CC52;CC52;110E 1162 11B5;CC52;110E 1162 11B5; # (챒; 챒; 챒; 챒; 챒; ) HANGUL SYLLABLE CAELP
+CC53;CC53;110E 1162 11B6;CC53;110E 1162 11B6; # (챓; 챓; 챓; 챓; 챓; ) HANGUL SYLLABLE CAELH
+CC54;CC54;110E 1162 11B7;CC54;110E 1162 11B7; # (챔; 챔; 챔; 챔; 챔; ) HANGUL SYLLABLE CAEM
+CC55;CC55;110E 1162 11B8;CC55;110E 1162 11B8; # (챕; 챕; 챕; 챕; 챕; ) HANGUL SYLLABLE CAEB
+CC56;CC56;110E 1162 11B9;CC56;110E 1162 11B9; # (챖; 챖; 챖; 챖; 챖; ) HANGUL SYLLABLE CAEBS
+CC57;CC57;110E 1162 11BA;CC57;110E 1162 11BA; # (챗; 챗; 챗; 챗; 챗; ) HANGUL SYLLABLE CAES
+CC58;CC58;110E 1162 11BB;CC58;110E 1162 11BB; # (챘; 챘; 챘; 챘; 챘; ) HANGUL SYLLABLE CAESS
+CC59;CC59;110E 1162 11BC;CC59;110E 1162 11BC; # (챙; 챙; 챙; 챙; 챙; ) HANGUL SYLLABLE CAENG
+CC5A;CC5A;110E 1162 11BD;CC5A;110E 1162 11BD; # (챚; 챚; 챚; 챚; 챚; ) HANGUL SYLLABLE CAEJ
+CC5B;CC5B;110E 1162 11BE;CC5B;110E 1162 11BE; # (챛; 챛; 챛; 챛; 챛; ) HANGUL SYLLABLE CAEC
+CC5C;CC5C;110E 1162 11BF;CC5C;110E 1162 11BF; # (챜; 챜; 챜; 챜; 챜; ) HANGUL SYLLABLE CAEK
+CC5D;CC5D;110E 1162 11C0;CC5D;110E 1162 11C0; # (챝; 챝; 챝; 챝; 챝; ) HANGUL SYLLABLE CAET
+CC5E;CC5E;110E 1162 11C1;CC5E;110E 1162 11C1; # (챞; 챞; 챞; 챞; 챞; ) HANGUL SYLLABLE CAEP
+CC5F;CC5F;110E 1162 11C2;CC5F;110E 1162 11C2; # (챟; 챟; 챟; 챟; 챟; ) HANGUL SYLLABLE CAEH
+CC60;CC60;110E 1163;CC60;110E 1163; # (챠; 챠; 챠; 챠; 챠; ) HANGUL SYLLABLE CYA
+CC61;CC61;110E 1163 11A8;CC61;110E 1163 11A8; # (챡; 챡; 챡; 챡; 챡; ) HANGUL SYLLABLE CYAG
+CC62;CC62;110E 1163 11A9;CC62;110E 1163 11A9; # (챢; 챢; 챢; 챢; 챢; ) HANGUL SYLLABLE CYAGG
+CC63;CC63;110E 1163 11AA;CC63;110E 1163 11AA; # (챣; 챣; 챣; 챣; 챣; ) HANGUL SYLLABLE CYAGS
+CC64;CC64;110E 1163 11AB;CC64;110E 1163 11AB; # (챤; 챤; 챤; 챤; 챤; ) HANGUL SYLLABLE CYAN
+CC65;CC65;110E 1163 11AC;CC65;110E 1163 11AC; # (챥; 챥; 챥; 챥; 챥; ) HANGUL SYLLABLE CYANJ
+CC66;CC66;110E 1163 11AD;CC66;110E 1163 11AD; # (챦; 챦; 챦; 챦; 챦; ) HANGUL SYLLABLE CYANH
+CC67;CC67;110E 1163 11AE;CC67;110E 1163 11AE; # (챧; 챧; 챧; 챧; 챧; ) HANGUL SYLLABLE CYAD
+CC68;CC68;110E 1163 11AF;CC68;110E 1163 11AF; # (챨; 챨; 챨; 챨; 챨; ) HANGUL SYLLABLE CYAL
+CC69;CC69;110E 1163 11B0;CC69;110E 1163 11B0; # (챩; 챩; 챩; 챩; 챩; ) HANGUL SYLLABLE CYALG
+CC6A;CC6A;110E 1163 11B1;CC6A;110E 1163 11B1; # (챪; 챪; 챪; 챪; 챪; ) HANGUL SYLLABLE CYALM
+CC6B;CC6B;110E 1163 11B2;CC6B;110E 1163 11B2; # (챫; 챫; 챫; 챫; 챫; ) HANGUL SYLLABLE CYALB
+CC6C;CC6C;110E 1163 11B3;CC6C;110E 1163 11B3; # (챬; 챬; 챬; 챬; 챬; ) HANGUL SYLLABLE CYALS
+CC6D;CC6D;110E 1163 11B4;CC6D;110E 1163 11B4; # (챭; 챭; 챭; 챭; 챭; ) HANGUL SYLLABLE CYALT
+CC6E;CC6E;110E 1163 11B5;CC6E;110E 1163 11B5; # (챮; 챮; 챮; 챮; 챮; ) HANGUL SYLLABLE CYALP
+CC6F;CC6F;110E 1163 11B6;CC6F;110E 1163 11B6; # (챯; 챯; 챯; 챯; 챯; ) HANGUL SYLLABLE CYALH
+CC70;CC70;110E 1163 11B7;CC70;110E 1163 11B7; # (챰; 챰; 챰; 챰; 챰; ) HANGUL SYLLABLE CYAM
+CC71;CC71;110E 1163 11B8;CC71;110E 1163 11B8; # (챱; 챱; 챱; 챱; 챱; ) HANGUL SYLLABLE CYAB
+CC72;CC72;110E 1163 11B9;CC72;110E 1163 11B9; # (챲; 챲; 챲; 챲; 챲; ) HANGUL SYLLABLE CYABS
+CC73;CC73;110E 1163 11BA;CC73;110E 1163 11BA; # (챳; 챳; 챳; 챳; 챳; ) HANGUL SYLLABLE CYAS
+CC74;CC74;110E 1163 11BB;CC74;110E 1163 11BB; # (챴; 챴; 챴; 챴; 챴; ) HANGUL SYLLABLE CYASS
+CC75;CC75;110E 1163 11BC;CC75;110E 1163 11BC; # (챵; 챵; 챵; 챵; 챵; ) HANGUL SYLLABLE CYANG
+CC76;CC76;110E 1163 11BD;CC76;110E 1163 11BD; # (챶; 챶; 챶; 챶; 챶; ) HANGUL SYLLABLE CYAJ
+CC77;CC77;110E 1163 11BE;CC77;110E 1163 11BE; # (챷; 챷; 챷; 챷; 챷; ) HANGUL SYLLABLE CYAC
+CC78;CC78;110E 1163 11BF;CC78;110E 1163 11BF; # (챸; 챸; 챸; 챸; 챸; ) HANGUL SYLLABLE CYAK
+CC79;CC79;110E 1163 11C0;CC79;110E 1163 11C0; # (챹; 챹; 챹; 챹; 챹; ) HANGUL SYLLABLE CYAT
+CC7A;CC7A;110E 1163 11C1;CC7A;110E 1163 11C1; # (챺; 챺; 챺; 챺; 챺; ) HANGUL SYLLABLE CYAP
+CC7B;CC7B;110E 1163 11C2;CC7B;110E 1163 11C2; # (챻; 챻; 챻; 챻; 챻; ) HANGUL SYLLABLE CYAH
+CC7C;CC7C;110E 1164;CC7C;110E 1164; # (챼; 챼; 챼; 챼; 챼; ) HANGUL SYLLABLE CYAE
+CC7D;CC7D;110E 1164 11A8;CC7D;110E 1164 11A8; # (챽; 챽; 챽; 챽; 챽; ) HANGUL SYLLABLE CYAEG
+CC7E;CC7E;110E 1164 11A9;CC7E;110E 1164 11A9; # (챾; 챾; 챾; 챾; 챾; ) HANGUL SYLLABLE CYAEGG
+CC7F;CC7F;110E 1164 11AA;CC7F;110E 1164 11AA; # (챿; 챿; 챿; 챿; 챿; ) HANGUL SYLLABLE CYAEGS
+CC80;CC80;110E 1164 11AB;CC80;110E 1164 11AB; # (첀; 첀; 첀; 첀; 첀; ) HANGUL SYLLABLE CYAEN
+CC81;CC81;110E 1164 11AC;CC81;110E 1164 11AC; # (첁; 첁; 첁; 첁; 첁; ) HANGUL SYLLABLE CYAENJ
+CC82;CC82;110E 1164 11AD;CC82;110E 1164 11AD; # (첂; 첂; 첂; 첂; 첂; ) HANGUL SYLLABLE CYAENH
+CC83;CC83;110E 1164 11AE;CC83;110E 1164 11AE; # (첃; 첃; 첃; 첃; 첃; ) HANGUL SYLLABLE CYAED
+CC84;CC84;110E 1164 11AF;CC84;110E 1164 11AF; # (첄; 첄; 첄; 첄; 첄; ) HANGUL SYLLABLE CYAEL
+CC85;CC85;110E 1164 11B0;CC85;110E 1164 11B0; # (첅; 첅; 첅; 첅; 첅; ) HANGUL SYLLABLE CYAELG
+CC86;CC86;110E 1164 11B1;CC86;110E 1164 11B1; # (첆; 첆; 첆; 첆; 첆; ) HANGUL SYLLABLE CYAELM
+CC87;CC87;110E 1164 11B2;CC87;110E 1164 11B2; # (첇; 첇; 첇; 첇; 첇; ) HANGUL SYLLABLE CYAELB
+CC88;CC88;110E 1164 11B3;CC88;110E 1164 11B3; # (첈; 첈; 첈; 첈; 첈; ) HANGUL SYLLABLE CYAELS
+CC89;CC89;110E 1164 11B4;CC89;110E 1164 11B4; # (첉; 첉; 첉; 첉; 첉; ) HANGUL SYLLABLE CYAELT
+CC8A;CC8A;110E 1164 11B5;CC8A;110E 1164 11B5; # (첊; 첊; 첊; 첊; 첊; ) HANGUL SYLLABLE CYAELP
+CC8B;CC8B;110E 1164 11B6;CC8B;110E 1164 11B6; # (첋; 첋; 첋; 첋; 첋; ) HANGUL SYLLABLE CYAELH
+CC8C;CC8C;110E 1164 11B7;CC8C;110E 1164 11B7; # (첌; 첌; 첌; 첌; 첌; ) HANGUL SYLLABLE CYAEM
+CC8D;CC8D;110E 1164 11B8;CC8D;110E 1164 11B8; # (첍; 첍; 첍; 첍; 첍; ) HANGUL SYLLABLE CYAEB
+CC8E;CC8E;110E 1164 11B9;CC8E;110E 1164 11B9; # (첎; 첎; 첎; 첎; 첎; ) HANGUL SYLLABLE CYAEBS
+CC8F;CC8F;110E 1164 11BA;CC8F;110E 1164 11BA; # (첏; 첏; 첏; 첏; 첏; ) HANGUL SYLLABLE CYAES
+CC90;CC90;110E 1164 11BB;CC90;110E 1164 11BB; # (첐; 첐; 첐; 첐; 첐; ) HANGUL SYLLABLE CYAESS
+CC91;CC91;110E 1164 11BC;CC91;110E 1164 11BC; # (첑; 첑; 첑; 첑; 첑; ) HANGUL SYLLABLE CYAENG
+CC92;CC92;110E 1164 11BD;CC92;110E 1164 11BD; # (첒; 첒; 첒; 첒; 첒; ) HANGUL SYLLABLE CYAEJ
+CC93;CC93;110E 1164 11BE;CC93;110E 1164 11BE; # (첓; 첓; 첓; 첓; 첓; ) HANGUL SYLLABLE CYAEC
+CC94;CC94;110E 1164 11BF;CC94;110E 1164 11BF; # (첔; 첔; 첔; 첔; 첔; ) HANGUL SYLLABLE CYAEK
+CC95;CC95;110E 1164 11C0;CC95;110E 1164 11C0; # (첕; 첕; 첕; 첕; 첕; ) HANGUL SYLLABLE CYAET
+CC96;CC96;110E 1164 11C1;CC96;110E 1164 11C1; # (첖; 첖; 첖; 첖; 첖; ) HANGUL SYLLABLE CYAEP
+CC97;CC97;110E 1164 11C2;CC97;110E 1164 11C2; # (첗; 첗; 첗; 첗; 첗; ) HANGUL SYLLABLE CYAEH
+CC98;CC98;110E 1165;CC98;110E 1165; # (처; 처; 처; 처; 처; ) HANGUL SYLLABLE CEO
+CC99;CC99;110E 1165 11A8;CC99;110E 1165 11A8; # (척; 척; 척; 척; 척; ) HANGUL SYLLABLE CEOG
+CC9A;CC9A;110E 1165 11A9;CC9A;110E 1165 11A9; # (첚; 첚; 첚; 첚; 첚; ) HANGUL SYLLABLE CEOGG
+CC9B;CC9B;110E 1165 11AA;CC9B;110E 1165 11AA; # (첛; 첛; 첛; 첛; 첛; ) HANGUL SYLLABLE CEOGS
+CC9C;CC9C;110E 1165 11AB;CC9C;110E 1165 11AB; # (천; 천; 천; 천; 천; ) HANGUL SYLLABLE CEON
+CC9D;CC9D;110E 1165 11AC;CC9D;110E 1165 11AC; # (첝; 첝; 첝; 첝; 첝; ) HANGUL SYLLABLE CEONJ
+CC9E;CC9E;110E 1165 11AD;CC9E;110E 1165 11AD; # (첞; 첞; 첞; 첞; 첞; ) HANGUL SYLLABLE CEONH
+CC9F;CC9F;110E 1165 11AE;CC9F;110E 1165 11AE; # (첟; 첟; 첟; 첟; 첟; ) HANGUL SYLLABLE CEOD
+CCA0;CCA0;110E 1165 11AF;CCA0;110E 1165 11AF; # (철; 철; 철; 철; 철; ) HANGUL SYLLABLE CEOL
+CCA1;CCA1;110E 1165 11B0;CCA1;110E 1165 11B0; # (첡; 첡; 첡; 첡; 첡; ) HANGUL SYLLABLE CEOLG
+CCA2;CCA2;110E 1165 11B1;CCA2;110E 1165 11B1; # (첢; 첢; 첢; 첢; 첢; ) HANGUL SYLLABLE CEOLM
+CCA3;CCA3;110E 1165 11B2;CCA3;110E 1165 11B2; # (첣; 첣; 첣; 첣; 첣; ) HANGUL SYLLABLE CEOLB
+CCA4;CCA4;110E 1165 11B3;CCA4;110E 1165 11B3; # (첤; 첤; 첤; 첤; 첤; ) HANGUL SYLLABLE CEOLS
+CCA5;CCA5;110E 1165 11B4;CCA5;110E 1165 11B4; # (첥; 첥; 첥; 첥; 첥; ) HANGUL SYLLABLE CEOLT
+CCA6;CCA6;110E 1165 11B5;CCA6;110E 1165 11B5; # (첦; 첦; 첦; 첦; 첦; ) HANGUL SYLLABLE CEOLP
+CCA7;CCA7;110E 1165 11B6;CCA7;110E 1165 11B6; # (첧; 첧; 첧; 첧; 첧; ) HANGUL SYLLABLE CEOLH
+CCA8;CCA8;110E 1165 11B7;CCA8;110E 1165 11B7; # (첨; 첨; 첨; 첨; 첨; ) HANGUL SYLLABLE CEOM
+CCA9;CCA9;110E 1165 11B8;CCA9;110E 1165 11B8; # (첩; 첩; 첩; 첩; 첩; ) HANGUL SYLLABLE CEOB
+CCAA;CCAA;110E 1165 11B9;CCAA;110E 1165 11B9; # (첪; 첪; 첪; 첪; 첪; ) HANGUL SYLLABLE CEOBS
+CCAB;CCAB;110E 1165 11BA;CCAB;110E 1165 11BA; # (첫; 첫; 첫; 첫; 첫; ) HANGUL SYLLABLE CEOS
+CCAC;CCAC;110E 1165 11BB;CCAC;110E 1165 11BB; # (첬; 첬; 첬; 첬; 첬; ) HANGUL SYLLABLE CEOSS
+CCAD;CCAD;110E 1165 11BC;CCAD;110E 1165 11BC; # (청; 청; 청; 청; 청; ) HANGUL SYLLABLE CEONG
+CCAE;CCAE;110E 1165 11BD;CCAE;110E 1165 11BD; # (첮; 첮; 첮; 첮; 첮; ) HANGUL SYLLABLE CEOJ
+CCAF;CCAF;110E 1165 11BE;CCAF;110E 1165 11BE; # (첯; 첯; 첯; 첯; 첯; ) HANGUL SYLLABLE CEOC
+CCB0;CCB0;110E 1165 11BF;CCB0;110E 1165 11BF; # (첰; 첰; 첰; 첰; 첰; ) HANGUL SYLLABLE CEOK
+CCB1;CCB1;110E 1165 11C0;CCB1;110E 1165 11C0; # (첱; 첱; 첱; 첱; 첱; ) HANGUL SYLLABLE CEOT
+CCB2;CCB2;110E 1165 11C1;CCB2;110E 1165 11C1; # (첲; 첲; 첲; 첲; 첲; ) HANGUL SYLLABLE CEOP
+CCB3;CCB3;110E 1165 11C2;CCB3;110E 1165 11C2; # (첳; 첳; 첳; 첳; 첳; ) HANGUL SYLLABLE CEOH
+CCB4;CCB4;110E 1166;CCB4;110E 1166; # (체; 체; 체; 체; 체; ) HANGUL SYLLABLE CE
+CCB5;CCB5;110E 1166 11A8;CCB5;110E 1166 11A8; # (첵; 첵; 첵; 첵; 첵; ) HANGUL SYLLABLE CEG
+CCB6;CCB6;110E 1166 11A9;CCB6;110E 1166 11A9; # (첶; 첶; 첶; 첶; 첶; ) HANGUL SYLLABLE CEGG
+CCB7;CCB7;110E 1166 11AA;CCB7;110E 1166 11AA; # (첷; 첷; 첷; 첷; 첷; ) HANGUL SYLLABLE CEGS
+CCB8;CCB8;110E 1166 11AB;CCB8;110E 1166 11AB; # (첸; 첸; 첸; 첸; 첸; ) HANGUL SYLLABLE CEN
+CCB9;CCB9;110E 1166 11AC;CCB9;110E 1166 11AC; # (첹; 첹; 첹; 첹; 첹; ) HANGUL SYLLABLE CENJ
+CCBA;CCBA;110E 1166 11AD;CCBA;110E 1166 11AD; # (첺; 첺; 첺; 첺; 첺; ) HANGUL SYLLABLE CENH
+CCBB;CCBB;110E 1166 11AE;CCBB;110E 1166 11AE; # (첻; 첻; 첻; 첻; 첻; ) HANGUL SYLLABLE CED
+CCBC;CCBC;110E 1166 11AF;CCBC;110E 1166 11AF; # (첼; 첼; 첼; 첼; 첼; ) HANGUL SYLLABLE CEL
+CCBD;CCBD;110E 1166 11B0;CCBD;110E 1166 11B0; # (첽; 첽; 첽; 첽; 첽; ) HANGUL SYLLABLE CELG
+CCBE;CCBE;110E 1166 11B1;CCBE;110E 1166 11B1; # (첾; 첾; 첾; 첾; 첾; ) HANGUL SYLLABLE CELM
+CCBF;CCBF;110E 1166 11B2;CCBF;110E 1166 11B2; # (첿; 첿; 첿; 첿; 첿; ) HANGUL SYLLABLE CELB
+CCC0;CCC0;110E 1166 11B3;CCC0;110E 1166 11B3; # (쳀; 쳀; 쳀; 쳀; 쳀; ) HANGUL SYLLABLE CELS
+CCC1;CCC1;110E 1166 11B4;CCC1;110E 1166 11B4; # (쳁; 쳁; 쳁; 쳁; 쳁; ) HANGUL SYLLABLE CELT
+CCC2;CCC2;110E 1166 11B5;CCC2;110E 1166 11B5; # (쳂; 쳂; 쳂; 쳂; 쳂; ) HANGUL SYLLABLE CELP
+CCC3;CCC3;110E 1166 11B6;CCC3;110E 1166 11B6; # (쳃; 쳃; 쳃; 쳃; 쳃; ) HANGUL SYLLABLE CELH
+CCC4;CCC4;110E 1166 11B7;CCC4;110E 1166 11B7; # (쳄; 쳄; 쳄; 쳄; 쳄; ) HANGUL SYLLABLE CEM
+CCC5;CCC5;110E 1166 11B8;CCC5;110E 1166 11B8; # (쳅; 쳅; 쳅; 쳅; 쳅; ) HANGUL SYLLABLE CEB
+CCC6;CCC6;110E 1166 11B9;CCC6;110E 1166 11B9; # (쳆; 쳆; 쳆; 쳆; 쳆; ) HANGUL SYLLABLE CEBS
+CCC7;CCC7;110E 1166 11BA;CCC7;110E 1166 11BA; # (쳇; 쳇; 쳇; 쳇; 쳇; ) HANGUL SYLLABLE CES
+CCC8;CCC8;110E 1166 11BB;CCC8;110E 1166 11BB; # (쳈; 쳈; 쳈; 쳈; 쳈; ) HANGUL SYLLABLE CESS
+CCC9;CCC9;110E 1166 11BC;CCC9;110E 1166 11BC; # (쳉; 쳉; 쳉; 쳉; 쳉; ) HANGUL SYLLABLE CENG
+CCCA;CCCA;110E 1166 11BD;CCCA;110E 1166 11BD; # (쳊; 쳊; 쳊; 쳊; 쳊; ) HANGUL SYLLABLE CEJ
+CCCB;CCCB;110E 1166 11BE;CCCB;110E 1166 11BE; # (쳋; 쳋; 쳋; 쳋; 쳋; ) HANGUL SYLLABLE CEC
+CCCC;CCCC;110E 1166 11BF;CCCC;110E 1166 11BF; # (쳌; 쳌; 쳌; 쳌; 쳌; ) HANGUL SYLLABLE CEK
+CCCD;CCCD;110E 1166 11C0;CCCD;110E 1166 11C0; # (쳍; 쳍; 쳍; 쳍; 쳍; ) HANGUL SYLLABLE CET
+CCCE;CCCE;110E 1166 11C1;CCCE;110E 1166 11C1; # (쳎; 쳎; 쳎; 쳎; 쳎; ) HANGUL SYLLABLE CEP
+CCCF;CCCF;110E 1166 11C2;CCCF;110E 1166 11C2; # (쳏; 쳏; 쳏; 쳏; 쳏; ) HANGUL SYLLABLE CEH
+CCD0;CCD0;110E 1167;CCD0;110E 1167; # (쳐; 쳐; 쳐; 쳐; 쳐; ) HANGUL SYLLABLE CYEO
+CCD1;CCD1;110E 1167 11A8;CCD1;110E 1167 11A8; # (쳑; 쳑; 쳑; 쳑; 쳑; ) HANGUL SYLLABLE CYEOG
+CCD2;CCD2;110E 1167 11A9;CCD2;110E 1167 11A9; # (쳒; 쳒; 쳒; 쳒; 쳒; ) HANGUL SYLLABLE CYEOGG
+CCD3;CCD3;110E 1167 11AA;CCD3;110E 1167 11AA; # (쳓; 쳓; 쳓; 쳓; 쳓; ) HANGUL SYLLABLE CYEOGS
+CCD4;CCD4;110E 1167 11AB;CCD4;110E 1167 11AB; # (쳔; 쳔; 쳔; 쳔; 쳔; ) HANGUL SYLLABLE CYEON
+CCD5;CCD5;110E 1167 11AC;CCD5;110E 1167 11AC; # (쳕; 쳕; 쳕; 쳕; 쳕; ) HANGUL SYLLABLE CYEONJ
+CCD6;CCD6;110E 1167 11AD;CCD6;110E 1167 11AD; # (쳖; 쳖; 쳖; 쳖; 쳖; ) HANGUL SYLLABLE CYEONH
+CCD7;CCD7;110E 1167 11AE;CCD7;110E 1167 11AE; # (쳗; 쳗; 쳗; 쳗; 쳗; ) HANGUL SYLLABLE CYEOD
+CCD8;CCD8;110E 1167 11AF;CCD8;110E 1167 11AF; # (쳘; 쳘; 쳘; 쳘; 쳘; ) HANGUL SYLLABLE CYEOL
+CCD9;CCD9;110E 1167 11B0;CCD9;110E 1167 11B0; # (쳙; 쳙; 쳙; 쳙; 쳙; ) HANGUL SYLLABLE CYEOLG
+CCDA;CCDA;110E 1167 11B1;CCDA;110E 1167 11B1; # (쳚; 쳚; 쳚; 쳚; 쳚; ) HANGUL SYLLABLE CYEOLM
+CCDB;CCDB;110E 1167 11B2;CCDB;110E 1167 11B2; # (쳛; 쳛; 쳛; 쳛; 쳛; ) HANGUL SYLLABLE CYEOLB
+CCDC;CCDC;110E 1167 11B3;CCDC;110E 1167 11B3; # (쳜; 쳜; 쳜; 쳜; 쳜; ) HANGUL SYLLABLE CYEOLS
+CCDD;CCDD;110E 1167 11B4;CCDD;110E 1167 11B4; # (쳝; 쳝; 쳝; 쳝; 쳝; ) HANGUL SYLLABLE CYEOLT
+CCDE;CCDE;110E 1167 11B5;CCDE;110E 1167 11B5; # (쳞; 쳞; 쳞; 쳞; 쳞; ) HANGUL SYLLABLE CYEOLP
+CCDF;CCDF;110E 1167 11B6;CCDF;110E 1167 11B6; # (쳟; 쳟; 쳟; 쳟; 쳟; ) HANGUL SYLLABLE CYEOLH
+CCE0;CCE0;110E 1167 11B7;CCE0;110E 1167 11B7; # (쳠; 쳠; 쳠; 쳠; 쳠; ) HANGUL SYLLABLE CYEOM
+CCE1;CCE1;110E 1167 11B8;CCE1;110E 1167 11B8; # (쳡; 쳡; 쳡; 쳡; 쳡; ) HANGUL SYLLABLE CYEOB
+CCE2;CCE2;110E 1167 11B9;CCE2;110E 1167 11B9; # (쳢; 쳢; 쳢; 쳢; 쳢; ) HANGUL SYLLABLE CYEOBS
+CCE3;CCE3;110E 1167 11BA;CCE3;110E 1167 11BA; # (쳣; 쳣; 쳣; 쳣; 쳣; ) HANGUL SYLLABLE CYEOS
+CCE4;CCE4;110E 1167 11BB;CCE4;110E 1167 11BB; # (쳤; 쳤; 쳤; 쳤; 쳤; ) HANGUL SYLLABLE CYEOSS
+CCE5;CCE5;110E 1167 11BC;CCE5;110E 1167 11BC; # (쳥; 쳥; 쳥; 쳥; 쳥; ) HANGUL SYLLABLE CYEONG
+CCE6;CCE6;110E 1167 11BD;CCE6;110E 1167 11BD; # (쳦; 쳦; 쳦; 쳦; 쳦; ) HANGUL SYLLABLE CYEOJ
+CCE7;CCE7;110E 1167 11BE;CCE7;110E 1167 11BE; # (쳧; 쳧; 쳧; 쳧; 쳧; ) HANGUL SYLLABLE CYEOC
+CCE8;CCE8;110E 1167 11BF;CCE8;110E 1167 11BF; # (쳨; 쳨; 쳨; 쳨; 쳨; ) HANGUL SYLLABLE CYEOK
+CCE9;CCE9;110E 1167 11C0;CCE9;110E 1167 11C0; # (쳩; 쳩; 쳩; 쳩; 쳩; ) HANGUL SYLLABLE CYEOT
+CCEA;CCEA;110E 1167 11C1;CCEA;110E 1167 11C1; # (쳪; 쳪; 쳪; 쳪; 쳪; ) HANGUL SYLLABLE CYEOP
+CCEB;CCEB;110E 1167 11C2;CCEB;110E 1167 11C2; # (쳫; 쳫; 쳫; 쳫; 쳫; ) HANGUL SYLLABLE CYEOH
+CCEC;CCEC;110E 1168;CCEC;110E 1168; # (쳬; 쳬; 쳬; 쳬; 쳬; ) HANGUL SYLLABLE CYE
+CCED;CCED;110E 1168 11A8;CCED;110E 1168 11A8; # (쳭; 쳭; 쳭; 쳭; 쳭; ) HANGUL SYLLABLE CYEG
+CCEE;CCEE;110E 1168 11A9;CCEE;110E 1168 11A9; # (쳮; 쳮; 쳮; 쳮; 쳮; ) HANGUL SYLLABLE CYEGG
+CCEF;CCEF;110E 1168 11AA;CCEF;110E 1168 11AA; # (쳯; 쳯; 쳯; 쳯; 쳯; ) HANGUL SYLLABLE CYEGS
+CCF0;CCF0;110E 1168 11AB;CCF0;110E 1168 11AB; # (쳰; 쳰; 쳰; 쳰; 쳰; ) HANGUL SYLLABLE CYEN
+CCF1;CCF1;110E 1168 11AC;CCF1;110E 1168 11AC; # (쳱; 쳱; 쳱; 쳱; 쳱; ) HANGUL SYLLABLE CYENJ
+CCF2;CCF2;110E 1168 11AD;CCF2;110E 1168 11AD; # (쳲; 쳲; 쳲; 쳲; 쳲; ) HANGUL SYLLABLE CYENH
+CCF3;CCF3;110E 1168 11AE;CCF3;110E 1168 11AE; # (쳳; 쳳; 쳳; 쳳; 쳳; ) HANGUL SYLLABLE CYED
+CCF4;CCF4;110E 1168 11AF;CCF4;110E 1168 11AF; # (쳴; 쳴; 쳴; 쳴; 쳴; ) HANGUL SYLLABLE CYEL
+CCF5;CCF5;110E 1168 11B0;CCF5;110E 1168 11B0; # (쳵; 쳵; 쳵; 쳵; 쳵; ) HANGUL SYLLABLE CYELG
+CCF6;CCF6;110E 1168 11B1;CCF6;110E 1168 11B1; # (쳶; 쳶; 쳶; 쳶; 쳶; ) HANGUL SYLLABLE CYELM
+CCF7;CCF7;110E 1168 11B2;CCF7;110E 1168 11B2; # (쳷; 쳷; 쳷; 쳷; 쳷; ) HANGUL SYLLABLE CYELB
+CCF8;CCF8;110E 1168 11B3;CCF8;110E 1168 11B3; # (쳸; 쳸; 쳸; 쳸; 쳸; ) HANGUL SYLLABLE CYELS
+CCF9;CCF9;110E 1168 11B4;CCF9;110E 1168 11B4; # (쳹; 쳹; 쳹; 쳹; 쳹; ) HANGUL SYLLABLE CYELT
+CCFA;CCFA;110E 1168 11B5;CCFA;110E 1168 11B5; # (쳺; 쳺; 쳺; 쳺; 쳺; ) HANGUL SYLLABLE CYELP
+CCFB;CCFB;110E 1168 11B6;CCFB;110E 1168 11B6; # (쳻; 쳻; 쳻; 쳻; 쳻; ) HANGUL SYLLABLE CYELH
+CCFC;CCFC;110E 1168 11B7;CCFC;110E 1168 11B7; # (쳼; 쳼; 쳼; 쳼; 쳼; ) HANGUL SYLLABLE CYEM
+CCFD;CCFD;110E 1168 11B8;CCFD;110E 1168 11B8; # (쳽; 쳽; 쳽; 쳽; 쳽; ) HANGUL SYLLABLE CYEB
+CCFE;CCFE;110E 1168 11B9;CCFE;110E 1168 11B9; # (쳾; 쳾; 쳾; 쳾; 쳾; ) HANGUL SYLLABLE CYEBS
+CCFF;CCFF;110E 1168 11BA;CCFF;110E 1168 11BA; # (쳿; 쳿; 쳿; 쳿; 쳿; ) HANGUL SYLLABLE CYES
+CD00;CD00;110E 1168 11BB;CD00;110E 1168 11BB; # (촀; 촀; 촀; 촀; 촀; ) HANGUL SYLLABLE CYESS
+CD01;CD01;110E 1168 11BC;CD01;110E 1168 11BC; # (촁; 촁; 촁; 촁; 촁; ) HANGUL SYLLABLE CYENG
+CD02;CD02;110E 1168 11BD;CD02;110E 1168 11BD; # (촂; 촂; 촂; 촂; 촂; ) HANGUL SYLLABLE CYEJ
+CD03;CD03;110E 1168 11BE;CD03;110E 1168 11BE; # (촃; 촃; 촃; 촃; 촃; ) HANGUL SYLLABLE CYEC
+CD04;CD04;110E 1168 11BF;CD04;110E 1168 11BF; # (촄; 촄; 촄; 촄; 촄; ) HANGUL SYLLABLE CYEK
+CD05;CD05;110E 1168 11C0;CD05;110E 1168 11C0; # (촅; 촅; 촅; 촅; 촅; ) HANGUL SYLLABLE CYET
+CD06;CD06;110E 1168 11C1;CD06;110E 1168 11C1; # (촆; 촆; 촆; 촆; 촆; ) HANGUL SYLLABLE CYEP
+CD07;CD07;110E 1168 11C2;CD07;110E 1168 11C2; # (촇; 촇; 촇; 촇; 촇; ) HANGUL SYLLABLE CYEH
+CD08;CD08;110E 1169;CD08;110E 1169; # (초; 초; 초; 초; 초; ) HANGUL SYLLABLE CO
+CD09;CD09;110E 1169 11A8;CD09;110E 1169 11A8; # (촉; 촉; 촉; 촉; 촉; ) HANGUL SYLLABLE COG
+CD0A;CD0A;110E 1169 11A9;CD0A;110E 1169 11A9; # (촊; 촊; 촊; 촊; 촊; ) HANGUL SYLLABLE COGG
+CD0B;CD0B;110E 1169 11AA;CD0B;110E 1169 11AA; # (촋; 촋; 촋; 촋; 촋; ) HANGUL SYLLABLE COGS
+CD0C;CD0C;110E 1169 11AB;CD0C;110E 1169 11AB; # (촌; 촌; 촌; 촌; 촌; ) HANGUL SYLLABLE CON
+CD0D;CD0D;110E 1169 11AC;CD0D;110E 1169 11AC; # (촍; 촍; 촍; 촍; 촍; ) HANGUL SYLLABLE CONJ
+CD0E;CD0E;110E 1169 11AD;CD0E;110E 1169 11AD; # (촎; 촎; 촎; 촎; 촎; ) HANGUL SYLLABLE CONH
+CD0F;CD0F;110E 1169 11AE;CD0F;110E 1169 11AE; # (촏; 촏; 촏; 촏; 촏; ) HANGUL SYLLABLE COD
+CD10;CD10;110E 1169 11AF;CD10;110E 1169 11AF; # (촐; 촐; 촐; 촐; 촐; ) HANGUL SYLLABLE COL
+CD11;CD11;110E 1169 11B0;CD11;110E 1169 11B0; # (촑; 촑; 촑; 촑; 촑; ) HANGUL SYLLABLE COLG
+CD12;CD12;110E 1169 11B1;CD12;110E 1169 11B1; # (촒; 촒; 촒; 촒; 촒; ) HANGUL SYLLABLE COLM
+CD13;CD13;110E 1169 11B2;CD13;110E 1169 11B2; # (촓; 촓; 촓; 촓; 촓; ) HANGUL SYLLABLE COLB
+CD14;CD14;110E 1169 11B3;CD14;110E 1169 11B3; # (촔; 촔; 촔; 촔; 촔; ) HANGUL SYLLABLE COLS
+CD15;CD15;110E 1169 11B4;CD15;110E 1169 11B4; # (촕; 촕; 촕; 촕; 촕; ) HANGUL SYLLABLE COLT
+CD16;CD16;110E 1169 11B5;CD16;110E 1169 11B5; # (촖; 촖; 촖; 촖; 촖; ) HANGUL SYLLABLE COLP
+CD17;CD17;110E 1169 11B6;CD17;110E 1169 11B6; # (촗; 촗; 촗; 촗; 촗; ) HANGUL SYLLABLE COLH
+CD18;CD18;110E 1169 11B7;CD18;110E 1169 11B7; # (촘; 촘; 촘; 촘; 촘; ) HANGUL SYLLABLE COM
+CD19;CD19;110E 1169 11B8;CD19;110E 1169 11B8; # (촙; 촙; 촙; 촙; 촙; ) HANGUL SYLLABLE COB
+CD1A;CD1A;110E 1169 11B9;CD1A;110E 1169 11B9; # (촚; 촚; 촚; 촚; 촚; ) HANGUL SYLLABLE COBS
+CD1B;CD1B;110E 1169 11BA;CD1B;110E 1169 11BA; # (촛; 촛; 촛; 촛; 촛; ) HANGUL SYLLABLE COS
+CD1C;CD1C;110E 1169 11BB;CD1C;110E 1169 11BB; # (촜; 촜; 촜; 촜; 촜; ) HANGUL SYLLABLE COSS
+CD1D;CD1D;110E 1169 11BC;CD1D;110E 1169 11BC; # (총; 총; 총; 총; 총; ) HANGUL SYLLABLE CONG
+CD1E;CD1E;110E 1169 11BD;CD1E;110E 1169 11BD; # (촞; 촞; 촞; 촞; 촞; ) HANGUL SYLLABLE COJ
+CD1F;CD1F;110E 1169 11BE;CD1F;110E 1169 11BE; # (촟; 촟; 촟; 촟; 촟; ) HANGUL SYLLABLE COC
+CD20;CD20;110E 1169 11BF;CD20;110E 1169 11BF; # (촠; 촠; 촠; 촠; 촠; ) HANGUL SYLLABLE COK
+CD21;CD21;110E 1169 11C0;CD21;110E 1169 11C0; # (촡; 촡; 촡; 촡; 촡; ) HANGUL SYLLABLE COT
+CD22;CD22;110E 1169 11C1;CD22;110E 1169 11C1; # (촢; 촢; 촢; 촢; 촢; ) HANGUL SYLLABLE COP
+CD23;CD23;110E 1169 11C2;CD23;110E 1169 11C2; # (촣; 촣; 촣; 촣; 촣; ) HANGUL SYLLABLE COH
+CD24;CD24;110E 116A;CD24;110E 116A; # (촤; 촤; 촤; 촤; 촤; ) HANGUL SYLLABLE CWA
+CD25;CD25;110E 116A 11A8;CD25;110E 116A 11A8; # (촥; 촥; 촥; 촥; 촥; ) HANGUL SYLLABLE CWAG
+CD26;CD26;110E 116A 11A9;CD26;110E 116A 11A9; # (촦; 촦; 촦; 촦; 촦; ) HANGUL SYLLABLE CWAGG
+CD27;CD27;110E 116A 11AA;CD27;110E 116A 11AA; # (촧; 촧; 촧; 촧; 촧; ) HANGUL SYLLABLE CWAGS
+CD28;CD28;110E 116A 11AB;CD28;110E 116A 11AB; # (촨; 촨; 촨; 촨; 촨; ) HANGUL SYLLABLE CWAN
+CD29;CD29;110E 116A 11AC;CD29;110E 116A 11AC; # (촩; 촩; 촩; 촩; 촩; ) HANGUL SYLLABLE CWANJ
+CD2A;CD2A;110E 116A 11AD;CD2A;110E 116A 11AD; # (촪; 촪; 촪; 촪; 촪; ) HANGUL SYLLABLE CWANH
+CD2B;CD2B;110E 116A 11AE;CD2B;110E 116A 11AE; # (촫; 촫; 촫; 촫; 촫; ) HANGUL SYLLABLE CWAD
+CD2C;CD2C;110E 116A 11AF;CD2C;110E 116A 11AF; # (촬; 촬; 촬; 촬; 촬; ) HANGUL SYLLABLE CWAL
+CD2D;CD2D;110E 116A 11B0;CD2D;110E 116A 11B0; # (촭; 촭; 촭; 촭; 촭; ) HANGUL SYLLABLE CWALG
+CD2E;CD2E;110E 116A 11B1;CD2E;110E 116A 11B1; # (촮; 촮; 촮; 촮; 촮; ) HANGUL SYLLABLE CWALM
+CD2F;CD2F;110E 116A 11B2;CD2F;110E 116A 11B2; # (촯; 촯; 촯; 촯; 촯; ) HANGUL SYLLABLE CWALB
+CD30;CD30;110E 116A 11B3;CD30;110E 116A 11B3; # (촰; 촰; 촰; 촰; 촰; ) HANGUL SYLLABLE CWALS
+CD31;CD31;110E 116A 11B4;CD31;110E 116A 11B4; # (촱; 촱; 촱; 촱; 촱; ) HANGUL SYLLABLE CWALT
+CD32;CD32;110E 116A 11B5;CD32;110E 116A 11B5; # (촲; 촲; 촲; 촲; 촲; ) HANGUL SYLLABLE CWALP
+CD33;CD33;110E 116A 11B6;CD33;110E 116A 11B6; # (촳; 촳; 촳; 촳; 촳; ) HANGUL SYLLABLE CWALH
+CD34;CD34;110E 116A 11B7;CD34;110E 116A 11B7; # (촴; 촴; 촴; 촴; 촴; ) HANGUL SYLLABLE CWAM
+CD35;CD35;110E 116A 11B8;CD35;110E 116A 11B8; # (촵; 촵; 촵; 촵; 촵; ) HANGUL SYLLABLE CWAB
+CD36;CD36;110E 116A 11B9;CD36;110E 116A 11B9; # (촶; 촶; 촶; 촶; 촶; ) HANGUL SYLLABLE CWABS
+CD37;CD37;110E 116A 11BA;CD37;110E 116A 11BA; # (촷; 촷; 촷; 촷; 촷; ) HANGUL SYLLABLE CWAS
+CD38;CD38;110E 116A 11BB;CD38;110E 116A 11BB; # (촸; 촸; 촸; 촸; 촸; ) HANGUL SYLLABLE CWASS
+CD39;CD39;110E 116A 11BC;CD39;110E 116A 11BC; # (촹; 촹; 촹; 촹; 촹; ) HANGUL SYLLABLE CWANG
+CD3A;CD3A;110E 116A 11BD;CD3A;110E 116A 11BD; # (촺; 촺; 촺; 촺; 촺; ) HANGUL SYLLABLE CWAJ
+CD3B;CD3B;110E 116A 11BE;CD3B;110E 116A 11BE; # (촻; 촻; 촻; 촻; 촻; ) HANGUL SYLLABLE CWAC
+CD3C;CD3C;110E 116A 11BF;CD3C;110E 116A 11BF; # (촼; 촼; 촼; 촼; 촼; ) HANGUL SYLLABLE CWAK
+CD3D;CD3D;110E 116A 11C0;CD3D;110E 116A 11C0; # (촽; 촽; 촽; 촽; 촽; ) HANGUL SYLLABLE CWAT
+CD3E;CD3E;110E 116A 11C1;CD3E;110E 116A 11C1; # (촾; 촾; 촾; 촾; 촾; ) HANGUL SYLLABLE CWAP
+CD3F;CD3F;110E 116A 11C2;CD3F;110E 116A 11C2; # (촿; 촿; 촿; 촿; 촿; ) HANGUL SYLLABLE CWAH
+CD40;CD40;110E 116B;CD40;110E 116B; # (쵀; 쵀; 쵀; 쵀; 쵀; ) HANGUL SYLLABLE CWAE
+CD41;CD41;110E 116B 11A8;CD41;110E 116B 11A8; # (쵁; 쵁; 쵁; 쵁; 쵁; ) HANGUL SYLLABLE CWAEG
+CD42;CD42;110E 116B 11A9;CD42;110E 116B 11A9; # (쵂; 쵂; 쵂; 쵂; 쵂; ) HANGUL SYLLABLE CWAEGG
+CD43;CD43;110E 116B 11AA;CD43;110E 116B 11AA; # (쵃; 쵃; 쵃; 쵃; 쵃; ) HANGUL SYLLABLE CWAEGS
+CD44;CD44;110E 116B 11AB;CD44;110E 116B 11AB; # (쵄; 쵄; 쵄; 쵄; 쵄; ) HANGUL SYLLABLE CWAEN
+CD45;CD45;110E 116B 11AC;CD45;110E 116B 11AC; # (쵅; 쵅; 쵅; 쵅; 쵅; ) HANGUL SYLLABLE CWAENJ
+CD46;CD46;110E 116B 11AD;CD46;110E 116B 11AD; # (쵆; 쵆; 쵆; 쵆; 쵆; ) HANGUL SYLLABLE CWAENH
+CD47;CD47;110E 116B 11AE;CD47;110E 116B 11AE; # (쵇; 쵇; 쵇; 쵇; 쵇; ) HANGUL SYLLABLE CWAED
+CD48;CD48;110E 116B 11AF;CD48;110E 116B 11AF; # (쵈; 쵈; 쵈; 쵈; 쵈; ) HANGUL SYLLABLE CWAEL
+CD49;CD49;110E 116B 11B0;CD49;110E 116B 11B0; # (쵉; 쵉; 쵉; 쵉; 쵉; ) HANGUL SYLLABLE CWAELG
+CD4A;CD4A;110E 116B 11B1;CD4A;110E 116B 11B1; # (쵊; 쵊; 쵊; 쵊; 쵊; ) HANGUL SYLLABLE CWAELM
+CD4B;CD4B;110E 116B 11B2;CD4B;110E 116B 11B2; # (쵋; 쵋; 쵋; 쵋; 쵋; ) HANGUL SYLLABLE CWAELB
+CD4C;CD4C;110E 116B 11B3;CD4C;110E 116B 11B3; # (쵌; 쵌; 쵌; 쵌; 쵌; ) HANGUL SYLLABLE CWAELS
+CD4D;CD4D;110E 116B 11B4;CD4D;110E 116B 11B4; # (쵍; 쵍; 쵍; 쵍; 쵍; ) HANGUL SYLLABLE CWAELT
+CD4E;CD4E;110E 116B 11B5;CD4E;110E 116B 11B5; # (쵎; 쵎; 쵎; 쵎; 쵎; ) HANGUL SYLLABLE CWAELP
+CD4F;CD4F;110E 116B 11B6;CD4F;110E 116B 11B6; # (쵏; 쵏; 쵏; 쵏; 쵏; ) HANGUL SYLLABLE CWAELH
+CD50;CD50;110E 116B 11B7;CD50;110E 116B 11B7; # (쵐; 쵐; 쵐; 쵐; 쵐; ) HANGUL SYLLABLE CWAEM
+CD51;CD51;110E 116B 11B8;CD51;110E 116B 11B8; # (쵑; 쵑; 쵑; 쵑; 쵑; ) HANGUL SYLLABLE CWAEB
+CD52;CD52;110E 116B 11B9;CD52;110E 116B 11B9; # (쵒; 쵒; 쵒; 쵒; 쵒; ) HANGUL SYLLABLE CWAEBS
+CD53;CD53;110E 116B 11BA;CD53;110E 116B 11BA; # (쵓; 쵓; 쵓; 쵓; 쵓; ) HANGUL SYLLABLE CWAES
+CD54;CD54;110E 116B 11BB;CD54;110E 116B 11BB; # (쵔; 쵔; 쵔; 쵔; 쵔; ) HANGUL SYLLABLE CWAESS
+CD55;CD55;110E 116B 11BC;CD55;110E 116B 11BC; # (쵕; 쵕; 쵕; 쵕; 쵕; ) HANGUL SYLLABLE CWAENG
+CD56;CD56;110E 116B 11BD;CD56;110E 116B 11BD; # (쵖; 쵖; 쵖; 쵖; 쵖; ) HANGUL SYLLABLE CWAEJ
+CD57;CD57;110E 116B 11BE;CD57;110E 116B 11BE; # (쵗; 쵗; 쵗; 쵗; 쵗; ) HANGUL SYLLABLE CWAEC
+CD58;CD58;110E 116B 11BF;CD58;110E 116B 11BF; # (쵘; 쵘; 쵘; 쵘; 쵘; ) HANGUL SYLLABLE CWAEK
+CD59;CD59;110E 116B 11C0;CD59;110E 116B 11C0; # (쵙; 쵙; 쵙; 쵙; 쵙; ) HANGUL SYLLABLE CWAET
+CD5A;CD5A;110E 116B 11C1;CD5A;110E 116B 11C1; # (쵚; 쵚; 쵚; 쵚; 쵚; ) HANGUL SYLLABLE CWAEP
+CD5B;CD5B;110E 116B 11C2;CD5B;110E 116B 11C2; # (쵛; 쵛; 쵛; 쵛; 쵛; ) HANGUL SYLLABLE CWAEH
+CD5C;CD5C;110E 116C;CD5C;110E 116C; # (최; 최; 최; 최; 최; ) HANGUL SYLLABLE COE
+CD5D;CD5D;110E 116C 11A8;CD5D;110E 116C 11A8; # (쵝; 쵝; 쵝; 쵝; 쵝; ) HANGUL SYLLABLE COEG
+CD5E;CD5E;110E 116C 11A9;CD5E;110E 116C 11A9; # (쵞; 쵞; 쵞; 쵞; 쵞; ) HANGUL SYLLABLE COEGG
+CD5F;CD5F;110E 116C 11AA;CD5F;110E 116C 11AA; # (쵟; 쵟; 쵟; 쵟; 쵟; ) HANGUL SYLLABLE COEGS
+CD60;CD60;110E 116C 11AB;CD60;110E 116C 11AB; # (쵠; 쵠; 쵠; 쵠; 쵠; ) HANGUL SYLLABLE COEN
+CD61;CD61;110E 116C 11AC;CD61;110E 116C 11AC; # (쵡; 쵡; 쵡; 쵡; 쵡; ) HANGUL SYLLABLE COENJ
+CD62;CD62;110E 116C 11AD;CD62;110E 116C 11AD; # (쵢; 쵢; 쵢; 쵢; 쵢; ) HANGUL SYLLABLE COENH
+CD63;CD63;110E 116C 11AE;CD63;110E 116C 11AE; # (쵣; 쵣; 쵣; 쵣; 쵣; ) HANGUL SYLLABLE COED
+CD64;CD64;110E 116C 11AF;CD64;110E 116C 11AF; # (쵤; 쵤; 쵤; 쵤; 쵤; ) HANGUL SYLLABLE COEL
+CD65;CD65;110E 116C 11B0;CD65;110E 116C 11B0; # (쵥; 쵥; 쵥; 쵥; 쵥; ) HANGUL SYLLABLE COELG
+CD66;CD66;110E 116C 11B1;CD66;110E 116C 11B1; # (쵦; 쵦; 쵦; 쵦; 쵦; ) HANGUL SYLLABLE COELM
+CD67;CD67;110E 116C 11B2;CD67;110E 116C 11B2; # (쵧; 쵧; 쵧; 쵧; 쵧; ) HANGUL SYLLABLE COELB
+CD68;CD68;110E 116C 11B3;CD68;110E 116C 11B3; # (쵨; 쵨; 쵨; 쵨; 쵨; ) HANGUL SYLLABLE COELS
+CD69;CD69;110E 116C 11B4;CD69;110E 116C 11B4; # (쵩; 쵩; 쵩; 쵩; 쵩; ) HANGUL SYLLABLE COELT
+CD6A;CD6A;110E 116C 11B5;CD6A;110E 116C 11B5; # (쵪; 쵪; 쵪; 쵪; 쵪; ) HANGUL SYLLABLE COELP
+CD6B;CD6B;110E 116C 11B6;CD6B;110E 116C 11B6; # (쵫; 쵫; 쵫; 쵫; 쵫; ) HANGUL SYLLABLE COELH
+CD6C;CD6C;110E 116C 11B7;CD6C;110E 116C 11B7; # (쵬; 쵬; 쵬; 쵬; 쵬; ) HANGUL SYLLABLE COEM
+CD6D;CD6D;110E 116C 11B8;CD6D;110E 116C 11B8; # (쵭; 쵭; 쵭; 쵭; 쵭; ) HANGUL SYLLABLE COEB
+CD6E;CD6E;110E 116C 11B9;CD6E;110E 116C 11B9; # (쵮; 쵮; 쵮; 쵮; 쵮; ) HANGUL SYLLABLE COEBS
+CD6F;CD6F;110E 116C 11BA;CD6F;110E 116C 11BA; # (쵯; 쵯; 쵯; 쵯; 쵯; ) HANGUL SYLLABLE COES
+CD70;CD70;110E 116C 11BB;CD70;110E 116C 11BB; # (쵰; 쵰; 쵰; 쵰; 쵰; ) HANGUL SYLLABLE COESS
+CD71;CD71;110E 116C 11BC;CD71;110E 116C 11BC; # (쵱; 쵱; 쵱; 쵱; 쵱; ) HANGUL SYLLABLE COENG
+CD72;CD72;110E 116C 11BD;CD72;110E 116C 11BD; # (쵲; 쵲; 쵲; 쵲; 쵲; ) HANGUL SYLLABLE COEJ
+CD73;CD73;110E 116C 11BE;CD73;110E 116C 11BE; # (쵳; 쵳; 쵳; 쵳; 쵳; ) HANGUL SYLLABLE COEC
+CD74;CD74;110E 116C 11BF;CD74;110E 116C 11BF; # (쵴; 쵴; 쵴; 쵴; 쵴; ) HANGUL SYLLABLE COEK
+CD75;CD75;110E 116C 11C0;CD75;110E 116C 11C0; # (쵵; 쵵; 쵵; 쵵; 쵵; ) HANGUL SYLLABLE COET
+CD76;CD76;110E 116C 11C1;CD76;110E 116C 11C1; # (쵶; 쵶; 쵶; 쵶; 쵶; ) HANGUL SYLLABLE COEP
+CD77;CD77;110E 116C 11C2;CD77;110E 116C 11C2; # (쵷; 쵷; 쵷; 쵷; 쵷; ) HANGUL SYLLABLE COEH
+CD78;CD78;110E 116D;CD78;110E 116D; # (쵸; 쵸; 쵸; 쵸; 쵸; ) HANGUL SYLLABLE CYO
+CD79;CD79;110E 116D 11A8;CD79;110E 116D 11A8; # (쵹; 쵹; 쵹; 쵹; 쵹; ) HANGUL SYLLABLE CYOG
+CD7A;CD7A;110E 116D 11A9;CD7A;110E 116D 11A9; # (쵺; 쵺; 쵺; 쵺; 쵺; ) HANGUL SYLLABLE CYOGG
+CD7B;CD7B;110E 116D 11AA;CD7B;110E 116D 11AA; # (쵻; 쵻; 쵻; 쵻; 쵻; ) HANGUL SYLLABLE CYOGS
+CD7C;CD7C;110E 116D 11AB;CD7C;110E 116D 11AB; # (쵼; 쵼; 쵼; 쵼; 쵼; ) HANGUL SYLLABLE CYON
+CD7D;CD7D;110E 116D 11AC;CD7D;110E 116D 11AC; # (쵽; 쵽; 쵽; 쵽; 쵽; ) HANGUL SYLLABLE CYONJ
+CD7E;CD7E;110E 116D 11AD;CD7E;110E 116D 11AD; # (쵾; 쵾; 쵾; 쵾; 쵾; ) HANGUL SYLLABLE CYONH
+CD7F;CD7F;110E 116D 11AE;CD7F;110E 116D 11AE; # (쵿; 쵿; 쵿; 쵿; 쵿; ) HANGUL SYLLABLE CYOD
+CD80;CD80;110E 116D 11AF;CD80;110E 116D 11AF; # (춀; 춀; 춀; 춀; 춀; ) HANGUL SYLLABLE CYOL
+CD81;CD81;110E 116D 11B0;CD81;110E 116D 11B0; # (춁; 춁; 춁; 춁; 춁; ) HANGUL SYLLABLE CYOLG
+CD82;CD82;110E 116D 11B1;CD82;110E 116D 11B1; # (춂; 춂; 춂; 춂; 춂; ) HANGUL SYLLABLE CYOLM
+CD83;CD83;110E 116D 11B2;CD83;110E 116D 11B2; # (춃; 춃; 춃; 춃; 춃; ) HANGUL SYLLABLE CYOLB
+CD84;CD84;110E 116D 11B3;CD84;110E 116D 11B3; # (춄; 춄; 춄; 춄; 춄; ) HANGUL SYLLABLE CYOLS
+CD85;CD85;110E 116D 11B4;CD85;110E 116D 11B4; # (춅; 춅; 춅; 춅; 춅; ) HANGUL SYLLABLE CYOLT
+CD86;CD86;110E 116D 11B5;CD86;110E 116D 11B5; # (춆; 춆; 춆; 춆; 춆; ) HANGUL SYLLABLE CYOLP
+CD87;CD87;110E 116D 11B6;CD87;110E 116D 11B6; # (춇; 춇; 춇; 춇; 춇; ) HANGUL SYLLABLE CYOLH
+CD88;CD88;110E 116D 11B7;CD88;110E 116D 11B7; # (춈; 춈; 춈; 춈; 춈; ) HANGUL SYLLABLE CYOM
+CD89;CD89;110E 116D 11B8;CD89;110E 116D 11B8; # (춉; 춉; 춉; 춉; 춉; ) HANGUL SYLLABLE CYOB
+CD8A;CD8A;110E 116D 11B9;CD8A;110E 116D 11B9; # (춊; 춊; 춊; 춊; 춊; ) HANGUL SYLLABLE CYOBS
+CD8B;CD8B;110E 116D 11BA;CD8B;110E 116D 11BA; # (춋; 춋; 춋; 춋; 춋; ) HANGUL SYLLABLE CYOS
+CD8C;CD8C;110E 116D 11BB;CD8C;110E 116D 11BB; # (춌; 춌; 춌; 춌; 춌; ) HANGUL SYLLABLE CYOSS
+CD8D;CD8D;110E 116D 11BC;CD8D;110E 116D 11BC; # (춍; 춍; 춍; 춍; 춍; ) HANGUL SYLLABLE CYONG
+CD8E;CD8E;110E 116D 11BD;CD8E;110E 116D 11BD; # (춎; 춎; 춎; 춎; 춎; ) HANGUL SYLLABLE CYOJ
+CD8F;CD8F;110E 116D 11BE;CD8F;110E 116D 11BE; # (춏; 춏; 춏; 춏; 춏; ) HANGUL SYLLABLE CYOC
+CD90;CD90;110E 116D 11BF;CD90;110E 116D 11BF; # (춐; 춐; 춐; 춐; 춐; ) HANGUL SYLLABLE CYOK
+CD91;CD91;110E 116D 11C0;CD91;110E 116D 11C0; # (춑; 춑; 춑; 춑; 춑; ) HANGUL SYLLABLE CYOT
+CD92;CD92;110E 116D 11C1;CD92;110E 116D 11C1; # (춒; 춒; 춒; 춒; 춒; ) HANGUL SYLLABLE CYOP
+CD93;CD93;110E 116D 11C2;CD93;110E 116D 11C2; # (춓; 춓; 춓; 춓; 춓; ) HANGUL SYLLABLE CYOH
+CD94;CD94;110E 116E;CD94;110E 116E; # (추; 추; 추; 추; 추; ) HANGUL SYLLABLE CU
+CD95;CD95;110E 116E 11A8;CD95;110E 116E 11A8; # (축; 축; 축; 축; 축; ) HANGUL SYLLABLE CUG
+CD96;CD96;110E 116E 11A9;CD96;110E 116E 11A9; # (춖; 춖; 춖; 춖; 춖; ) HANGUL SYLLABLE CUGG
+CD97;CD97;110E 116E 11AA;CD97;110E 116E 11AA; # (춗; 춗; 춗; 춗; 춗; ) HANGUL SYLLABLE CUGS
+CD98;CD98;110E 116E 11AB;CD98;110E 116E 11AB; # (춘; 춘; 춘; 춘; 춘; ) HANGUL SYLLABLE CUN
+CD99;CD99;110E 116E 11AC;CD99;110E 116E 11AC; # (춙; 춙; 춙; 춙; 춙; ) HANGUL SYLLABLE CUNJ
+CD9A;CD9A;110E 116E 11AD;CD9A;110E 116E 11AD; # (춚; 춚; 춚; 춚; 춚; ) HANGUL SYLLABLE CUNH
+CD9B;CD9B;110E 116E 11AE;CD9B;110E 116E 11AE; # (춛; 춛; 춛; 춛; 춛; ) HANGUL SYLLABLE CUD
+CD9C;CD9C;110E 116E 11AF;CD9C;110E 116E 11AF; # (출; 출; 출; 출; 출; ) HANGUL SYLLABLE CUL
+CD9D;CD9D;110E 116E 11B0;CD9D;110E 116E 11B0; # (춝; 춝; 춝; 춝; 춝; ) HANGUL SYLLABLE CULG
+CD9E;CD9E;110E 116E 11B1;CD9E;110E 116E 11B1; # (춞; 춞; 춞; 춞; 춞; ) HANGUL SYLLABLE CULM
+CD9F;CD9F;110E 116E 11B2;CD9F;110E 116E 11B2; # (춟; 춟; 춟; 춟; 춟; ) HANGUL SYLLABLE CULB
+CDA0;CDA0;110E 116E 11B3;CDA0;110E 116E 11B3; # (춠; 춠; 춠; 춠; 춠; ) HANGUL SYLLABLE CULS
+CDA1;CDA1;110E 116E 11B4;CDA1;110E 116E 11B4; # (춡; 춡; 춡; 춡; 춡; ) HANGUL SYLLABLE CULT
+CDA2;CDA2;110E 116E 11B5;CDA2;110E 116E 11B5; # (춢; 춢; 춢; 춢; 춢; ) HANGUL SYLLABLE CULP
+CDA3;CDA3;110E 116E 11B6;CDA3;110E 116E 11B6; # (춣; 춣; 춣; 춣; 춣; ) HANGUL SYLLABLE CULH
+CDA4;CDA4;110E 116E 11B7;CDA4;110E 116E 11B7; # (춤; 춤; 춤; 춤; 춤; ) HANGUL SYLLABLE CUM
+CDA5;CDA5;110E 116E 11B8;CDA5;110E 116E 11B8; # (춥; 춥; 춥; 춥; 춥; ) HANGUL SYLLABLE CUB
+CDA6;CDA6;110E 116E 11B9;CDA6;110E 116E 11B9; # (춦; 춦; 춦; 춦; 춦; ) HANGUL SYLLABLE CUBS
+CDA7;CDA7;110E 116E 11BA;CDA7;110E 116E 11BA; # (춧; 춧; 춧; 춧; 춧; ) HANGUL SYLLABLE CUS
+CDA8;CDA8;110E 116E 11BB;CDA8;110E 116E 11BB; # (춨; 춨; 춨; 춨; 춨; ) HANGUL SYLLABLE CUSS
+CDA9;CDA9;110E 116E 11BC;CDA9;110E 116E 11BC; # (충; 충; 충; 충; 충; ) HANGUL SYLLABLE CUNG
+CDAA;CDAA;110E 116E 11BD;CDAA;110E 116E 11BD; # (춪; 춪; 춪; 춪; 춪; ) HANGUL SYLLABLE CUJ
+CDAB;CDAB;110E 116E 11BE;CDAB;110E 116E 11BE; # (춫; 춫; 춫; 춫; 춫; ) HANGUL SYLLABLE CUC
+CDAC;CDAC;110E 116E 11BF;CDAC;110E 116E 11BF; # (춬; 춬; 춬; 춬; 춬; ) HANGUL SYLLABLE CUK
+CDAD;CDAD;110E 116E 11C0;CDAD;110E 116E 11C0; # (춭; 춭; 춭; 춭; 춭; ) HANGUL SYLLABLE CUT
+CDAE;CDAE;110E 116E 11C1;CDAE;110E 116E 11C1; # (춮; 춮; 춮; 춮; 춮; ) HANGUL SYLLABLE CUP
+CDAF;CDAF;110E 116E 11C2;CDAF;110E 116E 11C2; # (춯; 춯; 춯; 춯; 춯; ) HANGUL SYLLABLE CUH
+CDB0;CDB0;110E 116F;CDB0;110E 116F; # (춰; 춰; 춰; 춰; 춰; ) HANGUL SYLLABLE CWEO
+CDB1;CDB1;110E 116F 11A8;CDB1;110E 116F 11A8; # (춱; 춱; 춱; 춱; 춱; ) HANGUL SYLLABLE CWEOG
+CDB2;CDB2;110E 116F 11A9;CDB2;110E 116F 11A9; # (춲; 춲; 춲; 춲; 춲; ) HANGUL SYLLABLE CWEOGG
+CDB3;CDB3;110E 116F 11AA;CDB3;110E 116F 11AA; # (춳; 춳; 춳; 춳; 춳; ) HANGUL SYLLABLE CWEOGS
+CDB4;CDB4;110E 116F 11AB;CDB4;110E 116F 11AB; # (춴; 춴; 춴; 춴; 춴; ) HANGUL SYLLABLE CWEON
+CDB5;CDB5;110E 116F 11AC;CDB5;110E 116F 11AC; # (춵; 춵; 춵; 춵; 춵; ) HANGUL SYLLABLE CWEONJ
+CDB6;CDB6;110E 116F 11AD;CDB6;110E 116F 11AD; # (춶; 춶; 춶; 춶; 춶; ) HANGUL SYLLABLE CWEONH
+CDB7;CDB7;110E 116F 11AE;CDB7;110E 116F 11AE; # (춷; 춷; 춷; 춷; 춷; ) HANGUL SYLLABLE CWEOD
+CDB8;CDB8;110E 116F 11AF;CDB8;110E 116F 11AF; # (춸; 춸; 춸; 춸; 춸; ) HANGUL SYLLABLE CWEOL
+CDB9;CDB9;110E 116F 11B0;CDB9;110E 116F 11B0; # (춹; 춹; 춹; 춹; 춹; ) HANGUL SYLLABLE CWEOLG
+CDBA;CDBA;110E 116F 11B1;CDBA;110E 116F 11B1; # (춺; 춺; 춺; 춺; 춺; ) HANGUL SYLLABLE CWEOLM
+CDBB;CDBB;110E 116F 11B2;CDBB;110E 116F 11B2; # (춻; 춻; 춻; 춻; 춻; ) HANGUL SYLLABLE CWEOLB
+CDBC;CDBC;110E 116F 11B3;CDBC;110E 116F 11B3; # (춼; 춼; 춼; 춼; 춼; ) HANGUL SYLLABLE CWEOLS
+CDBD;CDBD;110E 116F 11B4;CDBD;110E 116F 11B4; # (춽; 춽; 춽; 춽; 춽; ) HANGUL SYLLABLE CWEOLT
+CDBE;CDBE;110E 116F 11B5;CDBE;110E 116F 11B5; # (춾; 춾; 춾; 춾; 춾; ) HANGUL SYLLABLE CWEOLP
+CDBF;CDBF;110E 116F 11B6;CDBF;110E 116F 11B6; # (춿; 춿; 춿; 춿; 춿; ) HANGUL SYLLABLE CWEOLH
+CDC0;CDC0;110E 116F 11B7;CDC0;110E 116F 11B7; # (췀; 췀; 췀; 췀; 췀; ) HANGUL SYLLABLE CWEOM
+CDC1;CDC1;110E 116F 11B8;CDC1;110E 116F 11B8; # (췁; 췁; 췁; 췁; 췁; ) HANGUL SYLLABLE CWEOB
+CDC2;CDC2;110E 116F 11B9;CDC2;110E 116F 11B9; # (췂; 췂; 췂; 췂; 췂; ) HANGUL SYLLABLE CWEOBS
+CDC3;CDC3;110E 116F 11BA;CDC3;110E 116F 11BA; # (췃; 췃; 췃; 췃; 췃; ) HANGUL SYLLABLE CWEOS
+CDC4;CDC4;110E 116F 11BB;CDC4;110E 116F 11BB; # (췄; 췄; 췄; 췄; 췄; ) HANGUL SYLLABLE CWEOSS
+CDC5;CDC5;110E 116F 11BC;CDC5;110E 116F 11BC; # (췅; 췅; 췅; 췅; 췅; ) HANGUL SYLLABLE CWEONG
+CDC6;CDC6;110E 116F 11BD;CDC6;110E 116F 11BD; # (췆; 췆; 췆; 췆; 췆; ) HANGUL SYLLABLE CWEOJ
+CDC7;CDC7;110E 116F 11BE;CDC7;110E 116F 11BE; # (췇; 췇; 췇; 췇; 췇; ) HANGUL SYLLABLE CWEOC
+CDC8;CDC8;110E 116F 11BF;CDC8;110E 116F 11BF; # (췈; 췈; 췈; 췈; 췈; ) HANGUL SYLLABLE CWEOK
+CDC9;CDC9;110E 116F 11C0;CDC9;110E 116F 11C0; # (췉; 췉; 췉; 췉; 췉; ) HANGUL SYLLABLE CWEOT
+CDCA;CDCA;110E 116F 11C1;CDCA;110E 116F 11C1; # (췊; 췊; 췊; 췊; 췊; ) HANGUL SYLLABLE CWEOP
+CDCB;CDCB;110E 116F 11C2;CDCB;110E 116F 11C2; # (췋; 췋; 췋; 췋; 췋; ) HANGUL SYLLABLE CWEOH
+CDCC;CDCC;110E 1170;CDCC;110E 1170; # (췌; 췌; 췌; 췌; 췌; ) HANGUL SYLLABLE CWE
+CDCD;CDCD;110E 1170 11A8;CDCD;110E 1170 11A8; # (췍; 췍; 췍; 췍; 췍; ) HANGUL SYLLABLE CWEG
+CDCE;CDCE;110E 1170 11A9;CDCE;110E 1170 11A9; # (췎; 췎; 췎; 췎; 췎; ) HANGUL SYLLABLE CWEGG
+CDCF;CDCF;110E 1170 11AA;CDCF;110E 1170 11AA; # (췏; 췏; 췏; 췏; 췏; ) HANGUL SYLLABLE CWEGS
+CDD0;CDD0;110E 1170 11AB;CDD0;110E 1170 11AB; # (췐; 췐; 췐; 췐; 췐; ) HANGUL SYLLABLE CWEN
+CDD1;CDD1;110E 1170 11AC;CDD1;110E 1170 11AC; # (췑; 췑; 췑; 췑; 췑; ) HANGUL SYLLABLE CWENJ
+CDD2;CDD2;110E 1170 11AD;CDD2;110E 1170 11AD; # (췒; 췒; 췒; 췒; 췒; ) HANGUL SYLLABLE CWENH
+CDD3;CDD3;110E 1170 11AE;CDD3;110E 1170 11AE; # (췓; 췓; 췓; 췓; 췓; ) HANGUL SYLLABLE CWED
+CDD4;CDD4;110E 1170 11AF;CDD4;110E 1170 11AF; # (췔; 췔; 췔; 췔; 췔; ) HANGUL SYLLABLE CWEL
+CDD5;CDD5;110E 1170 11B0;CDD5;110E 1170 11B0; # (췕; 췕; 췕; 췕; 췕; ) HANGUL SYLLABLE CWELG
+CDD6;CDD6;110E 1170 11B1;CDD6;110E 1170 11B1; # (췖; 췖; 췖; 췖; 췖; ) HANGUL SYLLABLE CWELM
+CDD7;CDD7;110E 1170 11B2;CDD7;110E 1170 11B2; # (췗; 췗; 췗; 췗; 췗; ) HANGUL SYLLABLE CWELB
+CDD8;CDD8;110E 1170 11B3;CDD8;110E 1170 11B3; # (췘; 췘; 췘; 췘; 췘; ) HANGUL SYLLABLE CWELS
+CDD9;CDD9;110E 1170 11B4;CDD9;110E 1170 11B4; # (췙; 췙; 췙; 췙; 췙; ) HANGUL SYLLABLE CWELT
+CDDA;CDDA;110E 1170 11B5;CDDA;110E 1170 11B5; # (췚; 췚; 췚; 췚; 췚; ) HANGUL SYLLABLE CWELP
+CDDB;CDDB;110E 1170 11B6;CDDB;110E 1170 11B6; # (췛; 췛; 췛; 췛; 췛; ) HANGUL SYLLABLE CWELH
+CDDC;CDDC;110E 1170 11B7;CDDC;110E 1170 11B7; # (췜; 췜; 췜; 췜; 췜; ) HANGUL SYLLABLE CWEM
+CDDD;CDDD;110E 1170 11B8;CDDD;110E 1170 11B8; # (췝; 췝; 췝; 췝; 췝; ) HANGUL SYLLABLE CWEB
+CDDE;CDDE;110E 1170 11B9;CDDE;110E 1170 11B9; # (췞; 췞; 췞; 췞; 췞; ) HANGUL SYLLABLE CWEBS
+CDDF;CDDF;110E 1170 11BA;CDDF;110E 1170 11BA; # (췟; 췟; 췟; 췟; 췟; ) HANGUL SYLLABLE CWES
+CDE0;CDE0;110E 1170 11BB;CDE0;110E 1170 11BB; # (췠; 췠; 췠; 췠; 췠; ) HANGUL SYLLABLE CWESS
+CDE1;CDE1;110E 1170 11BC;CDE1;110E 1170 11BC; # (췡; 췡; 췡; 췡; 췡; ) HANGUL SYLLABLE CWENG
+CDE2;CDE2;110E 1170 11BD;CDE2;110E 1170 11BD; # (췢; 췢; 췢; 췢; 췢; ) HANGUL SYLLABLE CWEJ
+CDE3;CDE3;110E 1170 11BE;CDE3;110E 1170 11BE; # (췣; 췣; 췣; 췣; 췣; ) HANGUL SYLLABLE CWEC
+CDE4;CDE4;110E 1170 11BF;CDE4;110E 1170 11BF; # (췤; 췤; 췤; 췤; 췤; ) HANGUL SYLLABLE CWEK
+CDE5;CDE5;110E 1170 11C0;CDE5;110E 1170 11C0; # (췥; 췥; 췥; 췥; 췥; ) HANGUL SYLLABLE CWET
+CDE6;CDE6;110E 1170 11C1;CDE6;110E 1170 11C1; # (췦; 췦; 췦; 췦; 췦; ) HANGUL SYLLABLE CWEP
+CDE7;CDE7;110E 1170 11C2;CDE7;110E 1170 11C2; # (췧; 췧; 췧; 췧; 췧; ) HANGUL SYLLABLE CWEH
+CDE8;CDE8;110E 1171;CDE8;110E 1171; # (취; 취; 취; 취; 취; ) HANGUL SYLLABLE CWI
+CDE9;CDE9;110E 1171 11A8;CDE9;110E 1171 11A8; # (췩; 췩; 췩; 췩; 췩; ) HANGUL SYLLABLE CWIG
+CDEA;CDEA;110E 1171 11A9;CDEA;110E 1171 11A9; # (췪; 췪; 췪; 췪; 췪; ) HANGUL SYLLABLE CWIGG
+CDEB;CDEB;110E 1171 11AA;CDEB;110E 1171 11AA; # (췫; 췫; 췫; 췫; 췫; ) HANGUL SYLLABLE CWIGS
+CDEC;CDEC;110E 1171 11AB;CDEC;110E 1171 11AB; # (췬; 췬; 췬; 췬; 췬; ) HANGUL SYLLABLE CWIN
+CDED;CDED;110E 1171 11AC;CDED;110E 1171 11AC; # (췭; 췭; 췭; 췭; 췭; ) HANGUL SYLLABLE CWINJ
+CDEE;CDEE;110E 1171 11AD;CDEE;110E 1171 11AD; # (췮; 췮; 췮; 췮; 췮; ) HANGUL SYLLABLE CWINH
+CDEF;CDEF;110E 1171 11AE;CDEF;110E 1171 11AE; # (췯; 췯; 췯; 췯; 췯; ) HANGUL SYLLABLE CWID
+CDF0;CDF0;110E 1171 11AF;CDF0;110E 1171 11AF; # (췰; 췰; 췰; 췰; 췰; ) HANGUL SYLLABLE CWIL
+CDF1;CDF1;110E 1171 11B0;CDF1;110E 1171 11B0; # (췱; 췱; 췱; 췱; 췱; ) HANGUL SYLLABLE CWILG
+CDF2;CDF2;110E 1171 11B1;CDF2;110E 1171 11B1; # (췲; 췲; 췲; 췲; 췲; ) HANGUL SYLLABLE CWILM
+CDF3;CDF3;110E 1171 11B2;CDF3;110E 1171 11B2; # (췳; 췳; 췳; 췳; 췳; ) HANGUL SYLLABLE CWILB
+CDF4;CDF4;110E 1171 11B3;CDF4;110E 1171 11B3; # (췴; 췴; 췴; 췴; 췴; ) HANGUL SYLLABLE CWILS
+CDF5;CDF5;110E 1171 11B4;CDF5;110E 1171 11B4; # (췵; 췵; 췵; 췵; 췵; ) HANGUL SYLLABLE CWILT
+CDF6;CDF6;110E 1171 11B5;CDF6;110E 1171 11B5; # (췶; 췶; 췶; 췶; 췶; ) HANGUL SYLLABLE CWILP
+CDF7;CDF7;110E 1171 11B6;CDF7;110E 1171 11B6; # (췷; 췷; 췷; 췷; 췷; ) HANGUL SYLLABLE CWILH
+CDF8;CDF8;110E 1171 11B7;CDF8;110E 1171 11B7; # (췸; 췸; 췸; 췸; 췸; ) HANGUL SYLLABLE CWIM
+CDF9;CDF9;110E 1171 11B8;CDF9;110E 1171 11B8; # (췹; 췹; 췹; 췹; 췹; ) HANGUL SYLLABLE CWIB
+CDFA;CDFA;110E 1171 11B9;CDFA;110E 1171 11B9; # (췺; 췺; 췺; 췺; 췺; ) HANGUL SYLLABLE CWIBS
+CDFB;CDFB;110E 1171 11BA;CDFB;110E 1171 11BA; # (췻; 췻; 췻; 췻; 췻; ) HANGUL SYLLABLE CWIS
+CDFC;CDFC;110E 1171 11BB;CDFC;110E 1171 11BB; # (췼; 췼; 췼; 췼; 췼; ) HANGUL SYLLABLE CWISS
+CDFD;CDFD;110E 1171 11BC;CDFD;110E 1171 11BC; # (췽; 췽; 췽; 췽; 췽; ) HANGUL SYLLABLE CWING
+CDFE;CDFE;110E 1171 11BD;CDFE;110E 1171 11BD; # (췾; 췾; 췾; 췾; 췾; ) HANGUL SYLLABLE CWIJ
+CDFF;CDFF;110E 1171 11BE;CDFF;110E 1171 11BE; # (췿; 췿; 췿; 췿; 췿; ) HANGUL SYLLABLE CWIC
+CE00;CE00;110E 1171 11BF;CE00;110E 1171 11BF; # (츀; 츀; 츀; 츀; 츀; ) HANGUL SYLLABLE CWIK
+CE01;CE01;110E 1171 11C0;CE01;110E 1171 11C0; # (츁; 츁; 츁; 츁; 츁; ) HANGUL SYLLABLE CWIT
+CE02;CE02;110E 1171 11C1;CE02;110E 1171 11C1; # (츂; 츂; 츂; 츂; 츂; ) HANGUL SYLLABLE CWIP
+CE03;CE03;110E 1171 11C2;CE03;110E 1171 11C2; # (츃; 츃; 츃; 츃; 츃; ) HANGUL SYLLABLE CWIH
+CE04;CE04;110E 1172;CE04;110E 1172; # (츄; 츄; 츄; 츄; 츄; ) HANGUL SYLLABLE CYU
+CE05;CE05;110E 1172 11A8;CE05;110E 1172 11A8; # (츅; 츅; 츅; 츅; 츅; ) HANGUL SYLLABLE CYUG
+CE06;CE06;110E 1172 11A9;CE06;110E 1172 11A9; # (츆; 츆; 츆; 츆; 츆; ) HANGUL SYLLABLE CYUGG
+CE07;CE07;110E 1172 11AA;CE07;110E 1172 11AA; # (츇; 츇; 츇; 츇; 츇; ) HANGUL SYLLABLE CYUGS
+CE08;CE08;110E 1172 11AB;CE08;110E 1172 11AB; # (츈; 츈; 츈; 츈; 츈; ) HANGUL SYLLABLE CYUN
+CE09;CE09;110E 1172 11AC;CE09;110E 1172 11AC; # (츉; 츉; 츉; 츉; 츉; ) HANGUL SYLLABLE CYUNJ
+CE0A;CE0A;110E 1172 11AD;CE0A;110E 1172 11AD; # (츊; 츊; 츊; 츊; 츊; ) HANGUL SYLLABLE CYUNH
+CE0B;CE0B;110E 1172 11AE;CE0B;110E 1172 11AE; # (츋; 츋; 츋; 츋; 츋; ) HANGUL SYLLABLE CYUD
+CE0C;CE0C;110E 1172 11AF;CE0C;110E 1172 11AF; # (츌; 츌; 츌; 츌; 츌; ) HANGUL SYLLABLE CYUL
+CE0D;CE0D;110E 1172 11B0;CE0D;110E 1172 11B0; # (츍; 츍; 츍; 츍; 츍; ) HANGUL SYLLABLE CYULG
+CE0E;CE0E;110E 1172 11B1;CE0E;110E 1172 11B1; # (츎; 츎; 츎; 츎; 츎; ) HANGUL SYLLABLE CYULM
+CE0F;CE0F;110E 1172 11B2;CE0F;110E 1172 11B2; # (츏; 츏; 츏; 츏; 츏; ) HANGUL SYLLABLE CYULB
+CE10;CE10;110E 1172 11B3;CE10;110E 1172 11B3; # (츐; 츐; 츐; 츐; 츐; ) HANGUL SYLLABLE CYULS
+CE11;CE11;110E 1172 11B4;CE11;110E 1172 11B4; # (츑; 츑; 츑; 츑; 츑; ) HANGUL SYLLABLE CYULT
+CE12;CE12;110E 1172 11B5;CE12;110E 1172 11B5; # (츒; 츒; 츒; 츒; 츒; ) HANGUL SYLLABLE CYULP
+CE13;CE13;110E 1172 11B6;CE13;110E 1172 11B6; # (츓; 츓; 츓; 츓; 츓; ) HANGUL SYLLABLE CYULH
+CE14;CE14;110E 1172 11B7;CE14;110E 1172 11B7; # (츔; 츔; 츔; 츔; 츔; ) HANGUL SYLLABLE CYUM
+CE15;CE15;110E 1172 11B8;CE15;110E 1172 11B8; # (츕; 츕; 츕; 츕; 츕; ) HANGUL SYLLABLE CYUB
+CE16;CE16;110E 1172 11B9;CE16;110E 1172 11B9; # (츖; 츖; 츖; 츖; 츖; ) HANGUL SYLLABLE CYUBS
+CE17;CE17;110E 1172 11BA;CE17;110E 1172 11BA; # (츗; 츗; 츗; 츗; 츗; ) HANGUL SYLLABLE CYUS
+CE18;CE18;110E 1172 11BB;CE18;110E 1172 11BB; # (츘; 츘; 츘; 츘; 츘; ) HANGUL SYLLABLE CYUSS
+CE19;CE19;110E 1172 11BC;CE19;110E 1172 11BC; # (츙; 츙; 츙; 츙; 츙; ) HANGUL SYLLABLE CYUNG
+CE1A;CE1A;110E 1172 11BD;CE1A;110E 1172 11BD; # (츚; 츚; 츚; 츚; 츚; ) HANGUL SYLLABLE CYUJ
+CE1B;CE1B;110E 1172 11BE;CE1B;110E 1172 11BE; # (츛; 츛; 츛; 츛; 츛; ) HANGUL SYLLABLE CYUC
+CE1C;CE1C;110E 1172 11BF;CE1C;110E 1172 11BF; # (츜; 츜; 츜; 츜; 츜; ) HANGUL SYLLABLE CYUK
+CE1D;CE1D;110E 1172 11C0;CE1D;110E 1172 11C0; # (츝; 츝; 츝; 츝; 츝; ) HANGUL SYLLABLE CYUT
+CE1E;CE1E;110E 1172 11C1;CE1E;110E 1172 11C1; # (츞; 츞; 츞; 츞; 츞; ) HANGUL SYLLABLE CYUP
+CE1F;CE1F;110E 1172 11C2;CE1F;110E 1172 11C2; # (츟; 츟; 츟; 츟; 츟; ) HANGUL SYLLABLE CYUH
+CE20;CE20;110E 1173;CE20;110E 1173; # (츠; 츠; 츠; 츠; 츠; ) HANGUL SYLLABLE CEU
+CE21;CE21;110E 1173 11A8;CE21;110E 1173 11A8; # (측; 측; 측; 측; 측; ) HANGUL SYLLABLE CEUG
+CE22;CE22;110E 1173 11A9;CE22;110E 1173 11A9; # (츢; 츢; 츢; 츢; 츢; ) HANGUL SYLLABLE CEUGG
+CE23;CE23;110E 1173 11AA;CE23;110E 1173 11AA; # (츣; 츣; 츣; 츣; 츣; ) HANGUL SYLLABLE CEUGS
+CE24;CE24;110E 1173 11AB;CE24;110E 1173 11AB; # (츤; 츤; 츤; 츤; 츤; ) HANGUL SYLLABLE CEUN
+CE25;CE25;110E 1173 11AC;CE25;110E 1173 11AC; # (츥; 츥; 츥; 츥; 츥; ) HANGUL SYLLABLE CEUNJ
+CE26;CE26;110E 1173 11AD;CE26;110E 1173 11AD; # (츦; 츦; 츦; 츦; 츦; ) HANGUL SYLLABLE CEUNH
+CE27;CE27;110E 1173 11AE;CE27;110E 1173 11AE; # (츧; 츧; 츧; 츧; 츧; ) HANGUL SYLLABLE CEUD
+CE28;CE28;110E 1173 11AF;CE28;110E 1173 11AF; # (츨; 츨; 츨; 츨; 츨; ) HANGUL SYLLABLE CEUL
+CE29;CE29;110E 1173 11B0;CE29;110E 1173 11B0; # (츩; 츩; 츩; 츩; 츩; ) HANGUL SYLLABLE CEULG
+CE2A;CE2A;110E 1173 11B1;CE2A;110E 1173 11B1; # (츪; 츪; 츪; 츪; 츪; ) HANGUL SYLLABLE CEULM
+CE2B;CE2B;110E 1173 11B2;CE2B;110E 1173 11B2; # (츫; 츫; 츫; 츫; 츫; ) HANGUL SYLLABLE CEULB
+CE2C;CE2C;110E 1173 11B3;CE2C;110E 1173 11B3; # (츬; 츬; 츬; 츬; 츬; ) HANGUL SYLLABLE CEULS
+CE2D;CE2D;110E 1173 11B4;CE2D;110E 1173 11B4; # (츭; 츭; 츭; 츭; 츭; ) HANGUL SYLLABLE CEULT
+CE2E;CE2E;110E 1173 11B5;CE2E;110E 1173 11B5; # (츮; 츮; 츮; 츮; 츮; ) HANGUL SYLLABLE CEULP
+CE2F;CE2F;110E 1173 11B6;CE2F;110E 1173 11B6; # (츯; 츯; 츯; 츯; 츯; ) HANGUL SYLLABLE CEULH
+CE30;CE30;110E 1173 11B7;CE30;110E 1173 11B7; # (츰; 츰; 츰; 츰; 츰; ) HANGUL SYLLABLE CEUM
+CE31;CE31;110E 1173 11B8;CE31;110E 1173 11B8; # (츱; 츱; 츱; 츱; 츱; ) HANGUL SYLLABLE CEUB
+CE32;CE32;110E 1173 11B9;CE32;110E 1173 11B9; # (츲; 츲; 츲; 츲; 츲; ) HANGUL SYLLABLE CEUBS
+CE33;CE33;110E 1173 11BA;CE33;110E 1173 11BA; # (츳; 츳; 츳; 츳; 츳; ) HANGUL SYLLABLE CEUS
+CE34;CE34;110E 1173 11BB;CE34;110E 1173 11BB; # (츴; 츴; 츴; 츴; 츴; ) HANGUL SYLLABLE CEUSS
+CE35;CE35;110E 1173 11BC;CE35;110E 1173 11BC; # (층; 층; 층; 층; 층; ) HANGUL SYLLABLE CEUNG
+CE36;CE36;110E 1173 11BD;CE36;110E 1173 11BD; # (츶; 츶; 츶; 츶; 츶; ) HANGUL SYLLABLE CEUJ
+CE37;CE37;110E 1173 11BE;CE37;110E 1173 11BE; # (츷; 츷; 츷; 츷; 츷; ) HANGUL SYLLABLE CEUC
+CE38;CE38;110E 1173 11BF;CE38;110E 1173 11BF; # (츸; 츸; 츸; 츸; 츸; ) HANGUL SYLLABLE CEUK
+CE39;CE39;110E 1173 11C0;CE39;110E 1173 11C0; # (츹; 츹; 츹; 츹; 츹; ) HANGUL SYLLABLE CEUT
+CE3A;CE3A;110E 1173 11C1;CE3A;110E 1173 11C1; # (츺; 츺; 츺; 츺; 츺; ) HANGUL SYLLABLE CEUP
+CE3B;CE3B;110E 1173 11C2;CE3B;110E 1173 11C2; # (츻; 츻; 츻; 츻; 츻; ) HANGUL SYLLABLE CEUH
+CE3C;CE3C;110E 1174;CE3C;110E 1174; # (츼; 츼; 츼; 츼; 츼; ) HANGUL SYLLABLE CYI
+CE3D;CE3D;110E 1174 11A8;CE3D;110E 1174 11A8; # (츽; 츽; 츽; 츽; 츽; ) HANGUL SYLLABLE CYIG
+CE3E;CE3E;110E 1174 11A9;CE3E;110E 1174 11A9; # (츾; 츾; 츾; 츾; 츾; ) HANGUL SYLLABLE CYIGG
+CE3F;CE3F;110E 1174 11AA;CE3F;110E 1174 11AA; # (츿; 츿; 츿; 츿; 츿; ) HANGUL SYLLABLE CYIGS
+CE40;CE40;110E 1174 11AB;CE40;110E 1174 11AB; # (칀; 칀; 칀; 칀; 칀; ) HANGUL SYLLABLE CYIN
+CE41;CE41;110E 1174 11AC;CE41;110E 1174 11AC; # (칁; 칁; 칁; 칁; 칁; ) HANGUL SYLLABLE CYINJ
+CE42;CE42;110E 1174 11AD;CE42;110E 1174 11AD; # (칂; 칂; 칂; 칂; 칂; ) HANGUL SYLLABLE CYINH
+CE43;CE43;110E 1174 11AE;CE43;110E 1174 11AE; # (칃; 칃; 칃; 칃; 칃; ) HANGUL SYLLABLE CYID
+CE44;CE44;110E 1174 11AF;CE44;110E 1174 11AF; # (칄; 칄; 칄; 칄; 칄; ) HANGUL SYLLABLE CYIL
+CE45;CE45;110E 1174 11B0;CE45;110E 1174 11B0; # (칅; 칅; 칅; 칅; 칅; ) HANGUL SYLLABLE CYILG
+CE46;CE46;110E 1174 11B1;CE46;110E 1174 11B1; # (칆; 칆; 칆; 칆; 칆; ) HANGUL SYLLABLE CYILM
+CE47;CE47;110E 1174 11B2;CE47;110E 1174 11B2; # (칇; 칇; 칇; 칇; 칇; ) HANGUL SYLLABLE CYILB
+CE48;CE48;110E 1174 11B3;CE48;110E 1174 11B3; # (칈; 칈; 칈; 칈; 칈; ) HANGUL SYLLABLE CYILS
+CE49;CE49;110E 1174 11B4;CE49;110E 1174 11B4; # (칉; 칉; 칉; 칉; 칉; ) HANGUL SYLLABLE CYILT
+CE4A;CE4A;110E 1174 11B5;CE4A;110E 1174 11B5; # (칊; 칊; 칊; 칊; 칊; ) HANGUL SYLLABLE CYILP
+CE4B;CE4B;110E 1174 11B6;CE4B;110E 1174 11B6; # (칋; 칋; 칋; 칋; 칋; ) HANGUL SYLLABLE CYILH
+CE4C;CE4C;110E 1174 11B7;CE4C;110E 1174 11B7; # (칌; 칌; 칌; 칌; 칌; ) HANGUL SYLLABLE CYIM
+CE4D;CE4D;110E 1174 11B8;CE4D;110E 1174 11B8; # (칍; 칍; 칍; 칍; 칍; ) HANGUL SYLLABLE CYIB
+CE4E;CE4E;110E 1174 11B9;CE4E;110E 1174 11B9; # (칎; 칎; 칎; 칎; 칎; ) HANGUL SYLLABLE CYIBS
+CE4F;CE4F;110E 1174 11BA;CE4F;110E 1174 11BA; # (칏; 칏; 칏; 칏; 칏; ) HANGUL SYLLABLE CYIS
+CE50;CE50;110E 1174 11BB;CE50;110E 1174 11BB; # (칐; 칐; 칐; 칐; 칐; ) HANGUL SYLLABLE CYISS
+CE51;CE51;110E 1174 11BC;CE51;110E 1174 11BC; # (칑; 칑; 칑; 칑; 칑; ) HANGUL SYLLABLE CYING
+CE52;CE52;110E 1174 11BD;CE52;110E 1174 11BD; # (칒; 칒; 칒; 칒; 칒; ) HANGUL SYLLABLE CYIJ
+CE53;CE53;110E 1174 11BE;CE53;110E 1174 11BE; # (칓; 칓; 칓; 칓; 칓; ) HANGUL SYLLABLE CYIC
+CE54;CE54;110E 1174 11BF;CE54;110E 1174 11BF; # (칔; 칔; 칔; 칔; 칔; ) HANGUL SYLLABLE CYIK
+CE55;CE55;110E 1174 11C0;CE55;110E 1174 11C0; # (칕; 칕; 칕; 칕; 칕; ) HANGUL SYLLABLE CYIT
+CE56;CE56;110E 1174 11C1;CE56;110E 1174 11C1; # (칖; 칖; 칖; 칖; 칖; ) HANGUL SYLLABLE CYIP
+CE57;CE57;110E 1174 11C2;CE57;110E 1174 11C2; # (칗; 칗; 칗; 칗; 칗; ) HANGUL SYLLABLE CYIH
+CE58;CE58;110E 1175;CE58;110E 1175; # (치; 치; 치; 치; 치; ) HANGUL SYLLABLE CI
+CE59;CE59;110E 1175 11A8;CE59;110E 1175 11A8; # (칙; 칙; 칙; 칙; 칙; ) HANGUL SYLLABLE CIG
+CE5A;CE5A;110E 1175 11A9;CE5A;110E 1175 11A9; # (칚; 칚; 칚; 칚; 칚; ) HANGUL SYLLABLE CIGG
+CE5B;CE5B;110E 1175 11AA;CE5B;110E 1175 11AA; # (칛; 칛; 칛; 칛; 칛; ) HANGUL SYLLABLE CIGS
+CE5C;CE5C;110E 1175 11AB;CE5C;110E 1175 11AB; # (친; 친; 친; 친; 친; ) HANGUL SYLLABLE CIN
+CE5D;CE5D;110E 1175 11AC;CE5D;110E 1175 11AC; # (칝; 칝; 칝; 칝; 칝; ) HANGUL SYLLABLE CINJ
+CE5E;CE5E;110E 1175 11AD;CE5E;110E 1175 11AD; # (칞; 칞; 칞; 칞; 칞; ) HANGUL SYLLABLE CINH
+CE5F;CE5F;110E 1175 11AE;CE5F;110E 1175 11AE; # (칟; 칟; 칟; 칟; 칟; ) HANGUL SYLLABLE CID
+CE60;CE60;110E 1175 11AF;CE60;110E 1175 11AF; # (칠; 칠; 칠; 칠; 칠; ) HANGUL SYLLABLE CIL
+CE61;CE61;110E 1175 11B0;CE61;110E 1175 11B0; # (칡; 칡; 칡; 칡; 칡; ) HANGUL SYLLABLE CILG
+CE62;CE62;110E 1175 11B1;CE62;110E 1175 11B1; # (칢; 칢; 칢; 칢; 칢; ) HANGUL SYLLABLE CILM
+CE63;CE63;110E 1175 11B2;CE63;110E 1175 11B2; # (칣; 칣; 칣; 칣; 칣; ) HANGUL SYLLABLE CILB
+CE64;CE64;110E 1175 11B3;CE64;110E 1175 11B3; # (칤; 칤; 칤; 칤; 칤; ) HANGUL SYLLABLE CILS
+CE65;CE65;110E 1175 11B4;CE65;110E 1175 11B4; # (칥; 칥; 칥; 칥; 칥; ) HANGUL SYLLABLE CILT
+CE66;CE66;110E 1175 11B5;CE66;110E 1175 11B5; # (칦; 칦; 칦; 칦; 칦; ) HANGUL SYLLABLE CILP
+CE67;CE67;110E 1175 11B6;CE67;110E 1175 11B6; # (칧; 칧; 칧; 칧; 칧; ) HANGUL SYLLABLE CILH
+CE68;CE68;110E 1175 11B7;CE68;110E 1175 11B7; # (침; 침; 침; 침; 침; ) HANGUL SYLLABLE CIM
+CE69;CE69;110E 1175 11B8;CE69;110E 1175 11B8; # (칩; 칩; 칩; 칩; 칩; ) HANGUL SYLLABLE CIB
+CE6A;CE6A;110E 1175 11B9;CE6A;110E 1175 11B9; # (칪; 칪; 칪; 칪; 칪; ) HANGUL SYLLABLE CIBS
+CE6B;CE6B;110E 1175 11BA;CE6B;110E 1175 11BA; # (칫; 칫; 칫; 칫; 칫; ) HANGUL SYLLABLE CIS
+CE6C;CE6C;110E 1175 11BB;CE6C;110E 1175 11BB; # (칬; 칬; 칬; 칬; 칬; ) HANGUL SYLLABLE CISS
+CE6D;CE6D;110E 1175 11BC;CE6D;110E 1175 11BC; # (칭; 칭; 칭; 칭; 칭; ) HANGUL SYLLABLE CING
+CE6E;CE6E;110E 1175 11BD;CE6E;110E 1175 11BD; # (칮; 칮; 칮; 칮; 칮; ) HANGUL SYLLABLE CIJ
+CE6F;CE6F;110E 1175 11BE;CE6F;110E 1175 11BE; # (칯; 칯; 칯; 칯; 칯; ) HANGUL SYLLABLE CIC
+CE70;CE70;110E 1175 11BF;CE70;110E 1175 11BF; # (칰; 칰; 칰; 칰; 칰; ) HANGUL SYLLABLE CIK
+CE71;CE71;110E 1175 11C0;CE71;110E 1175 11C0; # (칱; 칱; 칱; 칱; 칱; ) HANGUL SYLLABLE CIT
+CE72;CE72;110E 1175 11C1;CE72;110E 1175 11C1; # (칲; 칲; 칲; 칲; 칲; ) HANGUL SYLLABLE CIP
+CE73;CE73;110E 1175 11C2;CE73;110E 1175 11C2; # (칳; 칳; 칳; 칳; 칳; ) HANGUL SYLLABLE CIH
+CE74;CE74;110F 1161;CE74;110F 1161; # (카; 카; 카; 카; 카; ) HANGUL SYLLABLE KA
+CE75;CE75;110F 1161 11A8;CE75;110F 1161 11A8; # (칵; 칵; 칵; 칵; 칵; ) HANGUL SYLLABLE KAG
+CE76;CE76;110F 1161 11A9;CE76;110F 1161 11A9; # (칶; 칶; 칶; 칶; 칶; ) HANGUL SYLLABLE KAGG
+CE77;CE77;110F 1161 11AA;CE77;110F 1161 11AA; # (칷; 칷; 칷; 칷; 칷; ) HANGUL SYLLABLE KAGS
+CE78;CE78;110F 1161 11AB;CE78;110F 1161 11AB; # (칸; 칸; 칸; 칸; 칸; ) HANGUL SYLLABLE KAN
+CE79;CE79;110F 1161 11AC;CE79;110F 1161 11AC; # (칹; 칹; 칹; 칹; 칹; ) HANGUL SYLLABLE KANJ
+CE7A;CE7A;110F 1161 11AD;CE7A;110F 1161 11AD; # (칺; 칺; 칺; 칺; 칺; ) HANGUL SYLLABLE KANH
+CE7B;CE7B;110F 1161 11AE;CE7B;110F 1161 11AE; # (칻; 칻; 칻; 칻; 칻; ) HANGUL SYLLABLE KAD
+CE7C;CE7C;110F 1161 11AF;CE7C;110F 1161 11AF; # (칼; 칼; 칼; 칼; 칼; ) HANGUL SYLLABLE KAL
+CE7D;CE7D;110F 1161 11B0;CE7D;110F 1161 11B0; # (칽; 칽; 칽; 칽; 칽; ) HANGUL SYLLABLE KALG
+CE7E;CE7E;110F 1161 11B1;CE7E;110F 1161 11B1; # (칾; 칾; 칾; 칾; 칾; ) HANGUL SYLLABLE KALM
+CE7F;CE7F;110F 1161 11B2;CE7F;110F 1161 11B2; # (칿; 칿; 칿; 칿; 칿; ) HANGUL SYLLABLE KALB
+CE80;CE80;110F 1161 11B3;CE80;110F 1161 11B3; # (캀; 캀; 캀; 캀; 캀; ) HANGUL SYLLABLE KALS
+CE81;CE81;110F 1161 11B4;CE81;110F 1161 11B4; # (캁; 캁; 캁; 캁; 캁; ) HANGUL SYLLABLE KALT
+CE82;CE82;110F 1161 11B5;CE82;110F 1161 11B5; # (캂; 캂; 캂; 캂; 캂; ) HANGUL SYLLABLE KALP
+CE83;CE83;110F 1161 11B6;CE83;110F 1161 11B6; # (캃; 캃; 캃; 캃; 캃; ) HANGUL SYLLABLE KALH
+CE84;CE84;110F 1161 11B7;CE84;110F 1161 11B7; # (캄; 캄; 캄; 캄; 캄; ) HANGUL SYLLABLE KAM
+CE85;CE85;110F 1161 11B8;CE85;110F 1161 11B8; # (캅; 캅; 캅; 캅; 캅; ) HANGUL SYLLABLE KAB
+CE86;CE86;110F 1161 11B9;CE86;110F 1161 11B9; # (캆; 캆; 캆; 캆; 캆; ) HANGUL SYLLABLE KABS
+CE87;CE87;110F 1161 11BA;CE87;110F 1161 11BA; # (캇; 캇; 캇; 캇; 캇; ) HANGUL SYLLABLE KAS
+CE88;CE88;110F 1161 11BB;CE88;110F 1161 11BB; # (캈; 캈; 캈; 캈; 캈; ) HANGUL SYLLABLE KASS
+CE89;CE89;110F 1161 11BC;CE89;110F 1161 11BC; # (캉; 캉; 캉; 캉; 캉; ) HANGUL SYLLABLE KANG
+CE8A;CE8A;110F 1161 11BD;CE8A;110F 1161 11BD; # (캊; 캊; 캊; 캊; 캊; ) HANGUL SYLLABLE KAJ
+CE8B;CE8B;110F 1161 11BE;CE8B;110F 1161 11BE; # (캋; 캋; 캋; 캋; 캋; ) HANGUL SYLLABLE KAC
+CE8C;CE8C;110F 1161 11BF;CE8C;110F 1161 11BF; # (캌; 캌; 캌; 캌; 캌; ) HANGUL SYLLABLE KAK
+CE8D;CE8D;110F 1161 11C0;CE8D;110F 1161 11C0; # (캍; 캍; 캍; 캍; 캍; ) HANGUL SYLLABLE KAT
+CE8E;CE8E;110F 1161 11C1;CE8E;110F 1161 11C1; # (캎; 캎; 캎; 캎; 캎; ) HANGUL SYLLABLE KAP
+CE8F;CE8F;110F 1161 11C2;CE8F;110F 1161 11C2; # (캏; 캏; 캏; 캏; 캏; ) HANGUL SYLLABLE KAH
+CE90;CE90;110F 1162;CE90;110F 1162; # (캐; 캐; 캐; 캐; 캐; ) HANGUL SYLLABLE KAE
+CE91;CE91;110F 1162 11A8;CE91;110F 1162 11A8; # (캑; 캑; 캑; 캑; 캑; ) HANGUL SYLLABLE KAEG
+CE92;CE92;110F 1162 11A9;CE92;110F 1162 11A9; # (캒; 캒; 캒; 캒; 캒; ) HANGUL SYLLABLE KAEGG
+CE93;CE93;110F 1162 11AA;CE93;110F 1162 11AA; # (캓; 캓; 캓; 캓; 캓; ) HANGUL SYLLABLE KAEGS
+CE94;CE94;110F 1162 11AB;CE94;110F 1162 11AB; # (캔; 캔; 캔; 캔; 캔; ) HANGUL SYLLABLE KAEN
+CE95;CE95;110F 1162 11AC;CE95;110F 1162 11AC; # (캕; 캕; 캕; 캕; 캕; ) HANGUL SYLLABLE KAENJ
+CE96;CE96;110F 1162 11AD;CE96;110F 1162 11AD; # (캖; 캖; 캖; 캖; 캖; ) HANGUL SYLLABLE KAENH
+CE97;CE97;110F 1162 11AE;CE97;110F 1162 11AE; # (캗; 캗; 캗; 캗; 캗; ) HANGUL SYLLABLE KAED
+CE98;CE98;110F 1162 11AF;CE98;110F 1162 11AF; # (캘; 캘; 캘; 캘; 캘; ) HANGUL SYLLABLE KAEL
+CE99;CE99;110F 1162 11B0;CE99;110F 1162 11B0; # (캙; 캙; 캙; 캙; 캙; ) HANGUL SYLLABLE KAELG
+CE9A;CE9A;110F 1162 11B1;CE9A;110F 1162 11B1; # (캚; 캚; 캚; 캚; 캚; ) HANGUL SYLLABLE KAELM
+CE9B;CE9B;110F 1162 11B2;CE9B;110F 1162 11B2; # (캛; 캛; 캛; 캛; 캛; ) HANGUL SYLLABLE KAELB
+CE9C;CE9C;110F 1162 11B3;CE9C;110F 1162 11B3; # (캜; 캜; 캜; 캜; 캜; ) HANGUL SYLLABLE KAELS
+CE9D;CE9D;110F 1162 11B4;CE9D;110F 1162 11B4; # (캝; 캝; 캝; 캝; 캝; ) HANGUL SYLLABLE KAELT
+CE9E;CE9E;110F 1162 11B5;CE9E;110F 1162 11B5; # (캞; 캞; 캞; 캞; 캞; ) HANGUL SYLLABLE KAELP
+CE9F;CE9F;110F 1162 11B6;CE9F;110F 1162 11B6; # (캟; 캟; 캟; 캟; 캟; ) HANGUL SYLLABLE KAELH
+CEA0;CEA0;110F 1162 11B7;CEA0;110F 1162 11B7; # (캠; 캠; 캠; 캠; 캠; ) HANGUL SYLLABLE KAEM
+CEA1;CEA1;110F 1162 11B8;CEA1;110F 1162 11B8; # (캡; 캡; 캡; 캡; 캡; ) HANGUL SYLLABLE KAEB
+CEA2;CEA2;110F 1162 11B9;CEA2;110F 1162 11B9; # (캢; 캢; 캢; 캢; 캢; ) HANGUL SYLLABLE KAEBS
+CEA3;CEA3;110F 1162 11BA;CEA3;110F 1162 11BA; # (캣; 캣; 캣; 캣; 캣; ) HANGUL SYLLABLE KAES
+CEA4;CEA4;110F 1162 11BB;CEA4;110F 1162 11BB; # (캤; 캤; 캤; 캤; 캤; ) HANGUL SYLLABLE KAESS
+CEA5;CEA5;110F 1162 11BC;CEA5;110F 1162 11BC; # (캥; 캥; 캥; 캥; 캥; ) HANGUL SYLLABLE KAENG
+CEA6;CEA6;110F 1162 11BD;CEA6;110F 1162 11BD; # (캦; 캦; 캦; 캦; 캦; ) HANGUL SYLLABLE KAEJ
+CEA7;CEA7;110F 1162 11BE;CEA7;110F 1162 11BE; # (캧; 캧; 캧; 캧; 캧; ) HANGUL SYLLABLE KAEC
+CEA8;CEA8;110F 1162 11BF;CEA8;110F 1162 11BF; # (캨; 캨; 캨; 캨; 캨; ) HANGUL SYLLABLE KAEK
+CEA9;CEA9;110F 1162 11C0;CEA9;110F 1162 11C0; # (캩; 캩; 캩; 캩; 캩; ) HANGUL SYLLABLE KAET
+CEAA;CEAA;110F 1162 11C1;CEAA;110F 1162 11C1; # (캪; 캪; 캪; 캪; 캪; ) HANGUL SYLLABLE KAEP
+CEAB;CEAB;110F 1162 11C2;CEAB;110F 1162 11C2; # (캫; 캫; 캫; 캫; 캫; ) HANGUL SYLLABLE KAEH
+CEAC;CEAC;110F 1163;CEAC;110F 1163; # (캬; 캬; 캬; 캬; 캬; ) HANGUL SYLLABLE KYA
+CEAD;CEAD;110F 1163 11A8;CEAD;110F 1163 11A8; # (캭; 캭; 캭; 캭; 캭; ) HANGUL SYLLABLE KYAG
+CEAE;CEAE;110F 1163 11A9;CEAE;110F 1163 11A9; # (캮; 캮; 캮; 캮; 캮; ) HANGUL SYLLABLE KYAGG
+CEAF;CEAF;110F 1163 11AA;CEAF;110F 1163 11AA; # (캯; 캯; 캯; 캯; 캯; ) HANGUL SYLLABLE KYAGS
+CEB0;CEB0;110F 1163 11AB;CEB0;110F 1163 11AB; # (캰; 캰; 캰; 캰; 캰; ) HANGUL SYLLABLE KYAN
+CEB1;CEB1;110F 1163 11AC;CEB1;110F 1163 11AC; # (캱; 캱; 캱; 캱; 캱; ) HANGUL SYLLABLE KYANJ
+CEB2;CEB2;110F 1163 11AD;CEB2;110F 1163 11AD; # (캲; 캲; 캲; 캲; 캲; ) HANGUL SYLLABLE KYANH
+CEB3;CEB3;110F 1163 11AE;CEB3;110F 1163 11AE; # (캳; 캳; 캳; 캳; 캳; ) HANGUL SYLLABLE KYAD
+CEB4;CEB4;110F 1163 11AF;CEB4;110F 1163 11AF; # (캴; 캴; 캴; 캴; 캴; ) HANGUL SYLLABLE KYAL
+CEB5;CEB5;110F 1163 11B0;CEB5;110F 1163 11B0; # (캵; 캵; 캵; 캵; 캵; ) HANGUL SYLLABLE KYALG
+CEB6;CEB6;110F 1163 11B1;CEB6;110F 1163 11B1; # (캶; 캶; 캶; 캶; 캶; ) HANGUL SYLLABLE KYALM
+CEB7;CEB7;110F 1163 11B2;CEB7;110F 1163 11B2; # (캷; 캷; 캷; 캷; 캷; ) HANGUL SYLLABLE KYALB
+CEB8;CEB8;110F 1163 11B3;CEB8;110F 1163 11B3; # (캸; 캸; 캸; 캸; 캸; ) HANGUL SYLLABLE KYALS
+CEB9;CEB9;110F 1163 11B4;CEB9;110F 1163 11B4; # (캹; 캹; 캹; 캹; 캹; ) HANGUL SYLLABLE KYALT
+CEBA;CEBA;110F 1163 11B5;CEBA;110F 1163 11B5; # (캺; 캺; 캺; 캺; 캺; ) HANGUL SYLLABLE KYALP
+CEBB;CEBB;110F 1163 11B6;CEBB;110F 1163 11B6; # (캻; 캻; 캻; 캻; 캻; ) HANGUL SYLLABLE KYALH
+CEBC;CEBC;110F 1163 11B7;CEBC;110F 1163 11B7; # (캼; 캼; 캼; 캼; 캼; ) HANGUL SYLLABLE KYAM
+CEBD;CEBD;110F 1163 11B8;CEBD;110F 1163 11B8; # (캽; 캽; 캽; 캽; 캽; ) HANGUL SYLLABLE KYAB
+CEBE;CEBE;110F 1163 11B9;CEBE;110F 1163 11B9; # (캾; 캾; 캾; 캾; 캾; ) HANGUL SYLLABLE KYABS
+CEBF;CEBF;110F 1163 11BA;CEBF;110F 1163 11BA; # (캿; 캿; 캿; 캿; 캿; ) HANGUL SYLLABLE KYAS
+CEC0;CEC0;110F 1163 11BB;CEC0;110F 1163 11BB; # (컀; 컀; 컀; 컀; 컀; ) HANGUL SYLLABLE KYASS
+CEC1;CEC1;110F 1163 11BC;CEC1;110F 1163 11BC; # (컁; 컁; 컁; 컁; 컁; ) HANGUL SYLLABLE KYANG
+CEC2;CEC2;110F 1163 11BD;CEC2;110F 1163 11BD; # (컂; 컂; 컂; 컂; 컂; ) HANGUL SYLLABLE KYAJ
+CEC3;CEC3;110F 1163 11BE;CEC3;110F 1163 11BE; # (컃; 컃; 컃; 컃; 컃; ) HANGUL SYLLABLE KYAC
+CEC4;CEC4;110F 1163 11BF;CEC4;110F 1163 11BF; # (컄; 컄; 컄; 컄; 컄; ) HANGUL SYLLABLE KYAK
+CEC5;CEC5;110F 1163 11C0;CEC5;110F 1163 11C0; # (컅; 컅; 컅; 컅; 컅; ) HANGUL SYLLABLE KYAT
+CEC6;CEC6;110F 1163 11C1;CEC6;110F 1163 11C1; # (컆; 컆; 컆; 컆; 컆; ) HANGUL SYLLABLE KYAP
+CEC7;CEC7;110F 1163 11C2;CEC7;110F 1163 11C2; # (컇; 컇; 컇; 컇; 컇; ) HANGUL SYLLABLE KYAH
+CEC8;CEC8;110F 1164;CEC8;110F 1164; # (컈; 컈; 컈; 컈; 컈; ) HANGUL SYLLABLE KYAE
+CEC9;CEC9;110F 1164 11A8;CEC9;110F 1164 11A8; # (컉; 컉; 컉; 컉; 컉; ) HANGUL SYLLABLE KYAEG
+CECA;CECA;110F 1164 11A9;CECA;110F 1164 11A9; # (컊; 컊; 컊; 컊; 컊; ) HANGUL SYLLABLE KYAEGG
+CECB;CECB;110F 1164 11AA;CECB;110F 1164 11AA; # (컋; 컋; 컋; 컋; 컋; ) HANGUL SYLLABLE KYAEGS
+CECC;CECC;110F 1164 11AB;CECC;110F 1164 11AB; # (컌; 컌; 컌; 컌; 컌; ) HANGUL SYLLABLE KYAEN
+CECD;CECD;110F 1164 11AC;CECD;110F 1164 11AC; # (컍; 컍; 컍; 컍; 컍; ) HANGUL SYLLABLE KYAENJ
+CECE;CECE;110F 1164 11AD;CECE;110F 1164 11AD; # (컎; 컎; 컎; 컎; 컎; ) HANGUL SYLLABLE KYAENH
+CECF;CECF;110F 1164 11AE;CECF;110F 1164 11AE; # (컏; 컏; 컏; 컏; 컏; ) HANGUL SYLLABLE KYAED
+CED0;CED0;110F 1164 11AF;CED0;110F 1164 11AF; # (컐; 컐; 컐; 컐; 컐; ) HANGUL SYLLABLE KYAEL
+CED1;CED1;110F 1164 11B0;CED1;110F 1164 11B0; # (컑; 컑; 컑; 컑; 컑; ) HANGUL SYLLABLE KYAELG
+CED2;CED2;110F 1164 11B1;CED2;110F 1164 11B1; # (컒; 컒; 컒; 컒; 컒; ) HANGUL SYLLABLE KYAELM
+CED3;CED3;110F 1164 11B2;CED3;110F 1164 11B2; # (컓; 컓; 컓; 컓; 컓; ) HANGUL SYLLABLE KYAELB
+CED4;CED4;110F 1164 11B3;CED4;110F 1164 11B3; # (컔; 컔; 컔; 컔; 컔; ) HANGUL SYLLABLE KYAELS
+CED5;CED5;110F 1164 11B4;CED5;110F 1164 11B4; # (컕; 컕; 컕; 컕; 컕; ) HANGUL SYLLABLE KYAELT
+CED6;CED6;110F 1164 11B5;CED6;110F 1164 11B5; # (컖; 컖; 컖; 컖; 컖; ) HANGUL SYLLABLE KYAELP
+CED7;CED7;110F 1164 11B6;CED7;110F 1164 11B6; # (컗; 컗; 컗; 컗; 컗; ) HANGUL SYLLABLE KYAELH
+CED8;CED8;110F 1164 11B7;CED8;110F 1164 11B7; # (컘; 컘; 컘; 컘; 컘; ) HANGUL SYLLABLE KYAEM
+CED9;CED9;110F 1164 11B8;CED9;110F 1164 11B8; # (컙; 컙; 컙; 컙; 컙; ) HANGUL SYLLABLE KYAEB
+CEDA;CEDA;110F 1164 11B9;CEDA;110F 1164 11B9; # (컚; 컚; 컚; 컚; 컚; ) HANGUL SYLLABLE KYAEBS
+CEDB;CEDB;110F 1164 11BA;CEDB;110F 1164 11BA; # (컛; 컛; 컛; 컛; 컛; ) HANGUL SYLLABLE KYAES
+CEDC;CEDC;110F 1164 11BB;CEDC;110F 1164 11BB; # (컜; 컜; 컜; 컜; 컜; ) HANGUL SYLLABLE KYAESS
+CEDD;CEDD;110F 1164 11BC;CEDD;110F 1164 11BC; # (컝; 컝; 컝; 컝; 컝; ) HANGUL SYLLABLE KYAENG
+CEDE;CEDE;110F 1164 11BD;CEDE;110F 1164 11BD; # (컞; 컞; 컞; 컞; 컞; ) HANGUL SYLLABLE KYAEJ
+CEDF;CEDF;110F 1164 11BE;CEDF;110F 1164 11BE; # (컟; 컟; 컟; 컟; 컟; ) HANGUL SYLLABLE KYAEC
+CEE0;CEE0;110F 1164 11BF;CEE0;110F 1164 11BF; # (컠; 컠; 컠; 컠; 컠; ) HANGUL SYLLABLE KYAEK
+CEE1;CEE1;110F 1164 11C0;CEE1;110F 1164 11C0; # (컡; 컡; 컡; 컡; 컡; ) HANGUL SYLLABLE KYAET
+CEE2;CEE2;110F 1164 11C1;CEE2;110F 1164 11C1; # (컢; 컢; 컢; 컢; 컢; ) HANGUL SYLLABLE KYAEP
+CEE3;CEE3;110F 1164 11C2;CEE3;110F 1164 11C2; # (컣; 컣; 컣; 컣; 컣; ) HANGUL SYLLABLE KYAEH
+CEE4;CEE4;110F 1165;CEE4;110F 1165; # (커; 커; 커; 커; 커; ) HANGUL SYLLABLE KEO
+CEE5;CEE5;110F 1165 11A8;CEE5;110F 1165 11A8; # (컥; 컥; 컥; 컥; 컥; ) HANGUL SYLLABLE KEOG
+CEE6;CEE6;110F 1165 11A9;CEE6;110F 1165 11A9; # (컦; 컦; 컦; 컦; 컦; ) HANGUL SYLLABLE KEOGG
+CEE7;CEE7;110F 1165 11AA;CEE7;110F 1165 11AA; # (컧; 컧; 컧; 컧; 컧; ) HANGUL SYLLABLE KEOGS
+CEE8;CEE8;110F 1165 11AB;CEE8;110F 1165 11AB; # (컨; 컨; 컨; 컨; 컨; ) HANGUL SYLLABLE KEON
+CEE9;CEE9;110F 1165 11AC;CEE9;110F 1165 11AC; # (컩; 컩; 컩; 컩; 컩; ) HANGUL SYLLABLE KEONJ
+CEEA;CEEA;110F 1165 11AD;CEEA;110F 1165 11AD; # (컪; 컪; 컪; 컪; 컪; ) HANGUL SYLLABLE KEONH
+CEEB;CEEB;110F 1165 11AE;CEEB;110F 1165 11AE; # (컫; 컫; 컫; 컫; 컫; ) HANGUL SYLLABLE KEOD
+CEEC;CEEC;110F 1165 11AF;CEEC;110F 1165 11AF; # (컬; 컬; 컬; 컬; 컬; ) HANGUL SYLLABLE KEOL
+CEED;CEED;110F 1165 11B0;CEED;110F 1165 11B0; # (컭; 컭; 컭; 컭; 컭; ) HANGUL SYLLABLE KEOLG
+CEEE;CEEE;110F 1165 11B1;CEEE;110F 1165 11B1; # (컮; 컮; 컮; 컮; 컮; ) HANGUL SYLLABLE KEOLM
+CEEF;CEEF;110F 1165 11B2;CEEF;110F 1165 11B2; # (컯; 컯; 컯; 컯; 컯; ) HANGUL SYLLABLE KEOLB
+CEF0;CEF0;110F 1165 11B3;CEF0;110F 1165 11B3; # (컰; 컰; 컰; 컰; 컰; ) HANGUL SYLLABLE KEOLS
+CEF1;CEF1;110F 1165 11B4;CEF1;110F 1165 11B4; # (컱; 컱; 컱; 컱; 컱; ) HANGUL SYLLABLE KEOLT
+CEF2;CEF2;110F 1165 11B5;CEF2;110F 1165 11B5; # (컲; 컲; 컲; 컲; 컲; ) HANGUL SYLLABLE KEOLP
+CEF3;CEF3;110F 1165 11B6;CEF3;110F 1165 11B6; # (컳; 컳; 컳; 컳; 컳; ) HANGUL SYLLABLE KEOLH
+CEF4;CEF4;110F 1165 11B7;CEF4;110F 1165 11B7; # (컴; 컴; 컴; 컴; 컴; ) HANGUL SYLLABLE KEOM
+CEF5;CEF5;110F 1165 11B8;CEF5;110F 1165 11B8; # (컵; 컵; 컵; 컵; 컵; ) HANGUL SYLLABLE KEOB
+CEF6;CEF6;110F 1165 11B9;CEF6;110F 1165 11B9; # (컶; 컶; 컶; 컶; 컶; ) HANGUL SYLLABLE KEOBS
+CEF7;CEF7;110F 1165 11BA;CEF7;110F 1165 11BA; # (컷; 컷; 컷; 컷; 컷; ) HANGUL SYLLABLE KEOS
+CEF8;CEF8;110F 1165 11BB;CEF8;110F 1165 11BB; # (컸; 컸; 컸; 컸; 컸; ) HANGUL SYLLABLE KEOSS
+CEF9;CEF9;110F 1165 11BC;CEF9;110F 1165 11BC; # (컹; 컹; 컹; 컹; 컹; ) HANGUL SYLLABLE KEONG
+CEFA;CEFA;110F 1165 11BD;CEFA;110F 1165 11BD; # (컺; 컺; 컺; 컺; 컺; ) HANGUL SYLLABLE KEOJ
+CEFB;CEFB;110F 1165 11BE;CEFB;110F 1165 11BE; # (컻; 컻; 컻; 컻; 컻; ) HANGUL SYLLABLE KEOC
+CEFC;CEFC;110F 1165 11BF;CEFC;110F 1165 11BF; # (컼; 컼; 컼; 컼; 컼; ) HANGUL SYLLABLE KEOK
+CEFD;CEFD;110F 1165 11C0;CEFD;110F 1165 11C0; # (컽; 컽; 컽; 컽; 컽; ) HANGUL SYLLABLE KEOT
+CEFE;CEFE;110F 1165 11C1;CEFE;110F 1165 11C1; # (컾; 컾; 컾; 컾; 컾; ) HANGUL SYLLABLE KEOP
+CEFF;CEFF;110F 1165 11C2;CEFF;110F 1165 11C2; # (컿; 컿; 컿; 컿; 컿; ) HANGUL SYLLABLE KEOH
+CF00;CF00;110F 1166;CF00;110F 1166; # (케; 케; 케; 케; 케; ) HANGUL SYLLABLE KE
+CF01;CF01;110F 1166 11A8;CF01;110F 1166 11A8; # (켁; 켁; 켁; 켁; 켁; ) HANGUL SYLLABLE KEG
+CF02;CF02;110F 1166 11A9;CF02;110F 1166 11A9; # (켂; 켂; 켂; 켂; 켂; ) HANGUL SYLLABLE KEGG
+CF03;CF03;110F 1166 11AA;CF03;110F 1166 11AA; # (켃; 켃; 켃; 켃; 켃; ) HANGUL SYLLABLE KEGS
+CF04;CF04;110F 1166 11AB;CF04;110F 1166 11AB; # (켄; 켄; 켄; 켄; 켄; ) HANGUL SYLLABLE KEN
+CF05;CF05;110F 1166 11AC;CF05;110F 1166 11AC; # (켅; 켅; 켅; 켅; 켅; ) HANGUL SYLLABLE KENJ
+CF06;CF06;110F 1166 11AD;CF06;110F 1166 11AD; # (켆; 켆; 켆; 켆; 켆; ) HANGUL SYLLABLE KENH
+CF07;CF07;110F 1166 11AE;CF07;110F 1166 11AE; # (켇; 켇; 켇; 켇; 켇; ) HANGUL SYLLABLE KED
+CF08;CF08;110F 1166 11AF;CF08;110F 1166 11AF; # (켈; 켈; 켈; 켈; 켈; ) HANGUL SYLLABLE KEL
+CF09;CF09;110F 1166 11B0;CF09;110F 1166 11B0; # (켉; 켉; 켉; 켉; 켉; ) HANGUL SYLLABLE KELG
+CF0A;CF0A;110F 1166 11B1;CF0A;110F 1166 11B1; # (켊; 켊; 켊; 켊; 켊; ) HANGUL SYLLABLE KELM
+CF0B;CF0B;110F 1166 11B2;CF0B;110F 1166 11B2; # (켋; 켋; 켋; 켋; 켋; ) HANGUL SYLLABLE KELB
+CF0C;CF0C;110F 1166 11B3;CF0C;110F 1166 11B3; # (켌; 켌; 켌; 켌; 켌; ) HANGUL SYLLABLE KELS
+CF0D;CF0D;110F 1166 11B4;CF0D;110F 1166 11B4; # (켍; 켍; 켍; 켍; 켍; ) HANGUL SYLLABLE KELT
+CF0E;CF0E;110F 1166 11B5;CF0E;110F 1166 11B5; # (켎; 켎; 켎; 켎; 켎; ) HANGUL SYLLABLE KELP
+CF0F;CF0F;110F 1166 11B6;CF0F;110F 1166 11B6; # (켏; 켏; 켏; 켏; 켏; ) HANGUL SYLLABLE KELH
+CF10;CF10;110F 1166 11B7;CF10;110F 1166 11B7; # (켐; 켐; 켐; 켐; 켐; ) HANGUL SYLLABLE KEM
+CF11;CF11;110F 1166 11B8;CF11;110F 1166 11B8; # (켑; 켑; 켑; 켑; 켑; ) HANGUL SYLLABLE KEB
+CF12;CF12;110F 1166 11B9;CF12;110F 1166 11B9; # (켒; 켒; 켒; 켒; 켒; ) HANGUL SYLLABLE KEBS
+CF13;CF13;110F 1166 11BA;CF13;110F 1166 11BA; # (켓; 켓; 켓; 켓; 켓; ) HANGUL SYLLABLE KES
+CF14;CF14;110F 1166 11BB;CF14;110F 1166 11BB; # (켔; 켔; 켔; 켔; 켔; ) HANGUL SYLLABLE KESS
+CF15;CF15;110F 1166 11BC;CF15;110F 1166 11BC; # (켕; 켕; 켕; 켕; 켕; ) HANGUL SYLLABLE KENG
+CF16;CF16;110F 1166 11BD;CF16;110F 1166 11BD; # (켖; 켖; 켖; 켖; 켖; ) HANGUL SYLLABLE KEJ
+CF17;CF17;110F 1166 11BE;CF17;110F 1166 11BE; # (켗; 켗; 켗; 켗; 켗; ) HANGUL SYLLABLE KEC
+CF18;CF18;110F 1166 11BF;CF18;110F 1166 11BF; # (켘; 켘; 켘; 켘; 켘; ) HANGUL SYLLABLE KEK
+CF19;CF19;110F 1166 11C0;CF19;110F 1166 11C0; # (켙; 켙; 켙; 켙; 켙; ) HANGUL SYLLABLE KET
+CF1A;CF1A;110F 1166 11C1;CF1A;110F 1166 11C1; # (켚; 켚; 켚; 켚; 켚; ) HANGUL SYLLABLE KEP
+CF1B;CF1B;110F 1166 11C2;CF1B;110F 1166 11C2; # (켛; 켛; 켛; 켛; 켛; ) HANGUL SYLLABLE KEH
+CF1C;CF1C;110F 1167;CF1C;110F 1167; # (켜; 켜; 켜; 켜; 켜; ) HANGUL SYLLABLE KYEO
+CF1D;CF1D;110F 1167 11A8;CF1D;110F 1167 11A8; # (켝; 켝; 켝; 켝; 켝; ) HANGUL SYLLABLE KYEOG
+CF1E;CF1E;110F 1167 11A9;CF1E;110F 1167 11A9; # (켞; 켞; 켞; 켞; 켞; ) HANGUL SYLLABLE KYEOGG
+CF1F;CF1F;110F 1167 11AA;CF1F;110F 1167 11AA; # (켟; 켟; 켟; 켟; 켟; ) HANGUL SYLLABLE KYEOGS
+CF20;CF20;110F 1167 11AB;CF20;110F 1167 11AB; # (켠; 켠; 켠; 켠; 켠; ) HANGUL SYLLABLE KYEON
+CF21;CF21;110F 1167 11AC;CF21;110F 1167 11AC; # (켡; 켡; 켡; 켡; 켡; ) HANGUL SYLLABLE KYEONJ
+CF22;CF22;110F 1167 11AD;CF22;110F 1167 11AD; # (켢; 켢; 켢; 켢; 켢; ) HANGUL SYLLABLE KYEONH
+CF23;CF23;110F 1167 11AE;CF23;110F 1167 11AE; # (켣; 켣; 켣; 켣; 켣; ) HANGUL SYLLABLE KYEOD
+CF24;CF24;110F 1167 11AF;CF24;110F 1167 11AF; # (켤; 켤; 켤; 켤; 켤; ) HANGUL SYLLABLE KYEOL
+CF25;CF25;110F 1167 11B0;CF25;110F 1167 11B0; # (켥; 켥; 켥; 켥; 켥; ) HANGUL SYLLABLE KYEOLG
+CF26;CF26;110F 1167 11B1;CF26;110F 1167 11B1; # (켦; 켦; 켦; 켦; 켦; ) HANGUL SYLLABLE KYEOLM
+CF27;CF27;110F 1167 11B2;CF27;110F 1167 11B2; # (켧; 켧; 켧; 켧; 켧; ) HANGUL SYLLABLE KYEOLB
+CF28;CF28;110F 1167 11B3;CF28;110F 1167 11B3; # (켨; 켨; 켨; 켨; 켨; ) HANGUL SYLLABLE KYEOLS
+CF29;CF29;110F 1167 11B4;CF29;110F 1167 11B4; # (켩; 켩; 켩; 켩; 켩; ) HANGUL SYLLABLE KYEOLT
+CF2A;CF2A;110F 1167 11B5;CF2A;110F 1167 11B5; # (켪; 켪; 켪; 켪; 켪; ) HANGUL SYLLABLE KYEOLP
+CF2B;CF2B;110F 1167 11B6;CF2B;110F 1167 11B6; # (켫; 켫; 켫; 켫; 켫; ) HANGUL SYLLABLE KYEOLH
+CF2C;CF2C;110F 1167 11B7;CF2C;110F 1167 11B7; # (켬; 켬; 켬; 켬; 켬; ) HANGUL SYLLABLE KYEOM
+CF2D;CF2D;110F 1167 11B8;CF2D;110F 1167 11B8; # (켭; 켭; 켭; 켭; 켭; ) HANGUL SYLLABLE KYEOB
+CF2E;CF2E;110F 1167 11B9;CF2E;110F 1167 11B9; # (켮; 켮; 켮; 켮; 켮; ) HANGUL SYLLABLE KYEOBS
+CF2F;CF2F;110F 1167 11BA;CF2F;110F 1167 11BA; # (켯; 켯; 켯; 켯; 켯; ) HANGUL SYLLABLE KYEOS
+CF30;CF30;110F 1167 11BB;CF30;110F 1167 11BB; # (켰; 켰; 켰; 켰; 켰; ) HANGUL SYLLABLE KYEOSS
+CF31;CF31;110F 1167 11BC;CF31;110F 1167 11BC; # (켱; 켱; 켱; 켱; 켱; ) HANGUL SYLLABLE KYEONG
+CF32;CF32;110F 1167 11BD;CF32;110F 1167 11BD; # (켲; 켲; 켲; 켲; 켲; ) HANGUL SYLLABLE KYEOJ
+CF33;CF33;110F 1167 11BE;CF33;110F 1167 11BE; # (켳; 켳; 켳; 켳; 켳; ) HANGUL SYLLABLE KYEOC
+CF34;CF34;110F 1167 11BF;CF34;110F 1167 11BF; # (켴; 켴; 켴; 켴; 켴; ) HANGUL SYLLABLE KYEOK
+CF35;CF35;110F 1167 11C0;CF35;110F 1167 11C0; # (켵; 켵; 켵; 켵; 켵; ) HANGUL SYLLABLE KYEOT
+CF36;CF36;110F 1167 11C1;CF36;110F 1167 11C1; # (켶; 켶; 켶; 켶; 켶; ) HANGUL SYLLABLE KYEOP
+CF37;CF37;110F 1167 11C2;CF37;110F 1167 11C2; # (켷; 켷; 켷; 켷; 켷; ) HANGUL SYLLABLE KYEOH
+CF38;CF38;110F 1168;CF38;110F 1168; # (켸; 켸; 켸; 켸; 켸; ) HANGUL SYLLABLE KYE
+CF39;CF39;110F 1168 11A8;CF39;110F 1168 11A8; # (켹; 켹; 켹; 켹; 켹; ) HANGUL SYLLABLE KYEG
+CF3A;CF3A;110F 1168 11A9;CF3A;110F 1168 11A9; # (켺; 켺; 켺; 켺; 켺; ) HANGUL SYLLABLE KYEGG
+CF3B;CF3B;110F 1168 11AA;CF3B;110F 1168 11AA; # (켻; 켻; 켻; 켻; 켻; ) HANGUL SYLLABLE KYEGS
+CF3C;CF3C;110F 1168 11AB;CF3C;110F 1168 11AB; # (켼; 켼; 켼; 켼; 켼; ) HANGUL SYLLABLE KYEN
+CF3D;CF3D;110F 1168 11AC;CF3D;110F 1168 11AC; # (켽; 켽; 켽; 켽; 켽; ) HANGUL SYLLABLE KYENJ
+CF3E;CF3E;110F 1168 11AD;CF3E;110F 1168 11AD; # (켾; 켾; 켾; 켾; 켾; ) HANGUL SYLLABLE KYENH
+CF3F;CF3F;110F 1168 11AE;CF3F;110F 1168 11AE; # (켿; 켿; 켿; 켿; 켿; ) HANGUL SYLLABLE KYED
+CF40;CF40;110F 1168 11AF;CF40;110F 1168 11AF; # (콀; 콀; 콀; 콀; 콀; ) HANGUL SYLLABLE KYEL
+CF41;CF41;110F 1168 11B0;CF41;110F 1168 11B0; # (콁; 콁; 콁; 콁; 콁; ) HANGUL SYLLABLE KYELG
+CF42;CF42;110F 1168 11B1;CF42;110F 1168 11B1; # (콂; 콂; 콂; 콂; 콂; ) HANGUL SYLLABLE KYELM
+CF43;CF43;110F 1168 11B2;CF43;110F 1168 11B2; # (콃; 콃; 콃; 콃; 콃; ) HANGUL SYLLABLE KYELB
+CF44;CF44;110F 1168 11B3;CF44;110F 1168 11B3; # (콄; 콄; 콄; 콄; 콄; ) HANGUL SYLLABLE KYELS
+CF45;CF45;110F 1168 11B4;CF45;110F 1168 11B4; # (콅; 콅; 콅; 콅; 콅; ) HANGUL SYLLABLE KYELT
+CF46;CF46;110F 1168 11B5;CF46;110F 1168 11B5; # (콆; 콆; 콆; 콆; 콆; ) HANGUL SYLLABLE KYELP
+CF47;CF47;110F 1168 11B6;CF47;110F 1168 11B6; # (콇; 콇; 콇; 콇; 콇; ) HANGUL SYLLABLE KYELH
+CF48;CF48;110F 1168 11B7;CF48;110F 1168 11B7; # (콈; 콈; 콈; 콈; 콈; ) HANGUL SYLLABLE KYEM
+CF49;CF49;110F 1168 11B8;CF49;110F 1168 11B8; # (콉; 콉; 콉; 콉; 콉; ) HANGUL SYLLABLE KYEB
+CF4A;CF4A;110F 1168 11B9;CF4A;110F 1168 11B9; # (콊; 콊; 콊; 콊; 콊; ) HANGUL SYLLABLE KYEBS
+CF4B;CF4B;110F 1168 11BA;CF4B;110F 1168 11BA; # (콋; 콋; 콋; 콋; 콋; ) HANGUL SYLLABLE KYES
+CF4C;CF4C;110F 1168 11BB;CF4C;110F 1168 11BB; # (콌; 콌; 콌; 콌; 콌; ) HANGUL SYLLABLE KYESS
+CF4D;CF4D;110F 1168 11BC;CF4D;110F 1168 11BC; # (콍; 콍; 콍; 콍; 콍; ) HANGUL SYLLABLE KYENG
+CF4E;CF4E;110F 1168 11BD;CF4E;110F 1168 11BD; # (콎; 콎; 콎; 콎; 콎; ) HANGUL SYLLABLE KYEJ
+CF4F;CF4F;110F 1168 11BE;CF4F;110F 1168 11BE; # (콏; 콏; 콏; 콏; 콏; ) HANGUL SYLLABLE KYEC
+CF50;CF50;110F 1168 11BF;CF50;110F 1168 11BF; # (콐; 콐; 콐; 콐; 콐; ) HANGUL SYLLABLE KYEK
+CF51;CF51;110F 1168 11C0;CF51;110F 1168 11C0; # (콑; 콑; 콑; 콑; 콑; ) HANGUL SYLLABLE KYET
+CF52;CF52;110F 1168 11C1;CF52;110F 1168 11C1; # (콒; 콒; 콒; 콒; 콒; ) HANGUL SYLLABLE KYEP
+CF53;CF53;110F 1168 11C2;CF53;110F 1168 11C2; # (콓; 콓; 콓; 콓; 콓; ) HANGUL SYLLABLE KYEH
+CF54;CF54;110F 1169;CF54;110F 1169; # (코; 코; 코; 코; 코; ) HANGUL SYLLABLE KO
+CF55;CF55;110F 1169 11A8;CF55;110F 1169 11A8; # (콕; 콕; 콕; 콕; 콕; ) HANGUL SYLLABLE KOG
+CF56;CF56;110F 1169 11A9;CF56;110F 1169 11A9; # (콖; 콖; 콖; 콖; 콖; ) HANGUL SYLLABLE KOGG
+CF57;CF57;110F 1169 11AA;CF57;110F 1169 11AA; # (콗; 콗; 콗; 콗; 콗; ) HANGUL SYLLABLE KOGS
+CF58;CF58;110F 1169 11AB;CF58;110F 1169 11AB; # (콘; 콘; 콘; 콘; 콘; ) HANGUL SYLLABLE KON
+CF59;CF59;110F 1169 11AC;CF59;110F 1169 11AC; # (콙; 콙; 콙; 콙; 콙; ) HANGUL SYLLABLE KONJ
+CF5A;CF5A;110F 1169 11AD;CF5A;110F 1169 11AD; # (콚; 콚; 콚; 콚; 콚; ) HANGUL SYLLABLE KONH
+CF5B;CF5B;110F 1169 11AE;CF5B;110F 1169 11AE; # (콛; 콛; 콛; 콛; 콛; ) HANGUL SYLLABLE KOD
+CF5C;CF5C;110F 1169 11AF;CF5C;110F 1169 11AF; # (콜; 콜; 콜; 콜; 콜; ) HANGUL SYLLABLE KOL
+CF5D;CF5D;110F 1169 11B0;CF5D;110F 1169 11B0; # (콝; 콝; 콝; 콝; 콝; ) HANGUL SYLLABLE KOLG
+CF5E;CF5E;110F 1169 11B1;CF5E;110F 1169 11B1; # (콞; 콞; 콞; 콞; 콞; ) HANGUL SYLLABLE KOLM
+CF5F;CF5F;110F 1169 11B2;CF5F;110F 1169 11B2; # (콟; 콟; 콟; 콟; 콟; ) HANGUL SYLLABLE KOLB
+CF60;CF60;110F 1169 11B3;CF60;110F 1169 11B3; # (콠; 콠; 콠; 콠; 콠; ) HANGUL SYLLABLE KOLS
+CF61;CF61;110F 1169 11B4;CF61;110F 1169 11B4; # (콡; 콡; 콡; 콡; 콡; ) HANGUL SYLLABLE KOLT
+CF62;CF62;110F 1169 11B5;CF62;110F 1169 11B5; # (콢; 콢; 콢; 콢; 콢; ) HANGUL SYLLABLE KOLP
+CF63;CF63;110F 1169 11B6;CF63;110F 1169 11B6; # (콣; 콣; 콣; 콣; 콣; ) HANGUL SYLLABLE KOLH
+CF64;CF64;110F 1169 11B7;CF64;110F 1169 11B7; # (콤; 콤; 콤; 콤; 콤; ) HANGUL SYLLABLE KOM
+CF65;CF65;110F 1169 11B8;CF65;110F 1169 11B8; # (콥; 콥; 콥; 콥; 콥; ) HANGUL SYLLABLE KOB
+CF66;CF66;110F 1169 11B9;CF66;110F 1169 11B9; # (콦; 콦; 콦; 콦; 콦; ) HANGUL SYLLABLE KOBS
+CF67;CF67;110F 1169 11BA;CF67;110F 1169 11BA; # (콧; 콧; 콧; 콧; 콧; ) HANGUL SYLLABLE KOS
+CF68;CF68;110F 1169 11BB;CF68;110F 1169 11BB; # (콨; 콨; 콨; 콨; 콨; ) HANGUL SYLLABLE KOSS
+CF69;CF69;110F 1169 11BC;CF69;110F 1169 11BC; # (콩; 콩; 콩; 콩; 콩; ) HANGUL SYLLABLE KONG
+CF6A;CF6A;110F 1169 11BD;CF6A;110F 1169 11BD; # (콪; 콪; 콪; 콪; 콪; ) HANGUL SYLLABLE KOJ
+CF6B;CF6B;110F 1169 11BE;CF6B;110F 1169 11BE; # (콫; 콫; 콫; 콫; 콫; ) HANGUL SYLLABLE KOC
+CF6C;CF6C;110F 1169 11BF;CF6C;110F 1169 11BF; # (콬; 콬; 콬; 콬; 콬; ) HANGUL SYLLABLE KOK
+CF6D;CF6D;110F 1169 11C0;CF6D;110F 1169 11C0; # (콭; 콭; 콭; 콭; 콭; ) HANGUL SYLLABLE KOT
+CF6E;CF6E;110F 1169 11C1;CF6E;110F 1169 11C1; # (콮; 콮; 콮; 콮; 콮; ) HANGUL SYLLABLE KOP
+CF6F;CF6F;110F 1169 11C2;CF6F;110F 1169 11C2; # (콯; 콯; 콯; 콯; 콯; ) HANGUL SYLLABLE KOH
+CF70;CF70;110F 116A;CF70;110F 116A; # (콰; 콰; 콰; 콰; 콰; ) HANGUL SYLLABLE KWA
+CF71;CF71;110F 116A 11A8;CF71;110F 116A 11A8; # (콱; 콱; 콱; 콱; 콱; ) HANGUL SYLLABLE KWAG
+CF72;CF72;110F 116A 11A9;CF72;110F 116A 11A9; # (콲; 콲; 콲; 콲; 콲; ) HANGUL SYLLABLE KWAGG
+CF73;CF73;110F 116A 11AA;CF73;110F 116A 11AA; # (콳; 콳; 콳; 콳; 콳; ) HANGUL SYLLABLE KWAGS
+CF74;CF74;110F 116A 11AB;CF74;110F 116A 11AB; # (콴; 콴; 콴; 콴; 콴; ) HANGUL SYLLABLE KWAN
+CF75;CF75;110F 116A 11AC;CF75;110F 116A 11AC; # (콵; 콵; 콵; 콵; 콵; ) HANGUL SYLLABLE KWANJ
+CF76;CF76;110F 116A 11AD;CF76;110F 116A 11AD; # (콶; 콶; 콶; 콶; 콶; ) HANGUL SYLLABLE KWANH
+CF77;CF77;110F 116A 11AE;CF77;110F 116A 11AE; # (콷; 콷; 콷; 콷; 콷; ) HANGUL SYLLABLE KWAD
+CF78;CF78;110F 116A 11AF;CF78;110F 116A 11AF; # (콸; 콸; 콸; 콸; 콸; ) HANGUL SYLLABLE KWAL
+CF79;CF79;110F 116A 11B0;CF79;110F 116A 11B0; # (콹; 콹; 콹; 콹; 콹; ) HANGUL SYLLABLE KWALG
+CF7A;CF7A;110F 116A 11B1;CF7A;110F 116A 11B1; # (콺; 콺; 콺; 콺; 콺; ) HANGUL SYLLABLE KWALM
+CF7B;CF7B;110F 116A 11B2;CF7B;110F 116A 11B2; # (콻; 콻; 콻; 콻; 콻; ) HANGUL SYLLABLE KWALB
+CF7C;CF7C;110F 116A 11B3;CF7C;110F 116A 11B3; # (콼; 콼; 콼; 콼; 콼; ) HANGUL SYLLABLE KWALS
+CF7D;CF7D;110F 116A 11B4;CF7D;110F 116A 11B4; # (콽; 콽; 콽; 콽; 콽; ) HANGUL SYLLABLE KWALT
+CF7E;CF7E;110F 116A 11B5;CF7E;110F 116A 11B5; # (콾; 콾; 콾; 콾; 콾; ) HANGUL SYLLABLE KWALP
+CF7F;CF7F;110F 116A 11B6;CF7F;110F 116A 11B6; # (콿; 콿; 콿; 콿; 콿; ) HANGUL SYLLABLE KWALH
+CF80;CF80;110F 116A 11B7;CF80;110F 116A 11B7; # (쾀; 쾀; 쾀; 쾀; 쾀; ) HANGUL SYLLABLE KWAM
+CF81;CF81;110F 116A 11B8;CF81;110F 116A 11B8; # (쾁; 쾁; 쾁; 쾁; 쾁; ) HANGUL SYLLABLE KWAB
+CF82;CF82;110F 116A 11B9;CF82;110F 116A 11B9; # (쾂; 쾂; 쾂; 쾂; 쾂; ) HANGUL SYLLABLE KWABS
+CF83;CF83;110F 116A 11BA;CF83;110F 116A 11BA; # (쾃; 쾃; 쾃; 쾃; 쾃; ) HANGUL SYLLABLE KWAS
+CF84;CF84;110F 116A 11BB;CF84;110F 116A 11BB; # (쾄; 쾄; 쾄; 쾄; 쾄; ) HANGUL SYLLABLE KWASS
+CF85;CF85;110F 116A 11BC;CF85;110F 116A 11BC; # (쾅; 쾅; 쾅; 쾅; 쾅; ) HANGUL SYLLABLE KWANG
+CF86;CF86;110F 116A 11BD;CF86;110F 116A 11BD; # (쾆; 쾆; 쾆; 쾆; 쾆; ) HANGUL SYLLABLE KWAJ
+CF87;CF87;110F 116A 11BE;CF87;110F 116A 11BE; # (쾇; 쾇; 쾇; 쾇; 쾇; ) HANGUL SYLLABLE KWAC
+CF88;CF88;110F 116A 11BF;CF88;110F 116A 11BF; # (쾈; 쾈; 쾈; 쾈; 쾈; ) HANGUL SYLLABLE KWAK
+CF89;CF89;110F 116A 11C0;CF89;110F 116A 11C0; # (쾉; 쾉; 쾉; 쾉; 쾉; ) HANGUL SYLLABLE KWAT
+CF8A;CF8A;110F 116A 11C1;CF8A;110F 116A 11C1; # (쾊; 쾊; 쾊; 쾊; 쾊; ) HANGUL SYLLABLE KWAP
+CF8B;CF8B;110F 116A 11C2;CF8B;110F 116A 11C2; # (쾋; 쾋; 쾋; 쾋; 쾋; ) HANGUL SYLLABLE KWAH
+CF8C;CF8C;110F 116B;CF8C;110F 116B; # (쾌; 쾌; 쾌; 쾌; 쾌; ) HANGUL SYLLABLE KWAE
+CF8D;CF8D;110F 116B 11A8;CF8D;110F 116B 11A8; # (쾍; 쾍; 쾍; 쾍; 쾍; ) HANGUL SYLLABLE KWAEG
+CF8E;CF8E;110F 116B 11A9;CF8E;110F 116B 11A9; # (쾎; 쾎; 쾎; 쾎; 쾎; ) HANGUL SYLLABLE KWAEGG
+CF8F;CF8F;110F 116B 11AA;CF8F;110F 116B 11AA; # (쾏; 쾏; 쾏; 쾏; 쾏; ) HANGUL SYLLABLE KWAEGS
+CF90;CF90;110F 116B 11AB;CF90;110F 116B 11AB; # (쾐; 쾐; 쾐; 쾐; 쾐; ) HANGUL SYLLABLE KWAEN
+CF91;CF91;110F 116B 11AC;CF91;110F 116B 11AC; # (쾑; 쾑; 쾑; 쾑; 쾑; ) HANGUL SYLLABLE KWAENJ
+CF92;CF92;110F 116B 11AD;CF92;110F 116B 11AD; # (쾒; 쾒; 쾒; 쾒; 쾒; ) HANGUL SYLLABLE KWAENH
+CF93;CF93;110F 116B 11AE;CF93;110F 116B 11AE; # (쾓; 쾓; 쾓; 쾓; 쾓; ) HANGUL SYLLABLE KWAED
+CF94;CF94;110F 116B 11AF;CF94;110F 116B 11AF; # (쾔; 쾔; 쾔; 쾔; 쾔; ) HANGUL SYLLABLE KWAEL
+CF95;CF95;110F 116B 11B0;CF95;110F 116B 11B0; # (쾕; 쾕; 쾕; 쾕; 쾕; ) HANGUL SYLLABLE KWAELG
+CF96;CF96;110F 116B 11B1;CF96;110F 116B 11B1; # (쾖; 쾖; 쾖; 쾖; 쾖; ) HANGUL SYLLABLE KWAELM
+CF97;CF97;110F 116B 11B2;CF97;110F 116B 11B2; # (쾗; 쾗; 쾗; 쾗; 쾗; ) HANGUL SYLLABLE KWAELB
+CF98;CF98;110F 116B 11B3;CF98;110F 116B 11B3; # (쾘; 쾘; 쾘; 쾘; 쾘; ) HANGUL SYLLABLE KWAELS
+CF99;CF99;110F 116B 11B4;CF99;110F 116B 11B4; # (쾙; 쾙; 쾙; 쾙; 쾙; ) HANGUL SYLLABLE KWAELT
+CF9A;CF9A;110F 116B 11B5;CF9A;110F 116B 11B5; # (쾚; 쾚; 쾚; 쾚; 쾚; ) HANGUL SYLLABLE KWAELP
+CF9B;CF9B;110F 116B 11B6;CF9B;110F 116B 11B6; # (쾛; 쾛; 쾛; 쾛; 쾛; ) HANGUL SYLLABLE KWAELH
+CF9C;CF9C;110F 116B 11B7;CF9C;110F 116B 11B7; # (쾜; 쾜; 쾜; 쾜; 쾜; ) HANGUL SYLLABLE KWAEM
+CF9D;CF9D;110F 116B 11B8;CF9D;110F 116B 11B8; # (쾝; 쾝; 쾝; 쾝; 쾝; ) HANGUL SYLLABLE KWAEB
+CF9E;CF9E;110F 116B 11B9;CF9E;110F 116B 11B9; # (쾞; 쾞; 쾞; 쾞; 쾞; ) HANGUL SYLLABLE KWAEBS
+CF9F;CF9F;110F 116B 11BA;CF9F;110F 116B 11BA; # (쾟; 쾟; 쾟; 쾟; 쾟; ) HANGUL SYLLABLE KWAES
+CFA0;CFA0;110F 116B 11BB;CFA0;110F 116B 11BB; # (쾠; 쾠; 쾠; 쾠; 쾠; ) HANGUL SYLLABLE KWAESS
+CFA1;CFA1;110F 116B 11BC;CFA1;110F 116B 11BC; # (쾡; 쾡; 쾡; 쾡; 쾡; ) HANGUL SYLLABLE KWAENG
+CFA2;CFA2;110F 116B 11BD;CFA2;110F 116B 11BD; # (쾢; 쾢; 쾢; 쾢; 쾢; ) HANGUL SYLLABLE KWAEJ
+CFA3;CFA3;110F 116B 11BE;CFA3;110F 116B 11BE; # (쾣; 쾣; 쾣; 쾣; 쾣; ) HANGUL SYLLABLE KWAEC
+CFA4;CFA4;110F 116B 11BF;CFA4;110F 116B 11BF; # (쾤; 쾤; 쾤; 쾤; 쾤; ) HANGUL SYLLABLE KWAEK
+CFA5;CFA5;110F 116B 11C0;CFA5;110F 116B 11C0; # (쾥; 쾥; 쾥; 쾥; 쾥; ) HANGUL SYLLABLE KWAET
+CFA6;CFA6;110F 116B 11C1;CFA6;110F 116B 11C1; # (쾦; 쾦; 쾦; 쾦; 쾦; ) HANGUL SYLLABLE KWAEP
+CFA7;CFA7;110F 116B 11C2;CFA7;110F 116B 11C2; # (쾧; 쾧; 쾧; 쾧; 쾧; ) HANGUL SYLLABLE KWAEH
+CFA8;CFA8;110F 116C;CFA8;110F 116C; # (쾨; 쾨; 쾨; 쾨; 쾨; ) HANGUL SYLLABLE KOE
+CFA9;CFA9;110F 116C 11A8;CFA9;110F 116C 11A8; # (쾩; 쾩; 쾩; 쾩; 쾩; ) HANGUL SYLLABLE KOEG
+CFAA;CFAA;110F 116C 11A9;CFAA;110F 116C 11A9; # (쾪; 쾪; 쾪; 쾪; 쾪; ) HANGUL SYLLABLE KOEGG
+CFAB;CFAB;110F 116C 11AA;CFAB;110F 116C 11AA; # (쾫; 쾫; 쾫; 쾫; 쾫; ) HANGUL SYLLABLE KOEGS
+CFAC;CFAC;110F 116C 11AB;CFAC;110F 116C 11AB; # (쾬; 쾬; 쾬; 쾬; 쾬; ) HANGUL SYLLABLE KOEN
+CFAD;CFAD;110F 116C 11AC;CFAD;110F 116C 11AC; # (쾭; 쾭; 쾭; 쾭; 쾭; ) HANGUL SYLLABLE KOENJ
+CFAE;CFAE;110F 116C 11AD;CFAE;110F 116C 11AD; # (쾮; 쾮; 쾮; 쾮; 쾮; ) HANGUL SYLLABLE KOENH
+CFAF;CFAF;110F 116C 11AE;CFAF;110F 116C 11AE; # (쾯; 쾯; 쾯; 쾯; 쾯; ) HANGUL SYLLABLE KOED
+CFB0;CFB0;110F 116C 11AF;CFB0;110F 116C 11AF; # (쾰; 쾰; 쾰; 쾰; 쾰; ) HANGUL SYLLABLE KOEL
+CFB1;CFB1;110F 116C 11B0;CFB1;110F 116C 11B0; # (쾱; 쾱; 쾱; 쾱; 쾱; ) HANGUL SYLLABLE KOELG
+CFB2;CFB2;110F 116C 11B1;CFB2;110F 116C 11B1; # (쾲; 쾲; 쾲; 쾲; 쾲; ) HANGUL SYLLABLE KOELM
+CFB3;CFB3;110F 116C 11B2;CFB3;110F 116C 11B2; # (쾳; 쾳; 쾳; 쾳; 쾳; ) HANGUL SYLLABLE KOELB
+CFB4;CFB4;110F 116C 11B3;CFB4;110F 116C 11B3; # (쾴; 쾴; 쾴; 쾴; 쾴; ) HANGUL SYLLABLE KOELS
+CFB5;CFB5;110F 116C 11B4;CFB5;110F 116C 11B4; # (쾵; 쾵; 쾵; 쾵; 쾵; ) HANGUL SYLLABLE KOELT
+CFB6;CFB6;110F 116C 11B5;CFB6;110F 116C 11B5; # (쾶; 쾶; 쾶; 쾶; 쾶; ) HANGUL SYLLABLE KOELP
+CFB7;CFB7;110F 116C 11B6;CFB7;110F 116C 11B6; # (쾷; 쾷; 쾷; 쾷; 쾷; ) HANGUL SYLLABLE KOELH
+CFB8;CFB8;110F 116C 11B7;CFB8;110F 116C 11B7; # (쾸; 쾸; 쾸; 쾸; 쾸; ) HANGUL SYLLABLE KOEM
+CFB9;CFB9;110F 116C 11B8;CFB9;110F 116C 11B8; # (쾹; 쾹; 쾹; 쾹; 쾹; ) HANGUL SYLLABLE KOEB
+CFBA;CFBA;110F 116C 11B9;CFBA;110F 116C 11B9; # (쾺; 쾺; 쾺; 쾺; 쾺; ) HANGUL SYLLABLE KOEBS
+CFBB;CFBB;110F 116C 11BA;CFBB;110F 116C 11BA; # (쾻; 쾻; 쾻; 쾻; 쾻; ) HANGUL SYLLABLE KOES
+CFBC;CFBC;110F 116C 11BB;CFBC;110F 116C 11BB; # (쾼; 쾼; 쾼; 쾼; 쾼; ) HANGUL SYLLABLE KOESS
+CFBD;CFBD;110F 116C 11BC;CFBD;110F 116C 11BC; # (쾽; 쾽; 쾽; 쾽; 쾽; ) HANGUL SYLLABLE KOENG
+CFBE;CFBE;110F 116C 11BD;CFBE;110F 116C 11BD; # (쾾; 쾾; 쾾; 쾾; 쾾; ) HANGUL SYLLABLE KOEJ
+CFBF;CFBF;110F 116C 11BE;CFBF;110F 116C 11BE; # (쾿; 쾿; 쾿; 쾿; 쾿; ) HANGUL SYLLABLE KOEC
+CFC0;CFC0;110F 116C 11BF;CFC0;110F 116C 11BF; # (쿀; 쿀; 쿀; 쿀; 쿀; ) HANGUL SYLLABLE KOEK
+CFC1;CFC1;110F 116C 11C0;CFC1;110F 116C 11C0; # (쿁; 쿁; 쿁; 쿁; 쿁; ) HANGUL SYLLABLE KOET
+CFC2;CFC2;110F 116C 11C1;CFC2;110F 116C 11C1; # (쿂; 쿂; 쿂; 쿂; 쿂; ) HANGUL SYLLABLE KOEP
+CFC3;CFC3;110F 116C 11C2;CFC3;110F 116C 11C2; # (쿃; 쿃; 쿃; 쿃; 쿃; ) HANGUL SYLLABLE KOEH
+CFC4;CFC4;110F 116D;CFC4;110F 116D; # (쿄; 쿄; 쿄; 쿄; 쿄; ) HANGUL SYLLABLE KYO
+CFC5;CFC5;110F 116D 11A8;CFC5;110F 116D 11A8; # (쿅; 쿅; 쿅; 쿅; 쿅; ) HANGUL SYLLABLE KYOG
+CFC6;CFC6;110F 116D 11A9;CFC6;110F 116D 11A9; # (쿆; 쿆; 쿆; 쿆; 쿆; ) HANGUL SYLLABLE KYOGG
+CFC7;CFC7;110F 116D 11AA;CFC7;110F 116D 11AA; # (쿇; 쿇; 쿇; 쿇; 쿇; ) HANGUL SYLLABLE KYOGS
+CFC8;CFC8;110F 116D 11AB;CFC8;110F 116D 11AB; # (쿈; 쿈; 쿈; 쿈; 쿈; ) HANGUL SYLLABLE KYON
+CFC9;CFC9;110F 116D 11AC;CFC9;110F 116D 11AC; # (쿉; 쿉; 쿉; 쿉; 쿉; ) HANGUL SYLLABLE KYONJ
+CFCA;CFCA;110F 116D 11AD;CFCA;110F 116D 11AD; # (쿊; 쿊; 쿊; 쿊; 쿊; ) HANGUL SYLLABLE KYONH
+CFCB;CFCB;110F 116D 11AE;CFCB;110F 116D 11AE; # (쿋; 쿋; 쿋; 쿋; 쿋; ) HANGUL SYLLABLE KYOD
+CFCC;CFCC;110F 116D 11AF;CFCC;110F 116D 11AF; # (쿌; 쿌; 쿌; 쿌; 쿌; ) HANGUL SYLLABLE KYOL
+CFCD;CFCD;110F 116D 11B0;CFCD;110F 116D 11B0; # (쿍; 쿍; 쿍; 쿍; 쿍; ) HANGUL SYLLABLE KYOLG
+CFCE;CFCE;110F 116D 11B1;CFCE;110F 116D 11B1; # (쿎; 쿎; 쿎; 쿎; 쿎; ) HANGUL SYLLABLE KYOLM
+CFCF;CFCF;110F 116D 11B2;CFCF;110F 116D 11B2; # (쿏; 쿏; 쿏; 쿏; 쿏; ) HANGUL SYLLABLE KYOLB
+CFD0;CFD0;110F 116D 11B3;CFD0;110F 116D 11B3; # (쿐; 쿐; 쿐; 쿐; 쿐; ) HANGUL SYLLABLE KYOLS
+CFD1;CFD1;110F 116D 11B4;CFD1;110F 116D 11B4; # (쿑; 쿑; 쿑; 쿑; 쿑; ) HANGUL SYLLABLE KYOLT
+CFD2;CFD2;110F 116D 11B5;CFD2;110F 116D 11B5; # (쿒; 쿒; 쿒; 쿒; 쿒; ) HANGUL SYLLABLE KYOLP
+CFD3;CFD3;110F 116D 11B6;CFD3;110F 116D 11B6; # (쿓; 쿓; 쿓; 쿓; 쿓; ) HANGUL SYLLABLE KYOLH
+CFD4;CFD4;110F 116D 11B7;CFD4;110F 116D 11B7; # (쿔; 쿔; 쿔; 쿔; 쿔; ) HANGUL SYLLABLE KYOM
+CFD5;CFD5;110F 116D 11B8;CFD5;110F 116D 11B8; # (쿕; 쿕; 쿕; 쿕; 쿕; ) HANGUL SYLLABLE KYOB
+CFD6;CFD6;110F 116D 11B9;CFD6;110F 116D 11B9; # (쿖; 쿖; 쿖; 쿖; 쿖; ) HANGUL SYLLABLE KYOBS
+CFD7;CFD7;110F 116D 11BA;CFD7;110F 116D 11BA; # (쿗; 쿗; 쿗; 쿗; 쿗; ) HANGUL SYLLABLE KYOS
+CFD8;CFD8;110F 116D 11BB;CFD8;110F 116D 11BB; # (쿘; 쿘; 쿘; 쿘; 쿘; ) HANGUL SYLLABLE KYOSS
+CFD9;CFD9;110F 116D 11BC;CFD9;110F 116D 11BC; # (쿙; 쿙; 쿙; 쿙; 쿙; ) HANGUL SYLLABLE KYONG
+CFDA;CFDA;110F 116D 11BD;CFDA;110F 116D 11BD; # (쿚; 쿚; 쿚; 쿚; 쿚; ) HANGUL SYLLABLE KYOJ
+CFDB;CFDB;110F 116D 11BE;CFDB;110F 116D 11BE; # (쿛; 쿛; 쿛; 쿛; 쿛; ) HANGUL SYLLABLE KYOC
+CFDC;CFDC;110F 116D 11BF;CFDC;110F 116D 11BF; # (쿜; 쿜; 쿜; 쿜; 쿜; ) HANGUL SYLLABLE KYOK
+CFDD;CFDD;110F 116D 11C0;CFDD;110F 116D 11C0; # (쿝; 쿝; 쿝; 쿝; 쿝; ) HANGUL SYLLABLE KYOT
+CFDE;CFDE;110F 116D 11C1;CFDE;110F 116D 11C1; # (쿞; 쿞; 쿞; 쿞; 쿞; ) HANGUL SYLLABLE KYOP
+CFDF;CFDF;110F 116D 11C2;CFDF;110F 116D 11C2; # (쿟; 쿟; 쿟; 쿟; 쿟; ) HANGUL SYLLABLE KYOH
+CFE0;CFE0;110F 116E;CFE0;110F 116E; # (쿠; 쿠; 쿠; 쿠; 쿠; ) HANGUL SYLLABLE KU
+CFE1;CFE1;110F 116E 11A8;CFE1;110F 116E 11A8; # (쿡; 쿡; 쿡; 쿡; 쿡; ) HANGUL SYLLABLE KUG
+CFE2;CFE2;110F 116E 11A9;CFE2;110F 116E 11A9; # (쿢; 쿢; 쿢; 쿢; 쿢; ) HANGUL SYLLABLE KUGG
+CFE3;CFE3;110F 116E 11AA;CFE3;110F 116E 11AA; # (쿣; 쿣; 쿣; 쿣; 쿣; ) HANGUL SYLLABLE KUGS
+CFE4;CFE4;110F 116E 11AB;CFE4;110F 116E 11AB; # (쿤; 쿤; 쿤; 쿤; 쿤; ) HANGUL SYLLABLE KUN
+CFE5;CFE5;110F 116E 11AC;CFE5;110F 116E 11AC; # (쿥; 쿥; 쿥; 쿥; 쿥; ) HANGUL SYLLABLE KUNJ
+CFE6;CFE6;110F 116E 11AD;CFE6;110F 116E 11AD; # (쿦; 쿦; 쿦; 쿦; 쿦; ) HANGUL SYLLABLE KUNH
+CFE7;CFE7;110F 116E 11AE;CFE7;110F 116E 11AE; # (쿧; 쿧; 쿧; 쿧; 쿧; ) HANGUL SYLLABLE KUD
+CFE8;CFE8;110F 116E 11AF;CFE8;110F 116E 11AF; # (쿨; 쿨; 쿨; 쿨; 쿨; ) HANGUL SYLLABLE KUL
+CFE9;CFE9;110F 116E 11B0;CFE9;110F 116E 11B0; # (쿩; 쿩; 쿩; 쿩; 쿩; ) HANGUL SYLLABLE KULG
+CFEA;CFEA;110F 116E 11B1;CFEA;110F 116E 11B1; # (쿪; 쿪; 쿪; 쿪; 쿪; ) HANGUL SYLLABLE KULM
+CFEB;CFEB;110F 116E 11B2;CFEB;110F 116E 11B2; # (쿫; 쿫; 쿫; 쿫; 쿫; ) HANGUL SYLLABLE KULB
+CFEC;CFEC;110F 116E 11B3;CFEC;110F 116E 11B3; # (쿬; 쿬; 쿬; 쿬; 쿬; ) HANGUL SYLLABLE KULS
+CFED;CFED;110F 116E 11B4;CFED;110F 116E 11B4; # (쿭; 쿭; 쿭; 쿭; 쿭; ) HANGUL SYLLABLE KULT
+CFEE;CFEE;110F 116E 11B5;CFEE;110F 116E 11B5; # (쿮; 쿮; 쿮; 쿮; 쿮; ) HANGUL SYLLABLE KULP
+CFEF;CFEF;110F 116E 11B6;CFEF;110F 116E 11B6; # (쿯; 쿯; 쿯; 쿯; 쿯; ) HANGUL SYLLABLE KULH
+CFF0;CFF0;110F 116E 11B7;CFF0;110F 116E 11B7; # (쿰; 쿰; 쿰; 쿰; 쿰; ) HANGUL SYLLABLE KUM
+CFF1;CFF1;110F 116E 11B8;CFF1;110F 116E 11B8; # (쿱; 쿱; 쿱; 쿱; 쿱; ) HANGUL SYLLABLE KUB
+CFF2;CFF2;110F 116E 11B9;CFF2;110F 116E 11B9; # (쿲; 쿲; 쿲; 쿲; 쿲; ) HANGUL SYLLABLE KUBS
+CFF3;CFF3;110F 116E 11BA;CFF3;110F 116E 11BA; # (쿳; 쿳; 쿳; 쿳; 쿳; ) HANGUL SYLLABLE KUS
+CFF4;CFF4;110F 116E 11BB;CFF4;110F 116E 11BB; # (쿴; 쿴; 쿴; 쿴; 쿴; ) HANGUL SYLLABLE KUSS
+CFF5;CFF5;110F 116E 11BC;CFF5;110F 116E 11BC; # (쿵; 쿵; 쿵; 쿵; 쿵; ) HANGUL SYLLABLE KUNG
+CFF6;CFF6;110F 116E 11BD;CFF6;110F 116E 11BD; # (쿶; 쿶; 쿶; 쿶; 쿶; ) HANGUL SYLLABLE KUJ
+CFF7;CFF7;110F 116E 11BE;CFF7;110F 116E 11BE; # (쿷; 쿷; 쿷; 쿷; 쿷; ) HANGUL SYLLABLE KUC
+CFF8;CFF8;110F 116E 11BF;CFF8;110F 116E 11BF; # (쿸; 쿸; 쿸; 쿸; 쿸; ) HANGUL SYLLABLE KUK
+CFF9;CFF9;110F 116E 11C0;CFF9;110F 116E 11C0; # (쿹; 쿹; 쿹; 쿹; 쿹; ) HANGUL SYLLABLE KUT
+CFFA;CFFA;110F 116E 11C1;CFFA;110F 116E 11C1; # (쿺; 쿺; 쿺; 쿺; 쿺; ) HANGUL SYLLABLE KUP
+CFFB;CFFB;110F 116E 11C2;CFFB;110F 116E 11C2; # (쿻; 쿻; 쿻; 쿻; 쿻; ) HANGUL SYLLABLE KUH
+CFFC;CFFC;110F 116F;CFFC;110F 116F; # (쿼; 쿼; 쿼; 쿼; 쿼; ) HANGUL SYLLABLE KWEO
+CFFD;CFFD;110F 116F 11A8;CFFD;110F 116F 11A8; # (쿽; 쿽; 쿽; 쿽; 쿽; ) HANGUL SYLLABLE KWEOG
+CFFE;CFFE;110F 116F 11A9;CFFE;110F 116F 11A9; # (쿾; 쿾; 쿾; 쿾; 쿾; ) HANGUL SYLLABLE KWEOGG
+CFFF;CFFF;110F 116F 11AA;CFFF;110F 116F 11AA; # (쿿; 쿿; 쿿; 쿿; 쿿; ) HANGUL SYLLABLE KWEOGS
+D000;D000;110F 116F 11AB;D000;110F 116F 11AB; # (퀀; 퀀; 퀀; 퀀; 퀀; ) HANGUL SYLLABLE KWEON
+D001;D001;110F 116F 11AC;D001;110F 116F 11AC; # (퀁; 퀁; 퀁; 퀁; 퀁; ) HANGUL SYLLABLE KWEONJ
+D002;D002;110F 116F 11AD;D002;110F 116F 11AD; # (퀂; 퀂; 퀂; 퀂; 퀂; ) HANGUL SYLLABLE KWEONH
+D003;D003;110F 116F 11AE;D003;110F 116F 11AE; # (퀃; 퀃; 퀃; 퀃; 퀃; ) HANGUL SYLLABLE KWEOD
+D004;D004;110F 116F 11AF;D004;110F 116F 11AF; # (퀄; 퀄; 퀄; 퀄; 퀄; ) HANGUL SYLLABLE KWEOL
+D005;D005;110F 116F 11B0;D005;110F 116F 11B0; # (퀅; 퀅; 퀅; 퀅; 퀅; ) HANGUL SYLLABLE KWEOLG
+D006;D006;110F 116F 11B1;D006;110F 116F 11B1; # (퀆; 퀆; 퀆; 퀆; 퀆; ) HANGUL SYLLABLE KWEOLM
+D007;D007;110F 116F 11B2;D007;110F 116F 11B2; # (퀇; 퀇; 퀇; 퀇; 퀇; ) HANGUL SYLLABLE KWEOLB
+D008;D008;110F 116F 11B3;D008;110F 116F 11B3; # (퀈; 퀈; 퀈; 퀈; 퀈; ) HANGUL SYLLABLE KWEOLS
+D009;D009;110F 116F 11B4;D009;110F 116F 11B4; # (퀉; 퀉; 퀉; 퀉; 퀉; ) HANGUL SYLLABLE KWEOLT
+D00A;D00A;110F 116F 11B5;D00A;110F 116F 11B5; # (퀊; 퀊; 퀊; 퀊; 퀊; ) HANGUL SYLLABLE KWEOLP
+D00B;D00B;110F 116F 11B6;D00B;110F 116F 11B6; # (퀋; 퀋; 퀋; 퀋; 퀋; ) HANGUL SYLLABLE KWEOLH
+D00C;D00C;110F 116F 11B7;D00C;110F 116F 11B7; # (퀌; 퀌; 퀌; 퀌; 퀌; ) HANGUL SYLLABLE KWEOM
+D00D;D00D;110F 116F 11B8;D00D;110F 116F 11B8; # (퀍; 퀍; 퀍; 퀍; 퀍; ) HANGUL SYLLABLE KWEOB
+D00E;D00E;110F 116F 11B9;D00E;110F 116F 11B9; # (퀎; 퀎; 퀎; 퀎; 퀎; ) HANGUL SYLLABLE KWEOBS
+D00F;D00F;110F 116F 11BA;D00F;110F 116F 11BA; # (퀏; 퀏; 퀏; 퀏; 퀏; ) HANGUL SYLLABLE KWEOS
+D010;D010;110F 116F 11BB;D010;110F 116F 11BB; # (퀐; 퀐; 퀐; 퀐; 퀐; ) HANGUL SYLLABLE KWEOSS
+D011;D011;110F 116F 11BC;D011;110F 116F 11BC; # (퀑; 퀑; 퀑; 퀑; 퀑; ) HANGUL SYLLABLE KWEONG
+D012;D012;110F 116F 11BD;D012;110F 116F 11BD; # (퀒; 퀒; 퀒; 퀒; 퀒; ) HANGUL SYLLABLE KWEOJ
+D013;D013;110F 116F 11BE;D013;110F 116F 11BE; # (퀓; 퀓; 퀓; 퀓; 퀓; ) HANGUL SYLLABLE KWEOC
+D014;D014;110F 116F 11BF;D014;110F 116F 11BF; # (퀔; 퀔; 퀔; 퀔; 퀔; ) HANGUL SYLLABLE KWEOK
+D015;D015;110F 116F 11C0;D015;110F 116F 11C0; # (퀕; 퀕; 퀕; 퀕; 퀕; ) HANGUL SYLLABLE KWEOT
+D016;D016;110F 116F 11C1;D016;110F 116F 11C1; # (퀖; 퀖; 퀖; 퀖; 퀖; ) HANGUL SYLLABLE KWEOP
+D017;D017;110F 116F 11C2;D017;110F 116F 11C2; # (퀗; 퀗; 퀗; 퀗; 퀗; ) HANGUL SYLLABLE KWEOH
+D018;D018;110F 1170;D018;110F 1170; # (퀘; 퀘; 퀘; 퀘; 퀘; ) HANGUL SYLLABLE KWE
+D019;D019;110F 1170 11A8;D019;110F 1170 11A8; # (퀙; 퀙; 퀙; 퀙; 퀙; ) HANGUL SYLLABLE KWEG
+D01A;D01A;110F 1170 11A9;D01A;110F 1170 11A9; # (퀚; 퀚; 퀚; 퀚; 퀚; ) HANGUL SYLLABLE KWEGG
+D01B;D01B;110F 1170 11AA;D01B;110F 1170 11AA; # (퀛; 퀛; 퀛; 퀛; 퀛; ) HANGUL SYLLABLE KWEGS
+D01C;D01C;110F 1170 11AB;D01C;110F 1170 11AB; # (퀜; 퀜; 퀜; 퀜; 퀜; ) HANGUL SYLLABLE KWEN
+D01D;D01D;110F 1170 11AC;D01D;110F 1170 11AC; # (퀝; 퀝; 퀝; 퀝; 퀝; ) HANGUL SYLLABLE KWENJ
+D01E;D01E;110F 1170 11AD;D01E;110F 1170 11AD; # (퀞; 퀞; 퀞; 퀞; 퀞; ) HANGUL SYLLABLE KWENH
+D01F;D01F;110F 1170 11AE;D01F;110F 1170 11AE; # (퀟; 퀟; 퀟; 퀟; 퀟; ) HANGUL SYLLABLE KWED
+D020;D020;110F 1170 11AF;D020;110F 1170 11AF; # (퀠; 퀠; 퀠; 퀠; 퀠; ) HANGUL SYLLABLE KWEL
+D021;D021;110F 1170 11B0;D021;110F 1170 11B0; # (퀡; 퀡; 퀡; 퀡; 퀡; ) HANGUL SYLLABLE KWELG
+D022;D022;110F 1170 11B1;D022;110F 1170 11B1; # (퀢; 퀢; 퀢; 퀢; 퀢; ) HANGUL SYLLABLE KWELM
+D023;D023;110F 1170 11B2;D023;110F 1170 11B2; # (퀣; 퀣; 퀣; 퀣; 퀣; ) HANGUL SYLLABLE KWELB
+D024;D024;110F 1170 11B3;D024;110F 1170 11B3; # (퀤; 퀤; 퀤; 퀤; 퀤; ) HANGUL SYLLABLE KWELS
+D025;D025;110F 1170 11B4;D025;110F 1170 11B4; # (퀥; 퀥; 퀥; 퀥; 퀥; ) HANGUL SYLLABLE KWELT
+D026;D026;110F 1170 11B5;D026;110F 1170 11B5; # (퀦; 퀦; 퀦; 퀦; 퀦; ) HANGUL SYLLABLE KWELP
+D027;D027;110F 1170 11B6;D027;110F 1170 11B6; # (퀧; 퀧; 퀧; 퀧; 퀧; ) HANGUL SYLLABLE KWELH
+D028;D028;110F 1170 11B7;D028;110F 1170 11B7; # (퀨; 퀨; 퀨; 퀨; 퀨; ) HANGUL SYLLABLE KWEM
+D029;D029;110F 1170 11B8;D029;110F 1170 11B8; # (퀩; 퀩; 퀩; 퀩; 퀩; ) HANGUL SYLLABLE KWEB
+D02A;D02A;110F 1170 11B9;D02A;110F 1170 11B9; # (퀪; 퀪; 퀪; 퀪; 퀪; ) HANGUL SYLLABLE KWEBS
+D02B;D02B;110F 1170 11BA;D02B;110F 1170 11BA; # (퀫; 퀫; 퀫; 퀫; 퀫; ) HANGUL SYLLABLE KWES
+D02C;D02C;110F 1170 11BB;D02C;110F 1170 11BB; # (퀬; 퀬; 퀬; 퀬; 퀬; ) HANGUL SYLLABLE KWESS
+D02D;D02D;110F 1170 11BC;D02D;110F 1170 11BC; # (퀭; 퀭; 퀭; 퀭; 퀭; ) HANGUL SYLLABLE KWENG
+D02E;D02E;110F 1170 11BD;D02E;110F 1170 11BD; # (퀮; 퀮; 퀮; 퀮; 퀮; ) HANGUL SYLLABLE KWEJ
+D02F;D02F;110F 1170 11BE;D02F;110F 1170 11BE; # (퀯; 퀯; 퀯; 퀯; 퀯; ) HANGUL SYLLABLE KWEC
+D030;D030;110F 1170 11BF;D030;110F 1170 11BF; # (퀰; 퀰; 퀰; 퀰; 퀰; ) HANGUL SYLLABLE KWEK
+D031;D031;110F 1170 11C0;D031;110F 1170 11C0; # (퀱; 퀱; 퀱; 퀱; 퀱; ) HANGUL SYLLABLE KWET
+D032;D032;110F 1170 11C1;D032;110F 1170 11C1; # (퀲; 퀲; 퀲; 퀲; 퀲; ) HANGUL SYLLABLE KWEP
+D033;D033;110F 1170 11C2;D033;110F 1170 11C2; # (퀳; 퀳; 퀳; 퀳; 퀳; ) HANGUL SYLLABLE KWEH
+D034;D034;110F 1171;D034;110F 1171; # (퀴; 퀴; 퀴; 퀴; 퀴; ) HANGUL SYLLABLE KWI
+D035;D035;110F 1171 11A8;D035;110F 1171 11A8; # (퀵; 퀵; 퀵; 퀵; 퀵; ) HANGUL SYLLABLE KWIG
+D036;D036;110F 1171 11A9;D036;110F 1171 11A9; # (퀶; 퀶; 퀶; 퀶; 퀶; ) HANGUL SYLLABLE KWIGG
+D037;D037;110F 1171 11AA;D037;110F 1171 11AA; # (퀷; 퀷; 퀷; 퀷; 퀷; ) HANGUL SYLLABLE KWIGS
+D038;D038;110F 1171 11AB;D038;110F 1171 11AB; # (퀸; 퀸; 퀸; 퀸; 퀸; ) HANGUL SYLLABLE KWIN
+D039;D039;110F 1171 11AC;D039;110F 1171 11AC; # (퀹; 퀹; 퀹; 퀹; 퀹; ) HANGUL SYLLABLE KWINJ
+D03A;D03A;110F 1171 11AD;D03A;110F 1171 11AD; # (퀺; 퀺; 퀺; 퀺; 퀺; ) HANGUL SYLLABLE KWINH
+D03B;D03B;110F 1171 11AE;D03B;110F 1171 11AE; # (퀻; 퀻; 퀻; 퀻; 퀻; ) HANGUL SYLLABLE KWID
+D03C;D03C;110F 1171 11AF;D03C;110F 1171 11AF; # (퀼; 퀼; 퀼; 퀼; 퀼; ) HANGUL SYLLABLE KWIL
+D03D;D03D;110F 1171 11B0;D03D;110F 1171 11B0; # (퀽; 퀽; 퀽; 퀽; 퀽; ) HANGUL SYLLABLE KWILG
+D03E;D03E;110F 1171 11B1;D03E;110F 1171 11B1; # (퀾; 퀾; 퀾; 퀾; 퀾; ) HANGUL SYLLABLE KWILM
+D03F;D03F;110F 1171 11B2;D03F;110F 1171 11B2; # (퀿; 퀿; 퀿; 퀿; 퀿; ) HANGUL SYLLABLE KWILB
+D040;D040;110F 1171 11B3;D040;110F 1171 11B3; # (큀; 큀; 큀; 큀; 큀; ) HANGUL SYLLABLE KWILS
+D041;D041;110F 1171 11B4;D041;110F 1171 11B4; # (큁; 큁; 큁; 큁; 큁; ) HANGUL SYLLABLE KWILT
+D042;D042;110F 1171 11B5;D042;110F 1171 11B5; # (큂; 큂; 큂; 큂; 큂; ) HANGUL SYLLABLE KWILP
+D043;D043;110F 1171 11B6;D043;110F 1171 11B6; # (큃; 큃; 큃; 큃; 큃; ) HANGUL SYLLABLE KWILH
+D044;D044;110F 1171 11B7;D044;110F 1171 11B7; # (큄; 큄; 큄; 큄; 큄; ) HANGUL SYLLABLE KWIM
+D045;D045;110F 1171 11B8;D045;110F 1171 11B8; # (큅; 큅; 큅; 큅; 큅; ) HANGUL SYLLABLE KWIB
+D046;D046;110F 1171 11B9;D046;110F 1171 11B9; # (큆; 큆; 큆; 큆; 큆; ) HANGUL SYLLABLE KWIBS
+D047;D047;110F 1171 11BA;D047;110F 1171 11BA; # (큇; 큇; 큇; 큇; 큇; ) HANGUL SYLLABLE KWIS
+D048;D048;110F 1171 11BB;D048;110F 1171 11BB; # (큈; 큈; 큈; 큈; 큈; ) HANGUL SYLLABLE KWISS
+D049;D049;110F 1171 11BC;D049;110F 1171 11BC; # (큉; 큉; 큉; 큉; 큉; ) HANGUL SYLLABLE KWING
+D04A;D04A;110F 1171 11BD;D04A;110F 1171 11BD; # (큊; 큊; 큊; 큊; 큊; ) HANGUL SYLLABLE KWIJ
+D04B;D04B;110F 1171 11BE;D04B;110F 1171 11BE; # (큋; 큋; 큋; 큋; 큋; ) HANGUL SYLLABLE KWIC
+D04C;D04C;110F 1171 11BF;D04C;110F 1171 11BF; # (큌; 큌; 큌; 큌; 큌; ) HANGUL SYLLABLE KWIK
+D04D;D04D;110F 1171 11C0;D04D;110F 1171 11C0; # (큍; 큍; 큍; 큍; 큍; ) HANGUL SYLLABLE KWIT
+D04E;D04E;110F 1171 11C1;D04E;110F 1171 11C1; # (큎; 큎; 큎; 큎; 큎; ) HANGUL SYLLABLE KWIP
+D04F;D04F;110F 1171 11C2;D04F;110F 1171 11C2; # (큏; 큏; 큏; 큏; 큏; ) HANGUL SYLLABLE KWIH
+D050;D050;110F 1172;D050;110F 1172; # (큐; 큐; 큐; 큐; 큐; ) HANGUL SYLLABLE KYU
+D051;D051;110F 1172 11A8;D051;110F 1172 11A8; # (큑; 큑; 큑; 큑; 큑; ) HANGUL SYLLABLE KYUG
+D052;D052;110F 1172 11A9;D052;110F 1172 11A9; # (큒; 큒; 큒; 큒; 큒; ) HANGUL SYLLABLE KYUGG
+D053;D053;110F 1172 11AA;D053;110F 1172 11AA; # (큓; 큓; 큓; 큓; 큓; ) HANGUL SYLLABLE KYUGS
+D054;D054;110F 1172 11AB;D054;110F 1172 11AB; # (큔; 큔; 큔; 큔; 큔; ) HANGUL SYLLABLE KYUN
+D055;D055;110F 1172 11AC;D055;110F 1172 11AC; # (큕; 큕; 큕; 큕; 큕; ) HANGUL SYLLABLE KYUNJ
+D056;D056;110F 1172 11AD;D056;110F 1172 11AD; # (큖; 큖; 큖; 큖; 큖; ) HANGUL SYLLABLE KYUNH
+D057;D057;110F 1172 11AE;D057;110F 1172 11AE; # (큗; 큗; 큗; 큗; 큗; ) HANGUL SYLLABLE KYUD
+D058;D058;110F 1172 11AF;D058;110F 1172 11AF; # (큘; 큘; 큘; 큘; 큘; ) HANGUL SYLLABLE KYUL
+D059;D059;110F 1172 11B0;D059;110F 1172 11B0; # (큙; 큙; 큙; 큙; 큙; ) HANGUL SYLLABLE KYULG
+D05A;D05A;110F 1172 11B1;D05A;110F 1172 11B1; # (큚; 큚; 큚; 큚; 큚; ) HANGUL SYLLABLE KYULM
+D05B;D05B;110F 1172 11B2;D05B;110F 1172 11B2; # (큛; 큛; 큛; 큛; 큛; ) HANGUL SYLLABLE KYULB
+D05C;D05C;110F 1172 11B3;D05C;110F 1172 11B3; # (큜; 큜; 큜; 큜; 큜; ) HANGUL SYLLABLE KYULS
+D05D;D05D;110F 1172 11B4;D05D;110F 1172 11B4; # (큝; 큝; 큝; 큝; 큝; ) HANGUL SYLLABLE KYULT
+D05E;D05E;110F 1172 11B5;D05E;110F 1172 11B5; # (큞; 큞; 큞; 큞; 큞; ) HANGUL SYLLABLE KYULP
+D05F;D05F;110F 1172 11B6;D05F;110F 1172 11B6; # (큟; 큟; 큟; 큟; 큟; ) HANGUL SYLLABLE KYULH
+D060;D060;110F 1172 11B7;D060;110F 1172 11B7; # (큠; 큠; 큠; 큠; 큠; ) HANGUL SYLLABLE KYUM
+D061;D061;110F 1172 11B8;D061;110F 1172 11B8; # (큡; 큡; 큡; 큡; 큡; ) HANGUL SYLLABLE KYUB
+D062;D062;110F 1172 11B9;D062;110F 1172 11B9; # (큢; 큢; 큢; 큢; 큢; ) HANGUL SYLLABLE KYUBS
+D063;D063;110F 1172 11BA;D063;110F 1172 11BA; # (큣; 큣; 큣; 큣; 큣; ) HANGUL SYLLABLE KYUS
+D064;D064;110F 1172 11BB;D064;110F 1172 11BB; # (큤; 큤; 큤; 큤; 큤; ) HANGUL SYLLABLE KYUSS
+D065;D065;110F 1172 11BC;D065;110F 1172 11BC; # (큥; 큥; 큥; 큥; 큥; ) HANGUL SYLLABLE KYUNG
+D066;D066;110F 1172 11BD;D066;110F 1172 11BD; # (큦; 큦; 큦; 큦; 큦; ) HANGUL SYLLABLE KYUJ
+D067;D067;110F 1172 11BE;D067;110F 1172 11BE; # (큧; 큧; 큧; 큧; 큧; ) HANGUL SYLLABLE KYUC
+D068;D068;110F 1172 11BF;D068;110F 1172 11BF; # (큨; 큨; 큨; 큨; 큨; ) HANGUL SYLLABLE KYUK
+D069;D069;110F 1172 11C0;D069;110F 1172 11C0; # (큩; 큩; 큩; 큩; 큩; ) HANGUL SYLLABLE KYUT
+D06A;D06A;110F 1172 11C1;D06A;110F 1172 11C1; # (큪; 큪; 큪; 큪; 큪; ) HANGUL SYLLABLE KYUP
+D06B;D06B;110F 1172 11C2;D06B;110F 1172 11C2; # (큫; 큫; 큫; 큫; 큫; ) HANGUL SYLLABLE KYUH
+D06C;D06C;110F 1173;D06C;110F 1173; # (크; 크; 크; 크; 크; ) HANGUL SYLLABLE KEU
+D06D;D06D;110F 1173 11A8;D06D;110F 1173 11A8; # (큭; 큭; 큭; 큭; 큭; ) HANGUL SYLLABLE KEUG
+D06E;D06E;110F 1173 11A9;D06E;110F 1173 11A9; # (큮; 큮; 큮; 큮; 큮; ) HANGUL SYLLABLE KEUGG
+D06F;D06F;110F 1173 11AA;D06F;110F 1173 11AA; # (큯; 큯; 큯; 큯; 큯; ) HANGUL SYLLABLE KEUGS
+D070;D070;110F 1173 11AB;D070;110F 1173 11AB; # (큰; 큰; 큰; 큰; 큰; ) HANGUL SYLLABLE KEUN
+D071;D071;110F 1173 11AC;D071;110F 1173 11AC; # (큱; 큱; 큱; 큱; 큱; ) HANGUL SYLLABLE KEUNJ
+D072;D072;110F 1173 11AD;D072;110F 1173 11AD; # (큲; 큲; 큲; 큲; 큲; ) HANGUL SYLLABLE KEUNH
+D073;D073;110F 1173 11AE;D073;110F 1173 11AE; # (큳; 큳; 큳; 큳; 큳; ) HANGUL SYLLABLE KEUD
+D074;D074;110F 1173 11AF;D074;110F 1173 11AF; # (클; 클; 클; 클; 클; ) HANGUL SYLLABLE KEUL
+D075;D075;110F 1173 11B0;D075;110F 1173 11B0; # (큵; 큵; 큵; 큵; 큵; ) HANGUL SYLLABLE KEULG
+D076;D076;110F 1173 11B1;D076;110F 1173 11B1; # (큶; 큶; 큶; 큶; 큶; ) HANGUL SYLLABLE KEULM
+D077;D077;110F 1173 11B2;D077;110F 1173 11B2; # (큷; 큷; 큷; 큷; 큷; ) HANGUL SYLLABLE KEULB
+D078;D078;110F 1173 11B3;D078;110F 1173 11B3; # (큸; 큸; 큸; 큸; 큸; ) HANGUL SYLLABLE KEULS
+D079;D079;110F 1173 11B4;D079;110F 1173 11B4; # (큹; 큹; 큹; 큹; 큹; ) HANGUL SYLLABLE KEULT
+D07A;D07A;110F 1173 11B5;D07A;110F 1173 11B5; # (큺; 큺; 큺; 큺; 큺; ) HANGUL SYLLABLE KEULP
+D07B;D07B;110F 1173 11B6;D07B;110F 1173 11B6; # (큻; 큻; 큻; 큻; 큻; ) HANGUL SYLLABLE KEULH
+D07C;D07C;110F 1173 11B7;D07C;110F 1173 11B7; # (큼; 큼; 큼; 큼; 큼; ) HANGUL SYLLABLE KEUM
+D07D;D07D;110F 1173 11B8;D07D;110F 1173 11B8; # (큽; 큽; 큽; 큽; 큽; ) HANGUL SYLLABLE KEUB
+D07E;D07E;110F 1173 11B9;D07E;110F 1173 11B9; # (큾; 큾; 큾; 큾; 큾; ) HANGUL SYLLABLE KEUBS
+D07F;D07F;110F 1173 11BA;D07F;110F 1173 11BA; # (큿; 큿; 큿; 큿; 큿; ) HANGUL SYLLABLE KEUS
+D080;D080;110F 1173 11BB;D080;110F 1173 11BB; # (킀; 킀; 킀; 킀; 킀; ) HANGUL SYLLABLE KEUSS
+D081;D081;110F 1173 11BC;D081;110F 1173 11BC; # (킁; 킁; 킁; 킁; 킁; ) HANGUL SYLLABLE KEUNG
+D082;D082;110F 1173 11BD;D082;110F 1173 11BD; # (킂; 킂; 킂; 킂; 킂; ) HANGUL SYLLABLE KEUJ
+D083;D083;110F 1173 11BE;D083;110F 1173 11BE; # (킃; 킃; 킃; 킃; 킃; ) HANGUL SYLLABLE KEUC
+D084;D084;110F 1173 11BF;D084;110F 1173 11BF; # (킄; 킄; 킄; 킄; 킄; ) HANGUL SYLLABLE KEUK
+D085;D085;110F 1173 11C0;D085;110F 1173 11C0; # (킅; 킅; 킅; 킅; 킅; ) HANGUL SYLLABLE KEUT
+D086;D086;110F 1173 11C1;D086;110F 1173 11C1; # (킆; 킆; 킆; 킆; 킆; ) HANGUL SYLLABLE KEUP
+D087;D087;110F 1173 11C2;D087;110F 1173 11C2; # (킇; 킇; 킇; 킇; 킇; ) HANGUL SYLLABLE KEUH
+D088;D088;110F 1174;D088;110F 1174; # (킈; 킈; 킈; 킈; 킈; ) HANGUL SYLLABLE KYI
+D089;D089;110F 1174 11A8;D089;110F 1174 11A8; # (킉; 킉; 킉; 킉; 킉; ) HANGUL SYLLABLE KYIG
+D08A;D08A;110F 1174 11A9;D08A;110F 1174 11A9; # (킊; 킊; 킊; 킊; 킊; ) HANGUL SYLLABLE KYIGG
+D08B;D08B;110F 1174 11AA;D08B;110F 1174 11AA; # (킋; 킋; 킋; 킋; 킋; ) HANGUL SYLLABLE KYIGS
+D08C;D08C;110F 1174 11AB;D08C;110F 1174 11AB; # (킌; 킌; 킌; 킌; 킌; ) HANGUL SYLLABLE KYIN
+D08D;D08D;110F 1174 11AC;D08D;110F 1174 11AC; # (킍; 킍; 킍; 킍; 킍; ) HANGUL SYLLABLE KYINJ
+D08E;D08E;110F 1174 11AD;D08E;110F 1174 11AD; # (킎; 킎; 킎; 킎; 킎; ) HANGUL SYLLABLE KYINH
+D08F;D08F;110F 1174 11AE;D08F;110F 1174 11AE; # (킏; 킏; 킏; 킏; 킏; ) HANGUL SYLLABLE KYID
+D090;D090;110F 1174 11AF;D090;110F 1174 11AF; # (킐; 킐; 킐; 킐; 킐; ) HANGUL SYLLABLE KYIL
+D091;D091;110F 1174 11B0;D091;110F 1174 11B0; # (킑; 킑; 킑; 킑; 킑; ) HANGUL SYLLABLE KYILG
+D092;D092;110F 1174 11B1;D092;110F 1174 11B1; # (킒; 킒; 킒; 킒; 킒; ) HANGUL SYLLABLE KYILM
+D093;D093;110F 1174 11B2;D093;110F 1174 11B2; # (킓; 킓; 킓; 킓; 킓; ) HANGUL SYLLABLE KYILB
+D094;D094;110F 1174 11B3;D094;110F 1174 11B3; # (킔; 킔; 킔; 킔; 킔; ) HANGUL SYLLABLE KYILS
+D095;D095;110F 1174 11B4;D095;110F 1174 11B4; # (킕; 킕; 킕; 킕; 킕; ) HANGUL SYLLABLE KYILT
+D096;D096;110F 1174 11B5;D096;110F 1174 11B5; # (킖; 킖; 킖; 킖; 킖; ) HANGUL SYLLABLE KYILP
+D097;D097;110F 1174 11B6;D097;110F 1174 11B6; # (킗; 킗; 킗; 킗; 킗; ) HANGUL SYLLABLE KYILH
+D098;D098;110F 1174 11B7;D098;110F 1174 11B7; # (킘; 킘; 킘; 킘; 킘; ) HANGUL SYLLABLE KYIM
+D099;D099;110F 1174 11B8;D099;110F 1174 11B8; # (킙; 킙; 킙; 킙; 킙; ) HANGUL SYLLABLE KYIB
+D09A;D09A;110F 1174 11B9;D09A;110F 1174 11B9; # (킚; 킚; 킚; 킚; 킚; ) HANGUL SYLLABLE KYIBS
+D09B;D09B;110F 1174 11BA;D09B;110F 1174 11BA; # (킛; 킛; 킛; 킛; 킛; ) HANGUL SYLLABLE KYIS
+D09C;D09C;110F 1174 11BB;D09C;110F 1174 11BB; # (킜; 킜; 킜; 킜; 킜; ) HANGUL SYLLABLE KYISS
+D09D;D09D;110F 1174 11BC;D09D;110F 1174 11BC; # (킝; 킝; 킝; 킝; 킝; ) HANGUL SYLLABLE KYING
+D09E;D09E;110F 1174 11BD;D09E;110F 1174 11BD; # (킞; 킞; 킞; 킞; 킞; ) HANGUL SYLLABLE KYIJ
+D09F;D09F;110F 1174 11BE;D09F;110F 1174 11BE; # (킟; 킟; 킟; 킟; 킟; ) HANGUL SYLLABLE KYIC
+D0A0;D0A0;110F 1174 11BF;D0A0;110F 1174 11BF; # (킠; 킠; 킠; 킠; 킠; ) HANGUL SYLLABLE KYIK
+D0A1;D0A1;110F 1174 11C0;D0A1;110F 1174 11C0; # (킡; 킡; 킡; 킡; 킡; ) HANGUL SYLLABLE KYIT
+D0A2;D0A2;110F 1174 11C1;D0A2;110F 1174 11C1; # (킢; 킢; 킢; 킢; 킢; ) HANGUL SYLLABLE KYIP
+D0A3;D0A3;110F 1174 11C2;D0A3;110F 1174 11C2; # (킣; 킣; 킣; 킣; 킣; ) HANGUL SYLLABLE KYIH
+D0A4;D0A4;110F 1175;D0A4;110F 1175; # (키; 키; 키; 키; 키; ) HANGUL SYLLABLE KI
+D0A5;D0A5;110F 1175 11A8;D0A5;110F 1175 11A8; # (킥; 킥; 킥; 킥; 킥; ) HANGUL SYLLABLE KIG
+D0A6;D0A6;110F 1175 11A9;D0A6;110F 1175 11A9; # (킦; 킦; 킦; 킦; 킦; ) HANGUL SYLLABLE KIGG
+D0A7;D0A7;110F 1175 11AA;D0A7;110F 1175 11AA; # (킧; 킧; 킧; 킧; 킧; ) HANGUL SYLLABLE KIGS
+D0A8;D0A8;110F 1175 11AB;D0A8;110F 1175 11AB; # (킨; 킨; 킨; 킨; 킨; ) HANGUL SYLLABLE KIN
+D0A9;D0A9;110F 1175 11AC;D0A9;110F 1175 11AC; # (킩; 킩; 킩; 킩; 킩; ) HANGUL SYLLABLE KINJ
+D0AA;D0AA;110F 1175 11AD;D0AA;110F 1175 11AD; # (킪; 킪; 킪; 킪; 킪; ) HANGUL SYLLABLE KINH
+D0AB;D0AB;110F 1175 11AE;D0AB;110F 1175 11AE; # (킫; 킫; 킫; 킫; 킫; ) HANGUL SYLLABLE KID
+D0AC;D0AC;110F 1175 11AF;D0AC;110F 1175 11AF; # (킬; 킬; 킬; 킬; 킬; ) HANGUL SYLLABLE KIL
+D0AD;D0AD;110F 1175 11B0;D0AD;110F 1175 11B0; # (킭; 킭; 킭; 킭; 킭; ) HANGUL SYLLABLE KILG
+D0AE;D0AE;110F 1175 11B1;D0AE;110F 1175 11B1; # (킮; 킮; 킮; 킮; 킮; ) HANGUL SYLLABLE KILM
+D0AF;D0AF;110F 1175 11B2;D0AF;110F 1175 11B2; # (킯; 킯; 킯; 킯; 킯; ) HANGUL SYLLABLE KILB
+D0B0;D0B0;110F 1175 11B3;D0B0;110F 1175 11B3; # (킰; 킰; 킰; 킰; 킰; ) HANGUL SYLLABLE KILS
+D0B1;D0B1;110F 1175 11B4;D0B1;110F 1175 11B4; # (킱; 킱; 킱; 킱; 킱; ) HANGUL SYLLABLE KILT
+D0B2;D0B2;110F 1175 11B5;D0B2;110F 1175 11B5; # (킲; 킲; 킲; 킲; 킲; ) HANGUL SYLLABLE KILP
+D0B3;D0B3;110F 1175 11B6;D0B3;110F 1175 11B6; # (킳; 킳; 킳; 킳; 킳; ) HANGUL SYLLABLE KILH
+D0B4;D0B4;110F 1175 11B7;D0B4;110F 1175 11B7; # (킴; 킴; 킴; 킴; 킴; ) HANGUL SYLLABLE KIM
+D0B5;D0B5;110F 1175 11B8;D0B5;110F 1175 11B8; # (킵; 킵; 킵; 킵; 킵; ) HANGUL SYLLABLE KIB
+D0B6;D0B6;110F 1175 11B9;D0B6;110F 1175 11B9; # (킶; 킶; 킶; 킶; 킶; ) HANGUL SYLLABLE KIBS
+D0B7;D0B7;110F 1175 11BA;D0B7;110F 1175 11BA; # (킷; 킷; 킷; 킷; 킷; ) HANGUL SYLLABLE KIS
+D0B8;D0B8;110F 1175 11BB;D0B8;110F 1175 11BB; # (킸; 킸; 킸; 킸; 킸; ) HANGUL SYLLABLE KISS
+D0B9;D0B9;110F 1175 11BC;D0B9;110F 1175 11BC; # (킹; 킹; 킹; 킹; 킹; ) HANGUL SYLLABLE KING
+D0BA;D0BA;110F 1175 11BD;D0BA;110F 1175 11BD; # (킺; 킺; 킺; 킺; 킺; ) HANGUL SYLLABLE KIJ
+D0BB;D0BB;110F 1175 11BE;D0BB;110F 1175 11BE; # (킻; 킻; 킻; 킻; 킻; ) HANGUL SYLLABLE KIC
+D0BC;D0BC;110F 1175 11BF;D0BC;110F 1175 11BF; # (킼; 킼; 킼; 킼; 킼; ) HANGUL SYLLABLE KIK
+D0BD;D0BD;110F 1175 11C0;D0BD;110F 1175 11C0; # (킽; 킽; 킽; 킽; 킽; ) HANGUL SYLLABLE KIT
+D0BE;D0BE;110F 1175 11C1;D0BE;110F 1175 11C1; # (킾; 킾; 킾; 킾; 킾; ) HANGUL SYLLABLE KIP
+D0BF;D0BF;110F 1175 11C2;D0BF;110F 1175 11C2; # (킿; 킿; 킿; 킿; 킿; ) HANGUL SYLLABLE KIH
+D0C0;D0C0;1110 1161;D0C0;1110 1161; # (타; 타; 타; 타; 타; ) HANGUL SYLLABLE TA
+D0C1;D0C1;1110 1161 11A8;D0C1;1110 1161 11A8; # (탁; 탁; 탁; 탁; 탁; ) HANGUL SYLLABLE TAG
+D0C2;D0C2;1110 1161 11A9;D0C2;1110 1161 11A9; # (탂; 탂; 탂; 탂; 탂; ) HANGUL SYLLABLE TAGG
+D0C3;D0C3;1110 1161 11AA;D0C3;1110 1161 11AA; # (탃; 탃; 탃; 탃; 탃; ) HANGUL SYLLABLE TAGS
+D0C4;D0C4;1110 1161 11AB;D0C4;1110 1161 11AB; # (탄; 탄; 탄; 탄; 탄; ) HANGUL SYLLABLE TAN
+D0C5;D0C5;1110 1161 11AC;D0C5;1110 1161 11AC; # (탅; 탅; 탅; 탅; 탅; ) HANGUL SYLLABLE TANJ
+D0C6;D0C6;1110 1161 11AD;D0C6;1110 1161 11AD; # (탆; 탆; 탆; 탆; 탆; ) HANGUL SYLLABLE TANH
+D0C7;D0C7;1110 1161 11AE;D0C7;1110 1161 11AE; # (탇; 탇; 탇; 탇; 탇; ) HANGUL SYLLABLE TAD
+D0C8;D0C8;1110 1161 11AF;D0C8;1110 1161 11AF; # (탈; 탈; 탈; 탈; 탈; ) HANGUL SYLLABLE TAL
+D0C9;D0C9;1110 1161 11B0;D0C9;1110 1161 11B0; # (탉; 탉; 탉; 탉; 탉; ) HANGUL SYLLABLE TALG
+D0CA;D0CA;1110 1161 11B1;D0CA;1110 1161 11B1; # (탊; 탊; 탊; 탊; 탊; ) HANGUL SYLLABLE TALM
+D0CB;D0CB;1110 1161 11B2;D0CB;1110 1161 11B2; # (탋; 탋; 탋; 탋; 탋; ) HANGUL SYLLABLE TALB
+D0CC;D0CC;1110 1161 11B3;D0CC;1110 1161 11B3; # (탌; 탌; 탌; 탌; 탌; ) HANGUL SYLLABLE TALS
+D0CD;D0CD;1110 1161 11B4;D0CD;1110 1161 11B4; # (탍; 탍; 탍; 탍; 탍; ) HANGUL SYLLABLE TALT
+D0CE;D0CE;1110 1161 11B5;D0CE;1110 1161 11B5; # (탎; 탎; 탎; 탎; 탎; ) HANGUL SYLLABLE TALP
+D0CF;D0CF;1110 1161 11B6;D0CF;1110 1161 11B6; # (탏; 탏; 탏; 탏; 탏; ) HANGUL SYLLABLE TALH
+D0D0;D0D0;1110 1161 11B7;D0D0;1110 1161 11B7; # (탐; 탐; 탐; 탐; 탐; ) HANGUL SYLLABLE TAM
+D0D1;D0D1;1110 1161 11B8;D0D1;1110 1161 11B8; # (탑; 탑; 탑; 탑; 탑; ) HANGUL SYLLABLE TAB
+D0D2;D0D2;1110 1161 11B9;D0D2;1110 1161 11B9; # (탒; 탒; 탒; 탒; 탒; ) HANGUL SYLLABLE TABS
+D0D3;D0D3;1110 1161 11BA;D0D3;1110 1161 11BA; # (탓; 탓; 탓; 탓; 탓; ) HANGUL SYLLABLE TAS
+D0D4;D0D4;1110 1161 11BB;D0D4;1110 1161 11BB; # (탔; 탔; 탔; 탔; 탔; ) HANGUL SYLLABLE TASS
+D0D5;D0D5;1110 1161 11BC;D0D5;1110 1161 11BC; # (탕; 탕; 탕; 탕; 탕; ) HANGUL SYLLABLE TANG
+D0D6;D0D6;1110 1161 11BD;D0D6;1110 1161 11BD; # (탖; 탖; 탖; 탖; 탖; ) HANGUL SYLLABLE TAJ
+D0D7;D0D7;1110 1161 11BE;D0D7;1110 1161 11BE; # (탗; 탗; 탗; 탗; 탗; ) HANGUL SYLLABLE TAC
+D0D8;D0D8;1110 1161 11BF;D0D8;1110 1161 11BF; # (탘; 탘; 탘; 탘; 탘; ) HANGUL SYLLABLE TAK
+D0D9;D0D9;1110 1161 11C0;D0D9;1110 1161 11C0; # (탙; 탙; 탙; 탙; 탙; ) HANGUL SYLLABLE TAT
+D0DA;D0DA;1110 1161 11C1;D0DA;1110 1161 11C1; # (탚; 탚; 탚; 탚; 탚; ) HANGUL SYLLABLE TAP
+D0DB;D0DB;1110 1161 11C2;D0DB;1110 1161 11C2; # (탛; 탛; 탛; 탛; 탛; ) HANGUL SYLLABLE TAH
+D0DC;D0DC;1110 1162;D0DC;1110 1162; # (태; 태; 태; 태; 태; ) HANGUL SYLLABLE TAE
+D0DD;D0DD;1110 1162 11A8;D0DD;1110 1162 11A8; # (택; 택; 택; 택; 택; ) HANGUL SYLLABLE TAEG
+D0DE;D0DE;1110 1162 11A9;D0DE;1110 1162 11A9; # (탞; 탞; 탞; 탞; 탞; ) HANGUL SYLLABLE TAEGG
+D0DF;D0DF;1110 1162 11AA;D0DF;1110 1162 11AA; # (탟; 탟; 탟; 탟; 탟; ) HANGUL SYLLABLE TAEGS
+D0E0;D0E0;1110 1162 11AB;D0E0;1110 1162 11AB; # (탠; 탠; 탠; 탠; 탠; ) HANGUL SYLLABLE TAEN
+D0E1;D0E1;1110 1162 11AC;D0E1;1110 1162 11AC; # (탡; 탡; 탡; 탡; 탡; ) HANGUL SYLLABLE TAENJ
+D0E2;D0E2;1110 1162 11AD;D0E2;1110 1162 11AD; # (탢; 탢; 탢; 탢; 탢; ) HANGUL SYLLABLE TAENH
+D0E3;D0E3;1110 1162 11AE;D0E3;1110 1162 11AE; # (탣; 탣; 탣; 탣; 탣; ) HANGUL SYLLABLE TAED
+D0E4;D0E4;1110 1162 11AF;D0E4;1110 1162 11AF; # (탤; 탤; 탤; 탤; 탤; ) HANGUL SYLLABLE TAEL
+D0E5;D0E5;1110 1162 11B0;D0E5;1110 1162 11B0; # (탥; 탥; 탥; 탥; 탥; ) HANGUL SYLLABLE TAELG
+D0E6;D0E6;1110 1162 11B1;D0E6;1110 1162 11B1; # (탦; 탦; 탦; 탦; 탦; ) HANGUL SYLLABLE TAELM
+D0E7;D0E7;1110 1162 11B2;D0E7;1110 1162 11B2; # (탧; 탧; 탧; 탧; 탧; ) HANGUL SYLLABLE TAELB
+D0E8;D0E8;1110 1162 11B3;D0E8;1110 1162 11B3; # (탨; 탨; 탨; 탨; 탨; ) HANGUL SYLLABLE TAELS
+D0E9;D0E9;1110 1162 11B4;D0E9;1110 1162 11B4; # (탩; 탩; 탩; 탩; 탩; ) HANGUL SYLLABLE TAELT
+D0EA;D0EA;1110 1162 11B5;D0EA;1110 1162 11B5; # (탪; 탪; 탪; 탪; 탪; ) HANGUL SYLLABLE TAELP
+D0EB;D0EB;1110 1162 11B6;D0EB;1110 1162 11B6; # (탫; 탫; 탫; 탫; 탫; ) HANGUL SYLLABLE TAELH
+D0EC;D0EC;1110 1162 11B7;D0EC;1110 1162 11B7; # (탬; 탬; 탬; 탬; 탬; ) HANGUL SYLLABLE TAEM
+D0ED;D0ED;1110 1162 11B8;D0ED;1110 1162 11B8; # (탭; 탭; 탭; 탭; 탭; ) HANGUL SYLLABLE TAEB
+D0EE;D0EE;1110 1162 11B9;D0EE;1110 1162 11B9; # (탮; 탮; 탮; 탮; 탮; ) HANGUL SYLLABLE TAEBS
+D0EF;D0EF;1110 1162 11BA;D0EF;1110 1162 11BA; # (탯; 탯; 탯; 탯; 탯; ) HANGUL SYLLABLE TAES
+D0F0;D0F0;1110 1162 11BB;D0F0;1110 1162 11BB; # (탰; 탰; 탰; 탰; 탰; ) HANGUL SYLLABLE TAESS
+D0F1;D0F1;1110 1162 11BC;D0F1;1110 1162 11BC; # (탱; 탱; 탱; 탱; 탱; ) HANGUL SYLLABLE TAENG
+D0F2;D0F2;1110 1162 11BD;D0F2;1110 1162 11BD; # (탲; 탲; 탲; 탲; 탲; ) HANGUL SYLLABLE TAEJ
+D0F3;D0F3;1110 1162 11BE;D0F3;1110 1162 11BE; # (탳; 탳; 탳; 탳; 탳; ) HANGUL SYLLABLE TAEC
+D0F4;D0F4;1110 1162 11BF;D0F4;1110 1162 11BF; # (탴; 탴; 탴; 탴; 탴; ) HANGUL SYLLABLE TAEK
+D0F5;D0F5;1110 1162 11C0;D0F5;1110 1162 11C0; # (탵; 탵; 탵; 탵; 탵; ) HANGUL SYLLABLE TAET
+D0F6;D0F6;1110 1162 11C1;D0F6;1110 1162 11C1; # (탶; 탶; 탶; 탶; 탶; ) HANGUL SYLLABLE TAEP
+D0F7;D0F7;1110 1162 11C2;D0F7;1110 1162 11C2; # (탷; 탷; 탷; 탷; 탷; ) HANGUL SYLLABLE TAEH
+D0F8;D0F8;1110 1163;D0F8;1110 1163; # (탸; 탸; 탸; 탸; 탸; ) HANGUL SYLLABLE TYA
+D0F9;D0F9;1110 1163 11A8;D0F9;1110 1163 11A8; # (탹; 탹; 탹; 탹; 탹; ) HANGUL SYLLABLE TYAG
+D0FA;D0FA;1110 1163 11A9;D0FA;1110 1163 11A9; # (탺; 탺; 탺; 탺; 탺; ) HANGUL SYLLABLE TYAGG
+D0FB;D0FB;1110 1163 11AA;D0FB;1110 1163 11AA; # (탻; 탻; 탻; 탻; 탻; ) HANGUL SYLLABLE TYAGS
+D0FC;D0FC;1110 1163 11AB;D0FC;1110 1163 11AB; # (탼; 탼; 탼; 탼; 탼; ) HANGUL SYLLABLE TYAN
+D0FD;D0FD;1110 1163 11AC;D0FD;1110 1163 11AC; # (탽; 탽; 탽; 탽; 탽; ) HANGUL SYLLABLE TYANJ
+D0FE;D0FE;1110 1163 11AD;D0FE;1110 1163 11AD; # (탾; 탾; 탾; 탾; 탾; ) HANGUL SYLLABLE TYANH
+D0FF;D0FF;1110 1163 11AE;D0FF;1110 1163 11AE; # (탿; 탿; 탿; 탿; 탿; ) HANGUL SYLLABLE TYAD
+D100;D100;1110 1163 11AF;D100;1110 1163 11AF; # (턀; 턀; 턀; 턀; 턀; ) HANGUL SYLLABLE TYAL
+D101;D101;1110 1163 11B0;D101;1110 1163 11B0; # (턁; 턁; 턁; 턁; 턁; ) HANGUL SYLLABLE TYALG
+D102;D102;1110 1163 11B1;D102;1110 1163 11B1; # (턂; 턂; 턂; 턂; 턂; ) HANGUL SYLLABLE TYALM
+D103;D103;1110 1163 11B2;D103;1110 1163 11B2; # (턃; 턃; 턃; 턃; 턃; ) HANGUL SYLLABLE TYALB
+D104;D104;1110 1163 11B3;D104;1110 1163 11B3; # (턄; 턄; 턄; 턄; 턄; ) HANGUL SYLLABLE TYALS
+D105;D105;1110 1163 11B4;D105;1110 1163 11B4; # (턅; 턅; 턅; 턅; 턅; ) HANGUL SYLLABLE TYALT
+D106;D106;1110 1163 11B5;D106;1110 1163 11B5; # (턆; 턆; 턆; 턆; 턆; ) HANGUL SYLLABLE TYALP
+D107;D107;1110 1163 11B6;D107;1110 1163 11B6; # (턇; 턇; 턇; 턇; 턇; ) HANGUL SYLLABLE TYALH
+D108;D108;1110 1163 11B7;D108;1110 1163 11B7; # (턈; 턈; 턈; 턈; 턈; ) HANGUL SYLLABLE TYAM
+D109;D109;1110 1163 11B8;D109;1110 1163 11B8; # (턉; 턉; 턉; 턉; 턉; ) HANGUL SYLLABLE TYAB
+D10A;D10A;1110 1163 11B9;D10A;1110 1163 11B9; # (턊; 턊; 턊; 턊; 턊; ) HANGUL SYLLABLE TYABS
+D10B;D10B;1110 1163 11BA;D10B;1110 1163 11BA; # (턋; 턋; 턋; 턋; 턋; ) HANGUL SYLLABLE TYAS
+D10C;D10C;1110 1163 11BB;D10C;1110 1163 11BB; # (턌; 턌; 턌; 턌; 턌; ) HANGUL SYLLABLE TYASS
+D10D;D10D;1110 1163 11BC;D10D;1110 1163 11BC; # (턍; 턍; 턍; 턍; 턍; ) HANGUL SYLLABLE TYANG
+D10E;D10E;1110 1163 11BD;D10E;1110 1163 11BD; # (턎; 턎; 턎; 턎; 턎; ) HANGUL SYLLABLE TYAJ
+D10F;D10F;1110 1163 11BE;D10F;1110 1163 11BE; # (턏; 턏; 턏; 턏; 턏; ) HANGUL SYLLABLE TYAC
+D110;D110;1110 1163 11BF;D110;1110 1163 11BF; # (턐; 턐; 턐; 턐; 턐; ) HANGUL SYLLABLE TYAK
+D111;D111;1110 1163 11C0;D111;1110 1163 11C0; # (턑; 턑; 턑; 턑; 턑; ) HANGUL SYLLABLE TYAT
+D112;D112;1110 1163 11C1;D112;1110 1163 11C1; # (턒; 턒; 턒; 턒; 턒; ) HANGUL SYLLABLE TYAP
+D113;D113;1110 1163 11C2;D113;1110 1163 11C2; # (턓; 턓; 턓; 턓; 턓; ) HANGUL SYLLABLE TYAH
+D114;D114;1110 1164;D114;1110 1164; # (턔; 턔; 턔; 턔; 턔; ) HANGUL SYLLABLE TYAE
+D115;D115;1110 1164 11A8;D115;1110 1164 11A8; # (턕; 턕; 턕; 턕; 턕; ) HANGUL SYLLABLE TYAEG
+D116;D116;1110 1164 11A9;D116;1110 1164 11A9; # (턖; 턖; 턖; 턖; 턖; ) HANGUL SYLLABLE TYAEGG
+D117;D117;1110 1164 11AA;D117;1110 1164 11AA; # (턗; 턗; 턗; 턗; 턗; ) HANGUL SYLLABLE TYAEGS
+D118;D118;1110 1164 11AB;D118;1110 1164 11AB; # (턘; 턘; 턘; 턘; 턘; ) HANGUL SYLLABLE TYAEN
+D119;D119;1110 1164 11AC;D119;1110 1164 11AC; # (턙; 턙; 턙; 턙; 턙; ) HANGUL SYLLABLE TYAENJ
+D11A;D11A;1110 1164 11AD;D11A;1110 1164 11AD; # (턚; 턚; 턚; 턚; 턚; ) HANGUL SYLLABLE TYAENH
+D11B;D11B;1110 1164 11AE;D11B;1110 1164 11AE; # (턛; 턛; 턛; 턛; 턛; ) HANGUL SYLLABLE TYAED
+D11C;D11C;1110 1164 11AF;D11C;1110 1164 11AF; # (턜; 턜; 턜; 턜; 턜; ) HANGUL SYLLABLE TYAEL
+D11D;D11D;1110 1164 11B0;D11D;1110 1164 11B0; # (턝; 턝; 턝; 턝; 턝; ) HANGUL SYLLABLE TYAELG
+D11E;D11E;1110 1164 11B1;D11E;1110 1164 11B1; # (턞; 턞; 턞; 턞; 턞; ) HANGUL SYLLABLE TYAELM
+D11F;D11F;1110 1164 11B2;D11F;1110 1164 11B2; # (턟; 턟; 턟; 턟; 턟; ) HANGUL SYLLABLE TYAELB
+D120;D120;1110 1164 11B3;D120;1110 1164 11B3; # (턠; 턠; 턠; 턠; 턠; ) HANGUL SYLLABLE TYAELS
+D121;D121;1110 1164 11B4;D121;1110 1164 11B4; # (턡; 턡; 턡; 턡; 턡; ) HANGUL SYLLABLE TYAELT
+D122;D122;1110 1164 11B5;D122;1110 1164 11B5; # (턢; 턢; 턢; 턢; 턢; ) HANGUL SYLLABLE TYAELP
+D123;D123;1110 1164 11B6;D123;1110 1164 11B6; # (턣; 턣; 턣; 턣; 턣; ) HANGUL SYLLABLE TYAELH
+D124;D124;1110 1164 11B7;D124;1110 1164 11B7; # (턤; 턤; 턤; 턤; 턤; ) HANGUL SYLLABLE TYAEM
+D125;D125;1110 1164 11B8;D125;1110 1164 11B8; # (턥; 턥; 턥; 턥; 턥; ) HANGUL SYLLABLE TYAEB
+D126;D126;1110 1164 11B9;D126;1110 1164 11B9; # (턦; 턦; 턦; 턦; 턦; ) HANGUL SYLLABLE TYAEBS
+D127;D127;1110 1164 11BA;D127;1110 1164 11BA; # (턧; 턧; 턧; 턧; 턧; ) HANGUL SYLLABLE TYAES
+D128;D128;1110 1164 11BB;D128;1110 1164 11BB; # (턨; 턨; 턨; 턨; 턨; ) HANGUL SYLLABLE TYAESS
+D129;D129;1110 1164 11BC;D129;1110 1164 11BC; # (턩; 턩; 턩; 턩; 턩; ) HANGUL SYLLABLE TYAENG
+D12A;D12A;1110 1164 11BD;D12A;1110 1164 11BD; # (턪; 턪; 턪; 턪; 턪; ) HANGUL SYLLABLE TYAEJ
+D12B;D12B;1110 1164 11BE;D12B;1110 1164 11BE; # (턫; 턫; 턫; 턫; 턫; ) HANGUL SYLLABLE TYAEC
+D12C;D12C;1110 1164 11BF;D12C;1110 1164 11BF; # (턬; 턬; 턬; 턬; 턬; ) HANGUL SYLLABLE TYAEK
+D12D;D12D;1110 1164 11C0;D12D;1110 1164 11C0; # (턭; 턭; 턭; 턭; 턭; ) HANGUL SYLLABLE TYAET
+D12E;D12E;1110 1164 11C1;D12E;1110 1164 11C1; # (턮; 턮; 턮; 턮; 턮; ) HANGUL SYLLABLE TYAEP
+D12F;D12F;1110 1164 11C2;D12F;1110 1164 11C2; # (턯; 턯; 턯; 턯; 턯; ) HANGUL SYLLABLE TYAEH
+D130;D130;1110 1165;D130;1110 1165; # (터; 터; 터; 터; 터; ) HANGUL SYLLABLE TEO
+D131;D131;1110 1165 11A8;D131;1110 1165 11A8; # (턱; 턱; 턱; 턱; 턱; ) HANGUL SYLLABLE TEOG
+D132;D132;1110 1165 11A9;D132;1110 1165 11A9; # (턲; 턲; 턲; 턲; 턲; ) HANGUL SYLLABLE TEOGG
+D133;D133;1110 1165 11AA;D133;1110 1165 11AA; # (턳; 턳; 턳; 턳; 턳; ) HANGUL SYLLABLE TEOGS
+D134;D134;1110 1165 11AB;D134;1110 1165 11AB; # (턴; 턴; 턴; 턴; 턴; ) HANGUL SYLLABLE TEON
+D135;D135;1110 1165 11AC;D135;1110 1165 11AC; # (턵; 턵; 턵; 턵; 턵; ) HANGUL SYLLABLE TEONJ
+D136;D136;1110 1165 11AD;D136;1110 1165 11AD; # (턶; 턶; 턶; 턶; 턶; ) HANGUL SYLLABLE TEONH
+D137;D137;1110 1165 11AE;D137;1110 1165 11AE; # (턷; 턷; 턷; 턷; 턷; ) HANGUL SYLLABLE TEOD
+D138;D138;1110 1165 11AF;D138;1110 1165 11AF; # (털; 털; 털; 털; 털; ) HANGUL SYLLABLE TEOL
+D139;D139;1110 1165 11B0;D139;1110 1165 11B0; # (턹; 턹; 턹; 턹; 턹; ) HANGUL SYLLABLE TEOLG
+D13A;D13A;1110 1165 11B1;D13A;1110 1165 11B1; # (턺; 턺; 턺; 턺; 턺; ) HANGUL SYLLABLE TEOLM
+D13B;D13B;1110 1165 11B2;D13B;1110 1165 11B2; # (턻; 턻; 턻; 턻; 턻; ) HANGUL SYLLABLE TEOLB
+D13C;D13C;1110 1165 11B3;D13C;1110 1165 11B3; # (턼; 턼; 턼; 턼; 턼; ) HANGUL SYLLABLE TEOLS
+D13D;D13D;1110 1165 11B4;D13D;1110 1165 11B4; # (턽; 턽; 턽; 턽; 턽; ) HANGUL SYLLABLE TEOLT
+D13E;D13E;1110 1165 11B5;D13E;1110 1165 11B5; # (턾; 턾; 턾; 턾; 턾; ) HANGUL SYLLABLE TEOLP
+D13F;D13F;1110 1165 11B6;D13F;1110 1165 11B6; # (턿; 턿; 턿; 턿; 턿; ) HANGUL SYLLABLE TEOLH
+D140;D140;1110 1165 11B7;D140;1110 1165 11B7; # (텀; 텀; 텀; 텀; 텀; ) HANGUL SYLLABLE TEOM
+D141;D141;1110 1165 11B8;D141;1110 1165 11B8; # (텁; 텁; 텁; 텁; 텁; ) HANGUL SYLLABLE TEOB
+D142;D142;1110 1165 11B9;D142;1110 1165 11B9; # (텂; 텂; 텂; 텂; 텂; ) HANGUL SYLLABLE TEOBS
+D143;D143;1110 1165 11BA;D143;1110 1165 11BA; # (텃; 텃; 텃; 텃; 텃; ) HANGUL SYLLABLE TEOS
+D144;D144;1110 1165 11BB;D144;1110 1165 11BB; # (텄; 텄; 텄; 텄; 텄; ) HANGUL SYLLABLE TEOSS
+D145;D145;1110 1165 11BC;D145;1110 1165 11BC; # (텅; 텅; 텅; 텅; 텅; ) HANGUL SYLLABLE TEONG
+D146;D146;1110 1165 11BD;D146;1110 1165 11BD; # (텆; 텆; 텆; 텆; 텆; ) HANGUL SYLLABLE TEOJ
+D147;D147;1110 1165 11BE;D147;1110 1165 11BE; # (텇; 텇; 텇; 텇; 텇; ) HANGUL SYLLABLE TEOC
+D148;D148;1110 1165 11BF;D148;1110 1165 11BF; # (텈; 텈; 텈; 텈; 텈; ) HANGUL SYLLABLE TEOK
+D149;D149;1110 1165 11C0;D149;1110 1165 11C0; # (텉; 텉; 텉; 텉; 텉; ) HANGUL SYLLABLE TEOT
+D14A;D14A;1110 1165 11C1;D14A;1110 1165 11C1; # (텊; 텊; 텊; 텊; 텊; ) HANGUL SYLLABLE TEOP
+D14B;D14B;1110 1165 11C2;D14B;1110 1165 11C2; # (텋; 텋; 텋; 텋; 텋; ) HANGUL SYLLABLE TEOH
+D14C;D14C;1110 1166;D14C;1110 1166; # (테; 테; 테; 테; 테; ) HANGUL SYLLABLE TE
+D14D;D14D;1110 1166 11A8;D14D;1110 1166 11A8; # (텍; 텍; 텍; 텍; 텍; ) HANGUL SYLLABLE TEG
+D14E;D14E;1110 1166 11A9;D14E;1110 1166 11A9; # (텎; 텎; 텎; 텎; 텎; ) HANGUL SYLLABLE TEGG
+D14F;D14F;1110 1166 11AA;D14F;1110 1166 11AA; # (텏; 텏; 텏; 텏; 텏; ) HANGUL SYLLABLE TEGS
+D150;D150;1110 1166 11AB;D150;1110 1166 11AB; # (텐; 텐; 텐; 텐; 텐; ) HANGUL SYLLABLE TEN
+D151;D151;1110 1166 11AC;D151;1110 1166 11AC; # (텑; 텑; 텑; 텑; 텑; ) HANGUL SYLLABLE TENJ
+D152;D152;1110 1166 11AD;D152;1110 1166 11AD; # (텒; 텒; 텒; 텒; 텒; ) HANGUL SYLLABLE TENH
+D153;D153;1110 1166 11AE;D153;1110 1166 11AE; # (텓; 텓; 텓; 텓; 텓; ) HANGUL SYLLABLE TED
+D154;D154;1110 1166 11AF;D154;1110 1166 11AF; # (텔; 텔; 텔; 텔; 텔; ) HANGUL SYLLABLE TEL
+D155;D155;1110 1166 11B0;D155;1110 1166 11B0; # (텕; 텕; 텕; 텕; 텕; ) HANGUL SYLLABLE TELG
+D156;D156;1110 1166 11B1;D156;1110 1166 11B1; # (텖; 텖; 텖; 텖; 텖; ) HANGUL SYLLABLE TELM
+D157;D157;1110 1166 11B2;D157;1110 1166 11B2; # (텗; 텗; 텗; 텗; 텗; ) HANGUL SYLLABLE TELB
+D158;D158;1110 1166 11B3;D158;1110 1166 11B3; # (텘; 텘; 텘; 텘; 텘; ) HANGUL SYLLABLE TELS
+D159;D159;1110 1166 11B4;D159;1110 1166 11B4; # (텙; 텙; 텙; 텙; 텙; ) HANGUL SYLLABLE TELT
+D15A;D15A;1110 1166 11B5;D15A;1110 1166 11B5; # (텚; 텚; 텚; 텚; 텚; ) HANGUL SYLLABLE TELP
+D15B;D15B;1110 1166 11B6;D15B;1110 1166 11B6; # (텛; 텛; 텛; 텛; 텛; ) HANGUL SYLLABLE TELH
+D15C;D15C;1110 1166 11B7;D15C;1110 1166 11B7; # (템; 템; 템; 템; 템; ) HANGUL SYLLABLE TEM
+D15D;D15D;1110 1166 11B8;D15D;1110 1166 11B8; # (텝; 텝; 텝; 텝; 텝; ) HANGUL SYLLABLE TEB
+D15E;D15E;1110 1166 11B9;D15E;1110 1166 11B9; # (텞; 텞; 텞; 텞; 텞; ) HANGUL SYLLABLE TEBS
+D15F;D15F;1110 1166 11BA;D15F;1110 1166 11BA; # (텟; 텟; 텟; 텟; 텟; ) HANGUL SYLLABLE TES
+D160;D160;1110 1166 11BB;D160;1110 1166 11BB; # (텠; 텠; 텠; 텠; 텠; ) HANGUL SYLLABLE TESS
+D161;D161;1110 1166 11BC;D161;1110 1166 11BC; # (텡; 텡; 텡; 텡; 텡; ) HANGUL SYLLABLE TENG
+D162;D162;1110 1166 11BD;D162;1110 1166 11BD; # (텢; 텢; 텢; 텢; 텢; ) HANGUL SYLLABLE TEJ
+D163;D163;1110 1166 11BE;D163;1110 1166 11BE; # (텣; 텣; 텣; 텣; 텣; ) HANGUL SYLLABLE TEC
+D164;D164;1110 1166 11BF;D164;1110 1166 11BF; # (텤; 텤; 텤; 텤; 텤; ) HANGUL SYLLABLE TEK
+D165;D165;1110 1166 11C0;D165;1110 1166 11C0; # (텥; 텥; 텥; 텥; 텥; ) HANGUL SYLLABLE TET
+D166;D166;1110 1166 11C1;D166;1110 1166 11C1; # (텦; 텦; 텦; 텦; 텦; ) HANGUL SYLLABLE TEP
+D167;D167;1110 1166 11C2;D167;1110 1166 11C2; # (텧; 텧; 텧; 텧; 텧; ) HANGUL SYLLABLE TEH
+D168;D168;1110 1167;D168;1110 1167; # (텨; 텨; 텨; 텨; 텨; ) HANGUL SYLLABLE TYEO
+D169;D169;1110 1167 11A8;D169;1110 1167 11A8; # (텩; 텩; 텩; 텩; 텩; ) HANGUL SYLLABLE TYEOG
+D16A;D16A;1110 1167 11A9;D16A;1110 1167 11A9; # (텪; 텪; 텪; 텪; 텪; ) HANGUL SYLLABLE TYEOGG
+D16B;D16B;1110 1167 11AA;D16B;1110 1167 11AA; # (텫; 텫; 텫; 텫; 텫; ) HANGUL SYLLABLE TYEOGS
+D16C;D16C;1110 1167 11AB;D16C;1110 1167 11AB; # (텬; 텬; 텬; 텬; 텬; ) HANGUL SYLLABLE TYEON
+D16D;D16D;1110 1167 11AC;D16D;1110 1167 11AC; # (텭; 텭; 텭; 텭; 텭; ) HANGUL SYLLABLE TYEONJ
+D16E;D16E;1110 1167 11AD;D16E;1110 1167 11AD; # (텮; 텮; 텮; 텮; 텮; ) HANGUL SYLLABLE TYEONH
+D16F;D16F;1110 1167 11AE;D16F;1110 1167 11AE; # (텯; 텯; 텯; 텯; 텯; ) HANGUL SYLLABLE TYEOD
+D170;D170;1110 1167 11AF;D170;1110 1167 11AF; # (텰; 텰; 텰; 텰; 텰; ) HANGUL SYLLABLE TYEOL
+D171;D171;1110 1167 11B0;D171;1110 1167 11B0; # (텱; 텱; 텱; 텱; 텱; ) HANGUL SYLLABLE TYEOLG
+D172;D172;1110 1167 11B1;D172;1110 1167 11B1; # (텲; 텲; 텲; 텲; 텲; ) HANGUL SYLLABLE TYEOLM
+D173;D173;1110 1167 11B2;D173;1110 1167 11B2; # (텳; 텳; 텳; 텳; 텳; ) HANGUL SYLLABLE TYEOLB
+D174;D174;1110 1167 11B3;D174;1110 1167 11B3; # (텴; 텴; 텴; 텴; 텴; ) HANGUL SYLLABLE TYEOLS
+D175;D175;1110 1167 11B4;D175;1110 1167 11B4; # (텵; 텵; 텵; 텵; 텵; ) HANGUL SYLLABLE TYEOLT
+D176;D176;1110 1167 11B5;D176;1110 1167 11B5; # (텶; 텶; 텶; 텶; 텶; ) HANGUL SYLLABLE TYEOLP
+D177;D177;1110 1167 11B6;D177;1110 1167 11B6; # (텷; 텷; 텷; 텷; 텷; ) HANGUL SYLLABLE TYEOLH
+D178;D178;1110 1167 11B7;D178;1110 1167 11B7; # (텸; 텸; 텸; 텸; 텸; ) HANGUL SYLLABLE TYEOM
+D179;D179;1110 1167 11B8;D179;1110 1167 11B8; # (텹; 텹; 텹; 텹; 텹; ) HANGUL SYLLABLE TYEOB
+D17A;D17A;1110 1167 11B9;D17A;1110 1167 11B9; # (텺; 텺; 텺; 텺; 텺; ) HANGUL SYLLABLE TYEOBS
+D17B;D17B;1110 1167 11BA;D17B;1110 1167 11BA; # (텻; 텻; 텻; 텻; 텻; ) HANGUL SYLLABLE TYEOS
+D17C;D17C;1110 1167 11BB;D17C;1110 1167 11BB; # (텼; 텼; 텼; 텼; 텼; ) HANGUL SYLLABLE TYEOSS
+D17D;D17D;1110 1167 11BC;D17D;1110 1167 11BC; # (텽; 텽; 텽; 텽; 텽; ) HANGUL SYLLABLE TYEONG
+D17E;D17E;1110 1167 11BD;D17E;1110 1167 11BD; # (텾; 텾; 텾; 텾; 텾; ) HANGUL SYLLABLE TYEOJ
+D17F;D17F;1110 1167 11BE;D17F;1110 1167 11BE; # (텿; 텿; 텿; 텿; 텿; ) HANGUL SYLLABLE TYEOC
+D180;D180;1110 1167 11BF;D180;1110 1167 11BF; # (톀; 톀; 톀; 톀; 톀; ) HANGUL SYLLABLE TYEOK
+D181;D181;1110 1167 11C0;D181;1110 1167 11C0; # (톁; 톁; 톁; 톁; 톁; ) HANGUL SYLLABLE TYEOT
+D182;D182;1110 1167 11C1;D182;1110 1167 11C1; # (톂; 톂; 톂; 톂; 톂; ) HANGUL SYLLABLE TYEOP
+D183;D183;1110 1167 11C2;D183;1110 1167 11C2; # (톃; 톃; 톃; 톃; 톃; ) HANGUL SYLLABLE TYEOH
+D184;D184;1110 1168;D184;1110 1168; # (톄; 톄; 톄; 톄; 톄; ) HANGUL SYLLABLE TYE
+D185;D185;1110 1168 11A8;D185;1110 1168 11A8; # (톅; 톅; 톅; 톅; 톅; ) HANGUL SYLLABLE TYEG
+D186;D186;1110 1168 11A9;D186;1110 1168 11A9; # (톆; 톆; 톆; 톆; 톆; ) HANGUL SYLLABLE TYEGG
+D187;D187;1110 1168 11AA;D187;1110 1168 11AA; # (톇; 톇; 톇; 톇; 톇; ) HANGUL SYLLABLE TYEGS
+D188;D188;1110 1168 11AB;D188;1110 1168 11AB; # (톈; 톈; 톈; 톈; 톈; ) HANGUL SYLLABLE TYEN
+D189;D189;1110 1168 11AC;D189;1110 1168 11AC; # (톉; 톉; 톉; 톉; 톉; ) HANGUL SYLLABLE TYENJ
+D18A;D18A;1110 1168 11AD;D18A;1110 1168 11AD; # (톊; 톊; 톊; 톊; 톊; ) HANGUL SYLLABLE TYENH
+D18B;D18B;1110 1168 11AE;D18B;1110 1168 11AE; # (톋; 톋; 톋; 톋; 톋; ) HANGUL SYLLABLE TYED
+D18C;D18C;1110 1168 11AF;D18C;1110 1168 11AF; # (톌; 톌; 톌; 톌; 톌; ) HANGUL SYLLABLE TYEL
+D18D;D18D;1110 1168 11B0;D18D;1110 1168 11B0; # (톍; 톍; 톍; 톍; 톍; ) HANGUL SYLLABLE TYELG
+D18E;D18E;1110 1168 11B1;D18E;1110 1168 11B1; # (톎; 톎; 톎; 톎; 톎; ) HANGUL SYLLABLE TYELM
+D18F;D18F;1110 1168 11B2;D18F;1110 1168 11B2; # (톏; 톏; 톏; 톏; 톏; ) HANGUL SYLLABLE TYELB
+D190;D190;1110 1168 11B3;D190;1110 1168 11B3; # (톐; 톐; 톐; 톐; 톐; ) HANGUL SYLLABLE TYELS
+D191;D191;1110 1168 11B4;D191;1110 1168 11B4; # (톑; 톑; 톑; 톑; 톑; ) HANGUL SYLLABLE TYELT
+D192;D192;1110 1168 11B5;D192;1110 1168 11B5; # (톒; 톒; 톒; 톒; 톒; ) HANGUL SYLLABLE TYELP
+D193;D193;1110 1168 11B6;D193;1110 1168 11B6; # (톓; 톓; 톓; 톓; 톓; ) HANGUL SYLLABLE TYELH
+D194;D194;1110 1168 11B7;D194;1110 1168 11B7; # (톔; 톔; 톔; 톔; 톔; ) HANGUL SYLLABLE TYEM
+D195;D195;1110 1168 11B8;D195;1110 1168 11B8; # (톕; 톕; 톕; 톕; 톕; ) HANGUL SYLLABLE TYEB
+D196;D196;1110 1168 11B9;D196;1110 1168 11B9; # (톖; 톖; 톖; 톖; 톖; ) HANGUL SYLLABLE TYEBS
+D197;D197;1110 1168 11BA;D197;1110 1168 11BA; # (톗; 톗; 톗; 톗; 톗; ) HANGUL SYLLABLE TYES
+D198;D198;1110 1168 11BB;D198;1110 1168 11BB; # (톘; 톘; 톘; 톘; 톘; ) HANGUL SYLLABLE TYESS
+D199;D199;1110 1168 11BC;D199;1110 1168 11BC; # (톙; 톙; 톙; 톙; 톙; ) HANGUL SYLLABLE TYENG
+D19A;D19A;1110 1168 11BD;D19A;1110 1168 11BD; # (톚; 톚; 톚; 톚; 톚; ) HANGUL SYLLABLE TYEJ
+D19B;D19B;1110 1168 11BE;D19B;1110 1168 11BE; # (톛; 톛; 톛; 톛; 톛; ) HANGUL SYLLABLE TYEC
+D19C;D19C;1110 1168 11BF;D19C;1110 1168 11BF; # (톜; 톜; 톜; 톜; 톜; ) HANGUL SYLLABLE TYEK
+D19D;D19D;1110 1168 11C0;D19D;1110 1168 11C0; # (톝; 톝; 톝; 톝; 톝; ) HANGUL SYLLABLE TYET
+D19E;D19E;1110 1168 11C1;D19E;1110 1168 11C1; # (톞; 톞; 톞; 톞; 톞; ) HANGUL SYLLABLE TYEP
+D19F;D19F;1110 1168 11C2;D19F;1110 1168 11C2; # (톟; 톟; 톟; 톟; 톟; ) HANGUL SYLLABLE TYEH
+D1A0;D1A0;1110 1169;D1A0;1110 1169; # (토; 토; 토; 토; 토; ) HANGUL SYLLABLE TO
+D1A1;D1A1;1110 1169 11A8;D1A1;1110 1169 11A8; # (톡; 톡; 톡; 톡; 톡; ) HANGUL SYLLABLE TOG
+D1A2;D1A2;1110 1169 11A9;D1A2;1110 1169 11A9; # (톢; 톢; 톢; 톢; 톢; ) HANGUL SYLLABLE TOGG
+D1A3;D1A3;1110 1169 11AA;D1A3;1110 1169 11AA; # (톣; 톣; 톣; 톣; 톣; ) HANGUL SYLLABLE TOGS
+D1A4;D1A4;1110 1169 11AB;D1A4;1110 1169 11AB; # (톤; 톤; 톤; 톤; 톤; ) HANGUL SYLLABLE TON
+D1A5;D1A5;1110 1169 11AC;D1A5;1110 1169 11AC; # (톥; 톥; 톥; 톥; 톥; ) HANGUL SYLLABLE TONJ
+D1A6;D1A6;1110 1169 11AD;D1A6;1110 1169 11AD; # (톦; 톦; 톦; 톦; 톦; ) HANGUL SYLLABLE TONH
+D1A7;D1A7;1110 1169 11AE;D1A7;1110 1169 11AE; # (톧; 톧; 톧; 톧; 톧; ) HANGUL SYLLABLE TOD
+D1A8;D1A8;1110 1169 11AF;D1A8;1110 1169 11AF; # (톨; 톨; 톨; 톨; 톨; ) HANGUL SYLLABLE TOL
+D1A9;D1A9;1110 1169 11B0;D1A9;1110 1169 11B0; # (톩; 톩; 톩; 톩; 톩; ) HANGUL SYLLABLE TOLG
+D1AA;D1AA;1110 1169 11B1;D1AA;1110 1169 11B1; # (톪; 톪; 톪; 톪; 톪; ) HANGUL SYLLABLE TOLM
+D1AB;D1AB;1110 1169 11B2;D1AB;1110 1169 11B2; # (톫; 톫; 톫; 톫; 톫; ) HANGUL SYLLABLE TOLB
+D1AC;D1AC;1110 1169 11B3;D1AC;1110 1169 11B3; # (톬; 톬; 톬; 톬; 톬; ) HANGUL SYLLABLE TOLS
+D1AD;D1AD;1110 1169 11B4;D1AD;1110 1169 11B4; # (톭; 톭; 톭; 톭; 톭; ) HANGUL SYLLABLE TOLT
+D1AE;D1AE;1110 1169 11B5;D1AE;1110 1169 11B5; # (톮; 톮; 톮; 톮; 톮; ) HANGUL SYLLABLE TOLP
+D1AF;D1AF;1110 1169 11B6;D1AF;1110 1169 11B6; # (톯; 톯; 톯; 톯; 톯; ) HANGUL SYLLABLE TOLH
+D1B0;D1B0;1110 1169 11B7;D1B0;1110 1169 11B7; # (톰; 톰; 톰; 톰; 톰; ) HANGUL SYLLABLE TOM
+D1B1;D1B1;1110 1169 11B8;D1B1;1110 1169 11B8; # (톱; 톱; 톱; 톱; 톱; ) HANGUL SYLLABLE TOB
+D1B2;D1B2;1110 1169 11B9;D1B2;1110 1169 11B9; # (톲; 톲; 톲; 톲; 톲; ) HANGUL SYLLABLE TOBS
+D1B3;D1B3;1110 1169 11BA;D1B3;1110 1169 11BA; # (톳; 톳; 톳; 톳; 톳; ) HANGUL SYLLABLE TOS
+D1B4;D1B4;1110 1169 11BB;D1B4;1110 1169 11BB; # (톴; 톴; 톴; 톴; 톴; ) HANGUL SYLLABLE TOSS
+D1B5;D1B5;1110 1169 11BC;D1B5;1110 1169 11BC; # (통; 통; 통; 통; 통; ) HANGUL SYLLABLE TONG
+D1B6;D1B6;1110 1169 11BD;D1B6;1110 1169 11BD; # (톶; 톶; 톶; 톶; 톶; ) HANGUL SYLLABLE TOJ
+D1B7;D1B7;1110 1169 11BE;D1B7;1110 1169 11BE; # (톷; 톷; 톷; 톷; 톷; ) HANGUL SYLLABLE TOC
+D1B8;D1B8;1110 1169 11BF;D1B8;1110 1169 11BF; # (톸; 톸; 톸; 톸; 톸; ) HANGUL SYLLABLE TOK
+D1B9;D1B9;1110 1169 11C0;D1B9;1110 1169 11C0; # (톹; 톹; 톹; 톹; 톹; ) HANGUL SYLLABLE TOT
+D1BA;D1BA;1110 1169 11C1;D1BA;1110 1169 11C1; # (톺; 톺; 톺; 톺; 톺; ) HANGUL SYLLABLE TOP
+D1BB;D1BB;1110 1169 11C2;D1BB;1110 1169 11C2; # (톻; 톻; 톻; 톻; 톻; ) HANGUL SYLLABLE TOH
+D1BC;D1BC;1110 116A;D1BC;1110 116A; # (톼; 톼; 톼; 톼; 톼; ) HANGUL SYLLABLE TWA
+D1BD;D1BD;1110 116A 11A8;D1BD;1110 116A 11A8; # (톽; 톽; 톽; 톽; 톽; ) HANGUL SYLLABLE TWAG
+D1BE;D1BE;1110 116A 11A9;D1BE;1110 116A 11A9; # (톾; 톾; 톾; 톾; 톾; ) HANGUL SYLLABLE TWAGG
+D1BF;D1BF;1110 116A 11AA;D1BF;1110 116A 11AA; # (톿; 톿; 톿; 톿; 톿; ) HANGUL SYLLABLE TWAGS
+D1C0;D1C0;1110 116A 11AB;D1C0;1110 116A 11AB; # (퇀; 퇀; 퇀; 퇀; 퇀; ) HANGUL SYLLABLE TWAN
+D1C1;D1C1;1110 116A 11AC;D1C1;1110 116A 11AC; # (퇁; 퇁; 퇁; 퇁; 퇁; ) HANGUL SYLLABLE TWANJ
+D1C2;D1C2;1110 116A 11AD;D1C2;1110 116A 11AD; # (퇂; 퇂; 퇂; 퇂; 퇂; ) HANGUL SYLLABLE TWANH
+D1C3;D1C3;1110 116A 11AE;D1C3;1110 116A 11AE; # (퇃; 퇃; 퇃; 퇃; 퇃; ) HANGUL SYLLABLE TWAD
+D1C4;D1C4;1110 116A 11AF;D1C4;1110 116A 11AF; # (퇄; 퇄; 퇄; 퇄; 퇄; ) HANGUL SYLLABLE TWAL
+D1C5;D1C5;1110 116A 11B0;D1C5;1110 116A 11B0; # (퇅; 퇅; 퇅; 퇅; 퇅; ) HANGUL SYLLABLE TWALG
+D1C6;D1C6;1110 116A 11B1;D1C6;1110 116A 11B1; # (퇆; 퇆; 퇆; 퇆; 퇆; ) HANGUL SYLLABLE TWALM
+D1C7;D1C7;1110 116A 11B2;D1C7;1110 116A 11B2; # (퇇; 퇇; 퇇; 퇇; 퇇; ) HANGUL SYLLABLE TWALB
+D1C8;D1C8;1110 116A 11B3;D1C8;1110 116A 11B3; # (퇈; 퇈; 퇈; 퇈; 퇈; ) HANGUL SYLLABLE TWALS
+D1C9;D1C9;1110 116A 11B4;D1C9;1110 116A 11B4; # (퇉; 퇉; 퇉; 퇉; 퇉; ) HANGUL SYLLABLE TWALT
+D1CA;D1CA;1110 116A 11B5;D1CA;1110 116A 11B5; # (퇊; 퇊; 퇊; 퇊; 퇊; ) HANGUL SYLLABLE TWALP
+D1CB;D1CB;1110 116A 11B6;D1CB;1110 116A 11B6; # (퇋; 퇋; 퇋; 퇋; 퇋; ) HANGUL SYLLABLE TWALH
+D1CC;D1CC;1110 116A 11B7;D1CC;1110 116A 11B7; # (퇌; 퇌; 퇌; 퇌; 퇌; ) HANGUL SYLLABLE TWAM
+D1CD;D1CD;1110 116A 11B8;D1CD;1110 116A 11B8; # (퇍; 퇍; 퇍; 퇍; 퇍; ) HANGUL SYLLABLE TWAB
+D1CE;D1CE;1110 116A 11B9;D1CE;1110 116A 11B9; # (퇎; 퇎; 퇎; 퇎; 퇎; ) HANGUL SYLLABLE TWABS
+D1CF;D1CF;1110 116A 11BA;D1CF;1110 116A 11BA; # (퇏; 퇏; 퇏; 퇏; 퇏; ) HANGUL SYLLABLE TWAS
+D1D0;D1D0;1110 116A 11BB;D1D0;1110 116A 11BB; # (퇐; 퇐; 퇐; 퇐; 퇐; ) HANGUL SYLLABLE TWASS
+D1D1;D1D1;1110 116A 11BC;D1D1;1110 116A 11BC; # (퇑; 퇑; 퇑; 퇑; 퇑; ) HANGUL SYLLABLE TWANG
+D1D2;D1D2;1110 116A 11BD;D1D2;1110 116A 11BD; # (퇒; 퇒; 퇒; 퇒; 퇒; ) HANGUL SYLLABLE TWAJ
+D1D3;D1D3;1110 116A 11BE;D1D3;1110 116A 11BE; # (퇓; 퇓; 퇓; 퇓; 퇓; ) HANGUL SYLLABLE TWAC
+D1D4;D1D4;1110 116A 11BF;D1D4;1110 116A 11BF; # (퇔; 퇔; 퇔; 퇔; 퇔; ) HANGUL SYLLABLE TWAK
+D1D5;D1D5;1110 116A 11C0;D1D5;1110 116A 11C0; # (퇕; 퇕; 퇕; 퇕; 퇕; ) HANGUL SYLLABLE TWAT
+D1D6;D1D6;1110 116A 11C1;D1D6;1110 116A 11C1; # (퇖; 퇖; 퇖; 퇖; 퇖; ) HANGUL SYLLABLE TWAP
+D1D7;D1D7;1110 116A 11C2;D1D7;1110 116A 11C2; # (퇗; 퇗; 퇗; 퇗; 퇗; ) HANGUL SYLLABLE TWAH
+D1D8;D1D8;1110 116B;D1D8;1110 116B; # (퇘; 퇘; 퇘; 퇘; 퇘; ) HANGUL SYLLABLE TWAE
+D1D9;D1D9;1110 116B 11A8;D1D9;1110 116B 11A8; # (퇙; 퇙; 퇙; 퇙; 퇙; ) HANGUL SYLLABLE TWAEG
+D1DA;D1DA;1110 116B 11A9;D1DA;1110 116B 11A9; # (퇚; 퇚; 퇚; 퇚; 퇚; ) HANGUL SYLLABLE TWAEGG
+D1DB;D1DB;1110 116B 11AA;D1DB;1110 116B 11AA; # (퇛; 퇛; 퇛; 퇛; 퇛; ) HANGUL SYLLABLE TWAEGS
+D1DC;D1DC;1110 116B 11AB;D1DC;1110 116B 11AB; # (퇜; 퇜; 퇜; 퇜; 퇜; ) HANGUL SYLLABLE TWAEN
+D1DD;D1DD;1110 116B 11AC;D1DD;1110 116B 11AC; # (퇝; 퇝; 퇝; 퇝; 퇝; ) HANGUL SYLLABLE TWAENJ
+D1DE;D1DE;1110 116B 11AD;D1DE;1110 116B 11AD; # (퇞; 퇞; 퇞; 퇞; 퇞; ) HANGUL SYLLABLE TWAENH
+D1DF;D1DF;1110 116B 11AE;D1DF;1110 116B 11AE; # (퇟; 퇟; 퇟; 퇟; 퇟; ) HANGUL SYLLABLE TWAED
+D1E0;D1E0;1110 116B 11AF;D1E0;1110 116B 11AF; # (퇠; 퇠; 퇠; 퇠; 퇠; ) HANGUL SYLLABLE TWAEL
+D1E1;D1E1;1110 116B 11B0;D1E1;1110 116B 11B0; # (퇡; 퇡; 퇡; 퇡; 퇡; ) HANGUL SYLLABLE TWAELG
+D1E2;D1E2;1110 116B 11B1;D1E2;1110 116B 11B1; # (퇢; 퇢; 퇢; 퇢; 퇢; ) HANGUL SYLLABLE TWAELM
+D1E3;D1E3;1110 116B 11B2;D1E3;1110 116B 11B2; # (퇣; 퇣; 퇣; 퇣; 퇣; ) HANGUL SYLLABLE TWAELB
+D1E4;D1E4;1110 116B 11B3;D1E4;1110 116B 11B3; # (퇤; 퇤; 퇤; 퇤; 퇤; ) HANGUL SYLLABLE TWAELS
+D1E5;D1E5;1110 116B 11B4;D1E5;1110 116B 11B4; # (퇥; 퇥; 퇥; 퇥; 퇥; ) HANGUL SYLLABLE TWAELT
+D1E6;D1E6;1110 116B 11B5;D1E6;1110 116B 11B5; # (퇦; 퇦; 퇦; 퇦; 퇦; ) HANGUL SYLLABLE TWAELP
+D1E7;D1E7;1110 116B 11B6;D1E7;1110 116B 11B6; # (퇧; 퇧; 퇧; 퇧; 퇧; ) HANGUL SYLLABLE TWAELH
+D1E8;D1E8;1110 116B 11B7;D1E8;1110 116B 11B7; # (퇨; 퇨; 퇨; 퇨; 퇨; ) HANGUL SYLLABLE TWAEM
+D1E9;D1E9;1110 116B 11B8;D1E9;1110 116B 11B8; # (퇩; 퇩; 퇩; 퇩; 퇩; ) HANGUL SYLLABLE TWAEB
+D1EA;D1EA;1110 116B 11B9;D1EA;1110 116B 11B9; # (퇪; 퇪; 퇪; 퇪; 퇪; ) HANGUL SYLLABLE TWAEBS
+D1EB;D1EB;1110 116B 11BA;D1EB;1110 116B 11BA; # (퇫; 퇫; 퇫; 퇫; 퇫; ) HANGUL SYLLABLE TWAES
+D1EC;D1EC;1110 116B 11BB;D1EC;1110 116B 11BB; # (퇬; 퇬; 퇬; 퇬; 퇬; ) HANGUL SYLLABLE TWAESS
+D1ED;D1ED;1110 116B 11BC;D1ED;1110 116B 11BC; # (퇭; 퇭; 퇭; 퇭; 퇭; ) HANGUL SYLLABLE TWAENG
+D1EE;D1EE;1110 116B 11BD;D1EE;1110 116B 11BD; # (퇮; 퇮; 퇮; 퇮; 퇮; ) HANGUL SYLLABLE TWAEJ
+D1EF;D1EF;1110 116B 11BE;D1EF;1110 116B 11BE; # (퇯; 퇯; 퇯; 퇯; 퇯; ) HANGUL SYLLABLE TWAEC
+D1F0;D1F0;1110 116B 11BF;D1F0;1110 116B 11BF; # (퇰; 퇰; 퇰; 퇰; 퇰; ) HANGUL SYLLABLE TWAEK
+D1F1;D1F1;1110 116B 11C0;D1F1;1110 116B 11C0; # (퇱; 퇱; 퇱; 퇱; 퇱; ) HANGUL SYLLABLE TWAET
+D1F2;D1F2;1110 116B 11C1;D1F2;1110 116B 11C1; # (퇲; 퇲; 퇲; 퇲; 퇲; ) HANGUL SYLLABLE TWAEP
+D1F3;D1F3;1110 116B 11C2;D1F3;1110 116B 11C2; # (퇳; 퇳; 퇳; 퇳; 퇳; ) HANGUL SYLLABLE TWAEH
+D1F4;D1F4;1110 116C;D1F4;1110 116C; # (퇴; 퇴; 퇴; 퇴; 퇴; ) HANGUL SYLLABLE TOE
+D1F5;D1F5;1110 116C 11A8;D1F5;1110 116C 11A8; # (퇵; 퇵; 퇵; 퇵; 퇵; ) HANGUL SYLLABLE TOEG
+D1F6;D1F6;1110 116C 11A9;D1F6;1110 116C 11A9; # (퇶; 퇶; 퇶; 퇶; 퇶; ) HANGUL SYLLABLE TOEGG
+D1F7;D1F7;1110 116C 11AA;D1F7;1110 116C 11AA; # (퇷; 퇷; 퇷; 퇷; 퇷; ) HANGUL SYLLABLE TOEGS
+D1F8;D1F8;1110 116C 11AB;D1F8;1110 116C 11AB; # (퇸; 퇸; 퇸; 퇸; 퇸; ) HANGUL SYLLABLE TOEN
+D1F9;D1F9;1110 116C 11AC;D1F9;1110 116C 11AC; # (퇹; 퇹; 퇹; 퇹; 퇹; ) HANGUL SYLLABLE TOENJ
+D1FA;D1FA;1110 116C 11AD;D1FA;1110 116C 11AD; # (퇺; 퇺; 퇺; 퇺; 퇺; ) HANGUL SYLLABLE TOENH
+D1FB;D1FB;1110 116C 11AE;D1FB;1110 116C 11AE; # (퇻; 퇻; 퇻; 퇻; 퇻; ) HANGUL SYLLABLE TOED
+D1FC;D1FC;1110 116C 11AF;D1FC;1110 116C 11AF; # (퇼; 퇼; 퇼; 퇼; 퇼; ) HANGUL SYLLABLE TOEL
+D1FD;D1FD;1110 116C 11B0;D1FD;1110 116C 11B0; # (퇽; 퇽; 퇽; 퇽; 퇽; ) HANGUL SYLLABLE TOELG
+D1FE;D1FE;1110 116C 11B1;D1FE;1110 116C 11B1; # (퇾; 퇾; 퇾; 퇾; 퇾; ) HANGUL SYLLABLE TOELM
+D1FF;D1FF;1110 116C 11B2;D1FF;1110 116C 11B2; # (퇿; 퇿; 퇿; 퇿; 퇿; ) HANGUL SYLLABLE TOELB
+D200;D200;1110 116C 11B3;D200;1110 116C 11B3; # (툀; 툀; 툀; 툀; 툀; ) HANGUL SYLLABLE TOELS
+D201;D201;1110 116C 11B4;D201;1110 116C 11B4; # (툁; 툁; 툁; 툁; 툁; ) HANGUL SYLLABLE TOELT
+D202;D202;1110 116C 11B5;D202;1110 116C 11B5; # (툂; 툂; 툂; 툂; 툂; ) HANGUL SYLLABLE TOELP
+D203;D203;1110 116C 11B6;D203;1110 116C 11B6; # (툃; 툃; 툃; 툃; 툃; ) HANGUL SYLLABLE TOELH
+D204;D204;1110 116C 11B7;D204;1110 116C 11B7; # (툄; 툄; 툄; 툄; 툄; ) HANGUL SYLLABLE TOEM
+D205;D205;1110 116C 11B8;D205;1110 116C 11B8; # (툅; 툅; 툅; 툅; 툅; ) HANGUL SYLLABLE TOEB
+D206;D206;1110 116C 11B9;D206;1110 116C 11B9; # (툆; 툆; 툆; 툆; 툆; ) HANGUL SYLLABLE TOEBS
+D207;D207;1110 116C 11BA;D207;1110 116C 11BA; # (툇; 툇; 툇; 툇; 툇; ) HANGUL SYLLABLE TOES
+D208;D208;1110 116C 11BB;D208;1110 116C 11BB; # (툈; 툈; 툈; 툈; 툈; ) HANGUL SYLLABLE TOESS
+D209;D209;1110 116C 11BC;D209;1110 116C 11BC; # (툉; 툉; 툉; 툉; 툉; ) HANGUL SYLLABLE TOENG
+D20A;D20A;1110 116C 11BD;D20A;1110 116C 11BD; # (툊; 툊; 툊; 툊; 툊; ) HANGUL SYLLABLE TOEJ
+D20B;D20B;1110 116C 11BE;D20B;1110 116C 11BE; # (툋; 툋; 툋; 툋; 툋; ) HANGUL SYLLABLE TOEC
+D20C;D20C;1110 116C 11BF;D20C;1110 116C 11BF; # (툌; 툌; 툌; 툌; 툌; ) HANGUL SYLLABLE TOEK
+D20D;D20D;1110 116C 11C0;D20D;1110 116C 11C0; # (툍; 툍; 툍; 툍; 툍; ) HANGUL SYLLABLE TOET
+D20E;D20E;1110 116C 11C1;D20E;1110 116C 11C1; # (툎; 툎; 툎; 툎; 툎; ) HANGUL SYLLABLE TOEP
+D20F;D20F;1110 116C 11C2;D20F;1110 116C 11C2; # (툏; 툏; 툏; 툏; 툏; ) HANGUL SYLLABLE TOEH
+D210;D210;1110 116D;D210;1110 116D; # (툐; 툐; 툐; 툐; 툐; ) HANGUL SYLLABLE TYO
+D211;D211;1110 116D 11A8;D211;1110 116D 11A8; # (툑; 툑; 툑; 툑; 툑; ) HANGUL SYLLABLE TYOG
+D212;D212;1110 116D 11A9;D212;1110 116D 11A9; # (툒; 툒; 툒; 툒; 툒; ) HANGUL SYLLABLE TYOGG
+D213;D213;1110 116D 11AA;D213;1110 116D 11AA; # (툓; 툓; 툓; 툓; 툓; ) HANGUL SYLLABLE TYOGS
+D214;D214;1110 116D 11AB;D214;1110 116D 11AB; # (툔; 툔; 툔; 툔; 툔; ) HANGUL SYLLABLE TYON
+D215;D215;1110 116D 11AC;D215;1110 116D 11AC; # (툕; 툕; 툕; 툕; 툕; ) HANGUL SYLLABLE TYONJ
+D216;D216;1110 116D 11AD;D216;1110 116D 11AD; # (툖; 툖; 툖; 툖; 툖; ) HANGUL SYLLABLE TYONH
+D217;D217;1110 116D 11AE;D217;1110 116D 11AE; # (툗; 툗; 툗; 툗; 툗; ) HANGUL SYLLABLE TYOD
+D218;D218;1110 116D 11AF;D218;1110 116D 11AF; # (툘; 툘; 툘; 툘; 툘; ) HANGUL SYLLABLE TYOL
+D219;D219;1110 116D 11B0;D219;1110 116D 11B0; # (툙; 툙; 툙; 툙; 툙; ) HANGUL SYLLABLE TYOLG
+D21A;D21A;1110 116D 11B1;D21A;1110 116D 11B1; # (툚; 툚; 툚; 툚; 툚; ) HANGUL SYLLABLE TYOLM
+D21B;D21B;1110 116D 11B2;D21B;1110 116D 11B2; # (툛; 툛; 툛; 툛; 툛; ) HANGUL SYLLABLE TYOLB
+D21C;D21C;1110 116D 11B3;D21C;1110 116D 11B3; # (툜; 툜; 툜; 툜; 툜; ) HANGUL SYLLABLE TYOLS
+D21D;D21D;1110 116D 11B4;D21D;1110 116D 11B4; # (툝; 툝; 툝; 툝; 툝; ) HANGUL SYLLABLE TYOLT
+D21E;D21E;1110 116D 11B5;D21E;1110 116D 11B5; # (툞; 툞; 툞; 툞; 툞; ) HANGUL SYLLABLE TYOLP
+D21F;D21F;1110 116D 11B6;D21F;1110 116D 11B6; # (툟; 툟; 툟; 툟; 툟; ) HANGUL SYLLABLE TYOLH
+D220;D220;1110 116D 11B7;D220;1110 116D 11B7; # (툠; 툠; 툠; 툠; 툠; ) HANGUL SYLLABLE TYOM
+D221;D221;1110 116D 11B8;D221;1110 116D 11B8; # (툡; 툡; 툡; 툡; 툡; ) HANGUL SYLLABLE TYOB
+D222;D222;1110 116D 11B9;D222;1110 116D 11B9; # (툢; 툢; 툢; 툢; 툢; ) HANGUL SYLLABLE TYOBS
+D223;D223;1110 116D 11BA;D223;1110 116D 11BA; # (툣; 툣; 툣; 툣; 툣; ) HANGUL SYLLABLE TYOS
+D224;D224;1110 116D 11BB;D224;1110 116D 11BB; # (툤; 툤; 툤; 툤; 툤; ) HANGUL SYLLABLE TYOSS
+D225;D225;1110 116D 11BC;D225;1110 116D 11BC; # (툥; 툥; 툥; 툥; 툥; ) HANGUL SYLLABLE TYONG
+D226;D226;1110 116D 11BD;D226;1110 116D 11BD; # (툦; 툦; 툦; 툦; 툦; ) HANGUL SYLLABLE TYOJ
+D227;D227;1110 116D 11BE;D227;1110 116D 11BE; # (툧; 툧; 툧; 툧; 툧; ) HANGUL SYLLABLE TYOC
+D228;D228;1110 116D 11BF;D228;1110 116D 11BF; # (툨; 툨; 툨; 툨; 툨; ) HANGUL SYLLABLE TYOK
+D229;D229;1110 116D 11C0;D229;1110 116D 11C0; # (툩; 툩; 툩; 툩; 툩; ) HANGUL SYLLABLE TYOT
+D22A;D22A;1110 116D 11C1;D22A;1110 116D 11C1; # (툪; 툪; 툪; 툪; 툪; ) HANGUL SYLLABLE TYOP
+D22B;D22B;1110 116D 11C2;D22B;1110 116D 11C2; # (툫; 툫; 툫; 툫; 툫; ) HANGUL SYLLABLE TYOH
+D22C;D22C;1110 116E;D22C;1110 116E; # (투; 투; 투; 투; 투; ) HANGUL SYLLABLE TU
+D22D;D22D;1110 116E 11A8;D22D;1110 116E 11A8; # (툭; 툭; 툭; 툭; 툭; ) HANGUL SYLLABLE TUG
+D22E;D22E;1110 116E 11A9;D22E;1110 116E 11A9; # (툮; 툮; 툮; 툮; 툮; ) HANGUL SYLLABLE TUGG
+D22F;D22F;1110 116E 11AA;D22F;1110 116E 11AA; # (툯; 툯; 툯; 툯; 툯; ) HANGUL SYLLABLE TUGS
+D230;D230;1110 116E 11AB;D230;1110 116E 11AB; # (툰; 툰; 툰; 툰; 툰; ) HANGUL SYLLABLE TUN
+D231;D231;1110 116E 11AC;D231;1110 116E 11AC; # (툱; 툱; 툱; 툱; 툱; ) HANGUL SYLLABLE TUNJ
+D232;D232;1110 116E 11AD;D232;1110 116E 11AD; # (툲; 툲; 툲; 툲; 툲; ) HANGUL SYLLABLE TUNH
+D233;D233;1110 116E 11AE;D233;1110 116E 11AE; # (툳; 툳; 툳; 툳; 툳; ) HANGUL SYLLABLE TUD
+D234;D234;1110 116E 11AF;D234;1110 116E 11AF; # (툴; 툴; 툴; 툴; 툴; ) HANGUL SYLLABLE TUL
+D235;D235;1110 116E 11B0;D235;1110 116E 11B0; # (툵; 툵; 툵; 툵; 툵; ) HANGUL SYLLABLE TULG
+D236;D236;1110 116E 11B1;D236;1110 116E 11B1; # (툶; 툶; 툶; 툶; 툶; ) HANGUL SYLLABLE TULM
+D237;D237;1110 116E 11B2;D237;1110 116E 11B2; # (툷; 툷; 툷; 툷; 툷; ) HANGUL SYLLABLE TULB
+D238;D238;1110 116E 11B3;D238;1110 116E 11B3; # (툸; 툸; 툸; 툸; 툸; ) HANGUL SYLLABLE TULS
+D239;D239;1110 116E 11B4;D239;1110 116E 11B4; # (툹; 툹; 툹; 툹; 툹; ) HANGUL SYLLABLE TULT
+D23A;D23A;1110 116E 11B5;D23A;1110 116E 11B5; # (툺; 툺; 툺; 툺; 툺; ) HANGUL SYLLABLE TULP
+D23B;D23B;1110 116E 11B6;D23B;1110 116E 11B6; # (툻; 툻; 툻; 툻; 툻; ) HANGUL SYLLABLE TULH
+D23C;D23C;1110 116E 11B7;D23C;1110 116E 11B7; # (툼; 툼; 툼; 툼; 툼; ) HANGUL SYLLABLE TUM
+D23D;D23D;1110 116E 11B8;D23D;1110 116E 11B8; # (툽; 툽; 툽; 툽; 툽; ) HANGUL SYLLABLE TUB
+D23E;D23E;1110 116E 11B9;D23E;1110 116E 11B9; # (툾; 툾; 툾; 툾; 툾; ) HANGUL SYLLABLE TUBS
+D23F;D23F;1110 116E 11BA;D23F;1110 116E 11BA; # (툿; 툿; 툿; 툿; 툿; ) HANGUL SYLLABLE TUS
+D240;D240;1110 116E 11BB;D240;1110 116E 11BB; # (퉀; 퉀; 퉀; 퉀; 퉀; ) HANGUL SYLLABLE TUSS
+D241;D241;1110 116E 11BC;D241;1110 116E 11BC; # (퉁; 퉁; 퉁; 퉁; 퉁; ) HANGUL SYLLABLE TUNG
+D242;D242;1110 116E 11BD;D242;1110 116E 11BD; # (퉂; 퉂; 퉂; 퉂; 퉂; ) HANGUL SYLLABLE TUJ
+D243;D243;1110 116E 11BE;D243;1110 116E 11BE; # (퉃; 퉃; 퉃; 퉃; 퉃; ) HANGUL SYLLABLE TUC
+D244;D244;1110 116E 11BF;D244;1110 116E 11BF; # (퉄; 퉄; 퉄; 퉄; 퉄; ) HANGUL SYLLABLE TUK
+D245;D245;1110 116E 11C0;D245;1110 116E 11C0; # (퉅; 퉅; 퉅; 퉅; 퉅; ) HANGUL SYLLABLE TUT
+D246;D246;1110 116E 11C1;D246;1110 116E 11C1; # (퉆; 퉆; 퉆; 퉆; 퉆; ) HANGUL SYLLABLE TUP
+D247;D247;1110 116E 11C2;D247;1110 116E 11C2; # (퉇; 퉇; 퉇; 퉇; 퉇; ) HANGUL SYLLABLE TUH
+D248;D248;1110 116F;D248;1110 116F; # (퉈; 퉈; 퉈; 퉈; 퉈; ) HANGUL SYLLABLE TWEO
+D249;D249;1110 116F 11A8;D249;1110 116F 11A8; # (퉉; 퉉; 퉉; 퉉; 퉉; ) HANGUL SYLLABLE TWEOG
+D24A;D24A;1110 116F 11A9;D24A;1110 116F 11A9; # (퉊; 퉊; 퉊; 퉊; 퉊; ) HANGUL SYLLABLE TWEOGG
+D24B;D24B;1110 116F 11AA;D24B;1110 116F 11AA; # (퉋; 퉋; 퉋; 퉋; 퉋; ) HANGUL SYLLABLE TWEOGS
+D24C;D24C;1110 116F 11AB;D24C;1110 116F 11AB; # (퉌; 퉌; 퉌; 퉌; 퉌; ) HANGUL SYLLABLE TWEON
+D24D;D24D;1110 116F 11AC;D24D;1110 116F 11AC; # (퉍; 퉍; 퉍; 퉍; 퉍; ) HANGUL SYLLABLE TWEONJ
+D24E;D24E;1110 116F 11AD;D24E;1110 116F 11AD; # (퉎; 퉎; 퉎; 퉎; 퉎; ) HANGUL SYLLABLE TWEONH
+D24F;D24F;1110 116F 11AE;D24F;1110 116F 11AE; # (퉏; 퉏; 퉏; 퉏; 퉏; ) HANGUL SYLLABLE TWEOD
+D250;D250;1110 116F 11AF;D250;1110 116F 11AF; # (퉐; 퉐; 퉐; 퉐; 퉐; ) HANGUL SYLLABLE TWEOL
+D251;D251;1110 116F 11B0;D251;1110 116F 11B0; # (퉑; 퉑; 퉑; 퉑; 퉑; ) HANGUL SYLLABLE TWEOLG
+D252;D252;1110 116F 11B1;D252;1110 116F 11B1; # (퉒; 퉒; 퉒; 퉒; 퉒; ) HANGUL SYLLABLE TWEOLM
+D253;D253;1110 116F 11B2;D253;1110 116F 11B2; # (퉓; 퉓; 퉓; 퉓; 퉓; ) HANGUL SYLLABLE TWEOLB
+D254;D254;1110 116F 11B3;D254;1110 116F 11B3; # (퉔; 퉔; 퉔; 퉔; 퉔; ) HANGUL SYLLABLE TWEOLS
+D255;D255;1110 116F 11B4;D255;1110 116F 11B4; # (퉕; 퉕; 퉕; 퉕; 퉕; ) HANGUL SYLLABLE TWEOLT
+D256;D256;1110 116F 11B5;D256;1110 116F 11B5; # (퉖; 퉖; 퉖; 퉖; 퉖; ) HANGUL SYLLABLE TWEOLP
+D257;D257;1110 116F 11B6;D257;1110 116F 11B6; # (퉗; 퉗; 퉗; 퉗; 퉗; ) HANGUL SYLLABLE TWEOLH
+D258;D258;1110 116F 11B7;D258;1110 116F 11B7; # (퉘; 퉘; 퉘; 퉘; 퉘; ) HANGUL SYLLABLE TWEOM
+D259;D259;1110 116F 11B8;D259;1110 116F 11B8; # (퉙; 퉙; 퉙; 퉙; 퉙; ) HANGUL SYLLABLE TWEOB
+D25A;D25A;1110 116F 11B9;D25A;1110 116F 11B9; # (퉚; 퉚; 퉚; 퉚; 퉚; ) HANGUL SYLLABLE TWEOBS
+D25B;D25B;1110 116F 11BA;D25B;1110 116F 11BA; # (퉛; 퉛; 퉛; 퉛; 퉛; ) HANGUL SYLLABLE TWEOS
+D25C;D25C;1110 116F 11BB;D25C;1110 116F 11BB; # (퉜; 퉜; 퉜; 퉜; 퉜; ) HANGUL SYLLABLE TWEOSS
+D25D;D25D;1110 116F 11BC;D25D;1110 116F 11BC; # (퉝; 퉝; 퉝; 퉝; 퉝; ) HANGUL SYLLABLE TWEONG
+D25E;D25E;1110 116F 11BD;D25E;1110 116F 11BD; # (퉞; 퉞; 퉞; 퉞; 퉞; ) HANGUL SYLLABLE TWEOJ
+D25F;D25F;1110 116F 11BE;D25F;1110 116F 11BE; # (퉟; 퉟; 퉟; 퉟; 퉟; ) HANGUL SYLLABLE TWEOC
+D260;D260;1110 116F 11BF;D260;1110 116F 11BF; # (퉠; 퉠; 퉠; 퉠; 퉠; ) HANGUL SYLLABLE TWEOK
+D261;D261;1110 116F 11C0;D261;1110 116F 11C0; # (퉡; 퉡; 퉡; 퉡; 퉡; ) HANGUL SYLLABLE TWEOT
+D262;D262;1110 116F 11C1;D262;1110 116F 11C1; # (퉢; 퉢; 퉢; 퉢; 퉢; ) HANGUL SYLLABLE TWEOP
+D263;D263;1110 116F 11C2;D263;1110 116F 11C2; # (퉣; 퉣; 퉣; 퉣; 퉣; ) HANGUL SYLLABLE TWEOH
+D264;D264;1110 1170;D264;1110 1170; # (퉤; 퉤; 퉤; 퉤; 퉤; ) HANGUL SYLLABLE TWE
+D265;D265;1110 1170 11A8;D265;1110 1170 11A8; # (퉥; 퉥; 퉥; 퉥; 퉥; ) HANGUL SYLLABLE TWEG
+D266;D266;1110 1170 11A9;D266;1110 1170 11A9; # (퉦; 퉦; 퉦; 퉦; 퉦; ) HANGUL SYLLABLE TWEGG
+D267;D267;1110 1170 11AA;D267;1110 1170 11AA; # (퉧; 퉧; 퉧; 퉧; 퉧; ) HANGUL SYLLABLE TWEGS
+D268;D268;1110 1170 11AB;D268;1110 1170 11AB; # (퉨; 퉨; 퉨; 퉨; 퉨; ) HANGUL SYLLABLE TWEN
+D269;D269;1110 1170 11AC;D269;1110 1170 11AC; # (퉩; 퉩; 퉩; 퉩; 퉩; ) HANGUL SYLLABLE TWENJ
+D26A;D26A;1110 1170 11AD;D26A;1110 1170 11AD; # (퉪; 퉪; 퉪; 퉪; 퉪; ) HANGUL SYLLABLE TWENH
+D26B;D26B;1110 1170 11AE;D26B;1110 1170 11AE; # (퉫; 퉫; 퉫; 퉫; 퉫; ) HANGUL SYLLABLE TWED
+D26C;D26C;1110 1170 11AF;D26C;1110 1170 11AF; # (퉬; 퉬; 퉬; 퉬; 퉬; ) HANGUL SYLLABLE TWEL
+D26D;D26D;1110 1170 11B0;D26D;1110 1170 11B0; # (퉭; 퉭; 퉭; 퉭; 퉭; ) HANGUL SYLLABLE TWELG
+D26E;D26E;1110 1170 11B1;D26E;1110 1170 11B1; # (퉮; 퉮; 퉮; 퉮; 퉮; ) HANGUL SYLLABLE TWELM
+D26F;D26F;1110 1170 11B2;D26F;1110 1170 11B2; # (퉯; 퉯; 퉯; 퉯; 퉯; ) HANGUL SYLLABLE TWELB
+D270;D270;1110 1170 11B3;D270;1110 1170 11B3; # (퉰; 퉰; 퉰; 퉰; 퉰; ) HANGUL SYLLABLE TWELS
+D271;D271;1110 1170 11B4;D271;1110 1170 11B4; # (퉱; 퉱; 퉱; 퉱; 퉱; ) HANGUL SYLLABLE TWELT
+D272;D272;1110 1170 11B5;D272;1110 1170 11B5; # (퉲; 퉲; 퉲; 퉲; 퉲; ) HANGUL SYLLABLE TWELP
+D273;D273;1110 1170 11B6;D273;1110 1170 11B6; # (퉳; 퉳; 퉳; 퉳; 퉳; ) HANGUL SYLLABLE TWELH
+D274;D274;1110 1170 11B7;D274;1110 1170 11B7; # (퉴; 퉴; 퉴; 퉴; 퉴; ) HANGUL SYLLABLE TWEM
+D275;D275;1110 1170 11B8;D275;1110 1170 11B8; # (퉵; 퉵; 퉵; 퉵; 퉵; ) HANGUL SYLLABLE TWEB
+D276;D276;1110 1170 11B9;D276;1110 1170 11B9; # (퉶; 퉶; 퉶; 퉶; 퉶; ) HANGUL SYLLABLE TWEBS
+D277;D277;1110 1170 11BA;D277;1110 1170 11BA; # (퉷; 퉷; 퉷; 퉷; 퉷; ) HANGUL SYLLABLE TWES
+D278;D278;1110 1170 11BB;D278;1110 1170 11BB; # (퉸; 퉸; 퉸; 퉸; 퉸; ) HANGUL SYLLABLE TWESS
+D279;D279;1110 1170 11BC;D279;1110 1170 11BC; # (퉹; 퉹; 퉹; 퉹; 퉹; ) HANGUL SYLLABLE TWENG
+D27A;D27A;1110 1170 11BD;D27A;1110 1170 11BD; # (퉺; 퉺; 퉺; 퉺; 퉺; ) HANGUL SYLLABLE TWEJ
+D27B;D27B;1110 1170 11BE;D27B;1110 1170 11BE; # (퉻; 퉻; 퉻; 퉻; 퉻; ) HANGUL SYLLABLE TWEC
+D27C;D27C;1110 1170 11BF;D27C;1110 1170 11BF; # (퉼; 퉼; 퉼; 퉼; 퉼; ) HANGUL SYLLABLE TWEK
+D27D;D27D;1110 1170 11C0;D27D;1110 1170 11C0; # (퉽; 퉽; 퉽; 퉽; 퉽; ) HANGUL SYLLABLE TWET
+D27E;D27E;1110 1170 11C1;D27E;1110 1170 11C1; # (퉾; 퉾; 퉾; 퉾; 퉾; ) HANGUL SYLLABLE TWEP
+D27F;D27F;1110 1170 11C2;D27F;1110 1170 11C2; # (퉿; 퉿; 퉿; 퉿; 퉿; ) HANGUL SYLLABLE TWEH
+D280;D280;1110 1171;D280;1110 1171; # (튀; 튀; 튀; 튀; 튀; ) HANGUL SYLLABLE TWI
+D281;D281;1110 1171 11A8;D281;1110 1171 11A8; # (튁; 튁; 튁; 튁; 튁; ) HANGUL SYLLABLE TWIG
+D282;D282;1110 1171 11A9;D282;1110 1171 11A9; # (튂; 튂; 튂; 튂; 튂; ) HANGUL SYLLABLE TWIGG
+D283;D283;1110 1171 11AA;D283;1110 1171 11AA; # (튃; 튃; 튃; 튃; 튃; ) HANGUL SYLLABLE TWIGS
+D284;D284;1110 1171 11AB;D284;1110 1171 11AB; # (튄; 튄; 튄; 튄; 튄; ) HANGUL SYLLABLE TWIN
+D285;D285;1110 1171 11AC;D285;1110 1171 11AC; # (튅; 튅; 튅; 튅; 튅; ) HANGUL SYLLABLE TWINJ
+D286;D286;1110 1171 11AD;D286;1110 1171 11AD; # (튆; 튆; 튆; 튆; 튆; ) HANGUL SYLLABLE TWINH
+D287;D287;1110 1171 11AE;D287;1110 1171 11AE; # (튇; 튇; 튇; 튇; 튇; ) HANGUL SYLLABLE TWID
+D288;D288;1110 1171 11AF;D288;1110 1171 11AF; # (튈; 튈; 튈; 튈; 튈; ) HANGUL SYLLABLE TWIL
+D289;D289;1110 1171 11B0;D289;1110 1171 11B0; # (튉; 튉; 튉; 튉; 튉; ) HANGUL SYLLABLE TWILG
+D28A;D28A;1110 1171 11B1;D28A;1110 1171 11B1; # (튊; 튊; 튊; 튊; 튊; ) HANGUL SYLLABLE TWILM
+D28B;D28B;1110 1171 11B2;D28B;1110 1171 11B2; # (튋; 튋; 튋; 튋; 튋; ) HANGUL SYLLABLE TWILB
+D28C;D28C;1110 1171 11B3;D28C;1110 1171 11B3; # (튌; 튌; 튌; 튌; 튌; ) HANGUL SYLLABLE TWILS
+D28D;D28D;1110 1171 11B4;D28D;1110 1171 11B4; # (튍; 튍; 튍; 튍; 튍; ) HANGUL SYLLABLE TWILT
+D28E;D28E;1110 1171 11B5;D28E;1110 1171 11B5; # (튎; 튎; 튎; 튎; 튎; ) HANGUL SYLLABLE TWILP
+D28F;D28F;1110 1171 11B6;D28F;1110 1171 11B6; # (튏; 튏; 튏; 튏; 튏; ) HANGUL SYLLABLE TWILH
+D290;D290;1110 1171 11B7;D290;1110 1171 11B7; # (튐; 튐; 튐; 튐; 튐; ) HANGUL SYLLABLE TWIM
+D291;D291;1110 1171 11B8;D291;1110 1171 11B8; # (튑; 튑; 튑; 튑; 튑; ) HANGUL SYLLABLE TWIB
+D292;D292;1110 1171 11B9;D292;1110 1171 11B9; # (튒; 튒; 튒; 튒; 튒; ) HANGUL SYLLABLE TWIBS
+D293;D293;1110 1171 11BA;D293;1110 1171 11BA; # (튓; 튓; 튓; 튓; 튓; ) HANGUL SYLLABLE TWIS
+D294;D294;1110 1171 11BB;D294;1110 1171 11BB; # (튔; 튔; 튔; 튔; 튔; ) HANGUL SYLLABLE TWISS
+D295;D295;1110 1171 11BC;D295;1110 1171 11BC; # (튕; 튕; 튕; 튕; 튕; ) HANGUL SYLLABLE TWING
+D296;D296;1110 1171 11BD;D296;1110 1171 11BD; # (튖; 튖; 튖; 튖; 튖; ) HANGUL SYLLABLE TWIJ
+D297;D297;1110 1171 11BE;D297;1110 1171 11BE; # (튗; 튗; 튗; 튗; 튗; ) HANGUL SYLLABLE TWIC
+D298;D298;1110 1171 11BF;D298;1110 1171 11BF; # (튘; 튘; 튘; 튘; 튘; ) HANGUL SYLLABLE TWIK
+D299;D299;1110 1171 11C0;D299;1110 1171 11C0; # (튙; 튙; 튙; 튙; 튙; ) HANGUL SYLLABLE TWIT
+D29A;D29A;1110 1171 11C1;D29A;1110 1171 11C1; # (튚; 튚; 튚; 튚; 튚; ) HANGUL SYLLABLE TWIP
+D29B;D29B;1110 1171 11C2;D29B;1110 1171 11C2; # (튛; 튛; 튛; 튛; 튛; ) HANGUL SYLLABLE TWIH
+D29C;D29C;1110 1172;D29C;1110 1172; # (튜; 튜; 튜; 튜; 튜; ) HANGUL SYLLABLE TYU
+D29D;D29D;1110 1172 11A8;D29D;1110 1172 11A8; # (튝; 튝; 튝; 튝; 튝; ) HANGUL SYLLABLE TYUG
+D29E;D29E;1110 1172 11A9;D29E;1110 1172 11A9; # (튞; 튞; 튞; 튞; 튞; ) HANGUL SYLLABLE TYUGG
+D29F;D29F;1110 1172 11AA;D29F;1110 1172 11AA; # (튟; 튟; 튟; 튟; 튟; ) HANGUL SYLLABLE TYUGS
+D2A0;D2A0;1110 1172 11AB;D2A0;1110 1172 11AB; # (튠; 튠; 튠; 튠; 튠; ) HANGUL SYLLABLE TYUN
+D2A1;D2A1;1110 1172 11AC;D2A1;1110 1172 11AC; # (튡; 튡; 튡; 튡; 튡; ) HANGUL SYLLABLE TYUNJ
+D2A2;D2A2;1110 1172 11AD;D2A2;1110 1172 11AD; # (튢; 튢; 튢; 튢; 튢; ) HANGUL SYLLABLE TYUNH
+D2A3;D2A3;1110 1172 11AE;D2A3;1110 1172 11AE; # (튣; 튣; 튣; 튣; 튣; ) HANGUL SYLLABLE TYUD
+D2A4;D2A4;1110 1172 11AF;D2A4;1110 1172 11AF; # (튤; 튤; 튤; 튤; 튤; ) HANGUL SYLLABLE TYUL
+D2A5;D2A5;1110 1172 11B0;D2A5;1110 1172 11B0; # (튥; 튥; 튥; 튥; 튥; ) HANGUL SYLLABLE TYULG
+D2A6;D2A6;1110 1172 11B1;D2A6;1110 1172 11B1; # (튦; 튦; 튦; 튦; 튦; ) HANGUL SYLLABLE TYULM
+D2A7;D2A7;1110 1172 11B2;D2A7;1110 1172 11B2; # (튧; 튧; 튧; 튧; 튧; ) HANGUL SYLLABLE TYULB
+D2A8;D2A8;1110 1172 11B3;D2A8;1110 1172 11B3; # (튨; 튨; 튨; 튨; 튨; ) HANGUL SYLLABLE TYULS
+D2A9;D2A9;1110 1172 11B4;D2A9;1110 1172 11B4; # (튩; 튩; 튩; 튩; 튩; ) HANGUL SYLLABLE TYULT
+D2AA;D2AA;1110 1172 11B5;D2AA;1110 1172 11B5; # (튪; 튪; 튪; 튪; 튪; ) HANGUL SYLLABLE TYULP
+D2AB;D2AB;1110 1172 11B6;D2AB;1110 1172 11B6; # (튫; 튫; 튫; 튫; 튫; ) HANGUL SYLLABLE TYULH
+D2AC;D2AC;1110 1172 11B7;D2AC;1110 1172 11B7; # (튬; 튬; 튬; 튬; 튬; ) HANGUL SYLLABLE TYUM
+D2AD;D2AD;1110 1172 11B8;D2AD;1110 1172 11B8; # (튭; 튭; 튭; 튭; 튭; ) HANGUL SYLLABLE TYUB
+D2AE;D2AE;1110 1172 11B9;D2AE;1110 1172 11B9; # (튮; 튮; 튮; 튮; 튮; ) HANGUL SYLLABLE TYUBS
+D2AF;D2AF;1110 1172 11BA;D2AF;1110 1172 11BA; # (튯; 튯; 튯; 튯; 튯; ) HANGUL SYLLABLE TYUS
+D2B0;D2B0;1110 1172 11BB;D2B0;1110 1172 11BB; # (튰; 튰; 튰; 튰; 튰; ) HANGUL SYLLABLE TYUSS
+D2B1;D2B1;1110 1172 11BC;D2B1;1110 1172 11BC; # (튱; 튱; 튱; 튱; 튱; ) HANGUL SYLLABLE TYUNG
+D2B2;D2B2;1110 1172 11BD;D2B2;1110 1172 11BD; # (튲; 튲; 튲; 튲; 튲; ) HANGUL SYLLABLE TYUJ
+D2B3;D2B3;1110 1172 11BE;D2B3;1110 1172 11BE; # (튳; 튳; 튳; 튳; 튳; ) HANGUL SYLLABLE TYUC
+D2B4;D2B4;1110 1172 11BF;D2B4;1110 1172 11BF; # (튴; 튴; 튴; 튴; 튴; ) HANGUL SYLLABLE TYUK
+D2B5;D2B5;1110 1172 11C0;D2B5;1110 1172 11C0; # (튵; 튵; 튵; 튵; 튵; ) HANGUL SYLLABLE TYUT
+D2B6;D2B6;1110 1172 11C1;D2B6;1110 1172 11C1; # (튶; 튶; 튶; 튶; 튶; ) HANGUL SYLLABLE TYUP
+D2B7;D2B7;1110 1172 11C2;D2B7;1110 1172 11C2; # (튷; 튷; 튷; 튷; 튷; ) HANGUL SYLLABLE TYUH
+D2B8;D2B8;1110 1173;D2B8;1110 1173; # (트; 트; 트; 트; 트; ) HANGUL SYLLABLE TEU
+D2B9;D2B9;1110 1173 11A8;D2B9;1110 1173 11A8; # (특; 특; 특; 특; 특; ) HANGUL SYLLABLE TEUG
+D2BA;D2BA;1110 1173 11A9;D2BA;1110 1173 11A9; # (튺; 튺; 튺; 튺; 튺; ) HANGUL SYLLABLE TEUGG
+D2BB;D2BB;1110 1173 11AA;D2BB;1110 1173 11AA; # (튻; 튻; 튻; 튻; 튻; ) HANGUL SYLLABLE TEUGS
+D2BC;D2BC;1110 1173 11AB;D2BC;1110 1173 11AB; # (튼; 튼; 튼; 튼; 튼; ) HANGUL SYLLABLE TEUN
+D2BD;D2BD;1110 1173 11AC;D2BD;1110 1173 11AC; # (튽; 튽; 튽; 튽; 튽; ) HANGUL SYLLABLE TEUNJ
+D2BE;D2BE;1110 1173 11AD;D2BE;1110 1173 11AD; # (튾; 튾; 튾; 튾; 튾; ) HANGUL SYLLABLE TEUNH
+D2BF;D2BF;1110 1173 11AE;D2BF;1110 1173 11AE; # (튿; 튿; 튿; 튿; 튿; ) HANGUL SYLLABLE TEUD
+D2C0;D2C0;1110 1173 11AF;D2C0;1110 1173 11AF; # (틀; 틀; 틀; 틀; 틀; ) HANGUL SYLLABLE TEUL
+D2C1;D2C1;1110 1173 11B0;D2C1;1110 1173 11B0; # (틁; 틁; 틁; 틁; 틁; ) HANGUL SYLLABLE TEULG
+D2C2;D2C2;1110 1173 11B1;D2C2;1110 1173 11B1; # (틂; 틂; 틂; 틂; 틂; ) HANGUL SYLLABLE TEULM
+D2C3;D2C3;1110 1173 11B2;D2C3;1110 1173 11B2; # (틃; 틃; 틃; 틃; 틃; ) HANGUL SYLLABLE TEULB
+D2C4;D2C4;1110 1173 11B3;D2C4;1110 1173 11B3; # (틄; 틄; 틄; 틄; 틄; ) HANGUL SYLLABLE TEULS
+D2C5;D2C5;1110 1173 11B4;D2C5;1110 1173 11B4; # (틅; 틅; 틅; 틅; 틅; ) HANGUL SYLLABLE TEULT
+D2C6;D2C6;1110 1173 11B5;D2C6;1110 1173 11B5; # (틆; 틆; 틆; 틆; 틆; ) HANGUL SYLLABLE TEULP
+D2C7;D2C7;1110 1173 11B6;D2C7;1110 1173 11B6; # (틇; 틇; 틇; 틇; 틇; ) HANGUL SYLLABLE TEULH
+D2C8;D2C8;1110 1173 11B7;D2C8;1110 1173 11B7; # (틈; 틈; 틈; 틈; 틈; ) HANGUL SYLLABLE TEUM
+D2C9;D2C9;1110 1173 11B8;D2C9;1110 1173 11B8; # (틉; 틉; 틉; 틉; 틉; ) HANGUL SYLLABLE TEUB
+D2CA;D2CA;1110 1173 11B9;D2CA;1110 1173 11B9; # (틊; 틊; 틊; 틊; 틊; ) HANGUL SYLLABLE TEUBS
+D2CB;D2CB;1110 1173 11BA;D2CB;1110 1173 11BA; # (틋; 틋; 틋; 틋; 틋; ) HANGUL SYLLABLE TEUS
+D2CC;D2CC;1110 1173 11BB;D2CC;1110 1173 11BB; # (틌; 틌; 틌; 틌; 틌; ) HANGUL SYLLABLE TEUSS
+D2CD;D2CD;1110 1173 11BC;D2CD;1110 1173 11BC; # (틍; 틍; 틍; 틍; 틍; ) HANGUL SYLLABLE TEUNG
+D2CE;D2CE;1110 1173 11BD;D2CE;1110 1173 11BD; # (틎; 틎; 틎; 틎; 틎; ) HANGUL SYLLABLE TEUJ
+D2CF;D2CF;1110 1173 11BE;D2CF;1110 1173 11BE; # (틏; 틏; 틏; 틏; 틏; ) HANGUL SYLLABLE TEUC
+D2D0;D2D0;1110 1173 11BF;D2D0;1110 1173 11BF; # (틐; 틐; 틐; 틐; 틐; ) HANGUL SYLLABLE TEUK
+D2D1;D2D1;1110 1173 11C0;D2D1;1110 1173 11C0; # (틑; 틑; 틑; 틑; 틑; ) HANGUL SYLLABLE TEUT
+D2D2;D2D2;1110 1173 11C1;D2D2;1110 1173 11C1; # (틒; 틒; 틒; 틒; 틒; ) HANGUL SYLLABLE TEUP
+D2D3;D2D3;1110 1173 11C2;D2D3;1110 1173 11C2; # (틓; 틓; 틓; 틓; 틓; ) HANGUL SYLLABLE TEUH
+D2D4;D2D4;1110 1174;D2D4;1110 1174; # (틔; 틔; 틔; 틔; 틔; ) HANGUL SYLLABLE TYI
+D2D5;D2D5;1110 1174 11A8;D2D5;1110 1174 11A8; # (틕; 틕; 틕; 틕; 틕; ) HANGUL SYLLABLE TYIG
+D2D6;D2D6;1110 1174 11A9;D2D6;1110 1174 11A9; # (틖; 틖; 틖; 틖; 틖; ) HANGUL SYLLABLE TYIGG
+D2D7;D2D7;1110 1174 11AA;D2D7;1110 1174 11AA; # (틗; 틗; 틗; 틗; 틗; ) HANGUL SYLLABLE TYIGS
+D2D8;D2D8;1110 1174 11AB;D2D8;1110 1174 11AB; # (틘; 틘; 틘; 틘; 틘; ) HANGUL SYLLABLE TYIN
+D2D9;D2D9;1110 1174 11AC;D2D9;1110 1174 11AC; # (틙; 틙; 틙; 틙; 틙; ) HANGUL SYLLABLE TYINJ
+D2DA;D2DA;1110 1174 11AD;D2DA;1110 1174 11AD; # (틚; 틚; 틚; 틚; 틚; ) HANGUL SYLLABLE TYINH
+D2DB;D2DB;1110 1174 11AE;D2DB;1110 1174 11AE; # (틛; 틛; 틛; 틛; 틛; ) HANGUL SYLLABLE TYID
+D2DC;D2DC;1110 1174 11AF;D2DC;1110 1174 11AF; # (틜; 틜; 틜; 틜; 틜; ) HANGUL SYLLABLE TYIL
+D2DD;D2DD;1110 1174 11B0;D2DD;1110 1174 11B0; # (틝; 틝; 틝; 틝; 틝; ) HANGUL SYLLABLE TYILG
+D2DE;D2DE;1110 1174 11B1;D2DE;1110 1174 11B1; # (틞; 틞; 틞; 틞; 틞; ) HANGUL SYLLABLE TYILM
+D2DF;D2DF;1110 1174 11B2;D2DF;1110 1174 11B2; # (틟; 틟; 틟; 틟; 틟; ) HANGUL SYLLABLE TYILB
+D2E0;D2E0;1110 1174 11B3;D2E0;1110 1174 11B3; # (틠; 틠; 틠; 틠; 틠; ) HANGUL SYLLABLE TYILS
+D2E1;D2E1;1110 1174 11B4;D2E1;1110 1174 11B4; # (틡; 틡; 틡; 틡; 틡; ) HANGUL SYLLABLE TYILT
+D2E2;D2E2;1110 1174 11B5;D2E2;1110 1174 11B5; # (틢; 틢; 틢; 틢; 틢; ) HANGUL SYLLABLE TYILP
+D2E3;D2E3;1110 1174 11B6;D2E3;1110 1174 11B6; # (틣; 틣; 틣; 틣; 틣; ) HANGUL SYLLABLE TYILH
+D2E4;D2E4;1110 1174 11B7;D2E4;1110 1174 11B7; # (틤; 틤; 틤; 틤; 틤; ) HANGUL SYLLABLE TYIM
+D2E5;D2E5;1110 1174 11B8;D2E5;1110 1174 11B8; # (틥; 틥; 틥; 틥; 틥; ) HANGUL SYLLABLE TYIB
+D2E6;D2E6;1110 1174 11B9;D2E6;1110 1174 11B9; # (틦; 틦; 틦; 틦; 틦; ) HANGUL SYLLABLE TYIBS
+D2E7;D2E7;1110 1174 11BA;D2E7;1110 1174 11BA; # (틧; 틧; 틧; 틧; 틧; ) HANGUL SYLLABLE TYIS
+D2E8;D2E8;1110 1174 11BB;D2E8;1110 1174 11BB; # (틨; 틨; 틨; 틨; 틨; ) HANGUL SYLLABLE TYISS
+D2E9;D2E9;1110 1174 11BC;D2E9;1110 1174 11BC; # (틩; 틩; 틩; 틩; 틩; ) HANGUL SYLLABLE TYING
+D2EA;D2EA;1110 1174 11BD;D2EA;1110 1174 11BD; # (틪; 틪; 틪; 틪; 틪; ) HANGUL SYLLABLE TYIJ
+D2EB;D2EB;1110 1174 11BE;D2EB;1110 1174 11BE; # (틫; 틫; 틫; 틫; 틫; ) HANGUL SYLLABLE TYIC
+D2EC;D2EC;1110 1174 11BF;D2EC;1110 1174 11BF; # (틬; 틬; 틬; 틬; 틬; ) HANGUL SYLLABLE TYIK
+D2ED;D2ED;1110 1174 11C0;D2ED;1110 1174 11C0; # (틭; 틭; 틭; 틭; 틭; ) HANGUL SYLLABLE TYIT
+D2EE;D2EE;1110 1174 11C1;D2EE;1110 1174 11C1; # (틮; 틮; 틮; 틮; 틮; ) HANGUL SYLLABLE TYIP
+D2EF;D2EF;1110 1174 11C2;D2EF;1110 1174 11C2; # (틯; 틯; 틯; 틯; 틯; ) HANGUL SYLLABLE TYIH
+D2F0;D2F0;1110 1175;D2F0;1110 1175; # (티; 티; 티; 티; 티; ) HANGUL SYLLABLE TI
+D2F1;D2F1;1110 1175 11A8;D2F1;1110 1175 11A8; # (틱; 틱; 틱; 틱; 틱; ) HANGUL SYLLABLE TIG
+D2F2;D2F2;1110 1175 11A9;D2F2;1110 1175 11A9; # (틲; 틲; 틲; 틲; 틲; ) HANGUL SYLLABLE TIGG
+D2F3;D2F3;1110 1175 11AA;D2F3;1110 1175 11AA; # (틳; 틳; 틳; 틳; 틳; ) HANGUL SYLLABLE TIGS
+D2F4;D2F4;1110 1175 11AB;D2F4;1110 1175 11AB; # (틴; 틴; 틴; 틴; 틴; ) HANGUL SYLLABLE TIN
+D2F5;D2F5;1110 1175 11AC;D2F5;1110 1175 11AC; # (틵; 틵; 틵; 틵; 틵; ) HANGUL SYLLABLE TINJ
+D2F6;D2F6;1110 1175 11AD;D2F6;1110 1175 11AD; # (틶; 틶; 틶; 틶; 틶; ) HANGUL SYLLABLE TINH
+D2F7;D2F7;1110 1175 11AE;D2F7;1110 1175 11AE; # (틷; 틷; 틷; 틷; 틷; ) HANGUL SYLLABLE TID
+D2F8;D2F8;1110 1175 11AF;D2F8;1110 1175 11AF; # (틸; 틸; 틸; 틸; 틸; ) HANGUL SYLLABLE TIL
+D2F9;D2F9;1110 1175 11B0;D2F9;1110 1175 11B0; # (틹; 틹; 틹; 틹; 틹; ) HANGUL SYLLABLE TILG
+D2FA;D2FA;1110 1175 11B1;D2FA;1110 1175 11B1; # (틺; 틺; 틺; 틺; 틺; ) HANGUL SYLLABLE TILM
+D2FB;D2FB;1110 1175 11B2;D2FB;1110 1175 11B2; # (틻; 틻; 틻; 틻; 틻; ) HANGUL SYLLABLE TILB
+D2FC;D2FC;1110 1175 11B3;D2FC;1110 1175 11B3; # (틼; 틼; 틼; 틼; 틼; ) HANGUL SYLLABLE TILS
+D2FD;D2FD;1110 1175 11B4;D2FD;1110 1175 11B4; # (틽; 틽; 틽; 틽; 틽; ) HANGUL SYLLABLE TILT
+D2FE;D2FE;1110 1175 11B5;D2FE;1110 1175 11B5; # (틾; 틾; 틾; 틾; 틾; ) HANGUL SYLLABLE TILP
+D2FF;D2FF;1110 1175 11B6;D2FF;1110 1175 11B6; # (틿; 틿; 틿; 틿; 틿; ) HANGUL SYLLABLE TILH
+D300;D300;1110 1175 11B7;D300;1110 1175 11B7; # (팀; 팀; 팀; 팀; 팀; ) HANGUL SYLLABLE TIM
+D301;D301;1110 1175 11B8;D301;1110 1175 11B8; # (팁; 팁; 팁; 팁; 팁; ) HANGUL SYLLABLE TIB
+D302;D302;1110 1175 11B9;D302;1110 1175 11B9; # (팂; 팂; 팂; 팂; 팂; ) HANGUL SYLLABLE TIBS
+D303;D303;1110 1175 11BA;D303;1110 1175 11BA; # (팃; 팃; 팃; 팃; 팃; ) HANGUL SYLLABLE TIS
+D304;D304;1110 1175 11BB;D304;1110 1175 11BB; # (팄; 팄; 팄; 팄; 팄; ) HANGUL SYLLABLE TISS
+D305;D305;1110 1175 11BC;D305;1110 1175 11BC; # (팅; 팅; 팅; 팅; 팅; ) HANGUL SYLLABLE TING
+D306;D306;1110 1175 11BD;D306;1110 1175 11BD; # (팆; 팆; 팆; 팆; 팆; ) HANGUL SYLLABLE TIJ
+D307;D307;1110 1175 11BE;D307;1110 1175 11BE; # (팇; 팇; 팇; 팇; 팇; ) HANGUL SYLLABLE TIC
+D308;D308;1110 1175 11BF;D308;1110 1175 11BF; # (팈; 팈; 팈; 팈; 팈; ) HANGUL SYLLABLE TIK
+D309;D309;1110 1175 11C0;D309;1110 1175 11C0; # (팉; 팉; 팉; 팉; 팉; ) HANGUL SYLLABLE TIT
+D30A;D30A;1110 1175 11C1;D30A;1110 1175 11C1; # (팊; 팊; 팊; 팊; 팊; ) HANGUL SYLLABLE TIP
+D30B;D30B;1110 1175 11C2;D30B;1110 1175 11C2; # (팋; 팋; 팋; 팋; 팋; ) HANGUL SYLLABLE TIH
+D30C;D30C;1111 1161;D30C;1111 1161; # (파; 파; 파; 파; 파; ) HANGUL SYLLABLE PA
+D30D;D30D;1111 1161 11A8;D30D;1111 1161 11A8; # (팍; 팍; 팍; 팍; 팍; ) HANGUL SYLLABLE PAG
+D30E;D30E;1111 1161 11A9;D30E;1111 1161 11A9; # (팎; 팎; 팎; 팎; 팎; ) HANGUL SYLLABLE PAGG
+D30F;D30F;1111 1161 11AA;D30F;1111 1161 11AA; # (팏; 팏; 팏; 팏; 팏; ) HANGUL SYLLABLE PAGS
+D310;D310;1111 1161 11AB;D310;1111 1161 11AB; # (판; 판; 판; 판; 판; ) HANGUL SYLLABLE PAN
+D311;D311;1111 1161 11AC;D311;1111 1161 11AC; # (팑; 팑; 팑; 팑; 팑; ) HANGUL SYLLABLE PANJ
+D312;D312;1111 1161 11AD;D312;1111 1161 11AD; # (팒; 팒; 팒; 팒; 팒; ) HANGUL SYLLABLE PANH
+D313;D313;1111 1161 11AE;D313;1111 1161 11AE; # (팓; 팓; 팓; 팓; 팓; ) HANGUL SYLLABLE PAD
+D314;D314;1111 1161 11AF;D314;1111 1161 11AF; # (팔; 팔; 팔; 팔; 팔; ) HANGUL SYLLABLE PAL
+D315;D315;1111 1161 11B0;D315;1111 1161 11B0; # (팕; 팕; 팕; 팕; 팕; ) HANGUL SYLLABLE PALG
+D316;D316;1111 1161 11B1;D316;1111 1161 11B1; # (팖; 팖; 팖; 팖; 팖; ) HANGUL SYLLABLE PALM
+D317;D317;1111 1161 11B2;D317;1111 1161 11B2; # (팗; 팗; 팗; 팗; 팗; ) HANGUL SYLLABLE PALB
+D318;D318;1111 1161 11B3;D318;1111 1161 11B3; # (팘; 팘; 팘; 팘; 팘; ) HANGUL SYLLABLE PALS
+D319;D319;1111 1161 11B4;D319;1111 1161 11B4; # (팙; 팙; 팙; 팙; 팙; ) HANGUL SYLLABLE PALT
+D31A;D31A;1111 1161 11B5;D31A;1111 1161 11B5; # (팚; 팚; 팚; 팚; 팚; ) HANGUL SYLLABLE PALP
+D31B;D31B;1111 1161 11B6;D31B;1111 1161 11B6; # (팛; 팛; 팛; 팛; 팛; ) HANGUL SYLLABLE PALH
+D31C;D31C;1111 1161 11B7;D31C;1111 1161 11B7; # (팜; 팜; 팜; 팜; 팜; ) HANGUL SYLLABLE PAM
+D31D;D31D;1111 1161 11B8;D31D;1111 1161 11B8; # (팝; 팝; 팝; 팝; 팝; ) HANGUL SYLLABLE PAB
+D31E;D31E;1111 1161 11B9;D31E;1111 1161 11B9; # (팞; 팞; 팞; 팞; 팞; ) HANGUL SYLLABLE PABS
+D31F;D31F;1111 1161 11BA;D31F;1111 1161 11BA; # (팟; 팟; 팟; 팟; 팟; ) HANGUL SYLLABLE PAS
+D320;D320;1111 1161 11BB;D320;1111 1161 11BB; # (팠; 팠; 팠; 팠; 팠; ) HANGUL SYLLABLE PASS
+D321;D321;1111 1161 11BC;D321;1111 1161 11BC; # (팡; 팡; 팡; 팡; 팡; ) HANGUL SYLLABLE PANG
+D322;D322;1111 1161 11BD;D322;1111 1161 11BD; # (팢; 팢; 팢; 팢; 팢; ) HANGUL SYLLABLE PAJ
+D323;D323;1111 1161 11BE;D323;1111 1161 11BE; # (팣; 팣; 팣; 팣; 팣; ) HANGUL SYLLABLE PAC
+D324;D324;1111 1161 11BF;D324;1111 1161 11BF; # (팤; 팤; 팤; 팤; 팤; ) HANGUL SYLLABLE PAK
+D325;D325;1111 1161 11C0;D325;1111 1161 11C0; # (팥; 팥; 팥; 팥; 팥; ) HANGUL SYLLABLE PAT
+D326;D326;1111 1161 11C1;D326;1111 1161 11C1; # (팦; 팦; 팦; 팦; 팦; ) HANGUL SYLLABLE PAP
+D327;D327;1111 1161 11C2;D327;1111 1161 11C2; # (팧; 팧; 팧; 팧; 팧; ) HANGUL SYLLABLE PAH
+D328;D328;1111 1162;D328;1111 1162; # (패; 패; 패; 패; 패; ) HANGUL SYLLABLE PAE
+D329;D329;1111 1162 11A8;D329;1111 1162 11A8; # (팩; 팩; 팩; 팩; 팩; ) HANGUL SYLLABLE PAEG
+D32A;D32A;1111 1162 11A9;D32A;1111 1162 11A9; # (팪; 팪; 팪; 팪; 팪; ) HANGUL SYLLABLE PAEGG
+D32B;D32B;1111 1162 11AA;D32B;1111 1162 11AA; # (팫; 팫; 팫; 팫; 팫; ) HANGUL SYLLABLE PAEGS
+D32C;D32C;1111 1162 11AB;D32C;1111 1162 11AB; # (팬; 팬; 팬; 팬; 팬; ) HANGUL SYLLABLE PAEN
+D32D;D32D;1111 1162 11AC;D32D;1111 1162 11AC; # (팭; 팭; 팭; 팭; 팭; ) HANGUL SYLLABLE PAENJ
+D32E;D32E;1111 1162 11AD;D32E;1111 1162 11AD; # (팮; 팮; 팮; 팮; 팮; ) HANGUL SYLLABLE PAENH
+D32F;D32F;1111 1162 11AE;D32F;1111 1162 11AE; # (팯; 팯; 팯; 팯; 팯; ) HANGUL SYLLABLE PAED
+D330;D330;1111 1162 11AF;D330;1111 1162 11AF; # (팰; 팰; 팰; 팰; 팰; ) HANGUL SYLLABLE PAEL
+D331;D331;1111 1162 11B0;D331;1111 1162 11B0; # (팱; 팱; 팱; 팱; 팱; ) HANGUL SYLLABLE PAELG
+D332;D332;1111 1162 11B1;D332;1111 1162 11B1; # (팲; 팲; 팲; 팲; 팲; ) HANGUL SYLLABLE PAELM
+D333;D333;1111 1162 11B2;D333;1111 1162 11B2; # (팳; 팳; 팳; 팳; 팳; ) HANGUL SYLLABLE PAELB
+D334;D334;1111 1162 11B3;D334;1111 1162 11B3; # (팴; 팴; 팴; 팴; 팴; ) HANGUL SYLLABLE PAELS
+D335;D335;1111 1162 11B4;D335;1111 1162 11B4; # (팵; 팵; 팵; 팵; 팵; ) HANGUL SYLLABLE PAELT
+D336;D336;1111 1162 11B5;D336;1111 1162 11B5; # (팶; 팶; 팶; 팶; 팶; ) HANGUL SYLLABLE PAELP
+D337;D337;1111 1162 11B6;D337;1111 1162 11B6; # (팷; 팷; 팷; 팷; 팷; ) HANGUL SYLLABLE PAELH
+D338;D338;1111 1162 11B7;D338;1111 1162 11B7; # (팸; 팸; 팸; 팸; 팸; ) HANGUL SYLLABLE PAEM
+D339;D339;1111 1162 11B8;D339;1111 1162 11B8; # (팹; 팹; 팹; 팹; 팹; ) HANGUL SYLLABLE PAEB
+D33A;D33A;1111 1162 11B9;D33A;1111 1162 11B9; # (팺; 팺; 팺; 팺; 팺; ) HANGUL SYLLABLE PAEBS
+D33B;D33B;1111 1162 11BA;D33B;1111 1162 11BA; # (팻; 팻; 팻; 팻; 팻; ) HANGUL SYLLABLE PAES
+D33C;D33C;1111 1162 11BB;D33C;1111 1162 11BB; # (팼; 팼; 팼; 팼; 팼; ) HANGUL SYLLABLE PAESS
+D33D;D33D;1111 1162 11BC;D33D;1111 1162 11BC; # (팽; 팽; 팽; 팽; 팽; ) HANGUL SYLLABLE PAENG
+D33E;D33E;1111 1162 11BD;D33E;1111 1162 11BD; # (팾; 팾; 팾; 팾; 팾; ) HANGUL SYLLABLE PAEJ
+D33F;D33F;1111 1162 11BE;D33F;1111 1162 11BE; # (팿; 팿; 팿; 팿; 팿; ) HANGUL SYLLABLE PAEC
+D340;D340;1111 1162 11BF;D340;1111 1162 11BF; # (퍀; 퍀; 퍀; 퍀; 퍀; ) HANGUL SYLLABLE PAEK
+D341;D341;1111 1162 11C0;D341;1111 1162 11C0; # (퍁; 퍁; 퍁; 퍁; 퍁; ) HANGUL SYLLABLE PAET
+D342;D342;1111 1162 11C1;D342;1111 1162 11C1; # (퍂; 퍂; 퍂; 퍂; 퍂; ) HANGUL SYLLABLE PAEP
+D343;D343;1111 1162 11C2;D343;1111 1162 11C2; # (퍃; 퍃; 퍃; 퍃; 퍃; ) HANGUL SYLLABLE PAEH
+D344;D344;1111 1163;D344;1111 1163; # (퍄; 퍄; 퍄; 퍄; 퍄; ) HANGUL SYLLABLE PYA
+D345;D345;1111 1163 11A8;D345;1111 1163 11A8; # (퍅; 퍅; 퍅; 퍅; 퍅; ) HANGUL SYLLABLE PYAG
+D346;D346;1111 1163 11A9;D346;1111 1163 11A9; # (퍆; 퍆; 퍆; 퍆; 퍆; ) HANGUL SYLLABLE PYAGG
+D347;D347;1111 1163 11AA;D347;1111 1163 11AA; # (퍇; 퍇; 퍇; 퍇; 퍇; ) HANGUL SYLLABLE PYAGS
+D348;D348;1111 1163 11AB;D348;1111 1163 11AB; # (퍈; 퍈; 퍈; 퍈; 퍈; ) HANGUL SYLLABLE PYAN
+D349;D349;1111 1163 11AC;D349;1111 1163 11AC; # (퍉; 퍉; 퍉; 퍉; 퍉; ) HANGUL SYLLABLE PYANJ
+D34A;D34A;1111 1163 11AD;D34A;1111 1163 11AD; # (퍊; 퍊; 퍊; 퍊; 퍊; ) HANGUL SYLLABLE PYANH
+D34B;D34B;1111 1163 11AE;D34B;1111 1163 11AE; # (퍋; 퍋; 퍋; 퍋; 퍋; ) HANGUL SYLLABLE PYAD
+D34C;D34C;1111 1163 11AF;D34C;1111 1163 11AF; # (퍌; 퍌; 퍌; 퍌; 퍌; ) HANGUL SYLLABLE PYAL
+D34D;D34D;1111 1163 11B0;D34D;1111 1163 11B0; # (퍍; 퍍; 퍍; 퍍; 퍍; ) HANGUL SYLLABLE PYALG
+D34E;D34E;1111 1163 11B1;D34E;1111 1163 11B1; # (퍎; 퍎; 퍎; 퍎; 퍎; ) HANGUL SYLLABLE PYALM
+D34F;D34F;1111 1163 11B2;D34F;1111 1163 11B2; # (퍏; 퍏; 퍏; 퍏; 퍏; ) HANGUL SYLLABLE PYALB
+D350;D350;1111 1163 11B3;D350;1111 1163 11B3; # (퍐; 퍐; 퍐; 퍐; 퍐; ) HANGUL SYLLABLE PYALS
+D351;D351;1111 1163 11B4;D351;1111 1163 11B4; # (퍑; 퍑; 퍑; 퍑; 퍑; ) HANGUL SYLLABLE PYALT
+D352;D352;1111 1163 11B5;D352;1111 1163 11B5; # (퍒; 퍒; 퍒; 퍒; 퍒; ) HANGUL SYLLABLE PYALP
+D353;D353;1111 1163 11B6;D353;1111 1163 11B6; # (퍓; 퍓; 퍓; 퍓; 퍓; ) HANGUL SYLLABLE PYALH
+D354;D354;1111 1163 11B7;D354;1111 1163 11B7; # (퍔; 퍔; 퍔; 퍔; 퍔; ) HANGUL SYLLABLE PYAM
+D355;D355;1111 1163 11B8;D355;1111 1163 11B8; # (퍕; 퍕; 퍕; 퍕; 퍕; ) HANGUL SYLLABLE PYAB
+D356;D356;1111 1163 11B9;D356;1111 1163 11B9; # (퍖; 퍖; 퍖; 퍖; 퍖; ) HANGUL SYLLABLE PYABS
+D357;D357;1111 1163 11BA;D357;1111 1163 11BA; # (퍗; 퍗; 퍗; 퍗; 퍗; ) HANGUL SYLLABLE PYAS
+D358;D358;1111 1163 11BB;D358;1111 1163 11BB; # (퍘; 퍘; 퍘; 퍘; 퍘; ) HANGUL SYLLABLE PYASS
+D359;D359;1111 1163 11BC;D359;1111 1163 11BC; # (퍙; 퍙; 퍙; 퍙; 퍙; ) HANGUL SYLLABLE PYANG
+D35A;D35A;1111 1163 11BD;D35A;1111 1163 11BD; # (퍚; 퍚; 퍚; 퍚; 퍚; ) HANGUL SYLLABLE PYAJ
+D35B;D35B;1111 1163 11BE;D35B;1111 1163 11BE; # (퍛; 퍛; 퍛; 퍛; 퍛; ) HANGUL SYLLABLE PYAC
+D35C;D35C;1111 1163 11BF;D35C;1111 1163 11BF; # (퍜; 퍜; 퍜; 퍜; 퍜; ) HANGUL SYLLABLE PYAK
+D35D;D35D;1111 1163 11C0;D35D;1111 1163 11C0; # (퍝; 퍝; 퍝; 퍝; 퍝; ) HANGUL SYLLABLE PYAT
+D35E;D35E;1111 1163 11C1;D35E;1111 1163 11C1; # (퍞; 퍞; 퍞; 퍞; 퍞; ) HANGUL SYLLABLE PYAP
+D35F;D35F;1111 1163 11C2;D35F;1111 1163 11C2; # (퍟; 퍟; 퍟; 퍟; 퍟; ) HANGUL SYLLABLE PYAH
+D360;D360;1111 1164;D360;1111 1164; # (퍠; 퍠; 퍠; 퍠; 퍠; ) HANGUL SYLLABLE PYAE
+D361;D361;1111 1164 11A8;D361;1111 1164 11A8; # (퍡; 퍡; 퍡; 퍡; 퍡; ) HANGUL SYLLABLE PYAEG
+D362;D362;1111 1164 11A9;D362;1111 1164 11A9; # (퍢; 퍢; 퍢; 퍢; 퍢; ) HANGUL SYLLABLE PYAEGG
+D363;D363;1111 1164 11AA;D363;1111 1164 11AA; # (퍣; 퍣; 퍣; 퍣; 퍣; ) HANGUL SYLLABLE PYAEGS
+D364;D364;1111 1164 11AB;D364;1111 1164 11AB; # (퍤; 퍤; 퍤; 퍤; 퍤; ) HANGUL SYLLABLE PYAEN
+D365;D365;1111 1164 11AC;D365;1111 1164 11AC; # (퍥; 퍥; 퍥; 퍥; 퍥; ) HANGUL SYLLABLE PYAENJ
+D366;D366;1111 1164 11AD;D366;1111 1164 11AD; # (퍦; 퍦; 퍦; 퍦; 퍦; ) HANGUL SYLLABLE PYAENH
+D367;D367;1111 1164 11AE;D367;1111 1164 11AE; # (퍧; 퍧; 퍧; 퍧; 퍧; ) HANGUL SYLLABLE PYAED
+D368;D368;1111 1164 11AF;D368;1111 1164 11AF; # (퍨; 퍨; 퍨; 퍨; 퍨; ) HANGUL SYLLABLE PYAEL
+D369;D369;1111 1164 11B0;D369;1111 1164 11B0; # (퍩; 퍩; 퍩; 퍩; 퍩; ) HANGUL SYLLABLE PYAELG
+D36A;D36A;1111 1164 11B1;D36A;1111 1164 11B1; # (퍪; 퍪; 퍪; 퍪; 퍪; ) HANGUL SYLLABLE PYAELM
+D36B;D36B;1111 1164 11B2;D36B;1111 1164 11B2; # (퍫; 퍫; 퍫; 퍫; 퍫; ) HANGUL SYLLABLE PYAELB
+D36C;D36C;1111 1164 11B3;D36C;1111 1164 11B3; # (퍬; 퍬; 퍬; 퍬; 퍬; ) HANGUL SYLLABLE PYAELS
+D36D;D36D;1111 1164 11B4;D36D;1111 1164 11B4; # (퍭; 퍭; 퍭; 퍭; 퍭; ) HANGUL SYLLABLE PYAELT
+D36E;D36E;1111 1164 11B5;D36E;1111 1164 11B5; # (퍮; 퍮; 퍮; 퍮; 퍮; ) HANGUL SYLLABLE PYAELP
+D36F;D36F;1111 1164 11B6;D36F;1111 1164 11B6; # (퍯; 퍯; 퍯; 퍯; 퍯; ) HANGUL SYLLABLE PYAELH
+D370;D370;1111 1164 11B7;D370;1111 1164 11B7; # (퍰; 퍰; 퍰; 퍰; 퍰; ) HANGUL SYLLABLE PYAEM
+D371;D371;1111 1164 11B8;D371;1111 1164 11B8; # (퍱; 퍱; 퍱; 퍱; 퍱; ) HANGUL SYLLABLE PYAEB
+D372;D372;1111 1164 11B9;D372;1111 1164 11B9; # (퍲; 퍲; 퍲; 퍲; 퍲; ) HANGUL SYLLABLE PYAEBS
+D373;D373;1111 1164 11BA;D373;1111 1164 11BA; # (퍳; 퍳; 퍳; 퍳; 퍳; ) HANGUL SYLLABLE PYAES
+D374;D374;1111 1164 11BB;D374;1111 1164 11BB; # (퍴; 퍴; 퍴; 퍴; 퍴; ) HANGUL SYLLABLE PYAESS
+D375;D375;1111 1164 11BC;D375;1111 1164 11BC; # (퍵; 퍵; 퍵; 퍵; 퍵; ) HANGUL SYLLABLE PYAENG
+D376;D376;1111 1164 11BD;D376;1111 1164 11BD; # (퍶; 퍶; 퍶; 퍶; 퍶; ) HANGUL SYLLABLE PYAEJ
+D377;D377;1111 1164 11BE;D377;1111 1164 11BE; # (퍷; 퍷; 퍷; 퍷; 퍷; ) HANGUL SYLLABLE PYAEC
+D378;D378;1111 1164 11BF;D378;1111 1164 11BF; # (퍸; 퍸; 퍸; 퍸; 퍸; ) HANGUL SYLLABLE PYAEK
+D379;D379;1111 1164 11C0;D379;1111 1164 11C0; # (퍹; 퍹; 퍹; 퍹; 퍹; ) HANGUL SYLLABLE PYAET
+D37A;D37A;1111 1164 11C1;D37A;1111 1164 11C1; # (퍺; 퍺; 퍺; 퍺; 퍺; ) HANGUL SYLLABLE PYAEP
+D37B;D37B;1111 1164 11C2;D37B;1111 1164 11C2; # (퍻; 퍻; 퍻; 퍻; 퍻; ) HANGUL SYLLABLE PYAEH
+D37C;D37C;1111 1165;D37C;1111 1165; # (퍼; 퍼; 퍼; 퍼; 퍼; ) HANGUL SYLLABLE PEO
+D37D;D37D;1111 1165 11A8;D37D;1111 1165 11A8; # (퍽; 퍽; 퍽; 퍽; 퍽; ) HANGUL SYLLABLE PEOG
+D37E;D37E;1111 1165 11A9;D37E;1111 1165 11A9; # (퍾; 퍾; 퍾; 퍾; 퍾; ) HANGUL SYLLABLE PEOGG
+D37F;D37F;1111 1165 11AA;D37F;1111 1165 11AA; # (퍿; 퍿; 퍿; 퍿; 퍿; ) HANGUL SYLLABLE PEOGS
+D380;D380;1111 1165 11AB;D380;1111 1165 11AB; # (펀; 펀; 펀; 펀; 펀; ) HANGUL SYLLABLE PEON
+D381;D381;1111 1165 11AC;D381;1111 1165 11AC; # (펁; 펁; 펁; 펁; 펁; ) HANGUL SYLLABLE PEONJ
+D382;D382;1111 1165 11AD;D382;1111 1165 11AD; # (펂; 펂; 펂; 펂; 펂; ) HANGUL SYLLABLE PEONH
+D383;D383;1111 1165 11AE;D383;1111 1165 11AE; # (펃; 펃; 펃; 펃; 펃; ) HANGUL SYLLABLE PEOD
+D384;D384;1111 1165 11AF;D384;1111 1165 11AF; # (펄; 펄; 펄; 펄; 펄; ) HANGUL SYLLABLE PEOL
+D385;D385;1111 1165 11B0;D385;1111 1165 11B0; # (펅; 펅; 펅; 펅; 펅; ) HANGUL SYLLABLE PEOLG
+D386;D386;1111 1165 11B1;D386;1111 1165 11B1; # (펆; 펆; 펆; 펆; 펆; ) HANGUL SYLLABLE PEOLM
+D387;D387;1111 1165 11B2;D387;1111 1165 11B2; # (펇; 펇; 펇; 펇; 펇; ) HANGUL SYLLABLE PEOLB
+D388;D388;1111 1165 11B3;D388;1111 1165 11B3; # (펈; 펈; 펈; 펈; 펈; ) HANGUL SYLLABLE PEOLS
+D389;D389;1111 1165 11B4;D389;1111 1165 11B4; # (펉; 펉; 펉; 펉; 펉; ) HANGUL SYLLABLE PEOLT
+D38A;D38A;1111 1165 11B5;D38A;1111 1165 11B5; # (펊; 펊; 펊; 펊; 펊; ) HANGUL SYLLABLE PEOLP
+D38B;D38B;1111 1165 11B6;D38B;1111 1165 11B6; # (펋; 펋; 펋; 펋; 펋; ) HANGUL SYLLABLE PEOLH
+D38C;D38C;1111 1165 11B7;D38C;1111 1165 11B7; # (펌; 펌; 펌; 펌; 펌; ) HANGUL SYLLABLE PEOM
+D38D;D38D;1111 1165 11B8;D38D;1111 1165 11B8; # (펍; 펍; 펍; 펍; 펍; ) HANGUL SYLLABLE PEOB
+D38E;D38E;1111 1165 11B9;D38E;1111 1165 11B9; # (펎; 펎; 펎; 펎; 펎; ) HANGUL SYLLABLE PEOBS
+D38F;D38F;1111 1165 11BA;D38F;1111 1165 11BA; # (펏; 펏; 펏; 펏; 펏; ) HANGUL SYLLABLE PEOS
+D390;D390;1111 1165 11BB;D390;1111 1165 11BB; # (펐; 펐; 펐; 펐; 펐; ) HANGUL SYLLABLE PEOSS
+D391;D391;1111 1165 11BC;D391;1111 1165 11BC; # (펑; 펑; 펑; 펑; 펑; ) HANGUL SYLLABLE PEONG
+D392;D392;1111 1165 11BD;D392;1111 1165 11BD; # (펒; 펒; 펒; 펒; 펒; ) HANGUL SYLLABLE PEOJ
+D393;D393;1111 1165 11BE;D393;1111 1165 11BE; # (펓; 펓; 펓; 펓; 펓; ) HANGUL SYLLABLE PEOC
+D394;D394;1111 1165 11BF;D394;1111 1165 11BF; # (펔; 펔; 펔; 펔; 펔; ) HANGUL SYLLABLE PEOK
+D395;D395;1111 1165 11C0;D395;1111 1165 11C0; # (펕; 펕; 펕; 펕; 펕; ) HANGUL SYLLABLE PEOT
+D396;D396;1111 1165 11C1;D396;1111 1165 11C1; # (펖; 펖; 펖; 펖; 펖; ) HANGUL SYLLABLE PEOP
+D397;D397;1111 1165 11C2;D397;1111 1165 11C2; # (펗; 펗; 펗; 펗; 펗; ) HANGUL SYLLABLE PEOH
+D398;D398;1111 1166;D398;1111 1166; # (페; 페; 페; 페; 페; ) HANGUL SYLLABLE PE
+D399;D399;1111 1166 11A8;D399;1111 1166 11A8; # (펙; 펙; 펙; 펙; 펙; ) HANGUL SYLLABLE PEG
+D39A;D39A;1111 1166 11A9;D39A;1111 1166 11A9; # (펚; 펚; 펚; 펚; 펚; ) HANGUL SYLLABLE PEGG
+D39B;D39B;1111 1166 11AA;D39B;1111 1166 11AA; # (펛; 펛; 펛; 펛; 펛; ) HANGUL SYLLABLE PEGS
+D39C;D39C;1111 1166 11AB;D39C;1111 1166 11AB; # (펜; 펜; 펜; 펜; 펜; ) HANGUL SYLLABLE PEN
+D39D;D39D;1111 1166 11AC;D39D;1111 1166 11AC; # (펝; 펝; 펝; 펝; 펝; ) HANGUL SYLLABLE PENJ
+D39E;D39E;1111 1166 11AD;D39E;1111 1166 11AD; # (펞; 펞; 펞; 펞; 펞; ) HANGUL SYLLABLE PENH
+D39F;D39F;1111 1166 11AE;D39F;1111 1166 11AE; # (펟; 펟; 펟; 펟; 펟; ) HANGUL SYLLABLE PED
+D3A0;D3A0;1111 1166 11AF;D3A0;1111 1166 11AF; # (펠; 펠; 펠; 펠; 펠; ) HANGUL SYLLABLE PEL
+D3A1;D3A1;1111 1166 11B0;D3A1;1111 1166 11B0; # (펡; 펡; 펡; 펡; 펡; ) HANGUL SYLLABLE PELG
+D3A2;D3A2;1111 1166 11B1;D3A2;1111 1166 11B1; # (펢; 펢; 펢; 펢; 펢; ) HANGUL SYLLABLE PELM
+D3A3;D3A3;1111 1166 11B2;D3A3;1111 1166 11B2; # (펣; 펣; 펣; 펣; 펣; ) HANGUL SYLLABLE PELB
+D3A4;D3A4;1111 1166 11B3;D3A4;1111 1166 11B3; # (펤; 펤; 펤; 펤; 펤; ) HANGUL SYLLABLE PELS
+D3A5;D3A5;1111 1166 11B4;D3A5;1111 1166 11B4; # (펥; 펥; 펥; 펥; 펥; ) HANGUL SYLLABLE PELT
+D3A6;D3A6;1111 1166 11B5;D3A6;1111 1166 11B5; # (펦; 펦; 펦; 펦; 펦; ) HANGUL SYLLABLE PELP
+D3A7;D3A7;1111 1166 11B6;D3A7;1111 1166 11B6; # (펧; 펧; 펧; 펧; 펧; ) HANGUL SYLLABLE PELH
+D3A8;D3A8;1111 1166 11B7;D3A8;1111 1166 11B7; # (펨; 펨; 펨; 펨; 펨; ) HANGUL SYLLABLE PEM
+D3A9;D3A9;1111 1166 11B8;D3A9;1111 1166 11B8; # (펩; 펩; 펩; 펩; 펩; ) HANGUL SYLLABLE PEB
+D3AA;D3AA;1111 1166 11B9;D3AA;1111 1166 11B9; # (펪; 펪; 펪; 펪; 펪; ) HANGUL SYLLABLE PEBS
+D3AB;D3AB;1111 1166 11BA;D3AB;1111 1166 11BA; # (펫; 펫; 펫; 펫; 펫; ) HANGUL SYLLABLE PES
+D3AC;D3AC;1111 1166 11BB;D3AC;1111 1166 11BB; # (펬; 펬; 펬; 펬; 펬; ) HANGUL SYLLABLE PESS
+D3AD;D3AD;1111 1166 11BC;D3AD;1111 1166 11BC; # (펭; 펭; 펭; 펭; 펭; ) HANGUL SYLLABLE PENG
+D3AE;D3AE;1111 1166 11BD;D3AE;1111 1166 11BD; # (펮; 펮; 펮; 펮; 펮; ) HANGUL SYLLABLE PEJ
+D3AF;D3AF;1111 1166 11BE;D3AF;1111 1166 11BE; # (펯; 펯; 펯; 펯; 펯; ) HANGUL SYLLABLE PEC
+D3B0;D3B0;1111 1166 11BF;D3B0;1111 1166 11BF; # (펰; 펰; 펰; 펰; 펰; ) HANGUL SYLLABLE PEK
+D3B1;D3B1;1111 1166 11C0;D3B1;1111 1166 11C0; # (펱; 펱; 펱; 펱; 펱; ) HANGUL SYLLABLE PET
+D3B2;D3B2;1111 1166 11C1;D3B2;1111 1166 11C1; # (펲; 펲; 펲; 펲; 펲; ) HANGUL SYLLABLE PEP
+D3B3;D3B3;1111 1166 11C2;D3B3;1111 1166 11C2; # (펳; 펳; 펳; 펳; 펳; ) HANGUL SYLLABLE PEH
+D3B4;D3B4;1111 1167;D3B4;1111 1167; # (펴; 펴; 펴; 펴; 펴; ) HANGUL SYLLABLE PYEO
+D3B5;D3B5;1111 1167 11A8;D3B5;1111 1167 11A8; # (펵; 펵; 펵; 펵; 펵; ) HANGUL SYLLABLE PYEOG
+D3B6;D3B6;1111 1167 11A9;D3B6;1111 1167 11A9; # (펶; 펶; 펶; 펶; 펶; ) HANGUL SYLLABLE PYEOGG
+D3B7;D3B7;1111 1167 11AA;D3B7;1111 1167 11AA; # (펷; 펷; 펷; 펷; 펷; ) HANGUL SYLLABLE PYEOGS
+D3B8;D3B8;1111 1167 11AB;D3B8;1111 1167 11AB; # (편; 편; 편; 편; 편; ) HANGUL SYLLABLE PYEON
+D3B9;D3B9;1111 1167 11AC;D3B9;1111 1167 11AC; # (펹; 펹; 펹; 펹; 펹; ) HANGUL SYLLABLE PYEONJ
+D3BA;D3BA;1111 1167 11AD;D3BA;1111 1167 11AD; # (펺; 펺; 펺; 펺; 펺; ) HANGUL SYLLABLE PYEONH
+D3BB;D3BB;1111 1167 11AE;D3BB;1111 1167 11AE; # (펻; 펻; 펻; 펻; 펻; ) HANGUL SYLLABLE PYEOD
+D3BC;D3BC;1111 1167 11AF;D3BC;1111 1167 11AF; # (펼; 펼; 펼; 펼; 펼; ) HANGUL SYLLABLE PYEOL
+D3BD;D3BD;1111 1167 11B0;D3BD;1111 1167 11B0; # (펽; 펽; 펽; 펽; 펽; ) HANGUL SYLLABLE PYEOLG
+D3BE;D3BE;1111 1167 11B1;D3BE;1111 1167 11B1; # (펾; 펾; 펾; 펾; 펾; ) HANGUL SYLLABLE PYEOLM
+D3BF;D3BF;1111 1167 11B2;D3BF;1111 1167 11B2; # (펿; 펿; 펿; 펿; 펿; ) HANGUL SYLLABLE PYEOLB
+D3C0;D3C0;1111 1167 11B3;D3C0;1111 1167 11B3; # (폀; 폀; 폀; 폀; 폀; ) HANGUL SYLLABLE PYEOLS
+D3C1;D3C1;1111 1167 11B4;D3C1;1111 1167 11B4; # (폁; 폁; 폁; 폁; 폁; ) HANGUL SYLLABLE PYEOLT
+D3C2;D3C2;1111 1167 11B5;D3C2;1111 1167 11B5; # (폂; 폂; 폂; 폂; 폂; ) HANGUL SYLLABLE PYEOLP
+D3C3;D3C3;1111 1167 11B6;D3C3;1111 1167 11B6; # (폃; 폃; 폃; 폃; 폃; ) HANGUL SYLLABLE PYEOLH
+D3C4;D3C4;1111 1167 11B7;D3C4;1111 1167 11B7; # (폄; 폄; 폄; 폄; 폄; ) HANGUL SYLLABLE PYEOM
+D3C5;D3C5;1111 1167 11B8;D3C5;1111 1167 11B8; # (폅; 폅; 폅; 폅; 폅; ) HANGUL SYLLABLE PYEOB
+D3C6;D3C6;1111 1167 11B9;D3C6;1111 1167 11B9; # (폆; 폆; 폆; 폆; 폆; ) HANGUL SYLLABLE PYEOBS
+D3C7;D3C7;1111 1167 11BA;D3C7;1111 1167 11BA; # (폇; 폇; 폇; 폇; 폇; ) HANGUL SYLLABLE PYEOS
+D3C8;D3C8;1111 1167 11BB;D3C8;1111 1167 11BB; # (폈; 폈; 폈; 폈; 폈; ) HANGUL SYLLABLE PYEOSS
+D3C9;D3C9;1111 1167 11BC;D3C9;1111 1167 11BC; # (평; 평; 평; 평; 평; ) HANGUL SYLLABLE PYEONG
+D3CA;D3CA;1111 1167 11BD;D3CA;1111 1167 11BD; # (폊; 폊; 폊; 폊; 폊; ) HANGUL SYLLABLE PYEOJ
+D3CB;D3CB;1111 1167 11BE;D3CB;1111 1167 11BE; # (폋; 폋; 폋; 폋; 폋; ) HANGUL SYLLABLE PYEOC
+D3CC;D3CC;1111 1167 11BF;D3CC;1111 1167 11BF; # (폌; 폌; 폌; 폌; 폌; ) HANGUL SYLLABLE PYEOK
+D3CD;D3CD;1111 1167 11C0;D3CD;1111 1167 11C0; # (폍; 폍; 폍; 폍; 폍; ) HANGUL SYLLABLE PYEOT
+D3CE;D3CE;1111 1167 11C1;D3CE;1111 1167 11C1; # (폎; 폎; 폎; 폎; 폎; ) HANGUL SYLLABLE PYEOP
+D3CF;D3CF;1111 1167 11C2;D3CF;1111 1167 11C2; # (폏; 폏; 폏; 폏; 폏; ) HANGUL SYLLABLE PYEOH
+D3D0;D3D0;1111 1168;D3D0;1111 1168; # (폐; 폐; 폐; 폐; 폐; ) HANGUL SYLLABLE PYE
+D3D1;D3D1;1111 1168 11A8;D3D1;1111 1168 11A8; # (폑; 폑; 폑; 폑; 폑; ) HANGUL SYLLABLE PYEG
+D3D2;D3D2;1111 1168 11A9;D3D2;1111 1168 11A9; # (폒; 폒; 폒; 폒; 폒; ) HANGUL SYLLABLE PYEGG
+D3D3;D3D3;1111 1168 11AA;D3D3;1111 1168 11AA; # (폓; 폓; 폓; 폓; 폓; ) HANGUL SYLLABLE PYEGS
+D3D4;D3D4;1111 1168 11AB;D3D4;1111 1168 11AB; # (폔; 폔; 폔; 폔; 폔; ) HANGUL SYLLABLE PYEN
+D3D5;D3D5;1111 1168 11AC;D3D5;1111 1168 11AC; # (폕; 폕; 폕; 폕; 폕; ) HANGUL SYLLABLE PYENJ
+D3D6;D3D6;1111 1168 11AD;D3D6;1111 1168 11AD; # (폖; 폖; 폖; 폖; 폖; ) HANGUL SYLLABLE PYENH
+D3D7;D3D7;1111 1168 11AE;D3D7;1111 1168 11AE; # (폗; 폗; 폗; 폗; 폗; ) HANGUL SYLLABLE PYED
+D3D8;D3D8;1111 1168 11AF;D3D8;1111 1168 11AF; # (폘; 폘; 폘; 폘; 폘; ) HANGUL SYLLABLE PYEL
+D3D9;D3D9;1111 1168 11B0;D3D9;1111 1168 11B0; # (폙; 폙; 폙; 폙; 폙; ) HANGUL SYLLABLE PYELG
+D3DA;D3DA;1111 1168 11B1;D3DA;1111 1168 11B1; # (폚; 폚; 폚; 폚; 폚; ) HANGUL SYLLABLE PYELM
+D3DB;D3DB;1111 1168 11B2;D3DB;1111 1168 11B2; # (폛; 폛; 폛; 폛; 폛; ) HANGUL SYLLABLE PYELB
+D3DC;D3DC;1111 1168 11B3;D3DC;1111 1168 11B3; # (폜; 폜; 폜; 폜; 폜; ) HANGUL SYLLABLE PYELS
+D3DD;D3DD;1111 1168 11B4;D3DD;1111 1168 11B4; # (폝; 폝; 폝; 폝; 폝; ) HANGUL SYLLABLE PYELT
+D3DE;D3DE;1111 1168 11B5;D3DE;1111 1168 11B5; # (폞; 폞; 폞; 폞; 폞; ) HANGUL SYLLABLE PYELP
+D3DF;D3DF;1111 1168 11B6;D3DF;1111 1168 11B6; # (폟; 폟; 폟; 폟; 폟; ) HANGUL SYLLABLE PYELH
+D3E0;D3E0;1111 1168 11B7;D3E0;1111 1168 11B7; # (폠; 폠; 폠; 폠; 폠; ) HANGUL SYLLABLE PYEM
+D3E1;D3E1;1111 1168 11B8;D3E1;1111 1168 11B8; # (폡; 폡; 폡; 폡; 폡; ) HANGUL SYLLABLE PYEB
+D3E2;D3E2;1111 1168 11B9;D3E2;1111 1168 11B9; # (폢; 폢; 폢; 폢; 폢; ) HANGUL SYLLABLE PYEBS
+D3E3;D3E3;1111 1168 11BA;D3E3;1111 1168 11BA; # (폣; 폣; 폣; 폣; 폣; ) HANGUL SYLLABLE PYES
+D3E4;D3E4;1111 1168 11BB;D3E4;1111 1168 11BB; # (폤; 폤; 폤; 폤; 폤; ) HANGUL SYLLABLE PYESS
+D3E5;D3E5;1111 1168 11BC;D3E5;1111 1168 11BC; # (폥; 폥; 폥; 폥; 폥; ) HANGUL SYLLABLE PYENG
+D3E6;D3E6;1111 1168 11BD;D3E6;1111 1168 11BD; # (폦; 폦; 폦; 폦; 폦; ) HANGUL SYLLABLE PYEJ
+D3E7;D3E7;1111 1168 11BE;D3E7;1111 1168 11BE; # (폧; 폧; 폧; 폧; 폧; ) HANGUL SYLLABLE PYEC
+D3E8;D3E8;1111 1168 11BF;D3E8;1111 1168 11BF; # (폨; 폨; 폨; 폨; 폨; ) HANGUL SYLLABLE PYEK
+D3E9;D3E9;1111 1168 11C0;D3E9;1111 1168 11C0; # (폩; 폩; 폩; 폩; 폩; ) HANGUL SYLLABLE PYET
+D3EA;D3EA;1111 1168 11C1;D3EA;1111 1168 11C1; # (폪; 폪; 폪; 폪; 폪; ) HANGUL SYLLABLE PYEP
+D3EB;D3EB;1111 1168 11C2;D3EB;1111 1168 11C2; # (폫; 폫; 폫; 폫; 폫; ) HANGUL SYLLABLE PYEH
+D3EC;D3EC;1111 1169;D3EC;1111 1169; # (포; 포; 포; 포; 포; ) HANGUL SYLLABLE PO
+D3ED;D3ED;1111 1169 11A8;D3ED;1111 1169 11A8; # (폭; 폭; 폭; 폭; 폭; ) HANGUL SYLLABLE POG
+D3EE;D3EE;1111 1169 11A9;D3EE;1111 1169 11A9; # (폮; 폮; 폮; 폮; 폮; ) HANGUL SYLLABLE POGG
+D3EF;D3EF;1111 1169 11AA;D3EF;1111 1169 11AA; # (폯; 폯; 폯; 폯; 폯; ) HANGUL SYLLABLE POGS
+D3F0;D3F0;1111 1169 11AB;D3F0;1111 1169 11AB; # (폰; 폰; 폰; 폰; 폰; ) HANGUL SYLLABLE PON
+D3F1;D3F1;1111 1169 11AC;D3F1;1111 1169 11AC; # (폱; 폱; 폱; 폱; 폱; ) HANGUL SYLLABLE PONJ
+D3F2;D3F2;1111 1169 11AD;D3F2;1111 1169 11AD; # (폲; 폲; 폲; 폲; 폲; ) HANGUL SYLLABLE PONH
+D3F3;D3F3;1111 1169 11AE;D3F3;1111 1169 11AE; # (폳; 폳; 폳; 폳; 폳; ) HANGUL SYLLABLE POD
+D3F4;D3F4;1111 1169 11AF;D3F4;1111 1169 11AF; # (폴; 폴; 폴; 폴; 폴; ) HANGUL SYLLABLE POL
+D3F5;D3F5;1111 1169 11B0;D3F5;1111 1169 11B0; # (폵; 폵; 폵; 폵; 폵; ) HANGUL SYLLABLE POLG
+D3F6;D3F6;1111 1169 11B1;D3F6;1111 1169 11B1; # (폶; 폶; 폶; 폶; 폶; ) HANGUL SYLLABLE POLM
+D3F7;D3F7;1111 1169 11B2;D3F7;1111 1169 11B2; # (폷; 폷; 폷; 폷; 폷; ) HANGUL SYLLABLE POLB
+D3F8;D3F8;1111 1169 11B3;D3F8;1111 1169 11B3; # (폸; 폸; 폸; 폸; 폸; ) HANGUL SYLLABLE POLS
+D3F9;D3F9;1111 1169 11B4;D3F9;1111 1169 11B4; # (폹; 폹; 폹; 폹; 폹; ) HANGUL SYLLABLE POLT
+D3FA;D3FA;1111 1169 11B5;D3FA;1111 1169 11B5; # (폺; 폺; 폺; 폺; 폺; ) HANGUL SYLLABLE POLP
+D3FB;D3FB;1111 1169 11B6;D3FB;1111 1169 11B6; # (폻; 폻; 폻; 폻; 폻; ) HANGUL SYLLABLE POLH
+D3FC;D3FC;1111 1169 11B7;D3FC;1111 1169 11B7; # (폼; 폼; 폼; 폼; 폼; ) HANGUL SYLLABLE POM
+D3FD;D3FD;1111 1169 11B8;D3FD;1111 1169 11B8; # (폽; 폽; 폽; 폽; 폽; ) HANGUL SYLLABLE POB
+D3FE;D3FE;1111 1169 11B9;D3FE;1111 1169 11B9; # (폾; 폾; 폾; 폾; 폾; ) HANGUL SYLLABLE POBS
+D3FF;D3FF;1111 1169 11BA;D3FF;1111 1169 11BA; # (폿; 폿; 폿; 폿; 폿; ) HANGUL SYLLABLE POS
+D400;D400;1111 1169 11BB;D400;1111 1169 11BB; # (퐀; 퐀; 퐀; 퐀; 퐀; ) HANGUL SYLLABLE POSS
+D401;D401;1111 1169 11BC;D401;1111 1169 11BC; # (퐁; 퐁; 퐁; 퐁; 퐁; ) HANGUL SYLLABLE PONG
+D402;D402;1111 1169 11BD;D402;1111 1169 11BD; # (퐂; 퐂; 퐂; 퐂; 퐂; ) HANGUL SYLLABLE POJ
+D403;D403;1111 1169 11BE;D403;1111 1169 11BE; # (퐃; 퐃; 퐃; 퐃; 퐃; ) HANGUL SYLLABLE POC
+D404;D404;1111 1169 11BF;D404;1111 1169 11BF; # (퐄; 퐄; 퐄; 퐄; 퐄; ) HANGUL SYLLABLE POK
+D405;D405;1111 1169 11C0;D405;1111 1169 11C0; # (퐅; 퐅; 퐅; 퐅; 퐅; ) HANGUL SYLLABLE POT
+D406;D406;1111 1169 11C1;D406;1111 1169 11C1; # (퐆; 퐆; 퐆; 퐆; 퐆; ) HANGUL SYLLABLE POP
+D407;D407;1111 1169 11C2;D407;1111 1169 11C2; # (퐇; 퐇; 퐇; 퐇; 퐇; ) HANGUL SYLLABLE POH
+D408;D408;1111 116A;D408;1111 116A; # (퐈; 퐈; 퐈; 퐈; 퐈; ) HANGUL SYLLABLE PWA
+D409;D409;1111 116A 11A8;D409;1111 116A 11A8; # (퐉; 퐉; 퐉; 퐉; 퐉; ) HANGUL SYLLABLE PWAG
+D40A;D40A;1111 116A 11A9;D40A;1111 116A 11A9; # (퐊; 퐊; 퐊; 퐊; 퐊; ) HANGUL SYLLABLE PWAGG
+D40B;D40B;1111 116A 11AA;D40B;1111 116A 11AA; # (퐋; 퐋; 퐋; 퐋; 퐋; ) HANGUL SYLLABLE PWAGS
+D40C;D40C;1111 116A 11AB;D40C;1111 116A 11AB; # (퐌; 퐌; 퐌; 퐌; 퐌; ) HANGUL SYLLABLE PWAN
+D40D;D40D;1111 116A 11AC;D40D;1111 116A 11AC; # (퐍; 퐍; 퐍; 퐍; 퐍; ) HANGUL SYLLABLE PWANJ
+D40E;D40E;1111 116A 11AD;D40E;1111 116A 11AD; # (퐎; 퐎; 퐎; 퐎; 퐎; ) HANGUL SYLLABLE PWANH
+D40F;D40F;1111 116A 11AE;D40F;1111 116A 11AE; # (퐏; 퐏; 퐏; 퐏; 퐏; ) HANGUL SYLLABLE PWAD
+D410;D410;1111 116A 11AF;D410;1111 116A 11AF; # (퐐; 퐐; 퐐; 퐐; 퐐; ) HANGUL SYLLABLE PWAL
+D411;D411;1111 116A 11B0;D411;1111 116A 11B0; # (퐑; 퐑; 퐑; 퐑; 퐑; ) HANGUL SYLLABLE PWALG
+D412;D412;1111 116A 11B1;D412;1111 116A 11B1; # (퐒; 퐒; 퐒; 퐒; 퐒; ) HANGUL SYLLABLE PWALM
+D413;D413;1111 116A 11B2;D413;1111 116A 11B2; # (퐓; 퐓; 퐓; 퐓; 퐓; ) HANGUL SYLLABLE PWALB
+D414;D414;1111 116A 11B3;D414;1111 116A 11B3; # (퐔; 퐔; 퐔; 퐔; 퐔; ) HANGUL SYLLABLE PWALS
+D415;D415;1111 116A 11B4;D415;1111 116A 11B4; # (퐕; 퐕; 퐕; 퐕; 퐕; ) HANGUL SYLLABLE PWALT
+D416;D416;1111 116A 11B5;D416;1111 116A 11B5; # (퐖; 퐖; 퐖; 퐖; 퐖; ) HANGUL SYLLABLE PWALP
+D417;D417;1111 116A 11B6;D417;1111 116A 11B6; # (퐗; 퐗; 퐗; 퐗; 퐗; ) HANGUL SYLLABLE PWALH
+D418;D418;1111 116A 11B7;D418;1111 116A 11B7; # (퐘; 퐘; 퐘; 퐘; 퐘; ) HANGUL SYLLABLE PWAM
+D419;D419;1111 116A 11B8;D419;1111 116A 11B8; # (퐙; 퐙; 퐙; 퐙; 퐙; ) HANGUL SYLLABLE PWAB
+D41A;D41A;1111 116A 11B9;D41A;1111 116A 11B9; # (퐚; 퐚; 퐚; 퐚; 퐚; ) HANGUL SYLLABLE PWABS
+D41B;D41B;1111 116A 11BA;D41B;1111 116A 11BA; # (퐛; 퐛; 퐛; 퐛; 퐛; ) HANGUL SYLLABLE PWAS
+D41C;D41C;1111 116A 11BB;D41C;1111 116A 11BB; # (퐜; 퐜; 퐜; 퐜; 퐜; ) HANGUL SYLLABLE PWASS
+D41D;D41D;1111 116A 11BC;D41D;1111 116A 11BC; # (퐝; 퐝; 퐝; 퐝; 퐝; ) HANGUL SYLLABLE PWANG
+D41E;D41E;1111 116A 11BD;D41E;1111 116A 11BD; # (퐞; 퐞; 퐞; 퐞; 퐞; ) HANGUL SYLLABLE PWAJ
+D41F;D41F;1111 116A 11BE;D41F;1111 116A 11BE; # (퐟; 퐟; 퐟; 퐟; 퐟; ) HANGUL SYLLABLE PWAC
+D420;D420;1111 116A 11BF;D420;1111 116A 11BF; # (퐠; 퐠; 퐠; 퐠; 퐠; ) HANGUL SYLLABLE PWAK
+D421;D421;1111 116A 11C0;D421;1111 116A 11C0; # (퐡; 퐡; 퐡; 퐡; 퐡; ) HANGUL SYLLABLE PWAT
+D422;D422;1111 116A 11C1;D422;1111 116A 11C1; # (퐢; 퐢; 퐢; 퐢; 퐢; ) HANGUL SYLLABLE PWAP
+D423;D423;1111 116A 11C2;D423;1111 116A 11C2; # (퐣; 퐣; 퐣; 퐣; 퐣; ) HANGUL SYLLABLE PWAH
+D424;D424;1111 116B;D424;1111 116B; # (퐤; 퐤; 퐤; 퐤; 퐤; ) HANGUL SYLLABLE PWAE
+D425;D425;1111 116B 11A8;D425;1111 116B 11A8; # (퐥; 퐥; 퐥; 퐥; 퐥; ) HANGUL SYLLABLE PWAEG
+D426;D426;1111 116B 11A9;D426;1111 116B 11A9; # (퐦; 퐦; 퐦; 퐦; 퐦; ) HANGUL SYLLABLE PWAEGG
+D427;D427;1111 116B 11AA;D427;1111 116B 11AA; # (퐧; 퐧; 퐧; 퐧; 퐧; ) HANGUL SYLLABLE PWAEGS
+D428;D428;1111 116B 11AB;D428;1111 116B 11AB; # (퐨; 퐨; 퐨; 퐨; 퐨; ) HANGUL SYLLABLE PWAEN
+D429;D429;1111 116B 11AC;D429;1111 116B 11AC; # (퐩; 퐩; 퐩; 퐩; 퐩; ) HANGUL SYLLABLE PWAENJ
+D42A;D42A;1111 116B 11AD;D42A;1111 116B 11AD; # (퐪; 퐪; 퐪; 퐪; 퐪; ) HANGUL SYLLABLE PWAENH
+D42B;D42B;1111 116B 11AE;D42B;1111 116B 11AE; # (퐫; 퐫; 퐫; 퐫; 퐫; ) HANGUL SYLLABLE PWAED
+D42C;D42C;1111 116B 11AF;D42C;1111 116B 11AF; # (퐬; 퐬; 퐬; 퐬; 퐬; ) HANGUL SYLLABLE PWAEL
+D42D;D42D;1111 116B 11B0;D42D;1111 116B 11B0; # (퐭; 퐭; 퐭; 퐭; 퐭; ) HANGUL SYLLABLE PWAELG
+D42E;D42E;1111 116B 11B1;D42E;1111 116B 11B1; # (퐮; 퐮; 퐮; 퐮; 퐮; ) HANGUL SYLLABLE PWAELM
+D42F;D42F;1111 116B 11B2;D42F;1111 116B 11B2; # (퐯; 퐯; 퐯; 퐯; 퐯; ) HANGUL SYLLABLE PWAELB
+D430;D430;1111 116B 11B3;D430;1111 116B 11B3; # (퐰; 퐰; 퐰; 퐰; 퐰; ) HANGUL SYLLABLE PWAELS
+D431;D431;1111 116B 11B4;D431;1111 116B 11B4; # (퐱; 퐱; 퐱; 퐱; 퐱; ) HANGUL SYLLABLE PWAELT
+D432;D432;1111 116B 11B5;D432;1111 116B 11B5; # (퐲; 퐲; 퐲; 퐲; 퐲; ) HANGUL SYLLABLE PWAELP
+D433;D433;1111 116B 11B6;D433;1111 116B 11B6; # (퐳; 퐳; 퐳; 퐳; 퐳; ) HANGUL SYLLABLE PWAELH
+D434;D434;1111 116B 11B7;D434;1111 116B 11B7; # (퐴; 퐴; 퐴; 퐴; 퐴; ) HANGUL SYLLABLE PWAEM
+D435;D435;1111 116B 11B8;D435;1111 116B 11B8; # (퐵; 퐵; 퐵; 퐵; 퐵; ) HANGUL SYLLABLE PWAEB
+D436;D436;1111 116B 11B9;D436;1111 116B 11B9; # (퐶; 퐶; 퐶; 퐶; 퐶; ) HANGUL SYLLABLE PWAEBS
+D437;D437;1111 116B 11BA;D437;1111 116B 11BA; # (퐷; 퐷; 퐷; 퐷; 퐷; ) HANGUL SYLLABLE PWAES
+D438;D438;1111 116B 11BB;D438;1111 116B 11BB; # (퐸; 퐸; 퐸; 퐸; 퐸; ) HANGUL SYLLABLE PWAESS
+D439;D439;1111 116B 11BC;D439;1111 116B 11BC; # (퐹; 퐹; 퐹; 퐹; 퐹; ) HANGUL SYLLABLE PWAENG
+D43A;D43A;1111 116B 11BD;D43A;1111 116B 11BD; # (퐺; 퐺; 퐺; 퐺; 퐺; ) HANGUL SYLLABLE PWAEJ
+D43B;D43B;1111 116B 11BE;D43B;1111 116B 11BE; # (퐻; 퐻; 퐻; 퐻; 퐻; ) HANGUL SYLLABLE PWAEC
+D43C;D43C;1111 116B 11BF;D43C;1111 116B 11BF; # (퐼; 퐼; 퐼; 퐼; 퐼; ) HANGUL SYLLABLE PWAEK
+D43D;D43D;1111 116B 11C0;D43D;1111 116B 11C0; # (퐽; 퐽; 퐽; 퐽; 퐽; ) HANGUL SYLLABLE PWAET
+D43E;D43E;1111 116B 11C1;D43E;1111 116B 11C1; # (퐾; 퐾; 퐾; 퐾; 퐾; ) HANGUL SYLLABLE PWAEP
+D43F;D43F;1111 116B 11C2;D43F;1111 116B 11C2; # (퐿; 퐿; 퐿; 퐿; 퐿; ) HANGUL SYLLABLE PWAEH
+D440;D440;1111 116C;D440;1111 116C; # (푀; 푀; 푀; 푀; 푀; ) HANGUL SYLLABLE POE
+D441;D441;1111 116C 11A8;D441;1111 116C 11A8; # (푁; 푁; 푁; 푁; 푁; ) HANGUL SYLLABLE POEG
+D442;D442;1111 116C 11A9;D442;1111 116C 11A9; # (푂; 푂; 푂; 푂; 푂; ) HANGUL SYLLABLE POEGG
+D443;D443;1111 116C 11AA;D443;1111 116C 11AA; # (푃; 푃; 푃; 푃; 푃; ) HANGUL SYLLABLE POEGS
+D444;D444;1111 116C 11AB;D444;1111 116C 11AB; # (푄; 푄; 푄; 푄; 푄; ) HANGUL SYLLABLE POEN
+D445;D445;1111 116C 11AC;D445;1111 116C 11AC; # (푅; 푅; 푅; 푅; 푅; ) HANGUL SYLLABLE POENJ
+D446;D446;1111 116C 11AD;D446;1111 116C 11AD; # (푆; 푆; 푆; 푆; 푆; ) HANGUL SYLLABLE POENH
+D447;D447;1111 116C 11AE;D447;1111 116C 11AE; # (푇; 푇; 푇; 푇; 푇; ) HANGUL SYLLABLE POED
+D448;D448;1111 116C 11AF;D448;1111 116C 11AF; # (푈; 푈; 푈; 푈; 푈; ) HANGUL SYLLABLE POEL
+D449;D449;1111 116C 11B0;D449;1111 116C 11B0; # (푉; 푉; 푉; 푉; 푉; ) HANGUL SYLLABLE POELG
+D44A;D44A;1111 116C 11B1;D44A;1111 116C 11B1; # (푊; 푊; 푊; 푊; 푊; ) HANGUL SYLLABLE POELM
+D44B;D44B;1111 116C 11B2;D44B;1111 116C 11B2; # (푋; 푋; 푋; 푋; 푋; ) HANGUL SYLLABLE POELB
+D44C;D44C;1111 116C 11B3;D44C;1111 116C 11B3; # (푌; 푌; 푌; 푌; 푌; ) HANGUL SYLLABLE POELS
+D44D;D44D;1111 116C 11B4;D44D;1111 116C 11B4; # (푍; 푍; 푍; 푍; 푍; ) HANGUL SYLLABLE POELT
+D44E;D44E;1111 116C 11B5;D44E;1111 116C 11B5; # (푎; 푎; 푎; 푎; 푎; ) HANGUL SYLLABLE POELP
+D44F;D44F;1111 116C 11B6;D44F;1111 116C 11B6; # (푏; 푏; 푏; 푏; 푏; ) HANGUL SYLLABLE POELH
+D450;D450;1111 116C 11B7;D450;1111 116C 11B7; # (푐; 푐; 푐; 푐; 푐; ) HANGUL SYLLABLE POEM
+D451;D451;1111 116C 11B8;D451;1111 116C 11B8; # (푑; 푑; 푑; 푑; 푑; ) HANGUL SYLLABLE POEB
+D452;D452;1111 116C 11B9;D452;1111 116C 11B9; # (푒; 푒; 푒; 푒; 푒; ) HANGUL SYLLABLE POEBS
+D453;D453;1111 116C 11BA;D453;1111 116C 11BA; # (푓; 푓; 푓; 푓; 푓; ) HANGUL SYLLABLE POES
+D454;D454;1111 116C 11BB;D454;1111 116C 11BB; # (푔; 푔; 푔; 푔; 푔; ) HANGUL SYLLABLE POESS
+D455;D455;1111 116C 11BC;D455;1111 116C 11BC; # (푕; 푕; 푕; 푕; 푕; ) HANGUL SYLLABLE POENG
+D456;D456;1111 116C 11BD;D456;1111 116C 11BD; # (푖; 푖; 푖; 푖; 푖; ) HANGUL SYLLABLE POEJ
+D457;D457;1111 116C 11BE;D457;1111 116C 11BE; # (푗; 푗; 푗; 푗; 푗; ) HANGUL SYLLABLE POEC
+D458;D458;1111 116C 11BF;D458;1111 116C 11BF; # (푘; 푘; 푘; 푘; 푘; ) HANGUL SYLLABLE POEK
+D459;D459;1111 116C 11C0;D459;1111 116C 11C0; # (푙; 푙; 푙; 푙; 푙; ) HANGUL SYLLABLE POET
+D45A;D45A;1111 116C 11C1;D45A;1111 116C 11C1; # (푚; 푚; 푚; 푚; 푚; ) HANGUL SYLLABLE POEP
+D45B;D45B;1111 116C 11C2;D45B;1111 116C 11C2; # (푛; 푛; 푛; 푛; 푛; ) HANGUL SYLLABLE POEH
+D45C;D45C;1111 116D;D45C;1111 116D; # (표; 표; 표; 표; 표; ) HANGUL SYLLABLE PYO
+D45D;D45D;1111 116D 11A8;D45D;1111 116D 11A8; # (푝; 푝; 푝; 푝; 푝; ) HANGUL SYLLABLE PYOG
+D45E;D45E;1111 116D 11A9;D45E;1111 116D 11A9; # (푞; 푞; 푞; 푞; 푞; ) HANGUL SYLLABLE PYOGG
+D45F;D45F;1111 116D 11AA;D45F;1111 116D 11AA; # (푟; 푟; 푟; 푟; 푟; ) HANGUL SYLLABLE PYOGS
+D460;D460;1111 116D 11AB;D460;1111 116D 11AB; # (푠; 푠; 푠; 푠; 푠; ) HANGUL SYLLABLE PYON
+D461;D461;1111 116D 11AC;D461;1111 116D 11AC; # (푡; 푡; 푡; 푡; 푡; ) HANGUL SYLLABLE PYONJ
+D462;D462;1111 116D 11AD;D462;1111 116D 11AD; # (푢; 푢; 푢; 푢; 푢; ) HANGUL SYLLABLE PYONH
+D463;D463;1111 116D 11AE;D463;1111 116D 11AE; # (푣; 푣; 푣; 푣; 푣; ) HANGUL SYLLABLE PYOD
+D464;D464;1111 116D 11AF;D464;1111 116D 11AF; # (푤; 푤; 푤; 푤; 푤; ) HANGUL SYLLABLE PYOL
+D465;D465;1111 116D 11B0;D465;1111 116D 11B0; # (푥; 푥; 푥; 푥; 푥; ) HANGUL SYLLABLE PYOLG
+D466;D466;1111 116D 11B1;D466;1111 116D 11B1; # (푦; 푦; 푦; 푦; 푦; ) HANGUL SYLLABLE PYOLM
+D467;D467;1111 116D 11B2;D467;1111 116D 11B2; # (푧; 푧; 푧; 푧; 푧; ) HANGUL SYLLABLE PYOLB
+D468;D468;1111 116D 11B3;D468;1111 116D 11B3; # (푨; 푨; 푨; 푨; 푨; ) HANGUL SYLLABLE PYOLS
+D469;D469;1111 116D 11B4;D469;1111 116D 11B4; # (푩; 푩; 푩; 푩; 푩; ) HANGUL SYLLABLE PYOLT
+D46A;D46A;1111 116D 11B5;D46A;1111 116D 11B5; # (푪; 푪; 푪; 푪; 푪; ) HANGUL SYLLABLE PYOLP
+D46B;D46B;1111 116D 11B6;D46B;1111 116D 11B6; # (푫; 푫; 푫; 푫; 푫; ) HANGUL SYLLABLE PYOLH
+D46C;D46C;1111 116D 11B7;D46C;1111 116D 11B7; # (푬; 푬; 푬; 푬; 푬; ) HANGUL SYLLABLE PYOM
+D46D;D46D;1111 116D 11B8;D46D;1111 116D 11B8; # (푭; 푭; 푭; 푭; 푭; ) HANGUL SYLLABLE PYOB
+D46E;D46E;1111 116D 11B9;D46E;1111 116D 11B9; # (푮; 푮; 푮; 푮; 푮; ) HANGUL SYLLABLE PYOBS
+D46F;D46F;1111 116D 11BA;D46F;1111 116D 11BA; # (푯; 푯; 푯; 푯; 푯; ) HANGUL SYLLABLE PYOS
+D470;D470;1111 116D 11BB;D470;1111 116D 11BB; # (푰; 푰; 푰; 푰; 푰; ) HANGUL SYLLABLE PYOSS
+D471;D471;1111 116D 11BC;D471;1111 116D 11BC; # (푱; 푱; 푱; 푱; 푱; ) HANGUL SYLLABLE PYONG
+D472;D472;1111 116D 11BD;D472;1111 116D 11BD; # (푲; 푲; 푲; 푲; 푲; ) HANGUL SYLLABLE PYOJ
+D473;D473;1111 116D 11BE;D473;1111 116D 11BE; # (푳; 푳; 푳; 푳; 푳; ) HANGUL SYLLABLE PYOC
+D474;D474;1111 116D 11BF;D474;1111 116D 11BF; # (푴; 푴; 푴; 푴; 푴; ) HANGUL SYLLABLE PYOK
+D475;D475;1111 116D 11C0;D475;1111 116D 11C0; # (푵; 푵; 푵; 푵; 푵; ) HANGUL SYLLABLE PYOT
+D476;D476;1111 116D 11C1;D476;1111 116D 11C1; # (푶; 푶; 푶; 푶; 푶; ) HANGUL SYLLABLE PYOP
+D477;D477;1111 116D 11C2;D477;1111 116D 11C2; # (푷; 푷; 푷; 푷; 푷; ) HANGUL SYLLABLE PYOH
+D478;D478;1111 116E;D478;1111 116E; # (푸; 푸; 푸; 푸; 푸; ) HANGUL SYLLABLE PU
+D479;D479;1111 116E 11A8;D479;1111 116E 11A8; # (푹; 푹; 푹; 푹; 푹; ) HANGUL SYLLABLE PUG
+D47A;D47A;1111 116E 11A9;D47A;1111 116E 11A9; # (푺; 푺; 푺; 푺; 푺; ) HANGUL SYLLABLE PUGG
+D47B;D47B;1111 116E 11AA;D47B;1111 116E 11AA; # (푻; 푻; 푻; 푻; 푻; ) HANGUL SYLLABLE PUGS
+D47C;D47C;1111 116E 11AB;D47C;1111 116E 11AB; # (푼; 푼; 푼; 푼; 푼; ) HANGUL SYLLABLE PUN
+D47D;D47D;1111 116E 11AC;D47D;1111 116E 11AC; # (푽; 푽; 푽; 푽; 푽; ) HANGUL SYLLABLE PUNJ
+D47E;D47E;1111 116E 11AD;D47E;1111 116E 11AD; # (푾; 푾; 푾; 푾; 푾; ) HANGUL SYLLABLE PUNH
+D47F;D47F;1111 116E 11AE;D47F;1111 116E 11AE; # (푿; 푿; 푿; 푿; 푿; ) HANGUL SYLLABLE PUD
+D480;D480;1111 116E 11AF;D480;1111 116E 11AF; # (풀; 풀; 풀; 풀; 풀; ) HANGUL SYLLABLE PUL
+D481;D481;1111 116E 11B0;D481;1111 116E 11B0; # (풁; 풁; 풁; 풁; 풁; ) HANGUL SYLLABLE PULG
+D482;D482;1111 116E 11B1;D482;1111 116E 11B1; # (풂; 풂; 풂; 풂; 풂; ) HANGUL SYLLABLE PULM
+D483;D483;1111 116E 11B2;D483;1111 116E 11B2; # (풃; 풃; 풃; 풃; 풃; ) HANGUL SYLLABLE PULB
+D484;D484;1111 116E 11B3;D484;1111 116E 11B3; # (풄; 풄; 풄; 풄; 풄; ) HANGUL SYLLABLE PULS
+D485;D485;1111 116E 11B4;D485;1111 116E 11B4; # (풅; 풅; 풅; 풅; 풅; ) HANGUL SYLLABLE PULT
+D486;D486;1111 116E 11B5;D486;1111 116E 11B5; # (풆; 풆; 풆; 풆; 풆; ) HANGUL SYLLABLE PULP
+D487;D487;1111 116E 11B6;D487;1111 116E 11B6; # (풇; 풇; 풇; 풇; 풇; ) HANGUL SYLLABLE PULH
+D488;D488;1111 116E 11B7;D488;1111 116E 11B7; # (품; 품; 품; 품; 품; ) HANGUL SYLLABLE PUM
+D489;D489;1111 116E 11B8;D489;1111 116E 11B8; # (풉; 풉; 풉; 풉; 풉; ) HANGUL SYLLABLE PUB
+D48A;D48A;1111 116E 11B9;D48A;1111 116E 11B9; # (풊; 풊; 풊; 풊; 풊; ) HANGUL SYLLABLE PUBS
+D48B;D48B;1111 116E 11BA;D48B;1111 116E 11BA; # (풋; 풋; 풋; 풋; 풋; ) HANGUL SYLLABLE PUS
+D48C;D48C;1111 116E 11BB;D48C;1111 116E 11BB; # (풌; 풌; 풌; 풌; 풌; ) HANGUL SYLLABLE PUSS
+D48D;D48D;1111 116E 11BC;D48D;1111 116E 11BC; # (풍; 풍; 풍; 풍; 풍; ) HANGUL SYLLABLE PUNG
+D48E;D48E;1111 116E 11BD;D48E;1111 116E 11BD; # (풎; 풎; 풎; 풎; 풎; ) HANGUL SYLLABLE PUJ
+D48F;D48F;1111 116E 11BE;D48F;1111 116E 11BE; # (풏; 풏; 풏; 풏; 풏; ) HANGUL SYLLABLE PUC
+D490;D490;1111 116E 11BF;D490;1111 116E 11BF; # (풐; 풐; 풐; 풐; 풐; ) HANGUL SYLLABLE PUK
+D491;D491;1111 116E 11C0;D491;1111 116E 11C0; # (풑; 풑; 풑; 풑; 풑; ) HANGUL SYLLABLE PUT
+D492;D492;1111 116E 11C1;D492;1111 116E 11C1; # (풒; 풒; 풒; 풒; 풒; ) HANGUL SYLLABLE PUP
+D493;D493;1111 116E 11C2;D493;1111 116E 11C2; # (풓; 풓; 풓; 풓; 풓; ) HANGUL SYLLABLE PUH
+D494;D494;1111 116F;D494;1111 116F; # (풔; 풔; 풔; 풔; 풔; ) HANGUL SYLLABLE PWEO
+D495;D495;1111 116F 11A8;D495;1111 116F 11A8; # (풕; 풕; 풕; 풕; 풕; ) HANGUL SYLLABLE PWEOG
+D496;D496;1111 116F 11A9;D496;1111 116F 11A9; # (풖; 풖; 풖; 풖; 풖; ) HANGUL SYLLABLE PWEOGG
+D497;D497;1111 116F 11AA;D497;1111 116F 11AA; # (풗; 풗; 풗; 풗; 풗; ) HANGUL SYLLABLE PWEOGS
+D498;D498;1111 116F 11AB;D498;1111 116F 11AB; # (풘; 풘; 풘; 풘; 풘; ) HANGUL SYLLABLE PWEON
+D499;D499;1111 116F 11AC;D499;1111 116F 11AC; # (풙; 풙; 풙; 풙; 풙; ) HANGUL SYLLABLE PWEONJ
+D49A;D49A;1111 116F 11AD;D49A;1111 116F 11AD; # (풚; 풚; 풚; 풚; 풚; ) HANGUL SYLLABLE PWEONH
+D49B;D49B;1111 116F 11AE;D49B;1111 116F 11AE; # (풛; 풛; 풛; 풛; 풛; ) HANGUL SYLLABLE PWEOD
+D49C;D49C;1111 116F 11AF;D49C;1111 116F 11AF; # (풜; 풜; 풜; 풜; 풜; ) HANGUL SYLLABLE PWEOL
+D49D;D49D;1111 116F 11B0;D49D;1111 116F 11B0; # (풝; 풝; 풝; 풝; 풝; ) HANGUL SYLLABLE PWEOLG
+D49E;D49E;1111 116F 11B1;D49E;1111 116F 11B1; # (풞; 풞; 풞; 풞; 풞; ) HANGUL SYLLABLE PWEOLM
+D49F;D49F;1111 116F 11B2;D49F;1111 116F 11B2; # (풟; 풟; 풟; 풟; 풟; ) HANGUL SYLLABLE PWEOLB
+D4A0;D4A0;1111 116F 11B3;D4A0;1111 116F 11B3; # (풠; 풠; 풠; 풠; 풠; ) HANGUL SYLLABLE PWEOLS
+D4A1;D4A1;1111 116F 11B4;D4A1;1111 116F 11B4; # (풡; 풡; 풡; 풡; 풡; ) HANGUL SYLLABLE PWEOLT
+D4A2;D4A2;1111 116F 11B5;D4A2;1111 116F 11B5; # (풢; 풢; 풢; 풢; 풢; ) HANGUL SYLLABLE PWEOLP
+D4A3;D4A3;1111 116F 11B6;D4A3;1111 116F 11B6; # (풣; 풣; 풣; 풣; 풣; ) HANGUL SYLLABLE PWEOLH
+D4A4;D4A4;1111 116F 11B7;D4A4;1111 116F 11B7; # (풤; 풤; 풤; 풤; 풤; ) HANGUL SYLLABLE PWEOM
+D4A5;D4A5;1111 116F 11B8;D4A5;1111 116F 11B8; # (풥; 풥; 풥; 풥; 풥; ) HANGUL SYLLABLE PWEOB
+D4A6;D4A6;1111 116F 11B9;D4A6;1111 116F 11B9; # (풦; 풦; 풦; 풦; 풦; ) HANGUL SYLLABLE PWEOBS
+D4A7;D4A7;1111 116F 11BA;D4A7;1111 116F 11BA; # (풧; 풧; 풧; 풧; 풧; ) HANGUL SYLLABLE PWEOS
+D4A8;D4A8;1111 116F 11BB;D4A8;1111 116F 11BB; # (풨; 풨; 풨; 풨; 풨; ) HANGUL SYLLABLE PWEOSS
+D4A9;D4A9;1111 116F 11BC;D4A9;1111 116F 11BC; # (풩; 풩; 풩; 풩; 풩; ) HANGUL SYLLABLE PWEONG
+D4AA;D4AA;1111 116F 11BD;D4AA;1111 116F 11BD; # (풪; 풪; 풪; 풪; 풪; ) HANGUL SYLLABLE PWEOJ
+D4AB;D4AB;1111 116F 11BE;D4AB;1111 116F 11BE; # (풫; 풫; 풫; 풫; 풫; ) HANGUL SYLLABLE PWEOC
+D4AC;D4AC;1111 116F 11BF;D4AC;1111 116F 11BF; # (풬; 풬; 풬; 풬; 풬; ) HANGUL SYLLABLE PWEOK
+D4AD;D4AD;1111 116F 11C0;D4AD;1111 116F 11C0; # (풭; 풭; 풭; 풭; 풭; ) HANGUL SYLLABLE PWEOT
+D4AE;D4AE;1111 116F 11C1;D4AE;1111 116F 11C1; # (풮; 풮; 풮; 풮; 풮; ) HANGUL SYLLABLE PWEOP
+D4AF;D4AF;1111 116F 11C2;D4AF;1111 116F 11C2; # (풯; 풯; 풯; 풯; 풯; ) HANGUL SYLLABLE PWEOH
+D4B0;D4B0;1111 1170;D4B0;1111 1170; # (풰; 풰; 풰; 풰; 풰; ) HANGUL SYLLABLE PWE
+D4B1;D4B1;1111 1170 11A8;D4B1;1111 1170 11A8; # (풱; 풱; 풱; 풱; 풱; ) HANGUL SYLLABLE PWEG
+D4B2;D4B2;1111 1170 11A9;D4B2;1111 1170 11A9; # (풲; 풲; 풲; 풲; 풲; ) HANGUL SYLLABLE PWEGG
+D4B3;D4B3;1111 1170 11AA;D4B3;1111 1170 11AA; # (풳; 풳; 풳; 풳; 풳; ) HANGUL SYLLABLE PWEGS
+D4B4;D4B4;1111 1170 11AB;D4B4;1111 1170 11AB; # (풴; 풴; 풴; 풴; 풴; ) HANGUL SYLLABLE PWEN
+D4B5;D4B5;1111 1170 11AC;D4B5;1111 1170 11AC; # (풵; 풵; 풵; 풵; 풵; ) HANGUL SYLLABLE PWENJ
+D4B6;D4B6;1111 1170 11AD;D4B6;1111 1170 11AD; # (풶; 풶; 풶; 풶; 풶; ) HANGUL SYLLABLE PWENH
+D4B7;D4B7;1111 1170 11AE;D4B7;1111 1170 11AE; # (풷; 풷; 풷; 풷; 풷; ) HANGUL SYLLABLE PWED
+D4B8;D4B8;1111 1170 11AF;D4B8;1111 1170 11AF; # (풸; 풸; 풸; 풸; 풸; ) HANGUL SYLLABLE PWEL
+D4B9;D4B9;1111 1170 11B0;D4B9;1111 1170 11B0; # (풹; 풹; 풹; 풹; 풹; ) HANGUL SYLLABLE PWELG
+D4BA;D4BA;1111 1170 11B1;D4BA;1111 1170 11B1; # (풺; 풺; 풺; 풺; 풺; ) HANGUL SYLLABLE PWELM
+D4BB;D4BB;1111 1170 11B2;D4BB;1111 1170 11B2; # (풻; 풻; 풻; 풻; 풻; ) HANGUL SYLLABLE PWELB
+D4BC;D4BC;1111 1170 11B3;D4BC;1111 1170 11B3; # (풼; 풼; 풼; 풼; 풼; ) HANGUL SYLLABLE PWELS
+D4BD;D4BD;1111 1170 11B4;D4BD;1111 1170 11B4; # (풽; 풽; 풽; 풽; 풽; ) HANGUL SYLLABLE PWELT
+D4BE;D4BE;1111 1170 11B5;D4BE;1111 1170 11B5; # (풾; 풾; 풾; 풾; 풾; ) HANGUL SYLLABLE PWELP
+D4BF;D4BF;1111 1170 11B6;D4BF;1111 1170 11B6; # (풿; 풿; 풿; 풿; 풿; ) HANGUL SYLLABLE PWELH
+D4C0;D4C0;1111 1170 11B7;D4C0;1111 1170 11B7; # (퓀; 퓀; 퓀; 퓀; 퓀; ) HANGUL SYLLABLE PWEM
+D4C1;D4C1;1111 1170 11B8;D4C1;1111 1170 11B8; # (퓁; 퓁; 퓁; 퓁; 퓁; ) HANGUL SYLLABLE PWEB
+D4C2;D4C2;1111 1170 11B9;D4C2;1111 1170 11B9; # (퓂; 퓂; 퓂; 퓂; 퓂; ) HANGUL SYLLABLE PWEBS
+D4C3;D4C3;1111 1170 11BA;D4C3;1111 1170 11BA; # (퓃; 퓃; 퓃; 퓃; 퓃; ) HANGUL SYLLABLE PWES
+D4C4;D4C4;1111 1170 11BB;D4C4;1111 1170 11BB; # (퓄; 퓄; 퓄; 퓄; 퓄; ) HANGUL SYLLABLE PWESS
+D4C5;D4C5;1111 1170 11BC;D4C5;1111 1170 11BC; # (퓅; 퓅; 퓅; 퓅; 퓅; ) HANGUL SYLLABLE PWENG
+D4C6;D4C6;1111 1170 11BD;D4C6;1111 1170 11BD; # (퓆; 퓆; 퓆; 퓆; 퓆; ) HANGUL SYLLABLE PWEJ
+D4C7;D4C7;1111 1170 11BE;D4C7;1111 1170 11BE; # (퓇; 퓇; 퓇; 퓇; 퓇; ) HANGUL SYLLABLE PWEC
+D4C8;D4C8;1111 1170 11BF;D4C8;1111 1170 11BF; # (퓈; 퓈; 퓈; 퓈; 퓈; ) HANGUL SYLLABLE PWEK
+D4C9;D4C9;1111 1170 11C0;D4C9;1111 1170 11C0; # (퓉; 퓉; 퓉; 퓉; 퓉; ) HANGUL SYLLABLE PWET
+D4CA;D4CA;1111 1170 11C1;D4CA;1111 1170 11C1; # (퓊; 퓊; 퓊; 퓊; 퓊; ) HANGUL SYLLABLE PWEP
+D4CB;D4CB;1111 1170 11C2;D4CB;1111 1170 11C2; # (퓋; 퓋; 퓋; 퓋; 퓋; ) HANGUL SYLLABLE PWEH
+D4CC;D4CC;1111 1171;D4CC;1111 1171; # (퓌; 퓌; 퓌; 퓌; 퓌; ) HANGUL SYLLABLE PWI
+D4CD;D4CD;1111 1171 11A8;D4CD;1111 1171 11A8; # (퓍; 퓍; 퓍; 퓍; 퓍; ) HANGUL SYLLABLE PWIG
+D4CE;D4CE;1111 1171 11A9;D4CE;1111 1171 11A9; # (퓎; 퓎; 퓎; 퓎; 퓎; ) HANGUL SYLLABLE PWIGG
+D4CF;D4CF;1111 1171 11AA;D4CF;1111 1171 11AA; # (퓏; 퓏; 퓏; 퓏; 퓏; ) HANGUL SYLLABLE PWIGS
+D4D0;D4D0;1111 1171 11AB;D4D0;1111 1171 11AB; # (퓐; 퓐; 퓐; 퓐; 퓐; ) HANGUL SYLLABLE PWIN
+D4D1;D4D1;1111 1171 11AC;D4D1;1111 1171 11AC; # (퓑; 퓑; 퓑; 퓑; 퓑; ) HANGUL SYLLABLE PWINJ
+D4D2;D4D2;1111 1171 11AD;D4D2;1111 1171 11AD; # (퓒; 퓒; 퓒; 퓒; 퓒; ) HANGUL SYLLABLE PWINH
+D4D3;D4D3;1111 1171 11AE;D4D3;1111 1171 11AE; # (퓓; 퓓; 퓓; 퓓; 퓓; ) HANGUL SYLLABLE PWID
+D4D4;D4D4;1111 1171 11AF;D4D4;1111 1171 11AF; # (퓔; 퓔; 퓔; 퓔; 퓔; ) HANGUL SYLLABLE PWIL
+D4D5;D4D5;1111 1171 11B0;D4D5;1111 1171 11B0; # (퓕; 퓕; 퓕; 퓕; 퓕; ) HANGUL SYLLABLE PWILG
+D4D6;D4D6;1111 1171 11B1;D4D6;1111 1171 11B1; # (퓖; 퓖; 퓖; 퓖; 퓖; ) HANGUL SYLLABLE PWILM
+D4D7;D4D7;1111 1171 11B2;D4D7;1111 1171 11B2; # (퓗; 퓗; 퓗; 퓗; 퓗; ) HANGUL SYLLABLE PWILB
+D4D8;D4D8;1111 1171 11B3;D4D8;1111 1171 11B3; # (퓘; 퓘; 퓘; 퓘; 퓘; ) HANGUL SYLLABLE PWILS
+D4D9;D4D9;1111 1171 11B4;D4D9;1111 1171 11B4; # (퓙; 퓙; 퓙; 퓙; 퓙; ) HANGUL SYLLABLE PWILT
+D4DA;D4DA;1111 1171 11B5;D4DA;1111 1171 11B5; # (퓚; 퓚; 퓚; 퓚; 퓚; ) HANGUL SYLLABLE PWILP
+D4DB;D4DB;1111 1171 11B6;D4DB;1111 1171 11B6; # (퓛; 퓛; 퓛; 퓛; 퓛; ) HANGUL SYLLABLE PWILH
+D4DC;D4DC;1111 1171 11B7;D4DC;1111 1171 11B7; # (퓜; 퓜; 퓜; 퓜; 퓜; ) HANGUL SYLLABLE PWIM
+D4DD;D4DD;1111 1171 11B8;D4DD;1111 1171 11B8; # (퓝; 퓝; 퓝; 퓝; 퓝; ) HANGUL SYLLABLE PWIB
+D4DE;D4DE;1111 1171 11B9;D4DE;1111 1171 11B9; # (퓞; 퓞; 퓞; 퓞; 퓞; ) HANGUL SYLLABLE PWIBS
+D4DF;D4DF;1111 1171 11BA;D4DF;1111 1171 11BA; # (퓟; 퓟; 퓟; 퓟; 퓟; ) HANGUL SYLLABLE PWIS
+D4E0;D4E0;1111 1171 11BB;D4E0;1111 1171 11BB; # (퓠; 퓠; 퓠; 퓠; 퓠; ) HANGUL SYLLABLE PWISS
+D4E1;D4E1;1111 1171 11BC;D4E1;1111 1171 11BC; # (퓡; 퓡; 퓡; 퓡; 퓡; ) HANGUL SYLLABLE PWING
+D4E2;D4E2;1111 1171 11BD;D4E2;1111 1171 11BD; # (퓢; 퓢; 퓢; 퓢; 퓢; ) HANGUL SYLLABLE PWIJ
+D4E3;D4E3;1111 1171 11BE;D4E3;1111 1171 11BE; # (퓣; 퓣; 퓣; 퓣; 퓣; ) HANGUL SYLLABLE PWIC
+D4E4;D4E4;1111 1171 11BF;D4E4;1111 1171 11BF; # (퓤; 퓤; 퓤; 퓤; 퓤; ) HANGUL SYLLABLE PWIK
+D4E5;D4E5;1111 1171 11C0;D4E5;1111 1171 11C0; # (퓥; 퓥; 퓥; 퓥; 퓥; ) HANGUL SYLLABLE PWIT
+D4E6;D4E6;1111 1171 11C1;D4E6;1111 1171 11C1; # (퓦; 퓦; 퓦; 퓦; 퓦; ) HANGUL SYLLABLE PWIP
+D4E7;D4E7;1111 1171 11C2;D4E7;1111 1171 11C2; # (퓧; 퓧; 퓧; 퓧; 퓧; ) HANGUL SYLLABLE PWIH
+D4E8;D4E8;1111 1172;D4E8;1111 1172; # (퓨; 퓨; 퓨; 퓨; 퓨; ) HANGUL SYLLABLE PYU
+D4E9;D4E9;1111 1172 11A8;D4E9;1111 1172 11A8; # (퓩; 퓩; 퓩; 퓩; 퓩; ) HANGUL SYLLABLE PYUG
+D4EA;D4EA;1111 1172 11A9;D4EA;1111 1172 11A9; # (퓪; 퓪; 퓪; 퓪; 퓪; ) HANGUL SYLLABLE PYUGG
+D4EB;D4EB;1111 1172 11AA;D4EB;1111 1172 11AA; # (퓫; 퓫; 퓫; 퓫; 퓫; ) HANGUL SYLLABLE PYUGS
+D4EC;D4EC;1111 1172 11AB;D4EC;1111 1172 11AB; # (퓬; 퓬; 퓬; 퓬; 퓬; ) HANGUL SYLLABLE PYUN
+D4ED;D4ED;1111 1172 11AC;D4ED;1111 1172 11AC; # (퓭; 퓭; 퓭; 퓭; 퓭; ) HANGUL SYLLABLE PYUNJ
+D4EE;D4EE;1111 1172 11AD;D4EE;1111 1172 11AD; # (퓮; 퓮; 퓮; 퓮; 퓮; ) HANGUL SYLLABLE PYUNH
+D4EF;D4EF;1111 1172 11AE;D4EF;1111 1172 11AE; # (퓯; 퓯; 퓯; 퓯; 퓯; ) HANGUL SYLLABLE PYUD
+D4F0;D4F0;1111 1172 11AF;D4F0;1111 1172 11AF; # (퓰; 퓰; 퓰; 퓰; 퓰; ) HANGUL SYLLABLE PYUL
+D4F1;D4F1;1111 1172 11B0;D4F1;1111 1172 11B0; # (퓱; 퓱; 퓱; 퓱; 퓱; ) HANGUL SYLLABLE PYULG
+D4F2;D4F2;1111 1172 11B1;D4F2;1111 1172 11B1; # (퓲; 퓲; 퓲; 퓲; 퓲; ) HANGUL SYLLABLE PYULM
+D4F3;D4F3;1111 1172 11B2;D4F3;1111 1172 11B2; # (퓳; 퓳; 퓳; 퓳; 퓳; ) HANGUL SYLLABLE PYULB
+D4F4;D4F4;1111 1172 11B3;D4F4;1111 1172 11B3; # (퓴; 퓴; 퓴; 퓴; 퓴; ) HANGUL SYLLABLE PYULS
+D4F5;D4F5;1111 1172 11B4;D4F5;1111 1172 11B4; # (퓵; 퓵; 퓵; 퓵; 퓵; ) HANGUL SYLLABLE PYULT
+D4F6;D4F6;1111 1172 11B5;D4F6;1111 1172 11B5; # (퓶; 퓶; 퓶; 퓶; 퓶; ) HANGUL SYLLABLE PYULP
+D4F7;D4F7;1111 1172 11B6;D4F7;1111 1172 11B6; # (퓷; 퓷; 퓷; 퓷; 퓷; ) HANGUL SYLLABLE PYULH
+D4F8;D4F8;1111 1172 11B7;D4F8;1111 1172 11B7; # (퓸; 퓸; 퓸; 퓸; 퓸; ) HANGUL SYLLABLE PYUM
+D4F9;D4F9;1111 1172 11B8;D4F9;1111 1172 11B8; # (퓹; 퓹; 퓹; 퓹; 퓹; ) HANGUL SYLLABLE PYUB
+D4FA;D4FA;1111 1172 11B9;D4FA;1111 1172 11B9; # (퓺; 퓺; 퓺; 퓺; 퓺; ) HANGUL SYLLABLE PYUBS
+D4FB;D4FB;1111 1172 11BA;D4FB;1111 1172 11BA; # (퓻; 퓻; 퓻; 퓻; 퓻; ) HANGUL SYLLABLE PYUS
+D4FC;D4FC;1111 1172 11BB;D4FC;1111 1172 11BB; # (퓼; 퓼; 퓼; 퓼; 퓼; ) HANGUL SYLLABLE PYUSS
+D4FD;D4FD;1111 1172 11BC;D4FD;1111 1172 11BC; # (퓽; 퓽; 퓽; 퓽; 퓽; ) HANGUL SYLLABLE PYUNG
+D4FE;D4FE;1111 1172 11BD;D4FE;1111 1172 11BD; # (퓾; 퓾; 퓾; 퓾; 퓾; ) HANGUL SYLLABLE PYUJ
+D4FF;D4FF;1111 1172 11BE;D4FF;1111 1172 11BE; # (퓿; 퓿; 퓿; 퓿; 퓿; ) HANGUL SYLLABLE PYUC
+D500;D500;1111 1172 11BF;D500;1111 1172 11BF; # (픀; 픀; 픀; 픀; 픀; ) HANGUL SYLLABLE PYUK
+D501;D501;1111 1172 11C0;D501;1111 1172 11C0; # (픁; 픁; 픁; 픁; 픁; ) HANGUL SYLLABLE PYUT
+D502;D502;1111 1172 11C1;D502;1111 1172 11C1; # (픂; 픂; 픂; 픂; 픂; ) HANGUL SYLLABLE PYUP
+D503;D503;1111 1172 11C2;D503;1111 1172 11C2; # (픃; 픃; 픃; 픃; 픃; ) HANGUL SYLLABLE PYUH
+D504;D504;1111 1173;D504;1111 1173; # (프; 프; 프; 프; 프; ) HANGUL SYLLABLE PEU
+D505;D505;1111 1173 11A8;D505;1111 1173 11A8; # (픅; 픅; 픅; 픅; 픅; ) HANGUL SYLLABLE PEUG
+D506;D506;1111 1173 11A9;D506;1111 1173 11A9; # (픆; 픆; 픆; 픆; 픆; ) HANGUL SYLLABLE PEUGG
+D507;D507;1111 1173 11AA;D507;1111 1173 11AA; # (픇; 픇; 픇; 픇; 픇; ) HANGUL SYLLABLE PEUGS
+D508;D508;1111 1173 11AB;D508;1111 1173 11AB; # (픈; 픈; 픈; 픈; 픈; ) HANGUL SYLLABLE PEUN
+D509;D509;1111 1173 11AC;D509;1111 1173 11AC; # (픉; 픉; 픉; 픉; 픉; ) HANGUL SYLLABLE PEUNJ
+D50A;D50A;1111 1173 11AD;D50A;1111 1173 11AD; # (픊; 픊; 픊; 픊; 픊; ) HANGUL SYLLABLE PEUNH
+D50B;D50B;1111 1173 11AE;D50B;1111 1173 11AE; # (픋; 픋; 픋; 픋; 픋; ) HANGUL SYLLABLE PEUD
+D50C;D50C;1111 1173 11AF;D50C;1111 1173 11AF; # (플; 플; 플; 플; 플; ) HANGUL SYLLABLE PEUL
+D50D;D50D;1111 1173 11B0;D50D;1111 1173 11B0; # (픍; 픍; 픍; 픍; 픍; ) HANGUL SYLLABLE PEULG
+D50E;D50E;1111 1173 11B1;D50E;1111 1173 11B1; # (픎; 픎; 픎; 픎; 픎; ) HANGUL SYLLABLE PEULM
+D50F;D50F;1111 1173 11B2;D50F;1111 1173 11B2; # (픏; 픏; 픏; 픏; 픏; ) HANGUL SYLLABLE PEULB
+D510;D510;1111 1173 11B3;D510;1111 1173 11B3; # (픐; 픐; 픐; 픐; 픐; ) HANGUL SYLLABLE PEULS
+D511;D511;1111 1173 11B4;D511;1111 1173 11B4; # (픑; 픑; 픑; 픑; 픑; ) HANGUL SYLLABLE PEULT
+D512;D512;1111 1173 11B5;D512;1111 1173 11B5; # (픒; 픒; 픒; 픒; 픒; ) HANGUL SYLLABLE PEULP
+D513;D513;1111 1173 11B6;D513;1111 1173 11B6; # (픓; 픓; 픓; 픓; 픓; ) HANGUL SYLLABLE PEULH
+D514;D514;1111 1173 11B7;D514;1111 1173 11B7; # (픔; 픔; 픔; 픔; 픔; ) HANGUL SYLLABLE PEUM
+D515;D515;1111 1173 11B8;D515;1111 1173 11B8; # (픕; 픕; 픕; 픕; 픕; ) HANGUL SYLLABLE PEUB
+D516;D516;1111 1173 11B9;D516;1111 1173 11B9; # (픖; 픖; 픖; 픖; 픖; ) HANGUL SYLLABLE PEUBS
+D517;D517;1111 1173 11BA;D517;1111 1173 11BA; # (픗; 픗; 픗; 픗; 픗; ) HANGUL SYLLABLE PEUS
+D518;D518;1111 1173 11BB;D518;1111 1173 11BB; # (픘; 픘; 픘; 픘; 픘; ) HANGUL SYLLABLE PEUSS
+D519;D519;1111 1173 11BC;D519;1111 1173 11BC; # (픙; 픙; 픙; 픙; 픙; ) HANGUL SYLLABLE PEUNG
+D51A;D51A;1111 1173 11BD;D51A;1111 1173 11BD; # (픚; 픚; 픚; 픚; 픚; ) HANGUL SYLLABLE PEUJ
+D51B;D51B;1111 1173 11BE;D51B;1111 1173 11BE; # (픛; 픛; 픛; 픛; 픛; ) HANGUL SYLLABLE PEUC
+D51C;D51C;1111 1173 11BF;D51C;1111 1173 11BF; # (픜; 픜; 픜; 픜; 픜; ) HANGUL SYLLABLE PEUK
+D51D;D51D;1111 1173 11C0;D51D;1111 1173 11C0; # (픝; 픝; 픝; 픝; 픝; ) HANGUL SYLLABLE PEUT
+D51E;D51E;1111 1173 11C1;D51E;1111 1173 11C1; # (픞; 픞; 픞; 픞; 픞; ) HANGUL SYLLABLE PEUP
+D51F;D51F;1111 1173 11C2;D51F;1111 1173 11C2; # (픟; 픟; 픟; 픟; 픟; ) HANGUL SYLLABLE PEUH
+D520;D520;1111 1174;D520;1111 1174; # (픠; 픠; 픠; 픠; 픠; ) HANGUL SYLLABLE PYI
+D521;D521;1111 1174 11A8;D521;1111 1174 11A8; # (픡; 픡; 픡; 픡; 픡; ) HANGUL SYLLABLE PYIG
+D522;D522;1111 1174 11A9;D522;1111 1174 11A9; # (픢; 픢; 픢; 픢; 픢; ) HANGUL SYLLABLE PYIGG
+D523;D523;1111 1174 11AA;D523;1111 1174 11AA; # (픣; 픣; 픣; 픣; 픣; ) HANGUL SYLLABLE PYIGS
+D524;D524;1111 1174 11AB;D524;1111 1174 11AB; # (픤; 픤; 픤; 픤; 픤; ) HANGUL SYLLABLE PYIN
+D525;D525;1111 1174 11AC;D525;1111 1174 11AC; # (픥; 픥; 픥; 픥; 픥; ) HANGUL SYLLABLE PYINJ
+D526;D526;1111 1174 11AD;D526;1111 1174 11AD; # (픦; 픦; 픦; 픦; 픦; ) HANGUL SYLLABLE PYINH
+D527;D527;1111 1174 11AE;D527;1111 1174 11AE; # (픧; 픧; 픧; 픧; 픧; ) HANGUL SYLLABLE PYID
+D528;D528;1111 1174 11AF;D528;1111 1174 11AF; # (픨; 픨; 픨; 픨; 픨; ) HANGUL SYLLABLE PYIL
+D529;D529;1111 1174 11B0;D529;1111 1174 11B0; # (픩; 픩; 픩; 픩; 픩; ) HANGUL SYLLABLE PYILG
+D52A;D52A;1111 1174 11B1;D52A;1111 1174 11B1; # (픪; 픪; 픪; 픪; 픪; ) HANGUL SYLLABLE PYILM
+D52B;D52B;1111 1174 11B2;D52B;1111 1174 11B2; # (픫; 픫; 픫; 픫; 픫; ) HANGUL SYLLABLE PYILB
+D52C;D52C;1111 1174 11B3;D52C;1111 1174 11B3; # (픬; 픬; 픬; 픬; 픬; ) HANGUL SYLLABLE PYILS
+D52D;D52D;1111 1174 11B4;D52D;1111 1174 11B4; # (픭; 픭; 픭; 픭; 픭; ) HANGUL SYLLABLE PYILT
+D52E;D52E;1111 1174 11B5;D52E;1111 1174 11B5; # (픮; 픮; 픮; 픮; 픮; ) HANGUL SYLLABLE PYILP
+D52F;D52F;1111 1174 11B6;D52F;1111 1174 11B6; # (픯; 픯; 픯; 픯; 픯; ) HANGUL SYLLABLE PYILH
+D530;D530;1111 1174 11B7;D530;1111 1174 11B7; # (픰; 픰; 픰; 픰; 픰; ) HANGUL SYLLABLE PYIM
+D531;D531;1111 1174 11B8;D531;1111 1174 11B8; # (픱; 픱; 픱; 픱; 픱; ) HANGUL SYLLABLE PYIB
+D532;D532;1111 1174 11B9;D532;1111 1174 11B9; # (픲; 픲; 픲; 픲; 픲; ) HANGUL SYLLABLE PYIBS
+D533;D533;1111 1174 11BA;D533;1111 1174 11BA; # (픳; 픳; 픳; 픳; 픳; ) HANGUL SYLLABLE PYIS
+D534;D534;1111 1174 11BB;D534;1111 1174 11BB; # (픴; 픴; 픴; 픴; 픴; ) HANGUL SYLLABLE PYISS
+D535;D535;1111 1174 11BC;D535;1111 1174 11BC; # (픵; 픵; 픵; 픵; 픵; ) HANGUL SYLLABLE PYING
+D536;D536;1111 1174 11BD;D536;1111 1174 11BD; # (픶; 픶; 픶; 픶; 픶; ) HANGUL SYLLABLE PYIJ
+D537;D537;1111 1174 11BE;D537;1111 1174 11BE; # (픷; 픷; 픷; 픷; 픷; ) HANGUL SYLLABLE PYIC
+D538;D538;1111 1174 11BF;D538;1111 1174 11BF; # (픸; 픸; 픸; 픸; 픸; ) HANGUL SYLLABLE PYIK
+D539;D539;1111 1174 11C0;D539;1111 1174 11C0; # (픹; 픹; 픹; 픹; 픹; ) HANGUL SYLLABLE PYIT
+D53A;D53A;1111 1174 11C1;D53A;1111 1174 11C1; # (픺; 픺; 픺; 픺; 픺; ) HANGUL SYLLABLE PYIP
+D53B;D53B;1111 1174 11C2;D53B;1111 1174 11C2; # (픻; 픻; 픻; 픻; 픻; ) HANGUL SYLLABLE PYIH
+D53C;D53C;1111 1175;D53C;1111 1175; # (피; 피; 피; 피; 피; ) HANGUL SYLLABLE PI
+D53D;D53D;1111 1175 11A8;D53D;1111 1175 11A8; # (픽; 픽; 픽; 픽; 픽; ) HANGUL SYLLABLE PIG
+D53E;D53E;1111 1175 11A9;D53E;1111 1175 11A9; # (픾; 픾; 픾; 픾; 픾; ) HANGUL SYLLABLE PIGG
+D53F;D53F;1111 1175 11AA;D53F;1111 1175 11AA; # (픿; 픿; 픿; 픿; 픿; ) HANGUL SYLLABLE PIGS
+D540;D540;1111 1175 11AB;D540;1111 1175 11AB; # (핀; 핀; 핀; 핀; 핀; ) HANGUL SYLLABLE PIN
+D541;D541;1111 1175 11AC;D541;1111 1175 11AC; # (핁; 핁; 핁; 핁; 핁; ) HANGUL SYLLABLE PINJ
+D542;D542;1111 1175 11AD;D542;1111 1175 11AD; # (핂; 핂; 핂; 핂; 핂; ) HANGUL SYLLABLE PINH
+D543;D543;1111 1175 11AE;D543;1111 1175 11AE; # (핃; 핃; 핃; 핃; 핃; ) HANGUL SYLLABLE PID
+D544;D544;1111 1175 11AF;D544;1111 1175 11AF; # (필; 필; 필; 필; 필; ) HANGUL SYLLABLE PIL
+D545;D545;1111 1175 11B0;D545;1111 1175 11B0; # (핅; 핅; 핅; 핅; 핅; ) HANGUL SYLLABLE PILG
+D546;D546;1111 1175 11B1;D546;1111 1175 11B1; # (핆; 핆; 핆; 핆; 핆; ) HANGUL SYLLABLE PILM
+D547;D547;1111 1175 11B2;D547;1111 1175 11B2; # (핇; 핇; 핇; 핇; 핇; ) HANGUL SYLLABLE PILB
+D548;D548;1111 1175 11B3;D548;1111 1175 11B3; # (핈; 핈; 핈; 핈; 핈; ) HANGUL SYLLABLE PILS
+D549;D549;1111 1175 11B4;D549;1111 1175 11B4; # (핉; 핉; 핉; 핉; 핉; ) HANGUL SYLLABLE PILT
+D54A;D54A;1111 1175 11B5;D54A;1111 1175 11B5; # (핊; 핊; 핊; 핊; 핊; ) HANGUL SYLLABLE PILP
+D54B;D54B;1111 1175 11B6;D54B;1111 1175 11B6; # (핋; 핋; 핋; 핋; 핋; ) HANGUL SYLLABLE PILH
+D54C;D54C;1111 1175 11B7;D54C;1111 1175 11B7; # (핌; 핌; 핌; 핌; 핌; ) HANGUL SYLLABLE PIM
+D54D;D54D;1111 1175 11B8;D54D;1111 1175 11B8; # (핍; 핍; 핍; 핍; 핍; ) HANGUL SYLLABLE PIB
+D54E;D54E;1111 1175 11B9;D54E;1111 1175 11B9; # (핎; 핎; 핎; 핎; 핎; ) HANGUL SYLLABLE PIBS
+D54F;D54F;1111 1175 11BA;D54F;1111 1175 11BA; # (핏; 핏; 핏; 핏; 핏; ) HANGUL SYLLABLE PIS
+D550;D550;1111 1175 11BB;D550;1111 1175 11BB; # (핐; 핐; 핐; 핐; 핐; ) HANGUL SYLLABLE PISS
+D551;D551;1111 1175 11BC;D551;1111 1175 11BC; # (핑; 핑; 핑; 핑; 핑; ) HANGUL SYLLABLE PING
+D552;D552;1111 1175 11BD;D552;1111 1175 11BD; # (핒; 핒; 핒; 핒; 핒; ) HANGUL SYLLABLE PIJ
+D553;D553;1111 1175 11BE;D553;1111 1175 11BE; # (핓; 핓; 핓; 핓; 핓; ) HANGUL SYLLABLE PIC
+D554;D554;1111 1175 11BF;D554;1111 1175 11BF; # (핔; 핔; 핔; 핔; 핔; ) HANGUL SYLLABLE PIK
+D555;D555;1111 1175 11C0;D555;1111 1175 11C0; # (핕; 핕; 핕; 핕; 핕; ) HANGUL SYLLABLE PIT
+D556;D556;1111 1175 11C1;D556;1111 1175 11C1; # (핖; 핖; 핖; 핖; 핖; ) HANGUL SYLLABLE PIP
+D557;D557;1111 1175 11C2;D557;1111 1175 11C2; # (핗; 핗; 핗; 핗; 핗; ) HANGUL SYLLABLE PIH
+D558;D558;1112 1161;D558;1112 1161; # (하; 하; 하; 하; 하; ) HANGUL SYLLABLE HA
+D559;D559;1112 1161 11A8;D559;1112 1161 11A8; # (학; 학; 학; 학; 학; ) HANGUL SYLLABLE HAG
+D55A;D55A;1112 1161 11A9;D55A;1112 1161 11A9; # (핚; 핚; 핚; 핚; 핚; ) HANGUL SYLLABLE HAGG
+D55B;D55B;1112 1161 11AA;D55B;1112 1161 11AA; # (핛; 핛; 핛; 핛; 핛; ) HANGUL SYLLABLE HAGS
+D55C;D55C;1112 1161 11AB;D55C;1112 1161 11AB; # (한; 한; 한; 한; 한; ) HANGUL SYLLABLE HAN
+D55D;D55D;1112 1161 11AC;D55D;1112 1161 11AC; # (핝; 핝; 핝; 핝; 핝; ) HANGUL SYLLABLE HANJ
+D55E;D55E;1112 1161 11AD;D55E;1112 1161 11AD; # (핞; 핞; 핞; 핞; 핞; ) HANGUL SYLLABLE HANH
+D55F;D55F;1112 1161 11AE;D55F;1112 1161 11AE; # (핟; 핟; 핟; 핟; 핟; ) HANGUL SYLLABLE HAD
+D560;D560;1112 1161 11AF;D560;1112 1161 11AF; # (할; 할; 할; 할; 할; ) HANGUL SYLLABLE HAL
+D561;D561;1112 1161 11B0;D561;1112 1161 11B0; # (핡; 핡; 핡; 핡; 핡; ) HANGUL SYLLABLE HALG
+D562;D562;1112 1161 11B1;D562;1112 1161 11B1; # (핢; 핢; 핢; 핢; 핢; ) HANGUL SYLLABLE HALM
+D563;D563;1112 1161 11B2;D563;1112 1161 11B2; # (핣; 핣; 핣; 핣; 핣; ) HANGUL SYLLABLE HALB
+D564;D564;1112 1161 11B3;D564;1112 1161 11B3; # (핤; 핤; 핤; 핤; 핤; ) HANGUL SYLLABLE HALS
+D565;D565;1112 1161 11B4;D565;1112 1161 11B4; # (핥; 핥; 핥; 핥; 핥; ) HANGUL SYLLABLE HALT
+D566;D566;1112 1161 11B5;D566;1112 1161 11B5; # (핦; 핦; 핦; 핦; 핦; ) HANGUL SYLLABLE HALP
+D567;D567;1112 1161 11B6;D567;1112 1161 11B6; # (핧; 핧; 핧; 핧; 핧; ) HANGUL SYLLABLE HALH
+D568;D568;1112 1161 11B7;D568;1112 1161 11B7; # (함; 함; 함; 함; 함; ) HANGUL SYLLABLE HAM
+D569;D569;1112 1161 11B8;D569;1112 1161 11B8; # (합; 합; 합; 합; 합; ) HANGUL SYLLABLE HAB
+D56A;D56A;1112 1161 11B9;D56A;1112 1161 11B9; # (핪; 핪; 핪; 핪; 핪; ) HANGUL SYLLABLE HABS
+D56B;D56B;1112 1161 11BA;D56B;1112 1161 11BA; # (핫; 핫; 핫; 핫; 핫; ) HANGUL SYLLABLE HAS
+D56C;D56C;1112 1161 11BB;D56C;1112 1161 11BB; # (핬; 핬; 핬; 핬; 핬; ) HANGUL SYLLABLE HASS
+D56D;D56D;1112 1161 11BC;D56D;1112 1161 11BC; # (항; 항; 항; 항; 항; ) HANGUL SYLLABLE HANG
+D56E;D56E;1112 1161 11BD;D56E;1112 1161 11BD; # (핮; 핮; 핮; 핮; 핮; ) HANGUL SYLLABLE HAJ
+D56F;D56F;1112 1161 11BE;D56F;1112 1161 11BE; # (핯; 핯; 핯; 핯; 핯; ) HANGUL SYLLABLE HAC
+D570;D570;1112 1161 11BF;D570;1112 1161 11BF; # (핰; 핰; 핰; 핰; 핰; ) HANGUL SYLLABLE HAK
+D571;D571;1112 1161 11C0;D571;1112 1161 11C0; # (핱; 핱; 핱; 핱; 핱; ) HANGUL SYLLABLE HAT
+D572;D572;1112 1161 11C1;D572;1112 1161 11C1; # (핲; 핲; 핲; 핲; 핲; ) HANGUL SYLLABLE HAP
+D573;D573;1112 1161 11C2;D573;1112 1161 11C2; # (핳; 핳; 핳; 핳; 핳; ) HANGUL SYLLABLE HAH
+D574;D574;1112 1162;D574;1112 1162; # (해; 해; 해; 해; 해; ) HANGUL SYLLABLE HAE
+D575;D575;1112 1162 11A8;D575;1112 1162 11A8; # (핵; 핵; 핵; 핵; 핵; ) HANGUL SYLLABLE HAEG
+D576;D576;1112 1162 11A9;D576;1112 1162 11A9; # (핶; 핶; 핶; 핶; 핶; ) HANGUL SYLLABLE HAEGG
+D577;D577;1112 1162 11AA;D577;1112 1162 11AA; # (핷; 핷; 핷; 핷; 핷; ) HANGUL SYLLABLE HAEGS
+D578;D578;1112 1162 11AB;D578;1112 1162 11AB; # (핸; 핸; 핸; 핸; 핸; ) HANGUL SYLLABLE HAEN
+D579;D579;1112 1162 11AC;D579;1112 1162 11AC; # (핹; 핹; 핹; 핹; 핹; ) HANGUL SYLLABLE HAENJ
+D57A;D57A;1112 1162 11AD;D57A;1112 1162 11AD; # (핺; 핺; 핺; 핺; 핺; ) HANGUL SYLLABLE HAENH
+D57B;D57B;1112 1162 11AE;D57B;1112 1162 11AE; # (핻; 핻; 핻; 핻; 핻; ) HANGUL SYLLABLE HAED
+D57C;D57C;1112 1162 11AF;D57C;1112 1162 11AF; # (핼; 핼; 핼; 핼; 핼; ) HANGUL SYLLABLE HAEL
+D57D;D57D;1112 1162 11B0;D57D;1112 1162 11B0; # (핽; 핽; 핽; 핽; 핽; ) HANGUL SYLLABLE HAELG
+D57E;D57E;1112 1162 11B1;D57E;1112 1162 11B1; # (핾; 핾; 핾; 핾; 핾; ) HANGUL SYLLABLE HAELM
+D57F;D57F;1112 1162 11B2;D57F;1112 1162 11B2; # (핿; 핿; 핿; 핿; 핿; ) HANGUL SYLLABLE HAELB
+D580;D580;1112 1162 11B3;D580;1112 1162 11B3; # (햀; 햀; 햀; 햀; 햀; ) HANGUL SYLLABLE HAELS
+D581;D581;1112 1162 11B4;D581;1112 1162 11B4; # (햁; 햁; 햁; 햁; 햁; ) HANGUL SYLLABLE HAELT
+D582;D582;1112 1162 11B5;D582;1112 1162 11B5; # (햂; 햂; 햂; 햂; 햂; ) HANGUL SYLLABLE HAELP
+D583;D583;1112 1162 11B6;D583;1112 1162 11B6; # (햃; 햃; 햃; 햃; 햃; ) HANGUL SYLLABLE HAELH
+D584;D584;1112 1162 11B7;D584;1112 1162 11B7; # (햄; 햄; 햄; 햄; 햄; ) HANGUL SYLLABLE HAEM
+D585;D585;1112 1162 11B8;D585;1112 1162 11B8; # (햅; 햅; 햅; 햅; 햅; ) HANGUL SYLLABLE HAEB
+D586;D586;1112 1162 11B9;D586;1112 1162 11B9; # (햆; 햆; 햆; 햆; 햆; ) HANGUL SYLLABLE HAEBS
+D587;D587;1112 1162 11BA;D587;1112 1162 11BA; # (햇; 햇; 햇; 햇; 햇; ) HANGUL SYLLABLE HAES
+D588;D588;1112 1162 11BB;D588;1112 1162 11BB; # (했; 했; 했; 했; 했; ) HANGUL SYLLABLE HAESS
+D589;D589;1112 1162 11BC;D589;1112 1162 11BC; # (행; 행; 행; 행; 행; ) HANGUL SYLLABLE HAENG
+D58A;D58A;1112 1162 11BD;D58A;1112 1162 11BD; # (햊; 햊; 햊; 햊; 햊; ) HANGUL SYLLABLE HAEJ
+D58B;D58B;1112 1162 11BE;D58B;1112 1162 11BE; # (햋; 햋; 햋; 햋; 햋; ) HANGUL SYLLABLE HAEC
+D58C;D58C;1112 1162 11BF;D58C;1112 1162 11BF; # (햌; 햌; 햌; 햌; 햌; ) HANGUL SYLLABLE HAEK
+D58D;D58D;1112 1162 11C0;D58D;1112 1162 11C0; # (햍; 햍; 햍; 햍; 햍; ) HANGUL SYLLABLE HAET
+D58E;D58E;1112 1162 11C1;D58E;1112 1162 11C1; # (햎; 햎; 햎; 햎; 햎; ) HANGUL SYLLABLE HAEP
+D58F;D58F;1112 1162 11C2;D58F;1112 1162 11C2; # (햏; 햏; 햏; 햏; 햏; ) HANGUL SYLLABLE HAEH
+D590;D590;1112 1163;D590;1112 1163; # (햐; 햐; 햐; 햐; 햐; ) HANGUL SYLLABLE HYA
+D591;D591;1112 1163 11A8;D591;1112 1163 11A8; # (햑; 햑; 햑; 햑; 햑; ) HANGUL SYLLABLE HYAG
+D592;D592;1112 1163 11A9;D592;1112 1163 11A9; # (햒; 햒; 햒; 햒; 햒; ) HANGUL SYLLABLE HYAGG
+D593;D593;1112 1163 11AA;D593;1112 1163 11AA; # (햓; 햓; 햓; 햓; 햓; ) HANGUL SYLLABLE HYAGS
+D594;D594;1112 1163 11AB;D594;1112 1163 11AB; # (햔; 햔; 햔; 햔; 햔; ) HANGUL SYLLABLE HYAN
+D595;D595;1112 1163 11AC;D595;1112 1163 11AC; # (햕; 햕; 햕; 햕; 햕; ) HANGUL SYLLABLE HYANJ
+D596;D596;1112 1163 11AD;D596;1112 1163 11AD; # (햖; 햖; 햖; 햖; 햖; ) HANGUL SYLLABLE HYANH
+D597;D597;1112 1163 11AE;D597;1112 1163 11AE; # (햗; 햗; 햗; 햗; 햗; ) HANGUL SYLLABLE HYAD
+D598;D598;1112 1163 11AF;D598;1112 1163 11AF; # (햘; 햘; 햘; 햘; 햘; ) HANGUL SYLLABLE HYAL
+D599;D599;1112 1163 11B0;D599;1112 1163 11B0; # (햙; 햙; 햙; 햙; 햙; ) HANGUL SYLLABLE HYALG
+D59A;D59A;1112 1163 11B1;D59A;1112 1163 11B1; # (햚; 햚; 햚; 햚; 햚; ) HANGUL SYLLABLE HYALM
+D59B;D59B;1112 1163 11B2;D59B;1112 1163 11B2; # (햛; 햛; 햛; 햛; 햛; ) HANGUL SYLLABLE HYALB
+D59C;D59C;1112 1163 11B3;D59C;1112 1163 11B3; # (햜; 햜; 햜; 햜; 햜; ) HANGUL SYLLABLE HYALS
+D59D;D59D;1112 1163 11B4;D59D;1112 1163 11B4; # (햝; 햝; 햝; 햝; 햝; ) HANGUL SYLLABLE HYALT
+D59E;D59E;1112 1163 11B5;D59E;1112 1163 11B5; # (햞; 햞; 햞; 햞; 햞; ) HANGUL SYLLABLE HYALP
+D59F;D59F;1112 1163 11B6;D59F;1112 1163 11B6; # (햟; 햟; 햟; 햟; 햟; ) HANGUL SYLLABLE HYALH
+D5A0;D5A0;1112 1163 11B7;D5A0;1112 1163 11B7; # (햠; 햠; 햠; 햠; 햠; ) HANGUL SYLLABLE HYAM
+D5A1;D5A1;1112 1163 11B8;D5A1;1112 1163 11B8; # (햡; 햡; 햡; 햡; 햡; ) HANGUL SYLLABLE HYAB
+D5A2;D5A2;1112 1163 11B9;D5A2;1112 1163 11B9; # (햢; 햢; 햢; 햢; 햢; ) HANGUL SYLLABLE HYABS
+D5A3;D5A3;1112 1163 11BA;D5A3;1112 1163 11BA; # (햣; 햣; 햣; 햣; 햣; ) HANGUL SYLLABLE HYAS
+D5A4;D5A4;1112 1163 11BB;D5A4;1112 1163 11BB; # (햤; 햤; 햤; 햤; 햤; ) HANGUL SYLLABLE HYASS
+D5A5;D5A5;1112 1163 11BC;D5A5;1112 1163 11BC; # (향; 향; 향; 향; 향; ) HANGUL SYLLABLE HYANG
+D5A6;D5A6;1112 1163 11BD;D5A6;1112 1163 11BD; # (햦; 햦; 햦; 햦; 햦; ) HANGUL SYLLABLE HYAJ
+D5A7;D5A7;1112 1163 11BE;D5A7;1112 1163 11BE; # (햧; 햧; 햧; 햧; 햧; ) HANGUL SYLLABLE HYAC
+D5A8;D5A8;1112 1163 11BF;D5A8;1112 1163 11BF; # (햨; 햨; 햨; 햨; 햨; ) HANGUL SYLLABLE HYAK
+D5A9;D5A9;1112 1163 11C0;D5A9;1112 1163 11C0; # (햩; 햩; 햩; 햩; 햩; ) HANGUL SYLLABLE HYAT
+D5AA;D5AA;1112 1163 11C1;D5AA;1112 1163 11C1; # (햪; 햪; 햪; 햪; 햪; ) HANGUL SYLLABLE HYAP
+D5AB;D5AB;1112 1163 11C2;D5AB;1112 1163 11C2; # (햫; 햫; 햫; 햫; 햫; ) HANGUL SYLLABLE HYAH
+D5AC;D5AC;1112 1164;D5AC;1112 1164; # (햬; 햬; 햬; 햬; 햬; ) HANGUL SYLLABLE HYAE
+D5AD;D5AD;1112 1164 11A8;D5AD;1112 1164 11A8; # (햭; 햭; 햭; 햭; 햭; ) HANGUL SYLLABLE HYAEG
+D5AE;D5AE;1112 1164 11A9;D5AE;1112 1164 11A9; # (햮; 햮; 햮; 햮; 햮; ) HANGUL SYLLABLE HYAEGG
+D5AF;D5AF;1112 1164 11AA;D5AF;1112 1164 11AA; # (햯; 햯; 햯; 햯; 햯; ) HANGUL SYLLABLE HYAEGS
+D5B0;D5B0;1112 1164 11AB;D5B0;1112 1164 11AB; # (햰; 햰; 햰; 햰; 햰; ) HANGUL SYLLABLE HYAEN
+D5B1;D5B1;1112 1164 11AC;D5B1;1112 1164 11AC; # (햱; 햱; 햱; 햱; 햱; ) HANGUL SYLLABLE HYAENJ
+D5B2;D5B2;1112 1164 11AD;D5B2;1112 1164 11AD; # (햲; 햲; 햲; 햲; 햲; ) HANGUL SYLLABLE HYAENH
+D5B3;D5B3;1112 1164 11AE;D5B3;1112 1164 11AE; # (햳; 햳; 햳; 햳; 햳; ) HANGUL SYLLABLE HYAED
+D5B4;D5B4;1112 1164 11AF;D5B4;1112 1164 11AF; # (햴; 햴; 햴; 햴; 햴; ) HANGUL SYLLABLE HYAEL
+D5B5;D5B5;1112 1164 11B0;D5B5;1112 1164 11B0; # (햵; 햵; 햵; 햵; 햵; ) HANGUL SYLLABLE HYAELG
+D5B6;D5B6;1112 1164 11B1;D5B6;1112 1164 11B1; # (햶; 햶; 햶; 햶; 햶; ) HANGUL SYLLABLE HYAELM
+D5B7;D5B7;1112 1164 11B2;D5B7;1112 1164 11B2; # (햷; 햷; 햷; 햷; 햷; ) HANGUL SYLLABLE HYAELB
+D5B8;D5B8;1112 1164 11B3;D5B8;1112 1164 11B3; # (햸; 햸; 햸; 햸; 햸; ) HANGUL SYLLABLE HYAELS
+D5B9;D5B9;1112 1164 11B4;D5B9;1112 1164 11B4; # (햹; 햹; 햹; 햹; 햹; ) HANGUL SYLLABLE HYAELT
+D5BA;D5BA;1112 1164 11B5;D5BA;1112 1164 11B5; # (햺; 햺; 햺; 햺; 햺; ) HANGUL SYLLABLE HYAELP
+D5BB;D5BB;1112 1164 11B6;D5BB;1112 1164 11B6; # (햻; 햻; 햻; 햻; 햻; ) HANGUL SYLLABLE HYAELH
+D5BC;D5BC;1112 1164 11B7;D5BC;1112 1164 11B7; # (햼; 햼; 햼; 햼; 햼; ) HANGUL SYLLABLE HYAEM
+D5BD;D5BD;1112 1164 11B8;D5BD;1112 1164 11B8; # (햽; 햽; 햽; 햽; 햽; ) HANGUL SYLLABLE HYAEB
+D5BE;D5BE;1112 1164 11B9;D5BE;1112 1164 11B9; # (햾; 햾; 햾; 햾; 햾; ) HANGUL SYLLABLE HYAEBS
+D5BF;D5BF;1112 1164 11BA;D5BF;1112 1164 11BA; # (햿; 햿; 햿; 햿; 햿; ) HANGUL SYLLABLE HYAES
+D5C0;D5C0;1112 1164 11BB;D5C0;1112 1164 11BB; # (헀; 헀; 헀; 헀; 헀; ) HANGUL SYLLABLE HYAESS
+D5C1;D5C1;1112 1164 11BC;D5C1;1112 1164 11BC; # (헁; 헁; 헁; 헁; 헁; ) HANGUL SYLLABLE HYAENG
+D5C2;D5C2;1112 1164 11BD;D5C2;1112 1164 11BD; # (헂; 헂; 헂; 헂; 헂; ) HANGUL SYLLABLE HYAEJ
+D5C3;D5C3;1112 1164 11BE;D5C3;1112 1164 11BE; # (헃; 헃; 헃; 헃; 헃; ) HANGUL SYLLABLE HYAEC
+D5C4;D5C4;1112 1164 11BF;D5C4;1112 1164 11BF; # (헄; 헄; 헄; 헄; 헄; ) HANGUL SYLLABLE HYAEK
+D5C5;D5C5;1112 1164 11C0;D5C5;1112 1164 11C0; # (헅; 헅; 헅; 헅; 헅; ) HANGUL SYLLABLE HYAET
+D5C6;D5C6;1112 1164 11C1;D5C6;1112 1164 11C1; # (헆; 헆; 헆; 헆; 헆; ) HANGUL SYLLABLE HYAEP
+D5C7;D5C7;1112 1164 11C2;D5C7;1112 1164 11C2; # (헇; 헇; 헇; 헇; 헇; ) HANGUL SYLLABLE HYAEH
+D5C8;D5C8;1112 1165;D5C8;1112 1165; # (허; 허; 허; 허; 허; ) HANGUL SYLLABLE HEO
+D5C9;D5C9;1112 1165 11A8;D5C9;1112 1165 11A8; # (헉; 헉; 헉; 헉; 헉; ) HANGUL SYLLABLE HEOG
+D5CA;D5CA;1112 1165 11A9;D5CA;1112 1165 11A9; # (헊; 헊; 헊; 헊; 헊; ) HANGUL SYLLABLE HEOGG
+D5CB;D5CB;1112 1165 11AA;D5CB;1112 1165 11AA; # (헋; 헋; 헋; 헋; 헋; ) HANGUL SYLLABLE HEOGS
+D5CC;D5CC;1112 1165 11AB;D5CC;1112 1165 11AB; # (헌; 헌; 헌; 헌; 헌; ) HANGUL SYLLABLE HEON
+D5CD;D5CD;1112 1165 11AC;D5CD;1112 1165 11AC; # (헍; 헍; 헍; 헍; 헍; ) HANGUL SYLLABLE HEONJ
+D5CE;D5CE;1112 1165 11AD;D5CE;1112 1165 11AD; # (헎; 헎; 헎; 헎; 헎; ) HANGUL SYLLABLE HEONH
+D5CF;D5CF;1112 1165 11AE;D5CF;1112 1165 11AE; # (헏; 헏; 헏; 헏; 헏; ) HANGUL SYLLABLE HEOD
+D5D0;D5D0;1112 1165 11AF;D5D0;1112 1165 11AF; # (헐; 헐; 헐; 헐; 헐; ) HANGUL SYLLABLE HEOL
+D5D1;D5D1;1112 1165 11B0;D5D1;1112 1165 11B0; # (헑; 헑; 헑; 헑; 헑; ) HANGUL SYLLABLE HEOLG
+D5D2;D5D2;1112 1165 11B1;D5D2;1112 1165 11B1; # (헒; 헒; 헒; 헒; 헒; ) HANGUL SYLLABLE HEOLM
+D5D3;D5D3;1112 1165 11B2;D5D3;1112 1165 11B2; # (헓; 헓; 헓; 헓; 헓; ) HANGUL SYLLABLE HEOLB
+D5D4;D5D4;1112 1165 11B3;D5D4;1112 1165 11B3; # (헔; 헔; 헔; 헔; 헔; ) HANGUL SYLLABLE HEOLS
+D5D5;D5D5;1112 1165 11B4;D5D5;1112 1165 11B4; # (헕; 헕; 헕; 헕; 헕; ) HANGUL SYLLABLE HEOLT
+D5D6;D5D6;1112 1165 11B5;D5D6;1112 1165 11B5; # (헖; 헖; 헖; 헖; 헖; ) HANGUL SYLLABLE HEOLP
+D5D7;D5D7;1112 1165 11B6;D5D7;1112 1165 11B6; # (헗; 헗; 헗; 헗; 헗; ) HANGUL SYLLABLE HEOLH
+D5D8;D5D8;1112 1165 11B7;D5D8;1112 1165 11B7; # (험; 험; 험; 험; 험; ) HANGUL SYLLABLE HEOM
+D5D9;D5D9;1112 1165 11B8;D5D9;1112 1165 11B8; # (헙; 헙; 헙; 헙; 헙; ) HANGUL SYLLABLE HEOB
+D5DA;D5DA;1112 1165 11B9;D5DA;1112 1165 11B9; # (헚; 헚; 헚; 헚; 헚; ) HANGUL SYLLABLE HEOBS
+D5DB;D5DB;1112 1165 11BA;D5DB;1112 1165 11BA; # (헛; 헛; 헛; 헛; 헛; ) HANGUL SYLLABLE HEOS
+D5DC;D5DC;1112 1165 11BB;D5DC;1112 1165 11BB; # (헜; 헜; 헜; 헜; 헜; ) HANGUL SYLLABLE HEOSS
+D5DD;D5DD;1112 1165 11BC;D5DD;1112 1165 11BC; # (헝; 헝; 헝; 헝; 헝; ) HANGUL SYLLABLE HEONG
+D5DE;D5DE;1112 1165 11BD;D5DE;1112 1165 11BD; # (헞; 헞; 헞; 헞; 헞; ) HANGUL SYLLABLE HEOJ
+D5DF;D5DF;1112 1165 11BE;D5DF;1112 1165 11BE; # (헟; 헟; 헟; 헟; 헟; ) HANGUL SYLLABLE HEOC
+D5E0;D5E0;1112 1165 11BF;D5E0;1112 1165 11BF; # (헠; 헠; 헠; 헠; 헠; ) HANGUL SYLLABLE HEOK
+D5E1;D5E1;1112 1165 11C0;D5E1;1112 1165 11C0; # (헡; 헡; 헡; 헡; 헡; ) HANGUL SYLLABLE HEOT
+D5E2;D5E2;1112 1165 11C1;D5E2;1112 1165 11C1; # (헢; 헢; 헢; 헢; 헢; ) HANGUL SYLLABLE HEOP
+D5E3;D5E3;1112 1165 11C2;D5E3;1112 1165 11C2; # (헣; 헣; 헣; 헣; 헣; ) HANGUL SYLLABLE HEOH
+D5E4;D5E4;1112 1166;D5E4;1112 1166; # (헤; 헤; 헤; 헤; 헤; ) HANGUL SYLLABLE HE
+D5E5;D5E5;1112 1166 11A8;D5E5;1112 1166 11A8; # (헥; 헥; 헥; 헥; 헥; ) HANGUL SYLLABLE HEG
+D5E6;D5E6;1112 1166 11A9;D5E6;1112 1166 11A9; # (헦; 헦; 헦; 헦; 헦; ) HANGUL SYLLABLE HEGG
+D5E7;D5E7;1112 1166 11AA;D5E7;1112 1166 11AA; # (헧; 헧; 헧; 헧; 헧; ) HANGUL SYLLABLE HEGS
+D5E8;D5E8;1112 1166 11AB;D5E8;1112 1166 11AB; # (헨; 헨; 헨; 헨; 헨; ) HANGUL SYLLABLE HEN
+D5E9;D5E9;1112 1166 11AC;D5E9;1112 1166 11AC; # (헩; 헩; 헩; 헩; 헩; ) HANGUL SYLLABLE HENJ
+D5EA;D5EA;1112 1166 11AD;D5EA;1112 1166 11AD; # (헪; 헪; 헪; 헪; 헪; ) HANGUL SYLLABLE HENH
+D5EB;D5EB;1112 1166 11AE;D5EB;1112 1166 11AE; # (헫; 헫; 헫; 헫; 헫; ) HANGUL SYLLABLE HED
+D5EC;D5EC;1112 1166 11AF;D5EC;1112 1166 11AF; # (헬; 헬; 헬; 헬; 헬; ) HANGUL SYLLABLE HEL
+D5ED;D5ED;1112 1166 11B0;D5ED;1112 1166 11B0; # (헭; 헭; 헭; 헭; 헭; ) HANGUL SYLLABLE HELG
+D5EE;D5EE;1112 1166 11B1;D5EE;1112 1166 11B1; # (헮; 헮; 헮; 헮; 헮; ) HANGUL SYLLABLE HELM
+D5EF;D5EF;1112 1166 11B2;D5EF;1112 1166 11B2; # (헯; 헯; 헯; 헯; 헯; ) HANGUL SYLLABLE HELB
+D5F0;D5F0;1112 1166 11B3;D5F0;1112 1166 11B3; # (헰; 헰; 헰; 헰; 헰; ) HANGUL SYLLABLE HELS
+D5F1;D5F1;1112 1166 11B4;D5F1;1112 1166 11B4; # (헱; 헱; 헱; 헱; 헱; ) HANGUL SYLLABLE HELT
+D5F2;D5F2;1112 1166 11B5;D5F2;1112 1166 11B5; # (헲; 헲; 헲; 헲; 헲; ) HANGUL SYLLABLE HELP
+D5F3;D5F3;1112 1166 11B6;D5F3;1112 1166 11B6; # (헳; 헳; 헳; 헳; 헳; ) HANGUL SYLLABLE HELH
+D5F4;D5F4;1112 1166 11B7;D5F4;1112 1166 11B7; # (헴; 헴; 헴; 헴; 헴; ) HANGUL SYLLABLE HEM
+D5F5;D5F5;1112 1166 11B8;D5F5;1112 1166 11B8; # (헵; 헵; 헵; 헵; 헵; ) HANGUL SYLLABLE HEB
+D5F6;D5F6;1112 1166 11B9;D5F6;1112 1166 11B9; # (헶; 헶; 헶; 헶; 헶; ) HANGUL SYLLABLE HEBS
+D5F7;D5F7;1112 1166 11BA;D5F7;1112 1166 11BA; # (헷; 헷; 헷; 헷; 헷; ) HANGUL SYLLABLE HES
+D5F8;D5F8;1112 1166 11BB;D5F8;1112 1166 11BB; # (헸; 헸; 헸; 헸; 헸; ) HANGUL SYLLABLE HESS
+D5F9;D5F9;1112 1166 11BC;D5F9;1112 1166 11BC; # (헹; 헹; 헹; 헹; 헹; ) HANGUL SYLLABLE HENG
+D5FA;D5FA;1112 1166 11BD;D5FA;1112 1166 11BD; # (헺; 헺; 헺; 헺; 헺; ) HANGUL SYLLABLE HEJ
+D5FB;D5FB;1112 1166 11BE;D5FB;1112 1166 11BE; # (헻; 헻; 헻; 헻; 헻; ) HANGUL SYLLABLE HEC
+D5FC;D5FC;1112 1166 11BF;D5FC;1112 1166 11BF; # (헼; 헼; 헼; 헼; 헼; ) HANGUL SYLLABLE HEK
+D5FD;D5FD;1112 1166 11C0;D5FD;1112 1166 11C0; # (헽; 헽; 헽; 헽; 헽; ) HANGUL SYLLABLE HET
+D5FE;D5FE;1112 1166 11C1;D5FE;1112 1166 11C1; # (헾; 헾; 헾; 헾; 헾; ) HANGUL SYLLABLE HEP
+D5FF;D5FF;1112 1166 11C2;D5FF;1112 1166 11C2; # (헿; 헿; 헿; 헿; 헿; ) HANGUL SYLLABLE HEH
+D600;D600;1112 1167;D600;1112 1167; # (혀; 혀; 혀; 혀; 혀; ) HANGUL SYLLABLE HYEO
+D601;D601;1112 1167 11A8;D601;1112 1167 11A8; # (혁; 혁; 혁; 혁; 혁; ) HANGUL SYLLABLE HYEOG
+D602;D602;1112 1167 11A9;D602;1112 1167 11A9; # (혂; 혂; 혂; 혂; 혂; ) HANGUL SYLLABLE HYEOGG
+D603;D603;1112 1167 11AA;D603;1112 1167 11AA; # (혃; 혃; 혃; 혃; 혃; ) HANGUL SYLLABLE HYEOGS
+D604;D604;1112 1167 11AB;D604;1112 1167 11AB; # (현; 현; 현; 현; 현; ) HANGUL SYLLABLE HYEON
+D605;D605;1112 1167 11AC;D605;1112 1167 11AC; # (혅; 혅; 혅; 혅; 혅; ) HANGUL SYLLABLE HYEONJ
+D606;D606;1112 1167 11AD;D606;1112 1167 11AD; # (혆; 혆; 혆; 혆; 혆; ) HANGUL SYLLABLE HYEONH
+D607;D607;1112 1167 11AE;D607;1112 1167 11AE; # (혇; 혇; 혇; 혇; 혇; ) HANGUL SYLLABLE HYEOD
+D608;D608;1112 1167 11AF;D608;1112 1167 11AF; # (혈; 혈; 혈; 혈; 혈; ) HANGUL SYLLABLE HYEOL
+D609;D609;1112 1167 11B0;D609;1112 1167 11B0; # (혉; 혉; 혉; 혉; 혉; ) HANGUL SYLLABLE HYEOLG
+D60A;D60A;1112 1167 11B1;D60A;1112 1167 11B1; # (혊; 혊; 혊; 혊; 혊; ) HANGUL SYLLABLE HYEOLM
+D60B;D60B;1112 1167 11B2;D60B;1112 1167 11B2; # (혋; 혋; 혋; 혋; 혋; ) HANGUL SYLLABLE HYEOLB
+D60C;D60C;1112 1167 11B3;D60C;1112 1167 11B3; # (혌; 혌; 혌; 혌; 혌; ) HANGUL SYLLABLE HYEOLS
+D60D;D60D;1112 1167 11B4;D60D;1112 1167 11B4; # (혍; 혍; 혍; 혍; 혍; ) HANGUL SYLLABLE HYEOLT
+D60E;D60E;1112 1167 11B5;D60E;1112 1167 11B5; # (혎; 혎; 혎; 혎; 혎; ) HANGUL SYLLABLE HYEOLP
+D60F;D60F;1112 1167 11B6;D60F;1112 1167 11B6; # (혏; 혏; 혏; 혏; 혏; ) HANGUL SYLLABLE HYEOLH
+D610;D610;1112 1167 11B7;D610;1112 1167 11B7; # (혐; 혐; 혐; 혐; 혐; ) HANGUL SYLLABLE HYEOM
+D611;D611;1112 1167 11B8;D611;1112 1167 11B8; # (협; 협; 협; 협; 협; ) HANGUL SYLLABLE HYEOB
+D612;D612;1112 1167 11B9;D612;1112 1167 11B9; # (혒; 혒; 혒; 혒; 혒; ) HANGUL SYLLABLE HYEOBS
+D613;D613;1112 1167 11BA;D613;1112 1167 11BA; # (혓; 혓; 혓; 혓; 혓; ) HANGUL SYLLABLE HYEOS
+D614;D614;1112 1167 11BB;D614;1112 1167 11BB; # (혔; 혔; 혔; 혔; 혔; ) HANGUL SYLLABLE HYEOSS
+D615;D615;1112 1167 11BC;D615;1112 1167 11BC; # (형; 형; 형; 형; 형; ) HANGUL SYLLABLE HYEONG
+D616;D616;1112 1167 11BD;D616;1112 1167 11BD; # (혖; 혖; 혖; 혖; 혖; ) HANGUL SYLLABLE HYEOJ
+D617;D617;1112 1167 11BE;D617;1112 1167 11BE; # (혗; 혗; 혗; 혗; 혗; ) HANGUL SYLLABLE HYEOC
+D618;D618;1112 1167 11BF;D618;1112 1167 11BF; # (혘; 혘; 혘; 혘; 혘; ) HANGUL SYLLABLE HYEOK
+D619;D619;1112 1167 11C0;D619;1112 1167 11C0; # (혙; 혙; 혙; 혙; 혙; ) HANGUL SYLLABLE HYEOT
+D61A;D61A;1112 1167 11C1;D61A;1112 1167 11C1; # (혚; 혚; 혚; 혚; 혚; ) HANGUL SYLLABLE HYEOP
+D61B;D61B;1112 1167 11C2;D61B;1112 1167 11C2; # (혛; 혛; 혛; 혛; 혛; ) HANGUL SYLLABLE HYEOH
+D61C;D61C;1112 1168;D61C;1112 1168; # (혜; 혜; 혜; 혜; 혜; ) HANGUL SYLLABLE HYE
+D61D;D61D;1112 1168 11A8;D61D;1112 1168 11A8; # (혝; 혝; 혝; 혝; 혝; ) HANGUL SYLLABLE HYEG
+D61E;D61E;1112 1168 11A9;D61E;1112 1168 11A9; # (혞; 혞; 혞; 혞; 혞; ) HANGUL SYLLABLE HYEGG
+D61F;D61F;1112 1168 11AA;D61F;1112 1168 11AA; # (혟; 혟; 혟; 혟; 혟; ) HANGUL SYLLABLE HYEGS
+D620;D620;1112 1168 11AB;D620;1112 1168 11AB; # (혠; 혠; 혠; 혠; 혠; ) HANGUL SYLLABLE HYEN
+D621;D621;1112 1168 11AC;D621;1112 1168 11AC; # (혡; 혡; 혡; 혡; 혡; ) HANGUL SYLLABLE HYENJ
+D622;D622;1112 1168 11AD;D622;1112 1168 11AD; # (혢; 혢; 혢; 혢; 혢; ) HANGUL SYLLABLE HYENH
+D623;D623;1112 1168 11AE;D623;1112 1168 11AE; # (혣; 혣; 혣; 혣; 혣; ) HANGUL SYLLABLE HYED
+D624;D624;1112 1168 11AF;D624;1112 1168 11AF; # (혤; 혤; 혤; 혤; 혤; ) HANGUL SYLLABLE HYEL
+D625;D625;1112 1168 11B0;D625;1112 1168 11B0; # (혥; 혥; 혥; 혥; 혥; ) HANGUL SYLLABLE HYELG
+D626;D626;1112 1168 11B1;D626;1112 1168 11B1; # (혦; 혦; 혦; 혦; 혦; ) HANGUL SYLLABLE HYELM
+D627;D627;1112 1168 11B2;D627;1112 1168 11B2; # (혧; 혧; 혧; 혧; 혧; ) HANGUL SYLLABLE HYELB
+D628;D628;1112 1168 11B3;D628;1112 1168 11B3; # (혨; 혨; 혨; 혨; 혨; ) HANGUL SYLLABLE HYELS
+D629;D629;1112 1168 11B4;D629;1112 1168 11B4; # (혩; 혩; 혩; 혩; 혩; ) HANGUL SYLLABLE HYELT
+D62A;D62A;1112 1168 11B5;D62A;1112 1168 11B5; # (혪; 혪; 혪; 혪; 혪; ) HANGUL SYLLABLE HYELP
+D62B;D62B;1112 1168 11B6;D62B;1112 1168 11B6; # (혫; 혫; 혫; 혫; 혫; ) HANGUL SYLLABLE HYELH
+D62C;D62C;1112 1168 11B7;D62C;1112 1168 11B7; # (혬; 혬; 혬; 혬; 혬; ) HANGUL SYLLABLE HYEM
+D62D;D62D;1112 1168 11B8;D62D;1112 1168 11B8; # (혭; 혭; 혭; 혭; 혭; ) HANGUL SYLLABLE HYEB
+D62E;D62E;1112 1168 11B9;D62E;1112 1168 11B9; # (혮; 혮; 혮; 혮; 혮; ) HANGUL SYLLABLE HYEBS
+D62F;D62F;1112 1168 11BA;D62F;1112 1168 11BA; # (혯; 혯; 혯; 혯; 혯; ) HANGUL SYLLABLE HYES
+D630;D630;1112 1168 11BB;D630;1112 1168 11BB; # (혰; 혰; 혰; 혰; 혰; ) HANGUL SYLLABLE HYESS
+D631;D631;1112 1168 11BC;D631;1112 1168 11BC; # (혱; 혱; 혱; 혱; 혱; ) HANGUL SYLLABLE HYENG
+D632;D632;1112 1168 11BD;D632;1112 1168 11BD; # (혲; 혲; 혲; 혲; 혲; ) HANGUL SYLLABLE HYEJ
+D633;D633;1112 1168 11BE;D633;1112 1168 11BE; # (혳; 혳; 혳; 혳; 혳; ) HANGUL SYLLABLE HYEC
+D634;D634;1112 1168 11BF;D634;1112 1168 11BF; # (혴; 혴; 혴; 혴; 혴; ) HANGUL SYLLABLE HYEK
+D635;D635;1112 1168 11C0;D635;1112 1168 11C0; # (혵; 혵; 혵; 혵; 혵; ) HANGUL SYLLABLE HYET
+D636;D636;1112 1168 11C1;D636;1112 1168 11C1; # (혶; 혶; 혶; 혶; 혶; ) HANGUL SYLLABLE HYEP
+D637;D637;1112 1168 11C2;D637;1112 1168 11C2; # (혷; 혷; 혷; 혷; 혷; ) HANGUL SYLLABLE HYEH
+D638;D638;1112 1169;D638;1112 1169; # (호; 호; 호; 호; 호; ) HANGUL SYLLABLE HO
+D639;D639;1112 1169 11A8;D639;1112 1169 11A8; # (혹; 혹; 혹; 혹; 혹; ) HANGUL SYLLABLE HOG
+D63A;D63A;1112 1169 11A9;D63A;1112 1169 11A9; # (혺; 혺; 혺; 혺; 혺; ) HANGUL SYLLABLE HOGG
+D63B;D63B;1112 1169 11AA;D63B;1112 1169 11AA; # (혻; 혻; 혻; 혻; 혻; ) HANGUL SYLLABLE HOGS
+D63C;D63C;1112 1169 11AB;D63C;1112 1169 11AB; # (혼; 혼; 혼; 혼; 혼; ) HANGUL SYLLABLE HON
+D63D;D63D;1112 1169 11AC;D63D;1112 1169 11AC; # (혽; 혽; 혽; 혽; 혽; ) HANGUL SYLLABLE HONJ
+D63E;D63E;1112 1169 11AD;D63E;1112 1169 11AD; # (혾; 혾; 혾; 혾; 혾; ) HANGUL SYLLABLE HONH
+D63F;D63F;1112 1169 11AE;D63F;1112 1169 11AE; # (혿; 혿; 혿; 혿; 혿; ) HANGUL SYLLABLE HOD
+D640;D640;1112 1169 11AF;D640;1112 1169 11AF; # (홀; 홀; 홀; 홀; 홀; ) HANGUL SYLLABLE HOL
+D641;D641;1112 1169 11B0;D641;1112 1169 11B0; # (홁; 홁; 홁; 홁; 홁; ) HANGUL SYLLABLE HOLG
+D642;D642;1112 1169 11B1;D642;1112 1169 11B1; # (홂; 홂; 홂; 홂; 홂; ) HANGUL SYLLABLE HOLM
+D643;D643;1112 1169 11B2;D643;1112 1169 11B2; # (홃; 홃; 홃; 홃; 홃; ) HANGUL SYLLABLE HOLB
+D644;D644;1112 1169 11B3;D644;1112 1169 11B3; # (홄; 홄; 홄; 홄; 홄; ) HANGUL SYLLABLE HOLS
+D645;D645;1112 1169 11B4;D645;1112 1169 11B4; # (홅; 홅; 홅; 홅; 홅; ) HANGUL SYLLABLE HOLT
+D646;D646;1112 1169 11B5;D646;1112 1169 11B5; # (홆; 홆; 홆; 홆; 홆; ) HANGUL SYLLABLE HOLP
+D647;D647;1112 1169 11B6;D647;1112 1169 11B6; # (홇; 홇; 홇; 홇; 홇; ) HANGUL SYLLABLE HOLH
+D648;D648;1112 1169 11B7;D648;1112 1169 11B7; # (홈; 홈; 홈; 홈; 홈; ) HANGUL SYLLABLE HOM
+D649;D649;1112 1169 11B8;D649;1112 1169 11B8; # (홉; 홉; 홉; 홉; 홉; ) HANGUL SYLLABLE HOB
+D64A;D64A;1112 1169 11B9;D64A;1112 1169 11B9; # (홊; 홊; 홊; 홊; 홊; ) HANGUL SYLLABLE HOBS
+D64B;D64B;1112 1169 11BA;D64B;1112 1169 11BA; # (홋; 홋; 홋; 홋; 홋; ) HANGUL SYLLABLE HOS
+D64C;D64C;1112 1169 11BB;D64C;1112 1169 11BB; # (홌; 홌; 홌; 홌; 홌; ) HANGUL SYLLABLE HOSS
+D64D;D64D;1112 1169 11BC;D64D;1112 1169 11BC; # (홍; 홍; 홍; 홍; 홍; ) HANGUL SYLLABLE HONG
+D64E;D64E;1112 1169 11BD;D64E;1112 1169 11BD; # (홎; 홎; 홎; 홎; 홎; ) HANGUL SYLLABLE HOJ
+D64F;D64F;1112 1169 11BE;D64F;1112 1169 11BE; # (홏; 홏; 홏; 홏; 홏; ) HANGUL SYLLABLE HOC
+D650;D650;1112 1169 11BF;D650;1112 1169 11BF; # (홐; 홐; 홐; 홐; 홐; ) HANGUL SYLLABLE HOK
+D651;D651;1112 1169 11C0;D651;1112 1169 11C0; # (홑; 홑; 홑; 홑; 홑; ) HANGUL SYLLABLE HOT
+D652;D652;1112 1169 11C1;D652;1112 1169 11C1; # (홒; 홒; 홒; 홒; 홒; ) HANGUL SYLLABLE HOP
+D653;D653;1112 1169 11C2;D653;1112 1169 11C2; # (홓; 홓; 홓; 홓; 홓; ) HANGUL SYLLABLE HOH
+D654;D654;1112 116A;D654;1112 116A; # (화; 화; 화; 화; 화; ) HANGUL SYLLABLE HWA
+D655;D655;1112 116A 11A8;D655;1112 116A 11A8; # (확; 확; 확; 확; 확; ) HANGUL SYLLABLE HWAG
+D656;D656;1112 116A 11A9;D656;1112 116A 11A9; # (홖; 홖; 홖; 홖; 홖; ) HANGUL SYLLABLE HWAGG
+D657;D657;1112 116A 11AA;D657;1112 116A 11AA; # (홗; 홗; 홗; 홗; 홗; ) HANGUL SYLLABLE HWAGS
+D658;D658;1112 116A 11AB;D658;1112 116A 11AB; # (환; 환; 환; 환; 환; ) HANGUL SYLLABLE HWAN
+D659;D659;1112 116A 11AC;D659;1112 116A 11AC; # (홙; 홙; 홙; 홙; 홙; ) HANGUL SYLLABLE HWANJ
+D65A;D65A;1112 116A 11AD;D65A;1112 116A 11AD; # (홚; 홚; 홚; 홚; 홚; ) HANGUL SYLLABLE HWANH
+D65B;D65B;1112 116A 11AE;D65B;1112 116A 11AE; # (홛; 홛; 홛; 홛; 홛; ) HANGUL SYLLABLE HWAD
+D65C;D65C;1112 116A 11AF;D65C;1112 116A 11AF; # (활; 활; 활; 활; 활; ) HANGUL SYLLABLE HWAL
+D65D;D65D;1112 116A 11B0;D65D;1112 116A 11B0; # (홝; 홝; 홝; 홝; 홝; ) HANGUL SYLLABLE HWALG
+D65E;D65E;1112 116A 11B1;D65E;1112 116A 11B1; # (홞; 홞; 홞; 홞; 홞; ) HANGUL SYLLABLE HWALM
+D65F;D65F;1112 116A 11B2;D65F;1112 116A 11B2; # (홟; 홟; 홟; 홟; 홟; ) HANGUL SYLLABLE HWALB
+D660;D660;1112 116A 11B3;D660;1112 116A 11B3; # (홠; 홠; 홠; 홠; 홠; ) HANGUL SYLLABLE HWALS
+D661;D661;1112 116A 11B4;D661;1112 116A 11B4; # (홡; 홡; 홡; 홡; 홡; ) HANGUL SYLLABLE HWALT
+D662;D662;1112 116A 11B5;D662;1112 116A 11B5; # (홢; 홢; 홢; 홢; 홢; ) HANGUL SYLLABLE HWALP
+D663;D663;1112 116A 11B6;D663;1112 116A 11B6; # (홣; 홣; 홣; 홣; 홣; ) HANGUL SYLLABLE HWALH
+D664;D664;1112 116A 11B7;D664;1112 116A 11B7; # (홤; 홤; 홤; 홤; 홤; ) HANGUL SYLLABLE HWAM
+D665;D665;1112 116A 11B8;D665;1112 116A 11B8; # (홥; 홥; 홥; 홥; 홥; ) HANGUL SYLLABLE HWAB
+D666;D666;1112 116A 11B9;D666;1112 116A 11B9; # (홦; 홦; 홦; 홦; 홦; ) HANGUL SYLLABLE HWABS
+D667;D667;1112 116A 11BA;D667;1112 116A 11BA; # (홧; 홧; 홧; 홧; 홧; ) HANGUL SYLLABLE HWAS
+D668;D668;1112 116A 11BB;D668;1112 116A 11BB; # (홨; 홨; 홨; 홨; 홨; ) HANGUL SYLLABLE HWASS
+D669;D669;1112 116A 11BC;D669;1112 116A 11BC; # (황; 황; 황; 황; 황; ) HANGUL SYLLABLE HWANG
+D66A;D66A;1112 116A 11BD;D66A;1112 116A 11BD; # (홪; 홪; 홪; 홪; 홪; ) HANGUL SYLLABLE HWAJ
+D66B;D66B;1112 116A 11BE;D66B;1112 116A 11BE; # (홫; 홫; 홫; 홫; 홫; ) HANGUL SYLLABLE HWAC
+D66C;D66C;1112 116A 11BF;D66C;1112 116A 11BF; # (홬; 홬; 홬; 홬; 홬; ) HANGUL SYLLABLE HWAK
+D66D;D66D;1112 116A 11C0;D66D;1112 116A 11C0; # (홭; 홭; 홭; 홭; 홭; ) HANGUL SYLLABLE HWAT
+D66E;D66E;1112 116A 11C1;D66E;1112 116A 11C1; # (홮; 홮; 홮; 홮; 홮; ) HANGUL SYLLABLE HWAP
+D66F;D66F;1112 116A 11C2;D66F;1112 116A 11C2; # (홯; 홯; 홯; 홯; 홯; ) HANGUL SYLLABLE HWAH
+D670;D670;1112 116B;D670;1112 116B; # (홰; 홰; 홰; 홰; 홰; ) HANGUL SYLLABLE HWAE
+D671;D671;1112 116B 11A8;D671;1112 116B 11A8; # (홱; 홱; 홱; 홱; 홱; ) HANGUL SYLLABLE HWAEG
+D672;D672;1112 116B 11A9;D672;1112 116B 11A9; # (홲; 홲; 홲; 홲; 홲; ) HANGUL SYLLABLE HWAEGG
+D673;D673;1112 116B 11AA;D673;1112 116B 11AA; # (홳; 홳; 홳; 홳; 홳; ) HANGUL SYLLABLE HWAEGS
+D674;D674;1112 116B 11AB;D674;1112 116B 11AB; # (홴; 홴; 홴; 홴; 홴; ) HANGUL SYLLABLE HWAEN
+D675;D675;1112 116B 11AC;D675;1112 116B 11AC; # (홵; 홵; 홵; 홵; 홵; ) HANGUL SYLLABLE HWAENJ
+D676;D676;1112 116B 11AD;D676;1112 116B 11AD; # (홶; 홶; 홶; 홶; 홶; ) HANGUL SYLLABLE HWAENH
+D677;D677;1112 116B 11AE;D677;1112 116B 11AE; # (홷; 홷; 홷; 홷; 홷; ) HANGUL SYLLABLE HWAED
+D678;D678;1112 116B 11AF;D678;1112 116B 11AF; # (홸; 홸; 홸; 홸; 홸; ) HANGUL SYLLABLE HWAEL
+D679;D679;1112 116B 11B0;D679;1112 116B 11B0; # (홹; 홹; 홹; 홹; 홹; ) HANGUL SYLLABLE HWAELG
+D67A;D67A;1112 116B 11B1;D67A;1112 116B 11B1; # (홺; 홺; 홺; 홺; 홺; ) HANGUL SYLLABLE HWAELM
+D67B;D67B;1112 116B 11B2;D67B;1112 116B 11B2; # (홻; 홻; 홻; 홻; 홻; ) HANGUL SYLLABLE HWAELB
+D67C;D67C;1112 116B 11B3;D67C;1112 116B 11B3; # (홼; 홼; 홼; 홼; 홼; ) HANGUL SYLLABLE HWAELS
+D67D;D67D;1112 116B 11B4;D67D;1112 116B 11B4; # (홽; 홽; 홽; 홽; 홽; ) HANGUL SYLLABLE HWAELT
+D67E;D67E;1112 116B 11B5;D67E;1112 116B 11B5; # (홾; 홾; 홾; 홾; 홾; ) HANGUL SYLLABLE HWAELP
+D67F;D67F;1112 116B 11B6;D67F;1112 116B 11B6; # (홿; 홿; 홿; 홿; 홿; ) HANGUL SYLLABLE HWAELH
+D680;D680;1112 116B 11B7;D680;1112 116B 11B7; # (횀; 횀; 횀; 횀; 횀; ) HANGUL SYLLABLE HWAEM
+D681;D681;1112 116B 11B8;D681;1112 116B 11B8; # (횁; 횁; 횁; 횁; 횁; ) HANGUL SYLLABLE HWAEB
+D682;D682;1112 116B 11B9;D682;1112 116B 11B9; # (횂; 횂; 횂; 횂; 횂; ) HANGUL SYLLABLE HWAEBS
+D683;D683;1112 116B 11BA;D683;1112 116B 11BA; # (횃; 횃; 횃; 횃; 횃; ) HANGUL SYLLABLE HWAES
+D684;D684;1112 116B 11BB;D684;1112 116B 11BB; # (횄; 횄; 횄; 횄; 횄; ) HANGUL SYLLABLE HWAESS
+D685;D685;1112 116B 11BC;D685;1112 116B 11BC; # (횅; 횅; 횅; 횅; 횅; ) HANGUL SYLLABLE HWAENG
+D686;D686;1112 116B 11BD;D686;1112 116B 11BD; # (횆; 횆; 횆; 횆; 횆; ) HANGUL SYLLABLE HWAEJ
+D687;D687;1112 116B 11BE;D687;1112 116B 11BE; # (횇; 횇; 횇; 횇; 횇; ) HANGUL SYLLABLE HWAEC
+D688;D688;1112 116B 11BF;D688;1112 116B 11BF; # (횈; 횈; 횈; 횈; 횈; ) HANGUL SYLLABLE HWAEK
+D689;D689;1112 116B 11C0;D689;1112 116B 11C0; # (횉; 횉; 횉; 횉; 횉; ) HANGUL SYLLABLE HWAET
+D68A;D68A;1112 116B 11C1;D68A;1112 116B 11C1; # (횊; 횊; 횊; 횊; 횊; ) HANGUL SYLLABLE HWAEP
+D68B;D68B;1112 116B 11C2;D68B;1112 116B 11C2; # (횋; 횋; 횋; 횋; 횋; ) HANGUL SYLLABLE HWAEH
+D68C;D68C;1112 116C;D68C;1112 116C; # (회; 회; 회; 회; 회; ) HANGUL SYLLABLE HOE
+D68D;D68D;1112 116C 11A8;D68D;1112 116C 11A8; # (획; 획; 획; 획; 획; ) HANGUL SYLLABLE HOEG
+D68E;D68E;1112 116C 11A9;D68E;1112 116C 11A9; # (횎; 횎; 횎; 횎; 횎; ) HANGUL SYLLABLE HOEGG
+D68F;D68F;1112 116C 11AA;D68F;1112 116C 11AA; # (횏; 횏; 횏; 횏; 횏; ) HANGUL SYLLABLE HOEGS
+D690;D690;1112 116C 11AB;D690;1112 116C 11AB; # (횐; 횐; 횐; 횐; 횐; ) HANGUL SYLLABLE HOEN
+D691;D691;1112 116C 11AC;D691;1112 116C 11AC; # (횑; 횑; 횑; 횑; 횑; ) HANGUL SYLLABLE HOENJ
+D692;D692;1112 116C 11AD;D692;1112 116C 11AD; # (횒; 횒; 횒; 횒; 횒; ) HANGUL SYLLABLE HOENH
+D693;D693;1112 116C 11AE;D693;1112 116C 11AE; # (횓; 횓; 횓; 횓; 횓; ) HANGUL SYLLABLE HOED
+D694;D694;1112 116C 11AF;D694;1112 116C 11AF; # (횔; 횔; 횔; 횔; 횔; ) HANGUL SYLLABLE HOEL
+D695;D695;1112 116C 11B0;D695;1112 116C 11B0; # (횕; 횕; 횕; 횕; 횕; ) HANGUL SYLLABLE HOELG
+D696;D696;1112 116C 11B1;D696;1112 116C 11B1; # (횖; 횖; 횖; 횖; 횖; ) HANGUL SYLLABLE HOELM
+D697;D697;1112 116C 11B2;D697;1112 116C 11B2; # (횗; 횗; 횗; 횗; 횗; ) HANGUL SYLLABLE HOELB
+D698;D698;1112 116C 11B3;D698;1112 116C 11B3; # (횘; 횘; 횘; 횘; 횘; ) HANGUL SYLLABLE HOELS
+D699;D699;1112 116C 11B4;D699;1112 116C 11B4; # (횙; 횙; 횙; 횙; 횙; ) HANGUL SYLLABLE HOELT
+D69A;D69A;1112 116C 11B5;D69A;1112 116C 11B5; # (횚; 횚; 횚; 횚; 횚; ) HANGUL SYLLABLE HOELP
+D69B;D69B;1112 116C 11B6;D69B;1112 116C 11B6; # (횛; 횛; 횛; 횛; 횛; ) HANGUL SYLLABLE HOELH
+D69C;D69C;1112 116C 11B7;D69C;1112 116C 11B7; # (횜; 횜; 횜; 횜; 횜; ) HANGUL SYLLABLE HOEM
+D69D;D69D;1112 116C 11B8;D69D;1112 116C 11B8; # (횝; 횝; 횝; 횝; 횝; ) HANGUL SYLLABLE HOEB
+D69E;D69E;1112 116C 11B9;D69E;1112 116C 11B9; # (횞; 횞; 횞; 횞; 횞; ) HANGUL SYLLABLE HOEBS
+D69F;D69F;1112 116C 11BA;D69F;1112 116C 11BA; # (횟; 횟; 횟; 횟; 횟; ) HANGUL SYLLABLE HOES
+D6A0;D6A0;1112 116C 11BB;D6A0;1112 116C 11BB; # (횠; 횠; 횠; 횠; 횠; ) HANGUL SYLLABLE HOESS
+D6A1;D6A1;1112 116C 11BC;D6A1;1112 116C 11BC; # (횡; 횡; 횡; 횡; 횡; ) HANGUL SYLLABLE HOENG
+D6A2;D6A2;1112 116C 11BD;D6A2;1112 116C 11BD; # (횢; 횢; 횢; 횢; 횢; ) HANGUL SYLLABLE HOEJ
+D6A3;D6A3;1112 116C 11BE;D6A3;1112 116C 11BE; # (횣; 횣; 횣; 횣; 횣; ) HANGUL SYLLABLE HOEC
+D6A4;D6A4;1112 116C 11BF;D6A4;1112 116C 11BF; # (횤; 횤; 횤; 횤; 횤; ) HANGUL SYLLABLE HOEK
+D6A5;D6A5;1112 116C 11C0;D6A5;1112 116C 11C0; # (횥; 횥; 횥; 횥; 횥; ) HANGUL SYLLABLE HOET
+D6A6;D6A6;1112 116C 11C1;D6A6;1112 116C 11C1; # (횦; 횦; 횦; 횦; 횦; ) HANGUL SYLLABLE HOEP
+D6A7;D6A7;1112 116C 11C2;D6A7;1112 116C 11C2; # (횧; 횧; 횧; 횧; 횧; ) HANGUL SYLLABLE HOEH
+D6A8;D6A8;1112 116D;D6A8;1112 116D; # (효; 효; 효; 효; 효; ) HANGUL SYLLABLE HYO
+D6A9;D6A9;1112 116D 11A8;D6A9;1112 116D 11A8; # (횩; 횩; 횩; 횩; 횩; ) HANGUL SYLLABLE HYOG
+D6AA;D6AA;1112 116D 11A9;D6AA;1112 116D 11A9; # (횪; 횪; 횪; 횪; 횪; ) HANGUL SYLLABLE HYOGG
+D6AB;D6AB;1112 116D 11AA;D6AB;1112 116D 11AA; # (횫; 횫; 횫; 횫; 횫; ) HANGUL SYLLABLE HYOGS
+D6AC;D6AC;1112 116D 11AB;D6AC;1112 116D 11AB; # (횬; 횬; 횬; 횬; 횬; ) HANGUL SYLLABLE HYON
+D6AD;D6AD;1112 116D 11AC;D6AD;1112 116D 11AC; # (횭; 횭; 횭; 횭; 횭; ) HANGUL SYLLABLE HYONJ
+D6AE;D6AE;1112 116D 11AD;D6AE;1112 116D 11AD; # (횮; 횮; 횮; 횮; 횮; ) HANGUL SYLLABLE HYONH
+D6AF;D6AF;1112 116D 11AE;D6AF;1112 116D 11AE; # (횯; 횯; 횯; 횯; 횯; ) HANGUL SYLLABLE HYOD
+D6B0;D6B0;1112 116D 11AF;D6B0;1112 116D 11AF; # (횰; 횰; 횰; 횰; 횰; ) HANGUL SYLLABLE HYOL
+D6B1;D6B1;1112 116D 11B0;D6B1;1112 116D 11B0; # (횱; 횱; 횱; 횱; 횱; ) HANGUL SYLLABLE HYOLG
+D6B2;D6B2;1112 116D 11B1;D6B2;1112 116D 11B1; # (횲; 횲; 횲; 횲; 횲; ) HANGUL SYLLABLE HYOLM
+D6B3;D6B3;1112 116D 11B2;D6B3;1112 116D 11B2; # (횳; 횳; 횳; 횳; 횳; ) HANGUL SYLLABLE HYOLB
+D6B4;D6B4;1112 116D 11B3;D6B4;1112 116D 11B3; # (횴; 횴; 횴; 횴; 횴; ) HANGUL SYLLABLE HYOLS
+D6B5;D6B5;1112 116D 11B4;D6B5;1112 116D 11B4; # (횵; 횵; 횵; 횵; 횵; ) HANGUL SYLLABLE HYOLT
+D6B6;D6B6;1112 116D 11B5;D6B6;1112 116D 11B5; # (횶; 횶; 횶; 횶; 횶; ) HANGUL SYLLABLE HYOLP
+D6B7;D6B7;1112 116D 11B6;D6B7;1112 116D 11B6; # (횷; 횷; 횷; 횷; 횷; ) HANGUL SYLLABLE HYOLH
+D6B8;D6B8;1112 116D 11B7;D6B8;1112 116D 11B7; # (횸; 횸; 횸; 횸; 횸; ) HANGUL SYLLABLE HYOM
+D6B9;D6B9;1112 116D 11B8;D6B9;1112 116D 11B8; # (횹; 횹; 횹; 횹; 횹; ) HANGUL SYLLABLE HYOB
+D6BA;D6BA;1112 116D 11B9;D6BA;1112 116D 11B9; # (횺; 횺; 횺; 횺; 횺; ) HANGUL SYLLABLE HYOBS
+D6BB;D6BB;1112 116D 11BA;D6BB;1112 116D 11BA; # (횻; 횻; 횻; 횻; 횻; ) HANGUL SYLLABLE HYOS
+D6BC;D6BC;1112 116D 11BB;D6BC;1112 116D 11BB; # (횼; 횼; 횼; 횼; 횼; ) HANGUL SYLLABLE HYOSS
+D6BD;D6BD;1112 116D 11BC;D6BD;1112 116D 11BC; # (횽; 횽; 횽; 횽; 횽; ) HANGUL SYLLABLE HYONG
+D6BE;D6BE;1112 116D 11BD;D6BE;1112 116D 11BD; # (횾; 횾; 횾; 횾; 횾; ) HANGUL SYLLABLE HYOJ
+D6BF;D6BF;1112 116D 11BE;D6BF;1112 116D 11BE; # (횿; 횿; 횿; 횿; 횿; ) HANGUL SYLLABLE HYOC
+D6C0;D6C0;1112 116D 11BF;D6C0;1112 116D 11BF; # (훀; 훀; 훀; 훀; 훀; ) HANGUL SYLLABLE HYOK
+D6C1;D6C1;1112 116D 11C0;D6C1;1112 116D 11C0; # (훁; 훁; 훁; 훁; 훁; ) HANGUL SYLLABLE HYOT
+D6C2;D6C2;1112 116D 11C1;D6C2;1112 116D 11C1; # (훂; 훂; 훂; 훂; 훂; ) HANGUL SYLLABLE HYOP
+D6C3;D6C3;1112 116D 11C2;D6C3;1112 116D 11C2; # (훃; 훃; 훃; 훃; 훃; ) HANGUL SYLLABLE HYOH
+D6C4;D6C4;1112 116E;D6C4;1112 116E; # (후; 후; 후; 후; 후; ) HANGUL SYLLABLE HU
+D6C5;D6C5;1112 116E 11A8;D6C5;1112 116E 11A8; # (훅; 훅; 훅; 훅; 훅; ) HANGUL SYLLABLE HUG
+D6C6;D6C6;1112 116E 11A9;D6C6;1112 116E 11A9; # (훆; 훆; 훆; 훆; 훆; ) HANGUL SYLLABLE HUGG
+D6C7;D6C7;1112 116E 11AA;D6C7;1112 116E 11AA; # (훇; 훇; 훇; 훇; 훇; ) HANGUL SYLLABLE HUGS
+D6C8;D6C8;1112 116E 11AB;D6C8;1112 116E 11AB; # (훈; 훈; 훈; 훈; 훈; ) HANGUL SYLLABLE HUN
+D6C9;D6C9;1112 116E 11AC;D6C9;1112 116E 11AC; # (훉; 훉; 훉; 훉; 훉; ) HANGUL SYLLABLE HUNJ
+D6CA;D6CA;1112 116E 11AD;D6CA;1112 116E 11AD; # (훊; 훊; 훊; 훊; 훊; ) HANGUL SYLLABLE HUNH
+D6CB;D6CB;1112 116E 11AE;D6CB;1112 116E 11AE; # (훋; 훋; 훋; 훋; 훋; ) HANGUL SYLLABLE HUD
+D6CC;D6CC;1112 116E 11AF;D6CC;1112 116E 11AF; # (훌; 훌; 훌; 훌; 훌; ) HANGUL SYLLABLE HUL
+D6CD;D6CD;1112 116E 11B0;D6CD;1112 116E 11B0; # (훍; 훍; 훍; 훍; 훍; ) HANGUL SYLLABLE HULG
+D6CE;D6CE;1112 116E 11B1;D6CE;1112 116E 11B1; # (훎; 훎; 훎; 훎; 훎; ) HANGUL SYLLABLE HULM
+D6CF;D6CF;1112 116E 11B2;D6CF;1112 116E 11B2; # (훏; 훏; 훏; 훏; 훏; ) HANGUL SYLLABLE HULB
+D6D0;D6D0;1112 116E 11B3;D6D0;1112 116E 11B3; # (훐; 훐; 훐; 훐; 훐; ) HANGUL SYLLABLE HULS
+D6D1;D6D1;1112 116E 11B4;D6D1;1112 116E 11B4; # (훑; 훑; 훑; 훑; 훑; ) HANGUL SYLLABLE HULT
+D6D2;D6D2;1112 116E 11B5;D6D2;1112 116E 11B5; # (훒; 훒; 훒; 훒; 훒; ) HANGUL SYLLABLE HULP
+D6D3;D6D3;1112 116E 11B6;D6D3;1112 116E 11B6; # (훓; 훓; 훓; 훓; 훓; ) HANGUL SYLLABLE HULH
+D6D4;D6D4;1112 116E 11B7;D6D4;1112 116E 11B7; # (훔; 훔; 훔; 훔; 훔; ) HANGUL SYLLABLE HUM
+D6D5;D6D5;1112 116E 11B8;D6D5;1112 116E 11B8; # (훕; 훕; 훕; 훕; 훕; ) HANGUL SYLLABLE HUB
+D6D6;D6D6;1112 116E 11B9;D6D6;1112 116E 11B9; # (훖; 훖; 훖; 훖; 훖; ) HANGUL SYLLABLE HUBS
+D6D7;D6D7;1112 116E 11BA;D6D7;1112 116E 11BA; # (훗; 훗; 훗; 훗; 훗; ) HANGUL SYLLABLE HUS
+D6D8;D6D8;1112 116E 11BB;D6D8;1112 116E 11BB; # (훘; 훘; 훘; 훘; 훘; ) HANGUL SYLLABLE HUSS
+D6D9;D6D9;1112 116E 11BC;D6D9;1112 116E 11BC; # (훙; 훙; 훙; 훙; 훙; ) HANGUL SYLLABLE HUNG
+D6DA;D6DA;1112 116E 11BD;D6DA;1112 116E 11BD; # (훚; 훚; 훚; 훚; 훚; ) HANGUL SYLLABLE HUJ
+D6DB;D6DB;1112 116E 11BE;D6DB;1112 116E 11BE; # (훛; 훛; 훛; 훛; 훛; ) HANGUL SYLLABLE HUC
+D6DC;D6DC;1112 116E 11BF;D6DC;1112 116E 11BF; # (훜; 훜; 훜; 훜; 훜; ) HANGUL SYLLABLE HUK
+D6DD;D6DD;1112 116E 11C0;D6DD;1112 116E 11C0; # (훝; 훝; 훝; 훝; 훝; ) HANGUL SYLLABLE HUT
+D6DE;D6DE;1112 116E 11C1;D6DE;1112 116E 11C1; # (훞; 훞; 훞; 훞; 훞; ) HANGUL SYLLABLE HUP
+D6DF;D6DF;1112 116E 11C2;D6DF;1112 116E 11C2; # (훟; 훟; 훟; 훟; 훟; ) HANGUL SYLLABLE HUH
+D6E0;D6E0;1112 116F;D6E0;1112 116F; # (훠; 훠; 훠; 훠; 훠; ) HANGUL SYLLABLE HWEO
+D6E1;D6E1;1112 116F 11A8;D6E1;1112 116F 11A8; # (훡; 훡; 훡; 훡; 훡; ) HANGUL SYLLABLE HWEOG
+D6E2;D6E2;1112 116F 11A9;D6E2;1112 116F 11A9; # (훢; 훢; 훢; 훢; 훢; ) HANGUL SYLLABLE HWEOGG
+D6E3;D6E3;1112 116F 11AA;D6E3;1112 116F 11AA; # (훣; 훣; 훣; 훣; 훣; ) HANGUL SYLLABLE HWEOGS
+D6E4;D6E4;1112 116F 11AB;D6E4;1112 116F 11AB; # (훤; 훤; 훤; 훤; 훤; ) HANGUL SYLLABLE HWEON
+D6E5;D6E5;1112 116F 11AC;D6E5;1112 116F 11AC; # (훥; 훥; 훥; 훥; 훥; ) HANGUL SYLLABLE HWEONJ
+D6E6;D6E6;1112 116F 11AD;D6E6;1112 116F 11AD; # (훦; 훦; 훦; 훦; 훦; ) HANGUL SYLLABLE HWEONH
+D6E7;D6E7;1112 116F 11AE;D6E7;1112 116F 11AE; # (훧; 훧; 훧; 훧; 훧; ) HANGUL SYLLABLE HWEOD
+D6E8;D6E8;1112 116F 11AF;D6E8;1112 116F 11AF; # (훨; 훨; 훨; 훨; 훨; ) HANGUL SYLLABLE HWEOL
+D6E9;D6E9;1112 116F 11B0;D6E9;1112 116F 11B0; # (훩; 훩; 훩; 훩; 훩; ) HANGUL SYLLABLE HWEOLG
+D6EA;D6EA;1112 116F 11B1;D6EA;1112 116F 11B1; # (훪; 훪; 훪; 훪; 훪; ) HANGUL SYLLABLE HWEOLM
+D6EB;D6EB;1112 116F 11B2;D6EB;1112 116F 11B2; # (훫; 훫; 훫; 훫; 훫; ) HANGUL SYLLABLE HWEOLB
+D6EC;D6EC;1112 116F 11B3;D6EC;1112 116F 11B3; # (훬; 훬; 훬; 훬; 훬; ) HANGUL SYLLABLE HWEOLS
+D6ED;D6ED;1112 116F 11B4;D6ED;1112 116F 11B4; # (훭; 훭; 훭; 훭; 훭; ) HANGUL SYLLABLE HWEOLT
+D6EE;D6EE;1112 116F 11B5;D6EE;1112 116F 11B5; # (훮; 훮; 훮; 훮; 훮; ) HANGUL SYLLABLE HWEOLP
+D6EF;D6EF;1112 116F 11B6;D6EF;1112 116F 11B6; # (훯; 훯; 훯; 훯; 훯; ) HANGUL SYLLABLE HWEOLH
+D6F0;D6F0;1112 116F 11B7;D6F0;1112 116F 11B7; # (훰; 훰; 훰; 훰; 훰; ) HANGUL SYLLABLE HWEOM
+D6F1;D6F1;1112 116F 11B8;D6F1;1112 116F 11B8; # (훱; 훱; 훱; 훱; 훱; ) HANGUL SYLLABLE HWEOB
+D6F2;D6F2;1112 116F 11B9;D6F2;1112 116F 11B9; # (훲; 훲; 훲; 훲; 훲; ) HANGUL SYLLABLE HWEOBS
+D6F3;D6F3;1112 116F 11BA;D6F3;1112 116F 11BA; # (훳; 훳; 훳; 훳; 훳; ) HANGUL SYLLABLE HWEOS
+D6F4;D6F4;1112 116F 11BB;D6F4;1112 116F 11BB; # (훴; 훴; 훴; 훴; 훴; ) HANGUL SYLLABLE HWEOSS
+D6F5;D6F5;1112 116F 11BC;D6F5;1112 116F 11BC; # (훵; 훵; 훵; 훵; 훵; ) HANGUL SYLLABLE HWEONG
+D6F6;D6F6;1112 116F 11BD;D6F6;1112 116F 11BD; # (훶; 훶; 훶; 훶; 훶; ) HANGUL SYLLABLE HWEOJ
+D6F7;D6F7;1112 116F 11BE;D6F7;1112 116F 11BE; # (훷; 훷; 훷; 훷; 훷; ) HANGUL SYLLABLE HWEOC
+D6F8;D6F8;1112 116F 11BF;D6F8;1112 116F 11BF; # (훸; 훸; 훸; 훸; 훸; ) HANGUL SYLLABLE HWEOK
+D6F9;D6F9;1112 116F 11C0;D6F9;1112 116F 11C0; # (훹; 훹; 훹; 훹; 훹; ) HANGUL SYLLABLE HWEOT
+D6FA;D6FA;1112 116F 11C1;D6FA;1112 116F 11C1; # (훺; 훺; 훺; 훺; 훺; ) HANGUL SYLLABLE HWEOP
+D6FB;D6FB;1112 116F 11C2;D6FB;1112 116F 11C2; # (훻; 훻; 훻; 훻; 훻; ) HANGUL SYLLABLE HWEOH
+D6FC;D6FC;1112 1170;D6FC;1112 1170; # (훼; 훼; 훼; 훼; 훼; ) HANGUL SYLLABLE HWE
+D6FD;D6FD;1112 1170 11A8;D6FD;1112 1170 11A8; # (훽; 훽; 훽; 훽; 훽; ) HANGUL SYLLABLE HWEG
+D6FE;D6FE;1112 1170 11A9;D6FE;1112 1170 11A9; # (훾; 훾; 훾; 훾; 훾; ) HANGUL SYLLABLE HWEGG
+D6FF;D6FF;1112 1170 11AA;D6FF;1112 1170 11AA; # (훿; 훿; 훿; 훿; 훿; ) HANGUL SYLLABLE HWEGS
+D700;D700;1112 1170 11AB;D700;1112 1170 11AB; # (휀; 휀; 휀; 휀; 휀; ) HANGUL SYLLABLE HWEN
+D701;D701;1112 1170 11AC;D701;1112 1170 11AC; # (휁; 휁; 휁; 휁; 휁; ) HANGUL SYLLABLE HWENJ
+D702;D702;1112 1170 11AD;D702;1112 1170 11AD; # (휂; 휂; 휂; 휂; 휂; ) HANGUL SYLLABLE HWENH
+D703;D703;1112 1170 11AE;D703;1112 1170 11AE; # (휃; 휃; 휃; 휃; 휃; ) HANGUL SYLLABLE HWED
+D704;D704;1112 1170 11AF;D704;1112 1170 11AF; # (휄; 휄; 휄; 휄; 휄; ) HANGUL SYLLABLE HWEL
+D705;D705;1112 1170 11B0;D705;1112 1170 11B0; # (휅; 휅; 휅; 휅; 휅; ) HANGUL SYLLABLE HWELG
+D706;D706;1112 1170 11B1;D706;1112 1170 11B1; # (휆; 휆; 휆; 휆; 휆; ) HANGUL SYLLABLE HWELM
+D707;D707;1112 1170 11B2;D707;1112 1170 11B2; # (휇; 휇; 휇; 휇; 휇; ) HANGUL SYLLABLE HWELB
+D708;D708;1112 1170 11B3;D708;1112 1170 11B3; # (휈; 휈; 휈; 휈; 휈; ) HANGUL SYLLABLE HWELS
+D709;D709;1112 1170 11B4;D709;1112 1170 11B4; # (휉; 휉; 휉; 휉; 휉; ) HANGUL SYLLABLE HWELT
+D70A;D70A;1112 1170 11B5;D70A;1112 1170 11B5; # (휊; 휊; 휊; 휊; 휊; ) HANGUL SYLLABLE HWELP
+D70B;D70B;1112 1170 11B6;D70B;1112 1170 11B6; # (휋; 휋; 휋; 휋; 휋; ) HANGUL SYLLABLE HWELH
+D70C;D70C;1112 1170 11B7;D70C;1112 1170 11B7; # (휌; 휌; 휌; 휌; 휌; ) HANGUL SYLLABLE HWEM
+D70D;D70D;1112 1170 11B8;D70D;1112 1170 11B8; # (휍; 휍; 휍; 휍; 휍; ) HANGUL SYLLABLE HWEB
+D70E;D70E;1112 1170 11B9;D70E;1112 1170 11B9; # (휎; 휎; 휎; 휎; 휎; ) HANGUL SYLLABLE HWEBS
+D70F;D70F;1112 1170 11BA;D70F;1112 1170 11BA; # (휏; 휏; 휏; 휏; 휏; ) HANGUL SYLLABLE HWES
+D710;D710;1112 1170 11BB;D710;1112 1170 11BB; # (휐; 휐; 휐; 휐; 휐; ) HANGUL SYLLABLE HWESS
+D711;D711;1112 1170 11BC;D711;1112 1170 11BC; # (휑; 휑; 휑; 휑; 휑; ) HANGUL SYLLABLE HWENG
+D712;D712;1112 1170 11BD;D712;1112 1170 11BD; # (휒; 휒; 휒; 휒; 휒; ) HANGUL SYLLABLE HWEJ
+D713;D713;1112 1170 11BE;D713;1112 1170 11BE; # (휓; 휓; 휓; 휓; 휓; ) HANGUL SYLLABLE HWEC
+D714;D714;1112 1170 11BF;D714;1112 1170 11BF; # (휔; 휔; 휔; 휔; 휔; ) HANGUL SYLLABLE HWEK
+D715;D715;1112 1170 11C0;D715;1112 1170 11C0; # (휕; 휕; 휕; 휕; 휕; ) HANGUL SYLLABLE HWET
+D716;D716;1112 1170 11C1;D716;1112 1170 11C1; # (휖; 휖; 휖; 휖; 휖; ) HANGUL SYLLABLE HWEP
+D717;D717;1112 1170 11C2;D717;1112 1170 11C2; # (휗; 휗; 휗; 휗; 휗; ) HANGUL SYLLABLE HWEH
+D718;D718;1112 1171;D718;1112 1171; # (휘; 휘; 휘; 휘; 휘; ) HANGUL SYLLABLE HWI
+D719;D719;1112 1171 11A8;D719;1112 1171 11A8; # (휙; 휙; 휙; 휙; 휙; ) HANGUL SYLLABLE HWIG
+D71A;D71A;1112 1171 11A9;D71A;1112 1171 11A9; # (휚; 휚; 휚; 휚; 휚; ) HANGUL SYLLABLE HWIGG
+D71B;D71B;1112 1171 11AA;D71B;1112 1171 11AA; # (휛; 휛; 휛; 휛; 휛; ) HANGUL SYLLABLE HWIGS
+D71C;D71C;1112 1171 11AB;D71C;1112 1171 11AB; # (휜; 휜; 휜; 휜; 휜; ) HANGUL SYLLABLE HWIN
+D71D;D71D;1112 1171 11AC;D71D;1112 1171 11AC; # (휝; 휝; 휝; 휝; 휝; ) HANGUL SYLLABLE HWINJ
+D71E;D71E;1112 1171 11AD;D71E;1112 1171 11AD; # (휞; 휞; 휞; 휞; 휞; ) HANGUL SYLLABLE HWINH
+D71F;D71F;1112 1171 11AE;D71F;1112 1171 11AE; # (휟; 휟; 휟; 휟; 휟; ) HANGUL SYLLABLE HWID
+D720;D720;1112 1171 11AF;D720;1112 1171 11AF; # (휠; 휠; 휠; 휠; 휠; ) HANGUL SYLLABLE HWIL
+D721;D721;1112 1171 11B0;D721;1112 1171 11B0; # (휡; 휡; 휡; 휡; 휡; ) HANGUL SYLLABLE HWILG
+D722;D722;1112 1171 11B1;D722;1112 1171 11B1; # (휢; 휢; 휢; 휢; 휢; ) HANGUL SYLLABLE HWILM
+D723;D723;1112 1171 11B2;D723;1112 1171 11B2; # (휣; 휣; 휣; 휣; 휣; ) HANGUL SYLLABLE HWILB
+D724;D724;1112 1171 11B3;D724;1112 1171 11B3; # (휤; 휤; 휤; 휤; 휤; ) HANGUL SYLLABLE HWILS
+D725;D725;1112 1171 11B4;D725;1112 1171 11B4; # (휥; 휥; 휥; 휥; 휥; ) HANGUL SYLLABLE HWILT
+D726;D726;1112 1171 11B5;D726;1112 1171 11B5; # (휦; 휦; 휦; 휦; 휦; ) HANGUL SYLLABLE HWILP
+D727;D727;1112 1171 11B6;D727;1112 1171 11B6; # (휧; 휧; 휧; 휧; 휧; ) HANGUL SYLLABLE HWILH
+D728;D728;1112 1171 11B7;D728;1112 1171 11B7; # (휨; 휨; 휨; 휨; 휨; ) HANGUL SYLLABLE HWIM
+D729;D729;1112 1171 11B8;D729;1112 1171 11B8; # (휩; 휩; 휩; 휩; 휩; ) HANGUL SYLLABLE HWIB
+D72A;D72A;1112 1171 11B9;D72A;1112 1171 11B9; # (휪; 휪; 휪; 휪; 휪; ) HANGUL SYLLABLE HWIBS
+D72B;D72B;1112 1171 11BA;D72B;1112 1171 11BA; # (휫; 휫; 휫; 휫; 휫; ) HANGUL SYLLABLE HWIS
+D72C;D72C;1112 1171 11BB;D72C;1112 1171 11BB; # (휬; 휬; 휬; 휬; 휬; ) HANGUL SYLLABLE HWISS
+D72D;D72D;1112 1171 11BC;D72D;1112 1171 11BC; # (휭; 휭; 휭; 휭; 휭; ) HANGUL SYLLABLE HWING
+D72E;D72E;1112 1171 11BD;D72E;1112 1171 11BD; # (휮; 휮; 휮; 휮; 휮; ) HANGUL SYLLABLE HWIJ
+D72F;D72F;1112 1171 11BE;D72F;1112 1171 11BE; # (휯; 휯; 휯; 휯; 휯; ) HANGUL SYLLABLE HWIC
+D730;D730;1112 1171 11BF;D730;1112 1171 11BF; # (휰; 휰; 휰; 휰; 휰; ) HANGUL SYLLABLE HWIK
+D731;D731;1112 1171 11C0;D731;1112 1171 11C0; # (휱; 휱; 휱; 휱; 휱; ) HANGUL SYLLABLE HWIT
+D732;D732;1112 1171 11C1;D732;1112 1171 11C1; # (휲; 휲; 휲; 휲; 휲; ) HANGUL SYLLABLE HWIP
+D733;D733;1112 1171 11C2;D733;1112 1171 11C2; # (휳; 휳; 휳; 휳; 휳; ) HANGUL SYLLABLE HWIH
+D734;D734;1112 1172;D734;1112 1172; # (휴; 휴; 휴; 휴; 휴; ) HANGUL SYLLABLE HYU
+D735;D735;1112 1172 11A8;D735;1112 1172 11A8; # (휵; 휵; 휵; 휵; 휵; ) HANGUL SYLLABLE HYUG
+D736;D736;1112 1172 11A9;D736;1112 1172 11A9; # (휶; 휶; 휶; 휶; 휶; ) HANGUL SYLLABLE HYUGG
+D737;D737;1112 1172 11AA;D737;1112 1172 11AA; # (휷; 휷; 휷; 휷; 휷; ) HANGUL SYLLABLE HYUGS
+D738;D738;1112 1172 11AB;D738;1112 1172 11AB; # (휸; 휸; 휸; 휸; 휸; ) HANGUL SYLLABLE HYUN
+D739;D739;1112 1172 11AC;D739;1112 1172 11AC; # (휹; 휹; 휹; 휹; 휹; ) HANGUL SYLLABLE HYUNJ
+D73A;D73A;1112 1172 11AD;D73A;1112 1172 11AD; # (휺; 휺; 휺; 휺; 휺; ) HANGUL SYLLABLE HYUNH
+D73B;D73B;1112 1172 11AE;D73B;1112 1172 11AE; # (휻; 휻; 휻; 휻; 휻; ) HANGUL SYLLABLE HYUD
+D73C;D73C;1112 1172 11AF;D73C;1112 1172 11AF; # (휼; 휼; 휼; 휼; 휼; ) HANGUL SYLLABLE HYUL
+D73D;D73D;1112 1172 11B0;D73D;1112 1172 11B0; # (휽; 휽; 휽; 휽; 휽; ) HANGUL SYLLABLE HYULG
+D73E;D73E;1112 1172 11B1;D73E;1112 1172 11B1; # (휾; 휾; 휾; 휾; 휾; ) HANGUL SYLLABLE HYULM
+D73F;D73F;1112 1172 11B2;D73F;1112 1172 11B2; # (휿; 휿; 휿; 휿; 휿; ) HANGUL SYLLABLE HYULB
+D740;D740;1112 1172 11B3;D740;1112 1172 11B3; # (흀; 흀; 흀; 흀; 흀; ) HANGUL SYLLABLE HYULS
+D741;D741;1112 1172 11B4;D741;1112 1172 11B4; # (흁; 흁; 흁; 흁; 흁; ) HANGUL SYLLABLE HYULT
+D742;D742;1112 1172 11B5;D742;1112 1172 11B5; # (흂; 흂; 흂; 흂; 흂; ) HANGUL SYLLABLE HYULP
+D743;D743;1112 1172 11B6;D743;1112 1172 11B6; # (흃; 흃; 흃; 흃; 흃; ) HANGUL SYLLABLE HYULH
+D744;D744;1112 1172 11B7;D744;1112 1172 11B7; # (흄; 흄; 흄; 흄; 흄; ) HANGUL SYLLABLE HYUM
+D745;D745;1112 1172 11B8;D745;1112 1172 11B8; # (흅; 흅; 흅; 흅; 흅; ) HANGUL SYLLABLE HYUB
+D746;D746;1112 1172 11B9;D746;1112 1172 11B9; # (흆; 흆; 흆; 흆; 흆; ) HANGUL SYLLABLE HYUBS
+D747;D747;1112 1172 11BA;D747;1112 1172 11BA; # (흇; 흇; 흇; 흇; 흇; ) HANGUL SYLLABLE HYUS
+D748;D748;1112 1172 11BB;D748;1112 1172 11BB; # (흈; 흈; 흈; 흈; 흈; ) HANGUL SYLLABLE HYUSS
+D749;D749;1112 1172 11BC;D749;1112 1172 11BC; # (흉; 흉; 흉; 흉; 흉; ) HANGUL SYLLABLE HYUNG
+D74A;D74A;1112 1172 11BD;D74A;1112 1172 11BD; # (흊; 흊; 흊; 흊; 흊; ) HANGUL SYLLABLE HYUJ
+D74B;D74B;1112 1172 11BE;D74B;1112 1172 11BE; # (흋; 흋; 흋; 흋; 흋; ) HANGUL SYLLABLE HYUC
+D74C;D74C;1112 1172 11BF;D74C;1112 1172 11BF; # (흌; 흌; 흌; 흌; 흌; ) HANGUL SYLLABLE HYUK
+D74D;D74D;1112 1172 11C0;D74D;1112 1172 11C0; # (흍; 흍; 흍; 흍; 흍; ) HANGUL SYLLABLE HYUT
+D74E;D74E;1112 1172 11C1;D74E;1112 1172 11C1; # (흎; 흎; 흎; 흎; 흎; ) HANGUL SYLLABLE HYUP
+D74F;D74F;1112 1172 11C2;D74F;1112 1172 11C2; # (흏; 흏; 흏; 흏; 흏; ) HANGUL SYLLABLE HYUH
+D750;D750;1112 1173;D750;1112 1173; # (흐; 흐; 흐; 흐; 흐; ) HANGUL SYLLABLE HEU
+D751;D751;1112 1173 11A8;D751;1112 1173 11A8; # (흑; 흑; 흑; 흑; 흑; ) HANGUL SYLLABLE HEUG
+D752;D752;1112 1173 11A9;D752;1112 1173 11A9; # (흒; 흒; 흒; 흒; 흒; ) HANGUL SYLLABLE HEUGG
+D753;D753;1112 1173 11AA;D753;1112 1173 11AA; # (흓; 흓; 흓; 흓; 흓; ) HANGUL SYLLABLE HEUGS
+D754;D754;1112 1173 11AB;D754;1112 1173 11AB; # (흔; 흔; 흔; 흔; 흔; ) HANGUL SYLLABLE HEUN
+D755;D755;1112 1173 11AC;D755;1112 1173 11AC; # (흕; 흕; 흕; 흕; 흕; ) HANGUL SYLLABLE HEUNJ
+D756;D756;1112 1173 11AD;D756;1112 1173 11AD; # (흖; 흖; 흖; 흖; 흖; ) HANGUL SYLLABLE HEUNH
+D757;D757;1112 1173 11AE;D757;1112 1173 11AE; # (흗; 흗; 흗; 흗; 흗; ) HANGUL SYLLABLE HEUD
+D758;D758;1112 1173 11AF;D758;1112 1173 11AF; # (흘; 흘; 흘; 흘; 흘; ) HANGUL SYLLABLE HEUL
+D759;D759;1112 1173 11B0;D759;1112 1173 11B0; # (흙; 흙; 흙; 흙; 흙; ) HANGUL SYLLABLE HEULG
+D75A;D75A;1112 1173 11B1;D75A;1112 1173 11B1; # (흚; 흚; 흚; 흚; 흚; ) HANGUL SYLLABLE HEULM
+D75B;D75B;1112 1173 11B2;D75B;1112 1173 11B2; # (흛; 흛; 흛; 흛; 흛; ) HANGUL SYLLABLE HEULB
+D75C;D75C;1112 1173 11B3;D75C;1112 1173 11B3; # (흜; 흜; 흜; 흜; 흜; ) HANGUL SYLLABLE HEULS
+D75D;D75D;1112 1173 11B4;D75D;1112 1173 11B4; # (흝; 흝; 흝; 흝; 흝; ) HANGUL SYLLABLE HEULT
+D75E;D75E;1112 1173 11B5;D75E;1112 1173 11B5; # (흞; 흞; 흞; 흞; 흞; ) HANGUL SYLLABLE HEULP
+D75F;D75F;1112 1173 11B6;D75F;1112 1173 11B6; # (흟; 흟; 흟; 흟; 흟; ) HANGUL SYLLABLE HEULH
+D760;D760;1112 1173 11B7;D760;1112 1173 11B7; # (흠; 흠; 흠; 흠; 흠; ) HANGUL SYLLABLE HEUM
+D761;D761;1112 1173 11B8;D761;1112 1173 11B8; # (흡; 흡; 흡; 흡; 흡; ) HANGUL SYLLABLE HEUB
+D762;D762;1112 1173 11B9;D762;1112 1173 11B9; # (흢; 흢; 흢; 흢; 흢; ) HANGUL SYLLABLE HEUBS
+D763;D763;1112 1173 11BA;D763;1112 1173 11BA; # (흣; 흣; 흣; 흣; 흣; ) HANGUL SYLLABLE HEUS
+D764;D764;1112 1173 11BB;D764;1112 1173 11BB; # (흤; 흤; 흤; 흤; 흤; ) HANGUL SYLLABLE HEUSS
+D765;D765;1112 1173 11BC;D765;1112 1173 11BC; # (흥; 흥; 흥; 흥; 흥; ) HANGUL SYLLABLE HEUNG
+D766;D766;1112 1173 11BD;D766;1112 1173 11BD; # (흦; 흦; 흦; 흦; 흦; ) HANGUL SYLLABLE HEUJ
+D767;D767;1112 1173 11BE;D767;1112 1173 11BE; # (흧; 흧; 흧; 흧; 흧; ) HANGUL SYLLABLE HEUC
+D768;D768;1112 1173 11BF;D768;1112 1173 11BF; # (흨; 흨; 흨; 흨; 흨; ) HANGUL SYLLABLE HEUK
+D769;D769;1112 1173 11C0;D769;1112 1173 11C0; # (흩; 흩; 흩; 흩; 흩; ) HANGUL SYLLABLE HEUT
+D76A;D76A;1112 1173 11C1;D76A;1112 1173 11C1; # (흪; 흪; 흪; 흪; 흪; ) HANGUL SYLLABLE HEUP
+D76B;D76B;1112 1173 11C2;D76B;1112 1173 11C2; # (흫; 흫; 흫; 흫; 흫; ) HANGUL SYLLABLE HEUH
+D76C;D76C;1112 1174;D76C;1112 1174; # (희; 희; 희; 희; 희; ) HANGUL SYLLABLE HYI
+D76D;D76D;1112 1174 11A8;D76D;1112 1174 11A8; # (흭; 흭; 흭; 흭; 흭; ) HANGUL SYLLABLE HYIG
+D76E;D76E;1112 1174 11A9;D76E;1112 1174 11A9; # (흮; 흮; 흮; 흮; 흮; ) HANGUL SYLLABLE HYIGG
+D76F;D76F;1112 1174 11AA;D76F;1112 1174 11AA; # (흯; 흯; 흯; 흯; 흯; ) HANGUL SYLLABLE HYIGS
+D770;D770;1112 1174 11AB;D770;1112 1174 11AB; # (흰; 흰; 흰; 흰; 흰; ) HANGUL SYLLABLE HYIN
+D771;D771;1112 1174 11AC;D771;1112 1174 11AC; # (흱; 흱; 흱; 흱; 흱; ) HANGUL SYLLABLE HYINJ
+D772;D772;1112 1174 11AD;D772;1112 1174 11AD; # (흲; 흲; 흲; 흲; 흲; ) HANGUL SYLLABLE HYINH
+D773;D773;1112 1174 11AE;D773;1112 1174 11AE; # (흳; 흳; 흳; 흳; 흳; ) HANGUL SYLLABLE HYID
+D774;D774;1112 1174 11AF;D774;1112 1174 11AF; # (흴; 흴; 흴; 흴; 흴; ) HANGUL SYLLABLE HYIL
+D775;D775;1112 1174 11B0;D775;1112 1174 11B0; # (흵; 흵; 흵; 흵; 흵; ) HANGUL SYLLABLE HYILG
+D776;D776;1112 1174 11B1;D776;1112 1174 11B1; # (흶; 흶; 흶; 흶; 흶; ) HANGUL SYLLABLE HYILM
+D777;D777;1112 1174 11B2;D777;1112 1174 11B2; # (흷; 흷; 흷; 흷; 흷; ) HANGUL SYLLABLE HYILB
+D778;D778;1112 1174 11B3;D778;1112 1174 11B3; # (흸; 흸; 흸; 흸; 흸; ) HANGUL SYLLABLE HYILS
+D779;D779;1112 1174 11B4;D779;1112 1174 11B4; # (흹; 흹; 흹; 흹; 흹; ) HANGUL SYLLABLE HYILT
+D77A;D77A;1112 1174 11B5;D77A;1112 1174 11B5; # (흺; 흺; 흺; 흺; 흺; ) HANGUL SYLLABLE HYILP
+D77B;D77B;1112 1174 11B6;D77B;1112 1174 11B6; # (흻; 흻; 흻; 흻; 흻; ) HANGUL SYLLABLE HYILH
+D77C;D77C;1112 1174 11B7;D77C;1112 1174 11B7; # (흼; 흼; 흼; 흼; 흼; ) HANGUL SYLLABLE HYIM
+D77D;D77D;1112 1174 11B8;D77D;1112 1174 11B8; # (흽; 흽; 흽; 흽; 흽; ) HANGUL SYLLABLE HYIB
+D77E;D77E;1112 1174 11B9;D77E;1112 1174 11B9; # (흾; 흾; 흾; 흾; 흾; ) HANGUL SYLLABLE HYIBS
+D77F;D77F;1112 1174 11BA;D77F;1112 1174 11BA; # (흿; 흿; 흿; 흿; 흿; ) HANGUL SYLLABLE HYIS
+D780;D780;1112 1174 11BB;D780;1112 1174 11BB; # (힀; 힀; 힀; 힀; 힀; ) HANGUL SYLLABLE HYISS
+D781;D781;1112 1174 11BC;D781;1112 1174 11BC; # (힁; 힁; 힁; 힁; 힁; ) HANGUL SYLLABLE HYING
+D782;D782;1112 1174 11BD;D782;1112 1174 11BD; # (힂; 힂; 힂; 힂; 힂; ) HANGUL SYLLABLE HYIJ
+D783;D783;1112 1174 11BE;D783;1112 1174 11BE; # (힃; 힃; 힃; 힃; 힃; ) HANGUL SYLLABLE HYIC
+D784;D784;1112 1174 11BF;D784;1112 1174 11BF; # (힄; 힄; 힄; 힄; 힄; ) HANGUL SYLLABLE HYIK
+D785;D785;1112 1174 11C0;D785;1112 1174 11C0; # (힅; 힅; 힅; 힅; 힅; ) HANGUL SYLLABLE HYIT
+D786;D786;1112 1174 11C1;D786;1112 1174 11C1; # (힆; 힆; 힆; 힆; 힆; ) HANGUL SYLLABLE HYIP
+D787;D787;1112 1174 11C2;D787;1112 1174 11C2; # (힇; 힇; 힇; 힇; 힇; ) HANGUL SYLLABLE HYIH
+D788;D788;1112 1175;D788;1112 1175; # (히; 히; 히; 히; 히; ) HANGUL SYLLABLE HI
+D789;D789;1112 1175 11A8;D789;1112 1175 11A8; # (힉; 힉; 힉; 힉; 힉; ) HANGUL SYLLABLE HIG
+D78A;D78A;1112 1175 11A9;D78A;1112 1175 11A9; # (힊; 힊; 힊; 힊; 힊; ) HANGUL SYLLABLE HIGG
+D78B;D78B;1112 1175 11AA;D78B;1112 1175 11AA; # (힋; 힋; 힋; 힋; 힋; ) HANGUL SYLLABLE HIGS
+D78C;D78C;1112 1175 11AB;D78C;1112 1175 11AB; # (힌; 힌; 힌; 힌; 힌; ) HANGUL SYLLABLE HIN
+D78D;D78D;1112 1175 11AC;D78D;1112 1175 11AC; # (힍; 힍; 힍; 힍; 힍; ) HANGUL SYLLABLE HINJ
+D78E;D78E;1112 1175 11AD;D78E;1112 1175 11AD; # (힎; 힎; 힎; 힎; 힎; ) HANGUL SYLLABLE HINH
+D78F;D78F;1112 1175 11AE;D78F;1112 1175 11AE; # (힏; 힏; 힏; 힏; 힏; ) HANGUL SYLLABLE HID
+D790;D790;1112 1175 11AF;D790;1112 1175 11AF; # (힐; 힐; 힐; 힐; 힐; ) HANGUL SYLLABLE HIL
+D791;D791;1112 1175 11B0;D791;1112 1175 11B0; # (힑; 힑; 힑; 힑; 힑; ) HANGUL SYLLABLE HILG
+D792;D792;1112 1175 11B1;D792;1112 1175 11B1; # (힒; 힒; 힒; 힒; 힒; ) HANGUL SYLLABLE HILM
+D793;D793;1112 1175 11B2;D793;1112 1175 11B2; # (힓; 힓; 힓; 힓; 힓; ) HANGUL SYLLABLE HILB
+D794;D794;1112 1175 11B3;D794;1112 1175 11B3; # (힔; 힔; 힔; 힔; 힔; ) HANGUL SYLLABLE HILS
+D795;D795;1112 1175 11B4;D795;1112 1175 11B4; # (힕; 힕; 힕; 힕; 힕; ) HANGUL SYLLABLE HILT
+D796;D796;1112 1175 11B5;D796;1112 1175 11B5; # (힖; 힖; 힖; 힖; 힖; ) HANGUL SYLLABLE HILP
+D797;D797;1112 1175 11B6;D797;1112 1175 11B6; # (힗; 힗; 힗; 힗; 힗; ) HANGUL SYLLABLE HILH
+D798;D798;1112 1175 11B7;D798;1112 1175 11B7; # (힘; 힘; 힘; 힘; 힘; ) HANGUL SYLLABLE HIM
+D799;D799;1112 1175 11B8;D799;1112 1175 11B8; # (힙; 힙; 힙; 힙; 힙; ) HANGUL SYLLABLE HIB
+D79A;D79A;1112 1175 11B9;D79A;1112 1175 11B9; # (힚; 힚; 힚; 힚; 힚; ) HANGUL SYLLABLE HIBS
+D79B;D79B;1112 1175 11BA;D79B;1112 1175 11BA; # (힛; 힛; 힛; 힛; 힛; ) HANGUL SYLLABLE HIS
+D79C;D79C;1112 1175 11BB;D79C;1112 1175 11BB; # (힜; 힜; 힜; 힜; 힜; ) HANGUL SYLLABLE HISS
+D79D;D79D;1112 1175 11BC;D79D;1112 1175 11BC; # (힝; 힝; 힝; 힝; 힝; ) HANGUL SYLLABLE HING
+D79E;D79E;1112 1175 11BD;D79E;1112 1175 11BD; # (힞; 힞; 힞; 힞; 힞; ) HANGUL SYLLABLE HIJ
+D79F;D79F;1112 1175 11BE;D79F;1112 1175 11BE; # (힟; 힟; 힟; 힟; 힟; ) HANGUL SYLLABLE HIC
+D7A0;D7A0;1112 1175 11BF;D7A0;1112 1175 11BF; # (힠; 힠; 힠; 힠; 힠; ) HANGUL SYLLABLE HIK
+D7A1;D7A1;1112 1175 11C0;D7A1;1112 1175 11C0; # (힡; 힡; 힡; 힡; 힡; ) HANGUL SYLLABLE HIT
+D7A2;D7A2;1112 1175 11C1;D7A2;1112 1175 11C1; # (힢; 힢; 힢; 힢; 힢; ) HANGUL SYLLABLE HIP
+D7A3;D7A3;1112 1175 11C2;D7A3;1112 1175 11C2; # (힣; 힣; 힣; 힣; 힣; ) HANGUL SYLLABLE HIH
+F900;8C48;8C48;8C48;8C48; # (豈; 豈; 豈; 豈; 豈; ) CJK COMPATIBILITY IDEOGRAPH-F900
+F901;66F4;66F4;66F4;66F4; # (更; 更; 更; 更; 更; ) CJK COMPATIBILITY IDEOGRAPH-F901
+F902;8ECA;8ECA;8ECA;8ECA; # (車; 車; 車; 車; 車; ) CJK COMPATIBILITY IDEOGRAPH-F902
+F903;8CC8;8CC8;8CC8;8CC8; # (賈; 賈; 賈; 賈; 賈; ) CJK COMPATIBILITY IDEOGRAPH-F903
+F904;6ED1;6ED1;6ED1;6ED1; # (滑; 滑; 滑; 滑; 滑; ) CJK COMPATIBILITY IDEOGRAPH-F904
+F905;4E32;4E32;4E32;4E32; # (串; 串; 串; 串; 串; ) CJK COMPATIBILITY IDEOGRAPH-F905
+F906;53E5;53E5;53E5;53E5; # (句; 句; 句; 句; 句; ) CJK COMPATIBILITY IDEOGRAPH-F906
+F907;9F9C;9F9C;9F9C;9F9C; # (龜; 龜; 龜; 龜; 龜; ) CJK COMPATIBILITY IDEOGRAPH-F907
+F908;9F9C;9F9C;9F9C;9F9C; # (龜; 龜; 龜; 龜; 龜; ) CJK COMPATIBILITY IDEOGRAPH-F908
+F909;5951;5951;5951;5951; # (契; 契; 契; 契; 契; ) CJK COMPATIBILITY IDEOGRAPH-F909
+F90A;91D1;91D1;91D1;91D1; # (金; 金; 金; 金; 金; ) CJK COMPATIBILITY IDEOGRAPH-F90A
+F90B;5587;5587;5587;5587; # (喇; 喇; 喇; 喇; 喇; ) CJK COMPATIBILITY IDEOGRAPH-F90B
+F90C;5948;5948;5948;5948; # (奈; 奈; 奈; 奈; 奈; ) CJK COMPATIBILITY IDEOGRAPH-F90C
+F90D;61F6;61F6;61F6;61F6; # (懶; 懶; 懶; 懶; 懶; ) CJK COMPATIBILITY IDEOGRAPH-F90D
+F90E;7669;7669;7669;7669; # (癩; 癩; 癩; 癩; 癩; ) CJK COMPATIBILITY IDEOGRAPH-F90E
+F90F;7F85;7F85;7F85;7F85; # (羅; 羅; 羅; 羅; 羅; ) CJK COMPATIBILITY IDEOGRAPH-F90F
+F910;863F;863F;863F;863F; # (蘿; 蘿; 蘿; 蘿; 蘿; ) CJK COMPATIBILITY IDEOGRAPH-F910
+F911;87BA;87BA;87BA;87BA; # (螺; 螺; 螺; 螺; 螺; ) CJK COMPATIBILITY IDEOGRAPH-F911
+F912;88F8;88F8;88F8;88F8; # (裸; 裸; 裸; 裸; 裸; ) CJK COMPATIBILITY IDEOGRAPH-F912
+F913;908F;908F;908F;908F; # (邏; 邏; 邏; 邏; 邏; ) CJK COMPATIBILITY IDEOGRAPH-F913
+F914;6A02;6A02;6A02;6A02; # (樂; 樂; 樂; 樂; 樂; ) CJK COMPATIBILITY IDEOGRAPH-F914
+F915;6D1B;6D1B;6D1B;6D1B; # (洛; 洛; 洛; 洛; 洛; ) CJK COMPATIBILITY IDEOGRAPH-F915
+F916;70D9;70D9;70D9;70D9; # (烙; 烙; 烙; 烙; 烙; ) CJK COMPATIBILITY IDEOGRAPH-F916
+F917;73DE;73DE;73DE;73DE; # (珞; 珞; 珞; 珞; 珞; ) CJK COMPATIBILITY IDEOGRAPH-F917
+F918;843D;843D;843D;843D; # (落; 落; 落; 落; 落; ) CJK COMPATIBILITY IDEOGRAPH-F918
+F919;916A;916A;916A;916A; # (酪; 酪; 酪; 酪; 酪; ) CJK COMPATIBILITY IDEOGRAPH-F919
+F91A;99F1;99F1;99F1;99F1; # (駱; 駱; 駱; 駱; 駱; ) CJK COMPATIBILITY IDEOGRAPH-F91A
+F91B;4E82;4E82;4E82;4E82; # (亂; 亂; 亂; 亂; 亂; ) CJK COMPATIBILITY IDEOGRAPH-F91B
+F91C;5375;5375;5375;5375; # (卵; 卵; 卵; 卵; 卵; ) CJK COMPATIBILITY IDEOGRAPH-F91C
+F91D;6B04;6B04;6B04;6B04; # (欄; 欄; 欄; 欄; 欄; ) CJK COMPATIBILITY IDEOGRAPH-F91D
+F91E;721B;721B;721B;721B; # (爛; 爛; 爛; 爛; 爛; ) CJK COMPATIBILITY IDEOGRAPH-F91E
+F91F;862D;862D;862D;862D; # (蘭; 蘭; 蘭; 蘭; 蘭; ) CJK COMPATIBILITY IDEOGRAPH-F91F
+F920;9E1E;9E1E;9E1E;9E1E; # (鸞; 鸞; 鸞; 鸞; 鸞; ) CJK COMPATIBILITY IDEOGRAPH-F920
+F921;5D50;5D50;5D50;5D50; # (嵐; 嵐; 嵐; 嵐; 嵐; ) CJK COMPATIBILITY IDEOGRAPH-F921
+F922;6FEB;6FEB;6FEB;6FEB; # (濫; 濫; 濫; 濫; 濫; ) CJK COMPATIBILITY IDEOGRAPH-F922
+F923;85CD;85CD;85CD;85CD; # (藍; 藍; 藍; 藍; 藍; ) CJK COMPATIBILITY IDEOGRAPH-F923
+F924;8964;8964;8964;8964; # (襤; 襤; 襤; 襤; 襤; ) CJK COMPATIBILITY IDEOGRAPH-F924
+F925;62C9;62C9;62C9;62C9; # (拉; 拉; 拉; 拉; 拉; ) CJK COMPATIBILITY IDEOGRAPH-F925
+F926;81D8;81D8;81D8;81D8; # (臘; 臘; 臘; 臘; 臘; ) CJK COMPATIBILITY IDEOGRAPH-F926
+F927;881F;881F;881F;881F; # (蠟; 蠟; 蠟; 蠟; 蠟; ) CJK COMPATIBILITY IDEOGRAPH-F927
+F928;5ECA;5ECA;5ECA;5ECA; # (廊; 廊; 廊; 廊; 廊; ) CJK COMPATIBILITY IDEOGRAPH-F928
+F929;6717;6717;6717;6717; # (朗; 朗; 朗; 朗; 朗; ) CJK COMPATIBILITY IDEOGRAPH-F929
+F92A;6D6A;6D6A;6D6A;6D6A; # (浪; 浪; 浪; 浪; 浪; ) CJK COMPATIBILITY IDEOGRAPH-F92A
+F92B;72FC;72FC;72FC;72FC; # (狼; 狼; 狼; 狼; 狼; ) CJK COMPATIBILITY IDEOGRAPH-F92B
+F92C;90CE;90CE;90CE;90CE; # (郎; 郎; 郎; 郎; 郎; ) CJK COMPATIBILITY IDEOGRAPH-F92C
+F92D;4F86;4F86;4F86;4F86; # (來; 來; 來; 來; 來; ) CJK COMPATIBILITY IDEOGRAPH-F92D
+F92E;51B7;51B7;51B7;51B7; # (冷; 冷; 冷; 冷; 冷; ) CJK COMPATIBILITY IDEOGRAPH-F92E
+F92F;52DE;52DE;52DE;52DE; # (勞; 勞; 勞; 勞; 勞; ) CJK COMPATIBILITY IDEOGRAPH-F92F
+F930;64C4;64C4;64C4;64C4; # (擄; 擄; 擄; 擄; 擄; ) CJK COMPATIBILITY IDEOGRAPH-F930
+F931;6AD3;6AD3;6AD3;6AD3; # (櫓; 櫓; 櫓; 櫓; 櫓; ) CJK COMPATIBILITY IDEOGRAPH-F931
+F932;7210;7210;7210;7210; # (爐; 爐; 爐; 爐; 爐; ) CJK COMPATIBILITY IDEOGRAPH-F932
+F933;76E7;76E7;76E7;76E7; # (盧; 盧; 盧; 盧; 盧; ) CJK COMPATIBILITY IDEOGRAPH-F933
+F934;8001;8001;8001;8001; # (老; 老; 老; 老; 老; ) CJK COMPATIBILITY IDEOGRAPH-F934
+F935;8606;8606;8606;8606; # (蘆; 蘆; 蘆; 蘆; 蘆; ) CJK COMPATIBILITY IDEOGRAPH-F935
+F936;865C;865C;865C;865C; # (虜; 虜; 虜; 虜; 虜; ) CJK COMPATIBILITY IDEOGRAPH-F936
+F937;8DEF;8DEF;8DEF;8DEF; # (路; 路; 路; 路; 路; ) CJK COMPATIBILITY IDEOGRAPH-F937
+F938;9732;9732;9732;9732; # (露; 露; 露; 露; 露; ) CJK COMPATIBILITY IDEOGRAPH-F938
+F939;9B6F;9B6F;9B6F;9B6F; # (魯; 魯; 魯; 魯; 魯; ) CJK COMPATIBILITY IDEOGRAPH-F939
+F93A;9DFA;9DFA;9DFA;9DFA; # (鷺; 鷺; 鷺; 鷺; 鷺; ) CJK COMPATIBILITY IDEOGRAPH-F93A
+F93B;788C;788C;788C;788C; # (碌; 碌; 碌; 碌; 碌; ) CJK COMPATIBILITY IDEOGRAPH-F93B
+F93C;797F;797F;797F;797F; # (祿; 祿; 祿; 祿; 祿; ) CJK COMPATIBILITY IDEOGRAPH-F93C
+F93D;7DA0;7DA0;7DA0;7DA0; # (綠; 綠; 綠; 綠; 綠; ) CJK COMPATIBILITY IDEOGRAPH-F93D
+F93E;83C9;83C9;83C9;83C9; # (菉; 菉; 菉; 菉; 菉; ) CJK COMPATIBILITY IDEOGRAPH-F93E
+F93F;9304;9304;9304;9304; # (錄; 錄; 錄; 錄; 錄; ) CJK COMPATIBILITY IDEOGRAPH-F93F
+F940;9E7F;9E7F;9E7F;9E7F; # (鹿; 鹿; 鹿; 鹿; 鹿; ) CJK COMPATIBILITY IDEOGRAPH-F940
+F941;8AD6;8AD6;8AD6;8AD6; # (論; 論; 論; 論; 論; ) CJK COMPATIBILITY IDEOGRAPH-F941
+F942;58DF;58DF;58DF;58DF; # (壟; 壟; 壟; 壟; 壟; ) CJK COMPATIBILITY IDEOGRAPH-F942
+F943;5F04;5F04;5F04;5F04; # (弄; 弄; 弄; 弄; 弄; ) CJK COMPATIBILITY IDEOGRAPH-F943
+F944;7C60;7C60;7C60;7C60; # (籠; 籠; 籠; 籠; 籠; ) CJK COMPATIBILITY IDEOGRAPH-F944
+F945;807E;807E;807E;807E; # (聾; 聾; 聾; 聾; 聾; ) CJK COMPATIBILITY IDEOGRAPH-F945
+F946;7262;7262;7262;7262; # (牢; 牢; 牢; 牢; 牢; ) CJK COMPATIBILITY IDEOGRAPH-F946
+F947;78CA;78CA;78CA;78CA; # (磊; 磊; 磊; 磊; 磊; ) CJK COMPATIBILITY IDEOGRAPH-F947
+F948;8CC2;8CC2;8CC2;8CC2; # (賂; 賂; 賂; 賂; 賂; ) CJK COMPATIBILITY IDEOGRAPH-F948
+F949;96F7;96F7;96F7;96F7; # (雷; 雷; 雷; 雷; 雷; ) CJK COMPATIBILITY IDEOGRAPH-F949
+F94A;58D8;58D8;58D8;58D8; # (壘; 壘; 壘; 壘; 壘; ) CJK COMPATIBILITY IDEOGRAPH-F94A
+F94B;5C62;5C62;5C62;5C62; # (屢; 屢; 屢; 屢; 屢; ) CJK COMPATIBILITY IDEOGRAPH-F94B
+F94C;6A13;6A13;6A13;6A13; # (樓; 樓; 樓; 樓; 樓; ) CJK COMPATIBILITY IDEOGRAPH-F94C
+F94D;6DDA;6DDA;6DDA;6DDA; # (淚; 淚; 淚; 淚; 淚; ) CJK COMPATIBILITY IDEOGRAPH-F94D
+F94E;6F0F;6F0F;6F0F;6F0F; # (漏; 漏; 漏; 漏; 漏; ) CJK COMPATIBILITY IDEOGRAPH-F94E
+F94F;7D2F;7D2F;7D2F;7D2F; # (累; 累; 累; 累; 累; ) CJK COMPATIBILITY IDEOGRAPH-F94F
+F950;7E37;7E37;7E37;7E37; # (縷; 縷; 縷; 縷; 縷; ) CJK COMPATIBILITY IDEOGRAPH-F950
+F951;964B;964B;964B;964B; # (陋; 陋; 陋; 陋; 陋; ) CJK COMPATIBILITY IDEOGRAPH-F951
+F952;52D2;52D2;52D2;52D2; # (勒; 勒; 勒; 勒; 勒; ) CJK COMPATIBILITY IDEOGRAPH-F952
+F953;808B;808B;808B;808B; # (肋; 肋; 肋; 肋; 肋; ) CJK COMPATIBILITY IDEOGRAPH-F953
+F954;51DC;51DC;51DC;51DC; # (凜; 凜; 凜; 凜; 凜; ) CJK COMPATIBILITY IDEOGRAPH-F954
+F955;51CC;51CC;51CC;51CC; # (凌; 凌; 凌; 凌; 凌; ) CJK COMPATIBILITY IDEOGRAPH-F955
+F956;7A1C;7A1C;7A1C;7A1C; # (稜; 稜; 稜; 稜; 稜; ) CJK COMPATIBILITY IDEOGRAPH-F956
+F957;7DBE;7DBE;7DBE;7DBE; # (綾; 綾; 綾; 綾; 綾; ) CJK COMPATIBILITY IDEOGRAPH-F957
+F958;83F1;83F1;83F1;83F1; # (菱; 菱; 菱; 菱; 菱; ) CJK COMPATIBILITY IDEOGRAPH-F958
+F959;9675;9675;9675;9675; # (陵; 陵; 陵; 陵; 陵; ) CJK COMPATIBILITY IDEOGRAPH-F959
+F95A;8B80;8B80;8B80;8B80; # (讀; 讀; 讀; 讀; 讀; ) CJK COMPATIBILITY IDEOGRAPH-F95A
+F95B;62CF;62CF;62CF;62CF; # (拏; 拏; 拏; 拏; 拏; ) CJK COMPATIBILITY IDEOGRAPH-F95B
+F95C;6A02;6A02;6A02;6A02; # (樂; 樂; 樂; 樂; 樂; ) CJK COMPATIBILITY IDEOGRAPH-F95C
+F95D;8AFE;8AFE;8AFE;8AFE; # (諾; 諾; 諾; 諾; 諾; ) CJK COMPATIBILITY IDEOGRAPH-F95D
+F95E;4E39;4E39;4E39;4E39; # (丹; 丹; 丹; 丹; 丹; ) CJK COMPATIBILITY IDEOGRAPH-F95E
+F95F;5BE7;5BE7;5BE7;5BE7; # (寧; 寧; 寧; 寧; 寧; ) CJK COMPATIBILITY IDEOGRAPH-F95F
+F960;6012;6012;6012;6012; # (怒; 怒; 怒; 怒; 怒; ) CJK COMPATIBILITY IDEOGRAPH-F960
+F961;7387;7387;7387;7387; # (率; 率; 率; 率; 率; ) CJK COMPATIBILITY IDEOGRAPH-F961
+F962;7570;7570;7570;7570; # (異; 異; 異; 異; 異; ) CJK COMPATIBILITY IDEOGRAPH-F962
+F963;5317;5317;5317;5317; # (北; 北; 北; 北; 北; ) CJK COMPATIBILITY IDEOGRAPH-F963
+F964;78FB;78FB;78FB;78FB; # (磻; 磻; 磻; 磻; 磻; ) CJK COMPATIBILITY IDEOGRAPH-F964
+F965;4FBF;4FBF;4FBF;4FBF; # (便; 便; 便; 便; 便; ) CJK COMPATIBILITY IDEOGRAPH-F965
+F966;5FA9;5FA9;5FA9;5FA9; # (復; 復; 復; 復; 復; ) CJK COMPATIBILITY IDEOGRAPH-F966
+F967;4E0D;4E0D;4E0D;4E0D; # (不; 不; 不; 不; 不; ) CJK COMPATIBILITY IDEOGRAPH-F967
+F968;6CCC;6CCC;6CCC;6CCC; # (泌; 泌; 泌; 泌; 泌; ) CJK COMPATIBILITY IDEOGRAPH-F968
+F969;6578;6578;6578;6578; # (數; 數; 數; 數; 數; ) CJK COMPATIBILITY IDEOGRAPH-F969
+F96A;7D22;7D22;7D22;7D22; # (索; 索; 索; 索; 索; ) CJK COMPATIBILITY IDEOGRAPH-F96A
+F96B;53C3;53C3;53C3;53C3; # (參; 參; 參; 參; 參; ) CJK COMPATIBILITY IDEOGRAPH-F96B
+F96C;585E;585E;585E;585E; # (塞; 塞; 塞; 塞; 塞; ) CJK COMPATIBILITY IDEOGRAPH-F96C
+F96D;7701;7701;7701;7701; # (省; 省; 省; 省; 省; ) CJK COMPATIBILITY IDEOGRAPH-F96D
+F96E;8449;8449;8449;8449; # (葉; 葉; 葉; 葉; 葉; ) CJK COMPATIBILITY IDEOGRAPH-F96E
+F96F;8AAA;8AAA;8AAA;8AAA; # (說; 說; 說; 說; 說; ) CJK COMPATIBILITY IDEOGRAPH-F96F
+F970;6BBA;6BBA;6BBA;6BBA; # (殺; 殺; 殺; 殺; 殺; ) CJK COMPATIBILITY IDEOGRAPH-F970
+F971;8FB0;8FB0;8FB0;8FB0; # (辰; 辰; 辰; 辰; 辰; ) CJK COMPATIBILITY IDEOGRAPH-F971
+F972;6C88;6C88;6C88;6C88; # (沈; 沈; 沈; 沈; 沈; ) CJK COMPATIBILITY IDEOGRAPH-F972
+F973;62FE;62FE;62FE;62FE; # (拾; 拾; 拾; 拾; 拾; ) CJK COMPATIBILITY IDEOGRAPH-F973
+F974;82E5;82E5;82E5;82E5; # (若; 若; 若; 若; 若; ) CJK COMPATIBILITY IDEOGRAPH-F974
+F975;63A0;63A0;63A0;63A0; # (掠; 掠; 掠; 掠; 掠; ) CJK COMPATIBILITY IDEOGRAPH-F975
+F976;7565;7565;7565;7565; # (略; 略; 略; 略; 略; ) CJK COMPATIBILITY IDEOGRAPH-F976
+F977;4EAE;4EAE;4EAE;4EAE; # (亮; 亮; 亮; 亮; 亮; ) CJK COMPATIBILITY IDEOGRAPH-F977
+F978;5169;5169;5169;5169; # (兩; 兩; 兩; 兩; 兩; ) CJK COMPATIBILITY IDEOGRAPH-F978
+F979;51C9;51C9;51C9;51C9; # (凉; 凉; 凉; 凉; 凉; ) CJK COMPATIBILITY IDEOGRAPH-F979
+F97A;6881;6881;6881;6881; # (梁; 梁; 梁; 梁; 梁; ) CJK COMPATIBILITY IDEOGRAPH-F97A
+F97B;7CE7;7CE7;7CE7;7CE7; # (糧; 糧; 糧; 糧; 糧; ) CJK COMPATIBILITY IDEOGRAPH-F97B
+F97C;826F;826F;826F;826F; # (良; 良; 良; 良; 良; ) CJK COMPATIBILITY IDEOGRAPH-F97C
+F97D;8AD2;8AD2;8AD2;8AD2; # (諒; 諒; 諒; 諒; 諒; ) CJK COMPATIBILITY IDEOGRAPH-F97D
+F97E;91CF;91CF;91CF;91CF; # (量; 量; 量; 量; 量; ) CJK COMPATIBILITY IDEOGRAPH-F97E
+F97F;52F5;52F5;52F5;52F5; # (勵; 勵; 勵; 勵; 勵; ) CJK COMPATIBILITY IDEOGRAPH-F97F
+F980;5442;5442;5442;5442; # (呂; 呂; 呂; 呂; 呂; ) CJK COMPATIBILITY IDEOGRAPH-F980
+F981;5973;5973;5973;5973; # (女; 女; 女; 女; 女; ) CJK COMPATIBILITY IDEOGRAPH-F981
+F982;5EEC;5EEC;5EEC;5EEC; # (廬; 廬; 廬; 廬; 廬; ) CJK COMPATIBILITY IDEOGRAPH-F982
+F983;65C5;65C5;65C5;65C5; # (旅; 旅; 旅; 旅; 旅; ) CJK COMPATIBILITY IDEOGRAPH-F983
+F984;6FFE;6FFE;6FFE;6FFE; # (濾; 濾; 濾; 濾; 濾; ) CJK COMPATIBILITY IDEOGRAPH-F984
+F985;792A;792A;792A;792A; # (礪; 礪; 礪; 礪; 礪; ) CJK COMPATIBILITY IDEOGRAPH-F985
+F986;95AD;95AD;95AD;95AD; # (閭; 閭; 閭; 閭; 閭; ) CJK COMPATIBILITY IDEOGRAPH-F986
+F987;9A6A;9A6A;9A6A;9A6A; # (驪; 驪; 驪; 驪; 驪; ) CJK COMPATIBILITY IDEOGRAPH-F987
+F988;9E97;9E97;9E97;9E97; # (麗; 麗; 麗; 麗; 麗; ) CJK COMPATIBILITY IDEOGRAPH-F988
+F989;9ECE;9ECE;9ECE;9ECE; # (黎; 黎; 黎; 黎; 黎; ) CJK COMPATIBILITY IDEOGRAPH-F989
+F98A;529B;529B;529B;529B; # (力; 力; 力; 力; 力; ) CJK COMPATIBILITY IDEOGRAPH-F98A
+F98B;66C6;66C6;66C6;66C6; # (曆; 曆; 曆; 曆; 曆; ) CJK COMPATIBILITY IDEOGRAPH-F98B
+F98C;6B77;6B77;6B77;6B77; # (歷; 歷; 歷; 歷; 歷; ) CJK COMPATIBILITY IDEOGRAPH-F98C
+F98D;8F62;8F62;8F62;8F62; # (轢; 轢; 轢; 轢; 轢; ) CJK COMPATIBILITY IDEOGRAPH-F98D
+F98E;5E74;5E74;5E74;5E74; # (年; 年; 年; 年; 年; ) CJK COMPATIBILITY IDEOGRAPH-F98E
+F98F;6190;6190;6190;6190; # (憐; 憐; 憐; 憐; 憐; ) CJK COMPATIBILITY IDEOGRAPH-F98F
+F990;6200;6200;6200;6200; # (戀; 戀; 戀; 戀; 戀; ) CJK COMPATIBILITY IDEOGRAPH-F990
+F991;649A;649A;649A;649A; # (撚; 撚; 撚; 撚; 撚; ) CJK COMPATIBILITY IDEOGRAPH-F991
+F992;6F23;6F23;6F23;6F23; # (漣; 漣; 漣; 漣; 漣; ) CJK COMPATIBILITY IDEOGRAPH-F992
+F993;7149;7149;7149;7149; # (煉; 煉; 煉; 煉; 煉; ) CJK COMPATIBILITY IDEOGRAPH-F993
+F994;7489;7489;7489;7489; # (璉; 璉; 璉; 璉; 璉; ) CJK COMPATIBILITY IDEOGRAPH-F994
+F995;79CA;79CA;79CA;79CA; # (秊; 秊; 秊; 秊; 秊; ) CJK COMPATIBILITY IDEOGRAPH-F995
+F996;7DF4;7DF4;7DF4;7DF4; # (練; 練; 練; 練; 練; ) CJK COMPATIBILITY IDEOGRAPH-F996
+F997;806F;806F;806F;806F; # (聯; 聯; 聯; 聯; 聯; ) CJK COMPATIBILITY IDEOGRAPH-F997
+F998;8F26;8F26;8F26;8F26; # (輦; 輦; 輦; 輦; 輦; ) CJK COMPATIBILITY IDEOGRAPH-F998
+F999;84EE;84EE;84EE;84EE; # (蓮; 蓮; 蓮; 蓮; 蓮; ) CJK COMPATIBILITY IDEOGRAPH-F999
+F99A;9023;9023;9023;9023; # (連; 連; 連; 連; 連; ) CJK COMPATIBILITY IDEOGRAPH-F99A
+F99B;934A;934A;934A;934A; # (鍊; 鍊; 鍊; 鍊; 鍊; ) CJK COMPATIBILITY IDEOGRAPH-F99B
+F99C;5217;5217;5217;5217; # (列; 列; 列; 列; 列; ) CJK COMPATIBILITY IDEOGRAPH-F99C
+F99D;52A3;52A3;52A3;52A3; # (劣; 劣; 劣; 劣; 劣; ) CJK COMPATIBILITY IDEOGRAPH-F99D
+F99E;54BD;54BD;54BD;54BD; # (咽; 咽; 咽; 咽; 咽; ) CJK COMPATIBILITY IDEOGRAPH-F99E
+F99F;70C8;70C8;70C8;70C8; # (烈; 烈; 烈; 烈; 烈; ) CJK COMPATIBILITY IDEOGRAPH-F99F
+F9A0;88C2;88C2;88C2;88C2; # (裂; 裂; 裂; 裂; 裂; ) CJK COMPATIBILITY IDEOGRAPH-F9A0
+F9A1;8AAA;8AAA;8AAA;8AAA; # (說; 說; 說; 說; 說; ) CJK COMPATIBILITY IDEOGRAPH-F9A1
+F9A2;5EC9;5EC9;5EC9;5EC9; # (廉; 廉; 廉; 廉; 廉; ) CJK COMPATIBILITY IDEOGRAPH-F9A2
+F9A3;5FF5;5FF5;5FF5;5FF5; # (念; 念; 念; 念; 念; ) CJK COMPATIBILITY IDEOGRAPH-F9A3
+F9A4;637B;637B;637B;637B; # (捻; 捻; 捻; 捻; 捻; ) CJK COMPATIBILITY IDEOGRAPH-F9A4
+F9A5;6BAE;6BAE;6BAE;6BAE; # (殮; 殮; 殮; 殮; 殮; ) CJK COMPATIBILITY IDEOGRAPH-F9A5
+F9A6;7C3E;7C3E;7C3E;7C3E; # (簾; 簾; 簾; 簾; 簾; ) CJK COMPATIBILITY IDEOGRAPH-F9A6
+F9A7;7375;7375;7375;7375; # (獵; 獵; 獵; 獵; 獵; ) CJK COMPATIBILITY IDEOGRAPH-F9A7
+F9A8;4EE4;4EE4;4EE4;4EE4; # (令; 令; 令; 令; 令; ) CJK COMPATIBILITY IDEOGRAPH-F9A8
+F9A9;56F9;56F9;56F9;56F9; # (囹; 囹; 囹; 囹; 囹; ) CJK COMPATIBILITY IDEOGRAPH-F9A9
+F9AA;5BE7;5BE7;5BE7;5BE7; # (寧; 寧; 寧; 寧; 寧; ) CJK COMPATIBILITY IDEOGRAPH-F9AA
+F9AB;5DBA;5DBA;5DBA;5DBA; # (嶺; 嶺; 嶺; 嶺; 嶺; ) CJK COMPATIBILITY IDEOGRAPH-F9AB
+F9AC;601C;601C;601C;601C; # (怜; 怜; 怜; 怜; 怜; ) CJK COMPATIBILITY IDEOGRAPH-F9AC
+F9AD;73B2;73B2;73B2;73B2; # (玲; 玲; 玲; 玲; 玲; ) CJK COMPATIBILITY IDEOGRAPH-F9AD
+F9AE;7469;7469;7469;7469; # (瑩; 瑩; 瑩; 瑩; 瑩; ) CJK COMPATIBILITY IDEOGRAPH-F9AE
+F9AF;7F9A;7F9A;7F9A;7F9A; # (羚; 羚; 羚; 羚; 羚; ) CJK COMPATIBILITY IDEOGRAPH-F9AF
+F9B0;8046;8046;8046;8046; # (聆; 聆; 聆; 聆; 聆; ) CJK COMPATIBILITY IDEOGRAPH-F9B0
+F9B1;9234;9234;9234;9234; # (鈴; 鈴; 鈴; 鈴; 鈴; ) CJK COMPATIBILITY IDEOGRAPH-F9B1
+F9B2;96F6;96F6;96F6;96F6; # (零; 零; 零; 零; 零; ) CJK COMPATIBILITY IDEOGRAPH-F9B2
+F9B3;9748;9748;9748;9748; # (靈; 靈; 靈; 靈; 靈; ) CJK COMPATIBILITY IDEOGRAPH-F9B3
+F9B4;9818;9818;9818;9818; # (領; 領; 領; 領; 領; ) CJK COMPATIBILITY IDEOGRAPH-F9B4
+F9B5;4F8B;4F8B;4F8B;4F8B; # (例; 例; 例; 例; 例; ) CJK COMPATIBILITY IDEOGRAPH-F9B5
+F9B6;79AE;79AE;79AE;79AE; # (禮; 禮; 禮; 禮; 禮; ) CJK COMPATIBILITY IDEOGRAPH-F9B6
+F9B7;91B4;91B4;91B4;91B4; # (醴; 醴; 醴; 醴; 醴; ) CJK COMPATIBILITY IDEOGRAPH-F9B7
+F9B8;96B8;96B8;96B8;96B8; # (隸; 隸; 隸; 隸; 隸; ) CJK COMPATIBILITY IDEOGRAPH-F9B8
+F9B9;60E1;60E1;60E1;60E1; # (惡; 惡; 惡; 惡; 惡; ) CJK COMPATIBILITY IDEOGRAPH-F9B9
+F9BA;4E86;4E86;4E86;4E86; # (了; 了; 了; 了; 了; ) CJK COMPATIBILITY IDEOGRAPH-F9BA
+F9BB;50DA;50DA;50DA;50DA; # (僚; 僚; 僚; 僚; 僚; ) CJK COMPATIBILITY IDEOGRAPH-F9BB
+F9BC;5BEE;5BEE;5BEE;5BEE; # (寮; 寮; 寮; 寮; 寮; ) CJK COMPATIBILITY IDEOGRAPH-F9BC
+F9BD;5C3F;5C3F;5C3F;5C3F; # (尿; 尿; 尿; 尿; 尿; ) CJK COMPATIBILITY IDEOGRAPH-F9BD
+F9BE;6599;6599;6599;6599; # (料; 料; 料; 料; 料; ) CJK COMPATIBILITY IDEOGRAPH-F9BE
+F9BF;6A02;6A02;6A02;6A02; # (樂; 樂; 樂; 樂; 樂; ) CJK COMPATIBILITY IDEOGRAPH-F9BF
+F9C0;71CE;71CE;71CE;71CE; # (燎; 燎; 燎; 燎; 燎; ) CJK COMPATIBILITY IDEOGRAPH-F9C0
+F9C1;7642;7642;7642;7642; # (療; 療; 療; 療; 療; ) CJK COMPATIBILITY IDEOGRAPH-F9C1
+F9C2;84FC;84FC;84FC;84FC; # (蓼; 蓼; 蓼; 蓼; 蓼; ) CJK COMPATIBILITY IDEOGRAPH-F9C2
+F9C3;907C;907C;907C;907C; # (遼; 遼; 遼; 遼; 遼; ) CJK COMPATIBILITY IDEOGRAPH-F9C3
+F9C4;9F8D;9F8D;9F8D;9F8D; # (龍; 龍; 龍; 龍; 龍; ) CJK COMPATIBILITY IDEOGRAPH-F9C4
+F9C5;6688;6688;6688;6688; # (暈; 暈; 暈; 暈; 暈; ) CJK COMPATIBILITY IDEOGRAPH-F9C5
+F9C6;962E;962E;962E;962E; # (阮; 阮; 阮; 阮; 阮; ) CJK COMPATIBILITY IDEOGRAPH-F9C6
+F9C7;5289;5289;5289;5289; # (劉; 劉; 劉; 劉; 劉; ) CJK COMPATIBILITY IDEOGRAPH-F9C7
+F9C8;677B;677B;677B;677B; # (杻; 杻; 杻; 杻; 杻; ) CJK COMPATIBILITY IDEOGRAPH-F9C8
+F9C9;67F3;67F3;67F3;67F3; # (柳; 柳; 柳; 柳; 柳; ) CJK COMPATIBILITY IDEOGRAPH-F9C9
+F9CA;6D41;6D41;6D41;6D41; # (流; 流; 流; 流; 流; ) CJK COMPATIBILITY IDEOGRAPH-F9CA
+F9CB;6E9C;6E9C;6E9C;6E9C; # (溜; 溜; 溜; 溜; 溜; ) CJK COMPATIBILITY IDEOGRAPH-F9CB
+F9CC;7409;7409;7409;7409; # (琉; 琉; 琉; 琉; 琉; ) CJK COMPATIBILITY IDEOGRAPH-F9CC
+F9CD;7559;7559;7559;7559; # (留; 留; 留; 留; 留; ) CJK COMPATIBILITY IDEOGRAPH-F9CD
+F9CE;786B;786B;786B;786B; # (硫; 硫; 硫; 硫; 硫; ) CJK COMPATIBILITY IDEOGRAPH-F9CE
+F9CF;7D10;7D10;7D10;7D10; # (紐; 紐; 紐; 紐; 紐; ) CJK COMPATIBILITY IDEOGRAPH-F9CF
+F9D0;985E;985E;985E;985E; # (類; 類; 類; 類; 類; ) CJK COMPATIBILITY IDEOGRAPH-F9D0
+F9D1;516D;516D;516D;516D; # (六; 六; 六; 六; 六; ) CJK COMPATIBILITY IDEOGRAPH-F9D1
+F9D2;622E;622E;622E;622E; # (戮; 戮; 戮; 戮; 戮; ) CJK COMPATIBILITY IDEOGRAPH-F9D2
+F9D3;9678;9678;9678;9678; # (陸; 陸; 陸; 陸; 陸; ) CJK COMPATIBILITY IDEOGRAPH-F9D3
+F9D4;502B;502B;502B;502B; # (倫; 倫; 倫; 倫; 倫; ) CJK COMPATIBILITY IDEOGRAPH-F9D4
+F9D5;5D19;5D19;5D19;5D19; # (崙; 崙; 崙; 崙; 崙; ) CJK COMPATIBILITY IDEOGRAPH-F9D5
+F9D6;6DEA;6DEA;6DEA;6DEA; # (淪; 淪; 淪; 淪; 淪; ) CJK COMPATIBILITY IDEOGRAPH-F9D6
+F9D7;8F2A;8F2A;8F2A;8F2A; # (輪; 輪; 輪; 輪; 輪; ) CJK COMPATIBILITY IDEOGRAPH-F9D7
+F9D8;5F8B;5F8B;5F8B;5F8B; # (律; 律; 律; 律; 律; ) CJK COMPATIBILITY IDEOGRAPH-F9D8
+F9D9;6144;6144;6144;6144; # (慄; 慄; 慄; 慄; 慄; ) CJK COMPATIBILITY IDEOGRAPH-F9D9
+F9DA;6817;6817;6817;6817; # (栗; 栗; 栗; 栗; 栗; ) CJK COMPATIBILITY IDEOGRAPH-F9DA
+F9DB;7387;7387;7387;7387; # (率; 率; 率; 率; 率; ) CJK COMPATIBILITY IDEOGRAPH-F9DB
+F9DC;9686;9686;9686;9686; # (隆; 隆; 隆; 隆; 隆; ) CJK COMPATIBILITY IDEOGRAPH-F9DC
+F9DD;5229;5229;5229;5229; # (利; 利; 利; 利; 利; ) CJK COMPATIBILITY IDEOGRAPH-F9DD
+F9DE;540F;540F;540F;540F; # (吏; 吏; 吏; 吏; 吏; ) CJK COMPATIBILITY IDEOGRAPH-F9DE
+F9DF;5C65;5C65;5C65;5C65; # (履; 履; 履; 履; 履; ) CJK COMPATIBILITY IDEOGRAPH-F9DF
+F9E0;6613;6613;6613;6613; # (易; 易; 易; 易; 易; ) CJK COMPATIBILITY IDEOGRAPH-F9E0
+F9E1;674E;674E;674E;674E; # (李; 李; 李; 李; 李; ) CJK COMPATIBILITY IDEOGRAPH-F9E1
+F9E2;68A8;68A8;68A8;68A8; # (梨; 梨; 梨; 梨; 梨; ) CJK COMPATIBILITY IDEOGRAPH-F9E2
+F9E3;6CE5;6CE5;6CE5;6CE5; # (泥; 泥; 泥; 泥; 泥; ) CJK COMPATIBILITY IDEOGRAPH-F9E3
+F9E4;7406;7406;7406;7406; # (理; 理; 理; 理; 理; ) CJK COMPATIBILITY IDEOGRAPH-F9E4
+F9E5;75E2;75E2;75E2;75E2; # (痢; 痢; 痢; 痢; 痢; ) CJK COMPATIBILITY IDEOGRAPH-F9E5
+F9E6;7F79;7F79;7F79;7F79; # (罹; 罹; 罹; 罹; 罹; ) CJK COMPATIBILITY IDEOGRAPH-F9E6
+F9E7;88CF;88CF;88CF;88CF; # (裏; 裏; 裏; 裏; 裏; ) CJK COMPATIBILITY IDEOGRAPH-F9E7
+F9E8;88E1;88E1;88E1;88E1; # (裡; 裡; 裡; 裡; 裡; ) CJK COMPATIBILITY IDEOGRAPH-F9E8
+F9E9;91CC;91CC;91CC;91CC; # (里; 里; 里; 里; 里; ) CJK COMPATIBILITY IDEOGRAPH-F9E9
+F9EA;96E2;96E2;96E2;96E2; # (離; 離; 離; 離; 離; ) CJK COMPATIBILITY IDEOGRAPH-F9EA
+F9EB;533F;533F;533F;533F; # (匿; 匿; 匿; 匿; 匿; ) CJK COMPATIBILITY IDEOGRAPH-F9EB
+F9EC;6EBA;6EBA;6EBA;6EBA; # (溺; 溺; 溺; 溺; 溺; ) CJK COMPATIBILITY IDEOGRAPH-F9EC
+F9ED;541D;541D;541D;541D; # (吝; 吝; 吝; 吝; 吝; ) CJK COMPATIBILITY IDEOGRAPH-F9ED
+F9EE;71D0;71D0;71D0;71D0; # (燐; 燐; 燐; 燐; 燐; ) CJK COMPATIBILITY IDEOGRAPH-F9EE
+F9EF;7498;7498;7498;7498; # (璘; 璘; 璘; 璘; 璘; ) CJK COMPATIBILITY IDEOGRAPH-F9EF
+F9F0;85FA;85FA;85FA;85FA; # (藺; 藺; 藺; 藺; 藺; ) CJK COMPATIBILITY IDEOGRAPH-F9F0
+F9F1;96A3;96A3;96A3;96A3; # (隣; 隣; 隣; 隣; 隣; ) CJK COMPATIBILITY IDEOGRAPH-F9F1
+F9F2;9C57;9C57;9C57;9C57; # (鱗; 鱗; 鱗; 鱗; 鱗; ) CJK COMPATIBILITY IDEOGRAPH-F9F2
+F9F3;9E9F;9E9F;9E9F;9E9F; # (麟; 麟; 麟; 麟; 麟; ) CJK COMPATIBILITY IDEOGRAPH-F9F3
+F9F4;6797;6797;6797;6797; # (林; 林; 林; 林; 林; ) CJK COMPATIBILITY IDEOGRAPH-F9F4
+F9F5;6DCB;6DCB;6DCB;6DCB; # (淋; 淋; 淋; 淋; 淋; ) CJK COMPATIBILITY IDEOGRAPH-F9F5
+F9F6;81E8;81E8;81E8;81E8; # (臨; 臨; 臨; 臨; 臨; ) CJK COMPATIBILITY IDEOGRAPH-F9F6
+F9F7;7ACB;7ACB;7ACB;7ACB; # (立; 立; 立; 立; 立; ) CJK COMPATIBILITY IDEOGRAPH-F9F7
+F9F8;7B20;7B20;7B20;7B20; # (笠; 笠; 笠; 笠; 笠; ) CJK COMPATIBILITY IDEOGRAPH-F9F8
+F9F9;7C92;7C92;7C92;7C92; # (粒; 粒; 粒; 粒; 粒; ) CJK COMPATIBILITY IDEOGRAPH-F9F9
+F9FA;72C0;72C0;72C0;72C0; # (狀; 狀; 狀; 狀; 狀; ) CJK COMPATIBILITY IDEOGRAPH-F9FA
+F9FB;7099;7099;7099;7099; # (炙; 炙; 炙; 炙; 炙; ) CJK COMPATIBILITY IDEOGRAPH-F9FB
+F9FC;8B58;8B58;8B58;8B58; # (識; 識; 識; 識; 識; ) CJK COMPATIBILITY IDEOGRAPH-F9FC
+F9FD;4EC0;4EC0;4EC0;4EC0; # (什; 什; 什; 什; 什; ) CJK COMPATIBILITY IDEOGRAPH-F9FD
+F9FE;8336;8336;8336;8336; # (茶; 茶; 茶; 茶; 茶; ) CJK COMPATIBILITY IDEOGRAPH-F9FE
+F9FF;523A;523A;523A;523A; # (刺; 刺; 刺; 刺; 刺; ) CJK COMPATIBILITY IDEOGRAPH-F9FF
+FA00;5207;5207;5207;5207; # (切; 切; 切; 切; 切; ) CJK COMPATIBILITY IDEOGRAPH-FA00
+FA01;5EA6;5EA6;5EA6;5EA6; # (度; 度; 度; 度; 度; ) CJK COMPATIBILITY IDEOGRAPH-FA01
+FA02;62D3;62D3;62D3;62D3; # (拓; 拓; 拓; 拓; 拓; ) CJK COMPATIBILITY IDEOGRAPH-FA02
+FA03;7CD6;7CD6;7CD6;7CD6; # (糖; 糖; 糖; 糖; 糖; ) CJK COMPATIBILITY IDEOGRAPH-FA03
+FA04;5B85;5B85;5B85;5B85; # (宅; 宅; 宅; 宅; 宅; ) CJK COMPATIBILITY IDEOGRAPH-FA04
+FA05;6D1E;6D1E;6D1E;6D1E; # (洞; 洞; 洞; 洞; 洞; ) CJK COMPATIBILITY IDEOGRAPH-FA05
+FA06;66B4;66B4;66B4;66B4; # (暴; 暴; 暴; 暴; 暴; ) CJK COMPATIBILITY IDEOGRAPH-FA06
+FA07;8F3B;8F3B;8F3B;8F3B; # (輻; 輻; 輻; 輻; 輻; ) CJK COMPATIBILITY IDEOGRAPH-FA07
+FA08;884C;884C;884C;884C; # (行; 行; 行; 行; 行; ) CJK COMPATIBILITY IDEOGRAPH-FA08
+FA09;964D;964D;964D;964D; # (降; 降; 降; 降; 降; ) CJK COMPATIBILITY IDEOGRAPH-FA09
+FA0A;898B;898B;898B;898B; # (見; 見; 見; 見; 見; ) CJK COMPATIBILITY IDEOGRAPH-FA0A
+FA0B;5ED3;5ED3;5ED3;5ED3; # (廓; 廓; 廓; 廓; 廓; ) CJK COMPATIBILITY IDEOGRAPH-FA0B
+FA0C;5140;5140;5140;5140; # (兀; 兀; 兀; 兀; 兀; ) CJK COMPATIBILITY IDEOGRAPH-FA0C
+FA0D;55C0;55C0;55C0;55C0; # (嗀; 嗀; 嗀; 嗀; 嗀; ) CJK COMPATIBILITY IDEOGRAPH-FA0D
+FA10;585A;585A;585A;585A; # (塚; 塚; 塚; 塚; 塚; ) CJK COMPATIBILITY IDEOGRAPH-FA10
+FA12;6674;6674;6674;6674; # (晴; 晴; 晴; 晴; 晴; ) CJK COMPATIBILITY IDEOGRAPH-FA12
+FA15;51DE;51DE;51DE;51DE; # (凞; 凞; 凞; 凞; 凞; ) CJK COMPATIBILITY IDEOGRAPH-FA15
+FA16;732A;732A;732A;732A; # (猪; 猪; 猪; 猪; 猪; ) CJK COMPATIBILITY IDEOGRAPH-FA16
+FA17;76CA;76CA;76CA;76CA; # (益; 益; 益; 益; 益; ) CJK COMPATIBILITY IDEOGRAPH-FA17
+FA18;793C;793C;793C;793C; # (礼; 礼; 礼; 礼; 礼; ) CJK COMPATIBILITY IDEOGRAPH-FA18
+FA19;795E;795E;795E;795E; # (神; 神; 神; 神; 神; ) CJK COMPATIBILITY IDEOGRAPH-FA19
+FA1A;7965;7965;7965;7965; # (祥; 祥; 祥; 祥; 祥; ) CJK COMPATIBILITY IDEOGRAPH-FA1A
+FA1B;798F;798F;798F;798F; # (福; 福; 福; 福; 福; ) CJK COMPATIBILITY IDEOGRAPH-FA1B
+FA1C;9756;9756;9756;9756; # (靖; 靖; 靖; 靖; 靖; ) CJK COMPATIBILITY IDEOGRAPH-FA1C
+FA1D;7CBE;7CBE;7CBE;7CBE; # (精; 精; 精; 精; 精; ) CJK COMPATIBILITY IDEOGRAPH-FA1D
+FA1E;7FBD;7FBD;7FBD;7FBD; # (羽; 羽; 羽; 羽; 羽; ) CJK COMPATIBILITY IDEOGRAPH-FA1E
+FA20;8612;8612;8612;8612; # (蘒; 蘒; 蘒; 蘒; 蘒; ) CJK COMPATIBILITY IDEOGRAPH-FA20
+FA22;8AF8;8AF8;8AF8;8AF8; # (諸; 諸; 諸; 諸; 諸; ) CJK COMPATIBILITY IDEOGRAPH-FA22
+FA25;9038;9038;9038;9038; # (逸; 逸; 逸; 逸; 逸; ) CJK COMPATIBILITY IDEOGRAPH-FA25
+FA26;90FD;90FD;90FD;90FD; # (都; 都; 都; 都; 都; ) CJK COMPATIBILITY IDEOGRAPH-FA26
+FA2A;98EF;98EF;98EF;98EF; # (飯; 飯; 飯; 飯; 飯; ) CJK COMPATIBILITY IDEOGRAPH-FA2A
+FA2B;98FC;98FC;98FC;98FC; # (飼; 飼; 飼; 飼; 飼; ) CJK COMPATIBILITY IDEOGRAPH-FA2B
+FA2C;9928;9928;9928;9928; # (館; 館; 館; 館; 館; ) CJK COMPATIBILITY IDEOGRAPH-FA2C
+FA2D;9DB4;9DB4;9DB4;9DB4; # (鶴; 鶴; 鶴; 鶴; 鶴; ) CJK COMPATIBILITY IDEOGRAPH-FA2D
+FA2E;90DE;90DE;90DE;90DE; # (郞; 郞; 郞; 郞; 郞; ) CJK COMPATIBILITY IDEOGRAPH-FA2E
+FA2F;96B7;96B7;96B7;96B7; # (隷; 隷; 隷; 隷; 隷; ) CJK COMPATIBILITY IDEOGRAPH-FA2F
+FA30;4FAE;4FAE;4FAE;4FAE; # (侮; 侮; 侮; 侮; 侮; ) CJK COMPATIBILITY IDEOGRAPH-FA30
+FA31;50E7;50E7;50E7;50E7; # (僧; 僧; 僧; 僧; 僧; ) CJK COMPATIBILITY IDEOGRAPH-FA31
+FA32;514D;514D;514D;514D; # (免; 免; 免; 免; 免; ) CJK COMPATIBILITY IDEOGRAPH-FA32
+FA33;52C9;52C9;52C9;52C9; # (勉; 勉; 勉; 勉; 勉; ) CJK COMPATIBILITY IDEOGRAPH-FA33
+FA34;52E4;52E4;52E4;52E4; # (勤; 勤; 勤; 勤; 勤; ) CJK COMPATIBILITY IDEOGRAPH-FA34
+FA35;5351;5351;5351;5351; # (卑; 卑; 卑; 卑; 卑; ) CJK COMPATIBILITY IDEOGRAPH-FA35
+FA36;559D;559D;559D;559D; # (喝; 喝; 喝; 喝; 喝; ) CJK COMPATIBILITY IDEOGRAPH-FA36
+FA37;5606;5606;5606;5606; # (嘆; 嘆; 嘆; 嘆; 嘆; ) CJK COMPATIBILITY IDEOGRAPH-FA37
+FA38;5668;5668;5668;5668; # (器; 器; 器; 器; 器; ) CJK COMPATIBILITY IDEOGRAPH-FA38
+FA39;5840;5840;5840;5840; # (塀; 塀; 塀; 塀; 塀; ) CJK COMPATIBILITY IDEOGRAPH-FA39
+FA3A;58A8;58A8;58A8;58A8; # (墨; 墨; 墨; 墨; 墨; ) CJK COMPATIBILITY IDEOGRAPH-FA3A
+FA3B;5C64;5C64;5C64;5C64; # (層; 層; 層; 層; 層; ) CJK COMPATIBILITY IDEOGRAPH-FA3B
+FA3C;5C6E;5C6E;5C6E;5C6E; # (屮; 屮; 屮; 屮; 屮; ) CJK COMPATIBILITY IDEOGRAPH-FA3C
+FA3D;6094;6094;6094;6094; # (悔; 悔; 悔; 悔; 悔; ) CJK COMPATIBILITY IDEOGRAPH-FA3D
+FA3E;6168;6168;6168;6168; # (慨; 慨; 慨; 慨; 慨; ) CJK COMPATIBILITY IDEOGRAPH-FA3E
+FA3F;618E;618E;618E;618E; # (憎; 憎; 憎; 憎; 憎; ) CJK COMPATIBILITY IDEOGRAPH-FA3F
+FA40;61F2;61F2;61F2;61F2; # (懲; 懲; 懲; 懲; 懲; ) CJK COMPATIBILITY IDEOGRAPH-FA40
+FA41;654F;654F;654F;654F; # (敏; 敏; 敏; 敏; 敏; ) CJK COMPATIBILITY IDEOGRAPH-FA41
+FA42;65E2;65E2;65E2;65E2; # (既; 既; 既; 既; 既; ) CJK COMPATIBILITY IDEOGRAPH-FA42
+FA43;6691;6691;6691;6691; # (暑; 暑; 暑; 暑; 暑; ) CJK COMPATIBILITY IDEOGRAPH-FA43
+FA44;6885;6885;6885;6885; # (梅; 梅; 梅; 梅; 梅; ) CJK COMPATIBILITY IDEOGRAPH-FA44
+FA45;6D77;6D77;6D77;6D77; # (海; 海; 海; 海; 海; ) CJK COMPATIBILITY IDEOGRAPH-FA45
+FA46;6E1A;6E1A;6E1A;6E1A; # (渚; 渚; 渚; 渚; 渚; ) CJK COMPATIBILITY IDEOGRAPH-FA46
+FA47;6F22;6F22;6F22;6F22; # (漢; 漢; 漢; 漢; 漢; ) CJK COMPATIBILITY IDEOGRAPH-FA47
+FA48;716E;716E;716E;716E; # (煮; 煮; 煮; 煮; 煮; ) CJK COMPATIBILITY IDEOGRAPH-FA48
+FA49;722B;722B;722B;722B; # (爫; 爫; 爫; 爫; 爫; ) CJK COMPATIBILITY IDEOGRAPH-FA49
+FA4A;7422;7422;7422;7422; # (琢; 琢; 琢; 琢; 琢; ) CJK COMPATIBILITY IDEOGRAPH-FA4A
+FA4B;7891;7891;7891;7891; # (碑; 碑; 碑; 碑; 碑; ) CJK COMPATIBILITY IDEOGRAPH-FA4B
+FA4C;793E;793E;793E;793E; # (社; 社; 社; 社; 社; ) CJK COMPATIBILITY IDEOGRAPH-FA4C
+FA4D;7949;7949;7949;7949; # (祉; 祉; 祉; 祉; 祉; ) CJK COMPATIBILITY IDEOGRAPH-FA4D
+FA4E;7948;7948;7948;7948; # (祈; 祈; 祈; 祈; 祈; ) CJK COMPATIBILITY IDEOGRAPH-FA4E
+FA4F;7950;7950;7950;7950; # (祐; 祐; 祐; 祐; 祐; ) CJK COMPATIBILITY IDEOGRAPH-FA4F
+FA50;7956;7956;7956;7956; # (祖; 祖; 祖; 祖; 祖; ) CJK COMPATIBILITY IDEOGRAPH-FA50
+FA51;795D;795D;795D;795D; # (祝; 祝; 祝; 祝; 祝; ) CJK COMPATIBILITY IDEOGRAPH-FA51
+FA52;798D;798D;798D;798D; # (禍; 禍; 禍; 禍; 禍; ) CJK COMPATIBILITY IDEOGRAPH-FA52
+FA53;798E;798E;798E;798E; # (禎; 禎; 禎; 禎; 禎; ) CJK COMPATIBILITY IDEOGRAPH-FA53
+FA54;7A40;7A40;7A40;7A40; # (穀; 穀; 穀; 穀; 穀; ) CJK COMPATIBILITY IDEOGRAPH-FA54
+FA55;7A81;7A81;7A81;7A81; # (突; 突; 突; 突; 突; ) CJK COMPATIBILITY IDEOGRAPH-FA55
+FA56;7BC0;7BC0;7BC0;7BC0; # (節; 節; 節; 節; 節; ) CJK COMPATIBILITY IDEOGRAPH-FA56
+FA57;7DF4;7DF4;7DF4;7DF4; # (練; 練; 練; 練; 練; ) CJK COMPATIBILITY IDEOGRAPH-FA57
+FA58;7E09;7E09;7E09;7E09; # (縉; 縉; 縉; 縉; 縉; ) CJK COMPATIBILITY IDEOGRAPH-FA58
+FA59;7E41;7E41;7E41;7E41; # (繁; 繁; 繁; 繁; 繁; ) CJK COMPATIBILITY IDEOGRAPH-FA59
+FA5A;7F72;7F72;7F72;7F72; # (署; 署; 署; 署; 署; ) CJK COMPATIBILITY IDEOGRAPH-FA5A
+FA5B;8005;8005;8005;8005; # (者; 者; 者; 者; 者; ) CJK COMPATIBILITY IDEOGRAPH-FA5B
+FA5C;81ED;81ED;81ED;81ED; # (臭; 臭; 臭; 臭; 臭; ) CJK COMPATIBILITY IDEOGRAPH-FA5C
+FA5D;8279;8279;8279;8279; # (艹; 艹; 艹; 艹; 艹; ) CJK COMPATIBILITY IDEOGRAPH-FA5D
+FA5E;8279;8279;8279;8279; # (艹; 艹; 艹; 艹; 艹; ) CJK COMPATIBILITY IDEOGRAPH-FA5E
+FA5F;8457;8457;8457;8457; # (著; 著; 著; 著; 著; ) CJK COMPATIBILITY IDEOGRAPH-FA5F
+FA60;8910;8910;8910;8910; # (褐; 褐; 褐; 褐; 褐; ) CJK COMPATIBILITY IDEOGRAPH-FA60
+FA61;8996;8996;8996;8996; # (視; 視; 視; 視; 視; ) CJK COMPATIBILITY IDEOGRAPH-FA61
+FA62;8B01;8B01;8B01;8B01; # (謁; 謁; 謁; 謁; 謁; ) CJK COMPATIBILITY IDEOGRAPH-FA62
+FA63;8B39;8B39;8B39;8B39; # (謹; 謹; 謹; 謹; 謹; ) CJK COMPATIBILITY IDEOGRAPH-FA63
+FA64;8CD3;8CD3;8CD3;8CD3; # (賓; 賓; 賓; 賓; 賓; ) CJK COMPATIBILITY IDEOGRAPH-FA64
+FA65;8D08;8D08;8D08;8D08; # (贈; 贈; 贈; 贈; 贈; ) CJK COMPATIBILITY IDEOGRAPH-FA65
+FA66;8FB6;8FB6;8FB6;8FB6; # (辶; 辶; 辶; 辶; 辶; ) CJK COMPATIBILITY IDEOGRAPH-FA66
+FA67;9038;9038;9038;9038; # (逸; 逸; 逸; 逸; 逸; ) CJK COMPATIBILITY IDEOGRAPH-FA67
+FA68;96E3;96E3;96E3;96E3; # (難; 難; 難; 難; 難; ) CJK COMPATIBILITY IDEOGRAPH-FA68
+FA69;97FF;97FF;97FF;97FF; # (響; 響; 響; 響; 響; ) CJK COMPATIBILITY IDEOGRAPH-FA69
+FA6A;983B;983B;983B;983B; # (頻; 頻; 頻; 頻; 頻; ) CJK COMPATIBILITY IDEOGRAPH-FA6A
+FA6B;6075;6075;6075;6075; # (恵; 恵; 恵; 恵; 恵; ) CJK COMPATIBILITY IDEOGRAPH-FA6B
+FA6C;242EE;242EE;242EE;242EE; # (𤋮; 𤋮; 𤋮; 𤋮; 𤋮; ) CJK COMPATIBILITY IDEOGRAPH-FA6C
+FA6D;8218;8218;8218;8218; # (舘; 舘; 舘; 舘; 舘; ) CJK COMPATIBILITY IDEOGRAPH-FA6D
+FA70;4E26;4E26;4E26;4E26; # (並; 並; 並; 並; 並; ) CJK COMPATIBILITY IDEOGRAPH-FA70
+FA71;51B5;51B5;51B5;51B5; # (况; 况; 况; 况; 况; ) CJK COMPATIBILITY IDEOGRAPH-FA71
+FA72;5168;5168;5168;5168; # (全; 全; 全; 全; 全; ) CJK COMPATIBILITY IDEOGRAPH-FA72
+FA73;4F80;4F80;4F80;4F80; # (侀; 侀; 侀; 侀; 侀; ) CJK COMPATIBILITY IDEOGRAPH-FA73
+FA74;5145;5145;5145;5145; # (充; 充; 充; 充; 充; ) CJK COMPATIBILITY IDEOGRAPH-FA74
+FA75;5180;5180;5180;5180; # (冀; 冀; 冀; 冀; 冀; ) CJK COMPATIBILITY IDEOGRAPH-FA75
+FA76;52C7;52C7;52C7;52C7; # (勇; 勇; 勇; 勇; 勇; ) CJK COMPATIBILITY IDEOGRAPH-FA76
+FA77;52FA;52FA;52FA;52FA; # (勺; 勺; 勺; 勺; 勺; ) CJK COMPATIBILITY IDEOGRAPH-FA77
+FA78;559D;559D;559D;559D; # (喝; 喝; 喝; 喝; 喝; ) CJK COMPATIBILITY IDEOGRAPH-FA78
+FA79;5555;5555;5555;5555; # (啕; 啕; 啕; 啕; 啕; ) CJK COMPATIBILITY IDEOGRAPH-FA79
+FA7A;5599;5599;5599;5599; # (喙; 喙; 喙; 喙; 喙; ) CJK COMPATIBILITY IDEOGRAPH-FA7A
+FA7B;55E2;55E2;55E2;55E2; # (嗢; 嗢; 嗢; 嗢; 嗢; ) CJK COMPATIBILITY IDEOGRAPH-FA7B
+FA7C;585A;585A;585A;585A; # (塚; 塚; 塚; 塚; 塚; ) CJK COMPATIBILITY IDEOGRAPH-FA7C
+FA7D;58B3;58B3;58B3;58B3; # (墳; 墳; 墳; 墳; 墳; ) CJK COMPATIBILITY IDEOGRAPH-FA7D
+FA7E;5944;5944;5944;5944; # (奄; 奄; 奄; 奄; 奄; ) CJK COMPATIBILITY IDEOGRAPH-FA7E
+FA7F;5954;5954;5954;5954; # (奔; 奔; 奔; 奔; 奔; ) CJK COMPATIBILITY IDEOGRAPH-FA7F
+FA80;5A62;5A62;5A62;5A62; # (婢; 婢; 婢; 婢; 婢; ) CJK COMPATIBILITY IDEOGRAPH-FA80
+FA81;5B28;5B28;5B28;5B28; # (嬨; 嬨; 嬨; 嬨; 嬨; ) CJK COMPATIBILITY IDEOGRAPH-FA81
+FA82;5ED2;5ED2;5ED2;5ED2; # (廒; 廒; 廒; 廒; 廒; ) CJK COMPATIBILITY IDEOGRAPH-FA82
+FA83;5ED9;5ED9;5ED9;5ED9; # (廙; 廙; 廙; 廙; 廙; ) CJK COMPATIBILITY IDEOGRAPH-FA83
+FA84;5F69;5F69;5F69;5F69; # (彩; 彩; 彩; 彩; 彩; ) CJK COMPATIBILITY IDEOGRAPH-FA84
+FA85;5FAD;5FAD;5FAD;5FAD; # (徭; 徭; 徭; 徭; 徭; ) CJK COMPATIBILITY IDEOGRAPH-FA85
+FA86;60D8;60D8;60D8;60D8; # (惘; 惘; 惘; 惘; 惘; ) CJK COMPATIBILITY IDEOGRAPH-FA86
+FA87;614E;614E;614E;614E; # (慎; 慎; 慎; 慎; 慎; ) CJK COMPATIBILITY IDEOGRAPH-FA87
+FA88;6108;6108;6108;6108; # (愈; 愈; 愈; 愈; 愈; ) CJK COMPATIBILITY IDEOGRAPH-FA88
+FA89;618E;618E;618E;618E; # (憎; 憎; 憎; 憎; 憎; ) CJK COMPATIBILITY IDEOGRAPH-FA89
+FA8A;6160;6160;6160;6160; # (慠; 慠; 慠; 慠; 慠; ) CJK COMPATIBILITY IDEOGRAPH-FA8A
+FA8B;61F2;61F2;61F2;61F2; # (懲; 懲; 懲; 懲; 懲; ) CJK COMPATIBILITY IDEOGRAPH-FA8B
+FA8C;6234;6234;6234;6234; # (戴; 戴; 戴; 戴; 戴; ) CJK COMPATIBILITY IDEOGRAPH-FA8C
+FA8D;63C4;63C4;63C4;63C4; # (揄; 揄; 揄; 揄; 揄; ) CJK COMPATIBILITY IDEOGRAPH-FA8D
+FA8E;641C;641C;641C;641C; # (搜; 搜; 搜; 搜; 搜; ) CJK COMPATIBILITY IDEOGRAPH-FA8E
+FA8F;6452;6452;6452;6452; # (摒; 摒; 摒; 摒; 摒; ) CJK COMPATIBILITY IDEOGRAPH-FA8F
+FA90;6556;6556;6556;6556; # (敖; 敖; 敖; 敖; 敖; ) CJK COMPATIBILITY IDEOGRAPH-FA90
+FA91;6674;6674;6674;6674; # (晴; 晴; 晴; 晴; 晴; ) CJK COMPATIBILITY IDEOGRAPH-FA91
+FA92;6717;6717;6717;6717; # (朗; 朗; 朗; 朗; 朗; ) CJK COMPATIBILITY IDEOGRAPH-FA92
+FA93;671B;671B;671B;671B; # (望; 望; 望; 望; 望; ) CJK COMPATIBILITY IDEOGRAPH-FA93
+FA94;6756;6756;6756;6756; # (杖; 杖; 杖; 杖; 杖; ) CJK COMPATIBILITY IDEOGRAPH-FA94
+FA95;6B79;6B79;6B79;6B79; # (歹; 歹; 歹; 歹; 歹; ) CJK COMPATIBILITY IDEOGRAPH-FA95
+FA96;6BBA;6BBA;6BBA;6BBA; # (殺; 殺; 殺; 殺; 殺; ) CJK COMPATIBILITY IDEOGRAPH-FA96
+FA97;6D41;6D41;6D41;6D41; # (流; 流; 流; 流; 流; ) CJK COMPATIBILITY IDEOGRAPH-FA97
+FA98;6EDB;6EDB;6EDB;6EDB; # (滛; 滛; 滛; 滛; 滛; ) CJK COMPATIBILITY IDEOGRAPH-FA98
+FA99;6ECB;6ECB;6ECB;6ECB; # (滋; 滋; 滋; 滋; 滋; ) CJK COMPATIBILITY IDEOGRAPH-FA99
+FA9A;6F22;6F22;6F22;6F22; # (漢; 漢; 漢; 漢; 漢; ) CJK COMPATIBILITY IDEOGRAPH-FA9A
+FA9B;701E;701E;701E;701E; # (瀞; 瀞; 瀞; 瀞; 瀞; ) CJK COMPATIBILITY IDEOGRAPH-FA9B
+FA9C;716E;716E;716E;716E; # (煮; 煮; 煮; 煮; 煮; ) CJK COMPATIBILITY IDEOGRAPH-FA9C
+FA9D;77A7;77A7;77A7;77A7; # (瞧; 瞧; 瞧; 瞧; 瞧; ) CJK COMPATIBILITY IDEOGRAPH-FA9D
+FA9E;7235;7235;7235;7235; # (爵; 爵; 爵; 爵; 爵; ) CJK COMPATIBILITY IDEOGRAPH-FA9E
+FA9F;72AF;72AF;72AF;72AF; # (犯; 犯; 犯; 犯; 犯; ) CJK COMPATIBILITY IDEOGRAPH-FA9F
+FAA0;732A;732A;732A;732A; # (猪; 猪; 猪; 猪; 猪; ) CJK COMPATIBILITY IDEOGRAPH-FAA0
+FAA1;7471;7471;7471;7471; # (瑱; 瑱; 瑱; 瑱; 瑱; ) CJK COMPATIBILITY IDEOGRAPH-FAA1
+FAA2;7506;7506;7506;7506; # (甆; 甆; 甆; 甆; 甆; ) CJK COMPATIBILITY IDEOGRAPH-FAA2
+FAA3;753B;753B;753B;753B; # (画; 画; 画; 画; 画; ) CJK COMPATIBILITY IDEOGRAPH-FAA3
+FAA4;761D;761D;761D;761D; # (瘝; 瘝; 瘝; 瘝; 瘝; ) CJK COMPATIBILITY IDEOGRAPH-FAA4
+FAA5;761F;761F;761F;761F; # (瘟; 瘟; 瘟; 瘟; 瘟; ) CJK COMPATIBILITY IDEOGRAPH-FAA5
+FAA6;76CA;76CA;76CA;76CA; # (益; 益; 益; 益; 益; ) CJK COMPATIBILITY IDEOGRAPH-FAA6
+FAA7;76DB;76DB;76DB;76DB; # (盛; 盛; 盛; 盛; 盛; ) CJK COMPATIBILITY IDEOGRAPH-FAA7
+FAA8;76F4;76F4;76F4;76F4; # (直; 直; 直; 直; 直; ) CJK COMPATIBILITY IDEOGRAPH-FAA8
+FAA9;774A;774A;774A;774A; # (睊; 睊; 睊; 睊; 睊; ) CJK COMPATIBILITY IDEOGRAPH-FAA9
+FAAA;7740;7740;7740;7740; # (着; 着; 着; 着; 着; ) CJK COMPATIBILITY IDEOGRAPH-FAAA
+FAAB;78CC;78CC;78CC;78CC; # (磌; 磌; 磌; 磌; 磌; ) CJK COMPATIBILITY IDEOGRAPH-FAAB
+FAAC;7AB1;7AB1;7AB1;7AB1; # (窱; 窱; 窱; 窱; 窱; ) CJK COMPATIBILITY IDEOGRAPH-FAAC
+FAAD;7BC0;7BC0;7BC0;7BC0; # (節; 節; 節; 節; 節; ) CJK COMPATIBILITY IDEOGRAPH-FAAD
+FAAE;7C7B;7C7B;7C7B;7C7B; # (类; 类; 类; 类; 类; ) CJK COMPATIBILITY IDEOGRAPH-FAAE
+FAAF;7D5B;7D5B;7D5B;7D5B; # (絛; 絛; 絛; 絛; 絛; ) CJK COMPATIBILITY IDEOGRAPH-FAAF
+FAB0;7DF4;7DF4;7DF4;7DF4; # (練; 練; 練; 練; 練; ) CJK COMPATIBILITY IDEOGRAPH-FAB0
+FAB1;7F3E;7F3E;7F3E;7F3E; # (缾; 缾; 缾; 缾; 缾; ) CJK COMPATIBILITY IDEOGRAPH-FAB1
+FAB2;8005;8005;8005;8005; # (者; 者; 者; 者; 者; ) CJK COMPATIBILITY IDEOGRAPH-FAB2
+FAB3;8352;8352;8352;8352; # (荒; 荒; 荒; 荒; 荒; ) CJK COMPATIBILITY IDEOGRAPH-FAB3
+FAB4;83EF;83EF;83EF;83EF; # (華; 華; 華; 華; 華; ) CJK COMPATIBILITY IDEOGRAPH-FAB4
+FAB5;8779;8779;8779;8779; # (蝹; 蝹; 蝹; 蝹; 蝹; ) CJK COMPATIBILITY IDEOGRAPH-FAB5
+FAB6;8941;8941;8941;8941; # (襁; 襁; 襁; 襁; 襁; ) CJK COMPATIBILITY IDEOGRAPH-FAB6
+FAB7;8986;8986;8986;8986; # (覆; 覆; 覆; 覆; 覆; ) CJK COMPATIBILITY IDEOGRAPH-FAB7
+FAB8;8996;8996;8996;8996; # (視; 視; 視; 視; 視; ) CJK COMPATIBILITY IDEOGRAPH-FAB8
+FAB9;8ABF;8ABF;8ABF;8ABF; # (調; 調; 調; 調; 調; ) CJK COMPATIBILITY IDEOGRAPH-FAB9
+FABA;8AF8;8AF8;8AF8;8AF8; # (諸; 諸; 諸; 諸; 諸; ) CJK COMPATIBILITY IDEOGRAPH-FABA
+FABB;8ACB;8ACB;8ACB;8ACB; # (請; 請; 請; 請; 請; ) CJK COMPATIBILITY IDEOGRAPH-FABB
+FABC;8B01;8B01;8B01;8B01; # (謁; 謁; 謁; 謁; 謁; ) CJK COMPATIBILITY IDEOGRAPH-FABC
+FABD;8AFE;8AFE;8AFE;8AFE; # (諾; 諾; 諾; 諾; 諾; ) CJK COMPATIBILITY IDEOGRAPH-FABD
+FABE;8AED;8AED;8AED;8AED; # (諭; 諭; 諭; 諭; 諭; ) CJK COMPATIBILITY IDEOGRAPH-FABE
+FABF;8B39;8B39;8B39;8B39; # (謹; 謹; 謹; 謹; 謹; ) CJK COMPATIBILITY IDEOGRAPH-FABF
+FAC0;8B8A;8B8A;8B8A;8B8A; # (變; 變; 變; 變; 變; ) CJK COMPATIBILITY IDEOGRAPH-FAC0
+FAC1;8D08;8D08;8D08;8D08; # (贈; 贈; 贈; 贈; 贈; ) CJK COMPATIBILITY IDEOGRAPH-FAC1
+FAC2;8F38;8F38;8F38;8F38; # (輸; 輸; 輸; 輸; 輸; ) CJK COMPATIBILITY IDEOGRAPH-FAC2
+FAC3;9072;9072;9072;9072; # (遲; 遲; 遲; 遲; 遲; ) CJK COMPATIBILITY IDEOGRAPH-FAC3
+FAC4;9199;9199;9199;9199; # (醙; 醙; 醙; 醙; 醙; ) CJK COMPATIBILITY IDEOGRAPH-FAC4
+FAC5;9276;9276;9276;9276; # (鉶; 鉶; 鉶; 鉶; 鉶; ) CJK COMPATIBILITY IDEOGRAPH-FAC5
+FAC6;967C;967C;967C;967C; # (陼; 陼; 陼; 陼; 陼; ) CJK COMPATIBILITY IDEOGRAPH-FAC6
+FAC7;96E3;96E3;96E3;96E3; # (難; 難; 難; 難; 難; ) CJK COMPATIBILITY IDEOGRAPH-FAC7
+FAC8;9756;9756;9756;9756; # (靖; 靖; 靖; 靖; 靖; ) CJK COMPATIBILITY IDEOGRAPH-FAC8
+FAC9;97DB;97DB;97DB;97DB; # (韛; 韛; 韛; 韛; 韛; ) CJK COMPATIBILITY IDEOGRAPH-FAC9
+FACA;97FF;97FF;97FF;97FF; # (響; 響; 響; 響; 響; ) CJK COMPATIBILITY IDEOGRAPH-FACA
+FACB;980B;980B;980B;980B; # (頋; 頋; 頋; 頋; 頋; ) CJK COMPATIBILITY IDEOGRAPH-FACB
+FACC;983B;983B;983B;983B; # (頻; 頻; 頻; 頻; 頻; ) CJK COMPATIBILITY IDEOGRAPH-FACC
+FACD;9B12;9B12;9B12;9B12; # (鬒; 鬒; 鬒; 鬒; 鬒; ) CJK COMPATIBILITY IDEOGRAPH-FACD
+FACE;9F9C;9F9C;9F9C;9F9C; # (龜; 龜; 龜; 龜; 龜; ) CJK COMPATIBILITY IDEOGRAPH-FACE
+FACF;2284A;2284A;2284A;2284A; # (𢡊; 𢡊; 𢡊; 𢡊; 𢡊; ) CJK COMPATIBILITY IDEOGRAPH-FACF
+FAD0;22844;22844;22844;22844; # (𢡄; 𢡄; 𢡄; 𢡄; 𢡄; ) CJK COMPATIBILITY IDEOGRAPH-FAD0
+FAD1;233D5;233D5;233D5;233D5; # (𣏕; 𣏕; 𣏕; 𣏕; 𣏕; ) CJK COMPATIBILITY IDEOGRAPH-FAD1
+FAD2;3B9D;3B9D;3B9D;3B9D; # (㮝; 㮝; 㮝; 㮝; 㮝; ) CJK COMPATIBILITY IDEOGRAPH-FAD2
+FAD3;4018;4018;4018;4018; # (䀘; 䀘; 䀘; 䀘; 䀘; ) CJK COMPATIBILITY IDEOGRAPH-FAD3
+FAD4;4039;4039;4039;4039; # (䀹; 䀹; 䀹; 䀹; 䀹; ) CJK COMPATIBILITY IDEOGRAPH-FAD4
+FAD5;25249;25249;25249;25249; # (𥉉; 𥉉; 𥉉; 𥉉; 𥉉; ) CJK COMPATIBILITY IDEOGRAPH-FAD5
+FAD6;25CD0;25CD0;25CD0;25CD0; # (𥳐; 𥳐; 𥳐; 𥳐; 𥳐; ) CJK COMPATIBILITY IDEOGRAPH-FAD6
+FAD7;27ED3;27ED3;27ED3;27ED3; # (𧻓; 𧻓; 𧻓; 𧻓; 𧻓; ) CJK COMPATIBILITY IDEOGRAPH-FAD7
+FAD8;9F43;9F43;9F43;9F43; # (齃; 齃; 齃; 齃; 齃; ) CJK COMPATIBILITY IDEOGRAPH-FAD8
+FAD9;9F8E;9F8E;9F8E;9F8E; # (龎; 龎; 龎; 龎; 龎; ) CJK COMPATIBILITY IDEOGRAPH-FAD9
+FB00;FB00;FB00;0066 0066;0066 0066; # (ff; ff; ff; ff; ff; ) LATIN SMALL LIGATURE FF
+FB01;FB01;FB01;0066 0069;0066 0069; # (fi; fi; fi; fi; fi; ) LATIN SMALL LIGATURE FI
+FB02;FB02;FB02;0066 006C;0066 006C; # (fl; fl; fl; fl; fl; ) LATIN SMALL LIGATURE FL
+FB03;FB03;FB03;0066 0066 0069;0066 0066 0069; # (ffi; ffi; ffi; ffi; ffi; ) LATIN SMALL LIGATURE FFI
+FB04;FB04;FB04;0066 0066 006C;0066 0066 006C; # (ffl; ffl; ffl; ffl; ffl; ) LATIN SMALL LIGATURE FFL
+FB05;FB05;FB05;0073 0074;0073 0074; # (ſt; ſt; ſt; st; st; ) LATIN SMALL LIGATURE LONG S T
+FB06;FB06;FB06;0073 0074;0073 0074; # (st; st; st; st; st; ) LATIN SMALL LIGATURE ST
+FB13;FB13;FB13;0574 0576;0574 0576; # (ﬓ; ﬓ; ﬓ; մն; մն; ) ARMENIAN SMALL LIGATURE MEN NOW
+FB14;FB14;FB14;0574 0565;0574 0565; # (ﬔ; ﬔ; ﬔ; մե; մե; ) ARMENIAN SMALL LIGATURE MEN ECH
+FB15;FB15;FB15;0574 056B;0574 056B; # (ﬕ; ﬕ; ﬕ; մի; մի; ) ARMENIAN SMALL LIGATURE MEN INI
+FB16;FB16;FB16;057E 0576;057E 0576; # (ﬖ; ﬖ; ﬖ; վն; վն; ) ARMENIAN SMALL LIGATURE VEW NOW
+FB17;FB17;FB17;0574 056D;0574 056D; # (ﬗ; ﬗ; ﬗ; մխ; մխ; ) ARMENIAN SMALL LIGATURE MEN XEH
+FB1D;05D9 05B4;05D9 05B4;05D9 05B4;05D9 05B4; # (יִ; י◌ִ; י◌ִ; י◌ִ; י◌ִ; ) HEBREW LETTER YOD WITH HIRIQ
+FB1F;05F2 05B7;05F2 05B7;05F2 05B7;05F2 05B7; # (ײַ; ײ◌ַ; ײ◌ַ; ײ◌ַ; ײ◌ַ; ) HEBREW LIGATURE YIDDISH YOD YOD PATAH
+FB20;FB20;FB20;05E2;05E2; # (ﬠ; ﬠ; ﬠ; ע; ע; ) HEBREW LETTER ALTERNATIVE AYIN
+FB21;FB21;FB21;05D0;05D0; # (ﬡ; ﬡ; ﬡ; א; א; ) HEBREW LETTER WIDE ALEF
+FB22;FB22;FB22;05D3;05D3; # (ﬢ; ﬢ; ﬢ; ד; ד; ) HEBREW LETTER WIDE DALET
+FB23;FB23;FB23;05D4;05D4; # (ﬣ; ﬣ; ﬣ; ה; ה; ) HEBREW LETTER WIDE HE
+FB24;FB24;FB24;05DB;05DB; # (ﬤ; ﬤ; ﬤ; כ; כ; ) HEBREW LETTER WIDE KAF
+FB25;FB25;FB25;05DC;05DC; # (ﬥ; ﬥ; ﬥ; ל; ל; ) HEBREW LETTER WIDE LAMED
+FB26;FB26;FB26;05DD;05DD; # (ﬦ; ﬦ; ﬦ; ם; ם; ) HEBREW LETTER WIDE FINAL MEM
+FB27;FB27;FB27;05E8;05E8; # (ﬧ; ﬧ; ﬧ; ר; ר; ) HEBREW LETTER WIDE RESH
+FB28;FB28;FB28;05EA;05EA; # (ﬨ; ﬨ; ﬨ; ת; ת; ) HEBREW LETTER WIDE TAV
+FB29;FB29;FB29;002B;002B; # (﬩; ﬩; ﬩; +; +; ) HEBREW LETTER ALTERNATIVE PLUS SIGN
+FB2A;05E9 05C1;05E9 05C1;05E9 05C1;05E9 05C1; # (שׁ; ש◌ׁ; ש◌ׁ; ש◌ׁ; ש◌ׁ; ) HEBREW LETTER SHIN WITH SHIN DOT
+FB2B;05E9 05C2;05E9 05C2;05E9 05C2;05E9 05C2; # (שׂ; ש◌ׂ; ש◌ׂ; ש◌ׂ; ש◌ׂ; ) HEBREW LETTER SHIN WITH SIN DOT
+FB2C;05E9 05BC 05C1;05E9 05BC 05C1;05E9 05BC 05C1;05E9 05BC 05C1; # (שּׁ; ש◌ּ◌ׁ; ש◌ּ◌ׁ; ש◌ּ◌ׁ; ש◌ּ◌ׁ; ) HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT
+FB2D;05E9 05BC 05C2;05E9 05BC 05C2;05E9 05BC 05C2;05E9 05BC 05C2; # (שּׂ; ש◌ּ◌ׂ; ש◌ּ◌ׂ; ש◌ּ◌ׂ; ש◌ּ◌ׂ; ) HEBREW LETTER SHIN WITH DAGESH AND SIN DOT
+FB2E;05D0 05B7;05D0 05B7;05D0 05B7;05D0 05B7; # (אַ; א◌ַ; א◌ַ; א◌ַ; א◌ַ; ) HEBREW LETTER ALEF WITH PATAH
+FB2F;05D0 05B8;05D0 05B8;05D0 05B8;05D0 05B8; # (אָ; א◌ָ; א◌ָ; א◌ָ; א◌ָ; ) HEBREW LETTER ALEF WITH QAMATS
+FB30;05D0 05BC;05D0 05BC;05D0 05BC;05D0 05BC; # (אּ; א◌ּ; א◌ּ; א◌ּ; א◌ּ; ) HEBREW LETTER ALEF WITH MAPIQ
+FB31;05D1 05BC;05D1 05BC;05D1 05BC;05D1 05BC; # (בּ; ב◌ּ; ב◌ּ; ב◌ּ; ב◌ּ; ) HEBREW LETTER BET WITH DAGESH
+FB32;05D2 05BC;05D2 05BC;05D2 05BC;05D2 05BC; # (גּ; ג◌ּ; ג◌ּ; ג◌ּ; ג◌ּ; ) HEBREW LETTER GIMEL WITH DAGESH
+FB33;05D3 05BC;05D3 05BC;05D3 05BC;05D3 05BC; # (דּ; ד◌ּ; ד◌ּ; ד◌ּ; ד◌ּ; ) HEBREW LETTER DALET WITH DAGESH
+FB34;05D4 05BC;05D4 05BC;05D4 05BC;05D4 05BC; # (הּ; ה◌ּ; ה◌ּ; ה◌ּ; ה◌ּ; ) HEBREW LETTER HE WITH MAPIQ
+FB35;05D5 05BC;05D5 05BC;05D5 05BC;05D5 05BC; # (וּ; ו◌ּ; ו◌ּ; ו◌ּ; ו◌ּ; ) HEBREW LETTER VAV WITH DAGESH
+FB36;05D6 05BC;05D6 05BC;05D6 05BC;05D6 05BC; # (זּ; ז◌ּ; ז◌ּ; ז◌ּ; ז◌ּ; ) HEBREW LETTER ZAYIN WITH DAGESH
+FB38;05D8 05BC;05D8 05BC;05D8 05BC;05D8 05BC; # (טּ; ט◌ּ; ט◌ּ; ט◌ּ; ט◌ּ; ) HEBREW LETTER TET WITH DAGESH
+FB39;05D9 05BC;05D9 05BC;05D9 05BC;05D9 05BC; # (יּ; י◌ּ; י◌ּ; י◌ּ; י◌ּ; ) HEBREW LETTER YOD WITH DAGESH
+FB3A;05DA 05BC;05DA 05BC;05DA 05BC;05DA 05BC; # (ךּ; ך◌ּ; ך◌ּ; ך◌ּ; ך◌ּ; ) HEBREW LETTER FINAL KAF WITH DAGESH
+FB3B;05DB 05BC;05DB 05BC;05DB 05BC;05DB 05BC; # (כּ; כ◌ּ; כ◌ּ; כ◌ּ; כ◌ּ; ) HEBREW LETTER KAF WITH DAGESH
+FB3C;05DC 05BC;05DC 05BC;05DC 05BC;05DC 05BC; # (לּ; ל◌ּ; ל◌ּ; ל◌ּ; ל◌ּ; ) HEBREW LETTER LAMED WITH DAGESH
+FB3E;05DE 05BC;05DE 05BC;05DE 05BC;05DE 05BC; # (מּ; מ◌ּ; מ◌ּ; מ◌ּ; מ◌ּ; ) HEBREW LETTER MEM WITH DAGESH
+FB40;05E0 05BC;05E0 05BC;05E0 05BC;05E0 05BC; # (נּ; נ◌ּ; נ◌ּ; נ◌ּ; נ◌ּ; ) HEBREW LETTER NUN WITH DAGESH
+FB41;05E1 05BC;05E1 05BC;05E1 05BC;05E1 05BC; # (סּ; ס◌ּ; ס◌ּ; ס◌ּ; ס◌ּ; ) HEBREW LETTER SAMEKH WITH DAGESH
+FB43;05E3 05BC;05E3 05BC;05E3 05BC;05E3 05BC; # (ףּ; ף◌ּ; ף◌ּ; ף◌ּ; ף◌ּ; ) HEBREW LETTER FINAL PE WITH DAGESH
+FB44;05E4 05BC;05E4 05BC;05E4 05BC;05E4 05BC; # (פּ; פ◌ּ; פ◌ּ; פ◌ּ; פ◌ּ; ) HEBREW LETTER PE WITH DAGESH
+FB46;05E6 05BC;05E6 05BC;05E6 05BC;05E6 05BC; # (צּ; צ◌ּ; צ◌ּ; צ◌ּ; צ◌ּ; ) HEBREW LETTER TSADI WITH DAGESH
+FB47;05E7 05BC;05E7 05BC;05E7 05BC;05E7 05BC; # (קּ; ק◌ּ; ק◌ּ; ק◌ּ; ק◌ּ; ) HEBREW LETTER QOF WITH DAGESH
+FB48;05E8 05BC;05E8 05BC;05E8 05BC;05E8 05BC; # (רּ; ר◌ּ; ר◌ּ; ר◌ּ; ר◌ּ; ) HEBREW LETTER RESH WITH DAGESH
+FB49;05E9 05BC;05E9 05BC;05E9 05BC;05E9 05BC; # (שּ; ש◌ּ; ש◌ּ; ש◌ּ; ש◌ּ; ) HEBREW LETTER SHIN WITH DAGESH
+FB4A;05EA 05BC;05EA 05BC;05EA 05BC;05EA 05BC; # (תּ; ת◌ּ; ת◌ּ; ת◌ּ; ת◌ּ; ) HEBREW LETTER TAV WITH DAGESH
+FB4B;05D5 05B9;05D5 05B9;05D5 05B9;05D5 05B9; # (וֹ; ו◌ֹ; ו◌ֹ; ו◌ֹ; ו◌ֹ; ) HEBREW LETTER VAV WITH HOLAM
+FB4C;05D1 05BF;05D1 05BF;05D1 05BF;05D1 05BF; # (בֿ; ב◌ֿ; ב◌ֿ; ב◌ֿ; ב◌ֿ; ) HEBREW LETTER BET WITH RAFE
+FB4D;05DB 05BF;05DB 05BF;05DB 05BF;05DB 05BF; # (כֿ; כ◌ֿ; כ◌ֿ; כ◌ֿ; כ◌ֿ; ) HEBREW LETTER KAF WITH RAFE
+FB4E;05E4 05BF;05E4 05BF;05E4 05BF;05E4 05BF; # (פֿ; פ◌ֿ; פ◌ֿ; פ◌ֿ; פ◌ֿ; ) HEBREW LETTER PE WITH RAFE
+FB4F;FB4F;FB4F;05D0 05DC;05D0 05DC; # (ﭏ; ﭏ; ﭏ; אל; אל; ) HEBREW LIGATURE ALEF LAMED
+FB50;FB50;FB50;0671;0671; # (ﭐ; ﭐ; ﭐ; ٱ; ٱ; ) ARABIC LETTER ALEF WASLA ISOLATED FORM
+FB51;FB51;FB51;0671;0671; # (ﭑ; ﭑ; ﭑ; ٱ; ٱ; ) ARABIC LETTER ALEF WASLA FINAL FORM
+FB52;FB52;FB52;067B;067B; # (ﭒ; ﭒ; ﭒ; ٻ; ٻ; ) ARABIC LETTER BEEH ISOLATED FORM
+FB53;FB53;FB53;067B;067B; # (ﭓ; ﭓ; ﭓ; ٻ; ٻ; ) ARABIC LETTER BEEH FINAL FORM
+FB54;FB54;FB54;067B;067B; # (ﭔ; ﭔ; ﭔ; ٻ; ٻ; ) ARABIC LETTER BEEH INITIAL FORM
+FB55;FB55;FB55;067B;067B; # (ﭕ; ﭕ; ﭕ; ٻ; ٻ; ) ARABIC LETTER BEEH MEDIAL FORM
+FB56;FB56;FB56;067E;067E; # (ﭖ; ﭖ; ﭖ; پ; پ; ) ARABIC LETTER PEH ISOLATED FORM
+FB57;FB57;FB57;067E;067E; # (ﭗ; ﭗ; ﭗ; پ; پ; ) ARABIC LETTER PEH FINAL FORM
+FB58;FB58;FB58;067E;067E; # (ﭘ; ﭘ; ﭘ; پ; پ; ) ARABIC LETTER PEH INITIAL FORM
+FB59;FB59;FB59;067E;067E; # (ﭙ; ﭙ; ﭙ; پ; پ; ) ARABIC LETTER PEH MEDIAL FORM
+FB5A;FB5A;FB5A;0680;0680; # (ﭚ; ﭚ; ﭚ; ڀ; ڀ; ) ARABIC LETTER BEHEH ISOLATED FORM
+FB5B;FB5B;FB5B;0680;0680; # (ﭛ; ﭛ; ﭛ; ڀ; ڀ; ) ARABIC LETTER BEHEH FINAL FORM
+FB5C;FB5C;FB5C;0680;0680; # (ﭜ; ﭜ; ﭜ; ڀ; ڀ; ) ARABIC LETTER BEHEH INITIAL FORM
+FB5D;FB5D;FB5D;0680;0680; # (ﭝ; ﭝ; ﭝ; ڀ; ڀ; ) ARABIC LETTER BEHEH MEDIAL FORM
+FB5E;FB5E;FB5E;067A;067A; # (ﭞ; ﭞ; ﭞ; ٺ; ٺ; ) ARABIC LETTER TTEHEH ISOLATED FORM
+FB5F;FB5F;FB5F;067A;067A; # (ﭟ; ﭟ; ﭟ; ٺ; ٺ; ) ARABIC LETTER TTEHEH FINAL FORM
+FB60;FB60;FB60;067A;067A; # (ﭠ; ﭠ; ﭠ; ٺ; ٺ; ) ARABIC LETTER TTEHEH INITIAL FORM
+FB61;FB61;FB61;067A;067A; # (ﭡ; ﭡ; ﭡ; ٺ; ٺ; ) ARABIC LETTER TTEHEH MEDIAL FORM
+FB62;FB62;FB62;067F;067F; # (ﭢ; ﭢ; ﭢ; ٿ; ٿ; ) ARABIC LETTER TEHEH ISOLATED FORM
+FB63;FB63;FB63;067F;067F; # (ﭣ; ﭣ; ﭣ; ٿ; ٿ; ) ARABIC LETTER TEHEH FINAL FORM
+FB64;FB64;FB64;067F;067F; # (ﭤ; ﭤ; ﭤ; ٿ; ٿ; ) ARABIC LETTER TEHEH INITIAL FORM
+FB65;FB65;FB65;067F;067F; # (ﭥ; ﭥ; ﭥ; ٿ; ٿ; ) ARABIC LETTER TEHEH MEDIAL FORM
+FB66;FB66;FB66;0679;0679; # (ﭦ; ﭦ; ﭦ; ٹ; ٹ; ) ARABIC LETTER TTEH ISOLATED FORM
+FB67;FB67;FB67;0679;0679; # (ﭧ; ﭧ; ﭧ; ٹ; ٹ; ) ARABIC LETTER TTEH FINAL FORM
+FB68;FB68;FB68;0679;0679; # (ﭨ; ﭨ; ﭨ; ٹ; ٹ; ) ARABIC LETTER TTEH INITIAL FORM
+FB69;FB69;FB69;0679;0679; # (ﭩ; ﭩ; ﭩ; ٹ; ٹ; ) ARABIC LETTER TTEH MEDIAL FORM
+FB6A;FB6A;FB6A;06A4;06A4; # (ﭪ; ﭪ; ﭪ; ڤ; ڤ; ) ARABIC LETTER VEH ISOLATED FORM
+FB6B;FB6B;FB6B;06A4;06A4; # (ﭫ; ﭫ; ﭫ; ڤ; ڤ; ) ARABIC LETTER VEH FINAL FORM
+FB6C;FB6C;FB6C;06A4;06A4; # (ﭬ; ﭬ; ﭬ; ڤ; ڤ; ) ARABIC LETTER VEH INITIAL FORM
+FB6D;FB6D;FB6D;06A4;06A4; # (ﭭ; ﭭ; ﭭ; ڤ; ڤ; ) ARABIC LETTER VEH MEDIAL FORM
+FB6E;FB6E;FB6E;06A6;06A6; # (ﭮ; ﭮ; ﭮ; ڦ; ڦ; ) ARABIC LETTER PEHEH ISOLATED FORM
+FB6F;FB6F;FB6F;06A6;06A6; # (ﭯ; ﭯ; ﭯ; ڦ; ڦ; ) ARABIC LETTER PEHEH FINAL FORM
+FB70;FB70;FB70;06A6;06A6; # (ﭰ; ﭰ; ﭰ; ڦ; ڦ; ) ARABIC LETTER PEHEH INITIAL FORM
+FB71;FB71;FB71;06A6;06A6; # (ﭱ; ﭱ; ﭱ; ڦ; ڦ; ) ARABIC LETTER PEHEH MEDIAL FORM
+FB72;FB72;FB72;0684;0684; # (ﭲ; ﭲ; ﭲ; ڄ; ڄ; ) ARABIC LETTER DYEH ISOLATED FORM
+FB73;FB73;FB73;0684;0684; # (ﭳ; ﭳ; ﭳ; ڄ; ڄ; ) ARABIC LETTER DYEH FINAL FORM
+FB74;FB74;FB74;0684;0684; # (ﭴ; ﭴ; ﭴ; ڄ; ڄ; ) ARABIC LETTER DYEH INITIAL FORM
+FB75;FB75;FB75;0684;0684; # (ﭵ; ﭵ; ﭵ; ڄ; ڄ; ) ARABIC LETTER DYEH MEDIAL FORM
+FB76;FB76;FB76;0683;0683; # (ﭶ; ﭶ; ﭶ; ڃ; ڃ; ) ARABIC LETTER NYEH ISOLATED FORM
+FB77;FB77;FB77;0683;0683; # (ﭷ; ﭷ; ﭷ; ڃ; ڃ; ) ARABIC LETTER NYEH FINAL FORM
+FB78;FB78;FB78;0683;0683; # (ﭸ; ﭸ; ﭸ; ڃ; ڃ; ) ARABIC LETTER NYEH INITIAL FORM
+FB79;FB79;FB79;0683;0683; # (ﭹ; ﭹ; ﭹ; ڃ; ڃ; ) ARABIC LETTER NYEH MEDIAL FORM
+FB7A;FB7A;FB7A;0686;0686; # (ﭺ; ﭺ; ﭺ; چ; چ; ) ARABIC LETTER TCHEH ISOLATED FORM
+FB7B;FB7B;FB7B;0686;0686; # (ﭻ; ﭻ; ﭻ; چ; چ; ) ARABIC LETTER TCHEH FINAL FORM
+FB7C;FB7C;FB7C;0686;0686; # (ﭼ; ﭼ; ﭼ; چ; چ; ) ARABIC LETTER TCHEH INITIAL FORM
+FB7D;FB7D;FB7D;0686;0686; # (ﭽ; ﭽ; ﭽ; چ; چ; ) ARABIC LETTER TCHEH MEDIAL FORM
+FB7E;FB7E;FB7E;0687;0687; # (ﭾ; ﭾ; ﭾ; ڇ; ڇ; ) ARABIC LETTER TCHEHEH ISOLATED FORM
+FB7F;FB7F;FB7F;0687;0687; # (ﭿ; ﭿ; ﭿ; ڇ; ڇ; ) ARABIC LETTER TCHEHEH FINAL FORM
+FB80;FB80;FB80;0687;0687; # (ﮀ; ﮀ; ﮀ; ڇ; ڇ; ) ARABIC LETTER TCHEHEH INITIAL FORM
+FB81;FB81;FB81;0687;0687; # (ﮁ; ﮁ; ﮁ; ڇ; ڇ; ) ARABIC LETTER TCHEHEH MEDIAL FORM
+FB82;FB82;FB82;068D;068D; # (ﮂ; ﮂ; ﮂ; ڍ; ڍ; ) ARABIC LETTER DDAHAL ISOLATED FORM
+FB83;FB83;FB83;068D;068D; # (ﮃ; ﮃ; ﮃ; ڍ; ڍ; ) ARABIC LETTER DDAHAL FINAL FORM
+FB84;FB84;FB84;068C;068C; # (ﮄ; ﮄ; ﮄ; ڌ; ڌ; ) ARABIC LETTER DAHAL ISOLATED FORM
+FB85;FB85;FB85;068C;068C; # (ﮅ; ﮅ; ﮅ; ڌ; ڌ; ) ARABIC LETTER DAHAL FINAL FORM
+FB86;FB86;FB86;068E;068E; # (ﮆ; ﮆ; ﮆ; ڎ; ڎ; ) ARABIC LETTER DUL ISOLATED FORM
+FB87;FB87;FB87;068E;068E; # (ﮇ; ﮇ; ﮇ; ڎ; ڎ; ) ARABIC LETTER DUL FINAL FORM
+FB88;FB88;FB88;0688;0688; # (ﮈ; ﮈ; ﮈ; ڈ; ڈ; ) ARABIC LETTER DDAL ISOLATED FORM
+FB89;FB89;FB89;0688;0688; # (ﮉ; ﮉ; ﮉ; ڈ; ڈ; ) ARABIC LETTER DDAL FINAL FORM
+FB8A;FB8A;FB8A;0698;0698; # (ﮊ; ﮊ; ﮊ; ژ; ژ; ) ARABIC LETTER JEH ISOLATED FORM
+FB8B;FB8B;FB8B;0698;0698; # (ﮋ; ﮋ; ﮋ; ژ; ژ; ) ARABIC LETTER JEH FINAL FORM
+FB8C;FB8C;FB8C;0691;0691; # (ﮌ; ﮌ; ﮌ; ڑ; ڑ; ) ARABIC LETTER RREH ISOLATED FORM
+FB8D;FB8D;FB8D;0691;0691; # (ﮍ; ﮍ; ﮍ; ڑ; ڑ; ) ARABIC LETTER RREH FINAL FORM
+FB8E;FB8E;FB8E;06A9;06A9; # (ﮎ; ﮎ; ﮎ; ک; ک; ) ARABIC LETTER KEHEH ISOLATED FORM
+FB8F;FB8F;FB8F;06A9;06A9; # (ﮏ; ﮏ; ﮏ; ک; ک; ) ARABIC LETTER KEHEH FINAL FORM
+FB90;FB90;FB90;06A9;06A9; # (ﮐ; ﮐ; ﮐ; ک; ک; ) ARABIC LETTER KEHEH INITIAL FORM
+FB91;FB91;FB91;06A9;06A9; # (ﮑ; ﮑ; ﮑ; ک; ک; ) ARABIC LETTER KEHEH MEDIAL FORM
+FB92;FB92;FB92;06AF;06AF; # (ﮒ; ﮒ; ﮒ; گ; گ; ) ARABIC LETTER GAF ISOLATED FORM
+FB93;FB93;FB93;06AF;06AF; # (ﮓ; ﮓ; ﮓ; گ; گ; ) ARABIC LETTER GAF FINAL FORM
+FB94;FB94;FB94;06AF;06AF; # (ﮔ; ﮔ; ﮔ; گ; گ; ) ARABIC LETTER GAF INITIAL FORM
+FB95;FB95;FB95;06AF;06AF; # (ﮕ; ﮕ; ﮕ; گ; گ; ) ARABIC LETTER GAF MEDIAL FORM
+FB96;FB96;FB96;06B3;06B3; # (ﮖ; ﮖ; ﮖ; ڳ; ڳ; ) ARABIC LETTER GUEH ISOLATED FORM
+FB97;FB97;FB97;06B3;06B3; # (ﮗ; ﮗ; ﮗ; ڳ; ڳ; ) ARABIC LETTER GUEH FINAL FORM
+FB98;FB98;FB98;06B3;06B3; # (ﮘ; ﮘ; ﮘ; ڳ; ڳ; ) ARABIC LETTER GUEH INITIAL FORM
+FB99;FB99;FB99;06B3;06B3; # (ﮙ; ﮙ; ﮙ; ڳ; ڳ; ) ARABIC LETTER GUEH MEDIAL FORM
+FB9A;FB9A;FB9A;06B1;06B1; # (ﮚ; ﮚ; ﮚ; ڱ; ڱ; ) ARABIC LETTER NGOEH ISOLATED FORM
+FB9B;FB9B;FB9B;06B1;06B1; # (ﮛ; ﮛ; ﮛ; ڱ; ڱ; ) ARABIC LETTER NGOEH FINAL FORM
+FB9C;FB9C;FB9C;06B1;06B1; # (ﮜ; ﮜ; ﮜ; ڱ; ڱ; ) ARABIC LETTER NGOEH INITIAL FORM
+FB9D;FB9D;FB9D;06B1;06B1; # (ﮝ; ﮝ; ﮝ; ڱ; ڱ; ) ARABIC LETTER NGOEH MEDIAL FORM
+FB9E;FB9E;FB9E;06BA;06BA; # (ﮞ; ﮞ; ﮞ; ں; ں; ) ARABIC LETTER NOON GHUNNA ISOLATED FORM
+FB9F;FB9F;FB9F;06BA;06BA; # (ﮟ; ﮟ; ﮟ; ں; ں; ) ARABIC LETTER NOON GHUNNA FINAL FORM
+FBA0;FBA0;FBA0;06BB;06BB; # (ﮠ; ﮠ; ﮠ; ڻ; ڻ; ) ARABIC LETTER RNOON ISOLATED FORM
+FBA1;FBA1;FBA1;06BB;06BB; # (ﮡ; ﮡ; ﮡ; ڻ; ڻ; ) ARABIC LETTER RNOON FINAL FORM
+FBA2;FBA2;FBA2;06BB;06BB; # (ﮢ; ﮢ; ﮢ; ڻ; ڻ; ) ARABIC LETTER RNOON INITIAL FORM
+FBA3;FBA3;FBA3;06BB;06BB; # (ﮣ; ﮣ; ﮣ; ڻ; ڻ; ) ARABIC LETTER RNOON MEDIAL FORM
+FBA4;FBA4;FBA4;06C0;06D5 0654; # (ﮤ; ﮤ; ﮤ; ۀ; ە◌ٔ; ) ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM
+FBA5;FBA5;FBA5;06C0;06D5 0654; # (ﮥ; ﮥ; ﮥ; ۀ; ە◌ٔ; ) ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM
+FBA6;FBA6;FBA6;06C1;06C1; # (ﮦ; ﮦ; ﮦ; ہ; ہ; ) ARABIC LETTER HEH GOAL ISOLATED FORM
+FBA7;FBA7;FBA7;06C1;06C1; # (ﮧ; ﮧ; ﮧ; ہ; ہ; ) ARABIC LETTER HEH GOAL FINAL FORM
+FBA8;FBA8;FBA8;06C1;06C1; # (ﮨ; ﮨ; ﮨ; ہ; ہ; ) ARABIC LETTER HEH GOAL INITIAL FORM
+FBA9;FBA9;FBA9;06C1;06C1; # (ﮩ; ﮩ; ﮩ; ہ; ہ; ) ARABIC LETTER HEH GOAL MEDIAL FORM
+FBAA;FBAA;FBAA;06BE;06BE; # (ﮪ; ﮪ; ﮪ; ھ; ھ; ) ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM
+FBAB;FBAB;FBAB;06BE;06BE; # (ﮫ; ﮫ; ﮫ; ھ; ھ; ) ARABIC LETTER HEH DOACHASHMEE FINAL FORM
+FBAC;FBAC;FBAC;06BE;06BE; # (ﮬ; ﮬ; ﮬ; ھ; ھ; ) ARABIC LETTER HEH DOACHASHMEE INITIAL FORM
+FBAD;FBAD;FBAD;06BE;06BE; # (ﮭ; ﮭ; ﮭ; ھ; ھ; ) ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM
+FBAE;FBAE;FBAE;06D2;06D2; # (ﮮ; ﮮ; ﮮ; ے; ے; ) ARABIC LETTER YEH BARREE ISOLATED FORM
+FBAF;FBAF;FBAF;06D2;06D2; # (ﮯ; ﮯ; ﮯ; ے; ے; ) ARABIC LETTER YEH BARREE FINAL FORM
+FBB0;FBB0;FBB0;06D3;06D2 0654; # (ﮰ; ﮰ; ﮰ; ۓ; ے◌ٔ; ) ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM
+FBB1;FBB1;FBB1;06D3;06D2 0654; # (ﮱ; ﮱ; ﮱ; ۓ; ے◌ٔ; ) ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM
+FBD3;FBD3;FBD3;06AD;06AD; # (ﯓ; ﯓ; ﯓ; ڭ; ڭ; ) ARABIC LETTER NG ISOLATED FORM
+FBD4;FBD4;FBD4;06AD;06AD; # (ﯔ; ﯔ; ﯔ; ڭ; ڭ; ) ARABIC LETTER NG FINAL FORM
+FBD5;FBD5;FBD5;06AD;06AD; # (ﯕ; ﯕ; ﯕ; ڭ; ڭ; ) ARABIC LETTER NG INITIAL FORM
+FBD6;FBD6;FBD6;06AD;06AD; # (ﯖ; ﯖ; ﯖ; ڭ; ڭ; ) ARABIC LETTER NG MEDIAL FORM
+FBD7;FBD7;FBD7;06C7;06C7; # (ﯗ; ﯗ; ﯗ; ۇ; ۇ; ) ARABIC LETTER U ISOLATED FORM
+FBD8;FBD8;FBD8;06C7;06C7; # (ﯘ; ﯘ; ﯘ; ۇ; ۇ; ) ARABIC LETTER U FINAL FORM
+FBD9;FBD9;FBD9;06C6;06C6; # (ﯙ; ﯙ; ﯙ; ۆ; ۆ; ) ARABIC LETTER OE ISOLATED FORM
+FBDA;FBDA;FBDA;06C6;06C6; # (ﯚ; ﯚ; ﯚ; ۆ; ۆ; ) ARABIC LETTER OE FINAL FORM
+FBDB;FBDB;FBDB;06C8;06C8; # (ﯛ; ﯛ; ﯛ; ۈ; ۈ; ) ARABIC LETTER YU ISOLATED FORM
+FBDC;FBDC;FBDC;06C8;06C8; # (ﯜ; ﯜ; ﯜ; ۈ; ۈ; ) ARABIC LETTER YU FINAL FORM
+FBDD;FBDD;FBDD;06C7 0674;06C7 0674; # (ﯝ; ﯝ; ﯝ; ۇٴ; ۇٴ; ) ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM
+FBDE;FBDE;FBDE;06CB;06CB; # (ﯞ; ﯞ; ﯞ; ۋ; ۋ; ) ARABIC LETTER VE ISOLATED FORM
+FBDF;FBDF;FBDF;06CB;06CB; # (ﯟ; ﯟ; ﯟ; ۋ; ۋ; ) ARABIC LETTER VE FINAL FORM
+FBE0;FBE0;FBE0;06C5;06C5; # (ﯠ; ﯠ; ﯠ; ۅ; ۅ; ) ARABIC LETTER KIRGHIZ OE ISOLATED FORM
+FBE1;FBE1;FBE1;06C5;06C5; # (ﯡ; ﯡ; ﯡ; ۅ; ۅ; ) ARABIC LETTER KIRGHIZ OE FINAL FORM
+FBE2;FBE2;FBE2;06C9;06C9; # (ﯢ; ﯢ; ﯢ; ۉ; ۉ; ) ARABIC LETTER KIRGHIZ YU ISOLATED FORM
+FBE3;FBE3;FBE3;06C9;06C9; # (ﯣ; ﯣ; ﯣ; ۉ; ۉ; ) ARABIC LETTER KIRGHIZ YU FINAL FORM
+FBE4;FBE4;FBE4;06D0;06D0; # (ﯤ; ﯤ; ﯤ; ې; ې; ) ARABIC LETTER E ISOLATED FORM
+FBE5;FBE5;FBE5;06D0;06D0; # (ﯥ; ﯥ; ﯥ; ې; ې; ) ARABIC LETTER E FINAL FORM
+FBE6;FBE6;FBE6;06D0;06D0; # (ﯦ; ﯦ; ﯦ; ې; ې; ) ARABIC LETTER E INITIAL FORM
+FBE7;FBE7;FBE7;06D0;06D0; # (ﯧ; ﯧ; ﯧ; ې; ې; ) ARABIC LETTER E MEDIAL FORM
+FBE8;FBE8;FBE8;0649;0649; # (ﯨ; ﯨ; ﯨ; ى; ى; ) ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM
+FBE9;FBE9;FBE9;0649;0649; # (ﯩ; ﯩ; ﯩ; ى; ى; ) ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM
+FBEA;FBEA;FBEA;0626 0627;064A 0654 0627; # (ﯪ; ﯪ; ﯪ; ئا; ي◌ٔا; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM
+FBEB;FBEB;FBEB;0626 0627;064A 0654 0627; # (ﯫ; ﯫ; ﯫ; ئا; ي◌ٔا; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM
+FBEC;FBEC;FBEC;0626 06D5;064A 0654 06D5; # (ﯬ; ﯬ; ﯬ; ئە; ي◌ٔە; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM
+FBED;FBED;FBED;0626 06D5;064A 0654 06D5; # (ﯭ; ﯭ; ﯭ; ئە; ي◌ٔە; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM
+FBEE;FBEE;FBEE;0626 0648;064A 0654 0648; # (ﯮ; ﯮ; ﯮ; ئو; ي◌ٔو; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM
+FBEF;FBEF;FBEF;0626 0648;064A 0654 0648; # (ﯯ; ﯯ; ﯯ; ئو; ي◌ٔو; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM
+FBF0;FBF0;FBF0;0626 06C7;064A 0654 06C7; # (ﯰ; ﯰ; ﯰ; ئۇ; ي◌ٔۇ; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM
+FBF1;FBF1;FBF1;0626 06C7;064A 0654 06C7; # (ﯱ; ﯱ; ﯱ; ئۇ; ي◌ٔۇ; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM
+FBF2;FBF2;FBF2;0626 06C6;064A 0654 06C6; # (ﯲ; ﯲ; ﯲ; ئۆ; ي◌ٔۆ; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM
+FBF3;FBF3;FBF3;0626 06C6;064A 0654 06C6; # (ﯳ; ﯳ; ﯳ; ئۆ; ي◌ٔۆ; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM
+FBF4;FBF4;FBF4;0626 06C8;064A 0654 06C8; # (ﯴ; ﯴ; ﯴ; ئۈ; ي◌ٔۈ; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM
+FBF5;FBF5;FBF5;0626 06C8;064A 0654 06C8; # (ﯵ; ﯵ; ﯵ; ئۈ; ي◌ٔۈ; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM
+FBF6;FBF6;FBF6;0626 06D0;064A 0654 06D0; # (ﯶ; ﯶ; ﯶ; ئې; ي◌ٔې; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM
+FBF7;FBF7;FBF7;0626 06D0;064A 0654 06D0; # (ﯷ; ﯷ; ﯷ; ئې; ي◌ٔې; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM
+FBF8;FBF8;FBF8;0626 06D0;064A 0654 06D0; # (ﯸ; ﯸ; ﯸ; ئې; ي◌ٔې; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM
+FBF9;FBF9;FBF9;0626 0649;064A 0654 0649; # (ﯹ; ﯹ; ﯹ; ئى; ي◌ٔى; ) ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM
+FBFA;FBFA;FBFA;0626 0649;064A 0654 0649; # (ﯺ; ﯺ; ﯺ; ئى; ي◌ٔى; ) ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM
+FBFB;FBFB;FBFB;0626 0649;064A 0654 0649; # (ﯻ; ﯻ; ﯻ; ئى; ي◌ٔى; ) ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM
+FBFC;FBFC;FBFC;06CC;06CC; # (ﯼ; ﯼ; ﯼ; ی; ی; ) ARABIC LETTER FARSI YEH ISOLATED FORM
+FBFD;FBFD;FBFD;06CC;06CC; # (ﯽ; ﯽ; ﯽ; ی; ی; ) ARABIC LETTER FARSI YEH FINAL FORM
+FBFE;FBFE;FBFE;06CC;06CC; # (ﯾ; ﯾ; ﯾ; ی; ی; ) ARABIC LETTER FARSI YEH INITIAL FORM
+FBFF;FBFF;FBFF;06CC;06CC; # (ﯿ; ﯿ; ﯿ; ی; ی; ) ARABIC LETTER FARSI YEH MEDIAL FORM
+FC00;FC00;FC00;0626 062C;064A 0654 062C; # (ﰀ; ﰀ; ﰀ; ئج; ي◌ٔج; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM
+FC01;FC01;FC01;0626 062D;064A 0654 062D; # (ﰁ; ﰁ; ﰁ; ئح; ي◌ٔح; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM
+FC02;FC02;FC02;0626 0645;064A 0654 0645; # (ﰂ; ﰂ; ﰂ; ئم; ي◌ٔم; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM
+FC03;FC03;FC03;0626 0649;064A 0654 0649; # (ﰃ; ﰃ; ﰃ; ئى; ي◌ٔى; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM
+FC04;FC04;FC04;0626 064A;064A 0654 064A; # (ﰄ; ﰄ; ﰄ; ئي; ي◌ٔي; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM
+FC05;FC05;FC05;0628 062C;0628 062C; # (ﰅ; ﰅ; ﰅ; بج; بج; ) ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM
+FC06;FC06;FC06;0628 062D;0628 062D; # (ﰆ; ﰆ; ﰆ; بح; بح; ) ARABIC LIGATURE BEH WITH HAH ISOLATED FORM
+FC07;FC07;FC07;0628 062E;0628 062E; # (ﰇ; ﰇ; ﰇ; بخ; بخ; ) ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM
+FC08;FC08;FC08;0628 0645;0628 0645; # (ﰈ; ﰈ; ﰈ; بم; بم; ) ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM
+FC09;FC09;FC09;0628 0649;0628 0649; # (ﰉ; ﰉ; ﰉ; بى; بى; ) ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM
+FC0A;FC0A;FC0A;0628 064A;0628 064A; # (ﰊ; ﰊ; ﰊ; بي; بي; ) ARABIC LIGATURE BEH WITH YEH ISOLATED FORM
+FC0B;FC0B;FC0B;062A 062C;062A 062C; # (ﰋ; ﰋ; ﰋ; تج; تج; ) ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM
+FC0C;FC0C;FC0C;062A 062D;062A 062D; # (ﰌ; ﰌ; ﰌ; تح; تح; ) ARABIC LIGATURE TEH WITH HAH ISOLATED FORM
+FC0D;FC0D;FC0D;062A 062E;062A 062E; # (ﰍ; ﰍ; ﰍ; تخ; تخ; ) ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM
+FC0E;FC0E;FC0E;062A 0645;062A 0645; # (ﰎ; ﰎ; ﰎ; تم; تم; ) ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM
+FC0F;FC0F;FC0F;062A 0649;062A 0649; # (ﰏ; ﰏ; ﰏ; تى; تى; ) ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM
+FC10;FC10;FC10;062A 064A;062A 064A; # (ﰐ; ﰐ; ﰐ; تي; تي; ) ARABIC LIGATURE TEH WITH YEH ISOLATED FORM
+FC11;FC11;FC11;062B 062C;062B 062C; # (ﰑ; ﰑ; ﰑ; ثج; ثج; ) ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM
+FC12;FC12;FC12;062B 0645;062B 0645; # (ﰒ; ﰒ; ﰒ; ثم; ثم; ) ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM
+FC13;FC13;FC13;062B 0649;062B 0649; # (ﰓ; ﰓ; ﰓ; ثى; ثى; ) ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM
+FC14;FC14;FC14;062B 064A;062B 064A; # (ﰔ; ﰔ; ﰔ; ثي; ثي; ) ARABIC LIGATURE THEH WITH YEH ISOLATED FORM
+FC15;FC15;FC15;062C 062D;062C 062D; # (ﰕ; ﰕ; ﰕ; جح; جح; ) ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM
+FC16;FC16;FC16;062C 0645;062C 0645; # (ﰖ; ﰖ; ﰖ; جم; جم; ) ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM
+FC17;FC17;FC17;062D 062C;062D 062C; # (ﰗ; ﰗ; ﰗ; حج; حج; ) ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM
+FC18;FC18;FC18;062D 0645;062D 0645; # (ﰘ; ﰘ; ﰘ; حم; حم; ) ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM
+FC19;FC19;FC19;062E 062C;062E 062C; # (ﰙ; ﰙ; ﰙ; خج; خج; ) ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM
+FC1A;FC1A;FC1A;062E 062D;062E 062D; # (ﰚ; ﰚ; ﰚ; خح; خح; ) ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM
+FC1B;FC1B;FC1B;062E 0645;062E 0645; # (ﰛ; ﰛ; ﰛ; خم; خم; ) ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM
+FC1C;FC1C;FC1C;0633 062C;0633 062C; # (ﰜ; ﰜ; ﰜ; سج; سج; ) ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM
+FC1D;FC1D;FC1D;0633 062D;0633 062D; # (ﰝ; ﰝ; ﰝ; سح; سح; ) ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM
+FC1E;FC1E;FC1E;0633 062E;0633 062E; # (ﰞ; ﰞ; ﰞ; سخ; سخ; ) ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM
+FC1F;FC1F;FC1F;0633 0645;0633 0645; # (ﰟ; ﰟ; ﰟ; سم; سم; ) ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM
+FC20;FC20;FC20;0635 062D;0635 062D; # (ﰠ; ﰠ; ﰠ; صح; صح; ) ARABIC LIGATURE SAD WITH HAH ISOLATED FORM
+FC21;FC21;FC21;0635 0645;0635 0645; # (ﰡ; ﰡ; ﰡ; صم; صم; ) ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM
+FC22;FC22;FC22;0636 062C;0636 062C; # (ﰢ; ﰢ; ﰢ; ضج; ضج; ) ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM
+FC23;FC23;FC23;0636 062D;0636 062D; # (ﰣ; ﰣ; ﰣ; ضح; ضح; ) ARABIC LIGATURE DAD WITH HAH ISOLATED FORM
+FC24;FC24;FC24;0636 062E;0636 062E; # (ﰤ; ﰤ; ﰤ; ضخ; ضخ; ) ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM
+FC25;FC25;FC25;0636 0645;0636 0645; # (ﰥ; ﰥ; ﰥ; ضم; ضم; ) ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM
+FC26;FC26;FC26;0637 062D;0637 062D; # (ﰦ; ﰦ; ﰦ; طح; طح; ) ARABIC LIGATURE TAH WITH HAH ISOLATED FORM
+FC27;FC27;FC27;0637 0645;0637 0645; # (ﰧ; ﰧ; ﰧ; طم; طم; ) ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM
+FC28;FC28;FC28;0638 0645;0638 0645; # (ﰨ; ﰨ; ﰨ; ظم; ظم; ) ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM
+FC29;FC29;FC29;0639 062C;0639 062C; # (ﰩ; ﰩ; ﰩ; عج; عج; ) ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM
+FC2A;FC2A;FC2A;0639 0645;0639 0645; # (ﰪ; ﰪ; ﰪ; عم; عم; ) ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM
+FC2B;FC2B;FC2B;063A 062C;063A 062C; # (ﰫ; ﰫ; ﰫ; غج; غج; ) ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM
+FC2C;FC2C;FC2C;063A 0645;063A 0645; # (ﰬ; ﰬ; ﰬ; غم; غم; ) ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM
+FC2D;FC2D;FC2D;0641 062C;0641 062C; # (ﰭ; ﰭ; ﰭ; فج; فج; ) ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM
+FC2E;FC2E;FC2E;0641 062D;0641 062D; # (ﰮ; ﰮ; ﰮ; فح; فح; ) ARABIC LIGATURE FEH WITH HAH ISOLATED FORM
+FC2F;FC2F;FC2F;0641 062E;0641 062E; # (ﰯ; ﰯ; ﰯ; فخ; فخ; ) ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM
+FC30;FC30;FC30;0641 0645;0641 0645; # (ﰰ; ﰰ; ﰰ; فم; فم; ) ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM
+FC31;FC31;FC31;0641 0649;0641 0649; # (ﰱ; ﰱ; ﰱ; فى; فى; ) ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM
+FC32;FC32;FC32;0641 064A;0641 064A; # (ﰲ; ﰲ; ﰲ; في; في; ) ARABIC LIGATURE FEH WITH YEH ISOLATED FORM
+FC33;FC33;FC33;0642 062D;0642 062D; # (ﰳ; ﰳ; ﰳ; قح; قح; ) ARABIC LIGATURE QAF WITH HAH ISOLATED FORM
+FC34;FC34;FC34;0642 0645;0642 0645; # (ﰴ; ﰴ; ﰴ; قم; قم; ) ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM
+FC35;FC35;FC35;0642 0649;0642 0649; # (ﰵ; ﰵ; ﰵ; قى; قى; ) ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM
+FC36;FC36;FC36;0642 064A;0642 064A; # (ﰶ; ﰶ; ﰶ; قي; قي; ) ARABIC LIGATURE QAF WITH YEH ISOLATED FORM
+FC37;FC37;FC37;0643 0627;0643 0627; # (ﰷ; ﰷ; ﰷ; كا; كا; ) ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM
+FC38;FC38;FC38;0643 062C;0643 062C; # (ﰸ; ﰸ; ﰸ; كج; كج; ) ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM
+FC39;FC39;FC39;0643 062D;0643 062D; # (ﰹ; ﰹ; ﰹ; كح; كح; ) ARABIC LIGATURE KAF WITH HAH ISOLATED FORM
+FC3A;FC3A;FC3A;0643 062E;0643 062E; # (ﰺ; ﰺ; ﰺ; كخ; كخ; ) ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM
+FC3B;FC3B;FC3B;0643 0644;0643 0644; # (ﰻ; ﰻ; ﰻ; كل; كل; ) ARABIC LIGATURE KAF WITH LAM ISOLATED FORM
+FC3C;FC3C;FC3C;0643 0645;0643 0645; # (ﰼ; ﰼ; ﰼ; كم; كم; ) ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM
+FC3D;FC3D;FC3D;0643 0649;0643 0649; # (ﰽ; ﰽ; ﰽ; كى; كى; ) ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM
+FC3E;FC3E;FC3E;0643 064A;0643 064A; # (ﰾ; ﰾ; ﰾ; كي; كي; ) ARABIC LIGATURE KAF WITH YEH ISOLATED FORM
+FC3F;FC3F;FC3F;0644 062C;0644 062C; # (ﰿ; ﰿ; ﰿ; لج; لج; ) ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM
+FC40;FC40;FC40;0644 062D;0644 062D; # (ﱀ; ﱀ; ﱀ; لح; لح; ) ARABIC LIGATURE LAM WITH HAH ISOLATED FORM
+FC41;FC41;FC41;0644 062E;0644 062E; # (ﱁ; ﱁ; ﱁ; لخ; لخ; ) ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM
+FC42;FC42;FC42;0644 0645;0644 0645; # (ﱂ; ﱂ; ﱂ; لم; لم; ) ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM
+FC43;FC43;FC43;0644 0649;0644 0649; # (ﱃ; ﱃ; ﱃ; لى; لى; ) ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM
+FC44;FC44;FC44;0644 064A;0644 064A; # (ﱄ; ﱄ; ﱄ; لي; لي; ) ARABIC LIGATURE LAM WITH YEH ISOLATED FORM
+FC45;FC45;FC45;0645 062C;0645 062C; # (ﱅ; ﱅ; ﱅ; مج; مج; ) ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM
+FC46;FC46;FC46;0645 062D;0645 062D; # (ﱆ; ﱆ; ﱆ; مح; مح; ) ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM
+FC47;FC47;FC47;0645 062E;0645 062E; # (ﱇ; ﱇ; ﱇ; مخ; مخ; ) ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM
+FC48;FC48;FC48;0645 0645;0645 0645; # (ﱈ; ﱈ; ﱈ; مم; مم; ) ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM
+FC49;FC49;FC49;0645 0649;0645 0649; # (ﱉ; ﱉ; ﱉ; مى; مى; ) ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM
+FC4A;FC4A;FC4A;0645 064A;0645 064A; # (ﱊ; ﱊ; ﱊ; مي; مي; ) ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM
+FC4B;FC4B;FC4B;0646 062C;0646 062C; # (ﱋ; ﱋ; ﱋ; نج; نج; ) ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM
+FC4C;FC4C;FC4C;0646 062D;0646 062D; # (ﱌ; ﱌ; ﱌ; نح; نح; ) ARABIC LIGATURE NOON WITH HAH ISOLATED FORM
+FC4D;FC4D;FC4D;0646 062E;0646 062E; # (ﱍ; ﱍ; ﱍ; نخ; نخ; ) ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM
+FC4E;FC4E;FC4E;0646 0645;0646 0645; # (ﱎ; ﱎ; ﱎ; نم; نم; ) ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM
+FC4F;FC4F;FC4F;0646 0649;0646 0649; # (ﱏ; ﱏ; ﱏ; نى; نى; ) ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM
+FC50;FC50;FC50;0646 064A;0646 064A; # (ﱐ; ﱐ; ﱐ; ني; ني; ) ARABIC LIGATURE NOON WITH YEH ISOLATED FORM
+FC51;FC51;FC51;0647 062C;0647 062C; # (ﱑ; ﱑ; ﱑ; هج; هج; ) ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM
+FC52;FC52;FC52;0647 0645;0647 0645; # (ﱒ; ﱒ; ﱒ; هم; هم; ) ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM
+FC53;FC53;FC53;0647 0649;0647 0649; # (ﱓ; ﱓ; ﱓ; هى; هى; ) ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM
+FC54;FC54;FC54;0647 064A;0647 064A; # (ﱔ; ﱔ; ﱔ; هي; هي; ) ARABIC LIGATURE HEH WITH YEH ISOLATED FORM
+FC55;FC55;FC55;064A 062C;064A 062C; # (ﱕ; ﱕ; ﱕ; يج; يج; ) ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM
+FC56;FC56;FC56;064A 062D;064A 062D; # (ﱖ; ﱖ; ﱖ; يح; يح; ) ARABIC LIGATURE YEH WITH HAH ISOLATED FORM
+FC57;FC57;FC57;064A 062E;064A 062E; # (ﱗ; ﱗ; ﱗ; يخ; يخ; ) ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM
+FC58;FC58;FC58;064A 0645;064A 0645; # (ﱘ; ﱘ; ﱘ; يم; يم; ) ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM
+FC59;FC59;FC59;064A 0649;064A 0649; # (ﱙ; ﱙ; ﱙ; يى; يى; ) ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM
+FC5A;FC5A;FC5A;064A 064A;064A 064A; # (ﱚ; ﱚ; ﱚ; يي; يي; ) ARABIC LIGATURE YEH WITH YEH ISOLATED FORM
+FC5B;FC5B;FC5B;0630 0670;0630 0670; # (ﱛ; ﱛ; ﱛ; ذ◌ٰ; ذ◌ٰ; ) ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM
+FC5C;FC5C;FC5C;0631 0670;0631 0670; # (ﱜ; ﱜ; ﱜ; ر◌ٰ; ر◌ٰ; ) ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM
+FC5D;FC5D;FC5D;0649 0670;0649 0670; # (ﱝ; ﱝ; ﱝ; ى◌ٰ; ى◌ٰ; ) ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM
+FC5E;FC5E;FC5E;0020 064C 0651;0020 064C 0651; # (ﱞ; ﱞ; ﱞ; ◌ٌ◌ّ; ◌ٌ◌ّ; ) ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM
+FC5F;FC5F;FC5F;0020 064D 0651;0020 064D 0651; # (ﱟ; ﱟ; ﱟ; ◌ٍ◌ّ; ◌ٍ◌ّ; ) ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM
+FC60;FC60;FC60;0020 064E 0651;0020 064E 0651; # (ﱠ; ﱠ; ﱠ; ◌َ◌ّ; ◌َ◌ّ; ) ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM
+FC61;FC61;FC61;0020 064F 0651;0020 064F 0651; # (ﱡ; ﱡ; ﱡ; ◌ُ◌ّ; ◌ُ◌ّ; ) ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM
+FC62;FC62;FC62;0020 0650 0651;0020 0650 0651; # (ﱢ; ﱢ; ﱢ; ◌ِ◌ّ; ◌ِ◌ّ; ) ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM
+FC63;FC63;FC63;0020 0651 0670;0020 0651 0670; # (ﱣ; ﱣ; ﱣ; ◌ّ◌ٰ; ◌ّ◌ٰ; ) ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM
+FC64;FC64;FC64;0626 0631;064A 0654 0631; # (ﱤ; ﱤ; ﱤ; ئر; ي◌ٔر; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM
+FC65;FC65;FC65;0626 0632;064A 0654 0632; # (ﱥ; ﱥ; ﱥ; ئز; ي◌ٔز; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM
+FC66;FC66;FC66;0626 0645;064A 0654 0645; # (ﱦ; ﱦ; ﱦ; ئم; ي◌ٔم; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM
+FC67;FC67;FC67;0626 0646;064A 0654 0646; # (ﱧ; ﱧ; ﱧ; ئن; ي◌ٔن; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM
+FC68;FC68;FC68;0626 0649;064A 0654 0649; # (ﱨ; ﱨ; ﱨ; ئى; ي◌ٔى; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM
+FC69;FC69;FC69;0626 064A;064A 0654 064A; # (ﱩ; ﱩ; ﱩ; ئي; ي◌ٔي; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM
+FC6A;FC6A;FC6A;0628 0631;0628 0631; # (ﱪ; ﱪ; ﱪ; بر; بر; ) ARABIC LIGATURE BEH WITH REH FINAL FORM
+FC6B;FC6B;FC6B;0628 0632;0628 0632; # (ﱫ; ﱫ; ﱫ; بز; بز; ) ARABIC LIGATURE BEH WITH ZAIN FINAL FORM
+FC6C;FC6C;FC6C;0628 0645;0628 0645; # (ﱬ; ﱬ; ﱬ; بم; بم; ) ARABIC LIGATURE BEH WITH MEEM FINAL FORM
+FC6D;FC6D;FC6D;0628 0646;0628 0646; # (ﱭ; ﱭ; ﱭ; بن; بن; ) ARABIC LIGATURE BEH WITH NOON FINAL FORM
+FC6E;FC6E;FC6E;0628 0649;0628 0649; # (ﱮ; ﱮ; ﱮ; بى; بى; ) ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM
+FC6F;FC6F;FC6F;0628 064A;0628 064A; # (ﱯ; ﱯ; ﱯ; بي; بي; ) ARABIC LIGATURE BEH WITH YEH FINAL FORM
+FC70;FC70;FC70;062A 0631;062A 0631; # (ﱰ; ﱰ; ﱰ; تر; تر; ) ARABIC LIGATURE TEH WITH REH FINAL FORM
+FC71;FC71;FC71;062A 0632;062A 0632; # (ﱱ; ﱱ; ﱱ; تز; تز; ) ARABIC LIGATURE TEH WITH ZAIN FINAL FORM
+FC72;FC72;FC72;062A 0645;062A 0645; # (ﱲ; ﱲ; ﱲ; تم; تم; ) ARABIC LIGATURE TEH WITH MEEM FINAL FORM
+FC73;FC73;FC73;062A 0646;062A 0646; # (ﱳ; ﱳ; ﱳ; تن; تن; ) ARABIC LIGATURE TEH WITH NOON FINAL FORM
+FC74;FC74;FC74;062A 0649;062A 0649; # (ﱴ; ﱴ; ﱴ; تى; تى; ) ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM
+FC75;FC75;FC75;062A 064A;062A 064A; # (ﱵ; ﱵ; ﱵ; تي; تي; ) ARABIC LIGATURE TEH WITH YEH FINAL FORM
+FC76;FC76;FC76;062B 0631;062B 0631; # (ﱶ; ﱶ; ﱶ; ثر; ثر; ) ARABIC LIGATURE THEH WITH REH FINAL FORM
+FC77;FC77;FC77;062B 0632;062B 0632; # (ﱷ; ﱷ; ﱷ; ثز; ثز; ) ARABIC LIGATURE THEH WITH ZAIN FINAL FORM
+FC78;FC78;FC78;062B 0645;062B 0645; # (ﱸ; ﱸ; ﱸ; ثم; ثم; ) ARABIC LIGATURE THEH WITH MEEM FINAL FORM
+FC79;FC79;FC79;062B 0646;062B 0646; # (ﱹ; ﱹ; ﱹ; ثن; ثن; ) ARABIC LIGATURE THEH WITH NOON FINAL FORM
+FC7A;FC7A;FC7A;062B 0649;062B 0649; # (ﱺ; ﱺ; ﱺ; ثى; ثى; ) ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM
+FC7B;FC7B;FC7B;062B 064A;062B 064A; # (ﱻ; ﱻ; ﱻ; ثي; ثي; ) ARABIC LIGATURE THEH WITH YEH FINAL FORM
+FC7C;FC7C;FC7C;0641 0649;0641 0649; # (ﱼ; ﱼ; ﱼ; فى; فى; ) ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM
+FC7D;FC7D;FC7D;0641 064A;0641 064A; # (ﱽ; ﱽ; ﱽ; في; في; ) ARABIC LIGATURE FEH WITH YEH FINAL FORM
+FC7E;FC7E;FC7E;0642 0649;0642 0649; # (ﱾ; ﱾ; ﱾ; قى; قى; ) ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM
+FC7F;FC7F;FC7F;0642 064A;0642 064A; # (ﱿ; ﱿ; ﱿ; قي; قي; ) ARABIC LIGATURE QAF WITH YEH FINAL FORM
+FC80;FC80;FC80;0643 0627;0643 0627; # (ﲀ; ﲀ; ﲀ; كا; كا; ) ARABIC LIGATURE KAF WITH ALEF FINAL FORM
+FC81;FC81;FC81;0643 0644;0643 0644; # (ﲁ; ﲁ; ﲁ; كل; كل; ) ARABIC LIGATURE KAF WITH LAM FINAL FORM
+FC82;FC82;FC82;0643 0645;0643 0645; # (ﲂ; ﲂ; ﲂ; كم; كم; ) ARABIC LIGATURE KAF WITH MEEM FINAL FORM
+FC83;FC83;FC83;0643 0649;0643 0649; # (ﲃ; ﲃ; ﲃ; كى; كى; ) ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM
+FC84;FC84;FC84;0643 064A;0643 064A; # (ﲄ; ﲄ; ﲄ; كي; كي; ) ARABIC LIGATURE KAF WITH YEH FINAL FORM
+FC85;FC85;FC85;0644 0645;0644 0645; # (ﲅ; ﲅ; ﲅ; لم; لم; ) ARABIC LIGATURE LAM WITH MEEM FINAL FORM
+FC86;FC86;FC86;0644 0649;0644 0649; # (ﲆ; ﲆ; ﲆ; لى; لى; ) ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM
+FC87;FC87;FC87;0644 064A;0644 064A; # (ﲇ; ﲇ; ﲇ; لي; لي; ) ARABIC LIGATURE LAM WITH YEH FINAL FORM
+FC88;FC88;FC88;0645 0627;0645 0627; # (ﲈ; ﲈ; ﲈ; ما; ما; ) ARABIC LIGATURE MEEM WITH ALEF FINAL FORM
+FC89;FC89;FC89;0645 0645;0645 0645; # (ﲉ; ﲉ; ﲉ; مم; مم; ) ARABIC LIGATURE MEEM WITH MEEM FINAL FORM
+FC8A;FC8A;FC8A;0646 0631;0646 0631; # (ﲊ; ﲊ; ﲊ; نر; نر; ) ARABIC LIGATURE NOON WITH REH FINAL FORM
+FC8B;FC8B;FC8B;0646 0632;0646 0632; # (ﲋ; ﲋ; ﲋ; نز; نز; ) ARABIC LIGATURE NOON WITH ZAIN FINAL FORM
+FC8C;FC8C;FC8C;0646 0645;0646 0645; # (ﲌ; ﲌ; ﲌ; نم; نم; ) ARABIC LIGATURE NOON WITH MEEM FINAL FORM
+FC8D;FC8D;FC8D;0646 0646;0646 0646; # (ﲍ; ﲍ; ﲍ; نن; نن; ) ARABIC LIGATURE NOON WITH NOON FINAL FORM
+FC8E;FC8E;FC8E;0646 0649;0646 0649; # (ﲎ; ﲎ; ﲎ; نى; نى; ) ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM
+FC8F;FC8F;FC8F;0646 064A;0646 064A; # (ﲏ; ﲏ; ﲏ; ني; ني; ) ARABIC LIGATURE NOON WITH YEH FINAL FORM
+FC90;FC90;FC90;0649 0670;0649 0670; # (ﲐ; ﲐ; ﲐ; ى◌ٰ; ى◌ٰ; ) ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM
+FC91;FC91;FC91;064A 0631;064A 0631; # (ﲑ; ﲑ; ﲑ; ير; ير; ) ARABIC LIGATURE YEH WITH REH FINAL FORM
+FC92;FC92;FC92;064A 0632;064A 0632; # (ﲒ; ﲒ; ﲒ; يز; يز; ) ARABIC LIGATURE YEH WITH ZAIN FINAL FORM
+FC93;FC93;FC93;064A 0645;064A 0645; # (ﲓ; ﲓ; ﲓ; يم; يم; ) ARABIC LIGATURE YEH WITH MEEM FINAL FORM
+FC94;FC94;FC94;064A 0646;064A 0646; # (ﲔ; ﲔ; ﲔ; ين; ين; ) ARABIC LIGATURE YEH WITH NOON FINAL FORM
+FC95;FC95;FC95;064A 0649;064A 0649; # (ﲕ; ﲕ; ﲕ; يى; يى; ) ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM
+FC96;FC96;FC96;064A 064A;064A 064A; # (ﲖ; ﲖ; ﲖ; يي; يي; ) ARABIC LIGATURE YEH WITH YEH FINAL FORM
+FC97;FC97;FC97;0626 062C;064A 0654 062C; # (ﲗ; ﲗ; ﲗ; ئج; ي◌ٔج; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM
+FC98;FC98;FC98;0626 062D;064A 0654 062D; # (ﲘ; ﲘ; ﲘ; ئح; ي◌ٔح; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM
+FC99;FC99;FC99;0626 062E;064A 0654 062E; # (ﲙ; ﲙ; ﲙ; ئخ; ي◌ٔخ; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM
+FC9A;FC9A;FC9A;0626 0645;064A 0654 0645; # (ﲚ; ﲚ; ﲚ; ئم; ي◌ٔم; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM
+FC9B;FC9B;FC9B;0626 0647;064A 0654 0647; # (ﲛ; ﲛ; ﲛ; ئه; ي◌ٔه; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM
+FC9C;FC9C;FC9C;0628 062C;0628 062C; # (ﲜ; ﲜ; ﲜ; بج; بج; ) ARABIC LIGATURE BEH WITH JEEM INITIAL FORM
+FC9D;FC9D;FC9D;0628 062D;0628 062D; # (ﲝ; ﲝ; ﲝ; بح; بح; ) ARABIC LIGATURE BEH WITH HAH INITIAL FORM
+FC9E;FC9E;FC9E;0628 062E;0628 062E; # (ﲞ; ﲞ; ﲞ; بخ; بخ; ) ARABIC LIGATURE BEH WITH KHAH INITIAL FORM
+FC9F;FC9F;FC9F;0628 0645;0628 0645; # (ﲟ; ﲟ; ﲟ; بم; بم; ) ARABIC LIGATURE BEH WITH MEEM INITIAL FORM
+FCA0;FCA0;FCA0;0628 0647;0628 0647; # (ﲠ; ﲠ; ﲠ; به; به; ) ARABIC LIGATURE BEH WITH HEH INITIAL FORM
+FCA1;FCA1;FCA1;062A 062C;062A 062C; # (ﲡ; ﲡ; ﲡ; تج; تج; ) ARABIC LIGATURE TEH WITH JEEM INITIAL FORM
+FCA2;FCA2;FCA2;062A 062D;062A 062D; # (ﲢ; ﲢ; ﲢ; تح; تح; ) ARABIC LIGATURE TEH WITH HAH INITIAL FORM
+FCA3;FCA3;FCA3;062A 062E;062A 062E; # (ﲣ; ﲣ; ﲣ; تخ; تخ; ) ARABIC LIGATURE TEH WITH KHAH INITIAL FORM
+FCA4;FCA4;FCA4;062A 0645;062A 0645; # (ﲤ; ﲤ; ﲤ; تم; تم; ) ARABIC LIGATURE TEH WITH MEEM INITIAL FORM
+FCA5;FCA5;FCA5;062A 0647;062A 0647; # (ﲥ; ﲥ; ﲥ; ته; ته; ) ARABIC LIGATURE TEH WITH HEH INITIAL FORM
+FCA6;FCA6;FCA6;062B 0645;062B 0645; # (ﲦ; ﲦ; ﲦ; ثم; ثم; ) ARABIC LIGATURE THEH WITH MEEM INITIAL FORM
+FCA7;FCA7;FCA7;062C 062D;062C 062D; # (ﲧ; ﲧ; ﲧ; جح; جح; ) ARABIC LIGATURE JEEM WITH HAH INITIAL FORM
+FCA8;FCA8;FCA8;062C 0645;062C 0645; # (ﲨ; ﲨ; ﲨ; جم; جم; ) ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM
+FCA9;FCA9;FCA9;062D 062C;062D 062C; # (ﲩ; ﲩ; ﲩ; حج; حج; ) ARABIC LIGATURE HAH WITH JEEM INITIAL FORM
+FCAA;FCAA;FCAA;062D 0645;062D 0645; # (ﲪ; ﲪ; ﲪ; حم; حم; ) ARABIC LIGATURE HAH WITH MEEM INITIAL FORM
+FCAB;FCAB;FCAB;062E 062C;062E 062C; # (ﲫ; ﲫ; ﲫ; خج; خج; ) ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM
+FCAC;FCAC;FCAC;062E 0645;062E 0645; # (ﲬ; ﲬ; ﲬ; خم; خم; ) ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM
+FCAD;FCAD;FCAD;0633 062C;0633 062C; # (ﲭ; ﲭ; ﲭ; سج; سج; ) ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM
+FCAE;FCAE;FCAE;0633 062D;0633 062D; # (ﲮ; ﲮ; ﲮ; سح; سح; ) ARABIC LIGATURE SEEN WITH HAH INITIAL FORM
+FCAF;FCAF;FCAF;0633 062E;0633 062E; # (ﲯ; ﲯ; ﲯ; سخ; سخ; ) ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM
+FCB0;FCB0;FCB0;0633 0645;0633 0645; # (ﲰ; ﲰ; ﲰ; سم; سم; ) ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM
+FCB1;FCB1;FCB1;0635 062D;0635 062D; # (ﲱ; ﲱ; ﲱ; صح; صح; ) ARABIC LIGATURE SAD WITH HAH INITIAL FORM
+FCB2;FCB2;FCB2;0635 062E;0635 062E; # (ﲲ; ﲲ; ﲲ; صخ; صخ; ) ARABIC LIGATURE SAD WITH KHAH INITIAL FORM
+FCB3;FCB3;FCB3;0635 0645;0635 0645; # (ﲳ; ﲳ; ﲳ; صم; صم; ) ARABIC LIGATURE SAD WITH MEEM INITIAL FORM
+FCB4;FCB4;FCB4;0636 062C;0636 062C; # (ﲴ; ﲴ; ﲴ; ضج; ضج; ) ARABIC LIGATURE DAD WITH JEEM INITIAL FORM
+FCB5;FCB5;FCB5;0636 062D;0636 062D; # (ﲵ; ﲵ; ﲵ; ضح; ضح; ) ARABIC LIGATURE DAD WITH HAH INITIAL FORM
+FCB6;FCB6;FCB6;0636 062E;0636 062E; # (ﲶ; ﲶ; ﲶ; ضخ; ضخ; ) ARABIC LIGATURE DAD WITH KHAH INITIAL FORM
+FCB7;FCB7;FCB7;0636 0645;0636 0645; # (ﲷ; ﲷ; ﲷ; ضم; ضم; ) ARABIC LIGATURE DAD WITH MEEM INITIAL FORM
+FCB8;FCB8;FCB8;0637 062D;0637 062D; # (ﲸ; ﲸ; ﲸ; طح; طح; ) ARABIC LIGATURE TAH WITH HAH INITIAL FORM
+FCB9;FCB9;FCB9;0638 0645;0638 0645; # (ﲹ; ﲹ; ﲹ; ظم; ظم; ) ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM
+FCBA;FCBA;FCBA;0639 062C;0639 062C; # (ﲺ; ﲺ; ﲺ; عج; عج; ) ARABIC LIGATURE AIN WITH JEEM INITIAL FORM
+FCBB;FCBB;FCBB;0639 0645;0639 0645; # (ﲻ; ﲻ; ﲻ; عم; عم; ) ARABIC LIGATURE AIN WITH MEEM INITIAL FORM
+FCBC;FCBC;FCBC;063A 062C;063A 062C; # (ﲼ; ﲼ; ﲼ; غج; غج; ) ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM
+FCBD;FCBD;FCBD;063A 0645;063A 0645; # (ﲽ; ﲽ; ﲽ; غم; غم; ) ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM
+FCBE;FCBE;FCBE;0641 062C;0641 062C; # (ﲾ; ﲾ; ﲾ; فج; فج; ) ARABIC LIGATURE FEH WITH JEEM INITIAL FORM
+FCBF;FCBF;FCBF;0641 062D;0641 062D; # (ﲿ; ﲿ; ﲿ; فح; فح; ) ARABIC LIGATURE FEH WITH HAH INITIAL FORM
+FCC0;FCC0;FCC0;0641 062E;0641 062E; # (ﳀ; ﳀ; ﳀ; فخ; فخ; ) ARABIC LIGATURE FEH WITH KHAH INITIAL FORM
+FCC1;FCC1;FCC1;0641 0645;0641 0645; # (ﳁ; ﳁ; ﳁ; فم; فم; ) ARABIC LIGATURE FEH WITH MEEM INITIAL FORM
+FCC2;FCC2;FCC2;0642 062D;0642 062D; # (ﳂ; ﳂ; ﳂ; قح; قح; ) ARABIC LIGATURE QAF WITH HAH INITIAL FORM
+FCC3;FCC3;FCC3;0642 0645;0642 0645; # (ﳃ; ﳃ; ﳃ; قم; قم; ) ARABIC LIGATURE QAF WITH MEEM INITIAL FORM
+FCC4;FCC4;FCC4;0643 062C;0643 062C; # (ﳄ; ﳄ; ﳄ; كج; كج; ) ARABIC LIGATURE KAF WITH JEEM INITIAL FORM
+FCC5;FCC5;FCC5;0643 062D;0643 062D; # (ﳅ; ﳅ; ﳅ; كح; كح; ) ARABIC LIGATURE KAF WITH HAH INITIAL FORM
+FCC6;FCC6;FCC6;0643 062E;0643 062E; # (ﳆ; ﳆ; ﳆ; كخ; كخ; ) ARABIC LIGATURE KAF WITH KHAH INITIAL FORM
+FCC7;FCC7;FCC7;0643 0644;0643 0644; # (ﳇ; ﳇ; ﳇ; كل; كل; ) ARABIC LIGATURE KAF WITH LAM INITIAL FORM
+FCC8;FCC8;FCC8;0643 0645;0643 0645; # (ﳈ; ﳈ; ﳈ; كم; كم; ) ARABIC LIGATURE KAF WITH MEEM INITIAL FORM
+FCC9;FCC9;FCC9;0644 062C;0644 062C; # (ﳉ; ﳉ; ﳉ; لج; لج; ) ARABIC LIGATURE LAM WITH JEEM INITIAL FORM
+FCCA;FCCA;FCCA;0644 062D;0644 062D; # (ﳊ; ﳊ; ﳊ; لح; لح; ) ARABIC LIGATURE LAM WITH HAH INITIAL FORM
+FCCB;FCCB;FCCB;0644 062E;0644 062E; # (ﳋ; ﳋ; ﳋ; لخ; لخ; ) ARABIC LIGATURE LAM WITH KHAH INITIAL FORM
+FCCC;FCCC;FCCC;0644 0645;0644 0645; # (ﳌ; ﳌ; ﳌ; لم; لم; ) ARABIC LIGATURE LAM WITH MEEM INITIAL FORM
+FCCD;FCCD;FCCD;0644 0647;0644 0647; # (ﳍ; ﳍ; ﳍ; له; له; ) ARABIC LIGATURE LAM WITH HEH INITIAL FORM
+FCCE;FCCE;FCCE;0645 062C;0645 062C; # (ﳎ; ﳎ; ﳎ; مج; مج; ) ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM
+FCCF;FCCF;FCCF;0645 062D;0645 062D; # (ﳏ; ﳏ; ﳏ; مح; مح; ) ARABIC LIGATURE MEEM WITH HAH INITIAL FORM
+FCD0;FCD0;FCD0;0645 062E;0645 062E; # (ﳐ; ﳐ; ﳐ; مخ; مخ; ) ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM
+FCD1;FCD1;FCD1;0645 0645;0645 0645; # (ﳑ; ﳑ; ﳑ; مم; مم; ) ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM
+FCD2;FCD2;FCD2;0646 062C;0646 062C; # (ﳒ; ﳒ; ﳒ; نج; نج; ) ARABIC LIGATURE NOON WITH JEEM INITIAL FORM
+FCD3;FCD3;FCD3;0646 062D;0646 062D; # (ﳓ; ﳓ; ﳓ; نح; نح; ) ARABIC LIGATURE NOON WITH HAH INITIAL FORM
+FCD4;FCD4;FCD4;0646 062E;0646 062E; # (ﳔ; ﳔ; ﳔ; نخ; نخ; ) ARABIC LIGATURE NOON WITH KHAH INITIAL FORM
+FCD5;FCD5;FCD5;0646 0645;0646 0645; # (ﳕ; ﳕ; ﳕ; نم; نم; ) ARABIC LIGATURE NOON WITH MEEM INITIAL FORM
+FCD6;FCD6;FCD6;0646 0647;0646 0647; # (ﳖ; ﳖ; ﳖ; نه; نه; ) ARABIC LIGATURE NOON WITH HEH INITIAL FORM
+FCD7;FCD7;FCD7;0647 062C;0647 062C; # (ﳗ; ﳗ; ﳗ; هج; هج; ) ARABIC LIGATURE HEH WITH JEEM INITIAL FORM
+FCD8;FCD8;FCD8;0647 0645;0647 0645; # (ﳘ; ﳘ; ﳘ; هم; هم; ) ARABIC LIGATURE HEH WITH MEEM INITIAL FORM
+FCD9;FCD9;FCD9;0647 0670;0647 0670; # (ﳙ; ﳙ; ﳙ; ه◌ٰ; ه◌ٰ; ) ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM
+FCDA;FCDA;FCDA;064A 062C;064A 062C; # (ﳚ; ﳚ; ﳚ; يج; يج; ) ARABIC LIGATURE YEH WITH JEEM INITIAL FORM
+FCDB;FCDB;FCDB;064A 062D;064A 062D; # (ﳛ; ﳛ; ﳛ; يح; يح; ) ARABIC LIGATURE YEH WITH HAH INITIAL FORM
+FCDC;FCDC;FCDC;064A 062E;064A 062E; # (ﳜ; ﳜ; ﳜ; يخ; يخ; ) ARABIC LIGATURE YEH WITH KHAH INITIAL FORM
+FCDD;FCDD;FCDD;064A 0645;064A 0645; # (ﳝ; ﳝ; ﳝ; يم; يم; ) ARABIC LIGATURE YEH WITH MEEM INITIAL FORM
+FCDE;FCDE;FCDE;064A 0647;064A 0647; # (ﳞ; ﳞ; ﳞ; يه; يه; ) ARABIC LIGATURE YEH WITH HEH INITIAL FORM
+FCDF;FCDF;FCDF;0626 0645;064A 0654 0645; # (ﳟ; ﳟ; ﳟ; ئم; ي◌ٔم; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM
+FCE0;FCE0;FCE0;0626 0647;064A 0654 0647; # (ﳠ; ﳠ; ﳠ; ئه; ي◌ٔه; ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM
+FCE1;FCE1;FCE1;0628 0645;0628 0645; # (ﳡ; ﳡ; ﳡ; بم; بم; ) ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM
+FCE2;FCE2;FCE2;0628 0647;0628 0647; # (ﳢ; ﳢ; ﳢ; به; به; ) ARABIC LIGATURE BEH WITH HEH MEDIAL FORM
+FCE3;FCE3;FCE3;062A 0645;062A 0645; # (ﳣ; ﳣ; ﳣ; تم; تم; ) ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM
+FCE4;FCE4;FCE4;062A 0647;062A 0647; # (ﳤ; ﳤ; ﳤ; ته; ته; ) ARABIC LIGATURE TEH WITH HEH MEDIAL FORM
+FCE5;FCE5;FCE5;062B 0645;062B 0645; # (ﳥ; ﳥ; ﳥ; ثم; ثم; ) ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM
+FCE6;FCE6;FCE6;062B 0647;062B 0647; # (ﳦ; ﳦ; ﳦ; ثه; ثه; ) ARABIC LIGATURE THEH WITH HEH MEDIAL FORM
+FCE7;FCE7;FCE7;0633 0645;0633 0645; # (ﳧ; ﳧ; ﳧ; سم; سم; ) ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM
+FCE8;FCE8;FCE8;0633 0647;0633 0647; # (ﳨ; ﳨ; ﳨ; سه; سه; ) ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM
+FCE9;FCE9;FCE9;0634 0645;0634 0645; # (ﳩ; ﳩ; ﳩ; شم; شم; ) ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM
+FCEA;FCEA;FCEA;0634 0647;0634 0647; # (ﳪ; ﳪ; ﳪ; شه; شه; ) ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM
+FCEB;FCEB;FCEB;0643 0644;0643 0644; # (ﳫ; ﳫ; ﳫ; كل; كل; ) ARABIC LIGATURE KAF WITH LAM MEDIAL FORM
+FCEC;FCEC;FCEC;0643 0645;0643 0645; # (ﳬ; ﳬ; ﳬ; كم; كم; ) ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM
+FCED;FCED;FCED;0644 0645;0644 0645; # (ﳭ; ﳭ; ﳭ; لم; لم; ) ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM
+FCEE;FCEE;FCEE;0646 0645;0646 0645; # (ﳮ; ﳮ; ﳮ; نم; نم; ) ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM
+FCEF;FCEF;FCEF;0646 0647;0646 0647; # (ﳯ; ﳯ; ﳯ; نه; نه; ) ARABIC LIGATURE NOON WITH HEH MEDIAL FORM
+FCF0;FCF0;FCF0;064A 0645;064A 0645; # (ﳰ; ﳰ; ﳰ; يم; يم; ) ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM
+FCF1;FCF1;FCF1;064A 0647;064A 0647; # (ﳱ; ﳱ; ﳱ; يه; يه; ) ARABIC LIGATURE YEH WITH HEH MEDIAL FORM
+FCF2;FCF2;FCF2;0640 064E 0651;0640 064E 0651; # (ﳲ; ﳲ; ﳲ; ـ◌َ◌ّ; ـ◌َ◌ّ; ) ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM
+FCF3;FCF3;FCF3;0640 064F 0651;0640 064F 0651; # (ﳳ; ﳳ; ﳳ; ـ◌ُ◌ّ; ـ◌ُ◌ّ; ) ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM
+FCF4;FCF4;FCF4;0640 0650 0651;0640 0650 0651; # (ﳴ; ﳴ; ﳴ; ـ◌ِ◌ّ; ـ◌ِ◌ّ; ) ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM
+FCF5;FCF5;FCF5;0637 0649;0637 0649; # (ﳵ; ﳵ; ﳵ; طى; طى; ) ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM
+FCF6;FCF6;FCF6;0637 064A;0637 064A; # (ﳶ; ﳶ; ﳶ; طي; طي; ) ARABIC LIGATURE TAH WITH YEH ISOLATED FORM
+FCF7;FCF7;FCF7;0639 0649;0639 0649; # (ﳷ; ﳷ; ﳷ; عى; عى; ) ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM
+FCF8;FCF8;FCF8;0639 064A;0639 064A; # (ﳸ; ﳸ; ﳸ; عي; عي; ) ARABIC LIGATURE AIN WITH YEH ISOLATED FORM
+FCF9;FCF9;FCF9;063A 0649;063A 0649; # (ﳹ; ﳹ; ﳹ; غى; غى; ) ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM
+FCFA;FCFA;FCFA;063A 064A;063A 064A; # (ﳺ; ﳺ; ﳺ; غي; غي; ) ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM
+FCFB;FCFB;FCFB;0633 0649;0633 0649; # (ﳻ; ﳻ; ﳻ; سى; سى; ) ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM
+FCFC;FCFC;FCFC;0633 064A;0633 064A; # (ﳼ; ﳼ; ﳼ; سي; سي; ) ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM
+FCFD;FCFD;FCFD;0634 0649;0634 0649; # (ﳽ; ﳽ; ﳽ; شى; شى; ) ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM
+FCFE;FCFE;FCFE;0634 064A;0634 064A; # (ﳾ; ﳾ; ﳾ; شي; شي; ) ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM
+FCFF;FCFF;FCFF;062D 0649;062D 0649; # (ﳿ; ﳿ; ﳿ; حى; حى; ) ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM
+FD00;FD00;FD00;062D 064A;062D 064A; # (ﴀ; ﴀ; ﴀ; حي; حي; ) ARABIC LIGATURE HAH WITH YEH ISOLATED FORM
+FD01;FD01;FD01;062C 0649;062C 0649; # (ﴁ; ﴁ; ﴁ; جى; جى; ) ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM
+FD02;FD02;FD02;062C 064A;062C 064A; # (ﴂ; ﴂ; ﴂ; جي; جي; ) ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM
+FD03;FD03;FD03;062E 0649;062E 0649; # (ﴃ; ﴃ; ﴃ; خى; خى; ) ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM
+FD04;FD04;FD04;062E 064A;062E 064A; # (ﴄ; ﴄ; ﴄ; خي; خي; ) ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM
+FD05;FD05;FD05;0635 0649;0635 0649; # (ﴅ; ﴅ; ﴅ; صى; صى; ) ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM
+FD06;FD06;FD06;0635 064A;0635 064A; # (ﴆ; ﴆ; ﴆ; صي; صي; ) ARABIC LIGATURE SAD WITH YEH ISOLATED FORM
+FD07;FD07;FD07;0636 0649;0636 0649; # (ﴇ; ﴇ; ﴇ; ضى; ضى; ) ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM
+FD08;FD08;FD08;0636 064A;0636 064A; # (ﴈ; ﴈ; ﴈ; ضي; ضي; ) ARABIC LIGATURE DAD WITH YEH ISOLATED FORM
+FD09;FD09;FD09;0634 062C;0634 062C; # (ﴉ; ﴉ; ﴉ; شج; شج; ) ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM
+FD0A;FD0A;FD0A;0634 062D;0634 062D; # (ﴊ; ﴊ; ﴊ; شح; شح; ) ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM
+FD0B;FD0B;FD0B;0634 062E;0634 062E; # (ﴋ; ﴋ; ﴋ; شخ; شخ; ) ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM
+FD0C;FD0C;FD0C;0634 0645;0634 0645; # (ﴌ; ﴌ; ﴌ; شم; شم; ) ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM
+FD0D;FD0D;FD0D;0634 0631;0634 0631; # (ﴍ; ﴍ; ﴍ; شر; شر; ) ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM
+FD0E;FD0E;FD0E;0633 0631;0633 0631; # (ﴎ; ﴎ; ﴎ; سر; سر; ) ARABIC LIGATURE SEEN WITH REH ISOLATED FORM
+FD0F;FD0F;FD0F;0635 0631;0635 0631; # (ﴏ; ﴏ; ﴏ; صر; صر; ) ARABIC LIGATURE SAD WITH REH ISOLATED FORM
+FD10;FD10;FD10;0636 0631;0636 0631; # (ﴐ; ﴐ; ﴐ; ضر; ضر; ) ARABIC LIGATURE DAD WITH REH ISOLATED FORM
+FD11;FD11;FD11;0637 0649;0637 0649; # (ﴑ; ﴑ; ﴑ; طى; طى; ) ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM
+FD12;FD12;FD12;0637 064A;0637 064A; # (ﴒ; ﴒ; ﴒ; طي; طي; ) ARABIC LIGATURE TAH WITH YEH FINAL FORM
+FD13;FD13;FD13;0639 0649;0639 0649; # (ﴓ; ﴓ; ﴓ; عى; عى; ) ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM
+FD14;FD14;FD14;0639 064A;0639 064A; # (ﴔ; ﴔ; ﴔ; عي; عي; ) ARABIC LIGATURE AIN WITH YEH FINAL FORM
+FD15;FD15;FD15;063A 0649;063A 0649; # (ﴕ; ﴕ; ﴕ; غى; غى; ) ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM
+FD16;FD16;FD16;063A 064A;063A 064A; # (ﴖ; ﴖ; ﴖ; غي; غي; ) ARABIC LIGATURE GHAIN WITH YEH FINAL FORM
+FD17;FD17;FD17;0633 0649;0633 0649; # (ﴗ; ﴗ; ﴗ; سى; سى; ) ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM
+FD18;FD18;FD18;0633 064A;0633 064A; # (ﴘ; ﴘ; ﴘ; سي; سي; ) ARABIC LIGATURE SEEN WITH YEH FINAL FORM
+FD19;FD19;FD19;0634 0649;0634 0649; # (ﴙ; ﴙ; ﴙ; شى; شى; ) ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM
+FD1A;FD1A;FD1A;0634 064A;0634 064A; # (ﴚ; ﴚ; ﴚ; شي; شي; ) ARABIC LIGATURE SHEEN WITH YEH FINAL FORM
+FD1B;FD1B;FD1B;062D 0649;062D 0649; # (ﴛ; ﴛ; ﴛ; حى; حى; ) ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM
+FD1C;FD1C;FD1C;062D 064A;062D 064A; # (ﴜ; ﴜ; ﴜ; حي; حي; ) ARABIC LIGATURE HAH WITH YEH FINAL FORM
+FD1D;FD1D;FD1D;062C 0649;062C 0649; # (ﴝ; ﴝ; ﴝ; جى; جى; ) ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM
+FD1E;FD1E;FD1E;062C 064A;062C 064A; # (ﴞ; ﴞ; ﴞ; جي; جي; ) ARABIC LIGATURE JEEM WITH YEH FINAL FORM
+FD1F;FD1F;FD1F;062E 0649;062E 0649; # (ﴟ; ﴟ; ﴟ; خى; خى; ) ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM
+FD20;FD20;FD20;062E 064A;062E 064A; # (ﴠ; ﴠ; ﴠ; خي; خي; ) ARABIC LIGATURE KHAH WITH YEH FINAL FORM
+FD21;FD21;FD21;0635 0649;0635 0649; # (ﴡ; ﴡ; ﴡ; صى; صى; ) ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM
+FD22;FD22;FD22;0635 064A;0635 064A; # (ﴢ; ﴢ; ﴢ; صي; صي; ) ARABIC LIGATURE SAD WITH YEH FINAL FORM
+FD23;FD23;FD23;0636 0649;0636 0649; # (ﴣ; ﴣ; ﴣ; ضى; ضى; ) ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM
+FD24;FD24;FD24;0636 064A;0636 064A; # (ﴤ; ﴤ; ﴤ; ضي; ضي; ) ARABIC LIGATURE DAD WITH YEH FINAL FORM
+FD25;FD25;FD25;0634 062C;0634 062C; # (ﴥ; ﴥ; ﴥ; شج; شج; ) ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM
+FD26;FD26;FD26;0634 062D;0634 062D; # (ﴦ; ﴦ; ﴦ; شح; شح; ) ARABIC LIGATURE SHEEN WITH HAH FINAL FORM
+FD27;FD27;FD27;0634 062E;0634 062E; # (ﴧ; ﴧ; ﴧ; شخ; شخ; ) ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM
+FD28;FD28;FD28;0634 0645;0634 0645; # (ﴨ; ﴨ; ﴨ; شم; شم; ) ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM
+FD29;FD29;FD29;0634 0631;0634 0631; # (ﴩ; ﴩ; ﴩ; شر; شر; ) ARABIC LIGATURE SHEEN WITH REH FINAL FORM
+FD2A;FD2A;FD2A;0633 0631;0633 0631; # (ﴪ; ﴪ; ﴪ; سر; سر; ) ARABIC LIGATURE SEEN WITH REH FINAL FORM
+FD2B;FD2B;FD2B;0635 0631;0635 0631; # (ﴫ; ﴫ; ﴫ; صر; صر; ) ARABIC LIGATURE SAD WITH REH FINAL FORM
+FD2C;FD2C;FD2C;0636 0631;0636 0631; # (ﴬ; ﴬ; ﴬ; ضر; ضر; ) ARABIC LIGATURE DAD WITH REH FINAL FORM
+FD2D;FD2D;FD2D;0634 062C;0634 062C; # (ﴭ; ﴭ; ﴭ; شج; شج; ) ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM
+FD2E;FD2E;FD2E;0634 062D;0634 062D; # (ﴮ; ﴮ; ﴮ; شح; شح; ) ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM
+FD2F;FD2F;FD2F;0634 062E;0634 062E; # (ﴯ; ﴯ; ﴯ; شخ; شخ; ) ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM
+FD30;FD30;FD30;0634 0645;0634 0645; # (ﴰ; ﴰ; ﴰ; شم; شم; ) ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM
+FD31;FD31;FD31;0633 0647;0633 0647; # (ﴱ; ﴱ; ﴱ; سه; سه; ) ARABIC LIGATURE SEEN WITH HEH INITIAL FORM
+FD32;FD32;FD32;0634 0647;0634 0647; # (ﴲ; ﴲ; ﴲ; شه; شه; ) ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM
+FD33;FD33;FD33;0637 0645;0637 0645; # (ﴳ; ﴳ; ﴳ; طم; طم; ) ARABIC LIGATURE TAH WITH MEEM INITIAL FORM
+FD34;FD34;FD34;0633 062C;0633 062C; # (ﴴ; ﴴ; ﴴ; سج; سج; ) ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM
+FD35;FD35;FD35;0633 062D;0633 062D; # (ﴵ; ﴵ; ﴵ; سح; سح; ) ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM
+FD36;FD36;FD36;0633 062E;0633 062E; # (ﴶ; ﴶ; ﴶ; سخ; سخ; ) ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM
+FD37;FD37;FD37;0634 062C;0634 062C; # (ﴷ; ﴷ; ﴷ; شج; شج; ) ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM
+FD38;FD38;FD38;0634 062D;0634 062D; # (ﴸ; ﴸ; ﴸ; شح; شح; ) ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM
+FD39;FD39;FD39;0634 062E;0634 062E; # (ﴹ; ﴹ; ﴹ; شخ; شخ; ) ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM
+FD3A;FD3A;FD3A;0637 0645;0637 0645; # (ﴺ; ﴺ; ﴺ; طم; طم; ) ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM
+FD3B;FD3B;FD3B;0638 0645;0638 0645; # (ﴻ; ﴻ; ﴻ; ظم; ظم; ) ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM
+FD3C;FD3C;FD3C;0627 064B;0627 064B; # (ﴼ; ﴼ; ﴼ; ا◌ً; ا◌ً; ) ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM
+FD3D;FD3D;FD3D;0627 064B;0627 064B; # (ﴽ; ﴽ; ﴽ; ا◌ً; ا◌ً; ) ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM
+FD50;FD50;FD50;062A 062C 0645;062A 062C 0645; # (ﵐ; ﵐ; ﵐ; تجم; تجم; ) ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM
+FD51;FD51;FD51;062A 062D 062C;062A 062D 062C; # (ﵑ; ﵑ; ﵑ; تحج; تحج; ) ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM
+FD52;FD52;FD52;062A 062D 062C;062A 062D 062C; # (ﵒ; ﵒ; ﵒ; تحج; تحج; ) ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM
+FD53;FD53;FD53;062A 062D 0645;062A 062D 0645; # (ﵓ; ﵓ; ﵓ; تحم; تحم; ) ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM
+FD54;FD54;FD54;062A 062E 0645;062A 062E 0645; # (ﵔ; ﵔ; ﵔ; تخم; تخم; ) ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM
+FD55;FD55;FD55;062A 0645 062C;062A 0645 062C; # (ﵕ; ﵕ; ﵕ; تمج; تمج; ) ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM
+FD56;FD56;FD56;062A 0645 062D;062A 0645 062D; # (ﵖ; ﵖ; ﵖ; تمح; تمح; ) ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM
+FD57;FD57;FD57;062A 0645 062E;062A 0645 062E; # (ﵗ; ﵗ; ﵗ; تمخ; تمخ; ) ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM
+FD58;FD58;FD58;062C 0645 062D;062C 0645 062D; # (ﵘ; ﵘ; ﵘ; جمح; جمح; ) ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM
+FD59;FD59;FD59;062C 0645 062D;062C 0645 062D; # (ﵙ; ﵙ; ﵙ; جمح; جمح; ) ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM
+FD5A;FD5A;FD5A;062D 0645 064A;062D 0645 064A; # (ﵚ; ﵚ; ﵚ; حمي; حمي; ) ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM
+FD5B;FD5B;FD5B;062D 0645 0649;062D 0645 0649; # (ﵛ; ﵛ; ﵛ; حمى; حمى; ) ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM
+FD5C;FD5C;FD5C;0633 062D 062C;0633 062D 062C; # (ﵜ; ﵜ; ﵜ; سحج; سحج; ) ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM
+FD5D;FD5D;FD5D;0633 062C 062D;0633 062C 062D; # (ﵝ; ﵝ; ﵝ; سجح; سجح; ) ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM
+FD5E;FD5E;FD5E;0633 062C 0649;0633 062C 0649; # (ﵞ; ﵞ; ﵞ; سجى; سجى; ) ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM
+FD5F;FD5F;FD5F;0633 0645 062D;0633 0645 062D; # (ﵟ; ﵟ; ﵟ; سمح; سمح; ) ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM
+FD60;FD60;FD60;0633 0645 062D;0633 0645 062D; # (ﵠ; ﵠ; ﵠ; سمح; سمح; ) ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM
+FD61;FD61;FD61;0633 0645 062C;0633 0645 062C; # (ﵡ; ﵡ; ﵡ; سمج; سمج; ) ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM
+FD62;FD62;FD62;0633 0645 0645;0633 0645 0645; # (ﵢ; ﵢ; ﵢ; سمم; سمم; ) ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM
+FD63;FD63;FD63;0633 0645 0645;0633 0645 0645; # (ﵣ; ﵣ; ﵣ; سمم; سمم; ) ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM
+FD64;FD64;FD64;0635 062D 062D;0635 062D 062D; # (ﵤ; ﵤ; ﵤ; صحح; صحح; ) ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM
+FD65;FD65;FD65;0635 062D 062D;0635 062D 062D; # (ﵥ; ﵥ; ﵥ; صحح; صحح; ) ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM
+FD66;FD66;FD66;0635 0645 0645;0635 0645 0645; # (ﵦ; ﵦ; ﵦ; صمم; صمم; ) ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM
+FD67;FD67;FD67;0634 062D 0645;0634 062D 0645; # (ﵧ; ﵧ; ﵧ; شحم; شحم; ) ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM
+FD68;FD68;FD68;0634 062D 0645;0634 062D 0645; # (ﵨ; ﵨ; ﵨ; شحم; شحم; ) ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM
+FD69;FD69;FD69;0634 062C 064A;0634 062C 064A; # (ﵩ; ﵩ; ﵩ; شجي; شجي; ) ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM
+FD6A;FD6A;FD6A;0634 0645 062E;0634 0645 062E; # (ﵪ; ﵪ; ﵪ; شمخ; شمخ; ) ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM
+FD6B;FD6B;FD6B;0634 0645 062E;0634 0645 062E; # (ﵫ; ﵫ; ﵫ; شمخ; شمخ; ) ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM
+FD6C;FD6C;FD6C;0634 0645 0645;0634 0645 0645; # (ﵬ; ﵬ; ﵬ; شمم; شمم; ) ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM
+FD6D;FD6D;FD6D;0634 0645 0645;0634 0645 0645; # (ﵭ; ﵭ; ﵭ; شمم; شمم; ) ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM
+FD6E;FD6E;FD6E;0636 062D 0649;0636 062D 0649; # (ﵮ; ﵮ; ﵮ; ضحى; ضحى; ) ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM
+FD6F;FD6F;FD6F;0636 062E 0645;0636 062E 0645; # (ﵯ; ﵯ; ﵯ; ضخم; ضخم; ) ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM
+FD70;FD70;FD70;0636 062E 0645;0636 062E 0645; # (ﵰ; ﵰ; ﵰ; ضخم; ضخم; ) ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM
+FD71;FD71;FD71;0637 0645 062D;0637 0645 062D; # (ﵱ; ﵱ; ﵱ; طمح; طمح; ) ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM
+FD72;FD72;FD72;0637 0645 062D;0637 0645 062D; # (ﵲ; ﵲ; ﵲ; طمح; طمح; ) ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM
+FD73;FD73;FD73;0637 0645 0645;0637 0645 0645; # (ﵳ; ﵳ; ﵳ; طمم; طمم; ) ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM
+FD74;FD74;FD74;0637 0645 064A;0637 0645 064A; # (ﵴ; ﵴ; ﵴ; طمي; طمي; ) ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM
+FD75;FD75;FD75;0639 062C 0645;0639 062C 0645; # (ﵵ; ﵵ; ﵵ; عجم; عجم; ) ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM
+FD76;FD76;FD76;0639 0645 0645;0639 0645 0645; # (ﵶ; ﵶ; ﵶ; عمم; عمم; ) ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM
+FD77;FD77;FD77;0639 0645 0645;0639 0645 0645; # (ﵷ; ﵷ; ﵷ; عمم; عمم; ) ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM
+FD78;FD78;FD78;0639 0645 0649;0639 0645 0649; # (ﵸ; ﵸ; ﵸ; عمى; عمى; ) ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM
+FD79;FD79;FD79;063A 0645 0645;063A 0645 0645; # (ﵹ; ﵹ; ﵹ; غمم; غمم; ) ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM
+FD7A;FD7A;FD7A;063A 0645 064A;063A 0645 064A; # (ﵺ; ﵺ; ﵺ; غمي; غمي; ) ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM
+FD7B;FD7B;FD7B;063A 0645 0649;063A 0645 0649; # (ﵻ; ﵻ; ﵻ; غمى; غمى; ) ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM
+FD7C;FD7C;FD7C;0641 062E 0645;0641 062E 0645; # (ﵼ; ﵼ; ﵼ; فخم; فخم; ) ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM
+FD7D;FD7D;FD7D;0641 062E 0645;0641 062E 0645; # (ﵽ; ﵽ; ﵽ; فخم; فخم; ) ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM
+FD7E;FD7E;FD7E;0642 0645 062D;0642 0645 062D; # (ﵾ; ﵾ; ﵾ; قمح; قمح; ) ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM
+FD7F;FD7F;FD7F;0642 0645 0645;0642 0645 0645; # (ﵿ; ﵿ; ﵿ; قمم; قمم; ) ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM
+FD80;FD80;FD80;0644 062D 0645;0644 062D 0645; # (ﶀ; ﶀ; ﶀ; لحم; لحم; ) ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM
+FD81;FD81;FD81;0644 062D 064A;0644 062D 064A; # (ﶁ; ﶁ; ﶁ; لحي; لحي; ) ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM
+FD82;FD82;FD82;0644 062D 0649;0644 062D 0649; # (ﶂ; ﶂ; ﶂ; لحى; لحى; ) ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM
+FD83;FD83;FD83;0644 062C 062C;0644 062C 062C; # (ﶃ; ﶃ; ﶃ; لجج; لجج; ) ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM
+FD84;FD84;FD84;0644 062C 062C;0644 062C 062C; # (ﶄ; ﶄ; ﶄ; لجج; لجج; ) ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM
+FD85;FD85;FD85;0644 062E 0645;0644 062E 0645; # (ﶅ; ﶅ; ﶅ; لخم; لخم; ) ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM
+FD86;FD86;FD86;0644 062E 0645;0644 062E 0645; # (ﶆ; ﶆ; ﶆ; لخم; لخم; ) ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM
+FD87;FD87;FD87;0644 0645 062D;0644 0645 062D; # (ﶇ; ﶇ; ﶇ; لمح; لمح; ) ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM
+FD88;FD88;FD88;0644 0645 062D;0644 0645 062D; # (ﶈ; ﶈ; ﶈ; لمح; لمح; ) ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM
+FD89;FD89;FD89;0645 062D 062C;0645 062D 062C; # (ﶉ; ﶉ; ﶉ; محج; محج; ) ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM
+FD8A;FD8A;FD8A;0645 062D 0645;0645 062D 0645; # (ﶊ; ﶊ; ﶊ; محم; محم; ) ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM
+FD8B;FD8B;FD8B;0645 062D 064A;0645 062D 064A; # (ﶋ; ﶋ; ﶋ; محي; محي; ) ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM
+FD8C;FD8C;FD8C;0645 062C 062D;0645 062C 062D; # (ﶌ; ﶌ; ﶌ; مجح; مجح; ) ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM
+FD8D;FD8D;FD8D;0645 062C 0645;0645 062C 0645; # (ﶍ; ﶍ; ﶍ; مجم; مجم; ) ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM
+FD8E;FD8E;FD8E;0645 062E 062C;0645 062E 062C; # (ﶎ; ﶎ; ﶎ; مخج; مخج; ) ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM
+FD8F;FD8F;FD8F;0645 062E 0645;0645 062E 0645; # (ﶏ; ﶏ; ﶏ; مخم; مخم; ) ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM
+FD92;FD92;FD92;0645 062C 062E;0645 062C 062E; # (ﶒ; ﶒ; ﶒ; مجخ; مجخ; ) ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM
+FD93;FD93;FD93;0647 0645 062C;0647 0645 062C; # (ﶓ; ﶓ; ﶓ; همج; همج; ) ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM
+FD94;FD94;FD94;0647 0645 0645;0647 0645 0645; # (ﶔ; ﶔ; ﶔ; همم; همم; ) ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM
+FD95;FD95;FD95;0646 062D 0645;0646 062D 0645; # (ﶕ; ﶕ; ﶕ; نحم; نحم; ) ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM
+FD96;FD96;FD96;0646 062D 0649;0646 062D 0649; # (ﶖ; ﶖ; ﶖ; نحى; نحى; ) ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM
+FD97;FD97;FD97;0646 062C 0645;0646 062C 0645; # (ﶗ; ﶗ; ﶗ; نجم; نجم; ) ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM
+FD98;FD98;FD98;0646 062C 0645;0646 062C 0645; # (ﶘ; ﶘ; ﶘ; نجم; نجم; ) ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM
+FD99;FD99;FD99;0646 062C 0649;0646 062C 0649; # (ﶙ; ﶙ; ﶙ; نجى; نجى; ) ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM
+FD9A;FD9A;FD9A;0646 0645 064A;0646 0645 064A; # (ﶚ; ﶚ; ﶚ; نمي; نمي; ) ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM
+FD9B;FD9B;FD9B;0646 0645 0649;0646 0645 0649; # (ﶛ; ﶛ; ﶛ; نمى; نمى; ) ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM
+FD9C;FD9C;FD9C;064A 0645 0645;064A 0645 0645; # (ﶜ; ﶜ; ﶜ; يمم; يمم; ) ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM
+FD9D;FD9D;FD9D;064A 0645 0645;064A 0645 0645; # (ﶝ; ﶝ; ﶝ; يمم; يمم; ) ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM
+FD9E;FD9E;FD9E;0628 062E 064A;0628 062E 064A; # (ﶞ; ﶞ; ﶞ; بخي; بخي; ) ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM
+FD9F;FD9F;FD9F;062A 062C 064A;062A 062C 064A; # (ﶟ; ﶟ; ﶟ; تجي; تجي; ) ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM
+FDA0;FDA0;FDA0;062A 062C 0649;062A 062C 0649; # (ﶠ; ﶠ; ﶠ; تجى; تجى; ) ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM
+FDA1;FDA1;FDA1;062A 062E 064A;062A 062E 064A; # (ﶡ; ﶡ; ﶡ; تخي; تخي; ) ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM
+FDA2;FDA2;FDA2;062A 062E 0649;062A 062E 0649; # (ﶢ; ﶢ; ﶢ; تخى; تخى; ) ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM
+FDA3;FDA3;FDA3;062A 0645 064A;062A 0645 064A; # (ﶣ; ﶣ; ﶣ; تمي; تمي; ) ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM
+FDA4;FDA4;FDA4;062A 0645 0649;062A 0645 0649; # (ﶤ; ﶤ; ﶤ; تمى; تمى; ) ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM
+FDA5;FDA5;FDA5;062C 0645 064A;062C 0645 064A; # (ﶥ; ﶥ; ﶥ; جمي; جمي; ) ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM
+FDA6;FDA6;FDA6;062C 062D 0649;062C 062D 0649; # (ﶦ; ﶦ; ﶦ; جحى; جحى; ) ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM
+FDA7;FDA7;FDA7;062C 0645 0649;062C 0645 0649; # (ﶧ; ﶧ; ﶧ; جمى; جمى; ) ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM
+FDA8;FDA8;FDA8;0633 062E 0649;0633 062E 0649; # (ﶨ; ﶨ; ﶨ; سخى; سخى; ) ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM
+FDA9;FDA9;FDA9;0635 062D 064A;0635 062D 064A; # (ﶩ; ﶩ; ﶩ; صحي; صحي; ) ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM
+FDAA;FDAA;FDAA;0634 062D 064A;0634 062D 064A; # (ﶪ; ﶪ; ﶪ; شحي; شحي; ) ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM
+FDAB;FDAB;FDAB;0636 062D 064A;0636 062D 064A; # (ﶫ; ﶫ; ﶫ; ضحي; ضحي; ) ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM
+FDAC;FDAC;FDAC;0644 062C 064A;0644 062C 064A; # (ﶬ; ﶬ; ﶬ; لجي; لجي; ) ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM
+FDAD;FDAD;FDAD;0644 0645 064A;0644 0645 064A; # (ﶭ; ﶭ; ﶭ; لمي; لمي; ) ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM
+FDAE;FDAE;FDAE;064A 062D 064A;064A 062D 064A; # (ﶮ; ﶮ; ﶮ; يحي; يحي; ) ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM
+FDAF;FDAF;FDAF;064A 062C 064A;064A 062C 064A; # (ﶯ; ﶯ; ﶯ; يجي; يجي; ) ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM
+FDB0;FDB0;FDB0;064A 0645 064A;064A 0645 064A; # (ﶰ; ﶰ; ﶰ; يمي; يمي; ) ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM
+FDB1;FDB1;FDB1;0645 0645 064A;0645 0645 064A; # (ﶱ; ﶱ; ﶱ; ممي; ممي; ) ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM
+FDB2;FDB2;FDB2;0642 0645 064A;0642 0645 064A; # (ﶲ; ﶲ; ﶲ; قمي; قمي; ) ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM
+FDB3;FDB3;FDB3;0646 062D 064A;0646 062D 064A; # (ﶳ; ﶳ; ﶳ; نحي; نحي; ) ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM
+FDB4;FDB4;FDB4;0642 0645 062D;0642 0645 062D; # (ﶴ; ﶴ; ﶴ; قمح; قمح; ) ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM
+FDB5;FDB5;FDB5;0644 062D 0645;0644 062D 0645; # (ﶵ; ﶵ; ﶵ; لحم; لحم; ) ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM
+FDB6;FDB6;FDB6;0639 0645 064A;0639 0645 064A; # (ﶶ; ﶶ; ﶶ; عمي; عمي; ) ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM
+FDB7;FDB7;FDB7;0643 0645 064A;0643 0645 064A; # (ﶷ; ﶷ; ﶷ; كمي; كمي; ) ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM
+FDB8;FDB8;FDB8;0646 062C 062D;0646 062C 062D; # (ﶸ; ﶸ; ﶸ; نجح; نجح; ) ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM
+FDB9;FDB9;FDB9;0645 062E 064A;0645 062E 064A; # (ﶹ; ﶹ; ﶹ; مخي; مخي; ) ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM
+FDBA;FDBA;FDBA;0644 062C 0645;0644 062C 0645; # (ﶺ; ﶺ; ﶺ; لجم; لجم; ) ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM
+FDBB;FDBB;FDBB;0643 0645 0645;0643 0645 0645; # (ﶻ; ﶻ; ﶻ; كمم; كمم; ) ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM
+FDBC;FDBC;FDBC;0644 062C 0645;0644 062C 0645; # (ﶼ; ﶼ; ﶼ; لجم; لجم; ) ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM
+FDBD;FDBD;FDBD;0646 062C 062D;0646 062C 062D; # (ﶽ; ﶽ; ﶽ; نجح; نجح; ) ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM
+FDBE;FDBE;FDBE;062C 062D 064A;062C 062D 064A; # (ﶾ; ﶾ; ﶾ; جحي; جحي; ) ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM
+FDBF;FDBF;FDBF;062D 062C 064A;062D 062C 064A; # (ﶿ; ﶿ; ﶿ; حجي; حجي; ) ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM
+FDC0;FDC0;FDC0;0645 062C 064A;0645 062C 064A; # (ﷀ; ﷀ; ﷀ; مجي; مجي; ) ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM
+FDC1;FDC1;FDC1;0641 0645 064A;0641 0645 064A; # (ﷁ; ﷁ; ﷁ; فمي; فمي; ) ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM
+FDC2;FDC2;FDC2;0628 062D 064A;0628 062D 064A; # (ﷂ; ﷂ; ﷂ; بحي; بحي; ) ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM
+FDC3;FDC3;FDC3;0643 0645 0645;0643 0645 0645; # (ﷃ; ﷃ; ﷃ; كمم; كمم; ) ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM
+FDC4;FDC4;FDC4;0639 062C 0645;0639 062C 0645; # (ﷄ; ﷄ; ﷄ; عجم; عجم; ) ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM
+FDC5;FDC5;FDC5;0635 0645 0645;0635 0645 0645; # (ﷅ; ﷅ; ﷅ; صمم; صمم; ) ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM
+FDC6;FDC6;FDC6;0633 062E 064A;0633 062E 064A; # (ﷆ; ﷆ; ﷆ; سخي; سخي; ) ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM
+FDC7;FDC7;FDC7;0646 062C 064A;0646 062C 064A; # (ﷇ; ﷇ; ﷇ; نجي; نجي; ) ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM
+FDF0;FDF0;FDF0;0635 0644 06D2;0635 0644 06D2; # (ﷰ; ﷰ; ﷰ; صلے; صلے; ) ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM
+FDF1;FDF1;FDF1;0642 0644 06D2;0642 0644 06D2; # (ﷱ; ﷱ; ﷱ; قلے; قلے; ) ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM
+FDF2;FDF2;FDF2;0627 0644 0644 0647;0627 0644 0644 0647; # (ﷲ; ﷲ; ﷲ; الله; الله; ) ARABIC LIGATURE ALLAH ISOLATED FORM
+FDF3;FDF3;FDF3;0627 0643 0628 0631;0627 0643 0628 0631; # (ﷳ; ﷳ; ﷳ; اكبر; اكبر; ) ARABIC LIGATURE AKBAR ISOLATED FORM
+FDF4;FDF4;FDF4;0645 062D 0645 062F;0645 062D 0645 062F; # (ﷴ; ﷴ; ﷴ; محمد; محمد; ) ARABIC LIGATURE MOHAMMAD ISOLATED FORM
+FDF5;FDF5;FDF5;0635 0644 0639 0645;0635 0644 0639 0645; # (ﷵ; ﷵ; ﷵ; صلعم; صلعم; ) ARABIC LIGATURE SALAM ISOLATED FORM
+FDF6;FDF6;FDF6;0631 0633 0648 0644;0631 0633 0648 0644; # (ﷶ; ﷶ; ﷶ; رسول; رسول; ) ARABIC LIGATURE RASOUL ISOLATED FORM
+FDF7;FDF7;FDF7;0639 0644 064A 0647;0639 0644 064A 0647; # (ﷷ; ﷷ; ﷷ; عليه; عليه; ) ARABIC LIGATURE ALAYHE ISOLATED FORM
+FDF8;FDF8;FDF8;0648 0633 0644 0645;0648 0633 0644 0645; # (ﷸ; ﷸ; ﷸ; وسلم; وسلم; ) ARABIC LIGATURE WASALLAM ISOLATED FORM
+FDF9;FDF9;FDF9;0635 0644 0649;0635 0644 0649; # (ﷹ; ﷹ; ﷹ; صلى; صلى; ) ARABIC LIGATURE SALLA ISOLATED FORM
+FDFA;FDFA;FDFA;0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645; # (ﷺ; ﷺ; ﷺ; صلى الله عليه وسلم; صلى الله عليه وسلم; ) ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM
+FDFB;FDFB;FDFB;062C 0644 0020 062C 0644 0627 0644 0647;062C 0644 0020 062C 0644 0627 0644 0647; # (ﷻ; ﷻ; ﷻ; جل جلاله; جل جلاله; ) ARABIC LIGATURE JALLAJALALOUHOU
+FDFC;FDFC;FDFC;0631 06CC 0627 0644;0631 06CC 0627 0644; # (﷼; ﷼; ﷼; ریال; ریال; ) RIAL SIGN
+FE10;FE10;FE10;002C;002C; # (︐; ︐; ︐; ,; ,; ) PRESENTATION FORM FOR VERTICAL COMMA
+FE11;FE11;FE11;3001;3001; # (︑; ︑; ︑; 、; 、; ) PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA
+FE12;FE12;FE12;3002;3002; # (︒; ︒; ︒; 。; 。; ) PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP
+FE13;FE13;FE13;003A;003A; # (︓; ︓; ︓; :; :; ) PRESENTATION FORM FOR VERTICAL COLON
+FE14;FE14;FE14;003B;003B; # (︔; ︔; ︔; ;; ;; ) PRESENTATION FORM FOR VERTICAL SEMICOLON
+FE15;FE15;FE15;0021;0021; # (︕; ︕; ︕; !; !; ) PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK
+FE16;FE16;FE16;003F;003F; # (︖; ︖; ︖; ?; ?; ) PRESENTATION FORM FOR VERTICAL QUESTION MARK
+FE17;FE17;FE17;3016;3016; # (︗; ︗; ︗; 〖; 〖; ) PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET
+FE18;FE18;FE18;3017;3017; # (︘; ︘; ︘; 〗; 〗; ) PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET
+FE19;FE19;FE19;002E 002E 002E;002E 002E 002E; # (︙; ︙; ︙; ...; ...; ) PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS
+FE30;FE30;FE30;002E 002E;002E 002E; # (︰; ︰; ︰; ..; ..; ) PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+FE31;FE31;FE31;2014;2014; # (︱; ︱; ︱; —; —; ) PRESENTATION FORM FOR VERTICAL EM DASH
+FE32;FE32;FE32;2013;2013; # (︲; ︲; ︲; –; –; ) PRESENTATION FORM FOR VERTICAL EN DASH
+FE33;FE33;FE33;005F;005F; # (︳; ︳; ︳; _; _; ) PRESENTATION FORM FOR VERTICAL LOW LINE
+FE34;FE34;FE34;005F;005F; # (︴; ︴; ︴; _; _; ) PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
+FE35;FE35;FE35;0028;0028; # (︵; ︵; ︵; (; (; ) PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+FE36;FE36;FE36;0029;0029; # (︶; ︶; ︶; ); ); ) PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+FE37;FE37;FE37;007B;007B; # (︷; ︷; ︷; {; {; ) PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+FE38;FE38;FE38;007D;007D; # (︸; ︸; ︸; }; }; ) PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+FE39;FE39;FE39;3014;3014; # (︹; ︹; ︹; 〔; 〔; ) PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+FE3A;FE3A;FE3A;3015;3015; # (︺; ︺; ︺; 〕; 〕; ) PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+FE3B;FE3B;FE3B;3010;3010; # (︻; ︻; ︻; 【; 【; ) PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+FE3C;FE3C;FE3C;3011;3011; # (︼; ︼; ︼; 】; 】; ) PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+FE3D;FE3D;FE3D;300A;300A; # (︽; ︽; ︽; 《; 《; ) PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+FE3E;FE3E;FE3E;300B;300B; # (︾; ︾; ︾; 》; 》; ) PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+FE3F;FE3F;FE3F;3008;3008; # (︿; ︿; ︿; 〈; 〈; ) PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+FE40;FE40;FE40;3009;3009; # (﹀; ﹀; ﹀; 〉; 〉; ) PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+FE41;FE41;FE41;300C;300C; # (﹁; ﹁; ﹁; 「; 「; ) PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+FE42;FE42;FE42;300D;300D; # (﹂; ﹂; ﹂; 」; 」; ) PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+FE43;FE43;FE43;300E;300E; # (﹃; ﹃; ﹃; 『; 『; ) PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+FE44;FE44;FE44;300F;300F; # (﹄; ﹄; ﹄; 』; 』; ) PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+FE47;FE47;FE47;005B;005B; # (﹇; ﹇; ﹇; [; [; ) PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET
+FE48;FE48;FE48;005D;005D; # (﹈; ﹈; ﹈; ]; ]; ) PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET
+FE49;FE49;FE49;0020 0305;0020 0305; # (﹉; ﹉; ﹉; ◌̅; ◌̅; ) DASHED OVERLINE
+FE4A;FE4A;FE4A;0020 0305;0020 0305; # (﹊; ﹊; ﹊; ◌̅; ◌̅; ) CENTRELINE OVERLINE
+FE4B;FE4B;FE4B;0020 0305;0020 0305; # (﹋; ﹋; ﹋; ◌̅; ◌̅; ) WAVY OVERLINE
+FE4C;FE4C;FE4C;0020 0305;0020 0305; # (﹌; ﹌; ﹌; ◌̅; ◌̅; ) DOUBLE WAVY OVERLINE
+FE4D;FE4D;FE4D;005F;005F; # (﹍; ﹍; ﹍; _; _; ) DASHED LOW LINE
+FE4E;FE4E;FE4E;005F;005F; # (﹎; ﹎; ﹎; _; _; ) CENTRELINE LOW LINE
+FE4F;FE4F;FE4F;005F;005F; # (﹏; ﹏; ﹏; _; _; ) WAVY LOW LINE
+FE50;FE50;FE50;002C;002C; # (﹐; ﹐; ﹐; ,; ,; ) SMALL COMMA
+FE51;FE51;FE51;3001;3001; # (﹑; ﹑; ﹑; 、; 、; ) SMALL IDEOGRAPHIC COMMA
+FE52;FE52;FE52;002E;002E; # (﹒; ﹒; ﹒; .; .; ) SMALL FULL STOP
+FE54;FE54;FE54;003B;003B; # (﹔; ﹔; ﹔; ;; ;; ) SMALL SEMICOLON
+FE55;FE55;FE55;003A;003A; # (﹕; ﹕; ﹕; :; :; ) SMALL COLON
+FE56;FE56;FE56;003F;003F; # (﹖; ﹖; ﹖; ?; ?; ) SMALL QUESTION MARK
+FE57;FE57;FE57;0021;0021; # (﹗; ﹗; ﹗; !; !; ) SMALL EXCLAMATION MARK
+FE58;FE58;FE58;2014;2014; # (﹘; ﹘; ﹘; —; —; ) SMALL EM DASH
+FE59;FE59;FE59;0028;0028; # (﹙; ﹙; ﹙; (; (; ) SMALL LEFT PARENTHESIS
+FE5A;FE5A;FE5A;0029;0029; # (﹚; ﹚; ﹚; ); ); ) SMALL RIGHT PARENTHESIS
+FE5B;FE5B;FE5B;007B;007B; # (﹛; ﹛; ﹛; {; {; ) SMALL LEFT CURLY BRACKET
+FE5C;FE5C;FE5C;007D;007D; # (﹜; ﹜; ﹜; }; }; ) SMALL RIGHT CURLY BRACKET
+FE5D;FE5D;FE5D;3014;3014; # (﹝; ﹝; ﹝; 〔; 〔; ) SMALL LEFT TORTOISE SHELL BRACKET
+FE5E;FE5E;FE5E;3015;3015; # (﹞; ﹞; ﹞; 〕; 〕; ) SMALL RIGHT TORTOISE SHELL BRACKET
+FE5F;FE5F;FE5F;0023;0023; # (﹟; ﹟; ﹟; #; #; ) SMALL NUMBER SIGN
+FE60;FE60;FE60;0026;0026; # (﹠; ﹠; ﹠; &; &; ) SMALL AMPERSAND
+FE61;FE61;FE61;002A;002A; # (﹡; ﹡; ﹡; *; *; ) SMALL ASTERISK
+FE62;FE62;FE62;002B;002B; # (﹢; ﹢; ﹢; +; +; ) SMALL PLUS SIGN
+FE63;FE63;FE63;002D;002D; # (﹣; ﹣; ﹣; -; -; ) SMALL HYPHEN-MINUS
+FE64;FE64;FE64;003C;003C; # (﹤; ﹤; ﹤; <; <; ) SMALL LESS-THAN SIGN
+FE65;FE65;FE65;003E;003E; # (﹥; ﹥; ﹥; >; >; ) SMALL GREATER-THAN SIGN
+FE66;FE66;FE66;003D;003D; # (﹦; ﹦; ﹦; =; =; ) SMALL EQUALS SIGN
+FE68;FE68;FE68;005C;005C; # (﹨; ﹨; ﹨; \; \; ) SMALL REVERSE SOLIDUS
+FE69;FE69;FE69;0024;0024; # (﹩; ﹩; ﹩; $; $; ) SMALL DOLLAR SIGN
+FE6A;FE6A;FE6A;0025;0025; # (﹪; ﹪; ﹪; %; %; ) SMALL PERCENT SIGN
+FE6B;FE6B;FE6B;0040;0040; # (﹫; ﹫; ﹫; @; @; ) SMALL COMMERCIAL AT
+FE70;FE70;FE70;0020 064B;0020 064B; # (ﹰ; ﹰ; ﹰ; ◌ً; ◌ً; ) ARABIC FATHATAN ISOLATED FORM
+FE71;FE71;FE71;0640 064B;0640 064B; # (ﹱ; ﹱ; ﹱ; ـ◌ً; ـ◌ً; ) ARABIC TATWEEL WITH FATHATAN ABOVE
+FE72;FE72;FE72;0020 064C;0020 064C; # (ﹲ; ﹲ; ﹲ; ◌ٌ; ◌ٌ; ) ARABIC DAMMATAN ISOLATED FORM
+FE74;FE74;FE74;0020 064D;0020 064D; # (ﹴ; ﹴ; ﹴ; ◌ٍ; ◌ٍ; ) ARABIC KASRATAN ISOLATED FORM
+FE76;FE76;FE76;0020 064E;0020 064E; # (ﹶ; ﹶ; ﹶ; ◌َ; ◌َ; ) ARABIC FATHA ISOLATED FORM
+FE77;FE77;FE77;0640 064E;0640 064E; # (ﹷ; ﹷ; ﹷ; ـ◌َ; ـ◌َ; ) ARABIC FATHA MEDIAL FORM
+FE78;FE78;FE78;0020 064F;0020 064F; # (ﹸ; ﹸ; ﹸ; ◌ُ; ◌ُ; ) ARABIC DAMMA ISOLATED FORM
+FE79;FE79;FE79;0640 064F;0640 064F; # (ﹹ; ﹹ; ﹹ; ـ◌ُ; ـ◌ُ; ) ARABIC DAMMA MEDIAL FORM
+FE7A;FE7A;FE7A;0020 0650;0020 0650; # (ﹺ; ﹺ; ﹺ; ◌ِ; ◌ِ; ) ARABIC KASRA ISOLATED FORM
+FE7B;FE7B;FE7B;0640 0650;0640 0650; # (ﹻ; ﹻ; ﹻ; ـ◌ِ; ـ◌ِ; ) ARABIC KASRA MEDIAL FORM
+FE7C;FE7C;FE7C;0020 0651;0020 0651; # (ﹼ; ﹼ; ﹼ; ◌ّ; ◌ّ; ) ARABIC SHADDA ISOLATED FORM
+FE7D;FE7D;FE7D;0640 0651;0640 0651; # (ﹽ; ﹽ; ﹽ; ـ◌ّ; ـ◌ّ; ) ARABIC SHADDA MEDIAL FORM
+FE7E;FE7E;FE7E;0020 0652;0020 0652; # (ﹾ; ﹾ; ﹾ; ◌ْ; ◌ْ; ) ARABIC SUKUN ISOLATED FORM
+FE7F;FE7F;FE7F;0640 0652;0640 0652; # (ﹿ; ﹿ; ﹿ; ـ◌ْ; ـ◌ْ; ) ARABIC SUKUN MEDIAL FORM
+FE80;FE80;FE80;0621;0621; # (ﺀ; ﺀ; ﺀ; ء; ء; ) ARABIC LETTER HAMZA ISOLATED FORM
+FE81;FE81;FE81;0622;0627 0653; # (ﺁ; ﺁ; ﺁ; آ; ا◌ٓ; ) ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
+FE82;FE82;FE82;0622;0627 0653; # (ﺂ; ﺂ; ﺂ; آ; ا◌ٓ; ) ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM
+FE83;FE83;FE83;0623;0627 0654; # (ﺃ; ﺃ; ﺃ; أ; ا◌ٔ; ) ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
+FE84;FE84;FE84;0623;0627 0654; # (ﺄ; ﺄ; ﺄ; أ; ا◌ٔ; ) ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM
+FE85;FE85;FE85;0624;0648 0654; # (ﺅ; ﺅ; ﺅ; ؤ; و◌ٔ; ) ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
+FE86;FE86;FE86;0624;0648 0654; # (ﺆ; ﺆ; ﺆ; ؤ; و◌ٔ; ) ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM
+FE87;FE87;FE87;0625;0627 0655; # (ﺇ; ﺇ; ﺇ; إ; ا◌ٕ; ) ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM
+FE88;FE88;FE88;0625;0627 0655; # (ﺈ; ﺈ; ﺈ; إ; ا◌ٕ; ) ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM
+FE89;FE89;FE89;0626;064A 0654; # (ﺉ; ﺉ; ﺉ; ئ; ي◌ٔ; ) ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM
+FE8A;FE8A;FE8A;0626;064A 0654; # (ﺊ; ﺊ; ﺊ; ئ; ي◌ٔ; ) ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM
+FE8B;FE8B;FE8B;0626;064A 0654; # (ﺋ; ﺋ; ﺋ; ئ; ي◌ٔ; ) ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
+FE8C;FE8C;FE8C;0626;064A 0654; # (ﺌ; ﺌ; ﺌ; ئ; ي◌ٔ; ) ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM
+FE8D;FE8D;FE8D;0627;0627; # (ﺍ; ﺍ; ﺍ; ا; ا; ) ARABIC LETTER ALEF ISOLATED FORM
+FE8E;FE8E;FE8E;0627;0627; # (ﺎ; ﺎ; ﺎ; ا; ا; ) ARABIC LETTER ALEF FINAL FORM
+FE8F;FE8F;FE8F;0628;0628; # (ﺏ; ﺏ; ﺏ; ب; ب; ) ARABIC LETTER BEH ISOLATED FORM
+FE90;FE90;FE90;0628;0628; # (ﺐ; ﺐ; ﺐ; ب; ب; ) ARABIC LETTER BEH FINAL FORM
+FE91;FE91;FE91;0628;0628; # (ﺑ; ﺑ; ﺑ; ب; ب; ) ARABIC LETTER BEH INITIAL FORM
+FE92;FE92;FE92;0628;0628; # (ﺒ; ﺒ; ﺒ; ب; ب; ) ARABIC LETTER BEH MEDIAL FORM
+FE93;FE93;FE93;0629;0629; # (ﺓ; ﺓ; ﺓ; ة; ة; ) ARABIC LETTER TEH MARBUTA ISOLATED FORM
+FE94;FE94;FE94;0629;0629; # (ﺔ; ﺔ; ﺔ; ة; ة; ) ARABIC LETTER TEH MARBUTA FINAL FORM
+FE95;FE95;FE95;062A;062A; # (ﺕ; ﺕ; ﺕ; ت; ت; ) ARABIC LETTER TEH ISOLATED FORM
+FE96;FE96;FE96;062A;062A; # (ﺖ; ﺖ; ﺖ; ت; ت; ) ARABIC LETTER TEH FINAL FORM
+FE97;FE97;FE97;062A;062A; # (ﺗ; ﺗ; ﺗ; ت; ت; ) ARABIC LETTER TEH INITIAL FORM
+FE98;FE98;FE98;062A;062A; # (ﺘ; ﺘ; ﺘ; ت; ت; ) ARABIC LETTER TEH MEDIAL FORM
+FE99;FE99;FE99;062B;062B; # (ﺙ; ﺙ; ﺙ; ث; ث; ) ARABIC LETTER THEH ISOLATED FORM
+FE9A;FE9A;FE9A;062B;062B; # (ﺚ; ﺚ; ﺚ; ث; ث; ) ARABIC LETTER THEH FINAL FORM
+FE9B;FE9B;FE9B;062B;062B; # (ﺛ; ﺛ; ﺛ; ث; ث; ) ARABIC LETTER THEH INITIAL FORM
+FE9C;FE9C;FE9C;062B;062B; # (ﺜ; ﺜ; ﺜ; ث; ث; ) ARABIC LETTER THEH MEDIAL FORM
+FE9D;FE9D;FE9D;062C;062C; # (ﺝ; ﺝ; ﺝ; ج; ج; ) ARABIC LETTER JEEM ISOLATED FORM
+FE9E;FE9E;FE9E;062C;062C; # (ﺞ; ﺞ; ﺞ; ج; ج; ) ARABIC LETTER JEEM FINAL FORM
+FE9F;FE9F;FE9F;062C;062C; # (ﺟ; ﺟ; ﺟ; ج; ج; ) ARABIC LETTER JEEM INITIAL FORM
+FEA0;FEA0;FEA0;062C;062C; # (ﺠ; ﺠ; ﺠ; ج; ج; ) ARABIC LETTER JEEM MEDIAL FORM
+FEA1;FEA1;FEA1;062D;062D; # (ﺡ; ﺡ; ﺡ; ح; ح; ) ARABIC LETTER HAH ISOLATED FORM
+FEA2;FEA2;FEA2;062D;062D; # (ﺢ; ﺢ; ﺢ; ح; ح; ) ARABIC LETTER HAH FINAL FORM
+FEA3;FEA3;FEA3;062D;062D; # (ﺣ; ﺣ; ﺣ; ح; ح; ) ARABIC LETTER HAH INITIAL FORM
+FEA4;FEA4;FEA4;062D;062D; # (ﺤ; ﺤ; ﺤ; ح; ح; ) ARABIC LETTER HAH MEDIAL FORM
+FEA5;FEA5;FEA5;062E;062E; # (ﺥ; ﺥ; ﺥ; خ; خ; ) ARABIC LETTER KHAH ISOLATED FORM
+FEA6;FEA6;FEA6;062E;062E; # (ﺦ; ﺦ; ﺦ; خ; خ; ) ARABIC LETTER KHAH FINAL FORM
+FEA7;FEA7;FEA7;062E;062E; # (ﺧ; ﺧ; ﺧ; خ; خ; ) ARABIC LETTER KHAH INITIAL FORM
+FEA8;FEA8;FEA8;062E;062E; # (ﺨ; ﺨ; ﺨ; خ; خ; ) ARABIC LETTER KHAH MEDIAL FORM
+FEA9;FEA9;FEA9;062F;062F; # (ﺩ; ﺩ; ﺩ; د; د; ) ARABIC LETTER DAL ISOLATED FORM
+FEAA;FEAA;FEAA;062F;062F; # (ﺪ; ﺪ; ﺪ; د; د; ) ARABIC LETTER DAL FINAL FORM
+FEAB;FEAB;FEAB;0630;0630; # (ﺫ; ﺫ; ﺫ; ذ; ذ; ) ARABIC LETTER THAL ISOLATED FORM
+FEAC;FEAC;FEAC;0630;0630; # (ﺬ; ﺬ; ﺬ; ذ; ذ; ) ARABIC LETTER THAL FINAL FORM
+FEAD;FEAD;FEAD;0631;0631; # (ﺭ; ﺭ; ﺭ; ر; ر; ) ARABIC LETTER REH ISOLATED FORM
+FEAE;FEAE;FEAE;0631;0631; # (ﺮ; ﺮ; ﺮ; ر; ر; ) ARABIC LETTER REH FINAL FORM
+FEAF;FEAF;FEAF;0632;0632; # (ﺯ; ﺯ; ﺯ; ز; ز; ) ARABIC LETTER ZAIN ISOLATED FORM
+FEB0;FEB0;FEB0;0632;0632; # (ﺰ; ﺰ; ﺰ; ز; ز; ) ARABIC LETTER ZAIN FINAL FORM
+FEB1;FEB1;FEB1;0633;0633; # (ﺱ; ﺱ; ﺱ; س; س; ) ARABIC LETTER SEEN ISOLATED FORM
+FEB2;FEB2;FEB2;0633;0633; # (ﺲ; ﺲ; ﺲ; س; س; ) ARABIC LETTER SEEN FINAL FORM
+FEB3;FEB3;FEB3;0633;0633; # (ﺳ; ﺳ; ﺳ; س; س; ) ARABIC LETTER SEEN INITIAL FORM
+FEB4;FEB4;FEB4;0633;0633; # (ﺴ; ﺴ; ﺴ; س; س; ) ARABIC LETTER SEEN MEDIAL FORM
+FEB5;FEB5;FEB5;0634;0634; # (ﺵ; ﺵ; ﺵ; ش; ش; ) ARABIC LETTER SHEEN ISOLATED FORM
+FEB6;FEB6;FEB6;0634;0634; # (ﺶ; ﺶ; ﺶ; ش; ش; ) ARABIC LETTER SHEEN FINAL FORM
+FEB7;FEB7;FEB7;0634;0634; # (ﺷ; ﺷ; ﺷ; ش; ش; ) ARABIC LETTER SHEEN INITIAL FORM
+FEB8;FEB8;FEB8;0634;0634; # (ﺸ; ﺸ; ﺸ; ش; ش; ) ARABIC LETTER SHEEN MEDIAL FORM
+FEB9;FEB9;FEB9;0635;0635; # (ﺹ; ﺹ; ﺹ; ص; ص; ) ARABIC LETTER SAD ISOLATED FORM
+FEBA;FEBA;FEBA;0635;0635; # (ﺺ; ﺺ; ﺺ; ص; ص; ) ARABIC LETTER SAD FINAL FORM
+FEBB;FEBB;FEBB;0635;0635; # (ﺻ; ﺻ; ﺻ; ص; ص; ) ARABIC LETTER SAD INITIAL FORM
+FEBC;FEBC;FEBC;0635;0635; # (ﺼ; ﺼ; ﺼ; ص; ص; ) ARABIC LETTER SAD MEDIAL FORM
+FEBD;FEBD;FEBD;0636;0636; # (ﺽ; ﺽ; ﺽ; ض; ض; ) ARABIC LETTER DAD ISOLATED FORM
+FEBE;FEBE;FEBE;0636;0636; # (ﺾ; ﺾ; ﺾ; ض; ض; ) ARABIC LETTER DAD FINAL FORM
+FEBF;FEBF;FEBF;0636;0636; # (ﺿ; ﺿ; ﺿ; ض; ض; ) ARABIC LETTER DAD INITIAL FORM
+FEC0;FEC0;FEC0;0636;0636; # (ﻀ; ﻀ; ﻀ; ض; ض; ) ARABIC LETTER DAD MEDIAL FORM
+FEC1;FEC1;FEC1;0637;0637; # (ﻁ; ﻁ; ﻁ; ط; ط; ) ARABIC LETTER TAH ISOLATED FORM
+FEC2;FEC2;FEC2;0637;0637; # (ﻂ; ﻂ; ﻂ; ط; ط; ) ARABIC LETTER TAH FINAL FORM
+FEC3;FEC3;FEC3;0637;0637; # (ﻃ; ﻃ; ﻃ; ط; ط; ) ARABIC LETTER TAH INITIAL FORM
+FEC4;FEC4;FEC4;0637;0637; # (ﻄ; ﻄ; ﻄ; ط; ط; ) ARABIC LETTER TAH MEDIAL FORM
+FEC5;FEC5;FEC5;0638;0638; # (ﻅ; ﻅ; ﻅ; ظ; ظ; ) ARABIC LETTER ZAH ISOLATED FORM
+FEC6;FEC6;FEC6;0638;0638; # (ﻆ; ﻆ; ﻆ; ظ; ظ; ) ARABIC LETTER ZAH FINAL FORM
+FEC7;FEC7;FEC7;0638;0638; # (ﻇ; ﻇ; ﻇ; ظ; ظ; ) ARABIC LETTER ZAH INITIAL FORM
+FEC8;FEC8;FEC8;0638;0638; # (ﻈ; ﻈ; ﻈ; ظ; ظ; ) ARABIC LETTER ZAH MEDIAL FORM
+FEC9;FEC9;FEC9;0639;0639; # (ﻉ; ﻉ; ﻉ; ع; ع; ) ARABIC LETTER AIN ISOLATED FORM
+FECA;FECA;FECA;0639;0639; # (ﻊ; ﻊ; ﻊ; ع; ع; ) ARABIC LETTER AIN FINAL FORM
+FECB;FECB;FECB;0639;0639; # (ﻋ; ﻋ; ﻋ; ع; ع; ) ARABIC LETTER AIN INITIAL FORM
+FECC;FECC;FECC;0639;0639; # (ﻌ; ﻌ; ﻌ; ع; ع; ) ARABIC LETTER AIN MEDIAL FORM
+FECD;FECD;FECD;063A;063A; # (ﻍ; ﻍ; ﻍ; غ; غ; ) ARABIC LETTER GHAIN ISOLATED FORM
+FECE;FECE;FECE;063A;063A; # (ﻎ; ﻎ; ﻎ; غ; غ; ) ARABIC LETTER GHAIN FINAL FORM
+FECF;FECF;FECF;063A;063A; # (ﻏ; ﻏ; ﻏ; غ; غ; ) ARABIC LETTER GHAIN INITIAL FORM
+FED0;FED0;FED0;063A;063A; # (ﻐ; ﻐ; ﻐ; غ; غ; ) ARABIC LETTER GHAIN MEDIAL FORM
+FED1;FED1;FED1;0641;0641; # (ﻑ; ﻑ; ﻑ; ف; ف; ) ARABIC LETTER FEH ISOLATED FORM
+FED2;FED2;FED2;0641;0641; # (ﻒ; ﻒ; ﻒ; ف; ف; ) ARABIC LETTER FEH FINAL FORM
+FED3;FED3;FED3;0641;0641; # (ﻓ; ﻓ; ﻓ; ف; ف; ) ARABIC LETTER FEH INITIAL FORM
+FED4;FED4;FED4;0641;0641; # (ﻔ; ﻔ; ﻔ; ف; ف; ) ARABIC LETTER FEH MEDIAL FORM
+FED5;FED5;FED5;0642;0642; # (ﻕ; ﻕ; ﻕ; ق; ق; ) ARABIC LETTER QAF ISOLATED FORM
+FED6;FED6;FED6;0642;0642; # (ﻖ; ﻖ; ﻖ; ق; ق; ) ARABIC LETTER QAF FINAL FORM
+FED7;FED7;FED7;0642;0642; # (ﻗ; ﻗ; ﻗ; ق; ق; ) ARABIC LETTER QAF INITIAL FORM
+FED8;FED8;FED8;0642;0642; # (ﻘ; ﻘ; ﻘ; ق; ق; ) ARABIC LETTER QAF MEDIAL FORM
+FED9;FED9;FED9;0643;0643; # (ﻙ; ﻙ; ﻙ; ك; ك; ) ARABIC LETTER KAF ISOLATED FORM
+FEDA;FEDA;FEDA;0643;0643; # (ﻚ; ﻚ; ﻚ; ك; ك; ) ARABIC LETTER KAF FINAL FORM
+FEDB;FEDB;FEDB;0643;0643; # (ﻛ; ﻛ; ﻛ; ك; ك; ) ARABIC LETTER KAF INITIAL FORM
+FEDC;FEDC;FEDC;0643;0643; # (ﻜ; ﻜ; ﻜ; ك; ك; ) ARABIC LETTER KAF MEDIAL FORM
+FEDD;FEDD;FEDD;0644;0644; # (ﻝ; ﻝ; ﻝ; ل; ل; ) ARABIC LETTER LAM ISOLATED FORM
+FEDE;FEDE;FEDE;0644;0644; # (ﻞ; ﻞ; ﻞ; ل; ل; ) ARABIC LETTER LAM FINAL FORM
+FEDF;FEDF;FEDF;0644;0644; # (ﻟ; ﻟ; ﻟ; ل; ل; ) ARABIC LETTER LAM INITIAL FORM
+FEE0;FEE0;FEE0;0644;0644; # (ﻠ; ﻠ; ﻠ; ل; ل; ) ARABIC LETTER LAM MEDIAL FORM
+FEE1;FEE1;FEE1;0645;0645; # (ﻡ; ﻡ; ﻡ; م; م; ) ARABIC LETTER MEEM ISOLATED FORM
+FEE2;FEE2;FEE2;0645;0645; # (ﻢ; ﻢ; ﻢ; م; م; ) ARABIC LETTER MEEM FINAL FORM
+FEE3;FEE3;FEE3;0645;0645; # (ﻣ; ﻣ; ﻣ; م; م; ) ARABIC LETTER MEEM INITIAL FORM
+FEE4;FEE4;FEE4;0645;0645; # (ﻤ; ﻤ; ﻤ; م; م; ) ARABIC LETTER MEEM MEDIAL FORM
+FEE5;FEE5;FEE5;0646;0646; # (ﻥ; ﻥ; ﻥ; ن; ن; ) ARABIC LETTER NOON ISOLATED FORM
+FEE6;FEE6;FEE6;0646;0646; # (ﻦ; ﻦ; ﻦ; ن; ن; ) ARABIC LETTER NOON FINAL FORM
+FEE7;FEE7;FEE7;0646;0646; # (ﻧ; ﻧ; ﻧ; ن; ن; ) ARABIC LETTER NOON INITIAL FORM
+FEE8;FEE8;FEE8;0646;0646; # (ﻨ; ﻨ; ﻨ; ن; ن; ) ARABIC LETTER NOON MEDIAL FORM
+FEE9;FEE9;FEE9;0647;0647; # (ﻩ; ﻩ; ﻩ; ه; ه; ) ARABIC LETTER HEH ISOLATED FORM
+FEEA;FEEA;FEEA;0647;0647; # (ﻪ; ﻪ; ﻪ; ه; ه; ) ARABIC LETTER HEH FINAL FORM
+FEEB;FEEB;FEEB;0647;0647; # (ﻫ; ﻫ; ﻫ; ه; ه; ) ARABIC LETTER HEH INITIAL FORM
+FEEC;FEEC;FEEC;0647;0647; # (ﻬ; ﻬ; ﻬ; ه; ه; ) ARABIC LETTER HEH MEDIAL FORM
+FEED;FEED;FEED;0648;0648; # (ﻭ; ﻭ; ﻭ; و; و; ) ARABIC LETTER WAW ISOLATED FORM
+FEEE;FEEE;FEEE;0648;0648; # (ﻮ; ﻮ; ﻮ; و; و; ) ARABIC LETTER WAW FINAL FORM
+FEEF;FEEF;FEEF;0649;0649; # (ﻯ; ﻯ; ﻯ; ى; ى; ) ARABIC LETTER ALEF MAKSURA ISOLATED FORM
+FEF0;FEF0;FEF0;0649;0649; # (ﻰ; ﻰ; ﻰ; ى; ى; ) ARABIC LETTER ALEF MAKSURA FINAL FORM
+FEF1;FEF1;FEF1;064A;064A; # (ﻱ; ﻱ; ﻱ; ي; ي; ) ARABIC LETTER YEH ISOLATED FORM
+FEF2;FEF2;FEF2;064A;064A; # (ﻲ; ﻲ; ﻲ; ي; ي; ) ARABIC LETTER YEH FINAL FORM
+FEF3;FEF3;FEF3;064A;064A; # (ﻳ; ﻳ; ﻳ; ي; ي; ) ARABIC LETTER YEH INITIAL FORM
+FEF4;FEF4;FEF4;064A;064A; # (ﻴ; ﻴ; ﻴ; ي; ي; ) ARABIC LETTER YEH MEDIAL FORM
+FEF5;FEF5;FEF5;0644 0622;0644 0627 0653; # (ﻵ; ﻵ; ﻵ; لآ; لا◌ٓ; ) ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
+FEF6;FEF6;FEF6;0644 0622;0644 0627 0653; # (ﻶ; ﻶ; ﻶ; لآ; لا◌ٓ; ) ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
+FEF7;FEF7;FEF7;0644 0623;0644 0627 0654; # (ﻷ; ﻷ; ﻷ; لأ; لا◌ٔ; ) ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
+FEF8;FEF8;FEF8;0644 0623;0644 0627 0654; # (ﻸ; ﻸ; ﻸ; لأ; لا◌ٔ; ) ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
+FEF9;FEF9;FEF9;0644 0625;0644 0627 0655; # (ﻹ; ﻹ; ﻹ; لإ; لا◌ٕ; ) ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM
+FEFA;FEFA;FEFA;0644 0625;0644 0627 0655; # (ﻺ; ﻺ; ﻺ; لإ; لا◌ٕ; ) ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM
+FEFB;FEFB;FEFB;0644 0627;0644 0627; # (ﻻ; ﻻ; ﻻ; لا; لا; ) ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
+FEFC;FEFC;FEFC;0644 0627;0644 0627; # (ﻼ; ﻼ; ﻼ; لا; لا; ) ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+FF01;FF01;FF01;0021;0021; # (!; !; !; !; !; ) FULLWIDTH EXCLAMATION MARK
+FF02;FF02;FF02;0022;0022; # ("; "; "; "; "; ) FULLWIDTH QUOTATION MARK
+FF03;FF03;FF03;0023;0023; # (#; #; #; #; #; ) FULLWIDTH NUMBER SIGN
+FF04;FF04;FF04;0024;0024; # ($; $; $; $; $; ) FULLWIDTH DOLLAR SIGN
+FF05;FF05;FF05;0025;0025; # (%; %; %; %; %; ) FULLWIDTH PERCENT SIGN
+FF06;FF06;FF06;0026;0026; # (&; &; &; &; &; ) FULLWIDTH AMPERSAND
+FF07;FF07;FF07;0027;0027; # ('; '; '; '; '; ) FULLWIDTH APOSTROPHE
+FF08;FF08;FF08;0028;0028; # ((; (; (; (; (; ) FULLWIDTH LEFT PARENTHESIS
+FF09;FF09;FF09;0029;0029; # (); ); ); ); ); ) FULLWIDTH RIGHT PARENTHESIS
+FF0A;FF0A;FF0A;002A;002A; # (*; *; *; *; *; ) FULLWIDTH ASTERISK
+FF0B;FF0B;FF0B;002B;002B; # (+; +; +; +; +; ) FULLWIDTH PLUS SIGN
+FF0C;FF0C;FF0C;002C;002C; # (,; ,; ,; ,; ,; ) FULLWIDTH COMMA
+FF0D;FF0D;FF0D;002D;002D; # (-; -; -; -; -; ) FULLWIDTH HYPHEN-MINUS
+FF0E;FF0E;FF0E;002E;002E; # (.; .; .; .; .; ) FULLWIDTH FULL STOP
+FF0F;FF0F;FF0F;002F;002F; # (/; /; /; /; /; ) FULLWIDTH SOLIDUS
+FF10;FF10;FF10;0030;0030; # (0; 0; 0; 0; 0; ) FULLWIDTH DIGIT ZERO
+FF11;FF11;FF11;0031;0031; # (1; 1; 1; 1; 1; ) FULLWIDTH DIGIT ONE
+FF12;FF12;FF12;0032;0032; # (2; 2; 2; 2; 2; ) FULLWIDTH DIGIT TWO
+FF13;FF13;FF13;0033;0033; # (3; 3; 3; 3; 3; ) FULLWIDTH DIGIT THREE
+FF14;FF14;FF14;0034;0034; # (4; 4; 4; 4; 4; ) FULLWIDTH DIGIT FOUR
+FF15;FF15;FF15;0035;0035; # (5; 5; 5; 5; 5; ) FULLWIDTH DIGIT FIVE
+FF16;FF16;FF16;0036;0036; # (6; 6; 6; 6; 6; ) FULLWIDTH DIGIT SIX
+FF17;FF17;FF17;0037;0037; # (7; 7; 7; 7; 7; ) FULLWIDTH DIGIT SEVEN
+FF18;FF18;FF18;0038;0038; # (8; 8; 8; 8; 8; ) FULLWIDTH DIGIT EIGHT
+FF19;FF19;FF19;0039;0039; # (9; 9; 9; 9; 9; ) FULLWIDTH DIGIT NINE
+FF1A;FF1A;FF1A;003A;003A; # (:; :; :; :; :; ) FULLWIDTH COLON
+FF1B;FF1B;FF1B;003B;003B; # (;; ;; ;; ;; ;; ) FULLWIDTH SEMICOLON
+FF1C;FF1C;FF1C;003C;003C; # (<; <; <; <; <; ) FULLWIDTH LESS-THAN SIGN
+FF1D;FF1D;FF1D;003D;003D; # (=; =; =; =; =; ) FULLWIDTH EQUALS SIGN
+FF1E;FF1E;FF1E;003E;003E; # (>; >; >; >; >; ) FULLWIDTH GREATER-THAN SIGN
+FF1F;FF1F;FF1F;003F;003F; # (?; ?; ?; ?; ?; ) FULLWIDTH QUESTION MARK
+FF20;FF20;FF20;0040;0040; # (@; @; @; @; @; ) FULLWIDTH COMMERCIAL AT
+FF21;FF21;FF21;0041;0041; # (A; A; A; A; A; ) FULLWIDTH LATIN CAPITAL LETTER A
+FF22;FF22;FF22;0042;0042; # (B; B; B; B; B; ) FULLWIDTH LATIN CAPITAL LETTER B
+FF23;FF23;FF23;0043;0043; # (C; C; C; C; C; ) FULLWIDTH LATIN CAPITAL LETTER C
+FF24;FF24;FF24;0044;0044; # (D; D; D; D; D; ) FULLWIDTH LATIN CAPITAL LETTER D
+FF25;FF25;FF25;0045;0045; # (E; E; E; E; E; ) FULLWIDTH LATIN CAPITAL LETTER E
+FF26;FF26;FF26;0046;0046; # (F; F; F; F; F; ) FULLWIDTH LATIN CAPITAL LETTER F
+FF27;FF27;FF27;0047;0047; # (G; G; G; G; G; ) FULLWIDTH LATIN CAPITAL LETTER G
+FF28;FF28;FF28;0048;0048; # (H; H; H; H; H; ) FULLWIDTH LATIN CAPITAL LETTER H
+FF29;FF29;FF29;0049;0049; # (I; I; I; I; I; ) FULLWIDTH LATIN CAPITAL LETTER I
+FF2A;FF2A;FF2A;004A;004A; # (J; J; J; J; J; ) FULLWIDTH LATIN CAPITAL LETTER J
+FF2B;FF2B;FF2B;004B;004B; # (K; K; K; K; K; ) FULLWIDTH LATIN CAPITAL LETTER K
+FF2C;FF2C;FF2C;004C;004C; # (L; L; L; L; L; ) FULLWIDTH LATIN CAPITAL LETTER L
+FF2D;FF2D;FF2D;004D;004D; # (M; M; M; M; M; ) FULLWIDTH LATIN CAPITAL LETTER M
+FF2E;FF2E;FF2E;004E;004E; # (N; N; N; N; N; ) FULLWIDTH LATIN CAPITAL LETTER N
+FF2F;FF2F;FF2F;004F;004F; # (O; O; O; O; O; ) FULLWIDTH LATIN CAPITAL LETTER O
+FF30;FF30;FF30;0050;0050; # (P; P; P; P; P; ) FULLWIDTH LATIN CAPITAL LETTER P
+FF31;FF31;FF31;0051;0051; # (Q; Q; Q; Q; Q; ) FULLWIDTH LATIN CAPITAL LETTER Q
+FF32;FF32;FF32;0052;0052; # (R; R; R; R; R; ) FULLWIDTH LATIN CAPITAL LETTER R
+FF33;FF33;FF33;0053;0053; # (S; S; S; S; S; ) FULLWIDTH LATIN CAPITAL LETTER S
+FF34;FF34;FF34;0054;0054; # (T; T; T; T; T; ) FULLWIDTH LATIN CAPITAL LETTER T
+FF35;FF35;FF35;0055;0055; # (U; U; U; U; U; ) FULLWIDTH LATIN CAPITAL LETTER U
+FF36;FF36;FF36;0056;0056; # (V; V; V; V; V; ) FULLWIDTH LATIN CAPITAL LETTER V
+FF37;FF37;FF37;0057;0057; # (W; W; W; W; W; ) FULLWIDTH LATIN CAPITAL LETTER W
+FF38;FF38;FF38;0058;0058; # (X; X; X; X; X; ) FULLWIDTH LATIN CAPITAL LETTER X
+FF39;FF39;FF39;0059;0059; # (Y; Y; Y; Y; Y; ) FULLWIDTH LATIN CAPITAL LETTER Y
+FF3A;FF3A;FF3A;005A;005A; # (Z; Z; Z; Z; Z; ) FULLWIDTH LATIN CAPITAL LETTER Z
+FF3B;FF3B;FF3B;005B;005B; # ([; [; [; [; [; ) FULLWIDTH LEFT SQUARE BRACKET
+FF3C;FF3C;FF3C;005C;005C; # (\; \; \; \; \; ) FULLWIDTH REVERSE SOLIDUS
+FF3D;FF3D;FF3D;005D;005D; # (]; ]; ]; ]; ]; ) FULLWIDTH RIGHT SQUARE BRACKET
+FF3E;FF3E;FF3E;005E;005E; # (^; ^; ^; ^; ^; ) FULLWIDTH CIRCUMFLEX ACCENT
+FF3F;FF3F;FF3F;005F;005F; # (_; _; _; _; _; ) FULLWIDTH LOW LINE
+FF40;FF40;FF40;0060;0060; # (`; `; `; `; `; ) FULLWIDTH GRAVE ACCENT
+FF41;FF41;FF41;0061;0061; # (a; a; a; a; a; ) FULLWIDTH LATIN SMALL LETTER A
+FF42;FF42;FF42;0062;0062; # (b; b; b; b; b; ) FULLWIDTH LATIN SMALL LETTER B
+FF43;FF43;FF43;0063;0063; # (c; c; c; c; c; ) FULLWIDTH LATIN SMALL LETTER C
+FF44;FF44;FF44;0064;0064; # (d; d; d; d; d; ) FULLWIDTH LATIN SMALL LETTER D
+FF45;FF45;FF45;0065;0065; # (e; e; e; e; e; ) FULLWIDTH LATIN SMALL LETTER E
+FF46;FF46;FF46;0066;0066; # (f; f; f; f; f; ) FULLWIDTH LATIN SMALL LETTER F
+FF47;FF47;FF47;0067;0067; # (g; g; g; g; g; ) FULLWIDTH LATIN SMALL LETTER G
+FF48;FF48;FF48;0068;0068; # (h; h; h; h; h; ) FULLWIDTH LATIN SMALL LETTER H
+FF49;FF49;FF49;0069;0069; # (i; i; i; i; i; ) FULLWIDTH LATIN SMALL LETTER I
+FF4A;FF4A;FF4A;006A;006A; # (j; j; j; j; j; ) FULLWIDTH LATIN SMALL LETTER J
+FF4B;FF4B;FF4B;006B;006B; # (k; k; k; k; k; ) FULLWIDTH LATIN SMALL LETTER K
+FF4C;FF4C;FF4C;006C;006C; # (l; l; l; l; l; ) FULLWIDTH LATIN SMALL LETTER L
+FF4D;FF4D;FF4D;006D;006D; # (m; m; m; m; m; ) FULLWIDTH LATIN SMALL LETTER M
+FF4E;FF4E;FF4E;006E;006E; # (n; n; n; n; n; ) FULLWIDTH LATIN SMALL LETTER N
+FF4F;FF4F;FF4F;006F;006F; # (o; o; o; o; o; ) FULLWIDTH LATIN SMALL LETTER O
+FF50;FF50;FF50;0070;0070; # (p; p; p; p; p; ) FULLWIDTH LATIN SMALL LETTER P
+FF51;FF51;FF51;0071;0071; # (q; q; q; q; q; ) FULLWIDTH LATIN SMALL LETTER Q
+FF52;FF52;FF52;0072;0072; # (r; r; r; r; r; ) FULLWIDTH LATIN SMALL LETTER R
+FF53;FF53;FF53;0073;0073; # (s; s; s; s; s; ) FULLWIDTH LATIN SMALL LETTER S
+FF54;FF54;FF54;0074;0074; # (t; t; t; t; t; ) FULLWIDTH LATIN SMALL LETTER T
+FF55;FF55;FF55;0075;0075; # (u; u; u; u; u; ) FULLWIDTH LATIN SMALL LETTER U
+FF56;FF56;FF56;0076;0076; # (v; v; v; v; v; ) FULLWIDTH LATIN SMALL LETTER V
+FF57;FF57;FF57;0077;0077; # (w; w; w; w; w; ) FULLWIDTH LATIN SMALL LETTER W
+FF58;FF58;FF58;0078;0078; # (x; x; x; x; x; ) FULLWIDTH LATIN SMALL LETTER X
+FF59;FF59;FF59;0079;0079; # (y; y; y; y; y; ) FULLWIDTH LATIN SMALL LETTER Y
+FF5A;FF5A;FF5A;007A;007A; # (z; z; z; z; z; ) FULLWIDTH LATIN SMALL LETTER Z
+FF5B;FF5B;FF5B;007B;007B; # ({; {; {; {; {; ) FULLWIDTH LEFT CURLY BRACKET
+FF5C;FF5C;FF5C;007C;007C; # (|; |; |; |; |; ) FULLWIDTH VERTICAL LINE
+FF5D;FF5D;FF5D;007D;007D; # (}; }; }; }; }; ) FULLWIDTH RIGHT CURLY BRACKET
+FF5E;FF5E;FF5E;007E;007E; # (~; ~; ~; ~; ~; ) FULLWIDTH TILDE
+FF5F;FF5F;FF5F;2985;2985; # (⦅; ⦅; ⦅; ⦅; ⦅; ) FULLWIDTH LEFT WHITE PARENTHESIS
+FF60;FF60;FF60;2986;2986; # (⦆; ⦆; ⦆; ⦆; ⦆; ) FULLWIDTH RIGHT WHITE PARENTHESIS
+FF61;FF61;FF61;3002;3002; # (。; 。; 。; 。; 。; ) HALFWIDTH IDEOGRAPHIC FULL STOP
+FF62;FF62;FF62;300C;300C; # (「; 「; 「; 「; 「; ) HALFWIDTH LEFT CORNER BRACKET
+FF63;FF63;FF63;300D;300D; # (」; 」; 」; 」; 」; ) HALFWIDTH RIGHT CORNER BRACKET
+FF64;FF64;FF64;3001;3001; # (、; 、; 、; 、; 、; ) HALFWIDTH IDEOGRAPHIC COMMA
+FF65;FF65;FF65;30FB;30FB; # (・; ・; ・; ・; ・; ) HALFWIDTH KATAKANA MIDDLE DOT
+FF66;FF66;FF66;30F2;30F2; # (ヲ; ヲ; ヲ; ヲ; ヲ; ) HALFWIDTH KATAKANA LETTER WO
+FF67;FF67;FF67;30A1;30A1; # (ァ; ァ; ァ; ァ; ァ; ) HALFWIDTH KATAKANA LETTER SMALL A
+FF68;FF68;FF68;30A3;30A3; # (ィ; ィ; ィ; ィ; ィ; ) HALFWIDTH KATAKANA LETTER SMALL I
+FF69;FF69;FF69;30A5;30A5; # (ゥ; ゥ; ゥ; ゥ; ゥ; ) HALFWIDTH KATAKANA LETTER SMALL U
+FF6A;FF6A;FF6A;30A7;30A7; # (ェ; ェ; ェ; ェ; ェ; ) HALFWIDTH KATAKANA LETTER SMALL E
+FF6B;FF6B;FF6B;30A9;30A9; # (ォ; ォ; ォ; ォ; ォ; ) HALFWIDTH KATAKANA LETTER SMALL O
+FF6C;FF6C;FF6C;30E3;30E3; # (ャ; ャ; ャ; ャ; ャ; ) HALFWIDTH KATAKANA LETTER SMALL YA
+FF6D;FF6D;FF6D;30E5;30E5; # (ュ; ュ; ュ; ュ; ュ; ) HALFWIDTH KATAKANA LETTER SMALL YU
+FF6E;FF6E;FF6E;30E7;30E7; # (ョ; ョ; ョ; ョ; ョ; ) HALFWIDTH KATAKANA LETTER SMALL YO
+FF6F;FF6F;FF6F;30C3;30C3; # (ッ; ッ; ッ; ッ; ッ; ) HALFWIDTH KATAKANA LETTER SMALL TU
+FF70;FF70;FF70;30FC;30FC; # (ー; ー; ー; ー; ー; ) HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+FF71;FF71;FF71;30A2;30A2; # (ア; ア; ア; ア; ア; ) HALFWIDTH KATAKANA LETTER A
+FF72;FF72;FF72;30A4;30A4; # (イ; イ; イ; イ; イ; ) HALFWIDTH KATAKANA LETTER I
+FF73;FF73;FF73;30A6;30A6; # (ウ; ウ; ウ; ウ; ウ; ) HALFWIDTH KATAKANA LETTER U
+FF74;FF74;FF74;30A8;30A8; # (エ; エ; エ; エ; エ; ) HALFWIDTH KATAKANA LETTER E
+FF75;FF75;FF75;30AA;30AA; # (オ; オ; オ; オ; オ; ) HALFWIDTH KATAKANA LETTER O
+FF76;FF76;FF76;30AB;30AB; # (カ; カ; カ; カ; カ; ) HALFWIDTH KATAKANA LETTER KA
+FF77;FF77;FF77;30AD;30AD; # (キ; キ; キ; キ; キ; ) HALFWIDTH KATAKANA LETTER KI
+FF78;FF78;FF78;30AF;30AF; # (ク; ク; ク; ク; ク; ) HALFWIDTH KATAKANA LETTER KU
+FF79;FF79;FF79;30B1;30B1; # (ケ; ケ; ケ; ケ; ケ; ) HALFWIDTH KATAKANA LETTER KE
+FF7A;FF7A;FF7A;30B3;30B3; # (コ; コ; コ; コ; コ; ) HALFWIDTH KATAKANA LETTER KO
+FF7B;FF7B;FF7B;30B5;30B5; # (サ; サ; サ; サ; サ; ) HALFWIDTH KATAKANA LETTER SA
+FF7C;FF7C;FF7C;30B7;30B7; # (シ; シ; シ; シ; シ; ) HALFWIDTH KATAKANA LETTER SI
+FF7D;FF7D;FF7D;30B9;30B9; # (ス; ス; ス; ス; ス; ) HALFWIDTH KATAKANA LETTER SU
+FF7E;FF7E;FF7E;30BB;30BB; # (セ; セ; セ; セ; セ; ) HALFWIDTH KATAKANA LETTER SE
+FF7F;FF7F;FF7F;30BD;30BD; # (ソ; ソ; ソ; ソ; ソ; ) HALFWIDTH KATAKANA LETTER SO
+FF80;FF80;FF80;30BF;30BF; # (タ; タ; タ; タ; タ; ) HALFWIDTH KATAKANA LETTER TA
+FF81;FF81;FF81;30C1;30C1; # (チ; チ; チ; チ; チ; ) HALFWIDTH KATAKANA LETTER TI
+FF82;FF82;FF82;30C4;30C4; # (ツ; ツ; ツ; ツ; ツ; ) HALFWIDTH KATAKANA LETTER TU
+FF83;FF83;FF83;30C6;30C6; # (テ; テ; テ; テ; テ; ) HALFWIDTH KATAKANA LETTER TE
+FF84;FF84;FF84;30C8;30C8; # (ト; ト; ト; ト; ト; ) HALFWIDTH KATAKANA LETTER TO
+FF85;FF85;FF85;30CA;30CA; # (ナ; ナ; ナ; ナ; ナ; ) HALFWIDTH KATAKANA LETTER NA
+FF86;FF86;FF86;30CB;30CB; # (ニ; ニ; ニ; ニ; ニ; ) HALFWIDTH KATAKANA LETTER NI
+FF87;FF87;FF87;30CC;30CC; # (ヌ; ヌ; ヌ; ヌ; ヌ; ) HALFWIDTH KATAKANA LETTER NU
+FF88;FF88;FF88;30CD;30CD; # (ネ; ネ; ネ; ネ; ネ; ) HALFWIDTH KATAKANA LETTER NE
+FF89;FF89;FF89;30CE;30CE; # (ノ; ノ; ノ; ノ; ノ; ) HALFWIDTH KATAKANA LETTER NO
+FF8A;FF8A;FF8A;30CF;30CF; # (ハ; ハ; ハ; ハ; ハ; ) HALFWIDTH KATAKANA LETTER HA
+FF8B;FF8B;FF8B;30D2;30D2; # (ヒ; ヒ; ヒ; ヒ; ヒ; ) HALFWIDTH KATAKANA LETTER HI
+FF8C;FF8C;FF8C;30D5;30D5; # (フ; フ; フ; フ; フ; ) HALFWIDTH KATAKANA LETTER HU
+FF8D;FF8D;FF8D;30D8;30D8; # (ヘ; ヘ; ヘ; ヘ; ヘ; ) HALFWIDTH KATAKANA LETTER HE
+FF8E;FF8E;FF8E;30DB;30DB; # (ホ; ホ; ホ; ホ; ホ; ) HALFWIDTH KATAKANA LETTER HO
+FF8F;FF8F;FF8F;30DE;30DE; # (マ; マ; マ; マ; マ; ) HALFWIDTH KATAKANA LETTER MA
+FF90;FF90;FF90;30DF;30DF; # (ミ; ミ; ミ; ミ; ミ; ) HALFWIDTH KATAKANA LETTER MI
+FF91;FF91;FF91;30E0;30E0; # (ム; ム; ム; ム; ム; ) HALFWIDTH KATAKANA LETTER MU
+FF92;FF92;FF92;30E1;30E1; # (メ; メ; メ; メ; メ; ) HALFWIDTH KATAKANA LETTER ME
+FF93;FF93;FF93;30E2;30E2; # (モ; モ; モ; モ; モ; ) HALFWIDTH KATAKANA LETTER MO
+FF94;FF94;FF94;30E4;30E4; # (ヤ; ヤ; ヤ; ヤ; ヤ; ) HALFWIDTH KATAKANA LETTER YA
+FF95;FF95;FF95;30E6;30E6; # (ユ; ユ; ユ; ユ; ユ; ) HALFWIDTH KATAKANA LETTER YU
+FF96;FF96;FF96;30E8;30E8; # (ヨ; ヨ; ヨ; ヨ; ヨ; ) HALFWIDTH KATAKANA LETTER YO
+FF97;FF97;FF97;30E9;30E9; # (ラ; ラ; ラ; ラ; ラ; ) HALFWIDTH KATAKANA LETTER RA
+FF98;FF98;FF98;30EA;30EA; # (リ; リ; リ; リ; リ; ) HALFWIDTH KATAKANA LETTER RI
+FF99;FF99;FF99;30EB;30EB; # (ル; ル; ル; ル; ル; ) HALFWIDTH KATAKANA LETTER RU
+FF9A;FF9A;FF9A;30EC;30EC; # (レ; レ; レ; レ; レ; ) HALFWIDTH KATAKANA LETTER RE
+FF9B;FF9B;FF9B;30ED;30ED; # (ロ; ロ; ロ; ロ; ロ; ) HALFWIDTH KATAKANA LETTER RO
+FF9C;FF9C;FF9C;30EF;30EF; # (ワ; ワ; ワ; ワ; ワ; ) HALFWIDTH KATAKANA LETTER WA
+FF9D;FF9D;FF9D;30F3;30F3; # (ン; ン; ン; ン; ン; ) HALFWIDTH KATAKANA LETTER N
+FF9E;FF9E;FF9E;3099;3099; # (゙; ゙; ゙; ◌゙; ◌゙; ) HALFWIDTH KATAKANA VOICED SOUND MARK
+FF9F;FF9F;FF9F;309A;309A; # (゚; ゚; ゚; ◌゚; ◌゚; ) HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+FFA0;FFA0;FFA0;1160;1160; # (ᅠ; ᅠ; ᅠ; ᅠ; ᅠ; ) HALFWIDTH HANGUL FILLER
+FFA1;FFA1;FFA1;1100;1100; # (ᄀ; ᄀ; ᄀ; ᄀ; ᄀ; ) HALFWIDTH HANGUL LETTER KIYEOK
+FFA2;FFA2;FFA2;1101;1101; # (ᄁ; ᄁ; ᄁ; ᄁ; ᄁ; ) HALFWIDTH HANGUL LETTER SSANGKIYEOK
+FFA3;FFA3;FFA3;11AA;11AA; # (ᆪ; ᆪ; ᆪ; ᆪ; ᆪ; ) HALFWIDTH HANGUL LETTER KIYEOK-SIOS
+FFA4;FFA4;FFA4;1102;1102; # (ᄂ; ᄂ; ᄂ; ᄂ; ᄂ; ) HALFWIDTH HANGUL LETTER NIEUN
+FFA5;FFA5;FFA5;11AC;11AC; # (ᆬ; ᆬ; ᆬ; ᆬ; ᆬ; ) HALFWIDTH HANGUL LETTER NIEUN-CIEUC
+FFA6;FFA6;FFA6;11AD;11AD; # (ᆭ; ᆭ; ᆭ; ᆭ; ᆭ; ) HALFWIDTH HANGUL LETTER NIEUN-HIEUH
+FFA7;FFA7;FFA7;1103;1103; # (ᄃ; ᄃ; ᄃ; ᄃ; ᄃ; ) HALFWIDTH HANGUL LETTER TIKEUT
+FFA8;FFA8;FFA8;1104;1104; # (ᄄ; ᄄ; ᄄ; ᄄ; ᄄ; ) HALFWIDTH HANGUL LETTER SSANGTIKEUT
+FFA9;FFA9;FFA9;1105;1105; # (ᄅ; ᄅ; ᄅ; ᄅ; ᄅ; ) HALFWIDTH HANGUL LETTER RIEUL
+FFAA;FFAA;FFAA;11B0;11B0; # (ᆰ; ᆰ; ᆰ; ᆰ; ᆰ; ) HALFWIDTH HANGUL LETTER RIEUL-KIYEOK
+FFAB;FFAB;FFAB;11B1;11B1; # (ᆱ; ᆱ; ᆱ; ᆱ; ᆱ; ) HALFWIDTH HANGUL LETTER RIEUL-MIEUM
+FFAC;FFAC;FFAC;11B2;11B2; # (ᆲ; ᆲ; ᆲ; ᆲ; ᆲ; ) HALFWIDTH HANGUL LETTER RIEUL-PIEUP
+FFAD;FFAD;FFAD;11B3;11B3; # (ᆳ; ᆳ; ᆳ; ᆳ; ᆳ; ) HALFWIDTH HANGUL LETTER RIEUL-SIOS
+FFAE;FFAE;FFAE;11B4;11B4; # (ᆴ; ᆴ; ᆴ; ᆴ; ᆴ; ) HALFWIDTH HANGUL LETTER RIEUL-THIEUTH
+FFAF;FFAF;FFAF;11B5;11B5; # (ᆵ; ᆵ; ᆵ; ᆵ; ᆵ; ) HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH
+FFB0;FFB0;FFB0;111A;111A; # (ᄚ; ᄚ; ᄚ; ᄚ; ᄚ; ) HALFWIDTH HANGUL LETTER RIEUL-HIEUH
+FFB1;FFB1;FFB1;1106;1106; # (ᄆ; ᄆ; ᄆ; ᄆ; ᄆ; ) HALFWIDTH HANGUL LETTER MIEUM
+FFB2;FFB2;FFB2;1107;1107; # (ᄇ; ᄇ; ᄇ; ᄇ; ᄇ; ) HALFWIDTH HANGUL LETTER PIEUP
+FFB3;FFB3;FFB3;1108;1108; # (ᄈ; ᄈ; ᄈ; ᄈ; ᄈ; ) HALFWIDTH HANGUL LETTER SSANGPIEUP
+FFB4;FFB4;FFB4;1121;1121; # (ᄡ; ᄡ; ᄡ; ᄡ; ᄡ; ) HALFWIDTH HANGUL LETTER PIEUP-SIOS
+FFB5;FFB5;FFB5;1109;1109; # (ᄉ; ᄉ; ᄉ; ᄉ; ᄉ; ) HALFWIDTH HANGUL LETTER SIOS
+FFB6;FFB6;FFB6;110A;110A; # (ᄊ; ᄊ; ᄊ; ᄊ; ᄊ; ) HALFWIDTH HANGUL LETTER SSANGSIOS
+FFB7;FFB7;FFB7;110B;110B; # (ᄋ; ᄋ; ᄋ; ᄋ; ᄋ; ) HALFWIDTH HANGUL LETTER IEUNG
+FFB8;FFB8;FFB8;110C;110C; # (ᄌ; ᄌ; ᄌ; ᄌ; ᄌ; ) HALFWIDTH HANGUL LETTER CIEUC
+FFB9;FFB9;FFB9;110D;110D; # (ᄍ; ᄍ; ᄍ; ᄍ; ᄍ; ) HALFWIDTH HANGUL LETTER SSANGCIEUC
+FFBA;FFBA;FFBA;110E;110E; # (ᄎ; ᄎ; ᄎ; ᄎ; ᄎ; ) HALFWIDTH HANGUL LETTER CHIEUCH
+FFBB;FFBB;FFBB;110F;110F; # (ᄏ; ᄏ; ᄏ; ᄏ; ᄏ; ) HALFWIDTH HANGUL LETTER KHIEUKH
+FFBC;FFBC;FFBC;1110;1110; # (ᄐ; ᄐ; ᄐ; ᄐ; ᄐ; ) HALFWIDTH HANGUL LETTER THIEUTH
+FFBD;FFBD;FFBD;1111;1111; # (ᄑ; ᄑ; ᄑ; ᄑ; ᄑ; ) HALFWIDTH HANGUL LETTER PHIEUPH
+FFBE;FFBE;FFBE;1112;1112; # (ᄒ; ᄒ; ᄒ; ᄒ; ᄒ; ) HALFWIDTH HANGUL LETTER HIEUH
+FFC2;FFC2;FFC2;1161;1161; # (ᅡ; ᅡ; ᅡ; ᅡ; ᅡ; ) HALFWIDTH HANGUL LETTER A
+FFC3;FFC3;FFC3;1162;1162; # (ᅢ; ᅢ; ᅢ; ᅢ; ᅢ; ) HALFWIDTH HANGUL LETTER AE
+FFC4;FFC4;FFC4;1163;1163; # (ᅣ; ᅣ; ᅣ; ᅣ; ᅣ; ) HALFWIDTH HANGUL LETTER YA
+FFC5;FFC5;FFC5;1164;1164; # (ᅤ; ᅤ; ᅤ; ᅤ; ᅤ; ) HALFWIDTH HANGUL LETTER YAE
+FFC6;FFC6;FFC6;1165;1165; # (ᅥ; ᅥ; ᅥ; ᅥ; ᅥ; ) HALFWIDTH HANGUL LETTER EO
+FFC7;FFC7;FFC7;1166;1166; # (ᅦ; ᅦ; ᅦ; ᅦ; ᅦ; ) HALFWIDTH HANGUL LETTER E
+FFCA;FFCA;FFCA;1167;1167; # (ᅧ; ᅧ; ᅧ; ᅧ; ᅧ; ) HALFWIDTH HANGUL LETTER YEO
+FFCB;FFCB;FFCB;1168;1168; # (ᅨ; ᅨ; ᅨ; ᅨ; ᅨ; ) HALFWIDTH HANGUL LETTER YE
+FFCC;FFCC;FFCC;1169;1169; # (ᅩ; ᅩ; ᅩ; ᅩ; ᅩ; ) HALFWIDTH HANGUL LETTER O
+FFCD;FFCD;FFCD;116A;116A; # (ᅪ; ᅪ; ᅪ; ᅪ; ᅪ; ) HALFWIDTH HANGUL LETTER WA
+FFCE;FFCE;FFCE;116B;116B; # (ᅫ; ᅫ; ᅫ; ᅫ; ᅫ; ) HALFWIDTH HANGUL LETTER WAE
+FFCF;FFCF;FFCF;116C;116C; # (ᅬ; ᅬ; ᅬ; ᅬ; ᅬ; ) HALFWIDTH HANGUL LETTER OE
+FFD2;FFD2;FFD2;116D;116D; # (ᅭ; ᅭ; ᅭ; ᅭ; ᅭ; ) HALFWIDTH HANGUL LETTER YO
+FFD3;FFD3;FFD3;116E;116E; # (ᅮ; ᅮ; ᅮ; ᅮ; ᅮ; ) HALFWIDTH HANGUL LETTER U
+FFD4;FFD4;FFD4;116F;116F; # (ᅯ; ᅯ; ᅯ; ᅯ; ᅯ; ) HALFWIDTH HANGUL LETTER WEO
+FFD5;FFD5;FFD5;1170;1170; # (ᅰ; ᅰ; ᅰ; ᅰ; ᅰ; ) HALFWIDTH HANGUL LETTER WE
+FFD6;FFD6;FFD6;1171;1171; # (ᅱ; ᅱ; ᅱ; ᅱ; ᅱ; ) HALFWIDTH HANGUL LETTER WI
+FFD7;FFD7;FFD7;1172;1172; # (ᅲ; ᅲ; ᅲ; ᅲ; ᅲ; ) HALFWIDTH HANGUL LETTER YU
+FFDA;FFDA;FFDA;1173;1173; # (ᅳ; ᅳ; ᅳ; ᅳ; ᅳ; ) HALFWIDTH HANGUL LETTER EU
+FFDB;FFDB;FFDB;1174;1174; # (ᅴ; ᅴ; ᅴ; ᅴ; ᅴ; ) HALFWIDTH HANGUL LETTER YI
+FFDC;FFDC;FFDC;1175;1175; # (ᅵ; ᅵ; ᅵ; ᅵ; ᅵ; ) HALFWIDTH HANGUL LETTER I
+FFE0;FFE0;FFE0;00A2;00A2; # (¢; ¢; ¢; ¢; ¢; ) FULLWIDTH CENT SIGN
+FFE1;FFE1;FFE1;00A3;00A3; # (£; £; £; £; £; ) FULLWIDTH POUND SIGN
+FFE2;FFE2;FFE2;00AC;00AC; # (¬; ¬; ¬; ¬; ¬; ) FULLWIDTH NOT SIGN
+FFE3;FFE3;FFE3;0020 0304;0020 0304; # ( ̄;  ̄;  ̄; ◌̄; ◌̄; ) FULLWIDTH MACRON
+FFE4;FFE4;FFE4;00A6;00A6; # (¦; ¦; ¦; ¦; ¦; ) FULLWIDTH BROKEN BAR
+FFE5;FFE5;FFE5;00A5;00A5; # (¥; ¥; ¥; ¥; ¥; ) FULLWIDTH YEN SIGN
+FFE6;FFE6;FFE6;20A9;20A9; # (₩; ₩; ₩; ₩; ₩; ) FULLWIDTH WON SIGN
+FFE8;FFE8;FFE8;2502;2502; # (│; │; │; │; │; ) HALFWIDTH FORMS LIGHT VERTICAL
+FFE9;FFE9;FFE9;2190;2190; # (←; ←; ←; ←; ←; ) HALFWIDTH LEFTWARDS ARROW
+FFEA;FFEA;FFEA;2191;2191; # (↑; ↑; ↑; ↑; ↑; ) HALFWIDTH UPWARDS ARROW
+FFEB;FFEB;FFEB;2192;2192; # (→; →; →; →; →; ) HALFWIDTH RIGHTWARDS ARROW
+FFEC;FFEC;FFEC;2193;2193; # (↓; ↓; ↓; ↓; ↓; ) HALFWIDTH DOWNWARDS ARROW
+FFED;FFED;FFED;25A0;25A0; # (■; ■; ■; ■; ■; ) HALFWIDTH BLACK SQUARE
+FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
+1109A;1109A;11099 110BA;1109A;11099 110BA; # (𑂚; 𑂚; 𑂙◌𑂺; 𑂚; 𑂙◌𑂺; ) KAITHI LETTER DDDHA
+1109C;1109C;1109B 110BA;1109C;1109B 110BA; # (𑂜; 𑂜; 𑂛◌𑂺; 𑂜; 𑂛◌𑂺; ) KAITHI LETTER RHA
+110AB;110AB;110A5 110BA;110AB;110A5 110BA; # (𑂫; 𑂫; 𑂥◌𑂺; 𑂫; 𑂥◌𑂺; ) KAITHI LETTER VA
+1112E;1112E;11131 11127;1112E;11131 11127; # (◌𑄮; ◌𑄮; ◌𑄱◌𑄧; ◌𑄮; ◌𑄱◌𑄧; ) CHAKMA VOWEL SIGN O
+1112F;1112F;11132 11127;1112F;11132 11127; # (◌𑄯; ◌𑄯; ◌𑄲◌𑄧; ◌𑄯; ◌𑄲◌𑄧; ) CHAKMA VOWEL SIGN AU
+1134B;1134B;11347 1133E;1134B;11347 1133E; # (𑍋; 𑍋; 𑍋; 𑍋; 𑍋; ) GRANTHA VOWEL SIGN OO
+1134C;1134C;11347 11357;1134C;11347 11357; # (𑍌; 𑍌; 𑍌; 𑍌; 𑍌; ) GRANTHA VOWEL SIGN AU
+114BB;114BB;114B9 114BA;114BB;114B9 114BA; # (𑒻; 𑒻; 𑒹◌𑒺; 𑒻; 𑒹◌𑒺; ) TIRHUTA VOWEL SIGN AI
+114BC;114BC;114B9 114B0;114BC;114B9 114B0; # (𑒼; 𑒼; 𑒼; 𑒼; 𑒼; ) TIRHUTA VOWEL SIGN O
+114BE;114BE;114B9 114BD;114BE;114B9 114BD; # (𑒾; 𑒾; 𑒾; 𑒾; 𑒾; ) TIRHUTA VOWEL SIGN AU
+115BA;115BA;115B8 115AF;115BA;115B8 115AF; # (𑖺; 𑖺; 𑖺; 𑖺; 𑖺; ) SIDDHAM VOWEL SIGN O
+115BB;115BB;115B9 115AF;115BB;115B9 115AF; # (𑖻; 𑖻; 𑖻; 𑖻; 𑖻; ) SIDDHAM VOWEL SIGN AU
+1D15E;1D157 1D165;1D157 1D165;1D157 1D165;1D157 1D165; # (𝅗𝅥; 𝅗𝅥; 𝅗𝅥; 𝅗𝅥; 𝅗𝅥; ) MUSICAL SYMBOL HALF NOTE
+1D15F;1D158 1D165;1D158 1D165;1D158 1D165;1D158 1D165; # (𝅘𝅥; 𝅘𝅥; 𝅘𝅥; 𝅘𝅥; 𝅘𝅥; ) MUSICAL SYMBOL QUARTER NOTE
+1D160;1D158 1D165 1D16E;1D158 1D165 1D16E;1D158 1D165 1D16E;1D158 1D165 1D16E; # (𝅘𝅥𝅮; 𝅘𝅥𝅮; 𝅘𝅥𝅮; 𝅘𝅥𝅮; 𝅘𝅥𝅮; ) MUSICAL SYMBOL EIGHTH NOTE
+1D161;1D158 1D165 1D16F;1D158 1D165 1D16F;1D158 1D165 1D16F;1D158 1D165 1D16F; # (𝅘𝅥𝅯; 𝅘𝅥𝅯; 𝅘𝅥𝅯; 𝅘𝅥𝅯; 𝅘𝅥𝅯; ) MUSICAL SYMBOL SIXTEENTH NOTE
+1D162;1D158 1D165 1D170;1D158 1D165 1D170;1D158 1D165 1D170;1D158 1D165 1D170; # (𝅘𝅥𝅰; 𝅘𝅥𝅰; 𝅘𝅥𝅰; 𝅘𝅥𝅰; 𝅘𝅥𝅰; ) MUSICAL SYMBOL THIRTY-SECOND NOTE
+1D163;1D158 1D165 1D171;1D158 1D165 1D171;1D158 1D165 1D171;1D158 1D165 1D171; # (𝅘𝅥𝅱; 𝅘𝅥𝅱; 𝅘𝅥𝅱; 𝅘𝅥𝅱; 𝅘𝅥𝅱; ) MUSICAL SYMBOL SIXTY-FOURTH NOTE
+1D164;1D158 1D165 1D172;1D158 1D165 1D172;1D158 1D165 1D172;1D158 1D165 1D172; # (𝅘𝅥𝅲; 𝅘𝅥𝅲; 𝅘𝅥𝅲; 𝅘𝅥𝅲; 𝅘𝅥𝅲; ) MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE
+1D1BB;1D1B9 1D165;1D1B9 1D165;1D1B9 1D165;1D1B9 1D165; # (𝆹𝅥; 𝆹𝅥; 𝆹𝅥; 𝆹𝅥; 𝆹𝅥; ) MUSICAL SYMBOL MINIMA
+1D1BC;1D1BA 1D165;1D1BA 1D165;1D1BA 1D165;1D1BA 1D165; # (𝆺𝅥; 𝆺𝅥; 𝆺𝅥; 𝆺𝅥; 𝆺𝅥; ) MUSICAL SYMBOL MINIMA BLACK
+1D1BD;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E; # (𝆹𝅥𝅮; 𝆹𝅥𝅮; 𝆹𝅥𝅮; 𝆹𝅥𝅮; 𝆹𝅥𝅮; ) MUSICAL SYMBOL SEMIMINIMA WHITE
+1D1BE;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E; # (𝆺𝅥𝅮; 𝆺𝅥𝅮; 𝆺𝅥𝅮; 𝆺𝅥𝅮; 𝆺𝅥𝅮; ) MUSICAL SYMBOL SEMIMINIMA BLACK
+1D1BF;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F; # (𝆹𝅥𝅯; 𝆹𝅥𝅯; 𝆹𝅥𝅯; 𝆹𝅥𝅯; 𝆹𝅥𝅯; ) MUSICAL SYMBOL FUSA WHITE
+1D1C0;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F; # (𝆺𝅥𝅯; 𝆺𝅥𝅯; 𝆺𝅥𝅯; 𝆺𝅥𝅯; 𝆺𝅥𝅯; ) MUSICAL SYMBOL FUSA BLACK
+1D400;1D400;1D400;0041;0041; # (𝐀; 𝐀; 𝐀; A; A; ) MATHEMATICAL BOLD CAPITAL A
+1D401;1D401;1D401;0042;0042; # (𝐁; 𝐁; 𝐁; B; B; ) MATHEMATICAL BOLD CAPITAL B
+1D402;1D402;1D402;0043;0043; # (𝐂; 𝐂; 𝐂; C; C; ) MATHEMATICAL BOLD CAPITAL C
+1D403;1D403;1D403;0044;0044; # (𝐃; 𝐃; 𝐃; D; D; ) MATHEMATICAL BOLD CAPITAL D
+1D404;1D404;1D404;0045;0045; # (𝐄; 𝐄; 𝐄; E; E; ) MATHEMATICAL BOLD CAPITAL E
+1D405;1D405;1D405;0046;0046; # (𝐅; 𝐅; 𝐅; F; F; ) MATHEMATICAL BOLD CAPITAL F
+1D406;1D406;1D406;0047;0047; # (𝐆; 𝐆; 𝐆; G; G; ) MATHEMATICAL BOLD CAPITAL G
+1D407;1D407;1D407;0048;0048; # (𝐇; 𝐇; 𝐇; H; H; ) MATHEMATICAL BOLD CAPITAL H
+1D408;1D408;1D408;0049;0049; # (𝐈; 𝐈; 𝐈; I; I; ) MATHEMATICAL BOLD CAPITAL I
+1D409;1D409;1D409;004A;004A; # (𝐉; 𝐉; 𝐉; J; J; ) MATHEMATICAL BOLD CAPITAL J
+1D40A;1D40A;1D40A;004B;004B; # (𝐊; 𝐊; 𝐊; K; K; ) MATHEMATICAL BOLD CAPITAL K
+1D40B;1D40B;1D40B;004C;004C; # (𝐋; 𝐋; 𝐋; L; L; ) MATHEMATICAL BOLD CAPITAL L
+1D40C;1D40C;1D40C;004D;004D; # (𝐌; 𝐌; 𝐌; M; M; ) MATHEMATICAL BOLD CAPITAL M
+1D40D;1D40D;1D40D;004E;004E; # (𝐍; 𝐍; 𝐍; N; N; ) MATHEMATICAL BOLD CAPITAL N
+1D40E;1D40E;1D40E;004F;004F; # (𝐎; 𝐎; 𝐎; O; O; ) MATHEMATICAL BOLD CAPITAL O
+1D40F;1D40F;1D40F;0050;0050; # (𝐏; 𝐏; 𝐏; P; P; ) MATHEMATICAL BOLD CAPITAL P
+1D410;1D410;1D410;0051;0051; # (𝐐; 𝐐; 𝐐; Q; Q; ) MATHEMATICAL BOLD CAPITAL Q
+1D411;1D411;1D411;0052;0052; # (𝐑; 𝐑; 𝐑; R; R; ) MATHEMATICAL BOLD CAPITAL R
+1D412;1D412;1D412;0053;0053; # (𝐒; 𝐒; 𝐒; S; S; ) MATHEMATICAL BOLD CAPITAL S
+1D413;1D413;1D413;0054;0054; # (𝐓; 𝐓; 𝐓; T; T; ) MATHEMATICAL BOLD CAPITAL T
+1D414;1D414;1D414;0055;0055; # (𝐔; 𝐔; 𝐔; U; U; ) MATHEMATICAL BOLD CAPITAL U
+1D415;1D415;1D415;0056;0056; # (𝐕; 𝐕; 𝐕; V; V; ) MATHEMATICAL BOLD CAPITAL V
+1D416;1D416;1D416;0057;0057; # (𝐖; 𝐖; 𝐖; W; W; ) MATHEMATICAL BOLD CAPITAL W
+1D417;1D417;1D417;0058;0058; # (𝐗; 𝐗; 𝐗; X; X; ) MATHEMATICAL BOLD CAPITAL X
+1D418;1D418;1D418;0059;0059; # (𝐘; 𝐘; 𝐘; Y; Y; ) MATHEMATICAL BOLD CAPITAL Y
+1D419;1D419;1D419;005A;005A; # (𝐙; 𝐙; 𝐙; Z; Z; ) MATHEMATICAL BOLD CAPITAL Z
+1D41A;1D41A;1D41A;0061;0061; # (𝐚; 𝐚; 𝐚; a; a; ) MATHEMATICAL BOLD SMALL A
+1D41B;1D41B;1D41B;0062;0062; # (𝐛; 𝐛; 𝐛; b; b; ) MATHEMATICAL BOLD SMALL B
+1D41C;1D41C;1D41C;0063;0063; # (𝐜; 𝐜; 𝐜; c; c; ) MATHEMATICAL BOLD SMALL C
+1D41D;1D41D;1D41D;0064;0064; # (𝐝; 𝐝; 𝐝; d; d; ) MATHEMATICAL BOLD SMALL D
+1D41E;1D41E;1D41E;0065;0065; # (𝐞; 𝐞; 𝐞; e; e; ) MATHEMATICAL BOLD SMALL E
+1D41F;1D41F;1D41F;0066;0066; # (𝐟; 𝐟; 𝐟; f; f; ) MATHEMATICAL BOLD SMALL F
+1D420;1D420;1D420;0067;0067; # (𝐠; 𝐠; 𝐠; g; g; ) MATHEMATICAL BOLD SMALL G
+1D421;1D421;1D421;0068;0068; # (𝐡; 𝐡; 𝐡; h; h; ) MATHEMATICAL BOLD SMALL H
+1D422;1D422;1D422;0069;0069; # (𝐢; 𝐢; 𝐢; i; i; ) MATHEMATICAL BOLD SMALL I
+1D423;1D423;1D423;006A;006A; # (𝐣; 𝐣; 𝐣; j; j; ) MATHEMATICAL BOLD SMALL J
+1D424;1D424;1D424;006B;006B; # (𝐤; 𝐤; 𝐤; k; k; ) MATHEMATICAL BOLD SMALL K
+1D425;1D425;1D425;006C;006C; # (𝐥; 𝐥; 𝐥; l; l; ) MATHEMATICAL BOLD SMALL L
+1D426;1D426;1D426;006D;006D; # (𝐦; 𝐦; 𝐦; m; m; ) MATHEMATICAL BOLD SMALL M
+1D427;1D427;1D427;006E;006E; # (𝐧; 𝐧; 𝐧; n; n; ) MATHEMATICAL BOLD SMALL N
+1D428;1D428;1D428;006F;006F; # (𝐨; 𝐨; 𝐨; o; o; ) MATHEMATICAL BOLD SMALL O
+1D429;1D429;1D429;0070;0070; # (𝐩; 𝐩; 𝐩; p; p; ) MATHEMATICAL BOLD SMALL P
+1D42A;1D42A;1D42A;0071;0071; # (𝐪; 𝐪; 𝐪; q; q; ) MATHEMATICAL BOLD SMALL Q
+1D42B;1D42B;1D42B;0072;0072; # (𝐫; 𝐫; 𝐫; r; r; ) MATHEMATICAL BOLD SMALL R
+1D42C;1D42C;1D42C;0073;0073; # (𝐬; 𝐬; 𝐬; s; s; ) MATHEMATICAL BOLD SMALL S
+1D42D;1D42D;1D42D;0074;0074; # (𝐭; 𝐭; 𝐭; t; t; ) MATHEMATICAL BOLD SMALL T
+1D42E;1D42E;1D42E;0075;0075; # (𝐮; 𝐮; 𝐮; u; u; ) MATHEMATICAL BOLD SMALL U
+1D42F;1D42F;1D42F;0076;0076; # (𝐯; 𝐯; 𝐯; v; v; ) MATHEMATICAL BOLD SMALL V
+1D430;1D430;1D430;0077;0077; # (𝐰; 𝐰; 𝐰; w; w; ) MATHEMATICAL BOLD SMALL W
+1D431;1D431;1D431;0078;0078; # (𝐱; 𝐱; 𝐱; x; x; ) MATHEMATICAL BOLD SMALL X
+1D432;1D432;1D432;0079;0079; # (𝐲; 𝐲; 𝐲; y; y; ) MATHEMATICAL BOLD SMALL Y
+1D433;1D433;1D433;007A;007A; # (𝐳; 𝐳; 𝐳; z; z; ) MATHEMATICAL BOLD SMALL Z
+1D434;1D434;1D434;0041;0041; # (𝐴; 𝐴; 𝐴; A; A; ) MATHEMATICAL ITALIC CAPITAL A
+1D435;1D435;1D435;0042;0042; # (𝐵; 𝐵; 𝐵; B; B; ) MATHEMATICAL ITALIC CAPITAL B
+1D436;1D436;1D436;0043;0043; # (𝐶; 𝐶; 𝐶; C; C; ) MATHEMATICAL ITALIC CAPITAL C
+1D437;1D437;1D437;0044;0044; # (𝐷; 𝐷; 𝐷; D; D; ) MATHEMATICAL ITALIC CAPITAL D
+1D438;1D438;1D438;0045;0045; # (𝐸; 𝐸; 𝐸; E; E; ) MATHEMATICAL ITALIC CAPITAL E
+1D439;1D439;1D439;0046;0046; # (𝐹; 𝐹; 𝐹; F; F; ) MATHEMATICAL ITALIC CAPITAL F
+1D43A;1D43A;1D43A;0047;0047; # (𝐺; 𝐺; 𝐺; G; G; ) MATHEMATICAL ITALIC CAPITAL G
+1D43B;1D43B;1D43B;0048;0048; # (𝐻; 𝐻; 𝐻; H; H; ) MATHEMATICAL ITALIC CAPITAL H
+1D43C;1D43C;1D43C;0049;0049; # (𝐼; 𝐼; 𝐼; I; I; ) MATHEMATICAL ITALIC CAPITAL I
+1D43D;1D43D;1D43D;004A;004A; # (𝐽; 𝐽; 𝐽; J; J; ) MATHEMATICAL ITALIC CAPITAL J
+1D43E;1D43E;1D43E;004B;004B; # (𝐾; 𝐾; 𝐾; K; K; ) MATHEMATICAL ITALIC CAPITAL K
+1D43F;1D43F;1D43F;004C;004C; # (𝐿; 𝐿; 𝐿; L; L; ) MATHEMATICAL ITALIC CAPITAL L
+1D440;1D440;1D440;004D;004D; # (𝑀; 𝑀; 𝑀; M; M; ) MATHEMATICAL ITALIC CAPITAL M
+1D441;1D441;1D441;004E;004E; # (𝑁; 𝑁; 𝑁; N; N; ) MATHEMATICAL ITALIC CAPITAL N
+1D442;1D442;1D442;004F;004F; # (𝑂; 𝑂; 𝑂; O; O; ) MATHEMATICAL ITALIC CAPITAL O
+1D443;1D443;1D443;0050;0050; # (𝑃; 𝑃; 𝑃; P; P; ) MATHEMATICAL ITALIC CAPITAL P
+1D444;1D444;1D444;0051;0051; # (𝑄; 𝑄; 𝑄; Q; Q; ) MATHEMATICAL ITALIC CAPITAL Q
+1D445;1D445;1D445;0052;0052; # (𝑅; 𝑅; 𝑅; R; R; ) MATHEMATICAL ITALIC CAPITAL R
+1D446;1D446;1D446;0053;0053; # (𝑆; 𝑆; 𝑆; S; S; ) MATHEMATICAL ITALIC CAPITAL S
+1D447;1D447;1D447;0054;0054; # (𝑇; 𝑇; 𝑇; T; T; ) MATHEMATICAL ITALIC CAPITAL T
+1D448;1D448;1D448;0055;0055; # (𝑈; 𝑈; 𝑈; U; U; ) MATHEMATICAL ITALIC CAPITAL U
+1D449;1D449;1D449;0056;0056; # (𝑉; 𝑉; 𝑉; V; V; ) MATHEMATICAL ITALIC CAPITAL V
+1D44A;1D44A;1D44A;0057;0057; # (𝑊; 𝑊; 𝑊; W; W; ) MATHEMATICAL ITALIC CAPITAL W
+1D44B;1D44B;1D44B;0058;0058; # (𝑋; 𝑋; 𝑋; X; X; ) MATHEMATICAL ITALIC CAPITAL X
+1D44C;1D44C;1D44C;0059;0059; # (𝑌; 𝑌; 𝑌; Y; Y; ) MATHEMATICAL ITALIC CAPITAL Y
+1D44D;1D44D;1D44D;005A;005A; # (𝑍; 𝑍; 𝑍; Z; Z; ) MATHEMATICAL ITALIC CAPITAL Z
+1D44E;1D44E;1D44E;0061;0061; # (𝑎; 𝑎; 𝑎; a; a; ) MATHEMATICAL ITALIC SMALL A
+1D44F;1D44F;1D44F;0062;0062; # (𝑏; 𝑏; 𝑏; b; b; ) MATHEMATICAL ITALIC SMALL B
+1D450;1D450;1D450;0063;0063; # (𝑐; 𝑐; 𝑐; c; c; ) MATHEMATICAL ITALIC SMALL C
+1D451;1D451;1D451;0064;0064; # (𝑑; 𝑑; 𝑑; d; d; ) MATHEMATICAL ITALIC SMALL D
+1D452;1D452;1D452;0065;0065; # (𝑒; 𝑒; 𝑒; e; e; ) MATHEMATICAL ITALIC SMALL E
+1D453;1D453;1D453;0066;0066; # (𝑓; 𝑓; 𝑓; f; f; ) MATHEMATICAL ITALIC SMALL F
+1D454;1D454;1D454;0067;0067; # (𝑔; 𝑔; 𝑔; g; g; ) MATHEMATICAL ITALIC SMALL G
+1D456;1D456;1D456;0069;0069; # (𝑖; 𝑖; 𝑖; i; i; ) MATHEMATICAL ITALIC SMALL I
+1D457;1D457;1D457;006A;006A; # (𝑗; 𝑗; 𝑗; j; j; ) MATHEMATICAL ITALIC SMALL J
+1D458;1D458;1D458;006B;006B; # (𝑘; 𝑘; 𝑘; k; k; ) MATHEMATICAL ITALIC SMALL K
+1D459;1D459;1D459;006C;006C; # (𝑙; 𝑙; 𝑙; l; l; ) MATHEMATICAL ITALIC SMALL L
+1D45A;1D45A;1D45A;006D;006D; # (𝑚; 𝑚; 𝑚; m; m; ) MATHEMATICAL ITALIC SMALL M
+1D45B;1D45B;1D45B;006E;006E; # (𝑛; 𝑛; 𝑛; n; n; ) MATHEMATICAL ITALIC SMALL N
+1D45C;1D45C;1D45C;006F;006F; # (𝑜; 𝑜; 𝑜; o; o; ) MATHEMATICAL ITALIC SMALL O
+1D45D;1D45D;1D45D;0070;0070; # (𝑝; 𝑝; 𝑝; p; p; ) MATHEMATICAL ITALIC SMALL P
+1D45E;1D45E;1D45E;0071;0071; # (𝑞; 𝑞; 𝑞; q; q; ) MATHEMATICAL ITALIC SMALL Q
+1D45F;1D45F;1D45F;0072;0072; # (𝑟; 𝑟; 𝑟; r; r; ) MATHEMATICAL ITALIC SMALL R
+1D460;1D460;1D460;0073;0073; # (𝑠; 𝑠; 𝑠; s; s; ) MATHEMATICAL ITALIC SMALL S
+1D461;1D461;1D461;0074;0074; # (𝑡; 𝑡; 𝑡; t; t; ) MATHEMATICAL ITALIC SMALL T
+1D462;1D462;1D462;0075;0075; # (𝑢; 𝑢; 𝑢; u; u; ) MATHEMATICAL ITALIC SMALL U
+1D463;1D463;1D463;0076;0076; # (𝑣; 𝑣; 𝑣; v; v; ) MATHEMATICAL ITALIC SMALL V
+1D464;1D464;1D464;0077;0077; # (𝑤; 𝑤; 𝑤; w; w; ) MATHEMATICAL ITALIC SMALL W
+1D465;1D465;1D465;0078;0078; # (𝑥; 𝑥; 𝑥; x; x; ) MATHEMATICAL ITALIC SMALL X
+1D466;1D466;1D466;0079;0079; # (𝑦; 𝑦; 𝑦; y; y; ) MATHEMATICAL ITALIC SMALL Y
+1D467;1D467;1D467;007A;007A; # (𝑧; 𝑧; 𝑧; z; z; ) MATHEMATICAL ITALIC SMALL Z
+1D468;1D468;1D468;0041;0041; # (𝑨; 𝑨; 𝑨; A; A; ) MATHEMATICAL BOLD ITALIC CAPITAL A
+1D469;1D469;1D469;0042;0042; # (𝑩; 𝑩; 𝑩; B; B; ) MATHEMATICAL BOLD ITALIC CAPITAL B
+1D46A;1D46A;1D46A;0043;0043; # (𝑪; 𝑪; 𝑪; C; C; ) MATHEMATICAL BOLD ITALIC CAPITAL C
+1D46B;1D46B;1D46B;0044;0044; # (𝑫; 𝑫; 𝑫; D; D; ) MATHEMATICAL BOLD ITALIC CAPITAL D
+1D46C;1D46C;1D46C;0045;0045; # (𝑬; 𝑬; 𝑬; E; E; ) MATHEMATICAL BOLD ITALIC CAPITAL E
+1D46D;1D46D;1D46D;0046;0046; # (𝑭; 𝑭; 𝑭; F; F; ) MATHEMATICAL BOLD ITALIC CAPITAL F
+1D46E;1D46E;1D46E;0047;0047; # (𝑮; 𝑮; 𝑮; G; G; ) MATHEMATICAL BOLD ITALIC CAPITAL G
+1D46F;1D46F;1D46F;0048;0048; # (𝑯; 𝑯; 𝑯; H; H; ) MATHEMATICAL BOLD ITALIC CAPITAL H
+1D470;1D470;1D470;0049;0049; # (𝑰; 𝑰; 𝑰; I; I; ) MATHEMATICAL BOLD ITALIC CAPITAL I
+1D471;1D471;1D471;004A;004A; # (𝑱; 𝑱; 𝑱; J; J; ) MATHEMATICAL BOLD ITALIC CAPITAL J
+1D472;1D472;1D472;004B;004B; # (𝑲; 𝑲; 𝑲; K; K; ) MATHEMATICAL BOLD ITALIC CAPITAL K
+1D473;1D473;1D473;004C;004C; # (𝑳; 𝑳; 𝑳; L; L; ) MATHEMATICAL BOLD ITALIC CAPITAL L
+1D474;1D474;1D474;004D;004D; # (𝑴; 𝑴; 𝑴; M; M; ) MATHEMATICAL BOLD ITALIC CAPITAL M
+1D475;1D475;1D475;004E;004E; # (𝑵; 𝑵; 𝑵; N; N; ) MATHEMATICAL BOLD ITALIC CAPITAL N
+1D476;1D476;1D476;004F;004F; # (𝑶; 𝑶; 𝑶; O; O; ) MATHEMATICAL BOLD ITALIC CAPITAL O
+1D477;1D477;1D477;0050;0050; # (𝑷; 𝑷; 𝑷; P; P; ) MATHEMATICAL BOLD ITALIC CAPITAL P
+1D478;1D478;1D478;0051;0051; # (𝑸; 𝑸; 𝑸; Q; Q; ) MATHEMATICAL BOLD ITALIC CAPITAL Q
+1D479;1D479;1D479;0052;0052; # (𝑹; 𝑹; 𝑹; R; R; ) MATHEMATICAL BOLD ITALIC CAPITAL R
+1D47A;1D47A;1D47A;0053;0053; # (𝑺; 𝑺; 𝑺; S; S; ) MATHEMATICAL BOLD ITALIC CAPITAL S
+1D47B;1D47B;1D47B;0054;0054; # (𝑻; 𝑻; 𝑻; T; T; ) MATHEMATICAL BOLD ITALIC CAPITAL T
+1D47C;1D47C;1D47C;0055;0055; # (𝑼; 𝑼; 𝑼; U; U; ) MATHEMATICAL BOLD ITALIC CAPITAL U
+1D47D;1D47D;1D47D;0056;0056; # (𝑽; 𝑽; 𝑽; V; V; ) MATHEMATICAL BOLD ITALIC CAPITAL V
+1D47E;1D47E;1D47E;0057;0057; # (𝑾; 𝑾; 𝑾; W; W; ) MATHEMATICAL BOLD ITALIC CAPITAL W
+1D47F;1D47F;1D47F;0058;0058; # (𝑿; 𝑿; 𝑿; X; X; ) MATHEMATICAL BOLD ITALIC CAPITAL X
+1D480;1D480;1D480;0059;0059; # (𝒀; 𝒀; 𝒀; Y; Y; ) MATHEMATICAL BOLD ITALIC CAPITAL Y
+1D481;1D481;1D481;005A;005A; # (𝒁; 𝒁; 𝒁; Z; Z; ) MATHEMATICAL BOLD ITALIC CAPITAL Z
+1D482;1D482;1D482;0061;0061; # (𝒂; 𝒂; 𝒂; a; a; ) MATHEMATICAL BOLD ITALIC SMALL A
+1D483;1D483;1D483;0062;0062; # (𝒃; 𝒃; 𝒃; b; b; ) MATHEMATICAL BOLD ITALIC SMALL B
+1D484;1D484;1D484;0063;0063; # (𝒄; 𝒄; 𝒄; c; c; ) MATHEMATICAL BOLD ITALIC SMALL C
+1D485;1D485;1D485;0064;0064; # (𝒅; 𝒅; 𝒅; d; d; ) MATHEMATICAL BOLD ITALIC SMALL D
+1D486;1D486;1D486;0065;0065; # (𝒆; 𝒆; 𝒆; e; e; ) MATHEMATICAL BOLD ITALIC SMALL E
+1D487;1D487;1D487;0066;0066; # (𝒇; 𝒇; 𝒇; f; f; ) MATHEMATICAL BOLD ITALIC SMALL F
+1D488;1D488;1D488;0067;0067; # (𝒈; 𝒈; 𝒈; g; g; ) MATHEMATICAL BOLD ITALIC SMALL G
+1D489;1D489;1D489;0068;0068; # (𝒉; 𝒉; 𝒉; h; h; ) MATHEMATICAL BOLD ITALIC SMALL H
+1D48A;1D48A;1D48A;0069;0069; # (𝒊; 𝒊; 𝒊; i; i; ) MATHEMATICAL BOLD ITALIC SMALL I
+1D48B;1D48B;1D48B;006A;006A; # (𝒋; 𝒋; 𝒋; j; j; ) MATHEMATICAL BOLD ITALIC SMALL J
+1D48C;1D48C;1D48C;006B;006B; # (𝒌; 𝒌; 𝒌; k; k; ) MATHEMATICAL BOLD ITALIC SMALL K
+1D48D;1D48D;1D48D;006C;006C; # (𝒍; 𝒍; 𝒍; l; l; ) MATHEMATICAL BOLD ITALIC SMALL L
+1D48E;1D48E;1D48E;006D;006D; # (𝒎; 𝒎; 𝒎; m; m; ) MATHEMATICAL BOLD ITALIC SMALL M
+1D48F;1D48F;1D48F;006E;006E; # (𝒏; 𝒏; 𝒏; n; n; ) MATHEMATICAL BOLD ITALIC SMALL N
+1D490;1D490;1D490;006F;006F; # (𝒐; 𝒐; 𝒐; o; o; ) MATHEMATICAL BOLD ITALIC SMALL O
+1D491;1D491;1D491;0070;0070; # (𝒑; 𝒑; 𝒑; p; p; ) MATHEMATICAL BOLD ITALIC SMALL P
+1D492;1D492;1D492;0071;0071; # (𝒒; 𝒒; 𝒒; q; q; ) MATHEMATICAL BOLD ITALIC SMALL Q
+1D493;1D493;1D493;0072;0072; # (𝒓; 𝒓; 𝒓; r; r; ) MATHEMATICAL BOLD ITALIC SMALL R
+1D494;1D494;1D494;0073;0073; # (𝒔; 𝒔; 𝒔; s; s; ) MATHEMATICAL BOLD ITALIC SMALL S
+1D495;1D495;1D495;0074;0074; # (𝒕; 𝒕; 𝒕; t; t; ) MATHEMATICAL BOLD ITALIC SMALL T
+1D496;1D496;1D496;0075;0075; # (𝒖; 𝒖; 𝒖; u; u; ) MATHEMATICAL BOLD ITALIC SMALL U
+1D497;1D497;1D497;0076;0076; # (𝒗; 𝒗; 𝒗; v; v; ) MATHEMATICAL BOLD ITALIC SMALL V
+1D498;1D498;1D498;0077;0077; # (𝒘; 𝒘; 𝒘; w; w; ) MATHEMATICAL BOLD ITALIC SMALL W
+1D499;1D499;1D499;0078;0078; # (𝒙; 𝒙; 𝒙; x; x; ) MATHEMATICAL BOLD ITALIC SMALL X
+1D49A;1D49A;1D49A;0079;0079; # (𝒚; 𝒚; 𝒚; y; y; ) MATHEMATICAL BOLD ITALIC SMALL Y
+1D49B;1D49B;1D49B;007A;007A; # (𝒛; 𝒛; 𝒛; z; z; ) MATHEMATICAL BOLD ITALIC SMALL Z
+1D49C;1D49C;1D49C;0041;0041; # (𝒜; 𝒜; 𝒜; A; A; ) MATHEMATICAL SCRIPT CAPITAL A
+1D49E;1D49E;1D49E;0043;0043; # (𝒞; 𝒞; 𝒞; C; C; ) MATHEMATICAL SCRIPT CAPITAL C
+1D49F;1D49F;1D49F;0044;0044; # (𝒟; 𝒟; 𝒟; D; D; ) MATHEMATICAL SCRIPT CAPITAL D
+1D4A2;1D4A2;1D4A2;0047;0047; # (𝒢; 𝒢; 𝒢; G; G; ) MATHEMATICAL SCRIPT CAPITAL G
+1D4A5;1D4A5;1D4A5;004A;004A; # (𝒥; 𝒥; 𝒥; J; J; ) MATHEMATICAL SCRIPT CAPITAL J
+1D4A6;1D4A6;1D4A6;004B;004B; # (𝒦; 𝒦; 𝒦; K; K; ) MATHEMATICAL SCRIPT CAPITAL K
+1D4A9;1D4A9;1D4A9;004E;004E; # (𝒩; 𝒩; 𝒩; N; N; ) MATHEMATICAL SCRIPT CAPITAL N
+1D4AA;1D4AA;1D4AA;004F;004F; # (𝒪; 𝒪; 𝒪; O; O; ) MATHEMATICAL SCRIPT CAPITAL O
+1D4AB;1D4AB;1D4AB;0050;0050; # (𝒫; 𝒫; 𝒫; P; P; ) MATHEMATICAL SCRIPT CAPITAL P
+1D4AC;1D4AC;1D4AC;0051;0051; # (𝒬; 𝒬; 𝒬; Q; Q; ) MATHEMATICAL SCRIPT CAPITAL Q
+1D4AE;1D4AE;1D4AE;0053;0053; # (𝒮; 𝒮; 𝒮; S; S; ) MATHEMATICAL SCRIPT CAPITAL S
+1D4AF;1D4AF;1D4AF;0054;0054; # (𝒯; 𝒯; 𝒯; T; T; ) MATHEMATICAL SCRIPT CAPITAL T
+1D4B0;1D4B0;1D4B0;0055;0055; # (𝒰; 𝒰; 𝒰; U; U; ) MATHEMATICAL SCRIPT CAPITAL U
+1D4B1;1D4B1;1D4B1;0056;0056; # (𝒱; 𝒱; 𝒱; V; V; ) MATHEMATICAL SCRIPT CAPITAL V
+1D4B2;1D4B2;1D4B2;0057;0057; # (𝒲; 𝒲; 𝒲; W; W; ) MATHEMATICAL SCRIPT CAPITAL W
+1D4B3;1D4B3;1D4B3;0058;0058; # (𝒳; 𝒳; 𝒳; X; X; ) MATHEMATICAL SCRIPT CAPITAL X
+1D4B4;1D4B4;1D4B4;0059;0059; # (𝒴; 𝒴; 𝒴; Y; Y; ) MATHEMATICAL SCRIPT CAPITAL Y
+1D4B5;1D4B5;1D4B5;005A;005A; # (𝒵; 𝒵; 𝒵; Z; Z; ) MATHEMATICAL SCRIPT CAPITAL Z
+1D4B6;1D4B6;1D4B6;0061;0061; # (𝒶; 𝒶; 𝒶; a; a; ) MATHEMATICAL SCRIPT SMALL A
+1D4B7;1D4B7;1D4B7;0062;0062; # (𝒷; 𝒷; 𝒷; b; b; ) MATHEMATICAL SCRIPT SMALL B
+1D4B8;1D4B8;1D4B8;0063;0063; # (𝒸; 𝒸; 𝒸; c; c; ) MATHEMATICAL SCRIPT SMALL C
+1D4B9;1D4B9;1D4B9;0064;0064; # (𝒹; 𝒹; 𝒹; d; d; ) MATHEMATICAL SCRIPT SMALL D
+1D4BB;1D4BB;1D4BB;0066;0066; # (𝒻; 𝒻; 𝒻; f; f; ) MATHEMATICAL SCRIPT SMALL F
+1D4BD;1D4BD;1D4BD;0068;0068; # (𝒽; 𝒽; 𝒽; h; h; ) MATHEMATICAL SCRIPT SMALL H
+1D4BE;1D4BE;1D4BE;0069;0069; # (𝒾; 𝒾; 𝒾; i; i; ) MATHEMATICAL SCRIPT SMALL I
+1D4BF;1D4BF;1D4BF;006A;006A; # (𝒿; 𝒿; 𝒿; j; j; ) MATHEMATICAL SCRIPT SMALL J
+1D4C0;1D4C0;1D4C0;006B;006B; # (𝓀; 𝓀; 𝓀; k; k; ) MATHEMATICAL SCRIPT SMALL K
+1D4C1;1D4C1;1D4C1;006C;006C; # (𝓁; 𝓁; 𝓁; l; l; ) MATHEMATICAL SCRIPT SMALL L
+1D4C2;1D4C2;1D4C2;006D;006D; # (𝓂; 𝓂; 𝓂; m; m; ) MATHEMATICAL SCRIPT SMALL M
+1D4C3;1D4C3;1D4C3;006E;006E; # (𝓃; 𝓃; 𝓃; n; n; ) MATHEMATICAL SCRIPT SMALL N
+1D4C5;1D4C5;1D4C5;0070;0070; # (𝓅; 𝓅; 𝓅; p; p; ) MATHEMATICAL SCRIPT SMALL P
+1D4C6;1D4C6;1D4C6;0071;0071; # (𝓆; 𝓆; 𝓆; q; q; ) MATHEMATICAL SCRIPT SMALL Q
+1D4C7;1D4C7;1D4C7;0072;0072; # (𝓇; 𝓇; 𝓇; r; r; ) MATHEMATICAL SCRIPT SMALL R
+1D4C8;1D4C8;1D4C8;0073;0073; # (𝓈; 𝓈; 𝓈; s; s; ) MATHEMATICAL SCRIPT SMALL S
+1D4C9;1D4C9;1D4C9;0074;0074; # (𝓉; 𝓉; 𝓉; t; t; ) MATHEMATICAL SCRIPT SMALL T
+1D4CA;1D4CA;1D4CA;0075;0075; # (𝓊; 𝓊; 𝓊; u; u; ) MATHEMATICAL SCRIPT SMALL U
+1D4CB;1D4CB;1D4CB;0076;0076; # (𝓋; 𝓋; 𝓋; v; v; ) MATHEMATICAL SCRIPT SMALL V
+1D4CC;1D4CC;1D4CC;0077;0077; # (𝓌; 𝓌; 𝓌; w; w; ) MATHEMATICAL SCRIPT SMALL W
+1D4CD;1D4CD;1D4CD;0078;0078; # (𝓍; 𝓍; 𝓍; x; x; ) MATHEMATICAL SCRIPT SMALL X
+1D4CE;1D4CE;1D4CE;0079;0079; # (𝓎; 𝓎; 𝓎; y; y; ) MATHEMATICAL SCRIPT SMALL Y
+1D4CF;1D4CF;1D4CF;007A;007A; # (𝓏; 𝓏; 𝓏; z; z; ) MATHEMATICAL SCRIPT SMALL Z
+1D4D0;1D4D0;1D4D0;0041;0041; # (𝓐; 𝓐; 𝓐; A; A; ) MATHEMATICAL BOLD SCRIPT CAPITAL A
+1D4D1;1D4D1;1D4D1;0042;0042; # (𝓑; 𝓑; 𝓑; B; B; ) MATHEMATICAL BOLD SCRIPT CAPITAL B
+1D4D2;1D4D2;1D4D2;0043;0043; # (𝓒; 𝓒; 𝓒; C; C; ) MATHEMATICAL BOLD SCRIPT CAPITAL C
+1D4D3;1D4D3;1D4D3;0044;0044; # (𝓓; 𝓓; 𝓓; D; D; ) MATHEMATICAL BOLD SCRIPT CAPITAL D
+1D4D4;1D4D4;1D4D4;0045;0045; # (𝓔; 𝓔; 𝓔; E; E; ) MATHEMATICAL BOLD SCRIPT CAPITAL E
+1D4D5;1D4D5;1D4D5;0046;0046; # (𝓕; 𝓕; 𝓕; F; F; ) MATHEMATICAL BOLD SCRIPT CAPITAL F
+1D4D6;1D4D6;1D4D6;0047;0047; # (𝓖; 𝓖; 𝓖; G; G; ) MATHEMATICAL BOLD SCRIPT CAPITAL G
+1D4D7;1D4D7;1D4D7;0048;0048; # (𝓗; 𝓗; 𝓗; H; H; ) MATHEMATICAL BOLD SCRIPT CAPITAL H
+1D4D8;1D4D8;1D4D8;0049;0049; # (𝓘; 𝓘; 𝓘; I; I; ) MATHEMATICAL BOLD SCRIPT CAPITAL I
+1D4D9;1D4D9;1D4D9;004A;004A; # (𝓙; 𝓙; 𝓙; J; J; ) MATHEMATICAL BOLD SCRIPT CAPITAL J
+1D4DA;1D4DA;1D4DA;004B;004B; # (𝓚; 𝓚; 𝓚; K; K; ) MATHEMATICAL BOLD SCRIPT CAPITAL K
+1D4DB;1D4DB;1D4DB;004C;004C; # (𝓛; 𝓛; 𝓛; L; L; ) MATHEMATICAL BOLD SCRIPT CAPITAL L
+1D4DC;1D4DC;1D4DC;004D;004D; # (𝓜; 𝓜; 𝓜; M; M; ) MATHEMATICAL BOLD SCRIPT CAPITAL M
+1D4DD;1D4DD;1D4DD;004E;004E; # (𝓝; 𝓝; 𝓝; N; N; ) MATHEMATICAL BOLD SCRIPT CAPITAL N
+1D4DE;1D4DE;1D4DE;004F;004F; # (𝓞; 𝓞; 𝓞; O; O; ) MATHEMATICAL BOLD SCRIPT CAPITAL O
+1D4DF;1D4DF;1D4DF;0050;0050; # (𝓟; 𝓟; 𝓟; P; P; ) MATHEMATICAL BOLD SCRIPT CAPITAL P
+1D4E0;1D4E0;1D4E0;0051;0051; # (𝓠; 𝓠; 𝓠; Q; Q; ) MATHEMATICAL BOLD SCRIPT CAPITAL Q
+1D4E1;1D4E1;1D4E1;0052;0052; # (𝓡; 𝓡; 𝓡; R; R; ) MATHEMATICAL BOLD SCRIPT CAPITAL R
+1D4E2;1D4E2;1D4E2;0053;0053; # (𝓢; 𝓢; 𝓢; S; S; ) MATHEMATICAL BOLD SCRIPT CAPITAL S
+1D4E3;1D4E3;1D4E3;0054;0054; # (𝓣; 𝓣; 𝓣; T; T; ) MATHEMATICAL BOLD SCRIPT CAPITAL T
+1D4E4;1D4E4;1D4E4;0055;0055; # (𝓤; 𝓤; 𝓤; U; U; ) MATHEMATICAL BOLD SCRIPT CAPITAL U
+1D4E5;1D4E5;1D4E5;0056;0056; # (𝓥; 𝓥; 𝓥; V; V; ) MATHEMATICAL BOLD SCRIPT CAPITAL V
+1D4E6;1D4E6;1D4E6;0057;0057; # (𝓦; 𝓦; 𝓦; W; W; ) MATHEMATICAL BOLD SCRIPT CAPITAL W
+1D4E7;1D4E7;1D4E7;0058;0058; # (𝓧; 𝓧; 𝓧; X; X; ) MATHEMATICAL BOLD SCRIPT CAPITAL X
+1D4E8;1D4E8;1D4E8;0059;0059; # (𝓨; 𝓨; 𝓨; Y; Y; ) MATHEMATICAL BOLD SCRIPT CAPITAL Y
+1D4E9;1D4E9;1D4E9;005A;005A; # (𝓩; 𝓩; 𝓩; Z; Z; ) MATHEMATICAL BOLD SCRIPT CAPITAL Z
+1D4EA;1D4EA;1D4EA;0061;0061; # (𝓪; 𝓪; 𝓪; a; a; ) MATHEMATICAL BOLD SCRIPT SMALL A
+1D4EB;1D4EB;1D4EB;0062;0062; # (𝓫; 𝓫; 𝓫; b; b; ) MATHEMATICAL BOLD SCRIPT SMALL B
+1D4EC;1D4EC;1D4EC;0063;0063; # (𝓬; 𝓬; 𝓬; c; c; ) MATHEMATICAL BOLD SCRIPT SMALL C
+1D4ED;1D4ED;1D4ED;0064;0064; # (𝓭; 𝓭; 𝓭; d; d; ) MATHEMATICAL BOLD SCRIPT SMALL D
+1D4EE;1D4EE;1D4EE;0065;0065; # (𝓮; 𝓮; 𝓮; e; e; ) MATHEMATICAL BOLD SCRIPT SMALL E
+1D4EF;1D4EF;1D4EF;0066;0066; # (𝓯; 𝓯; 𝓯; f; f; ) MATHEMATICAL BOLD SCRIPT SMALL F
+1D4F0;1D4F0;1D4F0;0067;0067; # (𝓰; 𝓰; 𝓰; g; g; ) MATHEMATICAL BOLD SCRIPT SMALL G
+1D4F1;1D4F1;1D4F1;0068;0068; # (𝓱; 𝓱; 𝓱; h; h; ) MATHEMATICAL BOLD SCRIPT SMALL H
+1D4F2;1D4F2;1D4F2;0069;0069; # (𝓲; 𝓲; 𝓲; i; i; ) MATHEMATICAL BOLD SCRIPT SMALL I
+1D4F3;1D4F3;1D4F3;006A;006A; # (𝓳; 𝓳; 𝓳; j; j; ) MATHEMATICAL BOLD SCRIPT SMALL J
+1D4F4;1D4F4;1D4F4;006B;006B; # (𝓴; 𝓴; 𝓴; k; k; ) MATHEMATICAL BOLD SCRIPT SMALL K
+1D4F5;1D4F5;1D4F5;006C;006C; # (𝓵; 𝓵; 𝓵; l; l; ) MATHEMATICAL BOLD SCRIPT SMALL L
+1D4F6;1D4F6;1D4F6;006D;006D; # (𝓶; 𝓶; 𝓶; m; m; ) MATHEMATICAL BOLD SCRIPT SMALL M
+1D4F7;1D4F7;1D4F7;006E;006E; # (𝓷; 𝓷; 𝓷; n; n; ) MATHEMATICAL BOLD SCRIPT SMALL N
+1D4F8;1D4F8;1D4F8;006F;006F; # (𝓸; 𝓸; 𝓸; o; o; ) MATHEMATICAL BOLD SCRIPT SMALL O
+1D4F9;1D4F9;1D4F9;0070;0070; # (𝓹; 𝓹; 𝓹; p; p; ) MATHEMATICAL BOLD SCRIPT SMALL P
+1D4FA;1D4FA;1D4FA;0071;0071; # (𝓺; 𝓺; 𝓺; q; q; ) MATHEMATICAL BOLD SCRIPT SMALL Q
+1D4FB;1D4FB;1D4FB;0072;0072; # (𝓻; 𝓻; 𝓻; r; r; ) MATHEMATICAL BOLD SCRIPT SMALL R
+1D4FC;1D4FC;1D4FC;0073;0073; # (𝓼; 𝓼; 𝓼; s; s; ) MATHEMATICAL BOLD SCRIPT SMALL S
+1D4FD;1D4FD;1D4FD;0074;0074; # (𝓽; 𝓽; 𝓽; t; t; ) MATHEMATICAL BOLD SCRIPT SMALL T
+1D4FE;1D4FE;1D4FE;0075;0075; # (𝓾; 𝓾; 𝓾; u; u; ) MATHEMATICAL BOLD SCRIPT SMALL U
+1D4FF;1D4FF;1D4FF;0076;0076; # (𝓿; 𝓿; 𝓿; v; v; ) MATHEMATICAL BOLD SCRIPT SMALL V
+1D500;1D500;1D500;0077;0077; # (𝔀; 𝔀; 𝔀; w; w; ) MATHEMATICAL BOLD SCRIPT SMALL W
+1D501;1D501;1D501;0078;0078; # (𝔁; 𝔁; 𝔁; x; x; ) MATHEMATICAL BOLD SCRIPT SMALL X
+1D502;1D502;1D502;0079;0079; # (𝔂; 𝔂; 𝔂; y; y; ) MATHEMATICAL BOLD SCRIPT SMALL Y
+1D503;1D503;1D503;007A;007A; # (𝔃; 𝔃; 𝔃; z; z; ) MATHEMATICAL BOLD SCRIPT SMALL Z
+1D504;1D504;1D504;0041;0041; # (𝔄; 𝔄; 𝔄; A; A; ) MATHEMATICAL FRAKTUR CAPITAL A
+1D505;1D505;1D505;0042;0042; # (𝔅; 𝔅; 𝔅; B; B; ) MATHEMATICAL FRAKTUR CAPITAL B
+1D507;1D507;1D507;0044;0044; # (𝔇; 𝔇; 𝔇; D; D; ) MATHEMATICAL FRAKTUR CAPITAL D
+1D508;1D508;1D508;0045;0045; # (𝔈; 𝔈; 𝔈; E; E; ) MATHEMATICAL FRAKTUR CAPITAL E
+1D509;1D509;1D509;0046;0046; # (𝔉; 𝔉; 𝔉; F; F; ) MATHEMATICAL FRAKTUR CAPITAL F
+1D50A;1D50A;1D50A;0047;0047; # (𝔊; 𝔊; 𝔊; G; G; ) MATHEMATICAL FRAKTUR CAPITAL G
+1D50D;1D50D;1D50D;004A;004A; # (𝔍; 𝔍; 𝔍; J; J; ) MATHEMATICAL FRAKTUR CAPITAL J
+1D50E;1D50E;1D50E;004B;004B; # (𝔎; 𝔎; 𝔎; K; K; ) MATHEMATICAL FRAKTUR CAPITAL K
+1D50F;1D50F;1D50F;004C;004C; # (𝔏; 𝔏; 𝔏; L; L; ) MATHEMATICAL FRAKTUR CAPITAL L
+1D510;1D510;1D510;004D;004D; # (𝔐; 𝔐; 𝔐; M; M; ) MATHEMATICAL FRAKTUR CAPITAL M
+1D511;1D511;1D511;004E;004E; # (𝔑; 𝔑; 𝔑; N; N; ) MATHEMATICAL FRAKTUR CAPITAL N
+1D512;1D512;1D512;004F;004F; # (𝔒; 𝔒; 𝔒; O; O; ) MATHEMATICAL FRAKTUR CAPITAL O
+1D513;1D513;1D513;0050;0050; # (𝔓; 𝔓; 𝔓; P; P; ) MATHEMATICAL FRAKTUR CAPITAL P
+1D514;1D514;1D514;0051;0051; # (𝔔; 𝔔; 𝔔; Q; Q; ) MATHEMATICAL FRAKTUR CAPITAL Q
+1D516;1D516;1D516;0053;0053; # (𝔖; 𝔖; 𝔖; S; S; ) MATHEMATICAL FRAKTUR CAPITAL S
+1D517;1D517;1D517;0054;0054; # (𝔗; 𝔗; 𝔗; T; T; ) MATHEMATICAL FRAKTUR CAPITAL T
+1D518;1D518;1D518;0055;0055; # (𝔘; 𝔘; 𝔘; U; U; ) MATHEMATICAL FRAKTUR CAPITAL U
+1D519;1D519;1D519;0056;0056; # (𝔙; 𝔙; 𝔙; V; V; ) MATHEMATICAL FRAKTUR CAPITAL V
+1D51A;1D51A;1D51A;0057;0057; # (𝔚; 𝔚; 𝔚; W; W; ) MATHEMATICAL FRAKTUR CAPITAL W
+1D51B;1D51B;1D51B;0058;0058; # (𝔛; 𝔛; 𝔛; X; X; ) MATHEMATICAL FRAKTUR CAPITAL X
+1D51C;1D51C;1D51C;0059;0059; # (𝔜; 𝔜; 𝔜; Y; Y; ) MATHEMATICAL FRAKTUR CAPITAL Y
+1D51E;1D51E;1D51E;0061;0061; # (𝔞; 𝔞; 𝔞; a; a; ) MATHEMATICAL FRAKTUR SMALL A
+1D51F;1D51F;1D51F;0062;0062; # (𝔟; 𝔟; 𝔟; b; b; ) MATHEMATICAL FRAKTUR SMALL B
+1D520;1D520;1D520;0063;0063; # (𝔠; 𝔠; 𝔠; c; c; ) MATHEMATICAL FRAKTUR SMALL C
+1D521;1D521;1D521;0064;0064; # (𝔡; 𝔡; 𝔡; d; d; ) MATHEMATICAL FRAKTUR SMALL D
+1D522;1D522;1D522;0065;0065; # (𝔢; 𝔢; 𝔢; e; e; ) MATHEMATICAL FRAKTUR SMALL E
+1D523;1D523;1D523;0066;0066; # (𝔣; 𝔣; 𝔣; f; f; ) MATHEMATICAL FRAKTUR SMALL F
+1D524;1D524;1D524;0067;0067; # (𝔤; 𝔤; 𝔤; g; g; ) MATHEMATICAL FRAKTUR SMALL G
+1D525;1D525;1D525;0068;0068; # (𝔥; 𝔥; 𝔥; h; h; ) MATHEMATICAL FRAKTUR SMALL H
+1D526;1D526;1D526;0069;0069; # (𝔦; 𝔦; 𝔦; i; i; ) MATHEMATICAL FRAKTUR SMALL I
+1D527;1D527;1D527;006A;006A; # (𝔧; 𝔧; 𝔧; j; j; ) MATHEMATICAL FRAKTUR SMALL J
+1D528;1D528;1D528;006B;006B; # (𝔨; 𝔨; 𝔨; k; k; ) MATHEMATICAL FRAKTUR SMALL K
+1D529;1D529;1D529;006C;006C; # (𝔩; 𝔩; 𝔩; l; l; ) MATHEMATICAL FRAKTUR SMALL L
+1D52A;1D52A;1D52A;006D;006D; # (𝔪; 𝔪; 𝔪; m; m; ) MATHEMATICAL FRAKTUR SMALL M
+1D52B;1D52B;1D52B;006E;006E; # (𝔫; 𝔫; 𝔫; n; n; ) MATHEMATICAL FRAKTUR SMALL N
+1D52C;1D52C;1D52C;006F;006F; # (𝔬; 𝔬; 𝔬; o; o; ) MATHEMATICAL FRAKTUR SMALL O
+1D52D;1D52D;1D52D;0070;0070; # (𝔭; 𝔭; 𝔭; p; p; ) MATHEMATICAL FRAKTUR SMALL P
+1D52E;1D52E;1D52E;0071;0071; # (𝔮; 𝔮; 𝔮; q; q; ) MATHEMATICAL FRAKTUR SMALL Q
+1D52F;1D52F;1D52F;0072;0072; # (𝔯; 𝔯; 𝔯; r; r; ) MATHEMATICAL FRAKTUR SMALL R
+1D530;1D530;1D530;0073;0073; # (𝔰; 𝔰; 𝔰; s; s; ) MATHEMATICAL FRAKTUR SMALL S
+1D531;1D531;1D531;0074;0074; # (𝔱; 𝔱; 𝔱; t; t; ) MATHEMATICAL FRAKTUR SMALL T
+1D532;1D532;1D532;0075;0075; # (𝔲; 𝔲; 𝔲; u; u; ) MATHEMATICAL FRAKTUR SMALL U
+1D533;1D533;1D533;0076;0076; # (𝔳; 𝔳; 𝔳; v; v; ) MATHEMATICAL FRAKTUR SMALL V
+1D534;1D534;1D534;0077;0077; # (𝔴; 𝔴; 𝔴; w; w; ) MATHEMATICAL FRAKTUR SMALL W
+1D535;1D535;1D535;0078;0078; # (𝔵; 𝔵; 𝔵; x; x; ) MATHEMATICAL FRAKTUR SMALL X
+1D536;1D536;1D536;0079;0079; # (𝔶; 𝔶; 𝔶; y; y; ) MATHEMATICAL FRAKTUR SMALL Y
+1D537;1D537;1D537;007A;007A; # (𝔷; 𝔷; 𝔷; z; z; ) MATHEMATICAL FRAKTUR SMALL Z
+1D538;1D538;1D538;0041;0041; # (𝔸; 𝔸; 𝔸; A; A; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL A
+1D539;1D539;1D539;0042;0042; # (𝔹; 𝔹; 𝔹; B; B; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL B
+1D53B;1D53B;1D53B;0044;0044; # (𝔻; 𝔻; 𝔻; D; D; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL D
+1D53C;1D53C;1D53C;0045;0045; # (𝔼; 𝔼; 𝔼; E; E; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL E
+1D53D;1D53D;1D53D;0046;0046; # (𝔽; 𝔽; 𝔽; F; F; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL F
+1D53E;1D53E;1D53E;0047;0047; # (𝔾; 𝔾; 𝔾; G; G; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL G
+1D540;1D540;1D540;0049;0049; # (𝕀; 𝕀; 𝕀; I; I; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL I
+1D541;1D541;1D541;004A;004A; # (𝕁; 𝕁; 𝕁; J; J; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL J
+1D542;1D542;1D542;004B;004B; # (𝕂; 𝕂; 𝕂; K; K; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL K
+1D543;1D543;1D543;004C;004C; # (𝕃; 𝕃; 𝕃; L; L; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL L
+1D544;1D544;1D544;004D;004D; # (𝕄; 𝕄; 𝕄; M; M; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL M
+1D546;1D546;1D546;004F;004F; # (𝕆; 𝕆; 𝕆; O; O; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL O
+1D54A;1D54A;1D54A;0053;0053; # (𝕊; 𝕊; 𝕊; S; S; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL S
+1D54B;1D54B;1D54B;0054;0054; # (𝕋; 𝕋; 𝕋; T; T; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL T
+1D54C;1D54C;1D54C;0055;0055; # (𝕌; 𝕌; 𝕌; U; U; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL U
+1D54D;1D54D;1D54D;0056;0056; # (𝕍; 𝕍; 𝕍; V; V; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL V
+1D54E;1D54E;1D54E;0057;0057; # (𝕎; 𝕎; 𝕎; W; W; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL W
+1D54F;1D54F;1D54F;0058;0058; # (𝕏; 𝕏; 𝕏; X; X; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL X
+1D550;1D550;1D550;0059;0059; # (𝕐; 𝕐; 𝕐; Y; Y; ) MATHEMATICAL DOUBLE-STRUCK CAPITAL Y
+1D552;1D552;1D552;0061;0061; # (𝕒; 𝕒; 𝕒; a; a; ) MATHEMATICAL DOUBLE-STRUCK SMALL A
+1D553;1D553;1D553;0062;0062; # (𝕓; 𝕓; 𝕓; b; b; ) MATHEMATICAL DOUBLE-STRUCK SMALL B
+1D554;1D554;1D554;0063;0063; # (𝕔; 𝕔; 𝕔; c; c; ) MATHEMATICAL DOUBLE-STRUCK SMALL C
+1D555;1D555;1D555;0064;0064; # (𝕕; 𝕕; 𝕕; d; d; ) MATHEMATICAL DOUBLE-STRUCK SMALL D
+1D556;1D556;1D556;0065;0065; # (𝕖; 𝕖; 𝕖; e; e; ) MATHEMATICAL DOUBLE-STRUCK SMALL E
+1D557;1D557;1D557;0066;0066; # (𝕗; 𝕗; 𝕗; f; f; ) MATHEMATICAL DOUBLE-STRUCK SMALL F
+1D558;1D558;1D558;0067;0067; # (𝕘; 𝕘; 𝕘; g; g; ) MATHEMATICAL DOUBLE-STRUCK SMALL G
+1D559;1D559;1D559;0068;0068; # (𝕙; 𝕙; 𝕙; h; h; ) MATHEMATICAL DOUBLE-STRUCK SMALL H
+1D55A;1D55A;1D55A;0069;0069; # (𝕚; 𝕚; 𝕚; i; i; ) MATHEMATICAL DOUBLE-STRUCK SMALL I
+1D55B;1D55B;1D55B;006A;006A; # (𝕛; 𝕛; 𝕛; j; j; ) MATHEMATICAL DOUBLE-STRUCK SMALL J
+1D55C;1D55C;1D55C;006B;006B; # (𝕜; 𝕜; 𝕜; k; k; ) MATHEMATICAL DOUBLE-STRUCK SMALL K
+1D55D;1D55D;1D55D;006C;006C; # (𝕝; 𝕝; 𝕝; l; l; ) MATHEMATICAL DOUBLE-STRUCK SMALL L
+1D55E;1D55E;1D55E;006D;006D; # (𝕞; 𝕞; 𝕞; m; m; ) MATHEMATICAL DOUBLE-STRUCK SMALL M
+1D55F;1D55F;1D55F;006E;006E; # (𝕟; 𝕟; 𝕟; n; n; ) MATHEMATICAL DOUBLE-STRUCK SMALL N
+1D560;1D560;1D560;006F;006F; # (𝕠; 𝕠; 𝕠; o; o; ) MATHEMATICAL DOUBLE-STRUCK SMALL O
+1D561;1D561;1D561;0070;0070; # (𝕡; 𝕡; 𝕡; p; p; ) MATHEMATICAL DOUBLE-STRUCK SMALL P
+1D562;1D562;1D562;0071;0071; # (𝕢; 𝕢; 𝕢; q; q; ) MATHEMATICAL DOUBLE-STRUCK SMALL Q
+1D563;1D563;1D563;0072;0072; # (𝕣; 𝕣; 𝕣; r; r; ) MATHEMATICAL DOUBLE-STRUCK SMALL R
+1D564;1D564;1D564;0073;0073; # (𝕤; 𝕤; 𝕤; s; s; ) MATHEMATICAL DOUBLE-STRUCK SMALL S
+1D565;1D565;1D565;0074;0074; # (𝕥; 𝕥; 𝕥; t; t; ) MATHEMATICAL DOUBLE-STRUCK SMALL T
+1D566;1D566;1D566;0075;0075; # (𝕦; 𝕦; 𝕦; u; u; ) MATHEMATICAL DOUBLE-STRUCK SMALL U
+1D567;1D567;1D567;0076;0076; # (𝕧; 𝕧; 𝕧; v; v; ) MATHEMATICAL DOUBLE-STRUCK SMALL V
+1D568;1D568;1D568;0077;0077; # (𝕨; 𝕨; 𝕨; w; w; ) MATHEMATICAL DOUBLE-STRUCK SMALL W
+1D569;1D569;1D569;0078;0078; # (𝕩; 𝕩; 𝕩; x; x; ) MATHEMATICAL DOUBLE-STRUCK SMALL X
+1D56A;1D56A;1D56A;0079;0079; # (𝕪; 𝕪; 𝕪; y; y; ) MATHEMATICAL DOUBLE-STRUCK SMALL Y
+1D56B;1D56B;1D56B;007A;007A; # (𝕫; 𝕫; 𝕫; z; z; ) MATHEMATICAL DOUBLE-STRUCK SMALL Z
+1D56C;1D56C;1D56C;0041;0041; # (𝕬; 𝕬; 𝕬; A; A; ) MATHEMATICAL BOLD FRAKTUR CAPITAL A
+1D56D;1D56D;1D56D;0042;0042; # (𝕭; 𝕭; 𝕭; B; B; ) MATHEMATICAL BOLD FRAKTUR CAPITAL B
+1D56E;1D56E;1D56E;0043;0043; # (𝕮; 𝕮; 𝕮; C; C; ) MATHEMATICAL BOLD FRAKTUR CAPITAL C
+1D56F;1D56F;1D56F;0044;0044; # (𝕯; 𝕯; 𝕯; D; D; ) MATHEMATICAL BOLD FRAKTUR CAPITAL D
+1D570;1D570;1D570;0045;0045; # (𝕰; 𝕰; 𝕰; E; E; ) MATHEMATICAL BOLD FRAKTUR CAPITAL E
+1D571;1D571;1D571;0046;0046; # (𝕱; 𝕱; 𝕱; F; F; ) MATHEMATICAL BOLD FRAKTUR CAPITAL F
+1D572;1D572;1D572;0047;0047; # (𝕲; 𝕲; 𝕲; G; G; ) MATHEMATICAL BOLD FRAKTUR CAPITAL G
+1D573;1D573;1D573;0048;0048; # (𝕳; 𝕳; 𝕳; H; H; ) MATHEMATICAL BOLD FRAKTUR CAPITAL H
+1D574;1D574;1D574;0049;0049; # (𝕴; 𝕴; 𝕴; I; I; ) MATHEMATICAL BOLD FRAKTUR CAPITAL I
+1D575;1D575;1D575;004A;004A; # (𝕵; 𝕵; 𝕵; J; J; ) MATHEMATICAL BOLD FRAKTUR CAPITAL J
+1D576;1D576;1D576;004B;004B; # (𝕶; 𝕶; 𝕶; K; K; ) MATHEMATICAL BOLD FRAKTUR CAPITAL K
+1D577;1D577;1D577;004C;004C; # (𝕷; 𝕷; 𝕷; L; L; ) MATHEMATICAL BOLD FRAKTUR CAPITAL L
+1D578;1D578;1D578;004D;004D; # (𝕸; 𝕸; 𝕸; M; M; ) MATHEMATICAL BOLD FRAKTUR CAPITAL M
+1D579;1D579;1D579;004E;004E; # (𝕹; 𝕹; 𝕹; N; N; ) MATHEMATICAL BOLD FRAKTUR CAPITAL N
+1D57A;1D57A;1D57A;004F;004F; # (𝕺; 𝕺; 𝕺; O; O; ) MATHEMATICAL BOLD FRAKTUR CAPITAL O
+1D57B;1D57B;1D57B;0050;0050; # (𝕻; 𝕻; 𝕻; P; P; ) MATHEMATICAL BOLD FRAKTUR CAPITAL P
+1D57C;1D57C;1D57C;0051;0051; # (𝕼; 𝕼; 𝕼; Q; Q; ) MATHEMATICAL BOLD FRAKTUR CAPITAL Q
+1D57D;1D57D;1D57D;0052;0052; # (𝕽; 𝕽; 𝕽; R; R; ) MATHEMATICAL BOLD FRAKTUR CAPITAL R
+1D57E;1D57E;1D57E;0053;0053; # (𝕾; 𝕾; 𝕾; S; S; ) MATHEMATICAL BOLD FRAKTUR CAPITAL S
+1D57F;1D57F;1D57F;0054;0054; # (𝕿; 𝕿; 𝕿; T; T; ) MATHEMATICAL BOLD FRAKTUR CAPITAL T
+1D580;1D580;1D580;0055;0055; # (𝖀; 𝖀; 𝖀; U; U; ) MATHEMATICAL BOLD FRAKTUR CAPITAL U
+1D581;1D581;1D581;0056;0056; # (𝖁; 𝖁; 𝖁; V; V; ) MATHEMATICAL BOLD FRAKTUR CAPITAL V
+1D582;1D582;1D582;0057;0057; # (𝖂; 𝖂; 𝖂; W; W; ) MATHEMATICAL BOLD FRAKTUR CAPITAL W
+1D583;1D583;1D583;0058;0058; # (𝖃; 𝖃; 𝖃; X; X; ) MATHEMATICAL BOLD FRAKTUR CAPITAL X
+1D584;1D584;1D584;0059;0059; # (𝖄; 𝖄; 𝖄; Y; Y; ) MATHEMATICAL BOLD FRAKTUR CAPITAL Y
+1D585;1D585;1D585;005A;005A; # (𝖅; 𝖅; 𝖅; Z; Z; ) MATHEMATICAL BOLD FRAKTUR CAPITAL Z
+1D586;1D586;1D586;0061;0061; # (𝖆; 𝖆; 𝖆; a; a; ) MATHEMATICAL BOLD FRAKTUR SMALL A
+1D587;1D587;1D587;0062;0062; # (𝖇; 𝖇; 𝖇; b; b; ) MATHEMATICAL BOLD FRAKTUR SMALL B
+1D588;1D588;1D588;0063;0063; # (𝖈; 𝖈; 𝖈; c; c; ) MATHEMATICAL BOLD FRAKTUR SMALL C
+1D589;1D589;1D589;0064;0064; # (𝖉; 𝖉; 𝖉; d; d; ) MATHEMATICAL BOLD FRAKTUR SMALL D
+1D58A;1D58A;1D58A;0065;0065; # (𝖊; 𝖊; 𝖊; e; e; ) MATHEMATICAL BOLD FRAKTUR SMALL E
+1D58B;1D58B;1D58B;0066;0066; # (𝖋; 𝖋; 𝖋; f; f; ) MATHEMATICAL BOLD FRAKTUR SMALL F
+1D58C;1D58C;1D58C;0067;0067; # (𝖌; 𝖌; 𝖌; g; g; ) MATHEMATICAL BOLD FRAKTUR SMALL G
+1D58D;1D58D;1D58D;0068;0068; # (𝖍; 𝖍; 𝖍; h; h; ) MATHEMATICAL BOLD FRAKTUR SMALL H
+1D58E;1D58E;1D58E;0069;0069; # (𝖎; 𝖎; 𝖎; i; i; ) MATHEMATICAL BOLD FRAKTUR SMALL I
+1D58F;1D58F;1D58F;006A;006A; # (𝖏; 𝖏; 𝖏; j; j; ) MATHEMATICAL BOLD FRAKTUR SMALL J
+1D590;1D590;1D590;006B;006B; # (𝖐; 𝖐; 𝖐; k; k; ) MATHEMATICAL BOLD FRAKTUR SMALL K
+1D591;1D591;1D591;006C;006C; # (𝖑; 𝖑; 𝖑; l; l; ) MATHEMATICAL BOLD FRAKTUR SMALL L
+1D592;1D592;1D592;006D;006D; # (𝖒; 𝖒; 𝖒; m; m; ) MATHEMATICAL BOLD FRAKTUR SMALL M
+1D593;1D593;1D593;006E;006E; # (𝖓; 𝖓; 𝖓; n; n; ) MATHEMATICAL BOLD FRAKTUR SMALL N
+1D594;1D594;1D594;006F;006F; # (𝖔; 𝖔; 𝖔; o; o; ) MATHEMATICAL BOLD FRAKTUR SMALL O
+1D595;1D595;1D595;0070;0070; # (𝖕; 𝖕; 𝖕; p; p; ) MATHEMATICAL BOLD FRAKTUR SMALL P
+1D596;1D596;1D596;0071;0071; # (𝖖; 𝖖; 𝖖; q; q; ) MATHEMATICAL BOLD FRAKTUR SMALL Q
+1D597;1D597;1D597;0072;0072; # (𝖗; 𝖗; 𝖗; r; r; ) MATHEMATICAL BOLD FRAKTUR SMALL R
+1D598;1D598;1D598;0073;0073; # (𝖘; 𝖘; 𝖘; s; s; ) MATHEMATICAL BOLD FRAKTUR SMALL S
+1D599;1D599;1D599;0074;0074; # (𝖙; 𝖙; 𝖙; t; t; ) MATHEMATICAL BOLD FRAKTUR SMALL T
+1D59A;1D59A;1D59A;0075;0075; # (𝖚; 𝖚; 𝖚; u; u; ) MATHEMATICAL BOLD FRAKTUR SMALL U
+1D59B;1D59B;1D59B;0076;0076; # (𝖛; 𝖛; 𝖛; v; v; ) MATHEMATICAL BOLD FRAKTUR SMALL V
+1D59C;1D59C;1D59C;0077;0077; # (𝖜; 𝖜; 𝖜; w; w; ) MATHEMATICAL BOLD FRAKTUR SMALL W
+1D59D;1D59D;1D59D;0078;0078; # (𝖝; 𝖝; 𝖝; x; x; ) MATHEMATICAL BOLD FRAKTUR SMALL X
+1D59E;1D59E;1D59E;0079;0079; # (𝖞; 𝖞; 𝖞; y; y; ) MATHEMATICAL BOLD FRAKTUR SMALL Y
+1D59F;1D59F;1D59F;007A;007A; # (𝖟; 𝖟; 𝖟; z; z; ) MATHEMATICAL BOLD FRAKTUR SMALL Z
+1D5A0;1D5A0;1D5A0;0041;0041; # (𝖠; 𝖠; 𝖠; A; A; ) MATHEMATICAL SANS-SERIF CAPITAL A
+1D5A1;1D5A1;1D5A1;0042;0042; # (𝖡; 𝖡; 𝖡; B; B; ) MATHEMATICAL SANS-SERIF CAPITAL B
+1D5A2;1D5A2;1D5A2;0043;0043; # (𝖢; 𝖢; 𝖢; C; C; ) MATHEMATICAL SANS-SERIF CAPITAL C
+1D5A3;1D5A3;1D5A3;0044;0044; # (𝖣; 𝖣; 𝖣; D; D; ) MATHEMATICAL SANS-SERIF CAPITAL D
+1D5A4;1D5A4;1D5A4;0045;0045; # (𝖤; 𝖤; 𝖤; E; E; ) MATHEMATICAL SANS-SERIF CAPITAL E
+1D5A5;1D5A5;1D5A5;0046;0046; # (𝖥; 𝖥; 𝖥; F; F; ) MATHEMATICAL SANS-SERIF CAPITAL F
+1D5A6;1D5A6;1D5A6;0047;0047; # (𝖦; 𝖦; 𝖦; G; G; ) MATHEMATICAL SANS-SERIF CAPITAL G
+1D5A7;1D5A7;1D5A7;0048;0048; # (𝖧; 𝖧; 𝖧; H; H; ) MATHEMATICAL SANS-SERIF CAPITAL H
+1D5A8;1D5A8;1D5A8;0049;0049; # (𝖨; 𝖨; 𝖨; I; I; ) MATHEMATICAL SANS-SERIF CAPITAL I
+1D5A9;1D5A9;1D5A9;004A;004A; # (𝖩; 𝖩; 𝖩; J; J; ) MATHEMATICAL SANS-SERIF CAPITAL J
+1D5AA;1D5AA;1D5AA;004B;004B; # (𝖪; 𝖪; 𝖪; K; K; ) MATHEMATICAL SANS-SERIF CAPITAL K
+1D5AB;1D5AB;1D5AB;004C;004C; # (𝖫; 𝖫; 𝖫; L; L; ) MATHEMATICAL SANS-SERIF CAPITAL L
+1D5AC;1D5AC;1D5AC;004D;004D; # (𝖬; 𝖬; 𝖬; M; M; ) MATHEMATICAL SANS-SERIF CAPITAL M
+1D5AD;1D5AD;1D5AD;004E;004E; # (𝖭; 𝖭; 𝖭; N; N; ) MATHEMATICAL SANS-SERIF CAPITAL N
+1D5AE;1D5AE;1D5AE;004F;004F; # (𝖮; 𝖮; 𝖮; O; O; ) MATHEMATICAL SANS-SERIF CAPITAL O
+1D5AF;1D5AF;1D5AF;0050;0050; # (𝖯; 𝖯; 𝖯; P; P; ) MATHEMATICAL SANS-SERIF CAPITAL P
+1D5B0;1D5B0;1D5B0;0051;0051; # (𝖰; 𝖰; 𝖰; Q; Q; ) MATHEMATICAL SANS-SERIF CAPITAL Q
+1D5B1;1D5B1;1D5B1;0052;0052; # (𝖱; 𝖱; 𝖱; R; R; ) MATHEMATICAL SANS-SERIF CAPITAL R
+1D5B2;1D5B2;1D5B2;0053;0053; # (𝖲; 𝖲; 𝖲; S; S; ) MATHEMATICAL SANS-SERIF CAPITAL S
+1D5B3;1D5B3;1D5B3;0054;0054; # (𝖳; 𝖳; 𝖳; T; T; ) MATHEMATICAL SANS-SERIF CAPITAL T
+1D5B4;1D5B4;1D5B4;0055;0055; # (𝖴; 𝖴; 𝖴; U; U; ) MATHEMATICAL SANS-SERIF CAPITAL U
+1D5B5;1D5B5;1D5B5;0056;0056; # (𝖵; 𝖵; 𝖵; V; V; ) MATHEMATICAL SANS-SERIF CAPITAL V
+1D5B6;1D5B6;1D5B6;0057;0057; # (𝖶; 𝖶; 𝖶; W; W; ) MATHEMATICAL SANS-SERIF CAPITAL W
+1D5B7;1D5B7;1D5B7;0058;0058; # (𝖷; 𝖷; 𝖷; X; X; ) MATHEMATICAL SANS-SERIF CAPITAL X
+1D5B8;1D5B8;1D5B8;0059;0059; # (𝖸; 𝖸; 𝖸; Y; Y; ) MATHEMATICAL SANS-SERIF CAPITAL Y
+1D5B9;1D5B9;1D5B9;005A;005A; # (𝖹; 𝖹; 𝖹; Z; Z; ) MATHEMATICAL SANS-SERIF CAPITAL Z
+1D5BA;1D5BA;1D5BA;0061;0061; # (𝖺; 𝖺; 𝖺; a; a; ) MATHEMATICAL SANS-SERIF SMALL A
+1D5BB;1D5BB;1D5BB;0062;0062; # (𝖻; 𝖻; 𝖻; b; b; ) MATHEMATICAL SANS-SERIF SMALL B
+1D5BC;1D5BC;1D5BC;0063;0063; # (𝖼; 𝖼; 𝖼; c; c; ) MATHEMATICAL SANS-SERIF SMALL C
+1D5BD;1D5BD;1D5BD;0064;0064; # (𝖽; 𝖽; 𝖽; d; d; ) MATHEMATICAL SANS-SERIF SMALL D
+1D5BE;1D5BE;1D5BE;0065;0065; # (𝖾; 𝖾; 𝖾; e; e; ) MATHEMATICAL SANS-SERIF SMALL E
+1D5BF;1D5BF;1D5BF;0066;0066; # (𝖿; 𝖿; 𝖿; f; f; ) MATHEMATICAL SANS-SERIF SMALL F
+1D5C0;1D5C0;1D5C0;0067;0067; # (𝗀; 𝗀; 𝗀; g; g; ) MATHEMATICAL SANS-SERIF SMALL G
+1D5C1;1D5C1;1D5C1;0068;0068; # (𝗁; 𝗁; 𝗁; h; h; ) MATHEMATICAL SANS-SERIF SMALL H
+1D5C2;1D5C2;1D5C2;0069;0069; # (𝗂; 𝗂; 𝗂; i; i; ) MATHEMATICAL SANS-SERIF SMALL I
+1D5C3;1D5C3;1D5C3;006A;006A; # (𝗃; 𝗃; 𝗃; j; j; ) MATHEMATICAL SANS-SERIF SMALL J
+1D5C4;1D5C4;1D5C4;006B;006B; # (𝗄; 𝗄; 𝗄; k; k; ) MATHEMATICAL SANS-SERIF SMALL K
+1D5C5;1D5C5;1D5C5;006C;006C; # (𝗅; 𝗅; 𝗅; l; l; ) MATHEMATICAL SANS-SERIF SMALL L
+1D5C6;1D5C6;1D5C6;006D;006D; # (𝗆; 𝗆; 𝗆; m; m; ) MATHEMATICAL SANS-SERIF SMALL M
+1D5C7;1D5C7;1D5C7;006E;006E; # (𝗇; 𝗇; 𝗇; n; n; ) MATHEMATICAL SANS-SERIF SMALL N
+1D5C8;1D5C8;1D5C8;006F;006F; # (𝗈; 𝗈; 𝗈; o; o; ) MATHEMATICAL SANS-SERIF SMALL O
+1D5C9;1D5C9;1D5C9;0070;0070; # (𝗉; 𝗉; 𝗉; p; p; ) MATHEMATICAL SANS-SERIF SMALL P
+1D5CA;1D5CA;1D5CA;0071;0071; # (𝗊; 𝗊; 𝗊; q; q; ) MATHEMATICAL SANS-SERIF SMALL Q
+1D5CB;1D5CB;1D5CB;0072;0072; # (𝗋; 𝗋; 𝗋; r; r; ) MATHEMATICAL SANS-SERIF SMALL R
+1D5CC;1D5CC;1D5CC;0073;0073; # (𝗌; 𝗌; 𝗌; s; s; ) MATHEMATICAL SANS-SERIF SMALL S
+1D5CD;1D5CD;1D5CD;0074;0074; # (𝗍; 𝗍; 𝗍; t; t; ) MATHEMATICAL SANS-SERIF SMALL T
+1D5CE;1D5CE;1D5CE;0075;0075; # (𝗎; 𝗎; 𝗎; u; u; ) MATHEMATICAL SANS-SERIF SMALL U
+1D5CF;1D5CF;1D5CF;0076;0076; # (𝗏; 𝗏; 𝗏; v; v; ) MATHEMATICAL SANS-SERIF SMALL V
+1D5D0;1D5D0;1D5D0;0077;0077; # (𝗐; 𝗐; 𝗐; w; w; ) MATHEMATICAL SANS-SERIF SMALL W
+1D5D1;1D5D1;1D5D1;0078;0078; # (𝗑; 𝗑; 𝗑; x; x; ) MATHEMATICAL SANS-SERIF SMALL X
+1D5D2;1D5D2;1D5D2;0079;0079; # (𝗒; 𝗒; 𝗒; y; y; ) MATHEMATICAL SANS-SERIF SMALL Y
+1D5D3;1D5D3;1D5D3;007A;007A; # (𝗓; 𝗓; 𝗓; z; z; ) MATHEMATICAL SANS-SERIF SMALL Z
+1D5D4;1D5D4;1D5D4;0041;0041; # (𝗔; 𝗔; 𝗔; A; A; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL A
+1D5D5;1D5D5;1D5D5;0042;0042; # (𝗕; 𝗕; 𝗕; B; B; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL B
+1D5D6;1D5D6;1D5D6;0043;0043; # (𝗖; 𝗖; 𝗖; C; C; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL C
+1D5D7;1D5D7;1D5D7;0044;0044; # (𝗗; 𝗗; 𝗗; D; D; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL D
+1D5D8;1D5D8;1D5D8;0045;0045; # (𝗘; 𝗘; 𝗘; E; E; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL E
+1D5D9;1D5D9;1D5D9;0046;0046; # (𝗙; 𝗙; 𝗙; F; F; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL F
+1D5DA;1D5DA;1D5DA;0047;0047; # (𝗚; 𝗚; 𝗚; G; G; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL G
+1D5DB;1D5DB;1D5DB;0048;0048; # (𝗛; 𝗛; 𝗛; H; H; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL H
+1D5DC;1D5DC;1D5DC;0049;0049; # (𝗜; 𝗜; 𝗜; I; I; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL I
+1D5DD;1D5DD;1D5DD;004A;004A; # (𝗝; 𝗝; 𝗝; J; J; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL J
+1D5DE;1D5DE;1D5DE;004B;004B; # (𝗞; 𝗞; 𝗞; K; K; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL K
+1D5DF;1D5DF;1D5DF;004C;004C; # (𝗟; 𝗟; 𝗟; L; L; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL L
+1D5E0;1D5E0;1D5E0;004D;004D; # (𝗠; 𝗠; 𝗠; M; M; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL M
+1D5E1;1D5E1;1D5E1;004E;004E; # (𝗡; 𝗡; 𝗡; N; N; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL N
+1D5E2;1D5E2;1D5E2;004F;004F; # (𝗢; 𝗢; 𝗢; O; O; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL O
+1D5E3;1D5E3;1D5E3;0050;0050; # (𝗣; 𝗣; 𝗣; P; P; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL P
+1D5E4;1D5E4;1D5E4;0051;0051; # (𝗤; 𝗤; 𝗤; Q; Q; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL Q
+1D5E5;1D5E5;1D5E5;0052;0052; # (𝗥; 𝗥; 𝗥; R; R; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL R
+1D5E6;1D5E6;1D5E6;0053;0053; # (𝗦; 𝗦; 𝗦; S; S; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL S
+1D5E7;1D5E7;1D5E7;0054;0054; # (𝗧; 𝗧; 𝗧; T; T; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL T
+1D5E8;1D5E8;1D5E8;0055;0055; # (𝗨; 𝗨; 𝗨; U; U; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL U
+1D5E9;1D5E9;1D5E9;0056;0056; # (𝗩; 𝗩; 𝗩; V; V; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL V
+1D5EA;1D5EA;1D5EA;0057;0057; # (𝗪; 𝗪; 𝗪; W; W; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL W
+1D5EB;1D5EB;1D5EB;0058;0058; # (𝗫; 𝗫; 𝗫; X; X; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL X
+1D5EC;1D5EC;1D5EC;0059;0059; # (𝗬; 𝗬; 𝗬; Y; Y; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL Y
+1D5ED;1D5ED;1D5ED;005A;005A; # (𝗭; 𝗭; 𝗭; Z; Z; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL Z
+1D5EE;1D5EE;1D5EE;0061;0061; # (𝗮; 𝗮; 𝗮; a; a; ) MATHEMATICAL SANS-SERIF BOLD SMALL A
+1D5EF;1D5EF;1D5EF;0062;0062; # (𝗯; 𝗯; 𝗯; b; b; ) MATHEMATICAL SANS-SERIF BOLD SMALL B
+1D5F0;1D5F0;1D5F0;0063;0063; # (𝗰; 𝗰; 𝗰; c; c; ) MATHEMATICAL SANS-SERIF BOLD SMALL C
+1D5F1;1D5F1;1D5F1;0064;0064; # (𝗱; 𝗱; 𝗱; d; d; ) MATHEMATICAL SANS-SERIF BOLD SMALL D
+1D5F2;1D5F2;1D5F2;0065;0065; # (𝗲; 𝗲; 𝗲; e; e; ) MATHEMATICAL SANS-SERIF BOLD SMALL E
+1D5F3;1D5F3;1D5F3;0066;0066; # (𝗳; 𝗳; 𝗳; f; f; ) MATHEMATICAL SANS-SERIF BOLD SMALL F
+1D5F4;1D5F4;1D5F4;0067;0067; # (𝗴; 𝗴; 𝗴; g; g; ) MATHEMATICAL SANS-SERIF BOLD SMALL G
+1D5F5;1D5F5;1D5F5;0068;0068; # (𝗵; 𝗵; 𝗵; h; h; ) MATHEMATICAL SANS-SERIF BOLD SMALL H
+1D5F6;1D5F6;1D5F6;0069;0069; # (𝗶; 𝗶; 𝗶; i; i; ) MATHEMATICAL SANS-SERIF BOLD SMALL I
+1D5F7;1D5F7;1D5F7;006A;006A; # (𝗷; 𝗷; 𝗷; j; j; ) MATHEMATICAL SANS-SERIF BOLD SMALL J
+1D5F8;1D5F8;1D5F8;006B;006B; # (𝗸; 𝗸; 𝗸; k; k; ) MATHEMATICAL SANS-SERIF BOLD SMALL K
+1D5F9;1D5F9;1D5F9;006C;006C; # (𝗹; 𝗹; 𝗹; l; l; ) MATHEMATICAL SANS-SERIF BOLD SMALL L
+1D5FA;1D5FA;1D5FA;006D;006D; # (𝗺; 𝗺; 𝗺; m; m; ) MATHEMATICAL SANS-SERIF BOLD SMALL M
+1D5FB;1D5FB;1D5FB;006E;006E; # (𝗻; 𝗻; 𝗻; n; n; ) MATHEMATICAL SANS-SERIF BOLD SMALL N
+1D5FC;1D5FC;1D5FC;006F;006F; # (𝗼; 𝗼; 𝗼; o; o; ) MATHEMATICAL SANS-SERIF BOLD SMALL O
+1D5FD;1D5FD;1D5FD;0070;0070; # (𝗽; 𝗽; 𝗽; p; p; ) MATHEMATICAL SANS-SERIF BOLD SMALL P
+1D5FE;1D5FE;1D5FE;0071;0071; # (𝗾; 𝗾; 𝗾; q; q; ) MATHEMATICAL SANS-SERIF BOLD SMALL Q
+1D5FF;1D5FF;1D5FF;0072;0072; # (𝗿; 𝗿; 𝗿; r; r; ) MATHEMATICAL SANS-SERIF BOLD SMALL R
+1D600;1D600;1D600;0073;0073; # (𝘀; 𝘀; 𝘀; s; s; ) MATHEMATICAL SANS-SERIF BOLD SMALL S
+1D601;1D601;1D601;0074;0074; # (𝘁; 𝘁; 𝘁; t; t; ) MATHEMATICAL SANS-SERIF BOLD SMALL T
+1D602;1D602;1D602;0075;0075; # (𝘂; 𝘂; 𝘂; u; u; ) MATHEMATICAL SANS-SERIF BOLD SMALL U
+1D603;1D603;1D603;0076;0076; # (𝘃; 𝘃; 𝘃; v; v; ) MATHEMATICAL SANS-SERIF BOLD SMALL V
+1D604;1D604;1D604;0077;0077; # (𝘄; 𝘄; 𝘄; w; w; ) MATHEMATICAL SANS-SERIF BOLD SMALL W
+1D605;1D605;1D605;0078;0078; # (𝘅; 𝘅; 𝘅; x; x; ) MATHEMATICAL SANS-SERIF BOLD SMALL X
+1D606;1D606;1D606;0079;0079; # (𝘆; 𝘆; 𝘆; y; y; ) MATHEMATICAL SANS-SERIF BOLD SMALL Y
+1D607;1D607;1D607;007A;007A; # (𝘇; 𝘇; 𝘇; z; z; ) MATHEMATICAL SANS-SERIF BOLD SMALL Z
+1D608;1D608;1D608;0041;0041; # (𝘈; 𝘈; 𝘈; A; A; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL A
+1D609;1D609;1D609;0042;0042; # (𝘉; 𝘉; 𝘉; B; B; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL B
+1D60A;1D60A;1D60A;0043;0043; # (𝘊; 𝘊; 𝘊; C; C; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL C
+1D60B;1D60B;1D60B;0044;0044; # (𝘋; 𝘋; 𝘋; D; D; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL D
+1D60C;1D60C;1D60C;0045;0045; # (𝘌; 𝘌; 𝘌; E; E; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL E
+1D60D;1D60D;1D60D;0046;0046; # (𝘍; 𝘍; 𝘍; F; F; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL F
+1D60E;1D60E;1D60E;0047;0047; # (𝘎; 𝘎; 𝘎; G; G; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL G
+1D60F;1D60F;1D60F;0048;0048; # (𝘏; 𝘏; 𝘏; H; H; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL H
+1D610;1D610;1D610;0049;0049; # (𝘐; 𝘐; 𝘐; I; I; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL I
+1D611;1D611;1D611;004A;004A; # (𝘑; 𝘑; 𝘑; J; J; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL J
+1D612;1D612;1D612;004B;004B; # (𝘒; 𝘒; 𝘒; K; K; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL K
+1D613;1D613;1D613;004C;004C; # (𝘓; 𝘓; 𝘓; L; L; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL L
+1D614;1D614;1D614;004D;004D; # (𝘔; 𝘔; 𝘔; M; M; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL M
+1D615;1D615;1D615;004E;004E; # (𝘕; 𝘕; 𝘕; N; N; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL N
+1D616;1D616;1D616;004F;004F; # (𝘖; 𝘖; 𝘖; O; O; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL O
+1D617;1D617;1D617;0050;0050; # (𝘗; 𝘗; 𝘗; P; P; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL P
+1D618;1D618;1D618;0051;0051; # (𝘘; 𝘘; 𝘘; Q; Q; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q
+1D619;1D619;1D619;0052;0052; # (𝘙; 𝘙; 𝘙; R; R; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL R
+1D61A;1D61A;1D61A;0053;0053; # (𝘚; 𝘚; 𝘚; S; S; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL S
+1D61B;1D61B;1D61B;0054;0054; # (𝘛; 𝘛; 𝘛; T; T; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL T
+1D61C;1D61C;1D61C;0055;0055; # (𝘜; 𝘜; 𝘜; U; U; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL U
+1D61D;1D61D;1D61D;0056;0056; # (𝘝; 𝘝; 𝘝; V; V; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL V
+1D61E;1D61E;1D61E;0057;0057; # (𝘞; 𝘞; 𝘞; W; W; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL W
+1D61F;1D61F;1D61F;0058;0058; # (𝘟; 𝘟; 𝘟; X; X; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL X
+1D620;1D620;1D620;0059;0059; # (𝘠; 𝘠; 𝘠; Y; Y; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y
+1D621;1D621;1D621;005A;005A; # (𝘡; 𝘡; 𝘡; Z; Z; ) MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z
+1D622;1D622;1D622;0061;0061; # (𝘢; 𝘢; 𝘢; a; a; ) MATHEMATICAL SANS-SERIF ITALIC SMALL A
+1D623;1D623;1D623;0062;0062; # (𝘣; 𝘣; 𝘣; b; b; ) MATHEMATICAL SANS-SERIF ITALIC SMALL B
+1D624;1D624;1D624;0063;0063; # (𝘤; 𝘤; 𝘤; c; c; ) MATHEMATICAL SANS-SERIF ITALIC SMALL C
+1D625;1D625;1D625;0064;0064; # (𝘥; 𝘥; 𝘥; d; d; ) MATHEMATICAL SANS-SERIF ITALIC SMALL D
+1D626;1D626;1D626;0065;0065; # (𝘦; 𝘦; 𝘦; e; e; ) MATHEMATICAL SANS-SERIF ITALIC SMALL E
+1D627;1D627;1D627;0066;0066; # (𝘧; 𝘧; 𝘧; f; f; ) MATHEMATICAL SANS-SERIF ITALIC SMALL F
+1D628;1D628;1D628;0067;0067; # (𝘨; 𝘨; 𝘨; g; g; ) MATHEMATICAL SANS-SERIF ITALIC SMALL G
+1D629;1D629;1D629;0068;0068; # (𝘩; 𝘩; 𝘩; h; h; ) MATHEMATICAL SANS-SERIF ITALIC SMALL H
+1D62A;1D62A;1D62A;0069;0069; # (𝘪; 𝘪; 𝘪; i; i; ) MATHEMATICAL SANS-SERIF ITALIC SMALL I
+1D62B;1D62B;1D62B;006A;006A; # (𝘫; 𝘫; 𝘫; j; j; ) MATHEMATICAL SANS-SERIF ITALIC SMALL J
+1D62C;1D62C;1D62C;006B;006B; # (𝘬; 𝘬; 𝘬; k; k; ) MATHEMATICAL SANS-SERIF ITALIC SMALL K
+1D62D;1D62D;1D62D;006C;006C; # (𝘭; 𝘭; 𝘭; l; l; ) MATHEMATICAL SANS-SERIF ITALIC SMALL L
+1D62E;1D62E;1D62E;006D;006D; # (𝘮; 𝘮; 𝘮; m; m; ) MATHEMATICAL SANS-SERIF ITALIC SMALL M
+1D62F;1D62F;1D62F;006E;006E; # (𝘯; 𝘯; 𝘯; n; n; ) MATHEMATICAL SANS-SERIF ITALIC SMALL N
+1D630;1D630;1D630;006F;006F; # (𝘰; 𝘰; 𝘰; o; o; ) MATHEMATICAL SANS-SERIF ITALIC SMALL O
+1D631;1D631;1D631;0070;0070; # (𝘱; 𝘱; 𝘱; p; p; ) MATHEMATICAL SANS-SERIF ITALIC SMALL P
+1D632;1D632;1D632;0071;0071; # (𝘲; 𝘲; 𝘲; q; q; ) MATHEMATICAL SANS-SERIF ITALIC SMALL Q
+1D633;1D633;1D633;0072;0072; # (𝘳; 𝘳; 𝘳; r; r; ) MATHEMATICAL SANS-SERIF ITALIC SMALL R
+1D634;1D634;1D634;0073;0073; # (𝘴; 𝘴; 𝘴; s; s; ) MATHEMATICAL SANS-SERIF ITALIC SMALL S
+1D635;1D635;1D635;0074;0074; # (𝘵; 𝘵; 𝘵; t; t; ) MATHEMATICAL SANS-SERIF ITALIC SMALL T
+1D636;1D636;1D636;0075;0075; # (𝘶; 𝘶; 𝘶; u; u; ) MATHEMATICAL SANS-SERIF ITALIC SMALL U
+1D637;1D637;1D637;0076;0076; # (𝘷; 𝘷; 𝘷; v; v; ) MATHEMATICAL SANS-SERIF ITALIC SMALL V
+1D638;1D638;1D638;0077;0077; # (𝘸; 𝘸; 𝘸; w; w; ) MATHEMATICAL SANS-SERIF ITALIC SMALL W
+1D639;1D639;1D639;0078;0078; # (𝘹; 𝘹; 𝘹; x; x; ) MATHEMATICAL SANS-SERIF ITALIC SMALL X
+1D63A;1D63A;1D63A;0079;0079; # (𝘺; 𝘺; 𝘺; y; y; ) MATHEMATICAL SANS-SERIF ITALIC SMALL Y
+1D63B;1D63B;1D63B;007A;007A; # (𝘻; 𝘻; 𝘻; z; z; ) MATHEMATICAL SANS-SERIF ITALIC SMALL Z
+1D63C;1D63C;1D63C;0041;0041; # (𝘼; 𝘼; 𝘼; A; A; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A
+1D63D;1D63D;1D63D;0042;0042; # (𝘽; 𝘽; 𝘽; B; B; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B
+1D63E;1D63E;1D63E;0043;0043; # (𝘾; 𝘾; 𝘾; C; C; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C
+1D63F;1D63F;1D63F;0044;0044; # (𝘿; 𝘿; 𝘿; D; D; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D
+1D640;1D640;1D640;0045;0045; # (𝙀; 𝙀; 𝙀; E; E; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E
+1D641;1D641;1D641;0046;0046; # (𝙁; 𝙁; 𝙁; F; F; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F
+1D642;1D642;1D642;0047;0047; # (𝙂; 𝙂; 𝙂; G; G; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G
+1D643;1D643;1D643;0048;0048; # (𝙃; 𝙃; 𝙃; H; H; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H
+1D644;1D644;1D644;0049;0049; # (𝙄; 𝙄; 𝙄; I; I; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I
+1D645;1D645;1D645;004A;004A; # (𝙅; 𝙅; 𝙅; J; J; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J
+1D646;1D646;1D646;004B;004B; # (𝙆; 𝙆; 𝙆; K; K; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K
+1D647;1D647;1D647;004C;004C; # (𝙇; 𝙇; 𝙇; L; L; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L
+1D648;1D648;1D648;004D;004D; # (𝙈; 𝙈; 𝙈; M; M; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M
+1D649;1D649;1D649;004E;004E; # (𝙉; 𝙉; 𝙉; N; N; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N
+1D64A;1D64A;1D64A;004F;004F; # (𝙊; 𝙊; 𝙊; O; O; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O
+1D64B;1D64B;1D64B;0050;0050; # (𝙋; 𝙋; 𝙋; P; P; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P
+1D64C;1D64C;1D64C;0051;0051; # (𝙌; 𝙌; 𝙌; Q; Q; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q
+1D64D;1D64D;1D64D;0052;0052; # (𝙍; 𝙍; 𝙍; R; R; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R
+1D64E;1D64E;1D64E;0053;0053; # (𝙎; 𝙎; 𝙎; S; S; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S
+1D64F;1D64F;1D64F;0054;0054; # (𝙏; 𝙏; 𝙏; T; T; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T
+1D650;1D650;1D650;0055;0055; # (𝙐; 𝙐; 𝙐; U; U; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U
+1D651;1D651;1D651;0056;0056; # (𝙑; 𝙑; 𝙑; V; V; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V
+1D652;1D652;1D652;0057;0057; # (𝙒; 𝙒; 𝙒; W; W; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W
+1D653;1D653;1D653;0058;0058; # (𝙓; 𝙓; 𝙓; X; X; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X
+1D654;1D654;1D654;0059;0059; # (𝙔; 𝙔; 𝙔; Y; Y; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y
+1D655;1D655;1D655;005A;005A; # (𝙕; 𝙕; 𝙕; Z; Z; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z
+1D656;1D656;1D656;0061;0061; # (𝙖; 𝙖; 𝙖; a; a; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A
+1D657;1D657;1D657;0062;0062; # (𝙗; 𝙗; 𝙗; b; b; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B
+1D658;1D658;1D658;0063;0063; # (𝙘; 𝙘; 𝙘; c; c; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C
+1D659;1D659;1D659;0064;0064; # (𝙙; 𝙙; 𝙙; d; d; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D
+1D65A;1D65A;1D65A;0065;0065; # (𝙚; 𝙚; 𝙚; e; e; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E
+1D65B;1D65B;1D65B;0066;0066; # (𝙛; 𝙛; 𝙛; f; f; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F
+1D65C;1D65C;1D65C;0067;0067; # (𝙜; 𝙜; 𝙜; g; g; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G
+1D65D;1D65D;1D65D;0068;0068; # (𝙝; 𝙝; 𝙝; h; h; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H
+1D65E;1D65E;1D65E;0069;0069; # (𝙞; 𝙞; 𝙞; i; i; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I
+1D65F;1D65F;1D65F;006A;006A; # (𝙟; 𝙟; 𝙟; j; j; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J
+1D660;1D660;1D660;006B;006B; # (𝙠; 𝙠; 𝙠; k; k; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K
+1D661;1D661;1D661;006C;006C; # (𝙡; 𝙡; 𝙡; l; l; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L
+1D662;1D662;1D662;006D;006D; # (𝙢; 𝙢; 𝙢; m; m; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M
+1D663;1D663;1D663;006E;006E; # (𝙣; 𝙣; 𝙣; n; n; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N
+1D664;1D664;1D664;006F;006F; # (𝙤; 𝙤; 𝙤; o; o; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O
+1D665;1D665;1D665;0070;0070; # (𝙥; 𝙥; 𝙥; p; p; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P
+1D666;1D666;1D666;0071;0071; # (𝙦; 𝙦; 𝙦; q; q; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q
+1D667;1D667;1D667;0072;0072; # (𝙧; 𝙧; 𝙧; r; r; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R
+1D668;1D668;1D668;0073;0073; # (𝙨; 𝙨; 𝙨; s; s; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S
+1D669;1D669;1D669;0074;0074; # (𝙩; 𝙩; 𝙩; t; t; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T
+1D66A;1D66A;1D66A;0075;0075; # (𝙪; 𝙪; 𝙪; u; u; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U
+1D66B;1D66B;1D66B;0076;0076; # (𝙫; 𝙫; 𝙫; v; v; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V
+1D66C;1D66C;1D66C;0077;0077; # (𝙬; 𝙬; 𝙬; w; w; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W
+1D66D;1D66D;1D66D;0078;0078; # (𝙭; 𝙭; 𝙭; x; x; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X
+1D66E;1D66E;1D66E;0079;0079; # (𝙮; 𝙮; 𝙮; y; y; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y
+1D66F;1D66F;1D66F;007A;007A; # (𝙯; 𝙯; 𝙯; z; z; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z
+1D670;1D670;1D670;0041;0041; # (𝙰; 𝙰; 𝙰; A; A; ) MATHEMATICAL MONOSPACE CAPITAL A
+1D671;1D671;1D671;0042;0042; # (𝙱; 𝙱; 𝙱; B; B; ) MATHEMATICAL MONOSPACE CAPITAL B
+1D672;1D672;1D672;0043;0043; # (𝙲; 𝙲; 𝙲; C; C; ) MATHEMATICAL MONOSPACE CAPITAL C
+1D673;1D673;1D673;0044;0044; # (𝙳; 𝙳; 𝙳; D; D; ) MATHEMATICAL MONOSPACE CAPITAL D
+1D674;1D674;1D674;0045;0045; # (𝙴; 𝙴; 𝙴; E; E; ) MATHEMATICAL MONOSPACE CAPITAL E
+1D675;1D675;1D675;0046;0046; # (𝙵; 𝙵; 𝙵; F; F; ) MATHEMATICAL MONOSPACE CAPITAL F
+1D676;1D676;1D676;0047;0047; # (𝙶; 𝙶; 𝙶; G; G; ) MATHEMATICAL MONOSPACE CAPITAL G
+1D677;1D677;1D677;0048;0048; # (𝙷; 𝙷; 𝙷; H; H; ) MATHEMATICAL MONOSPACE CAPITAL H
+1D678;1D678;1D678;0049;0049; # (𝙸; 𝙸; 𝙸; I; I; ) MATHEMATICAL MONOSPACE CAPITAL I
+1D679;1D679;1D679;004A;004A; # (𝙹; 𝙹; 𝙹; J; J; ) MATHEMATICAL MONOSPACE CAPITAL J
+1D67A;1D67A;1D67A;004B;004B; # (𝙺; 𝙺; 𝙺; K; K; ) MATHEMATICAL MONOSPACE CAPITAL K
+1D67B;1D67B;1D67B;004C;004C; # (𝙻; 𝙻; 𝙻; L; L; ) MATHEMATICAL MONOSPACE CAPITAL L
+1D67C;1D67C;1D67C;004D;004D; # (𝙼; 𝙼; 𝙼; M; M; ) MATHEMATICAL MONOSPACE CAPITAL M
+1D67D;1D67D;1D67D;004E;004E; # (𝙽; 𝙽; 𝙽; N; N; ) MATHEMATICAL MONOSPACE CAPITAL N
+1D67E;1D67E;1D67E;004F;004F; # (𝙾; 𝙾; 𝙾; O; O; ) MATHEMATICAL MONOSPACE CAPITAL O
+1D67F;1D67F;1D67F;0050;0050; # (𝙿; 𝙿; 𝙿; P; P; ) MATHEMATICAL MONOSPACE CAPITAL P
+1D680;1D680;1D680;0051;0051; # (𝚀; 𝚀; 𝚀; Q; Q; ) MATHEMATICAL MONOSPACE CAPITAL Q
+1D681;1D681;1D681;0052;0052; # (𝚁; 𝚁; 𝚁; R; R; ) MATHEMATICAL MONOSPACE CAPITAL R
+1D682;1D682;1D682;0053;0053; # (𝚂; 𝚂; 𝚂; S; S; ) MATHEMATICAL MONOSPACE CAPITAL S
+1D683;1D683;1D683;0054;0054; # (𝚃; 𝚃; 𝚃; T; T; ) MATHEMATICAL MONOSPACE CAPITAL T
+1D684;1D684;1D684;0055;0055; # (𝚄; 𝚄; 𝚄; U; U; ) MATHEMATICAL MONOSPACE CAPITAL U
+1D685;1D685;1D685;0056;0056; # (𝚅; 𝚅; 𝚅; V; V; ) MATHEMATICAL MONOSPACE CAPITAL V
+1D686;1D686;1D686;0057;0057; # (𝚆; 𝚆; 𝚆; W; W; ) MATHEMATICAL MONOSPACE CAPITAL W
+1D687;1D687;1D687;0058;0058; # (𝚇; 𝚇; 𝚇; X; X; ) MATHEMATICAL MONOSPACE CAPITAL X
+1D688;1D688;1D688;0059;0059; # (𝚈; 𝚈; 𝚈; Y; Y; ) MATHEMATICAL MONOSPACE CAPITAL Y
+1D689;1D689;1D689;005A;005A; # (𝚉; 𝚉; 𝚉; Z; Z; ) MATHEMATICAL MONOSPACE CAPITAL Z
+1D68A;1D68A;1D68A;0061;0061; # (𝚊; 𝚊; 𝚊; a; a; ) MATHEMATICAL MONOSPACE SMALL A
+1D68B;1D68B;1D68B;0062;0062; # (𝚋; 𝚋; 𝚋; b; b; ) MATHEMATICAL MONOSPACE SMALL B
+1D68C;1D68C;1D68C;0063;0063; # (𝚌; 𝚌; 𝚌; c; c; ) MATHEMATICAL MONOSPACE SMALL C
+1D68D;1D68D;1D68D;0064;0064; # (𝚍; 𝚍; 𝚍; d; d; ) MATHEMATICAL MONOSPACE SMALL D
+1D68E;1D68E;1D68E;0065;0065; # (𝚎; 𝚎; 𝚎; e; e; ) MATHEMATICAL MONOSPACE SMALL E
+1D68F;1D68F;1D68F;0066;0066; # (𝚏; 𝚏; 𝚏; f; f; ) MATHEMATICAL MONOSPACE SMALL F
+1D690;1D690;1D690;0067;0067; # (𝚐; 𝚐; 𝚐; g; g; ) MATHEMATICAL MONOSPACE SMALL G
+1D691;1D691;1D691;0068;0068; # (𝚑; 𝚑; 𝚑; h; h; ) MATHEMATICAL MONOSPACE SMALL H
+1D692;1D692;1D692;0069;0069; # (𝚒; 𝚒; 𝚒; i; i; ) MATHEMATICAL MONOSPACE SMALL I
+1D693;1D693;1D693;006A;006A; # (𝚓; 𝚓; 𝚓; j; j; ) MATHEMATICAL MONOSPACE SMALL J
+1D694;1D694;1D694;006B;006B; # (𝚔; 𝚔; 𝚔; k; k; ) MATHEMATICAL MONOSPACE SMALL K
+1D695;1D695;1D695;006C;006C; # (𝚕; 𝚕; 𝚕; l; l; ) MATHEMATICAL MONOSPACE SMALL L
+1D696;1D696;1D696;006D;006D; # (𝚖; 𝚖; 𝚖; m; m; ) MATHEMATICAL MONOSPACE SMALL M
+1D697;1D697;1D697;006E;006E; # (𝚗; 𝚗; 𝚗; n; n; ) MATHEMATICAL MONOSPACE SMALL N
+1D698;1D698;1D698;006F;006F; # (𝚘; 𝚘; 𝚘; o; o; ) MATHEMATICAL MONOSPACE SMALL O
+1D699;1D699;1D699;0070;0070; # (𝚙; 𝚙; 𝚙; p; p; ) MATHEMATICAL MONOSPACE SMALL P
+1D69A;1D69A;1D69A;0071;0071; # (𝚚; 𝚚; 𝚚; q; q; ) MATHEMATICAL MONOSPACE SMALL Q
+1D69B;1D69B;1D69B;0072;0072; # (𝚛; 𝚛; 𝚛; r; r; ) MATHEMATICAL MONOSPACE SMALL R
+1D69C;1D69C;1D69C;0073;0073; # (𝚜; 𝚜; 𝚜; s; s; ) MATHEMATICAL MONOSPACE SMALL S
+1D69D;1D69D;1D69D;0074;0074; # (𝚝; 𝚝; 𝚝; t; t; ) MATHEMATICAL MONOSPACE SMALL T
+1D69E;1D69E;1D69E;0075;0075; # (𝚞; 𝚞; 𝚞; u; u; ) MATHEMATICAL MONOSPACE SMALL U
+1D69F;1D69F;1D69F;0076;0076; # (𝚟; 𝚟; 𝚟; v; v; ) MATHEMATICAL MONOSPACE SMALL V
+1D6A0;1D6A0;1D6A0;0077;0077; # (𝚠; 𝚠; 𝚠; w; w; ) MATHEMATICAL MONOSPACE SMALL W
+1D6A1;1D6A1;1D6A1;0078;0078; # (𝚡; 𝚡; 𝚡; x; x; ) MATHEMATICAL MONOSPACE SMALL X
+1D6A2;1D6A2;1D6A2;0079;0079; # (𝚢; 𝚢; 𝚢; y; y; ) MATHEMATICAL MONOSPACE SMALL Y
+1D6A3;1D6A3;1D6A3;007A;007A; # (𝚣; 𝚣; 𝚣; z; z; ) MATHEMATICAL MONOSPACE SMALL Z
+1D6A4;1D6A4;1D6A4;0131;0131; # (𝚤; 𝚤; 𝚤; ı; ı; ) MATHEMATICAL ITALIC SMALL DOTLESS I
+1D6A5;1D6A5;1D6A5;0237;0237; # (𝚥; 𝚥; 𝚥; ȷ; ȷ; ) MATHEMATICAL ITALIC SMALL DOTLESS J
+1D6A8;1D6A8;1D6A8;0391;0391; # (𝚨; 𝚨; 𝚨; Α; Α; ) MATHEMATICAL BOLD CAPITAL ALPHA
+1D6A9;1D6A9;1D6A9;0392;0392; # (𝚩; 𝚩; 𝚩; Β; Β; ) MATHEMATICAL BOLD CAPITAL BETA
+1D6AA;1D6AA;1D6AA;0393;0393; # (𝚪; 𝚪; 𝚪; Γ; Γ; ) MATHEMATICAL BOLD CAPITAL GAMMA
+1D6AB;1D6AB;1D6AB;0394;0394; # (𝚫; 𝚫; 𝚫; Δ; Δ; ) MATHEMATICAL BOLD CAPITAL DELTA
+1D6AC;1D6AC;1D6AC;0395;0395; # (𝚬; 𝚬; 𝚬; Ε; Ε; ) MATHEMATICAL BOLD CAPITAL EPSILON
+1D6AD;1D6AD;1D6AD;0396;0396; # (𝚭; 𝚭; 𝚭; Ζ; Ζ; ) MATHEMATICAL BOLD CAPITAL ZETA
+1D6AE;1D6AE;1D6AE;0397;0397; # (𝚮; 𝚮; 𝚮; Η; Η; ) MATHEMATICAL BOLD CAPITAL ETA
+1D6AF;1D6AF;1D6AF;0398;0398; # (𝚯; 𝚯; 𝚯; Θ; Θ; ) MATHEMATICAL BOLD CAPITAL THETA
+1D6B0;1D6B0;1D6B0;0399;0399; # (𝚰; 𝚰; 𝚰; Ι; Ι; ) MATHEMATICAL BOLD CAPITAL IOTA
+1D6B1;1D6B1;1D6B1;039A;039A; # (𝚱; 𝚱; 𝚱; Κ; Κ; ) MATHEMATICAL BOLD CAPITAL KAPPA
+1D6B2;1D6B2;1D6B2;039B;039B; # (𝚲; 𝚲; 𝚲; Λ; Λ; ) MATHEMATICAL BOLD CAPITAL LAMDA
+1D6B3;1D6B3;1D6B3;039C;039C; # (𝚳; 𝚳; 𝚳; Μ; Μ; ) MATHEMATICAL BOLD CAPITAL MU
+1D6B4;1D6B4;1D6B4;039D;039D; # (𝚴; 𝚴; 𝚴; Ν; Ν; ) MATHEMATICAL BOLD CAPITAL NU
+1D6B5;1D6B5;1D6B5;039E;039E; # (𝚵; 𝚵; 𝚵; Ξ; Ξ; ) MATHEMATICAL BOLD CAPITAL XI
+1D6B6;1D6B6;1D6B6;039F;039F; # (𝚶; 𝚶; 𝚶; Ο; Ο; ) MATHEMATICAL BOLD CAPITAL OMICRON
+1D6B7;1D6B7;1D6B7;03A0;03A0; # (𝚷; 𝚷; 𝚷; Π; Π; ) MATHEMATICAL BOLD CAPITAL PI
+1D6B8;1D6B8;1D6B8;03A1;03A1; # (𝚸; 𝚸; 𝚸; Ρ; Ρ; ) MATHEMATICAL BOLD CAPITAL RHO
+1D6B9;1D6B9;1D6B9;0398;0398; # (𝚹; 𝚹; 𝚹; Θ; Θ; ) MATHEMATICAL BOLD CAPITAL THETA SYMBOL
+1D6BA;1D6BA;1D6BA;03A3;03A3; # (𝚺; 𝚺; 𝚺; Σ; Σ; ) MATHEMATICAL BOLD CAPITAL SIGMA
+1D6BB;1D6BB;1D6BB;03A4;03A4; # (𝚻; 𝚻; 𝚻; Τ; Τ; ) MATHEMATICAL BOLD CAPITAL TAU
+1D6BC;1D6BC;1D6BC;03A5;03A5; # (𝚼; 𝚼; 𝚼; Υ; Υ; ) MATHEMATICAL BOLD CAPITAL UPSILON
+1D6BD;1D6BD;1D6BD;03A6;03A6; # (𝚽; 𝚽; 𝚽; Φ; Φ; ) MATHEMATICAL BOLD CAPITAL PHI
+1D6BE;1D6BE;1D6BE;03A7;03A7; # (𝚾; 𝚾; 𝚾; Χ; Χ; ) MATHEMATICAL BOLD CAPITAL CHI
+1D6BF;1D6BF;1D6BF;03A8;03A8; # (𝚿; 𝚿; 𝚿; Ψ; Ψ; ) MATHEMATICAL BOLD CAPITAL PSI
+1D6C0;1D6C0;1D6C0;03A9;03A9; # (𝛀; 𝛀; 𝛀; Ω; Ω; ) MATHEMATICAL BOLD CAPITAL OMEGA
+1D6C1;1D6C1;1D6C1;2207;2207; # (𝛁; 𝛁; 𝛁; ∇; ∇; ) MATHEMATICAL BOLD NABLA
+1D6C2;1D6C2;1D6C2;03B1;03B1; # (𝛂; 𝛂; 𝛂; α; α; ) MATHEMATICAL BOLD SMALL ALPHA
+1D6C3;1D6C3;1D6C3;03B2;03B2; # (𝛃; 𝛃; 𝛃; β; β; ) MATHEMATICAL BOLD SMALL BETA
+1D6C4;1D6C4;1D6C4;03B3;03B3; # (𝛄; 𝛄; 𝛄; γ; γ; ) MATHEMATICAL BOLD SMALL GAMMA
+1D6C5;1D6C5;1D6C5;03B4;03B4; # (𝛅; 𝛅; 𝛅; δ; δ; ) MATHEMATICAL BOLD SMALL DELTA
+1D6C6;1D6C6;1D6C6;03B5;03B5; # (𝛆; 𝛆; 𝛆; ε; ε; ) MATHEMATICAL BOLD SMALL EPSILON
+1D6C7;1D6C7;1D6C7;03B6;03B6; # (𝛇; 𝛇; 𝛇; ζ; ζ; ) MATHEMATICAL BOLD SMALL ZETA
+1D6C8;1D6C8;1D6C8;03B7;03B7; # (𝛈; 𝛈; 𝛈; η; η; ) MATHEMATICAL BOLD SMALL ETA
+1D6C9;1D6C9;1D6C9;03B8;03B8; # (𝛉; 𝛉; 𝛉; θ; θ; ) MATHEMATICAL BOLD SMALL THETA
+1D6CA;1D6CA;1D6CA;03B9;03B9; # (𝛊; 𝛊; 𝛊; ι; ι; ) MATHEMATICAL BOLD SMALL IOTA
+1D6CB;1D6CB;1D6CB;03BA;03BA; # (𝛋; 𝛋; 𝛋; κ; κ; ) MATHEMATICAL BOLD SMALL KAPPA
+1D6CC;1D6CC;1D6CC;03BB;03BB; # (𝛌; 𝛌; 𝛌; λ; λ; ) MATHEMATICAL BOLD SMALL LAMDA
+1D6CD;1D6CD;1D6CD;03BC;03BC; # (𝛍; 𝛍; 𝛍; μ; μ; ) MATHEMATICAL BOLD SMALL MU
+1D6CE;1D6CE;1D6CE;03BD;03BD; # (𝛎; 𝛎; 𝛎; ν; ν; ) MATHEMATICAL BOLD SMALL NU
+1D6CF;1D6CF;1D6CF;03BE;03BE; # (𝛏; 𝛏; 𝛏; ξ; ξ; ) MATHEMATICAL BOLD SMALL XI
+1D6D0;1D6D0;1D6D0;03BF;03BF; # (𝛐; 𝛐; 𝛐; ο; ο; ) MATHEMATICAL BOLD SMALL OMICRON
+1D6D1;1D6D1;1D6D1;03C0;03C0; # (𝛑; 𝛑; 𝛑; π; π; ) MATHEMATICAL BOLD SMALL PI
+1D6D2;1D6D2;1D6D2;03C1;03C1; # (𝛒; 𝛒; 𝛒; ρ; ρ; ) MATHEMATICAL BOLD SMALL RHO
+1D6D3;1D6D3;1D6D3;03C2;03C2; # (𝛓; 𝛓; 𝛓; ς; ς; ) MATHEMATICAL BOLD SMALL FINAL SIGMA
+1D6D4;1D6D4;1D6D4;03C3;03C3; # (𝛔; 𝛔; 𝛔; σ; σ; ) MATHEMATICAL BOLD SMALL SIGMA
+1D6D5;1D6D5;1D6D5;03C4;03C4; # (𝛕; 𝛕; 𝛕; τ; τ; ) MATHEMATICAL BOLD SMALL TAU
+1D6D6;1D6D6;1D6D6;03C5;03C5; # (𝛖; 𝛖; 𝛖; υ; υ; ) MATHEMATICAL BOLD SMALL UPSILON
+1D6D7;1D6D7;1D6D7;03C6;03C6; # (𝛗; 𝛗; 𝛗; φ; φ; ) MATHEMATICAL BOLD SMALL PHI
+1D6D8;1D6D8;1D6D8;03C7;03C7; # (𝛘; 𝛘; 𝛘; χ; χ; ) MATHEMATICAL BOLD SMALL CHI
+1D6D9;1D6D9;1D6D9;03C8;03C8; # (𝛙; 𝛙; 𝛙; ψ; ψ; ) MATHEMATICAL BOLD SMALL PSI
+1D6DA;1D6DA;1D6DA;03C9;03C9; # (𝛚; 𝛚; 𝛚; ω; ω; ) MATHEMATICAL BOLD SMALL OMEGA
+1D6DB;1D6DB;1D6DB;2202;2202; # (𝛛; 𝛛; 𝛛; ∂; ∂; ) MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
+1D6DC;1D6DC;1D6DC;03B5;03B5; # (𝛜; 𝛜; 𝛜; ε; ε; ) MATHEMATICAL BOLD EPSILON SYMBOL
+1D6DD;1D6DD;1D6DD;03B8;03B8; # (𝛝; 𝛝; 𝛝; θ; θ; ) MATHEMATICAL BOLD THETA SYMBOL
+1D6DE;1D6DE;1D6DE;03BA;03BA; # (𝛞; 𝛞; 𝛞; κ; κ; ) MATHEMATICAL BOLD KAPPA SYMBOL
+1D6DF;1D6DF;1D6DF;03C6;03C6; # (𝛟; 𝛟; 𝛟; φ; φ; ) MATHEMATICAL BOLD PHI SYMBOL
+1D6E0;1D6E0;1D6E0;03C1;03C1; # (𝛠; 𝛠; 𝛠; ρ; ρ; ) MATHEMATICAL BOLD RHO SYMBOL
+1D6E1;1D6E1;1D6E1;03C0;03C0; # (𝛡; 𝛡; 𝛡; π; π; ) MATHEMATICAL BOLD PI SYMBOL
+1D6E2;1D6E2;1D6E2;0391;0391; # (𝛢; 𝛢; 𝛢; Α; Α; ) MATHEMATICAL ITALIC CAPITAL ALPHA
+1D6E3;1D6E3;1D6E3;0392;0392; # (𝛣; 𝛣; 𝛣; Β; Β; ) MATHEMATICAL ITALIC CAPITAL BETA
+1D6E4;1D6E4;1D6E4;0393;0393; # (𝛤; 𝛤; 𝛤; Γ; Γ; ) MATHEMATICAL ITALIC CAPITAL GAMMA
+1D6E5;1D6E5;1D6E5;0394;0394; # (𝛥; 𝛥; 𝛥; Δ; Δ; ) MATHEMATICAL ITALIC CAPITAL DELTA
+1D6E6;1D6E6;1D6E6;0395;0395; # (𝛦; 𝛦; 𝛦; Ε; Ε; ) MATHEMATICAL ITALIC CAPITAL EPSILON
+1D6E7;1D6E7;1D6E7;0396;0396; # (𝛧; 𝛧; 𝛧; Ζ; Ζ; ) MATHEMATICAL ITALIC CAPITAL ZETA
+1D6E8;1D6E8;1D6E8;0397;0397; # (𝛨; 𝛨; 𝛨; Η; Η; ) MATHEMATICAL ITALIC CAPITAL ETA
+1D6E9;1D6E9;1D6E9;0398;0398; # (𝛩; 𝛩; 𝛩; Θ; Θ; ) MATHEMATICAL ITALIC CAPITAL THETA
+1D6EA;1D6EA;1D6EA;0399;0399; # (𝛪; 𝛪; 𝛪; Ι; Ι; ) MATHEMATICAL ITALIC CAPITAL IOTA
+1D6EB;1D6EB;1D6EB;039A;039A; # (𝛫; 𝛫; 𝛫; Κ; Κ; ) MATHEMATICAL ITALIC CAPITAL KAPPA
+1D6EC;1D6EC;1D6EC;039B;039B; # (𝛬; 𝛬; 𝛬; Λ; Λ; ) MATHEMATICAL ITALIC CAPITAL LAMDA
+1D6ED;1D6ED;1D6ED;039C;039C; # (𝛭; 𝛭; 𝛭; Μ; Μ; ) MATHEMATICAL ITALIC CAPITAL MU
+1D6EE;1D6EE;1D6EE;039D;039D; # (𝛮; 𝛮; 𝛮; Ν; Ν; ) MATHEMATICAL ITALIC CAPITAL NU
+1D6EF;1D6EF;1D6EF;039E;039E; # (𝛯; 𝛯; 𝛯; Ξ; Ξ; ) MATHEMATICAL ITALIC CAPITAL XI
+1D6F0;1D6F0;1D6F0;039F;039F; # (𝛰; 𝛰; 𝛰; Ο; Ο; ) MATHEMATICAL ITALIC CAPITAL OMICRON
+1D6F1;1D6F1;1D6F1;03A0;03A0; # (𝛱; 𝛱; 𝛱; Π; Π; ) MATHEMATICAL ITALIC CAPITAL PI
+1D6F2;1D6F2;1D6F2;03A1;03A1; # (𝛲; 𝛲; 𝛲; Ρ; Ρ; ) MATHEMATICAL ITALIC CAPITAL RHO
+1D6F3;1D6F3;1D6F3;0398;0398; # (𝛳; 𝛳; 𝛳; Θ; Θ; ) MATHEMATICAL ITALIC CAPITAL THETA SYMBOL
+1D6F4;1D6F4;1D6F4;03A3;03A3; # (𝛴; 𝛴; 𝛴; Σ; Σ; ) MATHEMATICAL ITALIC CAPITAL SIGMA
+1D6F5;1D6F5;1D6F5;03A4;03A4; # (𝛵; 𝛵; 𝛵; Τ; Τ; ) MATHEMATICAL ITALIC CAPITAL TAU
+1D6F6;1D6F6;1D6F6;03A5;03A5; # (𝛶; 𝛶; 𝛶; Υ; Υ; ) MATHEMATICAL ITALIC CAPITAL UPSILON
+1D6F7;1D6F7;1D6F7;03A6;03A6; # (𝛷; 𝛷; 𝛷; Φ; Φ; ) MATHEMATICAL ITALIC CAPITAL PHI
+1D6F8;1D6F8;1D6F8;03A7;03A7; # (𝛸; 𝛸; 𝛸; Χ; Χ; ) MATHEMATICAL ITALIC CAPITAL CHI
+1D6F9;1D6F9;1D6F9;03A8;03A8; # (𝛹; 𝛹; 𝛹; Ψ; Ψ; ) MATHEMATICAL ITALIC CAPITAL PSI
+1D6FA;1D6FA;1D6FA;03A9;03A9; # (𝛺; 𝛺; 𝛺; Ω; Ω; ) MATHEMATICAL ITALIC CAPITAL OMEGA
+1D6FB;1D6FB;1D6FB;2207;2207; # (𝛻; 𝛻; 𝛻; ∇; ∇; ) MATHEMATICAL ITALIC NABLA
+1D6FC;1D6FC;1D6FC;03B1;03B1; # (𝛼; 𝛼; 𝛼; α; α; ) MATHEMATICAL ITALIC SMALL ALPHA
+1D6FD;1D6FD;1D6FD;03B2;03B2; # (𝛽; 𝛽; 𝛽; β; β; ) MATHEMATICAL ITALIC SMALL BETA
+1D6FE;1D6FE;1D6FE;03B3;03B3; # (𝛾; 𝛾; 𝛾; γ; γ; ) MATHEMATICAL ITALIC SMALL GAMMA
+1D6FF;1D6FF;1D6FF;03B4;03B4; # (𝛿; 𝛿; 𝛿; δ; δ; ) MATHEMATICAL ITALIC SMALL DELTA
+1D700;1D700;1D700;03B5;03B5; # (𝜀; 𝜀; 𝜀; ε; ε; ) MATHEMATICAL ITALIC SMALL EPSILON
+1D701;1D701;1D701;03B6;03B6; # (𝜁; 𝜁; 𝜁; ζ; ζ; ) MATHEMATICAL ITALIC SMALL ZETA
+1D702;1D702;1D702;03B7;03B7; # (𝜂; 𝜂; 𝜂; η; η; ) MATHEMATICAL ITALIC SMALL ETA
+1D703;1D703;1D703;03B8;03B8; # (𝜃; 𝜃; 𝜃; θ; θ; ) MATHEMATICAL ITALIC SMALL THETA
+1D704;1D704;1D704;03B9;03B9; # (𝜄; 𝜄; 𝜄; ι; ι; ) MATHEMATICAL ITALIC SMALL IOTA
+1D705;1D705;1D705;03BA;03BA; # (𝜅; 𝜅; 𝜅; κ; κ; ) MATHEMATICAL ITALIC SMALL KAPPA
+1D706;1D706;1D706;03BB;03BB; # (𝜆; 𝜆; 𝜆; λ; λ; ) MATHEMATICAL ITALIC SMALL LAMDA
+1D707;1D707;1D707;03BC;03BC; # (𝜇; 𝜇; 𝜇; μ; μ; ) MATHEMATICAL ITALIC SMALL MU
+1D708;1D708;1D708;03BD;03BD; # (𝜈; 𝜈; 𝜈; ν; ν; ) MATHEMATICAL ITALIC SMALL NU
+1D709;1D709;1D709;03BE;03BE; # (𝜉; 𝜉; 𝜉; ξ; ξ; ) MATHEMATICAL ITALIC SMALL XI
+1D70A;1D70A;1D70A;03BF;03BF; # (𝜊; 𝜊; 𝜊; ο; ο; ) MATHEMATICAL ITALIC SMALL OMICRON
+1D70B;1D70B;1D70B;03C0;03C0; # (𝜋; 𝜋; 𝜋; π; π; ) MATHEMATICAL ITALIC SMALL PI
+1D70C;1D70C;1D70C;03C1;03C1; # (𝜌; 𝜌; 𝜌; ρ; ρ; ) MATHEMATICAL ITALIC SMALL RHO
+1D70D;1D70D;1D70D;03C2;03C2; # (𝜍; 𝜍; 𝜍; ς; ς; ) MATHEMATICAL ITALIC SMALL FINAL SIGMA
+1D70E;1D70E;1D70E;03C3;03C3; # (𝜎; 𝜎; 𝜎; σ; σ; ) MATHEMATICAL ITALIC SMALL SIGMA
+1D70F;1D70F;1D70F;03C4;03C4; # (𝜏; 𝜏; 𝜏; τ; τ; ) MATHEMATICAL ITALIC SMALL TAU
+1D710;1D710;1D710;03C5;03C5; # (𝜐; 𝜐; 𝜐; υ; υ; ) MATHEMATICAL ITALIC SMALL UPSILON
+1D711;1D711;1D711;03C6;03C6; # (𝜑; 𝜑; 𝜑; φ; φ; ) MATHEMATICAL ITALIC SMALL PHI
+1D712;1D712;1D712;03C7;03C7; # (𝜒; 𝜒; 𝜒; χ; χ; ) MATHEMATICAL ITALIC SMALL CHI
+1D713;1D713;1D713;03C8;03C8; # (𝜓; 𝜓; 𝜓; ψ; ψ; ) MATHEMATICAL ITALIC SMALL PSI
+1D714;1D714;1D714;03C9;03C9; # (𝜔; 𝜔; 𝜔; ω; ω; ) MATHEMATICAL ITALIC SMALL OMEGA
+1D715;1D715;1D715;2202;2202; # (𝜕; 𝜕; 𝜕; ∂; ∂; ) MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
+1D716;1D716;1D716;03B5;03B5; # (𝜖; 𝜖; 𝜖; ε; ε; ) MATHEMATICAL ITALIC EPSILON SYMBOL
+1D717;1D717;1D717;03B8;03B8; # (𝜗; 𝜗; 𝜗; θ; θ; ) MATHEMATICAL ITALIC THETA SYMBOL
+1D718;1D718;1D718;03BA;03BA; # (𝜘; 𝜘; 𝜘; κ; κ; ) MATHEMATICAL ITALIC KAPPA SYMBOL
+1D719;1D719;1D719;03C6;03C6; # (𝜙; 𝜙; 𝜙; φ; φ; ) MATHEMATICAL ITALIC PHI SYMBOL
+1D71A;1D71A;1D71A;03C1;03C1; # (𝜚; 𝜚; 𝜚; ρ; ρ; ) MATHEMATICAL ITALIC RHO SYMBOL
+1D71B;1D71B;1D71B;03C0;03C0; # (𝜛; 𝜛; 𝜛; π; π; ) MATHEMATICAL ITALIC PI SYMBOL
+1D71C;1D71C;1D71C;0391;0391; # (𝜜; 𝜜; 𝜜; Α; Α; ) MATHEMATICAL BOLD ITALIC CAPITAL ALPHA
+1D71D;1D71D;1D71D;0392;0392; # (𝜝; 𝜝; 𝜝; Β; Β; ) MATHEMATICAL BOLD ITALIC CAPITAL BETA
+1D71E;1D71E;1D71E;0393;0393; # (𝜞; 𝜞; 𝜞; Γ; Γ; ) MATHEMATICAL BOLD ITALIC CAPITAL GAMMA
+1D71F;1D71F;1D71F;0394;0394; # (𝜟; 𝜟; 𝜟; Δ; Δ; ) MATHEMATICAL BOLD ITALIC CAPITAL DELTA
+1D720;1D720;1D720;0395;0395; # (𝜠; 𝜠; 𝜠; Ε; Ε; ) MATHEMATICAL BOLD ITALIC CAPITAL EPSILON
+1D721;1D721;1D721;0396;0396; # (𝜡; 𝜡; 𝜡; Ζ; Ζ; ) MATHEMATICAL BOLD ITALIC CAPITAL ZETA
+1D722;1D722;1D722;0397;0397; # (𝜢; 𝜢; 𝜢; Η; Η; ) MATHEMATICAL BOLD ITALIC CAPITAL ETA
+1D723;1D723;1D723;0398;0398; # (𝜣; 𝜣; 𝜣; Θ; Θ; ) MATHEMATICAL BOLD ITALIC CAPITAL THETA
+1D724;1D724;1D724;0399;0399; # (𝜤; 𝜤; 𝜤; Ι; Ι; ) MATHEMATICAL BOLD ITALIC CAPITAL IOTA
+1D725;1D725;1D725;039A;039A; # (𝜥; 𝜥; 𝜥; Κ; Κ; ) MATHEMATICAL BOLD ITALIC CAPITAL KAPPA
+1D726;1D726;1D726;039B;039B; # (𝜦; 𝜦; 𝜦; Λ; Λ; ) MATHEMATICAL BOLD ITALIC CAPITAL LAMDA
+1D727;1D727;1D727;039C;039C; # (𝜧; 𝜧; 𝜧; Μ; Μ; ) MATHEMATICAL BOLD ITALIC CAPITAL MU
+1D728;1D728;1D728;039D;039D; # (𝜨; 𝜨; 𝜨; Ν; Ν; ) MATHEMATICAL BOLD ITALIC CAPITAL NU
+1D729;1D729;1D729;039E;039E; # (𝜩; 𝜩; 𝜩; Ξ; Ξ; ) MATHEMATICAL BOLD ITALIC CAPITAL XI
+1D72A;1D72A;1D72A;039F;039F; # (𝜪; 𝜪; 𝜪; Ο; Ο; ) MATHEMATICAL BOLD ITALIC CAPITAL OMICRON
+1D72B;1D72B;1D72B;03A0;03A0; # (𝜫; 𝜫; 𝜫; Π; Π; ) MATHEMATICAL BOLD ITALIC CAPITAL PI
+1D72C;1D72C;1D72C;03A1;03A1; # (𝜬; 𝜬; 𝜬; Ρ; Ρ; ) MATHEMATICAL BOLD ITALIC CAPITAL RHO
+1D72D;1D72D;1D72D;0398;0398; # (𝜭; 𝜭; 𝜭; Θ; Θ; ) MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL
+1D72E;1D72E;1D72E;03A3;03A3; # (𝜮; 𝜮; 𝜮; Σ; Σ; ) MATHEMATICAL BOLD ITALIC CAPITAL SIGMA
+1D72F;1D72F;1D72F;03A4;03A4; # (𝜯; 𝜯; 𝜯; Τ; Τ; ) MATHEMATICAL BOLD ITALIC CAPITAL TAU
+1D730;1D730;1D730;03A5;03A5; # (𝜰; 𝜰; 𝜰; Υ; Υ; ) MATHEMATICAL BOLD ITALIC CAPITAL UPSILON
+1D731;1D731;1D731;03A6;03A6; # (𝜱; 𝜱; 𝜱; Φ; Φ; ) MATHEMATICAL BOLD ITALIC CAPITAL PHI
+1D732;1D732;1D732;03A7;03A7; # (𝜲; 𝜲; 𝜲; Χ; Χ; ) MATHEMATICAL BOLD ITALIC CAPITAL CHI
+1D733;1D733;1D733;03A8;03A8; # (𝜳; 𝜳; 𝜳; Ψ; Ψ; ) MATHEMATICAL BOLD ITALIC CAPITAL PSI
+1D734;1D734;1D734;03A9;03A9; # (𝜴; 𝜴; 𝜴; Ω; Ω; ) MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
+1D735;1D735;1D735;2207;2207; # (𝜵; 𝜵; 𝜵; ∇; ∇; ) MATHEMATICAL BOLD ITALIC NABLA
+1D736;1D736;1D736;03B1;03B1; # (𝜶; 𝜶; 𝜶; α; α; ) MATHEMATICAL BOLD ITALIC SMALL ALPHA
+1D737;1D737;1D737;03B2;03B2; # (𝜷; 𝜷; 𝜷; β; β; ) MATHEMATICAL BOLD ITALIC SMALL BETA
+1D738;1D738;1D738;03B3;03B3; # (𝜸; 𝜸; 𝜸; γ; γ; ) MATHEMATICAL BOLD ITALIC SMALL GAMMA
+1D739;1D739;1D739;03B4;03B4; # (𝜹; 𝜹; 𝜹; δ; δ; ) MATHEMATICAL BOLD ITALIC SMALL DELTA
+1D73A;1D73A;1D73A;03B5;03B5; # (𝜺; 𝜺; 𝜺; ε; ε; ) MATHEMATICAL BOLD ITALIC SMALL EPSILON
+1D73B;1D73B;1D73B;03B6;03B6; # (𝜻; 𝜻; 𝜻; ζ; ζ; ) MATHEMATICAL BOLD ITALIC SMALL ZETA
+1D73C;1D73C;1D73C;03B7;03B7; # (𝜼; 𝜼; 𝜼; η; η; ) MATHEMATICAL BOLD ITALIC SMALL ETA
+1D73D;1D73D;1D73D;03B8;03B8; # (𝜽; 𝜽; 𝜽; θ; θ; ) MATHEMATICAL BOLD ITALIC SMALL THETA
+1D73E;1D73E;1D73E;03B9;03B9; # (𝜾; 𝜾; 𝜾; ι; ι; ) MATHEMATICAL BOLD ITALIC SMALL IOTA
+1D73F;1D73F;1D73F;03BA;03BA; # (𝜿; 𝜿; 𝜿; κ; κ; ) MATHEMATICAL BOLD ITALIC SMALL KAPPA
+1D740;1D740;1D740;03BB;03BB; # (𝝀; 𝝀; 𝝀; λ; λ; ) MATHEMATICAL BOLD ITALIC SMALL LAMDA
+1D741;1D741;1D741;03BC;03BC; # (𝝁; 𝝁; 𝝁; μ; μ; ) MATHEMATICAL BOLD ITALIC SMALL MU
+1D742;1D742;1D742;03BD;03BD; # (𝝂; 𝝂; 𝝂; ν; ν; ) MATHEMATICAL BOLD ITALIC SMALL NU
+1D743;1D743;1D743;03BE;03BE; # (𝝃; 𝝃; 𝝃; ξ; ξ; ) MATHEMATICAL BOLD ITALIC SMALL XI
+1D744;1D744;1D744;03BF;03BF; # (𝝄; 𝝄; 𝝄; ο; ο; ) MATHEMATICAL BOLD ITALIC SMALL OMICRON
+1D745;1D745;1D745;03C0;03C0; # (𝝅; 𝝅; 𝝅; π; π; ) MATHEMATICAL BOLD ITALIC SMALL PI
+1D746;1D746;1D746;03C1;03C1; # (𝝆; 𝝆; 𝝆; ρ; ρ; ) MATHEMATICAL BOLD ITALIC SMALL RHO
+1D747;1D747;1D747;03C2;03C2; # (𝝇; 𝝇; 𝝇; ς; ς; ) MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA
+1D748;1D748;1D748;03C3;03C3; # (𝝈; 𝝈; 𝝈; σ; σ; ) MATHEMATICAL BOLD ITALIC SMALL SIGMA
+1D749;1D749;1D749;03C4;03C4; # (𝝉; 𝝉; 𝝉; τ; τ; ) MATHEMATICAL BOLD ITALIC SMALL TAU
+1D74A;1D74A;1D74A;03C5;03C5; # (𝝊; 𝝊; 𝝊; υ; υ; ) MATHEMATICAL BOLD ITALIC SMALL UPSILON
+1D74B;1D74B;1D74B;03C6;03C6; # (𝝋; 𝝋; 𝝋; φ; φ; ) MATHEMATICAL BOLD ITALIC SMALL PHI
+1D74C;1D74C;1D74C;03C7;03C7; # (𝝌; 𝝌; 𝝌; χ; χ; ) MATHEMATICAL BOLD ITALIC SMALL CHI
+1D74D;1D74D;1D74D;03C8;03C8; # (𝝍; 𝝍; 𝝍; ψ; ψ; ) MATHEMATICAL BOLD ITALIC SMALL PSI
+1D74E;1D74E;1D74E;03C9;03C9; # (𝝎; 𝝎; 𝝎; ω; ω; ) MATHEMATICAL BOLD ITALIC SMALL OMEGA
+1D74F;1D74F;1D74F;2202;2202; # (𝝏; 𝝏; 𝝏; ∂; ∂; ) MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
+1D750;1D750;1D750;03B5;03B5; # (𝝐; 𝝐; 𝝐; ε; ε; ) MATHEMATICAL BOLD ITALIC EPSILON SYMBOL
+1D751;1D751;1D751;03B8;03B8; # (𝝑; 𝝑; 𝝑; θ; θ; ) MATHEMATICAL BOLD ITALIC THETA SYMBOL
+1D752;1D752;1D752;03BA;03BA; # (𝝒; 𝝒; 𝝒; κ; κ; ) MATHEMATICAL BOLD ITALIC KAPPA SYMBOL
+1D753;1D753;1D753;03C6;03C6; # (𝝓; 𝝓; 𝝓; φ; φ; ) MATHEMATICAL BOLD ITALIC PHI SYMBOL
+1D754;1D754;1D754;03C1;03C1; # (𝝔; 𝝔; 𝝔; ρ; ρ; ) MATHEMATICAL BOLD ITALIC RHO SYMBOL
+1D755;1D755;1D755;03C0;03C0; # (𝝕; 𝝕; 𝝕; π; π; ) MATHEMATICAL BOLD ITALIC PI SYMBOL
+1D756;1D756;1D756;0391;0391; # (𝝖; 𝝖; 𝝖; Α; Α; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA
+1D757;1D757;1D757;0392;0392; # (𝝗; 𝝗; 𝝗; Β; Β; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA
+1D758;1D758;1D758;0393;0393; # (𝝘; 𝝘; 𝝘; Γ; Γ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA
+1D759;1D759;1D759;0394;0394; # (𝝙; 𝝙; 𝝙; Δ; Δ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA
+1D75A;1D75A;1D75A;0395;0395; # (𝝚; 𝝚; 𝝚; Ε; Ε; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON
+1D75B;1D75B;1D75B;0396;0396; # (𝝛; 𝝛; 𝝛; Ζ; Ζ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA
+1D75C;1D75C;1D75C;0397;0397; # (𝝜; 𝝜; 𝝜; Η; Η; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA
+1D75D;1D75D;1D75D;0398;0398; # (𝝝; 𝝝; 𝝝; Θ; Θ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA
+1D75E;1D75E;1D75E;0399;0399; # (𝝞; 𝝞; 𝝞; Ι; Ι; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA
+1D75F;1D75F;1D75F;039A;039A; # (𝝟; 𝝟; 𝝟; Κ; Κ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA
+1D760;1D760;1D760;039B;039B; # (𝝠; 𝝠; 𝝠; Λ; Λ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA
+1D761;1D761;1D761;039C;039C; # (𝝡; 𝝡; 𝝡; Μ; Μ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL MU
+1D762;1D762;1D762;039D;039D; # (𝝢; 𝝢; 𝝢; Ν; Ν; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL NU
+1D763;1D763;1D763;039E;039E; # (𝝣; 𝝣; 𝝣; Ξ; Ξ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL XI
+1D764;1D764;1D764;039F;039F; # (𝝤; 𝝤; 𝝤; Ο; Ο; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON
+1D765;1D765;1D765;03A0;03A0; # (𝝥; 𝝥; 𝝥; Π; Π; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL PI
+1D766;1D766;1D766;03A1;03A1; # (𝝦; 𝝦; 𝝦; Ρ; Ρ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO
+1D767;1D767;1D767;0398;0398; # (𝝧; 𝝧; 𝝧; Θ; Θ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL
+1D768;1D768;1D768;03A3;03A3; # (𝝨; 𝝨; 𝝨; Σ; Σ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA
+1D769;1D769;1D769;03A4;03A4; # (𝝩; 𝝩; 𝝩; Τ; Τ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU
+1D76A;1D76A;1D76A;03A5;03A5; # (𝝪; 𝝪; 𝝪; Υ; Υ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON
+1D76B;1D76B;1D76B;03A6;03A6; # (𝝫; 𝝫; 𝝫; Φ; Φ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI
+1D76C;1D76C;1D76C;03A7;03A7; # (𝝬; 𝝬; 𝝬; Χ; Χ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI
+1D76D;1D76D;1D76D;03A8;03A8; # (𝝭; 𝝭; 𝝭; Ψ; Ψ; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI
+1D76E;1D76E;1D76E;03A9;03A9; # (𝝮; 𝝮; 𝝮; Ω; Ω; ) MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
+1D76F;1D76F;1D76F;2207;2207; # (𝝯; 𝝯; 𝝯; ∇; ∇; ) MATHEMATICAL SANS-SERIF BOLD NABLA
+1D770;1D770;1D770;03B1;03B1; # (𝝰; 𝝰; 𝝰; α; α; ) MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA
+1D771;1D771;1D771;03B2;03B2; # (𝝱; 𝝱; 𝝱; β; β; ) MATHEMATICAL SANS-SERIF BOLD SMALL BETA
+1D772;1D772;1D772;03B3;03B3; # (𝝲; 𝝲; 𝝲; γ; γ; ) MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA
+1D773;1D773;1D773;03B4;03B4; # (𝝳; 𝝳; 𝝳; δ; δ; ) MATHEMATICAL SANS-SERIF BOLD SMALL DELTA
+1D774;1D774;1D774;03B5;03B5; # (𝝴; 𝝴; 𝝴; ε; ε; ) MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON
+1D775;1D775;1D775;03B6;03B6; # (𝝵; 𝝵; 𝝵; ζ; ζ; ) MATHEMATICAL SANS-SERIF BOLD SMALL ZETA
+1D776;1D776;1D776;03B7;03B7; # (𝝶; 𝝶; 𝝶; η; η; ) MATHEMATICAL SANS-SERIF BOLD SMALL ETA
+1D777;1D777;1D777;03B8;03B8; # (𝝷; 𝝷; 𝝷; θ; θ; ) MATHEMATICAL SANS-SERIF BOLD SMALL THETA
+1D778;1D778;1D778;03B9;03B9; # (𝝸; 𝝸; 𝝸; ι; ι; ) MATHEMATICAL SANS-SERIF BOLD SMALL IOTA
+1D779;1D779;1D779;03BA;03BA; # (𝝹; 𝝹; 𝝹; κ; κ; ) MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA
+1D77A;1D77A;1D77A;03BB;03BB; # (𝝺; 𝝺; 𝝺; λ; λ; ) MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA
+1D77B;1D77B;1D77B;03BC;03BC; # (𝝻; 𝝻; 𝝻; μ; μ; ) MATHEMATICAL SANS-SERIF BOLD SMALL MU
+1D77C;1D77C;1D77C;03BD;03BD; # (𝝼; 𝝼; 𝝼; ν; ν; ) MATHEMATICAL SANS-SERIF BOLD SMALL NU
+1D77D;1D77D;1D77D;03BE;03BE; # (𝝽; 𝝽; 𝝽; ξ; ξ; ) MATHEMATICAL SANS-SERIF BOLD SMALL XI
+1D77E;1D77E;1D77E;03BF;03BF; # (𝝾; 𝝾; 𝝾; ο; ο; ) MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON
+1D77F;1D77F;1D77F;03C0;03C0; # (𝝿; 𝝿; 𝝿; π; π; ) MATHEMATICAL SANS-SERIF BOLD SMALL PI
+1D780;1D780;1D780;03C1;03C1; # (𝞀; 𝞀; 𝞀; ρ; ρ; ) MATHEMATICAL SANS-SERIF BOLD SMALL RHO
+1D781;1D781;1D781;03C2;03C2; # (𝞁; 𝞁; 𝞁; ς; ς; ) MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA
+1D782;1D782;1D782;03C3;03C3; # (𝞂; 𝞂; 𝞂; σ; σ; ) MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA
+1D783;1D783;1D783;03C4;03C4; # (𝞃; 𝞃; 𝞃; τ; τ; ) MATHEMATICAL SANS-SERIF BOLD SMALL TAU
+1D784;1D784;1D784;03C5;03C5; # (𝞄; 𝞄; 𝞄; υ; υ; ) MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON
+1D785;1D785;1D785;03C6;03C6; # (𝞅; 𝞅; 𝞅; φ; φ; ) MATHEMATICAL SANS-SERIF BOLD SMALL PHI
+1D786;1D786;1D786;03C7;03C7; # (𝞆; 𝞆; 𝞆; χ; χ; ) MATHEMATICAL SANS-SERIF BOLD SMALL CHI
+1D787;1D787;1D787;03C8;03C8; # (𝞇; 𝞇; 𝞇; ψ; ψ; ) MATHEMATICAL SANS-SERIF BOLD SMALL PSI
+1D788;1D788;1D788;03C9;03C9; # (𝞈; 𝞈; 𝞈; ω; ω; ) MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
+1D789;1D789;1D789;2202;2202; # (𝞉; 𝞉; 𝞉; ∂; ∂; ) MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
+1D78A;1D78A;1D78A;03B5;03B5; # (𝞊; 𝞊; 𝞊; ε; ε; ) MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL
+1D78B;1D78B;1D78B;03B8;03B8; # (𝞋; 𝞋; 𝞋; θ; θ; ) MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL
+1D78C;1D78C;1D78C;03BA;03BA; # (𝞌; 𝞌; 𝞌; κ; κ; ) MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL
+1D78D;1D78D;1D78D;03C6;03C6; # (𝞍; 𝞍; 𝞍; φ; φ; ) MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL
+1D78E;1D78E;1D78E;03C1;03C1; # (𝞎; 𝞎; 𝞎; ρ; ρ; ) MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL
+1D78F;1D78F;1D78F;03C0;03C0; # (𝞏; 𝞏; 𝞏; π; π; ) MATHEMATICAL SANS-SERIF BOLD PI SYMBOL
+1D790;1D790;1D790;0391;0391; # (𝞐; 𝞐; 𝞐; Α; Α; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA
+1D791;1D791;1D791;0392;0392; # (𝞑; 𝞑; 𝞑; Β; Β; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA
+1D792;1D792;1D792;0393;0393; # (𝞒; 𝞒; 𝞒; Γ; Γ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA
+1D793;1D793;1D793;0394;0394; # (𝞓; 𝞓; 𝞓; Δ; Δ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA
+1D794;1D794;1D794;0395;0395; # (𝞔; 𝞔; 𝞔; Ε; Ε; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON
+1D795;1D795;1D795;0396;0396; # (𝞕; 𝞕; 𝞕; Ζ; Ζ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA
+1D796;1D796;1D796;0397;0397; # (𝞖; 𝞖; 𝞖; Η; Η; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA
+1D797;1D797;1D797;0398;0398; # (𝞗; 𝞗; 𝞗; Θ; Θ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA
+1D798;1D798;1D798;0399;0399; # (𝞘; 𝞘; 𝞘; Ι; Ι; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA
+1D799;1D799;1D799;039A;039A; # (𝞙; 𝞙; 𝞙; Κ; Κ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA
+1D79A;1D79A;1D79A;039B;039B; # (𝞚; 𝞚; 𝞚; Λ; Λ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA
+1D79B;1D79B;1D79B;039C;039C; # (𝞛; 𝞛; 𝞛; Μ; Μ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU
+1D79C;1D79C;1D79C;039D;039D; # (𝞜; 𝞜; 𝞜; Ν; Ν; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU
+1D79D;1D79D;1D79D;039E;039E; # (𝞝; 𝞝; 𝞝; Ξ; Ξ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI
+1D79E;1D79E;1D79E;039F;039F; # (𝞞; 𝞞; 𝞞; Ο; Ο; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON
+1D79F;1D79F;1D79F;03A0;03A0; # (𝞟; 𝞟; 𝞟; Π; Π; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI
+1D7A0;1D7A0;1D7A0;03A1;03A1; # (𝞠; 𝞠; 𝞠; Ρ; Ρ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO
+1D7A1;1D7A1;1D7A1;0398;0398; # (𝞡; 𝞡; 𝞡; Θ; Θ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL
+1D7A2;1D7A2;1D7A2;03A3;03A3; # (𝞢; 𝞢; 𝞢; Σ; Σ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA
+1D7A3;1D7A3;1D7A3;03A4;03A4; # (𝞣; 𝞣; 𝞣; Τ; Τ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU
+1D7A4;1D7A4;1D7A4;03A5;03A5; # (𝞤; 𝞤; 𝞤; Υ; Υ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON
+1D7A5;1D7A5;1D7A5;03A6;03A6; # (𝞥; 𝞥; 𝞥; Φ; Φ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI
+1D7A6;1D7A6;1D7A6;03A7;03A7; # (𝞦; 𝞦; 𝞦; Χ; Χ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI
+1D7A7;1D7A7;1D7A7;03A8;03A8; # (𝞧; 𝞧; 𝞧; Ψ; Ψ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI
+1D7A8;1D7A8;1D7A8;03A9;03A9; # (𝞨; 𝞨; 𝞨; Ω; Ω; ) MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
+1D7A9;1D7A9;1D7A9;2207;2207; # (𝞩; 𝞩; 𝞩; ∇; ∇; ) MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA
+1D7AA;1D7AA;1D7AA;03B1;03B1; # (𝞪; 𝞪; 𝞪; α; α; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA
+1D7AB;1D7AB;1D7AB;03B2;03B2; # (𝞫; 𝞫; 𝞫; β; β; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA
+1D7AC;1D7AC;1D7AC;03B3;03B3; # (𝞬; 𝞬; 𝞬; γ; γ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA
+1D7AD;1D7AD;1D7AD;03B4;03B4; # (𝞭; 𝞭; 𝞭; δ; δ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA
+1D7AE;1D7AE;1D7AE;03B5;03B5; # (𝞮; 𝞮; 𝞮; ε; ε; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON
+1D7AF;1D7AF;1D7AF;03B6;03B6; # (𝞯; 𝞯; 𝞯; ζ; ζ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA
+1D7B0;1D7B0;1D7B0;03B7;03B7; # (𝞰; 𝞰; 𝞰; η; η; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA
+1D7B1;1D7B1;1D7B1;03B8;03B8; # (𝞱; 𝞱; 𝞱; θ; θ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA
+1D7B2;1D7B2;1D7B2;03B9;03B9; # (𝞲; 𝞲; 𝞲; ι; ι; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA
+1D7B3;1D7B3;1D7B3;03BA;03BA; # (𝞳; 𝞳; 𝞳; κ; κ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA
+1D7B4;1D7B4;1D7B4;03BB;03BB; # (𝞴; 𝞴; 𝞴; λ; λ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA
+1D7B5;1D7B5;1D7B5;03BC;03BC; # (𝞵; 𝞵; 𝞵; μ; μ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU
+1D7B6;1D7B6;1D7B6;03BD;03BD; # (𝞶; 𝞶; 𝞶; ν; ν; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU
+1D7B7;1D7B7;1D7B7;03BE;03BE; # (𝞷; 𝞷; 𝞷; ξ; ξ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI
+1D7B8;1D7B8;1D7B8;03BF;03BF; # (𝞸; 𝞸; 𝞸; ο; ο; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON
+1D7B9;1D7B9;1D7B9;03C0;03C0; # (𝞹; 𝞹; 𝞹; π; π; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI
+1D7BA;1D7BA;1D7BA;03C1;03C1; # (𝞺; 𝞺; 𝞺; ρ; ρ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO
+1D7BB;1D7BB;1D7BB;03C2;03C2; # (𝞻; 𝞻; 𝞻; ς; ς; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA
+1D7BC;1D7BC;1D7BC;03C3;03C3; # (𝞼; 𝞼; 𝞼; σ; σ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA
+1D7BD;1D7BD;1D7BD;03C4;03C4; # (𝞽; 𝞽; 𝞽; τ; τ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU
+1D7BE;1D7BE;1D7BE;03C5;03C5; # (𝞾; 𝞾; 𝞾; υ; υ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON
+1D7BF;1D7BF;1D7BF;03C6;03C6; # (𝞿; 𝞿; 𝞿; φ; φ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI
+1D7C0;1D7C0;1D7C0;03C7;03C7; # (𝟀; 𝟀; 𝟀; χ; χ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI
+1D7C1;1D7C1;1D7C1;03C8;03C8; # (𝟁; 𝟁; 𝟁; ψ; ψ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI
+1D7C2;1D7C2;1D7C2;03C9;03C9; # (𝟂; 𝟂; 𝟂; ω; ω; ) MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
+1D7C3;1D7C3;1D7C3;2202;2202; # (𝟃; 𝟃; 𝟃; ∂; ∂; ) MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
+1D7C4;1D7C4;1D7C4;03B5;03B5; # (𝟄; 𝟄; 𝟄; ε; ε; ) MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL
+1D7C5;1D7C5;1D7C5;03B8;03B8; # (𝟅; 𝟅; 𝟅; θ; θ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL
+1D7C6;1D7C6;1D7C6;03BA;03BA; # (𝟆; 𝟆; 𝟆; κ; κ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL
+1D7C7;1D7C7;1D7C7;03C6;03C6; # (𝟇; 𝟇; 𝟇; φ; φ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL
+1D7C8;1D7C8;1D7C8;03C1;03C1; # (𝟈; 𝟈; 𝟈; ρ; ρ; ) MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL
+1D7C9;1D7C9;1D7C9;03C0;03C0; # (𝟉; 𝟉; 𝟉; π; π; ) MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL
+1D7CA;1D7CA;1D7CA;03DC;03DC; # (𝟊; 𝟊; 𝟊; Ϝ; Ϝ; ) MATHEMATICAL BOLD CAPITAL DIGAMMA
+1D7CB;1D7CB;1D7CB;03DD;03DD; # (𝟋; 𝟋; 𝟋; ϝ; ϝ; ) MATHEMATICAL BOLD SMALL DIGAMMA
+1D7CE;1D7CE;1D7CE;0030;0030; # (𝟎; 𝟎; 𝟎; 0; 0; ) MATHEMATICAL BOLD DIGIT ZERO
+1D7CF;1D7CF;1D7CF;0031;0031; # (𝟏; 𝟏; 𝟏; 1; 1; ) MATHEMATICAL BOLD DIGIT ONE
+1D7D0;1D7D0;1D7D0;0032;0032; # (𝟐; 𝟐; 𝟐; 2; 2; ) MATHEMATICAL BOLD DIGIT TWO
+1D7D1;1D7D1;1D7D1;0033;0033; # (𝟑; 𝟑; 𝟑; 3; 3; ) MATHEMATICAL BOLD DIGIT THREE
+1D7D2;1D7D2;1D7D2;0034;0034; # (𝟒; 𝟒; 𝟒; 4; 4; ) MATHEMATICAL BOLD DIGIT FOUR
+1D7D3;1D7D3;1D7D3;0035;0035; # (𝟓; 𝟓; 𝟓; 5; 5; ) MATHEMATICAL BOLD DIGIT FIVE
+1D7D4;1D7D4;1D7D4;0036;0036; # (𝟔; 𝟔; 𝟔; 6; 6; ) MATHEMATICAL BOLD DIGIT SIX
+1D7D5;1D7D5;1D7D5;0037;0037; # (𝟕; 𝟕; 𝟕; 7; 7; ) MATHEMATICAL BOLD DIGIT SEVEN
+1D7D6;1D7D6;1D7D6;0038;0038; # (𝟖; 𝟖; 𝟖; 8; 8; ) MATHEMATICAL BOLD DIGIT EIGHT
+1D7D7;1D7D7;1D7D7;0039;0039; # (𝟗; 𝟗; 𝟗; 9; 9; ) MATHEMATICAL BOLD DIGIT NINE
+1D7D8;1D7D8;1D7D8;0030;0030; # (𝟘; 𝟘; 𝟘; 0; 0; ) MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO
+1D7D9;1D7D9;1D7D9;0031;0031; # (𝟙; 𝟙; 𝟙; 1; 1; ) MATHEMATICAL DOUBLE-STRUCK DIGIT ONE
+1D7DA;1D7DA;1D7DA;0032;0032; # (𝟚; 𝟚; 𝟚; 2; 2; ) MATHEMATICAL DOUBLE-STRUCK DIGIT TWO
+1D7DB;1D7DB;1D7DB;0033;0033; # (𝟛; 𝟛; 𝟛; 3; 3; ) MATHEMATICAL DOUBLE-STRUCK DIGIT THREE
+1D7DC;1D7DC;1D7DC;0034;0034; # (𝟜; 𝟜; 𝟜; 4; 4; ) MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR
+1D7DD;1D7DD;1D7DD;0035;0035; # (𝟝; 𝟝; 𝟝; 5; 5; ) MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE
+1D7DE;1D7DE;1D7DE;0036;0036; # (𝟞; 𝟞; 𝟞; 6; 6; ) MATHEMATICAL DOUBLE-STRUCK DIGIT SIX
+1D7DF;1D7DF;1D7DF;0037;0037; # (𝟟; 𝟟; 𝟟; 7; 7; ) MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN
+1D7E0;1D7E0;1D7E0;0038;0038; # (𝟠; 𝟠; 𝟠; 8; 8; ) MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT
+1D7E1;1D7E1;1D7E1;0039;0039; # (𝟡; 𝟡; 𝟡; 9; 9; ) MATHEMATICAL DOUBLE-STRUCK DIGIT NINE
+1D7E2;1D7E2;1D7E2;0030;0030; # (𝟢; 𝟢; 𝟢; 0; 0; ) MATHEMATICAL SANS-SERIF DIGIT ZERO
+1D7E3;1D7E3;1D7E3;0031;0031; # (𝟣; 𝟣; 𝟣; 1; 1; ) MATHEMATICAL SANS-SERIF DIGIT ONE
+1D7E4;1D7E4;1D7E4;0032;0032; # (𝟤; 𝟤; 𝟤; 2; 2; ) MATHEMATICAL SANS-SERIF DIGIT TWO
+1D7E5;1D7E5;1D7E5;0033;0033; # (𝟥; 𝟥; 𝟥; 3; 3; ) MATHEMATICAL SANS-SERIF DIGIT THREE
+1D7E6;1D7E6;1D7E6;0034;0034; # (𝟦; 𝟦; 𝟦; 4; 4; ) MATHEMATICAL SANS-SERIF DIGIT FOUR
+1D7E7;1D7E7;1D7E7;0035;0035; # (𝟧; 𝟧; 𝟧; 5; 5; ) MATHEMATICAL SANS-SERIF DIGIT FIVE
+1D7E8;1D7E8;1D7E8;0036;0036; # (𝟨; 𝟨; 𝟨; 6; 6; ) MATHEMATICAL SANS-SERIF DIGIT SIX
+1D7E9;1D7E9;1D7E9;0037;0037; # (𝟩; 𝟩; 𝟩; 7; 7; ) MATHEMATICAL SANS-SERIF DIGIT SEVEN
+1D7EA;1D7EA;1D7EA;0038;0038; # (𝟪; 𝟪; 𝟪; 8; 8; ) MATHEMATICAL SANS-SERIF DIGIT EIGHT
+1D7EB;1D7EB;1D7EB;0039;0039; # (𝟫; 𝟫; 𝟫; 9; 9; ) MATHEMATICAL SANS-SERIF DIGIT NINE
+1D7EC;1D7EC;1D7EC;0030;0030; # (𝟬; 𝟬; 𝟬; 0; 0; ) MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO
+1D7ED;1D7ED;1D7ED;0031;0031; # (𝟭; 𝟭; 𝟭; 1; 1; ) MATHEMATICAL SANS-SERIF BOLD DIGIT ONE
+1D7EE;1D7EE;1D7EE;0032;0032; # (𝟮; 𝟮; 𝟮; 2; 2; ) MATHEMATICAL SANS-SERIF BOLD DIGIT TWO
+1D7EF;1D7EF;1D7EF;0033;0033; # (𝟯; 𝟯; 𝟯; 3; 3; ) MATHEMATICAL SANS-SERIF BOLD DIGIT THREE
+1D7F0;1D7F0;1D7F0;0034;0034; # (𝟰; 𝟰; 𝟰; 4; 4; ) MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR
+1D7F1;1D7F1;1D7F1;0035;0035; # (𝟱; 𝟱; 𝟱; 5; 5; ) MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE
+1D7F2;1D7F2;1D7F2;0036;0036; # (𝟲; 𝟲; 𝟲; 6; 6; ) MATHEMATICAL SANS-SERIF BOLD DIGIT SIX
+1D7F3;1D7F3;1D7F3;0037;0037; # (𝟳; 𝟳; 𝟳; 7; 7; ) MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN
+1D7F4;1D7F4;1D7F4;0038;0038; # (𝟴; 𝟴; 𝟴; 8; 8; ) MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT
+1D7F5;1D7F5;1D7F5;0039;0039; # (𝟵; 𝟵; 𝟵; 9; 9; ) MATHEMATICAL SANS-SERIF BOLD DIGIT NINE
+1D7F6;1D7F6;1D7F6;0030;0030; # (𝟶; 𝟶; 𝟶; 0; 0; ) MATHEMATICAL MONOSPACE DIGIT ZERO
+1D7F7;1D7F7;1D7F7;0031;0031; # (𝟷; 𝟷; 𝟷; 1; 1; ) MATHEMATICAL MONOSPACE DIGIT ONE
+1D7F8;1D7F8;1D7F8;0032;0032; # (𝟸; 𝟸; 𝟸; 2; 2; ) MATHEMATICAL MONOSPACE DIGIT TWO
+1D7F9;1D7F9;1D7F9;0033;0033; # (𝟹; 𝟹; 𝟹; 3; 3; ) MATHEMATICAL MONOSPACE DIGIT THREE
+1D7FA;1D7FA;1D7FA;0034;0034; # (𝟺; 𝟺; 𝟺; 4; 4; ) MATHEMATICAL MONOSPACE DIGIT FOUR
+1D7FB;1D7FB;1D7FB;0035;0035; # (𝟻; 𝟻; 𝟻; 5; 5; ) MATHEMATICAL MONOSPACE DIGIT FIVE
+1D7FC;1D7FC;1D7FC;0036;0036; # (𝟼; 𝟼; 𝟼; 6; 6; ) MATHEMATICAL MONOSPACE DIGIT SIX
+1D7FD;1D7FD;1D7FD;0037;0037; # (𝟽; 𝟽; 𝟽; 7; 7; ) MATHEMATICAL MONOSPACE DIGIT SEVEN
+1D7FE;1D7FE;1D7FE;0038;0038; # (𝟾; 𝟾; 𝟾; 8; 8; ) MATHEMATICAL MONOSPACE DIGIT EIGHT
+1D7FF;1D7FF;1D7FF;0039;0039; # (𝟿; 𝟿; 𝟿; 9; 9; ) MATHEMATICAL MONOSPACE DIGIT NINE
+1EE00;1EE00;1EE00;0627;0627; # (𞸀; 𞸀; 𞸀; ا; ا; ) ARABIC MATHEMATICAL ALEF
+1EE01;1EE01;1EE01;0628;0628; # (𞸁; 𞸁; 𞸁; ب; ب; ) ARABIC MATHEMATICAL BEH
+1EE02;1EE02;1EE02;062C;062C; # (𞸂; 𞸂; 𞸂; ج; ج; ) ARABIC MATHEMATICAL JEEM
+1EE03;1EE03;1EE03;062F;062F; # (𞸃; 𞸃; 𞸃; د; د; ) ARABIC MATHEMATICAL DAL
+1EE05;1EE05;1EE05;0648;0648; # (𞸅; 𞸅; 𞸅; و; و; ) ARABIC MATHEMATICAL WAW
+1EE06;1EE06;1EE06;0632;0632; # (𞸆; 𞸆; 𞸆; ز; ز; ) ARABIC MATHEMATICAL ZAIN
+1EE07;1EE07;1EE07;062D;062D; # (𞸇; 𞸇; 𞸇; ح; ح; ) ARABIC MATHEMATICAL HAH
+1EE08;1EE08;1EE08;0637;0637; # (𞸈; 𞸈; 𞸈; ط; ط; ) ARABIC MATHEMATICAL TAH
+1EE09;1EE09;1EE09;064A;064A; # (𞸉; 𞸉; 𞸉; ي; ي; ) ARABIC MATHEMATICAL YEH
+1EE0A;1EE0A;1EE0A;0643;0643; # (𞸊; 𞸊; 𞸊; ك; ك; ) ARABIC MATHEMATICAL KAF
+1EE0B;1EE0B;1EE0B;0644;0644; # (𞸋; 𞸋; 𞸋; ل; ل; ) ARABIC MATHEMATICAL LAM
+1EE0C;1EE0C;1EE0C;0645;0645; # (𞸌; 𞸌; 𞸌; م; م; ) ARABIC MATHEMATICAL MEEM
+1EE0D;1EE0D;1EE0D;0646;0646; # (𞸍; 𞸍; 𞸍; ن; ن; ) ARABIC MATHEMATICAL NOON
+1EE0E;1EE0E;1EE0E;0633;0633; # (𞸎; 𞸎; 𞸎; س; س; ) ARABIC MATHEMATICAL SEEN
+1EE0F;1EE0F;1EE0F;0639;0639; # (𞸏; 𞸏; 𞸏; ع; ع; ) ARABIC MATHEMATICAL AIN
+1EE10;1EE10;1EE10;0641;0641; # (𞸐; 𞸐; 𞸐; ف; ف; ) ARABIC MATHEMATICAL FEH
+1EE11;1EE11;1EE11;0635;0635; # (𞸑; 𞸑; 𞸑; ص; ص; ) ARABIC MATHEMATICAL SAD
+1EE12;1EE12;1EE12;0642;0642; # (𞸒; 𞸒; 𞸒; ق; ق; ) ARABIC MATHEMATICAL QAF
+1EE13;1EE13;1EE13;0631;0631; # (𞸓; 𞸓; 𞸓; ر; ر; ) ARABIC MATHEMATICAL REH
+1EE14;1EE14;1EE14;0634;0634; # (𞸔; 𞸔; 𞸔; ش; ش; ) ARABIC MATHEMATICAL SHEEN
+1EE15;1EE15;1EE15;062A;062A; # (𞸕; 𞸕; 𞸕; ت; ت; ) ARABIC MATHEMATICAL TEH
+1EE16;1EE16;1EE16;062B;062B; # (𞸖; 𞸖; 𞸖; ث; ث; ) ARABIC MATHEMATICAL THEH
+1EE17;1EE17;1EE17;062E;062E; # (𞸗; 𞸗; 𞸗; خ; خ; ) ARABIC MATHEMATICAL KHAH
+1EE18;1EE18;1EE18;0630;0630; # (𞸘; 𞸘; 𞸘; ذ; ذ; ) ARABIC MATHEMATICAL THAL
+1EE19;1EE19;1EE19;0636;0636; # (𞸙; 𞸙; 𞸙; ض; ض; ) ARABIC MATHEMATICAL DAD
+1EE1A;1EE1A;1EE1A;0638;0638; # (𞸚; 𞸚; 𞸚; ظ; ظ; ) ARABIC MATHEMATICAL ZAH
+1EE1B;1EE1B;1EE1B;063A;063A; # (𞸛; 𞸛; 𞸛; غ; غ; ) ARABIC MATHEMATICAL GHAIN
+1EE1C;1EE1C;1EE1C;066E;066E; # (𞸜; 𞸜; 𞸜; ٮ; ٮ; ) ARABIC MATHEMATICAL DOTLESS BEH
+1EE1D;1EE1D;1EE1D;06BA;06BA; # (𞸝; 𞸝; 𞸝; ں; ں; ) ARABIC MATHEMATICAL DOTLESS NOON
+1EE1E;1EE1E;1EE1E;06A1;06A1; # (𞸞; 𞸞; 𞸞; ڡ; ڡ; ) ARABIC MATHEMATICAL DOTLESS FEH
+1EE1F;1EE1F;1EE1F;066F;066F; # (𞸟; 𞸟; 𞸟; ٯ; ٯ; ) ARABIC MATHEMATICAL DOTLESS QAF
+1EE21;1EE21;1EE21;0628;0628; # (𞸡; 𞸡; 𞸡; ب; ب; ) ARABIC MATHEMATICAL INITIAL BEH
+1EE22;1EE22;1EE22;062C;062C; # (𞸢; 𞸢; 𞸢; ج; ج; ) ARABIC MATHEMATICAL INITIAL JEEM
+1EE24;1EE24;1EE24;0647;0647; # (𞸤; 𞸤; 𞸤; ه; ه; ) ARABIC MATHEMATICAL INITIAL HEH
+1EE27;1EE27;1EE27;062D;062D; # (𞸧; 𞸧; 𞸧; ح; ح; ) ARABIC MATHEMATICAL INITIAL HAH
+1EE29;1EE29;1EE29;064A;064A; # (𞸩; 𞸩; 𞸩; ي; ي; ) ARABIC MATHEMATICAL INITIAL YEH
+1EE2A;1EE2A;1EE2A;0643;0643; # (𞸪; 𞸪; 𞸪; ك; ك; ) ARABIC MATHEMATICAL INITIAL KAF
+1EE2B;1EE2B;1EE2B;0644;0644; # (𞸫; 𞸫; 𞸫; ل; ل; ) ARABIC MATHEMATICAL INITIAL LAM
+1EE2C;1EE2C;1EE2C;0645;0645; # (𞸬; 𞸬; 𞸬; م; م; ) ARABIC MATHEMATICAL INITIAL MEEM
+1EE2D;1EE2D;1EE2D;0646;0646; # (𞸭; 𞸭; 𞸭; ن; ن; ) ARABIC MATHEMATICAL INITIAL NOON
+1EE2E;1EE2E;1EE2E;0633;0633; # (𞸮; 𞸮; 𞸮; س; س; ) ARABIC MATHEMATICAL INITIAL SEEN
+1EE2F;1EE2F;1EE2F;0639;0639; # (𞸯; 𞸯; 𞸯; ع; ع; ) ARABIC MATHEMATICAL INITIAL AIN
+1EE30;1EE30;1EE30;0641;0641; # (𞸰; 𞸰; 𞸰; ف; ف; ) ARABIC MATHEMATICAL INITIAL FEH
+1EE31;1EE31;1EE31;0635;0635; # (𞸱; 𞸱; 𞸱; ص; ص; ) ARABIC MATHEMATICAL INITIAL SAD
+1EE32;1EE32;1EE32;0642;0642; # (𞸲; 𞸲; 𞸲; ق; ق; ) ARABIC MATHEMATICAL INITIAL QAF
+1EE34;1EE34;1EE34;0634;0634; # (𞸴; 𞸴; 𞸴; ش; ش; ) ARABIC MATHEMATICAL INITIAL SHEEN
+1EE35;1EE35;1EE35;062A;062A; # (𞸵; 𞸵; 𞸵; ت; ت; ) ARABIC MATHEMATICAL INITIAL TEH
+1EE36;1EE36;1EE36;062B;062B; # (𞸶; 𞸶; 𞸶; ث; ث; ) ARABIC MATHEMATICAL INITIAL THEH
+1EE37;1EE37;1EE37;062E;062E; # (𞸷; 𞸷; 𞸷; خ; خ; ) ARABIC MATHEMATICAL INITIAL KHAH
+1EE39;1EE39;1EE39;0636;0636; # (𞸹; 𞸹; 𞸹; ض; ض; ) ARABIC MATHEMATICAL INITIAL DAD
+1EE3B;1EE3B;1EE3B;063A;063A; # (𞸻; 𞸻; 𞸻; غ; غ; ) ARABIC MATHEMATICAL INITIAL GHAIN
+1EE42;1EE42;1EE42;062C;062C; # (𞹂; 𞹂; 𞹂; ج; ج; ) ARABIC MATHEMATICAL TAILED JEEM
+1EE47;1EE47;1EE47;062D;062D; # (𞹇; 𞹇; 𞹇; ح; ح; ) ARABIC MATHEMATICAL TAILED HAH
+1EE49;1EE49;1EE49;064A;064A; # (𞹉; 𞹉; 𞹉; ي; ي; ) ARABIC MATHEMATICAL TAILED YEH
+1EE4B;1EE4B;1EE4B;0644;0644; # (𞹋; 𞹋; 𞹋; ل; ل; ) ARABIC MATHEMATICAL TAILED LAM
+1EE4D;1EE4D;1EE4D;0646;0646; # (𞹍; 𞹍; 𞹍; ن; ن; ) ARABIC MATHEMATICAL TAILED NOON
+1EE4E;1EE4E;1EE4E;0633;0633; # (𞹎; 𞹎; 𞹎; س; س; ) ARABIC MATHEMATICAL TAILED SEEN
+1EE4F;1EE4F;1EE4F;0639;0639; # (𞹏; 𞹏; 𞹏; ع; ع; ) ARABIC MATHEMATICAL TAILED AIN
+1EE51;1EE51;1EE51;0635;0635; # (𞹑; 𞹑; 𞹑; ص; ص; ) ARABIC MATHEMATICAL TAILED SAD
+1EE52;1EE52;1EE52;0642;0642; # (𞹒; 𞹒; 𞹒; ق; ق; ) ARABIC MATHEMATICAL TAILED QAF
+1EE54;1EE54;1EE54;0634;0634; # (𞹔; 𞹔; 𞹔; ش; ش; ) ARABIC MATHEMATICAL TAILED SHEEN
+1EE57;1EE57;1EE57;062E;062E; # (𞹗; 𞹗; 𞹗; خ; خ; ) ARABIC MATHEMATICAL TAILED KHAH
+1EE59;1EE59;1EE59;0636;0636; # (𞹙; 𞹙; 𞹙; ض; ض; ) ARABIC MATHEMATICAL TAILED DAD
+1EE5B;1EE5B;1EE5B;063A;063A; # (𞹛; 𞹛; 𞹛; غ; غ; ) ARABIC MATHEMATICAL TAILED GHAIN
+1EE5D;1EE5D;1EE5D;06BA;06BA; # (𞹝; 𞹝; 𞹝; ں; ں; ) ARABIC MATHEMATICAL TAILED DOTLESS NOON
+1EE5F;1EE5F;1EE5F;066F;066F; # (𞹟; 𞹟; 𞹟; ٯ; ٯ; ) ARABIC MATHEMATICAL TAILED DOTLESS QAF
+1EE61;1EE61;1EE61;0628;0628; # (𞹡; 𞹡; 𞹡; ب; ب; ) ARABIC MATHEMATICAL STRETCHED BEH
+1EE62;1EE62;1EE62;062C;062C; # (𞹢; 𞹢; 𞹢; ج; ج; ) ARABIC MATHEMATICAL STRETCHED JEEM
+1EE64;1EE64;1EE64;0647;0647; # (𞹤; 𞹤; 𞹤; ه; ه; ) ARABIC MATHEMATICAL STRETCHED HEH
+1EE67;1EE67;1EE67;062D;062D; # (𞹧; 𞹧; 𞹧; ح; ح; ) ARABIC MATHEMATICAL STRETCHED HAH
+1EE68;1EE68;1EE68;0637;0637; # (𞹨; 𞹨; 𞹨; ط; ط; ) ARABIC MATHEMATICAL STRETCHED TAH
+1EE69;1EE69;1EE69;064A;064A; # (𞹩; 𞹩; 𞹩; ي; ي; ) ARABIC MATHEMATICAL STRETCHED YEH
+1EE6A;1EE6A;1EE6A;0643;0643; # (𞹪; 𞹪; 𞹪; ك; ك; ) ARABIC MATHEMATICAL STRETCHED KAF
+1EE6C;1EE6C;1EE6C;0645;0645; # (𞹬; 𞹬; 𞹬; م; م; ) ARABIC MATHEMATICAL STRETCHED MEEM
+1EE6D;1EE6D;1EE6D;0646;0646; # (𞹭; 𞹭; 𞹭; ن; ن; ) ARABIC MATHEMATICAL STRETCHED NOON
+1EE6E;1EE6E;1EE6E;0633;0633; # (𞹮; 𞹮; 𞹮; س; س; ) ARABIC MATHEMATICAL STRETCHED SEEN
+1EE6F;1EE6F;1EE6F;0639;0639; # (𞹯; 𞹯; 𞹯; ع; ع; ) ARABIC MATHEMATICAL STRETCHED AIN
+1EE70;1EE70;1EE70;0641;0641; # (𞹰; 𞹰; 𞹰; ف; ف; ) ARABIC MATHEMATICAL STRETCHED FEH
+1EE71;1EE71;1EE71;0635;0635; # (𞹱; 𞹱; 𞹱; ص; ص; ) ARABIC MATHEMATICAL STRETCHED SAD
+1EE72;1EE72;1EE72;0642;0642; # (𞹲; 𞹲; 𞹲; ق; ق; ) ARABIC MATHEMATICAL STRETCHED QAF
+1EE74;1EE74;1EE74;0634;0634; # (𞹴; 𞹴; 𞹴; ش; ش; ) ARABIC MATHEMATICAL STRETCHED SHEEN
+1EE75;1EE75;1EE75;062A;062A; # (𞹵; 𞹵; 𞹵; ت; ت; ) ARABIC MATHEMATICAL STRETCHED TEH
+1EE76;1EE76;1EE76;062B;062B; # (𞹶; 𞹶; 𞹶; ث; ث; ) ARABIC MATHEMATICAL STRETCHED THEH
+1EE77;1EE77;1EE77;062E;062E; # (𞹷; 𞹷; 𞹷; خ; خ; ) ARABIC MATHEMATICAL STRETCHED KHAH
+1EE79;1EE79;1EE79;0636;0636; # (𞹹; 𞹹; 𞹹; ض; ض; ) ARABIC MATHEMATICAL STRETCHED DAD
+1EE7A;1EE7A;1EE7A;0638;0638; # (𞹺; 𞹺; 𞹺; ظ; ظ; ) ARABIC MATHEMATICAL STRETCHED ZAH
+1EE7B;1EE7B;1EE7B;063A;063A; # (𞹻; 𞹻; 𞹻; غ; غ; ) ARABIC MATHEMATICAL STRETCHED GHAIN
+1EE7C;1EE7C;1EE7C;066E;066E; # (𞹼; 𞹼; 𞹼; ٮ; ٮ; ) ARABIC MATHEMATICAL STRETCHED DOTLESS BEH
+1EE7E;1EE7E;1EE7E;06A1;06A1; # (𞹾; 𞹾; 𞹾; ڡ; ڡ; ) ARABIC MATHEMATICAL STRETCHED DOTLESS FEH
+1EE80;1EE80;1EE80;0627;0627; # (𞺀; 𞺀; 𞺀; ا; ا; ) ARABIC MATHEMATICAL LOOPED ALEF
+1EE81;1EE81;1EE81;0628;0628; # (𞺁; 𞺁; 𞺁; ب; ب; ) ARABIC MATHEMATICAL LOOPED BEH
+1EE82;1EE82;1EE82;062C;062C; # (𞺂; 𞺂; 𞺂; ج; ج; ) ARABIC MATHEMATICAL LOOPED JEEM
+1EE83;1EE83;1EE83;062F;062F; # (𞺃; 𞺃; 𞺃; د; د; ) ARABIC MATHEMATICAL LOOPED DAL
+1EE84;1EE84;1EE84;0647;0647; # (𞺄; 𞺄; 𞺄; ه; ه; ) ARABIC MATHEMATICAL LOOPED HEH
+1EE85;1EE85;1EE85;0648;0648; # (𞺅; 𞺅; 𞺅; و; و; ) ARABIC MATHEMATICAL LOOPED WAW
+1EE86;1EE86;1EE86;0632;0632; # (𞺆; 𞺆; 𞺆; ز; ز; ) ARABIC MATHEMATICAL LOOPED ZAIN
+1EE87;1EE87;1EE87;062D;062D; # (𞺇; 𞺇; 𞺇; ح; ح; ) ARABIC MATHEMATICAL LOOPED HAH
+1EE88;1EE88;1EE88;0637;0637; # (𞺈; 𞺈; 𞺈; ط; ط; ) ARABIC MATHEMATICAL LOOPED TAH
+1EE89;1EE89;1EE89;064A;064A; # (𞺉; 𞺉; 𞺉; ي; ي; ) ARABIC MATHEMATICAL LOOPED YEH
+1EE8B;1EE8B;1EE8B;0644;0644; # (𞺋; 𞺋; 𞺋; ل; ل; ) ARABIC MATHEMATICAL LOOPED LAM
+1EE8C;1EE8C;1EE8C;0645;0645; # (𞺌; 𞺌; 𞺌; م; م; ) ARABIC MATHEMATICAL LOOPED MEEM
+1EE8D;1EE8D;1EE8D;0646;0646; # (𞺍; 𞺍; 𞺍; ن; ن; ) ARABIC MATHEMATICAL LOOPED NOON
+1EE8E;1EE8E;1EE8E;0633;0633; # (𞺎; 𞺎; 𞺎; س; س; ) ARABIC MATHEMATICAL LOOPED SEEN
+1EE8F;1EE8F;1EE8F;0639;0639; # (𞺏; 𞺏; 𞺏; ع; ع; ) ARABIC MATHEMATICAL LOOPED AIN
+1EE90;1EE90;1EE90;0641;0641; # (𞺐; 𞺐; 𞺐; ف; ف; ) ARABIC MATHEMATICAL LOOPED FEH
+1EE91;1EE91;1EE91;0635;0635; # (𞺑; 𞺑; 𞺑; ص; ص; ) ARABIC MATHEMATICAL LOOPED SAD
+1EE92;1EE92;1EE92;0642;0642; # (𞺒; 𞺒; 𞺒; ق; ق; ) ARABIC MATHEMATICAL LOOPED QAF
+1EE93;1EE93;1EE93;0631;0631; # (𞺓; 𞺓; 𞺓; ر; ر; ) ARABIC MATHEMATICAL LOOPED REH
+1EE94;1EE94;1EE94;0634;0634; # (𞺔; 𞺔; 𞺔; ش; ش; ) ARABIC MATHEMATICAL LOOPED SHEEN
+1EE95;1EE95;1EE95;062A;062A; # (𞺕; 𞺕; 𞺕; ت; ت; ) ARABIC MATHEMATICAL LOOPED TEH
+1EE96;1EE96;1EE96;062B;062B; # (𞺖; 𞺖; 𞺖; ث; ث; ) ARABIC MATHEMATICAL LOOPED THEH
+1EE97;1EE97;1EE97;062E;062E; # (𞺗; 𞺗; 𞺗; خ; خ; ) ARABIC MATHEMATICAL LOOPED KHAH
+1EE98;1EE98;1EE98;0630;0630; # (𞺘; 𞺘; 𞺘; ذ; ذ; ) ARABIC MATHEMATICAL LOOPED THAL
+1EE99;1EE99;1EE99;0636;0636; # (𞺙; 𞺙; 𞺙; ض; ض; ) ARABIC MATHEMATICAL LOOPED DAD
+1EE9A;1EE9A;1EE9A;0638;0638; # (𞺚; 𞺚; 𞺚; ظ; ظ; ) ARABIC MATHEMATICAL LOOPED ZAH
+1EE9B;1EE9B;1EE9B;063A;063A; # (𞺛; 𞺛; 𞺛; غ; غ; ) ARABIC MATHEMATICAL LOOPED GHAIN
+1EEA1;1EEA1;1EEA1;0628;0628; # (𞺡; 𞺡; 𞺡; ب; ب; ) ARABIC MATHEMATICAL DOUBLE-STRUCK BEH
+1EEA2;1EEA2;1EEA2;062C;062C; # (𞺢; 𞺢; 𞺢; ج; ج; ) ARABIC MATHEMATICAL DOUBLE-STRUCK JEEM
+1EEA3;1EEA3;1EEA3;062F;062F; # (𞺣; 𞺣; 𞺣; د; د; ) ARABIC MATHEMATICAL DOUBLE-STRUCK DAL
+1EEA5;1EEA5;1EEA5;0648;0648; # (𞺥; 𞺥; 𞺥; و; و; ) ARABIC MATHEMATICAL DOUBLE-STRUCK WAW
+1EEA6;1EEA6;1EEA6;0632;0632; # (𞺦; 𞺦; 𞺦; ز; ز; ) ARABIC MATHEMATICAL DOUBLE-STRUCK ZAIN
+1EEA7;1EEA7;1EEA7;062D;062D; # (𞺧; 𞺧; 𞺧; ح; ح; ) ARABIC MATHEMATICAL DOUBLE-STRUCK HAH
+1EEA8;1EEA8;1EEA8;0637;0637; # (𞺨; 𞺨; 𞺨; ط; ط; ) ARABIC MATHEMATICAL DOUBLE-STRUCK TAH
+1EEA9;1EEA9;1EEA9;064A;064A; # (𞺩; 𞺩; 𞺩; ي; ي; ) ARABIC MATHEMATICAL DOUBLE-STRUCK YEH
+1EEAB;1EEAB;1EEAB;0644;0644; # (𞺫; 𞺫; 𞺫; ل; ل; ) ARABIC MATHEMATICAL DOUBLE-STRUCK LAM
+1EEAC;1EEAC;1EEAC;0645;0645; # (𞺬; 𞺬; 𞺬; م; م; ) ARABIC MATHEMATICAL DOUBLE-STRUCK MEEM
+1EEAD;1EEAD;1EEAD;0646;0646; # (𞺭; 𞺭; 𞺭; ن; ن; ) ARABIC MATHEMATICAL DOUBLE-STRUCK NOON
+1EEAE;1EEAE;1EEAE;0633;0633; # (𞺮; 𞺮; 𞺮; س; س; ) ARABIC MATHEMATICAL DOUBLE-STRUCK SEEN
+1EEAF;1EEAF;1EEAF;0639;0639; # (𞺯; 𞺯; 𞺯; ع; ع; ) ARABIC MATHEMATICAL DOUBLE-STRUCK AIN
+1EEB0;1EEB0;1EEB0;0641;0641; # (𞺰; 𞺰; 𞺰; ف; ف; ) ARABIC MATHEMATICAL DOUBLE-STRUCK FEH
+1EEB1;1EEB1;1EEB1;0635;0635; # (𞺱; 𞺱; 𞺱; ص; ص; ) ARABIC MATHEMATICAL DOUBLE-STRUCK SAD
+1EEB2;1EEB2;1EEB2;0642;0642; # (𞺲; 𞺲; 𞺲; ق; ق; ) ARABIC MATHEMATICAL DOUBLE-STRUCK QAF
+1EEB3;1EEB3;1EEB3;0631;0631; # (𞺳; 𞺳; 𞺳; ر; ر; ) ARABIC MATHEMATICAL DOUBLE-STRUCK REH
+1EEB4;1EEB4;1EEB4;0634;0634; # (𞺴; 𞺴; 𞺴; ش; ش; ) ARABIC MATHEMATICAL DOUBLE-STRUCK SHEEN
+1EEB5;1EEB5;1EEB5;062A;062A; # (𞺵; 𞺵; 𞺵; ت; ت; ) ARABIC MATHEMATICAL DOUBLE-STRUCK TEH
+1EEB6;1EEB6;1EEB6;062B;062B; # (𞺶; 𞺶; 𞺶; ث; ث; ) ARABIC MATHEMATICAL DOUBLE-STRUCK THEH
+1EEB7;1EEB7;1EEB7;062E;062E; # (𞺷; 𞺷; 𞺷; خ; خ; ) ARABIC MATHEMATICAL DOUBLE-STRUCK KHAH
+1EEB8;1EEB8;1EEB8;0630;0630; # (𞺸; 𞺸; 𞺸; ذ; ذ; ) ARABIC MATHEMATICAL DOUBLE-STRUCK THAL
+1EEB9;1EEB9;1EEB9;0636;0636; # (𞺹; 𞺹; 𞺹; ض; ض; ) ARABIC MATHEMATICAL DOUBLE-STRUCK DAD
+1EEBA;1EEBA;1EEBA;0638;0638; # (𞺺; 𞺺; 𞺺; ظ; ظ; ) ARABIC MATHEMATICAL DOUBLE-STRUCK ZAH
+1EEBB;1EEBB;1EEBB;063A;063A; # (𞺻; 𞺻; 𞺻; غ; غ; ) ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
+1F100;1F100;1F100;0030 002E;0030 002E; # (🄀; 🄀; 🄀; 0.; 0.; ) DIGIT ZERO FULL STOP
+1F101;1F101;1F101;0030 002C;0030 002C; # (🄁; 🄁; 🄁; 0,; 0,; ) DIGIT ZERO COMMA
+1F102;1F102;1F102;0031 002C;0031 002C; # (🄂; 🄂; 🄂; 1,; 1,; ) DIGIT ONE COMMA
+1F103;1F103;1F103;0032 002C;0032 002C; # (🄃; 🄃; 🄃; 2,; 2,; ) DIGIT TWO COMMA
+1F104;1F104;1F104;0033 002C;0033 002C; # (🄄; 🄄; 🄄; 3,; 3,; ) DIGIT THREE COMMA
+1F105;1F105;1F105;0034 002C;0034 002C; # (🄅; 🄅; 🄅; 4,; 4,; ) DIGIT FOUR COMMA
+1F106;1F106;1F106;0035 002C;0035 002C; # (🄆; 🄆; 🄆; 5,; 5,; ) DIGIT FIVE COMMA
+1F107;1F107;1F107;0036 002C;0036 002C; # (🄇; 🄇; 🄇; 6,; 6,; ) DIGIT SIX COMMA
+1F108;1F108;1F108;0037 002C;0037 002C; # (🄈; 🄈; 🄈; 7,; 7,; ) DIGIT SEVEN COMMA
+1F109;1F109;1F109;0038 002C;0038 002C; # (🄉; 🄉; 🄉; 8,; 8,; ) DIGIT EIGHT COMMA
+1F10A;1F10A;1F10A;0039 002C;0039 002C; # (🄊; 🄊; 🄊; 9,; 9,; ) DIGIT NINE COMMA
+1F110;1F110;1F110;0028 0041 0029;0028 0041 0029; # (🄐; 🄐; 🄐; (A); (A); ) PARENTHESIZED LATIN CAPITAL LETTER A
+1F111;1F111;1F111;0028 0042 0029;0028 0042 0029; # (🄑; 🄑; 🄑; (B); (B); ) PARENTHESIZED LATIN CAPITAL LETTER B
+1F112;1F112;1F112;0028 0043 0029;0028 0043 0029; # (🄒; 🄒; 🄒; (C); (C); ) PARENTHESIZED LATIN CAPITAL LETTER C
+1F113;1F113;1F113;0028 0044 0029;0028 0044 0029; # (🄓; 🄓; 🄓; (D); (D); ) PARENTHESIZED LATIN CAPITAL LETTER D
+1F114;1F114;1F114;0028 0045 0029;0028 0045 0029; # (🄔; 🄔; 🄔; (E); (E); ) PARENTHESIZED LATIN CAPITAL LETTER E
+1F115;1F115;1F115;0028 0046 0029;0028 0046 0029; # (🄕; 🄕; 🄕; (F); (F); ) PARENTHESIZED LATIN CAPITAL LETTER F
+1F116;1F116;1F116;0028 0047 0029;0028 0047 0029; # (🄖; 🄖; 🄖; (G); (G); ) PARENTHESIZED LATIN CAPITAL LETTER G
+1F117;1F117;1F117;0028 0048 0029;0028 0048 0029; # (🄗; 🄗; 🄗; (H); (H); ) PARENTHESIZED LATIN CAPITAL LETTER H
+1F118;1F118;1F118;0028 0049 0029;0028 0049 0029; # (🄘; 🄘; 🄘; (I); (I); ) PARENTHESIZED LATIN CAPITAL LETTER I
+1F119;1F119;1F119;0028 004A 0029;0028 004A 0029; # (🄙; 🄙; 🄙; (J); (J); ) PARENTHESIZED LATIN CAPITAL LETTER J
+1F11A;1F11A;1F11A;0028 004B 0029;0028 004B 0029; # (🄚; 🄚; 🄚; (K); (K); ) PARENTHESIZED LATIN CAPITAL LETTER K
+1F11B;1F11B;1F11B;0028 004C 0029;0028 004C 0029; # (🄛; 🄛; 🄛; (L); (L); ) PARENTHESIZED LATIN CAPITAL LETTER L
+1F11C;1F11C;1F11C;0028 004D 0029;0028 004D 0029; # (🄜; 🄜; 🄜; (M); (M); ) PARENTHESIZED LATIN CAPITAL LETTER M
+1F11D;1F11D;1F11D;0028 004E 0029;0028 004E 0029; # (🄝; 🄝; 🄝; (N); (N); ) PARENTHESIZED LATIN CAPITAL LETTER N
+1F11E;1F11E;1F11E;0028 004F 0029;0028 004F 0029; # (🄞; 🄞; 🄞; (O); (O); ) PARENTHESIZED LATIN CAPITAL LETTER O
+1F11F;1F11F;1F11F;0028 0050 0029;0028 0050 0029; # (🄟; 🄟; 🄟; (P); (P); ) PARENTHESIZED LATIN CAPITAL LETTER P
+1F120;1F120;1F120;0028 0051 0029;0028 0051 0029; # (🄠; 🄠; 🄠; (Q); (Q); ) PARENTHESIZED LATIN CAPITAL LETTER Q
+1F121;1F121;1F121;0028 0052 0029;0028 0052 0029; # (🄡; 🄡; 🄡; (R); (R); ) PARENTHESIZED LATIN CAPITAL LETTER R
+1F122;1F122;1F122;0028 0053 0029;0028 0053 0029; # (🄢; 🄢; 🄢; (S); (S); ) PARENTHESIZED LATIN CAPITAL LETTER S
+1F123;1F123;1F123;0028 0054 0029;0028 0054 0029; # (🄣; 🄣; 🄣; (T); (T); ) PARENTHESIZED LATIN CAPITAL LETTER T
+1F124;1F124;1F124;0028 0055 0029;0028 0055 0029; # (🄤; 🄤; 🄤; (U); (U); ) PARENTHESIZED LATIN CAPITAL LETTER U
+1F125;1F125;1F125;0028 0056 0029;0028 0056 0029; # (🄥; 🄥; 🄥; (V); (V); ) PARENTHESIZED LATIN CAPITAL LETTER V
+1F126;1F126;1F126;0028 0057 0029;0028 0057 0029; # (🄦; 🄦; 🄦; (W); (W); ) PARENTHESIZED LATIN CAPITAL LETTER W
+1F127;1F127;1F127;0028 0058 0029;0028 0058 0029; # (🄧; 🄧; 🄧; (X); (X); ) PARENTHESIZED LATIN CAPITAL LETTER X
+1F128;1F128;1F128;0028 0059 0029;0028 0059 0029; # (🄨; 🄨; 🄨; (Y); (Y); ) PARENTHESIZED LATIN CAPITAL LETTER Y
+1F129;1F129;1F129;0028 005A 0029;0028 005A 0029; # (🄩; 🄩; 🄩; (Z); (Z); ) PARENTHESIZED LATIN CAPITAL LETTER Z
+1F12A;1F12A;1F12A;3014 0053 3015;3014 0053 3015; # (🄪; 🄪; 🄪; 〔S〕; 〔S〕; ) TORTOISE SHELL BRACKETED LATIN CAPITAL LETTER S
+1F12B;1F12B;1F12B;0043;0043; # (🄫; 🄫; 🄫; C; C; ) CIRCLED ITALIC LATIN CAPITAL LETTER C
+1F12C;1F12C;1F12C;0052;0052; # (🄬; 🄬; 🄬; R; R; ) CIRCLED ITALIC LATIN CAPITAL LETTER R
+1F12D;1F12D;1F12D;0043 0044;0043 0044; # (🄭; 🄭; 🄭; CD; CD; ) CIRCLED CD
+1F12E;1F12E;1F12E;0057 005A;0057 005A; # (🄮; 🄮; 🄮; WZ; WZ; ) CIRCLED WZ
+1F130;1F130;1F130;0041;0041; # (🄰; 🄰; 🄰; A; A; ) SQUARED LATIN CAPITAL LETTER A
+1F131;1F131;1F131;0042;0042; # (🄱; 🄱; 🄱; B; B; ) SQUARED LATIN CAPITAL LETTER B
+1F132;1F132;1F132;0043;0043; # (🄲; 🄲; 🄲; C; C; ) SQUARED LATIN CAPITAL LETTER C
+1F133;1F133;1F133;0044;0044; # (🄳; 🄳; 🄳; D; D; ) SQUARED LATIN CAPITAL LETTER D
+1F134;1F134;1F134;0045;0045; # (🄴; 🄴; 🄴; E; E; ) SQUARED LATIN CAPITAL LETTER E
+1F135;1F135;1F135;0046;0046; # (🄵; 🄵; 🄵; F; F; ) SQUARED LATIN CAPITAL LETTER F
+1F136;1F136;1F136;0047;0047; # (🄶; 🄶; 🄶; G; G; ) SQUARED LATIN CAPITAL LETTER G
+1F137;1F137;1F137;0048;0048; # (🄷; 🄷; 🄷; H; H; ) SQUARED LATIN CAPITAL LETTER H
+1F138;1F138;1F138;0049;0049; # (🄸; 🄸; 🄸; I; I; ) SQUARED LATIN CAPITAL LETTER I
+1F139;1F139;1F139;004A;004A; # (🄹; 🄹; 🄹; J; J; ) SQUARED LATIN CAPITAL LETTER J
+1F13A;1F13A;1F13A;004B;004B; # (🄺; 🄺; 🄺; K; K; ) SQUARED LATIN CAPITAL LETTER K
+1F13B;1F13B;1F13B;004C;004C; # (🄻; 🄻; 🄻; L; L; ) SQUARED LATIN CAPITAL LETTER L
+1F13C;1F13C;1F13C;004D;004D; # (🄼; 🄼; 🄼; M; M; ) SQUARED LATIN CAPITAL LETTER M
+1F13D;1F13D;1F13D;004E;004E; # (🄽; 🄽; 🄽; N; N; ) SQUARED LATIN CAPITAL LETTER N
+1F13E;1F13E;1F13E;004F;004F; # (🄾; 🄾; 🄾; O; O; ) SQUARED LATIN CAPITAL LETTER O
+1F13F;1F13F;1F13F;0050;0050; # (🄿; 🄿; 🄿; P; P; ) SQUARED LATIN CAPITAL LETTER P
+1F140;1F140;1F140;0051;0051; # (🅀; 🅀; 🅀; Q; Q; ) SQUARED LATIN CAPITAL LETTER Q
+1F141;1F141;1F141;0052;0052; # (🅁; 🅁; 🅁; R; R; ) SQUARED LATIN CAPITAL LETTER R
+1F142;1F142;1F142;0053;0053; # (🅂; 🅂; 🅂; S; S; ) SQUARED LATIN CAPITAL LETTER S
+1F143;1F143;1F143;0054;0054; # (🅃; 🅃; 🅃; T; T; ) SQUARED LATIN CAPITAL LETTER T
+1F144;1F144;1F144;0055;0055; # (🅄; 🅄; 🅄; U; U; ) SQUARED LATIN CAPITAL LETTER U
+1F145;1F145;1F145;0056;0056; # (🅅; 🅅; 🅅; V; V; ) SQUARED LATIN CAPITAL LETTER V
+1F146;1F146;1F146;0057;0057; # (🅆; 🅆; 🅆; W; W; ) SQUARED LATIN CAPITAL LETTER W
+1F147;1F147;1F147;0058;0058; # (🅇; 🅇; 🅇; X; X; ) SQUARED LATIN CAPITAL LETTER X
+1F148;1F148;1F148;0059;0059; # (🅈; 🅈; 🅈; Y; Y; ) SQUARED LATIN CAPITAL LETTER Y
+1F149;1F149;1F149;005A;005A; # (🅉; 🅉; 🅉; Z; Z; ) SQUARED LATIN CAPITAL LETTER Z
+1F14A;1F14A;1F14A;0048 0056;0048 0056; # (🅊; 🅊; 🅊; HV; HV; ) SQUARED HV
+1F14B;1F14B;1F14B;004D 0056;004D 0056; # (🅋; 🅋; 🅋; MV; MV; ) SQUARED MV
+1F14C;1F14C;1F14C;0053 0044;0053 0044; # (🅌; 🅌; 🅌; SD; SD; ) SQUARED SD
+1F14D;1F14D;1F14D;0053 0053;0053 0053; # (🅍; 🅍; 🅍; SS; SS; ) SQUARED SS
+1F14E;1F14E;1F14E;0050 0050 0056;0050 0050 0056; # (🅎; 🅎; 🅎; PPV; PPV; ) SQUARED PPV
+1F14F;1F14F;1F14F;0057 0043;0057 0043; # (🅏; 🅏; 🅏; WC; WC; ) SQUARED WC
+1F16A;1F16A;1F16A;004D 0043;004D 0043; # (🅪; 🅪; 🅪; MC; MC; ) RAISED MC SIGN
+1F16B;1F16B;1F16B;004D 0044;004D 0044; # (🅫; 🅫; 🅫; MD; MD; ) RAISED MD SIGN
+1F190;1F190;1F190;0044 004A;0044 004A; # (🆐; 🆐; 🆐; DJ; DJ; ) SQUARE DJ
+1F200;1F200;1F200;307B 304B;307B 304B; # (🈀; 🈀; 🈀; ほか; ほか; ) SQUARE HIRAGANA HOKA
+1F201;1F201;1F201;30B3 30B3;30B3 30B3; # (🈁; 🈁; 🈁; ココ; ココ; ) SQUARED KATAKANA KOKO
+1F202;1F202;1F202;30B5;30B5; # (🈂; 🈂; 🈂; サ; サ; ) SQUARED KATAKANA SA
+1F210;1F210;1F210;624B;624B; # (🈐; 🈐; 🈐; 手; 手; ) SQUARED CJK UNIFIED IDEOGRAPH-624B
+1F211;1F211;1F211;5B57;5B57; # (🈑; 🈑; 🈑; 字; 字; ) SQUARED CJK UNIFIED IDEOGRAPH-5B57
+1F212;1F212;1F212;53CC;53CC; # (🈒; 🈒; 🈒; 双; 双; ) SQUARED CJK UNIFIED IDEOGRAPH-53CC
+1F213;1F213;1F213;30C7;30C6 3099; # (🈓; 🈓; 🈓; デ; テ◌゙; ) SQUARED KATAKANA DE
+1F214;1F214;1F214;4E8C;4E8C; # (🈔; 🈔; 🈔; 二; 二; ) SQUARED CJK UNIFIED IDEOGRAPH-4E8C
+1F215;1F215;1F215;591A;591A; # (🈕; 🈕; 🈕; 多; 多; ) SQUARED CJK UNIFIED IDEOGRAPH-591A
+1F216;1F216;1F216;89E3;89E3; # (🈖; 🈖; 🈖; 解; 解; ) SQUARED CJK UNIFIED IDEOGRAPH-89E3
+1F217;1F217;1F217;5929;5929; # (🈗; 🈗; 🈗; 天; 天; ) SQUARED CJK UNIFIED IDEOGRAPH-5929
+1F218;1F218;1F218;4EA4;4EA4; # (🈘; 🈘; 🈘; 交; 交; ) SQUARED CJK UNIFIED IDEOGRAPH-4EA4
+1F219;1F219;1F219;6620;6620; # (🈙; 🈙; 🈙; 映; 映; ) SQUARED CJK UNIFIED IDEOGRAPH-6620
+1F21A;1F21A;1F21A;7121;7121; # (🈚; 🈚; 🈚; 無; 無; ) SQUARED CJK UNIFIED IDEOGRAPH-7121
+1F21B;1F21B;1F21B;6599;6599; # (🈛; 🈛; 🈛; 料; 料; ) SQUARED CJK UNIFIED IDEOGRAPH-6599
+1F21C;1F21C;1F21C;524D;524D; # (🈜; 🈜; 🈜; 前; 前; ) SQUARED CJK UNIFIED IDEOGRAPH-524D
+1F21D;1F21D;1F21D;5F8C;5F8C; # (🈝; 🈝; 🈝; 後; 後; ) SQUARED CJK UNIFIED IDEOGRAPH-5F8C
+1F21E;1F21E;1F21E;518D;518D; # (🈞; 🈞; 🈞; 再; 再; ) SQUARED CJK UNIFIED IDEOGRAPH-518D
+1F21F;1F21F;1F21F;65B0;65B0; # (🈟; 🈟; 🈟; 新; 新; ) SQUARED CJK UNIFIED IDEOGRAPH-65B0
+1F220;1F220;1F220;521D;521D; # (🈠; 🈠; 🈠; 初; 初; ) SQUARED CJK UNIFIED IDEOGRAPH-521D
+1F221;1F221;1F221;7D42;7D42; # (🈡; 🈡; 🈡; 終; 終; ) SQUARED CJK UNIFIED IDEOGRAPH-7D42
+1F222;1F222;1F222;751F;751F; # (🈢; 🈢; 🈢; 生; 生; ) SQUARED CJK UNIFIED IDEOGRAPH-751F
+1F223;1F223;1F223;8CA9;8CA9; # (🈣; 🈣; 🈣; 販; 販; ) SQUARED CJK UNIFIED IDEOGRAPH-8CA9
+1F224;1F224;1F224;58F0;58F0; # (🈤; 🈤; 🈤; 声; 声; ) SQUARED CJK UNIFIED IDEOGRAPH-58F0
+1F225;1F225;1F225;5439;5439; # (🈥; 🈥; 🈥; 吹; 吹; ) SQUARED CJK UNIFIED IDEOGRAPH-5439
+1F226;1F226;1F226;6F14;6F14; # (🈦; 🈦; 🈦; 演; 演; ) SQUARED CJK UNIFIED IDEOGRAPH-6F14
+1F227;1F227;1F227;6295;6295; # (🈧; 🈧; 🈧; 投; 投; ) SQUARED CJK UNIFIED IDEOGRAPH-6295
+1F228;1F228;1F228;6355;6355; # (🈨; 🈨; 🈨; 捕; 捕; ) SQUARED CJK UNIFIED IDEOGRAPH-6355
+1F229;1F229;1F229;4E00;4E00; # (🈩; 🈩; 🈩; 一; 一; ) SQUARED CJK UNIFIED IDEOGRAPH-4E00
+1F22A;1F22A;1F22A;4E09;4E09; # (🈪; 🈪; 🈪; 三; 三; ) SQUARED CJK UNIFIED IDEOGRAPH-4E09
+1F22B;1F22B;1F22B;904A;904A; # (🈫; 🈫; 🈫; 遊; 遊; ) SQUARED CJK UNIFIED IDEOGRAPH-904A
+1F22C;1F22C;1F22C;5DE6;5DE6; # (🈬; 🈬; 🈬; 左; 左; ) SQUARED CJK UNIFIED IDEOGRAPH-5DE6
+1F22D;1F22D;1F22D;4E2D;4E2D; # (🈭; 🈭; 🈭; 中; 中; ) SQUARED CJK UNIFIED IDEOGRAPH-4E2D
+1F22E;1F22E;1F22E;53F3;53F3; # (🈮; 🈮; 🈮; 右; 右; ) SQUARED CJK UNIFIED IDEOGRAPH-53F3
+1F22F;1F22F;1F22F;6307;6307; # (🈯; 🈯; 🈯; 指; 指; ) SQUARED CJK UNIFIED IDEOGRAPH-6307
+1F230;1F230;1F230;8D70;8D70; # (🈰; 🈰; 🈰; 走; 走; ) SQUARED CJK UNIFIED IDEOGRAPH-8D70
+1F231;1F231;1F231;6253;6253; # (🈱; 🈱; 🈱; 打; 打; ) SQUARED CJK UNIFIED IDEOGRAPH-6253
+1F232;1F232;1F232;7981;7981; # (🈲; 🈲; 🈲; 禁; 禁; ) SQUARED CJK UNIFIED IDEOGRAPH-7981
+1F233;1F233;1F233;7A7A;7A7A; # (🈳; 🈳; 🈳; 空; 空; ) SQUARED CJK UNIFIED IDEOGRAPH-7A7A
+1F234;1F234;1F234;5408;5408; # (🈴; 🈴; 🈴; 合; 合; ) SQUARED CJK UNIFIED IDEOGRAPH-5408
+1F235;1F235;1F235;6E80;6E80; # (🈵; 🈵; 🈵; 満; 満; ) SQUARED CJK UNIFIED IDEOGRAPH-6E80
+1F236;1F236;1F236;6709;6709; # (🈶; 🈶; 🈶; 有; 有; ) SQUARED CJK UNIFIED IDEOGRAPH-6709
+1F237;1F237;1F237;6708;6708; # (🈷; 🈷; 🈷; 月; 月; ) SQUARED CJK UNIFIED IDEOGRAPH-6708
+1F238;1F238;1F238;7533;7533; # (🈸; 🈸; 🈸; 申; 申; ) SQUARED CJK UNIFIED IDEOGRAPH-7533
+1F239;1F239;1F239;5272;5272; # (🈹; 🈹; 🈹; 割; 割; ) SQUARED CJK UNIFIED IDEOGRAPH-5272
+1F23A;1F23A;1F23A;55B6;55B6; # (🈺; 🈺; 🈺; 営; 営; ) SQUARED CJK UNIFIED IDEOGRAPH-55B6
+1F23B;1F23B;1F23B;914D;914D; # (🈻; 🈻; 🈻; 配; 配; ) SQUARED CJK UNIFIED IDEOGRAPH-914D
+1F240;1F240;1F240;3014 672C 3015;3014 672C 3015; # (🉀; 🉀; 🉀; 〔本〕; 〔本〕; ) TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C
+1F241;1F241;1F241;3014 4E09 3015;3014 4E09 3015; # (🉁; 🉁; 🉁; 〔三〕; 〔三〕; ) TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09
+1F242;1F242;1F242;3014 4E8C 3015;3014 4E8C 3015; # (🉂; 🉂; 🉂; 〔二〕; 〔二〕; ) TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E8C
+1F243;1F243;1F243;3014 5B89 3015;3014 5B89 3015; # (🉃; 🉃; 🉃; 〔安〕; 〔安〕; ) TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-5B89
+1F244;1F244;1F244;3014 70B9 3015;3014 70B9 3015; # (🉄; 🉄; 🉄; 〔点〕; 〔点〕; ) TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-70B9
+1F245;1F245;1F245;3014 6253 3015;3014 6253 3015; # (🉅; 🉅; 🉅; 〔打〕; 〔打〕; ) TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6253
+1F246;1F246;1F246;3014 76D7 3015;3014 76D7 3015; # (🉆; 🉆; 🉆; 〔盗〕; 〔盗〕; ) TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-76D7
+1F247;1F247;1F247;3014 52DD 3015;3014 52DD 3015; # (🉇; 🉇; 🉇; 〔勝〕; 〔勝〕; ) TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-52DD
+1F248;1F248;1F248;3014 6557 3015;3014 6557 3015; # (🉈; 🉈; 🉈; 〔敗〕; 〔敗〕; ) TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557
+1F250;1F250;1F250;5F97;5F97; # (🉐; 🉐; 🉐; 得; 得; ) CIRCLED IDEOGRAPH ADVANTAGE
+1F251;1F251;1F251;53EF;53EF; # (🉑; 🉑; 🉑; 可; 可; ) CIRCLED IDEOGRAPH ACCEPT
+2F800;4E3D;4E3D;4E3D;4E3D; # (丽; 丽; 丽; 丽; 丽; ) CJK COMPATIBILITY IDEOGRAPH-2F800
+2F801;4E38;4E38;4E38;4E38; # (丸; 丸; 丸; 丸; 丸; ) CJK COMPATIBILITY IDEOGRAPH-2F801
+2F802;4E41;4E41;4E41;4E41; # (乁; 乁; 乁; 乁; 乁; ) CJK COMPATIBILITY IDEOGRAPH-2F802
+2F803;20122;20122;20122;20122; # (𠄢; 𠄢; 𠄢; 𠄢; 𠄢; ) CJK COMPATIBILITY IDEOGRAPH-2F803
+2F804;4F60;4F60;4F60;4F60; # (你; 你; 你; 你; 你; ) CJK COMPATIBILITY IDEOGRAPH-2F804
+2F805;4FAE;4FAE;4FAE;4FAE; # (侮; 侮; 侮; 侮; 侮; ) CJK COMPATIBILITY IDEOGRAPH-2F805
+2F806;4FBB;4FBB;4FBB;4FBB; # (侻; 侻; 侻; 侻; 侻; ) CJK COMPATIBILITY IDEOGRAPH-2F806
+2F807;5002;5002;5002;5002; # (倂; 倂; 倂; 倂; 倂; ) CJK COMPATIBILITY IDEOGRAPH-2F807
+2F808;507A;507A;507A;507A; # (偺; 偺; 偺; 偺; 偺; ) CJK COMPATIBILITY IDEOGRAPH-2F808
+2F809;5099;5099;5099;5099; # (備; 備; 備; 備; 備; ) CJK COMPATIBILITY IDEOGRAPH-2F809
+2F80A;50E7;50E7;50E7;50E7; # (僧; 僧; 僧; 僧; 僧; ) CJK COMPATIBILITY IDEOGRAPH-2F80A
+2F80B;50CF;50CF;50CF;50CF; # (像; 像; 像; 像; 像; ) CJK COMPATIBILITY IDEOGRAPH-2F80B
+2F80C;349E;349E;349E;349E; # (㒞; 㒞; 㒞; 㒞; 㒞; ) CJK COMPATIBILITY IDEOGRAPH-2F80C
+2F80D;2063A;2063A;2063A;2063A; # (𠘺; 𠘺; 𠘺; 𠘺; 𠘺; ) CJK COMPATIBILITY IDEOGRAPH-2F80D
+2F80E;514D;514D;514D;514D; # (免; 免; 免; 免; 免; ) CJK COMPATIBILITY IDEOGRAPH-2F80E
+2F80F;5154;5154;5154;5154; # (兔; 兔; 兔; 兔; 兔; ) CJK COMPATIBILITY IDEOGRAPH-2F80F
+2F810;5164;5164;5164;5164; # (兤; 兤; 兤; 兤; 兤; ) CJK COMPATIBILITY IDEOGRAPH-2F810
+2F811;5177;5177;5177;5177; # (具; 具; 具; 具; 具; ) CJK COMPATIBILITY IDEOGRAPH-2F811
+2F812;2051C;2051C;2051C;2051C; # (𠔜; 𠔜; 𠔜; 𠔜; 𠔜; ) CJK COMPATIBILITY IDEOGRAPH-2F812
+2F813;34B9;34B9;34B9;34B9; # (㒹; 㒹; 㒹; 㒹; 㒹; ) CJK COMPATIBILITY IDEOGRAPH-2F813
+2F814;5167;5167;5167;5167; # (內; 內; 內; 內; 內; ) CJK COMPATIBILITY IDEOGRAPH-2F814
+2F815;518D;518D;518D;518D; # (再; 再; 再; 再; 再; ) CJK COMPATIBILITY IDEOGRAPH-2F815
+2F816;2054B;2054B;2054B;2054B; # (𠕋; 𠕋; 𠕋; 𠕋; 𠕋; ) CJK COMPATIBILITY IDEOGRAPH-2F816
+2F817;5197;5197;5197;5197; # (冗; 冗; 冗; 冗; 冗; ) CJK COMPATIBILITY IDEOGRAPH-2F817
+2F818;51A4;51A4;51A4;51A4; # (冤; 冤; 冤; 冤; 冤; ) CJK COMPATIBILITY IDEOGRAPH-2F818
+2F819;4ECC;4ECC;4ECC;4ECC; # (仌; 仌; 仌; 仌; 仌; ) CJK COMPATIBILITY IDEOGRAPH-2F819
+2F81A;51AC;51AC;51AC;51AC; # (冬; 冬; 冬; 冬; 冬; ) CJK COMPATIBILITY IDEOGRAPH-2F81A
+2F81B;51B5;51B5;51B5;51B5; # (况; 况; 况; 况; 况; ) CJK COMPATIBILITY IDEOGRAPH-2F81B
+2F81C;291DF;291DF;291DF;291DF; # (𩇟; 𩇟; 𩇟; 𩇟; 𩇟; ) CJK COMPATIBILITY IDEOGRAPH-2F81C
+2F81D;51F5;51F5;51F5;51F5; # (凵; 凵; 凵; 凵; 凵; ) CJK COMPATIBILITY IDEOGRAPH-2F81D
+2F81E;5203;5203;5203;5203; # (刃; 刃; 刃; 刃; 刃; ) CJK COMPATIBILITY IDEOGRAPH-2F81E
+2F81F;34DF;34DF;34DF;34DF; # (㓟; 㓟; 㓟; 㓟; 㓟; ) CJK COMPATIBILITY IDEOGRAPH-2F81F
+2F820;523B;523B;523B;523B; # (刻; 刻; 刻; 刻; 刻; ) CJK COMPATIBILITY IDEOGRAPH-2F820
+2F821;5246;5246;5246;5246; # (剆; 剆; 剆; 剆; 剆; ) CJK COMPATIBILITY IDEOGRAPH-2F821
+2F822;5272;5272;5272;5272; # (割; 割; 割; 割; 割; ) CJK COMPATIBILITY IDEOGRAPH-2F822
+2F823;5277;5277;5277;5277; # (剷; 剷; 剷; 剷; 剷; ) CJK COMPATIBILITY IDEOGRAPH-2F823
+2F824;3515;3515;3515;3515; # (㔕; 㔕; 㔕; 㔕; 㔕; ) CJK COMPATIBILITY IDEOGRAPH-2F824
+2F825;52C7;52C7;52C7;52C7; # (勇; 勇; 勇; 勇; 勇; ) CJK COMPATIBILITY IDEOGRAPH-2F825
+2F826;52C9;52C9;52C9;52C9; # (勉; 勉; 勉; 勉; 勉; ) CJK COMPATIBILITY IDEOGRAPH-2F826
+2F827;52E4;52E4;52E4;52E4; # (勤; 勤; 勤; 勤; 勤; ) CJK COMPATIBILITY IDEOGRAPH-2F827
+2F828;52FA;52FA;52FA;52FA; # (勺; 勺; 勺; 勺; 勺; ) CJK COMPATIBILITY IDEOGRAPH-2F828
+2F829;5305;5305;5305;5305; # (包; 包; 包; 包; 包; ) CJK COMPATIBILITY IDEOGRAPH-2F829
+2F82A;5306;5306;5306;5306; # (匆; 匆; 匆; 匆; 匆; ) CJK COMPATIBILITY IDEOGRAPH-2F82A
+2F82B;5317;5317;5317;5317; # (北; 北; 北; 北; 北; ) CJK COMPATIBILITY IDEOGRAPH-2F82B
+2F82C;5349;5349;5349;5349; # (卉; 卉; 卉; 卉; 卉; ) CJK COMPATIBILITY IDEOGRAPH-2F82C
+2F82D;5351;5351;5351;5351; # (卑; 卑; 卑; 卑; 卑; ) CJK COMPATIBILITY IDEOGRAPH-2F82D
+2F82E;535A;535A;535A;535A; # (博; 博; 博; 博; 博; ) CJK COMPATIBILITY IDEOGRAPH-2F82E
+2F82F;5373;5373;5373;5373; # (即; 即; 即; 即; 即; ) CJK COMPATIBILITY IDEOGRAPH-2F82F
+2F830;537D;537D;537D;537D; # (卽; 卽; 卽; 卽; 卽; ) CJK COMPATIBILITY IDEOGRAPH-2F830
+2F831;537F;537F;537F;537F; # (卿; 卿; 卿; 卿; 卿; ) CJK COMPATIBILITY IDEOGRAPH-2F831
+2F832;537F;537F;537F;537F; # (卿; 卿; 卿; 卿; 卿; ) CJK COMPATIBILITY IDEOGRAPH-2F832
+2F833;537F;537F;537F;537F; # (卿; 卿; 卿; 卿; 卿; ) CJK COMPATIBILITY IDEOGRAPH-2F833
+2F834;20A2C;20A2C;20A2C;20A2C; # (𠨬; 𠨬; 𠨬; 𠨬; 𠨬; ) CJK COMPATIBILITY IDEOGRAPH-2F834
+2F835;7070;7070;7070;7070; # (灰; 灰; 灰; 灰; 灰; ) CJK COMPATIBILITY IDEOGRAPH-2F835
+2F836;53CA;53CA;53CA;53CA; # (及; 及; 及; 及; 及; ) CJK COMPATIBILITY IDEOGRAPH-2F836
+2F837;53DF;53DF;53DF;53DF; # (叟; 叟; 叟; 叟; 叟; ) CJK COMPATIBILITY IDEOGRAPH-2F837
+2F838;20B63;20B63;20B63;20B63; # (𠭣; 𠭣; 𠭣; 𠭣; 𠭣; ) CJK COMPATIBILITY IDEOGRAPH-2F838
+2F839;53EB;53EB;53EB;53EB; # (叫; 叫; 叫; 叫; 叫; ) CJK COMPATIBILITY IDEOGRAPH-2F839
+2F83A;53F1;53F1;53F1;53F1; # (叱; 叱; 叱; 叱; 叱; ) CJK COMPATIBILITY IDEOGRAPH-2F83A
+2F83B;5406;5406;5406;5406; # (吆; 吆; 吆; 吆; 吆; ) CJK COMPATIBILITY IDEOGRAPH-2F83B
+2F83C;549E;549E;549E;549E; # (咞; 咞; 咞; 咞; 咞; ) CJK COMPATIBILITY IDEOGRAPH-2F83C
+2F83D;5438;5438;5438;5438; # (吸; 吸; 吸; 吸; 吸; ) CJK COMPATIBILITY IDEOGRAPH-2F83D
+2F83E;5448;5448;5448;5448; # (呈; 呈; 呈; 呈; 呈; ) CJK COMPATIBILITY IDEOGRAPH-2F83E
+2F83F;5468;5468;5468;5468; # (周; 周; 周; 周; 周; ) CJK COMPATIBILITY IDEOGRAPH-2F83F
+2F840;54A2;54A2;54A2;54A2; # (咢; 咢; 咢; 咢; 咢; ) CJK COMPATIBILITY IDEOGRAPH-2F840
+2F841;54F6;54F6;54F6;54F6; # (哶; 哶; 哶; 哶; 哶; ) CJK COMPATIBILITY IDEOGRAPH-2F841
+2F842;5510;5510;5510;5510; # (唐; 唐; 唐; 唐; 唐; ) CJK COMPATIBILITY IDEOGRAPH-2F842
+2F843;5553;5553;5553;5553; # (啓; 啓; 啓; 啓; 啓; ) CJK COMPATIBILITY IDEOGRAPH-2F843
+2F844;5563;5563;5563;5563; # (啣; 啣; 啣; 啣; 啣; ) CJK COMPATIBILITY IDEOGRAPH-2F844
+2F845;5584;5584;5584;5584; # (善; 善; 善; 善; 善; ) CJK COMPATIBILITY IDEOGRAPH-2F845
+2F846;5584;5584;5584;5584; # (善; 善; 善; 善; 善; ) CJK COMPATIBILITY IDEOGRAPH-2F846
+2F847;5599;5599;5599;5599; # (喙; 喙; 喙; 喙; 喙; ) CJK COMPATIBILITY IDEOGRAPH-2F847
+2F848;55AB;55AB;55AB;55AB; # (喫; 喫; 喫; 喫; 喫; ) CJK COMPATIBILITY IDEOGRAPH-2F848
+2F849;55B3;55B3;55B3;55B3; # (喳; 喳; 喳; 喳; 喳; ) CJK COMPATIBILITY IDEOGRAPH-2F849
+2F84A;55C2;55C2;55C2;55C2; # (嗂; 嗂; 嗂; 嗂; 嗂; ) CJK COMPATIBILITY IDEOGRAPH-2F84A
+2F84B;5716;5716;5716;5716; # (圖; 圖; 圖; 圖; 圖; ) CJK COMPATIBILITY IDEOGRAPH-2F84B
+2F84C;5606;5606;5606;5606; # (嘆; 嘆; 嘆; 嘆; 嘆; ) CJK COMPATIBILITY IDEOGRAPH-2F84C
+2F84D;5717;5717;5717;5717; # (圗; 圗; 圗; 圗; 圗; ) CJK COMPATIBILITY IDEOGRAPH-2F84D
+2F84E;5651;5651;5651;5651; # (噑; 噑; 噑; 噑; 噑; ) CJK COMPATIBILITY IDEOGRAPH-2F84E
+2F84F;5674;5674;5674;5674; # (噴; 噴; 噴; 噴; 噴; ) CJK COMPATIBILITY IDEOGRAPH-2F84F
+2F850;5207;5207;5207;5207; # (切; 切; 切; 切; 切; ) CJK COMPATIBILITY IDEOGRAPH-2F850
+2F851;58EE;58EE;58EE;58EE; # (壮; 壮; 壮; 壮; 壮; ) CJK COMPATIBILITY IDEOGRAPH-2F851
+2F852;57CE;57CE;57CE;57CE; # (城; 城; 城; 城; 城; ) CJK COMPATIBILITY IDEOGRAPH-2F852
+2F853;57F4;57F4;57F4;57F4; # (埴; 埴; 埴; 埴; 埴; ) CJK COMPATIBILITY IDEOGRAPH-2F853
+2F854;580D;580D;580D;580D; # (堍; 堍; 堍; 堍; 堍; ) CJK COMPATIBILITY IDEOGRAPH-2F854
+2F855;578B;578B;578B;578B; # (型; 型; 型; 型; 型; ) CJK COMPATIBILITY IDEOGRAPH-2F855
+2F856;5832;5832;5832;5832; # (堲; 堲; 堲; 堲; 堲; ) CJK COMPATIBILITY IDEOGRAPH-2F856
+2F857;5831;5831;5831;5831; # (報; 報; 報; 報; 報; ) CJK COMPATIBILITY IDEOGRAPH-2F857
+2F858;58AC;58AC;58AC;58AC; # (墬; 墬; 墬; 墬; 墬; ) CJK COMPATIBILITY IDEOGRAPH-2F858
+2F859;214E4;214E4;214E4;214E4; # (𡓤; 𡓤; 𡓤; 𡓤; 𡓤; ) CJK COMPATIBILITY IDEOGRAPH-2F859
+2F85A;58F2;58F2;58F2;58F2; # (売; 売; 売; 売; 売; ) CJK COMPATIBILITY IDEOGRAPH-2F85A
+2F85B;58F7;58F7;58F7;58F7; # (壷; 壷; 壷; 壷; 壷; ) CJK COMPATIBILITY IDEOGRAPH-2F85B
+2F85C;5906;5906;5906;5906; # (夆; 夆; 夆; 夆; 夆; ) CJK COMPATIBILITY IDEOGRAPH-2F85C
+2F85D;591A;591A;591A;591A; # (多; 多; 多; 多; 多; ) CJK COMPATIBILITY IDEOGRAPH-2F85D
+2F85E;5922;5922;5922;5922; # (夢; 夢; 夢; 夢; 夢; ) CJK COMPATIBILITY IDEOGRAPH-2F85E
+2F85F;5962;5962;5962;5962; # (奢; 奢; 奢; 奢; 奢; ) CJK COMPATIBILITY IDEOGRAPH-2F85F
+2F860;216A8;216A8;216A8;216A8; # (𡚨; 𡚨; 𡚨; 𡚨; 𡚨; ) CJK COMPATIBILITY IDEOGRAPH-2F860
+2F861;216EA;216EA;216EA;216EA; # (𡛪; 𡛪; 𡛪; 𡛪; 𡛪; ) CJK COMPATIBILITY IDEOGRAPH-2F861
+2F862;59EC;59EC;59EC;59EC; # (姬; 姬; 姬; 姬; 姬; ) CJK COMPATIBILITY IDEOGRAPH-2F862
+2F863;5A1B;5A1B;5A1B;5A1B; # (娛; 娛; 娛; 娛; 娛; ) CJK COMPATIBILITY IDEOGRAPH-2F863
+2F864;5A27;5A27;5A27;5A27; # (娧; 娧; 娧; 娧; 娧; ) CJK COMPATIBILITY IDEOGRAPH-2F864
+2F865;59D8;59D8;59D8;59D8; # (姘; 姘; 姘; 姘; 姘; ) CJK COMPATIBILITY IDEOGRAPH-2F865
+2F866;5A66;5A66;5A66;5A66; # (婦; 婦; 婦; 婦; 婦; ) CJK COMPATIBILITY IDEOGRAPH-2F866
+2F867;36EE;36EE;36EE;36EE; # (㛮; 㛮; 㛮; 㛮; 㛮; ) CJK COMPATIBILITY IDEOGRAPH-2F867
+2F868;36FC;36FC;36FC;36FC; # (㛼; 㛼; 㛼; 㛼; 㛼; ) CJK COMPATIBILITY IDEOGRAPH-2F868
+2F869;5B08;5B08;5B08;5B08; # (嬈; 嬈; 嬈; 嬈; 嬈; ) CJK COMPATIBILITY IDEOGRAPH-2F869
+2F86A;5B3E;5B3E;5B3E;5B3E; # (嬾; 嬾; 嬾; 嬾; 嬾; ) CJK COMPATIBILITY IDEOGRAPH-2F86A
+2F86B;5B3E;5B3E;5B3E;5B3E; # (嬾; 嬾; 嬾; 嬾; 嬾; ) CJK COMPATIBILITY IDEOGRAPH-2F86B
+2F86C;219C8;219C8;219C8;219C8; # (𡧈; 𡧈; 𡧈; 𡧈; 𡧈; ) CJK COMPATIBILITY IDEOGRAPH-2F86C
+2F86D;5BC3;5BC3;5BC3;5BC3; # (寃; 寃; 寃; 寃; 寃; ) CJK COMPATIBILITY IDEOGRAPH-2F86D
+2F86E;5BD8;5BD8;5BD8;5BD8; # (寘; 寘; 寘; 寘; 寘; ) CJK COMPATIBILITY IDEOGRAPH-2F86E
+2F86F;5BE7;5BE7;5BE7;5BE7; # (寧; 寧; 寧; 寧; 寧; ) CJK COMPATIBILITY IDEOGRAPH-2F86F
+2F870;5BF3;5BF3;5BF3;5BF3; # (寳; 寳; 寳; 寳; 寳; ) CJK COMPATIBILITY IDEOGRAPH-2F870
+2F871;21B18;21B18;21B18;21B18; # (𡬘; 𡬘; 𡬘; 𡬘; 𡬘; ) CJK COMPATIBILITY IDEOGRAPH-2F871
+2F872;5BFF;5BFF;5BFF;5BFF; # (寿; 寿; 寿; 寿; 寿; ) CJK COMPATIBILITY IDEOGRAPH-2F872
+2F873;5C06;5C06;5C06;5C06; # (将; 将; 将; 将; 将; ) CJK COMPATIBILITY IDEOGRAPH-2F873
+2F874;5F53;5F53;5F53;5F53; # (当; 当; 当; 当; 当; ) CJK COMPATIBILITY IDEOGRAPH-2F874
+2F875;5C22;5C22;5C22;5C22; # (尢; 尢; 尢; 尢; 尢; ) CJK COMPATIBILITY IDEOGRAPH-2F875
+2F876;3781;3781;3781;3781; # (㞁; 㞁; 㞁; 㞁; 㞁; ) CJK COMPATIBILITY IDEOGRAPH-2F876
+2F877;5C60;5C60;5C60;5C60; # (屠; 屠; 屠; 屠; 屠; ) CJK COMPATIBILITY IDEOGRAPH-2F877
+2F878;5C6E;5C6E;5C6E;5C6E; # (屮; 屮; 屮; 屮; 屮; ) CJK COMPATIBILITY IDEOGRAPH-2F878
+2F879;5CC0;5CC0;5CC0;5CC0; # (峀; 峀; 峀; 峀; 峀; ) CJK COMPATIBILITY IDEOGRAPH-2F879
+2F87A;5C8D;5C8D;5C8D;5C8D; # (岍; 岍; 岍; 岍; 岍; ) CJK COMPATIBILITY IDEOGRAPH-2F87A
+2F87B;21DE4;21DE4;21DE4;21DE4; # (𡷤; 𡷤; 𡷤; 𡷤; 𡷤; ) CJK COMPATIBILITY IDEOGRAPH-2F87B
+2F87C;5D43;5D43;5D43;5D43; # (嵃; 嵃; 嵃; 嵃; 嵃; ) CJK COMPATIBILITY IDEOGRAPH-2F87C
+2F87D;21DE6;21DE6;21DE6;21DE6; # (𡷦; 𡷦; 𡷦; 𡷦; 𡷦; ) CJK COMPATIBILITY IDEOGRAPH-2F87D
+2F87E;5D6E;5D6E;5D6E;5D6E; # (嵮; 嵮; 嵮; 嵮; 嵮; ) CJK COMPATIBILITY IDEOGRAPH-2F87E
+2F87F;5D6B;5D6B;5D6B;5D6B; # (嵫; 嵫; 嵫; 嵫; 嵫; ) CJK COMPATIBILITY IDEOGRAPH-2F87F
+2F880;5D7C;5D7C;5D7C;5D7C; # (嵼; 嵼; 嵼; 嵼; 嵼; ) CJK COMPATIBILITY IDEOGRAPH-2F880
+2F881;5DE1;5DE1;5DE1;5DE1; # (巡; 巡; 巡; 巡; 巡; ) CJK COMPATIBILITY IDEOGRAPH-2F881
+2F882;5DE2;5DE2;5DE2;5DE2; # (巢; 巢; 巢; 巢; 巢; ) CJK COMPATIBILITY IDEOGRAPH-2F882
+2F883;382F;382F;382F;382F; # (㠯; 㠯; 㠯; 㠯; 㠯; ) CJK COMPATIBILITY IDEOGRAPH-2F883
+2F884;5DFD;5DFD;5DFD;5DFD; # (巽; 巽; 巽; 巽; 巽; ) CJK COMPATIBILITY IDEOGRAPH-2F884
+2F885;5E28;5E28;5E28;5E28; # (帨; 帨; 帨; 帨; 帨; ) CJK COMPATIBILITY IDEOGRAPH-2F885
+2F886;5E3D;5E3D;5E3D;5E3D; # (帽; 帽; 帽; 帽; 帽; ) CJK COMPATIBILITY IDEOGRAPH-2F886
+2F887;5E69;5E69;5E69;5E69; # (幩; 幩; 幩; 幩; 幩; ) CJK COMPATIBILITY IDEOGRAPH-2F887
+2F888;3862;3862;3862;3862; # (㡢; 㡢; 㡢; 㡢; 㡢; ) CJK COMPATIBILITY IDEOGRAPH-2F888
+2F889;22183;22183;22183;22183; # (𢆃; 𢆃; 𢆃; 𢆃; 𢆃; ) CJK COMPATIBILITY IDEOGRAPH-2F889
+2F88A;387C;387C;387C;387C; # (㡼; 㡼; 㡼; 㡼; 㡼; ) CJK COMPATIBILITY IDEOGRAPH-2F88A
+2F88B;5EB0;5EB0;5EB0;5EB0; # (庰; 庰; 庰; 庰; 庰; ) CJK COMPATIBILITY IDEOGRAPH-2F88B
+2F88C;5EB3;5EB3;5EB3;5EB3; # (庳; 庳; 庳; 庳; 庳; ) CJK COMPATIBILITY IDEOGRAPH-2F88C
+2F88D;5EB6;5EB6;5EB6;5EB6; # (庶; 庶; 庶; 庶; 庶; ) CJK COMPATIBILITY IDEOGRAPH-2F88D
+2F88E;5ECA;5ECA;5ECA;5ECA; # (廊; 廊; 廊; 廊; 廊; ) CJK COMPATIBILITY IDEOGRAPH-2F88E
+2F88F;2A392;2A392;2A392;2A392; # (𪎒; 𪎒; 𪎒; 𪎒; 𪎒; ) CJK COMPATIBILITY IDEOGRAPH-2F88F
+2F890;5EFE;5EFE;5EFE;5EFE; # (廾; 廾; 廾; 廾; 廾; ) CJK COMPATIBILITY IDEOGRAPH-2F890
+2F891;22331;22331;22331;22331; # (𢌱; 𢌱; 𢌱; 𢌱; 𢌱; ) CJK COMPATIBILITY IDEOGRAPH-2F891
+2F892;22331;22331;22331;22331; # (𢌱; 𢌱; 𢌱; 𢌱; 𢌱; ) CJK COMPATIBILITY IDEOGRAPH-2F892
+2F893;8201;8201;8201;8201; # (舁; 舁; 舁; 舁; 舁; ) CJK COMPATIBILITY IDEOGRAPH-2F893
+2F894;5F22;5F22;5F22;5F22; # (弢; 弢; 弢; 弢; 弢; ) CJK COMPATIBILITY IDEOGRAPH-2F894
+2F895;5F22;5F22;5F22;5F22; # (弢; 弢; 弢; 弢; 弢; ) CJK COMPATIBILITY IDEOGRAPH-2F895
+2F896;38C7;38C7;38C7;38C7; # (㣇; 㣇; 㣇; 㣇; 㣇; ) CJK COMPATIBILITY IDEOGRAPH-2F896
+2F897;232B8;232B8;232B8;232B8; # (𣊸; 𣊸; 𣊸; 𣊸; 𣊸; ) CJK COMPATIBILITY IDEOGRAPH-2F897
+2F898;261DA;261DA;261DA;261DA; # (𦇚; 𦇚; 𦇚; 𦇚; 𦇚; ) CJK COMPATIBILITY IDEOGRAPH-2F898
+2F899;5F62;5F62;5F62;5F62; # (形; 形; 形; 形; 形; ) CJK COMPATIBILITY IDEOGRAPH-2F899
+2F89A;5F6B;5F6B;5F6B;5F6B; # (彫; 彫; 彫; 彫; 彫; ) CJK COMPATIBILITY IDEOGRAPH-2F89A
+2F89B;38E3;38E3;38E3;38E3; # (㣣; 㣣; 㣣; 㣣; 㣣; ) CJK COMPATIBILITY IDEOGRAPH-2F89B
+2F89C;5F9A;5F9A;5F9A;5F9A; # (徚; 徚; 徚; 徚; 徚; ) CJK COMPATIBILITY IDEOGRAPH-2F89C
+2F89D;5FCD;5FCD;5FCD;5FCD; # (忍; 忍; 忍; 忍; 忍; ) CJK COMPATIBILITY IDEOGRAPH-2F89D
+2F89E;5FD7;5FD7;5FD7;5FD7; # (志; 志; 志; 志; 志; ) CJK COMPATIBILITY IDEOGRAPH-2F89E
+2F89F;5FF9;5FF9;5FF9;5FF9; # (忹; 忹; 忹; 忹; 忹; ) CJK COMPATIBILITY IDEOGRAPH-2F89F
+2F8A0;6081;6081;6081;6081; # (悁; 悁; 悁; 悁; 悁; ) CJK COMPATIBILITY IDEOGRAPH-2F8A0
+2F8A1;393A;393A;393A;393A; # (㤺; 㤺; 㤺; 㤺; 㤺; ) CJK COMPATIBILITY IDEOGRAPH-2F8A1
+2F8A2;391C;391C;391C;391C; # (㤜; 㤜; 㤜; 㤜; 㤜; ) CJK COMPATIBILITY IDEOGRAPH-2F8A2
+2F8A3;6094;6094;6094;6094; # (悔; 悔; 悔; 悔; 悔; ) CJK COMPATIBILITY IDEOGRAPH-2F8A3
+2F8A4;226D4;226D4;226D4;226D4; # (𢛔; 𢛔; 𢛔; 𢛔; 𢛔; ) CJK COMPATIBILITY IDEOGRAPH-2F8A4
+2F8A5;60C7;60C7;60C7;60C7; # (惇; 惇; 惇; 惇; 惇; ) CJK COMPATIBILITY IDEOGRAPH-2F8A5
+2F8A6;6148;6148;6148;6148; # (慈; 慈; 慈; 慈; 慈; ) CJK COMPATIBILITY IDEOGRAPH-2F8A6
+2F8A7;614C;614C;614C;614C; # (慌; 慌; 慌; 慌; 慌; ) CJK COMPATIBILITY IDEOGRAPH-2F8A7
+2F8A8;614E;614E;614E;614E; # (慎; 慎; 慎; 慎; 慎; ) CJK COMPATIBILITY IDEOGRAPH-2F8A8
+2F8A9;614C;614C;614C;614C; # (慌; 慌; 慌; 慌; 慌; ) CJK COMPATIBILITY IDEOGRAPH-2F8A9
+2F8AA;617A;617A;617A;617A; # (慺; 慺; 慺; 慺; 慺; ) CJK COMPATIBILITY IDEOGRAPH-2F8AA
+2F8AB;618E;618E;618E;618E; # (憎; 憎; 憎; 憎; 憎; ) CJK COMPATIBILITY IDEOGRAPH-2F8AB
+2F8AC;61B2;61B2;61B2;61B2; # (憲; 憲; 憲; 憲; 憲; ) CJK COMPATIBILITY IDEOGRAPH-2F8AC
+2F8AD;61A4;61A4;61A4;61A4; # (憤; 憤; 憤; 憤; 憤; ) CJK COMPATIBILITY IDEOGRAPH-2F8AD
+2F8AE;61AF;61AF;61AF;61AF; # (憯; 憯; 憯; 憯; 憯; ) CJK COMPATIBILITY IDEOGRAPH-2F8AE
+2F8AF;61DE;61DE;61DE;61DE; # (懞; 懞; 懞; 懞; 懞; ) CJK COMPATIBILITY IDEOGRAPH-2F8AF
+2F8B0;61F2;61F2;61F2;61F2; # (懲; 懲; 懲; 懲; 懲; ) CJK COMPATIBILITY IDEOGRAPH-2F8B0
+2F8B1;61F6;61F6;61F6;61F6; # (懶; 懶; 懶; 懶; 懶; ) CJK COMPATIBILITY IDEOGRAPH-2F8B1
+2F8B2;6210;6210;6210;6210; # (成; 成; 成; 成; 成; ) CJK COMPATIBILITY IDEOGRAPH-2F8B2
+2F8B3;621B;621B;621B;621B; # (戛; 戛; 戛; 戛; 戛; ) CJK COMPATIBILITY IDEOGRAPH-2F8B3
+2F8B4;625D;625D;625D;625D; # (扝; 扝; 扝; 扝; 扝; ) CJK COMPATIBILITY IDEOGRAPH-2F8B4
+2F8B5;62B1;62B1;62B1;62B1; # (抱; 抱; 抱; 抱; 抱; ) CJK COMPATIBILITY IDEOGRAPH-2F8B5
+2F8B6;62D4;62D4;62D4;62D4; # (拔; 拔; 拔; 拔; 拔; ) CJK COMPATIBILITY IDEOGRAPH-2F8B6
+2F8B7;6350;6350;6350;6350; # (捐; 捐; 捐; 捐; 捐; ) CJK COMPATIBILITY IDEOGRAPH-2F8B7
+2F8B8;22B0C;22B0C;22B0C;22B0C; # (𢬌; 𢬌; 𢬌; 𢬌; 𢬌; ) CJK COMPATIBILITY IDEOGRAPH-2F8B8
+2F8B9;633D;633D;633D;633D; # (挽; 挽; 挽; 挽; 挽; ) CJK COMPATIBILITY IDEOGRAPH-2F8B9
+2F8BA;62FC;62FC;62FC;62FC; # (拼; 拼; 拼; 拼; 拼; ) CJK COMPATIBILITY IDEOGRAPH-2F8BA
+2F8BB;6368;6368;6368;6368; # (捨; 捨; 捨; 捨; 捨; ) CJK COMPATIBILITY IDEOGRAPH-2F8BB
+2F8BC;6383;6383;6383;6383; # (掃; 掃; 掃; 掃; 掃; ) CJK COMPATIBILITY IDEOGRAPH-2F8BC
+2F8BD;63E4;63E4;63E4;63E4; # (揤; 揤; 揤; 揤; 揤; ) CJK COMPATIBILITY IDEOGRAPH-2F8BD
+2F8BE;22BF1;22BF1;22BF1;22BF1; # (𢯱; 𢯱; 𢯱; 𢯱; 𢯱; ) CJK COMPATIBILITY IDEOGRAPH-2F8BE
+2F8BF;6422;6422;6422;6422; # (搢; 搢; 搢; 搢; 搢; ) CJK COMPATIBILITY IDEOGRAPH-2F8BF
+2F8C0;63C5;63C5;63C5;63C5; # (揅; 揅; 揅; 揅; 揅; ) CJK COMPATIBILITY IDEOGRAPH-2F8C0
+2F8C1;63A9;63A9;63A9;63A9; # (掩; 掩; 掩; 掩; 掩; ) CJK COMPATIBILITY IDEOGRAPH-2F8C1
+2F8C2;3A2E;3A2E;3A2E;3A2E; # (㨮; 㨮; 㨮; 㨮; 㨮; ) CJK COMPATIBILITY IDEOGRAPH-2F8C2
+2F8C3;6469;6469;6469;6469; # (摩; 摩; 摩; 摩; 摩; ) CJK COMPATIBILITY IDEOGRAPH-2F8C3
+2F8C4;647E;647E;647E;647E; # (摾; 摾; 摾; 摾; 摾; ) CJK COMPATIBILITY IDEOGRAPH-2F8C4
+2F8C5;649D;649D;649D;649D; # (撝; 撝; 撝; 撝; 撝; ) CJK COMPATIBILITY IDEOGRAPH-2F8C5
+2F8C6;6477;6477;6477;6477; # (摷; 摷; 摷; 摷; 摷; ) CJK COMPATIBILITY IDEOGRAPH-2F8C6
+2F8C7;3A6C;3A6C;3A6C;3A6C; # (㩬; 㩬; 㩬; 㩬; 㩬; ) CJK COMPATIBILITY IDEOGRAPH-2F8C7
+2F8C8;654F;654F;654F;654F; # (敏; 敏; 敏; 敏; 敏; ) CJK COMPATIBILITY IDEOGRAPH-2F8C8
+2F8C9;656C;656C;656C;656C; # (敬; 敬; 敬; 敬; 敬; ) CJK COMPATIBILITY IDEOGRAPH-2F8C9
+2F8CA;2300A;2300A;2300A;2300A; # (𣀊; 𣀊; 𣀊; 𣀊; 𣀊; ) CJK COMPATIBILITY IDEOGRAPH-2F8CA
+2F8CB;65E3;65E3;65E3;65E3; # (旣; 旣; 旣; 旣; 旣; ) CJK COMPATIBILITY IDEOGRAPH-2F8CB
+2F8CC;66F8;66F8;66F8;66F8; # (書; 書; 書; 書; 書; ) CJK COMPATIBILITY IDEOGRAPH-2F8CC
+2F8CD;6649;6649;6649;6649; # (晉; 晉; 晉; 晉; 晉; ) CJK COMPATIBILITY IDEOGRAPH-2F8CD
+2F8CE;3B19;3B19;3B19;3B19; # (㬙; 㬙; 㬙; 㬙; 㬙; ) CJK COMPATIBILITY IDEOGRAPH-2F8CE
+2F8CF;6691;6691;6691;6691; # (暑; 暑; 暑; 暑; 暑; ) CJK COMPATIBILITY IDEOGRAPH-2F8CF
+2F8D0;3B08;3B08;3B08;3B08; # (㬈; 㬈; 㬈; 㬈; 㬈; ) CJK COMPATIBILITY IDEOGRAPH-2F8D0
+2F8D1;3AE4;3AE4;3AE4;3AE4; # (㫤; 㫤; 㫤; 㫤; 㫤; ) CJK COMPATIBILITY IDEOGRAPH-2F8D1
+2F8D2;5192;5192;5192;5192; # (冒; 冒; 冒; 冒; 冒; ) CJK COMPATIBILITY IDEOGRAPH-2F8D2
+2F8D3;5195;5195;5195;5195; # (冕; 冕; 冕; 冕; 冕; ) CJK COMPATIBILITY IDEOGRAPH-2F8D3
+2F8D4;6700;6700;6700;6700; # (最; 最; 最; 最; 最; ) CJK COMPATIBILITY IDEOGRAPH-2F8D4
+2F8D5;669C;669C;669C;669C; # (暜; 暜; 暜; 暜; 暜; ) CJK COMPATIBILITY IDEOGRAPH-2F8D5
+2F8D6;80AD;80AD;80AD;80AD; # (肭; 肭; 肭; 肭; 肭; ) CJK COMPATIBILITY IDEOGRAPH-2F8D6
+2F8D7;43D9;43D9;43D9;43D9; # (䏙; 䏙; 䏙; 䏙; 䏙; ) CJK COMPATIBILITY IDEOGRAPH-2F8D7
+2F8D8;6717;6717;6717;6717; # (朗; 朗; 朗; 朗; 朗; ) CJK COMPATIBILITY IDEOGRAPH-2F8D8
+2F8D9;671B;671B;671B;671B; # (望; 望; 望; 望; 望; ) CJK COMPATIBILITY IDEOGRAPH-2F8D9
+2F8DA;6721;6721;6721;6721; # (朡; 朡; 朡; 朡; 朡; ) CJK COMPATIBILITY IDEOGRAPH-2F8DA
+2F8DB;675E;675E;675E;675E; # (杞; 杞; 杞; 杞; 杞; ) CJK COMPATIBILITY IDEOGRAPH-2F8DB
+2F8DC;6753;6753;6753;6753; # (杓; 杓; 杓; 杓; 杓; ) CJK COMPATIBILITY IDEOGRAPH-2F8DC
+2F8DD;233C3;233C3;233C3;233C3; # (𣏃; 𣏃; 𣏃; 𣏃; 𣏃; ) CJK COMPATIBILITY IDEOGRAPH-2F8DD
+2F8DE;3B49;3B49;3B49;3B49; # (㭉; 㭉; 㭉; 㭉; 㭉; ) CJK COMPATIBILITY IDEOGRAPH-2F8DE
+2F8DF;67FA;67FA;67FA;67FA; # (柺; 柺; 柺; 柺; 柺; ) CJK COMPATIBILITY IDEOGRAPH-2F8DF
+2F8E0;6785;6785;6785;6785; # (枅; 枅; 枅; 枅; 枅; ) CJK COMPATIBILITY IDEOGRAPH-2F8E0
+2F8E1;6852;6852;6852;6852; # (桒; 桒; 桒; 桒; 桒; ) CJK COMPATIBILITY IDEOGRAPH-2F8E1
+2F8E2;6885;6885;6885;6885; # (梅; 梅; 梅; 梅; 梅; ) CJK COMPATIBILITY IDEOGRAPH-2F8E2
+2F8E3;2346D;2346D;2346D;2346D; # (𣑭; 𣑭; 𣑭; 𣑭; 𣑭; ) CJK COMPATIBILITY IDEOGRAPH-2F8E3
+2F8E4;688E;688E;688E;688E; # (梎; 梎; 梎; 梎; 梎; ) CJK COMPATIBILITY IDEOGRAPH-2F8E4
+2F8E5;681F;681F;681F;681F; # (栟; 栟; 栟; 栟; 栟; ) CJK COMPATIBILITY IDEOGRAPH-2F8E5
+2F8E6;6914;6914;6914;6914; # (椔; 椔; 椔; 椔; 椔; ) CJK COMPATIBILITY IDEOGRAPH-2F8E6
+2F8E7;3B9D;3B9D;3B9D;3B9D; # (㮝; 㮝; 㮝; 㮝; 㮝; ) CJK COMPATIBILITY IDEOGRAPH-2F8E7
+2F8E8;6942;6942;6942;6942; # (楂; 楂; 楂; 楂; 楂; ) CJK COMPATIBILITY IDEOGRAPH-2F8E8
+2F8E9;69A3;69A3;69A3;69A3; # (榣; 榣; 榣; 榣; 榣; ) CJK COMPATIBILITY IDEOGRAPH-2F8E9
+2F8EA;69EA;69EA;69EA;69EA; # (槪; 槪; 槪; 槪; 槪; ) CJK COMPATIBILITY IDEOGRAPH-2F8EA
+2F8EB;6AA8;6AA8;6AA8;6AA8; # (檨; 檨; 檨; 檨; 檨; ) CJK COMPATIBILITY IDEOGRAPH-2F8EB
+2F8EC;236A3;236A3;236A3;236A3; # (𣚣; 𣚣; 𣚣; 𣚣; 𣚣; ) CJK COMPATIBILITY IDEOGRAPH-2F8EC
+2F8ED;6ADB;6ADB;6ADB;6ADB; # (櫛; 櫛; 櫛; 櫛; 櫛; ) CJK COMPATIBILITY IDEOGRAPH-2F8ED
+2F8EE;3C18;3C18;3C18;3C18; # (㰘; 㰘; 㰘; 㰘; 㰘; ) CJK COMPATIBILITY IDEOGRAPH-2F8EE
+2F8EF;6B21;6B21;6B21;6B21; # (次; 次; 次; 次; 次; ) CJK COMPATIBILITY IDEOGRAPH-2F8EF
+2F8F0;238A7;238A7;238A7;238A7; # (𣢧; 𣢧; 𣢧; 𣢧; 𣢧; ) CJK COMPATIBILITY IDEOGRAPH-2F8F0
+2F8F1;6B54;6B54;6B54;6B54; # (歔; 歔; 歔; 歔; 歔; ) CJK COMPATIBILITY IDEOGRAPH-2F8F1
+2F8F2;3C4E;3C4E;3C4E;3C4E; # (㱎; 㱎; 㱎; 㱎; 㱎; ) CJK COMPATIBILITY IDEOGRAPH-2F8F2
+2F8F3;6B72;6B72;6B72;6B72; # (歲; 歲; 歲; 歲; 歲; ) CJK COMPATIBILITY IDEOGRAPH-2F8F3
+2F8F4;6B9F;6B9F;6B9F;6B9F; # (殟; 殟; 殟; 殟; 殟; ) CJK COMPATIBILITY IDEOGRAPH-2F8F4
+2F8F5;6BBA;6BBA;6BBA;6BBA; # (殺; 殺; 殺; 殺; 殺; ) CJK COMPATIBILITY IDEOGRAPH-2F8F5
+2F8F6;6BBB;6BBB;6BBB;6BBB; # (殻; 殻; 殻; 殻; 殻; ) CJK COMPATIBILITY IDEOGRAPH-2F8F6
+2F8F7;23A8D;23A8D;23A8D;23A8D; # (𣪍; 𣪍; 𣪍; 𣪍; 𣪍; ) CJK COMPATIBILITY IDEOGRAPH-2F8F7
+2F8F8;21D0B;21D0B;21D0B;21D0B; # (𡴋; 𡴋; 𡴋; 𡴋; 𡴋; ) CJK COMPATIBILITY IDEOGRAPH-2F8F8
+2F8F9;23AFA;23AFA;23AFA;23AFA; # (𣫺; 𣫺; 𣫺; 𣫺; 𣫺; ) CJK COMPATIBILITY IDEOGRAPH-2F8F9
+2F8FA;6C4E;6C4E;6C4E;6C4E; # (汎; 汎; 汎; 汎; 汎; ) CJK COMPATIBILITY IDEOGRAPH-2F8FA
+2F8FB;23CBC;23CBC;23CBC;23CBC; # (𣲼; 𣲼; 𣲼; 𣲼; 𣲼; ) CJK COMPATIBILITY IDEOGRAPH-2F8FB
+2F8FC;6CBF;6CBF;6CBF;6CBF; # (沿; 沿; 沿; 沿; 沿; ) CJK COMPATIBILITY IDEOGRAPH-2F8FC
+2F8FD;6CCD;6CCD;6CCD;6CCD; # (泍; 泍; 泍; 泍; 泍; ) CJK COMPATIBILITY IDEOGRAPH-2F8FD
+2F8FE;6C67;6C67;6C67;6C67; # (汧; 汧; 汧; 汧; 汧; ) CJK COMPATIBILITY IDEOGRAPH-2F8FE
+2F8FF;6D16;6D16;6D16;6D16; # (洖; 洖; 洖; 洖; 洖; ) CJK COMPATIBILITY IDEOGRAPH-2F8FF
+2F900;6D3E;6D3E;6D3E;6D3E; # (派; 派; 派; 派; 派; ) CJK COMPATIBILITY IDEOGRAPH-2F900
+2F901;6D77;6D77;6D77;6D77; # (海; 海; 海; 海; 海; ) CJK COMPATIBILITY IDEOGRAPH-2F901
+2F902;6D41;6D41;6D41;6D41; # (流; 流; 流; 流; 流; ) CJK COMPATIBILITY IDEOGRAPH-2F902
+2F903;6D69;6D69;6D69;6D69; # (浩; 浩; 浩; 浩; 浩; ) CJK COMPATIBILITY IDEOGRAPH-2F903
+2F904;6D78;6D78;6D78;6D78; # (浸; 浸; 浸; 浸; 浸; ) CJK COMPATIBILITY IDEOGRAPH-2F904
+2F905;6D85;6D85;6D85;6D85; # (涅; 涅; 涅; 涅; 涅; ) CJK COMPATIBILITY IDEOGRAPH-2F905
+2F906;23D1E;23D1E;23D1E;23D1E; # (𣴞; 𣴞; 𣴞; 𣴞; 𣴞; ) CJK COMPATIBILITY IDEOGRAPH-2F906
+2F907;6D34;6D34;6D34;6D34; # (洴; 洴; 洴; 洴; 洴; ) CJK COMPATIBILITY IDEOGRAPH-2F907
+2F908;6E2F;6E2F;6E2F;6E2F; # (港; 港; 港; 港; 港; ) CJK COMPATIBILITY IDEOGRAPH-2F908
+2F909;6E6E;6E6E;6E6E;6E6E; # (湮; 湮; 湮; 湮; 湮; ) CJK COMPATIBILITY IDEOGRAPH-2F909
+2F90A;3D33;3D33;3D33;3D33; # (㴳; 㴳; 㴳; 㴳; 㴳; ) CJK COMPATIBILITY IDEOGRAPH-2F90A
+2F90B;6ECB;6ECB;6ECB;6ECB; # (滋; 滋; 滋; 滋; 滋; ) CJK COMPATIBILITY IDEOGRAPH-2F90B
+2F90C;6EC7;6EC7;6EC7;6EC7; # (滇; 滇; 滇; 滇; 滇; ) CJK COMPATIBILITY IDEOGRAPH-2F90C
+2F90D;23ED1;23ED1;23ED1;23ED1; # (𣻑; 𣻑; 𣻑; 𣻑; 𣻑; ) CJK COMPATIBILITY IDEOGRAPH-2F90D
+2F90E;6DF9;6DF9;6DF9;6DF9; # (淹; 淹; 淹; 淹; 淹; ) CJK COMPATIBILITY IDEOGRAPH-2F90E
+2F90F;6F6E;6F6E;6F6E;6F6E; # (潮; 潮; 潮; 潮; 潮; ) CJK COMPATIBILITY IDEOGRAPH-2F90F
+2F910;23F5E;23F5E;23F5E;23F5E; # (𣽞; 𣽞; 𣽞; 𣽞; 𣽞; ) CJK COMPATIBILITY IDEOGRAPH-2F910
+2F911;23F8E;23F8E;23F8E;23F8E; # (𣾎; 𣾎; 𣾎; 𣾎; 𣾎; ) CJK COMPATIBILITY IDEOGRAPH-2F911
+2F912;6FC6;6FC6;6FC6;6FC6; # (濆; 濆; 濆; 濆; 濆; ) CJK COMPATIBILITY IDEOGRAPH-2F912
+2F913;7039;7039;7039;7039; # (瀹; 瀹; 瀹; 瀹; 瀹; ) CJK COMPATIBILITY IDEOGRAPH-2F913
+2F914;701E;701E;701E;701E; # (瀞; 瀞; 瀞; 瀞; 瀞; ) CJK COMPATIBILITY IDEOGRAPH-2F914
+2F915;701B;701B;701B;701B; # (瀛; 瀛; 瀛; 瀛; 瀛; ) CJK COMPATIBILITY IDEOGRAPH-2F915
+2F916;3D96;3D96;3D96;3D96; # (㶖; 㶖; 㶖; 㶖; 㶖; ) CJK COMPATIBILITY IDEOGRAPH-2F916
+2F917;704A;704A;704A;704A; # (灊; 灊; 灊; 灊; 灊; ) CJK COMPATIBILITY IDEOGRAPH-2F917
+2F918;707D;707D;707D;707D; # (災; 災; 災; 災; 災; ) CJK COMPATIBILITY IDEOGRAPH-2F918
+2F919;7077;7077;7077;7077; # (灷; 灷; 灷; 灷; 灷; ) CJK COMPATIBILITY IDEOGRAPH-2F919
+2F91A;70AD;70AD;70AD;70AD; # (炭; 炭; 炭; 炭; 炭; ) CJK COMPATIBILITY IDEOGRAPH-2F91A
+2F91B;20525;20525;20525;20525; # (𠔥; 𠔥; 𠔥; 𠔥; 𠔥; ) CJK COMPATIBILITY IDEOGRAPH-2F91B
+2F91C;7145;7145;7145;7145; # (煅; 煅; 煅; 煅; 煅; ) CJK COMPATIBILITY IDEOGRAPH-2F91C
+2F91D;24263;24263;24263;24263; # (𤉣; 𤉣; 𤉣; 𤉣; 𤉣; ) CJK COMPATIBILITY IDEOGRAPH-2F91D
+2F91E;719C;719C;719C;719C; # (熜; 熜; 熜; 熜; 熜; ) CJK COMPATIBILITY IDEOGRAPH-2F91E
+2F91F;243AB;243AB;243AB;243AB; # (𤎫; 𤎫; 𤎫; 𤎫; 𤎫; ) CJK COMPATIBILITY IDEOGRAPH-2F91F
+2F920;7228;7228;7228;7228; # (爨; 爨; 爨; 爨; 爨; ) CJK COMPATIBILITY IDEOGRAPH-2F920
+2F921;7235;7235;7235;7235; # (爵; 爵; 爵; 爵; 爵; ) CJK COMPATIBILITY IDEOGRAPH-2F921
+2F922;7250;7250;7250;7250; # (牐; 牐; 牐; 牐; 牐; ) CJK COMPATIBILITY IDEOGRAPH-2F922
+2F923;24608;24608;24608;24608; # (𤘈; 𤘈; 𤘈; 𤘈; 𤘈; ) CJK COMPATIBILITY IDEOGRAPH-2F923
+2F924;7280;7280;7280;7280; # (犀; 犀; 犀; 犀; 犀; ) CJK COMPATIBILITY IDEOGRAPH-2F924
+2F925;7295;7295;7295;7295; # (犕; 犕; 犕; 犕; 犕; ) CJK COMPATIBILITY IDEOGRAPH-2F925
+2F926;24735;24735;24735;24735; # (𤜵; 𤜵; 𤜵; 𤜵; 𤜵; ) CJK COMPATIBILITY IDEOGRAPH-2F926
+2F927;24814;24814;24814;24814; # (𤠔; 𤠔; 𤠔; 𤠔; 𤠔; ) CJK COMPATIBILITY IDEOGRAPH-2F927
+2F928;737A;737A;737A;737A; # (獺; 獺; 獺; 獺; 獺; ) CJK COMPATIBILITY IDEOGRAPH-2F928
+2F929;738B;738B;738B;738B; # (王; 王; 王; 王; 王; ) CJK COMPATIBILITY IDEOGRAPH-2F929
+2F92A;3EAC;3EAC;3EAC;3EAC; # (㺬; 㺬; 㺬; 㺬; 㺬; ) CJK COMPATIBILITY IDEOGRAPH-2F92A
+2F92B;73A5;73A5;73A5;73A5; # (玥; 玥; 玥; 玥; 玥; ) CJK COMPATIBILITY IDEOGRAPH-2F92B
+2F92C;3EB8;3EB8;3EB8;3EB8; # (㺸; 㺸; 㺸; 㺸; 㺸; ) CJK COMPATIBILITY IDEOGRAPH-2F92C
+2F92D;3EB8;3EB8;3EB8;3EB8; # (㺸; 㺸; 㺸; 㺸; 㺸; ) CJK COMPATIBILITY IDEOGRAPH-2F92D
+2F92E;7447;7447;7447;7447; # (瑇; 瑇; 瑇; 瑇; 瑇; ) CJK COMPATIBILITY IDEOGRAPH-2F92E
+2F92F;745C;745C;745C;745C; # (瑜; 瑜; 瑜; 瑜; 瑜; ) CJK COMPATIBILITY IDEOGRAPH-2F92F
+2F930;7471;7471;7471;7471; # (瑱; 瑱; 瑱; 瑱; 瑱; ) CJK COMPATIBILITY IDEOGRAPH-2F930
+2F931;7485;7485;7485;7485; # (璅; 璅; 璅; 璅; 璅; ) CJK COMPATIBILITY IDEOGRAPH-2F931
+2F932;74CA;74CA;74CA;74CA; # (瓊; 瓊; 瓊; 瓊; 瓊; ) CJK COMPATIBILITY IDEOGRAPH-2F932
+2F933;3F1B;3F1B;3F1B;3F1B; # (㼛; 㼛; 㼛; 㼛; 㼛; ) CJK COMPATIBILITY IDEOGRAPH-2F933
+2F934;7524;7524;7524;7524; # (甤; 甤; 甤; 甤; 甤; ) CJK COMPATIBILITY IDEOGRAPH-2F934
+2F935;24C36;24C36;24C36;24C36; # (𤰶; 𤰶; 𤰶; 𤰶; 𤰶; ) CJK COMPATIBILITY IDEOGRAPH-2F935
+2F936;753E;753E;753E;753E; # (甾; 甾; 甾; 甾; 甾; ) CJK COMPATIBILITY IDEOGRAPH-2F936
+2F937;24C92;24C92;24C92;24C92; # (𤲒; 𤲒; 𤲒; 𤲒; 𤲒; ) CJK COMPATIBILITY IDEOGRAPH-2F937
+2F938;7570;7570;7570;7570; # (異; 異; 異; 異; 異; ) CJK COMPATIBILITY IDEOGRAPH-2F938
+2F939;2219F;2219F;2219F;2219F; # (𢆟; 𢆟; 𢆟; 𢆟; 𢆟; ) CJK COMPATIBILITY IDEOGRAPH-2F939
+2F93A;7610;7610;7610;7610; # (瘐; 瘐; 瘐; 瘐; 瘐; ) CJK COMPATIBILITY IDEOGRAPH-2F93A
+2F93B;24FA1;24FA1;24FA1;24FA1; # (𤾡; 𤾡; 𤾡; 𤾡; 𤾡; ) CJK COMPATIBILITY IDEOGRAPH-2F93B
+2F93C;24FB8;24FB8;24FB8;24FB8; # (𤾸; 𤾸; 𤾸; 𤾸; 𤾸; ) CJK COMPATIBILITY IDEOGRAPH-2F93C
+2F93D;25044;25044;25044;25044; # (𥁄; 𥁄; 𥁄; 𥁄; 𥁄; ) CJK COMPATIBILITY IDEOGRAPH-2F93D
+2F93E;3FFC;3FFC;3FFC;3FFC; # (㿼; 㿼; 㿼; 㿼; 㿼; ) CJK COMPATIBILITY IDEOGRAPH-2F93E
+2F93F;4008;4008;4008;4008; # (䀈; 䀈; 䀈; 䀈; 䀈; ) CJK COMPATIBILITY IDEOGRAPH-2F93F
+2F940;76F4;76F4;76F4;76F4; # (直; 直; 直; 直; 直; ) CJK COMPATIBILITY IDEOGRAPH-2F940
+2F941;250F3;250F3;250F3;250F3; # (𥃳; 𥃳; 𥃳; 𥃳; 𥃳; ) CJK COMPATIBILITY IDEOGRAPH-2F941
+2F942;250F2;250F2;250F2;250F2; # (𥃲; 𥃲; 𥃲; 𥃲; 𥃲; ) CJK COMPATIBILITY IDEOGRAPH-2F942
+2F943;25119;25119;25119;25119; # (𥄙; 𥄙; 𥄙; 𥄙; 𥄙; ) CJK COMPATIBILITY IDEOGRAPH-2F943
+2F944;25133;25133;25133;25133; # (𥄳; 𥄳; 𥄳; 𥄳; 𥄳; ) CJK COMPATIBILITY IDEOGRAPH-2F944
+2F945;771E;771E;771E;771E; # (眞; 眞; 眞; 眞; 眞; ) CJK COMPATIBILITY IDEOGRAPH-2F945
+2F946;771F;771F;771F;771F; # (真; 真; 真; 真; 真; ) CJK COMPATIBILITY IDEOGRAPH-2F946
+2F947;771F;771F;771F;771F; # (真; 真; 真; 真; 真; ) CJK COMPATIBILITY IDEOGRAPH-2F947
+2F948;774A;774A;774A;774A; # (睊; 睊; 睊; 睊; 睊; ) CJK COMPATIBILITY IDEOGRAPH-2F948
+2F949;4039;4039;4039;4039; # (䀹; 䀹; 䀹; 䀹; 䀹; ) CJK COMPATIBILITY IDEOGRAPH-2F949
+2F94A;778B;778B;778B;778B; # (瞋; 瞋; 瞋; 瞋; 瞋; ) CJK COMPATIBILITY IDEOGRAPH-2F94A
+2F94B;4046;4046;4046;4046; # (䁆; 䁆; 䁆; 䁆; 䁆; ) CJK COMPATIBILITY IDEOGRAPH-2F94B
+2F94C;4096;4096;4096;4096; # (䂖; 䂖; 䂖; 䂖; 䂖; ) CJK COMPATIBILITY IDEOGRAPH-2F94C
+2F94D;2541D;2541D;2541D;2541D; # (𥐝; 𥐝; 𥐝; 𥐝; 𥐝; ) CJK COMPATIBILITY IDEOGRAPH-2F94D
+2F94E;784E;784E;784E;784E; # (硎; 硎; 硎; 硎; 硎; ) CJK COMPATIBILITY IDEOGRAPH-2F94E
+2F94F;788C;788C;788C;788C; # (碌; 碌; 碌; 碌; 碌; ) CJK COMPATIBILITY IDEOGRAPH-2F94F
+2F950;78CC;78CC;78CC;78CC; # (磌; 磌; 磌; 磌; 磌; ) CJK COMPATIBILITY IDEOGRAPH-2F950
+2F951;40E3;40E3;40E3;40E3; # (䃣; 䃣; 䃣; 䃣; 䃣; ) CJK COMPATIBILITY IDEOGRAPH-2F951
+2F952;25626;25626;25626;25626; # (𥘦; 𥘦; 𥘦; 𥘦; 𥘦; ) CJK COMPATIBILITY IDEOGRAPH-2F952
+2F953;7956;7956;7956;7956; # (祖; 祖; 祖; 祖; 祖; ) CJK COMPATIBILITY IDEOGRAPH-2F953
+2F954;2569A;2569A;2569A;2569A; # (𥚚; 𥚚; 𥚚; 𥚚; 𥚚; ) CJK COMPATIBILITY IDEOGRAPH-2F954
+2F955;256C5;256C5;256C5;256C5; # (𥛅; 𥛅; 𥛅; 𥛅; 𥛅; ) CJK COMPATIBILITY IDEOGRAPH-2F955
+2F956;798F;798F;798F;798F; # (福; 福; 福; 福; 福; ) CJK COMPATIBILITY IDEOGRAPH-2F956
+2F957;79EB;79EB;79EB;79EB; # (秫; 秫; 秫; 秫; 秫; ) CJK COMPATIBILITY IDEOGRAPH-2F957
+2F958;412F;412F;412F;412F; # (䄯; 䄯; 䄯; 䄯; 䄯; ) CJK COMPATIBILITY IDEOGRAPH-2F958
+2F959;7A40;7A40;7A40;7A40; # (穀; 穀; 穀; 穀; 穀; ) CJK COMPATIBILITY IDEOGRAPH-2F959
+2F95A;7A4A;7A4A;7A4A;7A4A; # (穊; 穊; 穊; 穊; 穊; ) CJK COMPATIBILITY IDEOGRAPH-2F95A
+2F95B;7A4F;7A4F;7A4F;7A4F; # (穏; 穏; 穏; 穏; 穏; ) CJK COMPATIBILITY IDEOGRAPH-2F95B
+2F95C;2597C;2597C;2597C;2597C; # (𥥼; 𥥼; 𥥼; 𥥼; 𥥼; ) CJK COMPATIBILITY IDEOGRAPH-2F95C
+2F95D;25AA7;25AA7;25AA7;25AA7; # (𥪧; 𥪧; 𥪧; 𥪧; 𥪧; ) CJK COMPATIBILITY IDEOGRAPH-2F95D
+2F95E;25AA7;25AA7;25AA7;25AA7; # (𥪧; 𥪧; 𥪧; 𥪧; 𥪧; ) CJK COMPATIBILITY IDEOGRAPH-2F95E
+2F95F;7AEE;7AEE;7AEE;7AEE; # (竮; 竮; 竮; 竮; 竮; ) CJK COMPATIBILITY IDEOGRAPH-2F95F
+2F960;4202;4202;4202;4202; # (䈂; 䈂; 䈂; 䈂; 䈂; ) CJK COMPATIBILITY IDEOGRAPH-2F960
+2F961;25BAB;25BAB;25BAB;25BAB; # (𥮫; 𥮫; 𥮫; 𥮫; 𥮫; ) CJK COMPATIBILITY IDEOGRAPH-2F961
+2F962;7BC6;7BC6;7BC6;7BC6; # (篆; 篆; 篆; 篆; 篆; ) CJK COMPATIBILITY IDEOGRAPH-2F962
+2F963;7BC9;7BC9;7BC9;7BC9; # (築; 築; 築; 築; 築; ) CJK COMPATIBILITY IDEOGRAPH-2F963
+2F964;4227;4227;4227;4227; # (䈧; 䈧; 䈧; 䈧; 䈧; ) CJK COMPATIBILITY IDEOGRAPH-2F964
+2F965;25C80;25C80;25C80;25C80; # (𥲀; 𥲀; 𥲀; 𥲀; 𥲀; ) CJK COMPATIBILITY IDEOGRAPH-2F965
+2F966;7CD2;7CD2;7CD2;7CD2; # (糒; 糒; 糒; 糒; 糒; ) CJK COMPATIBILITY IDEOGRAPH-2F966
+2F967;42A0;42A0;42A0;42A0; # (䊠; 䊠; 䊠; 䊠; 䊠; ) CJK COMPATIBILITY IDEOGRAPH-2F967
+2F968;7CE8;7CE8;7CE8;7CE8; # (糨; 糨; 糨; 糨; 糨; ) CJK COMPATIBILITY IDEOGRAPH-2F968
+2F969;7CE3;7CE3;7CE3;7CE3; # (糣; 糣; 糣; 糣; 糣; ) CJK COMPATIBILITY IDEOGRAPH-2F969
+2F96A;7D00;7D00;7D00;7D00; # (紀; 紀; 紀; 紀; 紀; ) CJK COMPATIBILITY IDEOGRAPH-2F96A
+2F96B;25F86;25F86;25F86;25F86; # (𥾆; 𥾆; 𥾆; 𥾆; 𥾆; ) CJK COMPATIBILITY IDEOGRAPH-2F96B
+2F96C;7D63;7D63;7D63;7D63; # (絣; 絣; 絣; 絣; 絣; ) CJK COMPATIBILITY IDEOGRAPH-2F96C
+2F96D;4301;4301;4301;4301; # (䌁; 䌁; 䌁; 䌁; 䌁; ) CJK COMPATIBILITY IDEOGRAPH-2F96D
+2F96E;7DC7;7DC7;7DC7;7DC7; # (緇; 緇; 緇; 緇; 緇; ) CJK COMPATIBILITY IDEOGRAPH-2F96E
+2F96F;7E02;7E02;7E02;7E02; # (縂; 縂; 縂; 縂; 縂; ) CJK COMPATIBILITY IDEOGRAPH-2F96F
+2F970;7E45;7E45;7E45;7E45; # (繅; 繅; 繅; 繅; 繅; ) CJK COMPATIBILITY IDEOGRAPH-2F970
+2F971;4334;4334;4334;4334; # (䌴; 䌴; 䌴; 䌴; 䌴; ) CJK COMPATIBILITY IDEOGRAPH-2F971
+2F972;26228;26228;26228;26228; # (𦈨; 𦈨; 𦈨; 𦈨; 𦈨; ) CJK COMPATIBILITY IDEOGRAPH-2F972
+2F973;26247;26247;26247;26247; # (𦉇; 𦉇; 𦉇; 𦉇; 𦉇; ) CJK COMPATIBILITY IDEOGRAPH-2F973
+2F974;4359;4359;4359;4359; # (䍙; 䍙; 䍙; 䍙; 䍙; ) CJK COMPATIBILITY IDEOGRAPH-2F974
+2F975;262D9;262D9;262D9;262D9; # (𦋙; 𦋙; 𦋙; 𦋙; 𦋙; ) CJK COMPATIBILITY IDEOGRAPH-2F975
+2F976;7F7A;7F7A;7F7A;7F7A; # (罺; 罺; 罺; 罺; 罺; ) CJK COMPATIBILITY IDEOGRAPH-2F976
+2F977;2633E;2633E;2633E;2633E; # (𦌾; 𦌾; 𦌾; 𦌾; 𦌾; ) CJK COMPATIBILITY IDEOGRAPH-2F977
+2F978;7F95;7F95;7F95;7F95; # (羕; 羕; 羕; 羕; 羕; ) CJK COMPATIBILITY IDEOGRAPH-2F978
+2F979;7FFA;7FFA;7FFA;7FFA; # (翺; 翺; 翺; 翺; 翺; ) CJK COMPATIBILITY IDEOGRAPH-2F979
+2F97A;8005;8005;8005;8005; # (者; 者; 者; 者; 者; ) CJK COMPATIBILITY IDEOGRAPH-2F97A
+2F97B;264DA;264DA;264DA;264DA; # (𦓚; 𦓚; 𦓚; 𦓚; 𦓚; ) CJK COMPATIBILITY IDEOGRAPH-2F97B
+2F97C;26523;26523;26523;26523; # (𦔣; 𦔣; 𦔣; 𦔣; 𦔣; ) CJK COMPATIBILITY IDEOGRAPH-2F97C
+2F97D;8060;8060;8060;8060; # (聠; 聠; 聠; 聠; 聠; ) CJK COMPATIBILITY IDEOGRAPH-2F97D
+2F97E;265A8;265A8;265A8;265A8; # (𦖨; 𦖨; 𦖨; 𦖨; 𦖨; ) CJK COMPATIBILITY IDEOGRAPH-2F97E
+2F97F;8070;8070;8070;8070; # (聰; 聰; 聰; 聰; 聰; ) CJK COMPATIBILITY IDEOGRAPH-2F97F
+2F980;2335F;2335F;2335F;2335F; # (𣍟; 𣍟; 𣍟; 𣍟; 𣍟; ) CJK COMPATIBILITY IDEOGRAPH-2F980
+2F981;43D5;43D5;43D5;43D5; # (䏕; 䏕; 䏕; 䏕; 䏕; ) CJK COMPATIBILITY IDEOGRAPH-2F981
+2F982;80B2;80B2;80B2;80B2; # (育; 育; 育; 育; 育; ) CJK COMPATIBILITY IDEOGRAPH-2F982
+2F983;8103;8103;8103;8103; # (脃; 脃; 脃; 脃; 脃; ) CJK COMPATIBILITY IDEOGRAPH-2F983
+2F984;440B;440B;440B;440B; # (䐋; 䐋; 䐋; 䐋; 䐋; ) CJK COMPATIBILITY IDEOGRAPH-2F984
+2F985;813E;813E;813E;813E; # (脾; 脾; 脾; 脾; 脾; ) CJK COMPATIBILITY IDEOGRAPH-2F985
+2F986;5AB5;5AB5;5AB5;5AB5; # (媵; 媵; 媵; 媵; 媵; ) CJK COMPATIBILITY IDEOGRAPH-2F986
+2F987;267A7;267A7;267A7;267A7; # (𦞧; 𦞧; 𦞧; 𦞧; 𦞧; ) CJK COMPATIBILITY IDEOGRAPH-2F987
+2F988;267B5;267B5;267B5;267B5; # (𦞵; 𦞵; 𦞵; 𦞵; 𦞵; ) CJK COMPATIBILITY IDEOGRAPH-2F988
+2F989;23393;23393;23393;23393; # (𣎓; 𣎓; 𣎓; 𣎓; 𣎓; ) CJK COMPATIBILITY IDEOGRAPH-2F989
+2F98A;2339C;2339C;2339C;2339C; # (𣎜; 𣎜; 𣎜; 𣎜; 𣎜; ) CJK COMPATIBILITY IDEOGRAPH-2F98A
+2F98B;8201;8201;8201;8201; # (舁; 舁; 舁; 舁; 舁; ) CJK COMPATIBILITY IDEOGRAPH-2F98B
+2F98C;8204;8204;8204;8204; # (舄; 舄; 舄; 舄; 舄; ) CJK COMPATIBILITY IDEOGRAPH-2F98C
+2F98D;8F9E;8F9E;8F9E;8F9E; # (辞; 辞; 辞; 辞; 辞; ) CJK COMPATIBILITY IDEOGRAPH-2F98D
+2F98E;446B;446B;446B;446B; # (䑫; 䑫; 䑫; 䑫; 䑫; ) CJK COMPATIBILITY IDEOGRAPH-2F98E
+2F98F;8291;8291;8291;8291; # (芑; 芑; 芑; 芑; 芑; ) CJK COMPATIBILITY IDEOGRAPH-2F98F
+2F990;828B;828B;828B;828B; # (芋; 芋; 芋; 芋; 芋; ) CJK COMPATIBILITY IDEOGRAPH-2F990
+2F991;829D;829D;829D;829D; # (芝; 芝; 芝; 芝; 芝; ) CJK COMPATIBILITY IDEOGRAPH-2F991
+2F992;52B3;52B3;52B3;52B3; # (劳; 劳; 劳; 劳; 劳; ) CJK COMPATIBILITY IDEOGRAPH-2F992
+2F993;82B1;82B1;82B1;82B1; # (花; 花; 花; 花; 花; ) CJK COMPATIBILITY IDEOGRAPH-2F993
+2F994;82B3;82B3;82B3;82B3; # (芳; 芳; 芳; 芳; 芳; ) CJK COMPATIBILITY IDEOGRAPH-2F994
+2F995;82BD;82BD;82BD;82BD; # (芽; 芽; 芽; 芽; 芽; ) CJK COMPATIBILITY IDEOGRAPH-2F995
+2F996;82E6;82E6;82E6;82E6; # (苦; 苦; 苦; 苦; 苦; ) CJK COMPATIBILITY IDEOGRAPH-2F996
+2F997;26B3C;26B3C;26B3C;26B3C; # (𦬼; 𦬼; 𦬼; 𦬼; 𦬼; ) CJK COMPATIBILITY IDEOGRAPH-2F997
+2F998;82E5;82E5;82E5;82E5; # (若; 若; 若; 若; 若; ) CJK COMPATIBILITY IDEOGRAPH-2F998
+2F999;831D;831D;831D;831D; # (茝; 茝; 茝; 茝; 茝; ) CJK COMPATIBILITY IDEOGRAPH-2F999
+2F99A;8363;8363;8363;8363; # (荣; 荣; 荣; 荣; 荣; ) CJK COMPATIBILITY IDEOGRAPH-2F99A
+2F99B;83AD;83AD;83AD;83AD; # (莭; 莭; 莭; 莭; 莭; ) CJK COMPATIBILITY IDEOGRAPH-2F99B
+2F99C;8323;8323;8323;8323; # (茣; 茣; 茣; 茣; 茣; ) CJK COMPATIBILITY IDEOGRAPH-2F99C
+2F99D;83BD;83BD;83BD;83BD; # (莽; 莽; 莽; 莽; 莽; ) CJK COMPATIBILITY IDEOGRAPH-2F99D
+2F99E;83E7;83E7;83E7;83E7; # (菧; 菧; 菧; 菧; 菧; ) CJK COMPATIBILITY IDEOGRAPH-2F99E
+2F99F;8457;8457;8457;8457; # (著; 著; 著; 著; 著; ) CJK COMPATIBILITY IDEOGRAPH-2F99F
+2F9A0;8353;8353;8353;8353; # (荓; 荓; 荓; 荓; 荓; ) CJK COMPATIBILITY IDEOGRAPH-2F9A0
+2F9A1;83CA;83CA;83CA;83CA; # (菊; 菊; 菊; 菊; 菊; ) CJK COMPATIBILITY IDEOGRAPH-2F9A1
+2F9A2;83CC;83CC;83CC;83CC; # (菌; 菌; 菌; 菌; 菌; ) CJK COMPATIBILITY IDEOGRAPH-2F9A2
+2F9A3;83DC;83DC;83DC;83DC; # (菜; 菜; 菜; 菜; 菜; ) CJK COMPATIBILITY IDEOGRAPH-2F9A3
+2F9A4;26C36;26C36;26C36;26C36; # (𦰶; 𦰶; 𦰶; 𦰶; 𦰶; ) CJK COMPATIBILITY IDEOGRAPH-2F9A4
+2F9A5;26D6B;26D6B;26D6B;26D6B; # (𦵫; 𦵫; 𦵫; 𦵫; 𦵫; ) CJK COMPATIBILITY IDEOGRAPH-2F9A5
+2F9A6;26CD5;26CD5;26CD5;26CD5; # (𦳕; 𦳕; 𦳕; 𦳕; 𦳕; ) CJK COMPATIBILITY IDEOGRAPH-2F9A6
+2F9A7;452B;452B;452B;452B; # (䔫; 䔫; 䔫; 䔫; 䔫; ) CJK COMPATIBILITY IDEOGRAPH-2F9A7
+2F9A8;84F1;84F1;84F1;84F1; # (蓱; 蓱; 蓱; 蓱; 蓱; ) CJK COMPATIBILITY IDEOGRAPH-2F9A8
+2F9A9;84F3;84F3;84F3;84F3; # (蓳; 蓳; 蓳; 蓳; 蓳; ) CJK COMPATIBILITY IDEOGRAPH-2F9A9
+2F9AA;8516;8516;8516;8516; # (蔖; 蔖; 蔖; 蔖; 蔖; ) CJK COMPATIBILITY IDEOGRAPH-2F9AA
+2F9AB;273CA;273CA;273CA;273CA; # (𧏊; 𧏊; 𧏊; 𧏊; 𧏊; ) CJK COMPATIBILITY IDEOGRAPH-2F9AB
+2F9AC;8564;8564;8564;8564; # (蕤; 蕤; 蕤; 蕤; 蕤; ) CJK COMPATIBILITY IDEOGRAPH-2F9AC
+2F9AD;26F2C;26F2C;26F2C;26F2C; # (𦼬; 𦼬; 𦼬; 𦼬; 𦼬; ) CJK COMPATIBILITY IDEOGRAPH-2F9AD
+2F9AE;455D;455D;455D;455D; # (䕝; 䕝; 䕝; 䕝; 䕝; ) CJK COMPATIBILITY IDEOGRAPH-2F9AE
+2F9AF;4561;4561;4561;4561; # (䕡; 䕡; 䕡; 䕡; 䕡; ) CJK COMPATIBILITY IDEOGRAPH-2F9AF
+2F9B0;26FB1;26FB1;26FB1;26FB1; # (𦾱; 𦾱; 𦾱; 𦾱; 𦾱; ) CJK COMPATIBILITY IDEOGRAPH-2F9B0
+2F9B1;270D2;270D2;270D2;270D2; # (𧃒; 𧃒; 𧃒; 𧃒; 𧃒; ) CJK COMPATIBILITY IDEOGRAPH-2F9B1
+2F9B2;456B;456B;456B;456B; # (䕫; 䕫; 䕫; 䕫; 䕫; ) CJK COMPATIBILITY IDEOGRAPH-2F9B2
+2F9B3;8650;8650;8650;8650; # (虐; 虐; 虐; 虐; 虐; ) CJK COMPATIBILITY IDEOGRAPH-2F9B3
+2F9B4;865C;865C;865C;865C; # (虜; 虜; 虜; 虜; 虜; ) CJK COMPATIBILITY IDEOGRAPH-2F9B4
+2F9B5;8667;8667;8667;8667; # (虧; 虧; 虧; 虧; 虧; ) CJK COMPATIBILITY IDEOGRAPH-2F9B5
+2F9B6;8669;8669;8669;8669; # (虩; 虩; 虩; 虩; 虩; ) CJK COMPATIBILITY IDEOGRAPH-2F9B6
+2F9B7;86A9;86A9;86A9;86A9; # (蚩; 蚩; 蚩; 蚩; 蚩; ) CJK COMPATIBILITY IDEOGRAPH-2F9B7
+2F9B8;8688;8688;8688;8688; # (蚈; 蚈; 蚈; 蚈; 蚈; ) CJK COMPATIBILITY IDEOGRAPH-2F9B8
+2F9B9;870E;870E;870E;870E; # (蜎; 蜎; 蜎; 蜎; 蜎; ) CJK COMPATIBILITY IDEOGRAPH-2F9B9
+2F9BA;86E2;86E2;86E2;86E2; # (蛢; 蛢; 蛢; 蛢; 蛢; ) CJK COMPATIBILITY IDEOGRAPH-2F9BA
+2F9BB;8779;8779;8779;8779; # (蝹; 蝹; 蝹; 蝹; 蝹; ) CJK COMPATIBILITY IDEOGRAPH-2F9BB
+2F9BC;8728;8728;8728;8728; # (蜨; 蜨; 蜨; 蜨; 蜨; ) CJK COMPATIBILITY IDEOGRAPH-2F9BC
+2F9BD;876B;876B;876B;876B; # (蝫; 蝫; 蝫; 蝫; 蝫; ) CJK COMPATIBILITY IDEOGRAPH-2F9BD
+2F9BE;8786;8786;8786;8786; # (螆; 螆; 螆; 螆; 螆; ) CJK COMPATIBILITY IDEOGRAPH-2F9BE
+2F9BF;45D7;45D7;45D7;45D7; # (䗗; 䗗; 䗗; 䗗; 䗗; ) CJK COMPATIBILITY IDEOGRAPH-2F9BF
+2F9C0;87E1;87E1;87E1;87E1; # (蟡; 蟡; 蟡; 蟡; 蟡; ) CJK COMPATIBILITY IDEOGRAPH-2F9C0
+2F9C1;8801;8801;8801;8801; # (蠁; 蠁; 蠁; 蠁; 蠁; ) CJK COMPATIBILITY IDEOGRAPH-2F9C1
+2F9C2;45F9;45F9;45F9;45F9; # (䗹; 䗹; 䗹; 䗹; 䗹; ) CJK COMPATIBILITY IDEOGRAPH-2F9C2
+2F9C3;8860;8860;8860;8860; # (衠; 衠; 衠; 衠; 衠; ) CJK COMPATIBILITY IDEOGRAPH-2F9C3
+2F9C4;8863;8863;8863;8863; # (衣; 衣; 衣; 衣; 衣; ) CJK COMPATIBILITY IDEOGRAPH-2F9C4
+2F9C5;27667;27667;27667;27667; # (𧙧; 𧙧; 𧙧; 𧙧; 𧙧; ) CJK COMPATIBILITY IDEOGRAPH-2F9C5
+2F9C6;88D7;88D7;88D7;88D7; # (裗; 裗; 裗; 裗; 裗; ) CJK COMPATIBILITY IDEOGRAPH-2F9C6
+2F9C7;88DE;88DE;88DE;88DE; # (裞; 裞; 裞; 裞; 裞; ) CJK COMPATIBILITY IDEOGRAPH-2F9C7
+2F9C8;4635;4635;4635;4635; # (䘵; 䘵; 䘵; 䘵; 䘵; ) CJK COMPATIBILITY IDEOGRAPH-2F9C8
+2F9C9;88FA;88FA;88FA;88FA; # (裺; 裺; 裺; 裺; 裺; ) CJK COMPATIBILITY IDEOGRAPH-2F9C9
+2F9CA;34BB;34BB;34BB;34BB; # (㒻; 㒻; 㒻; 㒻; 㒻; ) CJK COMPATIBILITY IDEOGRAPH-2F9CA
+2F9CB;278AE;278AE;278AE;278AE; # (𧢮; 𧢮; 𧢮; 𧢮; 𧢮; ) CJK COMPATIBILITY IDEOGRAPH-2F9CB
+2F9CC;27966;27966;27966;27966; # (𧥦; 𧥦; 𧥦; 𧥦; 𧥦; ) CJK COMPATIBILITY IDEOGRAPH-2F9CC
+2F9CD;46BE;46BE;46BE;46BE; # (䚾; 䚾; 䚾; 䚾; 䚾; ) CJK COMPATIBILITY IDEOGRAPH-2F9CD
+2F9CE;46C7;46C7;46C7;46C7; # (䛇; 䛇; 䛇; 䛇; 䛇; ) CJK COMPATIBILITY IDEOGRAPH-2F9CE
+2F9CF;8AA0;8AA0;8AA0;8AA0; # (誠; 誠; 誠; 誠; 誠; ) CJK COMPATIBILITY IDEOGRAPH-2F9CF
+2F9D0;8AED;8AED;8AED;8AED; # (諭; 諭; 諭; 諭; 諭; ) CJK COMPATIBILITY IDEOGRAPH-2F9D0
+2F9D1;8B8A;8B8A;8B8A;8B8A; # (變; 變; 變; 變; 變; ) CJK COMPATIBILITY IDEOGRAPH-2F9D1
+2F9D2;8C55;8C55;8C55;8C55; # (豕; 豕; 豕; 豕; 豕; ) CJK COMPATIBILITY IDEOGRAPH-2F9D2
+2F9D3;27CA8;27CA8;27CA8;27CA8; # (𧲨; 𧲨; 𧲨; 𧲨; 𧲨; ) CJK COMPATIBILITY IDEOGRAPH-2F9D3
+2F9D4;8CAB;8CAB;8CAB;8CAB; # (貫; 貫; 貫; 貫; 貫; ) CJK COMPATIBILITY IDEOGRAPH-2F9D4
+2F9D5;8CC1;8CC1;8CC1;8CC1; # (賁; 賁; 賁; 賁; 賁; ) CJK COMPATIBILITY IDEOGRAPH-2F9D5
+2F9D6;8D1B;8D1B;8D1B;8D1B; # (贛; 贛; 贛; 贛; 贛; ) CJK COMPATIBILITY IDEOGRAPH-2F9D6
+2F9D7;8D77;8D77;8D77;8D77; # (起; 起; 起; 起; 起; ) CJK COMPATIBILITY IDEOGRAPH-2F9D7
+2F9D8;27F2F;27F2F;27F2F;27F2F; # (𧼯; 𧼯; 𧼯; 𧼯; 𧼯; ) CJK COMPATIBILITY IDEOGRAPH-2F9D8
+2F9D9;20804;20804;20804;20804; # (𠠄; 𠠄; 𠠄; 𠠄; 𠠄; ) CJK COMPATIBILITY IDEOGRAPH-2F9D9
+2F9DA;8DCB;8DCB;8DCB;8DCB; # (跋; 跋; 跋; 跋; 跋; ) CJK COMPATIBILITY IDEOGRAPH-2F9DA
+2F9DB;8DBC;8DBC;8DBC;8DBC; # (趼; 趼; 趼; 趼; 趼; ) CJK COMPATIBILITY IDEOGRAPH-2F9DB
+2F9DC;8DF0;8DF0;8DF0;8DF0; # (跰; 跰; 跰; 跰; 跰; ) CJK COMPATIBILITY IDEOGRAPH-2F9DC
+2F9DD;208DE;208DE;208DE;208DE; # (𠣞; 𠣞; 𠣞; 𠣞; 𠣞; ) CJK COMPATIBILITY IDEOGRAPH-2F9DD
+2F9DE;8ED4;8ED4;8ED4;8ED4; # (軔; 軔; 軔; 軔; 軔; ) CJK COMPATIBILITY IDEOGRAPH-2F9DE
+2F9DF;8F38;8F38;8F38;8F38; # (輸; 輸; 輸; 輸; 輸; ) CJK COMPATIBILITY IDEOGRAPH-2F9DF
+2F9E0;285D2;285D2;285D2;285D2; # (𨗒; 𨗒; 𨗒; 𨗒; 𨗒; ) CJK COMPATIBILITY IDEOGRAPH-2F9E0
+2F9E1;285ED;285ED;285ED;285ED; # (𨗭; 𨗭; 𨗭; 𨗭; 𨗭; ) CJK COMPATIBILITY IDEOGRAPH-2F9E1
+2F9E2;9094;9094;9094;9094; # (邔; 邔; 邔; 邔; 邔; ) CJK COMPATIBILITY IDEOGRAPH-2F9E2
+2F9E3;90F1;90F1;90F1;90F1; # (郱; 郱; 郱; 郱; 郱; ) CJK COMPATIBILITY IDEOGRAPH-2F9E3
+2F9E4;9111;9111;9111;9111; # (鄑; 鄑; 鄑; 鄑; 鄑; ) CJK COMPATIBILITY IDEOGRAPH-2F9E4
+2F9E5;2872E;2872E;2872E;2872E; # (𨜮; 𨜮; 𨜮; 𨜮; 𨜮; ) CJK COMPATIBILITY IDEOGRAPH-2F9E5
+2F9E6;911B;911B;911B;911B; # (鄛; 鄛; 鄛; 鄛; 鄛; ) CJK COMPATIBILITY IDEOGRAPH-2F9E6
+2F9E7;9238;9238;9238;9238; # (鈸; 鈸; 鈸; 鈸; 鈸; ) CJK COMPATIBILITY IDEOGRAPH-2F9E7
+2F9E8;92D7;92D7;92D7;92D7; # (鋗; 鋗; 鋗; 鋗; 鋗; ) CJK COMPATIBILITY IDEOGRAPH-2F9E8
+2F9E9;92D8;92D8;92D8;92D8; # (鋘; 鋘; 鋘; 鋘; 鋘; ) CJK COMPATIBILITY IDEOGRAPH-2F9E9
+2F9EA;927C;927C;927C;927C; # (鉼; 鉼; 鉼; 鉼; 鉼; ) CJK COMPATIBILITY IDEOGRAPH-2F9EA
+2F9EB;93F9;93F9;93F9;93F9; # (鏹; 鏹; 鏹; 鏹; 鏹; ) CJK COMPATIBILITY IDEOGRAPH-2F9EB
+2F9EC;9415;9415;9415;9415; # (鐕; 鐕; 鐕; 鐕; 鐕; ) CJK COMPATIBILITY IDEOGRAPH-2F9EC
+2F9ED;28BFA;28BFA;28BFA;28BFA; # (𨯺; 𨯺; 𨯺; 𨯺; 𨯺; ) CJK COMPATIBILITY IDEOGRAPH-2F9ED
+2F9EE;958B;958B;958B;958B; # (開; 開; 開; 開; 開; ) CJK COMPATIBILITY IDEOGRAPH-2F9EE
+2F9EF;4995;4995;4995;4995; # (䦕; 䦕; 䦕; 䦕; 䦕; ) CJK COMPATIBILITY IDEOGRAPH-2F9EF
+2F9F0;95B7;95B7;95B7;95B7; # (閷; 閷; 閷; 閷; 閷; ) CJK COMPATIBILITY IDEOGRAPH-2F9F0
+2F9F1;28D77;28D77;28D77;28D77; # (𨵷; 𨵷; 𨵷; 𨵷; 𨵷; ) CJK COMPATIBILITY IDEOGRAPH-2F9F1
+2F9F2;49E6;49E6;49E6;49E6; # (䧦; 䧦; 䧦; 䧦; 䧦; ) CJK COMPATIBILITY IDEOGRAPH-2F9F2
+2F9F3;96C3;96C3;96C3;96C3; # (雃; 雃; 雃; 雃; 雃; ) CJK COMPATIBILITY IDEOGRAPH-2F9F3
+2F9F4;5DB2;5DB2;5DB2;5DB2; # (嶲; 嶲; 嶲; 嶲; 嶲; ) CJK COMPATIBILITY IDEOGRAPH-2F9F4
+2F9F5;9723;9723;9723;9723; # (霣; 霣; 霣; 霣; 霣; ) CJK COMPATIBILITY IDEOGRAPH-2F9F5
+2F9F6;29145;29145;29145;29145; # (𩅅; 𩅅; 𩅅; 𩅅; 𩅅; ) CJK COMPATIBILITY IDEOGRAPH-2F9F6
+2F9F7;2921A;2921A;2921A;2921A; # (𩈚; 𩈚; 𩈚; 𩈚; 𩈚; ) CJK COMPATIBILITY IDEOGRAPH-2F9F7
+2F9F8;4A6E;4A6E;4A6E;4A6E; # (䩮; 䩮; 䩮; 䩮; 䩮; ) CJK COMPATIBILITY IDEOGRAPH-2F9F8
+2F9F9;4A76;4A76;4A76;4A76; # (䩶; 䩶; 䩶; 䩶; 䩶; ) CJK COMPATIBILITY IDEOGRAPH-2F9F9
+2F9FA;97E0;97E0;97E0;97E0; # (韠; 韠; 韠; 韠; 韠; ) CJK COMPATIBILITY IDEOGRAPH-2F9FA
+2F9FB;2940A;2940A;2940A;2940A; # (𩐊; 𩐊; 𩐊; 𩐊; 𩐊; ) CJK COMPATIBILITY IDEOGRAPH-2F9FB
+2F9FC;4AB2;4AB2;4AB2;4AB2; # (䪲; 䪲; 䪲; 䪲; 䪲; ) CJK COMPATIBILITY IDEOGRAPH-2F9FC
+2F9FD;29496;29496;29496;29496; # (𩒖; 𩒖; 𩒖; 𩒖; 𩒖; ) CJK COMPATIBILITY IDEOGRAPH-2F9FD
+2F9FE;980B;980B;980B;980B; # (頋; 頋; 頋; 頋; 頋; ) CJK COMPATIBILITY IDEOGRAPH-2F9FE
+2F9FF;980B;980B;980B;980B; # (頋; 頋; 頋; 頋; 頋; ) CJK COMPATIBILITY IDEOGRAPH-2F9FF
+2FA00;9829;9829;9829;9829; # (頩; 頩; 頩; 頩; 頩; ) CJK COMPATIBILITY IDEOGRAPH-2FA00
+2FA01;295B6;295B6;295B6;295B6; # (𩖶; 𩖶; 𩖶; 𩖶; 𩖶; ) CJK COMPATIBILITY IDEOGRAPH-2FA01
+2FA02;98E2;98E2;98E2;98E2; # (飢; 飢; 飢; 飢; 飢; ) CJK COMPATIBILITY IDEOGRAPH-2FA02
+2FA03;4B33;4B33;4B33;4B33; # (䬳; 䬳; 䬳; 䬳; 䬳; ) CJK COMPATIBILITY IDEOGRAPH-2FA03
+2FA04;9929;9929;9929;9929; # (餩; 餩; 餩; 餩; 餩; ) CJK COMPATIBILITY IDEOGRAPH-2FA04
+2FA05;99A7;99A7;99A7;99A7; # (馧; 馧; 馧; 馧; 馧; ) CJK COMPATIBILITY IDEOGRAPH-2FA05
+2FA06;99C2;99C2;99C2;99C2; # (駂; 駂; 駂; 駂; 駂; ) CJK COMPATIBILITY IDEOGRAPH-2FA06
+2FA07;99FE;99FE;99FE;99FE; # (駾; 駾; 駾; 駾; 駾; ) CJK COMPATIBILITY IDEOGRAPH-2FA07
+2FA08;4BCE;4BCE;4BCE;4BCE; # (䯎; 䯎; 䯎; 䯎; 䯎; ) CJK COMPATIBILITY IDEOGRAPH-2FA08
+2FA09;29B30;29B30;29B30;29B30; # (𩬰; 𩬰; 𩬰; 𩬰; 𩬰; ) CJK COMPATIBILITY IDEOGRAPH-2FA09
+2FA0A;9B12;9B12;9B12;9B12; # (鬒; 鬒; 鬒; 鬒; 鬒; ) CJK COMPATIBILITY IDEOGRAPH-2FA0A
+2FA0B;9C40;9C40;9C40;9C40; # (鱀; 鱀; 鱀; 鱀; 鱀; ) CJK COMPATIBILITY IDEOGRAPH-2FA0B
+2FA0C;9CFD;9CFD;9CFD;9CFD; # (鳽; 鳽; 鳽; 鳽; 鳽; ) CJK COMPATIBILITY IDEOGRAPH-2FA0C
+2FA0D;4CCE;4CCE;4CCE;4CCE; # (䳎; 䳎; 䳎; 䳎; 䳎; ) CJK COMPATIBILITY IDEOGRAPH-2FA0D
+2FA0E;4CED;4CED;4CED;4CED; # (䳭; 䳭; 䳭; 䳭; 䳭; ) CJK COMPATIBILITY IDEOGRAPH-2FA0E
+2FA0F;9D67;9D67;9D67;9D67; # (鵧; 鵧; 鵧; 鵧; 鵧; ) CJK COMPATIBILITY IDEOGRAPH-2FA0F
+2FA10;2A0CE;2A0CE;2A0CE;2A0CE; # (𪃎; 𪃎; 𪃎; 𪃎; 𪃎; ) CJK COMPATIBILITY IDEOGRAPH-2FA10
+2FA11;4CF8;4CF8;4CF8;4CF8; # (䳸; 䳸; 䳸; 䳸; 䳸; ) CJK COMPATIBILITY IDEOGRAPH-2FA11
+2FA12;2A105;2A105;2A105;2A105; # (𪄅; 𪄅; 𪄅; 𪄅; 𪄅; ) CJK COMPATIBILITY IDEOGRAPH-2FA12
+2FA13;2A20E;2A20E;2A20E;2A20E; # (𪈎; 𪈎; 𪈎; 𪈎; 𪈎; ) CJK COMPATIBILITY IDEOGRAPH-2FA13
+2FA14;2A291;2A291;2A291;2A291; # (𪊑; 𪊑; 𪊑; 𪊑; 𪊑; ) CJK COMPATIBILITY IDEOGRAPH-2FA14
+2FA15;9EBB;9EBB;9EBB;9EBB; # (麻; 麻; 麻; 麻; 麻; ) CJK COMPATIBILITY IDEOGRAPH-2FA15
+2FA16;4D56;4D56;4D56;4D56; # (䵖; 䵖; 䵖; 䵖; 䵖; ) CJK COMPATIBILITY IDEOGRAPH-2FA16
+2FA17;9EF9;9EF9;9EF9;9EF9; # (黹; 黹; 黹; 黹; 黹; ) CJK COMPATIBILITY IDEOGRAPH-2FA17
+2FA18;9EFE;9EFE;9EFE;9EFE; # (黾; 黾; 黾; 黾; 黾; ) CJK COMPATIBILITY IDEOGRAPH-2FA18
+2FA19;9F05;9F05;9F05;9F05; # (鼅; 鼅; 鼅; 鼅; 鼅; ) CJK COMPATIBILITY IDEOGRAPH-2FA19
+2FA1A;9F0F;9F0F;9F0F;9F0F; # (鼏; 鼏; 鼏; 鼏; 鼏; ) CJK COMPATIBILITY IDEOGRAPH-2FA1A
+2FA1B;9F16;9F16;9F16;9F16; # (鼖; 鼖; 鼖; 鼖; 鼖; ) CJK COMPATIBILITY IDEOGRAPH-2FA1B
+2FA1C;9F3B;9F3B;9F3B;9F3B; # (鼻; 鼻; 鼻; 鼻; 鼻; ) CJK COMPATIBILITY IDEOGRAPH-2FA1C
+2FA1D;2A600;2A600;2A600;2A600; # (𪘀; 𪘀; 𪘀; 𪘀; 𪘀; ) CJK COMPATIBILITY IDEOGRAPH-2FA1D
+#
+@Part2 # Canonical Order Test
+#
+0061 0315 0300 05AE 0300 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; # (a◌̕◌̀◌֮◌̀b; à◌֮◌̀◌̕b; a◌֮◌̀◌̀◌̕b; à◌֮◌̀◌̕b; a◌֮◌̀◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRAVE ACCENT, LATIN SMALL LETTER B
+0061 0300 0315 0300 05AE 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; # (a◌̀◌̕◌̀◌֮b; à◌֮◌̀◌̕b; a◌֮◌̀◌̀◌̕b; à◌֮◌̀◌̕b; a◌֮◌̀◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0301 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062; # (a◌̕◌̀◌֮◌́b; à◌֮◌́◌̕b; a◌֮◌̀◌́◌̕b; à◌֮◌́◌̕b; a◌֮◌̀◌́◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING ACUTE ACCENT, LATIN SMALL LETTER B
+0061 0301 0315 0300 05AE 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062; # (a◌́◌̕◌̀◌֮b; á◌֮◌̀◌̕b; a◌֮◌́◌̀◌̕b; á◌֮◌̀◌̕b; a◌֮◌́◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ACUTE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0302 0062;00E0 05AE 0302 0315 0062;0061 05AE 0300 0302 0315 0062;00E0 05AE 0302 0315 0062;0061 05AE 0300 0302 0315 0062; # (a◌̕◌̀◌֮◌̂b; à◌֮◌̂◌̕b; a◌֮◌̀◌̂◌̕b; à◌֮◌̂◌̕b; a◌֮◌̀◌̂◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CIRCUMFLEX ACCENT, LATIN SMALL LETTER B
+0061 0302 0315 0300 05AE 0062;1EA7 05AE 0315 0062;0061 05AE 0302 0300 0315 0062;1EA7 05AE 0315 0062;0061 05AE 0302 0300 0315 0062; # (a◌̂◌̕◌̀◌֮b; ầ◌֮◌̕b; a◌֮◌̂◌̀◌̕b; ầ◌֮◌̕b; a◌֮◌̂◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CIRCUMFLEX ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0303 0062;00E0 05AE 0303 0315 0062;0061 05AE 0300 0303 0315 0062;00E0 05AE 0303 0315 0062;0061 05AE 0300 0303 0315 0062; # (a◌̕◌̀◌֮◌̃b; à◌֮◌̃◌̕b; a◌֮◌̀◌̃◌̕b; à◌֮◌̃◌̕b; a◌֮◌̀◌̃◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING TILDE, LATIN SMALL LETTER B
+0061 0303 0315 0300 05AE 0062;00E3 05AE 0300 0315 0062;0061 05AE 0303 0300 0315 0062;00E3 05AE 0300 0315 0062;0061 05AE 0303 0300 0315 0062; # (a◌̃◌̕◌̀◌֮b; ã◌֮◌̀◌̕b; a◌֮◌̃◌̀◌̕b; ã◌֮◌̀◌̕b; a◌֮◌̃◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING TILDE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0304 0062;00E0 05AE 0304 0315 0062;0061 05AE 0300 0304 0315 0062;00E0 05AE 0304 0315 0062;0061 05AE 0300 0304 0315 0062; # (a◌̕◌̀◌֮◌̄b; à◌֮◌̄◌̕b; a◌֮◌̀◌̄◌̕b; à◌֮◌̄◌̕b; a◌֮◌̀◌̄◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING MACRON, LATIN SMALL LETTER B
+0061 0304 0315 0300 05AE 0062;0101 05AE 0300 0315 0062;0061 05AE 0304 0300 0315 0062;0101 05AE 0300 0315 0062;0061 05AE 0304 0300 0315 0062; # (a◌̄◌̕◌̀◌֮b; ā◌֮◌̀◌̕b; a◌֮◌̄◌̀◌̕b; ā◌֮◌̀◌̕b; a◌֮◌̄◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING MACRON, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0305 0062;00E0 05AE 0305 0315 0062;0061 05AE 0300 0305 0315 0062;00E0 05AE 0305 0315 0062;0061 05AE 0300 0305 0315 0062; # (a◌̕◌̀◌֮◌̅b; à◌֮◌̅◌̕b; a◌֮◌̀◌̅◌̕b; à◌֮◌̅◌̕b; a◌֮◌̀◌̅◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING OVERLINE, LATIN SMALL LETTER B
+0061 0305 0315 0300 05AE 0062;0061 05AE 0305 0300 0315 0062;0061 05AE 0305 0300 0315 0062;0061 05AE 0305 0300 0315 0062;0061 05AE 0305 0300 0315 0062; # (a◌̅◌̕◌̀◌֮b; a◌֮◌̅◌̀◌̕b; a◌֮◌̅◌̀◌̕b; a◌֮◌̅◌̀◌̕b; a◌֮◌̅◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING OVERLINE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0306 0062;00E0 05AE 0306 0315 0062;0061 05AE 0300 0306 0315 0062;00E0 05AE 0306 0315 0062;0061 05AE 0300 0306 0315 0062; # (a◌̕◌̀◌֮◌̆b; à◌֮◌̆◌̕b; a◌֮◌̀◌̆◌̕b; à◌֮◌̆◌̕b; a◌֮◌̀◌̆◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING BREVE, LATIN SMALL LETTER B
+0061 0306 0315 0300 05AE 0062;1EB1 05AE 0315 0062;0061 05AE 0306 0300 0315 0062;1EB1 05AE 0315 0062;0061 05AE 0306 0300 0315 0062; # (a◌̆◌̕◌̀◌֮b; ằ◌֮◌̕b; a◌֮◌̆◌̀◌̕b; ằ◌֮◌̕b; a◌֮◌̆◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING BREVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0307 0062;00E0 05AE 0307 0315 0062;0061 05AE 0300 0307 0315 0062;00E0 05AE 0307 0315 0062;0061 05AE 0300 0307 0315 0062; # (a◌̕◌̀◌֮◌̇b; à◌֮◌̇◌̕b; a◌֮◌̀◌̇◌̕b; à◌֮◌̇◌̕b; a◌֮◌̀◌̇◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOT ABOVE, LATIN SMALL LETTER B
+0061 0307 0315 0300 05AE 0062;0227 05AE 0300 0315 0062;0061 05AE 0307 0300 0315 0062;0227 05AE 0300 0315 0062;0061 05AE 0307 0300 0315 0062; # (a◌̇◌̕◌̀◌֮b; ȧ◌֮◌̀◌̕b; a◌֮◌̇◌̀◌̕b; ȧ◌֮◌̀◌̕b; a◌֮◌̇◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0308 0062;00E0 05AE 0308 0315 0062;0061 05AE 0300 0308 0315 0062;00E0 05AE 0308 0315 0062;0061 05AE 0300 0308 0315 0062; # (a◌̕◌̀◌֮◌̈b; à◌֮◌̈◌̕b; a◌֮◌̀◌̈◌̕b; à◌֮◌̈◌̕b; a◌֮◌̀◌̈◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DIAERESIS, LATIN SMALL LETTER B
+0061 0308 0315 0300 05AE 0062;00E4 05AE 0300 0315 0062;0061 05AE 0308 0300 0315 0062;00E4 05AE 0300 0315 0062;0061 05AE 0308 0300 0315 0062; # (a◌̈◌̕◌̀◌֮b; ä◌֮◌̀◌̕b; a◌֮◌̈◌̀◌̕b; ä◌֮◌̀◌̕b; a◌֮◌̈◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DIAERESIS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0309 0062;00E0 05AE 0309 0315 0062;0061 05AE 0300 0309 0315 0062;00E0 05AE 0309 0315 0062;0061 05AE 0300 0309 0315 0062; # (a◌̕◌̀◌֮◌̉b; à◌֮◌̉◌̕b; a◌֮◌̀◌̉◌̕b; à◌֮◌̉◌̕b; a◌֮◌̀◌̉◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING HOOK ABOVE, LATIN SMALL LETTER B
+0061 0309 0315 0300 05AE 0062;1EA3 05AE 0300 0315 0062;0061 05AE 0309 0300 0315 0062;1EA3 05AE 0300 0315 0062;0061 05AE 0309 0300 0315 0062; # (a◌̉◌̕◌̀◌֮b; ả◌֮◌̀◌̕b; a◌֮◌̉◌̀◌̕b; ả◌֮◌̀◌̕b; a◌֮◌̉◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING HOOK ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 030A 0062;00E0 05AE 030A 0315 0062;0061 05AE 0300 030A 0315 0062;00E0 05AE 030A 0315 0062;0061 05AE 0300 030A 0315 0062; # (a◌̕◌̀◌֮◌̊b; à◌֮◌̊◌̕b; a◌֮◌̀◌̊◌̕b; à◌֮◌̊◌̕b; a◌֮◌̀◌̊◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING RING ABOVE, LATIN SMALL LETTER B
+0061 030A 0315 0300 05AE 0062;00E5 05AE 0300 0315 0062;0061 05AE 030A 0300 0315 0062;00E5 05AE 0300 0315 0062;0061 05AE 030A 0300 0315 0062; # (a◌̊◌̕◌̀◌֮b; å◌֮◌̀◌̕b; a◌֮◌̊◌̀◌̕b; å◌֮◌̀◌̕b; a◌֮◌̊◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING RING ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 030B 0062;00E0 05AE 030B 0315 0062;0061 05AE 0300 030B 0315 0062;00E0 05AE 030B 0315 0062;0061 05AE 0300 030B 0315 0062; # (a◌̕◌̀◌֮◌̋b; à◌֮◌̋◌̕b; a◌֮◌̀◌̋◌̕b; à◌֮◌̋◌̕b; a◌֮◌̀◌̋◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOUBLE ACUTE ACCENT, LATIN SMALL LETTER B
+0061 030B 0315 0300 05AE 0062;0061 05AE 030B 0300 0315 0062;0061 05AE 030B 0300 0315 0062;0061 05AE 030B 0300 0315 0062;0061 05AE 030B 0300 0315 0062; # (a◌̋◌̕◌̀◌֮b; a◌֮◌̋◌̀◌̕b; a◌֮◌̋◌̀◌̕b; a◌֮◌̋◌̀◌̕b; a◌֮◌̋◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOUBLE ACUTE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 030C 0062;00E0 05AE 030C 0315 0062;0061 05AE 0300 030C 0315 0062;00E0 05AE 030C 0315 0062;0061 05AE 0300 030C 0315 0062; # (a◌̕◌̀◌֮◌̌b; à◌֮◌̌◌̕b; a◌֮◌̀◌̌◌̕b; à◌֮◌̌◌̕b; a◌֮◌̀◌̌◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CARON, LATIN SMALL LETTER B
+0061 030C 0315 0300 05AE 0062;01CE 05AE 0300 0315 0062;0061 05AE 030C 0300 0315 0062;01CE 05AE 0300 0315 0062;0061 05AE 030C 0300 0315 0062; # (a◌̌◌̕◌̀◌֮b; ǎ◌֮◌̀◌̕b; a◌֮◌̌◌̀◌̕b; ǎ◌֮◌̀◌̕b; a◌֮◌̌◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CARON, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 030D 0062;00E0 05AE 030D 0315 0062;0061 05AE 0300 030D 0315 0062;00E0 05AE 030D 0315 0062;0061 05AE 0300 030D 0315 0062; # (a◌̕◌̀◌֮◌̍b; à◌֮◌̍◌̕b; a◌֮◌̀◌̍◌̕b; à◌֮◌̍◌̕b; a◌֮◌̀◌̍◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING VERTICAL LINE ABOVE, LATIN SMALL LETTER B
+0061 030D 0315 0300 05AE 0062;0061 05AE 030D 0300 0315 0062;0061 05AE 030D 0300 0315 0062;0061 05AE 030D 0300 0315 0062;0061 05AE 030D 0300 0315 0062; # (a◌̍◌̕◌̀◌֮b; a◌֮◌̍◌̀◌̕b; a◌֮◌̍◌̀◌̕b; a◌֮◌̍◌̀◌̕b; a◌֮◌̍◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING VERTICAL LINE ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 030E 0062;00E0 05AE 030E 0315 0062;0061 05AE 0300 030E 0315 0062;00E0 05AE 030E 0315 0062;0061 05AE 0300 030E 0315 0062; # (a◌̕◌̀◌֮◌̎b; à◌֮◌̎◌̕b; a◌֮◌̀◌̎◌̕b; à◌֮◌̎◌̕b; a◌֮◌̀◌̎◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOUBLE VERTICAL LINE ABOVE, LATIN SMALL LETTER B
+0061 030E 0315 0300 05AE 0062;0061 05AE 030E 0300 0315 0062;0061 05AE 030E 0300 0315 0062;0061 05AE 030E 0300 0315 0062;0061 05AE 030E 0300 0315 0062; # (a◌̎◌̕◌̀◌֮b; a◌֮◌̎◌̀◌̕b; a◌֮◌̎◌̀◌̕b; a◌֮◌̎◌̀◌̕b; a◌֮◌̎◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOUBLE VERTICAL LINE ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 030F 0062;00E0 05AE 030F 0315 0062;0061 05AE 0300 030F 0315 0062;00E0 05AE 030F 0315 0062;0061 05AE 0300 030F 0315 0062; # (a◌̕◌̀◌֮◌̏b; à◌֮◌̏◌̕b; a◌֮◌̀◌̏◌̕b; à◌֮◌̏◌̕b; a◌֮◌̀◌̏◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOUBLE GRAVE ACCENT, LATIN SMALL LETTER B
+0061 030F 0315 0300 05AE 0062;0201 05AE 0300 0315 0062;0061 05AE 030F 0300 0315 0062;0201 05AE 0300 0315 0062;0061 05AE 030F 0300 0315 0062; # (a◌̏◌̕◌̀◌֮b; ȁ◌֮◌̀◌̕b; a◌֮◌̏◌̀◌̕b; ȁ◌֮◌̀◌̕b; a◌֮◌̏◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOUBLE GRAVE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0310 0062;00E0 05AE 0310 0315 0062;0061 05AE 0300 0310 0315 0062;00E0 05AE 0310 0315 0062;0061 05AE 0300 0310 0315 0062; # (a◌̕◌̀◌֮◌̐b; à◌֮◌̐◌̕b; a◌֮◌̀◌̐◌̕b; à◌֮◌̐◌̕b; a◌֮◌̀◌̐◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CANDRABINDU, LATIN SMALL LETTER B
+0061 0310 0315 0300 05AE 0062;0061 05AE 0310 0300 0315 0062;0061 05AE 0310 0300 0315 0062;0061 05AE 0310 0300 0315 0062;0061 05AE 0310 0300 0315 0062; # (a◌̐◌̕◌̀◌֮b; a◌֮◌̐◌̀◌̕b; a◌֮◌̐◌̀◌̕b; a◌֮◌̐◌̀◌̕b; a◌֮◌̐◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CANDRABINDU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0311 0062;00E0 05AE 0311 0315 0062;0061 05AE 0300 0311 0315 0062;00E0 05AE 0311 0315 0062;0061 05AE 0300 0311 0315 0062; # (a◌̕◌̀◌֮◌̑b; à◌֮◌̑◌̕b; a◌֮◌̀◌̑◌̕b; à◌֮◌̑◌̕b; a◌֮◌̀◌̑◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING INVERTED BREVE, LATIN SMALL LETTER B
+0061 0311 0315 0300 05AE 0062;0203 05AE 0300 0315 0062;0061 05AE 0311 0300 0315 0062;0203 05AE 0300 0315 0062;0061 05AE 0311 0300 0315 0062; # (a◌̑◌̕◌̀◌֮b; ȃ◌֮◌̀◌̕b; a◌֮◌̑◌̀◌̕b; ȃ◌֮◌̀◌̕b; a◌֮◌̑◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING INVERTED BREVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0312 0062;00E0 05AE 0312 0315 0062;0061 05AE 0300 0312 0315 0062;00E0 05AE 0312 0315 0062;0061 05AE 0300 0312 0315 0062; # (a◌̕◌̀◌֮◌̒b; à◌֮◌̒◌̕b; a◌֮◌̀◌̒◌̕b; à◌֮◌̒◌̕b; a◌֮◌̀◌̒◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING TURNED COMMA ABOVE, LATIN SMALL LETTER B
+0061 0312 0315 0300 05AE 0062;0061 05AE 0312 0300 0315 0062;0061 05AE 0312 0300 0315 0062;0061 05AE 0312 0300 0315 0062;0061 05AE 0312 0300 0315 0062; # (a◌̒◌̕◌̀◌֮b; a◌֮◌̒◌̀◌̕b; a◌֮◌̒◌̀◌̕b; a◌֮◌̒◌̀◌̕b; a◌֮◌̒◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING TURNED COMMA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0313 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062; # (a◌̕◌̀◌֮◌̓b; à◌֮◌̓◌̕b; a◌֮◌̀◌̓◌̕b; à◌֮◌̓◌̕b; a◌֮◌̀◌̓◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING COMMA ABOVE, LATIN SMALL LETTER B
+0061 0313 0315 0300 05AE 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062; # (a◌̓◌̕◌̀◌֮b; a◌֮◌̓◌̀◌̕b; a◌֮◌̓◌̀◌̕b; a◌֮◌̓◌̀◌̕b; a◌֮◌̓◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0314 0062;00E0 05AE 0314 0315 0062;0061 05AE 0300 0314 0315 0062;00E0 05AE 0314 0315 0062;0061 05AE 0300 0314 0315 0062; # (a◌̕◌̀◌֮◌̔b; à◌֮◌̔◌̕b; a◌֮◌̀◌̔◌̕b; à◌֮◌̔◌̕b; a◌֮◌̀◌̔◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING REVERSED COMMA ABOVE, LATIN SMALL LETTER B
+0061 0314 0315 0300 05AE 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062;0061 05AE 0314 0300 0315 0062; # (a◌̔◌̕◌̀◌֮b; a◌֮◌̔◌̀◌̕b; a◌֮◌̔◌̀◌̕b; a◌֮◌̔◌̀◌̕b; a◌֮◌̔◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING REVERSED COMMA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 035C 0315 0300 0315 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062; # (a◌͜◌̕◌̀◌̕b; à◌̕◌̕◌͜b; a◌̀◌̕◌̕◌͜b; à◌̕◌̕◌͜b; a◌̀◌̕◌̕◌͜b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, COMBINING COMMA ABOVE RIGHT, LATIN SMALL LETTER B
+0061 0315 035C 0315 0300 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062;00E0 0315 0315 035C 0062;0061 0300 0315 0315 035C 0062; # (a◌̕◌͜◌̕◌̀b; à◌̕◌̕◌͜b; a◌̀◌̕◌̕◌͜b; à◌̕◌̕◌͜b; a◌̀◌̕◌̕◌͜b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, LATIN SMALL LETTER B
+0061 059A 0316 302A 0316 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062; # (a◌֚◌̖◌〪◌̖b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING GRAVE ACCENT BELOW, LATIN SMALL LETTER B
+0061 0316 059A 0316 302A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062;0061 302A 0316 0316 059A 0062; # (a◌̖◌֚◌̖◌〪b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; a◌〪◌̖◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0317 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062;0061 302A 0316 0317 059A 0062; # (a◌֚◌̖◌〪◌̗b; a◌〪◌̖◌̗◌֚b; a◌〪◌̖◌̗◌֚b; a◌〪◌̖◌̗◌֚b; a◌〪◌̖◌̗◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING ACUTE ACCENT BELOW, LATIN SMALL LETTER B
+0061 0317 059A 0316 302A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062;0061 302A 0317 0316 059A 0062; # (a◌̗◌֚◌̖◌〪b; a◌〪◌̗◌̖◌֚b; a◌〪◌̗◌̖◌֚b; a◌〪◌̗◌̖◌֚b; a◌〪◌̗◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ACUTE ACCENT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0318 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062;0061 302A 0316 0318 059A 0062; # (a◌֚◌̖◌〪◌̘b; a◌〪◌̖◌̘◌֚b; a◌〪◌̖◌̘◌֚b; a◌〪◌̖◌̘◌֚b; a◌〪◌̖◌̘◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT TACK BELOW, LATIN SMALL LETTER B
+0061 0318 059A 0316 302A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062;0061 302A 0318 0316 059A 0062; # (a◌̘◌֚◌̖◌〪b; a◌〪◌̘◌̖◌֚b; a◌〪◌̘◌̖◌֚b; a◌〪◌̘◌̖◌֚b; a◌〪◌̘◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0319 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062;0061 302A 0316 0319 059A 0062; # (a◌֚◌̖◌〪◌̙b; a◌〪◌̖◌̙◌֚b; a◌〪◌̖◌̙◌֚b; a◌〪◌̖◌̙◌֚b; a◌〪◌̖◌̙◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT TACK BELOW, LATIN SMALL LETTER B
+0061 0319 059A 0316 302A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062;0061 302A 0319 0316 059A 0062; # (a◌̙◌֚◌̖◌〪b; a◌〪◌̙◌̖◌֚b; a◌〪◌̙◌̖◌֚b; a◌〪◌̙◌̖◌֚b; a◌〪◌̙◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 035C 0315 0300 031A 0062;00E0 0315 031A 035C 0062;0061 0300 0315 031A 035C 0062;00E0 0315 031A 035C 0062;0061 0300 0315 031A 035C 0062; # (a◌͜◌̕◌̀◌̚b; à◌̕◌̚◌͜b; a◌̀◌̕◌̚◌͜b; à◌̕◌̚◌͜b; a◌̀◌̕◌̚◌͜b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, COMBINING LEFT ANGLE ABOVE, LATIN SMALL LETTER B
+0061 031A 035C 0315 0300 0062;00E0 031A 0315 035C 0062;0061 0300 031A 0315 035C 0062;00E0 031A 0315 035C 0062;0061 0300 031A 0315 035C 0062; # (a◌̚◌͜◌̕◌̀b; à◌̚◌̕◌͜b; a◌̀◌̚◌̕◌͜b; à◌̚◌̕◌͜b; a◌̀◌̚◌̕◌͜b; ) LATIN SMALL LETTER A, COMBINING LEFT ANGLE ABOVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, LATIN SMALL LETTER B
+0061 302A 031B 1DCE 031B 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062; # (a◌〪◌̛◌᷎◌̛b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, COMBINING HORN, LATIN SMALL LETTER B
+0061 031B 302A 031B 1DCE 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062;0061 1DCE 031B 031B 302A 0062; # (a◌̛◌〪◌̛◌᷎b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; a◌᷎◌̛◌̛◌〪b; ) LATIN SMALL LETTER A, COMBINING HORN, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 059A 0316 302A 031C 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062;0061 302A 0316 031C 059A 0062; # (a◌֚◌̖◌〪◌̜b; a◌〪◌̖◌̜◌֚b; a◌〪◌̖◌̜◌֚b; a◌〪◌̖◌̜◌֚b; a◌〪◌̖◌̜◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT HALF RING BELOW, LATIN SMALL LETTER B
+0061 031C 059A 0316 302A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062;0061 302A 031C 0316 059A 0062; # (a◌̜◌֚◌̖◌〪b; a◌〪◌̜◌̖◌֚b; a◌〪◌̜◌̖◌֚b; a◌〪◌̜◌̖◌֚b; a◌〪◌̜◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT HALF RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 031D 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062;0061 302A 0316 031D 059A 0062; # (a◌֚◌̖◌〪◌̝b; a◌〪◌̖◌̝◌֚b; a◌〪◌̖◌̝◌֚b; a◌〪◌̖◌̝◌֚b; a◌〪◌̖◌̝◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING UP TACK BELOW, LATIN SMALL LETTER B
+0061 031D 059A 0316 302A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062;0061 302A 031D 0316 059A 0062; # (a◌̝◌֚◌̖◌〪b; a◌〪◌̝◌̖◌֚b; a◌〪◌̝◌̖◌֚b; a◌〪◌̝◌̖◌֚b; a◌〪◌̝◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING UP TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 031E 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062;0061 302A 0316 031E 059A 0062; # (a◌֚◌̖◌〪◌̞b; a◌〪◌̖◌̞◌֚b; a◌〪◌̖◌̞◌֚b; a◌〪◌̖◌̞◌֚b; a◌〪◌̖◌̞◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOWN TACK BELOW, LATIN SMALL LETTER B
+0061 031E 059A 0316 302A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062;0061 302A 031E 0316 059A 0062; # (a◌̞◌֚◌̖◌〪b; a◌〪◌̞◌̖◌֚b; a◌〪◌̞◌̖◌֚b; a◌〪◌̞◌̖◌֚b; a◌〪◌̞◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOWN TACK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 031F 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062;0061 302A 0316 031F 059A 0062; # (a◌֚◌̖◌〪◌̟b; a◌〪◌̖◌̟◌֚b; a◌〪◌̖◌̟◌֚b; a◌〪◌̖◌̟◌֚b; a◌〪◌̖◌̟◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING PLUS SIGN BELOW, LATIN SMALL LETTER B
+0061 031F 059A 0316 302A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062;0061 302A 031F 0316 059A 0062; # (a◌̟◌֚◌̖◌〪b; a◌〪◌̟◌̖◌֚b; a◌〪◌̟◌̖◌֚b; a◌〪◌̟◌̖◌֚b; a◌〪◌̟◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING PLUS SIGN BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0320 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062;0061 302A 0316 0320 059A 0062; # (a◌֚◌̖◌〪◌̠b; a◌〪◌̖◌̠◌֚b; a◌〪◌̖◌̠◌֚b; a◌〪◌̖◌̠◌֚b; a◌〪◌̖◌̠◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING MINUS SIGN BELOW, LATIN SMALL LETTER B
+0061 0320 059A 0316 302A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062;0061 302A 0320 0316 059A 0062; # (a◌̠◌֚◌̖◌〪b; a◌〪◌̠◌̖◌֚b; a◌〪◌̠◌̖◌֚b; a◌〪◌̠◌̖◌֚b; a◌〪◌̠◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MINUS SIGN BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 1DCE 0321 0F74 0321 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062; # (a◌᷎◌̡◌ུ◌̡b; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, COMBINING PALATALIZED HOOK BELOW, LATIN SMALL LETTER B
+0061 0321 1DCE 0321 0F74 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062;0061 0F74 0321 0321 1DCE 0062; # (a◌̡◌᷎◌̡◌ུb; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; a◌ུ◌̡◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING PALATALIZED HOOK BELOW, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, LATIN SMALL LETTER B
+0061 1DCE 0321 0F74 0322 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062;0061 0F74 0321 0322 1DCE 0062; # (a◌᷎◌̡◌ུ◌̢b; a◌ུ◌̡◌̢◌᷎b; a◌ུ◌̡◌̢◌᷎b; a◌ུ◌̡◌̢◌᷎b; a◌ུ◌̡◌̢◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, COMBINING RETROFLEX HOOK BELOW, LATIN SMALL LETTER B
+0061 0322 1DCE 0321 0F74 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062;0061 0F74 0322 0321 1DCE 0062; # (a◌̢◌᷎◌̡◌ུb; a◌ུ◌̢◌̡◌᷎b; a◌ུ◌̢◌̡◌᷎b; a◌ུ◌̢◌̡◌᷎b; a◌ུ◌̢◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING RETROFLEX HOOK BELOW, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, LATIN SMALL LETTER B
+0061 059A 0316 302A 0323 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062;0061 302A 0316 0323 059A 0062; # (a◌֚◌̖◌〪◌̣b; a◌〪◌̖◌̣◌֚b; a◌〪◌̖◌̣◌֚b; a◌〪◌̖◌̣◌֚b; a◌〪◌̖◌̣◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOT BELOW, LATIN SMALL LETTER B
+0061 0323 059A 0316 302A 0062;1EA1 302A 0316 059A 0062;0061 302A 0323 0316 059A 0062;1EA1 302A 0316 059A 0062;0061 302A 0323 0316 059A 0062; # (a◌̣◌֚◌̖◌〪b; ạ◌〪◌̖◌֚b; a◌〪◌̣◌̖◌֚b; ạ◌〪◌̖◌֚b; a◌〪◌̣◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0324 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062;0061 302A 0316 0324 059A 0062; # (a◌֚◌̖◌〪◌̤b; a◌〪◌̖◌̤◌֚b; a◌〪◌̖◌̤◌֚b; a◌〪◌̖◌̤◌֚b; a◌〪◌̖◌̤◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DIAERESIS BELOW, LATIN SMALL LETTER B
+0061 0324 059A 0316 302A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062;0061 302A 0324 0316 059A 0062; # (a◌̤◌֚◌̖◌〪b; a◌〪◌̤◌̖◌֚b; a◌〪◌̤◌̖◌֚b; a◌〪◌̤◌̖◌֚b; a◌〪◌̤◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DIAERESIS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0325 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062;0061 302A 0316 0325 059A 0062; # (a◌֚◌̖◌〪◌̥b; a◌〪◌̖◌̥◌֚b; a◌〪◌̖◌̥◌֚b; a◌〪◌̖◌̥◌֚b; a◌〪◌̖◌̥◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RING BELOW, LATIN SMALL LETTER B
+0061 0325 059A 0316 302A 0062;1E01 302A 0316 059A 0062;0061 302A 0325 0316 059A 0062;1E01 302A 0316 059A 0062;0061 302A 0325 0316 059A 0062; # (a◌̥◌֚◌̖◌〪b; ḁ◌〪◌̖◌֚b; a◌〪◌̥◌̖◌֚b; ḁ◌〪◌̖◌֚b; a◌〪◌̥◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0326 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062;0061 302A 0316 0326 059A 0062; # (a◌֚◌̖◌〪◌̦b; a◌〪◌̖◌̦◌֚b; a◌〪◌̖◌̦◌֚b; a◌〪◌̖◌̦◌֚b; a◌〪◌̖◌̦◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING COMMA BELOW, LATIN SMALL LETTER B
+0061 0326 059A 0316 302A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062;0061 302A 0326 0316 059A 0062; # (a◌̦◌֚◌̖◌〪b; a◌〪◌̦◌̖◌֚b; a◌〪◌̦◌̖◌֚b; a◌〪◌̦◌̖◌֚b; a◌〪◌̦◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING COMMA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 1DCE 0321 0F74 0327 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062;0061 0F74 0321 0327 1DCE 0062; # (a◌᷎◌̡◌ུ◌̧b; a◌ུ◌̡◌̧◌᷎b; a◌ུ◌̡◌̧◌᷎b; a◌ུ◌̡◌̧◌᷎b; a◌ུ◌̡◌̧◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, COMBINING CEDILLA, LATIN SMALL LETTER B
+0061 0327 1DCE 0321 0F74 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062;0061 0F74 0327 0321 1DCE 0062; # (a◌̧◌᷎◌̡◌ུb; a◌ུ◌̧◌̡◌᷎b; a◌ུ◌̧◌̡◌᷎b; a◌ུ◌̧◌̡◌᷎b; a◌ུ◌̧◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING CEDILLA, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, LATIN SMALL LETTER B
+0061 1DCE 0321 0F74 0328 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062;0061 0F74 0321 0328 1DCE 0062; # (a◌᷎◌̡◌ུ◌̨b; a◌ུ◌̡◌̨◌᷎b; a◌ུ◌̡◌̨◌᷎b; a◌ུ◌̡◌̨◌᷎b; a◌ུ◌̡◌̨◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, COMBINING OGONEK, LATIN SMALL LETTER B
+0061 0328 1DCE 0321 0F74 0062;0105 0F74 0321 1DCE 0062;0061 0F74 0328 0321 1DCE 0062;0105 0F74 0321 1DCE 0062;0061 0F74 0328 0321 1DCE 0062; # (a◌̨◌᷎◌̡◌ུb; ą◌ུ◌̡◌᷎b; a◌ུ◌̨◌̡◌᷎b; ą◌ུ◌̡◌᷎b; a◌ུ◌̨◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, LATIN SMALL LETTER B
+0061 059A 0316 302A 0329 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062;0061 302A 0316 0329 059A 0062; # (a◌֚◌̖◌〪◌̩b; a◌〪◌̖◌̩◌֚b; a◌〪◌̖◌̩◌֚b; a◌〪◌̖◌̩◌֚b; a◌〪◌̖◌̩◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING VERTICAL LINE BELOW, LATIN SMALL LETTER B
+0061 0329 059A 0316 302A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062;0061 302A 0329 0316 059A 0062; # (a◌̩◌֚◌̖◌〪b; a◌〪◌̩◌̖◌֚b; a◌〪◌̩◌̖◌֚b; a◌〪◌̩◌̖◌֚b; a◌〪◌̩◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING VERTICAL LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 032A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062;0061 302A 0316 032A 059A 0062; # (a◌֚◌̖◌〪◌̪b; a◌〪◌̖◌̪◌֚b; a◌〪◌̖◌̪◌֚b; a◌〪◌̖◌̪◌֚b; a◌〪◌̖◌̪◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING BRIDGE BELOW, LATIN SMALL LETTER B
+0061 032A 059A 0316 302A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062;0061 302A 032A 0316 059A 0062; # (a◌̪◌֚◌̖◌〪b; a◌〪◌̪◌̖◌֚b; a◌〪◌̪◌̖◌֚b; a◌〪◌̪◌̖◌֚b; a◌〪◌̪◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING BRIDGE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 032B 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062;0061 302A 0316 032B 059A 0062; # (a◌֚◌̖◌〪◌̫b; a◌〪◌̖◌̫◌֚b; a◌〪◌̖◌̫◌֚b; a◌〪◌̖◌̫◌֚b; a◌〪◌̖◌̫◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING INVERTED DOUBLE ARCH BELOW, LATIN SMALL LETTER B
+0061 032B 059A 0316 302A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062;0061 302A 032B 0316 059A 0062; # (a◌̫◌֚◌̖◌〪b; a◌〪◌̫◌̖◌֚b; a◌〪◌̫◌̖◌֚b; a◌〪◌̫◌̖◌֚b; a◌〪◌̫◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING INVERTED DOUBLE ARCH BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 032C 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062;0061 302A 0316 032C 059A 0062; # (a◌֚◌̖◌〪◌̬b; a◌〪◌̖◌̬◌֚b; a◌〪◌̖◌̬◌֚b; a◌〪◌̖◌̬◌֚b; a◌〪◌̖◌̬◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING CARON BELOW, LATIN SMALL LETTER B
+0061 032C 059A 0316 302A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062;0061 302A 032C 0316 059A 0062; # (a◌̬◌֚◌̖◌〪b; a◌〪◌̬◌̖◌֚b; a◌〪◌̬◌̖◌֚b; a◌〪◌̬◌̖◌֚b; a◌〪◌̬◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING CARON BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 032D 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062;0061 302A 0316 032D 059A 0062; # (a◌֚◌̖◌〪◌̭b; a◌〪◌̖◌̭◌֚b; a◌〪◌̖◌̭◌֚b; a◌〪◌̖◌̭◌֚b; a◌〪◌̖◌̭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING CIRCUMFLEX ACCENT BELOW, LATIN SMALL LETTER B
+0061 032D 059A 0316 302A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062;0061 302A 032D 0316 059A 0062; # (a◌̭◌֚◌̖◌〪b; a◌〪◌̭◌̖◌֚b; a◌〪◌̭◌̖◌֚b; a◌〪◌̭◌̖◌֚b; a◌〪◌̭◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING CIRCUMFLEX ACCENT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 032E 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062;0061 302A 0316 032E 059A 0062; # (a◌֚◌̖◌〪◌̮b; a◌〪◌̖◌̮◌֚b; a◌〪◌̖◌̮◌֚b; a◌〪◌̖◌̮◌֚b; a◌〪◌̖◌̮◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING BREVE BELOW, LATIN SMALL LETTER B
+0061 032E 059A 0316 302A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062;0061 302A 032E 0316 059A 0062; # (a◌̮◌֚◌̖◌〪b; a◌〪◌̮◌̖◌֚b; a◌〪◌̮◌̖◌֚b; a◌〪◌̮◌̖◌֚b; a◌〪◌̮◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING BREVE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 032F 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062;0061 302A 0316 032F 059A 0062; # (a◌֚◌̖◌〪◌̯b; a◌〪◌̖◌̯◌֚b; a◌〪◌̖◌̯◌֚b; a◌〪◌̖◌̯◌֚b; a◌〪◌̖◌̯◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING INVERTED BREVE BELOW, LATIN SMALL LETTER B
+0061 032F 059A 0316 302A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062;0061 302A 032F 0316 059A 0062; # (a◌̯◌֚◌̖◌〪b; a◌〪◌̯◌̖◌֚b; a◌〪◌̯◌̖◌֚b; a◌〪◌̯◌̖◌֚b; a◌〪◌̯◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING INVERTED BREVE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0330 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062;0061 302A 0316 0330 059A 0062; # (a◌֚◌̖◌〪◌̰b; a◌〪◌̖◌̰◌֚b; a◌〪◌̖◌̰◌֚b; a◌〪◌̖◌̰◌֚b; a◌〪◌̖◌̰◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING TILDE BELOW, LATIN SMALL LETTER B
+0061 0330 059A 0316 302A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062;0061 302A 0330 0316 059A 0062; # (a◌̰◌֚◌̖◌〪b; a◌〪◌̰◌̖◌֚b; a◌〪◌̰◌̖◌֚b; a◌〪◌̰◌̖◌֚b; a◌〪◌̰◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TILDE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0331 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062;0061 302A 0316 0331 059A 0062; # (a◌֚◌̖◌〪◌̱b; a◌〪◌̖◌̱◌֚b; a◌〪◌̖◌̱◌֚b; a◌〪◌̖◌̱◌֚b; a◌〪◌̖◌̱◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING MACRON BELOW, LATIN SMALL LETTER B
+0061 0331 059A 0316 302A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062;0061 302A 0331 0316 059A 0062; # (a◌̱◌֚◌̖◌〪b; a◌〪◌̱◌̖◌֚b; a◌〪◌̱◌̖◌֚b; a◌〪◌̱◌̖◌֚b; a◌〪◌̱◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MACRON BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0332 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062;0061 302A 0316 0332 059A 0062; # (a◌֚◌̖◌〪◌̲b; a◌〪◌̖◌̲◌֚b; a◌〪◌̖◌̲◌֚b; a◌〪◌̖◌̲◌֚b; a◌〪◌̖◌̲◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LOW LINE, LATIN SMALL LETTER B
+0061 0332 059A 0316 302A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062;0061 302A 0332 0316 059A 0062; # (a◌̲◌֚◌̖◌〪b; a◌〪◌̲◌̖◌֚b; a◌〪◌̲◌̖◌֚b; a◌〪◌̲◌̖◌֚b; a◌〪◌̲◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LOW LINE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0333 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062;0061 302A 0316 0333 059A 0062; # (a◌֚◌̖◌〪◌̳b; a◌〪◌̖◌̳◌֚b; a◌〪◌̖◌̳◌֚b; a◌〪◌̖◌̳◌֚b; a◌〪◌̖◌̳◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOUBLE LOW LINE, LATIN SMALL LETTER B
+0061 0333 059A 0316 302A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062;0061 302A 0333 0316 059A 0062; # (a◌̳◌֚◌̖◌〪b; a◌〪◌̳◌̖◌֚b; a◌〪◌̳◌̖◌֚b; a◌〪◌̳◌̖◌֚b; a◌〪◌̳◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE LOW LINE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 093C 0334 0334 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062; # (a◌़◌̴◌̴b; a◌̴◌̴◌़b; a◌̴◌̴◌़b; a◌̴◌̴◌़b; a◌̴◌̴◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 0334 093C 0334 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062;0061 0334 0334 093C 0062; # (a◌̴◌़◌̴b; a◌̴◌̴◌़b; a◌̴◌̴◌़b; a◌̴◌̴◌़b; a◌̴◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING TILDE OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 0335 0062;0061 0334 0335 093C 0062;0061 0334 0335 093C 0062;0061 0334 0335 093C 0062;0061 0334 0335 093C 0062; # (a◌़◌̴◌̵b; a◌̴◌̵◌़b; a◌̴◌̵◌़b; a◌̴◌̵◌़b; a◌̴◌̵◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING SHORT STROKE OVERLAY, LATIN SMALL LETTER B
+0061 0335 093C 0334 0062;0061 0335 0334 093C 0062;0061 0335 0334 093C 0062;0061 0335 0334 093C 0062;0061 0335 0334 093C 0062; # (a◌̵◌़◌̴b; a◌̵◌̴◌़b; a◌̵◌̴◌़b; a◌̵◌̴◌़b; a◌̵◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING SHORT STROKE OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 0336 0062;0061 0334 0336 093C 0062;0061 0334 0336 093C 0062;0061 0334 0336 093C 0062;0061 0334 0336 093C 0062; # (a◌़◌̴◌̶b; a◌̴◌̶◌़b; a◌̴◌̶◌़b; a◌̴◌̶◌़b; a◌̴◌̶◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING LONG STROKE OVERLAY, LATIN SMALL LETTER B
+0061 0336 093C 0334 0062;0061 0336 0334 093C 0062;0061 0336 0334 093C 0062;0061 0336 0334 093C 0062;0061 0336 0334 093C 0062; # (a◌̶◌़◌̴b; a◌̶◌̴◌़b; a◌̶◌̴◌़b; a◌̶◌̴◌़b; a◌̶◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING LONG STROKE OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 0337 0062;0061 0334 0337 093C 0062;0061 0334 0337 093C 0062;0061 0334 0337 093C 0062;0061 0334 0337 093C 0062; # (a◌़◌̴◌̷b; a◌̴◌̷◌़b; a◌̴◌̷◌़b; a◌̴◌̷◌़b; a◌̴◌̷◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING SHORT SOLIDUS OVERLAY, LATIN SMALL LETTER B
+0061 0337 093C 0334 0062;0061 0337 0334 093C 0062;0061 0337 0334 093C 0062;0061 0337 0334 093C 0062;0061 0337 0334 093C 0062; # (a◌̷◌़◌̴b; a◌̷◌̴◌़b; a◌̷◌̴◌़b; a◌̷◌̴◌़b; a◌̷◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING SHORT SOLIDUS OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 0338 0062;0061 0334 0338 093C 0062;0061 0334 0338 093C 0062;0061 0334 0338 093C 0062;0061 0334 0338 093C 0062; # (a◌़◌̴◌̸b; a◌̴◌̸◌़b; a◌̴◌̸◌़b; a◌̴◌̸◌़b; a◌̴◌̸◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING LONG SOLIDUS OVERLAY, LATIN SMALL LETTER B
+0061 0338 093C 0334 0062;0061 0338 0334 093C 0062;0061 0338 0334 093C 0062;0061 0338 0334 093C 0062;0061 0338 0334 093C 0062; # (a◌̸◌़◌̴b; a◌̸◌̴◌़b; a◌̸◌̴◌़b; a◌̸◌̴◌़b; a◌̸◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING LONG SOLIDUS OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 059A 0316 302A 0339 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062;0061 302A 0316 0339 059A 0062; # (a◌֚◌̖◌〪◌̹b; a◌〪◌̖◌̹◌֚b; a◌〪◌̖◌̹◌֚b; a◌〪◌̖◌̹◌֚b; a◌〪◌̖◌̹◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT HALF RING BELOW, LATIN SMALL LETTER B
+0061 0339 059A 0316 302A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062;0061 302A 0339 0316 059A 0062; # (a◌̹◌֚◌̖◌〪b; a◌〪◌̹◌̖◌֚b; a◌〪◌̹◌̖◌֚b; a◌〪◌̹◌̖◌֚b; a◌〪◌̹◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT HALF RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 033A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062;0061 302A 0316 033A 059A 0062; # (a◌֚◌̖◌〪◌̺b; a◌〪◌̖◌̺◌֚b; a◌〪◌̖◌̺◌֚b; a◌〪◌̖◌̺◌֚b; a◌〪◌̖◌̺◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING INVERTED BRIDGE BELOW, LATIN SMALL LETTER B
+0061 033A 059A 0316 302A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062;0061 302A 033A 0316 059A 0062; # (a◌̺◌֚◌̖◌〪b; a◌〪◌̺◌̖◌֚b; a◌〪◌̺◌̖◌֚b; a◌〪◌̺◌̖◌֚b; a◌〪◌̺◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING INVERTED BRIDGE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 033B 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062;0061 302A 0316 033B 059A 0062; # (a◌֚◌̖◌〪◌̻b; a◌〪◌̖◌̻◌֚b; a◌〪◌̖◌̻◌֚b; a◌〪◌̖◌̻◌֚b; a◌〪◌̖◌̻◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING SQUARE BELOW, LATIN SMALL LETTER B
+0061 033B 059A 0316 302A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062;0061 302A 033B 0316 059A 0062; # (a◌̻◌֚◌̖◌〪b; a◌〪◌̻◌̖◌֚b; a◌〪◌̻◌̖◌֚b; a◌〪◌̻◌̖◌֚b; a◌〪◌̻◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING SQUARE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 033C 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062;0061 302A 0316 033C 059A 0062; # (a◌֚◌̖◌〪◌̼b; a◌〪◌̖◌̼◌֚b; a◌〪◌̖◌̼◌֚b; a◌〪◌̖◌̼◌֚b; a◌〪◌̖◌̼◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING SEAGULL BELOW, LATIN SMALL LETTER B
+0061 033C 059A 0316 302A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062;0061 302A 033C 0316 059A 0062; # (a◌̼◌֚◌̖◌〪b; a◌〪◌̼◌̖◌֚b; a◌〪◌̼◌̖◌֚b; a◌〪◌̼◌̖◌֚b; a◌〪◌̼◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING SEAGULL BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 033D 0062;00E0 05AE 033D 0315 0062;0061 05AE 0300 033D 0315 0062;00E0 05AE 033D 0315 0062;0061 05AE 0300 033D 0315 0062; # (a◌̕◌̀◌֮◌̽b; à◌֮◌̽◌̕b; a◌֮◌̀◌̽◌̕b; à◌֮◌̽◌̕b; a◌֮◌̀◌̽◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING X ABOVE, LATIN SMALL LETTER B
+0061 033D 0315 0300 05AE 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062;0061 05AE 033D 0300 0315 0062; # (a◌̽◌̕◌̀◌֮b; a◌֮◌̽◌̀◌̕b; a◌֮◌̽◌̀◌̕b; a◌֮◌̽◌̀◌̕b; a◌֮◌̽◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING X ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 033E 0062;00E0 05AE 033E 0315 0062;0061 05AE 0300 033E 0315 0062;00E0 05AE 033E 0315 0062;0061 05AE 0300 033E 0315 0062; # (a◌̕◌̀◌֮◌̾b; à◌֮◌̾◌̕b; a◌֮◌̀◌̾◌̕b; à◌֮◌̾◌̕b; a◌֮◌̀◌̾◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING VERTICAL TILDE, LATIN SMALL LETTER B
+0061 033E 0315 0300 05AE 0062;0061 05AE 033E 0300 0315 0062;0061 05AE 033E 0300 0315 0062;0061 05AE 033E 0300 0315 0062;0061 05AE 033E 0300 0315 0062; # (a◌̾◌̕◌̀◌֮b; a◌֮◌̾◌̀◌̕b; a◌֮◌̾◌̀◌̕b; a◌֮◌̾◌̀◌̕b; a◌֮◌̾◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING VERTICAL TILDE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 033F 0062;00E0 05AE 033F 0315 0062;0061 05AE 0300 033F 0315 0062;00E0 05AE 033F 0315 0062;0061 05AE 0300 033F 0315 0062; # (a◌̕◌̀◌֮◌̿b; à◌֮◌̿◌̕b; a◌֮◌̀◌̿◌̕b; à◌֮◌̿◌̕b; a◌֮◌̀◌̿◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOUBLE OVERLINE, LATIN SMALL LETTER B
+0061 033F 0315 0300 05AE 0062;0061 05AE 033F 0300 0315 0062;0061 05AE 033F 0300 0315 0062;0061 05AE 033F 0300 0315 0062;0061 05AE 033F 0300 0315 0062; # (a◌̿◌̕◌̀◌֮b; a◌֮◌̿◌̀◌̕b; a◌֮◌̿◌̀◌̕b; a◌֮◌̿◌̀◌̕b; a◌֮◌̿◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOUBLE OVERLINE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0340 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; # (a◌̕◌̀◌֮◌̀b; à◌֮◌̀◌̕b; a◌֮◌̀◌̀◌̕b; à◌֮◌̀◌̕b; a◌֮◌̀◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRAVE TONE MARK, LATIN SMALL LETTER B
+0061 0340 0315 0300 05AE 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062;00E0 05AE 0300 0315 0062;0061 05AE 0300 0300 0315 0062; # (a◌̀◌̕◌̀◌֮b; à◌֮◌̀◌̕b; a◌֮◌̀◌̀◌̕b; à◌֮◌̀◌̕b; a◌֮◌̀◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRAVE TONE MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0341 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062;00E0 05AE 0301 0315 0062;0061 05AE 0300 0301 0315 0062; # (a◌̕◌̀◌֮◌́b; à◌֮◌́◌̕b; a◌֮◌̀◌́◌̕b; à◌֮◌́◌̕b; a◌֮◌̀◌́◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING ACUTE TONE MARK, LATIN SMALL LETTER B
+0061 0341 0315 0300 05AE 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062;00E1 05AE 0300 0315 0062;0061 05AE 0301 0300 0315 0062; # (a◌́◌̕◌̀◌֮b; á◌֮◌̀◌̕b; a◌֮◌́◌̀◌̕b; á◌֮◌̀◌̕b; a◌֮◌́◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ACUTE TONE MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0342 0062;00E0 05AE 0342 0315 0062;0061 05AE 0300 0342 0315 0062;00E0 05AE 0342 0315 0062;0061 05AE 0300 0342 0315 0062; # (a◌̕◌̀◌֮◌͂b; à◌֮◌͂◌̕b; a◌֮◌̀◌͂◌̕b; à◌֮◌͂◌̕b; a◌֮◌̀◌͂◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GREEK PERISPOMENI, LATIN SMALL LETTER B
+0061 0342 0315 0300 05AE 0062;0061 05AE 0342 0300 0315 0062;0061 05AE 0342 0300 0315 0062;0061 05AE 0342 0300 0315 0062;0061 05AE 0342 0300 0315 0062; # (a◌͂◌̕◌̀◌֮b; a◌֮◌͂◌̀◌̕b; a◌֮◌͂◌̀◌̕b; a◌֮◌͂◌̀◌̕b; a◌֮◌͂◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GREEK PERISPOMENI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0343 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062;00E0 05AE 0313 0315 0062;0061 05AE 0300 0313 0315 0062; # (a◌̕◌̀◌֮◌̓b; à◌֮◌̓◌̕b; a◌֮◌̀◌̓◌̕b; à◌֮◌̓◌̕b; a◌֮◌̀◌̓◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GREEK KORONIS, LATIN SMALL LETTER B
+0061 0343 0315 0300 05AE 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062;0061 05AE 0313 0300 0315 0062; # (a◌̓◌̕◌̀◌֮b; a◌֮◌̓◌̀◌̕b; a◌֮◌̓◌̀◌̕b; a◌֮◌̓◌̀◌̕b; a◌֮◌̓◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GREEK KORONIS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0344 0062;00E0 05AE 0308 0301 0315 0062;0061 05AE 0300 0308 0301 0315 0062;00E0 05AE 0308 0301 0315 0062;0061 05AE 0300 0308 0301 0315 0062; # (a◌̕◌̀◌֮◌̈́b; à◌֮◌̈◌́◌̕b; a◌֮◌̀◌̈◌́◌̕b; à◌֮◌̈◌́◌̕b; a◌֮◌̀◌̈◌́◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GREEK DIALYTIKA TONOS, LATIN SMALL LETTER B
+0061 0344 0315 0300 05AE 0062;00E4 05AE 0301 0300 0315 0062;0061 05AE 0308 0301 0300 0315 0062;00E4 05AE 0301 0300 0315 0062;0061 05AE 0308 0301 0300 0315 0062; # (a◌̈́◌̕◌̀◌֮b; ä◌֮◌́◌̀◌̕b; a◌֮◌̈◌́◌̀◌̕b; ä◌֮◌́◌̀◌̕b; a◌֮◌̈◌́◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GREEK DIALYTIKA TONOS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0345 035D 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062; # (a◌ͅ◌͝◌ͅb; a◌͝◌ͅ◌ͅb; a◌͝◌ͅ◌ͅb; a◌͝◌ͅ◌ͅb; a◌͝◌ͅ◌ͅb; ) LATIN SMALL LETTER A, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING GREEK YPOGEGRAMMENI, LATIN SMALL LETTER B
+0061 0345 0345 035D 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062;0061 035D 0345 0345 0062; # (a◌ͅ◌ͅ◌͝b; a◌͝◌ͅ◌ͅb; a◌͝◌ͅ◌ͅb; a◌͝◌ͅ◌ͅb; a◌͝◌ͅ◌ͅb; ) LATIN SMALL LETTER A, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0346 0062;00E0 05AE 0346 0315 0062;0061 05AE 0300 0346 0315 0062;00E0 05AE 0346 0315 0062;0061 05AE 0300 0346 0315 0062; # (a◌̕◌̀◌֮◌͆b; à◌֮◌͆◌̕b; a◌֮◌̀◌͆◌̕b; à◌֮◌͆◌̕b; a◌֮◌̀◌͆◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING BRIDGE ABOVE, LATIN SMALL LETTER B
+0061 0346 0315 0300 05AE 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062;0061 05AE 0346 0300 0315 0062; # (a◌͆◌̕◌̀◌֮b; a◌֮◌͆◌̀◌̕b; a◌֮◌͆◌̀◌̕b; a◌֮◌͆◌̀◌̕b; a◌֮◌͆◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING BRIDGE ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0347 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062;0061 302A 0316 0347 059A 0062; # (a◌֚◌̖◌〪◌͇b; a◌〪◌̖◌͇◌֚b; a◌〪◌̖◌͇◌֚b; a◌〪◌̖◌͇◌֚b; a◌〪◌̖◌͇◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING EQUALS SIGN BELOW, LATIN SMALL LETTER B
+0061 0347 059A 0316 302A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062;0061 302A 0347 0316 059A 0062; # (a◌͇◌֚◌̖◌〪b; a◌〪◌͇◌̖◌֚b; a◌〪◌͇◌̖◌֚b; a◌〪◌͇◌̖◌֚b; a◌〪◌͇◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING EQUALS SIGN BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0348 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062;0061 302A 0316 0348 059A 0062; # (a◌֚◌̖◌〪◌͈b; a◌〪◌̖◌͈◌֚b; a◌〪◌̖◌͈◌֚b; a◌〪◌̖◌͈◌֚b; a◌〪◌̖◌͈◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOUBLE VERTICAL LINE BELOW, LATIN SMALL LETTER B
+0061 0348 059A 0316 302A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062;0061 302A 0348 0316 059A 0062; # (a◌͈◌֚◌̖◌〪b; a◌〪◌͈◌̖◌֚b; a◌〪◌͈◌̖◌֚b; a◌〪◌͈◌̖◌֚b; a◌〪◌͈◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE VERTICAL LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0349 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062;0061 302A 0316 0349 059A 0062; # (a◌֚◌̖◌〪◌͉b; a◌〪◌̖◌͉◌֚b; a◌〪◌̖◌͉◌֚b; a◌〪◌̖◌͉◌֚b; a◌〪◌̖◌͉◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT ANGLE BELOW, LATIN SMALL LETTER B
+0061 0349 059A 0316 302A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062;0061 302A 0349 0316 059A 0062; # (a◌͉◌֚◌̖◌〪b; a◌〪◌͉◌̖◌֚b; a◌〪◌͉◌̖◌֚b; a◌〪◌͉◌̖◌֚b; a◌〪◌͉◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT ANGLE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 034A 0062;00E0 05AE 034A 0315 0062;0061 05AE 0300 034A 0315 0062;00E0 05AE 034A 0315 0062;0061 05AE 0300 034A 0315 0062; # (a◌̕◌̀◌֮◌͊b; à◌֮◌͊◌̕b; a◌֮◌̀◌͊◌̕b; à◌֮◌͊◌̕b; a◌֮◌̀◌͊◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING NOT TILDE ABOVE, LATIN SMALL LETTER B
+0061 034A 0315 0300 05AE 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062;0061 05AE 034A 0300 0315 0062; # (a◌͊◌̕◌̀◌֮b; a◌֮◌͊◌̀◌̕b; a◌֮◌͊◌̀◌̕b; a◌֮◌͊◌̀◌̕b; a◌֮◌͊◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING NOT TILDE ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 034B 0062;00E0 05AE 034B 0315 0062;0061 05AE 0300 034B 0315 0062;00E0 05AE 034B 0315 0062;0061 05AE 0300 034B 0315 0062; # (a◌̕◌̀◌֮◌͋b; à◌֮◌͋◌̕b; a◌֮◌̀◌͋◌̕b; à◌֮◌͋◌̕b; a◌֮◌̀◌͋◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING HOMOTHETIC ABOVE, LATIN SMALL LETTER B
+0061 034B 0315 0300 05AE 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062;0061 05AE 034B 0300 0315 0062; # (a◌͋◌̕◌̀◌֮b; a◌֮◌͋◌̀◌̕b; a◌֮◌͋◌̀◌̕b; a◌֮◌͋◌̀◌̕b; a◌֮◌͋◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING HOMOTHETIC ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 034C 0062;00E0 05AE 034C 0315 0062;0061 05AE 0300 034C 0315 0062;00E0 05AE 034C 0315 0062;0061 05AE 0300 034C 0315 0062; # (a◌̕◌̀◌֮◌͌b; à◌֮◌͌◌̕b; a◌֮◌̀◌͌◌̕b; à◌֮◌͌◌̕b; a◌֮◌̀◌͌◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING ALMOST EQUAL TO ABOVE, LATIN SMALL LETTER B
+0061 034C 0315 0300 05AE 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062;0061 05AE 034C 0300 0315 0062; # (a◌͌◌̕◌̀◌֮b; a◌֮◌͌◌̀◌̕b; a◌֮◌͌◌̀◌̕b; a◌֮◌͌◌̀◌̕b; a◌֮◌͌◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ALMOST EQUAL TO ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 034D 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062;0061 302A 0316 034D 059A 0062; # (a◌֚◌̖◌〪◌͍b; a◌〪◌̖◌͍◌֚b; a◌〪◌̖◌͍◌֚b; a◌〪◌̖◌͍◌֚b; a◌〪◌̖◌͍◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT RIGHT ARROW BELOW, LATIN SMALL LETTER B
+0061 034D 059A 0316 302A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062;0061 302A 034D 0316 059A 0062; # (a◌͍◌֚◌̖◌〪b; a◌〪◌͍◌̖◌֚b; a◌〪◌͍◌̖◌֚b; a◌〪◌͍◌̖◌֚b; a◌〪◌͍◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT RIGHT ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 034E 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062;0061 302A 0316 034E 059A 0062; # (a◌֚◌̖◌〪◌͎b; a◌〪◌̖◌͎◌֚b; a◌〪◌̖◌͎◌֚b; a◌〪◌̖◌͎◌֚b; a◌〪◌̖◌͎◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING UPWARDS ARROW BELOW, LATIN SMALL LETTER B
+0061 034E 059A 0316 302A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062;0061 302A 034E 0316 059A 0062; # (a◌͎◌֚◌̖◌〪b; a◌〪◌͎◌̖◌֚b; a◌〪◌͎◌̖◌֚b; a◌〪◌͎◌̖◌֚b; a◌〪◌͎◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING UPWARDS ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0350 0062;00E0 05AE 0350 0315 0062;0061 05AE 0300 0350 0315 0062;00E0 05AE 0350 0315 0062;0061 05AE 0300 0350 0315 0062; # (a◌̕◌̀◌֮◌͐b; à◌֮◌͐◌̕b; a◌֮◌̀◌͐◌̕b; à◌֮◌͐◌̕b; a◌֮◌̀◌͐◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING RIGHT ARROWHEAD ABOVE, LATIN SMALL LETTER B
+0061 0350 0315 0300 05AE 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062;0061 05AE 0350 0300 0315 0062; # (a◌͐◌̕◌̀◌֮b; a◌֮◌͐◌̀◌̕b; a◌֮◌͐◌̀◌̕b; a◌֮◌͐◌̀◌̕b; a◌֮◌͐◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROWHEAD ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0351 0062;00E0 05AE 0351 0315 0062;0061 05AE 0300 0351 0315 0062;00E0 05AE 0351 0315 0062;0061 05AE 0300 0351 0315 0062; # (a◌̕◌̀◌֮◌͑b; à◌֮◌͑◌̕b; a◌֮◌̀◌͑◌̕b; à◌֮◌͑◌̕b; a◌֮◌̀◌͑◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LEFT HALF RING ABOVE, LATIN SMALL LETTER B
+0061 0351 0315 0300 05AE 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062;0061 05AE 0351 0300 0315 0062; # (a◌͑◌̕◌̀◌֮b; a◌֮◌͑◌̀◌̕b; a◌֮◌͑◌̀◌̕b; a◌֮◌͑◌̀◌̕b; a◌֮◌͑◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LEFT HALF RING ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0352 0062;00E0 05AE 0352 0315 0062;0061 05AE 0300 0352 0315 0062;00E0 05AE 0352 0315 0062;0061 05AE 0300 0352 0315 0062; # (a◌̕◌̀◌֮◌͒b; à◌֮◌͒◌̕b; a◌֮◌̀◌͒◌̕b; à◌֮◌͒◌̕b; a◌֮◌̀◌͒◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING FERMATA, LATIN SMALL LETTER B
+0061 0352 0315 0300 05AE 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062;0061 05AE 0352 0300 0315 0062; # (a◌͒◌̕◌̀◌֮b; a◌֮◌͒◌̀◌̕b; a◌֮◌͒◌̀◌̕b; a◌֮◌͒◌̀◌̕b; a◌֮◌͒◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING FERMATA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0353 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062;0061 302A 0316 0353 059A 0062; # (a◌֚◌̖◌〪◌͓b; a◌〪◌̖◌͓◌֚b; a◌〪◌̖◌͓◌֚b; a◌〪◌̖◌͓◌֚b; a◌〪◌̖◌͓◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING X BELOW, LATIN SMALL LETTER B
+0061 0353 059A 0316 302A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062;0061 302A 0353 0316 059A 0062; # (a◌͓◌֚◌̖◌〪b; a◌〪◌͓◌̖◌֚b; a◌〪◌͓◌̖◌֚b; a◌〪◌͓◌̖◌֚b; a◌〪◌͓◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING X BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0354 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062;0061 302A 0316 0354 059A 0062; # (a◌֚◌̖◌〪◌͔b; a◌〪◌̖◌͔◌֚b; a◌〪◌̖◌͔◌֚b; a◌〪◌̖◌͔◌֚b; a◌〪◌̖◌͔◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 0354 059A 0316 302A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062;0061 302A 0354 0316 059A 0062; # (a◌͔◌֚◌̖◌〪b; a◌〪◌͔◌̖◌֚b; a◌〪◌͔◌̖◌֚b; a◌〪◌͔◌̖◌֚b; a◌〪◌͔◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0355 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062;0061 302A 0316 0355 059A 0062; # (a◌֚◌̖◌〪◌͕b; a◌〪◌̖◌͕◌֚b; a◌〪◌̖◌͕◌֚b; a◌〪◌̖◌͕◌֚b; a◌〪◌̖◌͕◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 0355 059A 0316 302A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062;0061 302A 0355 0316 059A 0062; # (a◌͕◌֚◌̖◌〪b; a◌〪◌͕◌̖◌֚b; a◌〪◌͕◌̖◌֚b; a◌〪◌͕◌̖◌֚b; a◌〪◌͕◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0356 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062;0061 302A 0316 0356 059A 0062; # (a◌֚◌̖◌〪◌͖b; a◌〪◌̖◌͖◌֚b; a◌〪◌̖◌͖◌֚b; a◌〪◌̖◌͖◌֚b; a◌〪◌̖◌͖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 0356 059A 0316 302A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062;0061 302A 0356 0316 059A 0062; # (a◌͖◌֚◌̖◌〪b; a◌〪◌͖◌̖◌֚b; a◌〪◌͖◌̖◌֚b; a◌〪◌͖◌̖◌֚b; a◌〪◌͖◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0357 0062;00E0 05AE 0357 0315 0062;0061 05AE 0300 0357 0315 0062;00E0 05AE 0357 0315 0062;0061 05AE 0300 0357 0315 0062; # (a◌̕◌̀◌֮◌͗b; à◌֮◌͗◌̕b; a◌֮◌̀◌͗◌̕b; à◌֮◌͗◌̕b; a◌֮◌̀◌͗◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING RIGHT HALF RING ABOVE, LATIN SMALL LETTER B
+0061 0357 0315 0300 05AE 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062;0061 05AE 0357 0300 0315 0062; # (a◌͗◌̕◌̀◌֮b; a◌֮◌͗◌̀◌̕b; a◌֮◌͗◌̀◌̕b; a◌֮◌͗◌̀◌̕b; a◌֮◌͗◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING RIGHT HALF RING ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 035C 0315 0300 0358 0062;00E0 0315 0358 035C 0062;0061 0300 0315 0358 035C 0062;00E0 0315 0358 035C 0062;0061 0300 0315 0358 035C 0062; # (a◌͜◌̕◌̀◌͘b; à◌̕◌͘◌͜b; a◌̀◌̕◌͘◌͜b; à◌̕◌͘◌͜b; a◌̀◌̕◌͘◌͜b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, COMBINING DOT ABOVE RIGHT, LATIN SMALL LETTER B
+0061 0358 035C 0315 0300 0062;00E0 0358 0315 035C 0062;0061 0300 0358 0315 035C 0062;00E0 0358 0315 035C 0062;0061 0300 0358 0315 035C 0062; # (a◌͘◌͜◌̕◌̀b; à◌͘◌̕◌͜b; a◌̀◌͘◌̕◌͜b; à◌͘◌̕◌͜b; a◌̀◌͘◌̕◌͜b; ) LATIN SMALL LETTER A, COMBINING DOT ABOVE RIGHT, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, LATIN SMALL LETTER B
+0061 059A 0316 302A 0359 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062;0061 302A 0316 0359 059A 0062; # (a◌֚◌̖◌〪◌͙b; a◌〪◌̖◌͙◌֚b; a◌〪◌̖◌͙◌֚b; a◌〪◌̖◌͙◌֚b; a◌〪◌̖◌͙◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING ASTERISK BELOW, LATIN SMALL LETTER B
+0061 0359 059A 0316 302A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062;0061 302A 0359 0316 059A 0062; # (a◌͙◌֚◌̖◌〪b; a◌〪◌͙◌̖◌֚b; a◌〪◌͙◌̖◌֚b; a◌〪◌͙◌̖◌֚b; a◌〪◌͙◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ASTERISK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 035A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062;0061 302A 0316 035A 059A 0062; # (a◌֚◌̖◌〪◌͚b; a◌〪◌̖◌͚◌֚b; a◌〪◌̖◌͚◌֚b; a◌〪◌̖◌͚◌֚b; a◌〪◌̖◌͚◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOUBLE RING BELOW, LATIN SMALL LETTER B
+0061 035A 059A 0316 302A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062;0061 302A 035A 0316 059A 0062; # (a◌͚◌֚◌̖◌〪b; a◌〪◌͚◌̖◌֚b; a◌〪◌͚◌̖◌֚b; a◌〪◌͚◌̖◌֚b; a◌〪◌͚◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 035B 0062;00E0 05AE 035B 0315 0062;0061 05AE 0300 035B 0315 0062;00E0 05AE 035B 0315 0062;0061 05AE 0300 035B 0315 0062; # (a◌̕◌̀◌֮◌͛b; à◌֮◌͛◌̕b; a◌֮◌̀◌͛◌̕b; à◌֮◌͛◌̕b; a◌֮◌̀◌͛◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING ZIGZAG ABOVE, LATIN SMALL LETTER B
+0061 035B 0315 0300 05AE 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062;0061 05AE 035B 0300 0315 0062; # (a◌͛◌̕◌̀◌֮b; a◌֮◌͛◌̀◌̕b; a◌֮◌͛◌̀◌̕b; a◌֮◌͛◌̀◌̕b; a◌֮◌͛◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ZIGZAG ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 035D 035C 0315 035C 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062; # (a◌͝◌͜◌̕◌͜b; a◌̕◌͜◌͜◌͝b; a◌̕◌͜◌͜◌͝b; a◌̕◌͜◌͜◌͝b; a◌̕◌͜◌͜◌͝b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING DOUBLE BREVE BELOW, LATIN SMALL LETTER B
+0061 035C 035D 035C 0315 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062;0061 0315 035C 035C 035D 0062; # (a◌͜◌͝◌͜◌̕b; a◌̕◌͜◌͜◌͝b; a◌̕◌͜◌͜◌͝b; a◌̕◌͜◌͜◌͝b; a◌̕◌͜◌͜◌͝b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE BELOW, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, LATIN SMALL LETTER B
+0061 0345 035D 035C 035D 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062; # (a◌ͅ◌͝◌͜◌͝b; a◌͜◌͝◌͝◌ͅb; a◌͜◌͝◌͝◌ͅb; a◌͜◌͝◌͝◌ͅb; a◌͜◌͝◌͝◌ͅb; ) LATIN SMALL LETTER A, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING DOUBLE BREVE, LATIN SMALL LETTER B
+0061 035D 0345 035D 035C 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062;0061 035C 035D 035D 0345 0062; # (a◌͝◌ͅ◌͝◌͜b; a◌͜◌͝◌͝◌ͅb; a◌͜◌͝◌͝◌ͅb; a◌͜◌͝◌͝◌ͅb; a◌͜◌͝◌͝◌ͅb; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, LATIN SMALL LETTER B
+0061 0345 035D 035C 035E 0062;0061 035C 035D 035E 0345 0062;0061 035C 035D 035E 0345 0062;0061 035C 035D 035E 0345 0062;0061 035C 035D 035E 0345 0062; # (a◌ͅ◌͝◌͜◌͞b; a◌͜◌͝◌͞◌ͅb; a◌͜◌͝◌͞◌ͅb; a◌͜◌͝◌͞◌ͅb; a◌͜◌͝◌͞◌ͅb; ) LATIN SMALL LETTER A, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING DOUBLE MACRON, LATIN SMALL LETTER B
+0061 035E 0345 035D 035C 0062;0061 035C 035E 035D 0345 0062;0061 035C 035E 035D 0345 0062;0061 035C 035E 035D 0345 0062;0061 035C 035E 035D 0345 0062; # (a◌͞◌ͅ◌͝◌͜b; a◌͜◌͞◌͝◌ͅb; a◌͜◌͞◌͝◌ͅb; a◌͜◌͞◌͝◌ͅb; a◌͜◌͞◌͝◌ͅb; ) LATIN SMALL LETTER A, COMBINING DOUBLE MACRON, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, LATIN SMALL LETTER B
+0061 035D 035C 0315 035F 0062;0061 0315 035C 035F 035D 0062;0061 0315 035C 035F 035D 0062;0061 0315 035C 035F 035D 0062;0061 0315 035C 035F 035D 0062; # (a◌͝◌͜◌̕◌͟b; a◌̕◌͜◌͟◌͝b; a◌̕◌͜◌͟◌͝b; a◌̕◌͜◌͟◌͝b; a◌̕◌͜◌͟◌͝b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING DOUBLE MACRON BELOW, LATIN SMALL LETTER B
+0061 035F 035D 035C 0315 0062;0061 0315 035F 035C 035D 0062;0061 0315 035F 035C 035D 0062;0061 0315 035F 035C 035D 0062;0061 0315 035F 035C 035D 0062; # (a◌͟◌͝◌͜◌̕b; a◌̕◌͟◌͜◌͝b; a◌̕◌͟◌͜◌͝b; a◌̕◌͟◌͜◌͝b; a◌̕◌͟◌͜◌͝b; ) LATIN SMALL LETTER A, COMBINING DOUBLE MACRON BELOW, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, LATIN SMALL LETTER B
+0061 0345 035D 035C 0360 0062;0061 035C 035D 0360 0345 0062;0061 035C 035D 0360 0345 0062;0061 035C 035D 0360 0345 0062;0061 035C 035D 0360 0345 0062; # (a◌ͅ◌͝◌͜◌͠b; a◌͜◌͝◌͠◌ͅb; a◌͜◌͝◌͠◌ͅb; a◌͜◌͝◌͠◌ͅb; a◌͜◌͝◌͠◌ͅb; ) LATIN SMALL LETTER A, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING DOUBLE TILDE, LATIN SMALL LETTER B
+0061 0360 0345 035D 035C 0062;0061 035C 0360 035D 0345 0062;0061 035C 0360 035D 0345 0062;0061 035C 0360 035D 0345 0062;0061 035C 0360 035D 0345 0062; # (a◌͠◌ͅ◌͝◌͜b; a◌͜◌͠◌͝◌ͅb; a◌͜◌͠◌͝◌ͅb; a◌͜◌͠◌͝◌ͅb; a◌͜◌͠◌͝◌ͅb; ) LATIN SMALL LETTER A, COMBINING DOUBLE TILDE, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, LATIN SMALL LETTER B
+0061 0345 035D 035C 0361 0062;0061 035C 035D 0361 0345 0062;0061 035C 035D 0361 0345 0062;0061 035C 035D 0361 0345 0062;0061 035C 035D 0361 0345 0062; # (a◌ͅ◌͝◌͜◌͡b; a◌͜◌͝◌͡◌ͅb; a◌͜◌͝◌͡◌ͅb; a◌͜◌͝◌͡◌ͅb; a◌͜◌͝◌͡◌ͅb; ) LATIN SMALL LETTER A, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING DOUBLE INVERTED BREVE, LATIN SMALL LETTER B
+0061 0361 0345 035D 035C 0062;0061 035C 0361 035D 0345 0062;0061 035C 0361 035D 0345 0062;0061 035C 0361 035D 0345 0062;0061 035C 0361 035D 0345 0062; # (a◌͡◌ͅ◌͝◌͜b; a◌͜◌͡◌͝◌ͅb; a◌͜◌͡◌͝◌ͅb; a◌͜◌͡◌͝◌ͅb; a◌͜◌͡◌͝◌ͅb; ) LATIN SMALL LETTER A, COMBINING DOUBLE INVERTED BREVE, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, LATIN SMALL LETTER B
+0061 035D 035C 0315 0362 0062;0061 0315 035C 0362 035D 0062;0061 0315 035C 0362 035D 0062;0061 0315 035C 0362 035D 0062;0061 0315 035C 0362 035D 0062; # (a◌͝◌͜◌̕◌͢b; a◌̕◌͜◌͢◌͝b; a◌̕◌͜◌͢◌͝b; a◌̕◌͜◌͢◌͝b; a◌̕◌͜◌͢◌͝b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING DOUBLE RIGHTWARDS ARROW BELOW, LATIN SMALL LETTER B
+0061 0362 035D 035C 0315 0062;0061 0315 0362 035C 035D 0062;0061 0315 0362 035C 035D 0062;0061 0315 0362 035C 035D 0062;0061 0315 0362 035C 035D 0062; # (a◌͢◌͝◌͜◌̕b; a◌̕◌͢◌͜◌͝b; a◌̕◌͢◌͜◌͝b; a◌̕◌͢◌͜◌͝b; a◌̕◌͢◌͜◌͝b; ) LATIN SMALL LETTER A, COMBINING DOUBLE RIGHTWARDS ARROW BELOW, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0363 0062;00E0 05AE 0363 0315 0062;0061 05AE 0300 0363 0315 0062;00E0 05AE 0363 0315 0062;0061 05AE 0300 0363 0315 0062; # (a◌̕◌̀◌֮◌ͣb; à◌֮◌ͣ◌̕b; a◌֮◌̀◌ͣ◌̕b; à◌֮◌ͣ◌̕b; a◌֮◌̀◌ͣ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER A, LATIN SMALL LETTER B
+0061 0363 0315 0300 05AE 0062;0061 05AE 0363 0300 0315 0062;0061 05AE 0363 0300 0315 0062;0061 05AE 0363 0300 0315 0062;0061 05AE 0363 0300 0315 0062; # (a◌ͣ◌̕◌̀◌֮b; a◌֮◌ͣ◌̀◌̕b; a◌֮◌ͣ◌̀◌̕b; a◌֮◌ͣ◌̀◌̕b; a◌֮◌ͣ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0364 0062;00E0 05AE 0364 0315 0062;0061 05AE 0300 0364 0315 0062;00E0 05AE 0364 0315 0062;0061 05AE 0300 0364 0315 0062; # (a◌̕◌̀◌֮◌ͤb; à◌֮◌ͤ◌̕b; a◌֮◌̀◌ͤ◌̕b; à◌֮◌ͤ◌̕b; a◌֮◌̀◌ͤ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER E, LATIN SMALL LETTER B
+0061 0364 0315 0300 05AE 0062;0061 05AE 0364 0300 0315 0062;0061 05AE 0364 0300 0315 0062;0061 05AE 0364 0300 0315 0062;0061 05AE 0364 0300 0315 0062; # (a◌ͤ◌̕◌̀◌֮b; a◌֮◌ͤ◌̀◌̕b; a◌֮◌ͤ◌̀◌̕b; a◌֮◌ͤ◌̀◌̕b; a◌֮◌ͤ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER E, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0365 0062;00E0 05AE 0365 0315 0062;0061 05AE 0300 0365 0315 0062;00E0 05AE 0365 0315 0062;0061 05AE 0300 0365 0315 0062; # (a◌̕◌̀◌֮◌ͥb; à◌֮◌ͥ◌̕b; a◌֮◌̀◌ͥ◌̕b; à◌֮◌ͥ◌̕b; a◌֮◌̀◌ͥ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER I, LATIN SMALL LETTER B
+0061 0365 0315 0300 05AE 0062;0061 05AE 0365 0300 0315 0062;0061 05AE 0365 0300 0315 0062;0061 05AE 0365 0300 0315 0062;0061 05AE 0365 0300 0315 0062; # (a◌ͥ◌̕◌̀◌֮b; a◌֮◌ͥ◌̀◌̕b; a◌֮◌ͥ◌̀◌̕b; a◌֮◌ͥ◌̀◌̕b; a◌֮◌ͥ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER I, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0366 0062;00E0 05AE 0366 0315 0062;0061 05AE 0300 0366 0315 0062;00E0 05AE 0366 0315 0062;0061 05AE 0300 0366 0315 0062; # (a◌̕◌̀◌֮◌ͦb; à◌֮◌ͦ◌̕b; a◌֮◌̀◌ͦ◌̕b; à◌֮◌ͦ◌̕b; a◌֮◌̀◌ͦ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER O, LATIN SMALL LETTER B
+0061 0366 0315 0300 05AE 0062;0061 05AE 0366 0300 0315 0062;0061 05AE 0366 0300 0315 0062;0061 05AE 0366 0300 0315 0062;0061 05AE 0366 0300 0315 0062; # (a◌ͦ◌̕◌̀◌֮b; a◌֮◌ͦ◌̀◌̕b; a◌֮◌ͦ◌̀◌̕b; a◌֮◌ͦ◌̀◌̕b; a◌֮◌ͦ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER O, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0367 0062;00E0 05AE 0367 0315 0062;0061 05AE 0300 0367 0315 0062;00E0 05AE 0367 0315 0062;0061 05AE 0300 0367 0315 0062; # (a◌̕◌̀◌֮◌ͧb; à◌֮◌ͧ◌̕b; a◌֮◌̀◌ͧ◌̕b; à◌֮◌ͧ◌̕b; a◌֮◌̀◌ͧ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER U, LATIN SMALL LETTER B
+0061 0367 0315 0300 05AE 0062;0061 05AE 0367 0300 0315 0062;0061 05AE 0367 0300 0315 0062;0061 05AE 0367 0300 0315 0062;0061 05AE 0367 0300 0315 0062; # (a◌ͧ◌̕◌̀◌֮b; a◌֮◌ͧ◌̀◌̕b; a◌֮◌ͧ◌̀◌̕b; a◌֮◌ͧ◌̀◌̕b; a◌֮◌ͧ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER U, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0368 0062;00E0 05AE 0368 0315 0062;0061 05AE 0300 0368 0315 0062;00E0 05AE 0368 0315 0062;0061 05AE 0300 0368 0315 0062; # (a◌̕◌̀◌֮◌ͨb; à◌֮◌ͨ◌̕b; a◌֮◌̀◌ͨ◌̕b; à◌֮◌ͨ◌̕b; a◌֮◌̀◌ͨ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER C, LATIN SMALL LETTER B
+0061 0368 0315 0300 05AE 0062;0061 05AE 0368 0300 0315 0062;0061 05AE 0368 0300 0315 0062;0061 05AE 0368 0300 0315 0062;0061 05AE 0368 0300 0315 0062; # (a◌ͨ◌̕◌̀◌֮b; a◌֮◌ͨ◌̀◌̕b; a◌֮◌ͨ◌̀◌̕b; a◌֮◌ͨ◌̀◌̕b; a◌֮◌ͨ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER C, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0369 0062;00E0 05AE 0369 0315 0062;0061 05AE 0300 0369 0315 0062;00E0 05AE 0369 0315 0062;0061 05AE 0300 0369 0315 0062; # (a◌̕◌̀◌֮◌ͩb; à◌֮◌ͩ◌̕b; a◌֮◌̀◌ͩ◌̕b; à◌֮◌ͩ◌̕b; a◌֮◌̀◌ͩ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER D, LATIN SMALL LETTER B
+0061 0369 0315 0300 05AE 0062;0061 05AE 0369 0300 0315 0062;0061 05AE 0369 0300 0315 0062;0061 05AE 0369 0300 0315 0062;0061 05AE 0369 0300 0315 0062; # (a◌ͩ◌̕◌̀◌֮b; a◌֮◌ͩ◌̀◌̕b; a◌֮◌ͩ◌̀◌̕b; a◌֮◌ͩ◌̀◌̕b; a◌֮◌ͩ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER D, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 036A 0062;00E0 05AE 036A 0315 0062;0061 05AE 0300 036A 0315 0062;00E0 05AE 036A 0315 0062;0061 05AE 0300 036A 0315 0062; # (a◌̕◌̀◌֮◌ͪb; à◌֮◌ͪ◌̕b; a◌֮◌̀◌ͪ◌̕b; à◌֮◌ͪ◌̕b; a◌֮◌̀◌ͪ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER H, LATIN SMALL LETTER B
+0061 036A 0315 0300 05AE 0062;0061 05AE 036A 0300 0315 0062;0061 05AE 036A 0300 0315 0062;0061 05AE 036A 0300 0315 0062;0061 05AE 036A 0300 0315 0062; # (a◌ͪ◌̕◌̀◌֮b; a◌֮◌ͪ◌̀◌̕b; a◌֮◌ͪ◌̀◌̕b; a◌֮◌ͪ◌̀◌̕b; a◌֮◌ͪ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER H, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 036B 0062;00E0 05AE 036B 0315 0062;0061 05AE 0300 036B 0315 0062;00E0 05AE 036B 0315 0062;0061 05AE 0300 036B 0315 0062; # (a◌̕◌̀◌֮◌ͫb; à◌֮◌ͫ◌̕b; a◌֮◌̀◌ͫ◌̕b; à◌֮◌ͫ◌̕b; a◌֮◌̀◌ͫ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER M, LATIN SMALL LETTER B
+0061 036B 0315 0300 05AE 0062;0061 05AE 036B 0300 0315 0062;0061 05AE 036B 0300 0315 0062;0061 05AE 036B 0300 0315 0062;0061 05AE 036B 0300 0315 0062; # (a◌ͫ◌̕◌̀◌֮b; a◌֮◌ͫ◌̀◌̕b; a◌֮◌ͫ◌̀◌̕b; a◌֮◌ͫ◌̀◌̕b; a◌֮◌ͫ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER M, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 036C 0062;00E0 05AE 036C 0315 0062;0061 05AE 0300 036C 0315 0062;00E0 05AE 036C 0315 0062;0061 05AE 0300 036C 0315 0062; # (a◌̕◌̀◌֮◌ͬb; à◌֮◌ͬ◌̕b; a◌֮◌̀◌ͬ◌̕b; à◌֮◌ͬ◌̕b; a◌֮◌̀◌ͬ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER R, LATIN SMALL LETTER B
+0061 036C 0315 0300 05AE 0062;0061 05AE 036C 0300 0315 0062;0061 05AE 036C 0300 0315 0062;0061 05AE 036C 0300 0315 0062;0061 05AE 036C 0300 0315 0062; # (a◌ͬ◌̕◌̀◌֮b; a◌֮◌ͬ◌̀◌̕b; a◌֮◌ͬ◌̀◌̕b; a◌֮◌ͬ◌̀◌̕b; a◌֮◌ͬ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER R, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 036D 0062;00E0 05AE 036D 0315 0062;0061 05AE 0300 036D 0315 0062;00E0 05AE 036D 0315 0062;0061 05AE 0300 036D 0315 0062; # (a◌̕◌̀◌֮◌ͭb; à◌֮◌ͭ◌̕b; a◌֮◌̀◌ͭ◌̕b; à◌֮◌ͭ◌̕b; a◌֮◌̀◌ͭ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER T, LATIN SMALL LETTER B
+0061 036D 0315 0300 05AE 0062;0061 05AE 036D 0300 0315 0062;0061 05AE 036D 0300 0315 0062;0061 05AE 036D 0300 0315 0062;0061 05AE 036D 0300 0315 0062; # (a◌ͭ◌̕◌̀◌֮b; a◌֮◌ͭ◌̀◌̕b; a◌֮◌ͭ◌̀◌̕b; a◌֮◌ͭ◌̀◌̕b; a◌֮◌ͭ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER T, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 036E 0062;00E0 05AE 036E 0315 0062;0061 05AE 0300 036E 0315 0062;00E0 05AE 036E 0315 0062;0061 05AE 0300 036E 0315 0062; # (a◌̕◌̀◌֮◌ͮb; à◌֮◌ͮ◌̕b; a◌֮◌̀◌ͮ◌̕b; à◌֮◌ͮ◌̕b; a◌֮◌̀◌ͮ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER V, LATIN SMALL LETTER B
+0061 036E 0315 0300 05AE 0062;0061 05AE 036E 0300 0315 0062;0061 05AE 036E 0300 0315 0062;0061 05AE 036E 0300 0315 0062;0061 05AE 036E 0300 0315 0062; # (a◌ͮ◌̕◌̀◌֮b; a◌֮◌ͮ◌̀◌̕b; a◌֮◌ͮ◌̀◌̕b; a◌֮◌ͮ◌̀◌̕b; a◌֮◌ͮ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER V, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 036F 0062;00E0 05AE 036F 0315 0062;0061 05AE 0300 036F 0315 0062;00E0 05AE 036F 0315 0062;0061 05AE 0300 036F 0315 0062; # (a◌̕◌̀◌֮◌ͯb; à◌֮◌ͯ◌̕b; a◌֮◌̀◌ͯ◌̕b; à◌֮◌ͯ◌̕b; a◌֮◌̀◌ͯ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER X, LATIN SMALL LETTER B
+0061 036F 0315 0300 05AE 0062;0061 05AE 036F 0300 0315 0062;0061 05AE 036F 0300 0315 0062;0061 05AE 036F 0300 0315 0062;0061 05AE 036F 0300 0315 0062; # (a◌ͯ◌̕◌̀◌֮b; a◌֮◌ͯ◌̀◌̕b; a◌֮◌ͯ◌̀◌̕b; a◌֮◌ͯ◌̀◌̕b; a◌֮◌ͯ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER X, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0483 0062;00E0 05AE 0483 0315 0062;0061 05AE 0300 0483 0315 0062;00E0 05AE 0483 0315 0062;0061 05AE 0300 0483 0315 0062; # (a◌̕◌̀◌֮◌҃b; à◌֮◌҃◌̕b; a◌֮◌̀◌҃◌̕b; à◌֮◌҃◌̕b; a◌֮◌̀◌҃◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC TITLO, LATIN SMALL LETTER B
+0061 0483 0315 0300 05AE 0062;0061 05AE 0483 0300 0315 0062;0061 05AE 0483 0300 0315 0062;0061 05AE 0483 0300 0315 0062;0061 05AE 0483 0300 0315 0062; # (a◌҃◌̕◌̀◌֮b; a◌֮◌҃◌̀◌̕b; a◌֮◌҃◌̀◌̕b; a◌֮◌҃◌̀◌̕b; a◌֮◌҃◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0484 0062;00E0 05AE 0484 0315 0062;0061 05AE 0300 0484 0315 0062;00E0 05AE 0484 0315 0062;0061 05AE 0300 0484 0315 0062; # (a◌̕◌̀◌֮◌҄b; à◌֮◌҄◌̕b; a◌֮◌̀◌҄◌̕b; à◌֮◌҄◌̕b; a◌֮◌̀◌҄◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC PALATALIZATION, LATIN SMALL LETTER B
+0061 0484 0315 0300 05AE 0062;0061 05AE 0484 0300 0315 0062;0061 05AE 0484 0300 0315 0062;0061 05AE 0484 0300 0315 0062;0061 05AE 0484 0300 0315 0062; # (a◌҄◌̕◌̀◌֮b; a◌֮◌҄◌̀◌̕b; a◌֮◌҄◌̀◌̕b; a◌֮◌҄◌̀◌̕b; a◌֮◌҄◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC PALATALIZATION, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0485 0062;00E0 05AE 0485 0315 0062;0061 05AE 0300 0485 0315 0062;00E0 05AE 0485 0315 0062;0061 05AE 0300 0485 0315 0062; # (a◌̕◌̀◌֮◌҅b; à◌֮◌҅◌̕b; a◌֮◌̀◌҅◌̕b; à◌֮◌҅◌̕b; a◌֮◌̀◌҅◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC DASIA PNEUMATA, LATIN SMALL LETTER B
+0061 0485 0315 0300 05AE 0062;0061 05AE 0485 0300 0315 0062;0061 05AE 0485 0300 0315 0062;0061 05AE 0485 0300 0315 0062;0061 05AE 0485 0300 0315 0062; # (a◌҅◌̕◌̀◌֮b; a◌֮◌҅◌̀◌̕b; a◌֮◌҅◌̀◌̕b; a◌֮◌҅◌̀◌̕b; a◌֮◌҅◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC DASIA PNEUMATA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0486 0062;00E0 05AE 0486 0315 0062;0061 05AE 0300 0486 0315 0062;00E0 05AE 0486 0315 0062;0061 05AE 0300 0486 0315 0062; # (a◌̕◌̀◌֮◌҆b; à◌֮◌҆◌̕b; a◌֮◌̀◌҆◌̕b; à◌֮◌҆◌̕b; a◌֮◌̀◌҆◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC PSILI PNEUMATA, LATIN SMALL LETTER B
+0061 0486 0315 0300 05AE 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062;0061 05AE 0486 0300 0315 0062; # (a◌҆◌̕◌̀◌֮b; a◌֮◌҆◌̀◌̕b; a◌֮◌҆◌̀◌̕b; a◌֮◌҆◌̀◌̕b; a◌֮◌҆◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC PSILI PNEUMATA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0487 0062;00E0 05AE 0487 0315 0062;0061 05AE 0300 0487 0315 0062;00E0 05AE 0487 0315 0062;0061 05AE 0300 0487 0315 0062; # (a◌̕◌̀◌֮◌҇b; à◌֮◌҇◌̕b; a◌֮◌̀◌҇◌̕b; à◌֮◌҇◌̕b; a◌֮◌̀◌҇◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC POKRYTIE, LATIN SMALL LETTER B
+0061 0487 0315 0300 05AE 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062;0061 05AE 0487 0300 0315 0062; # (a◌҇◌̕◌̀◌֮b; a◌֮◌҇◌̀◌̕b; a◌֮◌҇◌̀◌̕b; a◌֮◌҇◌̀◌̕b; a◌֮◌҇◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC POKRYTIE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0591 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062;0061 302A 0316 0591 059A 0062; # (a◌֚◌̖◌〪◌֑b; a◌〪◌̖◌֑◌֚b; a◌〪◌̖◌֑◌֚b; a◌〪◌̖◌֑◌֚b; a◌〪◌̖◌֑◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT ETNAHTA, LATIN SMALL LETTER B
+0061 0591 059A 0316 302A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062;0061 302A 0591 0316 059A 0062; # (a◌֑◌֚◌̖◌〪b; a◌〪◌֑◌̖◌֚b; a◌〪◌֑◌̖◌֚b; a◌〪◌֑◌̖◌֚b; a◌〪◌֑◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT ETNAHTA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0592 0062;00E0 05AE 0592 0315 0062;0061 05AE 0300 0592 0315 0062;00E0 05AE 0592 0315 0062;0061 05AE 0300 0592 0315 0062; # (a◌̕◌̀◌֮◌֒b; à◌֮◌֒◌̕b; a◌֮◌̀◌֒◌̕b; à◌֮◌֒◌̕b; a◌֮◌̀◌֒◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT SEGOL, LATIN SMALL LETTER B
+0061 0592 0315 0300 05AE 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062;0061 05AE 0592 0300 0315 0062; # (a◌֒◌̕◌̀◌֮b; a◌֮◌֒◌̀◌̕b; a◌֮◌֒◌̀◌̕b; a◌֮◌֒◌̀◌̕b; a◌֮◌֒◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT SEGOL, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0593 0062;00E0 05AE 0593 0315 0062;0061 05AE 0300 0593 0315 0062;00E0 05AE 0593 0315 0062;0061 05AE 0300 0593 0315 0062; # (a◌̕◌̀◌֮◌֓b; à◌֮◌֓◌̕b; a◌֮◌̀◌֓◌̕b; à◌֮◌֓◌̕b; a◌֮◌̀◌֓◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT SHALSHELET, LATIN SMALL LETTER B
+0061 0593 0315 0300 05AE 0062;0061 05AE 0593 0300 0315 0062;0061 05AE 0593 0300 0315 0062;0061 05AE 0593 0300 0315 0062;0061 05AE 0593 0300 0315 0062; # (a◌֓◌̕◌̀◌֮b; a◌֮◌֓◌̀◌̕b; a◌֮◌֓◌̀◌̕b; a◌֮◌֓◌̀◌̕b; a◌֮◌֓◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT SHALSHELET, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0594 0062;00E0 05AE 0594 0315 0062;0061 05AE 0300 0594 0315 0062;00E0 05AE 0594 0315 0062;0061 05AE 0300 0594 0315 0062; # (a◌̕◌̀◌֮◌֔b; à◌֮◌֔◌̕b; a◌֮◌̀◌֔◌̕b; à◌֮◌֔◌̕b; a◌֮◌̀◌֔◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT ZAQEF QATAN, LATIN SMALL LETTER B
+0061 0594 0315 0300 05AE 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062;0061 05AE 0594 0300 0315 0062; # (a◌֔◌̕◌̀◌֮b; a◌֮◌֔◌̀◌̕b; a◌֮◌֔◌̀◌̕b; a◌֮◌֔◌̀◌̕b; a◌֮◌֔◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT ZAQEF QATAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0595 0062;00E0 05AE 0595 0315 0062;0061 05AE 0300 0595 0315 0062;00E0 05AE 0595 0315 0062;0061 05AE 0300 0595 0315 0062; # (a◌̕◌̀◌֮◌֕b; à◌֮◌֕◌̕b; a◌֮◌̀◌֕◌̕b; à◌֮◌֕◌̕b; a◌֮◌̀◌֕◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT ZAQEF GADOL, LATIN SMALL LETTER B
+0061 0595 0315 0300 05AE 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062;0061 05AE 0595 0300 0315 0062; # (a◌֕◌̕◌̀◌֮b; a◌֮◌֕◌̀◌̕b; a◌֮◌֕◌̀◌̕b; a◌֮◌֕◌̀◌̕b; a◌֮◌֕◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT ZAQEF GADOL, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0596 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062;0061 302A 0316 0596 059A 0062; # (a◌֚◌̖◌〪◌֖b; a◌〪◌̖◌֖◌֚b; a◌〪◌̖◌֖◌֚b; a◌〪◌̖◌֖◌֚b; a◌〪◌̖◌֖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT TIPEHA, LATIN SMALL LETTER B
+0061 0596 059A 0316 302A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062;0061 302A 0596 0316 059A 0062; # (a◌֖◌֚◌̖◌〪b; a◌〪◌֖◌̖◌֚b; a◌〪◌֖◌̖◌֚b; a◌〪◌֖◌̖◌֚b; a◌〪◌֖◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT TIPEHA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0597 0062;00E0 05AE 0597 0315 0062;0061 05AE 0300 0597 0315 0062;00E0 05AE 0597 0315 0062;0061 05AE 0300 0597 0315 0062; # (a◌̕◌̀◌֮◌֗b; à◌֮◌֗◌̕b; a◌֮◌̀◌֗◌̕b; à◌֮◌֗◌̕b; a◌֮◌̀◌֗◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT REVIA, LATIN SMALL LETTER B
+0061 0597 0315 0300 05AE 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062;0061 05AE 0597 0300 0315 0062; # (a◌֗◌̕◌̀◌֮b; a◌֮◌֗◌̀◌̕b; a◌֮◌֗◌̀◌̕b; a◌֮◌֗◌̀◌̕b; a◌֮◌֗◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT REVIA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0598 0062;00E0 05AE 0598 0315 0062;0061 05AE 0300 0598 0315 0062;00E0 05AE 0598 0315 0062;0061 05AE 0300 0598 0315 0062; # (a◌̕◌̀◌֮◌֘b; à◌֮◌֘◌̕b; a◌֮◌̀◌֘◌̕b; à◌֮◌֘◌̕b; a◌֮◌̀◌֘◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT ZARQA, LATIN SMALL LETTER B
+0061 0598 0315 0300 05AE 0062;0061 05AE 0598 0300 0315 0062;0061 05AE 0598 0300 0315 0062;0061 05AE 0598 0300 0315 0062;0061 05AE 0598 0300 0315 0062; # (a◌֘◌̕◌̀◌֮b; a◌֮◌֘◌̀◌̕b; a◌֮◌֘◌̀◌̕b; a◌֮◌֘◌̀◌̕b; a◌֮◌֘◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT ZARQA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0599 0062;00E0 05AE 0599 0315 0062;0061 05AE 0300 0599 0315 0062;00E0 05AE 0599 0315 0062;0061 05AE 0300 0599 0315 0062; # (a◌̕◌̀◌֮◌֙b; à◌֮◌֙◌̕b; a◌֮◌̀◌֙◌̕b; à◌֮◌֙◌̕b; a◌֮◌̀◌֙◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT PASHTA, LATIN SMALL LETTER B
+0061 0599 0315 0300 05AE 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062;0061 05AE 0599 0300 0315 0062; # (a◌֙◌̕◌̀◌֮b; a◌֮◌֙◌̀◌̕b; a◌֮◌֙◌̀◌̕b; a◌֮◌֙◌̀◌̕b; a◌֮◌֙◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT PASHTA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 302E 059A 0316 059A 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062; # (a〮◌֚◌̖◌֚b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; ) LATIN SMALL LETTER A, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, HEBREW ACCENT YETIV, LATIN SMALL LETTER B
+0061 059A 302E 059A 0316 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062;0061 0316 059A 059A 302E 0062; # (a◌֚〮◌֚◌̖b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; a◌̖◌֚◌֚〮b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, LATIN SMALL LETTER B
+0061 059A 0316 302A 059B 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062;0061 302A 0316 059B 059A 0062; # (a◌֚◌̖◌〪◌֛b; a◌〪◌̖◌֛◌֚b; a◌〪◌̖◌֛◌֚b; a◌〪◌̖◌֛◌֚b; a◌〪◌̖◌֛◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT TEVIR, LATIN SMALL LETTER B
+0061 059B 059A 0316 302A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062;0061 302A 059B 0316 059A 0062; # (a◌֛◌֚◌̖◌〪b; a◌〪◌֛◌̖◌֚b; a◌〪◌֛◌̖◌֚b; a◌〪◌֛◌̖◌֚b; a◌〪◌֛◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT TEVIR, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 059C 0062;00E0 05AE 059C 0315 0062;0061 05AE 0300 059C 0315 0062;00E0 05AE 059C 0315 0062;0061 05AE 0300 059C 0315 0062; # (a◌̕◌̀◌֮◌֜b; à◌֮◌֜◌̕b; a◌֮◌̀◌֜◌̕b; à◌֮◌֜◌̕b; a◌֮◌̀◌֜◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT GERESH, LATIN SMALL LETTER B
+0061 059C 0315 0300 05AE 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062;0061 05AE 059C 0300 0315 0062; # (a◌֜◌̕◌̀◌֮b; a◌֮◌֜◌̀◌̕b; a◌֮◌֜◌̀◌̕b; a◌֮◌֜◌̀◌̕b; a◌֮◌֜◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT GERESH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 059D 0062;00E0 05AE 059D 0315 0062;0061 05AE 0300 059D 0315 0062;00E0 05AE 059D 0315 0062;0061 05AE 0300 059D 0315 0062; # (a◌̕◌̀◌֮◌֝b; à◌֮◌֝◌̕b; a◌֮◌̀◌֝◌̕b; à◌֮◌֝◌̕b; a◌֮◌̀◌֝◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT GERESH MUQDAM, LATIN SMALL LETTER B
+0061 059D 0315 0300 05AE 0062;0061 05AE 059D 0300 0315 0062;0061 05AE 059D 0300 0315 0062;0061 05AE 059D 0300 0315 0062;0061 05AE 059D 0300 0315 0062; # (a◌֝◌̕◌̀◌֮b; a◌֮◌֝◌̀◌̕b; a◌֮◌֝◌̀◌̕b; a◌֮◌֝◌̀◌̕b; a◌֮◌֝◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT GERESH MUQDAM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 059E 0062;00E0 05AE 059E 0315 0062;0061 05AE 0300 059E 0315 0062;00E0 05AE 059E 0315 0062;0061 05AE 0300 059E 0315 0062; # (a◌̕◌̀◌֮◌֞b; à◌֮◌֞◌̕b; a◌֮◌̀◌֞◌̕b; à◌֮◌֞◌̕b; a◌֮◌̀◌֞◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT GERSHAYIM, LATIN SMALL LETTER B
+0061 059E 0315 0300 05AE 0062;0061 05AE 059E 0300 0315 0062;0061 05AE 059E 0300 0315 0062;0061 05AE 059E 0300 0315 0062;0061 05AE 059E 0300 0315 0062; # (a◌֞◌̕◌̀◌֮b; a◌֮◌֞◌̀◌̕b; a◌֮◌֞◌̀◌̕b; a◌֮◌֞◌̀◌̕b; a◌֮◌֞◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT GERSHAYIM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 059F 0062;00E0 05AE 059F 0315 0062;0061 05AE 0300 059F 0315 0062;00E0 05AE 059F 0315 0062;0061 05AE 0300 059F 0315 0062; # (a◌̕◌̀◌֮◌֟b; à◌֮◌֟◌̕b; a◌֮◌̀◌֟◌̕b; à◌֮◌֟◌̕b; a◌֮◌̀◌֟◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT QARNEY PARA, LATIN SMALL LETTER B
+0061 059F 0315 0300 05AE 0062;0061 05AE 059F 0300 0315 0062;0061 05AE 059F 0300 0315 0062;0061 05AE 059F 0300 0315 0062;0061 05AE 059F 0300 0315 0062; # (a◌֟◌̕◌̀◌֮b; a◌֮◌֟◌̀◌̕b; a◌֮◌֟◌̀◌̕b; a◌֮◌֟◌̀◌̕b; a◌֮◌֟◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT QARNEY PARA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 05A0 0062;00E0 05AE 05A0 0315 0062;0061 05AE 0300 05A0 0315 0062;00E0 05AE 05A0 0315 0062;0061 05AE 0300 05A0 0315 0062; # (a◌̕◌̀◌֮◌֠b; à◌֮◌֠◌̕b; a◌֮◌̀◌֠◌̕b; à◌֮◌֠◌̕b; a◌֮◌̀◌֠◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT TELISHA GEDOLA, LATIN SMALL LETTER B
+0061 05A0 0315 0300 05AE 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062;0061 05AE 05A0 0300 0315 0062; # (a◌֠◌̕◌̀◌֮b; a◌֮◌֠◌̀◌̕b; a◌֮◌֠◌̀◌̕b; a◌֮◌֠◌̀◌̕b; a◌֮◌֠◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT TELISHA GEDOLA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 05A1 0062;00E0 05AE 05A1 0315 0062;0061 05AE 0300 05A1 0315 0062;00E0 05AE 05A1 0315 0062;0061 05AE 0300 05A1 0315 0062; # (a◌̕◌̀◌֮◌֡b; à◌֮◌֡◌̕b; a◌֮◌̀◌֡◌̕b; à◌֮◌֡◌̕b; a◌֮◌̀◌֡◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT PAZER, LATIN SMALL LETTER B
+0061 05A1 0315 0300 05AE 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062;0061 05AE 05A1 0300 0315 0062; # (a◌֡◌̕◌̀◌֮b; a◌֮◌֡◌̀◌̕b; a◌֮◌֡◌̀◌̕b; a◌֮◌֡◌̀◌̕b; a◌֮◌֡◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT PAZER, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 05A2 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062;0061 302A 0316 05A2 059A 0062; # (a◌֚◌̖◌〪◌֢b; a◌〪◌̖◌֢◌֚b; a◌〪◌̖◌֢◌֚b; a◌〪◌̖◌֢◌֚b; a◌〪◌̖◌֢◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT ATNAH HAFUKH, LATIN SMALL LETTER B
+0061 05A2 059A 0316 302A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062;0061 302A 05A2 0316 059A 0062; # (a◌֢◌֚◌̖◌〪b; a◌〪◌֢◌̖◌֚b; a◌〪◌֢◌̖◌֚b; a◌〪◌֢◌̖◌֚b; a◌〪◌֢◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT ATNAH HAFUKH, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 05A3 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062;0061 302A 0316 05A3 059A 0062; # (a◌֚◌̖◌〪◌֣b; a◌〪◌̖◌֣◌֚b; a◌〪◌̖◌֣◌֚b; a◌〪◌̖◌֣◌֚b; a◌〪◌̖◌֣◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT MUNAH, LATIN SMALL LETTER B
+0061 05A3 059A 0316 302A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062;0061 302A 05A3 0316 059A 0062; # (a◌֣◌֚◌̖◌〪b; a◌〪◌֣◌̖◌֚b; a◌〪◌֣◌̖◌֚b; a◌〪◌֣◌̖◌֚b; a◌〪◌֣◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MUNAH, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 05A4 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062;0061 302A 0316 05A4 059A 0062; # (a◌֚◌̖◌〪◌֤b; a◌〪◌̖◌֤◌֚b; a◌〪◌̖◌֤◌֚b; a◌〪◌̖◌֤◌֚b; a◌〪◌̖◌֤◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT MAHAPAKH, LATIN SMALL LETTER B
+0061 05A4 059A 0316 302A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062;0061 302A 05A4 0316 059A 0062; # (a◌֤◌֚◌̖◌〪b; a◌〪◌֤◌̖◌֚b; a◌〪◌֤◌̖◌֚b; a◌〪◌֤◌̖◌֚b; a◌〪◌֤◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MAHAPAKH, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 05A5 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062;0061 302A 0316 05A5 059A 0062; # (a◌֚◌̖◌〪◌֥b; a◌〪◌̖◌֥◌֚b; a◌〪◌̖◌֥◌֚b; a◌〪◌̖◌֥◌֚b; a◌〪◌̖◌֥◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT MERKHA, LATIN SMALL LETTER B
+0061 05A5 059A 0316 302A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062;0061 302A 05A5 0316 059A 0062; # (a◌֥◌֚◌̖◌〪b; a◌〪◌֥◌̖◌֚b; a◌〪◌֥◌̖◌֚b; a◌〪◌֥◌̖◌֚b; a◌〪◌֥◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MERKHA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 05A6 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062;0061 302A 0316 05A6 059A 0062; # (a◌֚◌̖◌〪◌֦b; a◌〪◌̖◌֦◌֚b; a◌〪◌̖◌֦◌֚b; a◌〪◌̖◌֦◌֚b; a◌〪◌̖◌֦◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT MERKHA KEFULA, LATIN SMALL LETTER B
+0061 05A6 059A 0316 302A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062;0061 302A 05A6 0316 059A 0062; # (a◌֦◌֚◌̖◌〪b; a◌〪◌֦◌̖◌֚b; a◌〪◌֦◌̖◌֚b; a◌〪◌֦◌̖◌֚b; a◌〪◌֦◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT MERKHA KEFULA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 05A7 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062;0061 302A 0316 05A7 059A 0062; # (a◌֚◌̖◌〪◌֧b; a◌〪◌̖◌֧◌֚b; a◌〪◌̖◌֧◌֚b; a◌〪◌̖◌֧◌֚b; a◌〪◌̖◌֧◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT DARGA, LATIN SMALL LETTER B
+0061 05A7 059A 0316 302A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062;0061 302A 05A7 0316 059A 0062; # (a◌֧◌֚◌̖◌〪b; a◌〪◌֧◌̖◌֚b; a◌〪◌֧◌̖◌֚b; a◌〪◌֧◌̖◌֚b; a◌〪◌֧◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT DARGA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 05A8 0062;00E0 05AE 05A8 0315 0062;0061 05AE 0300 05A8 0315 0062;00E0 05AE 05A8 0315 0062;0061 05AE 0300 05A8 0315 0062; # (a◌̕◌̀◌֮◌֨b; à◌֮◌֨◌̕b; a◌֮◌̀◌֨◌̕b; à◌֮◌֨◌̕b; a◌֮◌̀◌֨◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT QADMA, LATIN SMALL LETTER B
+0061 05A8 0315 0300 05AE 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062;0061 05AE 05A8 0300 0315 0062; # (a◌֨◌̕◌̀◌֮b; a◌֮◌֨◌̀◌̕b; a◌֮◌֨◌̀◌̕b; a◌֮◌֨◌̀◌̕b; a◌֮◌֨◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT QADMA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 05A9 0062;00E0 05AE 05A9 0315 0062;0061 05AE 0300 05A9 0315 0062;00E0 05AE 05A9 0315 0062;0061 05AE 0300 05A9 0315 0062; # (a◌̕◌̀◌֮◌֩b; à◌֮◌֩◌̕b; a◌֮◌̀◌֩◌̕b; à◌֮◌֩◌̕b; a◌֮◌̀◌֩◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT TELISHA QETANA, LATIN SMALL LETTER B
+0061 05A9 0315 0300 05AE 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062;0061 05AE 05A9 0300 0315 0062; # (a◌֩◌̕◌̀◌֮b; a◌֮◌֩◌̀◌̕b; a◌֮◌֩◌̀◌̕b; a◌֮◌֩◌̀◌̕b; a◌֮◌֩◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT TELISHA QETANA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 05AA 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062;0061 302A 0316 05AA 059A 0062; # (a◌֚◌̖◌〪◌֪b; a◌〪◌̖◌֪◌֚b; a◌〪◌̖◌֪◌֚b; a◌〪◌̖◌֪◌֚b; a◌〪◌̖◌֪◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW ACCENT YERAH BEN YOMO, LATIN SMALL LETTER B
+0061 05AA 059A 0316 302A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062;0061 302A 05AA 0316 059A 0062; # (a◌֪◌֚◌̖◌〪b; a◌〪◌֪◌̖◌֚b; a◌〪◌֪◌̖◌֚b; a◌〪◌֪◌̖◌֚b; a◌〪◌֪◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YERAH BEN YOMO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 05AB 0062;00E0 05AE 05AB 0315 0062;0061 05AE 0300 05AB 0315 0062;00E0 05AE 05AB 0315 0062;0061 05AE 0300 05AB 0315 0062; # (a◌̕◌̀◌֮◌֫b; à◌֮◌֫◌̕b; a◌֮◌̀◌֫◌̕b; à◌֮◌֫◌̕b; a◌֮◌̀◌֫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT OLE, LATIN SMALL LETTER B
+0061 05AB 0315 0300 05AE 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062;0061 05AE 05AB 0300 0315 0062; # (a◌֫◌̕◌̀◌֮b; a◌֮◌֫◌̀◌̕b; a◌֮◌֫◌̀◌̕b; a◌֮◌֫◌̀◌̕b; a◌֮◌֫◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT OLE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 05AC 0062;00E0 05AE 05AC 0315 0062;0061 05AE 0300 05AC 0315 0062;00E0 05AE 05AC 0315 0062;0061 05AE 0300 05AC 0315 0062; # (a◌̕◌̀◌֮◌֬b; à◌֮◌֬◌̕b; a◌֮◌̀◌֬◌̕b; à◌֮◌֬◌̕b; a◌֮◌̀◌֬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW ACCENT ILUY, LATIN SMALL LETTER B
+0061 05AC 0315 0300 05AE 0062;0061 05AE 05AC 0300 0315 0062;0061 05AE 05AC 0300 0315 0062;0061 05AE 05AC 0300 0315 0062;0061 05AE 05AC 0300 0315 0062; # (a◌֬◌̕◌̀◌֮b; a◌֮◌֬◌̀◌̕b; a◌֮◌֬◌̀◌̕b; a◌֮◌֬◌̀◌̕b; a◌֮◌֬◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW ACCENT ILUY, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 302E 059A 0316 05AD 0062;0061 0316 059A 05AD 302E 0062;0061 0316 059A 05AD 302E 0062;0061 0316 059A 05AD 302E 0062;0061 0316 059A 05AD 302E 0062; # (a〮◌֚◌̖◌֭b; a◌̖◌֚◌֭〮b; a◌̖◌֚◌֭〮b; a◌̖◌֚◌֭〮b; a◌̖◌֚◌֭〮b; ) LATIN SMALL LETTER A, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, HEBREW ACCENT DEHI, LATIN SMALL LETTER B
+0061 05AD 302E 059A 0316 0062;0061 0316 05AD 059A 302E 0062;0061 0316 05AD 059A 302E 0062;0061 0316 05AD 059A 302E 0062;0061 0316 05AD 059A 302E 0062; # (a◌֭〮◌֚◌̖b; a◌̖◌֭◌֚〮b; a◌̖◌֭◌֚〮b; a◌̖◌֭◌֚〮b; a◌̖◌֭◌֚〮b; ) LATIN SMALL LETTER A, HEBREW ACCENT DEHI, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, LATIN SMALL LETTER B
+0061 0300 05AE 1D16D 05AE 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062; # (a◌̀◌𝅭֮◌֮b; à𝅭◌֮◌֮b; a𝅭◌֮◌֮◌̀b; à𝅭◌֮◌֮b; a𝅭◌֮◌֮◌̀b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 05AE 0300 05AE 1D16D 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062;00E0 1D16D 05AE 05AE 0062;0061 1D16D 05AE 05AE 0300 0062; # (a◌֮◌̀◌𝅭֮b; à𝅭◌֮◌֮b; a𝅭◌֮◌֮◌̀b; à𝅭◌֮◌֮b; a𝅭◌֮◌֮◌̀b; ) LATIN SMALL LETTER A, HEBREW ACCENT ZINOR, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, LATIN SMALL LETTER B
+0061 0315 0300 05AE 05AF 0062;00E0 05AE 05AF 0315 0062;0061 05AE 0300 05AF 0315 0062;00E0 05AE 05AF 0315 0062;0061 05AE 0300 05AF 0315 0062; # (a◌̕◌̀◌֮◌֯b; à◌֮◌֯◌̕b; a◌֮◌̀◌֯◌̕b; à◌֮◌֯◌̕b; a◌֮◌̀◌֯◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW MARK MASORA CIRCLE, LATIN SMALL LETTER B
+0061 05AF 0315 0300 05AE 0062;0061 05AE 05AF 0300 0315 0062;0061 05AE 05AF 0300 0315 0062;0061 05AE 05AF 0300 0315 0062;0061 05AE 05AF 0300 0315 0062; # (a◌֯◌̕◌̀◌֮b; a◌֮◌֯◌̀◌̕b; a◌֮◌֯◌̀◌̕b; a◌֮◌֯◌̀◌̕b; a◌֮◌֯◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW MARK MASORA CIRCLE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 05B1 05B0 094D 05B0 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062; # (a◌ֱ◌ְ◌्◌ְb; a◌्◌ְ◌ְ◌ֱb; a◌्◌ְ◌ְ◌ֱb; a◌्◌ְ◌ְ◌ֱb; a◌्◌ְ◌ְ◌ֱb; ) LATIN SMALL LETTER A, HEBREW POINT HATAF SEGOL, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, HEBREW POINT SHEVA, LATIN SMALL LETTER B
+0061 05B0 05B1 05B0 094D 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062;0061 094D 05B0 05B0 05B1 0062; # (a◌ְ◌ֱ◌ְ◌्b; a◌्◌ְ◌ְ◌ֱb; a◌्◌ְ◌ְ◌ֱb; a◌्◌ְ◌ְ◌ֱb; a◌्◌ְ◌ְ◌ֱb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, HEBREW POINT HATAF SEGOL, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, LATIN SMALL LETTER B
+0061 05B2 05B1 05B0 05B1 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062; # (a◌ֲ◌ֱ◌ְ◌ֱb; a◌ְ◌ֱ◌ֱ◌ֲb; a◌ְ◌ֱ◌ֱ◌ֲb; a◌ְ◌ֱ◌ֱ◌ֲb; a◌ְ◌ֱ◌ֱ◌ֲb; ) LATIN SMALL LETTER A, HEBREW POINT HATAF PATAH, HEBREW POINT HATAF SEGOL, HEBREW POINT SHEVA, HEBREW POINT HATAF SEGOL, LATIN SMALL LETTER B
+0061 05B1 05B2 05B1 05B0 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062;0061 05B0 05B1 05B1 05B2 0062; # (a◌ֱ◌ֲ◌ֱ◌ְb; a◌ְ◌ֱ◌ֱ◌ֲb; a◌ְ◌ֱ◌ֱ◌ֲb; a◌ְ◌ֱ◌ֱ◌ֲb; a◌ְ◌ֱ◌ֱ◌ֲb; ) LATIN SMALL LETTER A, HEBREW POINT HATAF SEGOL, HEBREW POINT HATAF PATAH, HEBREW POINT HATAF SEGOL, HEBREW POINT SHEVA, LATIN SMALL LETTER B
+0061 05B3 05B2 05B1 05B2 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062; # (a◌ֳ◌ֲ◌ֱ◌ֲb; a◌ֱ◌ֲ◌ֲ◌ֳb; a◌ֱ◌ֲ◌ֲ◌ֳb; a◌ֱ◌ֲ◌ֲ◌ֳb; a◌ֱ◌ֲ◌ֲ◌ֳb; ) LATIN SMALL LETTER A, HEBREW POINT HATAF QAMATS, HEBREW POINT HATAF PATAH, HEBREW POINT HATAF SEGOL, HEBREW POINT HATAF PATAH, LATIN SMALL LETTER B
+0061 05B2 05B3 05B2 05B1 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062;0061 05B1 05B2 05B2 05B3 0062; # (a◌ֲ◌ֳ◌ֲ◌ֱb; a◌ֱ◌ֲ◌ֲ◌ֳb; a◌ֱ◌ֲ◌ֲ◌ֳb; a◌ֱ◌ֲ◌ֲ◌ֳb; a◌ֱ◌ֲ◌ֲ◌ֳb; ) LATIN SMALL LETTER A, HEBREW POINT HATAF PATAH, HEBREW POINT HATAF QAMATS, HEBREW POINT HATAF PATAH, HEBREW POINT HATAF SEGOL, LATIN SMALL LETTER B
+0061 05B4 05B3 05B2 05B3 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062; # (a◌ִ◌ֳ◌ֲ◌ֳb; a◌ֲ◌ֳ◌ֳ◌ִb; a◌ֲ◌ֳ◌ֳ◌ִb; a◌ֲ◌ֳ◌ֳ◌ִb; a◌ֲ◌ֳ◌ֳ◌ִb; ) LATIN SMALL LETTER A, HEBREW POINT HIRIQ, HEBREW POINT HATAF QAMATS, HEBREW POINT HATAF PATAH, HEBREW POINT HATAF QAMATS, LATIN SMALL LETTER B
+0061 05B3 05B4 05B3 05B2 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062;0061 05B2 05B3 05B3 05B4 0062; # (a◌ֳ◌ִ◌ֳ◌ֲb; a◌ֲ◌ֳ◌ֳ◌ִb; a◌ֲ◌ֳ◌ֳ◌ִb; a◌ֲ◌ֳ◌ֳ◌ִb; a◌ֲ◌ֳ◌ֳ◌ִb; ) LATIN SMALL LETTER A, HEBREW POINT HATAF QAMATS, HEBREW POINT HIRIQ, HEBREW POINT HATAF QAMATS, HEBREW POINT HATAF PATAH, LATIN SMALL LETTER B
+0061 05B5 05B4 05B3 05B4 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062; # (a◌ֵ◌ִ◌ֳ◌ִb; a◌ֳ◌ִ◌ִ◌ֵb; a◌ֳ◌ִ◌ִ◌ֵb; a◌ֳ◌ִ◌ִ◌ֵb; a◌ֳ◌ִ◌ִ◌ֵb; ) LATIN SMALL LETTER A, HEBREW POINT TSERE, HEBREW POINT HIRIQ, HEBREW POINT HATAF QAMATS, HEBREW POINT HIRIQ, LATIN SMALL LETTER B
+0061 05B4 05B5 05B4 05B3 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062;0061 05B3 05B4 05B4 05B5 0062; # (a◌ִ◌ֵ◌ִ◌ֳb; a◌ֳ◌ִ◌ִ◌ֵb; a◌ֳ◌ִ◌ִ◌ֵb; a◌ֳ◌ִ◌ִ◌ֵb; a◌ֳ◌ִ◌ִ◌ֵb; ) LATIN SMALL LETTER A, HEBREW POINT HIRIQ, HEBREW POINT TSERE, HEBREW POINT HIRIQ, HEBREW POINT HATAF QAMATS, LATIN SMALL LETTER B
+0061 05B6 05B5 05B4 05B5 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062; # (a◌ֶ◌ֵ◌ִ◌ֵb; a◌ִ◌ֵ◌ֵ◌ֶb; a◌ִ◌ֵ◌ֵ◌ֶb; a◌ִ◌ֵ◌ֵ◌ֶb; a◌ִ◌ֵ◌ֵ◌ֶb; ) LATIN SMALL LETTER A, HEBREW POINT SEGOL, HEBREW POINT TSERE, HEBREW POINT HIRIQ, HEBREW POINT TSERE, LATIN SMALL LETTER B
+0061 05B5 05B6 05B5 05B4 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062;0061 05B4 05B5 05B5 05B6 0062; # (a◌ֵ◌ֶ◌ֵ◌ִb; a◌ִ◌ֵ◌ֵ◌ֶb; a◌ִ◌ֵ◌ֵ◌ֶb; a◌ִ◌ֵ◌ֵ◌ֶb; a◌ִ◌ֵ◌ֵ◌ֶb; ) LATIN SMALL LETTER A, HEBREW POINT TSERE, HEBREW POINT SEGOL, HEBREW POINT TSERE, HEBREW POINT HIRIQ, LATIN SMALL LETTER B
+0061 05B7 05B6 05B5 05B6 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062; # (a◌ַ◌ֶ◌ֵ◌ֶb; a◌ֵ◌ֶ◌ֶ◌ַb; a◌ֵ◌ֶ◌ֶ◌ַb; a◌ֵ◌ֶ◌ֶ◌ַb; a◌ֵ◌ֶ◌ֶ◌ַb; ) LATIN SMALL LETTER A, HEBREW POINT PATAH, HEBREW POINT SEGOL, HEBREW POINT TSERE, HEBREW POINT SEGOL, LATIN SMALL LETTER B
+0061 05B6 05B7 05B6 05B5 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062;0061 05B5 05B6 05B6 05B7 0062; # (a◌ֶ◌ַ◌ֶ◌ֵb; a◌ֵ◌ֶ◌ֶ◌ַb; a◌ֵ◌ֶ◌ֶ◌ַb; a◌ֵ◌ֶ◌ֶ◌ַb; a◌ֵ◌ֶ◌ֶ◌ַb; ) LATIN SMALL LETTER A, HEBREW POINT SEGOL, HEBREW POINT PATAH, HEBREW POINT SEGOL, HEBREW POINT TSERE, LATIN SMALL LETTER B
+0061 05B8 05B7 05B6 05B7 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062; # (a◌ָ◌ַ◌ֶ◌ַb; a◌ֶ◌ַ◌ַ◌ָb; a◌ֶ◌ַ◌ַ◌ָb; a◌ֶ◌ַ◌ַ◌ָb; a◌ֶ◌ַ◌ַ◌ָb; ) LATIN SMALL LETTER A, HEBREW POINT QAMATS, HEBREW POINT PATAH, HEBREW POINT SEGOL, HEBREW POINT PATAH, LATIN SMALL LETTER B
+0061 05B7 05B8 05B7 05B6 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062;0061 05B6 05B7 05B7 05B8 0062; # (a◌ַ◌ָ◌ַ◌ֶb; a◌ֶ◌ַ◌ַ◌ָb; a◌ֶ◌ַ◌ַ◌ָb; a◌ֶ◌ַ◌ַ◌ָb; a◌ֶ◌ַ◌ַ◌ָb; ) LATIN SMALL LETTER A, HEBREW POINT PATAH, HEBREW POINT QAMATS, HEBREW POINT PATAH, HEBREW POINT SEGOL, LATIN SMALL LETTER B
+0061 05B9 05B8 05B7 05B8 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062; # (a◌ֹ◌ָ◌ַ◌ָb; a◌ַ◌ָ◌ָ◌ֹb; a◌ַ◌ָ◌ָ◌ֹb; a◌ַ◌ָ◌ָ◌ֹb; a◌ַ◌ָ◌ָ◌ֹb; ) LATIN SMALL LETTER A, HEBREW POINT HOLAM, HEBREW POINT QAMATS, HEBREW POINT PATAH, HEBREW POINT QAMATS, LATIN SMALL LETTER B
+0061 05B8 05B9 05B8 05B7 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062;0061 05B7 05B8 05B8 05B9 0062; # (a◌ָ◌ֹ◌ָ◌ַb; a◌ַ◌ָ◌ָ◌ֹb; a◌ַ◌ָ◌ָ◌ֹb; a◌ַ◌ָ◌ָ◌ֹb; a◌ַ◌ָ◌ָ◌ֹb; ) LATIN SMALL LETTER A, HEBREW POINT QAMATS, HEBREW POINT HOLAM, HEBREW POINT QAMATS, HEBREW POINT PATAH, LATIN SMALL LETTER B
+0061 05BB 05B9 05B8 05B9 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062; # (a◌ֻ◌ֹ◌ָ◌ֹb; a◌ָ◌ֹ◌ֹ◌ֻb; a◌ָ◌ֹ◌ֹ◌ֻb; a◌ָ◌ֹ◌ֹ◌ֻb; a◌ָ◌ֹ◌ֹ◌ֻb; ) LATIN SMALL LETTER A, HEBREW POINT QUBUTS, HEBREW POINT HOLAM, HEBREW POINT QAMATS, HEBREW POINT HOLAM, LATIN SMALL LETTER B
+0061 05B9 05BB 05B9 05B8 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062;0061 05B8 05B9 05B9 05BB 0062; # (a◌ֹ◌ֻ◌ֹ◌ָb; a◌ָ◌ֹ◌ֹ◌ֻb; a◌ָ◌ֹ◌ֹ◌ֻb; a◌ָ◌ֹ◌ֹ◌ֻb; a◌ָ◌ֹ◌ֹ◌ֻb; ) LATIN SMALL LETTER A, HEBREW POINT HOLAM, HEBREW POINT QUBUTS, HEBREW POINT HOLAM, HEBREW POINT QAMATS, LATIN SMALL LETTER B
+0061 05BB 05B9 05B8 05BA 0062;0061 05B8 05B9 05BA 05BB 0062;0061 05B8 05B9 05BA 05BB 0062;0061 05B8 05B9 05BA 05BB 0062;0061 05B8 05B9 05BA 05BB 0062; # (a◌ֻ◌ֹ◌ָ◌ֺb; a◌ָ◌ֹ◌ֺ◌ֻb; a◌ָ◌ֹ◌ֺ◌ֻb; a◌ָ◌ֹ◌ֺ◌ֻb; a◌ָ◌ֹ◌ֺ◌ֻb; ) LATIN SMALL LETTER A, HEBREW POINT QUBUTS, HEBREW POINT HOLAM, HEBREW POINT QAMATS, HEBREW POINT HOLAM HASER FOR VAV, LATIN SMALL LETTER B
+0061 05BA 05BB 05B9 05B8 0062;0061 05B8 05BA 05B9 05BB 0062;0061 05B8 05BA 05B9 05BB 0062;0061 05B8 05BA 05B9 05BB 0062;0061 05B8 05BA 05B9 05BB 0062; # (a◌ֺ◌ֻ◌ֹ◌ָb; a◌ָ◌ֺ◌ֹ◌ֻb; a◌ָ◌ֺ◌ֹ◌ֻb; a◌ָ◌ֺ◌ֹ◌ֻb; a◌ָ◌ֺ◌ֹ◌ֻb; ) LATIN SMALL LETTER A, HEBREW POINT HOLAM HASER FOR VAV, HEBREW POINT QUBUTS, HEBREW POINT HOLAM, HEBREW POINT QAMATS, LATIN SMALL LETTER B
+0061 05BC 05BB 05B9 05BB 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062; # (a◌ּ◌ֻ◌ֹ◌ֻb; a◌ֹ◌ֻ◌ֻ◌ּb; a◌ֹ◌ֻ◌ֻ◌ּb; a◌ֹ◌ֻ◌ֻ◌ּb; a◌ֹ◌ֻ◌ֻ◌ּb; ) LATIN SMALL LETTER A, HEBREW POINT DAGESH OR MAPIQ, HEBREW POINT QUBUTS, HEBREW POINT HOLAM, HEBREW POINT QUBUTS, LATIN SMALL LETTER B
+0061 05BB 05BC 05BB 05B9 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062;0061 05B9 05BB 05BB 05BC 0062; # (a◌ֻ◌ּ◌ֻ◌ֹb; a◌ֹ◌ֻ◌ֻ◌ּb; a◌ֹ◌ֻ◌ֻ◌ּb; a◌ֹ◌ֻ◌ֻ◌ּb; a◌ֹ◌ֻ◌ֻ◌ּb; ) LATIN SMALL LETTER A, HEBREW POINT QUBUTS, HEBREW POINT DAGESH OR MAPIQ, HEBREW POINT QUBUTS, HEBREW POINT HOLAM, LATIN SMALL LETTER B
+0061 05BD 05BC 05BB 05BC 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062; # (a◌ֽ◌ּ◌ֻ◌ּb; a◌ֻ◌ּ◌ּ◌ֽb; a◌ֻ◌ּ◌ּ◌ֽb; a◌ֻ◌ּ◌ּ◌ֽb; a◌ֻ◌ּ◌ּ◌ֽb; ) LATIN SMALL LETTER A, HEBREW POINT METEG, HEBREW POINT DAGESH OR MAPIQ, HEBREW POINT QUBUTS, HEBREW POINT DAGESH OR MAPIQ, LATIN SMALL LETTER B
+0061 05BC 05BD 05BC 05BB 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062;0061 05BB 05BC 05BC 05BD 0062; # (a◌ּ◌ֽ◌ּ◌ֻb; a◌ֻ◌ּ◌ּ◌ֽb; a◌ֻ◌ּ◌ּ◌ֽb; a◌ֻ◌ּ◌ּ◌ֽb; a◌ֻ◌ּ◌ּ◌ֽb; ) LATIN SMALL LETTER A, HEBREW POINT DAGESH OR MAPIQ, HEBREW POINT METEG, HEBREW POINT DAGESH OR MAPIQ, HEBREW POINT QUBUTS, LATIN SMALL LETTER B
+0061 05BF 05BD 05BC 05BD 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062; # (a◌ֿ◌ֽ◌ּ◌ֽb; a◌ּ◌ֽ◌ֽ◌ֿb; a◌ּ◌ֽ◌ֽ◌ֿb; a◌ּ◌ֽ◌ֽ◌ֿb; a◌ּ◌ֽ◌ֽ◌ֿb; ) LATIN SMALL LETTER A, HEBREW POINT RAFE, HEBREW POINT METEG, HEBREW POINT DAGESH OR MAPIQ, HEBREW POINT METEG, LATIN SMALL LETTER B
+0061 05BD 05BF 05BD 05BC 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062;0061 05BC 05BD 05BD 05BF 0062; # (a◌ֽ◌ֿ◌ֽ◌ּb; a◌ּ◌ֽ◌ֽ◌ֿb; a◌ּ◌ֽ◌ֽ◌ֿb; a◌ּ◌ֽ◌ֽ◌ֿb; a◌ּ◌ֽ◌ֽ◌ֿb; ) LATIN SMALL LETTER A, HEBREW POINT METEG, HEBREW POINT RAFE, HEBREW POINT METEG, HEBREW POINT DAGESH OR MAPIQ, LATIN SMALL LETTER B
+0061 05C1 05BF 05BD 05BF 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062; # (a◌ׁ◌ֿ◌ֽ◌ֿb; a◌ֽ◌ֿ◌ֿ◌ׁb; a◌ֽ◌ֿ◌ֿ◌ׁb; a◌ֽ◌ֿ◌ֿ◌ׁb; a◌ֽ◌ֿ◌ֿ◌ׁb; ) LATIN SMALL LETTER A, HEBREW POINT SHIN DOT, HEBREW POINT RAFE, HEBREW POINT METEG, HEBREW POINT RAFE, LATIN SMALL LETTER B
+0061 05BF 05C1 05BF 05BD 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062;0061 05BD 05BF 05BF 05C1 0062; # (a◌ֿ◌ׁ◌ֿ◌ֽb; a◌ֽ◌ֿ◌ֿ◌ׁb; a◌ֽ◌ֿ◌ֿ◌ׁb; a◌ֽ◌ֿ◌ֿ◌ׁb; a◌ֽ◌ֿ◌ֿ◌ׁb; ) LATIN SMALL LETTER A, HEBREW POINT RAFE, HEBREW POINT SHIN DOT, HEBREW POINT RAFE, HEBREW POINT METEG, LATIN SMALL LETTER B
+0061 05C2 05C1 05BF 05C1 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062; # (a◌ׂ◌ׁ◌ֿ◌ׁb; a◌ֿ◌ׁ◌ׁ◌ׂb; a◌ֿ◌ׁ◌ׁ◌ׂb; a◌ֿ◌ׁ◌ׁ◌ׂb; a◌ֿ◌ׁ◌ׁ◌ׂb; ) LATIN SMALL LETTER A, HEBREW POINT SIN DOT, HEBREW POINT SHIN DOT, HEBREW POINT RAFE, HEBREW POINT SHIN DOT, LATIN SMALL LETTER B
+0061 05C1 05C2 05C1 05BF 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062;0061 05BF 05C1 05C1 05C2 0062; # (a◌ׁ◌ׂ◌ׁ◌ֿb; a◌ֿ◌ׁ◌ׁ◌ׂb; a◌ֿ◌ׁ◌ׁ◌ׂb; a◌ֿ◌ׁ◌ׁ◌ׂb; a◌ֿ◌ׁ◌ׁ◌ׂb; ) LATIN SMALL LETTER A, HEBREW POINT SHIN DOT, HEBREW POINT SIN DOT, HEBREW POINT SHIN DOT, HEBREW POINT RAFE, LATIN SMALL LETTER B
+0061 FB1E 05C2 05C1 05C2 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062; # (a◌ﬞ◌ׂ◌ׁ◌ׂb; a◌ׁ◌ׂ◌ׂ◌ﬞb; a◌ׁ◌ׂ◌ׂ◌ﬞb; a◌ׁ◌ׂ◌ׂ◌ﬞb; a◌ׁ◌ׂ◌ׂ◌ﬞb; ) LATIN SMALL LETTER A, HEBREW POINT JUDEO-SPANISH VARIKA, HEBREW POINT SIN DOT, HEBREW POINT SHIN DOT, HEBREW POINT SIN DOT, LATIN SMALL LETTER B
+0061 05C2 FB1E 05C2 05C1 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062;0061 05C1 05C2 05C2 FB1E 0062; # (a◌ׂ◌ﬞ◌ׂ◌ׁb; a◌ׁ◌ׂ◌ׂ◌ﬞb; a◌ׁ◌ׂ◌ׂ◌ﬞb; a◌ׁ◌ׂ◌ׂ◌ﬞb; a◌ׁ◌ׂ◌ׂ◌ﬞb; ) LATIN SMALL LETTER A, HEBREW POINT SIN DOT, HEBREW POINT JUDEO-SPANISH VARIKA, HEBREW POINT SIN DOT, HEBREW POINT SHIN DOT, LATIN SMALL LETTER B
+0061 0315 0300 05AE 05C4 0062;00E0 05AE 05C4 0315 0062;0061 05AE 0300 05C4 0315 0062;00E0 05AE 05C4 0315 0062;0061 05AE 0300 05C4 0315 0062; # (a◌̕◌̀◌֮◌ׄb; à◌֮◌ׄ◌̕b; a◌֮◌̀◌ׄ◌̕b; à◌֮◌ׄ◌̕b; a◌֮◌̀◌ׄ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HEBREW MARK UPPER DOT, LATIN SMALL LETTER B
+0061 05C4 0315 0300 05AE 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062;0061 05AE 05C4 0300 0315 0062; # (a◌ׄ◌̕◌̀◌֮b; a◌֮◌ׄ◌̀◌̕b; a◌֮◌ׄ◌̀◌̕b; a◌֮◌ׄ◌̀◌̕b; a◌֮◌ׄ◌̀◌̕b; ) LATIN SMALL LETTER A, HEBREW MARK UPPER DOT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 05C5 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062;0061 302A 0316 05C5 059A 0062; # (a◌֚◌̖◌〪◌ׅb; a◌〪◌̖◌ׅ◌֚b; a◌〪◌̖◌ׅ◌֚b; a◌〪◌̖◌ׅ◌֚b; a◌〪◌̖◌ׅ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, HEBREW MARK LOWER DOT, LATIN SMALL LETTER B
+0061 05C5 059A 0316 302A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062;0061 302A 05C5 0316 059A 0062; # (a◌ׅ◌֚◌̖◌〪b; a◌〪◌ׅ◌̖◌֚b; a◌〪◌ׅ◌̖◌֚b; a◌〪◌ׅ◌̖◌֚b; a◌〪◌ׅ◌̖◌֚b; ) LATIN SMALL LETTER A, HEBREW MARK LOWER DOT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 05B9 05B8 05B7 05C7 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062;0061 05B7 05B8 05C7 05B9 0062; # (a◌ֹ◌ָ◌ַ◌ׇb; a◌ַ◌ָ◌ׇ◌ֹb; a◌ַ◌ָ◌ׇ◌ֹb; a◌ַ◌ָ◌ׇ◌ֹb; a◌ַ◌ָ◌ׇ◌ֹb; ) LATIN SMALL LETTER A, HEBREW POINT HOLAM, HEBREW POINT QAMATS, HEBREW POINT PATAH, HEBREW POINT QAMATS QATAN, LATIN SMALL LETTER B
+0061 05C7 05B9 05B8 05B7 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062;0061 05B7 05C7 05B8 05B9 0062; # (a◌ׇ◌ֹ◌ָ◌ַb; a◌ַ◌ׇ◌ָ◌ֹb; a◌ַ◌ׇ◌ָ◌ֹb; a◌ַ◌ׇ◌ָ◌ֹb; a◌ַ◌ׇ◌ָ◌ֹb; ) LATIN SMALL LETTER A, HEBREW POINT QAMATS QATAN, HEBREW POINT HOLAM, HEBREW POINT QAMATS, HEBREW POINT PATAH, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0610 0062;00E0 05AE 0610 0315 0062;0061 05AE 0300 0610 0315 0062;00E0 05AE 0610 0315 0062;0061 05AE 0300 0610 0315 0062; # (a◌̕◌̀◌֮◌ؐb; à◌֮◌ؐ◌̕b; a◌֮◌̀◌ؐ◌̕b; à◌֮◌ؐ◌̕b; a◌֮◌̀◌ؐ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM, LATIN SMALL LETTER B
+0061 0610 0315 0300 05AE 0062;0061 05AE 0610 0300 0315 0062;0061 05AE 0610 0300 0315 0062;0061 05AE 0610 0300 0315 0062;0061 05AE 0610 0300 0315 0062; # (a◌ؐ◌̕◌̀◌֮b; a◌֮◌ؐ◌̀◌̕b; a◌֮◌ؐ◌̀◌̕b; a◌֮◌ؐ◌̀◌̕b; a◌֮◌ؐ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0611 0062;00E0 05AE 0611 0315 0062;0061 05AE 0300 0611 0315 0062;00E0 05AE 0611 0315 0062;0061 05AE 0300 0611 0315 0062; # (a◌̕◌̀◌֮◌ؑb; à◌֮◌ؑ◌̕b; a◌֮◌̀◌ؑ◌̕b; à◌֮◌ؑ◌̕b; a◌֮◌̀◌ؑ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SIGN ALAYHE ASSALLAM, LATIN SMALL LETTER B
+0061 0611 0315 0300 05AE 0062;0061 05AE 0611 0300 0315 0062;0061 05AE 0611 0300 0315 0062;0061 05AE 0611 0300 0315 0062;0061 05AE 0611 0300 0315 0062; # (a◌ؑ◌̕◌̀◌֮b; a◌֮◌ؑ◌̀◌̕b; a◌֮◌ؑ◌̀◌̕b; a◌֮◌ؑ◌̀◌̕b; a◌֮◌ؑ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SIGN ALAYHE ASSALLAM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0612 0062;00E0 05AE 0612 0315 0062;0061 05AE 0300 0612 0315 0062;00E0 05AE 0612 0315 0062;0061 05AE 0300 0612 0315 0062; # (a◌̕◌̀◌֮◌ؒb; à◌֮◌ؒ◌̕b; a◌֮◌̀◌ؒ◌̕b; à◌֮◌ؒ◌̕b; a◌֮◌̀◌ؒ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SIGN RAHMATULLAH ALAYHE, LATIN SMALL LETTER B
+0061 0612 0315 0300 05AE 0062;0061 05AE 0612 0300 0315 0062;0061 05AE 0612 0300 0315 0062;0061 05AE 0612 0300 0315 0062;0061 05AE 0612 0300 0315 0062; # (a◌ؒ◌̕◌̀◌֮b; a◌֮◌ؒ◌̀◌̕b; a◌֮◌ؒ◌̀◌̕b; a◌֮◌ؒ◌̀◌̕b; a◌֮◌ؒ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SIGN RAHMATULLAH ALAYHE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0613 0062;00E0 05AE 0613 0315 0062;0061 05AE 0300 0613 0315 0062;00E0 05AE 0613 0315 0062;0061 05AE 0300 0613 0315 0062; # (a◌̕◌̀◌֮◌ؓb; à◌֮◌ؓ◌̕b; a◌֮◌̀◌ؓ◌̕b; à◌֮◌ؓ◌̕b; a◌֮◌̀◌ؓ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SIGN RADI ALLAHOU ANHU, LATIN SMALL LETTER B
+0061 0613 0315 0300 05AE 0062;0061 05AE 0613 0300 0315 0062;0061 05AE 0613 0300 0315 0062;0061 05AE 0613 0300 0315 0062;0061 05AE 0613 0300 0315 0062; # (a◌ؓ◌̕◌̀◌֮b; a◌֮◌ؓ◌̀◌̕b; a◌֮◌ؓ◌̀◌̕b; a◌֮◌ؓ◌̀◌̕b; a◌֮◌ؓ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SIGN RADI ALLAHOU ANHU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0614 0062;00E0 05AE 0614 0315 0062;0061 05AE 0300 0614 0315 0062;00E0 05AE 0614 0315 0062;0061 05AE 0300 0614 0315 0062; # (a◌̕◌̀◌֮◌ؔb; à◌֮◌ؔ◌̕b; a◌֮◌̀◌ؔ◌̕b; à◌֮◌ؔ◌̕b; a◌֮◌̀◌ؔ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SIGN TAKHALLUS, LATIN SMALL LETTER B
+0061 0614 0315 0300 05AE 0062;0061 05AE 0614 0300 0315 0062;0061 05AE 0614 0300 0315 0062;0061 05AE 0614 0300 0315 0062;0061 05AE 0614 0300 0315 0062; # (a◌ؔ◌̕◌̀◌֮b; a◌֮◌ؔ◌̀◌̕b; a◌֮◌ؔ◌̀◌̕b; a◌֮◌ؔ◌̀◌̕b; a◌֮◌ؔ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SIGN TAKHALLUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0615 0062;00E0 05AE 0615 0315 0062;0061 05AE 0300 0615 0315 0062;00E0 05AE 0615 0315 0062;0061 05AE 0300 0615 0315 0062; # (a◌̕◌̀◌֮◌ؕb; à◌֮◌ؕ◌̕b; a◌֮◌̀◌ؕ◌̕b; à◌֮◌ؕ◌̕b; a◌֮◌̀◌ؕ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH TAH, LATIN SMALL LETTER B
+0061 0615 0315 0300 05AE 0062;0061 05AE 0615 0300 0315 0062;0061 05AE 0615 0300 0315 0062;0061 05AE 0615 0300 0315 0062;0061 05AE 0615 0300 0315 0062; # (a◌ؕ◌̕◌̀◌֮b; a◌֮◌ؕ◌̀◌̕b; a◌֮◌ؕ◌̀◌̕b; a◌֮◌ؕ◌̀◌̕b; a◌֮◌ؕ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH TAH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0616 0062;00E0 05AE 0616 0315 0062;0061 05AE 0300 0616 0315 0062;00E0 05AE 0616 0315 0062;0061 05AE 0300 0616 0315 0062; # (a◌̕◌̀◌֮◌ؖb; à◌֮◌ؖ◌̕b; a◌֮◌̀◌ؖ◌̕b; à◌֮◌ؖ◌̕b; a◌֮◌̀◌ؖ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH, LATIN SMALL LETTER B
+0061 0616 0315 0300 05AE 0062;0061 05AE 0616 0300 0315 0062;0061 05AE 0616 0300 0315 0062;0061 05AE 0616 0300 0315 0062;0061 05AE 0616 0300 0315 0062; # (a◌ؖ◌̕◌̀◌֮b; a◌֮◌ؖ◌̀◌̕b; a◌֮◌ؖ◌̀◌̕b; a◌֮◌ؖ◌̀◌̕b; a◌֮◌ؖ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0617 0062;00E0 05AE 0617 0315 0062;0061 05AE 0300 0617 0315 0062;00E0 05AE 0617 0315 0062;0061 05AE 0300 0617 0315 0062; # (a◌̕◌̀◌֮◌ؗb; à◌֮◌ؗ◌̕b; a◌֮◌̀◌ؗ◌̕b; à◌֮◌ؗ◌̕b; a◌֮◌̀◌ؗ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH ZAIN, LATIN SMALL LETTER B
+0061 0617 0315 0300 05AE 0062;0061 05AE 0617 0300 0315 0062;0061 05AE 0617 0300 0315 0062;0061 05AE 0617 0300 0315 0062;0061 05AE 0617 0300 0315 0062; # (a◌ؗ◌̕◌̀◌֮b; a◌֮◌ؗ◌̀◌̕b; a◌֮◌ؗ◌̀◌̕b; a◌֮◌ؗ◌̀◌̕b; a◌֮◌ؗ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH ZAIN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0619 0618 064D 0618 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062; # (a◌ؙ◌ؘ◌ٍ◌ؘb; a◌ٍ◌ؘ◌ؘ◌ؙb; a◌ٍ◌ؘ◌ؘ◌ؙb; a◌ٍ◌ؘ◌ؘ◌ؙb; a◌ٍ◌ؘ◌ؘ◌ؙb; ) LATIN SMALL LETTER A, ARABIC SMALL DAMMA, ARABIC SMALL FATHA, ARABIC KASRATAN, ARABIC SMALL FATHA, LATIN SMALL LETTER B
+0061 0618 0619 0618 064D 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062;0061 064D 0618 0618 0619 0062; # (a◌ؘ◌ؙ◌ؘ◌ٍb; a◌ٍ◌ؘ◌ؘ◌ؙb; a◌ٍ◌ؘ◌ؘ◌ؙb; a◌ٍ◌ؘ◌ؘ◌ؙb; a◌ٍ◌ؘ◌ؘ◌ؙb; ) LATIN SMALL LETTER A, ARABIC SMALL FATHA, ARABIC SMALL DAMMA, ARABIC SMALL FATHA, ARABIC KASRATAN, LATIN SMALL LETTER B
+0061 061A 0619 0618 0619 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062; # (a◌ؚ◌ؙ◌ؘ◌ؙb; a◌ؘ◌ؙ◌ؙ◌ؚb; a◌ؘ◌ؙ◌ؙ◌ؚb; a◌ؘ◌ؙ◌ؙ◌ؚb; a◌ؘ◌ؙ◌ؙ◌ؚb; ) LATIN SMALL LETTER A, ARABIC SMALL KASRA, ARABIC SMALL DAMMA, ARABIC SMALL FATHA, ARABIC SMALL DAMMA, LATIN SMALL LETTER B
+0061 0619 061A 0619 0618 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062;0061 0618 0619 0619 061A 0062; # (a◌ؙ◌ؚ◌ؙ◌ؘb; a◌ؘ◌ؙ◌ؙ◌ؚb; a◌ؘ◌ؙ◌ؙ◌ؚb; a◌ؘ◌ؙ◌ؙ◌ؚb; a◌ؘ◌ؙ◌ؙ◌ؚb; ) LATIN SMALL LETTER A, ARABIC SMALL DAMMA, ARABIC SMALL KASRA, ARABIC SMALL DAMMA, ARABIC SMALL FATHA, LATIN SMALL LETTER B
+0061 0651 061A 0619 061A 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062; # (a◌ّ◌ؚ◌ؙ◌ؚb; a◌ؙ◌ؚ◌ؚ◌ّb; a◌ؙ◌ؚ◌ؚ◌ّb; a◌ؙ◌ؚ◌ؚ◌ّb; a◌ؙ◌ؚ◌ؚ◌ّb; ) LATIN SMALL LETTER A, ARABIC SHADDA, ARABIC SMALL KASRA, ARABIC SMALL DAMMA, ARABIC SMALL KASRA, LATIN SMALL LETTER B
+0061 061A 0651 061A 0619 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062;0061 0619 061A 061A 0651 0062; # (a◌ؚ◌ّ◌ؚ◌ؙb; a◌ؙ◌ؚ◌ؚ◌ّb; a◌ؙ◌ؚ◌ؚ◌ّb; a◌ؙ◌ؚ◌ؚ◌ّb; a◌ؙ◌ؚ◌ؚ◌ّb; ) LATIN SMALL LETTER A, ARABIC SMALL KASRA, ARABIC SHADDA, ARABIC SMALL KASRA, ARABIC SMALL DAMMA, LATIN SMALL LETTER B
+0061 064C 064B FB1E 064B 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062; # (a◌ٌ◌ً◌ﬞ◌ًb; a◌ﬞ◌ً◌ً◌ٌb; a◌ﬞ◌ً◌ً◌ٌb; a◌ﬞ◌ً◌ً◌ٌb; a◌ﬞ◌ً◌ً◌ٌb; ) LATIN SMALL LETTER A, ARABIC DAMMATAN, ARABIC FATHATAN, HEBREW POINT JUDEO-SPANISH VARIKA, ARABIC FATHATAN, LATIN SMALL LETTER B
+0061 064B 064C 064B FB1E 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062;0061 FB1E 064B 064B 064C 0062; # (a◌ً◌ٌ◌ً◌ﬞb; a◌ﬞ◌ً◌ً◌ٌb; a◌ﬞ◌ً◌ً◌ٌb; a◌ﬞ◌ً◌ً◌ٌb; a◌ﬞ◌ً◌ً◌ٌb; ) LATIN SMALL LETTER A, ARABIC FATHATAN, ARABIC DAMMATAN, ARABIC FATHATAN, HEBREW POINT JUDEO-SPANISH VARIKA, LATIN SMALL LETTER B
+0061 064D 064C 064B 064C 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062; # (a◌ٍ◌ٌ◌ً◌ٌb; a◌ً◌ٌ◌ٌ◌ٍb; a◌ً◌ٌ◌ٌ◌ٍb; a◌ً◌ٌ◌ٌ◌ٍb; a◌ً◌ٌ◌ٌ◌ٍb; ) LATIN SMALL LETTER A, ARABIC KASRATAN, ARABIC DAMMATAN, ARABIC FATHATAN, ARABIC DAMMATAN, LATIN SMALL LETTER B
+0061 064C 064D 064C 064B 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062;0061 064B 064C 064C 064D 0062; # (a◌ٌ◌ٍ◌ٌ◌ًb; a◌ً◌ٌ◌ٌ◌ٍb; a◌ً◌ٌ◌ٌ◌ٍb; a◌ً◌ٌ◌ٌ◌ٍb; a◌ً◌ٌ◌ٌ◌ٍb; ) LATIN SMALL LETTER A, ARABIC DAMMATAN, ARABIC KASRATAN, ARABIC DAMMATAN, ARABIC FATHATAN, LATIN SMALL LETTER B
+0061 0618 064D 064C 064D 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062; # (a◌ؘ◌ٍ◌ٌ◌ٍb; a◌ٌ◌ٍ◌ٍ◌ؘb; a◌ٌ◌ٍ◌ٍ◌ؘb; a◌ٌ◌ٍ◌ٍ◌ؘb; a◌ٌ◌ٍ◌ٍ◌ؘb; ) LATIN SMALL LETTER A, ARABIC SMALL FATHA, ARABIC KASRATAN, ARABIC DAMMATAN, ARABIC KASRATAN, LATIN SMALL LETTER B
+0061 064D 0618 064D 064C 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062;0061 064C 064D 064D 0618 0062; # (a◌ٍ◌ؘ◌ٍ◌ٌb; a◌ٌ◌ٍ◌ٍ◌ؘb; a◌ٌ◌ٍ◌ٍ◌ؘb; a◌ٌ◌ٍ◌ٍ◌ؘb; a◌ٌ◌ٍ◌ٍ◌ؘb; ) LATIN SMALL LETTER A, ARABIC KASRATAN, ARABIC SMALL FATHA, ARABIC KASRATAN, ARABIC DAMMATAN, LATIN SMALL LETTER B
+0061 0619 0618 064D 064E 0062;0061 064D 0618 064E 0619 0062;0061 064D 0618 064E 0619 0062;0061 064D 0618 064E 0619 0062;0061 064D 0618 064E 0619 0062; # (a◌ؙ◌ؘ◌ٍ◌َb; a◌ٍ◌ؘ◌َ◌ؙb; a◌ٍ◌ؘ◌َ◌ؙb; a◌ٍ◌ؘ◌َ◌ؙb; a◌ٍ◌ؘ◌َ◌ؙb; ) LATIN SMALL LETTER A, ARABIC SMALL DAMMA, ARABIC SMALL FATHA, ARABIC KASRATAN, ARABIC FATHA, LATIN SMALL LETTER B
+0061 064E 0619 0618 064D 0062;0061 064D 064E 0618 0619 0062;0061 064D 064E 0618 0619 0062;0061 064D 064E 0618 0619 0062;0061 064D 064E 0618 0619 0062; # (a◌َ◌ؙ◌ؘ◌ٍb; a◌ٍ◌َ◌ؘ◌ؙb; a◌ٍ◌َ◌ؘ◌ؙb; a◌ٍ◌َ◌ؘ◌ؙb; a◌ٍ◌َ◌ؘ◌ؙb; ) LATIN SMALL LETTER A, ARABIC FATHA, ARABIC SMALL DAMMA, ARABIC SMALL FATHA, ARABIC KASRATAN, LATIN SMALL LETTER B
+0061 061A 0619 0618 064F 0062;0061 0618 0619 064F 061A 0062;0061 0618 0619 064F 061A 0062;0061 0618 0619 064F 061A 0062;0061 0618 0619 064F 061A 0062; # (a◌ؚ◌ؙ◌ؘ◌ُb; a◌ؘ◌ؙ◌ُ◌ؚb; a◌ؘ◌ؙ◌ُ◌ؚb; a◌ؘ◌ؙ◌ُ◌ؚb; a◌ؘ◌ؙ◌ُ◌ؚb; ) LATIN SMALL LETTER A, ARABIC SMALL KASRA, ARABIC SMALL DAMMA, ARABIC SMALL FATHA, ARABIC DAMMA, LATIN SMALL LETTER B
+0061 064F 061A 0619 0618 0062;0061 0618 064F 0619 061A 0062;0061 0618 064F 0619 061A 0062;0061 0618 064F 0619 061A 0062;0061 0618 064F 0619 061A 0062; # (a◌ُ◌ؚ◌ؙ◌ؘb; a◌ؘ◌ُ◌ؙ◌ؚb; a◌ؘ◌ُ◌ؙ◌ؚb; a◌ؘ◌ُ◌ؙ◌ؚb; a◌ؘ◌ُ◌ؙ◌ؚb; ) LATIN SMALL LETTER A, ARABIC DAMMA, ARABIC SMALL KASRA, ARABIC SMALL DAMMA, ARABIC SMALL FATHA, LATIN SMALL LETTER B
+0061 0651 061A 0619 0650 0062;0061 0619 061A 0650 0651 0062;0061 0619 061A 0650 0651 0062;0061 0619 061A 0650 0651 0062;0061 0619 061A 0650 0651 0062; # (a◌ّ◌ؚ◌ؙ◌ِb; a◌ؙ◌ؚ◌ِ◌ّb; a◌ؙ◌ؚ◌ِ◌ّb; a◌ؙ◌ؚ◌ِ◌ّb; a◌ؙ◌ؚ◌ِ◌ّb; ) LATIN SMALL LETTER A, ARABIC SHADDA, ARABIC SMALL KASRA, ARABIC SMALL DAMMA, ARABIC KASRA, LATIN SMALL LETTER B
+0061 0650 0651 061A 0619 0062;0061 0619 0650 061A 0651 0062;0061 0619 0650 061A 0651 0062;0061 0619 0650 061A 0651 0062;0061 0619 0650 061A 0651 0062; # (a◌ِ◌ّ◌ؚ◌ؙb; a◌ؙ◌ِ◌ؚ◌ّb; a◌ؙ◌ِ◌ؚ◌ّb; a◌ؙ◌ِ◌ؚ◌ّb; a◌ؙ◌ِ◌ؚ◌ّb; ) LATIN SMALL LETTER A, ARABIC KASRA, ARABIC SHADDA, ARABIC SMALL KASRA, ARABIC SMALL DAMMA, LATIN SMALL LETTER B
+0061 0652 0651 061A 0651 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062; # (a◌ْ◌ّ◌ؚ◌ّb; a◌ؚ◌ّ◌ّ◌ْb; a◌ؚ◌ّ◌ّ◌ْb; a◌ؚ◌ّ◌ّ◌ْb; a◌ؚ◌ّ◌ّ◌ْb; ) LATIN SMALL LETTER A, ARABIC SUKUN, ARABIC SHADDA, ARABIC SMALL KASRA, ARABIC SHADDA, LATIN SMALL LETTER B
+0061 0651 0652 0651 061A 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062;0061 061A 0651 0651 0652 0062; # (a◌ّ◌ْ◌ّ◌ؚb; a◌ؚ◌ّ◌ّ◌ْb; a◌ؚ◌ّ◌ّ◌ْb; a◌ؚ◌ّ◌ّ◌ْb; a◌ؚ◌ّ◌ّ◌ْb; ) LATIN SMALL LETTER A, ARABIC SHADDA, ARABIC SUKUN, ARABIC SHADDA, ARABIC SMALL KASRA, LATIN SMALL LETTER B
+0061 0670 0652 0651 0652 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062; # (a◌ٰ◌ْ◌ّ◌ْb; a◌ّ◌ْ◌ْ◌ٰb; a◌ّ◌ْ◌ْ◌ٰb; a◌ّ◌ْ◌ْ◌ٰb; a◌ّ◌ْ◌ْ◌ٰb; ) LATIN SMALL LETTER A, ARABIC LETTER SUPERSCRIPT ALEF, ARABIC SUKUN, ARABIC SHADDA, ARABIC SUKUN, LATIN SMALL LETTER B
+0061 0652 0670 0652 0651 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062;0061 0651 0652 0652 0670 0062; # (a◌ْ◌ٰ◌ْ◌ّb; a◌ّ◌ْ◌ْ◌ٰb; a◌ّ◌ْ◌ْ◌ٰb; a◌ّ◌ْ◌ْ◌ٰb; a◌ّ◌ْ◌ْ◌ٰb; ) LATIN SMALL LETTER A, ARABIC SUKUN, ARABIC LETTER SUPERSCRIPT ALEF, ARABIC SUKUN, ARABIC SHADDA, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0653 0062;00E0 05AE 0653 0315 0062;0061 05AE 0300 0653 0315 0062;00E0 05AE 0653 0315 0062;0061 05AE 0300 0653 0315 0062; # (a◌̕◌̀◌֮◌ٓb; à◌֮◌ٓ◌̕b; a◌֮◌̀◌ٓ◌̕b; à◌֮◌ٓ◌̕b; a◌֮◌̀◌ٓ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC MADDAH ABOVE, LATIN SMALL LETTER B
+0061 0653 0315 0300 05AE 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062;0061 05AE 0653 0300 0315 0062; # (a◌ٓ◌̕◌̀◌֮b; a◌֮◌ٓ◌̀◌̕b; a◌֮◌ٓ◌̀◌̕b; a◌֮◌ٓ◌̀◌̕b; a◌֮◌ٓ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC MADDAH ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0654 0062;00E0 05AE 0654 0315 0062;0061 05AE 0300 0654 0315 0062;00E0 05AE 0654 0315 0062;0061 05AE 0300 0654 0315 0062; # (a◌̕◌̀◌֮◌ٔb; à◌֮◌ٔ◌̕b; a◌֮◌̀◌ٔ◌̕b; à◌֮◌ٔ◌̕b; a◌֮◌̀◌ٔ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC HAMZA ABOVE, LATIN SMALL LETTER B
+0061 0654 0315 0300 05AE 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062;0061 05AE 0654 0300 0315 0062; # (a◌ٔ◌̕◌̀◌֮b; a◌֮◌ٔ◌̀◌̕b; a◌֮◌ٔ◌̀◌̕b; a◌֮◌ٔ◌̀◌̕b; a◌֮◌ٔ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC HAMZA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0655 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062;0061 302A 0316 0655 059A 0062; # (a◌֚◌̖◌〪◌ٕb; a◌〪◌̖◌ٕ◌֚b; a◌〪◌̖◌ٕ◌֚b; a◌〪◌̖◌ٕ◌֚b; a◌〪◌̖◌ٕ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC HAMZA BELOW, LATIN SMALL LETTER B
+0061 0655 059A 0316 302A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062;0061 302A 0655 0316 059A 0062; # (a◌ٕ◌֚◌̖◌〪b; a◌〪◌ٕ◌̖◌֚b; a◌〪◌ٕ◌̖◌֚b; a◌〪◌ٕ◌̖◌֚b; a◌〪◌ٕ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC HAMZA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0656 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062;0061 302A 0316 0656 059A 0062; # (a◌֚◌̖◌〪◌ٖb; a◌〪◌̖◌ٖ◌֚b; a◌〪◌̖◌ٖ◌֚b; a◌〪◌̖◌ٖ◌֚b; a◌〪◌̖◌ٖ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC SUBSCRIPT ALEF, LATIN SMALL LETTER B
+0061 0656 059A 0316 302A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062;0061 302A 0656 0316 059A 0062; # (a◌ٖ◌֚◌̖◌〪b; a◌〪◌ٖ◌̖◌֚b; a◌〪◌ٖ◌̖◌֚b; a◌〪◌ٖ◌̖◌֚b; a◌〪◌ٖ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SUBSCRIPT ALEF, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0657 0062;00E0 05AE 0657 0315 0062;0061 05AE 0300 0657 0315 0062;00E0 05AE 0657 0315 0062;0061 05AE 0300 0657 0315 0062; # (a◌̕◌̀◌֮◌ٗb; à◌֮◌ٗ◌̕b; a◌֮◌̀◌ٗ◌̕b; à◌֮◌ٗ◌̕b; a◌֮◌̀◌ٗ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC INVERTED DAMMA, LATIN SMALL LETTER B
+0061 0657 0315 0300 05AE 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062;0061 05AE 0657 0300 0315 0062; # (a◌ٗ◌̕◌̀◌֮b; a◌֮◌ٗ◌̀◌̕b; a◌֮◌ٗ◌̀◌̕b; a◌֮◌ٗ◌̀◌̕b; a◌֮◌ٗ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC INVERTED DAMMA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0658 0062;00E0 05AE 0658 0315 0062;0061 05AE 0300 0658 0315 0062;00E0 05AE 0658 0315 0062;0061 05AE 0300 0658 0315 0062; # (a◌̕◌̀◌֮◌٘b; à◌֮◌٘◌̕b; a◌֮◌̀◌٘◌̕b; à◌֮◌٘◌̕b; a◌֮◌̀◌٘◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC MARK NOON GHUNNA, LATIN SMALL LETTER B
+0061 0658 0315 0300 05AE 0062;0061 05AE 0658 0300 0315 0062;0061 05AE 0658 0300 0315 0062;0061 05AE 0658 0300 0315 0062;0061 05AE 0658 0300 0315 0062; # (a◌٘◌̕◌̀◌֮b; a◌֮◌٘◌̀◌̕b; a◌֮◌٘◌̀◌̕b; a◌֮◌٘◌̀◌̕b; a◌֮◌٘◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC MARK NOON GHUNNA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0659 0062;00E0 05AE 0659 0315 0062;0061 05AE 0300 0659 0315 0062;00E0 05AE 0659 0315 0062;0061 05AE 0300 0659 0315 0062; # (a◌̕◌̀◌֮◌ٙb; à◌֮◌ٙ◌̕b; a◌֮◌̀◌ٙ◌̕b; à◌֮◌ٙ◌̕b; a◌֮◌̀◌ٙ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC ZWARAKAY, LATIN SMALL LETTER B
+0061 0659 0315 0300 05AE 0062;0061 05AE 0659 0300 0315 0062;0061 05AE 0659 0300 0315 0062;0061 05AE 0659 0300 0315 0062;0061 05AE 0659 0300 0315 0062; # (a◌ٙ◌̕◌̀◌֮b; a◌֮◌ٙ◌̀◌̕b; a◌֮◌ٙ◌̀◌̕b; a◌֮◌ٙ◌̀◌̕b; a◌֮◌ٙ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC ZWARAKAY, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 065A 0062;00E0 05AE 065A 0315 0062;0061 05AE 0300 065A 0315 0062;00E0 05AE 065A 0315 0062;0061 05AE 0300 065A 0315 0062; # (a◌̕◌̀◌֮◌ٚb; à◌֮◌ٚ◌̕b; a◌֮◌̀◌ٚ◌̕b; à◌֮◌ٚ◌̕b; a◌֮◌̀◌ٚ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC VOWEL SIGN SMALL V ABOVE, LATIN SMALL LETTER B
+0061 065A 0315 0300 05AE 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062;0061 05AE 065A 0300 0315 0062; # (a◌ٚ◌̕◌̀◌֮b; a◌֮◌ٚ◌̀◌̕b; a◌֮◌ٚ◌̀◌̕b; a◌֮◌ٚ◌̀◌̕b; a◌֮◌ٚ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC VOWEL SIGN SMALL V ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 065B 0062;00E0 05AE 065B 0315 0062;0061 05AE 0300 065B 0315 0062;00E0 05AE 065B 0315 0062;0061 05AE 0300 065B 0315 0062; # (a◌̕◌̀◌֮◌ٛb; à◌֮◌ٛ◌̕b; a◌֮◌̀◌ٛ◌̕b; à◌֮◌ٛ◌̕b; a◌֮◌̀◌ٛ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC VOWEL SIGN INVERTED SMALL V ABOVE, LATIN SMALL LETTER B
+0061 065B 0315 0300 05AE 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062;0061 05AE 065B 0300 0315 0062; # (a◌ٛ◌̕◌̀◌֮b; a◌֮◌ٛ◌̀◌̕b; a◌֮◌ٛ◌̀◌̕b; a◌֮◌ٛ◌̀◌̕b; a◌֮◌ٛ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC VOWEL SIGN INVERTED SMALL V ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 065C 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062;0061 302A 0316 065C 059A 0062; # (a◌֚◌̖◌〪◌ٜb; a◌〪◌̖◌ٜ◌֚b; a◌〪◌̖◌ٜ◌֚b; a◌〪◌̖◌ٜ◌֚b; a◌〪◌̖◌ٜ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC VOWEL SIGN DOT BELOW, LATIN SMALL LETTER B
+0061 065C 059A 0316 302A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062;0061 302A 065C 0316 059A 0062; # (a◌ٜ◌֚◌̖◌〪b; a◌〪◌ٜ◌̖◌֚b; a◌〪◌ٜ◌̖◌֚b; a◌〪◌ٜ◌̖◌֚b; a◌〪◌ٜ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC VOWEL SIGN DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 065D 0062;00E0 05AE 065D 0315 0062;0061 05AE 0300 065D 0315 0062;00E0 05AE 065D 0315 0062;0061 05AE 0300 065D 0315 0062; # (a◌̕◌̀◌֮◌ٝb; à◌֮◌ٝ◌̕b; a◌֮◌̀◌ٝ◌̕b; à◌֮◌ٝ◌̕b; a◌֮◌̀◌ٝ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC REVERSED DAMMA, LATIN SMALL LETTER B
+0061 065D 0315 0300 05AE 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062;0061 05AE 065D 0300 0315 0062; # (a◌ٝ◌̕◌̀◌֮b; a◌֮◌ٝ◌̀◌̕b; a◌֮◌ٝ◌̀◌̕b; a◌֮◌ٝ◌̀◌̕b; a◌֮◌ٝ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC REVERSED DAMMA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 065E 0062;00E0 05AE 065E 0315 0062;0061 05AE 0300 065E 0315 0062;00E0 05AE 065E 0315 0062;0061 05AE 0300 065E 0315 0062; # (a◌̕◌̀◌֮◌ٞb; à◌֮◌ٞ◌̕b; a◌֮◌̀◌ٞ◌̕b; à◌֮◌ٞ◌̕b; a◌֮◌̀◌ٞ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC FATHA WITH TWO DOTS, LATIN SMALL LETTER B
+0061 065E 0315 0300 05AE 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062;0061 05AE 065E 0300 0315 0062; # (a◌ٞ◌̕◌̀◌֮b; a◌֮◌ٞ◌̀◌̕b; a◌֮◌ٞ◌̀◌̕b; a◌֮◌ٞ◌̀◌̕b; a◌֮◌ٞ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC FATHA WITH TWO DOTS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 065F 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062;0061 302A 0316 065F 059A 0062; # (a◌֚◌̖◌〪◌ٟb; a◌〪◌̖◌ٟ◌֚b; a◌〪◌̖◌ٟ◌֚b; a◌〪◌̖◌ٟ◌֚b; a◌〪◌̖◌ٟ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC WAVY HAMZA BELOW, LATIN SMALL LETTER B
+0061 065F 059A 0316 302A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062;0061 302A 065F 0316 059A 0062; # (a◌ٟ◌֚◌̖◌〪b; a◌〪◌ٟ◌̖◌֚b; a◌〪◌ٟ◌̖◌֚b; a◌〪◌ٟ◌̖◌֚b; a◌〪◌ٟ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC WAVY HAMZA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0711 0670 0652 0670 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062; # (a◌ܑ◌ٰ◌ْ◌ٰb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; ) LATIN SMALL LETTER A, SYRIAC LETTER SUPERSCRIPT ALAPH, ARABIC LETTER SUPERSCRIPT ALEF, ARABIC SUKUN, ARABIC LETTER SUPERSCRIPT ALEF, LATIN SMALL LETTER B
+0061 0670 0711 0670 0652 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062;0061 0652 0670 0670 0711 0062; # (a◌ٰ◌ܑ◌ٰ◌ْb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; a◌ْ◌ٰ◌ٰ◌ܑb; ) LATIN SMALL LETTER A, ARABIC LETTER SUPERSCRIPT ALEF, SYRIAC LETTER SUPERSCRIPT ALAPH, ARABIC LETTER SUPERSCRIPT ALEF, ARABIC SUKUN, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06D6 0062;00E0 05AE 06D6 0315 0062;0061 05AE 0300 06D6 0315 0062;00E0 05AE 06D6 0315 0062;0061 05AE 0300 06D6 0315 0062; # (a◌̕◌̀◌֮◌ۖb; à◌֮◌ۖ◌̕b; a◌֮◌̀◌ۖ◌̕b; à◌֮◌ۖ◌̕b; a◌֮◌̀◌ۖ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA, LATIN SMALL LETTER B
+0061 06D6 0315 0300 05AE 0062;0061 05AE 06D6 0300 0315 0062;0061 05AE 06D6 0300 0315 0062;0061 05AE 06D6 0300 0315 0062;0061 05AE 06D6 0300 0315 0062; # (a◌ۖ◌̕◌̀◌֮b; a◌֮◌ۖ◌̀◌̕b; a◌֮◌ۖ◌̀◌̕b; a◌֮◌ۖ◌̀◌̕b; a◌֮◌ۖ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06D7 0062;00E0 05AE 06D7 0315 0062;0061 05AE 0300 06D7 0315 0062;00E0 05AE 06D7 0315 0062;0061 05AE 0300 06D7 0315 0062; # (a◌̕◌̀◌֮◌ۗb; à◌֮◌ۗ◌̕b; a◌֮◌̀◌ۗ◌̕b; à◌֮◌ۗ◌̕b; a◌֮◌̀◌ۗ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA, LATIN SMALL LETTER B
+0061 06D7 0315 0300 05AE 0062;0061 05AE 06D7 0300 0315 0062;0061 05AE 06D7 0300 0315 0062;0061 05AE 06D7 0300 0315 0062;0061 05AE 06D7 0300 0315 0062; # (a◌ۗ◌̕◌̀◌֮b; a◌֮◌ۗ◌̀◌̕b; a◌֮◌ۗ◌̀◌̕b; a◌֮◌ۗ◌̀◌̕b; a◌֮◌ۗ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06D8 0062;00E0 05AE 06D8 0315 0062;0061 05AE 0300 06D8 0315 0062;00E0 05AE 06D8 0315 0062;0061 05AE 0300 06D8 0315 0062; # (a◌̕◌̀◌֮◌ۘb; à◌֮◌ۘ◌̕b; a◌֮◌̀◌ۘ◌̕b; à◌֮◌ۘ◌̕b; a◌֮◌̀◌ۘ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH MEEM INITIAL FORM, LATIN SMALL LETTER B
+0061 06D8 0315 0300 05AE 0062;0061 05AE 06D8 0300 0315 0062;0061 05AE 06D8 0300 0315 0062;0061 05AE 06D8 0300 0315 0062;0061 05AE 06D8 0300 0315 0062; # (a◌ۘ◌̕◌̀◌֮b; a◌֮◌ۘ◌̀◌̕b; a◌֮◌ۘ◌̀◌̕b; a◌֮◌ۘ◌̀◌̕b; a◌֮◌ۘ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH MEEM INITIAL FORM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06D9 0062;00E0 05AE 06D9 0315 0062;0061 05AE 0300 06D9 0315 0062;00E0 05AE 06D9 0315 0062;0061 05AE 0300 06D9 0315 0062; # (a◌̕◌̀◌֮◌ۙb; à◌֮◌ۙ◌̕b; a◌֮◌̀◌ۙ◌̕b; à◌֮◌ۙ◌̕b; a◌֮◌̀◌ۙ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH LAM ALEF, LATIN SMALL LETTER B
+0061 06D9 0315 0300 05AE 0062;0061 05AE 06D9 0300 0315 0062;0061 05AE 06D9 0300 0315 0062;0061 05AE 06D9 0300 0315 0062;0061 05AE 06D9 0300 0315 0062; # (a◌ۙ◌̕◌̀◌֮b; a◌֮◌ۙ◌̀◌̕b; a◌֮◌ۙ◌̀◌̕b; a◌֮◌ۙ◌̀◌̕b; a◌֮◌ۙ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH LAM ALEF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06DA 0062;00E0 05AE 06DA 0315 0062;0061 05AE 0300 06DA 0315 0062;00E0 05AE 06DA 0315 0062;0061 05AE 0300 06DA 0315 0062; # (a◌̕◌̀◌֮◌ۚb; à◌֮◌ۚ◌̕b; a◌֮◌̀◌ۚ◌̕b; à◌֮◌ۚ◌̕b; a◌֮◌̀◌ۚ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH JEEM, LATIN SMALL LETTER B
+0061 06DA 0315 0300 05AE 0062;0061 05AE 06DA 0300 0315 0062;0061 05AE 06DA 0300 0315 0062;0061 05AE 06DA 0300 0315 0062;0061 05AE 06DA 0300 0315 0062; # (a◌ۚ◌̕◌̀◌֮b; a◌֮◌ۚ◌̀◌̕b; a◌֮◌ۚ◌̀◌̕b; a◌֮◌ۚ◌̀◌̕b; a◌֮◌ۚ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH JEEM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06DB 0062;00E0 05AE 06DB 0315 0062;0061 05AE 0300 06DB 0315 0062;00E0 05AE 06DB 0315 0062;0061 05AE 0300 06DB 0315 0062; # (a◌̕◌̀◌֮◌ۛb; à◌֮◌ۛ◌̕b; a◌֮◌̀◌ۛ◌̕b; à◌֮◌ۛ◌̕b; a◌֮◌̀◌ۛ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH THREE DOTS, LATIN SMALL LETTER B
+0061 06DB 0315 0300 05AE 0062;0061 05AE 06DB 0300 0315 0062;0061 05AE 06DB 0300 0315 0062;0061 05AE 06DB 0300 0315 0062;0061 05AE 06DB 0300 0315 0062; # (a◌ۛ◌̕◌̀◌֮b; a◌֮◌ۛ◌̀◌̕b; a◌֮◌ۛ◌̀◌̕b; a◌֮◌ۛ◌̀◌̕b; a◌֮◌ۛ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH THREE DOTS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06DC 0062;00E0 05AE 06DC 0315 0062;0061 05AE 0300 06DC 0315 0062;00E0 05AE 06DC 0315 0062;0061 05AE 0300 06DC 0315 0062; # (a◌̕◌̀◌֮◌ۜb; à◌֮◌ۜ◌̕b; a◌֮◌̀◌ۜ◌̕b; à◌֮◌ۜ◌̕b; a◌֮◌̀◌ۜ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH SEEN, LATIN SMALL LETTER B
+0061 06DC 0315 0300 05AE 0062;0061 05AE 06DC 0300 0315 0062;0061 05AE 06DC 0300 0315 0062;0061 05AE 06DC 0300 0315 0062;0061 05AE 06DC 0300 0315 0062; # (a◌ۜ◌̕◌̀◌֮b; a◌֮◌ۜ◌̀◌̕b; a◌֮◌ۜ◌̀◌̕b; a◌֮◌ۜ◌̀◌̕b; a◌֮◌ۜ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH SEEN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06DF 0062;00E0 05AE 06DF 0315 0062;0061 05AE 0300 06DF 0315 0062;00E0 05AE 06DF 0315 0062;0061 05AE 0300 06DF 0315 0062; # (a◌̕◌̀◌֮◌۟b; à◌֮◌۟◌̕b; a◌֮◌̀◌۟◌̕b; à◌֮◌۟◌̕b; a◌֮◌̀◌۟◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH ROUNDED ZERO, LATIN SMALL LETTER B
+0061 06DF 0315 0300 05AE 0062;0061 05AE 06DF 0300 0315 0062;0061 05AE 06DF 0300 0315 0062;0061 05AE 06DF 0300 0315 0062;0061 05AE 06DF 0300 0315 0062; # (a◌۟◌̕◌̀◌֮b; a◌֮◌۟◌̀◌̕b; a◌֮◌۟◌̀◌̕b; a◌֮◌۟◌̀◌̕b; a◌֮◌۟◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH ROUNDED ZERO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06E0 0062;00E0 05AE 06E0 0315 0062;0061 05AE 0300 06E0 0315 0062;00E0 05AE 06E0 0315 0062;0061 05AE 0300 06E0 0315 0062; # (a◌̕◌̀◌֮◌۠b; à◌֮◌۠◌̕b; a◌֮◌̀◌۠◌̕b; à◌֮◌۠◌̕b; a◌֮◌̀◌۠◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO, LATIN SMALL LETTER B
+0061 06E0 0315 0300 05AE 0062;0061 05AE 06E0 0300 0315 0062;0061 05AE 06E0 0300 0315 0062;0061 05AE 06E0 0300 0315 0062;0061 05AE 06E0 0300 0315 0062; # (a◌۠◌̕◌̀◌֮b; a◌֮◌۠◌̀◌̕b; a◌֮◌۠◌̀◌̕b; a◌֮◌۠◌̀◌̕b; a◌֮◌۠◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06E1 0062;00E0 05AE 06E1 0315 0062;0061 05AE 0300 06E1 0315 0062;00E0 05AE 06E1 0315 0062;0061 05AE 0300 06E1 0315 0062; # (a◌̕◌̀◌֮◌ۡb; à◌֮◌ۡ◌̕b; a◌֮◌̀◌ۡ◌̕b; à◌֮◌ۡ◌̕b; a◌֮◌̀◌ۡ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH DOTLESS HEAD OF KHAH, LATIN SMALL LETTER B
+0061 06E1 0315 0300 05AE 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062;0061 05AE 06E1 0300 0315 0062; # (a◌ۡ◌̕◌̀◌֮b; a◌֮◌ۡ◌̀◌̕b; a◌֮◌ۡ◌̀◌̕b; a◌֮◌ۡ◌̀◌̕b; a◌֮◌ۡ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH DOTLESS HEAD OF KHAH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06E2 0062;00E0 05AE 06E2 0315 0062;0061 05AE 0300 06E2 0315 0062;00E0 05AE 06E2 0315 0062;0061 05AE 0300 06E2 0315 0062; # (a◌̕◌̀◌֮◌ۢb; à◌֮◌ۢ◌̕b; a◌֮◌̀◌ۢ◌̕b; à◌֮◌ۢ◌̕b; a◌֮◌̀◌ۢ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH MEEM ISOLATED FORM, LATIN SMALL LETTER B
+0061 06E2 0315 0300 05AE 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062;0061 05AE 06E2 0300 0315 0062; # (a◌ۢ◌̕◌̀◌֮b; a◌֮◌ۢ◌̀◌̕b; a◌֮◌ۢ◌̀◌̕b; a◌֮◌ۢ◌̀◌̕b; a◌֮◌ۢ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH MEEM ISOLATED FORM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 06E3 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062;0061 302A 0316 06E3 059A 0062; # (a◌֚◌̖◌〪◌ۣb; a◌〪◌̖◌ۣ◌֚b; a◌〪◌̖◌ۣ◌֚b; a◌〪◌̖◌ۣ◌֚b; a◌〪◌̖◌ۣ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC SMALL LOW SEEN, LATIN SMALL LETTER B
+0061 06E3 059A 0316 302A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062;0061 302A 06E3 0316 059A 0062; # (a◌ۣ◌֚◌̖◌〪b; a◌〪◌ۣ◌̖◌֚b; a◌〪◌ۣ◌̖◌֚b; a◌〪◌ۣ◌̖◌֚b; a◌〪◌ۣ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW SEEN, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06E4 0062;00E0 05AE 06E4 0315 0062;0061 05AE 0300 06E4 0315 0062;00E0 05AE 06E4 0315 0062;0061 05AE 0300 06E4 0315 0062; # (a◌̕◌̀◌֮◌ۤb; à◌֮◌ۤ◌̕b; a◌֮◌̀◌ۤ◌̕b; à◌֮◌ۤ◌̕b; a◌֮◌̀◌ۤ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH MADDA, LATIN SMALL LETTER B
+0061 06E4 0315 0300 05AE 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062;0061 05AE 06E4 0300 0315 0062; # (a◌ۤ◌̕◌̀◌֮b; a◌֮◌ۤ◌̀◌̕b; a◌֮◌ۤ◌̀◌̕b; a◌֮◌ۤ◌̀◌̕b; a◌֮◌ۤ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH MADDA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06E7 0062;00E0 05AE 06E7 0315 0062;0061 05AE 0300 06E7 0315 0062;00E0 05AE 06E7 0315 0062;0061 05AE 0300 06E7 0315 0062; # (a◌̕◌̀◌֮◌ۧb; à◌֮◌ۧ◌̕b; a◌֮◌̀◌ۧ◌̕b; à◌֮◌ۧ◌̕b; a◌֮◌̀◌ۧ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH YEH, LATIN SMALL LETTER B
+0061 06E7 0315 0300 05AE 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062;0061 05AE 06E7 0300 0315 0062; # (a◌ۧ◌̕◌̀◌֮b; a◌֮◌ۧ◌̀◌̕b; a◌֮◌ۧ◌̀◌̕b; a◌֮◌ۧ◌̀◌̕b; a◌֮◌ۧ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH YEH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06E8 0062;00E0 05AE 06E8 0315 0062;0061 05AE 0300 06E8 0315 0062;00E0 05AE 06E8 0315 0062;0061 05AE 0300 06E8 0315 0062; # (a◌̕◌̀◌֮◌ۨb; à◌֮◌ۨ◌̕b; a◌֮◌̀◌ۨ◌̕b; à◌֮◌ۨ◌̕b; a◌֮◌̀◌ۨ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH NOON, LATIN SMALL LETTER B
+0061 06E8 0315 0300 05AE 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062;0061 05AE 06E8 0300 0315 0062; # (a◌ۨ◌̕◌̀◌֮b; a◌֮◌ۨ◌̀◌̕b; a◌֮◌ۨ◌̀◌̕b; a◌֮◌ۨ◌̀◌̕b; a◌֮◌ۨ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH NOON, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 06EA 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062;0061 302A 0316 06EA 059A 0062; # (a◌֚◌̖◌〪◌۪b; a◌〪◌̖◌۪◌֚b; a◌〪◌̖◌۪◌֚b; a◌〪◌̖◌۪◌֚b; a◌〪◌̖◌۪◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC EMPTY CENTRE LOW STOP, LATIN SMALL LETTER B
+0061 06EA 059A 0316 302A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062;0061 302A 06EA 0316 059A 0062; # (a◌۪◌֚◌̖◌〪b; a◌〪◌۪◌̖◌֚b; a◌〪◌۪◌̖◌֚b; a◌〪◌۪◌̖◌֚b; a◌〪◌۪◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC EMPTY CENTRE LOW STOP, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06EB 0062;00E0 05AE 06EB 0315 0062;0061 05AE 0300 06EB 0315 0062;00E0 05AE 06EB 0315 0062;0061 05AE 0300 06EB 0315 0062; # (a◌̕◌̀◌֮◌۫b; à◌֮◌۫◌̕b; a◌֮◌̀◌۫◌̕b; à◌֮◌۫◌̕b; a◌֮◌̀◌۫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC EMPTY CENTRE HIGH STOP, LATIN SMALL LETTER B
+0061 06EB 0315 0300 05AE 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062;0061 05AE 06EB 0300 0315 0062; # (a◌۫◌̕◌̀◌֮b; a◌֮◌۫◌̀◌̕b; a◌֮◌۫◌̀◌̕b; a◌֮◌۫◌̀◌̕b; a◌֮◌۫◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC EMPTY CENTRE HIGH STOP, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 06EC 0062;00E0 05AE 06EC 0315 0062;0061 05AE 0300 06EC 0315 0062;00E0 05AE 06EC 0315 0062;0061 05AE 0300 06EC 0315 0062; # (a◌̕◌̀◌֮◌۬b; à◌֮◌۬◌̕b; a◌֮◌̀◌۬◌̕b; à◌֮◌۬◌̕b; a◌֮◌̀◌۬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE, LATIN SMALL LETTER B
+0061 06EC 0315 0300 05AE 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062;0061 05AE 06EC 0300 0315 0062; # (a◌۬◌̕◌̀◌֮b; a◌֮◌۬◌̀◌̕b; a◌֮◌۬◌̀◌̕b; a◌֮◌۬◌̀◌̕b; a◌֮◌۬◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 06ED 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062;0061 302A 0316 06ED 059A 0062; # (a◌֚◌̖◌〪◌ۭb; a◌〪◌̖◌ۭ◌֚b; a◌〪◌̖◌ۭ◌֚b; a◌〪◌̖◌ۭ◌֚b; a◌〪◌̖◌ۭ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC SMALL LOW MEEM, LATIN SMALL LETTER B
+0061 06ED 059A 0316 302A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062;0061 302A 06ED 0316 059A 0062; # (a◌ۭ◌֚◌̖◌〪b; a◌〪◌ۭ◌̖◌֚b; a◌〪◌ۭ◌̖◌֚b; a◌〪◌ۭ◌̖◌֚b; a◌〪◌ۭ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW MEEM, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0C55 0711 0670 0711 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062; # (a◌ౕ◌ܑ◌ٰ◌ܑb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; ) LATIN SMALL LETTER A, TELUGU LENGTH MARK, SYRIAC LETTER SUPERSCRIPT ALAPH, ARABIC LETTER SUPERSCRIPT ALEF, SYRIAC LETTER SUPERSCRIPT ALAPH, LATIN SMALL LETTER B
+0061 0711 0C55 0711 0670 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062;0061 0670 0711 0711 0C55 0062; # (a◌ܑ◌ౕ◌ܑ◌ٰb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; a◌ٰ◌ܑ◌ܑ◌ౕb; ) LATIN SMALL LETTER A, SYRIAC LETTER SUPERSCRIPT ALAPH, TELUGU LENGTH MARK, SYRIAC LETTER SUPERSCRIPT ALAPH, ARABIC LETTER SUPERSCRIPT ALEF, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0730 0062;00E0 05AE 0730 0315 0062;0061 05AE 0300 0730 0315 0062;00E0 05AE 0730 0315 0062;0061 05AE 0300 0730 0315 0062; # (a◌̕◌̀◌֮◌ܰb; à◌֮◌ܰ◌̕b; a◌֮◌̀◌ܰ◌̕b; à◌֮◌ܰ◌̕b; a◌֮◌̀◌ܰ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC PTHAHA ABOVE, LATIN SMALL LETTER B
+0061 0730 0315 0300 05AE 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062;0061 05AE 0730 0300 0315 0062; # (a◌ܰ◌̕◌̀◌֮b; a◌֮◌ܰ◌̀◌̕b; a◌֮◌ܰ◌̀◌̕b; a◌֮◌ܰ◌̀◌̕b; a◌֮◌ܰ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC PTHAHA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0731 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062;0061 302A 0316 0731 059A 0062; # (a◌֚◌̖◌〪◌ܱb; a◌〪◌̖◌ܱ◌֚b; a◌〪◌̖◌ܱ◌֚b; a◌〪◌̖◌ܱ◌֚b; a◌〪◌̖◌ܱ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC PTHAHA BELOW, LATIN SMALL LETTER B
+0061 0731 059A 0316 302A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062;0061 302A 0731 0316 059A 0062; # (a◌ܱ◌֚◌̖◌〪b; a◌〪◌ܱ◌̖◌֚b; a◌〪◌ܱ◌̖◌֚b; a◌〪◌ܱ◌̖◌֚b; a◌〪◌ܱ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC PTHAHA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0732 0062;00E0 05AE 0732 0315 0062;0061 05AE 0300 0732 0315 0062;00E0 05AE 0732 0315 0062;0061 05AE 0300 0732 0315 0062; # (a◌̕◌̀◌֮◌ܲb; à◌֮◌ܲ◌̕b; a◌֮◌̀◌ܲ◌̕b; à◌֮◌ܲ◌̕b; a◌֮◌̀◌ܲ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC PTHAHA DOTTED, LATIN SMALL LETTER B
+0061 0732 0315 0300 05AE 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062;0061 05AE 0732 0300 0315 0062; # (a◌ܲ◌̕◌̀◌֮b; a◌֮◌ܲ◌̀◌̕b; a◌֮◌ܲ◌̀◌̕b; a◌֮◌ܲ◌̀◌̕b; a◌֮◌ܲ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC PTHAHA DOTTED, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0733 0062;00E0 05AE 0733 0315 0062;0061 05AE 0300 0733 0315 0062;00E0 05AE 0733 0315 0062;0061 05AE 0300 0733 0315 0062; # (a◌̕◌̀◌֮◌ܳb; à◌֮◌ܳ◌̕b; a◌֮◌̀◌ܳ◌̕b; à◌֮◌ܳ◌̕b; a◌֮◌̀◌ܳ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC ZQAPHA ABOVE, LATIN SMALL LETTER B
+0061 0733 0315 0300 05AE 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062;0061 05AE 0733 0300 0315 0062; # (a◌ܳ◌̕◌̀◌֮b; a◌֮◌ܳ◌̀◌̕b; a◌֮◌ܳ◌̀◌̕b; a◌֮◌ܳ◌̀◌̕b; a◌֮◌ܳ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC ZQAPHA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0734 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062;0061 302A 0316 0734 059A 0062; # (a◌֚◌̖◌〪◌ܴb; a◌〪◌̖◌ܴ◌֚b; a◌〪◌̖◌ܴ◌֚b; a◌〪◌̖◌ܴ◌֚b; a◌〪◌̖◌ܴ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC ZQAPHA BELOW, LATIN SMALL LETTER B
+0061 0734 059A 0316 302A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062;0061 302A 0734 0316 059A 0062; # (a◌ܴ◌֚◌̖◌〪b; a◌〪◌ܴ◌̖◌֚b; a◌〪◌ܴ◌̖◌֚b; a◌〪◌ܴ◌̖◌֚b; a◌〪◌ܴ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC ZQAPHA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0735 0062;00E0 05AE 0735 0315 0062;0061 05AE 0300 0735 0315 0062;00E0 05AE 0735 0315 0062;0061 05AE 0300 0735 0315 0062; # (a◌̕◌̀◌֮◌ܵb; à◌֮◌ܵ◌̕b; a◌֮◌̀◌ܵ◌̕b; à◌֮◌ܵ◌̕b; a◌֮◌̀◌ܵ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC ZQAPHA DOTTED, LATIN SMALL LETTER B
+0061 0735 0315 0300 05AE 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062;0061 05AE 0735 0300 0315 0062; # (a◌ܵ◌̕◌̀◌֮b; a◌֮◌ܵ◌̀◌̕b; a◌֮◌ܵ◌̀◌̕b; a◌֮◌ܵ◌̀◌̕b; a◌֮◌ܵ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC ZQAPHA DOTTED, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0736 0062;00E0 05AE 0736 0315 0062;0061 05AE 0300 0736 0315 0062;00E0 05AE 0736 0315 0062;0061 05AE 0300 0736 0315 0062; # (a◌̕◌̀◌֮◌ܶb; à◌֮◌ܶ◌̕b; a◌֮◌̀◌ܶ◌̕b; à◌֮◌ܶ◌̕b; a◌֮◌̀◌ܶ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC RBASA ABOVE, LATIN SMALL LETTER B
+0061 0736 0315 0300 05AE 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062;0061 05AE 0736 0300 0315 0062; # (a◌ܶ◌̕◌̀◌֮b; a◌֮◌ܶ◌̀◌̕b; a◌֮◌ܶ◌̀◌̕b; a◌֮◌ܶ◌̀◌̕b; a◌֮◌ܶ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC RBASA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0737 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062;0061 302A 0316 0737 059A 0062; # (a◌֚◌̖◌〪◌ܷb; a◌〪◌̖◌ܷ◌֚b; a◌〪◌̖◌ܷ◌֚b; a◌〪◌̖◌ܷ◌֚b; a◌〪◌̖◌ܷ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC RBASA BELOW, LATIN SMALL LETTER B
+0061 0737 059A 0316 302A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062;0061 302A 0737 0316 059A 0062; # (a◌ܷ◌֚◌̖◌〪b; a◌〪◌ܷ◌̖◌֚b; a◌〪◌ܷ◌̖◌֚b; a◌〪◌ܷ◌̖◌֚b; a◌〪◌ܷ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC RBASA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0738 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062;0061 302A 0316 0738 059A 0062; # (a◌֚◌̖◌〪◌ܸb; a◌〪◌̖◌ܸ◌֚b; a◌〪◌̖◌ܸ◌֚b; a◌〪◌̖◌ܸ◌֚b; a◌〪◌̖◌ܸ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC DOTTED ZLAMA HORIZONTAL, LATIN SMALL LETTER B
+0061 0738 059A 0316 302A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062;0061 302A 0738 0316 059A 0062; # (a◌ܸ◌֚◌̖◌〪b; a◌〪◌ܸ◌̖◌֚b; a◌〪◌ܸ◌̖◌֚b; a◌〪◌ܸ◌̖◌֚b; a◌〪◌ܸ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC DOTTED ZLAMA HORIZONTAL, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0739 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062;0061 302A 0316 0739 059A 0062; # (a◌֚◌̖◌〪◌ܹb; a◌〪◌̖◌ܹ◌֚b; a◌〪◌̖◌ܹ◌֚b; a◌〪◌̖◌ܹ◌֚b; a◌〪◌̖◌ܹ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC DOTTED ZLAMA ANGULAR, LATIN SMALL LETTER B
+0061 0739 059A 0316 302A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062;0061 302A 0739 0316 059A 0062; # (a◌ܹ◌֚◌̖◌〪b; a◌〪◌ܹ◌̖◌֚b; a◌〪◌ܹ◌̖◌֚b; a◌〪◌ܹ◌̖◌֚b; a◌〪◌ܹ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC DOTTED ZLAMA ANGULAR, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 073A 0062;00E0 05AE 073A 0315 0062;0061 05AE 0300 073A 0315 0062;00E0 05AE 073A 0315 0062;0061 05AE 0300 073A 0315 0062; # (a◌̕◌̀◌֮◌ܺb; à◌֮◌ܺ◌̕b; a◌֮◌̀◌ܺ◌̕b; à◌֮◌ܺ◌̕b; a◌֮◌̀◌ܺ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC HBASA ABOVE, LATIN SMALL LETTER B
+0061 073A 0315 0300 05AE 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062;0061 05AE 073A 0300 0315 0062; # (a◌ܺ◌̕◌̀◌֮b; a◌֮◌ܺ◌̀◌̕b; a◌֮◌ܺ◌̀◌̕b; a◌֮◌ܺ◌̀◌̕b; a◌֮◌ܺ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC HBASA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 073B 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062;0061 302A 0316 073B 059A 0062; # (a◌֚◌̖◌〪◌ܻb; a◌〪◌̖◌ܻ◌֚b; a◌〪◌̖◌ܻ◌֚b; a◌〪◌̖◌ܻ◌֚b; a◌〪◌̖◌ܻ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC HBASA BELOW, LATIN SMALL LETTER B
+0061 073B 059A 0316 302A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062;0061 302A 073B 0316 059A 0062; # (a◌ܻ◌֚◌̖◌〪b; a◌〪◌ܻ◌̖◌֚b; a◌〪◌ܻ◌̖◌֚b; a◌〪◌ܻ◌̖◌֚b; a◌〪◌ܻ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC HBASA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 073C 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062;0061 302A 0316 073C 059A 0062; # (a◌֚◌̖◌〪◌ܼb; a◌〪◌̖◌ܼ◌֚b; a◌〪◌̖◌ܼ◌֚b; a◌〪◌̖◌ܼ◌֚b; a◌〪◌̖◌ܼ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC HBASA-ESASA DOTTED, LATIN SMALL LETTER B
+0061 073C 059A 0316 302A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062;0061 302A 073C 0316 059A 0062; # (a◌ܼ◌֚◌̖◌〪b; a◌〪◌ܼ◌̖◌֚b; a◌〪◌ܼ◌̖◌֚b; a◌〪◌ܼ◌̖◌֚b; a◌〪◌ܼ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC HBASA-ESASA DOTTED, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 073D 0062;00E0 05AE 073D 0315 0062;0061 05AE 0300 073D 0315 0062;00E0 05AE 073D 0315 0062;0061 05AE 0300 073D 0315 0062; # (a◌̕◌̀◌֮◌ܽb; à◌֮◌ܽ◌̕b; a◌֮◌̀◌ܽ◌̕b; à◌֮◌ܽ◌̕b; a◌֮◌̀◌ܽ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC ESASA ABOVE, LATIN SMALL LETTER B
+0061 073D 0315 0300 05AE 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062;0061 05AE 073D 0300 0315 0062; # (a◌ܽ◌̕◌̀◌֮b; a◌֮◌ܽ◌̀◌̕b; a◌֮◌ܽ◌̀◌̕b; a◌֮◌ܽ◌̀◌̕b; a◌֮◌ܽ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC ESASA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 073E 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062;0061 302A 0316 073E 059A 0062; # (a◌֚◌̖◌〪◌ܾb; a◌〪◌̖◌ܾ◌֚b; a◌〪◌̖◌ܾ◌֚b; a◌〪◌̖◌ܾ◌֚b; a◌〪◌̖◌ܾ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC ESASA BELOW, LATIN SMALL LETTER B
+0061 073E 059A 0316 302A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062;0061 302A 073E 0316 059A 0062; # (a◌ܾ◌֚◌̖◌〪b; a◌〪◌ܾ◌̖◌֚b; a◌〪◌ܾ◌̖◌֚b; a◌〪◌ܾ◌̖◌֚b; a◌〪◌ܾ◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC ESASA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 073F 0062;00E0 05AE 073F 0315 0062;0061 05AE 0300 073F 0315 0062;00E0 05AE 073F 0315 0062;0061 05AE 0300 073F 0315 0062; # (a◌̕◌̀◌֮◌ܿb; à◌֮◌ܿ◌̕b; a◌֮◌̀◌ܿ◌̕b; à◌֮◌ܿ◌̕b; a◌֮◌̀◌ܿ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC RWAHA, LATIN SMALL LETTER B
+0061 073F 0315 0300 05AE 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062;0061 05AE 073F 0300 0315 0062; # (a◌ܿ◌̕◌̀◌֮b; a◌֮◌ܿ◌̀◌̕b; a◌֮◌ܿ◌̀◌̕b; a◌֮◌ܿ◌̀◌̕b; a◌֮◌ܿ◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC RWAHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0740 0062;00E0 05AE 0740 0315 0062;0061 05AE 0300 0740 0315 0062;00E0 05AE 0740 0315 0062;0061 05AE 0300 0740 0315 0062; # (a◌̕◌̀◌֮◌݀b; à◌֮◌݀◌̕b; a◌֮◌̀◌݀◌̕b; à◌֮◌݀◌̕b; a◌֮◌̀◌݀◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC FEMININE DOT, LATIN SMALL LETTER B
+0061 0740 0315 0300 05AE 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062;0061 05AE 0740 0300 0315 0062; # (a◌݀◌̕◌̀◌֮b; a◌֮◌݀◌̀◌̕b; a◌֮◌݀◌̀◌̕b; a◌֮◌݀◌̀◌̕b; a◌֮◌݀◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC FEMININE DOT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0741 0062;00E0 05AE 0741 0315 0062;0061 05AE 0300 0741 0315 0062;00E0 05AE 0741 0315 0062;0061 05AE 0300 0741 0315 0062; # (a◌̕◌̀◌֮◌݁b; à◌֮◌݁◌̕b; a◌֮◌̀◌݁◌̕b; à◌֮◌݁◌̕b; a◌֮◌̀◌݁◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC QUSHSHAYA, LATIN SMALL LETTER B
+0061 0741 0315 0300 05AE 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062;0061 05AE 0741 0300 0315 0062; # (a◌݁◌̕◌̀◌֮b; a◌֮◌݁◌̀◌̕b; a◌֮◌݁◌̀◌̕b; a◌֮◌݁◌̀◌̕b; a◌֮◌݁◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC QUSHSHAYA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0742 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062;0061 302A 0316 0742 059A 0062; # (a◌֚◌̖◌〪◌݂b; a◌〪◌̖◌݂◌֚b; a◌〪◌̖◌݂◌֚b; a◌〪◌̖◌݂◌֚b; a◌〪◌̖◌݂◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC RUKKAKHA, LATIN SMALL LETTER B
+0061 0742 059A 0316 302A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062;0061 302A 0742 0316 059A 0062; # (a◌݂◌֚◌̖◌〪b; a◌〪◌݂◌̖◌֚b; a◌〪◌݂◌̖◌֚b; a◌〪◌݂◌̖◌֚b; a◌〪◌݂◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC RUKKAKHA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0743 0062;00E0 05AE 0743 0315 0062;0061 05AE 0300 0743 0315 0062;00E0 05AE 0743 0315 0062;0061 05AE 0300 0743 0315 0062; # (a◌̕◌̀◌֮◌݃b; à◌֮◌݃◌̕b; a◌֮◌̀◌݃◌̕b; à◌֮◌݃◌̕b; a◌֮◌̀◌݃◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC TWO VERTICAL DOTS ABOVE, LATIN SMALL LETTER B
+0061 0743 0315 0300 05AE 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062;0061 05AE 0743 0300 0315 0062; # (a◌݃◌̕◌̀◌֮b; a◌֮◌݃◌̀◌̕b; a◌֮◌݃◌̀◌̕b; a◌֮◌݃◌̀◌̕b; a◌֮◌݃◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC TWO VERTICAL DOTS ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0744 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062;0061 302A 0316 0744 059A 0062; # (a◌֚◌̖◌〪◌݄b; a◌〪◌̖◌݄◌֚b; a◌〪◌̖◌݄◌֚b; a◌〪◌̖◌݄◌֚b; a◌〪◌̖◌݄◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC TWO VERTICAL DOTS BELOW, LATIN SMALL LETTER B
+0061 0744 059A 0316 302A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062;0061 302A 0744 0316 059A 0062; # (a◌݄◌֚◌̖◌〪b; a◌〪◌݄◌̖◌֚b; a◌〪◌݄◌̖◌֚b; a◌〪◌݄◌̖◌֚b; a◌〪◌݄◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC TWO VERTICAL DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0745 0062;00E0 05AE 0745 0315 0062;0061 05AE 0300 0745 0315 0062;00E0 05AE 0745 0315 0062;0061 05AE 0300 0745 0315 0062; # (a◌̕◌̀◌֮◌݅b; à◌֮◌݅◌̕b; a◌֮◌̀◌݅◌̕b; à◌֮◌݅◌̕b; a◌֮◌̀◌݅◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC THREE DOTS ABOVE, LATIN SMALL LETTER B
+0061 0745 0315 0300 05AE 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062;0061 05AE 0745 0300 0315 0062; # (a◌݅◌̕◌̀◌֮b; a◌֮◌݅◌̀◌̕b; a◌֮◌݅◌̀◌̕b; a◌֮◌݅◌̀◌̕b; a◌֮◌݅◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC THREE DOTS ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0746 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062;0061 302A 0316 0746 059A 0062; # (a◌֚◌̖◌〪◌݆b; a◌〪◌̖◌݆◌֚b; a◌〪◌̖◌݆◌֚b; a◌〪◌̖◌݆◌֚b; a◌〪◌̖◌݆◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC THREE DOTS BELOW, LATIN SMALL LETTER B
+0061 0746 059A 0316 302A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062;0061 302A 0746 0316 059A 0062; # (a◌݆◌֚◌̖◌〪b; a◌〪◌݆◌̖◌֚b; a◌〪◌݆◌̖◌֚b; a◌〪◌݆◌̖◌֚b; a◌〪◌݆◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC THREE DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0747 0062;00E0 05AE 0747 0315 0062;0061 05AE 0300 0747 0315 0062;00E0 05AE 0747 0315 0062;0061 05AE 0300 0747 0315 0062; # (a◌̕◌̀◌֮◌݇b; à◌֮◌݇◌̕b; a◌֮◌̀◌݇◌̕b; à◌֮◌݇◌̕b; a◌֮◌̀◌݇◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC OBLIQUE LINE ABOVE, LATIN SMALL LETTER B
+0061 0747 0315 0300 05AE 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062;0061 05AE 0747 0300 0315 0062; # (a◌݇◌̕◌̀◌֮b; a◌֮◌݇◌̀◌̕b; a◌֮◌݇◌̀◌̕b; a◌֮◌݇◌̀◌̕b; a◌֮◌݇◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC OBLIQUE LINE ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0748 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062;0061 302A 0316 0748 059A 0062; # (a◌֚◌̖◌〪◌݈b; a◌〪◌̖◌݈◌֚b; a◌〪◌̖◌݈◌֚b; a◌〪◌̖◌݈◌֚b; a◌〪◌̖◌݈◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, SYRIAC OBLIQUE LINE BELOW, LATIN SMALL LETTER B
+0061 0748 059A 0316 302A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062;0061 302A 0748 0316 059A 0062; # (a◌݈◌֚◌̖◌〪b; a◌〪◌݈◌̖◌֚b; a◌〪◌݈◌̖◌֚b; a◌〪◌݈◌̖◌֚b; a◌〪◌݈◌̖◌֚b; ) LATIN SMALL LETTER A, SYRIAC OBLIQUE LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0749 0062;00E0 05AE 0749 0315 0062;0061 05AE 0300 0749 0315 0062;00E0 05AE 0749 0315 0062;0061 05AE 0300 0749 0315 0062; # (a◌̕◌̀◌֮◌݉b; à◌֮◌݉◌̕b; a◌֮◌̀◌݉◌̕b; à◌֮◌݉◌̕b; a◌֮◌̀◌݉◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC MUSIC, LATIN SMALL LETTER B
+0061 0749 0315 0300 05AE 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062;0061 05AE 0749 0300 0315 0062; # (a◌݉◌̕◌̀◌֮b; a◌֮◌݉◌̀◌̕b; a◌֮◌݉◌̀◌̕b; a◌֮◌݉◌̀◌̕b; a◌֮◌݉◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC MUSIC, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 074A 0062;00E0 05AE 074A 0315 0062;0061 05AE 0300 074A 0315 0062;00E0 05AE 074A 0315 0062;0061 05AE 0300 074A 0315 0062; # (a◌̕◌̀◌֮◌݊b; à◌֮◌݊◌̕b; a◌֮◌̀◌݊◌̕b; à◌֮◌݊◌̕b; a◌֮◌̀◌݊◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SYRIAC BARREKH, LATIN SMALL LETTER B
+0061 074A 0315 0300 05AE 0062;0061 05AE 074A 0300 0315 0062;0061 05AE 074A 0300 0315 0062;0061 05AE 074A 0300 0315 0062;0061 05AE 074A 0300 0315 0062; # (a◌݊◌̕◌̀◌֮b; a◌֮◌݊◌̀◌̕b; a◌֮◌݊◌̀◌̕b; a◌֮◌݊◌̀◌̕b; a◌֮◌݊◌̀◌̕b; ) LATIN SMALL LETTER A, SYRIAC BARREKH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 07EB 0062;00E0 05AE 07EB 0315 0062;0061 05AE 0300 07EB 0315 0062;00E0 05AE 07EB 0315 0062;0061 05AE 0300 07EB 0315 0062; # (a◌̕◌̀◌֮◌߫b; à◌֮◌߫◌̕b; a◌֮◌̀◌߫◌̕b; à◌֮◌߫◌̕b; a◌֮◌̀◌߫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NKO COMBINING SHORT HIGH TONE, LATIN SMALL LETTER B
+0061 07EB 0315 0300 05AE 0062;0061 05AE 07EB 0300 0315 0062;0061 05AE 07EB 0300 0315 0062;0061 05AE 07EB 0300 0315 0062;0061 05AE 07EB 0300 0315 0062; # (a◌߫◌̕◌̀◌֮b; a◌֮◌߫◌̀◌̕b; a◌֮◌߫◌̀◌̕b; a◌֮◌߫◌̀◌̕b; a◌֮◌߫◌̀◌̕b; ) LATIN SMALL LETTER A, NKO COMBINING SHORT HIGH TONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 07EC 0062;00E0 05AE 07EC 0315 0062;0061 05AE 0300 07EC 0315 0062;00E0 05AE 07EC 0315 0062;0061 05AE 0300 07EC 0315 0062; # (a◌̕◌̀◌֮◌߬b; à◌֮◌߬◌̕b; a◌֮◌̀◌߬◌̕b; à◌֮◌߬◌̕b; a◌֮◌̀◌߬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NKO COMBINING SHORT LOW TONE, LATIN SMALL LETTER B
+0061 07EC 0315 0300 05AE 0062;0061 05AE 07EC 0300 0315 0062;0061 05AE 07EC 0300 0315 0062;0061 05AE 07EC 0300 0315 0062;0061 05AE 07EC 0300 0315 0062; # (a◌߬◌̕◌̀◌֮b; a◌֮◌߬◌̀◌̕b; a◌֮◌߬◌̀◌̕b; a◌֮◌߬◌̀◌̕b; a◌֮◌߬◌̀◌̕b; ) LATIN SMALL LETTER A, NKO COMBINING SHORT LOW TONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 07ED 0062;00E0 05AE 07ED 0315 0062;0061 05AE 0300 07ED 0315 0062;00E0 05AE 07ED 0315 0062;0061 05AE 0300 07ED 0315 0062; # (a◌̕◌̀◌֮◌߭b; à◌֮◌߭◌̕b; a◌֮◌̀◌߭◌̕b; à◌֮◌߭◌̕b; a◌֮◌̀◌߭◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NKO COMBINING SHORT RISING TONE, LATIN SMALL LETTER B
+0061 07ED 0315 0300 05AE 0062;0061 05AE 07ED 0300 0315 0062;0061 05AE 07ED 0300 0315 0062;0061 05AE 07ED 0300 0315 0062;0061 05AE 07ED 0300 0315 0062; # (a◌߭◌̕◌̀◌֮b; a◌֮◌߭◌̀◌̕b; a◌֮◌߭◌̀◌̕b; a◌֮◌߭◌̀◌̕b; a◌֮◌߭◌̀◌̕b; ) LATIN SMALL LETTER A, NKO COMBINING SHORT RISING TONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 07EE 0062;00E0 05AE 07EE 0315 0062;0061 05AE 0300 07EE 0315 0062;00E0 05AE 07EE 0315 0062;0061 05AE 0300 07EE 0315 0062; # (a◌̕◌̀◌֮◌߮b; à◌֮◌߮◌̕b; a◌֮◌̀◌߮◌̕b; à◌֮◌߮◌̕b; a◌֮◌̀◌߮◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NKO COMBINING LONG DESCENDING TONE, LATIN SMALL LETTER B
+0061 07EE 0315 0300 05AE 0062;0061 05AE 07EE 0300 0315 0062;0061 05AE 07EE 0300 0315 0062;0061 05AE 07EE 0300 0315 0062;0061 05AE 07EE 0300 0315 0062; # (a◌߮◌̕◌̀◌֮b; a◌֮◌߮◌̀◌̕b; a◌֮◌߮◌̀◌̕b; a◌֮◌߮◌̀◌̕b; a◌֮◌߮◌̀◌̕b; ) LATIN SMALL LETTER A, NKO COMBINING LONG DESCENDING TONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 07EF 0062;00E0 05AE 07EF 0315 0062;0061 05AE 0300 07EF 0315 0062;00E0 05AE 07EF 0315 0062;0061 05AE 0300 07EF 0315 0062; # (a◌̕◌̀◌֮◌߯b; à◌֮◌߯◌̕b; a◌֮◌̀◌߯◌̕b; à◌֮◌߯◌̕b; a◌֮◌̀◌߯◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NKO COMBINING LONG HIGH TONE, LATIN SMALL LETTER B
+0061 07EF 0315 0300 05AE 0062;0061 05AE 07EF 0300 0315 0062;0061 05AE 07EF 0300 0315 0062;0061 05AE 07EF 0300 0315 0062;0061 05AE 07EF 0300 0315 0062; # (a◌߯◌̕◌̀◌֮b; a◌֮◌߯◌̀◌̕b; a◌֮◌߯◌̀◌̕b; a◌֮◌߯◌̀◌̕b; a◌֮◌߯◌̀◌̕b; ) LATIN SMALL LETTER A, NKO COMBINING LONG HIGH TONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 07F0 0062;00E0 05AE 07F0 0315 0062;0061 05AE 0300 07F0 0315 0062;00E0 05AE 07F0 0315 0062;0061 05AE 0300 07F0 0315 0062; # (a◌̕◌̀◌֮◌߰b; à◌֮◌߰◌̕b; a◌֮◌̀◌߰◌̕b; à◌֮◌߰◌̕b; a◌֮◌̀◌߰◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NKO COMBINING LONG LOW TONE, LATIN SMALL LETTER B
+0061 07F0 0315 0300 05AE 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062;0061 05AE 07F0 0300 0315 0062; # (a◌߰◌̕◌̀◌֮b; a◌֮◌߰◌̀◌̕b; a◌֮◌߰◌̀◌̕b; a◌֮◌߰◌̀◌̕b; a◌֮◌߰◌̀◌̕b; ) LATIN SMALL LETTER A, NKO COMBINING LONG LOW TONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 07F1 0062;00E0 05AE 07F1 0315 0062;0061 05AE 0300 07F1 0315 0062;00E0 05AE 07F1 0315 0062;0061 05AE 0300 07F1 0315 0062; # (a◌̕◌̀◌֮◌߱b; à◌֮◌߱◌̕b; a◌֮◌̀◌߱◌̕b; à◌֮◌߱◌̕b; a◌֮◌̀◌߱◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NKO COMBINING LONG RISING TONE, LATIN SMALL LETTER B
+0061 07F1 0315 0300 05AE 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062;0061 05AE 07F1 0300 0315 0062; # (a◌߱◌̕◌̀◌֮b; a◌֮◌߱◌̀◌̕b; a◌֮◌߱◌̀◌̕b; a◌֮◌߱◌̀◌̕b; a◌֮◌߱◌̀◌̕b; ) LATIN SMALL LETTER A, NKO COMBINING LONG RISING TONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 07F2 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062;0061 302A 0316 07F2 059A 0062; # (a◌֚◌̖◌〪◌߲b; a◌〪◌̖◌߲◌֚b; a◌〪◌̖◌߲◌֚b; a◌〪◌̖◌߲◌֚b; a◌〪◌̖◌߲◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, NKO COMBINING NASALIZATION MARK, LATIN SMALL LETTER B
+0061 07F2 059A 0316 302A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062;0061 302A 07F2 0316 059A 0062; # (a◌߲◌֚◌̖◌〪b; a◌〪◌߲◌̖◌֚b; a◌〪◌߲◌̖◌֚b; a◌〪◌߲◌̖◌֚b; a◌〪◌߲◌̖◌֚b; ) LATIN SMALL LETTER A, NKO COMBINING NASALIZATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 07F3 0062;00E0 05AE 07F3 0315 0062;0061 05AE 0300 07F3 0315 0062;00E0 05AE 07F3 0315 0062;0061 05AE 0300 07F3 0315 0062; # (a◌̕◌̀◌֮◌߳b; à◌֮◌߳◌̕b; a◌֮◌̀◌߳◌̕b; à◌֮◌߳◌̕b; a◌֮◌̀◌߳◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NKO COMBINING DOUBLE DOT ABOVE, LATIN SMALL LETTER B
+0061 07F3 0315 0300 05AE 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062;0061 05AE 07F3 0300 0315 0062; # (a◌߳◌̕◌̀◌֮b; a◌֮◌߳◌̀◌̕b; a◌֮◌߳◌̀◌̕b; a◌֮◌߳◌̀◌̕b; a◌֮◌߳◌̀◌̕b; ) LATIN SMALL LETTER A, NKO COMBINING DOUBLE DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0816 0062;00E0 05AE 0816 0315 0062;0061 05AE 0300 0816 0315 0062;00E0 05AE 0816 0315 0062;0061 05AE 0300 0816 0315 0062; # (a◌̕◌̀◌֮◌ࠖb; à◌֮◌ࠖ◌̕b; a◌֮◌̀◌ࠖ◌̕b; à◌֮◌ࠖ◌̕b; a◌֮◌̀◌ࠖ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN MARK IN, LATIN SMALL LETTER B
+0061 0816 0315 0300 05AE 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062;0061 05AE 0816 0300 0315 0062; # (a◌ࠖ◌̕◌̀◌֮b; a◌֮◌ࠖ◌̀◌̕b; a◌֮◌ࠖ◌̀◌̕b; a◌֮◌ࠖ◌̀◌̕b; a◌֮◌ࠖ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN MARK IN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0817 0062;00E0 05AE 0817 0315 0062;0061 05AE 0300 0817 0315 0062;00E0 05AE 0817 0315 0062;0061 05AE 0300 0817 0315 0062; # (a◌̕◌̀◌֮◌ࠗb; à◌֮◌ࠗ◌̕b; a◌֮◌̀◌ࠗ◌̕b; à◌֮◌ࠗ◌̕b; a◌֮◌̀◌ࠗ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN MARK IN-ALAF, LATIN SMALL LETTER B
+0061 0817 0315 0300 05AE 0062;0061 05AE 0817 0300 0315 0062;0061 05AE 0817 0300 0315 0062;0061 05AE 0817 0300 0315 0062;0061 05AE 0817 0300 0315 0062; # (a◌ࠗ◌̕◌̀◌֮b; a◌֮◌ࠗ◌̀◌̕b; a◌֮◌ࠗ◌̀◌̕b; a◌֮◌ࠗ◌̀◌̕b; a◌֮◌ࠗ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN MARK IN-ALAF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0818 0062;00E0 05AE 0818 0315 0062;0061 05AE 0300 0818 0315 0062;00E0 05AE 0818 0315 0062;0061 05AE 0300 0818 0315 0062; # (a◌̕◌̀◌֮◌࠘b; à◌֮◌࠘◌̕b; a◌֮◌̀◌࠘◌̕b; à◌֮◌࠘◌̕b; a◌֮◌̀◌࠘◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN MARK OCCLUSION, LATIN SMALL LETTER B
+0061 0818 0315 0300 05AE 0062;0061 05AE 0818 0300 0315 0062;0061 05AE 0818 0300 0315 0062;0061 05AE 0818 0300 0315 0062;0061 05AE 0818 0300 0315 0062; # (a◌࠘◌̕◌̀◌֮b; a◌֮◌࠘◌̀◌̕b; a◌֮◌࠘◌̀◌̕b; a◌֮◌࠘◌̀◌̕b; a◌֮◌࠘◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN MARK OCCLUSION, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0819 0062;00E0 05AE 0819 0315 0062;0061 05AE 0300 0819 0315 0062;00E0 05AE 0819 0315 0062;0061 05AE 0300 0819 0315 0062; # (a◌̕◌̀◌֮◌࠙b; à◌֮◌࠙◌̕b; a◌֮◌̀◌࠙◌̕b; à◌֮◌࠙◌̕b; a◌֮◌̀◌࠙◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN MARK DAGESH, LATIN SMALL LETTER B
+0061 0819 0315 0300 05AE 0062;0061 05AE 0819 0300 0315 0062;0061 05AE 0819 0300 0315 0062;0061 05AE 0819 0300 0315 0062;0061 05AE 0819 0300 0315 0062; # (a◌࠙◌̕◌̀◌֮b; a◌֮◌࠙◌̀◌̕b; a◌֮◌࠙◌̀◌̕b; a◌֮◌࠙◌̀◌̕b; a◌֮◌࠙◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN MARK DAGESH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 081B 0062;00E0 05AE 081B 0315 0062;0061 05AE 0300 081B 0315 0062;00E0 05AE 081B 0315 0062;0061 05AE 0300 081B 0315 0062; # (a◌̕◌̀◌֮◌ࠛb; à◌֮◌ࠛ◌̕b; a◌֮◌̀◌ࠛ◌̕b; à◌֮◌ࠛ◌̕b; a◌֮◌̀◌ࠛ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN MARK EPENTHETIC YUT, LATIN SMALL LETTER B
+0061 081B 0315 0300 05AE 0062;0061 05AE 081B 0300 0315 0062;0061 05AE 081B 0300 0315 0062;0061 05AE 081B 0300 0315 0062;0061 05AE 081B 0300 0315 0062; # (a◌ࠛ◌̕◌̀◌֮b; a◌֮◌ࠛ◌̀◌̕b; a◌֮◌ࠛ◌̀◌̕b; a◌֮◌ࠛ◌̀◌̕b; a◌֮◌ࠛ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN MARK EPENTHETIC YUT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 081C 0062;00E0 05AE 081C 0315 0062;0061 05AE 0300 081C 0315 0062;00E0 05AE 081C 0315 0062;0061 05AE 0300 081C 0315 0062; # (a◌̕◌̀◌֮◌ࠜb; à◌֮◌ࠜ◌̕b; a◌֮◌̀◌ࠜ◌̕b; à◌֮◌ࠜ◌̕b; a◌֮◌̀◌ࠜ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN LONG E, LATIN SMALL LETTER B
+0061 081C 0315 0300 05AE 0062;0061 05AE 081C 0300 0315 0062;0061 05AE 081C 0300 0315 0062;0061 05AE 081C 0300 0315 0062;0061 05AE 081C 0300 0315 0062; # (a◌ࠜ◌̕◌̀◌֮b; a◌֮◌ࠜ◌̀◌̕b; a◌֮◌ࠜ◌̀◌̕b; a◌֮◌ࠜ◌̀◌̕b; a◌֮◌ࠜ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN LONG E, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 081D 0062;00E0 05AE 081D 0315 0062;0061 05AE 0300 081D 0315 0062;00E0 05AE 081D 0315 0062;0061 05AE 0300 081D 0315 0062; # (a◌̕◌̀◌֮◌ࠝb; à◌֮◌ࠝ◌̕b; a◌֮◌̀◌ࠝ◌̕b; à◌֮◌ࠝ◌̕b; a◌֮◌̀◌ࠝ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN E, LATIN SMALL LETTER B
+0061 081D 0315 0300 05AE 0062;0061 05AE 081D 0300 0315 0062;0061 05AE 081D 0300 0315 0062;0061 05AE 081D 0300 0315 0062;0061 05AE 081D 0300 0315 0062; # (a◌ࠝ◌̕◌̀◌֮b; a◌֮◌ࠝ◌̀◌̕b; a◌֮◌ࠝ◌̀◌̕b; a◌֮◌ࠝ◌̀◌̕b; a◌֮◌ࠝ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN E, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 081E 0062;00E0 05AE 081E 0315 0062;0061 05AE 0300 081E 0315 0062;00E0 05AE 081E 0315 0062;0061 05AE 0300 081E 0315 0062; # (a◌̕◌̀◌֮◌ࠞb; à◌֮◌ࠞ◌̕b; a◌֮◌̀◌ࠞ◌̕b; à◌֮◌ࠞ◌̕b; a◌֮◌̀◌ࠞ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN OVERLONG AA, LATIN SMALL LETTER B
+0061 081E 0315 0300 05AE 0062;0061 05AE 081E 0300 0315 0062;0061 05AE 081E 0300 0315 0062;0061 05AE 081E 0300 0315 0062;0061 05AE 081E 0300 0315 0062; # (a◌ࠞ◌̕◌̀◌֮b; a◌֮◌ࠞ◌̀◌̕b; a◌֮◌ࠞ◌̀◌̕b; a◌֮◌ࠞ◌̀◌̕b; a◌֮◌ࠞ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN OVERLONG AA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 081F 0062;00E0 05AE 081F 0315 0062;0061 05AE 0300 081F 0315 0062;00E0 05AE 081F 0315 0062;0061 05AE 0300 081F 0315 0062; # (a◌̕◌̀◌֮◌ࠟb; à◌֮◌ࠟ◌̕b; a◌֮◌̀◌ࠟ◌̕b; à◌֮◌ࠟ◌̕b; a◌֮◌̀◌ࠟ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN LONG AA, LATIN SMALL LETTER B
+0061 081F 0315 0300 05AE 0062;0061 05AE 081F 0300 0315 0062;0061 05AE 081F 0300 0315 0062;0061 05AE 081F 0300 0315 0062;0061 05AE 081F 0300 0315 0062; # (a◌ࠟ◌̕◌̀◌֮b; a◌֮◌ࠟ◌̀◌̕b; a◌֮◌ࠟ◌̀◌̕b; a◌֮◌ࠟ◌̀◌̕b; a◌֮◌ࠟ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN LONG AA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0820 0062;00E0 05AE 0820 0315 0062;0061 05AE 0300 0820 0315 0062;00E0 05AE 0820 0315 0062;0061 05AE 0300 0820 0315 0062; # (a◌̕◌̀◌֮◌ࠠb; à◌֮◌ࠠ◌̕b; a◌֮◌̀◌ࠠ◌̕b; à◌֮◌ࠠ◌̕b; a◌֮◌̀◌ࠠ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN AA, LATIN SMALL LETTER B
+0061 0820 0315 0300 05AE 0062;0061 05AE 0820 0300 0315 0062;0061 05AE 0820 0300 0315 0062;0061 05AE 0820 0300 0315 0062;0061 05AE 0820 0300 0315 0062; # (a◌ࠠ◌̕◌̀◌֮b; a◌֮◌ࠠ◌̀◌̕b; a◌֮◌ࠠ◌̀◌̕b; a◌֮◌ࠠ◌̀◌̕b; a◌֮◌ࠠ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN AA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0821 0062;00E0 05AE 0821 0315 0062;0061 05AE 0300 0821 0315 0062;00E0 05AE 0821 0315 0062;0061 05AE 0300 0821 0315 0062; # (a◌̕◌̀◌֮◌ࠡb; à◌֮◌ࠡ◌̕b; a◌֮◌̀◌ࠡ◌̕b; à◌֮◌ࠡ◌̕b; a◌֮◌̀◌ࠡ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN OVERLONG A, LATIN SMALL LETTER B
+0061 0821 0315 0300 05AE 0062;0061 05AE 0821 0300 0315 0062;0061 05AE 0821 0300 0315 0062;0061 05AE 0821 0300 0315 0062;0061 05AE 0821 0300 0315 0062; # (a◌ࠡ◌̕◌̀◌֮b; a◌֮◌ࠡ◌̀◌̕b; a◌֮◌ࠡ◌̀◌̕b; a◌֮◌ࠡ◌̀◌̕b; a◌֮◌ࠡ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN OVERLONG A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0822 0062;00E0 05AE 0822 0315 0062;0061 05AE 0300 0822 0315 0062;00E0 05AE 0822 0315 0062;0061 05AE 0300 0822 0315 0062; # (a◌̕◌̀◌֮◌ࠢb; à◌֮◌ࠢ◌̕b; a◌֮◌̀◌ࠢ◌̕b; à◌֮◌ࠢ◌̕b; a◌֮◌̀◌ࠢ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN LONG A, LATIN SMALL LETTER B
+0061 0822 0315 0300 05AE 0062;0061 05AE 0822 0300 0315 0062;0061 05AE 0822 0300 0315 0062;0061 05AE 0822 0300 0315 0062;0061 05AE 0822 0300 0315 0062; # (a◌ࠢ◌̕◌̀◌֮b; a◌֮◌ࠢ◌̀◌̕b; a◌֮◌ࠢ◌̀◌̕b; a◌֮◌ࠢ◌̀◌̕b; a◌֮◌ࠢ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN LONG A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0823 0062;00E0 05AE 0823 0315 0062;0061 05AE 0300 0823 0315 0062;00E0 05AE 0823 0315 0062;0061 05AE 0300 0823 0315 0062; # (a◌̕◌̀◌֮◌ࠣb; à◌֮◌ࠣ◌̕b; a◌֮◌̀◌ࠣ◌̕b; à◌֮◌ࠣ◌̕b; a◌֮◌̀◌ࠣ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN A, LATIN SMALL LETTER B
+0061 0823 0315 0300 05AE 0062;0061 05AE 0823 0300 0315 0062;0061 05AE 0823 0300 0315 0062;0061 05AE 0823 0300 0315 0062;0061 05AE 0823 0300 0315 0062; # (a◌ࠣ◌̕◌̀◌֮b; a◌֮◌ࠣ◌̀◌̕b; a◌֮◌ࠣ◌̀◌̕b; a◌֮◌ࠣ◌̀◌̕b; a◌֮◌ࠣ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0825 0062;00E0 05AE 0825 0315 0062;0061 05AE 0300 0825 0315 0062;00E0 05AE 0825 0315 0062;0061 05AE 0300 0825 0315 0062; # (a◌̕◌̀◌֮◌ࠥb; à◌֮◌ࠥ◌̕b; a◌֮◌̀◌ࠥ◌̕b; à◌֮◌ࠥ◌̕b; a◌֮◌̀◌ࠥ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN SHORT A, LATIN SMALL LETTER B
+0061 0825 0315 0300 05AE 0062;0061 05AE 0825 0300 0315 0062;0061 05AE 0825 0300 0315 0062;0061 05AE 0825 0300 0315 0062;0061 05AE 0825 0300 0315 0062; # (a◌ࠥ◌̕◌̀◌֮b; a◌֮◌ࠥ◌̀◌̕b; a◌֮◌ࠥ◌̀◌̕b; a◌֮◌ࠥ◌̀◌̕b; a◌֮◌ࠥ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN SHORT A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0826 0062;00E0 05AE 0826 0315 0062;0061 05AE 0300 0826 0315 0062;00E0 05AE 0826 0315 0062;0061 05AE 0300 0826 0315 0062; # (a◌̕◌̀◌֮◌ࠦb; à◌֮◌ࠦ◌̕b; a◌֮◌̀◌ࠦ◌̕b; à◌֮◌ࠦ◌̕b; a◌֮◌̀◌ࠦ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN LONG U, LATIN SMALL LETTER B
+0061 0826 0315 0300 05AE 0062;0061 05AE 0826 0300 0315 0062;0061 05AE 0826 0300 0315 0062;0061 05AE 0826 0300 0315 0062;0061 05AE 0826 0300 0315 0062; # (a◌ࠦ◌̕◌̀◌֮b; a◌֮◌ࠦ◌̀◌̕b; a◌֮◌ࠦ◌̀◌̕b; a◌֮◌ࠦ◌̀◌̕b; a◌֮◌ࠦ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN LONG U, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0827 0062;00E0 05AE 0827 0315 0062;0061 05AE 0300 0827 0315 0062;00E0 05AE 0827 0315 0062;0061 05AE 0300 0827 0315 0062; # (a◌̕◌̀◌֮◌ࠧb; à◌֮◌ࠧ◌̕b; a◌֮◌̀◌ࠧ◌̕b; à◌֮◌ࠧ◌̕b; a◌֮◌̀◌ࠧ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN U, LATIN SMALL LETTER B
+0061 0827 0315 0300 05AE 0062;0061 05AE 0827 0300 0315 0062;0061 05AE 0827 0300 0315 0062;0061 05AE 0827 0300 0315 0062;0061 05AE 0827 0300 0315 0062; # (a◌ࠧ◌̕◌̀◌֮b; a◌֮◌ࠧ◌̀◌̕b; a◌֮◌ࠧ◌̀◌̕b; a◌֮◌ࠧ◌̀◌̕b; a◌֮◌ࠧ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN U, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0829 0062;00E0 05AE 0829 0315 0062;0061 05AE 0300 0829 0315 0062;00E0 05AE 0829 0315 0062;0061 05AE 0300 0829 0315 0062; # (a◌̕◌̀◌֮◌ࠩb; à◌֮◌ࠩ◌̕b; a◌֮◌̀◌ࠩ◌̕b; à◌֮◌ࠩ◌̕b; a◌֮◌̀◌ࠩ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN LONG I, LATIN SMALL LETTER B
+0061 0829 0315 0300 05AE 0062;0061 05AE 0829 0300 0315 0062;0061 05AE 0829 0300 0315 0062;0061 05AE 0829 0300 0315 0062;0061 05AE 0829 0300 0315 0062; # (a◌ࠩ◌̕◌̀◌֮b; a◌֮◌ࠩ◌̀◌̕b; a◌֮◌ࠩ◌̀◌̕b; a◌֮◌ࠩ◌̀◌̕b; a◌֮◌ࠩ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN LONG I, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 082A 0062;00E0 05AE 082A 0315 0062;0061 05AE 0300 082A 0315 0062;00E0 05AE 082A 0315 0062;0061 05AE 0300 082A 0315 0062; # (a◌̕◌̀◌֮◌ࠪb; à◌֮◌ࠪ◌̕b; a◌֮◌̀◌ࠪ◌̕b; à◌֮◌ࠪ◌̕b; a◌֮◌̀◌ࠪ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN I, LATIN SMALL LETTER B
+0061 082A 0315 0300 05AE 0062;0061 05AE 082A 0300 0315 0062;0061 05AE 082A 0300 0315 0062;0061 05AE 082A 0300 0315 0062;0061 05AE 082A 0300 0315 0062; # (a◌ࠪ◌̕◌̀◌֮b; a◌֮◌ࠪ◌̀◌̕b; a◌֮◌ࠪ◌̀◌̕b; a◌֮◌ࠪ◌̀◌̕b; a◌֮◌ࠪ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN I, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 082B 0062;00E0 05AE 082B 0315 0062;0061 05AE 0300 082B 0315 0062;00E0 05AE 082B 0315 0062;0061 05AE 0300 082B 0315 0062; # (a◌̕◌̀◌֮◌ࠫb; à◌֮◌ࠫ◌̕b; a◌֮◌̀◌ࠫ◌̕b; à◌֮◌ࠫ◌̕b; a◌֮◌̀◌ࠫ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN O, LATIN SMALL LETTER B
+0061 082B 0315 0300 05AE 0062;0061 05AE 082B 0300 0315 0062;0061 05AE 082B 0300 0315 0062;0061 05AE 082B 0300 0315 0062;0061 05AE 082B 0300 0315 0062; # (a◌ࠫ◌̕◌̀◌֮b; a◌֮◌ࠫ◌̀◌̕b; a◌֮◌ࠫ◌̀◌̕b; a◌֮◌ࠫ◌̀◌̕b; a◌֮◌ࠫ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN O, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 082C 0062;00E0 05AE 082C 0315 0062;0061 05AE 0300 082C 0315 0062;00E0 05AE 082C 0315 0062;0061 05AE 0300 082C 0315 0062; # (a◌̕◌̀◌֮◌ࠬb; à◌֮◌ࠬ◌̕b; a◌֮◌̀◌ࠬ◌̕b; à◌֮◌ࠬ◌̕b; a◌֮◌̀◌ࠬ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN VOWEL SIGN SUKUN, LATIN SMALL LETTER B
+0061 082C 0315 0300 05AE 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062;0061 05AE 082C 0300 0315 0062; # (a◌ࠬ◌̕◌̀◌֮b; a◌֮◌ࠬ◌̀◌̕b; a◌֮◌ࠬ◌̀◌̕b; a◌֮◌ࠬ◌̀◌̕b; a◌֮◌ࠬ◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN VOWEL SIGN SUKUN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 082D 0062;00E0 05AE 082D 0315 0062;0061 05AE 0300 082D 0315 0062;00E0 05AE 082D 0315 0062;0061 05AE 0300 082D 0315 0062; # (a◌̕◌̀◌֮◌࠭b; à◌֮◌࠭◌̕b; a◌֮◌̀◌࠭◌̕b; à◌֮◌࠭◌̕b; a◌֮◌̀◌࠭◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, SAMARITAN MARK NEQUDAA, LATIN SMALL LETTER B
+0061 082D 0315 0300 05AE 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062;0061 05AE 082D 0300 0315 0062; # (a◌࠭◌̕◌̀◌֮b; a◌֮◌࠭◌̀◌̕b; a◌֮◌࠭◌̀◌̕b; a◌֮◌࠭◌̀◌̕b; a◌֮◌࠭◌̀◌̕b; ) LATIN SMALL LETTER A, SAMARITAN MARK NEQUDAA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0859 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062;0061 302A 0316 0859 059A 0062; # (a◌֚◌̖◌〪◌࡙b; a◌〪◌̖◌࡙◌֚b; a◌〪◌̖◌࡙◌֚b; a◌〪◌̖◌࡙◌֚b; a◌〪◌̖◌࡙◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MANDAIC AFFRICATION MARK, LATIN SMALL LETTER B
+0061 0859 059A 0316 302A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062;0061 302A 0859 0316 059A 0062; # (a◌࡙◌֚◌̖◌〪b; a◌〪◌࡙◌̖◌֚b; a◌〪◌࡙◌̖◌֚b; a◌〪◌࡙◌̖◌֚b; a◌〪◌࡙◌̖◌֚b; ) LATIN SMALL LETTER A, MANDAIC AFFRICATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 085A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062;0061 302A 0316 085A 059A 0062; # (a◌֚◌̖◌〪◌࡚b; a◌〪◌̖◌࡚◌֚b; a◌〪◌̖◌࡚◌֚b; a◌〪◌̖◌࡚◌֚b; a◌〪◌̖◌࡚◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MANDAIC VOCALIZATION MARK, LATIN SMALL LETTER B
+0061 085A 059A 0316 302A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062;0061 302A 085A 0316 059A 0062; # (a◌࡚◌֚◌̖◌〪b; a◌〪◌࡚◌̖◌֚b; a◌〪◌࡚◌̖◌֚b; a◌〪◌࡚◌̖◌֚b; a◌〪◌࡚◌̖◌֚b; ) LATIN SMALL LETTER A, MANDAIC VOCALIZATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 085B 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062;0061 302A 0316 085B 059A 0062; # (a◌֚◌̖◌〪◌࡛b; a◌〪◌̖◌࡛◌֚b; a◌〪◌̖◌࡛◌֚b; a◌〪◌̖◌࡛◌֚b; a◌〪◌̖◌࡛◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MANDAIC GEMINATION MARK, LATIN SMALL LETTER B
+0061 085B 059A 0316 302A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062;0061 302A 085B 0316 059A 0062; # (a◌࡛◌֚◌̖◌〪b; a◌〪◌࡛◌̖◌֚b; a◌〪◌࡛◌̖◌֚b; a◌〪◌࡛◌̖◌֚b; a◌〪◌࡛◌̖◌֚b; ) LATIN SMALL LETTER A, MANDAIC GEMINATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08D4 0062;00E0 05AE 08D4 0315 0062;0061 05AE 0300 08D4 0315 0062;00E0 05AE 08D4 0315 0062;0061 05AE 0300 08D4 0315 0062; # (a◌̕◌̀◌֮◌ࣔb; à◌֮◌ࣔ◌̕b; a◌֮◌̀◌ࣔ◌̕b; à◌֮◌ࣔ◌̕b; a◌֮◌̀◌ࣔ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WORD AR-RUB, LATIN SMALL LETTER B
+0061 08D4 0315 0300 05AE 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062;0061 05AE 08D4 0300 0315 0062; # (a◌ࣔ◌̕◌̀◌֮b; a◌֮◌ࣔ◌̀◌̕b; a◌֮◌ࣔ◌̀◌̕b; a◌֮◌ࣔ◌̀◌̕b; a◌֮◌ࣔ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WORD AR-RUB, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08D5 0062;00E0 05AE 08D5 0315 0062;0061 05AE 0300 08D5 0315 0062;00E0 05AE 08D5 0315 0062;0061 05AE 0300 08D5 0315 0062; # (a◌̕◌̀◌֮◌ࣕb; à◌֮◌ࣕ◌̕b; a◌֮◌̀◌ࣕ◌̕b; à◌֮◌ࣕ◌̕b; a◌֮◌̀◌ࣕ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH SAD, LATIN SMALL LETTER B
+0061 08D5 0315 0300 05AE 0062;0061 05AE 08D5 0300 0315 0062;0061 05AE 08D5 0300 0315 0062;0061 05AE 08D5 0300 0315 0062;0061 05AE 08D5 0300 0315 0062; # (a◌ࣕ◌̕◌̀◌֮b; a◌֮◌ࣕ◌̀◌̕b; a◌֮◌ࣕ◌̀◌̕b; a◌֮◌ࣕ◌̀◌̕b; a◌֮◌ࣕ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH SAD, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08D6 0062;00E0 05AE 08D6 0315 0062;0061 05AE 0300 08D6 0315 0062;00E0 05AE 08D6 0315 0062;0061 05AE 0300 08D6 0315 0062; # (a◌̕◌̀◌֮◌ࣖb; à◌֮◌ࣖ◌̕b; a◌֮◌̀◌ࣖ◌̕b; à◌֮◌ࣖ◌̕b; a◌֮◌̀◌ࣖ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH AIN, LATIN SMALL LETTER B
+0061 08D6 0315 0300 05AE 0062;0061 05AE 08D6 0300 0315 0062;0061 05AE 08D6 0300 0315 0062;0061 05AE 08D6 0300 0315 0062;0061 05AE 08D6 0300 0315 0062; # (a◌ࣖ◌̕◌̀◌֮b; a◌֮◌ࣖ◌̀◌̕b; a◌֮◌ࣖ◌̀◌̕b; a◌֮◌ࣖ◌̀◌̕b; a◌֮◌ࣖ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH AIN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08D7 0062;00E0 05AE 08D7 0315 0062;0061 05AE 0300 08D7 0315 0062;00E0 05AE 08D7 0315 0062;0061 05AE 0300 08D7 0315 0062; # (a◌̕◌̀◌֮◌ࣗb; à◌֮◌ࣗ◌̕b; a◌֮◌̀◌ࣗ◌̕b; à◌֮◌ࣗ◌̕b; a◌֮◌̀◌ࣗ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH QAF, LATIN SMALL LETTER B
+0061 08D7 0315 0300 05AE 0062;0061 05AE 08D7 0300 0315 0062;0061 05AE 08D7 0300 0315 0062;0061 05AE 08D7 0300 0315 0062;0061 05AE 08D7 0300 0315 0062; # (a◌ࣗ◌̕◌̀◌֮b; a◌֮◌ࣗ◌̀◌̕b; a◌֮◌ࣗ◌̀◌̕b; a◌֮◌ࣗ◌̀◌̕b; a◌֮◌ࣗ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH QAF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08D8 0062;00E0 05AE 08D8 0315 0062;0061 05AE 0300 08D8 0315 0062;00E0 05AE 08D8 0315 0062;0061 05AE 0300 08D8 0315 0062; # (a◌̕◌̀◌֮◌ࣘb; à◌֮◌ࣘ◌̕b; a◌֮◌̀◌ࣘ◌̕b; à◌֮◌ࣘ◌̕b; a◌֮◌̀◌ࣘ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH NOON WITH KASRA, LATIN SMALL LETTER B
+0061 08D8 0315 0300 05AE 0062;0061 05AE 08D8 0300 0315 0062;0061 05AE 08D8 0300 0315 0062;0061 05AE 08D8 0300 0315 0062;0061 05AE 08D8 0300 0315 0062; # (a◌ࣘ◌̕◌̀◌֮b; a◌֮◌ࣘ◌̀◌̕b; a◌֮◌ࣘ◌̀◌̕b; a◌֮◌ࣘ◌̀◌̕b; a◌֮◌ࣘ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH NOON WITH KASRA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08D9 0062;00E0 05AE 08D9 0315 0062;0061 05AE 0300 08D9 0315 0062;00E0 05AE 08D9 0315 0062;0061 05AE 0300 08D9 0315 0062; # (a◌̕◌̀◌֮◌ࣙb; à◌֮◌ࣙ◌̕b; a◌֮◌̀◌ࣙ◌̕b; à◌֮◌ࣙ◌̕b; a◌֮◌̀◌ࣙ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL LOW NOON WITH KASRA, LATIN SMALL LETTER B
+0061 08D9 0315 0300 05AE 0062;0061 05AE 08D9 0300 0315 0062;0061 05AE 08D9 0300 0315 0062;0061 05AE 08D9 0300 0315 0062;0061 05AE 08D9 0300 0315 0062; # (a◌ࣙ◌̕◌̀◌֮b; a◌֮◌ࣙ◌̀◌̕b; a◌֮◌ࣙ◌̀◌̕b; a◌֮◌ࣙ◌̀◌̕b; a◌֮◌ࣙ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW NOON WITH KASRA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08DA 0062;00E0 05AE 08DA 0315 0062;0061 05AE 0300 08DA 0315 0062;00E0 05AE 08DA 0315 0062;0061 05AE 0300 08DA 0315 0062; # (a◌̕◌̀◌֮◌ࣚb; à◌֮◌ࣚ◌̕b; a◌֮◌̀◌ࣚ◌̕b; à◌֮◌ࣚ◌̕b; a◌֮◌̀◌ࣚ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WORD ATH-THALATHA, LATIN SMALL LETTER B
+0061 08DA 0315 0300 05AE 0062;0061 05AE 08DA 0300 0315 0062;0061 05AE 08DA 0300 0315 0062;0061 05AE 08DA 0300 0315 0062;0061 05AE 08DA 0300 0315 0062; # (a◌ࣚ◌̕◌̀◌֮b; a◌֮◌ࣚ◌̀◌̕b; a◌֮◌ࣚ◌̀◌̕b; a◌֮◌ࣚ◌̀◌̕b; a◌֮◌ࣚ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WORD ATH-THALATHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08DB 0062;00E0 05AE 08DB 0315 0062;0061 05AE 0300 08DB 0315 0062;00E0 05AE 08DB 0315 0062;0061 05AE 0300 08DB 0315 0062; # (a◌̕◌̀◌֮◌ࣛb; à◌֮◌ࣛ◌̕b; a◌֮◌̀◌ࣛ◌̕b; à◌֮◌ࣛ◌̕b; a◌֮◌̀◌ࣛ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WORD AS-SAJDA, LATIN SMALL LETTER B
+0061 08DB 0315 0300 05AE 0062;0061 05AE 08DB 0300 0315 0062;0061 05AE 08DB 0300 0315 0062;0061 05AE 08DB 0300 0315 0062;0061 05AE 08DB 0300 0315 0062; # (a◌ࣛ◌̕◌̀◌֮b; a◌֮◌ࣛ◌̀◌̕b; a◌֮◌ࣛ◌̀◌̕b; a◌֮◌ࣛ◌̀◌̕b; a◌֮◌ࣛ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WORD AS-SAJDA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08DC 0062;00E0 05AE 08DC 0315 0062;0061 05AE 0300 08DC 0315 0062;00E0 05AE 08DC 0315 0062;0061 05AE 0300 08DC 0315 0062; # (a◌̕◌̀◌֮◌ࣜb; à◌֮◌ࣜ◌̕b; a◌֮◌̀◌ࣜ◌̕b; à◌֮◌ࣜ◌̕b; a◌֮◌̀◌ࣜ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WORD AN-NISF, LATIN SMALL LETTER B
+0061 08DC 0315 0300 05AE 0062;0061 05AE 08DC 0300 0315 0062;0061 05AE 08DC 0300 0315 0062;0061 05AE 08DC 0300 0315 0062;0061 05AE 08DC 0300 0315 0062; # (a◌ࣜ◌̕◌̀◌֮b; a◌֮◌ࣜ◌̀◌̕b; a◌֮◌ࣜ◌̀◌̕b; a◌֮◌ࣜ◌̀◌̕b; a◌֮◌ࣜ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WORD AN-NISF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08DD 0062;00E0 05AE 08DD 0315 0062;0061 05AE 0300 08DD 0315 0062;00E0 05AE 08DD 0315 0062;0061 05AE 0300 08DD 0315 0062; # (a◌̕◌̀◌֮◌ࣝb; à◌֮◌ࣝ◌̕b; a◌֮◌̀◌ࣝ◌̕b; à◌֮◌ࣝ◌̕b; a◌֮◌̀◌ࣝ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WORD SAKTA, LATIN SMALL LETTER B
+0061 08DD 0315 0300 05AE 0062;0061 05AE 08DD 0300 0315 0062;0061 05AE 08DD 0300 0315 0062;0061 05AE 08DD 0300 0315 0062;0061 05AE 08DD 0300 0315 0062; # (a◌ࣝ◌̕◌̀◌֮b; a◌֮◌ࣝ◌̀◌̕b; a◌֮◌ࣝ◌̀◌̕b; a◌֮◌ࣝ◌̀◌̕b; a◌֮◌ࣝ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WORD SAKTA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08DE 0062;00E0 05AE 08DE 0315 0062;0061 05AE 0300 08DE 0315 0062;00E0 05AE 08DE 0315 0062;0061 05AE 0300 08DE 0315 0062; # (a◌̕◌̀◌֮◌ࣞb; à◌֮◌ࣞ◌̕b; a◌֮◌̀◌ࣞ◌̕b; à◌֮◌ࣞ◌̕b; a◌֮◌̀◌ࣞ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WORD QIF, LATIN SMALL LETTER B
+0061 08DE 0315 0300 05AE 0062;0061 05AE 08DE 0300 0315 0062;0061 05AE 08DE 0300 0315 0062;0061 05AE 08DE 0300 0315 0062;0061 05AE 08DE 0300 0315 0062; # (a◌ࣞ◌̕◌̀◌֮b; a◌֮◌ࣞ◌̀◌̕b; a◌֮◌ࣞ◌̀◌̕b; a◌֮◌ࣞ◌̀◌̕b; a◌֮◌ࣞ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WORD QIF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08DF 0062;00E0 05AE 08DF 0315 0062;0061 05AE 0300 08DF 0315 0062;00E0 05AE 08DF 0315 0062;0061 05AE 0300 08DF 0315 0062; # (a◌̕◌̀◌֮◌ࣟb; à◌֮◌ࣟ◌̕b; a◌֮◌̀◌ࣟ◌̕b; à◌֮◌ࣟ◌̕b; a◌֮◌̀◌ࣟ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WORD WAQFA, LATIN SMALL LETTER B
+0061 08DF 0315 0300 05AE 0062;0061 05AE 08DF 0300 0315 0062;0061 05AE 08DF 0300 0315 0062;0061 05AE 08DF 0300 0315 0062;0061 05AE 08DF 0300 0315 0062; # (a◌ࣟ◌̕◌̀◌֮b; a◌֮◌ࣟ◌̀◌̕b; a◌֮◌ࣟ◌̀◌̕b; a◌֮◌ࣟ◌̀◌̕b; a◌֮◌ࣟ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WORD WAQFA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08E0 0062;00E0 05AE 08E0 0315 0062;0061 05AE 0300 08E0 0315 0062;00E0 05AE 08E0 0315 0062;0061 05AE 0300 08E0 0315 0062; # (a◌̕◌̀◌֮◌࣠b; à◌֮◌࣠◌̕b; a◌֮◌̀◌࣠◌̕b; à◌֮◌࣠◌̕b; a◌֮◌̀◌࣠◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH FOOTNOTE MARKER, LATIN SMALL LETTER B
+0061 08E0 0315 0300 05AE 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062;0061 05AE 08E0 0300 0315 0062; # (a◌࣠◌̕◌̀◌֮b; a◌֮◌࣠◌̀◌̕b; a◌֮◌࣠◌̀◌̕b; a◌֮◌࣠◌̀◌̕b; a◌֮◌࣠◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH FOOTNOTE MARKER, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08E1 0062;00E0 05AE 08E1 0315 0062;0061 05AE 0300 08E1 0315 0062;00E0 05AE 08E1 0315 0062;0061 05AE 0300 08E1 0315 0062; # (a◌̕◌̀◌֮◌࣡b; à◌֮◌࣡◌̕b; a◌֮◌̀◌࣡◌̕b; à◌֮◌࣡◌̕b; a◌֮◌̀◌࣡◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH SIGN SAFHA, LATIN SMALL LETTER B
+0061 08E1 0315 0300 05AE 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062;0061 05AE 08E1 0300 0315 0062; # (a◌࣡◌̕◌̀◌֮b; a◌֮◌࣡◌̀◌̕b; a◌֮◌࣡◌̀◌̕b; a◌֮◌࣡◌̀◌̕b; a◌֮◌࣡◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH SIGN SAFHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 08E3 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062;0061 302A 0316 08E3 059A 0062; # (a◌֚◌̖◌〪◌ࣣb; a◌〪◌̖◌ࣣ◌֚b; a◌〪◌̖◌ࣣ◌֚b; a◌〪◌̖◌ࣣ◌֚b; a◌〪◌̖◌ࣣ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC TURNED DAMMA BELOW, LATIN SMALL LETTER B
+0061 08E3 059A 0316 302A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062;0061 302A 08E3 0316 059A 0062; # (a◌ࣣ◌֚◌̖◌〪b; a◌〪◌ࣣ◌̖◌֚b; a◌〪◌ࣣ◌̖◌֚b; a◌〪◌ࣣ◌̖◌֚b; a◌〪◌ࣣ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TURNED DAMMA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08E4 0062;00E0 05AE 08E4 0315 0062;0061 05AE 0300 08E4 0315 0062;00E0 05AE 08E4 0315 0062;0061 05AE 0300 08E4 0315 0062; # (a◌̕◌̀◌֮◌ࣤb; à◌֮◌ࣤ◌̕b; a◌֮◌̀◌ࣤ◌̕b; à◌֮◌ࣤ◌̕b; a◌֮◌̀◌ࣤ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC CURLY FATHA, LATIN SMALL LETTER B
+0061 08E4 0315 0300 05AE 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062;0061 05AE 08E4 0300 0315 0062; # (a◌ࣤ◌̕◌̀◌֮b; a◌֮◌ࣤ◌̀◌̕b; a◌֮◌ࣤ◌̀◌̕b; a◌֮◌ࣤ◌̀◌̕b; a◌֮◌ࣤ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC CURLY FATHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08E5 0062;00E0 05AE 08E5 0315 0062;0061 05AE 0300 08E5 0315 0062;00E0 05AE 08E5 0315 0062;0061 05AE 0300 08E5 0315 0062; # (a◌̕◌̀◌֮◌ࣥb; à◌֮◌ࣥ◌̕b; a◌֮◌̀◌ࣥ◌̕b; à◌֮◌ࣥ◌̕b; a◌֮◌̀◌ࣥ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC CURLY DAMMA, LATIN SMALL LETTER B
+0061 08E5 0315 0300 05AE 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062;0061 05AE 08E5 0300 0315 0062; # (a◌ࣥ◌̕◌̀◌֮b; a◌֮◌ࣥ◌̀◌̕b; a◌֮◌ࣥ◌̀◌̕b; a◌֮◌ࣥ◌̀◌̕b; a◌֮◌ࣥ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC CURLY DAMMA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 08E6 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062;0061 302A 0316 08E6 059A 0062; # (a◌֚◌̖◌〪◌ࣦb; a◌〪◌̖◌ࣦ◌֚b; a◌〪◌̖◌ࣦ◌֚b; a◌〪◌̖◌ࣦ◌֚b; a◌〪◌̖◌ࣦ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC CURLY KASRA, LATIN SMALL LETTER B
+0061 08E6 059A 0316 302A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062;0061 302A 08E6 0316 059A 0062; # (a◌ࣦ◌֚◌̖◌〪b; a◌〪◌ࣦ◌̖◌֚b; a◌〪◌ࣦ◌̖◌֚b; a◌〪◌ࣦ◌̖◌֚b; a◌〪◌ࣦ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC CURLY KASRA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08E7 0062;00E0 05AE 08E7 0315 0062;0061 05AE 0300 08E7 0315 0062;00E0 05AE 08E7 0315 0062;0061 05AE 0300 08E7 0315 0062; # (a◌̕◌̀◌֮◌ࣧb; à◌֮◌ࣧ◌̕b; a◌֮◌̀◌ࣧ◌̕b; à◌֮◌ࣧ◌̕b; a◌֮◌̀◌ࣧ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC CURLY FATHATAN, LATIN SMALL LETTER B
+0061 08E7 0315 0300 05AE 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062;0061 05AE 08E7 0300 0315 0062; # (a◌ࣧ◌̕◌̀◌֮b; a◌֮◌ࣧ◌̀◌̕b; a◌֮◌ࣧ◌̀◌̕b; a◌֮◌ࣧ◌̀◌̕b; a◌֮◌ࣧ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC CURLY FATHATAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08E8 0062;00E0 05AE 08E8 0315 0062;0061 05AE 0300 08E8 0315 0062;00E0 05AE 08E8 0315 0062;0061 05AE 0300 08E8 0315 0062; # (a◌̕◌̀◌֮◌ࣨb; à◌֮◌ࣨ◌̕b; a◌֮◌̀◌ࣨ◌̕b; à◌֮◌ࣨ◌̕b; a◌֮◌̀◌ࣨ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC CURLY DAMMATAN, LATIN SMALL LETTER B
+0061 08E8 0315 0300 05AE 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062;0061 05AE 08E8 0300 0315 0062; # (a◌ࣨ◌̕◌̀◌֮b; a◌֮◌ࣨ◌̀◌̕b; a◌֮◌ࣨ◌̀◌̕b; a◌֮◌ࣨ◌̀◌̕b; a◌֮◌ࣨ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC CURLY DAMMATAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 08E9 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062;0061 302A 0316 08E9 059A 0062; # (a◌֚◌̖◌〪◌ࣩb; a◌〪◌̖◌ࣩ◌֚b; a◌〪◌̖◌ࣩ◌֚b; a◌〪◌̖◌ࣩ◌֚b; a◌〪◌̖◌ࣩ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC CURLY KASRATAN, LATIN SMALL LETTER B
+0061 08E9 059A 0316 302A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062;0061 302A 08E9 0316 059A 0062; # (a◌ࣩ◌֚◌̖◌〪b; a◌〪◌ࣩ◌̖◌֚b; a◌〪◌ࣩ◌̖◌֚b; a◌〪◌ࣩ◌̖◌֚b; a◌〪◌ࣩ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC CURLY KASRATAN, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08EA 0062;00E0 05AE 08EA 0315 0062;0061 05AE 0300 08EA 0315 0062;00E0 05AE 08EA 0315 0062;0061 05AE 0300 08EA 0315 0062; # (a◌̕◌̀◌֮◌࣪b; à◌֮◌࣪◌̕b; a◌֮◌̀◌࣪◌̕b; à◌֮◌࣪◌̕b; a◌֮◌̀◌࣪◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC TONE ONE DOT ABOVE, LATIN SMALL LETTER B
+0061 08EA 0315 0300 05AE 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062;0061 05AE 08EA 0300 0315 0062; # (a◌࣪◌̕◌̀◌֮b; a◌֮◌࣪◌̀◌̕b; a◌֮◌࣪◌̀◌̕b; a◌֮◌࣪◌̀◌̕b; a◌֮◌࣪◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC TONE ONE DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08EB 0062;00E0 05AE 08EB 0315 0062;0061 05AE 0300 08EB 0315 0062;00E0 05AE 08EB 0315 0062;0061 05AE 0300 08EB 0315 0062; # (a◌̕◌̀◌֮◌࣫b; à◌֮◌࣫◌̕b; a◌֮◌̀◌࣫◌̕b; à◌֮◌࣫◌̕b; a◌֮◌̀◌࣫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC TONE TWO DOTS ABOVE, LATIN SMALL LETTER B
+0061 08EB 0315 0300 05AE 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062;0061 05AE 08EB 0300 0315 0062; # (a◌࣫◌̕◌̀◌֮b; a◌֮◌࣫◌̀◌̕b; a◌֮◌࣫◌̀◌̕b; a◌֮◌࣫◌̀◌̕b; a◌֮◌࣫◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC TONE TWO DOTS ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08EC 0062;00E0 05AE 08EC 0315 0062;0061 05AE 0300 08EC 0315 0062;00E0 05AE 08EC 0315 0062;0061 05AE 0300 08EC 0315 0062; # (a◌̕◌̀◌֮◌࣬b; à◌֮◌࣬◌̕b; a◌֮◌̀◌࣬◌̕b; à◌֮◌࣬◌̕b; a◌֮◌̀◌࣬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC TONE LOOP ABOVE, LATIN SMALL LETTER B
+0061 08EC 0315 0300 05AE 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062;0061 05AE 08EC 0300 0315 0062; # (a◌࣬◌̕◌̀◌֮b; a◌֮◌࣬◌̀◌̕b; a◌֮◌࣬◌̀◌̕b; a◌֮◌࣬◌̀◌̕b; a◌֮◌࣬◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC TONE LOOP ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 08ED 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062;0061 302A 0316 08ED 059A 0062; # (a◌֚◌̖◌〪◌࣭b; a◌〪◌̖◌࣭◌֚b; a◌〪◌̖◌࣭◌֚b; a◌〪◌̖◌࣭◌֚b; a◌〪◌̖◌࣭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC TONE ONE DOT BELOW, LATIN SMALL LETTER B
+0061 08ED 059A 0316 302A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062;0061 302A 08ED 0316 059A 0062; # (a◌࣭◌֚◌̖◌〪b; a◌〪◌࣭◌̖◌֚b; a◌〪◌࣭◌̖◌֚b; a◌〪◌࣭◌̖◌֚b; a◌〪◌࣭◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TONE ONE DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 08EE 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062;0061 302A 0316 08EE 059A 0062; # (a◌֚◌̖◌〪◌࣮b; a◌〪◌̖◌࣮◌֚b; a◌〪◌̖◌࣮◌֚b; a◌〪◌̖◌࣮◌֚b; a◌〪◌̖◌࣮◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC TONE TWO DOTS BELOW, LATIN SMALL LETTER B
+0061 08EE 059A 0316 302A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062;0061 302A 08EE 0316 059A 0062; # (a◌࣮◌֚◌̖◌〪b; a◌〪◌࣮◌̖◌֚b; a◌〪◌࣮◌̖◌֚b; a◌〪◌࣮◌̖◌֚b; a◌〪◌࣮◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TONE TWO DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 08EF 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062;0061 302A 0316 08EF 059A 0062; # (a◌֚◌̖◌〪◌࣯b; a◌〪◌̖◌࣯◌֚b; a◌〪◌̖◌࣯◌֚b; a◌〪◌̖◌࣯◌֚b; a◌〪◌̖◌࣯◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC TONE LOOP BELOW, LATIN SMALL LETTER B
+0061 08EF 059A 0316 302A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062;0061 302A 08EF 0316 059A 0062; # (a◌࣯◌֚◌̖◌〪b; a◌〪◌࣯◌̖◌֚b; a◌〪◌࣯◌̖◌֚b; a◌〪◌࣯◌̖◌֚b; a◌〪◌࣯◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC TONE LOOP BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 064C 064B FB1E 08F0 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062;0061 FB1E 064B 08F0 064C 0062; # (a◌ٌ◌ً◌ﬞ◌ࣰb; a◌ﬞ◌ً◌ࣰ◌ٌb; a◌ﬞ◌ً◌ࣰ◌ٌb; a◌ﬞ◌ً◌ࣰ◌ٌb; a◌ﬞ◌ً◌ࣰ◌ٌb; ) LATIN SMALL LETTER A, ARABIC DAMMATAN, ARABIC FATHATAN, HEBREW POINT JUDEO-SPANISH VARIKA, ARABIC OPEN FATHATAN, LATIN SMALL LETTER B
+0061 08F0 064C 064B FB1E 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062;0061 FB1E 08F0 064B 064C 0062; # (a◌ࣰ◌ٌ◌ً◌ﬞb; a◌ﬞ◌ࣰ◌ً◌ٌb; a◌ﬞ◌ࣰ◌ً◌ٌb; a◌ﬞ◌ࣰ◌ً◌ٌb; a◌ﬞ◌ࣰ◌ً◌ٌb; ) LATIN SMALL LETTER A, ARABIC OPEN FATHATAN, ARABIC DAMMATAN, ARABIC FATHATAN, HEBREW POINT JUDEO-SPANISH VARIKA, LATIN SMALL LETTER B
+0061 064D 064C 064B 08F1 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062;0061 064B 064C 08F1 064D 0062; # (a◌ٍ◌ٌ◌ً◌ࣱb; a◌ً◌ٌ◌ࣱ◌ٍb; a◌ً◌ٌ◌ࣱ◌ٍb; a◌ً◌ٌ◌ࣱ◌ٍb; a◌ً◌ٌ◌ࣱ◌ٍb; ) LATIN SMALL LETTER A, ARABIC KASRATAN, ARABIC DAMMATAN, ARABIC FATHATAN, ARABIC OPEN DAMMATAN, LATIN SMALL LETTER B
+0061 08F1 064D 064C 064B 0062;0061 064B 08F1 064C 064D 0062;0061 064B 08F1 064C 064D 0062;0061 064B 08F1 064C 064D 0062;0061 064B 08F1 064C 064D 0062; # (a◌ࣱ◌ٍ◌ٌ◌ًb; a◌ً◌ࣱ◌ٌ◌ٍb; a◌ً◌ࣱ◌ٌ◌ٍb; a◌ً◌ࣱ◌ٌ◌ٍb; a◌ً◌ࣱ◌ٌ◌ٍb; ) LATIN SMALL LETTER A, ARABIC OPEN DAMMATAN, ARABIC KASRATAN, ARABIC DAMMATAN, ARABIC FATHATAN, LATIN SMALL LETTER B
+0061 0618 064D 064C 08F2 0062;0061 064C 064D 08F2 0618 0062;0061 064C 064D 08F2 0618 0062;0061 064C 064D 08F2 0618 0062;0061 064C 064D 08F2 0618 0062; # (a◌ؘ◌ٍ◌ٌ◌ࣲb; a◌ٌ◌ٍ◌ࣲ◌ؘb; a◌ٌ◌ٍ◌ࣲ◌ؘb; a◌ٌ◌ٍ◌ࣲ◌ؘb; a◌ٌ◌ٍ◌ࣲ◌ؘb; ) LATIN SMALL LETTER A, ARABIC SMALL FATHA, ARABIC KASRATAN, ARABIC DAMMATAN, ARABIC OPEN KASRATAN, LATIN SMALL LETTER B
+0061 08F2 0618 064D 064C 0062;0061 064C 08F2 064D 0618 0062;0061 064C 08F2 064D 0618 0062;0061 064C 08F2 064D 0618 0062;0061 064C 08F2 064D 0618 0062; # (a◌ࣲ◌ؘ◌ٍ◌ٌb; a◌ٌ◌ࣲ◌ٍ◌ؘb; a◌ٌ◌ࣲ◌ٍ◌ؘb; a◌ٌ◌ࣲ◌ٍ◌ؘb; a◌ٌ◌ࣲ◌ٍ◌ؘb; ) LATIN SMALL LETTER A, ARABIC OPEN KASRATAN, ARABIC SMALL FATHA, ARABIC KASRATAN, ARABIC DAMMATAN, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08F3 0062;00E0 05AE 08F3 0315 0062;0061 05AE 0300 08F3 0315 0062;00E0 05AE 08F3 0315 0062;0061 05AE 0300 08F3 0315 0062; # (a◌̕◌̀◌֮◌ࣳb; à◌֮◌ࣳ◌̕b; a◌֮◌̀◌ࣳ◌̕b; à◌֮◌ࣳ◌̕b; a◌֮◌̀◌ࣳ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WAW, LATIN SMALL LETTER B
+0061 08F3 0315 0300 05AE 0062;0061 05AE 08F3 0300 0315 0062;0061 05AE 08F3 0300 0315 0062;0061 05AE 08F3 0300 0315 0062;0061 05AE 08F3 0300 0315 0062; # (a◌ࣳ◌̕◌̀◌֮b; a◌֮◌ࣳ◌̀◌̕b; a◌֮◌ࣳ◌̀◌̕b; a◌֮◌ࣳ◌̀◌̕b; a◌֮◌ࣳ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WAW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08F4 0062;00E0 05AE 08F4 0315 0062;0061 05AE 0300 08F4 0315 0062;00E0 05AE 08F4 0315 0062;0061 05AE 0300 08F4 0315 0062; # (a◌̕◌̀◌֮◌ࣴb; à◌֮◌ࣴ◌̕b; a◌֮◌̀◌ࣴ◌̕b; à◌֮◌ࣴ◌̕b; a◌֮◌̀◌ࣴ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC FATHA WITH RING, LATIN SMALL LETTER B
+0061 08F4 0315 0300 05AE 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062;0061 05AE 08F4 0300 0315 0062; # (a◌ࣴ◌̕◌̀◌֮b; a◌֮◌ࣴ◌̀◌̕b; a◌֮◌ࣴ◌̀◌̕b; a◌֮◌ࣴ◌̀◌̕b; a◌֮◌ࣴ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC FATHA WITH RING, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08F5 0062;00E0 05AE 08F5 0315 0062;0061 05AE 0300 08F5 0315 0062;00E0 05AE 08F5 0315 0062;0061 05AE 0300 08F5 0315 0062; # (a◌̕◌̀◌֮◌ࣵb; à◌֮◌ࣵ◌̕b; a◌֮◌̀◌ࣵ◌̕b; à◌֮◌ࣵ◌̕b; a◌֮◌̀◌ࣵ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC FATHA WITH DOT ABOVE, LATIN SMALL LETTER B
+0061 08F5 0315 0300 05AE 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062;0061 05AE 08F5 0300 0315 0062; # (a◌ࣵ◌̕◌̀◌֮b; a◌֮◌ࣵ◌̀◌̕b; a◌֮◌ࣵ◌̀◌̕b; a◌֮◌ࣵ◌̀◌̕b; a◌֮◌ࣵ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC FATHA WITH DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 08F6 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062;0061 302A 0316 08F6 059A 0062; # (a◌֚◌̖◌〪◌ࣶb; a◌〪◌̖◌ࣶ◌֚b; a◌〪◌̖◌ࣶ◌֚b; a◌〪◌̖◌ࣶ◌֚b; a◌〪◌̖◌ࣶ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC KASRA WITH DOT BELOW, LATIN SMALL LETTER B
+0061 08F6 059A 0316 302A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062;0061 302A 08F6 0316 059A 0062; # (a◌ࣶ◌֚◌̖◌〪b; a◌〪◌ࣶ◌̖◌֚b; a◌〪◌ࣶ◌̖◌֚b; a◌〪◌ࣶ◌̖◌֚b; a◌〪◌ࣶ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC KASRA WITH DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08F7 0062;00E0 05AE 08F7 0315 0062;0061 05AE 0300 08F7 0315 0062;00E0 05AE 08F7 0315 0062;0061 05AE 0300 08F7 0315 0062; # (a◌̕◌̀◌֮◌ࣷb; à◌֮◌ࣷ◌̕b; a◌֮◌̀◌ࣷ◌̕b; à◌֮◌ࣷ◌̕b; a◌֮◌̀◌ࣷ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC LEFT ARROWHEAD ABOVE, LATIN SMALL LETTER B
+0061 08F7 0315 0300 05AE 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062;0061 05AE 08F7 0300 0315 0062; # (a◌ࣷ◌̕◌̀◌֮b; a◌֮◌ࣷ◌̀◌̕b; a◌֮◌ࣷ◌̀◌̕b; a◌֮◌ࣷ◌̀◌̕b; a◌֮◌ࣷ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC LEFT ARROWHEAD ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08F8 0062;00E0 05AE 08F8 0315 0062;0061 05AE 0300 08F8 0315 0062;00E0 05AE 08F8 0315 0062;0061 05AE 0300 08F8 0315 0062; # (a◌̕◌̀◌֮◌ࣸb; à◌֮◌ࣸ◌̕b; a◌֮◌̀◌ࣸ◌̕b; à◌֮◌ࣸ◌̕b; a◌֮◌̀◌ࣸ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC RIGHT ARROWHEAD ABOVE, LATIN SMALL LETTER B
+0061 08F8 0315 0300 05AE 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062;0061 05AE 08F8 0300 0315 0062; # (a◌ࣸ◌̕◌̀◌֮b; a◌֮◌ࣸ◌̀◌̕b; a◌֮◌ࣸ◌̀◌̕b; a◌֮◌ࣸ◌̀◌̕b; a◌֮◌ࣸ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC RIGHT ARROWHEAD ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 08F9 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062;0061 302A 0316 08F9 059A 0062; # (a◌֚◌̖◌〪◌ࣹb; a◌〪◌̖◌ࣹ◌֚b; a◌〪◌̖◌ࣹ◌֚b; a◌〪◌̖◌ࣹ◌֚b; a◌〪◌̖◌ࣹ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC LEFT ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 08F9 059A 0316 302A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062;0061 302A 08F9 0316 059A 0062; # (a◌ࣹ◌֚◌̖◌〪b; a◌〪◌ࣹ◌̖◌֚b; a◌〪◌ࣹ◌̖◌֚b; a◌〪◌ࣹ◌̖◌֚b; a◌〪◌ࣹ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC LEFT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 08FA 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062;0061 302A 0316 08FA 059A 0062; # (a◌֚◌̖◌〪◌ࣺb; a◌〪◌̖◌ࣺ◌֚b; a◌〪◌̖◌ࣺ◌֚b; a◌〪◌̖◌ࣺ◌֚b; a◌〪◌̖◌ࣺ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, ARABIC RIGHT ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 08FA 059A 0316 302A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062;0061 302A 08FA 0316 059A 0062; # (a◌ࣺ◌֚◌̖◌〪b; a◌〪◌ࣺ◌̖◌֚b; a◌〪◌ࣺ◌̖◌֚b; a◌〪◌ࣺ◌̖◌֚b; a◌〪◌ࣺ◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC RIGHT ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08FB 0062;00E0 05AE 08FB 0315 0062;0061 05AE 0300 08FB 0315 0062;00E0 05AE 08FB 0315 0062;0061 05AE 0300 08FB 0315 0062; # (a◌̕◌̀◌֮◌ࣻb; à◌֮◌ࣻ◌̕b; a◌֮◌̀◌ࣻ◌̕b; à◌֮◌ࣻ◌̕b; a◌֮◌̀◌ࣻ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC DOUBLE RIGHT ARROWHEAD ABOVE, LATIN SMALL LETTER B
+0061 08FB 0315 0300 05AE 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062;0061 05AE 08FB 0300 0315 0062; # (a◌ࣻ◌̕◌̀◌֮b; a◌֮◌ࣻ◌̀◌̕b; a◌֮◌ࣻ◌̀◌̕b; a◌֮◌ࣻ◌̀◌̕b; a◌֮◌ࣻ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC DOUBLE RIGHT ARROWHEAD ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08FC 0062;00E0 05AE 08FC 0315 0062;0061 05AE 0300 08FC 0315 0062;00E0 05AE 08FC 0315 0062;0061 05AE 0300 08FC 0315 0062; # (a◌̕◌̀◌֮◌ࣼb; à◌֮◌ࣼ◌̕b; a◌֮◌̀◌ࣼ◌̕b; à◌֮◌ࣼ◌̕b; a◌֮◌̀◌ࣼ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC DOUBLE RIGHT ARROWHEAD ABOVE WITH DOT, LATIN SMALL LETTER B
+0061 08FC 0315 0300 05AE 0062;0061 05AE 08FC 0300 0315 0062;0061 05AE 08FC 0300 0315 0062;0061 05AE 08FC 0300 0315 0062;0061 05AE 08FC 0300 0315 0062; # (a◌ࣼ◌̕◌̀◌֮b; a◌֮◌ࣼ◌̀◌̕b; a◌֮◌ࣼ◌̀◌̕b; a◌֮◌ࣼ◌̀◌̕b; a◌֮◌ࣼ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC DOUBLE RIGHT ARROWHEAD ABOVE WITH DOT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08FD 0062;00E0 05AE 08FD 0315 0062;0061 05AE 0300 08FD 0315 0062;00E0 05AE 08FD 0315 0062;0061 05AE 0300 08FD 0315 0062; # (a◌̕◌̀◌֮◌ࣽb; à◌֮◌ࣽ◌̕b; a◌֮◌̀◌ࣽ◌̕b; à◌֮◌ࣽ◌̕b; a◌֮◌̀◌ࣽ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC RIGHT ARROWHEAD ABOVE WITH DOT, LATIN SMALL LETTER B
+0061 08FD 0315 0300 05AE 0062;0061 05AE 08FD 0300 0315 0062;0061 05AE 08FD 0300 0315 0062;0061 05AE 08FD 0300 0315 0062;0061 05AE 08FD 0300 0315 0062; # (a◌ࣽ◌̕◌̀◌֮b; a◌֮◌ࣽ◌̀◌̕b; a◌֮◌ࣽ◌̀◌̕b; a◌֮◌ࣽ◌̀◌̕b; a◌֮◌ࣽ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC RIGHT ARROWHEAD ABOVE WITH DOT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08FE 0062;00E0 05AE 08FE 0315 0062;0061 05AE 0300 08FE 0315 0062;00E0 05AE 08FE 0315 0062;0061 05AE 0300 08FE 0315 0062; # (a◌̕◌̀◌֮◌ࣾb; à◌֮◌ࣾ◌̕b; a◌֮◌̀◌ࣾ◌̕b; à◌֮◌ࣾ◌̕b; a◌֮◌̀◌ࣾ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC DAMMA WITH DOT, LATIN SMALL LETTER B
+0061 08FE 0315 0300 05AE 0062;0061 05AE 08FE 0300 0315 0062;0061 05AE 08FE 0300 0315 0062;0061 05AE 08FE 0300 0315 0062;0061 05AE 08FE 0300 0315 0062; # (a◌ࣾ◌̕◌̀◌֮b; a◌֮◌ࣾ◌̀◌̕b; a◌֮◌ࣾ◌̀◌̕b; a◌֮◌ࣾ◌̀◌̕b; a◌֮◌ࣾ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC DAMMA WITH DOT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 08FF 0062;00E0 05AE 08FF 0315 0062;0061 05AE 0300 08FF 0315 0062;00E0 05AE 08FF 0315 0062;0061 05AE 0300 08FF 0315 0062; # (a◌̕◌̀◌֮◌ࣿb; à◌֮◌ࣿ◌̕b; a◌֮◌̀◌ࣿ◌̕b; à◌֮◌ࣿ◌̕b; a◌֮◌̀◌ࣿ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC MARK SIDEWAYS NOON GHUNNA, LATIN SMALL LETTER B
+0061 08FF 0315 0300 05AE 0062;0061 05AE 08FF 0300 0315 0062;0061 05AE 08FF 0300 0315 0062;0061 05AE 08FF 0300 0315 0062;0061 05AE 08FF 0300 0315 0062; # (a◌ࣿ◌̕◌̀◌֮b; a◌֮◌ࣿ◌̀◌̕b; a◌֮◌ࣿ◌̀◌̕b; a◌֮◌ࣿ◌̀◌̕b; a◌֮◌ࣿ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC MARK SIDEWAYS NOON GHUNNA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 3099 093C 0334 093C 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062; # (a◌゙◌़◌̴◌़b; a◌̴◌़◌़◌゙b; a◌̴◌़◌़◌゙b; a◌̴◌़◌़◌゙b; a◌̴◌़◌़◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, DEVANAGARI SIGN NUKTA, LATIN SMALL LETTER B
+0061 093C 3099 093C 0334 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062;0061 0334 093C 093C 3099 0062; # (a◌़◌゙◌़◌̴b; a◌̴◌़◌़◌゙b; a◌̴◌़◌़◌゙b; a◌̴◌़◌़◌゙b; a◌̴◌़◌़◌゙b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 094D 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062; # (a◌ְ◌्◌゙◌्b; a◌゙◌्◌्◌ְb; a◌゙◌्◌्◌ְb; a◌゙◌्◌्◌ְb; a◌゙◌्◌्◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN VIRAMA, LATIN SMALL LETTER B
+0061 094D 05B0 094D 3099 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062;0061 3099 094D 094D 05B0 0062; # (a◌्◌ְ◌्◌゙b; a◌゙◌्◌्◌ְb; a◌゙◌्◌्◌ְb; a◌゙◌्◌्◌ְb; a◌゙◌्◌्◌ְb; ) LATIN SMALL LETTER A, DEVANAGARI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0951 0062;00E0 05AE 0951 0315 0062;0061 05AE 0300 0951 0315 0062;00E0 05AE 0951 0315 0062;0061 05AE 0300 0951 0315 0062; # (a◌̕◌̀◌֮◌॑b; à◌֮◌॑◌̕b; a◌֮◌̀◌॑◌̕b; à◌֮◌॑◌̕b; a◌֮◌̀◌॑◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, DEVANAGARI STRESS SIGN UDATTA, LATIN SMALL LETTER B
+0061 0951 0315 0300 05AE 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062;0061 05AE 0951 0300 0315 0062; # (a◌॑◌̕◌̀◌֮b; a◌֮◌॑◌̀◌̕b; a◌֮◌॑◌̀◌̕b; a◌֮◌॑◌̀◌̕b; a◌֮◌॑◌̀◌̕b; ) LATIN SMALL LETTER A, DEVANAGARI STRESS SIGN UDATTA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0952 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062;0061 302A 0316 0952 059A 0062; # (a◌֚◌̖◌〪◌॒b; a◌〪◌̖◌॒◌֚b; a◌〪◌̖◌॒◌֚b; a◌〪◌̖◌॒◌֚b; a◌〪◌̖◌॒◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, DEVANAGARI STRESS SIGN ANUDATTA, LATIN SMALL LETTER B
+0061 0952 059A 0316 302A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062;0061 302A 0952 0316 059A 0062; # (a◌॒◌֚◌̖◌〪b; a◌〪◌॒◌̖◌֚b; a◌〪◌॒◌̖◌֚b; a◌〪◌॒◌̖◌֚b; a◌〪◌॒◌̖◌֚b; ) LATIN SMALL LETTER A, DEVANAGARI STRESS SIGN ANUDATTA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0953 0062;00E0 05AE 0953 0315 0062;0061 05AE 0300 0953 0315 0062;00E0 05AE 0953 0315 0062;0061 05AE 0300 0953 0315 0062; # (a◌̕◌̀◌֮◌॓b; à◌֮◌॓◌̕b; a◌֮◌̀◌॓◌̕b; à◌֮◌॓◌̕b; a◌֮◌̀◌॓◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, DEVANAGARI GRAVE ACCENT, LATIN SMALL LETTER B
+0061 0953 0315 0300 05AE 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062;0061 05AE 0953 0300 0315 0062; # (a◌॓◌̕◌̀◌֮b; a◌֮◌॓◌̀◌̕b; a◌֮◌॓◌̀◌̕b; a◌֮◌॓◌̀◌̕b; a◌֮◌॓◌̀◌̕b; ) LATIN SMALL LETTER A, DEVANAGARI GRAVE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0954 0062;00E0 05AE 0954 0315 0062;0061 05AE 0300 0954 0315 0062;00E0 05AE 0954 0315 0062;0061 05AE 0300 0954 0315 0062; # (a◌̕◌̀◌֮◌॔b; à◌֮◌॔◌̕b; a◌֮◌̀◌॔◌̕b; à◌֮◌॔◌̕b; a◌֮◌̀◌॔◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, DEVANAGARI ACUTE ACCENT, LATIN SMALL LETTER B
+0061 0954 0315 0300 05AE 0062;0061 05AE 0954 0300 0315 0062;0061 05AE 0954 0300 0315 0062;0061 05AE 0954 0300 0315 0062;0061 05AE 0954 0300 0315 0062; # (a◌॔◌̕◌̀◌֮b; a◌֮◌॔◌̀◌̕b; a◌֮◌॔◌̀◌̕b; a◌֮◌॔◌̀◌̕b; a◌֮◌॔◌̀◌̕b; ) LATIN SMALL LETTER A, DEVANAGARI ACUTE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 3099 093C 0334 09BC 0062;0061 0334 093C 09BC 3099 0062;0061 0334 093C 09BC 3099 0062;0061 0334 093C 09BC 3099 0062;0061 0334 093C 09BC 3099 0062; # (a◌゙◌़◌̴◌়b; a◌̴◌़◌়◌゙b; a◌̴◌़◌়◌゙b; a◌̴◌़◌়◌゙b; a◌̴◌़◌়◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, BENGALI SIGN NUKTA, LATIN SMALL LETTER B
+0061 09BC 3099 093C 0334 0062;0061 0334 09BC 093C 3099 0062;0061 0334 09BC 093C 3099 0062;0061 0334 09BC 093C 3099 0062;0061 0334 09BC 093C 3099 0062; # (a◌়◌゙◌़◌̴b; a◌̴◌়◌़◌゙b; a◌̴◌়◌़◌゙b; a◌̴◌়◌़◌゙b; a◌̴◌়◌़◌゙b; ) LATIN SMALL LETTER A, BENGALI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 09CD 0062;0061 3099 094D 09CD 05B0 0062;0061 3099 094D 09CD 05B0 0062;0061 3099 094D 09CD 05B0 0062;0061 3099 094D 09CD 05B0 0062; # (a◌ְ◌्◌゙◌্b; a◌゙◌्◌্◌ְb; a◌゙◌्◌্◌ְb; a◌゙◌्◌্◌ְb; a◌゙◌्◌্◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, BENGALI SIGN VIRAMA, LATIN SMALL LETTER B
+0061 09CD 05B0 094D 3099 0062;0061 3099 09CD 094D 05B0 0062;0061 3099 09CD 094D 05B0 0062;0061 3099 09CD 094D 05B0 0062;0061 3099 09CD 094D 05B0 0062; # (a◌্◌ְ◌्◌゙b; a◌゙◌্◌्◌ְb; a◌゙◌্◌्◌ְb; a◌゙◌্◌्◌ְb; a◌゙◌্◌्◌ְb; ) LATIN SMALL LETTER A, BENGALI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 0A3C 0062;0061 0334 093C 0A3C 3099 0062;0061 0334 093C 0A3C 3099 0062;0061 0334 093C 0A3C 3099 0062;0061 0334 093C 0A3C 3099 0062; # (a◌゙◌़◌̴◌਼b; a◌̴◌़◌਼◌゙b; a◌̴◌़◌਼◌゙b; a◌̴◌़◌਼◌゙b; a◌̴◌़◌਼◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, GURMUKHI SIGN NUKTA, LATIN SMALL LETTER B
+0061 0A3C 3099 093C 0334 0062;0061 0334 0A3C 093C 3099 0062;0061 0334 0A3C 093C 3099 0062;0061 0334 0A3C 093C 3099 0062;0061 0334 0A3C 093C 3099 0062; # (a◌਼◌゙◌़◌̴b; a◌̴◌਼◌़◌゙b; a◌̴◌਼◌़◌゙b; a◌̴◌਼◌़◌゙b; a◌̴◌਼◌़◌゙b; ) LATIN SMALL LETTER A, GURMUKHI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0A4D 0062;0061 3099 094D 0A4D 05B0 0062;0061 3099 094D 0A4D 05B0 0062;0061 3099 094D 0A4D 05B0 0062;0061 3099 094D 0A4D 05B0 0062; # (a◌ְ◌्◌゙◌੍b; a◌゙◌्◌੍◌ְb; a◌゙◌्◌੍◌ְb; a◌゙◌्◌੍◌ְb; a◌゙◌्◌੍◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, GURMUKHI SIGN VIRAMA, LATIN SMALL LETTER B
+0061 0A4D 05B0 094D 3099 0062;0061 3099 0A4D 094D 05B0 0062;0061 3099 0A4D 094D 05B0 0062;0061 3099 0A4D 094D 05B0 0062;0061 3099 0A4D 094D 05B0 0062; # (a◌੍◌ְ◌्◌゙b; a◌゙◌੍◌्◌ְb; a◌゙◌੍◌्◌ְb; a◌゙◌੍◌्◌ְb; a◌゙◌੍◌्◌ְb; ) LATIN SMALL LETTER A, GURMUKHI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 0ABC 0062;0061 0334 093C 0ABC 3099 0062;0061 0334 093C 0ABC 3099 0062;0061 0334 093C 0ABC 3099 0062;0061 0334 093C 0ABC 3099 0062; # (a◌゙◌़◌̴◌઼b; a◌̴◌़◌઼◌゙b; a◌̴◌़◌઼◌゙b; a◌̴◌़◌઼◌゙b; a◌̴◌़◌઼◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, GUJARATI SIGN NUKTA, LATIN SMALL LETTER B
+0061 0ABC 3099 093C 0334 0062;0061 0334 0ABC 093C 3099 0062;0061 0334 0ABC 093C 3099 0062;0061 0334 0ABC 093C 3099 0062;0061 0334 0ABC 093C 3099 0062; # (a◌઼◌゙◌़◌̴b; a◌̴◌઼◌़◌゙b; a◌̴◌઼◌़◌゙b; a◌̴◌઼◌़◌゙b; a◌̴◌઼◌़◌゙b; ) LATIN SMALL LETTER A, GUJARATI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0ACD 0062;0061 3099 094D 0ACD 05B0 0062;0061 3099 094D 0ACD 05B0 0062;0061 3099 094D 0ACD 05B0 0062;0061 3099 094D 0ACD 05B0 0062; # (a◌ְ◌्◌゙◌્b; a◌゙◌्◌્◌ְb; a◌゙◌्◌્◌ְb; a◌゙◌्◌્◌ְb; a◌゙◌्◌્◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, GUJARATI SIGN VIRAMA, LATIN SMALL LETTER B
+0061 0ACD 05B0 094D 3099 0062;0061 3099 0ACD 094D 05B0 0062;0061 3099 0ACD 094D 05B0 0062;0061 3099 0ACD 094D 05B0 0062;0061 3099 0ACD 094D 05B0 0062; # (a◌્◌ְ◌्◌゙b; a◌゙◌્◌्◌ְb; a◌゙◌્◌्◌ְb; a◌゙◌્◌्◌ְb; a◌゙◌્◌्◌ְb; ) LATIN SMALL LETTER A, GUJARATI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 0B3C 0062;0061 0334 093C 0B3C 3099 0062;0061 0334 093C 0B3C 3099 0062;0061 0334 093C 0B3C 3099 0062;0061 0334 093C 0B3C 3099 0062; # (a◌゙◌़◌̴◌଼b; a◌̴◌़◌଼◌゙b; a◌̴◌़◌଼◌゙b; a◌̴◌़◌଼◌゙b; a◌̴◌़◌଼◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, ORIYA SIGN NUKTA, LATIN SMALL LETTER B
+0061 0B3C 3099 093C 0334 0062;0061 0334 0B3C 093C 3099 0062;0061 0334 0B3C 093C 3099 0062;0061 0334 0B3C 093C 3099 0062;0061 0334 0B3C 093C 3099 0062; # (a◌଼◌゙◌़◌̴b; a◌̴◌଼◌़◌゙b; a◌̴◌଼◌़◌゙b; a◌̴◌଼◌़◌゙b; a◌̴◌଼◌़◌゙b; ) LATIN SMALL LETTER A, ORIYA SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0B4D 0062;0061 3099 094D 0B4D 05B0 0062;0061 3099 094D 0B4D 05B0 0062;0061 3099 094D 0B4D 05B0 0062;0061 3099 094D 0B4D 05B0 0062; # (a◌ְ◌्◌゙◌୍b; a◌゙◌्◌୍◌ְb; a◌゙◌्◌୍◌ְb; a◌゙◌्◌୍◌ְb; a◌゙◌्◌୍◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, ORIYA SIGN VIRAMA, LATIN SMALL LETTER B
+0061 0B4D 05B0 094D 3099 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062;0061 3099 0B4D 094D 05B0 0062; # (a◌୍◌ְ◌्◌゙b; a◌゙◌୍◌्◌ְb; a◌゙◌୍◌्◌ְb; a◌゙◌୍◌्◌ְb; a◌゙◌୍◌्◌ְb; ) LATIN SMALL LETTER A, ORIYA SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0BCD 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 05B0 0062;0061 3099 094D 0BCD 05B0 0062; # (a◌ְ◌्◌゙◌்b; a◌゙◌्◌்◌ְb; a◌゙◌्◌்◌ְb; a◌゙◌्◌்◌ְb; a◌゙◌्◌்◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, TAMIL SIGN VIRAMA, LATIN SMALL LETTER B
+0061 0BCD 05B0 094D 3099 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062;0061 3099 0BCD 094D 05B0 0062; # (a◌்◌ְ◌्◌゙b; a◌゙◌்◌्◌ְb; a◌゙◌்◌्◌ְb; a◌゙◌்◌्◌ְb; a◌゙◌்◌्◌ְb; ) LATIN SMALL LETTER A, TAMIL SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0C4D 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 05B0 0062;0061 3099 094D 0C4D 05B0 0062; # (a◌ְ◌्◌゙◌్b; a◌゙◌्◌్◌ְb; a◌゙◌्◌్◌ְb; a◌゙◌्◌్◌ְb; a◌゙◌्◌్◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, TELUGU SIGN VIRAMA, LATIN SMALL LETTER B
+0061 0C4D 05B0 094D 3099 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062;0061 3099 0C4D 094D 05B0 0062; # (a◌్◌ְ◌्◌゙b; a◌゙◌్◌्◌ְb; a◌゙◌్◌्◌ְb; a◌゙◌్◌्◌ְb; a◌゙◌్◌्◌ְb; ) LATIN SMALL LETTER A, TELUGU SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0C56 0C55 0711 0C55 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062; # (a◌ౖ◌ౕ◌ܑ◌ౕb; a◌ܑ◌ౕ◌ౕ◌ౖb; a◌ܑ◌ౕ◌ౕ◌ౖb; a◌ܑ◌ౕ◌ౕ◌ౖb; a◌ܑ◌ౕ◌ౕ◌ౖb; ) LATIN SMALL LETTER A, TELUGU AI LENGTH MARK, TELUGU LENGTH MARK, SYRIAC LETTER SUPERSCRIPT ALAPH, TELUGU LENGTH MARK, LATIN SMALL LETTER B
+0061 0C55 0C56 0C55 0711 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062;0061 0711 0C55 0C55 0C56 0062; # (a◌ౕ◌ౖ◌ౕ◌ܑb; a◌ܑ◌ౕ◌ౕ◌ౖb; a◌ܑ◌ౕ◌ౕ◌ౖb; a◌ܑ◌ౕ◌ౕ◌ౖb; a◌ܑ◌ౕ◌ౕ◌ౖb; ) LATIN SMALL LETTER A, TELUGU LENGTH MARK, TELUGU AI LENGTH MARK, TELUGU LENGTH MARK, SYRIAC LETTER SUPERSCRIPT ALAPH, LATIN SMALL LETTER B
+0061 0E38 0C56 0C55 0C56 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062; # (a◌ุ◌ౖ◌ౕ◌ౖb; a◌ౕ◌ౖ◌ౖ◌ุb; a◌ౕ◌ౖ◌ౖ◌ุb; a◌ౕ◌ౖ◌ౖ◌ุb; a◌ౕ◌ౖ◌ౖ◌ุb; ) LATIN SMALL LETTER A, THAI CHARACTER SARA U, TELUGU AI LENGTH MARK, TELUGU LENGTH MARK, TELUGU AI LENGTH MARK, LATIN SMALL LETTER B
+0061 0C56 0E38 0C56 0C55 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062;0061 0C55 0C56 0C56 0E38 0062; # (a◌ౖ◌ุ◌ౖ◌ౕb; a◌ౕ◌ౖ◌ౖ◌ุb; a◌ౕ◌ౖ◌ౖ◌ุb; a◌ౕ◌ౖ◌ౖ◌ุb; a◌ౕ◌ౖ◌ౖ◌ุb; ) LATIN SMALL LETTER A, TELUGU AI LENGTH MARK, THAI CHARACTER SARA U, TELUGU AI LENGTH MARK, TELUGU LENGTH MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 0CBC 0062;0061 0334 093C 0CBC 3099 0062;0061 0334 093C 0CBC 3099 0062;0061 0334 093C 0CBC 3099 0062;0061 0334 093C 0CBC 3099 0062; # (a◌゙◌़◌̴◌಼b; a◌̴◌़◌಼◌゙b; a◌̴◌़◌಼◌゙b; a◌̴◌़◌಼◌゙b; a◌̴◌़◌಼◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, KANNADA SIGN NUKTA, LATIN SMALL LETTER B
+0061 0CBC 3099 093C 0334 0062;0061 0334 0CBC 093C 3099 0062;0061 0334 0CBC 093C 3099 0062;0061 0334 0CBC 093C 3099 0062;0061 0334 0CBC 093C 3099 0062; # (a◌಼◌゙◌़◌̴b; a◌̴◌಼◌़◌゙b; a◌̴◌಼◌़◌゙b; a◌̴◌಼◌़◌゙b; a◌̴◌಼◌़◌゙b; ) LATIN SMALL LETTER A, KANNADA SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0CCD 0062;0061 3099 094D 0CCD 05B0 0062;0061 3099 094D 0CCD 05B0 0062;0061 3099 094D 0CCD 05B0 0062;0061 3099 094D 0CCD 05B0 0062; # (a◌ְ◌्◌゙◌್b; a◌゙◌्◌್◌ְb; a◌゙◌्◌್◌ְb; a◌゙◌्◌್◌ְb; a◌゙◌्◌್◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, KANNADA SIGN VIRAMA, LATIN SMALL LETTER B
+0061 0CCD 05B0 094D 3099 0062;0061 3099 0CCD 094D 05B0 0062;0061 3099 0CCD 094D 05B0 0062;0061 3099 0CCD 094D 05B0 0062;0061 3099 0CCD 094D 05B0 0062; # (a◌್◌ְ◌्◌゙b; a◌゙◌್◌्◌ְb; a◌゙◌್◌्◌ְb; a◌゙◌್◌्◌ְb; a◌゙◌್◌्◌ְb; ) LATIN SMALL LETTER A, KANNADA SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0D4D 0062;0061 3099 094D 0D4D 05B0 0062;0061 3099 094D 0D4D 05B0 0062;0061 3099 094D 0D4D 05B0 0062;0061 3099 094D 0D4D 05B0 0062; # (a◌ְ◌्◌゙◌്b; a◌゙◌्◌്◌ְb; a◌゙◌्◌്◌ְb; a◌゙◌्◌്◌ְb; a◌゙◌्◌്◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, MALAYALAM SIGN VIRAMA, LATIN SMALL LETTER B
+0061 0D4D 05B0 094D 3099 0062;0061 3099 0D4D 094D 05B0 0062;0061 3099 0D4D 094D 05B0 0062;0061 3099 0D4D 094D 05B0 0062;0061 3099 0D4D 094D 05B0 0062; # (a◌്◌ְ◌्◌゙b; a◌゙◌്◌्◌ְb; a◌゙◌്◌्◌ְb; a◌゙◌്◌्◌ְb; a◌゙◌്◌्◌ְb; ) LATIN SMALL LETTER A, MALAYALAM SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0DCA 0062;0061 3099 094D 0DCA 05B0 0062;0061 3099 094D 0DCA 05B0 0062;0061 3099 094D 0DCA 05B0 0062;0061 3099 094D 0DCA 05B0 0062; # (a◌ְ◌्◌゙◌්b; a◌゙◌्◌්◌ְb; a◌゙◌्◌්◌ְb; a◌゙◌्◌්◌ְb; a◌゙◌्◌්◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, SINHALA SIGN AL-LAKUNA, LATIN SMALL LETTER B
+0061 0DCA 05B0 094D 3099 0062;0061 3099 0DCA 094D 05B0 0062;0061 3099 0DCA 094D 05B0 0062;0061 3099 0DCA 094D 05B0 0062;0061 3099 0DCA 094D 05B0 0062; # (a◌්◌ְ◌्◌゙b; a◌゙◌්◌्◌ְb; a◌゙◌්◌्◌ְb; a◌゙◌්◌्◌ְb; a◌゙◌්◌्◌ְb; ) LATIN SMALL LETTER A, SINHALA SIGN AL-LAKUNA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0E48 0E38 0C56 0E38 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062; # (a◌่◌ุ◌ౖ◌ุb; a◌ౖ◌ุ◌ุ◌่b; a◌ౖ◌ุ◌ุ◌่b; a◌ౖ◌ุ◌ุ◌่b; a◌ౖ◌ุ◌ุ◌่b; ) LATIN SMALL LETTER A, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, TELUGU AI LENGTH MARK, THAI CHARACTER SARA U, LATIN SMALL LETTER B
+0061 0E38 0E48 0E38 0C56 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062;0061 0C56 0E38 0E38 0E48 0062; # (a◌ุ◌่◌ุ◌ౖb; a◌ౖ◌ุ◌ุ◌่b; a◌ౖ◌ุ◌ุ◌่b; a◌ౖ◌ุ◌ุ◌่b; a◌ౖ◌ุ◌ุ◌่b; ) LATIN SMALL LETTER A, THAI CHARACTER SARA U, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, TELUGU AI LENGTH MARK, LATIN SMALL LETTER B
+0061 0E48 0E38 0C56 0E39 0062;0061 0C56 0E38 0E39 0E48 0062;0061 0C56 0E38 0E39 0E48 0062;0061 0C56 0E38 0E39 0E48 0062;0061 0C56 0E38 0E39 0E48 0062; # (a◌่◌ุ◌ౖ◌ูb; a◌ౖ◌ุ◌ู◌่b; a◌ౖ◌ุ◌ู◌่b; a◌ౖ◌ุ◌ู◌่b; a◌ౖ◌ุ◌ู◌่b; ) LATIN SMALL LETTER A, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, TELUGU AI LENGTH MARK, THAI CHARACTER SARA UU, LATIN SMALL LETTER B
+0061 0E39 0E48 0E38 0C56 0062;0061 0C56 0E39 0E38 0E48 0062;0061 0C56 0E39 0E38 0E48 0062;0061 0C56 0E39 0E38 0E48 0062;0061 0C56 0E39 0E38 0E48 0062; # (a◌ู◌่◌ุ◌ౖb; a◌ౖ◌ู◌ุ◌่b; a◌ౖ◌ู◌ุ◌่b; a◌ౖ◌ู◌ุ◌่b; a◌ౖ◌ู◌ุ◌่b; ) LATIN SMALL LETTER A, THAI CHARACTER SARA UU, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, TELUGU AI LENGTH MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0E3A 0062;0061 3099 094D 0E3A 05B0 0062;0061 3099 094D 0E3A 05B0 0062;0061 3099 094D 0E3A 05B0 0062;0061 3099 094D 0E3A 05B0 0062; # (a◌ְ◌्◌゙◌ฺb; a◌゙◌्◌ฺ◌ְb; a◌゙◌्◌ฺ◌ְb; a◌゙◌्◌ฺ◌ְb; a◌゙◌्◌ฺ◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, THAI CHARACTER PHINTHU, LATIN SMALL LETTER B
+0061 0E3A 05B0 094D 3099 0062;0061 3099 0E3A 094D 05B0 0062;0061 3099 0E3A 094D 05B0 0062;0061 3099 0E3A 094D 05B0 0062;0061 3099 0E3A 094D 05B0 0062; # (a◌ฺ◌ְ◌्◌゙b; a◌゙◌ฺ◌्◌ְb; a◌゙◌ฺ◌्◌ְb; a◌゙◌ฺ◌्◌ְb; a◌゙◌ฺ◌्◌ְb; ) LATIN SMALL LETTER A, THAI CHARACTER PHINTHU, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0EB8 0E48 0E38 0E48 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062; # (a◌ຸ◌่◌ุ◌่b; a◌ุ◌่◌่◌ຸb; a◌ุ◌่◌่◌ຸb; a◌ุ◌่◌่◌ຸb; a◌ุ◌่◌่◌ຸb; ) LATIN SMALL LETTER A, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, THAI CHARACTER MAI EK, LATIN SMALL LETTER B
+0061 0E48 0EB8 0E48 0E38 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062;0061 0E38 0E48 0E48 0EB8 0062; # (a◌่◌ຸ◌่◌ุb; a◌ุ◌่◌่◌ຸb; a◌ุ◌่◌่◌ຸb; a◌ุ◌่◌่◌ຸb; a◌ุ◌่◌่◌ຸb; ) LATIN SMALL LETTER A, THAI CHARACTER MAI EK, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, LATIN SMALL LETTER B
+0061 0EB8 0E48 0E38 0E49 0062;0061 0E38 0E48 0E49 0EB8 0062;0061 0E38 0E48 0E49 0EB8 0062;0061 0E38 0E48 0E49 0EB8 0062;0061 0E38 0E48 0E49 0EB8 0062; # (a◌ຸ◌่◌ุ◌้b; a◌ุ◌่◌้◌ຸb; a◌ุ◌่◌้◌ຸb; a◌ุ◌่◌้◌ຸb; a◌ุ◌่◌้◌ຸb; ) LATIN SMALL LETTER A, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, THAI CHARACTER MAI THO, LATIN SMALL LETTER B
+0061 0E49 0EB8 0E48 0E38 0062;0061 0E38 0E49 0E48 0EB8 0062;0061 0E38 0E49 0E48 0EB8 0062;0061 0E38 0E49 0E48 0EB8 0062;0061 0E38 0E49 0E48 0EB8 0062; # (a◌้◌ຸ◌่◌ุb; a◌ุ◌้◌่◌ຸb; a◌ุ◌้◌่◌ຸb; a◌ุ◌้◌่◌ຸb; a◌ุ◌้◌่◌ຸb; ) LATIN SMALL LETTER A, THAI CHARACTER MAI THO, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, LATIN SMALL LETTER B
+0061 0EB8 0E48 0E38 0E4A 0062;0061 0E38 0E48 0E4A 0EB8 0062;0061 0E38 0E48 0E4A 0EB8 0062;0061 0E38 0E48 0E4A 0EB8 0062;0061 0E38 0E48 0E4A 0EB8 0062; # (a◌ຸ◌่◌ุ◌๊b; a◌ุ◌่◌๊◌ຸb; a◌ุ◌่◌๊◌ຸb; a◌ุ◌่◌๊◌ຸb; a◌ุ◌่◌๊◌ຸb; ) LATIN SMALL LETTER A, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, THAI CHARACTER MAI TRI, LATIN SMALL LETTER B
+0061 0E4A 0EB8 0E48 0E38 0062;0061 0E38 0E4A 0E48 0EB8 0062;0061 0E38 0E4A 0E48 0EB8 0062;0061 0E38 0E4A 0E48 0EB8 0062;0061 0E38 0E4A 0E48 0EB8 0062; # (a◌๊◌ຸ◌่◌ุb; a◌ุ◌๊◌่◌ຸb; a◌ุ◌๊◌่◌ຸb; a◌ุ◌๊◌่◌ຸb; a◌ุ◌๊◌่◌ຸb; ) LATIN SMALL LETTER A, THAI CHARACTER MAI TRI, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, LATIN SMALL LETTER B
+0061 0EB8 0E48 0E38 0E4B 0062;0061 0E38 0E48 0E4B 0EB8 0062;0061 0E38 0E48 0E4B 0EB8 0062;0061 0E38 0E48 0E4B 0EB8 0062;0061 0E38 0E48 0E4B 0EB8 0062; # (a◌ຸ◌่◌ุ◌๋b; a◌ุ◌่◌๋◌ຸb; a◌ุ◌่◌๋◌ຸb; a◌ุ◌่◌๋◌ຸb; a◌ุ◌่◌๋◌ຸb; ) LATIN SMALL LETTER A, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, THAI CHARACTER MAI CHATTAWA, LATIN SMALL LETTER B
+0061 0E4B 0EB8 0E48 0E38 0062;0061 0E38 0E4B 0E48 0EB8 0062;0061 0E38 0E4B 0E48 0EB8 0062;0061 0E38 0E4B 0E48 0EB8 0062;0061 0E38 0E4B 0E48 0EB8 0062; # (a◌๋◌ຸ◌่◌ุb; a◌ุ◌๋◌่◌ຸb; a◌ุ◌๋◌่◌ຸb; a◌ุ◌๋◌่◌ຸb; a◌ุ◌๋◌่◌ຸb; ) LATIN SMALL LETTER A, THAI CHARACTER MAI CHATTAWA, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, THAI CHARACTER SARA U, LATIN SMALL LETTER B
+0061 0EC8 0EB8 0E48 0EB8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062; # (a◌່◌ຸ◌่◌ຸb; a◌่◌ຸ◌ຸ◌່b; a◌่◌ຸ◌ຸ◌່b; a◌่◌ຸ◌ຸ◌່b; a◌่◌ຸ◌ຸ◌່b; ) LATIN SMALL LETTER A, LAO TONE MAI EK, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, LAO VOWEL SIGN U, LATIN SMALL LETTER B
+0061 0EB8 0EC8 0EB8 0E48 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062; # (a◌ຸ◌່◌ຸ◌่b; a◌่◌ຸ◌ຸ◌່b; a◌่◌ຸ◌ຸ◌່b; a◌่◌ຸ◌ຸ◌່b; a◌่◌ຸ◌ຸ◌່b; ) LATIN SMALL LETTER A, LAO VOWEL SIGN U, LAO TONE MAI EK, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, LATIN SMALL LETTER B
+0061 0EC8 0EB8 0E48 0EB9 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062; # (a◌່◌ຸ◌่◌ູb; a◌่◌ຸ◌ູ◌່b; a◌่◌ຸ◌ູ◌່b; a◌่◌ຸ◌ູ◌່b; a◌่◌ຸ◌ູ◌່b; ) LATIN SMALL LETTER A, LAO TONE MAI EK, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, LAO VOWEL SIGN UU, LATIN SMALL LETTER B
+0061 0EB9 0EC8 0EB8 0E48 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062; # (a◌ູ◌່◌ຸ◌่b; a◌่◌ູ◌ຸ◌່b; a◌่◌ູ◌ຸ◌່b; a◌่◌ູ◌ຸ◌່b; a◌่◌ູ◌ຸ◌່b; ) LATIN SMALL LETTER A, LAO VOWEL SIGN UU, LAO TONE MAI EK, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, LATIN SMALL LETTER B
+0061 0F71 0EC8 0EB8 0EC8 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062; # (a◌ཱ◌່◌ຸ◌່b; a◌ຸ◌່◌່◌ཱb; a◌ຸ◌່◌່◌ཱb; a◌ຸ◌່◌່◌ཱb; a◌ຸ◌່◌່◌ཱb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LAO TONE MAI EK, LATIN SMALL LETTER B
+0061 0EC8 0F71 0EC8 0EB8 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062; # (a◌່◌ཱ◌່◌ຸb; a◌ຸ◌່◌່◌ཱb; a◌ຸ◌່◌່◌ཱb; a◌ຸ◌່◌່◌ཱb; a◌ຸ◌່◌່◌ཱb; ) LATIN SMALL LETTER A, LAO TONE MAI EK, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LATIN SMALL LETTER B
+0061 0F71 0EC8 0EB8 0EC9 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062; # (a◌ཱ◌່◌ຸ◌້b; a◌ຸ◌່◌້◌ཱb; a◌ຸ◌່◌້◌ཱb; a◌ຸ◌່◌້◌ཱb; a◌ຸ◌່◌້◌ཱb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LAO TONE MAI THO, LATIN SMALL LETTER B
+0061 0EC9 0F71 0EC8 0EB8 0062;0061 0EB8 0EC9 0EC8 0F71 0062;0061 0EB8 0EC9 0EC8 0F71 0062;0061 0EB8 0EC9 0EC8 0F71 0062;0061 0EB8 0EC9 0EC8 0F71 0062; # (a◌້◌ཱ◌່◌ຸb; a◌ຸ◌້◌່◌ཱb; a◌ຸ◌້◌່◌ཱb; a◌ຸ◌້◌່◌ཱb; a◌ຸ◌້◌່◌ཱb; ) LATIN SMALL LETTER A, LAO TONE MAI THO, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LATIN SMALL LETTER B
+0061 0F71 0EC8 0EB8 0ECA 0062;0061 0EB8 0EC8 0ECA 0F71 0062;0061 0EB8 0EC8 0ECA 0F71 0062;0061 0EB8 0EC8 0ECA 0F71 0062;0061 0EB8 0EC8 0ECA 0F71 0062; # (a◌ཱ◌່◌ຸ◌໊b; a◌ຸ◌່◌໊◌ཱb; a◌ຸ◌່◌໊◌ཱb; a◌ຸ◌່◌໊◌ཱb; a◌ຸ◌່◌໊◌ཱb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LAO TONE MAI TI, LATIN SMALL LETTER B
+0061 0ECA 0F71 0EC8 0EB8 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062;0061 0EB8 0ECA 0EC8 0F71 0062; # (a◌໊◌ཱ◌່◌ຸb; a◌ຸ◌໊◌່◌ཱb; a◌ຸ◌໊◌່◌ཱb; a◌ຸ◌໊◌່◌ཱb; a◌ຸ◌໊◌່◌ཱb; ) LATIN SMALL LETTER A, LAO TONE MAI TI, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LATIN SMALL LETTER B
+0061 0F71 0EC8 0EB8 0ECB 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062;0061 0EB8 0EC8 0ECB 0F71 0062; # (a◌ཱ◌່◌ຸ◌໋b; a◌ຸ◌່◌໋◌ཱb; a◌ຸ◌່◌໋◌ཱb; a◌ຸ◌່◌໋◌ཱb; a◌ຸ◌່◌໋◌ཱb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LAO TONE MAI CATAWA, LATIN SMALL LETTER B
+0061 0ECB 0F71 0EC8 0EB8 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062;0061 0EB8 0ECB 0EC8 0F71 0062; # (a◌໋◌ཱ◌່◌ຸb; a◌ຸ◌໋◌່◌ཱb; a◌ຸ◌໋◌່◌ཱb; a◌ຸ◌໋◌່◌ཱb; a◌ຸ◌໋◌່◌ཱb; ) LATIN SMALL LETTER A, LAO TONE MAI CATAWA, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LATIN SMALL LETTER B
+0061 059A 0316 302A 0F18 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062;0061 302A 0316 0F18 059A 0062; # (a◌֚◌̖◌〪◌༘b; a◌〪◌̖◌༘◌֚b; a◌〪◌̖◌༘◌֚b; a◌〪◌̖◌༘◌֚b; a◌〪◌̖◌༘◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TIBETAN ASTROLOGICAL SIGN -KHYUD PA, LATIN SMALL LETTER B
+0061 0F18 059A 0316 302A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062;0061 302A 0F18 0316 059A 0062; # (a◌༘◌֚◌̖◌〪b; a◌〪◌༘◌̖◌֚b; a◌〪◌༘◌̖◌֚b; a◌〪◌༘◌̖◌֚b; a◌〪◌༘◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN ASTROLOGICAL SIGN -KHYUD PA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0F19 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062;0061 302A 0316 0F19 059A 0062; # (a◌֚◌̖◌〪◌༙b; a◌〪◌̖◌༙◌֚b; a◌〪◌̖◌༙◌֚b; a◌〪◌̖◌༙◌֚b; a◌〪◌̖◌༙◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS, LATIN SMALL LETTER B
+0061 0F19 059A 0316 302A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062;0061 302A 0F19 0316 059A 0062; # (a◌༙◌֚◌̖◌〪b; a◌〪◌༙◌̖◌֚b; a◌〪◌༙◌̖◌֚b; a◌〪◌༙◌̖◌֚b; a◌〪◌༙◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0F35 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062;0061 302A 0316 0F35 059A 0062; # (a◌֚◌̖◌〪◌༵b; a◌〪◌̖◌༵◌֚b; a◌〪◌̖◌༵◌֚b; a◌〪◌̖◌༵◌֚b; a◌〪◌̖◌༵◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TIBETAN MARK NGAS BZUNG NYI ZLA, LATIN SMALL LETTER B
+0061 0F35 059A 0316 302A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062;0061 302A 0F35 0316 059A 0062; # (a◌༵◌֚◌̖◌〪b; a◌〪◌༵◌̖◌֚b; a◌〪◌༵◌̖◌֚b; a◌〪◌༵◌̖◌֚b; a◌〪◌༵◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN MARK NGAS BZUNG NYI ZLA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 0F37 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062;0061 302A 0316 0F37 059A 0062; # (a◌֚◌̖◌〪◌༷b; a◌〪◌̖◌༷◌֚b; a◌〪◌̖◌༷◌֚b; a◌〪◌̖◌༷◌֚b; a◌〪◌̖◌༷◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TIBETAN MARK NGAS BZUNG SGOR RTAGS, LATIN SMALL LETTER B
+0061 0F37 059A 0316 302A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062;0061 302A 0F37 0316 059A 0062; # (a◌༷◌֚◌̖◌〪b; a◌〪◌༷◌̖◌֚b; a◌〪◌༷◌̖◌֚b; a◌〪◌༷◌̖◌֚b; a◌〪◌༷◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN MARK NGAS BZUNG SGOR RTAGS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 302A 031B 1DCE 0F39 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062;0061 1DCE 031B 0F39 302A 0062; # (a◌〪◌̛◌᷎◌༹b; a◌᷎◌̛◌༹◌〪b; a◌᷎◌̛◌༹◌〪b; a◌᷎◌̛◌༹◌〪b; a◌᷎◌̛◌༹◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, TIBETAN MARK TSA -PHRU, LATIN SMALL LETTER B
+0061 0F39 302A 031B 1DCE 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062;0061 1DCE 0F39 031B 302A 0062; # (a◌༹◌〪◌̛◌᷎b; a◌᷎◌༹◌̛◌〪b; a◌᷎◌༹◌̛◌〪b; a◌᷎◌༹◌̛◌〪b; a◌᷎◌༹◌̛◌〪b; ) LATIN SMALL LETTER A, TIBETAN MARK TSA -PHRU, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 0F72 0F71 0EC8 0F71 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062; # (a◌ི◌ཱ◌່◌ཱb; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, TIBETAN VOWEL SIGN AA, LATIN SMALL LETTER B
+0061 0F71 0F72 0F71 0EC8 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062;0061 0EC8 0F71 0F71 0F72 0062; # (a◌ཱ◌ི◌ཱ◌່b; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; a◌່◌ཱ◌ཱ◌ིb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN AA, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LATIN SMALL LETTER B
+0061 0F74 0F72 0F71 0F72 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062; # (a◌ུ◌ི◌ཱ◌ིb; a◌ཱ◌ི◌ི◌ུb; a◌ཱ◌ི◌ི◌ུb; a◌ཱ◌ི◌ི◌ུb; a◌ཱ◌ི◌ི◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, TIBETAN VOWEL SIGN I, LATIN SMALL LETTER B
+0061 0F72 0F74 0F72 0F71 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062;0061 0F71 0F72 0F72 0F74 0062; # (a◌ི◌ུ◌ི◌ཱb; a◌ཱ◌ི◌ི◌ུb; a◌ཱ◌ི◌ི◌ུb; a◌ཱ◌ི◌ི◌ུb; a◌ཱ◌ི◌ི◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, LATIN SMALL LETTER B
+0061 0321 0F74 0F72 0F74 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062; # (a◌̡◌ུ◌ི◌ུb; a◌ི◌ུ◌ུ◌̡b; a◌ི◌ུ◌ུ◌̡b; a◌ི◌ུ◌ུ◌̡b; a◌ི◌ུ◌ུ◌̡b; ) LATIN SMALL LETTER A, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN U, LATIN SMALL LETTER B
+0061 0F74 0321 0F74 0F72 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062;0061 0F72 0F74 0F74 0321 0062; # (a◌ུ◌̡◌ུ◌ིb; a◌ི◌ུ◌ུ◌̡b; a◌ི◌ུ◌ུ◌̡b; a◌ི◌ུ◌ུ◌̡b; a◌ི◌ུ◌ུ◌̡b; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN U, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, LATIN SMALL LETTER B
+0061 0F74 0F72 0F71 0F7A 0062;0061 0F71 0F72 0F7A 0F74 0062;0061 0F71 0F72 0F7A 0F74 0062;0061 0F71 0F72 0F7A 0F74 0062;0061 0F71 0F72 0F7A 0F74 0062; # (a◌ུ◌ི◌ཱ◌ེb; a◌ཱ◌ི◌ེ◌ུb; a◌ཱ◌ི◌ེ◌ུb; a◌ཱ◌ི◌ེ◌ུb; a◌ཱ◌ི◌ེ◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, TIBETAN VOWEL SIGN E, LATIN SMALL LETTER B
+0061 0F7A 0F74 0F72 0F71 0062;0061 0F71 0F7A 0F72 0F74 0062;0061 0F71 0F7A 0F72 0F74 0062;0061 0F71 0F7A 0F72 0F74 0062;0061 0F71 0F7A 0F72 0F74 0062; # (a◌ེ◌ུ◌ི◌ཱb; a◌ཱ◌ེ◌ི◌ུb; a◌ཱ◌ེ◌ི◌ུb; a◌ཱ◌ེ◌ི◌ུb; a◌ཱ◌ེ◌ི◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN E, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, LATIN SMALL LETTER B
+0061 0F74 0F72 0F71 0F7B 0062;0061 0F71 0F72 0F7B 0F74 0062;0061 0F71 0F72 0F7B 0F74 0062;0061 0F71 0F72 0F7B 0F74 0062;0061 0F71 0F72 0F7B 0F74 0062; # (a◌ུ◌ི◌ཱ◌ཻb; a◌ཱ◌ི◌ཻ◌ུb; a◌ཱ◌ི◌ཻ◌ུb; a◌ཱ◌ི◌ཻ◌ུb; a◌ཱ◌ི◌ཻ◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, TIBETAN VOWEL SIGN EE, LATIN SMALL LETTER B
+0061 0F7B 0F74 0F72 0F71 0062;0061 0F71 0F7B 0F72 0F74 0062;0061 0F71 0F7B 0F72 0F74 0062;0061 0F71 0F7B 0F72 0F74 0062;0061 0F71 0F7B 0F72 0F74 0062; # (a◌ཻ◌ུ◌ི◌ཱb; a◌ཱ◌ཻ◌ི◌ུb; a◌ཱ◌ཻ◌ི◌ུb; a◌ཱ◌ཻ◌ི◌ུb; a◌ཱ◌ཻ◌ི◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN EE, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, LATIN SMALL LETTER B
+0061 0F74 0F72 0F71 0F7C 0062;0061 0F71 0F72 0F7C 0F74 0062;0061 0F71 0F72 0F7C 0F74 0062;0061 0F71 0F72 0F7C 0F74 0062;0061 0F71 0F72 0F7C 0F74 0062; # (a◌ུ◌ི◌ཱ◌ོb; a◌ཱ◌ི◌ོ◌ུb; a◌ཱ◌ི◌ོ◌ུb; a◌ཱ◌ི◌ོ◌ུb; a◌ཱ◌ི◌ོ◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, TIBETAN VOWEL SIGN O, LATIN SMALL LETTER B
+0061 0F7C 0F74 0F72 0F71 0062;0061 0F71 0F7C 0F72 0F74 0062;0061 0F71 0F7C 0F72 0F74 0062;0061 0F71 0F7C 0F72 0F74 0062;0061 0F71 0F7C 0F72 0F74 0062; # (a◌ོ◌ུ◌ི◌ཱb; a◌ཱ◌ོ◌ི◌ུb; a◌ཱ◌ོ◌ི◌ུb; a◌ཱ◌ོ◌ི◌ུb; a◌ཱ◌ོ◌ི◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN O, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, LATIN SMALL LETTER B
+0061 0F74 0F72 0F71 0F7D 0062;0061 0F71 0F72 0F7D 0F74 0062;0061 0F71 0F72 0F7D 0F74 0062;0061 0F71 0F72 0F7D 0F74 0062;0061 0F71 0F72 0F7D 0F74 0062; # (a◌ུ◌ི◌ཱ◌ཽb; a◌ཱ◌ི◌ཽ◌ུb; a◌ཱ◌ི◌ཽ◌ུb; a◌ཱ◌ི◌ཽ◌ུb; a◌ཱ◌ི◌ཽ◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, TIBETAN VOWEL SIGN OO, LATIN SMALL LETTER B
+0061 0F7D 0F74 0F72 0F71 0062;0061 0F71 0F7D 0F72 0F74 0062;0061 0F71 0F7D 0F72 0F74 0062;0061 0F71 0F7D 0F72 0F74 0062;0061 0F71 0F7D 0F72 0F74 0062; # (a◌ཽ◌ུ◌ི◌ཱb; a◌ཱ◌ཽ◌ི◌ུb; a◌ཱ◌ཽ◌ི◌ུb; a◌ཱ◌ཽ◌ི◌ུb; a◌ཱ◌ཽ◌ི◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN OO, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, LATIN SMALL LETTER B
+0061 0F74 0F72 0F71 0F80 0062;0061 0F71 0F72 0F80 0F74 0062;0061 0F71 0F72 0F80 0F74 0062;0061 0F71 0F72 0F80 0F74 0062;0061 0F71 0F72 0F80 0F74 0062; # (a◌ུ◌ི◌ཱ◌ྀb; a◌ཱ◌ི◌ྀ◌ུb; a◌ཱ◌ི◌ྀ◌ུb; a◌ཱ◌ི◌ྀ◌ུb; a◌ཱ◌ི◌ྀ◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, TIBETAN VOWEL SIGN REVERSED I, LATIN SMALL LETTER B
+0061 0F80 0F74 0F72 0F71 0062;0061 0F71 0F80 0F72 0F74 0062;0061 0F71 0F80 0F72 0F74 0062;0061 0F71 0F80 0F72 0F74 0062;0061 0F71 0F80 0F72 0F74 0062; # (a◌ྀ◌ུ◌ི◌ཱb; a◌ཱ◌ྀ◌ི◌ུb; a◌ཱ◌ྀ◌ི◌ུb; a◌ཱ◌ྀ◌ི◌ུb; a◌ཱ◌ྀ◌ི◌ུb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN REVERSED I, TIBETAN VOWEL SIGN U, TIBETAN VOWEL SIGN I, TIBETAN VOWEL SIGN AA, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0F82 0062;00E0 05AE 0F82 0315 0062;0061 05AE 0300 0F82 0315 0062;00E0 05AE 0F82 0315 0062;0061 05AE 0300 0F82 0315 0062; # (a◌̕◌̀◌֮◌ྂb; à◌֮◌ྂ◌̕b; a◌֮◌̀◌ྂ◌̕b; à◌֮◌ྂ◌̕b; a◌֮◌̀◌ྂ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TIBETAN SIGN NYI ZLA NAA DA, LATIN SMALL LETTER B
+0061 0F82 0315 0300 05AE 0062;0061 05AE 0F82 0300 0315 0062;0061 05AE 0F82 0300 0315 0062;0061 05AE 0F82 0300 0315 0062;0061 05AE 0F82 0300 0315 0062; # (a◌ྂ◌̕◌̀◌֮b; a◌֮◌ྂ◌̀◌̕b; a◌֮◌ྂ◌̀◌̕b; a◌֮◌ྂ◌̀◌̕b; a◌֮◌ྂ◌̀◌̕b; ) LATIN SMALL LETTER A, TIBETAN SIGN NYI ZLA NAA DA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0F83 0062;00E0 05AE 0F83 0315 0062;0061 05AE 0300 0F83 0315 0062;00E0 05AE 0F83 0315 0062;0061 05AE 0300 0F83 0315 0062; # (a◌̕◌̀◌֮◌ྃb; à◌֮◌ྃ◌̕b; a◌֮◌̀◌ྃ◌̕b; à◌֮◌ྃ◌̕b; a◌֮◌̀◌ྃ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TIBETAN SIGN SNA LDAN, LATIN SMALL LETTER B
+0061 0F83 0315 0300 05AE 0062;0061 05AE 0F83 0300 0315 0062;0061 05AE 0F83 0300 0315 0062;0061 05AE 0F83 0300 0315 0062;0061 05AE 0F83 0300 0315 0062; # (a◌ྃ◌̕◌̀◌֮b; a◌֮◌ྃ◌̀◌̕b; a◌֮◌ྃ◌̀◌̕b; a◌֮◌ྃ◌̀◌̕b; a◌֮◌ྃ◌̀◌̕b; ) LATIN SMALL LETTER A, TIBETAN SIGN SNA LDAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0F84 0062;0061 3099 094D 0F84 05B0 0062;0061 3099 094D 0F84 05B0 0062;0061 3099 094D 0F84 05B0 0062;0061 3099 094D 0F84 05B0 0062; # (a◌ְ◌्◌゙◌྄b; a◌゙◌्◌྄◌ְb; a◌゙◌्◌྄◌ְb; a◌゙◌्◌྄◌ְb; a◌゙◌्◌྄◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, TIBETAN MARK HALANTA, LATIN SMALL LETTER B
+0061 0F84 05B0 094D 3099 0062;0061 3099 0F84 094D 05B0 0062;0061 3099 0F84 094D 05B0 0062;0061 3099 0F84 094D 05B0 0062;0061 3099 0F84 094D 05B0 0062; # (a◌྄◌ְ◌्◌゙b; a◌゙◌྄◌्◌ְb; a◌゙◌྄◌्◌ְb; a◌゙◌྄◌्◌ְb; a◌゙◌྄◌्◌ְb; ) LATIN SMALL LETTER A, TIBETAN MARK HALANTA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0F86 0062;00E0 05AE 0F86 0315 0062;0061 05AE 0300 0F86 0315 0062;00E0 05AE 0F86 0315 0062;0061 05AE 0300 0F86 0315 0062; # (a◌̕◌̀◌֮◌྆b; à◌֮◌྆◌̕b; a◌֮◌̀◌྆◌̕b; à◌֮◌྆◌̕b; a◌֮◌̀◌྆◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TIBETAN SIGN LCI RTAGS, LATIN SMALL LETTER B
+0061 0F86 0315 0300 05AE 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062;0061 05AE 0F86 0300 0315 0062; # (a◌྆◌̕◌̀◌֮b; a◌֮◌྆◌̀◌̕b; a◌֮◌྆◌̀◌̕b; a◌֮◌྆◌̀◌̕b; a◌֮◌྆◌̀◌̕b; ) LATIN SMALL LETTER A, TIBETAN SIGN LCI RTAGS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 0F87 0062;00E0 05AE 0F87 0315 0062;0061 05AE 0300 0F87 0315 0062;00E0 05AE 0F87 0315 0062;0061 05AE 0300 0F87 0315 0062; # (a◌̕◌̀◌֮◌྇b; à◌֮◌྇◌̕b; a◌֮◌̀◌྇◌̕b; à◌֮◌྇◌̕b; a◌֮◌̀◌྇◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TIBETAN SIGN YANG RTAGS, LATIN SMALL LETTER B
+0061 0F87 0315 0300 05AE 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062;0061 05AE 0F87 0300 0315 0062; # (a◌྇◌̕◌̀◌֮b; a◌֮◌྇◌̀◌̕b; a◌֮◌྇◌̀◌̕b; a◌֮◌྇◌̀◌̕b; a◌֮◌྇◌̀◌̕b; ) LATIN SMALL LETTER A, TIBETAN SIGN YANG RTAGS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 0FC6 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062;0061 302A 0316 0FC6 059A 0062; # (a◌֚◌̖◌〪◌࿆b; a◌〪◌̖◌࿆◌֚b; a◌〪◌̖◌࿆◌֚b; a◌〪◌̖◌࿆◌֚b; a◌〪◌̖◌࿆◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TIBETAN SYMBOL PADMA GDAN, LATIN SMALL LETTER B
+0061 0FC6 059A 0316 302A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062;0061 302A 0FC6 0316 059A 0062; # (a◌࿆◌֚◌̖◌〪b; a◌〪◌࿆◌̖◌֚b; a◌〪◌࿆◌̖◌֚b; a◌〪◌࿆◌̖◌֚b; a◌〪◌࿆◌̖◌֚b; ) LATIN SMALL LETTER A, TIBETAN SYMBOL PADMA GDAN, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 1037 0062;0061 0334 093C 1037 3099 0062;0061 0334 093C 1037 3099 0062;0061 0334 093C 1037 3099 0062;0061 0334 093C 1037 3099 0062; # (a◌゙◌़◌̴◌့b; a◌̴◌़◌့◌゙b; a◌̴◌़◌့◌゙b; a◌̴◌़◌့◌゙b; a◌̴◌़◌့◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, MYANMAR SIGN DOT BELOW, LATIN SMALL LETTER B
+0061 1037 3099 093C 0334 0062;0061 0334 1037 093C 3099 0062;0061 0334 1037 093C 3099 0062;0061 0334 1037 093C 3099 0062;0061 0334 1037 093C 3099 0062; # (a◌့◌゙◌़◌̴b; a◌̴◌့◌़◌゙b; a◌̴◌့◌़◌゙b; a◌̴◌့◌़◌゙b; a◌̴◌့◌़◌゙b; ) LATIN SMALL LETTER A, MYANMAR SIGN DOT BELOW, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1039 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 05B0 0062;0061 3099 094D 1039 05B0 0062; # (a◌ְ◌्◌゙◌္b; a◌゙◌्◌္◌ְb; a◌゙◌्◌္◌ְb; a◌゙◌्◌္◌ְb; a◌゙◌्◌္◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, MYANMAR SIGN VIRAMA, LATIN SMALL LETTER B
+0061 1039 05B0 094D 3099 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062;0061 3099 1039 094D 05B0 0062; # (a◌္◌ְ◌्◌゙b; a◌゙◌္◌्◌ְb; a◌゙◌္◌्◌ְb; a◌゙◌္◌्◌ְb; a◌゙◌္◌्◌ְb; ) LATIN SMALL LETTER A, MYANMAR SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 103A 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 05B0 0062;0061 3099 094D 103A 05B0 0062; # (a◌ְ◌्◌゙◌်b; a◌゙◌्◌်◌ְb; a◌゙◌्◌်◌ְb; a◌゙◌्◌်◌ְb; a◌゙◌्◌်◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, MYANMAR SIGN ASAT, LATIN SMALL LETTER B
+0061 103A 05B0 094D 3099 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062;0061 3099 103A 094D 05B0 0062; # (a◌်◌ְ◌्◌゙b; a◌゙◌်◌्◌ְb; a◌゙◌်◌्◌ְb; a◌゙◌်◌्◌ְb; a◌゙◌်◌्◌ְb; ) LATIN SMALL LETTER A, MYANMAR SIGN ASAT, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 108D 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062;0061 302A 0316 108D 059A 0062; # (a◌֚◌̖◌〪◌ႍb; a◌〪◌̖◌ႍ◌֚b; a◌〪◌̖◌ႍ◌֚b; a◌〪◌̖◌ႍ◌֚b; a◌〪◌̖◌ႍ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE, LATIN SMALL LETTER B
+0061 108D 059A 0316 302A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062;0061 302A 108D 0316 059A 0062; # (a◌ႍ◌֚◌̖◌〪b; a◌〪◌ႍ◌̖◌֚b; a◌〪◌ႍ◌̖◌֚b; a◌〪◌ႍ◌̖◌֚b; a◌〪◌ႍ◌̖◌֚b; ) LATIN SMALL LETTER A, MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 135D 0062;00E0 05AE 135D 0315 0062;0061 05AE 0300 135D 0315 0062;00E0 05AE 135D 0315 0062;0061 05AE 0300 135D 0315 0062; # (a◌̕◌̀◌֮◌፝b; à◌֮◌፝◌̕b; a◌֮◌̀◌፝◌̕b; à◌֮◌፝◌̕b; a◌֮◌̀◌፝◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK, LATIN SMALL LETTER B
+0061 135D 0315 0300 05AE 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062;0061 05AE 135D 0300 0315 0062; # (a◌፝◌̕◌̀◌֮b; a◌֮◌፝◌̀◌̕b; a◌֮◌፝◌̀◌̕b; a◌֮◌፝◌̀◌̕b; a◌֮◌፝◌̀◌̕b; ) LATIN SMALL LETTER A, ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 135E 0062;00E0 05AE 135E 0315 0062;0061 05AE 0300 135E 0315 0062;00E0 05AE 135E 0315 0062;0061 05AE 0300 135E 0315 0062; # (a◌̕◌̀◌֮◌፞b; à◌֮◌፞◌̕b; a◌֮◌̀◌፞◌̕b; à◌֮◌፞◌̕b; a◌֮◌̀◌፞◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ETHIOPIC COMBINING VOWEL LENGTH MARK, LATIN SMALL LETTER B
+0061 135E 0315 0300 05AE 0062;0061 05AE 135E 0300 0315 0062;0061 05AE 135E 0300 0315 0062;0061 05AE 135E 0300 0315 0062;0061 05AE 135E 0300 0315 0062; # (a◌፞◌̕◌̀◌֮b; a◌֮◌፞◌̀◌̕b; a◌֮◌፞◌̀◌̕b; a◌֮◌፞◌̀◌̕b; a◌֮◌፞◌̀◌̕b; ) LATIN SMALL LETTER A, ETHIOPIC COMBINING VOWEL LENGTH MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 135F 0062;00E0 05AE 135F 0315 0062;0061 05AE 0300 135F 0315 0062;00E0 05AE 135F 0315 0062;0061 05AE 0300 135F 0315 0062; # (a◌̕◌̀◌֮◌፟b; à◌֮◌፟◌̕b; a◌֮◌̀◌፟◌̕b; à◌֮◌፟◌̕b; a◌֮◌̀◌፟◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ETHIOPIC COMBINING GEMINATION MARK, LATIN SMALL LETTER B
+0061 135F 0315 0300 05AE 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062;0061 05AE 135F 0300 0315 0062; # (a◌፟◌̕◌̀◌֮b; a◌֮◌፟◌̀◌̕b; a◌֮◌፟◌̀◌̕b; a◌֮◌፟◌̀◌̕b; a◌֮◌፟◌̀◌̕b; ) LATIN SMALL LETTER A, ETHIOPIC COMBINING GEMINATION MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1714 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 05B0 0062;0061 3099 094D 1714 05B0 0062; # (a◌ְ◌्◌゙◌᜔b; a◌゙◌्◌᜔◌ְb; a◌゙◌्◌᜔◌ְb; a◌゙◌्◌᜔◌ְb; a◌゙◌्◌᜔◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, TAGALOG SIGN VIRAMA, LATIN SMALL LETTER B
+0061 1714 05B0 094D 3099 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062;0061 3099 1714 094D 05B0 0062; # (a◌᜔◌ְ◌्◌゙b; a◌゙◌᜔◌्◌ְb; a◌゙◌᜔◌्◌ְb; a◌゙◌᜔◌्◌ְb; a◌゙◌᜔◌्◌ְb; ) LATIN SMALL LETTER A, TAGALOG SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1734 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062;0061 3099 094D 1734 05B0 0062; # (a◌ְ◌्◌゙◌᜴b; a◌゙◌्◌᜴◌ְb; a◌゙◌्◌᜴◌ְb; a◌゙◌्◌᜴◌ְb; a◌゙◌्◌᜴◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, HANUNOO SIGN PAMUDPOD, LATIN SMALL LETTER B
+0061 1734 05B0 094D 3099 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062;0061 3099 1734 094D 05B0 0062; # (a◌᜴◌ְ◌्◌゙b; a◌゙◌᜴◌्◌ְb; a◌゙◌᜴◌्◌ְb; a◌゙◌᜴◌्◌ְb; a◌゙◌᜴◌्◌ְb; ) LATIN SMALL LETTER A, HANUNOO SIGN PAMUDPOD, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 17D2 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 05B0 0062;0061 3099 094D 17D2 05B0 0062; # (a◌ְ◌्◌゙◌្b; a◌゙◌्◌្◌ְb; a◌゙◌्◌្◌ְb; a◌゙◌्◌្◌ְb; a◌゙◌्◌្◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, KHMER SIGN COENG, LATIN SMALL LETTER B
+0061 17D2 05B0 094D 3099 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062;0061 3099 17D2 094D 05B0 0062; # (a◌្◌ְ◌्◌゙b; a◌゙◌្◌्◌ְb; a◌゙◌្◌्◌ְb; a◌゙◌្◌्◌ְb; a◌゙◌្◌्◌ְb; ) LATIN SMALL LETTER A, KHMER SIGN COENG, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 17DD 0062;00E0 05AE 17DD 0315 0062;0061 05AE 0300 17DD 0315 0062;00E0 05AE 17DD 0315 0062;0061 05AE 0300 17DD 0315 0062; # (a◌̕◌̀◌֮◌៝b; à◌֮◌៝◌̕b; a◌֮◌̀◌៝◌̕b; à◌֮◌៝◌̕b; a◌֮◌̀◌៝◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, KHMER SIGN ATTHACAN, LATIN SMALL LETTER B
+0061 17DD 0315 0300 05AE 0062;0061 05AE 17DD 0300 0315 0062;0061 05AE 17DD 0300 0315 0062;0061 05AE 17DD 0300 0315 0062;0061 05AE 17DD 0300 0315 0062; # (a◌៝◌̕◌̀◌֮b; a◌֮◌៝◌̀◌̕b; a◌֮◌៝◌̀◌̕b; a◌֮◌៝◌̀◌̕b; a◌֮◌៝◌̀◌̕b; ) LATIN SMALL LETTER A, KHMER SIGN ATTHACAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0300 05AE 1D16D 18A9 0062;00E0 1D16D 05AE 18A9 0062;0061 1D16D 05AE 18A9 0300 0062;00E0 1D16D 05AE 18A9 0062;0061 1D16D 05AE 18A9 0300 0062; # (a◌̀◌𝅭֮◌ᢩb; à𝅭◌֮◌ᢩb; a𝅭◌֮◌ᢩ◌̀b; à𝅭◌֮◌ᢩb; a𝅭◌֮◌ᢩ◌̀b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, MONGOLIAN LETTER ALI GALI DAGALGA, LATIN SMALL LETTER B
+0061 18A9 0300 05AE 1D16D 0062;00E0 1D16D 18A9 05AE 0062;0061 1D16D 18A9 05AE 0300 0062;00E0 1D16D 18A9 05AE 0062;0061 1D16D 18A9 05AE 0300 0062; # (a◌ᢩ◌̀◌𝅭֮b; à𝅭◌ᢩ◌֮b; a𝅭◌ᢩ◌֮◌̀b; à𝅭◌ᢩ◌֮b; a𝅭◌ᢩ◌֮◌̀b; ) LATIN SMALL LETTER A, MONGOLIAN LETTER ALI GALI DAGALGA, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, LATIN SMALL LETTER B
+0061 302E 059A 0316 1939 0062;0061 0316 059A 1939 302E 0062;0061 0316 059A 1939 302E 0062;0061 0316 059A 1939 302E 0062;0061 0316 059A 1939 302E 0062; # (a〮◌֚◌̖◌᤹b; a◌̖◌֚◌᤹〮b; a◌̖◌֚◌᤹〮b; a◌̖◌֚◌᤹〮b; a◌̖◌֚◌᤹〮b; ) LATIN SMALL LETTER A, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, LIMBU SIGN MUKPHRENG, LATIN SMALL LETTER B
+0061 1939 302E 059A 0316 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062;0061 0316 1939 059A 302E 0062; # (a◌᤹〮◌֚◌̖b; a◌̖◌᤹◌֚〮b; a◌̖◌᤹◌֚〮b; a◌̖◌᤹◌֚〮b; a◌̖◌᤹◌֚〮b; ) LATIN SMALL LETTER A, LIMBU SIGN MUKPHRENG, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, LATIN SMALL LETTER B
+0061 0315 0300 05AE 193A 0062;00E0 05AE 193A 0315 0062;0061 05AE 0300 193A 0315 0062;00E0 05AE 193A 0315 0062;0061 05AE 0300 193A 0315 0062; # (a◌̕◌̀◌֮◌᤺b; à◌֮◌᤺◌̕b; a◌֮◌̀◌᤺◌̕b; à◌֮◌᤺◌̕b; a◌֮◌̀◌᤺◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LIMBU SIGN KEMPHRENG, LATIN SMALL LETTER B
+0061 193A 0315 0300 05AE 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062;0061 05AE 193A 0300 0315 0062; # (a◌᤺◌̕◌̀◌֮b; a◌֮◌᤺◌̀◌̕b; a◌֮◌᤺◌̀◌̕b; a◌֮◌᤺◌̀◌̕b; a◌֮◌᤺◌̀◌̕b; ) LATIN SMALL LETTER A, LIMBU SIGN KEMPHRENG, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 193B 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062;0061 302A 0316 193B 059A 0062; # (a◌֚◌̖◌〪◌᤻b; a◌〪◌̖◌᤻◌֚b; a◌〪◌̖◌᤻◌֚b; a◌〪◌̖◌᤻◌֚b; a◌〪◌̖◌᤻◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LIMBU SIGN SA-I, LATIN SMALL LETTER B
+0061 193B 059A 0316 302A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062;0061 302A 193B 0316 059A 0062; # (a◌᤻◌֚◌̖◌〪b; a◌〪◌᤻◌̖◌֚b; a◌〪◌᤻◌̖◌֚b; a◌〪◌᤻◌̖◌֚b; a◌〪◌᤻◌̖◌֚b; ) LATIN SMALL LETTER A, LIMBU SIGN SA-I, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1A17 0062;00E0 05AE 1A17 0315 0062;0061 05AE 0300 1A17 0315 0062;00E0 05AE 1A17 0315 0062;0061 05AE 0300 1A17 0315 0062; # (a◌̕◌̀◌֮◌ᨗb; à◌֮◌ᨗ◌̕b; a◌֮◌̀◌ᨗ◌̕b; à◌֮◌ᨗ◌̕b; a◌֮◌̀◌ᨗ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BUGINESE VOWEL SIGN I, LATIN SMALL LETTER B
+0061 1A17 0315 0300 05AE 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062;0061 05AE 1A17 0300 0315 0062; # (a◌ᨗ◌̕◌̀◌֮b; a◌֮◌ᨗ◌̀◌̕b; a◌֮◌ᨗ◌̀◌̕b; a◌֮◌ᨗ◌̀◌̕b; a◌֮◌ᨗ◌̀◌̕b; ) LATIN SMALL LETTER A, BUGINESE VOWEL SIGN I, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 1A18 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062;0061 302A 0316 1A18 059A 0062; # (a◌֚◌̖◌〪◌ᨘb; a◌〪◌̖◌ᨘ◌֚b; a◌〪◌̖◌ᨘ◌֚b; a◌〪◌̖◌ᨘ◌֚b; a◌〪◌̖◌ᨘ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, BUGINESE VOWEL SIGN U, LATIN SMALL LETTER B
+0061 1A18 059A 0316 302A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062;0061 302A 1A18 0316 059A 0062; # (a◌ᨘ◌֚◌̖◌〪b; a◌〪◌ᨘ◌̖◌֚b; a◌〪◌ᨘ◌̖◌֚b; a◌〪◌ᨘ◌̖◌֚b; a◌〪◌ᨘ◌̖◌֚b; ) LATIN SMALL LETTER A, BUGINESE VOWEL SIGN U, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1A60 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 05B0 0062;0061 3099 094D 1A60 05B0 0062; # (a◌ְ◌्◌゙◌᩠b; a◌゙◌्◌᩠◌ְb; a◌゙◌्◌᩠◌ְb; a◌゙◌्◌᩠◌ְb; a◌゙◌्◌᩠◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, TAI THAM SIGN SAKOT, LATIN SMALL LETTER B
+0061 1A60 05B0 094D 3099 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062;0061 3099 1A60 094D 05B0 0062; # (a◌᩠◌ְ◌्◌゙b; a◌゙◌᩠◌्◌ְb; a◌゙◌᩠◌्◌ְb; a◌゙◌᩠◌्◌ְb; a◌゙◌᩠◌्◌ְb; ) LATIN SMALL LETTER A, TAI THAM SIGN SAKOT, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1A75 0062;00E0 05AE 1A75 0315 0062;0061 05AE 0300 1A75 0315 0062;00E0 05AE 1A75 0315 0062;0061 05AE 0300 1A75 0315 0062; # (a◌̕◌̀◌֮◌᩵b; à◌֮◌᩵◌̕b; a◌֮◌̀◌᩵◌̕b; à◌֮◌᩵◌̕b; a◌֮◌̀◌᩵◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI THAM SIGN TONE-1, LATIN SMALL LETTER B
+0061 1A75 0315 0300 05AE 0062;0061 05AE 1A75 0300 0315 0062;0061 05AE 1A75 0300 0315 0062;0061 05AE 1A75 0300 0315 0062;0061 05AE 1A75 0300 0315 0062; # (a◌᩵◌̕◌̀◌֮b; a◌֮◌᩵◌̀◌̕b; a◌֮◌᩵◌̀◌̕b; a◌֮◌᩵◌̀◌̕b; a◌֮◌᩵◌̀◌̕b; ) LATIN SMALL LETTER A, TAI THAM SIGN TONE-1, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1A76 0062;00E0 05AE 1A76 0315 0062;0061 05AE 0300 1A76 0315 0062;00E0 05AE 1A76 0315 0062;0061 05AE 0300 1A76 0315 0062; # (a◌̕◌̀◌֮◌᩶b; à◌֮◌᩶◌̕b; a◌֮◌̀◌᩶◌̕b; à◌֮◌᩶◌̕b; a◌֮◌̀◌᩶◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI THAM SIGN TONE-2, LATIN SMALL LETTER B
+0061 1A76 0315 0300 05AE 0062;0061 05AE 1A76 0300 0315 0062;0061 05AE 1A76 0300 0315 0062;0061 05AE 1A76 0300 0315 0062;0061 05AE 1A76 0300 0315 0062; # (a◌᩶◌̕◌̀◌֮b; a◌֮◌᩶◌̀◌̕b; a◌֮◌᩶◌̀◌̕b; a◌֮◌᩶◌̀◌̕b; a◌֮◌᩶◌̀◌̕b; ) LATIN SMALL LETTER A, TAI THAM SIGN TONE-2, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1A77 0062;00E0 05AE 1A77 0315 0062;0061 05AE 0300 1A77 0315 0062;00E0 05AE 1A77 0315 0062;0061 05AE 0300 1A77 0315 0062; # (a◌̕◌̀◌֮◌᩷b; à◌֮◌᩷◌̕b; a◌֮◌̀◌᩷◌̕b; à◌֮◌᩷◌̕b; a◌֮◌̀◌᩷◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI THAM SIGN KHUEN TONE-3, LATIN SMALL LETTER B
+0061 1A77 0315 0300 05AE 0062;0061 05AE 1A77 0300 0315 0062;0061 05AE 1A77 0300 0315 0062;0061 05AE 1A77 0300 0315 0062;0061 05AE 1A77 0300 0315 0062; # (a◌᩷◌̕◌̀◌֮b; a◌֮◌᩷◌̀◌̕b; a◌֮◌᩷◌̀◌̕b; a◌֮◌᩷◌̀◌̕b; a◌֮◌᩷◌̀◌̕b; ) LATIN SMALL LETTER A, TAI THAM SIGN KHUEN TONE-3, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1A78 0062;00E0 05AE 1A78 0315 0062;0061 05AE 0300 1A78 0315 0062;00E0 05AE 1A78 0315 0062;0061 05AE 0300 1A78 0315 0062; # (a◌̕◌̀◌֮◌᩸b; à◌֮◌᩸◌̕b; a◌֮◌̀◌᩸◌̕b; à◌֮◌᩸◌̕b; a◌֮◌̀◌᩸◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI THAM SIGN KHUEN TONE-4, LATIN SMALL LETTER B
+0061 1A78 0315 0300 05AE 0062;0061 05AE 1A78 0300 0315 0062;0061 05AE 1A78 0300 0315 0062;0061 05AE 1A78 0300 0315 0062;0061 05AE 1A78 0300 0315 0062; # (a◌᩸◌̕◌̀◌֮b; a◌֮◌᩸◌̀◌̕b; a◌֮◌᩸◌̀◌̕b; a◌֮◌᩸◌̀◌̕b; a◌֮◌᩸◌̀◌̕b; ) LATIN SMALL LETTER A, TAI THAM SIGN KHUEN TONE-4, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1A79 0062;00E0 05AE 1A79 0315 0062;0061 05AE 0300 1A79 0315 0062;00E0 05AE 1A79 0315 0062;0061 05AE 0300 1A79 0315 0062; # (a◌̕◌̀◌֮◌᩹b; à◌֮◌᩹◌̕b; a◌֮◌̀◌᩹◌̕b; à◌֮◌᩹◌̕b; a◌֮◌̀◌᩹◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI THAM SIGN KHUEN TONE-5, LATIN SMALL LETTER B
+0061 1A79 0315 0300 05AE 0062;0061 05AE 1A79 0300 0315 0062;0061 05AE 1A79 0300 0315 0062;0061 05AE 1A79 0300 0315 0062;0061 05AE 1A79 0300 0315 0062; # (a◌᩹◌̕◌̀◌֮b; a◌֮◌᩹◌̀◌̕b; a◌֮◌᩹◌̀◌̕b; a◌֮◌᩹◌̀◌̕b; a◌֮◌᩹◌̀◌̕b; ) LATIN SMALL LETTER A, TAI THAM SIGN KHUEN TONE-5, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1A7A 0062;00E0 05AE 1A7A 0315 0062;0061 05AE 0300 1A7A 0315 0062;00E0 05AE 1A7A 0315 0062;0061 05AE 0300 1A7A 0315 0062; # (a◌̕◌̀◌֮◌᩺b; à◌֮◌᩺◌̕b; a◌֮◌̀◌᩺◌̕b; à◌֮◌᩺◌̕b; a◌֮◌̀◌᩺◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI THAM SIGN RA HAAM, LATIN SMALL LETTER B
+0061 1A7A 0315 0300 05AE 0062;0061 05AE 1A7A 0300 0315 0062;0061 05AE 1A7A 0300 0315 0062;0061 05AE 1A7A 0300 0315 0062;0061 05AE 1A7A 0300 0315 0062; # (a◌᩺◌̕◌̀◌֮b; a◌֮◌᩺◌̀◌̕b; a◌֮◌᩺◌̀◌̕b; a◌֮◌᩺◌̀◌̕b; a◌֮◌᩺◌̀◌̕b; ) LATIN SMALL LETTER A, TAI THAM SIGN RA HAAM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1A7B 0062;00E0 05AE 1A7B 0315 0062;0061 05AE 0300 1A7B 0315 0062;00E0 05AE 1A7B 0315 0062;0061 05AE 0300 1A7B 0315 0062; # (a◌̕◌̀◌֮◌᩻b; à◌֮◌᩻◌̕b; a◌֮◌̀◌᩻◌̕b; à◌֮◌᩻◌̕b; a◌֮◌̀◌᩻◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI THAM SIGN MAI SAM, LATIN SMALL LETTER B
+0061 1A7B 0315 0300 05AE 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062;0061 05AE 1A7B 0300 0315 0062; # (a◌᩻◌̕◌̀◌֮b; a◌֮◌᩻◌̀◌̕b; a◌֮◌᩻◌̀◌̕b; a◌֮◌᩻◌̀◌̕b; a◌֮◌᩻◌̀◌̕b; ) LATIN SMALL LETTER A, TAI THAM SIGN MAI SAM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1A7C 0062;00E0 05AE 1A7C 0315 0062;0061 05AE 0300 1A7C 0315 0062;00E0 05AE 1A7C 0315 0062;0061 05AE 0300 1A7C 0315 0062; # (a◌̕◌̀◌֮◌᩼b; à◌֮◌᩼◌̕b; a◌֮◌̀◌᩼◌̕b; à◌֮◌᩼◌̕b; a◌֮◌̀◌᩼◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI THAM SIGN KHUEN-LUE KARAN, LATIN SMALL LETTER B
+0061 1A7C 0315 0300 05AE 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062;0061 05AE 1A7C 0300 0315 0062; # (a◌᩼◌̕◌̀◌֮b; a◌֮◌᩼◌̀◌̕b; a◌֮◌᩼◌̀◌̕b; a◌֮◌᩼◌̀◌̕b; a◌֮◌᩼◌̀◌̕b; ) LATIN SMALL LETTER A, TAI THAM SIGN KHUEN-LUE KARAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 1A7F 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062;0061 302A 0316 1A7F 059A 0062; # (a◌֚◌̖◌〪◌᩿b; a◌〪◌̖◌᩿◌֚b; a◌〪◌̖◌᩿◌֚b; a◌〪◌̖◌᩿◌֚b; a◌〪◌̖◌᩿◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TAI THAM COMBINING CRYPTOGRAMMIC DOT, LATIN SMALL LETTER B
+0061 1A7F 059A 0316 302A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062;0061 302A 1A7F 0316 059A 0062; # (a◌᩿◌֚◌̖◌〪b; a◌〪◌᩿◌̖◌֚b; a◌〪◌᩿◌̖◌֚b; a◌〪◌᩿◌̖◌֚b; a◌〪◌᩿◌̖◌֚b; ) LATIN SMALL LETTER A, TAI THAM COMBINING CRYPTOGRAMMIC DOT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AB0 0062;00E0 05AE 1AB0 0315 0062;0061 05AE 0300 1AB0 0315 0062;00E0 05AE 1AB0 0315 0062;0061 05AE 0300 1AB0 0315 0062; # (a◌̕◌̀◌֮◌᪰b; à◌֮◌᪰◌̕b; a◌֮◌̀◌᪰◌̕b; à◌֮◌᪰◌̕b; a◌֮◌̀◌᪰◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOUBLED CIRCUMFLEX ACCENT, LATIN SMALL LETTER B
+0061 1AB0 0315 0300 05AE 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062;0061 05AE 1AB0 0300 0315 0062; # (a◌᪰◌̕◌̀◌֮b; a◌֮◌᪰◌̀◌̕b; a◌֮◌᪰◌̀◌̕b; a◌֮◌᪰◌̀◌̕b; a◌֮◌᪰◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOUBLED CIRCUMFLEX ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AB1 0062;00E0 05AE 1AB1 0315 0062;0061 05AE 0300 1AB1 0315 0062;00E0 05AE 1AB1 0315 0062;0061 05AE 0300 1AB1 0315 0062; # (a◌̕◌̀◌֮◌᪱b; à◌֮◌᪱◌̕b; a◌֮◌̀◌᪱◌̕b; à◌֮◌᪱◌̕b; a◌֮◌̀◌᪱◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DIAERESIS-RING, LATIN SMALL LETTER B
+0061 1AB1 0315 0300 05AE 0062;0061 05AE 1AB1 0300 0315 0062;0061 05AE 1AB1 0300 0315 0062;0061 05AE 1AB1 0300 0315 0062;0061 05AE 1AB1 0300 0315 0062; # (a◌᪱◌̕◌̀◌֮b; a◌֮◌᪱◌̀◌̕b; a◌֮◌᪱◌̀◌̕b; a◌֮◌᪱◌̀◌̕b; a◌֮◌᪱◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DIAERESIS-RING, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AB2 0062;00E0 05AE 1AB2 0315 0062;0061 05AE 0300 1AB2 0315 0062;00E0 05AE 1AB2 0315 0062;0061 05AE 0300 1AB2 0315 0062; # (a◌̕◌̀◌֮◌᪲b; à◌֮◌᪲◌̕b; a◌֮◌̀◌᪲◌̕b; à◌֮◌᪲◌̕b; a◌֮◌̀◌᪲◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING INFINITY, LATIN SMALL LETTER B
+0061 1AB2 0315 0300 05AE 0062;0061 05AE 1AB2 0300 0315 0062;0061 05AE 1AB2 0300 0315 0062;0061 05AE 1AB2 0300 0315 0062;0061 05AE 1AB2 0300 0315 0062; # (a◌᪲◌̕◌̀◌֮b; a◌֮◌᪲◌̀◌̕b; a◌֮◌᪲◌̀◌̕b; a◌֮◌᪲◌̀◌̕b; a◌֮◌᪲◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING INFINITY, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AB3 0062;00E0 05AE 1AB3 0315 0062;0061 05AE 0300 1AB3 0315 0062;00E0 05AE 1AB3 0315 0062;0061 05AE 0300 1AB3 0315 0062; # (a◌̕◌̀◌֮◌᪳b; à◌֮◌᪳◌̕b; a◌֮◌̀◌᪳◌̕b; à◌֮◌᪳◌̕b; a◌֮◌̀◌᪳◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOWNWARDS ARROW, LATIN SMALL LETTER B
+0061 1AB3 0315 0300 05AE 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062;0061 05AE 1AB3 0300 0315 0062; # (a◌᪳◌̕◌̀◌֮b; a◌֮◌᪳◌̀◌̕b; a◌֮◌᪳◌̀◌̕b; a◌֮◌᪳◌̀◌̕b; a◌֮◌᪳◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOWNWARDS ARROW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1AB4 0062;00E0 05AE 1AB4 0315 0062;0061 05AE 0300 1AB4 0315 0062;00E0 05AE 1AB4 0315 0062;0061 05AE 0300 1AB4 0315 0062; # (a◌̕◌̀◌֮◌᪴b; à◌֮◌᪴◌̕b; a◌֮◌̀◌᪴◌̕b; à◌֮◌᪴◌̕b; a◌֮◌̀◌᪴◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING TRIPLE DOT, LATIN SMALL LETTER B
+0061 1AB4 0315 0300 05AE 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062;0061 05AE 1AB4 0300 0315 0062; # (a◌᪴◌̕◌̀◌֮b; a◌֮◌᪴◌̀◌̕b; a◌֮◌᪴◌̀◌̕b; a◌֮◌᪴◌̀◌̕b; a◌֮◌᪴◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING TRIPLE DOT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 1AB5 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062;0061 302A 0316 1AB5 059A 0062; # (a◌֚◌̖◌〪◌᪵b; a◌〪◌̖◌᪵◌֚b; a◌〪◌̖◌᪵◌֚b; a◌〪◌̖◌᪵◌֚b; a◌〪◌̖◌᪵◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING X-X BELOW, LATIN SMALL LETTER B
+0061 1AB5 059A 0316 302A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062;0061 302A 1AB5 0316 059A 0062; # (a◌᪵◌֚◌̖◌〪b; a◌〪◌᪵◌̖◌֚b; a◌〪◌᪵◌̖◌֚b; a◌〪◌᪵◌̖◌֚b; a◌〪◌᪵◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING X-X BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1AB6 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062;0061 302A 0316 1AB6 059A 0062; # (a◌֚◌̖◌〪◌᪶b; a◌〪◌̖◌᪶◌֚b; a◌〪◌̖◌᪶◌֚b; a◌〪◌̖◌᪶◌֚b; a◌〪◌̖◌᪶◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING WIGGLY LINE BELOW, LATIN SMALL LETTER B
+0061 1AB6 059A 0316 302A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062;0061 302A 1AB6 0316 059A 0062; # (a◌᪶◌֚◌̖◌〪b; a◌〪◌᪶◌̖◌֚b; a◌〪◌᪶◌̖◌֚b; a◌〪◌᪶◌̖◌֚b; a◌〪◌᪶◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING WIGGLY LINE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1AB7 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062;0061 302A 0316 1AB7 059A 0062; # (a◌֚◌̖◌〪◌᪷b; a◌〪◌̖◌᪷◌֚b; a◌〪◌̖◌᪷◌֚b; a◌〪◌̖◌᪷◌֚b; a◌〪◌̖◌᪷◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING OPEN MARK BELOW, LATIN SMALL LETTER B
+0061 1AB7 059A 0316 302A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062;0061 302A 1AB7 0316 059A 0062; # (a◌᪷◌֚◌̖◌〪b; a◌〪◌᪷◌̖◌֚b; a◌〪◌᪷◌̖◌֚b; a◌〪◌᪷◌̖◌֚b; a◌〪◌᪷◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING OPEN MARK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1AB8 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062;0061 302A 0316 1AB8 059A 0062; # (a◌֚◌̖◌〪◌᪸b; a◌〪◌̖◌᪸◌֚b; a◌〪◌̖◌᪸◌֚b; a◌〪◌̖◌᪸◌֚b; a◌〪◌̖◌᪸◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING DOUBLE OPEN MARK BELOW, LATIN SMALL LETTER B
+0061 1AB8 059A 0316 302A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062;0061 302A 1AB8 0316 059A 0062; # (a◌᪸◌֚◌̖◌〪b; a◌〪◌᪸◌̖◌֚b; a◌〪◌᪸◌̖◌֚b; a◌〪◌᪸◌̖◌֚b; a◌〪◌᪸◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING DOUBLE OPEN MARK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1AB9 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062;0061 302A 0316 1AB9 059A 0062; # (a◌֚◌̖◌〪◌᪹b; a◌〪◌̖◌᪹◌֚b; a◌〪◌̖◌᪹◌֚b; a◌〪◌̖◌᪹◌֚b; a◌〪◌̖◌᪹◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LIGHT CENTRALIZATION STROKE BELOW, LATIN SMALL LETTER B
+0061 1AB9 059A 0316 302A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062;0061 302A 1AB9 0316 059A 0062; # (a◌᪹◌֚◌̖◌〪b; a◌〪◌᪹◌̖◌֚b; a◌〪◌᪹◌̖◌֚b; a◌〪◌᪹◌̖◌֚b; a◌〪◌᪹◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LIGHT CENTRALIZATION STROKE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1ABA 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062;0061 302A 0316 1ABA 059A 0062; # (a◌֚◌̖◌〪◌᪺b; a◌〪◌̖◌᪺◌֚b; a◌〪◌̖◌᪺◌֚b; a◌〪◌̖◌᪺◌֚b; a◌〪◌̖◌᪺◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING STRONG CENTRALIZATION STROKE BELOW, LATIN SMALL LETTER B
+0061 1ABA 059A 0316 302A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062;0061 302A 1ABA 0316 059A 0062; # (a◌᪺◌֚◌̖◌〪b; a◌〪◌᪺◌̖◌֚b; a◌〪◌᪺◌̖◌֚b; a◌〪◌᪺◌̖◌֚b; a◌〪◌᪺◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING STRONG CENTRALIZATION STROKE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1ABB 0062;00E0 05AE 1ABB 0315 0062;0061 05AE 0300 1ABB 0315 0062;00E0 05AE 1ABB 0315 0062;0061 05AE 0300 1ABB 0315 0062; # (a◌̕◌̀◌֮◌᪻b; à◌֮◌᪻◌̕b; a◌֮◌̀◌᪻◌̕b; à◌֮◌᪻◌̕b; a◌֮◌̀◌᪻◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING PARENTHESES ABOVE, LATIN SMALL LETTER B
+0061 1ABB 0315 0300 05AE 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062;0061 05AE 1ABB 0300 0315 0062; # (a◌᪻◌̕◌̀◌֮b; a◌֮◌᪻◌̀◌̕b; a◌֮◌᪻◌̀◌̕b; a◌֮◌᪻◌̀◌̕b; a◌֮◌᪻◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING PARENTHESES ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1ABC 0062;00E0 05AE 1ABC 0315 0062;0061 05AE 0300 1ABC 0315 0062;00E0 05AE 1ABC 0315 0062;0061 05AE 0300 1ABC 0315 0062; # (a◌̕◌̀◌֮◌᪼b; à◌֮◌᪼◌̕b; a◌֮◌̀◌᪼◌̕b; à◌֮◌᪼◌̕b; a◌֮◌̀◌᪼◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOUBLE PARENTHESES ABOVE, LATIN SMALL LETTER B
+0061 1ABC 0315 0300 05AE 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062;0061 05AE 1ABC 0300 0315 0062; # (a◌᪼◌̕◌̀◌֮b; a◌֮◌᪼◌̀◌̕b; a◌֮◌᪼◌̀◌̕b; a◌֮◌᪼◌̀◌̕b; a◌֮◌᪼◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOUBLE PARENTHESES ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 1ABD 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062;0061 302A 0316 1ABD 059A 0062; # (a◌֚◌̖◌〪◌᪽b; a◌〪◌̖◌᪽◌֚b; a◌〪◌̖◌᪽◌֚b; a◌〪◌̖◌᪽◌֚b; a◌〪◌̖◌᪽◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING PARENTHESES BELOW, LATIN SMALL LETTER B
+0061 1ABD 059A 0316 302A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062;0061 302A 1ABD 0316 059A 0062; # (a◌᪽◌֚◌̖◌〪b; a◌〪◌᪽◌̖◌֚b; a◌〪◌᪽◌̖◌֚b; a◌〪◌᪽◌̖◌֚b; a◌〪◌᪽◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING PARENTHESES BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 1B34 0062;0061 0334 093C 1B34 3099 0062;0061 0334 093C 1B34 3099 0062;0061 0334 093C 1B34 3099 0062;0061 0334 093C 1B34 3099 0062; # (a◌゙◌़◌̴◌᬴b; a◌̴◌़◌᬴◌゙b; a◌̴◌़◌᬴◌゙b; a◌̴◌़◌᬴◌゙b; a◌̴◌़◌᬴◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, BALINESE SIGN REREKAN, LATIN SMALL LETTER B
+0061 1B34 3099 093C 0334 0062;0061 0334 1B34 093C 3099 0062;0061 0334 1B34 093C 3099 0062;0061 0334 1B34 093C 3099 0062;0061 0334 1B34 093C 3099 0062; # (a◌᬴◌゙◌़◌̴b; a◌̴◌᬴◌़◌゙b; a◌̴◌᬴◌़◌゙b; a◌̴◌᬴◌़◌゙b; a◌̴◌᬴◌़◌゙b; ) LATIN SMALL LETTER A, BALINESE SIGN REREKAN, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1B44 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 05B0 0062;0061 3099 094D 1B44 05B0 0062; # (a◌ְ◌्◌゙᭄b; a◌゙◌्᭄◌ְb; a◌゙◌्᭄◌ְb; a◌゙◌्᭄◌ְb; a◌゙◌्᭄◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, BALINESE ADEG ADEG, LATIN SMALL LETTER B
+0061 1B44 05B0 094D 3099 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062;0061 3099 1B44 094D 05B0 0062; # (a᭄◌ְ◌्◌゙b; a◌゙᭄◌्◌ְb; a◌゙᭄◌्◌ְb; a◌゙᭄◌्◌ְb; a◌゙᭄◌्◌ְb; ) LATIN SMALL LETTER A, BALINESE ADEG ADEG, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1B6B 0062;00E0 05AE 1B6B 0315 0062;0061 05AE 0300 1B6B 0315 0062;00E0 05AE 1B6B 0315 0062;0061 05AE 0300 1B6B 0315 0062; # (a◌̕◌̀◌֮◌᭫b; à◌֮◌᭫◌̕b; a◌֮◌̀◌᭫◌̕b; à◌֮◌᭫◌̕b; a◌֮◌̀◌᭫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BALINESE MUSICAL SYMBOL COMBINING TEGEH, LATIN SMALL LETTER B
+0061 1B6B 0315 0300 05AE 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062;0061 05AE 1B6B 0300 0315 0062; # (a◌᭫◌̕◌̀◌֮b; a◌֮◌᭫◌̀◌̕b; a◌֮◌᭫◌̀◌̕b; a◌֮◌᭫◌̀◌̕b; a◌֮◌᭫◌̀◌̕b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING TEGEH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 1B6C 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062;0061 302A 0316 1B6C 059A 0062; # (a◌֚◌̖◌〪◌᭬b; a◌〪◌̖◌᭬◌֚b; a◌〪◌̖◌᭬◌֚b; a◌〪◌̖◌᭬◌֚b; a◌〪◌̖◌᭬◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, BALINESE MUSICAL SYMBOL COMBINING ENDEP, LATIN SMALL LETTER B
+0061 1B6C 059A 0316 302A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062;0061 302A 1B6C 0316 059A 0062; # (a◌᭬◌֚◌̖◌〪b; a◌〪◌᭬◌̖◌֚b; a◌〪◌᭬◌̖◌֚b; a◌〪◌᭬◌̖◌֚b; a◌〪◌᭬◌̖◌֚b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING ENDEP, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1B6D 0062;00E0 05AE 1B6D 0315 0062;0061 05AE 0300 1B6D 0315 0062;00E0 05AE 1B6D 0315 0062;0061 05AE 0300 1B6D 0315 0062; # (a◌̕◌̀◌֮◌᭭b; à◌֮◌᭭◌̕b; a◌֮◌̀◌᭭◌̕b; à◌֮◌᭭◌̕b; a◌֮◌̀◌᭭◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BALINESE MUSICAL SYMBOL COMBINING KEMPUL, LATIN SMALL LETTER B
+0061 1B6D 0315 0300 05AE 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062;0061 05AE 1B6D 0300 0315 0062; # (a◌᭭◌̕◌̀◌֮b; a◌֮◌᭭◌̀◌̕b; a◌֮◌᭭◌̀◌̕b; a◌֮◌᭭◌̀◌̕b; a◌֮◌᭭◌̀◌̕b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING KEMPUL, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1B6E 0062;00E0 05AE 1B6E 0315 0062;0061 05AE 0300 1B6E 0315 0062;00E0 05AE 1B6E 0315 0062;0061 05AE 0300 1B6E 0315 0062; # (a◌̕◌̀◌֮◌᭮b; à◌֮◌᭮◌̕b; a◌֮◌̀◌᭮◌̕b; à◌֮◌᭮◌̕b; a◌֮◌̀◌᭮◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BALINESE MUSICAL SYMBOL COMBINING KEMPLI, LATIN SMALL LETTER B
+0061 1B6E 0315 0300 05AE 0062;0061 05AE 1B6E 0300 0315 0062;0061 05AE 1B6E 0300 0315 0062;0061 05AE 1B6E 0300 0315 0062;0061 05AE 1B6E 0300 0315 0062; # (a◌᭮◌̕◌̀◌֮b; a◌֮◌᭮◌̀◌̕b; a◌֮◌᭮◌̀◌̕b; a◌֮◌᭮◌̀◌̕b; a◌֮◌᭮◌̀◌̕b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING KEMPLI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1B6F 0062;00E0 05AE 1B6F 0315 0062;0061 05AE 0300 1B6F 0315 0062;00E0 05AE 1B6F 0315 0062;0061 05AE 0300 1B6F 0315 0062; # (a◌̕◌̀◌֮◌᭯b; à◌֮◌᭯◌̕b; a◌֮◌̀◌᭯◌̕b; à◌֮◌᭯◌̕b; a◌֮◌̀◌᭯◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BALINESE MUSICAL SYMBOL COMBINING JEGOGAN, LATIN SMALL LETTER B
+0061 1B6F 0315 0300 05AE 0062;0061 05AE 1B6F 0300 0315 0062;0061 05AE 1B6F 0300 0315 0062;0061 05AE 1B6F 0300 0315 0062;0061 05AE 1B6F 0300 0315 0062; # (a◌᭯◌̕◌̀◌֮b; a◌֮◌᭯◌̀◌̕b; a◌֮◌᭯◌̀◌̕b; a◌֮◌᭯◌̀◌̕b; a◌֮◌᭯◌̀◌̕b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING JEGOGAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1B70 0062;00E0 05AE 1B70 0315 0062;0061 05AE 0300 1B70 0315 0062;00E0 05AE 1B70 0315 0062;0061 05AE 0300 1B70 0315 0062; # (a◌̕◌̀◌֮◌᭰b; à◌֮◌᭰◌̕b; a◌֮◌̀◌᭰◌̕b; à◌֮◌᭰◌̕b; a◌֮◌̀◌᭰◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN, LATIN SMALL LETTER B
+0061 1B70 0315 0300 05AE 0062;0061 05AE 1B70 0300 0315 0062;0061 05AE 1B70 0300 0315 0062;0061 05AE 1B70 0300 0315 0062;0061 05AE 1B70 0300 0315 0062; # (a◌᭰◌̕◌̀◌֮b; a◌֮◌᭰◌̀◌̕b; a◌֮◌᭰◌̀◌̕b; a◌֮◌᭰◌̀◌̕b; a◌֮◌᭰◌̀◌̕b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1B71 0062;00E0 05AE 1B71 0315 0062;0061 05AE 0300 1B71 0315 0062;00E0 05AE 1B71 0315 0062;0061 05AE 0300 1B71 0315 0062; # (a◌̕◌̀◌֮◌᭱b; à◌֮◌᭱◌̕b; a◌֮◌̀◌᭱◌̕b; à◌֮◌᭱◌̕b; a◌֮◌̀◌᭱◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN, LATIN SMALL LETTER B
+0061 1B71 0315 0300 05AE 0062;0061 05AE 1B71 0300 0315 0062;0061 05AE 1B71 0300 0315 0062;0061 05AE 1B71 0300 0315 0062;0061 05AE 1B71 0300 0315 0062; # (a◌᭱◌̕◌̀◌֮b; a◌֮◌᭱◌̀◌̕b; a◌֮◌᭱◌̀◌̕b; a◌֮◌᭱◌̀◌̕b; a◌֮◌᭱◌̀◌̕b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1B72 0062;00E0 05AE 1B72 0315 0062;0061 05AE 0300 1B72 0315 0062;00E0 05AE 1B72 0315 0062;0061 05AE 0300 1B72 0315 0062; # (a◌̕◌̀◌֮◌᭲b; à◌֮◌᭲◌̕b; a◌֮◌̀◌᭲◌̕b; à◌֮◌᭲◌̕b; a◌֮◌̀◌᭲◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BALINESE MUSICAL SYMBOL COMBINING BENDE, LATIN SMALL LETTER B
+0061 1B72 0315 0300 05AE 0062;0061 05AE 1B72 0300 0315 0062;0061 05AE 1B72 0300 0315 0062;0061 05AE 1B72 0300 0315 0062;0061 05AE 1B72 0300 0315 0062; # (a◌᭲◌̕◌̀◌֮b; a◌֮◌᭲◌̀◌̕b; a◌֮◌᭲◌̀◌̕b; a◌֮◌᭲◌̀◌̕b; a◌֮◌᭲◌̀◌̕b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING BENDE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1B73 0062;00E0 05AE 1B73 0315 0062;0061 05AE 0300 1B73 0315 0062;00E0 05AE 1B73 0315 0062;0061 05AE 0300 1B73 0315 0062; # (a◌̕◌̀◌֮◌᭳b; à◌֮◌᭳◌̕b; a◌֮◌̀◌᭳◌̕b; à◌֮◌᭳◌̕b; a◌֮◌̀◌᭳◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BALINESE MUSICAL SYMBOL COMBINING GONG, LATIN SMALL LETTER B
+0061 1B73 0315 0300 05AE 0062;0061 05AE 1B73 0300 0315 0062;0061 05AE 1B73 0300 0315 0062;0061 05AE 1B73 0300 0315 0062;0061 05AE 1B73 0300 0315 0062; # (a◌᭳◌̕◌̀◌֮b; a◌֮◌᭳◌̀◌̕b; a◌֮◌᭳◌̀◌̕b; a◌֮◌᭳◌̀◌̕b; a◌֮◌᭳◌̀◌̕b; ) LATIN SMALL LETTER A, BALINESE MUSICAL SYMBOL COMBINING GONG, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1BAA 0062;0061 3099 094D 1BAA 05B0 0062;0061 3099 094D 1BAA 05B0 0062;0061 3099 094D 1BAA 05B0 0062;0061 3099 094D 1BAA 05B0 0062; # (a◌ְ◌्◌゙᮪b; a◌゙◌्᮪◌ְb; a◌゙◌्᮪◌ְb; a◌゙◌्᮪◌ְb; a◌゙◌्᮪◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, SUNDANESE SIGN PAMAAEH, LATIN SMALL LETTER B
+0061 1BAA 05B0 094D 3099 0062;0061 3099 1BAA 094D 05B0 0062;0061 3099 1BAA 094D 05B0 0062;0061 3099 1BAA 094D 05B0 0062;0061 3099 1BAA 094D 05B0 0062; # (a᮪◌ְ◌्◌゙b; a◌゙᮪◌्◌ְb; a◌゙᮪◌्◌ְb; a◌゙᮪◌्◌ְb; a◌゙᮪◌्◌ְb; ) LATIN SMALL LETTER A, SUNDANESE SIGN PAMAAEH, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1BAB 0062;0061 3099 094D 1BAB 05B0 0062;0061 3099 094D 1BAB 05B0 0062;0061 3099 094D 1BAB 05B0 0062;0061 3099 094D 1BAB 05B0 0062; # (a◌ְ◌्◌゙◌᮫b; a◌゙◌्◌᮫◌ְb; a◌゙◌्◌᮫◌ְb; a◌゙◌्◌᮫◌ְb; a◌゙◌्◌᮫◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, SUNDANESE SIGN VIRAMA, LATIN SMALL LETTER B
+0061 1BAB 05B0 094D 3099 0062;0061 3099 1BAB 094D 05B0 0062;0061 3099 1BAB 094D 05B0 0062;0061 3099 1BAB 094D 05B0 0062;0061 3099 1BAB 094D 05B0 0062; # (a◌᮫◌ְ◌्◌゙b; a◌゙◌᮫◌्◌ְb; a◌゙◌᮫◌्◌ְb; a◌゙◌᮫◌्◌ְb; a◌゙◌᮫◌्◌ְb; ) LATIN SMALL LETTER A, SUNDANESE SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 1BE6 0062;0061 0334 093C 1BE6 3099 0062;0061 0334 093C 1BE6 3099 0062;0061 0334 093C 1BE6 3099 0062;0061 0334 093C 1BE6 3099 0062; # (a◌゙◌़◌̴◌᯦b; a◌̴◌़◌᯦◌゙b; a◌̴◌़◌᯦◌゙b; a◌̴◌़◌᯦◌゙b; a◌̴◌़◌᯦◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, BATAK SIGN TOMPI, LATIN SMALL LETTER B
+0061 1BE6 3099 093C 0334 0062;0061 0334 1BE6 093C 3099 0062;0061 0334 1BE6 093C 3099 0062;0061 0334 1BE6 093C 3099 0062;0061 0334 1BE6 093C 3099 0062; # (a◌᯦◌゙◌़◌̴b; a◌̴◌᯦◌़◌゙b; a◌̴◌᯦◌़◌゙b; a◌̴◌᯦◌़◌゙b; a◌̴◌᯦◌़◌゙b; ) LATIN SMALL LETTER A, BATAK SIGN TOMPI, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1BF2 0062;0061 3099 094D 1BF2 05B0 0062;0061 3099 094D 1BF2 05B0 0062;0061 3099 094D 1BF2 05B0 0062;0061 3099 094D 1BF2 05B0 0062; # (a◌ְ◌्◌゙᯲b; a◌゙◌्᯲◌ְb; a◌゙◌्᯲◌ְb; a◌゙◌्᯲◌ְb; a◌゙◌्᯲◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, BATAK PANGOLAT, LATIN SMALL LETTER B
+0061 1BF2 05B0 094D 3099 0062;0061 3099 1BF2 094D 05B0 0062;0061 3099 1BF2 094D 05B0 0062;0061 3099 1BF2 094D 05B0 0062;0061 3099 1BF2 094D 05B0 0062; # (a᯲◌ְ◌्◌゙b; a◌゙᯲◌्◌ְb; a◌゙᯲◌्◌ְb; a◌゙᯲◌्◌ְb; a◌゙᯲◌्◌ְb; ) LATIN SMALL LETTER A, BATAK PANGOLAT, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1BF3 0062;0061 3099 094D 1BF3 05B0 0062;0061 3099 094D 1BF3 05B0 0062;0061 3099 094D 1BF3 05B0 0062;0061 3099 094D 1BF3 05B0 0062; # (a◌ְ◌्◌゙᯳b; a◌゙◌्᯳◌ְb; a◌゙◌्᯳◌ְb; a◌゙◌्᯳◌ְb; a◌゙◌्᯳◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, BATAK PANONGONAN, LATIN SMALL LETTER B
+0061 1BF3 05B0 094D 3099 0062;0061 3099 1BF3 094D 05B0 0062;0061 3099 1BF3 094D 05B0 0062;0061 3099 1BF3 094D 05B0 0062;0061 3099 1BF3 094D 05B0 0062; # (a᯳◌ְ◌्◌゙b; a◌゙᯳◌्◌ְb; a◌゙᯳◌्◌ְb; a◌゙᯳◌्◌ְb; a◌゙᯳◌्◌ְb; ) LATIN SMALL LETTER A, BATAK PANONGONAN, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 1C37 0062;0061 0334 093C 1C37 3099 0062;0061 0334 093C 1C37 3099 0062;0061 0334 093C 1C37 3099 0062;0061 0334 093C 1C37 3099 0062; # (a◌゙◌़◌̴◌᰷b; a◌̴◌़◌᰷◌゙b; a◌̴◌़◌᰷◌゙b; a◌̴◌़◌᰷◌゙b; a◌̴◌़◌᰷◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LEPCHA SIGN NUKTA, LATIN SMALL LETTER B
+0061 1C37 3099 093C 0334 0062;0061 0334 1C37 093C 3099 0062;0061 0334 1C37 093C 3099 0062;0061 0334 1C37 093C 3099 0062;0061 0334 1C37 093C 3099 0062; # (a◌᰷◌゙◌़◌̴b; a◌̴◌᰷◌़◌゙b; a◌̴◌᰷◌़◌゙b; a◌̴◌᰷◌़◌゙b; a◌̴◌᰷◌़◌゙b; ) LATIN SMALL LETTER A, LEPCHA SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1CD0 0062;00E0 05AE 1CD0 0315 0062;0061 05AE 0300 1CD0 0315 0062;00E0 05AE 1CD0 0315 0062;0061 05AE 0300 1CD0 0315 0062; # (a◌̕◌̀◌֮◌᳐b; à◌֮◌᳐◌̕b; a◌֮◌̀◌᳐◌̕b; à◌֮◌᳐◌̕b; a◌֮◌̀◌᳐◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE KARSHANA, LATIN SMALL LETTER B
+0061 1CD0 0315 0300 05AE 0062;0061 05AE 1CD0 0300 0315 0062;0061 05AE 1CD0 0300 0315 0062;0061 05AE 1CD0 0300 0315 0062;0061 05AE 1CD0 0300 0315 0062; # (a◌᳐◌̕◌̀◌֮b; a◌֮◌᳐◌̀◌̕b; a◌֮◌᳐◌̀◌̕b; a◌֮◌᳐◌̀◌̕b; a◌֮◌᳐◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE KARSHANA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1CD1 0062;00E0 05AE 1CD1 0315 0062;0061 05AE 0300 1CD1 0315 0062;00E0 05AE 1CD1 0315 0062;0061 05AE 0300 1CD1 0315 0062; # (a◌̕◌̀◌֮◌᳑b; à◌֮◌᳑◌̕b; a◌֮◌̀◌᳑◌̕b; à◌֮◌᳑◌̕b; a◌֮◌̀◌᳑◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE SHARA, LATIN SMALL LETTER B
+0061 1CD1 0315 0300 05AE 0062;0061 05AE 1CD1 0300 0315 0062;0061 05AE 1CD1 0300 0315 0062;0061 05AE 1CD1 0300 0315 0062;0061 05AE 1CD1 0300 0315 0062; # (a◌᳑◌̕◌̀◌֮b; a◌֮◌᳑◌̀◌̕b; a◌֮◌᳑◌̀◌̕b; a◌֮◌᳑◌̀◌̕b; a◌֮◌᳑◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE SHARA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1CD2 0062;00E0 05AE 1CD2 0315 0062;0061 05AE 0300 1CD2 0315 0062;00E0 05AE 1CD2 0315 0062;0061 05AE 0300 1CD2 0315 0062; # (a◌̕◌̀◌֮◌᳒b; à◌֮◌᳒◌̕b; a◌֮◌̀◌᳒◌̕b; à◌֮◌᳒◌̕b; a◌֮◌̀◌᳒◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE PRENKHA, LATIN SMALL LETTER B
+0061 1CD2 0315 0300 05AE 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062;0061 05AE 1CD2 0300 0315 0062; # (a◌᳒◌̕◌̀◌֮b; a◌֮◌᳒◌̀◌̕b; a◌֮◌᳒◌̀◌̕b; a◌֮◌᳒◌̀◌̕b; a◌֮◌᳒◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE PRENKHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 093C 0334 1CD4 0062;0061 0334 1CD4 093C 0062;0061 0334 1CD4 093C 0062;0061 0334 1CD4 093C 0062;0061 0334 1CD4 093C 0062; # (a◌़◌̴◌᳔b; a◌̴◌᳔◌़b; a◌̴◌᳔◌़b; a◌̴◌᳔◌़b; a◌̴◌᳔◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, VEDIC SIGN YAJURVEDIC MIDLINE SVARITA, LATIN SMALL LETTER B
+0061 1CD4 093C 0334 0062;0061 1CD4 0334 093C 0062;0061 1CD4 0334 093C 0062;0061 1CD4 0334 093C 0062;0061 1CD4 0334 093C 0062; # (a◌᳔◌़◌̴b; a◌᳔◌̴◌़b; a◌᳔◌̴◌़b; a◌᳔◌̴◌़b; a◌᳔◌̴◌़b; ) LATIN SMALL LETTER A, VEDIC SIGN YAJURVEDIC MIDLINE SVARITA, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 059A 0316 302A 1CD5 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062;0061 302A 0316 1CD5 059A 0062; # (a◌֚◌̖◌〪◌᳕b; a◌〪◌̖◌᳕◌֚b; a◌〪◌̖◌᳕◌֚b; a◌〪◌̖◌᳕◌֚b; a◌〪◌̖◌᳕◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA, LATIN SMALL LETTER B
+0061 1CD5 059A 0316 302A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062;0061 302A 1CD5 0316 059A 0062; # (a◌᳕◌֚◌̖◌〪b; a◌〪◌᳕◌̖◌֚b; a◌〪◌᳕◌̖◌֚b; a◌〪◌᳕◌̖◌֚b; a◌〪◌᳕◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1CD6 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062;0061 302A 0316 1CD6 059A 0062; # (a◌֚◌̖◌〪◌᳖b; a◌〪◌̖◌᳖◌֚b; a◌〪◌̖◌᳖◌֚b; a◌〪◌̖◌᳖◌֚b; a◌〪◌̖◌᳖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA, LATIN SMALL LETTER B
+0061 1CD6 059A 0316 302A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062;0061 302A 1CD6 0316 059A 0062; # (a◌᳖◌֚◌̖◌〪b; a◌〪◌᳖◌̖◌֚b; a◌〪◌᳖◌̖◌֚b; a◌〪◌᳖◌̖◌֚b; a◌〪◌᳖◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1CD7 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062;0061 302A 0316 1CD7 059A 0062; # (a◌֚◌̖◌〪◌᳗b; a◌〪◌̖◌᳗◌֚b; a◌〪◌̖◌᳗◌֚b; a◌〪◌̖◌᳗◌֚b; a◌〪◌̖◌᳗◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA, LATIN SMALL LETTER B
+0061 1CD7 059A 0316 302A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062;0061 302A 1CD7 0316 059A 0062; # (a◌᳗◌֚◌̖◌〪b; a◌〪◌᳗◌̖◌֚b; a◌〪◌᳗◌̖◌֚b; a◌〪◌᳗◌̖◌֚b; a◌〪◌᳗◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1CD8 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062;0061 302A 0316 1CD8 059A 0062; # (a◌֚◌̖◌〪◌᳘b; a◌〪◌̖◌᳘◌֚b; a◌〪◌̖◌᳘◌֚b; a◌〪◌̖◌᳘◌֚b; a◌〪◌̖◌᳘◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE CANDRA BELOW, LATIN SMALL LETTER B
+0061 1CD8 059A 0316 302A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062;0061 302A 1CD8 0316 059A 0062; # (a◌᳘◌֚◌̖◌〪b; a◌〪◌᳘◌̖◌֚b; a◌〪◌᳘◌̖◌֚b; a◌〪◌᳘◌̖◌֚b; a◌〪◌᳘◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE CANDRA BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1CD9 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062;0061 302A 0316 1CD9 059A 0062; # (a◌֚◌̖◌〪◌᳙b; a◌〪◌̖◌᳙◌֚b; a◌〪◌̖◌᳙◌֚b; a◌〪◌̖◌᳙◌֚b; a◌〪◌̖◌᳙◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER, LATIN SMALL LETTER B
+0061 1CD9 059A 0316 302A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062;0061 302A 1CD9 0316 059A 0062; # (a◌᳙◌֚◌̖◌〪b; a◌〪◌᳙◌̖◌֚b; a◌〪◌᳙◌̖◌֚b; a◌〪◌᳙◌̖◌֚b; a◌〪◌᳙◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1CDA 0062;00E0 05AE 1CDA 0315 0062;0061 05AE 0300 1CDA 0315 0062;00E0 05AE 1CDA 0315 0062;0061 05AE 0300 1CDA 0315 0062; # (a◌̕◌̀◌֮◌᳚b; à◌֮◌᳚◌̕b; a◌֮◌̀◌᳚◌̕b; à◌֮◌᳚◌̕b; a◌֮◌̀◌᳚◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE DOUBLE SVARITA, LATIN SMALL LETTER B
+0061 1CDA 0315 0300 05AE 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062;0061 05AE 1CDA 0300 0315 0062; # (a◌᳚◌̕◌̀◌֮b; a◌֮◌᳚◌̀◌̕b; a◌֮◌᳚◌̀◌̕b; a◌֮◌᳚◌̀◌̕b; a◌֮◌᳚◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE DOUBLE SVARITA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1CDB 0062;00E0 05AE 1CDB 0315 0062;0061 05AE 0300 1CDB 0315 0062;00E0 05AE 1CDB 0315 0062;0061 05AE 0300 1CDB 0315 0062; # (a◌̕◌̀◌֮◌᳛b; à◌֮◌᳛◌̕b; a◌֮◌̀◌᳛◌̕b; à◌֮◌᳛◌̕b; a◌֮◌̀◌᳛◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE TRIPLE SVARITA, LATIN SMALL LETTER B
+0061 1CDB 0315 0300 05AE 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062;0061 05AE 1CDB 0300 0315 0062; # (a◌᳛◌̕◌̀◌֮b; a◌֮◌᳛◌̀◌̕b; a◌֮◌᳛◌̀◌̕b; a◌֮◌᳛◌̀◌̕b; a◌֮◌᳛◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE TRIPLE SVARITA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 1CDC 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062;0061 302A 0316 1CDC 059A 0062; # (a◌֚◌̖◌〪◌᳜b; a◌〪◌̖◌᳜◌֚b; a◌〪◌̖◌᳜◌֚b; a◌〪◌̖◌᳜◌֚b; a◌〪◌̖◌᳜◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE KATHAKA ANUDATTA, LATIN SMALL LETTER B
+0061 1CDC 059A 0316 302A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062;0061 302A 1CDC 0316 059A 0062; # (a◌᳜◌֚◌̖◌〪b; a◌〪◌᳜◌̖◌֚b; a◌〪◌᳜◌̖◌֚b; a◌〪◌᳜◌̖◌֚b; a◌〪◌᳜◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE KATHAKA ANUDATTA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1CDD 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062;0061 302A 0316 1CDD 059A 0062; # (a◌֚◌̖◌〪◌᳝b; a◌〪◌̖◌᳝◌֚b; a◌〪◌̖◌᳝◌֚b; a◌〪◌̖◌᳝◌֚b; a◌〪◌̖◌᳝◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE DOT BELOW, LATIN SMALL LETTER B
+0061 1CDD 059A 0316 302A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062;0061 302A 1CDD 0316 059A 0062; # (a◌᳝◌֚◌̖◌〪b; a◌〪◌᳝◌̖◌֚b; a◌〪◌᳝◌̖◌֚b; a◌〪◌᳝◌̖◌֚b; a◌〪◌᳝◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1CDE 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062;0061 302A 0316 1CDE 059A 0062; # (a◌֚◌̖◌〪◌᳞b; a◌〪◌̖◌᳞◌֚b; a◌〪◌̖◌᳞◌֚b; a◌〪◌̖◌᳞◌֚b; a◌〪◌̖◌᳞◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE TWO DOTS BELOW, LATIN SMALL LETTER B
+0061 1CDE 059A 0316 302A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062;0061 302A 1CDE 0316 059A 0062; # (a◌᳞◌֚◌̖◌〪b; a◌〪◌᳞◌̖◌֚b; a◌〪◌᳞◌̖◌֚b; a◌〪◌᳞◌̖◌֚b; a◌〪◌᳞◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE TWO DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1CDF 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062;0061 302A 0316 1CDF 059A 0062; # (a◌֚◌̖◌〪◌᳟b; a◌〪◌̖◌᳟◌֚b; a◌〪◌̖◌᳟◌֚b; a◌〪◌̖◌᳟◌֚b; a◌〪◌̖◌᳟◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC TONE THREE DOTS BELOW, LATIN SMALL LETTER B
+0061 1CDF 059A 0316 302A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062;0061 302A 1CDF 0316 059A 0062; # (a◌᳟◌֚◌̖◌〪b; a◌〪◌᳟◌̖◌֚b; a◌〪◌᳟◌̖◌֚b; a◌〪◌᳟◌̖◌֚b; a◌〪◌᳟◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC TONE THREE DOTS BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1CE0 0062;00E0 05AE 1CE0 0315 0062;0061 05AE 0300 1CE0 0315 0062;00E0 05AE 1CE0 0315 0062;0061 05AE 0300 1CE0 0315 0062; # (a◌̕◌̀◌֮◌᳠b; à◌֮◌᳠◌̕b; a◌֮◌̀◌᳠◌̕b; à◌֮◌᳠◌̕b; a◌֮◌̀◌᳠◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA, LATIN SMALL LETTER B
+0061 1CE0 0315 0300 05AE 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062;0061 05AE 1CE0 0300 0315 0062; # (a◌᳠◌̕◌̀◌֮b; a◌֮◌᳠◌̀◌̕b; a◌֮◌᳠◌̀◌̕b; a◌֮◌᳠◌̀◌̕b; a◌֮◌᳠◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 093C 0334 1CE2 0062;0061 0334 1CE2 093C 0062;0061 0334 1CE2 093C 0062;0061 0334 1CE2 093C 0062;0061 0334 1CE2 093C 0062; # (a◌़◌̴◌᳢b; a◌̴◌᳢◌़b; a◌̴◌᳢◌़b; a◌̴◌᳢◌़b; a◌̴◌᳢◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, VEDIC SIGN VISARGA SVARITA, LATIN SMALL LETTER B
+0061 1CE2 093C 0334 0062;0061 1CE2 0334 093C 0062;0061 1CE2 0334 093C 0062;0061 1CE2 0334 093C 0062;0061 1CE2 0334 093C 0062; # (a◌᳢◌़◌̴b; a◌᳢◌̴◌़b; a◌᳢◌̴◌़b; a◌᳢◌̴◌़b; a◌᳢◌̴◌़b; ) LATIN SMALL LETTER A, VEDIC SIGN VISARGA SVARITA, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 1CE3 0062;0061 0334 1CE3 093C 0062;0061 0334 1CE3 093C 0062;0061 0334 1CE3 093C 0062;0061 0334 1CE3 093C 0062; # (a◌़◌̴◌᳣b; a◌̴◌᳣◌़b; a◌̴◌᳣◌़b; a◌̴◌᳣◌़b; a◌̴◌᳣◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, VEDIC SIGN VISARGA UDATTA, LATIN SMALL LETTER B
+0061 1CE3 093C 0334 0062;0061 1CE3 0334 093C 0062;0061 1CE3 0334 093C 0062;0061 1CE3 0334 093C 0062;0061 1CE3 0334 093C 0062; # (a◌᳣◌़◌̴b; a◌᳣◌̴◌़b; a◌᳣◌̴◌़b; a◌᳣◌̴◌़b; a◌᳣◌̴◌़b; ) LATIN SMALL LETTER A, VEDIC SIGN VISARGA UDATTA, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 1CE4 0062;0061 0334 1CE4 093C 0062;0061 0334 1CE4 093C 0062;0061 0334 1CE4 093C 0062;0061 0334 1CE4 093C 0062; # (a◌़◌̴◌᳤b; a◌̴◌᳤◌़b; a◌̴◌᳤◌़b; a◌̴◌᳤◌़b; a◌̴◌᳤◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, VEDIC SIGN REVERSED VISARGA UDATTA, LATIN SMALL LETTER B
+0061 1CE4 093C 0334 0062;0061 1CE4 0334 093C 0062;0061 1CE4 0334 093C 0062;0061 1CE4 0334 093C 0062;0061 1CE4 0334 093C 0062; # (a◌᳤◌़◌̴b; a◌᳤◌̴◌़b; a◌᳤◌̴◌़b; a◌᳤◌̴◌़b; a◌᳤◌̴◌़b; ) LATIN SMALL LETTER A, VEDIC SIGN REVERSED VISARGA UDATTA, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 1CE5 0062;0061 0334 1CE5 093C 0062;0061 0334 1CE5 093C 0062;0061 0334 1CE5 093C 0062;0061 0334 1CE5 093C 0062; # (a◌़◌̴◌᳥b; a◌̴◌᳥◌़b; a◌̴◌᳥◌़b; a◌̴◌᳥◌़b; a◌̴◌᳥◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, VEDIC SIGN VISARGA ANUDATTA, LATIN SMALL LETTER B
+0061 1CE5 093C 0334 0062;0061 1CE5 0334 093C 0062;0061 1CE5 0334 093C 0062;0061 1CE5 0334 093C 0062;0061 1CE5 0334 093C 0062; # (a◌᳥◌़◌̴b; a◌᳥◌̴◌़b; a◌᳥◌̴◌़b; a◌᳥◌̴◌़b; a◌᳥◌̴◌़b; ) LATIN SMALL LETTER A, VEDIC SIGN VISARGA ANUDATTA, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 1CE6 0062;0061 0334 1CE6 093C 0062;0061 0334 1CE6 093C 0062;0061 0334 1CE6 093C 0062;0061 0334 1CE6 093C 0062; # (a◌़◌̴◌᳦b; a◌̴◌᳦◌़b; a◌̴◌᳦◌़b; a◌̴◌᳦◌़b; a◌̴◌᳦◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, VEDIC SIGN REVERSED VISARGA ANUDATTA, LATIN SMALL LETTER B
+0061 1CE6 093C 0334 0062;0061 1CE6 0334 093C 0062;0061 1CE6 0334 093C 0062;0061 1CE6 0334 093C 0062;0061 1CE6 0334 093C 0062; # (a◌᳦◌़◌̴b; a◌᳦◌̴◌़b; a◌᳦◌̴◌़b; a◌᳦◌̴◌़b; a◌᳦◌̴◌़b; ) LATIN SMALL LETTER A, VEDIC SIGN REVERSED VISARGA ANUDATTA, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 1CE7 0062;0061 0334 1CE7 093C 0062;0061 0334 1CE7 093C 0062;0061 0334 1CE7 093C 0062;0061 0334 1CE7 093C 0062; # (a◌़◌̴◌᳧b; a◌̴◌᳧◌़b; a◌̴◌᳧◌़b; a◌̴◌᳧◌़b; a◌̴◌᳧◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, VEDIC SIGN VISARGA UDATTA WITH TAIL, LATIN SMALL LETTER B
+0061 1CE7 093C 0334 0062;0061 1CE7 0334 093C 0062;0061 1CE7 0334 093C 0062;0061 1CE7 0334 093C 0062;0061 1CE7 0334 093C 0062; # (a◌᳧◌़◌̴b; a◌᳧◌̴◌़b; a◌᳧◌̴◌़b; a◌᳧◌̴◌़b; a◌᳧◌̴◌़b; ) LATIN SMALL LETTER A, VEDIC SIGN VISARGA UDATTA WITH TAIL, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 1CE8 0062;0061 0334 1CE8 093C 0062;0061 0334 1CE8 093C 0062;0061 0334 1CE8 093C 0062;0061 0334 1CE8 093C 0062; # (a◌़◌̴◌᳨b; a◌̴◌᳨◌़b; a◌̴◌᳨◌़b; a◌̴◌᳨◌़b; a◌̴◌᳨◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, VEDIC SIGN VISARGA ANUDATTA WITH TAIL, LATIN SMALL LETTER B
+0061 1CE8 093C 0334 0062;0061 1CE8 0334 093C 0062;0061 1CE8 0334 093C 0062;0061 1CE8 0334 093C 0062;0061 1CE8 0334 093C 0062; # (a◌᳨◌़◌̴b; a◌᳨◌̴◌़b; a◌᳨◌̴◌़b; a◌᳨◌̴◌़b; a◌᳨◌̴◌़b; ) LATIN SMALL LETTER A, VEDIC SIGN VISARGA ANUDATTA WITH TAIL, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 059A 0316 302A 1CED 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062;0061 302A 0316 1CED 059A 0062; # (a◌֚◌̖◌〪◌᳭b; a◌〪◌̖◌᳭◌֚b; a◌〪◌̖◌᳭◌֚b; a◌〪◌̖◌᳭◌֚b; a◌〪◌̖◌᳭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, VEDIC SIGN TIRYAK, LATIN SMALL LETTER B
+0061 1CED 059A 0316 302A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062;0061 302A 1CED 0316 059A 0062; # (a◌᳭◌֚◌̖◌〪b; a◌〪◌᳭◌̖◌֚b; a◌〪◌᳭◌̖◌֚b; a◌〪◌᳭◌̖◌֚b; a◌〪◌᳭◌̖◌֚b; ) LATIN SMALL LETTER A, VEDIC SIGN TIRYAK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1CF4 0062;00E0 05AE 1CF4 0315 0062;0061 05AE 0300 1CF4 0315 0062;00E0 05AE 1CF4 0315 0062;0061 05AE 0300 1CF4 0315 0062; # (a◌̕◌̀◌֮◌᳴b; à◌֮◌᳴◌̕b; a◌֮◌̀◌᳴◌̕b; à◌֮◌᳴◌̕b; a◌֮◌̀◌᳴◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE CANDRA ABOVE, LATIN SMALL LETTER B
+0061 1CF4 0315 0300 05AE 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062;0061 05AE 1CF4 0300 0315 0062; # (a◌᳴◌̕◌̀◌֮b; a◌֮◌᳴◌̀◌̕b; a◌֮◌᳴◌̀◌̕b; a◌֮◌᳴◌̀◌̕b; a◌֮◌᳴◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE CANDRA ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1CF8 0062;00E0 05AE 1CF8 0315 0062;0061 05AE 0300 1CF8 0315 0062;00E0 05AE 1CF8 0315 0062;0061 05AE 0300 1CF8 0315 0062; # (a◌̕◌̀◌֮◌᳸b; à◌֮◌᳸◌̕b; a◌֮◌̀◌᳸◌̕b; à◌֮◌᳸◌̕b; a◌֮◌̀◌᳸◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE RING ABOVE, LATIN SMALL LETTER B
+0061 1CF8 0315 0300 05AE 0062;0061 05AE 1CF8 0300 0315 0062;0061 05AE 1CF8 0300 0315 0062;0061 05AE 1CF8 0300 0315 0062;0061 05AE 1CF8 0300 0315 0062; # (a◌᳸◌̕◌̀◌֮b; a◌֮◌᳸◌̀◌̕b; a◌֮◌᳸◌̀◌̕b; a◌֮◌᳸◌̀◌̕b; a◌֮◌᳸◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE RING ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1CF9 0062;00E0 05AE 1CF9 0315 0062;0061 05AE 0300 1CF9 0315 0062;00E0 05AE 1CF9 0315 0062;0061 05AE 0300 1CF9 0315 0062; # (a◌̕◌̀◌֮◌᳹b; à◌֮◌᳹◌̕b; a◌֮◌̀◌᳹◌̕b; à◌֮◌᳹◌̕b; a◌֮◌̀◌᳹◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, VEDIC TONE DOUBLE RING ABOVE, LATIN SMALL LETTER B
+0061 1CF9 0315 0300 05AE 0062;0061 05AE 1CF9 0300 0315 0062;0061 05AE 1CF9 0300 0315 0062;0061 05AE 1CF9 0300 0315 0062;0061 05AE 1CF9 0300 0315 0062; # (a◌᳹◌̕◌̀◌֮b; a◌֮◌᳹◌̀◌̕b; a◌֮◌᳹◌̀◌̕b; a◌֮◌᳹◌̀◌̕b; a◌֮◌᳹◌̀◌̕b; ) LATIN SMALL LETTER A, VEDIC TONE DOUBLE RING ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DC0 0062;00E0 05AE 1DC0 0315 0062;0061 05AE 0300 1DC0 0315 0062;00E0 05AE 1DC0 0315 0062;0061 05AE 0300 1DC0 0315 0062; # (a◌̕◌̀◌֮◌᷀b; à◌֮◌᷀◌̕b; a◌֮◌̀◌᷀◌̕b; à◌֮◌᷀◌̕b; a◌֮◌̀◌᷀◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOTTED GRAVE ACCENT, LATIN SMALL LETTER B
+0061 1DC0 0315 0300 05AE 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062;0061 05AE 1DC0 0300 0315 0062; # (a◌᷀◌̕◌̀◌֮b; a◌֮◌᷀◌̀◌̕b; a◌֮◌᷀◌̀◌̕b; a◌֮◌᷀◌̀◌̕b; a◌֮◌᷀◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOTTED GRAVE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DC1 0062;00E0 05AE 1DC1 0315 0062;0061 05AE 0300 1DC1 0315 0062;00E0 05AE 1DC1 0315 0062;0061 05AE 0300 1DC1 0315 0062; # (a◌̕◌̀◌֮◌᷁b; à◌֮◌᷁◌̕b; a◌֮◌̀◌᷁◌̕b; à◌֮◌᷁◌̕b; a◌֮◌̀◌᷁◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOTTED ACUTE ACCENT, LATIN SMALL LETTER B
+0061 1DC1 0315 0300 05AE 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062;0061 05AE 1DC1 0300 0315 0062; # (a◌᷁◌̕◌̀◌֮b; a◌֮◌᷁◌̀◌̕b; a◌֮◌᷁◌̀◌̕b; a◌֮◌᷁◌̀◌̕b; a◌֮◌᷁◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOTTED ACUTE ACCENT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 1DC2 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062;0061 302A 0316 1DC2 059A 0062; # (a◌֚◌̖◌〪◌᷂b; a◌〪◌̖◌᷂◌֚b; a◌〪◌̖◌᷂◌֚b; a◌〪◌̖◌᷂◌֚b; a◌〪◌̖◌᷂◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING SNAKE BELOW, LATIN SMALL LETTER B
+0061 1DC2 059A 0316 302A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062;0061 302A 1DC2 0316 059A 0062; # (a◌᷂◌֚◌̖◌〪b; a◌〪◌᷂◌̖◌֚b; a◌〪◌᷂◌̖◌֚b; a◌〪◌᷂◌̖◌֚b; a◌〪◌᷂◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING SNAKE BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DC3 0062;00E0 05AE 1DC3 0315 0062;0061 05AE 0300 1DC3 0315 0062;00E0 05AE 1DC3 0315 0062;0061 05AE 0300 1DC3 0315 0062; # (a◌̕◌̀◌֮◌᷃b; à◌֮◌᷃◌̕b; a◌֮◌̀◌᷃◌̕b; à◌֮◌᷃◌̕b; a◌֮◌̀◌᷃◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING SUSPENSION MARK, LATIN SMALL LETTER B
+0061 1DC3 0315 0300 05AE 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062;0061 05AE 1DC3 0300 0315 0062; # (a◌᷃◌̕◌̀◌֮b; a◌֮◌᷃◌̀◌̕b; a◌֮◌᷃◌̀◌̕b; a◌֮◌᷃◌̀◌̕b; a◌֮◌᷃◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING SUSPENSION MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DC4 0062;00E0 05AE 1DC4 0315 0062;0061 05AE 0300 1DC4 0315 0062;00E0 05AE 1DC4 0315 0062;0061 05AE 0300 1DC4 0315 0062; # (a◌̕◌̀◌֮◌᷄b; à◌֮◌᷄◌̕b; a◌֮◌̀◌᷄◌̕b; à◌֮◌᷄◌̕b; a◌֮◌̀◌᷄◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING MACRON-ACUTE, LATIN SMALL LETTER B
+0061 1DC4 0315 0300 05AE 0062;0061 05AE 1DC4 0300 0315 0062;0061 05AE 1DC4 0300 0315 0062;0061 05AE 1DC4 0300 0315 0062;0061 05AE 1DC4 0300 0315 0062; # (a◌᷄◌̕◌̀◌֮b; a◌֮◌᷄◌̀◌̕b; a◌֮◌᷄◌̀◌̕b; a◌֮◌᷄◌̀◌̕b; a◌֮◌᷄◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING MACRON-ACUTE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DC5 0062;00E0 05AE 1DC5 0315 0062;0061 05AE 0300 1DC5 0315 0062;00E0 05AE 1DC5 0315 0062;0061 05AE 0300 1DC5 0315 0062; # (a◌̕◌̀◌֮◌᷅b; à◌֮◌᷅◌̕b; a◌֮◌̀◌᷅◌̕b; à◌֮◌᷅◌̕b; a◌֮◌̀◌᷅◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRAVE-MACRON, LATIN SMALL LETTER B
+0061 1DC5 0315 0300 05AE 0062;0061 05AE 1DC5 0300 0315 0062;0061 05AE 1DC5 0300 0315 0062;0061 05AE 1DC5 0300 0315 0062;0061 05AE 1DC5 0300 0315 0062; # (a◌᷅◌̕◌̀◌֮b; a◌֮◌᷅◌̀◌̕b; a◌֮◌᷅◌̀◌̕b; a◌֮◌᷅◌̀◌̕b; a◌֮◌᷅◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRAVE-MACRON, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DC6 0062;00E0 05AE 1DC6 0315 0062;0061 05AE 0300 1DC6 0315 0062;00E0 05AE 1DC6 0315 0062;0061 05AE 0300 1DC6 0315 0062; # (a◌̕◌̀◌֮◌᷆b; à◌֮◌᷆◌̕b; a◌֮◌̀◌᷆◌̕b; à◌֮◌᷆◌̕b; a◌֮◌̀◌᷆◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING MACRON-GRAVE, LATIN SMALL LETTER B
+0061 1DC6 0315 0300 05AE 0062;0061 05AE 1DC6 0300 0315 0062;0061 05AE 1DC6 0300 0315 0062;0061 05AE 1DC6 0300 0315 0062;0061 05AE 1DC6 0300 0315 0062; # (a◌᷆◌̕◌̀◌֮b; a◌֮◌᷆◌̀◌̕b; a◌֮◌᷆◌̀◌̕b; a◌֮◌᷆◌̀◌̕b; a◌֮◌᷆◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING MACRON-GRAVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DC7 0062;00E0 05AE 1DC7 0315 0062;0061 05AE 0300 1DC7 0315 0062;00E0 05AE 1DC7 0315 0062;0061 05AE 0300 1DC7 0315 0062; # (a◌̕◌̀◌֮◌᷇b; à◌֮◌᷇◌̕b; a◌֮◌̀◌᷇◌̕b; à◌֮◌᷇◌̕b; a◌֮◌̀◌᷇◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING ACUTE-MACRON, LATIN SMALL LETTER B
+0061 1DC7 0315 0300 05AE 0062;0061 05AE 1DC7 0300 0315 0062;0061 05AE 1DC7 0300 0315 0062;0061 05AE 1DC7 0300 0315 0062;0061 05AE 1DC7 0300 0315 0062; # (a◌᷇◌̕◌̀◌֮b; a◌֮◌᷇◌̀◌̕b; a◌֮◌᷇◌̀◌̕b; a◌֮◌᷇◌̀◌̕b; a◌֮◌᷇◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ACUTE-MACRON, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DC8 0062;00E0 05AE 1DC8 0315 0062;0061 05AE 0300 1DC8 0315 0062;00E0 05AE 1DC8 0315 0062;0061 05AE 0300 1DC8 0315 0062; # (a◌̕◌̀◌֮◌᷈b; à◌֮◌᷈◌̕b; a◌֮◌̀◌᷈◌̕b; à◌֮◌᷈◌̕b; a◌֮◌̀◌᷈◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRAVE-ACUTE-GRAVE, LATIN SMALL LETTER B
+0061 1DC8 0315 0300 05AE 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062;0061 05AE 1DC8 0300 0315 0062; # (a◌᷈◌̕◌̀◌֮b; a◌֮◌᷈◌̀◌̕b; a◌֮◌᷈◌̀◌̕b; a◌֮◌᷈◌̀◌̕b; a◌֮◌᷈◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRAVE-ACUTE-GRAVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DC9 0062;00E0 05AE 1DC9 0315 0062;0061 05AE 0300 1DC9 0315 0062;00E0 05AE 1DC9 0315 0062;0061 05AE 0300 1DC9 0315 0062; # (a◌̕◌̀◌֮◌᷉b; à◌֮◌᷉◌̕b; a◌֮◌̀◌᷉◌̕b; à◌֮◌᷉◌̕b; a◌֮◌̀◌᷉◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING ACUTE-GRAVE-ACUTE, LATIN SMALL LETTER B
+0061 1DC9 0315 0300 05AE 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062;0061 05AE 1DC9 0300 0315 0062; # (a◌᷉◌̕◌̀◌֮b; a◌֮◌᷉◌̀◌̕b; a◌֮◌᷉◌̀◌̕b; a◌֮◌᷉◌̀◌̕b; a◌֮◌᷉◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ACUTE-GRAVE-ACUTE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 1DCA 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062;0061 302A 0316 1DCA 059A 0062; # (a◌֚◌̖◌〪◌᷊b; a◌〪◌̖◌᷊◌֚b; a◌〪◌̖◌᷊◌֚b; a◌〪◌̖◌᷊◌֚b; a◌〪◌̖◌᷊◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LATIN SMALL LETTER R BELOW, LATIN SMALL LETTER B
+0061 1DCA 059A 0316 302A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062;0061 302A 1DCA 0316 059A 0062; # (a◌᷊◌֚◌̖◌〪b; a◌〪◌᷊◌̖◌֚b; a◌〪◌᷊◌̖◌֚b; a◌〪◌᷊◌̖◌֚b; a◌〪◌᷊◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER R BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DCB 0062;00E0 05AE 1DCB 0315 0062;0061 05AE 0300 1DCB 0315 0062;00E0 05AE 1DCB 0315 0062;0061 05AE 0300 1DCB 0315 0062; # (a◌̕◌̀◌֮◌᷋b; à◌֮◌᷋◌̕b; a◌֮◌̀◌᷋◌̕b; à◌֮◌᷋◌̕b; a◌֮◌̀◌᷋◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING BREVE-MACRON, LATIN SMALL LETTER B
+0061 1DCB 0315 0300 05AE 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062;0061 05AE 1DCB 0300 0315 0062; # (a◌᷋◌̕◌̀◌֮b; a◌֮◌᷋◌̀◌̕b; a◌֮◌᷋◌̀◌̕b; a◌֮◌᷋◌̀◌̕b; a◌֮◌᷋◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING BREVE-MACRON, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DCC 0062;00E0 05AE 1DCC 0315 0062;0061 05AE 0300 1DCC 0315 0062;00E0 05AE 1DCC 0315 0062;0061 05AE 0300 1DCC 0315 0062; # (a◌̕◌̀◌֮◌᷌b; à◌֮◌᷌◌̕b; a◌֮◌̀◌᷌◌̕b; à◌֮◌᷌◌̕b; a◌֮◌̀◌᷌◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING MACRON-BREVE, LATIN SMALL LETTER B
+0061 1DCC 0315 0300 05AE 0062;0061 05AE 1DCC 0300 0315 0062;0061 05AE 1DCC 0300 0315 0062;0061 05AE 1DCC 0300 0315 0062;0061 05AE 1DCC 0300 0315 0062; # (a◌᷌◌̕◌̀◌֮b; a◌֮◌᷌◌̀◌̕b; a◌֮◌᷌◌̀◌̕b; a◌֮◌᷌◌̀◌̕b; a◌֮◌᷌◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING MACRON-BREVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0345 035D 035C 1DCD 0062;0061 035C 035D 1DCD 0345 0062;0061 035C 035D 1DCD 0345 0062;0061 035C 035D 1DCD 0345 0062;0061 035C 035D 1DCD 0345 0062; # (a◌ͅ◌͝◌͜◌᷍b; a◌͜◌͝◌᷍◌ͅb; a◌͜◌͝◌᷍◌ͅb; a◌͜◌͝◌᷍◌ͅb; a◌͜◌͝◌᷍◌ͅb; ) LATIN SMALL LETTER A, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING DOUBLE CIRCUMFLEX ABOVE, LATIN SMALL LETTER B
+0061 1DCD 0345 035D 035C 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062;0061 035C 1DCD 035D 0345 0062; # (a◌᷍◌ͅ◌͝◌͜b; a◌͜◌᷍◌͝◌ͅb; a◌͜◌᷍◌͝◌ͅb; a◌͜◌᷍◌͝◌ͅb; a◌͜◌᷍◌͝◌ͅb; ) LATIN SMALL LETTER A, COMBINING DOUBLE CIRCUMFLEX ABOVE, COMBINING GREEK YPOGEGRAMMENI, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, LATIN SMALL LETTER B
+0061 031B 1DCE 0321 1DCE 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062; # (a◌̛◌᷎◌̡◌᷎b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; ) LATIN SMALL LETTER A, COMBINING HORN, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 1DCE 031B 1DCE 0321 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062;0061 0321 1DCE 1DCE 031B 0062; # (a◌᷎◌̛◌᷎◌̡b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; a◌̡◌᷎◌᷎◌̛b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING HORN, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, LATIN SMALL LETTER B
+0061 059A 0316 302A 1DCF 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062;0061 302A 0316 1DCF 059A 0062; # (a◌֚◌̖◌〪◌᷏b; a◌〪◌̖◌᷏◌֚b; a◌〪◌̖◌᷏◌֚b; a◌〪◌̖◌᷏◌֚b; a◌〪◌̖◌᷏◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING ZIGZAG BELOW, LATIN SMALL LETTER B
+0061 1DCF 059A 0316 302A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062;0061 302A 1DCF 0316 059A 0062; # (a◌᷏◌֚◌̖◌〪b; a◌〪◌᷏◌̖◌֚b; a◌〪◌᷏◌̖◌֚b; a◌〪◌᷏◌̖◌֚b; a◌〪◌᷏◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ZIGZAG BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 1DCE 0321 0F74 1DD0 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062;0061 0F74 0321 1DD0 1DCE 0062; # (a◌᷎◌̡◌ུ◌᷐b; a◌ུ◌̡◌᷐◌᷎b; a◌ུ◌̡◌᷐◌᷎b; a◌ུ◌̡◌᷐◌᷎b; a◌ུ◌̡◌᷐◌᷎b; ) LATIN SMALL LETTER A, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, COMBINING IS BELOW, LATIN SMALL LETTER B
+0061 1DD0 1DCE 0321 0F74 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062;0061 0F74 1DD0 0321 1DCE 0062; # (a◌᷐◌᷎◌̡◌ུb; a◌ུ◌᷐◌̡◌᷎b; a◌ུ◌᷐◌̡◌᷎b; a◌ུ◌᷐◌̡◌᷎b; a◌ུ◌᷐◌̡◌᷎b; ) LATIN SMALL LETTER A, COMBINING IS BELOW, COMBINING OGONEK ABOVE, COMBINING PALATALIZED HOOK BELOW, TIBETAN VOWEL SIGN U, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DD1 0062;00E0 05AE 1DD1 0315 0062;0061 05AE 0300 1DD1 0315 0062;00E0 05AE 1DD1 0315 0062;0061 05AE 0300 1DD1 0315 0062; # (a◌̕◌̀◌֮◌᷑b; à◌֮◌᷑◌̕b; a◌֮◌̀◌᷑◌̕b; à◌֮◌᷑◌̕b; a◌֮◌̀◌᷑◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING UR ABOVE, LATIN SMALL LETTER B
+0061 1DD1 0315 0300 05AE 0062;0061 05AE 1DD1 0300 0315 0062;0061 05AE 1DD1 0300 0315 0062;0061 05AE 1DD1 0300 0315 0062;0061 05AE 1DD1 0300 0315 0062; # (a◌᷑◌̕◌̀◌֮b; a◌֮◌᷑◌̀◌̕b; a◌֮◌᷑◌̀◌̕b; a◌֮◌᷑◌̀◌̕b; a◌֮◌᷑◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING UR ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DD2 0062;00E0 05AE 1DD2 0315 0062;0061 05AE 0300 1DD2 0315 0062;00E0 05AE 1DD2 0315 0062;0061 05AE 0300 1DD2 0315 0062; # (a◌̕◌̀◌֮◌᷒b; à◌֮◌᷒◌̕b; a◌֮◌̀◌᷒◌̕b; à◌֮◌᷒◌̕b; a◌֮◌̀◌᷒◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING US ABOVE, LATIN SMALL LETTER B
+0061 1DD2 0315 0300 05AE 0062;0061 05AE 1DD2 0300 0315 0062;0061 05AE 1DD2 0300 0315 0062;0061 05AE 1DD2 0300 0315 0062;0061 05AE 1DD2 0300 0315 0062; # (a◌᷒◌̕◌̀◌֮b; a◌֮◌᷒◌̀◌̕b; a◌֮◌᷒◌̀◌̕b; a◌֮◌᷒◌̀◌̕b; a◌֮◌᷒◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING US ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DD3 0062;00E0 05AE 1DD3 0315 0062;0061 05AE 0300 1DD3 0315 0062;00E0 05AE 1DD3 0315 0062;0061 05AE 0300 1DD3 0315 0062; # (a◌̕◌̀◌֮◌ᷓb; à◌֮◌ᷓ◌̕b; a◌֮◌̀◌ᷓ◌̕b; à◌֮◌ᷓ◌̕b; a◌֮◌̀◌ᷓ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE, LATIN SMALL LETTER B
+0061 1DD3 0315 0300 05AE 0062;0061 05AE 1DD3 0300 0315 0062;0061 05AE 1DD3 0300 0315 0062;0061 05AE 1DD3 0300 0315 0062;0061 05AE 1DD3 0300 0315 0062; # (a◌ᷓ◌̕◌̀◌֮b; a◌֮◌ᷓ◌̀◌̕b; a◌֮◌ᷓ◌̀◌̕b; a◌֮◌ᷓ◌̀◌̕b; a◌֮◌ᷓ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DD4 0062;00E0 05AE 1DD4 0315 0062;0061 05AE 0300 1DD4 0315 0062;00E0 05AE 1DD4 0315 0062;0061 05AE 0300 1DD4 0315 0062; # (a◌̕◌̀◌֮◌ᷔb; à◌֮◌ᷔ◌̕b; a◌֮◌̀◌ᷔ◌̕b; à◌֮◌ᷔ◌̕b; a◌֮◌̀◌ᷔ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER AE, LATIN SMALL LETTER B
+0061 1DD4 0315 0300 05AE 0062;0061 05AE 1DD4 0300 0315 0062;0061 05AE 1DD4 0300 0315 0062;0061 05AE 1DD4 0300 0315 0062;0061 05AE 1DD4 0300 0315 0062; # (a◌ᷔ◌̕◌̀◌֮b; a◌֮◌ᷔ◌̀◌̕b; a◌֮◌ᷔ◌̀◌̕b; a◌֮◌ᷔ◌̀◌̕b; a◌֮◌ᷔ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER AE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DD5 0062;00E0 05AE 1DD5 0315 0062;0061 05AE 0300 1DD5 0315 0062;00E0 05AE 1DD5 0315 0062;0061 05AE 0300 1DD5 0315 0062; # (a◌̕◌̀◌֮◌ᷕb; à◌֮◌ᷕ◌̕b; a◌֮◌̀◌ᷕ◌̕b; à◌֮◌ᷕ◌̕b; a◌֮◌̀◌ᷕ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER AO, LATIN SMALL LETTER B
+0061 1DD5 0315 0300 05AE 0062;0061 05AE 1DD5 0300 0315 0062;0061 05AE 1DD5 0300 0315 0062;0061 05AE 1DD5 0300 0315 0062;0061 05AE 1DD5 0300 0315 0062; # (a◌ᷕ◌̕◌̀◌֮b; a◌֮◌ᷕ◌̀◌̕b; a◌֮◌ᷕ◌̀◌̕b; a◌֮◌ᷕ◌̀◌̕b; a◌֮◌ᷕ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER AO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DD6 0062;00E0 05AE 1DD6 0315 0062;0061 05AE 0300 1DD6 0315 0062;00E0 05AE 1DD6 0315 0062;0061 05AE 0300 1DD6 0315 0062; # (a◌̕◌̀◌֮◌ᷖb; à◌֮◌ᷖ◌̕b; a◌֮◌̀◌ᷖ◌̕b; à◌֮◌ᷖ◌̕b; a◌֮◌̀◌ᷖ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER AV, LATIN SMALL LETTER B
+0061 1DD6 0315 0300 05AE 0062;0061 05AE 1DD6 0300 0315 0062;0061 05AE 1DD6 0300 0315 0062;0061 05AE 1DD6 0300 0315 0062;0061 05AE 1DD6 0300 0315 0062; # (a◌ᷖ◌̕◌̀◌֮b; a◌֮◌ᷖ◌̀◌̕b; a◌֮◌ᷖ◌̀◌̕b; a◌֮◌ᷖ◌̀◌̕b; a◌֮◌ᷖ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER AV, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DD7 0062;00E0 05AE 1DD7 0315 0062;0061 05AE 0300 1DD7 0315 0062;00E0 05AE 1DD7 0315 0062;0061 05AE 0300 1DD7 0315 0062; # (a◌̕◌̀◌֮◌ᷗb; à◌֮◌ᷗ◌̕b; a◌֮◌̀◌ᷗ◌̕b; à◌֮◌ᷗ◌̕b; a◌֮◌̀◌ᷗ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER C CEDILLA, LATIN SMALL LETTER B
+0061 1DD7 0315 0300 05AE 0062;0061 05AE 1DD7 0300 0315 0062;0061 05AE 1DD7 0300 0315 0062;0061 05AE 1DD7 0300 0315 0062;0061 05AE 1DD7 0300 0315 0062; # (a◌ᷗ◌̕◌̀◌֮b; a◌֮◌ᷗ◌̀◌̕b; a◌֮◌ᷗ◌̀◌̕b; a◌֮◌ᷗ◌̀◌̕b; a◌֮◌ᷗ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER C CEDILLA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DD8 0062;00E0 05AE 1DD8 0315 0062;0061 05AE 0300 1DD8 0315 0062;00E0 05AE 1DD8 0315 0062;0061 05AE 0300 1DD8 0315 0062; # (a◌̕◌̀◌֮◌ᷘb; à◌֮◌ᷘ◌̕b; a◌֮◌̀◌ᷘ◌̕b; à◌֮◌ᷘ◌̕b; a◌֮◌̀◌ᷘ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER INSULAR D, LATIN SMALL LETTER B
+0061 1DD8 0315 0300 05AE 0062;0061 05AE 1DD8 0300 0315 0062;0061 05AE 1DD8 0300 0315 0062;0061 05AE 1DD8 0300 0315 0062;0061 05AE 1DD8 0300 0315 0062; # (a◌ᷘ◌̕◌̀◌֮b; a◌֮◌ᷘ◌̀◌̕b; a◌֮◌ᷘ◌̀◌̕b; a◌֮◌ᷘ◌̀◌̕b; a◌֮◌ᷘ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER INSULAR D, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DD9 0062;00E0 05AE 1DD9 0315 0062;0061 05AE 0300 1DD9 0315 0062;00E0 05AE 1DD9 0315 0062;0061 05AE 0300 1DD9 0315 0062; # (a◌̕◌̀◌֮◌ᷙb; à◌֮◌ᷙ◌̕b; a◌֮◌̀◌ᷙ◌̕b; à◌֮◌ᷙ◌̕b; a◌֮◌̀◌ᷙ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER ETH, LATIN SMALL LETTER B
+0061 1DD9 0315 0300 05AE 0062;0061 05AE 1DD9 0300 0315 0062;0061 05AE 1DD9 0300 0315 0062;0061 05AE 1DD9 0300 0315 0062;0061 05AE 1DD9 0300 0315 0062; # (a◌ᷙ◌̕◌̀◌֮b; a◌֮◌ᷙ◌̀◌̕b; a◌֮◌ᷙ◌̀◌̕b; a◌֮◌ᷙ◌̀◌̕b; a◌֮◌ᷙ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER ETH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DDA 0062;00E0 05AE 1DDA 0315 0062;0061 05AE 0300 1DDA 0315 0062;00E0 05AE 1DDA 0315 0062;0061 05AE 0300 1DDA 0315 0062; # (a◌̕◌̀◌֮◌ᷚb; à◌֮◌ᷚ◌̕b; a◌֮◌̀◌ᷚ◌̕b; à◌֮◌ᷚ◌̕b; a◌֮◌̀◌ᷚ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER G, LATIN SMALL LETTER B
+0061 1DDA 0315 0300 05AE 0062;0061 05AE 1DDA 0300 0315 0062;0061 05AE 1DDA 0300 0315 0062;0061 05AE 1DDA 0300 0315 0062;0061 05AE 1DDA 0300 0315 0062; # (a◌ᷚ◌̕◌̀◌֮b; a◌֮◌ᷚ◌̀◌̕b; a◌֮◌ᷚ◌̀◌̕b; a◌֮◌ᷚ◌̀◌̕b; a◌֮◌ᷚ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER G, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DDB 0062;00E0 05AE 1DDB 0315 0062;0061 05AE 0300 1DDB 0315 0062;00E0 05AE 1DDB 0315 0062;0061 05AE 0300 1DDB 0315 0062; # (a◌̕◌̀◌֮◌ᷛb; à◌֮◌ᷛ◌̕b; a◌֮◌̀◌ᷛ◌̕b; à◌֮◌ᷛ◌̕b; a◌֮◌̀◌ᷛ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN LETTER SMALL CAPITAL G, LATIN SMALL LETTER B
+0061 1DDB 0315 0300 05AE 0062;0061 05AE 1DDB 0300 0315 0062;0061 05AE 1DDB 0300 0315 0062;0061 05AE 1DDB 0300 0315 0062;0061 05AE 1DDB 0300 0315 0062; # (a◌ᷛ◌̕◌̀◌֮b; a◌֮◌ᷛ◌̀◌̕b; a◌֮◌ᷛ◌̀◌̕b; a◌֮◌ᷛ◌̀◌̕b; a◌֮◌ᷛ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN LETTER SMALL CAPITAL G, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DDC 0062;00E0 05AE 1DDC 0315 0062;0061 05AE 0300 1DDC 0315 0062;00E0 05AE 1DDC 0315 0062;0061 05AE 0300 1DDC 0315 0062; # (a◌̕◌̀◌֮◌ᷜb; à◌֮◌ᷜ◌̕b; a◌֮◌̀◌ᷜ◌̕b; à◌֮◌ᷜ◌̕b; a◌֮◌̀◌ᷜ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER K, LATIN SMALL LETTER B
+0061 1DDC 0315 0300 05AE 0062;0061 05AE 1DDC 0300 0315 0062;0061 05AE 1DDC 0300 0315 0062;0061 05AE 1DDC 0300 0315 0062;0061 05AE 1DDC 0300 0315 0062; # (a◌ᷜ◌̕◌̀◌֮b; a◌֮◌ᷜ◌̀◌̕b; a◌֮◌ᷜ◌̀◌̕b; a◌֮◌ᷜ◌̀◌̕b; a◌֮◌ᷜ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER K, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DDD 0062;00E0 05AE 1DDD 0315 0062;0061 05AE 0300 1DDD 0315 0062;00E0 05AE 1DDD 0315 0062;0061 05AE 0300 1DDD 0315 0062; # (a◌̕◌̀◌֮◌ᷝb; à◌֮◌ᷝ◌̕b; a◌֮◌̀◌ᷝ◌̕b; à◌֮◌ᷝ◌̕b; a◌֮◌̀◌ᷝ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER L, LATIN SMALL LETTER B
+0061 1DDD 0315 0300 05AE 0062;0061 05AE 1DDD 0300 0315 0062;0061 05AE 1DDD 0300 0315 0062;0061 05AE 1DDD 0300 0315 0062;0061 05AE 1DDD 0300 0315 0062; # (a◌ᷝ◌̕◌̀◌֮b; a◌֮◌ᷝ◌̀◌̕b; a◌֮◌ᷝ◌̀◌̕b; a◌֮◌ᷝ◌̀◌̕b; a◌֮◌ᷝ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER L, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DDE 0062;00E0 05AE 1DDE 0315 0062;0061 05AE 0300 1DDE 0315 0062;00E0 05AE 1DDE 0315 0062;0061 05AE 0300 1DDE 0315 0062; # (a◌̕◌̀◌֮◌ᷞb; à◌֮◌ᷞ◌̕b; a◌֮◌̀◌ᷞ◌̕b; à◌֮◌ᷞ◌̕b; a◌֮◌̀◌ᷞ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN LETTER SMALL CAPITAL L, LATIN SMALL LETTER B
+0061 1DDE 0315 0300 05AE 0062;0061 05AE 1DDE 0300 0315 0062;0061 05AE 1DDE 0300 0315 0062;0061 05AE 1DDE 0300 0315 0062;0061 05AE 1DDE 0300 0315 0062; # (a◌ᷞ◌̕◌̀◌֮b; a◌֮◌ᷞ◌̀◌̕b; a◌֮◌ᷞ◌̀◌̕b; a◌֮◌ᷞ◌̀◌̕b; a◌֮◌ᷞ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN LETTER SMALL CAPITAL L, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DDF 0062;00E0 05AE 1DDF 0315 0062;0061 05AE 0300 1DDF 0315 0062;00E0 05AE 1DDF 0315 0062;0061 05AE 0300 1DDF 0315 0062; # (a◌̕◌̀◌֮◌ᷟb; à◌֮◌ᷟ◌̕b; a◌֮◌̀◌ᷟ◌̕b; à◌֮◌ᷟ◌̕b; a◌֮◌̀◌ᷟ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN LETTER SMALL CAPITAL M, LATIN SMALL LETTER B
+0061 1DDF 0315 0300 05AE 0062;0061 05AE 1DDF 0300 0315 0062;0061 05AE 1DDF 0300 0315 0062;0061 05AE 1DDF 0300 0315 0062;0061 05AE 1DDF 0300 0315 0062; # (a◌ᷟ◌̕◌̀◌֮b; a◌֮◌ᷟ◌̀◌̕b; a◌֮◌ᷟ◌̀◌̕b; a◌֮◌ᷟ◌̀◌̕b; a◌֮◌ᷟ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN LETTER SMALL CAPITAL M, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DE0 0062;00E0 05AE 1DE0 0315 0062;0061 05AE 0300 1DE0 0315 0062;00E0 05AE 1DE0 0315 0062;0061 05AE 0300 1DE0 0315 0062; # (a◌̕◌̀◌֮◌ᷠb; à◌֮◌ᷠ◌̕b; a◌֮◌̀◌ᷠ◌̕b; à◌֮◌ᷠ◌̕b; a◌֮◌̀◌ᷠ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER N, LATIN SMALL LETTER B
+0061 1DE0 0315 0300 05AE 0062;0061 05AE 1DE0 0300 0315 0062;0061 05AE 1DE0 0300 0315 0062;0061 05AE 1DE0 0300 0315 0062;0061 05AE 1DE0 0300 0315 0062; # (a◌ᷠ◌̕◌̀◌֮b; a◌֮◌ᷠ◌̀◌̕b; a◌֮◌ᷠ◌̀◌̕b; a◌֮◌ᷠ◌̀◌̕b; a◌֮◌ᷠ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER N, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DE1 0062;00E0 05AE 1DE1 0315 0062;0061 05AE 0300 1DE1 0315 0062;00E0 05AE 1DE1 0315 0062;0061 05AE 0300 1DE1 0315 0062; # (a◌̕◌̀◌֮◌ᷡb; à◌֮◌ᷡ◌̕b; a◌֮◌̀◌ᷡ◌̕b; à◌֮◌ᷡ◌̕b; a◌֮◌̀◌ᷡ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN LETTER SMALL CAPITAL N, LATIN SMALL LETTER B
+0061 1DE1 0315 0300 05AE 0062;0061 05AE 1DE1 0300 0315 0062;0061 05AE 1DE1 0300 0315 0062;0061 05AE 1DE1 0300 0315 0062;0061 05AE 1DE1 0300 0315 0062; # (a◌ᷡ◌̕◌̀◌֮b; a◌֮◌ᷡ◌̀◌̕b; a◌֮◌ᷡ◌̀◌̕b; a◌֮◌ᷡ◌̀◌̕b; a◌֮◌ᷡ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN LETTER SMALL CAPITAL N, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DE2 0062;00E0 05AE 1DE2 0315 0062;0061 05AE 0300 1DE2 0315 0062;00E0 05AE 1DE2 0315 0062;0061 05AE 0300 1DE2 0315 0062; # (a◌̕◌̀◌֮◌ᷢb; à◌֮◌ᷢ◌̕b; a◌֮◌̀◌ᷢ◌̕b; à◌֮◌ᷢ◌̕b; a◌֮◌̀◌ᷢ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN LETTER SMALL CAPITAL R, LATIN SMALL LETTER B
+0061 1DE2 0315 0300 05AE 0062;0061 05AE 1DE2 0300 0315 0062;0061 05AE 1DE2 0300 0315 0062;0061 05AE 1DE2 0300 0315 0062;0061 05AE 1DE2 0300 0315 0062; # (a◌ᷢ◌̕◌̀◌֮b; a◌֮◌ᷢ◌̀◌̕b; a◌֮◌ᷢ◌̀◌̕b; a◌֮◌ᷢ◌̀◌̕b; a◌֮◌ᷢ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN LETTER SMALL CAPITAL R, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DE3 0062;00E0 05AE 1DE3 0315 0062;0061 05AE 0300 1DE3 0315 0062;00E0 05AE 1DE3 0315 0062;0061 05AE 0300 1DE3 0315 0062; # (a◌̕◌̀◌֮◌ᷣb; à◌֮◌ᷣ◌̕b; a◌֮◌̀◌ᷣ◌̕b; à◌֮◌ᷣ◌̕b; a◌֮◌̀◌ᷣ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER R ROTUNDA, LATIN SMALL LETTER B
+0061 1DE3 0315 0300 05AE 0062;0061 05AE 1DE3 0300 0315 0062;0061 05AE 1DE3 0300 0315 0062;0061 05AE 1DE3 0300 0315 0062;0061 05AE 1DE3 0300 0315 0062; # (a◌ᷣ◌̕◌̀◌֮b; a◌֮◌ᷣ◌̀◌̕b; a◌֮◌ᷣ◌̀◌̕b; a◌֮◌ᷣ◌̀◌̕b; a◌֮◌ᷣ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER R ROTUNDA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DE4 0062;00E0 05AE 1DE4 0315 0062;0061 05AE 0300 1DE4 0315 0062;00E0 05AE 1DE4 0315 0062;0061 05AE 0300 1DE4 0315 0062; # (a◌̕◌̀◌֮◌ᷤb; à◌֮◌ᷤ◌̕b; a◌֮◌̀◌ᷤ◌̕b; à◌֮◌ᷤ◌̕b; a◌֮◌̀◌ᷤ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER S, LATIN SMALL LETTER B
+0061 1DE4 0315 0300 05AE 0062;0061 05AE 1DE4 0300 0315 0062;0061 05AE 1DE4 0300 0315 0062;0061 05AE 1DE4 0300 0315 0062;0061 05AE 1DE4 0300 0315 0062; # (a◌ᷤ◌̕◌̀◌֮b; a◌֮◌ᷤ◌̀◌̕b; a◌֮◌ᷤ◌̀◌̕b; a◌֮◌ᷤ◌̀◌̕b; a◌֮◌ᷤ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER S, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DE5 0062;00E0 05AE 1DE5 0315 0062;0061 05AE 0300 1DE5 0315 0062;00E0 05AE 1DE5 0315 0062;0061 05AE 0300 1DE5 0315 0062; # (a◌̕◌̀◌֮◌ᷥb; à◌֮◌ᷥ◌̕b; a◌֮◌̀◌ᷥ◌̕b; à◌֮◌ᷥ◌̕b; a◌֮◌̀◌ᷥ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER LONG S, LATIN SMALL LETTER B
+0061 1DE5 0315 0300 05AE 0062;0061 05AE 1DE5 0300 0315 0062;0061 05AE 1DE5 0300 0315 0062;0061 05AE 1DE5 0300 0315 0062;0061 05AE 1DE5 0300 0315 0062; # (a◌ᷥ◌̕◌̀◌֮b; a◌֮◌ᷥ◌̀◌̕b; a◌֮◌ᷥ◌̀◌̕b; a◌֮◌ᷥ◌̀◌̕b; a◌֮◌ᷥ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER LONG S, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DE6 0062;00E0 05AE 1DE6 0315 0062;0061 05AE 0300 1DE6 0315 0062;00E0 05AE 1DE6 0315 0062;0061 05AE 0300 1DE6 0315 0062; # (a◌̕◌̀◌֮◌ᷦb; à◌֮◌ᷦ◌̕b; a◌֮◌̀◌ᷦ◌̕b; à◌֮◌ᷦ◌̕b; a◌֮◌̀◌ᷦ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER Z, LATIN SMALL LETTER B
+0061 1DE6 0315 0300 05AE 0062;0061 05AE 1DE6 0300 0315 0062;0061 05AE 1DE6 0300 0315 0062;0061 05AE 1DE6 0300 0315 0062;0061 05AE 1DE6 0300 0315 0062; # (a◌ᷦ◌̕◌̀◌֮b; a◌֮◌ᷦ◌̀◌̕b; a◌֮◌ᷦ◌̀◌̕b; a◌֮◌ᷦ◌̀◌̕b; a◌֮◌ᷦ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER Z, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DE7 0062;00E0 05AE 1DE7 0315 0062;0061 05AE 0300 1DE7 0315 0062;00E0 05AE 1DE7 0315 0062;0061 05AE 0300 1DE7 0315 0062; # (a◌̕◌̀◌֮◌ᷧb; à◌֮◌ᷧ◌̕b; a◌֮◌̀◌ᷧ◌̕b; à◌֮◌ᷧ◌̕b; a◌֮◌̀◌ᷧ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER ALPHA, LATIN SMALL LETTER B
+0061 1DE7 0315 0300 05AE 0062;0061 05AE 1DE7 0300 0315 0062;0061 05AE 1DE7 0300 0315 0062;0061 05AE 1DE7 0300 0315 0062;0061 05AE 1DE7 0300 0315 0062; # (a◌ᷧ◌̕◌̀◌֮b; a◌֮◌ᷧ◌̀◌̕b; a◌֮◌ᷧ◌̀◌̕b; a◌֮◌ᷧ◌̀◌̕b; a◌֮◌ᷧ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER ALPHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DE8 0062;00E0 05AE 1DE8 0315 0062;0061 05AE 0300 1DE8 0315 0062;00E0 05AE 1DE8 0315 0062;0061 05AE 0300 1DE8 0315 0062; # (a◌̕◌̀◌֮◌ᷨb; à◌֮◌ᷨ◌̕b; a◌֮◌̀◌ᷨ◌̕b; à◌֮◌ᷨ◌̕b; a◌֮◌̀◌ᷨ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER B, LATIN SMALL LETTER B
+0061 1DE8 0315 0300 05AE 0062;0061 05AE 1DE8 0300 0315 0062;0061 05AE 1DE8 0300 0315 0062;0061 05AE 1DE8 0300 0315 0062;0061 05AE 1DE8 0300 0315 0062; # (a◌ᷨ◌̕◌̀◌֮b; a◌֮◌ᷨ◌̀◌̕b; a◌֮◌ᷨ◌̀◌̕b; a◌֮◌ᷨ◌̀◌̕b; a◌֮◌ᷨ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER B, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DE9 0062;00E0 05AE 1DE9 0315 0062;0061 05AE 0300 1DE9 0315 0062;00E0 05AE 1DE9 0315 0062;0061 05AE 0300 1DE9 0315 0062; # (a◌̕◌̀◌֮◌ᷩb; à◌֮◌ᷩ◌̕b; a◌֮◌̀◌ᷩ◌̕b; à◌֮◌ᷩ◌̕b; a◌֮◌̀◌ᷩ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER BETA, LATIN SMALL LETTER B
+0061 1DE9 0315 0300 05AE 0062;0061 05AE 1DE9 0300 0315 0062;0061 05AE 1DE9 0300 0315 0062;0061 05AE 1DE9 0300 0315 0062;0061 05AE 1DE9 0300 0315 0062; # (a◌ᷩ◌̕◌̀◌֮b; a◌֮◌ᷩ◌̀◌̕b; a◌֮◌ᷩ◌̀◌̕b; a◌֮◌ᷩ◌̀◌̕b; a◌֮◌ᷩ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER BETA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DEA 0062;00E0 05AE 1DEA 0315 0062;0061 05AE 0300 1DEA 0315 0062;00E0 05AE 1DEA 0315 0062;0061 05AE 0300 1DEA 0315 0062; # (a◌̕◌̀◌֮◌ᷪb; à◌֮◌ᷪ◌̕b; a◌֮◌̀◌ᷪ◌̕b; à◌֮◌ᷪ◌̕b; a◌֮◌̀◌ᷪ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER SCHWA, LATIN SMALL LETTER B
+0061 1DEA 0315 0300 05AE 0062;0061 05AE 1DEA 0300 0315 0062;0061 05AE 1DEA 0300 0315 0062;0061 05AE 1DEA 0300 0315 0062;0061 05AE 1DEA 0300 0315 0062; # (a◌ᷪ◌̕◌̀◌֮b; a◌֮◌ᷪ◌̀◌̕b; a◌֮◌ᷪ◌̀◌̕b; a◌֮◌ᷪ◌̀◌̕b; a◌֮◌ᷪ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER SCHWA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DEB 0062;00E0 05AE 1DEB 0315 0062;0061 05AE 0300 1DEB 0315 0062;00E0 05AE 1DEB 0315 0062;0061 05AE 0300 1DEB 0315 0062; # (a◌̕◌̀◌֮◌ᷫb; à◌֮◌ᷫ◌̕b; a◌֮◌̀◌ᷫ◌̕b; à◌֮◌ᷫ◌̕b; a◌֮◌̀◌ᷫ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER F, LATIN SMALL LETTER B
+0061 1DEB 0315 0300 05AE 0062;0061 05AE 1DEB 0300 0315 0062;0061 05AE 1DEB 0300 0315 0062;0061 05AE 1DEB 0300 0315 0062;0061 05AE 1DEB 0300 0315 0062; # (a◌ᷫ◌̕◌̀◌֮b; a◌֮◌ᷫ◌̀◌̕b; a◌֮◌ᷫ◌̀◌̕b; a◌֮◌ᷫ◌̀◌̕b; a◌֮◌ᷫ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER F, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DEC 0062;00E0 05AE 1DEC 0315 0062;0061 05AE 0300 1DEC 0315 0062;00E0 05AE 1DEC 0315 0062;0061 05AE 0300 1DEC 0315 0062; # (a◌̕◌̀◌֮◌ᷬb; à◌֮◌ᷬ◌̕b; a◌֮◌̀◌ᷬ◌̕b; à◌֮◌ᷬ◌̕b; a◌֮◌̀◌ᷬ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE, LATIN SMALL LETTER B
+0061 1DEC 0315 0300 05AE 0062;0061 05AE 1DEC 0300 0315 0062;0061 05AE 1DEC 0300 0315 0062;0061 05AE 1DEC 0300 0315 0062;0061 05AE 1DEC 0300 0315 0062; # (a◌ᷬ◌̕◌̀◌֮b; a◌֮◌ᷬ◌̀◌̕b; a◌֮◌ᷬ◌̀◌̕b; a◌֮◌ᷬ◌̀◌̕b; a◌֮◌ᷬ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DED 0062;00E0 05AE 1DED 0315 0062;0061 05AE 0300 1DED 0315 0062;00E0 05AE 1DED 0315 0062;0061 05AE 0300 1DED 0315 0062; # (a◌̕◌̀◌֮◌ᷭb; à◌֮◌ᷭ◌̕b; a◌֮◌̀◌ᷭ◌̕b; à◌֮◌ᷭ◌̕b; a◌֮◌̀◌ᷭ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER O WITH LIGHT CENTRALIZATION STROKE, LATIN SMALL LETTER B
+0061 1DED 0315 0300 05AE 0062;0061 05AE 1DED 0300 0315 0062;0061 05AE 1DED 0300 0315 0062;0061 05AE 1DED 0300 0315 0062;0061 05AE 1DED 0300 0315 0062; # (a◌ᷭ◌̕◌̀◌֮b; a◌֮◌ᷭ◌̀◌̕b; a◌֮◌ᷭ◌̀◌̕b; a◌֮◌ᷭ◌̀◌̕b; a◌֮◌ᷭ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER O WITH LIGHT CENTRALIZATION STROKE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DEE 0062;00E0 05AE 1DEE 0315 0062;0061 05AE 0300 1DEE 0315 0062;00E0 05AE 1DEE 0315 0062;0061 05AE 0300 1DEE 0315 0062; # (a◌̕◌̀◌֮◌ᷮb; à◌֮◌ᷮ◌̕b; a◌֮◌̀◌ᷮ◌̕b; à◌֮◌ᷮ◌̕b; a◌֮◌̀◌ᷮ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER P, LATIN SMALL LETTER B
+0061 1DEE 0315 0300 05AE 0062;0061 05AE 1DEE 0300 0315 0062;0061 05AE 1DEE 0300 0315 0062;0061 05AE 1DEE 0300 0315 0062;0061 05AE 1DEE 0300 0315 0062; # (a◌ᷮ◌̕◌̀◌֮b; a◌֮◌ᷮ◌̀◌̕b; a◌֮◌ᷮ◌̀◌̕b; a◌֮◌ᷮ◌̀◌̕b; a◌֮◌ᷮ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER P, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DEF 0062;00E0 05AE 1DEF 0315 0062;0061 05AE 0300 1DEF 0315 0062;00E0 05AE 1DEF 0315 0062;0061 05AE 0300 1DEF 0315 0062; # (a◌̕◌̀◌֮◌ᷯb; à◌֮◌ᷯ◌̕b; a◌֮◌̀◌ᷯ◌̕b; à◌֮◌ᷯ◌̕b; a◌֮◌̀◌ᷯ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER ESH, LATIN SMALL LETTER B
+0061 1DEF 0315 0300 05AE 0062;0061 05AE 1DEF 0300 0315 0062;0061 05AE 1DEF 0300 0315 0062;0061 05AE 1DEF 0300 0315 0062;0061 05AE 1DEF 0300 0315 0062; # (a◌ᷯ◌̕◌̀◌֮b; a◌֮◌ᷯ◌̀◌̕b; a◌֮◌ᷯ◌̀◌̕b; a◌֮◌ᷯ◌̀◌̕b; a◌֮◌ᷯ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER ESH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DF0 0062;00E0 05AE 1DF0 0315 0062;0061 05AE 0300 1DF0 0315 0062;00E0 05AE 1DF0 0315 0062;0061 05AE 0300 1DF0 0315 0062; # (a◌̕◌̀◌֮◌ᷰb; à◌֮◌ᷰ◌̕b; a◌֮◌̀◌ᷰ◌̕b; à◌֮◌ᷰ◌̕b; a◌֮◌̀◌ᷰ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER U WITH LIGHT CENTRALIZATION STROKE, LATIN SMALL LETTER B
+0061 1DF0 0315 0300 05AE 0062;0061 05AE 1DF0 0300 0315 0062;0061 05AE 1DF0 0300 0315 0062;0061 05AE 1DF0 0300 0315 0062;0061 05AE 1DF0 0300 0315 0062; # (a◌ᷰ◌̕◌̀◌֮b; a◌֮◌ᷰ◌̀◌̕b; a◌֮◌ᷰ◌̀◌̕b; a◌֮◌ᷰ◌̀◌̕b; a◌֮◌ᷰ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER U WITH LIGHT CENTRALIZATION STROKE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DF1 0062;00E0 05AE 1DF1 0315 0062;0061 05AE 0300 1DF1 0315 0062;00E0 05AE 1DF1 0315 0062;0061 05AE 0300 1DF1 0315 0062; # (a◌̕◌̀◌֮◌ᷱb; à◌֮◌ᷱ◌̕b; a◌֮◌̀◌ᷱ◌̕b; à◌֮◌ᷱ◌̕b; a◌֮◌̀◌ᷱ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER W, LATIN SMALL LETTER B
+0061 1DF1 0315 0300 05AE 0062;0061 05AE 1DF1 0300 0315 0062;0061 05AE 1DF1 0300 0315 0062;0061 05AE 1DF1 0300 0315 0062;0061 05AE 1DF1 0300 0315 0062; # (a◌ᷱ◌̕◌̀◌֮b; a◌֮◌ᷱ◌̀◌̕b; a◌֮◌ᷱ◌̀◌̕b; a◌֮◌ᷱ◌̀◌̕b; a◌֮◌ᷱ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER W, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DF2 0062;00E0 05AE 1DF2 0315 0062;0061 05AE 0300 1DF2 0315 0062;00E0 05AE 1DF2 0315 0062;0061 05AE 0300 1DF2 0315 0062; # (a◌̕◌̀◌֮◌ᷲb; à◌֮◌ᷲ◌̕b; a◌֮◌̀◌ᷲ◌̕b; à◌֮◌ᷲ◌̕b; a◌֮◌̀◌ᷲ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER A WITH DIAERESIS, LATIN SMALL LETTER B
+0061 1DF2 0315 0300 05AE 0062;0061 05AE 1DF2 0300 0315 0062;0061 05AE 1DF2 0300 0315 0062;0061 05AE 1DF2 0300 0315 0062;0061 05AE 1DF2 0300 0315 0062; # (a◌ᷲ◌̕◌̀◌֮b; a◌֮◌ᷲ◌̀◌̕b; a◌֮◌ᷲ◌̀◌̕b; a◌֮◌ᷲ◌̀◌̕b; a◌֮◌ᷲ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER A WITH DIAERESIS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DF3 0062;00E0 05AE 1DF3 0315 0062;0061 05AE 0300 1DF3 0315 0062;00E0 05AE 1DF3 0315 0062;0061 05AE 0300 1DF3 0315 0062; # (a◌̕◌̀◌֮◌ᷳb; à◌֮◌ᷳ◌̕b; a◌֮◌̀◌ᷳ◌̕b; à◌֮◌ᷳ◌̕b; a◌֮◌̀◌ᷳ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER O WITH DIAERESIS, LATIN SMALL LETTER B
+0061 1DF3 0315 0300 05AE 0062;0061 05AE 1DF3 0300 0315 0062;0061 05AE 1DF3 0300 0315 0062;0061 05AE 1DF3 0300 0315 0062;0061 05AE 1DF3 0300 0315 0062; # (a◌ᷳ◌̕◌̀◌֮b; a◌֮◌ᷳ◌̀◌̕b; a◌֮◌ᷳ◌̀◌̕b; a◌֮◌ᷳ◌̀◌̕b; a◌֮◌ᷳ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER O WITH DIAERESIS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DF4 0062;00E0 05AE 1DF4 0315 0062;0061 05AE 0300 1DF4 0315 0062;00E0 05AE 1DF4 0315 0062;0061 05AE 0300 1DF4 0315 0062; # (a◌̕◌̀◌֮◌ᷴb; à◌֮◌ᷴ◌̕b; a◌֮◌̀◌ᷴ◌̕b; à◌֮◌ᷴ◌̕b; a◌֮◌̀◌ᷴ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LATIN SMALL LETTER U WITH DIAERESIS, LATIN SMALL LETTER B
+0061 1DF4 0315 0300 05AE 0062;0061 05AE 1DF4 0300 0315 0062;0061 05AE 1DF4 0300 0315 0062;0061 05AE 1DF4 0300 0315 0062;0061 05AE 1DF4 0300 0315 0062; # (a◌ᷴ◌̕◌̀◌֮b; a◌֮◌ᷴ◌̀◌̕b; a◌֮◌ᷴ◌̀◌̕b; a◌֮◌ᷴ◌̀◌̕b; a◌֮◌ᷴ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LATIN SMALL LETTER U WITH DIAERESIS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DF5 0062;00E0 05AE 1DF5 0315 0062;0061 05AE 0300 1DF5 0315 0062;00E0 05AE 1DF5 0315 0062;0061 05AE 0300 1DF5 0315 0062; # (a◌̕◌̀◌֮◌᷵b; à◌֮◌᷵◌̕b; a◌֮◌̀◌᷵◌̕b; à◌֮◌᷵◌̕b; a◌֮◌̀◌᷵◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING UP TACK ABOVE, LATIN SMALL LETTER B
+0061 1DF5 0315 0300 05AE 0062;0061 05AE 1DF5 0300 0315 0062;0061 05AE 1DF5 0300 0315 0062;0061 05AE 1DF5 0300 0315 0062;0061 05AE 1DF5 0300 0315 0062; # (a◌᷵◌̕◌̀◌֮b; a◌֮◌᷵◌̀◌̕b; a◌֮◌᷵◌̀◌̕b; a◌֮◌᷵◌̀◌̕b; a◌֮◌᷵◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING UP TACK ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DFB 0062;00E0 05AE 1DFB 0315 0062;0061 05AE 0300 1DFB 0315 0062;00E0 05AE 1DFB 0315 0062;0061 05AE 0300 1DFB 0315 0062; # (a◌̕◌̀◌֮◌᷻b; à◌֮◌᷻◌̕b; a◌֮◌̀◌᷻◌̕b; à◌֮◌᷻◌̕b; a◌֮◌̀◌᷻◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DELETION MARK, LATIN SMALL LETTER B
+0061 1DFB 0315 0300 05AE 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062; # (a◌᷻◌̕◌̀◌֮b; a◌֮◌᷻◌̀◌̕b; a◌֮◌᷻◌̀◌̕b; a◌֮◌᷻◌̀◌̕b; a◌֮◌᷻◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DELETION MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 035D 035C 0315 1DFC 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062; # (a◌͝◌͜◌̕◌᷼b; a◌̕◌͜◌᷼◌͝b; a◌̕◌͜◌᷼◌͝b; a◌̕◌͜◌᷼◌͝b; a◌̕◌͜◌᷼◌͝b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING DOUBLE INVERTED BREVE BELOW, LATIN SMALL LETTER B
+0061 1DFC 035D 035C 0315 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062;0061 0315 1DFC 035C 035D 0062; # (a◌᷼◌͝◌͜◌̕b; a◌̕◌᷼◌͜◌͝b; a◌̕◌᷼◌͜◌͝b; a◌̕◌᷼◌͜◌͝b; a◌̕◌᷼◌͜◌͝b; ) LATIN SMALL LETTER A, COMBINING DOUBLE INVERTED BREVE BELOW, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, LATIN SMALL LETTER B
+0061 059A 0316 302A 1DFD 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062;0061 302A 0316 1DFD 059A 0062; # (a◌֚◌̖◌〪◌᷽b; a◌〪◌̖◌᷽◌֚b; a◌〪◌̖◌᷽◌֚b; a◌〪◌̖◌᷽◌֚b; a◌〪◌̖◌᷽◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING ALMOST EQUAL TO BELOW, LATIN SMALL LETTER B
+0061 1DFD 059A 0316 302A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062;0061 302A 1DFD 0316 059A 0062; # (a◌᷽◌֚◌̖◌〪b; a◌〪◌᷽◌̖◌֚b; a◌〪◌᷽◌̖◌֚b; a◌〪◌᷽◌̖◌֚b; a◌〪◌᷽◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING ALMOST EQUAL TO BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1DFE 0062;00E0 05AE 1DFE 0315 0062;0061 05AE 0300 1DFE 0315 0062;00E0 05AE 1DFE 0315 0062;0061 05AE 0300 1DFE 0315 0062; # (a◌̕◌̀◌֮◌᷾b; à◌֮◌᷾◌̕b; a◌֮◌̀◌᷾◌̕b; à◌֮◌᷾◌̕b; a◌֮◌̀◌᷾◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LEFT ARROWHEAD ABOVE, LATIN SMALL LETTER B
+0061 1DFE 0315 0300 05AE 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062;0061 05AE 1DFE 0300 0315 0062; # (a◌᷾◌̕◌̀◌֮b; a◌֮◌᷾◌̀◌̕b; a◌֮◌᷾◌̀◌̕b; a◌֮◌᷾◌̀◌̕b; a◌֮◌᷾◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LEFT ARROWHEAD ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 1DFF 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062;0061 302A 0316 1DFF 059A 0062; # (a◌֚◌̖◌〪◌᷿b; a◌〪◌̖◌᷿◌֚b; a◌〪◌̖◌᷿◌֚b; a◌〪◌̖◌᷿◌֚b; a◌〪◌̖◌᷿◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW, LATIN SMALL LETTER B
+0061 1DFF 059A 0316 302A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062;0061 302A 1DFF 0316 059A 0062; # (a◌᷿◌֚◌̖◌〪b; a◌〪◌᷿◌̖◌֚b; a◌〪◌᷿◌̖◌֚b; a◌〪◌᷿◌̖◌֚b; a◌〪◌᷿◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20D0 0062;00E0 05AE 20D0 0315 0062;0061 05AE 0300 20D0 0315 0062;00E0 05AE 20D0 0315 0062;0061 05AE 0300 20D0 0315 0062; # (a◌̕◌̀◌֮◌⃐b; à◌֮◌⃐◌̕b; a◌֮◌̀◌⃐◌̕b; à◌֮◌⃐◌̕b; a◌֮◌̀◌⃐◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LEFT HARPOON ABOVE, LATIN SMALL LETTER B
+0061 20D0 0315 0300 05AE 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062;0061 05AE 20D0 0300 0315 0062; # (a◌⃐◌̕◌̀◌֮b; a◌֮◌⃐◌̀◌̕b; a◌֮◌⃐◌̀◌̕b; a◌֮◌⃐◌̀◌̕b; a◌֮◌⃐◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LEFT HARPOON ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20D1 0062;00E0 05AE 20D1 0315 0062;0061 05AE 0300 20D1 0315 0062;00E0 05AE 20D1 0315 0062;0061 05AE 0300 20D1 0315 0062; # (a◌̕◌̀◌֮◌⃑b; à◌֮◌⃑◌̕b; a◌֮◌̀◌⃑◌̕b; à◌֮◌⃑◌̕b; a◌֮◌̀◌⃑◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING RIGHT HARPOON ABOVE, LATIN SMALL LETTER B
+0061 20D1 0315 0300 05AE 0062;0061 05AE 20D1 0300 0315 0062;0061 05AE 20D1 0300 0315 0062;0061 05AE 20D1 0300 0315 0062;0061 05AE 20D1 0300 0315 0062; # (a◌⃑◌̕◌̀◌֮b; a◌֮◌⃑◌̀◌̕b; a◌֮◌⃑◌̀◌̕b; a◌֮◌⃑◌̀◌̕b; a◌֮◌⃑◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING RIGHT HARPOON ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 093C 0334 20D2 0062;0061 0334 20D2 093C 0062;0061 0334 20D2 093C 0062;0061 0334 20D2 093C 0062;0061 0334 20D2 093C 0062; # (a◌़◌̴◌⃒b; a◌̴◌⃒◌़b; a◌̴◌⃒◌़b; a◌̴◌⃒◌़b; a◌̴◌⃒◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING LONG VERTICAL LINE OVERLAY, LATIN SMALL LETTER B
+0061 20D2 093C 0334 0062;0061 20D2 0334 093C 0062;0061 20D2 0334 093C 0062;0061 20D2 0334 093C 0062;0061 20D2 0334 093C 0062; # (a◌⃒◌़◌̴b; a◌⃒◌̴◌़b; a◌⃒◌̴◌़b; a◌⃒◌̴◌़b; a◌⃒◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING LONG VERTICAL LINE OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 20D3 0062;0061 0334 20D3 093C 0062;0061 0334 20D3 093C 0062;0061 0334 20D3 093C 0062;0061 0334 20D3 093C 0062; # (a◌़◌̴◌⃓b; a◌̴◌⃓◌़b; a◌̴◌⃓◌़b; a◌̴◌⃓◌़b; a◌̴◌⃓◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING SHORT VERTICAL LINE OVERLAY, LATIN SMALL LETTER B
+0061 20D3 093C 0334 0062;0061 20D3 0334 093C 0062;0061 20D3 0334 093C 0062;0061 20D3 0334 093C 0062;0061 20D3 0334 093C 0062; # (a◌⃓◌़◌̴b; a◌⃓◌̴◌़b; a◌⃓◌̴◌़b; a◌⃓◌̴◌़b; a◌⃓◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING SHORT VERTICAL LINE OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20D4 0062;00E0 05AE 20D4 0315 0062;0061 05AE 0300 20D4 0315 0062;00E0 05AE 20D4 0315 0062;0061 05AE 0300 20D4 0315 0062; # (a◌̕◌̀◌֮◌⃔b; à◌֮◌⃔◌̕b; a◌֮◌̀◌⃔◌̕b; à◌֮◌⃔◌̕b; a◌֮◌̀◌⃔◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING ANTICLOCKWISE ARROW ABOVE, LATIN SMALL LETTER B
+0061 20D4 0315 0300 05AE 0062;0061 05AE 20D4 0300 0315 0062;0061 05AE 20D4 0300 0315 0062;0061 05AE 20D4 0300 0315 0062;0061 05AE 20D4 0300 0315 0062; # (a◌⃔◌̕◌̀◌֮b; a◌֮◌⃔◌̀◌̕b; a◌֮◌⃔◌̀◌̕b; a◌֮◌⃔◌̀◌̕b; a◌֮◌⃔◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ANTICLOCKWISE ARROW ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20D5 0062;00E0 05AE 20D5 0315 0062;0061 05AE 0300 20D5 0315 0062;00E0 05AE 20D5 0315 0062;0061 05AE 0300 20D5 0315 0062; # (a◌̕◌̀◌֮◌⃕b; à◌֮◌⃕◌̕b; a◌֮◌̀◌⃕◌̕b; à◌֮◌⃕◌̕b; a◌֮◌̀◌⃕◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CLOCKWISE ARROW ABOVE, LATIN SMALL LETTER B
+0061 20D5 0315 0300 05AE 0062;0061 05AE 20D5 0300 0315 0062;0061 05AE 20D5 0300 0315 0062;0061 05AE 20D5 0300 0315 0062;0061 05AE 20D5 0300 0315 0062; # (a◌⃕◌̕◌̀◌֮b; a◌֮◌⃕◌̀◌̕b; a◌֮◌⃕◌̀◌̕b; a◌֮◌⃕◌̀◌̕b; a◌֮◌⃕◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CLOCKWISE ARROW ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20D6 0062;00E0 05AE 20D6 0315 0062;0061 05AE 0300 20D6 0315 0062;00E0 05AE 20D6 0315 0062;0061 05AE 0300 20D6 0315 0062; # (a◌̕◌̀◌֮◌⃖b; à◌֮◌⃖◌̕b; a◌֮◌̀◌⃖◌̕b; à◌֮◌⃖◌̕b; a◌֮◌̀◌⃖◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LEFT ARROW ABOVE, LATIN SMALL LETTER B
+0061 20D6 0315 0300 05AE 0062;0061 05AE 20D6 0300 0315 0062;0061 05AE 20D6 0300 0315 0062;0061 05AE 20D6 0300 0315 0062;0061 05AE 20D6 0300 0315 0062; # (a◌⃖◌̕◌̀◌֮b; a◌֮◌⃖◌̀◌̕b; a◌֮◌⃖◌̀◌̕b; a◌֮◌⃖◌̀◌̕b; a◌֮◌⃖◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LEFT ARROW ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20D7 0062;00E0 05AE 20D7 0315 0062;0061 05AE 0300 20D7 0315 0062;00E0 05AE 20D7 0315 0062;0061 05AE 0300 20D7 0315 0062; # (a◌̕◌̀◌֮◌⃗b; à◌֮◌⃗◌̕b; a◌֮◌̀◌⃗◌̕b; à◌֮◌⃗◌̕b; a◌֮◌̀◌⃗◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING RIGHT ARROW ABOVE, LATIN SMALL LETTER B
+0061 20D7 0315 0300 05AE 0062;0061 05AE 20D7 0300 0315 0062;0061 05AE 20D7 0300 0315 0062;0061 05AE 20D7 0300 0315 0062;0061 05AE 20D7 0300 0315 0062; # (a◌⃗◌̕◌̀◌֮b; a◌֮◌⃗◌̀◌̕b; a◌֮◌⃗◌̀◌̕b; a◌֮◌⃗◌̀◌̕b; a◌֮◌⃗◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROW ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 093C 0334 20D8 0062;0061 0334 20D8 093C 0062;0061 0334 20D8 093C 0062;0061 0334 20D8 093C 0062;0061 0334 20D8 093C 0062; # (a◌़◌̴◌⃘b; a◌̴◌⃘◌़b; a◌̴◌⃘◌़b; a◌̴◌⃘◌़b; a◌̴◌⃘◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING RING OVERLAY, LATIN SMALL LETTER B
+0061 20D8 093C 0334 0062;0061 20D8 0334 093C 0062;0061 20D8 0334 093C 0062;0061 20D8 0334 093C 0062;0061 20D8 0334 093C 0062; # (a◌⃘◌़◌̴b; a◌⃘◌̴◌़b; a◌⃘◌̴◌़b; a◌⃘◌̴◌़b; a◌⃘◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING RING OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 20D9 0062;0061 0334 20D9 093C 0062;0061 0334 20D9 093C 0062;0061 0334 20D9 093C 0062;0061 0334 20D9 093C 0062; # (a◌़◌̴◌⃙b; a◌̴◌⃙◌़b; a◌̴◌⃙◌़b; a◌̴◌⃙◌़b; a◌̴◌⃙◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING CLOCKWISE RING OVERLAY, LATIN SMALL LETTER B
+0061 20D9 093C 0334 0062;0061 20D9 0334 093C 0062;0061 20D9 0334 093C 0062;0061 20D9 0334 093C 0062;0061 20D9 0334 093C 0062; # (a◌⃙◌़◌̴b; a◌⃙◌̴◌़b; a◌⃙◌̴◌़b; a◌⃙◌̴◌़b; a◌⃙◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING CLOCKWISE RING OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 20DA 0062;0061 0334 20DA 093C 0062;0061 0334 20DA 093C 0062;0061 0334 20DA 093C 0062;0061 0334 20DA 093C 0062; # (a◌़◌̴◌⃚b; a◌̴◌⃚◌़b; a◌̴◌⃚◌़b; a◌̴◌⃚◌़b; a◌̴◌⃚◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING ANTICLOCKWISE RING OVERLAY, LATIN SMALL LETTER B
+0061 20DA 093C 0334 0062;0061 20DA 0334 093C 0062;0061 20DA 0334 093C 0062;0061 20DA 0334 093C 0062;0061 20DA 0334 093C 0062; # (a◌⃚◌़◌̴b; a◌⃚◌̴◌़b; a◌⃚◌̴◌़b; a◌⃚◌̴◌़b; a◌⃚◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING ANTICLOCKWISE RING OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20DB 0062;00E0 05AE 20DB 0315 0062;0061 05AE 0300 20DB 0315 0062;00E0 05AE 20DB 0315 0062;0061 05AE 0300 20DB 0315 0062; # (a◌̕◌̀◌֮◌⃛b; à◌֮◌⃛◌̕b; a◌֮◌̀◌⃛◌̕b; à◌֮◌⃛◌̕b; a◌֮◌̀◌⃛◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING THREE DOTS ABOVE, LATIN SMALL LETTER B
+0061 20DB 0315 0300 05AE 0062;0061 05AE 20DB 0300 0315 0062;0061 05AE 20DB 0300 0315 0062;0061 05AE 20DB 0300 0315 0062;0061 05AE 20DB 0300 0315 0062; # (a◌⃛◌̕◌̀◌֮b; a◌֮◌⃛◌̀◌̕b; a◌֮◌⃛◌̀◌̕b; a◌֮◌⃛◌̀◌̕b; a◌֮◌⃛◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING THREE DOTS ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20DC 0062;00E0 05AE 20DC 0315 0062;0061 05AE 0300 20DC 0315 0062;00E0 05AE 20DC 0315 0062;0061 05AE 0300 20DC 0315 0062; # (a◌̕◌̀◌֮◌⃜b; à◌֮◌⃜◌̕b; a◌֮◌̀◌⃜◌̕b; à◌֮◌⃜◌̕b; a◌֮◌̀◌⃜◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING FOUR DOTS ABOVE, LATIN SMALL LETTER B
+0061 20DC 0315 0300 05AE 0062;0061 05AE 20DC 0300 0315 0062;0061 05AE 20DC 0300 0315 0062;0061 05AE 20DC 0300 0315 0062;0061 05AE 20DC 0300 0315 0062; # (a◌⃜◌̕◌̀◌֮b; a◌֮◌⃜◌̀◌̕b; a◌֮◌⃜◌̀◌̕b; a◌֮◌⃜◌̀◌̕b; a◌֮◌⃜◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING FOUR DOTS ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20E1 0062;00E0 05AE 20E1 0315 0062;0061 05AE 0300 20E1 0315 0062;00E0 05AE 20E1 0315 0062;0061 05AE 0300 20E1 0315 0062; # (a◌̕◌̀◌֮◌⃡b; à◌֮◌⃡◌̕b; a◌֮◌̀◌⃡◌̕b; à◌֮◌⃡◌̕b; a◌֮◌̀◌⃡◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LEFT RIGHT ARROW ABOVE, LATIN SMALL LETTER B
+0061 20E1 0315 0300 05AE 0062;0061 05AE 20E1 0300 0315 0062;0061 05AE 20E1 0300 0315 0062;0061 05AE 20E1 0300 0315 0062;0061 05AE 20E1 0300 0315 0062; # (a◌⃡◌̕◌̀◌֮b; a◌֮◌⃡◌̀◌̕b; a◌֮◌⃡◌̀◌̕b; a◌֮◌⃡◌̀◌̕b; a◌֮◌⃡◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LEFT RIGHT ARROW ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 093C 0334 20E5 0062;0061 0334 20E5 093C 0062;0061 0334 20E5 093C 0062;0061 0334 20E5 093C 0062;0061 0334 20E5 093C 0062; # (a◌़◌̴◌⃥b; a◌̴◌⃥◌़b; a◌̴◌⃥◌़b; a◌̴◌⃥◌़b; a◌̴◌⃥◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING REVERSE SOLIDUS OVERLAY, LATIN SMALL LETTER B
+0061 20E5 093C 0334 0062;0061 20E5 0334 093C 0062;0061 20E5 0334 093C 0062;0061 20E5 0334 093C 0062;0061 20E5 0334 093C 0062; # (a◌⃥◌़◌̴b; a◌⃥◌̴◌़b; a◌⃥◌̴◌़b; a◌⃥◌̴◌़b; a◌⃥◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING REVERSE SOLIDUS OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 20E6 0062;0061 0334 20E6 093C 0062;0061 0334 20E6 093C 0062;0061 0334 20E6 093C 0062;0061 0334 20E6 093C 0062; # (a◌़◌̴◌⃦b; a◌̴◌⃦◌़b; a◌̴◌⃦◌़b; a◌̴◌⃦◌़b; a◌̴◌⃦◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING DOUBLE VERTICAL STROKE OVERLAY, LATIN SMALL LETTER B
+0061 20E6 093C 0334 0062;0061 20E6 0334 093C 0062;0061 20E6 0334 093C 0062;0061 20E6 0334 093C 0062;0061 20E6 0334 093C 0062; # (a◌⃦◌़◌̴b; a◌⃦◌̴◌़b; a◌⃦◌̴◌़b; a◌⃦◌̴◌़b; a◌⃦◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING DOUBLE VERTICAL STROKE OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20E7 0062;00E0 05AE 20E7 0315 0062;0061 05AE 0300 20E7 0315 0062;00E0 05AE 20E7 0315 0062;0061 05AE 0300 20E7 0315 0062; # (a◌̕◌̀◌֮◌⃧b; à◌֮◌⃧◌̕b; a◌֮◌̀◌⃧◌̕b; à◌֮◌⃧◌̕b; a◌֮◌̀◌⃧◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING ANNUITY SYMBOL, LATIN SMALL LETTER B
+0061 20E7 0315 0300 05AE 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062;0061 05AE 20E7 0300 0315 0062; # (a◌⃧◌̕◌̀◌֮b; a◌֮◌⃧◌̀◌̕b; a◌֮◌⃧◌̀◌̕b; a◌֮◌⃧◌̀◌̕b; a◌֮◌⃧◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ANNUITY SYMBOL, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 20E8 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062;0061 302A 0316 20E8 059A 0062; # (a◌֚◌̖◌〪◌⃨b; a◌〪◌̖◌⃨◌֚b; a◌〪◌̖◌⃨◌֚b; a◌〪◌̖◌⃨◌֚b; a◌〪◌̖◌⃨◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING TRIPLE UNDERDOT, LATIN SMALL LETTER B
+0061 20E8 059A 0316 302A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062;0061 302A 20E8 0316 059A 0062; # (a◌⃨◌֚◌̖◌〪b; a◌〪◌⃨◌̖◌֚b; a◌〪◌⃨◌̖◌֚b; a◌〪◌⃨◌̖◌֚b; a◌〪◌⃨◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TRIPLE UNDERDOT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20E9 0062;00E0 05AE 20E9 0315 0062;0061 05AE 0300 20E9 0315 0062;00E0 05AE 20E9 0315 0062;0061 05AE 0300 20E9 0315 0062; # (a◌̕◌̀◌֮◌⃩b; à◌֮◌⃩◌̕b; a◌֮◌̀◌⃩◌̕b; à◌֮◌⃩◌̕b; a◌֮◌̀◌⃩◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING WIDE BRIDGE ABOVE, LATIN SMALL LETTER B
+0061 20E9 0315 0300 05AE 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062;0061 05AE 20E9 0300 0315 0062; # (a◌⃩◌̕◌̀◌֮b; a◌֮◌⃩◌̀◌̕b; a◌֮◌⃩◌̀◌̕b; a◌֮◌⃩◌̀◌̕b; a◌֮◌⃩◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING WIDE BRIDGE ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 093C 0334 20EA 0062;0061 0334 20EA 093C 0062;0061 0334 20EA 093C 0062;0061 0334 20EA 093C 0062;0061 0334 20EA 093C 0062; # (a◌़◌̴◌⃪b; a◌̴◌⃪◌़b; a◌̴◌⃪◌़b; a◌̴◌⃪◌़b; a◌̴◌⃪◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING LEFTWARDS ARROW OVERLAY, LATIN SMALL LETTER B
+0061 20EA 093C 0334 0062;0061 20EA 0334 093C 0062;0061 20EA 0334 093C 0062;0061 20EA 0334 093C 0062;0061 20EA 0334 093C 0062; # (a◌⃪◌़◌̴b; a◌⃪◌̴◌़b; a◌⃪◌̴◌़b; a◌⃪◌̴◌़b; a◌⃪◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING LEFTWARDS ARROW OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 20EB 0062;0061 0334 20EB 093C 0062;0061 0334 20EB 093C 0062;0061 0334 20EB 093C 0062;0061 0334 20EB 093C 0062; # (a◌़◌̴◌⃫b; a◌̴◌⃫◌़b; a◌̴◌⃫◌़b; a◌̴◌⃫◌़b; a◌̴◌⃫◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, COMBINING LONG DOUBLE SOLIDUS OVERLAY, LATIN SMALL LETTER B
+0061 20EB 093C 0334 0062;0061 20EB 0334 093C 0062;0061 20EB 0334 093C 0062;0061 20EB 0334 093C 0062;0061 20EB 0334 093C 0062; # (a◌⃫◌़◌̴b; a◌⃫◌̴◌़b; a◌⃫◌̴◌़b; a◌⃫◌̴◌़b; a◌⃫◌̴◌़b; ) LATIN SMALL LETTER A, COMBINING LONG DOUBLE SOLIDUS OVERLAY, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 059A 0316 302A 20EC 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062;0061 302A 0316 20EC 059A 0062; # (a◌֚◌̖◌〪◌⃬b; a◌〪◌̖◌⃬◌֚b; a◌〪◌̖◌⃬◌֚b; a◌〪◌̖◌⃬◌֚b; a◌〪◌̖◌⃬◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS, LATIN SMALL LETTER B
+0061 20EC 059A 0316 302A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062;0061 302A 20EC 0316 059A 0062; # (a◌⃬◌֚◌̖◌〪b; a◌〪◌⃬◌̖◌֚b; a◌〪◌⃬◌̖◌֚b; a◌〪◌⃬◌̖◌֚b; a◌〪◌⃬◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 20ED 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062;0061 302A 0316 20ED 059A 0062; # (a◌֚◌̖◌〪◌⃭b; a◌〪◌̖◌⃭◌֚b; a◌〪◌̖◌⃭◌֚b; a◌〪◌̖◌⃭◌֚b; a◌〪◌̖◌⃭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS, LATIN SMALL LETTER B
+0061 20ED 059A 0316 302A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062;0061 302A 20ED 0316 059A 0062; # (a◌⃭◌֚◌̖◌〪b; a◌〪◌⃭◌̖◌֚b; a◌〪◌⃭◌̖◌֚b; a◌〪◌⃭◌̖◌֚b; a◌〪◌⃭◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 20EE 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062;0061 302A 0316 20EE 059A 0062; # (a◌֚◌̖◌〪◌⃮b; a◌〪◌̖◌⃮◌֚b; a◌〪◌̖◌⃮◌֚b; a◌〪◌̖◌⃮◌֚b; a◌〪◌̖◌⃮◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LEFT ARROW BELOW, LATIN SMALL LETTER B
+0061 20EE 059A 0316 302A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062;0061 302A 20EE 0316 059A 0062; # (a◌⃮◌֚◌̖◌〪b; a◌〪◌⃮◌̖◌֚b; a◌〪◌⃮◌̖◌֚b; a◌〪◌⃮◌̖◌֚b; a◌〪◌⃮◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LEFT ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 20EF 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062;0061 302A 0316 20EF 059A 0062; # (a◌֚◌̖◌〪◌⃯b; a◌〪◌̖◌⃯◌֚b; a◌〪◌̖◌⃯◌֚b; a◌〪◌̖◌⃯◌֚b; a◌〪◌̖◌⃯◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING RIGHT ARROW BELOW, LATIN SMALL LETTER B
+0061 20EF 059A 0316 302A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062;0061 302A 20EF 0316 059A 0062; # (a◌⃯◌֚◌̖◌〪b; a◌〪◌⃯◌̖◌֚b; a◌〪◌⃯◌̖◌֚b; a◌〪◌⃯◌̖◌֚b; a◌〪◌⃯◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING RIGHT ARROW BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 20F0 0062;00E0 05AE 20F0 0315 0062;0061 05AE 0300 20F0 0315 0062;00E0 05AE 20F0 0315 0062;0061 05AE 0300 20F0 0315 0062; # (a◌̕◌̀◌֮◌⃰b; à◌֮◌⃰◌̕b; a◌֮◌̀◌⃰◌̕b; à◌֮◌⃰◌̕b; a◌֮◌̀◌⃰◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING ASTERISK ABOVE, LATIN SMALL LETTER B
+0061 20F0 0315 0300 05AE 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062;0061 05AE 20F0 0300 0315 0062; # (a◌⃰◌̕◌̀◌֮b; a◌֮◌⃰◌̀◌̕b; a◌֮◌⃰◌̀◌̕b; a◌֮◌⃰◌̀◌̕b; a◌֮◌⃰◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING ASTERISK ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2CEF 0062;00E0 05AE 2CEF 0315 0062;0061 05AE 0300 2CEF 0315 0062;00E0 05AE 2CEF 0315 0062;0061 05AE 0300 2CEF 0315 0062; # (a◌̕◌̀◌֮◌⳯b; à◌֮◌⳯◌̕b; a◌֮◌̀◌⳯◌̕b; à◌֮◌⳯◌̕b; a◌֮◌̀◌⳯◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COPTIC COMBINING NI ABOVE, LATIN SMALL LETTER B
+0061 2CEF 0315 0300 05AE 0062;0061 05AE 2CEF 0300 0315 0062;0061 05AE 2CEF 0300 0315 0062;0061 05AE 2CEF 0300 0315 0062;0061 05AE 2CEF 0300 0315 0062; # (a◌⳯◌̕◌̀◌֮b; a◌֮◌⳯◌̀◌̕b; a◌֮◌⳯◌̀◌̕b; a◌֮◌⳯◌̀◌̕b; a◌֮◌⳯◌̀◌̕b; ) LATIN SMALL LETTER A, COPTIC COMBINING NI ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2CF0 0062;00E0 05AE 2CF0 0315 0062;0061 05AE 0300 2CF0 0315 0062;00E0 05AE 2CF0 0315 0062;0061 05AE 0300 2CF0 0315 0062; # (a◌̕◌̀◌֮◌⳰b; à◌֮◌⳰◌̕b; a◌֮◌̀◌⳰◌̕b; à◌֮◌⳰◌̕b; a◌֮◌̀◌⳰◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COPTIC COMBINING SPIRITUS ASPER, LATIN SMALL LETTER B
+0061 2CF0 0315 0300 05AE 0062;0061 05AE 2CF0 0300 0315 0062;0061 05AE 2CF0 0300 0315 0062;0061 05AE 2CF0 0300 0315 0062;0061 05AE 2CF0 0300 0315 0062; # (a◌⳰◌̕◌̀◌֮b; a◌֮◌⳰◌̀◌̕b; a◌֮◌⳰◌̀◌̕b; a◌֮◌⳰◌̀◌̕b; a◌֮◌⳰◌̀◌̕b; ) LATIN SMALL LETTER A, COPTIC COMBINING SPIRITUS ASPER, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2CF1 0062;00E0 05AE 2CF1 0315 0062;0061 05AE 0300 2CF1 0315 0062;00E0 05AE 2CF1 0315 0062;0061 05AE 0300 2CF1 0315 0062; # (a◌̕◌̀◌֮◌⳱b; à◌֮◌⳱◌̕b; a◌֮◌̀◌⳱◌̕b; à◌֮◌⳱◌̕b; a◌֮◌̀◌⳱◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COPTIC COMBINING SPIRITUS LENIS, LATIN SMALL LETTER B
+0061 2CF1 0315 0300 05AE 0062;0061 05AE 2CF1 0300 0315 0062;0061 05AE 2CF1 0300 0315 0062;0061 05AE 2CF1 0300 0315 0062;0061 05AE 2CF1 0300 0315 0062; # (a◌⳱◌̕◌̀◌֮b; a◌֮◌⳱◌̀◌̕b; a◌֮◌⳱◌̀◌̕b; a◌֮◌⳱◌̀◌̕b; a◌֮◌⳱◌̀◌̕b; ) LATIN SMALL LETTER A, COPTIC COMBINING SPIRITUS LENIS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 05B0 094D 3099 2D7F 0062;0061 3099 094D 2D7F 05B0 0062;0061 3099 094D 2D7F 05B0 0062;0061 3099 094D 2D7F 05B0 0062;0061 3099 094D 2D7F 05B0 0062; # (a◌ְ◌्◌゙◌⵿b; a◌゙◌्◌⵿◌ְb; a◌゙◌्◌⵿◌ְb; a◌゙◌्◌⵿◌ְb; a◌゙◌्◌⵿◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, TIFINAGH CONSONANT JOINER, LATIN SMALL LETTER B
+0061 2D7F 05B0 094D 3099 0062;0061 3099 2D7F 094D 05B0 0062;0061 3099 2D7F 094D 05B0 0062;0061 3099 2D7F 094D 05B0 0062;0061 3099 2D7F 094D 05B0 0062; # (a◌⵿◌ְ◌्◌゙b; a◌゙◌⵿◌्◌ְb; a◌゙◌⵿◌्◌ְb; a◌゙◌⵿◌्◌ְb; a◌゙◌⵿◌्◌ְb; ) LATIN SMALL LETTER A, TIFINAGH CONSONANT JOINER, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DE0 0062;00E0 05AE 2DE0 0315 0062;0061 05AE 0300 2DE0 0315 0062;00E0 05AE 2DE0 0315 0062;0061 05AE 0300 2DE0 0315 0062; # (a◌̕◌̀◌֮◌ⷠb; à◌֮◌ⷠ◌̕b; a◌֮◌̀◌ⷠ◌̕b; à◌֮◌ⷠ◌̕b; a◌֮◌̀◌ⷠ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER BE, LATIN SMALL LETTER B
+0061 2DE0 0315 0300 05AE 0062;0061 05AE 2DE0 0300 0315 0062;0061 05AE 2DE0 0300 0315 0062;0061 05AE 2DE0 0300 0315 0062;0061 05AE 2DE0 0300 0315 0062; # (a◌ⷠ◌̕◌̀◌֮b; a◌֮◌ⷠ◌̀◌̕b; a◌֮◌ⷠ◌̀◌̕b; a◌֮◌ⷠ◌̀◌̕b; a◌֮◌ⷠ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER BE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DE1 0062;00E0 05AE 2DE1 0315 0062;0061 05AE 0300 2DE1 0315 0062;00E0 05AE 2DE1 0315 0062;0061 05AE 0300 2DE1 0315 0062; # (a◌̕◌̀◌֮◌ⷡb; à◌֮◌ⷡ◌̕b; a◌֮◌̀◌ⷡ◌̕b; à◌֮◌ⷡ◌̕b; a◌֮◌̀◌ⷡ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER VE, LATIN SMALL LETTER B
+0061 2DE1 0315 0300 05AE 0062;0061 05AE 2DE1 0300 0315 0062;0061 05AE 2DE1 0300 0315 0062;0061 05AE 2DE1 0300 0315 0062;0061 05AE 2DE1 0300 0315 0062; # (a◌ⷡ◌̕◌̀◌֮b; a◌֮◌ⷡ◌̀◌̕b; a◌֮◌ⷡ◌̀◌̕b; a◌֮◌ⷡ◌̀◌̕b; a◌֮◌ⷡ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER VE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DE2 0062;00E0 05AE 2DE2 0315 0062;0061 05AE 0300 2DE2 0315 0062;00E0 05AE 2DE2 0315 0062;0061 05AE 0300 2DE2 0315 0062; # (a◌̕◌̀◌֮◌ⷢb; à◌֮◌ⷢ◌̕b; a◌֮◌̀◌ⷢ◌̕b; à◌֮◌ⷢ◌̕b; a◌֮◌̀◌ⷢ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER GHE, LATIN SMALL LETTER B
+0061 2DE2 0315 0300 05AE 0062;0061 05AE 2DE2 0300 0315 0062;0061 05AE 2DE2 0300 0315 0062;0061 05AE 2DE2 0300 0315 0062;0061 05AE 2DE2 0300 0315 0062; # (a◌ⷢ◌̕◌̀◌֮b; a◌֮◌ⷢ◌̀◌̕b; a◌֮◌ⷢ◌̀◌̕b; a◌֮◌ⷢ◌̀◌̕b; a◌֮◌ⷢ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER GHE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DE3 0062;00E0 05AE 2DE3 0315 0062;0061 05AE 0300 2DE3 0315 0062;00E0 05AE 2DE3 0315 0062;0061 05AE 0300 2DE3 0315 0062; # (a◌̕◌̀◌֮◌ⷣb; à◌֮◌ⷣ◌̕b; a◌֮◌̀◌ⷣ◌̕b; à◌֮◌ⷣ◌̕b; a◌֮◌̀◌ⷣ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER DE, LATIN SMALL LETTER B
+0061 2DE3 0315 0300 05AE 0062;0061 05AE 2DE3 0300 0315 0062;0061 05AE 2DE3 0300 0315 0062;0061 05AE 2DE3 0300 0315 0062;0061 05AE 2DE3 0300 0315 0062; # (a◌ⷣ◌̕◌̀◌֮b; a◌֮◌ⷣ◌̀◌̕b; a◌֮◌ⷣ◌̀◌̕b; a◌֮◌ⷣ◌̀◌̕b; a◌֮◌ⷣ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER DE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DE4 0062;00E0 05AE 2DE4 0315 0062;0061 05AE 0300 2DE4 0315 0062;00E0 05AE 2DE4 0315 0062;0061 05AE 0300 2DE4 0315 0062; # (a◌̕◌̀◌֮◌ⷤb; à◌֮◌ⷤ◌̕b; a◌֮◌̀◌ⷤ◌̕b; à◌֮◌ⷤ◌̕b; a◌֮◌̀◌ⷤ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER ZHE, LATIN SMALL LETTER B
+0061 2DE4 0315 0300 05AE 0062;0061 05AE 2DE4 0300 0315 0062;0061 05AE 2DE4 0300 0315 0062;0061 05AE 2DE4 0300 0315 0062;0061 05AE 2DE4 0300 0315 0062; # (a◌ⷤ◌̕◌̀◌֮b; a◌֮◌ⷤ◌̀◌̕b; a◌֮◌ⷤ◌̀◌̕b; a◌֮◌ⷤ◌̀◌̕b; a◌֮◌ⷤ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER ZHE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DE5 0062;00E0 05AE 2DE5 0315 0062;0061 05AE 0300 2DE5 0315 0062;00E0 05AE 2DE5 0315 0062;0061 05AE 0300 2DE5 0315 0062; # (a◌̕◌̀◌֮◌ⷥb; à◌֮◌ⷥ◌̕b; a◌֮◌̀◌ⷥ◌̕b; à◌֮◌ⷥ◌̕b; a◌֮◌̀◌ⷥ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER ZE, LATIN SMALL LETTER B
+0061 2DE5 0315 0300 05AE 0062;0061 05AE 2DE5 0300 0315 0062;0061 05AE 2DE5 0300 0315 0062;0061 05AE 2DE5 0300 0315 0062;0061 05AE 2DE5 0300 0315 0062; # (a◌ⷥ◌̕◌̀◌֮b; a◌֮◌ⷥ◌̀◌̕b; a◌֮◌ⷥ◌̀◌̕b; a◌֮◌ⷥ◌̀◌̕b; a◌֮◌ⷥ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER ZE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DE6 0062;00E0 05AE 2DE6 0315 0062;0061 05AE 0300 2DE6 0315 0062;00E0 05AE 2DE6 0315 0062;0061 05AE 0300 2DE6 0315 0062; # (a◌̕◌̀◌֮◌ⷦb; à◌֮◌ⷦ◌̕b; a◌֮◌̀◌ⷦ◌̕b; à◌֮◌ⷦ◌̕b; a◌֮◌̀◌ⷦ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER KA, LATIN SMALL LETTER B
+0061 2DE6 0315 0300 05AE 0062;0061 05AE 2DE6 0300 0315 0062;0061 05AE 2DE6 0300 0315 0062;0061 05AE 2DE6 0300 0315 0062;0061 05AE 2DE6 0300 0315 0062; # (a◌ⷦ◌̕◌̀◌֮b; a◌֮◌ⷦ◌̀◌̕b; a◌֮◌ⷦ◌̀◌̕b; a◌֮◌ⷦ◌̀◌̕b; a◌֮◌ⷦ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER KA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DE7 0062;00E0 05AE 2DE7 0315 0062;0061 05AE 0300 2DE7 0315 0062;00E0 05AE 2DE7 0315 0062;0061 05AE 0300 2DE7 0315 0062; # (a◌̕◌̀◌֮◌ⷧb; à◌֮◌ⷧ◌̕b; a◌֮◌̀◌ⷧ◌̕b; à◌֮◌ⷧ◌̕b; a◌֮◌̀◌ⷧ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER EL, LATIN SMALL LETTER B
+0061 2DE7 0315 0300 05AE 0062;0061 05AE 2DE7 0300 0315 0062;0061 05AE 2DE7 0300 0315 0062;0061 05AE 2DE7 0300 0315 0062;0061 05AE 2DE7 0300 0315 0062; # (a◌ⷧ◌̕◌̀◌֮b; a◌֮◌ⷧ◌̀◌̕b; a◌֮◌ⷧ◌̀◌̕b; a◌֮◌ⷧ◌̀◌̕b; a◌֮◌ⷧ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER EL, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DE8 0062;00E0 05AE 2DE8 0315 0062;0061 05AE 0300 2DE8 0315 0062;00E0 05AE 2DE8 0315 0062;0061 05AE 0300 2DE8 0315 0062; # (a◌̕◌̀◌֮◌ⷨb; à◌֮◌ⷨ◌̕b; a◌֮◌̀◌ⷨ◌̕b; à◌֮◌ⷨ◌̕b; a◌֮◌̀◌ⷨ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER EM, LATIN SMALL LETTER B
+0061 2DE8 0315 0300 05AE 0062;0061 05AE 2DE8 0300 0315 0062;0061 05AE 2DE8 0300 0315 0062;0061 05AE 2DE8 0300 0315 0062;0061 05AE 2DE8 0300 0315 0062; # (a◌ⷨ◌̕◌̀◌֮b; a◌֮◌ⷨ◌̀◌̕b; a◌֮◌ⷨ◌̀◌̕b; a◌֮◌ⷨ◌̀◌̕b; a◌֮◌ⷨ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER EM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DE9 0062;00E0 05AE 2DE9 0315 0062;0061 05AE 0300 2DE9 0315 0062;00E0 05AE 2DE9 0315 0062;0061 05AE 0300 2DE9 0315 0062; # (a◌̕◌̀◌֮◌ⷩb; à◌֮◌ⷩ◌̕b; a◌֮◌̀◌ⷩ◌̕b; à◌֮◌ⷩ◌̕b; a◌֮◌̀◌ⷩ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER EN, LATIN SMALL LETTER B
+0061 2DE9 0315 0300 05AE 0062;0061 05AE 2DE9 0300 0315 0062;0061 05AE 2DE9 0300 0315 0062;0061 05AE 2DE9 0300 0315 0062;0061 05AE 2DE9 0300 0315 0062; # (a◌ⷩ◌̕◌̀◌֮b; a◌֮◌ⷩ◌̀◌̕b; a◌֮◌ⷩ◌̀◌̕b; a◌֮◌ⷩ◌̀◌̕b; a◌֮◌ⷩ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER EN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DEA 0062;00E0 05AE 2DEA 0315 0062;0061 05AE 0300 2DEA 0315 0062;00E0 05AE 2DEA 0315 0062;0061 05AE 0300 2DEA 0315 0062; # (a◌̕◌̀◌֮◌ⷪb; à◌֮◌ⷪ◌̕b; a◌֮◌̀◌ⷪ◌̕b; à◌֮◌ⷪ◌̕b; a◌֮◌̀◌ⷪ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER O, LATIN SMALL LETTER B
+0061 2DEA 0315 0300 05AE 0062;0061 05AE 2DEA 0300 0315 0062;0061 05AE 2DEA 0300 0315 0062;0061 05AE 2DEA 0300 0315 0062;0061 05AE 2DEA 0300 0315 0062; # (a◌ⷪ◌̕◌̀◌֮b; a◌֮◌ⷪ◌̀◌̕b; a◌֮◌ⷪ◌̀◌̕b; a◌֮◌ⷪ◌̀◌̕b; a◌֮◌ⷪ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER O, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DEB 0062;00E0 05AE 2DEB 0315 0062;0061 05AE 0300 2DEB 0315 0062;00E0 05AE 2DEB 0315 0062;0061 05AE 0300 2DEB 0315 0062; # (a◌̕◌̀◌֮◌ⷫb; à◌֮◌ⷫ◌̕b; a◌֮◌̀◌ⷫ◌̕b; à◌֮◌ⷫ◌̕b; a◌֮◌̀◌ⷫ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER PE, LATIN SMALL LETTER B
+0061 2DEB 0315 0300 05AE 0062;0061 05AE 2DEB 0300 0315 0062;0061 05AE 2DEB 0300 0315 0062;0061 05AE 2DEB 0300 0315 0062;0061 05AE 2DEB 0300 0315 0062; # (a◌ⷫ◌̕◌̀◌֮b; a◌֮◌ⷫ◌̀◌̕b; a◌֮◌ⷫ◌̀◌̕b; a◌֮◌ⷫ◌̀◌̕b; a◌֮◌ⷫ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER PE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DEC 0062;00E0 05AE 2DEC 0315 0062;0061 05AE 0300 2DEC 0315 0062;00E0 05AE 2DEC 0315 0062;0061 05AE 0300 2DEC 0315 0062; # (a◌̕◌̀◌֮◌ⷬb; à◌֮◌ⷬ◌̕b; a◌֮◌̀◌ⷬ◌̕b; à◌֮◌ⷬ◌̕b; a◌֮◌̀◌ⷬ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER ER, LATIN SMALL LETTER B
+0061 2DEC 0315 0300 05AE 0062;0061 05AE 2DEC 0300 0315 0062;0061 05AE 2DEC 0300 0315 0062;0061 05AE 2DEC 0300 0315 0062;0061 05AE 2DEC 0300 0315 0062; # (a◌ⷬ◌̕◌̀◌֮b; a◌֮◌ⷬ◌̀◌̕b; a◌֮◌ⷬ◌̀◌̕b; a◌֮◌ⷬ◌̀◌̕b; a◌֮◌ⷬ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER ER, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DED 0062;00E0 05AE 2DED 0315 0062;0061 05AE 0300 2DED 0315 0062;00E0 05AE 2DED 0315 0062;0061 05AE 0300 2DED 0315 0062; # (a◌̕◌̀◌֮◌ⷭb; à◌֮◌ⷭ◌̕b; a◌֮◌̀◌ⷭ◌̕b; à◌֮◌ⷭ◌̕b; a◌֮◌̀◌ⷭ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER ES, LATIN SMALL LETTER B
+0061 2DED 0315 0300 05AE 0062;0061 05AE 2DED 0300 0315 0062;0061 05AE 2DED 0300 0315 0062;0061 05AE 2DED 0300 0315 0062;0061 05AE 2DED 0300 0315 0062; # (a◌ⷭ◌̕◌̀◌֮b; a◌֮◌ⷭ◌̀◌̕b; a◌֮◌ⷭ◌̀◌̕b; a◌֮◌ⷭ◌̀◌̕b; a◌֮◌ⷭ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER ES, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DEE 0062;00E0 05AE 2DEE 0315 0062;0061 05AE 0300 2DEE 0315 0062;00E0 05AE 2DEE 0315 0062;0061 05AE 0300 2DEE 0315 0062; # (a◌̕◌̀◌֮◌ⷮb; à◌֮◌ⷮ◌̕b; a◌֮◌̀◌ⷮ◌̕b; à◌֮◌ⷮ◌̕b; a◌֮◌̀◌ⷮ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER TE, LATIN SMALL LETTER B
+0061 2DEE 0315 0300 05AE 0062;0061 05AE 2DEE 0300 0315 0062;0061 05AE 2DEE 0300 0315 0062;0061 05AE 2DEE 0300 0315 0062;0061 05AE 2DEE 0300 0315 0062; # (a◌ⷮ◌̕◌̀◌֮b; a◌֮◌ⷮ◌̀◌̕b; a◌֮◌ⷮ◌̀◌̕b; a◌֮◌ⷮ◌̀◌̕b; a◌֮◌ⷮ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER TE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DEF 0062;00E0 05AE 2DEF 0315 0062;0061 05AE 0300 2DEF 0315 0062;00E0 05AE 2DEF 0315 0062;0061 05AE 0300 2DEF 0315 0062; # (a◌̕◌̀◌֮◌ⷯb; à◌֮◌ⷯ◌̕b; a◌֮◌̀◌ⷯ◌̕b; à◌֮◌ⷯ◌̕b; a◌֮◌̀◌ⷯ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER HA, LATIN SMALL LETTER B
+0061 2DEF 0315 0300 05AE 0062;0061 05AE 2DEF 0300 0315 0062;0061 05AE 2DEF 0300 0315 0062;0061 05AE 2DEF 0300 0315 0062;0061 05AE 2DEF 0300 0315 0062; # (a◌ⷯ◌̕◌̀◌֮b; a◌֮◌ⷯ◌̀◌̕b; a◌֮◌ⷯ◌̀◌̕b; a◌֮◌ⷯ◌̀◌̕b; a◌֮◌ⷯ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER HA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DF0 0062;00E0 05AE 2DF0 0315 0062;0061 05AE 0300 2DF0 0315 0062;00E0 05AE 2DF0 0315 0062;0061 05AE 0300 2DF0 0315 0062; # (a◌̕◌̀◌֮◌ⷰb; à◌֮◌ⷰ◌̕b; a◌֮◌̀◌ⷰ◌̕b; à◌֮◌ⷰ◌̕b; a◌֮◌̀◌ⷰ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER TSE, LATIN SMALL LETTER B
+0061 2DF0 0315 0300 05AE 0062;0061 05AE 2DF0 0300 0315 0062;0061 05AE 2DF0 0300 0315 0062;0061 05AE 2DF0 0300 0315 0062;0061 05AE 2DF0 0300 0315 0062; # (a◌ⷰ◌̕◌̀◌֮b; a◌֮◌ⷰ◌̀◌̕b; a◌֮◌ⷰ◌̀◌̕b; a◌֮◌ⷰ◌̀◌̕b; a◌֮◌ⷰ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER TSE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DF1 0062;00E0 05AE 2DF1 0315 0062;0061 05AE 0300 2DF1 0315 0062;00E0 05AE 2DF1 0315 0062;0061 05AE 0300 2DF1 0315 0062; # (a◌̕◌̀◌֮◌ⷱb; à◌֮◌ⷱ◌̕b; a◌֮◌̀◌ⷱ◌̕b; à◌֮◌ⷱ◌̕b; a◌֮◌̀◌ⷱ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER CHE, LATIN SMALL LETTER B
+0061 2DF1 0315 0300 05AE 0062;0061 05AE 2DF1 0300 0315 0062;0061 05AE 2DF1 0300 0315 0062;0061 05AE 2DF1 0300 0315 0062;0061 05AE 2DF1 0300 0315 0062; # (a◌ⷱ◌̕◌̀◌֮b; a◌֮◌ⷱ◌̀◌̕b; a◌֮◌ⷱ◌̀◌̕b; a◌֮◌ⷱ◌̀◌̕b; a◌֮◌ⷱ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER CHE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DF2 0062;00E0 05AE 2DF2 0315 0062;0061 05AE 0300 2DF2 0315 0062;00E0 05AE 2DF2 0315 0062;0061 05AE 0300 2DF2 0315 0062; # (a◌̕◌̀◌֮◌ⷲb; à◌֮◌ⷲ◌̕b; a◌֮◌̀◌ⷲ◌̕b; à◌֮◌ⷲ◌̕b; a◌֮◌̀◌ⷲ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER SHA, LATIN SMALL LETTER B
+0061 2DF2 0315 0300 05AE 0062;0061 05AE 2DF2 0300 0315 0062;0061 05AE 2DF2 0300 0315 0062;0061 05AE 2DF2 0300 0315 0062;0061 05AE 2DF2 0300 0315 0062; # (a◌ⷲ◌̕◌̀◌֮b; a◌֮◌ⷲ◌̀◌̕b; a◌֮◌ⷲ◌̀◌̕b; a◌֮◌ⷲ◌̀◌̕b; a◌֮◌ⷲ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER SHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DF3 0062;00E0 05AE 2DF3 0315 0062;0061 05AE 0300 2DF3 0315 0062;00E0 05AE 2DF3 0315 0062;0061 05AE 0300 2DF3 0315 0062; # (a◌̕◌̀◌֮◌ⷳb; à◌֮◌ⷳ◌̕b; a◌֮◌̀◌ⷳ◌̕b; à◌֮◌ⷳ◌̕b; a◌֮◌̀◌ⷳ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER SHCHA, LATIN SMALL LETTER B
+0061 2DF3 0315 0300 05AE 0062;0061 05AE 2DF3 0300 0315 0062;0061 05AE 2DF3 0300 0315 0062;0061 05AE 2DF3 0300 0315 0062;0061 05AE 2DF3 0300 0315 0062; # (a◌ⷳ◌̕◌̀◌֮b; a◌֮◌ⷳ◌̀◌̕b; a◌֮◌ⷳ◌̀◌̕b; a◌֮◌ⷳ◌̀◌̕b; a◌֮◌ⷳ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER SHCHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DF4 0062;00E0 05AE 2DF4 0315 0062;0061 05AE 0300 2DF4 0315 0062;00E0 05AE 2DF4 0315 0062;0061 05AE 0300 2DF4 0315 0062; # (a◌̕◌̀◌֮◌ⷴb; à◌֮◌ⷴ◌̕b; a◌֮◌̀◌ⷴ◌̕b; à◌֮◌ⷴ◌̕b; a◌֮◌̀◌ⷴ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER FITA, LATIN SMALL LETTER B
+0061 2DF4 0315 0300 05AE 0062;0061 05AE 2DF4 0300 0315 0062;0061 05AE 2DF4 0300 0315 0062;0061 05AE 2DF4 0300 0315 0062;0061 05AE 2DF4 0300 0315 0062; # (a◌ⷴ◌̕◌̀◌֮b; a◌֮◌ⷴ◌̀◌̕b; a◌֮◌ⷴ◌̀◌̕b; a◌֮◌ⷴ◌̀◌̕b; a◌֮◌ⷴ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER FITA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DF5 0062;00E0 05AE 2DF5 0315 0062;0061 05AE 0300 2DF5 0315 0062;00E0 05AE 2DF5 0315 0062;0061 05AE 0300 2DF5 0315 0062; # (a◌̕◌̀◌֮◌ⷵb; à◌֮◌ⷵ◌̕b; a◌֮◌̀◌ⷵ◌̕b; à◌֮◌ⷵ◌̕b; a◌֮◌̀◌ⷵ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER ES-TE, LATIN SMALL LETTER B
+0061 2DF5 0315 0300 05AE 0062;0061 05AE 2DF5 0300 0315 0062;0061 05AE 2DF5 0300 0315 0062;0061 05AE 2DF5 0300 0315 0062;0061 05AE 2DF5 0300 0315 0062; # (a◌ⷵ◌̕◌̀◌֮b; a◌֮◌ⷵ◌̀◌̕b; a◌֮◌ⷵ◌̀◌̕b; a◌֮◌ⷵ◌̀◌̕b; a◌֮◌ⷵ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER ES-TE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DF6 0062;00E0 05AE 2DF6 0315 0062;0061 05AE 0300 2DF6 0315 0062;00E0 05AE 2DF6 0315 0062;0061 05AE 0300 2DF6 0315 0062; # (a◌̕◌̀◌֮◌ⷶb; à◌֮◌ⷶ◌̕b; a◌֮◌̀◌ⷶ◌̕b; à◌֮◌ⷶ◌̕b; a◌֮◌̀◌ⷶ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER A, LATIN SMALL LETTER B
+0061 2DF6 0315 0300 05AE 0062;0061 05AE 2DF6 0300 0315 0062;0061 05AE 2DF6 0300 0315 0062;0061 05AE 2DF6 0300 0315 0062;0061 05AE 2DF6 0300 0315 0062; # (a◌ⷶ◌̕◌̀◌֮b; a◌֮◌ⷶ◌̀◌̕b; a◌֮◌ⷶ◌̀◌̕b; a◌֮◌ⷶ◌̀◌̕b; a◌֮◌ⷶ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DF7 0062;00E0 05AE 2DF7 0315 0062;0061 05AE 0300 2DF7 0315 0062;00E0 05AE 2DF7 0315 0062;0061 05AE 0300 2DF7 0315 0062; # (a◌̕◌̀◌֮◌ⷷb; à◌֮◌ⷷ◌̕b; a◌֮◌̀◌ⷷ◌̕b; à◌֮◌ⷷ◌̕b; a◌֮◌̀◌ⷷ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER IE, LATIN SMALL LETTER B
+0061 2DF7 0315 0300 05AE 0062;0061 05AE 2DF7 0300 0315 0062;0061 05AE 2DF7 0300 0315 0062;0061 05AE 2DF7 0300 0315 0062;0061 05AE 2DF7 0300 0315 0062; # (a◌ⷷ◌̕◌̀◌֮b; a◌֮◌ⷷ◌̀◌̕b; a◌֮◌ⷷ◌̀◌̕b; a◌֮◌ⷷ◌̀◌̕b; a◌֮◌ⷷ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER IE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DF8 0062;00E0 05AE 2DF8 0315 0062;0061 05AE 0300 2DF8 0315 0062;00E0 05AE 2DF8 0315 0062;0061 05AE 0300 2DF8 0315 0062; # (a◌̕◌̀◌֮◌ⷸb; à◌֮◌ⷸ◌̕b; a◌֮◌̀◌ⷸ◌̕b; à◌֮◌ⷸ◌̕b; a◌֮◌̀◌ⷸ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER DJERV, LATIN SMALL LETTER B
+0061 2DF8 0315 0300 05AE 0062;0061 05AE 2DF8 0300 0315 0062;0061 05AE 2DF8 0300 0315 0062;0061 05AE 2DF8 0300 0315 0062;0061 05AE 2DF8 0300 0315 0062; # (a◌ⷸ◌̕◌̀◌֮b; a◌֮◌ⷸ◌̀◌̕b; a◌֮◌ⷸ◌̀◌̕b; a◌֮◌ⷸ◌̀◌̕b; a◌֮◌ⷸ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER DJERV, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DF9 0062;00E0 05AE 2DF9 0315 0062;0061 05AE 0300 2DF9 0315 0062;00E0 05AE 2DF9 0315 0062;0061 05AE 0300 2DF9 0315 0062; # (a◌̕◌̀◌֮◌ⷹb; à◌֮◌ⷹ◌̕b; a◌֮◌̀◌ⷹ◌̕b; à◌֮◌ⷹ◌̕b; a◌֮◌̀◌ⷹ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER MONOGRAPH UK, LATIN SMALL LETTER B
+0061 2DF9 0315 0300 05AE 0062;0061 05AE 2DF9 0300 0315 0062;0061 05AE 2DF9 0300 0315 0062;0061 05AE 2DF9 0300 0315 0062;0061 05AE 2DF9 0300 0315 0062; # (a◌ⷹ◌̕◌̀◌֮b; a◌֮◌ⷹ◌̀◌̕b; a◌֮◌ⷹ◌̀◌̕b; a◌֮◌ⷹ◌̀◌̕b; a◌֮◌ⷹ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER MONOGRAPH UK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DFA 0062;00E0 05AE 2DFA 0315 0062;0061 05AE 0300 2DFA 0315 0062;00E0 05AE 2DFA 0315 0062;0061 05AE 0300 2DFA 0315 0062; # (a◌̕◌̀◌֮◌ⷺb; à◌֮◌ⷺ◌̕b; a◌֮◌̀◌ⷺ◌̕b; à◌֮◌ⷺ◌̕b; a◌֮◌̀◌ⷺ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER YAT, LATIN SMALL LETTER B
+0061 2DFA 0315 0300 05AE 0062;0061 05AE 2DFA 0300 0315 0062;0061 05AE 2DFA 0300 0315 0062;0061 05AE 2DFA 0300 0315 0062;0061 05AE 2DFA 0300 0315 0062; # (a◌ⷺ◌̕◌̀◌֮b; a◌֮◌ⷺ◌̀◌̕b; a◌֮◌ⷺ◌̀◌̕b; a◌֮◌ⷺ◌̀◌̕b; a◌֮◌ⷺ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER YAT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DFB 0062;00E0 05AE 2DFB 0315 0062;0061 05AE 0300 2DFB 0315 0062;00E0 05AE 2DFB 0315 0062;0061 05AE 0300 2DFB 0315 0062; # (a◌̕◌̀◌֮◌ⷻb; à◌֮◌ⷻ◌̕b; a◌֮◌̀◌ⷻ◌̕b; à◌֮◌ⷻ◌̕b; a◌֮◌̀◌ⷻ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER YU, LATIN SMALL LETTER B
+0061 2DFB 0315 0300 05AE 0062;0061 05AE 2DFB 0300 0315 0062;0061 05AE 2DFB 0300 0315 0062;0061 05AE 2DFB 0300 0315 0062;0061 05AE 2DFB 0300 0315 0062; # (a◌ⷻ◌̕◌̀◌֮b; a◌֮◌ⷻ◌̀◌̕b; a◌֮◌ⷻ◌̀◌̕b; a◌֮◌ⷻ◌̀◌̕b; a◌֮◌ⷻ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER YU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DFC 0062;00E0 05AE 2DFC 0315 0062;0061 05AE 0300 2DFC 0315 0062;00E0 05AE 2DFC 0315 0062;0061 05AE 0300 2DFC 0315 0062; # (a◌̕◌̀◌֮◌ⷼb; à◌֮◌ⷼ◌̕b; a◌֮◌̀◌ⷼ◌̕b; à◌֮◌ⷼ◌̕b; a◌֮◌̀◌ⷼ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER IOTIFIED A, LATIN SMALL LETTER B
+0061 2DFC 0315 0300 05AE 0062;0061 05AE 2DFC 0300 0315 0062;0061 05AE 2DFC 0300 0315 0062;0061 05AE 2DFC 0300 0315 0062;0061 05AE 2DFC 0300 0315 0062; # (a◌ⷼ◌̕◌̀◌֮b; a◌֮◌ⷼ◌̀◌̕b; a◌֮◌ⷼ◌̀◌̕b; a◌֮◌ⷼ◌̀◌̕b; a◌֮◌ⷼ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER IOTIFIED A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DFD 0062;00E0 05AE 2DFD 0315 0062;0061 05AE 0300 2DFD 0315 0062;00E0 05AE 2DFD 0315 0062;0061 05AE 0300 2DFD 0315 0062; # (a◌̕◌̀◌֮◌ⷽb; à◌֮◌ⷽ◌̕b; a◌֮◌̀◌ⷽ◌̕b; à◌֮◌ⷽ◌̕b; a◌֮◌̀◌ⷽ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER LITTLE YUS, LATIN SMALL LETTER B
+0061 2DFD 0315 0300 05AE 0062;0061 05AE 2DFD 0300 0315 0062;0061 05AE 2DFD 0300 0315 0062;0061 05AE 2DFD 0300 0315 0062;0061 05AE 2DFD 0300 0315 0062; # (a◌ⷽ◌̕◌̀◌֮b; a◌֮◌ⷽ◌̀◌̕b; a◌֮◌ⷽ◌̀◌̕b; a◌֮◌ⷽ◌̀◌̕b; a◌֮◌ⷽ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER LITTLE YUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DFE 0062;00E0 05AE 2DFE 0315 0062;0061 05AE 0300 2DFE 0315 0062;00E0 05AE 2DFE 0315 0062;0061 05AE 0300 2DFE 0315 0062; # (a◌̕◌̀◌֮◌ⷾb; à◌֮◌ⷾ◌̕b; a◌֮◌̀◌ⷾ◌̕b; à◌֮◌ⷾ◌̕b; a◌֮◌̀◌ⷾ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER BIG YUS, LATIN SMALL LETTER B
+0061 2DFE 0315 0300 05AE 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062;0061 05AE 2DFE 0300 0315 0062; # (a◌ⷾ◌̕◌̀◌֮b; a◌֮◌ⷾ◌̀◌̕b; a◌֮◌ⷾ◌̀◌̕b; a◌֮◌ⷾ◌̀◌̕b; a◌֮◌ⷾ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER BIG YUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 2DFF 0062;00E0 05AE 2DFF 0315 0062;0061 05AE 0300 2DFF 0315 0062;00E0 05AE 2DFF 0315 0062;0061 05AE 0300 2DFF 0315 0062; # (a◌̕◌̀◌֮◌ⷿb; à◌֮◌ⷿ◌̕b; a◌֮◌̀◌ⷿ◌̕b; à◌֮◌ⷿ◌̕b; a◌֮◌̀◌ⷿ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER IOTIFIED BIG YUS, LATIN SMALL LETTER B
+0061 2DFF 0315 0300 05AE 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062;0061 05AE 2DFF 0300 0315 0062; # (a◌ⷿ◌̕◌̀◌֮b; a◌֮◌ⷿ◌̀◌̕b; a◌֮◌ⷿ◌̀◌̕b; a◌֮◌ⷿ◌̀◌̕b; a◌֮◌ⷿ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER IOTIFIED BIG YUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0316 302A 031B 302A 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062; # (a◌̖◌〪◌̛◌〪b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 302A 0316 302A 031B 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062;0061 031B 302A 302A 0316 0062; # (a◌〪◌̖◌〪◌̛b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; a◌̛◌〪◌〪◌̖b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, LATIN SMALL LETTER B
+0061 0300 05AE 1D16D 302B 0062;00E0 1D16D 05AE 302B 0062;0061 1D16D 05AE 302B 0300 0062;00E0 1D16D 05AE 302B 0062;0061 1D16D 05AE 302B 0300 0062; # (a◌̀◌𝅭֮◌〫b; à𝅭◌֮◌〫b; a𝅭◌֮◌〫◌̀b; à𝅭◌֮◌〫b; a𝅭◌֮◌〫◌̀b; ) LATIN SMALL LETTER A, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, IDEOGRAPHIC RISING TONE MARK, LATIN SMALL LETTER B
+0061 302B 0300 05AE 1D16D 0062;00E0 1D16D 302B 05AE 0062;0061 1D16D 302B 05AE 0300 0062;00E0 1D16D 302B 05AE 0062;0061 1D16D 302B 05AE 0300 0062; # (a◌〫◌̀◌𝅭֮b; à𝅭◌〫◌֮b; a𝅭◌〫◌֮◌̀b; à𝅭◌〫◌֮b; a𝅭◌〫◌֮◌̀b; ) LATIN SMALL LETTER A, IDEOGRAPHIC RISING TONE MARK, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, LATIN SMALL LETTER B
+0061 035C 0315 0300 302C 0062;00E0 0315 302C 035C 0062;0061 0300 0315 302C 035C 0062;00E0 0315 302C 035C 0062;0061 0300 0315 302C 035C 0062; # (a◌͜◌̕◌̀◌〬b; à◌̕◌〬◌͜b; a◌̀◌̕◌〬◌͜b; à◌̕◌〬◌͜b; a◌̀◌̕◌〬◌͜b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, IDEOGRAPHIC DEPARTING TONE MARK, LATIN SMALL LETTER B
+0061 302C 035C 0315 0300 0062;00E0 302C 0315 035C 0062;0061 0300 302C 0315 035C 0062;00E0 302C 0315 035C 0062;0061 0300 302C 0315 035C 0062; # (a◌〬◌͜◌̕◌̀b; à◌〬◌̕◌͜b; a◌̀◌〬◌̕◌͜b; à◌〬◌̕◌͜b; a◌̀◌〬◌̕◌͜b; ) LATIN SMALL LETTER A, IDEOGRAPHIC DEPARTING TONE MARK, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, LATIN SMALL LETTER B
+0061 302E 059A 0316 302D 0062;0061 0316 059A 302D 302E 0062;0061 0316 059A 302D 302E 0062;0061 0316 059A 302D 302E 0062;0061 0316 059A 302D 302E 0062; # (a〮◌֚◌̖◌〭b; a◌̖◌֚◌〭〮b; a◌̖◌֚◌〭〮b; a◌̖◌֚◌〭〮b; a◌̖◌֚◌〭〮b; ) LATIN SMALL LETTER A, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC ENTERING TONE MARK, LATIN SMALL LETTER B
+0061 302D 302E 059A 0316 0062;0061 0316 302D 059A 302E 0062;0061 0316 302D 059A 302E 0062;0061 0316 302D 059A 302E 0062;0061 0316 302D 059A 302E 0062; # (a◌〭〮◌֚◌̖b; a◌̖◌〭◌֚〮b; a◌̖◌〭◌֚〮b; a◌̖◌〭◌֚〮b; a◌̖◌〭◌֚〮b; ) LATIN SMALL LETTER A, IDEOGRAPHIC ENTERING TONE MARK, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, LATIN SMALL LETTER B
+0061 1D16D 302E 059A 302E 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062; # (a〮𝅭◌֚〮b; a◌֚〮〮𝅭b; a◌֚〮〮𝅭b; a◌֚〮〮𝅭b; a◌֚〮〮𝅭b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, HANGUL SINGLE DOT TONE MARK, LATIN SMALL LETTER B
+0061 302E 1D16D 302E 059A 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062;0061 059A 302E 302E 1D16D 0062; # (a〮〮𝅭◌֚b; a◌֚〮〮𝅭b; a◌֚〮〮𝅭b; a◌֚〮〮𝅭b; a◌֚〮〮𝅭b; ) LATIN SMALL LETTER A, HANGUL SINGLE DOT TONE MARK, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, LATIN SMALL LETTER B
+0061 1D16D 302E 059A 302F 0062;0061 059A 302E 302F 1D16D 0062;0061 059A 302E 302F 1D16D 0062;0061 059A 302E 302F 1D16D 0062;0061 059A 302E 302F 1D16D 0062; # (a〮𝅭◌֚〯b; a◌֚〮〯𝅭b; a◌֚〮〯𝅭b; a◌֚〮〯𝅭b; a◌֚〮〯𝅭b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, HANGUL DOUBLE DOT TONE MARK, LATIN SMALL LETTER B
+0061 302F 1D16D 302E 059A 0062;0061 059A 302F 302E 1D16D 0062;0061 059A 302F 302E 1D16D 0062;0061 059A 302F 302E 1D16D 0062;0061 059A 302F 302E 1D16D 0062; # (a〯〮𝅭◌֚b; a◌֚〯〮𝅭b; a◌֚〯〮𝅭b; a◌֚〯〮𝅭b; a◌֚〯〮𝅭b; ) LATIN SMALL LETTER A, HANGUL DOUBLE DOT TONE MARK, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HANGUL SINGLE DOT TONE MARK, HEBREW ACCENT YETIV, LATIN SMALL LETTER B
+0061 094D 3099 093C 3099 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062; # (a◌्◌゙◌़◌゙b; a◌़◌゙◌゙◌्b; a◌़◌゙◌゙◌्b; a◌़◌゙◌゙◌्b; a◌़◌゙◌゙◌्b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 094D 3099 093C 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062;0061 093C 3099 3099 094D 0062; # (a◌゙◌्◌゙◌़b; a◌़◌゙◌゙◌्b; a◌़◌゙◌゙◌्b; a◌़◌゙◌゙◌्b; a◌़◌゙◌゙◌्b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, LATIN SMALL LETTER B
+0061 094D 3099 093C 309A 0062;0061 093C 3099 309A 094D 0062;0061 093C 3099 309A 094D 0062;0061 093C 3099 309A 094D 0062;0061 093C 3099 309A 094D 0062; # (a◌्◌゙◌़◌゚b; a◌़◌゙◌゚◌्b; a◌़◌゙◌゚◌्b; a◌़◌゙◌゚◌्b; a◌़◌゙◌゚◌्b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 309A 094D 3099 093C 0062;0061 093C 309A 3099 094D 0062;0061 093C 309A 3099 094D 0062;0061 093C 309A 3099 094D 0062;0061 093C 309A 3099 094D 0062; # (a◌゚◌्◌゙◌़b; a◌़◌゚◌゙◌्b; a◌़◌゚◌゙◌्b; a◌़◌゚◌゙◌्b; a◌़◌゚◌゙◌्b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, LATIN SMALL LETTER B
+0061 0315 0300 05AE A66F 0062;00E0 05AE A66F 0315 0062;0061 05AE 0300 A66F 0315 0062;00E0 05AE A66F 0315 0062;0061 05AE 0300 A66F 0315 0062; # (a◌̕◌̀◌֮◌꙯b; à◌֮◌꙯◌̕b; a◌֮◌̀◌꙯◌̕b; à◌֮◌꙯◌̕b; a◌֮◌̀◌꙯◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC VZMET, LATIN SMALL LETTER B
+0061 A66F 0315 0300 05AE 0062;0061 05AE A66F 0300 0315 0062;0061 05AE A66F 0300 0315 0062;0061 05AE A66F 0300 0315 0062;0061 05AE A66F 0300 0315 0062; # (a◌꙯◌̕◌̀◌֮b; a◌֮◌꙯◌̀◌̕b; a◌֮◌꙯◌̀◌̕b; a◌֮◌꙯◌̀◌̕b; a◌֮◌꙯◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC VZMET, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A674 0062;00E0 05AE A674 0315 0062;0061 05AE 0300 A674 0315 0062;00E0 05AE A674 0315 0062;0061 05AE 0300 A674 0315 0062; # (a◌̕◌̀◌֮◌ꙴb; à◌֮◌ꙴ◌̕b; a◌֮◌̀◌ꙴ◌̕b; à◌֮◌ꙴ◌̕b; a◌֮◌̀◌ꙴ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER UKRAINIAN IE, LATIN SMALL LETTER B
+0061 A674 0315 0300 05AE 0062;0061 05AE A674 0300 0315 0062;0061 05AE A674 0300 0315 0062;0061 05AE A674 0300 0315 0062;0061 05AE A674 0300 0315 0062; # (a◌ꙴ◌̕◌̀◌֮b; a◌֮◌ꙴ◌̀◌̕b; a◌֮◌ꙴ◌̀◌̕b; a◌֮◌ꙴ◌̀◌̕b; a◌֮◌ꙴ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER UKRAINIAN IE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A675 0062;00E0 05AE A675 0315 0062;0061 05AE 0300 A675 0315 0062;00E0 05AE A675 0315 0062;0061 05AE 0300 A675 0315 0062; # (a◌̕◌̀◌֮◌ꙵb; à◌֮◌ꙵ◌̕b; a◌֮◌̀◌ꙵ◌̕b; à◌֮◌ꙵ◌̕b; a◌֮◌̀◌ꙵ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER I, LATIN SMALL LETTER B
+0061 A675 0315 0300 05AE 0062;0061 05AE A675 0300 0315 0062;0061 05AE A675 0300 0315 0062;0061 05AE A675 0300 0315 0062;0061 05AE A675 0300 0315 0062; # (a◌ꙵ◌̕◌̀◌֮b; a◌֮◌ꙵ◌̀◌̕b; a◌֮◌ꙵ◌̀◌̕b; a◌֮◌ꙵ◌̀◌̕b; a◌֮◌ꙵ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER I, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A676 0062;00E0 05AE A676 0315 0062;0061 05AE 0300 A676 0315 0062;00E0 05AE A676 0315 0062;0061 05AE 0300 A676 0315 0062; # (a◌̕◌̀◌֮◌ꙶb; à◌֮◌ꙶ◌̕b; a◌֮◌̀◌ꙶ◌̕b; à◌֮◌ꙶ◌̕b; a◌֮◌̀◌ꙶ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER YI, LATIN SMALL LETTER B
+0061 A676 0315 0300 05AE 0062;0061 05AE A676 0300 0315 0062;0061 05AE A676 0300 0315 0062;0061 05AE A676 0300 0315 0062;0061 05AE A676 0300 0315 0062; # (a◌ꙶ◌̕◌̀◌֮b; a◌֮◌ꙶ◌̀◌̕b; a◌֮◌ꙶ◌̀◌̕b; a◌֮◌ꙶ◌̀◌̕b; a◌֮◌ꙶ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER YI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A677 0062;00E0 05AE A677 0315 0062;0061 05AE 0300 A677 0315 0062;00E0 05AE A677 0315 0062;0061 05AE 0300 A677 0315 0062; # (a◌̕◌̀◌֮◌ꙷb; à◌֮◌ꙷ◌̕b; a◌֮◌̀◌ꙷ◌̕b; à◌֮◌ꙷ◌̕b; a◌֮◌̀◌ꙷ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER U, LATIN SMALL LETTER B
+0061 A677 0315 0300 05AE 0062;0061 05AE A677 0300 0315 0062;0061 05AE A677 0300 0315 0062;0061 05AE A677 0300 0315 0062;0061 05AE A677 0300 0315 0062; # (a◌ꙷ◌̕◌̀◌֮b; a◌֮◌ꙷ◌̀◌̕b; a◌֮◌ꙷ◌̀◌̕b; a◌֮◌ꙷ◌̀◌̕b; a◌֮◌ꙷ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER U, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A678 0062;00E0 05AE A678 0315 0062;0061 05AE 0300 A678 0315 0062;00E0 05AE A678 0315 0062;0061 05AE 0300 A678 0315 0062; # (a◌̕◌̀◌֮◌ꙸb; à◌֮◌ꙸ◌̕b; a◌֮◌̀◌ꙸ◌̕b; à◌֮◌ꙸ◌̕b; a◌֮◌̀◌ꙸ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER HARD SIGN, LATIN SMALL LETTER B
+0061 A678 0315 0300 05AE 0062;0061 05AE A678 0300 0315 0062;0061 05AE A678 0300 0315 0062;0061 05AE A678 0300 0315 0062;0061 05AE A678 0300 0315 0062; # (a◌ꙸ◌̕◌̀◌֮b; a◌֮◌ꙸ◌̀◌̕b; a◌֮◌ꙸ◌̀◌̕b; a◌֮◌ꙸ◌̀◌̕b; a◌֮◌ꙸ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER HARD SIGN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A679 0062;00E0 05AE A679 0315 0062;0061 05AE 0300 A679 0315 0062;00E0 05AE A679 0315 0062;0061 05AE 0300 A679 0315 0062; # (a◌̕◌̀◌֮◌ꙹb; à◌֮◌ꙹ◌̕b; a◌֮◌̀◌ꙹ◌̕b; à◌֮◌ꙹ◌̕b; a◌֮◌̀◌ꙹ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER YERU, LATIN SMALL LETTER B
+0061 A679 0315 0300 05AE 0062;0061 05AE A679 0300 0315 0062;0061 05AE A679 0300 0315 0062;0061 05AE A679 0300 0315 0062;0061 05AE A679 0300 0315 0062; # (a◌ꙹ◌̕◌̀◌֮b; a◌֮◌ꙹ◌̀◌̕b; a◌֮◌ꙹ◌̀◌̕b; a◌֮◌ꙹ◌̀◌̕b; a◌֮◌ꙹ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER YERU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A67A 0062;00E0 05AE A67A 0315 0062;0061 05AE 0300 A67A 0315 0062;00E0 05AE A67A 0315 0062;0061 05AE 0300 A67A 0315 0062; # (a◌̕◌̀◌֮◌ꙺb; à◌֮◌ꙺ◌̕b; a◌֮◌̀◌ꙺ◌̕b; à◌֮◌ꙺ◌̕b; a◌֮◌̀◌ꙺ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER SOFT SIGN, LATIN SMALL LETTER B
+0061 A67A 0315 0300 05AE 0062;0061 05AE A67A 0300 0315 0062;0061 05AE A67A 0300 0315 0062;0061 05AE A67A 0300 0315 0062;0061 05AE A67A 0300 0315 0062; # (a◌ꙺ◌̕◌̀◌֮b; a◌֮◌ꙺ◌̀◌̕b; a◌֮◌ꙺ◌̀◌̕b; a◌֮◌ꙺ◌̀◌̕b; a◌֮◌ꙺ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER SOFT SIGN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A67B 0062;00E0 05AE A67B 0315 0062;0061 05AE 0300 A67B 0315 0062;00E0 05AE A67B 0315 0062;0061 05AE 0300 A67B 0315 0062; # (a◌̕◌̀◌֮◌ꙻb; à◌֮◌ꙻ◌̕b; a◌֮◌̀◌ꙻ◌̕b; à◌֮◌ꙻ◌̕b; a◌֮◌̀◌ꙻ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER OMEGA, LATIN SMALL LETTER B
+0061 A67B 0315 0300 05AE 0062;0061 05AE A67B 0300 0315 0062;0061 05AE A67B 0300 0315 0062;0061 05AE A67B 0300 0315 0062;0061 05AE A67B 0300 0315 0062; # (a◌ꙻ◌̕◌̀◌֮b; a◌֮◌ꙻ◌̀◌̕b; a◌֮◌ꙻ◌̀◌̕b; a◌֮◌ꙻ◌̀◌̕b; a◌֮◌ꙻ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER OMEGA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A67C 0062;00E0 05AE A67C 0315 0062;0061 05AE 0300 A67C 0315 0062;00E0 05AE A67C 0315 0062;0061 05AE 0300 A67C 0315 0062; # (a◌̕◌̀◌֮◌꙼b; à◌֮◌꙼◌̕b; a◌֮◌̀◌꙼◌̕b; à◌֮◌꙼◌̕b; a◌֮◌̀◌꙼◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC KAVYKA, LATIN SMALL LETTER B
+0061 A67C 0315 0300 05AE 0062;0061 05AE A67C 0300 0315 0062;0061 05AE A67C 0300 0315 0062;0061 05AE A67C 0300 0315 0062;0061 05AE A67C 0300 0315 0062; # (a◌꙼◌̕◌̀◌֮b; a◌֮◌꙼◌̀◌̕b; a◌֮◌꙼◌̀◌̕b; a◌֮◌꙼◌̀◌̕b; a◌֮◌꙼◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC KAVYKA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A67D 0062;00E0 05AE A67D 0315 0062;0061 05AE 0300 A67D 0315 0062;00E0 05AE A67D 0315 0062;0061 05AE 0300 A67D 0315 0062; # (a◌̕◌̀◌֮◌꙽b; à◌֮◌꙽◌̕b; a◌֮◌̀◌꙽◌̕b; à◌֮◌꙽◌̕b; a◌֮◌̀◌꙽◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC PAYEROK, LATIN SMALL LETTER B
+0061 A67D 0315 0300 05AE 0062;0061 05AE A67D 0300 0315 0062;0061 05AE A67D 0300 0315 0062;0061 05AE A67D 0300 0315 0062;0061 05AE A67D 0300 0315 0062; # (a◌꙽◌̕◌̀◌֮b; a◌֮◌꙽◌̀◌̕b; a◌֮◌꙽◌̀◌̕b; a◌֮◌꙽◌̀◌̕b; a◌֮◌꙽◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC PAYEROK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A69E 0062;00E0 05AE A69E 0315 0062;0061 05AE 0300 A69E 0315 0062;00E0 05AE A69E 0315 0062;0061 05AE 0300 A69E 0315 0062; # (a◌̕◌̀◌֮◌ꚞb; à◌֮◌ꚞ◌̕b; a◌֮◌̀◌ꚞ◌̕b; à◌֮◌ꚞ◌̕b; a◌֮◌̀◌ꚞ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER EF, LATIN SMALL LETTER B
+0061 A69E 0315 0300 05AE 0062;0061 05AE A69E 0300 0315 0062;0061 05AE A69E 0300 0315 0062;0061 05AE A69E 0300 0315 0062;0061 05AE A69E 0300 0315 0062; # (a◌ꚞ◌̕◌̀◌֮b; a◌֮◌ꚞ◌̀◌̕b; a◌֮◌ꚞ◌̀◌̕b; a◌֮◌ꚞ◌̀◌̕b; a◌֮◌ꚞ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER EF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A69F 0062;00E0 05AE A69F 0315 0062;0061 05AE 0300 A69F 0315 0062;00E0 05AE A69F 0315 0062;0061 05AE 0300 A69F 0315 0062; # (a◌̕◌̀◌֮◌ꚟb; à◌֮◌ꚟ◌̕b; a◌֮◌̀◌ꚟ◌̕b; à◌֮◌ꚟ◌̕b; a◌֮◌̀◌ꚟ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC LETTER IOTIFIED E, LATIN SMALL LETTER B
+0061 A69F 0315 0300 05AE 0062;0061 05AE A69F 0300 0315 0062;0061 05AE A69F 0300 0315 0062;0061 05AE A69F 0300 0315 0062;0061 05AE A69F 0300 0315 0062; # (a◌ꚟ◌̕◌̀◌֮b; a◌֮◌ꚟ◌̀◌̕b; a◌֮◌ꚟ◌̀◌̕b; a◌֮◌ꚟ◌̀◌̕b; a◌֮◌ꚟ◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC LETTER IOTIFIED E, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A6F0 0062;00E0 05AE A6F0 0315 0062;0061 05AE 0300 A6F0 0315 0062;00E0 05AE A6F0 0315 0062;0061 05AE 0300 A6F0 0315 0062; # (a◌̕◌̀◌֮◌꛰b; à◌֮◌꛰◌̕b; a◌֮◌̀◌꛰◌̕b; à◌֮◌꛰◌̕b; a◌֮◌̀◌꛰◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BAMUM COMBINING MARK KOQNDON, LATIN SMALL LETTER B
+0061 A6F0 0315 0300 05AE 0062;0061 05AE A6F0 0300 0315 0062;0061 05AE A6F0 0300 0315 0062;0061 05AE A6F0 0300 0315 0062;0061 05AE A6F0 0300 0315 0062; # (a◌꛰◌̕◌̀◌֮b; a◌֮◌꛰◌̀◌̕b; a◌֮◌꛰◌̀◌̕b; a◌֮◌꛰◌̀◌̕b; a◌֮◌꛰◌̀◌̕b; ) LATIN SMALL LETTER A, BAMUM COMBINING MARK KOQNDON, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A6F1 0062;00E0 05AE A6F1 0315 0062;0061 05AE 0300 A6F1 0315 0062;00E0 05AE A6F1 0315 0062;0061 05AE 0300 A6F1 0315 0062; # (a◌̕◌̀◌֮◌꛱b; à◌֮◌꛱◌̕b; a◌֮◌̀◌꛱◌̕b; à◌֮◌꛱◌̕b; a◌֮◌̀◌꛱◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, BAMUM COMBINING MARK TUKWENTIS, LATIN SMALL LETTER B
+0061 A6F1 0315 0300 05AE 0062;0061 05AE A6F1 0300 0315 0062;0061 05AE A6F1 0300 0315 0062;0061 05AE A6F1 0300 0315 0062;0061 05AE A6F1 0300 0315 0062; # (a◌꛱◌̕◌̀◌֮b; a◌֮◌꛱◌̀◌̕b; a◌֮◌꛱◌̀◌̕b; a◌֮◌꛱◌̀◌̕b; a◌֮◌꛱◌̀◌̕b; ) LATIN SMALL LETTER A, BAMUM COMBINING MARK TUKWENTIS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 05B0 094D 3099 A806 0062;0061 3099 094D A806 05B0 0062;0061 3099 094D A806 05B0 0062;0061 3099 094D A806 05B0 0062;0061 3099 094D A806 05B0 0062; # (a◌ְ◌्◌゙◌꠆b; a◌゙◌्◌꠆◌ְb; a◌゙◌्◌꠆◌ְb; a◌゙◌्◌꠆◌ְb; a◌゙◌्◌꠆◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, SYLOTI NAGRI SIGN HASANTA, LATIN SMALL LETTER B
+0061 A806 05B0 094D 3099 0062;0061 3099 A806 094D 05B0 0062;0061 3099 A806 094D 05B0 0062;0061 3099 A806 094D 05B0 0062;0061 3099 A806 094D 05B0 0062; # (a◌꠆◌ְ◌्◌゙b; a◌゙◌꠆◌्◌ְb; a◌゙◌꠆◌्◌ְb; a◌゙◌꠆◌्◌ְb; a◌゙◌꠆◌्◌ְb; ) LATIN SMALL LETTER A, SYLOTI NAGRI SIGN HASANTA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 A8C4 0062;0061 3099 094D A8C4 05B0 0062;0061 3099 094D A8C4 05B0 0062;0061 3099 094D A8C4 05B0 0062;0061 3099 094D A8C4 05B0 0062; # (a◌ְ◌्◌゙◌꣄b; a◌゙◌्◌꣄◌ְb; a◌゙◌्◌꣄◌ְb; a◌゙◌्◌꣄◌ְb; a◌゙◌्◌꣄◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, SAURASHTRA SIGN VIRAMA, LATIN SMALL LETTER B
+0061 A8C4 05B0 094D 3099 0062;0061 3099 A8C4 094D 05B0 0062;0061 3099 A8C4 094D 05B0 0062;0061 3099 A8C4 094D 05B0 0062;0061 3099 A8C4 094D 05B0 0062; # (a◌꣄◌ְ◌्◌゙b; a◌゙◌꣄◌्◌ְb; a◌゙◌꣄◌्◌ְb; a◌゙◌꣄◌्◌ְb; a◌゙◌꣄◌्◌ְb; ) LATIN SMALL LETTER A, SAURASHTRA SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8E0 0062;00E0 05AE A8E0 0315 0062;0061 05AE 0300 A8E0 0315 0062;00E0 05AE A8E0 0315 0062;0061 05AE 0300 A8E0 0315 0062; # (a◌̕◌̀◌֮◌꣠b; à◌֮◌꣠◌̕b; a◌֮◌̀◌꣠◌̕b; à◌֮◌꣠◌̕b; a◌֮◌̀◌꣠◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI DIGIT ZERO, LATIN SMALL LETTER B
+0061 A8E0 0315 0300 05AE 0062;0061 05AE A8E0 0300 0315 0062;0061 05AE A8E0 0300 0315 0062;0061 05AE A8E0 0300 0315 0062;0061 05AE A8E0 0300 0315 0062; # (a◌꣠◌̕◌̀◌֮b; a◌֮◌꣠◌̀◌̕b; a◌֮◌꣠◌̀◌̕b; a◌֮◌꣠◌̀◌̕b; a◌֮◌꣠◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI DIGIT ZERO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8E1 0062;00E0 05AE A8E1 0315 0062;0061 05AE 0300 A8E1 0315 0062;00E0 05AE A8E1 0315 0062;0061 05AE 0300 A8E1 0315 0062; # (a◌̕◌̀◌֮◌꣡b; à◌֮◌꣡◌̕b; a◌֮◌̀◌꣡◌̕b; à◌֮◌꣡◌̕b; a◌֮◌̀◌꣡◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI DIGIT ONE, LATIN SMALL LETTER B
+0061 A8E1 0315 0300 05AE 0062;0061 05AE A8E1 0300 0315 0062;0061 05AE A8E1 0300 0315 0062;0061 05AE A8E1 0300 0315 0062;0061 05AE A8E1 0300 0315 0062; # (a◌꣡◌̕◌̀◌֮b; a◌֮◌꣡◌̀◌̕b; a◌֮◌꣡◌̀◌̕b; a◌֮◌꣡◌̀◌̕b; a◌֮◌꣡◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI DIGIT ONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8E2 0062;00E0 05AE A8E2 0315 0062;0061 05AE 0300 A8E2 0315 0062;00E0 05AE A8E2 0315 0062;0061 05AE 0300 A8E2 0315 0062; # (a◌̕◌̀◌֮◌꣢b; à◌֮◌꣢◌̕b; a◌֮◌̀◌꣢◌̕b; à◌֮◌꣢◌̕b; a◌֮◌̀◌꣢◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI DIGIT TWO, LATIN SMALL LETTER B
+0061 A8E2 0315 0300 05AE 0062;0061 05AE A8E2 0300 0315 0062;0061 05AE A8E2 0300 0315 0062;0061 05AE A8E2 0300 0315 0062;0061 05AE A8E2 0300 0315 0062; # (a◌꣢◌̕◌̀◌֮b; a◌֮◌꣢◌̀◌̕b; a◌֮◌꣢◌̀◌̕b; a◌֮◌꣢◌̀◌̕b; a◌֮◌꣢◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI DIGIT TWO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8E3 0062;00E0 05AE A8E3 0315 0062;0061 05AE 0300 A8E3 0315 0062;00E0 05AE A8E3 0315 0062;0061 05AE 0300 A8E3 0315 0062; # (a◌̕◌̀◌֮◌꣣b; à◌֮◌꣣◌̕b; a◌֮◌̀◌꣣◌̕b; à◌֮◌꣣◌̕b; a◌֮◌̀◌꣣◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI DIGIT THREE, LATIN SMALL LETTER B
+0061 A8E3 0315 0300 05AE 0062;0061 05AE A8E3 0300 0315 0062;0061 05AE A8E3 0300 0315 0062;0061 05AE A8E3 0300 0315 0062;0061 05AE A8E3 0300 0315 0062; # (a◌꣣◌̕◌̀◌֮b; a◌֮◌꣣◌̀◌̕b; a◌֮◌꣣◌̀◌̕b; a◌֮◌꣣◌̀◌̕b; a◌֮◌꣣◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI DIGIT THREE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8E4 0062;00E0 05AE A8E4 0315 0062;0061 05AE 0300 A8E4 0315 0062;00E0 05AE A8E4 0315 0062;0061 05AE 0300 A8E4 0315 0062; # (a◌̕◌̀◌֮◌꣤b; à◌֮◌꣤◌̕b; a◌֮◌̀◌꣤◌̕b; à◌֮◌꣤◌̕b; a◌֮◌̀◌꣤◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI DIGIT FOUR, LATIN SMALL LETTER B
+0061 A8E4 0315 0300 05AE 0062;0061 05AE A8E4 0300 0315 0062;0061 05AE A8E4 0300 0315 0062;0061 05AE A8E4 0300 0315 0062;0061 05AE A8E4 0300 0315 0062; # (a◌꣤◌̕◌̀◌֮b; a◌֮◌꣤◌̀◌̕b; a◌֮◌꣤◌̀◌̕b; a◌֮◌꣤◌̀◌̕b; a◌֮◌꣤◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI DIGIT FOUR, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8E5 0062;00E0 05AE A8E5 0315 0062;0061 05AE 0300 A8E5 0315 0062;00E0 05AE A8E5 0315 0062;0061 05AE 0300 A8E5 0315 0062; # (a◌̕◌̀◌֮◌꣥b; à◌֮◌꣥◌̕b; a◌֮◌̀◌꣥◌̕b; à◌֮◌꣥◌̕b; a◌֮◌̀◌꣥◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI DIGIT FIVE, LATIN SMALL LETTER B
+0061 A8E5 0315 0300 05AE 0062;0061 05AE A8E5 0300 0315 0062;0061 05AE A8E5 0300 0315 0062;0061 05AE A8E5 0300 0315 0062;0061 05AE A8E5 0300 0315 0062; # (a◌꣥◌̕◌̀◌֮b; a◌֮◌꣥◌̀◌̕b; a◌֮◌꣥◌̀◌̕b; a◌֮◌꣥◌̀◌̕b; a◌֮◌꣥◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI DIGIT FIVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8E6 0062;00E0 05AE A8E6 0315 0062;0061 05AE 0300 A8E6 0315 0062;00E0 05AE A8E6 0315 0062;0061 05AE 0300 A8E6 0315 0062; # (a◌̕◌̀◌֮◌꣦b; à◌֮◌꣦◌̕b; a◌֮◌̀◌꣦◌̕b; à◌֮◌꣦◌̕b; a◌֮◌̀◌꣦◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI DIGIT SIX, LATIN SMALL LETTER B
+0061 A8E6 0315 0300 05AE 0062;0061 05AE A8E6 0300 0315 0062;0061 05AE A8E6 0300 0315 0062;0061 05AE A8E6 0300 0315 0062;0061 05AE A8E6 0300 0315 0062; # (a◌꣦◌̕◌̀◌֮b; a◌֮◌꣦◌̀◌̕b; a◌֮◌꣦◌̀◌̕b; a◌֮◌꣦◌̀◌̕b; a◌֮◌꣦◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI DIGIT SIX, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8E7 0062;00E0 05AE A8E7 0315 0062;0061 05AE 0300 A8E7 0315 0062;00E0 05AE A8E7 0315 0062;0061 05AE 0300 A8E7 0315 0062; # (a◌̕◌̀◌֮◌꣧b; à◌֮◌꣧◌̕b; a◌֮◌̀◌꣧◌̕b; à◌֮◌꣧◌̕b; a◌֮◌̀◌꣧◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI DIGIT SEVEN, LATIN SMALL LETTER B
+0061 A8E7 0315 0300 05AE 0062;0061 05AE A8E7 0300 0315 0062;0061 05AE A8E7 0300 0315 0062;0061 05AE A8E7 0300 0315 0062;0061 05AE A8E7 0300 0315 0062; # (a◌꣧◌̕◌̀◌֮b; a◌֮◌꣧◌̀◌̕b; a◌֮◌꣧◌̀◌̕b; a◌֮◌꣧◌̀◌̕b; a◌֮◌꣧◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI DIGIT SEVEN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8E8 0062;00E0 05AE A8E8 0315 0062;0061 05AE 0300 A8E8 0315 0062;00E0 05AE A8E8 0315 0062;0061 05AE 0300 A8E8 0315 0062; # (a◌̕◌̀◌֮◌꣨b; à◌֮◌꣨◌̕b; a◌֮◌̀◌꣨◌̕b; à◌֮◌꣨◌̕b; a◌֮◌̀◌꣨◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI DIGIT EIGHT, LATIN SMALL LETTER B
+0061 A8E8 0315 0300 05AE 0062;0061 05AE A8E8 0300 0315 0062;0061 05AE A8E8 0300 0315 0062;0061 05AE A8E8 0300 0315 0062;0061 05AE A8E8 0300 0315 0062; # (a◌꣨◌̕◌̀◌֮b; a◌֮◌꣨◌̀◌̕b; a◌֮◌꣨◌̀◌̕b; a◌֮◌꣨◌̀◌̕b; a◌֮◌꣨◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI DIGIT EIGHT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8E9 0062;00E0 05AE A8E9 0315 0062;0061 05AE 0300 A8E9 0315 0062;00E0 05AE A8E9 0315 0062;0061 05AE 0300 A8E9 0315 0062; # (a◌̕◌̀◌֮◌꣩b; à◌֮◌꣩◌̕b; a◌֮◌̀◌꣩◌̕b; à◌֮◌꣩◌̕b; a◌֮◌̀◌꣩◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI DIGIT NINE, LATIN SMALL LETTER B
+0061 A8E9 0315 0300 05AE 0062;0061 05AE A8E9 0300 0315 0062;0061 05AE A8E9 0300 0315 0062;0061 05AE A8E9 0300 0315 0062;0061 05AE A8E9 0300 0315 0062; # (a◌꣩◌̕◌̀◌֮b; a◌֮◌꣩◌̀◌̕b; a◌֮◌꣩◌̀◌̕b; a◌֮◌꣩◌̀◌̕b; a◌֮◌꣩◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI DIGIT NINE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8EA 0062;00E0 05AE A8EA 0315 0062;0061 05AE 0300 A8EA 0315 0062;00E0 05AE A8EA 0315 0062;0061 05AE 0300 A8EA 0315 0062; # (a◌̕◌̀◌֮◌꣪b; à◌֮◌꣪◌̕b; a◌֮◌̀◌꣪◌̕b; à◌֮◌꣪◌̕b; a◌֮◌̀◌꣪◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI LETTER A, LATIN SMALL LETTER B
+0061 A8EA 0315 0300 05AE 0062;0061 05AE A8EA 0300 0315 0062;0061 05AE A8EA 0300 0315 0062;0061 05AE A8EA 0300 0315 0062;0061 05AE A8EA 0300 0315 0062; # (a◌꣪◌̕◌̀◌֮b; a◌֮◌꣪◌̀◌̕b; a◌֮◌꣪◌̀◌̕b; a◌֮◌꣪◌̀◌̕b; a◌֮◌꣪◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8EB 0062;00E0 05AE A8EB 0315 0062;0061 05AE 0300 A8EB 0315 0062;00E0 05AE A8EB 0315 0062;0061 05AE 0300 A8EB 0315 0062; # (a◌̕◌̀◌֮◌꣫b; à◌֮◌꣫◌̕b; a◌֮◌̀◌꣫◌̕b; à◌֮◌꣫◌̕b; a◌֮◌̀◌꣫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI LETTER U, LATIN SMALL LETTER B
+0061 A8EB 0315 0300 05AE 0062;0061 05AE A8EB 0300 0315 0062;0061 05AE A8EB 0300 0315 0062;0061 05AE A8EB 0300 0315 0062;0061 05AE A8EB 0300 0315 0062; # (a◌꣫◌̕◌̀◌֮b; a◌֮◌꣫◌̀◌̕b; a◌֮◌꣫◌̀◌̕b; a◌֮◌꣫◌̀◌̕b; a◌֮◌꣫◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI LETTER U, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8EC 0062;00E0 05AE A8EC 0315 0062;0061 05AE 0300 A8EC 0315 0062;00E0 05AE A8EC 0315 0062;0061 05AE 0300 A8EC 0315 0062; # (a◌̕◌̀◌֮◌꣬b; à◌֮◌꣬◌̕b; a◌֮◌̀◌꣬◌̕b; à◌֮◌꣬◌̕b; a◌֮◌̀◌꣬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI LETTER KA, LATIN SMALL LETTER B
+0061 A8EC 0315 0300 05AE 0062;0061 05AE A8EC 0300 0315 0062;0061 05AE A8EC 0300 0315 0062;0061 05AE A8EC 0300 0315 0062;0061 05AE A8EC 0300 0315 0062; # (a◌꣬◌̕◌̀◌֮b; a◌֮◌꣬◌̀◌̕b; a◌֮◌꣬◌̀◌̕b; a◌֮◌꣬◌̀◌̕b; a◌֮◌꣬◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI LETTER KA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8ED 0062;00E0 05AE A8ED 0315 0062;0061 05AE 0300 A8ED 0315 0062;00E0 05AE A8ED 0315 0062;0061 05AE 0300 A8ED 0315 0062; # (a◌̕◌̀◌֮◌꣭b; à◌֮◌꣭◌̕b; a◌֮◌̀◌꣭◌̕b; à◌֮◌꣭◌̕b; a◌֮◌̀◌꣭◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI LETTER NA, LATIN SMALL LETTER B
+0061 A8ED 0315 0300 05AE 0062;0061 05AE A8ED 0300 0315 0062;0061 05AE A8ED 0300 0315 0062;0061 05AE A8ED 0300 0315 0062;0061 05AE A8ED 0300 0315 0062; # (a◌꣭◌̕◌̀◌֮b; a◌֮◌꣭◌̀◌̕b; a◌֮◌꣭◌̀◌̕b; a◌֮◌꣭◌̀◌̕b; a◌֮◌꣭◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI LETTER NA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8EE 0062;00E0 05AE A8EE 0315 0062;0061 05AE 0300 A8EE 0315 0062;00E0 05AE A8EE 0315 0062;0061 05AE 0300 A8EE 0315 0062; # (a◌̕◌̀◌֮◌꣮b; à◌֮◌꣮◌̕b; a◌֮◌̀◌꣮◌̕b; à◌֮◌꣮◌̕b; a◌֮◌̀◌꣮◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI LETTER PA, LATIN SMALL LETTER B
+0061 A8EE 0315 0300 05AE 0062;0061 05AE A8EE 0300 0315 0062;0061 05AE A8EE 0300 0315 0062;0061 05AE A8EE 0300 0315 0062;0061 05AE A8EE 0300 0315 0062; # (a◌꣮◌̕◌̀◌֮b; a◌֮◌꣮◌̀◌̕b; a◌֮◌꣮◌̀◌̕b; a◌֮◌꣮◌̀◌̕b; a◌֮◌꣮◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI LETTER PA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8EF 0062;00E0 05AE A8EF 0315 0062;0061 05AE 0300 A8EF 0315 0062;00E0 05AE A8EF 0315 0062;0061 05AE 0300 A8EF 0315 0062; # (a◌̕◌̀◌֮◌꣯b; à◌֮◌꣯◌̕b; a◌֮◌̀◌꣯◌̕b; à◌֮◌꣯◌̕b; a◌֮◌̀◌꣯◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI LETTER RA, LATIN SMALL LETTER B
+0061 A8EF 0315 0300 05AE 0062;0061 05AE A8EF 0300 0315 0062;0061 05AE A8EF 0300 0315 0062;0061 05AE A8EF 0300 0315 0062;0061 05AE A8EF 0300 0315 0062; # (a◌꣯◌̕◌̀◌֮b; a◌֮◌꣯◌̀◌̕b; a◌֮◌꣯◌̀◌̕b; a◌֮◌꣯◌̀◌̕b; a◌֮◌꣯◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI LETTER RA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8F0 0062;00E0 05AE A8F0 0315 0062;0061 05AE 0300 A8F0 0315 0062;00E0 05AE A8F0 0315 0062;0061 05AE 0300 A8F0 0315 0062; # (a◌̕◌̀◌֮◌꣰b; à◌֮◌꣰◌̕b; a◌֮◌̀◌꣰◌̕b; à◌֮◌꣰◌̕b; a◌֮◌̀◌꣰◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI LETTER VI, LATIN SMALL LETTER B
+0061 A8F0 0315 0300 05AE 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062;0061 05AE A8F0 0300 0315 0062; # (a◌꣰◌̕◌̀◌֮b; a◌֮◌꣰◌̀◌̕b; a◌֮◌꣰◌̀◌̕b; a◌֮◌꣰◌̀◌̕b; a◌֮◌꣰◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI LETTER VI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE A8F1 0062;00E0 05AE A8F1 0315 0062;0061 05AE 0300 A8F1 0315 0062;00E0 05AE A8F1 0315 0062;0061 05AE 0300 A8F1 0315 0062; # (a◌̕◌̀◌֮◌꣱b; à◌֮◌꣱◌̕b; a◌֮◌̀◌꣱◌̕b; à◌֮◌꣱◌̕b; a◌֮◌̀◌꣱◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DEVANAGARI SIGN AVAGRAHA, LATIN SMALL LETTER B
+0061 A8F1 0315 0300 05AE 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062;0061 05AE A8F1 0300 0315 0062; # (a◌꣱◌̕◌̀◌֮b; a◌֮◌꣱◌̀◌̕b; a◌֮◌꣱◌̀◌̕b; a◌֮◌꣱◌̀◌̕b; a◌֮◌꣱◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DEVANAGARI SIGN AVAGRAHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A A92B 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062;0061 302A 0316 A92B 059A 0062; # (a◌֚◌̖◌〪◌꤫b; a◌〪◌̖◌꤫◌֚b; a◌〪◌̖◌꤫◌֚b; a◌〪◌̖◌꤫◌֚b; a◌〪◌̖◌꤫◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, KAYAH LI TONE PLOPHU, LATIN SMALL LETTER B
+0061 A92B 059A 0316 302A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062;0061 302A A92B 0316 059A 0062; # (a◌꤫◌֚◌̖◌〪b; a◌〪◌꤫◌̖◌֚b; a◌〪◌꤫◌̖◌֚b; a◌〪◌꤫◌̖◌֚b; a◌〪◌꤫◌̖◌֚b; ) LATIN SMALL LETTER A, KAYAH LI TONE PLOPHU, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A A92C 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062;0061 302A 0316 A92C 059A 0062; # (a◌֚◌̖◌〪◌꤬b; a◌〪◌̖◌꤬◌֚b; a◌〪◌̖◌꤬◌֚b; a◌〪◌̖◌꤬◌֚b; a◌〪◌̖◌꤬◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, KAYAH LI TONE CALYA, LATIN SMALL LETTER B
+0061 A92C 059A 0316 302A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062;0061 302A A92C 0316 059A 0062; # (a◌꤬◌֚◌̖◌〪b; a◌〪◌꤬◌̖◌֚b; a◌〪◌꤬◌̖◌֚b; a◌〪◌꤬◌̖◌֚b; a◌〪◌꤬◌̖◌֚b; ) LATIN SMALL LETTER A, KAYAH LI TONE CALYA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A A92D 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062;0061 302A 0316 A92D 059A 0062; # (a◌֚◌̖◌〪◌꤭b; a◌〪◌̖◌꤭◌֚b; a◌〪◌̖◌꤭◌֚b; a◌〪◌̖◌꤭◌֚b; a◌〪◌̖◌꤭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, KAYAH LI TONE CALYA PLOPHU, LATIN SMALL LETTER B
+0061 A92D 059A 0316 302A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062;0061 302A A92D 0316 059A 0062; # (a◌꤭◌֚◌̖◌〪b; a◌〪◌꤭◌̖◌֚b; a◌〪◌꤭◌̖◌֚b; a◌〪◌꤭◌̖◌֚b; a◌〪◌꤭◌̖◌֚b; ) LATIN SMALL LETTER A, KAYAH LI TONE CALYA PLOPHU, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 A953 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 05B0 0062;0061 3099 094D A953 05B0 0062; # (a◌ְ◌्◌゙꥓b; a◌゙◌्꥓◌ְb; a◌゙◌्꥓◌ְb; a◌゙◌्꥓◌ְb; a◌゙◌्꥓◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, REJANG VIRAMA, LATIN SMALL LETTER B
+0061 A953 05B0 094D 3099 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062;0061 3099 A953 094D 05B0 0062; # (a꥓◌ְ◌्◌゙b; a◌゙꥓◌्◌ְb; a◌゙꥓◌्◌ְb; a◌゙꥓◌्◌ְb; a◌゙꥓◌्◌ְb; ) LATIN SMALL LETTER A, REJANG VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 A9B3 0062;0061 0334 093C A9B3 3099 0062;0061 0334 093C A9B3 3099 0062;0061 0334 093C A9B3 3099 0062;0061 0334 093C A9B3 3099 0062; # (a◌゙◌़◌̴◌꦳b; a◌̴◌़◌꦳◌゙b; a◌̴◌़◌꦳◌゙b; a◌̴◌़◌꦳◌゙b; a◌̴◌़◌꦳◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, JAVANESE SIGN CECAK TELU, LATIN SMALL LETTER B
+0061 A9B3 3099 093C 0334 0062;0061 0334 A9B3 093C 3099 0062;0061 0334 A9B3 093C 3099 0062;0061 0334 A9B3 093C 3099 0062;0061 0334 A9B3 093C 3099 0062; # (a◌꦳◌゙◌़◌̴b; a◌̴◌꦳◌़◌゙b; a◌̴◌꦳◌़◌゙b; a◌̴◌꦳◌़◌゙b; a◌̴◌꦳◌़◌゙b; ) LATIN SMALL LETTER A, JAVANESE SIGN CECAK TELU, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 A9C0 0062;0061 3099 094D A9C0 05B0 0062;0061 3099 094D A9C0 05B0 0062;0061 3099 094D A9C0 05B0 0062;0061 3099 094D A9C0 05B0 0062; # (a◌ְ◌्◌゙꧀b; a◌゙◌्꧀◌ְb; a◌゙◌्꧀◌ְb; a◌゙◌्꧀◌ְb; a◌゙◌्꧀◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, JAVANESE PANGKON, LATIN SMALL LETTER B
+0061 A9C0 05B0 094D 3099 0062;0061 3099 A9C0 094D 05B0 0062;0061 3099 A9C0 094D 05B0 0062;0061 3099 A9C0 094D 05B0 0062;0061 3099 A9C0 094D 05B0 0062; # (a꧀◌ְ◌्◌゙b; a◌゙꧀◌्◌ְb; a◌゙꧀◌्◌ְb; a◌゙꧀◌्◌ְb; a◌゙꧀◌्◌ְb; ) LATIN SMALL LETTER A, JAVANESE PANGKON, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE AAB0 0062;00E0 05AE AAB0 0315 0062;0061 05AE 0300 AAB0 0315 0062;00E0 05AE AAB0 0315 0062;0061 05AE 0300 AAB0 0315 0062; # (a◌̕◌̀◌֮◌ꪰb; à◌֮◌ꪰ◌̕b; a◌֮◌̀◌ꪰ◌̕b; à◌֮◌ꪰ◌̕b; a◌֮◌̀◌ꪰ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI VIET MAI KANG, LATIN SMALL LETTER B
+0061 AAB0 0315 0300 05AE 0062;0061 05AE AAB0 0300 0315 0062;0061 05AE AAB0 0300 0315 0062;0061 05AE AAB0 0300 0315 0062;0061 05AE AAB0 0300 0315 0062; # (a◌ꪰ◌̕◌̀◌֮b; a◌֮◌ꪰ◌̀◌̕b; a◌֮◌ꪰ◌̀◌̕b; a◌֮◌ꪰ◌̀◌̕b; a◌֮◌ꪰ◌̀◌̕b; ) LATIN SMALL LETTER A, TAI VIET MAI KANG, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE AAB2 0062;00E0 05AE AAB2 0315 0062;0061 05AE 0300 AAB2 0315 0062;00E0 05AE AAB2 0315 0062;0061 05AE 0300 AAB2 0315 0062; # (a◌̕◌̀◌֮◌ꪲb; à◌֮◌ꪲ◌̕b; a◌֮◌̀◌ꪲ◌̕b; à◌֮◌ꪲ◌̕b; a◌֮◌̀◌ꪲ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI VIET VOWEL I, LATIN SMALL LETTER B
+0061 AAB2 0315 0300 05AE 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062;0061 05AE AAB2 0300 0315 0062; # (a◌ꪲ◌̕◌̀◌֮b; a◌֮◌ꪲ◌̀◌̕b; a◌֮◌ꪲ◌̀◌̕b; a◌֮◌ꪲ◌̀◌̕b; a◌֮◌ꪲ◌̀◌̕b; ) LATIN SMALL LETTER A, TAI VIET VOWEL I, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE AAB3 0062;00E0 05AE AAB3 0315 0062;0061 05AE 0300 AAB3 0315 0062;00E0 05AE AAB3 0315 0062;0061 05AE 0300 AAB3 0315 0062; # (a◌̕◌̀◌֮◌ꪳb; à◌֮◌ꪳ◌̕b; a◌֮◌̀◌ꪳ◌̕b; à◌֮◌ꪳ◌̕b; a◌֮◌̀◌ꪳ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI VIET VOWEL UE, LATIN SMALL LETTER B
+0061 AAB3 0315 0300 05AE 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062;0061 05AE AAB3 0300 0315 0062; # (a◌ꪳ◌̕◌̀◌֮b; a◌֮◌ꪳ◌̀◌̕b; a◌֮◌ꪳ◌̀◌̕b; a◌֮◌ꪳ◌̀◌̕b; a◌֮◌ꪳ◌̀◌̕b; ) LATIN SMALL LETTER A, TAI VIET VOWEL UE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A AAB4 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062;0061 302A 0316 AAB4 059A 0062; # (a◌֚◌̖◌〪◌ꪴb; a◌〪◌̖◌ꪴ◌֚b; a◌〪◌̖◌ꪴ◌֚b; a◌〪◌̖◌ꪴ◌֚b; a◌〪◌̖◌ꪴ◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, TAI VIET VOWEL U, LATIN SMALL LETTER B
+0061 AAB4 059A 0316 302A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062;0061 302A AAB4 0316 059A 0062; # (a◌ꪴ◌֚◌̖◌〪b; a◌〪◌ꪴ◌̖◌֚b; a◌〪◌ꪴ◌̖◌֚b; a◌〪◌ꪴ◌̖◌֚b; a◌〪◌ꪴ◌̖◌֚b; ) LATIN SMALL LETTER A, TAI VIET VOWEL U, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE AAB7 0062;00E0 05AE AAB7 0315 0062;0061 05AE 0300 AAB7 0315 0062;00E0 05AE AAB7 0315 0062;0061 05AE 0300 AAB7 0315 0062; # (a◌̕◌̀◌֮◌ꪷb; à◌֮◌ꪷ◌̕b; a◌֮◌̀◌ꪷ◌̕b; à◌֮◌ꪷ◌̕b; a◌֮◌̀◌ꪷ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI VIET MAI KHIT, LATIN SMALL LETTER B
+0061 AAB7 0315 0300 05AE 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062;0061 05AE AAB7 0300 0315 0062; # (a◌ꪷ◌̕◌̀◌֮b; a◌֮◌ꪷ◌̀◌̕b; a◌֮◌ꪷ◌̀◌̕b; a◌֮◌ꪷ◌̀◌̕b; a◌֮◌ꪷ◌̀◌̕b; ) LATIN SMALL LETTER A, TAI VIET MAI KHIT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE AAB8 0062;00E0 05AE AAB8 0315 0062;0061 05AE 0300 AAB8 0315 0062;00E0 05AE AAB8 0315 0062;0061 05AE 0300 AAB8 0315 0062; # (a◌̕◌̀◌֮◌ꪸb; à◌֮◌ꪸ◌̕b; a◌֮◌̀◌ꪸ◌̕b; à◌֮◌ꪸ◌̕b; a◌֮◌̀◌ꪸ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI VIET VOWEL IA, LATIN SMALL LETTER B
+0061 AAB8 0315 0300 05AE 0062;0061 05AE AAB8 0300 0315 0062;0061 05AE AAB8 0300 0315 0062;0061 05AE AAB8 0300 0315 0062;0061 05AE AAB8 0300 0315 0062; # (a◌ꪸ◌̕◌̀◌֮b; a◌֮◌ꪸ◌̀◌̕b; a◌֮◌ꪸ◌̀◌̕b; a◌֮◌ꪸ◌̀◌̕b; a◌֮◌ꪸ◌̀◌̕b; ) LATIN SMALL LETTER A, TAI VIET VOWEL IA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE AABE 0062;00E0 05AE AABE 0315 0062;0061 05AE 0300 AABE 0315 0062;00E0 05AE AABE 0315 0062;0061 05AE 0300 AABE 0315 0062; # (a◌̕◌̀◌֮◌ꪾb; à◌֮◌ꪾ◌̕b; a◌֮◌̀◌ꪾ◌̕b; à◌֮◌ꪾ◌̕b; a◌֮◌̀◌ꪾ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI VIET VOWEL AM, LATIN SMALL LETTER B
+0061 AABE 0315 0300 05AE 0062;0061 05AE AABE 0300 0315 0062;0061 05AE AABE 0300 0315 0062;0061 05AE AABE 0300 0315 0062;0061 05AE AABE 0300 0315 0062; # (a◌ꪾ◌̕◌̀◌֮b; a◌֮◌ꪾ◌̀◌̕b; a◌֮◌ꪾ◌̀◌̕b; a◌֮◌ꪾ◌̀◌̕b; a◌֮◌ꪾ◌̀◌̕b; ) LATIN SMALL LETTER A, TAI VIET VOWEL AM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE AABF 0062;00E0 05AE AABF 0315 0062;0061 05AE 0300 AABF 0315 0062;00E0 05AE AABF 0315 0062;0061 05AE 0300 AABF 0315 0062; # (a◌̕◌̀◌֮◌꪿b; à◌֮◌꪿◌̕b; a◌֮◌̀◌꪿◌̕b; à◌֮◌꪿◌̕b; a◌֮◌̀◌꪿◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI VIET TONE MAI EK, LATIN SMALL LETTER B
+0061 AABF 0315 0300 05AE 0062;0061 05AE AABF 0300 0315 0062;0061 05AE AABF 0300 0315 0062;0061 05AE AABF 0300 0315 0062;0061 05AE AABF 0300 0315 0062; # (a◌꪿◌̕◌̀◌֮b; a◌֮◌꪿◌̀◌̕b; a◌֮◌꪿◌̀◌̕b; a◌֮◌꪿◌̀◌̕b; a◌֮◌꪿◌̀◌̕b; ) LATIN SMALL LETTER A, TAI VIET TONE MAI EK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE AAC1 0062;00E0 05AE AAC1 0315 0062;0061 05AE 0300 AAC1 0315 0062;00E0 05AE AAC1 0315 0062;0061 05AE 0300 AAC1 0315 0062; # (a◌̕◌̀◌֮◌꫁b; à◌֮◌꫁◌̕b; a◌֮◌̀◌꫁◌̕b; à◌֮◌꫁◌̕b; a◌֮◌̀◌꫁◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, TAI VIET TONE MAI THO, LATIN SMALL LETTER B
+0061 AAC1 0315 0300 05AE 0062;0061 05AE AAC1 0300 0315 0062;0061 05AE AAC1 0300 0315 0062;0061 05AE AAC1 0300 0315 0062;0061 05AE AAC1 0300 0315 0062; # (a◌꫁◌̕◌̀◌֮b; a◌֮◌꫁◌̀◌̕b; a◌֮◌꫁◌̀◌̕b; a◌֮◌꫁◌̀◌̕b; a◌֮◌꫁◌̀◌̕b; ) LATIN SMALL LETTER A, TAI VIET TONE MAI THO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 05B0 094D 3099 AAF6 0062;0061 3099 094D AAF6 05B0 0062;0061 3099 094D AAF6 05B0 0062;0061 3099 094D AAF6 05B0 0062;0061 3099 094D AAF6 05B0 0062; # (a◌ְ◌्◌゙◌꫶b; a◌゙◌्◌꫶◌ְb; a◌゙◌्◌꫶◌ְb; a◌゙◌्◌꫶◌ְb; a◌゙◌्◌꫶◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, MEETEI MAYEK VIRAMA, LATIN SMALL LETTER B
+0061 AAF6 05B0 094D 3099 0062;0061 3099 AAF6 094D 05B0 0062;0061 3099 AAF6 094D 05B0 0062;0061 3099 AAF6 094D 05B0 0062;0061 3099 AAF6 094D 05B0 0062; # (a◌꫶◌ְ◌्◌゙b; a◌゙◌꫶◌्◌ְb; a◌゙◌꫶◌्◌ְb; a◌゙◌꫶◌्◌ְb; a◌゙◌꫶◌्◌ְb; ) LATIN SMALL LETTER A, MEETEI MAYEK VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 ABED 0062;0061 3099 094D ABED 05B0 0062;0061 3099 094D ABED 05B0 0062;0061 3099 094D ABED 05B0 0062;0061 3099 094D ABED 05B0 0062; # (a◌ְ◌्◌゙◌꯭b; a◌゙◌्◌꯭◌ְb; a◌゙◌्◌꯭◌ְb; a◌゙◌्◌꯭◌ְb; a◌゙◌्◌꯭◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, MEETEI MAYEK APUN IYEK, LATIN SMALL LETTER B
+0061 ABED 05B0 094D 3099 0062;0061 3099 ABED 094D 05B0 0062;0061 3099 ABED 094D 05B0 0062;0061 3099 ABED 094D 05B0 0062;0061 3099 ABED 094D 05B0 0062; # (a◌꯭◌ְ◌्◌゙b; a◌゙◌꯭◌्◌ְb; a◌゙◌꯭◌्◌ְb; a◌゙◌꯭◌्◌ְb; a◌゙◌꯭◌्◌ְb; ) LATIN SMALL LETTER A, MEETEI MAYEK APUN IYEK, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 064B FB1E 05C2 FB1E 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062; # (a◌ً◌ﬞ◌ׂ◌ﬞb; a◌ׂ◌ﬞ◌ﬞ◌ًb; a◌ׂ◌ﬞ◌ﬞ◌ًb; a◌ׂ◌ﬞ◌ﬞ◌ًb; a◌ׂ◌ﬞ◌ﬞ◌ًb; ) LATIN SMALL LETTER A, ARABIC FATHATAN, HEBREW POINT JUDEO-SPANISH VARIKA, HEBREW POINT SIN DOT, HEBREW POINT JUDEO-SPANISH VARIKA, LATIN SMALL LETTER B
+0061 FB1E 064B FB1E 05C2 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062;0061 05C2 FB1E FB1E 064B 0062; # (a◌ﬞ◌ً◌ﬞ◌ׂb; a◌ׂ◌ﬞ◌ﬞ◌ًb; a◌ׂ◌ﬞ◌ﬞ◌ًb; a◌ׂ◌ﬞ◌ﬞ◌ًb; a◌ׂ◌ﬞ◌ﬞ◌ًb; ) LATIN SMALL LETTER A, HEBREW POINT JUDEO-SPANISH VARIKA, ARABIC FATHATAN, HEBREW POINT JUDEO-SPANISH VARIKA, HEBREW POINT SIN DOT, LATIN SMALL LETTER B
+0061 0315 0300 05AE FE20 0062;00E0 05AE FE20 0315 0062;0061 05AE 0300 FE20 0315 0062;00E0 05AE FE20 0315 0062;0061 05AE 0300 FE20 0315 0062; # (a◌̕◌̀◌֮◌︠b; à◌֮◌︠◌̕b; a◌֮◌̀◌︠◌̕b; à◌֮◌︠◌̕b; a◌֮◌̀◌︠◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LIGATURE LEFT HALF, LATIN SMALL LETTER B
+0061 FE20 0315 0300 05AE 0062;0061 05AE FE20 0300 0315 0062;0061 05AE FE20 0300 0315 0062;0061 05AE FE20 0300 0315 0062;0061 05AE FE20 0300 0315 0062; # (a◌︠◌̕◌̀◌֮b; a◌֮◌︠◌̀◌̕b; a◌֮◌︠◌̀◌̕b; a◌֮◌︠◌̀◌̕b; a◌֮◌︠◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LIGATURE LEFT HALF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE FE21 0062;00E0 05AE FE21 0315 0062;0061 05AE 0300 FE21 0315 0062;00E0 05AE FE21 0315 0062;0061 05AE 0300 FE21 0315 0062; # (a◌̕◌̀◌֮◌︡b; à◌֮◌︡◌̕b; a◌֮◌̀◌︡◌̕b; à◌֮◌︡◌̕b; a◌֮◌̀◌︡◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING LIGATURE RIGHT HALF, LATIN SMALL LETTER B
+0061 FE21 0315 0300 05AE 0062;0061 05AE FE21 0300 0315 0062;0061 05AE FE21 0300 0315 0062;0061 05AE FE21 0300 0315 0062;0061 05AE FE21 0300 0315 0062; # (a◌︡◌̕◌̀◌֮b; a◌֮◌︡◌̀◌̕b; a◌֮◌︡◌̀◌̕b; a◌֮◌︡◌̀◌̕b; a◌֮◌︡◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING LIGATURE RIGHT HALF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE FE22 0062;00E0 05AE FE22 0315 0062;0061 05AE 0300 FE22 0315 0062;00E0 05AE FE22 0315 0062;0061 05AE 0300 FE22 0315 0062; # (a◌̕◌̀◌֮◌︢b; à◌֮◌︢◌̕b; a◌֮◌̀◌︢◌̕b; à◌֮◌︢◌̕b; a◌֮◌̀◌︢◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOUBLE TILDE LEFT HALF, LATIN SMALL LETTER B
+0061 FE22 0315 0300 05AE 0062;0061 05AE FE22 0300 0315 0062;0061 05AE FE22 0300 0315 0062;0061 05AE FE22 0300 0315 0062;0061 05AE FE22 0300 0315 0062; # (a◌︢◌̕◌̀◌֮b; a◌֮◌︢◌̀◌̕b; a◌֮◌︢◌̀◌̕b; a◌֮◌︢◌̀◌̕b; a◌֮◌︢◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOUBLE TILDE LEFT HALF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE FE23 0062;00E0 05AE FE23 0315 0062;0061 05AE 0300 FE23 0315 0062;00E0 05AE FE23 0315 0062;0061 05AE 0300 FE23 0315 0062; # (a◌̕◌̀◌֮◌︣b; à◌֮◌︣◌̕b; a◌֮◌̀◌︣◌̕b; à◌֮◌︣◌̕b; a◌֮◌̀◌︣◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING DOUBLE TILDE RIGHT HALF, LATIN SMALL LETTER B
+0061 FE23 0315 0300 05AE 0062;0061 05AE FE23 0300 0315 0062;0061 05AE FE23 0300 0315 0062;0061 05AE FE23 0300 0315 0062;0061 05AE FE23 0300 0315 0062; # (a◌︣◌̕◌̀◌֮b; a◌֮◌︣◌̀◌̕b; a◌֮◌︣◌̀◌̕b; a◌֮◌︣◌̀◌̕b; a◌֮◌︣◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING DOUBLE TILDE RIGHT HALF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE FE24 0062;00E0 05AE FE24 0315 0062;0061 05AE 0300 FE24 0315 0062;00E0 05AE FE24 0315 0062;0061 05AE 0300 FE24 0315 0062; # (a◌̕◌̀◌֮◌︤b; à◌֮◌︤◌̕b; a◌֮◌̀◌︤◌̕b; à◌֮◌︤◌̕b; a◌֮◌̀◌︤◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING MACRON LEFT HALF, LATIN SMALL LETTER B
+0061 FE24 0315 0300 05AE 0062;0061 05AE FE24 0300 0315 0062;0061 05AE FE24 0300 0315 0062;0061 05AE FE24 0300 0315 0062;0061 05AE FE24 0300 0315 0062; # (a◌︤◌̕◌̀◌֮b; a◌֮◌︤◌̀◌̕b; a◌֮◌︤◌̀◌̕b; a◌֮◌︤◌̀◌̕b; a◌֮◌︤◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING MACRON LEFT HALF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE FE25 0062;00E0 05AE FE25 0315 0062;0061 05AE 0300 FE25 0315 0062;00E0 05AE FE25 0315 0062;0061 05AE 0300 FE25 0315 0062; # (a◌̕◌̀◌֮◌︥b; à◌֮◌︥◌̕b; a◌֮◌̀◌︥◌̕b; à◌֮◌︥◌̕b; a◌֮◌̀◌︥◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING MACRON RIGHT HALF, LATIN SMALL LETTER B
+0061 FE25 0315 0300 05AE 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062;0061 05AE FE25 0300 0315 0062; # (a◌︥◌̕◌̀◌֮b; a◌֮◌︥◌̀◌̕b; a◌֮◌︥◌̀◌̕b; a◌֮◌︥◌̀◌̕b; a◌֮◌︥◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING MACRON RIGHT HALF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE FE26 0062;00E0 05AE FE26 0315 0062;0061 05AE 0300 FE26 0315 0062;00E0 05AE FE26 0315 0062;0061 05AE 0300 FE26 0315 0062; # (a◌̕◌̀◌֮◌︦b; à◌֮◌︦◌̕b; a◌֮◌̀◌︦◌̕b; à◌֮◌︦◌̕b; a◌֮◌̀◌︦◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CONJOINING MACRON, LATIN SMALL LETTER B
+0061 FE26 0315 0300 05AE 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062;0061 05AE FE26 0300 0315 0062; # (a◌︦◌̕◌̀◌֮b; a◌֮◌︦◌̀◌̕b; a◌֮◌︦◌̀◌̕b; a◌֮◌︦◌̀◌̕b; a◌֮◌︦◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CONJOINING MACRON, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A FE27 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062;0061 302A 0316 FE27 059A 0062; # (a◌֚◌̖◌〪◌︧b; a◌〪◌̖◌︧◌֚b; a◌〪◌̖◌︧◌֚b; a◌〪◌̖◌︧◌֚b; a◌〪◌̖◌︧◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LIGATURE LEFT HALF BELOW, LATIN SMALL LETTER B
+0061 FE27 059A 0316 302A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062;0061 302A FE27 0316 059A 0062; # (a◌︧◌֚◌̖◌〪b; a◌〪◌︧◌̖◌֚b; a◌〪◌︧◌̖◌֚b; a◌〪◌︧◌̖◌֚b; a◌〪◌︧◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LIGATURE LEFT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A FE28 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062;0061 302A 0316 FE28 059A 0062; # (a◌֚◌̖◌〪◌︨b; a◌〪◌̖◌︨◌֚b; a◌〪◌̖◌︨◌֚b; a◌〪◌̖◌︨◌֚b; a◌〪◌̖◌︨◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING LIGATURE RIGHT HALF BELOW, LATIN SMALL LETTER B
+0061 FE28 059A 0316 302A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062;0061 302A FE28 0316 059A 0062; # (a◌︨◌֚◌̖◌〪b; a◌〪◌︨◌̖◌֚b; a◌〪◌︨◌̖◌֚b; a◌〪◌︨◌̖◌֚b; a◌〪◌︨◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING LIGATURE RIGHT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A FE29 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062;0061 302A 0316 FE29 059A 0062; # (a◌֚◌̖◌〪◌︩b; a◌〪◌̖◌︩◌֚b; a◌〪◌̖◌︩◌֚b; a◌〪◌̖◌︩◌֚b; a◌〪◌̖◌︩◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING TILDE LEFT HALF BELOW, LATIN SMALL LETTER B
+0061 FE29 059A 0316 302A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062;0061 302A FE29 0316 059A 0062; # (a◌︩◌֚◌̖◌〪b; a◌〪◌︩◌̖◌֚b; a◌〪◌︩◌̖◌֚b; a◌〪◌︩◌̖◌֚b; a◌〪◌︩◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TILDE LEFT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A FE2A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062;0061 302A 0316 FE2A 059A 0062; # (a◌֚◌̖◌〪◌︪b; a◌〪◌̖◌︪◌֚b; a◌〪◌̖◌︪◌֚b; a◌〪◌̖◌︪◌֚b; a◌〪◌̖◌︪◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING TILDE RIGHT HALF BELOW, LATIN SMALL LETTER B
+0061 FE2A 059A 0316 302A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062;0061 302A FE2A 0316 059A 0062; # (a◌︪◌֚◌̖◌〪b; a◌〪◌︪◌̖◌֚b; a◌〪◌︪◌̖◌֚b; a◌〪◌︪◌̖◌֚b; a◌〪◌︪◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING TILDE RIGHT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A FE2B 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062;0061 302A 0316 FE2B 059A 0062; # (a◌֚◌̖◌〪◌︫b; a◌〪◌̖◌︫◌֚b; a◌〪◌̖◌︫◌֚b; a◌〪◌̖◌︫◌֚b; a◌〪◌̖◌︫◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING MACRON LEFT HALF BELOW, LATIN SMALL LETTER B
+0061 FE2B 059A 0316 302A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062;0061 302A FE2B 0316 059A 0062; # (a◌︫◌֚◌̖◌〪b; a◌〪◌︫◌̖◌֚b; a◌〪◌︫◌̖◌֚b; a◌〪◌︫◌̖◌֚b; a◌〪◌︫◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MACRON LEFT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A FE2C 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062;0061 302A 0316 FE2C 059A 0062; # (a◌֚◌̖◌〪◌︬b; a◌〪◌̖◌︬◌֚b; a◌〪◌̖◌︬◌֚b; a◌〪◌̖◌︬◌֚b; a◌〪◌̖◌︬◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING MACRON RIGHT HALF BELOW, LATIN SMALL LETTER B
+0061 FE2C 059A 0316 302A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062;0061 302A FE2C 0316 059A 0062; # (a◌︬◌֚◌̖◌〪b; a◌〪◌︬◌̖◌֚b; a◌〪◌︬◌̖◌֚b; a◌〪◌︬◌̖◌֚b; a◌〪◌︬◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING MACRON RIGHT HALF BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A FE2D 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062;0061 302A 0316 FE2D 059A 0062; # (a◌֚◌̖◌〪◌︭b; a◌〪◌̖◌︭◌֚b; a◌〪◌̖◌︭◌֚b; a◌〪◌̖◌︭◌֚b; a◌〪◌̖◌︭◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COMBINING CONJOINING MACRON BELOW, LATIN SMALL LETTER B
+0061 FE2D 059A 0316 302A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062;0061 302A FE2D 0316 059A 0062; # (a◌︭◌֚◌̖◌〪b; a◌〪◌︭◌̖◌֚b; a◌〪◌︭◌̖◌֚b; a◌〪◌︭◌̖◌֚b; a◌〪◌︭◌̖◌֚b; ) LATIN SMALL LETTER A, COMBINING CONJOINING MACRON BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE FE2E 0062;00E0 05AE FE2E 0315 0062;0061 05AE 0300 FE2E 0315 0062;00E0 05AE FE2E 0315 0062;0061 05AE 0300 FE2E 0315 0062; # (a◌̕◌̀◌֮◌︮b; à◌֮◌︮◌̕b; a◌֮◌̀◌︮◌̕b; à◌֮◌︮◌̕b; a◌֮◌̀◌︮◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC TITLO LEFT HALF, LATIN SMALL LETTER B
+0061 FE2E 0315 0300 05AE 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062;0061 05AE FE2E 0300 0315 0062; # (a◌︮◌̕◌̀◌֮b; a◌֮◌︮◌̀◌̕b; a◌֮◌︮◌̀◌̕b; a◌֮◌︮◌̀◌̕b; a◌֮◌︮◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO LEFT HALF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE FE2F 0062;00E0 05AE FE2F 0315 0062;0061 05AE 0300 FE2F 0315 0062;00E0 05AE FE2F 0315 0062;0061 05AE 0300 FE2F 0315 0062; # (a◌̕◌̀◌֮◌︯b; à◌֮◌︯◌̕b; a◌֮◌̀◌︯◌̕b; à◌֮◌︯◌̕b; a◌֮◌̀◌︯◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC TITLO RIGHT HALF, LATIN SMALL LETTER B
+0061 FE2F 0315 0300 05AE 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062;0061 05AE FE2F 0300 0315 0062; # (a◌︯◌̕◌̀◌֮b; a◌֮◌︯◌̀◌̕b; a◌֮◌︯◌̀◌̕b; a◌֮◌︯◌̀◌̕b; a◌֮◌︯◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC TITLO RIGHT HALF, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 101FD 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062;0061 302A 0316 101FD 059A 0062; # (a◌֚◌̖◌〪◌𐇽b; a◌〪◌̖◌𐇽◌֚b; a◌〪◌̖◌𐇽◌֚b; a◌〪◌̖◌𐇽◌֚b; a◌〪◌̖◌𐇽◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE, LATIN SMALL LETTER B
+0061 101FD 059A 0316 302A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062;0061 302A 101FD 0316 059A 0062; # (a◌𐇽◌֚◌̖◌〪b; a◌〪◌𐇽◌̖◌֚b; a◌〪◌𐇽◌̖◌֚b; a◌〪◌𐇽◌̖◌֚b; a◌〪◌𐇽◌̖◌֚b; ) LATIN SMALL LETTER A, PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 102E0 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062;0061 302A 0316 102E0 059A 0062; # (a◌֚◌̖◌〪◌𐋠b; a◌〪◌̖◌𐋠◌֚b; a◌〪◌̖◌𐋠◌֚b; a◌〪◌̖◌𐋠◌֚b; a◌〪◌̖◌𐋠◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, COPTIC EPACT THOUSANDS MARK, LATIN SMALL LETTER B
+0061 102E0 059A 0316 302A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062;0061 302A 102E0 0316 059A 0062; # (a◌𐋠◌֚◌̖◌〪b; a◌〪◌𐋠◌̖◌֚b; a◌〪◌𐋠◌̖◌֚b; a◌〪◌𐋠◌̖◌֚b; a◌〪◌𐋠◌̖◌֚b; ) LATIN SMALL LETTER A, COPTIC EPACT THOUSANDS MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 10376 0062;00E0 05AE 10376 0315 0062;0061 05AE 0300 10376 0315 0062;00E0 05AE 10376 0315 0062;0061 05AE 0300 10376 0315 0062; # (a◌̕◌̀◌֮◌𐍶b; à◌֮◌𐍶◌̕b; a◌֮◌̀◌𐍶◌̕b; à◌֮◌𐍶◌̕b; a◌֮◌̀◌𐍶◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING OLD PERMIC LETTER AN, LATIN SMALL LETTER B
+0061 10376 0315 0300 05AE 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062;0061 05AE 10376 0300 0315 0062; # (a◌𐍶◌̕◌̀◌֮b; a◌֮◌𐍶◌̀◌̕b; a◌֮◌𐍶◌̀◌̕b; a◌֮◌𐍶◌̀◌̕b; a◌֮◌𐍶◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING OLD PERMIC LETTER AN, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 10377 0062;00E0 05AE 10377 0315 0062;0061 05AE 0300 10377 0315 0062;00E0 05AE 10377 0315 0062;0061 05AE 0300 10377 0315 0062; # (a◌̕◌̀◌֮◌𐍷b; à◌֮◌𐍷◌̕b; a◌֮◌̀◌𐍷◌̕b; à◌֮◌𐍷◌̕b; a◌֮◌̀◌𐍷◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING OLD PERMIC LETTER DOI, LATIN SMALL LETTER B
+0061 10377 0315 0300 05AE 0062;0061 05AE 10377 0300 0315 0062;0061 05AE 10377 0300 0315 0062;0061 05AE 10377 0300 0315 0062;0061 05AE 10377 0300 0315 0062; # (a◌𐍷◌̕◌̀◌֮b; a◌֮◌𐍷◌̀◌̕b; a◌֮◌𐍷◌̀◌̕b; a◌֮◌𐍷◌̀◌̕b; a◌֮◌𐍷◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING OLD PERMIC LETTER DOI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 10378 0062;00E0 05AE 10378 0315 0062;0061 05AE 0300 10378 0315 0062;00E0 05AE 10378 0315 0062;0061 05AE 0300 10378 0315 0062; # (a◌̕◌̀◌֮◌𐍸b; à◌֮◌𐍸◌̕b; a◌֮◌̀◌𐍸◌̕b; à◌֮◌𐍸◌̕b; a◌֮◌̀◌𐍸◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING OLD PERMIC LETTER ZATA, LATIN SMALL LETTER B
+0061 10378 0315 0300 05AE 0062;0061 05AE 10378 0300 0315 0062;0061 05AE 10378 0300 0315 0062;0061 05AE 10378 0300 0315 0062;0061 05AE 10378 0300 0315 0062; # (a◌𐍸◌̕◌̀◌֮b; a◌֮◌𐍸◌̀◌̕b; a◌֮◌𐍸◌̀◌̕b; a◌֮◌𐍸◌̀◌̕b; a◌֮◌𐍸◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING OLD PERMIC LETTER ZATA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 10379 0062;00E0 05AE 10379 0315 0062;0061 05AE 0300 10379 0315 0062;00E0 05AE 10379 0315 0062;0061 05AE 0300 10379 0315 0062; # (a◌̕◌̀◌֮◌𐍹b; à◌֮◌𐍹◌̕b; a◌֮◌̀◌𐍹◌̕b; à◌֮◌𐍹◌̕b; a◌֮◌̀◌𐍹◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING OLD PERMIC LETTER NENOE, LATIN SMALL LETTER B
+0061 10379 0315 0300 05AE 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062;0061 05AE 10379 0300 0315 0062; # (a◌𐍹◌̕◌̀◌֮b; a◌֮◌𐍹◌̀◌̕b; a◌֮◌𐍹◌̀◌̕b; a◌֮◌𐍹◌̀◌̕b; a◌֮◌𐍹◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING OLD PERMIC LETTER NENOE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1037A 0062;00E0 05AE 1037A 0315 0062;0061 05AE 0300 1037A 0315 0062;00E0 05AE 1037A 0315 0062;0061 05AE 0300 1037A 0315 0062; # (a◌̕◌̀◌֮◌𐍺b; à◌֮◌𐍺◌̕b; a◌֮◌̀◌𐍺◌̕b; à◌֮◌𐍺◌̕b; a◌֮◌̀◌𐍺◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING OLD PERMIC LETTER SII, LATIN SMALL LETTER B
+0061 1037A 0315 0300 05AE 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062;0061 05AE 1037A 0300 0315 0062; # (a◌𐍺◌̕◌̀◌֮b; a◌֮◌𐍺◌̀◌̕b; a◌֮◌𐍺◌̀◌̕b; a◌֮◌𐍺◌̀◌̕b; a◌֮◌𐍺◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING OLD PERMIC LETTER SII, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 10A0D 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062;0061 302A 0316 10A0D 059A 0062; # (a◌֚◌̖◌〪◌𐨍b; a◌〪◌̖◌𐨍◌֚b; a◌〪◌̖◌𐨍◌֚b; a◌〪◌̖◌𐨍◌֚b; a◌〪◌̖◌𐨍◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, KHAROSHTHI SIGN DOUBLE RING BELOW, LATIN SMALL LETTER B
+0061 10A0D 059A 0316 302A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062;0061 302A 10A0D 0316 059A 0062; # (a◌𐨍◌֚◌̖◌〪b; a◌〪◌𐨍◌̖◌֚b; a◌〪◌𐨍◌̖◌֚b; a◌〪◌𐨍◌̖◌֚b; a◌〪◌𐨍◌̖◌֚b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN DOUBLE RING BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 10A0F 0062;00E0 05AE 10A0F 0315 0062;0061 05AE 0300 10A0F 0315 0062;00E0 05AE 10A0F 0315 0062;0061 05AE 0300 10A0F 0315 0062; # (a◌̕◌̀◌֮◌𐨏b; à◌֮◌𐨏◌̕b; a◌֮◌̀◌𐨏◌̕b; à◌֮◌𐨏◌̕b; a◌֮◌̀◌𐨏◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, KHAROSHTHI SIGN VISARGA, LATIN SMALL LETTER B
+0061 10A0F 0315 0300 05AE 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062;0061 05AE 10A0F 0300 0315 0062; # (a◌𐨏◌̕◌̀◌֮b; a◌֮◌𐨏◌̀◌̕b; a◌֮◌𐨏◌̀◌̕b; a◌֮◌𐨏◌̀◌̕b; a◌֮◌𐨏◌̀◌̕b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN VISARGA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 10A38 0062;00E0 05AE 10A38 0315 0062;0061 05AE 0300 10A38 0315 0062;00E0 05AE 10A38 0315 0062;0061 05AE 0300 10A38 0315 0062; # (a◌̕◌̀◌֮◌𐨸b; à◌֮◌𐨸◌̕b; a◌֮◌̀◌𐨸◌̕b; à◌֮◌𐨸◌̕b; a◌֮◌̀◌𐨸◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, KHAROSHTHI SIGN BAR ABOVE, LATIN SMALL LETTER B
+0061 10A38 0315 0300 05AE 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062;0061 05AE 10A38 0300 0315 0062; # (a◌𐨸◌̕◌̀◌֮b; a◌֮◌𐨸◌̀◌̕b; a◌֮◌𐨸◌̀◌̕b; a◌֮◌𐨸◌̀◌̕b; a◌֮◌𐨸◌̀◌̕b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN BAR ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 093C 0334 10A39 0062;0061 0334 10A39 093C 0062;0061 0334 10A39 093C 0062;0061 0334 10A39 093C 0062;0061 0334 10A39 093C 0062; # (a◌़◌̴◌𐨹b; a◌̴◌𐨹◌़b; a◌̴◌𐨹◌़b; a◌̴◌𐨹◌़b; a◌̴◌𐨹◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, KHAROSHTHI SIGN CAUDA, LATIN SMALL LETTER B
+0061 10A39 093C 0334 0062;0061 10A39 0334 093C 0062;0061 10A39 0334 093C 0062;0061 10A39 0334 093C 0062;0061 10A39 0334 093C 0062; # (a◌𐨹◌़◌̴b; a◌𐨹◌̴◌़b; a◌𐨹◌̴◌़b; a◌𐨹◌̴◌़b; a◌𐨹◌̴◌़b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN CAUDA, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 059A 0316 302A 10A3A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062;0061 302A 0316 10A3A 059A 0062; # (a◌֚◌̖◌〪◌𐨺b; a◌〪◌̖◌𐨺◌֚b; a◌〪◌̖◌𐨺◌֚b; a◌〪◌̖◌𐨺◌֚b; a◌〪◌̖◌𐨺◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, KHAROSHTHI SIGN DOT BELOW, LATIN SMALL LETTER B
+0061 10A3A 059A 0316 302A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062;0061 302A 10A3A 0316 059A 0062; # (a◌𐨺◌֚◌̖◌〪b; a◌〪◌𐨺◌̖◌֚b; a◌〪◌𐨺◌̖◌֚b; a◌〪◌𐨺◌̖◌֚b; a◌〪◌𐨺◌̖◌֚b; ) LATIN SMALL LETTER A, KHAROSHTHI SIGN DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 10A3F 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 05B0 0062;0061 3099 094D 10A3F 05B0 0062; # (a◌ְ◌्◌゙◌𐨿b; a◌゙◌्◌𐨿◌ְb; a◌゙◌्◌𐨿◌ְb; a◌゙◌्◌𐨿◌ְb; a◌゙◌्◌𐨿◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, KHAROSHTHI VIRAMA, LATIN SMALL LETTER B
+0061 10A3F 05B0 094D 3099 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062;0061 3099 10A3F 094D 05B0 0062; # (a◌𐨿◌ְ◌्◌゙b; a◌゙◌𐨿◌्◌ְb; a◌゙◌𐨿◌्◌ְb; a◌゙◌𐨿◌्◌ְb; a◌゙◌𐨿◌्◌ְb; ) LATIN SMALL LETTER A, KHAROSHTHI VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 10AE5 0062;00E0 05AE 10AE5 0315 0062;0061 05AE 0300 10AE5 0315 0062;00E0 05AE 10AE5 0315 0062;0061 05AE 0300 10AE5 0315 0062; # (a◌̕◌̀◌֮◌𐫥b; à◌֮◌𐫥◌̕b; a◌֮◌̀◌𐫥◌̕b; à◌֮◌𐫥◌̕b; a◌֮◌̀◌𐫥◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MANICHAEAN ABBREVIATION MARK ABOVE, LATIN SMALL LETTER B
+0061 10AE5 0315 0300 05AE 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062;0061 05AE 10AE5 0300 0315 0062; # (a◌𐫥◌̕◌̀◌֮b; a◌֮◌𐫥◌̀◌̕b; a◌֮◌𐫥◌̀◌̕b; a◌֮◌𐫥◌̀◌̕b; a◌֮◌𐫥◌̀◌̕b; ) LATIN SMALL LETTER A, MANICHAEAN ABBREVIATION MARK ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 10AE6 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062;0061 302A 0316 10AE6 059A 0062; # (a◌֚◌̖◌〪◌𐫦b; a◌〪◌̖◌𐫦◌֚b; a◌〪◌̖◌𐫦◌֚b; a◌〪◌̖◌𐫦◌֚b; a◌〪◌̖◌𐫦◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MANICHAEAN ABBREVIATION MARK BELOW, LATIN SMALL LETTER B
+0061 10AE6 059A 0316 302A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062;0061 302A 10AE6 0316 059A 0062; # (a◌𐫦◌֚◌̖◌〪b; a◌〪◌𐫦◌̖◌֚b; a◌〪◌𐫦◌̖◌֚b; a◌〪◌𐫦◌̖◌֚b; a◌〪◌𐫦◌̖◌֚b; ) LATIN SMALL LETTER A, MANICHAEAN ABBREVIATION MARK BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11046 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 05B0 0062;0061 3099 094D 11046 05B0 0062; # (a◌ְ◌्◌゙◌𑁆b; a◌゙◌्◌𑁆◌ְb; a◌゙◌्◌𑁆◌ְb; a◌゙◌्◌𑁆◌ְb; a◌゙◌्◌𑁆◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, BRAHMI VIRAMA, LATIN SMALL LETTER B
+0061 11046 05B0 094D 3099 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062;0061 3099 11046 094D 05B0 0062; # (a◌𑁆◌ְ◌्◌゙b; a◌゙◌𑁆◌्◌ְb; a◌゙◌𑁆◌्◌ְb; a◌゙◌𑁆◌्◌ְb; a◌゙◌𑁆◌्◌ְb; ) LATIN SMALL LETTER A, BRAHMI VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1107F 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 05B0 0062;0061 3099 094D 1107F 05B0 0062; # (a◌ְ◌्◌゙◌𑁿b; a◌゙◌्◌𑁿◌ְb; a◌゙◌्◌𑁿◌ְb; a◌゙◌्◌𑁿◌ְb; a◌゙◌्◌𑁿◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, BRAHMI NUMBER JOINER, LATIN SMALL LETTER B
+0061 1107F 05B0 094D 3099 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062;0061 3099 1107F 094D 05B0 0062; # (a◌𑁿◌ְ◌्◌゙b; a◌゙◌𑁿◌्◌ְb; a◌゙◌𑁿◌्◌ְb; a◌゙◌𑁿◌्◌ְb; a◌゙◌𑁿◌्◌ְb; ) LATIN SMALL LETTER A, BRAHMI NUMBER JOINER, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 110B9 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 05B0 0062;0061 3099 094D 110B9 05B0 0062; # (a◌ְ◌्◌゙◌𑂹b; a◌゙◌्◌𑂹◌ְb; a◌゙◌्◌𑂹◌ְb; a◌゙◌्◌𑂹◌ְb; a◌゙◌्◌𑂹◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, KAITHI SIGN VIRAMA, LATIN SMALL LETTER B
+0061 110B9 05B0 094D 3099 0062;0061 3099 110B9 094D 05B0 0062;0061 3099 110B9 094D 05B0 0062;0061 3099 110B9 094D 05B0 0062;0061 3099 110B9 094D 05B0 0062; # (a◌𑂹◌ְ◌्◌゙b; a◌゙◌𑂹◌्◌ְb; a◌゙◌𑂹◌्◌ְb; a◌゙◌𑂹◌्◌ְb; a◌゙◌𑂹◌्◌ְb; ) LATIN SMALL LETTER A, KAITHI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 110BA 0062;0061 0334 093C 110BA 3099 0062;0061 0334 093C 110BA 3099 0062;0061 0334 093C 110BA 3099 0062;0061 0334 093C 110BA 3099 0062; # (a◌゙◌़◌̴◌𑂺b; a◌̴◌़◌𑂺◌゙b; a◌̴◌़◌𑂺◌゙b; a◌̴◌़◌𑂺◌゙b; a◌̴◌़◌𑂺◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, KAITHI SIGN NUKTA, LATIN SMALL LETTER B
+0061 110BA 3099 093C 0334 0062;0061 0334 110BA 093C 3099 0062;0061 0334 110BA 093C 3099 0062;0061 0334 110BA 093C 3099 0062;0061 0334 110BA 093C 3099 0062; # (a◌𑂺◌゙◌़◌̴b; a◌̴◌𑂺◌़◌゙b; a◌̴◌𑂺◌़◌゙b; a◌̴◌𑂺◌़◌゙b; a◌̴◌𑂺◌़◌゙b; ) LATIN SMALL LETTER A, KAITHI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11100 0062;00E0 05AE 11100 0315 0062;0061 05AE 0300 11100 0315 0062;00E0 05AE 11100 0315 0062;0061 05AE 0300 11100 0315 0062; # (a◌̕◌̀◌֮◌𑄀b; à◌֮◌𑄀◌̕b; a◌֮◌̀◌𑄀◌̕b; à◌֮◌𑄀◌̕b; a◌֮◌̀◌𑄀◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, CHAKMA SIGN CANDRABINDU, LATIN SMALL LETTER B
+0061 11100 0315 0300 05AE 0062;0061 05AE 11100 0300 0315 0062;0061 05AE 11100 0300 0315 0062;0061 05AE 11100 0300 0315 0062;0061 05AE 11100 0300 0315 0062; # (a◌𑄀◌̕◌̀◌֮b; a◌֮◌𑄀◌̀◌̕b; a◌֮◌𑄀◌̀◌̕b; a◌֮◌𑄀◌̀◌̕b; a◌֮◌𑄀◌̀◌̕b; ) LATIN SMALL LETTER A, CHAKMA SIGN CANDRABINDU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11101 0062;00E0 05AE 11101 0315 0062;0061 05AE 0300 11101 0315 0062;00E0 05AE 11101 0315 0062;0061 05AE 0300 11101 0315 0062; # (a◌̕◌̀◌֮◌𑄁b; à◌֮◌𑄁◌̕b; a◌֮◌̀◌𑄁◌̕b; à◌֮◌𑄁◌̕b; a◌֮◌̀◌𑄁◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, CHAKMA SIGN ANUSVARA, LATIN SMALL LETTER B
+0061 11101 0315 0300 05AE 0062;0061 05AE 11101 0300 0315 0062;0061 05AE 11101 0300 0315 0062;0061 05AE 11101 0300 0315 0062;0061 05AE 11101 0300 0315 0062; # (a◌𑄁◌̕◌̀◌֮b; a◌֮◌𑄁◌̀◌̕b; a◌֮◌𑄁◌̀◌̕b; a◌֮◌𑄁◌̀◌̕b; a◌֮◌𑄁◌̀◌̕b; ) LATIN SMALL LETTER A, CHAKMA SIGN ANUSVARA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11102 0062;00E0 05AE 11102 0315 0062;0061 05AE 0300 11102 0315 0062;00E0 05AE 11102 0315 0062;0061 05AE 0300 11102 0315 0062; # (a◌̕◌̀◌֮◌𑄂b; à◌֮◌𑄂◌̕b; a◌֮◌̀◌𑄂◌̕b; à◌֮◌𑄂◌̕b; a◌֮◌̀◌𑄂◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, CHAKMA SIGN VISARGA, LATIN SMALL LETTER B
+0061 11102 0315 0300 05AE 0062;0061 05AE 11102 0300 0315 0062;0061 05AE 11102 0300 0315 0062;0061 05AE 11102 0300 0315 0062;0061 05AE 11102 0300 0315 0062; # (a◌𑄂◌̕◌̀◌֮b; a◌֮◌𑄂◌̀◌̕b; a◌֮◌𑄂◌̀◌̕b; a◌֮◌𑄂◌̀◌̕b; a◌֮◌𑄂◌̀◌̕b; ) LATIN SMALL LETTER A, CHAKMA SIGN VISARGA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11133 0062;0061 3099 094D 11133 05B0 0062;0061 3099 094D 11133 05B0 0062;0061 3099 094D 11133 05B0 0062;0061 3099 094D 11133 05B0 0062; # (a◌ְ◌्◌゙◌𑄳b; a◌゙◌्◌𑄳◌ְb; a◌゙◌्◌𑄳◌ְb; a◌゙◌्◌𑄳◌ְb; a◌゙◌्◌𑄳◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, CHAKMA VIRAMA, LATIN SMALL LETTER B
+0061 11133 05B0 094D 3099 0062;0061 3099 11133 094D 05B0 0062;0061 3099 11133 094D 05B0 0062;0061 3099 11133 094D 05B0 0062;0061 3099 11133 094D 05B0 0062; # (a◌𑄳◌ְ◌्◌゙b; a◌゙◌𑄳◌्◌ְb; a◌゙◌𑄳◌्◌ְb; a◌゙◌𑄳◌्◌ְb; a◌゙◌𑄳◌्◌ְb; ) LATIN SMALL LETTER A, CHAKMA VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11134 0062;0061 3099 094D 11134 05B0 0062;0061 3099 094D 11134 05B0 0062;0061 3099 094D 11134 05B0 0062;0061 3099 094D 11134 05B0 0062; # (a◌ְ◌्◌゙◌𑄴b; a◌゙◌्◌𑄴◌ְb; a◌゙◌्◌𑄴◌ְb; a◌゙◌्◌𑄴◌ְb; a◌゙◌्◌𑄴◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, CHAKMA MAAYYAA, LATIN SMALL LETTER B
+0061 11134 05B0 094D 3099 0062;0061 3099 11134 094D 05B0 0062;0061 3099 11134 094D 05B0 0062;0061 3099 11134 094D 05B0 0062;0061 3099 11134 094D 05B0 0062; # (a◌𑄴◌ְ◌्◌゙b; a◌゙◌𑄴◌्◌ְb; a◌゙◌𑄴◌्◌ְb; a◌゙◌𑄴◌्◌ְb; a◌゙◌𑄴◌्◌ְb; ) LATIN SMALL LETTER A, CHAKMA MAAYYAA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 11173 0062;0061 0334 093C 11173 3099 0062;0061 0334 093C 11173 3099 0062;0061 0334 093C 11173 3099 0062;0061 0334 093C 11173 3099 0062; # (a◌゙◌़◌̴◌𑅳b; a◌̴◌़◌𑅳◌゙b; a◌̴◌़◌𑅳◌゙b; a◌̴◌़◌𑅳◌゙b; a◌̴◌़◌𑅳◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, MAHAJANI SIGN NUKTA, LATIN SMALL LETTER B
+0061 11173 3099 093C 0334 0062;0061 0334 11173 093C 3099 0062;0061 0334 11173 093C 3099 0062;0061 0334 11173 093C 3099 0062;0061 0334 11173 093C 3099 0062; # (a◌𑅳◌゙◌़◌̴b; a◌̴◌𑅳◌़◌゙b; a◌̴◌𑅳◌़◌゙b; a◌̴◌𑅳◌़◌゙b; a◌̴◌𑅳◌़◌゙b; ) LATIN SMALL LETTER A, MAHAJANI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 111C0 0062;0061 3099 094D 111C0 05B0 0062;0061 3099 094D 111C0 05B0 0062;0061 3099 094D 111C0 05B0 0062;0061 3099 094D 111C0 05B0 0062; # (a◌ְ◌्◌゙𑇀b; a◌゙◌्𑇀◌ְb; a◌゙◌्𑇀◌ְb; a◌゙◌्𑇀◌ְb; a◌゙◌्𑇀◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, SHARADA SIGN VIRAMA, LATIN SMALL LETTER B
+0061 111C0 05B0 094D 3099 0062;0061 3099 111C0 094D 05B0 0062;0061 3099 111C0 094D 05B0 0062;0061 3099 111C0 094D 05B0 0062;0061 3099 111C0 094D 05B0 0062; # (a𑇀◌ְ◌्◌゙b; a◌゙𑇀◌्◌ְb; a◌゙𑇀◌्◌ְb; a◌゙𑇀◌्◌ְb; a◌゙𑇀◌्◌ְb; ) LATIN SMALL LETTER A, SHARADA SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 111CA 0062;0061 0334 093C 111CA 3099 0062;0061 0334 093C 111CA 3099 0062;0061 0334 093C 111CA 3099 0062;0061 0334 093C 111CA 3099 0062; # (a◌゙◌़◌̴◌𑇊b; a◌̴◌़◌𑇊◌゙b; a◌̴◌़◌𑇊◌゙b; a◌̴◌़◌𑇊◌゙b; a◌̴◌़◌𑇊◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, SHARADA SIGN NUKTA, LATIN SMALL LETTER B
+0061 111CA 3099 093C 0334 0062;0061 0334 111CA 093C 3099 0062;0061 0334 111CA 093C 3099 0062;0061 0334 111CA 093C 3099 0062;0061 0334 111CA 093C 3099 0062; # (a◌𑇊◌゙◌़◌̴b; a◌̴◌𑇊◌़◌゙b; a◌̴◌𑇊◌़◌゙b; a◌̴◌𑇊◌़◌゙b; a◌̴◌𑇊◌़◌゙b; ) LATIN SMALL LETTER A, SHARADA SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11235 0062;0061 3099 094D 11235 05B0 0062;0061 3099 094D 11235 05B0 0062;0061 3099 094D 11235 05B0 0062;0061 3099 094D 11235 05B0 0062; # (a◌ְ◌्◌゙𑈵b; a◌゙◌्𑈵◌ְb; a◌゙◌्𑈵◌ְb; a◌゙◌्𑈵◌ְb; a◌゙◌्𑈵◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, KHOJKI SIGN VIRAMA, LATIN SMALL LETTER B
+0061 11235 05B0 094D 3099 0062;0061 3099 11235 094D 05B0 0062;0061 3099 11235 094D 05B0 0062;0061 3099 11235 094D 05B0 0062;0061 3099 11235 094D 05B0 0062; # (a𑈵◌ְ◌्◌゙b; a◌゙𑈵◌्◌ְb; a◌゙𑈵◌्◌ְb; a◌゙𑈵◌्◌ְb; a◌゙𑈵◌्◌ְb; ) LATIN SMALL LETTER A, KHOJKI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 11236 0062;0061 0334 093C 11236 3099 0062;0061 0334 093C 11236 3099 0062;0061 0334 093C 11236 3099 0062;0061 0334 093C 11236 3099 0062; # (a◌゙◌़◌̴◌𑈶b; a◌̴◌़◌𑈶◌゙b; a◌̴◌़◌𑈶◌゙b; a◌̴◌़◌𑈶◌゙b; a◌̴◌़◌𑈶◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, KHOJKI SIGN NUKTA, LATIN SMALL LETTER B
+0061 11236 3099 093C 0334 0062;0061 0334 11236 093C 3099 0062;0061 0334 11236 093C 3099 0062;0061 0334 11236 093C 3099 0062;0061 0334 11236 093C 3099 0062; # (a◌𑈶◌゙◌़◌̴b; a◌̴◌𑈶◌़◌゙b; a◌̴◌𑈶◌़◌゙b; a◌̴◌𑈶◌़◌゙b; a◌̴◌𑈶◌़◌゙b; ) LATIN SMALL LETTER A, KHOJKI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 3099 093C 0334 112E9 0062;0061 0334 093C 112E9 3099 0062;0061 0334 093C 112E9 3099 0062;0061 0334 093C 112E9 3099 0062;0061 0334 093C 112E9 3099 0062; # (a◌゙◌़◌̴◌𑋩b; a◌̴◌़◌𑋩◌゙b; a◌̴◌़◌𑋩◌゙b; a◌̴◌़◌𑋩◌゙b; a◌̴◌़◌𑋩◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, KHUDAWADI SIGN NUKTA, LATIN SMALL LETTER B
+0061 112E9 3099 093C 0334 0062;0061 0334 112E9 093C 3099 0062;0061 0334 112E9 093C 3099 0062;0061 0334 112E9 093C 3099 0062;0061 0334 112E9 093C 3099 0062; # (a◌𑋩◌゙◌़◌̴b; a◌̴◌𑋩◌़◌゙b; a◌̴◌𑋩◌़◌゙b; a◌̴◌𑋩◌़◌゙b; a◌̴◌𑋩◌़◌゙b; ) LATIN SMALL LETTER A, KHUDAWADI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 112EA 0062;0061 3099 094D 112EA 05B0 0062;0061 3099 094D 112EA 05B0 0062;0061 3099 094D 112EA 05B0 0062;0061 3099 094D 112EA 05B0 0062; # (a◌ְ◌्◌゙◌𑋪b; a◌゙◌्◌𑋪◌ְb; a◌゙◌्◌𑋪◌ְb; a◌゙◌्◌𑋪◌ְb; a◌゙◌्◌𑋪◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, KHUDAWADI SIGN VIRAMA, LATIN SMALL LETTER B
+0061 112EA 05B0 094D 3099 0062;0061 3099 112EA 094D 05B0 0062;0061 3099 112EA 094D 05B0 0062;0061 3099 112EA 094D 05B0 0062;0061 3099 112EA 094D 05B0 0062; # (a◌𑋪◌ְ◌्◌゙b; a◌゙◌𑋪◌्◌ְb; a◌゙◌𑋪◌्◌ְb; a◌゙◌𑋪◌्◌ְb; a◌゙◌𑋪◌्◌ְb; ) LATIN SMALL LETTER A, KHUDAWADI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 1133C 0062;0061 0334 093C 1133C 3099 0062;0061 0334 093C 1133C 3099 0062;0061 0334 093C 1133C 3099 0062;0061 0334 093C 1133C 3099 0062; # (a◌゙◌़◌̴◌𑌼b; a◌̴◌़◌𑌼◌゙b; a◌̴◌़◌𑌼◌゙b; a◌̴◌़◌𑌼◌゙b; a◌̴◌़◌𑌼◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, GRANTHA SIGN NUKTA, LATIN SMALL LETTER B
+0061 1133C 3099 093C 0334 0062;0061 0334 1133C 093C 3099 0062;0061 0334 1133C 093C 3099 0062;0061 0334 1133C 093C 3099 0062;0061 0334 1133C 093C 3099 0062; # (a◌𑌼◌゙◌़◌̴b; a◌̴◌𑌼◌़◌゙b; a◌̴◌𑌼◌़◌゙b; a◌̴◌𑌼◌़◌゙b; a◌̴◌𑌼◌़◌゙b; ) LATIN SMALL LETTER A, GRANTHA SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1134D 0062;0061 3099 094D 1134D 05B0 0062;0061 3099 094D 1134D 05B0 0062;0061 3099 094D 1134D 05B0 0062;0061 3099 094D 1134D 05B0 0062; # (a◌ְ◌्◌゙𑍍b; a◌゙◌्𑍍◌ְb; a◌゙◌्𑍍◌ְb; a◌゙◌्𑍍◌ְb; a◌゙◌्𑍍◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, GRANTHA SIGN VIRAMA, LATIN SMALL LETTER B
+0061 1134D 05B0 094D 3099 0062;0061 3099 1134D 094D 05B0 0062;0061 3099 1134D 094D 05B0 0062;0061 3099 1134D 094D 05B0 0062;0061 3099 1134D 094D 05B0 0062; # (a𑍍◌ְ◌्◌゙b; a◌゙𑍍◌्◌ְb; a◌゙𑍍◌्◌ְb; a◌゙𑍍◌्◌ְb; a◌゙𑍍◌्◌ְb; ) LATIN SMALL LETTER A, GRANTHA SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11366 0062;00E0 05AE 11366 0315 0062;0061 05AE 0300 11366 0315 0062;00E0 05AE 11366 0315 0062;0061 05AE 0300 11366 0315 0062; # (a◌̕◌̀◌֮◌𑍦b; à◌֮◌𑍦◌̕b; a◌֮◌̀◌𑍦◌̕b; à◌֮◌𑍦◌̕b; a◌֮◌̀◌𑍦◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA DIGIT ZERO, LATIN SMALL LETTER B
+0061 11366 0315 0300 05AE 0062;0061 05AE 11366 0300 0315 0062;0061 05AE 11366 0300 0315 0062;0061 05AE 11366 0300 0315 0062;0061 05AE 11366 0300 0315 0062; # (a◌𑍦◌̕◌̀◌֮b; a◌֮◌𑍦◌̀◌̕b; a◌֮◌𑍦◌̀◌̕b; a◌֮◌𑍦◌̀◌̕b; a◌֮◌𑍦◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA DIGIT ZERO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11367 0062;00E0 05AE 11367 0315 0062;0061 05AE 0300 11367 0315 0062;00E0 05AE 11367 0315 0062;0061 05AE 0300 11367 0315 0062; # (a◌̕◌̀◌֮◌𑍧b; à◌֮◌𑍧◌̕b; a◌֮◌̀◌𑍧◌̕b; à◌֮◌𑍧◌̕b; a◌֮◌̀◌𑍧◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA DIGIT ONE, LATIN SMALL LETTER B
+0061 11367 0315 0300 05AE 0062;0061 05AE 11367 0300 0315 0062;0061 05AE 11367 0300 0315 0062;0061 05AE 11367 0300 0315 0062;0061 05AE 11367 0300 0315 0062; # (a◌𑍧◌̕◌̀◌֮b; a◌֮◌𑍧◌̀◌̕b; a◌֮◌𑍧◌̀◌̕b; a◌֮◌𑍧◌̀◌̕b; a◌֮◌𑍧◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA DIGIT ONE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11368 0062;00E0 05AE 11368 0315 0062;0061 05AE 0300 11368 0315 0062;00E0 05AE 11368 0315 0062;0061 05AE 0300 11368 0315 0062; # (a◌̕◌̀◌֮◌𑍨b; à◌֮◌𑍨◌̕b; a◌֮◌̀◌𑍨◌̕b; à◌֮◌𑍨◌̕b; a◌֮◌̀◌𑍨◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA DIGIT TWO, LATIN SMALL LETTER B
+0061 11368 0315 0300 05AE 0062;0061 05AE 11368 0300 0315 0062;0061 05AE 11368 0300 0315 0062;0061 05AE 11368 0300 0315 0062;0061 05AE 11368 0300 0315 0062; # (a◌𑍨◌̕◌̀◌֮b; a◌֮◌𑍨◌̀◌̕b; a◌֮◌𑍨◌̀◌̕b; a◌֮◌𑍨◌̀◌̕b; a◌֮◌𑍨◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA DIGIT TWO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11369 0062;00E0 05AE 11369 0315 0062;0061 05AE 0300 11369 0315 0062;00E0 05AE 11369 0315 0062;0061 05AE 0300 11369 0315 0062; # (a◌̕◌̀◌֮◌𑍩b; à◌֮◌𑍩◌̕b; a◌֮◌̀◌𑍩◌̕b; à◌֮◌𑍩◌̕b; a◌֮◌̀◌𑍩◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA DIGIT THREE, LATIN SMALL LETTER B
+0061 11369 0315 0300 05AE 0062;0061 05AE 11369 0300 0315 0062;0061 05AE 11369 0300 0315 0062;0061 05AE 11369 0300 0315 0062;0061 05AE 11369 0300 0315 0062; # (a◌𑍩◌̕◌̀◌֮b; a◌֮◌𑍩◌̀◌̕b; a◌֮◌𑍩◌̀◌̕b; a◌֮◌𑍩◌̀◌̕b; a◌֮◌𑍩◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA DIGIT THREE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1136A 0062;00E0 05AE 1136A 0315 0062;0061 05AE 0300 1136A 0315 0062;00E0 05AE 1136A 0315 0062;0061 05AE 0300 1136A 0315 0062; # (a◌̕◌̀◌֮◌𑍪b; à◌֮◌𑍪◌̕b; a◌֮◌̀◌𑍪◌̕b; à◌֮◌𑍪◌̕b; a◌֮◌̀◌𑍪◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA DIGIT FOUR, LATIN SMALL LETTER B
+0061 1136A 0315 0300 05AE 0062;0061 05AE 1136A 0300 0315 0062;0061 05AE 1136A 0300 0315 0062;0061 05AE 1136A 0300 0315 0062;0061 05AE 1136A 0300 0315 0062; # (a◌𑍪◌̕◌̀◌֮b; a◌֮◌𑍪◌̀◌̕b; a◌֮◌𑍪◌̀◌̕b; a◌֮◌𑍪◌̀◌̕b; a◌֮◌𑍪◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA DIGIT FOUR, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1136B 0062;00E0 05AE 1136B 0315 0062;0061 05AE 0300 1136B 0315 0062;00E0 05AE 1136B 0315 0062;0061 05AE 0300 1136B 0315 0062; # (a◌̕◌̀◌֮◌𑍫b; à◌֮◌𑍫◌̕b; a◌֮◌̀◌𑍫◌̕b; à◌֮◌𑍫◌̕b; a◌֮◌̀◌𑍫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA DIGIT FIVE, LATIN SMALL LETTER B
+0061 1136B 0315 0300 05AE 0062;0061 05AE 1136B 0300 0315 0062;0061 05AE 1136B 0300 0315 0062;0061 05AE 1136B 0300 0315 0062;0061 05AE 1136B 0300 0315 0062; # (a◌𑍫◌̕◌̀◌֮b; a◌֮◌𑍫◌̀◌̕b; a◌֮◌𑍫◌̀◌̕b; a◌֮◌𑍫◌̀◌̕b; a◌֮◌𑍫◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA DIGIT FIVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1136C 0062;00E0 05AE 1136C 0315 0062;0061 05AE 0300 1136C 0315 0062;00E0 05AE 1136C 0315 0062;0061 05AE 0300 1136C 0315 0062; # (a◌̕◌̀◌֮◌𑍬b; à◌֮◌𑍬◌̕b; a◌֮◌̀◌𑍬◌̕b; à◌֮◌𑍬◌̕b; a◌֮◌̀◌𑍬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA DIGIT SIX, LATIN SMALL LETTER B
+0061 1136C 0315 0300 05AE 0062;0061 05AE 1136C 0300 0315 0062;0061 05AE 1136C 0300 0315 0062;0061 05AE 1136C 0300 0315 0062;0061 05AE 1136C 0300 0315 0062; # (a◌𑍬◌̕◌̀◌֮b; a◌֮◌𑍬◌̀◌̕b; a◌֮◌𑍬◌̀◌̕b; a◌֮◌𑍬◌̀◌̕b; a◌֮◌𑍬◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA DIGIT SIX, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11370 0062;00E0 05AE 11370 0315 0062;0061 05AE 0300 11370 0315 0062;00E0 05AE 11370 0315 0062;0061 05AE 0300 11370 0315 0062; # (a◌̕◌̀◌֮◌𑍰b; à◌֮◌𑍰◌̕b; a◌֮◌̀◌𑍰◌̕b; à◌֮◌𑍰◌̕b; a◌֮◌̀◌𑍰◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA LETTER A, LATIN SMALL LETTER B
+0061 11370 0315 0300 05AE 0062;0061 05AE 11370 0300 0315 0062;0061 05AE 11370 0300 0315 0062;0061 05AE 11370 0300 0315 0062;0061 05AE 11370 0300 0315 0062; # (a◌𑍰◌̕◌̀◌֮b; a◌֮◌𑍰◌̀◌̕b; a◌֮◌𑍰◌̀◌̕b; a◌֮◌𑍰◌̀◌̕b; a◌֮◌𑍰◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11371 0062;00E0 05AE 11371 0315 0062;0061 05AE 0300 11371 0315 0062;00E0 05AE 11371 0315 0062;0061 05AE 0300 11371 0315 0062; # (a◌̕◌̀◌֮◌𑍱b; à◌֮◌𑍱◌̕b; a◌֮◌̀◌𑍱◌̕b; à◌֮◌𑍱◌̕b; a◌֮◌̀◌𑍱◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA LETTER KA, LATIN SMALL LETTER B
+0061 11371 0315 0300 05AE 0062;0061 05AE 11371 0300 0315 0062;0061 05AE 11371 0300 0315 0062;0061 05AE 11371 0300 0315 0062;0061 05AE 11371 0300 0315 0062; # (a◌𑍱◌̕◌̀◌֮b; a◌֮◌𑍱◌̀◌̕b; a◌֮◌𑍱◌̀◌̕b; a◌֮◌𑍱◌̀◌̕b; a◌֮◌𑍱◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA LETTER KA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11372 0062;00E0 05AE 11372 0315 0062;0061 05AE 0300 11372 0315 0062;00E0 05AE 11372 0315 0062;0061 05AE 0300 11372 0315 0062; # (a◌̕◌̀◌֮◌𑍲b; à◌֮◌𑍲◌̕b; a◌֮◌̀◌𑍲◌̕b; à◌֮◌𑍲◌̕b; a◌֮◌̀◌𑍲◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA LETTER NA, LATIN SMALL LETTER B
+0061 11372 0315 0300 05AE 0062;0061 05AE 11372 0300 0315 0062;0061 05AE 11372 0300 0315 0062;0061 05AE 11372 0300 0315 0062;0061 05AE 11372 0300 0315 0062; # (a◌𑍲◌̕◌̀◌֮b; a◌֮◌𑍲◌̀◌̕b; a◌֮◌𑍲◌̀◌̕b; a◌֮◌𑍲◌̀◌̕b; a◌֮◌𑍲◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA LETTER NA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11373 0062;00E0 05AE 11373 0315 0062;0061 05AE 0300 11373 0315 0062;00E0 05AE 11373 0315 0062;0061 05AE 0300 11373 0315 0062; # (a◌̕◌̀◌֮◌𑍳b; à◌֮◌𑍳◌̕b; a◌֮◌̀◌𑍳◌̕b; à◌֮◌𑍳◌̕b; a◌֮◌̀◌𑍳◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA LETTER VI, LATIN SMALL LETTER B
+0061 11373 0315 0300 05AE 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062; # (a◌𑍳◌̕◌̀◌֮b; a◌֮◌𑍳◌̀◌̕b; a◌֮◌𑍳◌̀◌̕b; a◌֮◌𑍳◌̀◌̕b; a◌֮◌𑍳◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA LETTER VI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 11374 0062;00E0 05AE 11374 0315 0062;0061 05AE 0300 11374 0315 0062;00E0 05AE 11374 0315 0062;0061 05AE 0300 11374 0315 0062; # (a◌̕◌̀◌֮◌𑍴b; à◌֮◌𑍴◌̕b; a◌֮◌̀◌𑍴◌̕b; à◌֮◌𑍴◌̕b; a◌֮◌̀◌𑍴◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA LETTER PA, LATIN SMALL LETTER B
+0061 11374 0315 0300 05AE 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062; # (a◌𑍴◌̕◌̀◌֮b; a◌֮◌𑍴◌̀◌̕b; a◌֮◌𑍴◌̀◌̕b; a◌֮◌𑍴◌̀◌̕b; a◌֮◌𑍴◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA LETTER PA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11442 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062; # (a◌ְ◌्◌゙◌𑑂b; a◌゙◌्◌𑑂◌ְb; a◌゙◌्◌𑑂◌ְb; a◌゙◌्◌𑑂◌ְb; a◌゙◌्◌𑑂◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, NEWA SIGN VIRAMA, LATIN SMALL LETTER B
+0061 11442 05B0 094D 3099 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062; # (a◌𑑂◌ְ◌्◌゙b; a◌゙◌𑑂◌्◌ְb; a◌゙◌𑑂◌्◌ְb; a◌゙◌𑑂◌्◌ְb; a◌゙◌𑑂◌्◌ְb; ) LATIN SMALL LETTER A, NEWA SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 11446 0062;0061 0334 093C 11446 3099 0062;0061 0334 093C 11446 3099 0062;0061 0334 093C 11446 3099 0062;0061 0334 093C 11446 3099 0062; # (a◌゙◌़◌̴◌𑑆b; a◌̴◌़◌𑑆◌゙b; a◌̴◌़◌𑑆◌゙b; a◌̴◌़◌𑑆◌゙b; a◌̴◌़◌𑑆◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, NEWA SIGN NUKTA, LATIN SMALL LETTER B
+0061 11446 3099 093C 0334 0062;0061 0334 11446 093C 3099 0062;0061 0334 11446 093C 3099 0062;0061 0334 11446 093C 3099 0062;0061 0334 11446 093C 3099 0062; # (a◌𑑆◌゙◌़◌̴b; a◌̴◌𑑆◌़◌゙b; a◌̴◌𑑆◌़◌゙b; a◌̴◌𑑆◌़◌゙b; a◌̴◌𑑆◌़◌゙b; ) LATIN SMALL LETTER A, NEWA SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 114C2 0062;0061 3099 094D 114C2 05B0 0062;0061 3099 094D 114C2 05B0 0062;0061 3099 094D 114C2 05B0 0062;0061 3099 094D 114C2 05B0 0062; # (a◌ְ◌्◌゙◌𑓂b; a◌゙◌्◌𑓂◌ְb; a◌゙◌्◌𑓂◌ְb; a◌゙◌्◌𑓂◌ְb; a◌゙◌्◌𑓂◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, TIRHUTA SIGN VIRAMA, LATIN SMALL LETTER B
+0061 114C2 05B0 094D 3099 0062;0061 3099 114C2 094D 05B0 0062;0061 3099 114C2 094D 05B0 0062;0061 3099 114C2 094D 05B0 0062;0061 3099 114C2 094D 05B0 0062; # (a◌𑓂◌ְ◌्◌゙b; a◌゙◌𑓂◌्◌ְb; a◌゙◌𑓂◌्◌ְb; a◌゙◌𑓂◌्◌ְb; a◌゙◌𑓂◌्◌ְb; ) LATIN SMALL LETTER A, TIRHUTA SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 114C3 0062;0061 0334 093C 114C3 3099 0062;0061 0334 093C 114C3 3099 0062;0061 0334 093C 114C3 3099 0062;0061 0334 093C 114C3 3099 0062; # (a◌゙◌़◌̴◌𑓃b; a◌̴◌़◌𑓃◌゙b; a◌̴◌़◌𑓃◌゙b; a◌̴◌़◌𑓃◌゙b; a◌̴◌़◌𑓃◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, TIRHUTA SIGN NUKTA, LATIN SMALL LETTER B
+0061 114C3 3099 093C 0334 0062;0061 0334 114C3 093C 3099 0062;0061 0334 114C3 093C 3099 0062;0061 0334 114C3 093C 3099 0062;0061 0334 114C3 093C 3099 0062; # (a◌𑓃◌゙◌़◌̴b; a◌̴◌𑓃◌़◌゙b; a◌̴◌𑓃◌़◌゙b; a◌̴◌𑓃◌़◌゙b; a◌̴◌𑓃◌़◌゙b; ) LATIN SMALL LETTER A, TIRHUTA SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 115BF 0062;0061 3099 094D 115BF 05B0 0062;0061 3099 094D 115BF 05B0 0062;0061 3099 094D 115BF 05B0 0062;0061 3099 094D 115BF 05B0 0062; # (a◌ְ◌्◌゙◌𑖿b; a◌゙◌्◌𑖿◌ְb; a◌゙◌्◌𑖿◌ְb; a◌゙◌्◌𑖿◌ְb; a◌゙◌्◌𑖿◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, SIDDHAM SIGN VIRAMA, LATIN SMALL LETTER B
+0061 115BF 05B0 094D 3099 0062;0061 3099 115BF 094D 05B0 0062;0061 3099 115BF 094D 05B0 0062;0061 3099 115BF 094D 05B0 0062;0061 3099 115BF 094D 05B0 0062; # (a◌𑖿◌ְ◌्◌゙b; a◌゙◌𑖿◌्◌ְb; a◌゙◌𑖿◌्◌ְb; a◌゙◌𑖿◌्◌ְb; a◌゙◌𑖿◌्◌ְb; ) LATIN SMALL LETTER A, SIDDHAM SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 115C0 0062;0061 0334 093C 115C0 3099 0062;0061 0334 093C 115C0 3099 0062;0061 0334 093C 115C0 3099 0062;0061 0334 093C 115C0 3099 0062; # (a◌゙◌़◌̴◌𑗀b; a◌̴◌़◌𑗀◌゙b; a◌̴◌़◌𑗀◌゙b; a◌̴◌़◌𑗀◌゙b; a◌̴◌़◌𑗀◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, SIDDHAM SIGN NUKTA, LATIN SMALL LETTER B
+0061 115C0 3099 093C 0334 0062;0061 0334 115C0 093C 3099 0062;0061 0334 115C0 093C 3099 0062;0061 0334 115C0 093C 3099 0062;0061 0334 115C0 093C 3099 0062; # (a◌𑗀◌゙◌़◌̴b; a◌̴◌𑗀◌़◌゙b; a◌̴◌𑗀◌़◌゙b; a◌̴◌𑗀◌़◌゙b; a◌̴◌𑗀◌़◌゙b; ) LATIN SMALL LETTER A, SIDDHAM SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1163F 0062;0061 3099 094D 1163F 05B0 0062;0061 3099 094D 1163F 05B0 0062;0061 3099 094D 1163F 05B0 0062;0061 3099 094D 1163F 05B0 0062; # (a◌ְ◌्◌゙◌𑘿b; a◌゙◌्◌𑘿◌ְb; a◌゙◌्◌𑘿◌ְb; a◌゙◌्◌𑘿◌ְb; a◌゙◌्◌𑘿◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, MODI SIGN VIRAMA, LATIN SMALL LETTER B
+0061 1163F 05B0 094D 3099 0062;0061 3099 1163F 094D 05B0 0062;0061 3099 1163F 094D 05B0 0062;0061 3099 1163F 094D 05B0 0062;0061 3099 1163F 094D 05B0 0062; # (a◌𑘿◌ְ◌्◌゙b; a◌゙◌𑘿◌्◌ְb; a◌゙◌𑘿◌्◌ְb; a◌゙◌𑘿◌्◌ְb; a◌゙◌𑘿◌्◌ְb; ) LATIN SMALL LETTER A, MODI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 116B6 0062;0061 3099 094D 116B6 05B0 0062;0061 3099 094D 116B6 05B0 0062;0061 3099 094D 116B6 05B0 0062;0061 3099 094D 116B6 05B0 0062; # (a◌ְ◌्◌゙𑚶b; a◌゙◌्𑚶◌ְb; a◌゙◌्𑚶◌ְb; a◌゙◌्𑚶◌ְb; a◌゙◌्𑚶◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, TAKRI SIGN VIRAMA, LATIN SMALL LETTER B
+0061 116B6 05B0 094D 3099 0062;0061 3099 116B6 094D 05B0 0062;0061 3099 116B6 094D 05B0 0062;0061 3099 116B6 094D 05B0 0062;0061 3099 116B6 094D 05B0 0062; # (a𑚶◌ְ◌्◌゙b; a◌゙𑚶◌्◌ְb; a◌゙𑚶◌्◌ְb; a◌゙𑚶◌्◌ְb; a◌゙𑚶◌्◌ְb; ) LATIN SMALL LETTER A, TAKRI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 116B7 0062;0061 0334 093C 116B7 3099 0062;0061 0334 093C 116B7 3099 0062;0061 0334 093C 116B7 3099 0062;0061 0334 093C 116B7 3099 0062; # (a◌゙◌़◌̴◌𑚷b; a◌̴◌़◌𑚷◌゙b; a◌̴◌़◌𑚷◌゙b; a◌̴◌़◌𑚷◌゙b; a◌̴◌़◌𑚷◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, TAKRI SIGN NUKTA, LATIN SMALL LETTER B
+0061 116B7 3099 093C 0334 0062;0061 0334 116B7 093C 3099 0062;0061 0334 116B7 093C 3099 0062;0061 0334 116B7 093C 3099 0062;0061 0334 116B7 093C 3099 0062; # (a◌𑚷◌゙◌़◌̴b; a◌̴◌𑚷◌़◌゙b; a◌̴◌𑚷◌़◌゙b; a◌̴◌𑚷◌़◌゙b; a◌̴◌𑚷◌़◌゙b; ) LATIN SMALL LETTER A, TAKRI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 1172B 0062;0061 3099 094D 1172B 05B0 0062;0061 3099 094D 1172B 05B0 0062;0061 3099 094D 1172B 05B0 0062;0061 3099 094D 1172B 05B0 0062; # (a◌ְ◌्◌゙◌𑜫b; a◌゙◌्◌𑜫◌ְb; a◌゙◌्◌𑜫◌ְb; a◌゙◌्◌𑜫◌ְb; a◌゙◌्◌𑜫◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, AHOM SIGN KILLER, LATIN SMALL LETTER B
+0061 1172B 05B0 094D 3099 0062;0061 3099 1172B 094D 05B0 0062;0061 3099 1172B 094D 05B0 0062;0061 3099 1172B 094D 05B0 0062;0061 3099 1172B 094D 05B0 0062; # (a◌𑜫◌ְ◌्◌゙b; a◌゙◌𑜫◌्◌ְb; a◌゙◌𑜫◌्◌ְb; a◌゙◌𑜫◌्◌ְb; a◌゙◌𑜫◌्◌ְb; ) LATIN SMALL LETTER A, AHOM SIGN KILLER, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11C3F 0062;0061 3099 094D 11C3F 05B0 0062;0061 3099 094D 11C3F 05B0 0062;0061 3099 094D 11C3F 05B0 0062;0061 3099 094D 11C3F 05B0 0062; # (a◌ְ◌्◌゙◌𑰿b; a◌゙◌्◌𑰿◌ְb; a◌゙◌्◌𑰿◌ְb; a◌゙◌्◌𑰿◌ְb; a◌゙◌्◌𑰿◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, BHAIKSUKI SIGN VIRAMA, LATIN SMALL LETTER B
+0061 11C3F 05B0 094D 3099 0062;0061 3099 11C3F 094D 05B0 0062;0061 3099 11C3F 094D 05B0 0062;0061 3099 11C3F 094D 05B0 0062;0061 3099 11C3F 094D 05B0 0062; # (a◌𑰿◌ְ◌्◌゙b; a◌゙◌𑰿◌्◌ְb; a◌゙◌𑰿◌्◌ְb; a◌゙◌𑰿◌्◌ְb; a◌゙◌𑰿◌्◌ְb; ) LATIN SMALL LETTER A, BHAIKSUKI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 093C 0334 16AF0 0062;0061 0334 16AF0 093C 0062;0061 0334 16AF0 093C 0062;0061 0334 16AF0 093C 0062;0061 0334 16AF0 093C 0062; # (a◌़◌̴◌𖫰b; a◌̴◌𖫰◌़b; a◌̴◌𖫰◌़b; a◌̴◌𖫰◌़b; a◌̴◌𖫰◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, BASSA VAH COMBINING HIGH TONE, LATIN SMALL LETTER B
+0061 16AF0 093C 0334 0062;0061 16AF0 0334 093C 0062;0061 16AF0 0334 093C 0062;0061 16AF0 0334 093C 0062;0061 16AF0 0334 093C 0062; # (a◌𖫰◌़◌̴b; a◌𖫰◌̴◌़b; a◌𖫰◌̴◌़b; a◌𖫰◌̴◌़b; a◌𖫰◌̴◌़b; ) LATIN SMALL LETTER A, BASSA VAH COMBINING HIGH TONE, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 16AF1 0062;0061 0334 16AF1 093C 0062;0061 0334 16AF1 093C 0062;0061 0334 16AF1 093C 0062;0061 0334 16AF1 093C 0062; # (a◌़◌̴◌𖫱b; a◌̴◌𖫱◌़b; a◌̴◌𖫱◌़b; a◌̴◌𖫱◌़b; a◌̴◌𖫱◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, BASSA VAH COMBINING LOW TONE, LATIN SMALL LETTER B
+0061 16AF1 093C 0334 0062;0061 16AF1 0334 093C 0062;0061 16AF1 0334 093C 0062;0061 16AF1 0334 093C 0062;0061 16AF1 0334 093C 0062; # (a◌𖫱◌़◌̴b; a◌𖫱◌̴◌़b; a◌𖫱◌̴◌़b; a◌𖫱◌̴◌़b; a◌𖫱◌̴◌़b; ) LATIN SMALL LETTER A, BASSA VAH COMBINING LOW TONE, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 16AF2 0062;0061 0334 16AF2 093C 0062;0061 0334 16AF2 093C 0062;0061 0334 16AF2 093C 0062;0061 0334 16AF2 093C 0062; # (a◌़◌̴◌𖫲b; a◌̴◌𖫲◌़b; a◌̴◌𖫲◌़b; a◌̴◌𖫲◌़b; a◌̴◌𖫲◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, BASSA VAH COMBINING MID TONE, LATIN SMALL LETTER B
+0061 16AF2 093C 0334 0062;0061 16AF2 0334 093C 0062;0061 16AF2 0334 093C 0062;0061 16AF2 0334 093C 0062;0061 16AF2 0334 093C 0062; # (a◌𖫲◌़◌̴b; a◌𖫲◌̴◌़b; a◌𖫲◌̴◌़b; a◌𖫲◌̴◌़b; a◌𖫲◌̴◌़b; ) LATIN SMALL LETTER A, BASSA VAH COMBINING MID TONE, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 16AF3 0062;0061 0334 16AF3 093C 0062;0061 0334 16AF3 093C 0062;0061 0334 16AF3 093C 0062;0061 0334 16AF3 093C 0062; # (a◌़◌̴◌𖫳b; a◌̴◌𖫳◌़b; a◌̴◌𖫳◌़b; a◌̴◌𖫳◌़b; a◌̴◌𖫳◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, BASSA VAH COMBINING LOW-MID TONE, LATIN SMALL LETTER B
+0061 16AF3 093C 0334 0062;0061 16AF3 0334 093C 0062;0061 16AF3 0334 093C 0062;0061 16AF3 0334 093C 0062;0061 16AF3 0334 093C 0062; # (a◌𖫳◌़◌̴b; a◌𖫳◌̴◌़b; a◌𖫳◌̴◌़b; a◌𖫳◌̴◌़b; a◌𖫳◌̴◌़b; ) LATIN SMALL LETTER A, BASSA VAH COMBINING LOW-MID TONE, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 16AF4 0062;0061 0334 16AF4 093C 0062;0061 0334 16AF4 093C 0062;0061 0334 16AF4 093C 0062;0061 0334 16AF4 093C 0062; # (a◌़◌̴◌𖫴b; a◌̴◌𖫴◌़b; a◌̴◌𖫴◌़b; a◌̴◌𖫴◌़b; a◌̴◌𖫴◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, BASSA VAH COMBINING HIGH-LOW TONE, LATIN SMALL LETTER B
+0061 16AF4 093C 0334 0062;0061 16AF4 0334 093C 0062;0061 16AF4 0334 093C 0062;0061 16AF4 0334 093C 0062;0061 16AF4 0334 093C 0062; # (a◌𖫴◌़◌̴b; a◌𖫴◌̴◌़b; a◌𖫴◌̴◌़b; a◌𖫴◌̴◌़b; a◌𖫴◌̴◌़b; ) LATIN SMALL LETTER A, BASSA VAH COMBINING HIGH-LOW TONE, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 0315 0300 05AE 16B30 0062;00E0 05AE 16B30 0315 0062;0061 05AE 0300 16B30 0315 0062;00E0 05AE 16B30 0315 0062;0061 05AE 0300 16B30 0315 0062; # (a◌̕◌̀◌֮◌𖬰b; à◌֮◌𖬰◌̕b; a◌֮◌̀◌𖬰◌̕b; à◌֮◌𖬰◌̕b; a◌֮◌̀◌𖬰◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, PAHAWH HMONG MARK CIM TUB, LATIN SMALL LETTER B
+0061 16B30 0315 0300 05AE 0062;0061 05AE 16B30 0300 0315 0062;0061 05AE 16B30 0300 0315 0062;0061 05AE 16B30 0300 0315 0062;0061 05AE 16B30 0300 0315 0062; # (a◌𖬰◌̕◌̀◌֮b; a◌֮◌𖬰◌̀◌̕b; a◌֮◌𖬰◌̀◌̕b; a◌֮◌𖬰◌̀◌̕b; a◌֮◌𖬰◌̀◌̕b; ) LATIN SMALL LETTER A, PAHAWH HMONG MARK CIM TUB, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 16B31 0062;00E0 05AE 16B31 0315 0062;0061 05AE 0300 16B31 0315 0062;00E0 05AE 16B31 0315 0062;0061 05AE 0300 16B31 0315 0062; # (a◌̕◌̀◌֮◌𖬱b; à◌֮◌𖬱◌̕b; a◌֮◌̀◌𖬱◌̕b; à◌֮◌𖬱◌̕b; a◌֮◌̀◌𖬱◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, PAHAWH HMONG MARK CIM SO, LATIN SMALL LETTER B
+0061 16B31 0315 0300 05AE 0062;0061 05AE 16B31 0300 0315 0062;0061 05AE 16B31 0300 0315 0062;0061 05AE 16B31 0300 0315 0062;0061 05AE 16B31 0300 0315 0062; # (a◌𖬱◌̕◌̀◌֮b; a◌֮◌𖬱◌̀◌̕b; a◌֮◌𖬱◌̀◌̕b; a◌֮◌𖬱◌̀◌̕b; a◌֮◌𖬱◌̀◌̕b; ) LATIN SMALL LETTER A, PAHAWH HMONG MARK CIM SO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 16B32 0062;00E0 05AE 16B32 0315 0062;0061 05AE 0300 16B32 0315 0062;00E0 05AE 16B32 0315 0062;0061 05AE 0300 16B32 0315 0062; # (a◌̕◌̀◌֮◌𖬲b; à◌֮◌𖬲◌̕b; a◌֮◌̀◌𖬲◌̕b; à◌֮◌𖬲◌̕b; a◌֮◌̀◌𖬲◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, PAHAWH HMONG MARK CIM KES, LATIN SMALL LETTER B
+0061 16B32 0315 0300 05AE 0062;0061 05AE 16B32 0300 0315 0062;0061 05AE 16B32 0300 0315 0062;0061 05AE 16B32 0300 0315 0062;0061 05AE 16B32 0300 0315 0062; # (a◌𖬲◌̕◌̀◌֮b; a◌֮◌𖬲◌̀◌̕b; a◌֮◌𖬲◌̀◌̕b; a◌֮◌𖬲◌̀◌̕b; a◌֮◌𖬲◌̀◌̕b; ) LATIN SMALL LETTER A, PAHAWH HMONG MARK CIM KES, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 16B33 0062;00E0 05AE 16B33 0315 0062;0061 05AE 0300 16B33 0315 0062;00E0 05AE 16B33 0315 0062;0061 05AE 0300 16B33 0315 0062; # (a◌̕◌̀◌֮◌𖬳b; à◌֮◌𖬳◌̕b; a◌֮◌̀◌𖬳◌̕b; à◌֮◌𖬳◌̕b; a◌֮◌̀◌𖬳◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, PAHAWH HMONG MARK CIM KHAV, LATIN SMALL LETTER B
+0061 16B33 0315 0300 05AE 0062;0061 05AE 16B33 0300 0315 0062;0061 05AE 16B33 0300 0315 0062;0061 05AE 16B33 0300 0315 0062;0061 05AE 16B33 0300 0315 0062; # (a◌𖬳◌̕◌̀◌֮b; a◌֮◌𖬳◌̀◌̕b; a◌֮◌𖬳◌̀◌̕b; a◌֮◌𖬳◌̀◌̕b; a◌֮◌𖬳◌̀◌̕b; ) LATIN SMALL LETTER A, PAHAWH HMONG MARK CIM KHAV, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 16B34 0062;00E0 05AE 16B34 0315 0062;0061 05AE 0300 16B34 0315 0062;00E0 05AE 16B34 0315 0062;0061 05AE 0300 16B34 0315 0062; # (a◌̕◌̀◌֮◌𖬴b; à◌֮◌𖬴◌̕b; a◌֮◌̀◌𖬴◌̕b; à◌֮◌𖬴◌̕b; a◌֮◌̀◌𖬴◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, PAHAWH HMONG MARK CIM SUAM, LATIN SMALL LETTER B
+0061 16B34 0315 0300 05AE 0062;0061 05AE 16B34 0300 0315 0062;0061 05AE 16B34 0300 0315 0062;0061 05AE 16B34 0300 0315 0062;0061 05AE 16B34 0300 0315 0062; # (a◌𖬴◌̕◌̀◌֮b; a◌֮◌𖬴◌̀◌̕b; a◌֮◌𖬴◌̀◌̕b; a◌֮◌𖬴◌̀◌̕b; a◌֮◌𖬴◌̀◌̕b; ) LATIN SMALL LETTER A, PAHAWH HMONG MARK CIM SUAM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 16B35 0062;00E0 05AE 16B35 0315 0062;0061 05AE 0300 16B35 0315 0062;00E0 05AE 16B35 0315 0062;0061 05AE 0300 16B35 0315 0062; # (a◌̕◌̀◌֮◌𖬵b; à◌֮◌𖬵◌̕b; a◌֮◌̀◌𖬵◌̕b; à◌֮◌𖬵◌̕b; a◌֮◌̀◌𖬵◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, PAHAWH HMONG MARK CIM HOM, LATIN SMALL LETTER B
+0061 16B35 0315 0300 05AE 0062;0061 05AE 16B35 0300 0315 0062;0061 05AE 16B35 0300 0315 0062;0061 05AE 16B35 0300 0315 0062;0061 05AE 16B35 0300 0315 0062; # (a◌𖬵◌̕◌̀◌֮b; a◌֮◌𖬵◌̀◌̕b; a◌֮◌𖬵◌̀◌̕b; a◌֮◌𖬵◌̀◌̕b; a◌֮◌𖬵◌̀◌̕b; ) LATIN SMALL LETTER A, PAHAWH HMONG MARK CIM HOM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 16B36 0062;00E0 05AE 16B36 0315 0062;0061 05AE 0300 16B36 0315 0062;00E0 05AE 16B36 0315 0062;0061 05AE 0300 16B36 0315 0062; # (a◌̕◌̀◌֮◌𖬶b; à◌֮◌𖬶◌̕b; a◌֮◌̀◌𖬶◌̕b; à◌֮◌𖬶◌̕b; a◌֮◌̀◌𖬶◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, PAHAWH HMONG MARK CIM TAUM, LATIN SMALL LETTER B
+0061 16B36 0315 0300 05AE 0062;0061 05AE 16B36 0300 0315 0062;0061 05AE 16B36 0300 0315 0062;0061 05AE 16B36 0300 0315 0062;0061 05AE 16B36 0300 0315 0062; # (a◌𖬶◌̕◌̀◌֮b; a◌֮◌𖬶◌̀◌̕b; a◌֮◌𖬶◌̀◌̕b; a◌֮◌𖬶◌̀◌̕b; a◌֮◌𖬶◌̀◌̕b; ) LATIN SMALL LETTER A, PAHAWH HMONG MARK CIM TAUM, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 093C 0334 1BC9E 0062;0061 0334 1BC9E 093C 0062;0061 0334 1BC9E 093C 0062;0061 0334 1BC9E 093C 0062;0061 0334 1BC9E 093C 0062; # (a◌़◌̴◌𛲞b; a◌̴◌𛲞◌़b; a◌̴◌𛲞◌़b; a◌̴◌𛲞◌़b; a◌̴◌𛲞◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, DUPLOYAN DOUBLE MARK, LATIN SMALL LETTER B
+0061 1BC9E 093C 0334 0062;0061 1BC9E 0334 093C 0062;0061 1BC9E 0334 093C 0062;0061 1BC9E 0334 093C 0062;0061 1BC9E 0334 093C 0062; # (a◌𛲞◌़◌̴b; a◌𛲞◌̴◌़b; a◌𛲞◌̴◌़b; a◌𛲞◌̴◌़b; a◌𛲞◌̴◌़b; ) LATIN SMALL LETTER A, DUPLOYAN DOUBLE MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 302A 031B 1DCE 1D165 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062;0061 1DCE 031B 1D165 302A 0062; # (a◌〪◌̛◌᷎𝅥b; a◌᷎◌̛𝅥◌〪b; a◌᷎◌̛𝅥◌〪b; a◌᷎◌̛𝅥◌〪b; a◌᷎◌̛𝅥◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING STEM, LATIN SMALL LETTER B
+0061 1D165 302A 031B 1DCE 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062;0061 1DCE 1D165 031B 302A 0062; # (a𝅥◌〪◌̛◌᷎b; a◌᷎𝅥◌̛◌〪b; a◌᷎𝅥◌̛◌〪b; a◌᷎𝅥◌̛◌〪b; a◌᷎𝅥◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING STEM, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 302A 031B 1DCE 1D166 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062;0061 1DCE 031B 1D166 302A 0062; # (a◌〪◌̛◌᷎𝅦b; a◌᷎◌̛𝅦◌〪b; a◌᷎◌̛𝅦◌〪b; a◌᷎◌̛𝅦◌〪b; a◌᷎◌̛𝅦◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING SPRECHGESANG STEM, LATIN SMALL LETTER B
+0061 1D166 302A 031B 1DCE 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062;0061 1DCE 1D166 031B 302A 0062; # (a𝅦◌〪◌̛◌᷎b; a◌᷎𝅦◌̛◌〪b; a◌᷎𝅦◌̛◌〪b; a◌᷎𝅦◌̛◌〪b; a◌᷎𝅦◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING SPRECHGESANG STEM, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 093C 0334 1D167 0062;0061 0334 1D167 093C 0062;0061 0334 1D167 093C 0062;0061 0334 1D167 093C 0062;0061 0334 1D167 093C 0062; # (a◌़◌̴◌𝅧b; a◌̴◌𝅧◌़b; a◌̴◌𝅧◌़b; a◌̴◌𝅧◌़b; a◌̴◌𝅧◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, MUSICAL SYMBOL COMBINING TREMOLO-1, LATIN SMALL LETTER B
+0061 1D167 093C 0334 0062;0061 1D167 0334 093C 0062;0061 1D167 0334 093C 0062;0061 1D167 0334 093C 0062;0061 1D167 0334 093C 0062; # (a◌𝅧◌़◌̴b; a◌𝅧◌̴◌़b; a◌𝅧◌̴◌़b; a◌𝅧◌̴◌़b; a◌𝅧◌̴◌़b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING TREMOLO-1, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 1D168 0062;0061 0334 1D168 093C 0062;0061 0334 1D168 093C 0062;0061 0334 1D168 093C 0062;0061 0334 1D168 093C 0062; # (a◌़◌̴◌𝅨b; a◌̴◌𝅨◌़b; a◌̴◌𝅨◌़b; a◌̴◌𝅨◌़b; a◌̴◌𝅨◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, MUSICAL SYMBOL COMBINING TREMOLO-2, LATIN SMALL LETTER B
+0061 1D168 093C 0334 0062;0061 1D168 0334 093C 0062;0061 1D168 0334 093C 0062;0061 1D168 0334 093C 0062;0061 1D168 0334 093C 0062; # (a◌𝅨◌़◌̴b; a◌𝅨◌̴◌़b; a◌𝅨◌̴◌़b; a◌𝅨◌̴◌़b; a◌𝅨◌̴◌़b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING TREMOLO-2, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 093C 0334 1D169 0062;0061 0334 1D169 093C 0062;0061 0334 1D169 093C 0062;0061 0334 1D169 093C 0062;0061 0334 1D169 093C 0062; # (a◌़◌̴◌𝅩b; a◌̴◌𝅩◌़b; a◌̴◌𝅩◌़b; a◌̴◌𝅩◌़b; a◌̴◌𝅩◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, MUSICAL SYMBOL COMBINING TREMOLO-3, LATIN SMALL LETTER B
+0061 1D169 093C 0334 0062;0061 1D169 0334 093C 0062;0061 1D169 0334 093C 0062;0061 1D169 0334 093C 0062;0061 1D169 0334 093C 0062; # (a◌𝅩◌़◌̴b; a◌𝅩◌̴◌़b; a◌𝅩◌̴◌़b; a◌𝅩◌̴◌़b; a◌𝅩◌̴◌़b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING TREMOLO-3, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05AE 1D16D 302E 1D16D 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062; # (a◌〮𝅭𝅭֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; ) LATIN SMALL LETTER A, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HANGUL SINGLE DOT TONE MARK, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, LATIN SMALL LETTER B
+0061 1D16D 05AE 1D16D 302E 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062;0061 302E 1D16D 1D16D 05AE 0062; # (a𝅭◌〮𝅭֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; a〮𝅭𝅭◌֮b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING AUGMENTATION DOT, HANGUL SINGLE DOT TONE MARK, LATIN SMALL LETTER B
+0061 302A 031B 1DCE 1D16E 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062;0061 1DCE 031B 1D16E 302A 0062; # (a◌〪◌̛◌᷎𝅮b; a◌᷎◌̛𝅮◌〪b; a◌᷎◌̛𝅮◌〪b; a◌᷎◌̛𝅮◌〪b; a◌᷎◌̛𝅮◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-1, LATIN SMALL LETTER B
+0061 1D16E 302A 031B 1DCE 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062;0061 1DCE 1D16E 031B 302A 0062; # (a𝅮◌〪◌̛◌᷎b; a◌᷎𝅮◌̛◌〪b; a◌᷎𝅮◌̛◌〪b; a◌᷎𝅮◌̛◌〪b; a◌᷎𝅮◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-1, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 302A 031B 1DCE 1D16F 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062;0061 1DCE 031B 1D16F 302A 0062; # (a◌〪◌̛◌᷎𝅯b; a◌᷎◌̛𝅯◌〪b; a◌᷎◌̛𝅯◌〪b; a◌᷎◌̛𝅯◌〪b; a◌᷎◌̛𝅯◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-2, LATIN SMALL LETTER B
+0061 1D16F 302A 031B 1DCE 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062;0061 1DCE 1D16F 031B 302A 0062; # (a𝅯◌〪◌̛◌᷎b; a◌᷎𝅯◌̛◌〪b; a◌᷎𝅯◌̛◌〪b; a◌᷎𝅯◌̛◌〪b; a◌᷎𝅯◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-2, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 302A 031B 1DCE 1D170 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062;0061 1DCE 031B 1D170 302A 0062; # (a◌〪◌̛◌᷎𝅰b; a◌᷎◌̛𝅰◌〪b; a◌᷎◌̛𝅰◌〪b; a◌᷎◌̛𝅰◌〪b; a◌᷎◌̛𝅰◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-3, LATIN SMALL LETTER B
+0061 1D170 302A 031B 1DCE 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062;0061 1DCE 1D170 031B 302A 0062; # (a𝅰◌〪◌̛◌᷎b; a◌᷎𝅰◌̛◌〪b; a◌᷎𝅰◌̛◌〪b; a◌᷎𝅰◌̛◌〪b; a◌᷎𝅰◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-3, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 302A 031B 1DCE 1D171 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062;0061 1DCE 031B 1D171 302A 0062; # (a◌〪◌̛◌᷎𝅱b; a◌᷎◌̛𝅱◌〪b; a◌᷎◌̛𝅱◌〪b; a◌᷎◌̛𝅱◌〪b; a◌᷎◌̛𝅱◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-4, LATIN SMALL LETTER B
+0061 1D171 302A 031B 1DCE 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062;0061 1DCE 1D171 031B 302A 0062; # (a𝅱◌〪◌̛◌᷎b; a◌᷎𝅱◌̛◌〪b; a◌᷎𝅱◌̛◌〪b; a◌᷎𝅱◌̛◌〪b; a◌᷎𝅱◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-4, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 302A 031B 1DCE 1D172 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062;0061 1DCE 031B 1D172 302A 0062; # (a◌〪◌̛◌᷎𝅲b; a◌᷎◌̛𝅲◌〪b; a◌᷎◌̛𝅲◌〪b; a◌᷎◌̛𝅲◌〪b; a◌᷎◌̛𝅲◌〪b; ) LATIN SMALL LETTER A, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, MUSICAL SYMBOL COMBINING FLAG-5, LATIN SMALL LETTER B
+0061 1D172 302A 031B 1DCE 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062;0061 1DCE 1D172 031B 302A 0062; # (a𝅲◌〪◌̛◌᷎b; a◌᷎𝅲◌̛◌〪b; a◌᷎𝅲◌̛◌〪b; a◌᷎𝅲◌̛◌〪b; a◌᷎𝅲◌̛◌〪b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLAG-5, IDEOGRAPHIC LEVEL TONE MARK, COMBINING HORN, COMBINING OGONEK ABOVE, LATIN SMALL LETTER B
+0061 059A 0316 302A 1D17B 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062;0061 302A 0316 1D17B 059A 0062; # (a◌֚◌̖◌〪◌𝅻b; a◌〪◌̖◌𝅻◌֚b; a◌〪◌̖◌𝅻◌֚b; a◌〪◌̖◌𝅻◌֚b; a◌〪◌̖◌𝅻◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING ACCENT, LATIN SMALL LETTER B
+0061 1D17B 059A 0316 302A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062;0061 302A 1D17B 0316 059A 0062; # (a◌𝅻◌֚◌̖◌〪b; a◌〪◌𝅻◌̖◌֚b; a◌〪◌𝅻◌̖◌֚b; a◌〪◌𝅻◌̖◌֚b; a◌〪◌𝅻◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING ACCENT, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1D17C 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062;0061 302A 0316 1D17C 059A 0062; # (a◌֚◌̖◌〪◌𝅼b; a◌〪◌̖◌𝅼◌֚b; a◌〪◌̖◌𝅼◌֚b; a◌〪◌̖◌𝅼◌֚b; a◌〪◌̖◌𝅼◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING STACCATO, LATIN SMALL LETTER B
+0061 1D17C 059A 0316 302A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062;0061 302A 1D17C 0316 059A 0062; # (a◌𝅼◌֚◌̖◌〪b; a◌〪◌𝅼◌̖◌֚b; a◌〪◌𝅼◌̖◌֚b; a◌〪◌𝅼◌̖◌֚b; a◌〪◌𝅼◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING STACCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1D17D 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062;0061 302A 0316 1D17D 059A 0062; # (a◌֚◌̖◌〪◌𝅽b; a◌〪◌̖◌𝅽◌֚b; a◌〪◌̖◌𝅽◌֚b; a◌〪◌̖◌𝅽◌֚b; a◌〪◌̖◌𝅽◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING TENUTO, LATIN SMALL LETTER B
+0061 1D17D 059A 0316 302A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062;0061 302A 1D17D 0316 059A 0062; # (a◌𝅽◌֚◌̖◌〪b; a◌〪◌𝅽◌̖◌֚b; a◌〪◌𝅽◌̖◌֚b; a◌〪◌𝅽◌̖◌֚b; a◌〪◌𝅽◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING TENUTO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1D17E 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062;0061 302A 0316 1D17E 059A 0062; # (a◌֚◌̖◌〪◌𝅾b; a◌〪◌̖◌𝅾◌֚b; a◌〪◌̖◌𝅾◌֚b; a◌〪◌̖◌𝅾◌֚b; a◌〪◌̖◌𝅾◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING STACCATISSIMO, LATIN SMALL LETTER B
+0061 1D17E 059A 0316 302A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062;0061 302A 1D17E 0316 059A 0062; # (a◌𝅾◌֚◌̖◌〪b; a◌〪◌𝅾◌̖◌֚b; a◌〪◌𝅾◌̖◌֚b; a◌〪◌𝅾◌̖◌֚b; a◌〪◌𝅾◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING STACCATISSIMO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1D17F 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062;0061 302A 0316 1D17F 059A 0062; # (a◌֚◌̖◌〪◌𝅿b; a◌〪◌̖◌𝅿◌֚b; a◌〪◌̖◌𝅿◌֚b; a◌〪◌̖◌𝅿◌֚b; a◌〪◌̖◌𝅿◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING MARCATO, LATIN SMALL LETTER B
+0061 1D17F 059A 0316 302A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062;0061 302A 1D17F 0316 059A 0062; # (a◌𝅿◌֚◌̖◌〪b; a◌〪◌𝅿◌̖◌֚b; a◌〪◌𝅿◌̖◌֚b; a◌〪◌𝅿◌̖◌֚b; a◌〪◌𝅿◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING MARCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1D180 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062;0061 302A 0316 1D180 059A 0062; # (a◌֚◌̖◌〪◌𝆀b; a◌〪◌̖◌𝆀◌֚b; a◌〪◌̖◌𝆀◌֚b; a◌〪◌̖◌𝆀◌֚b; a◌〪◌̖◌𝆀◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING MARCATO-STACCATO, LATIN SMALL LETTER B
+0061 1D180 059A 0316 302A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062;0061 302A 1D180 0316 059A 0062; # (a◌𝆀◌֚◌̖◌〪b; a◌〪◌𝆀◌̖◌֚b; a◌〪◌𝆀◌̖◌֚b; a◌〪◌𝆀◌̖◌֚b; a◌〪◌𝆀◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING MARCATO-STACCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1D181 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062;0061 302A 0316 1D181 059A 0062; # (a◌֚◌̖◌〪◌𝆁b; a◌〪◌̖◌𝆁◌֚b; a◌〪◌̖◌𝆁◌֚b; a◌〪◌̖◌𝆁◌֚b; a◌〪◌̖◌𝆁◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING ACCENT-STACCATO, LATIN SMALL LETTER B
+0061 1D181 059A 0316 302A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062;0061 302A 1D181 0316 059A 0062; # (a◌𝆁◌֚◌̖◌〪b; a◌〪◌𝆁◌̖◌֚b; a◌〪◌𝆁◌̖◌֚b; a◌〪◌𝆁◌̖◌֚b; a◌〪◌𝆁◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING ACCENT-STACCATO, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1D182 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062;0061 302A 0316 1D182 059A 0062; # (a◌֚◌̖◌〪◌𝆂b; a◌〪◌̖◌𝆂◌֚b; a◌〪◌̖◌𝆂◌֚b; a◌〪◌̖◌𝆂◌֚b; a◌〪◌̖◌𝆂◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING LOURE, LATIN SMALL LETTER B
+0061 1D182 059A 0316 302A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062;0061 302A 1D182 0316 059A 0062; # (a◌𝆂◌֚◌̖◌〪b; a◌〪◌𝆂◌̖◌֚b; a◌〪◌𝆂◌̖◌֚b; a◌〪◌𝆂◌̖◌֚b; a◌〪◌𝆂◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING LOURE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D185 0062;00E0 05AE 1D185 0315 0062;0061 05AE 0300 1D185 0315 0062;00E0 05AE 1D185 0315 0062;0061 05AE 0300 1D185 0315 0062; # (a◌̕◌̀◌֮◌𝆅b; à◌֮◌𝆅◌̕b; a◌֮◌̀◌𝆅◌̕b; à◌֮◌𝆅◌̕b; a◌֮◌̀◌𝆅◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING DOIT, LATIN SMALL LETTER B
+0061 1D185 0315 0300 05AE 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062;0061 05AE 1D185 0300 0315 0062; # (a◌𝆅◌̕◌̀◌֮b; a◌֮◌𝆅◌̀◌̕b; a◌֮◌𝆅◌̀◌̕b; a◌֮◌𝆅◌̀◌̕b; a◌֮◌𝆅◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING DOIT, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D186 0062;00E0 05AE 1D186 0315 0062;0061 05AE 0300 1D186 0315 0062;00E0 05AE 1D186 0315 0062;0061 05AE 0300 1D186 0315 0062; # (a◌̕◌̀◌֮◌𝆆b; à◌֮◌𝆆◌̕b; a◌֮◌̀◌𝆆◌̕b; à◌֮◌𝆆◌̕b; a◌֮◌̀◌𝆆◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING RIP, LATIN SMALL LETTER B
+0061 1D186 0315 0300 05AE 0062;0061 05AE 1D186 0300 0315 0062;0061 05AE 1D186 0300 0315 0062;0061 05AE 1D186 0300 0315 0062;0061 05AE 1D186 0300 0315 0062; # (a◌𝆆◌̕◌̀◌֮b; a◌֮◌𝆆◌̀◌̕b; a◌֮◌𝆆◌̀◌̕b; a◌֮◌𝆆◌̀◌̕b; a◌֮◌𝆆◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING RIP, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D187 0062;00E0 05AE 1D187 0315 0062;0061 05AE 0300 1D187 0315 0062;00E0 05AE 1D187 0315 0062;0061 05AE 0300 1D187 0315 0062; # (a◌̕◌̀◌֮◌𝆇b; à◌֮◌𝆇◌̕b; a◌֮◌̀◌𝆇◌̕b; à◌֮◌𝆇◌̕b; a◌֮◌̀◌𝆇◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING FLIP, LATIN SMALL LETTER B
+0061 1D187 0315 0300 05AE 0062;0061 05AE 1D187 0300 0315 0062;0061 05AE 1D187 0300 0315 0062;0061 05AE 1D187 0300 0315 0062;0061 05AE 1D187 0300 0315 0062; # (a◌𝆇◌̕◌̀◌֮b; a◌֮◌𝆇◌̀◌̕b; a◌֮◌𝆇◌̀◌̕b; a◌֮◌𝆇◌̀◌̕b; a◌֮◌𝆇◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING FLIP, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D188 0062;00E0 05AE 1D188 0315 0062;0061 05AE 0300 1D188 0315 0062;00E0 05AE 1D188 0315 0062;0061 05AE 0300 1D188 0315 0062; # (a◌̕◌̀◌֮◌𝆈b; à◌֮◌𝆈◌̕b; a◌֮◌̀◌𝆈◌̕b; à◌֮◌𝆈◌̕b; a◌֮◌̀◌𝆈◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING SMEAR, LATIN SMALL LETTER B
+0061 1D188 0315 0300 05AE 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062;0061 05AE 1D188 0300 0315 0062; # (a◌𝆈◌̕◌̀◌֮b; a◌֮◌𝆈◌̀◌̕b; a◌֮◌𝆈◌̀◌̕b; a◌֮◌𝆈◌̀◌̕b; a◌֮◌𝆈◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING SMEAR, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D189 0062;00E0 05AE 1D189 0315 0062;0061 05AE 0300 1D189 0315 0062;00E0 05AE 1D189 0315 0062;0061 05AE 0300 1D189 0315 0062; # (a◌̕◌̀◌֮◌𝆉b; à◌֮◌𝆉◌̕b; a◌֮◌̀◌𝆉◌̕b; à◌֮◌𝆉◌̕b; a◌֮◌̀◌𝆉◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING BEND, LATIN SMALL LETTER B
+0061 1D189 0315 0300 05AE 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062;0061 05AE 1D189 0300 0315 0062; # (a◌𝆉◌̕◌̀◌֮b; a◌֮◌𝆉◌̀◌̕b; a◌֮◌𝆉◌̀◌̕b; a◌֮◌𝆉◌̀◌̕b; a◌֮◌𝆉◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING BEND, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 1D18A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062;0061 302A 0316 1D18A 059A 0062; # (a◌֚◌̖◌〪◌𝆊b; a◌〪◌̖◌𝆊◌֚b; a◌〪◌̖◌𝆊◌֚b; a◌〪◌̖◌𝆊◌֚b; a◌〪◌̖◌𝆊◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING DOUBLE TONGUE, LATIN SMALL LETTER B
+0061 1D18A 059A 0316 302A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062;0061 302A 1D18A 0316 059A 0062; # (a◌𝆊◌֚◌̖◌〪b; a◌〪◌𝆊◌̖◌֚b; a◌〪◌𝆊◌̖◌֚b; a◌〪◌𝆊◌̖◌֚b; a◌〪◌𝆊◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING DOUBLE TONGUE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1D18B 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062;0061 302A 0316 1D18B 059A 0062; # (a◌֚◌̖◌〪◌𝆋b; a◌〪◌̖◌𝆋◌֚b; a◌〪◌̖◌𝆋◌֚b; a◌〪◌̖◌𝆋◌֚b; a◌〪◌̖◌𝆋◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MUSICAL SYMBOL COMBINING TRIPLE TONGUE, LATIN SMALL LETTER B
+0061 1D18B 059A 0316 302A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062;0061 302A 1D18B 0316 059A 0062; # (a◌𝆋◌֚◌̖◌〪b; a◌〪◌𝆋◌̖◌֚b; a◌〪◌𝆋◌̖◌֚b; a◌〪◌𝆋◌̖◌֚b; a◌〪◌𝆋◌̖◌֚b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING TRIPLE TONGUE, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D1AA 0062;00E0 05AE 1D1AA 0315 0062;0061 05AE 0300 1D1AA 0315 0062;00E0 05AE 1D1AA 0315 0062;0061 05AE 0300 1D1AA 0315 0062; # (a◌̕◌̀◌֮◌𝆪b; à◌֮◌𝆪◌̕b; a◌֮◌̀◌𝆪◌̕b; à◌֮◌𝆪◌̕b; a◌֮◌̀◌𝆪◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING DOWN BOW, LATIN SMALL LETTER B
+0061 1D1AA 0315 0300 05AE 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062;0061 05AE 1D1AA 0300 0315 0062; # (a◌𝆪◌̕◌̀◌֮b; a◌֮◌𝆪◌̀◌̕b; a◌֮◌𝆪◌̀◌̕b; a◌֮◌𝆪◌̀◌̕b; a◌֮◌𝆪◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING DOWN BOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D1AB 0062;00E0 05AE 1D1AB 0315 0062;0061 05AE 0300 1D1AB 0315 0062;00E0 05AE 1D1AB 0315 0062;0061 05AE 0300 1D1AB 0315 0062; # (a◌̕◌̀◌֮◌𝆫b; à◌֮◌𝆫◌̕b; a◌֮◌̀◌𝆫◌̕b; à◌֮◌𝆫◌̕b; a◌֮◌̀◌𝆫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING UP BOW, LATIN SMALL LETTER B
+0061 1D1AB 0315 0300 05AE 0062;0061 05AE 1D1AB 0300 0315 0062;0061 05AE 1D1AB 0300 0315 0062;0061 05AE 1D1AB 0300 0315 0062;0061 05AE 1D1AB 0300 0315 0062; # (a◌𝆫◌̕◌̀◌֮b; a◌֮◌𝆫◌̀◌̕b; a◌֮◌𝆫◌̀◌̕b; a◌֮◌𝆫◌̀◌̕b; a◌֮◌𝆫◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING UP BOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D1AC 0062;00E0 05AE 1D1AC 0315 0062;0061 05AE 0300 1D1AC 0315 0062;00E0 05AE 1D1AC 0315 0062;0061 05AE 0300 1D1AC 0315 0062; # (a◌̕◌̀◌֮◌𝆬b; à◌֮◌𝆬◌̕b; a◌֮◌̀◌𝆬◌̕b; à◌֮◌𝆬◌̕b; a◌֮◌̀◌𝆬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING HARMONIC, LATIN SMALL LETTER B
+0061 1D1AC 0315 0300 05AE 0062;0061 05AE 1D1AC 0300 0315 0062;0061 05AE 1D1AC 0300 0315 0062;0061 05AE 1D1AC 0300 0315 0062;0061 05AE 1D1AC 0300 0315 0062; # (a◌𝆬◌̕◌̀◌֮b; a◌֮◌𝆬◌̀◌̕b; a◌֮◌𝆬◌̀◌̕b; a◌֮◌𝆬◌̀◌̕b; a◌֮◌𝆬◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING HARMONIC, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D1AD 0062;00E0 05AE 1D1AD 0315 0062;0061 05AE 0300 1D1AD 0315 0062;00E0 05AE 1D1AD 0315 0062;0061 05AE 0300 1D1AD 0315 0062; # (a◌̕◌̀◌֮◌𝆭b; à◌֮◌𝆭◌̕b; a◌֮◌̀◌𝆭◌̕b; à◌֮◌𝆭◌̕b; a◌֮◌̀◌𝆭◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING SNAP PIZZICATO, LATIN SMALL LETTER B
+0061 1D1AD 0315 0300 05AE 0062;0061 05AE 1D1AD 0300 0315 0062;0061 05AE 1D1AD 0300 0315 0062;0061 05AE 1D1AD 0300 0315 0062;0061 05AE 1D1AD 0300 0315 0062; # (a◌𝆭◌̕◌̀◌֮b; a◌֮◌𝆭◌̀◌̕b; a◌֮◌𝆭◌̀◌̕b; a◌֮◌𝆭◌̀◌̕b; a◌֮◌𝆭◌̀◌̕b; ) LATIN SMALL LETTER A, MUSICAL SYMBOL COMBINING SNAP PIZZICATO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D242 0062;00E0 05AE 1D242 0315 0062;0061 05AE 0300 1D242 0315 0062;00E0 05AE 1D242 0315 0062;0061 05AE 0300 1D242 0315 0062; # (a◌̕◌̀◌֮◌𝉂b; à◌֮◌𝉂◌̕b; a◌֮◌̀◌𝉂◌̕b; à◌֮◌𝉂◌̕b; a◌֮◌̀◌𝉂◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GREEK MUSICAL TRISEME, LATIN SMALL LETTER B
+0061 1D242 0315 0300 05AE 0062;0061 05AE 1D242 0300 0315 0062;0061 05AE 1D242 0300 0315 0062;0061 05AE 1D242 0300 0315 0062;0061 05AE 1D242 0300 0315 0062; # (a◌𝉂◌̕◌̀◌֮b; a◌֮◌𝉂◌̀◌̕b; a◌֮◌𝉂◌̀◌̕b; a◌֮◌𝉂◌̀◌̕b; a◌֮◌𝉂◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GREEK MUSICAL TRISEME, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D243 0062;00E0 05AE 1D243 0315 0062;0061 05AE 0300 1D243 0315 0062;00E0 05AE 1D243 0315 0062;0061 05AE 0300 1D243 0315 0062; # (a◌̕◌̀◌֮◌𝉃b; à◌֮◌𝉃◌̕b; a◌֮◌̀◌𝉃◌̕b; à◌֮◌𝉃◌̕b; a◌֮◌̀◌𝉃◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GREEK MUSICAL TETRASEME, LATIN SMALL LETTER B
+0061 1D243 0315 0300 05AE 0062;0061 05AE 1D243 0300 0315 0062;0061 05AE 1D243 0300 0315 0062;0061 05AE 1D243 0300 0315 0062;0061 05AE 1D243 0300 0315 0062; # (a◌𝉃◌̕◌̀◌֮b; a◌֮◌𝉃◌̀◌̕b; a◌֮◌𝉃◌̀◌̕b; a◌֮◌𝉃◌̀◌̕b; a◌֮◌𝉃◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GREEK MUSICAL TETRASEME, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1D244 0062;00E0 05AE 1D244 0315 0062;0061 05AE 0300 1D244 0315 0062;00E0 05AE 1D244 0315 0062;0061 05AE 0300 1D244 0315 0062; # (a◌̕◌̀◌֮◌𝉄b; à◌֮◌𝉄◌̕b; a◌֮◌̀◌𝉄◌̕b; à◌֮◌𝉄◌̕b; a◌֮◌̀◌𝉄◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GREEK MUSICAL PENTASEME, LATIN SMALL LETTER B
+0061 1D244 0315 0300 05AE 0062;0061 05AE 1D244 0300 0315 0062;0061 05AE 1D244 0300 0315 0062;0061 05AE 1D244 0300 0315 0062;0061 05AE 1D244 0300 0315 0062; # (a◌𝉄◌̕◌̀◌֮b; a◌֮◌𝉄◌̀◌̕b; a◌֮◌𝉄◌̀◌̕b; a◌֮◌𝉄◌̀◌̕b; a◌֮◌𝉄◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GREEK MUSICAL PENTASEME, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E000 0062;00E0 05AE 1E000 0315 0062;0061 05AE 0300 1E000 0315 0062;00E0 05AE 1E000 0315 0062;0061 05AE 0300 1E000 0315 0062; # (a◌̕◌̀◌֮◌𞀀b; à◌֮◌𞀀◌̕b; a◌֮◌̀◌𞀀◌̕b; à◌֮◌𞀀◌̕b; a◌֮◌̀◌𞀀◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER AZU, LATIN SMALL LETTER B
+0061 1E000 0315 0300 05AE 0062;0061 05AE 1E000 0300 0315 0062;0061 05AE 1E000 0300 0315 0062;0061 05AE 1E000 0300 0315 0062;0061 05AE 1E000 0300 0315 0062; # (a◌𞀀◌̕◌̀◌֮b; a◌֮◌𞀀◌̀◌̕b; a◌֮◌𞀀◌̀◌̕b; a◌֮◌𞀀◌̀◌̕b; a◌֮◌𞀀◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER AZU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E001 0062;00E0 05AE 1E001 0315 0062;0061 05AE 0300 1E001 0315 0062;00E0 05AE 1E001 0315 0062;0061 05AE 0300 1E001 0315 0062; # (a◌̕◌̀◌֮◌𞀁b; à◌֮◌𞀁◌̕b; a◌֮◌̀◌𞀁◌̕b; à◌֮◌𞀁◌̕b; a◌֮◌̀◌𞀁◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER BUKY, LATIN SMALL LETTER B
+0061 1E001 0315 0300 05AE 0062;0061 05AE 1E001 0300 0315 0062;0061 05AE 1E001 0300 0315 0062;0061 05AE 1E001 0300 0315 0062;0061 05AE 1E001 0300 0315 0062; # (a◌𞀁◌̕◌̀◌֮b; a◌֮◌𞀁◌̀◌̕b; a◌֮◌𞀁◌̀◌̕b; a◌֮◌𞀁◌̀◌̕b; a◌֮◌𞀁◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER BUKY, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E002 0062;00E0 05AE 1E002 0315 0062;0061 05AE 0300 1E002 0315 0062;00E0 05AE 1E002 0315 0062;0061 05AE 0300 1E002 0315 0062; # (a◌̕◌̀◌֮◌𞀂b; à◌֮◌𞀂◌̕b; a◌֮◌̀◌𞀂◌̕b; à◌֮◌𞀂◌̕b; a◌֮◌̀◌𞀂◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER VEDE, LATIN SMALL LETTER B
+0061 1E002 0315 0300 05AE 0062;0061 05AE 1E002 0300 0315 0062;0061 05AE 1E002 0300 0315 0062;0061 05AE 1E002 0300 0315 0062;0061 05AE 1E002 0300 0315 0062; # (a◌𞀂◌̕◌̀◌֮b; a◌֮◌𞀂◌̀◌̕b; a◌֮◌𞀂◌̀◌̕b; a◌֮◌𞀂◌̀◌̕b; a◌֮◌𞀂◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER VEDE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E003 0062;00E0 05AE 1E003 0315 0062;0061 05AE 0300 1E003 0315 0062;00E0 05AE 1E003 0315 0062;0061 05AE 0300 1E003 0315 0062; # (a◌̕◌̀◌֮◌𞀃b; à◌֮◌𞀃◌̕b; a◌֮◌̀◌𞀃◌̕b; à◌֮◌𞀃◌̕b; a◌֮◌̀◌𞀃◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER GLAGOLI, LATIN SMALL LETTER B
+0061 1E003 0315 0300 05AE 0062;0061 05AE 1E003 0300 0315 0062;0061 05AE 1E003 0300 0315 0062;0061 05AE 1E003 0300 0315 0062;0061 05AE 1E003 0300 0315 0062; # (a◌𞀃◌̕◌̀◌֮b; a◌֮◌𞀃◌̀◌̕b; a◌֮◌𞀃◌̀◌̕b; a◌֮◌𞀃◌̀◌̕b; a◌֮◌𞀃◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER GLAGOLI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E004 0062;00E0 05AE 1E004 0315 0062;0061 05AE 0300 1E004 0315 0062;00E0 05AE 1E004 0315 0062;0061 05AE 0300 1E004 0315 0062; # (a◌̕◌̀◌֮◌𞀄b; à◌֮◌𞀄◌̕b; a◌֮◌̀◌𞀄◌̕b; à◌֮◌𞀄◌̕b; a◌֮◌̀◌𞀄◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER DOBRO, LATIN SMALL LETTER B
+0061 1E004 0315 0300 05AE 0062;0061 05AE 1E004 0300 0315 0062;0061 05AE 1E004 0300 0315 0062;0061 05AE 1E004 0300 0315 0062;0061 05AE 1E004 0300 0315 0062; # (a◌𞀄◌̕◌̀◌֮b; a◌֮◌𞀄◌̀◌̕b; a◌֮◌𞀄◌̀◌̕b; a◌֮◌𞀄◌̀◌̕b; a◌֮◌𞀄◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER DOBRO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E005 0062;00E0 05AE 1E005 0315 0062;0061 05AE 0300 1E005 0315 0062;00E0 05AE 1E005 0315 0062;0061 05AE 0300 1E005 0315 0062; # (a◌̕◌̀◌֮◌𞀅b; à◌֮◌𞀅◌̕b; a◌֮◌̀◌𞀅◌̕b; à◌֮◌𞀅◌̕b; a◌֮◌̀◌𞀅◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER YESTU, LATIN SMALL LETTER B
+0061 1E005 0315 0300 05AE 0062;0061 05AE 1E005 0300 0315 0062;0061 05AE 1E005 0300 0315 0062;0061 05AE 1E005 0300 0315 0062;0061 05AE 1E005 0300 0315 0062; # (a◌𞀅◌̕◌̀◌֮b; a◌֮◌𞀅◌̀◌̕b; a◌֮◌𞀅◌̀◌̕b; a◌֮◌𞀅◌̀◌̕b; a◌֮◌𞀅◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER YESTU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E006 0062;00E0 05AE 1E006 0315 0062;0061 05AE 0300 1E006 0315 0062;00E0 05AE 1E006 0315 0062;0061 05AE 0300 1E006 0315 0062; # (a◌̕◌̀◌֮◌𞀆b; à◌֮◌𞀆◌̕b; a◌֮◌̀◌𞀆◌̕b; à◌֮◌𞀆◌̕b; a◌֮◌̀◌𞀆◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER ZHIVETE, LATIN SMALL LETTER B
+0061 1E006 0315 0300 05AE 0062;0061 05AE 1E006 0300 0315 0062;0061 05AE 1E006 0300 0315 0062;0061 05AE 1E006 0300 0315 0062;0061 05AE 1E006 0300 0315 0062; # (a◌𞀆◌̕◌̀◌֮b; a◌֮◌𞀆◌̀◌̕b; a◌֮◌𞀆◌̀◌̕b; a◌֮◌𞀆◌̀◌̕b; a◌֮◌𞀆◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER ZHIVETE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E008 0062;00E0 05AE 1E008 0315 0062;0061 05AE 0300 1E008 0315 0062;00E0 05AE 1E008 0315 0062;0061 05AE 0300 1E008 0315 0062; # (a◌̕◌̀◌֮◌𞀈b; à◌֮◌𞀈◌̕b; a◌֮◌̀◌𞀈◌̕b; à◌֮◌𞀈◌̕b; a◌֮◌̀◌𞀈◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER ZEMLJA, LATIN SMALL LETTER B
+0061 1E008 0315 0300 05AE 0062;0061 05AE 1E008 0300 0315 0062;0061 05AE 1E008 0300 0315 0062;0061 05AE 1E008 0300 0315 0062;0061 05AE 1E008 0300 0315 0062; # (a◌𞀈◌̕◌̀◌֮b; a◌֮◌𞀈◌̀◌̕b; a◌֮◌𞀈◌̀◌̕b; a◌֮◌𞀈◌̀◌̕b; a◌֮◌𞀈◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER ZEMLJA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E009 0062;00E0 05AE 1E009 0315 0062;0061 05AE 0300 1E009 0315 0062;00E0 05AE 1E009 0315 0062;0061 05AE 0300 1E009 0315 0062; # (a◌̕◌̀◌֮◌𞀉b; à◌֮◌𞀉◌̕b; a◌֮◌̀◌𞀉◌̕b; à◌֮◌𞀉◌̕b; a◌֮◌̀◌𞀉◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER IZHE, LATIN SMALL LETTER B
+0061 1E009 0315 0300 05AE 0062;0061 05AE 1E009 0300 0315 0062;0061 05AE 1E009 0300 0315 0062;0061 05AE 1E009 0300 0315 0062;0061 05AE 1E009 0300 0315 0062; # (a◌𞀉◌̕◌̀◌֮b; a◌֮◌𞀉◌̀◌̕b; a◌֮◌𞀉◌̀◌̕b; a◌֮◌𞀉◌̀◌̕b; a◌֮◌𞀉◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER IZHE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E00A 0062;00E0 05AE 1E00A 0315 0062;0061 05AE 0300 1E00A 0315 0062;00E0 05AE 1E00A 0315 0062;0061 05AE 0300 1E00A 0315 0062; # (a◌̕◌̀◌֮◌𞀊b; à◌֮◌𞀊◌̕b; a◌֮◌̀◌𞀊◌̕b; à◌֮◌𞀊◌̕b; a◌֮◌̀◌𞀊◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER INITIAL IZHE, LATIN SMALL LETTER B
+0061 1E00A 0315 0300 05AE 0062;0061 05AE 1E00A 0300 0315 0062;0061 05AE 1E00A 0300 0315 0062;0061 05AE 1E00A 0300 0315 0062;0061 05AE 1E00A 0300 0315 0062; # (a◌𞀊◌̕◌̀◌֮b; a◌֮◌𞀊◌̀◌̕b; a◌֮◌𞀊◌̀◌̕b; a◌֮◌𞀊◌̀◌̕b; a◌֮◌𞀊◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER INITIAL IZHE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E00B 0062;00E0 05AE 1E00B 0315 0062;0061 05AE 0300 1E00B 0315 0062;00E0 05AE 1E00B 0315 0062;0061 05AE 0300 1E00B 0315 0062; # (a◌̕◌̀◌֮◌𞀋b; à◌֮◌𞀋◌̕b; a◌֮◌̀◌𞀋◌̕b; à◌֮◌𞀋◌̕b; a◌֮◌̀◌𞀋◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER I, LATIN SMALL LETTER B
+0061 1E00B 0315 0300 05AE 0062;0061 05AE 1E00B 0300 0315 0062;0061 05AE 1E00B 0300 0315 0062;0061 05AE 1E00B 0300 0315 0062;0061 05AE 1E00B 0300 0315 0062; # (a◌𞀋◌̕◌̀◌֮b; a◌֮◌𞀋◌̀◌̕b; a◌֮◌𞀋◌̀◌̕b; a◌֮◌𞀋◌̀◌̕b; a◌֮◌𞀋◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER I, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E00C 0062;00E0 05AE 1E00C 0315 0062;0061 05AE 0300 1E00C 0315 0062;00E0 05AE 1E00C 0315 0062;0061 05AE 0300 1E00C 0315 0062; # (a◌̕◌̀◌֮◌𞀌b; à◌֮◌𞀌◌̕b; a◌֮◌̀◌𞀌◌̕b; à◌֮◌𞀌◌̕b; a◌֮◌̀◌𞀌◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER DJERVI, LATIN SMALL LETTER B
+0061 1E00C 0315 0300 05AE 0062;0061 05AE 1E00C 0300 0315 0062;0061 05AE 1E00C 0300 0315 0062;0061 05AE 1E00C 0300 0315 0062;0061 05AE 1E00C 0300 0315 0062; # (a◌𞀌◌̕◌̀◌֮b; a◌֮◌𞀌◌̀◌̕b; a◌֮◌𞀌◌̀◌̕b; a◌֮◌𞀌◌̀◌̕b; a◌֮◌𞀌◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER DJERVI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E00D 0062;00E0 05AE 1E00D 0315 0062;0061 05AE 0300 1E00D 0315 0062;00E0 05AE 1E00D 0315 0062;0061 05AE 0300 1E00D 0315 0062; # (a◌̕◌̀◌֮◌𞀍b; à◌֮◌𞀍◌̕b; a◌֮◌̀◌𞀍◌̕b; à◌֮◌𞀍◌̕b; a◌֮◌̀◌𞀍◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER KAKO, LATIN SMALL LETTER B
+0061 1E00D 0315 0300 05AE 0062;0061 05AE 1E00D 0300 0315 0062;0061 05AE 1E00D 0300 0315 0062;0061 05AE 1E00D 0300 0315 0062;0061 05AE 1E00D 0300 0315 0062; # (a◌𞀍◌̕◌̀◌֮b; a◌֮◌𞀍◌̀◌̕b; a◌֮◌𞀍◌̀◌̕b; a◌֮◌𞀍◌̀◌̕b; a◌֮◌𞀍◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER KAKO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E00E 0062;00E0 05AE 1E00E 0315 0062;0061 05AE 0300 1E00E 0315 0062;00E0 05AE 1E00E 0315 0062;0061 05AE 0300 1E00E 0315 0062; # (a◌̕◌̀◌֮◌𞀎b; à◌֮◌𞀎◌̕b; a◌֮◌̀◌𞀎◌̕b; à◌֮◌𞀎◌̕b; a◌֮◌̀◌𞀎◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER LJUDIJE, LATIN SMALL LETTER B
+0061 1E00E 0315 0300 05AE 0062;0061 05AE 1E00E 0300 0315 0062;0061 05AE 1E00E 0300 0315 0062;0061 05AE 1E00E 0300 0315 0062;0061 05AE 1E00E 0300 0315 0062; # (a◌𞀎◌̕◌̀◌֮b; a◌֮◌𞀎◌̀◌̕b; a◌֮◌𞀎◌̀◌̕b; a◌֮◌𞀎◌̀◌̕b; a◌֮◌𞀎◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER LJUDIJE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E00F 0062;00E0 05AE 1E00F 0315 0062;0061 05AE 0300 1E00F 0315 0062;00E0 05AE 1E00F 0315 0062;0061 05AE 0300 1E00F 0315 0062; # (a◌̕◌̀◌֮◌𞀏b; à◌֮◌𞀏◌̕b; a◌֮◌̀◌𞀏◌̕b; à◌֮◌𞀏◌̕b; a◌֮◌̀◌𞀏◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER MYSLITE, LATIN SMALL LETTER B
+0061 1E00F 0315 0300 05AE 0062;0061 05AE 1E00F 0300 0315 0062;0061 05AE 1E00F 0300 0315 0062;0061 05AE 1E00F 0300 0315 0062;0061 05AE 1E00F 0300 0315 0062; # (a◌𞀏◌̕◌̀◌֮b; a◌֮◌𞀏◌̀◌̕b; a◌֮◌𞀏◌̀◌̕b; a◌֮◌𞀏◌̀◌̕b; a◌֮◌𞀏◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER MYSLITE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E010 0062;00E0 05AE 1E010 0315 0062;0061 05AE 0300 1E010 0315 0062;00E0 05AE 1E010 0315 0062;0061 05AE 0300 1E010 0315 0062; # (a◌̕◌̀◌֮◌𞀐b; à◌֮◌𞀐◌̕b; a◌֮◌̀◌𞀐◌̕b; à◌֮◌𞀐◌̕b; a◌֮◌̀◌𞀐◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER NASHI, LATIN SMALL LETTER B
+0061 1E010 0315 0300 05AE 0062;0061 05AE 1E010 0300 0315 0062;0061 05AE 1E010 0300 0315 0062;0061 05AE 1E010 0300 0315 0062;0061 05AE 1E010 0300 0315 0062; # (a◌𞀐◌̕◌̀◌֮b; a◌֮◌𞀐◌̀◌̕b; a◌֮◌𞀐◌̀◌̕b; a◌֮◌𞀐◌̀◌̕b; a◌֮◌𞀐◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER NASHI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E011 0062;00E0 05AE 1E011 0315 0062;0061 05AE 0300 1E011 0315 0062;00E0 05AE 1E011 0315 0062;0061 05AE 0300 1E011 0315 0062; # (a◌̕◌̀◌֮◌𞀑b; à◌֮◌𞀑◌̕b; a◌֮◌̀◌𞀑◌̕b; à◌֮◌𞀑◌̕b; a◌֮◌̀◌𞀑◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER ONU, LATIN SMALL LETTER B
+0061 1E011 0315 0300 05AE 0062;0061 05AE 1E011 0300 0315 0062;0061 05AE 1E011 0300 0315 0062;0061 05AE 1E011 0300 0315 0062;0061 05AE 1E011 0300 0315 0062; # (a◌𞀑◌̕◌̀◌֮b; a◌֮◌𞀑◌̀◌̕b; a◌֮◌𞀑◌̀◌̕b; a◌֮◌𞀑◌̀◌̕b; a◌֮◌𞀑◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER ONU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E012 0062;00E0 05AE 1E012 0315 0062;0061 05AE 0300 1E012 0315 0062;00E0 05AE 1E012 0315 0062;0061 05AE 0300 1E012 0315 0062; # (a◌̕◌̀◌֮◌𞀒b; à◌֮◌𞀒◌̕b; a◌֮◌̀◌𞀒◌̕b; à◌֮◌𞀒◌̕b; a◌֮◌̀◌𞀒◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER POKOJI, LATIN SMALL LETTER B
+0061 1E012 0315 0300 05AE 0062;0061 05AE 1E012 0300 0315 0062;0061 05AE 1E012 0300 0315 0062;0061 05AE 1E012 0300 0315 0062;0061 05AE 1E012 0300 0315 0062; # (a◌𞀒◌̕◌̀◌֮b; a◌֮◌𞀒◌̀◌̕b; a◌֮◌𞀒◌̀◌̕b; a◌֮◌𞀒◌̀◌̕b; a◌֮◌𞀒◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER POKOJI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E013 0062;00E0 05AE 1E013 0315 0062;0061 05AE 0300 1E013 0315 0062;00E0 05AE 1E013 0315 0062;0061 05AE 0300 1E013 0315 0062; # (a◌̕◌̀◌֮◌𞀓b; à◌֮◌𞀓◌̕b; a◌֮◌̀◌𞀓◌̕b; à◌֮◌𞀓◌̕b; a◌֮◌̀◌𞀓◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER RITSI, LATIN SMALL LETTER B
+0061 1E013 0315 0300 05AE 0062;0061 05AE 1E013 0300 0315 0062;0061 05AE 1E013 0300 0315 0062;0061 05AE 1E013 0300 0315 0062;0061 05AE 1E013 0300 0315 0062; # (a◌𞀓◌̕◌̀◌֮b; a◌֮◌𞀓◌̀◌̕b; a◌֮◌𞀓◌̀◌̕b; a◌֮◌𞀓◌̀◌̕b; a◌֮◌𞀓◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER RITSI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E014 0062;00E0 05AE 1E014 0315 0062;0061 05AE 0300 1E014 0315 0062;00E0 05AE 1E014 0315 0062;0061 05AE 0300 1E014 0315 0062; # (a◌̕◌̀◌֮◌𞀔b; à◌֮◌𞀔◌̕b; a◌֮◌̀◌𞀔◌̕b; à◌֮◌𞀔◌̕b; a◌֮◌̀◌𞀔◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER SLOVO, LATIN SMALL LETTER B
+0061 1E014 0315 0300 05AE 0062;0061 05AE 1E014 0300 0315 0062;0061 05AE 1E014 0300 0315 0062;0061 05AE 1E014 0300 0315 0062;0061 05AE 1E014 0300 0315 0062; # (a◌𞀔◌̕◌̀◌֮b; a◌֮◌𞀔◌̀◌̕b; a◌֮◌𞀔◌̀◌̕b; a◌֮◌𞀔◌̀◌̕b; a◌֮◌𞀔◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER SLOVO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E015 0062;00E0 05AE 1E015 0315 0062;0061 05AE 0300 1E015 0315 0062;00E0 05AE 1E015 0315 0062;0061 05AE 0300 1E015 0315 0062; # (a◌̕◌̀◌֮◌𞀕b; à◌֮◌𞀕◌̕b; a◌֮◌̀◌𞀕◌̕b; à◌֮◌𞀕◌̕b; a◌֮◌̀◌𞀕◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER TVRIDO, LATIN SMALL LETTER B
+0061 1E015 0315 0300 05AE 0062;0061 05AE 1E015 0300 0315 0062;0061 05AE 1E015 0300 0315 0062;0061 05AE 1E015 0300 0315 0062;0061 05AE 1E015 0300 0315 0062; # (a◌𞀕◌̕◌̀◌֮b; a◌֮◌𞀕◌̀◌̕b; a◌֮◌𞀕◌̀◌̕b; a◌֮◌𞀕◌̀◌̕b; a◌֮◌𞀕◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER TVRIDO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E016 0062;00E0 05AE 1E016 0315 0062;0061 05AE 0300 1E016 0315 0062;00E0 05AE 1E016 0315 0062;0061 05AE 0300 1E016 0315 0062; # (a◌̕◌̀◌֮◌𞀖b; à◌֮◌𞀖◌̕b; a◌֮◌̀◌𞀖◌̕b; à◌֮◌𞀖◌̕b; a◌֮◌̀◌𞀖◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER UKU, LATIN SMALL LETTER B
+0061 1E016 0315 0300 05AE 0062;0061 05AE 1E016 0300 0315 0062;0061 05AE 1E016 0300 0315 0062;0061 05AE 1E016 0300 0315 0062;0061 05AE 1E016 0300 0315 0062; # (a◌𞀖◌̕◌̀◌֮b; a◌֮◌𞀖◌̀◌̕b; a◌֮◌𞀖◌̀◌̕b; a◌֮◌𞀖◌̀◌̕b; a◌֮◌𞀖◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER UKU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E017 0062;00E0 05AE 1E017 0315 0062;0061 05AE 0300 1E017 0315 0062;00E0 05AE 1E017 0315 0062;0061 05AE 0300 1E017 0315 0062; # (a◌̕◌̀◌֮◌𞀗b; à◌֮◌𞀗◌̕b; a◌֮◌̀◌𞀗◌̕b; à◌֮◌𞀗◌̕b; a◌֮◌̀◌𞀗◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER FRITU, LATIN SMALL LETTER B
+0061 1E017 0315 0300 05AE 0062;0061 05AE 1E017 0300 0315 0062;0061 05AE 1E017 0300 0315 0062;0061 05AE 1E017 0300 0315 0062;0061 05AE 1E017 0300 0315 0062; # (a◌𞀗◌̕◌̀◌֮b; a◌֮◌𞀗◌̀◌̕b; a◌֮◌𞀗◌̀◌̕b; a◌֮◌𞀗◌̀◌̕b; a◌֮◌𞀗◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER FRITU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E018 0062;00E0 05AE 1E018 0315 0062;0061 05AE 0300 1E018 0315 0062;00E0 05AE 1E018 0315 0062;0061 05AE 0300 1E018 0315 0062; # (a◌̕◌̀◌֮◌𞀘b; à◌֮◌𞀘◌̕b; a◌֮◌̀◌𞀘◌̕b; à◌֮◌𞀘◌̕b; a◌֮◌̀◌𞀘◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER HERU, LATIN SMALL LETTER B
+0061 1E018 0315 0300 05AE 0062;0061 05AE 1E018 0300 0315 0062;0061 05AE 1E018 0300 0315 0062;0061 05AE 1E018 0300 0315 0062;0061 05AE 1E018 0300 0315 0062; # (a◌𞀘◌̕◌̀◌֮b; a◌֮◌𞀘◌̀◌̕b; a◌֮◌𞀘◌̀◌̕b; a◌֮◌𞀘◌̀◌̕b; a◌֮◌𞀘◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER HERU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E01B 0062;00E0 05AE 1E01B 0315 0062;0061 05AE 0300 1E01B 0315 0062;00E0 05AE 1E01B 0315 0062;0061 05AE 0300 1E01B 0315 0062; # (a◌̕◌̀◌֮◌𞀛b; à◌֮◌𞀛◌̕b; a◌֮◌̀◌𞀛◌̕b; à◌֮◌𞀛◌̕b; a◌֮◌̀◌𞀛◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER SHTA, LATIN SMALL LETTER B
+0061 1E01B 0315 0300 05AE 0062;0061 05AE 1E01B 0300 0315 0062;0061 05AE 1E01B 0300 0315 0062;0061 05AE 1E01B 0300 0315 0062;0061 05AE 1E01B 0300 0315 0062; # (a◌𞀛◌̕◌̀◌֮b; a◌֮◌𞀛◌̀◌̕b; a◌֮◌𞀛◌̀◌̕b; a◌֮◌𞀛◌̀◌̕b; a◌֮◌𞀛◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER SHTA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E01C 0062;00E0 05AE 1E01C 0315 0062;0061 05AE 0300 1E01C 0315 0062;00E0 05AE 1E01C 0315 0062;0061 05AE 0300 1E01C 0315 0062; # (a◌̕◌̀◌֮◌𞀜b; à◌֮◌𞀜◌̕b; a◌֮◌̀◌𞀜◌̕b; à◌֮◌𞀜◌̕b; a◌֮◌̀◌𞀜◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER TSI, LATIN SMALL LETTER B
+0061 1E01C 0315 0300 05AE 0062;0061 05AE 1E01C 0300 0315 0062;0061 05AE 1E01C 0300 0315 0062;0061 05AE 1E01C 0300 0315 0062;0061 05AE 1E01C 0300 0315 0062; # (a◌𞀜◌̕◌̀◌֮b; a◌֮◌𞀜◌̀◌̕b; a◌֮◌𞀜◌̀◌̕b; a◌֮◌𞀜◌̀◌̕b; a◌֮◌𞀜◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER TSI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E01D 0062;00E0 05AE 1E01D 0315 0062;0061 05AE 0300 1E01D 0315 0062;00E0 05AE 1E01D 0315 0062;0061 05AE 0300 1E01D 0315 0062; # (a◌̕◌̀◌֮◌𞀝b; à◌֮◌𞀝◌̕b; a◌֮◌̀◌𞀝◌̕b; à◌֮◌𞀝◌̕b; a◌֮◌̀◌𞀝◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER CHRIVI, LATIN SMALL LETTER B
+0061 1E01D 0315 0300 05AE 0062;0061 05AE 1E01D 0300 0315 0062;0061 05AE 1E01D 0300 0315 0062;0061 05AE 1E01D 0300 0315 0062;0061 05AE 1E01D 0300 0315 0062; # (a◌𞀝◌̕◌̀◌֮b; a◌֮◌𞀝◌̀◌̕b; a◌֮◌𞀝◌̀◌̕b; a◌֮◌𞀝◌̀◌̕b; a◌֮◌𞀝◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER CHRIVI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E01E 0062;00E0 05AE 1E01E 0315 0062;0061 05AE 0300 1E01E 0315 0062;00E0 05AE 1E01E 0315 0062;0061 05AE 0300 1E01E 0315 0062; # (a◌̕◌̀◌֮◌𞀞b; à◌֮◌𞀞◌̕b; a◌֮◌̀◌𞀞◌̕b; à◌֮◌𞀞◌̕b; a◌֮◌̀◌𞀞◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER SHA, LATIN SMALL LETTER B
+0061 1E01E 0315 0300 05AE 0062;0061 05AE 1E01E 0300 0315 0062;0061 05AE 1E01E 0300 0315 0062;0061 05AE 1E01E 0300 0315 0062;0061 05AE 1E01E 0300 0315 0062; # (a◌𞀞◌̕◌̀◌֮b; a◌֮◌𞀞◌̀◌̕b; a◌֮◌𞀞◌̀◌̕b; a◌֮◌𞀞◌̀◌̕b; a◌֮◌𞀞◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER SHA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E01F 0062;00E0 05AE 1E01F 0315 0062;0061 05AE 0300 1E01F 0315 0062;00E0 05AE 1E01F 0315 0062;0061 05AE 0300 1E01F 0315 0062; # (a◌̕◌̀◌֮◌𞀟b; à◌֮◌𞀟◌̕b; a◌֮◌̀◌𞀟◌̕b; à◌֮◌𞀟◌̕b; a◌֮◌̀◌𞀟◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER YERU, LATIN SMALL LETTER B
+0061 1E01F 0315 0300 05AE 0062;0061 05AE 1E01F 0300 0315 0062;0061 05AE 1E01F 0300 0315 0062;0061 05AE 1E01F 0300 0315 0062;0061 05AE 1E01F 0300 0315 0062; # (a◌𞀟◌̕◌̀◌֮b; a◌֮◌𞀟◌̀◌̕b; a◌֮◌𞀟◌̀◌̕b; a◌֮◌𞀟◌̀◌̕b; a◌֮◌𞀟◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER YERU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E020 0062;00E0 05AE 1E020 0315 0062;0061 05AE 0300 1E020 0315 0062;00E0 05AE 1E020 0315 0062;0061 05AE 0300 1E020 0315 0062; # (a◌̕◌̀◌֮◌𞀠b; à◌֮◌𞀠◌̕b; a◌֮◌̀◌𞀠◌̕b; à◌֮◌𞀠◌̕b; a◌֮◌̀◌𞀠◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER YERI, LATIN SMALL LETTER B
+0061 1E020 0315 0300 05AE 0062;0061 05AE 1E020 0300 0315 0062;0061 05AE 1E020 0300 0315 0062;0061 05AE 1E020 0300 0315 0062;0061 05AE 1E020 0300 0315 0062; # (a◌𞀠◌̕◌̀◌֮b; a◌֮◌𞀠◌̀◌̕b; a◌֮◌𞀠◌̀◌̕b; a◌֮◌𞀠◌̀◌̕b; a◌֮◌𞀠◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER YERI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E021 0062;00E0 05AE 1E021 0315 0062;0061 05AE 0300 1E021 0315 0062;00E0 05AE 1E021 0315 0062;0061 05AE 0300 1E021 0315 0062; # (a◌̕◌̀◌֮◌𞀡b; à◌֮◌𞀡◌̕b; a◌֮◌̀◌𞀡◌̕b; à◌֮◌𞀡◌̕b; a◌֮◌̀◌𞀡◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER YATI, LATIN SMALL LETTER B
+0061 1E021 0315 0300 05AE 0062;0061 05AE 1E021 0300 0315 0062;0061 05AE 1E021 0300 0315 0062;0061 05AE 1E021 0300 0315 0062;0061 05AE 1E021 0300 0315 0062; # (a◌𞀡◌̕◌̀◌֮b; a◌֮◌𞀡◌̀◌̕b; a◌֮◌𞀡◌̀◌̕b; a◌֮◌𞀡◌̀◌̕b; a◌֮◌𞀡◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER YATI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E023 0062;00E0 05AE 1E023 0315 0062;0061 05AE 0300 1E023 0315 0062;00E0 05AE 1E023 0315 0062;0061 05AE 0300 1E023 0315 0062; # (a◌̕◌̀◌֮◌𞀣b; à◌֮◌𞀣◌̕b; a◌֮◌̀◌𞀣◌̕b; à◌֮◌𞀣◌̕b; a◌֮◌̀◌𞀣◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER YU, LATIN SMALL LETTER B
+0061 1E023 0315 0300 05AE 0062;0061 05AE 1E023 0300 0315 0062;0061 05AE 1E023 0300 0315 0062;0061 05AE 1E023 0300 0315 0062;0061 05AE 1E023 0300 0315 0062; # (a◌𞀣◌̕◌̀◌֮b; a◌֮◌𞀣◌̀◌̕b; a◌֮◌𞀣◌̀◌̕b; a◌֮◌𞀣◌̀◌̕b; a◌֮◌𞀣◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER YU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E024 0062;00E0 05AE 1E024 0315 0062;0061 05AE 0300 1E024 0315 0062;00E0 05AE 1E024 0315 0062;0061 05AE 0300 1E024 0315 0062; # (a◌̕◌̀◌֮◌𞀤b; à◌֮◌𞀤◌̕b; a◌֮◌̀◌𞀤◌̕b; à◌֮◌𞀤◌̕b; a◌֮◌̀◌𞀤◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER SMALL YUS, LATIN SMALL LETTER B
+0061 1E024 0315 0300 05AE 0062;0061 05AE 1E024 0300 0315 0062;0061 05AE 1E024 0300 0315 0062;0061 05AE 1E024 0300 0315 0062;0061 05AE 1E024 0300 0315 0062; # (a◌𞀤◌̕◌̀◌֮b; a◌֮◌𞀤◌̀◌̕b; a◌֮◌𞀤◌̀◌̕b; a◌֮◌𞀤◌̀◌̕b; a◌֮◌𞀤◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER SMALL YUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E026 0062;00E0 05AE 1E026 0315 0062;0061 05AE 0300 1E026 0315 0062;00E0 05AE 1E026 0315 0062;0061 05AE 0300 1E026 0315 0062; # (a◌̕◌̀◌֮◌𞀦b; à◌֮◌𞀦◌̕b; a◌֮◌̀◌𞀦◌̕b; à◌֮◌𞀦◌̕b; a◌֮◌̀◌𞀦◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER YO, LATIN SMALL LETTER B
+0061 1E026 0315 0300 05AE 0062;0061 05AE 1E026 0300 0315 0062;0061 05AE 1E026 0300 0315 0062;0061 05AE 1E026 0300 0315 0062;0061 05AE 1E026 0300 0315 0062; # (a◌𞀦◌̕◌̀◌֮b; a◌֮◌𞀦◌̀◌̕b; a◌֮◌𞀦◌̀◌̕b; a◌֮◌𞀦◌̀◌̕b; a◌֮◌𞀦◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER YO, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E027 0062;00E0 05AE 1E027 0315 0062;0061 05AE 0300 1E027 0315 0062;00E0 05AE 1E027 0315 0062;0061 05AE 0300 1E027 0315 0062; # (a◌̕◌̀◌֮◌𞀧b; à◌֮◌𞀧◌̕b; a◌֮◌̀◌𞀧◌̕b; à◌֮◌𞀧◌̕b; a◌֮◌̀◌𞀧◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER IOTATED SMALL YUS, LATIN SMALL LETTER B
+0061 1E027 0315 0300 05AE 0062;0061 05AE 1E027 0300 0315 0062;0061 05AE 1E027 0300 0315 0062;0061 05AE 1E027 0300 0315 0062;0061 05AE 1E027 0300 0315 0062; # (a◌𞀧◌̕◌̀◌֮b; a◌֮◌𞀧◌̀◌̕b; a◌֮◌𞀧◌̀◌̕b; a◌֮◌𞀧◌̀◌̕b; a◌֮◌𞀧◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER IOTATED SMALL YUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E028 0062;00E0 05AE 1E028 0315 0062;0061 05AE 0300 1E028 0315 0062;00E0 05AE 1E028 0315 0062;0061 05AE 0300 1E028 0315 0062; # (a◌̕◌̀◌֮◌𞀨b; à◌֮◌𞀨◌̕b; a◌֮◌̀◌𞀨◌̕b; à◌֮◌𞀨◌̕b; a◌֮◌̀◌𞀨◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER BIG YUS, LATIN SMALL LETTER B
+0061 1E028 0315 0300 05AE 0062;0061 05AE 1E028 0300 0315 0062;0061 05AE 1E028 0300 0315 0062;0061 05AE 1E028 0300 0315 0062;0061 05AE 1E028 0300 0315 0062; # (a◌𞀨◌̕◌̀◌֮b; a◌֮◌𞀨◌̀◌̕b; a◌֮◌𞀨◌̀◌̕b; a◌֮◌𞀨◌̀◌̕b; a◌֮◌𞀨◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER BIG YUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E029 0062;00E0 05AE 1E029 0315 0062;0061 05AE 0300 1E029 0315 0062;00E0 05AE 1E029 0315 0062;0061 05AE 0300 1E029 0315 0062; # (a◌̕◌̀◌֮◌𞀩b; à◌֮◌𞀩◌̕b; a◌֮◌̀◌𞀩◌̕b; à◌֮◌𞀩◌̕b; a◌֮◌̀◌𞀩◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER IOTATED BIG YUS, LATIN SMALL LETTER B
+0061 1E029 0315 0300 05AE 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062; # (a◌𞀩◌̕◌̀◌֮b; a◌֮◌𞀩◌̀◌̕b; a◌֮◌𞀩◌̀◌̕b; a◌֮◌𞀩◌̀◌̕b; a◌֮◌𞀩◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER IOTATED BIG YUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E02A 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062; # (a◌̕◌̀◌֮◌𞀪b; à◌֮◌𞀪◌̕b; a◌֮◌̀◌𞀪◌̕b; à◌֮◌𞀪◌̕b; a◌֮◌̀◌𞀪◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER FITA, LATIN SMALL LETTER B
+0061 1E02A 0315 0300 05AE 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062; # (a◌𞀪◌̕◌̀◌֮b; a◌֮◌𞀪◌̀◌̕b; a◌֮◌𞀪◌̀◌̕b; a◌֮◌𞀪◌̀◌̕b; a◌֮◌𞀪◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER FITA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 302A 1E8D0 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062; # (a◌֚◌̖◌〪◌𞣐b; a◌〪◌̖◌𞣐◌֚b; a◌〪◌̖◌𞣐◌֚b; a◌〪◌̖◌𞣐◌֚b; a◌〪◌̖◌𞣐◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER TEENS, LATIN SMALL LETTER B
+0061 1E8D0 059A 0316 302A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062; # (a◌𞣐◌֚◌̖◌〪b; a◌〪◌𞣐◌̖◌֚b; a◌〪◌𞣐◌̖◌֚b; a◌〪◌𞣐◌̖◌֚b; a◌〪◌𞣐◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER TEENS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1E8D1 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062; # (a◌֚◌̖◌〪◌𞣑b; a◌〪◌̖◌𞣑◌֚b; a◌〪◌̖◌𞣑◌֚b; a◌〪◌̖◌𞣑◌֚b; a◌〪◌̖◌𞣑◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER TENS, LATIN SMALL LETTER B
+0061 1E8D1 059A 0316 302A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062;0061 302A 1E8D1 0316 059A 0062; # (a◌𞣑◌֚◌̖◌〪b; a◌〪◌𞣑◌̖◌֚b; a◌〪◌𞣑◌̖◌֚b; a◌〪◌𞣑◌̖◌֚b; a◌〪◌𞣑◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER TENS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1E8D2 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062;0061 302A 0316 1E8D2 059A 0062; # (a◌֚◌̖◌〪◌𞣒b; a◌〪◌̖◌𞣒◌֚b; a◌〪◌̖◌𞣒◌֚b; a◌〪◌̖◌𞣒◌֚b; a◌〪◌̖◌𞣒◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER HUNDREDS, LATIN SMALL LETTER B
+0061 1E8D2 059A 0316 302A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062;0061 302A 1E8D2 0316 059A 0062; # (a◌𞣒◌֚◌̖◌〪b; a◌〪◌𞣒◌̖◌֚b; a◌〪◌𞣒◌̖◌֚b; a◌〪◌𞣒◌̖◌֚b; a◌〪◌𞣒◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER HUNDREDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1E8D3 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062;0061 302A 0316 1E8D3 059A 0062; # (a◌֚◌̖◌〪◌𞣓b; a◌〪◌̖◌𞣓◌֚b; a◌〪◌̖◌𞣓◌֚b; a◌〪◌̖◌𞣓◌֚b; a◌〪◌̖◌𞣓◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER THOUSANDS, LATIN SMALL LETTER B
+0061 1E8D3 059A 0316 302A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062;0061 302A 1E8D3 0316 059A 0062; # (a◌𞣓◌֚◌̖◌〪b; a◌〪◌𞣓◌̖◌֚b; a◌〪◌𞣓◌̖◌֚b; a◌〪◌𞣓◌̖◌֚b; a◌〪◌𞣓◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER THOUSANDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1E8D4 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062;0061 302A 0316 1E8D4 059A 0062; # (a◌֚◌̖◌〪◌𞣔b; a◌〪◌̖◌𞣔◌֚b; a◌〪◌̖◌𞣔◌֚b; a◌〪◌̖◌𞣔◌֚b; a◌〪◌̖◌𞣔◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER TEN THOUSANDS, LATIN SMALL LETTER B
+0061 1E8D4 059A 0316 302A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062;0061 302A 1E8D4 0316 059A 0062; # (a◌𞣔◌֚◌̖◌〪b; a◌〪◌𞣔◌̖◌֚b; a◌〪◌𞣔◌̖◌֚b; a◌〪◌𞣔◌̖◌֚b; a◌〪◌𞣔◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER TEN THOUSANDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1E8D5 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062;0061 302A 0316 1E8D5 059A 0062; # (a◌֚◌̖◌〪◌𞣕b; a◌〪◌̖◌𞣕◌֚b; a◌〪◌̖◌𞣕◌֚b; a◌〪◌̖◌𞣕◌֚b; a◌〪◌̖◌𞣕◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER HUNDRED THOUSANDS, LATIN SMALL LETTER B
+0061 1E8D5 059A 0316 302A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062;0061 302A 1E8D5 0316 059A 0062; # (a◌𞣕◌֚◌̖◌〪b; a◌〪◌𞣕◌̖◌֚b; a◌〪◌𞣕◌̖◌֚b; a◌〪◌𞣕◌̖◌֚b; a◌〪◌𞣕◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER HUNDRED THOUSANDS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 059A 0316 302A 1E8D6 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062;0061 302A 0316 1E8D6 059A 0062; # (a◌֚◌̖◌〪◌𞣖b; a◌〪◌̖◌𞣖◌֚b; a◌〪◌̖◌𞣖◌֚b; a◌〪◌̖◌𞣖◌֚b; a◌〪◌̖◌𞣖◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER MILLIONS, LATIN SMALL LETTER B
+0061 1E8D6 059A 0316 302A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062;0061 302A 1E8D6 0316 059A 0062; # (a◌𞣖◌֚◌̖◌〪b; a◌〪◌𞣖◌̖◌֚b; a◌〪◌𞣖◌̖◌֚b; a◌〪◌𞣖◌̖◌֚b; a◌〪◌𞣖◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER MILLIONS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E944 0062;00E0 05AE 1E944 0315 0062;0061 05AE 0300 1E944 0315 0062;00E0 05AE 1E944 0315 0062;0061 05AE 0300 1E944 0315 0062; # (a◌̕◌̀◌֮◌𞥄b; à◌֮◌𞥄◌̕b; a◌֮◌̀◌𞥄◌̕b; à◌֮◌𞥄◌̕b; a◌֮◌̀◌𞥄◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ADLAM ALIF LENGTHENER, LATIN SMALL LETTER B
+0061 1E944 0315 0300 05AE 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062;0061 05AE 1E944 0300 0315 0062; # (a◌𞥄◌̕◌̀◌֮b; a◌֮◌𞥄◌̀◌̕b; a◌֮◌𞥄◌̀◌̕b; a◌֮◌𞥄◌̀◌̕b; a◌֮◌𞥄◌̀◌̕b; ) LATIN SMALL LETTER A, ADLAM ALIF LENGTHENER, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E945 0062;00E0 05AE 1E945 0315 0062;0061 05AE 0300 1E945 0315 0062;00E0 05AE 1E945 0315 0062;0061 05AE 0300 1E945 0315 0062; # (a◌̕◌̀◌֮◌𞥅b; à◌֮◌𞥅◌̕b; a◌֮◌̀◌𞥅◌̕b; à◌֮◌𞥅◌̕b; a◌֮◌̀◌𞥅◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ADLAM VOWEL LENGTHENER, LATIN SMALL LETTER B
+0061 1E945 0315 0300 05AE 0062;0061 05AE 1E945 0300 0315 0062;0061 05AE 1E945 0300 0315 0062;0061 05AE 1E945 0300 0315 0062;0061 05AE 1E945 0300 0315 0062; # (a◌𞥅◌̕◌̀◌֮b; a◌֮◌𞥅◌̀◌̕b; a◌֮◌𞥅◌̀◌̕b; a◌֮◌𞥅◌̀◌̕b; a◌֮◌𞥅◌̀◌̕b; ) LATIN SMALL LETTER A, ADLAM VOWEL LENGTHENER, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E946 0062;00E0 05AE 1E946 0315 0062;0061 05AE 0300 1E946 0315 0062;00E0 05AE 1E946 0315 0062;0061 05AE 0300 1E946 0315 0062; # (a◌̕◌̀◌֮◌𞥆b; à◌֮◌𞥆◌̕b; a◌֮◌̀◌𞥆◌̕b; à◌֮◌𞥆◌̕b; a◌֮◌̀◌𞥆◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ADLAM GEMINATION MARK, LATIN SMALL LETTER B
+0061 1E946 0315 0300 05AE 0062;0061 05AE 1E946 0300 0315 0062;0061 05AE 1E946 0300 0315 0062;0061 05AE 1E946 0300 0315 0062;0061 05AE 1E946 0300 0315 0062; # (a◌𞥆◌̕◌̀◌֮b; a◌֮◌𞥆◌̀◌̕b; a◌֮◌𞥆◌̀◌̕b; a◌֮◌𞥆◌̀◌̕b; a◌֮◌𞥆◌̀◌̕b; ) LATIN SMALL LETTER A, ADLAM GEMINATION MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E947 0062;00E0 05AE 1E947 0315 0062;0061 05AE 0300 1E947 0315 0062;00E0 05AE 1E947 0315 0062;0061 05AE 0300 1E947 0315 0062; # (a◌̕◌̀◌֮◌𞥇b; à◌֮◌𞥇◌̕b; a◌֮◌̀◌𞥇◌̕b; à◌֮◌𞥇◌̕b; a◌֮◌̀◌𞥇◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ADLAM HAMZA, LATIN SMALL LETTER B
+0061 1E947 0315 0300 05AE 0062;0061 05AE 1E947 0300 0315 0062;0061 05AE 1E947 0300 0315 0062;0061 05AE 1E947 0300 0315 0062;0061 05AE 1E947 0300 0315 0062; # (a◌𞥇◌̕◌̀◌֮b; a◌֮◌𞥇◌̀◌̕b; a◌֮◌𞥇◌̀◌̕b; a◌֮◌𞥇◌̀◌̕b; a◌֮◌𞥇◌̀◌̕b; ) LATIN SMALL LETTER A, ADLAM HAMZA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E948 0062;00E0 05AE 1E948 0315 0062;0061 05AE 0300 1E948 0315 0062;00E0 05AE 1E948 0315 0062;0061 05AE 0300 1E948 0315 0062; # (a◌̕◌̀◌֮◌𞥈b; à◌֮◌𞥈◌̕b; a◌֮◌̀◌𞥈◌̕b; à◌֮◌𞥈◌̕b; a◌֮◌̀◌𞥈◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ADLAM CONSONANT MODIFIER, LATIN SMALL LETTER B
+0061 1E948 0315 0300 05AE 0062;0061 05AE 1E948 0300 0315 0062;0061 05AE 1E948 0300 0315 0062;0061 05AE 1E948 0300 0315 0062;0061 05AE 1E948 0300 0315 0062; # (a◌𞥈◌̕◌̀◌֮b; a◌֮◌𞥈◌̀◌̕b; a◌֮◌𞥈◌̀◌̕b; a◌֮◌𞥈◌̀◌̕b; a◌֮◌𞥈◌̀◌̕b; ) LATIN SMALL LETTER A, ADLAM CONSONANT MODIFIER, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E949 0062;00E0 05AE 1E949 0315 0062;0061 05AE 0300 1E949 0315 0062;00E0 05AE 1E949 0315 0062;0061 05AE 0300 1E949 0315 0062; # (a◌̕◌̀◌֮◌𞥉b; à◌֮◌𞥉◌̕b; a◌֮◌̀◌𞥉◌̕b; à◌֮◌𞥉◌̕b; a◌֮◌̀◌𞥉◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ADLAM GEMINATE CONSONANT MODIFIER, LATIN SMALL LETTER B
+0061 1E949 0315 0300 05AE 0062;0061 05AE 1E949 0300 0315 0062;0061 05AE 1E949 0300 0315 0062;0061 05AE 1E949 0300 0315 0062;0061 05AE 1E949 0300 0315 0062; # (a◌𞥉◌̕◌̀◌֮b; a◌֮◌𞥉◌̀◌̕b; a◌֮◌𞥉◌̀◌̕b; a◌֮◌𞥉◌̀◌̕b; a◌֮◌𞥉◌̀◌̕b; ) LATIN SMALL LETTER A, ADLAM GEMINATE CONSONANT MODIFIER, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 3099 093C 0334 1E94A 0062;0061 0334 093C 1E94A 3099 0062;0061 0334 093C 1E94A 3099 0062;0061 0334 093C 1E94A 3099 0062;0061 0334 093C 1E94A 3099 0062; # (a◌゙◌़◌̴◌𞥊b; a◌̴◌़◌𞥊◌゙b; a◌̴◌़◌𞥊◌゙b; a◌̴◌़◌𞥊◌゙b; a◌̴◌़◌𞥊◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, ADLAM NUKTA, LATIN SMALL LETTER B
+0061 1E94A 3099 093C 0334 0062;0061 0334 1E94A 093C 3099 0062;0061 0334 1E94A 093C 3099 0062;0061 0334 1E94A 093C 3099 0062;0061 0334 1E94A 093C 3099 0062; # (a◌𞥊◌゙◌़◌̴b; a◌̴◌𞥊◌़◌゙b; a◌̴◌𞥊◌़◌゙b; a◌̴◌𞥊◌़◌゙b; a◌̴◌𞥊◌़◌゙b; ) LATIN SMALL LETTER A, ADLAM NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+#
+@Part3 # PRI #29 Test
+#
+09C7 0334 09BE;09C7 0334 09BE;09C7 0334 09BE;09C7 0334 09BE;09C7 0334 09BE; # (ে◌̴া; ে◌̴া; ে◌̴া; ে◌̴া; ে◌̴া; ) BENGALI VOWEL SIGN E, COMBINING TILDE OVERLAY, BENGALI VOWEL SIGN AA
+09C7 0334 09D7;09C7 0334 09D7;09C7 0334 09D7;09C7 0334 09D7;09C7 0334 09D7; # (ে◌̴ৗ; ে◌̴ৗ; ে◌̴ৗ; ে◌̴ৗ; ে◌̴ৗ; ) BENGALI VOWEL SIGN E, COMBINING TILDE OVERLAY, BENGALI AU LENGTH MARK
+0B47 0334 0B3E;0B47 0334 0B3E;0B47 0334 0B3E;0B47 0334 0B3E;0B47 0334 0B3E; # (େ◌̴ା; େ◌̴ା; େ◌̴ା; େ◌̴ା; େ◌̴ା; ) ORIYA VOWEL SIGN E, COMBINING TILDE OVERLAY, ORIYA VOWEL SIGN AA
+0B47 0334 0B56;0B47 0334 0B56;0B47 0334 0B56;0B47 0334 0B56;0B47 0334 0B56; # (େ◌̴◌ୖ; େ◌̴◌ୖ; େ◌̴◌ୖ; େ◌̴◌ୖ; େ◌̴◌ୖ; ) ORIYA VOWEL SIGN E, COMBINING TILDE OVERLAY, ORIYA AI LENGTH MARK
+0B47 0334 0B57;0B47 0334 0B57;0B47 0334 0B57;0B47 0334 0B57;0B47 0334 0B57; # (େ◌̴ୗ; େ◌̴ୗ; େ◌̴ୗ; େ◌̴ୗ; େ◌̴ୗ; ) ORIYA VOWEL SIGN E, COMBINING TILDE OVERLAY, ORIYA AU LENGTH MARK
+0B92 0334 0BD7;0B92 0334 0BD7;0B92 0334 0BD7;0B92 0334 0BD7;0B92 0334 0BD7; # (ஒ◌̴ௗ; ஒ◌̴ௗ; ஒ◌̴ௗ; ஒ◌̴ௗ; ஒ◌̴ௗ; ) TAMIL LETTER O, COMBINING TILDE OVERLAY, TAMIL AU LENGTH MARK
+0BC6 0334 0BBE;0BC6 0334 0BBE;0BC6 0334 0BBE;0BC6 0334 0BBE;0BC6 0334 0BBE; # (ெ◌̴ா; ெ◌̴ா; ெ◌̴ா; ெ◌̴ா; ெ◌̴ா; ) TAMIL VOWEL SIGN E, COMBINING TILDE OVERLAY, TAMIL VOWEL SIGN AA
+0BC6 0334 0BD7;0BC6 0334 0BD7;0BC6 0334 0BD7;0BC6 0334 0BD7;0BC6 0334 0BD7; # (ெ◌̴ௗ; ெ◌̴ௗ; ெ◌̴ௗ; ெ◌̴ௗ; ெ◌̴ௗ; ) TAMIL VOWEL SIGN E, COMBINING TILDE OVERLAY, TAMIL AU LENGTH MARK
+0BC7 0334 0BBE;0BC7 0334 0BBE;0BC7 0334 0BBE;0BC7 0334 0BBE;0BC7 0334 0BBE; # (ே◌̴ா; ே◌̴ா; ே◌̴ா; ே◌̴ா; ே◌̴ா; ) TAMIL VOWEL SIGN EE, COMBINING TILDE OVERLAY, TAMIL VOWEL SIGN AA
+0CBF 0334 0CD5;0CBF 0334 0CD5;0CBF 0334 0CD5;0CBF 0334 0CD5;0CBF 0334 0CD5; # (◌ಿ◌̴ೕ; ◌ಿ◌̴ೕ; ◌ಿ◌̴ೕ; ◌ಿ◌̴ೕ; ◌ಿ◌̴ೕ; ) KANNADA VOWEL SIGN I, COMBINING TILDE OVERLAY, KANNADA LENGTH MARK
+0CC6 0334 0CC2;0CC6 0334 0CC2;0CC6 0334 0CC2;0CC6 0334 0CC2;0CC6 0334 0CC2; # (◌ೆ◌̴ೂ; ◌ೆ◌̴ೂ; ◌ೆ◌̴ೂ; ◌ೆ◌̴ೂ; ◌ೆ◌̴ೂ; ) KANNADA VOWEL SIGN E, COMBINING TILDE OVERLAY, KANNADA VOWEL SIGN UU
+0CC6 0334 0CD5;0CC6 0334 0CD5;0CC6 0334 0CD5;0CC6 0334 0CD5;0CC6 0334 0CD5; # (◌ೆ◌̴ೕ; ◌ೆ◌̴ೕ; ◌ೆ◌̴ೕ; ◌ೆ◌̴ೕ; ◌ೆ◌̴ೕ; ) KANNADA VOWEL SIGN E, COMBINING TILDE OVERLAY, KANNADA LENGTH MARK
+0CC6 0334 0CD6;0CC6 0334 0CD6;0CC6 0334 0CD6;0CC6 0334 0CD6;0CC6 0334 0CD6; # (◌ೆ◌̴ೖ; ◌ೆ◌̴ೖ; ◌ೆ◌̴ೖ; ◌ೆ◌̴ೖ; ◌ೆ◌̴ೖ; ) KANNADA VOWEL SIGN E, COMBINING TILDE OVERLAY, KANNADA AI LENGTH MARK
+0CCA 0334 0CD5;0CCA 0334 0CD5;0CC6 0CC2 0334 0CD5;0CCA 0334 0CD5;0CC6 0CC2 0334 0CD5; # (ೊ◌̴ೕ; ೊ◌̴ೕ; ◌ೊ◌̴ೕ; ೊ◌̴ೕ; ◌ೊ◌̴ೕ; ) KANNADA VOWEL SIGN O, COMBINING TILDE OVERLAY, KANNADA LENGTH MARK
+0D46 0334 0D3E;0D46 0334 0D3E;0D46 0334 0D3E;0D46 0334 0D3E;0D46 0334 0D3E; # (െ◌̴ാ; െ◌̴ാ; െ◌̴ാ; െ◌̴ാ; െ◌̴ാ; ) MALAYALAM VOWEL SIGN E, COMBINING TILDE OVERLAY, MALAYALAM VOWEL SIGN AA
+0D46 0334 0D57;0D46 0334 0D57;0D46 0334 0D57;0D46 0334 0D57;0D46 0334 0D57; # (െ◌̴ൗ; െ◌̴ൗ; െ◌̴ൗ; െ◌̴ൗ; െ◌̴ൗ; ) MALAYALAM VOWEL SIGN E, COMBINING TILDE OVERLAY, MALAYALAM AU LENGTH MARK
+0D47 0334 0D3E;0D47 0334 0D3E;0D47 0334 0D3E;0D47 0334 0D3E;0D47 0334 0D3E; # (േ◌̴ാ; േ◌̴ാ; േ◌̴ാ; േ◌̴ാ; േ◌̴ാ; ) MALAYALAM VOWEL SIGN EE, COMBINING TILDE OVERLAY, MALAYALAM VOWEL SIGN AA
+0DD9 0334 0DCF;0DD9 0334 0DCF;0DD9 0334 0DCF;0DD9 0334 0DCF;0DD9 0334 0DCF; # (ෙ◌̴ා; ෙ◌̴ා; ෙ◌̴ා; ෙ◌̴ා; ෙ◌̴ා; ) SINHALA VOWEL SIGN KOMBUVA, COMBINING TILDE OVERLAY, SINHALA VOWEL SIGN AELA-PILLA
+0DD9 0334 0DDF;0DD9 0334 0DDF;0DD9 0334 0DDF;0DD9 0334 0DDF;0DD9 0334 0DDF; # (ෙ◌̴ෟ; ෙ◌̴ෟ; ෙ◌̴ෟ; ෙ◌̴ෟ; ෙ◌̴ෟ; ) SINHALA VOWEL SIGN KOMBUVA, COMBINING TILDE OVERLAY, SINHALA VOWEL SIGN GAYANUKITTA
+0F40 0334 0FB5;0F40 0334 0FB5;0F40 0334 0FB5;0F40 0334 0FB5;0F40 0334 0FB5; # (ཀ◌̴◌ྵ; ཀ◌̴◌ྵ; ཀ◌̴◌ྵ; ཀ◌̴◌ྵ; ཀ◌̴◌ྵ; ) TIBETAN LETTER KA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER SSA
+0F42 0334 0FB7;0F42 0334 0FB7;0F42 0334 0FB7;0F42 0334 0FB7;0F42 0334 0FB7; # (ག◌̴◌ྷ; ག◌̴◌ྷ; ག◌̴◌ྷ; ག◌̴◌ྷ; ག◌̴◌ྷ; ) TIBETAN LETTER GA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER HA
+0F4C 0334 0FB7;0F4C 0334 0FB7;0F4C 0334 0FB7;0F4C 0334 0FB7;0F4C 0334 0FB7; # (ཌ◌̴◌ྷ; ཌ◌̴◌ྷ; ཌ◌̴◌ྷ; ཌ◌̴◌ྷ; ཌ◌̴◌ྷ; ) TIBETAN LETTER DDA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER HA
+0F51 0334 0FB7;0F51 0334 0FB7;0F51 0334 0FB7;0F51 0334 0FB7;0F51 0334 0FB7; # (ད◌̴◌ྷ; ད◌̴◌ྷ; ད◌̴◌ྷ; ད◌̴◌ྷ; ད◌̴◌ྷ; ) TIBETAN LETTER DA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER HA
+0F56 0334 0FB7;0F56 0334 0FB7;0F56 0334 0FB7;0F56 0334 0FB7;0F56 0334 0FB7; # (བ◌̴◌ྷ; བ◌̴◌ྷ; བ◌̴◌ྷ; བ◌̴◌ྷ; བ◌̴◌ྷ; ) TIBETAN LETTER BA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER HA
+0F5B 0334 0FB7;0F5B 0334 0FB7;0F5B 0334 0FB7;0F5B 0334 0FB7;0F5B 0334 0FB7; # (ཛ◌̴◌ྷ; ཛ◌̴◌ྷ; ཛ◌̴◌ྷ; ཛ◌̴◌ྷ; ཛ◌̴◌ྷ; ) TIBETAN LETTER DZA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER HA
+0F90 0334 0FB5;0F90 0334 0FB5;0F90 0334 0FB5;0F90 0334 0FB5;0F90 0334 0FB5; # (◌ྐ◌̴◌ྵ; ◌ྐ◌̴◌ྵ; ◌ྐ◌̴◌ྵ; ◌ྐ◌̴◌ྵ; ◌ྐ◌̴◌ྵ; ) TIBETAN SUBJOINED LETTER KA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER SSA
+0F92 0334 0FB7;0F92 0334 0FB7;0F92 0334 0FB7;0F92 0334 0FB7;0F92 0334 0FB7; # (◌ྒ◌̴◌ྷ; ◌ྒ◌̴◌ྷ; ◌ྒ◌̴◌ྷ; ◌ྒ◌̴◌ྷ; ◌ྒ◌̴◌ྷ; ) TIBETAN SUBJOINED LETTER GA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER HA
+0F9C 0334 0FB7;0F9C 0334 0FB7;0F9C 0334 0FB7;0F9C 0334 0FB7;0F9C 0334 0FB7; # (◌ྜ◌̴◌ྷ; ◌ྜ◌̴◌ྷ; ◌ྜ◌̴◌ྷ; ◌ྜ◌̴◌ྷ; ◌ྜ◌̴◌ྷ; ) TIBETAN SUBJOINED LETTER DDA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER HA
+0FA1 0334 0FB7;0FA1 0334 0FB7;0FA1 0334 0FB7;0FA1 0334 0FB7;0FA1 0334 0FB7; # (◌ྡ◌̴◌ྷ; ◌ྡ◌̴◌ྷ; ◌ྡ◌̴◌ྷ; ◌ྡ◌̴◌ྷ; ◌ྡ◌̴◌ྷ; ) TIBETAN SUBJOINED LETTER DA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER HA
+0FA6 0334 0FB7;0FA6 0334 0FB7;0FA6 0334 0FB7;0FA6 0334 0FB7;0FA6 0334 0FB7; # (◌ྦ◌̴◌ྷ; ◌ྦ◌̴◌ྷ; ◌ྦ◌̴◌ྷ; ◌ྦ◌̴◌ྷ; ◌ྦ◌̴◌ྷ; ) TIBETAN SUBJOINED LETTER BA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER HA
+0FAB 0334 0FB7;0FAB 0334 0FB7;0FAB 0334 0FB7;0FAB 0334 0FB7;0FAB 0334 0FB7; # (◌ྫ◌̴◌ྷ; ◌ྫ◌̴◌ྷ; ◌ྫ◌̴◌ྷ; ◌ྫ◌̴◌ྷ; ◌ྫ◌̴◌ྷ; ) TIBETAN SUBJOINED LETTER DZA, COMBINING TILDE OVERLAY, TIBETAN SUBJOINED LETTER HA
+1025 0334 102E;1025 0334 102E;1025 0334 102E;1025 0334 102E;1025 0334 102E; # (ဥ◌̴◌ီ; ဥ◌̴◌ီ; ဥ◌̴◌ီ; ဥ◌̴◌ီ; ဥ◌̴◌ီ; ) MYANMAR LETTER U, COMBINING TILDE OVERLAY, MYANMAR VOWEL SIGN II
+1100 0334 1161;1100 0334 1161;1100 0334 1161;1100 0334 1161;1100 0334 1161; # (ᄀ◌̴ᅡ; ᄀ◌̴ᅡ; ᄀ◌̴ᅡ; ᄀ◌̴ᅡ; ᄀ◌̴ᅡ; ) HANGUL CHOSEONG KIYEOK, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG A
+1100 0334 116E;1100 0334 116E;1100 0334 116E;1100 0334 116E;1100 0334 116E; # (ᄀ◌̴ᅮ; ᄀ◌̴ᅮ; ᄀ◌̴ᅮ; ᄀ◌̴ᅮ; ᄀ◌̴ᅮ; ) HANGUL CHOSEONG KIYEOK, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG U
+1101 0334 1166;1101 0334 1166;1101 0334 1166;1101 0334 1166;1101 0334 1166; # (ᄁ◌̴ᅦ; ᄁ◌̴ᅦ; ᄁ◌̴ᅦ; ᄁ◌̴ᅦ; ᄁ◌̴ᅦ; ) HANGUL CHOSEONG SSANGKIYEOK, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG E
+1101 0334 1173;1101 0334 1173;1101 0334 1173;1101 0334 1173;1101 0334 1173; # (ᄁ◌̴ᅳ; ᄁ◌̴ᅳ; ᄁ◌̴ᅳ; ᄁ◌̴ᅳ; ᄁ◌̴ᅳ; ) HANGUL CHOSEONG SSANGKIYEOK, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG EU
+1102 0334 116B;1102 0334 116B;1102 0334 116B;1102 0334 116B;1102 0334 116B; # (ᄂ◌̴ᅫ; ᄂ◌̴ᅫ; ᄂ◌̴ᅫ; ᄂ◌̴ᅫ; ᄂ◌̴ᅫ; ) HANGUL CHOSEONG NIEUN, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG WAE
+1103 0334 1163;1103 0334 1163;1103 0334 1163;1103 0334 1163;1103 0334 1163; # (ᄃ◌̴ᅣ; ᄃ◌̴ᅣ; ᄃ◌̴ᅣ; ᄃ◌̴ᅣ; ᄃ◌̴ᅣ; ) HANGUL CHOSEONG TIKEUT, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG YA
+1103 0334 1170;1103 0334 1170;1103 0334 1170;1103 0334 1170;1103 0334 1170; # (ᄃ◌̴ᅰ; ᄃ◌̴ᅰ; ᄃ◌̴ᅰ; ᄃ◌̴ᅰ; ᄃ◌̴ᅰ; ) HANGUL CHOSEONG TIKEUT, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG WE
+1104 0334 1168;1104 0334 1168;1104 0334 1168;1104 0334 1168;1104 0334 1168; # (ᄄ◌̴ᅨ; ᄄ◌̴ᅨ; ᄄ◌̴ᅨ; ᄄ◌̴ᅨ; ᄄ◌̴ᅨ; ) HANGUL CHOSEONG SSANGTIKEUT, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG YE
+1104 0334 1175;1104 0334 1175;1104 0334 1175;1104 0334 1175;1104 0334 1175; # (ᄄ◌̴ᅵ; ᄄ◌̴ᅵ; ᄄ◌̴ᅵ; ᄄ◌̴ᅵ; ᄄ◌̴ᅵ; ) HANGUL CHOSEONG SSANGTIKEUT, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG I
+1105 0334 116D;1105 0334 116D;1105 0334 116D;1105 0334 116D;1105 0334 116D; # (ᄅ◌̴ᅭ; ᄅ◌̴ᅭ; ᄅ◌̴ᅭ; ᄅ◌̴ᅭ; ᄅ◌̴ᅭ; ) HANGUL CHOSEONG RIEUL, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG YO
+1106 0334 1165;1106 0334 1165;1106 0334 1165;1106 0334 1165;1106 0334 1165; # (ᄆ◌̴ᅥ; ᄆ◌̴ᅥ; ᄆ◌̴ᅥ; ᄆ◌̴ᅥ; ᄆ◌̴ᅥ; ) HANGUL CHOSEONG MIEUM, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG EO
+1106 0334 1172;1106 0334 1172;1106 0334 1172;1106 0334 1172;1106 0334 1172; # (ᄆ◌̴ᅲ; ᄆ◌̴ᅲ; ᄆ◌̴ᅲ; ᄆ◌̴ᅲ; ᄆ◌̴ᅲ; ) HANGUL CHOSEONG MIEUM, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG YU
+1107 0334 116A;1107 0334 116A;1107 0334 116A;1107 0334 116A;1107 0334 116A; # (ᄇ◌̴ᅪ; ᄇ◌̴ᅪ; ᄇ◌̴ᅪ; ᄇ◌̴ᅪ; ᄇ◌̴ᅪ; ) HANGUL CHOSEONG PIEUP, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG WA
+1108 0334 1162;1108 0334 1162;1108 0334 1162;1108 0334 1162;1108 0334 1162; # (ᄈ◌̴ᅢ; ᄈ◌̴ᅢ; ᄈ◌̴ᅢ; ᄈ◌̴ᅢ; ᄈ◌̴ᅢ; ) HANGUL CHOSEONG SSANGPIEUP, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG AE
+1108 0334 116F;1108 0334 116F;1108 0334 116F;1108 0334 116F;1108 0334 116F; # (ᄈ◌̴ᅯ; ᄈ◌̴ᅯ; ᄈ◌̴ᅯ; ᄈ◌̴ᅯ; ᄈ◌̴ᅯ; ) HANGUL CHOSEONG SSANGPIEUP, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG WEO
+1109 0334 1167;1109 0334 1167;1109 0334 1167;1109 0334 1167;1109 0334 1167; # (ᄉ◌̴ᅧ; ᄉ◌̴ᅧ; ᄉ◌̴ᅧ; ᄉ◌̴ᅧ; ᄉ◌̴ᅧ; ) HANGUL CHOSEONG SIOS, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG YEO
+1109 0334 1174;1109 0334 1174;1109 0334 1174;1109 0334 1174;1109 0334 1174; # (ᄉ◌̴ᅴ; ᄉ◌̴ᅴ; ᄉ◌̴ᅴ; ᄉ◌̴ᅴ; ᄉ◌̴ᅴ; ) HANGUL CHOSEONG SIOS, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG YI
+110A 0334 116C;110A 0334 116C;110A 0334 116C;110A 0334 116C;110A 0334 116C; # (ᄊ◌̴ᅬ; ᄊ◌̴ᅬ; ᄊ◌̴ᅬ; ᄊ◌̴ᅬ; ᄊ◌̴ᅬ; ) HANGUL CHOSEONG SSANGSIOS, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG OE
+110B 0334 1164;110B 0334 1164;110B 0334 1164;110B 0334 1164;110B 0334 1164; # (ᄋ◌̴ᅤ; ᄋ◌̴ᅤ; ᄋ◌̴ᅤ; ᄋ◌̴ᅤ; ᄋ◌̴ᅤ; ) HANGUL CHOSEONG IEUNG, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG YAE
+110B 0334 1171;110B 0334 1171;110B 0334 1171;110B 0334 1171;110B 0334 1171; # (ᄋ◌̴ᅱ; ᄋ◌̴ᅱ; ᄋ◌̴ᅱ; ᄋ◌̴ᅱ; ᄋ◌̴ᅱ; ) HANGUL CHOSEONG IEUNG, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG WI
+110C 0334 1169;110C 0334 1169;110C 0334 1169;110C 0334 1169;110C 0334 1169; # (ᄌ◌̴ᅩ; ᄌ◌̴ᅩ; ᄌ◌̴ᅩ; ᄌ◌̴ᅩ; ᄌ◌̴ᅩ; ) HANGUL CHOSEONG CIEUC, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG O
+110D 0334 1161;110D 0334 1161;110D 0334 1161;110D 0334 1161;110D 0334 1161; # (ᄍ◌̴ᅡ; ᄍ◌̴ᅡ; ᄍ◌̴ᅡ; ᄍ◌̴ᅡ; ᄍ◌̴ᅡ; ) HANGUL CHOSEONG SSANGCIEUC, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG A
+110D 0334 116E;110D 0334 116E;110D 0334 116E;110D 0334 116E;110D 0334 116E; # (ᄍ◌̴ᅮ; ᄍ◌̴ᅮ; ᄍ◌̴ᅮ; ᄍ◌̴ᅮ; ᄍ◌̴ᅮ; ) HANGUL CHOSEONG SSANGCIEUC, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG U
+110E 0334 1166;110E 0334 1166;110E 0334 1166;110E 0334 1166;110E 0334 1166; # (ᄎ◌̴ᅦ; ᄎ◌̴ᅦ; ᄎ◌̴ᅦ; ᄎ◌̴ᅦ; ᄎ◌̴ᅦ; ) HANGUL CHOSEONG CHIEUCH, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG E
+110E 0334 1173;110E 0334 1173;110E 0334 1173;110E 0334 1173;110E 0334 1173; # (ᄎ◌̴ᅳ; ᄎ◌̴ᅳ; ᄎ◌̴ᅳ; ᄎ◌̴ᅳ; ᄎ◌̴ᅳ; ) HANGUL CHOSEONG CHIEUCH, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG EU
+110F 0334 116B;110F 0334 116B;110F 0334 116B;110F 0334 116B;110F 0334 116B; # (ᄏ◌̴ᅫ; ᄏ◌̴ᅫ; ᄏ◌̴ᅫ; ᄏ◌̴ᅫ; ᄏ◌̴ᅫ; ) HANGUL CHOSEONG KHIEUKH, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG WAE
+1110 0334 1163;1110 0334 1163;1110 0334 1163;1110 0334 1163;1110 0334 1163; # (ᄐ◌̴ᅣ; ᄐ◌̴ᅣ; ᄐ◌̴ᅣ; ᄐ◌̴ᅣ; ᄐ◌̴ᅣ; ) HANGUL CHOSEONG THIEUTH, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG YA
+1110 0334 1170;1110 0334 1170;1110 0334 1170;1110 0334 1170;1110 0334 1170; # (ᄐ◌̴ᅰ; ᄐ◌̴ᅰ; ᄐ◌̴ᅰ; ᄐ◌̴ᅰ; ᄐ◌̴ᅰ; ) HANGUL CHOSEONG THIEUTH, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG WE
+1111 0334 1168;1111 0334 1168;1111 0334 1168;1111 0334 1168;1111 0334 1168; # (ᄑ◌̴ᅨ; ᄑ◌̴ᅨ; ᄑ◌̴ᅨ; ᄑ◌̴ᅨ; ᄑ◌̴ᅨ; ) HANGUL CHOSEONG PHIEUPH, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG YE
+1111 0334 1175;1111 0334 1175;1111 0334 1175;1111 0334 1175;1111 0334 1175; # (ᄑ◌̴ᅵ; ᄑ◌̴ᅵ; ᄑ◌̴ᅵ; ᄑ◌̴ᅵ; ᄑ◌̴ᅵ; ) HANGUL CHOSEONG PHIEUPH, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG I
+1112 0334 116D;1112 0334 116D;1112 0334 116D;1112 0334 116D;1112 0334 116D; # (ᄒ◌̴ᅭ; ᄒ◌̴ᅭ; ᄒ◌̴ᅭ; ᄒ◌̴ᅭ; ᄒ◌̴ᅭ; ) HANGUL CHOSEONG HIEUH, COMBINING TILDE OVERLAY, HANGUL JUNGSEONG YO
+1B05 0334 1B35;1B05 0334 1B35;1B05 0334 1B35;1B05 0334 1B35;1B05 0334 1B35; # (ᬅ◌̴ᬵ; ᬅ◌̴ᬵ; ᬅ◌̴ᬵ; ᬅ◌̴ᬵ; ᬅ◌̴ᬵ; ) BALINESE LETTER AKARA, COMBINING TILDE OVERLAY, BALINESE VOWEL SIGN TEDUNG
+1B07 0334 1B35;1B07 0334 1B35;1B07 0334 1B35;1B07 0334 1B35;1B07 0334 1B35; # (ᬇ◌̴ᬵ; ᬇ◌̴ᬵ; ᬇ◌̴ᬵ; ᬇ◌̴ᬵ; ᬇ◌̴ᬵ; ) BALINESE LETTER IKARA, COMBINING TILDE OVERLAY, BALINESE VOWEL SIGN TEDUNG
+1B09 0334 1B35;1B09 0334 1B35;1B09 0334 1B35;1B09 0334 1B35;1B09 0334 1B35; # (ᬉ◌̴ᬵ; ᬉ◌̴ᬵ; ᬉ◌̴ᬵ; ᬉ◌̴ᬵ; ᬉ◌̴ᬵ; ) BALINESE LETTER UKARA, COMBINING TILDE OVERLAY, BALINESE VOWEL SIGN TEDUNG
+1B0B 0334 1B35;1B0B 0334 1B35;1B0B 0334 1B35;1B0B 0334 1B35;1B0B 0334 1B35; # (ᬋ◌̴ᬵ; ᬋ◌̴ᬵ; ᬋ◌̴ᬵ; ᬋ◌̴ᬵ; ᬋ◌̴ᬵ; ) BALINESE LETTER RA REPA, COMBINING TILDE OVERLAY, BALINESE VOWEL SIGN TEDUNG
+1B0D 0334 1B35;1B0D 0334 1B35;1B0D 0334 1B35;1B0D 0334 1B35;1B0D 0334 1B35; # (ᬍ◌̴ᬵ; ᬍ◌̴ᬵ; ᬍ◌̴ᬵ; ᬍ◌̴ᬵ; ᬍ◌̴ᬵ; ) BALINESE LETTER LA LENGA, COMBINING TILDE OVERLAY, BALINESE VOWEL SIGN TEDUNG
+1B11 0334 1B35;1B11 0334 1B35;1B11 0334 1B35;1B11 0334 1B35;1B11 0334 1B35; # (ᬑ◌̴ᬵ; ᬑ◌̴ᬵ; ᬑ◌̴ᬵ; ᬑ◌̴ᬵ; ᬑ◌̴ᬵ; ) BALINESE LETTER OKARA, COMBINING TILDE OVERLAY, BALINESE VOWEL SIGN TEDUNG
+1B3A 0334 1B35;1B3A 0334 1B35;1B3A 0334 1B35;1B3A 0334 1B35;1B3A 0334 1B35; # (◌ᬺ◌̴ᬵ; ◌ᬺ◌̴ᬵ; ◌ᬺ◌̴ᬵ; ◌ᬺ◌̴ᬵ; ◌ᬺ◌̴ᬵ; ) BALINESE VOWEL SIGN RA REPA, COMBINING TILDE OVERLAY, BALINESE VOWEL SIGN TEDUNG
+1B3C 0334 1B35;1B3C 0334 1B35;1B3C 0334 1B35;1B3C 0334 1B35;1B3C 0334 1B35; # (◌ᬼ◌̴ᬵ; ◌ᬼ◌̴ᬵ; ◌ᬼ◌̴ᬵ; ◌ᬼ◌̴ᬵ; ◌ᬼ◌̴ᬵ; ) BALINESE VOWEL SIGN LA LENGA, COMBINING TILDE OVERLAY, BALINESE VOWEL SIGN TEDUNG
+1B3E 0334 1B35;1B3E 0334 1B35;1B3E 0334 1B35;1B3E 0334 1B35;1B3E 0334 1B35; # (ᬾ◌̴ᬵ; ᬾ◌̴ᬵ; ᬾ◌̴ᬵ; ᬾ◌̴ᬵ; ᬾ◌̴ᬵ; ) BALINESE VOWEL SIGN TALING, COMBINING TILDE OVERLAY, BALINESE VOWEL SIGN TEDUNG
+1B3F 0334 1B35;1B3F 0334 1B35;1B3F 0334 1B35;1B3F 0334 1B35;1B3F 0334 1B35; # (ᬿ◌̴ᬵ; ᬿ◌̴ᬵ; ᬿ◌̴ᬵ; ᬿ◌̴ᬵ; ᬿ◌̴ᬵ; ) BALINESE VOWEL SIGN TALING REPA, COMBINING TILDE OVERLAY, BALINESE VOWEL SIGN TEDUNG
+1B42 0334 1B35;1B42 0334 1B35;1B42 0334 1B35;1B42 0334 1B35;1B42 0334 1B35; # (◌ᭂ◌̴ᬵ; ◌ᭂ◌̴ᬵ; ◌ᭂ◌̴ᬵ; ◌ᭂ◌̴ᬵ; ◌ᭂ◌̴ᬵ; ) BALINESE VOWEL SIGN PEPET, COMBINING TILDE OVERLAY, BALINESE VOWEL SIGN TEDUNG
+AC54 0334 11AE;AC54 0334 11AE;1100 1164 0334 11AE;AC54 0334 11AE;1100 1164 0334 11AE; # (걔◌̴ᆮ; 걔◌̴ᆮ; 걔◌̴ᆮ; 걔◌̴ᆮ; 걔◌̴ᆮ; ) HANGUL SYLLABLE GYAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+ACA8 0334 11B5;ACA8 0334 11B5;1100 1167 0334 11B5;ACA8 0334 11B5;1100 1167 0334 11B5; # (겨◌̴ᆵ; 겨◌̴ᆵ; 겨◌̴ᆵ; 겨◌̴ᆵ; 겨◌̴ᆵ; ) HANGUL SYLLABLE GYEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+ACFC 0334 11BC;ACFC 0334 11BC;1100 116A 0334 11BC;ACFC 0334 11BC;1100 116A 0334 11BC; # (과◌̴ᆼ; 과◌̴ᆼ; 과◌̴ᆼ; 과◌̴ᆼ; 과◌̴ᆼ; ) HANGUL SYLLABLE GWA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+ADC0 0334 11AE;ADC0 0334 11AE;1100 1171 0334 11AE;ADC0 0334 11AE;1100 1171 0334 11AE; # (귀◌̴ᆮ; 귀◌̴ᆮ; 귀◌̴ᆮ; 귀◌̴ᆮ; 귀◌̴ᆮ; ) HANGUL SYLLABLE GWI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+AE14 0334 11B5;AE14 0334 11B5;1100 1174 0334 11B5;AE14 0334 11B5;1100 1174 0334 11B5; # (긔◌̴ᆵ; 긔◌̴ᆵ; 긔◌̴ᆵ; 긔◌̴ᆵ; 긔◌̴ᆵ; ) HANGUL SYLLABLE GYI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+AE68 0334 11BC;AE68 0334 11BC;1101 1162 0334 11BC;AE68 0334 11BC;1101 1162 0334 11BC; # (깨◌̴ᆼ; 깨◌̴ᆼ; 깨◌̴ᆼ; 깨◌̴ᆼ; 깨◌̴ᆼ; ) HANGUL SYLLABLE GGAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+AF2C 0334 11AE;AF2C 0334 11AE;1101 1169 0334 11AE;AF2C 0334 11AE;1101 1169 0334 11AE; # (꼬◌̴ᆮ; 꼬◌̴ᆮ; 꼬◌̴ᆮ; 꼬◌̴ᆮ; 꼬◌̴ᆮ; ) HANGUL SYLLABLE GGO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+AF80 0334 11B5;AF80 0334 11B5;1101 116C 0334 11B5;AF80 0334 11B5;1101 116C 0334 11B5; # (꾀◌̴ᆵ; 꾀◌̴ᆵ; 꾀◌̴ᆵ; 꾀◌̴ᆵ; 꾀◌̴ᆵ; ) HANGUL SYLLABLE GGOE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+AFD4 0334 11BC;AFD4 0334 11BC;1101 116F 0334 11BC;AFD4 0334 11BC;1101 116F 0334 11BC; # (꿔◌̴ᆼ; 꿔◌̴ᆼ; 꿔◌̴ᆼ; 꿔◌̴ᆼ; 꿔◌̴ᆼ; ) HANGUL SYLLABLE GGWEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+B098 0334 11AE;B098 0334 11AE;1102 1161 0334 11AE;B098 0334 11AE;1102 1161 0334 11AE; # (나◌̴ᆮ; 나◌̴ᆮ; 나◌̴ᆮ; 나◌̴ᆮ; 나◌̴ᆮ; ) HANGUL SYLLABLE NA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+B0EC 0334 11B5;B0EC 0334 11B5;1102 1164 0334 11B5;B0EC 0334 11B5;1102 1164 0334 11B5; # (냬◌̴ᆵ; 냬◌̴ᆵ; 냬◌̴ᆵ; 냬◌̴ᆵ; 냬◌̴ᆵ; ) HANGUL SYLLABLE NYAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+B140 0334 11BC;B140 0334 11BC;1102 1167 0334 11BC;B140 0334 11BC;1102 1167 0334 11BC; # (녀◌̴ᆼ; 녀◌̴ᆼ; 녀◌̴ᆼ; 녀◌̴ᆼ; 녀◌̴ᆼ; ) HANGUL SYLLABLE NYEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+B204 0334 11AE;B204 0334 11AE;1102 116E 0334 11AE;B204 0334 11AE;1102 116E 0334 11AE; # (누◌̴ᆮ; 누◌̴ᆮ; 누◌̴ᆮ; 누◌̴ᆮ; 누◌̴ᆮ; ) HANGUL SYLLABLE NU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+B258 0334 11B5;B258 0334 11B5;1102 1171 0334 11B5;B258 0334 11B5;1102 1171 0334 11B5; # (뉘◌̴ᆵ; 뉘◌̴ᆵ; 뉘◌̴ᆵ; 뉘◌̴ᆵ; 뉘◌̴ᆵ; ) HANGUL SYLLABLE NWI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+B2AC 0334 11BC;B2AC 0334 11BC;1102 1174 0334 11BC;B2AC 0334 11BC;1102 1174 0334 11BC; # (늬◌̴ᆼ; 늬◌̴ᆼ; 늬◌̴ᆼ; 늬◌̴ᆼ; 늬◌̴ᆼ; ) HANGUL SYLLABLE NYI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+B370 0334 11AE;B370 0334 11AE;1103 1166 0334 11AE;B370 0334 11AE;1103 1166 0334 11AE; # (데◌̴ᆮ; 데◌̴ᆮ; 데◌̴ᆮ; 데◌̴ᆮ; 데◌̴ᆮ; ) HANGUL SYLLABLE DE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+B3C4 0334 11B5;B3C4 0334 11B5;1103 1169 0334 11B5;B3C4 0334 11B5;1103 1169 0334 11B5; # (도◌̴ᆵ; 도◌̴ᆵ; 도◌̴ᆵ; 도◌̴ᆵ; 도◌̴ᆵ; ) HANGUL SYLLABLE DO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+B418 0334 11BC;B418 0334 11BC;1103 116C 0334 11BC;B418 0334 11BC;1103 116C 0334 11BC; # (되◌̴ᆼ; 되◌̴ᆼ; 되◌̴ᆼ; 되◌̴ᆼ; 되◌̴ᆼ; ) HANGUL SYLLABLE DOE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+B4DC 0334 11AE;B4DC 0334 11AE;1103 1173 0334 11AE;B4DC 0334 11AE;1103 1173 0334 11AE; # (드◌̴ᆮ; 드◌̴ᆮ; 드◌̴ᆮ; 드◌̴ᆮ; 드◌̴ᆮ; ) HANGUL SYLLABLE DEU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+B530 0334 11B5;B530 0334 11B5;1104 1161 0334 11B5;B530 0334 11B5;1104 1161 0334 11B5; # (따◌̴ᆵ; 따◌̴ᆵ; 따◌̴ᆵ; 따◌̴ᆵ; 따◌̴ᆵ; ) HANGUL SYLLABLE DDA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+B584 0334 11BC;B584 0334 11BC;1104 1164 0334 11BC;B584 0334 11BC;1104 1164 0334 11BC; # (떄◌̴ᆼ; 떄◌̴ᆼ; 떄◌̴ᆼ; 떄◌̴ᆼ; 떄◌̴ᆼ; ) HANGUL SYLLABLE DDYAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+B648 0334 11AE;B648 0334 11AE;1104 116B 0334 11AE;B648 0334 11AE;1104 116B 0334 11AE; # (뙈◌̴ᆮ; 뙈◌̴ᆮ; 뙈◌̴ᆮ; 뙈◌̴ᆮ; 뙈◌̴ᆮ; ) HANGUL SYLLABLE DDWAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+B69C 0334 11B5;B69C 0334 11B5;1104 116E 0334 11B5;B69C 0334 11B5;1104 116E 0334 11B5; # (뚜◌̴ᆵ; 뚜◌̴ᆵ; 뚜◌̴ᆵ; 뚜◌̴ᆵ; 뚜◌̴ᆵ; ) HANGUL SYLLABLE DDU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+B6F0 0334 11BC;B6F0 0334 11BC;1104 1171 0334 11BC;B6F0 0334 11BC;1104 1171 0334 11BC; # (뛰◌̴ᆼ; 뛰◌̴ᆼ; 뛰◌̴ᆼ; 뛰◌̴ᆼ; 뛰◌̴ᆼ; ) HANGUL SYLLABLE DDWI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+B7B4 0334 11AE;B7B4 0334 11AE;1105 1163 0334 11AE;B7B4 0334 11AE;1105 1163 0334 11AE; # (랴◌̴ᆮ; 랴◌̴ᆮ; 랴◌̴ᆮ; 랴◌̴ᆮ; 랴◌̴ᆮ; ) HANGUL SYLLABLE RYA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+B808 0334 11B5;B808 0334 11B5;1105 1166 0334 11B5;B808 0334 11B5;1105 1166 0334 11B5; # (레◌̴ᆵ; 레◌̴ᆵ; 레◌̴ᆵ; 레◌̴ᆵ; 레◌̴ᆵ; ) HANGUL SYLLABLE RE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+B85C 0334 11BC;B85C 0334 11BC;1105 1169 0334 11BC;B85C 0334 11BC;1105 1169 0334 11BC; # (로◌̴ᆼ; 로◌̴ᆼ; 로◌̴ᆼ; 로◌̴ᆼ; 로◌̴ᆼ; ) HANGUL SYLLABLE RO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+B920 0334 11AE;B920 0334 11AE;1105 1170 0334 11AE;B920 0334 11AE;1105 1170 0334 11AE; # (뤠◌̴ᆮ; 뤠◌̴ᆮ; 뤠◌̴ᆮ; 뤠◌̴ᆮ; 뤠◌̴ᆮ; ) HANGUL SYLLABLE RWE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+B974 0334 11B5;B974 0334 11B5;1105 1173 0334 11B5;B974 0334 11B5;1105 1173 0334 11B5; # (르◌̴ᆵ; 르◌̴ᆵ; 르◌̴ᆵ; 르◌̴ᆵ; 르◌̴ᆵ; ) HANGUL SYLLABLE REU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+B9C8 0334 11BC;B9C8 0334 11BC;1106 1161 0334 11BC;B9C8 0334 11BC;1106 1161 0334 11BC; # (마◌̴ᆼ; 마◌̴ᆼ; 마◌̴ᆼ; 마◌̴ᆼ; 마◌̴ᆼ; ) HANGUL SYLLABLE MA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+BA8C 0334 11AE;BA8C 0334 11AE;1106 1168 0334 11AE;BA8C 0334 11AE;1106 1168 0334 11AE; # (몌◌̴ᆮ; 몌◌̴ᆮ; 몌◌̴ᆮ; 몌◌̴ᆮ; 몌◌̴ᆮ; ) HANGUL SYLLABLE MYE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+BAE0 0334 11B5;BAE0 0334 11B5;1106 116B 0334 11B5;BAE0 0334 11B5;1106 116B 0334 11B5; # (뫠◌̴ᆵ; 뫠◌̴ᆵ; 뫠◌̴ᆵ; 뫠◌̴ᆵ; 뫠◌̴ᆵ; ) HANGUL SYLLABLE MWAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+BB34 0334 11BC;BB34 0334 11BC;1106 116E 0334 11BC;BB34 0334 11BC;1106 116E 0334 11BC; # (무◌̴ᆼ; 무◌̴ᆼ; 무◌̴ᆼ; 무◌̴ᆼ; 무◌̴ᆼ; ) HANGUL SYLLABLE MU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+BBF8 0334 11AE;BBF8 0334 11AE;1106 1175 0334 11AE;BBF8 0334 11AE;1106 1175 0334 11AE; # (미◌̴ᆮ; 미◌̴ᆮ; 미◌̴ᆮ; 미◌̴ᆮ; 미◌̴ᆮ; ) HANGUL SYLLABLE MI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+BC4C 0334 11B5;BC4C 0334 11B5;1107 1163 0334 11B5;BC4C 0334 11B5;1107 1163 0334 11B5; # (뱌◌̴ᆵ; 뱌◌̴ᆵ; 뱌◌̴ᆵ; 뱌◌̴ᆵ; 뱌◌̴ᆵ; ) HANGUL SYLLABLE BYA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+BCA0 0334 11BC;BCA0 0334 11BC;1107 1166 0334 11BC;BCA0 0334 11BC;1107 1166 0334 11BC; # (베◌̴ᆼ; 베◌̴ᆼ; 베◌̴ᆼ; 베◌̴ᆼ; 베◌̴ᆼ; ) HANGUL SYLLABLE BE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+BD64 0334 11AE;BD64 0334 11AE;1107 116D 0334 11AE;BD64 0334 11AE;1107 116D 0334 11AE; # (뵤◌̴ᆮ; 뵤◌̴ᆮ; 뵤◌̴ᆮ; 뵤◌̴ᆮ; 뵤◌̴ᆮ; ) HANGUL SYLLABLE BYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+BDB8 0334 11B5;BDB8 0334 11B5;1107 1170 0334 11B5;BDB8 0334 11B5;1107 1170 0334 11B5; # (붸◌̴ᆵ; 붸◌̴ᆵ; 붸◌̴ᆵ; 붸◌̴ᆵ; 붸◌̴ᆵ; ) HANGUL SYLLABLE BWE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+BE0C 0334 11BC;BE0C 0334 11BC;1107 1173 0334 11BC;BE0C 0334 11BC;1107 1173 0334 11BC; # (브◌̴ᆼ; 브◌̴ᆼ; 브◌̴ᆼ; 브◌̴ᆼ; 브◌̴ᆼ; ) HANGUL SYLLABLE BEU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+BED0 0334 11AE;BED0 0334 11AE;1108 1165 0334 11AE;BED0 0334 11AE;1108 1165 0334 11AE; # (뻐◌̴ᆮ; 뻐◌̴ᆮ; 뻐◌̴ᆮ; 뻐◌̴ᆮ; 뻐◌̴ᆮ; ) HANGUL SYLLABLE BBEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+BF24 0334 11B5;BF24 0334 11B5;1108 1168 0334 11B5;BF24 0334 11B5;1108 1168 0334 11B5; # (뼤◌̴ᆵ; 뼤◌̴ᆵ; 뼤◌̴ᆵ; 뼤◌̴ᆵ; 뼤◌̴ᆵ; ) HANGUL SYLLABLE BBYE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+BF78 0334 11BC;BF78 0334 11BC;1108 116B 0334 11BC;BF78 0334 11BC;1108 116B 0334 11BC; # (뽸◌̴ᆼ; 뽸◌̴ᆼ; 뽸◌̴ᆼ; 뽸◌̴ᆼ; 뽸◌̴ᆼ; ) HANGUL SYLLABLE BBWAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+C03C 0334 11AE;C03C 0334 11AE;1108 1172 0334 11AE;C03C 0334 11AE;1108 1172 0334 11AE; # (쀼◌̴ᆮ; 쀼◌̴ᆮ; 쀼◌̴ᆮ; 쀼◌̴ᆮ; 쀼◌̴ᆮ; ) HANGUL SYLLABLE BBYU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+C090 0334 11B5;C090 0334 11B5;1108 1175 0334 11B5;C090 0334 11B5;1108 1175 0334 11B5; # (삐◌̴ᆵ; 삐◌̴ᆵ; 삐◌̴ᆵ; 삐◌̴ᆵ; 삐◌̴ᆵ; ) HANGUL SYLLABLE BBI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+C0E4 0334 11BC;C0E4 0334 11BC;1109 1163 0334 11BC;C0E4 0334 11BC;1109 1163 0334 11BC; # (샤◌̴ᆼ; 샤◌̴ᆼ; 샤◌̴ᆼ; 샤◌̴ᆼ; 샤◌̴ᆼ; ) HANGUL SYLLABLE SYA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+C1A8 0334 11AE;C1A8 0334 11AE;1109 116A 0334 11AE;C1A8 0334 11AE;1109 116A 0334 11AE; # (솨◌̴ᆮ; 솨◌̴ᆮ; 솨◌̴ᆮ; 솨◌̴ᆮ; 솨◌̴ᆮ; ) HANGUL SYLLABLE SWA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+C1FC 0334 11B5;C1FC 0334 11B5;1109 116D 0334 11B5;C1FC 0334 11B5;1109 116D 0334 11B5; # (쇼◌̴ᆵ; 쇼◌̴ᆵ; 쇼◌̴ᆵ; 쇼◌̴ᆵ; 쇼◌̴ᆵ; ) HANGUL SYLLABLE SYO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+C250 0334 11BC;C250 0334 11BC;1109 1170 0334 11BC;C250 0334 11BC;1109 1170 0334 11BC; # (쉐◌̴ᆼ; 쉐◌̴ᆼ; 쉐◌̴ᆼ; 쉐◌̴ᆼ; 쉐◌̴ᆼ; ) HANGUL SYLLABLE SWE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+C314 0334 11AE;C314 0334 11AE;110A 1162 0334 11AE;C314 0334 11AE;110A 1162 0334 11AE; # (쌔◌̴ᆮ; 쌔◌̴ᆮ; 쌔◌̴ᆮ; 쌔◌̴ᆮ; 쌔◌̴ᆮ; ) HANGUL SYLLABLE SSAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+C368 0334 11B5;C368 0334 11B5;110A 1165 0334 11B5;C368 0334 11B5;110A 1165 0334 11B5; # (써◌̴ᆵ; 써◌̴ᆵ; 써◌̴ᆵ; 써◌̴ᆵ; 써◌̴ᆵ; ) HANGUL SYLLABLE SSEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+C3BC 0334 11BC;C3BC 0334 11BC;110A 1168 0334 11BC;C3BC 0334 11BC;110A 1168 0334 11BC; # (쎼◌̴ᆼ; 쎼◌̴ᆼ; 쎼◌̴ᆼ; 쎼◌̴ᆼ; 쎼◌̴ᆼ; ) HANGUL SYLLABLE SSYE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+C480 0334 11AE;C480 0334 11AE;110A 116F 0334 11AE;C480 0334 11AE;110A 116F 0334 11AE; # (쒀◌̴ᆮ; 쒀◌̴ᆮ; 쒀◌̴ᆮ; 쒀◌̴ᆮ; 쒀◌̴ᆮ; ) HANGUL SYLLABLE SSWEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+C4D4 0334 11B5;C4D4 0334 11B5;110A 1172 0334 11B5;C4D4 0334 11B5;110A 1172 0334 11B5; # (쓔◌̴ᆵ; 쓔◌̴ᆵ; 쓔◌̴ᆵ; 쓔◌̴ᆵ; 쓔◌̴ᆵ; ) HANGUL SYLLABLE SSYU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+C528 0334 11BC;C528 0334 11BC;110A 1175 0334 11BC;C528 0334 11BC;110A 1175 0334 11BC; # (씨◌̴ᆼ; 씨◌̴ᆼ; 씨◌̴ᆼ; 씨◌̴ᆼ; 씨◌̴ᆼ; ) HANGUL SYLLABLE SSI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+C5EC 0334 11AE;C5EC 0334 11AE;110B 1167 0334 11AE;C5EC 0334 11AE;110B 1167 0334 11AE; # (여◌̴ᆮ; 여◌̴ᆮ; 여◌̴ᆮ; 여◌̴ᆮ; 여◌̴ᆮ; ) HANGUL SYLLABLE YEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+C640 0334 11B5;C640 0334 11B5;110B 116A 0334 11B5;C640 0334 11B5;110B 116A 0334 11B5; # (와◌̴ᆵ; 와◌̴ᆵ; 와◌̴ᆵ; 와◌̴ᆵ; 와◌̴ᆵ; ) HANGUL SYLLABLE WA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+C694 0334 11BC;C694 0334 11BC;110B 116D 0334 11BC;C694 0334 11BC;110B 116D 0334 11BC; # (요◌̴ᆼ; 요◌̴ᆼ; 요◌̴ᆼ; 요◌̴ᆼ; 요◌̴ᆼ; ) HANGUL SYLLABLE YO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+C758 0334 11AE;C758 0334 11AE;110B 1174 0334 11AE;C758 0334 11AE;110B 1174 0334 11AE; # (의◌̴ᆮ; 의◌̴ᆮ; 의◌̴ᆮ; 의◌̴ᆮ; 의◌̴ᆮ; ) HANGUL SYLLABLE YI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+C7AC 0334 11B5;C7AC 0334 11B5;110C 1162 0334 11B5;C7AC 0334 11B5;110C 1162 0334 11B5; # (재◌̴ᆵ; 재◌̴ᆵ; 재◌̴ᆵ; 재◌̴ᆵ; 재◌̴ᆵ; ) HANGUL SYLLABLE JAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+C800 0334 11BC;C800 0334 11BC;110C 1165 0334 11BC;C800 0334 11BC;110C 1165 0334 11BC; # (저◌̴ᆼ; 저◌̴ᆼ; 저◌̴ᆼ; 저◌̴ᆼ; 저◌̴ᆼ; ) HANGUL SYLLABLE JEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+C8C4 0334 11AE;C8C4 0334 11AE;110C 116C 0334 11AE;C8C4 0334 11AE;110C 116C 0334 11AE; # (죄◌̴ᆮ; 죄◌̴ᆮ; 죄◌̴ᆮ; 죄◌̴ᆮ; 죄◌̴ᆮ; ) HANGUL SYLLABLE JOE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+C918 0334 11B5;C918 0334 11B5;110C 116F 0334 11B5;C918 0334 11B5;110C 116F 0334 11B5; # (줘◌̴ᆵ; 줘◌̴ᆵ; 줘◌̴ᆵ; 줘◌̴ᆵ; 줘◌̴ᆵ; ) HANGUL SYLLABLE JWEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+C96C 0334 11BC;C96C 0334 11BC;110C 1172 0334 11BC;C96C 0334 11BC;110C 1172 0334 11BC; # (쥬◌̴ᆼ; 쥬◌̴ᆼ; 쥬◌̴ᆼ; 쥬◌̴ᆼ; 쥬◌̴ᆼ; ) HANGUL SYLLABLE JYU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+CA30 0334 11AE;CA30 0334 11AE;110D 1164 0334 11AE;CA30 0334 11AE;110D 1164 0334 11AE; # (쨰◌̴ᆮ; 쨰◌̴ᆮ; 쨰◌̴ᆮ; 쨰◌̴ᆮ; 쨰◌̴ᆮ; ) HANGUL SYLLABLE JJYAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+CA84 0334 11B5;CA84 0334 11B5;110D 1167 0334 11B5;CA84 0334 11B5;110D 1167 0334 11B5; # (쪄◌̴ᆵ; 쪄◌̴ᆵ; 쪄◌̴ᆵ; 쪄◌̴ᆵ; 쪄◌̴ᆵ; ) HANGUL SYLLABLE JJYEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+CAD8 0334 11BC;CAD8 0334 11BC;110D 116A 0334 11BC;CAD8 0334 11BC;110D 116A 0334 11BC; # (쫘◌̴ᆼ; 쫘◌̴ᆼ; 쫘◌̴ᆼ; 쫘◌̴ᆼ; 쫘◌̴ᆼ; ) HANGUL SYLLABLE JJWA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+CB9C 0334 11AE;CB9C 0334 11AE;110D 1171 0334 11AE;CB9C 0334 11AE;110D 1171 0334 11AE; # (쮜◌̴ᆮ; 쮜◌̴ᆮ; 쮜◌̴ᆮ; 쮜◌̴ᆮ; 쮜◌̴ᆮ; ) HANGUL SYLLABLE JJWI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+CBF0 0334 11B5;CBF0 0334 11B5;110D 1174 0334 11B5;CBF0 0334 11B5;110D 1174 0334 11B5; # (쯰◌̴ᆵ; 쯰◌̴ᆵ; 쯰◌̴ᆵ; 쯰◌̴ᆵ; 쯰◌̴ᆵ; ) HANGUL SYLLABLE JJYI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+CC44 0334 11BC;CC44 0334 11BC;110E 1162 0334 11BC;CC44 0334 11BC;110E 1162 0334 11BC; # (채◌̴ᆼ; 채◌̴ᆼ; 채◌̴ᆼ; 채◌̴ᆼ; 채◌̴ᆼ; ) HANGUL SYLLABLE CAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+CD08 0334 11AE;CD08 0334 11AE;110E 1169 0334 11AE;CD08 0334 11AE;110E 1169 0334 11AE; # (초◌̴ᆮ; 초◌̴ᆮ; 초◌̴ᆮ; 초◌̴ᆮ; 초◌̴ᆮ; ) HANGUL SYLLABLE CO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+CD5C 0334 11B5;CD5C 0334 11B5;110E 116C 0334 11B5;CD5C 0334 11B5;110E 116C 0334 11B5; # (최◌̴ᆵ; 최◌̴ᆵ; 최◌̴ᆵ; 최◌̴ᆵ; 최◌̴ᆵ; ) HANGUL SYLLABLE COE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+CDB0 0334 11BC;CDB0 0334 11BC;110E 116F 0334 11BC;CDB0 0334 11BC;110E 116F 0334 11BC; # (춰◌̴ᆼ; 춰◌̴ᆼ; 춰◌̴ᆼ; 춰◌̴ᆼ; 춰◌̴ᆼ; ) HANGUL SYLLABLE CWEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+CE74 0334 11AE;CE74 0334 11AE;110F 1161 0334 11AE;CE74 0334 11AE;110F 1161 0334 11AE; # (카◌̴ᆮ; 카◌̴ᆮ; 카◌̴ᆮ; 카◌̴ᆮ; 카◌̴ᆮ; ) HANGUL SYLLABLE KA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+CEC8 0334 11B5;CEC8 0334 11B5;110F 1164 0334 11B5;CEC8 0334 11B5;110F 1164 0334 11B5; # (컈◌̴ᆵ; 컈◌̴ᆵ; 컈◌̴ᆵ; 컈◌̴ᆵ; 컈◌̴ᆵ; ) HANGUL SYLLABLE KYAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+CF1C 0334 11BC;CF1C 0334 11BC;110F 1167 0334 11BC;CF1C 0334 11BC;110F 1167 0334 11BC; # (켜◌̴ᆼ; 켜◌̴ᆼ; 켜◌̴ᆼ; 켜◌̴ᆼ; 켜◌̴ᆼ; ) HANGUL SYLLABLE KYEO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+CFE0 0334 11AE;CFE0 0334 11AE;110F 116E 0334 11AE;CFE0 0334 11AE;110F 116E 0334 11AE; # (쿠◌̴ᆮ; 쿠◌̴ᆮ; 쿠◌̴ᆮ; 쿠◌̴ᆮ; 쿠◌̴ᆮ; ) HANGUL SYLLABLE KU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+D034 0334 11B5;D034 0334 11B5;110F 1171 0334 11B5;D034 0334 11B5;110F 1171 0334 11B5; # (퀴◌̴ᆵ; 퀴◌̴ᆵ; 퀴◌̴ᆵ; 퀴◌̴ᆵ; 퀴◌̴ᆵ; ) HANGUL SYLLABLE KWI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+D088 0334 11BC;D088 0334 11BC;110F 1174 0334 11BC;D088 0334 11BC;110F 1174 0334 11BC; # (킈◌̴ᆼ; 킈◌̴ᆼ; 킈◌̴ᆼ; 킈◌̴ᆼ; 킈◌̴ᆼ; ) HANGUL SYLLABLE KYI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+D14C 0334 11AE;D14C 0334 11AE;1110 1166 0334 11AE;D14C 0334 11AE;1110 1166 0334 11AE; # (테◌̴ᆮ; 테◌̴ᆮ; 테◌̴ᆮ; 테◌̴ᆮ; 테◌̴ᆮ; ) HANGUL SYLLABLE TE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+D1A0 0334 11B5;D1A0 0334 11B5;1110 1169 0334 11B5;D1A0 0334 11B5;1110 1169 0334 11B5; # (토◌̴ᆵ; 토◌̴ᆵ; 토◌̴ᆵ; 토◌̴ᆵ; 토◌̴ᆵ; ) HANGUL SYLLABLE TO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+D1F4 0334 11BC;D1F4 0334 11BC;1110 116C 0334 11BC;D1F4 0334 11BC;1110 116C 0334 11BC; # (퇴◌̴ᆼ; 퇴◌̴ᆼ; 퇴◌̴ᆼ; 퇴◌̴ᆼ; 퇴◌̴ᆼ; ) HANGUL SYLLABLE TOE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+D2B8 0334 11AE;D2B8 0334 11AE;1110 1173 0334 11AE;D2B8 0334 11AE;1110 1173 0334 11AE; # (트◌̴ᆮ; 트◌̴ᆮ; 트◌̴ᆮ; 트◌̴ᆮ; 트◌̴ᆮ; ) HANGUL SYLLABLE TEU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+D30C 0334 11B5;D30C 0334 11B5;1111 1161 0334 11B5;D30C 0334 11B5;1111 1161 0334 11B5; # (파◌̴ᆵ; 파◌̴ᆵ; 파◌̴ᆵ; 파◌̴ᆵ; 파◌̴ᆵ; ) HANGUL SYLLABLE PA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+D360 0334 11BC;D360 0334 11BC;1111 1164 0334 11BC;D360 0334 11BC;1111 1164 0334 11BC; # (퍠◌̴ᆼ; 퍠◌̴ᆼ; 퍠◌̴ᆼ; 퍠◌̴ᆼ; 퍠◌̴ᆼ; ) HANGUL SYLLABLE PYAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+D424 0334 11AE;D424 0334 11AE;1111 116B 0334 11AE;D424 0334 11AE;1111 116B 0334 11AE; # (퐤◌̴ᆮ; 퐤◌̴ᆮ; 퐤◌̴ᆮ; 퐤◌̴ᆮ; 퐤◌̴ᆮ; ) HANGUL SYLLABLE PWAE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+D478 0334 11B5;D478 0334 11B5;1111 116E 0334 11B5;D478 0334 11B5;1111 116E 0334 11B5; # (푸◌̴ᆵ; 푸◌̴ᆵ; 푸◌̴ᆵ; 푸◌̴ᆵ; 푸◌̴ᆵ; ) HANGUL SYLLABLE PU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+D4CC 0334 11BC;D4CC 0334 11BC;1111 1171 0334 11BC;D4CC 0334 11BC;1111 1171 0334 11BC; # (퓌◌̴ᆼ; 퓌◌̴ᆼ; 퓌◌̴ᆼ; 퓌◌̴ᆼ; 퓌◌̴ᆼ; ) HANGUL SYLLABLE PWI, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+D590 0334 11AE;D590 0334 11AE;1112 1163 0334 11AE;D590 0334 11AE;1112 1163 0334 11AE; # (햐◌̴ᆮ; 햐◌̴ᆮ; 햐◌̴ᆮ; 햐◌̴ᆮ; 햐◌̴ᆮ; ) HANGUL SYLLABLE HYA, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+D5E4 0334 11B5;D5E4 0334 11B5;1112 1166 0334 11B5;D5E4 0334 11B5;1112 1166 0334 11B5; # (헤◌̴ᆵ; 헤◌̴ᆵ; 헤◌̴ᆵ; 헤◌̴ᆵ; 헤◌̴ᆵ; ) HANGUL SYLLABLE HE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+D638 0334 11BC;D638 0334 11BC;1112 1169 0334 11BC;D638 0334 11BC;1112 1169 0334 11BC; # (호◌̴ᆼ; 호◌̴ᆼ; 호◌̴ᆼ; 호◌̴ᆼ; 호◌̴ᆼ; ) HANGUL SYLLABLE HO, COMBINING TILDE OVERLAY, HANGUL JONGSEONG IEUNG
+D6FC 0334 11AE;D6FC 0334 11AE;1112 1170 0334 11AE;D6FC 0334 11AE;1112 1170 0334 11AE; # (훼◌̴ᆮ; 훼◌̴ᆮ; 훼◌̴ᆮ; 훼◌̴ᆮ; 훼◌̴ᆮ; ) HANGUL SYLLABLE HWE, COMBINING TILDE OVERLAY, HANGUL JONGSEONG TIKEUT
+D750 0334 11B5;D750 0334 11B5;1112 1173 0334 11B5;D750 0334 11B5;1112 1173 0334 11B5; # (흐◌̴ᆵ; 흐◌̴ᆵ; 흐◌̴ᆵ; 흐◌̴ᆵ; 흐◌̴ᆵ; ) HANGUL SYLLABLE HEU, COMBINING TILDE OVERLAY, HANGUL JONGSEONG RIEUL-PHIEUPH
+11131 0334 11127;11131 0334 11127;11131 0334 11127;11131 0334 11127;11131 0334 11127; # (◌𑄱◌̴◌𑄧; ◌𑄱◌̴◌𑄧; ◌𑄱◌̴◌𑄧; ◌𑄱◌̴◌𑄧; ◌𑄱◌̴◌𑄧; ) CHAKMA O MARK, COMBINING TILDE OVERLAY, CHAKMA VOWEL SIGN A
+11132 0334 11127;11132 0334 11127;11132 0334 11127;11132 0334 11127;11132 0334 11127; # (◌𑄲◌̴◌𑄧; ◌𑄲◌̴◌𑄧; ◌𑄲◌̴◌𑄧; ◌𑄲◌̴◌𑄧; ◌𑄲◌̴◌𑄧; ) CHAKMA AU MARK, COMBINING TILDE OVERLAY, CHAKMA VOWEL SIGN A
+11347 0334 1133E;11347 0334 1133E;11347 0334 1133E;11347 0334 1133E;11347 0334 1133E; # (𑍇◌̴𑌾; 𑍇◌̴𑌾; 𑍇◌̴𑌾; 𑍇◌̴𑌾; 𑍇◌̴𑌾; ) GRANTHA VOWEL SIGN EE, COMBINING TILDE OVERLAY, GRANTHA VOWEL SIGN AA
+11347 0334 11357;11347 0334 11357;11347 0334 11357;11347 0334 11357;11347 0334 11357; # (𑍇◌̴𑍗; 𑍇◌̴𑍗; 𑍇◌̴𑍗; 𑍇◌̴𑍗; 𑍇◌̴𑍗; ) GRANTHA VOWEL SIGN EE, COMBINING TILDE OVERLAY, GRANTHA AU LENGTH MARK
+114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0; # (𑒹◌̴𑒰; 𑒹◌̴𑒰; 𑒹◌̴𑒰; 𑒹◌̴𑒰; 𑒹◌̴𑒰; ) TIRHUTA VOWEL SIGN E, COMBINING TILDE OVERLAY, TIRHUTA VOWEL SIGN AA
+114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA; # (𑒹◌̴◌𑒺; 𑒹◌̴◌𑒺; 𑒹◌̴◌𑒺; 𑒹◌̴◌𑒺; 𑒹◌̴◌𑒺; ) TIRHUTA VOWEL SIGN E, COMBINING TILDE OVERLAY, TIRHUTA VOWEL SIGN SHORT E
+114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD; # (𑒹◌̴𑒽; 𑒹◌̴𑒽; 𑒹◌̴𑒽; 𑒹◌̴𑒽; 𑒹◌̴𑒽; ) TIRHUTA VOWEL SIGN E, COMBINING TILDE OVERLAY, TIRHUTA VOWEL SIGN SHORT O
+115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF; # (𑖸◌̴𑖯; 𑖸◌̴𑖯; 𑖸◌̴𑖯; 𑖸◌̴𑖯; 𑖸◌̴𑖯; ) SIDDHAM VOWEL SIGN E, COMBINING TILDE OVERLAY, SIDDHAM VOWEL SIGN AA
+115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF; # (𑖹◌̴𑖯; 𑖹◌̴𑖯; 𑖹◌̴𑖯; 𑖹◌̴𑖯; 𑖹◌̴𑖯; ) SIDDHAM VOWEL SIGN AI, COMBINING TILDE OVERLAY, SIDDHAM VOWEL SIGN AA
+#
+# EOF
diff --git a/lib/stdlib/test/zip_SUITE.erl b/lib/stdlib/test/zip_SUITE.erl
index 2add5a39a2..1dfcda4ed0 100644
--- a/lib/stdlib/test/zip_SUITE.erl
+++ b/lib/stdlib/test/zip_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -25,8 +25,9 @@
zip_to_binary/1,
unzip_options/1, zip_options/1, list_dir_options/1, aliases/1,
openzip_api/1, zip_api/1, open_leak/1, unzip_jar/1,
+ unzip_traversal_exploit/1,
compress_control/1,
- foldl/1]).
+ foldl/1,fd_leak/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("kernel/include/file.hrl").
@@ -38,7 +39,8 @@ all() ->
[borderline, atomic, bad_zip, unzip_from_binary,
unzip_to_binary, zip_to_binary, unzip_options,
zip_options, list_dir_options, aliases, openzip_api,
- zip_api, open_leak, unzip_jar, compress_control, foldl].
+ zip_api, open_leak, unzip_jar, compress_control, foldl,
+ unzip_traversal_exploit,fd_leak].
groups() ->
[].
@@ -377,6 +379,52 @@ unzip_options(Config) when is_list(Config) ->
0 = delete_files([Subdir]),
ok.
+%% Test that unzip handles directory traversal exploit (OTP-13633)
+unzip_traversal_exploit(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ ZipName = filename:join(DataDir, "exploit.zip"),
+
+ %% $ zipinfo -1 test/zip_SUITE_data/exploit.zip
+ %% clash.txt
+ %% ../clash.txt
+ %% ../above.txt
+ %% subdir/../in_root_dir.txt
+
+ %% create a temp directory
+ SubDir = filename:join(PrivDir, "exploit_test"),
+ ok = file:make_dir(SubDir),
+
+ ClashFile = filename:join(SubDir,"clash.txt"),
+ AboveFile = filename:join(SubDir,"above.txt"),
+ RelativePathFile = filename:join(SubDir,"subdir/../in_root_dir.txt"),
+
+ %% unzip in SubDir
+ {ok, [ClashFile, ClashFile, AboveFile, RelativePathFile]} =
+ zip:unzip(ZipName, [{cwd,SubDir}]),
+
+ {ok,<<"This file will overwrite other file.\n">>} =
+ file:read_file(ClashFile),
+ {ok,_} = file:read_file(AboveFile),
+ {ok,_} = file:read_file(RelativePathFile),
+
+ %% clean up
+ delete_files([SubDir]),
+
+ %% create the temp directory again
+ ok = file:make_dir(SubDir),
+
+ %% unzip in SubDir
+ {ok, [ClashFile, AboveFile, RelativePathFile]} =
+ zip:unzip(ZipName, [{cwd,SubDir},keep_old_files]),
+
+ {ok,<<"This is the original file.\n">>} =
+ file:read_file(ClashFile),
+
+ %% clean up
+ delete_files([SubDir]),
+ ok.
+
%% Test unzip a jar file (OTP-7382).
unzip_jar(Config) when is_list(Config) ->
DataDir = proplists:get_value(data_dir, Config),
@@ -834,3 +882,35 @@ foldl(Config) ->
{error, enoent} = zip:foldl(ZipFun, [], File),
ok.
+
+fd_leak(Config) ->
+ ok = file:set_cwd(proplists:get_value(priv_dir, Config)),
+ DataDir = proplists:get_value(data_dir, Config),
+ Name = filename:join(DataDir, "bad_file_header.zip"),
+ BadExtract = fun() ->
+ {error,bad_file_header} = zip:extract(Name),
+ ok
+ end,
+ do_fd_leak(BadExtract, 1),
+
+ BadCreate = fun() ->
+ {error,enoent} = zip:zip("failed.zip",
+ ["none"]),
+ ok
+ end,
+ do_fd_leak(BadCreate, 1),
+
+ ok.
+
+do_fd_leak(_Bad, 10000) ->
+ ok;
+do_fd_leak(Bad, N) ->
+ try Bad() of
+ ok ->
+ do_fd_leak(Bad, N + 1)
+ catch
+ C:R ->
+ Stk = erlang:get_stacktrace(),
+ io:format("Bad error after ~p attempts\n", [N]),
+ erlang:raise(C, R, Stk)
+ end.
diff --git a/lib/stdlib/test/zip_SUITE_data/exploit.zip b/lib/stdlib/test/zip_SUITE_data/exploit.zip
new file mode 100644
index 0000000000..afb8dbd192
--- /dev/null
+++ b/lib/stdlib/test/zip_SUITE_data/exploit.zip
Binary files differ
diff --git a/lib/stdlib/uc_spec/CaseFolding.txt b/lib/stdlib/uc_spec/CaseFolding.txt
new file mode 100644
index 0000000000..372ee68bd8
--- /dev/null
+++ b/lib/stdlib/uc_spec/CaseFolding.txt
@@ -0,0 +1,1495 @@
+# CaseFolding-9.0.0.txt
+# Date: 2016-03-02, 18:54:54 GMT
+# © 2016 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see http://www.unicode.org/reports/tr44/
+#
+# Case Folding Properties
+#
+# This file is a supplement to the UnicodeData file.
+# It provides a case folding mapping generated from the Unicode Character Database.
+# If all characters are mapped according to the full mapping below, then
+# case differences (according to UnicodeData.txt and SpecialCasing.txt)
+# are eliminated.
+#
+# The data supports both implementations that require simple case foldings
+# (where string lengths don't change), and implementations that allow full case folding
+# (where string lengths may grow). Note that where they can be supported, the
+# full case foldings are superior: for example, they allow "MASSE" and "Maße" to match.
+#
+# All code points not listed in this file map to themselves.
+#
+# NOTE: case folding does not preserve normalization formats!
+#
+# For information on case folding, including how to have case folding
+# preserve normalization formats, see Section 3.13 Default Case Algorithms in
+# The Unicode Standard.
+#
+# ================================================================================
+# Format
+# ================================================================================
+# The entries in this file are in the following machine-readable format:
+#
+# <code>; <status>; <mapping>; # <name>
+#
+# The status field is:
+# C: common case folding, common mappings shared by both simple and full mappings.
+# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+# S: simple case folding, mappings to single characters where different from F.
+# T: special case for uppercase I and dotted uppercase I
+# - For non-Turkic languages, this mapping is normally not used.
+# - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+# Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+# See the discussions of case mapping in the Unicode Standard for more information.
+#
+# Usage:
+# A. To do a simple case folding, use the mappings with status C + S.
+# B. To do a full case folding, use the mappings with status C + F.
+#
+# The mappings with status T can be used or omitted depending on the desired case-folding
+# behavior. (The default option is to exclude them.)
+#
+# =================================================================
+
+# Property: Case_Folding
+
+# All code points not explicitly listed for Case_Folding
+# have the value C for the status field, and the code point itself for the mapping field.
+
+# =================================================================
+0041; C; 0061; # LATIN CAPITAL LETTER A
+0042; C; 0062; # LATIN CAPITAL LETTER B
+0043; C; 0063; # LATIN CAPITAL LETTER C
+0044; C; 0064; # LATIN CAPITAL LETTER D
+0045; C; 0065; # LATIN CAPITAL LETTER E
+0046; C; 0066; # LATIN CAPITAL LETTER F
+0047; C; 0067; # LATIN CAPITAL LETTER G
+0048; C; 0068; # LATIN CAPITAL LETTER H
+0049; C; 0069; # LATIN CAPITAL LETTER I
+0049; T; 0131; # LATIN CAPITAL LETTER I
+004A; C; 006A; # LATIN CAPITAL LETTER J
+004B; C; 006B; # LATIN CAPITAL LETTER K
+004C; C; 006C; # LATIN CAPITAL LETTER L
+004D; C; 006D; # LATIN CAPITAL LETTER M
+004E; C; 006E; # LATIN CAPITAL LETTER N
+004F; C; 006F; # LATIN CAPITAL LETTER O
+0050; C; 0070; # LATIN CAPITAL LETTER P
+0051; C; 0071; # LATIN CAPITAL LETTER Q
+0052; C; 0072; # LATIN CAPITAL LETTER R
+0053; C; 0073; # LATIN CAPITAL LETTER S
+0054; C; 0074; # LATIN CAPITAL LETTER T
+0055; C; 0075; # LATIN CAPITAL LETTER U
+0056; C; 0076; # LATIN CAPITAL LETTER V
+0057; C; 0077; # LATIN CAPITAL LETTER W
+0058; C; 0078; # LATIN CAPITAL LETTER X
+0059; C; 0079; # LATIN CAPITAL LETTER Y
+005A; C; 007A; # LATIN CAPITAL LETTER Z
+00B5; C; 03BC; # MICRO SIGN
+00C0; C; 00E0; # LATIN CAPITAL LETTER A WITH GRAVE
+00C1; C; 00E1; # LATIN CAPITAL LETTER A WITH ACUTE
+00C2; C; 00E2; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+00C3; C; 00E3; # LATIN CAPITAL LETTER A WITH TILDE
+00C4; C; 00E4; # LATIN CAPITAL LETTER A WITH DIAERESIS
+00C5; C; 00E5; # LATIN CAPITAL LETTER A WITH RING ABOVE
+00C6; C; 00E6; # LATIN CAPITAL LETTER AE
+00C7; C; 00E7; # LATIN CAPITAL LETTER C WITH CEDILLA
+00C8; C; 00E8; # LATIN CAPITAL LETTER E WITH GRAVE
+00C9; C; 00E9; # LATIN CAPITAL LETTER E WITH ACUTE
+00CA; C; 00EA; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+00CB; C; 00EB; # LATIN CAPITAL LETTER E WITH DIAERESIS
+00CC; C; 00EC; # LATIN CAPITAL LETTER I WITH GRAVE
+00CD; C; 00ED; # LATIN CAPITAL LETTER I WITH ACUTE
+00CE; C; 00EE; # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+00CF; C; 00EF; # LATIN CAPITAL LETTER I WITH DIAERESIS
+00D0; C; 00F0; # LATIN CAPITAL LETTER ETH
+00D1; C; 00F1; # LATIN CAPITAL LETTER N WITH TILDE
+00D2; C; 00F2; # LATIN CAPITAL LETTER O WITH GRAVE
+00D3; C; 00F3; # LATIN CAPITAL LETTER O WITH ACUTE
+00D4; C; 00F4; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+00D5; C; 00F5; # LATIN CAPITAL LETTER O WITH TILDE
+00D6; C; 00F6; # LATIN CAPITAL LETTER O WITH DIAERESIS
+00D8; C; 00F8; # LATIN CAPITAL LETTER O WITH STROKE
+00D9; C; 00F9; # LATIN CAPITAL LETTER U WITH GRAVE
+00DA; C; 00FA; # LATIN CAPITAL LETTER U WITH ACUTE
+00DB; C; 00FB; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+00DC; C; 00FC; # LATIN CAPITAL LETTER U WITH DIAERESIS
+00DD; C; 00FD; # LATIN CAPITAL LETTER Y WITH ACUTE
+00DE; C; 00FE; # LATIN CAPITAL LETTER THORN
+00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S
+0100; C; 0101; # LATIN CAPITAL LETTER A WITH MACRON
+0102; C; 0103; # LATIN CAPITAL LETTER A WITH BREVE
+0104; C; 0105; # LATIN CAPITAL LETTER A WITH OGONEK
+0106; C; 0107; # LATIN CAPITAL LETTER C WITH ACUTE
+0108; C; 0109; # LATIN CAPITAL LETTER C WITH CIRCUMFLEX
+010A; C; 010B; # LATIN CAPITAL LETTER C WITH DOT ABOVE
+010C; C; 010D; # LATIN CAPITAL LETTER C WITH CARON
+010E; C; 010F; # LATIN CAPITAL LETTER D WITH CARON
+0110; C; 0111; # LATIN CAPITAL LETTER D WITH STROKE
+0112; C; 0113; # LATIN CAPITAL LETTER E WITH MACRON
+0114; C; 0115; # LATIN CAPITAL LETTER E WITH BREVE
+0116; C; 0117; # LATIN CAPITAL LETTER E WITH DOT ABOVE
+0118; C; 0119; # LATIN CAPITAL LETTER E WITH OGONEK
+011A; C; 011B; # LATIN CAPITAL LETTER E WITH CARON
+011C; C; 011D; # LATIN CAPITAL LETTER G WITH CIRCUMFLEX
+011E; C; 011F; # LATIN CAPITAL LETTER G WITH BREVE
+0120; C; 0121; # LATIN CAPITAL LETTER G WITH DOT ABOVE
+0122; C; 0123; # LATIN CAPITAL LETTER G WITH CEDILLA
+0124; C; 0125; # LATIN CAPITAL LETTER H WITH CIRCUMFLEX
+0126; C; 0127; # LATIN CAPITAL LETTER H WITH STROKE
+0128; C; 0129; # LATIN CAPITAL LETTER I WITH TILDE
+012A; C; 012B; # LATIN CAPITAL LETTER I WITH MACRON
+012C; C; 012D; # LATIN CAPITAL LETTER I WITH BREVE
+012E; C; 012F; # LATIN CAPITAL LETTER I WITH OGONEK
+0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE
+0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE
+0132; C; 0133; # LATIN CAPITAL LIGATURE IJ
+0134; C; 0135; # LATIN CAPITAL LETTER J WITH CIRCUMFLEX
+0136; C; 0137; # LATIN CAPITAL LETTER K WITH CEDILLA
+0139; C; 013A; # LATIN CAPITAL LETTER L WITH ACUTE
+013B; C; 013C; # LATIN CAPITAL LETTER L WITH CEDILLA
+013D; C; 013E; # LATIN CAPITAL LETTER L WITH CARON
+013F; C; 0140; # LATIN CAPITAL LETTER L WITH MIDDLE DOT
+0141; C; 0142; # LATIN CAPITAL LETTER L WITH STROKE
+0143; C; 0144; # LATIN CAPITAL LETTER N WITH ACUTE
+0145; C; 0146; # LATIN CAPITAL LETTER N WITH CEDILLA
+0147; C; 0148; # LATIN CAPITAL LETTER N WITH CARON
+0149; F; 02BC 006E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+014A; C; 014B; # LATIN CAPITAL LETTER ENG
+014C; C; 014D; # LATIN CAPITAL LETTER O WITH MACRON
+014E; C; 014F; # LATIN CAPITAL LETTER O WITH BREVE
+0150; C; 0151; # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+0152; C; 0153; # LATIN CAPITAL LIGATURE OE
+0154; C; 0155; # LATIN CAPITAL LETTER R WITH ACUTE
+0156; C; 0157; # LATIN CAPITAL LETTER R WITH CEDILLA
+0158; C; 0159; # LATIN CAPITAL LETTER R WITH CARON
+015A; C; 015B; # LATIN CAPITAL LETTER S WITH ACUTE
+015C; C; 015D; # LATIN CAPITAL LETTER S WITH CIRCUMFLEX
+015E; C; 015F; # LATIN CAPITAL LETTER S WITH CEDILLA
+0160; C; 0161; # LATIN CAPITAL LETTER S WITH CARON
+0162; C; 0163; # LATIN CAPITAL LETTER T WITH CEDILLA
+0164; C; 0165; # LATIN CAPITAL LETTER T WITH CARON
+0166; C; 0167; # LATIN CAPITAL LETTER T WITH STROKE
+0168; C; 0169; # LATIN CAPITAL LETTER U WITH TILDE
+016A; C; 016B; # LATIN CAPITAL LETTER U WITH MACRON
+016C; C; 016D; # LATIN CAPITAL LETTER U WITH BREVE
+016E; C; 016F; # LATIN CAPITAL LETTER U WITH RING ABOVE
+0170; C; 0171; # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+0172; C; 0173; # LATIN CAPITAL LETTER U WITH OGONEK
+0174; C; 0175; # LATIN CAPITAL LETTER W WITH CIRCUMFLEX
+0176; C; 0177; # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
+0178; C; 00FF; # LATIN CAPITAL LETTER Y WITH DIAERESIS
+0179; C; 017A; # LATIN CAPITAL LETTER Z WITH ACUTE
+017B; C; 017C; # LATIN CAPITAL LETTER Z WITH DOT ABOVE
+017D; C; 017E; # LATIN CAPITAL LETTER Z WITH CARON
+017F; C; 0073; # LATIN SMALL LETTER LONG S
+0181; C; 0253; # LATIN CAPITAL LETTER B WITH HOOK
+0182; C; 0183; # LATIN CAPITAL LETTER B WITH TOPBAR
+0184; C; 0185; # LATIN CAPITAL LETTER TONE SIX
+0186; C; 0254; # LATIN CAPITAL LETTER OPEN O
+0187; C; 0188; # LATIN CAPITAL LETTER C WITH HOOK
+0189; C; 0256; # LATIN CAPITAL LETTER AFRICAN D
+018A; C; 0257; # LATIN CAPITAL LETTER D WITH HOOK
+018B; C; 018C; # LATIN CAPITAL LETTER D WITH TOPBAR
+018E; C; 01DD; # LATIN CAPITAL LETTER REVERSED E
+018F; C; 0259; # LATIN CAPITAL LETTER SCHWA
+0190; C; 025B; # LATIN CAPITAL LETTER OPEN E
+0191; C; 0192; # LATIN CAPITAL LETTER F WITH HOOK
+0193; C; 0260; # LATIN CAPITAL LETTER G WITH HOOK
+0194; C; 0263; # LATIN CAPITAL LETTER GAMMA
+0196; C; 0269; # LATIN CAPITAL LETTER IOTA
+0197; C; 0268; # LATIN CAPITAL LETTER I WITH STROKE
+0198; C; 0199; # LATIN CAPITAL LETTER K WITH HOOK
+019C; C; 026F; # LATIN CAPITAL LETTER TURNED M
+019D; C; 0272; # LATIN CAPITAL LETTER N WITH LEFT HOOK
+019F; C; 0275; # LATIN CAPITAL LETTER O WITH MIDDLE TILDE
+01A0; C; 01A1; # LATIN CAPITAL LETTER O WITH HORN
+01A2; C; 01A3; # LATIN CAPITAL LETTER OI
+01A4; C; 01A5; # LATIN CAPITAL LETTER P WITH HOOK
+01A6; C; 0280; # LATIN LETTER YR
+01A7; C; 01A8; # LATIN CAPITAL LETTER TONE TWO
+01A9; C; 0283; # LATIN CAPITAL LETTER ESH
+01AC; C; 01AD; # LATIN CAPITAL LETTER T WITH HOOK
+01AE; C; 0288; # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK
+01AF; C; 01B0; # LATIN CAPITAL LETTER U WITH HORN
+01B1; C; 028A; # LATIN CAPITAL LETTER UPSILON
+01B2; C; 028B; # LATIN CAPITAL LETTER V WITH HOOK
+01B3; C; 01B4; # LATIN CAPITAL LETTER Y WITH HOOK
+01B5; C; 01B6; # LATIN CAPITAL LETTER Z WITH STROKE
+01B7; C; 0292; # LATIN CAPITAL LETTER EZH
+01B8; C; 01B9; # LATIN CAPITAL LETTER EZH REVERSED
+01BC; C; 01BD; # LATIN CAPITAL LETTER TONE FIVE
+01C4; C; 01C6; # LATIN CAPITAL LETTER DZ WITH CARON
+01C5; C; 01C6; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
+01C7; C; 01C9; # LATIN CAPITAL LETTER LJ
+01C8; C; 01C9; # LATIN CAPITAL LETTER L WITH SMALL LETTER J
+01CA; C; 01CC; # LATIN CAPITAL LETTER NJ
+01CB; C; 01CC; # LATIN CAPITAL LETTER N WITH SMALL LETTER J
+01CD; C; 01CE; # LATIN CAPITAL LETTER A WITH CARON
+01CF; C; 01D0; # LATIN CAPITAL LETTER I WITH CARON
+01D1; C; 01D2; # LATIN CAPITAL LETTER O WITH CARON
+01D3; C; 01D4; # LATIN CAPITAL LETTER U WITH CARON
+01D5; C; 01D6; # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
+01D7; C; 01D8; # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
+01D9; C; 01DA; # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
+01DB; C; 01DC; # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
+01DE; C; 01DF; # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
+01E0; C; 01E1; # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
+01E2; C; 01E3; # LATIN CAPITAL LETTER AE WITH MACRON
+01E4; C; 01E5; # LATIN CAPITAL LETTER G WITH STROKE
+01E6; C; 01E7; # LATIN CAPITAL LETTER G WITH CARON
+01E8; C; 01E9; # LATIN CAPITAL LETTER K WITH CARON
+01EA; C; 01EB; # LATIN CAPITAL LETTER O WITH OGONEK
+01EC; C; 01ED; # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
+01EE; C; 01EF; # LATIN CAPITAL LETTER EZH WITH CARON
+01F0; F; 006A 030C; # LATIN SMALL LETTER J WITH CARON
+01F1; C; 01F3; # LATIN CAPITAL LETTER DZ
+01F2; C; 01F3; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z
+01F4; C; 01F5; # LATIN CAPITAL LETTER G WITH ACUTE
+01F6; C; 0195; # LATIN CAPITAL LETTER HWAIR
+01F7; C; 01BF; # LATIN CAPITAL LETTER WYNN
+01F8; C; 01F9; # LATIN CAPITAL LETTER N WITH GRAVE
+01FA; C; 01FB; # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
+01FC; C; 01FD; # LATIN CAPITAL LETTER AE WITH ACUTE
+01FE; C; 01FF; # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
+0200; C; 0201; # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
+0202; C; 0203; # LATIN CAPITAL LETTER A WITH INVERTED BREVE
+0204; C; 0205; # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
+0206; C; 0207; # LATIN CAPITAL LETTER E WITH INVERTED BREVE
+0208; C; 0209; # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
+020A; C; 020B; # LATIN CAPITAL LETTER I WITH INVERTED BREVE
+020C; C; 020D; # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
+020E; C; 020F; # LATIN CAPITAL LETTER O WITH INVERTED BREVE
+0210; C; 0211; # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
+0212; C; 0213; # LATIN CAPITAL LETTER R WITH INVERTED BREVE
+0214; C; 0215; # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
+0216; C; 0217; # LATIN CAPITAL LETTER U WITH INVERTED BREVE
+0218; C; 0219; # LATIN CAPITAL LETTER S WITH COMMA BELOW
+021A; C; 021B; # LATIN CAPITAL LETTER T WITH COMMA BELOW
+021C; C; 021D; # LATIN CAPITAL LETTER YOGH
+021E; C; 021F; # LATIN CAPITAL LETTER H WITH CARON
+0220; C; 019E; # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG
+0222; C; 0223; # LATIN CAPITAL LETTER OU
+0224; C; 0225; # LATIN CAPITAL LETTER Z WITH HOOK
+0226; C; 0227; # LATIN CAPITAL LETTER A WITH DOT ABOVE
+0228; C; 0229; # LATIN CAPITAL LETTER E WITH CEDILLA
+022A; C; 022B; # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
+022C; C; 022D; # LATIN CAPITAL LETTER O WITH TILDE AND MACRON
+022E; C; 022F; # LATIN CAPITAL LETTER O WITH DOT ABOVE
+0230; C; 0231; # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
+0232; C; 0233; # LATIN CAPITAL LETTER Y WITH MACRON
+023A; C; 2C65; # LATIN CAPITAL LETTER A WITH STROKE
+023B; C; 023C; # LATIN CAPITAL LETTER C WITH STROKE
+023D; C; 019A; # LATIN CAPITAL LETTER L WITH BAR
+023E; C; 2C66; # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE
+0241; C; 0242; # LATIN CAPITAL LETTER GLOTTAL STOP
+0243; C; 0180; # LATIN CAPITAL LETTER B WITH STROKE
+0244; C; 0289; # LATIN CAPITAL LETTER U BAR
+0245; C; 028C; # LATIN CAPITAL LETTER TURNED V
+0246; C; 0247; # LATIN CAPITAL LETTER E WITH STROKE
+0248; C; 0249; # LATIN CAPITAL LETTER J WITH STROKE
+024A; C; 024B; # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL
+024C; C; 024D; # LATIN CAPITAL LETTER R WITH STROKE
+024E; C; 024F; # LATIN CAPITAL LETTER Y WITH STROKE
+0345; C; 03B9; # COMBINING GREEK YPOGEGRAMMENI
+0370; C; 0371; # GREEK CAPITAL LETTER HETA
+0372; C; 0373; # GREEK CAPITAL LETTER ARCHAIC SAMPI
+0376; C; 0377; # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA
+037F; C; 03F3; # GREEK CAPITAL LETTER YOT
+0386; C; 03AC; # GREEK CAPITAL LETTER ALPHA WITH TONOS
+0388; C; 03AD; # GREEK CAPITAL LETTER EPSILON WITH TONOS
+0389; C; 03AE; # GREEK CAPITAL LETTER ETA WITH TONOS
+038A; C; 03AF; # GREEK CAPITAL LETTER IOTA WITH TONOS
+038C; C; 03CC; # GREEK CAPITAL LETTER OMICRON WITH TONOS
+038E; C; 03CD; # GREEK CAPITAL LETTER UPSILON WITH TONOS
+038F; C; 03CE; # GREEK CAPITAL LETTER OMEGA WITH TONOS
+0390; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+0391; C; 03B1; # GREEK CAPITAL LETTER ALPHA
+0392; C; 03B2; # GREEK CAPITAL LETTER BETA
+0393; C; 03B3; # GREEK CAPITAL LETTER GAMMA
+0394; C; 03B4; # GREEK CAPITAL LETTER DELTA
+0395; C; 03B5; # GREEK CAPITAL LETTER EPSILON
+0396; C; 03B6; # GREEK CAPITAL LETTER ZETA
+0397; C; 03B7; # GREEK CAPITAL LETTER ETA
+0398; C; 03B8; # GREEK CAPITAL LETTER THETA
+0399; C; 03B9; # GREEK CAPITAL LETTER IOTA
+039A; C; 03BA; # GREEK CAPITAL LETTER KAPPA
+039B; C; 03BB; # GREEK CAPITAL LETTER LAMDA
+039C; C; 03BC; # GREEK CAPITAL LETTER MU
+039D; C; 03BD; # GREEK CAPITAL LETTER NU
+039E; C; 03BE; # GREEK CAPITAL LETTER XI
+039F; C; 03BF; # GREEK CAPITAL LETTER OMICRON
+03A0; C; 03C0; # GREEK CAPITAL LETTER PI
+03A1; C; 03C1; # GREEK CAPITAL LETTER RHO
+03A3; C; 03C3; # GREEK CAPITAL LETTER SIGMA
+03A4; C; 03C4; # GREEK CAPITAL LETTER TAU
+03A5; C; 03C5; # GREEK CAPITAL LETTER UPSILON
+03A6; C; 03C6; # GREEK CAPITAL LETTER PHI
+03A7; C; 03C7; # GREEK CAPITAL LETTER CHI
+03A8; C; 03C8; # GREEK CAPITAL LETTER PSI
+03A9; C; 03C9; # GREEK CAPITAL LETTER OMEGA
+03AA; C; 03CA; # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+03AB; C; 03CB; # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+03B0; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+03C2; C; 03C3; # GREEK SMALL LETTER FINAL SIGMA
+03CF; C; 03D7; # GREEK CAPITAL KAI SYMBOL
+03D0; C; 03B2; # GREEK BETA SYMBOL
+03D1; C; 03B8; # GREEK THETA SYMBOL
+03D5; C; 03C6; # GREEK PHI SYMBOL
+03D6; C; 03C0; # GREEK PI SYMBOL
+03D8; C; 03D9; # GREEK LETTER ARCHAIC KOPPA
+03DA; C; 03DB; # GREEK LETTER STIGMA
+03DC; C; 03DD; # GREEK LETTER DIGAMMA
+03DE; C; 03DF; # GREEK LETTER KOPPA
+03E0; C; 03E1; # GREEK LETTER SAMPI
+03E2; C; 03E3; # COPTIC CAPITAL LETTER SHEI
+03E4; C; 03E5; # COPTIC CAPITAL LETTER FEI
+03E6; C; 03E7; # COPTIC CAPITAL LETTER KHEI
+03E8; C; 03E9; # COPTIC CAPITAL LETTER HORI
+03EA; C; 03EB; # COPTIC CAPITAL LETTER GANGIA
+03EC; C; 03ED; # COPTIC CAPITAL LETTER SHIMA
+03EE; C; 03EF; # COPTIC CAPITAL LETTER DEI
+03F0; C; 03BA; # GREEK KAPPA SYMBOL
+03F1; C; 03C1; # GREEK RHO SYMBOL
+03F4; C; 03B8; # GREEK CAPITAL THETA SYMBOL
+03F5; C; 03B5; # GREEK LUNATE EPSILON SYMBOL
+03F7; C; 03F8; # GREEK CAPITAL LETTER SHO
+03F9; C; 03F2; # GREEK CAPITAL LUNATE SIGMA SYMBOL
+03FA; C; 03FB; # GREEK CAPITAL LETTER SAN
+03FD; C; 037B; # GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL
+03FE; C; 037C; # GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL
+03FF; C; 037D; # GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
+0400; C; 0450; # CYRILLIC CAPITAL LETTER IE WITH GRAVE
+0401; C; 0451; # CYRILLIC CAPITAL LETTER IO
+0402; C; 0452; # CYRILLIC CAPITAL LETTER DJE
+0403; C; 0453; # CYRILLIC CAPITAL LETTER GJE
+0404; C; 0454; # CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0405; C; 0455; # CYRILLIC CAPITAL LETTER DZE
+0406; C; 0456; # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+0407; C; 0457; # CYRILLIC CAPITAL LETTER YI
+0408; C; 0458; # CYRILLIC CAPITAL LETTER JE
+0409; C; 0459; # CYRILLIC CAPITAL LETTER LJE
+040A; C; 045A; # CYRILLIC CAPITAL LETTER NJE
+040B; C; 045B; # CYRILLIC CAPITAL LETTER TSHE
+040C; C; 045C; # CYRILLIC CAPITAL LETTER KJE
+040D; C; 045D; # CYRILLIC CAPITAL LETTER I WITH GRAVE
+040E; C; 045E; # CYRILLIC CAPITAL LETTER SHORT U
+040F; C; 045F; # CYRILLIC CAPITAL LETTER DZHE
+0410; C; 0430; # CYRILLIC CAPITAL LETTER A
+0411; C; 0431; # CYRILLIC CAPITAL LETTER BE
+0412; C; 0432; # CYRILLIC CAPITAL LETTER VE
+0413; C; 0433; # CYRILLIC CAPITAL LETTER GHE
+0414; C; 0434; # CYRILLIC CAPITAL LETTER DE
+0415; C; 0435; # CYRILLIC CAPITAL LETTER IE
+0416; C; 0436; # CYRILLIC CAPITAL LETTER ZHE
+0417; C; 0437; # CYRILLIC CAPITAL LETTER ZE
+0418; C; 0438; # CYRILLIC CAPITAL LETTER I
+0419; C; 0439; # CYRILLIC CAPITAL LETTER SHORT I
+041A; C; 043A; # CYRILLIC CAPITAL LETTER KA
+041B; C; 043B; # CYRILLIC CAPITAL LETTER EL
+041C; C; 043C; # CYRILLIC CAPITAL LETTER EM
+041D; C; 043D; # CYRILLIC CAPITAL LETTER EN
+041E; C; 043E; # CYRILLIC CAPITAL LETTER O
+041F; C; 043F; # CYRILLIC CAPITAL LETTER PE
+0420; C; 0440; # CYRILLIC CAPITAL LETTER ER
+0421; C; 0441; # CYRILLIC CAPITAL LETTER ES
+0422; C; 0442; # CYRILLIC CAPITAL LETTER TE
+0423; C; 0443; # CYRILLIC CAPITAL LETTER U
+0424; C; 0444; # CYRILLIC CAPITAL LETTER EF
+0425; C; 0445; # CYRILLIC CAPITAL LETTER HA
+0426; C; 0446; # CYRILLIC CAPITAL LETTER TSE
+0427; C; 0447; # CYRILLIC CAPITAL LETTER CHE
+0428; C; 0448; # CYRILLIC CAPITAL LETTER SHA
+0429; C; 0449; # CYRILLIC CAPITAL LETTER SHCHA
+042A; C; 044A; # CYRILLIC CAPITAL LETTER HARD SIGN
+042B; C; 044B; # CYRILLIC CAPITAL LETTER YERU
+042C; C; 044C; # CYRILLIC CAPITAL LETTER SOFT SIGN
+042D; C; 044D; # CYRILLIC CAPITAL LETTER E
+042E; C; 044E; # CYRILLIC CAPITAL LETTER YU
+042F; C; 044F; # CYRILLIC CAPITAL LETTER YA
+0460; C; 0461; # CYRILLIC CAPITAL LETTER OMEGA
+0462; C; 0463; # CYRILLIC CAPITAL LETTER YAT
+0464; C; 0465; # CYRILLIC CAPITAL LETTER IOTIFIED E
+0466; C; 0467; # CYRILLIC CAPITAL LETTER LITTLE YUS
+0468; C; 0469; # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
+046A; C; 046B; # CYRILLIC CAPITAL LETTER BIG YUS
+046C; C; 046D; # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
+046E; C; 046F; # CYRILLIC CAPITAL LETTER KSI
+0470; C; 0471; # CYRILLIC CAPITAL LETTER PSI
+0472; C; 0473; # CYRILLIC CAPITAL LETTER FITA
+0474; C; 0475; # CYRILLIC CAPITAL LETTER IZHITSA
+0476; C; 0477; # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
+0478; C; 0479; # CYRILLIC CAPITAL LETTER UK
+047A; C; 047B; # CYRILLIC CAPITAL LETTER ROUND OMEGA
+047C; C; 047D; # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
+047E; C; 047F; # CYRILLIC CAPITAL LETTER OT
+0480; C; 0481; # CYRILLIC CAPITAL LETTER KOPPA
+048A; C; 048B; # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL
+048C; C; 048D; # CYRILLIC CAPITAL LETTER SEMISOFT SIGN
+048E; C; 048F; # CYRILLIC CAPITAL LETTER ER WITH TICK
+0490; C; 0491; # CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+0492; C; 0493; # CYRILLIC CAPITAL LETTER GHE WITH STROKE
+0494; C; 0495; # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
+0496; C; 0497; # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
+0498; C; 0499; # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
+049A; C; 049B; # CYRILLIC CAPITAL LETTER KA WITH DESCENDER
+049C; C; 049D; # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
+049E; C; 049F; # CYRILLIC CAPITAL LETTER KA WITH STROKE
+04A0; C; 04A1; # CYRILLIC CAPITAL LETTER BASHKIR KA
+04A2; C; 04A3; # CYRILLIC CAPITAL LETTER EN WITH DESCENDER
+04A4; C; 04A5; # CYRILLIC CAPITAL LIGATURE EN GHE
+04A6; C; 04A7; # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
+04A8; C; 04A9; # CYRILLIC CAPITAL LETTER ABKHASIAN HA
+04AA; C; 04AB; # CYRILLIC CAPITAL LETTER ES WITH DESCENDER
+04AC; C; 04AD; # CYRILLIC CAPITAL LETTER TE WITH DESCENDER
+04AE; C; 04AF; # CYRILLIC CAPITAL LETTER STRAIGHT U
+04B0; C; 04B1; # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
+04B2; C; 04B3; # CYRILLIC CAPITAL LETTER HA WITH DESCENDER
+04B4; C; 04B5; # CYRILLIC CAPITAL LIGATURE TE TSE
+04B6; C; 04B7; # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
+04B8; C; 04B9; # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
+04BA; C; 04BB; # CYRILLIC CAPITAL LETTER SHHA
+04BC; C; 04BD; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE
+04BE; C; 04BF; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
+04C0; C; 04CF; # CYRILLIC LETTER PALOCHKA
+04C1; C; 04C2; # CYRILLIC CAPITAL LETTER ZHE WITH BREVE
+04C3; C; 04C4; # CYRILLIC CAPITAL LETTER KA WITH HOOK
+04C5; C; 04C6; # CYRILLIC CAPITAL LETTER EL WITH TAIL
+04C7; C; 04C8; # CYRILLIC CAPITAL LETTER EN WITH HOOK
+04C9; C; 04CA; # CYRILLIC CAPITAL LETTER EN WITH TAIL
+04CB; C; 04CC; # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
+04CD; C; 04CE; # CYRILLIC CAPITAL LETTER EM WITH TAIL
+04D0; C; 04D1; # CYRILLIC CAPITAL LETTER A WITH BREVE
+04D2; C; 04D3; # CYRILLIC CAPITAL LETTER A WITH DIAERESIS
+04D4; C; 04D5; # CYRILLIC CAPITAL LIGATURE A IE
+04D6; C; 04D7; # CYRILLIC CAPITAL LETTER IE WITH BREVE
+04D8; C; 04D9; # CYRILLIC CAPITAL LETTER SCHWA
+04DA; C; 04DB; # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS
+04DC; C; 04DD; # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS
+04DE; C; 04DF; # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS
+04E0; C; 04E1; # CYRILLIC CAPITAL LETTER ABKHASIAN DZE
+04E2; C; 04E3; # CYRILLIC CAPITAL LETTER I WITH MACRON
+04E4; C; 04E5; # CYRILLIC CAPITAL LETTER I WITH DIAERESIS
+04E6; C; 04E7; # CYRILLIC CAPITAL LETTER O WITH DIAERESIS
+04E8; C; 04E9; # CYRILLIC CAPITAL LETTER BARRED O
+04EA; C; 04EB; # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS
+04EC; C; 04ED; # CYRILLIC CAPITAL LETTER E WITH DIAERESIS
+04EE; C; 04EF; # CYRILLIC CAPITAL LETTER U WITH MACRON
+04F0; C; 04F1; # CYRILLIC CAPITAL LETTER U WITH DIAERESIS
+04F2; C; 04F3; # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE
+04F4; C; 04F5; # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS
+04F6; C; 04F7; # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER
+04F8; C; 04F9; # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS
+04FA; C; 04FB; # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK
+04FC; C; 04FD; # CYRILLIC CAPITAL LETTER HA WITH HOOK
+04FE; C; 04FF; # CYRILLIC CAPITAL LETTER HA WITH STROKE
+0500; C; 0501; # CYRILLIC CAPITAL LETTER KOMI DE
+0502; C; 0503; # CYRILLIC CAPITAL LETTER KOMI DJE
+0504; C; 0505; # CYRILLIC CAPITAL LETTER KOMI ZJE
+0506; C; 0507; # CYRILLIC CAPITAL LETTER KOMI DZJE
+0508; C; 0509; # CYRILLIC CAPITAL LETTER KOMI LJE
+050A; C; 050B; # CYRILLIC CAPITAL LETTER KOMI NJE
+050C; C; 050D; # CYRILLIC CAPITAL LETTER KOMI SJE
+050E; C; 050F; # CYRILLIC CAPITAL LETTER KOMI TJE
+0510; C; 0511; # CYRILLIC CAPITAL LETTER REVERSED ZE
+0512; C; 0513; # CYRILLIC CAPITAL LETTER EL WITH HOOK
+0514; C; 0515; # CYRILLIC CAPITAL LETTER LHA
+0516; C; 0517; # CYRILLIC CAPITAL LETTER RHA
+0518; C; 0519; # CYRILLIC CAPITAL LETTER YAE
+051A; C; 051B; # CYRILLIC CAPITAL LETTER QA
+051C; C; 051D; # CYRILLIC CAPITAL LETTER WE
+051E; C; 051F; # CYRILLIC CAPITAL LETTER ALEUT KA
+0520; C; 0521; # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK
+0522; C; 0523; # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK
+0524; C; 0525; # CYRILLIC CAPITAL LETTER PE WITH DESCENDER
+0526; C; 0527; # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER
+0528; C; 0529; # CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK
+052A; C; 052B; # CYRILLIC CAPITAL LETTER DZZHE
+052C; C; 052D; # CYRILLIC CAPITAL LETTER DCHE
+052E; C; 052F; # CYRILLIC CAPITAL LETTER EL WITH DESCENDER
+0531; C; 0561; # ARMENIAN CAPITAL LETTER AYB
+0532; C; 0562; # ARMENIAN CAPITAL LETTER BEN
+0533; C; 0563; # ARMENIAN CAPITAL LETTER GIM
+0534; C; 0564; # ARMENIAN CAPITAL LETTER DA
+0535; C; 0565; # ARMENIAN CAPITAL LETTER ECH
+0536; C; 0566; # ARMENIAN CAPITAL LETTER ZA
+0537; C; 0567; # ARMENIAN CAPITAL LETTER EH
+0538; C; 0568; # ARMENIAN CAPITAL LETTER ET
+0539; C; 0569; # ARMENIAN CAPITAL LETTER TO
+053A; C; 056A; # ARMENIAN CAPITAL LETTER ZHE
+053B; C; 056B; # ARMENIAN CAPITAL LETTER INI
+053C; C; 056C; # ARMENIAN CAPITAL LETTER LIWN
+053D; C; 056D; # ARMENIAN CAPITAL LETTER XEH
+053E; C; 056E; # ARMENIAN CAPITAL LETTER CA
+053F; C; 056F; # ARMENIAN CAPITAL LETTER KEN
+0540; C; 0570; # ARMENIAN CAPITAL LETTER HO
+0541; C; 0571; # ARMENIAN CAPITAL LETTER JA
+0542; C; 0572; # ARMENIAN CAPITAL LETTER GHAD
+0543; C; 0573; # ARMENIAN CAPITAL LETTER CHEH
+0544; C; 0574; # ARMENIAN CAPITAL LETTER MEN
+0545; C; 0575; # ARMENIAN CAPITAL LETTER YI
+0546; C; 0576; # ARMENIAN CAPITAL LETTER NOW
+0547; C; 0577; # ARMENIAN CAPITAL LETTER SHA
+0548; C; 0578; # ARMENIAN CAPITAL LETTER VO
+0549; C; 0579; # ARMENIAN CAPITAL LETTER CHA
+054A; C; 057A; # ARMENIAN CAPITAL LETTER PEH
+054B; C; 057B; # ARMENIAN CAPITAL LETTER JHEH
+054C; C; 057C; # ARMENIAN CAPITAL LETTER RA
+054D; C; 057D; # ARMENIAN CAPITAL LETTER SEH
+054E; C; 057E; # ARMENIAN CAPITAL LETTER VEW
+054F; C; 057F; # ARMENIAN CAPITAL LETTER TIWN
+0550; C; 0580; # ARMENIAN CAPITAL LETTER REH
+0551; C; 0581; # ARMENIAN CAPITAL LETTER CO
+0552; C; 0582; # ARMENIAN CAPITAL LETTER YIWN
+0553; C; 0583; # ARMENIAN CAPITAL LETTER PIWR
+0554; C; 0584; # ARMENIAN CAPITAL LETTER KEH
+0555; C; 0585; # ARMENIAN CAPITAL LETTER OH
+0556; C; 0586; # ARMENIAN CAPITAL LETTER FEH
+0587; F; 0565 0582; # ARMENIAN SMALL LIGATURE ECH YIWN
+10A0; C; 2D00; # GEORGIAN CAPITAL LETTER AN
+10A1; C; 2D01; # GEORGIAN CAPITAL LETTER BAN
+10A2; C; 2D02; # GEORGIAN CAPITAL LETTER GAN
+10A3; C; 2D03; # GEORGIAN CAPITAL LETTER DON
+10A4; C; 2D04; # GEORGIAN CAPITAL LETTER EN
+10A5; C; 2D05; # GEORGIAN CAPITAL LETTER VIN
+10A6; C; 2D06; # GEORGIAN CAPITAL LETTER ZEN
+10A7; C; 2D07; # GEORGIAN CAPITAL LETTER TAN
+10A8; C; 2D08; # GEORGIAN CAPITAL LETTER IN
+10A9; C; 2D09; # GEORGIAN CAPITAL LETTER KAN
+10AA; C; 2D0A; # GEORGIAN CAPITAL LETTER LAS
+10AB; C; 2D0B; # GEORGIAN CAPITAL LETTER MAN
+10AC; C; 2D0C; # GEORGIAN CAPITAL LETTER NAR
+10AD; C; 2D0D; # GEORGIAN CAPITAL LETTER ON
+10AE; C; 2D0E; # GEORGIAN CAPITAL LETTER PAR
+10AF; C; 2D0F; # GEORGIAN CAPITAL LETTER ZHAR
+10B0; C; 2D10; # GEORGIAN CAPITAL LETTER RAE
+10B1; C; 2D11; # GEORGIAN CAPITAL LETTER SAN
+10B2; C; 2D12; # GEORGIAN CAPITAL LETTER TAR
+10B3; C; 2D13; # GEORGIAN CAPITAL LETTER UN
+10B4; C; 2D14; # GEORGIAN CAPITAL LETTER PHAR
+10B5; C; 2D15; # GEORGIAN CAPITAL LETTER KHAR
+10B6; C; 2D16; # GEORGIAN CAPITAL LETTER GHAN
+10B7; C; 2D17; # GEORGIAN CAPITAL LETTER QAR
+10B8; C; 2D18; # GEORGIAN CAPITAL LETTER SHIN
+10B9; C; 2D19; # GEORGIAN CAPITAL LETTER CHIN
+10BA; C; 2D1A; # GEORGIAN CAPITAL LETTER CAN
+10BB; C; 2D1B; # GEORGIAN CAPITAL LETTER JIL
+10BC; C; 2D1C; # GEORGIAN CAPITAL LETTER CIL
+10BD; C; 2D1D; # GEORGIAN CAPITAL LETTER CHAR
+10BE; C; 2D1E; # GEORGIAN CAPITAL LETTER XAN
+10BF; C; 2D1F; # GEORGIAN CAPITAL LETTER JHAN
+10C0; C; 2D20; # GEORGIAN CAPITAL LETTER HAE
+10C1; C; 2D21; # GEORGIAN CAPITAL LETTER HE
+10C2; C; 2D22; # GEORGIAN CAPITAL LETTER HIE
+10C3; C; 2D23; # GEORGIAN CAPITAL LETTER WE
+10C4; C; 2D24; # GEORGIAN CAPITAL LETTER HAR
+10C5; C; 2D25; # GEORGIAN CAPITAL LETTER HOE
+10C7; C; 2D27; # GEORGIAN CAPITAL LETTER YN
+10CD; C; 2D2D; # GEORGIAN CAPITAL LETTER AEN
+13F8; C; 13F0; # CHEROKEE SMALL LETTER YE
+13F9; C; 13F1; # CHEROKEE SMALL LETTER YI
+13FA; C; 13F2; # CHEROKEE SMALL LETTER YO
+13FB; C; 13F3; # CHEROKEE SMALL LETTER YU
+13FC; C; 13F4; # CHEROKEE SMALL LETTER YV
+13FD; C; 13F5; # CHEROKEE SMALL LETTER MV
+1C80; C; 0432; # CYRILLIC SMALL LETTER ROUNDED VE
+1C81; C; 0434; # CYRILLIC SMALL LETTER LONG-LEGGED DE
+1C82; C; 043E; # CYRILLIC SMALL LETTER NARROW O
+1C83; C; 0441; # CYRILLIC SMALL LETTER WIDE ES
+1C84; C; 0442; # CYRILLIC SMALL LETTER TALL TE
+1C85; C; 0442; # CYRILLIC SMALL LETTER THREE-LEGGED TE
+1C86; C; 044A; # CYRILLIC SMALL LETTER TALL HARD SIGN
+1C87; C; 0463; # CYRILLIC SMALL LETTER TALL YAT
+1C88; C; A64B; # CYRILLIC SMALL LETTER UNBLENDED UK
+1E00; C; 1E01; # LATIN CAPITAL LETTER A WITH RING BELOW
+1E02; C; 1E03; # LATIN CAPITAL LETTER B WITH DOT ABOVE
+1E04; C; 1E05; # LATIN CAPITAL LETTER B WITH DOT BELOW
+1E06; C; 1E07; # LATIN CAPITAL LETTER B WITH LINE BELOW
+1E08; C; 1E09; # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
+1E0A; C; 1E0B; # LATIN CAPITAL LETTER D WITH DOT ABOVE
+1E0C; C; 1E0D; # LATIN CAPITAL LETTER D WITH DOT BELOW
+1E0E; C; 1E0F; # LATIN CAPITAL LETTER D WITH LINE BELOW
+1E10; C; 1E11; # LATIN CAPITAL LETTER D WITH CEDILLA
+1E12; C; 1E13; # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
+1E14; C; 1E15; # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
+1E16; C; 1E17; # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
+1E18; C; 1E19; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
+1E1A; C; 1E1B; # LATIN CAPITAL LETTER E WITH TILDE BELOW
+1E1C; C; 1E1D; # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
+1E1E; C; 1E1F; # LATIN CAPITAL LETTER F WITH DOT ABOVE
+1E20; C; 1E21; # LATIN CAPITAL LETTER G WITH MACRON
+1E22; C; 1E23; # LATIN CAPITAL LETTER H WITH DOT ABOVE
+1E24; C; 1E25; # LATIN CAPITAL LETTER H WITH DOT BELOW
+1E26; C; 1E27; # LATIN CAPITAL LETTER H WITH DIAERESIS
+1E28; C; 1E29; # LATIN CAPITAL LETTER H WITH CEDILLA
+1E2A; C; 1E2B; # LATIN CAPITAL LETTER H WITH BREVE BELOW
+1E2C; C; 1E2D; # LATIN CAPITAL LETTER I WITH TILDE BELOW
+1E2E; C; 1E2F; # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
+1E30; C; 1E31; # LATIN CAPITAL LETTER K WITH ACUTE
+1E32; C; 1E33; # LATIN CAPITAL LETTER K WITH DOT BELOW
+1E34; C; 1E35; # LATIN CAPITAL LETTER K WITH LINE BELOW
+1E36; C; 1E37; # LATIN CAPITAL LETTER L WITH DOT BELOW
+1E38; C; 1E39; # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
+1E3A; C; 1E3B; # LATIN CAPITAL LETTER L WITH LINE BELOW
+1E3C; C; 1E3D; # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
+1E3E; C; 1E3F; # LATIN CAPITAL LETTER M WITH ACUTE
+1E40; C; 1E41; # LATIN CAPITAL LETTER M WITH DOT ABOVE
+1E42; C; 1E43; # LATIN CAPITAL LETTER M WITH DOT BELOW
+1E44; C; 1E45; # LATIN CAPITAL LETTER N WITH DOT ABOVE
+1E46; C; 1E47; # LATIN CAPITAL LETTER N WITH DOT BELOW
+1E48; C; 1E49; # LATIN CAPITAL LETTER N WITH LINE BELOW
+1E4A; C; 1E4B; # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
+1E4C; C; 1E4D; # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
+1E4E; C; 1E4F; # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
+1E50; C; 1E51; # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
+1E52; C; 1E53; # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
+1E54; C; 1E55; # LATIN CAPITAL LETTER P WITH ACUTE
+1E56; C; 1E57; # LATIN CAPITAL LETTER P WITH DOT ABOVE
+1E58; C; 1E59; # LATIN CAPITAL LETTER R WITH DOT ABOVE
+1E5A; C; 1E5B; # LATIN CAPITAL LETTER R WITH DOT BELOW
+1E5C; C; 1E5D; # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
+1E5E; C; 1E5F; # LATIN CAPITAL LETTER R WITH LINE BELOW
+1E60; C; 1E61; # LATIN CAPITAL LETTER S WITH DOT ABOVE
+1E62; C; 1E63; # LATIN CAPITAL LETTER S WITH DOT BELOW
+1E64; C; 1E65; # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
+1E66; C; 1E67; # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
+1E68; C; 1E69; # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
+1E6A; C; 1E6B; # LATIN CAPITAL LETTER T WITH DOT ABOVE
+1E6C; C; 1E6D; # LATIN CAPITAL LETTER T WITH DOT BELOW
+1E6E; C; 1E6F; # LATIN CAPITAL LETTER T WITH LINE BELOW
+1E70; C; 1E71; # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
+1E72; C; 1E73; # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
+1E74; C; 1E75; # LATIN CAPITAL LETTER U WITH TILDE BELOW
+1E76; C; 1E77; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
+1E78; C; 1E79; # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
+1E7A; C; 1E7B; # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
+1E7C; C; 1E7D; # LATIN CAPITAL LETTER V WITH TILDE
+1E7E; C; 1E7F; # LATIN CAPITAL LETTER V WITH DOT BELOW
+1E80; C; 1E81; # LATIN CAPITAL LETTER W WITH GRAVE
+1E82; C; 1E83; # LATIN CAPITAL LETTER W WITH ACUTE
+1E84; C; 1E85; # LATIN CAPITAL LETTER W WITH DIAERESIS
+1E86; C; 1E87; # LATIN CAPITAL LETTER W WITH DOT ABOVE
+1E88; C; 1E89; # LATIN CAPITAL LETTER W WITH DOT BELOW
+1E8A; C; 1E8B; # LATIN CAPITAL LETTER X WITH DOT ABOVE
+1E8C; C; 1E8D; # LATIN CAPITAL LETTER X WITH DIAERESIS
+1E8E; C; 1E8F; # LATIN CAPITAL LETTER Y WITH DOT ABOVE
+1E90; C; 1E91; # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
+1E92; C; 1E93; # LATIN CAPITAL LETTER Z WITH DOT BELOW
+1E94; C; 1E95; # LATIN CAPITAL LETTER Z WITH LINE BELOW
+1E96; F; 0068 0331; # LATIN SMALL LETTER H WITH LINE BELOW
+1E97; F; 0074 0308; # LATIN SMALL LETTER T WITH DIAERESIS
+1E98; F; 0077 030A; # LATIN SMALL LETTER W WITH RING ABOVE
+1E99; F; 0079 030A; # LATIN SMALL LETTER Y WITH RING ABOVE
+1E9A; F; 0061 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING
+1E9B; C; 1E61; # LATIN SMALL LETTER LONG S WITH DOT ABOVE
+1E9E; F; 0073 0073; # LATIN CAPITAL LETTER SHARP S
+1E9E; S; 00DF; # LATIN CAPITAL LETTER SHARP S
+1EA0; C; 1EA1; # LATIN CAPITAL LETTER A WITH DOT BELOW
+1EA2; C; 1EA3; # LATIN CAPITAL LETTER A WITH HOOK ABOVE
+1EA4; C; 1EA5; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
+1EA6; C; 1EA7; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
+1EA8; C; 1EA9; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
+1EAA; C; 1EAB; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
+1EAC; C; 1EAD; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
+1EAE; C; 1EAF; # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
+1EB0; C; 1EB1; # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
+1EB2; C; 1EB3; # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
+1EB4; C; 1EB5; # LATIN CAPITAL LETTER A WITH BREVE AND TILDE
+1EB6; C; 1EB7; # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
+1EB8; C; 1EB9; # LATIN CAPITAL LETTER E WITH DOT BELOW
+1EBA; C; 1EBB; # LATIN CAPITAL LETTER E WITH HOOK ABOVE
+1EBC; C; 1EBD; # LATIN CAPITAL LETTER E WITH TILDE
+1EBE; C; 1EBF; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
+1EC0; C; 1EC1; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
+1EC2; C; 1EC3; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
+1EC4; C; 1EC5; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
+1EC6; C; 1EC7; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
+1EC8; C; 1EC9; # LATIN CAPITAL LETTER I WITH HOOK ABOVE
+1ECA; C; 1ECB; # LATIN CAPITAL LETTER I WITH DOT BELOW
+1ECC; C; 1ECD; # LATIN CAPITAL LETTER O WITH DOT BELOW
+1ECE; C; 1ECF; # LATIN CAPITAL LETTER O WITH HOOK ABOVE
+1ED0; C; 1ED1; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
+1ED2; C; 1ED3; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
+1ED4; C; 1ED5; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
+1ED6; C; 1ED7; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
+1ED8; C; 1ED9; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
+1EDA; C; 1EDB; # LATIN CAPITAL LETTER O WITH HORN AND ACUTE
+1EDC; C; 1EDD; # LATIN CAPITAL LETTER O WITH HORN AND GRAVE
+1EDE; C; 1EDF; # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
+1EE0; C; 1EE1; # LATIN CAPITAL LETTER O WITH HORN AND TILDE
+1EE2; C; 1EE3; # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
+1EE4; C; 1EE5; # LATIN CAPITAL LETTER U WITH DOT BELOW
+1EE6; C; 1EE7; # LATIN CAPITAL LETTER U WITH HOOK ABOVE
+1EE8; C; 1EE9; # LATIN CAPITAL LETTER U WITH HORN AND ACUTE
+1EEA; C; 1EEB; # LATIN CAPITAL LETTER U WITH HORN AND GRAVE
+1EEC; C; 1EED; # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
+1EEE; C; 1EEF; # LATIN CAPITAL LETTER U WITH HORN AND TILDE
+1EF0; C; 1EF1; # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
+1EF2; C; 1EF3; # LATIN CAPITAL LETTER Y WITH GRAVE
+1EF4; C; 1EF5; # LATIN CAPITAL LETTER Y WITH DOT BELOW
+1EF6; C; 1EF7; # LATIN CAPITAL LETTER Y WITH HOOK ABOVE
+1EF8; C; 1EF9; # LATIN CAPITAL LETTER Y WITH TILDE
+1EFA; C; 1EFB; # LATIN CAPITAL LETTER MIDDLE-WELSH LL
+1EFC; C; 1EFD; # LATIN CAPITAL LETTER MIDDLE-WELSH V
+1EFE; C; 1EFF; # LATIN CAPITAL LETTER Y WITH LOOP
+1F08; C; 1F00; # GREEK CAPITAL LETTER ALPHA WITH PSILI
+1F09; C; 1F01; # GREEK CAPITAL LETTER ALPHA WITH DASIA
+1F0A; C; 1F02; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
+1F0B; C; 1F03; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
+1F0C; C; 1F04; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
+1F0D; C; 1F05; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
+1F0E; C; 1F06; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
+1F0F; C; 1F07; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
+1F18; C; 1F10; # GREEK CAPITAL LETTER EPSILON WITH PSILI
+1F19; C; 1F11; # GREEK CAPITAL LETTER EPSILON WITH DASIA
+1F1A; C; 1F12; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
+1F1B; C; 1F13; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
+1F1C; C; 1F14; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
+1F1D; C; 1F15; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
+1F28; C; 1F20; # GREEK CAPITAL LETTER ETA WITH PSILI
+1F29; C; 1F21; # GREEK CAPITAL LETTER ETA WITH DASIA
+1F2A; C; 1F22; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
+1F2B; C; 1F23; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
+1F2C; C; 1F24; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
+1F2D; C; 1F25; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
+1F2E; C; 1F26; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
+1F2F; C; 1F27; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
+1F38; C; 1F30; # GREEK CAPITAL LETTER IOTA WITH PSILI
+1F39; C; 1F31; # GREEK CAPITAL LETTER IOTA WITH DASIA
+1F3A; C; 1F32; # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
+1F3B; C; 1F33; # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
+1F3C; C; 1F34; # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
+1F3D; C; 1F35; # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
+1F3E; C; 1F36; # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
+1F3F; C; 1F37; # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
+1F48; C; 1F40; # GREEK CAPITAL LETTER OMICRON WITH PSILI
+1F49; C; 1F41; # GREEK CAPITAL LETTER OMICRON WITH DASIA
+1F4A; C; 1F42; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
+1F4B; C; 1F43; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
+1F4C; C; 1F44; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
+1F4D; C; 1F45; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
+1F50; F; 03C5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI
+1F52; F; 03C5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
+1F54; F; 03C5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
+1F56; F; 03C5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
+1F59; C; 1F51; # GREEK CAPITAL LETTER UPSILON WITH DASIA
+1F5B; C; 1F53; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
+1F5D; C; 1F55; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
+1F5F; C; 1F57; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
+1F68; C; 1F60; # GREEK CAPITAL LETTER OMEGA WITH PSILI
+1F69; C; 1F61; # GREEK CAPITAL LETTER OMEGA WITH DASIA
+1F6A; C; 1F62; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
+1F6B; C; 1F63; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
+1F6C; C; 1F64; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
+1F6D; C; 1F65; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
+1F6E; C; 1F66; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
+1F6F; C; 1F67; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
+1F80; F; 1F00 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
+1F81; F; 1F01 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
+1F82; F; 1F02 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1F83; F; 1F03 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1F84; F; 1F04 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1F85; F; 1F05 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1F86; F; 1F06 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1F87; F; 1F07 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1F88; F; 1F00 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
+1F88; S; 1F80; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
+1F89; F; 1F01 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
+1F89; S; 1F81; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
+1F8A; F; 1F02 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F8A; S; 1F82; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F8B; F; 1F03 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F8B; S; 1F83; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F8C; F; 1F04 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F8C; S; 1F84; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F8D; F; 1F05 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F8D; S; 1F85; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F8E; F; 1F06 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F8E; S; 1F86; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F8F; F; 1F07 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1F8F; S; 1F87; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1F90; F; 1F20 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
+1F91; F; 1F21 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
+1F92; F; 1F22 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1F93; F; 1F23 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1F94; F; 1F24 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1F95; F; 1F25 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1F96; F; 1F26 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1F97; F; 1F27 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1F98; F; 1F20 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
+1F98; S; 1F90; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
+1F99; F; 1F21 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
+1F99; S; 1F91; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
+1F9A; F; 1F22 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F9A; S; 1F92; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F9B; F; 1F23 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F9B; S; 1F93; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F9C; F; 1F24 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F9C; S; 1F94; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F9D; F; 1F25 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F9D; S; 1F95; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F9E; F; 1F26 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F9E; S; 1F96; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F9F; F; 1F27 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1F9F; S; 1F97; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1FA0; F; 1F60 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
+1FA1; F; 1F61 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
+1FA2; F; 1F62 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1FA3; F; 1F63 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1FA4; F; 1F64 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1FA5; F; 1F65 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1FA6; F; 1F66 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1FA7; F; 1F67 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1FA8; F; 1F60 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
+1FA8; S; 1FA0; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
+1FA9; F; 1F61 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
+1FA9; S; 1FA1; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
+1FAA; F; 1F62 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1FAA; S; 1FA2; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1FAB; F; 1F63 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1FAB; S; 1FA3; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1FAC; F; 1F64 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1FAC; S; 1FA4; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1FAD; F; 1F65 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1FAD; S; 1FA5; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1FAE; F; 1F66 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1FAE; S; 1FA6; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1FAF; F; 1F67 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1FAF; S; 1FA7; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1FB2; F; 1F70 03B9; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
+1FB3; F; 03B1 03B9; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
+1FB4; F; 03AC 03B9; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
+1FB6; F; 03B1 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI
+1FB7; F; 03B1 0342 03B9; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
+1FB8; C; 1FB0; # GREEK CAPITAL LETTER ALPHA WITH VRACHY
+1FB9; C; 1FB1; # GREEK CAPITAL LETTER ALPHA WITH MACRON
+1FBA; C; 1F70; # GREEK CAPITAL LETTER ALPHA WITH VARIA
+1FBB; C; 1F71; # GREEK CAPITAL LETTER ALPHA WITH OXIA
+1FBC; F; 03B1 03B9; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+1FBC; S; 1FB3; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+1FBE; C; 03B9; # GREEK PROSGEGRAMMENI
+1FC2; F; 1F74 03B9; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
+1FC3; F; 03B7 03B9; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
+1FC4; F; 03AE 03B9; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
+1FC6; F; 03B7 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI
+1FC7; F; 03B7 0342 03B9; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
+1FC8; C; 1F72; # GREEK CAPITAL LETTER EPSILON WITH VARIA
+1FC9; C; 1F73; # GREEK CAPITAL LETTER EPSILON WITH OXIA
+1FCA; C; 1F74; # GREEK CAPITAL LETTER ETA WITH VARIA
+1FCB; C; 1F75; # GREEK CAPITAL LETTER ETA WITH OXIA
+1FCC; F; 03B7 03B9; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+1FCC; S; 1FC3; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+1FD2; F; 03B9 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
+1FD3; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
+1FD6; F; 03B9 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI
+1FD7; F; 03B9 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
+1FD8; C; 1FD0; # GREEK CAPITAL LETTER IOTA WITH VRACHY
+1FD9; C; 1FD1; # GREEK CAPITAL LETTER IOTA WITH MACRON
+1FDA; C; 1F76; # GREEK CAPITAL LETTER IOTA WITH VARIA
+1FDB; C; 1F77; # GREEK CAPITAL LETTER IOTA WITH OXIA
+1FE2; F; 03C5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
+1FE3; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
+1FE4; F; 03C1 0313; # GREEK SMALL LETTER RHO WITH PSILI
+1FE6; F; 03C5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI
+1FE7; F; 03C5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
+1FE8; C; 1FE0; # GREEK CAPITAL LETTER UPSILON WITH VRACHY
+1FE9; C; 1FE1; # GREEK CAPITAL LETTER UPSILON WITH MACRON
+1FEA; C; 1F7A; # GREEK CAPITAL LETTER UPSILON WITH VARIA
+1FEB; C; 1F7B; # GREEK CAPITAL LETTER UPSILON WITH OXIA
+1FEC; C; 1FE5; # GREEK CAPITAL LETTER RHO WITH DASIA
+1FF2; F; 1F7C 03B9; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
+1FF3; F; 03C9 03B9; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
+1FF4; F; 03CE 03B9; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
+1FF6; F; 03C9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI
+1FF7; F; 03C9 0342 03B9; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
+1FF8; C; 1F78; # GREEK CAPITAL LETTER OMICRON WITH VARIA
+1FF9; C; 1F79; # GREEK CAPITAL LETTER OMICRON WITH OXIA
+1FFA; C; 1F7C; # GREEK CAPITAL LETTER OMEGA WITH VARIA
+1FFB; C; 1F7D; # GREEK CAPITAL LETTER OMEGA WITH OXIA
+1FFC; F; 03C9 03B9; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+1FFC; S; 1FF3; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+2126; C; 03C9; # OHM SIGN
+212A; C; 006B; # KELVIN SIGN
+212B; C; 00E5; # ANGSTROM SIGN
+2132; C; 214E; # TURNED CAPITAL F
+2160; C; 2170; # ROMAN NUMERAL ONE
+2161; C; 2171; # ROMAN NUMERAL TWO
+2162; C; 2172; # ROMAN NUMERAL THREE
+2163; C; 2173; # ROMAN NUMERAL FOUR
+2164; C; 2174; # ROMAN NUMERAL FIVE
+2165; C; 2175; # ROMAN NUMERAL SIX
+2166; C; 2176; # ROMAN NUMERAL SEVEN
+2167; C; 2177; # ROMAN NUMERAL EIGHT
+2168; C; 2178; # ROMAN NUMERAL NINE
+2169; C; 2179; # ROMAN NUMERAL TEN
+216A; C; 217A; # ROMAN NUMERAL ELEVEN
+216B; C; 217B; # ROMAN NUMERAL TWELVE
+216C; C; 217C; # ROMAN NUMERAL FIFTY
+216D; C; 217D; # ROMAN NUMERAL ONE HUNDRED
+216E; C; 217E; # ROMAN NUMERAL FIVE HUNDRED
+216F; C; 217F; # ROMAN NUMERAL ONE THOUSAND
+2183; C; 2184; # ROMAN NUMERAL REVERSED ONE HUNDRED
+24B6; C; 24D0; # CIRCLED LATIN CAPITAL LETTER A
+24B7; C; 24D1; # CIRCLED LATIN CAPITAL LETTER B
+24B8; C; 24D2; # CIRCLED LATIN CAPITAL LETTER C
+24B9; C; 24D3; # CIRCLED LATIN CAPITAL LETTER D
+24BA; C; 24D4; # CIRCLED LATIN CAPITAL LETTER E
+24BB; C; 24D5; # CIRCLED LATIN CAPITAL LETTER F
+24BC; C; 24D6; # CIRCLED LATIN CAPITAL LETTER G
+24BD; C; 24D7; # CIRCLED LATIN CAPITAL LETTER H
+24BE; C; 24D8; # CIRCLED LATIN CAPITAL LETTER I
+24BF; C; 24D9; # CIRCLED LATIN CAPITAL LETTER J
+24C0; C; 24DA; # CIRCLED LATIN CAPITAL LETTER K
+24C1; C; 24DB; # CIRCLED LATIN CAPITAL LETTER L
+24C2; C; 24DC; # CIRCLED LATIN CAPITAL LETTER M
+24C3; C; 24DD; # CIRCLED LATIN CAPITAL LETTER N
+24C4; C; 24DE; # CIRCLED LATIN CAPITAL LETTER O
+24C5; C; 24DF; # CIRCLED LATIN CAPITAL LETTER P
+24C6; C; 24E0; # CIRCLED LATIN CAPITAL LETTER Q
+24C7; C; 24E1; # CIRCLED LATIN CAPITAL LETTER R
+24C8; C; 24E2; # CIRCLED LATIN CAPITAL LETTER S
+24C9; C; 24E3; # CIRCLED LATIN CAPITAL LETTER T
+24CA; C; 24E4; # CIRCLED LATIN CAPITAL LETTER U
+24CB; C; 24E5; # CIRCLED LATIN CAPITAL LETTER V
+24CC; C; 24E6; # CIRCLED LATIN CAPITAL LETTER W
+24CD; C; 24E7; # CIRCLED LATIN CAPITAL LETTER X
+24CE; C; 24E8; # CIRCLED LATIN CAPITAL LETTER Y
+24CF; C; 24E9; # CIRCLED LATIN CAPITAL LETTER Z
+2C00; C; 2C30; # GLAGOLITIC CAPITAL LETTER AZU
+2C01; C; 2C31; # GLAGOLITIC CAPITAL LETTER BUKY
+2C02; C; 2C32; # GLAGOLITIC CAPITAL LETTER VEDE
+2C03; C; 2C33; # GLAGOLITIC CAPITAL LETTER GLAGOLI
+2C04; C; 2C34; # GLAGOLITIC CAPITAL LETTER DOBRO
+2C05; C; 2C35; # GLAGOLITIC CAPITAL LETTER YESTU
+2C06; C; 2C36; # GLAGOLITIC CAPITAL LETTER ZHIVETE
+2C07; C; 2C37; # GLAGOLITIC CAPITAL LETTER DZELO
+2C08; C; 2C38; # GLAGOLITIC CAPITAL LETTER ZEMLJA
+2C09; C; 2C39; # GLAGOLITIC CAPITAL LETTER IZHE
+2C0A; C; 2C3A; # GLAGOLITIC CAPITAL LETTER INITIAL IZHE
+2C0B; C; 2C3B; # GLAGOLITIC CAPITAL LETTER I
+2C0C; C; 2C3C; # GLAGOLITIC CAPITAL LETTER DJERVI
+2C0D; C; 2C3D; # GLAGOLITIC CAPITAL LETTER KAKO
+2C0E; C; 2C3E; # GLAGOLITIC CAPITAL LETTER LJUDIJE
+2C0F; C; 2C3F; # GLAGOLITIC CAPITAL LETTER MYSLITE
+2C10; C; 2C40; # GLAGOLITIC CAPITAL LETTER NASHI
+2C11; C; 2C41; # GLAGOLITIC CAPITAL LETTER ONU
+2C12; C; 2C42; # GLAGOLITIC CAPITAL LETTER POKOJI
+2C13; C; 2C43; # GLAGOLITIC CAPITAL LETTER RITSI
+2C14; C; 2C44; # GLAGOLITIC CAPITAL LETTER SLOVO
+2C15; C; 2C45; # GLAGOLITIC CAPITAL LETTER TVRIDO
+2C16; C; 2C46; # GLAGOLITIC CAPITAL LETTER UKU
+2C17; C; 2C47; # GLAGOLITIC CAPITAL LETTER FRITU
+2C18; C; 2C48; # GLAGOLITIC CAPITAL LETTER HERU
+2C19; C; 2C49; # GLAGOLITIC CAPITAL LETTER OTU
+2C1A; C; 2C4A; # GLAGOLITIC CAPITAL LETTER PE
+2C1B; C; 2C4B; # GLAGOLITIC CAPITAL LETTER SHTA
+2C1C; C; 2C4C; # GLAGOLITIC CAPITAL LETTER TSI
+2C1D; C; 2C4D; # GLAGOLITIC CAPITAL LETTER CHRIVI
+2C1E; C; 2C4E; # GLAGOLITIC CAPITAL LETTER SHA
+2C1F; C; 2C4F; # GLAGOLITIC CAPITAL LETTER YERU
+2C20; C; 2C50; # GLAGOLITIC CAPITAL LETTER YERI
+2C21; C; 2C51; # GLAGOLITIC CAPITAL LETTER YATI
+2C22; C; 2C52; # GLAGOLITIC CAPITAL LETTER SPIDERY HA
+2C23; C; 2C53; # GLAGOLITIC CAPITAL LETTER YU
+2C24; C; 2C54; # GLAGOLITIC CAPITAL LETTER SMALL YUS
+2C25; C; 2C55; # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL
+2C26; C; 2C56; # GLAGOLITIC CAPITAL LETTER YO
+2C27; C; 2C57; # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS
+2C28; C; 2C58; # GLAGOLITIC CAPITAL LETTER BIG YUS
+2C29; C; 2C59; # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS
+2C2A; C; 2C5A; # GLAGOLITIC CAPITAL LETTER FITA
+2C2B; C; 2C5B; # GLAGOLITIC CAPITAL LETTER IZHITSA
+2C2C; C; 2C5C; # GLAGOLITIC CAPITAL LETTER SHTAPIC
+2C2D; C; 2C5D; # GLAGOLITIC CAPITAL LETTER TROKUTASTI A
+2C2E; C; 2C5E; # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
+2C60; C; 2C61; # LATIN CAPITAL LETTER L WITH DOUBLE BAR
+2C62; C; 026B; # LATIN CAPITAL LETTER L WITH MIDDLE TILDE
+2C63; C; 1D7D; # LATIN CAPITAL LETTER P WITH STROKE
+2C64; C; 027D; # LATIN CAPITAL LETTER R WITH TAIL
+2C67; C; 2C68; # LATIN CAPITAL LETTER H WITH DESCENDER
+2C69; C; 2C6A; # LATIN CAPITAL LETTER K WITH DESCENDER
+2C6B; C; 2C6C; # LATIN CAPITAL LETTER Z WITH DESCENDER
+2C6D; C; 0251; # LATIN CAPITAL LETTER ALPHA
+2C6E; C; 0271; # LATIN CAPITAL LETTER M WITH HOOK
+2C6F; C; 0250; # LATIN CAPITAL LETTER TURNED A
+2C70; C; 0252; # LATIN CAPITAL LETTER TURNED ALPHA
+2C72; C; 2C73; # LATIN CAPITAL LETTER W WITH HOOK
+2C75; C; 2C76; # LATIN CAPITAL LETTER HALF H
+2C7E; C; 023F; # LATIN CAPITAL LETTER S WITH SWASH TAIL
+2C7F; C; 0240; # LATIN CAPITAL LETTER Z WITH SWASH TAIL
+2C80; C; 2C81; # COPTIC CAPITAL LETTER ALFA
+2C82; C; 2C83; # COPTIC CAPITAL LETTER VIDA
+2C84; C; 2C85; # COPTIC CAPITAL LETTER GAMMA
+2C86; C; 2C87; # COPTIC CAPITAL LETTER DALDA
+2C88; C; 2C89; # COPTIC CAPITAL LETTER EIE
+2C8A; C; 2C8B; # COPTIC CAPITAL LETTER SOU
+2C8C; C; 2C8D; # COPTIC CAPITAL LETTER ZATA
+2C8E; C; 2C8F; # COPTIC CAPITAL LETTER HATE
+2C90; C; 2C91; # COPTIC CAPITAL LETTER THETHE
+2C92; C; 2C93; # COPTIC CAPITAL LETTER IAUDA
+2C94; C; 2C95; # COPTIC CAPITAL LETTER KAPA
+2C96; C; 2C97; # COPTIC CAPITAL LETTER LAULA
+2C98; C; 2C99; # COPTIC CAPITAL LETTER MI
+2C9A; C; 2C9B; # COPTIC CAPITAL LETTER NI
+2C9C; C; 2C9D; # COPTIC CAPITAL LETTER KSI
+2C9E; C; 2C9F; # COPTIC CAPITAL LETTER O
+2CA0; C; 2CA1; # COPTIC CAPITAL LETTER PI
+2CA2; C; 2CA3; # COPTIC CAPITAL LETTER RO
+2CA4; C; 2CA5; # COPTIC CAPITAL LETTER SIMA
+2CA6; C; 2CA7; # COPTIC CAPITAL LETTER TAU
+2CA8; C; 2CA9; # COPTIC CAPITAL LETTER UA
+2CAA; C; 2CAB; # COPTIC CAPITAL LETTER FI
+2CAC; C; 2CAD; # COPTIC CAPITAL LETTER KHI
+2CAE; C; 2CAF; # COPTIC CAPITAL LETTER PSI
+2CB0; C; 2CB1; # COPTIC CAPITAL LETTER OOU
+2CB2; C; 2CB3; # COPTIC CAPITAL LETTER DIALECT-P ALEF
+2CB4; C; 2CB5; # COPTIC CAPITAL LETTER OLD COPTIC AIN
+2CB6; C; 2CB7; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE
+2CB8; C; 2CB9; # COPTIC CAPITAL LETTER DIALECT-P KAPA
+2CBA; C; 2CBB; # COPTIC CAPITAL LETTER DIALECT-P NI
+2CBC; C; 2CBD; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI
+2CBE; C; 2CBF; # COPTIC CAPITAL LETTER OLD COPTIC OOU
+2CC0; C; 2CC1; # COPTIC CAPITAL LETTER SAMPI
+2CC2; C; 2CC3; # COPTIC CAPITAL LETTER CROSSED SHEI
+2CC4; C; 2CC5; # COPTIC CAPITAL LETTER OLD COPTIC SHEI
+2CC6; C; 2CC7; # COPTIC CAPITAL LETTER OLD COPTIC ESH
+2CC8; C; 2CC9; # COPTIC CAPITAL LETTER AKHMIMIC KHEI
+2CCA; C; 2CCB; # COPTIC CAPITAL LETTER DIALECT-P HORI
+2CCC; C; 2CCD; # COPTIC CAPITAL LETTER OLD COPTIC HORI
+2CCE; C; 2CCF; # COPTIC CAPITAL LETTER OLD COPTIC HA
+2CD0; C; 2CD1; # COPTIC CAPITAL LETTER L-SHAPED HA
+2CD2; C; 2CD3; # COPTIC CAPITAL LETTER OLD COPTIC HEI
+2CD4; C; 2CD5; # COPTIC CAPITAL LETTER OLD COPTIC HAT
+2CD6; C; 2CD7; # COPTIC CAPITAL LETTER OLD COPTIC GANGIA
+2CD8; C; 2CD9; # COPTIC CAPITAL LETTER OLD COPTIC DJA
+2CDA; C; 2CDB; # COPTIC CAPITAL LETTER OLD COPTIC SHIMA
+2CDC; C; 2CDD; # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA
+2CDE; C; 2CDF; # COPTIC CAPITAL LETTER OLD NUBIAN NGI
+2CE0; C; 2CE1; # COPTIC CAPITAL LETTER OLD NUBIAN NYI
+2CE2; C; 2CE3; # COPTIC CAPITAL LETTER OLD NUBIAN WAU
+2CEB; C; 2CEC; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI
+2CED; C; 2CEE; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA
+2CF2; C; 2CF3; # COPTIC CAPITAL LETTER BOHAIRIC KHEI
+A640; C; A641; # CYRILLIC CAPITAL LETTER ZEMLYA
+A642; C; A643; # CYRILLIC CAPITAL LETTER DZELO
+A644; C; A645; # CYRILLIC CAPITAL LETTER REVERSED DZE
+A646; C; A647; # CYRILLIC CAPITAL LETTER IOTA
+A648; C; A649; # CYRILLIC CAPITAL LETTER DJERV
+A64A; C; A64B; # CYRILLIC CAPITAL LETTER MONOGRAPH UK
+A64C; C; A64D; # CYRILLIC CAPITAL LETTER BROAD OMEGA
+A64E; C; A64F; # CYRILLIC CAPITAL LETTER NEUTRAL YER
+A650; C; A651; # CYRILLIC CAPITAL LETTER YERU WITH BACK YER
+A652; C; A653; # CYRILLIC CAPITAL LETTER IOTIFIED YAT
+A654; C; A655; # CYRILLIC CAPITAL LETTER REVERSED YU
+A656; C; A657; # CYRILLIC CAPITAL LETTER IOTIFIED A
+A658; C; A659; # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS
+A65A; C; A65B; # CYRILLIC CAPITAL LETTER BLENDED YUS
+A65C; C; A65D; # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS
+A65E; C; A65F; # CYRILLIC CAPITAL LETTER YN
+A660; C; A661; # CYRILLIC CAPITAL LETTER REVERSED TSE
+A662; C; A663; # CYRILLIC CAPITAL LETTER SOFT DE
+A664; C; A665; # CYRILLIC CAPITAL LETTER SOFT EL
+A666; C; A667; # CYRILLIC CAPITAL LETTER SOFT EM
+A668; C; A669; # CYRILLIC CAPITAL LETTER MONOCULAR O
+A66A; C; A66B; # CYRILLIC CAPITAL LETTER BINOCULAR O
+A66C; C; A66D; # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O
+A680; C; A681; # CYRILLIC CAPITAL LETTER DWE
+A682; C; A683; # CYRILLIC CAPITAL LETTER DZWE
+A684; C; A685; # CYRILLIC CAPITAL LETTER ZHWE
+A686; C; A687; # CYRILLIC CAPITAL LETTER CCHE
+A688; C; A689; # CYRILLIC CAPITAL LETTER DZZE
+A68A; C; A68B; # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK
+A68C; C; A68D; # CYRILLIC CAPITAL LETTER TWE
+A68E; C; A68F; # CYRILLIC CAPITAL LETTER TSWE
+A690; C; A691; # CYRILLIC CAPITAL LETTER TSSE
+A692; C; A693; # CYRILLIC CAPITAL LETTER TCHE
+A694; C; A695; # CYRILLIC CAPITAL LETTER HWE
+A696; C; A697; # CYRILLIC CAPITAL LETTER SHWE
+A698; C; A699; # CYRILLIC CAPITAL LETTER DOUBLE O
+A69A; C; A69B; # CYRILLIC CAPITAL LETTER CROSSED O
+A722; C; A723; # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF
+A724; C; A725; # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN
+A726; C; A727; # LATIN CAPITAL LETTER HENG
+A728; C; A729; # LATIN CAPITAL LETTER TZ
+A72A; C; A72B; # LATIN CAPITAL LETTER TRESILLO
+A72C; C; A72D; # LATIN CAPITAL LETTER CUATRILLO
+A72E; C; A72F; # LATIN CAPITAL LETTER CUATRILLO WITH COMMA
+A732; C; A733; # LATIN CAPITAL LETTER AA
+A734; C; A735; # LATIN CAPITAL LETTER AO
+A736; C; A737; # LATIN CAPITAL LETTER AU
+A738; C; A739; # LATIN CAPITAL LETTER AV
+A73A; C; A73B; # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR
+A73C; C; A73D; # LATIN CAPITAL LETTER AY
+A73E; C; A73F; # LATIN CAPITAL LETTER REVERSED C WITH DOT
+A740; C; A741; # LATIN CAPITAL LETTER K WITH STROKE
+A742; C; A743; # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE
+A744; C; A745; # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE
+A746; C; A747; # LATIN CAPITAL LETTER BROKEN L
+A748; C; A749; # LATIN CAPITAL LETTER L WITH HIGH STROKE
+A74A; C; A74B; # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY
+A74C; C; A74D; # LATIN CAPITAL LETTER O WITH LOOP
+A74E; C; A74F; # LATIN CAPITAL LETTER OO
+A750; C; A751; # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER
+A752; C; A753; # LATIN CAPITAL LETTER P WITH FLOURISH
+A754; C; A755; # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL
+A756; C; A757; # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER
+A758; C; A759; # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE
+A75A; C; A75B; # LATIN CAPITAL LETTER R ROTUNDA
+A75C; C; A75D; # LATIN CAPITAL LETTER RUM ROTUNDA
+A75E; C; A75F; # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE
+A760; C; A761; # LATIN CAPITAL LETTER VY
+A762; C; A763; # LATIN CAPITAL LETTER VISIGOTHIC Z
+A764; C; A765; # LATIN CAPITAL LETTER THORN WITH STROKE
+A766; C; A767; # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER
+A768; C; A769; # LATIN CAPITAL LETTER VEND
+A76A; C; A76B; # LATIN CAPITAL LETTER ET
+A76C; C; A76D; # LATIN CAPITAL LETTER IS
+A76E; C; A76F; # LATIN CAPITAL LETTER CON
+A779; C; A77A; # LATIN CAPITAL LETTER INSULAR D
+A77B; C; A77C; # LATIN CAPITAL LETTER INSULAR F
+A77D; C; 1D79; # LATIN CAPITAL LETTER INSULAR G
+A77E; C; A77F; # LATIN CAPITAL LETTER TURNED INSULAR G
+A780; C; A781; # LATIN CAPITAL LETTER TURNED L
+A782; C; A783; # LATIN CAPITAL LETTER INSULAR R
+A784; C; A785; # LATIN CAPITAL LETTER INSULAR S
+A786; C; A787; # LATIN CAPITAL LETTER INSULAR T
+A78B; C; A78C; # LATIN CAPITAL LETTER SALTILLO
+A78D; C; 0265; # LATIN CAPITAL LETTER TURNED H
+A790; C; A791; # LATIN CAPITAL LETTER N WITH DESCENDER
+A792; C; A793; # LATIN CAPITAL LETTER C WITH BAR
+A796; C; A797; # LATIN CAPITAL LETTER B WITH FLOURISH
+A798; C; A799; # LATIN CAPITAL LETTER F WITH STROKE
+A79A; C; A79B; # LATIN CAPITAL LETTER VOLAPUK AE
+A79C; C; A79D; # LATIN CAPITAL LETTER VOLAPUK OE
+A79E; C; A79F; # LATIN CAPITAL LETTER VOLAPUK UE
+A7A0; C; A7A1; # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE
+A7A2; C; A7A3; # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE
+A7A4; C; A7A5; # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE
+A7A6; C; A7A7; # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE
+A7A8; C; A7A9; # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE
+A7AA; C; 0266; # LATIN CAPITAL LETTER H WITH HOOK
+A7AB; C; 025C; # LATIN CAPITAL LETTER REVERSED OPEN E
+A7AC; C; 0261; # LATIN CAPITAL LETTER SCRIPT G
+A7AD; C; 026C; # LATIN CAPITAL LETTER L WITH BELT
+A7AE; C; 026A; # LATIN CAPITAL LETTER SMALL CAPITAL I
+A7B0; C; 029E; # LATIN CAPITAL LETTER TURNED K
+A7B1; C; 0287; # LATIN CAPITAL LETTER TURNED T
+A7B2; C; 029D; # LATIN CAPITAL LETTER J WITH CROSSED-TAIL
+A7B3; C; AB53; # LATIN CAPITAL LETTER CHI
+A7B4; C; A7B5; # LATIN CAPITAL LETTER BETA
+A7B6; C; A7B7; # LATIN CAPITAL LETTER OMEGA
+AB70; C; 13A0; # CHEROKEE SMALL LETTER A
+AB71; C; 13A1; # CHEROKEE SMALL LETTER E
+AB72; C; 13A2; # CHEROKEE SMALL LETTER I
+AB73; C; 13A3; # CHEROKEE SMALL LETTER O
+AB74; C; 13A4; # CHEROKEE SMALL LETTER U
+AB75; C; 13A5; # CHEROKEE SMALL LETTER V
+AB76; C; 13A6; # CHEROKEE SMALL LETTER GA
+AB77; C; 13A7; # CHEROKEE SMALL LETTER KA
+AB78; C; 13A8; # CHEROKEE SMALL LETTER GE
+AB79; C; 13A9; # CHEROKEE SMALL LETTER GI
+AB7A; C; 13AA; # CHEROKEE SMALL LETTER GO
+AB7B; C; 13AB; # CHEROKEE SMALL LETTER GU
+AB7C; C; 13AC; # CHEROKEE SMALL LETTER GV
+AB7D; C; 13AD; # CHEROKEE SMALL LETTER HA
+AB7E; C; 13AE; # CHEROKEE SMALL LETTER HE
+AB7F; C; 13AF; # CHEROKEE SMALL LETTER HI
+AB80; C; 13B0; # CHEROKEE SMALL LETTER HO
+AB81; C; 13B1; # CHEROKEE SMALL LETTER HU
+AB82; C; 13B2; # CHEROKEE SMALL LETTER HV
+AB83; C; 13B3; # CHEROKEE SMALL LETTER LA
+AB84; C; 13B4; # CHEROKEE SMALL LETTER LE
+AB85; C; 13B5; # CHEROKEE SMALL LETTER LI
+AB86; C; 13B6; # CHEROKEE SMALL LETTER LO
+AB87; C; 13B7; # CHEROKEE SMALL LETTER LU
+AB88; C; 13B8; # CHEROKEE SMALL LETTER LV
+AB89; C; 13B9; # CHEROKEE SMALL LETTER MA
+AB8A; C; 13BA; # CHEROKEE SMALL LETTER ME
+AB8B; C; 13BB; # CHEROKEE SMALL LETTER MI
+AB8C; C; 13BC; # CHEROKEE SMALL LETTER MO
+AB8D; C; 13BD; # CHEROKEE SMALL LETTER MU
+AB8E; C; 13BE; # CHEROKEE SMALL LETTER NA
+AB8F; C; 13BF; # CHEROKEE SMALL LETTER HNA
+AB90; C; 13C0; # CHEROKEE SMALL LETTER NAH
+AB91; C; 13C1; # CHEROKEE SMALL LETTER NE
+AB92; C; 13C2; # CHEROKEE SMALL LETTER NI
+AB93; C; 13C3; # CHEROKEE SMALL LETTER NO
+AB94; C; 13C4; # CHEROKEE SMALL LETTER NU
+AB95; C; 13C5; # CHEROKEE SMALL LETTER NV
+AB96; C; 13C6; # CHEROKEE SMALL LETTER QUA
+AB97; C; 13C7; # CHEROKEE SMALL LETTER QUE
+AB98; C; 13C8; # CHEROKEE SMALL LETTER QUI
+AB99; C; 13C9; # CHEROKEE SMALL LETTER QUO
+AB9A; C; 13CA; # CHEROKEE SMALL LETTER QUU
+AB9B; C; 13CB; # CHEROKEE SMALL LETTER QUV
+AB9C; C; 13CC; # CHEROKEE SMALL LETTER SA
+AB9D; C; 13CD; # CHEROKEE SMALL LETTER S
+AB9E; C; 13CE; # CHEROKEE SMALL LETTER SE
+AB9F; C; 13CF; # CHEROKEE SMALL LETTER SI
+ABA0; C; 13D0; # CHEROKEE SMALL LETTER SO
+ABA1; C; 13D1; # CHEROKEE SMALL LETTER SU
+ABA2; C; 13D2; # CHEROKEE SMALL LETTER SV
+ABA3; C; 13D3; # CHEROKEE SMALL LETTER DA
+ABA4; C; 13D4; # CHEROKEE SMALL LETTER TA
+ABA5; C; 13D5; # CHEROKEE SMALL LETTER DE
+ABA6; C; 13D6; # CHEROKEE SMALL LETTER TE
+ABA7; C; 13D7; # CHEROKEE SMALL LETTER DI
+ABA8; C; 13D8; # CHEROKEE SMALL LETTER TI
+ABA9; C; 13D9; # CHEROKEE SMALL LETTER DO
+ABAA; C; 13DA; # CHEROKEE SMALL LETTER DU
+ABAB; C; 13DB; # CHEROKEE SMALL LETTER DV
+ABAC; C; 13DC; # CHEROKEE SMALL LETTER DLA
+ABAD; C; 13DD; # CHEROKEE SMALL LETTER TLA
+ABAE; C; 13DE; # CHEROKEE SMALL LETTER TLE
+ABAF; C; 13DF; # CHEROKEE SMALL LETTER TLI
+ABB0; C; 13E0; # CHEROKEE SMALL LETTER TLO
+ABB1; C; 13E1; # CHEROKEE SMALL LETTER TLU
+ABB2; C; 13E2; # CHEROKEE SMALL LETTER TLV
+ABB3; C; 13E3; # CHEROKEE SMALL LETTER TSA
+ABB4; C; 13E4; # CHEROKEE SMALL LETTER TSE
+ABB5; C; 13E5; # CHEROKEE SMALL LETTER TSI
+ABB6; C; 13E6; # CHEROKEE SMALL LETTER TSO
+ABB7; C; 13E7; # CHEROKEE SMALL LETTER TSU
+ABB8; C; 13E8; # CHEROKEE SMALL LETTER TSV
+ABB9; C; 13E9; # CHEROKEE SMALL LETTER WA
+ABBA; C; 13EA; # CHEROKEE SMALL LETTER WE
+ABBB; C; 13EB; # CHEROKEE SMALL LETTER WI
+ABBC; C; 13EC; # CHEROKEE SMALL LETTER WO
+ABBD; C; 13ED; # CHEROKEE SMALL LETTER WU
+ABBE; C; 13EE; # CHEROKEE SMALL LETTER WV
+ABBF; C; 13EF; # CHEROKEE SMALL LETTER YA
+FB00; F; 0066 0066; # LATIN SMALL LIGATURE FF
+FB01; F; 0066 0069; # LATIN SMALL LIGATURE FI
+FB02; F; 0066 006C; # LATIN SMALL LIGATURE FL
+FB03; F; 0066 0066 0069; # LATIN SMALL LIGATURE FFI
+FB04; F; 0066 0066 006C; # LATIN SMALL LIGATURE FFL
+FB05; F; 0073 0074; # LATIN SMALL LIGATURE LONG S T
+FB06; F; 0073 0074; # LATIN SMALL LIGATURE ST
+FB13; F; 0574 0576; # ARMENIAN SMALL LIGATURE MEN NOW
+FB14; F; 0574 0565; # ARMENIAN SMALL LIGATURE MEN ECH
+FB15; F; 0574 056B; # ARMENIAN SMALL LIGATURE MEN INI
+FB16; F; 057E 0576; # ARMENIAN SMALL LIGATURE VEW NOW
+FB17; F; 0574 056D; # ARMENIAN SMALL LIGATURE MEN XEH
+FF21; C; FF41; # FULLWIDTH LATIN CAPITAL LETTER A
+FF22; C; FF42; # FULLWIDTH LATIN CAPITAL LETTER B
+FF23; C; FF43; # FULLWIDTH LATIN CAPITAL LETTER C
+FF24; C; FF44; # FULLWIDTH LATIN CAPITAL LETTER D
+FF25; C; FF45; # FULLWIDTH LATIN CAPITAL LETTER E
+FF26; C; FF46; # FULLWIDTH LATIN CAPITAL LETTER F
+FF27; C; FF47; # FULLWIDTH LATIN CAPITAL LETTER G
+FF28; C; FF48; # FULLWIDTH LATIN CAPITAL LETTER H
+FF29; C; FF49; # FULLWIDTH LATIN CAPITAL LETTER I
+FF2A; C; FF4A; # FULLWIDTH LATIN CAPITAL LETTER J
+FF2B; C; FF4B; # FULLWIDTH LATIN CAPITAL LETTER K
+FF2C; C; FF4C; # FULLWIDTH LATIN CAPITAL LETTER L
+FF2D; C; FF4D; # FULLWIDTH LATIN CAPITAL LETTER M
+FF2E; C; FF4E; # FULLWIDTH LATIN CAPITAL LETTER N
+FF2F; C; FF4F; # FULLWIDTH LATIN CAPITAL LETTER O
+FF30; C; FF50; # FULLWIDTH LATIN CAPITAL LETTER P
+FF31; C; FF51; # FULLWIDTH LATIN CAPITAL LETTER Q
+FF32; C; FF52; # FULLWIDTH LATIN CAPITAL LETTER R
+FF33; C; FF53; # FULLWIDTH LATIN CAPITAL LETTER S
+FF34; C; FF54; # FULLWIDTH LATIN CAPITAL LETTER T
+FF35; C; FF55; # FULLWIDTH LATIN CAPITAL LETTER U
+FF36; C; FF56; # FULLWIDTH LATIN CAPITAL LETTER V
+FF37; C; FF57; # FULLWIDTH LATIN CAPITAL LETTER W
+FF38; C; FF58; # FULLWIDTH LATIN CAPITAL LETTER X
+FF39; C; FF59; # FULLWIDTH LATIN CAPITAL LETTER Y
+FF3A; C; FF5A; # FULLWIDTH LATIN CAPITAL LETTER Z
+10400; C; 10428; # DESERET CAPITAL LETTER LONG I
+10401; C; 10429; # DESERET CAPITAL LETTER LONG E
+10402; C; 1042A; # DESERET CAPITAL LETTER LONG A
+10403; C; 1042B; # DESERET CAPITAL LETTER LONG AH
+10404; C; 1042C; # DESERET CAPITAL LETTER LONG O
+10405; C; 1042D; # DESERET CAPITAL LETTER LONG OO
+10406; C; 1042E; # DESERET CAPITAL LETTER SHORT I
+10407; C; 1042F; # DESERET CAPITAL LETTER SHORT E
+10408; C; 10430; # DESERET CAPITAL LETTER SHORT A
+10409; C; 10431; # DESERET CAPITAL LETTER SHORT AH
+1040A; C; 10432; # DESERET CAPITAL LETTER SHORT O
+1040B; C; 10433; # DESERET CAPITAL LETTER SHORT OO
+1040C; C; 10434; # DESERET CAPITAL LETTER AY
+1040D; C; 10435; # DESERET CAPITAL LETTER OW
+1040E; C; 10436; # DESERET CAPITAL LETTER WU
+1040F; C; 10437; # DESERET CAPITAL LETTER YEE
+10410; C; 10438; # DESERET CAPITAL LETTER H
+10411; C; 10439; # DESERET CAPITAL LETTER PEE
+10412; C; 1043A; # DESERET CAPITAL LETTER BEE
+10413; C; 1043B; # DESERET CAPITAL LETTER TEE
+10414; C; 1043C; # DESERET CAPITAL LETTER DEE
+10415; C; 1043D; # DESERET CAPITAL LETTER CHEE
+10416; C; 1043E; # DESERET CAPITAL LETTER JEE
+10417; C; 1043F; # DESERET CAPITAL LETTER KAY
+10418; C; 10440; # DESERET CAPITAL LETTER GAY
+10419; C; 10441; # DESERET CAPITAL LETTER EF
+1041A; C; 10442; # DESERET CAPITAL LETTER VEE
+1041B; C; 10443; # DESERET CAPITAL LETTER ETH
+1041C; C; 10444; # DESERET CAPITAL LETTER THEE
+1041D; C; 10445; # DESERET CAPITAL LETTER ES
+1041E; C; 10446; # DESERET CAPITAL LETTER ZEE
+1041F; C; 10447; # DESERET CAPITAL LETTER ESH
+10420; C; 10448; # DESERET CAPITAL LETTER ZHEE
+10421; C; 10449; # DESERET CAPITAL LETTER ER
+10422; C; 1044A; # DESERET CAPITAL LETTER EL
+10423; C; 1044B; # DESERET CAPITAL LETTER EM
+10424; C; 1044C; # DESERET CAPITAL LETTER EN
+10425; C; 1044D; # DESERET CAPITAL LETTER ENG
+10426; C; 1044E; # DESERET CAPITAL LETTER OI
+10427; C; 1044F; # DESERET CAPITAL LETTER EW
+104B0; C; 104D8; # OSAGE CAPITAL LETTER A
+104B1; C; 104D9; # OSAGE CAPITAL LETTER AI
+104B2; C; 104DA; # OSAGE CAPITAL LETTER AIN
+104B3; C; 104DB; # OSAGE CAPITAL LETTER AH
+104B4; C; 104DC; # OSAGE CAPITAL LETTER BRA
+104B5; C; 104DD; # OSAGE CAPITAL LETTER CHA
+104B6; C; 104DE; # OSAGE CAPITAL LETTER EHCHA
+104B7; C; 104DF; # OSAGE CAPITAL LETTER E
+104B8; C; 104E0; # OSAGE CAPITAL LETTER EIN
+104B9; C; 104E1; # OSAGE CAPITAL LETTER HA
+104BA; C; 104E2; # OSAGE CAPITAL LETTER HYA
+104BB; C; 104E3; # OSAGE CAPITAL LETTER I
+104BC; C; 104E4; # OSAGE CAPITAL LETTER KA
+104BD; C; 104E5; # OSAGE CAPITAL LETTER EHKA
+104BE; C; 104E6; # OSAGE CAPITAL LETTER KYA
+104BF; C; 104E7; # OSAGE CAPITAL LETTER LA
+104C0; C; 104E8; # OSAGE CAPITAL LETTER MA
+104C1; C; 104E9; # OSAGE CAPITAL LETTER NA
+104C2; C; 104EA; # OSAGE CAPITAL LETTER O
+104C3; C; 104EB; # OSAGE CAPITAL LETTER OIN
+104C4; C; 104EC; # OSAGE CAPITAL LETTER PA
+104C5; C; 104ED; # OSAGE CAPITAL LETTER EHPA
+104C6; C; 104EE; # OSAGE CAPITAL LETTER SA
+104C7; C; 104EF; # OSAGE CAPITAL LETTER SHA
+104C8; C; 104F0; # OSAGE CAPITAL LETTER TA
+104C9; C; 104F1; # OSAGE CAPITAL LETTER EHTA
+104CA; C; 104F2; # OSAGE CAPITAL LETTER TSA
+104CB; C; 104F3; # OSAGE CAPITAL LETTER EHTSA
+104CC; C; 104F4; # OSAGE CAPITAL LETTER TSHA
+104CD; C; 104F5; # OSAGE CAPITAL LETTER DHA
+104CE; C; 104F6; # OSAGE CAPITAL LETTER U
+104CF; C; 104F7; # OSAGE CAPITAL LETTER WA
+104D0; C; 104F8; # OSAGE CAPITAL LETTER KHA
+104D1; C; 104F9; # OSAGE CAPITAL LETTER GHA
+104D2; C; 104FA; # OSAGE CAPITAL LETTER ZA
+104D3; C; 104FB; # OSAGE CAPITAL LETTER ZHA
+10C80; C; 10CC0; # OLD HUNGARIAN CAPITAL LETTER A
+10C81; C; 10CC1; # OLD HUNGARIAN CAPITAL LETTER AA
+10C82; C; 10CC2; # OLD HUNGARIAN CAPITAL LETTER EB
+10C83; C; 10CC3; # OLD HUNGARIAN CAPITAL LETTER AMB
+10C84; C; 10CC4; # OLD HUNGARIAN CAPITAL LETTER EC
+10C85; C; 10CC5; # OLD HUNGARIAN CAPITAL LETTER ENC
+10C86; C; 10CC6; # OLD HUNGARIAN CAPITAL LETTER ECS
+10C87; C; 10CC7; # OLD HUNGARIAN CAPITAL LETTER ED
+10C88; C; 10CC8; # OLD HUNGARIAN CAPITAL LETTER AND
+10C89; C; 10CC9; # OLD HUNGARIAN CAPITAL LETTER E
+10C8A; C; 10CCA; # OLD HUNGARIAN CAPITAL LETTER CLOSE E
+10C8B; C; 10CCB; # OLD HUNGARIAN CAPITAL LETTER EE
+10C8C; C; 10CCC; # OLD HUNGARIAN CAPITAL LETTER EF
+10C8D; C; 10CCD; # OLD HUNGARIAN CAPITAL LETTER EG
+10C8E; C; 10CCE; # OLD HUNGARIAN CAPITAL LETTER EGY
+10C8F; C; 10CCF; # OLD HUNGARIAN CAPITAL LETTER EH
+10C90; C; 10CD0; # OLD HUNGARIAN CAPITAL LETTER I
+10C91; C; 10CD1; # OLD HUNGARIAN CAPITAL LETTER II
+10C92; C; 10CD2; # OLD HUNGARIAN CAPITAL LETTER EJ
+10C93; C; 10CD3; # OLD HUNGARIAN CAPITAL LETTER EK
+10C94; C; 10CD4; # OLD HUNGARIAN CAPITAL LETTER AK
+10C95; C; 10CD5; # OLD HUNGARIAN CAPITAL LETTER UNK
+10C96; C; 10CD6; # OLD HUNGARIAN CAPITAL LETTER EL
+10C97; C; 10CD7; # OLD HUNGARIAN CAPITAL LETTER ELY
+10C98; C; 10CD8; # OLD HUNGARIAN CAPITAL LETTER EM
+10C99; C; 10CD9; # OLD HUNGARIAN CAPITAL LETTER EN
+10C9A; C; 10CDA; # OLD HUNGARIAN CAPITAL LETTER ENY
+10C9B; C; 10CDB; # OLD HUNGARIAN CAPITAL LETTER O
+10C9C; C; 10CDC; # OLD HUNGARIAN CAPITAL LETTER OO
+10C9D; C; 10CDD; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE
+10C9E; C; 10CDE; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE
+10C9F; C; 10CDF; # OLD HUNGARIAN CAPITAL LETTER OEE
+10CA0; C; 10CE0; # OLD HUNGARIAN CAPITAL LETTER EP
+10CA1; C; 10CE1; # OLD HUNGARIAN CAPITAL LETTER EMP
+10CA2; C; 10CE2; # OLD HUNGARIAN CAPITAL LETTER ER
+10CA3; C; 10CE3; # OLD HUNGARIAN CAPITAL LETTER SHORT ER
+10CA4; C; 10CE4; # OLD HUNGARIAN CAPITAL LETTER ES
+10CA5; C; 10CE5; # OLD HUNGARIAN CAPITAL LETTER ESZ
+10CA6; C; 10CE6; # OLD HUNGARIAN CAPITAL LETTER ET
+10CA7; C; 10CE7; # OLD HUNGARIAN CAPITAL LETTER ENT
+10CA8; C; 10CE8; # OLD HUNGARIAN CAPITAL LETTER ETY
+10CA9; C; 10CE9; # OLD HUNGARIAN CAPITAL LETTER ECH
+10CAA; C; 10CEA; # OLD HUNGARIAN CAPITAL LETTER U
+10CAB; C; 10CEB; # OLD HUNGARIAN CAPITAL LETTER UU
+10CAC; C; 10CEC; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE
+10CAD; C; 10CED; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE
+10CAE; C; 10CEE; # OLD HUNGARIAN CAPITAL LETTER EV
+10CAF; C; 10CEF; # OLD HUNGARIAN CAPITAL LETTER EZ
+10CB0; C; 10CF0; # OLD HUNGARIAN CAPITAL LETTER EZS
+10CB1; C; 10CF1; # OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN
+10CB2; C; 10CF2; # OLD HUNGARIAN CAPITAL LETTER US
+118A0; C; 118C0; # WARANG CITI CAPITAL LETTER NGAA
+118A1; C; 118C1; # WARANG CITI CAPITAL LETTER A
+118A2; C; 118C2; # WARANG CITI CAPITAL LETTER WI
+118A3; C; 118C3; # WARANG CITI CAPITAL LETTER YU
+118A4; C; 118C4; # WARANG CITI CAPITAL LETTER YA
+118A5; C; 118C5; # WARANG CITI CAPITAL LETTER YO
+118A6; C; 118C6; # WARANG CITI CAPITAL LETTER II
+118A7; C; 118C7; # WARANG CITI CAPITAL LETTER UU
+118A8; C; 118C8; # WARANG CITI CAPITAL LETTER E
+118A9; C; 118C9; # WARANG CITI CAPITAL LETTER O
+118AA; C; 118CA; # WARANG CITI CAPITAL LETTER ANG
+118AB; C; 118CB; # WARANG CITI CAPITAL LETTER GA
+118AC; C; 118CC; # WARANG CITI CAPITAL LETTER KO
+118AD; C; 118CD; # WARANG CITI CAPITAL LETTER ENY
+118AE; C; 118CE; # WARANG CITI CAPITAL LETTER YUJ
+118AF; C; 118CF; # WARANG CITI CAPITAL LETTER UC
+118B0; C; 118D0; # WARANG CITI CAPITAL LETTER ENN
+118B1; C; 118D1; # WARANG CITI CAPITAL LETTER ODD
+118B2; C; 118D2; # WARANG CITI CAPITAL LETTER TTE
+118B3; C; 118D3; # WARANG CITI CAPITAL LETTER NUNG
+118B4; C; 118D4; # WARANG CITI CAPITAL LETTER DA
+118B5; C; 118D5; # WARANG CITI CAPITAL LETTER AT
+118B6; C; 118D6; # WARANG CITI CAPITAL LETTER AM
+118B7; C; 118D7; # WARANG CITI CAPITAL LETTER BU
+118B8; C; 118D8; # WARANG CITI CAPITAL LETTER PU
+118B9; C; 118D9; # WARANG CITI CAPITAL LETTER HIYO
+118BA; C; 118DA; # WARANG CITI CAPITAL LETTER HOLO
+118BB; C; 118DB; # WARANG CITI CAPITAL LETTER HORR
+118BC; C; 118DC; # WARANG CITI CAPITAL LETTER HAR
+118BD; C; 118DD; # WARANG CITI CAPITAL LETTER SSUU
+118BE; C; 118DE; # WARANG CITI CAPITAL LETTER SII
+118BF; C; 118DF; # WARANG CITI CAPITAL LETTER VIYO
+1E900; C; 1E922; # ADLAM CAPITAL LETTER ALIF
+1E901; C; 1E923; # ADLAM CAPITAL LETTER DAALI
+1E902; C; 1E924; # ADLAM CAPITAL LETTER LAAM
+1E903; C; 1E925; # ADLAM CAPITAL LETTER MIIM
+1E904; C; 1E926; # ADLAM CAPITAL LETTER BA
+1E905; C; 1E927; # ADLAM CAPITAL LETTER SINNYIIYHE
+1E906; C; 1E928; # ADLAM CAPITAL LETTER PE
+1E907; C; 1E929; # ADLAM CAPITAL LETTER BHE
+1E908; C; 1E92A; # ADLAM CAPITAL LETTER RA
+1E909; C; 1E92B; # ADLAM CAPITAL LETTER E
+1E90A; C; 1E92C; # ADLAM CAPITAL LETTER FA
+1E90B; C; 1E92D; # ADLAM CAPITAL LETTER I
+1E90C; C; 1E92E; # ADLAM CAPITAL LETTER O
+1E90D; C; 1E92F; # ADLAM CAPITAL LETTER DHA
+1E90E; C; 1E930; # ADLAM CAPITAL LETTER YHE
+1E90F; C; 1E931; # ADLAM CAPITAL LETTER WAW
+1E910; C; 1E932; # ADLAM CAPITAL LETTER NUN
+1E911; C; 1E933; # ADLAM CAPITAL LETTER KAF
+1E912; C; 1E934; # ADLAM CAPITAL LETTER YA
+1E913; C; 1E935; # ADLAM CAPITAL LETTER U
+1E914; C; 1E936; # ADLAM CAPITAL LETTER JIIM
+1E915; C; 1E937; # ADLAM CAPITAL LETTER CHI
+1E916; C; 1E938; # ADLAM CAPITAL LETTER HA
+1E917; C; 1E939; # ADLAM CAPITAL LETTER QAAF
+1E918; C; 1E93A; # ADLAM CAPITAL LETTER GA
+1E919; C; 1E93B; # ADLAM CAPITAL LETTER NYA
+1E91A; C; 1E93C; # ADLAM CAPITAL LETTER TU
+1E91B; C; 1E93D; # ADLAM CAPITAL LETTER NHA
+1E91C; C; 1E93E; # ADLAM CAPITAL LETTER VA
+1E91D; C; 1E93F; # ADLAM CAPITAL LETTER KHA
+1E91E; C; 1E940; # ADLAM CAPITAL LETTER GBE
+1E91F; C; 1E941; # ADLAM CAPITAL LETTER ZAL
+1E920; C; 1E942; # ADLAM CAPITAL LETTER KPO
+1E921; C; 1E943; # ADLAM CAPITAL LETTER SHA
+#
+# EOF
diff --git a/lib/stdlib/uc_spec/CompositionExclusions.txt b/lib/stdlib/uc_spec/CompositionExclusions.txt
new file mode 100644
index 0000000000..1999ed1328
--- /dev/null
+++ b/lib/stdlib/uc_spec/CompositionExclusions.txt
@@ -0,0 +1,208 @@
+# CompositionExclusions-9.0.0.txt
+# Date: 2016-01-21, 22:00:00 GMT [KW, LI]
+# © 2016 Unicode®, Inc.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see http://www.unicode.org/reports/tr44/
+#
+# This file lists the characters for the Composition Exclusion Table
+# defined in UAX #15, Unicode Normalization Forms.
+#
+# This file is a normative contributory data file in the
+# Unicode Character Database.
+#
+# For more information, see
+# http://www.unicode.org/unicode/reports/tr15/#Primary_Exclusion_List_Table
+#
+# For a full derivation of composition exclusions, see the derived property
+# Full_Composition_Exclusion in DerivedNormalizationProps.txt
+#
+
+# ================================================
+# (1) Script Specifics
+#
+# This list of characters cannot be derived from the UnicodeData.txt file.
+# ================================================
+
+0958 # DEVANAGARI LETTER QA
+0959 # DEVANAGARI LETTER KHHA
+095A # DEVANAGARI LETTER GHHA
+095B # DEVANAGARI LETTER ZA
+095C # DEVANAGARI LETTER DDDHA
+095D # DEVANAGARI LETTER RHA
+095E # DEVANAGARI LETTER FA
+095F # DEVANAGARI LETTER YYA
+09DC # BENGALI LETTER RRA
+09DD # BENGALI LETTER RHA
+09DF # BENGALI LETTER YYA
+0A33 # GURMUKHI LETTER LLA
+0A36 # GURMUKHI LETTER SHA
+0A59 # GURMUKHI LETTER KHHA
+0A5A # GURMUKHI LETTER GHHA
+0A5B # GURMUKHI LETTER ZA
+0A5E # GURMUKHI LETTER FA
+0B5C # ORIYA LETTER RRA
+0B5D # ORIYA LETTER RHA
+0F43 # TIBETAN LETTER GHA
+0F4D # TIBETAN LETTER DDHA
+0F52 # TIBETAN LETTER DHA
+0F57 # TIBETAN LETTER BHA
+0F5C # TIBETAN LETTER DZHA
+0F69 # TIBETAN LETTER KSSA
+0F76 # TIBETAN VOWEL SIGN VOCALIC R
+0F78 # TIBETAN VOWEL SIGN VOCALIC L
+0F93 # TIBETAN SUBJOINED LETTER GHA
+0F9D # TIBETAN SUBJOINED LETTER DDHA
+0FA2 # TIBETAN SUBJOINED LETTER DHA
+0FA7 # TIBETAN SUBJOINED LETTER BHA
+0FAC # TIBETAN SUBJOINED LETTER DZHA
+0FB9 # TIBETAN SUBJOINED LETTER KSSA
+FB1D # HEBREW LETTER YOD WITH HIRIQ
+FB1F # HEBREW LIGATURE YIDDISH YOD YOD PATAH
+FB2A # HEBREW LETTER SHIN WITH SHIN DOT
+FB2B # HEBREW LETTER SHIN WITH SIN DOT
+FB2C # HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT
+FB2D # HEBREW LETTER SHIN WITH DAGESH AND SIN DOT
+FB2E # HEBREW LETTER ALEF WITH PATAH
+FB2F # HEBREW LETTER ALEF WITH QAMATS
+FB30 # HEBREW LETTER ALEF WITH MAPIQ
+FB31 # HEBREW LETTER BET WITH DAGESH
+FB32 # HEBREW LETTER GIMEL WITH DAGESH
+FB33 # HEBREW LETTER DALET WITH DAGESH
+FB34 # HEBREW LETTER HE WITH MAPIQ
+FB35 # HEBREW LETTER VAV WITH DAGESH
+FB36 # HEBREW LETTER ZAYIN WITH DAGESH
+FB38 # HEBREW LETTER TET WITH DAGESH
+FB39 # HEBREW LETTER YOD WITH DAGESH
+FB3A # HEBREW LETTER FINAL KAF WITH DAGESH
+FB3B # HEBREW LETTER KAF WITH DAGESH
+FB3C # HEBREW LETTER LAMED WITH DAGESH
+FB3E # HEBREW LETTER MEM WITH DAGESH
+FB40 # HEBREW LETTER NUN WITH DAGESH
+FB41 # HEBREW LETTER SAMEKH WITH DAGESH
+FB43 # HEBREW LETTER FINAL PE WITH DAGESH
+FB44 # HEBREW LETTER PE WITH DAGESH
+FB46 # HEBREW LETTER TSADI WITH DAGESH
+FB47 # HEBREW LETTER QOF WITH DAGESH
+FB48 # HEBREW LETTER RESH WITH DAGESH
+FB49 # HEBREW LETTER SHIN WITH DAGESH
+FB4A # HEBREW LETTER TAV WITH DAGESH
+FB4B # HEBREW LETTER VAV WITH HOLAM
+FB4C # HEBREW LETTER BET WITH RAFE
+FB4D # HEBREW LETTER KAF WITH RAFE
+FB4E # HEBREW LETTER PE WITH RAFE
+
+# Total code points: 67
+
+# ================================================
+# (2) Post Composition Version precomposed characters
+#
+# These characters cannot be derived solely from the UnicodeData.txt file
+# in this version of Unicode.
+#
+# Note that characters added to the standard after the
+# Composition Version and which have canonical decomposition mappings
+# are not automatically added to this list of Post Composition
+# Version precomposed characters.
+# ================================================
+
+2ADC # FORKING
+1D15E # MUSICAL SYMBOL HALF NOTE
+1D15F # MUSICAL SYMBOL QUARTER NOTE
+1D160 # MUSICAL SYMBOL EIGHTH NOTE
+1D161 # MUSICAL SYMBOL SIXTEENTH NOTE
+1D162 # MUSICAL SYMBOL THIRTY-SECOND NOTE
+1D163 # MUSICAL SYMBOL SIXTY-FOURTH NOTE
+1D164 # MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE
+1D1BB # MUSICAL SYMBOL MINIMA
+1D1BC # MUSICAL SYMBOL MINIMA BLACK
+1D1BD # MUSICAL SYMBOL SEMIMINIMA WHITE
+1D1BE # MUSICAL SYMBOL SEMIMINIMA BLACK
+1D1BF # MUSICAL SYMBOL FUSA WHITE
+1D1C0 # MUSICAL SYMBOL FUSA BLACK
+
+# Total code points: 14
+
+# ================================================
+# (3) Singleton Decompositions
+#
+# These characters can be derived from the UnicodeData.txt file
+# by including all canonically decomposable characters whose
+# canonical decomposition consists of a single character.
+#
+# These characters are simply quoted here for reference.
+# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt
+# ================================================
+
+# 0340..0341 [2] COMBINING GRAVE TONE MARK..COMBINING ACUTE TONE MARK
+# 0343 COMBINING GREEK KORONIS
+# 0374 GREEK NUMERAL SIGN
+# 037E GREEK QUESTION MARK
+# 0387 GREEK ANO TELEIA
+# 1F71 GREEK SMALL LETTER ALPHA WITH OXIA
+# 1F73 GREEK SMALL LETTER EPSILON WITH OXIA
+# 1F75 GREEK SMALL LETTER ETA WITH OXIA
+# 1F77 GREEK SMALL LETTER IOTA WITH OXIA
+# 1F79 GREEK SMALL LETTER OMICRON WITH OXIA
+# 1F7B GREEK SMALL LETTER UPSILON WITH OXIA
+# 1F7D GREEK SMALL LETTER OMEGA WITH OXIA
+# 1FBB GREEK CAPITAL LETTER ALPHA WITH OXIA
+# 1FBE GREEK PROSGEGRAMMENI
+# 1FC9 GREEK CAPITAL LETTER EPSILON WITH OXIA
+# 1FCB GREEK CAPITAL LETTER ETA WITH OXIA
+# 1FD3 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
+# 1FDB GREEK CAPITAL LETTER IOTA WITH OXIA
+# 1FE3 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
+# 1FEB GREEK CAPITAL LETTER UPSILON WITH OXIA
+# 1FEE..1FEF [2] GREEK DIALYTIKA AND OXIA..GREEK VARIA
+# 1FF9 GREEK CAPITAL LETTER OMICRON WITH OXIA
+# 1FFB GREEK CAPITAL LETTER OMEGA WITH OXIA
+# 1FFD GREEK OXIA
+# 2000..2001 [2] EN QUAD..EM QUAD
+# 2126 OHM SIGN
+# 212A..212B [2] KELVIN SIGN..ANGSTROM SIGN
+# 2329 LEFT-POINTING ANGLE BRACKET
+# 232A RIGHT-POINTING ANGLE BRACKET
+# F900..FA0D [270] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA0D
+# FA10 CJK COMPATIBILITY IDEOGRAPH-FA10
+# FA12 CJK COMPATIBILITY IDEOGRAPH-FA12
+# FA15..FA1E [10] CJK COMPATIBILITY IDEOGRAPH-FA15..CJK COMPATIBILITY IDEOGRAPH-FA1E
+# FA20 CJK COMPATIBILITY IDEOGRAPH-FA20
+# FA22 CJK COMPATIBILITY IDEOGRAPH-FA22
+# FA25..FA26 [2] CJK COMPATIBILITY IDEOGRAPH-FA25..CJK COMPATIBILITY IDEOGRAPH-FA26
+# FA2A..FA6D [68] CJK COMPATIBILITY IDEOGRAPH-FA2A..CJK COMPATIBILITY IDEOGRAPH-FA6D
+# FA70..FAD9 [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9
+# 2F800..2FA1D [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
+
+# Total code points: 1035
+
+# ================================================
+# (4) Non-Starter Decompositions
+#
+# These characters can be derived from the UnicodeData.txt file
+# by including each expanding canonical decomposition
+# (i.e., those which canonically decompose to a sequence
+# of characters instead of a single character), such that:
+#
+# A. The character is not a Starter.
+#
+# OR (inclusive)
+#
+# B. The character's canonical decomposition begins
+# with a character that is not a Starter.
+#
+# Note that a "Starter" is any character with a zero combining class.
+#
+# These characters are simply quoted here for reference.
+# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt
+# ================================================
+
+# 0344 COMBINING GREEK DIALYTIKA TONOS
+# 0F73 TIBETAN VOWEL SIGN II
+# 0F75 TIBETAN VOWEL SIGN UU
+# 0F81 TIBETAN VOWEL SIGN REVERSED II
+
+# Total code points: 4
+
+# EOF
diff --git a/lib/stdlib/uc_spec/GraphemeBreakProperty.txt b/lib/stdlib/uc_spec/GraphemeBreakProperty.txt
new file mode 100644
index 0000000000..c5e94a3762
--- /dev/null
+++ b/lib/stdlib/uc_spec/GraphemeBreakProperty.txt
@@ -0,0 +1,1431 @@
+# GraphemeBreakProperty-9.0.0.txt
+# Date: 2016-06-03, 22:23:55 GMT
+# © 2016 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see http://www.unicode.org/reports/tr44/
+
+# ================================================
+
+# Property: Grapheme_Cluster_Break
+
+# All code points not explicitly listed for Grapheme_Cluster_Break
+# have the value Other (XX).
+
+# @missing: 0000..10FFFF; Other
+
+# ================================================
+
+0600..0605 ; Prepend # Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE
+06DD ; Prepend # Cf ARABIC END OF AYAH
+070F ; Prepend # Cf SYRIAC ABBREVIATION MARK
+08E2 ; Prepend # Cf ARABIC DISPUTED END OF AYAH
+0D4E ; Prepend # Lo MALAYALAM LETTER DOT REPH
+110BD ; Prepend # Cf KAITHI NUMBER SIGN
+111C2..111C3 ; Prepend # Lo [2] SHARADA SIGN JIHVAMULIYA..SHARADA SIGN UPADHMANIYA
+
+# Total code points: 13
+
+# ================================================
+
+000D ; CR # Cc <control-000D>
+
+# Total code points: 1
+
+# ================================================
+
+000A ; LF # Cc <control-000A>
+
+# Total code points: 1
+
+# ================================================
+
+0000..0009 ; Control # Cc [10] <control-0000>..<control-0009>
+000B..000C ; Control # Cc [2] <control-000B>..<control-000C>
+000E..001F ; Control # Cc [18] <control-000E>..<control-001F>
+007F..009F ; Control # Cc [33] <control-007F>..<control-009F>
+00AD ; Control # Cf SOFT HYPHEN
+061C ; Control # Cf ARABIC LETTER MARK
+180E ; Control # Cf MONGOLIAN VOWEL SEPARATOR
+200B ; Control # Cf ZERO WIDTH SPACE
+200E..200F ; Control # Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK
+2028 ; Control # Zl LINE SEPARATOR
+2029 ; Control # Zp PARAGRAPH SEPARATOR
+202A..202E ; Control # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
+2060..2064 ; Control # Cf [5] WORD JOINER..INVISIBLE PLUS
+2065 ; Control # Cn <reserved-2065>
+2066..206F ; Control # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
+D800..DFFF ; Control # Cs [2048] <surrogate-D800>..<surrogate-DFFF>
+FEFF ; Control # Cf ZERO WIDTH NO-BREAK SPACE
+FFF0..FFF8 ; Control # Cn [9] <reserved-FFF0>..<reserved-FFF8>
+FFF9..FFFB ; Control # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
+1BCA0..1BCA3 ; Control # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP
+1D173..1D17A ; Control # Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
+E0000 ; Control # Cn <reserved-E0000>
+E0001 ; Control # Cf LANGUAGE TAG
+E0002..E001F ; Control # Cn [30] <reserved-E0002>..<reserved-E001F>
+E0080..E00FF ; Control # Cn [128] <reserved-E0080>..<reserved-E00FF>
+E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF>
+
+# Total code points: 5925
+
+# ================================================
+
+0300..036F ; Extend # Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X
+0483..0487 ; Extend # Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
+0488..0489 ; Extend # Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN
+0591..05BD ; Extend # Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG
+05BF ; Extend # Mn HEBREW POINT RAFE
+05C1..05C2 ; Extend # Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
+05C4..05C5 ; Extend # Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT
+05C7 ; Extend # Mn HEBREW POINT QAMATS QATAN
+0610..061A ; Extend # Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA
+064B..065F ; Extend # Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW
+0670 ; Extend # Mn ARABIC LETTER SUPERSCRIPT ALEF
+06D6..06DC ; Extend # Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
+06DF..06E4 ; Extend # Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA
+06E7..06E8 ; Extend # Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
+06EA..06ED ; Extend # Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM
+0711 ; Extend # Mn SYRIAC LETTER SUPERSCRIPT ALAPH
+0730..074A ; Extend # Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH
+07A6..07B0 ; Extend # Mn [11] THAANA ABAFILI..THAANA SUKUN
+07EB..07F3 ; Extend # Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE
+0816..0819 ; Extend # Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH
+081B..0823 ; Extend # Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A
+0825..0827 ; Extend # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U
+0829..082D ; Extend # Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA
+0859..085B ; Extend # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK
+08D4..08E1 ; Extend # Mn [14] ARABIC SMALL HIGH WORD AR-RUB..ARABIC SMALL HIGH SIGN SAFHA
+08E3..0902 ; Extend # Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA
+093A ; Extend # Mn DEVANAGARI VOWEL SIGN OE
+093C ; Extend # Mn DEVANAGARI SIGN NUKTA
+0941..0948 ; Extend # Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
+094D ; Extend # Mn DEVANAGARI SIGN VIRAMA
+0951..0957 ; Extend # Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE
+0962..0963 ; Extend # Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
+0981 ; Extend # Mn BENGALI SIGN CANDRABINDU
+09BC ; Extend # Mn BENGALI SIGN NUKTA
+09BE ; Extend # Mc BENGALI VOWEL SIGN AA
+09C1..09C4 ; Extend # Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR
+09CD ; Extend # Mn BENGALI SIGN VIRAMA
+09D7 ; Extend # Mc BENGALI AU LENGTH MARK
+09E2..09E3 ; Extend # Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
+0A01..0A02 ; Extend # Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI
+0A3C ; Extend # Mn GURMUKHI SIGN NUKTA
+0A41..0A42 ; Extend # Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU
+0A47..0A48 ; Extend # Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
+0A4B..0A4D ; Extend # Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA
+0A51 ; Extend # Mn GURMUKHI SIGN UDAAT
+0A70..0A71 ; Extend # Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK
+0A75 ; Extend # Mn GURMUKHI SIGN YAKASH
+0A81..0A82 ; Extend # Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA
+0ABC ; Extend # Mn GUJARATI SIGN NUKTA
+0AC1..0AC5 ; Extend # Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E
+0AC7..0AC8 ; Extend # Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI
+0ACD ; Extend # Mn GUJARATI SIGN VIRAMA
+0AE2..0AE3 ; Extend # Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL
+0B01 ; Extend # Mn ORIYA SIGN CANDRABINDU
+0B3C ; Extend # Mn ORIYA SIGN NUKTA
+0B3E ; Extend # Mc ORIYA VOWEL SIGN AA
+0B3F ; Extend # Mn ORIYA VOWEL SIGN I
+0B41..0B44 ; Extend # Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
+0B4D ; Extend # Mn ORIYA SIGN VIRAMA
+0B56 ; Extend # Mn ORIYA AI LENGTH MARK
+0B57 ; Extend # Mc ORIYA AU LENGTH MARK
+0B62..0B63 ; Extend # Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
+0B82 ; Extend # Mn TAMIL SIGN ANUSVARA
+0BBE ; Extend # Mc TAMIL VOWEL SIGN AA
+0BC0 ; Extend # Mn TAMIL VOWEL SIGN II
+0BCD ; Extend # Mn TAMIL SIGN VIRAMA
+0BD7 ; Extend # Mc TAMIL AU LENGTH MARK
+0C00 ; Extend # Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE
+0C3E..0C40 ; Extend # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II
+0C46..0C48 ; Extend # Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
+0C4A..0C4D ; Extend # Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA
+0C55..0C56 ; Extend # Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
+0C62..0C63 ; Extend # Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL
+0C81 ; Extend # Mn KANNADA SIGN CANDRABINDU
+0CBC ; Extend # Mn KANNADA SIGN NUKTA
+0CBF ; Extend # Mn KANNADA VOWEL SIGN I
+0CC2 ; Extend # Mc KANNADA VOWEL SIGN UU
+0CC6 ; Extend # Mn KANNADA VOWEL SIGN E
+0CCC..0CCD ; Extend # Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA
+0CD5..0CD6 ; Extend # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
+0CE2..0CE3 ; Extend # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
+0D01 ; Extend # Mn MALAYALAM SIGN CANDRABINDU
+0D3E ; Extend # Mc MALAYALAM VOWEL SIGN AA
+0D41..0D44 ; Extend # Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
+0D4D ; Extend # Mn MALAYALAM SIGN VIRAMA
+0D57 ; Extend # Mc MALAYALAM AU LENGTH MARK
+0D62..0D63 ; Extend # Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
+0DCA ; Extend # Mn SINHALA SIGN AL-LAKUNA
+0DCF ; Extend # Mc SINHALA VOWEL SIGN AELA-PILLA
+0DD2..0DD4 ; Extend # Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
+0DD6 ; Extend # Mn SINHALA VOWEL SIGN DIGA PAA-PILLA
+0DDF ; Extend # Mc SINHALA VOWEL SIGN GAYANUKITTA
+0E31 ; Extend # Mn THAI CHARACTER MAI HAN-AKAT
+0E34..0E3A ; Extend # Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
+0E47..0E4E ; Extend # Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN
+0EB1 ; Extend # Mn LAO VOWEL SIGN MAI KAN
+0EB4..0EB9 ; Extend # Mn [6] LAO VOWEL SIGN I..LAO VOWEL SIGN UU
+0EBB..0EBC ; Extend # Mn [2] LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO
+0EC8..0ECD ; Extend # Mn [6] LAO TONE MAI EK..LAO NIGGAHITA
+0F18..0F19 ; Extend # Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
+0F35 ; Extend # Mn TIBETAN MARK NGAS BZUNG NYI ZLA
+0F37 ; Extend # Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS
+0F39 ; Extend # Mn TIBETAN MARK TSA -PHRU
+0F71..0F7E ; Extend # Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO
+0F80..0F84 ; Extend # Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA
+0F86..0F87 ; Extend # Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
+0F8D..0F97 ; Extend # Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA
+0F99..0FBC ; Extend # Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
+0FC6 ; Extend # Mn TIBETAN SYMBOL PADMA GDAN
+102D..1030 ; Extend # Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU
+1032..1037 ; Extend # Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW
+1039..103A ; Extend # Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT
+103D..103E ; Extend # Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA
+1058..1059 ; Extend # Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL
+105E..1060 ; Extend # Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA
+1071..1074 ; Extend # Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE
+1082 ; Extend # Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA
+1085..1086 ; Extend # Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y
+108D ; Extend # Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE
+109D ; Extend # Mn MYANMAR VOWEL SIGN AITON AI
+135D..135F ; Extend # Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK
+1712..1714 ; Extend # Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA
+1732..1734 ; Extend # Mn [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD
+1752..1753 ; Extend # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U
+1772..1773 ; Extend # Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U
+17B4..17B5 ; Extend # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
+17B7..17BD ; Extend # Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA
+17C6 ; Extend # Mn KHMER SIGN NIKAHIT
+17C9..17D3 ; Extend # Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT
+17DD ; Extend # Mn KHMER SIGN ATTHACAN
+180B..180D ; Extend # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
+1885..1886 ; Extend # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA
+18A9 ; Extend # Mn MONGOLIAN LETTER ALI GALI DAGALGA
+1920..1922 ; Extend # Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U
+1927..1928 ; Extend # Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O
+1932 ; Extend # Mn LIMBU SMALL LETTER ANUSVARA
+1939..193B ; Extend # Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I
+1A17..1A18 ; Extend # Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
+1A1B ; Extend # Mn BUGINESE VOWEL SIGN AE
+1A56 ; Extend # Mn TAI THAM CONSONANT SIGN MEDIAL LA
+1A58..1A5E ; Extend # Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA
+1A60 ; Extend # Mn TAI THAM SIGN SAKOT
+1A62 ; Extend # Mn TAI THAM VOWEL SIGN MAI SAT
+1A65..1A6C ; Extend # Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW
+1A73..1A7C ; Extend # Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN
+1A7F ; Extend # Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT
+1AB0..1ABD ; Extend # Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
+1ABE ; Extend # Me COMBINING PARENTHESES OVERLAY
+1B00..1B03 ; Extend # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
+1B34 ; Extend # Mn BALINESE SIGN REREKAN
+1B36..1B3A ; Extend # Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
+1B3C ; Extend # Mn BALINESE VOWEL SIGN LA LENGA
+1B42 ; Extend # Mn BALINESE VOWEL SIGN PEPET
+1B6B..1B73 ; Extend # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG
+1B80..1B81 ; Extend # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR
+1BA2..1BA5 ; Extend # Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU
+1BA8..1BA9 ; Extend # Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG
+1BAB..1BAD ; Extend # Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA
+1BE6 ; Extend # Mn BATAK SIGN TOMPI
+1BE8..1BE9 ; Extend # Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE
+1BED ; Extend # Mn BATAK VOWEL SIGN KARO O
+1BEF..1BF1 ; Extend # Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H
+1C2C..1C33 ; Extend # Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T
+1C36..1C37 ; Extend # Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA
+1CD0..1CD2 ; Extend # Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA
+1CD4..1CE0 ; Extend # Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA
+1CE2..1CE8 ; Extend # Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL
+1CED ; Extend # Mn VEDIC SIGN TIRYAK
+1CF4 ; Extend # Mn VEDIC TONE CANDRA ABOVE
+1CF8..1CF9 ; Extend # Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE
+1DC0..1DF5 ; Extend # Mn [54] COMBINING DOTTED GRAVE ACCENT..COMBINING UP TACK ABOVE
+1DFB..1DFF ; Extend # Mn [5] COMBINING DELETION MARK..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW
+200C ; Extend # Cf ZERO WIDTH NON-JOINER
+20D0..20DC ; Extend # Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE
+20DD..20E0 ; Extend # Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH
+20E1 ; Extend # Mn COMBINING LEFT RIGHT ARROW ABOVE
+20E2..20E4 ; Extend # Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE
+20E5..20F0 ; Extend # Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE
+2CEF..2CF1 ; Extend # Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS
+2D7F ; Extend # Mn TIFINAGH CONSONANT JOINER
+2DE0..2DFF ; Extend # Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS
+302A..302D ; Extend # Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK
+302E..302F ; Extend # Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK
+3099..309A ; Extend # Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+A66F ; Extend # Mn COMBINING CYRILLIC VZMET
+A670..A672 ; Extend # Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN
+A674..A67D ; Extend # Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK
+A69E..A69F ; Extend # Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E
+A6F0..A6F1 ; Extend # Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS
+A802 ; Extend # Mn SYLOTI NAGRI SIGN DVISVARA
+A806 ; Extend # Mn SYLOTI NAGRI SIGN HASANTA
+A80B ; Extend # Mn SYLOTI NAGRI SIGN ANUSVARA
+A825..A826 ; Extend # Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
+A8C4..A8C5 ; Extend # Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU
+A8E0..A8F1 ; Extend # Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA
+A926..A92D ; Extend # Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU
+A947..A951 ; Extend # Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R
+A980..A982 ; Extend # Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR
+A9B3 ; Extend # Mn JAVANESE SIGN CECAK TELU
+A9B6..A9B9 ; Extend # Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT
+A9BC ; Extend # Mn JAVANESE VOWEL SIGN PEPET
+A9E5 ; Extend # Mn MYANMAR SIGN SHAN SAW
+AA29..AA2E ; Extend # Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE
+AA31..AA32 ; Extend # Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE
+AA35..AA36 ; Extend # Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA
+AA43 ; Extend # Mn CHAM CONSONANT SIGN FINAL NG
+AA4C ; Extend # Mn CHAM CONSONANT SIGN FINAL M
+AA7C ; Extend # Mn MYANMAR SIGN TAI LAING TONE-2
+AAB0 ; Extend # Mn TAI VIET MAI KANG
+AAB2..AAB4 ; Extend # Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U
+AAB7..AAB8 ; Extend # Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA
+AABE..AABF ; Extend # Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK
+AAC1 ; Extend # Mn TAI VIET TONE MAI THO
+AAEC..AAED ; Extend # Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI
+AAF6 ; Extend # Mn MEETEI MAYEK VIRAMA
+ABE5 ; Extend # Mn MEETEI MAYEK VOWEL SIGN ANAP
+ABE8 ; Extend # Mn MEETEI MAYEK VOWEL SIGN UNAP
+ABED ; Extend # Mn MEETEI MAYEK APUN IYEK
+FB1E ; Extend # Mn HEBREW POINT JUDEO-SPANISH VARIKA
+FE00..FE0F ; Extend # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
+FE20..FE2F ; Extend # Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF
+FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+101FD ; Extend # Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE
+102E0 ; Extend # Mn COPTIC EPACT THOUSANDS MARK
+10376..1037A ; Extend # Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII
+10A01..10A03 ; Extend # Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R
+10A05..10A06 ; Extend # Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O
+10A0C..10A0F ; Extend # Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA
+10A38..10A3A ; Extend # Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW
+10A3F ; Extend # Mn KHAROSHTHI VIRAMA
+10AE5..10AE6 ; Extend # Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW
+11001 ; Extend # Mn BRAHMI SIGN ANUSVARA
+11038..11046 ; Extend # Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA
+1107F..11081 ; Extend # Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA
+110B3..110B6 ; Extend # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI
+110B9..110BA ; Extend # Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA
+11100..11102 ; Extend # Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA
+11127..1112B ; Extend # Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU
+1112D..11134 ; Extend # Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA
+11173 ; Extend # Mn MAHAJANI SIGN NUKTA
+11180..11181 ; Extend # Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA
+111B6..111BE ; Extend # Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O
+111CA..111CC ; Extend # Mn [3] SHARADA SIGN NUKTA..SHARADA EXTRA SHORT VOWEL MARK
+1122F..11231 ; Extend # Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI
+11234 ; Extend # Mn KHOJKI SIGN ANUSVARA
+11236..11237 ; Extend # Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
+1123E ; Extend # Mn KHOJKI SIGN SUKUN
+112DF ; Extend # Mn KHUDAWADI SIGN ANUSVARA
+112E3..112EA ; Extend # Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA
+11300..11301 ; Extend # Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU
+1133C ; Extend # Mn GRANTHA SIGN NUKTA
+1133E ; Extend # Mc GRANTHA VOWEL SIGN AA
+11340 ; Extend # Mn GRANTHA VOWEL SIGN II
+11357 ; Extend # Mc GRANTHA AU LENGTH MARK
+11366..1136C ; Extend # Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX
+11370..11374 ; Extend # Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA
+11438..1143F ; Extend # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI
+11442..11444 ; Extend # Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA
+11446 ; Extend # Mn NEWA SIGN NUKTA
+114B0 ; Extend # Mc TIRHUTA VOWEL SIGN AA
+114B3..114B8 ; Extend # Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL
+114BA ; Extend # Mn TIRHUTA VOWEL SIGN SHORT E
+114BD ; Extend # Mc TIRHUTA VOWEL SIGN SHORT O
+114BF..114C0 ; Extend # Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA
+114C2..114C3 ; Extend # Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA
+115AF ; Extend # Mc SIDDHAM VOWEL SIGN AA
+115B2..115B5 ; Extend # Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR
+115BC..115BD ; Extend # Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA
+115BF..115C0 ; Extend # Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA
+115DC..115DD ; Extend # Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU
+11633..1163A ; Extend # Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI
+1163D ; Extend # Mn MODI SIGN ANUSVARA
+1163F..11640 ; Extend # Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA
+116AB ; Extend # Mn TAKRI SIGN ANUSVARA
+116AD ; Extend # Mn TAKRI VOWEL SIGN AA
+116B0..116B5 ; Extend # Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU
+116B7 ; Extend # Mn TAKRI SIGN NUKTA
+1171D..1171F ; Extend # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA
+11722..11725 ; Extend # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU
+11727..1172B ; Extend # Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER
+11C30..11C36 ; Extend # Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L
+11C38..11C3D ; Extend # Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA
+11C3F ; Extend # Mn BHAIKSUKI SIGN VIRAMA
+11C92..11CA7 ; Extend # Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA
+11CAA..11CB0 ; Extend # Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA
+11CB2..11CB3 ; Extend # Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E
+11CB5..11CB6 ; Extend # Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU
+16AF0..16AF4 ; Extend # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE
+16B30..16B36 ; Extend # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM
+16F8F..16F92 ; Extend # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW
+1BC9D..1BC9E ; Extend # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK
+1D165 ; Extend # Mc MUSICAL SYMBOL COMBINING STEM
+1D167..1D169 ; Extend # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
+1D16E..1D172 ; Extend # Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5
+1D17B..1D182 ; Extend # Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE
+1D185..1D18B ; Extend # Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
+1D1AA..1D1AD ; Extend # Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
+1D242..1D244 ; Extend # Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
+1DA00..1DA36 ; Extend # Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN
+1DA3B..1DA6C ; Extend # Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT
+1DA75 ; Extend # Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS
+1DA84 ; Extend # Mn SIGNWRITING LOCATION HEAD NECK
+1DA9B..1DA9F ; Extend # Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6
+1DAA1..1DAAF ; Extend # Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16
+1E000..1E006 ; Extend # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE
+1E008..1E018 ; Extend # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU
+1E01B..1E021 ; Extend # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI
+1E023..1E024 ; Extend # Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS
+1E026..1E02A ; Extend # Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA
+1E8D0..1E8D6 ; Extend # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS
+1E944..1E94A ; Extend # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA
+E0020..E007F ; Extend # Cf [96] TAG SPACE..CANCEL TAG
+E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
+
+# Total code points: 1828
+
+# ================================================
+
+1F1E6..1F1FF ; Regional_Indicator # So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
+
+# Total code points: 26
+
+# ================================================
+
+0903 ; SpacingMark # Mc DEVANAGARI SIGN VISARGA
+093B ; SpacingMark # Mc DEVANAGARI VOWEL SIGN OOE
+093E..0940 ; SpacingMark # Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II
+0949..094C ; SpacingMark # Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU
+094E..094F ; SpacingMark # Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW
+0982..0983 ; SpacingMark # Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA
+09BF..09C0 ; SpacingMark # Mc [2] BENGALI VOWEL SIGN I..BENGALI VOWEL SIGN II
+09C7..09C8 ; SpacingMark # Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
+09CB..09CC ; SpacingMark # Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU
+0A03 ; SpacingMark # Mc GURMUKHI SIGN VISARGA
+0A3E..0A40 ; SpacingMark # Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II
+0A83 ; SpacingMark # Mc GUJARATI SIGN VISARGA
+0ABE..0AC0 ; SpacingMark # Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II
+0AC9 ; SpacingMark # Mc GUJARATI VOWEL SIGN CANDRA O
+0ACB..0ACC ; SpacingMark # Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU
+0B02..0B03 ; SpacingMark # Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA
+0B40 ; SpacingMark # Mc ORIYA VOWEL SIGN II
+0B47..0B48 ; SpacingMark # Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
+0B4B..0B4C ; SpacingMark # Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
+0BBF ; SpacingMark # Mc TAMIL VOWEL SIGN I
+0BC1..0BC2 ; SpacingMark # Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU
+0BC6..0BC8 ; SpacingMark # Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
+0BCA..0BCC ; SpacingMark # Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU
+0C01..0C03 ; SpacingMark # Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
+0C41..0C44 ; SpacingMark # Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR
+0C82..0C83 ; SpacingMark # Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
+0CBE ; SpacingMark # Mc KANNADA VOWEL SIGN AA
+0CC0..0CC1 ; SpacingMark # Mc [2] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN U
+0CC3..0CC4 ; SpacingMark # Mc [2] KANNADA VOWEL SIGN VOCALIC R..KANNADA VOWEL SIGN VOCALIC RR
+0CC7..0CC8 ; SpacingMark # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI
+0CCA..0CCB ; SpacingMark # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO
+0D02..0D03 ; SpacingMark # Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
+0D3F..0D40 ; SpacingMark # Mc [2] MALAYALAM VOWEL SIGN I..MALAYALAM VOWEL SIGN II
+0D46..0D48 ; SpacingMark # Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
+0D4A..0D4C ; SpacingMark # Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU
+0D82..0D83 ; SpacingMark # Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
+0DD0..0DD1 ; SpacingMark # Mc [2] SINHALA VOWEL SIGN KETTI AEDA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA
+0DD8..0DDE ; SpacingMark # Mc [7] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA
+0DF2..0DF3 ; SpacingMark # Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
+0E33 ; SpacingMark # Lo THAI CHARACTER SARA AM
+0EB3 ; SpacingMark # Lo LAO VOWEL SIGN AM
+0F3E..0F3F ; SpacingMark # Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
+0F7F ; SpacingMark # Mc TIBETAN SIGN RNAM BCAD
+1031 ; SpacingMark # Mc MYANMAR VOWEL SIGN E
+103B..103C ; SpacingMark # Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA
+1056..1057 ; SpacingMark # Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR
+1084 ; SpacingMark # Mc MYANMAR VOWEL SIGN SHAN E
+17B6 ; SpacingMark # Mc KHMER VOWEL SIGN AA
+17BE..17C5 ; SpacingMark # Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU
+17C7..17C8 ; SpacingMark # Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU
+1923..1926 ; SpacingMark # Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU
+1929..192B ; SpacingMark # Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
+1930..1931 ; SpacingMark # Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
+1933..1938 ; SpacingMark # Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
+1A19..1A1A ; SpacingMark # Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
+1A55 ; SpacingMark # Mc TAI THAM CONSONANT SIGN MEDIAL RA
+1A57 ; SpacingMark # Mc TAI THAM CONSONANT SIGN LA TANG LAI
+1A6D..1A72 ; SpacingMark # Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI
+1B04 ; SpacingMark # Mc BALINESE SIGN BISAH
+1B35 ; SpacingMark # Mc BALINESE VOWEL SIGN TEDUNG
+1B3B ; SpacingMark # Mc BALINESE VOWEL SIGN RA REPA TEDUNG
+1B3D..1B41 ; SpacingMark # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG
+1B43..1B44 ; SpacingMark # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG
+1B82 ; SpacingMark # Mc SUNDANESE SIGN PANGWISAD
+1BA1 ; SpacingMark # Mc SUNDANESE CONSONANT SIGN PAMINGKAL
+1BA6..1BA7 ; SpacingMark # Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG
+1BAA ; SpacingMark # Mc SUNDANESE SIGN PAMAAEH
+1BE7 ; SpacingMark # Mc BATAK VOWEL SIGN E
+1BEA..1BEC ; SpacingMark # Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O
+1BEE ; SpacingMark # Mc BATAK VOWEL SIGN U
+1BF2..1BF3 ; SpacingMark # Mc [2] BATAK PANGOLAT..BATAK PANONGONAN
+1C24..1C2B ; SpacingMark # Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU
+1C34..1C35 ; SpacingMark # Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG
+1CE1 ; SpacingMark # Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA
+1CF2..1CF3 ; SpacingMark # Mc [2] VEDIC SIGN ARDHAVISARGA..VEDIC SIGN ROTATED ARDHAVISARGA
+A823..A824 ; SpacingMark # Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
+A827 ; SpacingMark # Mc SYLOTI NAGRI VOWEL SIGN OO
+A880..A881 ; SpacingMark # Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
+A8B4..A8C3 ; SpacingMark # Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU
+A952..A953 ; SpacingMark # Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA
+A983 ; SpacingMark # Mc JAVANESE SIGN WIGNYAN
+A9B4..A9B5 ; SpacingMark # Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG
+A9BA..A9BB ; SpacingMark # Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE
+A9BD..A9C0 ; SpacingMark # Mc [4] JAVANESE CONSONANT SIGN KERET..JAVANESE PANGKON
+AA2F..AA30 ; SpacingMark # Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
+AA33..AA34 ; SpacingMark # Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA
+AA4D ; SpacingMark # Mc CHAM CONSONANT SIGN FINAL H
+AAEB ; SpacingMark # Mc MEETEI MAYEK VOWEL SIGN II
+AAEE..AAEF ; SpacingMark # Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU
+AAF5 ; SpacingMark # Mc MEETEI MAYEK VOWEL SIGN VISARGA
+ABE3..ABE4 ; SpacingMark # Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP
+ABE6..ABE7 ; SpacingMark # Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP
+ABE9..ABEA ; SpacingMark # Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG
+ABEC ; SpacingMark # Mc MEETEI MAYEK LUM IYEK
+11000 ; SpacingMark # Mc BRAHMI SIGN CANDRABINDU
+11002 ; SpacingMark # Mc BRAHMI SIGN VISARGA
+11082 ; SpacingMark # Mc KAITHI SIGN VISARGA
+110B0..110B2 ; SpacingMark # Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II
+110B7..110B8 ; SpacingMark # Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU
+1112C ; SpacingMark # Mc CHAKMA VOWEL SIGN E
+11182 ; SpacingMark # Mc SHARADA SIGN VISARGA
+111B3..111B5 ; SpacingMark # Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II
+111BF..111C0 ; SpacingMark # Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA
+1122C..1122E ; SpacingMark # Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II
+11232..11233 ; SpacingMark # Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU
+11235 ; SpacingMark # Mc KHOJKI SIGN VIRAMA
+112E0..112E2 ; SpacingMark # Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II
+11302..11303 ; SpacingMark # Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA
+1133F ; SpacingMark # Mc GRANTHA VOWEL SIGN I
+11341..11344 ; SpacingMark # Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR
+11347..11348 ; SpacingMark # Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI
+1134B..1134D ; SpacingMark # Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA
+11362..11363 ; SpacingMark # Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL
+11435..11437 ; SpacingMark # Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II
+11440..11441 ; SpacingMark # Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU
+11445 ; SpacingMark # Mc NEWA SIGN VISARGA
+114B1..114B2 ; SpacingMark # Mc [2] TIRHUTA VOWEL SIGN I..TIRHUTA VOWEL SIGN II
+114B9 ; SpacingMark # Mc TIRHUTA VOWEL SIGN E
+114BB..114BC ; SpacingMark # Mc [2] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN O
+114BE ; SpacingMark # Mc TIRHUTA VOWEL SIGN AU
+114C1 ; SpacingMark # Mc TIRHUTA SIGN VISARGA
+115B0..115B1 ; SpacingMark # Mc [2] SIDDHAM VOWEL SIGN I..SIDDHAM VOWEL SIGN II
+115B8..115BB ; SpacingMark # Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU
+115BE ; SpacingMark # Mc SIDDHAM SIGN VISARGA
+11630..11632 ; SpacingMark # Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II
+1163B..1163C ; SpacingMark # Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU
+1163E ; SpacingMark # Mc MODI SIGN VISARGA
+116AC ; SpacingMark # Mc TAKRI SIGN VISARGA
+116AE..116AF ; SpacingMark # Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II
+116B6 ; SpacingMark # Mc TAKRI SIGN VIRAMA
+11720..11721 ; SpacingMark # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA
+11726 ; SpacingMark # Mc AHOM VOWEL SIGN E
+11C2F ; SpacingMark # Mc BHAIKSUKI VOWEL SIGN AA
+11C3E ; SpacingMark # Mc BHAIKSUKI SIGN VISARGA
+11CA9 ; SpacingMark # Mc MARCHEN SUBJOINED LETTER YA
+11CB1 ; SpacingMark # Mc MARCHEN VOWEL SIGN I
+11CB4 ; SpacingMark # Mc MARCHEN VOWEL SIGN O
+16F51..16F7E ; SpacingMark # Mc [46] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN NG
+1D166 ; SpacingMark # Mc MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
+1D16D ; SpacingMark # Mc MUSICAL SYMBOL COMBINING AUGMENTATION DOT
+
+# Total code points: 341
+
+# ================================================
+
+1100..115F ; L # Lo [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER
+A960..A97C ; L # Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH
+
+# Total code points: 125
+
+# ================================================
+
+1160..11A7 ; V # Lo [72] HANGUL JUNGSEONG FILLER..HANGUL JUNGSEONG O-YAE
+D7B0..D7C6 ; V # Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E
+
+# Total code points: 95
+
+# ================================================
+
+11A8..11FF ; T # Lo [88] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG SSANGNIEUN
+D7CB..D7FB ; T # Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH
+
+# Total code points: 137
+
+# ================================================
+
+AC00 ; LV # Lo HANGUL SYLLABLE GA
+AC1C ; LV # Lo HANGUL SYLLABLE GAE
+AC38 ; LV # Lo HANGUL SYLLABLE GYA
+AC54 ; LV # Lo HANGUL SYLLABLE GYAE
+AC70 ; LV # Lo HANGUL SYLLABLE GEO
+AC8C ; LV # Lo HANGUL SYLLABLE GE
+ACA8 ; LV # Lo HANGUL SYLLABLE GYEO
+ACC4 ; LV # Lo HANGUL SYLLABLE GYE
+ACE0 ; LV # Lo HANGUL SYLLABLE GO
+ACFC ; LV # Lo HANGUL SYLLABLE GWA
+AD18 ; LV # Lo HANGUL SYLLABLE GWAE
+AD34 ; LV # Lo HANGUL SYLLABLE GOE
+AD50 ; LV # Lo HANGUL SYLLABLE GYO
+AD6C ; LV # Lo HANGUL SYLLABLE GU
+AD88 ; LV # Lo HANGUL SYLLABLE GWEO
+ADA4 ; LV # Lo HANGUL SYLLABLE GWE
+ADC0 ; LV # Lo HANGUL SYLLABLE GWI
+ADDC ; LV # Lo HANGUL SYLLABLE GYU
+ADF8 ; LV # Lo HANGUL SYLLABLE GEU
+AE14 ; LV # Lo HANGUL SYLLABLE GYI
+AE30 ; LV # Lo HANGUL SYLLABLE GI
+AE4C ; LV # Lo HANGUL SYLLABLE GGA
+AE68 ; LV # Lo HANGUL SYLLABLE GGAE
+AE84 ; LV # Lo HANGUL SYLLABLE GGYA
+AEA0 ; LV # Lo HANGUL SYLLABLE GGYAE
+AEBC ; LV # Lo HANGUL SYLLABLE GGEO
+AED8 ; LV # Lo HANGUL SYLLABLE GGE
+AEF4 ; LV # Lo HANGUL SYLLABLE GGYEO
+AF10 ; LV # Lo HANGUL SYLLABLE GGYE
+AF2C ; LV # Lo HANGUL SYLLABLE GGO
+AF48 ; LV # Lo HANGUL SYLLABLE GGWA
+AF64 ; LV # Lo HANGUL SYLLABLE GGWAE
+AF80 ; LV # Lo HANGUL SYLLABLE GGOE
+AF9C ; LV # Lo HANGUL SYLLABLE GGYO
+AFB8 ; LV # Lo HANGUL SYLLABLE GGU
+AFD4 ; LV # Lo HANGUL SYLLABLE GGWEO
+AFF0 ; LV # Lo HANGUL SYLLABLE GGWE
+B00C ; LV # Lo HANGUL SYLLABLE GGWI
+B028 ; LV # Lo HANGUL SYLLABLE GGYU
+B044 ; LV # Lo HANGUL SYLLABLE GGEU
+B060 ; LV # Lo HANGUL SYLLABLE GGYI
+B07C ; LV # Lo HANGUL SYLLABLE GGI
+B098 ; LV # Lo HANGUL SYLLABLE NA
+B0B4 ; LV # Lo HANGUL SYLLABLE NAE
+B0D0 ; LV # Lo HANGUL SYLLABLE NYA
+B0EC ; LV # Lo HANGUL SYLLABLE NYAE
+B108 ; LV # Lo HANGUL SYLLABLE NEO
+B124 ; LV # Lo HANGUL SYLLABLE NE
+B140 ; LV # Lo HANGUL SYLLABLE NYEO
+B15C ; LV # Lo HANGUL SYLLABLE NYE
+B178 ; LV # Lo HANGUL SYLLABLE NO
+B194 ; LV # Lo HANGUL SYLLABLE NWA
+B1B0 ; LV # Lo HANGUL SYLLABLE NWAE
+B1CC ; LV # Lo HANGUL SYLLABLE NOE
+B1E8 ; LV # Lo HANGUL SYLLABLE NYO
+B204 ; LV # Lo HANGUL SYLLABLE NU
+B220 ; LV # Lo HANGUL SYLLABLE NWEO
+B23C ; LV # Lo HANGUL SYLLABLE NWE
+B258 ; LV # Lo HANGUL SYLLABLE NWI
+B274 ; LV # Lo HANGUL SYLLABLE NYU
+B290 ; LV # Lo HANGUL SYLLABLE NEU
+B2AC ; LV # Lo HANGUL SYLLABLE NYI
+B2C8 ; LV # Lo HANGUL SYLLABLE NI
+B2E4 ; LV # Lo HANGUL SYLLABLE DA
+B300 ; LV # Lo HANGUL SYLLABLE DAE
+B31C ; LV # Lo HANGUL SYLLABLE DYA
+B338 ; LV # Lo HANGUL SYLLABLE DYAE
+B354 ; LV # Lo HANGUL SYLLABLE DEO
+B370 ; LV # Lo HANGUL SYLLABLE DE
+B38C ; LV # Lo HANGUL SYLLABLE DYEO
+B3A8 ; LV # Lo HANGUL SYLLABLE DYE
+B3C4 ; LV # Lo HANGUL SYLLABLE DO
+B3E0 ; LV # Lo HANGUL SYLLABLE DWA
+B3FC ; LV # Lo HANGUL SYLLABLE DWAE
+B418 ; LV # Lo HANGUL SYLLABLE DOE
+B434 ; LV # Lo HANGUL SYLLABLE DYO
+B450 ; LV # Lo HANGUL SYLLABLE DU
+B46C ; LV # Lo HANGUL SYLLABLE DWEO
+B488 ; LV # Lo HANGUL SYLLABLE DWE
+B4A4 ; LV # Lo HANGUL SYLLABLE DWI
+B4C0 ; LV # Lo HANGUL SYLLABLE DYU
+B4DC ; LV # Lo HANGUL SYLLABLE DEU
+B4F8 ; LV # Lo HANGUL SYLLABLE DYI
+B514 ; LV # Lo HANGUL SYLLABLE DI
+B530 ; LV # Lo HANGUL SYLLABLE DDA
+B54C ; LV # Lo HANGUL SYLLABLE DDAE
+B568 ; LV # Lo HANGUL SYLLABLE DDYA
+B584 ; LV # Lo HANGUL SYLLABLE DDYAE
+B5A0 ; LV # Lo HANGUL SYLLABLE DDEO
+B5BC ; LV # Lo HANGUL SYLLABLE DDE
+B5D8 ; LV # Lo HANGUL SYLLABLE DDYEO
+B5F4 ; LV # Lo HANGUL SYLLABLE DDYE
+B610 ; LV # Lo HANGUL SYLLABLE DDO
+B62C ; LV # Lo HANGUL SYLLABLE DDWA
+B648 ; LV # Lo HANGUL SYLLABLE DDWAE
+B664 ; LV # Lo HANGUL SYLLABLE DDOE
+B680 ; LV # Lo HANGUL SYLLABLE DDYO
+B69C ; LV # Lo HANGUL SYLLABLE DDU
+B6B8 ; LV # Lo HANGUL SYLLABLE DDWEO
+B6D4 ; LV # Lo HANGUL SYLLABLE DDWE
+B6F0 ; LV # Lo HANGUL SYLLABLE DDWI
+B70C ; LV # Lo HANGUL SYLLABLE DDYU
+B728 ; LV # Lo HANGUL SYLLABLE DDEU
+B744 ; LV # Lo HANGUL SYLLABLE DDYI
+B760 ; LV # Lo HANGUL SYLLABLE DDI
+B77C ; LV # Lo HANGUL SYLLABLE RA
+B798 ; LV # Lo HANGUL SYLLABLE RAE
+B7B4 ; LV # Lo HANGUL SYLLABLE RYA
+B7D0 ; LV # Lo HANGUL SYLLABLE RYAE
+B7EC ; LV # Lo HANGUL SYLLABLE REO
+B808 ; LV # Lo HANGUL SYLLABLE RE
+B824 ; LV # Lo HANGUL SYLLABLE RYEO
+B840 ; LV # Lo HANGUL SYLLABLE RYE
+B85C ; LV # Lo HANGUL SYLLABLE RO
+B878 ; LV # Lo HANGUL SYLLABLE RWA
+B894 ; LV # Lo HANGUL SYLLABLE RWAE
+B8B0 ; LV # Lo HANGUL SYLLABLE ROE
+B8CC ; LV # Lo HANGUL SYLLABLE RYO
+B8E8 ; LV # Lo HANGUL SYLLABLE RU
+B904 ; LV # Lo HANGUL SYLLABLE RWEO
+B920 ; LV # Lo HANGUL SYLLABLE RWE
+B93C ; LV # Lo HANGUL SYLLABLE RWI
+B958 ; LV # Lo HANGUL SYLLABLE RYU
+B974 ; LV # Lo HANGUL SYLLABLE REU
+B990 ; LV # Lo HANGUL SYLLABLE RYI
+B9AC ; LV # Lo HANGUL SYLLABLE RI
+B9C8 ; LV # Lo HANGUL SYLLABLE MA
+B9E4 ; LV # Lo HANGUL SYLLABLE MAE
+BA00 ; LV # Lo HANGUL SYLLABLE MYA
+BA1C ; LV # Lo HANGUL SYLLABLE MYAE
+BA38 ; LV # Lo HANGUL SYLLABLE MEO
+BA54 ; LV # Lo HANGUL SYLLABLE ME
+BA70 ; LV # Lo HANGUL SYLLABLE MYEO
+BA8C ; LV # Lo HANGUL SYLLABLE MYE
+BAA8 ; LV # Lo HANGUL SYLLABLE MO
+BAC4 ; LV # Lo HANGUL SYLLABLE MWA
+BAE0 ; LV # Lo HANGUL SYLLABLE MWAE
+BAFC ; LV # Lo HANGUL SYLLABLE MOE
+BB18 ; LV # Lo HANGUL SYLLABLE MYO
+BB34 ; LV # Lo HANGUL SYLLABLE MU
+BB50 ; LV # Lo HANGUL SYLLABLE MWEO
+BB6C ; LV # Lo HANGUL SYLLABLE MWE
+BB88 ; LV # Lo HANGUL SYLLABLE MWI
+BBA4 ; LV # Lo HANGUL SYLLABLE MYU
+BBC0 ; LV # Lo HANGUL SYLLABLE MEU
+BBDC ; LV # Lo HANGUL SYLLABLE MYI
+BBF8 ; LV # Lo HANGUL SYLLABLE MI
+BC14 ; LV # Lo HANGUL SYLLABLE BA
+BC30 ; LV # Lo HANGUL SYLLABLE BAE
+BC4C ; LV # Lo HANGUL SYLLABLE BYA
+BC68 ; LV # Lo HANGUL SYLLABLE BYAE
+BC84 ; LV # Lo HANGUL SYLLABLE BEO
+BCA0 ; LV # Lo HANGUL SYLLABLE BE
+BCBC ; LV # Lo HANGUL SYLLABLE BYEO
+BCD8 ; LV # Lo HANGUL SYLLABLE BYE
+BCF4 ; LV # Lo HANGUL SYLLABLE BO
+BD10 ; LV # Lo HANGUL SYLLABLE BWA
+BD2C ; LV # Lo HANGUL SYLLABLE BWAE
+BD48 ; LV # Lo HANGUL SYLLABLE BOE
+BD64 ; LV # Lo HANGUL SYLLABLE BYO
+BD80 ; LV # Lo HANGUL SYLLABLE BU
+BD9C ; LV # Lo HANGUL SYLLABLE BWEO
+BDB8 ; LV # Lo HANGUL SYLLABLE BWE
+BDD4 ; LV # Lo HANGUL SYLLABLE BWI
+BDF0 ; LV # Lo HANGUL SYLLABLE BYU
+BE0C ; LV # Lo HANGUL SYLLABLE BEU
+BE28 ; LV # Lo HANGUL SYLLABLE BYI
+BE44 ; LV # Lo HANGUL SYLLABLE BI
+BE60 ; LV # Lo HANGUL SYLLABLE BBA
+BE7C ; LV # Lo HANGUL SYLLABLE BBAE
+BE98 ; LV # Lo HANGUL SYLLABLE BBYA
+BEB4 ; LV # Lo HANGUL SYLLABLE BBYAE
+BED0 ; LV # Lo HANGUL SYLLABLE BBEO
+BEEC ; LV # Lo HANGUL SYLLABLE BBE
+BF08 ; LV # Lo HANGUL SYLLABLE BBYEO
+BF24 ; LV # Lo HANGUL SYLLABLE BBYE
+BF40 ; LV # Lo HANGUL SYLLABLE BBO
+BF5C ; LV # Lo HANGUL SYLLABLE BBWA
+BF78 ; LV # Lo HANGUL SYLLABLE BBWAE
+BF94 ; LV # Lo HANGUL SYLLABLE BBOE
+BFB0 ; LV # Lo HANGUL SYLLABLE BBYO
+BFCC ; LV # Lo HANGUL SYLLABLE BBU
+BFE8 ; LV # Lo HANGUL SYLLABLE BBWEO
+C004 ; LV # Lo HANGUL SYLLABLE BBWE
+C020 ; LV # Lo HANGUL SYLLABLE BBWI
+C03C ; LV # Lo HANGUL SYLLABLE BBYU
+C058 ; LV # Lo HANGUL SYLLABLE BBEU
+C074 ; LV # Lo HANGUL SYLLABLE BBYI
+C090 ; LV # Lo HANGUL SYLLABLE BBI
+C0AC ; LV # Lo HANGUL SYLLABLE SA
+C0C8 ; LV # Lo HANGUL SYLLABLE SAE
+C0E4 ; LV # Lo HANGUL SYLLABLE SYA
+C100 ; LV # Lo HANGUL SYLLABLE SYAE
+C11C ; LV # Lo HANGUL SYLLABLE SEO
+C138 ; LV # Lo HANGUL SYLLABLE SE
+C154 ; LV # Lo HANGUL SYLLABLE SYEO
+C170 ; LV # Lo HANGUL SYLLABLE SYE
+C18C ; LV # Lo HANGUL SYLLABLE SO
+C1A8 ; LV # Lo HANGUL SYLLABLE SWA
+C1C4 ; LV # Lo HANGUL SYLLABLE SWAE
+C1E0 ; LV # Lo HANGUL SYLLABLE SOE
+C1FC ; LV # Lo HANGUL SYLLABLE SYO
+C218 ; LV # Lo HANGUL SYLLABLE SU
+C234 ; LV # Lo HANGUL SYLLABLE SWEO
+C250 ; LV # Lo HANGUL SYLLABLE SWE
+C26C ; LV # Lo HANGUL SYLLABLE SWI
+C288 ; LV # Lo HANGUL SYLLABLE SYU
+C2A4 ; LV # Lo HANGUL SYLLABLE SEU
+C2C0 ; LV # Lo HANGUL SYLLABLE SYI
+C2DC ; LV # Lo HANGUL SYLLABLE SI
+C2F8 ; LV # Lo HANGUL SYLLABLE SSA
+C314 ; LV # Lo HANGUL SYLLABLE SSAE
+C330 ; LV # Lo HANGUL SYLLABLE SSYA
+C34C ; LV # Lo HANGUL SYLLABLE SSYAE
+C368 ; LV # Lo HANGUL SYLLABLE SSEO
+C384 ; LV # Lo HANGUL SYLLABLE SSE
+C3A0 ; LV # Lo HANGUL SYLLABLE SSYEO
+C3BC ; LV # Lo HANGUL SYLLABLE SSYE
+C3D8 ; LV # Lo HANGUL SYLLABLE SSO
+C3F4 ; LV # Lo HANGUL SYLLABLE SSWA
+C410 ; LV # Lo HANGUL SYLLABLE SSWAE
+C42C ; LV # Lo HANGUL SYLLABLE SSOE
+C448 ; LV # Lo HANGUL SYLLABLE SSYO
+C464 ; LV # Lo HANGUL SYLLABLE SSU
+C480 ; LV # Lo HANGUL SYLLABLE SSWEO
+C49C ; LV # Lo HANGUL SYLLABLE SSWE
+C4B8 ; LV # Lo HANGUL SYLLABLE SSWI
+C4D4 ; LV # Lo HANGUL SYLLABLE SSYU
+C4F0 ; LV # Lo HANGUL SYLLABLE SSEU
+C50C ; LV # Lo HANGUL SYLLABLE SSYI
+C528 ; LV # Lo HANGUL SYLLABLE SSI
+C544 ; LV # Lo HANGUL SYLLABLE A
+C560 ; LV # Lo HANGUL SYLLABLE AE
+C57C ; LV # Lo HANGUL SYLLABLE YA
+C598 ; LV # Lo HANGUL SYLLABLE YAE
+C5B4 ; LV # Lo HANGUL SYLLABLE EO
+C5D0 ; LV # Lo HANGUL SYLLABLE E
+C5EC ; LV # Lo HANGUL SYLLABLE YEO
+C608 ; LV # Lo HANGUL SYLLABLE YE
+C624 ; LV # Lo HANGUL SYLLABLE O
+C640 ; LV # Lo HANGUL SYLLABLE WA
+C65C ; LV # Lo HANGUL SYLLABLE WAE
+C678 ; LV # Lo HANGUL SYLLABLE OE
+C694 ; LV # Lo HANGUL SYLLABLE YO
+C6B0 ; LV # Lo HANGUL SYLLABLE U
+C6CC ; LV # Lo HANGUL SYLLABLE WEO
+C6E8 ; LV # Lo HANGUL SYLLABLE WE
+C704 ; LV # Lo HANGUL SYLLABLE WI
+C720 ; LV # Lo HANGUL SYLLABLE YU
+C73C ; LV # Lo HANGUL SYLLABLE EU
+C758 ; LV # Lo HANGUL SYLLABLE YI
+C774 ; LV # Lo HANGUL SYLLABLE I
+C790 ; LV # Lo HANGUL SYLLABLE JA
+C7AC ; LV # Lo HANGUL SYLLABLE JAE
+C7C8 ; LV # Lo HANGUL SYLLABLE JYA
+C7E4 ; LV # Lo HANGUL SYLLABLE JYAE
+C800 ; LV # Lo HANGUL SYLLABLE JEO
+C81C ; LV # Lo HANGUL SYLLABLE JE
+C838 ; LV # Lo HANGUL SYLLABLE JYEO
+C854 ; LV # Lo HANGUL SYLLABLE JYE
+C870 ; LV # Lo HANGUL SYLLABLE JO
+C88C ; LV # Lo HANGUL SYLLABLE JWA
+C8A8 ; LV # Lo HANGUL SYLLABLE JWAE
+C8C4 ; LV # Lo HANGUL SYLLABLE JOE
+C8E0 ; LV # Lo HANGUL SYLLABLE JYO
+C8FC ; LV # Lo HANGUL SYLLABLE JU
+C918 ; LV # Lo HANGUL SYLLABLE JWEO
+C934 ; LV # Lo HANGUL SYLLABLE JWE
+C950 ; LV # Lo HANGUL SYLLABLE JWI
+C96C ; LV # Lo HANGUL SYLLABLE JYU
+C988 ; LV # Lo HANGUL SYLLABLE JEU
+C9A4 ; LV # Lo HANGUL SYLLABLE JYI
+C9C0 ; LV # Lo HANGUL SYLLABLE JI
+C9DC ; LV # Lo HANGUL SYLLABLE JJA
+C9F8 ; LV # Lo HANGUL SYLLABLE JJAE
+CA14 ; LV # Lo HANGUL SYLLABLE JJYA
+CA30 ; LV # Lo HANGUL SYLLABLE JJYAE
+CA4C ; LV # Lo HANGUL SYLLABLE JJEO
+CA68 ; LV # Lo HANGUL SYLLABLE JJE
+CA84 ; LV # Lo HANGUL SYLLABLE JJYEO
+CAA0 ; LV # Lo HANGUL SYLLABLE JJYE
+CABC ; LV # Lo HANGUL SYLLABLE JJO
+CAD8 ; LV # Lo HANGUL SYLLABLE JJWA
+CAF4 ; LV # Lo HANGUL SYLLABLE JJWAE
+CB10 ; LV # Lo HANGUL SYLLABLE JJOE
+CB2C ; LV # Lo HANGUL SYLLABLE JJYO
+CB48 ; LV # Lo HANGUL SYLLABLE JJU
+CB64 ; LV # Lo HANGUL SYLLABLE JJWEO
+CB80 ; LV # Lo HANGUL SYLLABLE JJWE
+CB9C ; LV # Lo HANGUL SYLLABLE JJWI
+CBB8 ; LV # Lo HANGUL SYLLABLE JJYU
+CBD4 ; LV # Lo HANGUL SYLLABLE JJEU
+CBF0 ; LV # Lo HANGUL SYLLABLE JJYI
+CC0C ; LV # Lo HANGUL SYLLABLE JJI
+CC28 ; LV # Lo HANGUL SYLLABLE CA
+CC44 ; LV # Lo HANGUL SYLLABLE CAE
+CC60 ; LV # Lo HANGUL SYLLABLE CYA
+CC7C ; LV # Lo HANGUL SYLLABLE CYAE
+CC98 ; LV # Lo HANGUL SYLLABLE CEO
+CCB4 ; LV # Lo HANGUL SYLLABLE CE
+CCD0 ; LV # Lo HANGUL SYLLABLE CYEO
+CCEC ; LV # Lo HANGUL SYLLABLE CYE
+CD08 ; LV # Lo HANGUL SYLLABLE CO
+CD24 ; LV # Lo HANGUL SYLLABLE CWA
+CD40 ; LV # Lo HANGUL SYLLABLE CWAE
+CD5C ; LV # Lo HANGUL SYLLABLE COE
+CD78 ; LV # Lo HANGUL SYLLABLE CYO
+CD94 ; LV # Lo HANGUL SYLLABLE CU
+CDB0 ; LV # Lo HANGUL SYLLABLE CWEO
+CDCC ; LV # Lo HANGUL SYLLABLE CWE
+CDE8 ; LV # Lo HANGUL SYLLABLE CWI
+CE04 ; LV # Lo HANGUL SYLLABLE CYU
+CE20 ; LV # Lo HANGUL SYLLABLE CEU
+CE3C ; LV # Lo HANGUL SYLLABLE CYI
+CE58 ; LV # Lo HANGUL SYLLABLE CI
+CE74 ; LV # Lo HANGUL SYLLABLE KA
+CE90 ; LV # Lo HANGUL SYLLABLE KAE
+CEAC ; LV # Lo HANGUL SYLLABLE KYA
+CEC8 ; LV # Lo HANGUL SYLLABLE KYAE
+CEE4 ; LV # Lo HANGUL SYLLABLE KEO
+CF00 ; LV # Lo HANGUL SYLLABLE KE
+CF1C ; LV # Lo HANGUL SYLLABLE KYEO
+CF38 ; LV # Lo HANGUL SYLLABLE KYE
+CF54 ; LV # Lo HANGUL SYLLABLE KO
+CF70 ; LV # Lo HANGUL SYLLABLE KWA
+CF8C ; LV # Lo HANGUL SYLLABLE KWAE
+CFA8 ; LV # Lo HANGUL SYLLABLE KOE
+CFC4 ; LV # Lo HANGUL SYLLABLE KYO
+CFE0 ; LV # Lo HANGUL SYLLABLE KU
+CFFC ; LV # Lo HANGUL SYLLABLE KWEO
+D018 ; LV # Lo HANGUL SYLLABLE KWE
+D034 ; LV # Lo HANGUL SYLLABLE KWI
+D050 ; LV # Lo HANGUL SYLLABLE KYU
+D06C ; LV # Lo HANGUL SYLLABLE KEU
+D088 ; LV # Lo HANGUL SYLLABLE KYI
+D0A4 ; LV # Lo HANGUL SYLLABLE KI
+D0C0 ; LV # Lo HANGUL SYLLABLE TA
+D0DC ; LV # Lo HANGUL SYLLABLE TAE
+D0F8 ; LV # Lo HANGUL SYLLABLE TYA
+D114 ; LV # Lo HANGUL SYLLABLE TYAE
+D130 ; LV # Lo HANGUL SYLLABLE TEO
+D14C ; LV # Lo HANGUL SYLLABLE TE
+D168 ; LV # Lo HANGUL SYLLABLE TYEO
+D184 ; LV # Lo HANGUL SYLLABLE TYE
+D1A0 ; LV # Lo HANGUL SYLLABLE TO
+D1BC ; LV # Lo HANGUL SYLLABLE TWA
+D1D8 ; LV # Lo HANGUL SYLLABLE TWAE
+D1F4 ; LV # Lo HANGUL SYLLABLE TOE
+D210 ; LV # Lo HANGUL SYLLABLE TYO
+D22C ; LV # Lo HANGUL SYLLABLE TU
+D248 ; LV # Lo HANGUL SYLLABLE TWEO
+D264 ; LV # Lo HANGUL SYLLABLE TWE
+D280 ; LV # Lo HANGUL SYLLABLE TWI
+D29C ; LV # Lo HANGUL SYLLABLE TYU
+D2B8 ; LV # Lo HANGUL SYLLABLE TEU
+D2D4 ; LV # Lo HANGUL SYLLABLE TYI
+D2F0 ; LV # Lo HANGUL SYLLABLE TI
+D30C ; LV # Lo HANGUL SYLLABLE PA
+D328 ; LV # Lo HANGUL SYLLABLE PAE
+D344 ; LV # Lo HANGUL SYLLABLE PYA
+D360 ; LV # Lo HANGUL SYLLABLE PYAE
+D37C ; LV # Lo HANGUL SYLLABLE PEO
+D398 ; LV # Lo HANGUL SYLLABLE PE
+D3B4 ; LV # Lo HANGUL SYLLABLE PYEO
+D3D0 ; LV # Lo HANGUL SYLLABLE PYE
+D3EC ; LV # Lo HANGUL SYLLABLE PO
+D408 ; LV # Lo HANGUL SYLLABLE PWA
+D424 ; LV # Lo HANGUL SYLLABLE PWAE
+D440 ; LV # Lo HANGUL SYLLABLE POE
+D45C ; LV # Lo HANGUL SYLLABLE PYO
+D478 ; LV # Lo HANGUL SYLLABLE PU
+D494 ; LV # Lo HANGUL SYLLABLE PWEO
+D4B0 ; LV # Lo HANGUL SYLLABLE PWE
+D4CC ; LV # Lo HANGUL SYLLABLE PWI
+D4E8 ; LV # Lo HANGUL SYLLABLE PYU
+D504 ; LV # Lo HANGUL SYLLABLE PEU
+D520 ; LV # Lo HANGUL SYLLABLE PYI
+D53C ; LV # Lo HANGUL SYLLABLE PI
+D558 ; LV # Lo HANGUL SYLLABLE HA
+D574 ; LV # Lo HANGUL SYLLABLE HAE
+D590 ; LV # Lo HANGUL SYLLABLE HYA
+D5AC ; LV # Lo HANGUL SYLLABLE HYAE
+D5C8 ; LV # Lo HANGUL SYLLABLE HEO
+D5E4 ; LV # Lo HANGUL SYLLABLE HE
+D600 ; LV # Lo HANGUL SYLLABLE HYEO
+D61C ; LV # Lo HANGUL SYLLABLE HYE
+D638 ; LV # Lo HANGUL SYLLABLE HO
+D654 ; LV # Lo HANGUL SYLLABLE HWA
+D670 ; LV # Lo HANGUL SYLLABLE HWAE
+D68C ; LV # Lo HANGUL SYLLABLE HOE
+D6A8 ; LV # Lo HANGUL SYLLABLE HYO
+D6C4 ; LV # Lo HANGUL SYLLABLE HU
+D6E0 ; LV # Lo HANGUL SYLLABLE HWEO
+D6FC ; LV # Lo HANGUL SYLLABLE HWE
+D718 ; LV # Lo HANGUL SYLLABLE HWI
+D734 ; LV # Lo HANGUL SYLLABLE HYU
+D750 ; LV # Lo HANGUL SYLLABLE HEU
+D76C ; LV # Lo HANGUL SYLLABLE HYI
+D788 ; LV # Lo HANGUL SYLLABLE HI
+
+# Total code points: 399
+
+# ================================================
+
+AC01..AC1B ; LVT # Lo [27] HANGUL SYLLABLE GAG..HANGUL SYLLABLE GAH
+AC1D..AC37 ; LVT # Lo [27] HANGUL SYLLABLE GAEG..HANGUL SYLLABLE GAEH
+AC39..AC53 ; LVT # Lo [27] HANGUL SYLLABLE GYAG..HANGUL SYLLABLE GYAH
+AC55..AC6F ; LVT # Lo [27] HANGUL SYLLABLE GYAEG..HANGUL SYLLABLE GYAEH
+AC71..AC8B ; LVT # Lo [27] HANGUL SYLLABLE GEOG..HANGUL SYLLABLE GEOH
+AC8D..ACA7 ; LVT # Lo [27] HANGUL SYLLABLE GEG..HANGUL SYLLABLE GEH
+ACA9..ACC3 ; LVT # Lo [27] HANGUL SYLLABLE GYEOG..HANGUL SYLLABLE GYEOH
+ACC5..ACDF ; LVT # Lo [27] HANGUL SYLLABLE GYEG..HANGUL SYLLABLE GYEH
+ACE1..ACFB ; LVT # Lo [27] HANGUL SYLLABLE GOG..HANGUL SYLLABLE GOH
+ACFD..AD17 ; LVT # Lo [27] HANGUL SYLLABLE GWAG..HANGUL SYLLABLE GWAH
+AD19..AD33 ; LVT # Lo [27] HANGUL SYLLABLE GWAEG..HANGUL SYLLABLE GWAEH
+AD35..AD4F ; LVT # Lo [27] HANGUL SYLLABLE GOEG..HANGUL SYLLABLE GOEH
+AD51..AD6B ; LVT # Lo [27] HANGUL SYLLABLE GYOG..HANGUL SYLLABLE GYOH
+AD6D..AD87 ; LVT # Lo [27] HANGUL SYLLABLE GUG..HANGUL SYLLABLE GUH
+AD89..ADA3 ; LVT # Lo [27] HANGUL SYLLABLE GWEOG..HANGUL SYLLABLE GWEOH
+ADA5..ADBF ; LVT # Lo [27] HANGUL SYLLABLE GWEG..HANGUL SYLLABLE GWEH
+ADC1..ADDB ; LVT # Lo [27] HANGUL SYLLABLE GWIG..HANGUL SYLLABLE GWIH
+ADDD..ADF7 ; LVT # Lo [27] HANGUL SYLLABLE GYUG..HANGUL SYLLABLE GYUH
+ADF9..AE13 ; LVT # Lo [27] HANGUL SYLLABLE GEUG..HANGUL SYLLABLE GEUH
+AE15..AE2F ; LVT # Lo [27] HANGUL SYLLABLE GYIG..HANGUL SYLLABLE GYIH
+AE31..AE4B ; LVT # Lo [27] HANGUL SYLLABLE GIG..HANGUL SYLLABLE GIH
+AE4D..AE67 ; LVT # Lo [27] HANGUL SYLLABLE GGAG..HANGUL SYLLABLE GGAH
+AE69..AE83 ; LVT # Lo [27] HANGUL SYLLABLE GGAEG..HANGUL SYLLABLE GGAEH
+AE85..AE9F ; LVT # Lo [27] HANGUL SYLLABLE GGYAG..HANGUL SYLLABLE GGYAH
+AEA1..AEBB ; LVT # Lo [27] HANGUL SYLLABLE GGYAEG..HANGUL SYLLABLE GGYAEH
+AEBD..AED7 ; LVT # Lo [27] HANGUL SYLLABLE GGEOG..HANGUL SYLLABLE GGEOH
+AED9..AEF3 ; LVT # Lo [27] HANGUL SYLLABLE GGEG..HANGUL SYLLABLE GGEH
+AEF5..AF0F ; LVT # Lo [27] HANGUL SYLLABLE GGYEOG..HANGUL SYLLABLE GGYEOH
+AF11..AF2B ; LVT # Lo [27] HANGUL SYLLABLE GGYEG..HANGUL SYLLABLE GGYEH
+AF2D..AF47 ; LVT # Lo [27] HANGUL SYLLABLE GGOG..HANGUL SYLLABLE GGOH
+AF49..AF63 ; LVT # Lo [27] HANGUL SYLLABLE GGWAG..HANGUL SYLLABLE GGWAH
+AF65..AF7F ; LVT # Lo [27] HANGUL SYLLABLE GGWAEG..HANGUL SYLLABLE GGWAEH
+AF81..AF9B ; LVT # Lo [27] HANGUL SYLLABLE GGOEG..HANGUL SYLLABLE GGOEH
+AF9D..AFB7 ; LVT # Lo [27] HANGUL SYLLABLE GGYOG..HANGUL SYLLABLE GGYOH
+AFB9..AFD3 ; LVT # Lo [27] HANGUL SYLLABLE GGUG..HANGUL SYLLABLE GGUH
+AFD5..AFEF ; LVT # Lo [27] HANGUL SYLLABLE GGWEOG..HANGUL SYLLABLE GGWEOH
+AFF1..B00B ; LVT # Lo [27] HANGUL SYLLABLE GGWEG..HANGUL SYLLABLE GGWEH
+B00D..B027 ; LVT # Lo [27] HANGUL SYLLABLE GGWIG..HANGUL SYLLABLE GGWIH
+B029..B043 ; LVT # Lo [27] HANGUL SYLLABLE GGYUG..HANGUL SYLLABLE GGYUH
+B045..B05F ; LVT # Lo [27] HANGUL SYLLABLE GGEUG..HANGUL SYLLABLE GGEUH
+B061..B07B ; LVT # Lo [27] HANGUL SYLLABLE GGYIG..HANGUL SYLLABLE GGYIH
+B07D..B097 ; LVT # Lo [27] HANGUL SYLLABLE GGIG..HANGUL SYLLABLE GGIH
+B099..B0B3 ; LVT # Lo [27] HANGUL SYLLABLE NAG..HANGUL SYLLABLE NAH
+B0B5..B0CF ; LVT # Lo [27] HANGUL SYLLABLE NAEG..HANGUL SYLLABLE NAEH
+B0D1..B0EB ; LVT # Lo [27] HANGUL SYLLABLE NYAG..HANGUL SYLLABLE NYAH
+B0ED..B107 ; LVT # Lo [27] HANGUL SYLLABLE NYAEG..HANGUL SYLLABLE NYAEH
+B109..B123 ; LVT # Lo [27] HANGUL SYLLABLE NEOG..HANGUL SYLLABLE NEOH
+B125..B13F ; LVT # Lo [27] HANGUL SYLLABLE NEG..HANGUL SYLLABLE NEH
+B141..B15B ; LVT # Lo [27] HANGUL SYLLABLE NYEOG..HANGUL SYLLABLE NYEOH
+B15D..B177 ; LVT # Lo [27] HANGUL SYLLABLE NYEG..HANGUL SYLLABLE NYEH
+B179..B193 ; LVT # Lo [27] HANGUL SYLLABLE NOG..HANGUL SYLLABLE NOH
+B195..B1AF ; LVT # Lo [27] HANGUL SYLLABLE NWAG..HANGUL SYLLABLE NWAH
+B1B1..B1CB ; LVT # Lo [27] HANGUL SYLLABLE NWAEG..HANGUL SYLLABLE NWAEH
+B1CD..B1E7 ; LVT # Lo [27] HANGUL SYLLABLE NOEG..HANGUL SYLLABLE NOEH
+B1E9..B203 ; LVT # Lo [27] HANGUL SYLLABLE NYOG..HANGUL SYLLABLE NYOH
+B205..B21F ; LVT # Lo [27] HANGUL SYLLABLE NUG..HANGUL SYLLABLE NUH
+B221..B23B ; LVT # Lo [27] HANGUL SYLLABLE NWEOG..HANGUL SYLLABLE NWEOH
+B23D..B257 ; LVT # Lo [27] HANGUL SYLLABLE NWEG..HANGUL SYLLABLE NWEH
+B259..B273 ; LVT # Lo [27] HANGUL SYLLABLE NWIG..HANGUL SYLLABLE NWIH
+B275..B28F ; LVT # Lo [27] HANGUL SYLLABLE NYUG..HANGUL SYLLABLE NYUH
+B291..B2AB ; LVT # Lo [27] HANGUL SYLLABLE NEUG..HANGUL SYLLABLE NEUH
+B2AD..B2C7 ; LVT # Lo [27] HANGUL SYLLABLE NYIG..HANGUL SYLLABLE NYIH
+B2C9..B2E3 ; LVT # Lo [27] HANGUL SYLLABLE NIG..HANGUL SYLLABLE NIH
+B2E5..B2FF ; LVT # Lo [27] HANGUL SYLLABLE DAG..HANGUL SYLLABLE DAH
+B301..B31B ; LVT # Lo [27] HANGUL SYLLABLE DAEG..HANGUL SYLLABLE DAEH
+B31D..B337 ; LVT # Lo [27] HANGUL SYLLABLE DYAG..HANGUL SYLLABLE DYAH
+B339..B353 ; LVT # Lo [27] HANGUL SYLLABLE DYAEG..HANGUL SYLLABLE DYAEH
+B355..B36F ; LVT # Lo [27] HANGUL SYLLABLE DEOG..HANGUL SYLLABLE DEOH
+B371..B38B ; LVT # Lo [27] HANGUL SYLLABLE DEG..HANGUL SYLLABLE DEH
+B38D..B3A7 ; LVT # Lo [27] HANGUL SYLLABLE DYEOG..HANGUL SYLLABLE DYEOH
+B3A9..B3C3 ; LVT # Lo [27] HANGUL SYLLABLE DYEG..HANGUL SYLLABLE DYEH
+B3C5..B3DF ; LVT # Lo [27] HANGUL SYLLABLE DOG..HANGUL SYLLABLE DOH
+B3E1..B3FB ; LVT # Lo [27] HANGUL SYLLABLE DWAG..HANGUL SYLLABLE DWAH
+B3FD..B417 ; LVT # Lo [27] HANGUL SYLLABLE DWAEG..HANGUL SYLLABLE DWAEH
+B419..B433 ; LVT # Lo [27] HANGUL SYLLABLE DOEG..HANGUL SYLLABLE DOEH
+B435..B44F ; LVT # Lo [27] HANGUL SYLLABLE DYOG..HANGUL SYLLABLE DYOH
+B451..B46B ; LVT # Lo [27] HANGUL SYLLABLE DUG..HANGUL SYLLABLE DUH
+B46D..B487 ; LVT # Lo [27] HANGUL SYLLABLE DWEOG..HANGUL SYLLABLE DWEOH
+B489..B4A3 ; LVT # Lo [27] HANGUL SYLLABLE DWEG..HANGUL SYLLABLE DWEH
+B4A5..B4BF ; LVT # Lo [27] HANGUL SYLLABLE DWIG..HANGUL SYLLABLE DWIH
+B4C1..B4DB ; LVT # Lo [27] HANGUL SYLLABLE DYUG..HANGUL SYLLABLE DYUH
+B4DD..B4F7 ; LVT # Lo [27] HANGUL SYLLABLE DEUG..HANGUL SYLLABLE DEUH
+B4F9..B513 ; LVT # Lo [27] HANGUL SYLLABLE DYIG..HANGUL SYLLABLE DYIH
+B515..B52F ; LVT # Lo [27] HANGUL SYLLABLE DIG..HANGUL SYLLABLE DIH
+B531..B54B ; LVT # Lo [27] HANGUL SYLLABLE DDAG..HANGUL SYLLABLE DDAH
+B54D..B567 ; LVT # Lo [27] HANGUL SYLLABLE DDAEG..HANGUL SYLLABLE DDAEH
+B569..B583 ; LVT # Lo [27] HANGUL SYLLABLE DDYAG..HANGUL SYLLABLE DDYAH
+B585..B59F ; LVT # Lo [27] HANGUL SYLLABLE DDYAEG..HANGUL SYLLABLE DDYAEH
+B5A1..B5BB ; LVT # Lo [27] HANGUL SYLLABLE DDEOG..HANGUL SYLLABLE DDEOH
+B5BD..B5D7 ; LVT # Lo [27] HANGUL SYLLABLE DDEG..HANGUL SYLLABLE DDEH
+B5D9..B5F3 ; LVT # Lo [27] HANGUL SYLLABLE DDYEOG..HANGUL SYLLABLE DDYEOH
+B5F5..B60F ; LVT # Lo [27] HANGUL SYLLABLE DDYEG..HANGUL SYLLABLE DDYEH
+B611..B62B ; LVT # Lo [27] HANGUL SYLLABLE DDOG..HANGUL SYLLABLE DDOH
+B62D..B647 ; LVT # Lo [27] HANGUL SYLLABLE DDWAG..HANGUL SYLLABLE DDWAH
+B649..B663 ; LVT # Lo [27] HANGUL SYLLABLE DDWAEG..HANGUL SYLLABLE DDWAEH
+B665..B67F ; LVT # Lo [27] HANGUL SYLLABLE DDOEG..HANGUL SYLLABLE DDOEH
+B681..B69B ; LVT # Lo [27] HANGUL SYLLABLE DDYOG..HANGUL SYLLABLE DDYOH
+B69D..B6B7 ; LVT # Lo [27] HANGUL SYLLABLE DDUG..HANGUL SYLLABLE DDUH
+B6B9..B6D3 ; LVT # Lo [27] HANGUL SYLLABLE DDWEOG..HANGUL SYLLABLE DDWEOH
+B6D5..B6EF ; LVT # Lo [27] HANGUL SYLLABLE DDWEG..HANGUL SYLLABLE DDWEH
+B6F1..B70B ; LVT # Lo [27] HANGUL SYLLABLE DDWIG..HANGUL SYLLABLE DDWIH
+B70D..B727 ; LVT # Lo [27] HANGUL SYLLABLE DDYUG..HANGUL SYLLABLE DDYUH
+B729..B743 ; LVT # Lo [27] HANGUL SYLLABLE DDEUG..HANGUL SYLLABLE DDEUH
+B745..B75F ; LVT # Lo [27] HANGUL SYLLABLE DDYIG..HANGUL SYLLABLE DDYIH
+B761..B77B ; LVT # Lo [27] HANGUL SYLLABLE DDIG..HANGUL SYLLABLE DDIH
+B77D..B797 ; LVT # Lo [27] HANGUL SYLLABLE RAG..HANGUL SYLLABLE RAH
+B799..B7B3 ; LVT # Lo [27] HANGUL SYLLABLE RAEG..HANGUL SYLLABLE RAEH
+B7B5..B7CF ; LVT # Lo [27] HANGUL SYLLABLE RYAG..HANGUL SYLLABLE RYAH
+B7D1..B7EB ; LVT # Lo [27] HANGUL SYLLABLE RYAEG..HANGUL SYLLABLE RYAEH
+B7ED..B807 ; LVT # Lo [27] HANGUL SYLLABLE REOG..HANGUL SYLLABLE REOH
+B809..B823 ; LVT # Lo [27] HANGUL SYLLABLE REG..HANGUL SYLLABLE REH
+B825..B83F ; LVT # Lo [27] HANGUL SYLLABLE RYEOG..HANGUL SYLLABLE RYEOH
+B841..B85B ; LVT # Lo [27] HANGUL SYLLABLE RYEG..HANGUL SYLLABLE RYEH
+B85D..B877 ; LVT # Lo [27] HANGUL SYLLABLE ROG..HANGUL SYLLABLE ROH
+B879..B893 ; LVT # Lo [27] HANGUL SYLLABLE RWAG..HANGUL SYLLABLE RWAH
+B895..B8AF ; LVT # Lo [27] HANGUL SYLLABLE RWAEG..HANGUL SYLLABLE RWAEH
+B8B1..B8CB ; LVT # Lo [27] HANGUL SYLLABLE ROEG..HANGUL SYLLABLE ROEH
+B8CD..B8E7 ; LVT # Lo [27] HANGUL SYLLABLE RYOG..HANGUL SYLLABLE RYOH
+B8E9..B903 ; LVT # Lo [27] HANGUL SYLLABLE RUG..HANGUL SYLLABLE RUH
+B905..B91F ; LVT # Lo [27] HANGUL SYLLABLE RWEOG..HANGUL SYLLABLE RWEOH
+B921..B93B ; LVT # Lo [27] HANGUL SYLLABLE RWEG..HANGUL SYLLABLE RWEH
+B93D..B957 ; LVT # Lo [27] HANGUL SYLLABLE RWIG..HANGUL SYLLABLE RWIH
+B959..B973 ; LVT # Lo [27] HANGUL SYLLABLE RYUG..HANGUL SYLLABLE RYUH
+B975..B98F ; LVT # Lo [27] HANGUL SYLLABLE REUG..HANGUL SYLLABLE REUH
+B991..B9AB ; LVT # Lo [27] HANGUL SYLLABLE RYIG..HANGUL SYLLABLE RYIH
+B9AD..B9C7 ; LVT # Lo [27] HANGUL SYLLABLE RIG..HANGUL SYLLABLE RIH
+B9C9..B9E3 ; LVT # Lo [27] HANGUL SYLLABLE MAG..HANGUL SYLLABLE MAH
+B9E5..B9FF ; LVT # Lo [27] HANGUL SYLLABLE MAEG..HANGUL SYLLABLE MAEH
+BA01..BA1B ; LVT # Lo [27] HANGUL SYLLABLE MYAG..HANGUL SYLLABLE MYAH
+BA1D..BA37 ; LVT # Lo [27] HANGUL SYLLABLE MYAEG..HANGUL SYLLABLE MYAEH
+BA39..BA53 ; LVT # Lo [27] HANGUL SYLLABLE MEOG..HANGUL SYLLABLE MEOH
+BA55..BA6F ; LVT # Lo [27] HANGUL SYLLABLE MEG..HANGUL SYLLABLE MEH
+BA71..BA8B ; LVT # Lo [27] HANGUL SYLLABLE MYEOG..HANGUL SYLLABLE MYEOH
+BA8D..BAA7 ; LVT # Lo [27] HANGUL SYLLABLE MYEG..HANGUL SYLLABLE MYEH
+BAA9..BAC3 ; LVT # Lo [27] HANGUL SYLLABLE MOG..HANGUL SYLLABLE MOH
+BAC5..BADF ; LVT # Lo [27] HANGUL SYLLABLE MWAG..HANGUL SYLLABLE MWAH
+BAE1..BAFB ; LVT # Lo [27] HANGUL SYLLABLE MWAEG..HANGUL SYLLABLE MWAEH
+BAFD..BB17 ; LVT # Lo [27] HANGUL SYLLABLE MOEG..HANGUL SYLLABLE MOEH
+BB19..BB33 ; LVT # Lo [27] HANGUL SYLLABLE MYOG..HANGUL SYLLABLE MYOH
+BB35..BB4F ; LVT # Lo [27] HANGUL SYLLABLE MUG..HANGUL SYLLABLE MUH
+BB51..BB6B ; LVT # Lo [27] HANGUL SYLLABLE MWEOG..HANGUL SYLLABLE MWEOH
+BB6D..BB87 ; LVT # Lo [27] HANGUL SYLLABLE MWEG..HANGUL SYLLABLE MWEH
+BB89..BBA3 ; LVT # Lo [27] HANGUL SYLLABLE MWIG..HANGUL SYLLABLE MWIH
+BBA5..BBBF ; LVT # Lo [27] HANGUL SYLLABLE MYUG..HANGUL SYLLABLE MYUH
+BBC1..BBDB ; LVT # Lo [27] HANGUL SYLLABLE MEUG..HANGUL SYLLABLE MEUH
+BBDD..BBF7 ; LVT # Lo [27] HANGUL SYLLABLE MYIG..HANGUL SYLLABLE MYIH
+BBF9..BC13 ; LVT # Lo [27] HANGUL SYLLABLE MIG..HANGUL SYLLABLE MIH
+BC15..BC2F ; LVT # Lo [27] HANGUL SYLLABLE BAG..HANGUL SYLLABLE BAH
+BC31..BC4B ; LVT # Lo [27] HANGUL SYLLABLE BAEG..HANGUL SYLLABLE BAEH
+BC4D..BC67 ; LVT # Lo [27] HANGUL SYLLABLE BYAG..HANGUL SYLLABLE BYAH
+BC69..BC83 ; LVT # Lo [27] HANGUL SYLLABLE BYAEG..HANGUL SYLLABLE BYAEH
+BC85..BC9F ; LVT # Lo [27] HANGUL SYLLABLE BEOG..HANGUL SYLLABLE BEOH
+BCA1..BCBB ; LVT # Lo [27] HANGUL SYLLABLE BEG..HANGUL SYLLABLE BEH
+BCBD..BCD7 ; LVT # Lo [27] HANGUL SYLLABLE BYEOG..HANGUL SYLLABLE BYEOH
+BCD9..BCF3 ; LVT # Lo [27] HANGUL SYLLABLE BYEG..HANGUL SYLLABLE BYEH
+BCF5..BD0F ; LVT # Lo [27] HANGUL SYLLABLE BOG..HANGUL SYLLABLE BOH
+BD11..BD2B ; LVT # Lo [27] HANGUL SYLLABLE BWAG..HANGUL SYLLABLE BWAH
+BD2D..BD47 ; LVT # Lo [27] HANGUL SYLLABLE BWAEG..HANGUL SYLLABLE BWAEH
+BD49..BD63 ; LVT # Lo [27] HANGUL SYLLABLE BOEG..HANGUL SYLLABLE BOEH
+BD65..BD7F ; LVT # Lo [27] HANGUL SYLLABLE BYOG..HANGUL SYLLABLE BYOH
+BD81..BD9B ; LVT # Lo [27] HANGUL SYLLABLE BUG..HANGUL SYLLABLE BUH
+BD9D..BDB7 ; LVT # Lo [27] HANGUL SYLLABLE BWEOG..HANGUL SYLLABLE BWEOH
+BDB9..BDD3 ; LVT # Lo [27] HANGUL SYLLABLE BWEG..HANGUL SYLLABLE BWEH
+BDD5..BDEF ; LVT # Lo [27] HANGUL SYLLABLE BWIG..HANGUL SYLLABLE BWIH
+BDF1..BE0B ; LVT # Lo [27] HANGUL SYLLABLE BYUG..HANGUL SYLLABLE BYUH
+BE0D..BE27 ; LVT # Lo [27] HANGUL SYLLABLE BEUG..HANGUL SYLLABLE BEUH
+BE29..BE43 ; LVT # Lo [27] HANGUL SYLLABLE BYIG..HANGUL SYLLABLE BYIH
+BE45..BE5F ; LVT # Lo [27] HANGUL SYLLABLE BIG..HANGUL SYLLABLE BIH
+BE61..BE7B ; LVT # Lo [27] HANGUL SYLLABLE BBAG..HANGUL SYLLABLE BBAH
+BE7D..BE97 ; LVT # Lo [27] HANGUL SYLLABLE BBAEG..HANGUL SYLLABLE BBAEH
+BE99..BEB3 ; LVT # Lo [27] HANGUL SYLLABLE BBYAG..HANGUL SYLLABLE BBYAH
+BEB5..BECF ; LVT # Lo [27] HANGUL SYLLABLE BBYAEG..HANGUL SYLLABLE BBYAEH
+BED1..BEEB ; LVT # Lo [27] HANGUL SYLLABLE BBEOG..HANGUL SYLLABLE BBEOH
+BEED..BF07 ; LVT # Lo [27] HANGUL SYLLABLE BBEG..HANGUL SYLLABLE BBEH
+BF09..BF23 ; LVT # Lo [27] HANGUL SYLLABLE BBYEOG..HANGUL SYLLABLE BBYEOH
+BF25..BF3F ; LVT # Lo [27] HANGUL SYLLABLE BBYEG..HANGUL SYLLABLE BBYEH
+BF41..BF5B ; LVT # Lo [27] HANGUL SYLLABLE BBOG..HANGUL SYLLABLE BBOH
+BF5D..BF77 ; LVT # Lo [27] HANGUL SYLLABLE BBWAG..HANGUL SYLLABLE BBWAH
+BF79..BF93 ; LVT # Lo [27] HANGUL SYLLABLE BBWAEG..HANGUL SYLLABLE BBWAEH
+BF95..BFAF ; LVT # Lo [27] HANGUL SYLLABLE BBOEG..HANGUL SYLLABLE BBOEH
+BFB1..BFCB ; LVT # Lo [27] HANGUL SYLLABLE BBYOG..HANGUL SYLLABLE BBYOH
+BFCD..BFE7 ; LVT # Lo [27] HANGUL SYLLABLE BBUG..HANGUL SYLLABLE BBUH
+BFE9..C003 ; LVT # Lo [27] HANGUL SYLLABLE BBWEOG..HANGUL SYLLABLE BBWEOH
+C005..C01F ; LVT # Lo [27] HANGUL SYLLABLE BBWEG..HANGUL SYLLABLE BBWEH
+C021..C03B ; LVT # Lo [27] HANGUL SYLLABLE BBWIG..HANGUL SYLLABLE BBWIH
+C03D..C057 ; LVT # Lo [27] HANGUL SYLLABLE BBYUG..HANGUL SYLLABLE BBYUH
+C059..C073 ; LVT # Lo [27] HANGUL SYLLABLE BBEUG..HANGUL SYLLABLE BBEUH
+C075..C08F ; LVT # Lo [27] HANGUL SYLLABLE BBYIG..HANGUL SYLLABLE BBYIH
+C091..C0AB ; LVT # Lo [27] HANGUL SYLLABLE BBIG..HANGUL SYLLABLE BBIH
+C0AD..C0C7 ; LVT # Lo [27] HANGUL SYLLABLE SAG..HANGUL SYLLABLE SAH
+C0C9..C0E3 ; LVT # Lo [27] HANGUL SYLLABLE SAEG..HANGUL SYLLABLE SAEH
+C0E5..C0FF ; LVT # Lo [27] HANGUL SYLLABLE SYAG..HANGUL SYLLABLE SYAH
+C101..C11B ; LVT # Lo [27] HANGUL SYLLABLE SYAEG..HANGUL SYLLABLE SYAEH
+C11D..C137 ; LVT # Lo [27] HANGUL SYLLABLE SEOG..HANGUL SYLLABLE SEOH
+C139..C153 ; LVT # Lo [27] HANGUL SYLLABLE SEG..HANGUL SYLLABLE SEH
+C155..C16F ; LVT # Lo [27] HANGUL SYLLABLE SYEOG..HANGUL SYLLABLE SYEOH
+C171..C18B ; LVT # Lo [27] HANGUL SYLLABLE SYEG..HANGUL SYLLABLE SYEH
+C18D..C1A7 ; LVT # Lo [27] HANGUL SYLLABLE SOG..HANGUL SYLLABLE SOH
+C1A9..C1C3 ; LVT # Lo [27] HANGUL SYLLABLE SWAG..HANGUL SYLLABLE SWAH
+C1C5..C1DF ; LVT # Lo [27] HANGUL SYLLABLE SWAEG..HANGUL SYLLABLE SWAEH
+C1E1..C1FB ; LVT # Lo [27] HANGUL SYLLABLE SOEG..HANGUL SYLLABLE SOEH
+C1FD..C217 ; LVT # Lo [27] HANGUL SYLLABLE SYOG..HANGUL SYLLABLE SYOH
+C219..C233 ; LVT # Lo [27] HANGUL SYLLABLE SUG..HANGUL SYLLABLE SUH
+C235..C24F ; LVT # Lo [27] HANGUL SYLLABLE SWEOG..HANGUL SYLLABLE SWEOH
+C251..C26B ; LVT # Lo [27] HANGUL SYLLABLE SWEG..HANGUL SYLLABLE SWEH
+C26D..C287 ; LVT # Lo [27] HANGUL SYLLABLE SWIG..HANGUL SYLLABLE SWIH
+C289..C2A3 ; LVT # Lo [27] HANGUL SYLLABLE SYUG..HANGUL SYLLABLE SYUH
+C2A5..C2BF ; LVT # Lo [27] HANGUL SYLLABLE SEUG..HANGUL SYLLABLE SEUH
+C2C1..C2DB ; LVT # Lo [27] HANGUL SYLLABLE SYIG..HANGUL SYLLABLE SYIH
+C2DD..C2F7 ; LVT # Lo [27] HANGUL SYLLABLE SIG..HANGUL SYLLABLE SIH
+C2F9..C313 ; LVT # Lo [27] HANGUL SYLLABLE SSAG..HANGUL SYLLABLE SSAH
+C315..C32F ; LVT # Lo [27] HANGUL SYLLABLE SSAEG..HANGUL SYLLABLE SSAEH
+C331..C34B ; LVT # Lo [27] HANGUL SYLLABLE SSYAG..HANGUL SYLLABLE SSYAH
+C34D..C367 ; LVT # Lo [27] HANGUL SYLLABLE SSYAEG..HANGUL SYLLABLE SSYAEH
+C369..C383 ; LVT # Lo [27] HANGUL SYLLABLE SSEOG..HANGUL SYLLABLE SSEOH
+C385..C39F ; LVT # Lo [27] HANGUL SYLLABLE SSEG..HANGUL SYLLABLE SSEH
+C3A1..C3BB ; LVT # Lo [27] HANGUL SYLLABLE SSYEOG..HANGUL SYLLABLE SSYEOH
+C3BD..C3D7 ; LVT # Lo [27] HANGUL SYLLABLE SSYEG..HANGUL SYLLABLE SSYEH
+C3D9..C3F3 ; LVT # Lo [27] HANGUL SYLLABLE SSOG..HANGUL SYLLABLE SSOH
+C3F5..C40F ; LVT # Lo [27] HANGUL SYLLABLE SSWAG..HANGUL SYLLABLE SSWAH
+C411..C42B ; LVT # Lo [27] HANGUL SYLLABLE SSWAEG..HANGUL SYLLABLE SSWAEH
+C42D..C447 ; LVT # Lo [27] HANGUL SYLLABLE SSOEG..HANGUL SYLLABLE SSOEH
+C449..C463 ; LVT # Lo [27] HANGUL SYLLABLE SSYOG..HANGUL SYLLABLE SSYOH
+C465..C47F ; LVT # Lo [27] HANGUL SYLLABLE SSUG..HANGUL SYLLABLE SSUH
+C481..C49B ; LVT # Lo [27] HANGUL SYLLABLE SSWEOG..HANGUL SYLLABLE SSWEOH
+C49D..C4B7 ; LVT # Lo [27] HANGUL SYLLABLE SSWEG..HANGUL SYLLABLE SSWEH
+C4B9..C4D3 ; LVT # Lo [27] HANGUL SYLLABLE SSWIG..HANGUL SYLLABLE SSWIH
+C4D5..C4EF ; LVT # Lo [27] HANGUL SYLLABLE SSYUG..HANGUL SYLLABLE SSYUH
+C4F1..C50B ; LVT # Lo [27] HANGUL SYLLABLE SSEUG..HANGUL SYLLABLE SSEUH
+C50D..C527 ; LVT # Lo [27] HANGUL SYLLABLE SSYIG..HANGUL SYLLABLE SSYIH
+C529..C543 ; LVT # Lo [27] HANGUL SYLLABLE SSIG..HANGUL SYLLABLE SSIH
+C545..C55F ; LVT # Lo [27] HANGUL SYLLABLE AG..HANGUL SYLLABLE AH
+C561..C57B ; LVT # Lo [27] HANGUL SYLLABLE AEG..HANGUL SYLLABLE AEH
+C57D..C597 ; LVT # Lo [27] HANGUL SYLLABLE YAG..HANGUL SYLLABLE YAH
+C599..C5B3 ; LVT # Lo [27] HANGUL SYLLABLE YAEG..HANGUL SYLLABLE YAEH
+C5B5..C5CF ; LVT # Lo [27] HANGUL SYLLABLE EOG..HANGUL SYLLABLE EOH
+C5D1..C5EB ; LVT # Lo [27] HANGUL SYLLABLE EG..HANGUL SYLLABLE EH
+C5ED..C607 ; LVT # Lo [27] HANGUL SYLLABLE YEOG..HANGUL SYLLABLE YEOH
+C609..C623 ; LVT # Lo [27] HANGUL SYLLABLE YEG..HANGUL SYLLABLE YEH
+C625..C63F ; LVT # Lo [27] HANGUL SYLLABLE OG..HANGUL SYLLABLE OH
+C641..C65B ; LVT # Lo [27] HANGUL SYLLABLE WAG..HANGUL SYLLABLE WAH
+C65D..C677 ; LVT # Lo [27] HANGUL SYLLABLE WAEG..HANGUL SYLLABLE WAEH
+C679..C693 ; LVT # Lo [27] HANGUL SYLLABLE OEG..HANGUL SYLLABLE OEH
+C695..C6AF ; LVT # Lo [27] HANGUL SYLLABLE YOG..HANGUL SYLLABLE YOH
+C6B1..C6CB ; LVT # Lo [27] HANGUL SYLLABLE UG..HANGUL SYLLABLE UH
+C6CD..C6E7 ; LVT # Lo [27] HANGUL SYLLABLE WEOG..HANGUL SYLLABLE WEOH
+C6E9..C703 ; LVT # Lo [27] HANGUL SYLLABLE WEG..HANGUL SYLLABLE WEH
+C705..C71F ; LVT # Lo [27] HANGUL SYLLABLE WIG..HANGUL SYLLABLE WIH
+C721..C73B ; LVT # Lo [27] HANGUL SYLLABLE YUG..HANGUL SYLLABLE YUH
+C73D..C757 ; LVT # Lo [27] HANGUL SYLLABLE EUG..HANGUL SYLLABLE EUH
+C759..C773 ; LVT # Lo [27] HANGUL SYLLABLE YIG..HANGUL SYLLABLE YIH
+C775..C78F ; LVT # Lo [27] HANGUL SYLLABLE IG..HANGUL SYLLABLE IH
+C791..C7AB ; LVT # Lo [27] HANGUL SYLLABLE JAG..HANGUL SYLLABLE JAH
+C7AD..C7C7 ; LVT # Lo [27] HANGUL SYLLABLE JAEG..HANGUL SYLLABLE JAEH
+C7C9..C7E3 ; LVT # Lo [27] HANGUL SYLLABLE JYAG..HANGUL SYLLABLE JYAH
+C7E5..C7FF ; LVT # Lo [27] HANGUL SYLLABLE JYAEG..HANGUL SYLLABLE JYAEH
+C801..C81B ; LVT # Lo [27] HANGUL SYLLABLE JEOG..HANGUL SYLLABLE JEOH
+C81D..C837 ; LVT # Lo [27] HANGUL SYLLABLE JEG..HANGUL SYLLABLE JEH
+C839..C853 ; LVT # Lo [27] HANGUL SYLLABLE JYEOG..HANGUL SYLLABLE JYEOH
+C855..C86F ; LVT # Lo [27] HANGUL SYLLABLE JYEG..HANGUL SYLLABLE JYEH
+C871..C88B ; LVT # Lo [27] HANGUL SYLLABLE JOG..HANGUL SYLLABLE JOH
+C88D..C8A7 ; LVT # Lo [27] HANGUL SYLLABLE JWAG..HANGUL SYLLABLE JWAH
+C8A9..C8C3 ; LVT # Lo [27] HANGUL SYLLABLE JWAEG..HANGUL SYLLABLE JWAEH
+C8C5..C8DF ; LVT # Lo [27] HANGUL SYLLABLE JOEG..HANGUL SYLLABLE JOEH
+C8E1..C8FB ; LVT # Lo [27] HANGUL SYLLABLE JYOG..HANGUL SYLLABLE JYOH
+C8FD..C917 ; LVT # Lo [27] HANGUL SYLLABLE JUG..HANGUL SYLLABLE JUH
+C919..C933 ; LVT # Lo [27] HANGUL SYLLABLE JWEOG..HANGUL SYLLABLE JWEOH
+C935..C94F ; LVT # Lo [27] HANGUL SYLLABLE JWEG..HANGUL SYLLABLE JWEH
+C951..C96B ; LVT # Lo [27] HANGUL SYLLABLE JWIG..HANGUL SYLLABLE JWIH
+C96D..C987 ; LVT # Lo [27] HANGUL SYLLABLE JYUG..HANGUL SYLLABLE JYUH
+C989..C9A3 ; LVT # Lo [27] HANGUL SYLLABLE JEUG..HANGUL SYLLABLE JEUH
+C9A5..C9BF ; LVT # Lo [27] HANGUL SYLLABLE JYIG..HANGUL SYLLABLE JYIH
+C9C1..C9DB ; LVT # Lo [27] HANGUL SYLLABLE JIG..HANGUL SYLLABLE JIH
+C9DD..C9F7 ; LVT # Lo [27] HANGUL SYLLABLE JJAG..HANGUL SYLLABLE JJAH
+C9F9..CA13 ; LVT # Lo [27] HANGUL SYLLABLE JJAEG..HANGUL SYLLABLE JJAEH
+CA15..CA2F ; LVT # Lo [27] HANGUL SYLLABLE JJYAG..HANGUL SYLLABLE JJYAH
+CA31..CA4B ; LVT # Lo [27] HANGUL SYLLABLE JJYAEG..HANGUL SYLLABLE JJYAEH
+CA4D..CA67 ; LVT # Lo [27] HANGUL SYLLABLE JJEOG..HANGUL SYLLABLE JJEOH
+CA69..CA83 ; LVT # Lo [27] HANGUL SYLLABLE JJEG..HANGUL SYLLABLE JJEH
+CA85..CA9F ; LVT # Lo [27] HANGUL SYLLABLE JJYEOG..HANGUL SYLLABLE JJYEOH
+CAA1..CABB ; LVT # Lo [27] HANGUL SYLLABLE JJYEG..HANGUL SYLLABLE JJYEH
+CABD..CAD7 ; LVT # Lo [27] HANGUL SYLLABLE JJOG..HANGUL SYLLABLE JJOH
+CAD9..CAF3 ; LVT # Lo [27] HANGUL SYLLABLE JJWAG..HANGUL SYLLABLE JJWAH
+CAF5..CB0F ; LVT # Lo [27] HANGUL SYLLABLE JJWAEG..HANGUL SYLLABLE JJWAEH
+CB11..CB2B ; LVT # Lo [27] HANGUL SYLLABLE JJOEG..HANGUL SYLLABLE JJOEH
+CB2D..CB47 ; LVT # Lo [27] HANGUL SYLLABLE JJYOG..HANGUL SYLLABLE JJYOH
+CB49..CB63 ; LVT # Lo [27] HANGUL SYLLABLE JJUG..HANGUL SYLLABLE JJUH
+CB65..CB7F ; LVT # Lo [27] HANGUL SYLLABLE JJWEOG..HANGUL SYLLABLE JJWEOH
+CB81..CB9B ; LVT # Lo [27] HANGUL SYLLABLE JJWEG..HANGUL SYLLABLE JJWEH
+CB9D..CBB7 ; LVT # Lo [27] HANGUL SYLLABLE JJWIG..HANGUL SYLLABLE JJWIH
+CBB9..CBD3 ; LVT # Lo [27] HANGUL SYLLABLE JJYUG..HANGUL SYLLABLE JJYUH
+CBD5..CBEF ; LVT # Lo [27] HANGUL SYLLABLE JJEUG..HANGUL SYLLABLE JJEUH
+CBF1..CC0B ; LVT # Lo [27] HANGUL SYLLABLE JJYIG..HANGUL SYLLABLE JJYIH
+CC0D..CC27 ; LVT # Lo [27] HANGUL SYLLABLE JJIG..HANGUL SYLLABLE JJIH
+CC29..CC43 ; LVT # Lo [27] HANGUL SYLLABLE CAG..HANGUL SYLLABLE CAH
+CC45..CC5F ; LVT # Lo [27] HANGUL SYLLABLE CAEG..HANGUL SYLLABLE CAEH
+CC61..CC7B ; LVT # Lo [27] HANGUL SYLLABLE CYAG..HANGUL SYLLABLE CYAH
+CC7D..CC97 ; LVT # Lo [27] HANGUL SYLLABLE CYAEG..HANGUL SYLLABLE CYAEH
+CC99..CCB3 ; LVT # Lo [27] HANGUL SYLLABLE CEOG..HANGUL SYLLABLE CEOH
+CCB5..CCCF ; LVT # Lo [27] HANGUL SYLLABLE CEG..HANGUL SYLLABLE CEH
+CCD1..CCEB ; LVT # Lo [27] HANGUL SYLLABLE CYEOG..HANGUL SYLLABLE CYEOH
+CCED..CD07 ; LVT # Lo [27] HANGUL SYLLABLE CYEG..HANGUL SYLLABLE CYEH
+CD09..CD23 ; LVT # Lo [27] HANGUL SYLLABLE COG..HANGUL SYLLABLE COH
+CD25..CD3F ; LVT # Lo [27] HANGUL SYLLABLE CWAG..HANGUL SYLLABLE CWAH
+CD41..CD5B ; LVT # Lo [27] HANGUL SYLLABLE CWAEG..HANGUL SYLLABLE CWAEH
+CD5D..CD77 ; LVT # Lo [27] HANGUL SYLLABLE COEG..HANGUL SYLLABLE COEH
+CD79..CD93 ; LVT # Lo [27] HANGUL SYLLABLE CYOG..HANGUL SYLLABLE CYOH
+CD95..CDAF ; LVT # Lo [27] HANGUL SYLLABLE CUG..HANGUL SYLLABLE CUH
+CDB1..CDCB ; LVT # Lo [27] HANGUL SYLLABLE CWEOG..HANGUL SYLLABLE CWEOH
+CDCD..CDE7 ; LVT # Lo [27] HANGUL SYLLABLE CWEG..HANGUL SYLLABLE CWEH
+CDE9..CE03 ; LVT # Lo [27] HANGUL SYLLABLE CWIG..HANGUL SYLLABLE CWIH
+CE05..CE1F ; LVT # Lo [27] HANGUL SYLLABLE CYUG..HANGUL SYLLABLE CYUH
+CE21..CE3B ; LVT # Lo [27] HANGUL SYLLABLE CEUG..HANGUL SYLLABLE CEUH
+CE3D..CE57 ; LVT # Lo [27] HANGUL SYLLABLE CYIG..HANGUL SYLLABLE CYIH
+CE59..CE73 ; LVT # Lo [27] HANGUL SYLLABLE CIG..HANGUL SYLLABLE CIH
+CE75..CE8F ; LVT # Lo [27] HANGUL SYLLABLE KAG..HANGUL SYLLABLE KAH
+CE91..CEAB ; LVT # Lo [27] HANGUL SYLLABLE KAEG..HANGUL SYLLABLE KAEH
+CEAD..CEC7 ; LVT # Lo [27] HANGUL SYLLABLE KYAG..HANGUL SYLLABLE KYAH
+CEC9..CEE3 ; LVT # Lo [27] HANGUL SYLLABLE KYAEG..HANGUL SYLLABLE KYAEH
+CEE5..CEFF ; LVT # Lo [27] HANGUL SYLLABLE KEOG..HANGUL SYLLABLE KEOH
+CF01..CF1B ; LVT # Lo [27] HANGUL SYLLABLE KEG..HANGUL SYLLABLE KEH
+CF1D..CF37 ; LVT # Lo [27] HANGUL SYLLABLE KYEOG..HANGUL SYLLABLE KYEOH
+CF39..CF53 ; LVT # Lo [27] HANGUL SYLLABLE KYEG..HANGUL SYLLABLE KYEH
+CF55..CF6F ; LVT # Lo [27] HANGUL SYLLABLE KOG..HANGUL SYLLABLE KOH
+CF71..CF8B ; LVT # Lo [27] HANGUL SYLLABLE KWAG..HANGUL SYLLABLE KWAH
+CF8D..CFA7 ; LVT # Lo [27] HANGUL SYLLABLE KWAEG..HANGUL SYLLABLE KWAEH
+CFA9..CFC3 ; LVT # Lo [27] HANGUL SYLLABLE KOEG..HANGUL SYLLABLE KOEH
+CFC5..CFDF ; LVT # Lo [27] HANGUL SYLLABLE KYOG..HANGUL SYLLABLE KYOH
+CFE1..CFFB ; LVT # Lo [27] HANGUL SYLLABLE KUG..HANGUL SYLLABLE KUH
+CFFD..D017 ; LVT # Lo [27] HANGUL SYLLABLE KWEOG..HANGUL SYLLABLE KWEOH
+D019..D033 ; LVT # Lo [27] HANGUL SYLLABLE KWEG..HANGUL SYLLABLE KWEH
+D035..D04F ; LVT # Lo [27] HANGUL SYLLABLE KWIG..HANGUL SYLLABLE KWIH
+D051..D06B ; LVT # Lo [27] HANGUL SYLLABLE KYUG..HANGUL SYLLABLE KYUH
+D06D..D087 ; LVT # Lo [27] HANGUL SYLLABLE KEUG..HANGUL SYLLABLE KEUH
+D089..D0A3 ; LVT # Lo [27] HANGUL SYLLABLE KYIG..HANGUL SYLLABLE KYIH
+D0A5..D0BF ; LVT # Lo [27] HANGUL SYLLABLE KIG..HANGUL SYLLABLE KIH
+D0C1..D0DB ; LVT # Lo [27] HANGUL SYLLABLE TAG..HANGUL SYLLABLE TAH
+D0DD..D0F7 ; LVT # Lo [27] HANGUL SYLLABLE TAEG..HANGUL SYLLABLE TAEH
+D0F9..D113 ; LVT # Lo [27] HANGUL SYLLABLE TYAG..HANGUL SYLLABLE TYAH
+D115..D12F ; LVT # Lo [27] HANGUL SYLLABLE TYAEG..HANGUL SYLLABLE TYAEH
+D131..D14B ; LVT # Lo [27] HANGUL SYLLABLE TEOG..HANGUL SYLLABLE TEOH
+D14D..D167 ; LVT # Lo [27] HANGUL SYLLABLE TEG..HANGUL SYLLABLE TEH
+D169..D183 ; LVT # Lo [27] HANGUL SYLLABLE TYEOG..HANGUL SYLLABLE TYEOH
+D185..D19F ; LVT # Lo [27] HANGUL SYLLABLE TYEG..HANGUL SYLLABLE TYEH
+D1A1..D1BB ; LVT # Lo [27] HANGUL SYLLABLE TOG..HANGUL SYLLABLE TOH
+D1BD..D1D7 ; LVT # Lo [27] HANGUL SYLLABLE TWAG..HANGUL SYLLABLE TWAH
+D1D9..D1F3 ; LVT # Lo [27] HANGUL SYLLABLE TWAEG..HANGUL SYLLABLE TWAEH
+D1F5..D20F ; LVT # Lo [27] HANGUL SYLLABLE TOEG..HANGUL SYLLABLE TOEH
+D211..D22B ; LVT # Lo [27] HANGUL SYLLABLE TYOG..HANGUL SYLLABLE TYOH
+D22D..D247 ; LVT # Lo [27] HANGUL SYLLABLE TUG..HANGUL SYLLABLE TUH
+D249..D263 ; LVT # Lo [27] HANGUL SYLLABLE TWEOG..HANGUL SYLLABLE TWEOH
+D265..D27F ; LVT # Lo [27] HANGUL SYLLABLE TWEG..HANGUL SYLLABLE TWEH
+D281..D29B ; LVT # Lo [27] HANGUL SYLLABLE TWIG..HANGUL SYLLABLE TWIH
+D29D..D2B7 ; LVT # Lo [27] HANGUL SYLLABLE TYUG..HANGUL SYLLABLE TYUH
+D2B9..D2D3 ; LVT # Lo [27] HANGUL SYLLABLE TEUG..HANGUL SYLLABLE TEUH
+D2D5..D2EF ; LVT # Lo [27] HANGUL SYLLABLE TYIG..HANGUL SYLLABLE TYIH
+D2F1..D30B ; LVT # Lo [27] HANGUL SYLLABLE TIG..HANGUL SYLLABLE TIH
+D30D..D327 ; LVT # Lo [27] HANGUL SYLLABLE PAG..HANGUL SYLLABLE PAH
+D329..D343 ; LVT # Lo [27] HANGUL SYLLABLE PAEG..HANGUL SYLLABLE PAEH
+D345..D35F ; LVT # Lo [27] HANGUL SYLLABLE PYAG..HANGUL SYLLABLE PYAH
+D361..D37B ; LVT # Lo [27] HANGUL SYLLABLE PYAEG..HANGUL SYLLABLE PYAEH
+D37D..D397 ; LVT # Lo [27] HANGUL SYLLABLE PEOG..HANGUL SYLLABLE PEOH
+D399..D3B3 ; LVT # Lo [27] HANGUL SYLLABLE PEG..HANGUL SYLLABLE PEH
+D3B5..D3CF ; LVT # Lo [27] HANGUL SYLLABLE PYEOG..HANGUL SYLLABLE PYEOH
+D3D1..D3EB ; LVT # Lo [27] HANGUL SYLLABLE PYEG..HANGUL SYLLABLE PYEH
+D3ED..D407 ; LVT # Lo [27] HANGUL SYLLABLE POG..HANGUL SYLLABLE POH
+D409..D423 ; LVT # Lo [27] HANGUL SYLLABLE PWAG..HANGUL SYLLABLE PWAH
+D425..D43F ; LVT # Lo [27] HANGUL SYLLABLE PWAEG..HANGUL SYLLABLE PWAEH
+D441..D45B ; LVT # Lo [27] HANGUL SYLLABLE POEG..HANGUL SYLLABLE POEH
+D45D..D477 ; LVT # Lo [27] HANGUL SYLLABLE PYOG..HANGUL SYLLABLE PYOH
+D479..D493 ; LVT # Lo [27] HANGUL SYLLABLE PUG..HANGUL SYLLABLE PUH
+D495..D4AF ; LVT # Lo [27] HANGUL SYLLABLE PWEOG..HANGUL SYLLABLE PWEOH
+D4B1..D4CB ; LVT # Lo [27] HANGUL SYLLABLE PWEG..HANGUL SYLLABLE PWEH
+D4CD..D4E7 ; LVT # Lo [27] HANGUL SYLLABLE PWIG..HANGUL SYLLABLE PWIH
+D4E9..D503 ; LVT # Lo [27] HANGUL SYLLABLE PYUG..HANGUL SYLLABLE PYUH
+D505..D51F ; LVT # Lo [27] HANGUL SYLLABLE PEUG..HANGUL SYLLABLE PEUH
+D521..D53B ; LVT # Lo [27] HANGUL SYLLABLE PYIG..HANGUL SYLLABLE PYIH
+D53D..D557 ; LVT # Lo [27] HANGUL SYLLABLE PIG..HANGUL SYLLABLE PIH
+D559..D573 ; LVT # Lo [27] HANGUL SYLLABLE HAG..HANGUL SYLLABLE HAH
+D575..D58F ; LVT # Lo [27] HANGUL SYLLABLE HAEG..HANGUL SYLLABLE HAEH
+D591..D5AB ; LVT # Lo [27] HANGUL SYLLABLE HYAG..HANGUL SYLLABLE HYAH
+D5AD..D5C7 ; LVT # Lo [27] HANGUL SYLLABLE HYAEG..HANGUL SYLLABLE HYAEH
+D5C9..D5E3 ; LVT # Lo [27] HANGUL SYLLABLE HEOG..HANGUL SYLLABLE HEOH
+D5E5..D5FF ; LVT # Lo [27] HANGUL SYLLABLE HEG..HANGUL SYLLABLE HEH
+D601..D61B ; LVT # Lo [27] HANGUL SYLLABLE HYEOG..HANGUL SYLLABLE HYEOH
+D61D..D637 ; LVT # Lo [27] HANGUL SYLLABLE HYEG..HANGUL SYLLABLE HYEH
+D639..D653 ; LVT # Lo [27] HANGUL SYLLABLE HOG..HANGUL SYLLABLE HOH
+D655..D66F ; LVT # Lo [27] HANGUL SYLLABLE HWAG..HANGUL SYLLABLE HWAH
+D671..D68B ; LVT # Lo [27] HANGUL SYLLABLE HWAEG..HANGUL SYLLABLE HWAEH
+D68D..D6A7 ; LVT # Lo [27] HANGUL SYLLABLE HOEG..HANGUL SYLLABLE HOEH
+D6A9..D6C3 ; LVT # Lo [27] HANGUL SYLLABLE HYOG..HANGUL SYLLABLE HYOH
+D6C5..D6DF ; LVT # Lo [27] HANGUL SYLLABLE HUG..HANGUL SYLLABLE HUH
+D6E1..D6FB ; LVT # Lo [27] HANGUL SYLLABLE HWEOG..HANGUL SYLLABLE HWEOH
+D6FD..D717 ; LVT # Lo [27] HANGUL SYLLABLE HWEG..HANGUL SYLLABLE HWEH
+D719..D733 ; LVT # Lo [27] HANGUL SYLLABLE HWIG..HANGUL SYLLABLE HWIH
+D735..D74F ; LVT # Lo [27] HANGUL SYLLABLE HYUG..HANGUL SYLLABLE HYUH
+D751..D76B ; LVT # Lo [27] HANGUL SYLLABLE HEUG..HANGUL SYLLABLE HEUH
+D76D..D787 ; LVT # Lo [27] HANGUL SYLLABLE HYIG..HANGUL SYLLABLE HYIH
+D789..D7A3 ; LVT # Lo [27] HANGUL SYLLABLE HIG..HANGUL SYLLABLE HIH
+
+# Total code points: 10773
+
+# ================================================
+
+261D ; E_Base # So WHITE UP POINTING INDEX
+26F9 ; E_Base # So PERSON WITH BALL
+270A..270D ; E_Base # So [4] RAISED FIST..WRITING HAND
+1F385 ; E_Base # So FATHER CHRISTMAS
+1F3C3..1F3C4 ; E_Base # So [2] RUNNER..SURFER
+1F3CA..1F3CB ; E_Base # So [2] SWIMMER..WEIGHT LIFTER
+1F442..1F443 ; E_Base # So [2] EAR..NOSE
+1F446..1F450 ; E_Base # So [11] WHITE UP POINTING BACKHAND INDEX..OPEN HANDS SIGN
+1F46E ; E_Base # So POLICE OFFICER
+1F470..1F478 ; E_Base # So [9] BRIDE WITH VEIL..PRINCESS
+1F47C ; E_Base # So BABY ANGEL
+1F481..1F483 ; E_Base # So [3] INFORMATION DESK PERSON..DANCER
+1F485..1F487 ; E_Base # So [3] NAIL POLISH..HAIRCUT
+1F4AA ; E_Base # So FLEXED BICEPS
+1F575 ; E_Base # So SLEUTH OR SPY
+1F57A ; E_Base # So MAN DANCING
+1F590 ; E_Base # So RAISED HAND WITH FINGERS SPLAYED
+1F595..1F596 ; E_Base # So [2] REVERSED HAND WITH MIDDLE FINGER EXTENDED..RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS
+1F645..1F647 ; E_Base # So [3] FACE WITH NO GOOD GESTURE..PERSON BOWING DEEPLY
+1F64B..1F64F ; E_Base # So [5] HAPPY PERSON RAISING ONE HAND..PERSON WITH FOLDED HANDS
+1F6A3 ; E_Base # So ROWBOAT
+1F6B4..1F6B6 ; E_Base # So [3] BICYCLIST..PEDESTRIAN
+1F6C0 ; E_Base # So BATH
+1F918..1F91E ; E_Base # So [7] SIGN OF THE HORNS..HAND WITH INDEX AND MIDDLE FINGERS CROSSED
+1F926 ; E_Base # So FACE PALM
+1F930 ; E_Base # So PREGNANT WOMAN
+1F933..1F939 ; E_Base # So [7] SELFIE..JUGGLING
+1F93C..1F93E ; E_Base # So [3] WRESTLERS..HANDBALL
+
+# Total code points: 79
+
+# ================================================
+
+1F3FB..1F3FF ; E_Modifier # Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6
+
+# Total code points: 5
+
+# ================================================
+
+200D ; ZWJ # Cf ZERO WIDTH JOINER
+
+# Total code points: 1
+
+# ================================================
+
+2764 ; Glue_After_Zwj # So HEAVY BLACK HEART
+1F48B ; Glue_After_Zwj # So KISS MARK
+1F5E8 ; Glue_After_Zwj # So LEFT SPEECH BUBBLE
+
+# Total code points: 3
+
+# ================================================
+
+1F466..1F469 ; E_Base_GAZ # So [4] BOY..WOMAN
+
+# Total code points: 4
+
+# EOF
diff --git a/lib/stdlib/uc_spec/PropList.txt b/lib/stdlib/uc_spec/PropList.txt
new file mode 100644
index 0000000000..a8c0da7135
--- /dev/null
+++ b/lib/stdlib/uc_spec/PropList.txt
@@ -0,0 +1,1579 @@
+# PropList-9.0.0.txt
+# Date: 2016-06-01, 10:34:30 GMT
+# © 2016 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see http://www.unicode.org/reports/tr44/
+
+# ================================================
+
+0009..000D ; White_Space # Cc [5] <control-0009>..<control-000D>
+0020 ; White_Space # Zs SPACE
+0085 ; White_Space # Cc <control-0085>
+00A0 ; White_Space # Zs NO-BREAK SPACE
+1680 ; White_Space # Zs OGHAM SPACE MARK
+2000..200A ; White_Space # Zs [11] EN QUAD..HAIR SPACE
+2028 ; White_Space # Zl LINE SEPARATOR
+2029 ; White_Space # Zp PARAGRAPH SEPARATOR
+202F ; White_Space # Zs NARROW NO-BREAK SPACE
+205F ; White_Space # Zs MEDIUM MATHEMATICAL SPACE
+3000 ; White_Space # Zs IDEOGRAPHIC SPACE
+
+# Total code points: 25
+
+# ================================================
+
+061C ; Bidi_Control # Cf ARABIC LETTER MARK
+200E..200F ; Bidi_Control # Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK
+202A..202E ; Bidi_Control # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
+2066..2069 ; Bidi_Control # Cf [4] LEFT-TO-RIGHT ISOLATE..POP DIRECTIONAL ISOLATE
+
+# Total code points: 12
+
+# ================================================
+
+200C..200D ; Join_Control # Cf [2] ZERO WIDTH NON-JOINER..ZERO WIDTH JOINER
+
+# Total code points: 2
+
+# ================================================
+
+002D ; Dash # Pd HYPHEN-MINUS
+058A ; Dash # Pd ARMENIAN HYPHEN
+05BE ; Dash # Pd HEBREW PUNCTUATION MAQAF
+1400 ; Dash # Pd CANADIAN SYLLABICS HYPHEN
+1806 ; Dash # Pd MONGOLIAN TODO SOFT HYPHEN
+2010..2015 ; Dash # Pd [6] HYPHEN..HORIZONTAL BAR
+2053 ; Dash # Po SWUNG DASH
+207B ; Dash # Sm SUPERSCRIPT MINUS
+208B ; Dash # Sm SUBSCRIPT MINUS
+2212 ; Dash # Sm MINUS SIGN
+2E17 ; Dash # Pd DOUBLE OBLIQUE HYPHEN
+2E1A ; Dash # Pd HYPHEN WITH DIAERESIS
+2E3A..2E3B ; Dash # Pd [2] TWO-EM DASH..THREE-EM DASH
+2E40 ; Dash # Pd DOUBLE HYPHEN
+301C ; Dash # Pd WAVE DASH
+3030 ; Dash # Pd WAVY DASH
+30A0 ; Dash # Pd KATAKANA-HIRAGANA DOUBLE HYPHEN
+FE31..FE32 ; Dash # Pd [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH
+FE58 ; Dash # Pd SMALL EM DASH
+FE63 ; Dash # Pd SMALL HYPHEN-MINUS
+FF0D ; Dash # Pd FULLWIDTH HYPHEN-MINUS
+
+# Total code points: 28
+
+# ================================================
+
+002D ; Hyphen # Pd HYPHEN-MINUS
+00AD ; Hyphen # Cf SOFT HYPHEN
+058A ; Hyphen # Pd ARMENIAN HYPHEN
+1806 ; Hyphen # Pd MONGOLIAN TODO SOFT HYPHEN
+2010..2011 ; Hyphen # Pd [2] HYPHEN..NON-BREAKING HYPHEN
+2E17 ; Hyphen # Pd DOUBLE OBLIQUE HYPHEN
+30FB ; Hyphen # Po KATAKANA MIDDLE DOT
+FE63 ; Hyphen # Pd SMALL HYPHEN-MINUS
+FF0D ; Hyphen # Pd FULLWIDTH HYPHEN-MINUS
+FF65 ; Hyphen # Po HALFWIDTH KATAKANA MIDDLE DOT
+
+# Total code points: 11
+
+# ================================================
+
+0022 ; Quotation_Mark # Po QUOTATION MARK
+0027 ; Quotation_Mark # Po APOSTROPHE
+00AB ; Quotation_Mark # Pi LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+00BB ; Quotation_Mark # Pf RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+2018 ; Quotation_Mark # Pi LEFT SINGLE QUOTATION MARK
+2019 ; Quotation_Mark # Pf RIGHT SINGLE QUOTATION MARK
+201A ; Quotation_Mark # Ps SINGLE LOW-9 QUOTATION MARK
+201B..201C ; Quotation_Mark # Pi [2] SINGLE HIGH-REVERSED-9 QUOTATION MARK..LEFT DOUBLE QUOTATION MARK
+201D ; Quotation_Mark # Pf RIGHT DOUBLE QUOTATION MARK
+201E ; Quotation_Mark # Ps DOUBLE LOW-9 QUOTATION MARK
+201F ; Quotation_Mark # Pi DOUBLE HIGH-REVERSED-9 QUOTATION MARK
+2039 ; Quotation_Mark # Pi SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+203A ; Quotation_Mark # Pf SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+2E42 ; Quotation_Mark # Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK
+300C ; Quotation_Mark # Ps LEFT CORNER BRACKET
+300D ; Quotation_Mark # Pe RIGHT CORNER BRACKET
+300E ; Quotation_Mark # Ps LEFT WHITE CORNER BRACKET
+300F ; Quotation_Mark # Pe RIGHT WHITE CORNER BRACKET
+301D ; Quotation_Mark # Ps REVERSED DOUBLE PRIME QUOTATION MARK
+301E..301F ; Quotation_Mark # Pe [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK
+FE41 ; Quotation_Mark # Ps PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+FE42 ; Quotation_Mark # Pe PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+FE43 ; Quotation_Mark # Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+FE44 ; Quotation_Mark # Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+FF02 ; Quotation_Mark # Po FULLWIDTH QUOTATION MARK
+FF07 ; Quotation_Mark # Po FULLWIDTH APOSTROPHE
+FF62 ; Quotation_Mark # Ps HALFWIDTH LEFT CORNER BRACKET
+FF63 ; Quotation_Mark # Pe HALFWIDTH RIGHT CORNER BRACKET
+
+# Total code points: 30
+
+# ================================================
+
+0021 ; Terminal_Punctuation # Po EXCLAMATION MARK
+002C ; Terminal_Punctuation # Po COMMA
+002E ; Terminal_Punctuation # Po FULL STOP
+003A..003B ; Terminal_Punctuation # Po [2] COLON..SEMICOLON
+003F ; Terminal_Punctuation # Po QUESTION MARK
+037E ; Terminal_Punctuation # Po GREEK QUESTION MARK
+0387 ; Terminal_Punctuation # Po GREEK ANO TELEIA
+0589 ; Terminal_Punctuation # Po ARMENIAN FULL STOP
+05C3 ; Terminal_Punctuation # Po HEBREW PUNCTUATION SOF PASUQ
+060C ; Terminal_Punctuation # Po ARABIC COMMA
+061B ; Terminal_Punctuation # Po ARABIC SEMICOLON
+061F ; Terminal_Punctuation # Po ARABIC QUESTION MARK
+06D4 ; Terminal_Punctuation # Po ARABIC FULL STOP
+0700..070A ; Terminal_Punctuation # Po [11] SYRIAC END OF PARAGRAPH..SYRIAC CONTRACTION
+070C ; Terminal_Punctuation # Po SYRIAC HARKLEAN METOBELUS
+07F8..07F9 ; Terminal_Punctuation # Po [2] NKO COMMA..NKO EXCLAMATION MARK
+0830..083E ; Terminal_Punctuation # Po [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU
+085E ; Terminal_Punctuation # Po MANDAIC PUNCTUATION
+0964..0965 ; Terminal_Punctuation # Po [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA
+0E5A..0E5B ; Terminal_Punctuation # Po [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT
+0F08 ; Terminal_Punctuation # Po TIBETAN MARK SBRUL SHAD
+0F0D..0F12 ; Terminal_Punctuation # Po [6] TIBETAN MARK SHAD..TIBETAN MARK RGYA GRAM SHAD
+104A..104B ; Terminal_Punctuation # Po [2] MYANMAR SIGN LITTLE SECTION..MYANMAR SIGN SECTION
+1361..1368 ; Terminal_Punctuation # Po [8] ETHIOPIC WORDSPACE..ETHIOPIC PARAGRAPH SEPARATOR
+166D..166E ; Terminal_Punctuation # Po [2] CANADIAN SYLLABICS CHI SIGN..CANADIAN SYLLABICS FULL STOP
+16EB..16ED ; Terminal_Punctuation # Po [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION
+1735..1736 ; Terminal_Punctuation # Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION
+17D4..17D6 ; Terminal_Punctuation # Po [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH
+17DA ; Terminal_Punctuation # Po KHMER SIGN KOOMUUT
+1802..1805 ; Terminal_Punctuation # Po [4] MONGOLIAN COMMA..MONGOLIAN FOUR DOTS
+1808..1809 ; Terminal_Punctuation # Po [2] MONGOLIAN MANCHU COMMA..MONGOLIAN MANCHU FULL STOP
+1944..1945 ; Terminal_Punctuation # Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK
+1AA8..1AAB ; Terminal_Punctuation # Po [4] TAI THAM SIGN KAAN..TAI THAM SIGN SATKAANKUU
+1B5A..1B5B ; Terminal_Punctuation # Po [2] BALINESE PANTI..BALINESE PAMADA
+1B5D..1B5F ; Terminal_Punctuation # Po [3] BALINESE CARIK PAMUNGKAH..BALINESE CARIK PAREREN
+1C3B..1C3F ; Terminal_Punctuation # Po [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK
+1C7E..1C7F ; Terminal_Punctuation # Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD
+203C..203D ; Terminal_Punctuation # Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG
+2047..2049 ; Terminal_Punctuation # Po [3] DOUBLE QUESTION MARK..EXCLAMATION QUESTION MARK
+2E2E ; Terminal_Punctuation # Po REVERSED QUESTION MARK
+2E3C ; Terminal_Punctuation # Po STENOGRAPHIC FULL STOP
+2E41 ; Terminal_Punctuation # Po REVERSED COMMA
+3001..3002 ; Terminal_Punctuation # Po [2] IDEOGRAPHIC COMMA..IDEOGRAPHIC FULL STOP
+A4FE..A4FF ; Terminal_Punctuation # Po [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP
+A60D..A60F ; Terminal_Punctuation # Po [3] VAI COMMA..VAI QUESTION MARK
+A6F3..A6F7 ; Terminal_Punctuation # Po [5] BAMUM FULL STOP..BAMUM QUESTION MARK
+A876..A877 ; Terminal_Punctuation # Po [2] PHAGS-PA MARK SHAD..PHAGS-PA MARK DOUBLE SHAD
+A8CE..A8CF ; Terminal_Punctuation # Po [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA
+A92F ; Terminal_Punctuation # Po KAYAH LI SIGN SHYA
+A9C7..A9C9 ; Terminal_Punctuation # Po [3] JAVANESE PADA PANGKAT..JAVANESE PADA LUNGSI
+AA5D..AA5F ; Terminal_Punctuation # Po [3] CHAM PUNCTUATION DANDA..CHAM PUNCTUATION TRIPLE DANDA
+AADF ; Terminal_Punctuation # Po TAI VIET SYMBOL KOI KOI
+AAF0..AAF1 ; Terminal_Punctuation # Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM
+ABEB ; Terminal_Punctuation # Po MEETEI MAYEK CHEIKHEI
+FE50..FE52 ; Terminal_Punctuation # Po [3] SMALL COMMA..SMALL FULL STOP
+FE54..FE57 ; Terminal_Punctuation # Po [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK
+FF01 ; Terminal_Punctuation # Po FULLWIDTH EXCLAMATION MARK
+FF0C ; Terminal_Punctuation # Po FULLWIDTH COMMA
+FF0E ; Terminal_Punctuation # Po FULLWIDTH FULL STOP
+FF1A..FF1B ; Terminal_Punctuation # Po [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON
+FF1F ; Terminal_Punctuation # Po FULLWIDTH QUESTION MARK
+FF61 ; Terminal_Punctuation # Po HALFWIDTH IDEOGRAPHIC FULL STOP
+FF64 ; Terminal_Punctuation # Po HALFWIDTH IDEOGRAPHIC COMMA
+1039F ; Terminal_Punctuation # Po UGARITIC WORD DIVIDER
+103D0 ; Terminal_Punctuation # Po OLD PERSIAN WORD DIVIDER
+10857 ; Terminal_Punctuation # Po IMPERIAL ARAMAIC SECTION SIGN
+1091F ; Terminal_Punctuation # Po PHOENICIAN WORD SEPARATOR
+10A56..10A57 ; Terminal_Punctuation # Po [2] KHAROSHTHI PUNCTUATION DANDA..KHAROSHTHI PUNCTUATION DOUBLE DANDA
+10AF0..10AF5 ; Terminal_Punctuation # Po [6] MANICHAEAN PUNCTUATION STAR..MANICHAEAN PUNCTUATION TWO DOTS
+10B3A..10B3F ; Terminal_Punctuation # Po [6] TINY TWO DOTS OVER ONE DOT PUNCTUATION..LARGE ONE RING OVER TWO RINGS PUNCTUATION
+10B99..10B9C ; Terminal_Punctuation # Po [4] PSALTER PAHLAVI SECTION MARK..PSALTER PAHLAVI FOUR DOTS WITH DOT
+11047..1104D ; Terminal_Punctuation # Po [7] BRAHMI DANDA..BRAHMI PUNCTUATION LOTUS
+110BE..110C1 ; Terminal_Punctuation # Po [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA
+11141..11143 ; Terminal_Punctuation # Po [3] CHAKMA DANDA..CHAKMA QUESTION MARK
+111C5..111C6 ; Terminal_Punctuation # Po [2] SHARADA DANDA..SHARADA DOUBLE DANDA
+111CD ; Terminal_Punctuation # Po SHARADA SUTRA MARK
+111DE..111DF ; Terminal_Punctuation # Po [2] SHARADA SECTION MARK-1..SHARADA SECTION MARK-2
+11238..1123C ; Terminal_Punctuation # Po [5] KHOJKI DANDA..KHOJKI DOUBLE SECTION MARK
+112A9 ; Terminal_Punctuation # Po MULTANI SECTION MARK
+1144B..1144D ; Terminal_Punctuation # Po [3] NEWA DANDA..NEWA COMMA
+1145B ; Terminal_Punctuation # Po NEWA PLACEHOLDER MARK
+115C2..115C5 ; Terminal_Punctuation # Po [4] SIDDHAM DANDA..SIDDHAM SEPARATOR BAR
+115C9..115D7 ; Terminal_Punctuation # Po [15] SIDDHAM END OF TEXT MARK..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES
+11641..11642 ; Terminal_Punctuation # Po [2] MODI DANDA..MODI DOUBLE DANDA
+1173C..1173E ; Terminal_Punctuation # Po [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI
+11C41..11C43 ; Terminal_Punctuation # Po [3] BHAIKSUKI DANDA..BHAIKSUKI WORD SEPARATOR
+11C71 ; Terminal_Punctuation # Po MARCHEN MARK SHAD
+12470..12474 ; Terminal_Punctuation # Po [5] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON
+16A6E..16A6F ; Terminal_Punctuation # Po [2] MRO DANDA..MRO DOUBLE DANDA
+16AF5 ; Terminal_Punctuation # Po BASSA VAH FULL STOP
+16B37..16B39 ; Terminal_Punctuation # Po [3] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN CIM CHEEM
+16B44 ; Terminal_Punctuation # Po PAHAWH HMONG SIGN XAUS
+1BC9F ; Terminal_Punctuation # Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP
+1DA87..1DA8A ; Terminal_Punctuation # Po [4] SIGNWRITING COMMA..SIGNWRITING COLON
+
+# Total code points: 246
+
+# ================================================
+
+005E ; Other_Math # Sk CIRCUMFLEX ACCENT
+03D0..03D2 ; Other_Math # L& [3] GREEK BETA SYMBOL..GREEK UPSILON WITH HOOK SYMBOL
+03D5 ; Other_Math # L& GREEK PHI SYMBOL
+03F0..03F1 ; Other_Math # L& [2] GREEK KAPPA SYMBOL..GREEK RHO SYMBOL
+03F4..03F5 ; Other_Math # L& [2] GREEK CAPITAL THETA SYMBOL..GREEK LUNATE EPSILON SYMBOL
+2016 ; Other_Math # Po DOUBLE VERTICAL LINE
+2032..2034 ; Other_Math # Po [3] PRIME..TRIPLE PRIME
+2040 ; Other_Math # Pc CHARACTER TIE
+2061..2064 ; Other_Math # Cf [4] FUNCTION APPLICATION..INVISIBLE PLUS
+207D ; Other_Math # Ps SUPERSCRIPT LEFT PARENTHESIS
+207E ; Other_Math # Pe SUPERSCRIPT RIGHT PARENTHESIS
+208D ; Other_Math # Ps SUBSCRIPT LEFT PARENTHESIS
+208E ; Other_Math # Pe SUBSCRIPT RIGHT PARENTHESIS
+20D0..20DC ; Other_Math # Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE
+20E1 ; Other_Math # Mn COMBINING LEFT RIGHT ARROW ABOVE
+20E5..20E6 ; Other_Math # Mn [2] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING DOUBLE VERTICAL STROKE OVERLAY
+20EB..20EF ; Other_Math # Mn [5] COMBINING LONG DOUBLE SOLIDUS OVERLAY..COMBINING RIGHT ARROW BELOW
+2102 ; Other_Math # L& DOUBLE-STRUCK CAPITAL C
+2107 ; Other_Math # L& EULER CONSTANT
+210A..2113 ; Other_Math # L& [10] SCRIPT SMALL G..SCRIPT SMALL L
+2115 ; Other_Math # L& DOUBLE-STRUCK CAPITAL N
+2119..211D ; Other_Math # L& [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R
+2124 ; Other_Math # L& DOUBLE-STRUCK CAPITAL Z
+2128 ; Other_Math # L& BLACK-LETTER CAPITAL Z
+2129 ; Other_Math # So TURNED GREEK SMALL LETTER IOTA
+212C..212D ; Other_Math # L& [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C
+212F..2131 ; Other_Math # L& [3] SCRIPT SMALL E..SCRIPT CAPITAL F
+2133..2134 ; Other_Math # L& [2] SCRIPT CAPITAL M..SCRIPT SMALL O
+2135..2138 ; Other_Math # Lo [4] ALEF SYMBOL..DALET SYMBOL
+213C..213F ; Other_Math # L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI
+2145..2149 ; Other_Math # L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J
+2195..2199 ; Other_Math # So [5] UP DOWN ARROW..SOUTH WEST ARROW
+219C..219F ; Other_Math # So [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW
+21A1..21A2 ; Other_Math # So [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL
+21A4..21A5 ; Other_Math # So [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR
+21A7 ; Other_Math # So DOWNWARDS ARROW FROM BAR
+21A9..21AD ; Other_Math # So [5] LEFTWARDS ARROW WITH HOOK..LEFT RIGHT WAVE ARROW
+21B0..21B1 ; Other_Math # So [2] UPWARDS ARROW WITH TIP LEFTWARDS..UPWARDS ARROW WITH TIP RIGHTWARDS
+21B6..21B7 ; Other_Math # So [2] ANTICLOCKWISE TOP SEMICIRCLE ARROW..CLOCKWISE TOP SEMICIRCLE ARROW
+21BC..21CD ; Other_Math # So [18] LEFTWARDS HARPOON WITH BARB UPWARDS..LEFTWARDS DOUBLE ARROW WITH STROKE
+21D0..21D1 ; Other_Math # So [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW
+21D3 ; Other_Math # So DOWNWARDS DOUBLE ARROW
+21D5..21DB ; Other_Math # So [7] UP DOWN DOUBLE ARROW..RIGHTWARDS TRIPLE ARROW
+21DD ; Other_Math # So RIGHTWARDS SQUIGGLE ARROW
+21E4..21E5 ; Other_Math # So [2] LEFTWARDS ARROW TO BAR..RIGHTWARDS ARROW TO BAR
+2308 ; Other_Math # Ps LEFT CEILING
+2309 ; Other_Math # Pe RIGHT CEILING
+230A ; Other_Math # Ps LEFT FLOOR
+230B ; Other_Math # Pe RIGHT FLOOR
+23B4..23B5 ; Other_Math # So [2] TOP SQUARE BRACKET..BOTTOM SQUARE BRACKET
+23B7 ; Other_Math # So RADICAL SYMBOL BOTTOM
+23D0 ; Other_Math # So VERTICAL LINE EXTENSION
+23E2 ; Other_Math # So WHITE TRAPEZIUM
+25A0..25A1 ; Other_Math # So [2] BLACK SQUARE..WHITE SQUARE
+25AE..25B6 ; Other_Math # So [9] BLACK VERTICAL RECTANGLE..BLACK RIGHT-POINTING TRIANGLE
+25BC..25C0 ; Other_Math # So [5] BLACK DOWN-POINTING TRIANGLE..BLACK LEFT-POINTING TRIANGLE
+25C6..25C7 ; Other_Math # So [2] BLACK DIAMOND..WHITE DIAMOND
+25CA..25CB ; Other_Math # So [2] LOZENGE..WHITE CIRCLE
+25CF..25D3 ; Other_Math # So [5] BLACK CIRCLE..CIRCLE WITH UPPER HALF BLACK
+25E2 ; Other_Math # So BLACK LOWER RIGHT TRIANGLE
+25E4 ; Other_Math # So BLACK UPPER LEFT TRIANGLE
+25E7..25EC ; Other_Math # So [6] SQUARE WITH LEFT HALF BLACK..WHITE UP-POINTING TRIANGLE WITH DOT
+2605..2606 ; Other_Math # So [2] BLACK STAR..WHITE STAR
+2640 ; Other_Math # So FEMALE SIGN
+2642 ; Other_Math # So MALE SIGN
+2660..2663 ; Other_Math # So [4] BLACK SPADE SUIT..BLACK CLUB SUIT
+266D..266E ; Other_Math # So [2] MUSIC FLAT SIGN..MUSIC NATURAL SIGN
+27C5 ; Other_Math # Ps LEFT S-SHAPED BAG DELIMITER
+27C6 ; Other_Math # Pe RIGHT S-SHAPED BAG DELIMITER
+27E6 ; Other_Math # Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET
+27E7 ; Other_Math # Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET
+27E8 ; Other_Math # Ps MATHEMATICAL LEFT ANGLE BRACKET
+27E9 ; Other_Math # Pe MATHEMATICAL RIGHT ANGLE BRACKET
+27EA ; Other_Math # Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
+27EB ; Other_Math # Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
+27EC ; Other_Math # Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
+27ED ; Other_Math # Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
+27EE ; Other_Math # Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS
+27EF ; Other_Math # Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS
+2983 ; Other_Math # Ps LEFT WHITE CURLY BRACKET
+2984 ; Other_Math # Pe RIGHT WHITE CURLY BRACKET
+2985 ; Other_Math # Ps LEFT WHITE PARENTHESIS
+2986 ; Other_Math # Pe RIGHT WHITE PARENTHESIS
+2987 ; Other_Math # Ps Z NOTATION LEFT IMAGE BRACKET
+2988 ; Other_Math # Pe Z NOTATION RIGHT IMAGE BRACKET
+2989 ; Other_Math # Ps Z NOTATION LEFT BINDING BRACKET
+298A ; Other_Math # Pe Z NOTATION RIGHT BINDING BRACKET
+298B ; Other_Math # Ps LEFT SQUARE BRACKET WITH UNDERBAR
+298C ; Other_Math # Pe RIGHT SQUARE BRACKET WITH UNDERBAR
+298D ; Other_Math # Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
+298E ; Other_Math # Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+298F ; Other_Math # Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+2990 ; Other_Math # Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
+2991 ; Other_Math # Ps LEFT ANGLE BRACKET WITH DOT
+2992 ; Other_Math # Pe RIGHT ANGLE BRACKET WITH DOT
+2993 ; Other_Math # Ps LEFT ARC LESS-THAN BRACKET
+2994 ; Other_Math # Pe RIGHT ARC GREATER-THAN BRACKET
+2995 ; Other_Math # Ps DOUBLE LEFT ARC GREATER-THAN BRACKET
+2996 ; Other_Math # Pe DOUBLE RIGHT ARC LESS-THAN BRACKET
+2997 ; Other_Math # Ps LEFT BLACK TORTOISE SHELL BRACKET
+2998 ; Other_Math # Pe RIGHT BLACK TORTOISE SHELL BRACKET
+29D8 ; Other_Math # Ps LEFT WIGGLY FENCE
+29D9 ; Other_Math # Pe RIGHT WIGGLY FENCE
+29DA ; Other_Math # Ps LEFT DOUBLE WIGGLY FENCE
+29DB ; Other_Math # Pe RIGHT DOUBLE WIGGLY FENCE
+29FC ; Other_Math # Ps LEFT-POINTING CURVED ANGLE BRACKET
+29FD ; Other_Math # Pe RIGHT-POINTING CURVED ANGLE BRACKET
+FE61 ; Other_Math # Po SMALL ASTERISK
+FE63 ; Other_Math # Pd SMALL HYPHEN-MINUS
+FE68 ; Other_Math # Po SMALL REVERSE SOLIDUS
+FF3C ; Other_Math # Po FULLWIDTH REVERSE SOLIDUS
+FF3E ; Other_Math # Sk FULLWIDTH CIRCUMFLEX ACCENT
+1D400..1D454 ; Other_Math # L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G
+1D456..1D49C ; Other_Math # L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A
+1D49E..1D49F ; Other_Math # L& [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D
+1D4A2 ; Other_Math # L& MATHEMATICAL SCRIPT CAPITAL G
+1D4A5..1D4A6 ; Other_Math # L& [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K
+1D4A9..1D4AC ; Other_Math # L& [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q
+1D4AE..1D4B9 ; Other_Math # L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D
+1D4BB ; Other_Math # L& MATHEMATICAL SCRIPT SMALL F
+1D4BD..1D4C3 ; Other_Math # L& [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N
+1D4C5..1D505 ; Other_Math # L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B
+1D507..1D50A ; Other_Math # L& [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G
+1D50D..1D514 ; Other_Math # L& [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q
+1D516..1D51C ; Other_Math # L& [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y
+1D51E..1D539 ; Other_Math # L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B
+1D53B..1D53E ; Other_Math # L& [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G
+1D540..1D544 ; Other_Math # L& [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M
+1D546 ; Other_Math # L& MATHEMATICAL DOUBLE-STRUCK CAPITAL O
+1D54A..1D550 ; Other_Math # L& [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y
+1D552..1D6A5 ; Other_Math # L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J
+1D6A8..1D6C0 ; Other_Math # L& [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA
+1D6C2..1D6DA ; Other_Math # L& [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA
+1D6DC..1D6FA ; Other_Math # L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA
+1D6FC..1D714 ; Other_Math # L& [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA
+1D716..1D734 ; Other_Math # L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
+1D736..1D74E ; Other_Math # L& [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA
+1D750..1D76E ; Other_Math # L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
+1D770..1D788 ; Other_Math # L& [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
+1D78A..1D7A8 ; Other_Math # L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
+1D7AA..1D7C2 ; Other_Math # L& [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
+1D7C4..1D7CB ; Other_Math # L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA
+1D7CE..1D7FF ; Other_Math # Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE
+1EE00..1EE03 ; Other_Math # Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL
+1EE05..1EE1F ; Other_Math # Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF
+1EE21..1EE22 ; Other_Math # Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM
+1EE24 ; Other_Math # Lo ARABIC MATHEMATICAL INITIAL HEH
+1EE27 ; Other_Math # Lo ARABIC MATHEMATICAL INITIAL HAH
+1EE29..1EE32 ; Other_Math # Lo [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF
+1EE34..1EE37 ; Other_Math # Lo [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH
+1EE39 ; Other_Math # Lo ARABIC MATHEMATICAL INITIAL DAD
+1EE3B ; Other_Math # Lo ARABIC MATHEMATICAL INITIAL GHAIN
+1EE42 ; Other_Math # Lo ARABIC MATHEMATICAL TAILED JEEM
+1EE47 ; Other_Math # Lo ARABIC MATHEMATICAL TAILED HAH
+1EE49 ; Other_Math # Lo ARABIC MATHEMATICAL TAILED YEH
+1EE4B ; Other_Math # Lo ARABIC MATHEMATICAL TAILED LAM
+1EE4D..1EE4F ; Other_Math # Lo [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN
+1EE51..1EE52 ; Other_Math # Lo [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF
+1EE54 ; Other_Math # Lo ARABIC MATHEMATICAL TAILED SHEEN
+1EE57 ; Other_Math # Lo ARABIC MATHEMATICAL TAILED KHAH
+1EE59 ; Other_Math # Lo ARABIC MATHEMATICAL TAILED DAD
+1EE5B ; Other_Math # Lo ARABIC MATHEMATICAL TAILED GHAIN
+1EE5D ; Other_Math # Lo ARABIC MATHEMATICAL TAILED DOTLESS NOON
+1EE5F ; Other_Math # Lo ARABIC MATHEMATICAL TAILED DOTLESS QAF
+1EE61..1EE62 ; Other_Math # Lo [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM
+1EE64 ; Other_Math # Lo ARABIC MATHEMATICAL STRETCHED HEH
+1EE67..1EE6A ; Other_Math # Lo [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF
+1EE6C..1EE72 ; Other_Math # Lo [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF
+1EE74..1EE77 ; Other_Math # Lo [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH
+1EE79..1EE7C ; Other_Math # Lo [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH
+1EE7E ; Other_Math # Lo ARABIC MATHEMATICAL STRETCHED DOTLESS FEH
+1EE80..1EE89 ; Other_Math # Lo [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH
+1EE8B..1EE9B ; Other_Math # Lo [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN
+1EEA1..1EEA3 ; Other_Math # Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL
+1EEA5..1EEA9 ; Other_Math # Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH
+1EEAB..1EEBB ; Other_Math # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
+
+# Total code points: 1362
+
+# ================================================
+
+0030..0039 ; Hex_Digit # Nd [10] DIGIT ZERO..DIGIT NINE
+0041..0046 ; Hex_Digit # L& [6] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER F
+0061..0066 ; Hex_Digit # L& [6] LATIN SMALL LETTER A..LATIN SMALL LETTER F
+FF10..FF19 ; Hex_Digit # Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE
+FF21..FF26 ; Hex_Digit # L& [6] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER F
+FF41..FF46 ; Hex_Digit # L& [6] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER F
+
+# Total code points: 44
+
+# ================================================
+
+0030..0039 ; ASCII_Hex_Digit # Nd [10] DIGIT ZERO..DIGIT NINE
+0041..0046 ; ASCII_Hex_Digit # L& [6] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER F
+0061..0066 ; ASCII_Hex_Digit # L& [6] LATIN SMALL LETTER A..LATIN SMALL LETTER F
+
+# Total code points: 22
+
+# ================================================
+
+0345 ; Other_Alphabetic # Mn COMBINING GREEK YPOGEGRAMMENI
+05B0..05BD ; Other_Alphabetic # Mn [14] HEBREW POINT SHEVA..HEBREW POINT METEG
+05BF ; Other_Alphabetic # Mn HEBREW POINT RAFE
+05C1..05C2 ; Other_Alphabetic # Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
+05C4..05C5 ; Other_Alphabetic # Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT
+05C7 ; Other_Alphabetic # Mn HEBREW POINT QAMATS QATAN
+0610..061A ; Other_Alphabetic # Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA
+064B..0657 ; Other_Alphabetic # Mn [13] ARABIC FATHATAN..ARABIC INVERTED DAMMA
+0659..065F ; Other_Alphabetic # Mn [7] ARABIC ZWARAKAY..ARABIC WAVY HAMZA BELOW
+0670 ; Other_Alphabetic # Mn ARABIC LETTER SUPERSCRIPT ALEF
+06D6..06DC ; Other_Alphabetic # Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
+06E1..06E4 ; Other_Alphabetic # Mn [4] ARABIC SMALL HIGH DOTLESS HEAD OF KHAH..ARABIC SMALL HIGH MADDA
+06E7..06E8 ; Other_Alphabetic # Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
+06ED ; Other_Alphabetic # Mn ARABIC SMALL LOW MEEM
+0711 ; Other_Alphabetic # Mn SYRIAC LETTER SUPERSCRIPT ALAPH
+0730..073F ; Other_Alphabetic # Mn [16] SYRIAC PTHAHA ABOVE..SYRIAC RWAHA
+07A6..07B0 ; Other_Alphabetic # Mn [11] THAANA ABAFILI..THAANA SUKUN
+0816..0817 ; Other_Alphabetic # Mn [2] SAMARITAN MARK IN..SAMARITAN MARK IN-ALAF
+081B..0823 ; Other_Alphabetic # Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A
+0825..0827 ; Other_Alphabetic # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U
+0829..082C ; Other_Alphabetic # Mn [4] SAMARITAN VOWEL SIGN LONG I..SAMARITAN VOWEL SIGN SUKUN
+08D4..08DF ; Other_Alphabetic # Mn [12] ARABIC SMALL HIGH WORD AR-RUB..ARABIC SMALL HIGH WORD WAQFA
+08E3..08E9 ; Other_Alphabetic # Mn [7] ARABIC TURNED DAMMA BELOW..ARABIC CURLY KASRATAN
+08F0..0902 ; Other_Alphabetic # Mn [19] ARABIC OPEN FATHATAN..DEVANAGARI SIGN ANUSVARA
+0903 ; Other_Alphabetic # Mc DEVANAGARI SIGN VISARGA
+093A ; Other_Alphabetic # Mn DEVANAGARI VOWEL SIGN OE
+093B ; Other_Alphabetic # Mc DEVANAGARI VOWEL SIGN OOE
+093E..0940 ; Other_Alphabetic # Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II
+0941..0948 ; Other_Alphabetic # Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
+0949..094C ; Other_Alphabetic # Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU
+094E..094F ; Other_Alphabetic # Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW
+0955..0957 ; Other_Alphabetic # Mn [3] DEVANAGARI VOWEL SIGN CANDRA LONG E..DEVANAGARI VOWEL SIGN UUE
+0962..0963 ; Other_Alphabetic # Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
+0981 ; Other_Alphabetic # Mn BENGALI SIGN CANDRABINDU
+0982..0983 ; Other_Alphabetic # Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA
+09BE..09C0 ; Other_Alphabetic # Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II
+09C1..09C4 ; Other_Alphabetic # Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR
+09C7..09C8 ; Other_Alphabetic # Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
+09CB..09CC ; Other_Alphabetic # Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU
+09D7 ; Other_Alphabetic # Mc BENGALI AU LENGTH MARK
+09E2..09E3 ; Other_Alphabetic # Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
+0A01..0A02 ; Other_Alphabetic # Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI
+0A03 ; Other_Alphabetic # Mc GURMUKHI SIGN VISARGA
+0A3E..0A40 ; Other_Alphabetic # Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II
+0A41..0A42 ; Other_Alphabetic # Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU
+0A47..0A48 ; Other_Alphabetic # Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
+0A4B..0A4C ; Other_Alphabetic # Mn [2] GURMUKHI VOWEL SIGN OO..GURMUKHI VOWEL SIGN AU
+0A51 ; Other_Alphabetic # Mn GURMUKHI SIGN UDAAT
+0A70..0A71 ; Other_Alphabetic # Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK
+0A75 ; Other_Alphabetic # Mn GURMUKHI SIGN YAKASH
+0A81..0A82 ; Other_Alphabetic # Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA
+0A83 ; Other_Alphabetic # Mc GUJARATI SIGN VISARGA
+0ABE..0AC0 ; Other_Alphabetic # Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II
+0AC1..0AC5 ; Other_Alphabetic # Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E
+0AC7..0AC8 ; Other_Alphabetic # Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI
+0AC9 ; Other_Alphabetic # Mc GUJARATI VOWEL SIGN CANDRA O
+0ACB..0ACC ; Other_Alphabetic # Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU
+0AE2..0AE3 ; Other_Alphabetic # Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL
+0B01 ; Other_Alphabetic # Mn ORIYA SIGN CANDRABINDU
+0B02..0B03 ; Other_Alphabetic # Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA
+0B3E ; Other_Alphabetic # Mc ORIYA VOWEL SIGN AA
+0B3F ; Other_Alphabetic # Mn ORIYA VOWEL SIGN I
+0B40 ; Other_Alphabetic # Mc ORIYA VOWEL SIGN II
+0B41..0B44 ; Other_Alphabetic # Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
+0B47..0B48 ; Other_Alphabetic # Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
+0B4B..0B4C ; Other_Alphabetic # Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
+0B56 ; Other_Alphabetic # Mn ORIYA AI LENGTH MARK
+0B57 ; Other_Alphabetic # Mc ORIYA AU LENGTH MARK
+0B62..0B63 ; Other_Alphabetic # Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
+0B82 ; Other_Alphabetic # Mn TAMIL SIGN ANUSVARA
+0BBE..0BBF ; Other_Alphabetic # Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I
+0BC0 ; Other_Alphabetic # Mn TAMIL VOWEL SIGN II
+0BC1..0BC2 ; Other_Alphabetic # Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU
+0BC6..0BC8 ; Other_Alphabetic # Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
+0BCA..0BCC ; Other_Alphabetic # Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU
+0BD7 ; Other_Alphabetic # Mc TAMIL AU LENGTH MARK
+0C00 ; Other_Alphabetic # Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE
+0C01..0C03 ; Other_Alphabetic # Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
+0C3E..0C40 ; Other_Alphabetic # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II
+0C41..0C44 ; Other_Alphabetic # Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR
+0C46..0C48 ; Other_Alphabetic # Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
+0C4A..0C4C ; Other_Alphabetic # Mn [3] TELUGU VOWEL SIGN O..TELUGU VOWEL SIGN AU
+0C55..0C56 ; Other_Alphabetic # Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
+0C62..0C63 ; Other_Alphabetic # Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL
+0C81 ; Other_Alphabetic # Mn KANNADA SIGN CANDRABINDU
+0C82..0C83 ; Other_Alphabetic # Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
+0CBE ; Other_Alphabetic # Mc KANNADA VOWEL SIGN AA
+0CBF ; Other_Alphabetic # Mn KANNADA VOWEL SIGN I
+0CC0..0CC4 ; Other_Alphabetic # Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR
+0CC6 ; Other_Alphabetic # Mn KANNADA VOWEL SIGN E
+0CC7..0CC8 ; Other_Alphabetic # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI
+0CCA..0CCB ; Other_Alphabetic # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO
+0CCC ; Other_Alphabetic # Mn KANNADA VOWEL SIGN AU
+0CD5..0CD6 ; Other_Alphabetic # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
+0CE2..0CE3 ; Other_Alphabetic # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
+0D01 ; Other_Alphabetic # Mn MALAYALAM SIGN CANDRABINDU
+0D02..0D03 ; Other_Alphabetic # Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
+0D3E..0D40 ; Other_Alphabetic # Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II
+0D41..0D44 ; Other_Alphabetic # Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
+0D46..0D48 ; Other_Alphabetic # Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
+0D4A..0D4C ; Other_Alphabetic # Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU
+0D57 ; Other_Alphabetic # Mc MALAYALAM AU LENGTH MARK
+0D62..0D63 ; Other_Alphabetic # Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
+0D82..0D83 ; Other_Alphabetic # Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
+0DCF..0DD1 ; Other_Alphabetic # Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA
+0DD2..0DD4 ; Other_Alphabetic # Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
+0DD6 ; Other_Alphabetic # Mn SINHALA VOWEL SIGN DIGA PAA-PILLA
+0DD8..0DDF ; Other_Alphabetic # Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA
+0DF2..0DF3 ; Other_Alphabetic # Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
+0E31 ; Other_Alphabetic # Mn THAI CHARACTER MAI HAN-AKAT
+0E34..0E3A ; Other_Alphabetic # Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
+0E4D ; Other_Alphabetic # Mn THAI CHARACTER NIKHAHIT
+0EB1 ; Other_Alphabetic # Mn LAO VOWEL SIGN MAI KAN
+0EB4..0EB9 ; Other_Alphabetic # Mn [6] LAO VOWEL SIGN I..LAO VOWEL SIGN UU
+0EBB..0EBC ; Other_Alphabetic # Mn [2] LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO
+0ECD ; Other_Alphabetic # Mn LAO NIGGAHITA
+0F71..0F7E ; Other_Alphabetic # Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO
+0F7F ; Other_Alphabetic # Mc TIBETAN SIGN RNAM BCAD
+0F80..0F81 ; Other_Alphabetic # Mn [2] TIBETAN VOWEL SIGN REVERSED I..TIBETAN VOWEL SIGN REVERSED II
+0F8D..0F97 ; Other_Alphabetic # Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA
+0F99..0FBC ; Other_Alphabetic # Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
+102B..102C ; Other_Alphabetic # Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA
+102D..1030 ; Other_Alphabetic # Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU
+1031 ; Other_Alphabetic # Mc MYANMAR VOWEL SIGN E
+1032..1036 ; Other_Alphabetic # Mn [5] MYANMAR VOWEL SIGN AI..MYANMAR SIGN ANUSVARA
+1038 ; Other_Alphabetic # Mc MYANMAR SIGN VISARGA
+103B..103C ; Other_Alphabetic # Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA
+103D..103E ; Other_Alphabetic # Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA
+1056..1057 ; Other_Alphabetic # Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR
+1058..1059 ; Other_Alphabetic # Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL
+105E..1060 ; Other_Alphabetic # Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA
+1062 ; Other_Alphabetic # Mc MYANMAR VOWEL SIGN SGAW KAREN EU
+1067..1068 ; Other_Alphabetic # Mc [2] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR VOWEL SIGN WESTERN PWO KAREN UE
+1071..1074 ; Other_Alphabetic # Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE
+1082 ; Other_Alphabetic # Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA
+1083..1084 ; Other_Alphabetic # Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E
+1085..1086 ; Other_Alphabetic # Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y
+109C ; Other_Alphabetic # Mc MYANMAR VOWEL SIGN AITON A
+109D ; Other_Alphabetic # Mn MYANMAR VOWEL SIGN AITON AI
+135F ; Other_Alphabetic # Mn ETHIOPIC COMBINING GEMINATION MARK
+1712..1713 ; Other_Alphabetic # Mn [2] TAGALOG VOWEL SIGN I..TAGALOG VOWEL SIGN U
+1732..1733 ; Other_Alphabetic # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U
+1752..1753 ; Other_Alphabetic # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U
+1772..1773 ; Other_Alphabetic # Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U
+17B6 ; Other_Alphabetic # Mc KHMER VOWEL SIGN AA
+17B7..17BD ; Other_Alphabetic # Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA
+17BE..17C5 ; Other_Alphabetic # Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU
+17C6 ; Other_Alphabetic # Mn KHMER SIGN NIKAHIT
+17C7..17C8 ; Other_Alphabetic # Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU
+1885..1886 ; Other_Alphabetic # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA
+18A9 ; Other_Alphabetic # Mn MONGOLIAN LETTER ALI GALI DAGALGA
+1920..1922 ; Other_Alphabetic # Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U
+1923..1926 ; Other_Alphabetic # Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU
+1927..1928 ; Other_Alphabetic # Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O
+1929..192B ; Other_Alphabetic # Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
+1930..1931 ; Other_Alphabetic # Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
+1932 ; Other_Alphabetic # Mn LIMBU SMALL LETTER ANUSVARA
+1933..1938 ; Other_Alphabetic # Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
+1A17..1A18 ; Other_Alphabetic # Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
+1A19..1A1A ; Other_Alphabetic # Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
+1A1B ; Other_Alphabetic # Mn BUGINESE VOWEL SIGN AE
+1A55 ; Other_Alphabetic # Mc TAI THAM CONSONANT SIGN MEDIAL RA
+1A56 ; Other_Alphabetic # Mn TAI THAM CONSONANT SIGN MEDIAL LA
+1A57 ; Other_Alphabetic # Mc TAI THAM CONSONANT SIGN LA TANG LAI
+1A58..1A5E ; Other_Alphabetic # Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA
+1A61 ; Other_Alphabetic # Mc TAI THAM VOWEL SIGN A
+1A62 ; Other_Alphabetic # Mn TAI THAM VOWEL SIGN MAI SAT
+1A63..1A64 ; Other_Alphabetic # Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA
+1A65..1A6C ; Other_Alphabetic # Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW
+1A6D..1A72 ; Other_Alphabetic # Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI
+1A73..1A74 ; Other_Alphabetic # Mn [2] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN MAI KANG
+1B00..1B03 ; Other_Alphabetic # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
+1B04 ; Other_Alphabetic # Mc BALINESE SIGN BISAH
+1B35 ; Other_Alphabetic # Mc BALINESE VOWEL SIGN TEDUNG
+1B36..1B3A ; Other_Alphabetic # Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
+1B3B ; Other_Alphabetic # Mc BALINESE VOWEL SIGN RA REPA TEDUNG
+1B3C ; Other_Alphabetic # Mn BALINESE VOWEL SIGN LA LENGA
+1B3D..1B41 ; Other_Alphabetic # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG
+1B42 ; Other_Alphabetic # Mn BALINESE VOWEL SIGN PEPET
+1B43 ; Other_Alphabetic # Mc BALINESE VOWEL SIGN PEPET TEDUNG
+1B80..1B81 ; Other_Alphabetic # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR
+1B82 ; Other_Alphabetic # Mc SUNDANESE SIGN PANGWISAD
+1BA1 ; Other_Alphabetic # Mc SUNDANESE CONSONANT SIGN PAMINGKAL
+1BA2..1BA5 ; Other_Alphabetic # Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU
+1BA6..1BA7 ; Other_Alphabetic # Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG
+1BA8..1BA9 ; Other_Alphabetic # Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG
+1BAC..1BAD ; Other_Alphabetic # Mn [2] SUNDANESE CONSONANT SIGN PASANGAN MA..SUNDANESE CONSONANT SIGN PASANGAN WA
+1BE7 ; Other_Alphabetic # Mc BATAK VOWEL SIGN E
+1BE8..1BE9 ; Other_Alphabetic # Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE
+1BEA..1BEC ; Other_Alphabetic # Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O
+1BED ; Other_Alphabetic # Mn BATAK VOWEL SIGN KARO O
+1BEE ; Other_Alphabetic # Mc BATAK VOWEL SIGN U
+1BEF..1BF1 ; Other_Alphabetic # Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H
+1C24..1C2B ; Other_Alphabetic # Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU
+1C2C..1C33 ; Other_Alphabetic # Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T
+1C34..1C35 ; Other_Alphabetic # Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG
+1CF2..1CF3 ; Other_Alphabetic # Mc [2] VEDIC SIGN ARDHAVISARGA..VEDIC SIGN ROTATED ARDHAVISARGA
+1DE7..1DF4 ; Other_Alphabetic # Mn [14] COMBINING LATIN SMALL LETTER ALPHA..COMBINING LATIN SMALL LETTER U WITH DIAERESIS
+24B6..24E9 ; Other_Alphabetic # So [52] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN SMALL LETTER Z
+2DE0..2DFF ; Other_Alphabetic # Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS
+A674..A67B ; Other_Alphabetic # Mn [8] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC LETTER OMEGA
+A69E..A69F ; Other_Alphabetic # Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E
+A823..A824 ; Other_Alphabetic # Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
+A825..A826 ; Other_Alphabetic # Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
+A827 ; Other_Alphabetic # Mc SYLOTI NAGRI VOWEL SIGN OO
+A880..A881 ; Other_Alphabetic # Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
+A8B4..A8C3 ; Other_Alphabetic # Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU
+A8C5 ; Other_Alphabetic # Mn SAURASHTRA SIGN CANDRABINDU
+A926..A92A ; Other_Alphabetic # Mn [5] KAYAH LI VOWEL UE..KAYAH LI VOWEL O
+A947..A951 ; Other_Alphabetic # Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R
+A952 ; Other_Alphabetic # Mc REJANG CONSONANT SIGN H
+A980..A982 ; Other_Alphabetic # Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR
+A983 ; Other_Alphabetic # Mc JAVANESE SIGN WIGNYAN
+A9B4..A9B5 ; Other_Alphabetic # Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG
+A9B6..A9B9 ; Other_Alphabetic # Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT
+A9BA..A9BB ; Other_Alphabetic # Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE
+A9BC ; Other_Alphabetic # Mn JAVANESE VOWEL SIGN PEPET
+A9BD..A9BF ; Other_Alphabetic # Mc [3] JAVANESE CONSONANT SIGN KERET..JAVANESE CONSONANT SIGN CAKRA
+AA29..AA2E ; Other_Alphabetic # Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE
+AA2F..AA30 ; Other_Alphabetic # Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
+AA31..AA32 ; Other_Alphabetic # Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE
+AA33..AA34 ; Other_Alphabetic # Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA
+AA35..AA36 ; Other_Alphabetic # Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA
+AA43 ; Other_Alphabetic # Mn CHAM CONSONANT SIGN FINAL NG
+AA4C ; Other_Alphabetic # Mn CHAM CONSONANT SIGN FINAL M
+AA4D ; Other_Alphabetic # Mc CHAM CONSONANT SIGN FINAL H
+AAB0 ; Other_Alphabetic # Mn TAI VIET MAI KANG
+AAB2..AAB4 ; Other_Alphabetic # Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U
+AAB7..AAB8 ; Other_Alphabetic # Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA
+AABE ; Other_Alphabetic # Mn TAI VIET VOWEL AM
+AAEB ; Other_Alphabetic # Mc MEETEI MAYEK VOWEL SIGN II
+AAEC..AAED ; Other_Alphabetic # Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI
+AAEE..AAEF ; Other_Alphabetic # Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU
+AAF5 ; Other_Alphabetic # Mc MEETEI MAYEK VOWEL SIGN VISARGA
+ABE3..ABE4 ; Other_Alphabetic # Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP
+ABE5 ; Other_Alphabetic # Mn MEETEI MAYEK VOWEL SIGN ANAP
+ABE6..ABE7 ; Other_Alphabetic # Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP
+ABE8 ; Other_Alphabetic # Mn MEETEI MAYEK VOWEL SIGN UNAP
+ABE9..ABEA ; Other_Alphabetic # Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG
+FB1E ; Other_Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA
+10376..1037A ; Other_Alphabetic # Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII
+10A01..10A03 ; Other_Alphabetic # Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R
+10A05..10A06 ; Other_Alphabetic # Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O
+10A0C..10A0F ; Other_Alphabetic # Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA
+11000 ; Other_Alphabetic # Mc BRAHMI SIGN CANDRABINDU
+11001 ; Other_Alphabetic # Mn BRAHMI SIGN ANUSVARA
+11002 ; Other_Alphabetic # Mc BRAHMI SIGN VISARGA
+11038..11045 ; Other_Alphabetic # Mn [14] BRAHMI VOWEL SIGN AA..BRAHMI VOWEL SIGN AU
+11082 ; Other_Alphabetic # Mc KAITHI SIGN VISARGA
+110B0..110B2 ; Other_Alphabetic # Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II
+110B3..110B6 ; Other_Alphabetic # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI
+110B7..110B8 ; Other_Alphabetic # Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU
+11100..11102 ; Other_Alphabetic # Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA
+11127..1112B ; Other_Alphabetic # Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU
+1112C ; Other_Alphabetic # Mc CHAKMA VOWEL SIGN E
+1112D..11132 ; Other_Alphabetic # Mn [6] CHAKMA VOWEL SIGN AI..CHAKMA AU MARK
+11180..11181 ; Other_Alphabetic # Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA
+11182 ; Other_Alphabetic # Mc SHARADA SIGN VISARGA
+111B3..111B5 ; Other_Alphabetic # Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II
+111B6..111BE ; Other_Alphabetic # Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O
+111BF ; Other_Alphabetic # Mc SHARADA VOWEL SIGN AU
+1122C..1122E ; Other_Alphabetic # Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II
+1122F..11231 ; Other_Alphabetic # Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI
+11232..11233 ; Other_Alphabetic # Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU
+11234 ; Other_Alphabetic # Mn KHOJKI SIGN ANUSVARA
+11237 ; Other_Alphabetic # Mn KHOJKI SIGN SHADDA
+1123E ; Other_Alphabetic # Mn KHOJKI SIGN SUKUN
+112DF ; Other_Alphabetic # Mn KHUDAWADI SIGN ANUSVARA
+112E0..112E2 ; Other_Alphabetic # Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II
+112E3..112E8 ; Other_Alphabetic # Mn [6] KHUDAWADI VOWEL SIGN U..KHUDAWADI VOWEL SIGN AU
+11300..11301 ; Other_Alphabetic # Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU
+11302..11303 ; Other_Alphabetic # Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA
+1133E..1133F ; Other_Alphabetic # Mc [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I
+11340 ; Other_Alphabetic # Mn GRANTHA VOWEL SIGN II
+11341..11344 ; Other_Alphabetic # Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR
+11347..11348 ; Other_Alphabetic # Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI
+1134B..1134C ; Other_Alphabetic # Mc [2] GRANTHA VOWEL SIGN OO..GRANTHA VOWEL SIGN AU
+11357 ; Other_Alphabetic # Mc GRANTHA AU LENGTH MARK
+11362..11363 ; Other_Alphabetic # Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL
+11435..11437 ; Other_Alphabetic # Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II
+11438..1143F ; Other_Alphabetic # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI
+11440..11441 ; Other_Alphabetic # Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU
+11443..11444 ; Other_Alphabetic # Mn [2] NEWA SIGN CANDRABINDU..NEWA SIGN ANUSVARA
+11445 ; Other_Alphabetic # Mc NEWA SIGN VISARGA
+114B0..114B2 ; Other_Alphabetic # Mc [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II
+114B3..114B8 ; Other_Alphabetic # Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL
+114B9 ; Other_Alphabetic # Mc TIRHUTA VOWEL SIGN E
+114BA ; Other_Alphabetic # Mn TIRHUTA VOWEL SIGN SHORT E
+114BB..114BE ; Other_Alphabetic # Mc [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU
+114BF..114C0 ; Other_Alphabetic # Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA
+114C1 ; Other_Alphabetic # Mc TIRHUTA SIGN VISARGA
+115AF..115B1 ; Other_Alphabetic # Mc [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II
+115B2..115B5 ; Other_Alphabetic # Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR
+115B8..115BB ; Other_Alphabetic # Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU
+115BC..115BD ; Other_Alphabetic # Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA
+115BE ; Other_Alphabetic # Mc SIDDHAM SIGN VISARGA
+115DC..115DD ; Other_Alphabetic # Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU
+11630..11632 ; Other_Alphabetic # Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II
+11633..1163A ; Other_Alphabetic # Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI
+1163B..1163C ; Other_Alphabetic # Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU
+1163D ; Other_Alphabetic # Mn MODI SIGN ANUSVARA
+1163E ; Other_Alphabetic # Mc MODI SIGN VISARGA
+11640 ; Other_Alphabetic # Mn MODI SIGN ARDHACANDRA
+116AB ; Other_Alphabetic # Mn TAKRI SIGN ANUSVARA
+116AC ; Other_Alphabetic # Mc TAKRI SIGN VISARGA
+116AD ; Other_Alphabetic # Mn TAKRI VOWEL SIGN AA
+116AE..116AF ; Other_Alphabetic # Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II
+116B0..116B5 ; Other_Alphabetic # Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU
+1171D..1171F ; Other_Alphabetic # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA
+11720..11721 ; Other_Alphabetic # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA
+11722..11725 ; Other_Alphabetic # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU
+11726 ; Other_Alphabetic # Mc AHOM VOWEL SIGN E
+11727..1172A ; Other_Alphabetic # Mn [4] AHOM VOWEL SIGN AW..AHOM VOWEL SIGN AM
+11C2F ; Other_Alphabetic # Mc BHAIKSUKI VOWEL SIGN AA
+11C30..11C36 ; Other_Alphabetic # Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L
+11C38..11C3D ; Other_Alphabetic # Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA
+11C3E ; Other_Alphabetic # Mc BHAIKSUKI SIGN VISARGA
+11C92..11CA7 ; Other_Alphabetic # Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA
+11CA9 ; Other_Alphabetic # Mc MARCHEN SUBJOINED LETTER YA
+11CAA..11CB0 ; Other_Alphabetic # Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA
+11CB1 ; Other_Alphabetic # Mc MARCHEN VOWEL SIGN I
+11CB2..11CB3 ; Other_Alphabetic # Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E
+11CB4 ; Other_Alphabetic # Mc MARCHEN VOWEL SIGN O
+11CB5..11CB6 ; Other_Alphabetic # Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU
+16B30..16B36 ; Other_Alphabetic # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM
+16F51..16F7E ; Other_Alphabetic # Mc [46] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN NG
+1BC9E ; Other_Alphabetic # Mn DUPLOYAN DOUBLE MARK
+1E000..1E006 ; Other_Alphabetic # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE
+1E008..1E018 ; Other_Alphabetic # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU
+1E01B..1E021 ; Other_Alphabetic # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI
+1E023..1E024 ; Other_Alphabetic # Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS
+1E026..1E02A ; Other_Alphabetic # Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA
+1E947 ; Other_Alphabetic # Mn ADLAM HAMZA
+1F130..1F149 ; Other_Alphabetic # So [26] SQUARED LATIN CAPITAL LETTER A..SQUARED LATIN CAPITAL LETTER Z
+1F150..1F169 ; Other_Alphabetic # So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z
+1F170..1F189 ; Other_Alphabetic # So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z
+
+# Total code points: 1238
+
+# ================================================
+
+3006 ; Ideographic # Lo IDEOGRAPHIC CLOSING MARK
+3007 ; Ideographic # Nl IDEOGRAPHIC NUMBER ZERO
+3021..3029 ; Ideographic # Nl [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE
+3038..303A ; Ideographic # Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY
+3400..4DB5 ; Ideographic # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
+4E00..9FD5 ; Ideographic # Lo [20950] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FD5
+F900..FA6D ; Ideographic # Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D
+FA70..FAD9 ; Ideographic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9
+17000..187EC ; Ideographic # Lo [6125] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187EC
+18800..18AF2 ; Ideographic # Lo [755] TANGUT COMPONENT-001..TANGUT COMPONENT-755
+20000..2A6D6 ; Ideographic # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
+2A700..2B734 ; Ideographic # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734
+2B740..2B81D ; Ideographic # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
+2B820..2CEA1 ; Ideographic # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
+2F800..2FA1D ; Ideographic # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
+
+# Total code points: 88284
+
+# ================================================
+
+005E ; Diacritic # Sk CIRCUMFLEX ACCENT
+0060 ; Diacritic # Sk GRAVE ACCENT
+00A8 ; Diacritic # Sk DIAERESIS
+00AF ; Diacritic # Sk MACRON
+00B4 ; Diacritic # Sk ACUTE ACCENT
+00B7 ; Diacritic # Po MIDDLE DOT
+00B8 ; Diacritic # Sk CEDILLA
+02B0..02C1 ; Diacritic # Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP
+02C2..02C5 ; Diacritic # Sk [4] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER DOWN ARROWHEAD
+02C6..02D1 ; Diacritic # Lm [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON
+02D2..02DF ; Diacritic # Sk [14] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER CROSS ACCENT
+02E0..02E4 ; Diacritic # Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
+02E5..02EB ; Diacritic # Sk [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK
+02EC ; Diacritic # Lm MODIFIER LETTER VOICING
+02ED ; Diacritic # Sk MODIFIER LETTER UNASPIRATED
+02EE ; Diacritic # Lm MODIFIER LETTER DOUBLE APOSTROPHE
+02EF..02FF ; Diacritic # Sk [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW
+0300..034E ; Diacritic # Mn [79] COMBINING GRAVE ACCENT..COMBINING UPWARDS ARROW BELOW
+0350..0357 ; Diacritic # Mn [8] COMBINING RIGHT ARROWHEAD ABOVE..COMBINING RIGHT HALF RING ABOVE
+035D..0362 ; Diacritic # Mn [6] COMBINING DOUBLE BREVE..COMBINING DOUBLE RIGHTWARDS ARROW BELOW
+0374 ; Diacritic # Lm GREEK NUMERAL SIGN
+0375 ; Diacritic # Sk GREEK LOWER NUMERAL SIGN
+037A ; Diacritic # Lm GREEK YPOGEGRAMMENI
+0384..0385 ; Diacritic # Sk [2] GREEK TONOS..GREEK DIALYTIKA TONOS
+0483..0487 ; Diacritic # Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
+0559 ; Diacritic # Lm ARMENIAN MODIFIER LETTER LEFT HALF RING
+0591..05A1 ; Diacritic # Mn [17] HEBREW ACCENT ETNAHTA..HEBREW ACCENT PAZER
+05A3..05BD ; Diacritic # Mn [27] HEBREW ACCENT MUNAH..HEBREW POINT METEG
+05BF ; Diacritic # Mn HEBREW POINT RAFE
+05C1..05C2 ; Diacritic # Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
+05C4 ; Diacritic # Mn HEBREW MARK UPPER DOT
+064B..0652 ; Diacritic # Mn [8] ARABIC FATHATAN..ARABIC SUKUN
+0657..0658 ; Diacritic # Mn [2] ARABIC INVERTED DAMMA..ARABIC MARK NOON GHUNNA
+06DF..06E0 ; Diacritic # Mn [2] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO
+06E5..06E6 ; Diacritic # Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH
+06EA..06EC ; Diacritic # Mn [3] ARABIC EMPTY CENTRE LOW STOP..ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE
+0730..074A ; Diacritic # Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH
+07A6..07B0 ; Diacritic # Mn [11] THAANA ABAFILI..THAANA SUKUN
+07EB..07F3 ; Diacritic # Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE
+07F4..07F5 ; Diacritic # Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE
+0818..0819 ; Diacritic # Mn [2] SAMARITAN MARK OCCLUSION..SAMARITAN MARK DAGESH
+08E3..08FE ; Diacritic # Mn [28] ARABIC TURNED DAMMA BELOW..ARABIC DAMMA WITH DOT
+093C ; Diacritic # Mn DEVANAGARI SIGN NUKTA
+094D ; Diacritic # Mn DEVANAGARI SIGN VIRAMA
+0951..0954 ; Diacritic # Mn [4] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI ACUTE ACCENT
+0971 ; Diacritic # Lm DEVANAGARI SIGN HIGH SPACING DOT
+09BC ; Diacritic # Mn BENGALI SIGN NUKTA
+09CD ; Diacritic # Mn BENGALI SIGN VIRAMA
+0A3C ; Diacritic # Mn GURMUKHI SIGN NUKTA
+0A4D ; Diacritic # Mn GURMUKHI SIGN VIRAMA
+0ABC ; Diacritic # Mn GUJARATI SIGN NUKTA
+0ACD ; Diacritic # Mn GUJARATI SIGN VIRAMA
+0B3C ; Diacritic # Mn ORIYA SIGN NUKTA
+0B4D ; Diacritic # Mn ORIYA SIGN VIRAMA
+0BCD ; Diacritic # Mn TAMIL SIGN VIRAMA
+0C4D ; Diacritic # Mn TELUGU SIGN VIRAMA
+0CBC ; Diacritic # Mn KANNADA SIGN NUKTA
+0CCD ; Diacritic # Mn KANNADA SIGN VIRAMA
+0D4D ; Diacritic # Mn MALAYALAM SIGN VIRAMA
+0DCA ; Diacritic # Mn SINHALA SIGN AL-LAKUNA
+0E47..0E4C ; Diacritic # Mn [6] THAI CHARACTER MAITAIKHU..THAI CHARACTER THANTHAKHAT
+0E4E ; Diacritic # Mn THAI CHARACTER YAMAKKAN
+0EC8..0ECC ; Diacritic # Mn [5] LAO TONE MAI EK..LAO CANCELLATION MARK
+0F18..0F19 ; Diacritic # Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
+0F35 ; Diacritic # Mn TIBETAN MARK NGAS BZUNG NYI ZLA
+0F37 ; Diacritic # Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS
+0F39 ; Diacritic # Mn TIBETAN MARK TSA -PHRU
+0F3E..0F3F ; Diacritic # Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
+0F82..0F84 ; Diacritic # Mn [3] TIBETAN SIGN NYI ZLA NAA DA..TIBETAN MARK HALANTA
+0F86..0F87 ; Diacritic # Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
+0FC6 ; Diacritic # Mn TIBETAN SYMBOL PADMA GDAN
+1037 ; Diacritic # Mn MYANMAR SIGN DOT BELOW
+1039..103A ; Diacritic # Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT
+1087..108C ; Diacritic # Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3
+108D ; Diacritic # Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE
+108F ; Diacritic # Mc MYANMAR SIGN RUMAI PALAUNG TONE-5
+109A..109B ; Diacritic # Mc [2] MYANMAR SIGN KHAMTI TONE-1..MYANMAR SIGN KHAMTI TONE-3
+17C9..17D3 ; Diacritic # Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT
+17DD ; Diacritic # Mn KHMER SIGN ATTHACAN
+1939..193B ; Diacritic # Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I
+1A75..1A7C ; Diacritic # Mn [8] TAI THAM SIGN TONE-1..TAI THAM SIGN KHUEN-LUE KARAN
+1A7F ; Diacritic # Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT
+1AB0..1ABD ; Diacritic # Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
+1B34 ; Diacritic # Mn BALINESE SIGN REREKAN
+1B44 ; Diacritic # Mc BALINESE ADEG ADEG
+1B6B..1B73 ; Diacritic # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG
+1BAA ; Diacritic # Mc SUNDANESE SIGN PAMAAEH
+1BAB ; Diacritic # Mn SUNDANESE SIGN VIRAMA
+1C36..1C37 ; Diacritic # Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA
+1C78..1C7D ; Diacritic # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD
+1CD0..1CD2 ; Diacritic # Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA
+1CD3 ; Diacritic # Po VEDIC SIGN NIHSHVASA
+1CD4..1CE0 ; Diacritic # Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA
+1CE1 ; Diacritic # Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA
+1CE2..1CE8 ; Diacritic # Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL
+1CED ; Diacritic # Mn VEDIC SIGN TIRYAK
+1CF4 ; Diacritic # Mn VEDIC TONE CANDRA ABOVE
+1CF8..1CF9 ; Diacritic # Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE
+1D2C..1D6A ; Diacritic # Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI
+1DC4..1DCF ; Diacritic # Mn [12] COMBINING MACRON-ACUTE..COMBINING ZIGZAG BELOW
+1DF5 ; Diacritic # Mn COMBINING UP TACK ABOVE
+1DFD..1DFF ; Diacritic # Mn [3] COMBINING ALMOST EQUAL TO BELOW..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW
+1FBD ; Diacritic # Sk GREEK KORONIS
+1FBF..1FC1 ; Diacritic # Sk [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI
+1FCD..1FCF ; Diacritic # Sk [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI
+1FDD..1FDF ; Diacritic # Sk [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI
+1FED..1FEF ; Diacritic # Sk [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA
+1FFD..1FFE ; Diacritic # Sk [2] GREEK OXIA..GREEK DASIA
+2CEF..2CF1 ; Diacritic # Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS
+2E2F ; Diacritic # Lm VERTICAL TILDE
+302A..302D ; Diacritic # Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK
+302E..302F ; Diacritic # Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK
+3099..309A ; Diacritic # Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+309B..309C ; Diacritic # Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+30FC ; Diacritic # Lm KATAKANA-HIRAGANA PROLONGED SOUND MARK
+A66F ; Diacritic # Mn COMBINING CYRILLIC VZMET
+A67C..A67D ; Diacritic # Mn [2] COMBINING CYRILLIC KAVYKA..COMBINING CYRILLIC PAYEROK
+A67F ; Diacritic # Lm CYRILLIC PAYEROK
+A69C..A69D ; Diacritic # Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN
+A6F0..A6F1 ; Diacritic # Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS
+A717..A71F ; Diacritic # Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK
+A720..A721 ; Diacritic # Sk [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE
+A788 ; Diacritic # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT
+A7F8..A7F9 ; Diacritic # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
+A8C4 ; Diacritic # Mn SAURASHTRA SIGN VIRAMA
+A8E0..A8F1 ; Diacritic # Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA
+A92B..A92D ; Diacritic # Mn [3] KAYAH LI TONE PLOPHU..KAYAH LI TONE CALYA PLOPHU
+A92E ; Diacritic # Po KAYAH LI SIGN CWI
+A953 ; Diacritic # Mc REJANG VIRAMA
+A9B3 ; Diacritic # Mn JAVANESE SIGN CECAK TELU
+A9C0 ; Diacritic # Mc JAVANESE PANGKON
+A9E5 ; Diacritic # Mn MYANMAR SIGN SHAN SAW
+AA7B ; Diacritic # Mc MYANMAR SIGN PAO KAREN TONE
+AA7C ; Diacritic # Mn MYANMAR SIGN TAI LAING TONE-2
+AA7D ; Diacritic # Mc MYANMAR SIGN TAI LAING TONE-5
+AABF ; Diacritic # Mn TAI VIET TONE MAI EK
+AAC0 ; Diacritic # Lo TAI VIET TONE MAI NUENG
+AAC1 ; Diacritic # Mn TAI VIET TONE MAI THO
+AAC2 ; Diacritic # Lo TAI VIET TONE MAI SONG
+AAF6 ; Diacritic # Mn MEETEI MAYEK VIRAMA
+AB5B ; Diacritic # Sk MODIFIER BREVE WITH INVERTED BREVE
+AB5C..AB5F ; Diacritic # Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
+ABEC ; Diacritic # Mc MEETEI MAYEK LUM IYEK
+ABED ; Diacritic # Mn MEETEI MAYEK APUN IYEK
+FB1E ; Diacritic # Mn HEBREW POINT JUDEO-SPANISH VARIKA
+FE20..FE2F ; Diacritic # Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF
+FF3E ; Diacritic # Sk FULLWIDTH CIRCUMFLEX ACCENT
+FF40 ; Diacritic # Sk FULLWIDTH GRAVE ACCENT
+FF70 ; Diacritic # Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+FF9E..FF9F ; Diacritic # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+FFE3 ; Diacritic # Sk FULLWIDTH MACRON
+102E0 ; Diacritic # Mn COPTIC EPACT THOUSANDS MARK
+10AE5..10AE6 ; Diacritic # Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW
+110B9..110BA ; Diacritic # Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA
+11133..11134 ; Diacritic # Mn [2] CHAKMA VIRAMA..CHAKMA MAAYYAA
+11173 ; Diacritic # Mn MAHAJANI SIGN NUKTA
+111C0 ; Diacritic # Mc SHARADA SIGN VIRAMA
+111CA..111CC ; Diacritic # Mn [3] SHARADA SIGN NUKTA..SHARADA EXTRA SHORT VOWEL MARK
+11235 ; Diacritic # Mc KHOJKI SIGN VIRAMA
+11236 ; Diacritic # Mn KHOJKI SIGN NUKTA
+112E9..112EA ; Diacritic # Mn [2] KHUDAWADI SIGN NUKTA..KHUDAWADI SIGN VIRAMA
+1133C ; Diacritic # Mn GRANTHA SIGN NUKTA
+1134D ; Diacritic # Mc GRANTHA SIGN VIRAMA
+11366..1136C ; Diacritic # Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX
+11370..11374 ; Diacritic # Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA
+11442 ; Diacritic # Mn NEWA SIGN VIRAMA
+11446 ; Diacritic # Mn NEWA SIGN NUKTA
+114C2..114C3 ; Diacritic # Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA
+115BF..115C0 ; Diacritic # Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA
+1163F ; Diacritic # Mn MODI SIGN VIRAMA
+116B6 ; Diacritic # Mc TAKRI SIGN VIRAMA
+116B7 ; Diacritic # Mn TAKRI SIGN NUKTA
+1172B ; Diacritic # Mn AHOM SIGN KILLER
+11C3F ; Diacritic # Mn BHAIKSUKI SIGN VIRAMA
+16AF0..16AF4 ; Diacritic # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE
+16F8F..16F92 ; Diacritic # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW
+16F93..16F9F ; Diacritic # Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8
+1D167..1D169 ; Diacritic # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
+1D16D..1D172 ; Diacritic # Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5
+1D17B..1D182 ; Diacritic # Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE
+1D185..1D18B ; Diacritic # Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
+1D1AA..1D1AD ; Diacritic # Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
+1E8D0..1E8D6 ; Diacritic # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS
+1E944..1E946 ; Diacritic # Mn [3] ADLAM ALIF LENGTHENER..ADLAM GEMINATION MARK
+1E948..1E94A ; Diacritic # Mn [3] ADLAM CONSONANT MODIFIER..ADLAM NUKTA
+
+# Total code points: 782
+
+# ================================================
+
+00B7 ; Extender # Po MIDDLE DOT
+02D0..02D1 ; Extender # Lm [2] MODIFIER LETTER TRIANGULAR COLON..MODIFIER LETTER HALF TRIANGULAR COLON
+0640 ; Extender # Lm ARABIC TATWEEL
+07FA ; Extender # Lm NKO LAJANYALAN
+0E46 ; Extender # Lm THAI CHARACTER MAIYAMOK
+0EC6 ; Extender # Lm LAO KO LA
+180A ; Extender # Po MONGOLIAN NIRUGU
+1843 ; Extender # Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN
+1AA7 ; Extender # Lm TAI THAM SIGN MAI YAMOK
+1C36 ; Extender # Mn LEPCHA SIGN RAN
+1C7B ; Extender # Lm OL CHIKI RELAA
+3005 ; Extender # Lm IDEOGRAPHIC ITERATION MARK
+3031..3035 ; Extender # Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF
+309D..309E ; Extender # Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK
+30FC..30FE ; Extender # Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK
+A015 ; Extender # Lm YI SYLLABLE WU
+A60C ; Extender # Lm VAI SYLLABLE LENGTHENER
+A9CF ; Extender # Lm JAVANESE PANGRANGKEP
+A9E6 ; Extender # Lm MYANMAR MODIFIER LETTER SHAN REDUPLICATION
+AA70 ; Extender # Lm MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION
+AADD ; Extender # Lm TAI VIET SYMBOL SAM
+AAF3..AAF4 ; Extender # Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK
+FF70 ; Extender # Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+1135D ; Extender # Lo GRANTHA SIGN PLUTA
+115C6..115C8 ; Extender # Po [3] SIDDHAM REPETITION MARK-1..SIDDHAM REPETITION MARK-3
+16B42..16B43 ; Extender # Lm [2] PAHAWH HMONG SIGN VOS NRUA..PAHAWH HMONG SIGN IB YAM
+16FE0 ; Extender # Lm TANGUT ITERATION MARK
+1E944..1E946 ; Extender # Mn [3] ADLAM ALIF LENGTHENER..ADLAM GEMINATION MARK
+
+# Total code points: 42
+
+# ================================================
+
+00AA ; Other_Lowercase # Lo FEMININE ORDINAL INDICATOR
+00BA ; Other_Lowercase # Lo MASCULINE ORDINAL INDICATOR
+02B0..02B8 ; Other_Lowercase # Lm [9] MODIFIER LETTER SMALL H..MODIFIER LETTER SMALL Y
+02C0..02C1 ; Other_Lowercase # Lm [2] MODIFIER LETTER GLOTTAL STOP..MODIFIER LETTER REVERSED GLOTTAL STOP
+02E0..02E4 ; Other_Lowercase # Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
+0345 ; Other_Lowercase # Mn COMBINING GREEK YPOGEGRAMMENI
+037A ; Other_Lowercase # Lm GREEK YPOGEGRAMMENI
+1D2C..1D6A ; Other_Lowercase # Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI
+1D78 ; Other_Lowercase # Lm MODIFIER LETTER CYRILLIC EN
+1D9B..1DBF ; Other_Lowercase # Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA
+2071 ; Other_Lowercase # Lm SUPERSCRIPT LATIN SMALL LETTER I
+207F ; Other_Lowercase # Lm SUPERSCRIPT LATIN SMALL LETTER N
+2090..209C ; Other_Lowercase # Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T
+2170..217F ; Other_Lowercase # Nl [16] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL ONE THOUSAND
+24D0..24E9 ; Other_Lowercase # So [26] CIRCLED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z
+2C7C..2C7D ; Other_Lowercase # Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V
+A69C..A69D ; Other_Lowercase # Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN
+A770 ; Other_Lowercase # Lm MODIFIER LETTER US
+A7F8..A7F9 ; Other_Lowercase # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
+AB5C..AB5F ; Other_Lowercase # Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
+
+# Total code points: 189
+
+# ================================================
+
+2160..216F ; Other_Uppercase # Nl [16] ROMAN NUMERAL ONE..ROMAN NUMERAL ONE THOUSAND
+24B6..24CF ; Other_Uppercase # So [26] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN CAPITAL LETTER Z
+1F130..1F149 ; Other_Uppercase # So [26] SQUARED LATIN CAPITAL LETTER A..SQUARED LATIN CAPITAL LETTER Z
+1F150..1F169 ; Other_Uppercase # So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z
+1F170..1F189 ; Other_Uppercase # So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z
+
+# Total code points: 120
+
+# ================================================
+
+FDD0..FDEF ; Noncharacter_Code_Point # Cn [32] <noncharacter-FDD0>..<noncharacter-FDEF>
+FFFE..FFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-FFFE>..<noncharacter-FFFF>
+1FFFE..1FFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-1FFFE>..<noncharacter-1FFFF>
+2FFFE..2FFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-2FFFE>..<noncharacter-2FFFF>
+3FFFE..3FFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-3FFFE>..<noncharacter-3FFFF>
+4FFFE..4FFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-4FFFE>..<noncharacter-4FFFF>
+5FFFE..5FFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-5FFFE>..<noncharacter-5FFFF>
+6FFFE..6FFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-6FFFE>..<noncharacter-6FFFF>
+7FFFE..7FFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-7FFFE>..<noncharacter-7FFFF>
+8FFFE..8FFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-8FFFE>..<noncharacter-8FFFF>
+9FFFE..9FFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-9FFFE>..<noncharacter-9FFFF>
+AFFFE..AFFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-AFFFE>..<noncharacter-AFFFF>
+BFFFE..BFFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-BFFFE>..<noncharacter-BFFFF>
+CFFFE..CFFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-CFFFE>..<noncharacter-CFFFF>
+DFFFE..DFFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-DFFFE>..<noncharacter-DFFFF>
+EFFFE..EFFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-EFFFE>..<noncharacter-EFFFF>
+FFFFE..FFFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-FFFFE>..<noncharacter-FFFFF>
+10FFFE..10FFFF; Noncharacter_Code_Point # Cn [2] <noncharacter-10FFFE>..<noncharacter-10FFFF>
+
+# Total code points: 66
+
+# ================================================
+
+09BE ; Other_Grapheme_Extend # Mc BENGALI VOWEL SIGN AA
+09D7 ; Other_Grapheme_Extend # Mc BENGALI AU LENGTH MARK
+0B3E ; Other_Grapheme_Extend # Mc ORIYA VOWEL SIGN AA
+0B57 ; Other_Grapheme_Extend # Mc ORIYA AU LENGTH MARK
+0BBE ; Other_Grapheme_Extend # Mc TAMIL VOWEL SIGN AA
+0BD7 ; Other_Grapheme_Extend # Mc TAMIL AU LENGTH MARK
+0CC2 ; Other_Grapheme_Extend # Mc KANNADA VOWEL SIGN UU
+0CD5..0CD6 ; Other_Grapheme_Extend # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
+0D3E ; Other_Grapheme_Extend # Mc MALAYALAM VOWEL SIGN AA
+0D57 ; Other_Grapheme_Extend # Mc MALAYALAM AU LENGTH MARK
+0DCF ; Other_Grapheme_Extend # Mc SINHALA VOWEL SIGN AELA-PILLA
+0DDF ; Other_Grapheme_Extend # Mc SINHALA VOWEL SIGN GAYANUKITTA
+200C ; Other_Grapheme_Extend # Cf ZERO WIDTH NON-JOINER
+302E..302F ; Other_Grapheme_Extend # Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK
+FF9E..FF9F ; Other_Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+1133E ; Other_Grapheme_Extend # Mc GRANTHA VOWEL SIGN AA
+11357 ; Other_Grapheme_Extend # Mc GRANTHA AU LENGTH MARK
+114B0 ; Other_Grapheme_Extend # Mc TIRHUTA VOWEL SIGN AA
+114BD ; Other_Grapheme_Extend # Mc TIRHUTA VOWEL SIGN SHORT O
+115AF ; Other_Grapheme_Extend # Mc SIDDHAM VOWEL SIGN AA
+1D165 ; Other_Grapheme_Extend # Mc MUSICAL SYMBOL COMBINING STEM
+1D16E..1D172 ; Other_Grapheme_Extend # Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5
+E0020..E007F ; Other_Grapheme_Extend # Cf [96] TAG SPACE..CANCEL TAG
+
+# Total code points: 125
+
+# ================================================
+
+2FF0..2FF1 ; IDS_Binary_Operator # So [2] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW
+2FF4..2FFB ; IDS_Binary_Operator # So [8] IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID
+
+# Total code points: 10
+
+# ================================================
+
+2FF2..2FF3 ; IDS_Trinary_Operator # So [2] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW
+
+# Total code points: 2
+
+# ================================================
+
+2E80..2E99 ; Radical # So [26] CJK RADICAL REPEAT..CJK RADICAL RAP
+2E9B..2EF3 ; Radical # So [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE
+2F00..2FD5 ; Radical # So [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE
+
+# Total code points: 329
+
+# ================================================
+
+3400..4DB5 ; Unified_Ideograph # Lo [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5
+4E00..9FD5 ; Unified_Ideograph # Lo [20950] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FD5
+FA0E..FA0F ; Unified_Ideograph # Lo [2] CJK COMPATIBILITY IDEOGRAPH-FA0E..CJK COMPATIBILITY IDEOGRAPH-FA0F
+FA11 ; Unified_Ideograph # Lo CJK COMPATIBILITY IDEOGRAPH-FA11
+FA13..FA14 ; Unified_Ideograph # Lo [2] CJK COMPATIBILITY IDEOGRAPH-FA13..CJK COMPATIBILITY IDEOGRAPH-FA14
+FA1F ; Unified_Ideograph # Lo CJK COMPATIBILITY IDEOGRAPH-FA1F
+FA21 ; Unified_Ideograph # Lo CJK COMPATIBILITY IDEOGRAPH-FA21
+FA23..FA24 ; Unified_Ideograph # Lo [2] CJK COMPATIBILITY IDEOGRAPH-FA23..CJK COMPATIBILITY IDEOGRAPH-FA24
+FA27..FA29 ; Unified_Ideograph # Lo [3] CJK COMPATIBILITY IDEOGRAPH-FA27..CJK COMPATIBILITY IDEOGRAPH-FA29
+20000..2A6D6 ; Unified_Ideograph # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6
+2A700..2B734 ; Unified_Ideograph # Lo [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734
+2B740..2B81D ; Unified_Ideograph # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
+2B820..2CEA1 ; Unified_Ideograph # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
+
+# Total code points: 80388
+
+# ================================================
+
+034F ; Other_Default_Ignorable_Code_Point # Mn COMBINING GRAPHEME JOINER
+115F..1160 ; Other_Default_Ignorable_Code_Point # Lo [2] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG FILLER
+17B4..17B5 ; Other_Default_Ignorable_Code_Point # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
+2065 ; Other_Default_Ignorable_Code_Point # Cn <reserved-2065>
+3164 ; Other_Default_Ignorable_Code_Point # Lo HANGUL FILLER
+FFA0 ; Other_Default_Ignorable_Code_Point # Lo HALFWIDTH HANGUL FILLER
+FFF0..FFF8 ; Other_Default_Ignorable_Code_Point # Cn [9] <reserved-FFF0>..<reserved-FFF8>
+E0000 ; Other_Default_Ignorable_Code_Point # Cn <reserved-E0000>
+E0002..E001F ; Other_Default_Ignorable_Code_Point # Cn [30] <reserved-E0002>..<reserved-E001F>
+E0080..E00FF ; Other_Default_Ignorable_Code_Point # Cn [128] <reserved-E0080>..<reserved-E00FF>
+E01F0..E0FFF ; Other_Default_Ignorable_Code_Point # Cn [3600] <reserved-E01F0>..<reserved-E0FFF>
+
+# Total code points: 3776
+
+# ================================================
+
+0149 ; Deprecated # L& LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+0673 ; Deprecated # Lo ARABIC LETTER ALEF WITH WAVY HAMZA BELOW
+0F77 ; Deprecated # Mn TIBETAN VOWEL SIGN VOCALIC RR
+0F79 ; Deprecated # Mn TIBETAN VOWEL SIGN VOCALIC LL
+17A3..17A4 ; Deprecated # Lo [2] KHMER INDEPENDENT VOWEL QAQ..KHMER INDEPENDENT VOWEL QAA
+206A..206F ; Deprecated # Cf [6] INHIBIT SYMMETRIC SWAPPING..NOMINAL DIGIT SHAPES
+2329 ; Deprecated # Ps LEFT-POINTING ANGLE BRACKET
+232A ; Deprecated # Pe RIGHT-POINTING ANGLE BRACKET
+E0001 ; Deprecated # Cf LANGUAGE TAG
+
+# Total code points: 15
+
+# ================================================
+
+0069..006A ; Soft_Dotted # L& [2] LATIN SMALL LETTER I..LATIN SMALL LETTER J
+012F ; Soft_Dotted # L& LATIN SMALL LETTER I WITH OGONEK
+0249 ; Soft_Dotted # L& LATIN SMALL LETTER J WITH STROKE
+0268 ; Soft_Dotted # L& LATIN SMALL LETTER I WITH STROKE
+029D ; Soft_Dotted # L& LATIN SMALL LETTER J WITH CROSSED-TAIL
+02B2 ; Soft_Dotted # Lm MODIFIER LETTER SMALL J
+03F3 ; Soft_Dotted # L& GREEK LETTER YOT
+0456 ; Soft_Dotted # L& CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+0458 ; Soft_Dotted # L& CYRILLIC SMALL LETTER JE
+1D62 ; Soft_Dotted # Lm LATIN SUBSCRIPT SMALL LETTER I
+1D96 ; Soft_Dotted # L& LATIN SMALL LETTER I WITH RETROFLEX HOOK
+1DA4 ; Soft_Dotted # Lm MODIFIER LETTER SMALL I WITH STROKE
+1DA8 ; Soft_Dotted # Lm MODIFIER LETTER SMALL J WITH CROSSED-TAIL
+1E2D ; Soft_Dotted # L& LATIN SMALL LETTER I WITH TILDE BELOW
+1ECB ; Soft_Dotted # L& LATIN SMALL LETTER I WITH DOT BELOW
+2071 ; Soft_Dotted # Lm SUPERSCRIPT LATIN SMALL LETTER I
+2148..2149 ; Soft_Dotted # L& [2] DOUBLE-STRUCK ITALIC SMALL I..DOUBLE-STRUCK ITALIC SMALL J
+2C7C ; Soft_Dotted # Lm LATIN SUBSCRIPT SMALL LETTER J
+1D422..1D423 ; Soft_Dotted # L& [2] MATHEMATICAL BOLD SMALL I..MATHEMATICAL BOLD SMALL J
+1D456..1D457 ; Soft_Dotted # L& [2] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL ITALIC SMALL J
+1D48A..1D48B ; Soft_Dotted # L& [2] MATHEMATICAL BOLD ITALIC SMALL I..MATHEMATICAL BOLD ITALIC SMALL J
+1D4BE..1D4BF ; Soft_Dotted # L& [2] MATHEMATICAL SCRIPT SMALL I..MATHEMATICAL SCRIPT SMALL J
+1D4F2..1D4F3 ; Soft_Dotted # L& [2] MATHEMATICAL BOLD SCRIPT SMALL I..MATHEMATICAL BOLD SCRIPT SMALL J
+1D526..1D527 ; Soft_Dotted # L& [2] MATHEMATICAL FRAKTUR SMALL I..MATHEMATICAL FRAKTUR SMALL J
+1D55A..1D55B ; Soft_Dotted # L& [2] MATHEMATICAL DOUBLE-STRUCK SMALL I..MATHEMATICAL DOUBLE-STRUCK SMALL J
+1D58E..1D58F ; Soft_Dotted # L& [2] MATHEMATICAL BOLD FRAKTUR SMALL I..MATHEMATICAL BOLD FRAKTUR SMALL J
+1D5C2..1D5C3 ; Soft_Dotted # L& [2] MATHEMATICAL SANS-SERIF SMALL I..MATHEMATICAL SANS-SERIF SMALL J
+1D5F6..1D5F7 ; Soft_Dotted # L& [2] MATHEMATICAL SANS-SERIF BOLD SMALL I..MATHEMATICAL SANS-SERIF BOLD SMALL J
+1D62A..1D62B ; Soft_Dotted # L& [2] MATHEMATICAL SANS-SERIF ITALIC SMALL I..MATHEMATICAL SANS-SERIF ITALIC SMALL J
+1D65E..1D65F ; Soft_Dotted # L& [2] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J
+1D692..1D693 ; Soft_Dotted # L& [2] MATHEMATICAL MONOSPACE SMALL I..MATHEMATICAL MONOSPACE SMALL J
+
+# Total code points: 46
+
+# ================================================
+
+0E40..0E44 ; Logical_Order_Exception # Lo [5] THAI CHARACTER SARA E..THAI CHARACTER SARA AI MAIMALAI
+0EC0..0EC4 ; Logical_Order_Exception # Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
+19B5..19B7 ; Logical_Order_Exception # Lo [3] NEW TAI LUE VOWEL SIGN E..NEW TAI LUE VOWEL SIGN O
+19BA ; Logical_Order_Exception # Lo NEW TAI LUE VOWEL SIGN AY
+AAB5..AAB6 ; Logical_Order_Exception # Lo [2] TAI VIET VOWEL E..TAI VIET VOWEL O
+AAB9 ; Logical_Order_Exception # Lo TAI VIET VOWEL UEA
+AABB..AABC ; Logical_Order_Exception # Lo [2] TAI VIET VOWEL AUE..TAI VIET VOWEL AY
+
+# Total code points: 19
+
+# ================================================
+
+1885..1886 ; Other_ID_Start # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA
+2118 ; Other_ID_Start # Sm SCRIPT CAPITAL P
+212E ; Other_ID_Start # So ESTIMATED SYMBOL
+309B..309C ; Other_ID_Start # Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+
+# Total code points: 6
+
+# ================================================
+
+00B7 ; Other_ID_Continue # Po MIDDLE DOT
+0387 ; Other_ID_Continue # Po GREEK ANO TELEIA
+1369..1371 ; Other_ID_Continue # No [9] ETHIOPIC DIGIT ONE..ETHIOPIC DIGIT NINE
+19DA ; Other_ID_Continue # No NEW TAI LUE THAM DIGIT ONE
+
+# Total code points: 12
+
+# ================================================
+
+0021 ; Sentence_Terminal # Po EXCLAMATION MARK
+002E ; Sentence_Terminal # Po FULL STOP
+003F ; Sentence_Terminal # Po QUESTION MARK
+0589 ; Sentence_Terminal # Po ARMENIAN FULL STOP
+061F ; Sentence_Terminal # Po ARABIC QUESTION MARK
+06D4 ; Sentence_Terminal # Po ARABIC FULL STOP
+0700..0702 ; Sentence_Terminal # Po [3] SYRIAC END OF PARAGRAPH..SYRIAC SUBLINEAR FULL STOP
+07F9 ; Sentence_Terminal # Po NKO EXCLAMATION MARK
+0964..0965 ; Sentence_Terminal # Po [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA
+104A..104B ; Sentence_Terminal # Po [2] MYANMAR SIGN LITTLE SECTION..MYANMAR SIGN SECTION
+1362 ; Sentence_Terminal # Po ETHIOPIC FULL STOP
+1367..1368 ; Sentence_Terminal # Po [2] ETHIOPIC QUESTION MARK..ETHIOPIC PARAGRAPH SEPARATOR
+166E ; Sentence_Terminal # Po CANADIAN SYLLABICS FULL STOP
+1735..1736 ; Sentence_Terminal # Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION
+1803 ; Sentence_Terminal # Po MONGOLIAN FULL STOP
+1809 ; Sentence_Terminal # Po MONGOLIAN MANCHU FULL STOP
+1944..1945 ; Sentence_Terminal # Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK
+1AA8..1AAB ; Sentence_Terminal # Po [4] TAI THAM SIGN KAAN..TAI THAM SIGN SATKAANKUU
+1B5A..1B5B ; Sentence_Terminal # Po [2] BALINESE PANTI..BALINESE PAMADA
+1B5E..1B5F ; Sentence_Terminal # Po [2] BALINESE CARIK SIKI..BALINESE CARIK PAREREN
+1C3B..1C3C ; Sentence_Terminal # Po [2] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION NYET THYOOM TA-ROL
+1C7E..1C7F ; Sentence_Terminal # Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD
+203C..203D ; Sentence_Terminal # Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG
+2047..2049 ; Sentence_Terminal # Po [3] DOUBLE QUESTION MARK..EXCLAMATION QUESTION MARK
+2E2E ; Sentence_Terminal # Po REVERSED QUESTION MARK
+2E3C ; Sentence_Terminal # Po STENOGRAPHIC FULL STOP
+3002 ; Sentence_Terminal # Po IDEOGRAPHIC FULL STOP
+A4FF ; Sentence_Terminal # Po LISU PUNCTUATION FULL STOP
+A60E..A60F ; Sentence_Terminal # Po [2] VAI FULL STOP..VAI QUESTION MARK
+A6F3 ; Sentence_Terminal # Po BAMUM FULL STOP
+A6F7 ; Sentence_Terminal # Po BAMUM QUESTION MARK
+A876..A877 ; Sentence_Terminal # Po [2] PHAGS-PA MARK SHAD..PHAGS-PA MARK DOUBLE SHAD
+A8CE..A8CF ; Sentence_Terminal # Po [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA
+A92F ; Sentence_Terminal # Po KAYAH LI SIGN SHYA
+A9C8..A9C9 ; Sentence_Terminal # Po [2] JAVANESE PADA LINGSA..JAVANESE PADA LUNGSI
+AA5D..AA5F ; Sentence_Terminal # Po [3] CHAM PUNCTUATION DANDA..CHAM PUNCTUATION TRIPLE DANDA
+AAF0..AAF1 ; Sentence_Terminal # Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM
+ABEB ; Sentence_Terminal # Po MEETEI MAYEK CHEIKHEI
+FE52 ; Sentence_Terminal # Po SMALL FULL STOP
+FE56..FE57 ; Sentence_Terminal # Po [2] SMALL QUESTION MARK..SMALL EXCLAMATION MARK
+FF01 ; Sentence_Terminal # Po FULLWIDTH EXCLAMATION MARK
+FF0E ; Sentence_Terminal # Po FULLWIDTH FULL STOP
+FF1F ; Sentence_Terminal # Po FULLWIDTH QUESTION MARK
+FF61 ; Sentence_Terminal # Po HALFWIDTH IDEOGRAPHIC FULL STOP
+10A56..10A57 ; Sentence_Terminal # Po [2] KHAROSHTHI PUNCTUATION DANDA..KHAROSHTHI PUNCTUATION DOUBLE DANDA
+11047..11048 ; Sentence_Terminal # Po [2] BRAHMI DANDA..BRAHMI DOUBLE DANDA
+110BE..110C1 ; Sentence_Terminal # Po [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA
+11141..11143 ; Sentence_Terminal # Po [3] CHAKMA DANDA..CHAKMA QUESTION MARK
+111C5..111C6 ; Sentence_Terminal # Po [2] SHARADA DANDA..SHARADA DOUBLE DANDA
+111CD ; Sentence_Terminal # Po SHARADA SUTRA MARK
+111DE..111DF ; Sentence_Terminal # Po [2] SHARADA SECTION MARK-1..SHARADA SECTION MARK-2
+11238..11239 ; Sentence_Terminal # Po [2] KHOJKI DANDA..KHOJKI DOUBLE DANDA
+1123B..1123C ; Sentence_Terminal # Po [2] KHOJKI SECTION MARK..KHOJKI DOUBLE SECTION MARK
+112A9 ; Sentence_Terminal # Po MULTANI SECTION MARK
+1144B..1144C ; Sentence_Terminal # Po [2] NEWA DANDA..NEWA DOUBLE DANDA
+115C2..115C3 ; Sentence_Terminal # Po [2] SIDDHAM DANDA..SIDDHAM DOUBLE DANDA
+115C9..115D7 ; Sentence_Terminal # Po [15] SIDDHAM END OF TEXT MARK..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES
+11641..11642 ; Sentence_Terminal # Po [2] MODI DANDA..MODI DOUBLE DANDA
+1173C..1173E ; Sentence_Terminal # Po [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI
+11C41..11C42 ; Sentence_Terminal # Po [2] BHAIKSUKI DANDA..BHAIKSUKI DOUBLE DANDA
+16A6E..16A6F ; Sentence_Terminal # Po [2] MRO DANDA..MRO DOUBLE DANDA
+16AF5 ; Sentence_Terminal # Po BASSA VAH FULL STOP
+16B37..16B38 ; Sentence_Terminal # Po [2] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN VOS TSHAB CEEB
+16B44 ; Sentence_Terminal # Po PAHAWH HMONG SIGN XAUS
+1BC9F ; Sentence_Terminal # Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP
+1DA88 ; Sentence_Terminal # Po SIGNWRITING FULL STOP
+
+# Total code points: 124
+
+# ================================================
+
+180B..180D ; Variation_Selector # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
+FE00..FE0F ; Variation_Selector # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
+E0100..E01EF ; Variation_Selector # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
+
+# Total code points: 259
+
+# ================================================
+
+0009..000D ; Pattern_White_Space # Cc [5] <control-0009>..<control-000D>
+0020 ; Pattern_White_Space # Zs SPACE
+0085 ; Pattern_White_Space # Cc <control-0085>
+200E..200F ; Pattern_White_Space # Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK
+2028 ; Pattern_White_Space # Zl LINE SEPARATOR
+2029 ; Pattern_White_Space # Zp PARAGRAPH SEPARATOR
+
+# Total code points: 11
+
+# ================================================
+
+0021..0023 ; Pattern_Syntax # Po [3] EXCLAMATION MARK..NUMBER SIGN
+0024 ; Pattern_Syntax # Sc DOLLAR SIGN
+0025..0027 ; Pattern_Syntax # Po [3] PERCENT SIGN..APOSTROPHE
+0028 ; Pattern_Syntax # Ps LEFT PARENTHESIS
+0029 ; Pattern_Syntax # Pe RIGHT PARENTHESIS
+002A ; Pattern_Syntax # Po ASTERISK
+002B ; Pattern_Syntax # Sm PLUS SIGN
+002C ; Pattern_Syntax # Po COMMA
+002D ; Pattern_Syntax # Pd HYPHEN-MINUS
+002E..002F ; Pattern_Syntax # Po [2] FULL STOP..SOLIDUS
+003A..003B ; Pattern_Syntax # Po [2] COLON..SEMICOLON
+003C..003E ; Pattern_Syntax # Sm [3] LESS-THAN SIGN..GREATER-THAN SIGN
+003F..0040 ; Pattern_Syntax # Po [2] QUESTION MARK..COMMERCIAL AT
+005B ; Pattern_Syntax # Ps LEFT SQUARE BRACKET
+005C ; Pattern_Syntax # Po REVERSE SOLIDUS
+005D ; Pattern_Syntax # Pe RIGHT SQUARE BRACKET
+005E ; Pattern_Syntax # Sk CIRCUMFLEX ACCENT
+0060 ; Pattern_Syntax # Sk GRAVE ACCENT
+007B ; Pattern_Syntax # Ps LEFT CURLY BRACKET
+007C ; Pattern_Syntax # Sm VERTICAL LINE
+007D ; Pattern_Syntax # Pe RIGHT CURLY BRACKET
+007E ; Pattern_Syntax # Sm TILDE
+00A1 ; Pattern_Syntax # Po INVERTED EXCLAMATION MARK
+00A2..00A5 ; Pattern_Syntax # Sc [4] CENT SIGN..YEN SIGN
+00A6 ; Pattern_Syntax # So BROKEN BAR
+00A7 ; Pattern_Syntax # Po SECTION SIGN
+00A9 ; Pattern_Syntax # So COPYRIGHT SIGN
+00AB ; Pattern_Syntax # Pi LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+00AC ; Pattern_Syntax # Sm NOT SIGN
+00AE ; Pattern_Syntax # So REGISTERED SIGN
+00B0 ; Pattern_Syntax # So DEGREE SIGN
+00B1 ; Pattern_Syntax # Sm PLUS-MINUS SIGN
+00B6 ; Pattern_Syntax # Po PILCROW SIGN
+00BB ; Pattern_Syntax # Pf RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+00BF ; Pattern_Syntax # Po INVERTED QUESTION MARK
+00D7 ; Pattern_Syntax # Sm MULTIPLICATION SIGN
+00F7 ; Pattern_Syntax # Sm DIVISION SIGN
+2010..2015 ; Pattern_Syntax # Pd [6] HYPHEN..HORIZONTAL BAR
+2016..2017 ; Pattern_Syntax # Po [2] DOUBLE VERTICAL LINE..DOUBLE LOW LINE
+2018 ; Pattern_Syntax # Pi LEFT SINGLE QUOTATION MARK
+2019 ; Pattern_Syntax # Pf RIGHT SINGLE QUOTATION MARK
+201A ; Pattern_Syntax # Ps SINGLE LOW-9 QUOTATION MARK
+201B..201C ; Pattern_Syntax # Pi [2] SINGLE HIGH-REVERSED-9 QUOTATION MARK..LEFT DOUBLE QUOTATION MARK
+201D ; Pattern_Syntax # Pf RIGHT DOUBLE QUOTATION MARK
+201E ; Pattern_Syntax # Ps DOUBLE LOW-9 QUOTATION MARK
+201F ; Pattern_Syntax # Pi DOUBLE HIGH-REVERSED-9 QUOTATION MARK
+2020..2027 ; Pattern_Syntax # Po [8] DAGGER..HYPHENATION POINT
+2030..2038 ; Pattern_Syntax # Po [9] PER MILLE SIGN..CARET
+2039 ; Pattern_Syntax # Pi SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+203A ; Pattern_Syntax # Pf SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+203B..203E ; Pattern_Syntax # Po [4] REFERENCE MARK..OVERLINE
+2041..2043 ; Pattern_Syntax # Po [3] CARET INSERTION POINT..HYPHEN BULLET
+2044 ; Pattern_Syntax # Sm FRACTION SLASH
+2045 ; Pattern_Syntax # Ps LEFT SQUARE BRACKET WITH QUILL
+2046 ; Pattern_Syntax # Pe RIGHT SQUARE BRACKET WITH QUILL
+2047..2051 ; Pattern_Syntax # Po [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY
+2052 ; Pattern_Syntax # Sm COMMERCIAL MINUS SIGN
+2053 ; Pattern_Syntax # Po SWUNG DASH
+2055..205E ; Pattern_Syntax # Po [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS
+2190..2194 ; Pattern_Syntax # Sm [5] LEFTWARDS ARROW..LEFT RIGHT ARROW
+2195..2199 ; Pattern_Syntax # So [5] UP DOWN ARROW..SOUTH WEST ARROW
+219A..219B ; Pattern_Syntax # Sm [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE
+219C..219F ; Pattern_Syntax # So [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW
+21A0 ; Pattern_Syntax # Sm RIGHTWARDS TWO HEADED ARROW
+21A1..21A2 ; Pattern_Syntax # So [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL
+21A3 ; Pattern_Syntax # Sm RIGHTWARDS ARROW WITH TAIL
+21A4..21A5 ; Pattern_Syntax # So [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR
+21A6 ; Pattern_Syntax # Sm RIGHTWARDS ARROW FROM BAR
+21A7..21AD ; Pattern_Syntax # So [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW
+21AE ; Pattern_Syntax # Sm LEFT RIGHT ARROW WITH STROKE
+21AF..21CD ; Pattern_Syntax # So [31] DOWNWARDS ZIGZAG ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE
+21CE..21CF ; Pattern_Syntax # Sm [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE
+21D0..21D1 ; Pattern_Syntax # So [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW
+21D2 ; Pattern_Syntax # Sm RIGHTWARDS DOUBLE ARROW
+21D3 ; Pattern_Syntax # So DOWNWARDS DOUBLE ARROW
+21D4 ; Pattern_Syntax # Sm LEFT RIGHT DOUBLE ARROW
+21D5..21F3 ; Pattern_Syntax # So [31] UP DOWN DOUBLE ARROW..UP DOWN WHITE ARROW
+21F4..22FF ; Pattern_Syntax # Sm [268] RIGHT ARROW WITH SMALL CIRCLE..Z NOTATION BAG MEMBERSHIP
+2300..2307 ; Pattern_Syntax # So [8] DIAMETER SIGN..WAVY LINE
+2308 ; Pattern_Syntax # Ps LEFT CEILING
+2309 ; Pattern_Syntax # Pe RIGHT CEILING
+230A ; Pattern_Syntax # Ps LEFT FLOOR
+230B ; Pattern_Syntax # Pe RIGHT FLOOR
+230C..231F ; Pattern_Syntax # So [20] BOTTOM RIGHT CROP..BOTTOM RIGHT CORNER
+2320..2321 ; Pattern_Syntax # Sm [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL
+2322..2328 ; Pattern_Syntax # So [7] FROWN..KEYBOARD
+2329 ; Pattern_Syntax # Ps LEFT-POINTING ANGLE BRACKET
+232A ; Pattern_Syntax # Pe RIGHT-POINTING ANGLE BRACKET
+232B..237B ; Pattern_Syntax # So [81] ERASE TO THE LEFT..NOT CHECK MARK
+237C ; Pattern_Syntax # Sm RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW
+237D..239A ; Pattern_Syntax # So [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL
+239B..23B3 ; Pattern_Syntax # Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM
+23B4..23DB ; Pattern_Syntax # So [40] TOP SQUARE BRACKET..FUSE
+23DC..23E1 ; Pattern_Syntax # Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET
+23E2..23FE ; Pattern_Syntax # So [29] WHITE TRAPEZIUM..POWER SLEEP SYMBOL
+23FF ; Pattern_Syntax # Cn <reserved-23FF>
+2400..2426 ; Pattern_Syntax # So [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO
+2427..243F ; Pattern_Syntax # Cn [25] <reserved-2427>..<reserved-243F>
+2440..244A ; Pattern_Syntax # So [11] OCR HOOK..OCR DOUBLE BACKSLASH
+244B..245F ; Pattern_Syntax # Cn [21] <reserved-244B>..<reserved-245F>
+2500..25B6 ; Pattern_Syntax # So [183] BOX DRAWINGS LIGHT HORIZONTAL..BLACK RIGHT-POINTING TRIANGLE
+25B7 ; Pattern_Syntax # Sm WHITE RIGHT-POINTING TRIANGLE
+25B8..25C0 ; Pattern_Syntax # So [9] BLACK RIGHT-POINTING SMALL TRIANGLE..BLACK LEFT-POINTING TRIANGLE
+25C1 ; Pattern_Syntax # Sm WHITE LEFT-POINTING TRIANGLE
+25C2..25F7 ; Pattern_Syntax # So [54] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE CIRCLE WITH UPPER RIGHT QUADRANT
+25F8..25FF ; Pattern_Syntax # Sm [8] UPPER LEFT TRIANGLE..LOWER RIGHT TRIANGLE
+2600..266E ; Pattern_Syntax # So [111] BLACK SUN WITH RAYS..MUSIC NATURAL SIGN
+266F ; Pattern_Syntax # Sm MUSIC SHARP SIGN
+2670..2767 ; Pattern_Syntax # So [248] WEST SYRIAC CROSS..ROTATED FLORAL HEART BULLET
+2768 ; Pattern_Syntax # Ps MEDIUM LEFT PARENTHESIS ORNAMENT
+2769 ; Pattern_Syntax # Pe MEDIUM RIGHT PARENTHESIS ORNAMENT
+276A ; Pattern_Syntax # Ps MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
+276B ; Pattern_Syntax # Pe MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
+276C ; Pattern_Syntax # Ps MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
+276D ; Pattern_Syntax # Pe MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
+276E ; Pattern_Syntax # Ps HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
+276F ; Pattern_Syntax # Pe HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
+2770 ; Pattern_Syntax # Ps HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
+2771 ; Pattern_Syntax # Pe HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
+2772 ; Pattern_Syntax # Ps LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
+2773 ; Pattern_Syntax # Pe LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
+2774 ; Pattern_Syntax # Ps MEDIUM LEFT CURLY BRACKET ORNAMENT
+2775 ; Pattern_Syntax # Pe MEDIUM RIGHT CURLY BRACKET ORNAMENT
+2794..27BF ; Pattern_Syntax # So [44] HEAVY WIDE-HEADED RIGHTWARDS ARROW..DOUBLE CURLY LOOP
+27C0..27C4 ; Pattern_Syntax # Sm [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET
+27C5 ; Pattern_Syntax # Ps LEFT S-SHAPED BAG DELIMITER
+27C6 ; Pattern_Syntax # Pe RIGHT S-SHAPED BAG DELIMITER
+27C7..27E5 ; Pattern_Syntax # Sm [31] OR WITH DOT INSIDE..WHITE SQUARE WITH RIGHTWARDS TICK
+27E6 ; Pattern_Syntax # Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET
+27E7 ; Pattern_Syntax # Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET
+27E8 ; Pattern_Syntax # Ps MATHEMATICAL LEFT ANGLE BRACKET
+27E9 ; Pattern_Syntax # Pe MATHEMATICAL RIGHT ANGLE BRACKET
+27EA ; Pattern_Syntax # Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
+27EB ; Pattern_Syntax # Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
+27EC ; Pattern_Syntax # Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
+27ED ; Pattern_Syntax # Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
+27EE ; Pattern_Syntax # Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS
+27EF ; Pattern_Syntax # Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS
+27F0..27FF ; Pattern_Syntax # Sm [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW
+2800..28FF ; Pattern_Syntax # So [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678
+2900..2982 ; Pattern_Syntax # Sm [131] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..Z NOTATION TYPE COLON
+2983 ; Pattern_Syntax # Ps LEFT WHITE CURLY BRACKET
+2984 ; Pattern_Syntax # Pe RIGHT WHITE CURLY BRACKET
+2985 ; Pattern_Syntax # Ps LEFT WHITE PARENTHESIS
+2986 ; Pattern_Syntax # Pe RIGHT WHITE PARENTHESIS
+2987 ; Pattern_Syntax # Ps Z NOTATION LEFT IMAGE BRACKET
+2988 ; Pattern_Syntax # Pe Z NOTATION RIGHT IMAGE BRACKET
+2989 ; Pattern_Syntax # Ps Z NOTATION LEFT BINDING BRACKET
+298A ; Pattern_Syntax # Pe Z NOTATION RIGHT BINDING BRACKET
+298B ; Pattern_Syntax # Ps LEFT SQUARE BRACKET WITH UNDERBAR
+298C ; Pattern_Syntax # Pe RIGHT SQUARE BRACKET WITH UNDERBAR
+298D ; Pattern_Syntax # Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
+298E ; Pattern_Syntax # Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+298F ; Pattern_Syntax # Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+2990 ; Pattern_Syntax # Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
+2991 ; Pattern_Syntax # Ps LEFT ANGLE BRACKET WITH DOT
+2992 ; Pattern_Syntax # Pe RIGHT ANGLE BRACKET WITH DOT
+2993 ; Pattern_Syntax # Ps LEFT ARC LESS-THAN BRACKET
+2994 ; Pattern_Syntax # Pe RIGHT ARC GREATER-THAN BRACKET
+2995 ; Pattern_Syntax # Ps DOUBLE LEFT ARC GREATER-THAN BRACKET
+2996 ; Pattern_Syntax # Pe DOUBLE RIGHT ARC LESS-THAN BRACKET
+2997 ; Pattern_Syntax # Ps LEFT BLACK TORTOISE SHELL BRACKET
+2998 ; Pattern_Syntax # Pe RIGHT BLACK TORTOISE SHELL BRACKET
+2999..29D7 ; Pattern_Syntax # Sm [63] DOTTED FENCE..BLACK HOURGLASS
+29D8 ; Pattern_Syntax # Ps LEFT WIGGLY FENCE
+29D9 ; Pattern_Syntax # Pe RIGHT WIGGLY FENCE
+29DA ; Pattern_Syntax # Ps LEFT DOUBLE WIGGLY FENCE
+29DB ; Pattern_Syntax # Pe RIGHT DOUBLE WIGGLY FENCE
+29DC..29FB ; Pattern_Syntax # Sm [32] INCOMPLETE INFINITY..TRIPLE PLUS
+29FC ; Pattern_Syntax # Ps LEFT-POINTING CURVED ANGLE BRACKET
+29FD ; Pattern_Syntax # Pe RIGHT-POINTING CURVED ANGLE BRACKET
+29FE..2AFF ; Pattern_Syntax # Sm [258] TINY..N-ARY WHITE VERTICAL BAR
+2B00..2B2F ; Pattern_Syntax # So [48] NORTH EAST WHITE ARROW..WHITE VERTICAL ELLIPSE
+2B30..2B44 ; Pattern_Syntax # Sm [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET
+2B45..2B46 ; Pattern_Syntax # So [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW
+2B47..2B4C ; Pattern_Syntax # Sm [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR
+2B4D..2B73 ; Pattern_Syntax # So [39] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR
+2B74..2B75 ; Pattern_Syntax # Cn [2] <reserved-2B74>..<reserved-2B75>
+2B76..2B95 ; Pattern_Syntax # So [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW
+2B96..2B97 ; Pattern_Syntax # Cn [2] <reserved-2B96>..<reserved-2B97>
+2B98..2BB9 ; Pattern_Syntax # So [34] THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD..UP ARROWHEAD IN A RECTANGLE BOX
+2BBA..2BBC ; Pattern_Syntax # Cn [3] <reserved-2BBA>..<reserved-2BBC>
+2BBD..2BC8 ; Pattern_Syntax # So [12] BALLOT BOX WITH LIGHT X..BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED
+2BC9 ; Pattern_Syntax # Cn <reserved-2BC9>
+2BCA..2BD1 ; Pattern_Syntax # So [8] TOP HALF BLACK CIRCLE..UNCERTAINTY SIGN
+2BD2..2BEB ; Pattern_Syntax # Cn [26] <reserved-2BD2>..<reserved-2BEB>
+2BEC..2BEF ; Pattern_Syntax # So [4] LEFTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS..DOWNWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS
+2BF0..2BFF ; Pattern_Syntax # Cn [16] <reserved-2BF0>..<reserved-2BFF>
+2E00..2E01 ; Pattern_Syntax # Po [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER
+2E02 ; Pattern_Syntax # Pi LEFT SUBSTITUTION BRACKET
+2E03 ; Pattern_Syntax # Pf RIGHT SUBSTITUTION BRACKET
+2E04 ; Pattern_Syntax # Pi LEFT DOTTED SUBSTITUTION BRACKET
+2E05 ; Pattern_Syntax # Pf RIGHT DOTTED SUBSTITUTION BRACKET
+2E06..2E08 ; Pattern_Syntax # Po [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER
+2E09 ; Pattern_Syntax # Pi LEFT TRANSPOSITION BRACKET
+2E0A ; Pattern_Syntax # Pf RIGHT TRANSPOSITION BRACKET
+2E0B ; Pattern_Syntax # Po RAISED SQUARE
+2E0C ; Pattern_Syntax # Pi LEFT RAISED OMISSION BRACKET
+2E0D ; Pattern_Syntax # Pf RIGHT RAISED OMISSION BRACKET
+2E0E..2E16 ; Pattern_Syntax # Po [9] EDITORIAL CORONIS..DOTTED RIGHT-POINTING ANGLE
+2E17 ; Pattern_Syntax # Pd DOUBLE OBLIQUE HYPHEN
+2E18..2E19 ; Pattern_Syntax # Po [2] INVERTED INTERROBANG..PALM BRANCH
+2E1A ; Pattern_Syntax # Pd HYPHEN WITH DIAERESIS
+2E1B ; Pattern_Syntax # Po TILDE WITH RING ABOVE
+2E1C ; Pattern_Syntax # Pi LEFT LOW PARAPHRASE BRACKET
+2E1D ; Pattern_Syntax # Pf RIGHT LOW PARAPHRASE BRACKET
+2E1E..2E1F ; Pattern_Syntax # Po [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW
+2E20 ; Pattern_Syntax # Pi LEFT VERTICAL BAR WITH QUILL
+2E21 ; Pattern_Syntax # Pf RIGHT VERTICAL BAR WITH QUILL
+2E22 ; Pattern_Syntax # Ps TOP LEFT HALF BRACKET
+2E23 ; Pattern_Syntax # Pe TOP RIGHT HALF BRACKET
+2E24 ; Pattern_Syntax # Ps BOTTOM LEFT HALF BRACKET
+2E25 ; Pattern_Syntax # Pe BOTTOM RIGHT HALF BRACKET
+2E26 ; Pattern_Syntax # Ps LEFT SIDEWAYS U BRACKET
+2E27 ; Pattern_Syntax # Pe RIGHT SIDEWAYS U BRACKET
+2E28 ; Pattern_Syntax # Ps LEFT DOUBLE PARENTHESIS
+2E29 ; Pattern_Syntax # Pe RIGHT DOUBLE PARENTHESIS
+2E2A..2E2E ; Pattern_Syntax # Po [5] TWO DOTS OVER ONE DOT PUNCTUATION..REVERSED QUESTION MARK
+2E2F ; Pattern_Syntax # Lm VERTICAL TILDE
+2E30..2E39 ; Pattern_Syntax # Po [10] RING POINT..TOP HALF SECTION SIGN
+2E3A..2E3B ; Pattern_Syntax # Pd [2] TWO-EM DASH..THREE-EM DASH
+2E3C..2E3F ; Pattern_Syntax # Po [4] STENOGRAPHIC FULL STOP..CAPITULUM
+2E40 ; Pattern_Syntax # Pd DOUBLE HYPHEN
+2E41 ; Pattern_Syntax # Po REVERSED COMMA
+2E42 ; Pattern_Syntax # Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK
+2E43..2E44 ; Pattern_Syntax # Po [2] DASH WITH LEFT UPTURN..DOUBLE SUSPENSION MARK
+2E45..2E7F ; Pattern_Syntax # Cn [59] <reserved-2E45>..<reserved-2E7F>
+3001..3003 ; Pattern_Syntax # Po [3] IDEOGRAPHIC COMMA..DITTO MARK
+3008 ; Pattern_Syntax # Ps LEFT ANGLE BRACKET
+3009 ; Pattern_Syntax # Pe RIGHT ANGLE BRACKET
+300A ; Pattern_Syntax # Ps LEFT DOUBLE ANGLE BRACKET
+300B ; Pattern_Syntax # Pe RIGHT DOUBLE ANGLE BRACKET
+300C ; Pattern_Syntax # Ps LEFT CORNER BRACKET
+300D ; Pattern_Syntax # Pe RIGHT CORNER BRACKET
+300E ; Pattern_Syntax # Ps LEFT WHITE CORNER BRACKET
+300F ; Pattern_Syntax # Pe RIGHT WHITE CORNER BRACKET
+3010 ; Pattern_Syntax # Ps LEFT BLACK LENTICULAR BRACKET
+3011 ; Pattern_Syntax # Pe RIGHT BLACK LENTICULAR BRACKET
+3012..3013 ; Pattern_Syntax # So [2] POSTAL MARK..GETA MARK
+3014 ; Pattern_Syntax # Ps LEFT TORTOISE SHELL BRACKET
+3015 ; Pattern_Syntax # Pe RIGHT TORTOISE SHELL BRACKET
+3016 ; Pattern_Syntax # Ps LEFT WHITE LENTICULAR BRACKET
+3017 ; Pattern_Syntax # Pe RIGHT WHITE LENTICULAR BRACKET
+3018 ; Pattern_Syntax # Ps LEFT WHITE TORTOISE SHELL BRACKET
+3019 ; Pattern_Syntax # Pe RIGHT WHITE TORTOISE SHELL BRACKET
+301A ; Pattern_Syntax # Ps LEFT WHITE SQUARE BRACKET
+301B ; Pattern_Syntax # Pe RIGHT WHITE SQUARE BRACKET
+301C ; Pattern_Syntax # Pd WAVE DASH
+301D ; Pattern_Syntax # Ps REVERSED DOUBLE PRIME QUOTATION MARK
+301E..301F ; Pattern_Syntax # Pe [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK
+3020 ; Pattern_Syntax # So POSTAL MARK FACE
+3030 ; Pattern_Syntax # Pd WAVY DASH
+FD3E ; Pattern_Syntax # Pe ORNATE LEFT PARENTHESIS
+FD3F ; Pattern_Syntax # Ps ORNATE RIGHT PARENTHESIS
+FE45..FE46 ; Pattern_Syntax # Po [2] SESAME DOT..WHITE SESAME DOT
+
+# Total code points: 2760
+
+# ================================================
+
+0600..0605 ; Prepended_Concatenation_Mark # Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE
+06DD ; Prepended_Concatenation_Mark # Cf ARABIC END OF AYAH
+070F ; Prepended_Concatenation_Mark # Cf SYRIAC ABBREVIATION MARK
+08E2 ; Prepended_Concatenation_Mark # Cf ARABIC DISPUTED END OF AYAH
+110BD ; Prepended_Concatenation_Mark # Cf KAITHI NUMBER SIGN
+
+# Total code points: 10
+
+# EOF
diff --git a/lib/stdlib/uc_spec/README-UPDATE.txt b/lib/stdlib/uc_spec/README-UPDATE.txt
new file mode 100644
index 0000000000..d59337e1a5
--- /dev/null
+++ b/lib/stdlib/uc_spec/README-UPDATE.txt
@@ -0,0 +1,7 @@
+When updating the unicode version copy the necessary files to this
+directory.
+
+And update the test files in stdlib/test/unicode_util_SUITE_data/*
+
+Update the spec_version(..) function in the generator,
+gen_unicode_mod.escript
diff --git a/lib/stdlib/uc_spec/SpecialCasing.txt b/lib/stdlib/uc_spec/SpecialCasing.txt
new file mode 100644
index 0000000000..b23fa7f768
--- /dev/null
+++ b/lib/stdlib/uc_spec/SpecialCasing.txt
@@ -0,0 +1,281 @@
+# SpecialCasing-9.0.0.txt
+# Date: 2016-03-02, 18:55:13 GMT
+# © 2016 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see http://www.unicode.org/reports/tr44/
+#
+# Special Casing
+#
+# This file is a supplement to the UnicodeData.txt file. It does not define any
+# properties, but rather provides additional information about the casing of
+# Unicode characters, for situations when casing incurs a change in string length
+# or is dependent on context or locale. For compatibility, the UnicodeData.txt
+# file only contains simple case mappings for characters where they are one-to-one
+# and independent of context and language. The data in this file, combined with
+# the simple case mappings in UnicodeData.txt, defines the full case mappings
+# Lowercase_Mapping (lc), Titlecase_Mapping (tc), and Uppercase_Mapping (uc).
+#
+# Note that the preferred mechanism for defining tailored casing operations is
+# the Unicode Common Locale Data Repository (CLDR). For more information, see the
+# discussion of case mappings and case algorithms in the Unicode Standard.
+#
+# All code points not listed in this file that do not have a simple case mappings
+# in UnicodeData.txt map to themselves.
+# ================================================================================
+# Format
+# ================================================================================
+# The entries in this file are in the following machine-readable format:
+#
+# <code>; <lower>; <title>; <upper>; (<condition_list>;)? # <comment>
+#
+# <code>, <lower>, <title>, and <upper> provide the respective full case mappings
+# of <code>, expressed as character values in hex. If there is more than one character,
+# they are separated by spaces. Other than as used to separate elements, spaces are
+# to be ignored.
+#
+# The <condition_list> is optional. Where present, it consists of one or more language IDs
+# or casing contexts, separated by spaces. In these conditions:
+# - A condition list overrides the normal behavior if all of the listed conditions are true.
+# - The casing context is always the context of the characters in the original string,
+# NOT in the resulting string.
+# - Case distinctions in the condition list are not significant.
+# - Conditions preceded by "Not_" represent the negation of the condition.
+# The condition list is not represented in the UCD as a formal property.
+#
+# A language ID is defined by BCP 47, with '-' and '_' treated equivalently.
+#
+# A casing context for a character is defined by Section 3.13 Default Case Algorithms
+# of The Unicode Standard.
+#
+# Parsers of this file must be prepared to deal with future additions to this format:
+# * Additional contexts
+# * Additional fields
+# ================================================================================
+
+# ================================================================================
+# Unconditional mappings
+# ================================================================================
+
+# The German es-zed is special--the normal mapping is to SS.
+# Note: the titlecase should never occur in practice. It is equal to titlecase(uppercase(<es-zed>))
+
+00DF; 00DF; 0053 0073; 0053 0053; # LATIN SMALL LETTER SHARP S
+
+# Preserve canonical equivalence for I with dot. Turkic is handled below.
+
+0130; 0069 0307; 0130; 0130; # LATIN CAPITAL LETTER I WITH DOT ABOVE
+
+# Ligatures
+
+FB00; FB00; 0046 0066; 0046 0046; # LATIN SMALL LIGATURE FF
+FB01; FB01; 0046 0069; 0046 0049; # LATIN SMALL LIGATURE FI
+FB02; FB02; 0046 006C; 0046 004C; # LATIN SMALL LIGATURE FL
+FB03; FB03; 0046 0066 0069; 0046 0046 0049; # LATIN SMALL LIGATURE FFI
+FB04; FB04; 0046 0066 006C; 0046 0046 004C; # LATIN SMALL LIGATURE FFL
+FB05; FB05; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE LONG S T
+FB06; FB06; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE ST
+
+0587; 0587; 0535 0582; 0535 0552; # ARMENIAN SMALL LIGATURE ECH YIWN
+FB13; FB13; 0544 0576; 0544 0546; # ARMENIAN SMALL LIGATURE MEN NOW
+FB14; FB14; 0544 0565; 0544 0535; # ARMENIAN SMALL LIGATURE MEN ECH
+FB15; FB15; 0544 056B; 0544 053B; # ARMENIAN SMALL LIGATURE MEN INI
+FB16; FB16; 054E 0576; 054E 0546; # ARMENIAN SMALL LIGATURE VEW NOW
+FB17; FB17; 0544 056D; 0544 053D; # ARMENIAN SMALL LIGATURE MEN XEH
+
+# No corresponding uppercase precomposed character
+
+0149; 0149; 02BC 004E; 02BC 004E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+0390; 0390; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+03B0; 03B0; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+01F0; 01F0; 004A 030C; 004A 030C; # LATIN SMALL LETTER J WITH CARON
+1E96; 1E96; 0048 0331; 0048 0331; # LATIN SMALL LETTER H WITH LINE BELOW
+1E97; 1E97; 0054 0308; 0054 0308; # LATIN SMALL LETTER T WITH DIAERESIS
+1E98; 1E98; 0057 030A; 0057 030A; # LATIN SMALL LETTER W WITH RING ABOVE
+1E99; 1E99; 0059 030A; 0059 030A; # LATIN SMALL LETTER Y WITH RING ABOVE
+1E9A; 1E9A; 0041 02BE; 0041 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING
+1F50; 1F50; 03A5 0313; 03A5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI
+1F52; 1F52; 03A5 0313 0300; 03A5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
+1F54; 1F54; 03A5 0313 0301; 03A5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
+1F56; 1F56; 03A5 0313 0342; 03A5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
+1FB6; 1FB6; 0391 0342; 0391 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI
+1FC6; 1FC6; 0397 0342; 0397 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI
+1FD2; 1FD2; 0399 0308 0300; 0399 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
+1FD3; 1FD3; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
+1FD6; 1FD6; 0399 0342; 0399 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI
+1FD7; 1FD7; 0399 0308 0342; 0399 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
+1FE2; 1FE2; 03A5 0308 0300; 03A5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
+1FE3; 1FE3; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
+1FE4; 1FE4; 03A1 0313; 03A1 0313; # GREEK SMALL LETTER RHO WITH PSILI
+1FE6; 1FE6; 03A5 0342; 03A5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI
+1FE7; 1FE7; 03A5 0308 0342; 03A5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
+1FF6; 1FF6; 03A9 0342; 03A9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI
+
+# IMPORTANT-when iota-subscript (0345) is uppercased or titlecased,
+# the result will be incorrect unless the iota-subscript is moved to the end
+# of any sequence of combining marks. Otherwise, the accents will go on the capital iota.
+# This process can be achieved by first transforming the text to NFC before casing.
+# E.g. <alpha><iota_subscript><acute> is uppercased to <ALPHA><acute><IOTA>
+
+# The following cases are already in the UnicodeData.txt file, so are only commented here.
+
+# 0345; 0345; 0345; 0399; # COMBINING GREEK YPOGEGRAMMENI
+
+# All letters with YPOGEGRAMMENI (iota-subscript) or PROSGEGRAMMENI (iota adscript)
+# have special uppercases.
+# Note: characters with PROSGEGRAMMENI are actually titlecase, not uppercase!
+
+1F80; 1F80; 1F88; 1F08 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
+1F81; 1F81; 1F89; 1F09 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
+1F82; 1F82; 1F8A; 1F0A 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1F83; 1F83; 1F8B; 1F0B 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1F84; 1F84; 1F8C; 1F0C 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1F85; 1F85; 1F8D; 1F0D 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1F86; 1F86; 1F8E; 1F0E 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1F87; 1F87; 1F8F; 1F0F 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1F88; 1F80; 1F88; 1F08 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
+1F89; 1F81; 1F89; 1F09 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
+1F8A; 1F82; 1F8A; 1F0A 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F8B; 1F83; 1F8B; 1F0B 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F8C; 1F84; 1F8C; 1F0C 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F8D; 1F85; 1F8D; 1F0D 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F8E; 1F86; 1F8E; 1F0E 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F8F; 1F87; 1F8F; 1F0F 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1F90; 1F90; 1F98; 1F28 0399; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
+1F91; 1F91; 1F99; 1F29 0399; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
+1F92; 1F92; 1F9A; 1F2A 0399; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1F93; 1F93; 1F9B; 1F2B 0399; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1F94; 1F94; 1F9C; 1F2C 0399; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1F95; 1F95; 1F9D; 1F2D 0399; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1F96; 1F96; 1F9E; 1F2E 0399; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1F97; 1F97; 1F9F; 1F2F 0399; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1F98; 1F90; 1F98; 1F28 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
+1F99; 1F91; 1F99; 1F29 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
+1F9A; 1F92; 1F9A; 1F2A 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F9B; 1F93; 1F9B; 1F2B 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F9C; 1F94; 1F9C; 1F2C 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F9D; 1F95; 1F9D; 1F2D 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F9E; 1F96; 1F9E; 1F2E 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F9F; 1F97; 1F9F; 1F2F 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1FA0; 1FA0; 1FA8; 1F68 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
+1FA1; 1FA1; 1FA9; 1F69 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
+1FA2; 1FA2; 1FAA; 1F6A 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1FA3; 1FA3; 1FAB; 1F6B 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1FA4; 1FA4; 1FAC; 1F6C 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1FA5; 1FA5; 1FAD; 1F6D 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1FA6; 1FA6; 1FAE; 1F6E 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1FA7; 1FA7; 1FAF; 1F6F 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1FA8; 1FA0; 1FA8; 1F68 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
+1FA9; 1FA1; 1FA9; 1F69 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
+1FAA; 1FA2; 1FAA; 1F6A 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1FAB; 1FA3; 1FAB; 1F6B 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1FAC; 1FA4; 1FAC; 1F6C 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1FAD; 1FA5; 1FAD; 1F6D 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1FAE; 1FA6; 1FAE; 1F6E 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1FAF; 1FA7; 1FAF; 1F6F 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1FB3; 1FB3; 1FBC; 0391 0399; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
+1FBC; 1FB3; 1FBC; 0391 0399; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+1FC3; 1FC3; 1FCC; 0397 0399; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
+1FCC; 1FC3; 1FCC; 0397 0399; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+1FF3; 1FF3; 1FFC; 03A9 0399; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
+1FFC; 1FF3; 1FFC; 03A9 0399; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+
+# Some characters with YPOGEGRAMMENI also have no corresponding titlecases
+
+1FB2; 1FB2; 1FBA 0345; 1FBA 0399; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
+1FB4; 1FB4; 0386 0345; 0386 0399; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
+1FC2; 1FC2; 1FCA 0345; 1FCA 0399; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
+1FC4; 1FC4; 0389 0345; 0389 0399; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
+1FF2; 1FF2; 1FFA 0345; 1FFA 0399; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
+1FF4; 1FF4; 038F 0345; 038F 0399; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
+
+1FB7; 1FB7; 0391 0342 0345; 0391 0342 0399; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
+1FC7; 1FC7; 0397 0342 0345; 0397 0342 0399; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
+1FF7; 1FF7; 03A9 0342 0345; 03A9 0342 0399; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
+
+# ================================================================================
+# Conditional Mappings
+# The remainder of this file provides conditional casing data used to produce
+# full case mappings.
+# ================================================================================
+# Language-Insensitive Mappings
+# These are characters whose full case mappings do not depend on language, but do
+# depend on context (which characters come before or after). For more information
+# see the header of this file and the Unicode Standard.
+# ================================================================================
+
+# Special case for final form of sigma
+
+03A3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK CAPITAL LETTER SIGMA
+
+# Note: the following cases for non-final are already in the UnicodeData.txt file.
+
+# 03A3; 03C3; 03A3; 03A3; # GREEK CAPITAL LETTER SIGMA
+# 03C3; 03C3; 03A3; 03A3; # GREEK SMALL LETTER SIGMA
+# 03C2; 03C2; 03A3; 03A3; # GREEK SMALL LETTER FINAL SIGMA
+
+# Note: the following cases are not included, since they would case-fold in lowercasing
+
+# 03C3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK SMALL LETTER SIGMA
+# 03C2; 03C3; 03A3; 03A3; Not_Final_Sigma; # GREEK SMALL LETTER FINAL SIGMA
+
+# ================================================================================
+# Language-Sensitive Mappings
+# These are characters whose full case mappings depend on language and perhaps also
+# context (which characters come before or after). For more information
+# see the header of this file and the Unicode Standard.
+# ================================================================================
+
+# Lithuanian
+
+# Lithuanian retains the dot in a lowercase i when followed by accents.
+
+# Remove DOT ABOVE after "i" with upper or titlecase
+
+0307; 0307; ; ; lt After_Soft_Dotted; # COMBINING DOT ABOVE
+
+# Introduce an explicit dot above when lowercasing capital I's and J's
+# whenever there are more accents above.
+# (of the accents used in Lithuanian: grave, acute, tilde above, and ogonek)
+
+0049; 0069 0307; 0049; 0049; lt More_Above; # LATIN CAPITAL LETTER I
+004A; 006A 0307; 004A; 004A; lt More_Above; # LATIN CAPITAL LETTER J
+012E; 012F 0307; 012E; 012E; lt More_Above; # LATIN CAPITAL LETTER I WITH OGONEK
+00CC; 0069 0307 0300; 00CC; 00CC; lt; # LATIN CAPITAL LETTER I WITH GRAVE
+00CD; 0069 0307 0301; 00CD; 00CD; lt; # LATIN CAPITAL LETTER I WITH ACUTE
+0128; 0069 0307 0303; 0128; 0128; lt; # LATIN CAPITAL LETTER I WITH TILDE
+
+# ================================================================================
+
+# Turkish and Azeri
+
+# I and i-dotless; I-dot and i are case pairs in Turkish and Azeri
+# The following rules handle those cases.
+
+0130; 0069; 0130; 0130; tr; # LATIN CAPITAL LETTER I WITH DOT ABOVE
+0130; 0069; 0130; 0130; az; # LATIN CAPITAL LETTER I WITH DOT ABOVE
+
+# When lowercasing, remove dot_above in the sequence I + dot_above, which will turn into i.
+# This matches the behavior of the canonically equivalent I-dot_above
+
+0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE
+0307; ; 0307; 0307; az After_I; # COMBINING DOT ABOVE
+
+# When lowercasing, unless an I is before a dot_above, it turns into a dotless i.
+
+0049; 0131; 0049; 0049; tr Not_Before_Dot; # LATIN CAPITAL LETTER I
+0049; 0131; 0049; 0049; az Not_Before_Dot; # LATIN CAPITAL LETTER I
+
+# When uppercasing, i turns into a dotted capital I
+
+0069; 0069; 0130; 0130; tr; # LATIN SMALL LETTER I
+0069; 0069; 0130; 0130; az; # LATIN SMALL LETTER I
+
+# Note: the following case is already in the UnicodeData.txt file.
+
+# 0131; 0131; 0049; 0049; tr; # LATIN SMALL LETTER DOTLESS I
+
+# EOF
+
diff --git a/lib/stdlib/uc_spec/UnicodeData.txt b/lib/stdlib/uc_spec/UnicodeData.txt
new file mode 100644
index 0000000000..a756976461
--- /dev/null
+++ b/lib/stdlib/uc_spec/UnicodeData.txt
@@ -0,0 +1,30592 @@
+0000;<control>;Cc;0;BN;;;;;N;NULL;;;;
+0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;;
+0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;;
+0003;<control>;Cc;0;BN;;;;;N;END OF TEXT;;;;
+0004;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;;
+0005;<control>;Cc;0;BN;;;;;N;ENQUIRY;;;;
+0006;<control>;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;;
+0007;<control>;Cc;0;BN;;;;;N;BELL;;;;
+0008;<control>;Cc;0;BN;;;;;N;BACKSPACE;;;;
+0009;<control>;Cc;0;S;;;;;N;CHARACTER TABULATION;;;;
+000A;<control>;Cc;0;B;;;;;N;LINE FEED (LF);;;;
+000B;<control>;Cc;0;S;;;;;N;LINE TABULATION;;;;
+000C;<control>;Cc;0;WS;;;;;N;FORM FEED (FF);;;;
+000D;<control>;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;;
+000E;<control>;Cc;0;BN;;;;;N;SHIFT OUT;;;;
+000F;<control>;Cc;0;BN;;;;;N;SHIFT IN;;;;
+0010;<control>;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;;
+0011;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;;
+0012;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;;
+0013;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;;
+0014;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;;
+0015;<control>;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;;
+0016;<control>;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;;
+0017;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;;
+0018;<control>;Cc;0;BN;;;;;N;CANCEL;;;;
+0019;<control>;Cc;0;BN;;;;;N;END OF MEDIUM;;;;
+001A;<control>;Cc;0;BN;;;;;N;SUBSTITUTE;;;;
+001B;<control>;Cc;0;BN;;;;;N;ESCAPE;;;;
+001C;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR FOUR;;;;
+001D;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;;
+001E;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;;
+001F;<control>;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;;
+0020;SPACE;Zs;0;WS;;;;;N;;;;;
+0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;;
+0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;;
+0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;;
+0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;;
+0026;AMPERSAND;Po;0;ON;;;;;N;;;;;
+0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;;
+0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;;
+0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;;
+002A;ASTERISK;Po;0;ON;;;;;N;;;;;
+002B;PLUS SIGN;Sm;0;ES;;;;;N;;;;;
+002C;COMMA;Po;0;CS;;;;;N;;;;;
+002D;HYPHEN-MINUS;Pd;0;ES;;;;;N;;;;;
+002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;;
+002F;SOLIDUS;Po;0;CS;;;;;N;SLASH;;;;
+0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;;
+0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;;
+0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;;
+0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;;
+0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;;
+0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;;
+0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;;
+0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;;
+0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;;
+0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;;
+003A;COLON;Po;0;CS;;;;;N;;;;;
+003B;SEMICOLON;Po;0;ON;;;;;N;;;;;
+003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;;
+003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;;
+003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;;
+003F;QUESTION MARK;Po;0;ON;;;;;N;;;;;
+0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;;
+0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;
+0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062;
+0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063;
+0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064;
+0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065;
+0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066;
+0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067;
+0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068;
+0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069;
+004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A;
+004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B;
+004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C;
+004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D;
+004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E;
+004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F;
+0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070;
+0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071;
+0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072;
+0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073;
+0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074;
+0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075;
+0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076;
+0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077;
+0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078;
+0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079;
+005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A;
+005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;;
+005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;;
+005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;;
+005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;;
+005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;;
+0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;;
+0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041
+0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042
+0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043
+0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044
+0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045
+0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046
+0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047
+0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048
+0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049
+006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A
+006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B
+006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C
+006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D
+006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E
+006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F
+0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050
+0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051
+0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052
+0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053
+0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054
+0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055
+0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056
+0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057
+0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058
+0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059
+007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A
+007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;;
+007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;;
+007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;;
+007E;TILDE;Sm;0;ON;;;;;N;;;;;
+007F;<control>;Cc;0;BN;;;;;N;DELETE;;;;
+0080;<control>;Cc;0;BN;;;;;N;;;;;
+0081;<control>;Cc;0;BN;;;;;N;;;;;
+0082;<control>;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;;
+0083;<control>;Cc;0;BN;;;;;N;NO BREAK HERE;;;;
+0084;<control>;Cc;0;BN;;;;;N;;;;;
+0085;<control>;Cc;0;B;;;;;N;NEXT LINE (NEL);;;;
+0086;<control>;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;;
+0087;<control>;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;;
+0088;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;;
+0089;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;;
+008A;<control>;Cc;0;BN;;;;;N;LINE TABULATION SET;;;;
+008B;<control>;Cc;0;BN;;;;;N;PARTIAL LINE FORWARD;;;;
+008C;<control>;Cc;0;BN;;;;;N;PARTIAL LINE BACKWARD;;;;
+008D;<control>;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;;
+008E;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;;
+008F;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;;
+0090;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;;
+0091;<control>;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;;
+0092;<control>;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;;
+0093;<control>;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;;
+0094;<control>;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;;
+0095;<control>;Cc;0;BN;;;;;N;MESSAGE WAITING;;;;
+0096;<control>;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;;
+0097;<control>;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;;
+0098;<control>;Cc;0;BN;;;;;N;START OF STRING;;;;
+0099;<control>;Cc;0;BN;;;;;N;;;;;
+009A;<control>;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;;
+009B;<control>;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;;
+009C;<control>;Cc;0;BN;;;;;N;STRING TERMINATOR;;;;
+009D;<control>;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;;
+009E;<control>;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;;
+009F;<control>;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;;
+00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;
+00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;;
+00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;;
+00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;
+00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;;
+00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;;
+00A7;SECTION SIGN;Po;0;ON;;;;;N;;;;;
+00A8;DIAERESIS;Sk;0;ON;<compat> 0020 0308;;;;N;SPACING DIAERESIS;;;;
+00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;;
+00AA;FEMININE ORDINAL INDICATOR;Lo;0;L;<super> 0061;;;;N;;;;;
+00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;;;;
+00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;;
+00AD;SOFT HYPHEN;Cf;0;BN;;;;;N;;;;;
+00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;;
+00AF;MACRON;Sk;0;ON;<compat> 0020 0304;;;;N;SPACING MACRON;;;;
+00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;;
+00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;;
+00B2;SUPERSCRIPT TWO;No;0;EN;<super> 0032;;2;2;N;SUPERSCRIPT DIGIT TWO;;;;
+00B3;SUPERSCRIPT THREE;No;0;EN;<super> 0033;;3;3;N;SUPERSCRIPT DIGIT THREE;;;;
+00B4;ACUTE ACCENT;Sk;0;ON;<compat> 0020 0301;;;;N;SPACING ACUTE;;;;
+00B5;MICRO SIGN;Ll;0;L;<compat> 03BC;;;;N;;;039C;;039C
+00B6;PILCROW SIGN;Po;0;ON;;;;;N;PARAGRAPH SIGN;;;;
+00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;;
+00B8;CEDILLA;Sk;0;ON;<compat> 0020 0327;;;;N;SPACING CEDILLA;;;;
+00B9;SUPERSCRIPT ONE;No;0;EN;<super> 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;;
+00BA;MASCULINE ORDINAL INDICATOR;Lo;0;L;<super> 006F;;;;N;;;;;
+00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;;;;
+00BC;VULGAR FRACTION ONE QUARTER;No;0;ON;<fraction> 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;;
+00BD;VULGAR FRACTION ONE HALF;No;0;ON;<fraction> 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;;
+00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON;<fraction> 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;;
+00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;;
+00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0;
+00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1;
+00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2;
+00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3;
+00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4;
+00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5;
+00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;;;00E6;
+00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7;
+00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8;
+00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9;
+00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA;
+00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB;
+00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC;
+00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED;
+00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE;
+00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF;
+00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;00F0;
+00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1;
+00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2;
+00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3;
+00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4;
+00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5;
+00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6;
+00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;;
+00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8;
+00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9;
+00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA;
+00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB;
+00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC;
+00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD;
+00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;;;00FE;
+00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;;;;
+00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0
+00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1
+00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2
+00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3
+00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4
+00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5
+00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;;00C6;;00C6
+00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7
+00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8
+00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9
+00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA
+00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB
+00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC
+00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD
+00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE
+00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF
+00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;;00D0;;00D0
+00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1
+00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2
+00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3
+00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4
+00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5
+00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6
+00F7;DIVISION SIGN;Sm;0;ON;;;;;N;;;;;
+00F8;LATIN SMALL LETTER O WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER O SLASH;;00D8;;00D8
+00F9;LATIN SMALL LETTER U WITH GRAVE;Ll;0;L;0075 0300;;;;N;LATIN SMALL LETTER U GRAVE;;00D9;;00D9
+00FA;LATIN SMALL LETTER U WITH ACUTE;Ll;0;L;0075 0301;;;;N;LATIN SMALL LETTER U ACUTE;;00DA;;00DA
+00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB
+00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC
+00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD
+00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;;00DE;;00DE
+00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178
+0100;LATIN CAPITAL LETTER A WITH MACRON;Lu;0;L;0041 0304;;;;N;LATIN CAPITAL LETTER A MACRON;;;0101;
+0101;LATIN SMALL LETTER A WITH MACRON;Ll;0;L;0061 0304;;;;N;LATIN SMALL LETTER A MACRON;;0100;;0100
+0102;LATIN CAPITAL LETTER A WITH BREVE;Lu;0;L;0041 0306;;;;N;LATIN CAPITAL LETTER A BREVE;;;0103;
+0103;LATIN SMALL LETTER A WITH BREVE;Ll;0;L;0061 0306;;;;N;LATIN SMALL LETTER A BREVE;;0102;;0102
+0104;LATIN CAPITAL LETTER A WITH OGONEK;Lu;0;L;0041 0328;;;;N;LATIN CAPITAL LETTER A OGONEK;;;0105;
+0105;LATIN SMALL LETTER A WITH OGONEK;Ll;0;L;0061 0328;;;;N;LATIN SMALL LETTER A OGONEK;;0104;;0104
+0106;LATIN CAPITAL LETTER C WITH ACUTE;Lu;0;L;0043 0301;;;;N;LATIN CAPITAL LETTER C ACUTE;;;0107;
+0107;LATIN SMALL LETTER C WITH ACUTE;Ll;0;L;0063 0301;;;;N;LATIN SMALL LETTER C ACUTE;;0106;;0106
+0108;LATIN CAPITAL LETTER C WITH CIRCUMFLEX;Lu;0;L;0043 0302;;;;N;LATIN CAPITAL LETTER C CIRCUMFLEX;;;0109;
+0109;LATIN SMALL LETTER C WITH CIRCUMFLEX;Ll;0;L;0063 0302;;;;N;LATIN SMALL LETTER C CIRCUMFLEX;;0108;;0108
+010A;LATIN CAPITAL LETTER C WITH DOT ABOVE;Lu;0;L;0043 0307;;;;N;LATIN CAPITAL LETTER C DOT;;;010B;
+010B;LATIN SMALL LETTER C WITH DOT ABOVE;Ll;0;L;0063 0307;;;;N;LATIN SMALL LETTER C DOT;;010A;;010A
+010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D;
+010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C
+010E;LATIN CAPITAL LETTER D WITH CARON;Lu;0;L;0044 030C;;;;N;LATIN CAPITAL LETTER D HACEK;;;010F;
+010F;LATIN SMALL LETTER D WITH CARON;Ll;0;L;0064 030C;;;;N;LATIN SMALL LETTER D HACEK;;010E;;010E
+0110;LATIN CAPITAL LETTER D WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D BAR;;;0111;
+0111;LATIN SMALL LETTER D WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER D BAR;;0110;;0110
+0112;LATIN CAPITAL LETTER E WITH MACRON;Lu;0;L;0045 0304;;;;N;LATIN CAPITAL LETTER E MACRON;;;0113;
+0113;LATIN SMALL LETTER E WITH MACRON;Ll;0;L;0065 0304;;;;N;LATIN SMALL LETTER E MACRON;;0112;;0112
+0114;LATIN CAPITAL LETTER E WITH BREVE;Lu;0;L;0045 0306;;;;N;LATIN CAPITAL LETTER E BREVE;;;0115;
+0115;LATIN SMALL LETTER E WITH BREVE;Ll;0;L;0065 0306;;;;N;LATIN SMALL LETTER E BREVE;;0114;;0114
+0116;LATIN CAPITAL LETTER E WITH DOT ABOVE;Lu;0;L;0045 0307;;;;N;LATIN CAPITAL LETTER E DOT;;;0117;
+0117;LATIN SMALL LETTER E WITH DOT ABOVE;Ll;0;L;0065 0307;;;;N;LATIN SMALL LETTER E DOT;;0116;;0116
+0118;LATIN CAPITAL LETTER E WITH OGONEK;Lu;0;L;0045 0328;;;;N;LATIN CAPITAL LETTER E OGONEK;;;0119;
+0119;LATIN SMALL LETTER E WITH OGONEK;Ll;0;L;0065 0328;;;;N;LATIN SMALL LETTER E OGONEK;;0118;;0118
+011A;LATIN CAPITAL LETTER E WITH CARON;Lu;0;L;0045 030C;;;;N;LATIN CAPITAL LETTER E HACEK;;;011B;
+011B;LATIN SMALL LETTER E WITH CARON;Ll;0;L;0065 030C;;;;N;LATIN SMALL LETTER E HACEK;;011A;;011A
+011C;LATIN CAPITAL LETTER G WITH CIRCUMFLEX;Lu;0;L;0047 0302;;;;N;LATIN CAPITAL LETTER G CIRCUMFLEX;;;011D;
+011D;LATIN SMALL LETTER G WITH CIRCUMFLEX;Ll;0;L;0067 0302;;;;N;LATIN SMALL LETTER G CIRCUMFLEX;;011C;;011C
+011E;LATIN CAPITAL LETTER G WITH BREVE;Lu;0;L;0047 0306;;;;N;LATIN CAPITAL LETTER G BREVE;;;011F;
+011F;LATIN SMALL LETTER G WITH BREVE;Ll;0;L;0067 0306;;;;N;LATIN SMALL LETTER G BREVE;;011E;;011E
+0120;LATIN CAPITAL LETTER G WITH DOT ABOVE;Lu;0;L;0047 0307;;;;N;LATIN CAPITAL LETTER G DOT;;;0121;
+0121;LATIN SMALL LETTER G WITH DOT ABOVE;Ll;0;L;0067 0307;;;;N;LATIN SMALL LETTER G DOT;;0120;;0120
+0122;LATIN CAPITAL LETTER G WITH CEDILLA;Lu;0;L;0047 0327;;;;N;LATIN CAPITAL LETTER G CEDILLA;;;0123;
+0123;LATIN SMALL LETTER G WITH CEDILLA;Ll;0;L;0067 0327;;;;N;LATIN SMALL LETTER G CEDILLA;;0122;;0122
+0124;LATIN CAPITAL LETTER H WITH CIRCUMFLEX;Lu;0;L;0048 0302;;;;N;LATIN CAPITAL LETTER H CIRCUMFLEX;;;0125;
+0125;LATIN SMALL LETTER H WITH CIRCUMFLEX;Ll;0;L;0068 0302;;;;N;LATIN SMALL LETTER H CIRCUMFLEX;;0124;;0124
+0126;LATIN CAPITAL LETTER H WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER H BAR;;;0127;
+0127;LATIN SMALL LETTER H WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER H BAR;;0126;;0126
+0128;LATIN CAPITAL LETTER I WITH TILDE;Lu;0;L;0049 0303;;;;N;LATIN CAPITAL LETTER I TILDE;;;0129;
+0129;LATIN SMALL LETTER I WITH TILDE;Ll;0;L;0069 0303;;;;N;LATIN SMALL LETTER I TILDE;;0128;;0128
+012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B;
+012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A
+012C;LATIN CAPITAL LETTER I WITH BREVE;Lu;0;L;0049 0306;;;;N;LATIN CAPITAL LETTER I BREVE;;;012D;
+012D;LATIN SMALL LETTER I WITH BREVE;Ll;0;L;0069 0306;;;;N;LATIN SMALL LETTER I BREVE;;012C;;012C
+012E;LATIN CAPITAL LETTER I WITH OGONEK;Lu;0;L;0049 0328;;;;N;LATIN CAPITAL LETTER I OGONEK;;;012F;
+012F;LATIN SMALL LETTER I WITH OGONEK;Ll;0;L;0069 0328;;;;N;LATIN SMALL LETTER I OGONEK;;012E;;012E
+0130;LATIN CAPITAL LETTER I WITH DOT ABOVE;Lu;0;L;0049 0307;;;;N;LATIN CAPITAL LETTER I DOT;;;0069;
+0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049
+0132;LATIN CAPITAL LIGATURE IJ;Lu;0;L;<compat> 0049 004A;;;;N;LATIN CAPITAL LETTER I J;;;0133;
+0133;LATIN SMALL LIGATURE IJ;Ll;0;L;<compat> 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132
+0134;LATIN CAPITAL LETTER J WITH CIRCUMFLEX;Lu;0;L;004A 0302;;;;N;LATIN CAPITAL LETTER J CIRCUMFLEX;;;0135;
+0135;LATIN SMALL LETTER J WITH CIRCUMFLEX;Ll;0;L;006A 0302;;;;N;LATIN SMALL LETTER J CIRCUMFLEX;;0134;;0134
+0136;LATIN CAPITAL LETTER K WITH CEDILLA;Lu;0;L;004B 0327;;;;N;LATIN CAPITAL LETTER K CEDILLA;;;0137;
+0137;LATIN SMALL LETTER K WITH CEDILLA;Ll;0;L;006B 0327;;;;N;LATIN SMALL LETTER K CEDILLA;;0136;;0136
+0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;;;;
+0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A;
+013A;LATIN SMALL LETTER L WITH ACUTE;Ll;0;L;006C 0301;;;;N;LATIN SMALL LETTER L ACUTE;;0139;;0139
+013B;LATIN CAPITAL LETTER L WITH CEDILLA;Lu;0;L;004C 0327;;;;N;LATIN CAPITAL LETTER L CEDILLA;;;013C;
+013C;LATIN SMALL LETTER L WITH CEDILLA;Ll;0;L;006C 0327;;;;N;LATIN SMALL LETTER L CEDILLA;;013B;;013B
+013D;LATIN CAPITAL LETTER L WITH CARON;Lu;0;L;004C 030C;;;;N;LATIN CAPITAL LETTER L HACEK;;;013E;
+013E;LATIN SMALL LETTER L WITH CARON;Ll;0;L;006C 030C;;;;N;LATIN SMALL LETTER L HACEK;;013D;;013D
+013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L;<compat> 004C 00B7;;;;N;;;;0140;
+0140;LATIN SMALL LETTER L WITH MIDDLE DOT;Ll;0;L;<compat> 006C 00B7;;;;N;;;013F;;013F
+0141;LATIN CAPITAL LETTER L WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER L SLASH;;;0142;
+0142;LATIN SMALL LETTER L WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER L SLASH;;0141;;0141
+0143;LATIN CAPITAL LETTER N WITH ACUTE;Lu;0;L;004E 0301;;;;N;LATIN CAPITAL LETTER N ACUTE;;;0144;
+0144;LATIN SMALL LETTER N WITH ACUTE;Ll;0;L;006E 0301;;;;N;LATIN SMALL LETTER N ACUTE;;0143;;0143
+0145;LATIN CAPITAL LETTER N WITH CEDILLA;Lu;0;L;004E 0327;;;;N;LATIN CAPITAL LETTER N CEDILLA;;;0146;
+0146;LATIN SMALL LETTER N WITH CEDILLA;Ll;0;L;006E 0327;;;;N;LATIN SMALL LETTER N CEDILLA;;0145;;0145
+0147;LATIN CAPITAL LETTER N WITH CARON;Lu;0;L;004E 030C;;;;N;LATIN CAPITAL LETTER N HACEK;;;0148;
+0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147
+0149;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE;Ll;0;L;<compat> 02BC 006E;;;;N;LATIN SMALL LETTER APOSTROPHE N;;;;
+014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;014B;
+014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;;014A;;014A
+014C;LATIN CAPITAL LETTER O WITH MACRON;Lu;0;L;004F 0304;;;;N;LATIN CAPITAL LETTER O MACRON;;;014D;
+014D;LATIN SMALL LETTER O WITH MACRON;Ll;0;L;006F 0304;;;;N;LATIN SMALL LETTER O MACRON;;014C;;014C
+014E;LATIN CAPITAL LETTER O WITH BREVE;Lu;0;L;004F 0306;;;;N;LATIN CAPITAL LETTER O BREVE;;;014F;
+014F;LATIN SMALL LETTER O WITH BREVE;Ll;0;L;006F 0306;;;;N;LATIN SMALL LETTER O BREVE;;014E;;014E
+0150;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE;Lu;0;L;004F 030B;;;;N;LATIN CAPITAL LETTER O DOUBLE ACUTE;;;0151;
+0151;LATIN SMALL LETTER O WITH DOUBLE ACUTE;Ll;0;L;006F 030B;;;;N;LATIN SMALL LETTER O DOUBLE ACUTE;;0150;;0150
+0152;LATIN CAPITAL LIGATURE OE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O E;;;0153;
+0153;LATIN SMALL LIGATURE OE;Ll;0;L;;;;;N;LATIN SMALL LETTER O E;;0152;;0152
+0154;LATIN CAPITAL LETTER R WITH ACUTE;Lu;0;L;0052 0301;;;;N;LATIN CAPITAL LETTER R ACUTE;;;0155;
+0155;LATIN SMALL LETTER R WITH ACUTE;Ll;0;L;0072 0301;;;;N;LATIN SMALL LETTER R ACUTE;;0154;;0154
+0156;LATIN CAPITAL LETTER R WITH CEDILLA;Lu;0;L;0052 0327;;;;N;LATIN CAPITAL LETTER R CEDILLA;;;0157;
+0157;LATIN SMALL LETTER R WITH CEDILLA;Ll;0;L;0072 0327;;;;N;LATIN SMALL LETTER R CEDILLA;;0156;;0156
+0158;LATIN CAPITAL LETTER R WITH CARON;Lu;0;L;0052 030C;;;;N;LATIN CAPITAL LETTER R HACEK;;;0159;
+0159;LATIN SMALL LETTER R WITH CARON;Ll;0;L;0072 030C;;;;N;LATIN SMALL LETTER R HACEK;;0158;;0158
+015A;LATIN CAPITAL LETTER S WITH ACUTE;Lu;0;L;0053 0301;;;;N;LATIN CAPITAL LETTER S ACUTE;;;015B;
+015B;LATIN SMALL LETTER S WITH ACUTE;Ll;0;L;0073 0301;;;;N;LATIN SMALL LETTER S ACUTE;;015A;;015A
+015C;LATIN CAPITAL LETTER S WITH CIRCUMFLEX;Lu;0;L;0053 0302;;;;N;LATIN CAPITAL LETTER S CIRCUMFLEX;;;015D;
+015D;LATIN SMALL LETTER S WITH CIRCUMFLEX;Ll;0;L;0073 0302;;;;N;LATIN SMALL LETTER S CIRCUMFLEX;;015C;;015C
+015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;;;015F;
+015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;;015E;;015E
+0160;LATIN CAPITAL LETTER S WITH CARON;Lu;0;L;0053 030C;;;;N;LATIN CAPITAL LETTER S HACEK;;;0161;
+0161;LATIN SMALL LETTER S WITH CARON;Ll;0;L;0073 030C;;;;N;LATIN SMALL LETTER S HACEK;;0160;;0160
+0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;;;0163;
+0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;;0162;;0162
+0164;LATIN CAPITAL LETTER T WITH CARON;Lu;0;L;0054 030C;;;;N;LATIN CAPITAL LETTER T HACEK;;;0165;
+0165;LATIN SMALL LETTER T WITH CARON;Ll;0;L;0074 030C;;;;N;LATIN SMALL LETTER T HACEK;;0164;;0164
+0166;LATIN CAPITAL LETTER T WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T BAR;;;0167;
+0167;LATIN SMALL LETTER T WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER T BAR;;0166;;0166
+0168;LATIN CAPITAL LETTER U WITH TILDE;Lu;0;L;0055 0303;;;;N;LATIN CAPITAL LETTER U TILDE;;;0169;
+0169;LATIN SMALL LETTER U WITH TILDE;Ll;0;L;0075 0303;;;;N;LATIN SMALL LETTER U TILDE;;0168;;0168
+016A;LATIN CAPITAL LETTER U WITH MACRON;Lu;0;L;0055 0304;;;;N;LATIN CAPITAL LETTER U MACRON;;;016B;
+016B;LATIN SMALL LETTER U WITH MACRON;Ll;0;L;0075 0304;;;;N;LATIN SMALL LETTER U MACRON;;016A;;016A
+016C;LATIN CAPITAL LETTER U WITH BREVE;Lu;0;L;0055 0306;;;;N;LATIN CAPITAL LETTER U BREVE;;;016D;
+016D;LATIN SMALL LETTER U WITH BREVE;Ll;0;L;0075 0306;;;;N;LATIN SMALL LETTER U BREVE;;016C;;016C
+016E;LATIN CAPITAL LETTER U WITH RING ABOVE;Lu;0;L;0055 030A;;;;N;LATIN CAPITAL LETTER U RING;;;016F;
+016F;LATIN SMALL LETTER U WITH RING ABOVE;Ll;0;L;0075 030A;;;;N;LATIN SMALL LETTER U RING;;016E;;016E
+0170;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0055 030B;;;;N;LATIN CAPITAL LETTER U DOUBLE ACUTE;;;0171;
+0171;LATIN SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0075 030B;;;;N;LATIN SMALL LETTER U DOUBLE ACUTE;;0170;;0170
+0172;LATIN CAPITAL LETTER U WITH OGONEK;Lu;0;L;0055 0328;;;;N;LATIN CAPITAL LETTER U OGONEK;;;0173;
+0173;LATIN SMALL LETTER U WITH OGONEK;Ll;0;L;0075 0328;;;;N;LATIN SMALL LETTER U OGONEK;;0172;;0172
+0174;LATIN CAPITAL LETTER W WITH CIRCUMFLEX;Lu;0;L;0057 0302;;;;N;LATIN CAPITAL LETTER W CIRCUMFLEX;;;0175;
+0175;LATIN SMALL LETTER W WITH CIRCUMFLEX;Ll;0;L;0077 0302;;;;N;LATIN SMALL LETTER W CIRCUMFLEX;;0174;;0174
+0176;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX;Lu;0;L;0059 0302;;;;N;LATIN CAPITAL LETTER Y CIRCUMFLEX;;;0177;
+0177;LATIN SMALL LETTER Y WITH CIRCUMFLEX;Ll;0;L;0079 0302;;;;N;LATIN SMALL LETTER Y CIRCUMFLEX;;0176;;0176
+0178;LATIN CAPITAL LETTER Y WITH DIAERESIS;Lu;0;L;0059 0308;;;;N;LATIN CAPITAL LETTER Y DIAERESIS;;;00FF;
+0179;LATIN CAPITAL LETTER Z WITH ACUTE;Lu;0;L;005A 0301;;;;N;LATIN CAPITAL LETTER Z ACUTE;;;017A;
+017A;LATIN SMALL LETTER Z WITH ACUTE;Ll;0;L;007A 0301;;;;N;LATIN SMALL LETTER Z ACUTE;;0179;;0179
+017B;LATIN CAPITAL LETTER Z WITH DOT ABOVE;Lu;0;L;005A 0307;;;;N;LATIN CAPITAL LETTER Z DOT;;;017C;
+017C;LATIN SMALL LETTER Z WITH DOT ABOVE;Ll;0;L;007A 0307;;;;N;LATIN SMALL LETTER Z DOT;;017B;;017B
+017D;LATIN CAPITAL LETTER Z WITH CARON;Lu;0;L;005A 030C;;;;N;LATIN CAPITAL LETTER Z HACEK;;;017E;
+017E;LATIN SMALL LETTER Z WITH CARON;Ll;0;L;007A 030C;;;;N;LATIN SMALL LETTER Z HACEK;;017D;;017D
+017F;LATIN SMALL LETTER LONG S;Ll;0;L;<compat> 0073;;;;N;;;0053;;0053
+0180;LATIN SMALL LETTER B WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER B BAR;;0243;;0243
+0181;LATIN CAPITAL LETTER B WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B HOOK;;;0253;
+0182;LATIN CAPITAL LETTER B WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B TOPBAR;;;0183;
+0183;LATIN SMALL LETTER B WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER B TOPBAR;;0182;;0182
+0184;LATIN CAPITAL LETTER TONE SIX;Lu;0;L;;;;;N;;;;0185;
+0185;LATIN SMALL LETTER TONE SIX;Ll;0;L;;;;;N;;;0184;;0184
+0186;LATIN CAPITAL LETTER OPEN O;Lu;0;L;;;;;N;;;;0254;
+0187;LATIN CAPITAL LETTER C WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER C HOOK;;;0188;
+0188;LATIN SMALL LETTER C WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER C HOOK;;0187;;0187
+0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;;;0256;
+018A;LATIN CAPITAL LETTER D WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D HOOK;;;0257;
+018B;LATIN CAPITAL LETTER D WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D TOPBAR;;;018C;
+018C;LATIN SMALL LETTER D WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER D TOPBAR;;018B;;018B
+018D;LATIN SMALL LETTER TURNED DELTA;Ll;0;L;;;;;N;;;;;
+018E;LATIN CAPITAL LETTER REVERSED E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER TURNED E;;;01DD;
+018F;LATIN CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;0259;
+0190;LATIN CAPITAL LETTER OPEN E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER EPSILON;;;025B;
+0191;LATIN CAPITAL LETTER F WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER F HOOK;;;0192;
+0192;LATIN SMALL LETTER F WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT F;;0191;;0191
+0193;LATIN CAPITAL LETTER G WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G HOOK;;;0260;
+0194;LATIN CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;0263;
+0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;;01F6;;01F6
+0196;LATIN CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;0269;
+0197;LATIN CAPITAL LETTER I WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED I;;;0268;
+0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199;
+0199;LATIN SMALL LETTER K WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER K HOOK;;0198;;0198
+019A;LATIN SMALL LETTER L WITH BAR;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED L;;023D;;023D
+019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;;;
+019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F;
+019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272;
+019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;0220;;0220
+019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;;;0275;
+01A0;LATIN CAPITAL LETTER O WITH HORN;Lu;0;L;004F 031B;;;;N;LATIN CAPITAL LETTER O HORN;;;01A1;
+01A1;LATIN SMALL LETTER O WITH HORN;Ll;0;L;006F 031B;;;;N;LATIN SMALL LETTER O HORN;;01A0;;01A0
+01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;;;01A3;
+01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;;01A2;;01A2
+01A4;LATIN CAPITAL LETTER P WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER P HOOK;;;01A5;
+01A5;LATIN SMALL LETTER P WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER P HOOK;;01A4;;01A4
+01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;;;0280;
+01A7;LATIN CAPITAL LETTER TONE TWO;Lu;0;L;;;;;N;;;;01A8;
+01A8;LATIN SMALL LETTER TONE TWO;Ll;0;L;;;;;N;;;01A7;;01A7
+01A9;LATIN CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;0283;
+01AA;LATIN LETTER REVERSED ESH LOOP;Ll;0;L;;;;;N;;;;;
+01AB;LATIN SMALL LETTER T WITH PALATAL HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T PALATAL HOOK;;;;
+01AC;LATIN CAPITAL LETTER T WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T HOOK;;;01AD;
+01AD;LATIN SMALL LETTER T WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T HOOK;;01AC;;01AC
+01AE;LATIN CAPITAL LETTER T WITH RETROFLEX HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T RETROFLEX HOOK;;;0288;
+01AF;LATIN CAPITAL LETTER U WITH HORN;Lu;0;L;0055 031B;;;;N;LATIN CAPITAL LETTER U HORN;;;01B0;
+01B0;LATIN SMALL LETTER U WITH HORN;Ll;0;L;0075 031B;;;;N;LATIN SMALL LETTER U HORN;;01AF;;01AF
+01B1;LATIN CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;028A;
+01B2;LATIN CAPITAL LETTER V WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER SCRIPT V;;;028B;
+01B3;LATIN CAPITAL LETTER Y WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Y HOOK;;;01B4;
+01B4;LATIN SMALL LETTER Y WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Y HOOK;;01B3;;01B3
+01B5;LATIN CAPITAL LETTER Z WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Z BAR;;;01B6;
+01B6;LATIN SMALL LETTER Z WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER Z BAR;;01B5;;01B5
+01B7;LATIN CAPITAL LETTER EZH;Lu;0;L;;;;;N;LATIN CAPITAL LETTER YOGH;;;0292;
+01B8;LATIN CAPITAL LETTER EZH REVERSED;Lu;0;L;;;;;N;LATIN CAPITAL LETTER REVERSED YOGH;;;01B9;
+01B9;LATIN SMALL LETTER EZH REVERSED;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED YOGH;;01B8;;01B8
+01BA;LATIN SMALL LETTER EZH WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH WITH TAIL;;;;
+01BB;LATIN LETTER TWO WITH STROKE;Lo;0;L;;;;;N;LATIN LETTER TWO BAR;;;;
+01BC;LATIN CAPITAL LETTER TONE FIVE;Lu;0;L;;;;;N;;;;01BD;
+01BD;LATIN SMALL LETTER TONE FIVE;Ll;0;L;;;;;N;;;01BC;;01BC
+01BE;LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER INVERTED GLOTTAL STOP BAR;;;;
+01BF;LATIN LETTER WYNN;Ll;0;L;;;;;N;;;01F7;;01F7
+01C0;LATIN LETTER DENTAL CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE;;;;
+01C1;LATIN LETTER LATERAL CLICK;Lo;0;L;;;;;N;LATIN LETTER DOUBLE PIPE;;;;
+01C2;LATIN LETTER ALVEOLAR CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE DOUBLE BAR;;;;
+01C3;LATIN LETTER RETROFLEX CLICK;Lo;0;L;;;;;N;LATIN LETTER EXCLAMATION MARK;;;;
+01C4;LATIN CAPITAL LETTER DZ WITH CARON;Lu;0;L;<compat> 0044 017D;;;;N;LATIN CAPITAL LETTER D Z HACEK;;;01C6;01C5
+01C5;LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON;Lt;0;L;<compat> 0044 017E;;;;N;LATIN LETTER CAPITAL D SMALL Z HACEK;;01C4;01C6;01C5
+01C6;LATIN SMALL LETTER DZ WITH CARON;Ll;0;L;<compat> 0064 017E;;;;N;LATIN SMALL LETTER D Z HACEK;;01C4;;01C5
+01C7;LATIN CAPITAL LETTER LJ;Lu;0;L;<compat> 004C 004A;;;;N;LATIN CAPITAL LETTER L J;;;01C9;01C8
+01C8;LATIN CAPITAL LETTER L WITH SMALL LETTER J;Lt;0;L;<compat> 004C 006A;;;;N;LATIN LETTER CAPITAL L SMALL J;;01C7;01C9;01C8
+01C9;LATIN SMALL LETTER LJ;Ll;0;L;<compat> 006C 006A;;;;N;LATIN SMALL LETTER L J;;01C7;;01C8
+01CA;LATIN CAPITAL LETTER NJ;Lu;0;L;<compat> 004E 004A;;;;N;LATIN CAPITAL LETTER N J;;;01CC;01CB
+01CB;LATIN CAPITAL LETTER N WITH SMALL LETTER J;Lt;0;L;<compat> 004E 006A;;;;N;LATIN LETTER CAPITAL N SMALL J;;01CA;01CC;01CB
+01CC;LATIN SMALL LETTER NJ;Ll;0;L;<compat> 006E 006A;;;;N;LATIN SMALL LETTER N J;;01CA;;01CB
+01CD;LATIN CAPITAL LETTER A WITH CARON;Lu;0;L;0041 030C;;;;N;LATIN CAPITAL LETTER A HACEK;;;01CE;
+01CE;LATIN SMALL LETTER A WITH CARON;Ll;0;L;0061 030C;;;;N;LATIN SMALL LETTER A HACEK;;01CD;;01CD
+01CF;LATIN CAPITAL LETTER I WITH CARON;Lu;0;L;0049 030C;;;;N;LATIN CAPITAL LETTER I HACEK;;;01D0;
+01D0;LATIN SMALL LETTER I WITH CARON;Ll;0;L;0069 030C;;;;N;LATIN SMALL LETTER I HACEK;;01CF;;01CF
+01D1;LATIN CAPITAL LETTER O WITH CARON;Lu;0;L;004F 030C;;;;N;LATIN CAPITAL LETTER O HACEK;;;01D2;
+01D2;LATIN SMALL LETTER O WITH CARON;Ll;0;L;006F 030C;;;;N;LATIN SMALL LETTER O HACEK;;01D1;;01D1
+01D3;LATIN CAPITAL LETTER U WITH CARON;Lu;0;L;0055 030C;;;;N;LATIN CAPITAL LETTER U HACEK;;;01D4;
+01D4;LATIN SMALL LETTER U WITH CARON;Ll;0;L;0075 030C;;;;N;LATIN SMALL LETTER U HACEK;;01D3;;01D3
+01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6;
+01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5
+01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8;
+01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7
+01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA;
+01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9
+01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC;
+01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB
+01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E
+01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF;
+01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE
+01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1;
+01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0
+01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;;;01E3;
+01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;;01E2;;01E2
+01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5;
+01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4
+01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7;
+01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6
+01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9;
+01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8
+01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB;
+01EB;LATIN SMALL LETTER O WITH OGONEK;Ll;0;L;006F 0328;;;;N;LATIN SMALL LETTER O OGONEK;;01EA;;01EA
+01EC;LATIN CAPITAL LETTER O WITH OGONEK AND MACRON;Lu;0;L;01EA 0304;;;;N;LATIN CAPITAL LETTER O OGONEK MACRON;;;01ED;
+01ED;LATIN SMALL LETTER O WITH OGONEK AND MACRON;Ll;0;L;01EB 0304;;;;N;LATIN SMALL LETTER O OGONEK MACRON;;01EC;;01EC
+01EE;LATIN CAPITAL LETTER EZH WITH CARON;Lu;0;L;01B7 030C;;;;N;LATIN CAPITAL LETTER YOGH HACEK;;;01EF;
+01EF;LATIN SMALL LETTER EZH WITH CARON;Ll;0;L;0292 030C;;;;N;LATIN SMALL LETTER YOGH HACEK;;01EE;;01EE
+01F0;LATIN SMALL LETTER J WITH CARON;Ll;0;L;006A 030C;;;;N;LATIN SMALL LETTER J HACEK;;;;
+01F1;LATIN CAPITAL LETTER DZ;Lu;0;L;<compat> 0044 005A;;;;N;;;;01F3;01F2
+01F2;LATIN CAPITAL LETTER D WITH SMALL LETTER Z;Lt;0;L;<compat> 0044 007A;;;;N;;;01F1;01F3;01F2
+01F3;LATIN SMALL LETTER DZ;Ll;0;L;<compat> 0064 007A;;;;N;;;01F1;;01F2
+01F4;LATIN CAPITAL LETTER G WITH ACUTE;Lu;0;L;0047 0301;;;;N;;;;01F5;
+01F5;LATIN SMALL LETTER G WITH ACUTE;Ll;0;L;0067 0301;;;;N;;;01F4;;01F4
+01F6;LATIN CAPITAL LETTER HWAIR;Lu;0;L;;;;;N;;;;0195;
+01F7;LATIN CAPITAL LETTER WYNN;Lu;0;L;;;;;N;;;;01BF;
+01F8;LATIN CAPITAL LETTER N WITH GRAVE;Lu;0;L;004E 0300;;;;N;;;;01F9;
+01F9;LATIN SMALL LETTER N WITH GRAVE;Ll;0;L;006E 0300;;;;N;;;01F8;;01F8
+01FA;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE;Lu;0;L;00C5 0301;;;;N;;;;01FB;
+01FB;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE;Ll;0;L;00E5 0301;;;;N;;;01FA;;01FA
+01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;;;01FD;
+01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;;01FC;;01FC
+01FE;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE;Lu;0;L;00D8 0301;;;;N;;;;01FF;
+01FF;LATIN SMALL LETTER O WITH STROKE AND ACUTE;Ll;0;L;00F8 0301;;;;N;;;01FE;;01FE
+0200;LATIN CAPITAL LETTER A WITH DOUBLE GRAVE;Lu;0;L;0041 030F;;;;N;;;;0201;
+0201;LATIN SMALL LETTER A WITH DOUBLE GRAVE;Ll;0;L;0061 030F;;;;N;;;0200;;0200
+0202;LATIN CAPITAL LETTER A WITH INVERTED BREVE;Lu;0;L;0041 0311;;;;N;;;;0203;
+0203;LATIN SMALL LETTER A WITH INVERTED BREVE;Ll;0;L;0061 0311;;;;N;;;0202;;0202
+0204;LATIN CAPITAL LETTER E WITH DOUBLE GRAVE;Lu;0;L;0045 030F;;;;N;;;;0205;
+0205;LATIN SMALL LETTER E WITH DOUBLE GRAVE;Ll;0;L;0065 030F;;;;N;;;0204;;0204
+0206;LATIN CAPITAL LETTER E WITH INVERTED BREVE;Lu;0;L;0045 0311;;;;N;;;;0207;
+0207;LATIN SMALL LETTER E WITH INVERTED BREVE;Ll;0;L;0065 0311;;;;N;;;0206;;0206
+0208;LATIN CAPITAL LETTER I WITH DOUBLE GRAVE;Lu;0;L;0049 030F;;;;N;;;;0209;
+0209;LATIN SMALL LETTER I WITH DOUBLE GRAVE;Ll;0;L;0069 030F;;;;N;;;0208;;0208
+020A;LATIN CAPITAL LETTER I WITH INVERTED BREVE;Lu;0;L;0049 0311;;;;N;;;;020B;
+020B;LATIN SMALL LETTER I WITH INVERTED BREVE;Ll;0;L;0069 0311;;;;N;;;020A;;020A
+020C;LATIN CAPITAL LETTER O WITH DOUBLE GRAVE;Lu;0;L;004F 030F;;;;N;;;;020D;
+020D;LATIN SMALL LETTER O WITH DOUBLE GRAVE;Ll;0;L;006F 030F;;;;N;;;020C;;020C
+020E;LATIN CAPITAL LETTER O WITH INVERTED BREVE;Lu;0;L;004F 0311;;;;N;;;;020F;
+020F;LATIN SMALL LETTER O WITH INVERTED BREVE;Ll;0;L;006F 0311;;;;N;;;020E;;020E
+0210;LATIN CAPITAL LETTER R WITH DOUBLE GRAVE;Lu;0;L;0052 030F;;;;N;;;;0211;
+0211;LATIN SMALL LETTER R WITH DOUBLE GRAVE;Ll;0;L;0072 030F;;;;N;;;0210;;0210
+0212;LATIN CAPITAL LETTER R WITH INVERTED BREVE;Lu;0;L;0052 0311;;;;N;;;;0213;
+0213;LATIN SMALL LETTER R WITH INVERTED BREVE;Ll;0;L;0072 0311;;;;N;;;0212;;0212
+0214;LATIN CAPITAL LETTER U WITH DOUBLE GRAVE;Lu;0;L;0055 030F;;;;N;;;;0215;
+0215;LATIN SMALL LETTER U WITH DOUBLE GRAVE;Ll;0;L;0075 030F;;;;N;;;0214;;0214
+0216;LATIN CAPITAL LETTER U WITH INVERTED BREVE;Lu;0;L;0055 0311;;;;N;;;;0217;
+0217;LATIN SMALL LETTER U WITH INVERTED BREVE;Ll;0;L;0075 0311;;;;N;;;0216;;0216
+0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;;;0219;
+0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;;0218;;0218
+021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;;;021B;
+021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;;021A;;021A
+021C;LATIN CAPITAL LETTER YOGH;Lu;0;L;;;;;N;;;;021D;
+021D;LATIN SMALL LETTER YOGH;Ll;0;L;;;;;N;;;021C;;021C
+021E;LATIN CAPITAL LETTER H WITH CARON;Lu;0;L;0048 030C;;;;N;;;;021F;
+021F;LATIN SMALL LETTER H WITH CARON;Ll;0;L;0068 030C;;;;N;;;021E;;021E
+0220;LATIN CAPITAL LETTER N WITH LONG RIGHT LEG;Lu;0;L;;;;;N;;;;019E;
+0221;LATIN SMALL LETTER D WITH CURL;Ll;0;L;;;;;N;;;;;
+0222;LATIN CAPITAL LETTER OU;Lu;0;L;;;;;N;;;;0223;
+0223;LATIN SMALL LETTER OU;Ll;0;L;;;;;N;;;0222;;0222
+0224;LATIN CAPITAL LETTER Z WITH HOOK;Lu;0;L;;;;;N;;;;0225;
+0225;LATIN SMALL LETTER Z WITH HOOK;Ll;0;L;;;;;N;;;0224;;0224
+0226;LATIN CAPITAL LETTER A WITH DOT ABOVE;Lu;0;L;0041 0307;;;;N;;;;0227;
+0227;LATIN SMALL LETTER A WITH DOT ABOVE;Ll;0;L;0061 0307;;;;N;;;0226;;0226
+0228;LATIN CAPITAL LETTER E WITH CEDILLA;Lu;0;L;0045 0327;;;;N;;;;0229;
+0229;LATIN SMALL LETTER E WITH CEDILLA;Ll;0;L;0065 0327;;;;N;;;0228;;0228
+022A;LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON;Lu;0;L;00D6 0304;;;;N;;;;022B;
+022B;LATIN SMALL LETTER O WITH DIAERESIS AND MACRON;Ll;0;L;00F6 0304;;;;N;;;022A;;022A
+022C;LATIN CAPITAL LETTER O WITH TILDE AND MACRON;Lu;0;L;00D5 0304;;;;N;;;;022D;
+022D;LATIN SMALL LETTER O WITH TILDE AND MACRON;Ll;0;L;00F5 0304;;;;N;;;022C;;022C
+022E;LATIN CAPITAL LETTER O WITH DOT ABOVE;Lu;0;L;004F 0307;;;;N;;;;022F;
+022F;LATIN SMALL LETTER O WITH DOT ABOVE;Ll;0;L;006F 0307;;;;N;;;022E;;022E
+0230;LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON;Lu;0;L;022E 0304;;;;N;;;;0231;
+0231;LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON;Ll;0;L;022F 0304;;;;N;;;0230;;0230
+0232;LATIN CAPITAL LETTER Y WITH MACRON;Lu;0;L;0059 0304;;;;N;;;;0233;
+0233;LATIN SMALL LETTER Y WITH MACRON;Ll;0;L;0079 0304;;;;N;;;0232;;0232
+0234;LATIN SMALL LETTER L WITH CURL;Ll;0;L;;;;;N;;;;;
+0235;LATIN SMALL LETTER N WITH CURL;Ll;0;L;;;;;N;;;;;
+0236;LATIN SMALL LETTER T WITH CURL;Ll;0;L;;;;;N;;;;;
+0237;LATIN SMALL LETTER DOTLESS J;Ll;0;L;;;;;N;;;;;
+0238;LATIN SMALL LETTER DB DIGRAPH;Ll;0;L;;;;;N;;;;;
+0239;LATIN SMALL LETTER QP DIGRAPH;Ll;0;L;;;;;N;;;;;
+023A;LATIN CAPITAL LETTER A WITH STROKE;Lu;0;L;;;;;N;;;;2C65;
+023B;LATIN CAPITAL LETTER C WITH STROKE;Lu;0;L;;;;;N;;;;023C;
+023C;LATIN SMALL LETTER C WITH STROKE;Ll;0;L;;;;;N;;;023B;;023B
+023D;LATIN CAPITAL LETTER L WITH BAR;Lu;0;L;;;;;N;;;;019A;
+023E;LATIN CAPITAL LETTER T WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;2C66;
+023F;LATIN SMALL LETTER S WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7E;;2C7E
+0240;LATIN SMALL LETTER Z WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7F;;2C7F
+0241;LATIN CAPITAL LETTER GLOTTAL STOP;Lu;0;L;;;;;N;;;;0242;
+0242;LATIN SMALL LETTER GLOTTAL STOP;Ll;0;L;;;;;N;;;0241;;0241
+0243;LATIN CAPITAL LETTER B WITH STROKE;Lu;0;L;;;;;N;;;;0180;
+0244;LATIN CAPITAL LETTER U BAR;Lu;0;L;;;;;N;;;;0289;
+0245;LATIN CAPITAL LETTER TURNED V;Lu;0;L;;;;;N;;;;028C;
+0246;LATIN CAPITAL LETTER E WITH STROKE;Lu;0;L;;;;;N;;;;0247;
+0247;LATIN SMALL LETTER E WITH STROKE;Ll;0;L;;;;;N;;;0246;;0246
+0248;LATIN CAPITAL LETTER J WITH STROKE;Lu;0;L;;;;;N;;;;0249;
+0249;LATIN SMALL LETTER J WITH STROKE;Ll;0;L;;;;;N;;;0248;;0248
+024A;LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL;Lu;0;L;;;;;N;;;;024B;
+024B;LATIN SMALL LETTER Q WITH HOOK TAIL;Ll;0;L;;;;;N;;;024A;;024A
+024C;LATIN CAPITAL LETTER R WITH STROKE;Lu;0;L;;;;;N;;;;024D;
+024D;LATIN SMALL LETTER R WITH STROKE;Ll;0;L;;;;;N;;;024C;;024C
+024E;LATIN CAPITAL LETTER Y WITH STROKE;Lu;0;L;;;;;N;;;;024F;
+024F;LATIN SMALL LETTER Y WITH STROKE;Ll;0;L;;;;;N;;;024E;;024E
+0250;LATIN SMALL LETTER TURNED A;Ll;0;L;;;;;N;;;2C6F;;2C6F
+0251;LATIN SMALL LETTER ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT A;;2C6D;;2C6D
+0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;2C70;;2C70
+0253;LATIN SMALL LETTER B WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER B HOOK;;0181;;0181
+0254;LATIN SMALL LETTER OPEN O;Ll;0;L;;;;;N;;;0186;;0186
+0255;LATIN SMALL LETTER C WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER C CURL;;;;
+0256;LATIN SMALL LETTER D WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER D RETROFLEX HOOK;;0189;;0189
+0257;LATIN SMALL LETTER D WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER D HOOK;;018A;;018A
+0258;LATIN SMALL LETTER REVERSED E;Ll;0;L;;;;;N;;;;;
+0259;LATIN SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;018F;;018F
+025A;LATIN SMALL LETTER SCHWA WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCHWA HOOK;;;;
+025B;LATIN SMALL LETTER OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER EPSILON;;0190;;0190
+025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;A7AB;;A7AB
+025D;LATIN SMALL LETTER REVERSED OPEN E WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON HOOK;;;;
+025E;LATIN SMALL LETTER CLOSED REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED REVERSED EPSILON;;;;
+025F;LATIN SMALL LETTER DOTLESS J WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR;;;;
+0260;LATIN SMALL LETTER G WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER G HOOK;;0193;;0193
+0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;A7AC;;A7AC
+0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;;
+0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194
+0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;;
+0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;A78D;;A78D
+0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;A7AA;;A7AA
+0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;;
+0268;LATIN SMALL LETTER I WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED I;;0197;;0197
+0269;LATIN SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0196;;0196
+026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;A7AE;;A7AE
+026B;LATIN SMALL LETTER L WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;2C62;;2C62
+026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;A7AD;;A7AD
+026D;LATIN SMALL LETTER L WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER L RETROFLEX HOOK;;;;
+026E;LATIN SMALL LETTER LEZH;Ll;0;L;;;;;N;LATIN SMALL LETTER L YOGH;;;;
+026F;LATIN SMALL LETTER TURNED M;Ll;0;L;;;;;N;;;019C;;019C
+0270;LATIN SMALL LETTER TURNED M WITH LONG LEG;Ll;0;L;;;;;N;;;;;
+0271;LATIN SMALL LETTER M WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER M HOOK;;2C6E;;2C6E
+0272;LATIN SMALL LETTER N WITH LEFT HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N HOOK;;019D;;019D
+0273;LATIN SMALL LETTER N WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N RETROFLEX HOOK;;;;
+0274;LATIN LETTER SMALL CAPITAL N;Ll;0;L;;;;;N;;;;;
+0275;LATIN SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;019F;;019F
+0276;LATIN LETTER SMALL CAPITAL OE;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL O E;;;;
+0277;LATIN SMALL LETTER CLOSED OMEGA;Ll;0;L;;;;;N;;;;;
+0278;LATIN SMALL LETTER PHI;Ll;0;L;;;;;N;;;;;
+0279;LATIN SMALL LETTER TURNED R;Ll;0;L;;;;;N;;;;;
+027A;LATIN SMALL LETTER TURNED R WITH LONG LEG;Ll;0;L;;;;;N;;;;;
+027B;LATIN SMALL LETTER TURNED R WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED R HOOK;;;;
+027C;LATIN SMALL LETTER R WITH LONG LEG;Ll;0;L;;;;;N;;;;;
+027D;LATIN SMALL LETTER R WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER R HOOK;;2C64;;2C64
+027E;LATIN SMALL LETTER R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER FISHHOOK R;;;;
+027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;;
+0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;;01A6;;01A6
+0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;;
+0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;;
+0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9
+0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;;
+0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;;
+0286;LATIN SMALL LETTER ESH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER ESH CURL;;;;
+0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;A7B1;;A7B1
+0288;LATIN SMALL LETTER T WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T RETROFLEX HOOK;;01AE;;01AE
+0289;LATIN SMALL LETTER U BAR;Ll;0;L;;;;;N;;;0244;;0244
+028A;LATIN SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;01B1;;01B1
+028B;LATIN SMALL LETTER V WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT V;;01B2;;01B2
+028C;LATIN SMALL LETTER TURNED V;Ll;0;L;;;;;N;;;0245;;0245
+028D;LATIN SMALL LETTER TURNED W;Ll;0;L;;;;;N;;;;;
+028E;LATIN SMALL LETTER TURNED Y;Ll;0;L;;;;;N;;;;;
+028F;LATIN LETTER SMALL CAPITAL Y;Ll;0;L;;;;;N;;;;;
+0290;LATIN SMALL LETTER Z WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Z RETROFLEX HOOK;;;;
+0291;LATIN SMALL LETTER Z WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER Z CURL;;;;
+0292;LATIN SMALL LETTER EZH;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH;;01B7;;01B7
+0293;LATIN SMALL LETTER EZH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH CURL;;;;
+0294;LATIN LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
+0295;LATIN LETTER PHARYNGEAL VOICED FRICATIVE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP;;;;
+0296;LATIN LETTER INVERTED GLOTTAL STOP;Ll;0;L;;;;;N;;;;;
+0297;LATIN LETTER STRETCHED C;Ll;0;L;;;;;N;;;;;
+0298;LATIN LETTER BILABIAL CLICK;Ll;0;L;;;;;N;LATIN LETTER BULLSEYE;;;;
+0299;LATIN LETTER SMALL CAPITAL B;Ll;0;L;;;;;N;;;;;
+029A;LATIN SMALL LETTER CLOSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED EPSILON;;;;
+029B;LATIN LETTER SMALL CAPITAL G WITH HOOK;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL G HOOK;;;;
+029C;LATIN LETTER SMALL CAPITAL H;Ll;0;L;;;;;N;;;;;
+029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;A7B2;;A7B2
+029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;A7B0;;A7B0
+029F;LATIN LETTER SMALL CAPITAL L;Ll;0;L;;;;;N;;;;;
+02A0;LATIN SMALL LETTER Q WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Q HOOK;;;;
+02A1;LATIN LETTER GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER GLOTTAL STOP BAR;;;;
+02A2;LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP BAR;;;;
+02A3;LATIN SMALL LETTER DZ DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z;;;;
+02A4;LATIN SMALL LETTER DEZH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D YOGH;;;;
+02A5;LATIN SMALL LETTER DZ DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z CURL;;;;
+02A6;LATIN SMALL LETTER TS DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T S;;;;
+02A7;LATIN SMALL LETTER TESH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T ESH;;;;
+02A8;LATIN SMALL LETTER TC DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER T C CURL;;;;
+02A9;LATIN SMALL LETTER FENG DIGRAPH;Ll;0;L;;;;;N;;;;;
+02AA;LATIN SMALL LETTER LS DIGRAPH;Ll;0;L;;;;;N;;;;;
+02AB;LATIN SMALL LETTER LZ DIGRAPH;Ll;0;L;;;;;N;;;;;
+02AC;LATIN LETTER BILABIAL PERCUSSIVE;Ll;0;L;;;;;N;;;;;
+02AD;LATIN LETTER BIDENTAL PERCUSSIVE;Ll;0;L;;;;;N;;;;;
+02AE;LATIN SMALL LETTER TURNED H WITH FISHHOOK;Ll;0;L;;;;;N;;;;;
+02AF;LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL;Ll;0;L;;;;;N;;;;;
+02B0;MODIFIER LETTER SMALL H;Lm;0;L;<super> 0068;;;;N;;;;;
+02B1;MODIFIER LETTER SMALL H WITH HOOK;Lm;0;L;<super> 0266;;;;N;MODIFIER LETTER SMALL H HOOK;;;;
+02B2;MODIFIER LETTER SMALL J;Lm;0;L;<super> 006A;;;;N;;;;;
+02B3;MODIFIER LETTER SMALL R;Lm;0;L;<super> 0072;;;;N;;;;;
+02B4;MODIFIER LETTER SMALL TURNED R;Lm;0;L;<super> 0279;;;;N;;;;;
+02B5;MODIFIER LETTER SMALL TURNED R WITH HOOK;Lm;0;L;<super> 027B;;;;N;MODIFIER LETTER SMALL TURNED R HOOK;;;;
+02B6;MODIFIER LETTER SMALL CAPITAL INVERTED R;Lm;0;L;<super> 0281;;;;N;;;;;
+02B7;MODIFIER LETTER SMALL W;Lm;0;L;<super> 0077;;;;N;;;;;
+02B8;MODIFIER LETTER SMALL Y;Lm;0;L;<super> 0079;;;;N;;;;;
+02B9;MODIFIER LETTER PRIME;Lm;0;ON;;;;;N;;;;;
+02BA;MODIFIER LETTER DOUBLE PRIME;Lm;0;ON;;;;;N;;;;;
+02BB;MODIFIER LETTER TURNED COMMA;Lm;0;L;;;;;N;;;;;
+02BC;MODIFIER LETTER APOSTROPHE;Lm;0;L;;;;;N;;;;;
+02BD;MODIFIER LETTER REVERSED COMMA;Lm;0;L;;;;;N;;;;;
+02BE;MODIFIER LETTER RIGHT HALF RING;Lm;0;L;;;;;N;;;;;
+02BF;MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;;
+02C0;MODIFIER LETTER GLOTTAL STOP;Lm;0;L;;;;;N;;;;;
+02C1;MODIFIER LETTER REVERSED GLOTTAL STOP;Lm;0;L;;;;;N;;;;;
+02C2;MODIFIER LETTER LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C3;MODIFIER LETTER RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C4;MODIFIER LETTER UP ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C5;MODIFIER LETTER DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02C6;MODIFIER LETTER CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER CIRCUMFLEX;;;;
+02C7;CARON;Lm;0;ON;;;;;N;MODIFIER LETTER HACEK;;;;
+02C8;MODIFIER LETTER VERTICAL LINE;Lm;0;ON;;;;;N;;;;;
+02C9;MODIFIER LETTER MACRON;Lm;0;ON;;;;;N;;;;;
+02CA;MODIFIER LETTER ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER ACUTE;;;;
+02CB;MODIFIER LETTER GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER GRAVE;;;;
+02CC;MODIFIER LETTER LOW VERTICAL LINE;Lm;0;ON;;;;;N;;;;;
+02CD;MODIFIER LETTER LOW MACRON;Lm;0;ON;;;;;N;;;;;
+02CE;MODIFIER LETTER LOW GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW GRAVE;;;;
+02CF;MODIFIER LETTER LOW ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW ACUTE;;;;
+02D0;MODIFIER LETTER TRIANGULAR COLON;Lm;0;L;;;;;N;;;;;
+02D1;MODIFIER LETTER HALF TRIANGULAR COLON;Lm;0;L;;;;;N;;;;;
+02D2;MODIFIER LETTER CENTRED RIGHT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED RIGHT HALF RING;;;;
+02D3;MODIFIER LETTER CENTRED LEFT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED LEFT HALF RING;;;;
+02D4;MODIFIER LETTER UP TACK;Sk;0;ON;;;;;N;;;;;
+02D5;MODIFIER LETTER DOWN TACK;Sk;0;ON;;;;;N;;;;;
+02D6;MODIFIER LETTER PLUS SIGN;Sk;0;ON;;;;;N;;;;;
+02D7;MODIFIER LETTER MINUS SIGN;Sk;0;ON;;;;;N;;;;;
+02D8;BREVE;Sk;0;ON;<compat> 0020 0306;;;;N;SPACING BREVE;;;;
+02D9;DOT ABOVE;Sk;0;ON;<compat> 0020 0307;;;;N;SPACING DOT ABOVE;;;;
+02DA;RING ABOVE;Sk;0;ON;<compat> 0020 030A;;;;N;SPACING RING ABOVE;;;;
+02DB;OGONEK;Sk;0;ON;<compat> 0020 0328;;;;N;SPACING OGONEK;;;;
+02DC;SMALL TILDE;Sk;0;ON;<compat> 0020 0303;;;;N;SPACING TILDE;;;;
+02DD;DOUBLE ACUTE ACCENT;Sk;0;ON;<compat> 0020 030B;;;;N;SPACING DOUBLE ACUTE;;;;
+02DE;MODIFIER LETTER RHOTIC HOOK;Sk;0;ON;;;;;N;;;;;
+02DF;MODIFIER LETTER CROSS ACCENT;Sk;0;ON;;;;;N;;;;;
+02E0;MODIFIER LETTER SMALL GAMMA;Lm;0;L;<super> 0263;;;;N;;;;;
+02E1;MODIFIER LETTER SMALL L;Lm;0;L;<super> 006C;;;;N;;;;;
+02E2;MODIFIER LETTER SMALL S;Lm;0;L;<super> 0073;;;;N;;;;;
+02E3;MODIFIER LETTER SMALL X;Lm;0;L;<super> 0078;;;;N;;;;;
+02E4;MODIFIER LETTER SMALL REVERSED GLOTTAL STOP;Lm;0;L;<super> 0295;;;;N;;;;;
+02E5;MODIFIER LETTER EXTRA-HIGH TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E6;MODIFIER LETTER HIGH TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E7;MODIFIER LETTER MID TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E8;MODIFIER LETTER LOW TONE BAR;Sk;0;ON;;;;;N;;;;;
+02E9;MODIFIER LETTER EXTRA-LOW TONE BAR;Sk;0;ON;;;;;N;;;;;
+02EA;MODIFIER LETTER YIN DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;;
+02EB;MODIFIER LETTER YANG DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;;
+02EC;MODIFIER LETTER VOICING;Lm;0;ON;;;;;N;;;;;
+02ED;MODIFIER LETTER UNASPIRATED;Sk;0;ON;;;;;N;;;;;
+02EE;MODIFIER LETTER DOUBLE APOSTROPHE;Lm;0;L;;;;;N;;;;;
+02EF;MODIFIER LETTER LOW DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02F0;MODIFIER LETTER LOW UP ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02F1;MODIFIER LETTER LOW LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02F2;MODIFIER LETTER LOW RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
+02F3;MODIFIER LETTER LOW RING;Sk;0;ON;;;;;N;;;;;
+02F4;MODIFIER LETTER MIDDLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;;
+02F5;MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;;
+02F6;MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT;Sk;0;ON;;;;;N;;;;;
+02F7;MODIFIER LETTER LOW TILDE;Sk;0;ON;;;;;N;;;;;
+02F8;MODIFIER LETTER RAISED COLON;Sk;0;ON;;;;;N;;;;;
+02F9;MODIFIER LETTER BEGIN HIGH TONE;Sk;0;ON;;;;;N;;;;;
+02FA;MODIFIER LETTER END HIGH TONE;Sk;0;ON;;;;;N;;;;;
+02FB;MODIFIER LETTER BEGIN LOW TONE;Sk;0;ON;;;;;N;;;;;
+02FC;MODIFIER LETTER END LOW TONE;Sk;0;ON;;;;;N;;;;;
+02FD;MODIFIER LETTER SHELF;Sk;0;ON;;;;;N;;;;;
+02FE;MODIFIER LETTER OPEN SHELF;Sk;0;ON;;;;;N;;;;;
+02FF;MODIFIER LETTER LOW LEFT ARROW;Sk;0;ON;;;;;N;;;;;
+0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;;;;
+0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;;;;
+0302;COMBINING CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;NON-SPACING CIRCUMFLEX;;;;
+0303;COMBINING TILDE;Mn;230;NSM;;;;;N;NON-SPACING TILDE;;;;
+0304;COMBINING MACRON;Mn;230;NSM;;;;;N;NON-SPACING MACRON;;;;
+0305;COMBINING OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING OVERSCORE;;;;
+0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;;;;
+0307;COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOT ABOVE;;;;
+0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;;;;
+0309;COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;NON-SPACING HOOK ABOVE;;;;
+030A;COMBINING RING ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RING ABOVE;;;;
+030B;COMBINING DOUBLE ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE ACUTE;;;;
+030C;COMBINING CARON;Mn;230;NSM;;;;;N;NON-SPACING HACEK;;;;
+030D;COMBINING VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL LINE ABOVE;;;;
+030E;COMBINING DOUBLE VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE VERTICAL LINE ABOVE;;;;
+030F;COMBINING DOUBLE GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE GRAVE;;;;
+0310;COMBINING CANDRABINDU;Mn;230;NSM;;;;;N;NON-SPACING CANDRABINDU;;;;
+0311;COMBINING INVERTED BREVE;Mn;230;NSM;;;;;N;NON-SPACING INVERTED BREVE;;;;
+0312;COMBINING TURNED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING TURNED COMMA ABOVE;;;;
+0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;;;;
+0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;;;;
+0315;COMBINING COMMA ABOVE RIGHT;Mn;232;NSM;;;;;N;NON-SPACING COMMA ABOVE RIGHT;;;;
+0316;COMBINING GRAVE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING GRAVE BELOW;;;;
+0317;COMBINING ACUTE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING ACUTE BELOW;;;;
+0318;COMBINING LEFT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT TACK BELOW;;;;
+0319;COMBINING RIGHT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT TACK BELOW;;;;
+031A;COMBINING LEFT ANGLE ABOVE;Mn;232;NSM;;;;;N;NON-SPACING LEFT ANGLE ABOVE;;;;
+031B;COMBINING HORN;Mn;216;NSM;;;;;N;NON-SPACING HORN;;;;
+031C;COMBINING LEFT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT HALF RING BELOW;;;;
+031D;COMBINING UP TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING UP TACK BELOW;;;;
+031E;COMBINING DOWN TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOWN TACK BELOW;;;;
+031F;COMBINING PLUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING PLUS SIGN BELOW;;;;
+0320;COMBINING MINUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING MINUS SIGN BELOW;;;;
+0321;COMBINING PALATALIZED HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING PALATALIZED HOOK BELOW;;;;
+0322;COMBINING RETROFLEX HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING RETROFLEX HOOK BELOW;;;;
+0323;COMBINING DOT BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOT BELOW;;;;
+0324;COMBINING DIAERESIS BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE DOT BELOW;;;;
+0325;COMBINING RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RING BELOW;;;;
+0326;COMBINING COMMA BELOW;Mn;220;NSM;;;;;N;NON-SPACING COMMA BELOW;;;;
+0327;COMBINING CEDILLA;Mn;202;NSM;;;;;N;NON-SPACING CEDILLA;;;;
+0328;COMBINING OGONEK;Mn;202;NSM;;;;;N;NON-SPACING OGONEK;;;;
+0329;COMBINING VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;NON-SPACING VERTICAL LINE BELOW;;;;
+032A;COMBINING BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BRIDGE BELOW;;;;
+032B;COMBINING INVERTED DOUBLE ARCH BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED DOUBLE ARCH BELOW;;;;
+032C;COMBINING CARON BELOW;Mn;220;NSM;;;;;N;NON-SPACING HACEK BELOW;;;;
+032D;COMBINING CIRCUMFLEX ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING CIRCUMFLEX BELOW;;;;
+032E;COMBINING BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BREVE BELOW;;;;
+032F;COMBINING INVERTED BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BREVE BELOW;;;;
+0330;COMBINING TILDE BELOW;Mn;220;NSM;;;;;N;NON-SPACING TILDE BELOW;;;;
+0331;COMBINING MACRON BELOW;Mn;220;NSM;;;;;N;NON-SPACING MACRON BELOW;;;;
+0332;COMBINING LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING UNDERSCORE;;;;
+0333;COMBINING DOUBLE LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE UNDERSCORE;;;;
+0334;COMBINING TILDE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING TILDE OVERLAY;;;;
+0335;COMBINING SHORT STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT BAR OVERLAY;;;;
+0336;COMBINING LONG STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG BAR OVERLAY;;;;
+0337;COMBINING SHORT SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT SLASH OVERLAY;;;;
+0338;COMBINING LONG SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG SLASH OVERLAY;;;;
+0339;COMBINING RIGHT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT HALF RING BELOW;;;;
+033A;COMBINING INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BRIDGE BELOW;;;;
+033B;COMBINING SQUARE BELOW;Mn;220;NSM;;;;;N;NON-SPACING SQUARE BELOW;;;;
+033C;COMBINING SEAGULL BELOW;Mn;220;NSM;;;;;N;NON-SPACING SEAGULL BELOW;;;;
+033D;COMBINING X ABOVE;Mn;230;NSM;;;;;N;NON-SPACING X ABOVE;;;;
+033E;COMBINING VERTICAL TILDE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL TILDE;;;;
+033F;COMBINING DOUBLE OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE OVERSCORE;;;;
+0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;;;;
+0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;;;;
+0342;COMBINING GREEK PERISPOMENI;Mn;230;NSM;;;;;N;;;;;
+0343;COMBINING GREEK KORONIS;Mn;230;NSM;0313;;;;N;;;;;
+0344;COMBINING GREEK DIALYTIKA TONOS;Mn;230;NSM;0308 0301;;;;N;GREEK NON-SPACING DIAERESIS TONOS;;;;
+0345;COMBINING GREEK YPOGEGRAMMENI;Mn;240;NSM;;;;;N;GREEK NON-SPACING IOTA BELOW;;0399;;0399
+0346;COMBINING BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;;
+0347;COMBINING EQUALS SIGN BELOW;Mn;220;NSM;;;;;N;;;;;
+0348;COMBINING DOUBLE VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;;;;;
+0349;COMBINING LEFT ANGLE BELOW;Mn;220;NSM;;;;;N;;;;;
+034A;COMBINING NOT TILDE ABOVE;Mn;230;NSM;;;;;N;;;;;
+034B;COMBINING HOMOTHETIC ABOVE;Mn;230;NSM;;;;;N;;;;;
+034C;COMBINING ALMOST EQUAL TO ABOVE;Mn;230;NSM;;;;;N;;;;;
+034D;COMBINING LEFT RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
+034E;COMBINING UPWARDS ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
+034F;COMBINING GRAPHEME JOINER;Mn;0;NSM;;;;;N;;;;;
+0350;COMBINING RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
+0351;COMBINING LEFT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;;
+0352;COMBINING FERMATA;Mn;230;NSM;;;;;N;;;;;
+0353;COMBINING X BELOW;Mn;220;NSM;;;;;N;;;;;
+0354;COMBINING LEFT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+0355;COMBINING RIGHT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+0356;COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+0357;COMBINING RIGHT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;;
+0358;COMBINING DOT ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;;
+0359;COMBINING ASTERISK BELOW;Mn;220;NSM;;;;;N;;;;;
+035A;COMBINING DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;;
+035B;COMBINING ZIGZAG ABOVE;Mn;230;NSM;;;;;N;;;;;
+035C;COMBINING DOUBLE BREVE BELOW;Mn;233;NSM;;;;;N;;;;;
+035D;COMBINING DOUBLE BREVE;Mn;234;NSM;;;;;N;;;;;
+035E;COMBINING DOUBLE MACRON;Mn;234;NSM;;;;;N;;;;;
+035F;COMBINING DOUBLE MACRON BELOW;Mn;233;NSM;;;;;N;;;;;
+0360;COMBINING DOUBLE TILDE;Mn;234;NSM;;;;;N;;;;;
+0361;COMBINING DOUBLE INVERTED BREVE;Mn;234;NSM;;;;;N;;;;;
+0362;COMBINING DOUBLE RIGHTWARDS ARROW BELOW;Mn;233;NSM;;;;;N;;;;;
+0363;COMBINING LATIN SMALL LETTER A;Mn;230;NSM;;;;;N;;;;;
+0364;COMBINING LATIN SMALL LETTER E;Mn;230;NSM;;;;;N;;;;;
+0365;COMBINING LATIN SMALL LETTER I;Mn;230;NSM;;;;;N;;;;;
+0366;COMBINING LATIN SMALL LETTER O;Mn;230;NSM;;;;;N;;;;;
+0367;COMBINING LATIN SMALL LETTER U;Mn;230;NSM;;;;;N;;;;;
+0368;COMBINING LATIN SMALL LETTER C;Mn;230;NSM;;;;;N;;;;;
+0369;COMBINING LATIN SMALL LETTER D;Mn;230;NSM;;;;;N;;;;;
+036A;COMBINING LATIN SMALL LETTER H;Mn;230;NSM;;;;;N;;;;;
+036B;COMBINING LATIN SMALL LETTER M;Mn;230;NSM;;;;;N;;;;;
+036C;COMBINING LATIN SMALL LETTER R;Mn;230;NSM;;;;;N;;;;;
+036D;COMBINING LATIN SMALL LETTER T;Mn;230;NSM;;;;;N;;;;;
+036E;COMBINING LATIN SMALL LETTER V;Mn;230;NSM;;;;;N;;;;;
+036F;COMBINING LATIN SMALL LETTER X;Mn;230;NSM;;;;;N;;;;;
+0370;GREEK CAPITAL LETTER HETA;Lu;0;L;;;;;N;;;;0371;
+0371;GREEK SMALL LETTER HETA;Ll;0;L;;;;;N;;;0370;;0370
+0372;GREEK CAPITAL LETTER ARCHAIC SAMPI;Lu;0;L;;;;;N;;;;0373;
+0373;GREEK SMALL LETTER ARCHAIC SAMPI;Ll;0;L;;;;;N;;;0372;;0372
+0374;GREEK NUMERAL SIGN;Lm;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;;;;
+0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;;;;
+0376;GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA;Lu;0;L;;;;;N;;;;0377;
+0377;GREEK SMALL LETTER PAMPHYLIAN DIGAMMA;Ll;0;L;;;;;N;;;0376;;0376
+037A;GREEK YPOGEGRAMMENI;Lm;0;L;<compat> 0020 0345;;;;N;GREEK SPACING IOTA BELOW;;;;
+037B;GREEK SMALL REVERSED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FD;;03FD
+037C;GREEK SMALL DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FE;;03FE
+037D;GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FF;;03FF
+037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;;;;
+037F;GREEK CAPITAL LETTER YOT;Lu;0;L;;;;;N;;;;03F3;
+0384;GREEK TONOS;Sk;0;ON;<compat> 0020 0301;;;;N;GREEK SPACING TONOS;;;;
+0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;;
+0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC;
+0387;GREEK ANO TELEIA;Po;0;ON;00B7;;;;N;;;;;
+0388;GREEK CAPITAL LETTER EPSILON WITH TONOS;Lu;0;L;0395 0301;;;;N;GREEK CAPITAL LETTER EPSILON TONOS;;;03AD;
+0389;GREEK CAPITAL LETTER ETA WITH TONOS;Lu;0;L;0397 0301;;;;N;GREEK CAPITAL LETTER ETA TONOS;;;03AE;
+038A;GREEK CAPITAL LETTER IOTA WITH TONOS;Lu;0;L;0399 0301;;;;N;GREEK CAPITAL LETTER IOTA TONOS;;;03AF;
+038C;GREEK CAPITAL LETTER OMICRON WITH TONOS;Lu;0;L;039F 0301;;;;N;GREEK CAPITAL LETTER OMICRON TONOS;;;03CC;
+038E;GREEK CAPITAL LETTER UPSILON WITH TONOS;Lu;0;L;03A5 0301;;;;N;GREEK CAPITAL LETTER UPSILON TONOS;;;03CD;
+038F;GREEK CAPITAL LETTER OMEGA WITH TONOS;Lu;0;L;03A9 0301;;;;N;GREEK CAPITAL LETTER OMEGA TONOS;;;03CE;
+0390;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS;Ll;0;L;03CA 0301;;;;N;GREEK SMALL LETTER IOTA DIAERESIS TONOS;;;;
+0391;GREEK CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;03B1;
+0392;GREEK CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;03B2;
+0393;GREEK CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;03B3;
+0394;GREEK CAPITAL LETTER DELTA;Lu;0;L;;;;;N;;;;03B4;
+0395;GREEK CAPITAL LETTER EPSILON;Lu;0;L;;;;;N;;;;03B5;
+0396;GREEK CAPITAL LETTER ZETA;Lu;0;L;;;;;N;;;;03B6;
+0397;GREEK CAPITAL LETTER ETA;Lu;0;L;;;;;N;;;;03B7;
+0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8;
+0399;GREEK CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;03B9;
+039A;GREEK CAPITAL LETTER KAPPA;Lu;0;L;;;;;N;;;;03BA;
+039B;GREEK CAPITAL LETTER LAMDA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER LAMBDA;;;03BB;
+039C;GREEK CAPITAL LETTER MU;Lu;0;L;;;;;N;;;;03BC;
+039D;GREEK CAPITAL LETTER NU;Lu;0;L;;;;;N;;;;03BD;
+039E;GREEK CAPITAL LETTER XI;Lu;0;L;;;;;N;;;;03BE;
+039F;GREEK CAPITAL LETTER OMICRON;Lu;0;L;;;;;N;;;;03BF;
+03A0;GREEK CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;03C0;
+03A1;GREEK CAPITAL LETTER RHO;Lu;0;L;;;;;N;;;;03C1;
+03A3;GREEK CAPITAL LETTER SIGMA;Lu;0;L;;;;;N;;;;03C3;
+03A4;GREEK CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;03C4;
+03A5;GREEK CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;03C5;
+03A6;GREEK CAPITAL LETTER PHI;Lu;0;L;;;;;N;;;;03C6;
+03A7;GREEK CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;03C7;
+03A8;GREEK CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;03C8;
+03A9;GREEK CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;03C9;
+03AA;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA;Lu;0;L;0399 0308;;;;N;GREEK CAPITAL LETTER IOTA DIAERESIS;;;03CA;
+03AB;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA;Lu;0;L;03A5 0308;;;;N;GREEK CAPITAL LETTER UPSILON DIAERESIS;;;03CB;
+03AC;GREEK SMALL LETTER ALPHA WITH TONOS;Ll;0;L;03B1 0301;;;;N;GREEK SMALL LETTER ALPHA TONOS;;0386;;0386
+03AD;GREEK SMALL LETTER EPSILON WITH TONOS;Ll;0;L;03B5 0301;;;;N;GREEK SMALL LETTER EPSILON TONOS;;0388;;0388
+03AE;GREEK SMALL LETTER ETA WITH TONOS;Ll;0;L;03B7 0301;;;;N;GREEK SMALL LETTER ETA TONOS;;0389;;0389
+03AF;GREEK SMALL LETTER IOTA WITH TONOS;Ll;0;L;03B9 0301;;;;N;GREEK SMALL LETTER IOTA TONOS;;038A;;038A
+03B0;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS;Ll;0;L;03CB 0301;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS TONOS;;;;
+03B1;GREEK SMALL LETTER ALPHA;Ll;0;L;;;;;N;;;0391;;0391
+03B2;GREEK SMALL LETTER BETA;Ll;0;L;;;;;N;;;0392;;0392
+03B3;GREEK SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0393;;0393
+03B4;GREEK SMALL LETTER DELTA;Ll;0;L;;;;;N;;;0394;;0394
+03B5;GREEK SMALL LETTER EPSILON;Ll;0;L;;;;;N;;;0395;;0395
+03B6;GREEK SMALL LETTER ZETA;Ll;0;L;;;;;N;;;0396;;0396
+03B7;GREEK SMALL LETTER ETA;Ll;0;L;;;;;N;;;0397;;0397
+03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398
+03B9;GREEK SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0399;;0399
+03BA;GREEK SMALL LETTER KAPPA;Ll;0;L;;;;;N;;;039A;;039A
+03BB;GREEK SMALL LETTER LAMDA;Ll;0;L;;;;;N;GREEK SMALL LETTER LAMBDA;;039B;;039B
+03BC;GREEK SMALL LETTER MU;Ll;0;L;;;;;N;;;039C;;039C
+03BD;GREEK SMALL LETTER NU;Ll;0;L;;;;;N;;;039D;;039D
+03BE;GREEK SMALL LETTER XI;Ll;0;L;;;;;N;;;039E;;039E
+03BF;GREEK SMALL LETTER OMICRON;Ll;0;L;;;;;N;;;039F;;039F
+03C0;GREEK SMALL LETTER PI;Ll;0;L;;;;;N;;;03A0;;03A0
+03C1;GREEK SMALL LETTER RHO;Ll;0;L;;;;;N;;;03A1;;03A1
+03C2;GREEK SMALL LETTER FINAL SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3
+03C3;GREEK SMALL LETTER SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3
+03C4;GREEK SMALL LETTER TAU;Ll;0;L;;;;;N;;;03A4;;03A4
+03C5;GREEK SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;03A5;;03A5
+03C6;GREEK SMALL LETTER PHI;Ll;0;L;;;;;N;;;03A6;;03A6
+03C7;GREEK SMALL LETTER CHI;Ll;0;L;;;;;N;;;03A7;;03A7
+03C8;GREEK SMALL LETTER PSI;Ll;0;L;;;;;N;;;03A8;;03A8
+03C9;GREEK SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;03A9;;03A9
+03CA;GREEK SMALL LETTER IOTA WITH DIALYTIKA;Ll;0;L;03B9 0308;;;;N;GREEK SMALL LETTER IOTA DIAERESIS;;03AA;;03AA
+03CB;GREEK SMALL LETTER UPSILON WITH DIALYTIKA;Ll;0;L;03C5 0308;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS;;03AB;;03AB
+03CC;GREEK SMALL LETTER OMICRON WITH TONOS;Ll;0;L;03BF 0301;;;;N;GREEK SMALL LETTER OMICRON TONOS;;038C;;038C
+03CD;GREEK SMALL LETTER UPSILON WITH TONOS;Ll;0;L;03C5 0301;;;;N;GREEK SMALL LETTER UPSILON TONOS;;038E;;038E
+03CE;GREEK SMALL LETTER OMEGA WITH TONOS;Ll;0;L;03C9 0301;;;;N;GREEK SMALL LETTER OMEGA TONOS;;038F;;038F
+03CF;GREEK CAPITAL KAI SYMBOL;Lu;0;L;;;;;N;;;;03D7;
+03D0;GREEK BETA SYMBOL;Ll;0;L;<compat> 03B2;;;;N;GREEK SMALL LETTER CURLED BETA;;0392;;0392
+03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398
+03D2;GREEK UPSILON WITH HOOK SYMBOL;Lu;0;L;<compat> 03A5;;;;N;GREEK CAPITAL LETTER UPSILON HOOK;;;;
+03D3;GREEK UPSILON WITH ACUTE AND HOOK SYMBOL;Lu;0;L;03D2 0301;;;;N;GREEK CAPITAL LETTER UPSILON HOOK TONOS;;;;
+03D4;GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL;Lu;0;L;03D2 0308;;;;N;GREEK CAPITAL LETTER UPSILON HOOK DIAERESIS;;;;
+03D5;GREEK PHI SYMBOL;Ll;0;L;<compat> 03C6;;;;N;GREEK SMALL LETTER SCRIPT PHI;;03A6;;03A6
+03D6;GREEK PI SYMBOL;Ll;0;L;<compat> 03C0;;;;N;GREEK SMALL LETTER OMEGA PI;;03A0;;03A0
+03D7;GREEK KAI SYMBOL;Ll;0;L;;;;;N;;;03CF;;03CF
+03D8;GREEK LETTER ARCHAIC KOPPA;Lu;0;L;;;;;N;;;;03D9;
+03D9;GREEK SMALL LETTER ARCHAIC KOPPA;Ll;0;L;;;;;N;;;03D8;;03D8
+03DA;GREEK LETTER STIGMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER STIGMA;;;03DB;
+03DB;GREEK SMALL LETTER STIGMA;Ll;0;L;;;;;N;;;03DA;;03DA
+03DC;GREEK LETTER DIGAMMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DIGAMMA;;;03DD;
+03DD;GREEK SMALL LETTER DIGAMMA;Ll;0;L;;;;;N;;;03DC;;03DC
+03DE;GREEK LETTER KOPPA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KOPPA;;;03DF;
+03DF;GREEK SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;03DE;;03DE
+03E0;GREEK LETTER SAMPI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SAMPI;;;03E1;
+03E1;GREEK SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;03E0;;03E0
+03E2;COPTIC CAPITAL LETTER SHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHEI;;;03E3;
+03E3;COPTIC SMALL LETTER SHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER SHEI;;03E2;;03E2
+03E4;COPTIC CAPITAL LETTER FEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER FEI;;;03E5;
+03E5;COPTIC SMALL LETTER FEI;Ll;0;L;;;;;N;GREEK SMALL LETTER FEI;;03E4;;03E4
+03E6;COPTIC CAPITAL LETTER KHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KHEI;;;03E7;
+03E7;COPTIC SMALL LETTER KHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER KHEI;;03E6;;03E6
+03E8;COPTIC CAPITAL LETTER HORI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER HORI;;;03E9;
+03E9;COPTIC SMALL LETTER HORI;Ll;0;L;;;;;N;GREEK SMALL LETTER HORI;;03E8;;03E8
+03EA;COPTIC CAPITAL LETTER GANGIA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER GANGIA;;;03EB;
+03EB;COPTIC SMALL LETTER GANGIA;Ll;0;L;;;;;N;GREEK SMALL LETTER GANGIA;;03EA;;03EA
+03EC;COPTIC CAPITAL LETTER SHIMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHIMA;;;03ED;
+03ED;COPTIC SMALL LETTER SHIMA;Ll;0;L;;;;;N;GREEK SMALL LETTER SHIMA;;03EC;;03EC
+03EE;COPTIC CAPITAL LETTER DEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DEI;;;03EF;
+03EF;COPTIC SMALL LETTER DEI;Ll;0;L;;;;;N;GREEK SMALL LETTER DEI;;03EE;;03EE
+03F0;GREEK KAPPA SYMBOL;Ll;0;L;<compat> 03BA;;;;N;GREEK SMALL LETTER SCRIPT KAPPA;;039A;;039A
+03F1;GREEK RHO SYMBOL;Ll;0;L;<compat> 03C1;;;;N;GREEK SMALL LETTER TAILED RHO;;03A1;;03A1
+03F2;GREEK LUNATE SIGMA SYMBOL;Ll;0;L;<compat> 03C2;;;;N;GREEK SMALL LETTER LUNATE SIGMA;;03F9;;03F9
+03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;037F;;037F
+03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8;
+03F5;GREEK LUNATE EPSILON SYMBOL;Ll;0;L;<compat> 03B5;;;;N;;;0395;;0395
+03F6;GREEK REVERSED LUNATE EPSILON SYMBOL;Sm;0;ON;;;;;N;;;;;
+03F7;GREEK CAPITAL LETTER SHO;Lu;0;L;;;;;N;;;;03F8;
+03F8;GREEK SMALL LETTER SHO;Ll;0;L;;;;;N;;;03F7;;03F7
+03F9;GREEK CAPITAL LUNATE SIGMA SYMBOL;Lu;0;L;<compat> 03A3;;;;N;;;;03F2;
+03FA;GREEK CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;03FB;
+03FB;GREEK SMALL LETTER SAN;Ll;0;L;;;;;N;;;03FA;;03FA
+03FC;GREEK RHO WITH STROKE SYMBOL;Ll;0;L;;;;;N;;;;;
+03FD;GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037B;
+03FE;GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037C;
+03FF;GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037D;
+0400;CYRILLIC CAPITAL LETTER IE WITH GRAVE;Lu;0;L;0415 0300;;;;N;;;;0450;
+0401;CYRILLIC CAPITAL LETTER IO;Lu;0;L;0415 0308;;;;N;;;;0451;
+0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;;;0452;
+0403;CYRILLIC CAPITAL LETTER GJE;Lu;0;L;0413 0301;;;;N;;;;0453;
+0404;CYRILLIC CAPITAL LETTER UKRAINIAN IE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER E;;;0454;
+0405;CYRILLIC CAPITAL LETTER DZE;Lu;0;L;;;;;N;;;;0455;
+0406;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER I;;;0456;
+0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;;;0457;
+0408;CYRILLIC CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;0458;
+0409;CYRILLIC CAPITAL LETTER LJE;Lu;0;L;;;;;N;;;;0459;
+040A;CYRILLIC CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;045A;
+040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;;;045B;
+040C;CYRILLIC CAPITAL LETTER KJE;Lu;0;L;041A 0301;;;;N;;;;045C;
+040D;CYRILLIC CAPITAL LETTER I WITH GRAVE;Lu;0;L;0418 0300;;;;N;;;;045D;
+040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;;;045E;
+040F;CYRILLIC CAPITAL LETTER DZHE;Lu;0;L;;;;;N;;;;045F;
+0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430;
+0411;CYRILLIC CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;0431;
+0412;CYRILLIC CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;0432;
+0413;CYRILLIC CAPITAL LETTER GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE;;;0433;
+0414;CYRILLIC CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;0434;
+0415;CYRILLIC CAPITAL LETTER IE;Lu;0;L;;;;;N;;;;0435;
+0416;CYRILLIC CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;0436;
+0417;CYRILLIC CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;0437;
+0418;CYRILLIC CAPITAL LETTER I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER II;;;0438;
+0419;CYRILLIC CAPITAL LETTER SHORT I;Lu;0;L;0418 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT II;;;0439;
+041A;CYRILLIC CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;043A;
+041B;CYRILLIC CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;043B;
+041C;CYRILLIC CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;043C;
+041D;CYRILLIC CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;043D;
+041E;CYRILLIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;043E;
+041F;CYRILLIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;043F;
+0420;CYRILLIC CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;0440;
+0421;CYRILLIC CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;0441;
+0422;CYRILLIC CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;0442;
+0423;CYRILLIC CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0443;
+0424;CYRILLIC CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;0444;
+0425;CYRILLIC CAPITAL LETTER HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA;;;0445;
+0426;CYRILLIC CAPITAL LETTER TSE;Lu;0;L;;;;;N;;;;0446;
+0427;CYRILLIC CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;0447;
+0428;CYRILLIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0448;
+0429;CYRILLIC CAPITAL LETTER SHCHA;Lu;0;L;;;;;N;;;;0449;
+042A;CYRILLIC CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;044A;
+042B;CYRILLIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER YERI;;;044B;
+042C;CYRILLIC CAPITAL LETTER SOFT SIGN;Lu;0;L;;;;;N;;;;044C;
+042D;CYRILLIC CAPITAL LETTER E;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED E;;;044D;
+042E;CYRILLIC CAPITAL LETTER YU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IU;;;044E;
+042F;CYRILLIC CAPITAL LETTER YA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IA;;;044F;
+0430;CYRILLIC SMALL LETTER A;Ll;0;L;;;;;N;;;0410;;0410
+0431;CYRILLIC SMALL LETTER BE;Ll;0;L;;;;;N;;;0411;;0411
+0432;CYRILLIC SMALL LETTER VE;Ll;0;L;;;;;N;;;0412;;0412
+0433;CYRILLIC SMALL LETTER GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE;;0413;;0413
+0434;CYRILLIC SMALL LETTER DE;Ll;0;L;;;;;N;;;0414;;0414
+0435;CYRILLIC SMALL LETTER IE;Ll;0;L;;;;;N;;;0415;;0415
+0436;CYRILLIC SMALL LETTER ZHE;Ll;0;L;;;;;N;;;0416;;0416
+0437;CYRILLIC SMALL LETTER ZE;Ll;0;L;;;;;N;;;0417;;0417
+0438;CYRILLIC SMALL LETTER I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER II;;0418;;0418
+0439;CYRILLIC SMALL LETTER SHORT I;Ll;0;L;0438 0306;;;;N;CYRILLIC SMALL LETTER SHORT II;;0419;;0419
+043A;CYRILLIC SMALL LETTER KA;Ll;0;L;;;;;N;;;041A;;041A
+043B;CYRILLIC SMALL LETTER EL;Ll;0;L;;;;;N;;;041B;;041B
+043C;CYRILLIC SMALL LETTER EM;Ll;0;L;;;;;N;;;041C;;041C
+043D;CYRILLIC SMALL LETTER EN;Ll;0;L;;;;;N;;;041D;;041D
+043E;CYRILLIC SMALL LETTER O;Ll;0;L;;;;;N;;;041E;;041E
+043F;CYRILLIC SMALL LETTER PE;Ll;0;L;;;;;N;;;041F;;041F
+0440;CYRILLIC SMALL LETTER ER;Ll;0;L;;;;;N;;;0420;;0420
+0441;CYRILLIC SMALL LETTER ES;Ll;0;L;;;;;N;;;0421;;0421
+0442;CYRILLIC SMALL LETTER TE;Ll;0;L;;;;;N;;;0422;;0422
+0443;CYRILLIC SMALL LETTER U;Ll;0;L;;;;;N;;;0423;;0423
+0444;CYRILLIC SMALL LETTER EF;Ll;0;L;;;;;N;;;0424;;0424
+0445;CYRILLIC SMALL LETTER HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA;;0425;;0425
+0446;CYRILLIC SMALL LETTER TSE;Ll;0;L;;;;;N;;;0426;;0426
+0447;CYRILLIC SMALL LETTER CHE;Ll;0;L;;;;;N;;;0427;;0427
+0448;CYRILLIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;0428;;0428
+0449;CYRILLIC SMALL LETTER SHCHA;Ll;0;L;;;;;N;;;0429;;0429
+044A;CYRILLIC SMALL LETTER HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A
+044B;CYRILLIC SMALL LETTER YERU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER YERI;;042B;;042B
+044C;CYRILLIC SMALL LETTER SOFT SIGN;Ll;0;L;;;;;N;;;042C;;042C
+044D;CYRILLIC SMALL LETTER E;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED E;;042D;;042D
+044E;CYRILLIC SMALL LETTER YU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IU;;042E;;042E
+044F;CYRILLIC SMALL LETTER YA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IA;;042F;;042F
+0450;CYRILLIC SMALL LETTER IE WITH GRAVE;Ll;0;L;0435 0300;;;;N;;;0400;;0400
+0451;CYRILLIC SMALL LETTER IO;Ll;0;L;0435 0308;;;;N;;;0401;;0401
+0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;;0402;;0402
+0453;CYRILLIC SMALL LETTER GJE;Ll;0;L;0433 0301;;;;N;;;0403;;0403
+0454;CYRILLIC SMALL LETTER UKRAINIAN IE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER E;;0404;;0404
+0455;CYRILLIC SMALL LETTER DZE;Ll;0;L;;;;;N;;;0405;;0405
+0456;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER I;;0406;;0406
+0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;;0407;;0407
+0458;CYRILLIC SMALL LETTER JE;Ll;0;L;;;;;N;;;0408;;0408
+0459;CYRILLIC SMALL LETTER LJE;Ll;0;L;;;;;N;;;0409;;0409
+045A;CYRILLIC SMALL LETTER NJE;Ll;0;L;;;;;N;;;040A;;040A
+045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;;040B;;040B
+045C;CYRILLIC SMALL LETTER KJE;Ll;0;L;043A 0301;;;;N;;;040C;;040C
+045D;CYRILLIC SMALL LETTER I WITH GRAVE;Ll;0;L;0438 0300;;;;N;;;040D;;040D
+045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;;040E;;040E
+045F;CYRILLIC SMALL LETTER DZHE;Ll;0;L;;;;;N;;;040F;;040F
+0460;CYRILLIC CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;0461;
+0461;CYRILLIC SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;0460;;0460
+0462;CYRILLIC CAPITAL LETTER YAT;Lu;0;L;;;;;N;;;;0463;
+0463;CYRILLIC SMALL LETTER YAT;Ll;0;L;;;;;N;;;0462;;0462
+0464;CYRILLIC CAPITAL LETTER IOTIFIED E;Lu;0;L;;;;;N;;;;0465;
+0465;CYRILLIC SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;0464;;0464
+0466;CYRILLIC CAPITAL LETTER LITTLE YUS;Lu;0;L;;;;;N;;;;0467;
+0467;CYRILLIC SMALL LETTER LITTLE YUS;Ll;0;L;;;;;N;;;0466;;0466
+0468;CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS;Lu;0;L;;;;;N;;;;0469;
+0469;CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS;Ll;0;L;;;;;N;;;0468;;0468
+046A;CYRILLIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;046B;
+046B;CYRILLIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;046A;;046A
+046C;CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS;Lu;0;L;;;;;N;;;;046D;
+046D;CYRILLIC SMALL LETTER IOTIFIED BIG YUS;Ll;0;L;;;;;N;;;046C;;046C
+046E;CYRILLIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;046F;
+046F;CYRILLIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;046E;;046E
+0470;CYRILLIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;0471;
+0471;CYRILLIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;0470;;0470
+0472;CYRILLIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;0473;
+0473;CYRILLIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;0472;;0472
+0474;CYRILLIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;0475;
+0475;CYRILLIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;0474;;0474
+0476;CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Lu;0;L;0474 030F;;;;N;CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE;;;0477;
+0477;CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Ll;0;L;0475 030F;;;;N;CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE;;0476;;0476
+0478;CYRILLIC CAPITAL LETTER UK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER UK DIGRAPH;;;0479;
+0479;CYRILLIC SMALL LETTER UK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER UK DIGRAPH;;0478;;0478
+047A;CYRILLIC CAPITAL LETTER ROUND OMEGA;Lu;0;L;;;;;N;;;;047B;
+047B;CYRILLIC SMALL LETTER ROUND OMEGA;Ll;0;L;;;;;N;;;047A;;047A
+047C;CYRILLIC CAPITAL LETTER OMEGA WITH TITLO;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER OMEGA TITLO;;;047D;
+047D;CYRILLIC SMALL LETTER OMEGA WITH TITLO;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER OMEGA TITLO;;047C;;047C
+047E;CYRILLIC CAPITAL LETTER OT;Lu;0;L;;;;;N;;;;047F;
+047F;CYRILLIC SMALL LETTER OT;Ll;0;L;;;;;N;;;047E;;047E
+0480;CYRILLIC CAPITAL LETTER KOPPA;Lu;0;L;;;;;N;;;;0481;
+0481;CYRILLIC SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;0480;;0480
+0482;CYRILLIC THOUSANDS SIGN;So;0;L;;;;;N;;;;;
+0483;COMBINING CYRILLIC TITLO;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING TITLO;;;;
+0484;COMBINING CYRILLIC PALATALIZATION;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PALATALIZATION;;;;
+0485;COMBINING CYRILLIC DASIA PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING DASIA PNEUMATA;;;;
+0486;COMBINING CYRILLIC PSILI PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PSILI PNEUMATA;;;;
+0487;COMBINING CYRILLIC POKRYTIE;Mn;230;NSM;;;;;N;;;;;
+0488;COMBINING CYRILLIC HUNDRED THOUSANDS SIGN;Me;0;NSM;;;;;N;;;;;
+0489;COMBINING CYRILLIC MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
+048A;CYRILLIC CAPITAL LETTER SHORT I WITH TAIL;Lu;0;L;;;;;N;;;;048B;
+048B;CYRILLIC SMALL LETTER SHORT I WITH TAIL;Ll;0;L;;;;;N;;;048A;;048A
+048C;CYRILLIC CAPITAL LETTER SEMISOFT SIGN;Lu;0;L;;;;;N;;;;048D;
+048D;CYRILLIC SMALL LETTER SEMISOFT SIGN;Ll;0;L;;;;;N;;;048C;;048C
+048E;CYRILLIC CAPITAL LETTER ER WITH TICK;Lu;0;L;;;;;N;;;;048F;
+048F;CYRILLIC SMALL LETTER ER WITH TICK;Ll;0;L;;;;;N;;;048E;;048E
+0490;CYRILLIC CAPITAL LETTER GHE WITH UPTURN;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE WITH UPTURN;;;0491;
+0491;CYRILLIC SMALL LETTER GHE WITH UPTURN;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE WITH UPTURN;;0490;;0490
+0492;CYRILLIC CAPITAL LETTER GHE WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE BAR;;;0493;
+0493;CYRILLIC SMALL LETTER GHE WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE BAR;;0492;;0492
+0494;CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE HOOK;;;0495;
+0495;CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE HOOK;;0494;;0494
+0496;CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER;;;0497;
+0497;CYRILLIC SMALL LETTER ZHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER;;0496;;0496
+0498;CYRILLIC CAPITAL LETTER ZE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZE CEDILLA;;;0499;
+0499;CYRILLIC SMALL LETTER ZE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZE CEDILLA;;0498;;0498
+049A;CYRILLIC CAPITAL LETTER KA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER;;;049B;
+049B;CYRILLIC SMALL LETTER KA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER;;049A;;049A
+049C;CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA VERTICAL BAR;;;049D;
+049D;CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA VERTICAL BAR;;049C;;049C
+049E;CYRILLIC CAPITAL LETTER KA WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA BAR;;;049F;
+049F;CYRILLIC SMALL LETTER KA WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA BAR;;049E;;049E
+04A0;CYRILLIC CAPITAL LETTER BASHKIR KA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED GE KA;;;04A1;
+04A1;CYRILLIC SMALL LETTER BASHKIR KA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED GE KA;;04A0;;04A0
+04A2;CYRILLIC CAPITAL LETTER EN WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER;;;04A3;
+04A3;CYRILLIC SMALL LETTER EN WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER;;04A2;;04A2
+04A4;CYRILLIC CAPITAL LIGATURE EN GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN GE;;;04A5;
+04A5;CYRILLIC SMALL LIGATURE EN GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN GE;;04A4;;04A4
+04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;;;04A7;
+04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;;04A6;;04A6
+04A8;CYRILLIC CAPITAL LETTER ABKHASIAN HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER O HOOK;;;04A9;
+04A9;CYRILLIC SMALL LETTER ABKHASIAN HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER O HOOK;;04A8;;04A8
+04AA;CYRILLIC CAPITAL LETTER ES WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ES CEDILLA;;;04AB;
+04AB;CYRILLIC SMALL LETTER ES WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ES CEDILLA;;04AA;;04AA
+04AC;CYRILLIC CAPITAL LETTER TE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER;;;04AD;
+04AD;CYRILLIC SMALL LETTER TE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER;;04AC;;04AC
+04AE;CYRILLIC CAPITAL LETTER STRAIGHT U;Lu;0;L;;;;;N;;;;04AF;
+04AF;CYRILLIC SMALL LETTER STRAIGHT U;Ll;0;L;;;;;N;;;04AE;;04AE
+04B0;CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER STRAIGHT U BAR;;;04B1;
+04B1;CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER STRAIGHT U BAR;;04B0;;04B0
+04B2;CYRILLIC CAPITAL LETTER HA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER;;;04B3;
+04B3;CYRILLIC SMALL LETTER HA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER;;04B2;;04B2
+04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;;;04B5;
+04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;;04B4;;04B4
+04B6;CYRILLIC CAPITAL LETTER CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER;;;04B7;
+04B7;CYRILLIC SMALL LETTER CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER;;04B6;;04B6
+04B8;CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE VERTICAL BAR;;;04B9;
+04B9;CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE VERTICAL BAR;;04B8;;04B8
+04BA;CYRILLIC CAPITAL LETTER SHHA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER H;;;04BB;
+04BB;CYRILLIC SMALL LETTER SHHA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER H;;04BA;;04BA
+04BC;CYRILLIC CAPITAL LETTER ABKHASIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK;;;04BD;
+04BD;CYRILLIC SMALL LETTER ABKHASIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK;;04BC;;04BC
+04BE;CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK OGONEK;;;04BF;
+04BF;CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK OGONEK;;04BE;;04BE
+04C0;CYRILLIC LETTER PALOCHKA;Lu;0;L;;;;;N;CYRILLIC LETTER I;;;04CF;
+04C1;CYRILLIC CAPITAL LETTER ZHE WITH BREVE;Lu;0;L;0416 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT ZHE;;;04C2;
+04C2;CYRILLIC SMALL LETTER ZHE WITH BREVE;Ll;0;L;0436 0306;;;;N;CYRILLIC SMALL LETTER SHORT ZHE;;04C1;;04C1
+04C3;CYRILLIC CAPITAL LETTER KA WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA HOOK;;;04C4;
+04C4;CYRILLIC SMALL LETTER KA WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA HOOK;;04C3;;04C3
+04C5;CYRILLIC CAPITAL LETTER EL WITH TAIL;Lu;0;L;;;;;N;;;;04C6;
+04C6;CYRILLIC SMALL LETTER EL WITH TAIL;Ll;0;L;;;;;N;;;04C5;;04C5
+04C7;CYRILLIC CAPITAL LETTER EN WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN HOOK;;;04C8;
+04C8;CYRILLIC SMALL LETTER EN WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN HOOK;;04C7;;04C7
+04C9;CYRILLIC CAPITAL LETTER EN WITH TAIL;Lu;0;L;;;;;N;;;;04CA;
+04CA;CYRILLIC SMALL LETTER EN WITH TAIL;Ll;0;L;;;;;N;;;04C9;;04C9
+04CB;CYRILLIC CAPITAL LETTER KHAKASSIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER;;;04CC;
+04CC;CYRILLIC SMALL LETTER KHAKASSIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER;;04CB;;04CB
+04CD;CYRILLIC CAPITAL LETTER EM WITH TAIL;Lu;0;L;;;;;N;;;;04CE;
+04CE;CYRILLIC SMALL LETTER EM WITH TAIL;Ll;0;L;;;;;N;;;04CD;;04CD
+04CF;CYRILLIC SMALL LETTER PALOCHKA;Ll;0;L;;;;;N;;;04C0;;04C0
+04D0;CYRILLIC CAPITAL LETTER A WITH BREVE;Lu;0;L;0410 0306;;;;N;;;;04D1;
+04D1;CYRILLIC SMALL LETTER A WITH BREVE;Ll;0;L;0430 0306;;;;N;;;04D0;;04D0
+04D2;CYRILLIC CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0410 0308;;;;N;;;;04D3;
+04D3;CYRILLIC SMALL LETTER A WITH DIAERESIS;Ll;0;L;0430 0308;;;;N;;;04D2;;04D2
+04D4;CYRILLIC CAPITAL LIGATURE A IE;Lu;0;L;;;;;N;;;;04D5;
+04D5;CYRILLIC SMALL LIGATURE A IE;Ll;0;L;;;;;N;;;04D4;;04D4
+04D6;CYRILLIC CAPITAL LETTER IE WITH BREVE;Lu;0;L;0415 0306;;;;N;;;;04D7;
+04D7;CYRILLIC SMALL LETTER IE WITH BREVE;Ll;0;L;0435 0306;;;;N;;;04D6;;04D6
+04D8;CYRILLIC CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;04D9;
+04D9;CYRILLIC SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;04D8;;04D8
+04DA;CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS;Lu;0;L;04D8 0308;;;;N;;;;04DB;
+04DB;CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS;Ll;0;L;04D9 0308;;;;N;;;04DA;;04DA
+04DC;CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS;Lu;0;L;0416 0308;;;;N;;;;04DD;
+04DD;CYRILLIC SMALL LETTER ZHE WITH DIAERESIS;Ll;0;L;0436 0308;;;;N;;;04DC;;04DC
+04DE;CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS;Lu;0;L;0417 0308;;;;N;;;;04DF;
+04DF;CYRILLIC SMALL LETTER ZE WITH DIAERESIS;Ll;0;L;0437 0308;;;;N;;;04DE;;04DE
+04E0;CYRILLIC CAPITAL LETTER ABKHASIAN DZE;Lu;0;L;;;;;N;;;;04E1;
+04E1;CYRILLIC SMALL LETTER ABKHASIAN DZE;Ll;0;L;;;;;N;;;04E0;;04E0
+04E2;CYRILLIC CAPITAL LETTER I WITH MACRON;Lu;0;L;0418 0304;;;;N;;;;04E3;
+04E3;CYRILLIC SMALL LETTER I WITH MACRON;Ll;0;L;0438 0304;;;;N;;;04E2;;04E2
+04E4;CYRILLIC CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0418 0308;;;;N;;;;04E5;
+04E5;CYRILLIC SMALL LETTER I WITH DIAERESIS;Ll;0;L;0438 0308;;;;N;;;04E4;;04E4
+04E6;CYRILLIC CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;041E 0308;;;;N;;;;04E7;
+04E7;CYRILLIC SMALL LETTER O WITH DIAERESIS;Ll;0;L;043E 0308;;;;N;;;04E6;;04E6
+04E8;CYRILLIC CAPITAL LETTER BARRED O;Lu;0;L;;;;;N;;;;04E9;
+04E9;CYRILLIC SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;04E8;;04E8
+04EA;CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS;Lu;0;L;04E8 0308;;;;N;;;;04EB;
+04EB;CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS;Ll;0;L;04E9 0308;;;;N;;;04EA;;04EA
+04EC;CYRILLIC CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;042D 0308;;;;N;;;;04ED;
+04ED;CYRILLIC SMALL LETTER E WITH DIAERESIS;Ll;0;L;044D 0308;;;;N;;;04EC;;04EC
+04EE;CYRILLIC CAPITAL LETTER U WITH MACRON;Lu;0;L;0423 0304;;;;N;;;;04EF;
+04EF;CYRILLIC SMALL LETTER U WITH MACRON;Ll;0;L;0443 0304;;;;N;;;04EE;;04EE
+04F0;CYRILLIC CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0423 0308;;;;N;;;;04F1;
+04F1;CYRILLIC SMALL LETTER U WITH DIAERESIS;Ll;0;L;0443 0308;;;;N;;;04F0;;04F0
+04F2;CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0423 030B;;;;N;;;;04F3;
+04F3;CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0443 030B;;;;N;;;04F2;;04F2
+04F4;CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS;Lu;0;L;0427 0308;;;;N;;;;04F5;
+04F5;CYRILLIC SMALL LETTER CHE WITH DIAERESIS;Ll;0;L;0447 0308;;;;N;;;04F4;;04F4
+04F6;CYRILLIC CAPITAL LETTER GHE WITH DESCENDER;Lu;0;L;;;;;N;;;;04F7;
+04F7;CYRILLIC SMALL LETTER GHE WITH DESCENDER;Ll;0;L;;;;;N;;;04F6;;04F6
+04F8;CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS;Lu;0;L;042B 0308;;;;N;;;;04F9;
+04F9;CYRILLIC SMALL LETTER YERU WITH DIAERESIS;Ll;0;L;044B 0308;;;;N;;;04F8;;04F8
+04FA;CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK;Lu;0;L;;;;;N;;;;04FB;
+04FB;CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK;Ll;0;L;;;;;N;;;04FA;;04FA
+04FC;CYRILLIC CAPITAL LETTER HA WITH HOOK;Lu;0;L;;;;;N;;;;04FD;
+04FD;CYRILLIC SMALL LETTER HA WITH HOOK;Ll;0;L;;;;;N;;;04FC;;04FC
+04FE;CYRILLIC CAPITAL LETTER HA WITH STROKE;Lu;0;L;;;;;N;;;;04FF;
+04FF;CYRILLIC SMALL LETTER HA WITH STROKE;Ll;0;L;;;;;N;;;04FE;;04FE
+0500;CYRILLIC CAPITAL LETTER KOMI DE;Lu;0;L;;;;;N;;;;0501;
+0501;CYRILLIC SMALL LETTER KOMI DE;Ll;0;L;;;;;N;;;0500;;0500
+0502;CYRILLIC CAPITAL LETTER KOMI DJE;Lu;0;L;;;;;N;;;;0503;
+0503;CYRILLIC SMALL LETTER KOMI DJE;Ll;0;L;;;;;N;;;0502;;0502
+0504;CYRILLIC CAPITAL LETTER KOMI ZJE;Lu;0;L;;;;;N;;;;0505;
+0505;CYRILLIC SMALL LETTER KOMI ZJE;Ll;0;L;;;;;N;;;0504;;0504
+0506;CYRILLIC CAPITAL LETTER KOMI DZJE;Lu;0;L;;;;;N;;;;0507;
+0507;CYRILLIC SMALL LETTER KOMI DZJE;Ll;0;L;;;;;N;;;0506;;0506
+0508;CYRILLIC CAPITAL LETTER KOMI LJE;Lu;0;L;;;;;N;;;;0509;
+0509;CYRILLIC SMALL LETTER KOMI LJE;Ll;0;L;;;;;N;;;0508;;0508
+050A;CYRILLIC CAPITAL LETTER KOMI NJE;Lu;0;L;;;;;N;;;;050B;
+050B;CYRILLIC SMALL LETTER KOMI NJE;Ll;0;L;;;;;N;;;050A;;050A
+050C;CYRILLIC CAPITAL LETTER KOMI SJE;Lu;0;L;;;;;N;;;;050D;
+050D;CYRILLIC SMALL LETTER KOMI SJE;Ll;0;L;;;;;N;;;050C;;050C
+050E;CYRILLIC CAPITAL LETTER KOMI TJE;Lu;0;L;;;;;N;;;;050F;
+050F;CYRILLIC SMALL LETTER KOMI TJE;Ll;0;L;;;;;N;;;050E;;050E
+0510;CYRILLIC CAPITAL LETTER REVERSED ZE;Lu;0;L;;;;;N;;;;0511;
+0511;CYRILLIC SMALL LETTER REVERSED ZE;Ll;0;L;;;;;N;;;0510;;0510
+0512;CYRILLIC CAPITAL LETTER EL WITH HOOK;Lu;0;L;;;;;N;;;;0513;
+0513;CYRILLIC SMALL LETTER EL WITH HOOK;Ll;0;L;;;;;N;;;0512;;0512
+0514;CYRILLIC CAPITAL LETTER LHA;Lu;0;L;;;;;N;;;;0515;
+0515;CYRILLIC SMALL LETTER LHA;Ll;0;L;;;;;N;;;0514;;0514
+0516;CYRILLIC CAPITAL LETTER RHA;Lu;0;L;;;;;N;;;;0517;
+0517;CYRILLIC SMALL LETTER RHA;Ll;0;L;;;;;N;;;0516;;0516
+0518;CYRILLIC CAPITAL LETTER YAE;Lu;0;L;;;;;N;;;;0519;
+0519;CYRILLIC SMALL LETTER YAE;Ll;0;L;;;;;N;;;0518;;0518
+051A;CYRILLIC CAPITAL LETTER QA;Lu;0;L;;;;;N;;;;051B;
+051B;CYRILLIC SMALL LETTER QA;Ll;0;L;;;;;N;;;051A;;051A
+051C;CYRILLIC CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;051D;
+051D;CYRILLIC SMALL LETTER WE;Ll;0;L;;;;;N;;;051C;;051C
+051E;CYRILLIC CAPITAL LETTER ALEUT KA;Lu;0;L;;;;;N;;;;051F;
+051F;CYRILLIC SMALL LETTER ALEUT KA;Ll;0;L;;;;;N;;;051E;;051E
+0520;CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0521;
+0521;CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0520;;0520
+0522;CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0523;
+0523;CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0522;;0522
+0524;CYRILLIC CAPITAL LETTER PE WITH DESCENDER;Lu;0;L;;;;;N;;;;0525;
+0525;CYRILLIC SMALL LETTER PE WITH DESCENDER;Ll;0;L;;;;;N;;;0524;;0524
+0526;CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER;Lu;0;L;;;;;N;;;;0527;
+0527;CYRILLIC SMALL LETTER SHHA WITH DESCENDER;Ll;0;L;;;;;N;;;0526;;0526
+0528;CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK;Lu;0;L;;;;;N;;;;0529;
+0529;CYRILLIC SMALL LETTER EN WITH LEFT HOOK;Ll;0;L;;;;;N;;;0528;;0528
+052A;CYRILLIC CAPITAL LETTER DZZHE;Lu;0;L;;;;;N;;;;052B;
+052B;CYRILLIC SMALL LETTER DZZHE;Ll;0;L;;;;;N;;;052A;;052A
+052C;CYRILLIC CAPITAL LETTER DCHE;Lu;0;L;;;;;N;;;;052D;
+052D;CYRILLIC SMALL LETTER DCHE;Ll;0;L;;;;;N;;;052C;;052C
+052E;CYRILLIC CAPITAL LETTER EL WITH DESCENDER;Lu;0;L;;;;;N;;;;052F;
+052F;CYRILLIC SMALL LETTER EL WITH DESCENDER;Ll;0;L;;;;;N;;;052E;;052E
+0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561;
+0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562;
+0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563;
+0534;ARMENIAN CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;0564;
+0535;ARMENIAN CAPITAL LETTER ECH;Lu;0;L;;;;;N;;;;0565;
+0536;ARMENIAN CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;0566;
+0537;ARMENIAN CAPITAL LETTER EH;Lu;0;L;;;;;N;;;;0567;
+0538;ARMENIAN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;0568;
+0539;ARMENIAN CAPITAL LETTER TO;Lu;0;L;;;;;N;;;;0569;
+053A;ARMENIAN CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;056A;
+053B;ARMENIAN CAPITAL LETTER INI;Lu;0;L;;;;;N;;;;056B;
+053C;ARMENIAN CAPITAL LETTER LIWN;Lu;0;L;;;;;N;;;;056C;
+053D;ARMENIAN CAPITAL LETTER XEH;Lu;0;L;;;;;N;;;;056D;
+053E;ARMENIAN CAPITAL LETTER CA;Lu;0;L;;;;;N;;;;056E;
+053F;ARMENIAN CAPITAL LETTER KEN;Lu;0;L;;;;;N;;;;056F;
+0540;ARMENIAN CAPITAL LETTER HO;Lu;0;L;;;;;N;;;;0570;
+0541;ARMENIAN CAPITAL LETTER JA;Lu;0;L;;;;;N;;;;0571;
+0542;ARMENIAN CAPITAL LETTER GHAD;Lu;0;L;;;;;N;ARMENIAN CAPITAL LETTER LAD;;;0572;
+0543;ARMENIAN CAPITAL LETTER CHEH;Lu;0;L;;;;;N;;;;0573;
+0544;ARMENIAN CAPITAL LETTER MEN;Lu;0;L;;;;;N;;;;0574;
+0545;ARMENIAN CAPITAL LETTER YI;Lu;0;L;;;;;N;;;;0575;
+0546;ARMENIAN CAPITAL LETTER NOW;Lu;0;L;;;;;N;;;;0576;
+0547;ARMENIAN CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0577;
+0548;ARMENIAN CAPITAL LETTER VO;Lu;0;L;;;;;N;;;;0578;
+0549;ARMENIAN CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;0579;
+054A;ARMENIAN CAPITAL LETTER PEH;Lu;0;L;;;;;N;;;;057A;
+054B;ARMENIAN CAPITAL LETTER JHEH;Lu;0;L;;;;;N;;;;057B;
+054C;ARMENIAN CAPITAL LETTER RA;Lu;0;L;;;;;N;;;;057C;
+054D;ARMENIAN CAPITAL LETTER SEH;Lu;0;L;;;;;N;;;;057D;
+054E;ARMENIAN CAPITAL LETTER VEW;Lu;0;L;;;;;N;;;;057E;
+054F;ARMENIAN CAPITAL LETTER TIWN;Lu;0;L;;;;;N;;;;057F;
+0550;ARMENIAN CAPITAL LETTER REH;Lu;0;L;;;;;N;;;;0580;
+0551;ARMENIAN CAPITAL LETTER CO;Lu;0;L;;;;;N;;;;0581;
+0552;ARMENIAN CAPITAL LETTER YIWN;Lu;0;L;;;;;N;;;;0582;
+0553;ARMENIAN CAPITAL LETTER PIWR;Lu;0;L;;;;;N;;;;0583;
+0554;ARMENIAN CAPITAL LETTER KEH;Lu;0;L;;;;;N;;;;0584;
+0555;ARMENIAN CAPITAL LETTER OH;Lu;0;L;;;;;N;;;;0585;
+0556;ARMENIAN CAPITAL LETTER FEH;Lu;0;L;;;;;N;;;;0586;
+0559;ARMENIAN MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;;
+055A;ARMENIAN APOSTROPHE;Po;0;L;;;;;N;ARMENIAN MODIFIER LETTER RIGHT HALF RING;;;;
+055B;ARMENIAN EMPHASIS MARK;Po;0;L;;;;;N;;;;;
+055C;ARMENIAN EXCLAMATION MARK;Po;0;L;;;;;N;;;;;
+055D;ARMENIAN COMMA;Po;0;L;;;;;N;;;;;
+055E;ARMENIAN QUESTION MARK;Po;0;L;;;;;N;;;;;
+055F;ARMENIAN ABBREVIATION MARK;Po;0;L;;;;;N;;;;;
+0561;ARMENIAN SMALL LETTER AYB;Ll;0;L;;;;;N;;;0531;;0531
+0562;ARMENIAN SMALL LETTER BEN;Ll;0;L;;;;;N;;;0532;;0532
+0563;ARMENIAN SMALL LETTER GIM;Ll;0;L;;;;;N;;;0533;;0533
+0564;ARMENIAN SMALL LETTER DA;Ll;0;L;;;;;N;;;0534;;0534
+0565;ARMENIAN SMALL LETTER ECH;Ll;0;L;;;;;N;;;0535;;0535
+0566;ARMENIAN SMALL LETTER ZA;Ll;0;L;;;;;N;;;0536;;0536
+0567;ARMENIAN SMALL LETTER EH;Ll;0;L;;;;;N;;;0537;;0537
+0568;ARMENIAN SMALL LETTER ET;Ll;0;L;;;;;N;;;0538;;0538
+0569;ARMENIAN SMALL LETTER TO;Ll;0;L;;;;;N;;;0539;;0539
+056A;ARMENIAN SMALL LETTER ZHE;Ll;0;L;;;;;N;;;053A;;053A
+056B;ARMENIAN SMALL LETTER INI;Ll;0;L;;;;;N;;;053B;;053B
+056C;ARMENIAN SMALL LETTER LIWN;Ll;0;L;;;;;N;;;053C;;053C
+056D;ARMENIAN SMALL LETTER XEH;Ll;0;L;;;;;N;;;053D;;053D
+056E;ARMENIAN SMALL LETTER CA;Ll;0;L;;;;;N;;;053E;;053E
+056F;ARMENIAN SMALL LETTER KEN;Ll;0;L;;;;;N;;;053F;;053F
+0570;ARMENIAN SMALL LETTER HO;Ll;0;L;;;;;N;;;0540;;0540
+0571;ARMENIAN SMALL LETTER JA;Ll;0;L;;;;;N;;;0541;;0541
+0572;ARMENIAN SMALL LETTER GHAD;Ll;0;L;;;;;N;ARMENIAN SMALL LETTER LAD;;0542;;0542
+0573;ARMENIAN SMALL LETTER CHEH;Ll;0;L;;;;;N;;;0543;;0543
+0574;ARMENIAN SMALL LETTER MEN;Ll;0;L;;;;;N;;;0544;;0544
+0575;ARMENIAN SMALL LETTER YI;Ll;0;L;;;;;N;;;0545;;0545
+0576;ARMENIAN SMALL LETTER NOW;Ll;0;L;;;;;N;;;0546;;0546
+0577;ARMENIAN SMALL LETTER SHA;Ll;0;L;;;;;N;;;0547;;0547
+0578;ARMENIAN SMALL LETTER VO;Ll;0;L;;;;;N;;;0548;;0548
+0579;ARMENIAN SMALL LETTER CHA;Ll;0;L;;;;;N;;;0549;;0549
+057A;ARMENIAN SMALL LETTER PEH;Ll;0;L;;;;;N;;;054A;;054A
+057B;ARMENIAN SMALL LETTER JHEH;Ll;0;L;;;;;N;;;054B;;054B
+057C;ARMENIAN SMALL LETTER RA;Ll;0;L;;;;;N;;;054C;;054C
+057D;ARMENIAN SMALL LETTER SEH;Ll;0;L;;;;;N;;;054D;;054D
+057E;ARMENIAN SMALL LETTER VEW;Ll;0;L;;;;;N;;;054E;;054E
+057F;ARMENIAN SMALL LETTER TIWN;Ll;0;L;;;;;N;;;054F;;054F
+0580;ARMENIAN SMALL LETTER REH;Ll;0;L;;;;;N;;;0550;;0550
+0581;ARMENIAN SMALL LETTER CO;Ll;0;L;;;;;N;;;0551;;0551
+0582;ARMENIAN SMALL LETTER YIWN;Ll;0;L;;;;;N;;;0552;;0552
+0583;ARMENIAN SMALL LETTER PIWR;Ll;0;L;;;;;N;;;0553;;0553
+0584;ARMENIAN SMALL LETTER KEH;Ll;0;L;;;;;N;;;0554;;0554
+0585;ARMENIAN SMALL LETTER OH;Ll;0;L;;;;;N;;;0555;;0555
+0586;ARMENIAN SMALL LETTER FEH;Ll;0;L;;;;;N;;;0556;;0556
+0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L;<compat> 0565 0582;;;;N;;;;;
+0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;;
+058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;;
+058D;RIGHT-FACING ARMENIAN ETERNITY SIGN;So;0;ON;;;;;N;;;;;
+058E;LEFT-FACING ARMENIAN ETERNITY SIGN;So;0;ON;;;;;N;;;;;
+058F;ARMENIAN DRAM SIGN;Sc;0;ET;;;;;N;;;;;
+0591;HEBREW ACCENT ETNAHTA;Mn;220;NSM;;;;;N;;;;;
+0592;HEBREW ACCENT SEGOL;Mn;230;NSM;;;;;N;;;;;
+0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;;
+0594;HEBREW ACCENT ZAQEF QATAN;Mn;230;NSM;;;;;N;;;;;
+0595;HEBREW ACCENT ZAQEF GADOL;Mn;230;NSM;;;;;N;;;;;
+0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;;;;
+0597;HEBREW ACCENT REVIA;Mn;230;NSM;;;;;N;;;;;
+0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;;;;
+0599;HEBREW ACCENT PASHTA;Mn;230;NSM;;;;;N;;;;;
+059A;HEBREW ACCENT YETIV;Mn;222;NSM;;;;;N;;;;;
+059B;HEBREW ACCENT TEVIR;Mn;220;NSM;;;;;N;;;;;
+059C;HEBREW ACCENT GERESH;Mn;230;NSM;;;;;N;;;;;
+059D;HEBREW ACCENT GERESH MUQDAM;Mn;230;NSM;;;;;N;;;;;
+059E;HEBREW ACCENT GERSHAYIM;Mn;230;NSM;;;;;N;;;;;
+059F;HEBREW ACCENT QARNEY PARA;Mn;230;NSM;;;;;N;;;;;
+05A0;HEBREW ACCENT TELISHA GEDOLA;Mn;230;NSM;;;;;N;;;;;
+05A1;HEBREW ACCENT PAZER;Mn;230;NSM;;;;;N;;;;;
+05A2;HEBREW ACCENT ATNAH HAFUKH;Mn;220;NSM;;;;;N;;;;;
+05A3;HEBREW ACCENT MUNAH;Mn;220;NSM;;;;;N;;;;;
+05A4;HEBREW ACCENT MAHAPAKH;Mn;220;NSM;;;;;N;;;;;
+05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;;;;
+05A6;HEBREW ACCENT MERKHA KEFULA;Mn;220;NSM;;;;;N;;;;;
+05A7;HEBREW ACCENT DARGA;Mn;220;NSM;;;;;N;;;;;
+05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;;;;
+05A9;HEBREW ACCENT TELISHA QETANA;Mn;230;NSM;;;;;N;;;;;
+05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;;;;
+05AB;HEBREW ACCENT OLE;Mn;230;NSM;;;;;N;;;;;
+05AC;HEBREW ACCENT ILUY;Mn;230;NSM;;;;;N;;;;;
+05AD;HEBREW ACCENT DEHI;Mn;222;NSM;;;;;N;;;;;
+05AE;HEBREW ACCENT ZINOR;Mn;228;NSM;;;;;N;;;;;
+05AF;HEBREW MARK MASORA CIRCLE;Mn;230;NSM;;;;;N;;;;;
+05B0;HEBREW POINT SHEVA;Mn;10;NSM;;;;;N;;;;;
+05B1;HEBREW POINT HATAF SEGOL;Mn;11;NSM;;;;;N;;;;;
+05B2;HEBREW POINT HATAF PATAH;Mn;12;NSM;;;;;N;;;;;
+05B3;HEBREW POINT HATAF QAMATS;Mn;13;NSM;;;;;N;;;;;
+05B4;HEBREW POINT HIRIQ;Mn;14;NSM;;;;;N;;;;;
+05B5;HEBREW POINT TSERE;Mn;15;NSM;;;;;N;;;;;
+05B6;HEBREW POINT SEGOL;Mn;16;NSM;;;;;N;;;;;
+05B7;HEBREW POINT PATAH;Mn;17;NSM;;;;;N;;;;;
+05B8;HEBREW POINT QAMATS;Mn;18;NSM;;;;;N;;;;;
+05B9;HEBREW POINT HOLAM;Mn;19;NSM;;;;;N;;;;;
+05BA;HEBREW POINT HOLAM HASER FOR VAV;Mn;19;NSM;;;;;N;;;;;
+05BB;HEBREW POINT QUBUTS;Mn;20;NSM;;;;;N;;;;;
+05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;;;;
+05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;;;;
+05BE;HEBREW PUNCTUATION MAQAF;Pd;0;R;;;;;N;;;;;
+05BF;HEBREW POINT RAFE;Mn;23;NSM;;;;;N;;;;;
+05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;;;;
+05C1;HEBREW POINT SHIN DOT;Mn;24;NSM;;;;;N;;;;;
+05C2;HEBREW POINT SIN DOT;Mn;25;NSM;;;;;N;;;;;
+05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;;;;
+05C4;HEBREW MARK UPPER DOT;Mn;230;NSM;;;;;N;;;;;
+05C5;HEBREW MARK LOWER DOT;Mn;220;NSM;;;;;N;;;;;
+05C6;HEBREW PUNCTUATION NUN HAFUKHA;Po;0;R;;;;;N;;;;;
+05C7;HEBREW POINT QAMATS QATAN;Mn;18;NSM;;;;;N;;;;;
+05D0;HEBREW LETTER ALEF;Lo;0;R;;;;;N;;;;;
+05D1;HEBREW LETTER BET;Lo;0;R;;;;;N;;;;;
+05D2;HEBREW LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+05D3;HEBREW LETTER DALET;Lo;0;R;;;;;N;;;;;
+05D4;HEBREW LETTER HE;Lo;0;R;;;;;N;;;;;
+05D5;HEBREW LETTER VAV;Lo;0;R;;;;;N;;;;;
+05D6;HEBREW LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+05D7;HEBREW LETTER HET;Lo;0;R;;;;;N;;;;;
+05D8;HEBREW LETTER TET;Lo;0;R;;;;;N;;;;;
+05D9;HEBREW LETTER YOD;Lo;0;R;;;;;N;;;;;
+05DA;HEBREW LETTER FINAL KAF;Lo;0;R;;;;;N;;;;;
+05DB;HEBREW LETTER KAF;Lo;0;R;;;;;N;;;;;
+05DC;HEBREW LETTER LAMED;Lo;0;R;;;;;N;;;;;
+05DD;HEBREW LETTER FINAL MEM;Lo;0;R;;;;;N;;;;;
+05DE;HEBREW LETTER MEM;Lo;0;R;;;;;N;;;;;
+05DF;HEBREW LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;
+05E0;HEBREW LETTER NUN;Lo;0;R;;;;;N;;;;;
+05E1;HEBREW LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+05E2;HEBREW LETTER AYIN;Lo;0;R;;;;;N;;;;;
+05E3;HEBREW LETTER FINAL PE;Lo;0;R;;;;;N;;;;;
+05E4;HEBREW LETTER PE;Lo;0;R;;;;;N;;;;;
+05E5;HEBREW LETTER FINAL TSADI;Lo;0;R;;;;;N;;;;;
+05E6;HEBREW LETTER TSADI;Lo;0;R;;;;;N;;;;;
+05E7;HEBREW LETTER QOF;Lo;0;R;;;;;N;;;;;
+05E8;HEBREW LETTER RESH;Lo;0;R;;;;;N;;;;;
+05E9;HEBREW LETTER SHIN;Lo;0;R;;;;;N;;;;;
+05EA;HEBREW LETTER TAV;Lo;0;R;;;;;N;;;;;
+05F0;HEBREW LIGATURE YIDDISH DOUBLE VAV;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE VAV;;;;
+05F1;HEBREW LIGATURE YIDDISH VAV YOD;Lo;0;R;;;;;N;HEBREW LETTER VAV YOD;;;;
+05F2;HEBREW LIGATURE YIDDISH DOUBLE YOD;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE YOD;;;;
+05F3;HEBREW PUNCTUATION GERESH;Po;0;R;;;;;N;;;;;
+05F4;HEBREW PUNCTUATION GERSHAYIM;Po;0;R;;;;;N;;;;;
+0600;ARABIC NUMBER SIGN;Cf;0;AN;;;;;N;;;;;
+0601;ARABIC SIGN SANAH;Cf;0;AN;;;;;N;;;;;
+0602;ARABIC FOOTNOTE MARKER;Cf;0;AN;;;;;N;;;;;
+0603;ARABIC SIGN SAFHA;Cf;0;AN;;;;;N;;;;;
+0604;ARABIC SIGN SAMVAT;Cf;0;AN;;;;;N;;;;;
+0605;ARABIC NUMBER MARK ABOVE;Cf;0;AN;;;;;N;;;;;
+0606;ARABIC-INDIC CUBE ROOT;Sm;0;ON;;;;;N;;;;;
+0607;ARABIC-INDIC FOURTH ROOT;Sm;0;ON;;;;;N;;;;;
+0608;ARABIC RAY;Sm;0;AL;;;;;N;;;;;
+0609;ARABIC-INDIC PER MILLE SIGN;Po;0;ET;;;;;N;;;;;
+060A;ARABIC-INDIC PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;;
+060B;AFGHANI SIGN;Sc;0;AL;;;;;N;;;;;
+060C;ARABIC COMMA;Po;0;CS;;;;;N;;;;;
+060D;ARABIC DATE SEPARATOR;Po;0;AL;;;;;N;;;;;
+060E;ARABIC POETIC VERSE SIGN;So;0;ON;;;;;N;;;;;
+060F;ARABIC SIGN MISRA;So;0;ON;;;;;N;;;;;
+0610;ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM;Mn;230;NSM;;;;;N;;;;;
+0611;ARABIC SIGN ALAYHE ASSALLAM;Mn;230;NSM;;;;;N;;;;;
+0612;ARABIC SIGN RAHMATULLAH ALAYHE;Mn;230;NSM;;;;;N;;;;;
+0613;ARABIC SIGN RADI ALLAHOU ANHU;Mn;230;NSM;;;;;N;;;;;
+0614;ARABIC SIGN TAKHALLUS;Mn;230;NSM;;;;;N;;;;;
+0615;ARABIC SMALL HIGH TAH;Mn;230;NSM;;;;;N;;;;;
+0616;ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH;Mn;230;NSM;;;;;N;;;;;
+0617;ARABIC SMALL HIGH ZAIN;Mn;230;NSM;;;;;N;;;;;
+0618;ARABIC SMALL FATHA;Mn;30;NSM;;;;;N;;;;;
+0619;ARABIC SMALL DAMMA;Mn;31;NSM;;;;;N;;;;;
+061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;;
+061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;;
+061C;ARABIC LETTER MARK;Cf;0;AL;;;;;N;;;;;
+061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;;
+061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;;
+0620;ARABIC LETTER KASHMIRI YEH;Lo;0;AL;;;;;N;;;;;
+0621;ARABIC LETTER HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH;;;;
+0622;ARABIC LETTER ALEF WITH MADDA ABOVE;Lo;0;AL;0627 0653;;;;N;ARABIC LETTER MADDAH ON ALEF;;;;
+0623;ARABIC LETTER ALEF WITH HAMZA ABOVE;Lo;0;AL;0627 0654;;;;N;ARABIC LETTER HAMZAH ON ALEF;;;;
+0624;ARABIC LETTER WAW WITH HAMZA ABOVE;Lo;0;AL;0648 0654;;;;N;ARABIC LETTER HAMZAH ON WAW;;;;
+0625;ARABIC LETTER ALEF WITH HAMZA BELOW;Lo;0;AL;0627 0655;;;;N;ARABIC LETTER HAMZAH UNDER ALEF;;;;
+0626;ARABIC LETTER YEH WITH HAMZA ABOVE;Lo;0;AL;064A 0654;;;;N;ARABIC LETTER HAMZAH ON YA;;;;
+0627;ARABIC LETTER ALEF;Lo;0;AL;;;;;N;;;;;
+0628;ARABIC LETTER BEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA;;;;
+0629;ARABIC LETTER TEH MARBUTA;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH;;;;
+062A;ARABIC LETTER TEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA;;;;
+062B;ARABIC LETTER THEH;Lo;0;AL;;;;;N;ARABIC LETTER THAA;;;;
+062C;ARABIC LETTER JEEM;Lo;0;AL;;;;;N;;;;;
+062D;ARABIC LETTER HAH;Lo;0;AL;;;;;N;ARABIC LETTER HAA;;;;
+062E;ARABIC LETTER KHAH;Lo;0;AL;;;;;N;ARABIC LETTER KHAA;;;;
+062F;ARABIC LETTER DAL;Lo;0;AL;;;;;N;;;;;
+0630;ARABIC LETTER THAL;Lo;0;AL;;;;;N;;;;;
+0631;ARABIC LETTER REH;Lo;0;AL;;;;;N;ARABIC LETTER RA;;;;
+0632;ARABIC LETTER ZAIN;Lo;0;AL;;;;;N;;;;;
+0633;ARABIC LETTER SEEN;Lo;0;AL;;;;;N;;;;;
+0634;ARABIC LETTER SHEEN;Lo;0;AL;;;;;N;;;;;
+0635;ARABIC LETTER SAD;Lo;0;AL;;;;;N;;;;;
+0636;ARABIC LETTER DAD;Lo;0;AL;;;;;N;;;;;
+0637;ARABIC LETTER TAH;Lo;0;AL;;;;;N;;;;;
+0638;ARABIC LETTER ZAH;Lo;0;AL;;;;;N;ARABIC LETTER DHAH;;;;
+0639;ARABIC LETTER AIN;Lo;0;AL;;;;;N;;;;;
+063A;ARABIC LETTER GHAIN;Lo;0;AL;;;;;N;;;;;
+063B;ARABIC LETTER KEHEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+063C;ARABIC LETTER KEHEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+063D;ARABIC LETTER FARSI YEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
+063E;ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+063F;ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0640;ARABIC TATWEEL;Lm;0;AL;;;;;N;;;;;
+0641;ARABIC LETTER FEH;Lo;0;AL;;;;;N;ARABIC LETTER FA;;;;
+0642;ARABIC LETTER QAF;Lo;0;AL;;;;;N;;;;;
+0643;ARABIC LETTER KAF;Lo;0;AL;;;;;N;ARABIC LETTER CAF;;;;
+0644;ARABIC LETTER LAM;Lo;0;AL;;;;;N;;;;;
+0645;ARABIC LETTER MEEM;Lo;0;AL;;;;;N;;;;;
+0646;ARABIC LETTER NOON;Lo;0;AL;;;;;N;;;;;
+0647;ARABIC LETTER HEH;Lo;0;AL;;;;;N;ARABIC LETTER HA;;;;
+0648;ARABIC LETTER WAW;Lo;0;AL;;;;;N;;;;;
+0649;ARABIC LETTER ALEF MAKSURA;Lo;0;AL;;;;;N;ARABIC LETTER ALEF MAQSURAH;;;;
+064A;ARABIC LETTER YEH;Lo;0;AL;;;;;N;ARABIC LETTER YA;;;;
+064B;ARABIC FATHATAN;Mn;27;NSM;;;;;N;;;;;
+064C;ARABIC DAMMATAN;Mn;28;NSM;;;;;N;;;;;
+064D;ARABIC KASRATAN;Mn;29;NSM;;;;;N;;;;;
+064E;ARABIC FATHA;Mn;30;NSM;;;;;N;ARABIC FATHAH;;;;
+064F;ARABIC DAMMA;Mn;31;NSM;;;;;N;ARABIC DAMMAH;;;;
+0650;ARABIC KASRA;Mn;32;NSM;;;;;N;ARABIC KASRAH;;;;
+0651;ARABIC SHADDA;Mn;33;NSM;;;;;N;ARABIC SHADDAH;;;;
+0652;ARABIC SUKUN;Mn;34;NSM;;;;;N;;;;;
+0653;ARABIC MADDAH ABOVE;Mn;230;NSM;;;;;N;;;;;
+0654;ARABIC HAMZA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0655;ARABIC HAMZA BELOW;Mn;220;NSM;;;;;N;;;;;
+0656;ARABIC SUBSCRIPT ALEF;Mn;220;NSM;;;;;N;;;;;
+0657;ARABIC INVERTED DAMMA;Mn;230;NSM;;;;;N;;;;;
+0658;ARABIC MARK NOON GHUNNA;Mn;230;NSM;;;;;N;;;;;
+0659;ARABIC ZWARAKAY;Mn;230;NSM;;;;;N;;;;;
+065A;ARABIC VOWEL SIGN SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;;
+065B;ARABIC VOWEL SIGN INVERTED SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;;
+065C;ARABIC VOWEL SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+065D;ARABIC REVERSED DAMMA;Mn;230;NSM;;;;;N;;;;;
+065E;ARABIC FATHA WITH TWO DOTS;Mn;230;NSM;;;;;N;;;;;
+065F;ARABIC WAVY HAMZA BELOW;Mn;220;NSM;;;;;N;;;;;
+0660;ARABIC-INDIC DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;;
+0661;ARABIC-INDIC DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;;
+0662;ARABIC-INDIC DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;;
+0663;ARABIC-INDIC DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;;
+0664;ARABIC-INDIC DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;;
+0665;ARABIC-INDIC DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;;
+0666;ARABIC-INDIC DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;;
+0667;ARABIC-INDIC DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;;
+0668;ARABIC-INDIC DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;;
+0669;ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;;
+066A;ARABIC PERCENT SIGN;Po;0;ET;;;;;N;;;;;
+066B;ARABIC DECIMAL SEPARATOR;Po;0;AN;;;;;N;;;;;
+066C;ARABIC THOUSANDS SEPARATOR;Po;0;AN;;;;;N;;;;;
+066D;ARABIC FIVE POINTED STAR;Po;0;AL;;;;;N;;;;;
+066E;ARABIC LETTER DOTLESS BEH;Lo;0;AL;;;;;N;;;;;
+066F;ARABIC LETTER DOTLESS QAF;Lo;0;AL;;;;;N;;;;;
+0670;ARABIC LETTER SUPERSCRIPT ALEF;Mn;35;NSM;;;;;N;ARABIC ALEF ABOVE;;;;
+0671;ARABIC LETTER ALEF WASLA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAT WASL ON ALEF;;;;
+0672;ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH ON ALEF;;;;
+0673;ARABIC LETTER ALEF WITH WAVY HAMZA BELOW;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH UNDER ALEF;;;;
+0674;ARABIC LETTER HIGH HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HIGH HAMZAH;;;;
+0675;ARABIC LETTER HIGH HAMZA ALEF;Lo;0;AL;<compat> 0627 0674;;;;N;ARABIC LETTER HIGH HAMZAH ALEF;;;;
+0676;ARABIC LETTER HIGH HAMZA WAW;Lo;0;AL;<compat> 0648 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW;;;;
+0677;ARABIC LETTER U WITH HAMZA ABOVE;Lo;0;AL;<compat> 06C7 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW WITH DAMMAH;;;;
+0678;ARABIC LETTER HIGH HAMZA YEH;Lo;0;AL;<compat> 064A 0674;;;;N;ARABIC LETTER HIGH HAMZAH YA;;;;
+0679;ARABIC LETTER TTEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH SMALL TAH;;;;
+067A;ARABIC LETTER TTEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH TWO DOTS VERTICAL ABOVE;;;;
+067B;ARABIC LETTER BEEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH TWO DOTS VERTICAL BELOW;;;;
+067C;ARABIC LETTER TEH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH RING;;;;
+067D;ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS ABOVE DOWNWARD;;;;
+067E;ARABIC LETTER PEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS BELOW;;;;
+067F;ARABIC LETTER TEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH FOUR DOTS ABOVE;;;;
+0680;ARABIC LETTER BEHEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH FOUR DOTS BELOW;;;;
+0681;ARABIC LETTER HAH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH ON HAA;;;;
+0682;ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH TWO DOTS VERTICAL ABOVE;;;;
+0683;ARABIC LETTER NYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS;;;;
+0684;ARABIC LETTER DYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS VERTICAL;;;;
+0685;ARABIC LETTER HAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH THREE DOTS ABOVE;;;;
+0686;ARABIC LETTER TCHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE THREE DOTS DOWNWARD;;;;
+0687;ARABIC LETTER TCHEHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE FOUR DOTS;;;;
+0688;ARABIC LETTER DDAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH SMALL TAH;;;;
+0689;ARABIC LETTER DAL WITH RING;Lo;0;AL;;;;;N;;;;;
+068A;ARABIC LETTER DAL WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+068B;ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;;
+068C;ARABIC LETTER DAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS ABOVE;;;;
+068D;ARABIC LETTER DDAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS BELOW;;;;
+068E;ARABIC LETTER DUL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE;;;;
+068F;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARD;;;;
+0690;ARABIC LETTER DAL WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0691;ARABIC LETTER RREH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL TAH;;;;
+0692;ARABIC LETTER REH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V;;;;
+0693;ARABIC LETTER REH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH RING;;;;
+0694;ARABIC LETTER REH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW;;;;
+0695;ARABIC LETTER REH WITH SMALL V BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V BELOW;;;;
+0696;ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW AND DOT ABOVE;;;;
+0697;ARABIC LETTER REH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH TWO DOTS ABOVE;;;;
+0698;ARABIC LETTER JEH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH THREE DOTS ABOVE;;;;
+0699;ARABIC LETTER REH WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH FOUR DOTS ABOVE;;;;
+069A;ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+069B;ARABIC LETTER SEEN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+069C;ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+069D;ARABIC LETTER SAD WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+069E;ARABIC LETTER SAD WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+069F;ARABIC LETTER TAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06A0;ARABIC LETTER AIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06A1;ARABIC LETTER DOTLESS FEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS FA;;;;
+06A2;ARABIC LETTER FEH WITH DOT MOVED BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT MOVED BELOW;;;;
+06A3;ARABIC LETTER FEH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT BELOW;;;;
+06A4;ARABIC LETTER VEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS ABOVE;;;;
+06A5;ARABIC LETTER FEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS BELOW;;;;
+06A6;ARABIC LETTER PEHEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH FOUR DOTS ABOVE;;;;
+06A7;ARABIC LETTER QAF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06A8;ARABIC LETTER QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06A9;ARABIC LETTER KEHEH;Lo;0;AL;;;;;N;ARABIC LETTER OPEN CAF;;;;
+06AA;ARABIC LETTER SWASH KAF;Lo;0;AL;;;;;N;ARABIC LETTER SWASH CAF;;;;
+06AB;ARABIC LETTER KAF WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH RING;;;;
+06AC;ARABIC LETTER KAF WITH DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH DOT ABOVE;;;;
+06AD;ARABIC LETTER NG;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS ABOVE;;;;
+06AE;ARABIC LETTER KAF WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS BELOW;;;;
+06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;;;;
+06B0;ARABIC LETTER GAF WITH RING;Lo;0;AL;;;;;N;;;;;
+06B1;ARABIC LETTER NGOEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS ABOVE;;;;
+06B2;ARABIC LETTER GAF WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+06B3;ARABIC LETTER GUEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS VERTICAL BELOW;;;;
+06B4;ARABIC LETTER GAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06B5;ARABIC LETTER LAM WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+06B6;ARABIC LETTER LAM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06B7;ARABIC LETTER LAM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06B8;ARABIC LETTER LAM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+06B9;ARABIC LETTER NOON WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06BA;ARABIC LETTER NOON GHUNNA;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON;;;;
+06BB;ARABIC LETTER RNOON;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON WITH SMALL TAH;;;;
+06BC;ARABIC LETTER NOON WITH RING;Lo;0;AL;;;;;N;;;;;
+06BD;ARABIC LETTER NOON WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06BE;ARABIC LETTER HEH DOACHASHMEE;Lo;0;AL;;;;;N;ARABIC LETTER KNOTTED HA;;;;
+06BF;ARABIC LETTER TCHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06C0;ARABIC LETTER HEH WITH YEH ABOVE;Lo;0;AL;06D5 0654;;;;N;ARABIC LETTER HAMZAH ON HA;;;;
+06C1;ARABIC LETTER HEH GOAL;Lo;0;AL;;;;;N;ARABIC LETTER HA GOAL;;;;
+06C2;ARABIC LETTER HEH GOAL WITH HAMZA ABOVE;Lo;0;AL;06C1 0654;;;;N;ARABIC LETTER HAMZAH ON HA GOAL;;;;
+06C3;ARABIC LETTER TEH MARBUTA GOAL;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH GOAL;;;;
+06C4;ARABIC LETTER WAW WITH RING;Lo;0;AL;;;;;N;;;;;
+06C5;ARABIC LETTER KIRGHIZ OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH BAR;;;;
+06C6;ARABIC LETTER OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH SMALL V;;;;
+06C7;ARABIC LETTER U;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH DAMMAH;;;;
+06C8;ARABIC LETTER YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH ALEF ABOVE;;;;
+06C9;ARABIC LETTER KIRGHIZ YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH INVERTED SMALL V;;;;
+06CA;ARABIC LETTER WAW WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+06CB;ARABIC LETTER VE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH THREE DOTS ABOVE;;;;
+06CC;ARABIC LETTER FARSI YEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS YA;;;;
+06CD;ARABIC LETTER YEH WITH TAIL;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TAIL;;;;
+06CE;ARABIC LETTER YEH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH SMALL V;;;;
+06CF;ARABIC LETTER WAW WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;;;;
+06D1;ARABIC LETTER YEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH THREE DOTS BELOW;;;;
+06D2;ARABIC LETTER YEH BARREE;Lo;0;AL;;;;;N;ARABIC LETTER YA BARREE;;;;
+06D3;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE;Lo;0;AL;06D2 0654;;;;N;ARABIC LETTER HAMZAH ON YA BARREE;;;;
+06D4;ARABIC FULL STOP;Po;0;AL;;;;;N;ARABIC PERIOD;;;;
+06D5;ARABIC LETTER AE;Lo;0;AL;;;;;N;;;;;
+06D6;ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;;
+06D7;ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;;
+06D8;ARABIC SMALL HIGH MEEM INITIAL FORM;Mn;230;NSM;;;;;N;;;;;
+06D9;ARABIC SMALL HIGH LAM ALEF;Mn;230;NSM;;;;;N;;;;;
+06DA;ARABIC SMALL HIGH JEEM;Mn;230;NSM;;;;;N;;;;;
+06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;;
+06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;;
+06DD;ARABIC END OF AYAH;Cf;0;AN;;;;;N;;;;;
+06DE;ARABIC START OF RUB EL HIZB;So;0;ON;;;;;N;;;;;
+06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;;
+06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;;
+06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;;
+06E2;ARABIC SMALL HIGH MEEM ISOLATED FORM;Mn;230;NSM;;;;;N;;;;;
+06E3;ARABIC SMALL LOW SEEN;Mn;220;NSM;;;;;N;;;;;
+06E4;ARABIC SMALL HIGH MADDA;Mn;230;NSM;;;;;N;;;;;
+06E5;ARABIC SMALL WAW;Lm;0;AL;;;;;N;;;;;
+06E6;ARABIC SMALL YEH;Lm;0;AL;;;;;N;;;;;
+06E7;ARABIC SMALL HIGH YEH;Mn;230;NSM;;;;;N;;;;;
+06E8;ARABIC SMALL HIGH NOON;Mn;230;NSM;;;;;N;;;;;
+06E9;ARABIC PLACE OF SAJDAH;So;0;ON;;;;;N;;;;;
+06EA;ARABIC EMPTY CENTRE LOW STOP;Mn;220;NSM;;;;;N;;;;;
+06EB;ARABIC EMPTY CENTRE HIGH STOP;Mn;230;NSM;;;;;N;;;;;
+06EC;ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE;Mn;230;NSM;;;;;N;;;;;
+06ED;ARABIC SMALL LOW MEEM;Mn;220;NSM;;;;;N;;;;;
+06EE;ARABIC LETTER DAL WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
+06EF;ARABIC LETTER REH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
+06F0;EXTENDED ARABIC-INDIC DIGIT ZERO;Nd;0;EN;;0;0;0;N;EASTERN ARABIC-INDIC DIGIT ZERO;;;;
+06F1;EXTENDED ARABIC-INDIC DIGIT ONE;Nd;0;EN;;1;1;1;N;EASTERN ARABIC-INDIC DIGIT ONE;;;;
+06F2;EXTENDED ARABIC-INDIC DIGIT TWO;Nd;0;EN;;2;2;2;N;EASTERN ARABIC-INDIC DIGIT TWO;;;;
+06F3;EXTENDED ARABIC-INDIC DIGIT THREE;Nd;0;EN;;3;3;3;N;EASTERN ARABIC-INDIC DIGIT THREE;;;;
+06F4;EXTENDED ARABIC-INDIC DIGIT FOUR;Nd;0;EN;;4;4;4;N;EASTERN ARABIC-INDIC DIGIT FOUR;;;;
+06F5;EXTENDED ARABIC-INDIC DIGIT FIVE;Nd;0;EN;;5;5;5;N;EASTERN ARABIC-INDIC DIGIT FIVE;;;;
+06F6;EXTENDED ARABIC-INDIC DIGIT SIX;Nd;0;EN;;6;6;6;N;EASTERN ARABIC-INDIC DIGIT SIX;;;;
+06F7;EXTENDED ARABIC-INDIC DIGIT SEVEN;Nd;0;EN;;7;7;7;N;EASTERN ARABIC-INDIC DIGIT SEVEN;;;;
+06F8;EXTENDED ARABIC-INDIC DIGIT EIGHT;Nd;0;EN;;8;8;8;N;EASTERN ARABIC-INDIC DIGIT EIGHT;;;;
+06F9;EXTENDED ARABIC-INDIC DIGIT NINE;Nd;0;EN;;9;9;9;N;EASTERN ARABIC-INDIC DIGIT NINE;;;;
+06FA;ARABIC LETTER SHEEN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06FB;ARABIC LETTER DAD WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06FC;ARABIC LETTER GHAIN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+06FD;ARABIC SIGN SINDHI AMPERSAND;So;0;AL;;;;;N;;;;;
+06FE;ARABIC SIGN SINDHI POSTPOSITION MEN;So;0;AL;;;;;N;;;;;
+06FF;ARABIC LETTER HEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
+0700;SYRIAC END OF PARAGRAPH;Po;0;AL;;;;;N;;;;;
+0701;SYRIAC SUPRALINEAR FULL STOP;Po;0;AL;;;;;N;;;;;
+0702;SYRIAC SUBLINEAR FULL STOP;Po;0;AL;;;;;N;;;;;
+0703;SYRIAC SUPRALINEAR COLON;Po;0;AL;;;;;N;;;;;
+0704;SYRIAC SUBLINEAR COLON;Po;0;AL;;;;;N;;;;;
+0705;SYRIAC HORIZONTAL COLON;Po;0;AL;;;;;N;;;;;
+0706;SYRIAC COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;;
+0707;SYRIAC COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;;
+0708;SYRIAC SUPRALINEAR COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;;
+0709;SYRIAC SUBLINEAR COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;;
+070A;SYRIAC CONTRACTION;Po;0;AL;;;;;N;;;;;
+070B;SYRIAC HARKLEAN OBELUS;Po;0;AL;;;;;N;;;;;
+070C;SYRIAC HARKLEAN METOBELUS;Po;0;AL;;;;;N;;;;;
+070D;SYRIAC HARKLEAN ASTERISCUS;Po;0;AL;;;;;N;;;;;
+070F;SYRIAC ABBREVIATION MARK;Cf;0;AL;;;;;N;;;;;
+0710;SYRIAC LETTER ALAPH;Lo;0;AL;;;;;N;;;;;
+0711;SYRIAC LETTER SUPERSCRIPT ALAPH;Mn;36;NSM;;;;;N;;;;;
+0712;SYRIAC LETTER BETH;Lo;0;AL;;;;;N;;;;;
+0713;SYRIAC LETTER GAMAL;Lo;0;AL;;;;;N;;;;;
+0714;SYRIAC LETTER GAMAL GARSHUNI;Lo;0;AL;;;;;N;;;;;
+0715;SYRIAC LETTER DALATH;Lo;0;AL;;;;;N;;;;;
+0716;SYRIAC LETTER DOTLESS DALATH RISH;Lo;0;AL;;;;;N;;;;;
+0717;SYRIAC LETTER HE;Lo;0;AL;;;;;N;;;;;
+0718;SYRIAC LETTER WAW;Lo;0;AL;;;;;N;;;;;
+0719;SYRIAC LETTER ZAIN;Lo;0;AL;;;;;N;;;;;
+071A;SYRIAC LETTER HETH;Lo;0;AL;;;;;N;;;;;
+071B;SYRIAC LETTER TETH;Lo;0;AL;;;;;N;;;;;
+071C;SYRIAC LETTER TETH GARSHUNI;Lo;0;AL;;;;;N;;;;;
+071D;SYRIAC LETTER YUDH;Lo;0;AL;;;;;N;;;;;
+071E;SYRIAC LETTER YUDH HE;Lo;0;AL;;;;;N;;;;;
+071F;SYRIAC LETTER KAPH;Lo;0;AL;;;;;N;;;;;
+0720;SYRIAC LETTER LAMADH;Lo;0;AL;;;;;N;;;;;
+0721;SYRIAC LETTER MIM;Lo;0;AL;;;;;N;;;;;
+0722;SYRIAC LETTER NUN;Lo;0;AL;;;;;N;;;;;
+0723;SYRIAC LETTER SEMKATH;Lo;0;AL;;;;;N;;;;;
+0724;SYRIAC LETTER FINAL SEMKATH;Lo;0;AL;;;;;N;;;;;
+0725;SYRIAC LETTER E;Lo;0;AL;;;;;N;;;;;
+0726;SYRIAC LETTER PE;Lo;0;AL;;;;;N;;;;;
+0727;SYRIAC LETTER REVERSED PE;Lo;0;AL;;;;;N;;;;;
+0728;SYRIAC LETTER SADHE;Lo;0;AL;;;;;N;;;;;
+0729;SYRIAC LETTER QAPH;Lo;0;AL;;;;;N;;;;;
+072A;SYRIAC LETTER RISH;Lo;0;AL;;;;;N;;;;;
+072B;SYRIAC LETTER SHIN;Lo;0;AL;;;;;N;;;;;
+072C;SYRIAC LETTER TAW;Lo;0;AL;;;;;N;;;;;
+072D;SYRIAC LETTER PERSIAN BHETH;Lo;0;AL;;;;;N;;;;;
+072E;SYRIAC LETTER PERSIAN GHAMAL;Lo;0;AL;;;;;N;;;;;
+072F;SYRIAC LETTER PERSIAN DHALATH;Lo;0;AL;;;;;N;;;;;
+0730;SYRIAC PTHAHA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0731;SYRIAC PTHAHA BELOW;Mn;220;NSM;;;;;N;;;;;
+0732;SYRIAC PTHAHA DOTTED;Mn;230;NSM;;;;;N;;;;;
+0733;SYRIAC ZQAPHA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0734;SYRIAC ZQAPHA BELOW;Mn;220;NSM;;;;;N;;;;;
+0735;SYRIAC ZQAPHA DOTTED;Mn;230;NSM;;;;;N;;;;;
+0736;SYRIAC RBASA ABOVE;Mn;230;NSM;;;;;N;;;;;
+0737;SYRIAC RBASA BELOW;Mn;220;NSM;;;;;N;;;;;
+0738;SYRIAC DOTTED ZLAMA HORIZONTAL;Mn;220;NSM;;;;;N;;;;;
+0739;SYRIAC DOTTED ZLAMA ANGULAR;Mn;220;NSM;;;;;N;;;;;
+073A;SYRIAC HBASA ABOVE;Mn;230;NSM;;;;;N;;;;;
+073B;SYRIAC HBASA BELOW;Mn;220;NSM;;;;;N;;;;;
+073C;SYRIAC HBASA-ESASA DOTTED;Mn;220;NSM;;;;;N;;;;;
+073D;SYRIAC ESASA ABOVE;Mn;230;NSM;;;;;N;;;;;
+073E;SYRIAC ESASA BELOW;Mn;220;NSM;;;;;N;;;;;
+073F;SYRIAC RWAHA;Mn;230;NSM;;;;;N;;;;;
+0740;SYRIAC FEMININE DOT;Mn;230;NSM;;;;;N;;;;;
+0741;SYRIAC QUSHSHAYA;Mn;230;NSM;;;;;N;;;;;
+0742;SYRIAC RUKKAKHA;Mn;220;NSM;;;;;N;;;;;
+0743;SYRIAC TWO VERTICAL DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
+0744;SYRIAC TWO VERTICAL DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+0745;SYRIAC THREE DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
+0746;SYRIAC THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+0747;SYRIAC OBLIQUE LINE ABOVE;Mn;230;NSM;;;;;N;;;;;
+0748;SYRIAC OBLIQUE LINE BELOW;Mn;220;NSM;;;;;N;;;;;
+0749;SYRIAC MUSIC;Mn;230;NSM;;;;;N;;;;;
+074A;SYRIAC BARREKH;Mn;230;NSM;;;;;N;;;;;
+074D;SYRIAC LETTER SOGDIAN ZHAIN;Lo;0;AL;;;;;N;;;;;
+074E;SYRIAC LETTER SOGDIAN KHAPH;Lo;0;AL;;;;;N;;;;;
+074F;SYRIAC LETTER SOGDIAN FE;Lo;0;AL;;;;;N;;;;;
+0750;ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW;Lo;0;AL;;;;;N;;;;;
+0751;ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0752;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
+0753;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0754;ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+0755;ARABIC LETTER BEH WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
+0756;ARABIC LETTER BEH WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+0757;ARABIC LETTER HAH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0758;ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
+0759;ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;;
+075A;ARABIC LETTER DAL WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
+075B;ARABIC LETTER REH WITH STROKE;Lo;0;AL;;;;;N;;;;;
+075C;ARABIC LETTER SEEN WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+075D;ARABIC LETTER AIN WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+075E;ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE;Lo;0;AL;;;;;N;;;;;
+075F;ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;
+0760;ARABIC LETTER FEH WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+0761;ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
+0762;ARABIC LETTER KEHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+0763;ARABIC LETTER KEHEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0764;ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
+0765;ARABIC LETTER MEEM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+0766;ARABIC LETTER MEEM WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+0767;ARABIC LETTER NOON WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+0768;ARABIC LETTER NOON WITH SMALL TAH;Lo;0;AL;;;;;N;;;;;
+0769;ARABIC LETTER NOON WITH SMALL V;Lo;0;AL;;;;;N;;;;;
+076A;ARABIC LETTER LAM WITH BAR;Lo;0;AL;;;;;N;;;;;
+076B;ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;
+076C;ARABIC LETTER REH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;
+076D;ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;
+076E;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW;Lo;0;AL;;;;;N;;;;;
+076F;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;
+0770;ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;
+0771;ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;
+0772;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;;
+0773;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
+0774;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
+0775;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
+0776;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
+0777;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;;
+0778;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
+0779;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
+077A;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
+077B;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
+077C;ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;;
+077D;ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE;Lo;0;AL;;;;;N;;;;;
+077E;ARABIC LETTER SEEN WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
+077F;ARABIC LETTER KAF WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+0780;THAANA LETTER HAA;Lo;0;AL;;;;;N;;;;;
+0781;THAANA LETTER SHAVIYANI;Lo;0;AL;;;;;N;;;;;
+0782;THAANA LETTER NOONU;Lo;0;AL;;;;;N;;;;;
+0783;THAANA LETTER RAA;Lo;0;AL;;;;;N;;;;;
+0784;THAANA LETTER BAA;Lo;0;AL;;;;;N;;;;;
+0785;THAANA LETTER LHAVIYANI;Lo;0;AL;;;;;N;;;;;
+0786;THAANA LETTER KAAFU;Lo;0;AL;;;;;N;;;;;
+0787;THAANA LETTER ALIFU;Lo;0;AL;;;;;N;;;;;
+0788;THAANA LETTER VAAVU;Lo;0;AL;;;;;N;;;;;
+0789;THAANA LETTER MEEMU;Lo;0;AL;;;;;N;;;;;
+078A;THAANA LETTER FAAFU;Lo;0;AL;;;;;N;;;;;
+078B;THAANA LETTER DHAALU;Lo;0;AL;;;;;N;;;;;
+078C;THAANA LETTER THAA;Lo;0;AL;;;;;N;;;;;
+078D;THAANA LETTER LAAMU;Lo;0;AL;;;;;N;;;;;
+078E;THAANA LETTER GAAFU;Lo;0;AL;;;;;N;;;;;
+078F;THAANA LETTER GNAVIYANI;Lo;0;AL;;;;;N;;;;;
+0790;THAANA LETTER SEENU;Lo;0;AL;;;;;N;;;;;
+0791;THAANA LETTER DAVIYANI;Lo;0;AL;;;;;N;;;;;
+0792;THAANA LETTER ZAVIYANI;Lo;0;AL;;;;;N;;;;;
+0793;THAANA LETTER TAVIYANI;Lo;0;AL;;;;;N;;;;;
+0794;THAANA LETTER YAA;Lo;0;AL;;;;;N;;;;;
+0795;THAANA LETTER PAVIYANI;Lo;0;AL;;;;;N;;;;;
+0796;THAANA LETTER JAVIYANI;Lo;0;AL;;;;;N;;;;;
+0797;THAANA LETTER CHAVIYANI;Lo;0;AL;;;;;N;;;;;
+0798;THAANA LETTER TTAA;Lo;0;AL;;;;;N;;;;;
+0799;THAANA LETTER HHAA;Lo;0;AL;;;;;N;;;;;
+079A;THAANA LETTER KHAA;Lo;0;AL;;;;;N;;;;;
+079B;THAANA LETTER THAALU;Lo;0;AL;;;;;N;;;;;
+079C;THAANA LETTER ZAA;Lo;0;AL;;;;;N;;;;;
+079D;THAANA LETTER SHEENU;Lo;0;AL;;;;;N;;;;;
+079E;THAANA LETTER SAADHU;Lo;0;AL;;;;;N;;;;;
+079F;THAANA LETTER DAADHU;Lo;0;AL;;;;;N;;;;;
+07A0;THAANA LETTER TO;Lo;0;AL;;;;;N;;;;;
+07A1;THAANA LETTER ZO;Lo;0;AL;;;;;N;;;;;
+07A2;THAANA LETTER AINU;Lo;0;AL;;;;;N;;;;;
+07A3;THAANA LETTER GHAINU;Lo;0;AL;;;;;N;;;;;
+07A4;THAANA LETTER QAAFU;Lo;0;AL;;;;;N;;;;;
+07A5;THAANA LETTER WAAVU;Lo;0;AL;;;;;N;;;;;
+07A6;THAANA ABAFILI;Mn;0;NSM;;;;;N;;;;;
+07A7;THAANA AABAAFILI;Mn;0;NSM;;;;;N;;;;;
+07A8;THAANA IBIFILI;Mn;0;NSM;;;;;N;;;;;
+07A9;THAANA EEBEEFILI;Mn;0;NSM;;;;;N;;;;;
+07AA;THAANA UBUFILI;Mn;0;NSM;;;;;N;;;;;
+07AB;THAANA OOBOOFILI;Mn;0;NSM;;;;;N;;;;;
+07AC;THAANA EBEFILI;Mn;0;NSM;;;;;N;;;;;
+07AD;THAANA EYBEYFILI;Mn;0;NSM;;;;;N;;;;;
+07AE;THAANA OBOFILI;Mn;0;NSM;;;;;N;;;;;
+07AF;THAANA OABOAFILI;Mn;0;NSM;;;;;N;;;;;
+07B0;THAANA SUKUN;Mn;0;NSM;;;;;N;;;;;
+07B1;THAANA LETTER NAA;Lo;0;AL;;;;;N;;;;;
+07C0;NKO DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;;
+07C1;NKO DIGIT ONE;Nd;0;R;;1;1;1;N;;;;;
+07C2;NKO DIGIT TWO;Nd;0;R;;2;2;2;N;;;;;
+07C3;NKO DIGIT THREE;Nd;0;R;;3;3;3;N;;;;;
+07C4;NKO DIGIT FOUR;Nd;0;R;;4;4;4;N;;;;;
+07C5;NKO DIGIT FIVE;Nd;0;R;;5;5;5;N;;;;;
+07C6;NKO DIGIT SIX;Nd;0;R;;6;6;6;N;;;;;
+07C7;NKO DIGIT SEVEN;Nd;0;R;;7;7;7;N;;;;;
+07C8;NKO DIGIT EIGHT;Nd;0;R;;8;8;8;N;;;;;
+07C9;NKO DIGIT NINE;Nd;0;R;;9;9;9;N;;;;;
+07CA;NKO LETTER A;Lo;0;R;;;;;N;;;;;
+07CB;NKO LETTER EE;Lo;0;R;;;;;N;;;;;
+07CC;NKO LETTER I;Lo;0;R;;;;;N;;;;;
+07CD;NKO LETTER E;Lo;0;R;;;;;N;;;;;
+07CE;NKO LETTER U;Lo;0;R;;;;;N;;;;;
+07CF;NKO LETTER OO;Lo;0;R;;;;;N;;;;;
+07D0;NKO LETTER O;Lo;0;R;;;;;N;;;;;
+07D1;NKO LETTER DAGBASINNA;Lo;0;R;;;;;N;;;;;
+07D2;NKO LETTER N;Lo;0;R;;;;;N;;;;;
+07D3;NKO LETTER BA;Lo;0;R;;;;;N;;;;;
+07D4;NKO LETTER PA;Lo;0;R;;;;;N;;;;;
+07D5;NKO LETTER TA;Lo;0;R;;;;;N;;;;;
+07D6;NKO LETTER JA;Lo;0;R;;;;;N;;;;;
+07D7;NKO LETTER CHA;Lo;0;R;;;;;N;;;;;
+07D8;NKO LETTER DA;Lo;0;R;;;;;N;;;;;
+07D9;NKO LETTER RA;Lo;0;R;;;;;N;;;;;
+07DA;NKO LETTER RRA;Lo;0;R;;;;;N;;;;;
+07DB;NKO LETTER SA;Lo;0;R;;;;;N;;;;;
+07DC;NKO LETTER GBA;Lo;0;R;;;;;N;;;;;
+07DD;NKO LETTER FA;Lo;0;R;;;;;N;;;;;
+07DE;NKO LETTER KA;Lo;0;R;;;;;N;;;;;
+07DF;NKO LETTER LA;Lo;0;R;;;;;N;;;;;
+07E0;NKO LETTER NA WOLOSO;Lo;0;R;;;;;N;;;;;
+07E1;NKO LETTER MA;Lo;0;R;;;;;N;;;;;
+07E2;NKO LETTER NYA;Lo;0;R;;;;;N;;;;;
+07E3;NKO LETTER NA;Lo;0;R;;;;;N;;;;;
+07E4;NKO LETTER HA;Lo;0;R;;;;;N;;;;;
+07E5;NKO LETTER WA;Lo;0;R;;;;;N;;;;;
+07E6;NKO LETTER YA;Lo;0;R;;;;;N;;;;;
+07E7;NKO LETTER NYA WOLOSO;Lo;0;R;;;;;N;;;;;
+07E8;NKO LETTER JONA JA;Lo;0;R;;;;;N;;;;;
+07E9;NKO LETTER JONA CHA;Lo;0;R;;;;;N;;;;;
+07EA;NKO LETTER JONA RA;Lo;0;R;;;;;N;;;;;
+07EB;NKO COMBINING SHORT HIGH TONE;Mn;230;NSM;;;;;N;;;;;
+07EC;NKO COMBINING SHORT LOW TONE;Mn;230;NSM;;;;;N;;;;;
+07ED;NKO COMBINING SHORT RISING TONE;Mn;230;NSM;;;;;N;;;;;
+07EE;NKO COMBINING LONG DESCENDING TONE;Mn;230;NSM;;;;;N;;;;;
+07EF;NKO COMBINING LONG HIGH TONE;Mn;230;NSM;;;;;N;;;;;
+07F0;NKO COMBINING LONG LOW TONE;Mn;230;NSM;;;;;N;;;;;
+07F1;NKO COMBINING LONG RISING TONE;Mn;230;NSM;;;;;N;;;;;
+07F2;NKO COMBINING NASALIZATION MARK;Mn;220;NSM;;;;;N;;;;;
+07F3;NKO COMBINING DOUBLE DOT ABOVE;Mn;230;NSM;;;;;N;;;;;
+07F4;NKO HIGH TONE APOSTROPHE;Lm;0;R;;;;;N;;;;;
+07F5;NKO LOW TONE APOSTROPHE;Lm;0;R;;;;;N;;;;;
+07F6;NKO SYMBOL OO DENNEN;So;0;ON;;;;;N;;;;;
+07F7;NKO SYMBOL GBAKURUNEN;Po;0;ON;;;;;N;;;;;
+07F8;NKO COMMA;Po;0;ON;;;;;N;;;;;
+07F9;NKO EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+07FA;NKO LAJANYALAN;Lm;0;R;;;;;N;;;;;
+0800;SAMARITAN LETTER ALAF;Lo;0;R;;;;;N;;;;;
+0801;SAMARITAN LETTER BIT;Lo;0;R;;;;;N;;;;;
+0802;SAMARITAN LETTER GAMAN;Lo;0;R;;;;;N;;;;;
+0803;SAMARITAN LETTER DALAT;Lo;0;R;;;;;N;;;;;
+0804;SAMARITAN LETTER IY;Lo;0;R;;;;;N;;;;;
+0805;SAMARITAN LETTER BAA;Lo;0;R;;;;;N;;;;;
+0806;SAMARITAN LETTER ZEN;Lo;0;R;;;;;N;;;;;
+0807;SAMARITAN LETTER IT;Lo;0;R;;;;;N;;;;;
+0808;SAMARITAN LETTER TIT;Lo;0;R;;;;;N;;;;;
+0809;SAMARITAN LETTER YUT;Lo;0;R;;;;;N;;;;;
+080A;SAMARITAN LETTER KAAF;Lo;0;R;;;;;N;;;;;
+080B;SAMARITAN LETTER LABAT;Lo;0;R;;;;;N;;;;;
+080C;SAMARITAN LETTER MIM;Lo;0;R;;;;;N;;;;;
+080D;SAMARITAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+080E;SAMARITAN LETTER SINGAAT;Lo;0;R;;;;;N;;;;;
+080F;SAMARITAN LETTER IN;Lo;0;R;;;;;N;;;;;
+0810;SAMARITAN LETTER FI;Lo;0;R;;;;;N;;;;;
+0811;SAMARITAN LETTER TSAADIY;Lo;0;R;;;;;N;;;;;
+0812;SAMARITAN LETTER QUF;Lo;0;R;;;;;N;;;;;
+0813;SAMARITAN LETTER RISH;Lo;0;R;;;;;N;;;;;
+0814;SAMARITAN LETTER SHAN;Lo;0;R;;;;;N;;;;;
+0815;SAMARITAN LETTER TAAF;Lo;0;R;;;;;N;;;;;
+0816;SAMARITAN MARK IN;Mn;230;NSM;;;;;N;;;;;
+0817;SAMARITAN MARK IN-ALAF;Mn;230;NSM;;;;;N;;;;;
+0818;SAMARITAN MARK OCCLUSION;Mn;230;NSM;;;;;N;;;;;
+0819;SAMARITAN MARK DAGESH;Mn;230;NSM;;;;;N;;;;;
+081A;SAMARITAN MODIFIER LETTER EPENTHETIC YUT;Lm;0;R;;;;;N;;;;;
+081B;SAMARITAN MARK EPENTHETIC YUT;Mn;230;NSM;;;;;N;;;;;
+081C;SAMARITAN VOWEL SIGN LONG E;Mn;230;NSM;;;;;N;;;;;
+081D;SAMARITAN VOWEL SIGN E;Mn;230;NSM;;;;;N;;;;;
+081E;SAMARITAN VOWEL SIGN OVERLONG AA;Mn;230;NSM;;;;;N;;;;;
+081F;SAMARITAN VOWEL SIGN LONG AA;Mn;230;NSM;;;;;N;;;;;
+0820;SAMARITAN VOWEL SIGN AA;Mn;230;NSM;;;;;N;;;;;
+0821;SAMARITAN VOWEL SIGN OVERLONG A;Mn;230;NSM;;;;;N;;;;;
+0822;SAMARITAN VOWEL SIGN LONG A;Mn;230;NSM;;;;;N;;;;;
+0823;SAMARITAN VOWEL SIGN A;Mn;230;NSM;;;;;N;;;;;
+0824;SAMARITAN MODIFIER LETTER SHORT A;Lm;0;R;;;;;N;;;;;
+0825;SAMARITAN VOWEL SIGN SHORT A;Mn;230;NSM;;;;;N;;;;;
+0826;SAMARITAN VOWEL SIGN LONG U;Mn;230;NSM;;;;;N;;;;;
+0827;SAMARITAN VOWEL SIGN U;Mn;230;NSM;;;;;N;;;;;
+0828;SAMARITAN MODIFIER LETTER I;Lm;0;R;;;;;N;;;;;
+0829;SAMARITAN VOWEL SIGN LONG I;Mn;230;NSM;;;;;N;;;;;
+082A;SAMARITAN VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;;
+082B;SAMARITAN VOWEL SIGN O;Mn;230;NSM;;;;;N;;;;;
+082C;SAMARITAN VOWEL SIGN SUKUN;Mn;230;NSM;;;;;N;;;;;
+082D;SAMARITAN MARK NEQUDAA;Mn;230;NSM;;;;;N;;;;;
+0830;SAMARITAN PUNCTUATION NEQUDAA;Po;0;R;;;;;N;;;;;
+0831;SAMARITAN PUNCTUATION AFSAAQ;Po;0;R;;;;;N;;;;;
+0832;SAMARITAN PUNCTUATION ANGED;Po;0;R;;;;;N;;;;;
+0833;SAMARITAN PUNCTUATION BAU;Po;0;R;;;;;N;;;;;
+0834;SAMARITAN PUNCTUATION ATMAAU;Po;0;R;;;;;N;;;;;
+0835;SAMARITAN PUNCTUATION SHIYYAALAA;Po;0;R;;;;;N;;;;;
+0836;SAMARITAN ABBREVIATION MARK;Po;0;R;;;;;N;;;;;
+0837;SAMARITAN PUNCTUATION MELODIC QITSA;Po;0;R;;;;;N;;;;;
+0838;SAMARITAN PUNCTUATION ZIQAA;Po;0;R;;;;;N;;;;;
+0839;SAMARITAN PUNCTUATION QITSA;Po;0;R;;;;;N;;;;;
+083A;SAMARITAN PUNCTUATION ZAEF;Po;0;R;;;;;N;;;;;
+083B;SAMARITAN PUNCTUATION TURU;Po;0;R;;;;;N;;;;;
+083C;SAMARITAN PUNCTUATION ARKAANU;Po;0;R;;;;;N;;;;;
+083D;SAMARITAN PUNCTUATION SOF MASHFAAT;Po;0;R;;;;;N;;;;;
+083E;SAMARITAN PUNCTUATION ANNAAU;Po;0;R;;;;;N;;;;;
+0840;MANDAIC LETTER HALQA;Lo;0;R;;;;;N;;;;;
+0841;MANDAIC LETTER AB;Lo;0;R;;;;;N;;;;;
+0842;MANDAIC LETTER AG;Lo;0;R;;;;;N;;;;;
+0843;MANDAIC LETTER AD;Lo;0;R;;;;;N;;;;;
+0844;MANDAIC LETTER AH;Lo;0;R;;;;;N;;;;;
+0845;MANDAIC LETTER USHENNA;Lo;0;R;;;;;N;;;;;
+0846;MANDAIC LETTER AZ;Lo;0;R;;;;;N;;;;;
+0847;MANDAIC LETTER IT;Lo;0;R;;;;;N;;;;;
+0848;MANDAIC LETTER ATT;Lo;0;R;;;;;N;;;;;
+0849;MANDAIC LETTER AKSA;Lo;0;R;;;;;N;;;;;
+084A;MANDAIC LETTER AK;Lo;0;R;;;;;N;;;;;
+084B;MANDAIC LETTER AL;Lo;0;R;;;;;N;;;;;
+084C;MANDAIC LETTER AM;Lo;0;R;;;;;N;;;;;
+084D;MANDAIC LETTER AN;Lo;0;R;;;;;N;;;;;
+084E;MANDAIC LETTER AS;Lo;0;R;;;;;N;;;;;
+084F;MANDAIC LETTER IN;Lo;0;R;;;;;N;;;;;
+0850;MANDAIC LETTER AP;Lo;0;R;;;;;N;;;;;
+0851;MANDAIC LETTER ASZ;Lo;0;R;;;;;N;;;;;
+0852;MANDAIC LETTER AQ;Lo;0;R;;;;;N;;;;;
+0853;MANDAIC LETTER AR;Lo;0;R;;;;;N;;;;;
+0854;MANDAIC LETTER ASH;Lo;0;R;;;;;N;;;;;
+0855;MANDAIC LETTER AT;Lo;0;R;;;;;N;;;;;
+0856;MANDAIC LETTER DUSHENNA;Lo;0;R;;;;;N;;;;;
+0857;MANDAIC LETTER KAD;Lo;0;R;;;;;N;;;;;
+0858;MANDAIC LETTER AIN;Lo;0;R;;;;;N;;;;;
+0859;MANDAIC AFFRICATION MARK;Mn;220;NSM;;;;;N;;;;;
+085A;MANDAIC VOCALIZATION MARK;Mn;220;NSM;;;;;N;;;;;
+085B;MANDAIC GEMINATION MARK;Mn;220;NSM;;;;;N;;;;;
+085E;MANDAIC PUNCTUATION;Po;0;R;;;;;N;;;;;
+08A0;ARABIC LETTER BEH WITH SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
+08A1;ARABIC LETTER BEH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;
+08A2;ARABIC LETTER JEEM WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+08A3;ARABIC LETTER TAH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+08A4;ARABIC LETTER FEH WITH DOT BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+08A5;ARABIC LETTER QAF WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+08A6;ARABIC LETTER LAM WITH DOUBLE BAR;Lo;0;AL;;;;;N;;;;;
+08A7;ARABIC LETTER MEEM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
+08A8;ARABIC LETTER YEH WITH TWO DOTS BELOW AND HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;
+08A9;ARABIC LETTER YEH WITH TWO DOTS BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
+08AA;ARABIC LETTER REH WITH LOOP;Lo;0;AL;;;;;N;;;;;
+08AB;ARABIC LETTER WAW WITH DOT WITHIN;Lo;0;AL;;;;;N;;;;;
+08AC;ARABIC LETTER ROHINGYA YEH;Lo;0;AL;;;;;N;;;;;
+08AD;ARABIC LETTER LOW ALEF;Lo;0;AL;;;;;N;;;;;
+08AE;ARABIC LETTER DAL WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+08AF;ARABIC LETTER SAD WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+08B0;ARABIC LETTER GAF WITH INVERTED STROKE;Lo;0;AL;;;;;N;;;;;
+08B1;ARABIC LETTER STRAIGHT WAW;Lo;0;AL;;;;;N;;;;;
+08B2;ARABIC LETTER ZAIN WITH INVERTED V ABOVE;Lo;0;AL;;;;;N;;;;;
+08B3;ARABIC LETTER AIN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
+08B4;ARABIC LETTER KAF WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
+08B6;ARABIC LETTER BEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;;
+08B7;ARABIC LETTER PEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;;
+08B8;ARABIC LETTER TEH WITH SMALL TEH ABOVE;Lo;0;AL;;;;;N;;;;;
+08B9;ARABIC LETTER REH WITH SMALL NOON ABOVE;Lo;0;AL;;;;;N;;;;;
+08BA;ARABIC LETTER YEH WITH TWO DOTS BELOW AND SMALL NOON ABOVE;Lo;0;AL;;;;;N;;;;;
+08BB;ARABIC LETTER AFRICAN FEH;Lo;0;AL;;;;;N;;;;;
+08BC;ARABIC LETTER AFRICAN QAF;Lo;0;AL;;;;;N;;;;;
+08BD;ARABIC LETTER AFRICAN NOON;Lo;0;AL;;;;;N;;;;;
+08D4;ARABIC SMALL HIGH WORD AR-RUB;Mn;230;NSM;;;;;N;;;;;
+08D5;ARABIC SMALL HIGH SAD;Mn;230;NSM;;;;;N;;;;;
+08D6;ARABIC SMALL HIGH AIN;Mn;230;NSM;;;;;N;;;;;
+08D7;ARABIC SMALL HIGH QAF;Mn;230;NSM;;;;;N;;;;;
+08D8;ARABIC SMALL HIGH NOON WITH KASRA;Mn;230;NSM;;;;;N;;;;;
+08D9;ARABIC SMALL LOW NOON WITH KASRA;Mn;230;NSM;;;;;N;;;;;
+08DA;ARABIC SMALL HIGH WORD ATH-THALATHA;Mn;230;NSM;;;;;N;;;;;
+08DB;ARABIC SMALL HIGH WORD AS-SAJDA;Mn;230;NSM;;;;;N;;;;;
+08DC;ARABIC SMALL HIGH WORD AN-NISF;Mn;230;NSM;;;;;N;;;;;
+08DD;ARABIC SMALL HIGH WORD SAKTA;Mn;230;NSM;;;;;N;;;;;
+08DE;ARABIC SMALL HIGH WORD QIF;Mn;230;NSM;;;;;N;;;;;
+08DF;ARABIC SMALL HIGH WORD WAQFA;Mn;230;NSM;;;;;N;;;;;
+08E0;ARABIC SMALL HIGH FOOTNOTE MARKER;Mn;230;NSM;;;;;N;;;;;
+08E1;ARABIC SMALL HIGH SIGN SAFHA;Mn;230;NSM;;;;;N;;;;;
+08E2;ARABIC DISPUTED END OF AYAH;Cf;0;AN;;;;;N;;;;;
+08E3;ARABIC TURNED DAMMA BELOW;Mn;220;NSM;;;;;N;;;;;
+08E4;ARABIC CURLY FATHA;Mn;230;NSM;;;;;N;;;;;
+08E5;ARABIC CURLY DAMMA;Mn;230;NSM;;;;;N;;;;;
+08E6;ARABIC CURLY KASRA;Mn;220;NSM;;;;;N;;;;;
+08E7;ARABIC CURLY FATHATAN;Mn;230;NSM;;;;;N;;;;;
+08E8;ARABIC CURLY DAMMATAN;Mn;230;NSM;;;;;N;;;;;
+08E9;ARABIC CURLY KASRATAN;Mn;220;NSM;;;;;N;;;;;
+08EA;ARABIC TONE ONE DOT ABOVE;Mn;230;NSM;;;;;N;;;;;
+08EB;ARABIC TONE TWO DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
+08EC;ARABIC TONE LOOP ABOVE;Mn;230;NSM;;;;;N;;;;;
+08ED;ARABIC TONE ONE DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+08EE;ARABIC TONE TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+08EF;ARABIC TONE LOOP BELOW;Mn;220;NSM;;;;;N;;;;;
+08F0;ARABIC OPEN FATHATAN;Mn;27;NSM;;;;;N;;;;;
+08F1;ARABIC OPEN DAMMATAN;Mn;28;NSM;;;;;N;;;;;
+08F2;ARABIC OPEN KASRATAN;Mn;29;NSM;;;;;N;;;;;
+08F3;ARABIC SMALL HIGH WAW;Mn;230;NSM;;;;;N;;;;;
+08F4;ARABIC FATHA WITH RING;Mn;230;NSM;;;;;N;;;;;
+08F5;ARABIC FATHA WITH DOT ABOVE;Mn;230;NSM;;;;;N;;;;;
+08F6;ARABIC KASRA WITH DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+08F7;ARABIC LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
+08F8;ARABIC RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
+08F9;ARABIC LEFT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+08FA;ARABIC RIGHT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+08FB;ARABIC DOUBLE RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
+08FC;ARABIC DOUBLE RIGHT ARROWHEAD ABOVE WITH DOT;Mn;230;NSM;;;;;N;;;;;
+08FD;ARABIC RIGHT ARROWHEAD ABOVE WITH DOT;Mn;230;NSM;;;;;N;;;;;
+08FE;ARABIC DAMMA WITH DOT;Mn;230;NSM;;;;;N;;;;;
+08FF;ARABIC MARK SIDEWAYS NOON GHUNNA;Mn;230;NSM;;;;;N;;;;;
+0900;DEVANAGARI SIGN INVERTED CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+0903;DEVANAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0904;DEVANAGARI LETTER SHORT A;Lo;0;L;;;;;N;;;;;
+0905;DEVANAGARI LETTER A;Lo;0;L;;;;;N;;;;;
+0906;DEVANAGARI LETTER AA;Lo;0;L;;;;;N;;;;;
+0907;DEVANAGARI LETTER I;Lo;0;L;;;;;N;;;;;
+0908;DEVANAGARI LETTER II;Lo;0;L;;;;;N;;;;;
+0909;DEVANAGARI LETTER U;Lo;0;L;;;;;N;;;;;
+090A;DEVANAGARI LETTER UU;Lo;0;L;;;;;N;;;;;
+090B;DEVANAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+090C;DEVANAGARI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+090D;DEVANAGARI LETTER CANDRA E;Lo;0;L;;;;;N;;;;;
+090E;DEVANAGARI LETTER SHORT E;Lo;0;L;;;;;N;;;;;
+090F;DEVANAGARI LETTER E;Lo;0;L;;;;;N;;;;;
+0910;DEVANAGARI LETTER AI;Lo;0;L;;;;;N;;;;;
+0911;DEVANAGARI LETTER CANDRA O;Lo;0;L;;;;;N;;;;;
+0912;DEVANAGARI LETTER SHORT O;Lo;0;L;;;;;N;;;;;
+0913;DEVANAGARI LETTER O;Lo;0;L;;;;;N;;;;;
+0914;DEVANAGARI LETTER AU;Lo;0;L;;;;;N;;;;;
+0915;DEVANAGARI LETTER KA;Lo;0;L;;;;;N;;;;;
+0916;DEVANAGARI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0917;DEVANAGARI LETTER GA;Lo;0;L;;;;;N;;;;;
+0918;DEVANAGARI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0919;DEVANAGARI LETTER NGA;Lo;0;L;;;;;N;;;;;
+091A;DEVANAGARI LETTER CA;Lo;0;L;;;;;N;;;;;
+091B;DEVANAGARI LETTER CHA;Lo;0;L;;;;;N;;;;;
+091C;DEVANAGARI LETTER JA;Lo;0;L;;;;;N;;;;;
+091D;DEVANAGARI LETTER JHA;Lo;0;L;;;;;N;;;;;
+091E;DEVANAGARI LETTER NYA;Lo;0;L;;;;;N;;;;;
+091F;DEVANAGARI LETTER TTA;Lo;0;L;;;;;N;;;;;
+0920;DEVANAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0921;DEVANAGARI LETTER DDA;Lo;0;L;;;;;N;;;;;
+0922;DEVANAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0923;DEVANAGARI LETTER NNA;Lo;0;L;;;;;N;;;;;
+0924;DEVANAGARI LETTER TA;Lo;0;L;;;;;N;;;;;
+0925;DEVANAGARI LETTER THA;Lo;0;L;;;;;N;;;;;
+0926;DEVANAGARI LETTER DA;Lo;0;L;;;;;N;;;;;
+0927;DEVANAGARI LETTER DHA;Lo;0;L;;;;;N;;;;;
+0928;DEVANAGARI LETTER NA;Lo;0;L;;;;;N;;;;;
+0929;DEVANAGARI LETTER NNNA;Lo;0;L;0928 093C;;;;N;;;;;
+092A;DEVANAGARI LETTER PA;Lo;0;L;;;;;N;;;;;
+092B;DEVANAGARI LETTER PHA;Lo;0;L;;;;;N;;;;;
+092C;DEVANAGARI LETTER BA;Lo;0;L;;;;;N;;;;;
+092D;DEVANAGARI LETTER BHA;Lo;0;L;;;;;N;;;;;
+092E;DEVANAGARI LETTER MA;Lo;0;L;;;;;N;;;;;
+092F;DEVANAGARI LETTER YA;Lo;0;L;;;;;N;;;;;
+0930;DEVANAGARI LETTER RA;Lo;0;L;;;;;N;;;;;
+0931;DEVANAGARI LETTER RRA;Lo;0;L;0930 093C;;;;N;;;;;
+0932;DEVANAGARI LETTER LA;Lo;0;L;;;;;N;;;;;
+0933;DEVANAGARI LETTER LLA;Lo;0;L;;;;;N;;;;;
+0934;DEVANAGARI LETTER LLLA;Lo;0;L;0933 093C;;;;N;;;;;
+0935;DEVANAGARI LETTER VA;Lo;0;L;;;;;N;;;;;
+0936;DEVANAGARI LETTER SHA;Lo;0;L;;;;;N;;;;;
+0937;DEVANAGARI LETTER SSA;Lo;0;L;;;;;N;;;;;
+0938;DEVANAGARI LETTER SA;Lo;0;L;;;;;N;;;;;
+0939;DEVANAGARI LETTER HA;Lo;0;L;;;;;N;;;;;
+093A;DEVANAGARI VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;
+093B;DEVANAGARI VOWEL SIGN OOE;Mc;0;L;;;;;N;;;;;
+093C;DEVANAGARI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+093D;DEVANAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+093E;DEVANAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+093F;DEVANAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0940;DEVANAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0941;DEVANAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0942;DEVANAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0943;DEVANAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0944;DEVANAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+0945;DEVANAGARI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;;
+0946;DEVANAGARI VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;;
+0947;DEVANAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+0948;DEVANAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+0949;DEVANAGARI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;;
+094A;DEVANAGARI VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;;
+094B;DEVANAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+094E;DEVANAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;;
+094F;DEVANAGARI VOWEL SIGN AW;Mc;0;L;;;;;N;;;;;
+0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;;
+0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;;
+0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;;
+0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;;
+0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;
+0955;DEVANAGARI VOWEL SIGN CANDRA LONG E;Mn;0;NSM;;;;;N;;;;;
+0956;DEVANAGARI VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
+0957;DEVANAGARI VOWEL SIGN UUE;Mn;0;NSM;;;;;N;;;;;
+0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;;
+0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;;
+095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;;
+095B;DEVANAGARI LETTER ZA;Lo;0;L;091C 093C;;;;N;;;;;
+095C;DEVANAGARI LETTER DDDHA;Lo;0;L;0921 093C;;;;N;;;;;
+095D;DEVANAGARI LETTER RHA;Lo;0;L;0922 093C;;;;N;;;;;
+095E;DEVANAGARI LETTER FA;Lo;0;L;092B 093C;;;;N;;;;;
+095F;DEVANAGARI LETTER YYA;Lo;0;L;092F 093C;;;;N;;;;;
+0960;DEVANAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0961;DEVANAGARI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0962;DEVANAGARI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0963;DEVANAGARI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0964;DEVANAGARI DANDA;Po;0;L;;;;;N;;;;;
+0965;DEVANAGARI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+0966;DEVANAGARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0967;DEVANAGARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0968;DEVANAGARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0969;DEVANAGARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+096A;DEVANAGARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+096B;DEVANAGARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+096C;DEVANAGARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+096D;DEVANAGARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+096E;DEVANAGARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+096F;DEVANAGARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+0971;DEVANAGARI SIGN HIGH SPACING DOT;Lm;0;L;;;;;N;;;;;
+0972;DEVANAGARI LETTER CANDRA A;Lo;0;L;;;;;N;;;;;
+0973;DEVANAGARI LETTER OE;Lo;0;L;;;;;N;;;;;
+0974;DEVANAGARI LETTER OOE;Lo;0;L;;;;;N;;;;;
+0975;DEVANAGARI LETTER AW;Lo;0;L;;;;;N;;;;;
+0976;DEVANAGARI LETTER UE;Lo;0;L;;;;;N;;;;;
+0977;DEVANAGARI LETTER UUE;Lo;0;L;;;;;N;;;;;
+0978;DEVANAGARI LETTER MARWARI DDA;Lo;0;L;;;;;N;;;;;
+0979;DEVANAGARI LETTER ZHA;Lo;0;L;;;;;N;;;;;
+097A;DEVANAGARI LETTER HEAVY YA;Lo;0;L;;;;;N;;;;;
+097B;DEVANAGARI LETTER GGA;Lo;0;L;;;;;N;;;;;
+097C;DEVANAGARI LETTER JJA;Lo;0;L;;;;;N;;;;;
+097D;DEVANAGARI LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
+097E;DEVANAGARI LETTER DDDA;Lo;0;L;;;;;N;;;;;
+097F;DEVANAGARI LETTER BBA;Lo;0;L;;;;;N;;;;;
+0980;BENGALI ANJI;Lo;0;L;;;;;N;;;;;
+0981;BENGALI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0982;BENGALI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0983;BENGALI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0985;BENGALI LETTER A;Lo;0;L;;;;;N;;;;;
+0986;BENGALI LETTER AA;Lo;0;L;;;;;N;;;;;
+0987;BENGALI LETTER I;Lo;0;L;;;;;N;;;;;
+0988;BENGALI LETTER II;Lo;0;L;;;;;N;;;;;
+0989;BENGALI LETTER U;Lo;0;L;;;;;N;;;;;
+098A;BENGALI LETTER UU;Lo;0;L;;;;;N;;;;;
+098B;BENGALI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+098C;BENGALI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+098F;BENGALI LETTER E;Lo;0;L;;;;;N;;;;;
+0990;BENGALI LETTER AI;Lo;0;L;;;;;N;;;;;
+0993;BENGALI LETTER O;Lo;0;L;;;;;N;;;;;
+0994;BENGALI LETTER AU;Lo;0;L;;;;;N;;;;;
+0995;BENGALI LETTER KA;Lo;0;L;;;;;N;;;;;
+0996;BENGALI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0997;BENGALI LETTER GA;Lo;0;L;;;;;N;;;;;
+0998;BENGALI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0999;BENGALI LETTER NGA;Lo;0;L;;;;;N;;;;;
+099A;BENGALI LETTER CA;Lo;0;L;;;;;N;;;;;
+099B;BENGALI LETTER CHA;Lo;0;L;;;;;N;;;;;
+099C;BENGALI LETTER JA;Lo;0;L;;;;;N;;;;;
+099D;BENGALI LETTER JHA;Lo;0;L;;;;;N;;;;;
+099E;BENGALI LETTER NYA;Lo;0;L;;;;;N;;;;;
+099F;BENGALI LETTER TTA;Lo;0;L;;;;;N;;;;;
+09A0;BENGALI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+09A1;BENGALI LETTER DDA;Lo;0;L;;;;;N;;;;;
+09A2;BENGALI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+09A3;BENGALI LETTER NNA;Lo;0;L;;;;;N;;;;;
+09A4;BENGALI LETTER TA;Lo;0;L;;;;;N;;;;;
+09A5;BENGALI LETTER THA;Lo;0;L;;;;;N;;;;;
+09A6;BENGALI LETTER DA;Lo;0;L;;;;;N;;;;;
+09A7;BENGALI LETTER DHA;Lo;0;L;;;;;N;;;;;
+09A8;BENGALI LETTER NA;Lo;0;L;;;;;N;;;;;
+09AA;BENGALI LETTER PA;Lo;0;L;;;;;N;;;;;
+09AB;BENGALI LETTER PHA;Lo;0;L;;;;;N;;;;;
+09AC;BENGALI LETTER BA;Lo;0;L;;;;;N;;;;;
+09AD;BENGALI LETTER BHA;Lo;0;L;;;;;N;;;;;
+09AE;BENGALI LETTER MA;Lo;0;L;;;;;N;;;;;
+09AF;BENGALI LETTER YA;Lo;0;L;;;;;N;;;;;
+09B0;BENGALI LETTER RA;Lo;0;L;;;;;N;;;;;
+09B2;BENGALI LETTER LA;Lo;0;L;;;;;N;;;;;
+09B6;BENGALI LETTER SHA;Lo;0;L;;;;;N;;;;;
+09B7;BENGALI LETTER SSA;Lo;0;L;;;;;N;;;;;
+09B8;BENGALI LETTER SA;Lo;0;L;;;;;N;;;;;
+09B9;BENGALI LETTER HA;Lo;0;L;;;;;N;;;;;
+09BC;BENGALI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+09BD;BENGALI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+09BE;BENGALI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+09BF;BENGALI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+09C0;BENGALI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+09C1;BENGALI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+09C2;BENGALI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+09C3;BENGALI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+09C4;BENGALI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+09C7;BENGALI VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+09C8;BENGALI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+09CB;BENGALI VOWEL SIGN O;Mc;0;L;09C7 09BE;;;;N;;;;;
+09CC;BENGALI VOWEL SIGN AU;Mc;0;L;09C7 09D7;;;;N;;;;;
+09CD;BENGALI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+09CE;BENGALI LETTER KHANDA TA;Lo;0;L;;;;;N;;;;;
+09D7;BENGALI AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+09DC;BENGALI LETTER RRA;Lo;0;L;09A1 09BC;;;;N;;;;;
+09DD;BENGALI LETTER RHA;Lo;0;L;09A2 09BC;;;;N;;;;;
+09DF;BENGALI LETTER YYA;Lo;0;L;09AF 09BC;;;;N;;;;;
+09E0;BENGALI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+09E1;BENGALI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+09E2;BENGALI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+09E3;BENGALI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+09E6;BENGALI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+09E7;BENGALI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+09E8;BENGALI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+09E9;BENGALI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+09EA;BENGALI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+09EB;BENGALI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+09EC;BENGALI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+09ED;BENGALI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+09EE;BENGALI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+09EF;BENGALI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;;;;
+09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;;;;
+09F2;BENGALI RUPEE MARK;Sc;0;ET;;;;;N;;;;;
+09F3;BENGALI RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
+09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1/16;N;;;;;
+09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;1/8;N;;;;;
+09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3/16;N;;;;;
+09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;1/4;N;;;;;
+09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;3/4;N;;;;;
+09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;;
+09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;;
+09FB;BENGALI GANDA MARK;Sc;0;ET;;;;;N;;;;;
+0A01;GURMUKHI SIGN ADAK BINDI;Mn;0;NSM;;;;;N;;;;;
+0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;;
+0A03;GURMUKHI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0A05;GURMUKHI LETTER A;Lo;0;L;;;;;N;;;;;
+0A06;GURMUKHI LETTER AA;Lo;0;L;;;;;N;;;;;
+0A07;GURMUKHI LETTER I;Lo;0;L;;;;;N;;;;;
+0A08;GURMUKHI LETTER II;Lo;0;L;;;;;N;;;;;
+0A09;GURMUKHI LETTER U;Lo;0;L;;;;;N;;;;;
+0A0A;GURMUKHI LETTER UU;Lo;0;L;;;;;N;;;;;
+0A0F;GURMUKHI LETTER EE;Lo;0;L;;;;;N;;;;;
+0A10;GURMUKHI LETTER AI;Lo;0;L;;;;;N;;;;;
+0A13;GURMUKHI LETTER OO;Lo;0;L;;;;;N;;;;;
+0A14;GURMUKHI LETTER AU;Lo;0;L;;;;;N;;;;;
+0A15;GURMUKHI LETTER KA;Lo;0;L;;;;;N;;;;;
+0A16;GURMUKHI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0A17;GURMUKHI LETTER GA;Lo;0;L;;;;;N;;;;;
+0A18;GURMUKHI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0A19;GURMUKHI LETTER NGA;Lo;0;L;;;;;N;;;;;
+0A1A;GURMUKHI LETTER CA;Lo;0;L;;;;;N;;;;;
+0A1B;GURMUKHI LETTER CHA;Lo;0;L;;;;;N;;;;;
+0A1C;GURMUKHI LETTER JA;Lo;0;L;;;;;N;;;;;
+0A1D;GURMUKHI LETTER JHA;Lo;0;L;;;;;N;;;;;
+0A1E;GURMUKHI LETTER NYA;Lo;0;L;;;;;N;;;;;
+0A1F;GURMUKHI LETTER TTA;Lo;0;L;;;;;N;;;;;
+0A20;GURMUKHI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0A21;GURMUKHI LETTER DDA;Lo;0;L;;;;;N;;;;;
+0A22;GURMUKHI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0A23;GURMUKHI LETTER NNA;Lo;0;L;;;;;N;;;;;
+0A24;GURMUKHI LETTER TA;Lo;0;L;;;;;N;;;;;
+0A25;GURMUKHI LETTER THA;Lo;0;L;;;;;N;;;;;
+0A26;GURMUKHI LETTER DA;Lo;0;L;;;;;N;;;;;
+0A27;GURMUKHI LETTER DHA;Lo;0;L;;;;;N;;;;;
+0A28;GURMUKHI LETTER NA;Lo;0;L;;;;;N;;;;;
+0A2A;GURMUKHI LETTER PA;Lo;0;L;;;;;N;;;;;
+0A2B;GURMUKHI LETTER PHA;Lo;0;L;;;;;N;;;;;
+0A2C;GURMUKHI LETTER BA;Lo;0;L;;;;;N;;;;;
+0A2D;GURMUKHI LETTER BHA;Lo;0;L;;;;;N;;;;;
+0A2E;GURMUKHI LETTER MA;Lo;0;L;;;;;N;;;;;
+0A2F;GURMUKHI LETTER YA;Lo;0;L;;;;;N;;;;;
+0A30;GURMUKHI LETTER RA;Lo;0;L;;;;;N;;;;;
+0A32;GURMUKHI LETTER LA;Lo;0;L;;;;;N;;;;;
+0A33;GURMUKHI LETTER LLA;Lo;0;L;0A32 0A3C;;;;N;;;;;
+0A35;GURMUKHI LETTER VA;Lo;0;L;;;;;N;;;;;
+0A36;GURMUKHI LETTER SHA;Lo;0;L;0A38 0A3C;;;;N;;;;;
+0A38;GURMUKHI LETTER SA;Lo;0;L;;;;;N;;;;;
+0A39;GURMUKHI LETTER HA;Lo;0;L;;;;;N;;;;;
+0A3C;GURMUKHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+0A3E;GURMUKHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0A3F;GURMUKHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0A40;GURMUKHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0A41;GURMUKHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0A42;GURMUKHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0A47;GURMUKHI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;
+0A48;GURMUKHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+0A4B;GURMUKHI VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;;
+0A4C;GURMUKHI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+0A4D;GURMUKHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0A51;GURMUKHI SIGN UDAAT;Mn;0;NSM;;;;;N;;;;;
+0A59;GURMUKHI LETTER KHHA;Lo;0;L;0A16 0A3C;;;;N;;;;;
+0A5A;GURMUKHI LETTER GHHA;Lo;0;L;0A17 0A3C;;;;N;;;;;
+0A5B;GURMUKHI LETTER ZA;Lo;0;L;0A1C 0A3C;;;;N;;;;;
+0A5C;GURMUKHI LETTER RRA;Lo;0;L;;;;;N;;;;;
+0A5E;GURMUKHI LETTER FA;Lo;0;L;0A2B 0A3C;;;;N;;;;;
+0A66;GURMUKHI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0A67;GURMUKHI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0A68;GURMUKHI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0A69;GURMUKHI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0A6A;GURMUKHI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0A6B;GURMUKHI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0A6C;GURMUKHI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0A6D;GURMUKHI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0A6E;GURMUKHI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0A6F;GURMUKHI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0A70;GURMUKHI TIPPI;Mn;0;NSM;;;;;N;;;;;
+0A71;GURMUKHI ADDAK;Mn;0;NSM;;;;;N;;;;;
+0A72;GURMUKHI IRI;Lo;0;L;;;;;N;;;;;
+0A73;GURMUKHI URA;Lo;0;L;;;;;N;;;;;
+0A74;GURMUKHI EK ONKAR;Lo;0;L;;;;;N;;;;;
+0A75;GURMUKHI SIGN YAKASH;Mn;0;NSM;;;;;N;;;;;
+0A81;GUJARATI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0A82;GUJARATI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+0A83;GUJARATI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0A85;GUJARATI LETTER A;Lo;0;L;;;;;N;;;;;
+0A86;GUJARATI LETTER AA;Lo;0;L;;;;;N;;;;;
+0A87;GUJARATI LETTER I;Lo;0;L;;;;;N;;;;;
+0A88;GUJARATI LETTER II;Lo;0;L;;;;;N;;;;;
+0A89;GUJARATI LETTER U;Lo;0;L;;;;;N;;;;;
+0A8A;GUJARATI LETTER UU;Lo;0;L;;;;;N;;;;;
+0A8B;GUJARATI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0A8C;GUJARATI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0A8D;GUJARATI VOWEL CANDRA E;Lo;0;L;;;;;N;;;;;
+0A8F;GUJARATI LETTER E;Lo;0;L;;;;;N;;;;;
+0A90;GUJARATI LETTER AI;Lo;0;L;;;;;N;;;;;
+0A91;GUJARATI VOWEL CANDRA O;Lo;0;L;;;;;N;;;;;
+0A93;GUJARATI LETTER O;Lo;0;L;;;;;N;;;;;
+0A94;GUJARATI LETTER AU;Lo;0;L;;;;;N;;;;;
+0A95;GUJARATI LETTER KA;Lo;0;L;;;;;N;;;;;
+0A96;GUJARATI LETTER KHA;Lo;0;L;;;;;N;;;;;
+0A97;GUJARATI LETTER GA;Lo;0;L;;;;;N;;;;;
+0A98;GUJARATI LETTER GHA;Lo;0;L;;;;;N;;;;;
+0A99;GUJARATI LETTER NGA;Lo;0;L;;;;;N;;;;;
+0A9A;GUJARATI LETTER CA;Lo;0;L;;;;;N;;;;;
+0A9B;GUJARATI LETTER CHA;Lo;0;L;;;;;N;;;;;
+0A9C;GUJARATI LETTER JA;Lo;0;L;;;;;N;;;;;
+0A9D;GUJARATI LETTER JHA;Lo;0;L;;;;;N;;;;;
+0A9E;GUJARATI LETTER NYA;Lo;0;L;;;;;N;;;;;
+0A9F;GUJARATI LETTER TTA;Lo;0;L;;;;;N;;;;;
+0AA0;GUJARATI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0AA1;GUJARATI LETTER DDA;Lo;0;L;;;;;N;;;;;
+0AA2;GUJARATI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0AA3;GUJARATI LETTER NNA;Lo;0;L;;;;;N;;;;;
+0AA4;GUJARATI LETTER TA;Lo;0;L;;;;;N;;;;;
+0AA5;GUJARATI LETTER THA;Lo;0;L;;;;;N;;;;;
+0AA6;GUJARATI LETTER DA;Lo;0;L;;;;;N;;;;;
+0AA7;GUJARATI LETTER DHA;Lo;0;L;;;;;N;;;;;
+0AA8;GUJARATI LETTER NA;Lo;0;L;;;;;N;;;;;
+0AAA;GUJARATI LETTER PA;Lo;0;L;;;;;N;;;;;
+0AAB;GUJARATI LETTER PHA;Lo;0;L;;;;;N;;;;;
+0AAC;GUJARATI LETTER BA;Lo;0;L;;;;;N;;;;;
+0AAD;GUJARATI LETTER BHA;Lo;0;L;;;;;N;;;;;
+0AAE;GUJARATI LETTER MA;Lo;0;L;;;;;N;;;;;
+0AAF;GUJARATI LETTER YA;Lo;0;L;;;;;N;;;;;
+0AB0;GUJARATI LETTER RA;Lo;0;L;;;;;N;;;;;
+0AB2;GUJARATI LETTER LA;Lo;0;L;;;;;N;;;;;
+0AB3;GUJARATI LETTER LLA;Lo;0;L;;;;;N;;;;;
+0AB5;GUJARATI LETTER VA;Lo;0;L;;;;;N;;;;;
+0AB6;GUJARATI LETTER SHA;Lo;0;L;;;;;N;;;;;
+0AB7;GUJARATI LETTER SSA;Lo;0;L;;;;;N;;;;;
+0AB8;GUJARATI LETTER SA;Lo;0;L;;;;;N;;;;;
+0AB9;GUJARATI LETTER HA;Lo;0;L;;;;;N;;;;;
+0ABC;GUJARATI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+0ABD;GUJARATI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0ABE;GUJARATI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0ABF;GUJARATI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0AC0;GUJARATI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0AC1;GUJARATI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0AC2;GUJARATI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0AC3;GUJARATI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0AC4;GUJARATI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+0AC5;GUJARATI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;;
+0AC7;GUJARATI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+0AC8;GUJARATI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+0AC9;GUJARATI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;;
+0ACB;GUJARATI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+0ACC;GUJARATI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+0ACD;GUJARATI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0AD0;GUJARATI OM;Lo;0;L;;;;;N;;;;;
+0AE0;GUJARATI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0AE1;GUJARATI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0AE2;GUJARATI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0AE3;GUJARATI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0AE6;GUJARATI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0AE7;GUJARATI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0AE8;GUJARATI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0AE9;GUJARATI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0AEA;GUJARATI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0AEB;GUJARATI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0AEC;GUJARATI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0AED;GUJARATI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0AEE;GUJARATI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0AEF;GUJARATI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0AF0;GUJARATI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+0AF1;GUJARATI RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
+0AF9;GUJARATI LETTER ZHA;Lo;0;L;;;;;N;;;;;
+0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0B05;ORIYA LETTER A;Lo;0;L;;;;;N;;;;;
+0B06;ORIYA LETTER AA;Lo;0;L;;;;;N;;;;;
+0B07;ORIYA LETTER I;Lo;0;L;;;;;N;;;;;
+0B08;ORIYA LETTER II;Lo;0;L;;;;;N;;;;;
+0B09;ORIYA LETTER U;Lo;0;L;;;;;N;;;;;
+0B0A;ORIYA LETTER UU;Lo;0;L;;;;;N;;;;;
+0B0B;ORIYA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0B0C;ORIYA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0B0F;ORIYA LETTER E;Lo;0;L;;;;;N;;;;;
+0B10;ORIYA LETTER AI;Lo;0;L;;;;;N;;;;;
+0B13;ORIYA LETTER O;Lo;0;L;;;;;N;;;;;
+0B14;ORIYA LETTER AU;Lo;0;L;;;;;N;;;;;
+0B15;ORIYA LETTER KA;Lo;0;L;;;;;N;;;;;
+0B16;ORIYA LETTER KHA;Lo;0;L;;;;;N;;;;;
+0B17;ORIYA LETTER GA;Lo;0;L;;;;;N;;;;;
+0B18;ORIYA LETTER GHA;Lo;0;L;;;;;N;;;;;
+0B19;ORIYA LETTER NGA;Lo;0;L;;;;;N;;;;;
+0B1A;ORIYA LETTER CA;Lo;0;L;;;;;N;;;;;
+0B1B;ORIYA LETTER CHA;Lo;0;L;;;;;N;;;;;
+0B1C;ORIYA LETTER JA;Lo;0;L;;;;;N;;;;;
+0B1D;ORIYA LETTER JHA;Lo;0;L;;;;;N;;;;;
+0B1E;ORIYA LETTER NYA;Lo;0;L;;;;;N;;;;;
+0B1F;ORIYA LETTER TTA;Lo;0;L;;;;;N;;;;;
+0B20;ORIYA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0B21;ORIYA LETTER DDA;Lo;0;L;;;;;N;;;;;
+0B22;ORIYA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0B23;ORIYA LETTER NNA;Lo;0;L;;;;;N;;;;;
+0B24;ORIYA LETTER TA;Lo;0;L;;;;;N;;;;;
+0B25;ORIYA LETTER THA;Lo;0;L;;;;;N;;;;;
+0B26;ORIYA LETTER DA;Lo;0;L;;;;;N;;;;;
+0B27;ORIYA LETTER DHA;Lo;0;L;;;;;N;;;;;
+0B28;ORIYA LETTER NA;Lo;0;L;;;;;N;;;;;
+0B2A;ORIYA LETTER PA;Lo;0;L;;;;;N;;;;;
+0B2B;ORIYA LETTER PHA;Lo;0;L;;;;;N;;;;;
+0B2C;ORIYA LETTER BA;Lo;0;L;;;;;N;;;;;
+0B2D;ORIYA LETTER BHA;Lo;0;L;;;;;N;;;;;
+0B2E;ORIYA LETTER MA;Lo;0;L;;;;;N;;;;;
+0B2F;ORIYA LETTER YA;Lo;0;L;;;;;N;;;;;
+0B30;ORIYA LETTER RA;Lo;0;L;;;;;N;;;;;
+0B32;ORIYA LETTER LA;Lo;0;L;;;;;N;;;;;
+0B33;ORIYA LETTER LLA;Lo;0;L;;;;;N;;;;;
+0B35;ORIYA LETTER VA;Lo;0;L;;;;;N;;;;;
+0B36;ORIYA LETTER SHA;Lo;0;L;;;;;N;;;;;
+0B37;ORIYA LETTER SSA;Lo;0;L;;;;;N;;;;;
+0B38;ORIYA LETTER SA;Lo;0;L;;;;;N;;;;;
+0B39;ORIYA LETTER HA;Lo;0;L;;;;;N;;;;;
+0B3C;ORIYA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+0B3D;ORIYA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0B3E;ORIYA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0B3F;ORIYA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+0B40;ORIYA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0B41;ORIYA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0B42;ORIYA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0B43;ORIYA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0B44;ORIYA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+0B47;ORIYA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+0B48;ORIYA VOWEL SIGN AI;Mc;0;L;0B47 0B56;;;;N;;;;;
+0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;;
+0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;;
+0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
+0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;;
+0B5D;ORIYA LETTER RHA;Lo;0;L;0B22 0B3C;;;;N;;;;;
+0B5F;ORIYA LETTER YYA;Lo;0;L;;;;;N;;;;;
+0B60;ORIYA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0B61;ORIYA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0B62;ORIYA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0B63;ORIYA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0B66;ORIYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0B67;ORIYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0B68;ORIYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0B69;ORIYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0B6A;ORIYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0B6B;ORIYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0B6C;ORIYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0B6D;ORIYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0B6E;ORIYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0B6F;ORIYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0B70;ORIYA ISSHAR;So;0;L;;;;;N;;;;;
+0B71;ORIYA LETTER WA;Lo;0;L;;;;;N;;;;;
+0B72;ORIYA FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;
+0B73;ORIYA FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;
+0B74;ORIYA FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;
+0B75;ORIYA FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;;
+0B76;ORIYA FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;
+0B77;ORIYA FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;
+0B82;TAMIL SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+0B83;TAMIL SIGN VISARGA;Lo;0;L;;;;;N;;;;;
+0B85;TAMIL LETTER A;Lo;0;L;;;;;N;;;;;
+0B86;TAMIL LETTER AA;Lo;0;L;;;;;N;;;;;
+0B87;TAMIL LETTER I;Lo;0;L;;;;;N;;;;;
+0B88;TAMIL LETTER II;Lo;0;L;;;;;N;;;;;
+0B89;TAMIL LETTER U;Lo;0;L;;;;;N;;;;;
+0B8A;TAMIL LETTER UU;Lo;0;L;;;;;N;;;;;
+0B8E;TAMIL LETTER E;Lo;0;L;;;;;N;;;;;
+0B8F;TAMIL LETTER EE;Lo;0;L;;;;;N;;;;;
+0B90;TAMIL LETTER AI;Lo;0;L;;;;;N;;;;;
+0B92;TAMIL LETTER O;Lo;0;L;;;;;N;;;;;
+0B93;TAMIL LETTER OO;Lo;0;L;;;;;N;;;;;
+0B94;TAMIL LETTER AU;Lo;0;L;0B92 0BD7;;;;N;;;;;
+0B95;TAMIL LETTER KA;Lo;0;L;;;;;N;;;;;
+0B99;TAMIL LETTER NGA;Lo;0;L;;;;;N;;;;;
+0B9A;TAMIL LETTER CA;Lo;0;L;;;;;N;;;;;
+0B9C;TAMIL LETTER JA;Lo;0;L;;;;;N;;;;;
+0B9E;TAMIL LETTER NYA;Lo;0;L;;;;;N;;;;;
+0B9F;TAMIL LETTER TTA;Lo;0;L;;;;;N;;;;;
+0BA3;TAMIL LETTER NNA;Lo;0;L;;;;;N;;;;;
+0BA4;TAMIL LETTER TA;Lo;0;L;;;;;N;;;;;
+0BA8;TAMIL LETTER NA;Lo;0;L;;;;;N;;;;;
+0BA9;TAMIL LETTER NNNA;Lo;0;L;;;;;N;;;;;
+0BAA;TAMIL LETTER PA;Lo;0;L;;;;;N;;;;;
+0BAE;TAMIL LETTER MA;Lo;0;L;;;;;N;;;;;
+0BAF;TAMIL LETTER YA;Lo;0;L;;;;;N;;;;;
+0BB0;TAMIL LETTER RA;Lo;0;L;;;;;N;;;;;
+0BB1;TAMIL LETTER RRA;Lo;0;L;;;;;N;;;;;
+0BB2;TAMIL LETTER LA;Lo;0;L;;;;;N;;;;;
+0BB3;TAMIL LETTER LLA;Lo;0;L;;;;;N;;;;;
+0BB4;TAMIL LETTER LLLA;Lo;0;L;;;;;N;;;;;
+0BB5;TAMIL LETTER VA;Lo;0;L;;;;;N;;;;;
+0BB6;TAMIL LETTER SHA;Lo;0;L;;;;;N;;;;;
+0BB7;TAMIL LETTER SSA;Lo;0;L;;;;;N;;;;;
+0BB8;TAMIL LETTER SA;Lo;0;L;;;;;N;;;;;
+0BB9;TAMIL LETTER HA;Lo;0;L;;;;;N;;;;;
+0BBE;TAMIL VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0BBF;TAMIL VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0BC0;TAMIL VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+0BC1;TAMIL VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+0BC2;TAMIL VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+0BC6;TAMIL VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+0BC7;TAMIL VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+0BC8;TAMIL VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+0BCA;TAMIL VOWEL SIGN O;Mc;0;L;0BC6 0BBE;;;;N;;;;;
+0BCB;TAMIL VOWEL SIGN OO;Mc;0;L;0BC7 0BBE;;;;N;;;;;
+0BCC;TAMIL VOWEL SIGN AU;Mc;0;L;0BC6 0BD7;;;;N;;;;;
+0BCD;TAMIL SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0BD0;TAMIL OM;Lo;0;L;;;;;N;;;;;
+0BD7;TAMIL AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0BE6;TAMIL DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0BE7;TAMIL DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0BE8;TAMIL DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0BE9;TAMIL DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0BEA;TAMIL DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0BEB;TAMIL DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0BEC;TAMIL DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0BED;TAMIL DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0BEE;TAMIL DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0BEF;TAMIL DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0BF0;TAMIL NUMBER TEN;No;0;L;;;;10;N;;;;;
+0BF1;TAMIL NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
+0BF2;TAMIL NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
+0BF3;TAMIL DAY SIGN;So;0;ON;;;;;N;;;;;
+0BF4;TAMIL MONTH SIGN;So;0;ON;;;;;N;;;;;
+0BF5;TAMIL YEAR SIGN;So;0;ON;;;;;N;;;;;
+0BF6;TAMIL DEBIT SIGN;So;0;ON;;;;;N;;;;;
+0BF7;TAMIL CREDIT SIGN;So;0;ON;;;;;N;;;;;
+0BF8;TAMIL AS ABOVE SIGN;So;0;ON;;;;;N;;;;;
+0BF9;TAMIL RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
+0BFA;TAMIL NUMBER SIGN;So;0;ON;;;;;N;;;;;
+0C00;TELUGU SIGN COMBINING CANDRABINDU ABOVE;Mn;0;NSM;;;;;N;;;;;
+0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;;
+0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0C05;TELUGU LETTER A;Lo;0;L;;;;;N;;;;;
+0C06;TELUGU LETTER AA;Lo;0;L;;;;;N;;;;;
+0C07;TELUGU LETTER I;Lo;0;L;;;;;N;;;;;
+0C08;TELUGU LETTER II;Lo;0;L;;;;;N;;;;;
+0C09;TELUGU LETTER U;Lo;0;L;;;;;N;;;;;
+0C0A;TELUGU LETTER UU;Lo;0;L;;;;;N;;;;;
+0C0B;TELUGU LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0C0C;TELUGU LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0C0E;TELUGU LETTER E;Lo;0;L;;;;;N;;;;;
+0C0F;TELUGU LETTER EE;Lo;0;L;;;;;N;;;;;
+0C10;TELUGU LETTER AI;Lo;0;L;;;;;N;;;;;
+0C12;TELUGU LETTER O;Lo;0;L;;;;;N;;;;;
+0C13;TELUGU LETTER OO;Lo;0;L;;;;;N;;;;;
+0C14;TELUGU LETTER AU;Lo;0;L;;;;;N;;;;;
+0C15;TELUGU LETTER KA;Lo;0;L;;;;;N;;;;;
+0C16;TELUGU LETTER KHA;Lo;0;L;;;;;N;;;;;
+0C17;TELUGU LETTER GA;Lo;0;L;;;;;N;;;;;
+0C18;TELUGU LETTER GHA;Lo;0;L;;;;;N;;;;;
+0C19;TELUGU LETTER NGA;Lo;0;L;;;;;N;;;;;
+0C1A;TELUGU LETTER CA;Lo;0;L;;;;;N;;;;;
+0C1B;TELUGU LETTER CHA;Lo;0;L;;;;;N;;;;;
+0C1C;TELUGU LETTER JA;Lo;0;L;;;;;N;;;;;
+0C1D;TELUGU LETTER JHA;Lo;0;L;;;;;N;;;;;
+0C1E;TELUGU LETTER NYA;Lo;0;L;;;;;N;;;;;
+0C1F;TELUGU LETTER TTA;Lo;0;L;;;;;N;;;;;
+0C20;TELUGU LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0C21;TELUGU LETTER DDA;Lo;0;L;;;;;N;;;;;
+0C22;TELUGU LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0C23;TELUGU LETTER NNA;Lo;0;L;;;;;N;;;;;
+0C24;TELUGU LETTER TA;Lo;0;L;;;;;N;;;;;
+0C25;TELUGU LETTER THA;Lo;0;L;;;;;N;;;;;
+0C26;TELUGU LETTER DA;Lo;0;L;;;;;N;;;;;
+0C27;TELUGU LETTER DHA;Lo;0;L;;;;;N;;;;;
+0C28;TELUGU LETTER NA;Lo;0;L;;;;;N;;;;;
+0C2A;TELUGU LETTER PA;Lo;0;L;;;;;N;;;;;
+0C2B;TELUGU LETTER PHA;Lo;0;L;;;;;N;;;;;
+0C2C;TELUGU LETTER BA;Lo;0;L;;;;;N;;;;;
+0C2D;TELUGU LETTER BHA;Lo;0;L;;;;;N;;;;;
+0C2E;TELUGU LETTER MA;Lo;0;L;;;;;N;;;;;
+0C2F;TELUGU LETTER YA;Lo;0;L;;;;;N;;;;;
+0C30;TELUGU LETTER RA;Lo;0;L;;;;;N;;;;;
+0C31;TELUGU LETTER RRA;Lo;0;L;;;;;N;;;;;
+0C32;TELUGU LETTER LA;Lo;0;L;;;;;N;;;;;
+0C33;TELUGU LETTER LLA;Lo;0;L;;;;;N;;;;;
+0C34;TELUGU LETTER LLLA;Lo;0;L;;;;;N;;;;;
+0C35;TELUGU LETTER VA;Lo;0;L;;;;;N;;;;;
+0C36;TELUGU LETTER SHA;Lo;0;L;;;;;N;;;;;
+0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;;
+0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;;
+0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;;
+0C3D;TELUGU SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+0C40;TELUGU VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+0C41;TELUGU VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+0C42;TELUGU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+0C43;TELUGU VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+0C44;TELUGU VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+0C46;TELUGU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+0C47;TELUGU VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;
+0C48;TELUGU VOWEL SIGN AI;Mn;0;NSM;0C46 0C56;;;;N;;;;;
+0C4A;TELUGU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+0C4B;TELUGU VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;;
+0C4C;TELUGU VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+0C4D;TELUGU SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0C55;TELUGU LENGTH MARK;Mn;84;NSM;;;;;N;;;;;
+0C56;TELUGU AI LENGTH MARK;Mn;91;NSM;;;;;N;;;;;
+0C58;TELUGU LETTER TSA;Lo;0;L;;;;;N;;;;;
+0C59;TELUGU LETTER DZA;Lo;0;L;;;;;N;;;;;
+0C5A;TELUGU LETTER RRRA;Lo;0;L;;;;;N;;;;;
+0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0C62;TELUGU VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0C63;TELUGU VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0C66;TELUGU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0C67;TELUGU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0C68;TELUGU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0C69;TELUGU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0C6A;TELUGU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0C6B;TELUGU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0C6C;TELUGU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0C78;TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR;No;0;ON;;;;0;N;;;;;
+0C79;TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR;No;0;ON;;;;1;N;;;;;
+0C7A;TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR;No;0;ON;;;;2;N;;;;;
+0C7B;TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR;No;0;ON;;;;3;N;;;;;
+0C7C;TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR;No;0;ON;;;;1;N;;;;;
+0C7D;TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR;No;0;ON;;;;2;N;;;;;
+0C7E;TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR;No;0;ON;;;;3;N;;;;;
+0C7F;TELUGU SIGN TUUMU;So;0;L;;;;;N;;;;;
+0C80;KANNADA SIGN SPACING CANDRABINDU;Lo;0;L;;;;;N;;;;;
+0C81;KANNADA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;;
+0C86;KANNADA LETTER AA;Lo;0;L;;;;;N;;;;;
+0C87;KANNADA LETTER I;Lo;0;L;;;;;N;;;;;
+0C88;KANNADA LETTER II;Lo;0;L;;;;;N;;;;;
+0C89;KANNADA LETTER U;Lo;0;L;;;;;N;;;;;
+0C8A;KANNADA LETTER UU;Lo;0;L;;;;;N;;;;;
+0C8B;KANNADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0C8C;KANNADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0C8E;KANNADA LETTER E;Lo;0;L;;;;;N;;;;;
+0C8F;KANNADA LETTER EE;Lo;0;L;;;;;N;;;;;
+0C90;KANNADA LETTER AI;Lo;0;L;;;;;N;;;;;
+0C92;KANNADA LETTER O;Lo;0;L;;;;;N;;;;;
+0C93;KANNADA LETTER OO;Lo;0;L;;;;;N;;;;;
+0C94;KANNADA LETTER AU;Lo;0;L;;;;;N;;;;;
+0C95;KANNADA LETTER KA;Lo;0;L;;;;;N;;;;;
+0C96;KANNADA LETTER KHA;Lo;0;L;;;;;N;;;;;
+0C97;KANNADA LETTER GA;Lo;0;L;;;;;N;;;;;
+0C98;KANNADA LETTER GHA;Lo;0;L;;;;;N;;;;;
+0C99;KANNADA LETTER NGA;Lo;0;L;;;;;N;;;;;
+0C9A;KANNADA LETTER CA;Lo;0;L;;;;;N;;;;;
+0C9B;KANNADA LETTER CHA;Lo;0;L;;;;;N;;;;;
+0C9C;KANNADA LETTER JA;Lo;0;L;;;;;N;;;;;
+0C9D;KANNADA LETTER JHA;Lo;0;L;;;;;N;;;;;
+0C9E;KANNADA LETTER NYA;Lo;0;L;;;;;N;;;;;
+0C9F;KANNADA LETTER TTA;Lo;0;L;;;;;N;;;;;
+0CA0;KANNADA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0CA1;KANNADA LETTER DDA;Lo;0;L;;;;;N;;;;;
+0CA2;KANNADA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0CA3;KANNADA LETTER NNA;Lo;0;L;;;;;N;;;;;
+0CA4;KANNADA LETTER TA;Lo;0;L;;;;;N;;;;;
+0CA5;KANNADA LETTER THA;Lo;0;L;;;;;N;;;;;
+0CA6;KANNADA LETTER DA;Lo;0;L;;;;;N;;;;;
+0CA7;KANNADA LETTER DHA;Lo;0;L;;;;;N;;;;;
+0CA8;KANNADA LETTER NA;Lo;0;L;;;;;N;;;;;
+0CAA;KANNADA LETTER PA;Lo;0;L;;;;;N;;;;;
+0CAB;KANNADA LETTER PHA;Lo;0;L;;;;;N;;;;;
+0CAC;KANNADA LETTER BA;Lo;0;L;;;;;N;;;;;
+0CAD;KANNADA LETTER BHA;Lo;0;L;;;;;N;;;;;
+0CAE;KANNADA LETTER MA;Lo;0;L;;;;;N;;;;;
+0CAF;KANNADA LETTER YA;Lo;0;L;;;;;N;;;;;
+0CB0;KANNADA LETTER RA;Lo;0;L;;;;;N;;;;;
+0CB1;KANNADA LETTER RRA;Lo;0;L;;;;;N;;;;;
+0CB2;KANNADA LETTER LA;Lo;0;L;;;;;N;;;;;
+0CB3;KANNADA LETTER LLA;Lo;0;L;;;;;N;;;;;
+0CB5;KANNADA LETTER VA;Lo;0;L;;;;;N;;;;;
+0CB6;KANNADA LETTER SHA;Lo;0;L;;;;;N;;;;;
+0CB7;KANNADA LETTER SSA;Lo;0;L;;;;;N;;;;;
+0CB8;KANNADA LETTER SA;Lo;0;L;;;;;N;;;;;
+0CB9;KANNADA LETTER HA;Lo;0;L;;;;;N;;;;;
+0CBC;KANNADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+0CBD;KANNADA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0CBE;KANNADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0CBF;KANNADA VOWEL SIGN I;Mn;0;L;;;;;N;;;;;
+0CC0;KANNADA VOWEL SIGN II;Mc;0;L;0CBF 0CD5;;;;N;;;;;
+0CC1;KANNADA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+0CC2;KANNADA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+0CC3;KANNADA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+0CC4;KANNADA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+0CC6;KANNADA VOWEL SIGN E;Mn;0;L;;;;;N;;;;;
+0CC7;KANNADA VOWEL SIGN EE;Mc;0;L;0CC6 0CD5;;;;N;;;;;
+0CC8;KANNADA VOWEL SIGN AI;Mc;0;L;0CC6 0CD6;;;;N;;;;;
+0CCA;KANNADA VOWEL SIGN O;Mc;0;L;0CC6 0CC2;;;;N;;;;;
+0CCB;KANNADA VOWEL SIGN OO;Mc;0;L;0CCA 0CD5;;;;N;;;;;
+0CCC;KANNADA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;;
+0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0CE2;KANNADA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0CE3;KANNADA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0CE6;KANNADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0CE7;KANNADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0CE8;KANNADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0CE9;KANNADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0CEA;KANNADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0CEB;KANNADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0CEC;KANNADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0CED;KANNADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0CEE;KANNADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+0CF2;KANNADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;;
+0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;;
+0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;;
+0D08;MALAYALAM LETTER II;Lo;0;L;;;;;N;;;;;
+0D09;MALAYALAM LETTER U;Lo;0;L;;;;;N;;;;;
+0D0A;MALAYALAM LETTER UU;Lo;0;L;;;;;N;;;;;
+0D0B;MALAYALAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+0D0C;MALAYALAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+0D0E;MALAYALAM LETTER E;Lo;0;L;;;;;N;;;;;
+0D0F;MALAYALAM LETTER EE;Lo;0;L;;;;;N;;;;;
+0D10;MALAYALAM LETTER AI;Lo;0;L;;;;;N;;;;;
+0D12;MALAYALAM LETTER O;Lo;0;L;;;;;N;;;;;
+0D13;MALAYALAM LETTER OO;Lo;0;L;;;;;N;;;;;
+0D14;MALAYALAM LETTER AU;Lo;0;L;;;;;N;;;;;
+0D15;MALAYALAM LETTER KA;Lo;0;L;;;;;N;;;;;
+0D16;MALAYALAM LETTER KHA;Lo;0;L;;;;;N;;;;;
+0D17;MALAYALAM LETTER GA;Lo;0;L;;;;;N;;;;;
+0D18;MALAYALAM LETTER GHA;Lo;0;L;;;;;N;;;;;
+0D19;MALAYALAM LETTER NGA;Lo;0;L;;;;;N;;;;;
+0D1A;MALAYALAM LETTER CA;Lo;0;L;;;;;N;;;;;
+0D1B;MALAYALAM LETTER CHA;Lo;0;L;;;;;N;;;;;
+0D1C;MALAYALAM LETTER JA;Lo;0;L;;;;;N;;;;;
+0D1D;MALAYALAM LETTER JHA;Lo;0;L;;;;;N;;;;;
+0D1E;MALAYALAM LETTER NYA;Lo;0;L;;;;;N;;;;;
+0D1F;MALAYALAM LETTER TTA;Lo;0;L;;;;;N;;;;;
+0D20;MALAYALAM LETTER TTHA;Lo;0;L;;;;;N;;;;;
+0D21;MALAYALAM LETTER DDA;Lo;0;L;;;;;N;;;;;
+0D22;MALAYALAM LETTER DDHA;Lo;0;L;;;;;N;;;;;
+0D23;MALAYALAM LETTER NNA;Lo;0;L;;;;;N;;;;;
+0D24;MALAYALAM LETTER TA;Lo;0;L;;;;;N;;;;;
+0D25;MALAYALAM LETTER THA;Lo;0;L;;;;;N;;;;;
+0D26;MALAYALAM LETTER DA;Lo;0;L;;;;;N;;;;;
+0D27;MALAYALAM LETTER DHA;Lo;0;L;;;;;N;;;;;
+0D28;MALAYALAM LETTER NA;Lo;0;L;;;;;N;;;;;
+0D29;MALAYALAM LETTER NNNA;Lo;0;L;;;;;N;;;;;
+0D2A;MALAYALAM LETTER PA;Lo;0;L;;;;;N;;;;;
+0D2B;MALAYALAM LETTER PHA;Lo;0;L;;;;;N;;;;;
+0D2C;MALAYALAM LETTER BA;Lo;0;L;;;;;N;;;;;
+0D2D;MALAYALAM LETTER BHA;Lo;0;L;;;;;N;;;;;
+0D2E;MALAYALAM LETTER MA;Lo;0;L;;;;;N;;;;;
+0D2F;MALAYALAM LETTER YA;Lo;0;L;;;;;N;;;;;
+0D30;MALAYALAM LETTER RA;Lo;0;L;;;;;N;;;;;
+0D31;MALAYALAM LETTER RRA;Lo;0;L;;;;;N;;;;;
+0D32;MALAYALAM LETTER LA;Lo;0;L;;;;;N;;;;;
+0D33;MALAYALAM LETTER LLA;Lo;0;L;;;;;N;;;;;
+0D34;MALAYALAM LETTER LLLA;Lo;0;L;;;;;N;;;;;
+0D35;MALAYALAM LETTER VA;Lo;0;L;;;;;N;;;;;
+0D36;MALAYALAM LETTER SHA;Lo;0;L;;;;;N;;;;;
+0D37;MALAYALAM LETTER SSA;Lo;0;L;;;;;N;;;;;
+0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;;
+0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;;
+0D3A;MALAYALAM LETTER TTTA;Lo;0;L;;;;;N;;;;;
+0D3D;MALAYALAM SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+0D40;MALAYALAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+0D41;MALAYALAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+0D42;MALAYALAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+0D43;MALAYALAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+0D44;MALAYALAM VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+0D46;MALAYALAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+0D47;MALAYALAM VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+0D48;MALAYALAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+0D4A;MALAYALAM VOWEL SIGN O;Mc;0;L;0D46 0D3E;;;;N;;;;;
+0D4B;MALAYALAM VOWEL SIGN OO;Mc;0;L;0D47 0D3E;;;;N;;;;;
+0D4C;MALAYALAM VOWEL SIGN AU;Mc;0;L;0D46 0D57;;;;N;;;;;
+0D4D;MALAYALAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0D4E;MALAYALAM LETTER DOT REPH;Lo;0;L;;;;;N;;;;;
+0D4F;MALAYALAM SIGN PARA;So;0;L;;;;;N;;;;;
+0D54;MALAYALAM LETTER CHILLU M;Lo;0;L;;;;;N;;;;;
+0D55;MALAYALAM LETTER CHILLU Y;Lo;0;L;;;;;N;;;;;
+0D56;MALAYALAM LETTER CHILLU LLL;Lo;0;L;;;;;N;;;;;
+0D57;MALAYALAM AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+0D58;MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;;
+0D59;MALAYALAM FRACTION ONE FORTIETH;No;0;L;;;;1/40;N;;;;;
+0D5A;MALAYALAM FRACTION THREE EIGHTIETHS;No;0;L;;;;3/80;N;;;;;
+0D5B;MALAYALAM FRACTION ONE TWENTIETH;No;0;L;;;;1/20;N;;;;;
+0D5C;MALAYALAM FRACTION ONE TENTH;No;0;L;;;;1/10;N;;;;;
+0D5D;MALAYALAM FRACTION THREE TWENTIETHS;No;0;L;;;;3/20;N;;;;;
+0D5E;MALAYALAM FRACTION ONE FIFTH;No;0;L;;;;1/5;N;;;;;
+0D5F;MALAYALAM LETTER ARCHAIC II;Lo;0;L;;;;;N;;;;;
+0D60;MALAYALAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+0D61;MALAYALAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+0D62;MALAYALAM VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+0D63;MALAYALAM VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+0D66;MALAYALAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0D67;MALAYALAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0D68;MALAYALAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0D69;MALAYALAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0D6A;MALAYALAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0D6B;MALAYALAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0D6C;MALAYALAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0D6D;MALAYALAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0D6E;MALAYALAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0D6F;MALAYALAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0D70;MALAYALAM NUMBER TEN;No;0;L;;;;10;N;;;;;
+0D71;MALAYALAM NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
+0D72;MALAYALAM NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
+0D73;MALAYALAM FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;
+0D74;MALAYALAM FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;
+0D75;MALAYALAM FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;
+0D76;MALAYALAM FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;;
+0D77;MALAYALAM FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;
+0D78;MALAYALAM FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;
+0D79;MALAYALAM DATE MARK;So;0;L;;;;;N;;;;;
+0D7A;MALAYALAM LETTER CHILLU NN;Lo;0;L;;;;;N;;;;;
+0D7B;MALAYALAM LETTER CHILLU N;Lo;0;L;;;;;N;;;;;
+0D7C;MALAYALAM LETTER CHILLU RR;Lo;0;L;;;;;N;;;;;
+0D7D;MALAYALAM LETTER CHILLU L;Lo;0;L;;;;;N;;;;;
+0D7E;MALAYALAM LETTER CHILLU LL;Lo;0;L;;;;;N;;;;;
+0D7F;MALAYALAM LETTER CHILLU K;Lo;0;L;;;;;N;;;;;
+0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;;
+0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;;
+0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;;
+0D86;SINHALA LETTER AAYANNA;Lo;0;L;;;;;N;;;;;
+0D87;SINHALA LETTER AEYANNA;Lo;0;L;;;;;N;;;;;
+0D88;SINHALA LETTER AEEYANNA;Lo;0;L;;;;;N;;;;;
+0D89;SINHALA LETTER IYANNA;Lo;0;L;;;;;N;;;;;
+0D8A;SINHALA LETTER IIYANNA;Lo;0;L;;;;;N;;;;;
+0D8B;SINHALA LETTER UYANNA;Lo;0;L;;;;;N;;;;;
+0D8C;SINHALA LETTER UUYANNA;Lo;0;L;;;;;N;;;;;
+0D8D;SINHALA LETTER IRUYANNA;Lo;0;L;;;;;N;;;;;
+0D8E;SINHALA LETTER IRUUYANNA;Lo;0;L;;;;;N;;;;;
+0D8F;SINHALA LETTER ILUYANNA;Lo;0;L;;;;;N;;;;;
+0D90;SINHALA LETTER ILUUYANNA;Lo;0;L;;;;;N;;;;;
+0D91;SINHALA LETTER EYANNA;Lo;0;L;;;;;N;;;;;
+0D92;SINHALA LETTER EEYANNA;Lo;0;L;;;;;N;;;;;
+0D93;SINHALA LETTER AIYANNA;Lo;0;L;;;;;N;;;;;
+0D94;SINHALA LETTER OYANNA;Lo;0;L;;;;;N;;;;;
+0D95;SINHALA LETTER OOYANNA;Lo;0;L;;;;;N;;;;;
+0D96;SINHALA LETTER AUYANNA;Lo;0;L;;;;;N;;;;;
+0D9A;SINHALA LETTER ALPAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;;
+0D9B;SINHALA LETTER MAHAAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;;
+0D9C;SINHALA LETTER ALPAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;;
+0D9D;SINHALA LETTER MAHAAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;;
+0D9E;SINHALA LETTER KANTAJA NAASIKYAYA;Lo;0;L;;;;;N;;;;;
+0D9F;SINHALA LETTER SANYAKA GAYANNA;Lo;0;L;;;;;N;;;;;
+0DA0;SINHALA LETTER ALPAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;;
+0DA1;SINHALA LETTER MAHAAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;;
+0DA2;SINHALA LETTER ALPAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;;
+0DA3;SINHALA LETTER MAHAAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;;
+0DA4;SINHALA LETTER TAALUJA NAASIKYAYA;Lo;0;L;;;;;N;;;;;
+0DA5;SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA;Lo;0;L;;;;;N;;;;;
+0DA6;SINHALA LETTER SANYAKA JAYANNA;Lo;0;L;;;;;N;;;;;
+0DA7;SINHALA LETTER ALPAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;;
+0DA8;SINHALA LETTER MAHAAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;;
+0DA9;SINHALA LETTER ALPAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;;
+0DAA;SINHALA LETTER MAHAAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;;
+0DAB;SINHALA LETTER MUURDHAJA NAYANNA;Lo;0;L;;;;;N;;;;;
+0DAC;SINHALA LETTER SANYAKA DDAYANNA;Lo;0;L;;;;;N;;;;;
+0DAD;SINHALA LETTER ALPAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;;
+0DAE;SINHALA LETTER MAHAAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;;
+0DAF;SINHALA LETTER ALPAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;;
+0DB0;SINHALA LETTER MAHAAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;;
+0DB1;SINHALA LETTER DANTAJA NAYANNA;Lo;0;L;;;;;N;;;;;
+0DB3;SINHALA LETTER SANYAKA DAYANNA;Lo;0;L;;;;;N;;;;;
+0DB4;SINHALA LETTER ALPAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;;
+0DB5;SINHALA LETTER MAHAAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;;
+0DB6;SINHALA LETTER ALPAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;;
+0DB7;SINHALA LETTER MAHAAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;;
+0DB8;SINHALA LETTER MAYANNA;Lo;0;L;;;;;N;;;;;
+0DB9;SINHALA LETTER AMBA BAYANNA;Lo;0;L;;;;;N;;;;;
+0DBA;SINHALA LETTER YAYANNA;Lo;0;L;;;;;N;;;;;
+0DBB;SINHALA LETTER RAYANNA;Lo;0;L;;;;;N;;;;;
+0DBD;SINHALA LETTER DANTAJA LAYANNA;Lo;0;L;;;;;N;;;;;
+0DC0;SINHALA LETTER VAYANNA;Lo;0;L;;;;;N;;;;;
+0DC1;SINHALA LETTER TAALUJA SAYANNA;Lo;0;L;;;;;N;;;;;
+0DC2;SINHALA LETTER MUURDHAJA SAYANNA;Lo;0;L;;;;;N;;;;;
+0DC3;SINHALA LETTER DANTAJA SAYANNA;Lo;0;L;;;;;N;;;;;
+0DC4;SINHALA LETTER HAYANNA;Lo;0;L;;;;;N;;;;;
+0DC5;SINHALA LETTER MUURDHAJA LAYANNA;Lo;0;L;;;;;N;;;;;
+0DC6;SINHALA LETTER FAYANNA;Lo;0;L;;;;;N;;;;;
+0DCA;SINHALA SIGN AL-LAKUNA;Mn;9;NSM;;;;;N;;;;;
+0DCF;SINHALA VOWEL SIGN AELA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD0;SINHALA VOWEL SIGN KETTI AEDA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD1;SINHALA VOWEL SIGN DIGA AEDA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD2;SINHALA VOWEL SIGN KETTI IS-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD3;SINHALA VOWEL SIGN DIGA IS-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD4;SINHALA VOWEL SIGN KETTI PAA-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD6;SINHALA VOWEL SIGN DIGA PAA-PILLA;Mn;0;NSM;;;;;N;;;;;
+0DD8;SINHALA VOWEL SIGN GAETTA-PILLA;Mc;0;L;;;;;N;;;;;
+0DD9;SINHALA VOWEL SIGN KOMBUVA;Mc;0;L;;;;;N;;;;;
+0DDA;SINHALA VOWEL SIGN DIGA KOMBUVA;Mc;0;L;0DD9 0DCA;;;;N;;;;;
+0DDB;SINHALA VOWEL SIGN KOMBU DEKA;Mc;0;L;;;;;N;;;;;
+0DDC;SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA;Mc;0;L;0DD9 0DCF;;;;N;;;;;
+0DDD;SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA;Mc;0;L;0DDC 0DCA;;;;N;;;;;
+0DDE;SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA;Mc;0;L;0DD9 0DDF;;;;N;;;;;
+0DDF;SINHALA VOWEL SIGN GAYANUKITTA;Mc;0;L;;;;;N;;;;;
+0DE6;SINHALA LITH DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0DE7;SINHALA LITH DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0DE8;SINHALA LITH DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0DE9;SINHALA LITH DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0DEA;SINHALA LITH DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0DEB;SINHALA LITH DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0DEC;SINHALA LITH DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0DED;SINHALA LITH DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0DEE;SINHALA LITH DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0DEF;SINHALA LITH DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0DF2;SINHALA VOWEL SIGN DIGA GAETTA-PILLA;Mc;0;L;;;;;N;;;;;
+0DF3;SINHALA VOWEL SIGN DIGA GAYANUKITTA;Mc;0;L;;;;;N;;;;;
+0DF4;SINHALA PUNCTUATION KUNDDALIYA;Po;0;L;;;;;N;;;;;
+0E01;THAI CHARACTER KO KAI;Lo;0;L;;;;;N;THAI LETTER KO KAI;;;;
+0E02;THAI CHARACTER KHO KHAI;Lo;0;L;;;;;N;THAI LETTER KHO KHAI;;;;
+0E03;THAI CHARACTER KHO KHUAT;Lo;0;L;;;;;N;THAI LETTER KHO KHUAT;;;;
+0E04;THAI CHARACTER KHO KHWAI;Lo;0;L;;;;;N;THAI LETTER KHO KHWAI;;;;
+0E05;THAI CHARACTER KHO KHON;Lo;0;L;;;;;N;THAI LETTER KHO KHON;;;;
+0E06;THAI CHARACTER KHO RAKHANG;Lo;0;L;;;;;N;THAI LETTER KHO RAKHANG;;;;
+0E07;THAI CHARACTER NGO NGU;Lo;0;L;;;;;N;THAI LETTER NGO NGU;;;;
+0E08;THAI CHARACTER CHO CHAN;Lo;0;L;;;;;N;THAI LETTER CHO CHAN;;;;
+0E09;THAI CHARACTER CHO CHING;Lo;0;L;;;;;N;THAI LETTER CHO CHING;;;;
+0E0A;THAI CHARACTER CHO CHANG;Lo;0;L;;;;;N;THAI LETTER CHO CHANG;;;;
+0E0B;THAI CHARACTER SO SO;Lo;0;L;;;;;N;THAI LETTER SO SO;;;;
+0E0C;THAI CHARACTER CHO CHOE;Lo;0;L;;;;;N;THAI LETTER CHO CHOE;;;;
+0E0D;THAI CHARACTER YO YING;Lo;0;L;;;;;N;THAI LETTER YO YING;;;;
+0E0E;THAI CHARACTER DO CHADA;Lo;0;L;;;;;N;THAI LETTER DO CHADA;;;;
+0E0F;THAI CHARACTER TO PATAK;Lo;0;L;;;;;N;THAI LETTER TO PATAK;;;;
+0E10;THAI CHARACTER THO THAN;Lo;0;L;;;;;N;THAI LETTER THO THAN;;;;
+0E11;THAI CHARACTER THO NANGMONTHO;Lo;0;L;;;;;N;THAI LETTER THO NANGMONTHO;;;;
+0E12;THAI CHARACTER THO PHUTHAO;Lo;0;L;;;;;N;THAI LETTER THO PHUTHAO;;;;
+0E13;THAI CHARACTER NO NEN;Lo;0;L;;;;;N;THAI LETTER NO NEN;;;;
+0E14;THAI CHARACTER DO DEK;Lo;0;L;;;;;N;THAI LETTER DO DEK;;;;
+0E15;THAI CHARACTER TO TAO;Lo;0;L;;;;;N;THAI LETTER TO TAO;;;;
+0E16;THAI CHARACTER THO THUNG;Lo;0;L;;;;;N;THAI LETTER THO THUNG;;;;
+0E17;THAI CHARACTER THO THAHAN;Lo;0;L;;;;;N;THAI LETTER THO THAHAN;;;;
+0E18;THAI CHARACTER THO THONG;Lo;0;L;;;;;N;THAI LETTER THO THONG;;;;
+0E19;THAI CHARACTER NO NU;Lo;0;L;;;;;N;THAI LETTER NO NU;;;;
+0E1A;THAI CHARACTER BO BAIMAI;Lo;0;L;;;;;N;THAI LETTER BO BAIMAI;;;;
+0E1B;THAI CHARACTER PO PLA;Lo;0;L;;;;;N;THAI LETTER PO PLA;;;;
+0E1C;THAI CHARACTER PHO PHUNG;Lo;0;L;;;;;N;THAI LETTER PHO PHUNG;;;;
+0E1D;THAI CHARACTER FO FA;Lo;0;L;;;;;N;THAI LETTER FO FA;;;;
+0E1E;THAI CHARACTER PHO PHAN;Lo;0;L;;;;;N;THAI LETTER PHO PHAN;;;;
+0E1F;THAI CHARACTER FO FAN;Lo;0;L;;;;;N;THAI LETTER FO FAN;;;;
+0E20;THAI CHARACTER PHO SAMPHAO;Lo;0;L;;;;;N;THAI LETTER PHO SAMPHAO;;;;
+0E21;THAI CHARACTER MO MA;Lo;0;L;;;;;N;THAI LETTER MO MA;;;;
+0E22;THAI CHARACTER YO YAK;Lo;0;L;;;;;N;THAI LETTER YO YAK;;;;
+0E23;THAI CHARACTER RO RUA;Lo;0;L;;;;;N;THAI LETTER RO RUA;;;;
+0E24;THAI CHARACTER RU;Lo;0;L;;;;;N;THAI LETTER RU;;;;
+0E25;THAI CHARACTER LO LING;Lo;0;L;;;;;N;THAI LETTER LO LING;;;;
+0E26;THAI CHARACTER LU;Lo;0;L;;;;;N;THAI LETTER LU;;;;
+0E27;THAI CHARACTER WO WAEN;Lo;0;L;;;;;N;THAI LETTER WO WAEN;;;;
+0E28;THAI CHARACTER SO SALA;Lo;0;L;;;;;N;THAI LETTER SO SALA;;;;
+0E29;THAI CHARACTER SO RUSI;Lo;0;L;;;;;N;THAI LETTER SO RUSI;;;;
+0E2A;THAI CHARACTER SO SUA;Lo;0;L;;;;;N;THAI LETTER SO SUA;;;;
+0E2B;THAI CHARACTER HO HIP;Lo;0;L;;;;;N;THAI LETTER HO HIP;;;;
+0E2C;THAI CHARACTER LO CHULA;Lo;0;L;;;;;N;THAI LETTER LO CHULA;;;;
+0E2D;THAI CHARACTER O ANG;Lo;0;L;;;;;N;THAI LETTER O ANG;;;;
+0E2E;THAI CHARACTER HO NOKHUK;Lo;0;L;;;;;N;THAI LETTER HO NOK HUK;;;;
+0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;;;;
+0E30;THAI CHARACTER SARA A;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA A;;;;
+0E31;THAI CHARACTER MAI HAN-AKAT;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI HAN-AKAT;;;;
+0E32;THAI CHARACTER SARA AA;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AA;;;;
+0E33;THAI CHARACTER SARA AM;Lo;0;L;<compat> 0E4D 0E32;;;;N;THAI VOWEL SIGN SARA AM;;;;
+0E34;THAI CHARACTER SARA I;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA I;;;;
+0E35;THAI CHARACTER SARA II;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA II;;;;
+0E36;THAI CHARACTER SARA UE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UE;;;;
+0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;;;;
+0E38;THAI CHARACTER SARA U;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA U;;;;
+0E39;THAI CHARACTER SARA UU;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA UU;;;;
+0E3A;THAI CHARACTER PHINTHU;Mn;9;NSM;;;;;N;THAI VOWEL SIGN PHINTHU;;;;
+0E3F;THAI CURRENCY SYMBOL BAHT;Sc;0;ET;;;;;N;THAI BAHT SIGN;;;;
+0E40;THAI CHARACTER SARA E;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA E;;;;
+0E41;THAI CHARACTER SARA AE;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AE;;;;
+0E42;THAI CHARACTER SARA O;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA O;;;;
+0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;;;;
+0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;;;;
+0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;;;;
+0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;;;;
+0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;;;;
+0E48;THAI CHARACTER MAI EK;Mn;107;NSM;;;;;N;THAI TONE MAI EK;;;;
+0E49;THAI CHARACTER MAI THO;Mn;107;NSM;;;;;N;THAI TONE MAI THO;;;;
+0E4A;THAI CHARACTER MAI TRI;Mn;107;NSM;;;;;N;THAI TONE MAI TRI;;;;
+0E4B;THAI CHARACTER MAI CHATTAWA;Mn;107;NSM;;;;;N;THAI TONE MAI CHATTAWA;;;;
+0E4C;THAI CHARACTER THANTHAKHAT;Mn;0;NSM;;;;;N;THAI THANTHAKHAT;;;;
+0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;;;;
+0E4E;THAI CHARACTER YAMAKKAN;Mn;0;NSM;;;;;N;THAI YAMAKKAN;;;;
+0E4F;THAI CHARACTER FONGMAN;Po;0;L;;;;;N;THAI FONGMAN;;;;
+0E50;THAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0E51;THAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0E52;THAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0E53;THAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0E54;THAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0E55;THAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0E56;THAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0E57;THAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0E58;THAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0E59;THAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0E5A;THAI CHARACTER ANGKHANKHU;Po;0;L;;;;;N;THAI ANGKHANKHU;;;;
+0E5B;THAI CHARACTER KHOMUT;Po;0;L;;;;;N;THAI KHOMUT;;;;
+0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;;
+0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;;
+0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;;
+0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;;
+0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;;
+0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;;
+0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;;
+0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;;
+0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;;
+0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;;
+0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;;
+0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;;
+0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;;
+0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;;
+0E9C;LAO LETTER PHO SUNG;Lo;0;L;;;;;N;;;;;
+0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;;
+0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;;
+0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;;
+0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;;
+0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;;
+0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;;
+0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;;
+0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;;
+0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;;
+0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;;
+0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;;
+0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;;
+0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;;
+0EB0;LAO VOWEL SIGN A;Lo;0;L;;;;;N;;;;;
+0EB1;LAO VOWEL SIGN MAI KAN;Mn;0;NSM;;;;;N;;;;;
+0EB2;LAO VOWEL SIGN AA;Lo;0;L;;;;;N;;;;;
+0EB3;LAO VOWEL SIGN AM;Lo;0;L;<compat> 0ECD 0EB2;;;;N;;;;;
+0EB4;LAO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+0EB5;LAO VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+0EB6;LAO VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;;
+0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;;
+0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;;
+0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;;
+0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;;
+0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;;
+0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;;
+0EC0;LAO VOWEL SIGN E;Lo;0;L;;;;;N;;;;;
+0EC1;LAO VOWEL SIGN EI;Lo;0;L;;;;;N;;;;;
+0EC2;LAO VOWEL SIGN O;Lo;0;L;;;;;N;;;;;
+0EC3;LAO VOWEL SIGN AY;Lo;0;L;;;;;N;;;;;
+0EC4;LAO VOWEL SIGN AI;Lo;0;L;;;;;N;;;;;
+0EC6;LAO KO LA;Lm;0;L;;;;;N;;;;;
+0EC8;LAO TONE MAI EK;Mn;122;NSM;;;;;N;;;;;
+0EC9;LAO TONE MAI THO;Mn;122;NSM;;;;;N;;;;;
+0ECA;LAO TONE MAI TI;Mn;122;NSM;;;;;N;;;;;
+0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;;
+0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;;
+0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;;
+0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0ED3;LAO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0ED4;LAO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0ED5;LAO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0ED6;LAO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0ED7;LAO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0ED8;LAO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0ED9;LAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0EDC;LAO HO NO;Lo;0;L;<compat> 0EAB 0E99;;;;N;;;;;
+0EDD;LAO HO MO;Lo;0;L;<compat> 0EAB 0EA1;;;;N;;;;;
+0EDE;LAO LETTER KHMU GO;Lo;0;L;;;;;N;;;;;
+0EDF;LAO LETTER KHMU NYO;Lo;0;L;;;;;N;;;;;
+0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;;
+0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;;;;
+0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;;;;
+0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;;;;
+0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;;;;
+0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;;
+0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;;;;
+0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;;;;
+0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;;;;
+0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;;;;
+0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;;;;
+0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;;;;
+0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L;<noBreak> 0F0B;;;;N;;;;;
+0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;;;;
+0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;;;;
+0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;;;;
+0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;;;;
+0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;;;;
+0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;;;;
+0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;;;;
+0F14;TIBETAN MARK GTER TSHEG;Po;0;L;;;;;N;TIBETAN COMMA;;;;
+0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;;;;
+0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;;;;
+0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;;;;
+0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;;;;
+0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;;;;
+0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;;;;
+0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;;;;
+0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;;;;
+0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;;;;
+0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;;;;
+0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;;;;
+0F20;TIBETAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+0F21;TIBETAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+0F22;TIBETAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+0F23;TIBETAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+0F24;TIBETAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+0F25;TIBETAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+0F26;TIBETAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+0F27;TIBETAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+0F28;TIBETAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+0F29;TIBETAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0F2A;TIBETAN DIGIT HALF ONE;No;0;L;;;;1/2;N;;;;;
+0F2B;TIBETAN DIGIT HALF TWO;No;0;L;;;;3/2;N;;;;;
+0F2C;TIBETAN DIGIT HALF THREE;No;0;L;;;;5/2;N;;;;;
+0F2D;TIBETAN DIGIT HALF FOUR;No;0;L;;;;7/2;N;;;;;
+0F2E;TIBETAN DIGIT HALF FIVE;No;0;L;;;;9/2;N;;;;;
+0F2F;TIBETAN DIGIT HALF SIX;No;0;L;;;;11/2;N;;;;;
+0F30;TIBETAN DIGIT HALF SEVEN;No;0;L;;;;13/2;N;;;;;
+0F31;TIBETAN DIGIT HALF EIGHT;No;0;L;;;;15/2;N;;;;;
+0F32;TIBETAN DIGIT HALF NINE;No;0;L;;;;17/2;N;;;;;
+0F33;TIBETAN DIGIT HALF ZERO;No;0;L;;;;-1/2;N;;;;;
+0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;;;;
+0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;;;;
+0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;;;;
+0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;;;;
+0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;;;;
+0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;;;;
+0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;Y;;;;;
+0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;Y;;;;;
+0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;Y;TIBETAN LEFT BRACE;;;;
+0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;Y;TIBETAN RIGHT BRACE;;;;
+0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;;;;
+0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;;;;
+0F40;TIBETAN LETTER KA;Lo;0;L;;;;;N;;;;;
+0F41;TIBETAN LETTER KHA;Lo;0;L;;;;;N;;;;;
+0F42;TIBETAN LETTER GA;Lo;0;L;;;;;N;;;;;
+0F43;TIBETAN LETTER GHA;Lo;0;L;0F42 0FB7;;;;N;;;;;
+0F44;TIBETAN LETTER NGA;Lo;0;L;;;;;N;;;;;
+0F45;TIBETAN LETTER CA;Lo;0;L;;;;;N;;;;;
+0F46;TIBETAN LETTER CHA;Lo;0;L;;;;;N;;;;;
+0F47;TIBETAN LETTER JA;Lo;0;L;;;;;N;;;;;
+0F49;TIBETAN LETTER NYA;Lo;0;L;;;;;N;;;;;
+0F4A;TIBETAN LETTER TTA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED TA;;;;
+0F4B;TIBETAN LETTER TTHA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED THA;;;;
+0F4C;TIBETAN LETTER DDA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED DA;;;;
+0F4D;TIBETAN LETTER DDHA;Lo;0;L;0F4C 0FB7;;;;N;;;;;
+0F4E;TIBETAN LETTER NNA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED NA;;;;
+0F4F;TIBETAN LETTER TA;Lo;0;L;;;;;N;;;;;
+0F50;TIBETAN LETTER THA;Lo;0;L;;;;;N;;;;;
+0F51;TIBETAN LETTER DA;Lo;0;L;;;;;N;;;;;
+0F52;TIBETAN LETTER DHA;Lo;0;L;0F51 0FB7;;;;N;;;;;
+0F53;TIBETAN LETTER NA;Lo;0;L;;;;;N;;;;;
+0F54;TIBETAN LETTER PA;Lo;0;L;;;;;N;;;;;
+0F55;TIBETAN LETTER PHA;Lo;0;L;;;;;N;;;;;
+0F56;TIBETAN LETTER BA;Lo;0;L;;;;;N;;;;;
+0F57;TIBETAN LETTER BHA;Lo;0;L;0F56 0FB7;;;;N;;;;;
+0F58;TIBETAN LETTER MA;Lo;0;L;;;;;N;;;;;
+0F59;TIBETAN LETTER TSA;Lo;0;L;;;;;N;;;;;
+0F5A;TIBETAN LETTER TSHA;Lo;0;L;;;;;N;;;;;
+0F5B;TIBETAN LETTER DZA;Lo;0;L;;;;;N;;;;;
+0F5C;TIBETAN LETTER DZHA;Lo;0;L;0F5B 0FB7;;;;N;;;;;
+0F5D;TIBETAN LETTER WA;Lo;0;L;;;;;N;;;;;
+0F5E;TIBETAN LETTER ZHA;Lo;0;L;;;;;N;;;;;
+0F5F;TIBETAN LETTER ZA;Lo;0;L;;;;;N;;;;;
+0F60;TIBETAN LETTER -A;Lo;0;L;;;;;N;TIBETAN LETTER AA;;;;
+0F61;TIBETAN LETTER YA;Lo;0;L;;;;;N;;;;;
+0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;;;;
+0F63;TIBETAN LETTER LA;Lo;0;L;;;;;N;;;;;
+0F64;TIBETAN LETTER SHA;Lo;0;L;;;;;N;;;;;
+0F65;TIBETAN LETTER SSA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED SHA;;;;
+0F66;TIBETAN LETTER SA;Lo;0;L;;;;;N;;;;;
+0F67;TIBETAN LETTER HA;Lo;0;L;;;;;N;;;;;
+0F68;TIBETAN LETTER A;Lo;0;L;;;;;N;;;;;
+0F69;TIBETAN LETTER KSSA;Lo;0;L;0F40 0FB5;;;;N;;;;;
+0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;;;;
+0F6B;TIBETAN LETTER KKA;Lo;0;L;;;;;N;;;;;
+0F6C;TIBETAN LETTER RRA;Lo;0;L;;;;;N;;;;;
+0F71;TIBETAN VOWEL SIGN AA;Mn;129;NSM;;;;;N;;;;;
+0F72;TIBETAN VOWEL SIGN I;Mn;130;NSM;;;;;N;;;;;
+0F73;TIBETAN VOWEL SIGN II;Mn;0;NSM;0F71 0F72;;;;N;;;;;
+0F74;TIBETAN VOWEL SIGN U;Mn;132;NSM;;;;;N;;;;;
+0F75;TIBETAN VOWEL SIGN UU;Mn;0;NSM;0F71 0F74;;;;N;;;;;
+0F76;TIBETAN VOWEL SIGN VOCALIC R;Mn;0;NSM;0FB2 0F80;;;;N;;;;;
+0F77;TIBETAN VOWEL SIGN VOCALIC RR;Mn;0;NSM;<compat> 0FB2 0F81;;;;N;;;;;
+0F78;TIBETAN VOWEL SIGN VOCALIC L;Mn;0;NSM;0FB3 0F80;;;;N;;;;;
+0F79;TIBETAN VOWEL SIGN VOCALIC LL;Mn;0;NSM;<compat> 0FB3 0F81;;;;N;;;;;
+0F7A;TIBETAN VOWEL SIGN E;Mn;130;NSM;;;;;N;;;;;
+0F7B;TIBETAN VOWEL SIGN EE;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AI;;;;
+0F7C;TIBETAN VOWEL SIGN O;Mn;130;NSM;;;;;N;;;;;
+0F7D;TIBETAN VOWEL SIGN OO;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AU;;;;
+0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;;;;
+0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;;;;
+0F80;TIBETAN VOWEL SIGN REVERSED I;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN SHORT I;;;;
+0F81;TIBETAN VOWEL SIGN REVERSED II;Mn;0;NSM;0F71 0F80;;;;N;;;;;
+0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;;;;
+0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;;;;
+0F84;TIBETAN MARK HALANTA;Mn;9;NSM;;;;;N;TIBETAN VIRAMA;;;;
+0F85;TIBETAN MARK PALUTA;Po;0;L;;;;;N;TIBETAN CHUCHENYIGE;;;;
+0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;;;;
+0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;;;;
+0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;;;;
+0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;;;;
+0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;;;;
+0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;;;;
+0F8C;TIBETAN SIGN INVERTED MCHU CAN;Lo;0;L;;;;;N;;;;;
+0F8D;TIBETAN SUBJOINED SIGN LCE TSA CAN;Mn;0;NSM;;;;;N;;;;;
+0F8E;TIBETAN SUBJOINED SIGN MCHU CAN;Mn;0;NSM;;;;;N;;;;;
+0F8F;TIBETAN SUBJOINED SIGN INVERTED MCHU CAN;Mn;0;NSM;;;;;N;;;;;
+0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;;
+0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;;
+0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;;
+0F93;TIBETAN SUBJOINED LETTER GHA;Mn;0;NSM;0F92 0FB7;;;;N;;;;;
+0F94;TIBETAN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;;
+0F95;TIBETAN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;;
+0F96;TIBETAN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;;
+0F97;TIBETAN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;;
+0F99;TIBETAN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;;
+0F9A;TIBETAN SUBJOINED LETTER TTA;Mn;0;NSM;;;;;N;;;;;
+0F9B;TIBETAN SUBJOINED LETTER TTHA;Mn;0;NSM;;;;;N;;;;;
+0F9C;TIBETAN SUBJOINED LETTER DDA;Mn;0;NSM;;;;;N;;;;;
+0F9D;TIBETAN SUBJOINED LETTER DDHA;Mn;0;NSM;0F9C 0FB7;;;;N;;;;;
+0F9E;TIBETAN SUBJOINED LETTER NNA;Mn;0;NSM;;;;;N;;;;;
+0F9F;TIBETAN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;;
+0FA0;TIBETAN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;;
+0FA1;TIBETAN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;;
+0FA2;TIBETAN SUBJOINED LETTER DHA;Mn;0;NSM;0FA1 0FB7;;;;N;;;;;
+0FA3;TIBETAN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;;
+0FA4;TIBETAN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;;
+0FA5;TIBETAN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;;
+0FA6;TIBETAN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;;
+0FA7;TIBETAN SUBJOINED LETTER BHA;Mn;0;NSM;0FA6 0FB7;;;;N;;;;;
+0FA8;TIBETAN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;;
+0FA9;TIBETAN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;;
+0FAA;TIBETAN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;;
+0FAB;TIBETAN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;;
+0FAC;TIBETAN SUBJOINED LETTER DZHA;Mn;0;NSM;0FAB 0FB7;;;;N;;;;;
+0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;;;;
+0FAE;TIBETAN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;;
+0FAF;TIBETAN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;;
+0FB0;TIBETAN SUBJOINED LETTER -A;Mn;0;NSM;;;;;N;;;;;
+0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;;;;
+0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;;;;
+0FB3;TIBETAN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;;
+0FB4;TIBETAN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;;
+0FB5;TIBETAN SUBJOINED LETTER SSA;Mn;0;NSM;;;;;N;;;;;
+0FB6;TIBETAN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;;
+0FB7;TIBETAN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;;
+0FB8;TIBETAN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;;
+0FB9;TIBETAN SUBJOINED LETTER KSSA;Mn;0;NSM;0F90 0FB5;;;;N;;;;;
+0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;;;;
+0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;;;;
+0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;;;;
+0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;;;;
+0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;;;;
+0FC0;TIBETAN CANTILLATION SIGN HEAVY BEAT;So;0;L;;;;;N;;;;;
+0FC1;TIBETAN CANTILLATION SIGN LIGHT BEAT;So;0;L;;;;;N;;;;;
+0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;;;;
+0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;;;;
+0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;;;;
+0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;;;;
+0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;;;;
+0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;;;;
+0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;;;;
+0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;;;;
+0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;;;;
+0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;;;;
+0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;;;;
+0FCE;TIBETAN SIGN RDEL NAG RDEL DKAR;So;0;L;;;;;N;;;;;
+0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;;;;
+0FD0;TIBETAN MARK BSKA- SHOG GI MGO RGYAN;Po;0;L;;;;;N;;;;;
+0FD1;TIBETAN MARK MNYAM YIG GI MGO RGYAN;Po;0;L;;;;;N;;;;;
+0FD2;TIBETAN MARK NYIS TSHEG;Po;0;L;;;;;N;;;;;
+0FD3;TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA;Po;0;L;;;;;N;;;;;
+0FD4;TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;;
+0FD5;RIGHT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;;
+0FD6;LEFT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;;
+0FD7;RIGHT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;;
+0FD8;LEFT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;;
+0FD9;TIBETAN MARK LEADING MCHAN RTAGS;Po;0;L;;;;;N;;;;;
+0FDA;TIBETAN MARK TRAILING MCHAN RTAGS;Po;0;L;;;;;N;;;;;
+1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;;
+1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;;
+1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;;
+1003;MYANMAR LETTER GHA;Lo;0;L;;;;;N;;;;;
+1004;MYANMAR LETTER NGA;Lo;0;L;;;;;N;;;;;
+1005;MYANMAR LETTER CA;Lo;0;L;;;;;N;;;;;
+1006;MYANMAR LETTER CHA;Lo;0;L;;;;;N;;;;;
+1007;MYANMAR LETTER JA;Lo;0;L;;;;;N;;;;;
+1008;MYANMAR LETTER JHA;Lo;0;L;;;;;N;;;;;
+1009;MYANMAR LETTER NYA;Lo;0;L;;;;;N;;;;;
+100A;MYANMAR LETTER NNYA;Lo;0;L;;;;;N;;;;;
+100B;MYANMAR LETTER TTA;Lo;0;L;;;;;N;;;;;
+100C;MYANMAR LETTER TTHA;Lo;0;L;;;;;N;;;;;
+100D;MYANMAR LETTER DDA;Lo;0;L;;;;;N;;;;;
+100E;MYANMAR LETTER DDHA;Lo;0;L;;;;;N;;;;;
+100F;MYANMAR LETTER NNA;Lo;0;L;;;;;N;;;;;
+1010;MYANMAR LETTER TA;Lo;0;L;;;;;N;;;;;
+1011;MYANMAR LETTER THA;Lo;0;L;;;;;N;;;;;
+1012;MYANMAR LETTER DA;Lo;0;L;;;;;N;;;;;
+1013;MYANMAR LETTER DHA;Lo;0;L;;;;;N;;;;;
+1014;MYANMAR LETTER NA;Lo;0;L;;;;;N;;;;;
+1015;MYANMAR LETTER PA;Lo;0;L;;;;;N;;;;;
+1016;MYANMAR LETTER PHA;Lo;0;L;;;;;N;;;;;
+1017;MYANMAR LETTER BA;Lo;0;L;;;;;N;;;;;
+1018;MYANMAR LETTER BHA;Lo;0;L;;;;;N;;;;;
+1019;MYANMAR LETTER MA;Lo;0;L;;;;;N;;;;;
+101A;MYANMAR LETTER YA;Lo;0;L;;;;;N;;;;;
+101B;MYANMAR LETTER RA;Lo;0;L;;;;;N;;;;;
+101C;MYANMAR LETTER LA;Lo;0;L;;;;;N;;;;;
+101D;MYANMAR LETTER WA;Lo;0;L;;;;;N;;;;;
+101E;MYANMAR LETTER SA;Lo;0;L;;;;;N;;;;;
+101F;MYANMAR LETTER HA;Lo;0;L;;;;;N;;;;;
+1020;MYANMAR LETTER LLA;Lo;0;L;;;;;N;;;;;
+1021;MYANMAR LETTER A;Lo;0;L;;;;;N;;;;;
+1022;MYANMAR LETTER SHAN A;Lo;0;L;;;;;N;;;;;
+1023;MYANMAR LETTER I;Lo;0;L;;;;;N;;;;;
+1024;MYANMAR LETTER II;Lo;0;L;;;;;N;;;;;
+1025;MYANMAR LETTER U;Lo;0;L;;;;;N;;;;;
+1026;MYANMAR LETTER UU;Lo;0;L;1025 102E;;;;N;;;;;
+1027;MYANMAR LETTER E;Lo;0;L;;;;;N;;;;;
+1028;MYANMAR LETTER MON E;Lo;0;L;;;;;N;;;;;
+1029;MYANMAR LETTER O;Lo;0;L;;;;;N;;;;;
+102A;MYANMAR LETTER AU;Lo;0;L;;;;;N;;;;;
+102B;MYANMAR VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;;
+102C;MYANMAR VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+102D;MYANMAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+102E;MYANMAR VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+102F;MYANMAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1030;MYANMAR VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1031;MYANMAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1032;MYANMAR VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+1033;MYANMAR VOWEL SIGN MON II;Mn;0;NSM;;;;;N;;;;;
+1034;MYANMAR VOWEL SIGN MON O;Mn;0;NSM;;;;;N;;;;;
+1035;MYANMAR VOWEL SIGN E ABOVE;Mn;0;NSM;;;;;N;;;;;
+1036;MYANMAR SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+1037;MYANMAR SIGN DOT BELOW;Mn;7;NSM;;;;;N;;;;;
+1038;MYANMAR SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+1039;MYANMAR SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+103A;MYANMAR SIGN ASAT;Mn;9;NSM;;;;;N;;;;;
+103B;MYANMAR CONSONANT SIGN MEDIAL YA;Mc;0;L;;;;;N;;;;;
+103C;MYANMAR CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;;
+103D;MYANMAR CONSONANT SIGN MEDIAL WA;Mn;0;NSM;;;;;N;;;;;
+103E;MYANMAR CONSONANT SIGN MEDIAL HA;Mn;0;NSM;;;;;N;;;;;
+103F;MYANMAR LETTER GREAT SA;Lo;0;L;;;;;N;;;;;
+1040;MYANMAR DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1041;MYANMAR DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1042;MYANMAR DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1043;MYANMAR DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1044;MYANMAR DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1045;MYANMAR DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1046;MYANMAR DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1047;MYANMAR DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1048;MYANMAR DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1049;MYANMAR DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+104A;MYANMAR SIGN LITTLE SECTION;Po;0;L;;;;;N;;;;;
+104B;MYANMAR SIGN SECTION;Po;0;L;;;;;N;;;;;
+104C;MYANMAR SYMBOL LOCATIVE;Po;0;L;;;;;N;;;;;
+104D;MYANMAR SYMBOL COMPLETED;Po;0;L;;;;;N;;;;;
+104E;MYANMAR SYMBOL AFOREMENTIONED;Po;0;L;;;;;N;;;;;
+104F;MYANMAR SYMBOL GENITIVE;Po;0;L;;;;;N;;;;;
+1050;MYANMAR LETTER SHA;Lo;0;L;;;;;N;;;;;
+1051;MYANMAR LETTER SSA;Lo;0;L;;;;;N;;;;;
+1052;MYANMAR LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+1053;MYANMAR LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+1054;MYANMAR LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1055;MYANMAR LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1056;MYANMAR VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+1057;MYANMAR VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+1058;MYANMAR VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+1059;MYANMAR VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+105A;MYANMAR LETTER MON NGA;Lo;0;L;;;;;N;;;;;
+105B;MYANMAR LETTER MON JHA;Lo;0;L;;;;;N;;;;;
+105C;MYANMAR LETTER MON BBA;Lo;0;L;;;;;N;;;;;
+105D;MYANMAR LETTER MON BBE;Lo;0;L;;;;;N;;;;;
+105E;MYANMAR CONSONANT SIGN MON MEDIAL NA;Mn;0;NSM;;;;;N;;;;;
+105F;MYANMAR CONSONANT SIGN MON MEDIAL MA;Mn;0;NSM;;;;;N;;;;;
+1060;MYANMAR CONSONANT SIGN MON MEDIAL LA;Mn;0;NSM;;;;;N;;;;;
+1061;MYANMAR LETTER SGAW KAREN SHA;Lo;0;L;;;;;N;;;;;
+1062;MYANMAR VOWEL SIGN SGAW KAREN EU;Mc;0;L;;;;;N;;;;;
+1063;MYANMAR TONE MARK SGAW KAREN HATHI;Mc;0;L;;;;;N;;;;;
+1064;MYANMAR TONE MARK SGAW KAREN KE PHO;Mc;0;L;;;;;N;;;;;
+1065;MYANMAR LETTER WESTERN PWO KAREN THA;Lo;0;L;;;;;N;;;;;
+1066;MYANMAR LETTER WESTERN PWO KAREN PWA;Lo;0;L;;;;;N;;;;;
+1067;MYANMAR VOWEL SIGN WESTERN PWO KAREN EU;Mc;0;L;;;;;N;;;;;
+1068;MYANMAR VOWEL SIGN WESTERN PWO KAREN UE;Mc;0;L;;;;;N;;;;;
+1069;MYANMAR SIGN WESTERN PWO KAREN TONE-1;Mc;0;L;;;;;N;;;;;
+106A;MYANMAR SIGN WESTERN PWO KAREN TONE-2;Mc;0;L;;;;;N;;;;;
+106B;MYANMAR SIGN WESTERN PWO KAREN TONE-3;Mc;0;L;;;;;N;;;;;
+106C;MYANMAR SIGN WESTERN PWO KAREN TONE-4;Mc;0;L;;;;;N;;;;;
+106D;MYANMAR SIGN WESTERN PWO KAREN TONE-5;Mc;0;L;;;;;N;;;;;
+106E;MYANMAR LETTER EASTERN PWO KAREN NNA;Lo;0;L;;;;;N;;;;;
+106F;MYANMAR LETTER EASTERN PWO KAREN YWA;Lo;0;L;;;;;N;;;;;
+1070;MYANMAR LETTER EASTERN PWO KAREN GHWA;Lo;0;L;;;;;N;;;;;
+1071;MYANMAR VOWEL SIGN GEBA KAREN I;Mn;0;NSM;;;;;N;;;;;
+1072;MYANMAR VOWEL SIGN KAYAH OE;Mn;0;NSM;;;;;N;;;;;
+1073;MYANMAR VOWEL SIGN KAYAH U;Mn;0;NSM;;;;;N;;;;;
+1074;MYANMAR VOWEL SIGN KAYAH EE;Mn;0;NSM;;;;;N;;;;;
+1075;MYANMAR LETTER SHAN KA;Lo;0;L;;;;;N;;;;;
+1076;MYANMAR LETTER SHAN KHA;Lo;0;L;;;;;N;;;;;
+1077;MYANMAR LETTER SHAN GA;Lo;0;L;;;;;N;;;;;
+1078;MYANMAR LETTER SHAN CA;Lo;0;L;;;;;N;;;;;
+1079;MYANMAR LETTER SHAN ZA;Lo;0;L;;;;;N;;;;;
+107A;MYANMAR LETTER SHAN NYA;Lo;0;L;;;;;N;;;;;
+107B;MYANMAR LETTER SHAN DA;Lo;0;L;;;;;N;;;;;
+107C;MYANMAR LETTER SHAN NA;Lo;0;L;;;;;N;;;;;
+107D;MYANMAR LETTER SHAN PHA;Lo;0;L;;;;;N;;;;;
+107E;MYANMAR LETTER SHAN FA;Lo;0;L;;;;;N;;;;;
+107F;MYANMAR LETTER SHAN BA;Lo;0;L;;;;;N;;;;;
+1080;MYANMAR LETTER SHAN THA;Lo;0;L;;;;;N;;;;;
+1081;MYANMAR LETTER SHAN HA;Lo;0;L;;;;;N;;;;;
+1082;MYANMAR CONSONANT SIGN SHAN MEDIAL WA;Mn;0;NSM;;;;;N;;;;;
+1083;MYANMAR VOWEL SIGN SHAN AA;Mc;0;L;;;;;N;;;;;
+1084;MYANMAR VOWEL SIGN SHAN E;Mc;0;L;;;;;N;;;;;
+1085;MYANMAR VOWEL SIGN SHAN E ABOVE;Mn;0;NSM;;;;;N;;;;;
+1086;MYANMAR VOWEL SIGN SHAN FINAL Y;Mn;0;NSM;;;;;N;;;;;
+1087;MYANMAR SIGN SHAN TONE-2;Mc;0;L;;;;;N;;;;;
+1088;MYANMAR SIGN SHAN TONE-3;Mc;0;L;;;;;N;;;;;
+1089;MYANMAR SIGN SHAN TONE-5;Mc;0;L;;;;;N;;;;;
+108A;MYANMAR SIGN SHAN TONE-6;Mc;0;L;;;;;N;;;;;
+108B;MYANMAR SIGN SHAN COUNCIL TONE-2;Mc;0;L;;;;;N;;;;;
+108C;MYANMAR SIGN SHAN COUNCIL TONE-3;Mc;0;L;;;;;N;;;;;
+108D;MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE;Mn;220;NSM;;;;;N;;;;;
+108E;MYANMAR LETTER RUMAI PALAUNG FA;Lo;0;L;;;;;N;;;;;
+108F;MYANMAR SIGN RUMAI PALAUNG TONE-5;Mc;0;L;;;;;N;;;;;
+1090;MYANMAR SHAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1091;MYANMAR SHAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1092;MYANMAR SHAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1093;MYANMAR SHAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1094;MYANMAR SHAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1095;MYANMAR SHAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1096;MYANMAR SHAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1097;MYANMAR SHAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1098;MYANMAR SHAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1099;MYANMAR SHAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+109A;MYANMAR SIGN KHAMTI TONE-1;Mc;0;L;;;;;N;;;;;
+109B;MYANMAR SIGN KHAMTI TONE-3;Mc;0;L;;;;;N;;;;;
+109C;MYANMAR VOWEL SIGN AITON A;Mc;0;L;;;;;N;;;;;
+109D;MYANMAR VOWEL SIGN AITON AI;Mn;0;NSM;;;;;N;;;;;
+109E;MYANMAR SYMBOL SHAN ONE;So;0;L;;;;;N;;;;;
+109F;MYANMAR SYMBOL SHAN EXCLAMATION;So;0;L;;;;;N;;;;;
+10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;;;2D00;
+10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;;;2D01;
+10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;;;2D02;
+10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;;;2D03;
+10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;2D04;
+10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;;;2D05;
+10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;;;2D06;
+10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;;;2D07;
+10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;;;2D08;
+10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;;;2D09;
+10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;;;2D0A;
+10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;;;2D0B;
+10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;;;2D0C;
+10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;;;2D0D;
+10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;;;2D0E;
+10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;;;2D0F;
+10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;;;2D10;
+10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;2D11;
+10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;;;2D12;
+10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;;;2D13;
+10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;;;2D14;
+10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;;;2D15;
+10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;;;2D16;
+10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;;;2D17;
+10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;;;2D18;
+10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;;;2D19;
+10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;;;2D1A;
+10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;;;2D1B;
+10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;;;2D1C;
+10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;;;2D1D;
+10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;;;2D1E;
+10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;;;2D1F;
+10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;;;2D20;
+10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;;;2D21;
+10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;;;2D22;
+10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;2D23;
+10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;2D24;
+10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;;;2D25;
+10C7;GEORGIAN CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;2D27;
+10CD;GEORGIAN CAPITAL LETTER AEN;Lu;0;L;;;;;N;;;;2D2D;
+10D0;GEORGIAN LETTER AN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;;;
+10D1;GEORGIAN LETTER BAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;;;
+10D2;GEORGIAN LETTER GAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;;;
+10D3;GEORGIAN LETTER DON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;;;
+10D4;GEORGIAN LETTER EN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;;;
+10D5;GEORGIAN LETTER VIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;;;
+10D6;GEORGIAN LETTER ZEN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;;;
+10D7;GEORGIAN LETTER TAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;;;
+10D8;GEORGIAN LETTER IN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;;;
+10D9;GEORGIAN LETTER KAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;;;
+10DA;GEORGIAN LETTER LAS;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;;;
+10DB;GEORGIAN LETTER MAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;;;
+10DC;GEORGIAN LETTER NAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;;;
+10DD;GEORGIAN LETTER ON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;;;
+10DE;GEORGIAN LETTER PAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;;;
+10DF;GEORGIAN LETTER ZHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;;;
+10E0;GEORGIAN LETTER RAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;;;
+10E1;GEORGIAN LETTER SAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;;;
+10E2;GEORGIAN LETTER TAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;;;
+10E3;GEORGIAN LETTER UN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;;;
+10E4;GEORGIAN LETTER PHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;;;
+10E5;GEORGIAN LETTER KHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;;;
+10E6;GEORGIAN LETTER GHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;;;
+10E7;GEORGIAN LETTER QAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;;;
+10E8;GEORGIAN LETTER SHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;;;
+10E9;GEORGIAN LETTER CHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;;;
+10EA;GEORGIAN LETTER CAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;;;
+10EB;GEORGIAN LETTER JIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;;;
+10EC;GEORGIAN LETTER CIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;;;
+10ED;GEORGIAN LETTER CHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;;;
+10EE;GEORGIAN LETTER XAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;;;
+10EF;GEORGIAN LETTER JHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;;;
+10F0;GEORGIAN LETTER HAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;;;
+10F1;GEORGIAN LETTER HE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;;;
+10F2;GEORGIAN LETTER HIE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;;;
+10F3;GEORGIAN LETTER WE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;;;
+10F4;GEORGIAN LETTER HAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;;;
+10F5;GEORGIAN LETTER HOE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;;;
+10F6;GEORGIAN LETTER FI;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;;;
+10F7;GEORGIAN LETTER YN;Lo;0;L;;;;;N;;;;;
+10F8;GEORGIAN LETTER ELIFI;Lo;0;L;;;;;N;;;;;
+10F9;GEORGIAN LETTER TURNED GAN;Lo;0;L;;;;;N;;;;;
+10FA;GEORGIAN LETTER AIN;Lo;0;L;;;;;N;;;;;
+10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;;
+10FC;MODIFIER LETTER GEORGIAN NAR;Lm;0;L;<super> 10DC;;;;N;;;;;
+10FD;GEORGIAN LETTER AEN;Lo;0;L;;;;;N;;;;;
+10FE;GEORGIAN LETTER HARD SIGN;Lo;0;L;;;;;N;;;;;
+10FF;GEORGIAN LETTER LABIAL SIGN;Lo;0;L;;;;;N;;;;;
+1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;;;;
+1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
+1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;;;;
+1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;;;;
+1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;;
+1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;;;;
+1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;;;;
+1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;;;;
+1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;;
+1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;;;;
+110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;;
+110B;HANGUL CHOSEONG IEUNG;Lo;0;L;;;;;N;;;;;
+110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;;;;
+110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;;
+110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;;;;
+110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;;;;
+1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;;;;
+1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;;;;
+1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;;;;
+1113;HANGUL CHOSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;;
+1114;HANGUL CHOSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;;
+1115;HANGUL CHOSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;;
+1116;HANGUL CHOSEONG NIEUN-PIEUP;Lo;0;L;;;;;N;;;;;
+1117;HANGUL CHOSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;;
+1118;HANGUL CHOSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;;
+1119;HANGUL CHOSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;;
+111A;HANGUL CHOSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;;
+111B;HANGUL CHOSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;;
+111C;HANGUL CHOSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;;
+111D;HANGUL CHOSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;;
+111E;HANGUL CHOSEONG PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;;
+111F;HANGUL CHOSEONG PIEUP-NIEUN;Lo;0;L;;;;;N;;;;;
+1120;HANGUL CHOSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;;
+1121;HANGUL CHOSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
+1122;HANGUL CHOSEONG PIEUP-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+1123;HANGUL CHOSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+1124;HANGUL CHOSEONG PIEUP-SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+1125;HANGUL CHOSEONG PIEUP-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+1126;HANGUL CHOSEONG PIEUP-SIOS-CIEUC;Lo;0;L;;;;;N;;;;;
+1127;HANGUL CHOSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;;
+1128;HANGUL CHOSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;;
+1129;HANGUL CHOSEONG PIEUP-THIEUTH;Lo;0;L;;;;;N;;;;;
+112A;HANGUL CHOSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;
+112B;HANGUL CHOSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+112C;HANGUL CHOSEONG KAPYEOUNSSANGPIEUP;Lo;0;L;;;;;N;;;;;
+112D;HANGUL CHOSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+112E;HANGUL CHOSEONG SIOS-NIEUN;Lo;0;L;;;;;N;;;;;
+112F;HANGUL CHOSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+1130;HANGUL CHOSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;;
+1131;HANGUL CHOSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;;
+1132;HANGUL CHOSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+1133;HANGUL CHOSEONG SIOS-PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;;
+1134;HANGUL CHOSEONG SIOS-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+1135;HANGUL CHOSEONG SIOS-IEUNG;Lo;0;L;;;;;N;;;;;
+1136;HANGUL CHOSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;;
+1137;HANGUL CHOSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;;
+1138;HANGUL CHOSEONG SIOS-KHIEUKH;Lo;0;L;;;;;N;;;;;
+1139;HANGUL CHOSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;;
+113A;HANGUL CHOSEONG SIOS-PHIEUPH;Lo;0;L;;;;;N;;;;;
+113B;HANGUL CHOSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;;
+113C;HANGUL CHOSEONG CHITUEUMSIOS;Lo;0;L;;;;;N;;;;;
+113D;HANGUL CHOSEONG CHITUEUMSSANGSIOS;Lo;0;L;;;;;N;;;;;
+113E;HANGUL CHOSEONG CEONGCHIEUMSIOS;Lo;0;L;;;;;N;;;;;
+113F;HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS;Lo;0;L;;;;;N;;;;;
+1140;HANGUL CHOSEONG PANSIOS;Lo;0;L;;;;;N;;;;;
+1141;HANGUL CHOSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;;
+1142;HANGUL CHOSEONG IEUNG-TIKEUT;Lo;0;L;;;;;N;;;;;
+1143;HANGUL CHOSEONG IEUNG-MIEUM;Lo;0;L;;;;;N;;;;;
+1144;HANGUL CHOSEONG IEUNG-PIEUP;Lo;0;L;;;;;N;;;;;
+1145;HANGUL CHOSEONG IEUNG-SIOS;Lo;0;L;;;;;N;;;;;
+1146;HANGUL CHOSEONG IEUNG-PANSIOS;Lo;0;L;;;;;N;;;;;
+1147;HANGUL CHOSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;;
+1148;HANGUL CHOSEONG IEUNG-CIEUC;Lo;0;L;;;;;N;;;;;
+1149;HANGUL CHOSEONG IEUNG-CHIEUCH;Lo;0;L;;;;;N;;;;;
+114A;HANGUL CHOSEONG IEUNG-THIEUTH;Lo;0;L;;;;;N;;;;;
+114B;HANGUL CHOSEONG IEUNG-PHIEUPH;Lo;0;L;;;;;N;;;;;
+114C;HANGUL CHOSEONG YESIEUNG;Lo;0;L;;;;;N;;;;;
+114D;HANGUL CHOSEONG CIEUC-IEUNG;Lo;0;L;;;;;N;;;;;
+114E;HANGUL CHOSEONG CHITUEUMCIEUC;Lo;0;L;;;;;N;;;;;
+114F;HANGUL CHOSEONG CHITUEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;;
+1150;HANGUL CHOSEONG CEONGCHIEUMCIEUC;Lo;0;L;;;;;N;;;;;
+1151;HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;;
+1152;HANGUL CHOSEONG CHIEUCH-KHIEUKH;Lo;0;L;;;;;N;;;;;
+1153;HANGUL CHOSEONG CHIEUCH-HIEUH;Lo;0;L;;;;;N;;;;;
+1154;HANGUL CHOSEONG CHITUEUMCHIEUCH;Lo;0;L;;;;;N;;;;;
+1155;HANGUL CHOSEONG CEONGCHIEUMCHIEUCH;Lo;0;L;;;;;N;;;;;
+1156;HANGUL CHOSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;;
+1157;HANGUL CHOSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;;
+1158;HANGUL CHOSEONG SSANGHIEUH;Lo;0;L;;;;;N;;;;;
+1159;HANGUL CHOSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;;
+115A;HANGUL CHOSEONG KIYEOK-TIKEUT;Lo;0;L;;;;;N;;;;;
+115B;HANGUL CHOSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;;
+115C;HANGUL CHOSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;;
+115D;HANGUL CHOSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;;
+115E;HANGUL CHOSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;;
+115F;HANGUL CHOSEONG FILLER;Lo;0;L;;;;;N;;;;;
+1160;HANGUL JUNGSEONG FILLER;Lo;0;L;;;;;N;;;;;
+1161;HANGUL JUNGSEONG A;Lo;0;L;;;;;N;;;;;
+1162;HANGUL JUNGSEONG AE;Lo;0;L;;;;;N;;;;;
+1163;HANGUL JUNGSEONG YA;Lo;0;L;;;;;N;;;;;
+1164;HANGUL JUNGSEONG YAE;Lo;0;L;;;;;N;;;;;
+1165;HANGUL JUNGSEONG EO;Lo;0;L;;;;;N;;;;;
+1166;HANGUL JUNGSEONG E;Lo;0;L;;;;;N;;;;;
+1167;HANGUL JUNGSEONG YEO;Lo;0;L;;;;;N;;;;;
+1168;HANGUL JUNGSEONG YE;Lo;0;L;;;;;N;;;;;
+1169;HANGUL JUNGSEONG O;Lo;0;L;;;;;N;;;;;
+116A;HANGUL JUNGSEONG WA;Lo;0;L;;;;;N;;;;;
+116B;HANGUL JUNGSEONG WAE;Lo;0;L;;;;;N;;;;;
+116C;HANGUL JUNGSEONG OE;Lo;0;L;;;;;N;;;;;
+116D;HANGUL JUNGSEONG YO;Lo;0;L;;;;;N;;;;;
+116E;HANGUL JUNGSEONG U;Lo;0;L;;;;;N;;;;;
+116F;HANGUL JUNGSEONG WEO;Lo;0;L;;;;;N;;;;;
+1170;HANGUL JUNGSEONG WE;Lo;0;L;;;;;N;;;;;
+1171;HANGUL JUNGSEONG WI;Lo;0;L;;;;;N;;;;;
+1172;HANGUL JUNGSEONG YU;Lo;0;L;;;;;N;;;;;
+1173;HANGUL JUNGSEONG EU;Lo;0;L;;;;;N;;;;;
+1174;HANGUL JUNGSEONG YI;Lo;0;L;;;;;N;;;;;
+1175;HANGUL JUNGSEONG I;Lo;0;L;;;;;N;;;;;
+1176;HANGUL JUNGSEONG A-O;Lo;0;L;;;;;N;;;;;
+1177;HANGUL JUNGSEONG A-U;Lo;0;L;;;;;N;;;;;
+1178;HANGUL JUNGSEONG YA-O;Lo;0;L;;;;;N;;;;;
+1179;HANGUL JUNGSEONG YA-YO;Lo;0;L;;;;;N;;;;;
+117A;HANGUL JUNGSEONG EO-O;Lo;0;L;;;;;N;;;;;
+117B;HANGUL JUNGSEONG EO-U;Lo;0;L;;;;;N;;;;;
+117C;HANGUL JUNGSEONG EO-EU;Lo;0;L;;;;;N;;;;;
+117D;HANGUL JUNGSEONG YEO-O;Lo;0;L;;;;;N;;;;;
+117E;HANGUL JUNGSEONG YEO-U;Lo;0;L;;;;;N;;;;;
+117F;HANGUL JUNGSEONG O-EO;Lo;0;L;;;;;N;;;;;
+1180;HANGUL JUNGSEONG O-E;Lo;0;L;;;;;N;;;;;
+1181;HANGUL JUNGSEONG O-YE;Lo;0;L;;;;;N;;;;;
+1182;HANGUL JUNGSEONG O-O;Lo;0;L;;;;;N;;;;;
+1183;HANGUL JUNGSEONG O-U;Lo;0;L;;;;;N;;;;;
+1184;HANGUL JUNGSEONG YO-YA;Lo;0;L;;;;;N;;;;;
+1185;HANGUL JUNGSEONG YO-YAE;Lo;0;L;;;;;N;;;;;
+1186;HANGUL JUNGSEONG YO-YEO;Lo;0;L;;;;;N;;;;;
+1187;HANGUL JUNGSEONG YO-O;Lo;0;L;;;;;N;;;;;
+1188;HANGUL JUNGSEONG YO-I;Lo;0;L;;;;;N;;;;;
+1189;HANGUL JUNGSEONG U-A;Lo;0;L;;;;;N;;;;;
+118A;HANGUL JUNGSEONG U-AE;Lo;0;L;;;;;N;;;;;
+118B;HANGUL JUNGSEONG U-EO-EU;Lo;0;L;;;;;N;;;;;
+118C;HANGUL JUNGSEONG U-YE;Lo;0;L;;;;;N;;;;;
+118D;HANGUL JUNGSEONG U-U;Lo;0;L;;;;;N;;;;;
+118E;HANGUL JUNGSEONG YU-A;Lo;0;L;;;;;N;;;;;
+118F;HANGUL JUNGSEONG YU-EO;Lo;0;L;;;;;N;;;;;
+1190;HANGUL JUNGSEONG YU-E;Lo;0;L;;;;;N;;;;;
+1191;HANGUL JUNGSEONG YU-YEO;Lo;0;L;;;;;N;;;;;
+1192;HANGUL JUNGSEONG YU-YE;Lo;0;L;;;;;N;;;;;
+1193;HANGUL JUNGSEONG YU-U;Lo;0;L;;;;;N;;;;;
+1194;HANGUL JUNGSEONG YU-I;Lo;0;L;;;;;N;;;;;
+1195;HANGUL JUNGSEONG EU-U;Lo;0;L;;;;;N;;;;;
+1196;HANGUL JUNGSEONG EU-EU;Lo;0;L;;;;;N;;;;;
+1197;HANGUL JUNGSEONG YI-U;Lo;0;L;;;;;N;;;;;
+1198;HANGUL JUNGSEONG I-A;Lo;0;L;;;;;N;;;;;
+1199;HANGUL JUNGSEONG I-YA;Lo;0;L;;;;;N;;;;;
+119A;HANGUL JUNGSEONG I-O;Lo;0;L;;;;;N;;;;;
+119B;HANGUL JUNGSEONG I-U;Lo;0;L;;;;;N;;;;;
+119C;HANGUL JUNGSEONG I-EU;Lo;0;L;;;;;N;;;;;
+119D;HANGUL JUNGSEONG I-ARAEA;Lo;0;L;;;;;N;;;;;
+119E;HANGUL JUNGSEONG ARAEA;Lo;0;L;;;;;N;;;;;
+119F;HANGUL JUNGSEONG ARAEA-EO;Lo;0;L;;;;;N;;;;;
+11A0;HANGUL JUNGSEONG ARAEA-U;Lo;0;L;;;;;N;;;;;
+11A1;HANGUL JUNGSEONG ARAEA-I;Lo;0;L;;;;;N;;;;;
+11A2;HANGUL JUNGSEONG SSANGARAEA;Lo;0;L;;;;;N;;;;;
+11A3;HANGUL JUNGSEONG A-EU;Lo;0;L;;;;;N;;;;;
+11A4;HANGUL JUNGSEONG YA-U;Lo;0;L;;;;;N;;;;;
+11A5;HANGUL JUNGSEONG YEO-YA;Lo;0;L;;;;;N;;;;;
+11A6;HANGUL JUNGSEONG O-YA;Lo;0;L;;;;;N;;;;;
+11A7;HANGUL JUNGSEONG O-YAE;Lo;0;L;;;;;N;;;;;
+11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;;;;
+11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
+11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;;;;
+11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;;;;
+11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;;
+11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;;
+11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;;;;
+11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;;;;
+11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;;
+11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;;
+11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;;
+11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;;
+11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;;;;
+11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;;
+11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;;
+11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;;;;
+11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;;;;
+11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
+11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;;;;
+11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;;
+11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;;;;
+11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;;;;
+11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;;;;
+11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;;;;
+11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;;;;
+11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;;;;
+11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;;;;
+11C3;HANGUL JONGSEONG KIYEOK-RIEUL;Lo;0;L;;;;;N;;;;;
+11C4;HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+11C5;HANGUL JONGSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;;
+11C6;HANGUL JONGSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;;
+11C7;HANGUL JONGSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;;
+11C8;HANGUL JONGSEONG NIEUN-PANSIOS;Lo;0;L;;;;;N;;;;;
+11C9;HANGUL JONGSEONG NIEUN-THIEUTH;Lo;0;L;;;;;N;;;;;
+11CA;HANGUL JONGSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;;
+11CB;HANGUL JONGSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;;
+11CC;HANGUL JONGSEONG RIEUL-KIYEOK-SIOS;Lo;0;L;;;;;N;;;;;
+11CD;HANGUL JONGSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;;
+11CE;HANGUL JONGSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;;
+11CF;HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH;Lo;0;L;;;;;N;;;;;
+11D0;HANGUL JONGSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;;
+11D1;HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;
+11D2;HANGUL JONGSEONG RIEUL-MIEUM-SIOS;Lo;0;L;;;;;N;;;;;
+11D3;HANGUL JONGSEONG RIEUL-PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
+11D4;HANGUL JONGSEONG RIEUL-PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;
+11D5;HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+11D6;HANGUL JONGSEONG RIEUL-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+11D7;HANGUL JONGSEONG RIEUL-PANSIOS;Lo;0;L;;;;;N;;;;;
+11D8;HANGUL JONGSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;;
+11D9;HANGUL JONGSEONG RIEUL-YEORINHIEUH;Lo;0;L;;;;;N;;;;;
+11DA;HANGUL JONGSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;
+11DB;HANGUL JONGSEONG MIEUM-RIEUL;Lo;0;L;;;;;N;;;;;
+11DC;HANGUL JONGSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;;
+11DD;HANGUL JONGSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;;
+11DE;HANGUL JONGSEONG MIEUM-SSANGSIOS;Lo;0;L;;;;;N;;;;;
+11DF;HANGUL JONGSEONG MIEUM-PANSIOS;Lo;0;L;;;;;N;;;;;
+11E0;HANGUL JONGSEONG MIEUM-CHIEUCH;Lo;0;L;;;;;N;;;;;
+11E1;HANGUL JONGSEONG MIEUM-HIEUH;Lo;0;L;;;;;N;;;;;
+11E2;HANGUL JONGSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;;
+11E3;HANGUL JONGSEONG PIEUP-RIEUL;Lo;0;L;;;;;N;;;;;
+11E4;HANGUL JONGSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;
+11E5;HANGUL JONGSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;
+11E6;HANGUL JONGSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+11E7;HANGUL JONGSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+11E8;HANGUL JONGSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+11E9;HANGUL JONGSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;;
+11EA;HANGUL JONGSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+11EB;HANGUL JONGSEONG PANSIOS;Lo;0;L;;;;;N;;;;;
+11EC;HANGUL JONGSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;;
+11ED;HANGUL JONGSEONG IEUNG-SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
+11EE;HANGUL JONGSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;;
+11EF;HANGUL JONGSEONG IEUNG-KHIEUKH;Lo;0;L;;;;;N;;;;;
+11F0;HANGUL JONGSEONG YESIEUNG;Lo;0;L;;;;;N;;;;;
+11F1;HANGUL JONGSEONG YESIEUNG-SIOS;Lo;0;L;;;;;N;;;;;
+11F2;HANGUL JONGSEONG YESIEUNG-PANSIOS;Lo;0;L;;;;;N;;;;;
+11F3;HANGUL JONGSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;;
+11F4;HANGUL JONGSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;;
+11F5;HANGUL JONGSEONG HIEUH-NIEUN;Lo;0;L;;;;;N;;;;;
+11F6;HANGUL JONGSEONG HIEUH-RIEUL;Lo;0;L;;;;;N;;;;;
+11F7;HANGUL JONGSEONG HIEUH-MIEUM;Lo;0;L;;;;;N;;;;;
+11F8;HANGUL JONGSEONG HIEUH-PIEUP;Lo;0;L;;;;;N;;;;;
+11F9;HANGUL JONGSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;;
+11FA;HANGUL JONGSEONG KIYEOK-NIEUN;Lo;0;L;;;;;N;;;;;
+11FB;HANGUL JONGSEONG KIYEOK-PIEUP;Lo;0;L;;;;;N;;;;;
+11FC;HANGUL JONGSEONG KIYEOK-CHIEUCH;Lo;0;L;;;;;N;;;;;
+11FD;HANGUL JONGSEONG KIYEOK-KHIEUKH;Lo;0;L;;;;;N;;;;;
+11FE;HANGUL JONGSEONG KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;;
+11FF;HANGUL JONGSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;;
+1200;ETHIOPIC SYLLABLE HA;Lo;0;L;;;;;N;;;;;
+1201;ETHIOPIC SYLLABLE HU;Lo;0;L;;;;;N;;;;;
+1202;ETHIOPIC SYLLABLE HI;Lo;0;L;;;;;N;;;;;
+1203;ETHIOPIC SYLLABLE HAA;Lo;0;L;;;;;N;;;;;
+1204;ETHIOPIC SYLLABLE HEE;Lo;0;L;;;;;N;;;;;
+1205;ETHIOPIC SYLLABLE HE;Lo;0;L;;;;;N;;;;;
+1206;ETHIOPIC SYLLABLE HO;Lo;0;L;;;;;N;;;;;
+1207;ETHIOPIC SYLLABLE HOA;Lo;0;L;;;;;N;;;;;
+1208;ETHIOPIC SYLLABLE LA;Lo;0;L;;;;;N;;;;;
+1209;ETHIOPIC SYLLABLE LU;Lo;0;L;;;;;N;;;;;
+120A;ETHIOPIC SYLLABLE LI;Lo;0;L;;;;;N;;;;;
+120B;ETHIOPIC SYLLABLE LAA;Lo;0;L;;;;;N;;;;;
+120C;ETHIOPIC SYLLABLE LEE;Lo;0;L;;;;;N;;;;;
+120D;ETHIOPIC SYLLABLE LE;Lo;0;L;;;;;N;;;;;
+120E;ETHIOPIC SYLLABLE LO;Lo;0;L;;;;;N;;;;;
+120F;ETHIOPIC SYLLABLE LWA;Lo;0;L;;;;;N;;;;;
+1210;ETHIOPIC SYLLABLE HHA;Lo;0;L;;;;;N;;;;;
+1211;ETHIOPIC SYLLABLE HHU;Lo;0;L;;;;;N;;;;;
+1212;ETHIOPIC SYLLABLE HHI;Lo;0;L;;;;;N;;;;;
+1213;ETHIOPIC SYLLABLE HHAA;Lo;0;L;;;;;N;;;;;
+1214;ETHIOPIC SYLLABLE HHEE;Lo;0;L;;;;;N;;;;;
+1215;ETHIOPIC SYLLABLE HHE;Lo;0;L;;;;;N;;;;;
+1216;ETHIOPIC SYLLABLE HHO;Lo;0;L;;;;;N;;;;;
+1217;ETHIOPIC SYLLABLE HHWA;Lo;0;L;;;;;N;;;;;
+1218;ETHIOPIC SYLLABLE MA;Lo;0;L;;;;;N;;;;;
+1219;ETHIOPIC SYLLABLE MU;Lo;0;L;;;;;N;;;;;
+121A;ETHIOPIC SYLLABLE MI;Lo;0;L;;;;;N;;;;;
+121B;ETHIOPIC SYLLABLE MAA;Lo;0;L;;;;;N;;;;;
+121C;ETHIOPIC SYLLABLE MEE;Lo;0;L;;;;;N;;;;;
+121D;ETHIOPIC SYLLABLE ME;Lo;0;L;;;;;N;;;;;
+121E;ETHIOPIC SYLLABLE MO;Lo;0;L;;;;;N;;;;;
+121F;ETHIOPIC SYLLABLE MWA;Lo;0;L;;;;;N;;;;;
+1220;ETHIOPIC SYLLABLE SZA;Lo;0;L;;;;;N;;;;;
+1221;ETHIOPIC SYLLABLE SZU;Lo;0;L;;;;;N;;;;;
+1222;ETHIOPIC SYLLABLE SZI;Lo;0;L;;;;;N;;;;;
+1223;ETHIOPIC SYLLABLE SZAA;Lo;0;L;;;;;N;;;;;
+1224;ETHIOPIC SYLLABLE SZEE;Lo;0;L;;;;;N;;;;;
+1225;ETHIOPIC SYLLABLE SZE;Lo;0;L;;;;;N;;;;;
+1226;ETHIOPIC SYLLABLE SZO;Lo;0;L;;;;;N;;;;;
+1227;ETHIOPIC SYLLABLE SZWA;Lo;0;L;;;;;N;;;;;
+1228;ETHIOPIC SYLLABLE RA;Lo;0;L;;;;;N;;;;;
+1229;ETHIOPIC SYLLABLE RU;Lo;0;L;;;;;N;;;;;
+122A;ETHIOPIC SYLLABLE RI;Lo;0;L;;;;;N;;;;;
+122B;ETHIOPIC SYLLABLE RAA;Lo;0;L;;;;;N;;;;;
+122C;ETHIOPIC SYLLABLE REE;Lo;0;L;;;;;N;;;;;
+122D;ETHIOPIC SYLLABLE RE;Lo;0;L;;;;;N;;;;;
+122E;ETHIOPIC SYLLABLE RO;Lo;0;L;;;;;N;;;;;
+122F;ETHIOPIC SYLLABLE RWA;Lo;0;L;;;;;N;;;;;
+1230;ETHIOPIC SYLLABLE SA;Lo;0;L;;;;;N;;;;;
+1231;ETHIOPIC SYLLABLE SU;Lo;0;L;;;;;N;;;;;
+1232;ETHIOPIC SYLLABLE SI;Lo;0;L;;;;;N;;;;;
+1233;ETHIOPIC SYLLABLE SAA;Lo;0;L;;;;;N;;;;;
+1234;ETHIOPIC SYLLABLE SEE;Lo;0;L;;;;;N;;;;;
+1235;ETHIOPIC SYLLABLE SE;Lo;0;L;;;;;N;;;;;
+1236;ETHIOPIC SYLLABLE SO;Lo;0;L;;;;;N;;;;;
+1237;ETHIOPIC SYLLABLE SWA;Lo;0;L;;;;;N;;;;;
+1238;ETHIOPIC SYLLABLE SHA;Lo;0;L;;;;;N;;;;;
+1239;ETHIOPIC SYLLABLE SHU;Lo;0;L;;;;;N;;;;;
+123A;ETHIOPIC SYLLABLE SHI;Lo;0;L;;;;;N;;;;;
+123B;ETHIOPIC SYLLABLE SHAA;Lo;0;L;;;;;N;;;;;
+123C;ETHIOPIC SYLLABLE SHEE;Lo;0;L;;;;;N;;;;;
+123D;ETHIOPIC SYLLABLE SHE;Lo;0;L;;;;;N;;;;;
+123E;ETHIOPIC SYLLABLE SHO;Lo;0;L;;;;;N;;;;;
+123F;ETHIOPIC SYLLABLE SHWA;Lo;0;L;;;;;N;;;;;
+1240;ETHIOPIC SYLLABLE QA;Lo;0;L;;;;;N;;;;;
+1241;ETHIOPIC SYLLABLE QU;Lo;0;L;;;;;N;;;;;
+1242;ETHIOPIC SYLLABLE QI;Lo;0;L;;;;;N;;;;;
+1243;ETHIOPIC SYLLABLE QAA;Lo;0;L;;;;;N;;;;;
+1244;ETHIOPIC SYLLABLE QEE;Lo;0;L;;;;;N;;;;;
+1245;ETHIOPIC SYLLABLE QE;Lo;0;L;;;;;N;;;;;
+1246;ETHIOPIC SYLLABLE QO;Lo;0;L;;;;;N;;;;;
+1247;ETHIOPIC SYLLABLE QOA;Lo;0;L;;;;;N;;;;;
+1248;ETHIOPIC SYLLABLE QWA;Lo;0;L;;;;;N;;;;;
+124A;ETHIOPIC SYLLABLE QWI;Lo;0;L;;;;;N;;;;;
+124B;ETHIOPIC SYLLABLE QWAA;Lo;0;L;;;;;N;;;;;
+124C;ETHIOPIC SYLLABLE QWEE;Lo;0;L;;;;;N;;;;;
+124D;ETHIOPIC SYLLABLE QWE;Lo;0;L;;;;;N;;;;;
+1250;ETHIOPIC SYLLABLE QHA;Lo;0;L;;;;;N;;;;;
+1251;ETHIOPIC SYLLABLE QHU;Lo;0;L;;;;;N;;;;;
+1252;ETHIOPIC SYLLABLE QHI;Lo;0;L;;;;;N;;;;;
+1253;ETHIOPIC SYLLABLE QHAA;Lo;0;L;;;;;N;;;;;
+1254;ETHIOPIC SYLLABLE QHEE;Lo;0;L;;;;;N;;;;;
+1255;ETHIOPIC SYLLABLE QHE;Lo;0;L;;;;;N;;;;;
+1256;ETHIOPIC SYLLABLE QHO;Lo;0;L;;;;;N;;;;;
+1258;ETHIOPIC SYLLABLE QHWA;Lo;0;L;;;;;N;;;;;
+125A;ETHIOPIC SYLLABLE QHWI;Lo;0;L;;;;;N;;;;;
+125B;ETHIOPIC SYLLABLE QHWAA;Lo;0;L;;;;;N;;;;;
+125C;ETHIOPIC SYLLABLE QHWEE;Lo;0;L;;;;;N;;;;;
+125D;ETHIOPIC SYLLABLE QHWE;Lo;0;L;;;;;N;;;;;
+1260;ETHIOPIC SYLLABLE BA;Lo;0;L;;;;;N;;;;;
+1261;ETHIOPIC SYLLABLE BU;Lo;0;L;;;;;N;;;;;
+1262;ETHIOPIC SYLLABLE BI;Lo;0;L;;;;;N;;;;;
+1263;ETHIOPIC SYLLABLE BAA;Lo;0;L;;;;;N;;;;;
+1264;ETHIOPIC SYLLABLE BEE;Lo;0;L;;;;;N;;;;;
+1265;ETHIOPIC SYLLABLE BE;Lo;0;L;;;;;N;;;;;
+1266;ETHIOPIC SYLLABLE BO;Lo;0;L;;;;;N;;;;;
+1267;ETHIOPIC SYLLABLE BWA;Lo;0;L;;;;;N;;;;;
+1268;ETHIOPIC SYLLABLE VA;Lo;0;L;;;;;N;;;;;
+1269;ETHIOPIC SYLLABLE VU;Lo;0;L;;;;;N;;;;;
+126A;ETHIOPIC SYLLABLE VI;Lo;0;L;;;;;N;;;;;
+126B;ETHIOPIC SYLLABLE VAA;Lo;0;L;;;;;N;;;;;
+126C;ETHIOPIC SYLLABLE VEE;Lo;0;L;;;;;N;;;;;
+126D;ETHIOPIC SYLLABLE VE;Lo;0;L;;;;;N;;;;;
+126E;ETHIOPIC SYLLABLE VO;Lo;0;L;;;;;N;;;;;
+126F;ETHIOPIC SYLLABLE VWA;Lo;0;L;;;;;N;;;;;
+1270;ETHIOPIC SYLLABLE TA;Lo;0;L;;;;;N;;;;;
+1271;ETHIOPIC SYLLABLE TU;Lo;0;L;;;;;N;;;;;
+1272;ETHIOPIC SYLLABLE TI;Lo;0;L;;;;;N;;;;;
+1273;ETHIOPIC SYLLABLE TAA;Lo;0;L;;;;;N;;;;;
+1274;ETHIOPIC SYLLABLE TEE;Lo;0;L;;;;;N;;;;;
+1275;ETHIOPIC SYLLABLE TE;Lo;0;L;;;;;N;;;;;
+1276;ETHIOPIC SYLLABLE TO;Lo;0;L;;;;;N;;;;;
+1277;ETHIOPIC SYLLABLE TWA;Lo;0;L;;;;;N;;;;;
+1278;ETHIOPIC SYLLABLE CA;Lo;0;L;;;;;N;;;;;
+1279;ETHIOPIC SYLLABLE CU;Lo;0;L;;;;;N;;;;;
+127A;ETHIOPIC SYLLABLE CI;Lo;0;L;;;;;N;;;;;
+127B;ETHIOPIC SYLLABLE CAA;Lo;0;L;;;;;N;;;;;
+127C;ETHIOPIC SYLLABLE CEE;Lo;0;L;;;;;N;;;;;
+127D;ETHIOPIC SYLLABLE CE;Lo;0;L;;;;;N;;;;;
+127E;ETHIOPIC SYLLABLE CO;Lo;0;L;;;;;N;;;;;
+127F;ETHIOPIC SYLLABLE CWA;Lo;0;L;;;;;N;;;;;
+1280;ETHIOPIC SYLLABLE XA;Lo;0;L;;;;;N;;;;;
+1281;ETHIOPIC SYLLABLE XU;Lo;0;L;;;;;N;;;;;
+1282;ETHIOPIC SYLLABLE XI;Lo;0;L;;;;;N;;;;;
+1283;ETHIOPIC SYLLABLE XAA;Lo;0;L;;;;;N;;;;;
+1284;ETHIOPIC SYLLABLE XEE;Lo;0;L;;;;;N;;;;;
+1285;ETHIOPIC SYLLABLE XE;Lo;0;L;;;;;N;;;;;
+1286;ETHIOPIC SYLLABLE XO;Lo;0;L;;;;;N;;;;;
+1287;ETHIOPIC SYLLABLE XOA;Lo;0;L;;;;;N;;;;;
+1288;ETHIOPIC SYLLABLE XWA;Lo;0;L;;;;;N;;;;;
+128A;ETHIOPIC SYLLABLE XWI;Lo;0;L;;;;;N;;;;;
+128B;ETHIOPIC SYLLABLE XWAA;Lo;0;L;;;;;N;;;;;
+128C;ETHIOPIC SYLLABLE XWEE;Lo;0;L;;;;;N;;;;;
+128D;ETHIOPIC SYLLABLE XWE;Lo;0;L;;;;;N;;;;;
+1290;ETHIOPIC SYLLABLE NA;Lo;0;L;;;;;N;;;;;
+1291;ETHIOPIC SYLLABLE NU;Lo;0;L;;;;;N;;;;;
+1292;ETHIOPIC SYLLABLE NI;Lo;0;L;;;;;N;;;;;
+1293;ETHIOPIC SYLLABLE NAA;Lo;0;L;;;;;N;;;;;
+1294;ETHIOPIC SYLLABLE NEE;Lo;0;L;;;;;N;;;;;
+1295;ETHIOPIC SYLLABLE NE;Lo;0;L;;;;;N;;;;;
+1296;ETHIOPIC SYLLABLE NO;Lo;0;L;;;;;N;;;;;
+1297;ETHIOPIC SYLLABLE NWA;Lo;0;L;;;;;N;;;;;
+1298;ETHIOPIC SYLLABLE NYA;Lo;0;L;;;;;N;;;;;
+1299;ETHIOPIC SYLLABLE NYU;Lo;0;L;;;;;N;;;;;
+129A;ETHIOPIC SYLLABLE NYI;Lo;0;L;;;;;N;;;;;
+129B;ETHIOPIC SYLLABLE NYAA;Lo;0;L;;;;;N;;;;;
+129C;ETHIOPIC SYLLABLE NYEE;Lo;0;L;;;;;N;;;;;
+129D;ETHIOPIC SYLLABLE NYE;Lo;0;L;;;;;N;;;;;
+129E;ETHIOPIC SYLLABLE NYO;Lo;0;L;;;;;N;;;;;
+129F;ETHIOPIC SYLLABLE NYWA;Lo;0;L;;;;;N;;;;;
+12A0;ETHIOPIC SYLLABLE GLOTTAL A;Lo;0;L;;;;;N;;;;;
+12A1;ETHIOPIC SYLLABLE GLOTTAL U;Lo;0;L;;;;;N;;;;;
+12A2;ETHIOPIC SYLLABLE GLOTTAL I;Lo;0;L;;;;;N;;;;;
+12A3;ETHIOPIC SYLLABLE GLOTTAL AA;Lo;0;L;;;;;N;;;;;
+12A4;ETHIOPIC SYLLABLE GLOTTAL EE;Lo;0;L;;;;;N;;;;;
+12A5;ETHIOPIC SYLLABLE GLOTTAL E;Lo;0;L;;;;;N;;;;;
+12A6;ETHIOPIC SYLLABLE GLOTTAL O;Lo;0;L;;;;;N;;;;;
+12A7;ETHIOPIC SYLLABLE GLOTTAL WA;Lo;0;L;;;;;N;;;;;
+12A8;ETHIOPIC SYLLABLE KA;Lo;0;L;;;;;N;;;;;
+12A9;ETHIOPIC SYLLABLE KU;Lo;0;L;;;;;N;;;;;
+12AA;ETHIOPIC SYLLABLE KI;Lo;0;L;;;;;N;;;;;
+12AB;ETHIOPIC SYLLABLE KAA;Lo;0;L;;;;;N;;;;;
+12AC;ETHIOPIC SYLLABLE KEE;Lo;0;L;;;;;N;;;;;
+12AD;ETHIOPIC SYLLABLE KE;Lo;0;L;;;;;N;;;;;
+12AE;ETHIOPIC SYLLABLE KO;Lo;0;L;;;;;N;;;;;
+12AF;ETHIOPIC SYLLABLE KOA;Lo;0;L;;;;;N;;;;;
+12B0;ETHIOPIC SYLLABLE KWA;Lo;0;L;;;;;N;;;;;
+12B2;ETHIOPIC SYLLABLE KWI;Lo;0;L;;;;;N;;;;;
+12B3;ETHIOPIC SYLLABLE KWAA;Lo;0;L;;;;;N;;;;;
+12B4;ETHIOPIC SYLLABLE KWEE;Lo;0;L;;;;;N;;;;;
+12B5;ETHIOPIC SYLLABLE KWE;Lo;0;L;;;;;N;;;;;
+12B8;ETHIOPIC SYLLABLE KXA;Lo;0;L;;;;;N;;;;;
+12B9;ETHIOPIC SYLLABLE KXU;Lo;0;L;;;;;N;;;;;
+12BA;ETHIOPIC SYLLABLE KXI;Lo;0;L;;;;;N;;;;;
+12BB;ETHIOPIC SYLLABLE KXAA;Lo;0;L;;;;;N;;;;;
+12BC;ETHIOPIC SYLLABLE KXEE;Lo;0;L;;;;;N;;;;;
+12BD;ETHIOPIC SYLLABLE KXE;Lo;0;L;;;;;N;;;;;
+12BE;ETHIOPIC SYLLABLE KXO;Lo;0;L;;;;;N;;;;;
+12C0;ETHIOPIC SYLLABLE KXWA;Lo;0;L;;;;;N;;;;;
+12C2;ETHIOPIC SYLLABLE KXWI;Lo;0;L;;;;;N;;;;;
+12C3;ETHIOPIC SYLLABLE KXWAA;Lo;0;L;;;;;N;;;;;
+12C4;ETHIOPIC SYLLABLE KXWEE;Lo;0;L;;;;;N;;;;;
+12C5;ETHIOPIC SYLLABLE KXWE;Lo;0;L;;;;;N;;;;;
+12C8;ETHIOPIC SYLLABLE WA;Lo;0;L;;;;;N;;;;;
+12C9;ETHIOPIC SYLLABLE WU;Lo;0;L;;;;;N;;;;;
+12CA;ETHIOPIC SYLLABLE WI;Lo;0;L;;;;;N;;;;;
+12CB;ETHIOPIC SYLLABLE WAA;Lo;0;L;;;;;N;;;;;
+12CC;ETHIOPIC SYLLABLE WEE;Lo;0;L;;;;;N;;;;;
+12CD;ETHIOPIC SYLLABLE WE;Lo;0;L;;;;;N;;;;;
+12CE;ETHIOPIC SYLLABLE WO;Lo;0;L;;;;;N;;;;;
+12CF;ETHIOPIC SYLLABLE WOA;Lo;0;L;;;;;N;;;;;
+12D0;ETHIOPIC SYLLABLE PHARYNGEAL A;Lo;0;L;;;;;N;;;;;
+12D1;ETHIOPIC SYLLABLE PHARYNGEAL U;Lo;0;L;;;;;N;;;;;
+12D2;ETHIOPIC SYLLABLE PHARYNGEAL I;Lo;0;L;;;;;N;;;;;
+12D3;ETHIOPIC SYLLABLE PHARYNGEAL AA;Lo;0;L;;;;;N;;;;;
+12D4;ETHIOPIC SYLLABLE PHARYNGEAL EE;Lo;0;L;;;;;N;;;;;
+12D5;ETHIOPIC SYLLABLE PHARYNGEAL E;Lo;0;L;;;;;N;;;;;
+12D6;ETHIOPIC SYLLABLE PHARYNGEAL O;Lo;0;L;;;;;N;;;;;
+12D8;ETHIOPIC SYLLABLE ZA;Lo;0;L;;;;;N;;;;;
+12D9;ETHIOPIC SYLLABLE ZU;Lo;0;L;;;;;N;;;;;
+12DA;ETHIOPIC SYLLABLE ZI;Lo;0;L;;;;;N;;;;;
+12DB;ETHIOPIC SYLLABLE ZAA;Lo;0;L;;;;;N;;;;;
+12DC;ETHIOPIC SYLLABLE ZEE;Lo;0;L;;;;;N;;;;;
+12DD;ETHIOPIC SYLLABLE ZE;Lo;0;L;;;;;N;;;;;
+12DE;ETHIOPIC SYLLABLE ZO;Lo;0;L;;;;;N;;;;;
+12DF;ETHIOPIC SYLLABLE ZWA;Lo;0;L;;;;;N;;;;;
+12E0;ETHIOPIC SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;
+12E1;ETHIOPIC SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;
+12E2;ETHIOPIC SYLLABLE ZHI;Lo;0;L;;;;;N;;;;;
+12E3;ETHIOPIC SYLLABLE ZHAA;Lo;0;L;;;;;N;;;;;
+12E4;ETHIOPIC SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;;
+12E5;ETHIOPIC SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;
+12E6;ETHIOPIC SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;
+12E7;ETHIOPIC SYLLABLE ZHWA;Lo;0;L;;;;;N;;;;;
+12E8;ETHIOPIC SYLLABLE YA;Lo;0;L;;;;;N;;;;;
+12E9;ETHIOPIC SYLLABLE YU;Lo;0;L;;;;;N;;;;;
+12EA;ETHIOPIC SYLLABLE YI;Lo;0;L;;;;;N;;;;;
+12EB;ETHIOPIC SYLLABLE YAA;Lo;0;L;;;;;N;;;;;
+12EC;ETHIOPIC SYLLABLE YEE;Lo;0;L;;;;;N;;;;;
+12ED;ETHIOPIC SYLLABLE YE;Lo;0;L;;;;;N;;;;;
+12EE;ETHIOPIC SYLLABLE YO;Lo;0;L;;;;;N;;;;;
+12EF;ETHIOPIC SYLLABLE YOA;Lo;0;L;;;;;N;;;;;
+12F0;ETHIOPIC SYLLABLE DA;Lo;0;L;;;;;N;;;;;
+12F1;ETHIOPIC SYLLABLE DU;Lo;0;L;;;;;N;;;;;
+12F2;ETHIOPIC SYLLABLE DI;Lo;0;L;;;;;N;;;;;
+12F3;ETHIOPIC SYLLABLE DAA;Lo;0;L;;;;;N;;;;;
+12F4;ETHIOPIC SYLLABLE DEE;Lo;0;L;;;;;N;;;;;
+12F5;ETHIOPIC SYLLABLE DE;Lo;0;L;;;;;N;;;;;
+12F6;ETHIOPIC SYLLABLE DO;Lo;0;L;;;;;N;;;;;
+12F7;ETHIOPIC SYLLABLE DWA;Lo;0;L;;;;;N;;;;;
+12F8;ETHIOPIC SYLLABLE DDA;Lo;0;L;;;;;N;;;;;
+12F9;ETHIOPIC SYLLABLE DDU;Lo;0;L;;;;;N;;;;;
+12FA;ETHIOPIC SYLLABLE DDI;Lo;0;L;;;;;N;;;;;
+12FB;ETHIOPIC SYLLABLE DDAA;Lo;0;L;;;;;N;;;;;
+12FC;ETHIOPIC SYLLABLE DDEE;Lo;0;L;;;;;N;;;;;
+12FD;ETHIOPIC SYLLABLE DDE;Lo;0;L;;;;;N;;;;;
+12FE;ETHIOPIC SYLLABLE DDO;Lo;0;L;;;;;N;;;;;
+12FF;ETHIOPIC SYLLABLE DDWA;Lo;0;L;;;;;N;;;;;
+1300;ETHIOPIC SYLLABLE JA;Lo;0;L;;;;;N;;;;;
+1301;ETHIOPIC SYLLABLE JU;Lo;0;L;;;;;N;;;;;
+1302;ETHIOPIC SYLLABLE JI;Lo;0;L;;;;;N;;;;;
+1303;ETHIOPIC SYLLABLE JAA;Lo;0;L;;;;;N;;;;;
+1304;ETHIOPIC SYLLABLE JEE;Lo;0;L;;;;;N;;;;;
+1305;ETHIOPIC SYLLABLE JE;Lo;0;L;;;;;N;;;;;
+1306;ETHIOPIC SYLLABLE JO;Lo;0;L;;;;;N;;;;;
+1307;ETHIOPIC SYLLABLE JWA;Lo;0;L;;;;;N;;;;;
+1308;ETHIOPIC SYLLABLE GA;Lo;0;L;;;;;N;;;;;
+1309;ETHIOPIC SYLLABLE GU;Lo;0;L;;;;;N;;;;;
+130A;ETHIOPIC SYLLABLE GI;Lo;0;L;;;;;N;;;;;
+130B;ETHIOPIC SYLLABLE GAA;Lo;0;L;;;;;N;;;;;
+130C;ETHIOPIC SYLLABLE GEE;Lo;0;L;;;;;N;;;;;
+130D;ETHIOPIC SYLLABLE GE;Lo;0;L;;;;;N;;;;;
+130E;ETHIOPIC SYLLABLE GO;Lo;0;L;;;;;N;;;;;
+130F;ETHIOPIC SYLLABLE GOA;Lo;0;L;;;;;N;;;;;
+1310;ETHIOPIC SYLLABLE GWA;Lo;0;L;;;;;N;;;;;
+1312;ETHIOPIC SYLLABLE GWI;Lo;0;L;;;;;N;;;;;
+1313;ETHIOPIC SYLLABLE GWAA;Lo;0;L;;;;;N;;;;;
+1314;ETHIOPIC SYLLABLE GWEE;Lo;0;L;;;;;N;;;;;
+1315;ETHIOPIC SYLLABLE GWE;Lo;0;L;;;;;N;;;;;
+1318;ETHIOPIC SYLLABLE GGA;Lo;0;L;;;;;N;;;;;
+1319;ETHIOPIC SYLLABLE GGU;Lo;0;L;;;;;N;;;;;
+131A;ETHIOPIC SYLLABLE GGI;Lo;0;L;;;;;N;;;;;
+131B;ETHIOPIC SYLLABLE GGAA;Lo;0;L;;;;;N;;;;;
+131C;ETHIOPIC SYLLABLE GGEE;Lo;0;L;;;;;N;;;;;
+131D;ETHIOPIC SYLLABLE GGE;Lo;0;L;;;;;N;;;;;
+131E;ETHIOPIC SYLLABLE GGO;Lo;0;L;;;;;N;;;;;
+131F;ETHIOPIC SYLLABLE GGWAA;Lo;0;L;;;;;N;;;;;
+1320;ETHIOPIC SYLLABLE THA;Lo;0;L;;;;;N;;;;;
+1321;ETHIOPIC SYLLABLE THU;Lo;0;L;;;;;N;;;;;
+1322;ETHIOPIC SYLLABLE THI;Lo;0;L;;;;;N;;;;;
+1323;ETHIOPIC SYLLABLE THAA;Lo;0;L;;;;;N;;;;;
+1324;ETHIOPIC SYLLABLE THEE;Lo;0;L;;;;;N;;;;;
+1325;ETHIOPIC SYLLABLE THE;Lo;0;L;;;;;N;;;;;
+1326;ETHIOPIC SYLLABLE THO;Lo;0;L;;;;;N;;;;;
+1327;ETHIOPIC SYLLABLE THWA;Lo;0;L;;;;;N;;;;;
+1328;ETHIOPIC SYLLABLE CHA;Lo;0;L;;;;;N;;;;;
+1329;ETHIOPIC SYLLABLE CHU;Lo;0;L;;;;;N;;;;;
+132A;ETHIOPIC SYLLABLE CHI;Lo;0;L;;;;;N;;;;;
+132B;ETHIOPIC SYLLABLE CHAA;Lo;0;L;;;;;N;;;;;
+132C;ETHIOPIC SYLLABLE CHEE;Lo;0;L;;;;;N;;;;;
+132D;ETHIOPIC SYLLABLE CHE;Lo;0;L;;;;;N;;;;;
+132E;ETHIOPIC SYLLABLE CHO;Lo;0;L;;;;;N;;;;;
+132F;ETHIOPIC SYLLABLE CHWA;Lo;0;L;;;;;N;;;;;
+1330;ETHIOPIC SYLLABLE PHA;Lo;0;L;;;;;N;;;;;
+1331;ETHIOPIC SYLLABLE PHU;Lo;0;L;;;;;N;;;;;
+1332;ETHIOPIC SYLLABLE PHI;Lo;0;L;;;;;N;;;;;
+1333;ETHIOPIC SYLLABLE PHAA;Lo;0;L;;;;;N;;;;;
+1334;ETHIOPIC SYLLABLE PHEE;Lo;0;L;;;;;N;;;;;
+1335;ETHIOPIC SYLLABLE PHE;Lo;0;L;;;;;N;;;;;
+1336;ETHIOPIC SYLLABLE PHO;Lo;0;L;;;;;N;;;;;
+1337;ETHIOPIC SYLLABLE PHWA;Lo;0;L;;;;;N;;;;;
+1338;ETHIOPIC SYLLABLE TSA;Lo;0;L;;;;;N;;;;;
+1339;ETHIOPIC SYLLABLE TSU;Lo;0;L;;;;;N;;;;;
+133A;ETHIOPIC SYLLABLE TSI;Lo;0;L;;;;;N;;;;;
+133B;ETHIOPIC SYLLABLE TSAA;Lo;0;L;;;;;N;;;;;
+133C;ETHIOPIC SYLLABLE TSEE;Lo;0;L;;;;;N;;;;;
+133D;ETHIOPIC SYLLABLE TSE;Lo;0;L;;;;;N;;;;;
+133E;ETHIOPIC SYLLABLE TSO;Lo;0;L;;;;;N;;;;;
+133F;ETHIOPIC SYLLABLE TSWA;Lo;0;L;;;;;N;;;;;
+1340;ETHIOPIC SYLLABLE TZA;Lo;0;L;;;;;N;;;;;
+1341;ETHIOPIC SYLLABLE TZU;Lo;0;L;;;;;N;;;;;
+1342;ETHIOPIC SYLLABLE TZI;Lo;0;L;;;;;N;;;;;
+1343;ETHIOPIC SYLLABLE TZAA;Lo;0;L;;;;;N;;;;;
+1344;ETHIOPIC SYLLABLE TZEE;Lo;0;L;;;;;N;;;;;
+1345;ETHIOPIC SYLLABLE TZE;Lo;0;L;;;;;N;;;;;
+1346;ETHIOPIC SYLLABLE TZO;Lo;0;L;;;;;N;;;;;
+1347;ETHIOPIC SYLLABLE TZOA;Lo;0;L;;;;;N;;;;;
+1348;ETHIOPIC SYLLABLE FA;Lo;0;L;;;;;N;;;;;
+1349;ETHIOPIC SYLLABLE FU;Lo;0;L;;;;;N;;;;;
+134A;ETHIOPIC SYLLABLE FI;Lo;0;L;;;;;N;;;;;
+134B;ETHIOPIC SYLLABLE FAA;Lo;0;L;;;;;N;;;;;
+134C;ETHIOPIC SYLLABLE FEE;Lo;0;L;;;;;N;;;;;
+134D;ETHIOPIC SYLLABLE FE;Lo;0;L;;;;;N;;;;;
+134E;ETHIOPIC SYLLABLE FO;Lo;0;L;;;;;N;;;;;
+134F;ETHIOPIC SYLLABLE FWA;Lo;0;L;;;;;N;;;;;
+1350;ETHIOPIC SYLLABLE PA;Lo;0;L;;;;;N;;;;;
+1351;ETHIOPIC SYLLABLE PU;Lo;0;L;;;;;N;;;;;
+1352;ETHIOPIC SYLLABLE PI;Lo;0;L;;;;;N;;;;;
+1353;ETHIOPIC SYLLABLE PAA;Lo;0;L;;;;;N;;;;;
+1354;ETHIOPIC SYLLABLE PEE;Lo;0;L;;;;;N;;;;;
+1355;ETHIOPIC SYLLABLE PE;Lo;0;L;;;;;N;;;;;
+1356;ETHIOPIC SYLLABLE PO;Lo;0;L;;;;;N;;;;;
+1357;ETHIOPIC SYLLABLE PWA;Lo;0;L;;;;;N;;;;;
+1358;ETHIOPIC SYLLABLE RYA;Lo;0;L;;;;;N;;;;;
+1359;ETHIOPIC SYLLABLE MYA;Lo;0;L;;;;;N;;;;;
+135A;ETHIOPIC SYLLABLE FYA;Lo;0;L;;;;;N;;;;;
+135D;ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK;Mn;230;NSM;;;;;N;;;;;
+135E;ETHIOPIC COMBINING VOWEL LENGTH MARK;Mn;230;NSM;;;;;N;;;;;
+135F;ETHIOPIC COMBINING GEMINATION MARK;Mn;230;NSM;;;;;N;;;;;
+1360;ETHIOPIC SECTION MARK;Po;0;L;;;;;N;;;;;
+1361;ETHIOPIC WORDSPACE;Po;0;L;;;;;N;;;;;
+1362;ETHIOPIC FULL STOP;Po;0;L;;;;;N;;;;;
+1363;ETHIOPIC COMMA;Po;0;L;;;;;N;;;;;
+1364;ETHIOPIC SEMICOLON;Po;0;L;;;;;N;;;;;
+1365;ETHIOPIC COLON;Po;0;L;;;;;N;;;;;
+1366;ETHIOPIC PREFACE COLON;Po;0;L;;;;;N;;;;;
+1367;ETHIOPIC QUESTION MARK;Po;0;L;;;;;N;;;;;
+1368;ETHIOPIC PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;;
+1369;ETHIOPIC DIGIT ONE;No;0;L;;;1;1;N;;;;;
+136A;ETHIOPIC DIGIT TWO;No;0;L;;;2;2;N;;;;;
+136B;ETHIOPIC DIGIT THREE;No;0;L;;;3;3;N;;;;;
+136C;ETHIOPIC DIGIT FOUR;No;0;L;;;4;4;N;;;;;
+136D;ETHIOPIC DIGIT FIVE;No;0;L;;;5;5;N;;;;;
+136E;ETHIOPIC DIGIT SIX;No;0;L;;;6;6;N;;;;;
+136F;ETHIOPIC DIGIT SEVEN;No;0;L;;;7;7;N;;;;;
+1370;ETHIOPIC DIGIT EIGHT;No;0;L;;;8;8;N;;;;;
+1371;ETHIOPIC DIGIT NINE;No;0;L;;;9;9;N;;;;;
+1372;ETHIOPIC NUMBER TEN;No;0;L;;;;10;N;;;;;
+1373;ETHIOPIC NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+1374;ETHIOPIC NUMBER THIRTY;No;0;L;;;;30;N;;;;;
+1375;ETHIOPIC NUMBER FORTY;No;0;L;;;;40;N;;;;;
+1376;ETHIOPIC NUMBER FIFTY;No;0;L;;;;50;N;;;;;
+1377;ETHIOPIC NUMBER SIXTY;No;0;L;;;;60;N;;;;;
+1378;ETHIOPIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
+1379;ETHIOPIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
+137A;ETHIOPIC NUMBER NINETY;No;0;L;;;;90;N;;;;;
+137B;ETHIOPIC NUMBER HUNDRED;No;0;L;;;;100;N;;;;;
+137C;ETHIOPIC NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;;
+1380;ETHIOPIC SYLLABLE SEBATBEIT MWA;Lo;0;L;;;;;N;;;;;
+1381;ETHIOPIC SYLLABLE MWI;Lo;0;L;;;;;N;;;;;
+1382;ETHIOPIC SYLLABLE MWEE;Lo;0;L;;;;;N;;;;;
+1383;ETHIOPIC SYLLABLE MWE;Lo;0;L;;;;;N;;;;;
+1384;ETHIOPIC SYLLABLE SEBATBEIT BWA;Lo;0;L;;;;;N;;;;;
+1385;ETHIOPIC SYLLABLE BWI;Lo;0;L;;;;;N;;;;;
+1386;ETHIOPIC SYLLABLE BWEE;Lo;0;L;;;;;N;;;;;
+1387;ETHIOPIC SYLLABLE BWE;Lo;0;L;;;;;N;;;;;
+1388;ETHIOPIC SYLLABLE SEBATBEIT FWA;Lo;0;L;;;;;N;;;;;
+1389;ETHIOPIC SYLLABLE FWI;Lo;0;L;;;;;N;;;;;
+138A;ETHIOPIC SYLLABLE FWEE;Lo;0;L;;;;;N;;;;;
+138B;ETHIOPIC SYLLABLE FWE;Lo;0;L;;;;;N;;;;;
+138C;ETHIOPIC SYLLABLE SEBATBEIT PWA;Lo;0;L;;;;;N;;;;;
+138D;ETHIOPIC SYLLABLE PWI;Lo;0;L;;;;;N;;;;;
+138E;ETHIOPIC SYLLABLE PWEE;Lo;0;L;;;;;N;;;;;
+138F;ETHIOPIC SYLLABLE PWE;Lo;0;L;;;;;N;;;;;
+1390;ETHIOPIC TONAL MARK YIZET;So;0;ON;;;;;N;;;;;
+1391;ETHIOPIC TONAL MARK DERET;So;0;ON;;;;;N;;;;;
+1392;ETHIOPIC TONAL MARK RIKRIK;So;0;ON;;;;;N;;;;;
+1393;ETHIOPIC TONAL MARK SHORT RIKRIK;So;0;ON;;;;;N;;;;;
+1394;ETHIOPIC TONAL MARK DIFAT;So;0;ON;;;;;N;;;;;
+1395;ETHIOPIC TONAL MARK KENAT;So;0;ON;;;;;N;;;;;
+1396;ETHIOPIC TONAL MARK CHIRET;So;0;ON;;;;;N;;;;;
+1397;ETHIOPIC TONAL MARK HIDET;So;0;ON;;;;;N;;;;;
+1398;ETHIOPIC TONAL MARK DERET-HIDET;So;0;ON;;;;;N;;;;;
+1399;ETHIOPIC TONAL MARK KURT;So;0;ON;;;;;N;;;;;
+13A0;CHEROKEE LETTER A;Lu;0;L;;;;;N;;;;AB70;
+13A1;CHEROKEE LETTER E;Lu;0;L;;;;;N;;;;AB71;
+13A2;CHEROKEE LETTER I;Lu;0;L;;;;;N;;;;AB72;
+13A3;CHEROKEE LETTER O;Lu;0;L;;;;;N;;;;AB73;
+13A4;CHEROKEE LETTER U;Lu;0;L;;;;;N;;;;AB74;
+13A5;CHEROKEE LETTER V;Lu;0;L;;;;;N;;;;AB75;
+13A6;CHEROKEE LETTER GA;Lu;0;L;;;;;N;;;;AB76;
+13A7;CHEROKEE LETTER KA;Lu;0;L;;;;;N;;;;AB77;
+13A8;CHEROKEE LETTER GE;Lu;0;L;;;;;N;;;;AB78;
+13A9;CHEROKEE LETTER GI;Lu;0;L;;;;;N;;;;AB79;
+13AA;CHEROKEE LETTER GO;Lu;0;L;;;;;N;;;;AB7A;
+13AB;CHEROKEE LETTER GU;Lu;0;L;;;;;N;;;;AB7B;
+13AC;CHEROKEE LETTER GV;Lu;0;L;;;;;N;;;;AB7C;
+13AD;CHEROKEE LETTER HA;Lu;0;L;;;;;N;;;;AB7D;
+13AE;CHEROKEE LETTER HE;Lu;0;L;;;;;N;;;;AB7E;
+13AF;CHEROKEE LETTER HI;Lu;0;L;;;;;N;;;;AB7F;
+13B0;CHEROKEE LETTER HO;Lu;0;L;;;;;N;;;;AB80;
+13B1;CHEROKEE LETTER HU;Lu;0;L;;;;;N;;;;AB81;
+13B2;CHEROKEE LETTER HV;Lu;0;L;;;;;N;;;;AB82;
+13B3;CHEROKEE LETTER LA;Lu;0;L;;;;;N;;;;AB83;
+13B4;CHEROKEE LETTER LE;Lu;0;L;;;;;N;;;;AB84;
+13B5;CHEROKEE LETTER LI;Lu;0;L;;;;;N;;;;AB85;
+13B6;CHEROKEE LETTER LO;Lu;0;L;;;;;N;;;;AB86;
+13B7;CHEROKEE LETTER LU;Lu;0;L;;;;;N;;;;AB87;
+13B8;CHEROKEE LETTER LV;Lu;0;L;;;;;N;;;;AB88;
+13B9;CHEROKEE LETTER MA;Lu;0;L;;;;;N;;;;AB89;
+13BA;CHEROKEE LETTER ME;Lu;0;L;;;;;N;;;;AB8A;
+13BB;CHEROKEE LETTER MI;Lu;0;L;;;;;N;;;;AB8B;
+13BC;CHEROKEE LETTER MO;Lu;0;L;;;;;N;;;;AB8C;
+13BD;CHEROKEE LETTER MU;Lu;0;L;;;;;N;;;;AB8D;
+13BE;CHEROKEE LETTER NA;Lu;0;L;;;;;N;;;;AB8E;
+13BF;CHEROKEE LETTER HNA;Lu;0;L;;;;;N;;;;AB8F;
+13C0;CHEROKEE LETTER NAH;Lu;0;L;;;;;N;;;;AB90;
+13C1;CHEROKEE LETTER NE;Lu;0;L;;;;;N;;;;AB91;
+13C2;CHEROKEE LETTER NI;Lu;0;L;;;;;N;;;;AB92;
+13C3;CHEROKEE LETTER NO;Lu;0;L;;;;;N;;;;AB93;
+13C4;CHEROKEE LETTER NU;Lu;0;L;;;;;N;;;;AB94;
+13C5;CHEROKEE LETTER NV;Lu;0;L;;;;;N;;;;AB95;
+13C6;CHEROKEE LETTER QUA;Lu;0;L;;;;;N;;;;AB96;
+13C7;CHEROKEE LETTER QUE;Lu;0;L;;;;;N;;;;AB97;
+13C8;CHEROKEE LETTER QUI;Lu;0;L;;;;;N;;;;AB98;
+13C9;CHEROKEE LETTER QUO;Lu;0;L;;;;;N;;;;AB99;
+13CA;CHEROKEE LETTER QUU;Lu;0;L;;;;;N;;;;AB9A;
+13CB;CHEROKEE LETTER QUV;Lu;0;L;;;;;N;;;;AB9B;
+13CC;CHEROKEE LETTER SA;Lu;0;L;;;;;N;;;;AB9C;
+13CD;CHEROKEE LETTER S;Lu;0;L;;;;;N;;;;AB9D;
+13CE;CHEROKEE LETTER SE;Lu;0;L;;;;;N;;;;AB9E;
+13CF;CHEROKEE LETTER SI;Lu;0;L;;;;;N;;;;AB9F;
+13D0;CHEROKEE LETTER SO;Lu;0;L;;;;;N;;;;ABA0;
+13D1;CHEROKEE LETTER SU;Lu;0;L;;;;;N;;;;ABA1;
+13D2;CHEROKEE LETTER SV;Lu;0;L;;;;;N;;;;ABA2;
+13D3;CHEROKEE LETTER DA;Lu;0;L;;;;;N;;;;ABA3;
+13D4;CHEROKEE LETTER TA;Lu;0;L;;;;;N;;;;ABA4;
+13D5;CHEROKEE LETTER DE;Lu;0;L;;;;;N;;;;ABA5;
+13D6;CHEROKEE LETTER TE;Lu;0;L;;;;;N;;;;ABA6;
+13D7;CHEROKEE LETTER DI;Lu;0;L;;;;;N;;;;ABA7;
+13D8;CHEROKEE LETTER TI;Lu;0;L;;;;;N;;;;ABA8;
+13D9;CHEROKEE LETTER DO;Lu;0;L;;;;;N;;;;ABA9;
+13DA;CHEROKEE LETTER DU;Lu;0;L;;;;;N;;;;ABAA;
+13DB;CHEROKEE LETTER DV;Lu;0;L;;;;;N;;;;ABAB;
+13DC;CHEROKEE LETTER DLA;Lu;0;L;;;;;N;;;;ABAC;
+13DD;CHEROKEE LETTER TLA;Lu;0;L;;;;;N;;;;ABAD;
+13DE;CHEROKEE LETTER TLE;Lu;0;L;;;;;N;;;;ABAE;
+13DF;CHEROKEE LETTER TLI;Lu;0;L;;;;;N;;;;ABAF;
+13E0;CHEROKEE LETTER TLO;Lu;0;L;;;;;N;;;;ABB0;
+13E1;CHEROKEE LETTER TLU;Lu;0;L;;;;;N;;;;ABB1;
+13E2;CHEROKEE LETTER TLV;Lu;0;L;;;;;N;;;;ABB2;
+13E3;CHEROKEE LETTER TSA;Lu;0;L;;;;;N;;;;ABB3;
+13E4;CHEROKEE LETTER TSE;Lu;0;L;;;;;N;;;;ABB4;
+13E5;CHEROKEE LETTER TSI;Lu;0;L;;;;;N;;;;ABB5;
+13E6;CHEROKEE LETTER TSO;Lu;0;L;;;;;N;;;;ABB6;
+13E7;CHEROKEE LETTER TSU;Lu;0;L;;;;;N;;;;ABB7;
+13E8;CHEROKEE LETTER TSV;Lu;0;L;;;;;N;;;;ABB8;
+13E9;CHEROKEE LETTER WA;Lu;0;L;;;;;N;;;;ABB9;
+13EA;CHEROKEE LETTER WE;Lu;0;L;;;;;N;;;;ABBA;
+13EB;CHEROKEE LETTER WI;Lu;0;L;;;;;N;;;;ABBB;
+13EC;CHEROKEE LETTER WO;Lu;0;L;;;;;N;;;;ABBC;
+13ED;CHEROKEE LETTER WU;Lu;0;L;;;;;N;;;;ABBD;
+13EE;CHEROKEE LETTER WV;Lu;0;L;;;;;N;;;;ABBE;
+13EF;CHEROKEE LETTER YA;Lu;0;L;;;;;N;;;;ABBF;
+13F0;CHEROKEE LETTER YE;Lu;0;L;;;;;N;;;;13F8;
+13F1;CHEROKEE LETTER YI;Lu;0;L;;;;;N;;;;13F9;
+13F2;CHEROKEE LETTER YO;Lu;0;L;;;;;N;;;;13FA;
+13F3;CHEROKEE LETTER YU;Lu;0;L;;;;;N;;;;13FB;
+13F4;CHEROKEE LETTER YV;Lu;0;L;;;;;N;;;;13FC;
+13F5;CHEROKEE LETTER MV;Lu;0;L;;;;;N;;;;13FD;
+13F8;CHEROKEE SMALL LETTER YE;Ll;0;L;;;;;N;;;13F0;;13F0
+13F9;CHEROKEE SMALL LETTER YI;Ll;0;L;;;;;N;;;13F1;;13F1
+13FA;CHEROKEE SMALL LETTER YO;Ll;0;L;;;;;N;;;13F2;;13F2
+13FB;CHEROKEE SMALL LETTER YU;Ll;0;L;;;;;N;;;13F3;;13F3
+13FC;CHEROKEE SMALL LETTER YV;Ll;0;L;;;;;N;;;13F4;;13F4
+13FD;CHEROKEE SMALL LETTER MV;Ll;0;L;;;;;N;;;13F5;;13F5
+1400;CANADIAN SYLLABICS HYPHEN;Pd;0;ON;;;;;N;;;;;
+1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;;
+1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;;
+1403;CANADIAN SYLLABICS I;Lo;0;L;;;;;N;;;;;
+1404;CANADIAN SYLLABICS II;Lo;0;L;;;;;N;;;;;
+1405;CANADIAN SYLLABICS O;Lo;0;L;;;;;N;;;;;
+1406;CANADIAN SYLLABICS OO;Lo;0;L;;;;;N;;;;;
+1407;CANADIAN SYLLABICS Y-CREE OO;Lo;0;L;;;;;N;;;;;
+1408;CANADIAN SYLLABICS CARRIER EE;Lo;0;L;;;;;N;;;;;
+1409;CANADIAN SYLLABICS CARRIER I;Lo;0;L;;;;;N;;;;;
+140A;CANADIAN SYLLABICS A;Lo;0;L;;;;;N;;;;;
+140B;CANADIAN SYLLABICS AA;Lo;0;L;;;;;N;;;;;
+140C;CANADIAN SYLLABICS WE;Lo;0;L;;;;;N;;;;;
+140D;CANADIAN SYLLABICS WEST-CREE WE;Lo;0;L;;;;;N;;;;;
+140E;CANADIAN SYLLABICS WI;Lo;0;L;;;;;N;;;;;
+140F;CANADIAN SYLLABICS WEST-CREE WI;Lo;0;L;;;;;N;;;;;
+1410;CANADIAN SYLLABICS WII;Lo;0;L;;;;;N;;;;;
+1411;CANADIAN SYLLABICS WEST-CREE WII;Lo;0;L;;;;;N;;;;;
+1412;CANADIAN SYLLABICS WO;Lo;0;L;;;;;N;;;;;
+1413;CANADIAN SYLLABICS WEST-CREE WO;Lo;0;L;;;;;N;;;;;
+1414;CANADIAN SYLLABICS WOO;Lo;0;L;;;;;N;;;;;
+1415;CANADIAN SYLLABICS WEST-CREE WOO;Lo;0;L;;;;;N;;;;;
+1416;CANADIAN SYLLABICS NASKAPI WOO;Lo;0;L;;;;;N;;;;;
+1417;CANADIAN SYLLABICS WA;Lo;0;L;;;;;N;;;;;
+1418;CANADIAN SYLLABICS WEST-CREE WA;Lo;0;L;;;;;N;;;;;
+1419;CANADIAN SYLLABICS WAA;Lo;0;L;;;;;N;;;;;
+141A;CANADIAN SYLLABICS WEST-CREE WAA;Lo;0;L;;;;;N;;;;;
+141B;CANADIAN SYLLABICS NASKAPI WAA;Lo;0;L;;;;;N;;;;;
+141C;CANADIAN SYLLABICS AI;Lo;0;L;;;;;N;;;;;
+141D;CANADIAN SYLLABICS Y-CREE W;Lo;0;L;;;;;N;;;;;
+141E;CANADIAN SYLLABICS GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
+141F;CANADIAN SYLLABICS FINAL ACUTE;Lo;0;L;;;;;N;;;;;
+1420;CANADIAN SYLLABICS FINAL GRAVE;Lo;0;L;;;;;N;;;;;
+1421;CANADIAN SYLLABICS FINAL BOTTOM HALF RING;Lo;0;L;;;;;N;;;;;
+1422;CANADIAN SYLLABICS FINAL TOP HALF RING;Lo;0;L;;;;;N;;;;;
+1423;CANADIAN SYLLABICS FINAL RIGHT HALF RING;Lo;0;L;;;;;N;;;;;
+1424;CANADIAN SYLLABICS FINAL RING;Lo;0;L;;;;;N;;;;;
+1425;CANADIAN SYLLABICS FINAL DOUBLE ACUTE;Lo;0;L;;;;;N;;;;;
+1426;CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES;Lo;0;L;;;;;N;;;;;
+1427;CANADIAN SYLLABICS FINAL MIDDLE DOT;Lo;0;L;;;;;N;;;;;
+1428;CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE;Lo;0;L;;;;;N;;;;;
+1429;CANADIAN SYLLABICS FINAL PLUS;Lo;0;L;;;;;N;;;;;
+142A;CANADIAN SYLLABICS FINAL DOWN TACK;Lo;0;L;;;;;N;;;;;
+142B;CANADIAN SYLLABICS EN;Lo;0;L;;;;;N;;;;;
+142C;CANADIAN SYLLABICS IN;Lo;0;L;;;;;N;;;;;
+142D;CANADIAN SYLLABICS ON;Lo;0;L;;;;;N;;;;;
+142E;CANADIAN SYLLABICS AN;Lo;0;L;;;;;N;;;;;
+142F;CANADIAN SYLLABICS PE;Lo;0;L;;;;;N;;;;;
+1430;CANADIAN SYLLABICS PAAI;Lo;0;L;;;;;N;;;;;
+1431;CANADIAN SYLLABICS PI;Lo;0;L;;;;;N;;;;;
+1432;CANADIAN SYLLABICS PII;Lo;0;L;;;;;N;;;;;
+1433;CANADIAN SYLLABICS PO;Lo;0;L;;;;;N;;;;;
+1434;CANADIAN SYLLABICS POO;Lo;0;L;;;;;N;;;;;
+1435;CANADIAN SYLLABICS Y-CREE POO;Lo;0;L;;;;;N;;;;;
+1436;CANADIAN SYLLABICS CARRIER HEE;Lo;0;L;;;;;N;;;;;
+1437;CANADIAN SYLLABICS CARRIER HI;Lo;0;L;;;;;N;;;;;
+1438;CANADIAN SYLLABICS PA;Lo;0;L;;;;;N;;;;;
+1439;CANADIAN SYLLABICS PAA;Lo;0;L;;;;;N;;;;;
+143A;CANADIAN SYLLABICS PWE;Lo;0;L;;;;;N;;;;;
+143B;CANADIAN SYLLABICS WEST-CREE PWE;Lo;0;L;;;;;N;;;;;
+143C;CANADIAN SYLLABICS PWI;Lo;0;L;;;;;N;;;;;
+143D;CANADIAN SYLLABICS WEST-CREE PWI;Lo;0;L;;;;;N;;;;;
+143E;CANADIAN SYLLABICS PWII;Lo;0;L;;;;;N;;;;;
+143F;CANADIAN SYLLABICS WEST-CREE PWII;Lo;0;L;;;;;N;;;;;
+1440;CANADIAN SYLLABICS PWO;Lo;0;L;;;;;N;;;;;
+1441;CANADIAN SYLLABICS WEST-CREE PWO;Lo;0;L;;;;;N;;;;;
+1442;CANADIAN SYLLABICS PWOO;Lo;0;L;;;;;N;;;;;
+1443;CANADIAN SYLLABICS WEST-CREE PWOO;Lo;0;L;;;;;N;;;;;
+1444;CANADIAN SYLLABICS PWA;Lo;0;L;;;;;N;;;;;
+1445;CANADIAN SYLLABICS WEST-CREE PWA;Lo;0;L;;;;;N;;;;;
+1446;CANADIAN SYLLABICS PWAA;Lo;0;L;;;;;N;;;;;
+1447;CANADIAN SYLLABICS WEST-CREE PWAA;Lo;0;L;;;;;N;;;;;
+1448;CANADIAN SYLLABICS Y-CREE PWAA;Lo;0;L;;;;;N;;;;;
+1449;CANADIAN SYLLABICS P;Lo;0;L;;;;;N;;;;;
+144A;CANADIAN SYLLABICS WEST-CREE P;Lo;0;L;;;;;N;;;;;
+144B;CANADIAN SYLLABICS CARRIER H;Lo;0;L;;;;;N;;;;;
+144C;CANADIAN SYLLABICS TE;Lo;0;L;;;;;N;;;;;
+144D;CANADIAN SYLLABICS TAAI;Lo;0;L;;;;;N;;;;;
+144E;CANADIAN SYLLABICS TI;Lo;0;L;;;;;N;;;;;
+144F;CANADIAN SYLLABICS TII;Lo;0;L;;;;;N;;;;;
+1450;CANADIAN SYLLABICS TO;Lo;0;L;;;;;N;;;;;
+1451;CANADIAN SYLLABICS TOO;Lo;0;L;;;;;N;;;;;
+1452;CANADIAN SYLLABICS Y-CREE TOO;Lo;0;L;;;;;N;;;;;
+1453;CANADIAN SYLLABICS CARRIER DEE;Lo;0;L;;;;;N;;;;;
+1454;CANADIAN SYLLABICS CARRIER DI;Lo;0;L;;;;;N;;;;;
+1455;CANADIAN SYLLABICS TA;Lo;0;L;;;;;N;;;;;
+1456;CANADIAN SYLLABICS TAA;Lo;0;L;;;;;N;;;;;
+1457;CANADIAN SYLLABICS TWE;Lo;0;L;;;;;N;;;;;
+1458;CANADIAN SYLLABICS WEST-CREE TWE;Lo;0;L;;;;;N;;;;;
+1459;CANADIAN SYLLABICS TWI;Lo;0;L;;;;;N;;;;;
+145A;CANADIAN SYLLABICS WEST-CREE TWI;Lo;0;L;;;;;N;;;;;
+145B;CANADIAN SYLLABICS TWII;Lo;0;L;;;;;N;;;;;
+145C;CANADIAN SYLLABICS WEST-CREE TWII;Lo;0;L;;;;;N;;;;;
+145D;CANADIAN SYLLABICS TWO;Lo;0;L;;;;;N;;;;;
+145E;CANADIAN SYLLABICS WEST-CREE TWO;Lo;0;L;;;;;N;;;;;
+145F;CANADIAN SYLLABICS TWOO;Lo;0;L;;;;;N;;;;;
+1460;CANADIAN SYLLABICS WEST-CREE TWOO;Lo;0;L;;;;;N;;;;;
+1461;CANADIAN SYLLABICS TWA;Lo;0;L;;;;;N;;;;;
+1462;CANADIAN SYLLABICS WEST-CREE TWA;Lo;0;L;;;;;N;;;;;
+1463;CANADIAN SYLLABICS TWAA;Lo;0;L;;;;;N;;;;;
+1464;CANADIAN SYLLABICS WEST-CREE TWAA;Lo;0;L;;;;;N;;;;;
+1465;CANADIAN SYLLABICS NASKAPI TWAA;Lo;0;L;;;;;N;;;;;
+1466;CANADIAN SYLLABICS T;Lo;0;L;;;;;N;;;;;
+1467;CANADIAN SYLLABICS TTE;Lo;0;L;;;;;N;;;;;
+1468;CANADIAN SYLLABICS TTI;Lo;0;L;;;;;N;;;;;
+1469;CANADIAN SYLLABICS TTO;Lo;0;L;;;;;N;;;;;
+146A;CANADIAN SYLLABICS TTA;Lo;0;L;;;;;N;;;;;
+146B;CANADIAN SYLLABICS KE;Lo;0;L;;;;;N;;;;;
+146C;CANADIAN SYLLABICS KAAI;Lo;0;L;;;;;N;;;;;
+146D;CANADIAN SYLLABICS KI;Lo;0;L;;;;;N;;;;;
+146E;CANADIAN SYLLABICS KII;Lo;0;L;;;;;N;;;;;
+146F;CANADIAN SYLLABICS KO;Lo;0;L;;;;;N;;;;;
+1470;CANADIAN SYLLABICS KOO;Lo;0;L;;;;;N;;;;;
+1471;CANADIAN SYLLABICS Y-CREE KOO;Lo;0;L;;;;;N;;;;;
+1472;CANADIAN SYLLABICS KA;Lo;0;L;;;;;N;;;;;
+1473;CANADIAN SYLLABICS KAA;Lo;0;L;;;;;N;;;;;
+1474;CANADIAN SYLLABICS KWE;Lo;0;L;;;;;N;;;;;
+1475;CANADIAN SYLLABICS WEST-CREE KWE;Lo;0;L;;;;;N;;;;;
+1476;CANADIAN SYLLABICS KWI;Lo;0;L;;;;;N;;;;;
+1477;CANADIAN SYLLABICS WEST-CREE KWI;Lo;0;L;;;;;N;;;;;
+1478;CANADIAN SYLLABICS KWII;Lo;0;L;;;;;N;;;;;
+1479;CANADIAN SYLLABICS WEST-CREE KWII;Lo;0;L;;;;;N;;;;;
+147A;CANADIAN SYLLABICS KWO;Lo;0;L;;;;;N;;;;;
+147B;CANADIAN SYLLABICS WEST-CREE KWO;Lo;0;L;;;;;N;;;;;
+147C;CANADIAN SYLLABICS KWOO;Lo;0;L;;;;;N;;;;;
+147D;CANADIAN SYLLABICS WEST-CREE KWOO;Lo;0;L;;;;;N;;;;;
+147E;CANADIAN SYLLABICS KWA;Lo;0;L;;;;;N;;;;;
+147F;CANADIAN SYLLABICS WEST-CREE KWA;Lo;0;L;;;;;N;;;;;
+1480;CANADIAN SYLLABICS KWAA;Lo;0;L;;;;;N;;;;;
+1481;CANADIAN SYLLABICS WEST-CREE KWAA;Lo;0;L;;;;;N;;;;;
+1482;CANADIAN SYLLABICS NASKAPI KWAA;Lo;0;L;;;;;N;;;;;
+1483;CANADIAN SYLLABICS K;Lo;0;L;;;;;N;;;;;
+1484;CANADIAN SYLLABICS KW;Lo;0;L;;;;;N;;;;;
+1485;CANADIAN SYLLABICS SOUTH-SLAVEY KEH;Lo;0;L;;;;;N;;;;;
+1486;CANADIAN SYLLABICS SOUTH-SLAVEY KIH;Lo;0;L;;;;;N;;;;;
+1487;CANADIAN SYLLABICS SOUTH-SLAVEY KOH;Lo;0;L;;;;;N;;;;;
+1488;CANADIAN SYLLABICS SOUTH-SLAVEY KAH;Lo;0;L;;;;;N;;;;;
+1489;CANADIAN SYLLABICS CE;Lo;0;L;;;;;N;;;;;
+148A;CANADIAN SYLLABICS CAAI;Lo;0;L;;;;;N;;;;;
+148B;CANADIAN SYLLABICS CI;Lo;0;L;;;;;N;;;;;
+148C;CANADIAN SYLLABICS CII;Lo;0;L;;;;;N;;;;;
+148D;CANADIAN SYLLABICS CO;Lo;0;L;;;;;N;;;;;
+148E;CANADIAN SYLLABICS COO;Lo;0;L;;;;;N;;;;;
+148F;CANADIAN SYLLABICS Y-CREE COO;Lo;0;L;;;;;N;;;;;
+1490;CANADIAN SYLLABICS CA;Lo;0;L;;;;;N;;;;;
+1491;CANADIAN SYLLABICS CAA;Lo;0;L;;;;;N;;;;;
+1492;CANADIAN SYLLABICS CWE;Lo;0;L;;;;;N;;;;;
+1493;CANADIAN SYLLABICS WEST-CREE CWE;Lo;0;L;;;;;N;;;;;
+1494;CANADIAN SYLLABICS CWI;Lo;0;L;;;;;N;;;;;
+1495;CANADIAN SYLLABICS WEST-CREE CWI;Lo;0;L;;;;;N;;;;;
+1496;CANADIAN SYLLABICS CWII;Lo;0;L;;;;;N;;;;;
+1497;CANADIAN SYLLABICS WEST-CREE CWII;Lo;0;L;;;;;N;;;;;
+1498;CANADIAN SYLLABICS CWO;Lo;0;L;;;;;N;;;;;
+1499;CANADIAN SYLLABICS WEST-CREE CWO;Lo;0;L;;;;;N;;;;;
+149A;CANADIAN SYLLABICS CWOO;Lo;0;L;;;;;N;;;;;
+149B;CANADIAN SYLLABICS WEST-CREE CWOO;Lo;0;L;;;;;N;;;;;
+149C;CANADIAN SYLLABICS CWA;Lo;0;L;;;;;N;;;;;
+149D;CANADIAN SYLLABICS WEST-CREE CWA;Lo;0;L;;;;;N;;;;;
+149E;CANADIAN SYLLABICS CWAA;Lo;0;L;;;;;N;;;;;
+149F;CANADIAN SYLLABICS WEST-CREE CWAA;Lo;0;L;;;;;N;;;;;
+14A0;CANADIAN SYLLABICS NASKAPI CWAA;Lo;0;L;;;;;N;;;;;
+14A1;CANADIAN SYLLABICS C;Lo;0;L;;;;;N;;;;;
+14A2;CANADIAN SYLLABICS SAYISI TH;Lo;0;L;;;;;N;;;;;
+14A3;CANADIAN SYLLABICS ME;Lo;0;L;;;;;N;;;;;
+14A4;CANADIAN SYLLABICS MAAI;Lo;0;L;;;;;N;;;;;
+14A5;CANADIAN SYLLABICS MI;Lo;0;L;;;;;N;;;;;
+14A6;CANADIAN SYLLABICS MII;Lo;0;L;;;;;N;;;;;
+14A7;CANADIAN SYLLABICS MO;Lo;0;L;;;;;N;;;;;
+14A8;CANADIAN SYLLABICS MOO;Lo;0;L;;;;;N;;;;;
+14A9;CANADIAN SYLLABICS Y-CREE MOO;Lo;0;L;;;;;N;;;;;
+14AA;CANADIAN SYLLABICS MA;Lo;0;L;;;;;N;;;;;
+14AB;CANADIAN SYLLABICS MAA;Lo;0;L;;;;;N;;;;;
+14AC;CANADIAN SYLLABICS MWE;Lo;0;L;;;;;N;;;;;
+14AD;CANADIAN SYLLABICS WEST-CREE MWE;Lo;0;L;;;;;N;;;;;
+14AE;CANADIAN SYLLABICS MWI;Lo;0;L;;;;;N;;;;;
+14AF;CANADIAN SYLLABICS WEST-CREE MWI;Lo;0;L;;;;;N;;;;;
+14B0;CANADIAN SYLLABICS MWII;Lo;0;L;;;;;N;;;;;
+14B1;CANADIAN SYLLABICS WEST-CREE MWII;Lo;0;L;;;;;N;;;;;
+14B2;CANADIAN SYLLABICS MWO;Lo;0;L;;;;;N;;;;;
+14B3;CANADIAN SYLLABICS WEST-CREE MWO;Lo;0;L;;;;;N;;;;;
+14B4;CANADIAN SYLLABICS MWOO;Lo;0;L;;;;;N;;;;;
+14B5;CANADIAN SYLLABICS WEST-CREE MWOO;Lo;0;L;;;;;N;;;;;
+14B6;CANADIAN SYLLABICS MWA;Lo;0;L;;;;;N;;;;;
+14B7;CANADIAN SYLLABICS WEST-CREE MWA;Lo;0;L;;;;;N;;;;;
+14B8;CANADIAN SYLLABICS MWAA;Lo;0;L;;;;;N;;;;;
+14B9;CANADIAN SYLLABICS WEST-CREE MWAA;Lo;0;L;;;;;N;;;;;
+14BA;CANADIAN SYLLABICS NASKAPI MWAA;Lo;0;L;;;;;N;;;;;
+14BB;CANADIAN SYLLABICS M;Lo;0;L;;;;;N;;;;;
+14BC;CANADIAN SYLLABICS WEST-CREE M;Lo;0;L;;;;;N;;;;;
+14BD;CANADIAN SYLLABICS MH;Lo;0;L;;;;;N;;;;;
+14BE;CANADIAN SYLLABICS ATHAPASCAN M;Lo;0;L;;;;;N;;;;;
+14BF;CANADIAN SYLLABICS SAYISI M;Lo;0;L;;;;;N;;;;;
+14C0;CANADIAN SYLLABICS NE;Lo;0;L;;;;;N;;;;;
+14C1;CANADIAN SYLLABICS NAAI;Lo;0;L;;;;;N;;;;;
+14C2;CANADIAN SYLLABICS NI;Lo;0;L;;;;;N;;;;;
+14C3;CANADIAN SYLLABICS NII;Lo;0;L;;;;;N;;;;;
+14C4;CANADIAN SYLLABICS NO;Lo;0;L;;;;;N;;;;;
+14C5;CANADIAN SYLLABICS NOO;Lo;0;L;;;;;N;;;;;
+14C6;CANADIAN SYLLABICS Y-CREE NOO;Lo;0;L;;;;;N;;;;;
+14C7;CANADIAN SYLLABICS NA;Lo;0;L;;;;;N;;;;;
+14C8;CANADIAN SYLLABICS NAA;Lo;0;L;;;;;N;;;;;
+14C9;CANADIAN SYLLABICS NWE;Lo;0;L;;;;;N;;;;;
+14CA;CANADIAN SYLLABICS WEST-CREE NWE;Lo;0;L;;;;;N;;;;;
+14CB;CANADIAN SYLLABICS NWA;Lo;0;L;;;;;N;;;;;
+14CC;CANADIAN SYLLABICS WEST-CREE NWA;Lo;0;L;;;;;N;;;;;
+14CD;CANADIAN SYLLABICS NWAA;Lo;0;L;;;;;N;;;;;
+14CE;CANADIAN SYLLABICS WEST-CREE NWAA;Lo;0;L;;;;;N;;;;;
+14CF;CANADIAN SYLLABICS NASKAPI NWAA;Lo;0;L;;;;;N;;;;;
+14D0;CANADIAN SYLLABICS N;Lo;0;L;;;;;N;;;;;
+14D1;CANADIAN SYLLABICS CARRIER NG;Lo;0;L;;;;;N;;;;;
+14D2;CANADIAN SYLLABICS NH;Lo;0;L;;;;;N;;;;;
+14D3;CANADIAN SYLLABICS LE;Lo;0;L;;;;;N;;;;;
+14D4;CANADIAN SYLLABICS LAAI;Lo;0;L;;;;;N;;;;;
+14D5;CANADIAN SYLLABICS LI;Lo;0;L;;;;;N;;;;;
+14D6;CANADIAN SYLLABICS LII;Lo;0;L;;;;;N;;;;;
+14D7;CANADIAN SYLLABICS LO;Lo;0;L;;;;;N;;;;;
+14D8;CANADIAN SYLLABICS LOO;Lo;0;L;;;;;N;;;;;
+14D9;CANADIAN SYLLABICS Y-CREE LOO;Lo;0;L;;;;;N;;;;;
+14DA;CANADIAN SYLLABICS LA;Lo;0;L;;;;;N;;;;;
+14DB;CANADIAN SYLLABICS LAA;Lo;0;L;;;;;N;;;;;
+14DC;CANADIAN SYLLABICS LWE;Lo;0;L;;;;;N;;;;;
+14DD;CANADIAN SYLLABICS WEST-CREE LWE;Lo;0;L;;;;;N;;;;;
+14DE;CANADIAN SYLLABICS LWI;Lo;0;L;;;;;N;;;;;
+14DF;CANADIAN SYLLABICS WEST-CREE LWI;Lo;0;L;;;;;N;;;;;
+14E0;CANADIAN SYLLABICS LWII;Lo;0;L;;;;;N;;;;;
+14E1;CANADIAN SYLLABICS WEST-CREE LWII;Lo;0;L;;;;;N;;;;;
+14E2;CANADIAN SYLLABICS LWO;Lo;0;L;;;;;N;;;;;
+14E3;CANADIAN SYLLABICS WEST-CREE LWO;Lo;0;L;;;;;N;;;;;
+14E4;CANADIAN SYLLABICS LWOO;Lo;0;L;;;;;N;;;;;
+14E5;CANADIAN SYLLABICS WEST-CREE LWOO;Lo;0;L;;;;;N;;;;;
+14E6;CANADIAN SYLLABICS LWA;Lo;0;L;;;;;N;;;;;
+14E7;CANADIAN SYLLABICS WEST-CREE LWA;Lo;0;L;;;;;N;;;;;
+14E8;CANADIAN SYLLABICS LWAA;Lo;0;L;;;;;N;;;;;
+14E9;CANADIAN SYLLABICS WEST-CREE LWAA;Lo;0;L;;;;;N;;;;;
+14EA;CANADIAN SYLLABICS L;Lo;0;L;;;;;N;;;;;
+14EB;CANADIAN SYLLABICS WEST-CREE L;Lo;0;L;;;;;N;;;;;
+14EC;CANADIAN SYLLABICS MEDIAL L;Lo;0;L;;;;;N;;;;;
+14ED;CANADIAN SYLLABICS SE;Lo;0;L;;;;;N;;;;;
+14EE;CANADIAN SYLLABICS SAAI;Lo;0;L;;;;;N;;;;;
+14EF;CANADIAN SYLLABICS SI;Lo;0;L;;;;;N;;;;;
+14F0;CANADIAN SYLLABICS SII;Lo;0;L;;;;;N;;;;;
+14F1;CANADIAN SYLLABICS SO;Lo;0;L;;;;;N;;;;;
+14F2;CANADIAN SYLLABICS SOO;Lo;0;L;;;;;N;;;;;
+14F3;CANADIAN SYLLABICS Y-CREE SOO;Lo;0;L;;;;;N;;;;;
+14F4;CANADIAN SYLLABICS SA;Lo;0;L;;;;;N;;;;;
+14F5;CANADIAN SYLLABICS SAA;Lo;0;L;;;;;N;;;;;
+14F6;CANADIAN SYLLABICS SWE;Lo;0;L;;;;;N;;;;;
+14F7;CANADIAN SYLLABICS WEST-CREE SWE;Lo;0;L;;;;;N;;;;;
+14F8;CANADIAN SYLLABICS SWI;Lo;0;L;;;;;N;;;;;
+14F9;CANADIAN SYLLABICS WEST-CREE SWI;Lo;0;L;;;;;N;;;;;
+14FA;CANADIAN SYLLABICS SWII;Lo;0;L;;;;;N;;;;;
+14FB;CANADIAN SYLLABICS WEST-CREE SWII;Lo;0;L;;;;;N;;;;;
+14FC;CANADIAN SYLLABICS SWO;Lo;0;L;;;;;N;;;;;
+14FD;CANADIAN SYLLABICS WEST-CREE SWO;Lo;0;L;;;;;N;;;;;
+14FE;CANADIAN SYLLABICS SWOO;Lo;0;L;;;;;N;;;;;
+14FF;CANADIAN SYLLABICS WEST-CREE SWOO;Lo;0;L;;;;;N;;;;;
+1500;CANADIAN SYLLABICS SWA;Lo;0;L;;;;;N;;;;;
+1501;CANADIAN SYLLABICS WEST-CREE SWA;Lo;0;L;;;;;N;;;;;
+1502;CANADIAN SYLLABICS SWAA;Lo;0;L;;;;;N;;;;;
+1503;CANADIAN SYLLABICS WEST-CREE SWAA;Lo;0;L;;;;;N;;;;;
+1504;CANADIAN SYLLABICS NASKAPI SWAA;Lo;0;L;;;;;N;;;;;
+1505;CANADIAN SYLLABICS S;Lo;0;L;;;;;N;;;;;
+1506;CANADIAN SYLLABICS ATHAPASCAN S;Lo;0;L;;;;;N;;;;;
+1507;CANADIAN SYLLABICS SW;Lo;0;L;;;;;N;;;;;
+1508;CANADIAN SYLLABICS BLACKFOOT S;Lo;0;L;;;;;N;;;;;
+1509;CANADIAN SYLLABICS MOOSE-CREE SK;Lo;0;L;;;;;N;;;;;
+150A;CANADIAN SYLLABICS NASKAPI SKW;Lo;0;L;;;;;N;;;;;
+150B;CANADIAN SYLLABICS NASKAPI S-W;Lo;0;L;;;;;N;;;;;
+150C;CANADIAN SYLLABICS NASKAPI SPWA;Lo;0;L;;;;;N;;;;;
+150D;CANADIAN SYLLABICS NASKAPI STWA;Lo;0;L;;;;;N;;;;;
+150E;CANADIAN SYLLABICS NASKAPI SKWA;Lo;0;L;;;;;N;;;;;
+150F;CANADIAN SYLLABICS NASKAPI SCWA;Lo;0;L;;;;;N;;;;;
+1510;CANADIAN SYLLABICS SHE;Lo;0;L;;;;;N;;;;;
+1511;CANADIAN SYLLABICS SHI;Lo;0;L;;;;;N;;;;;
+1512;CANADIAN SYLLABICS SHII;Lo;0;L;;;;;N;;;;;
+1513;CANADIAN SYLLABICS SHO;Lo;0;L;;;;;N;;;;;
+1514;CANADIAN SYLLABICS SHOO;Lo;0;L;;;;;N;;;;;
+1515;CANADIAN SYLLABICS SHA;Lo;0;L;;;;;N;;;;;
+1516;CANADIAN SYLLABICS SHAA;Lo;0;L;;;;;N;;;;;
+1517;CANADIAN SYLLABICS SHWE;Lo;0;L;;;;;N;;;;;
+1518;CANADIAN SYLLABICS WEST-CREE SHWE;Lo;0;L;;;;;N;;;;;
+1519;CANADIAN SYLLABICS SHWI;Lo;0;L;;;;;N;;;;;
+151A;CANADIAN SYLLABICS WEST-CREE SHWI;Lo;0;L;;;;;N;;;;;
+151B;CANADIAN SYLLABICS SHWII;Lo;0;L;;;;;N;;;;;
+151C;CANADIAN SYLLABICS WEST-CREE SHWII;Lo;0;L;;;;;N;;;;;
+151D;CANADIAN SYLLABICS SHWO;Lo;0;L;;;;;N;;;;;
+151E;CANADIAN SYLLABICS WEST-CREE SHWO;Lo;0;L;;;;;N;;;;;
+151F;CANADIAN SYLLABICS SHWOO;Lo;0;L;;;;;N;;;;;
+1520;CANADIAN SYLLABICS WEST-CREE SHWOO;Lo;0;L;;;;;N;;;;;
+1521;CANADIAN SYLLABICS SHWA;Lo;0;L;;;;;N;;;;;
+1522;CANADIAN SYLLABICS WEST-CREE SHWA;Lo;0;L;;;;;N;;;;;
+1523;CANADIAN SYLLABICS SHWAA;Lo;0;L;;;;;N;;;;;
+1524;CANADIAN SYLLABICS WEST-CREE SHWAA;Lo;0;L;;;;;N;;;;;
+1525;CANADIAN SYLLABICS SH;Lo;0;L;;;;;N;;;;;
+1526;CANADIAN SYLLABICS YE;Lo;0;L;;;;;N;;;;;
+1527;CANADIAN SYLLABICS YAAI;Lo;0;L;;;;;N;;;;;
+1528;CANADIAN SYLLABICS YI;Lo;0;L;;;;;N;;;;;
+1529;CANADIAN SYLLABICS YII;Lo;0;L;;;;;N;;;;;
+152A;CANADIAN SYLLABICS YO;Lo;0;L;;;;;N;;;;;
+152B;CANADIAN SYLLABICS YOO;Lo;0;L;;;;;N;;;;;
+152C;CANADIAN SYLLABICS Y-CREE YOO;Lo;0;L;;;;;N;;;;;
+152D;CANADIAN SYLLABICS YA;Lo;0;L;;;;;N;;;;;
+152E;CANADIAN SYLLABICS YAA;Lo;0;L;;;;;N;;;;;
+152F;CANADIAN SYLLABICS YWE;Lo;0;L;;;;;N;;;;;
+1530;CANADIAN SYLLABICS WEST-CREE YWE;Lo;0;L;;;;;N;;;;;
+1531;CANADIAN SYLLABICS YWI;Lo;0;L;;;;;N;;;;;
+1532;CANADIAN SYLLABICS WEST-CREE YWI;Lo;0;L;;;;;N;;;;;
+1533;CANADIAN SYLLABICS YWII;Lo;0;L;;;;;N;;;;;
+1534;CANADIAN SYLLABICS WEST-CREE YWII;Lo;0;L;;;;;N;;;;;
+1535;CANADIAN SYLLABICS YWO;Lo;0;L;;;;;N;;;;;
+1536;CANADIAN SYLLABICS WEST-CREE YWO;Lo;0;L;;;;;N;;;;;
+1537;CANADIAN SYLLABICS YWOO;Lo;0;L;;;;;N;;;;;
+1538;CANADIAN SYLLABICS WEST-CREE YWOO;Lo;0;L;;;;;N;;;;;
+1539;CANADIAN SYLLABICS YWA;Lo;0;L;;;;;N;;;;;
+153A;CANADIAN SYLLABICS WEST-CREE YWA;Lo;0;L;;;;;N;;;;;
+153B;CANADIAN SYLLABICS YWAA;Lo;0;L;;;;;N;;;;;
+153C;CANADIAN SYLLABICS WEST-CREE YWAA;Lo;0;L;;;;;N;;;;;
+153D;CANADIAN SYLLABICS NASKAPI YWAA;Lo;0;L;;;;;N;;;;;
+153E;CANADIAN SYLLABICS Y;Lo;0;L;;;;;N;;;;;
+153F;CANADIAN SYLLABICS BIBLE-CREE Y;Lo;0;L;;;;;N;;;;;
+1540;CANADIAN SYLLABICS WEST-CREE Y;Lo;0;L;;;;;N;;;;;
+1541;CANADIAN SYLLABICS SAYISI YI;Lo;0;L;;;;;N;;;;;
+1542;CANADIAN SYLLABICS RE;Lo;0;L;;;;;N;;;;;
+1543;CANADIAN SYLLABICS R-CREE RE;Lo;0;L;;;;;N;;;;;
+1544;CANADIAN SYLLABICS WEST-CREE LE;Lo;0;L;;;;;N;;;;;
+1545;CANADIAN SYLLABICS RAAI;Lo;0;L;;;;;N;;;;;
+1546;CANADIAN SYLLABICS RI;Lo;0;L;;;;;N;;;;;
+1547;CANADIAN SYLLABICS RII;Lo;0;L;;;;;N;;;;;
+1548;CANADIAN SYLLABICS RO;Lo;0;L;;;;;N;;;;;
+1549;CANADIAN SYLLABICS ROO;Lo;0;L;;;;;N;;;;;
+154A;CANADIAN SYLLABICS WEST-CREE LO;Lo;0;L;;;;;N;;;;;
+154B;CANADIAN SYLLABICS RA;Lo;0;L;;;;;N;;;;;
+154C;CANADIAN SYLLABICS RAA;Lo;0;L;;;;;N;;;;;
+154D;CANADIAN SYLLABICS WEST-CREE LA;Lo;0;L;;;;;N;;;;;
+154E;CANADIAN SYLLABICS RWAA;Lo;0;L;;;;;N;;;;;
+154F;CANADIAN SYLLABICS WEST-CREE RWAA;Lo;0;L;;;;;N;;;;;
+1550;CANADIAN SYLLABICS R;Lo;0;L;;;;;N;;;;;
+1551;CANADIAN SYLLABICS WEST-CREE R;Lo;0;L;;;;;N;;;;;
+1552;CANADIAN SYLLABICS MEDIAL R;Lo;0;L;;;;;N;;;;;
+1553;CANADIAN SYLLABICS FE;Lo;0;L;;;;;N;;;;;
+1554;CANADIAN SYLLABICS FAAI;Lo;0;L;;;;;N;;;;;
+1555;CANADIAN SYLLABICS FI;Lo;0;L;;;;;N;;;;;
+1556;CANADIAN SYLLABICS FII;Lo;0;L;;;;;N;;;;;
+1557;CANADIAN SYLLABICS FO;Lo;0;L;;;;;N;;;;;
+1558;CANADIAN SYLLABICS FOO;Lo;0;L;;;;;N;;;;;
+1559;CANADIAN SYLLABICS FA;Lo;0;L;;;;;N;;;;;
+155A;CANADIAN SYLLABICS FAA;Lo;0;L;;;;;N;;;;;
+155B;CANADIAN SYLLABICS FWAA;Lo;0;L;;;;;N;;;;;
+155C;CANADIAN SYLLABICS WEST-CREE FWAA;Lo;0;L;;;;;N;;;;;
+155D;CANADIAN SYLLABICS F;Lo;0;L;;;;;N;;;;;
+155E;CANADIAN SYLLABICS THE;Lo;0;L;;;;;N;;;;;
+155F;CANADIAN SYLLABICS N-CREE THE;Lo;0;L;;;;;N;;;;;
+1560;CANADIAN SYLLABICS THI;Lo;0;L;;;;;N;;;;;
+1561;CANADIAN SYLLABICS N-CREE THI;Lo;0;L;;;;;N;;;;;
+1562;CANADIAN SYLLABICS THII;Lo;0;L;;;;;N;;;;;
+1563;CANADIAN SYLLABICS N-CREE THII;Lo;0;L;;;;;N;;;;;
+1564;CANADIAN SYLLABICS THO;Lo;0;L;;;;;N;;;;;
+1565;CANADIAN SYLLABICS THOO;Lo;0;L;;;;;N;;;;;
+1566;CANADIAN SYLLABICS THA;Lo;0;L;;;;;N;;;;;
+1567;CANADIAN SYLLABICS THAA;Lo;0;L;;;;;N;;;;;
+1568;CANADIAN SYLLABICS THWAA;Lo;0;L;;;;;N;;;;;
+1569;CANADIAN SYLLABICS WEST-CREE THWAA;Lo;0;L;;;;;N;;;;;
+156A;CANADIAN SYLLABICS TH;Lo;0;L;;;;;N;;;;;
+156B;CANADIAN SYLLABICS TTHE;Lo;0;L;;;;;N;;;;;
+156C;CANADIAN SYLLABICS TTHI;Lo;0;L;;;;;N;;;;;
+156D;CANADIAN SYLLABICS TTHO;Lo;0;L;;;;;N;;;;;
+156E;CANADIAN SYLLABICS TTHA;Lo;0;L;;;;;N;;;;;
+156F;CANADIAN SYLLABICS TTH;Lo;0;L;;;;;N;;;;;
+1570;CANADIAN SYLLABICS TYE;Lo;0;L;;;;;N;;;;;
+1571;CANADIAN SYLLABICS TYI;Lo;0;L;;;;;N;;;;;
+1572;CANADIAN SYLLABICS TYO;Lo;0;L;;;;;N;;;;;
+1573;CANADIAN SYLLABICS TYA;Lo;0;L;;;;;N;;;;;
+1574;CANADIAN SYLLABICS NUNAVIK HE;Lo;0;L;;;;;N;;;;;
+1575;CANADIAN SYLLABICS NUNAVIK HI;Lo;0;L;;;;;N;;;;;
+1576;CANADIAN SYLLABICS NUNAVIK HII;Lo;0;L;;;;;N;;;;;
+1577;CANADIAN SYLLABICS NUNAVIK HO;Lo;0;L;;;;;N;;;;;
+1578;CANADIAN SYLLABICS NUNAVIK HOO;Lo;0;L;;;;;N;;;;;
+1579;CANADIAN SYLLABICS NUNAVIK HA;Lo;0;L;;;;;N;;;;;
+157A;CANADIAN SYLLABICS NUNAVIK HAA;Lo;0;L;;;;;N;;;;;
+157B;CANADIAN SYLLABICS NUNAVIK H;Lo;0;L;;;;;N;;;;;
+157C;CANADIAN SYLLABICS NUNAVUT H;Lo;0;L;;;;;N;;;;;
+157D;CANADIAN SYLLABICS HK;Lo;0;L;;;;;N;;;;;
+157E;CANADIAN SYLLABICS QAAI;Lo;0;L;;;;;N;;;;;
+157F;CANADIAN SYLLABICS QI;Lo;0;L;;;;;N;;;;;
+1580;CANADIAN SYLLABICS QII;Lo;0;L;;;;;N;;;;;
+1581;CANADIAN SYLLABICS QO;Lo;0;L;;;;;N;;;;;
+1582;CANADIAN SYLLABICS QOO;Lo;0;L;;;;;N;;;;;
+1583;CANADIAN SYLLABICS QA;Lo;0;L;;;;;N;;;;;
+1584;CANADIAN SYLLABICS QAA;Lo;0;L;;;;;N;;;;;
+1585;CANADIAN SYLLABICS Q;Lo;0;L;;;;;N;;;;;
+1586;CANADIAN SYLLABICS TLHE;Lo;0;L;;;;;N;;;;;
+1587;CANADIAN SYLLABICS TLHI;Lo;0;L;;;;;N;;;;;
+1588;CANADIAN SYLLABICS TLHO;Lo;0;L;;;;;N;;;;;
+1589;CANADIAN SYLLABICS TLHA;Lo;0;L;;;;;N;;;;;
+158A;CANADIAN SYLLABICS WEST-CREE RE;Lo;0;L;;;;;N;;;;;
+158B;CANADIAN SYLLABICS WEST-CREE RI;Lo;0;L;;;;;N;;;;;
+158C;CANADIAN SYLLABICS WEST-CREE RO;Lo;0;L;;;;;N;;;;;
+158D;CANADIAN SYLLABICS WEST-CREE RA;Lo;0;L;;;;;N;;;;;
+158E;CANADIAN SYLLABICS NGAAI;Lo;0;L;;;;;N;;;;;
+158F;CANADIAN SYLLABICS NGI;Lo;0;L;;;;;N;;;;;
+1590;CANADIAN SYLLABICS NGII;Lo;0;L;;;;;N;;;;;
+1591;CANADIAN SYLLABICS NGO;Lo;0;L;;;;;N;;;;;
+1592;CANADIAN SYLLABICS NGOO;Lo;0;L;;;;;N;;;;;
+1593;CANADIAN SYLLABICS NGA;Lo;0;L;;;;;N;;;;;
+1594;CANADIAN SYLLABICS NGAA;Lo;0;L;;;;;N;;;;;
+1595;CANADIAN SYLLABICS NG;Lo;0;L;;;;;N;;;;;
+1596;CANADIAN SYLLABICS NNG;Lo;0;L;;;;;N;;;;;
+1597;CANADIAN SYLLABICS SAYISI SHE;Lo;0;L;;;;;N;;;;;
+1598;CANADIAN SYLLABICS SAYISI SHI;Lo;0;L;;;;;N;;;;;
+1599;CANADIAN SYLLABICS SAYISI SHO;Lo;0;L;;;;;N;;;;;
+159A;CANADIAN SYLLABICS SAYISI SHA;Lo;0;L;;;;;N;;;;;
+159B;CANADIAN SYLLABICS WOODS-CREE THE;Lo;0;L;;;;;N;;;;;
+159C;CANADIAN SYLLABICS WOODS-CREE THI;Lo;0;L;;;;;N;;;;;
+159D;CANADIAN SYLLABICS WOODS-CREE THO;Lo;0;L;;;;;N;;;;;
+159E;CANADIAN SYLLABICS WOODS-CREE THA;Lo;0;L;;;;;N;;;;;
+159F;CANADIAN SYLLABICS WOODS-CREE TH;Lo;0;L;;;;;N;;;;;
+15A0;CANADIAN SYLLABICS LHI;Lo;0;L;;;;;N;;;;;
+15A1;CANADIAN SYLLABICS LHII;Lo;0;L;;;;;N;;;;;
+15A2;CANADIAN SYLLABICS LHO;Lo;0;L;;;;;N;;;;;
+15A3;CANADIAN SYLLABICS LHOO;Lo;0;L;;;;;N;;;;;
+15A4;CANADIAN SYLLABICS LHA;Lo;0;L;;;;;N;;;;;
+15A5;CANADIAN SYLLABICS LHAA;Lo;0;L;;;;;N;;;;;
+15A6;CANADIAN SYLLABICS LH;Lo;0;L;;;;;N;;;;;
+15A7;CANADIAN SYLLABICS TH-CREE THE;Lo;0;L;;;;;N;;;;;
+15A8;CANADIAN SYLLABICS TH-CREE THI;Lo;0;L;;;;;N;;;;;
+15A9;CANADIAN SYLLABICS TH-CREE THII;Lo;0;L;;;;;N;;;;;
+15AA;CANADIAN SYLLABICS TH-CREE THO;Lo;0;L;;;;;N;;;;;
+15AB;CANADIAN SYLLABICS TH-CREE THOO;Lo;0;L;;;;;N;;;;;
+15AC;CANADIAN SYLLABICS TH-CREE THA;Lo;0;L;;;;;N;;;;;
+15AD;CANADIAN SYLLABICS TH-CREE THAA;Lo;0;L;;;;;N;;;;;
+15AE;CANADIAN SYLLABICS TH-CREE TH;Lo;0;L;;;;;N;;;;;
+15AF;CANADIAN SYLLABICS AIVILIK B;Lo;0;L;;;;;N;;;;;
+15B0;CANADIAN SYLLABICS BLACKFOOT E;Lo;0;L;;;;;N;;;;;
+15B1;CANADIAN SYLLABICS BLACKFOOT I;Lo;0;L;;;;;N;;;;;
+15B2;CANADIAN SYLLABICS BLACKFOOT O;Lo;0;L;;;;;N;;;;;
+15B3;CANADIAN SYLLABICS BLACKFOOT A;Lo;0;L;;;;;N;;;;;
+15B4;CANADIAN SYLLABICS BLACKFOOT WE;Lo;0;L;;;;;N;;;;;
+15B5;CANADIAN SYLLABICS BLACKFOOT WI;Lo;0;L;;;;;N;;;;;
+15B6;CANADIAN SYLLABICS BLACKFOOT WO;Lo;0;L;;;;;N;;;;;
+15B7;CANADIAN SYLLABICS BLACKFOOT WA;Lo;0;L;;;;;N;;;;;
+15B8;CANADIAN SYLLABICS BLACKFOOT NE;Lo;0;L;;;;;N;;;;;
+15B9;CANADIAN SYLLABICS BLACKFOOT NI;Lo;0;L;;;;;N;;;;;
+15BA;CANADIAN SYLLABICS BLACKFOOT NO;Lo;0;L;;;;;N;;;;;
+15BB;CANADIAN SYLLABICS BLACKFOOT NA;Lo;0;L;;;;;N;;;;;
+15BC;CANADIAN SYLLABICS BLACKFOOT KE;Lo;0;L;;;;;N;;;;;
+15BD;CANADIAN SYLLABICS BLACKFOOT KI;Lo;0;L;;;;;N;;;;;
+15BE;CANADIAN SYLLABICS BLACKFOOT KO;Lo;0;L;;;;;N;;;;;
+15BF;CANADIAN SYLLABICS BLACKFOOT KA;Lo;0;L;;;;;N;;;;;
+15C0;CANADIAN SYLLABICS SAYISI HE;Lo;0;L;;;;;N;;;;;
+15C1;CANADIAN SYLLABICS SAYISI HI;Lo;0;L;;;;;N;;;;;
+15C2;CANADIAN SYLLABICS SAYISI HO;Lo;0;L;;;;;N;;;;;
+15C3;CANADIAN SYLLABICS SAYISI HA;Lo;0;L;;;;;N;;;;;
+15C4;CANADIAN SYLLABICS CARRIER GHU;Lo;0;L;;;;;N;;;;;
+15C5;CANADIAN SYLLABICS CARRIER GHO;Lo;0;L;;;;;N;;;;;
+15C6;CANADIAN SYLLABICS CARRIER GHE;Lo;0;L;;;;;N;;;;;
+15C7;CANADIAN SYLLABICS CARRIER GHEE;Lo;0;L;;;;;N;;;;;
+15C8;CANADIAN SYLLABICS CARRIER GHI;Lo;0;L;;;;;N;;;;;
+15C9;CANADIAN SYLLABICS CARRIER GHA;Lo;0;L;;;;;N;;;;;
+15CA;CANADIAN SYLLABICS CARRIER RU;Lo;0;L;;;;;N;;;;;
+15CB;CANADIAN SYLLABICS CARRIER RO;Lo;0;L;;;;;N;;;;;
+15CC;CANADIAN SYLLABICS CARRIER RE;Lo;0;L;;;;;N;;;;;
+15CD;CANADIAN SYLLABICS CARRIER REE;Lo;0;L;;;;;N;;;;;
+15CE;CANADIAN SYLLABICS CARRIER RI;Lo;0;L;;;;;N;;;;;
+15CF;CANADIAN SYLLABICS CARRIER RA;Lo;0;L;;;;;N;;;;;
+15D0;CANADIAN SYLLABICS CARRIER WU;Lo;0;L;;;;;N;;;;;
+15D1;CANADIAN SYLLABICS CARRIER WO;Lo;0;L;;;;;N;;;;;
+15D2;CANADIAN SYLLABICS CARRIER WE;Lo;0;L;;;;;N;;;;;
+15D3;CANADIAN SYLLABICS CARRIER WEE;Lo;0;L;;;;;N;;;;;
+15D4;CANADIAN SYLLABICS CARRIER WI;Lo;0;L;;;;;N;;;;;
+15D5;CANADIAN SYLLABICS CARRIER WA;Lo;0;L;;;;;N;;;;;
+15D6;CANADIAN SYLLABICS CARRIER HWU;Lo;0;L;;;;;N;;;;;
+15D7;CANADIAN SYLLABICS CARRIER HWO;Lo;0;L;;;;;N;;;;;
+15D8;CANADIAN SYLLABICS CARRIER HWE;Lo;0;L;;;;;N;;;;;
+15D9;CANADIAN SYLLABICS CARRIER HWEE;Lo;0;L;;;;;N;;;;;
+15DA;CANADIAN SYLLABICS CARRIER HWI;Lo;0;L;;;;;N;;;;;
+15DB;CANADIAN SYLLABICS CARRIER HWA;Lo;0;L;;;;;N;;;;;
+15DC;CANADIAN SYLLABICS CARRIER THU;Lo;0;L;;;;;N;;;;;
+15DD;CANADIAN SYLLABICS CARRIER THO;Lo;0;L;;;;;N;;;;;
+15DE;CANADIAN SYLLABICS CARRIER THE;Lo;0;L;;;;;N;;;;;
+15DF;CANADIAN SYLLABICS CARRIER THEE;Lo;0;L;;;;;N;;;;;
+15E0;CANADIAN SYLLABICS CARRIER THI;Lo;0;L;;;;;N;;;;;
+15E1;CANADIAN SYLLABICS CARRIER THA;Lo;0;L;;;;;N;;;;;
+15E2;CANADIAN SYLLABICS CARRIER TTU;Lo;0;L;;;;;N;;;;;
+15E3;CANADIAN SYLLABICS CARRIER TTO;Lo;0;L;;;;;N;;;;;
+15E4;CANADIAN SYLLABICS CARRIER TTE;Lo;0;L;;;;;N;;;;;
+15E5;CANADIAN SYLLABICS CARRIER TTEE;Lo;0;L;;;;;N;;;;;
+15E6;CANADIAN SYLLABICS CARRIER TTI;Lo;0;L;;;;;N;;;;;
+15E7;CANADIAN SYLLABICS CARRIER TTA;Lo;0;L;;;;;N;;;;;
+15E8;CANADIAN SYLLABICS CARRIER PU;Lo;0;L;;;;;N;;;;;
+15E9;CANADIAN SYLLABICS CARRIER PO;Lo;0;L;;;;;N;;;;;
+15EA;CANADIAN SYLLABICS CARRIER PE;Lo;0;L;;;;;N;;;;;
+15EB;CANADIAN SYLLABICS CARRIER PEE;Lo;0;L;;;;;N;;;;;
+15EC;CANADIAN SYLLABICS CARRIER PI;Lo;0;L;;;;;N;;;;;
+15ED;CANADIAN SYLLABICS CARRIER PA;Lo;0;L;;;;;N;;;;;
+15EE;CANADIAN SYLLABICS CARRIER P;Lo;0;L;;;;;N;;;;;
+15EF;CANADIAN SYLLABICS CARRIER GU;Lo;0;L;;;;;N;;;;;
+15F0;CANADIAN SYLLABICS CARRIER GO;Lo;0;L;;;;;N;;;;;
+15F1;CANADIAN SYLLABICS CARRIER GE;Lo;0;L;;;;;N;;;;;
+15F2;CANADIAN SYLLABICS CARRIER GEE;Lo;0;L;;;;;N;;;;;
+15F3;CANADIAN SYLLABICS CARRIER GI;Lo;0;L;;;;;N;;;;;
+15F4;CANADIAN SYLLABICS CARRIER GA;Lo;0;L;;;;;N;;;;;
+15F5;CANADIAN SYLLABICS CARRIER KHU;Lo;0;L;;;;;N;;;;;
+15F6;CANADIAN SYLLABICS CARRIER KHO;Lo;0;L;;;;;N;;;;;
+15F7;CANADIAN SYLLABICS CARRIER KHE;Lo;0;L;;;;;N;;;;;
+15F8;CANADIAN SYLLABICS CARRIER KHEE;Lo;0;L;;;;;N;;;;;
+15F9;CANADIAN SYLLABICS CARRIER KHI;Lo;0;L;;;;;N;;;;;
+15FA;CANADIAN SYLLABICS CARRIER KHA;Lo;0;L;;;;;N;;;;;
+15FB;CANADIAN SYLLABICS CARRIER KKU;Lo;0;L;;;;;N;;;;;
+15FC;CANADIAN SYLLABICS CARRIER KKO;Lo;0;L;;;;;N;;;;;
+15FD;CANADIAN SYLLABICS CARRIER KKE;Lo;0;L;;;;;N;;;;;
+15FE;CANADIAN SYLLABICS CARRIER KKEE;Lo;0;L;;;;;N;;;;;
+15FF;CANADIAN SYLLABICS CARRIER KKI;Lo;0;L;;;;;N;;;;;
+1600;CANADIAN SYLLABICS CARRIER KKA;Lo;0;L;;;;;N;;;;;
+1601;CANADIAN SYLLABICS CARRIER KK;Lo;0;L;;;;;N;;;;;
+1602;CANADIAN SYLLABICS CARRIER NU;Lo;0;L;;;;;N;;;;;
+1603;CANADIAN SYLLABICS CARRIER NO;Lo;0;L;;;;;N;;;;;
+1604;CANADIAN SYLLABICS CARRIER NE;Lo;0;L;;;;;N;;;;;
+1605;CANADIAN SYLLABICS CARRIER NEE;Lo;0;L;;;;;N;;;;;
+1606;CANADIAN SYLLABICS CARRIER NI;Lo;0;L;;;;;N;;;;;
+1607;CANADIAN SYLLABICS CARRIER NA;Lo;0;L;;;;;N;;;;;
+1608;CANADIAN SYLLABICS CARRIER MU;Lo;0;L;;;;;N;;;;;
+1609;CANADIAN SYLLABICS CARRIER MO;Lo;0;L;;;;;N;;;;;
+160A;CANADIAN SYLLABICS CARRIER ME;Lo;0;L;;;;;N;;;;;
+160B;CANADIAN SYLLABICS CARRIER MEE;Lo;0;L;;;;;N;;;;;
+160C;CANADIAN SYLLABICS CARRIER MI;Lo;0;L;;;;;N;;;;;
+160D;CANADIAN SYLLABICS CARRIER MA;Lo;0;L;;;;;N;;;;;
+160E;CANADIAN SYLLABICS CARRIER YU;Lo;0;L;;;;;N;;;;;
+160F;CANADIAN SYLLABICS CARRIER YO;Lo;0;L;;;;;N;;;;;
+1610;CANADIAN SYLLABICS CARRIER YE;Lo;0;L;;;;;N;;;;;
+1611;CANADIAN SYLLABICS CARRIER YEE;Lo;0;L;;;;;N;;;;;
+1612;CANADIAN SYLLABICS CARRIER YI;Lo;0;L;;;;;N;;;;;
+1613;CANADIAN SYLLABICS CARRIER YA;Lo;0;L;;;;;N;;;;;
+1614;CANADIAN SYLLABICS CARRIER JU;Lo;0;L;;;;;N;;;;;
+1615;CANADIAN SYLLABICS SAYISI JU;Lo;0;L;;;;;N;;;;;
+1616;CANADIAN SYLLABICS CARRIER JO;Lo;0;L;;;;;N;;;;;
+1617;CANADIAN SYLLABICS CARRIER JE;Lo;0;L;;;;;N;;;;;
+1618;CANADIAN SYLLABICS CARRIER JEE;Lo;0;L;;;;;N;;;;;
+1619;CANADIAN SYLLABICS CARRIER JI;Lo;0;L;;;;;N;;;;;
+161A;CANADIAN SYLLABICS SAYISI JI;Lo;0;L;;;;;N;;;;;
+161B;CANADIAN SYLLABICS CARRIER JA;Lo;0;L;;;;;N;;;;;
+161C;CANADIAN SYLLABICS CARRIER JJU;Lo;0;L;;;;;N;;;;;
+161D;CANADIAN SYLLABICS CARRIER JJO;Lo;0;L;;;;;N;;;;;
+161E;CANADIAN SYLLABICS CARRIER JJE;Lo;0;L;;;;;N;;;;;
+161F;CANADIAN SYLLABICS CARRIER JJEE;Lo;0;L;;;;;N;;;;;
+1620;CANADIAN SYLLABICS CARRIER JJI;Lo;0;L;;;;;N;;;;;
+1621;CANADIAN SYLLABICS CARRIER JJA;Lo;0;L;;;;;N;;;;;
+1622;CANADIAN SYLLABICS CARRIER LU;Lo;0;L;;;;;N;;;;;
+1623;CANADIAN SYLLABICS CARRIER LO;Lo;0;L;;;;;N;;;;;
+1624;CANADIAN SYLLABICS CARRIER LE;Lo;0;L;;;;;N;;;;;
+1625;CANADIAN SYLLABICS CARRIER LEE;Lo;0;L;;;;;N;;;;;
+1626;CANADIAN SYLLABICS CARRIER LI;Lo;0;L;;;;;N;;;;;
+1627;CANADIAN SYLLABICS CARRIER LA;Lo;0;L;;;;;N;;;;;
+1628;CANADIAN SYLLABICS CARRIER DLU;Lo;0;L;;;;;N;;;;;
+1629;CANADIAN SYLLABICS CARRIER DLO;Lo;0;L;;;;;N;;;;;
+162A;CANADIAN SYLLABICS CARRIER DLE;Lo;0;L;;;;;N;;;;;
+162B;CANADIAN SYLLABICS CARRIER DLEE;Lo;0;L;;;;;N;;;;;
+162C;CANADIAN SYLLABICS CARRIER DLI;Lo;0;L;;;;;N;;;;;
+162D;CANADIAN SYLLABICS CARRIER DLA;Lo;0;L;;;;;N;;;;;
+162E;CANADIAN SYLLABICS CARRIER LHU;Lo;0;L;;;;;N;;;;;
+162F;CANADIAN SYLLABICS CARRIER LHO;Lo;0;L;;;;;N;;;;;
+1630;CANADIAN SYLLABICS CARRIER LHE;Lo;0;L;;;;;N;;;;;
+1631;CANADIAN SYLLABICS CARRIER LHEE;Lo;0;L;;;;;N;;;;;
+1632;CANADIAN SYLLABICS CARRIER LHI;Lo;0;L;;;;;N;;;;;
+1633;CANADIAN SYLLABICS CARRIER LHA;Lo;0;L;;;;;N;;;;;
+1634;CANADIAN SYLLABICS CARRIER TLHU;Lo;0;L;;;;;N;;;;;
+1635;CANADIAN SYLLABICS CARRIER TLHO;Lo;0;L;;;;;N;;;;;
+1636;CANADIAN SYLLABICS CARRIER TLHE;Lo;0;L;;;;;N;;;;;
+1637;CANADIAN SYLLABICS CARRIER TLHEE;Lo;0;L;;;;;N;;;;;
+1638;CANADIAN SYLLABICS CARRIER TLHI;Lo;0;L;;;;;N;;;;;
+1639;CANADIAN SYLLABICS CARRIER TLHA;Lo;0;L;;;;;N;;;;;
+163A;CANADIAN SYLLABICS CARRIER TLU;Lo;0;L;;;;;N;;;;;
+163B;CANADIAN SYLLABICS CARRIER TLO;Lo;0;L;;;;;N;;;;;
+163C;CANADIAN SYLLABICS CARRIER TLE;Lo;0;L;;;;;N;;;;;
+163D;CANADIAN SYLLABICS CARRIER TLEE;Lo;0;L;;;;;N;;;;;
+163E;CANADIAN SYLLABICS CARRIER TLI;Lo;0;L;;;;;N;;;;;
+163F;CANADIAN SYLLABICS CARRIER TLA;Lo;0;L;;;;;N;;;;;
+1640;CANADIAN SYLLABICS CARRIER ZU;Lo;0;L;;;;;N;;;;;
+1641;CANADIAN SYLLABICS CARRIER ZO;Lo;0;L;;;;;N;;;;;
+1642;CANADIAN SYLLABICS CARRIER ZE;Lo;0;L;;;;;N;;;;;
+1643;CANADIAN SYLLABICS CARRIER ZEE;Lo;0;L;;;;;N;;;;;
+1644;CANADIAN SYLLABICS CARRIER ZI;Lo;0;L;;;;;N;;;;;
+1645;CANADIAN SYLLABICS CARRIER ZA;Lo;0;L;;;;;N;;;;;
+1646;CANADIAN SYLLABICS CARRIER Z;Lo;0;L;;;;;N;;;;;
+1647;CANADIAN SYLLABICS CARRIER INITIAL Z;Lo;0;L;;;;;N;;;;;
+1648;CANADIAN SYLLABICS CARRIER DZU;Lo;0;L;;;;;N;;;;;
+1649;CANADIAN SYLLABICS CARRIER DZO;Lo;0;L;;;;;N;;;;;
+164A;CANADIAN SYLLABICS CARRIER DZE;Lo;0;L;;;;;N;;;;;
+164B;CANADIAN SYLLABICS CARRIER DZEE;Lo;0;L;;;;;N;;;;;
+164C;CANADIAN SYLLABICS CARRIER DZI;Lo;0;L;;;;;N;;;;;
+164D;CANADIAN SYLLABICS CARRIER DZA;Lo;0;L;;;;;N;;;;;
+164E;CANADIAN SYLLABICS CARRIER SU;Lo;0;L;;;;;N;;;;;
+164F;CANADIAN SYLLABICS CARRIER SO;Lo;0;L;;;;;N;;;;;
+1650;CANADIAN SYLLABICS CARRIER SE;Lo;0;L;;;;;N;;;;;
+1651;CANADIAN SYLLABICS CARRIER SEE;Lo;0;L;;;;;N;;;;;
+1652;CANADIAN SYLLABICS CARRIER SI;Lo;0;L;;;;;N;;;;;
+1653;CANADIAN SYLLABICS CARRIER SA;Lo;0;L;;;;;N;;;;;
+1654;CANADIAN SYLLABICS CARRIER SHU;Lo;0;L;;;;;N;;;;;
+1655;CANADIAN SYLLABICS CARRIER SHO;Lo;0;L;;;;;N;;;;;
+1656;CANADIAN SYLLABICS CARRIER SHE;Lo;0;L;;;;;N;;;;;
+1657;CANADIAN SYLLABICS CARRIER SHEE;Lo;0;L;;;;;N;;;;;
+1658;CANADIAN SYLLABICS CARRIER SHI;Lo;0;L;;;;;N;;;;;
+1659;CANADIAN SYLLABICS CARRIER SHA;Lo;0;L;;;;;N;;;;;
+165A;CANADIAN SYLLABICS CARRIER SH;Lo;0;L;;;;;N;;;;;
+165B;CANADIAN SYLLABICS CARRIER TSU;Lo;0;L;;;;;N;;;;;
+165C;CANADIAN SYLLABICS CARRIER TSO;Lo;0;L;;;;;N;;;;;
+165D;CANADIAN SYLLABICS CARRIER TSE;Lo;0;L;;;;;N;;;;;
+165E;CANADIAN SYLLABICS CARRIER TSEE;Lo;0;L;;;;;N;;;;;
+165F;CANADIAN SYLLABICS CARRIER TSI;Lo;0;L;;;;;N;;;;;
+1660;CANADIAN SYLLABICS CARRIER TSA;Lo;0;L;;;;;N;;;;;
+1661;CANADIAN SYLLABICS CARRIER CHU;Lo;0;L;;;;;N;;;;;
+1662;CANADIAN SYLLABICS CARRIER CHO;Lo;0;L;;;;;N;;;;;
+1663;CANADIAN SYLLABICS CARRIER CHE;Lo;0;L;;;;;N;;;;;
+1664;CANADIAN SYLLABICS CARRIER CHEE;Lo;0;L;;;;;N;;;;;
+1665;CANADIAN SYLLABICS CARRIER CHI;Lo;0;L;;;;;N;;;;;
+1666;CANADIAN SYLLABICS CARRIER CHA;Lo;0;L;;;;;N;;;;;
+1667;CANADIAN SYLLABICS CARRIER TTSU;Lo;0;L;;;;;N;;;;;
+1668;CANADIAN SYLLABICS CARRIER TTSO;Lo;0;L;;;;;N;;;;;
+1669;CANADIAN SYLLABICS CARRIER TTSE;Lo;0;L;;;;;N;;;;;
+166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;;
+166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;;
+166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;;
+166D;CANADIAN SYLLABICS CHI SIGN;Po;0;L;;;;;N;;;;;
+166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;;
+166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;;
+1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;;
+1671;CANADIAN SYLLABICS NNGI;Lo;0;L;;;;;N;;;;;
+1672;CANADIAN SYLLABICS NNGII;Lo;0;L;;;;;N;;;;;
+1673;CANADIAN SYLLABICS NNGO;Lo;0;L;;;;;N;;;;;
+1674;CANADIAN SYLLABICS NNGOO;Lo;0;L;;;;;N;;;;;
+1675;CANADIAN SYLLABICS NNGA;Lo;0;L;;;;;N;;;;;
+1676;CANADIAN SYLLABICS NNGAA;Lo;0;L;;;;;N;;;;;
+1677;CANADIAN SYLLABICS WOODS-CREE THWEE;Lo;0;L;;;;;N;;;;;
+1678;CANADIAN SYLLABICS WOODS-CREE THWI;Lo;0;L;;;;;N;;;;;
+1679;CANADIAN SYLLABICS WOODS-CREE THWII;Lo;0;L;;;;;N;;;;;
+167A;CANADIAN SYLLABICS WOODS-CREE THWO;Lo;0;L;;;;;N;;;;;
+167B;CANADIAN SYLLABICS WOODS-CREE THWOO;Lo;0;L;;;;;N;;;;;
+167C;CANADIAN SYLLABICS WOODS-CREE THWA;Lo;0;L;;;;;N;;;;;
+167D;CANADIAN SYLLABICS WOODS-CREE THWAA;Lo;0;L;;;;;N;;;;;
+167E;CANADIAN SYLLABICS WOODS-CREE FINAL TH;Lo;0;L;;;;;N;;;;;
+167F;CANADIAN SYLLABICS BLACKFOOT W;Lo;0;L;;;;;N;;;;;
+1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;;
+1681;OGHAM LETTER BEITH;Lo;0;L;;;;;N;;;;;
+1682;OGHAM LETTER LUIS;Lo;0;L;;;;;N;;;;;
+1683;OGHAM LETTER FEARN;Lo;0;L;;;;;N;;;;;
+1684;OGHAM LETTER SAIL;Lo;0;L;;;;;N;;;;;
+1685;OGHAM LETTER NION;Lo;0;L;;;;;N;;;;;
+1686;OGHAM LETTER UATH;Lo;0;L;;;;;N;;;;;
+1687;OGHAM LETTER DAIR;Lo;0;L;;;;;N;;;;;
+1688;OGHAM LETTER TINNE;Lo;0;L;;;;;N;;;;;
+1689;OGHAM LETTER COLL;Lo;0;L;;;;;N;;;;;
+168A;OGHAM LETTER CEIRT;Lo;0;L;;;;;N;;;;;
+168B;OGHAM LETTER MUIN;Lo;0;L;;;;;N;;;;;
+168C;OGHAM LETTER GORT;Lo;0;L;;;;;N;;;;;
+168D;OGHAM LETTER NGEADAL;Lo;0;L;;;;;N;;;;;
+168E;OGHAM LETTER STRAIF;Lo;0;L;;;;;N;;;;;
+168F;OGHAM LETTER RUIS;Lo;0;L;;;;;N;;;;;
+1690;OGHAM LETTER AILM;Lo;0;L;;;;;N;;;;;
+1691;OGHAM LETTER ONN;Lo;0;L;;;;;N;;;;;
+1692;OGHAM LETTER UR;Lo;0;L;;;;;N;;;;;
+1693;OGHAM LETTER EADHADH;Lo;0;L;;;;;N;;;;;
+1694;OGHAM LETTER IODHADH;Lo;0;L;;;;;N;;;;;
+1695;OGHAM LETTER EABHADH;Lo;0;L;;;;;N;;;;;
+1696;OGHAM LETTER OR;Lo;0;L;;;;;N;;;;;
+1697;OGHAM LETTER UILLEANN;Lo;0;L;;;;;N;;;;;
+1698;OGHAM LETTER IFIN;Lo;0;L;;;;;N;;;;;
+1699;OGHAM LETTER EAMHANCHOLL;Lo;0;L;;;;;N;;;;;
+169A;OGHAM LETTER PEITH;Lo;0;L;;;;;N;;;;;
+169B;OGHAM FEATHER MARK;Ps;0;ON;;;;;Y;;;;;
+169C;OGHAM REVERSED FEATHER MARK;Pe;0;ON;;;;;Y;;;;;
+16A0;RUNIC LETTER FEHU FEOH FE F;Lo;0;L;;;;;N;;;;;
+16A1;RUNIC LETTER V;Lo;0;L;;;;;N;;;;;
+16A2;RUNIC LETTER URUZ UR U;Lo;0;L;;;;;N;;;;;
+16A3;RUNIC LETTER YR;Lo;0;L;;;;;N;;;;;
+16A4;RUNIC LETTER Y;Lo;0;L;;;;;N;;;;;
+16A5;RUNIC LETTER W;Lo;0;L;;;;;N;;;;;
+16A6;RUNIC LETTER THURISAZ THURS THORN;Lo;0;L;;;;;N;;;;;
+16A7;RUNIC LETTER ETH;Lo;0;L;;;;;N;;;;;
+16A8;RUNIC LETTER ANSUZ A;Lo;0;L;;;;;N;;;;;
+16A9;RUNIC LETTER OS O;Lo;0;L;;;;;N;;;;;
+16AA;RUNIC LETTER AC A;Lo;0;L;;;;;N;;;;;
+16AB;RUNIC LETTER AESC;Lo;0;L;;;;;N;;;;;
+16AC;RUNIC LETTER LONG-BRANCH-OSS O;Lo;0;L;;;;;N;;;;;
+16AD;RUNIC LETTER SHORT-TWIG-OSS O;Lo;0;L;;;;;N;;;;;
+16AE;RUNIC LETTER O;Lo;0;L;;;;;N;;;;;
+16AF;RUNIC LETTER OE;Lo;0;L;;;;;N;;;;;
+16B0;RUNIC LETTER ON;Lo;0;L;;;;;N;;;;;
+16B1;RUNIC LETTER RAIDO RAD REID R;Lo;0;L;;;;;N;;;;;
+16B2;RUNIC LETTER KAUNA;Lo;0;L;;;;;N;;;;;
+16B3;RUNIC LETTER CEN;Lo;0;L;;;;;N;;;;;
+16B4;RUNIC LETTER KAUN K;Lo;0;L;;;;;N;;;;;
+16B5;RUNIC LETTER G;Lo;0;L;;;;;N;;;;;
+16B6;RUNIC LETTER ENG;Lo;0;L;;;;;N;;;;;
+16B7;RUNIC LETTER GEBO GYFU G;Lo;0;L;;;;;N;;;;;
+16B8;RUNIC LETTER GAR;Lo;0;L;;;;;N;;;;;
+16B9;RUNIC LETTER WUNJO WYNN W;Lo;0;L;;;;;N;;;;;
+16BA;RUNIC LETTER HAGLAZ H;Lo;0;L;;;;;N;;;;;
+16BB;RUNIC LETTER HAEGL H;Lo;0;L;;;;;N;;;;;
+16BC;RUNIC LETTER LONG-BRANCH-HAGALL H;Lo;0;L;;;;;N;;;;;
+16BD;RUNIC LETTER SHORT-TWIG-HAGALL H;Lo;0;L;;;;;N;;;;;
+16BE;RUNIC LETTER NAUDIZ NYD NAUD N;Lo;0;L;;;;;N;;;;;
+16BF;RUNIC LETTER SHORT-TWIG-NAUD N;Lo;0;L;;;;;N;;;;;
+16C0;RUNIC LETTER DOTTED-N;Lo;0;L;;;;;N;;;;;
+16C1;RUNIC LETTER ISAZ IS ISS I;Lo;0;L;;;;;N;;;;;
+16C2;RUNIC LETTER E;Lo;0;L;;;;;N;;;;;
+16C3;RUNIC LETTER JERAN J;Lo;0;L;;;;;N;;;;;
+16C4;RUNIC LETTER GER;Lo;0;L;;;;;N;;;;;
+16C5;RUNIC LETTER LONG-BRANCH-AR AE;Lo;0;L;;;;;N;;;;;
+16C6;RUNIC LETTER SHORT-TWIG-AR A;Lo;0;L;;;;;N;;;;;
+16C7;RUNIC LETTER IWAZ EOH;Lo;0;L;;;;;N;;;;;
+16C8;RUNIC LETTER PERTHO PEORTH P;Lo;0;L;;;;;N;;;;;
+16C9;RUNIC LETTER ALGIZ EOLHX;Lo;0;L;;;;;N;;;;;
+16CA;RUNIC LETTER SOWILO S;Lo;0;L;;;;;N;;;;;
+16CB;RUNIC LETTER SIGEL LONG-BRANCH-SOL S;Lo;0;L;;;;;N;;;;;
+16CC;RUNIC LETTER SHORT-TWIG-SOL S;Lo;0;L;;;;;N;;;;;
+16CD;RUNIC LETTER C;Lo;0;L;;;;;N;;;;;
+16CE;RUNIC LETTER Z;Lo;0;L;;;;;N;;;;;
+16CF;RUNIC LETTER TIWAZ TIR TYR T;Lo;0;L;;;;;N;;;;;
+16D0;RUNIC LETTER SHORT-TWIG-TYR T;Lo;0;L;;;;;N;;;;;
+16D1;RUNIC LETTER D;Lo;0;L;;;;;N;;;;;
+16D2;RUNIC LETTER BERKANAN BEORC BJARKAN B;Lo;0;L;;;;;N;;;;;
+16D3;RUNIC LETTER SHORT-TWIG-BJARKAN B;Lo;0;L;;;;;N;;;;;
+16D4;RUNIC LETTER DOTTED-P;Lo;0;L;;;;;N;;;;;
+16D5;RUNIC LETTER OPEN-P;Lo;0;L;;;;;N;;;;;
+16D6;RUNIC LETTER EHWAZ EH E;Lo;0;L;;;;;N;;;;;
+16D7;RUNIC LETTER MANNAZ MAN M;Lo;0;L;;;;;N;;;;;
+16D8;RUNIC LETTER LONG-BRANCH-MADR M;Lo;0;L;;;;;N;;;;;
+16D9;RUNIC LETTER SHORT-TWIG-MADR M;Lo;0;L;;;;;N;;;;;
+16DA;RUNIC LETTER LAUKAZ LAGU LOGR L;Lo;0;L;;;;;N;;;;;
+16DB;RUNIC LETTER DOTTED-L;Lo;0;L;;;;;N;;;;;
+16DC;RUNIC LETTER INGWAZ;Lo;0;L;;;;;N;;;;;
+16DD;RUNIC LETTER ING;Lo;0;L;;;;;N;;;;;
+16DE;RUNIC LETTER DAGAZ DAEG D;Lo;0;L;;;;;N;;;;;
+16DF;RUNIC LETTER OTHALAN ETHEL O;Lo;0;L;;;;;N;;;;;
+16E0;RUNIC LETTER EAR;Lo;0;L;;;;;N;;;;;
+16E1;RUNIC LETTER IOR;Lo;0;L;;;;;N;;;;;
+16E2;RUNIC LETTER CWEORTH;Lo;0;L;;;;;N;;;;;
+16E3;RUNIC LETTER CALC;Lo;0;L;;;;;N;;;;;
+16E4;RUNIC LETTER CEALC;Lo;0;L;;;;;N;;;;;
+16E5;RUNIC LETTER STAN;Lo;0;L;;;;;N;;;;;
+16E6;RUNIC LETTER LONG-BRANCH-YR;Lo;0;L;;;;;N;;;;;
+16E7;RUNIC LETTER SHORT-TWIG-YR;Lo;0;L;;;;;N;;;;;
+16E8;RUNIC LETTER ICELANDIC-YR;Lo;0;L;;;;;N;;;;;
+16E9;RUNIC LETTER Q;Lo;0;L;;;;;N;;;;;
+16EA;RUNIC LETTER X;Lo;0;L;;;;;N;;;;;
+16EB;RUNIC SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;;
+16EC;RUNIC MULTIPLE PUNCTUATION;Po;0;L;;;;;N;;;;;
+16ED;RUNIC CROSS PUNCTUATION;Po;0;L;;;;;N;;;;;
+16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;;;;
+16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;;;;
+16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;;;;
+16F1;RUNIC LETTER K;Lo;0;L;;;;;N;;;;;
+16F2;RUNIC LETTER SH;Lo;0;L;;;;;N;;;;;
+16F3;RUNIC LETTER OO;Lo;0;L;;;;;N;;;;;
+16F4;RUNIC LETTER FRANKS CASKET OS;Lo;0;L;;;;;N;;;;;
+16F5;RUNIC LETTER FRANKS CASKET IS;Lo;0;L;;;;;N;;;;;
+16F6;RUNIC LETTER FRANKS CASKET EH;Lo;0;L;;;;;N;;;;;
+16F7;RUNIC LETTER FRANKS CASKET AC;Lo;0;L;;;;;N;;;;;
+16F8;RUNIC LETTER FRANKS CASKET AESC;Lo;0;L;;;;;N;;;;;
+1700;TAGALOG LETTER A;Lo;0;L;;;;;N;;;;;
+1701;TAGALOG LETTER I;Lo;0;L;;;;;N;;;;;
+1702;TAGALOG LETTER U;Lo;0;L;;;;;N;;;;;
+1703;TAGALOG LETTER KA;Lo;0;L;;;;;N;;;;;
+1704;TAGALOG LETTER GA;Lo;0;L;;;;;N;;;;;
+1705;TAGALOG LETTER NGA;Lo;0;L;;;;;N;;;;;
+1706;TAGALOG LETTER TA;Lo;0;L;;;;;N;;;;;
+1707;TAGALOG LETTER DA;Lo;0;L;;;;;N;;;;;
+1708;TAGALOG LETTER NA;Lo;0;L;;;;;N;;;;;
+1709;TAGALOG LETTER PA;Lo;0;L;;;;;N;;;;;
+170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;;
+170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;;
+170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;;
+170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;;
+170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;;
+1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;;
+1711;TAGALOG LETTER HA;Lo;0;L;;;;;N;;;;;
+1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;;
+1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;;
+1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;;
+1723;HANUNOO LETTER KA;Lo;0;L;;;;;N;;;;;
+1724;HANUNOO LETTER GA;Lo;0;L;;;;;N;;;;;
+1725;HANUNOO LETTER NGA;Lo;0;L;;;;;N;;;;;
+1726;HANUNOO LETTER TA;Lo;0;L;;;;;N;;;;;
+1727;HANUNOO LETTER DA;Lo;0;L;;;;;N;;;;;
+1728;HANUNOO LETTER NA;Lo;0;L;;;;;N;;;;;
+1729;HANUNOO LETTER PA;Lo;0;L;;;;;N;;;;;
+172A;HANUNOO LETTER BA;Lo;0;L;;;;;N;;;;;
+172B;HANUNOO LETTER MA;Lo;0;L;;;;;N;;;;;
+172C;HANUNOO LETTER YA;Lo;0;L;;;;;N;;;;;
+172D;HANUNOO LETTER RA;Lo;0;L;;;;;N;;;;;
+172E;HANUNOO LETTER LA;Lo;0;L;;;;;N;;;;;
+172F;HANUNOO LETTER WA;Lo;0;L;;;;;N;;;;;
+1730;HANUNOO LETTER SA;Lo;0;L;;;;;N;;;;;
+1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;;
+1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;;
+1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;;
+1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;;
+1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;;
+1741;BUHID LETTER I;Lo;0;L;;;;;N;;;;;
+1742;BUHID LETTER U;Lo;0;L;;;;;N;;;;;
+1743;BUHID LETTER KA;Lo;0;L;;;;;N;;;;;
+1744;BUHID LETTER GA;Lo;0;L;;;;;N;;;;;
+1745;BUHID LETTER NGA;Lo;0;L;;;;;N;;;;;
+1746;BUHID LETTER TA;Lo;0;L;;;;;N;;;;;
+1747;BUHID LETTER DA;Lo;0;L;;;;;N;;;;;
+1748;BUHID LETTER NA;Lo;0;L;;;;;N;;;;;
+1749;BUHID LETTER PA;Lo;0;L;;;;;N;;;;;
+174A;BUHID LETTER BA;Lo;0;L;;;;;N;;;;;
+174B;BUHID LETTER MA;Lo;0;L;;;;;N;;;;;
+174C;BUHID LETTER YA;Lo;0;L;;;;;N;;;;;
+174D;BUHID LETTER RA;Lo;0;L;;;;;N;;;;;
+174E;BUHID LETTER LA;Lo;0;L;;;;;N;;;;;
+174F;BUHID LETTER WA;Lo;0;L;;;;;N;;;;;
+1750;BUHID LETTER SA;Lo;0;L;;;;;N;;;;;
+1751;BUHID LETTER HA;Lo;0;L;;;;;N;;;;;
+1752;BUHID VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1753;BUHID VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1760;TAGBANWA LETTER A;Lo;0;L;;;;;N;;;;;
+1761;TAGBANWA LETTER I;Lo;0;L;;;;;N;;;;;
+1762;TAGBANWA LETTER U;Lo;0;L;;;;;N;;;;;
+1763;TAGBANWA LETTER KA;Lo;0;L;;;;;N;;;;;
+1764;TAGBANWA LETTER GA;Lo;0;L;;;;;N;;;;;
+1765;TAGBANWA LETTER NGA;Lo;0;L;;;;;N;;;;;
+1766;TAGBANWA LETTER TA;Lo;0;L;;;;;N;;;;;
+1767;TAGBANWA LETTER DA;Lo;0;L;;;;;N;;;;;
+1768;TAGBANWA LETTER NA;Lo;0;L;;;;;N;;;;;
+1769;TAGBANWA LETTER PA;Lo;0;L;;;;;N;;;;;
+176A;TAGBANWA LETTER BA;Lo;0;L;;;;;N;;;;;
+176B;TAGBANWA LETTER MA;Lo;0;L;;;;;N;;;;;
+176C;TAGBANWA LETTER YA;Lo;0;L;;;;;N;;;;;
+176E;TAGBANWA LETTER LA;Lo;0;L;;;;;N;;;;;
+176F;TAGBANWA LETTER WA;Lo;0;L;;;;;N;;;;;
+1770;TAGBANWA LETTER SA;Lo;0;L;;;;;N;;;;;
+1772;TAGBANWA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1773;TAGBANWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1780;KHMER LETTER KA;Lo;0;L;;;;;N;;;;;
+1781;KHMER LETTER KHA;Lo;0;L;;;;;N;;;;;
+1782;KHMER LETTER KO;Lo;0;L;;;;;N;;;;;
+1783;KHMER LETTER KHO;Lo;0;L;;;;;N;;;;;
+1784;KHMER LETTER NGO;Lo;0;L;;;;;N;;;;;
+1785;KHMER LETTER CA;Lo;0;L;;;;;N;;;;;
+1786;KHMER LETTER CHA;Lo;0;L;;;;;N;;;;;
+1787;KHMER LETTER CO;Lo;0;L;;;;;N;;;;;
+1788;KHMER LETTER CHO;Lo;0;L;;;;;N;;;;;
+1789;KHMER LETTER NYO;Lo;0;L;;;;;N;;;;;
+178A;KHMER LETTER DA;Lo;0;L;;;;;N;;;;;
+178B;KHMER LETTER TTHA;Lo;0;L;;;;;N;;;;;
+178C;KHMER LETTER DO;Lo;0;L;;;;;N;;;;;
+178D;KHMER LETTER TTHO;Lo;0;L;;;;;N;;;;;
+178E;KHMER LETTER NNO;Lo;0;L;;;;;N;;;;;
+178F;KHMER LETTER TA;Lo;0;L;;;;;N;;;;;
+1790;KHMER LETTER THA;Lo;0;L;;;;;N;;;;;
+1791;KHMER LETTER TO;Lo;0;L;;;;;N;;;;;
+1792;KHMER LETTER THO;Lo;0;L;;;;;N;;;;;
+1793;KHMER LETTER NO;Lo;0;L;;;;;N;;;;;
+1794;KHMER LETTER BA;Lo;0;L;;;;;N;;;;;
+1795;KHMER LETTER PHA;Lo;0;L;;;;;N;;;;;
+1796;KHMER LETTER PO;Lo;0;L;;;;;N;;;;;
+1797;KHMER LETTER PHO;Lo;0;L;;;;;N;;;;;
+1798;KHMER LETTER MO;Lo;0;L;;;;;N;;;;;
+1799;KHMER LETTER YO;Lo;0;L;;;;;N;;;;;
+179A;KHMER LETTER RO;Lo;0;L;;;;;N;;;;;
+179B;KHMER LETTER LO;Lo;0;L;;;;;N;;;;;
+179C;KHMER LETTER VO;Lo;0;L;;;;;N;;;;;
+179D;KHMER LETTER SHA;Lo;0;L;;;;;N;;;;;
+179E;KHMER LETTER SSO;Lo;0;L;;;;;N;;;;;
+179F;KHMER LETTER SA;Lo;0;L;;;;;N;;;;;
+17A0;KHMER LETTER HA;Lo;0;L;;;;;N;;;;;
+17A1;KHMER LETTER LA;Lo;0;L;;;;;N;;;;;
+17A2;KHMER LETTER QA;Lo;0;L;;;;;N;;;;;
+17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;;;;
+17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;;;;
+17A5;KHMER INDEPENDENT VOWEL QI;Lo;0;L;;;;;N;;;;;
+17A6;KHMER INDEPENDENT VOWEL QII;Lo;0;L;;;;;N;;;;;
+17A7;KHMER INDEPENDENT VOWEL QU;Lo;0;L;;;;;N;;;;;
+17A8;KHMER INDEPENDENT VOWEL QUK;Lo;0;L;;;;;N;;;;;
+17A9;KHMER INDEPENDENT VOWEL QUU;Lo;0;L;;;;;N;;;;;
+17AA;KHMER INDEPENDENT VOWEL QUUV;Lo;0;L;;;;;N;;;;;
+17AB;KHMER INDEPENDENT VOWEL RY;Lo;0;L;;;;;N;;;;;
+17AC;KHMER INDEPENDENT VOWEL RYY;Lo;0;L;;;;;N;;;;;
+17AD;KHMER INDEPENDENT VOWEL LY;Lo;0;L;;;;;N;;;;;
+17AE;KHMER INDEPENDENT VOWEL LYY;Lo;0;L;;;;;N;;;;;
+17AF;KHMER INDEPENDENT VOWEL QE;Lo;0;L;;;;;N;;;;;
+17B0;KHMER INDEPENDENT VOWEL QAI;Lo;0;L;;;;;N;;;;;
+17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;;
+17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;;
+17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;;
+17B4;KHMER VOWEL INHERENT AQ;Mn;0;NSM;;;;;N;;;;;
+17B5;KHMER VOWEL INHERENT AA;Mn;0;NSM;;;;;N;;;;;
+17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+17B9;KHMER VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;;
+17BA;KHMER VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;;
+17BB;KHMER VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+17BC;KHMER VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+17BD;KHMER VOWEL SIGN UA;Mn;0;NSM;;;;;N;;;;;
+17BE;KHMER VOWEL SIGN OE;Mc;0;L;;;;;N;;;;;
+17BF;KHMER VOWEL SIGN YA;Mc;0;L;;;;;N;;;;;
+17C0;KHMER VOWEL SIGN IE;Mc;0;L;;;;;N;;;;;
+17C1;KHMER VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+17C2;KHMER VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
+17C3;KHMER VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+17C4;KHMER VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+17C5;KHMER VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+17C6;KHMER SIGN NIKAHIT;Mn;0;NSM;;;;;N;;;;;
+17C7;KHMER SIGN REAHMUK;Mc;0;L;;;;;N;;;;;
+17C8;KHMER SIGN YUUKALEAPINTU;Mc;0;L;;;;;N;;;;;
+17C9;KHMER SIGN MUUSIKATOAN;Mn;0;NSM;;;;;N;;;;;
+17CA;KHMER SIGN TRIISAP;Mn;0;NSM;;;;;N;;;;;
+17CB;KHMER SIGN BANTOC;Mn;0;NSM;;;;;N;;;;;
+17CC;KHMER SIGN ROBAT;Mn;0;NSM;;;;;N;;;;;
+17CD;KHMER SIGN TOANDAKHIAT;Mn;0;NSM;;;;;N;;;;;
+17CE;KHMER SIGN KAKABAT;Mn;0;NSM;;;;;N;;;;;
+17CF;KHMER SIGN AHSDA;Mn;0;NSM;;;;;N;;;;;
+17D0;KHMER SIGN SAMYOK SANNYA;Mn;0;NSM;;;;;N;;;;;
+17D1;KHMER SIGN VIRIAM;Mn;0;NSM;;;;;N;;;;;
+17D2;KHMER SIGN COENG;Mn;9;NSM;;;;;N;;;;;
+17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;;;;
+17D4;KHMER SIGN KHAN;Po;0;L;;;;;N;;;;;
+17D5;KHMER SIGN BARIYOOSAN;Po;0;L;;;;;N;;;;;
+17D6;KHMER SIGN CAMNUC PII KUUH;Po;0;L;;;;;N;;;;;
+17D7;KHMER SIGN LEK TOO;Lm;0;L;;;;;N;;;;;
+17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;;;;
+17D9;KHMER SIGN PHNAEK MUAN;Po;0;L;;;;;N;;;;;
+17DA;KHMER SIGN KOOMUUT;Po;0;L;;;;;N;;;;;
+17DB;KHMER CURRENCY SYMBOL RIEL;Sc;0;ET;;;;;N;;;;;
+17DC;KHMER SIGN AVAKRAHASANYA;Lo;0;L;;;;;N;;;;;
+17DD;KHMER SIGN ATTHACAN;Mn;230;NSM;;;;;N;;;;;
+17E0;KHMER DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+17E1;KHMER DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+17E2;KHMER DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+17E3;KHMER DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+17E4;KHMER DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+17E5;KHMER DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+17E6;KHMER DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+17E7;KHMER DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+17E8;KHMER DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+17E9;KHMER DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+17F0;KHMER SYMBOL LEK ATTAK SON;No;0;ON;;;;0;N;;;;;
+17F1;KHMER SYMBOL LEK ATTAK MUOY;No;0;ON;;;;1;N;;;;;
+17F2;KHMER SYMBOL LEK ATTAK PII;No;0;ON;;;;2;N;;;;;
+17F3;KHMER SYMBOL LEK ATTAK BEI;No;0;ON;;;;3;N;;;;;
+17F4;KHMER SYMBOL LEK ATTAK BUON;No;0;ON;;;;4;N;;;;;
+17F5;KHMER SYMBOL LEK ATTAK PRAM;No;0;ON;;;;5;N;;;;;
+17F6;KHMER SYMBOL LEK ATTAK PRAM-MUOY;No;0;ON;;;;6;N;;;;;
+17F7;KHMER SYMBOL LEK ATTAK PRAM-PII;No;0;ON;;;;7;N;;;;;
+17F8;KHMER SYMBOL LEK ATTAK PRAM-BEI;No;0;ON;;;;8;N;;;;;
+17F9;KHMER SYMBOL LEK ATTAK PRAM-BUON;No;0;ON;;;;9;N;;;;;
+1800;MONGOLIAN BIRGA;Po;0;ON;;;;;N;;;;;
+1801;MONGOLIAN ELLIPSIS;Po;0;ON;;;;;N;;;;;
+1802;MONGOLIAN COMMA;Po;0;ON;;;;;N;;;;;
+1803;MONGOLIAN FULL STOP;Po;0;ON;;;;;N;;;;;
+1804;MONGOLIAN COLON;Po;0;ON;;;;;N;;;;;
+1805;MONGOLIAN FOUR DOTS;Po;0;ON;;;;;N;;;;;
+1806;MONGOLIAN TODO SOFT HYPHEN;Pd;0;ON;;;;;N;;;;;
+1807;MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER;Po;0;ON;;;;;N;;;;;
+1808;MONGOLIAN MANCHU COMMA;Po;0;ON;;;;;N;;;;;
+1809;MONGOLIAN MANCHU FULL STOP;Po;0;ON;;;;;N;;;;;
+180A;MONGOLIAN NIRUGU;Po;0;ON;;;;;N;;;;;
+180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Mn;0;NSM;;;;;N;;;;;
+180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;;
+180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;;
+180E;MONGOLIAN VOWEL SEPARATOR;Cf;0;BN;;;;;N;;;;;
+1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1813;MONGOLIAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1814;MONGOLIAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1815;MONGOLIAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1816;MONGOLIAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1817;MONGOLIAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1818;MONGOLIAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1819;MONGOLIAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1820;MONGOLIAN LETTER A;Lo;0;L;;;;;N;;;;;
+1821;MONGOLIAN LETTER E;Lo;0;L;;;;;N;;;;;
+1822;MONGOLIAN LETTER I;Lo;0;L;;;;;N;;;;;
+1823;MONGOLIAN LETTER O;Lo;0;L;;;;;N;;;;;
+1824;MONGOLIAN LETTER U;Lo;0;L;;;;;N;;;;;
+1825;MONGOLIAN LETTER OE;Lo;0;L;;;;;N;;;;;
+1826;MONGOLIAN LETTER UE;Lo;0;L;;;;;N;;;;;
+1827;MONGOLIAN LETTER EE;Lo;0;L;;;;;N;;;;;
+1828;MONGOLIAN LETTER NA;Lo;0;L;;;;;N;;;;;
+1829;MONGOLIAN LETTER ANG;Lo;0;L;;;;;N;;;;;
+182A;MONGOLIAN LETTER BA;Lo;0;L;;;;;N;;;;;
+182B;MONGOLIAN LETTER PA;Lo;0;L;;;;;N;;;;;
+182C;MONGOLIAN LETTER QA;Lo;0;L;;;;;N;;;;;
+182D;MONGOLIAN LETTER GA;Lo;0;L;;;;;N;;;;;
+182E;MONGOLIAN LETTER MA;Lo;0;L;;;;;N;;;;;
+182F;MONGOLIAN LETTER LA;Lo;0;L;;;;;N;;;;;
+1830;MONGOLIAN LETTER SA;Lo;0;L;;;;;N;;;;;
+1831;MONGOLIAN LETTER SHA;Lo;0;L;;;;;N;;;;;
+1832;MONGOLIAN LETTER TA;Lo;0;L;;;;;N;;;;;
+1833;MONGOLIAN LETTER DA;Lo;0;L;;;;;N;;;;;
+1834;MONGOLIAN LETTER CHA;Lo;0;L;;;;;N;;;;;
+1835;MONGOLIAN LETTER JA;Lo;0;L;;;;;N;;;;;
+1836;MONGOLIAN LETTER YA;Lo;0;L;;;;;N;;;;;
+1837;MONGOLIAN LETTER RA;Lo;0;L;;;;;N;;;;;
+1838;MONGOLIAN LETTER WA;Lo;0;L;;;;;N;;;;;
+1839;MONGOLIAN LETTER FA;Lo;0;L;;;;;N;;;;;
+183A;MONGOLIAN LETTER KA;Lo;0;L;;;;;N;;;;;
+183B;MONGOLIAN LETTER KHA;Lo;0;L;;;;;N;;;;;
+183C;MONGOLIAN LETTER TSA;Lo;0;L;;;;;N;;;;;
+183D;MONGOLIAN LETTER ZA;Lo;0;L;;;;;N;;;;;
+183E;MONGOLIAN LETTER HAA;Lo;0;L;;;;;N;;;;;
+183F;MONGOLIAN LETTER ZRA;Lo;0;L;;;;;N;;;;;
+1840;MONGOLIAN LETTER LHA;Lo;0;L;;;;;N;;;;;
+1841;MONGOLIAN LETTER ZHI;Lo;0;L;;;;;N;;;;;
+1842;MONGOLIAN LETTER CHI;Lo;0;L;;;;;N;;;;;
+1843;MONGOLIAN LETTER TODO LONG VOWEL SIGN;Lm;0;L;;;;;N;;;;;
+1844;MONGOLIAN LETTER TODO E;Lo;0;L;;;;;N;;;;;
+1845;MONGOLIAN LETTER TODO I;Lo;0;L;;;;;N;;;;;
+1846;MONGOLIAN LETTER TODO O;Lo;0;L;;;;;N;;;;;
+1847;MONGOLIAN LETTER TODO U;Lo;0;L;;;;;N;;;;;
+1848;MONGOLIAN LETTER TODO OE;Lo;0;L;;;;;N;;;;;
+1849;MONGOLIAN LETTER TODO UE;Lo;0;L;;;;;N;;;;;
+184A;MONGOLIAN LETTER TODO ANG;Lo;0;L;;;;;N;;;;;
+184B;MONGOLIAN LETTER TODO BA;Lo;0;L;;;;;N;;;;;
+184C;MONGOLIAN LETTER TODO PA;Lo;0;L;;;;;N;;;;;
+184D;MONGOLIAN LETTER TODO QA;Lo;0;L;;;;;N;;;;;
+184E;MONGOLIAN LETTER TODO GA;Lo;0;L;;;;;N;;;;;
+184F;MONGOLIAN LETTER TODO MA;Lo;0;L;;;;;N;;;;;
+1850;MONGOLIAN LETTER TODO TA;Lo;0;L;;;;;N;;;;;
+1851;MONGOLIAN LETTER TODO DA;Lo;0;L;;;;;N;;;;;
+1852;MONGOLIAN LETTER TODO CHA;Lo;0;L;;;;;N;;;;;
+1853;MONGOLIAN LETTER TODO JA;Lo;0;L;;;;;N;;;;;
+1854;MONGOLIAN LETTER TODO TSA;Lo;0;L;;;;;N;;;;;
+1855;MONGOLIAN LETTER TODO YA;Lo;0;L;;;;;N;;;;;
+1856;MONGOLIAN LETTER TODO WA;Lo;0;L;;;;;N;;;;;
+1857;MONGOLIAN LETTER TODO KA;Lo;0;L;;;;;N;;;;;
+1858;MONGOLIAN LETTER TODO GAA;Lo;0;L;;;;;N;;;;;
+1859;MONGOLIAN LETTER TODO HAA;Lo;0;L;;;;;N;;;;;
+185A;MONGOLIAN LETTER TODO JIA;Lo;0;L;;;;;N;;;;;
+185B;MONGOLIAN LETTER TODO NIA;Lo;0;L;;;;;N;;;;;
+185C;MONGOLIAN LETTER TODO DZA;Lo;0;L;;;;;N;;;;;
+185D;MONGOLIAN LETTER SIBE E;Lo;0;L;;;;;N;;;;;
+185E;MONGOLIAN LETTER SIBE I;Lo;0;L;;;;;N;;;;;
+185F;MONGOLIAN LETTER SIBE IY;Lo;0;L;;;;;N;;;;;
+1860;MONGOLIAN LETTER SIBE UE;Lo;0;L;;;;;N;;;;;
+1861;MONGOLIAN LETTER SIBE U;Lo;0;L;;;;;N;;;;;
+1862;MONGOLIAN LETTER SIBE ANG;Lo;0;L;;;;;N;;;;;
+1863;MONGOLIAN LETTER SIBE KA;Lo;0;L;;;;;N;;;;;
+1864;MONGOLIAN LETTER SIBE GA;Lo;0;L;;;;;N;;;;;
+1865;MONGOLIAN LETTER SIBE HA;Lo;0;L;;;;;N;;;;;
+1866;MONGOLIAN LETTER SIBE PA;Lo;0;L;;;;;N;;;;;
+1867;MONGOLIAN LETTER SIBE SHA;Lo;0;L;;;;;N;;;;;
+1868;MONGOLIAN LETTER SIBE TA;Lo;0;L;;;;;N;;;;;
+1869;MONGOLIAN LETTER SIBE DA;Lo;0;L;;;;;N;;;;;
+186A;MONGOLIAN LETTER SIBE JA;Lo;0;L;;;;;N;;;;;
+186B;MONGOLIAN LETTER SIBE FA;Lo;0;L;;;;;N;;;;;
+186C;MONGOLIAN LETTER SIBE GAA;Lo;0;L;;;;;N;;;;;
+186D;MONGOLIAN LETTER SIBE HAA;Lo;0;L;;;;;N;;;;;
+186E;MONGOLIAN LETTER SIBE TSA;Lo;0;L;;;;;N;;;;;
+186F;MONGOLIAN LETTER SIBE ZA;Lo;0;L;;;;;N;;;;;
+1870;MONGOLIAN LETTER SIBE RAA;Lo;0;L;;;;;N;;;;;
+1871;MONGOLIAN LETTER SIBE CHA;Lo;0;L;;;;;N;;;;;
+1872;MONGOLIAN LETTER SIBE ZHA;Lo;0;L;;;;;N;;;;;
+1873;MONGOLIAN LETTER MANCHU I;Lo;0;L;;;;;N;;;;;
+1874;MONGOLIAN LETTER MANCHU KA;Lo;0;L;;;;;N;;;;;
+1875;MONGOLIAN LETTER MANCHU RA;Lo;0;L;;;;;N;;;;;
+1876;MONGOLIAN LETTER MANCHU FA;Lo;0;L;;;;;N;;;;;
+1877;MONGOLIAN LETTER MANCHU ZHA;Lo;0;L;;;;;N;;;;;
+1880;MONGOLIAN LETTER ALI GALI ANUSVARA ONE;Lo;0;L;;;;;N;;;;;
+1881;MONGOLIAN LETTER ALI GALI VISARGA ONE;Lo;0;L;;;;;N;;;;;
+1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;;
+1883;MONGOLIAN LETTER ALI GALI UBADAMA;Lo;0;L;;;;;N;;;;;
+1884;MONGOLIAN LETTER ALI GALI INVERTED UBADAMA;Lo;0;L;;;;;N;;;;;
+1885;MONGOLIAN LETTER ALI GALI BALUDA;Mn;0;NSM;;;;;N;;;;;
+1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Mn;0;NSM;;;;;N;;;;;
+1887;MONGOLIAN LETTER ALI GALI A;Lo;0;L;;;;;N;;;;;
+1888;MONGOLIAN LETTER ALI GALI I;Lo;0;L;;;;;N;;;;;
+1889;MONGOLIAN LETTER ALI GALI KA;Lo;0;L;;;;;N;;;;;
+188A;MONGOLIAN LETTER ALI GALI NGA;Lo;0;L;;;;;N;;;;;
+188B;MONGOLIAN LETTER ALI GALI CA;Lo;0;L;;;;;N;;;;;
+188C;MONGOLIAN LETTER ALI GALI TTA;Lo;0;L;;;;;N;;;;;
+188D;MONGOLIAN LETTER ALI GALI TTHA;Lo;0;L;;;;;N;;;;;
+188E;MONGOLIAN LETTER ALI GALI DDA;Lo;0;L;;;;;N;;;;;
+188F;MONGOLIAN LETTER ALI GALI NNA;Lo;0;L;;;;;N;;;;;
+1890;MONGOLIAN LETTER ALI GALI TA;Lo;0;L;;;;;N;;;;;
+1891;MONGOLIAN LETTER ALI GALI DA;Lo;0;L;;;;;N;;;;;
+1892;MONGOLIAN LETTER ALI GALI PA;Lo;0;L;;;;;N;;;;;
+1893;MONGOLIAN LETTER ALI GALI PHA;Lo;0;L;;;;;N;;;;;
+1894;MONGOLIAN LETTER ALI GALI SSA;Lo;0;L;;;;;N;;;;;
+1895;MONGOLIAN LETTER ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
+1896;MONGOLIAN LETTER ALI GALI ZA;Lo;0;L;;;;;N;;;;;
+1897;MONGOLIAN LETTER ALI GALI AH;Lo;0;L;;;;;N;;;;;
+1898;MONGOLIAN LETTER TODO ALI GALI TA;Lo;0;L;;;;;N;;;;;
+1899;MONGOLIAN LETTER TODO ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
+189A;MONGOLIAN LETTER MANCHU ALI GALI GHA;Lo;0;L;;;;;N;;;;;
+189B;MONGOLIAN LETTER MANCHU ALI GALI NGA;Lo;0;L;;;;;N;;;;;
+189C;MONGOLIAN LETTER MANCHU ALI GALI CA;Lo;0;L;;;;;N;;;;;
+189D;MONGOLIAN LETTER MANCHU ALI GALI JHA;Lo;0;L;;;;;N;;;;;
+189E;MONGOLIAN LETTER MANCHU ALI GALI TTA;Lo;0;L;;;;;N;;;;;
+189F;MONGOLIAN LETTER MANCHU ALI GALI DDHA;Lo;0;L;;;;;N;;;;;
+18A0;MONGOLIAN LETTER MANCHU ALI GALI TA;Lo;0;L;;;;;N;;;;;
+18A1;MONGOLIAN LETTER MANCHU ALI GALI DHA;Lo;0;L;;;;;N;;;;;
+18A2;MONGOLIAN LETTER MANCHU ALI GALI SSA;Lo;0;L;;;;;N;;;;;
+18A3;MONGOLIAN LETTER MANCHU ALI GALI CYA;Lo;0;L;;;;;N;;;;;
+18A4;MONGOLIAN LETTER MANCHU ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
+18A5;MONGOLIAN LETTER MANCHU ALI GALI ZA;Lo;0;L;;;;;N;;;;;
+18A6;MONGOLIAN LETTER ALI GALI HALF U;Lo;0;L;;;;;N;;;;;
+18A7;MONGOLIAN LETTER ALI GALI HALF YA;Lo;0;L;;;;;N;;;;;
+18A8;MONGOLIAN LETTER MANCHU ALI GALI BHA;Lo;0;L;;;;;N;;;;;
+18A9;MONGOLIAN LETTER ALI GALI DAGALGA;Mn;228;NSM;;;;;N;;;;;
+18AA;MONGOLIAN LETTER MANCHU ALI GALI LHA;Lo;0;L;;;;;N;;;;;
+18B0;CANADIAN SYLLABICS OY;Lo;0;L;;;;;N;;;;;
+18B1;CANADIAN SYLLABICS AY;Lo;0;L;;;;;N;;;;;
+18B2;CANADIAN SYLLABICS AAY;Lo;0;L;;;;;N;;;;;
+18B3;CANADIAN SYLLABICS WAY;Lo;0;L;;;;;N;;;;;
+18B4;CANADIAN SYLLABICS POY;Lo;0;L;;;;;N;;;;;
+18B5;CANADIAN SYLLABICS PAY;Lo;0;L;;;;;N;;;;;
+18B6;CANADIAN SYLLABICS PWOY;Lo;0;L;;;;;N;;;;;
+18B7;CANADIAN SYLLABICS TAY;Lo;0;L;;;;;N;;;;;
+18B8;CANADIAN SYLLABICS KAY;Lo;0;L;;;;;N;;;;;
+18B9;CANADIAN SYLLABICS KWAY;Lo;0;L;;;;;N;;;;;
+18BA;CANADIAN SYLLABICS MAY;Lo;0;L;;;;;N;;;;;
+18BB;CANADIAN SYLLABICS NOY;Lo;0;L;;;;;N;;;;;
+18BC;CANADIAN SYLLABICS NAY;Lo;0;L;;;;;N;;;;;
+18BD;CANADIAN SYLLABICS LAY;Lo;0;L;;;;;N;;;;;
+18BE;CANADIAN SYLLABICS SOY;Lo;0;L;;;;;N;;;;;
+18BF;CANADIAN SYLLABICS SAY;Lo;0;L;;;;;N;;;;;
+18C0;CANADIAN SYLLABICS SHOY;Lo;0;L;;;;;N;;;;;
+18C1;CANADIAN SYLLABICS SHAY;Lo;0;L;;;;;N;;;;;
+18C2;CANADIAN SYLLABICS SHWOY;Lo;0;L;;;;;N;;;;;
+18C3;CANADIAN SYLLABICS YOY;Lo;0;L;;;;;N;;;;;
+18C4;CANADIAN SYLLABICS YAY;Lo;0;L;;;;;N;;;;;
+18C5;CANADIAN SYLLABICS RAY;Lo;0;L;;;;;N;;;;;
+18C6;CANADIAN SYLLABICS NWI;Lo;0;L;;;;;N;;;;;
+18C7;CANADIAN SYLLABICS OJIBWAY NWI;Lo;0;L;;;;;N;;;;;
+18C8;CANADIAN SYLLABICS NWII;Lo;0;L;;;;;N;;;;;
+18C9;CANADIAN SYLLABICS OJIBWAY NWII;Lo;0;L;;;;;N;;;;;
+18CA;CANADIAN SYLLABICS NWO;Lo;0;L;;;;;N;;;;;
+18CB;CANADIAN SYLLABICS OJIBWAY NWO;Lo;0;L;;;;;N;;;;;
+18CC;CANADIAN SYLLABICS NWOO;Lo;0;L;;;;;N;;;;;
+18CD;CANADIAN SYLLABICS OJIBWAY NWOO;Lo;0;L;;;;;N;;;;;
+18CE;CANADIAN SYLLABICS RWEE;Lo;0;L;;;;;N;;;;;
+18CF;CANADIAN SYLLABICS RWI;Lo;0;L;;;;;N;;;;;
+18D0;CANADIAN SYLLABICS RWII;Lo;0;L;;;;;N;;;;;
+18D1;CANADIAN SYLLABICS RWO;Lo;0;L;;;;;N;;;;;
+18D2;CANADIAN SYLLABICS RWOO;Lo;0;L;;;;;N;;;;;
+18D3;CANADIAN SYLLABICS RWA;Lo;0;L;;;;;N;;;;;
+18D4;CANADIAN SYLLABICS OJIBWAY P;Lo;0;L;;;;;N;;;;;
+18D5;CANADIAN SYLLABICS OJIBWAY T;Lo;0;L;;;;;N;;;;;
+18D6;CANADIAN SYLLABICS OJIBWAY K;Lo;0;L;;;;;N;;;;;
+18D7;CANADIAN SYLLABICS OJIBWAY C;Lo;0;L;;;;;N;;;;;
+18D8;CANADIAN SYLLABICS OJIBWAY M;Lo;0;L;;;;;N;;;;;
+18D9;CANADIAN SYLLABICS OJIBWAY N;Lo;0;L;;;;;N;;;;;
+18DA;CANADIAN SYLLABICS OJIBWAY S;Lo;0;L;;;;;N;;;;;
+18DB;CANADIAN SYLLABICS OJIBWAY SH;Lo;0;L;;;;;N;;;;;
+18DC;CANADIAN SYLLABICS EASTERN W;Lo;0;L;;;;;N;;;;;
+18DD;CANADIAN SYLLABICS WESTERN W;Lo;0;L;;;;;N;;;;;
+18DE;CANADIAN SYLLABICS FINAL SMALL RING;Lo;0;L;;;;;N;;;;;
+18DF;CANADIAN SYLLABICS FINAL RAISED DOT;Lo;0;L;;;;;N;;;;;
+18E0;CANADIAN SYLLABICS R-CREE RWE;Lo;0;L;;;;;N;;;;;
+18E1;CANADIAN SYLLABICS WEST-CREE LOO;Lo;0;L;;;;;N;;;;;
+18E2;CANADIAN SYLLABICS WEST-CREE LAA;Lo;0;L;;;;;N;;;;;
+18E3;CANADIAN SYLLABICS THWE;Lo;0;L;;;;;N;;;;;
+18E4;CANADIAN SYLLABICS THWA;Lo;0;L;;;;;N;;;;;
+18E5;CANADIAN SYLLABICS TTHWE;Lo;0;L;;;;;N;;;;;
+18E6;CANADIAN SYLLABICS TTHOO;Lo;0;L;;;;;N;;;;;
+18E7;CANADIAN SYLLABICS TTHAA;Lo;0;L;;;;;N;;;;;
+18E8;CANADIAN SYLLABICS TLHWE;Lo;0;L;;;;;N;;;;;
+18E9;CANADIAN SYLLABICS TLHOO;Lo;0;L;;;;;N;;;;;
+18EA;CANADIAN SYLLABICS SAYISI SHWE;Lo;0;L;;;;;N;;;;;
+18EB;CANADIAN SYLLABICS SAYISI SHOO;Lo;0;L;;;;;N;;;;;
+18EC;CANADIAN SYLLABICS SAYISI HOO;Lo;0;L;;;;;N;;;;;
+18ED;CANADIAN SYLLABICS CARRIER GWU;Lo;0;L;;;;;N;;;;;
+18EE;CANADIAN SYLLABICS CARRIER DENE GEE;Lo;0;L;;;;;N;;;;;
+18EF;CANADIAN SYLLABICS CARRIER GAA;Lo;0;L;;;;;N;;;;;
+18F0;CANADIAN SYLLABICS CARRIER GWA;Lo;0;L;;;;;N;;;;;
+18F1;CANADIAN SYLLABICS SAYISI JUU;Lo;0;L;;;;;N;;;;;
+18F2;CANADIAN SYLLABICS CARRIER JWA;Lo;0;L;;;;;N;;;;;
+18F3;CANADIAN SYLLABICS BEAVER DENE L;Lo;0;L;;;;;N;;;;;
+18F4;CANADIAN SYLLABICS BEAVER DENE R;Lo;0;L;;;;;N;;;;;
+18F5;CANADIAN SYLLABICS CARRIER DENTAL S;Lo;0;L;;;;;N;;;;;
+1900;LIMBU VOWEL-CARRIER LETTER;Lo;0;L;;;;;N;;;;;
+1901;LIMBU LETTER KA;Lo;0;L;;;;;N;;;;;
+1902;LIMBU LETTER KHA;Lo;0;L;;;;;N;;;;;
+1903;LIMBU LETTER GA;Lo;0;L;;;;;N;;;;;
+1904;LIMBU LETTER GHA;Lo;0;L;;;;;N;;;;;
+1905;LIMBU LETTER NGA;Lo;0;L;;;;;N;;;;;
+1906;LIMBU LETTER CA;Lo;0;L;;;;;N;;;;;
+1907;LIMBU LETTER CHA;Lo;0;L;;;;;N;;;;;
+1908;LIMBU LETTER JA;Lo;0;L;;;;;N;;;;;
+1909;LIMBU LETTER JHA;Lo;0;L;;;;;N;;;;;
+190A;LIMBU LETTER YAN;Lo;0;L;;;;;N;;;;;
+190B;LIMBU LETTER TA;Lo;0;L;;;;;N;;;;;
+190C;LIMBU LETTER THA;Lo;0;L;;;;;N;;;;;
+190D;LIMBU LETTER DA;Lo;0;L;;;;;N;;;;;
+190E;LIMBU LETTER DHA;Lo;0;L;;;;;N;;;;;
+190F;LIMBU LETTER NA;Lo;0;L;;;;;N;;;;;
+1910;LIMBU LETTER PA;Lo;0;L;;;;;N;;;;;
+1911;LIMBU LETTER PHA;Lo;0;L;;;;;N;;;;;
+1912;LIMBU LETTER BA;Lo;0;L;;;;;N;;;;;
+1913;LIMBU LETTER BHA;Lo;0;L;;;;;N;;;;;
+1914;LIMBU LETTER MA;Lo;0;L;;;;;N;;;;;
+1915;LIMBU LETTER YA;Lo;0;L;;;;;N;;;;;
+1916;LIMBU LETTER RA;Lo;0;L;;;;;N;;;;;
+1917;LIMBU LETTER LA;Lo;0;L;;;;;N;;;;;
+1918;LIMBU LETTER WA;Lo;0;L;;;;;N;;;;;
+1919;LIMBU LETTER SHA;Lo;0;L;;;;;N;;;;;
+191A;LIMBU LETTER SSA;Lo;0;L;;;;;N;;;;;
+191B;LIMBU LETTER SA;Lo;0;L;;;;;N;;;;;
+191C;LIMBU LETTER HA;Lo;0;L;;;;;N;;;;;
+191D;LIMBU LETTER GYAN;Lo;0;L;;;;;N;;;;;
+191E;LIMBU LETTER TRA;Lo;0;L;;;;;N;;;;;
+1920;LIMBU VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;;
+1921;LIMBU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1922;LIMBU VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1923;LIMBU VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+1924;LIMBU VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+1925;LIMBU VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+1926;LIMBU VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+1927;LIMBU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+1928;LIMBU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+1929;LIMBU SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;;
+192A;LIMBU SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;;
+192B;LIMBU SUBJOINED LETTER WA;Mc;0;L;;;;;N;;;;;
+1930;LIMBU SMALL LETTER KA;Mc;0;L;;;;;N;;;;;
+1931;LIMBU SMALL LETTER NGA;Mc;0;L;;;;;N;;;;;
+1932;LIMBU SMALL LETTER ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+1933;LIMBU SMALL LETTER TA;Mc;0;L;;;;;N;;;;;
+1934;LIMBU SMALL LETTER NA;Mc;0;L;;;;;N;;;;;
+1935;LIMBU SMALL LETTER PA;Mc;0;L;;;;;N;;;;;
+1936;LIMBU SMALL LETTER MA;Mc;0;L;;;;;N;;;;;
+1937;LIMBU SMALL LETTER RA;Mc;0;L;;;;;N;;;;;
+1938;LIMBU SMALL LETTER LA;Mc;0;L;;;;;N;;;;;
+1939;LIMBU SIGN MUKPHRENG;Mn;222;NSM;;;;;N;;;;;
+193A;LIMBU SIGN KEMPHRENG;Mn;230;NSM;;;;;N;;;;;
+193B;LIMBU SIGN SA-I;Mn;220;NSM;;;;;N;;;;;
+1940;LIMBU SIGN LOO;So;0;ON;;;;;N;;;;;
+1944;LIMBU EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
+1945;LIMBU QUESTION MARK;Po;0;ON;;;;;N;;;;;
+1946;LIMBU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1947;LIMBU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1948;LIMBU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1949;LIMBU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+194A;LIMBU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+194B;LIMBU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+194C;LIMBU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+194D;LIMBU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+194E;LIMBU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+194F;LIMBU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1950;TAI LE LETTER KA;Lo;0;L;;;;;N;;;;;
+1951;TAI LE LETTER XA;Lo;0;L;;;;;N;;;;;
+1952;TAI LE LETTER NGA;Lo;0;L;;;;;N;;;;;
+1953;TAI LE LETTER TSA;Lo;0;L;;;;;N;;;;;
+1954;TAI LE LETTER SA;Lo;0;L;;;;;N;;;;;
+1955;TAI LE LETTER YA;Lo;0;L;;;;;N;;;;;
+1956;TAI LE LETTER TA;Lo;0;L;;;;;N;;;;;
+1957;TAI LE LETTER THA;Lo;0;L;;;;;N;;;;;
+1958;TAI LE LETTER LA;Lo;0;L;;;;;N;;;;;
+1959;TAI LE LETTER PA;Lo;0;L;;;;;N;;;;;
+195A;TAI LE LETTER PHA;Lo;0;L;;;;;N;;;;;
+195B;TAI LE LETTER MA;Lo;0;L;;;;;N;;;;;
+195C;TAI LE LETTER FA;Lo;0;L;;;;;N;;;;;
+195D;TAI LE LETTER VA;Lo;0;L;;;;;N;;;;;
+195E;TAI LE LETTER HA;Lo;0;L;;;;;N;;;;;
+195F;TAI LE LETTER QA;Lo;0;L;;;;;N;;;;;
+1960;TAI LE LETTER KHA;Lo;0;L;;;;;N;;;;;
+1961;TAI LE LETTER TSHA;Lo;0;L;;;;;N;;;;;
+1962;TAI LE LETTER NA;Lo;0;L;;;;;N;;;;;
+1963;TAI LE LETTER A;Lo;0;L;;;;;N;;;;;
+1964;TAI LE LETTER I;Lo;0;L;;;;;N;;;;;
+1965;TAI LE LETTER EE;Lo;0;L;;;;;N;;;;;
+1966;TAI LE LETTER EH;Lo;0;L;;;;;N;;;;;
+1967;TAI LE LETTER U;Lo;0;L;;;;;N;;;;;
+1968;TAI LE LETTER OO;Lo;0;L;;;;;N;;;;;
+1969;TAI LE LETTER O;Lo;0;L;;;;;N;;;;;
+196A;TAI LE LETTER UE;Lo;0;L;;;;;N;;;;;
+196B;TAI LE LETTER E;Lo;0;L;;;;;N;;;;;
+196C;TAI LE LETTER AUE;Lo;0;L;;;;;N;;;;;
+196D;TAI LE LETTER AI;Lo;0;L;;;;;N;;;;;
+1970;TAI LE LETTER TONE-2;Lo;0;L;;;;;N;;;;;
+1971;TAI LE LETTER TONE-3;Lo;0;L;;;;;N;;;;;
+1972;TAI LE LETTER TONE-4;Lo;0;L;;;;;N;;;;;
+1973;TAI LE LETTER TONE-5;Lo;0;L;;;;;N;;;;;
+1974;TAI LE LETTER TONE-6;Lo;0;L;;;;;N;;;;;
+1980;NEW TAI LUE LETTER HIGH QA;Lo;0;L;;;;;N;;;;;
+1981;NEW TAI LUE LETTER LOW QA;Lo;0;L;;;;;N;;;;;
+1982;NEW TAI LUE LETTER HIGH KA;Lo;0;L;;;;;N;;;;;
+1983;NEW TAI LUE LETTER HIGH XA;Lo;0;L;;;;;N;;;;;
+1984;NEW TAI LUE LETTER HIGH NGA;Lo;0;L;;;;;N;;;;;
+1985;NEW TAI LUE LETTER LOW KA;Lo;0;L;;;;;N;;;;;
+1986;NEW TAI LUE LETTER LOW XA;Lo;0;L;;;;;N;;;;;
+1987;NEW TAI LUE LETTER LOW NGA;Lo;0;L;;;;;N;;;;;
+1988;NEW TAI LUE LETTER HIGH TSA;Lo;0;L;;;;;N;;;;;
+1989;NEW TAI LUE LETTER HIGH SA;Lo;0;L;;;;;N;;;;;
+198A;NEW TAI LUE LETTER HIGH YA;Lo;0;L;;;;;N;;;;;
+198B;NEW TAI LUE LETTER LOW TSA;Lo;0;L;;;;;N;;;;;
+198C;NEW TAI LUE LETTER LOW SA;Lo;0;L;;;;;N;;;;;
+198D;NEW TAI LUE LETTER LOW YA;Lo;0;L;;;;;N;;;;;
+198E;NEW TAI LUE LETTER HIGH TA;Lo;0;L;;;;;N;;;;;
+198F;NEW TAI LUE LETTER HIGH THA;Lo;0;L;;;;;N;;;;;
+1990;NEW TAI LUE LETTER HIGH NA;Lo;0;L;;;;;N;;;;;
+1991;NEW TAI LUE LETTER LOW TA;Lo;0;L;;;;;N;;;;;
+1992;NEW TAI LUE LETTER LOW THA;Lo;0;L;;;;;N;;;;;
+1993;NEW TAI LUE LETTER LOW NA;Lo;0;L;;;;;N;;;;;
+1994;NEW TAI LUE LETTER HIGH PA;Lo;0;L;;;;;N;;;;;
+1995;NEW TAI LUE LETTER HIGH PHA;Lo;0;L;;;;;N;;;;;
+1996;NEW TAI LUE LETTER HIGH MA;Lo;0;L;;;;;N;;;;;
+1997;NEW TAI LUE LETTER LOW PA;Lo;0;L;;;;;N;;;;;
+1998;NEW TAI LUE LETTER LOW PHA;Lo;0;L;;;;;N;;;;;
+1999;NEW TAI LUE LETTER LOW MA;Lo;0;L;;;;;N;;;;;
+199A;NEW TAI LUE LETTER HIGH FA;Lo;0;L;;;;;N;;;;;
+199B;NEW TAI LUE LETTER HIGH VA;Lo;0;L;;;;;N;;;;;
+199C;NEW TAI LUE LETTER HIGH LA;Lo;0;L;;;;;N;;;;;
+199D;NEW TAI LUE LETTER LOW FA;Lo;0;L;;;;;N;;;;;
+199E;NEW TAI LUE LETTER LOW VA;Lo;0;L;;;;;N;;;;;
+199F;NEW TAI LUE LETTER LOW LA;Lo;0;L;;;;;N;;;;;
+19A0;NEW TAI LUE LETTER HIGH HA;Lo;0;L;;;;;N;;;;;
+19A1;NEW TAI LUE LETTER HIGH DA;Lo;0;L;;;;;N;;;;;
+19A2;NEW TAI LUE LETTER HIGH BA;Lo;0;L;;;;;N;;;;;
+19A3;NEW TAI LUE LETTER LOW HA;Lo;0;L;;;;;N;;;;;
+19A4;NEW TAI LUE LETTER LOW DA;Lo;0;L;;;;;N;;;;;
+19A5;NEW TAI LUE LETTER LOW BA;Lo;0;L;;;;;N;;;;;
+19A6;NEW TAI LUE LETTER HIGH KVA;Lo;0;L;;;;;N;;;;;
+19A7;NEW TAI LUE LETTER HIGH XVA;Lo;0;L;;;;;N;;;;;
+19A8;NEW TAI LUE LETTER LOW KVA;Lo;0;L;;;;;N;;;;;
+19A9;NEW TAI LUE LETTER LOW XVA;Lo;0;L;;;;;N;;;;;
+19AA;NEW TAI LUE LETTER HIGH SUA;Lo;0;L;;;;;N;;;;;
+19AB;NEW TAI LUE LETTER LOW SUA;Lo;0;L;;;;;N;;;;;
+19B0;NEW TAI LUE VOWEL SIGN VOWEL SHORTENER;Lo;0;L;;;;;N;;;;;
+19B1;NEW TAI LUE VOWEL SIGN AA;Lo;0;L;;;;;N;;;;;
+19B2;NEW TAI LUE VOWEL SIGN II;Lo;0;L;;;;;N;;;;;
+19B3;NEW TAI LUE VOWEL SIGN U;Lo;0;L;;;;;N;;;;;
+19B4;NEW TAI LUE VOWEL SIGN UU;Lo;0;L;;;;;N;;;;;
+19B5;NEW TAI LUE VOWEL SIGN E;Lo;0;L;;;;;N;;;;;
+19B6;NEW TAI LUE VOWEL SIGN AE;Lo;0;L;;;;;N;;;;;
+19B7;NEW TAI LUE VOWEL SIGN O;Lo;0;L;;;;;N;;;;;
+19B8;NEW TAI LUE VOWEL SIGN OA;Lo;0;L;;;;;N;;;;;
+19B9;NEW TAI LUE VOWEL SIGN UE;Lo;0;L;;;;;N;;;;;
+19BA;NEW TAI LUE VOWEL SIGN AY;Lo;0;L;;;;;N;;;;;
+19BB;NEW TAI LUE VOWEL SIGN AAY;Lo;0;L;;;;;N;;;;;
+19BC;NEW TAI LUE VOWEL SIGN UY;Lo;0;L;;;;;N;;;;;
+19BD;NEW TAI LUE VOWEL SIGN OY;Lo;0;L;;;;;N;;;;;
+19BE;NEW TAI LUE VOWEL SIGN OAY;Lo;0;L;;;;;N;;;;;
+19BF;NEW TAI LUE VOWEL SIGN UEY;Lo;0;L;;;;;N;;;;;
+19C0;NEW TAI LUE VOWEL SIGN IY;Lo;0;L;;;;;N;;;;;
+19C1;NEW TAI LUE LETTER FINAL V;Lo;0;L;;;;;N;;;;;
+19C2;NEW TAI LUE LETTER FINAL NG;Lo;0;L;;;;;N;;;;;
+19C3;NEW TAI LUE LETTER FINAL N;Lo;0;L;;;;;N;;;;;
+19C4;NEW TAI LUE LETTER FINAL M;Lo;0;L;;;;;N;;;;;
+19C5;NEW TAI LUE LETTER FINAL K;Lo;0;L;;;;;N;;;;;
+19C6;NEW TAI LUE LETTER FINAL D;Lo;0;L;;;;;N;;;;;
+19C7;NEW TAI LUE LETTER FINAL B;Lo;0;L;;;;;N;;;;;
+19C8;NEW TAI LUE TONE MARK-1;Lo;0;L;;;;;N;;;;;
+19C9;NEW TAI LUE TONE MARK-2;Lo;0;L;;;;;N;;;;;
+19D0;NEW TAI LUE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+19D1;NEW TAI LUE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+19D2;NEW TAI LUE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+19D3;NEW TAI LUE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+19D4;NEW TAI LUE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+19D5;NEW TAI LUE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+19D6;NEW TAI LUE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+19D7;NEW TAI LUE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+19D8;NEW TAI LUE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+19D9;NEW TAI LUE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+19DA;NEW TAI LUE THAM DIGIT ONE;No;0;L;;;1;1;N;;;;;
+19DE;NEW TAI LUE SIGN LAE;So;0;ON;;;;;N;;;;;
+19DF;NEW TAI LUE SIGN LAEV;So;0;ON;;;;;N;;;;;
+19E0;KHMER SYMBOL PATHAMASAT;So;0;ON;;;;;N;;;;;
+19E1;KHMER SYMBOL MUOY KOET;So;0;ON;;;;;N;;;;;
+19E2;KHMER SYMBOL PII KOET;So;0;ON;;;;;N;;;;;
+19E3;KHMER SYMBOL BEI KOET;So;0;ON;;;;;N;;;;;
+19E4;KHMER SYMBOL BUON KOET;So;0;ON;;;;;N;;;;;
+19E5;KHMER SYMBOL PRAM KOET;So;0;ON;;;;;N;;;;;
+19E6;KHMER SYMBOL PRAM-MUOY KOET;So;0;ON;;;;;N;;;;;
+19E7;KHMER SYMBOL PRAM-PII KOET;So;0;ON;;;;;N;;;;;
+19E8;KHMER SYMBOL PRAM-BEI KOET;So;0;ON;;;;;N;;;;;
+19E9;KHMER SYMBOL PRAM-BUON KOET;So;0;ON;;;;;N;;;;;
+19EA;KHMER SYMBOL DAP KOET;So;0;ON;;;;;N;;;;;
+19EB;KHMER SYMBOL DAP-MUOY KOET;So;0;ON;;;;;N;;;;;
+19EC;KHMER SYMBOL DAP-PII KOET;So;0;ON;;;;;N;;;;;
+19ED;KHMER SYMBOL DAP-BEI KOET;So;0;ON;;;;;N;;;;;
+19EE;KHMER SYMBOL DAP-BUON KOET;So;0;ON;;;;;N;;;;;
+19EF;KHMER SYMBOL DAP-PRAM KOET;So;0;ON;;;;;N;;;;;
+19F0;KHMER SYMBOL TUTEYASAT;So;0;ON;;;;;N;;;;;
+19F1;KHMER SYMBOL MUOY ROC;So;0;ON;;;;;N;;;;;
+19F2;KHMER SYMBOL PII ROC;So;0;ON;;;;;N;;;;;
+19F3;KHMER SYMBOL BEI ROC;So;0;ON;;;;;N;;;;;
+19F4;KHMER SYMBOL BUON ROC;So;0;ON;;;;;N;;;;;
+19F5;KHMER SYMBOL PRAM ROC;So;0;ON;;;;;N;;;;;
+19F6;KHMER SYMBOL PRAM-MUOY ROC;So;0;ON;;;;;N;;;;;
+19F7;KHMER SYMBOL PRAM-PII ROC;So;0;ON;;;;;N;;;;;
+19F8;KHMER SYMBOL PRAM-BEI ROC;So;0;ON;;;;;N;;;;;
+19F9;KHMER SYMBOL PRAM-BUON ROC;So;0;ON;;;;;N;;;;;
+19FA;KHMER SYMBOL DAP ROC;So;0;ON;;;;;N;;;;;
+19FB;KHMER SYMBOL DAP-MUOY ROC;So;0;ON;;;;;N;;;;;
+19FC;KHMER SYMBOL DAP-PII ROC;So;0;ON;;;;;N;;;;;
+19FD;KHMER SYMBOL DAP-BEI ROC;So;0;ON;;;;;N;;;;;
+19FE;KHMER SYMBOL DAP-BUON ROC;So;0;ON;;;;;N;;;;;
+19FF;KHMER SYMBOL DAP-PRAM ROC;So;0;ON;;;;;N;;;;;
+1A00;BUGINESE LETTER KA;Lo;0;L;;;;;N;;;;;
+1A01;BUGINESE LETTER GA;Lo;0;L;;;;;N;;;;;
+1A02;BUGINESE LETTER NGA;Lo;0;L;;;;;N;;;;;
+1A03;BUGINESE LETTER NGKA;Lo;0;L;;;;;N;;;;;
+1A04;BUGINESE LETTER PA;Lo;0;L;;;;;N;;;;;
+1A05;BUGINESE LETTER BA;Lo;0;L;;;;;N;;;;;
+1A06;BUGINESE LETTER MA;Lo;0;L;;;;;N;;;;;
+1A07;BUGINESE LETTER MPA;Lo;0;L;;;;;N;;;;;
+1A08;BUGINESE LETTER TA;Lo;0;L;;;;;N;;;;;
+1A09;BUGINESE LETTER DA;Lo;0;L;;;;;N;;;;;
+1A0A;BUGINESE LETTER NA;Lo;0;L;;;;;N;;;;;
+1A0B;BUGINESE LETTER NRA;Lo;0;L;;;;;N;;;;;
+1A0C;BUGINESE LETTER CA;Lo;0;L;;;;;N;;;;;
+1A0D;BUGINESE LETTER JA;Lo;0;L;;;;;N;;;;;
+1A0E;BUGINESE LETTER NYA;Lo;0;L;;;;;N;;;;;
+1A0F;BUGINESE LETTER NYCA;Lo;0;L;;;;;N;;;;;
+1A10;BUGINESE LETTER YA;Lo;0;L;;;;;N;;;;;
+1A11;BUGINESE LETTER RA;Lo;0;L;;;;;N;;;;;
+1A12;BUGINESE LETTER LA;Lo;0;L;;;;;N;;;;;
+1A13;BUGINESE LETTER VA;Lo;0;L;;;;;N;;;;;
+1A14;BUGINESE LETTER SA;Lo;0;L;;;;;N;;;;;
+1A15;BUGINESE LETTER A;Lo;0;L;;;;;N;;;;;
+1A16;BUGINESE LETTER HA;Lo;0;L;;;;;N;;;;;
+1A17;BUGINESE VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;;
+1A18;BUGINESE VOWEL SIGN U;Mn;220;NSM;;;;;N;;;;;
+1A19;BUGINESE VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1A1A;BUGINESE VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+1A1B;BUGINESE VOWEL SIGN AE;Mn;0;NSM;;;;;N;;;;;
+1A1E;BUGINESE PALLAWA;Po;0;L;;;;;N;;;;;
+1A1F;BUGINESE END OF SECTION;Po;0;L;;;;;N;;;;;
+1A20;TAI THAM LETTER HIGH KA;Lo;0;L;;;;;N;;;;;
+1A21;TAI THAM LETTER HIGH KHA;Lo;0;L;;;;;N;;;;;
+1A22;TAI THAM LETTER HIGH KXA;Lo;0;L;;;;;N;;;;;
+1A23;TAI THAM LETTER LOW KA;Lo;0;L;;;;;N;;;;;
+1A24;TAI THAM LETTER LOW KXA;Lo;0;L;;;;;N;;;;;
+1A25;TAI THAM LETTER LOW KHA;Lo;0;L;;;;;N;;;;;
+1A26;TAI THAM LETTER NGA;Lo;0;L;;;;;N;;;;;
+1A27;TAI THAM LETTER HIGH CA;Lo;0;L;;;;;N;;;;;
+1A28;TAI THAM LETTER HIGH CHA;Lo;0;L;;;;;N;;;;;
+1A29;TAI THAM LETTER LOW CA;Lo;0;L;;;;;N;;;;;
+1A2A;TAI THAM LETTER LOW SA;Lo;0;L;;;;;N;;;;;
+1A2B;TAI THAM LETTER LOW CHA;Lo;0;L;;;;;N;;;;;
+1A2C;TAI THAM LETTER NYA;Lo;0;L;;;;;N;;;;;
+1A2D;TAI THAM LETTER RATA;Lo;0;L;;;;;N;;;;;
+1A2E;TAI THAM LETTER HIGH RATHA;Lo;0;L;;;;;N;;;;;
+1A2F;TAI THAM LETTER DA;Lo;0;L;;;;;N;;;;;
+1A30;TAI THAM LETTER LOW RATHA;Lo;0;L;;;;;N;;;;;
+1A31;TAI THAM LETTER RANA;Lo;0;L;;;;;N;;;;;
+1A32;TAI THAM LETTER HIGH TA;Lo;0;L;;;;;N;;;;;
+1A33;TAI THAM LETTER HIGH THA;Lo;0;L;;;;;N;;;;;
+1A34;TAI THAM LETTER LOW TA;Lo;0;L;;;;;N;;;;;
+1A35;TAI THAM LETTER LOW THA;Lo;0;L;;;;;N;;;;;
+1A36;TAI THAM LETTER NA;Lo;0;L;;;;;N;;;;;
+1A37;TAI THAM LETTER BA;Lo;0;L;;;;;N;;;;;
+1A38;TAI THAM LETTER HIGH PA;Lo;0;L;;;;;N;;;;;
+1A39;TAI THAM LETTER HIGH PHA;Lo;0;L;;;;;N;;;;;
+1A3A;TAI THAM LETTER HIGH FA;Lo;0;L;;;;;N;;;;;
+1A3B;TAI THAM LETTER LOW PA;Lo;0;L;;;;;N;;;;;
+1A3C;TAI THAM LETTER LOW FA;Lo;0;L;;;;;N;;;;;
+1A3D;TAI THAM LETTER LOW PHA;Lo;0;L;;;;;N;;;;;
+1A3E;TAI THAM LETTER MA;Lo;0;L;;;;;N;;;;;
+1A3F;TAI THAM LETTER LOW YA;Lo;0;L;;;;;N;;;;;
+1A40;TAI THAM LETTER HIGH YA;Lo;0;L;;;;;N;;;;;
+1A41;TAI THAM LETTER RA;Lo;0;L;;;;;N;;;;;
+1A42;TAI THAM LETTER RUE;Lo;0;L;;;;;N;;;;;
+1A43;TAI THAM LETTER LA;Lo;0;L;;;;;N;;;;;
+1A44;TAI THAM LETTER LUE;Lo;0;L;;;;;N;;;;;
+1A45;TAI THAM LETTER WA;Lo;0;L;;;;;N;;;;;
+1A46;TAI THAM LETTER HIGH SHA;Lo;0;L;;;;;N;;;;;
+1A47;TAI THAM LETTER HIGH SSA;Lo;0;L;;;;;N;;;;;
+1A48;TAI THAM LETTER HIGH SA;Lo;0;L;;;;;N;;;;;
+1A49;TAI THAM LETTER HIGH HA;Lo;0;L;;;;;N;;;;;
+1A4A;TAI THAM LETTER LLA;Lo;0;L;;;;;N;;;;;
+1A4B;TAI THAM LETTER A;Lo;0;L;;;;;N;;;;;
+1A4C;TAI THAM LETTER LOW HA;Lo;0;L;;;;;N;;;;;
+1A4D;TAI THAM LETTER I;Lo;0;L;;;;;N;;;;;
+1A4E;TAI THAM LETTER II;Lo;0;L;;;;;N;;;;;
+1A4F;TAI THAM LETTER U;Lo;0;L;;;;;N;;;;;
+1A50;TAI THAM LETTER UU;Lo;0;L;;;;;N;;;;;
+1A51;TAI THAM LETTER EE;Lo;0;L;;;;;N;;;;;
+1A52;TAI THAM LETTER OO;Lo;0;L;;;;;N;;;;;
+1A53;TAI THAM LETTER LAE;Lo;0;L;;;;;N;;;;;
+1A54;TAI THAM LETTER GREAT SA;Lo;0;L;;;;;N;;;;;
+1A55;TAI THAM CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;;
+1A56;TAI THAM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;;
+1A57;TAI THAM CONSONANT SIGN LA TANG LAI;Mc;0;L;;;;;N;;;;;
+1A58;TAI THAM SIGN MAI KANG LAI;Mn;0;NSM;;;;;N;;;;;
+1A59;TAI THAM CONSONANT SIGN FINAL NGA;Mn;0;NSM;;;;;N;;;;;
+1A5A;TAI THAM CONSONANT SIGN LOW PA;Mn;0;NSM;;;;;N;;;;;
+1A5B;TAI THAM CONSONANT SIGN HIGH RATHA OR LOW PA;Mn;0;NSM;;;;;N;;;;;
+1A5C;TAI THAM CONSONANT SIGN MA;Mn;0;NSM;;;;;N;;;;;
+1A5D;TAI THAM CONSONANT SIGN BA;Mn;0;NSM;;;;;N;;;;;
+1A5E;TAI THAM CONSONANT SIGN SA;Mn;0;NSM;;;;;N;;;;;
+1A60;TAI THAM SIGN SAKOT;Mn;9;NSM;;;;;N;;;;;
+1A61;TAI THAM VOWEL SIGN A;Mc;0;L;;;;;N;;;;;
+1A62;TAI THAM VOWEL SIGN MAI SAT;Mn;0;NSM;;;;;N;;;;;
+1A63;TAI THAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+1A64;TAI THAM VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;;
+1A65;TAI THAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1A66;TAI THAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+1A67;TAI THAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
+1A68;TAI THAM VOWEL SIGN UUE;Mn;0;NSM;;;;;N;;;;;
+1A69;TAI THAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1A6A;TAI THAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1A6B;TAI THAM VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+1A6C;TAI THAM VOWEL SIGN OA BELOW;Mn;0;NSM;;;;;N;;;;;
+1A6D;TAI THAM VOWEL SIGN OY;Mc;0;L;;;;;N;;;;;
+1A6E;TAI THAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1A6F;TAI THAM VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
+1A70;TAI THAM VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+1A71;TAI THAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+1A72;TAI THAM VOWEL SIGN THAM AI;Mc;0;L;;;;;N;;;;;
+1A73;TAI THAM VOWEL SIGN OA ABOVE;Mn;0;NSM;;;;;N;;;;;
+1A74;TAI THAM SIGN MAI KANG;Mn;0;NSM;;;;;N;;;;;
+1A75;TAI THAM SIGN TONE-1;Mn;230;NSM;;;;;N;;;;;
+1A76;TAI THAM SIGN TONE-2;Mn;230;NSM;;;;;N;;;;;
+1A77;TAI THAM SIGN KHUEN TONE-3;Mn;230;NSM;;;;;N;;;;;
+1A78;TAI THAM SIGN KHUEN TONE-4;Mn;230;NSM;;;;;N;;;;;
+1A79;TAI THAM SIGN KHUEN TONE-5;Mn;230;NSM;;;;;N;;;;;
+1A7A;TAI THAM SIGN RA HAAM;Mn;230;NSM;;;;;N;;;;;
+1A7B;TAI THAM SIGN MAI SAM;Mn;230;NSM;;;;;N;;;;;
+1A7C;TAI THAM SIGN KHUEN-LUE KARAN;Mn;230;NSM;;;;;N;;;;;
+1A7F;TAI THAM COMBINING CRYPTOGRAMMIC DOT;Mn;220;NSM;;;;;N;;;;;
+1A80;TAI THAM HORA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1A81;TAI THAM HORA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1A82;TAI THAM HORA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1A83;TAI THAM HORA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1A84;TAI THAM HORA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1A85;TAI THAM HORA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1A86;TAI THAM HORA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1A87;TAI THAM HORA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1A88;TAI THAM HORA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1A89;TAI THAM HORA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1A90;TAI THAM THAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1A91;TAI THAM THAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1A92;TAI THAM THAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1A93;TAI THAM THAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1A94;TAI THAM THAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1A95;TAI THAM THAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1A96;TAI THAM THAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1A97;TAI THAM THAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1A98;TAI THAM THAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1A99;TAI THAM THAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1AA0;TAI THAM SIGN WIANG;Po;0;L;;;;;N;;;;;
+1AA1;TAI THAM SIGN WIANGWAAK;Po;0;L;;;;;N;;;;;
+1AA2;TAI THAM SIGN SAWAN;Po;0;L;;;;;N;;;;;
+1AA3;TAI THAM SIGN KEOW;Po;0;L;;;;;N;;;;;
+1AA4;TAI THAM SIGN HOY;Po;0;L;;;;;N;;;;;
+1AA5;TAI THAM SIGN DOKMAI;Po;0;L;;;;;N;;;;;
+1AA6;TAI THAM SIGN REVERSED ROTATED RANA;Po;0;L;;;;;N;;;;;
+1AA7;TAI THAM SIGN MAI YAMOK;Lm;0;L;;;;;N;;;;;
+1AA8;TAI THAM SIGN KAAN;Po;0;L;;;;;N;;;;;
+1AA9;TAI THAM SIGN KAANKUU;Po;0;L;;;;;N;;;;;
+1AAA;TAI THAM SIGN SATKAAN;Po;0;L;;;;;N;;;;;
+1AAB;TAI THAM SIGN SATKAANKUU;Po;0;L;;;;;N;;;;;
+1AAC;TAI THAM SIGN HANG;Po;0;L;;;;;N;;;;;
+1AAD;TAI THAM SIGN CAANG;Po;0;L;;;;;N;;;;;
+1AB0;COMBINING DOUBLED CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;;;;;
+1AB1;COMBINING DIAERESIS-RING;Mn;230;NSM;;;;;N;;;;;
+1AB2;COMBINING INFINITY;Mn;230;NSM;;;;;N;;;;;
+1AB3;COMBINING DOWNWARDS ARROW;Mn;230;NSM;;;;;N;;;;;
+1AB4;COMBINING TRIPLE DOT;Mn;230;NSM;;;;;N;;;;;
+1AB5;COMBINING X-X BELOW;Mn;220;NSM;;;;;N;;;;;
+1AB6;COMBINING WIGGLY LINE BELOW;Mn;220;NSM;;;;;N;;;;;
+1AB7;COMBINING OPEN MARK BELOW;Mn;220;NSM;;;;;N;;;;;
+1AB8;COMBINING DOUBLE OPEN MARK BELOW;Mn;220;NSM;;;;;N;;;;;
+1AB9;COMBINING LIGHT CENTRALIZATION STROKE BELOW;Mn;220;NSM;;;;;N;;;;;
+1ABA;COMBINING STRONG CENTRALIZATION STROKE BELOW;Mn;220;NSM;;;;;N;;;;;
+1ABB;COMBINING PARENTHESES ABOVE;Mn;230;NSM;;;;;N;;;;;
+1ABC;COMBINING DOUBLE PARENTHESES ABOVE;Mn;230;NSM;;;;;N;;;;;
+1ABD;COMBINING PARENTHESES BELOW;Mn;220;NSM;;;;;N;;;;;
+1ABE;COMBINING PARENTHESES OVERLAY;Me;0;NSM;;;;;N;;;;;
+1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;;
+1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;;
+1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;;
+1B03;BALINESE SIGN SURANG;Mn;0;NSM;;;;;N;;;;;
+1B04;BALINESE SIGN BISAH;Mc;0;L;;;;;N;;;;;
+1B05;BALINESE LETTER AKARA;Lo;0;L;;;;;N;;;;;
+1B06;BALINESE LETTER AKARA TEDUNG;Lo;0;L;1B05 1B35;;;;N;;;;;
+1B07;BALINESE LETTER IKARA;Lo;0;L;;;;;N;;;;;
+1B08;BALINESE LETTER IKARA TEDUNG;Lo;0;L;1B07 1B35;;;;N;;;;;
+1B09;BALINESE LETTER UKARA;Lo;0;L;;;;;N;;;;;
+1B0A;BALINESE LETTER UKARA TEDUNG;Lo;0;L;1B09 1B35;;;;N;;;;;
+1B0B;BALINESE LETTER RA REPA;Lo;0;L;;;;;N;;;;;
+1B0C;BALINESE LETTER RA REPA TEDUNG;Lo;0;L;1B0B 1B35;;;;N;;;;;
+1B0D;BALINESE LETTER LA LENGA;Lo;0;L;;;;;N;;;;;
+1B0E;BALINESE LETTER LA LENGA TEDUNG;Lo;0;L;1B0D 1B35;;;;N;;;;;
+1B0F;BALINESE LETTER EKARA;Lo;0;L;;;;;N;;;;;
+1B10;BALINESE LETTER AIKARA;Lo;0;L;;;;;N;;;;;
+1B11;BALINESE LETTER OKARA;Lo;0;L;;;;;N;;;;;
+1B12;BALINESE LETTER OKARA TEDUNG;Lo;0;L;1B11 1B35;;;;N;;;;;
+1B13;BALINESE LETTER KA;Lo;0;L;;;;;N;;;;;
+1B14;BALINESE LETTER KA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+1B15;BALINESE LETTER GA;Lo;0;L;;;;;N;;;;;
+1B16;BALINESE LETTER GA GORA;Lo;0;L;;;;;N;;;;;
+1B17;BALINESE LETTER NGA;Lo;0;L;;;;;N;;;;;
+1B18;BALINESE LETTER CA;Lo;0;L;;;;;N;;;;;
+1B19;BALINESE LETTER CA LACA;Lo;0;L;;;;;N;;;;;
+1B1A;BALINESE LETTER JA;Lo;0;L;;;;;N;;;;;
+1B1B;BALINESE LETTER JA JERA;Lo;0;L;;;;;N;;;;;
+1B1C;BALINESE LETTER NYA;Lo;0;L;;;;;N;;;;;
+1B1D;BALINESE LETTER TA LATIK;Lo;0;L;;;;;N;;;;;
+1B1E;BALINESE LETTER TA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+1B1F;BALINESE LETTER DA MURDA ALPAPRANA;Lo;0;L;;;;;N;;;;;
+1B20;BALINESE LETTER DA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+1B21;BALINESE LETTER NA RAMBAT;Lo;0;L;;;;;N;;;;;
+1B22;BALINESE LETTER TA;Lo;0;L;;;;;N;;;;;
+1B23;BALINESE LETTER TA TAWA;Lo;0;L;;;;;N;;;;;
+1B24;BALINESE LETTER DA;Lo;0;L;;;;;N;;;;;
+1B25;BALINESE LETTER DA MADU;Lo;0;L;;;;;N;;;;;
+1B26;BALINESE LETTER NA;Lo;0;L;;;;;N;;;;;
+1B27;BALINESE LETTER PA;Lo;0;L;;;;;N;;;;;
+1B28;BALINESE LETTER PA KAPAL;Lo;0;L;;;;;N;;;;;
+1B29;BALINESE LETTER BA;Lo;0;L;;;;;N;;;;;
+1B2A;BALINESE LETTER BA KEMBANG;Lo;0;L;;;;;N;;;;;
+1B2B;BALINESE LETTER MA;Lo;0;L;;;;;N;;;;;
+1B2C;BALINESE LETTER YA;Lo;0;L;;;;;N;;;;;
+1B2D;BALINESE LETTER RA;Lo;0;L;;;;;N;;;;;
+1B2E;BALINESE LETTER LA;Lo;0;L;;;;;N;;;;;
+1B2F;BALINESE LETTER WA;Lo;0;L;;;;;N;;;;;
+1B30;BALINESE LETTER SA SAGA;Lo;0;L;;;;;N;;;;;
+1B31;BALINESE LETTER SA SAPA;Lo;0;L;;;;;N;;;;;
+1B32;BALINESE LETTER SA;Lo;0;L;;;;;N;;;;;
+1B33;BALINESE LETTER HA;Lo;0;L;;;;;N;;;;;
+1B34;BALINESE SIGN REREKAN;Mn;7;NSM;;;;;N;;;;;
+1B35;BALINESE VOWEL SIGN TEDUNG;Mc;0;L;;;;;N;;;;;
+1B36;BALINESE VOWEL SIGN ULU;Mn;0;NSM;;;;;N;;;;;
+1B37;BALINESE VOWEL SIGN ULU SARI;Mn;0;NSM;;;;;N;;;;;
+1B38;BALINESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;;
+1B39;BALINESE VOWEL SIGN SUKU ILUT;Mn;0;NSM;;;;;N;;;;;
+1B3A;BALINESE VOWEL SIGN RA REPA;Mn;0;NSM;;;;;N;;;;;
+1B3B;BALINESE VOWEL SIGN RA REPA TEDUNG;Mc;0;L;1B3A 1B35;;;;N;;;;;
+1B3C;BALINESE VOWEL SIGN LA LENGA;Mn;0;NSM;;;;;N;;;;;
+1B3D;BALINESE VOWEL SIGN LA LENGA TEDUNG;Mc;0;L;1B3C 1B35;;;;N;;;;;
+1B3E;BALINESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;;
+1B3F;BALINESE VOWEL SIGN TALING REPA;Mc;0;L;;;;;N;;;;;
+1B40;BALINESE VOWEL SIGN TALING TEDUNG;Mc;0;L;1B3E 1B35;;;;N;;;;;
+1B41;BALINESE VOWEL SIGN TALING REPA TEDUNG;Mc;0;L;1B3F 1B35;;;;N;;;;;
+1B42;BALINESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;;
+1B43;BALINESE VOWEL SIGN PEPET TEDUNG;Mc;0;L;1B42 1B35;;;;N;;;;;
+1B44;BALINESE ADEG ADEG;Mc;9;L;;;;;N;;;;;
+1B45;BALINESE LETTER KAF SASAK;Lo;0;L;;;;;N;;;;;
+1B46;BALINESE LETTER KHOT SASAK;Lo;0;L;;;;;N;;;;;
+1B47;BALINESE LETTER TZIR SASAK;Lo;0;L;;;;;N;;;;;
+1B48;BALINESE LETTER EF SASAK;Lo;0;L;;;;;N;;;;;
+1B49;BALINESE LETTER VE SASAK;Lo;0;L;;;;;N;;;;;
+1B4A;BALINESE LETTER ZAL SASAK;Lo;0;L;;;;;N;;;;;
+1B4B;BALINESE LETTER ASYURA SASAK;Lo;0;L;;;;;N;;;;;
+1B50;BALINESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1B51;BALINESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1B52;BALINESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1B53;BALINESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1B54;BALINESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1B55;BALINESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1B56;BALINESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1B57;BALINESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1B58;BALINESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1B59;BALINESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1B5A;BALINESE PANTI;Po;0;L;;;;;N;;;;;
+1B5B;BALINESE PAMADA;Po;0;L;;;;;N;;;;;
+1B5C;BALINESE WINDU;Po;0;L;;;;;N;;;;;
+1B5D;BALINESE CARIK PAMUNGKAH;Po;0;L;;;;;N;;;;;
+1B5E;BALINESE CARIK SIKI;Po;0;L;;;;;N;;;;;
+1B5F;BALINESE CARIK PAREREN;Po;0;L;;;;;N;;;;;
+1B60;BALINESE PAMENENG;Po;0;L;;;;;N;;;;;
+1B61;BALINESE MUSICAL SYMBOL DONG;So;0;L;;;;;N;;;;;
+1B62;BALINESE MUSICAL SYMBOL DENG;So;0;L;;;;;N;;;;;
+1B63;BALINESE MUSICAL SYMBOL DUNG;So;0;L;;;;;N;;;;;
+1B64;BALINESE MUSICAL SYMBOL DANG;So;0;L;;;;;N;;;;;
+1B65;BALINESE MUSICAL SYMBOL DANG SURANG;So;0;L;;;;;N;;;;;
+1B66;BALINESE MUSICAL SYMBOL DING;So;0;L;;;;;N;;;;;
+1B67;BALINESE MUSICAL SYMBOL DAENG;So;0;L;;;;;N;;;;;
+1B68;BALINESE MUSICAL SYMBOL DEUNG;So;0;L;;;;;N;;;;;
+1B69;BALINESE MUSICAL SYMBOL DAING;So;0;L;;;;;N;;;;;
+1B6A;BALINESE MUSICAL SYMBOL DANG GEDE;So;0;L;;;;;N;;;;;
+1B6B;BALINESE MUSICAL SYMBOL COMBINING TEGEH;Mn;230;NSM;;;;;N;;;;;
+1B6C;BALINESE MUSICAL SYMBOL COMBINING ENDEP;Mn;220;NSM;;;;;N;;;;;
+1B6D;BALINESE MUSICAL SYMBOL COMBINING KEMPUL;Mn;230;NSM;;;;;N;;;;;
+1B6E;BALINESE MUSICAL SYMBOL COMBINING KEMPLI;Mn;230;NSM;;;;;N;;;;;
+1B6F;BALINESE MUSICAL SYMBOL COMBINING JEGOGAN;Mn;230;NSM;;;;;N;;;;;
+1B70;BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;;
+1B71;BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;;
+1B72;BALINESE MUSICAL SYMBOL COMBINING BENDE;Mn;230;NSM;;;;;N;;;;;
+1B73;BALINESE MUSICAL SYMBOL COMBINING GONG;Mn;230;NSM;;;;;N;;;;;
+1B74;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG;So;0;L;;;;;N;;;;;
+1B75;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG;So;0;L;;;;;N;;;;;
+1B76;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK;So;0;L;;;;;N;;;;;
+1B77;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK;So;0;L;;;;;N;;;;;
+1B78;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG;So;0;L;;;;;N;;;;;
+1B79;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG;So;0;L;;;;;N;;;;;
+1B7A;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK;So;0;L;;;;;N;;;;;
+1B7B;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK;So;0;L;;;;;N;;;;;
+1B7C;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING;So;0;L;;;;;N;;;;;
+1B80;SUNDANESE SIGN PANYECEK;Mn;0;NSM;;;;;N;;;;;
+1B81;SUNDANESE SIGN PANGLAYAR;Mn;0;NSM;;;;;N;;;;;
+1B82;SUNDANESE SIGN PANGWISAD;Mc;0;L;;;;;N;;;;;
+1B83;SUNDANESE LETTER A;Lo;0;L;;;;;N;;;;;
+1B84;SUNDANESE LETTER I;Lo;0;L;;;;;N;;;;;
+1B85;SUNDANESE LETTER U;Lo;0;L;;;;;N;;;;;
+1B86;SUNDANESE LETTER AE;Lo;0;L;;;;;N;;;;;
+1B87;SUNDANESE LETTER O;Lo;0;L;;;;;N;;;;;
+1B88;SUNDANESE LETTER E;Lo;0;L;;;;;N;;;;;
+1B89;SUNDANESE LETTER EU;Lo;0;L;;;;;N;;;;;
+1B8A;SUNDANESE LETTER KA;Lo;0;L;;;;;N;;;;;
+1B8B;SUNDANESE LETTER QA;Lo;0;L;;;;;N;;;;;
+1B8C;SUNDANESE LETTER GA;Lo;0;L;;;;;N;;;;;
+1B8D;SUNDANESE LETTER NGA;Lo;0;L;;;;;N;;;;;
+1B8E;SUNDANESE LETTER CA;Lo;0;L;;;;;N;;;;;
+1B8F;SUNDANESE LETTER JA;Lo;0;L;;;;;N;;;;;
+1B90;SUNDANESE LETTER ZA;Lo;0;L;;;;;N;;;;;
+1B91;SUNDANESE LETTER NYA;Lo;0;L;;;;;N;;;;;
+1B92;SUNDANESE LETTER TA;Lo;0;L;;;;;N;;;;;
+1B93;SUNDANESE LETTER DA;Lo;0;L;;;;;N;;;;;
+1B94;SUNDANESE LETTER NA;Lo;0;L;;;;;N;;;;;
+1B95;SUNDANESE LETTER PA;Lo;0;L;;;;;N;;;;;
+1B96;SUNDANESE LETTER FA;Lo;0;L;;;;;N;;;;;
+1B97;SUNDANESE LETTER VA;Lo;0;L;;;;;N;;;;;
+1B98;SUNDANESE LETTER BA;Lo;0;L;;;;;N;;;;;
+1B99;SUNDANESE LETTER MA;Lo;0;L;;;;;N;;;;;
+1B9A;SUNDANESE LETTER YA;Lo;0;L;;;;;N;;;;;
+1B9B;SUNDANESE LETTER RA;Lo;0;L;;;;;N;;;;;
+1B9C;SUNDANESE LETTER LA;Lo;0;L;;;;;N;;;;;
+1B9D;SUNDANESE LETTER WA;Lo;0;L;;;;;N;;;;;
+1B9E;SUNDANESE LETTER SA;Lo;0;L;;;;;N;;;;;
+1B9F;SUNDANESE LETTER XA;Lo;0;L;;;;;N;;;;;
+1BA0;SUNDANESE LETTER HA;Lo;0;L;;;;;N;;;;;
+1BA1;SUNDANESE CONSONANT SIGN PAMINGKAL;Mc;0;L;;;;;N;;;;;
+1BA2;SUNDANESE CONSONANT SIGN PANYAKRA;Mn;0;NSM;;;;;N;;;;;
+1BA3;SUNDANESE CONSONANT SIGN PANYIKU;Mn;0;NSM;;;;;N;;;;;
+1BA4;SUNDANESE VOWEL SIGN PANGHULU;Mn;0;NSM;;;;;N;;;;;
+1BA5;SUNDANESE VOWEL SIGN PANYUKU;Mn;0;NSM;;;;;N;;;;;
+1BA6;SUNDANESE VOWEL SIGN PANAELAENG;Mc;0;L;;;;;N;;;;;
+1BA7;SUNDANESE VOWEL SIGN PANOLONG;Mc;0;L;;;;;N;;;;;
+1BA8;SUNDANESE VOWEL SIGN PAMEPET;Mn;0;NSM;;;;;N;;;;;
+1BA9;SUNDANESE VOWEL SIGN PANEULEUNG;Mn;0;NSM;;;;;N;;;;;
+1BAA;SUNDANESE SIGN PAMAAEH;Mc;9;L;;;;;N;;;;;
+1BAB;SUNDANESE SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+1BAC;SUNDANESE CONSONANT SIGN PASANGAN MA;Mn;0;NSM;;;;;N;;;;;
+1BAD;SUNDANESE CONSONANT SIGN PASANGAN WA;Mn;0;NSM;;;;;N;;;;;
+1BAE;SUNDANESE LETTER KHA;Lo;0;L;;;;;N;;;;;
+1BAF;SUNDANESE LETTER SYA;Lo;0;L;;;;;N;;;;;
+1BB0;SUNDANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1BB1;SUNDANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1BB2;SUNDANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1BB3;SUNDANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1BB4;SUNDANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1BB5;SUNDANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1BB6;SUNDANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1BB7;SUNDANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1BB8;SUNDANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1BB9;SUNDANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1BBA;SUNDANESE AVAGRAHA;Lo;0;L;;;;;N;;;;;
+1BBB;SUNDANESE LETTER REU;Lo;0;L;;;;;N;;;;;
+1BBC;SUNDANESE LETTER LEU;Lo;0;L;;;;;N;;;;;
+1BBD;SUNDANESE LETTER BHA;Lo;0;L;;;;;N;;;;;
+1BBE;SUNDANESE LETTER FINAL K;Lo;0;L;;;;;N;;;;;
+1BBF;SUNDANESE LETTER FINAL M;Lo;0;L;;;;;N;;;;;
+1BC0;BATAK LETTER A;Lo;0;L;;;;;N;;;;;
+1BC1;BATAK LETTER SIMALUNGUN A;Lo;0;L;;;;;N;;;;;
+1BC2;BATAK LETTER HA;Lo;0;L;;;;;N;;;;;
+1BC3;BATAK LETTER SIMALUNGUN HA;Lo;0;L;;;;;N;;;;;
+1BC4;BATAK LETTER MANDAILING HA;Lo;0;L;;;;;N;;;;;
+1BC5;BATAK LETTER BA;Lo;0;L;;;;;N;;;;;
+1BC6;BATAK LETTER KARO BA;Lo;0;L;;;;;N;;;;;
+1BC7;BATAK LETTER PA;Lo;0;L;;;;;N;;;;;
+1BC8;BATAK LETTER SIMALUNGUN PA;Lo;0;L;;;;;N;;;;;
+1BC9;BATAK LETTER NA;Lo;0;L;;;;;N;;;;;
+1BCA;BATAK LETTER MANDAILING NA;Lo;0;L;;;;;N;;;;;
+1BCB;BATAK LETTER WA;Lo;0;L;;;;;N;;;;;
+1BCC;BATAK LETTER SIMALUNGUN WA;Lo;0;L;;;;;N;;;;;
+1BCD;BATAK LETTER PAKPAK WA;Lo;0;L;;;;;N;;;;;
+1BCE;BATAK LETTER GA;Lo;0;L;;;;;N;;;;;
+1BCF;BATAK LETTER SIMALUNGUN GA;Lo;0;L;;;;;N;;;;;
+1BD0;BATAK LETTER JA;Lo;0;L;;;;;N;;;;;
+1BD1;BATAK LETTER DA;Lo;0;L;;;;;N;;;;;
+1BD2;BATAK LETTER RA;Lo;0;L;;;;;N;;;;;
+1BD3;BATAK LETTER SIMALUNGUN RA;Lo;0;L;;;;;N;;;;;
+1BD4;BATAK LETTER MA;Lo;0;L;;;;;N;;;;;
+1BD5;BATAK LETTER SIMALUNGUN MA;Lo;0;L;;;;;N;;;;;
+1BD6;BATAK LETTER SOUTHERN TA;Lo;0;L;;;;;N;;;;;
+1BD7;BATAK LETTER NORTHERN TA;Lo;0;L;;;;;N;;;;;
+1BD8;BATAK LETTER SA;Lo;0;L;;;;;N;;;;;
+1BD9;BATAK LETTER SIMALUNGUN SA;Lo;0;L;;;;;N;;;;;
+1BDA;BATAK LETTER MANDAILING SA;Lo;0;L;;;;;N;;;;;
+1BDB;BATAK LETTER YA;Lo;0;L;;;;;N;;;;;
+1BDC;BATAK LETTER SIMALUNGUN YA;Lo;0;L;;;;;N;;;;;
+1BDD;BATAK LETTER NGA;Lo;0;L;;;;;N;;;;;
+1BDE;BATAK LETTER LA;Lo;0;L;;;;;N;;;;;
+1BDF;BATAK LETTER SIMALUNGUN LA;Lo;0;L;;;;;N;;;;;
+1BE0;BATAK LETTER NYA;Lo;0;L;;;;;N;;;;;
+1BE1;BATAK LETTER CA;Lo;0;L;;;;;N;;;;;
+1BE2;BATAK LETTER NDA;Lo;0;L;;;;;N;;;;;
+1BE3;BATAK LETTER MBA;Lo;0;L;;;;;N;;;;;
+1BE4;BATAK LETTER I;Lo;0;L;;;;;N;;;;;
+1BE5;BATAK LETTER U;Lo;0;L;;;;;N;;;;;
+1BE6;BATAK SIGN TOMPI;Mn;7;NSM;;;;;N;;;;;
+1BE7;BATAK VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1BE8;BATAK VOWEL SIGN PAKPAK E;Mn;0;NSM;;;;;N;;;;;
+1BE9;BATAK VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;
+1BEA;BATAK VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+1BEB;BATAK VOWEL SIGN KARO I;Mc;0;L;;;;;N;;;;;
+1BEC;BATAK VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+1BED;BATAK VOWEL SIGN KARO O;Mn;0;NSM;;;;;N;;;;;
+1BEE;BATAK VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+1BEF;BATAK VOWEL SIGN U FOR SIMALUNGUN SA;Mn;0;NSM;;;;;N;;;;;
+1BF0;BATAK CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;;
+1BF1;BATAK CONSONANT SIGN H;Mn;0;NSM;;;;;N;;;;;
+1BF2;BATAK PANGOLAT;Mc;9;L;;;;;N;;;;;
+1BF3;BATAK PANONGONAN;Mc;9;L;;;;;N;;;;;
+1BFC;BATAK SYMBOL BINDU NA METEK;Po;0;L;;;;;N;;;;;
+1BFD;BATAK SYMBOL BINDU PINARBORAS;Po;0;L;;;;;N;;;;;
+1BFE;BATAK SYMBOL BINDU JUDUL;Po;0;L;;;;;N;;;;;
+1BFF;BATAK SYMBOL BINDU PANGOLAT;Po;0;L;;;;;N;;;;;
+1C00;LEPCHA LETTER KA;Lo;0;L;;;;;N;;;;;
+1C01;LEPCHA LETTER KLA;Lo;0;L;;;;;N;;;;;
+1C02;LEPCHA LETTER KHA;Lo;0;L;;;;;N;;;;;
+1C03;LEPCHA LETTER GA;Lo;0;L;;;;;N;;;;;
+1C04;LEPCHA LETTER GLA;Lo;0;L;;;;;N;;;;;
+1C05;LEPCHA LETTER NGA;Lo;0;L;;;;;N;;;;;
+1C06;LEPCHA LETTER CA;Lo;0;L;;;;;N;;;;;
+1C07;LEPCHA LETTER CHA;Lo;0;L;;;;;N;;;;;
+1C08;LEPCHA LETTER JA;Lo;0;L;;;;;N;;;;;
+1C09;LEPCHA LETTER NYA;Lo;0;L;;;;;N;;;;;
+1C0A;LEPCHA LETTER TA;Lo;0;L;;;;;N;;;;;
+1C0B;LEPCHA LETTER THA;Lo;0;L;;;;;N;;;;;
+1C0C;LEPCHA LETTER DA;Lo;0;L;;;;;N;;;;;
+1C0D;LEPCHA LETTER NA;Lo;0;L;;;;;N;;;;;
+1C0E;LEPCHA LETTER PA;Lo;0;L;;;;;N;;;;;
+1C0F;LEPCHA LETTER PLA;Lo;0;L;;;;;N;;;;;
+1C10;LEPCHA LETTER PHA;Lo;0;L;;;;;N;;;;;
+1C11;LEPCHA LETTER FA;Lo;0;L;;;;;N;;;;;
+1C12;LEPCHA LETTER FLA;Lo;0;L;;;;;N;;;;;
+1C13;LEPCHA LETTER BA;Lo;0;L;;;;;N;;;;;
+1C14;LEPCHA LETTER BLA;Lo;0;L;;;;;N;;;;;
+1C15;LEPCHA LETTER MA;Lo;0;L;;;;;N;;;;;
+1C16;LEPCHA LETTER MLA;Lo;0;L;;;;;N;;;;;
+1C17;LEPCHA LETTER TSA;Lo;0;L;;;;;N;;;;;
+1C18;LEPCHA LETTER TSHA;Lo;0;L;;;;;N;;;;;
+1C19;LEPCHA LETTER DZA;Lo;0;L;;;;;N;;;;;
+1C1A;LEPCHA LETTER YA;Lo;0;L;;;;;N;;;;;
+1C1B;LEPCHA LETTER RA;Lo;0;L;;;;;N;;;;;
+1C1C;LEPCHA LETTER LA;Lo;0;L;;;;;N;;;;;
+1C1D;LEPCHA LETTER HA;Lo;0;L;;;;;N;;;;;
+1C1E;LEPCHA LETTER HLA;Lo;0;L;;;;;N;;;;;
+1C1F;LEPCHA LETTER VA;Lo;0;L;;;;;N;;;;;
+1C20;LEPCHA LETTER SA;Lo;0;L;;;;;N;;;;;
+1C21;LEPCHA LETTER SHA;Lo;0;L;;;;;N;;;;;
+1C22;LEPCHA LETTER WA;Lo;0;L;;;;;N;;;;;
+1C23;LEPCHA LETTER A;Lo;0;L;;;;;N;;;;;
+1C24;LEPCHA SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;;
+1C25;LEPCHA SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;;
+1C26;LEPCHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+1C27;LEPCHA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+1C28;LEPCHA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+1C29;LEPCHA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+1C2A;LEPCHA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+1C2B;LEPCHA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+1C2C;LEPCHA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+1C2D;LEPCHA CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;;
+1C2E;LEPCHA CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;;
+1C2F;LEPCHA CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;;
+1C30;LEPCHA CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;;
+1C31;LEPCHA CONSONANT SIGN P;Mn;0;NSM;;;;;N;;;;;
+1C32;LEPCHA CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;;
+1C33;LEPCHA CONSONANT SIGN T;Mn;0;NSM;;;;;N;;;;;
+1C34;LEPCHA CONSONANT SIGN NYIN-DO;Mc;0;L;;;;;N;;;;;
+1C35;LEPCHA CONSONANT SIGN KANG;Mc;0;L;;;;;N;;;;;
+1C36;LEPCHA SIGN RAN;Mn;0;NSM;;;;;N;;;;;
+1C37;LEPCHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+1C3B;LEPCHA PUNCTUATION TA-ROL;Po;0;L;;;;;N;;;;;
+1C3C;LEPCHA PUNCTUATION NYET THYOOM TA-ROL;Po;0;L;;;;;N;;;;;
+1C3D;LEPCHA PUNCTUATION CER-WA;Po;0;L;;;;;N;;;;;
+1C3E;LEPCHA PUNCTUATION TSHOOK CER-WA;Po;0;L;;;;;N;;;;;
+1C3F;LEPCHA PUNCTUATION TSHOOK;Po;0;L;;;;;N;;;;;
+1C40;LEPCHA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1C41;LEPCHA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1C42;LEPCHA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1C43;LEPCHA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1C44;LEPCHA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1C45;LEPCHA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1C46;LEPCHA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1C47;LEPCHA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1C48;LEPCHA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1C49;LEPCHA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1C4D;LEPCHA LETTER TTA;Lo;0;L;;;;;N;;;;;
+1C4E;LEPCHA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1C4F;LEPCHA LETTER DDA;Lo;0;L;;;;;N;;;;;
+1C50;OL CHIKI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1C51;OL CHIKI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1C52;OL CHIKI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1C53;OL CHIKI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1C54;OL CHIKI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1C55;OL CHIKI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1C56;OL CHIKI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1C57;OL CHIKI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1C58;OL CHIKI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1C59;OL CHIKI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1C5A;OL CHIKI LETTER LA;Lo;0;L;;;;;N;;;;;
+1C5B;OL CHIKI LETTER AT;Lo;0;L;;;;;N;;;;;
+1C5C;OL CHIKI LETTER AG;Lo;0;L;;;;;N;;;;;
+1C5D;OL CHIKI LETTER ANG;Lo;0;L;;;;;N;;;;;
+1C5E;OL CHIKI LETTER AL;Lo;0;L;;;;;N;;;;;
+1C5F;OL CHIKI LETTER LAA;Lo;0;L;;;;;N;;;;;
+1C60;OL CHIKI LETTER AAK;Lo;0;L;;;;;N;;;;;
+1C61;OL CHIKI LETTER AAJ;Lo;0;L;;;;;N;;;;;
+1C62;OL CHIKI LETTER AAM;Lo;0;L;;;;;N;;;;;
+1C63;OL CHIKI LETTER AAW;Lo;0;L;;;;;N;;;;;
+1C64;OL CHIKI LETTER LI;Lo;0;L;;;;;N;;;;;
+1C65;OL CHIKI LETTER IS;Lo;0;L;;;;;N;;;;;
+1C66;OL CHIKI LETTER IH;Lo;0;L;;;;;N;;;;;
+1C67;OL CHIKI LETTER INY;Lo;0;L;;;;;N;;;;;
+1C68;OL CHIKI LETTER IR;Lo;0;L;;;;;N;;;;;
+1C69;OL CHIKI LETTER LU;Lo;0;L;;;;;N;;;;;
+1C6A;OL CHIKI LETTER UC;Lo;0;L;;;;;N;;;;;
+1C6B;OL CHIKI LETTER UD;Lo;0;L;;;;;N;;;;;
+1C6C;OL CHIKI LETTER UNN;Lo;0;L;;;;;N;;;;;
+1C6D;OL CHIKI LETTER UY;Lo;0;L;;;;;N;;;;;
+1C6E;OL CHIKI LETTER LE;Lo;0;L;;;;;N;;;;;
+1C6F;OL CHIKI LETTER EP;Lo;0;L;;;;;N;;;;;
+1C70;OL CHIKI LETTER EDD;Lo;0;L;;;;;N;;;;;
+1C71;OL CHIKI LETTER EN;Lo;0;L;;;;;N;;;;;
+1C72;OL CHIKI LETTER ERR;Lo;0;L;;;;;N;;;;;
+1C73;OL CHIKI LETTER LO;Lo;0;L;;;;;N;;;;;
+1C74;OL CHIKI LETTER OTT;Lo;0;L;;;;;N;;;;;
+1C75;OL CHIKI LETTER OB;Lo;0;L;;;;;N;;;;;
+1C76;OL CHIKI LETTER OV;Lo;0;L;;;;;N;;;;;
+1C77;OL CHIKI LETTER OH;Lo;0;L;;;;;N;;;;;
+1C78;OL CHIKI MU TTUDDAG;Lm;0;L;;;;;N;;;;;
+1C79;OL CHIKI GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;;
+1C7A;OL CHIKI MU-GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;;
+1C7B;OL CHIKI RELAA;Lm;0;L;;;;;N;;;;;
+1C7C;OL CHIKI PHAARKAA;Lm;0;L;;;;;N;;;;;
+1C7D;OL CHIKI AHAD;Lm;0;L;;;;;N;;;;;
+1C7E;OL CHIKI PUNCTUATION MUCAAD;Po;0;L;;;;;N;;;;;
+1C7F;OL CHIKI PUNCTUATION DOUBLE MUCAAD;Po;0;L;;;;;N;;;;;
+1C80;CYRILLIC SMALL LETTER ROUNDED VE;Ll;0;L;;;;;N;;;0412;;0412
+1C81;CYRILLIC SMALL LETTER LONG-LEGGED DE;Ll;0;L;;;;;N;;;0414;;0414
+1C82;CYRILLIC SMALL LETTER NARROW O;Ll;0;L;;;;;N;;;041E;;041E
+1C83;CYRILLIC SMALL LETTER WIDE ES;Ll;0;L;;;;;N;;;0421;;0421
+1C84;CYRILLIC SMALL LETTER TALL TE;Ll;0;L;;;;;N;;;0422;;0422
+1C85;CYRILLIC SMALL LETTER THREE-LEGGED TE;Ll;0;L;;;;;N;;;0422;;0422
+1C86;CYRILLIC SMALL LETTER TALL HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A
+1C87;CYRILLIC SMALL LETTER TALL YAT;Ll;0;L;;;;;N;;;0462;;0462
+1C88;CYRILLIC SMALL LETTER UNBLENDED UK;Ll;0;L;;;;;N;;;A64A;;A64A
+1CC0;SUNDANESE PUNCTUATION BINDU SURYA;Po;0;L;;;;;N;;;;;
+1CC1;SUNDANESE PUNCTUATION BINDU PANGLONG;Po;0;L;;;;;N;;;;;
+1CC2;SUNDANESE PUNCTUATION BINDU PURNAMA;Po;0;L;;;;;N;;;;;
+1CC3;SUNDANESE PUNCTUATION BINDU CAKRA;Po;0;L;;;;;N;;;;;
+1CC4;SUNDANESE PUNCTUATION BINDU LEU SATANGA;Po;0;L;;;;;N;;;;;
+1CC5;SUNDANESE PUNCTUATION BINDU KA SATANGA;Po;0;L;;;;;N;;;;;
+1CC6;SUNDANESE PUNCTUATION BINDU DA SATANGA;Po;0;L;;;;;N;;;;;
+1CC7;SUNDANESE PUNCTUATION BINDU BA SATANGA;Po;0;L;;;;;N;;;;;
+1CD0;VEDIC TONE KARSHANA;Mn;230;NSM;;;;;N;;;;;
+1CD1;VEDIC TONE SHARA;Mn;230;NSM;;;;;N;;;;;
+1CD2;VEDIC TONE PRENKHA;Mn;230;NSM;;;;;N;;;;;
+1CD3;VEDIC SIGN NIHSHVASA;Po;0;L;;;;;N;;;;;
+1CD4;VEDIC SIGN YAJURVEDIC MIDLINE SVARITA;Mn;1;NSM;;;;;N;;;;;
+1CD5;VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;;
+1CD6;VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;;
+1CD7;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;;
+1CD8;VEDIC TONE CANDRA BELOW;Mn;220;NSM;;;;;N;;;;;
+1CD9;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER;Mn;220;NSM;;;;;N;;;;;
+1CDA;VEDIC TONE DOUBLE SVARITA;Mn;230;NSM;;;;;N;;;;;
+1CDB;VEDIC TONE TRIPLE SVARITA;Mn;230;NSM;;;;;N;;;;;
+1CDC;VEDIC TONE KATHAKA ANUDATTA;Mn;220;NSM;;;;;N;;;;;
+1CDD;VEDIC TONE DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+1CDE;VEDIC TONE TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+1CDF;VEDIC TONE THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
+1CE0;VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA;Mn;230;NSM;;;;;N;;;;;
+1CE1;VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA;Mc;0;L;;;;;N;;;;;
+1CE2;VEDIC SIGN VISARGA SVARITA;Mn;1;NSM;;;;;N;;;;;
+1CE3;VEDIC SIGN VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;;
+1CE4;VEDIC SIGN REVERSED VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;;
+1CE5;VEDIC SIGN VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;;
+1CE6;VEDIC SIGN REVERSED VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;;
+1CE7;VEDIC SIGN VISARGA UDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;;
+1CE8;VEDIC SIGN VISARGA ANUDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;;
+1CE9;VEDIC SIGN ANUSVARA ANTARGOMUKHA;Lo;0;L;;;;;N;;;;;
+1CEA;VEDIC SIGN ANUSVARA BAHIRGOMUKHA;Lo;0;L;;;;;N;;;;;
+1CEB;VEDIC SIGN ANUSVARA VAMAGOMUKHA;Lo;0;L;;;;;N;;;;;
+1CEC;VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL;Lo;0;L;;;;;N;;;;;
+1CED;VEDIC SIGN TIRYAK;Mn;220;NSM;;;;;N;;;;;
+1CEE;VEDIC SIGN HEXIFORM LONG ANUSVARA;Lo;0;L;;;;;N;;;;;
+1CEF;VEDIC SIGN LONG ANUSVARA;Lo;0;L;;;;;N;;;;;
+1CF0;VEDIC SIGN RTHANG LONG ANUSVARA;Lo;0;L;;;;;N;;;;;
+1CF1;VEDIC SIGN ANUSVARA UBHAYATO MUKHA;Lo;0;L;;;;;N;;;;;
+1CF2;VEDIC SIGN ARDHAVISARGA;Mc;0;L;;;;;N;;;;;
+1CF3;VEDIC SIGN ROTATED ARDHAVISARGA;Mc;0;L;;;;;N;;;;;
+1CF4;VEDIC TONE CANDRA ABOVE;Mn;230;NSM;;;;;N;;;;;
+1CF5;VEDIC SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+1CF6;VEDIC SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+1CF8;VEDIC TONE RING ABOVE;Mn;230;NSM;;;;;N;;;;;
+1CF9;VEDIC TONE DOUBLE RING ABOVE;Mn;230;NSM;;;;;N;;;;;
+1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;;
+1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;;
+1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;;
+1D03;LATIN LETTER SMALL CAPITAL BARRED B;Ll;0;L;;;;;N;;;;;
+1D04;LATIN LETTER SMALL CAPITAL C;Ll;0;L;;;;;N;;;;;
+1D05;LATIN LETTER SMALL CAPITAL D;Ll;0;L;;;;;N;;;;;
+1D06;LATIN LETTER SMALL CAPITAL ETH;Ll;0;L;;;;;N;;;;;
+1D07;LATIN LETTER SMALL CAPITAL E;Ll;0;L;;;;;N;;;;;
+1D08;LATIN SMALL LETTER TURNED OPEN E;Ll;0;L;;;;;N;;;;;
+1D09;LATIN SMALL LETTER TURNED I;Ll;0;L;;;;;N;;;;;
+1D0A;LATIN LETTER SMALL CAPITAL J;Ll;0;L;;;;;N;;;;;
+1D0B;LATIN LETTER SMALL CAPITAL K;Ll;0;L;;;;;N;;;;;
+1D0C;LATIN LETTER SMALL CAPITAL L WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D0D;LATIN LETTER SMALL CAPITAL M;Ll;0;L;;;;;N;;;;;
+1D0E;LATIN LETTER SMALL CAPITAL REVERSED N;Ll;0;L;;;;;N;;;;;
+1D0F;LATIN LETTER SMALL CAPITAL O;Ll;0;L;;;;;N;;;;;
+1D10;LATIN LETTER SMALL CAPITAL OPEN O;Ll;0;L;;;;;N;;;;;
+1D11;LATIN SMALL LETTER SIDEWAYS O;Ll;0;L;;;;;N;;;;;
+1D12;LATIN SMALL LETTER SIDEWAYS OPEN O;Ll;0;L;;;;;N;;;;;
+1D13;LATIN SMALL LETTER SIDEWAYS O WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D14;LATIN SMALL LETTER TURNED OE;Ll;0;L;;;;;N;;;;;
+1D15;LATIN LETTER SMALL CAPITAL OU;Ll;0;L;;;;;N;;;;;
+1D16;LATIN SMALL LETTER TOP HALF O;Ll;0;L;;;;;N;;;;;
+1D17;LATIN SMALL LETTER BOTTOM HALF O;Ll;0;L;;;;;N;;;;;
+1D18;LATIN LETTER SMALL CAPITAL P;Ll;0;L;;;;;N;;;;;
+1D19;LATIN LETTER SMALL CAPITAL REVERSED R;Ll;0;L;;;;;N;;;;;
+1D1A;LATIN LETTER SMALL CAPITAL TURNED R;Ll;0;L;;;;;N;;;;;
+1D1B;LATIN LETTER SMALL CAPITAL T;Ll;0;L;;;;;N;;;;;
+1D1C;LATIN LETTER SMALL CAPITAL U;Ll;0;L;;;;;N;;;;;
+1D1D;LATIN SMALL LETTER SIDEWAYS U;Ll;0;L;;;;;N;;;;;
+1D1E;LATIN SMALL LETTER SIDEWAYS DIAERESIZED U;Ll;0;L;;;;;N;;;;;
+1D1F;LATIN SMALL LETTER SIDEWAYS TURNED M;Ll;0;L;;;;;N;;;;;
+1D20;LATIN LETTER SMALL CAPITAL V;Ll;0;L;;;;;N;;;;;
+1D21;LATIN LETTER SMALL CAPITAL W;Ll;0;L;;;;;N;;;;;
+1D22;LATIN LETTER SMALL CAPITAL Z;Ll;0;L;;;;;N;;;;;
+1D23;LATIN LETTER SMALL CAPITAL EZH;Ll;0;L;;;;;N;;;;;
+1D24;LATIN LETTER VOICED LARYNGEAL SPIRANT;Ll;0;L;;;;;N;;;;;
+1D25;LATIN LETTER AIN;Ll;0;L;;;;;N;;;;;
+1D26;GREEK LETTER SMALL CAPITAL GAMMA;Ll;0;L;;;;;N;;;;;
+1D27;GREEK LETTER SMALL CAPITAL LAMDA;Ll;0;L;;;;;N;;;;;
+1D28;GREEK LETTER SMALL CAPITAL PI;Ll;0;L;;;;;N;;;;;
+1D29;GREEK LETTER SMALL CAPITAL RHO;Ll;0;L;;;;;N;;;;;
+1D2A;GREEK LETTER SMALL CAPITAL PSI;Ll;0;L;;;;;N;;;;;
+1D2B;CYRILLIC LETTER SMALL CAPITAL EL;Ll;0;L;;;;;N;;;;;
+1D2C;MODIFIER LETTER CAPITAL A;Lm;0;L;<super> 0041;;;;N;;;;;
+1D2D;MODIFIER LETTER CAPITAL AE;Lm;0;L;<super> 00C6;;;;N;;;;;
+1D2E;MODIFIER LETTER CAPITAL B;Lm;0;L;<super> 0042;;;;N;;;;;
+1D2F;MODIFIER LETTER CAPITAL BARRED B;Lm;0;L;;;;;N;;;;;
+1D30;MODIFIER LETTER CAPITAL D;Lm;0;L;<super> 0044;;;;N;;;;;
+1D31;MODIFIER LETTER CAPITAL E;Lm;0;L;<super> 0045;;;;N;;;;;
+1D32;MODIFIER LETTER CAPITAL REVERSED E;Lm;0;L;<super> 018E;;;;N;;;;;
+1D33;MODIFIER LETTER CAPITAL G;Lm;0;L;<super> 0047;;;;N;;;;;
+1D34;MODIFIER LETTER CAPITAL H;Lm;0;L;<super> 0048;;;;N;;;;;
+1D35;MODIFIER LETTER CAPITAL I;Lm;0;L;<super> 0049;;;;N;;;;;
+1D36;MODIFIER LETTER CAPITAL J;Lm;0;L;<super> 004A;;;;N;;;;;
+1D37;MODIFIER LETTER CAPITAL K;Lm;0;L;<super> 004B;;;;N;;;;;
+1D38;MODIFIER LETTER CAPITAL L;Lm;0;L;<super> 004C;;;;N;;;;;
+1D39;MODIFIER LETTER CAPITAL M;Lm;0;L;<super> 004D;;;;N;;;;;
+1D3A;MODIFIER LETTER CAPITAL N;Lm;0;L;<super> 004E;;;;N;;;;;
+1D3B;MODIFIER LETTER CAPITAL REVERSED N;Lm;0;L;;;;;N;;;;;
+1D3C;MODIFIER LETTER CAPITAL O;Lm;0;L;<super> 004F;;;;N;;;;;
+1D3D;MODIFIER LETTER CAPITAL OU;Lm;0;L;<super> 0222;;;;N;;;;;
+1D3E;MODIFIER LETTER CAPITAL P;Lm;0;L;<super> 0050;;;;N;;;;;
+1D3F;MODIFIER LETTER CAPITAL R;Lm;0;L;<super> 0052;;;;N;;;;;
+1D40;MODIFIER LETTER CAPITAL T;Lm;0;L;<super> 0054;;;;N;;;;;
+1D41;MODIFIER LETTER CAPITAL U;Lm;0;L;<super> 0055;;;;N;;;;;
+1D42;MODIFIER LETTER CAPITAL W;Lm;0;L;<super> 0057;;;;N;;;;;
+1D43;MODIFIER LETTER SMALL A;Lm;0;L;<super> 0061;;;;N;;;;;
+1D44;MODIFIER LETTER SMALL TURNED A;Lm;0;L;<super> 0250;;;;N;;;;;
+1D45;MODIFIER LETTER SMALL ALPHA;Lm;0;L;<super> 0251;;;;N;;;;;
+1D46;MODIFIER LETTER SMALL TURNED AE;Lm;0;L;<super> 1D02;;;;N;;;;;
+1D47;MODIFIER LETTER SMALL B;Lm;0;L;<super> 0062;;;;N;;;;;
+1D48;MODIFIER LETTER SMALL D;Lm;0;L;<super> 0064;;;;N;;;;;
+1D49;MODIFIER LETTER SMALL E;Lm;0;L;<super> 0065;;;;N;;;;;
+1D4A;MODIFIER LETTER SMALL SCHWA;Lm;0;L;<super> 0259;;;;N;;;;;
+1D4B;MODIFIER LETTER SMALL OPEN E;Lm;0;L;<super> 025B;;;;N;;;;;
+1D4C;MODIFIER LETTER SMALL TURNED OPEN E;Lm;0;L;<super> 025C;;;;N;;;;;
+1D4D;MODIFIER LETTER SMALL G;Lm;0;L;<super> 0067;;;;N;;;;;
+1D4E;MODIFIER LETTER SMALL TURNED I;Lm;0;L;;;;;N;;;;;
+1D4F;MODIFIER LETTER SMALL K;Lm;0;L;<super> 006B;;;;N;;;;;
+1D50;MODIFIER LETTER SMALL M;Lm;0;L;<super> 006D;;;;N;;;;;
+1D51;MODIFIER LETTER SMALL ENG;Lm;0;L;<super> 014B;;;;N;;;;;
+1D52;MODIFIER LETTER SMALL O;Lm;0;L;<super> 006F;;;;N;;;;;
+1D53;MODIFIER LETTER SMALL OPEN O;Lm;0;L;<super> 0254;;;;N;;;;;
+1D54;MODIFIER LETTER SMALL TOP HALF O;Lm;0;L;<super> 1D16;;;;N;;;;;
+1D55;MODIFIER LETTER SMALL BOTTOM HALF O;Lm;0;L;<super> 1D17;;;;N;;;;;
+1D56;MODIFIER LETTER SMALL P;Lm;0;L;<super> 0070;;;;N;;;;;
+1D57;MODIFIER LETTER SMALL T;Lm;0;L;<super> 0074;;;;N;;;;;
+1D58;MODIFIER LETTER SMALL U;Lm;0;L;<super> 0075;;;;N;;;;;
+1D59;MODIFIER LETTER SMALL SIDEWAYS U;Lm;0;L;<super> 1D1D;;;;N;;;;;
+1D5A;MODIFIER LETTER SMALL TURNED M;Lm;0;L;<super> 026F;;;;N;;;;;
+1D5B;MODIFIER LETTER SMALL V;Lm;0;L;<super> 0076;;;;N;;;;;
+1D5C;MODIFIER LETTER SMALL AIN;Lm;0;L;<super> 1D25;;;;N;;;;;
+1D5D;MODIFIER LETTER SMALL BETA;Lm;0;L;<super> 03B2;;;;N;;;;;
+1D5E;MODIFIER LETTER SMALL GREEK GAMMA;Lm;0;L;<super> 03B3;;;;N;;;;;
+1D5F;MODIFIER LETTER SMALL DELTA;Lm;0;L;<super> 03B4;;;;N;;;;;
+1D60;MODIFIER LETTER SMALL GREEK PHI;Lm;0;L;<super> 03C6;;;;N;;;;;
+1D61;MODIFIER LETTER SMALL CHI;Lm;0;L;<super> 03C7;;;;N;;;;;
+1D62;LATIN SUBSCRIPT SMALL LETTER I;Lm;0;L;<sub> 0069;;;;N;;;;;
+1D63;LATIN SUBSCRIPT SMALL LETTER R;Lm;0;L;<sub> 0072;;;;N;;;;;
+1D64;LATIN SUBSCRIPT SMALL LETTER U;Lm;0;L;<sub> 0075;;;;N;;;;;
+1D65;LATIN SUBSCRIPT SMALL LETTER V;Lm;0;L;<sub> 0076;;;;N;;;;;
+1D66;GREEK SUBSCRIPT SMALL LETTER BETA;Lm;0;L;<sub> 03B2;;;;N;;;;;
+1D67;GREEK SUBSCRIPT SMALL LETTER GAMMA;Lm;0;L;<sub> 03B3;;;;N;;;;;
+1D68;GREEK SUBSCRIPT SMALL LETTER RHO;Lm;0;L;<sub> 03C1;;;;N;;;;;
+1D69;GREEK SUBSCRIPT SMALL LETTER PHI;Lm;0;L;<sub> 03C6;;;;N;;;;;
+1D6A;GREEK SUBSCRIPT SMALL LETTER CHI;Lm;0;L;<sub> 03C7;;;;N;;;;;
+1D6B;LATIN SMALL LETTER UE;Ll;0;L;;;;;N;;;;;
+1D6C;LATIN SMALL LETTER B WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D6D;LATIN SMALL LETTER D WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D6E;LATIN SMALL LETTER F WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D6F;LATIN SMALL LETTER M WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D70;LATIN SMALL LETTER N WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D71;LATIN SMALL LETTER P WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D72;LATIN SMALL LETTER R WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D73;LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D74;LATIN SMALL LETTER S WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D75;LATIN SMALL LETTER T WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D76;LATIN SMALL LETTER Z WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+1D77;LATIN SMALL LETTER TURNED G;Ll;0;L;;;;;N;;;;;
+1D78;MODIFIER LETTER CYRILLIC EN;Lm;0;L;<super> 043D;;;;N;;;;;
+1D79;LATIN SMALL LETTER INSULAR G;Ll;0;L;;;;;N;;;A77D;;A77D
+1D7A;LATIN SMALL LETTER TH WITH STRIKETHROUGH;Ll;0;L;;;;;N;;;;;
+1D7B;LATIN SMALL CAPITAL LETTER I WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D7C;LATIN SMALL LETTER IOTA WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D7D;LATIN SMALL LETTER P WITH STROKE;Ll;0;L;;;;;N;;;2C63;;2C63
+1D7E;LATIN SMALL CAPITAL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D7F;LATIN SMALL LETTER UPSILON WITH STROKE;Ll;0;L;;;;;N;;;;;
+1D80;LATIN SMALL LETTER B WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D81;LATIN SMALL LETTER D WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D82;LATIN SMALL LETTER F WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D83;LATIN SMALL LETTER G WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D84;LATIN SMALL LETTER K WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D85;LATIN SMALL LETTER L WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D86;LATIN SMALL LETTER M WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D87;LATIN SMALL LETTER N WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D88;LATIN SMALL LETTER P WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D89;LATIN SMALL LETTER R WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8A;LATIN SMALL LETTER S WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8B;LATIN SMALL LETTER ESH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8C;LATIN SMALL LETTER V WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8D;LATIN SMALL LETTER X WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8F;LATIN SMALL LETTER A WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D90;LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D91;LATIN SMALL LETTER D WITH HOOK AND TAIL;Ll;0;L;;;;;N;;;;;
+1D92;LATIN SMALL LETTER E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D93;LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D94;LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D95;LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D96;LATIN SMALL LETTER I WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D97;LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D98;LATIN SMALL LETTER ESH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D99;LATIN SMALL LETTER U WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D9A;LATIN SMALL LETTER EZH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+1D9B;MODIFIER LETTER SMALL TURNED ALPHA;Lm;0;L;<super> 0252;;;;N;;;;;
+1D9C;MODIFIER LETTER SMALL C;Lm;0;L;<super> 0063;;;;N;;;;;
+1D9D;MODIFIER LETTER SMALL C WITH CURL;Lm;0;L;<super> 0255;;;;N;;;;;
+1D9E;MODIFIER LETTER SMALL ETH;Lm;0;L;<super> 00F0;;;;N;;;;;
+1D9F;MODIFIER LETTER SMALL REVERSED OPEN E;Lm;0;L;<super> 025C;;;;N;;;;;
+1DA0;MODIFIER LETTER SMALL F;Lm;0;L;<super> 0066;;;;N;;;;;
+1DA1;MODIFIER LETTER SMALL DOTLESS J WITH STROKE;Lm;0;L;<super> 025F;;;;N;;;;;
+1DA2;MODIFIER LETTER SMALL SCRIPT G;Lm;0;L;<super> 0261;;;;N;;;;;
+1DA3;MODIFIER LETTER SMALL TURNED H;Lm;0;L;<super> 0265;;;;N;;;;;
+1DA4;MODIFIER LETTER SMALL I WITH STROKE;Lm;0;L;<super> 0268;;;;N;;;;;
+1DA5;MODIFIER LETTER SMALL IOTA;Lm;0;L;<super> 0269;;;;N;;;;;
+1DA6;MODIFIER LETTER SMALL CAPITAL I;Lm;0;L;<super> 026A;;;;N;;;;;
+1DA7;MODIFIER LETTER SMALL CAPITAL I WITH STROKE;Lm;0;L;<super> 1D7B;;;;N;;;;;
+1DA8;MODIFIER LETTER SMALL J WITH CROSSED-TAIL;Lm;0;L;<super> 029D;;;;N;;;;;
+1DA9;MODIFIER LETTER SMALL L WITH RETROFLEX HOOK;Lm;0;L;<super> 026D;;;;N;;;;;
+1DAA;MODIFIER LETTER SMALL L WITH PALATAL HOOK;Lm;0;L;<super> 1D85;;;;N;;;;;
+1DAB;MODIFIER LETTER SMALL CAPITAL L;Lm;0;L;<super> 029F;;;;N;;;;;
+1DAC;MODIFIER LETTER SMALL M WITH HOOK;Lm;0;L;<super> 0271;;;;N;;;;;
+1DAD;MODIFIER LETTER SMALL TURNED M WITH LONG LEG;Lm;0;L;<super> 0270;;;;N;;;;;
+1DAE;MODIFIER LETTER SMALL N WITH LEFT HOOK;Lm;0;L;<super> 0272;;;;N;;;;;
+1DAF;MODIFIER LETTER SMALL N WITH RETROFLEX HOOK;Lm;0;L;<super> 0273;;;;N;;;;;
+1DB0;MODIFIER LETTER SMALL CAPITAL N;Lm;0;L;<super> 0274;;;;N;;;;;
+1DB1;MODIFIER LETTER SMALL BARRED O;Lm;0;L;<super> 0275;;;;N;;;;;
+1DB2;MODIFIER LETTER SMALL PHI;Lm;0;L;<super> 0278;;;;N;;;;;
+1DB3;MODIFIER LETTER SMALL S WITH HOOK;Lm;0;L;<super> 0282;;;;N;;;;;
+1DB4;MODIFIER LETTER SMALL ESH;Lm;0;L;<super> 0283;;;;N;;;;;
+1DB5;MODIFIER LETTER SMALL T WITH PALATAL HOOK;Lm;0;L;<super> 01AB;;;;N;;;;;
+1DB6;MODIFIER LETTER SMALL U BAR;Lm;0;L;<super> 0289;;;;N;;;;;
+1DB7;MODIFIER LETTER SMALL UPSILON;Lm;0;L;<super> 028A;;;;N;;;;;
+1DB8;MODIFIER LETTER SMALL CAPITAL U;Lm;0;L;<super> 1D1C;;;;N;;;;;
+1DB9;MODIFIER LETTER SMALL V WITH HOOK;Lm;0;L;<super> 028B;;;;N;;;;;
+1DBA;MODIFIER LETTER SMALL TURNED V;Lm;0;L;<super> 028C;;;;N;;;;;
+1DBB;MODIFIER LETTER SMALL Z;Lm;0;L;<super> 007A;;;;N;;;;;
+1DBC;MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK;Lm;0;L;<super> 0290;;;;N;;;;;
+1DBD;MODIFIER LETTER SMALL Z WITH CURL;Lm;0;L;<super> 0291;;;;N;;;;;
+1DBE;MODIFIER LETTER SMALL EZH;Lm;0;L;<super> 0292;;;;N;;;;;
+1DBF;MODIFIER LETTER SMALL THETA;Lm;0;L;<super> 03B8;;;;N;;;;;
+1DC0;COMBINING DOTTED GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;;
+1DC1;COMBINING DOTTED ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;
+1DC2;COMBINING SNAKE BELOW;Mn;220;NSM;;;;;N;;;;;
+1DC3;COMBINING SUSPENSION MARK;Mn;230;NSM;;;;;N;;;;;
+1DC4;COMBINING MACRON-ACUTE;Mn;230;NSM;;;;;N;;;;;
+1DC5;COMBINING GRAVE-MACRON;Mn;230;NSM;;;;;N;;;;;
+1DC6;COMBINING MACRON-GRAVE;Mn;230;NSM;;;;;N;;;;;
+1DC7;COMBINING ACUTE-MACRON;Mn;230;NSM;;;;;N;;;;;
+1DC8;COMBINING GRAVE-ACUTE-GRAVE;Mn;230;NSM;;;;;N;;;;;
+1DC9;COMBINING ACUTE-GRAVE-ACUTE;Mn;230;NSM;;;;;N;;;;;
+1DCA;COMBINING LATIN SMALL LETTER R BELOW;Mn;220;NSM;;;;;N;;;;;
+1DCB;COMBINING BREVE-MACRON;Mn;230;NSM;;;;;N;;;;;
+1DCC;COMBINING MACRON-BREVE;Mn;230;NSM;;;;;N;;;;;
+1DCD;COMBINING DOUBLE CIRCUMFLEX ABOVE;Mn;234;NSM;;;;;N;;;;;
+1DCE;COMBINING OGONEK ABOVE;Mn;214;NSM;;;;;N;;;;;
+1DCF;COMBINING ZIGZAG BELOW;Mn;220;NSM;;;;;N;;;;;
+1DD0;COMBINING IS BELOW;Mn;202;NSM;;;;;N;;;;;
+1DD1;COMBINING UR ABOVE;Mn;230;NSM;;;;;N;;;;;
+1DD2;COMBINING US ABOVE;Mn;230;NSM;;;;;N;;;;;
+1DD3;COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE;Mn;230;NSM;;;;;N;;;;;
+1DD4;COMBINING LATIN SMALL LETTER AE;Mn;230;NSM;;;;;N;;;;;
+1DD5;COMBINING LATIN SMALL LETTER AO;Mn;230;NSM;;;;;N;;;;;
+1DD6;COMBINING LATIN SMALL LETTER AV;Mn;230;NSM;;;;;N;;;;;
+1DD7;COMBINING LATIN SMALL LETTER C CEDILLA;Mn;230;NSM;;;;;N;;;;;
+1DD8;COMBINING LATIN SMALL LETTER INSULAR D;Mn;230;NSM;;;;;N;;;;;
+1DD9;COMBINING LATIN SMALL LETTER ETH;Mn;230;NSM;;;;;N;;;;;
+1DDA;COMBINING LATIN SMALL LETTER G;Mn;230;NSM;;;;;N;;;;;
+1DDB;COMBINING LATIN LETTER SMALL CAPITAL G;Mn;230;NSM;;;;;N;;;;;
+1DDC;COMBINING LATIN SMALL LETTER K;Mn;230;NSM;;;;;N;;;;;
+1DDD;COMBINING LATIN SMALL LETTER L;Mn;230;NSM;;;;;N;;;;;
+1DDE;COMBINING LATIN LETTER SMALL CAPITAL L;Mn;230;NSM;;;;;N;;;;;
+1DDF;COMBINING LATIN LETTER SMALL CAPITAL M;Mn;230;NSM;;;;;N;;;;;
+1DE0;COMBINING LATIN SMALL LETTER N;Mn;230;NSM;;;;;N;;;;;
+1DE1;COMBINING LATIN LETTER SMALL CAPITAL N;Mn;230;NSM;;;;;N;;;;;
+1DE2;COMBINING LATIN LETTER SMALL CAPITAL R;Mn;230;NSM;;;;;N;;;;;
+1DE3;COMBINING LATIN SMALL LETTER R ROTUNDA;Mn;230;NSM;;;;;N;;;;;
+1DE4;COMBINING LATIN SMALL LETTER S;Mn;230;NSM;;;;;N;;;;;
+1DE5;COMBINING LATIN SMALL LETTER LONG S;Mn;230;NSM;;;;;N;;;;;
+1DE6;COMBINING LATIN SMALL LETTER Z;Mn;230;NSM;;;;;N;;;;;
+1DE7;COMBINING LATIN SMALL LETTER ALPHA;Mn;230;NSM;;;;;N;;;;;
+1DE8;COMBINING LATIN SMALL LETTER B;Mn;230;NSM;;;;;N;;;;;
+1DE9;COMBINING LATIN SMALL LETTER BETA;Mn;230;NSM;;;;;N;;;;;
+1DEA;COMBINING LATIN SMALL LETTER SCHWA;Mn;230;NSM;;;;;N;;;;;
+1DEB;COMBINING LATIN SMALL LETTER F;Mn;230;NSM;;;;;N;;;;;
+1DEC;COMBINING LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE;Mn;230;NSM;;;;;N;;;;;
+1DED;COMBINING LATIN SMALL LETTER O WITH LIGHT CENTRALIZATION STROKE;Mn;230;NSM;;;;;N;;;;;
+1DEE;COMBINING LATIN SMALL LETTER P;Mn;230;NSM;;;;;N;;;;;
+1DEF;COMBINING LATIN SMALL LETTER ESH;Mn;230;NSM;;;;;N;;;;;
+1DF0;COMBINING LATIN SMALL LETTER U WITH LIGHT CENTRALIZATION STROKE;Mn;230;NSM;;;;;N;;;;;
+1DF1;COMBINING LATIN SMALL LETTER W;Mn;230;NSM;;;;;N;;;;;
+1DF2;COMBINING LATIN SMALL LETTER A WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;;
+1DF3;COMBINING LATIN SMALL LETTER O WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;;
+1DF4;COMBINING LATIN SMALL LETTER U WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;;
+1DF5;COMBINING UP TACK ABOVE;Mn;230;NSM;;;;;N;;;;;
+1DFB;COMBINING DELETION MARK;Mn;230;NSM;;;;;N;;;;;
+1DFC;COMBINING DOUBLE INVERTED BREVE BELOW;Mn;233;NSM;;;;;N;;;;;
+1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;;
+1DFE;COMBINING LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
+1DFF;COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
+1E00;LATIN CAPITAL LETTER A WITH RING BELOW;Lu;0;L;0041 0325;;;;N;;;;1E01;
+1E01;LATIN SMALL LETTER A WITH RING BELOW;Ll;0;L;0061 0325;;;;N;;;1E00;;1E00
+1E02;LATIN CAPITAL LETTER B WITH DOT ABOVE;Lu;0;L;0042 0307;;;;N;;;;1E03;
+1E03;LATIN SMALL LETTER B WITH DOT ABOVE;Ll;0;L;0062 0307;;;;N;;;1E02;;1E02
+1E04;LATIN CAPITAL LETTER B WITH DOT BELOW;Lu;0;L;0042 0323;;;;N;;;;1E05;
+1E05;LATIN SMALL LETTER B WITH DOT BELOW;Ll;0;L;0062 0323;;;;N;;;1E04;;1E04
+1E06;LATIN CAPITAL LETTER B WITH LINE BELOW;Lu;0;L;0042 0331;;;;N;;;;1E07;
+1E07;LATIN SMALL LETTER B WITH LINE BELOW;Ll;0;L;0062 0331;;;;N;;;1E06;;1E06
+1E08;LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE;Lu;0;L;00C7 0301;;;;N;;;;1E09;
+1E09;LATIN SMALL LETTER C WITH CEDILLA AND ACUTE;Ll;0;L;00E7 0301;;;;N;;;1E08;;1E08
+1E0A;LATIN CAPITAL LETTER D WITH DOT ABOVE;Lu;0;L;0044 0307;;;;N;;;;1E0B;
+1E0B;LATIN SMALL LETTER D WITH DOT ABOVE;Ll;0;L;0064 0307;;;;N;;;1E0A;;1E0A
+1E0C;LATIN CAPITAL LETTER D WITH DOT BELOW;Lu;0;L;0044 0323;;;;N;;;;1E0D;
+1E0D;LATIN SMALL LETTER D WITH DOT BELOW;Ll;0;L;0064 0323;;;;N;;;1E0C;;1E0C
+1E0E;LATIN CAPITAL LETTER D WITH LINE BELOW;Lu;0;L;0044 0331;;;;N;;;;1E0F;
+1E0F;LATIN SMALL LETTER D WITH LINE BELOW;Ll;0;L;0064 0331;;;;N;;;1E0E;;1E0E
+1E10;LATIN CAPITAL LETTER D WITH CEDILLA;Lu;0;L;0044 0327;;;;N;;;;1E11;
+1E11;LATIN SMALL LETTER D WITH CEDILLA;Ll;0;L;0064 0327;;;;N;;;1E10;;1E10
+1E12;LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW;Lu;0;L;0044 032D;;;;N;;;;1E13;
+1E13;LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW;Ll;0;L;0064 032D;;;;N;;;1E12;;1E12
+1E14;LATIN CAPITAL LETTER E WITH MACRON AND GRAVE;Lu;0;L;0112 0300;;;;N;;;;1E15;
+1E15;LATIN SMALL LETTER E WITH MACRON AND GRAVE;Ll;0;L;0113 0300;;;;N;;;1E14;;1E14
+1E16;LATIN CAPITAL LETTER E WITH MACRON AND ACUTE;Lu;0;L;0112 0301;;;;N;;;;1E17;
+1E17;LATIN SMALL LETTER E WITH MACRON AND ACUTE;Ll;0;L;0113 0301;;;;N;;;1E16;;1E16
+1E18;LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW;Lu;0;L;0045 032D;;;;N;;;;1E19;
+1E19;LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW;Ll;0;L;0065 032D;;;;N;;;1E18;;1E18
+1E1A;LATIN CAPITAL LETTER E WITH TILDE BELOW;Lu;0;L;0045 0330;;;;N;;;;1E1B;
+1E1B;LATIN SMALL LETTER E WITH TILDE BELOW;Ll;0;L;0065 0330;;;;N;;;1E1A;;1E1A
+1E1C;LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE;Lu;0;L;0228 0306;;;;N;;;;1E1D;
+1E1D;LATIN SMALL LETTER E WITH CEDILLA AND BREVE;Ll;0;L;0229 0306;;;;N;;;1E1C;;1E1C
+1E1E;LATIN CAPITAL LETTER F WITH DOT ABOVE;Lu;0;L;0046 0307;;;;N;;;;1E1F;
+1E1F;LATIN SMALL LETTER F WITH DOT ABOVE;Ll;0;L;0066 0307;;;;N;;;1E1E;;1E1E
+1E20;LATIN CAPITAL LETTER G WITH MACRON;Lu;0;L;0047 0304;;;;N;;;;1E21;
+1E21;LATIN SMALL LETTER G WITH MACRON;Ll;0;L;0067 0304;;;;N;;;1E20;;1E20
+1E22;LATIN CAPITAL LETTER H WITH DOT ABOVE;Lu;0;L;0048 0307;;;;N;;;;1E23;
+1E23;LATIN SMALL LETTER H WITH DOT ABOVE;Ll;0;L;0068 0307;;;;N;;;1E22;;1E22
+1E24;LATIN CAPITAL LETTER H WITH DOT BELOW;Lu;0;L;0048 0323;;;;N;;;;1E25;
+1E25;LATIN SMALL LETTER H WITH DOT BELOW;Ll;0;L;0068 0323;;;;N;;;1E24;;1E24
+1E26;LATIN CAPITAL LETTER H WITH DIAERESIS;Lu;0;L;0048 0308;;;;N;;;;1E27;
+1E27;LATIN SMALL LETTER H WITH DIAERESIS;Ll;0;L;0068 0308;;;;N;;;1E26;;1E26
+1E28;LATIN CAPITAL LETTER H WITH CEDILLA;Lu;0;L;0048 0327;;;;N;;;;1E29;
+1E29;LATIN SMALL LETTER H WITH CEDILLA;Ll;0;L;0068 0327;;;;N;;;1E28;;1E28
+1E2A;LATIN CAPITAL LETTER H WITH BREVE BELOW;Lu;0;L;0048 032E;;;;N;;;;1E2B;
+1E2B;LATIN SMALL LETTER H WITH BREVE BELOW;Ll;0;L;0068 032E;;;;N;;;1E2A;;1E2A
+1E2C;LATIN CAPITAL LETTER I WITH TILDE BELOW;Lu;0;L;0049 0330;;;;N;;;;1E2D;
+1E2D;LATIN SMALL LETTER I WITH TILDE BELOW;Ll;0;L;0069 0330;;;;N;;;1E2C;;1E2C
+1E2E;LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE;Lu;0;L;00CF 0301;;;;N;;;;1E2F;
+1E2F;LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE;Ll;0;L;00EF 0301;;;;N;;;1E2E;;1E2E
+1E30;LATIN CAPITAL LETTER K WITH ACUTE;Lu;0;L;004B 0301;;;;N;;;;1E31;
+1E31;LATIN SMALL LETTER K WITH ACUTE;Ll;0;L;006B 0301;;;;N;;;1E30;;1E30
+1E32;LATIN CAPITAL LETTER K WITH DOT BELOW;Lu;0;L;004B 0323;;;;N;;;;1E33;
+1E33;LATIN SMALL LETTER K WITH DOT BELOW;Ll;0;L;006B 0323;;;;N;;;1E32;;1E32
+1E34;LATIN CAPITAL LETTER K WITH LINE BELOW;Lu;0;L;004B 0331;;;;N;;;;1E35;
+1E35;LATIN SMALL LETTER K WITH LINE BELOW;Ll;0;L;006B 0331;;;;N;;;1E34;;1E34
+1E36;LATIN CAPITAL LETTER L WITH DOT BELOW;Lu;0;L;004C 0323;;;;N;;;;1E37;
+1E37;LATIN SMALL LETTER L WITH DOT BELOW;Ll;0;L;006C 0323;;;;N;;;1E36;;1E36
+1E38;LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON;Lu;0;L;1E36 0304;;;;N;;;;1E39;
+1E39;LATIN SMALL LETTER L WITH DOT BELOW AND MACRON;Ll;0;L;1E37 0304;;;;N;;;1E38;;1E38
+1E3A;LATIN CAPITAL LETTER L WITH LINE BELOW;Lu;0;L;004C 0331;;;;N;;;;1E3B;
+1E3B;LATIN SMALL LETTER L WITH LINE BELOW;Ll;0;L;006C 0331;;;;N;;;1E3A;;1E3A
+1E3C;LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW;Lu;0;L;004C 032D;;;;N;;;;1E3D;
+1E3D;LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW;Ll;0;L;006C 032D;;;;N;;;1E3C;;1E3C
+1E3E;LATIN CAPITAL LETTER M WITH ACUTE;Lu;0;L;004D 0301;;;;N;;;;1E3F;
+1E3F;LATIN SMALL LETTER M WITH ACUTE;Ll;0;L;006D 0301;;;;N;;;1E3E;;1E3E
+1E40;LATIN CAPITAL LETTER M WITH DOT ABOVE;Lu;0;L;004D 0307;;;;N;;;;1E41;
+1E41;LATIN SMALL LETTER M WITH DOT ABOVE;Ll;0;L;006D 0307;;;;N;;;1E40;;1E40
+1E42;LATIN CAPITAL LETTER M WITH DOT BELOW;Lu;0;L;004D 0323;;;;N;;;;1E43;
+1E43;LATIN SMALL LETTER M WITH DOT BELOW;Ll;0;L;006D 0323;;;;N;;;1E42;;1E42
+1E44;LATIN CAPITAL LETTER N WITH DOT ABOVE;Lu;0;L;004E 0307;;;;N;;;;1E45;
+1E45;LATIN SMALL LETTER N WITH DOT ABOVE;Ll;0;L;006E 0307;;;;N;;;1E44;;1E44
+1E46;LATIN CAPITAL LETTER N WITH DOT BELOW;Lu;0;L;004E 0323;;;;N;;;;1E47;
+1E47;LATIN SMALL LETTER N WITH DOT BELOW;Ll;0;L;006E 0323;;;;N;;;1E46;;1E46
+1E48;LATIN CAPITAL LETTER N WITH LINE BELOW;Lu;0;L;004E 0331;;;;N;;;;1E49;
+1E49;LATIN SMALL LETTER N WITH LINE BELOW;Ll;0;L;006E 0331;;;;N;;;1E48;;1E48
+1E4A;LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW;Lu;0;L;004E 032D;;;;N;;;;1E4B;
+1E4B;LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW;Ll;0;L;006E 032D;;;;N;;;1E4A;;1E4A
+1E4C;LATIN CAPITAL LETTER O WITH TILDE AND ACUTE;Lu;0;L;00D5 0301;;;;N;;;;1E4D;
+1E4D;LATIN SMALL LETTER O WITH TILDE AND ACUTE;Ll;0;L;00F5 0301;;;;N;;;1E4C;;1E4C
+1E4E;LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS;Lu;0;L;00D5 0308;;;;N;;;;1E4F;
+1E4F;LATIN SMALL LETTER O WITH TILDE AND DIAERESIS;Ll;0;L;00F5 0308;;;;N;;;1E4E;;1E4E
+1E50;LATIN CAPITAL LETTER O WITH MACRON AND GRAVE;Lu;0;L;014C 0300;;;;N;;;;1E51;
+1E51;LATIN SMALL LETTER O WITH MACRON AND GRAVE;Ll;0;L;014D 0300;;;;N;;;1E50;;1E50
+1E52;LATIN CAPITAL LETTER O WITH MACRON AND ACUTE;Lu;0;L;014C 0301;;;;N;;;;1E53;
+1E53;LATIN SMALL LETTER O WITH MACRON AND ACUTE;Ll;0;L;014D 0301;;;;N;;;1E52;;1E52
+1E54;LATIN CAPITAL LETTER P WITH ACUTE;Lu;0;L;0050 0301;;;;N;;;;1E55;
+1E55;LATIN SMALL LETTER P WITH ACUTE;Ll;0;L;0070 0301;;;;N;;;1E54;;1E54
+1E56;LATIN CAPITAL LETTER P WITH DOT ABOVE;Lu;0;L;0050 0307;;;;N;;;;1E57;
+1E57;LATIN SMALL LETTER P WITH DOT ABOVE;Ll;0;L;0070 0307;;;;N;;;1E56;;1E56
+1E58;LATIN CAPITAL LETTER R WITH DOT ABOVE;Lu;0;L;0052 0307;;;;N;;;;1E59;
+1E59;LATIN SMALL LETTER R WITH DOT ABOVE;Ll;0;L;0072 0307;;;;N;;;1E58;;1E58
+1E5A;LATIN CAPITAL LETTER R WITH DOT BELOW;Lu;0;L;0052 0323;;;;N;;;;1E5B;
+1E5B;LATIN SMALL LETTER R WITH DOT BELOW;Ll;0;L;0072 0323;;;;N;;;1E5A;;1E5A
+1E5C;LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON;Lu;0;L;1E5A 0304;;;;N;;;;1E5D;
+1E5D;LATIN SMALL LETTER R WITH DOT BELOW AND MACRON;Ll;0;L;1E5B 0304;;;;N;;;1E5C;;1E5C
+1E5E;LATIN CAPITAL LETTER R WITH LINE BELOW;Lu;0;L;0052 0331;;;;N;;;;1E5F;
+1E5F;LATIN SMALL LETTER R WITH LINE BELOW;Ll;0;L;0072 0331;;;;N;;;1E5E;;1E5E
+1E60;LATIN CAPITAL LETTER S WITH DOT ABOVE;Lu;0;L;0053 0307;;;;N;;;;1E61;
+1E61;LATIN SMALL LETTER S WITH DOT ABOVE;Ll;0;L;0073 0307;;;;N;;;1E60;;1E60
+1E62;LATIN CAPITAL LETTER S WITH DOT BELOW;Lu;0;L;0053 0323;;;;N;;;;1E63;
+1E63;LATIN SMALL LETTER S WITH DOT BELOW;Ll;0;L;0073 0323;;;;N;;;1E62;;1E62
+1E64;LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE;Lu;0;L;015A 0307;;;;N;;;;1E65;
+1E65;LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE;Ll;0;L;015B 0307;;;;N;;;1E64;;1E64
+1E66;LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE;Lu;0;L;0160 0307;;;;N;;;;1E67;
+1E67;LATIN SMALL LETTER S WITH CARON AND DOT ABOVE;Ll;0;L;0161 0307;;;;N;;;1E66;;1E66
+1E68;LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE;Lu;0;L;1E62 0307;;;;N;;;;1E69;
+1E69;LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE;Ll;0;L;1E63 0307;;;;N;;;1E68;;1E68
+1E6A;LATIN CAPITAL LETTER T WITH DOT ABOVE;Lu;0;L;0054 0307;;;;N;;;;1E6B;
+1E6B;LATIN SMALL LETTER T WITH DOT ABOVE;Ll;0;L;0074 0307;;;;N;;;1E6A;;1E6A
+1E6C;LATIN CAPITAL LETTER T WITH DOT BELOW;Lu;0;L;0054 0323;;;;N;;;;1E6D;
+1E6D;LATIN SMALL LETTER T WITH DOT BELOW;Ll;0;L;0074 0323;;;;N;;;1E6C;;1E6C
+1E6E;LATIN CAPITAL LETTER T WITH LINE BELOW;Lu;0;L;0054 0331;;;;N;;;;1E6F;
+1E6F;LATIN SMALL LETTER T WITH LINE BELOW;Ll;0;L;0074 0331;;;;N;;;1E6E;;1E6E
+1E70;LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW;Lu;0;L;0054 032D;;;;N;;;;1E71;
+1E71;LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW;Ll;0;L;0074 032D;;;;N;;;1E70;;1E70
+1E72;LATIN CAPITAL LETTER U WITH DIAERESIS BELOW;Lu;0;L;0055 0324;;;;N;;;;1E73;
+1E73;LATIN SMALL LETTER U WITH DIAERESIS BELOW;Ll;0;L;0075 0324;;;;N;;;1E72;;1E72
+1E74;LATIN CAPITAL LETTER U WITH TILDE BELOW;Lu;0;L;0055 0330;;;;N;;;;1E75;
+1E75;LATIN SMALL LETTER U WITH TILDE BELOW;Ll;0;L;0075 0330;;;;N;;;1E74;;1E74
+1E76;LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW;Lu;0;L;0055 032D;;;;N;;;;1E77;
+1E77;LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW;Ll;0;L;0075 032D;;;;N;;;1E76;;1E76
+1E78;LATIN CAPITAL LETTER U WITH TILDE AND ACUTE;Lu;0;L;0168 0301;;;;N;;;;1E79;
+1E79;LATIN SMALL LETTER U WITH TILDE AND ACUTE;Ll;0;L;0169 0301;;;;N;;;1E78;;1E78
+1E7A;LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS;Lu;0;L;016A 0308;;;;N;;;;1E7B;
+1E7B;LATIN SMALL LETTER U WITH MACRON AND DIAERESIS;Ll;0;L;016B 0308;;;;N;;;1E7A;;1E7A
+1E7C;LATIN CAPITAL LETTER V WITH TILDE;Lu;0;L;0056 0303;;;;N;;;;1E7D;
+1E7D;LATIN SMALL LETTER V WITH TILDE;Ll;0;L;0076 0303;;;;N;;;1E7C;;1E7C
+1E7E;LATIN CAPITAL LETTER V WITH DOT BELOW;Lu;0;L;0056 0323;;;;N;;;;1E7F;
+1E7F;LATIN SMALL LETTER V WITH DOT BELOW;Ll;0;L;0076 0323;;;;N;;;1E7E;;1E7E
+1E80;LATIN CAPITAL LETTER W WITH GRAVE;Lu;0;L;0057 0300;;;;N;;;;1E81;
+1E81;LATIN SMALL LETTER W WITH GRAVE;Ll;0;L;0077 0300;;;;N;;;1E80;;1E80
+1E82;LATIN CAPITAL LETTER W WITH ACUTE;Lu;0;L;0057 0301;;;;N;;;;1E83;
+1E83;LATIN SMALL LETTER W WITH ACUTE;Ll;0;L;0077 0301;;;;N;;;1E82;;1E82
+1E84;LATIN CAPITAL LETTER W WITH DIAERESIS;Lu;0;L;0057 0308;;;;N;;;;1E85;
+1E85;LATIN SMALL LETTER W WITH DIAERESIS;Ll;0;L;0077 0308;;;;N;;;1E84;;1E84
+1E86;LATIN CAPITAL LETTER W WITH DOT ABOVE;Lu;0;L;0057 0307;;;;N;;;;1E87;
+1E87;LATIN SMALL LETTER W WITH DOT ABOVE;Ll;0;L;0077 0307;;;;N;;;1E86;;1E86
+1E88;LATIN CAPITAL LETTER W WITH DOT BELOW;Lu;0;L;0057 0323;;;;N;;;;1E89;
+1E89;LATIN SMALL LETTER W WITH DOT BELOW;Ll;0;L;0077 0323;;;;N;;;1E88;;1E88
+1E8A;LATIN CAPITAL LETTER X WITH DOT ABOVE;Lu;0;L;0058 0307;;;;N;;;;1E8B;
+1E8B;LATIN SMALL LETTER X WITH DOT ABOVE;Ll;0;L;0078 0307;;;;N;;;1E8A;;1E8A
+1E8C;LATIN CAPITAL LETTER X WITH DIAERESIS;Lu;0;L;0058 0308;;;;N;;;;1E8D;
+1E8D;LATIN SMALL LETTER X WITH DIAERESIS;Ll;0;L;0078 0308;;;;N;;;1E8C;;1E8C
+1E8E;LATIN CAPITAL LETTER Y WITH DOT ABOVE;Lu;0;L;0059 0307;;;;N;;;;1E8F;
+1E8F;LATIN SMALL LETTER Y WITH DOT ABOVE;Ll;0;L;0079 0307;;;;N;;;1E8E;;1E8E
+1E90;LATIN CAPITAL LETTER Z WITH CIRCUMFLEX;Lu;0;L;005A 0302;;;;N;;;;1E91;
+1E91;LATIN SMALL LETTER Z WITH CIRCUMFLEX;Ll;0;L;007A 0302;;;;N;;;1E90;;1E90
+1E92;LATIN CAPITAL LETTER Z WITH DOT BELOW;Lu;0;L;005A 0323;;;;N;;;;1E93;
+1E93;LATIN SMALL LETTER Z WITH DOT BELOW;Ll;0;L;007A 0323;;;;N;;;1E92;;1E92
+1E94;LATIN CAPITAL LETTER Z WITH LINE BELOW;Lu;0;L;005A 0331;;;;N;;;;1E95;
+1E95;LATIN SMALL LETTER Z WITH LINE BELOW;Ll;0;L;007A 0331;;;;N;;;1E94;;1E94
+1E96;LATIN SMALL LETTER H WITH LINE BELOW;Ll;0;L;0068 0331;;;;N;;;;;
+1E97;LATIN SMALL LETTER T WITH DIAERESIS;Ll;0;L;0074 0308;;;;N;;;;;
+1E98;LATIN SMALL LETTER W WITH RING ABOVE;Ll;0;L;0077 030A;;;;N;;;;;
+1E99;LATIN SMALL LETTER Y WITH RING ABOVE;Ll;0;L;0079 030A;;;;N;;;;;
+1E9A;LATIN SMALL LETTER A WITH RIGHT HALF RING;Ll;0;L;<compat> 0061 02BE;;;;N;;;;;
+1E9B;LATIN SMALL LETTER LONG S WITH DOT ABOVE;Ll;0;L;017F 0307;;;;N;;;1E60;;1E60
+1E9C;LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;;;
+1E9D;LATIN SMALL LETTER LONG S WITH HIGH STROKE;Ll;0;L;;;;;N;;;;;
+1E9E;LATIN CAPITAL LETTER SHARP S;Lu;0;L;;;;;N;;;;00DF;
+1E9F;LATIN SMALL LETTER DELTA;Ll;0;L;;;;;N;;;;;
+1EA0;LATIN CAPITAL LETTER A WITH DOT BELOW;Lu;0;L;0041 0323;;;;N;;;;1EA1;
+1EA1;LATIN SMALL LETTER A WITH DOT BELOW;Ll;0;L;0061 0323;;;;N;;;1EA0;;1EA0
+1EA2;LATIN CAPITAL LETTER A WITH HOOK ABOVE;Lu;0;L;0041 0309;;;;N;;;;1EA3;
+1EA3;LATIN SMALL LETTER A WITH HOOK ABOVE;Ll;0;L;0061 0309;;;;N;;;1EA2;;1EA2
+1EA4;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00C2 0301;;;;N;;;;1EA5;
+1EA5;LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00E2 0301;;;;N;;;1EA4;;1EA4
+1EA6;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00C2 0300;;;;N;;;;1EA7;
+1EA7;LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00E2 0300;;;;N;;;1EA6;;1EA6
+1EA8;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00C2 0309;;;;N;;;;1EA9;
+1EA9;LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00E2 0309;;;;N;;;1EA8;;1EA8
+1EAA;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE;Lu;0;L;00C2 0303;;;;N;;;;1EAB;
+1EAB;LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE;Ll;0;L;00E2 0303;;;;N;;;1EAA;;1EAA
+1EAC;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EA0 0302;;;;N;;;;1EAD;
+1EAD;LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EA1 0302;;;;N;;;1EAC;;1EAC
+1EAE;LATIN CAPITAL LETTER A WITH BREVE AND ACUTE;Lu;0;L;0102 0301;;;;N;;;;1EAF;
+1EAF;LATIN SMALL LETTER A WITH BREVE AND ACUTE;Ll;0;L;0103 0301;;;;N;;;1EAE;;1EAE
+1EB0;LATIN CAPITAL LETTER A WITH BREVE AND GRAVE;Lu;0;L;0102 0300;;;;N;;;;1EB1;
+1EB1;LATIN SMALL LETTER A WITH BREVE AND GRAVE;Ll;0;L;0103 0300;;;;N;;;1EB0;;1EB0
+1EB2;LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE;Lu;0;L;0102 0309;;;;N;;;;1EB3;
+1EB3;LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE;Ll;0;L;0103 0309;;;;N;;;1EB2;;1EB2
+1EB4;LATIN CAPITAL LETTER A WITH BREVE AND TILDE;Lu;0;L;0102 0303;;;;N;;;;1EB5;
+1EB5;LATIN SMALL LETTER A WITH BREVE AND TILDE;Ll;0;L;0103 0303;;;;N;;;1EB4;;1EB4
+1EB6;LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW;Lu;0;L;1EA0 0306;;;;N;;;;1EB7;
+1EB7;LATIN SMALL LETTER A WITH BREVE AND DOT BELOW;Ll;0;L;1EA1 0306;;;;N;;;1EB6;;1EB6
+1EB8;LATIN CAPITAL LETTER E WITH DOT BELOW;Lu;0;L;0045 0323;;;;N;;;;1EB9;
+1EB9;LATIN SMALL LETTER E WITH DOT BELOW;Ll;0;L;0065 0323;;;;N;;;1EB8;;1EB8
+1EBA;LATIN CAPITAL LETTER E WITH HOOK ABOVE;Lu;0;L;0045 0309;;;;N;;;;1EBB;
+1EBB;LATIN SMALL LETTER E WITH HOOK ABOVE;Ll;0;L;0065 0309;;;;N;;;1EBA;;1EBA
+1EBC;LATIN CAPITAL LETTER E WITH TILDE;Lu;0;L;0045 0303;;;;N;;;;1EBD;
+1EBD;LATIN SMALL LETTER E WITH TILDE;Ll;0;L;0065 0303;;;;N;;;1EBC;;1EBC
+1EBE;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00CA 0301;;;;N;;;;1EBF;
+1EBF;LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00EA 0301;;;;N;;;1EBE;;1EBE
+1EC0;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00CA 0300;;;;N;;;;1EC1;
+1EC1;LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00EA 0300;;;;N;;;1EC0;;1EC0
+1EC2;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00CA 0309;;;;N;;;;1EC3;
+1EC3;LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00EA 0309;;;;N;;;1EC2;;1EC2
+1EC4;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE;Lu;0;L;00CA 0303;;;;N;;;;1EC5;
+1EC5;LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE;Ll;0;L;00EA 0303;;;;N;;;1EC4;;1EC4
+1EC6;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EB8 0302;;;;N;;;;1EC7;
+1EC7;LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EB9 0302;;;;N;;;1EC6;;1EC6
+1EC8;LATIN CAPITAL LETTER I WITH HOOK ABOVE;Lu;0;L;0049 0309;;;;N;;;;1EC9;
+1EC9;LATIN SMALL LETTER I WITH HOOK ABOVE;Ll;0;L;0069 0309;;;;N;;;1EC8;;1EC8
+1ECA;LATIN CAPITAL LETTER I WITH DOT BELOW;Lu;0;L;0049 0323;;;;N;;;;1ECB;
+1ECB;LATIN SMALL LETTER I WITH DOT BELOW;Ll;0;L;0069 0323;;;;N;;;1ECA;;1ECA
+1ECC;LATIN CAPITAL LETTER O WITH DOT BELOW;Lu;0;L;004F 0323;;;;N;;;;1ECD;
+1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC
+1ECE;LATIN CAPITAL LETTER O WITH HOOK ABOVE;Lu;0;L;004F 0309;;;;N;;;;1ECF;
+1ECF;LATIN SMALL LETTER O WITH HOOK ABOVE;Ll;0;L;006F 0309;;;;N;;;1ECE;;1ECE
+1ED0;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00D4 0301;;;;N;;;;1ED1;
+1ED1;LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00F4 0301;;;;N;;;1ED0;;1ED0
+1ED2;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00D4 0300;;;;N;;;;1ED3;
+1ED3;LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00F4 0300;;;;N;;;1ED2;;1ED2
+1ED4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00D4 0309;;;;N;;;;1ED5;
+1ED5;LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00F4 0309;;;;N;;;1ED4;;1ED4
+1ED6;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE;Lu;0;L;00D4 0303;;;;N;;;;1ED7;
+1ED7;LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE;Ll;0;L;00F4 0303;;;;N;;;1ED6;;1ED6
+1ED8;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1ECC 0302;;;;N;;;;1ED9;
+1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8
+1EDA;LATIN CAPITAL LETTER O WITH HORN AND ACUTE;Lu;0;L;01A0 0301;;;;N;;;;1EDB;
+1EDB;LATIN SMALL LETTER O WITH HORN AND ACUTE;Ll;0;L;01A1 0301;;;;N;;;1EDA;;1EDA
+1EDC;LATIN CAPITAL LETTER O WITH HORN AND GRAVE;Lu;0;L;01A0 0300;;;;N;;;;1EDD;
+1EDD;LATIN SMALL LETTER O WITH HORN AND GRAVE;Ll;0;L;01A1 0300;;;;N;;;1EDC;;1EDC
+1EDE;LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE;Lu;0;L;01A0 0309;;;;N;;;;1EDF;
+1EDF;LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE;Ll;0;L;01A1 0309;;;;N;;;1EDE;;1EDE
+1EE0;LATIN CAPITAL LETTER O WITH HORN AND TILDE;Lu;0;L;01A0 0303;;;;N;;;;1EE1;
+1EE1;LATIN SMALL LETTER O WITH HORN AND TILDE;Ll;0;L;01A1 0303;;;;N;;;1EE0;;1EE0
+1EE2;LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW;Lu;0;L;01A0 0323;;;;N;;;;1EE3;
+1EE3;LATIN SMALL LETTER O WITH HORN AND DOT BELOW;Ll;0;L;01A1 0323;;;;N;;;1EE2;;1EE2
+1EE4;LATIN CAPITAL LETTER U WITH DOT BELOW;Lu;0;L;0055 0323;;;;N;;;;1EE5;
+1EE5;LATIN SMALL LETTER U WITH DOT BELOW;Ll;0;L;0075 0323;;;;N;;;1EE4;;1EE4
+1EE6;LATIN CAPITAL LETTER U WITH HOOK ABOVE;Lu;0;L;0055 0309;;;;N;;;;1EE7;
+1EE7;LATIN SMALL LETTER U WITH HOOK ABOVE;Ll;0;L;0075 0309;;;;N;;;1EE6;;1EE6
+1EE8;LATIN CAPITAL LETTER U WITH HORN AND ACUTE;Lu;0;L;01AF 0301;;;;N;;;;1EE9;
+1EE9;LATIN SMALL LETTER U WITH HORN AND ACUTE;Ll;0;L;01B0 0301;;;;N;;;1EE8;;1EE8
+1EEA;LATIN CAPITAL LETTER U WITH HORN AND GRAVE;Lu;0;L;01AF 0300;;;;N;;;;1EEB;
+1EEB;LATIN SMALL LETTER U WITH HORN AND GRAVE;Ll;0;L;01B0 0300;;;;N;;;1EEA;;1EEA
+1EEC;LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE;Lu;0;L;01AF 0309;;;;N;;;;1EED;
+1EED;LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE;Ll;0;L;01B0 0309;;;;N;;;1EEC;;1EEC
+1EEE;LATIN CAPITAL LETTER U WITH HORN AND TILDE;Lu;0;L;01AF 0303;;;;N;;;;1EEF;
+1EEF;LATIN SMALL LETTER U WITH HORN AND TILDE;Ll;0;L;01B0 0303;;;;N;;;1EEE;;1EEE
+1EF0;LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW;Lu;0;L;01AF 0323;;;;N;;;;1EF1;
+1EF1;LATIN SMALL LETTER U WITH HORN AND DOT BELOW;Ll;0;L;01B0 0323;;;;N;;;1EF0;;1EF0
+1EF2;LATIN CAPITAL LETTER Y WITH GRAVE;Lu;0;L;0059 0300;;;;N;;;;1EF3;
+1EF3;LATIN SMALL LETTER Y WITH GRAVE;Ll;0;L;0079 0300;;;;N;;;1EF2;;1EF2
+1EF4;LATIN CAPITAL LETTER Y WITH DOT BELOW;Lu;0;L;0059 0323;;;;N;;;;1EF5;
+1EF5;LATIN SMALL LETTER Y WITH DOT BELOW;Ll;0;L;0079 0323;;;;N;;;1EF4;;1EF4
+1EF6;LATIN CAPITAL LETTER Y WITH HOOK ABOVE;Lu;0;L;0059 0309;;;;N;;;;1EF7;
+1EF7;LATIN SMALL LETTER Y WITH HOOK ABOVE;Ll;0;L;0079 0309;;;;N;;;1EF6;;1EF6
+1EF8;LATIN CAPITAL LETTER Y WITH TILDE;Lu;0;L;0059 0303;;;;N;;;;1EF9;
+1EF9;LATIN SMALL LETTER Y WITH TILDE;Ll;0;L;0079 0303;;;;N;;;1EF8;;1EF8
+1EFA;LATIN CAPITAL LETTER MIDDLE-WELSH LL;Lu;0;L;;;;;N;;;;1EFB;
+1EFB;LATIN SMALL LETTER MIDDLE-WELSH LL;Ll;0;L;;;;;N;;;1EFA;;1EFA
+1EFC;LATIN CAPITAL LETTER MIDDLE-WELSH V;Lu;0;L;;;;;N;;;;1EFD;
+1EFD;LATIN SMALL LETTER MIDDLE-WELSH V;Ll;0;L;;;;;N;;;1EFC;;1EFC
+1EFE;LATIN CAPITAL LETTER Y WITH LOOP;Lu;0;L;;;;;N;;;;1EFF;
+1EFF;LATIN SMALL LETTER Y WITH LOOP;Ll;0;L;;;;;N;;;1EFE;;1EFE
+1F00;GREEK SMALL LETTER ALPHA WITH PSILI;Ll;0;L;03B1 0313;;;;N;;;1F08;;1F08
+1F01;GREEK SMALL LETTER ALPHA WITH DASIA;Ll;0;L;03B1 0314;;;;N;;;1F09;;1F09
+1F02;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA;Ll;0;L;1F00 0300;;;;N;;;1F0A;;1F0A
+1F03;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA;Ll;0;L;1F01 0300;;;;N;;;1F0B;;1F0B
+1F04;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA;Ll;0;L;1F00 0301;;;;N;;;1F0C;;1F0C
+1F05;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA;Ll;0;L;1F01 0301;;;;N;;;1F0D;;1F0D
+1F06;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI;Ll;0;L;1F00 0342;;;;N;;;1F0E;;1F0E
+1F07;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI;Ll;0;L;1F01 0342;;;;N;;;1F0F;;1F0F
+1F08;GREEK CAPITAL LETTER ALPHA WITH PSILI;Lu;0;L;0391 0313;;;;N;;;;1F00;
+1F09;GREEK CAPITAL LETTER ALPHA WITH DASIA;Lu;0;L;0391 0314;;;;N;;;;1F01;
+1F0A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA;Lu;0;L;1F08 0300;;;;N;;;;1F02;
+1F0B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA;Lu;0;L;1F09 0300;;;;N;;;;1F03;
+1F0C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA;Lu;0;L;1F08 0301;;;;N;;;;1F04;
+1F0D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA;Lu;0;L;1F09 0301;;;;N;;;;1F05;
+1F0E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI;Lu;0;L;1F08 0342;;;;N;;;;1F06;
+1F0F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI;Lu;0;L;1F09 0342;;;;N;;;;1F07;
+1F10;GREEK SMALL LETTER EPSILON WITH PSILI;Ll;0;L;03B5 0313;;;;N;;;1F18;;1F18
+1F11;GREEK SMALL LETTER EPSILON WITH DASIA;Ll;0;L;03B5 0314;;;;N;;;1F19;;1F19
+1F12;GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA;Ll;0;L;1F10 0300;;;;N;;;1F1A;;1F1A
+1F13;GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA;Ll;0;L;1F11 0300;;;;N;;;1F1B;;1F1B
+1F14;GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA;Ll;0;L;1F10 0301;;;;N;;;1F1C;;1F1C
+1F15;GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA;Ll;0;L;1F11 0301;;;;N;;;1F1D;;1F1D
+1F18;GREEK CAPITAL LETTER EPSILON WITH PSILI;Lu;0;L;0395 0313;;;;N;;;;1F10;
+1F19;GREEK CAPITAL LETTER EPSILON WITH DASIA;Lu;0;L;0395 0314;;;;N;;;;1F11;
+1F1A;GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA;Lu;0;L;1F18 0300;;;;N;;;;1F12;
+1F1B;GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA;Lu;0;L;1F19 0300;;;;N;;;;1F13;
+1F1C;GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA;Lu;0;L;1F18 0301;;;;N;;;;1F14;
+1F1D;GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA;Lu;0;L;1F19 0301;;;;N;;;;1F15;
+1F20;GREEK SMALL LETTER ETA WITH PSILI;Ll;0;L;03B7 0313;;;;N;;;1F28;;1F28
+1F21;GREEK SMALL LETTER ETA WITH DASIA;Ll;0;L;03B7 0314;;;;N;;;1F29;;1F29
+1F22;GREEK SMALL LETTER ETA WITH PSILI AND VARIA;Ll;0;L;1F20 0300;;;;N;;;1F2A;;1F2A
+1F23;GREEK SMALL LETTER ETA WITH DASIA AND VARIA;Ll;0;L;1F21 0300;;;;N;;;1F2B;;1F2B
+1F24;GREEK SMALL LETTER ETA WITH PSILI AND OXIA;Ll;0;L;1F20 0301;;;;N;;;1F2C;;1F2C
+1F25;GREEK SMALL LETTER ETA WITH DASIA AND OXIA;Ll;0;L;1F21 0301;;;;N;;;1F2D;;1F2D
+1F26;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI;Ll;0;L;1F20 0342;;;;N;;;1F2E;;1F2E
+1F27;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI;Ll;0;L;1F21 0342;;;;N;;;1F2F;;1F2F
+1F28;GREEK CAPITAL LETTER ETA WITH PSILI;Lu;0;L;0397 0313;;;;N;;;;1F20;
+1F29;GREEK CAPITAL LETTER ETA WITH DASIA;Lu;0;L;0397 0314;;;;N;;;;1F21;
+1F2A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA;Lu;0;L;1F28 0300;;;;N;;;;1F22;
+1F2B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA;Lu;0;L;1F29 0300;;;;N;;;;1F23;
+1F2C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA;Lu;0;L;1F28 0301;;;;N;;;;1F24;
+1F2D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA;Lu;0;L;1F29 0301;;;;N;;;;1F25;
+1F2E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI;Lu;0;L;1F28 0342;;;;N;;;;1F26;
+1F2F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI;Lu;0;L;1F29 0342;;;;N;;;;1F27;
+1F30;GREEK SMALL LETTER IOTA WITH PSILI;Ll;0;L;03B9 0313;;;;N;;;1F38;;1F38
+1F31;GREEK SMALL LETTER IOTA WITH DASIA;Ll;0;L;03B9 0314;;;;N;;;1F39;;1F39
+1F32;GREEK SMALL LETTER IOTA WITH PSILI AND VARIA;Ll;0;L;1F30 0300;;;;N;;;1F3A;;1F3A
+1F33;GREEK SMALL LETTER IOTA WITH DASIA AND VARIA;Ll;0;L;1F31 0300;;;;N;;;1F3B;;1F3B
+1F34;GREEK SMALL LETTER IOTA WITH PSILI AND OXIA;Ll;0;L;1F30 0301;;;;N;;;1F3C;;1F3C
+1F35;GREEK SMALL LETTER IOTA WITH DASIA AND OXIA;Ll;0;L;1F31 0301;;;;N;;;1F3D;;1F3D
+1F36;GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI;Ll;0;L;1F30 0342;;;;N;;;1F3E;;1F3E
+1F37;GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI;Ll;0;L;1F31 0342;;;;N;;;1F3F;;1F3F
+1F38;GREEK CAPITAL LETTER IOTA WITH PSILI;Lu;0;L;0399 0313;;;;N;;;;1F30;
+1F39;GREEK CAPITAL LETTER IOTA WITH DASIA;Lu;0;L;0399 0314;;;;N;;;;1F31;
+1F3A;GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA;Lu;0;L;1F38 0300;;;;N;;;;1F32;
+1F3B;GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA;Lu;0;L;1F39 0300;;;;N;;;;1F33;
+1F3C;GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA;Lu;0;L;1F38 0301;;;;N;;;;1F34;
+1F3D;GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA;Lu;0;L;1F39 0301;;;;N;;;;1F35;
+1F3E;GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI;Lu;0;L;1F38 0342;;;;N;;;;1F36;
+1F3F;GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI;Lu;0;L;1F39 0342;;;;N;;;;1F37;
+1F40;GREEK SMALL LETTER OMICRON WITH PSILI;Ll;0;L;03BF 0313;;;;N;;;1F48;;1F48
+1F41;GREEK SMALL LETTER OMICRON WITH DASIA;Ll;0;L;03BF 0314;;;;N;;;1F49;;1F49
+1F42;GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA;Ll;0;L;1F40 0300;;;;N;;;1F4A;;1F4A
+1F43;GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA;Ll;0;L;1F41 0300;;;;N;;;1F4B;;1F4B
+1F44;GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA;Ll;0;L;1F40 0301;;;;N;;;1F4C;;1F4C
+1F45;GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA;Ll;0;L;1F41 0301;;;;N;;;1F4D;;1F4D
+1F48;GREEK CAPITAL LETTER OMICRON WITH PSILI;Lu;0;L;039F 0313;;;;N;;;;1F40;
+1F49;GREEK CAPITAL LETTER OMICRON WITH DASIA;Lu;0;L;039F 0314;;;;N;;;;1F41;
+1F4A;GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA;Lu;0;L;1F48 0300;;;;N;;;;1F42;
+1F4B;GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA;Lu;0;L;1F49 0300;;;;N;;;;1F43;
+1F4C;GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA;Lu;0;L;1F48 0301;;;;N;;;;1F44;
+1F4D;GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA;Lu;0;L;1F49 0301;;;;N;;;;1F45;
+1F50;GREEK SMALL LETTER UPSILON WITH PSILI;Ll;0;L;03C5 0313;;;;N;;;;;
+1F51;GREEK SMALL LETTER UPSILON WITH DASIA;Ll;0;L;03C5 0314;;;;N;;;1F59;;1F59
+1F52;GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA;Ll;0;L;1F50 0300;;;;N;;;;;
+1F53;GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA;Ll;0;L;1F51 0300;;;;N;;;1F5B;;1F5B
+1F54;GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA;Ll;0;L;1F50 0301;;;;N;;;;;
+1F55;GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA;Ll;0;L;1F51 0301;;;;N;;;1F5D;;1F5D
+1F56;GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI;Ll;0;L;1F50 0342;;;;N;;;;;
+1F57;GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI;Ll;0;L;1F51 0342;;;;N;;;1F5F;;1F5F
+1F59;GREEK CAPITAL LETTER UPSILON WITH DASIA;Lu;0;L;03A5 0314;;;;N;;;;1F51;
+1F5B;GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA;Lu;0;L;1F59 0300;;;;N;;;;1F53;
+1F5D;GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA;Lu;0;L;1F59 0301;;;;N;;;;1F55;
+1F5F;GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI;Lu;0;L;1F59 0342;;;;N;;;;1F57;
+1F60;GREEK SMALL LETTER OMEGA WITH PSILI;Ll;0;L;03C9 0313;;;;N;;;1F68;;1F68
+1F61;GREEK SMALL LETTER OMEGA WITH DASIA;Ll;0;L;03C9 0314;;;;N;;;1F69;;1F69
+1F62;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA;Ll;0;L;1F60 0300;;;;N;;;1F6A;;1F6A
+1F63;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA;Ll;0;L;1F61 0300;;;;N;;;1F6B;;1F6B
+1F64;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA;Ll;0;L;1F60 0301;;;;N;;;1F6C;;1F6C
+1F65;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA;Ll;0;L;1F61 0301;;;;N;;;1F6D;;1F6D
+1F66;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI;Ll;0;L;1F60 0342;;;;N;;;1F6E;;1F6E
+1F67;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI;Ll;0;L;1F61 0342;;;;N;;;1F6F;;1F6F
+1F68;GREEK CAPITAL LETTER OMEGA WITH PSILI;Lu;0;L;03A9 0313;;;;N;;;;1F60;
+1F69;GREEK CAPITAL LETTER OMEGA WITH DASIA;Lu;0;L;03A9 0314;;;;N;;;;1F61;
+1F6A;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA;Lu;0;L;1F68 0300;;;;N;;;;1F62;
+1F6B;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA;Lu;0;L;1F69 0300;;;;N;;;;1F63;
+1F6C;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA;Lu;0;L;1F68 0301;;;;N;;;;1F64;
+1F6D;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA;Lu;0;L;1F69 0301;;;;N;;;;1F65;
+1F6E;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI;Lu;0;L;1F68 0342;;;;N;;;;1F66;
+1F6F;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI;Lu;0;L;1F69 0342;;;;N;;;;1F67;
+1F70;GREEK SMALL LETTER ALPHA WITH VARIA;Ll;0;L;03B1 0300;;;;N;;;1FBA;;1FBA
+1F71;GREEK SMALL LETTER ALPHA WITH OXIA;Ll;0;L;03AC;;;;N;;;1FBB;;1FBB
+1F72;GREEK SMALL LETTER EPSILON WITH VARIA;Ll;0;L;03B5 0300;;;;N;;;1FC8;;1FC8
+1F73;GREEK SMALL LETTER EPSILON WITH OXIA;Ll;0;L;03AD;;;;N;;;1FC9;;1FC9
+1F74;GREEK SMALL LETTER ETA WITH VARIA;Ll;0;L;03B7 0300;;;;N;;;1FCA;;1FCA
+1F75;GREEK SMALL LETTER ETA WITH OXIA;Ll;0;L;03AE;;;;N;;;1FCB;;1FCB
+1F76;GREEK SMALL LETTER IOTA WITH VARIA;Ll;0;L;03B9 0300;;;;N;;;1FDA;;1FDA
+1F77;GREEK SMALL LETTER IOTA WITH OXIA;Ll;0;L;03AF;;;;N;;;1FDB;;1FDB
+1F78;GREEK SMALL LETTER OMICRON WITH VARIA;Ll;0;L;03BF 0300;;;;N;;;1FF8;;1FF8
+1F79;GREEK SMALL LETTER OMICRON WITH OXIA;Ll;0;L;03CC;;;;N;;;1FF9;;1FF9
+1F7A;GREEK SMALL LETTER UPSILON WITH VARIA;Ll;0;L;03C5 0300;;;;N;;;1FEA;;1FEA
+1F7B;GREEK SMALL LETTER UPSILON WITH OXIA;Ll;0;L;03CD;;;;N;;;1FEB;;1FEB
+1F7C;GREEK SMALL LETTER OMEGA WITH VARIA;Ll;0;L;03C9 0300;;;;N;;;1FFA;;1FFA
+1F7D;GREEK SMALL LETTER OMEGA WITH OXIA;Ll;0;L;03CE;;;;N;;;1FFB;;1FFB
+1F80;GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F00 0345;;;;N;;;1F88;;1F88
+1F81;GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F01 0345;;;;N;;;1F89;;1F89
+1F82;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F02 0345;;;;N;;;1F8A;;1F8A
+1F83;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F03 0345;;;;N;;;1F8B;;1F8B
+1F84;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F04 0345;;;;N;;;1F8C;;1F8C
+1F85;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F05 0345;;;;N;;;1F8D;;1F8D
+1F86;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F06 0345;;;;N;;;1F8E;;1F8E
+1F87;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F07 0345;;;;N;;;1F8F;;1F8F
+1F88;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F08 0345;;;;N;;;;1F80;
+1F89;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F09 0345;;;;N;;;;1F81;
+1F8A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0A 0345;;;;N;;;;1F82;
+1F8B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0B 0345;;;;N;;;;1F83;
+1F8C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0C 0345;;;;N;;;;1F84;
+1F8D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0D 0345;;;;N;;;;1F85;
+1F8E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0E 0345;;;;N;;;;1F86;
+1F8F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0F 0345;;;;N;;;;1F87;
+1F90;GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F20 0345;;;;N;;;1F98;;1F98
+1F91;GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F21 0345;;;;N;;;1F99;;1F99
+1F92;GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F22 0345;;;;N;;;1F9A;;1F9A
+1F93;GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F23 0345;;;;N;;;1F9B;;1F9B
+1F94;GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F24 0345;;;;N;;;1F9C;;1F9C
+1F95;GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F25 0345;;;;N;;;1F9D;;1F9D
+1F96;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F26 0345;;;;N;;;1F9E;;1F9E
+1F97;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F27 0345;;;;N;;;1F9F;;1F9F
+1F98;GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F28 0345;;;;N;;;;1F90;
+1F99;GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F29 0345;;;;N;;;;1F91;
+1F9A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2A 0345;;;;N;;;;1F92;
+1F9B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2B 0345;;;;N;;;;1F93;
+1F9C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2C 0345;;;;N;;;;1F94;
+1F9D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2D 0345;;;;N;;;;1F95;
+1F9E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2E 0345;;;;N;;;;1F96;
+1F9F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2F 0345;;;;N;;;;1F97;
+1FA0;GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F60 0345;;;;N;;;1FA8;;1FA8
+1FA1;GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F61 0345;;;;N;;;1FA9;;1FA9
+1FA2;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F62 0345;;;;N;;;1FAA;;1FAA
+1FA3;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F63 0345;;;;N;;;1FAB;;1FAB
+1FA4;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F64 0345;;;;N;;;1FAC;;1FAC
+1FA5;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F65 0345;;;;N;;;1FAD;;1FAD
+1FA6;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F66 0345;;;;N;;;1FAE;;1FAE
+1FA7;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F67 0345;;;;N;;;1FAF;;1FAF
+1FA8;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F68 0345;;;;N;;;;1FA0;
+1FA9;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F69 0345;;;;N;;;;1FA1;
+1FAA;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6A 0345;;;;N;;;;1FA2;
+1FAB;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6B 0345;;;;N;;;;1FA3;
+1FAC;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6C 0345;;;;N;;;;1FA4;
+1FAD;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6D 0345;;;;N;;;;1FA5;
+1FAE;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6E 0345;;;;N;;;;1FA6;
+1FAF;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6F 0345;;;;N;;;;1FA7;
+1FB0;GREEK SMALL LETTER ALPHA WITH VRACHY;Ll;0;L;03B1 0306;;;;N;;;1FB8;;1FB8
+1FB1;GREEK SMALL LETTER ALPHA WITH MACRON;Ll;0;L;03B1 0304;;;;N;;;1FB9;;1FB9
+1FB2;GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F70 0345;;;;N;;;;;
+1FB3;GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI;Ll;0;L;03B1 0345;;;;N;;;1FBC;;1FBC
+1FB4;GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AC 0345;;;;N;;;;;
+1FB6;GREEK SMALL LETTER ALPHA WITH PERISPOMENI;Ll;0;L;03B1 0342;;;;N;;;;;
+1FB7;GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FB6 0345;;;;N;;;;;
+1FB8;GREEK CAPITAL LETTER ALPHA WITH VRACHY;Lu;0;L;0391 0306;;;;N;;;;1FB0;
+1FB9;GREEK CAPITAL LETTER ALPHA WITH MACRON;Lu;0;L;0391 0304;;;;N;;;;1FB1;
+1FBA;GREEK CAPITAL LETTER ALPHA WITH VARIA;Lu;0;L;0391 0300;;;;N;;;;1F70;
+1FBB;GREEK CAPITAL LETTER ALPHA WITH OXIA;Lu;0;L;0386;;;;N;;;;1F71;
+1FBC;GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI;Lt;0;L;0391 0345;;;;N;;;;1FB3;
+1FBD;GREEK KORONIS;Sk;0;ON;<compat> 0020 0313;;;;N;;;;;
+1FBE;GREEK PROSGEGRAMMENI;Ll;0;L;03B9;;;;N;;;0399;;0399
+1FBF;GREEK PSILI;Sk;0;ON;<compat> 0020 0313;;;;N;;;;;
+1FC0;GREEK PERISPOMENI;Sk;0;ON;<compat> 0020 0342;;;;N;;;;;
+1FC1;GREEK DIALYTIKA AND PERISPOMENI;Sk;0;ON;00A8 0342;;;;N;;;;;
+1FC2;GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F74 0345;;;;N;;;;;
+1FC3;GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI;Ll;0;L;03B7 0345;;;;N;;;1FCC;;1FCC
+1FC4;GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AE 0345;;;;N;;;;;
+1FC6;GREEK SMALL LETTER ETA WITH PERISPOMENI;Ll;0;L;03B7 0342;;;;N;;;;;
+1FC7;GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FC6 0345;;;;N;;;;;
+1FC8;GREEK CAPITAL LETTER EPSILON WITH VARIA;Lu;0;L;0395 0300;;;;N;;;;1F72;
+1FC9;GREEK CAPITAL LETTER EPSILON WITH OXIA;Lu;0;L;0388;;;;N;;;;1F73;
+1FCA;GREEK CAPITAL LETTER ETA WITH VARIA;Lu;0;L;0397 0300;;;;N;;;;1F74;
+1FCB;GREEK CAPITAL LETTER ETA WITH OXIA;Lu;0;L;0389;;;;N;;;;1F75;
+1FCC;GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI;Lt;0;L;0397 0345;;;;N;;;;1FC3;
+1FCD;GREEK PSILI AND VARIA;Sk;0;ON;1FBF 0300;;;;N;;;;;
+1FCE;GREEK PSILI AND OXIA;Sk;0;ON;1FBF 0301;;;;N;;;;;
+1FCF;GREEK PSILI AND PERISPOMENI;Sk;0;ON;1FBF 0342;;;;N;;;;;
+1FD0;GREEK SMALL LETTER IOTA WITH VRACHY;Ll;0;L;03B9 0306;;;;N;;;1FD8;;1FD8
+1FD1;GREEK SMALL LETTER IOTA WITH MACRON;Ll;0;L;03B9 0304;;;;N;;;1FD9;;1FD9
+1FD2;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA;Ll;0;L;03CA 0300;;;;N;;;;;
+1FD3;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA;Ll;0;L;0390;;;;N;;;;;
+1FD6;GREEK SMALL LETTER IOTA WITH PERISPOMENI;Ll;0;L;03B9 0342;;;;N;;;;;
+1FD7;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CA 0342;;;;N;;;;;
+1FD8;GREEK CAPITAL LETTER IOTA WITH VRACHY;Lu;0;L;0399 0306;;;;N;;;;1FD0;
+1FD9;GREEK CAPITAL LETTER IOTA WITH MACRON;Lu;0;L;0399 0304;;;;N;;;;1FD1;
+1FDA;GREEK CAPITAL LETTER IOTA WITH VARIA;Lu;0;L;0399 0300;;;;N;;;;1F76;
+1FDB;GREEK CAPITAL LETTER IOTA WITH OXIA;Lu;0;L;038A;;;;N;;;;1F77;
+1FDD;GREEK DASIA AND VARIA;Sk;0;ON;1FFE 0300;;;;N;;;;;
+1FDE;GREEK DASIA AND OXIA;Sk;0;ON;1FFE 0301;;;;N;;;;;
+1FDF;GREEK DASIA AND PERISPOMENI;Sk;0;ON;1FFE 0342;;;;N;;;;;
+1FE0;GREEK SMALL LETTER UPSILON WITH VRACHY;Ll;0;L;03C5 0306;;;;N;;;1FE8;;1FE8
+1FE1;GREEK SMALL LETTER UPSILON WITH MACRON;Ll;0;L;03C5 0304;;;;N;;;1FE9;;1FE9
+1FE2;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA;Ll;0;L;03CB 0300;;;;N;;;;;
+1FE3;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA;Ll;0;L;03B0;;;;N;;;;;
+1FE4;GREEK SMALL LETTER RHO WITH PSILI;Ll;0;L;03C1 0313;;;;N;;;;;
+1FE5;GREEK SMALL LETTER RHO WITH DASIA;Ll;0;L;03C1 0314;;;;N;;;1FEC;;1FEC
+1FE6;GREEK SMALL LETTER UPSILON WITH PERISPOMENI;Ll;0;L;03C5 0342;;;;N;;;;;
+1FE7;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CB 0342;;;;N;;;;;
+1FE8;GREEK CAPITAL LETTER UPSILON WITH VRACHY;Lu;0;L;03A5 0306;;;;N;;;;1FE0;
+1FE9;GREEK CAPITAL LETTER UPSILON WITH MACRON;Lu;0;L;03A5 0304;;;;N;;;;1FE1;
+1FEA;GREEK CAPITAL LETTER UPSILON WITH VARIA;Lu;0;L;03A5 0300;;;;N;;;;1F7A;
+1FEB;GREEK CAPITAL LETTER UPSILON WITH OXIA;Lu;0;L;038E;;;;N;;;;1F7B;
+1FEC;GREEK CAPITAL LETTER RHO WITH DASIA;Lu;0;L;03A1 0314;;;;N;;;;1FE5;
+1FED;GREEK DIALYTIKA AND VARIA;Sk;0;ON;00A8 0300;;;;N;;;;;
+1FEE;GREEK DIALYTIKA AND OXIA;Sk;0;ON;0385;;;;N;;;;;
+1FEF;GREEK VARIA;Sk;0;ON;0060;;;;N;;;;;
+1FF2;GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F7C 0345;;;;N;;;;;
+1FF3;GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI;Ll;0;L;03C9 0345;;;;N;;;1FFC;;1FFC
+1FF4;GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03CE 0345;;;;N;;;;;
+1FF6;GREEK SMALL LETTER OMEGA WITH PERISPOMENI;Ll;0;L;03C9 0342;;;;N;;;;;
+1FF7;GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FF6 0345;;;;N;;;;;
+1FF8;GREEK CAPITAL LETTER OMICRON WITH VARIA;Lu;0;L;039F 0300;;;;N;;;;1F78;
+1FF9;GREEK CAPITAL LETTER OMICRON WITH OXIA;Lu;0;L;038C;;;;N;;;;1F79;
+1FFA;GREEK CAPITAL LETTER OMEGA WITH VARIA;Lu;0;L;03A9 0300;;;;N;;;;1F7C;
+1FFB;GREEK CAPITAL LETTER OMEGA WITH OXIA;Lu;0;L;038F;;;;N;;;;1F7D;
+1FFC;GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI;Lt;0;L;03A9 0345;;;;N;;;;1FF3;
+1FFD;GREEK OXIA;Sk;0;ON;00B4;;;;N;;;;;
+1FFE;GREEK DASIA;Sk;0;ON;<compat> 0020 0314;;;;N;;;;;
+2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;;
+2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;;
+2002;EN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2003;EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2004;THREE-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2005;FOUR-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2006;SIX-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2007;FIGURE SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;
+2008;PUNCTUATION SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2009;THIN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+200A;HAIR SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+200B;ZERO WIDTH SPACE;Cf;0;BN;;;;;N;;;;;
+200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;;
+200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;;
+200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;;
+200F;RIGHT-TO-LEFT MARK;Cf;0;R;;;;;N;;;;;
+2010;HYPHEN;Pd;0;ON;;;;;N;;;;;
+2011;NON-BREAKING HYPHEN;Pd;0;ON;<noBreak> 2010;;;;N;;;;;
+2012;FIGURE DASH;Pd;0;ON;;;;;N;;;;;
+2013;EN DASH;Pd;0;ON;;;;;N;;;;;
+2014;EM DASH;Pd;0;ON;;;;;N;;;;;
+2015;HORIZONTAL BAR;Pd;0;ON;;;;;N;QUOTATION DASH;;;;
+2016;DOUBLE VERTICAL LINE;Po;0;ON;;;;;N;DOUBLE VERTICAL BAR;;;;
+2017;DOUBLE LOW LINE;Po;0;ON;<compat> 0020 0333;;;;N;SPACING DOUBLE UNDERSCORE;;;;
+2018;LEFT SINGLE QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE TURNED COMMA QUOTATION MARK;;;;
+2019;RIGHT SINGLE QUOTATION MARK;Pf;0;ON;;;;;N;SINGLE COMMA QUOTATION MARK;;;;
+201A;SINGLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW SINGLE COMMA QUOTATION MARK;;;;
+201B;SINGLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE REVERSED COMMA QUOTATION MARK;;;;
+201C;LEFT DOUBLE QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE TURNED COMMA QUOTATION MARK;;;;
+201D;RIGHT DOUBLE QUOTATION MARK;Pf;0;ON;;;;;N;DOUBLE COMMA QUOTATION MARK;;;;
+201E;DOUBLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW DOUBLE COMMA QUOTATION MARK;;;;
+201F;DOUBLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE REVERSED COMMA QUOTATION MARK;;;;
+2020;DAGGER;Po;0;ON;;;;;N;;;;;
+2021;DOUBLE DAGGER;Po;0;ON;;;;;N;;;;;
+2022;BULLET;Po;0;ON;;;;;N;;;;;
+2023;TRIANGULAR BULLET;Po;0;ON;;;;;N;;;;;
+2024;ONE DOT LEADER;Po;0;ON;<compat> 002E;;;;N;;;;;
+2025;TWO DOT LEADER;Po;0;ON;<compat> 002E 002E;;;;N;;;;;
+2026;HORIZONTAL ELLIPSIS;Po;0;ON;<compat> 002E 002E 002E;;;;N;;;;;
+2027;HYPHENATION POINT;Po;0;ON;;;;;N;;;;;
+2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;;
+2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;;
+202A;LEFT-TO-RIGHT EMBEDDING;Cf;0;LRE;;;;;N;;;;;
+202B;RIGHT-TO-LEFT EMBEDDING;Cf;0;RLE;;;;;N;;;;;
+202C;POP DIRECTIONAL FORMATTING;Cf;0;PDF;;;;;N;;;;;
+202D;LEFT-TO-RIGHT OVERRIDE;Cf;0;LRO;;;;;N;;;;;
+202E;RIGHT-TO-LEFT OVERRIDE;Cf;0;RLO;;;;;N;;;;;
+202F;NARROW NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;;;;;
+2030;PER MILLE SIGN;Po;0;ET;;;;;N;;;;;
+2031;PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;;
+2032;PRIME;Po;0;ET;;;;;N;;;;;
+2033;DOUBLE PRIME;Po;0;ET;<compat> 2032 2032;;;;N;;;;;
+2034;TRIPLE PRIME;Po;0;ET;<compat> 2032 2032 2032;;;;N;;;;;
+2035;REVERSED PRIME;Po;0;ON;;;;;N;;;;;
+2036;REVERSED DOUBLE PRIME;Po;0;ON;<compat> 2035 2035;;;;N;;;;;
+2037;REVERSED TRIPLE PRIME;Po;0;ON;<compat> 2035 2035 2035;;;;N;;;;;
+2038;CARET;Po;0;ON;;;;;N;;;;;
+2039;SINGLE LEFT-POINTING ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING SINGLE GUILLEMET;;;;
+203A;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING SINGLE GUILLEMET;;;;
+203B;REFERENCE MARK;Po;0;ON;;;;;N;;;;;
+203C;DOUBLE EXCLAMATION MARK;Po;0;ON;<compat> 0021 0021;;;;N;;;;;
+203D;INTERROBANG;Po;0;ON;;;;;N;;;;;
+203E;OVERLINE;Po;0;ON;<compat> 0020 0305;;;;N;SPACING OVERSCORE;;;;
+203F;UNDERTIE;Pc;0;ON;;;;;N;;;;;
+2040;CHARACTER TIE;Pc;0;ON;;;;;N;;;;;
+2041;CARET INSERTION POINT;Po;0;ON;;;;;N;;;;;
+2042;ASTERISM;Po;0;ON;;;;;N;;;;;
+2043;HYPHEN BULLET;Po;0;ON;;;;;N;;;;;
+2044;FRACTION SLASH;Sm;0;CS;;;;;N;;;;;
+2045;LEFT SQUARE BRACKET WITH QUILL;Ps;0;ON;;;;;Y;;;;;
+2046;RIGHT SQUARE BRACKET WITH QUILL;Pe;0;ON;;;;;Y;;;;;
+2047;DOUBLE QUESTION MARK;Po;0;ON;<compat> 003F 003F;;;;N;;;;;
+2048;QUESTION EXCLAMATION MARK;Po;0;ON;<compat> 003F 0021;;;;N;;;;;
+2049;EXCLAMATION QUESTION MARK;Po;0;ON;<compat> 0021 003F;;;;N;;;;;
+204A;TIRONIAN SIGN ET;Po;0;ON;;;;;N;;;;;
+204B;REVERSED PILCROW SIGN;Po;0;ON;;;;;N;;;;;
+204C;BLACK LEFTWARDS BULLET;Po;0;ON;;;;;N;;;;;
+204D;BLACK RIGHTWARDS BULLET;Po;0;ON;;;;;N;;;;;
+204E;LOW ASTERISK;Po;0;ON;;;;;N;;;;;
+204F;REVERSED SEMICOLON;Po;0;ON;;;;;N;;;;;
+2050;CLOSE UP;Po;0;ON;;;;;N;;;;;
+2051;TWO ASTERISKS ALIGNED VERTICALLY;Po;0;ON;;;;;N;;;;;
+2052;COMMERCIAL MINUS SIGN;Sm;0;ON;;;;;N;;;;;
+2053;SWUNG DASH;Po;0;ON;;;;;N;;;;;
+2054;INVERTED UNDERTIE;Pc;0;ON;;;;;N;;;;;
+2055;FLOWER PUNCTUATION MARK;Po;0;ON;;;;;N;;;;;
+2056;THREE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+2057;QUADRUPLE PRIME;Po;0;ON;<compat> 2032 2032 2032 2032;;;;N;;;;;
+2058;FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+2059;FIVE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+205A;TWO DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+205B;FOUR DOT MARK;Po;0;ON;;;;;N;;;;;
+205C;DOTTED CROSS;Po;0;ON;;;;;N;;;;;
+205D;TRICOLON;Po;0;ON;;;;;N;;;;;
+205E;VERTICAL FOUR DOTS;Po;0;ON;;;;;N;;;;;
+205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
+2060;WORD JOINER;Cf;0;BN;;;;;N;;;;;
+2061;FUNCTION APPLICATION;Cf;0;BN;;;;;N;;;;;
+2062;INVISIBLE TIMES;Cf;0;BN;;;;;N;;;;;
+2063;INVISIBLE SEPARATOR;Cf;0;BN;;;;;N;;;;;
+2064;INVISIBLE PLUS;Cf;0;BN;;;;;N;;;;;
+2066;LEFT-TO-RIGHT ISOLATE;Cf;0;LRI;;;;;N;;;;;
+2067;RIGHT-TO-LEFT ISOLATE;Cf;0;RLI;;;;;N;;;;;
+2068;FIRST STRONG ISOLATE;Cf;0;FSI;;;;;N;;;;;
+2069;POP DIRECTIONAL ISOLATE;Cf;0;PDI;;;;;N;;;;;
+206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
+206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
+206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;
+206D;ACTIVATE ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;
+206E;NATIONAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;;
+206F;NOMINAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;;
+2070;SUPERSCRIPT ZERO;No;0;EN;<super> 0030;;0;0;N;SUPERSCRIPT DIGIT ZERO;;;;
+2071;SUPERSCRIPT LATIN SMALL LETTER I;Lm;0;L;<super> 0069;;;;N;;;;;
+2074;SUPERSCRIPT FOUR;No;0;EN;<super> 0034;;4;4;N;SUPERSCRIPT DIGIT FOUR;;;;
+2075;SUPERSCRIPT FIVE;No;0;EN;<super> 0035;;5;5;N;SUPERSCRIPT DIGIT FIVE;;;;
+2076;SUPERSCRIPT SIX;No;0;EN;<super> 0036;;6;6;N;SUPERSCRIPT DIGIT SIX;;;;
+2077;SUPERSCRIPT SEVEN;No;0;EN;<super> 0037;;7;7;N;SUPERSCRIPT DIGIT SEVEN;;;;
+2078;SUPERSCRIPT EIGHT;No;0;EN;<super> 0038;;8;8;N;SUPERSCRIPT DIGIT EIGHT;;;;
+2079;SUPERSCRIPT NINE;No;0;EN;<super> 0039;;9;9;N;SUPERSCRIPT DIGIT NINE;;;;
+207A;SUPERSCRIPT PLUS SIGN;Sm;0;ES;<super> 002B;;;;N;;;;;
+207B;SUPERSCRIPT MINUS;Sm;0;ES;<super> 2212;;;;N;SUPERSCRIPT HYPHEN-MINUS;;;;
+207C;SUPERSCRIPT EQUALS SIGN;Sm;0;ON;<super> 003D;;;;N;;;;;
+207D;SUPERSCRIPT LEFT PARENTHESIS;Ps;0;ON;<super> 0028;;;;Y;SUPERSCRIPT OPENING PARENTHESIS;;;;
+207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe;0;ON;<super> 0029;;;;Y;SUPERSCRIPT CLOSING PARENTHESIS;;;;
+207F;SUPERSCRIPT LATIN SMALL LETTER N;Lm;0;L;<super> 006E;;;;N;;;;;
+2080;SUBSCRIPT ZERO;No;0;EN;<sub> 0030;;0;0;N;SUBSCRIPT DIGIT ZERO;;;;
+2081;SUBSCRIPT ONE;No;0;EN;<sub> 0031;;1;1;N;SUBSCRIPT DIGIT ONE;;;;
+2082;SUBSCRIPT TWO;No;0;EN;<sub> 0032;;2;2;N;SUBSCRIPT DIGIT TWO;;;;
+2083;SUBSCRIPT THREE;No;0;EN;<sub> 0033;;3;3;N;SUBSCRIPT DIGIT THREE;;;;
+2084;SUBSCRIPT FOUR;No;0;EN;<sub> 0034;;4;4;N;SUBSCRIPT DIGIT FOUR;;;;
+2085;SUBSCRIPT FIVE;No;0;EN;<sub> 0035;;5;5;N;SUBSCRIPT DIGIT FIVE;;;;
+2086;SUBSCRIPT SIX;No;0;EN;<sub> 0036;;6;6;N;SUBSCRIPT DIGIT SIX;;;;
+2087;SUBSCRIPT SEVEN;No;0;EN;<sub> 0037;;7;7;N;SUBSCRIPT DIGIT SEVEN;;;;
+2088;SUBSCRIPT EIGHT;No;0;EN;<sub> 0038;;8;8;N;SUBSCRIPT DIGIT EIGHT;;;;
+2089;SUBSCRIPT NINE;No;0;EN;<sub> 0039;;9;9;N;SUBSCRIPT DIGIT NINE;;;;
+208A;SUBSCRIPT PLUS SIGN;Sm;0;ES;<sub> 002B;;;;N;;;;;
+208B;SUBSCRIPT MINUS;Sm;0;ES;<sub> 2212;;;;N;SUBSCRIPT HYPHEN-MINUS;;;;
+208C;SUBSCRIPT EQUALS SIGN;Sm;0;ON;<sub> 003D;;;;N;;;;;
+208D;SUBSCRIPT LEFT PARENTHESIS;Ps;0;ON;<sub> 0028;;;;Y;SUBSCRIPT OPENING PARENTHESIS;;;;
+208E;SUBSCRIPT RIGHT PARENTHESIS;Pe;0;ON;<sub> 0029;;;;Y;SUBSCRIPT CLOSING PARENTHESIS;;;;
+2090;LATIN SUBSCRIPT SMALL LETTER A;Lm;0;L;<sub> 0061;;;;N;;;;;
+2091;LATIN SUBSCRIPT SMALL LETTER E;Lm;0;L;<sub> 0065;;;;N;;;;;
+2092;LATIN SUBSCRIPT SMALL LETTER O;Lm;0;L;<sub> 006F;;;;N;;;;;
+2093;LATIN SUBSCRIPT SMALL LETTER X;Lm;0;L;<sub> 0078;;;;N;;;;;
+2094;LATIN SUBSCRIPT SMALL LETTER SCHWA;Lm;0;L;<sub> 0259;;;;N;;;;;
+2095;LATIN SUBSCRIPT SMALL LETTER H;Lm;0;L;<sub> 0068;;;;N;;;;;
+2096;LATIN SUBSCRIPT SMALL LETTER K;Lm;0;L;<sub> 006B;;;;N;;;;;
+2097;LATIN SUBSCRIPT SMALL LETTER L;Lm;0;L;<sub> 006C;;;;N;;;;;
+2098;LATIN SUBSCRIPT SMALL LETTER M;Lm;0;L;<sub> 006D;;;;N;;;;;
+2099;LATIN SUBSCRIPT SMALL LETTER N;Lm;0;L;<sub> 006E;;;;N;;;;;
+209A;LATIN SUBSCRIPT SMALL LETTER P;Lm;0;L;<sub> 0070;;;;N;;;;;
+209B;LATIN SUBSCRIPT SMALL LETTER S;Lm;0;L;<sub> 0073;;;;N;;;;;
+209C;LATIN SUBSCRIPT SMALL LETTER T;Lm;0;L;<sub> 0074;;;;N;;;;;
+20A0;EURO-CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;
+20A1;COLON SIGN;Sc;0;ET;;;;;N;;;;;
+20A2;CRUZEIRO SIGN;Sc;0;ET;;;;;N;;;;;
+20A3;FRENCH FRANC SIGN;Sc;0;ET;;;;;N;;;;;
+20A4;LIRA SIGN;Sc;0;ET;;;;;N;;;;;
+20A5;MILL SIGN;Sc;0;ET;;;;;N;;;;;
+20A6;NAIRA SIGN;Sc;0;ET;;;;;N;;;;;
+20A7;PESETA SIGN;Sc;0;ET;;;;;N;;;;;
+20A8;RUPEE SIGN;Sc;0;ET;<compat> 0052 0073;;;;N;;;;;
+20A9;WON SIGN;Sc;0;ET;;;;;N;;;;;
+20AA;NEW SHEQEL SIGN;Sc;0;ET;;;;;N;;;;;
+20AB;DONG SIGN;Sc;0;ET;;;;;N;;;;;
+20AC;EURO SIGN;Sc;0;ET;;;;;N;;;;;
+20AD;KIP SIGN;Sc;0;ET;;;;;N;;;;;
+20AE;TUGRIK SIGN;Sc;0;ET;;;;;N;;;;;
+20AF;DRACHMA SIGN;Sc;0;ET;;;;;N;;;;;
+20B0;GERMAN PENNY SIGN;Sc;0;ET;;;;;N;;;;;
+20B1;PESO SIGN;Sc;0;ET;;;;;N;;;;;
+20B2;GUARANI SIGN;Sc;0;ET;;;;;N;;;;;
+20B3;AUSTRAL SIGN;Sc;0;ET;;;;;N;;;;;
+20B4;HRYVNIA SIGN;Sc;0;ET;;;;;N;;;;;
+20B5;CEDI SIGN;Sc;0;ET;;;;;N;;;;;
+20B6;LIVRE TOURNOIS SIGN;Sc;0;ET;;;;;N;;;;;
+20B7;SPESMILO SIGN;Sc;0;ET;;;;;N;;;;;
+20B8;TENGE SIGN;Sc;0;ET;;;;;N;;;;;
+20B9;INDIAN RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
+20BA;TURKISH LIRA SIGN;Sc;0;ET;;;;;N;;;;;
+20BB;NORDIC MARK SIGN;Sc;0;ET;;;;;N;;;;;
+20BC;MANAT SIGN;Sc;0;ET;;;;;N;;;;;
+20BD;RUBLE SIGN;Sc;0;ET;;;;;N;;;;;
+20BE;LARI SIGN;Sc;0;ET;;;;;N;;;;;
+20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;;
+20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;;
+20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;;
+20D3;COMBINING SHORT VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT VERTICAL BAR OVERLAY;;;;
+20D4;COMBINING ANTICLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING ANTICLOCKWISE ARROW ABOVE;;;;
+20D5;COMBINING CLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING CLOCKWISE ARROW ABOVE;;;;
+20D6;COMBINING LEFT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT ARROW ABOVE;;;;
+20D7;COMBINING RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT ARROW ABOVE;;;;
+20D8;COMBINING RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING RING OVERLAY;;;;
+20D9;COMBINING CLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING CLOCKWISE RING OVERLAY;;;;
+20DA;COMBINING ANTICLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING ANTICLOCKWISE RING OVERLAY;;;;
+20DB;COMBINING THREE DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING THREE DOTS ABOVE;;;;
+20DC;COMBINING FOUR DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING FOUR DOTS ABOVE;;;;
+20DD;COMBINING ENCLOSING CIRCLE;Me;0;NSM;;;;;N;ENCLOSING CIRCLE;;;;
+20DE;COMBINING ENCLOSING SQUARE;Me;0;NSM;;;;;N;ENCLOSING SQUARE;;;;
+20DF;COMBINING ENCLOSING DIAMOND;Me;0;NSM;;;;;N;ENCLOSING DIAMOND;;;;
+20E0;COMBINING ENCLOSING CIRCLE BACKSLASH;Me;0;NSM;;;;;N;ENCLOSING CIRCLE SLASH;;;;
+20E1;COMBINING LEFT RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT RIGHT ARROW ABOVE;;;;
+20E2;COMBINING ENCLOSING SCREEN;Me;0;NSM;;;;;N;;;;;
+20E3;COMBINING ENCLOSING KEYCAP;Me;0;NSM;;;;;N;;;;;
+20E4;COMBINING ENCLOSING UPWARD POINTING TRIANGLE;Me;0;NSM;;;;;N;;;;;
+20E5;COMBINING REVERSE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;;
+20E6;COMBINING DOUBLE VERTICAL STROKE OVERLAY;Mn;1;NSM;;;;;N;;;;;
+20E7;COMBINING ANNUITY SYMBOL;Mn;230;NSM;;;;;N;;;;;
+20E8;COMBINING TRIPLE UNDERDOT;Mn;220;NSM;;;;;N;;;;;
+20E9;COMBINING WIDE BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;;
+20EA;COMBINING LEFTWARDS ARROW OVERLAY;Mn;1;NSM;;;;;N;;;;;
+20EB;COMBINING LONG DOUBLE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;;
+20EC;COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;;
+20ED;COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;;
+20EE;COMBINING LEFT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
+20EF;COMBINING RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
+20F0;COMBINING ASTERISK ABOVE;Mn;230;NSM;;;;;N;;;;;
+2100;ACCOUNT OF;So;0;ON;<compat> 0061 002F 0063;;;;N;;;;;
+2101;ADDRESSED TO THE SUBJECT;So;0;ON;<compat> 0061 002F 0073;;;;N;;;;;
+2102;DOUBLE-STRUCK CAPITAL C;Lu;0;L;<font> 0043;;;;N;DOUBLE-STRUCK C;;;;
+2103;DEGREE CELSIUS;So;0;ON;<compat> 00B0 0043;;;;N;DEGREES CENTIGRADE;;;;
+2104;CENTRE LINE SYMBOL;So;0;ON;;;;;N;C L SYMBOL;;;;
+2105;CARE OF;So;0;ON;<compat> 0063 002F 006F;;;;N;;;;;
+2106;CADA UNA;So;0;ON;<compat> 0063 002F 0075;;;;N;;;;;
+2107;EULER CONSTANT;Lu;0;L;<compat> 0190;;;;N;EULERS;;;;
+2108;SCRUPLE;So;0;ON;;;;;N;;;;;
+2109;DEGREE FAHRENHEIT;So;0;ON;<compat> 00B0 0046;;;;N;DEGREES FAHRENHEIT;;;;
+210A;SCRIPT SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+210B;SCRIPT CAPITAL H;Lu;0;L;<font> 0048;;;;N;SCRIPT H;;;;
+210C;BLACK-LETTER CAPITAL H;Lu;0;L;<font> 0048;;;;N;BLACK-LETTER H;;;;
+210D;DOUBLE-STRUCK CAPITAL H;Lu;0;L;<font> 0048;;;;N;DOUBLE-STRUCK H;;;;
+210E;PLANCK CONSTANT;Ll;0;L;<font> 0068;;;;N;;;;;
+210F;PLANCK CONSTANT OVER TWO PI;Ll;0;L;<font> 0127;;;;N;PLANCK CONSTANT OVER 2 PI;;;;
+2110;SCRIPT CAPITAL I;Lu;0;L;<font> 0049;;;;N;SCRIPT I;;;;
+2111;BLACK-LETTER CAPITAL I;Lu;0;L;<font> 0049;;;;N;BLACK-LETTER I;;;;
+2112;SCRIPT CAPITAL L;Lu;0;L;<font> 004C;;;;N;SCRIPT L;;;;
+2113;SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+2114;L B BAR SYMBOL;So;0;ON;;;;;N;;;;;
+2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L;<font> 004E;;;;N;DOUBLE-STRUCK N;;;;
+2116;NUMERO SIGN;So;0;ON;<compat> 004E 006F;;;;N;NUMERO;;;;
+2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;;
+2118;SCRIPT CAPITAL P;Sm;0;ON;;;;;N;SCRIPT P;;;;
+2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L;<font> 0050;;;;N;DOUBLE-STRUCK P;;;;
+211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L;<font> 0051;;;;N;DOUBLE-STRUCK Q;;;;
+211B;SCRIPT CAPITAL R;Lu;0;L;<font> 0052;;;;N;SCRIPT R;;;;
+211C;BLACK-LETTER CAPITAL R;Lu;0;L;<font> 0052;;;;N;BLACK-LETTER R;;;;
+211D;DOUBLE-STRUCK CAPITAL R;Lu;0;L;<font> 0052;;;;N;DOUBLE-STRUCK R;;;;
+211E;PRESCRIPTION TAKE;So;0;ON;;;;;N;;;;;
+211F;RESPONSE;So;0;ON;;;;;N;;;;;
+2120;SERVICE MARK;So;0;ON;<super> 0053 004D;;;;N;;;;;
+2121;TELEPHONE SIGN;So;0;ON;<compat> 0054 0045 004C;;;;N;T E L SYMBOL;;;;
+2122;TRADE MARK SIGN;So;0;ON;<super> 0054 004D;;;;N;TRADEMARK;;;;
+2123;VERSICLE;So;0;ON;;;;;N;;;;;
+2124;DOUBLE-STRUCK CAPITAL Z;Lu;0;L;<font> 005A;;;;N;DOUBLE-STRUCK Z;;;;
+2125;OUNCE SIGN;So;0;ON;;;;;N;OUNCE;;;;
+2126;OHM SIGN;Lu;0;L;03A9;;;;N;OHM;;;03C9;
+2127;INVERTED OHM SIGN;So;0;ON;;;;;N;MHO;;;;
+2128;BLACK-LETTER CAPITAL Z;Lu;0;L;<font> 005A;;;;N;BLACK-LETTER Z;;;;
+2129;TURNED GREEK SMALL LETTER IOTA;So;0;ON;;;;;N;;;;;
+212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B;
+212B;ANGSTROM SIGN;Lu;0;L;00C5;;;;N;ANGSTROM UNIT;;;00E5;
+212C;SCRIPT CAPITAL B;Lu;0;L;<font> 0042;;;;N;SCRIPT B;;;;
+212D;BLACK-LETTER CAPITAL C;Lu;0;L;<font> 0043;;;;N;BLACK-LETTER C;;;;
+212E;ESTIMATED SYMBOL;So;0;ET;;;;;N;;;;;
+212F;SCRIPT SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+2130;SCRIPT CAPITAL E;Lu;0;L;<font> 0045;;;;N;SCRIPT E;;;;
+2131;SCRIPT CAPITAL F;Lu;0;L;<font> 0046;;;;N;SCRIPT F;;;;
+2132;TURNED CAPITAL F;Lu;0;L;;;;;N;TURNED F;;;214E;
+2133;SCRIPT CAPITAL M;Lu;0;L;<font> 004D;;;;N;SCRIPT M;;;;
+2134;SCRIPT SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+2135;ALEF SYMBOL;Lo;0;L;<compat> 05D0;;;;N;FIRST TRANSFINITE CARDINAL;;;;
+2136;BET SYMBOL;Lo;0;L;<compat> 05D1;;;;N;SECOND TRANSFINITE CARDINAL;;;;
+2137;GIMEL SYMBOL;Lo;0;L;<compat> 05D2;;;;N;THIRD TRANSFINITE CARDINAL;;;;
+2138;DALET SYMBOL;Lo;0;L;<compat> 05D3;;;;N;FOURTH TRANSFINITE CARDINAL;;;;
+2139;INFORMATION SOURCE;Ll;0;L;<font> 0069;;;;N;;;;;
+213A;ROTATED CAPITAL Q;So;0;ON;;;;;N;;;;;
+213B;FACSIMILE SIGN;So;0;ON;<compat> 0046 0041 0058;;;;N;;;;;
+213C;DOUBLE-STRUCK SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+213D;DOUBLE-STRUCK SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+213E;DOUBLE-STRUCK CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+213F;DOUBLE-STRUCK CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+2140;DOUBLE-STRUCK N-ARY SUMMATION;Sm;0;ON;<font> 2211;;;;Y;;;;;
+2141;TURNED SANS-SERIF CAPITAL G;Sm;0;ON;;;;;N;;;;;
+2142;TURNED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;;
+2143;REVERSED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;;
+2144;TURNED SANS-SERIF CAPITAL Y;Sm;0;ON;;;;;N;;;;;
+2145;DOUBLE-STRUCK ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+2146;DOUBLE-STRUCK ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+2147;DOUBLE-STRUCK ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+2148;DOUBLE-STRUCK ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+2149;DOUBLE-STRUCK ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+214A;PROPERTY LINE;So;0;ON;;;;;N;;;;;
+214B;TURNED AMPERSAND;Sm;0;ON;;;;;N;;;;;
+214C;PER SIGN;So;0;ON;;;;;N;;;;;
+214D;AKTIESELSKAB;So;0;ON;;;;;N;;;;;
+214E;TURNED SMALL F;Ll;0;L;;;;;N;;;2132;;2132
+214F;SYMBOL FOR SAMARITAN SOURCE;So;0;L;;;;;N;;;;;
+2150;VULGAR FRACTION ONE SEVENTH;No;0;ON;<fraction> 0031 2044 0037;;;1/7;N;;;;;
+2151;VULGAR FRACTION ONE NINTH;No;0;ON;<fraction> 0031 2044 0039;;;1/9;N;;;;;
+2152;VULGAR FRACTION ONE TENTH;No;0;ON;<fraction> 0031 2044 0031 0030;;;1/10;N;;;;;
+2153;VULGAR FRACTION ONE THIRD;No;0;ON;<fraction> 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;;
+2154;VULGAR FRACTION TWO THIRDS;No;0;ON;<fraction> 0032 2044 0033;;;2/3;N;FRACTION TWO THIRDS;;;;
+2155;VULGAR FRACTION ONE FIFTH;No;0;ON;<fraction> 0031 2044 0035;;;1/5;N;FRACTION ONE FIFTH;;;;
+2156;VULGAR FRACTION TWO FIFTHS;No;0;ON;<fraction> 0032 2044 0035;;;2/5;N;FRACTION TWO FIFTHS;;;;
+2157;VULGAR FRACTION THREE FIFTHS;No;0;ON;<fraction> 0033 2044 0035;;;3/5;N;FRACTION THREE FIFTHS;;;;
+2158;VULGAR FRACTION FOUR FIFTHS;No;0;ON;<fraction> 0034 2044 0035;;;4/5;N;FRACTION FOUR FIFTHS;;;;
+2159;VULGAR FRACTION ONE SIXTH;No;0;ON;<fraction> 0031 2044 0036;;;1/6;N;FRACTION ONE SIXTH;;;;
+215A;VULGAR FRACTION FIVE SIXTHS;No;0;ON;<fraction> 0035 2044 0036;;;5/6;N;FRACTION FIVE SIXTHS;;;;
+215B;VULGAR FRACTION ONE EIGHTH;No;0;ON;<fraction> 0031 2044 0038;;;1/8;N;FRACTION ONE EIGHTH;;;;
+215C;VULGAR FRACTION THREE EIGHTHS;No;0;ON;<fraction> 0033 2044 0038;;;3/8;N;FRACTION THREE EIGHTHS;;;;
+215D;VULGAR FRACTION FIVE EIGHTHS;No;0;ON;<fraction> 0035 2044 0038;;;5/8;N;FRACTION FIVE EIGHTHS;;;;
+215E;VULGAR FRACTION SEVEN EIGHTHS;No;0;ON;<fraction> 0037 2044 0038;;;7/8;N;FRACTION SEVEN EIGHTHS;;;;
+215F;FRACTION NUMERATOR ONE;No;0;ON;<fraction> 0031 2044;;;1;N;;;;;
+2160;ROMAN NUMERAL ONE;Nl;0;L;<compat> 0049;;;1;N;;;;2170;
+2161;ROMAN NUMERAL TWO;Nl;0;L;<compat> 0049 0049;;;2;N;;;;2171;
+2162;ROMAN NUMERAL THREE;Nl;0;L;<compat> 0049 0049 0049;;;3;N;;;;2172;
+2163;ROMAN NUMERAL FOUR;Nl;0;L;<compat> 0049 0056;;;4;N;;;;2173;
+2164;ROMAN NUMERAL FIVE;Nl;0;L;<compat> 0056;;;5;N;;;;2174;
+2165;ROMAN NUMERAL SIX;Nl;0;L;<compat> 0056 0049;;;6;N;;;;2175;
+2166;ROMAN NUMERAL SEVEN;Nl;0;L;<compat> 0056 0049 0049;;;7;N;;;;2176;
+2167;ROMAN NUMERAL EIGHT;Nl;0;L;<compat> 0056 0049 0049 0049;;;8;N;;;;2177;
+2168;ROMAN NUMERAL NINE;Nl;0;L;<compat> 0049 0058;;;9;N;;;;2178;
+2169;ROMAN NUMERAL TEN;Nl;0;L;<compat> 0058;;;10;N;;;;2179;
+216A;ROMAN NUMERAL ELEVEN;Nl;0;L;<compat> 0058 0049;;;11;N;;;;217A;
+216B;ROMAN NUMERAL TWELVE;Nl;0;L;<compat> 0058 0049 0049;;;12;N;;;;217B;
+216C;ROMAN NUMERAL FIFTY;Nl;0;L;<compat> 004C;;;50;N;;;;217C;
+216D;ROMAN NUMERAL ONE HUNDRED;Nl;0;L;<compat> 0043;;;100;N;;;;217D;
+216E;ROMAN NUMERAL FIVE HUNDRED;Nl;0;L;<compat> 0044;;;500;N;;;;217E;
+216F;ROMAN NUMERAL ONE THOUSAND;Nl;0;L;<compat> 004D;;;1000;N;;;;217F;
+2170;SMALL ROMAN NUMERAL ONE;Nl;0;L;<compat> 0069;;;1;N;;;2160;;2160
+2171;SMALL ROMAN NUMERAL TWO;Nl;0;L;<compat> 0069 0069;;;2;N;;;2161;;2161
+2172;SMALL ROMAN NUMERAL THREE;Nl;0;L;<compat> 0069 0069 0069;;;3;N;;;2162;;2162
+2173;SMALL ROMAN NUMERAL FOUR;Nl;0;L;<compat> 0069 0076;;;4;N;;;2163;;2163
+2174;SMALL ROMAN NUMERAL FIVE;Nl;0;L;<compat> 0076;;;5;N;;;2164;;2164
+2175;SMALL ROMAN NUMERAL SIX;Nl;0;L;<compat> 0076 0069;;;6;N;;;2165;;2165
+2176;SMALL ROMAN NUMERAL SEVEN;Nl;0;L;<compat> 0076 0069 0069;;;7;N;;;2166;;2166
+2177;SMALL ROMAN NUMERAL EIGHT;Nl;0;L;<compat> 0076 0069 0069 0069;;;8;N;;;2167;;2167
+2178;SMALL ROMAN NUMERAL NINE;Nl;0;L;<compat> 0069 0078;;;9;N;;;2168;;2168
+2179;SMALL ROMAN NUMERAL TEN;Nl;0;L;<compat> 0078;;;10;N;;;2169;;2169
+217A;SMALL ROMAN NUMERAL ELEVEN;Nl;0;L;<compat> 0078 0069;;;11;N;;;216A;;216A
+217B;SMALL ROMAN NUMERAL TWELVE;Nl;0;L;<compat> 0078 0069 0069;;;12;N;;;216B;;216B
+217C;SMALL ROMAN NUMERAL FIFTY;Nl;0;L;<compat> 006C;;;50;N;;;216C;;216C
+217D;SMALL ROMAN NUMERAL ONE HUNDRED;Nl;0;L;<compat> 0063;;;100;N;;;216D;;216D
+217E;SMALL ROMAN NUMERAL FIVE HUNDRED;Nl;0;L;<compat> 0064;;;500;N;;;216E;;216E
+217F;SMALL ROMAN NUMERAL ONE THOUSAND;Nl;0;L;<compat> 006D;;;1000;N;;;216F;;216F
+2180;ROMAN NUMERAL ONE THOUSAND C D;Nl;0;L;;;;1000;N;;;;;
+2181;ROMAN NUMERAL FIVE THOUSAND;Nl;0;L;;;;5000;N;;;;;
+2182;ROMAN NUMERAL TEN THOUSAND;Nl;0;L;;;;10000;N;;;;;
+2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Lu;0;L;;;;;N;;;;2184;
+2184;LATIN SMALL LETTER REVERSED C;Ll;0;L;;;;;N;;;2183;;2183
+2185;ROMAN NUMERAL SIX LATE FORM;Nl;0;L;;;;6;N;;;;;
+2186;ROMAN NUMERAL FIFTY EARLY FORM;Nl;0;L;;;;50;N;;;;;
+2187;ROMAN NUMERAL FIFTY THOUSAND;Nl;0;L;;;;50000;N;;;;;
+2188;ROMAN NUMERAL ONE HUNDRED THOUSAND;Nl;0;L;;;;100000;N;;;;;
+2189;VULGAR FRACTION ZERO THIRDS;No;0;ON;<fraction> 0030 2044 0033;;;0;N;;;;;
+218A;TURNED DIGIT TWO;So;0;ON;;;;;N;;;;;
+218B;TURNED DIGIT THREE;So;0;ON;;;;;N;;;;;
+2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;;
+2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;;
+2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;;
+2193;DOWNWARDS ARROW;Sm;0;ON;;;;;N;DOWN ARROW;;;;
+2194;LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;;
+2195;UP DOWN ARROW;So;0;ON;;;;;N;;;;;
+2196;NORTH WEST ARROW;So;0;ON;;;;;N;UPPER LEFT ARROW;;;;
+2197;NORTH EAST ARROW;So;0;ON;;;;;N;UPPER RIGHT ARROW;;;;
+2198;SOUTH EAST ARROW;So;0;ON;;;;;N;LOWER RIGHT ARROW;;;;
+2199;SOUTH WEST ARROW;So;0;ON;;;;;N;LOWER LEFT ARROW;;;;
+219A;LEFTWARDS ARROW WITH STROKE;Sm;0;ON;2190 0338;;;;N;LEFT ARROW WITH STROKE;;;;
+219B;RIGHTWARDS ARROW WITH STROKE;Sm;0;ON;2192 0338;;;;N;RIGHT ARROW WITH STROKE;;;;
+219C;LEFTWARDS WAVE ARROW;So;0;ON;;;;;N;LEFT WAVE ARROW;;;;
+219D;RIGHTWARDS WAVE ARROW;So;0;ON;;;;;N;RIGHT WAVE ARROW;;;;
+219E;LEFTWARDS TWO HEADED ARROW;So;0;ON;;;;;N;LEFT TWO HEADED ARROW;;;;
+219F;UPWARDS TWO HEADED ARROW;So;0;ON;;;;;N;UP TWO HEADED ARROW;;;;
+21A0;RIGHTWARDS TWO HEADED ARROW;Sm;0;ON;;;;;N;RIGHT TWO HEADED ARROW;;;;
+21A1;DOWNWARDS TWO HEADED ARROW;So;0;ON;;;;;N;DOWN TWO HEADED ARROW;;;;
+21A2;LEFTWARDS ARROW WITH TAIL;So;0;ON;;;;;N;LEFT ARROW WITH TAIL;;;;
+21A3;RIGHTWARDS ARROW WITH TAIL;Sm;0;ON;;;;;N;RIGHT ARROW WITH TAIL;;;;
+21A4;LEFTWARDS ARROW FROM BAR;So;0;ON;;;;;N;LEFT ARROW FROM BAR;;;;
+21A5;UPWARDS ARROW FROM BAR;So;0;ON;;;;;N;UP ARROW FROM BAR;;;;
+21A6;RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;RIGHT ARROW FROM BAR;;;;
+21A7;DOWNWARDS ARROW FROM BAR;So;0;ON;;;;;N;DOWN ARROW FROM BAR;;;;
+21A8;UP DOWN ARROW WITH BASE;So;0;ON;;;;;N;;;;;
+21A9;LEFTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;LEFT ARROW WITH HOOK;;;;
+21AA;RIGHTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;RIGHT ARROW WITH HOOK;;;;
+21AB;LEFTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;LEFT ARROW WITH LOOP;;;;
+21AC;RIGHTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;RIGHT ARROW WITH LOOP;;;;
+21AD;LEFT RIGHT WAVE ARROW;So;0;ON;;;;;N;;;;;
+21AE;LEFT RIGHT ARROW WITH STROKE;Sm;0;ON;2194 0338;;;;N;;;;;
+21AF;DOWNWARDS ZIGZAG ARROW;So;0;ON;;;;;N;DOWN ZIGZAG ARROW;;;;
+21B0;UPWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP LEFT;;;;
+21B1;UPWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP RIGHT;;;;
+21B2;DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP LEFT;;;;
+21B3;DOWNWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP RIGHT;;;;
+21B4;RIGHTWARDS ARROW WITH CORNER DOWNWARDS;So;0;ON;;;;;N;RIGHT ARROW WITH CORNER DOWN;;;;
+21B5;DOWNWARDS ARROW WITH CORNER LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH CORNER LEFT;;;;
+21B6;ANTICLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21B7;CLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21B8;NORTH WEST ARROW TO LONG BAR;So;0;ON;;;;;N;UPPER LEFT ARROW TO LONG BAR;;;;
+21B9;LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR OVER RIGHT ARROW TO BAR;;;;
+21BA;ANTICLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21BB;CLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
+21BC;LEFTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB UP;;;;
+21BD;LEFTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB DOWN;;;;
+21BE;UPWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB RIGHT;;;;
+21BF;UPWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB LEFT;;;;
+21C0;RIGHTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB UP;;;;
+21C1;RIGHTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB DOWN;;;;
+21C2;DOWNWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB RIGHT;;;;
+21C3;DOWNWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB LEFT;;;;
+21C4;RIGHTWARDS ARROW OVER LEFTWARDS ARROW;So;0;ON;;;;;N;RIGHT ARROW OVER LEFT ARROW;;;;
+21C5;UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW;So;0;ON;;;;;N;UP ARROW LEFT OF DOWN ARROW;;;;
+21C6;LEFTWARDS ARROW OVER RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT ARROW OVER RIGHT ARROW;;;;
+21C7;LEFTWARDS PAIRED ARROWS;So;0;ON;;;;;N;LEFT PAIRED ARROWS;;;;
+21C8;UPWARDS PAIRED ARROWS;So;0;ON;;;;;N;UP PAIRED ARROWS;;;;
+21C9;RIGHTWARDS PAIRED ARROWS;So;0;ON;;;;;N;RIGHT PAIRED ARROWS;;;;
+21CA;DOWNWARDS PAIRED ARROWS;So;0;ON;;;;;N;DOWN PAIRED ARROWS;;;;
+21CB;LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON;So;0;ON;;;;;N;LEFT HARPOON OVER RIGHT HARPOON;;;;
+21CC;RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON;So;0;ON;;;;;N;RIGHT HARPOON OVER LEFT HARPOON;;;;
+21CD;LEFTWARDS DOUBLE ARROW WITH STROKE;So;0;ON;21D0 0338;;;;N;LEFT DOUBLE ARROW WITH STROKE;;;;
+21CE;LEFT RIGHT DOUBLE ARROW WITH STROKE;Sm;0;ON;21D4 0338;;;;N;;;;;
+21CF;RIGHTWARDS DOUBLE ARROW WITH STROKE;Sm;0;ON;21D2 0338;;;;N;RIGHT DOUBLE ARROW WITH STROKE;;;;
+21D0;LEFTWARDS DOUBLE ARROW;So;0;ON;;;;;N;LEFT DOUBLE ARROW;;;;
+21D1;UPWARDS DOUBLE ARROW;So;0;ON;;;;;N;UP DOUBLE ARROW;;;;
+21D2;RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;RIGHT DOUBLE ARROW;;;;
+21D3;DOWNWARDS DOUBLE ARROW;So;0;ON;;;;;N;DOWN DOUBLE ARROW;;;;
+21D4;LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
+21D5;UP DOWN DOUBLE ARROW;So;0;ON;;;;;N;;;;;
+21D6;NORTH WEST DOUBLE ARROW;So;0;ON;;;;;N;UPPER LEFT DOUBLE ARROW;;;;
+21D7;NORTH EAST DOUBLE ARROW;So;0;ON;;;;;N;UPPER RIGHT DOUBLE ARROW;;;;
+21D8;SOUTH EAST DOUBLE ARROW;So;0;ON;;;;;N;LOWER RIGHT DOUBLE ARROW;;;;
+21D9;SOUTH WEST DOUBLE ARROW;So;0;ON;;;;;N;LOWER LEFT DOUBLE ARROW;;;;
+21DA;LEFTWARDS TRIPLE ARROW;So;0;ON;;;;;N;LEFT TRIPLE ARROW;;;;
+21DB;RIGHTWARDS TRIPLE ARROW;So;0;ON;;;;;N;RIGHT TRIPLE ARROW;;;;
+21DC;LEFTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;LEFT SQUIGGLE ARROW;;;;
+21DD;RIGHTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;RIGHT SQUIGGLE ARROW;;;;
+21DE;UPWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;UP ARROW WITH DOUBLE STROKE;;;;
+21DF;DOWNWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;DOWN ARROW WITH DOUBLE STROKE;;;;
+21E0;LEFTWARDS DASHED ARROW;So;0;ON;;;;;N;LEFT DASHED ARROW;;;;
+21E1;UPWARDS DASHED ARROW;So;0;ON;;;;;N;UP DASHED ARROW;;;;
+21E2;RIGHTWARDS DASHED ARROW;So;0;ON;;;;;N;RIGHT DASHED ARROW;;;;
+21E3;DOWNWARDS DASHED ARROW;So;0;ON;;;;;N;DOWN DASHED ARROW;;;;
+21E4;LEFTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR;;;;
+21E5;RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;RIGHT ARROW TO BAR;;;;
+21E6;LEFTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE LEFT ARROW;;;;
+21E7;UPWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE UP ARROW;;;;
+21E8;RIGHTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE RIGHT ARROW;;;;
+21E9;DOWNWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE DOWN ARROW;;;;
+21EA;UPWARDS WHITE ARROW FROM BAR;So;0;ON;;;;;N;WHITE UP ARROW FROM BAR;;;;
+21EB;UPWARDS WHITE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;;
+21EC;UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;;
+21ED;UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;
+21EE;UPWARDS WHITE DOUBLE ARROW;So;0;ON;;;;;N;;;;;
+21EF;UPWARDS WHITE DOUBLE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;;
+21F0;RIGHTWARDS WHITE ARROW FROM WALL;So;0;ON;;;;;N;;;;;
+21F1;NORTH WEST ARROW TO CORNER;So;0;ON;;;;;N;;;;;
+21F2;SOUTH EAST ARROW TO CORNER;So;0;ON;;;;;N;;;;;
+21F3;UP DOWN WHITE ARROW;So;0;ON;;;;;N;;;;;
+21F4;RIGHT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
+21F5;DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+21F6;THREE RIGHTWARDS ARROWS;Sm;0;ON;;;;;N;;;;;
+21F7;LEFTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21F8;RIGHTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21F9;LEFT RIGHT ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21FA;LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21FB;RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21FC;LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+21FD;LEFTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;
+21FE;RIGHTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;
+21FF;LEFT RIGHT OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;
+2200;FOR ALL;Sm;0;ON;;;;;N;;;;;
+2201;COMPLEMENT;Sm;0;ON;;;;;Y;;;;;
+2202;PARTIAL DIFFERENTIAL;Sm;0;ON;;;;;Y;;;;;
+2203;THERE EXISTS;Sm;0;ON;;;;;Y;;;;;
+2204;THERE DOES NOT EXIST;Sm;0;ON;2203 0338;;;;Y;;;;;
+2205;EMPTY SET;Sm;0;ON;;;;;N;;;;;
+2206;INCREMENT;Sm;0;ON;;;;;N;;;;;
+2207;NABLA;Sm;0;ON;;;;;N;;;;;
+2208;ELEMENT OF;Sm;0;ON;;;;;Y;;;;;
+2209;NOT AN ELEMENT OF;Sm;0;ON;2208 0338;;;;Y;;;;;
+220A;SMALL ELEMENT OF;Sm;0;ON;;;;;Y;;;;;
+220B;CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;;
+220C;DOES NOT CONTAIN AS MEMBER;Sm;0;ON;220B 0338;;;;Y;;;;;
+220D;SMALL CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;;
+220E;END OF PROOF;Sm;0;ON;;;;;N;;;;;
+220F;N-ARY PRODUCT;Sm;0;ON;;;;;N;;;;;
+2210;N-ARY COPRODUCT;Sm;0;ON;;;;;N;;;;;
+2211;N-ARY SUMMATION;Sm;0;ON;;;;;Y;;;;;
+2212;MINUS SIGN;Sm;0;ES;;;;;N;;;;;
+2213;MINUS-OR-PLUS SIGN;Sm;0;ET;;;;;N;;;;;
+2214;DOT PLUS;Sm;0;ON;;;;;N;;;;;
+2215;DIVISION SLASH;Sm;0;ON;;;;;Y;;;;;
+2216;SET MINUS;Sm;0;ON;;;;;Y;;;;;
+2217;ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;;
+2218;RING OPERATOR;Sm;0;ON;;;;;N;;;;;
+2219;BULLET OPERATOR;Sm;0;ON;;;;;N;;;;;
+221A;SQUARE ROOT;Sm;0;ON;;;;;Y;;;;;
+221B;CUBE ROOT;Sm;0;ON;;;;;Y;;;;;
+221C;FOURTH ROOT;Sm;0;ON;;;;;Y;;;;;
+221D;PROPORTIONAL TO;Sm;0;ON;;;;;Y;;;;;
+221E;INFINITY;Sm;0;ON;;;;;N;;;;;
+221F;RIGHT ANGLE;Sm;0;ON;;;;;Y;;;;;
+2220;ANGLE;Sm;0;ON;;;;;Y;;;;;
+2221;MEASURED ANGLE;Sm;0;ON;;;;;Y;;;;;
+2222;SPHERICAL ANGLE;Sm;0;ON;;;;;Y;;;;;
+2223;DIVIDES;Sm;0;ON;;;;;N;;;;;
+2224;DOES NOT DIVIDE;Sm;0;ON;2223 0338;;;;Y;;;;;
+2225;PARALLEL TO;Sm;0;ON;;;;;N;;;;;
+2226;NOT PARALLEL TO;Sm;0;ON;2225 0338;;;;Y;;;;;
+2227;LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+2228;LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+2229;INTERSECTION;Sm;0;ON;;;;;N;;;;;
+222A;UNION;Sm;0;ON;;;;;N;;;;;
+222B;INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+222C;DOUBLE INTEGRAL;Sm;0;ON;<compat> 222B 222B;;;;Y;;;;;
+222D;TRIPLE INTEGRAL;Sm;0;ON;<compat> 222B 222B 222B;;;;Y;;;;;
+222E;CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+222F;SURFACE INTEGRAL;Sm;0;ON;<compat> 222E 222E;;;;Y;;;;;
+2230;VOLUME INTEGRAL;Sm;0;ON;<compat> 222E 222E 222E;;;;Y;;;;;
+2231;CLOCKWISE INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2232;CLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2233;ANTICLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2234;THEREFORE;Sm;0;ON;;;;;N;;;;;
+2235;BECAUSE;Sm;0;ON;;;;;N;;;;;
+2236;RATIO;Sm;0;ON;;;;;N;;;;;
+2237;PROPORTION;Sm;0;ON;;;;;N;;;;;
+2238;DOT MINUS;Sm;0;ON;;;;;N;;;;;
+2239;EXCESS;Sm;0;ON;;;;;Y;;;;;
+223A;GEOMETRIC PROPORTION;Sm;0;ON;;;;;N;;;;;
+223B;HOMOTHETIC;Sm;0;ON;;;;;Y;;;;;
+223C;TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;;;;
+223E;INVERTED LAZY S;Sm;0;ON;;;;;Y;;;;;
+223F;SINE WAVE;Sm;0;ON;;;;;Y;;;;;
+2240;WREATH PRODUCT;Sm;0;ON;;;;;Y;;;;;
+2241;NOT TILDE;Sm;0;ON;223C 0338;;;;Y;;;;;
+2242;MINUS TILDE;Sm;0;ON;;;;;Y;;;;;
+2243;ASYMPTOTICALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2244;NOT ASYMPTOTICALLY EQUAL TO;Sm;0;ON;2243 0338;;;;Y;;;;;
+2245;APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2246;APPROXIMATELY BUT NOT ACTUALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2247;NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO;Sm;0;ON;2245 0338;;;;Y;;;;;
+2248;ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2249;NOT ALMOST EQUAL TO;Sm;0;ON;2248 0338;;;;Y;;;;;
+224A;ALMOST EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+224B;TRIPLE TILDE;Sm;0;ON;;;;;Y;;;;;
+224C;ALL EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+224D;EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
+224E;GEOMETRICALLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
+224F;DIFFERENCE BETWEEN;Sm;0;ON;;;;;N;;;;;
+2250;APPROACHES THE LIMIT;Sm;0;ON;;;;;N;;;;;
+2251;GEOMETRICALLY EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2252;APPROXIMATELY EQUAL TO OR THE IMAGE OF;Sm;0;ON;;;;;Y;;;;;
+2253;IMAGE OF OR APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2254;COLON EQUALS;Sm;0;ON;;;;;Y;COLON EQUAL;;;;
+2255;EQUALS COLON;Sm;0;ON;;;;;Y;EQUAL COLON;;;;
+2256;RING IN EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2257;RING EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2258;CORRESPONDS TO;Sm;0;ON;;;;;N;;;;;
+2259;ESTIMATES;Sm;0;ON;;;;;N;;;;;
+225A;EQUIANGULAR TO;Sm;0;ON;;;;;N;;;;;
+225B;STAR EQUALS;Sm;0;ON;;;;;N;;;;;
+225C;DELTA EQUAL TO;Sm;0;ON;;;;;N;;;;;
+225D;EQUAL TO BY DEFINITION;Sm;0;ON;;;;;N;;;;;
+225E;MEASURED BY;Sm;0;ON;;;;;N;;;;;
+225F;QUESTIONED EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2260;NOT EQUAL TO;Sm;0;ON;003D 0338;;;;Y;;;;;
+2261;IDENTICAL TO;Sm;0;ON;;;;;N;;;;;
+2262;NOT IDENTICAL TO;Sm;0;ON;2261 0338;;;;Y;;;;;
+2263;STRICTLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
+2264;LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUAL TO;;;;
+2265;GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUAL TO;;;;
+2266;LESS-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OVER EQUAL TO;;;;
+2267;GREATER-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OVER EQUAL TO;;;;
+2268;LESS-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUAL TO;;;;
+2269;GREATER-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUAL TO;;;;
+226A;MUCH LESS-THAN;Sm;0;ON;;;;;Y;MUCH LESS THAN;;;;
+226B;MUCH GREATER-THAN;Sm;0;ON;;;;;Y;MUCH GREATER THAN;;;;
+226C;BETWEEN;Sm;0;ON;;;;;N;;;;;
+226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;N;;;;;
+226E;NOT LESS-THAN;Sm;0;ON;003C 0338;;;;Y;NOT LESS THAN;;;;
+226F;NOT GREATER-THAN;Sm;0;ON;003E 0338;;;;Y;NOT GREATER THAN;;;;
+2270;NEITHER LESS-THAN NOR EQUAL TO;Sm;0;ON;2264 0338;;;;Y;NEITHER LESS THAN NOR EQUAL TO;;;;
+2271;NEITHER GREATER-THAN NOR EQUAL TO;Sm;0;ON;2265 0338;;;;Y;NEITHER GREATER THAN NOR EQUAL TO;;;;
+2272;LESS-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUIVALENT TO;;;;
+2273;GREATER-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUIVALENT TO;;;;
+2274;NEITHER LESS-THAN NOR EQUIVALENT TO;Sm;0;ON;2272 0338;;;;Y;NEITHER LESS THAN NOR EQUIVALENT TO;;;;
+2275;NEITHER GREATER-THAN NOR EQUIVALENT TO;Sm;0;ON;2273 0338;;;;Y;NEITHER GREATER THAN NOR EQUIVALENT TO;;;;
+2276;LESS-THAN OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN OR GREATER THAN;;;;
+2277;GREATER-THAN OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN OR LESS THAN;;;;
+2278;NEITHER LESS-THAN NOR GREATER-THAN;Sm;0;ON;2276 0338;;;;Y;NEITHER LESS THAN NOR GREATER THAN;;;;
+2279;NEITHER GREATER-THAN NOR LESS-THAN;Sm;0;ON;2277 0338;;;;Y;NEITHER GREATER THAN NOR LESS THAN;;;;
+227A;PRECEDES;Sm;0;ON;;;;;Y;;;;;
+227B;SUCCEEDS;Sm;0;ON;;;;;Y;;;;;
+227C;PRECEDES OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+227D;SUCCEEDS OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+227E;PRECEDES OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+227F;SUCCEEDS OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+2280;DOES NOT PRECEDE;Sm;0;ON;227A 0338;;;;Y;;;;;
+2281;DOES NOT SUCCEED;Sm;0;ON;227B 0338;;;;Y;;;;;
+2282;SUBSET OF;Sm;0;ON;;;;;Y;;;;;
+2283;SUPERSET OF;Sm;0;ON;;;;;Y;;;;;
+2284;NOT A SUBSET OF;Sm;0;ON;2282 0338;;;;Y;;;;;
+2285;NOT A SUPERSET OF;Sm;0;ON;2283 0338;;;;Y;;;;;
+2286;SUBSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2287;SUPERSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2288;NEITHER A SUBSET OF NOR EQUAL TO;Sm;0;ON;2286 0338;;;;Y;;;;;
+2289;NEITHER A SUPERSET OF NOR EQUAL TO;Sm;0;ON;2287 0338;;;;Y;;;;;
+228A;SUBSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUBSET OF OR NOT EQUAL TO;;;;
+228B;SUPERSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUPERSET OF OR NOT EQUAL TO;;;;
+228C;MULTISET;Sm;0;ON;;;;;Y;;;;;
+228D;MULTISET MULTIPLICATION;Sm;0;ON;;;;;N;;;;;
+228E;MULTISET UNION;Sm;0;ON;;;;;N;;;;;
+228F;SQUARE IMAGE OF;Sm;0;ON;;;;;Y;;;;;
+2290;SQUARE ORIGINAL OF;Sm;0;ON;;;;;Y;;;;;
+2291;SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2292;SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2293;SQUARE CAP;Sm;0;ON;;;;;N;;;;;
+2294;SQUARE CUP;Sm;0;ON;;;;;N;;;;;
+2295;CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;
+2296;CIRCLED MINUS;Sm;0;ON;;;;;N;;;;;
+2297;CIRCLED TIMES;Sm;0;ON;;;;;N;;;;;
+2298;CIRCLED DIVISION SLASH;Sm;0;ON;;;;;Y;;;;;
+2299;CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
+229A;CIRCLED RING OPERATOR;Sm;0;ON;;;;;N;;;;;
+229B;CIRCLED ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;;
+229C;CIRCLED EQUALS;Sm;0;ON;;;;;N;;;;;
+229D;CIRCLED DASH;Sm;0;ON;;;;;N;;;;;
+229E;SQUARED PLUS;Sm;0;ON;;;;;N;;;;;
+229F;SQUARED MINUS;Sm;0;ON;;;;;N;;;;;
+22A0;SQUARED TIMES;Sm;0;ON;;;;;N;;;;;
+22A1;SQUARED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
+22A2;RIGHT TACK;Sm;0;ON;;;;;Y;;;;;
+22A3;LEFT TACK;Sm;0;ON;;;;;Y;;;;;
+22A4;DOWN TACK;Sm;0;ON;;;;;N;;;;;
+22A5;UP TACK;Sm;0;ON;;;;;N;;;;;
+22A6;ASSERTION;Sm;0;ON;;;;;Y;;;;;
+22A7;MODELS;Sm;0;ON;;;;;Y;;;;;
+22A8;TRUE;Sm;0;ON;;;;;Y;;;;;
+22A9;FORCES;Sm;0;ON;;;;;Y;;;;;
+22AA;TRIPLE VERTICAL BAR RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+22AB;DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+22AC;DOES NOT PROVE;Sm;0;ON;22A2 0338;;;;Y;;;;;
+22AD;NOT TRUE;Sm;0;ON;22A8 0338;;;;Y;;;;;
+22AE;DOES NOT FORCE;Sm;0;ON;22A9 0338;;;;Y;;;;;
+22AF;NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;22AB 0338;;;;Y;;;;;
+22B0;PRECEDES UNDER RELATION;Sm;0;ON;;;;;Y;;;;;
+22B1;SUCCEEDS UNDER RELATION;Sm;0;ON;;;;;Y;;;;;
+22B2;NORMAL SUBGROUP OF;Sm;0;ON;;;;;Y;;;;;
+22B3;CONTAINS AS NORMAL SUBGROUP;Sm;0;ON;;;;;Y;;;;;
+22B4;NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22B5;CONTAINS AS NORMAL SUBGROUP OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22B6;ORIGINAL OF;Sm;0;ON;;;;;Y;;;;;
+22B7;IMAGE OF;Sm;0;ON;;;;;Y;;;;;
+22B8;MULTIMAP;Sm;0;ON;;;;;Y;;;;;
+22B9;HERMITIAN CONJUGATE MATRIX;Sm;0;ON;;;;;N;;;;;
+22BA;INTERCALATE;Sm;0;ON;;;;;N;;;;;
+22BB;XOR;Sm;0;ON;;;;;N;;;;;
+22BC;NAND;Sm;0;ON;;;;;N;;;;;
+22BD;NOR;Sm;0;ON;;;;;N;;;;;
+22BE;RIGHT ANGLE WITH ARC;Sm;0;ON;;;;;Y;;;;;
+22BF;RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;;
+22C0;N-ARY LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+22C1;N-ARY LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+22C2;N-ARY INTERSECTION;Sm;0;ON;;;;;N;;;;;
+22C3;N-ARY UNION;Sm;0;ON;;;;;N;;;;;
+22C4;DIAMOND OPERATOR;Sm;0;ON;;;;;N;;;;;
+22C5;DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
+22C6;STAR OPERATOR;Sm;0;ON;;;;;N;;;;;
+22C7;DIVISION TIMES;Sm;0;ON;;;;;N;;;;;
+22C8;BOWTIE;Sm;0;ON;;;;;N;;;;;
+22C9;LEFT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CA;RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CB;LEFT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CC;RIGHT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
+22CD;REVERSED TILDE EQUALS;Sm;0;ON;;;;;Y;;;;;
+22CE;CURLY LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+22CF;CURLY LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+22D0;DOUBLE SUBSET;Sm;0;ON;;;;;Y;;;;;
+22D1;DOUBLE SUPERSET;Sm;0;ON;;;;;Y;;;;;
+22D2;DOUBLE INTERSECTION;Sm;0;ON;;;;;N;;;;;
+22D3;DOUBLE UNION;Sm;0;ON;;;;;N;;;;;
+22D4;PITCHFORK;Sm;0;ON;;;;;N;;;;;
+22D5;EQUAL AND PARALLEL TO;Sm;0;ON;;;;;N;;;;;
+22D6;LESS-THAN WITH DOT;Sm;0;ON;;;;;Y;LESS THAN WITH DOT;;;;
+22D7;GREATER-THAN WITH DOT;Sm;0;ON;;;;;Y;GREATER THAN WITH DOT;;;;
+22D8;VERY MUCH LESS-THAN;Sm;0;ON;;;;;Y;VERY MUCH LESS THAN;;;;
+22D9;VERY MUCH GREATER-THAN;Sm;0;ON;;;;;Y;VERY MUCH GREATER THAN;;;;
+22DA;LESS-THAN EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN EQUAL TO OR GREATER THAN;;;;
+22DB;GREATER-THAN EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN EQUAL TO OR LESS THAN;;;;
+22DC;EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR LESS THAN;;;;
+22DD;EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR GREATER THAN;;;;
+22DE;EQUAL TO OR PRECEDES;Sm;0;ON;;;;;Y;;;;;
+22DF;EQUAL TO OR SUCCEEDS;Sm;0;ON;;;;;Y;;;;;
+22E0;DOES NOT PRECEDE OR EQUAL;Sm;0;ON;227C 0338;;;;Y;;;;;
+22E1;DOES NOT SUCCEED OR EQUAL;Sm;0;ON;227D 0338;;;;Y;;;;;
+22E2;NOT SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;2291 0338;;;;Y;;;;;
+22E3;NOT SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;2292 0338;;;;Y;;;;;
+22E4;SQUARE IMAGE OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22E5;SQUARE ORIGINAL OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+22E6;LESS-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUIVALENT TO;;;;
+22E7;GREATER-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUIVALENT TO;;;;
+22E8;PRECEDES BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+22E9;SUCCEEDS BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
+22EA;NOT NORMAL SUBGROUP OF;Sm;0;ON;22B2 0338;;;;Y;;;;;
+22EB;DOES NOT CONTAIN AS NORMAL SUBGROUP;Sm;0;ON;22B3 0338;;;;Y;;;;;
+22EC;NOT NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;22B4 0338;;;;Y;;;;;
+22ED;DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL;Sm;0;ON;22B5 0338;;;;Y;;;;;
+22EE;VERTICAL ELLIPSIS;Sm;0;ON;;;;;N;;;;;
+22EF;MIDLINE HORIZONTAL ELLIPSIS;Sm;0;ON;;;;;N;;;;;
+22F0;UP RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;;
+22F1;DOWN RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;;
+22F2;ELEMENT OF WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22F3;ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22F4;SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22F5;ELEMENT OF WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+22F6;ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+22F7;SMALL ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+22F8;ELEMENT OF WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
+22F9;ELEMENT OF WITH TWO HORIZONTAL STROKES;Sm;0;ON;;;;;Y;;;;;
+22FA;CONTAINS WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22FB;CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22FC;SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+22FD;CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+22FE;SMALL CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+22FF;Z NOTATION BAG MEMBERSHIP;Sm;0;ON;;;;;Y;;;;;
+2300;DIAMETER SIGN;So;0;ON;;;;;N;;;;;
+2301;ELECTRIC ARROW;So;0;ON;;;;;N;;;;;
+2302;HOUSE;So;0;ON;;;;;N;;;;;
+2303;UP ARROWHEAD;So;0;ON;;;;;N;;;;;
+2304;DOWN ARROWHEAD;So;0;ON;;;;;N;;;;;
+2305;PROJECTIVE;So;0;ON;;;;;N;;;;;
+2306;PERSPECTIVE;So;0;ON;;;;;N;;;;;
+2307;WAVY LINE;So;0;ON;;;;;N;;;;;
+2308;LEFT CEILING;Ps;0;ON;;;;;Y;;;;;
+2309;RIGHT CEILING;Pe;0;ON;;;;;Y;;;;;
+230A;LEFT FLOOR;Ps;0;ON;;;;;Y;;;;;
+230B;RIGHT FLOOR;Pe;0;ON;;;;;Y;;;;;
+230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;;
+230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;;
+230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;;
+230F;TOP LEFT CROP;So;0;ON;;;;;N;;;;;
+2310;REVERSED NOT SIGN;So;0;ON;;;;;N;;;;;
+2311;SQUARE LOZENGE;So;0;ON;;;;;N;;;;;
+2312;ARC;So;0;ON;;;;;N;;;;;
+2313;SEGMENT;So;0;ON;;;;;N;;;;;
+2314;SECTOR;So;0;ON;;;;;N;;;;;
+2315;TELEPHONE RECORDER;So;0;ON;;;;;N;;;;;
+2316;POSITION INDICATOR;So;0;ON;;;;;N;;;;;
+2317;VIEWDATA SQUARE;So;0;ON;;;;;N;;;;;
+2318;PLACE OF INTEREST SIGN;So;0;ON;;;;;N;COMMAND KEY;;;;
+2319;TURNED NOT SIGN;So;0;ON;;;;;N;;;;;
+231A;WATCH;So;0;ON;;;;;N;;;;;
+231B;HOURGLASS;So;0;ON;;;;;N;;;;;
+231C;TOP LEFT CORNER;So;0;ON;;;;;N;;;;;
+231D;TOP RIGHT CORNER;So;0;ON;;;;;N;;;;;
+231E;BOTTOM LEFT CORNER;So;0;ON;;;;;N;;;;;
+231F;BOTTOM RIGHT CORNER;So;0;ON;;;;;N;;;;;
+2320;TOP HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2321;BOTTOM HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2322;FROWN;So;0;ON;;;;;N;;;;;
+2323;SMILE;So;0;ON;;;;;N;;;;;
+2324;UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS;So;0;ON;;;;;N;ENTER KEY;;;;
+2325;OPTION KEY;So;0;ON;;;;;N;;;;;
+2326;ERASE TO THE RIGHT;So;0;ON;;;;;N;DELETE TO THE RIGHT KEY;;;;
+2327;X IN A RECTANGLE BOX;So;0;ON;;;;;N;CLEAR KEY;;;;
+2328;KEYBOARD;So;0;ON;;;;;N;;;;;
+2329;LEFT-POINTING ANGLE BRACKET;Ps;0;ON;3008;;;;Y;BRA;;;;
+232A;RIGHT-POINTING ANGLE BRACKET;Pe;0;ON;3009;;;;Y;KET;;;;
+232B;ERASE TO THE LEFT;So;0;ON;;;;;N;DELETE TO THE LEFT KEY;;;;
+232C;BENZENE RING;So;0;ON;;;;;N;;;;;
+232D;CYLINDRICITY;So;0;ON;;;;;N;;;;;
+232E;ALL AROUND-PROFILE;So;0;ON;;;;;N;;;;;
+232F;SYMMETRY;So;0;ON;;;;;N;;;;;
+2330;TOTAL RUNOUT;So;0;ON;;;;;N;;;;;
+2331;DIMENSION ORIGIN;So;0;ON;;;;;N;;;;;
+2332;CONICAL TAPER;So;0;ON;;;;;N;;;;;
+2333;SLOPE;So;0;ON;;;;;N;;;;;
+2334;COUNTERBORE;So;0;ON;;;;;N;;;;;
+2335;COUNTERSINK;So;0;ON;;;;;N;;;;;
+2336;APL FUNCTIONAL SYMBOL I-BEAM;So;0;L;;;;;N;;;;;
+2337;APL FUNCTIONAL SYMBOL SQUISH QUAD;So;0;L;;;;;N;;;;;
+2338;APL FUNCTIONAL SYMBOL QUAD EQUAL;So;0;L;;;;;N;;;;;
+2339;APL FUNCTIONAL SYMBOL QUAD DIVIDE;So;0;L;;;;;N;;;;;
+233A;APL FUNCTIONAL SYMBOL QUAD DIAMOND;So;0;L;;;;;N;;;;;
+233B;APL FUNCTIONAL SYMBOL QUAD JOT;So;0;L;;;;;N;;;;;
+233C;APL FUNCTIONAL SYMBOL QUAD CIRCLE;So;0;L;;;;;N;;;;;
+233D;APL FUNCTIONAL SYMBOL CIRCLE STILE;So;0;L;;;;;N;;;;;
+233E;APL FUNCTIONAL SYMBOL CIRCLE JOT;So;0;L;;;;;N;;;;;
+233F;APL FUNCTIONAL SYMBOL SLASH BAR;So;0;L;;;;;N;;;;;
+2340;APL FUNCTIONAL SYMBOL BACKSLASH BAR;So;0;L;;;;;N;;;;;
+2341;APL FUNCTIONAL SYMBOL QUAD SLASH;So;0;L;;;;;N;;;;;
+2342;APL FUNCTIONAL SYMBOL QUAD BACKSLASH;So;0;L;;;;;N;;;;;
+2343;APL FUNCTIONAL SYMBOL QUAD LESS-THAN;So;0;L;;;;;N;;;;;
+2344;APL FUNCTIONAL SYMBOL QUAD GREATER-THAN;So;0;L;;;;;N;;;;;
+2345;APL FUNCTIONAL SYMBOL LEFTWARDS VANE;So;0;L;;;;;N;;;;;
+2346;APL FUNCTIONAL SYMBOL RIGHTWARDS VANE;So;0;L;;;;;N;;;;;
+2347;APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW;So;0;L;;;;;N;;;;;
+2348;APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW;So;0;L;;;;;N;;;;;
+2349;APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH;So;0;L;;;;;N;;;;;
+234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;;;;
+234B;APL FUNCTIONAL SYMBOL DELTA STILE;So;0;L;;;;;N;;;;;
+234C;APL FUNCTIONAL SYMBOL QUAD DOWN CARET;So;0;L;;;;;N;;;;;
+234D;APL FUNCTIONAL SYMBOL QUAD DELTA;So;0;L;;;;;N;;;;;
+234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;;;;
+234F;APL FUNCTIONAL SYMBOL UPWARDS VANE;So;0;L;;;;;N;;;;;
+2350;APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW;So;0;L;;;;;N;;;;;
+2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;;;;
+2352;APL FUNCTIONAL SYMBOL DEL STILE;So;0;L;;;;;N;;;;;
+2353;APL FUNCTIONAL SYMBOL QUAD UP CARET;So;0;L;;;;;N;;;;;
+2354;APL FUNCTIONAL SYMBOL QUAD DEL;So;0;L;;;;;N;;;;;
+2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;;;;
+2356;APL FUNCTIONAL SYMBOL DOWNWARDS VANE;So;0;L;;;;;N;;;;;
+2357;APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW;So;0;L;;;;;N;;;;;
+2358;APL FUNCTIONAL SYMBOL QUOTE UNDERBAR;So;0;L;;;;;N;;;;;
+2359;APL FUNCTIONAL SYMBOL DELTA UNDERBAR;So;0;L;;;;;N;;;;;
+235A;APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR;So;0;L;;;;;N;;;;;
+235B;APL FUNCTIONAL SYMBOL JOT UNDERBAR;So;0;L;;;;;N;;;;;
+235C;APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR;So;0;L;;;;;N;;;;;
+235D;APL FUNCTIONAL SYMBOL UP SHOE JOT;So;0;L;;;;;N;;;;;
+235E;APL FUNCTIONAL SYMBOL QUOTE QUAD;So;0;L;;;;;N;;;;;
+235F;APL FUNCTIONAL SYMBOL CIRCLE STAR;So;0;L;;;;;N;;;;;
+2360;APL FUNCTIONAL SYMBOL QUAD COLON;So;0;L;;;;;N;;;;;
+2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;;;;
+2362;APL FUNCTIONAL SYMBOL DEL DIAERESIS;So;0;L;;;;;N;;;;;
+2363;APL FUNCTIONAL SYMBOL STAR DIAERESIS;So;0;L;;;;;N;;;;;
+2364;APL FUNCTIONAL SYMBOL JOT DIAERESIS;So;0;L;;;;;N;;;;;
+2365;APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS;So;0;L;;;;;N;;;;;
+2366;APL FUNCTIONAL SYMBOL DOWN SHOE STILE;So;0;L;;;;;N;;;;;
+2367;APL FUNCTIONAL SYMBOL LEFT SHOE STILE;So;0;L;;;;;N;;;;;
+2368;APL FUNCTIONAL SYMBOL TILDE DIAERESIS;So;0;L;;;;;N;;;;;
+2369;APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS;So;0;L;;;;;N;;;;;
+236A;APL FUNCTIONAL SYMBOL COMMA BAR;So;0;L;;;;;N;;;;;
+236B;APL FUNCTIONAL SYMBOL DEL TILDE;So;0;L;;;;;N;;;;;
+236C;APL FUNCTIONAL SYMBOL ZILDE;So;0;L;;;;;N;;;;;
+236D;APL FUNCTIONAL SYMBOL STILE TILDE;So;0;L;;;;;N;;;;;
+236E;APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR;So;0;L;;;;;N;;;;;
+236F;APL FUNCTIONAL SYMBOL QUAD NOT EQUAL;So;0;L;;;;;N;;;;;
+2370;APL FUNCTIONAL SYMBOL QUAD QUESTION;So;0;L;;;;;N;;;;;
+2371;APL FUNCTIONAL SYMBOL DOWN CARET TILDE;So;0;L;;;;;N;;;;;
+2372;APL FUNCTIONAL SYMBOL UP CARET TILDE;So;0;L;;;;;N;;;;;
+2373;APL FUNCTIONAL SYMBOL IOTA;So;0;L;;;;;N;;;;;
+2374;APL FUNCTIONAL SYMBOL RHO;So;0;L;;;;;N;;;;;
+2375;APL FUNCTIONAL SYMBOL OMEGA;So;0;L;;;;;N;;;;;
+2376;APL FUNCTIONAL SYMBOL ALPHA UNDERBAR;So;0;L;;;;;N;;;;;
+2377;APL FUNCTIONAL SYMBOL EPSILON UNDERBAR;So;0;L;;;;;N;;;;;
+2378;APL FUNCTIONAL SYMBOL IOTA UNDERBAR;So;0;L;;;;;N;;;;;
+2379;APL FUNCTIONAL SYMBOL OMEGA UNDERBAR;So;0;L;;;;;N;;;;;
+237A;APL FUNCTIONAL SYMBOL ALPHA;So;0;L;;;;;N;;;;;
+237B;NOT CHECK MARK;So;0;ON;;;;;N;;;;;
+237C;RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW;Sm;0;ON;;;;;N;;;;;
+237D;SHOULDERED OPEN BOX;So;0;ON;;;;;N;;;;;
+237E;BELL SYMBOL;So;0;ON;;;;;N;;;;;
+237F;VERTICAL LINE WITH MIDDLE DOT;So;0;ON;;;;;N;;;;;
+2380;INSERTION SYMBOL;So;0;ON;;;;;N;;;;;
+2381;CONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;;
+2382;DISCONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;;
+2383;EMPHASIS SYMBOL;So;0;ON;;;;;N;;;;;
+2384;COMPOSITION SYMBOL;So;0;ON;;;;;N;;;;;
+2385;WHITE SQUARE WITH CENTRE VERTICAL LINE;So;0;ON;;;;;N;;;;;
+2386;ENTER SYMBOL;So;0;ON;;;;;N;;;;;
+2387;ALTERNATIVE KEY SYMBOL;So;0;ON;;;;;N;;;;;
+2388;HELM SYMBOL;So;0;ON;;;;;N;;;;;
+2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;;;;
+238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;;;;
+238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;;;;
+238C;UNDO SYMBOL;So;0;ON;;;;;N;;;;;
+238D;MONOSTABLE SYMBOL;So;0;ON;;;;;N;;;;;
+238E;HYSTERESIS SYMBOL;So;0;ON;;;;;N;;;;;
+238F;OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL;So;0;ON;;;;;N;;;;;
+2390;OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL;So;0;ON;;;;;N;;;;;
+2391;PASSIVE-PULL-DOWN-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;;
+2392;PASSIVE-PULL-UP-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;;
+2393;DIRECT CURRENT SYMBOL FORM TWO;So;0;ON;;;;;N;;;;;
+2394;SOFTWARE-FUNCTION SYMBOL;So;0;ON;;;;;N;;;;;
+2395;APL FUNCTIONAL SYMBOL QUAD;So;0;L;;;;;N;;;;;
+2396;DECIMAL SEPARATOR KEY SYMBOL;So;0;ON;;;;;N;;;;;
+2397;PREVIOUS PAGE;So;0;ON;;;;;N;;;;;
+2398;NEXT PAGE;So;0;ON;;;;;N;;;;;
+2399;PRINT SCREEN SYMBOL;So;0;ON;;;;;N;;;;;
+239A;CLEAR SCREEN SYMBOL;So;0;ON;;;;;N;;;;;
+239B;LEFT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;;
+239C;LEFT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;;
+239D;LEFT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;;
+239E;RIGHT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;;
+239F;RIGHT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;;
+23A0;RIGHT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;;
+23A1;LEFT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;;
+23A2;LEFT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;
+23A3;LEFT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;;
+23A4;RIGHT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;;
+23A5;RIGHT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;
+23A6;RIGHT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;;
+23A7;LEFT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;;
+23A8;LEFT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;;
+23A9;LEFT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;;
+23AA;CURLY BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;
+23AB;RIGHT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;;
+23AC;RIGHT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;;
+23AD;RIGHT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;;
+23AE;INTEGRAL EXTENSION;Sm;0;ON;;;;;N;;;;;
+23AF;HORIZONTAL LINE EXTENSION;Sm;0;ON;;;;;N;;;;;
+23B0;UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;;
+23B1;UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;;
+23B2;SUMMATION TOP;Sm;0;ON;;;;;N;;;;;
+23B3;SUMMATION BOTTOM;Sm;0;ON;;;;;N;;;;;
+23B4;TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;;
+23B5;BOTTOM SQUARE BRACKET;So;0;ON;;;;;N;;;;;
+23B6;BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;;
+23B7;RADICAL SYMBOL BOTTOM;So;0;ON;;;;;N;;;;;
+23B8;LEFT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;;
+23B9;RIGHT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;;
+23BA;HORIZONTAL SCAN LINE-1;So;0;ON;;;;;N;;;;;
+23BB;HORIZONTAL SCAN LINE-3;So;0;ON;;;;;N;;;;;
+23BC;HORIZONTAL SCAN LINE-7;So;0;ON;;;;;N;;;;;
+23BD;HORIZONTAL SCAN LINE-9;So;0;ON;;;;;N;;;;;
+23BE;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT;So;0;ON;;;;;N;;;;;
+23BF;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT;So;0;ON;;;;;N;;;;;
+23C0;DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE;So;0;ON;;;;;N;;;;;
+23C1;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;;
+23C2;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;;
+23C3;DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;
+23C4;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;
+23C5;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;
+23C6;DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE;So;0;ON;;;;;N;;;;;
+23C7;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;;
+23C8;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;;
+23C9;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;;;;;
+23CA;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;;;;;
+23CB;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT;So;0;ON;;;;;N;;;;;
+23CC;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT;So;0;ON;;;;;N;;;;;
+23CD;SQUARE FOOT;So;0;ON;;;;;N;;;;;
+23CE;RETURN SYMBOL;So;0;ON;;;;;N;;;;;
+23CF;EJECT SYMBOL;So;0;ON;;;;;N;;;;;
+23D0;VERTICAL LINE EXTENSION;So;0;ON;;;;;N;;;;;
+23D1;METRICAL BREVE;So;0;ON;;;;;N;;;;;
+23D2;METRICAL LONG OVER SHORT;So;0;ON;;;;;N;;;;;
+23D3;METRICAL SHORT OVER LONG;So;0;ON;;;;;N;;;;;
+23D4;METRICAL LONG OVER TWO SHORTS;So;0;ON;;;;;N;;;;;
+23D5;METRICAL TWO SHORTS OVER LONG;So;0;ON;;;;;N;;;;;
+23D6;METRICAL TWO SHORTS JOINED;So;0;ON;;;;;N;;;;;
+23D7;METRICAL TRISEME;So;0;ON;;;;;N;;;;;
+23D8;METRICAL TETRASEME;So;0;ON;;;;;N;;;;;
+23D9;METRICAL PENTASEME;So;0;ON;;;;;N;;;;;
+23DA;EARTH GROUND;So;0;ON;;;;;N;;;;;
+23DB;FUSE;So;0;ON;;;;;N;;;;;
+23DC;TOP PARENTHESIS;Sm;0;ON;;;;;N;;;;;
+23DD;BOTTOM PARENTHESIS;Sm;0;ON;;;;;N;;;;;
+23DE;TOP CURLY BRACKET;Sm;0;ON;;;;;N;;;;;
+23DF;BOTTOM CURLY BRACKET;Sm;0;ON;;;;;N;;;;;
+23E0;TOP TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;;
+23E1;BOTTOM TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;;
+23E2;WHITE TRAPEZIUM;So;0;ON;;;;;N;;;;;
+23E3;BENZENE RING WITH CIRCLE;So;0;ON;;;;;N;;;;;
+23E4;STRAIGHTNESS;So;0;ON;;;;;N;;;;;
+23E5;FLATNESS;So;0;ON;;;;;N;;;;;
+23E6;AC CURRENT;So;0;ON;;;;;N;;;;;
+23E7;ELECTRICAL INTERSECTION;So;0;ON;;;;;N;;;;;
+23E8;DECIMAL EXPONENT SYMBOL;So;0;ON;;;;;N;;;;;
+23E9;BLACK RIGHT-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23EA;BLACK LEFT-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23EB;BLACK UP-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23EC;BLACK DOWN-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;
+23ED;BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;
+23EE;BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;
+23EF;BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR;So;0;ON;;;;;N;;;;;
+23F0;ALARM CLOCK;So;0;ON;;;;;N;;;;;
+23F1;STOPWATCH;So;0;ON;;;;;N;;;;;
+23F2;TIMER CLOCK;So;0;ON;;;;;N;;;;;
+23F3;HOURGLASS WITH FLOWING SAND;So;0;ON;;;;;N;;;;;
+23F4;BLACK MEDIUM LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;
+23F5;BLACK MEDIUM RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;
+23F6;BLACK MEDIUM UP-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;
+23F7;BLACK MEDIUM DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;
+23F8;DOUBLE VERTICAL BAR;So;0;ON;;;;;N;;;;;
+23F9;BLACK SQUARE FOR STOP;So;0;ON;;;;;N;;;;;
+23FA;BLACK CIRCLE FOR RECORD;So;0;ON;;;;;N;;;;;
+23FB;POWER SYMBOL;So;0;ON;;;;;N;;;;;
+23FC;POWER ON-OFF SYMBOL;So;0;ON;;;;;N;;;;;
+23FD;POWER ON SYMBOL;So;0;ON;;;;;N;;;;;
+23FE;POWER SLEEP SYMBOL;So;0;ON;;;;;N;;;;;
+2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;;
+2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;;
+2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;;
+2403;SYMBOL FOR END OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR END OF TEXT;;;;
+2404;SYMBOL FOR END OF TRANSMISSION;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION;;;;
+2405;SYMBOL FOR ENQUIRY;So;0;ON;;;;;N;GRAPHIC FOR ENQUIRY;;;;
+2406;SYMBOL FOR ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR ACKNOWLEDGE;;;;
+2407;SYMBOL FOR BELL;So;0;ON;;;;;N;GRAPHIC FOR BELL;;;;
+2408;SYMBOL FOR BACKSPACE;So;0;ON;;;;;N;GRAPHIC FOR BACKSPACE;;;;
+2409;SYMBOL FOR HORIZONTAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR HORIZONTAL TABULATION;;;;
+240A;SYMBOL FOR LINE FEED;So;0;ON;;;;;N;GRAPHIC FOR LINE FEED;;;;
+240B;SYMBOL FOR VERTICAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR VERTICAL TABULATION;;;;
+240C;SYMBOL FOR FORM FEED;So;0;ON;;;;;N;GRAPHIC FOR FORM FEED;;;;
+240D;SYMBOL FOR CARRIAGE RETURN;So;0;ON;;;;;N;GRAPHIC FOR CARRIAGE RETURN;;;;
+240E;SYMBOL FOR SHIFT OUT;So;0;ON;;;;;N;GRAPHIC FOR SHIFT OUT;;;;
+240F;SYMBOL FOR SHIFT IN;So;0;ON;;;;;N;GRAPHIC FOR SHIFT IN;;;;
+2410;SYMBOL FOR DATA LINK ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR DATA LINK ESCAPE;;;;
+2411;SYMBOL FOR DEVICE CONTROL ONE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL ONE;;;;
+2412;SYMBOL FOR DEVICE CONTROL TWO;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL TWO;;;;
+2413;SYMBOL FOR DEVICE CONTROL THREE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL THREE;;;;
+2414;SYMBOL FOR DEVICE CONTROL FOUR;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL FOUR;;;;
+2415;SYMBOL FOR NEGATIVE ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR NEGATIVE ACKNOWLEDGE;;;;
+2416;SYMBOL FOR SYNCHRONOUS IDLE;So;0;ON;;;;;N;GRAPHIC FOR SYNCHRONOUS IDLE;;;;
+2417;SYMBOL FOR END OF TRANSMISSION BLOCK;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION BLOCK;;;;
+2418;SYMBOL FOR CANCEL;So;0;ON;;;;;N;GRAPHIC FOR CANCEL;;;;
+2419;SYMBOL FOR END OF MEDIUM;So;0;ON;;;;;N;GRAPHIC FOR END OF MEDIUM;;;;
+241A;SYMBOL FOR SUBSTITUTE;So;0;ON;;;;;N;GRAPHIC FOR SUBSTITUTE;;;;
+241B;SYMBOL FOR ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR ESCAPE;;;;
+241C;SYMBOL FOR FILE SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR FILE SEPARATOR;;;;
+241D;SYMBOL FOR GROUP SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR GROUP SEPARATOR;;;;
+241E;SYMBOL FOR RECORD SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR RECORD SEPARATOR;;;;
+241F;SYMBOL FOR UNIT SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR UNIT SEPARATOR;;;;
+2420;SYMBOL FOR SPACE;So;0;ON;;;;;N;GRAPHIC FOR SPACE;;;;
+2421;SYMBOL FOR DELETE;So;0;ON;;;;;N;GRAPHIC FOR DELETE;;;;
+2422;BLANK SYMBOL;So;0;ON;;;;;N;BLANK;;;;
+2423;OPEN BOX;So;0;ON;;;;;N;;;;;
+2424;SYMBOL FOR NEWLINE;So;0;ON;;;;;N;GRAPHIC FOR NEWLINE;;;;
+2425;SYMBOL FOR DELETE FORM TWO;So;0;ON;;;;;N;;;;;
+2426;SYMBOL FOR SUBSTITUTE FORM TWO;So;0;ON;;;;;N;;;;;
+2440;OCR HOOK;So;0;ON;;;;;N;;;;;
+2441;OCR CHAIR;So;0;ON;;;;;N;;;;;
+2442;OCR FORK;So;0;ON;;;;;N;;;;;
+2443;OCR INVERTED FORK;So;0;ON;;;;;N;;;;;
+2444;OCR BELT BUCKLE;So;0;ON;;;;;N;;;;;
+2445;OCR BOW TIE;So;0;ON;;;;;N;;;;;
+2446;OCR BRANCH BANK IDENTIFICATION;So;0;ON;;;;;N;;;;;
+2447;OCR AMOUNT OF CHECK;So;0;ON;;;;;N;;;;;
+2448;OCR DASH;So;0;ON;;;;;N;;;;;
+2449;OCR CUSTOMER ACCOUNT NUMBER;So;0;ON;;;;;N;;;;;
+244A;OCR DOUBLE BACKSLASH;So;0;ON;;;;;N;;;;;
+2460;CIRCLED DIGIT ONE;No;0;ON;<circle> 0031;;1;1;N;;;;;
+2461;CIRCLED DIGIT TWO;No;0;ON;<circle> 0032;;2;2;N;;;;;
+2462;CIRCLED DIGIT THREE;No;0;ON;<circle> 0033;;3;3;N;;;;;
+2463;CIRCLED DIGIT FOUR;No;0;ON;<circle> 0034;;4;4;N;;;;;
+2464;CIRCLED DIGIT FIVE;No;0;ON;<circle> 0035;;5;5;N;;;;;
+2465;CIRCLED DIGIT SIX;No;0;ON;<circle> 0036;;6;6;N;;;;;
+2466;CIRCLED DIGIT SEVEN;No;0;ON;<circle> 0037;;7;7;N;;;;;
+2467;CIRCLED DIGIT EIGHT;No;0;ON;<circle> 0038;;8;8;N;;;;;
+2468;CIRCLED DIGIT NINE;No;0;ON;<circle> 0039;;9;9;N;;;;;
+2469;CIRCLED NUMBER TEN;No;0;ON;<circle> 0031 0030;;;10;N;;;;;
+246A;CIRCLED NUMBER ELEVEN;No;0;ON;<circle> 0031 0031;;;11;N;;;;;
+246B;CIRCLED NUMBER TWELVE;No;0;ON;<circle> 0031 0032;;;12;N;;;;;
+246C;CIRCLED NUMBER THIRTEEN;No;0;ON;<circle> 0031 0033;;;13;N;;;;;
+246D;CIRCLED NUMBER FOURTEEN;No;0;ON;<circle> 0031 0034;;;14;N;;;;;
+246E;CIRCLED NUMBER FIFTEEN;No;0;ON;<circle> 0031 0035;;;15;N;;;;;
+246F;CIRCLED NUMBER SIXTEEN;No;0;ON;<circle> 0031 0036;;;16;N;;;;;
+2470;CIRCLED NUMBER SEVENTEEN;No;0;ON;<circle> 0031 0037;;;17;N;;;;;
+2471;CIRCLED NUMBER EIGHTEEN;No;0;ON;<circle> 0031 0038;;;18;N;;;;;
+2472;CIRCLED NUMBER NINETEEN;No;0;ON;<circle> 0031 0039;;;19;N;;;;;
+2473;CIRCLED NUMBER TWENTY;No;0;ON;<circle> 0032 0030;;;20;N;;;;;
+2474;PARENTHESIZED DIGIT ONE;No;0;ON;<compat> 0028 0031 0029;;1;1;N;;;;;
+2475;PARENTHESIZED DIGIT TWO;No;0;ON;<compat> 0028 0032 0029;;2;2;N;;;;;
+2476;PARENTHESIZED DIGIT THREE;No;0;ON;<compat> 0028 0033 0029;;3;3;N;;;;;
+2477;PARENTHESIZED DIGIT FOUR;No;0;ON;<compat> 0028 0034 0029;;4;4;N;;;;;
+2478;PARENTHESIZED DIGIT FIVE;No;0;ON;<compat> 0028 0035 0029;;5;5;N;;;;;
+2479;PARENTHESIZED DIGIT SIX;No;0;ON;<compat> 0028 0036 0029;;6;6;N;;;;;
+247A;PARENTHESIZED DIGIT SEVEN;No;0;ON;<compat> 0028 0037 0029;;7;7;N;;;;;
+247B;PARENTHESIZED DIGIT EIGHT;No;0;ON;<compat> 0028 0038 0029;;8;8;N;;;;;
+247C;PARENTHESIZED DIGIT NINE;No;0;ON;<compat> 0028 0039 0029;;9;9;N;;;;;
+247D;PARENTHESIZED NUMBER TEN;No;0;ON;<compat> 0028 0031 0030 0029;;;10;N;;;;;
+247E;PARENTHESIZED NUMBER ELEVEN;No;0;ON;<compat> 0028 0031 0031 0029;;;11;N;;;;;
+247F;PARENTHESIZED NUMBER TWELVE;No;0;ON;<compat> 0028 0031 0032 0029;;;12;N;;;;;
+2480;PARENTHESIZED NUMBER THIRTEEN;No;0;ON;<compat> 0028 0031 0033 0029;;;13;N;;;;;
+2481;PARENTHESIZED NUMBER FOURTEEN;No;0;ON;<compat> 0028 0031 0034 0029;;;14;N;;;;;
+2482;PARENTHESIZED NUMBER FIFTEEN;No;0;ON;<compat> 0028 0031 0035 0029;;;15;N;;;;;
+2483;PARENTHESIZED NUMBER SIXTEEN;No;0;ON;<compat> 0028 0031 0036 0029;;;16;N;;;;;
+2484;PARENTHESIZED NUMBER SEVENTEEN;No;0;ON;<compat> 0028 0031 0037 0029;;;17;N;;;;;
+2485;PARENTHESIZED NUMBER EIGHTEEN;No;0;ON;<compat> 0028 0031 0038 0029;;;18;N;;;;;
+2486;PARENTHESIZED NUMBER NINETEEN;No;0;ON;<compat> 0028 0031 0039 0029;;;19;N;;;;;
+2487;PARENTHESIZED NUMBER TWENTY;No;0;ON;<compat> 0028 0032 0030 0029;;;20;N;;;;;
+2488;DIGIT ONE FULL STOP;No;0;EN;<compat> 0031 002E;;1;1;N;DIGIT ONE PERIOD;;;;
+2489;DIGIT TWO FULL STOP;No;0;EN;<compat> 0032 002E;;2;2;N;DIGIT TWO PERIOD;;;;
+248A;DIGIT THREE FULL STOP;No;0;EN;<compat> 0033 002E;;3;3;N;DIGIT THREE PERIOD;;;;
+248B;DIGIT FOUR FULL STOP;No;0;EN;<compat> 0034 002E;;4;4;N;DIGIT FOUR PERIOD;;;;
+248C;DIGIT FIVE FULL STOP;No;0;EN;<compat> 0035 002E;;5;5;N;DIGIT FIVE PERIOD;;;;
+248D;DIGIT SIX FULL STOP;No;0;EN;<compat> 0036 002E;;6;6;N;DIGIT SIX PERIOD;;;;
+248E;DIGIT SEVEN FULL STOP;No;0;EN;<compat> 0037 002E;;7;7;N;DIGIT SEVEN PERIOD;;;;
+248F;DIGIT EIGHT FULL STOP;No;0;EN;<compat> 0038 002E;;8;8;N;DIGIT EIGHT PERIOD;;;;
+2490;DIGIT NINE FULL STOP;No;0;EN;<compat> 0039 002E;;9;9;N;DIGIT NINE PERIOD;;;;
+2491;NUMBER TEN FULL STOP;No;0;EN;<compat> 0031 0030 002E;;;10;N;NUMBER TEN PERIOD;;;;
+2492;NUMBER ELEVEN FULL STOP;No;0;EN;<compat> 0031 0031 002E;;;11;N;NUMBER ELEVEN PERIOD;;;;
+2493;NUMBER TWELVE FULL STOP;No;0;EN;<compat> 0031 0032 002E;;;12;N;NUMBER TWELVE PERIOD;;;;
+2494;NUMBER THIRTEEN FULL STOP;No;0;EN;<compat> 0031 0033 002E;;;13;N;NUMBER THIRTEEN PERIOD;;;;
+2495;NUMBER FOURTEEN FULL STOP;No;0;EN;<compat> 0031 0034 002E;;;14;N;NUMBER FOURTEEN PERIOD;;;;
+2496;NUMBER FIFTEEN FULL STOP;No;0;EN;<compat> 0031 0035 002E;;;15;N;NUMBER FIFTEEN PERIOD;;;;
+2497;NUMBER SIXTEEN FULL STOP;No;0;EN;<compat> 0031 0036 002E;;;16;N;NUMBER SIXTEEN PERIOD;;;;
+2498;NUMBER SEVENTEEN FULL STOP;No;0;EN;<compat> 0031 0037 002E;;;17;N;NUMBER SEVENTEEN PERIOD;;;;
+2499;NUMBER EIGHTEEN FULL STOP;No;0;EN;<compat> 0031 0038 002E;;;18;N;NUMBER EIGHTEEN PERIOD;;;;
+249A;NUMBER NINETEEN FULL STOP;No;0;EN;<compat> 0031 0039 002E;;;19;N;NUMBER NINETEEN PERIOD;;;;
+249B;NUMBER TWENTY FULL STOP;No;0;EN;<compat> 0032 0030 002E;;;20;N;NUMBER TWENTY PERIOD;;;;
+249C;PARENTHESIZED LATIN SMALL LETTER A;So;0;L;<compat> 0028 0061 0029;;;;N;;;;;
+249D;PARENTHESIZED LATIN SMALL LETTER B;So;0;L;<compat> 0028 0062 0029;;;;N;;;;;
+249E;PARENTHESIZED LATIN SMALL LETTER C;So;0;L;<compat> 0028 0063 0029;;;;N;;;;;
+249F;PARENTHESIZED LATIN SMALL LETTER D;So;0;L;<compat> 0028 0064 0029;;;;N;;;;;
+24A0;PARENTHESIZED LATIN SMALL LETTER E;So;0;L;<compat> 0028 0065 0029;;;;N;;;;;
+24A1;PARENTHESIZED LATIN SMALL LETTER F;So;0;L;<compat> 0028 0066 0029;;;;N;;;;;
+24A2;PARENTHESIZED LATIN SMALL LETTER G;So;0;L;<compat> 0028 0067 0029;;;;N;;;;;
+24A3;PARENTHESIZED LATIN SMALL LETTER H;So;0;L;<compat> 0028 0068 0029;;;;N;;;;;
+24A4;PARENTHESIZED LATIN SMALL LETTER I;So;0;L;<compat> 0028 0069 0029;;;;N;;;;;
+24A5;PARENTHESIZED LATIN SMALL LETTER J;So;0;L;<compat> 0028 006A 0029;;;;N;;;;;
+24A6;PARENTHESIZED LATIN SMALL LETTER K;So;0;L;<compat> 0028 006B 0029;;;;N;;;;;
+24A7;PARENTHESIZED LATIN SMALL LETTER L;So;0;L;<compat> 0028 006C 0029;;;;N;;;;;
+24A8;PARENTHESIZED LATIN SMALL LETTER M;So;0;L;<compat> 0028 006D 0029;;;;N;;;;;
+24A9;PARENTHESIZED LATIN SMALL LETTER N;So;0;L;<compat> 0028 006E 0029;;;;N;;;;;
+24AA;PARENTHESIZED LATIN SMALL LETTER O;So;0;L;<compat> 0028 006F 0029;;;;N;;;;;
+24AB;PARENTHESIZED LATIN SMALL LETTER P;So;0;L;<compat> 0028 0070 0029;;;;N;;;;;
+24AC;PARENTHESIZED LATIN SMALL LETTER Q;So;0;L;<compat> 0028 0071 0029;;;;N;;;;;
+24AD;PARENTHESIZED LATIN SMALL LETTER R;So;0;L;<compat> 0028 0072 0029;;;;N;;;;;
+24AE;PARENTHESIZED LATIN SMALL LETTER S;So;0;L;<compat> 0028 0073 0029;;;;N;;;;;
+24AF;PARENTHESIZED LATIN SMALL LETTER T;So;0;L;<compat> 0028 0074 0029;;;;N;;;;;
+24B0;PARENTHESIZED LATIN SMALL LETTER U;So;0;L;<compat> 0028 0075 0029;;;;N;;;;;
+24B1;PARENTHESIZED LATIN SMALL LETTER V;So;0;L;<compat> 0028 0076 0029;;;;N;;;;;
+24B2;PARENTHESIZED LATIN SMALL LETTER W;So;0;L;<compat> 0028 0077 0029;;;;N;;;;;
+24B3;PARENTHESIZED LATIN SMALL LETTER X;So;0;L;<compat> 0028 0078 0029;;;;N;;;;;
+24B4;PARENTHESIZED LATIN SMALL LETTER Y;So;0;L;<compat> 0028 0079 0029;;;;N;;;;;
+24B5;PARENTHESIZED LATIN SMALL LETTER Z;So;0;L;<compat> 0028 007A 0029;;;;N;;;;;
+24B6;CIRCLED LATIN CAPITAL LETTER A;So;0;L;<circle> 0041;;;;N;;;;24D0;
+24B7;CIRCLED LATIN CAPITAL LETTER B;So;0;L;<circle> 0042;;;;N;;;;24D1;
+24B8;CIRCLED LATIN CAPITAL LETTER C;So;0;L;<circle> 0043;;;;N;;;;24D2;
+24B9;CIRCLED LATIN CAPITAL LETTER D;So;0;L;<circle> 0044;;;;N;;;;24D3;
+24BA;CIRCLED LATIN CAPITAL LETTER E;So;0;L;<circle> 0045;;;;N;;;;24D4;
+24BB;CIRCLED LATIN CAPITAL LETTER F;So;0;L;<circle> 0046;;;;N;;;;24D5;
+24BC;CIRCLED LATIN CAPITAL LETTER G;So;0;L;<circle> 0047;;;;N;;;;24D6;
+24BD;CIRCLED LATIN CAPITAL LETTER H;So;0;L;<circle> 0048;;;;N;;;;24D7;
+24BE;CIRCLED LATIN CAPITAL LETTER I;So;0;L;<circle> 0049;;;;N;;;;24D8;
+24BF;CIRCLED LATIN CAPITAL LETTER J;So;0;L;<circle> 004A;;;;N;;;;24D9;
+24C0;CIRCLED LATIN CAPITAL LETTER K;So;0;L;<circle> 004B;;;;N;;;;24DA;
+24C1;CIRCLED LATIN CAPITAL LETTER L;So;0;L;<circle> 004C;;;;N;;;;24DB;
+24C2;CIRCLED LATIN CAPITAL LETTER M;So;0;L;<circle> 004D;;;;N;;;;24DC;
+24C3;CIRCLED LATIN CAPITAL LETTER N;So;0;L;<circle> 004E;;;;N;;;;24DD;
+24C4;CIRCLED LATIN CAPITAL LETTER O;So;0;L;<circle> 004F;;;;N;;;;24DE;
+24C5;CIRCLED LATIN CAPITAL LETTER P;So;0;L;<circle> 0050;;;;N;;;;24DF;
+24C6;CIRCLED LATIN CAPITAL LETTER Q;So;0;L;<circle> 0051;;;;N;;;;24E0;
+24C7;CIRCLED LATIN CAPITAL LETTER R;So;0;L;<circle> 0052;;;;N;;;;24E1;
+24C8;CIRCLED LATIN CAPITAL LETTER S;So;0;L;<circle> 0053;;;;N;;;;24E2;
+24C9;CIRCLED LATIN CAPITAL LETTER T;So;0;L;<circle> 0054;;;;N;;;;24E3;
+24CA;CIRCLED LATIN CAPITAL LETTER U;So;0;L;<circle> 0055;;;;N;;;;24E4;
+24CB;CIRCLED LATIN CAPITAL LETTER V;So;0;L;<circle> 0056;;;;N;;;;24E5;
+24CC;CIRCLED LATIN CAPITAL LETTER W;So;0;L;<circle> 0057;;;;N;;;;24E6;
+24CD;CIRCLED LATIN CAPITAL LETTER X;So;0;L;<circle> 0058;;;;N;;;;24E7;
+24CE;CIRCLED LATIN CAPITAL LETTER Y;So;0;L;<circle> 0059;;;;N;;;;24E8;
+24CF;CIRCLED LATIN CAPITAL LETTER Z;So;0;L;<circle> 005A;;;;N;;;;24E9;
+24D0;CIRCLED LATIN SMALL LETTER A;So;0;L;<circle> 0061;;;;N;;;24B6;;24B6
+24D1;CIRCLED LATIN SMALL LETTER B;So;0;L;<circle> 0062;;;;N;;;24B7;;24B7
+24D2;CIRCLED LATIN SMALL LETTER C;So;0;L;<circle> 0063;;;;N;;;24B8;;24B8
+24D3;CIRCLED LATIN SMALL LETTER D;So;0;L;<circle> 0064;;;;N;;;24B9;;24B9
+24D4;CIRCLED LATIN SMALL LETTER E;So;0;L;<circle> 0065;;;;N;;;24BA;;24BA
+24D5;CIRCLED LATIN SMALL LETTER F;So;0;L;<circle> 0066;;;;N;;;24BB;;24BB
+24D6;CIRCLED LATIN SMALL LETTER G;So;0;L;<circle> 0067;;;;N;;;24BC;;24BC
+24D7;CIRCLED LATIN SMALL LETTER H;So;0;L;<circle> 0068;;;;N;;;24BD;;24BD
+24D8;CIRCLED LATIN SMALL LETTER I;So;0;L;<circle> 0069;;;;N;;;24BE;;24BE
+24D9;CIRCLED LATIN SMALL LETTER J;So;0;L;<circle> 006A;;;;N;;;24BF;;24BF
+24DA;CIRCLED LATIN SMALL LETTER K;So;0;L;<circle> 006B;;;;N;;;24C0;;24C0
+24DB;CIRCLED LATIN SMALL LETTER L;So;0;L;<circle> 006C;;;;N;;;24C1;;24C1
+24DC;CIRCLED LATIN SMALL LETTER M;So;0;L;<circle> 006D;;;;N;;;24C2;;24C2
+24DD;CIRCLED LATIN SMALL LETTER N;So;0;L;<circle> 006E;;;;N;;;24C3;;24C3
+24DE;CIRCLED LATIN SMALL LETTER O;So;0;L;<circle> 006F;;;;N;;;24C4;;24C4
+24DF;CIRCLED LATIN SMALL LETTER P;So;0;L;<circle> 0070;;;;N;;;24C5;;24C5
+24E0;CIRCLED LATIN SMALL LETTER Q;So;0;L;<circle> 0071;;;;N;;;24C6;;24C6
+24E1;CIRCLED LATIN SMALL LETTER R;So;0;L;<circle> 0072;;;;N;;;24C7;;24C7
+24E2;CIRCLED LATIN SMALL LETTER S;So;0;L;<circle> 0073;;;;N;;;24C8;;24C8
+24E3;CIRCLED LATIN SMALL LETTER T;So;0;L;<circle> 0074;;;;N;;;24C9;;24C9
+24E4;CIRCLED LATIN SMALL LETTER U;So;0;L;<circle> 0075;;;;N;;;24CA;;24CA
+24E5;CIRCLED LATIN SMALL LETTER V;So;0;L;<circle> 0076;;;;N;;;24CB;;24CB
+24E6;CIRCLED LATIN SMALL LETTER W;So;0;L;<circle> 0077;;;;N;;;24CC;;24CC
+24E7;CIRCLED LATIN SMALL LETTER X;So;0;L;<circle> 0078;;;;N;;;24CD;;24CD
+24E8;CIRCLED LATIN SMALL LETTER Y;So;0;L;<circle> 0079;;;;N;;;24CE;;24CE
+24E9;CIRCLED LATIN SMALL LETTER Z;So;0;L;<circle> 007A;;;;N;;;24CF;;24CF
+24EA;CIRCLED DIGIT ZERO;No;0;ON;<circle> 0030;;0;0;N;;;;;
+24EB;NEGATIVE CIRCLED NUMBER ELEVEN;No;0;ON;;;;11;N;;;;;
+24EC;NEGATIVE CIRCLED NUMBER TWELVE;No;0;ON;;;;12;N;;;;;
+24ED;NEGATIVE CIRCLED NUMBER THIRTEEN;No;0;ON;;;;13;N;;;;;
+24EE;NEGATIVE CIRCLED NUMBER FOURTEEN;No;0;ON;;;;14;N;;;;;
+24EF;NEGATIVE CIRCLED NUMBER FIFTEEN;No;0;ON;;;;15;N;;;;;
+24F0;NEGATIVE CIRCLED NUMBER SIXTEEN;No;0;ON;;;;16;N;;;;;
+24F1;NEGATIVE CIRCLED NUMBER SEVENTEEN;No;0;ON;;;;17;N;;;;;
+24F2;NEGATIVE CIRCLED NUMBER EIGHTEEN;No;0;ON;;;;18;N;;;;;
+24F3;NEGATIVE CIRCLED NUMBER NINETEEN;No;0;ON;;;;19;N;;;;;
+24F4;NEGATIVE CIRCLED NUMBER TWENTY;No;0;ON;;;;20;N;;;;;
+24F5;DOUBLE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;;;;;
+24F6;DOUBLE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;;;;;
+24F7;DOUBLE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;;;;;
+24F8;DOUBLE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;;;;;
+24F9;DOUBLE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;;;;;
+24FA;DOUBLE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;;;;;
+24FB;DOUBLE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;;;;;
+24FC;DOUBLE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;;;;;
+24FD;DOUBLE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;;;;;
+24FE;DOUBLE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;;;;;
+24FF;NEGATIVE CIRCLED DIGIT ZERO;No;0;ON;;;0;0;N;;;;;
+2500;BOX DRAWINGS LIGHT HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT HORIZONTAL;;;;
+2501;BOX DRAWINGS HEAVY HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY HORIZONTAL;;;;
+2502;BOX DRAWINGS LIGHT VERTICAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL;;;;
+2503;BOX DRAWINGS HEAVY VERTICAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL;;;;
+2504;BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH HORIZONTAL;;;;
+2505;BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH HORIZONTAL;;;;
+2506;BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH VERTICAL;;;;
+2507;BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH VERTICAL;;;;
+2508;BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH HORIZONTAL;;;;
+2509;BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH HORIZONTAL;;;;
+250A;BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH VERTICAL;;;;
+250B;BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH VERTICAL;;;;
+250C;BOX DRAWINGS LIGHT DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND RIGHT;;;;
+250D;BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT HEAVY;;;;
+250E;BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT LIGHT;;;;
+250F;BOX DRAWINGS HEAVY DOWN AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND RIGHT;;;;
+2510;BOX DRAWINGS LIGHT DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND LEFT;;;;
+2511;BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT HEAVY;;;;
+2512;BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT LIGHT;;;;
+2513;BOX DRAWINGS HEAVY DOWN AND LEFT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND LEFT;;;;
+2514;BOX DRAWINGS LIGHT UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT UP AND RIGHT;;;;
+2515;BOX DRAWINGS UP LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT HEAVY;;;;
+2516;BOX DRAWINGS UP HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT LIGHT;;;;
+2517;BOX DRAWINGS HEAVY UP AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY UP AND RIGHT;;;;
+2518;BOX DRAWINGS LIGHT UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT UP AND LEFT;;;;
+2519;BOX DRAWINGS UP LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT HEAVY;;;;
+251A;BOX DRAWINGS UP HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT LIGHT;;;;
+251B;BOX DRAWINGS HEAVY UP AND LEFT;So;0;ON;;;;;N;FORMS HEAVY UP AND LEFT;;;;
+251C;BOX DRAWINGS LIGHT VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND RIGHT;;;;
+251D;BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND RIGHT HEAVY;;;;
+251E;BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT DOWN LIGHT;;;;
+251F;BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT UP LIGHT;;;;
+2520;BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND RIGHT LIGHT;;;;
+2521;BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT UP HEAVY;;;;
+2522;BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT DOWN HEAVY;;;;
+2523;BOX DRAWINGS HEAVY VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND RIGHT;;;;
+2524;BOX DRAWINGS LIGHT VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND LEFT;;;;
+2525;BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND LEFT HEAVY;;;;
+2526;BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT DOWN LIGHT;;;;
+2527;BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT UP LIGHT;;;;
+2528;BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND LEFT LIGHT;;;;
+2529;BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT UP HEAVY;;;;
+252A;BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT DOWN HEAVY;;;;
+252B;BOX DRAWINGS HEAVY VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND LEFT;;;;
+252C;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOWN AND HORIZONTAL;;;;
+252D;BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT DOWN LIGHT;;;;
+252E;BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT DOWN LIGHT;;;;
+252F;BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND HORIZONTAL HEAVY;;;;
+2530;BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND HORIZONTAL LIGHT;;;;
+2531;BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT DOWN HEAVY;;;;
+2532;BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT DOWN HEAVY;;;;
+2533;BOX DRAWINGS HEAVY DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOWN AND HORIZONTAL;;;;
+2534;BOX DRAWINGS LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT UP AND HORIZONTAL;;;;
+2535;BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT UP LIGHT;;;;
+2536;BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT UP LIGHT;;;;
+2537;BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND HORIZONTAL HEAVY;;;;
+2538;BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND HORIZONTAL LIGHT;;;;
+2539;BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT UP HEAVY;;;;
+253A;BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT UP HEAVY;;;;
+253B;BOX DRAWINGS HEAVY UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY UP AND HORIZONTAL;;;;
+253C;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND HORIZONTAL;;;;
+253D;BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT VERTICAL LIGHT;;;;
+253E;BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT VERTICAL LIGHT;;;;
+253F;BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND HORIZONTAL HEAVY;;;;
+2540;BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND DOWN HORIZONTAL LIGHT;;;;
+2541;BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND UP HORIZONTAL LIGHT;;;;
+2542;BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND HORIZONTAL LIGHT;;;;
+2543;BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT UP HEAVY AND RIGHT DOWN LIGHT;;;;
+2544;BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT UP HEAVY AND LEFT DOWN LIGHT;;;;
+2545;BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT DOWN HEAVY AND RIGHT UP LIGHT;;;;
+2546;BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT DOWN HEAVY AND LEFT UP LIGHT;;;;
+2547;BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND UP HORIZONTAL HEAVY;;;;
+2548;BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND DOWN HORIZONTAL HEAVY;;;;
+2549;BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT VERTICAL HEAVY;;;;
+254A;BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT VERTICAL HEAVY;;;;
+254B;BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND HORIZONTAL;;;;
+254C;BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH HORIZONTAL;;;;
+254D;BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH HORIZONTAL;;;;
+254E;BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH VERTICAL;;;;
+254F;BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH VERTICAL;;;;
+2550;BOX DRAWINGS DOUBLE HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE HORIZONTAL;;;;
+2551;BOX DRAWINGS DOUBLE VERTICAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL;;;;
+2552;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND RIGHT DOUBLE;;;;
+2553;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND RIGHT SINGLE;;;;
+2554;BOX DRAWINGS DOUBLE DOWN AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND RIGHT;;;;
+2555;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND LEFT DOUBLE;;;;
+2556;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND LEFT SINGLE;;;;
+2557;BOX DRAWINGS DOUBLE DOWN AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND LEFT;;;;
+2558;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND RIGHT DOUBLE;;;;
+2559;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND RIGHT SINGLE;;;;
+255A;BOX DRAWINGS DOUBLE UP AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE UP AND RIGHT;;;;
+255B;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND LEFT DOUBLE;;;;
+255C;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND LEFT SINGLE;;;;
+255D;BOX DRAWINGS DOUBLE UP AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE UP AND LEFT;;;;
+255E;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND RIGHT DOUBLE;;;;
+255F;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND RIGHT SINGLE;;;;
+2560;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND RIGHT;;;;
+2561;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND LEFT DOUBLE;;;;
+2562;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND LEFT SINGLE;;;;
+2563;BOX DRAWINGS DOUBLE VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND LEFT;;;;
+2564;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND HORIZONTAL DOUBLE;;;;
+2565;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND HORIZONTAL SINGLE;;;;
+2566;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND HORIZONTAL;;;;
+2567;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND HORIZONTAL DOUBLE;;;;
+2568;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND HORIZONTAL SINGLE;;;;
+2569;BOX DRAWINGS DOUBLE UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE UP AND HORIZONTAL;;;;
+256A;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND HORIZONTAL DOUBLE;;;;
+256B;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND HORIZONTAL SINGLE;;;;
+256C;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND HORIZONTAL;;;;
+256D;BOX DRAWINGS LIGHT ARC DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND RIGHT;;;;
+256E;BOX DRAWINGS LIGHT ARC DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND LEFT;;;;
+256F;BOX DRAWINGS LIGHT ARC UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND LEFT;;;;
+2570;BOX DRAWINGS LIGHT ARC UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND RIGHT;;;;
+2571;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;;;;
+2572;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;;;;
+2573;BOX DRAWINGS LIGHT DIAGONAL CROSS;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL CROSS;;;;
+2574;BOX DRAWINGS LIGHT LEFT;So;0;ON;;;;;N;FORMS LIGHT LEFT;;;;
+2575;BOX DRAWINGS LIGHT UP;So;0;ON;;;;;N;FORMS LIGHT UP;;;;
+2576;BOX DRAWINGS LIGHT RIGHT;So;0;ON;;;;;N;FORMS LIGHT RIGHT;;;;
+2577;BOX DRAWINGS LIGHT DOWN;So;0;ON;;;;;N;FORMS LIGHT DOWN;;;;
+2578;BOX DRAWINGS HEAVY LEFT;So;0;ON;;;;;N;FORMS HEAVY LEFT;;;;
+2579;BOX DRAWINGS HEAVY UP;So;0;ON;;;;;N;FORMS HEAVY UP;;;;
+257A;BOX DRAWINGS HEAVY RIGHT;So;0;ON;;;;;N;FORMS HEAVY RIGHT;;;;
+257B;BOX DRAWINGS HEAVY DOWN;So;0;ON;;;;;N;FORMS HEAVY DOWN;;;;
+257C;BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT;So;0;ON;;;;;N;FORMS LIGHT LEFT AND HEAVY RIGHT;;;;
+257D;BOX DRAWINGS LIGHT UP AND HEAVY DOWN;So;0;ON;;;;;N;FORMS LIGHT UP AND HEAVY DOWN;;;;
+257E;BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT;So;0;ON;;;;;N;FORMS HEAVY LEFT AND LIGHT RIGHT;;;;
+257F;BOX DRAWINGS HEAVY UP AND LIGHT DOWN;So;0;ON;;;;;N;FORMS HEAVY UP AND LIGHT DOWN;;;;
+2580;UPPER HALF BLOCK;So;0;ON;;;;;N;;;;;
+2581;LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+2582;LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+2583;LOWER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+2584;LOWER HALF BLOCK;So;0;ON;;;;;N;;;;;
+2585;LOWER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+2586;LOWER THREE QUARTERS BLOCK;So;0;ON;;;;;N;LOWER THREE QUARTER BLOCK;;;;
+2587;LOWER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+2588;FULL BLOCK;So;0;ON;;;;;N;;;;;
+2589;LEFT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+258A;LEFT THREE QUARTERS BLOCK;So;0;ON;;;;;N;LEFT THREE QUARTER BLOCK;;;;
+258B;LEFT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+258C;LEFT HALF BLOCK;So;0;ON;;;;;N;;;;;
+258D;LEFT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
+258E;LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
+258F;LEFT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+2590;RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;;
+2591;LIGHT SHADE;So;0;ON;;;;;N;;;;;
+2592;MEDIUM SHADE;So;0;ON;;;;;N;;;;;
+2593;DARK SHADE;So;0;ON;;;;;N;;;;;
+2594;UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+2595;RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
+2596;QUADRANT LOWER LEFT;So;0;ON;;;;;N;;;;;
+2597;QUADRANT LOWER RIGHT;So;0;ON;;;;;N;;;;;
+2598;QUADRANT UPPER LEFT;So;0;ON;;;;;N;;;;;
+2599;QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
+259A;QUADRANT UPPER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
+259B;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;;
+259C;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
+259D;QUADRANT UPPER RIGHT;So;0;ON;;;;;N;;;;;
+259E;QUADRANT UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;;
+259F;QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
+25A0;BLACK SQUARE;So;0;ON;;;;;N;;;;;
+25A1;WHITE SQUARE;So;0;ON;;;;;N;;;;;
+25A2;WHITE SQUARE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;;
+25A3;WHITE SQUARE CONTAINING BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;;
+25A4;SQUARE WITH HORIZONTAL FILL;So;0;ON;;;;;N;;;;;
+25A5;SQUARE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;;
+25A6;SQUARE WITH ORTHOGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;;
+25A7;SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;;
+25A8;SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;;
+25A9;SQUARE WITH DIAGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;;
+25AA;BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;;
+25AB;WHITE SMALL SQUARE;So;0;ON;;;;;N;;;;;
+25AC;BLACK RECTANGLE;So;0;ON;;;;;N;;;;;
+25AD;WHITE RECTANGLE;So;0;ON;;;;;N;;;;;
+25AE;BLACK VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;;
+25AF;WHITE VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;;
+25B0;BLACK PARALLELOGRAM;So;0;ON;;;;;N;;;;;
+25B1;WHITE PARALLELOGRAM;So;0;ON;;;;;N;;;;;
+25B2;BLACK UP-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING TRIANGLE;;;;
+25B3;WHITE UP-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE;;;;
+25B4;BLACK UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING SMALL TRIANGLE;;;;
+25B5;WHITE UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING SMALL TRIANGLE;;;;
+25B6;BLACK RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING TRIANGLE;;;;
+25B7;WHITE RIGHT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE RIGHT POINTING TRIANGLE;;;;
+25B8;BLACK RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING SMALL TRIANGLE;;;;
+25B9;WHITE RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE RIGHT POINTING SMALL TRIANGLE;;;;
+25BA;BLACK RIGHT-POINTING POINTER;So;0;ON;;;;;N;BLACK RIGHT POINTING POINTER;;;;
+25BB;WHITE RIGHT-POINTING POINTER;So;0;ON;;;;;N;WHITE RIGHT POINTING POINTER;;;;
+25BC;BLACK DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING TRIANGLE;;;;
+25BD;WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING TRIANGLE;;;;
+25BE;BLACK DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING SMALL TRIANGLE;;;;
+25BF;WHITE DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING SMALL TRIANGLE;;;;
+25C0;BLACK LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING TRIANGLE;;;;
+25C1;WHITE LEFT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE LEFT POINTING TRIANGLE;;;;
+25C2;BLACK LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING SMALL TRIANGLE;;;;
+25C3;WHITE LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE LEFT POINTING SMALL TRIANGLE;;;;
+25C4;BLACK LEFT-POINTING POINTER;So;0;ON;;;;;N;BLACK LEFT POINTING POINTER;;;;
+25C5;WHITE LEFT-POINTING POINTER;So;0;ON;;;;;N;WHITE LEFT POINTING POINTER;;;;
+25C6;BLACK DIAMOND;So;0;ON;;;;;N;;;;;
+25C7;WHITE DIAMOND;So;0;ON;;;;;N;;;;;
+25C8;WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;;
+25C9;FISHEYE;So;0;ON;;;;;N;;;;;
+25CA;LOZENGE;So;0;ON;;;;;N;;;;;
+25CB;WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25CC;DOTTED CIRCLE;So;0;ON;;;;;N;;;;;
+25CD;CIRCLE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;;
+25CE;BULLSEYE;So;0;ON;;;;;N;;;;;
+25CF;BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+25D0;CIRCLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;
+25D1;CIRCLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;
+25D2;CIRCLE WITH LOWER HALF BLACK;So;0;ON;;;;;N;;;;;
+25D3;CIRCLE WITH UPPER HALF BLACK;So;0;ON;;;;;N;;;;;
+25D4;CIRCLE WITH UPPER RIGHT QUADRANT BLACK;So;0;ON;;;;;N;;;;;
+25D5;CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK;So;0;ON;;;;;N;;;;;
+25D6;LEFT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+25D7;RIGHT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+25D8;INVERSE BULLET;So;0;ON;;;;;N;;;;;
+25D9;INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25DA;UPPER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25DB;LOWER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+25DC;UPPER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25DD;UPPER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25DE;LOWER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25DF;LOWER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
+25E0;UPPER HALF CIRCLE;So;0;ON;;;;;N;;;;;
+25E1;LOWER HALF CIRCLE;So;0;ON;;;;;N;;;;;
+25E2;BLACK LOWER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E3;BLACK LOWER LEFT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E4;BLACK UPPER LEFT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E5;BLACK UPPER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+25E6;WHITE BULLET;So;0;ON;;;;;N;;;;;
+25E7;SQUARE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;
+25E8;SQUARE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;
+25E9;SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
+25EA;SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
+25EB;WHITE SQUARE WITH VERTICAL BISECTING LINE;So;0;ON;;;;;N;;;;;
+25EC;WHITE UP-POINTING TRIANGLE WITH DOT;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE WITH DOT;;;;
+25ED;UP-POINTING TRIANGLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH LEFT HALF BLACK;;;;
+25EE;UP-POINTING TRIANGLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH RIGHT HALF BLACK;;;;
+25EF;LARGE CIRCLE;So;0;ON;;;;;N;;;;;
+25F0;WHITE SQUARE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F1;WHITE SQUARE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F2;WHITE SQUARE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+25F3;WHITE SQUARE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+25F4;WHITE CIRCLE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F5;WHITE CIRCLE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
+25F6;WHITE CIRCLE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+25F7;WHITE CIRCLE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
+25F8;UPPER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;;
+25F9;UPPER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;;
+25FA;LOWER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;;
+25FB;WHITE MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;;
+25FC;BLACK MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;;
+25FD;WHITE MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;;
+25FE;BLACK MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;;
+25FF;LOWER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;;
+2600;BLACK SUN WITH RAYS;So;0;ON;;;;;N;;;;;
+2601;CLOUD;So;0;ON;;;;;N;;;;;
+2602;UMBRELLA;So;0;ON;;;;;N;;;;;
+2603;SNOWMAN;So;0;ON;;;;;N;;;;;
+2604;COMET;So;0;ON;;;;;N;;;;;
+2605;BLACK STAR;So;0;ON;;;;;N;;;;;
+2606;WHITE STAR;So;0;ON;;;;;N;;;;;
+2607;LIGHTNING;So;0;ON;;;;;N;;;;;
+2608;THUNDERSTORM;So;0;ON;;;;;N;;;;;
+2609;SUN;So;0;ON;;;;;N;;;;;
+260A;ASCENDING NODE;So;0;ON;;;;;N;;;;;
+260B;DESCENDING NODE;So;0;ON;;;;;N;;;;;
+260C;CONJUNCTION;So;0;ON;;;;;N;;;;;
+260D;OPPOSITION;So;0;ON;;;;;N;;;;;
+260E;BLACK TELEPHONE;So;0;ON;;;;;N;;;;;
+260F;WHITE TELEPHONE;So;0;ON;;;;;N;;;;;
+2610;BALLOT BOX;So;0;ON;;;;;N;;;;;
+2611;BALLOT BOX WITH CHECK;So;0;ON;;;;;N;;;;;
+2612;BALLOT BOX WITH X;So;0;ON;;;;;N;;;;;
+2613;SALTIRE;So;0;ON;;;;;N;;;;;
+2614;UMBRELLA WITH RAIN DROPS;So;0;ON;;;;;N;;;;;
+2615;HOT BEVERAGE;So;0;ON;;;;;N;;;;;
+2616;WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;;
+2617;BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;;
+2618;SHAMROCK;So;0;ON;;;;;N;;;;;
+2619;REVERSED ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;;
+261A;BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261B;BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261C;WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261D;WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;;
+261E;WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+261F;WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;;
+2620;SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;;
+2621;CAUTION SIGN;So;0;ON;;;;;N;;;;;
+2622;RADIOACTIVE SIGN;So;0;ON;;;;;N;;;;;
+2623;BIOHAZARD SIGN;So;0;ON;;;;;N;;;;;
+2624;CADUCEUS;So;0;ON;;;;;N;;;;;
+2625;ANKH;So;0;ON;;;;;N;;;;;
+2626;ORTHODOX CROSS;So;0;ON;;;;;N;;;;;
+2627;CHI RHO;So;0;ON;;;;;N;;;;;
+2628;CROSS OF LORRAINE;So;0;ON;;;;;N;;;;;
+2629;CROSS OF JERUSALEM;So;0;ON;;;;;N;;;;;
+262A;STAR AND CRESCENT;So;0;ON;;;;;N;;;;;
+262B;FARSI SYMBOL;So;0;ON;;;;;N;SYMBOL OF IRAN;;;;
+262C;ADI SHAKTI;So;0;ON;;;;;N;;;;;
+262D;HAMMER AND SICKLE;So;0;ON;;;;;N;;;;;
+262E;PEACE SYMBOL;So;0;ON;;;;;N;;;;;
+262F;YIN YANG;So;0;ON;;;;;N;;;;;
+2630;TRIGRAM FOR HEAVEN;So;0;ON;;;;;N;;;;;
+2631;TRIGRAM FOR LAKE;So;0;ON;;;;;N;;;;;
+2632;TRIGRAM FOR FIRE;So;0;ON;;;;;N;;;;;
+2633;TRIGRAM FOR THUNDER;So;0;ON;;;;;N;;;;;
+2634;TRIGRAM FOR WIND;So;0;ON;;;;;N;;;;;
+2635;TRIGRAM FOR WATER;So;0;ON;;;;;N;;;;;
+2636;TRIGRAM FOR MOUNTAIN;So;0;ON;;;;;N;;;;;
+2637;TRIGRAM FOR EARTH;So;0;ON;;;;;N;;;;;
+2638;WHEEL OF DHARMA;So;0;ON;;;;;N;;;;;
+2639;WHITE FROWNING FACE;So;0;ON;;;;;N;;;;;
+263A;WHITE SMILING FACE;So;0;ON;;;;;N;;;;;
+263B;BLACK SMILING FACE;So;0;ON;;;;;N;;;;;
+263C;WHITE SUN WITH RAYS;So;0;ON;;;;;N;;;;;
+263D;FIRST QUARTER MOON;So;0;ON;;;;;N;;;;;
+263E;LAST QUARTER MOON;So;0;ON;;;;;N;;;;;
+263F;MERCURY;So;0;ON;;;;;N;;;;;
+2640;FEMALE SIGN;So;0;ON;;;;;N;;;;;
+2641;EARTH;So;0;ON;;;;;N;;;;;
+2642;MALE SIGN;So;0;ON;;;;;N;;;;;
+2643;JUPITER;So;0;ON;;;;;N;;;;;
+2644;SATURN;So;0;ON;;;;;N;;;;;
+2645;URANUS;So;0;ON;;;;;N;;;;;
+2646;NEPTUNE;So;0;ON;;;;;N;;;;;
+2647;PLUTO;So;0;ON;;;;;N;;;;;
+2648;ARIES;So;0;ON;;;;;N;;;;;
+2649;TAURUS;So;0;ON;;;;;N;;;;;
+264A;GEMINI;So;0;ON;;;;;N;;;;;
+264B;CANCER;So;0;ON;;;;;N;;;;;
+264C;LEO;So;0;ON;;;;;N;;;;;
+264D;VIRGO;So;0;ON;;;;;N;;;;;
+264E;LIBRA;So;0;ON;;;;;N;;;;;
+264F;SCORPIUS;So;0;ON;;;;;N;;;;;
+2650;SAGITTARIUS;So;0;ON;;;;;N;;;;;
+2651;CAPRICORN;So;0;ON;;;;;N;;;;;
+2652;AQUARIUS;So;0;ON;;;;;N;;;;;
+2653;PISCES;So;0;ON;;;;;N;;;;;
+2654;WHITE CHESS KING;So;0;ON;;;;;N;;;;;
+2655;WHITE CHESS QUEEN;So;0;ON;;;;;N;;;;;
+2656;WHITE CHESS ROOK;So;0;ON;;;;;N;;;;;
+2657;WHITE CHESS BISHOP;So;0;ON;;;;;N;;;;;
+2658;WHITE CHESS KNIGHT;So;0;ON;;;;;N;;;;;
+2659;WHITE CHESS PAWN;So;0;ON;;;;;N;;;;;
+265A;BLACK CHESS KING;So;0;ON;;;;;N;;;;;
+265B;BLACK CHESS QUEEN;So;0;ON;;;;;N;;;;;
+265C;BLACK CHESS ROOK;So;0;ON;;;;;N;;;;;
+265D;BLACK CHESS BISHOP;So;0;ON;;;;;N;;;;;
+265E;BLACK CHESS KNIGHT;So;0;ON;;;;;N;;;;;
+265F;BLACK CHESS PAWN;So;0;ON;;;;;N;;;;;
+2660;BLACK SPADE SUIT;So;0;ON;;;;;N;;;;;
+2661;WHITE HEART SUIT;So;0;ON;;;;;N;;;;;
+2662;WHITE DIAMOND SUIT;So;0;ON;;;;;N;;;;;
+2663;BLACK CLUB SUIT;So;0;ON;;;;;N;;;;;
+2664;WHITE SPADE SUIT;So;0;ON;;;;;N;;;;;
+2665;BLACK HEART SUIT;So;0;ON;;;;;N;;;;;
+2666;BLACK DIAMOND SUIT;So;0;ON;;;;;N;;;;;
+2667;WHITE CLUB SUIT;So;0;ON;;;;;N;;;;;
+2668;HOT SPRINGS;So;0;ON;;;;;N;;;;;
+2669;QUARTER NOTE;So;0;ON;;;;;N;;;;;
+266A;EIGHTH NOTE;So;0;ON;;;;;N;;;;;
+266B;BEAMED EIGHTH NOTES;So;0;ON;;;;;N;BARRED EIGHTH NOTES;;;;
+266C;BEAMED SIXTEENTH NOTES;So;0;ON;;;;;N;BARRED SIXTEENTH NOTES;;;;
+266D;MUSIC FLAT SIGN;So;0;ON;;;;;N;FLAT;;;;
+266E;MUSIC NATURAL SIGN;So;0;ON;;;;;N;NATURAL;;;;
+266F;MUSIC SHARP SIGN;Sm;0;ON;;;;;N;SHARP;;;;
+2670;WEST SYRIAC CROSS;So;0;ON;;;;;N;;;;;
+2671;EAST SYRIAC CROSS;So;0;ON;;;;;N;;;;;
+2672;UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;;
+2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;;;;
+2674;RECYCLING SYMBOL FOR TYPE-2 PLASTICS;So;0;ON;;;;;N;;;;;
+2675;RECYCLING SYMBOL FOR TYPE-3 PLASTICS;So;0;ON;;;;;N;;;;;
+2676;RECYCLING SYMBOL FOR TYPE-4 PLASTICS;So;0;ON;;;;;N;;;;;
+2677;RECYCLING SYMBOL FOR TYPE-5 PLASTICS;So;0;ON;;;;;N;;;;;
+2678;RECYCLING SYMBOL FOR TYPE-6 PLASTICS;So;0;ON;;;;;N;;;;;
+2679;RECYCLING SYMBOL FOR TYPE-7 PLASTICS;So;0;ON;;;;;N;;;;;
+267A;RECYCLING SYMBOL FOR GENERIC MATERIALS;So;0;ON;;;;;N;;;;;
+267B;BLACK UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;;
+267C;RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;;
+267D;PARTIALLY-RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;;
+267E;PERMANENT PAPER SIGN;So;0;ON;;;;;N;;;;;
+267F;WHEELCHAIR SYMBOL;So;0;ON;;;;;N;;;;;
+2680;DIE FACE-1;So;0;ON;;;;;N;;;;;
+2681;DIE FACE-2;So;0;ON;;;;;N;;;;;
+2682;DIE FACE-3;So;0;ON;;;;;N;;;;;
+2683;DIE FACE-4;So;0;ON;;;;;N;;;;;
+2684;DIE FACE-5;So;0;ON;;;;;N;;;;;
+2685;DIE FACE-6;So;0;ON;;;;;N;;;;;
+2686;WHITE CIRCLE WITH DOT RIGHT;So;0;ON;;;;;N;;;;;
+2687;WHITE CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;;
+2688;BLACK CIRCLE WITH WHITE DOT RIGHT;So;0;ON;;;;;N;;;;;
+2689;BLACK CIRCLE WITH TWO WHITE DOTS;So;0;ON;;;;;N;;;;;
+268A;MONOGRAM FOR YANG;So;0;ON;;;;;N;;;;;
+268B;MONOGRAM FOR YIN;So;0;ON;;;;;N;;;;;
+268C;DIGRAM FOR GREATER YANG;So;0;ON;;;;;N;;;;;
+268D;DIGRAM FOR LESSER YIN;So;0;ON;;;;;N;;;;;
+268E;DIGRAM FOR LESSER YANG;So;0;ON;;;;;N;;;;;
+268F;DIGRAM FOR GREATER YIN;So;0;ON;;;;;N;;;;;
+2690;WHITE FLAG;So;0;ON;;;;;N;;;;;
+2691;BLACK FLAG;So;0;ON;;;;;N;;;;;
+2692;HAMMER AND PICK;So;0;ON;;;;;N;;;;;
+2693;ANCHOR;So;0;ON;;;;;N;;;;;
+2694;CROSSED SWORDS;So;0;ON;;;;;N;;;;;
+2695;STAFF OF AESCULAPIUS;So;0;ON;;;;;N;;;;;
+2696;SCALES;So;0;ON;;;;;N;;;;;
+2697;ALEMBIC;So;0;ON;;;;;N;;;;;
+2698;FLOWER;So;0;ON;;;;;N;;;;;
+2699;GEAR;So;0;ON;;;;;N;;;;;
+269A;STAFF OF HERMES;So;0;ON;;;;;N;;;;;
+269B;ATOM SYMBOL;So;0;ON;;;;;N;;;;;
+269C;FLEUR-DE-LIS;So;0;ON;;;;;N;;;;;
+269D;OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;;
+269E;THREE LINES CONVERGING RIGHT;So;0;ON;;;;;N;;;;;
+269F;THREE LINES CONVERGING LEFT;So;0;ON;;;;;N;;;;;
+26A0;WARNING SIGN;So;0;ON;;;;;N;;;;;
+26A1;HIGH VOLTAGE SIGN;So;0;ON;;;;;N;;;;;
+26A2;DOUBLED FEMALE SIGN;So;0;ON;;;;;N;;;;;
+26A3;DOUBLED MALE SIGN;So;0;ON;;;;;N;;;;;
+26A4;INTERLOCKED FEMALE AND MALE SIGN;So;0;ON;;;;;N;;;;;
+26A5;MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;;
+26A6;MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;
+26A7;MALE WITH STROKE AND MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;;
+26A8;VERTICAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;
+26A9;HORIZONTAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;
+26AA;MEDIUM WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+26AB;MEDIUM BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+26AC;MEDIUM SMALL WHITE CIRCLE;So;0;L;;;;;N;;;;;
+26AD;MARRIAGE SYMBOL;So;0;ON;;;;;N;;;;;
+26AE;DIVORCE SYMBOL;So;0;ON;;;;;N;;;;;
+26AF;UNMARRIED PARTNERSHIP SYMBOL;So;0;ON;;;;;N;;;;;
+26B0;COFFIN;So;0;ON;;;;;N;;;;;
+26B1;FUNERAL URN;So;0;ON;;;;;N;;;;;
+26B2;NEUTER;So;0;ON;;;;;N;;;;;
+26B3;CERES;So;0;ON;;;;;N;;;;;
+26B4;PALLAS;So;0;ON;;;;;N;;;;;
+26B5;JUNO;So;0;ON;;;;;N;;;;;
+26B6;VESTA;So;0;ON;;;;;N;;;;;
+26B7;CHIRON;So;0;ON;;;;;N;;;;;
+26B8;BLACK MOON LILITH;So;0;ON;;;;;N;;;;;
+26B9;SEXTILE;So;0;ON;;;;;N;;;;;
+26BA;SEMISEXTILE;So;0;ON;;;;;N;;;;;
+26BB;QUINCUNX;So;0;ON;;;;;N;;;;;
+26BC;SESQUIQUADRATE;So;0;ON;;;;;N;;;;;
+26BD;SOCCER BALL;So;0;ON;;;;;N;;;;;
+26BE;BASEBALL;So;0;ON;;;;;N;;;;;
+26BF;SQUARED KEY;So;0;ON;;;;;N;;;;;
+26C0;WHITE DRAUGHTS MAN;So;0;ON;;;;;N;;;;;
+26C1;WHITE DRAUGHTS KING;So;0;ON;;;;;N;;;;;
+26C2;BLACK DRAUGHTS MAN;So;0;ON;;;;;N;;;;;
+26C3;BLACK DRAUGHTS KING;So;0;ON;;;;;N;;;;;
+26C4;SNOWMAN WITHOUT SNOW;So;0;ON;;;;;N;;;;;
+26C5;SUN BEHIND CLOUD;So;0;ON;;;;;N;;;;;
+26C6;RAIN;So;0;ON;;;;;N;;;;;
+26C7;BLACK SNOWMAN;So;0;ON;;;;;N;;;;;
+26C8;THUNDER CLOUD AND RAIN;So;0;ON;;;;;N;;;;;
+26C9;TURNED WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;;
+26CA;TURNED BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;;
+26CB;WHITE DIAMOND IN SQUARE;So;0;ON;;;;;N;;;;;
+26CC;CROSSING LANES;So;0;ON;;;;;N;;;;;
+26CD;DISABLED CAR;So;0;ON;;;;;N;;;;;
+26CE;OPHIUCHUS;So;0;ON;;;;;N;;;;;
+26CF;PICK;So;0;ON;;;;;N;;;;;
+26D0;CAR SLIDING;So;0;ON;;;;;N;;;;;
+26D1;HELMET WITH WHITE CROSS;So;0;ON;;;;;N;;;;;
+26D2;CIRCLED CROSSING LANES;So;0;ON;;;;;N;;;;;
+26D3;CHAINS;So;0;ON;;;;;N;;;;;
+26D4;NO ENTRY;So;0;ON;;;;;N;;;;;
+26D5;ALTERNATE ONE-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;;
+26D6;BLACK TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;;
+26D7;WHITE TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;;
+26D8;BLACK LEFT LANE MERGE;So;0;ON;;;;;N;;;;;
+26D9;WHITE LEFT LANE MERGE;So;0;ON;;;;;N;;;;;
+26DA;DRIVE SLOW SIGN;So;0;ON;;;;;N;;;;;
+26DB;HEAVY WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;
+26DC;LEFT CLOSED ENTRY;So;0;ON;;;;;N;;;;;
+26DD;SQUARED SALTIRE;So;0;ON;;;;;N;;;;;
+26DE;FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE;So;0;ON;;;;;N;;;;;
+26DF;BLACK TRUCK;So;0;ON;;;;;N;;;;;
+26E0;RESTRICTED LEFT ENTRY-1;So;0;ON;;;;;N;;;;;
+26E1;RESTRICTED LEFT ENTRY-2;So;0;ON;;;;;N;;;;;
+26E2;ASTRONOMICAL SYMBOL FOR URANUS;So;0;ON;;;;;N;;;;;
+26E3;HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE;So;0;ON;;;;;N;;;;;
+26E4;PENTAGRAM;So;0;ON;;;;;N;;;;;
+26E5;RIGHT-HANDED INTERLACED PENTAGRAM;So;0;ON;;;;;N;;;;;
+26E6;LEFT-HANDED INTERLACED PENTAGRAM;So;0;ON;;;;;N;;;;;
+26E7;INVERTED PENTAGRAM;So;0;ON;;;;;N;;;;;
+26E8;BLACK CROSS ON SHIELD;So;0;ON;;;;;N;;;;;
+26E9;SHINTO SHRINE;So;0;ON;;;;;N;;;;;
+26EA;CHURCH;So;0;ON;;;;;N;;;;;
+26EB;CASTLE;So;0;ON;;;;;N;;;;;
+26EC;HISTORIC SITE;So;0;ON;;;;;N;;;;;
+26ED;GEAR WITHOUT HUB;So;0;ON;;;;;N;;;;;
+26EE;GEAR WITH HANDLES;So;0;ON;;;;;N;;;;;
+26EF;MAP SYMBOL FOR LIGHTHOUSE;So;0;ON;;;;;N;;;;;
+26F0;MOUNTAIN;So;0;ON;;;;;N;;;;;
+26F1;UMBRELLA ON GROUND;So;0;ON;;;;;N;;;;;
+26F2;FOUNTAIN;So;0;ON;;;;;N;;;;;
+26F3;FLAG IN HOLE;So;0;ON;;;;;N;;;;;
+26F4;FERRY;So;0;ON;;;;;N;;;;;
+26F5;SAILBOAT;So;0;ON;;;;;N;;;;;
+26F6;SQUARE FOUR CORNERS;So;0;ON;;;;;N;;;;;
+26F7;SKIER;So;0;ON;;;;;N;;;;;
+26F8;ICE SKATE;So;0;ON;;;;;N;;;;;
+26F9;PERSON WITH BALL;So;0;ON;;;;;N;;;;;
+26FA;TENT;So;0;ON;;;;;N;;;;;
+26FB;JAPANESE BANK SYMBOL;So;0;ON;;;;;N;;;;;
+26FC;HEADSTONE GRAVEYARD SYMBOL;So;0;ON;;;;;N;;;;;
+26FD;FUEL PUMP;So;0;ON;;;;;N;;;;;
+26FE;CUP ON BLACK SQUARE;So;0;ON;;;;;N;;;;;
+26FF;WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE;So;0;ON;;;;;N;;;;;
+2700;BLACK SAFETY SCISSORS;So;0;ON;;;;;N;;;;;
+2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;;
+2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;;
+2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;;
+2704;WHITE SCISSORS;So;0;ON;;;;;N;;;;;
+2705;WHITE HEAVY CHECK MARK;So;0;ON;;;;;N;;;;;
+2706;TELEPHONE LOCATION SIGN;So;0;ON;;;;;N;;;;;
+2707;TAPE DRIVE;So;0;ON;;;;;N;;;;;
+2708;AIRPLANE;So;0;ON;;;;;N;;;;;
+2709;ENVELOPE;So;0;ON;;;;;N;;;;;
+270A;RAISED FIST;So;0;ON;;;;;N;;;;;
+270B;RAISED HAND;So;0;ON;;;;;N;;;;;
+270C;VICTORY HAND;So;0;ON;;;;;N;;;;;
+270D;WRITING HAND;So;0;ON;;;;;N;;;;;
+270E;LOWER RIGHT PENCIL;So;0;ON;;;;;N;;;;;
+270F;PENCIL;So;0;ON;;;;;N;;;;;
+2710;UPPER RIGHT PENCIL;So;0;ON;;;;;N;;;;;
+2711;WHITE NIB;So;0;ON;;;;;N;;;;;
+2712;BLACK NIB;So;0;ON;;;;;N;;;;;
+2713;CHECK MARK;So;0;ON;;;;;N;;;;;
+2714;HEAVY CHECK MARK;So;0;ON;;;;;N;;;;;
+2715;MULTIPLICATION X;So;0;ON;;;;;N;;;;;
+2716;HEAVY MULTIPLICATION X;So;0;ON;;;;;N;;;;;
+2717;BALLOT X;So;0;ON;;;;;N;;;;;
+2718;HEAVY BALLOT X;So;0;ON;;;;;N;;;;;
+2719;OUTLINED GREEK CROSS;So;0;ON;;;;;N;;;;;
+271A;HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;;
+271B;OPEN CENTRE CROSS;So;0;ON;;;;;N;OPEN CENTER CROSS;;;;
+271C;HEAVY OPEN CENTRE CROSS;So;0;ON;;;;;N;HEAVY OPEN CENTER CROSS;;;;
+271D;LATIN CROSS;So;0;ON;;;;;N;;;;;
+271E;SHADOWED WHITE LATIN CROSS;So;0;ON;;;;;N;;;;;
+271F;OUTLINED LATIN CROSS;So;0;ON;;;;;N;;;;;
+2720;MALTESE CROSS;So;0;ON;;;;;N;;;;;
+2721;STAR OF DAVID;So;0;ON;;;;;N;;;;;
+2722;FOUR TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2723;FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2724;HEAVY FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2725;FOUR CLUB-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2726;BLACK FOUR POINTED STAR;So;0;ON;;;;;N;;;;;
+2727;WHITE FOUR POINTED STAR;So;0;ON;;;;;N;;;;;
+2728;SPARKLES;So;0;ON;;;;;N;;;;;
+2729;STRESS OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;;
+272A;CIRCLED WHITE STAR;So;0;ON;;;;;N;;;;;
+272B;OPEN CENTRE BLACK STAR;So;0;ON;;;;;N;OPEN CENTER BLACK STAR;;;;
+272C;BLACK CENTRE WHITE STAR;So;0;ON;;;;;N;BLACK CENTER WHITE STAR;;;;
+272D;OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;;
+272E;HEAVY OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;;
+272F;PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+2730;SHADOWED WHITE STAR;So;0;ON;;;;;N;;;;;
+2731;HEAVY ASTERISK;So;0;ON;;;;;N;;;;;
+2732;OPEN CENTRE ASTERISK;So;0;ON;;;;;N;OPEN CENTER ASTERISK;;;;
+2733;EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+2734;EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+2735;EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+2736;SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+2737;EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;;
+2738;HEAVY EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;;
+2739;TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+273A;SIXTEEN POINTED ASTERISK;So;0;ON;;;;;N;;;;;
+273B;TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+273C;OPEN CENTRE TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;OPEN CENTER TEARDROP-SPOKED ASTERISK;;;;
+273D;HEAVY TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+273E;SIX PETALLED BLACK AND WHITE FLORETTE;So;0;ON;;;;;N;;;;;
+273F;BLACK FLORETTE;So;0;ON;;;;;N;;;;;
+2740;WHITE FLORETTE;So;0;ON;;;;;N;;;;;
+2741;EIGHT PETALLED OUTLINED BLACK FLORETTE;So;0;ON;;;;;N;;;;;
+2742;CIRCLED OPEN CENTRE EIGHT POINTED STAR;So;0;ON;;;;;N;CIRCLED OPEN CENTER EIGHT POINTED STAR;;;;
+2743;HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK;So;0;ON;;;;;N;;;;;
+2744;SNOWFLAKE;So;0;ON;;;;;N;;;;;
+2745;TIGHT TRIFOLIATE SNOWFLAKE;So;0;ON;;;;;N;;;;;
+2746;HEAVY CHEVRON SNOWFLAKE;So;0;ON;;;;;N;;;;;
+2747;SPARKLE;So;0;ON;;;;;N;;;;;
+2748;HEAVY SPARKLE;So;0;ON;;;;;N;;;;;
+2749;BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+274A;EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;
+274B;HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;
+274C;CROSS MARK;So;0;ON;;;;;N;;;;;
+274D;SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+274E;NEGATIVE SQUARED CROSS MARK;So;0;ON;;;;;N;;;;;
+274F;LOWER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2750;UPPER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
+2753;BLACK QUESTION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2754;WHITE QUESTION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2755;WHITE EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;;
+2757;HEAVY EXCLAMATION MARK SYMBOL;So;0;ON;;;;;N;;;;;
+2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;;
+2759;MEDIUM VERTICAL BAR;So;0;ON;;;;;N;;;;;
+275A;HEAVY VERTICAL BAR;So;0;ON;;;;;N;;;;;
+275B;HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275C;HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275D;HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275E;HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+275F;HEAVY LOW SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2760;HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2761;CURVED STEM PARAGRAPH SIGN ORNAMENT;So;0;ON;;;;;N;;;;;
+2762;HEAVY EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2763;HEAVY HEART EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+2764;HEAVY BLACK HEART;So;0;ON;;;;;N;;;;;
+2765;ROTATED HEAVY BLACK HEART BULLET;So;0;ON;;;;;N;;;;;
+2766;FLORAL HEART;So;0;ON;;;;;N;;;;;
+2767;ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;;
+2768;MEDIUM LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+2769;MEDIUM RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+276A;MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+276B;MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+276C;MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+276D;MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+276E;HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+276F;HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+2770;HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+2771;HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+2772;LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+2773;LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+2774;MEDIUM LEFT CURLY BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
+2775;MEDIUM RIGHT CURLY BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
+2776;DINGBAT NEGATIVE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED DIGIT ONE;;;;
+2777;DINGBAT NEGATIVE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED DIGIT TWO;;;;
+2778;DINGBAT NEGATIVE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED DIGIT THREE;;;;
+2779;DINGBAT NEGATIVE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED DIGIT FOUR;;;;
+277A;DINGBAT NEGATIVE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED DIGIT FIVE;;;;
+277B;DINGBAT NEGATIVE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED DIGIT SIX;;;;
+277C;DINGBAT NEGATIVE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED DIGIT SEVEN;;;;
+277D;DINGBAT NEGATIVE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED DIGIT EIGHT;;;;
+277E;DINGBAT NEGATIVE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED DIGIT NINE;;;;
+277F;DINGBAT NEGATIVE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED NUMBER TEN;;;;
+2780;DINGBAT CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;CIRCLED SANS-SERIF DIGIT ONE;;;;
+2781;DINGBAT CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;CIRCLED SANS-SERIF DIGIT TWO;;;;
+2782;DINGBAT CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;CIRCLED SANS-SERIF DIGIT THREE;;;;
+2783;DINGBAT CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;CIRCLED SANS-SERIF DIGIT FOUR;;;;
+2784;DINGBAT CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;CIRCLED SANS-SERIF DIGIT FIVE;;;;
+2785;DINGBAT CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;CIRCLED SANS-SERIF DIGIT SIX;;;;
+2786;DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;CIRCLED SANS-SERIF DIGIT SEVEN;;;;
+2787;DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;CIRCLED SANS-SERIF DIGIT EIGHT;;;;
+2788;DINGBAT CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;CIRCLED SANS-SERIF DIGIT NINE;;;;
+2789;DINGBAT CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;CIRCLED SANS-SERIF NUMBER TEN;;;;
+278A;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED SANS-SERIF DIGIT ONE;;;;
+278B;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED SANS-SERIF DIGIT TWO;;;;
+278C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED SANS-SERIF DIGIT THREE;;;;
+278D;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED SANS-SERIF DIGIT FOUR;;;;
+278E;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED SANS-SERIF DIGIT FIVE;;;;
+278F;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED SANS-SERIF DIGIT SIX;;;;
+2790;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED SANS-SERIF DIGIT SEVEN;;;;
+2791;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED SANS-SERIF DIGIT EIGHT;;;;
+2792;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED SANS-SERIF DIGIT NINE;;;;
+2793;DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED SANS-SERIF NUMBER TEN;;;;
+2794;HEAVY WIDE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WIDE-HEADED RIGHT ARROW;;;;
+2795;HEAVY PLUS SIGN;So;0;ON;;;;;N;;;;;
+2796;HEAVY MINUS SIGN;So;0;ON;;;;;N;;;;;
+2797;HEAVY DIVISION SIGN;So;0;ON;;;;;N;;;;;
+2798;HEAVY SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT ARROW;;;;
+2799;HEAVY RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY RIGHT ARROW;;;;
+279A;HEAVY NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT ARROW;;;;
+279B;DRAFTING POINT RIGHTWARDS ARROW;So;0;ON;;;;;N;DRAFTING POINT RIGHT ARROW;;;;
+279C;HEAVY ROUND-TIPPED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY ROUND-TIPPED RIGHT ARROW;;;;
+279D;TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;TRIANGLE-HEADED RIGHT ARROW;;;;
+279E;HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TRIANGLE-HEADED RIGHT ARROW;;;;
+279F;DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;DASHED TRIANGLE-HEADED RIGHT ARROW;;;;
+27A0;HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY DASHED TRIANGLE-HEADED RIGHT ARROW;;;;
+27A1;BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK RIGHT ARROW;;;;
+27A2;THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D TOP-LIGHTED RIGHT ARROWHEAD;;;;
+27A3;THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D BOTTOM-LIGHTED RIGHT ARROWHEAD;;;;
+27A4;BLACK RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;BLACK RIGHT ARROWHEAD;;;;
+27A5;HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED DOWN AND RIGHT ARROW;;;;
+27A6;HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED UP AND RIGHT ARROW;;;;
+27A7;SQUAT BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;SQUAT BLACK RIGHT ARROW;;;;
+27A8;HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY CONCAVE-POINTED BLACK RIGHT ARROW;;;;
+27A9;RIGHT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;RIGHT-SHADED WHITE RIGHT ARROW;;;;
+27AA;LEFT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT-SHADED WHITE RIGHT ARROW;;;;
+27AB;BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;BACK-TILTED SHADOWED WHITE RIGHT ARROW;;;;
+27AC;FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;FRONT-TILTED SHADOWED WHITE RIGHT ARROW;;;;
+27AD;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27AE;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27AF;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27B0;CURLY LOOP;So;0;ON;;;;;N;;;;;
+27B1;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
+27B2;CIRCLED HEAVY WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;CIRCLED HEAVY WHITE RIGHT ARROW;;;;
+27B3;WHITE-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;WHITE-FEATHERED RIGHT ARROW;;;;
+27B4;BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED LOWER RIGHT ARROW;;;;
+27B5;BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK-FEATHERED RIGHT ARROW;;;;
+27B6;BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED UPPER RIGHT ARROW;;;;
+27B7;HEAVY BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED LOWER RIGHT ARROW;;;;
+27B8;HEAVY BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED RIGHT ARROW;;;;
+27B9;HEAVY BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED UPPER RIGHT ARROW;;;;
+27BA;TEARDROP-BARBED RIGHTWARDS ARROW;So;0;ON;;;;;N;TEARDROP-BARBED RIGHT ARROW;;;;
+27BB;HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TEARDROP-SHANKED RIGHT ARROW;;;;
+27BC;WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;WEDGE-TAILED RIGHT ARROW;;;;
+27BD;HEAVY WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WEDGE-TAILED RIGHT ARROW;;;;
+27BE;OPEN-OUTLINED RIGHTWARDS ARROW;So;0;ON;;;;;N;OPEN-OUTLINED RIGHT ARROW;;;;
+27BF;DOUBLE CURLY LOOP;So;0;ON;;;;;N;;;;;
+27C0;THREE DIMENSIONAL ANGLE;Sm;0;ON;;;;;Y;;;;;
+27C1;WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE;Sm;0;ON;;;;;N;;;;;
+27C2;PERPENDICULAR;Sm;0;ON;;;;;N;;;;;
+27C3;OPEN SUBSET;Sm;0;ON;;;;;Y;;;;;
+27C4;OPEN SUPERSET;Sm;0;ON;;;;;Y;;;;;
+27C5;LEFT S-SHAPED BAG DELIMITER;Ps;0;ON;;;;;Y;;;;;
+27C6;RIGHT S-SHAPED BAG DELIMITER;Pe;0;ON;;;;;Y;;;;;
+27C7;OR WITH DOT INSIDE;Sm;0;ON;;;;;N;;;;;
+27C8;REVERSE SOLIDUS PRECEDING SUBSET;Sm;0;ON;;;;;Y;;;;;
+27C9;SUPERSET PRECEDING SOLIDUS;Sm;0;ON;;;;;Y;;;;;
+27CA;VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
+27CB;MATHEMATICAL RISING DIAGONAL;Sm;0;ON;;;;;Y;;;;;
+27CC;LONG DIVISION;Sm;0;ON;;;;;Y;;;;;
+27CD;MATHEMATICAL FALLING DIAGONAL;Sm;0;ON;;;;;Y;;;;;
+27CE;SQUARED LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+27CF;SQUARED LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+27D0;WHITE DIAMOND WITH CENTRED DOT;Sm;0;ON;;;;;N;;;;;
+27D1;AND WITH DOT;Sm;0;ON;;;;;N;;;;;
+27D2;ELEMENT OF OPENING UPWARDS;Sm;0;ON;;;;;N;;;;;
+27D3;LOWER RIGHT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;;
+27D4;UPPER LEFT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;;
+27D5;LEFT OUTER JOIN;Sm;0;ON;;;;;Y;;;;;
+27D6;RIGHT OUTER JOIN;Sm;0;ON;;;;;Y;;;;;
+27D7;FULL OUTER JOIN;Sm;0;ON;;;;;N;;;;;
+27D8;LARGE UP TACK;Sm;0;ON;;;;;N;;;;;
+27D9;LARGE DOWN TACK;Sm;0;ON;;;;;N;;;;;
+27DA;LEFT AND RIGHT DOUBLE TURNSTILE;Sm;0;ON;;;;;N;;;;;
+27DB;LEFT AND RIGHT TACK;Sm;0;ON;;;;;N;;;;;
+27DC;LEFT MULTIMAP;Sm;0;ON;;;;;Y;;;;;
+27DD;LONG RIGHT TACK;Sm;0;ON;;;;;Y;;;;;
+27DE;LONG LEFT TACK;Sm;0;ON;;;;;Y;;;;;
+27DF;UP TACK WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
+27E0;LOZENGE DIVIDED BY HORIZONTAL RULE;Sm;0;ON;;;;;N;;;;;
+27E1;WHITE CONCAVE-SIDED DIAMOND;Sm;0;ON;;;;;N;;;;;
+27E2;WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
+27E3;WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
+27E4;WHITE SQUARE WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
+27E5;WHITE SQUARE WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
+27E6;MATHEMATICAL LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;;;;;
+27E7;MATHEMATICAL RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;;;;;
+27E8;MATHEMATICAL LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;
+27E9;MATHEMATICAL RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;
+27EA;MATHEMATICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;
+27EB;MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;
+27EC;MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;;
+27ED;MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;;
+27EE;MATHEMATICAL LEFT FLATTENED PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
+27EF;MATHEMATICAL RIGHT FLATTENED PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
+27F0;UPWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;;
+27F1;DOWNWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;;
+27F2;ANTICLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
+27F3;CLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
+27F4;RIGHT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;
+27F5;LONG LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+27F6;LONG RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+27F7;LONG LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;;
+27F8;LONG LEFTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
+27F9;LONG RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
+27FA;LONG LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
+27FB;LONG LEFTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+27FC;LONG RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+27FD;LONG LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+27FE;LONG RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+27FF;LONG RIGHTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;;
+2800;BRAILLE PATTERN BLANK;So;0;L;;;;;N;;;;;
+2801;BRAILLE PATTERN DOTS-1;So;0;L;;;;;N;;;;;
+2802;BRAILLE PATTERN DOTS-2;So;0;L;;;;;N;;;;;
+2803;BRAILLE PATTERN DOTS-12;So;0;L;;;;;N;;;;;
+2804;BRAILLE PATTERN DOTS-3;So;0;L;;;;;N;;;;;
+2805;BRAILLE PATTERN DOTS-13;So;0;L;;;;;N;;;;;
+2806;BRAILLE PATTERN DOTS-23;So;0;L;;;;;N;;;;;
+2807;BRAILLE PATTERN DOTS-123;So;0;L;;;;;N;;;;;
+2808;BRAILLE PATTERN DOTS-4;So;0;L;;;;;N;;;;;
+2809;BRAILLE PATTERN DOTS-14;So;0;L;;;;;N;;;;;
+280A;BRAILLE PATTERN DOTS-24;So;0;L;;;;;N;;;;;
+280B;BRAILLE PATTERN DOTS-124;So;0;L;;;;;N;;;;;
+280C;BRAILLE PATTERN DOTS-34;So;0;L;;;;;N;;;;;
+280D;BRAILLE PATTERN DOTS-134;So;0;L;;;;;N;;;;;
+280E;BRAILLE PATTERN DOTS-234;So;0;L;;;;;N;;;;;
+280F;BRAILLE PATTERN DOTS-1234;So;0;L;;;;;N;;;;;
+2810;BRAILLE PATTERN DOTS-5;So;0;L;;;;;N;;;;;
+2811;BRAILLE PATTERN DOTS-15;So;0;L;;;;;N;;;;;
+2812;BRAILLE PATTERN DOTS-25;So;0;L;;;;;N;;;;;
+2813;BRAILLE PATTERN DOTS-125;So;0;L;;;;;N;;;;;
+2814;BRAILLE PATTERN DOTS-35;So;0;L;;;;;N;;;;;
+2815;BRAILLE PATTERN DOTS-135;So;0;L;;;;;N;;;;;
+2816;BRAILLE PATTERN DOTS-235;So;0;L;;;;;N;;;;;
+2817;BRAILLE PATTERN DOTS-1235;So;0;L;;;;;N;;;;;
+2818;BRAILLE PATTERN DOTS-45;So;0;L;;;;;N;;;;;
+2819;BRAILLE PATTERN DOTS-145;So;0;L;;;;;N;;;;;
+281A;BRAILLE PATTERN DOTS-245;So;0;L;;;;;N;;;;;
+281B;BRAILLE PATTERN DOTS-1245;So;0;L;;;;;N;;;;;
+281C;BRAILLE PATTERN DOTS-345;So;0;L;;;;;N;;;;;
+281D;BRAILLE PATTERN DOTS-1345;So;0;L;;;;;N;;;;;
+281E;BRAILLE PATTERN DOTS-2345;So;0;L;;;;;N;;;;;
+281F;BRAILLE PATTERN DOTS-12345;So;0;L;;;;;N;;;;;
+2820;BRAILLE PATTERN DOTS-6;So;0;L;;;;;N;;;;;
+2821;BRAILLE PATTERN DOTS-16;So;0;L;;;;;N;;;;;
+2822;BRAILLE PATTERN DOTS-26;So;0;L;;;;;N;;;;;
+2823;BRAILLE PATTERN DOTS-126;So;0;L;;;;;N;;;;;
+2824;BRAILLE PATTERN DOTS-36;So;0;L;;;;;N;;;;;
+2825;BRAILLE PATTERN DOTS-136;So;0;L;;;;;N;;;;;
+2826;BRAILLE PATTERN DOTS-236;So;0;L;;;;;N;;;;;
+2827;BRAILLE PATTERN DOTS-1236;So;0;L;;;;;N;;;;;
+2828;BRAILLE PATTERN DOTS-46;So;0;L;;;;;N;;;;;
+2829;BRAILLE PATTERN DOTS-146;So;0;L;;;;;N;;;;;
+282A;BRAILLE PATTERN DOTS-246;So;0;L;;;;;N;;;;;
+282B;BRAILLE PATTERN DOTS-1246;So;0;L;;;;;N;;;;;
+282C;BRAILLE PATTERN DOTS-346;So;0;L;;;;;N;;;;;
+282D;BRAILLE PATTERN DOTS-1346;So;0;L;;;;;N;;;;;
+282E;BRAILLE PATTERN DOTS-2346;So;0;L;;;;;N;;;;;
+282F;BRAILLE PATTERN DOTS-12346;So;0;L;;;;;N;;;;;
+2830;BRAILLE PATTERN DOTS-56;So;0;L;;;;;N;;;;;
+2831;BRAILLE PATTERN DOTS-156;So;0;L;;;;;N;;;;;
+2832;BRAILLE PATTERN DOTS-256;So;0;L;;;;;N;;;;;
+2833;BRAILLE PATTERN DOTS-1256;So;0;L;;;;;N;;;;;
+2834;BRAILLE PATTERN DOTS-356;So;0;L;;;;;N;;;;;
+2835;BRAILLE PATTERN DOTS-1356;So;0;L;;;;;N;;;;;
+2836;BRAILLE PATTERN DOTS-2356;So;0;L;;;;;N;;;;;
+2837;BRAILLE PATTERN DOTS-12356;So;0;L;;;;;N;;;;;
+2838;BRAILLE PATTERN DOTS-456;So;0;L;;;;;N;;;;;
+2839;BRAILLE PATTERN DOTS-1456;So;0;L;;;;;N;;;;;
+283A;BRAILLE PATTERN DOTS-2456;So;0;L;;;;;N;;;;;
+283B;BRAILLE PATTERN DOTS-12456;So;0;L;;;;;N;;;;;
+283C;BRAILLE PATTERN DOTS-3456;So;0;L;;;;;N;;;;;
+283D;BRAILLE PATTERN DOTS-13456;So;0;L;;;;;N;;;;;
+283E;BRAILLE PATTERN DOTS-23456;So;0;L;;;;;N;;;;;
+283F;BRAILLE PATTERN DOTS-123456;So;0;L;;;;;N;;;;;
+2840;BRAILLE PATTERN DOTS-7;So;0;L;;;;;N;;;;;
+2841;BRAILLE PATTERN DOTS-17;So;0;L;;;;;N;;;;;
+2842;BRAILLE PATTERN DOTS-27;So;0;L;;;;;N;;;;;
+2843;BRAILLE PATTERN DOTS-127;So;0;L;;;;;N;;;;;
+2844;BRAILLE PATTERN DOTS-37;So;0;L;;;;;N;;;;;
+2845;BRAILLE PATTERN DOTS-137;So;0;L;;;;;N;;;;;
+2846;BRAILLE PATTERN DOTS-237;So;0;L;;;;;N;;;;;
+2847;BRAILLE PATTERN DOTS-1237;So;0;L;;;;;N;;;;;
+2848;BRAILLE PATTERN DOTS-47;So;0;L;;;;;N;;;;;
+2849;BRAILLE PATTERN DOTS-147;So;0;L;;;;;N;;;;;
+284A;BRAILLE PATTERN DOTS-247;So;0;L;;;;;N;;;;;
+284B;BRAILLE PATTERN DOTS-1247;So;0;L;;;;;N;;;;;
+284C;BRAILLE PATTERN DOTS-347;So;0;L;;;;;N;;;;;
+284D;BRAILLE PATTERN DOTS-1347;So;0;L;;;;;N;;;;;
+284E;BRAILLE PATTERN DOTS-2347;So;0;L;;;;;N;;;;;
+284F;BRAILLE PATTERN DOTS-12347;So;0;L;;;;;N;;;;;
+2850;BRAILLE PATTERN DOTS-57;So;0;L;;;;;N;;;;;
+2851;BRAILLE PATTERN DOTS-157;So;0;L;;;;;N;;;;;
+2852;BRAILLE PATTERN DOTS-257;So;0;L;;;;;N;;;;;
+2853;BRAILLE PATTERN DOTS-1257;So;0;L;;;;;N;;;;;
+2854;BRAILLE PATTERN DOTS-357;So;0;L;;;;;N;;;;;
+2855;BRAILLE PATTERN DOTS-1357;So;0;L;;;;;N;;;;;
+2856;BRAILLE PATTERN DOTS-2357;So;0;L;;;;;N;;;;;
+2857;BRAILLE PATTERN DOTS-12357;So;0;L;;;;;N;;;;;
+2858;BRAILLE PATTERN DOTS-457;So;0;L;;;;;N;;;;;
+2859;BRAILLE PATTERN DOTS-1457;So;0;L;;;;;N;;;;;
+285A;BRAILLE PATTERN DOTS-2457;So;0;L;;;;;N;;;;;
+285B;BRAILLE PATTERN DOTS-12457;So;0;L;;;;;N;;;;;
+285C;BRAILLE PATTERN DOTS-3457;So;0;L;;;;;N;;;;;
+285D;BRAILLE PATTERN DOTS-13457;So;0;L;;;;;N;;;;;
+285E;BRAILLE PATTERN DOTS-23457;So;0;L;;;;;N;;;;;
+285F;BRAILLE PATTERN DOTS-123457;So;0;L;;;;;N;;;;;
+2860;BRAILLE PATTERN DOTS-67;So;0;L;;;;;N;;;;;
+2861;BRAILLE PATTERN DOTS-167;So;0;L;;;;;N;;;;;
+2862;BRAILLE PATTERN DOTS-267;So;0;L;;;;;N;;;;;
+2863;BRAILLE PATTERN DOTS-1267;So;0;L;;;;;N;;;;;
+2864;BRAILLE PATTERN DOTS-367;So;0;L;;;;;N;;;;;
+2865;BRAILLE PATTERN DOTS-1367;So;0;L;;;;;N;;;;;
+2866;BRAILLE PATTERN DOTS-2367;So;0;L;;;;;N;;;;;
+2867;BRAILLE PATTERN DOTS-12367;So;0;L;;;;;N;;;;;
+2868;BRAILLE PATTERN DOTS-467;So;0;L;;;;;N;;;;;
+2869;BRAILLE PATTERN DOTS-1467;So;0;L;;;;;N;;;;;
+286A;BRAILLE PATTERN DOTS-2467;So;0;L;;;;;N;;;;;
+286B;BRAILLE PATTERN DOTS-12467;So;0;L;;;;;N;;;;;
+286C;BRAILLE PATTERN DOTS-3467;So;0;L;;;;;N;;;;;
+286D;BRAILLE PATTERN DOTS-13467;So;0;L;;;;;N;;;;;
+286E;BRAILLE PATTERN DOTS-23467;So;0;L;;;;;N;;;;;
+286F;BRAILLE PATTERN DOTS-123467;So;0;L;;;;;N;;;;;
+2870;BRAILLE PATTERN DOTS-567;So;0;L;;;;;N;;;;;
+2871;BRAILLE PATTERN DOTS-1567;So;0;L;;;;;N;;;;;
+2872;BRAILLE PATTERN DOTS-2567;So;0;L;;;;;N;;;;;
+2873;BRAILLE PATTERN DOTS-12567;So;0;L;;;;;N;;;;;
+2874;BRAILLE PATTERN DOTS-3567;So;0;L;;;;;N;;;;;
+2875;BRAILLE PATTERN DOTS-13567;So;0;L;;;;;N;;;;;
+2876;BRAILLE PATTERN DOTS-23567;So;0;L;;;;;N;;;;;
+2877;BRAILLE PATTERN DOTS-123567;So;0;L;;;;;N;;;;;
+2878;BRAILLE PATTERN DOTS-4567;So;0;L;;;;;N;;;;;
+2879;BRAILLE PATTERN DOTS-14567;So;0;L;;;;;N;;;;;
+287A;BRAILLE PATTERN DOTS-24567;So;0;L;;;;;N;;;;;
+287B;BRAILLE PATTERN DOTS-124567;So;0;L;;;;;N;;;;;
+287C;BRAILLE PATTERN DOTS-34567;So;0;L;;;;;N;;;;;
+287D;BRAILLE PATTERN DOTS-134567;So;0;L;;;;;N;;;;;
+287E;BRAILLE PATTERN DOTS-234567;So;0;L;;;;;N;;;;;
+287F;BRAILLE PATTERN DOTS-1234567;So;0;L;;;;;N;;;;;
+2880;BRAILLE PATTERN DOTS-8;So;0;L;;;;;N;;;;;
+2881;BRAILLE PATTERN DOTS-18;So;0;L;;;;;N;;;;;
+2882;BRAILLE PATTERN DOTS-28;So;0;L;;;;;N;;;;;
+2883;BRAILLE PATTERN DOTS-128;So;0;L;;;;;N;;;;;
+2884;BRAILLE PATTERN DOTS-38;So;0;L;;;;;N;;;;;
+2885;BRAILLE PATTERN DOTS-138;So;0;L;;;;;N;;;;;
+2886;BRAILLE PATTERN DOTS-238;So;0;L;;;;;N;;;;;
+2887;BRAILLE PATTERN DOTS-1238;So;0;L;;;;;N;;;;;
+2888;BRAILLE PATTERN DOTS-48;So;0;L;;;;;N;;;;;
+2889;BRAILLE PATTERN DOTS-148;So;0;L;;;;;N;;;;;
+288A;BRAILLE PATTERN DOTS-248;So;0;L;;;;;N;;;;;
+288B;BRAILLE PATTERN DOTS-1248;So;0;L;;;;;N;;;;;
+288C;BRAILLE PATTERN DOTS-348;So;0;L;;;;;N;;;;;
+288D;BRAILLE PATTERN DOTS-1348;So;0;L;;;;;N;;;;;
+288E;BRAILLE PATTERN DOTS-2348;So;0;L;;;;;N;;;;;
+288F;BRAILLE PATTERN DOTS-12348;So;0;L;;;;;N;;;;;
+2890;BRAILLE PATTERN DOTS-58;So;0;L;;;;;N;;;;;
+2891;BRAILLE PATTERN DOTS-158;So;0;L;;;;;N;;;;;
+2892;BRAILLE PATTERN DOTS-258;So;0;L;;;;;N;;;;;
+2893;BRAILLE PATTERN DOTS-1258;So;0;L;;;;;N;;;;;
+2894;BRAILLE PATTERN DOTS-358;So;0;L;;;;;N;;;;;
+2895;BRAILLE PATTERN DOTS-1358;So;0;L;;;;;N;;;;;
+2896;BRAILLE PATTERN DOTS-2358;So;0;L;;;;;N;;;;;
+2897;BRAILLE PATTERN DOTS-12358;So;0;L;;;;;N;;;;;
+2898;BRAILLE PATTERN DOTS-458;So;0;L;;;;;N;;;;;
+2899;BRAILLE PATTERN DOTS-1458;So;0;L;;;;;N;;;;;
+289A;BRAILLE PATTERN DOTS-2458;So;0;L;;;;;N;;;;;
+289B;BRAILLE PATTERN DOTS-12458;So;0;L;;;;;N;;;;;
+289C;BRAILLE PATTERN DOTS-3458;So;0;L;;;;;N;;;;;
+289D;BRAILLE PATTERN DOTS-13458;So;0;L;;;;;N;;;;;
+289E;BRAILLE PATTERN DOTS-23458;So;0;L;;;;;N;;;;;
+289F;BRAILLE PATTERN DOTS-123458;So;0;L;;;;;N;;;;;
+28A0;BRAILLE PATTERN DOTS-68;So;0;L;;;;;N;;;;;
+28A1;BRAILLE PATTERN DOTS-168;So;0;L;;;;;N;;;;;
+28A2;BRAILLE PATTERN DOTS-268;So;0;L;;;;;N;;;;;
+28A3;BRAILLE PATTERN DOTS-1268;So;0;L;;;;;N;;;;;
+28A4;BRAILLE PATTERN DOTS-368;So;0;L;;;;;N;;;;;
+28A5;BRAILLE PATTERN DOTS-1368;So;0;L;;;;;N;;;;;
+28A6;BRAILLE PATTERN DOTS-2368;So;0;L;;;;;N;;;;;
+28A7;BRAILLE PATTERN DOTS-12368;So;0;L;;;;;N;;;;;
+28A8;BRAILLE PATTERN DOTS-468;So;0;L;;;;;N;;;;;
+28A9;BRAILLE PATTERN DOTS-1468;So;0;L;;;;;N;;;;;
+28AA;BRAILLE PATTERN DOTS-2468;So;0;L;;;;;N;;;;;
+28AB;BRAILLE PATTERN DOTS-12468;So;0;L;;;;;N;;;;;
+28AC;BRAILLE PATTERN DOTS-3468;So;0;L;;;;;N;;;;;
+28AD;BRAILLE PATTERN DOTS-13468;So;0;L;;;;;N;;;;;
+28AE;BRAILLE PATTERN DOTS-23468;So;0;L;;;;;N;;;;;
+28AF;BRAILLE PATTERN DOTS-123468;So;0;L;;;;;N;;;;;
+28B0;BRAILLE PATTERN DOTS-568;So;0;L;;;;;N;;;;;
+28B1;BRAILLE PATTERN DOTS-1568;So;0;L;;;;;N;;;;;
+28B2;BRAILLE PATTERN DOTS-2568;So;0;L;;;;;N;;;;;
+28B3;BRAILLE PATTERN DOTS-12568;So;0;L;;;;;N;;;;;
+28B4;BRAILLE PATTERN DOTS-3568;So;0;L;;;;;N;;;;;
+28B5;BRAILLE PATTERN DOTS-13568;So;0;L;;;;;N;;;;;
+28B6;BRAILLE PATTERN DOTS-23568;So;0;L;;;;;N;;;;;
+28B7;BRAILLE PATTERN DOTS-123568;So;0;L;;;;;N;;;;;
+28B8;BRAILLE PATTERN DOTS-4568;So;0;L;;;;;N;;;;;
+28B9;BRAILLE PATTERN DOTS-14568;So;0;L;;;;;N;;;;;
+28BA;BRAILLE PATTERN DOTS-24568;So;0;L;;;;;N;;;;;
+28BB;BRAILLE PATTERN DOTS-124568;So;0;L;;;;;N;;;;;
+28BC;BRAILLE PATTERN DOTS-34568;So;0;L;;;;;N;;;;;
+28BD;BRAILLE PATTERN DOTS-134568;So;0;L;;;;;N;;;;;
+28BE;BRAILLE PATTERN DOTS-234568;So;0;L;;;;;N;;;;;
+28BF;BRAILLE PATTERN DOTS-1234568;So;0;L;;;;;N;;;;;
+28C0;BRAILLE PATTERN DOTS-78;So;0;L;;;;;N;;;;;
+28C1;BRAILLE PATTERN DOTS-178;So;0;L;;;;;N;;;;;
+28C2;BRAILLE PATTERN DOTS-278;So;0;L;;;;;N;;;;;
+28C3;BRAILLE PATTERN DOTS-1278;So;0;L;;;;;N;;;;;
+28C4;BRAILLE PATTERN DOTS-378;So;0;L;;;;;N;;;;;
+28C5;BRAILLE PATTERN DOTS-1378;So;0;L;;;;;N;;;;;
+28C6;BRAILLE PATTERN DOTS-2378;So;0;L;;;;;N;;;;;
+28C7;BRAILLE PATTERN DOTS-12378;So;0;L;;;;;N;;;;;
+28C8;BRAILLE PATTERN DOTS-478;So;0;L;;;;;N;;;;;
+28C9;BRAILLE PATTERN DOTS-1478;So;0;L;;;;;N;;;;;
+28CA;BRAILLE PATTERN DOTS-2478;So;0;L;;;;;N;;;;;
+28CB;BRAILLE PATTERN DOTS-12478;So;0;L;;;;;N;;;;;
+28CC;BRAILLE PATTERN DOTS-3478;So;0;L;;;;;N;;;;;
+28CD;BRAILLE PATTERN DOTS-13478;So;0;L;;;;;N;;;;;
+28CE;BRAILLE PATTERN DOTS-23478;So;0;L;;;;;N;;;;;
+28CF;BRAILLE PATTERN DOTS-123478;So;0;L;;;;;N;;;;;
+28D0;BRAILLE PATTERN DOTS-578;So;0;L;;;;;N;;;;;
+28D1;BRAILLE PATTERN DOTS-1578;So;0;L;;;;;N;;;;;
+28D2;BRAILLE PATTERN DOTS-2578;So;0;L;;;;;N;;;;;
+28D3;BRAILLE PATTERN DOTS-12578;So;0;L;;;;;N;;;;;
+28D4;BRAILLE PATTERN DOTS-3578;So;0;L;;;;;N;;;;;
+28D5;BRAILLE PATTERN DOTS-13578;So;0;L;;;;;N;;;;;
+28D6;BRAILLE PATTERN DOTS-23578;So;0;L;;;;;N;;;;;
+28D7;BRAILLE PATTERN DOTS-123578;So;0;L;;;;;N;;;;;
+28D8;BRAILLE PATTERN DOTS-4578;So;0;L;;;;;N;;;;;
+28D9;BRAILLE PATTERN DOTS-14578;So;0;L;;;;;N;;;;;
+28DA;BRAILLE PATTERN DOTS-24578;So;0;L;;;;;N;;;;;
+28DB;BRAILLE PATTERN DOTS-124578;So;0;L;;;;;N;;;;;
+28DC;BRAILLE PATTERN DOTS-34578;So;0;L;;;;;N;;;;;
+28DD;BRAILLE PATTERN DOTS-134578;So;0;L;;;;;N;;;;;
+28DE;BRAILLE PATTERN DOTS-234578;So;0;L;;;;;N;;;;;
+28DF;BRAILLE PATTERN DOTS-1234578;So;0;L;;;;;N;;;;;
+28E0;BRAILLE PATTERN DOTS-678;So;0;L;;;;;N;;;;;
+28E1;BRAILLE PATTERN DOTS-1678;So;0;L;;;;;N;;;;;
+28E2;BRAILLE PATTERN DOTS-2678;So;0;L;;;;;N;;;;;
+28E3;BRAILLE PATTERN DOTS-12678;So;0;L;;;;;N;;;;;
+28E4;BRAILLE PATTERN DOTS-3678;So;0;L;;;;;N;;;;;
+28E5;BRAILLE PATTERN DOTS-13678;So;0;L;;;;;N;;;;;
+28E6;BRAILLE PATTERN DOTS-23678;So;0;L;;;;;N;;;;;
+28E7;BRAILLE PATTERN DOTS-123678;So;0;L;;;;;N;;;;;
+28E8;BRAILLE PATTERN DOTS-4678;So;0;L;;;;;N;;;;;
+28E9;BRAILLE PATTERN DOTS-14678;So;0;L;;;;;N;;;;;
+28EA;BRAILLE PATTERN DOTS-24678;So;0;L;;;;;N;;;;;
+28EB;BRAILLE PATTERN DOTS-124678;So;0;L;;;;;N;;;;;
+28EC;BRAILLE PATTERN DOTS-34678;So;0;L;;;;;N;;;;;
+28ED;BRAILLE PATTERN DOTS-134678;So;0;L;;;;;N;;;;;
+28EE;BRAILLE PATTERN DOTS-234678;So;0;L;;;;;N;;;;;
+28EF;BRAILLE PATTERN DOTS-1234678;So;0;L;;;;;N;;;;;
+28F0;BRAILLE PATTERN DOTS-5678;So;0;L;;;;;N;;;;;
+28F1;BRAILLE PATTERN DOTS-15678;So;0;L;;;;;N;;;;;
+28F2;BRAILLE PATTERN DOTS-25678;So;0;L;;;;;N;;;;;
+28F3;BRAILLE PATTERN DOTS-125678;So;0;L;;;;;N;;;;;
+28F4;BRAILLE PATTERN DOTS-35678;So;0;L;;;;;N;;;;;
+28F5;BRAILLE PATTERN DOTS-135678;So;0;L;;;;;N;;;;;
+28F6;BRAILLE PATTERN DOTS-235678;So;0;L;;;;;N;;;;;
+28F7;BRAILLE PATTERN DOTS-1235678;So;0;L;;;;;N;;;;;
+28F8;BRAILLE PATTERN DOTS-45678;So;0;L;;;;;N;;;;;
+28F9;BRAILLE PATTERN DOTS-145678;So;0;L;;;;;N;;;;;
+28FA;BRAILLE PATTERN DOTS-245678;So;0;L;;;;;N;;;;;
+28FB;BRAILLE PATTERN DOTS-1245678;So;0;L;;;;;N;;;;;
+28FC;BRAILLE PATTERN DOTS-345678;So;0;L;;;;;N;;;;;
+28FD;BRAILLE PATTERN DOTS-1345678;So;0;L;;;;;N;;;;;
+28FE;BRAILLE PATTERN DOTS-2345678;So;0;L;;;;;N;;;;;
+28FF;BRAILLE PATTERN DOTS-12345678;So;0;L;;;;;N;;;;;
+2900;RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2901;RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2902;LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2903;RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2904;LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2905;RIGHTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+2906;LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+2907;RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+2908;DOWNWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
+2909;UPWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
+290A;UPWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;;
+290B;DOWNWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;;
+290C;LEFTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+290D;RIGHTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+290E;LEFTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+290F;RIGHTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+2910;RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+2911;RIGHTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;;
+2912;UPWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;;
+2913;DOWNWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;;
+2914;RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2915;RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2916;RIGHTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;;
+2917;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2918;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2919;LEFTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
+291A;RIGHTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
+291B;LEFTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
+291C;RIGHTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
+291D;LEFTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
+291E;RIGHTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
+291F;LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
+2920;RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
+2921;NORTH WEST AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2922;NORTH EAST AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
+2923;NORTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
+2924;NORTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
+2925;SOUTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
+2926;SOUTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
+2927;NORTH WEST ARROW AND NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2928;NORTH EAST ARROW AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2929;SOUTH EAST ARROW AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
+292A;SOUTH WEST ARROW AND NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
+292B;RISING DIAGONAL CROSSING FALLING DIAGONAL;Sm;0;ON;;;;;N;;;;;
+292C;FALLING DIAGONAL CROSSING RISING DIAGONAL;Sm;0;ON;;;;;N;;;;;
+292D;SOUTH EAST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+292E;NORTH EAST ARROW CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+292F;FALLING DIAGONAL CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2930;RISING DIAGONAL CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2931;NORTH EAST ARROW CROSSING NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
+2932;NORTH WEST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
+2933;WAVE ARROW POINTING DIRECTLY RIGHT;Sm;0;ON;;;;;N;;;;;
+2934;ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS;Sm;0;ON;;;;;N;;;;;
+2935;ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS;Sm;0;ON;;;;;N;;;;;
+2936;ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS;Sm;0;ON;;;;;N;;;;;
+2937;ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS;Sm;0;ON;;;;;N;;;;;
+2938;RIGHT-SIDE ARC CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+2939;LEFT-SIDE ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+293A;TOP ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+293B;BOTTOM ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+293C;TOP ARC CLOCKWISE ARROW WITH MINUS;Sm;0;ON;;;;;N;;;;;
+293D;TOP ARC ANTICLOCKWISE ARROW WITH PLUS;Sm;0;ON;;;;;N;;;;;
+293E;LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+293F;LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
+2940;ANTICLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
+2941;CLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
+2942;RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2943;LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2944;SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2945;RIGHTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;;
+2946;LEFTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;;
+2947;RIGHTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;;
+2948;LEFT RIGHT ARROW THROUGH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
+2949;UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
+294A;LEFT BARB UP RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;;
+294B;LEFT BARB DOWN RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;;
+294C;UP BARB RIGHT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;;
+294D;UP BARB LEFT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;;
+294E;LEFT BARB UP RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;;
+294F;UP BARB RIGHT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;;
+2950;LEFT BARB DOWN RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;;
+2951;UP BARB LEFT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;;
+2952;LEFTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;;
+2953;RIGHTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;;
+2954;UPWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;;
+2955;DOWNWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;;
+2956;LEFTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;;
+2957;RIGHTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;;
+2958;UPWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;;
+2959;DOWNWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;;
+295A;LEFTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;;
+295B;RIGHTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;;
+295C;UPWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;;
+295D;DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;;
+295E;LEFTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;;
+295F;RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;;
+2960;UPWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;;
+2961;DOWNWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;;
+2962;LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
+2963;UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
+2964;RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
+2965;DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
+2966;LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;;
+2967;LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
+2968;RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;;
+2969;RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
+296A;LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;;
+296B;LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;;
+296C;RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;;
+296D;RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;;
+296E;UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
+296F;DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
+2970;RIGHT DOUBLE ARROW WITH ROUNDED HEAD;Sm;0;ON;;;;;N;;;;;
+2971;EQUALS SIGN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2972;TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2973;LEFTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
+2974;RIGHTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
+2975;RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2976;LESS-THAN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2977;LEFTWARDS ARROW THROUGH LESS-THAN;Sm;0;ON;;;;;N;;;;;
+2978;GREATER-THAN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2979;SUBSET ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+297A;LEFTWARDS ARROW THROUGH SUBSET;Sm;0;ON;;;;;N;;;;;
+297B;SUPERSET ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+297C;LEFT FISH TAIL;Sm;0;ON;;;;;N;;;;;
+297D;RIGHT FISH TAIL;Sm;0;ON;;;;;N;;;;;
+297E;UP FISH TAIL;Sm;0;ON;;;;;N;;;;;
+297F;DOWN FISH TAIL;Sm;0;ON;;;;;N;;;;;
+2980;TRIPLE VERTICAL BAR DELIMITER;Sm;0;ON;;;;;N;;;;;
+2981;Z NOTATION SPOT;Sm;0;ON;;;;;N;;;;;
+2982;Z NOTATION TYPE COLON;Sm;0;ON;;;;;N;;;;;
+2983;LEFT WHITE CURLY BRACKET;Ps;0;ON;;;;;Y;;;;;
+2984;RIGHT WHITE CURLY BRACKET;Pe;0;ON;;;;;Y;;;;;
+2985;LEFT WHITE PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
+2986;RIGHT WHITE PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
+2987;Z NOTATION LEFT IMAGE BRACKET;Ps;0;ON;;;;;Y;;;;;
+2988;Z NOTATION RIGHT IMAGE BRACKET;Pe;0;ON;;;;;Y;;;;;
+2989;Z NOTATION LEFT BINDING BRACKET;Ps;0;ON;;;;;Y;;;;;
+298A;Z NOTATION RIGHT BINDING BRACKET;Pe;0;ON;;;;;Y;;;;;
+298B;LEFT SQUARE BRACKET WITH UNDERBAR;Ps;0;ON;;;;;Y;;;;;
+298C;RIGHT SQUARE BRACKET WITH UNDERBAR;Pe;0;ON;;;;;Y;;;;;
+298D;LEFT SQUARE BRACKET WITH TICK IN TOP CORNER;Ps;0;ON;;;;;Y;;;;;
+298E;RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Pe;0;ON;;;;;Y;;;;;
+298F;LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Ps;0;ON;;;;;Y;;;;;
+2990;RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER;Pe;0;ON;;;;;Y;;;;;
+2991;LEFT ANGLE BRACKET WITH DOT;Ps;0;ON;;;;;Y;;;;;
+2992;RIGHT ANGLE BRACKET WITH DOT;Pe;0;ON;;;;;Y;;;;;
+2993;LEFT ARC LESS-THAN BRACKET;Ps;0;ON;;;;;Y;;;;;
+2994;RIGHT ARC GREATER-THAN BRACKET;Pe;0;ON;;;;;Y;;;;;
+2995;DOUBLE LEFT ARC GREATER-THAN BRACKET;Ps;0;ON;;;;;Y;;;;;
+2996;DOUBLE RIGHT ARC LESS-THAN BRACKET;Pe;0;ON;;;;;Y;;;;;
+2997;LEFT BLACK TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;;
+2998;RIGHT BLACK TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;;
+2999;DOTTED FENCE;Sm;0;ON;;;;;N;;;;;
+299A;VERTICAL ZIGZAG LINE;Sm;0;ON;;;;;N;;;;;
+299B;MEASURED ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;;
+299C;RIGHT ANGLE VARIANT WITH SQUARE;Sm;0;ON;;;;;Y;;;;;
+299D;MEASURED RIGHT ANGLE WITH DOT;Sm;0;ON;;;;;Y;;;;;
+299E;ANGLE WITH S INSIDE;Sm;0;ON;;;;;Y;;;;;
+299F;ACUTE ANGLE;Sm;0;ON;;;;;Y;;;;;
+29A0;SPHERICAL ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;;
+29A1;SPHERICAL ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;;
+29A2;TURNED ANGLE;Sm;0;ON;;;;;Y;;;;;
+29A3;REVERSED ANGLE;Sm;0;ON;;;;;Y;;;;;
+29A4;ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
+29A5;REVERSED ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
+29A6;OBLIQUE ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;;
+29A7;OBLIQUE ANGLE OPENING DOWN;Sm;0;ON;;;;;Y;;;;;
+29A8;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT;Sm;0;ON;;;;;Y;;;;;
+29A9;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT;Sm;0;ON;;;;;Y;;;;;
+29AA;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT;Sm;0;ON;;;;;Y;;;;;
+29AB;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT;Sm;0;ON;;;;;Y;;;;;
+29AC;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP;Sm;0;ON;;;;;Y;;;;;
+29AD;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP;Sm;0;ON;;;;;Y;;;;;
+29AE;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN;Sm;0;ON;;;;;Y;;;;;
+29AF;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN;Sm;0;ON;;;;;Y;;;;;
+29B0;REVERSED EMPTY SET;Sm;0;ON;;;;;N;;;;;
+29B1;EMPTY SET WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
+29B2;EMPTY SET WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
+29B3;EMPTY SET WITH RIGHT ARROW ABOVE;Sm;0;ON;;;;;N;;;;;
+29B4;EMPTY SET WITH LEFT ARROW ABOVE;Sm;0;ON;;;;;N;;;;;
+29B5;CIRCLE WITH HORIZONTAL BAR;Sm;0;ON;;;;;N;;;;;
+29B6;CIRCLED VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
+29B7;CIRCLED PARALLEL;Sm;0;ON;;;;;N;;;;;
+29B8;CIRCLED REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;;
+29B9;CIRCLED PERPENDICULAR;Sm;0;ON;;;;;N;;;;;
+29BA;CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
+29BB;CIRCLE WITH SUPERIMPOSED X;Sm;0;ON;;;;;N;;;;;
+29BC;CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN;Sm;0;ON;;;;;N;;;;;
+29BD;UP ARROW THROUGH CIRCLE;Sm;0;ON;;;;;N;;;;;
+29BE;CIRCLED WHITE BULLET;Sm;0;ON;;;;;N;;;;;
+29BF;CIRCLED BULLET;Sm;0;ON;;;;;N;;;;;
+29C0;CIRCLED LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+29C1;CIRCLED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+29C2;CIRCLE WITH SMALL CIRCLE TO THE RIGHT;Sm;0;ON;;;;;Y;;;;;
+29C3;CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT;Sm;0;ON;;;;;Y;;;;;
+29C4;SQUARED RISING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;;
+29C5;SQUARED FALLING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;;
+29C6;SQUARED ASTERISK;Sm;0;ON;;;;;N;;;;;
+29C7;SQUARED SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
+29C8;SQUARED SQUARE;Sm;0;ON;;;;;N;;;;;
+29C9;TWO JOINED SQUARES;Sm;0;ON;;;;;Y;;;;;
+29CA;TRIANGLE WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
+29CB;TRIANGLE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
+29CC;S IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
+29CD;TRIANGLE WITH SERIFS AT BOTTOM;Sm;0;ON;;;;;N;;;;;
+29CE;RIGHT TRIANGLE ABOVE LEFT TRIANGLE;Sm;0;ON;;;;;Y;;;;;
+29CF;LEFT TRIANGLE BESIDE VERTICAL BAR;Sm;0;ON;;;;;Y;;;;;
+29D0;VERTICAL BAR BESIDE RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;;
+29D1;BOWTIE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29D2;BOWTIE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29D3;BLACK BOWTIE;Sm;0;ON;;;;;N;;;;;
+29D4;TIMES WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29D5;TIMES WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29D6;WHITE HOURGLASS;Sm;0;ON;;;;;N;;;;;
+29D7;BLACK HOURGLASS;Sm;0;ON;;;;;N;;;;;
+29D8;LEFT WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;;
+29D9;RIGHT WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;;
+29DA;LEFT DOUBLE WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;;
+29DB;RIGHT DOUBLE WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;;
+29DC;INCOMPLETE INFINITY;Sm;0;ON;;;;;Y;;;;;
+29DD;TIE OVER INFINITY;Sm;0;ON;;;;;N;;;;;
+29DE;INFINITY NEGATED WITH VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
+29DF;DOUBLE-ENDED MULTIMAP;Sm;0;ON;;;;;N;;;;;
+29E0;SQUARE WITH CONTOURED OUTLINE;Sm;0;ON;;;;;N;;;;;
+29E1;INCREASES AS;Sm;0;ON;;;;;Y;;;;;
+29E2;SHUFFLE PRODUCT;Sm;0;ON;;;;;N;;;;;
+29E3;EQUALS SIGN AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;;
+29E4;EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;;
+29E5;IDENTICAL TO AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;;
+29E6;GLEICH STARK;Sm;0;ON;;;;;N;;;;;
+29E7;THERMODYNAMIC;Sm;0;ON;;;;;N;;;;;
+29E8;DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29E9;DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
+29EA;BLACK DIAMOND WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;
+29EB;BLACK LOZENGE;Sm;0;ON;;;;;N;;;;;
+29EC;WHITE CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;
+29ED;BLACK CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;
+29EE;ERROR-BARRED WHITE SQUARE;Sm;0;ON;;;;;N;;;;;
+29EF;ERROR-BARRED BLACK SQUARE;Sm;0;ON;;;;;N;;;;;
+29F0;ERROR-BARRED WHITE DIAMOND;Sm;0;ON;;;;;N;;;;;
+29F1;ERROR-BARRED BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
+29F2;ERROR-BARRED WHITE CIRCLE;Sm;0;ON;;;;;N;;;;;
+29F3;ERROR-BARRED BLACK CIRCLE;Sm;0;ON;;;;;N;;;;;
+29F4;RULE-DELAYED;Sm;0;ON;;;;;Y;;;;;
+29F5;REVERSE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;;
+29F6;SOLIDUS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+29F7;REVERSE SOLIDUS WITH HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
+29F8;BIG SOLIDUS;Sm;0;ON;;;;;Y;;;;;
+29F9;BIG REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;;
+29FA;DOUBLE PLUS;Sm;0;ON;;;;;N;;;;;
+29FB;TRIPLE PLUS;Sm;0;ON;;;;;N;;;;;
+29FC;LEFT-POINTING CURVED ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;
+29FD;RIGHT-POINTING CURVED ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;
+29FE;TINY;Sm;0;ON;;;;;N;;;;;
+29FF;MINY;Sm;0;ON;;;;;N;;;;;
+2A00;N-ARY CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A01;N-ARY CIRCLED PLUS OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A02;N-ARY CIRCLED TIMES OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A03;N-ARY UNION OPERATOR WITH DOT;Sm;0;ON;;;;;N;;;;;
+2A04;N-ARY UNION OPERATOR WITH PLUS;Sm;0;ON;;;;;N;;;;;
+2A05;N-ARY SQUARE INTERSECTION OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A06;N-ARY SQUARE UNION OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A07;TWO LOGICAL AND OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A08;TWO LOGICAL OR OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A09;N-ARY TIMES OPERATOR;Sm;0;ON;;;;;N;;;;;
+2A0A;MODULO TWO SUM;Sm;0;ON;;;;;Y;;;;;
+2A0B;SUMMATION WITH INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2A0C;QUADRUPLE INTEGRAL OPERATOR;Sm;0;ON;<compat> 222B 222B 222B 222B;;;;Y;;;;;
+2A0D;FINITE PART INTEGRAL;Sm;0;ON;;;;;Y;;;;;
+2A0E;INTEGRAL WITH DOUBLE STROKE;Sm;0;ON;;;;;Y;;;;;
+2A0F;INTEGRAL AVERAGE WITH SLASH;Sm;0;ON;;;;;Y;;;;;
+2A10;CIRCULATION FUNCTION;Sm;0;ON;;;;;Y;;;;;
+2A11;ANTICLOCKWISE INTEGRATION;Sm;0;ON;;;;;Y;;;;;
+2A12;LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;;
+2A13;LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;;
+2A14;LINE INTEGRATION NOT INCLUDING THE POLE;Sm;0;ON;;;;;Y;;;;;
+2A15;INTEGRAL AROUND A POINT OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2A16;QUATERNION INTEGRAL OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2A17;INTEGRAL WITH LEFTWARDS ARROW WITH HOOK;Sm;0;ON;;;;;Y;;;;;
+2A18;INTEGRAL WITH TIMES SIGN;Sm;0;ON;;;;;Y;;;;;
+2A19;INTEGRAL WITH INTERSECTION;Sm;0;ON;;;;;Y;;;;;
+2A1A;INTEGRAL WITH UNION;Sm;0;ON;;;;;Y;;;;;
+2A1B;INTEGRAL WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
+2A1C;INTEGRAL WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
+2A1D;JOIN;Sm;0;ON;;;;;N;;;;;
+2A1E;LARGE LEFT TRIANGLE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2A1F;Z NOTATION SCHEMA COMPOSITION;Sm;0;ON;;;;;Y;;;;;
+2A20;Z NOTATION SCHEMA PIPING;Sm;0;ON;;;;;Y;;;;;
+2A21;Z NOTATION SCHEMA PROJECTION;Sm;0;ON;;;;;Y;;;;;
+2A22;PLUS SIGN WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
+2A23;PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE;Sm;0;ON;;;;;N;;;;;
+2A24;PLUS SIGN WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A25;PLUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;
+2A26;PLUS SIGN WITH TILDE BELOW;Sm;0;ON;;;;;Y;;;;;
+2A27;PLUS SIGN WITH SUBSCRIPT TWO;Sm;0;ON;;;;;N;;;;;
+2A28;PLUS SIGN WITH BLACK TRIANGLE;Sm;0;ON;;;;;N;;;;;
+2A29;MINUS SIGN WITH COMMA ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A2A;MINUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;
+2A2B;MINUS SIGN WITH FALLING DOTS;Sm;0;ON;;;;;Y;;;;;
+2A2C;MINUS SIGN WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;;
+2A2D;PLUS SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
+2A2E;PLUS SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
+2A2F;VECTOR OR CROSS PRODUCT;Sm;0;ON;;;;;N;;;;;
+2A30;MULTIPLICATION SIGN WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
+2A31;MULTIPLICATION SIGN WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2A32;SEMIDIRECT PRODUCT WITH BOTTOM CLOSED;Sm;0;ON;;;;;N;;;;;
+2A33;SMASH PRODUCT;Sm;0;ON;;;;;N;;;;;
+2A34;MULTIPLICATION SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
+2A35;MULTIPLICATION SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
+2A36;CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;N;;;;;
+2A37;MULTIPLICATION SIGN IN DOUBLE CIRCLE;Sm;0;ON;;;;;N;;;;;
+2A38;CIRCLED DIVISION SIGN;Sm;0;ON;;;;;N;;;;;
+2A39;PLUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
+2A3A;MINUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
+2A3B;MULTIPLICATION SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
+2A3C;INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;;
+2A3D;RIGHTHAND INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;;
+2A3E;Z NOTATION RELATIONAL COMPOSITION;Sm;0;ON;;;;;Y;;;;;
+2A3F;AMALGAMATION OR COPRODUCT;Sm;0;ON;;;;;N;;;;;
+2A40;INTERSECTION WITH DOT;Sm;0;ON;;;;;N;;;;;
+2A41;UNION WITH MINUS SIGN;Sm;0;ON;;;;;N;;;;;
+2A42;UNION WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
+2A43;INTERSECTION WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
+2A44;INTERSECTION WITH LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+2A45;UNION WITH LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+2A46;UNION ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;;
+2A47;INTERSECTION ABOVE UNION;Sm;0;ON;;;;;N;;;;;
+2A48;UNION ABOVE BAR ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;;
+2A49;INTERSECTION ABOVE BAR ABOVE UNION;Sm;0;ON;;;;;N;;;;;
+2A4A;UNION BESIDE AND JOINED WITH UNION;Sm;0;ON;;;;;N;;;;;
+2A4B;INTERSECTION BESIDE AND JOINED WITH INTERSECTION;Sm;0;ON;;;;;N;;;;;
+2A4C;CLOSED UNION WITH SERIFS;Sm;0;ON;;;;;N;;;;;
+2A4D;CLOSED INTERSECTION WITH SERIFS;Sm;0;ON;;;;;N;;;;;
+2A4E;DOUBLE SQUARE INTERSECTION;Sm;0;ON;;;;;N;;;;;
+2A4F;DOUBLE SQUARE UNION;Sm;0;ON;;;;;N;;;;;
+2A50;CLOSED UNION WITH SERIFS AND SMASH PRODUCT;Sm;0;ON;;;;;N;;;;;
+2A51;LOGICAL AND WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
+2A52;LOGICAL OR WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
+2A53;DOUBLE LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+2A54;DOUBLE LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+2A55;TWO INTERSECTING LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+2A56;TWO INTERSECTING LOGICAL OR;Sm;0;ON;;;;;N;;;;;
+2A57;SLOPING LARGE OR;Sm;0;ON;;;;;Y;;;;;
+2A58;SLOPING LARGE AND;Sm;0;ON;;;;;Y;;;;;
+2A59;LOGICAL OR OVERLAPPING LOGICAL AND;Sm;0;ON;;;;;N;;;;;
+2A5A;LOGICAL AND WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;;
+2A5B;LOGICAL OR WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;;
+2A5C;LOGICAL AND WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;;
+2A5D;LOGICAL OR WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;;
+2A5E;LOGICAL AND WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;;
+2A5F;LOGICAL AND WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2A60;LOGICAL AND WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2A61;SMALL VEE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2A62;LOGICAL OR WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;;
+2A63;LOGICAL OR WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2A64;Z NOTATION DOMAIN ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;;
+2A65;Z NOTATION RANGE ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;;
+2A66;EQUALS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;
+2A67;IDENTICAL WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
+2A68;TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2A69;TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2A6A;TILDE OPERATOR WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A6B;TILDE OPERATOR WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;;
+2A6C;SIMILAR MINUS SIMILAR;Sm;0;ON;;;;;Y;;;;;
+2A6D;CONGRUENT WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A6E;EQUALS WITH ASTERISK;Sm;0;ON;;;;;N;;;;;
+2A6F;ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;Y;;;;;
+2A70;APPROXIMATELY EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2A71;EQUALS SIGN ABOVE PLUS SIGN;Sm;0;ON;;;;;N;;;;;
+2A72;PLUS SIGN ABOVE EQUALS SIGN;Sm;0;ON;;;;;N;;;;;
+2A73;EQUALS SIGN ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2A74;DOUBLE COLON EQUAL;Sm;0;ON;<compat> 003A 003A 003D;;;;Y;;;;;
+2A75;TWO CONSECUTIVE EQUALS SIGNS;Sm;0;ON;<compat> 003D 003D;;;;N;;;;;
+2A76;THREE CONSECUTIVE EQUALS SIGNS;Sm;0;ON;<compat> 003D 003D 003D;;;;N;;;;;
+2A77;EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW;Sm;0;ON;;;;;N;;;;;
+2A78;EQUIVALENT WITH FOUR DOTS ABOVE;Sm;0;ON;;;;;N;;;;;
+2A79;LESS-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A7A;GREATER-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A7B;LESS-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A7C;GREATER-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A7D;LESS-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2A7E;GREATER-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2A7F;LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A80;GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A81;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A82;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2A83;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT;Sm;0;ON;;;;;Y;;;;;
+2A84;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT;Sm;0;ON;;;;;Y;;;;;
+2A85;LESS-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
+2A86;GREATER-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
+2A87;LESS-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2A88;GREATER-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2A89;LESS-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
+2A8A;GREATER-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
+2A8B;LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A8C;GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A8D;LESS-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A8E;GREATER-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A8F;LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A90;GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A91;LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A92;GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A93;LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A94;GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
+2A95;SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A96;SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A97;SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A98;SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
+2A99;DOUBLE-LINE EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9A;DOUBLE-LINE EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9B;DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9C;DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9D;SIMILAR OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9E;SIMILAR OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2A9F;SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AA0;SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AA1;DOUBLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2AA2;DOUBLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2AA3;DOUBLE NESTED LESS-THAN WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
+2AA4;GREATER-THAN OVERLAPPING LESS-THAN;Sm;0;ON;;;;;N;;;;;
+2AA5;GREATER-THAN BESIDE LESS-THAN;Sm;0;ON;;;;;N;;;;;
+2AA6;LESS-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;;
+2AA7;GREATER-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;;
+2AA8;LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
+2AA9;GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
+2AAA;SMALLER THAN;Sm;0;ON;;;;;Y;;;;;
+2AAB;LARGER THAN;Sm;0;ON;;;;;Y;;;;;
+2AAC;SMALLER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AAD;LARGER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AAE;EQUALS SIGN WITH BUMPY ABOVE;Sm;0;ON;;;;;N;;;;;
+2AAF;PRECEDES ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AB0;SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AB1;PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB2;SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB3;PRECEDES ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AB4;SUCCEEDS ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AB5;PRECEDES ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB6;SUCCEEDS ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB7;PRECEDES ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB8;SUCCEEDS ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AB9;PRECEDES ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ABA;SUCCEEDS ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ABB;DOUBLE PRECEDES;Sm;0;ON;;;;;Y;;;;;
+2ABC;DOUBLE SUCCEEDS;Sm;0;ON;;;;;Y;;;;;
+2ABD;SUBSET WITH DOT;Sm;0;ON;;;;;Y;;;;;
+2ABE;SUPERSET WITH DOT;Sm;0;ON;;;;;Y;;;;;
+2ABF;SUBSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
+2AC0;SUPERSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
+2AC1;SUBSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
+2AC2;SUPERSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
+2AC3;SUBSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2AC4;SUPERSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
+2AC5;SUBSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AC6;SUPERSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
+2AC7;SUBSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2AC8;SUPERSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2AC9;SUBSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ACA;SUPERSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ACB;SUBSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ACC;SUPERSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2ACD;SQUARE LEFT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2ACE;SQUARE RIGHT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2ACF;CLOSED SUBSET;Sm;0;ON;;;;;Y;;;;;
+2AD0;CLOSED SUPERSET;Sm;0;ON;;;;;Y;;;;;
+2AD1;CLOSED SUBSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AD2;CLOSED SUPERSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AD3;SUBSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;;
+2AD4;SUPERSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;;
+2AD5;SUBSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;;
+2AD6;SUPERSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;;
+2AD7;SUPERSET BESIDE SUBSET;Sm;0;ON;;;;;N;;;;;
+2AD8;SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET;Sm;0;ON;;;;;N;;;;;
+2AD9;ELEMENT OF OPENING DOWNWARDS;Sm;0;ON;;;;;N;;;;;
+2ADA;PITCHFORK WITH TEE TOP;Sm;0;ON;;;;;N;;;;;
+2ADB;TRANSVERSAL INTERSECTION;Sm;0;ON;;;;;N;;;;;
+2ADC;FORKING;Sm;0;ON;2ADD 0338;;;;Y;;;;;
+2ADD;NONFORKING;Sm;0;ON;;;;;N;;;;;
+2ADE;SHORT LEFT TACK;Sm;0;ON;;;;;Y;;;;;
+2ADF;SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;;
+2AE0;SHORT UP TACK;Sm;0;ON;;;;;N;;;;;
+2AE1;PERPENDICULAR WITH S;Sm;0;ON;;;;;N;;;;;
+2AE2;VERTICAL BAR TRIPLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+2AE3;DOUBLE VERTICAL BAR LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+2AE4;VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+2AE5;DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
+2AE6;LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL;Sm;0;ON;;;;;Y;;;;;
+2AE7;SHORT DOWN TACK WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
+2AE8;SHORT UP TACK WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
+2AE9;SHORT UP TACK ABOVE SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;;
+2AEA;DOUBLE DOWN TACK;Sm;0;ON;;;;;N;;;;;
+2AEB;DOUBLE UP TACK;Sm;0;ON;;;;;N;;;;;
+2AEC;DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;;
+2AED;REVERSED DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;;
+2AEE;DOES NOT DIVIDE WITH REVERSED NEGATION SLASH;Sm;0;ON;;;;;Y;;;;;
+2AEF;VERTICAL LINE WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
+2AF0;VERTICAL LINE WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;;
+2AF1;DOWN TACK WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;;
+2AF2;PARALLEL WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
+2AF3;PARALLEL WITH TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2AF4;TRIPLE VERTICAL BAR BINARY RELATION;Sm;0;ON;;;;;N;;;;;
+2AF5;TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
+2AF6;TRIPLE COLON OPERATOR;Sm;0;ON;;;;;N;;;;;
+2AF7;TRIPLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;;
+2AF8;TRIPLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
+2AF9;DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AFA;DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
+2AFB;TRIPLE SOLIDUS BINARY RELATION;Sm;0;ON;;;;;Y;;;;;
+2AFC;LARGE TRIPLE VERTICAL BAR OPERATOR;Sm;0;ON;;;;;N;;;;;
+2AFD;DOUBLE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;;
+2AFE;WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
+2AFF;N-ARY WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
+2B00;NORTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B01;NORTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B02;SOUTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B03;SOUTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B04;LEFT RIGHT WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B05;LEFTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B06;UPWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B07;DOWNWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B08;NORTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B09;NORTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B0A;SOUTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B0B;SOUTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B0C;LEFT RIGHT BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B0D;UP DOWN BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B0E;RIGHTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;;
+2B0F;RIGHTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;;
+2B10;LEFTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;;
+2B11;LEFTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;;
+2B12;SQUARE WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;;
+2B13;SQUARE WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;;
+2B14;SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
+2B15;SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
+2B16;DIAMOND WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;
+2B17;DIAMOND WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;
+2B18;DIAMOND WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;;
+2B19;DIAMOND WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;;
+2B1A;DOTTED SQUARE;So;0;ON;;;;;N;;;;;
+2B1B;BLACK LARGE SQUARE;So;0;ON;;;;;N;;;;;
+2B1C;WHITE LARGE SQUARE;So;0;ON;;;;;N;;;;;
+2B1D;BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;;
+2B1E;WHITE VERY SMALL SQUARE;So;0;ON;;;;;N;;;;;
+2B1F;BLACK PENTAGON;So;0;ON;;;;;N;;;;;
+2B20;WHITE PENTAGON;So;0;ON;;;;;N;;;;;
+2B21;WHITE HEXAGON;So;0;ON;;;;;N;;;;;
+2B22;BLACK HEXAGON;So;0;ON;;;;;N;;;;;
+2B23;HORIZONTAL BLACK HEXAGON;So;0;ON;;;;;N;;;;;
+2B24;BLACK LARGE CIRCLE;So;0;ON;;;;;N;;;;;
+2B25;BLACK MEDIUM DIAMOND;So;0;ON;;;;;N;;;;;
+2B26;WHITE MEDIUM DIAMOND;So;0;ON;;;;;N;;;;;
+2B27;BLACK MEDIUM LOZENGE;So;0;ON;;;;;N;;;;;
+2B28;WHITE MEDIUM LOZENGE;So;0;ON;;;;;N;;;;;
+2B29;BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;;
+2B2A;BLACK SMALL LOZENGE;So;0;ON;;;;;N;;;;;
+2B2B;WHITE SMALL LOZENGE;So;0;ON;;;;;N;;;;;
+2B2C;BLACK HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;;
+2B2D;WHITE HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;;
+2B2E;BLACK VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;;
+2B2F;WHITE VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;;
+2B30;LEFT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
+2B31;THREE LEFTWARDS ARROWS;Sm;0;ON;;;;;N;;;;;
+2B32;LEFT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;
+2B33;LONG LEFTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;;
+2B34;LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B35;LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B36;LEFTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
+2B37;LEFTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
+2B38;LEFTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;;
+2B39;LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B3A;LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B3B;LEFTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;;
+2B3C;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B3D;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
+2B3E;LEFTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;;
+2B3F;WAVE ARROW POINTING DIRECTLY LEFT;Sm;0;ON;;;;;N;;;;;
+2B40;EQUALS SIGN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2B41;REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2B42;LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2B43;RIGHTWARDS ARROW THROUGH GREATER-THAN;Sm;0;ON;;;;;N;;;;;
+2B44;RIGHTWARDS ARROW THROUGH SUPERSET;Sm;0;ON;;;;;N;;;;;
+2B45;LEFTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;;
+2B46;RIGHTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;;
+2B47;REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2B48;RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2B49;TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
+2B4A;LEFTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
+2B4B;LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
+2B4C;RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
+2B4D;DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW;So;0;ON;;;;;N;;;;;
+2B4E;SHORT SLANTED NORTH ARROW;So;0;ON;;;;;N;;;;;
+2B4F;SHORT BACKSLANTED SOUTH ARROW;So;0;ON;;;;;N;;;;;
+2B50;WHITE MEDIUM STAR;So;0;ON;;;;;N;;;;;
+2B51;BLACK SMALL STAR;So;0;ON;;;;;N;;;;;
+2B52;WHITE SMALL STAR;So;0;ON;;;;;N;;;;;
+2B53;BLACK RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;;
+2B54;WHITE RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;;
+2B55;HEAVY LARGE CIRCLE;So;0;ON;;;;;N;;;;;
+2B56;HEAVY OVAL WITH OVAL INSIDE;So;0;ON;;;;;N;;;;;
+2B57;HEAVY CIRCLE WITH CIRCLE INSIDE;So;0;ON;;;;;N;;;;;
+2B58;HEAVY CIRCLE;So;0;ON;;;;;N;;;;;
+2B59;HEAVY CIRCLED SALTIRE;So;0;ON;;;;;N;;;;;
+2B5A;SLANTED NORTH ARROW WITH HOOKED HEAD;So;0;ON;;;;;N;;;;;
+2B5B;BACKSLANTED SOUTH ARROW WITH HOOKED TAIL;So;0;ON;;;;;N;;;;;
+2B5C;SLANTED NORTH ARROW WITH HORIZONTAL TAIL;So;0;ON;;;;;N;;;;;
+2B5D;BACKSLANTED SOUTH ARROW WITH HORIZONTAL TAIL;So;0;ON;;;;;N;;;;;
+2B5E;BENT ARROW POINTING DOWNWARDS THEN NORTH EAST;So;0;ON;;;;;N;;;;;
+2B5F;SHORT BENT ARROW POINTING DOWNWARDS THEN NORTH EAST;So;0;ON;;;;;N;;;;;
+2B60;LEFTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B61;UPWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B62;RIGHTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B63;DOWNWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B64;LEFT RIGHT TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B65;UP DOWN TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B66;NORTH WEST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B67;NORTH EAST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B68;SOUTH EAST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B69;SOUTH WEST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B6A;LEFTWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;
+2B6B;UPWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;
+2B6C;RIGHTWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;
+2B6D;DOWNWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;
+2B6E;CLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
+2B6F;ANTICLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
+2B70;LEFTWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B71;UPWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B72;RIGHTWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B73;DOWNWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B76;NORTH WEST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B77;NORTH EAST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B78;SOUTH EAST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B79;SOUTH WEST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;
+2B7A;LEFTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;
+2B7B;UPWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;
+2B7C;RIGHTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;
+2B7D;DOWNWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;
+2B7E;HORIZONTAL TAB KEY;So;0;ON;;;;;N;;;;;
+2B7F;VERTICAL TAB KEY;So;0;ON;;;;;N;;;;;
+2B80;LEFTWARDS TRIANGLE-HEADED ARROW OVER RIGHTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B81;UPWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF DOWNWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B82;RIGHTWARDS TRIANGLE-HEADED ARROW OVER LEFTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B83;DOWNWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF UPWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;
+2B84;LEFTWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;
+2B85;UPWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;
+2B86;RIGHTWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;
+2B87;DOWNWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;
+2B88;LEFTWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B89;UPWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B8A;RIGHTWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B8B;DOWNWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;
+2B8C;ANTICLOCKWISE TRIANGLE-HEADED RIGHT U-SHAPED ARROW;So;0;ON;;;;;N;;;;;
+2B8D;ANTICLOCKWISE TRIANGLE-HEADED BOTTOM U-SHAPED ARROW;So;0;ON;;;;;N;;;;;
+2B8E;ANTICLOCKWISE TRIANGLE-HEADED LEFT U-SHAPED ARROW;So;0;ON;;;;;N;;;;;
+2B8F;ANTICLOCKWISE TRIANGLE-HEADED TOP U-SHAPED ARROW;So;0;ON;;;;;N;;;;;
+2B90;RETURN LEFT;So;0;ON;;;;;N;;;;;
+2B91;RETURN RIGHT;So;0;ON;;;;;N;;;;;
+2B92;NEWLINE LEFT;So;0;ON;;;;;N;;;;;
+2B93;NEWLINE RIGHT;So;0;ON;;;;;N;;;;;
+2B94;FOUR CORNER ARROWS CIRCLING ANTICLOCKWISE;So;0;ON;;;;;N;;;;;
+2B95;RIGHTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
+2B98;THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B99;THREE-D RIGHT-LIGHTED UPWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9A;THREE-D TOP-LIGHTED RIGHTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9B;THREE-D LEFT-LIGHTED DOWNWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9C;BLACK LEFTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9D;BLACK UPWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9E;BLACK RIGHTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2B9F;BLACK DOWNWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+2BA0;DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS;So;0;ON;;;;;N;;;;;
+2BA1;DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS;So;0;ON;;;;;N;;;;;
+2BA2;UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS;So;0;ON;;;;;N;;;;;
+2BA3;UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS;So;0;ON;;;;;N;;;;;
+2BA4;LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS;So;0;ON;;;;;N;;;;;
+2BA5;RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS;So;0;ON;;;;;N;;;;;
+2BA6;LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS;So;0;ON;;;;;N;;;;;
+2BA7;RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS;So;0;ON;;;;;N;;;;;
+2BA8;BLACK CURVED DOWNWARDS AND LEFTWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BA9;BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAA;BLACK CURVED UPWARDS AND LEFTWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAB;BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAC;BLACK CURVED LEFTWARDS AND UPWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAD;BLACK CURVED RIGHTWARDS AND UPWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAE;BLACK CURVED LEFTWARDS AND DOWNWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BAF;BLACK CURVED RIGHTWARDS AND DOWNWARDS ARROW;So;0;ON;;;;;N;;;;;
+2BB0;RIBBON ARROW DOWN LEFT;So;0;ON;;;;;N;;;;;
+2BB1;RIBBON ARROW DOWN RIGHT;So;0;ON;;;;;N;;;;;
+2BB2;RIBBON ARROW UP LEFT;So;0;ON;;;;;N;;;;;
+2BB3;RIBBON ARROW UP RIGHT;So;0;ON;;;;;N;;;;;
+2BB4;RIBBON ARROW LEFT UP;So;0;ON;;;;;N;;;;;
+2BB5;RIBBON ARROW RIGHT UP;So;0;ON;;;;;N;;;;;
+2BB6;RIBBON ARROW LEFT DOWN;So;0;ON;;;;;N;;;;;
+2BB7;RIBBON ARROW RIGHT DOWN;So;0;ON;;;;;N;;;;;
+2BB8;UPWARDS WHITE ARROW FROM BAR WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;;
+2BB9;UP ARROWHEAD IN A RECTANGLE BOX;So;0;ON;;;;;N;;;;;
+2BBD;BALLOT BOX WITH LIGHT X;So;0;ON;;;;;N;;;;;
+2BBE;CIRCLED X;So;0;ON;;;;;N;;;;;
+2BBF;CIRCLED BOLD X;So;0;ON;;;;;N;;;;;
+2BC0;BLACK SQUARE CENTRED;So;0;ON;;;;;N;;;;;
+2BC1;BLACK DIAMOND CENTRED;So;0;ON;;;;;N;;;;;
+2BC2;TURNED BLACK PENTAGON;So;0;ON;;;;;N;;;;;
+2BC3;HORIZONTAL BLACK OCTAGON;So;0;ON;;;;;N;;;;;
+2BC4;BLACK OCTAGON;So;0;ON;;;;;N;;;;;
+2BC5;BLACK MEDIUM UP-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;
+2BC6;BLACK MEDIUM DOWN-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;
+2BC7;BLACK MEDIUM LEFT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;
+2BC8;BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;
+2BCA;TOP HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+2BCB;BOTTOM HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
+2BCC;LIGHT FOUR POINTED BLACK CUSP;So;0;ON;;;;;N;;;;;
+2BCD;ROTATED LIGHT FOUR POINTED BLACK CUSP;So;0;ON;;;;;N;;;;;
+2BCE;WHITE FOUR POINTED CUSP;So;0;ON;;;;;N;;;;;
+2BCF;ROTATED WHITE FOUR POINTED CUSP;So;0;ON;;;;;N;;;;;
+2BD0;SQUARE POSITION INDICATOR;So;0;ON;;;;;N;;;;;
+2BD1;UNCERTAINTY SIGN;So;0;ON;;;;;N;;;;;
+2BEC;LEFTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;
+2BED;UPWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;
+2BEE;RIGHTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;
+2BEF;DOWNWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;
+2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30;
+2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31;
+2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32;
+2C03;GLAGOLITIC CAPITAL LETTER GLAGOLI;Lu;0;L;;;;;N;;;;2C33;
+2C04;GLAGOLITIC CAPITAL LETTER DOBRO;Lu;0;L;;;;;N;;;;2C34;
+2C05;GLAGOLITIC CAPITAL LETTER YESTU;Lu;0;L;;;;;N;;;;2C35;
+2C06;GLAGOLITIC CAPITAL LETTER ZHIVETE;Lu;0;L;;;;;N;;;;2C36;
+2C07;GLAGOLITIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;2C37;
+2C08;GLAGOLITIC CAPITAL LETTER ZEMLJA;Lu;0;L;;;;;N;;;;2C38;
+2C09;GLAGOLITIC CAPITAL LETTER IZHE;Lu;0;L;;;;;N;;;;2C39;
+2C0A;GLAGOLITIC CAPITAL LETTER INITIAL IZHE;Lu;0;L;;;;;N;;;;2C3A;
+2C0B;GLAGOLITIC CAPITAL LETTER I;Lu;0;L;;;;;N;;;;2C3B;
+2C0C;GLAGOLITIC CAPITAL LETTER DJERVI;Lu;0;L;;;;;N;;;;2C3C;
+2C0D;GLAGOLITIC CAPITAL LETTER KAKO;Lu;0;L;;;;;N;;;;2C3D;
+2C0E;GLAGOLITIC CAPITAL LETTER LJUDIJE;Lu;0;L;;;;;N;;;;2C3E;
+2C0F;GLAGOLITIC CAPITAL LETTER MYSLITE;Lu;0;L;;;;;N;;;;2C3F;
+2C10;GLAGOLITIC CAPITAL LETTER NASHI;Lu;0;L;;;;;N;;;;2C40;
+2C11;GLAGOLITIC CAPITAL LETTER ONU;Lu;0;L;;;;;N;;;;2C41;
+2C12;GLAGOLITIC CAPITAL LETTER POKOJI;Lu;0;L;;;;;N;;;;2C42;
+2C13;GLAGOLITIC CAPITAL LETTER RITSI;Lu;0;L;;;;;N;;;;2C43;
+2C14;GLAGOLITIC CAPITAL LETTER SLOVO;Lu;0;L;;;;;N;;;;2C44;
+2C15;GLAGOLITIC CAPITAL LETTER TVRIDO;Lu;0;L;;;;;N;;;;2C45;
+2C16;GLAGOLITIC CAPITAL LETTER UKU;Lu;0;L;;;;;N;;;;2C46;
+2C17;GLAGOLITIC CAPITAL LETTER FRITU;Lu;0;L;;;;;N;;;;2C47;
+2C18;GLAGOLITIC CAPITAL LETTER HERU;Lu;0;L;;;;;N;;;;2C48;
+2C19;GLAGOLITIC CAPITAL LETTER OTU;Lu;0;L;;;;;N;;;;2C49;
+2C1A;GLAGOLITIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;2C4A;
+2C1B;GLAGOLITIC CAPITAL LETTER SHTA;Lu;0;L;;;;;N;;;;2C4B;
+2C1C;GLAGOLITIC CAPITAL LETTER TSI;Lu;0;L;;;;;N;;;;2C4C;
+2C1D;GLAGOLITIC CAPITAL LETTER CHRIVI;Lu;0;L;;;;;N;;;;2C4D;
+2C1E;GLAGOLITIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;2C4E;
+2C1F;GLAGOLITIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;;;;2C4F;
+2C20;GLAGOLITIC CAPITAL LETTER YERI;Lu;0;L;;;;;N;;;;2C50;
+2C21;GLAGOLITIC CAPITAL LETTER YATI;Lu;0;L;;;;;N;;;;2C51;
+2C22;GLAGOLITIC CAPITAL LETTER SPIDERY HA;Lu;0;L;;;;;N;;;;2C52;
+2C23;GLAGOLITIC CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;2C53;
+2C24;GLAGOLITIC CAPITAL LETTER SMALL YUS;Lu;0;L;;;;;N;;;;2C54;
+2C25;GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL;Lu;0;L;;;;;N;;;;2C55;
+2C26;GLAGOLITIC CAPITAL LETTER YO;Lu;0;L;;;;;N;;;;2C56;
+2C27;GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS;Lu;0;L;;;;;N;;;;2C57;
+2C28;GLAGOLITIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;2C58;
+2C29;GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS;Lu;0;L;;;;;N;;;;2C59;
+2C2A;GLAGOLITIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;2C5A;
+2C2B;GLAGOLITIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;2C5B;
+2C2C;GLAGOLITIC CAPITAL LETTER SHTAPIC;Lu;0;L;;;;;N;;;;2C5C;
+2C2D;GLAGOLITIC CAPITAL LETTER TROKUTASTI A;Lu;0;L;;;;;N;;;;2C5D;
+2C2E;GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE;Lu;0;L;;;;;N;;;;2C5E;
+2C30;GLAGOLITIC SMALL LETTER AZU;Ll;0;L;;;;;N;;;2C00;;2C00
+2C31;GLAGOLITIC SMALL LETTER BUKY;Ll;0;L;;;;;N;;;2C01;;2C01
+2C32;GLAGOLITIC SMALL LETTER VEDE;Ll;0;L;;;;;N;;;2C02;;2C02
+2C33;GLAGOLITIC SMALL LETTER GLAGOLI;Ll;0;L;;;;;N;;;2C03;;2C03
+2C34;GLAGOLITIC SMALL LETTER DOBRO;Ll;0;L;;;;;N;;;2C04;;2C04
+2C35;GLAGOLITIC SMALL LETTER YESTU;Ll;0;L;;;;;N;;;2C05;;2C05
+2C36;GLAGOLITIC SMALL LETTER ZHIVETE;Ll;0;L;;;;;N;;;2C06;;2C06
+2C37;GLAGOLITIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;2C07;;2C07
+2C38;GLAGOLITIC SMALL LETTER ZEMLJA;Ll;0;L;;;;;N;;;2C08;;2C08
+2C39;GLAGOLITIC SMALL LETTER IZHE;Ll;0;L;;;;;N;;;2C09;;2C09
+2C3A;GLAGOLITIC SMALL LETTER INITIAL IZHE;Ll;0;L;;;;;N;;;2C0A;;2C0A
+2C3B;GLAGOLITIC SMALL LETTER I;Ll;0;L;;;;;N;;;2C0B;;2C0B
+2C3C;GLAGOLITIC SMALL LETTER DJERVI;Ll;0;L;;;;;N;;;2C0C;;2C0C
+2C3D;GLAGOLITIC SMALL LETTER KAKO;Ll;0;L;;;;;N;;;2C0D;;2C0D
+2C3E;GLAGOLITIC SMALL LETTER LJUDIJE;Ll;0;L;;;;;N;;;2C0E;;2C0E
+2C3F;GLAGOLITIC SMALL LETTER MYSLITE;Ll;0;L;;;;;N;;;2C0F;;2C0F
+2C40;GLAGOLITIC SMALL LETTER NASHI;Ll;0;L;;;;;N;;;2C10;;2C10
+2C41;GLAGOLITIC SMALL LETTER ONU;Ll;0;L;;;;;N;;;2C11;;2C11
+2C42;GLAGOLITIC SMALL LETTER POKOJI;Ll;0;L;;;;;N;;;2C12;;2C12
+2C43;GLAGOLITIC SMALL LETTER RITSI;Ll;0;L;;;;;N;;;2C13;;2C13
+2C44;GLAGOLITIC SMALL LETTER SLOVO;Ll;0;L;;;;;N;;;2C14;;2C14
+2C45;GLAGOLITIC SMALL LETTER TVRIDO;Ll;0;L;;;;;N;;;2C15;;2C15
+2C46;GLAGOLITIC SMALL LETTER UKU;Ll;0;L;;;;;N;;;2C16;;2C16
+2C47;GLAGOLITIC SMALL LETTER FRITU;Ll;0;L;;;;;N;;;2C17;;2C17
+2C48;GLAGOLITIC SMALL LETTER HERU;Ll;0;L;;;;;N;;;2C18;;2C18
+2C49;GLAGOLITIC SMALL LETTER OTU;Ll;0;L;;;;;N;;;2C19;;2C19
+2C4A;GLAGOLITIC SMALL LETTER PE;Ll;0;L;;;;;N;;;2C1A;;2C1A
+2C4B;GLAGOLITIC SMALL LETTER SHTA;Ll;0;L;;;;;N;;;2C1B;;2C1B
+2C4C;GLAGOLITIC SMALL LETTER TSI;Ll;0;L;;;;;N;;;2C1C;;2C1C
+2C4D;GLAGOLITIC SMALL LETTER CHRIVI;Ll;0;L;;;;;N;;;2C1D;;2C1D
+2C4E;GLAGOLITIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;2C1E;;2C1E
+2C4F;GLAGOLITIC SMALL LETTER YERU;Ll;0;L;;;;;N;;;2C1F;;2C1F
+2C50;GLAGOLITIC SMALL LETTER YERI;Ll;0;L;;;;;N;;;2C20;;2C20
+2C51;GLAGOLITIC SMALL LETTER YATI;Ll;0;L;;;;;N;;;2C21;;2C21
+2C52;GLAGOLITIC SMALL LETTER SPIDERY HA;Ll;0;L;;;;;N;;;2C22;;2C22
+2C53;GLAGOLITIC SMALL LETTER YU;Ll;0;L;;;;;N;;;2C23;;2C23
+2C54;GLAGOLITIC SMALL LETTER SMALL YUS;Ll;0;L;;;;;N;;;2C24;;2C24
+2C55;GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL;Ll;0;L;;;;;N;;;2C25;;2C25
+2C56;GLAGOLITIC SMALL LETTER YO;Ll;0;L;;;;;N;;;2C26;;2C26
+2C57;GLAGOLITIC SMALL LETTER IOTATED SMALL YUS;Ll;0;L;;;;;N;;;2C27;;2C27
+2C58;GLAGOLITIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;2C28;;2C28
+2C59;GLAGOLITIC SMALL LETTER IOTATED BIG YUS;Ll;0;L;;;;;N;;;2C29;;2C29
+2C5A;GLAGOLITIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;2C2A;;2C2A
+2C5B;GLAGOLITIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;2C2B;;2C2B
+2C5C;GLAGOLITIC SMALL LETTER SHTAPIC;Ll;0;L;;;;;N;;;2C2C;;2C2C
+2C5D;GLAGOLITIC SMALL LETTER TROKUTASTI A;Ll;0;L;;;;;N;;;2C2D;;2C2D
+2C5E;GLAGOLITIC SMALL LETTER LATINATE MYSLITE;Ll;0;L;;;;;N;;;2C2E;;2C2E
+2C60;LATIN CAPITAL LETTER L WITH DOUBLE BAR;Lu;0;L;;;;;N;;;;2C61;
+2C61;LATIN SMALL LETTER L WITH DOUBLE BAR;Ll;0;L;;;;;N;;;2C60;;2C60
+2C62;LATIN CAPITAL LETTER L WITH MIDDLE TILDE;Lu;0;L;;;;;N;;;;026B;
+2C63;LATIN CAPITAL LETTER P WITH STROKE;Lu;0;L;;;;;N;;;;1D7D;
+2C64;LATIN CAPITAL LETTER R WITH TAIL;Lu;0;L;;;;;N;;;;027D;
+2C65;LATIN SMALL LETTER A WITH STROKE;Ll;0;L;;;;;N;;;023A;;023A
+2C66;LATIN SMALL LETTER T WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;023E;;023E
+2C67;LATIN CAPITAL LETTER H WITH DESCENDER;Lu;0;L;;;;;N;;;;2C68;
+2C68;LATIN SMALL LETTER H WITH DESCENDER;Ll;0;L;;;;;N;;;2C67;;2C67
+2C69;LATIN CAPITAL LETTER K WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6A;
+2C6A;LATIN SMALL LETTER K WITH DESCENDER;Ll;0;L;;;;;N;;;2C69;;2C69
+2C6B;LATIN CAPITAL LETTER Z WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6C;
+2C6C;LATIN SMALL LETTER Z WITH DESCENDER;Ll;0;L;;;;;N;;;2C6B;;2C6B
+2C6D;LATIN CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;0251;
+2C6E;LATIN CAPITAL LETTER M WITH HOOK;Lu;0;L;;;;;N;;;;0271;
+2C6F;LATIN CAPITAL LETTER TURNED A;Lu;0;L;;;;;N;;;;0250;
+2C70;LATIN CAPITAL LETTER TURNED ALPHA;Lu;0;L;;;;;N;;;;0252;
+2C71;LATIN SMALL LETTER V WITH RIGHT HOOK;Ll;0;L;;;;;N;;;;;
+2C72;LATIN CAPITAL LETTER W WITH HOOK;Lu;0;L;;;;;N;;;;2C73;
+2C73;LATIN SMALL LETTER W WITH HOOK;Ll;0;L;;;;;N;;;2C72;;2C72
+2C74;LATIN SMALL LETTER V WITH CURL;Ll;0;L;;;;;N;;;;;
+2C75;LATIN CAPITAL LETTER HALF H;Lu;0;L;;;;;N;;;;2C76;
+2C76;LATIN SMALL LETTER HALF H;Ll;0;L;;;;;N;;;2C75;;2C75
+2C77;LATIN SMALL LETTER TAILLESS PHI;Ll;0;L;;;;;N;;;;;
+2C78;LATIN SMALL LETTER E WITH NOTCH;Ll;0;L;;;;;N;;;;;
+2C79;LATIN SMALL LETTER TURNED R WITH TAIL;Ll;0;L;;;;;N;;;;;
+2C7A;LATIN SMALL LETTER O WITH LOW RING INSIDE;Ll;0;L;;;;;N;;;;;
+2C7B;LATIN LETTER SMALL CAPITAL TURNED E;Ll;0;L;;;;;N;;;;;
+2C7C;LATIN SUBSCRIPT SMALL LETTER J;Lm;0;L;<sub> 006A;;;;N;;;;;
+2C7D;MODIFIER LETTER CAPITAL V;Lm;0;L;<super> 0056;;;;N;;;;;
+2C7E;LATIN CAPITAL LETTER S WITH SWASH TAIL;Lu;0;L;;;;;N;;;;023F;
+2C7F;LATIN CAPITAL LETTER Z WITH SWASH TAIL;Lu;0;L;;;;;N;;;;0240;
+2C80;COPTIC CAPITAL LETTER ALFA;Lu;0;L;;;;;N;;;;2C81;
+2C81;COPTIC SMALL LETTER ALFA;Ll;0;L;;;;;N;;;2C80;;2C80
+2C82;COPTIC CAPITAL LETTER VIDA;Lu;0;L;;;;;N;;;;2C83;
+2C83;COPTIC SMALL LETTER VIDA;Ll;0;L;;;;;N;;;2C82;;2C82
+2C84;COPTIC CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;2C85;
+2C85;COPTIC SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;2C84;;2C84
+2C86;COPTIC CAPITAL LETTER DALDA;Lu;0;L;;;;;N;;;;2C87;
+2C87;COPTIC SMALL LETTER DALDA;Ll;0;L;;;;;N;;;2C86;;2C86
+2C88;COPTIC CAPITAL LETTER EIE;Lu;0;L;;;;;N;;;;2C89;
+2C89;COPTIC SMALL LETTER EIE;Ll;0;L;;;;;N;;;2C88;;2C88
+2C8A;COPTIC CAPITAL LETTER SOU;Lu;0;L;;;;;N;;;;2C8B;
+2C8B;COPTIC SMALL LETTER SOU;Ll;0;L;;;;;N;;;2C8A;;2C8A
+2C8C;COPTIC CAPITAL LETTER ZATA;Lu;0;L;;;;;N;;;;2C8D;
+2C8D;COPTIC SMALL LETTER ZATA;Ll;0;L;;;;;N;;;2C8C;;2C8C
+2C8E;COPTIC CAPITAL LETTER HATE;Lu;0;L;;;;;N;;;;2C8F;
+2C8F;COPTIC SMALL LETTER HATE;Ll;0;L;;;;;N;;;2C8E;;2C8E
+2C90;COPTIC CAPITAL LETTER THETHE;Lu;0;L;;;;;N;;;;2C91;
+2C91;COPTIC SMALL LETTER THETHE;Ll;0;L;;;;;N;;;2C90;;2C90
+2C92;COPTIC CAPITAL LETTER IAUDA;Lu;0;L;;;;;N;;;;2C93;
+2C93;COPTIC SMALL LETTER IAUDA;Ll;0;L;;;;;N;;;2C92;;2C92
+2C94;COPTIC CAPITAL LETTER KAPA;Lu;0;L;;;;;N;;;;2C95;
+2C95;COPTIC SMALL LETTER KAPA;Ll;0;L;;;;;N;;;2C94;;2C94
+2C96;COPTIC CAPITAL LETTER LAULA;Lu;0;L;;;;;N;;;;2C97;
+2C97;COPTIC SMALL LETTER LAULA;Ll;0;L;;;;;N;;;2C96;;2C96
+2C98;COPTIC CAPITAL LETTER MI;Lu;0;L;;;;;N;;;;2C99;
+2C99;COPTIC SMALL LETTER MI;Ll;0;L;;;;;N;;;2C98;;2C98
+2C9A;COPTIC CAPITAL LETTER NI;Lu;0;L;;;;;N;;;;2C9B;
+2C9B;COPTIC SMALL LETTER NI;Ll;0;L;;;;;N;;;2C9A;;2C9A
+2C9C;COPTIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;2C9D;
+2C9D;COPTIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;2C9C;;2C9C
+2C9E;COPTIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;2C9F;
+2C9F;COPTIC SMALL LETTER O;Ll;0;L;;;;;N;;;2C9E;;2C9E
+2CA0;COPTIC CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;2CA1;
+2CA1;COPTIC SMALL LETTER PI;Ll;0;L;;;;;N;;;2CA0;;2CA0
+2CA2;COPTIC CAPITAL LETTER RO;Lu;0;L;;;;;N;;;;2CA3;
+2CA3;COPTIC SMALL LETTER RO;Ll;0;L;;;;;N;;;2CA2;;2CA2
+2CA4;COPTIC CAPITAL LETTER SIMA;Lu;0;L;;;;;N;;;;2CA5;
+2CA5;COPTIC SMALL LETTER SIMA;Ll;0;L;;;;;N;;;2CA4;;2CA4
+2CA6;COPTIC CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;2CA7;
+2CA7;COPTIC SMALL LETTER TAU;Ll;0;L;;;;;N;;;2CA6;;2CA6
+2CA8;COPTIC CAPITAL LETTER UA;Lu;0;L;;;;;N;;;;2CA9;
+2CA9;COPTIC SMALL LETTER UA;Ll;0;L;;;;;N;;;2CA8;;2CA8
+2CAA;COPTIC CAPITAL LETTER FI;Lu;0;L;;;;;N;;;;2CAB;
+2CAB;COPTIC SMALL LETTER FI;Ll;0;L;;;;;N;;;2CAA;;2CAA
+2CAC;COPTIC CAPITAL LETTER KHI;Lu;0;L;;;;;N;;;;2CAD;
+2CAD;COPTIC SMALL LETTER KHI;Ll;0;L;;;;;N;;;2CAC;;2CAC
+2CAE;COPTIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;2CAF;
+2CAF;COPTIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;2CAE;;2CAE
+2CB0;COPTIC CAPITAL LETTER OOU;Lu;0;L;;;;;N;;;;2CB1;
+2CB1;COPTIC SMALL LETTER OOU;Ll;0;L;;;;;N;;;2CB0;;2CB0
+2CB2;COPTIC CAPITAL LETTER DIALECT-P ALEF;Lu;0;L;;;;;N;;;;2CB3;
+2CB3;COPTIC SMALL LETTER DIALECT-P ALEF;Ll;0;L;;;;;N;;;2CB2;;2CB2
+2CB4;COPTIC CAPITAL LETTER OLD COPTIC AIN;Lu;0;L;;;;;N;;;;2CB5;
+2CB5;COPTIC SMALL LETTER OLD COPTIC AIN;Ll;0;L;;;;;N;;;2CB4;;2CB4
+2CB6;COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE;Lu;0;L;;;;;N;;;;2CB7;
+2CB7;COPTIC SMALL LETTER CRYPTOGRAMMIC EIE;Ll;0;L;;;;;N;;;2CB6;;2CB6
+2CB8;COPTIC CAPITAL LETTER DIALECT-P KAPA;Lu;0;L;;;;;N;;;;2CB9;
+2CB9;COPTIC SMALL LETTER DIALECT-P KAPA;Ll;0;L;;;;;N;;;2CB8;;2CB8
+2CBA;COPTIC CAPITAL LETTER DIALECT-P NI;Lu;0;L;;;;;N;;;;2CBB;
+2CBB;COPTIC SMALL LETTER DIALECT-P NI;Ll;0;L;;;;;N;;;2CBA;;2CBA
+2CBC;COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI;Lu;0;L;;;;;N;;;;2CBD;
+2CBD;COPTIC SMALL LETTER CRYPTOGRAMMIC NI;Ll;0;L;;;;;N;;;2CBC;;2CBC
+2CBE;COPTIC CAPITAL LETTER OLD COPTIC OOU;Lu;0;L;;;;;N;;;;2CBF;
+2CBF;COPTIC SMALL LETTER OLD COPTIC OOU;Ll;0;L;;;;;N;;;2CBE;;2CBE
+2CC0;COPTIC CAPITAL LETTER SAMPI;Lu;0;L;;;;;N;;;;2CC1;
+2CC1;COPTIC SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;2CC0;;2CC0
+2CC2;COPTIC CAPITAL LETTER CROSSED SHEI;Lu;0;L;;;;;N;;;;2CC3;
+2CC3;COPTIC SMALL LETTER CROSSED SHEI;Ll;0;L;;;;;N;;;2CC2;;2CC2
+2CC4;COPTIC CAPITAL LETTER OLD COPTIC SHEI;Lu;0;L;;;;;N;;;;2CC5;
+2CC5;COPTIC SMALL LETTER OLD COPTIC SHEI;Ll;0;L;;;;;N;;;2CC4;;2CC4
+2CC6;COPTIC CAPITAL LETTER OLD COPTIC ESH;Lu;0;L;;;;;N;;;;2CC7;
+2CC7;COPTIC SMALL LETTER OLD COPTIC ESH;Ll;0;L;;;;;N;;;2CC6;;2CC6
+2CC8;COPTIC CAPITAL LETTER AKHMIMIC KHEI;Lu;0;L;;;;;N;;;;2CC9;
+2CC9;COPTIC SMALL LETTER AKHMIMIC KHEI;Ll;0;L;;;;;N;;;2CC8;;2CC8
+2CCA;COPTIC CAPITAL LETTER DIALECT-P HORI;Lu;0;L;;;;;N;;;;2CCB;
+2CCB;COPTIC SMALL LETTER DIALECT-P HORI;Ll;0;L;;;;;N;;;2CCA;;2CCA
+2CCC;COPTIC CAPITAL LETTER OLD COPTIC HORI;Lu;0;L;;;;;N;;;;2CCD;
+2CCD;COPTIC SMALL LETTER OLD COPTIC HORI;Ll;0;L;;;;;N;;;2CCC;;2CCC
+2CCE;COPTIC CAPITAL LETTER OLD COPTIC HA;Lu;0;L;;;;;N;;;;2CCF;
+2CCF;COPTIC SMALL LETTER OLD COPTIC HA;Ll;0;L;;;;;N;;;2CCE;;2CCE
+2CD0;COPTIC CAPITAL LETTER L-SHAPED HA;Lu;0;L;;;;;N;;;;2CD1;
+2CD1;COPTIC SMALL LETTER L-SHAPED HA;Ll;0;L;;;;;N;;;2CD0;;2CD0
+2CD2;COPTIC CAPITAL LETTER OLD COPTIC HEI;Lu;0;L;;;;;N;;;;2CD3;
+2CD3;COPTIC SMALL LETTER OLD COPTIC HEI;Ll;0;L;;;;;N;;;2CD2;;2CD2
+2CD4;COPTIC CAPITAL LETTER OLD COPTIC HAT;Lu;0;L;;;;;N;;;;2CD5;
+2CD5;COPTIC SMALL LETTER OLD COPTIC HAT;Ll;0;L;;;;;N;;;2CD4;;2CD4
+2CD6;COPTIC CAPITAL LETTER OLD COPTIC GANGIA;Lu;0;L;;;;;N;;;;2CD7;
+2CD7;COPTIC SMALL LETTER OLD COPTIC GANGIA;Ll;0;L;;;;;N;;;2CD6;;2CD6
+2CD8;COPTIC CAPITAL LETTER OLD COPTIC DJA;Lu;0;L;;;;;N;;;;2CD9;
+2CD9;COPTIC SMALL LETTER OLD COPTIC DJA;Ll;0;L;;;;;N;;;2CD8;;2CD8
+2CDA;COPTIC CAPITAL LETTER OLD COPTIC SHIMA;Lu;0;L;;;;;N;;;;2CDB;
+2CDB;COPTIC SMALL LETTER OLD COPTIC SHIMA;Ll;0;L;;;;;N;;;2CDA;;2CDA
+2CDC;COPTIC CAPITAL LETTER OLD NUBIAN SHIMA;Lu;0;L;;;;;N;;;;2CDD;
+2CDD;COPTIC SMALL LETTER OLD NUBIAN SHIMA;Ll;0;L;;;;;N;;;2CDC;;2CDC
+2CDE;COPTIC CAPITAL LETTER OLD NUBIAN NGI;Lu;0;L;;;;;N;;;;2CDF;
+2CDF;COPTIC SMALL LETTER OLD NUBIAN NGI;Ll;0;L;;;;;N;;;2CDE;;2CDE
+2CE0;COPTIC CAPITAL LETTER OLD NUBIAN NYI;Lu;0;L;;;;;N;;;;2CE1;
+2CE1;COPTIC SMALL LETTER OLD NUBIAN NYI;Ll;0;L;;;;;N;;;2CE0;;2CE0
+2CE2;COPTIC CAPITAL LETTER OLD NUBIAN WAU;Lu;0;L;;;;;N;;;;2CE3;
+2CE3;COPTIC SMALL LETTER OLD NUBIAN WAU;Ll;0;L;;;;;N;;;2CE2;;2CE2
+2CE4;COPTIC SYMBOL KAI;Ll;0;L;;;;;N;;;;;
+2CE5;COPTIC SYMBOL MI RO;So;0;ON;;;;;N;;;;;
+2CE6;COPTIC SYMBOL PI RO;So;0;ON;;;;;N;;;;;
+2CE7;COPTIC SYMBOL STAUROS;So;0;ON;;;;;N;;;;;
+2CE8;COPTIC SYMBOL TAU RO;So;0;ON;;;;;N;;;;;
+2CE9;COPTIC SYMBOL KHI RO;So;0;ON;;;;;N;;;;;
+2CEA;COPTIC SYMBOL SHIMA SIMA;So;0;ON;;;;;N;;;;;
+2CEB;COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI;Lu;0;L;;;;;N;;;;2CEC;
+2CEC;COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI;Ll;0;L;;;;;N;;;2CEB;;2CEB
+2CED;COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA;Lu;0;L;;;;;N;;;;2CEE;
+2CEE;COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA;Ll;0;L;;;;;N;;;2CED;;2CED
+2CEF;COPTIC COMBINING NI ABOVE;Mn;230;NSM;;;;;N;;;;;
+2CF0;COPTIC COMBINING SPIRITUS ASPER;Mn;230;NSM;;;;;N;;;;;
+2CF1;COPTIC COMBINING SPIRITUS LENIS;Mn;230;NSM;;;;;N;;;;;
+2CF2;COPTIC CAPITAL LETTER BOHAIRIC KHEI;Lu;0;L;;;;;N;;;;2CF3;
+2CF3;COPTIC SMALL LETTER BOHAIRIC KHEI;Ll;0;L;;;;;N;;;2CF2;;2CF2
+2CF9;COPTIC OLD NUBIAN FULL STOP;Po;0;ON;;;;;N;;;;;
+2CFA;COPTIC OLD NUBIAN DIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;;
+2CFB;COPTIC OLD NUBIAN INDIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;;
+2CFC;COPTIC OLD NUBIAN VERSE DIVIDER;Po;0;ON;;;;;N;;;;;
+2CFD;COPTIC FRACTION ONE HALF;No;0;ON;;;;1/2;N;;;;;
+2CFE;COPTIC FULL STOP;Po;0;ON;;;;;N;;;;;
+2CFF;COPTIC MORPHOLOGICAL DIVIDER;Po;0;ON;;;;;N;;;;;
+2D00;GEORGIAN SMALL LETTER AN;Ll;0;L;;;;;N;;;10A0;;10A0
+2D01;GEORGIAN SMALL LETTER BAN;Ll;0;L;;;;;N;;;10A1;;10A1
+2D02;GEORGIAN SMALL LETTER GAN;Ll;0;L;;;;;N;;;10A2;;10A2
+2D03;GEORGIAN SMALL LETTER DON;Ll;0;L;;;;;N;;;10A3;;10A3
+2D04;GEORGIAN SMALL LETTER EN;Ll;0;L;;;;;N;;;10A4;;10A4
+2D05;GEORGIAN SMALL LETTER VIN;Ll;0;L;;;;;N;;;10A5;;10A5
+2D06;GEORGIAN SMALL LETTER ZEN;Ll;0;L;;;;;N;;;10A6;;10A6
+2D07;GEORGIAN SMALL LETTER TAN;Ll;0;L;;;;;N;;;10A7;;10A7
+2D08;GEORGIAN SMALL LETTER IN;Ll;0;L;;;;;N;;;10A8;;10A8
+2D09;GEORGIAN SMALL LETTER KAN;Ll;0;L;;;;;N;;;10A9;;10A9
+2D0A;GEORGIAN SMALL LETTER LAS;Ll;0;L;;;;;N;;;10AA;;10AA
+2D0B;GEORGIAN SMALL LETTER MAN;Ll;0;L;;;;;N;;;10AB;;10AB
+2D0C;GEORGIAN SMALL LETTER NAR;Ll;0;L;;;;;N;;;10AC;;10AC
+2D0D;GEORGIAN SMALL LETTER ON;Ll;0;L;;;;;N;;;10AD;;10AD
+2D0E;GEORGIAN SMALL LETTER PAR;Ll;0;L;;;;;N;;;10AE;;10AE
+2D0F;GEORGIAN SMALL LETTER ZHAR;Ll;0;L;;;;;N;;;10AF;;10AF
+2D10;GEORGIAN SMALL LETTER RAE;Ll;0;L;;;;;N;;;10B0;;10B0
+2D11;GEORGIAN SMALL LETTER SAN;Ll;0;L;;;;;N;;;10B1;;10B1
+2D12;GEORGIAN SMALL LETTER TAR;Ll;0;L;;;;;N;;;10B2;;10B2
+2D13;GEORGIAN SMALL LETTER UN;Ll;0;L;;;;;N;;;10B3;;10B3
+2D14;GEORGIAN SMALL LETTER PHAR;Ll;0;L;;;;;N;;;10B4;;10B4
+2D15;GEORGIAN SMALL LETTER KHAR;Ll;0;L;;;;;N;;;10B5;;10B5
+2D16;GEORGIAN SMALL LETTER GHAN;Ll;0;L;;;;;N;;;10B6;;10B6
+2D17;GEORGIAN SMALL LETTER QAR;Ll;0;L;;;;;N;;;10B7;;10B7
+2D18;GEORGIAN SMALL LETTER SHIN;Ll;0;L;;;;;N;;;10B8;;10B8
+2D19;GEORGIAN SMALL LETTER CHIN;Ll;0;L;;;;;N;;;10B9;;10B9
+2D1A;GEORGIAN SMALL LETTER CAN;Ll;0;L;;;;;N;;;10BA;;10BA
+2D1B;GEORGIAN SMALL LETTER JIL;Ll;0;L;;;;;N;;;10BB;;10BB
+2D1C;GEORGIAN SMALL LETTER CIL;Ll;0;L;;;;;N;;;10BC;;10BC
+2D1D;GEORGIAN SMALL LETTER CHAR;Ll;0;L;;;;;N;;;10BD;;10BD
+2D1E;GEORGIAN SMALL LETTER XAN;Ll;0;L;;;;;N;;;10BE;;10BE
+2D1F;GEORGIAN SMALL LETTER JHAN;Ll;0;L;;;;;N;;;10BF;;10BF
+2D20;GEORGIAN SMALL LETTER HAE;Ll;0;L;;;;;N;;;10C0;;10C0
+2D21;GEORGIAN SMALL LETTER HE;Ll;0;L;;;;;N;;;10C1;;10C1
+2D22;GEORGIAN SMALL LETTER HIE;Ll;0;L;;;;;N;;;10C2;;10C2
+2D23;GEORGIAN SMALL LETTER WE;Ll;0;L;;;;;N;;;10C3;;10C3
+2D24;GEORGIAN SMALL LETTER HAR;Ll;0;L;;;;;N;;;10C4;;10C4
+2D25;GEORGIAN SMALL LETTER HOE;Ll;0;L;;;;;N;;;10C5;;10C5
+2D27;GEORGIAN SMALL LETTER YN;Ll;0;L;;;;;N;;;10C7;;10C7
+2D2D;GEORGIAN SMALL LETTER AEN;Ll;0;L;;;;;N;;;10CD;;10CD
+2D30;TIFINAGH LETTER YA;Lo;0;L;;;;;N;;;;;
+2D31;TIFINAGH LETTER YAB;Lo;0;L;;;;;N;;;;;
+2D32;TIFINAGH LETTER YABH;Lo;0;L;;;;;N;;;;;
+2D33;TIFINAGH LETTER YAG;Lo;0;L;;;;;N;;;;;
+2D34;TIFINAGH LETTER YAGHH;Lo;0;L;;;;;N;;;;;
+2D35;TIFINAGH LETTER BERBER ACADEMY YAJ;Lo;0;L;;;;;N;;;;;
+2D36;TIFINAGH LETTER YAJ;Lo;0;L;;;;;N;;;;;
+2D37;TIFINAGH LETTER YAD;Lo;0;L;;;;;N;;;;;
+2D38;TIFINAGH LETTER YADH;Lo;0;L;;;;;N;;;;;
+2D39;TIFINAGH LETTER YADD;Lo;0;L;;;;;N;;;;;
+2D3A;TIFINAGH LETTER YADDH;Lo;0;L;;;;;N;;;;;
+2D3B;TIFINAGH LETTER YEY;Lo;0;L;;;;;N;;;;;
+2D3C;TIFINAGH LETTER YAF;Lo;0;L;;;;;N;;;;;
+2D3D;TIFINAGH LETTER YAK;Lo;0;L;;;;;N;;;;;
+2D3E;TIFINAGH LETTER TUAREG YAK;Lo;0;L;;;;;N;;;;;
+2D3F;TIFINAGH LETTER YAKHH;Lo;0;L;;;;;N;;;;;
+2D40;TIFINAGH LETTER YAH;Lo;0;L;;;;;N;;;;;
+2D41;TIFINAGH LETTER BERBER ACADEMY YAH;Lo;0;L;;;;;N;;;;;
+2D42;TIFINAGH LETTER TUAREG YAH;Lo;0;L;;;;;N;;;;;
+2D43;TIFINAGH LETTER YAHH;Lo;0;L;;;;;N;;;;;
+2D44;TIFINAGH LETTER YAA;Lo;0;L;;;;;N;;;;;
+2D45;TIFINAGH LETTER YAKH;Lo;0;L;;;;;N;;;;;
+2D46;TIFINAGH LETTER TUAREG YAKH;Lo;0;L;;;;;N;;;;;
+2D47;TIFINAGH LETTER YAQ;Lo;0;L;;;;;N;;;;;
+2D48;TIFINAGH LETTER TUAREG YAQ;Lo;0;L;;;;;N;;;;;
+2D49;TIFINAGH LETTER YI;Lo;0;L;;;;;N;;;;;
+2D4A;TIFINAGH LETTER YAZH;Lo;0;L;;;;;N;;;;;
+2D4B;TIFINAGH LETTER AHAGGAR YAZH;Lo;0;L;;;;;N;;;;;
+2D4C;TIFINAGH LETTER TUAREG YAZH;Lo;0;L;;;;;N;;;;;
+2D4D;TIFINAGH LETTER YAL;Lo;0;L;;;;;N;;;;;
+2D4E;TIFINAGH LETTER YAM;Lo;0;L;;;;;N;;;;;
+2D4F;TIFINAGH LETTER YAN;Lo;0;L;;;;;N;;;;;
+2D50;TIFINAGH LETTER TUAREG YAGN;Lo;0;L;;;;;N;;;;;
+2D51;TIFINAGH LETTER TUAREG YANG;Lo;0;L;;;;;N;;;;;
+2D52;TIFINAGH LETTER YAP;Lo;0;L;;;;;N;;;;;
+2D53;TIFINAGH LETTER YU;Lo;0;L;;;;;N;;;;;
+2D54;TIFINAGH LETTER YAR;Lo;0;L;;;;;N;;;;;
+2D55;TIFINAGH LETTER YARR;Lo;0;L;;;;;N;;;;;
+2D56;TIFINAGH LETTER YAGH;Lo;0;L;;;;;N;;;;;
+2D57;TIFINAGH LETTER TUAREG YAGH;Lo;0;L;;;;;N;;;;;
+2D58;TIFINAGH LETTER AYER YAGH;Lo;0;L;;;;;N;;;;;
+2D59;TIFINAGH LETTER YAS;Lo;0;L;;;;;N;;;;;
+2D5A;TIFINAGH LETTER YASS;Lo;0;L;;;;;N;;;;;
+2D5B;TIFINAGH LETTER YASH;Lo;0;L;;;;;N;;;;;
+2D5C;TIFINAGH LETTER YAT;Lo;0;L;;;;;N;;;;;
+2D5D;TIFINAGH LETTER YATH;Lo;0;L;;;;;N;;;;;
+2D5E;TIFINAGH LETTER YACH;Lo;0;L;;;;;N;;;;;
+2D5F;TIFINAGH LETTER YATT;Lo;0;L;;;;;N;;;;;
+2D60;TIFINAGH LETTER YAV;Lo;0;L;;;;;N;;;;;
+2D61;TIFINAGH LETTER YAW;Lo;0;L;;;;;N;;;;;
+2D62;TIFINAGH LETTER YAY;Lo;0;L;;;;;N;;;;;
+2D63;TIFINAGH LETTER YAZ;Lo;0;L;;;;;N;;;;;
+2D64;TIFINAGH LETTER TAWELLEMET YAZ;Lo;0;L;;;;;N;;;;;
+2D65;TIFINAGH LETTER YAZZ;Lo;0;L;;;;;N;;;;;
+2D66;TIFINAGH LETTER YE;Lo;0;L;;;;;N;;;;;
+2D67;TIFINAGH LETTER YO;Lo;0;L;;;;;N;;;;;
+2D6F;TIFINAGH MODIFIER LETTER LABIALIZATION MARK;Lm;0;L;<super> 2D61;;;;N;;;;;
+2D70;TIFINAGH SEPARATOR MARK;Po;0;L;;;;;N;;;;;
+2D7F;TIFINAGH CONSONANT JOINER;Mn;9;NSM;;;;;N;;;;;
+2D80;ETHIOPIC SYLLABLE LOA;Lo;0;L;;;;;N;;;;;
+2D81;ETHIOPIC SYLLABLE MOA;Lo;0;L;;;;;N;;;;;
+2D82;ETHIOPIC SYLLABLE ROA;Lo;0;L;;;;;N;;;;;
+2D83;ETHIOPIC SYLLABLE SOA;Lo;0;L;;;;;N;;;;;
+2D84;ETHIOPIC SYLLABLE SHOA;Lo;0;L;;;;;N;;;;;
+2D85;ETHIOPIC SYLLABLE BOA;Lo;0;L;;;;;N;;;;;
+2D86;ETHIOPIC SYLLABLE TOA;Lo;0;L;;;;;N;;;;;
+2D87;ETHIOPIC SYLLABLE COA;Lo;0;L;;;;;N;;;;;
+2D88;ETHIOPIC SYLLABLE NOA;Lo;0;L;;;;;N;;;;;
+2D89;ETHIOPIC SYLLABLE NYOA;Lo;0;L;;;;;N;;;;;
+2D8A;ETHIOPIC SYLLABLE GLOTTAL OA;Lo;0;L;;;;;N;;;;;
+2D8B;ETHIOPIC SYLLABLE ZOA;Lo;0;L;;;;;N;;;;;
+2D8C;ETHIOPIC SYLLABLE DOA;Lo;0;L;;;;;N;;;;;
+2D8D;ETHIOPIC SYLLABLE DDOA;Lo;0;L;;;;;N;;;;;
+2D8E;ETHIOPIC SYLLABLE JOA;Lo;0;L;;;;;N;;;;;
+2D8F;ETHIOPIC SYLLABLE THOA;Lo;0;L;;;;;N;;;;;
+2D90;ETHIOPIC SYLLABLE CHOA;Lo;0;L;;;;;N;;;;;
+2D91;ETHIOPIC SYLLABLE PHOA;Lo;0;L;;;;;N;;;;;
+2D92;ETHIOPIC SYLLABLE POA;Lo;0;L;;;;;N;;;;;
+2D93;ETHIOPIC SYLLABLE GGWA;Lo;0;L;;;;;N;;;;;
+2D94;ETHIOPIC SYLLABLE GGWI;Lo;0;L;;;;;N;;;;;
+2D95;ETHIOPIC SYLLABLE GGWEE;Lo;0;L;;;;;N;;;;;
+2D96;ETHIOPIC SYLLABLE GGWE;Lo;0;L;;;;;N;;;;;
+2DA0;ETHIOPIC SYLLABLE SSA;Lo;0;L;;;;;N;;;;;
+2DA1;ETHIOPIC SYLLABLE SSU;Lo;0;L;;;;;N;;;;;
+2DA2;ETHIOPIC SYLLABLE SSI;Lo;0;L;;;;;N;;;;;
+2DA3;ETHIOPIC SYLLABLE SSAA;Lo;0;L;;;;;N;;;;;
+2DA4;ETHIOPIC SYLLABLE SSEE;Lo;0;L;;;;;N;;;;;
+2DA5;ETHIOPIC SYLLABLE SSE;Lo;0;L;;;;;N;;;;;
+2DA6;ETHIOPIC SYLLABLE SSO;Lo;0;L;;;;;N;;;;;
+2DA8;ETHIOPIC SYLLABLE CCA;Lo;0;L;;;;;N;;;;;
+2DA9;ETHIOPIC SYLLABLE CCU;Lo;0;L;;;;;N;;;;;
+2DAA;ETHIOPIC SYLLABLE CCI;Lo;0;L;;;;;N;;;;;
+2DAB;ETHIOPIC SYLLABLE CCAA;Lo;0;L;;;;;N;;;;;
+2DAC;ETHIOPIC SYLLABLE CCEE;Lo;0;L;;;;;N;;;;;
+2DAD;ETHIOPIC SYLLABLE CCE;Lo;0;L;;;;;N;;;;;
+2DAE;ETHIOPIC SYLLABLE CCO;Lo;0;L;;;;;N;;;;;
+2DB0;ETHIOPIC SYLLABLE ZZA;Lo;0;L;;;;;N;;;;;
+2DB1;ETHIOPIC SYLLABLE ZZU;Lo;0;L;;;;;N;;;;;
+2DB2;ETHIOPIC SYLLABLE ZZI;Lo;0;L;;;;;N;;;;;
+2DB3;ETHIOPIC SYLLABLE ZZAA;Lo;0;L;;;;;N;;;;;
+2DB4;ETHIOPIC SYLLABLE ZZEE;Lo;0;L;;;;;N;;;;;
+2DB5;ETHIOPIC SYLLABLE ZZE;Lo;0;L;;;;;N;;;;;
+2DB6;ETHIOPIC SYLLABLE ZZO;Lo;0;L;;;;;N;;;;;
+2DB8;ETHIOPIC SYLLABLE CCHA;Lo;0;L;;;;;N;;;;;
+2DB9;ETHIOPIC SYLLABLE CCHU;Lo;0;L;;;;;N;;;;;
+2DBA;ETHIOPIC SYLLABLE CCHI;Lo;0;L;;;;;N;;;;;
+2DBB;ETHIOPIC SYLLABLE CCHAA;Lo;0;L;;;;;N;;;;;
+2DBC;ETHIOPIC SYLLABLE CCHEE;Lo;0;L;;;;;N;;;;;
+2DBD;ETHIOPIC SYLLABLE CCHE;Lo;0;L;;;;;N;;;;;
+2DBE;ETHIOPIC SYLLABLE CCHO;Lo;0;L;;;;;N;;;;;
+2DC0;ETHIOPIC SYLLABLE QYA;Lo;0;L;;;;;N;;;;;
+2DC1;ETHIOPIC SYLLABLE QYU;Lo;0;L;;;;;N;;;;;
+2DC2;ETHIOPIC SYLLABLE QYI;Lo;0;L;;;;;N;;;;;
+2DC3;ETHIOPIC SYLLABLE QYAA;Lo;0;L;;;;;N;;;;;
+2DC4;ETHIOPIC SYLLABLE QYEE;Lo;0;L;;;;;N;;;;;
+2DC5;ETHIOPIC SYLLABLE QYE;Lo;0;L;;;;;N;;;;;
+2DC6;ETHIOPIC SYLLABLE QYO;Lo;0;L;;;;;N;;;;;
+2DC8;ETHIOPIC SYLLABLE KYA;Lo;0;L;;;;;N;;;;;
+2DC9;ETHIOPIC SYLLABLE KYU;Lo;0;L;;;;;N;;;;;
+2DCA;ETHIOPIC SYLLABLE KYI;Lo;0;L;;;;;N;;;;;
+2DCB;ETHIOPIC SYLLABLE KYAA;Lo;0;L;;;;;N;;;;;
+2DCC;ETHIOPIC SYLLABLE KYEE;Lo;0;L;;;;;N;;;;;
+2DCD;ETHIOPIC SYLLABLE KYE;Lo;0;L;;;;;N;;;;;
+2DCE;ETHIOPIC SYLLABLE KYO;Lo;0;L;;;;;N;;;;;
+2DD0;ETHIOPIC SYLLABLE XYA;Lo;0;L;;;;;N;;;;;
+2DD1;ETHIOPIC SYLLABLE XYU;Lo;0;L;;;;;N;;;;;
+2DD2;ETHIOPIC SYLLABLE XYI;Lo;0;L;;;;;N;;;;;
+2DD3;ETHIOPIC SYLLABLE XYAA;Lo;0;L;;;;;N;;;;;
+2DD4;ETHIOPIC SYLLABLE XYEE;Lo;0;L;;;;;N;;;;;
+2DD5;ETHIOPIC SYLLABLE XYE;Lo;0;L;;;;;N;;;;;
+2DD6;ETHIOPIC SYLLABLE XYO;Lo;0;L;;;;;N;;;;;
+2DD8;ETHIOPIC SYLLABLE GYA;Lo;0;L;;;;;N;;;;;
+2DD9;ETHIOPIC SYLLABLE GYU;Lo;0;L;;;;;N;;;;;
+2DDA;ETHIOPIC SYLLABLE GYI;Lo;0;L;;;;;N;;;;;
+2DDB;ETHIOPIC SYLLABLE GYAA;Lo;0;L;;;;;N;;;;;
+2DDC;ETHIOPIC SYLLABLE GYEE;Lo;0;L;;;;;N;;;;;
+2DDD;ETHIOPIC SYLLABLE GYE;Lo;0;L;;;;;N;;;;;
+2DDE;ETHIOPIC SYLLABLE GYO;Lo;0;L;;;;;N;;;;;
+2DE0;COMBINING CYRILLIC LETTER BE;Mn;230;NSM;;;;;N;;;;;
+2DE1;COMBINING CYRILLIC LETTER VE;Mn;230;NSM;;;;;N;;;;;
+2DE2;COMBINING CYRILLIC LETTER GHE;Mn;230;NSM;;;;;N;;;;;
+2DE3;COMBINING CYRILLIC LETTER DE;Mn;230;NSM;;;;;N;;;;;
+2DE4;COMBINING CYRILLIC LETTER ZHE;Mn;230;NSM;;;;;N;;;;;
+2DE5;COMBINING CYRILLIC LETTER ZE;Mn;230;NSM;;;;;N;;;;;
+2DE6;COMBINING CYRILLIC LETTER KA;Mn;230;NSM;;;;;N;;;;;
+2DE7;COMBINING CYRILLIC LETTER EL;Mn;230;NSM;;;;;N;;;;;
+2DE8;COMBINING CYRILLIC LETTER EM;Mn;230;NSM;;;;;N;;;;;
+2DE9;COMBINING CYRILLIC LETTER EN;Mn;230;NSM;;;;;N;;;;;
+2DEA;COMBINING CYRILLIC LETTER O;Mn;230;NSM;;;;;N;;;;;
+2DEB;COMBINING CYRILLIC LETTER PE;Mn;230;NSM;;;;;N;;;;;
+2DEC;COMBINING CYRILLIC LETTER ER;Mn;230;NSM;;;;;N;;;;;
+2DED;COMBINING CYRILLIC LETTER ES;Mn;230;NSM;;;;;N;;;;;
+2DEE;COMBINING CYRILLIC LETTER TE;Mn;230;NSM;;;;;N;;;;;
+2DEF;COMBINING CYRILLIC LETTER HA;Mn;230;NSM;;;;;N;;;;;
+2DF0;COMBINING CYRILLIC LETTER TSE;Mn;230;NSM;;;;;N;;;;;
+2DF1;COMBINING CYRILLIC LETTER CHE;Mn;230;NSM;;;;;N;;;;;
+2DF2;COMBINING CYRILLIC LETTER SHA;Mn;230;NSM;;;;;N;;;;;
+2DF3;COMBINING CYRILLIC LETTER SHCHA;Mn;230;NSM;;;;;N;;;;;
+2DF4;COMBINING CYRILLIC LETTER FITA;Mn;230;NSM;;;;;N;;;;;
+2DF5;COMBINING CYRILLIC LETTER ES-TE;Mn;230;NSM;;;;;N;;;;;
+2DF6;COMBINING CYRILLIC LETTER A;Mn;230;NSM;;;;;N;;;;;
+2DF7;COMBINING CYRILLIC LETTER IE;Mn;230;NSM;;;;;N;;;;;
+2DF8;COMBINING CYRILLIC LETTER DJERV;Mn;230;NSM;;;;;N;;;;;
+2DF9;COMBINING CYRILLIC LETTER MONOGRAPH UK;Mn;230;NSM;;;;;N;;;;;
+2DFA;COMBINING CYRILLIC LETTER YAT;Mn;230;NSM;;;;;N;;;;;
+2DFB;COMBINING CYRILLIC LETTER YU;Mn;230;NSM;;;;;N;;;;;
+2DFC;COMBINING CYRILLIC LETTER IOTIFIED A;Mn;230;NSM;;;;;N;;;;;
+2DFD;COMBINING CYRILLIC LETTER LITTLE YUS;Mn;230;NSM;;;;;N;;;;;
+2DFE;COMBINING CYRILLIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;;
+2DFF;COMBINING CYRILLIC LETTER IOTIFIED BIG YUS;Mn;230;NSM;;;;;N;;;;;
+2E00;RIGHT ANGLE SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;;
+2E01;RIGHT ANGLE DOTTED SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;;
+2E02;LEFT SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;;
+2E03;RIGHT SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;;
+2E04;LEFT DOTTED SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;;
+2E05;RIGHT DOTTED SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;;
+2E06;RAISED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;;
+2E07;RAISED DOTTED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;;
+2E08;DOTTED TRANSPOSITION MARKER;Po;0;ON;;;;;N;;;;;
+2E09;LEFT TRANSPOSITION BRACKET;Pi;0;ON;;;;;Y;;;;;
+2E0A;RIGHT TRANSPOSITION BRACKET;Pf;0;ON;;;;;Y;;;;;
+2E0B;RAISED SQUARE;Po;0;ON;;;;;N;;;;;
+2E0C;LEFT RAISED OMISSION BRACKET;Pi;0;ON;;;;;Y;;;;;
+2E0D;RIGHT RAISED OMISSION BRACKET;Pf;0;ON;;;;;Y;;;;;
+2E0E;EDITORIAL CORONIS;Po;0;ON;;;;;N;;;;;
+2E0F;PARAGRAPHOS;Po;0;ON;;;;;N;;;;;
+2E10;FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;;
+2E11;REVERSED FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;;
+2E12;HYPODIASTOLE;Po;0;ON;;;;;N;;;;;
+2E13;DOTTED OBELOS;Po;0;ON;;;;;N;;;;;
+2E14;DOWNWARDS ANCORA;Po;0;ON;;;;;N;;;;;
+2E15;UPWARDS ANCORA;Po;0;ON;;;;;N;;;;;
+2E16;DOTTED RIGHT-POINTING ANGLE;Po;0;ON;;;;;N;;;;;
+2E17;DOUBLE OBLIQUE HYPHEN;Pd;0;ON;;;;;N;;;;;
+2E18;INVERTED INTERROBANG;Po;0;ON;;;;;N;;;;;
+2E19;PALM BRANCH;Po;0;ON;;;;;N;;;;;
+2E1A;HYPHEN WITH DIAERESIS;Pd;0;ON;;;;;N;;;;;
+2E1B;TILDE WITH RING ABOVE;Po;0;ON;;;;;N;;;;;
+2E1C;LEFT LOW PARAPHRASE BRACKET;Pi;0;ON;;;;;Y;;;;;
+2E1D;RIGHT LOW PARAPHRASE BRACKET;Pf;0;ON;;;;;Y;;;;;
+2E1E;TILDE WITH DOT ABOVE;Po;0;ON;;;;;N;;;;;
+2E1F;TILDE WITH DOT BELOW;Po;0;ON;;;;;N;;;;;
+2E20;LEFT VERTICAL BAR WITH QUILL;Pi;0;ON;;;;;Y;;;;;
+2E21;RIGHT VERTICAL BAR WITH QUILL;Pf;0;ON;;;;;Y;;;;;
+2E22;TOP LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;;
+2E23;TOP RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;;
+2E24;BOTTOM LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;;
+2E25;BOTTOM RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;;
+2E26;LEFT SIDEWAYS U BRACKET;Ps;0;ON;;;;;Y;;;;;
+2E27;RIGHT SIDEWAYS U BRACKET;Pe;0;ON;;;;;Y;;;;;
+2E28;LEFT DOUBLE PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
+2E29;RIGHT DOUBLE PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
+2E2A;TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+2E2B;ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;;
+2E2C;SQUARED FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+2E2D;FIVE DOT MARK;Po;0;ON;;;;;N;;;;;
+2E2E;REVERSED QUESTION MARK;Po;0;ON;;;;;N;;;;;
+2E2F;VERTICAL TILDE;Lm;0;ON;;;;;N;;;;;
+2E30;RING POINT;Po;0;ON;;;;;N;;;;;
+2E31;WORD SEPARATOR MIDDLE DOT;Po;0;ON;;;;;N;;;;;
+2E32;TURNED COMMA;Po;0;ON;;;;;N;;;;;
+2E33;RAISED DOT;Po;0;ON;;;;;N;;;;;
+2E34;RAISED COMMA;Po;0;ON;;;;;N;;;;;
+2E35;TURNED SEMICOLON;Po;0;ON;;;;;N;;;;;
+2E36;DAGGER WITH LEFT GUARD;Po;0;ON;;;;;N;;;;;
+2E37;DAGGER WITH RIGHT GUARD;Po;0;ON;;;;;N;;;;;
+2E38;TURNED DAGGER;Po;0;ON;;;;;N;;;;;
+2E39;TOP HALF SECTION SIGN;Po;0;ON;;;;;N;;;;;
+2E3A;TWO-EM DASH;Pd;0;ON;;;;;N;;;;;
+2E3B;THREE-EM DASH;Pd;0;ON;;;;;N;;;;;
+2E3C;STENOGRAPHIC FULL STOP;Po;0;ON;;;;;N;;;;;
+2E3D;VERTICAL SIX DOTS;Po;0;ON;;;;;N;;;;;
+2E3E;WIGGLY VERTICAL LINE;Po;0;ON;;;;;N;;;;;
+2E3F;CAPITULUM;Po;0;ON;;;;;N;;;;;
+2E40;DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;;
+2E41;REVERSED COMMA;Po;0;ON;;;;;N;;;;;
+2E42;DOUBLE LOW-REVERSED-9 QUOTATION MARK;Ps;0;ON;;;;;N;;;;;
+2E43;DASH WITH LEFT UPTURN;Po;0;ON;;;;;N;;;;;
+2E44;DOUBLE SUSPENSION MARK;Po;0;ON;;;;;N;;;;;
+2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;;
+2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;;
+2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;;
+2E83;CJK RADICAL SECOND TWO;So;0;ON;;;;;N;;;;;
+2E84;CJK RADICAL SECOND THREE;So;0;ON;;;;;N;;;;;
+2E85;CJK RADICAL PERSON;So;0;ON;;;;;N;;;;;
+2E86;CJK RADICAL BOX;So;0;ON;;;;;N;;;;;
+2E87;CJK RADICAL TABLE;So;0;ON;;;;;N;;;;;
+2E88;CJK RADICAL KNIFE ONE;So;0;ON;;;;;N;;;;;
+2E89;CJK RADICAL KNIFE TWO;So;0;ON;;;;;N;;;;;
+2E8A;CJK RADICAL DIVINATION;So;0;ON;;;;;N;;;;;
+2E8B;CJK RADICAL SEAL;So;0;ON;;;;;N;;;;;
+2E8C;CJK RADICAL SMALL ONE;So;0;ON;;;;;N;;;;;
+2E8D;CJK RADICAL SMALL TWO;So;0;ON;;;;;N;;;;;
+2E8E;CJK RADICAL LAME ONE;So;0;ON;;;;;N;;;;;
+2E8F;CJK RADICAL LAME TWO;So;0;ON;;;;;N;;;;;
+2E90;CJK RADICAL LAME THREE;So;0;ON;;;;;N;;;;;
+2E91;CJK RADICAL LAME FOUR;So;0;ON;;;;;N;;;;;
+2E92;CJK RADICAL SNAKE;So;0;ON;;;;;N;;;;;
+2E93;CJK RADICAL THREAD;So;0;ON;;;;;N;;;;;
+2E94;CJK RADICAL SNOUT ONE;So;0;ON;;;;;N;;;;;
+2E95;CJK RADICAL SNOUT TWO;So;0;ON;;;;;N;;;;;
+2E96;CJK RADICAL HEART ONE;So;0;ON;;;;;N;;;;;
+2E97;CJK RADICAL HEART TWO;So;0;ON;;;;;N;;;;;
+2E98;CJK RADICAL HAND;So;0;ON;;;;;N;;;;;
+2E99;CJK RADICAL RAP;So;0;ON;;;;;N;;;;;
+2E9B;CJK RADICAL CHOKE;So;0;ON;;;;;N;;;;;
+2E9C;CJK RADICAL SUN;So;0;ON;;;;;N;;;;;
+2E9D;CJK RADICAL MOON;So;0;ON;;;;;N;;;;;
+2E9E;CJK RADICAL DEATH;So;0;ON;;;;;N;;;;;
+2E9F;CJK RADICAL MOTHER;So;0;ON;<compat> 6BCD;;;;N;;;;;
+2EA0;CJK RADICAL CIVILIAN;So;0;ON;;;;;N;;;;;
+2EA1;CJK RADICAL WATER ONE;So;0;ON;;;;;N;;;;;
+2EA2;CJK RADICAL WATER TWO;So;0;ON;;;;;N;;;;;
+2EA3;CJK RADICAL FIRE;So;0;ON;;;;;N;;;;;
+2EA4;CJK RADICAL PAW ONE;So;0;ON;;;;;N;;;;;
+2EA5;CJK RADICAL PAW TWO;So;0;ON;;;;;N;;;;;
+2EA6;CJK RADICAL SIMPLIFIED HALF TREE TRUNK;So;0;ON;;;;;N;;;;;
+2EA7;CJK RADICAL COW;So;0;ON;;;;;N;;;;;
+2EA8;CJK RADICAL DOG;So;0;ON;;;;;N;;;;;
+2EA9;CJK RADICAL JADE;So;0;ON;;;;;N;;;;;
+2EAA;CJK RADICAL BOLT OF CLOTH;So;0;ON;;;;;N;;;;;
+2EAB;CJK RADICAL EYE;So;0;ON;;;;;N;;;;;
+2EAC;CJK RADICAL SPIRIT ONE;So;0;ON;;;;;N;;;;;
+2EAD;CJK RADICAL SPIRIT TWO;So;0;ON;;;;;N;;;;;
+2EAE;CJK RADICAL BAMBOO;So;0;ON;;;;;N;;;;;
+2EAF;CJK RADICAL SILK;So;0;ON;;;;;N;;;;;
+2EB0;CJK RADICAL C-SIMPLIFIED SILK;So;0;ON;;;;;N;;;;;
+2EB1;CJK RADICAL NET ONE;So;0;ON;;;;;N;;;;;
+2EB2;CJK RADICAL NET TWO;So;0;ON;;;;;N;;;;;
+2EB3;CJK RADICAL NET THREE;So;0;ON;;;;;N;;;;;
+2EB4;CJK RADICAL NET FOUR;So;0;ON;;;;;N;;;;;
+2EB5;CJK RADICAL MESH;So;0;ON;;;;;N;;;;;
+2EB6;CJK RADICAL SHEEP;So;0;ON;;;;;N;;;;;
+2EB7;CJK RADICAL RAM;So;0;ON;;;;;N;;;;;
+2EB8;CJK RADICAL EWE;So;0;ON;;;;;N;;;;;
+2EB9;CJK RADICAL OLD;So;0;ON;;;;;N;;;;;
+2EBA;CJK RADICAL BRUSH ONE;So;0;ON;;;;;N;;;;;
+2EBB;CJK RADICAL BRUSH TWO;So;0;ON;;;;;N;;;;;
+2EBC;CJK RADICAL MEAT;So;0;ON;;;;;N;;;;;
+2EBD;CJK RADICAL MORTAR;So;0;ON;;;;;N;;;;;
+2EBE;CJK RADICAL GRASS ONE;So;0;ON;;;;;N;;;;;
+2EBF;CJK RADICAL GRASS TWO;So;0;ON;;;;;N;;;;;
+2EC0;CJK RADICAL GRASS THREE;So;0;ON;;;;;N;;;;;
+2EC1;CJK RADICAL TIGER;So;0;ON;;;;;N;;;;;
+2EC2;CJK RADICAL CLOTHES;So;0;ON;;;;;N;;;;;
+2EC3;CJK RADICAL WEST ONE;So;0;ON;;;;;N;;;;;
+2EC4;CJK RADICAL WEST TWO;So;0;ON;;;;;N;;;;;
+2EC5;CJK RADICAL C-SIMPLIFIED SEE;So;0;ON;;;;;N;;;;;
+2EC6;CJK RADICAL SIMPLIFIED HORN;So;0;ON;;;;;N;;;;;
+2EC7;CJK RADICAL HORN;So;0;ON;;;;;N;;;;;
+2EC8;CJK RADICAL C-SIMPLIFIED SPEECH;So;0;ON;;;;;N;;;;;
+2EC9;CJK RADICAL C-SIMPLIFIED SHELL;So;0;ON;;;;;N;;;;;
+2ECA;CJK RADICAL FOOT;So;0;ON;;;;;N;;;;;
+2ECB;CJK RADICAL C-SIMPLIFIED CART;So;0;ON;;;;;N;;;;;
+2ECC;CJK RADICAL SIMPLIFIED WALK;So;0;ON;;;;;N;;;;;
+2ECD;CJK RADICAL WALK ONE;So;0;ON;;;;;N;;;;;
+2ECE;CJK RADICAL WALK TWO;So;0;ON;;;;;N;;;;;
+2ECF;CJK RADICAL CITY;So;0;ON;;;;;N;;;;;
+2ED0;CJK RADICAL C-SIMPLIFIED GOLD;So;0;ON;;;;;N;;;;;
+2ED1;CJK RADICAL LONG ONE;So;0;ON;;;;;N;;;;;
+2ED2;CJK RADICAL LONG TWO;So;0;ON;;;;;N;;;;;
+2ED3;CJK RADICAL C-SIMPLIFIED LONG;So;0;ON;;;;;N;;;;;
+2ED4;CJK RADICAL C-SIMPLIFIED GATE;So;0;ON;;;;;N;;;;;
+2ED5;CJK RADICAL MOUND ONE;So;0;ON;;;;;N;;;;;
+2ED6;CJK RADICAL MOUND TWO;So;0;ON;;;;;N;;;;;
+2ED7;CJK RADICAL RAIN;So;0;ON;;;;;N;;;;;
+2ED8;CJK RADICAL BLUE;So;0;ON;;;;;N;;;;;
+2ED9;CJK RADICAL C-SIMPLIFIED TANNED LEATHER;So;0;ON;;;;;N;;;;;
+2EDA;CJK RADICAL C-SIMPLIFIED LEAF;So;0;ON;;;;;N;;;;;
+2EDB;CJK RADICAL C-SIMPLIFIED WIND;So;0;ON;;;;;N;;;;;
+2EDC;CJK RADICAL C-SIMPLIFIED FLY;So;0;ON;;;;;N;;;;;
+2EDD;CJK RADICAL EAT ONE;So;0;ON;;;;;N;;;;;
+2EDE;CJK RADICAL EAT TWO;So;0;ON;;;;;N;;;;;
+2EDF;CJK RADICAL EAT THREE;So;0;ON;;;;;N;;;;;
+2EE0;CJK RADICAL C-SIMPLIFIED EAT;So;0;ON;;;;;N;;;;;
+2EE1;CJK RADICAL HEAD;So;0;ON;;;;;N;;;;;
+2EE2;CJK RADICAL C-SIMPLIFIED HORSE;So;0;ON;;;;;N;;;;;
+2EE3;CJK RADICAL BONE;So;0;ON;;;;;N;;;;;
+2EE4;CJK RADICAL GHOST;So;0;ON;;;;;N;;;;;
+2EE5;CJK RADICAL C-SIMPLIFIED FISH;So;0;ON;;;;;N;;;;;
+2EE6;CJK RADICAL C-SIMPLIFIED BIRD;So;0;ON;;;;;N;;;;;
+2EE7;CJK RADICAL C-SIMPLIFIED SALT;So;0;ON;;;;;N;;;;;
+2EE8;CJK RADICAL SIMPLIFIED WHEAT;So;0;ON;;;;;N;;;;;
+2EE9;CJK RADICAL SIMPLIFIED YELLOW;So;0;ON;;;;;N;;;;;
+2EEA;CJK RADICAL C-SIMPLIFIED FROG;So;0;ON;;;;;N;;;;;
+2EEB;CJK RADICAL J-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;;
+2EEC;CJK RADICAL C-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;;
+2EED;CJK RADICAL J-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;;
+2EEE;CJK RADICAL C-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;;
+2EEF;CJK RADICAL J-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;;
+2EF0;CJK RADICAL C-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;;
+2EF1;CJK RADICAL TURTLE;So;0;ON;;;;;N;;;;;
+2EF2;CJK RADICAL J-SIMPLIFIED TURTLE;So;0;ON;;;;;N;;;;;
+2EF3;CJK RADICAL C-SIMPLIFIED TURTLE;So;0;ON;<compat> 9F9F;;;;N;;;;;
+2F00;KANGXI RADICAL ONE;So;0;ON;<compat> 4E00;;;;N;;;;;
+2F01;KANGXI RADICAL LINE;So;0;ON;<compat> 4E28;;;;N;;;;;
+2F02;KANGXI RADICAL DOT;So;0;ON;<compat> 4E36;;;;N;;;;;
+2F03;KANGXI RADICAL SLASH;So;0;ON;<compat> 4E3F;;;;N;;;;;
+2F04;KANGXI RADICAL SECOND;So;0;ON;<compat> 4E59;;;;N;;;;;
+2F05;KANGXI RADICAL HOOK;So;0;ON;<compat> 4E85;;;;N;;;;;
+2F06;KANGXI RADICAL TWO;So;0;ON;<compat> 4E8C;;;;N;;;;;
+2F07;KANGXI RADICAL LID;So;0;ON;<compat> 4EA0;;;;N;;;;;
+2F08;KANGXI RADICAL MAN;So;0;ON;<compat> 4EBA;;;;N;;;;;
+2F09;KANGXI RADICAL LEGS;So;0;ON;<compat> 513F;;;;N;;;;;
+2F0A;KANGXI RADICAL ENTER;So;0;ON;<compat> 5165;;;;N;;;;;
+2F0B;KANGXI RADICAL EIGHT;So;0;ON;<compat> 516B;;;;N;;;;;
+2F0C;KANGXI RADICAL DOWN BOX;So;0;ON;<compat> 5182;;;;N;;;;;
+2F0D;KANGXI RADICAL COVER;So;0;ON;<compat> 5196;;;;N;;;;;
+2F0E;KANGXI RADICAL ICE;So;0;ON;<compat> 51AB;;;;N;;;;;
+2F0F;KANGXI RADICAL TABLE;So;0;ON;<compat> 51E0;;;;N;;;;;
+2F10;KANGXI RADICAL OPEN BOX;So;0;ON;<compat> 51F5;;;;N;;;;;
+2F11;KANGXI RADICAL KNIFE;So;0;ON;<compat> 5200;;;;N;;;;;
+2F12;KANGXI RADICAL POWER;So;0;ON;<compat> 529B;;;;N;;;;;
+2F13;KANGXI RADICAL WRAP;So;0;ON;<compat> 52F9;;;;N;;;;;
+2F14;KANGXI RADICAL SPOON;So;0;ON;<compat> 5315;;;;N;;;;;
+2F15;KANGXI RADICAL RIGHT OPEN BOX;So;0;ON;<compat> 531A;;;;N;;;;;
+2F16;KANGXI RADICAL HIDING ENCLOSURE;So;0;ON;<compat> 5338;;;;N;;;;;
+2F17;KANGXI RADICAL TEN;So;0;ON;<compat> 5341;;;;N;;;;;
+2F18;KANGXI RADICAL DIVINATION;So;0;ON;<compat> 535C;;;;N;;;;;
+2F19;KANGXI RADICAL SEAL;So;0;ON;<compat> 5369;;;;N;;;;;
+2F1A;KANGXI RADICAL CLIFF;So;0;ON;<compat> 5382;;;;N;;;;;
+2F1B;KANGXI RADICAL PRIVATE;So;0;ON;<compat> 53B6;;;;N;;;;;
+2F1C;KANGXI RADICAL AGAIN;So;0;ON;<compat> 53C8;;;;N;;;;;
+2F1D;KANGXI RADICAL MOUTH;So;0;ON;<compat> 53E3;;;;N;;;;;
+2F1E;KANGXI RADICAL ENCLOSURE;So;0;ON;<compat> 56D7;;;;N;;;;;
+2F1F;KANGXI RADICAL EARTH;So;0;ON;<compat> 571F;;;;N;;;;;
+2F20;KANGXI RADICAL SCHOLAR;So;0;ON;<compat> 58EB;;;;N;;;;;
+2F21;KANGXI RADICAL GO;So;0;ON;<compat> 5902;;;;N;;;;;
+2F22;KANGXI RADICAL GO SLOWLY;So;0;ON;<compat> 590A;;;;N;;;;;
+2F23;KANGXI RADICAL EVENING;So;0;ON;<compat> 5915;;;;N;;;;;
+2F24;KANGXI RADICAL BIG;So;0;ON;<compat> 5927;;;;N;;;;;
+2F25;KANGXI RADICAL WOMAN;So;0;ON;<compat> 5973;;;;N;;;;;
+2F26;KANGXI RADICAL CHILD;So;0;ON;<compat> 5B50;;;;N;;;;;
+2F27;KANGXI RADICAL ROOF;So;0;ON;<compat> 5B80;;;;N;;;;;
+2F28;KANGXI RADICAL INCH;So;0;ON;<compat> 5BF8;;;;N;;;;;
+2F29;KANGXI RADICAL SMALL;So;0;ON;<compat> 5C0F;;;;N;;;;;
+2F2A;KANGXI RADICAL LAME;So;0;ON;<compat> 5C22;;;;N;;;;;
+2F2B;KANGXI RADICAL CORPSE;So;0;ON;<compat> 5C38;;;;N;;;;;
+2F2C;KANGXI RADICAL SPROUT;So;0;ON;<compat> 5C6E;;;;N;;;;;
+2F2D;KANGXI RADICAL MOUNTAIN;So;0;ON;<compat> 5C71;;;;N;;;;;
+2F2E;KANGXI RADICAL RIVER;So;0;ON;<compat> 5DDB;;;;N;;;;;
+2F2F;KANGXI RADICAL WORK;So;0;ON;<compat> 5DE5;;;;N;;;;;
+2F30;KANGXI RADICAL ONESELF;So;0;ON;<compat> 5DF1;;;;N;;;;;
+2F31;KANGXI RADICAL TURBAN;So;0;ON;<compat> 5DFE;;;;N;;;;;
+2F32;KANGXI RADICAL DRY;So;0;ON;<compat> 5E72;;;;N;;;;;
+2F33;KANGXI RADICAL SHORT THREAD;So;0;ON;<compat> 5E7A;;;;N;;;;;
+2F34;KANGXI RADICAL DOTTED CLIFF;So;0;ON;<compat> 5E7F;;;;N;;;;;
+2F35;KANGXI RADICAL LONG STRIDE;So;0;ON;<compat> 5EF4;;;;N;;;;;
+2F36;KANGXI RADICAL TWO HANDS;So;0;ON;<compat> 5EFE;;;;N;;;;;
+2F37;KANGXI RADICAL SHOOT;So;0;ON;<compat> 5F0B;;;;N;;;;;
+2F38;KANGXI RADICAL BOW;So;0;ON;<compat> 5F13;;;;N;;;;;
+2F39;KANGXI RADICAL SNOUT;So;0;ON;<compat> 5F50;;;;N;;;;;
+2F3A;KANGXI RADICAL BRISTLE;So;0;ON;<compat> 5F61;;;;N;;;;;
+2F3B;KANGXI RADICAL STEP;So;0;ON;<compat> 5F73;;;;N;;;;;
+2F3C;KANGXI RADICAL HEART;So;0;ON;<compat> 5FC3;;;;N;;;;;
+2F3D;KANGXI RADICAL HALBERD;So;0;ON;<compat> 6208;;;;N;;;;;
+2F3E;KANGXI RADICAL DOOR;So;0;ON;<compat> 6236;;;;N;;;;;
+2F3F;KANGXI RADICAL HAND;So;0;ON;<compat> 624B;;;;N;;;;;
+2F40;KANGXI RADICAL BRANCH;So;0;ON;<compat> 652F;;;;N;;;;;
+2F41;KANGXI RADICAL RAP;So;0;ON;<compat> 6534;;;;N;;;;;
+2F42;KANGXI RADICAL SCRIPT;So;0;ON;<compat> 6587;;;;N;;;;;
+2F43;KANGXI RADICAL DIPPER;So;0;ON;<compat> 6597;;;;N;;;;;
+2F44;KANGXI RADICAL AXE;So;0;ON;<compat> 65A4;;;;N;;;;;
+2F45;KANGXI RADICAL SQUARE;So;0;ON;<compat> 65B9;;;;N;;;;;
+2F46;KANGXI RADICAL NOT;So;0;ON;<compat> 65E0;;;;N;;;;;
+2F47;KANGXI RADICAL SUN;So;0;ON;<compat> 65E5;;;;N;;;;;
+2F48;KANGXI RADICAL SAY;So;0;ON;<compat> 66F0;;;;N;;;;;
+2F49;KANGXI RADICAL MOON;So;0;ON;<compat> 6708;;;;N;;;;;
+2F4A;KANGXI RADICAL TREE;So;0;ON;<compat> 6728;;;;N;;;;;
+2F4B;KANGXI RADICAL LACK;So;0;ON;<compat> 6B20;;;;N;;;;;
+2F4C;KANGXI RADICAL STOP;So;0;ON;<compat> 6B62;;;;N;;;;;
+2F4D;KANGXI RADICAL DEATH;So;0;ON;<compat> 6B79;;;;N;;;;;
+2F4E;KANGXI RADICAL WEAPON;So;0;ON;<compat> 6BB3;;;;N;;;;;
+2F4F;KANGXI RADICAL DO NOT;So;0;ON;<compat> 6BCB;;;;N;;;;;
+2F50;KANGXI RADICAL COMPARE;So;0;ON;<compat> 6BD4;;;;N;;;;;
+2F51;KANGXI RADICAL FUR;So;0;ON;<compat> 6BDB;;;;N;;;;;
+2F52;KANGXI RADICAL CLAN;So;0;ON;<compat> 6C0F;;;;N;;;;;
+2F53;KANGXI RADICAL STEAM;So;0;ON;<compat> 6C14;;;;N;;;;;
+2F54;KANGXI RADICAL WATER;So;0;ON;<compat> 6C34;;;;N;;;;;
+2F55;KANGXI RADICAL FIRE;So;0;ON;<compat> 706B;;;;N;;;;;
+2F56;KANGXI RADICAL CLAW;So;0;ON;<compat> 722A;;;;N;;;;;
+2F57;KANGXI RADICAL FATHER;So;0;ON;<compat> 7236;;;;N;;;;;
+2F58;KANGXI RADICAL DOUBLE X;So;0;ON;<compat> 723B;;;;N;;;;;
+2F59;KANGXI RADICAL HALF TREE TRUNK;So;0;ON;<compat> 723F;;;;N;;;;;
+2F5A;KANGXI RADICAL SLICE;So;0;ON;<compat> 7247;;;;N;;;;;
+2F5B;KANGXI RADICAL FANG;So;0;ON;<compat> 7259;;;;N;;;;;
+2F5C;KANGXI RADICAL COW;So;0;ON;<compat> 725B;;;;N;;;;;
+2F5D;KANGXI RADICAL DOG;So;0;ON;<compat> 72AC;;;;N;;;;;
+2F5E;KANGXI RADICAL PROFOUND;So;0;ON;<compat> 7384;;;;N;;;;;
+2F5F;KANGXI RADICAL JADE;So;0;ON;<compat> 7389;;;;N;;;;;
+2F60;KANGXI RADICAL MELON;So;0;ON;<compat> 74DC;;;;N;;;;;
+2F61;KANGXI RADICAL TILE;So;0;ON;<compat> 74E6;;;;N;;;;;
+2F62;KANGXI RADICAL SWEET;So;0;ON;<compat> 7518;;;;N;;;;;
+2F63;KANGXI RADICAL LIFE;So;0;ON;<compat> 751F;;;;N;;;;;
+2F64;KANGXI RADICAL USE;So;0;ON;<compat> 7528;;;;N;;;;;
+2F65;KANGXI RADICAL FIELD;So;0;ON;<compat> 7530;;;;N;;;;;
+2F66;KANGXI RADICAL BOLT OF CLOTH;So;0;ON;<compat> 758B;;;;N;;;;;
+2F67;KANGXI RADICAL SICKNESS;So;0;ON;<compat> 7592;;;;N;;;;;
+2F68;KANGXI RADICAL DOTTED TENT;So;0;ON;<compat> 7676;;;;N;;;;;
+2F69;KANGXI RADICAL WHITE;So;0;ON;<compat> 767D;;;;N;;;;;
+2F6A;KANGXI RADICAL SKIN;So;0;ON;<compat> 76AE;;;;N;;;;;
+2F6B;KANGXI RADICAL DISH;So;0;ON;<compat> 76BF;;;;N;;;;;
+2F6C;KANGXI RADICAL EYE;So;0;ON;<compat> 76EE;;;;N;;;;;
+2F6D;KANGXI RADICAL SPEAR;So;0;ON;<compat> 77DB;;;;N;;;;;
+2F6E;KANGXI RADICAL ARROW;So;0;ON;<compat> 77E2;;;;N;;;;;
+2F6F;KANGXI RADICAL STONE;So;0;ON;<compat> 77F3;;;;N;;;;;
+2F70;KANGXI RADICAL SPIRIT;So;0;ON;<compat> 793A;;;;N;;;;;
+2F71;KANGXI RADICAL TRACK;So;0;ON;<compat> 79B8;;;;N;;;;;
+2F72;KANGXI RADICAL GRAIN;So;0;ON;<compat> 79BE;;;;N;;;;;
+2F73;KANGXI RADICAL CAVE;So;0;ON;<compat> 7A74;;;;N;;;;;
+2F74;KANGXI RADICAL STAND;So;0;ON;<compat> 7ACB;;;;N;;;;;
+2F75;KANGXI RADICAL BAMBOO;So;0;ON;<compat> 7AF9;;;;N;;;;;
+2F76;KANGXI RADICAL RICE;So;0;ON;<compat> 7C73;;;;N;;;;;
+2F77;KANGXI RADICAL SILK;So;0;ON;<compat> 7CF8;;;;N;;;;;
+2F78;KANGXI RADICAL JAR;So;0;ON;<compat> 7F36;;;;N;;;;;
+2F79;KANGXI RADICAL NET;So;0;ON;<compat> 7F51;;;;N;;;;;
+2F7A;KANGXI RADICAL SHEEP;So;0;ON;<compat> 7F8A;;;;N;;;;;
+2F7B;KANGXI RADICAL FEATHER;So;0;ON;<compat> 7FBD;;;;N;;;;;
+2F7C;KANGXI RADICAL OLD;So;0;ON;<compat> 8001;;;;N;;;;;
+2F7D;KANGXI RADICAL AND;So;0;ON;<compat> 800C;;;;N;;;;;
+2F7E;KANGXI RADICAL PLOW;So;0;ON;<compat> 8012;;;;N;;;;;
+2F7F;KANGXI RADICAL EAR;So;0;ON;<compat> 8033;;;;N;;;;;
+2F80;KANGXI RADICAL BRUSH;So;0;ON;<compat> 807F;;;;N;;;;;
+2F81;KANGXI RADICAL MEAT;So;0;ON;<compat> 8089;;;;N;;;;;
+2F82;KANGXI RADICAL MINISTER;So;0;ON;<compat> 81E3;;;;N;;;;;
+2F83;KANGXI RADICAL SELF;So;0;ON;<compat> 81EA;;;;N;;;;;
+2F84;KANGXI RADICAL ARRIVE;So;0;ON;<compat> 81F3;;;;N;;;;;
+2F85;KANGXI RADICAL MORTAR;So;0;ON;<compat> 81FC;;;;N;;;;;
+2F86;KANGXI RADICAL TONGUE;So;0;ON;<compat> 820C;;;;N;;;;;
+2F87;KANGXI RADICAL OPPOSE;So;0;ON;<compat> 821B;;;;N;;;;;
+2F88;KANGXI RADICAL BOAT;So;0;ON;<compat> 821F;;;;N;;;;;
+2F89;KANGXI RADICAL STOPPING;So;0;ON;<compat> 826E;;;;N;;;;;
+2F8A;KANGXI RADICAL COLOR;So;0;ON;<compat> 8272;;;;N;;;;;
+2F8B;KANGXI RADICAL GRASS;So;0;ON;<compat> 8278;;;;N;;;;;
+2F8C;KANGXI RADICAL TIGER;So;0;ON;<compat> 864D;;;;N;;;;;
+2F8D;KANGXI RADICAL INSECT;So;0;ON;<compat> 866B;;;;N;;;;;
+2F8E;KANGXI RADICAL BLOOD;So;0;ON;<compat> 8840;;;;N;;;;;
+2F8F;KANGXI RADICAL WALK ENCLOSURE;So;0;ON;<compat> 884C;;;;N;;;;;
+2F90;KANGXI RADICAL CLOTHES;So;0;ON;<compat> 8863;;;;N;;;;;
+2F91;KANGXI RADICAL WEST;So;0;ON;<compat> 897E;;;;N;;;;;
+2F92;KANGXI RADICAL SEE;So;0;ON;<compat> 898B;;;;N;;;;;
+2F93;KANGXI RADICAL HORN;So;0;ON;<compat> 89D2;;;;N;;;;;
+2F94;KANGXI RADICAL SPEECH;So;0;ON;<compat> 8A00;;;;N;;;;;
+2F95;KANGXI RADICAL VALLEY;So;0;ON;<compat> 8C37;;;;N;;;;;
+2F96;KANGXI RADICAL BEAN;So;0;ON;<compat> 8C46;;;;N;;;;;
+2F97;KANGXI RADICAL PIG;So;0;ON;<compat> 8C55;;;;N;;;;;
+2F98;KANGXI RADICAL BADGER;So;0;ON;<compat> 8C78;;;;N;;;;;
+2F99;KANGXI RADICAL SHELL;So;0;ON;<compat> 8C9D;;;;N;;;;;
+2F9A;KANGXI RADICAL RED;So;0;ON;<compat> 8D64;;;;N;;;;;
+2F9B;KANGXI RADICAL RUN;So;0;ON;<compat> 8D70;;;;N;;;;;
+2F9C;KANGXI RADICAL FOOT;So;0;ON;<compat> 8DB3;;;;N;;;;;
+2F9D;KANGXI RADICAL BODY;So;0;ON;<compat> 8EAB;;;;N;;;;;
+2F9E;KANGXI RADICAL CART;So;0;ON;<compat> 8ECA;;;;N;;;;;
+2F9F;KANGXI RADICAL BITTER;So;0;ON;<compat> 8F9B;;;;N;;;;;
+2FA0;KANGXI RADICAL MORNING;So;0;ON;<compat> 8FB0;;;;N;;;;;
+2FA1;KANGXI RADICAL WALK;So;0;ON;<compat> 8FB5;;;;N;;;;;
+2FA2;KANGXI RADICAL CITY;So;0;ON;<compat> 9091;;;;N;;;;;
+2FA3;KANGXI RADICAL WINE;So;0;ON;<compat> 9149;;;;N;;;;;
+2FA4;KANGXI RADICAL DISTINGUISH;So;0;ON;<compat> 91C6;;;;N;;;;;
+2FA5;KANGXI RADICAL VILLAGE;So;0;ON;<compat> 91CC;;;;N;;;;;
+2FA6;KANGXI RADICAL GOLD;So;0;ON;<compat> 91D1;;;;N;;;;;
+2FA7;KANGXI RADICAL LONG;So;0;ON;<compat> 9577;;;;N;;;;;
+2FA8;KANGXI RADICAL GATE;So;0;ON;<compat> 9580;;;;N;;;;;
+2FA9;KANGXI RADICAL MOUND;So;0;ON;<compat> 961C;;;;N;;;;;
+2FAA;KANGXI RADICAL SLAVE;So;0;ON;<compat> 96B6;;;;N;;;;;
+2FAB;KANGXI RADICAL SHORT TAILED BIRD;So;0;ON;<compat> 96B9;;;;N;;;;;
+2FAC;KANGXI RADICAL RAIN;So;0;ON;<compat> 96E8;;;;N;;;;;
+2FAD;KANGXI RADICAL BLUE;So;0;ON;<compat> 9751;;;;N;;;;;
+2FAE;KANGXI RADICAL WRONG;So;0;ON;<compat> 975E;;;;N;;;;;
+2FAF;KANGXI RADICAL FACE;So;0;ON;<compat> 9762;;;;N;;;;;
+2FB0;KANGXI RADICAL LEATHER;So;0;ON;<compat> 9769;;;;N;;;;;
+2FB1;KANGXI RADICAL TANNED LEATHER;So;0;ON;<compat> 97CB;;;;N;;;;;
+2FB2;KANGXI RADICAL LEEK;So;0;ON;<compat> 97ED;;;;N;;;;;
+2FB3;KANGXI RADICAL SOUND;So;0;ON;<compat> 97F3;;;;N;;;;;
+2FB4;KANGXI RADICAL LEAF;So;0;ON;<compat> 9801;;;;N;;;;;
+2FB5;KANGXI RADICAL WIND;So;0;ON;<compat> 98A8;;;;N;;;;;
+2FB6;KANGXI RADICAL FLY;So;0;ON;<compat> 98DB;;;;N;;;;;
+2FB7;KANGXI RADICAL EAT;So;0;ON;<compat> 98DF;;;;N;;;;;
+2FB8;KANGXI RADICAL HEAD;So;0;ON;<compat> 9996;;;;N;;;;;
+2FB9;KANGXI RADICAL FRAGRANT;So;0;ON;<compat> 9999;;;;N;;;;;
+2FBA;KANGXI RADICAL HORSE;So;0;ON;<compat> 99AC;;;;N;;;;;
+2FBB;KANGXI RADICAL BONE;So;0;ON;<compat> 9AA8;;;;N;;;;;
+2FBC;KANGXI RADICAL TALL;So;0;ON;<compat> 9AD8;;;;N;;;;;
+2FBD;KANGXI RADICAL HAIR;So;0;ON;<compat> 9ADF;;;;N;;;;;
+2FBE;KANGXI RADICAL FIGHT;So;0;ON;<compat> 9B25;;;;N;;;;;
+2FBF;KANGXI RADICAL SACRIFICIAL WINE;So;0;ON;<compat> 9B2F;;;;N;;;;;
+2FC0;KANGXI RADICAL CAULDRON;So;0;ON;<compat> 9B32;;;;N;;;;;
+2FC1;KANGXI RADICAL GHOST;So;0;ON;<compat> 9B3C;;;;N;;;;;
+2FC2;KANGXI RADICAL FISH;So;0;ON;<compat> 9B5A;;;;N;;;;;
+2FC3;KANGXI RADICAL BIRD;So;0;ON;<compat> 9CE5;;;;N;;;;;
+2FC4;KANGXI RADICAL SALT;So;0;ON;<compat> 9E75;;;;N;;;;;
+2FC5;KANGXI RADICAL DEER;So;0;ON;<compat> 9E7F;;;;N;;;;;
+2FC6;KANGXI RADICAL WHEAT;So;0;ON;<compat> 9EA5;;;;N;;;;;
+2FC7;KANGXI RADICAL HEMP;So;0;ON;<compat> 9EBB;;;;N;;;;;
+2FC8;KANGXI RADICAL YELLOW;So;0;ON;<compat> 9EC3;;;;N;;;;;
+2FC9;KANGXI RADICAL MILLET;So;0;ON;<compat> 9ECD;;;;N;;;;;
+2FCA;KANGXI RADICAL BLACK;So;0;ON;<compat> 9ED1;;;;N;;;;;
+2FCB;KANGXI RADICAL EMBROIDERY;So;0;ON;<compat> 9EF9;;;;N;;;;;
+2FCC;KANGXI RADICAL FROG;So;0;ON;<compat> 9EFD;;;;N;;;;;
+2FCD;KANGXI RADICAL TRIPOD;So;0;ON;<compat> 9F0E;;;;N;;;;;
+2FCE;KANGXI RADICAL DRUM;So;0;ON;<compat> 9F13;;;;N;;;;;
+2FCF;KANGXI RADICAL RAT;So;0;ON;<compat> 9F20;;;;N;;;;;
+2FD0;KANGXI RADICAL NOSE;So;0;ON;<compat> 9F3B;;;;N;;;;;
+2FD1;KANGXI RADICAL EVEN;So;0;ON;<compat> 9F4A;;;;N;;;;;
+2FD2;KANGXI RADICAL TOOTH;So;0;ON;<compat> 9F52;;;;N;;;;;
+2FD3;KANGXI RADICAL DRAGON;So;0;ON;<compat> 9F8D;;;;N;;;;;
+2FD4;KANGXI RADICAL TURTLE;So;0;ON;<compat> 9F9C;;;;N;;;;;
+2FD5;KANGXI RADICAL FLUTE;So;0;ON;<compat> 9FA0;;;;N;;;;;
+2FF0;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT;So;0;ON;;;;;N;;;;;
+2FF1;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW;So;0;ON;;;;;N;;;;;
+2FF2;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT;So;0;ON;;;;;N;;;;;
+2FF3;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW;So;0;ON;;;;;N;;;;;
+2FF4;IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND;So;0;ON;;;;;N;;;;;
+2FF5;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE;So;0;ON;;;;;N;;;;;
+2FF6;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW;So;0;ON;;;;;N;;;;;
+2FF7;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT;So;0;ON;;;;;N;;;;;
+2FF8;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT;So;0;ON;;;;;N;;;;;
+2FF9;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT;So;0;ON;;;;;N;;;;;
+2FFA;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT;So;0;ON;;;;;N;;;;;
+2FFB;IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID;So;0;ON;;;;;N;;;;;
+3000;IDEOGRAPHIC SPACE;Zs;0;WS;<wide> 0020;;;;N;;;;;
+3001;IDEOGRAPHIC COMMA;Po;0;ON;;;;;N;;;;;
+3002;IDEOGRAPHIC FULL STOP;Po;0;ON;;;;;N;IDEOGRAPHIC PERIOD;;;;
+3003;DITTO MARK;Po;0;ON;;;;;N;;;;;
+3004;JAPANESE INDUSTRIAL STANDARD SYMBOL;So;0;ON;;;;;N;;;;;
+3005;IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;;
+3006;IDEOGRAPHIC CLOSING MARK;Lo;0;L;;;;;N;;;;;
+3007;IDEOGRAPHIC NUMBER ZERO;Nl;0;L;;;;0;N;;;;;
+3008;LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING ANGLE BRACKET;;;;
+3009;RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING ANGLE BRACKET;;;;
+300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING DOUBLE ANGLE BRACKET;;;;
+300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING DOUBLE ANGLE BRACKET;;;;
+300C;LEFT CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING CORNER BRACKET;;;;
+300D;RIGHT CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING CORNER BRACKET;;;;
+300E;LEFT WHITE CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE CORNER BRACKET;;;;
+300F;RIGHT WHITE CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE CORNER BRACKET;;;;
+3010;LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING BLACK LENTICULAR BRACKET;;;;
+3011;RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING BLACK LENTICULAR BRACKET;;;;
+3012;POSTAL MARK;So;0;ON;;;;;N;;;;;
+3013;GETA MARK;So;0;ON;;;;;N;;;;;
+3014;LEFT TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING TORTOISE SHELL BRACKET;;;;
+3015;RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING TORTOISE SHELL BRACKET;;;;
+3016;LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE LENTICULAR BRACKET;;;;
+3017;RIGHT WHITE LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE LENTICULAR BRACKET;;;;
+3018;LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE TORTOISE SHELL BRACKET;;;;
+3019;RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE TORTOISE SHELL BRACKET;;;;
+301A;LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE SQUARE BRACKET;;;;
+301B;RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE SQUARE BRACKET;;;;
+301C;WAVE DASH;Pd;0;ON;;;;;N;;;;;
+301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps;0;ON;;;;;N;;;;;
+301E;DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;;
+301F;LOW DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;;
+3020;POSTAL MARK FACE;So;0;ON;;;;;N;;;;;
+3021;HANGZHOU NUMERAL ONE;Nl;0;L;;;;1;N;;;;;
+3022;HANGZHOU NUMERAL TWO;Nl;0;L;;;;2;N;;;;;
+3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;;
+3024;HANGZHOU NUMERAL FOUR;Nl;0;L;;;;4;N;;;;;
+3025;HANGZHOU NUMERAL FIVE;Nl;0;L;;;;5;N;;;;;
+3026;HANGZHOU NUMERAL SIX;Nl;0;L;;;;6;N;;;;;
+3027;HANGZHOU NUMERAL SEVEN;Nl;0;L;;;;7;N;;;;;
+3028;HANGZHOU NUMERAL EIGHT;Nl;0;L;;;;8;N;;;;;
+3029;HANGZHOU NUMERAL NINE;Nl;0;L;;;;9;N;;;;;
+302A;IDEOGRAPHIC LEVEL TONE MARK;Mn;218;NSM;;;;;N;;;;;
+302B;IDEOGRAPHIC RISING TONE MARK;Mn;228;NSM;;;;;N;;;;;
+302C;IDEOGRAPHIC DEPARTING TONE MARK;Mn;232;NSM;;;;;N;;;;;
+302D;IDEOGRAPHIC ENTERING TONE MARK;Mn;222;NSM;;;;;N;;;;;
+302E;HANGUL SINGLE DOT TONE MARK;Mc;224;L;;;;;N;;;;;
+302F;HANGUL DOUBLE DOT TONE MARK;Mc;224;L;;;;;N;;;;;
+3030;WAVY DASH;Pd;0;ON;;;;;N;;;;;
+3031;VERTICAL KANA REPEAT MARK;Lm;0;L;;;;;N;;;;;
+3032;VERTICAL KANA REPEAT WITH VOICED SOUND MARK;Lm;0;L;;;;;N;;;;;
+3033;VERTICAL KANA REPEAT MARK UPPER HALF;Lm;0;L;;;;;N;;;;;
+3034;VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF;Lm;0;L;;;;;N;;;;;
+3035;VERTICAL KANA REPEAT MARK LOWER HALF;Lm;0;L;;;;;N;;;;;
+3036;CIRCLED POSTAL MARK;So;0;ON;<compat> 3012;;;;N;;;;;
+3037;IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL;So;0;ON;;;;;N;;;;;
+3038;HANGZHOU NUMERAL TEN;Nl;0;L;<compat> 5341;;;10;N;;;;;
+3039;HANGZHOU NUMERAL TWENTY;Nl;0;L;<compat> 5344;;;20;N;;;;;
+303A;HANGZHOU NUMERAL THIRTY;Nl;0;L;<compat> 5345;;;30;N;;;;;
+303B;VERTICAL IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;;
+303C;MASU MARK;Lo;0;L;;;;;N;;;;;
+303D;PART ALTERNATION MARK;Po;0;ON;;;;;N;;;;;
+303E;IDEOGRAPHIC VARIATION INDICATOR;So;0;ON;;;;;N;;;;;
+303F;IDEOGRAPHIC HALF FILL SPACE;So;0;ON;;;;;N;;;;;
+3041;HIRAGANA LETTER SMALL A;Lo;0;L;;;;;N;;;;;
+3042;HIRAGANA LETTER A;Lo;0;L;;;;;N;;;;;
+3043;HIRAGANA LETTER SMALL I;Lo;0;L;;;;;N;;;;;
+3044;HIRAGANA LETTER I;Lo;0;L;;;;;N;;;;;
+3045;HIRAGANA LETTER SMALL U;Lo;0;L;;;;;N;;;;;
+3046;HIRAGANA LETTER U;Lo;0;L;;;;;N;;;;;
+3047;HIRAGANA LETTER SMALL E;Lo;0;L;;;;;N;;;;;
+3048;HIRAGANA LETTER E;Lo;0;L;;;;;N;;;;;
+3049;HIRAGANA LETTER SMALL O;Lo;0;L;;;;;N;;;;;
+304A;HIRAGANA LETTER O;Lo;0;L;;;;;N;;;;;
+304B;HIRAGANA LETTER KA;Lo;0;L;;;;;N;;;;;
+304C;HIRAGANA LETTER GA;Lo;0;L;304B 3099;;;;N;;;;;
+304D;HIRAGANA LETTER KI;Lo;0;L;;;;;N;;;;;
+304E;HIRAGANA LETTER GI;Lo;0;L;304D 3099;;;;N;;;;;
+304F;HIRAGANA LETTER KU;Lo;0;L;;;;;N;;;;;
+3050;HIRAGANA LETTER GU;Lo;0;L;304F 3099;;;;N;;;;;
+3051;HIRAGANA LETTER KE;Lo;0;L;;;;;N;;;;;
+3052;HIRAGANA LETTER GE;Lo;0;L;3051 3099;;;;N;;;;;
+3053;HIRAGANA LETTER KO;Lo;0;L;;;;;N;;;;;
+3054;HIRAGANA LETTER GO;Lo;0;L;3053 3099;;;;N;;;;;
+3055;HIRAGANA LETTER SA;Lo;0;L;;;;;N;;;;;
+3056;HIRAGANA LETTER ZA;Lo;0;L;3055 3099;;;;N;;;;;
+3057;HIRAGANA LETTER SI;Lo;0;L;;;;;N;;;;;
+3058;HIRAGANA LETTER ZI;Lo;0;L;3057 3099;;;;N;;;;;
+3059;HIRAGANA LETTER SU;Lo;0;L;;;;;N;;;;;
+305A;HIRAGANA LETTER ZU;Lo;0;L;3059 3099;;;;N;;;;;
+305B;HIRAGANA LETTER SE;Lo;0;L;;;;;N;;;;;
+305C;HIRAGANA LETTER ZE;Lo;0;L;305B 3099;;;;N;;;;;
+305D;HIRAGANA LETTER SO;Lo;0;L;;;;;N;;;;;
+305E;HIRAGANA LETTER ZO;Lo;0;L;305D 3099;;;;N;;;;;
+305F;HIRAGANA LETTER TA;Lo;0;L;;;;;N;;;;;
+3060;HIRAGANA LETTER DA;Lo;0;L;305F 3099;;;;N;;;;;
+3061;HIRAGANA LETTER TI;Lo;0;L;;;;;N;;;;;
+3062;HIRAGANA LETTER DI;Lo;0;L;3061 3099;;;;N;;;;;
+3063;HIRAGANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;;
+3064;HIRAGANA LETTER TU;Lo;0;L;;;;;N;;;;;
+3065;HIRAGANA LETTER DU;Lo;0;L;3064 3099;;;;N;;;;;
+3066;HIRAGANA LETTER TE;Lo;0;L;;;;;N;;;;;
+3067;HIRAGANA LETTER DE;Lo;0;L;3066 3099;;;;N;;;;;
+3068;HIRAGANA LETTER TO;Lo;0;L;;;;;N;;;;;
+3069;HIRAGANA LETTER DO;Lo;0;L;3068 3099;;;;N;;;;;
+306A;HIRAGANA LETTER NA;Lo;0;L;;;;;N;;;;;
+306B;HIRAGANA LETTER NI;Lo;0;L;;;;;N;;;;;
+306C;HIRAGANA LETTER NU;Lo;0;L;;;;;N;;;;;
+306D;HIRAGANA LETTER NE;Lo;0;L;;;;;N;;;;;
+306E;HIRAGANA LETTER NO;Lo;0;L;;;;;N;;;;;
+306F;HIRAGANA LETTER HA;Lo;0;L;;;;;N;;;;;
+3070;HIRAGANA LETTER BA;Lo;0;L;306F 3099;;;;N;;;;;
+3071;HIRAGANA LETTER PA;Lo;0;L;306F 309A;;;;N;;;;;
+3072;HIRAGANA LETTER HI;Lo;0;L;;;;;N;;;;;
+3073;HIRAGANA LETTER BI;Lo;0;L;3072 3099;;;;N;;;;;
+3074;HIRAGANA LETTER PI;Lo;0;L;3072 309A;;;;N;;;;;
+3075;HIRAGANA LETTER HU;Lo;0;L;;;;;N;;;;;
+3076;HIRAGANA LETTER BU;Lo;0;L;3075 3099;;;;N;;;;;
+3077;HIRAGANA LETTER PU;Lo;0;L;3075 309A;;;;N;;;;;
+3078;HIRAGANA LETTER HE;Lo;0;L;;;;;N;;;;;
+3079;HIRAGANA LETTER BE;Lo;0;L;3078 3099;;;;N;;;;;
+307A;HIRAGANA LETTER PE;Lo;0;L;3078 309A;;;;N;;;;;
+307B;HIRAGANA LETTER HO;Lo;0;L;;;;;N;;;;;
+307C;HIRAGANA LETTER BO;Lo;0;L;307B 3099;;;;N;;;;;
+307D;HIRAGANA LETTER PO;Lo;0;L;307B 309A;;;;N;;;;;
+307E;HIRAGANA LETTER MA;Lo;0;L;;;;;N;;;;;
+307F;HIRAGANA LETTER MI;Lo;0;L;;;;;N;;;;;
+3080;HIRAGANA LETTER MU;Lo;0;L;;;;;N;;;;;
+3081;HIRAGANA LETTER ME;Lo;0;L;;;;;N;;;;;
+3082;HIRAGANA LETTER MO;Lo;0;L;;;;;N;;;;;
+3083;HIRAGANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;;
+3084;HIRAGANA LETTER YA;Lo;0;L;;;;;N;;;;;
+3085;HIRAGANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;;
+3086;HIRAGANA LETTER YU;Lo;0;L;;;;;N;;;;;
+3087;HIRAGANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;;
+3088;HIRAGANA LETTER YO;Lo;0;L;;;;;N;;;;;
+3089;HIRAGANA LETTER RA;Lo;0;L;;;;;N;;;;;
+308A;HIRAGANA LETTER RI;Lo;0;L;;;;;N;;;;;
+308B;HIRAGANA LETTER RU;Lo;0;L;;;;;N;;;;;
+308C;HIRAGANA LETTER RE;Lo;0;L;;;;;N;;;;;
+308D;HIRAGANA LETTER RO;Lo;0;L;;;;;N;;;;;
+308E;HIRAGANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;;
+308F;HIRAGANA LETTER WA;Lo;0;L;;;;;N;;;;;
+3090;HIRAGANA LETTER WI;Lo;0;L;;;;;N;;;;;
+3091;HIRAGANA LETTER WE;Lo;0;L;;;;;N;;;;;
+3092;HIRAGANA LETTER WO;Lo;0;L;;;;;N;;;;;
+3093;HIRAGANA LETTER N;Lo;0;L;;;;;N;;;;;
+3094;HIRAGANA LETTER VU;Lo;0;L;3046 3099;;;;N;;;;;
+3095;HIRAGANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;;
+3096;HIRAGANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;;
+3099;COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA VOICED SOUND MARK;;;;
+309A;COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;;;;
+309B;KATAKANA-HIRAGANA VOICED SOUND MARK;Sk;0;ON;<compat> 0020 3099;;;;N;;;;;
+309C;KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Sk;0;ON;<compat> 0020 309A;;;;N;;;;;
+309D;HIRAGANA ITERATION MARK;Lm;0;L;;;;;N;;;;;
+309E;HIRAGANA VOICED ITERATION MARK;Lm;0;L;309D 3099;;;;N;;;;;
+309F;HIRAGANA DIGRAPH YORI;Lo;0;L;<vertical> 3088 308A;;;;N;;;;;
+30A0;KATAKANA-HIRAGANA DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;;
+30A1;KATAKANA LETTER SMALL A;Lo;0;L;;;;;N;;;;;
+30A2;KATAKANA LETTER A;Lo;0;L;;;;;N;;;;;
+30A3;KATAKANA LETTER SMALL I;Lo;0;L;;;;;N;;;;;
+30A4;KATAKANA LETTER I;Lo;0;L;;;;;N;;;;;
+30A5;KATAKANA LETTER SMALL U;Lo;0;L;;;;;N;;;;;
+30A6;KATAKANA LETTER U;Lo;0;L;;;;;N;;;;;
+30A7;KATAKANA LETTER SMALL E;Lo;0;L;;;;;N;;;;;
+30A8;KATAKANA LETTER E;Lo;0;L;;;;;N;;;;;
+30A9;KATAKANA LETTER SMALL O;Lo;0;L;;;;;N;;;;;
+30AA;KATAKANA LETTER O;Lo;0;L;;;;;N;;;;;
+30AB;KATAKANA LETTER KA;Lo;0;L;;;;;N;;;;;
+30AC;KATAKANA LETTER GA;Lo;0;L;30AB 3099;;;;N;;;;;
+30AD;KATAKANA LETTER KI;Lo;0;L;;;;;N;;;;;
+30AE;KATAKANA LETTER GI;Lo;0;L;30AD 3099;;;;N;;;;;
+30AF;KATAKANA LETTER KU;Lo;0;L;;;;;N;;;;;
+30B0;KATAKANA LETTER GU;Lo;0;L;30AF 3099;;;;N;;;;;
+30B1;KATAKANA LETTER KE;Lo;0;L;;;;;N;;;;;
+30B2;KATAKANA LETTER GE;Lo;0;L;30B1 3099;;;;N;;;;;
+30B3;KATAKANA LETTER KO;Lo;0;L;;;;;N;;;;;
+30B4;KATAKANA LETTER GO;Lo;0;L;30B3 3099;;;;N;;;;;
+30B5;KATAKANA LETTER SA;Lo;0;L;;;;;N;;;;;
+30B6;KATAKANA LETTER ZA;Lo;0;L;30B5 3099;;;;N;;;;;
+30B7;KATAKANA LETTER SI;Lo;0;L;;;;;N;;;;;
+30B8;KATAKANA LETTER ZI;Lo;0;L;30B7 3099;;;;N;;;;;
+30B9;KATAKANA LETTER SU;Lo;0;L;;;;;N;;;;;
+30BA;KATAKANA LETTER ZU;Lo;0;L;30B9 3099;;;;N;;;;;
+30BB;KATAKANA LETTER SE;Lo;0;L;;;;;N;;;;;
+30BC;KATAKANA LETTER ZE;Lo;0;L;30BB 3099;;;;N;;;;;
+30BD;KATAKANA LETTER SO;Lo;0;L;;;;;N;;;;;
+30BE;KATAKANA LETTER ZO;Lo;0;L;30BD 3099;;;;N;;;;;
+30BF;KATAKANA LETTER TA;Lo;0;L;;;;;N;;;;;
+30C0;KATAKANA LETTER DA;Lo;0;L;30BF 3099;;;;N;;;;;
+30C1;KATAKANA LETTER TI;Lo;0;L;;;;;N;;;;;
+30C2;KATAKANA LETTER DI;Lo;0;L;30C1 3099;;;;N;;;;;
+30C3;KATAKANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;;
+30C4;KATAKANA LETTER TU;Lo;0;L;;;;;N;;;;;
+30C5;KATAKANA LETTER DU;Lo;0;L;30C4 3099;;;;N;;;;;
+30C6;KATAKANA LETTER TE;Lo;0;L;;;;;N;;;;;
+30C7;KATAKANA LETTER DE;Lo;0;L;30C6 3099;;;;N;;;;;
+30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;;
+30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;;
+30CA;KATAKANA LETTER NA;Lo;0;L;;;;;N;;;;;
+30CB;KATAKANA LETTER NI;Lo;0;L;;;;;N;;;;;
+30CC;KATAKANA LETTER NU;Lo;0;L;;;;;N;;;;;
+30CD;KATAKANA LETTER NE;Lo;0;L;;;;;N;;;;;
+30CE;KATAKANA LETTER NO;Lo;0;L;;;;;N;;;;;
+30CF;KATAKANA LETTER HA;Lo;0;L;;;;;N;;;;;
+30D0;KATAKANA LETTER BA;Lo;0;L;30CF 3099;;;;N;;;;;
+30D1;KATAKANA LETTER PA;Lo;0;L;30CF 309A;;;;N;;;;;
+30D2;KATAKANA LETTER HI;Lo;0;L;;;;;N;;;;;
+30D3;KATAKANA LETTER BI;Lo;0;L;30D2 3099;;;;N;;;;;
+30D4;KATAKANA LETTER PI;Lo;0;L;30D2 309A;;;;N;;;;;
+30D5;KATAKANA LETTER HU;Lo;0;L;;;;;N;;;;;
+30D6;KATAKANA LETTER BU;Lo;0;L;30D5 3099;;;;N;;;;;
+30D7;KATAKANA LETTER PU;Lo;0;L;30D5 309A;;;;N;;;;;
+30D8;KATAKANA LETTER HE;Lo;0;L;;;;;N;;;;;
+30D9;KATAKANA LETTER BE;Lo;0;L;30D8 3099;;;;N;;;;;
+30DA;KATAKANA LETTER PE;Lo;0;L;30D8 309A;;;;N;;;;;
+30DB;KATAKANA LETTER HO;Lo;0;L;;;;;N;;;;;
+30DC;KATAKANA LETTER BO;Lo;0;L;30DB 3099;;;;N;;;;;
+30DD;KATAKANA LETTER PO;Lo;0;L;30DB 309A;;;;N;;;;;
+30DE;KATAKANA LETTER MA;Lo;0;L;;;;;N;;;;;
+30DF;KATAKANA LETTER MI;Lo;0;L;;;;;N;;;;;
+30E0;KATAKANA LETTER MU;Lo;0;L;;;;;N;;;;;
+30E1;KATAKANA LETTER ME;Lo;0;L;;;;;N;;;;;
+30E2;KATAKANA LETTER MO;Lo;0;L;;;;;N;;;;;
+30E3;KATAKANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;;
+30E4;KATAKANA LETTER YA;Lo;0;L;;;;;N;;;;;
+30E5;KATAKANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;;
+30E6;KATAKANA LETTER YU;Lo;0;L;;;;;N;;;;;
+30E7;KATAKANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;;
+30E8;KATAKANA LETTER YO;Lo;0;L;;;;;N;;;;;
+30E9;KATAKANA LETTER RA;Lo;0;L;;;;;N;;;;;
+30EA;KATAKANA LETTER RI;Lo;0;L;;;;;N;;;;;
+30EB;KATAKANA LETTER RU;Lo;0;L;;;;;N;;;;;
+30EC;KATAKANA LETTER RE;Lo;0;L;;;;;N;;;;;
+30ED;KATAKANA LETTER RO;Lo;0;L;;;;;N;;;;;
+30EE;KATAKANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;;
+30EF;KATAKANA LETTER WA;Lo;0;L;;;;;N;;;;;
+30F0;KATAKANA LETTER WI;Lo;0;L;;;;;N;;;;;
+30F1;KATAKANA LETTER WE;Lo;0;L;;;;;N;;;;;
+30F2;KATAKANA LETTER WO;Lo;0;L;;;;;N;;;;;
+30F3;KATAKANA LETTER N;Lo;0;L;;;;;N;;;;;
+30F4;KATAKANA LETTER VU;Lo;0;L;30A6 3099;;;;N;;;;;
+30F5;KATAKANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;;
+30F6;KATAKANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;;
+30F7;KATAKANA LETTER VA;Lo;0;L;30EF 3099;;;;N;;;;;
+30F8;KATAKANA LETTER VI;Lo;0;L;30F0 3099;;;;N;;;;;
+30F9;KATAKANA LETTER VE;Lo;0;L;30F1 3099;;;;N;;;;;
+30FA;KATAKANA LETTER VO;Lo;0;L;30F2 3099;;;;N;;;;;
+30FB;KATAKANA MIDDLE DOT;Po;0;ON;;;;;N;;;;;
+30FC;KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;;;;;N;;;;;
+30FD;KATAKANA ITERATION MARK;Lm;0;L;;;;;N;;;;;
+30FE;KATAKANA VOICED ITERATION MARK;Lm;0;L;30FD 3099;;;;N;;;;;
+30FF;KATAKANA DIGRAPH KOTO;Lo;0;L;<vertical> 30B3 30C8;;;;N;;;;;
+3105;BOPOMOFO LETTER B;Lo;0;L;;;;;N;;;;;
+3106;BOPOMOFO LETTER P;Lo;0;L;;;;;N;;;;;
+3107;BOPOMOFO LETTER M;Lo;0;L;;;;;N;;;;;
+3108;BOPOMOFO LETTER F;Lo;0;L;;;;;N;;;;;
+3109;BOPOMOFO LETTER D;Lo;0;L;;;;;N;;;;;
+310A;BOPOMOFO LETTER T;Lo;0;L;;;;;N;;;;;
+310B;BOPOMOFO LETTER N;Lo;0;L;;;;;N;;;;;
+310C;BOPOMOFO LETTER L;Lo;0;L;;;;;N;;;;;
+310D;BOPOMOFO LETTER G;Lo;0;L;;;;;N;;;;;
+310E;BOPOMOFO LETTER K;Lo;0;L;;;;;N;;;;;
+310F;BOPOMOFO LETTER H;Lo;0;L;;;;;N;;;;;
+3110;BOPOMOFO LETTER J;Lo;0;L;;;;;N;;;;;
+3111;BOPOMOFO LETTER Q;Lo;0;L;;;;;N;;;;;
+3112;BOPOMOFO LETTER X;Lo;0;L;;;;;N;;;;;
+3113;BOPOMOFO LETTER ZH;Lo;0;L;;;;;N;;;;;
+3114;BOPOMOFO LETTER CH;Lo;0;L;;;;;N;;;;;
+3115;BOPOMOFO LETTER SH;Lo;0;L;;;;;N;;;;;
+3116;BOPOMOFO LETTER R;Lo;0;L;;;;;N;;;;;
+3117;BOPOMOFO LETTER Z;Lo;0;L;;;;;N;;;;;
+3118;BOPOMOFO LETTER C;Lo;0;L;;;;;N;;;;;
+3119;BOPOMOFO LETTER S;Lo;0;L;;;;;N;;;;;
+311A;BOPOMOFO LETTER A;Lo;0;L;;;;;N;;;;;
+311B;BOPOMOFO LETTER O;Lo;0;L;;;;;N;;;;;
+311C;BOPOMOFO LETTER E;Lo;0;L;;;;;N;;;;;
+311D;BOPOMOFO LETTER EH;Lo;0;L;;;;;N;;;;;
+311E;BOPOMOFO LETTER AI;Lo;0;L;;;;;N;;;;;
+311F;BOPOMOFO LETTER EI;Lo;0;L;;;;;N;;;;;
+3120;BOPOMOFO LETTER AU;Lo;0;L;;;;;N;;;;;
+3121;BOPOMOFO LETTER OU;Lo;0;L;;;;;N;;;;;
+3122;BOPOMOFO LETTER AN;Lo;0;L;;;;;N;;;;;
+3123;BOPOMOFO LETTER EN;Lo;0;L;;;;;N;;;;;
+3124;BOPOMOFO LETTER ANG;Lo;0;L;;;;;N;;;;;
+3125;BOPOMOFO LETTER ENG;Lo;0;L;;;;;N;;;;;
+3126;BOPOMOFO LETTER ER;Lo;0;L;;;;;N;;;;;
+3127;BOPOMOFO LETTER I;Lo;0;L;;;;;N;;;;;
+3128;BOPOMOFO LETTER U;Lo;0;L;;;;;N;;;;;
+3129;BOPOMOFO LETTER IU;Lo;0;L;;;;;N;;;;;
+312A;BOPOMOFO LETTER V;Lo;0;L;;;;;N;;;;;
+312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;;
+312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;;
+312D;BOPOMOFO LETTER IH;Lo;0;L;;;;;N;;;;;
+3131;HANGUL LETTER KIYEOK;Lo;0;L;<compat> 1100;;;;N;HANGUL LETTER GIYEOG;;;;
+3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L;<compat> 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;;
+3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<compat> 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;;
+3134;HANGUL LETTER NIEUN;Lo;0;L;<compat> 1102;;;;N;;;;;
+3135;HANGUL LETTER NIEUN-CIEUC;Lo;0;L;<compat> 11AC;;;;N;HANGUL LETTER NIEUN JIEUJ;;;;
+3136;HANGUL LETTER NIEUN-HIEUH;Lo;0;L;<compat> 11AD;;;;N;HANGUL LETTER NIEUN HIEUH;;;;
+3137;HANGUL LETTER TIKEUT;Lo;0;L;<compat> 1103;;;;N;HANGUL LETTER DIGEUD;;;;
+3138;HANGUL LETTER SSANGTIKEUT;Lo;0;L;<compat> 1104;;;;N;HANGUL LETTER SSANG DIGEUD;;;;
+3139;HANGUL LETTER RIEUL;Lo;0;L;<compat> 1105;;;;N;HANGUL LETTER LIEUL;;;;
+313A;HANGUL LETTER RIEUL-KIYEOK;Lo;0;L;<compat> 11B0;;;;N;HANGUL LETTER LIEUL GIYEOG;;;;
+313B;HANGUL LETTER RIEUL-MIEUM;Lo;0;L;<compat> 11B1;;;;N;HANGUL LETTER LIEUL MIEUM;;;;
+313C;HANGUL LETTER RIEUL-PIEUP;Lo;0;L;<compat> 11B2;;;;N;HANGUL LETTER LIEUL BIEUB;;;;
+313D;HANGUL LETTER RIEUL-SIOS;Lo;0;L;<compat> 11B3;;;;N;HANGUL LETTER LIEUL SIOS;;;;
+313E;HANGUL LETTER RIEUL-THIEUTH;Lo;0;L;<compat> 11B4;;;;N;HANGUL LETTER LIEUL TIEUT;;;;
+313F;HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L;<compat> 11B5;;;;N;HANGUL LETTER LIEUL PIEUP;;;;
+3140;HANGUL LETTER RIEUL-HIEUH;Lo;0;L;<compat> 111A;;;;N;HANGUL LETTER LIEUL HIEUH;;;;
+3141;HANGUL LETTER MIEUM;Lo;0;L;<compat> 1106;;;;N;;;;;
+3142;HANGUL LETTER PIEUP;Lo;0;L;<compat> 1107;;;;N;HANGUL LETTER BIEUB;;;;
+3143;HANGUL LETTER SSANGPIEUP;Lo;0;L;<compat> 1108;;;;N;HANGUL LETTER SSANG BIEUB;;;;
+3144;HANGUL LETTER PIEUP-SIOS;Lo;0;L;<compat> 1121;;;;N;HANGUL LETTER BIEUB SIOS;;;;
+3145;HANGUL LETTER SIOS;Lo;0;L;<compat> 1109;;;;N;;;;;
+3146;HANGUL LETTER SSANGSIOS;Lo;0;L;<compat> 110A;;;;N;HANGUL LETTER SSANG SIOS;;;;
+3147;HANGUL LETTER IEUNG;Lo;0;L;<compat> 110B;;;;N;;;;;
+3148;HANGUL LETTER CIEUC;Lo;0;L;<compat> 110C;;;;N;HANGUL LETTER JIEUJ;;;;
+3149;HANGUL LETTER SSANGCIEUC;Lo;0;L;<compat> 110D;;;;N;HANGUL LETTER SSANG JIEUJ;;;;
+314A;HANGUL LETTER CHIEUCH;Lo;0;L;<compat> 110E;;;;N;HANGUL LETTER CIEUC;;;;
+314B;HANGUL LETTER KHIEUKH;Lo;0;L;<compat> 110F;;;;N;HANGUL LETTER KIYEOK;;;;
+314C;HANGUL LETTER THIEUTH;Lo;0;L;<compat> 1110;;;;N;HANGUL LETTER TIEUT;;;;
+314D;HANGUL LETTER PHIEUPH;Lo;0;L;<compat> 1111;;;;N;HANGUL LETTER PIEUP;;;;
+314E;HANGUL LETTER HIEUH;Lo;0;L;<compat> 1112;;;;N;;;;;
+314F;HANGUL LETTER A;Lo;0;L;<compat> 1161;;;;N;;;;;
+3150;HANGUL LETTER AE;Lo;0;L;<compat> 1162;;;;N;;;;;
+3151;HANGUL LETTER YA;Lo;0;L;<compat> 1163;;;;N;;;;;
+3152;HANGUL LETTER YAE;Lo;0;L;<compat> 1164;;;;N;;;;;
+3153;HANGUL LETTER EO;Lo;0;L;<compat> 1165;;;;N;;;;;
+3154;HANGUL LETTER E;Lo;0;L;<compat> 1166;;;;N;;;;;
+3155;HANGUL LETTER YEO;Lo;0;L;<compat> 1167;;;;N;;;;;
+3156;HANGUL LETTER YE;Lo;0;L;<compat> 1168;;;;N;;;;;
+3157;HANGUL LETTER O;Lo;0;L;<compat> 1169;;;;N;;;;;
+3158;HANGUL LETTER WA;Lo;0;L;<compat> 116A;;;;N;;;;;
+3159;HANGUL LETTER WAE;Lo;0;L;<compat> 116B;;;;N;;;;;
+315A;HANGUL LETTER OE;Lo;0;L;<compat> 116C;;;;N;;;;;
+315B;HANGUL LETTER YO;Lo;0;L;<compat> 116D;;;;N;;;;;
+315C;HANGUL LETTER U;Lo;0;L;<compat> 116E;;;;N;;;;;
+315D;HANGUL LETTER WEO;Lo;0;L;<compat> 116F;;;;N;;;;;
+315E;HANGUL LETTER WE;Lo;0;L;<compat> 1170;;;;N;;;;;
+315F;HANGUL LETTER WI;Lo;0;L;<compat> 1171;;;;N;;;;;
+3160;HANGUL LETTER YU;Lo;0;L;<compat> 1172;;;;N;;;;;
+3161;HANGUL LETTER EU;Lo;0;L;<compat> 1173;;;;N;;;;;
+3162;HANGUL LETTER YI;Lo;0;L;<compat> 1174;;;;N;;;;;
+3163;HANGUL LETTER I;Lo;0;L;<compat> 1175;;;;N;;;;;
+3164;HANGUL FILLER;Lo;0;L;<compat> 1160;;;;N;HANGUL CAE OM;;;;
+3165;HANGUL LETTER SSANGNIEUN;Lo;0;L;<compat> 1114;;;;N;HANGUL LETTER SSANG NIEUN;;;;
+3166;HANGUL LETTER NIEUN-TIKEUT;Lo;0;L;<compat> 1115;;;;N;HANGUL LETTER NIEUN DIGEUD;;;;
+3167;HANGUL LETTER NIEUN-SIOS;Lo;0;L;<compat> 11C7;;;;N;HANGUL LETTER NIEUN SIOS;;;;
+3168;HANGUL LETTER NIEUN-PANSIOS;Lo;0;L;<compat> 11C8;;;;N;HANGUL LETTER NIEUN BAN CHI EUM;;;;
+3169;HANGUL LETTER RIEUL-KIYEOK-SIOS;Lo;0;L;<compat> 11CC;;;;N;HANGUL LETTER LIEUL GIYEOG SIOS;;;;
+316A;HANGUL LETTER RIEUL-TIKEUT;Lo;0;L;<compat> 11CE;;;;N;HANGUL LETTER LIEUL DIGEUD;;;;
+316B;HANGUL LETTER RIEUL-PIEUP-SIOS;Lo;0;L;<compat> 11D3;;;;N;HANGUL LETTER LIEUL BIEUB SIOS;;;;
+316C;HANGUL LETTER RIEUL-PANSIOS;Lo;0;L;<compat> 11D7;;;;N;HANGUL LETTER LIEUL BAN CHI EUM;;;;
+316D;HANGUL LETTER RIEUL-YEORINHIEUH;Lo;0;L;<compat> 11D9;;;;N;HANGUL LETTER LIEUL YEOLIN HIEUH;;;;
+316E;HANGUL LETTER MIEUM-PIEUP;Lo;0;L;<compat> 111C;;;;N;HANGUL LETTER MIEUM BIEUB;;;;
+316F;HANGUL LETTER MIEUM-SIOS;Lo;0;L;<compat> 11DD;;;;N;HANGUL LETTER MIEUM SIOS;;;;
+3170;HANGUL LETTER MIEUM-PANSIOS;Lo;0;L;<compat> 11DF;;;;N;HANGUL LETTER BIEUB BAN CHI EUM;;;;
+3171;HANGUL LETTER KAPYEOUNMIEUM;Lo;0;L;<compat> 111D;;;;N;HANGUL LETTER MIEUM SUN GYEONG EUM;;;;
+3172;HANGUL LETTER PIEUP-KIYEOK;Lo;0;L;<compat> 111E;;;;N;HANGUL LETTER BIEUB GIYEOG;;;;
+3173;HANGUL LETTER PIEUP-TIKEUT;Lo;0;L;<compat> 1120;;;;N;HANGUL LETTER BIEUB DIGEUD;;;;
+3174;HANGUL LETTER PIEUP-SIOS-KIYEOK;Lo;0;L;<compat> 1122;;;;N;HANGUL LETTER BIEUB SIOS GIYEOG;;;;
+3175;HANGUL LETTER PIEUP-SIOS-TIKEUT;Lo;0;L;<compat> 1123;;;;N;HANGUL LETTER BIEUB SIOS DIGEUD;;;;
+3176;HANGUL LETTER PIEUP-CIEUC;Lo;0;L;<compat> 1127;;;;N;HANGUL LETTER BIEUB JIEUJ;;;;
+3177;HANGUL LETTER PIEUP-THIEUTH;Lo;0;L;<compat> 1129;;;;N;HANGUL LETTER BIEUB TIEUT;;;;
+3178;HANGUL LETTER KAPYEOUNPIEUP;Lo;0;L;<compat> 112B;;;;N;HANGUL LETTER BIEUB SUN GYEONG EUM;;;;
+3179;HANGUL LETTER KAPYEOUNSSANGPIEUP;Lo;0;L;<compat> 112C;;;;N;HANGUL LETTER SSANG BIEUB SUN GYEONG EUM;;;;
+317A;HANGUL LETTER SIOS-KIYEOK;Lo;0;L;<compat> 112D;;;;N;HANGUL LETTER SIOS GIYEOG;;;;
+317B;HANGUL LETTER SIOS-NIEUN;Lo;0;L;<compat> 112E;;;;N;HANGUL LETTER SIOS NIEUN;;;;
+317C;HANGUL LETTER SIOS-TIKEUT;Lo;0;L;<compat> 112F;;;;N;HANGUL LETTER SIOS DIGEUD;;;;
+317D;HANGUL LETTER SIOS-PIEUP;Lo;0;L;<compat> 1132;;;;N;HANGUL LETTER SIOS BIEUB;;;;
+317E;HANGUL LETTER SIOS-CIEUC;Lo;0;L;<compat> 1136;;;;N;HANGUL LETTER SIOS JIEUJ;;;;
+317F;HANGUL LETTER PANSIOS;Lo;0;L;<compat> 1140;;;;N;HANGUL LETTER BAN CHI EUM;;;;
+3180;HANGUL LETTER SSANGIEUNG;Lo;0;L;<compat> 1147;;;;N;HANGUL LETTER SSANG IEUNG;;;;
+3181;HANGUL LETTER YESIEUNG;Lo;0;L;<compat> 114C;;;;N;HANGUL LETTER NGIEUNG;;;;
+3182;HANGUL LETTER YESIEUNG-SIOS;Lo;0;L;<compat> 11F1;;;;N;HANGUL LETTER NGIEUNG SIOS;;;;
+3183;HANGUL LETTER YESIEUNG-PANSIOS;Lo;0;L;<compat> 11F2;;;;N;HANGUL LETTER NGIEUNG BAN CHI EUM;;;;
+3184;HANGUL LETTER KAPYEOUNPHIEUPH;Lo;0;L;<compat> 1157;;;;N;HANGUL LETTER PIEUP SUN GYEONG EUM;;;;
+3185;HANGUL LETTER SSANGHIEUH;Lo;0;L;<compat> 1158;;;;N;HANGUL LETTER SSANG HIEUH;;;;
+3186;HANGUL LETTER YEORINHIEUH;Lo;0;L;<compat> 1159;;;;N;HANGUL LETTER YEOLIN HIEUH;;;;
+3187;HANGUL LETTER YO-YA;Lo;0;L;<compat> 1184;;;;N;HANGUL LETTER YOYA;;;;
+3188;HANGUL LETTER YO-YAE;Lo;0;L;<compat> 1185;;;;N;HANGUL LETTER YOYAE;;;;
+3189;HANGUL LETTER YO-I;Lo;0;L;<compat> 1188;;;;N;HANGUL LETTER YOI;;;;
+318A;HANGUL LETTER YU-YEO;Lo;0;L;<compat> 1191;;;;N;HANGUL LETTER YUYEO;;;;
+318B;HANGUL LETTER YU-YE;Lo;0;L;<compat> 1192;;;;N;HANGUL LETTER YUYE;;;;
+318C;HANGUL LETTER YU-I;Lo;0;L;<compat> 1194;;;;N;HANGUL LETTER YUI;;;;
+318D;HANGUL LETTER ARAEA;Lo;0;L;<compat> 119E;;;;N;HANGUL LETTER ALAE A;;;;
+318E;HANGUL LETTER ARAEAE;Lo;0;L;<compat> 11A1;;;;N;HANGUL LETTER ALAE AE;;;;
+3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;;;;
+3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;;;;
+3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L;<super> 4E00;;;1;N;KAERITEN ITI;;;;
+3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L;<super> 4E8C;;;2;N;KAERITEN NI;;;;
+3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L;<super> 4E09;;;3;N;KAERITEN SAN;;;;
+3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L;<super> 56DB;;;4;N;KAERITEN SI;;;;
+3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L;<super> 4E0A;;;;N;KAERITEN ZYOU;;;;
+3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L;<super> 4E2D;;;;N;KAERITEN TYUU;;;;
+3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L;<super> 4E0B;;;;N;KAERITEN GE;;;;
+3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L;<super> 7532;;;;N;KAERITEN KOU;;;;
+319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L;<super> 4E59;;;;N;KAERITEN OTU;;;;
+319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L;<super> 4E19;;;;N;KAERITEN HEI;;;;
+319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L;<super> 4E01;;;;N;KAERITEN TEI;;;;
+319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L;<super> 5929;;;;N;KAERITEN TEN;;;;
+319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L;<super> 5730;;;;N;KAERITEN TI;;;;
+319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L;<super> 4EBA;;;;N;KAERITEN ZIN;;;;
+31A0;BOPOMOFO LETTER BU;Lo;0;L;;;;;N;;;;;
+31A1;BOPOMOFO LETTER ZI;Lo;0;L;;;;;N;;;;;
+31A2;BOPOMOFO LETTER JI;Lo;0;L;;;;;N;;;;;
+31A3;BOPOMOFO LETTER GU;Lo;0;L;;;;;N;;;;;
+31A4;BOPOMOFO LETTER EE;Lo;0;L;;;;;N;;;;;
+31A5;BOPOMOFO LETTER ENN;Lo;0;L;;;;;N;;;;;
+31A6;BOPOMOFO LETTER OO;Lo;0;L;;;;;N;;;;;
+31A7;BOPOMOFO LETTER ONN;Lo;0;L;;;;;N;;;;;
+31A8;BOPOMOFO LETTER IR;Lo;0;L;;;;;N;;;;;
+31A9;BOPOMOFO LETTER ANN;Lo;0;L;;;;;N;;;;;
+31AA;BOPOMOFO LETTER INN;Lo;0;L;;;;;N;;;;;
+31AB;BOPOMOFO LETTER UNN;Lo;0;L;;;;;N;;;;;
+31AC;BOPOMOFO LETTER IM;Lo;0;L;;;;;N;;;;;
+31AD;BOPOMOFO LETTER NGG;Lo;0;L;;;;;N;;;;;
+31AE;BOPOMOFO LETTER AINN;Lo;0;L;;;;;N;;;;;
+31AF;BOPOMOFO LETTER AUNN;Lo;0;L;;;;;N;;;;;
+31B0;BOPOMOFO LETTER AM;Lo;0;L;;;;;N;;;;;
+31B1;BOPOMOFO LETTER OM;Lo;0;L;;;;;N;;;;;
+31B2;BOPOMOFO LETTER ONG;Lo;0;L;;;;;N;;;;;
+31B3;BOPOMOFO LETTER INNN;Lo;0;L;;;;;N;;;;;
+31B4;BOPOMOFO FINAL LETTER P;Lo;0;L;;;;;N;;;;;
+31B5;BOPOMOFO FINAL LETTER T;Lo;0;L;;;;;N;;;;;
+31B6;BOPOMOFO FINAL LETTER K;Lo;0;L;;;;;N;;;;;
+31B7;BOPOMOFO FINAL LETTER H;Lo;0;L;;;;;N;;;;;
+31B8;BOPOMOFO LETTER GH;Lo;0;L;;;;;N;;;;;
+31B9;BOPOMOFO LETTER LH;Lo;0;L;;;;;N;;;;;
+31BA;BOPOMOFO LETTER ZY;Lo;0;L;;;;;N;;;;;
+31C0;CJK STROKE T;So;0;ON;;;;;N;;;;;
+31C1;CJK STROKE WG;So;0;ON;;;;;N;;;;;
+31C2;CJK STROKE XG;So;0;ON;;;;;N;;;;;
+31C3;CJK STROKE BXG;So;0;ON;;;;;N;;;;;
+31C4;CJK STROKE SW;So;0;ON;;;;;N;;;;;
+31C5;CJK STROKE HZZ;So;0;ON;;;;;N;;;;;
+31C6;CJK STROKE HZG;So;0;ON;;;;;N;;;;;
+31C7;CJK STROKE HP;So;0;ON;;;;;N;;;;;
+31C8;CJK STROKE HZWG;So;0;ON;;;;;N;;;;;
+31C9;CJK STROKE SZWG;So;0;ON;;;;;N;;;;;
+31CA;CJK STROKE HZT;So;0;ON;;;;;N;;;;;
+31CB;CJK STROKE HZZP;So;0;ON;;;;;N;;;;;
+31CC;CJK STROKE HPWG;So;0;ON;;;;;N;;;;;
+31CD;CJK STROKE HZW;So;0;ON;;;;;N;;;;;
+31CE;CJK STROKE HZZZ;So;0;ON;;;;;N;;;;;
+31CF;CJK STROKE N;So;0;ON;;;;;N;;;;;
+31D0;CJK STROKE H;So;0;ON;;;;;N;;;;;
+31D1;CJK STROKE S;So;0;ON;;;;;N;;;;;
+31D2;CJK STROKE P;So;0;ON;;;;;N;;;;;
+31D3;CJK STROKE SP;So;0;ON;;;;;N;;;;;
+31D4;CJK STROKE D;So;0;ON;;;;;N;;;;;
+31D5;CJK STROKE HZ;So;0;ON;;;;;N;;;;;
+31D6;CJK STROKE HG;So;0;ON;;;;;N;;;;;
+31D7;CJK STROKE SZ;So;0;ON;;;;;N;;;;;
+31D8;CJK STROKE SWZ;So;0;ON;;;;;N;;;;;
+31D9;CJK STROKE ST;So;0;ON;;;;;N;;;;;
+31DA;CJK STROKE SG;So;0;ON;;;;;N;;;;;
+31DB;CJK STROKE PD;So;0;ON;;;;;N;;;;;
+31DC;CJK STROKE PZ;So;0;ON;;;;;N;;;;;
+31DD;CJK STROKE TN;So;0;ON;;;;;N;;;;;
+31DE;CJK STROKE SZZ;So;0;ON;;;;;N;;;;;
+31DF;CJK STROKE SWG;So;0;ON;;;;;N;;;;;
+31E0;CJK STROKE HXWG;So;0;ON;;;;;N;;;;;
+31E1;CJK STROKE HZZZG;So;0;ON;;;;;N;;;;;
+31E2;CJK STROKE PG;So;0;ON;;;;;N;;;;;
+31E3;CJK STROKE Q;So;0;ON;;;;;N;;;;;
+31F0;KATAKANA LETTER SMALL KU;Lo;0;L;;;;;N;;;;;
+31F1;KATAKANA LETTER SMALL SI;Lo;0;L;;;;;N;;;;;
+31F2;KATAKANA LETTER SMALL SU;Lo;0;L;;;;;N;;;;;
+31F3;KATAKANA LETTER SMALL TO;Lo;0;L;;;;;N;;;;;
+31F4;KATAKANA LETTER SMALL NU;Lo;0;L;;;;;N;;;;;
+31F5;KATAKANA LETTER SMALL HA;Lo;0;L;;;;;N;;;;;
+31F6;KATAKANA LETTER SMALL HI;Lo;0;L;;;;;N;;;;;
+31F7;KATAKANA LETTER SMALL HU;Lo;0;L;;;;;N;;;;;
+31F8;KATAKANA LETTER SMALL HE;Lo;0;L;;;;;N;;;;;
+31F9;KATAKANA LETTER SMALL HO;Lo;0;L;;;;;N;;;;;
+31FA;KATAKANA LETTER SMALL MU;Lo;0;L;;;;;N;;;;;
+31FB;KATAKANA LETTER SMALL RA;Lo;0;L;;;;;N;;;;;
+31FC;KATAKANA LETTER SMALL RI;Lo;0;L;;;;;N;;;;;
+31FD;KATAKANA LETTER SMALL RU;Lo;0;L;;;;;N;;;;;
+31FE;KATAKANA LETTER SMALL RE;Lo;0;L;;;;;N;;;;;
+31FF;KATAKANA LETTER SMALL RO;Lo;0;L;;;;;N;;;;;
+3200;PARENTHESIZED HANGUL KIYEOK;So;0;L;<compat> 0028 1100 0029;;;;N;PARENTHESIZED HANGUL GIYEOG;;;;
+3201;PARENTHESIZED HANGUL NIEUN;So;0;L;<compat> 0028 1102 0029;;;;N;;;;;
+3202;PARENTHESIZED HANGUL TIKEUT;So;0;L;<compat> 0028 1103 0029;;;;N;PARENTHESIZED HANGUL DIGEUD;;;;
+3203;PARENTHESIZED HANGUL RIEUL;So;0;L;<compat> 0028 1105 0029;;;;N;PARENTHESIZED HANGUL LIEUL;;;;
+3204;PARENTHESIZED HANGUL MIEUM;So;0;L;<compat> 0028 1106 0029;;;;N;;;;;
+3205;PARENTHESIZED HANGUL PIEUP;So;0;L;<compat> 0028 1107 0029;;;;N;PARENTHESIZED HANGUL BIEUB;;;;
+3206;PARENTHESIZED HANGUL SIOS;So;0;L;<compat> 0028 1109 0029;;;;N;;;;;
+3207;PARENTHESIZED HANGUL IEUNG;So;0;L;<compat> 0028 110B 0029;;;;N;;;;;
+3208;PARENTHESIZED HANGUL CIEUC;So;0;L;<compat> 0028 110C 0029;;;;N;PARENTHESIZED HANGUL JIEUJ;;;;
+3209;PARENTHESIZED HANGUL CHIEUCH;So;0;L;<compat> 0028 110E 0029;;;;N;PARENTHESIZED HANGUL CIEUC;;;;
+320A;PARENTHESIZED HANGUL KHIEUKH;So;0;L;<compat> 0028 110F 0029;;;;N;PARENTHESIZED HANGUL KIYEOK;;;;
+320B;PARENTHESIZED HANGUL THIEUTH;So;0;L;<compat> 0028 1110 0029;;;;N;PARENTHESIZED HANGUL TIEUT;;;;
+320C;PARENTHESIZED HANGUL PHIEUPH;So;0;L;<compat> 0028 1111 0029;;;;N;PARENTHESIZED HANGUL PIEUP;;;;
+320D;PARENTHESIZED HANGUL HIEUH;So;0;L;<compat> 0028 1112 0029;;;;N;;;;;
+320E;PARENTHESIZED HANGUL KIYEOK A;So;0;L;<compat> 0028 1100 1161 0029;;;;N;PARENTHESIZED HANGUL GA;;;;
+320F;PARENTHESIZED HANGUL NIEUN A;So;0;L;<compat> 0028 1102 1161 0029;;;;N;PARENTHESIZED HANGUL NA;;;;
+3210;PARENTHESIZED HANGUL TIKEUT A;So;0;L;<compat> 0028 1103 1161 0029;;;;N;PARENTHESIZED HANGUL DA;;;;
+3211;PARENTHESIZED HANGUL RIEUL A;So;0;L;<compat> 0028 1105 1161 0029;;;;N;PARENTHESIZED HANGUL LA;;;;
+3212;PARENTHESIZED HANGUL MIEUM A;So;0;L;<compat> 0028 1106 1161 0029;;;;N;PARENTHESIZED HANGUL MA;;;;
+3213;PARENTHESIZED HANGUL PIEUP A;So;0;L;<compat> 0028 1107 1161 0029;;;;N;PARENTHESIZED HANGUL BA;;;;
+3214;PARENTHESIZED HANGUL SIOS A;So;0;L;<compat> 0028 1109 1161 0029;;;;N;PARENTHESIZED HANGUL SA;;;;
+3215;PARENTHESIZED HANGUL IEUNG A;So;0;L;<compat> 0028 110B 1161 0029;;;;N;PARENTHESIZED HANGUL A;;;;
+3216;PARENTHESIZED HANGUL CIEUC A;So;0;L;<compat> 0028 110C 1161 0029;;;;N;PARENTHESIZED HANGUL JA;;;;
+3217;PARENTHESIZED HANGUL CHIEUCH A;So;0;L;<compat> 0028 110E 1161 0029;;;;N;PARENTHESIZED HANGUL CA;;;;
+3218;PARENTHESIZED HANGUL KHIEUKH A;So;0;L;<compat> 0028 110F 1161 0029;;;;N;PARENTHESIZED HANGUL KA;;;;
+3219;PARENTHESIZED HANGUL THIEUTH A;So;0;L;<compat> 0028 1110 1161 0029;;;;N;PARENTHESIZED HANGUL TA;;;;
+321A;PARENTHESIZED HANGUL PHIEUPH A;So;0;L;<compat> 0028 1111 1161 0029;;;;N;PARENTHESIZED HANGUL PA;;;;
+321B;PARENTHESIZED HANGUL HIEUH A;So;0;L;<compat> 0028 1112 1161 0029;;;;N;PARENTHESIZED HANGUL HA;;;;
+321C;PARENTHESIZED HANGUL CIEUC U;So;0;L;<compat> 0028 110C 116E 0029;;;;N;PARENTHESIZED HANGUL JU;;;;
+321D;PARENTHESIZED KOREAN CHARACTER OJEON;So;0;ON;<compat> 0028 110B 1169 110C 1165 11AB 0029;;;;N;;;;;
+321E;PARENTHESIZED KOREAN CHARACTER O HU;So;0;ON;<compat> 0028 110B 1169 1112 116E 0029;;;;N;;;;;
+3220;PARENTHESIZED IDEOGRAPH ONE;No;0;L;<compat> 0028 4E00 0029;;;1;N;;;;;
+3221;PARENTHESIZED IDEOGRAPH TWO;No;0;L;<compat> 0028 4E8C 0029;;;2;N;;;;;
+3222;PARENTHESIZED IDEOGRAPH THREE;No;0;L;<compat> 0028 4E09 0029;;;3;N;;;;;
+3223;PARENTHESIZED IDEOGRAPH FOUR;No;0;L;<compat> 0028 56DB 0029;;;4;N;;;;;
+3224;PARENTHESIZED IDEOGRAPH FIVE;No;0;L;<compat> 0028 4E94 0029;;;5;N;;;;;
+3225;PARENTHESIZED IDEOGRAPH SIX;No;0;L;<compat> 0028 516D 0029;;;6;N;;;;;
+3226;PARENTHESIZED IDEOGRAPH SEVEN;No;0;L;<compat> 0028 4E03 0029;;;7;N;;;;;
+3227;PARENTHESIZED IDEOGRAPH EIGHT;No;0;L;<compat> 0028 516B 0029;;;8;N;;;;;
+3228;PARENTHESIZED IDEOGRAPH NINE;No;0;L;<compat> 0028 4E5D 0029;;;9;N;;;;;
+3229;PARENTHESIZED IDEOGRAPH TEN;No;0;L;<compat> 0028 5341 0029;;;10;N;;;;;
+322A;PARENTHESIZED IDEOGRAPH MOON;So;0;L;<compat> 0028 6708 0029;;;;N;;;;;
+322B;PARENTHESIZED IDEOGRAPH FIRE;So;0;L;<compat> 0028 706B 0029;;;;N;;;;;
+322C;PARENTHESIZED IDEOGRAPH WATER;So;0;L;<compat> 0028 6C34 0029;;;;N;;;;;
+322D;PARENTHESIZED IDEOGRAPH WOOD;So;0;L;<compat> 0028 6728 0029;;;;N;;;;;
+322E;PARENTHESIZED IDEOGRAPH METAL;So;0;L;<compat> 0028 91D1 0029;;;;N;;;;;
+322F;PARENTHESIZED IDEOGRAPH EARTH;So;0;L;<compat> 0028 571F 0029;;;;N;;;;;
+3230;PARENTHESIZED IDEOGRAPH SUN;So;0;L;<compat> 0028 65E5 0029;;;;N;;;;;
+3231;PARENTHESIZED IDEOGRAPH STOCK;So;0;L;<compat> 0028 682A 0029;;;;N;;;;;
+3232;PARENTHESIZED IDEOGRAPH HAVE;So;0;L;<compat> 0028 6709 0029;;;;N;;;;;
+3233;PARENTHESIZED IDEOGRAPH SOCIETY;So;0;L;<compat> 0028 793E 0029;;;;N;;;;;
+3234;PARENTHESIZED IDEOGRAPH NAME;So;0;L;<compat> 0028 540D 0029;;;;N;;;;;
+3235;PARENTHESIZED IDEOGRAPH SPECIAL;So;0;L;<compat> 0028 7279 0029;;;;N;;;;;
+3236;PARENTHESIZED IDEOGRAPH FINANCIAL;So;0;L;<compat> 0028 8CA1 0029;;;;N;;;;;
+3237;PARENTHESIZED IDEOGRAPH CONGRATULATION;So;0;L;<compat> 0028 795D 0029;;;;N;;;;;
+3238;PARENTHESIZED IDEOGRAPH LABOR;So;0;L;<compat> 0028 52B4 0029;;;;N;;;;;
+3239;PARENTHESIZED IDEOGRAPH REPRESENT;So;0;L;<compat> 0028 4EE3 0029;;;;N;;;;;
+323A;PARENTHESIZED IDEOGRAPH CALL;So;0;L;<compat> 0028 547C 0029;;;;N;;;;;
+323B;PARENTHESIZED IDEOGRAPH STUDY;So;0;L;<compat> 0028 5B66 0029;;;;N;;;;;
+323C;PARENTHESIZED IDEOGRAPH SUPERVISE;So;0;L;<compat> 0028 76E3 0029;;;;N;;;;;
+323D;PARENTHESIZED IDEOGRAPH ENTERPRISE;So;0;L;<compat> 0028 4F01 0029;;;;N;;;;;
+323E;PARENTHESIZED IDEOGRAPH RESOURCE;So;0;L;<compat> 0028 8CC7 0029;;;;N;;;;;
+323F;PARENTHESIZED IDEOGRAPH ALLIANCE;So;0;L;<compat> 0028 5354 0029;;;;N;;;;;
+3240;PARENTHESIZED IDEOGRAPH FESTIVAL;So;0;L;<compat> 0028 796D 0029;;;;N;;;;;
+3241;PARENTHESIZED IDEOGRAPH REST;So;0;L;<compat> 0028 4F11 0029;;;;N;;;;;
+3242;PARENTHESIZED IDEOGRAPH SELF;So;0;L;<compat> 0028 81EA 0029;;;;N;;;;;
+3243;PARENTHESIZED IDEOGRAPH REACH;So;0;L;<compat> 0028 81F3 0029;;;;N;;;;;
+3244;CIRCLED IDEOGRAPH QUESTION;So;0;L;<circle> 554F;;;;N;;;;;
+3245;CIRCLED IDEOGRAPH KINDERGARTEN;So;0;L;<circle> 5E7C;;;;N;;;;;
+3246;CIRCLED IDEOGRAPH SCHOOL;So;0;L;<circle> 6587;;;;N;;;;;
+3247;CIRCLED IDEOGRAPH KOTO;So;0;L;<circle> 7B8F;;;;N;;;;;
+3248;CIRCLED NUMBER TEN ON BLACK SQUARE;No;0;L;;;;10;N;;;;;
+3249;CIRCLED NUMBER TWENTY ON BLACK SQUARE;No;0;L;;;;20;N;;;;;
+324A;CIRCLED NUMBER THIRTY ON BLACK SQUARE;No;0;L;;;;30;N;;;;;
+324B;CIRCLED NUMBER FORTY ON BLACK SQUARE;No;0;L;;;;40;N;;;;;
+324C;CIRCLED NUMBER FIFTY ON BLACK SQUARE;No;0;L;;;;50;N;;;;;
+324D;CIRCLED NUMBER SIXTY ON BLACK SQUARE;No;0;L;;;;60;N;;;;;
+324E;CIRCLED NUMBER SEVENTY ON BLACK SQUARE;No;0;L;;;;70;N;;;;;
+324F;CIRCLED NUMBER EIGHTY ON BLACK SQUARE;No;0;L;;;;80;N;;;;;
+3250;PARTNERSHIP SIGN;So;0;ON;<square> 0050 0054 0045;;;;N;;;;;
+3251;CIRCLED NUMBER TWENTY ONE;No;0;ON;<circle> 0032 0031;;;21;N;;;;;
+3252;CIRCLED NUMBER TWENTY TWO;No;0;ON;<circle> 0032 0032;;;22;N;;;;;
+3253;CIRCLED NUMBER TWENTY THREE;No;0;ON;<circle> 0032 0033;;;23;N;;;;;
+3254;CIRCLED NUMBER TWENTY FOUR;No;0;ON;<circle> 0032 0034;;;24;N;;;;;
+3255;CIRCLED NUMBER TWENTY FIVE;No;0;ON;<circle> 0032 0035;;;25;N;;;;;
+3256;CIRCLED NUMBER TWENTY SIX;No;0;ON;<circle> 0032 0036;;;26;N;;;;;
+3257;CIRCLED NUMBER TWENTY SEVEN;No;0;ON;<circle> 0032 0037;;;27;N;;;;;
+3258;CIRCLED NUMBER TWENTY EIGHT;No;0;ON;<circle> 0032 0038;;;28;N;;;;;
+3259;CIRCLED NUMBER TWENTY NINE;No;0;ON;<circle> 0032 0039;;;29;N;;;;;
+325A;CIRCLED NUMBER THIRTY;No;0;ON;<circle> 0033 0030;;;30;N;;;;;
+325B;CIRCLED NUMBER THIRTY ONE;No;0;ON;<circle> 0033 0031;;;31;N;;;;;
+325C;CIRCLED NUMBER THIRTY TWO;No;0;ON;<circle> 0033 0032;;;32;N;;;;;
+325D;CIRCLED NUMBER THIRTY THREE;No;0;ON;<circle> 0033 0033;;;33;N;;;;;
+325E;CIRCLED NUMBER THIRTY FOUR;No;0;ON;<circle> 0033 0034;;;34;N;;;;;
+325F;CIRCLED NUMBER THIRTY FIVE;No;0;ON;<circle> 0033 0035;;;35;N;;;;;
+3260;CIRCLED HANGUL KIYEOK;So;0;L;<circle> 1100;;;;N;CIRCLED HANGUL GIYEOG;;;;
+3261;CIRCLED HANGUL NIEUN;So;0;L;<circle> 1102;;;;N;;;;;
+3262;CIRCLED HANGUL TIKEUT;So;0;L;<circle> 1103;;;;N;CIRCLED HANGUL DIGEUD;;;;
+3263;CIRCLED HANGUL RIEUL;So;0;L;<circle> 1105;;;;N;CIRCLED HANGUL LIEUL;;;;
+3264;CIRCLED HANGUL MIEUM;So;0;L;<circle> 1106;;;;N;;;;;
+3265;CIRCLED HANGUL PIEUP;So;0;L;<circle> 1107;;;;N;CIRCLED HANGUL BIEUB;;;;
+3266;CIRCLED HANGUL SIOS;So;0;L;<circle> 1109;;;;N;;;;;
+3267;CIRCLED HANGUL IEUNG;So;0;L;<circle> 110B;;;;N;;;;;
+3268;CIRCLED HANGUL CIEUC;So;0;L;<circle> 110C;;;;N;CIRCLED HANGUL JIEUJ;;;;
+3269;CIRCLED HANGUL CHIEUCH;So;0;L;<circle> 110E;;;;N;CIRCLED HANGUL CIEUC;;;;
+326A;CIRCLED HANGUL KHIEUKH;So;0;L;<circle> 110F;;;;N;CIRCLED HANGUL KIYEOK;;;;
+326B;CIRCLED HANGUL THIEUTH;So;0;L;<circle> 1110;;;;N;CIRCLED HANGUL TIEUT;;;;
+326C;CIRCLED HANGUL PHIEUPH;So;0;L;<circle> 1111;;;;N;CIRCLED HANGUL PIEUP;;;;
+326D;CIRCLED HANGUL HIEUH;So;0;L;<circle> 1112;;;;N;;;;;
+326E;CIRCLED HANGUL KIYEOK A;So;0;L;<circle> 1100 1161;;;;N;CIRCLED HANGUL GA;;;;
+326F;CIRCLED HANGUL NIEUN A;So;0;L;<circle> 1102 1161;;;;N;CIRCLED HANGUL NA;;;;
+3270;CIRCLED HANGUL TIKEUT A;So;0;L;<circle> 1103 1161;;;;N;CIRCLED HANGUL DA;;;;
+3271;CIRCLED HANGUL RIEUL A;So;0;L;<circle> 1105 1161;;;;N;CIRCLED HANGUL LA;;;;
+3272;CIRCLED HANGUL MIEUM A;So;0;L;<circle> 1106 1161;;;;N;CIRCLED HANGUL MA;;;;
+3273;CIRCLED HANGUL PIEUP A;So;0;L;<circle> 1107 1161;;;;N;CIRCLED HANGUL BA;;;;
+3274;CIRCLED HANGUL SIOS A;So;0;L;<circle> 1109 1161;;;;N;CIRCLED HANGUL SA;;;;
+3275;CIRCLED HANGUL IEUNG A;So;0;L;<circle> 110B 1161;;;;N;CIRCLED HANGUL A;;;;
+3276;CIRCLED HANGUL CIEUC A;So;0;L;<circle> 110C 1161;;;;N;CIRCLED HANGUL JA;;;;
+3277;CIRCLED HANGUL CHIEUCH A;So;0;L;<circle> 110E 1161;;;;N;CIRCLED HANGUL CA;;;;
+3278;CIRCLED HANGUL KHIEUKH A;So;0;L;<circle> 110F 1161;;;;N;CIRCLED HANGUL KA;;;;
+3279;CIRCLED HANGUL THIEUTH A;So;0;L;<circle> 1110 1161;;;;N;CIRCLED HANGUL TA;;;;
+327A;CIRCLED HANGUL PHIEUPH A;So;0;L;<circle> 1111 1161;;;;N;CIRCLED HANGUL PA;;;;
+327B;CIRCLED HANGUL HIEUH A;So;0;L;<circle> 1112 1161;;;;N;CIRCLED HANGUL HA;;;;
+327C;CIRCLED KOREAN CHARACTER CHAMKO;So;0;ON;<circle> 110E 1161 11B7 1100 1169;;;;N;;;;;
+327D;CIRCLED KOREAN CHARACTER JUEUI;So;0;ON;<circle> 110C 116E 110B 1174;;;;N;;;;;
+327E;CIRCLED HANGUL IEUNG U;So;0;ON;<circle> 110B 116E;;;;N;;;;;
+327F;KOREAN STANDARD SYMBOL;So;0;L;;;;;N;;;;;
+3280;CIRCLED IDEOGRAPH ONE;No;0;L;<circle> 4E00;;;1;N;;;;;
+3281;CIRCLED IDEOGRAPH TWO;No;0;L;<circle> 4E8C;;;2;N;;;;;
+3282;CIRCLED IDEOGRAPH THREE;No;0;L;<circle> 4E09;;;3;N;;;;;
+3283;CIRCLED IDEOGRAPH FOUR;No;0;L;<circle> 56DB;;;4;N;;;;;
+3284;CIRCLED IDEOGRAPH FIVE;No;0;L;<circle> 4E94;;;5;N;;;;;
+3285;CIRCLED IDEOGRAPH SIX;No;0;L;<circle> 516D;;;6;N;;;;;
+3286;CIRCLED IDEOGRAPH SEVEN;No;0;L;<circle> 4E03;;;7;N;;;;;
+3287;CIRCLED IDEOGRAPH EIGHT;No;0;L;<circle> 516B;;;8;N;;;;;
+3288;CIRCLED IDEOGRAPH NINE;No;0;L;<circle> 4E5D;;;9;N;;;;;
+3289;CIRCLED IDEOGRAPH TEN;No;0;L;<circle> 5341;;;10;N;;;;;
+328A;CIRCLED IDEOGRAPH MOON;So;0;L;<circle> 6708;;;;N;;;;;
+328B;CIRCLED IDEOGRAPH FIRE;So;0;L;<circle> 706B;;;;N;;;;;
+328C;CIRCLED IDEOGRAPH WATER;So;0;L;<circle> 6C34;;;;N;;;;;
+328D;CIRCLED IDEOGRAPH WOOD;So;0;L;<circle> 6728;;;;N;;;;;
+328E;CIRCLED IDEOGRAPH METAL;So;0;L;<circle> 91D1;;;;N;;;;;
+328F;CIRCLED IDEOGRAPH EARTH;So;0;L;<circle> 571F;;;;N;;;;;
+3290;CIRCLED IDEOGRAPH SUN;So;0;L;<circle> 65E5;;;;N;;;;;
+3291;CIRCLED IDEOGRAPH STOCK;So;0;L;<circle> 682A;;;;N;;;;;
+3292;CIRCLED IDEOGRAPH HAVE;So;0;L;<circle> 6709;;;;N;;;;;
+3293;CIRCLED IDEOGRAPH SOCIETY;So;0;L;<circle> 793E;;;;N;;;;;
+3294;CIRCLED IDEOGRAPH NAME;So;0;L;<circle> 540D;;;;N;;;;;
+3295;CIRCLED IDEOGRAPH SPECIAL;So;0;L;<circle> 7279;;;;N;;;;;
+3296;CIRCLED IDEOGRAPH FINANCIAL;So;0;L;<circle> 8CA1;;;;N;;;;;
+3297;CIRCLED IDEOGRAPH CONGRATULATION;So;0;L;<circle> 795D;;;;N;;;;;
+3298;CIRCLED IDEOGRAPH LABOR;So;0;L;<circle> 52B4;;;;N;;;;;
+3299;CIRCLED IDEOGRAPH SECRET;So;0;L;<circle> 79D8;;;;N;;;;;
+329A;CIRCLED IDEOGRAPH MALE;So;0;L;<circle> 7537;;;;N;;;;;
+329B;CIRCLED IDEOGRAPH FEMALE;So;0;L;<circle> 5973;;;;N;;;;;
+329C;CIRCLED IDEOGRAPH SUITABLE;So;0;L;<circle> 9069;;;;N;;;;;
+329D;CIRCLED IDEOGRAPH EXCELLENT;So;0;L;<circle> 512A;;;;N;;;;;
+329E;CIRCLED IDEOGRAPH PRINT;So;0;L;<circle> 5370;;;;N;;;;;
+329F;CIRCLED IDEOGRAPH ATTENTION;So;0;L;<circle> 6CE8;;;;N;;;;;
+32A0;CIRCLED IDEOGRAPH ITEM;So;0;L;<circle> 9805;;;;N;;;;;
+32A1;CIRCLED IDEOGRAPH REST;So;0;L;<circle> 4F11;;;;N;;;;;
+32A2;CIRCLED IDEOGRAPH COPY;So;0;L;<circle> 5199;;;;N;;;;;
+32A3;CIRCLED IDEOGRAPH CORRECT;So;0;L;<circle> 6B63;;;;N;;;;;
+32A4;CIRCLED IDEOGRAPH HIGH;So;0;L;<circle> 4E0A;;;;N;;;;;
+32A5;CIRCLED IDEOGRAPH CENTRE;So;0;L;<circle> 4E2D;;;;N;CIRCLED IDEOGRAPH CENTER;;;;
+32A6;CIRCLED IDEOGRAPH LOW;So;0;L;<circle> 4E0B;;;;N;;;;;
+32A7;CIRCLED IDEOGRAPH LEFT;So;0;L;<circle> 5DE6;;;;N;;;;;
+32A8;CIRCLED IDEOGRAPH RIGHT;So;0;L;<circle> 53F3;;;;N;;;;;
+32A9;CIRCLED IDEOGRAPH MEDICINE;So;0;L;<circle> 533B;;;;N;;;;;
+32AA;CIRCLED IDEOGRAPH RELIGION;So;0;L;<circle> 5B97;;;;N;;;;;
+32AB;CIRCLED IDEOGRAPH STUDY;So;0;L;<circle> 5B66;;;;N;;;;;
+32AC;CIRCLED IDEOGRAPH SUPERVISE;So;0;L;<circle> 76E3;;;;N;;;;;
+32AD;CIRCLED IDEOGRAPH ENTERPRISE;So;0;L;<circle> 4F01;;;;N;;;;;
+32AE;CIRCLED IDEOGRAPH RESOURCE;So;0;L;<circle> 8CC7;;;;N;;;;;
+32AF;CIRCLED IDEOGRAPH ALLIANCE;So;0;L;<circle> 5354;;;;N;;;;;
+32B0;CIRCLED IDEOGRAPH NIGHT;So;0;L;<circle> 591C;;;;N;;;;;
+32B1;CIRCLED NUMBER THIRTY SIX;No;0;ON;<circle> 0033 0036;;;36;N;;;;;
+32B2;CIRCLED NUMBER THIRTY SEVEN;No;0;ON;<circle> 0033 0037;;;37;N;;;;;
+32B3;CIRCLED NUMBER THIRTY EIGHT;No;0;ON;<circle> 0033 0038;;;38;N;;;;;
+32B4;CIRCLED NUMBER THIRTY NINE;No;0;ON;<circle> 0033 0039;;;39;N;;;;;
+32B5;CIRCLED NUMBER FORTY;No;0;ON;<circle> 0034 0030;;;40;N;;;;;
+32B6;CIRCLED NUMBER FORTY ONE;No;0;ON;<circle> 0034 0031;;;41;N;;;;;
+32B7;CIRCLED NUMBER FORTY TWO;No;0;ON;<circle> 0034 0032;;;42;N;;;;;
+32B8;CIRCLED NUMBER FORTY THREE;No;0;ON;<circle> 0034 0033;;;43;N;;;;;
+32B9;CIRCLED NUMBER FORTY FOUR;No;0;ON;<circle> 0034 0034;;;44;N;;;;;
+32BA;CIRCLED NUMBER FORTY FIVE;No;0;ON;<circle> 0034 0035;;;45;N;;;;;
+32BB;CIRCLED NUMBER FORTY SIX;No;0;ON;<circle> 0034 0036;;;46;N;;;;;
+32BC;CIRCLED NUMBER FORTY SEVEN;No;0;ON;<circle> 0034 0037;;;47;N;;;;;
+32BD;CIRCLED NUMBER FORTY EIGHT;No;0;ON;<circle> 0034 0038;;;48;N;;;;;
+32BE;CIRCLED NUMBER FORTY NINE;No;0;ON;<circle> 0034 0039;;;49;N;;;;;
+32BF;CIRCLED NUMBER FIFTY;No;0;ON;<circle> 0035 0030;;;50;N;;;;;
+32C0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY;So;0;L;<compat> 0031 6708;;;;N;;;;;
+32C1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY;So;0;L;<compat> 0032 6708;;;;N;;;;;
+32C2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH;So;0;L;<compat> 0033 6708;;;;N;;;;;
+32C3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL;So;0;L;<compat> 0034 6708;;;;N;;;;;
+32C4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY;So;0;L;<compat> 0035 6708;;;;N;;;;;
+32C5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE;So;0;L;<compat> 0036 6708;;;;N;;;;;
+32C6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY;So;0;L;<compat> 0037 6708;;;;N;;;;;
+32C7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST;So;0;L;<compat> 0038 6708;;;;N;;;;;
+32C8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER;So;0;L;<compat> 0039 6708;;;;N;;;;;
+32C9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER;So;0;L;<compat> 0031 0030 6708;;;;N;;;;;
+32CA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER;So;0;L;<compat> 0031 0031 6708;;;;N;;;;;
+32CB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER;So;0;L;<compat> 0031 0032 6708;;;;N;;;;;
+32CC;SQUARE HG;So;0;ON;<square> 0048 0067;;;;N;;;;;
+32CD;SQUARE ERG;So;0;ON;<square> 0065 0072 0067;;;;N;;;;;
+32CE;SQUARE EV;So;0;ON;<square> 0065 0056;;;;N;;;;;
+32CF;LIMITED LIABILITY SIGN;So;0;ON;<square> 004C 0054 0044;;;;N;;;;;
+32D0;CIRCLED KATAKANA A;So;0;L;<circle> 30A2;;;;N;;;;;
+32D1;CIRCLED KATAKANA I;So;0;L;<circle> 30A4;;;;N;;;;;
+32D2;CIRCLED KATAKANA U;So;0;L;<circle> 30A6;;;;N;;;;;
+32D3;CIRCLED KATAKANA E;So;0;L;<circle> 30A8;;;;N;;;;;
+32D4;CIRCLED KATAKANA O;So;0;L;<circle> 30AA;;;;N;;;;;
+32D5;CIRCLED KATAKANA KA;So;0;L;<circle> 30AB;;;;N;;;;;
+32D6;CIRCLED KATAKANA KI;So;0;L;<circle> 30AD;;;;N;;;;;
+32D7;CIRCLED KATAKANA KU;So;0;L;<circle> 30AF;;;;N;;;;;
+32D8;CIRCLED KATAKANA KE;So;0;L;<circle> 30B1;;;;N;;;;;
+32D9;CIRCLED KATAKANA KO;So;0;L;<circle> 30B3;;;;N;;;;;
+32DA;CIRCLED KATAKANA SA;So;0;L;<circle> 30B5;;;;N;;;;;
+32DB;CIRCLED KATAKANA SI;So;0;L;<circle> 30B7;;;;N;;;;;
+32DC;CIRCLED KATAKANA SU;So;0;L;<circle> 30B9;;;;N;;;;;
+32DD;CIRCLED KATAKANA SE;So;0;L;<circle> 30BB;;;;N;;;;;
+32DE;CIRCLED KATAKANA SO;So;0;L;<circle> 30BD;;;;N;;;;;
+32DF;CIRCLED KATAKANA TA;So;0;L;<circle> 30BF;;;;N;;;;;
+32E0;CIRCLED KATAKANA TI;So;0;L;<circle> 30C1;;;;N;;;;;
+32E1;CIRCLED KATAKANA TU;So;0;L;<circle> 30C4;;;;N;;;;;
+32E2;CIRCLED KATAKANA TE;So;0;L;<circle> 30C6;;;;N;;;;;
+32E3;CIRCLED KATAKANA TO;So;0;L;<circle> 30C8;;;;N;;;;;
+32E4;CIRCLED KATAKANA NA;So;0;L;<circle> 30CA;;;;N;;;;;
+32E5;CIRCLED KATAKANA NI;So;0;L;<circle> 30CB;;;;N;;;;;
+32E6;CIRCLED KATAKANA NU;So;0;L;<circle> 30CC;;;;N;;;;;
+32E7;CIRCLED KATAKANA NE;So;0;L;<circle> 30CD;;;;N;;;;;
+32E8;CIRCLED KATAKANA NO;So;0;L;<circle> 30CE;;;;N;;;;;
+32E9;CIRCLED KATAKANA HA;So;0;L;<circle> 30CF;;;;N;;;;;
+32EA;CIRCLED KATAKANA HI;So;0;L;<circle> 30D2;;;;N;;;;;
+32EB;CIRCLED KATAKANA HU;So;0;L;<circle> 30D5;;;;N;;;;;
+32EC;CIRCLED KATAKANA HE;So;0;L;<circle> 30D8;;;;N;;;;;
+32ED;CIRCLED KATAKANA HO;So;0;L;<circle> 30DB;;;;N;;;;;
+32EE;CIRCLED KATAKANA MA;So;0;L;<circle> 30DE;;;;N;;;;;
+32EF;CIRCLED KATAKANA MI;So;0;L;<circle> 30DF;;;;N;;;;;
+32F0;CIRCLED KATAKANA MU;So;0;L;<circle> 30E0;;;;N;;;;;
+32F1;CIRCLED KATAKANA ME;So;0;L;<circle> 30E1;;;;N;;;;;
+32F2;CIRCLED KATAKANA MO;So;0;L;<circle> 30E2;;;;N;;;;;
+32F3;CIRCLED KATAKANA YA;So;0;L;<circle> 30E4;;;;N;;;;;
+32F4;CIRCLED KATAKANA YU;So;0;L;<circle> 30E6;;;;N;;;;;
+32F5;CIRCLED KATAKANA YO;So;0;L;<circle> 30E8;;;;N;;;;;
+32F6;CIRCLED KATAKANA RA;So;0;L;<circle> 30E9;;;;N;;;;;
+32F7;CIRCLED KATAKANA RI;So;0;L;<circle> 30EA;;;;N;;;;;
+32F8;CIRCLED KATAKANA RU;So;0;L;<circle> 30EB;;;;N;;;;;
+32F9;CIRCLED KATAKANA RE;So;0;L;<circle> 30EC;;;;N;;;;;
+32FA;CIRCLED KATAKANA RO;So;0;L;<circle> 30ED;;;;N;;;;;
+32FB;CIRCLED KATAKANA WA;So;0;L;<circle> 30EF;;;;N;;;;;
+32FC;CIRCLED KATAKANA WI;So;0;L;<circle> 30F0;;;;N;;;;;
+32FD;CIRCLED KATAKANA WE;So;0;L;<circle> 30F1;;;;N;;;;;
+32FE;CIRCLED KATAKANA WO;So;0;L;<circle> 30F2;;;;N;;;;;
+3300;SQUARE APAATO;So;0;L;<square> 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;;
+3301;SQUARE ARUHUA;So;0;L;<square> 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;;
+3302;SQUARE ANPEA;So;0;L;<square> 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;;
+3303;SQUARE AARU;So;0;L;<square> 30A2 30FC 30EB;;;;N;SQUARED AARU;;;;
+3304;SQUARE ININGU;So;0;L;<square> 30A4 30CB 30F3 30B0;;;;N;SQUARED ININGU;;;;
+3305;SQUARE INTI;So;0;L;<square> 30A4 30F3 30C1;;;;N;SQUARED INTI;;;;
+3306;SQUARE UON;So;0;L;<square> 30A6 30A9 30F3;;;;N;SQUARED UON;;;;
+3307;SQUARE ESUKUUDO;So;0;L;<square> 30A8 30B9 30AF 30FC 30C9;;;;N;SQUARED ESUKUUDO;;;;
+3308;SQUARE EEKAA;So;0;L;<square> 30A8 30FC 30AB 30FC;;;;N;SQUARED EEKAA;;;;
+3309;SQUARE ONSU;So;0;L;<square> 30AA 30F3 30B9;;;;N;SQUARED ONSU;;;;
+330A;SQUARE OOMU;So;0;L;<square> 30AA 30FC 30E0;;;;N;SQUARED OOMU;;;;
+330B;SQUARE KAIRI;So;0;L;<square> 30AB 30A4 30EA;;;;N;SQUARED KAIRI;;;;
+330C;SQUARE KARATTO;So;0;L;<square> 30AB 30E9 30C3 30C8;;;;N;SQUARED KARATTO;;;;
+330D;SQUARE KARORII;So;0;L;<square> 30AB 30ED 30EA 30FC;;;;N;SQUARED KARORII;;;;
+330E;SQUARE GARON;So;0;L;<square> 30AC 30ED 30F3;;;;N;SQUARED GARON;;;;
+330F;SQUARE GANMA;So;0;L;<square> 30AC 30F3 30DE;;;;N;SQUARED GANMA;;;;
+3310;SQUARE GIGA;So;0;L;<square> 30AE 30AC;;;;N;SQUARED GIGA;;;;
+3311;SQUARE GINII;So;0;L;<square> 30AE 30CB 30FC;;;;N;SQUARED GINII;;;;
+3312;SQUARE KYURII;So;0;L;<square> 30AD 30E5 30EA 30FC;;;;N;SQUARED KYURII;;;;
+3313;SQUARE GIRUDAA;So;0;L;<square> 30AE 30EB 30C0 30FC;;;;N;SQUARED GIRUDAA;;;;
+3314;SQUARE KIRO;So;0;L;<square> 30AD 30ED;;;;N;SQUARED KIRO;;;;
+3315;SQUARE KIROGURAMU;So;0;L;<square> 30AD 30ED 30B0 30E9 30E0;;;;N;SQUARED KIROGURAMU;;;;
+3316;SQUARE KIROMEETORU;So;0;L;<square> 30AD 30ED 30E1 30FC 30C8 30EB;;;;N;SQUARED KIROMEETORU;;;;
+3317;SQUARE KIROWATTO;So;0;L;<square> 30AD 30ED 30EF 30C3 30C8;;;;N;SQUARED KIROWATTO;;;;
+3318;SQUARE GURAMU;So;0;L;<square> 30B0 30E9 30E0;;;;N;SQUARED GURAMU;;;;
+3319;SQUARE GURAMUTON;So;0;L;<square> 30B0 30E9 30E0 30C8 30F3;;;;N;SQUARED GURAMUTON;;;;
+331A;SQUARE KURUZEIRO;So;0;L;<square> 30AF 30EB 30BC 30A4 30ED;;;;N;SQUARED KURUZEIRO;;;;
+331B;SQUARE KUROONE;So;0;L;<square> 30AF 30ED 30FC 30CD;;;;N;SQUARED KUROONE;;;;
+331C;SQUARE KEESU;So;0;L;<square> 30B1 30FC 30B9;;;;N;SQUARED KEESU;;;;
+331D;SQUARE KORUNA;So;0;L;<square> 30B3 30EB 30CA;;;;N;SQUARED KORUNA;;;;
+331E;SQUARE KOOPO;So;0;L;<square> 30B3 30FC 30DD;;;;N;SQUARED KOOPO;;;;
+331F;SQUARE SAIKURU;So;0;L;<square> 30B5 30A4 30AF 30EB;;;;N;SQUARED SAIKURU;;;;
+3320;SQUARE SANTIIMU;So;0;L;<square> 30B5 30F3 30C1 30FC 30E0;;;;N;SQUARED SANTIIMU;;;;
+3321;SQUARE SIRINGU;So;0;L;<square> 30B7 30EA 30F3 30B0;;;;N;SQUARED SIRINGU;;;;
+3322;SQUARE SENTI;So;0;L;<square> 30BB 30F3 30C1;;;;N;SQUARED SENTI;;;;
+3323;SQUARE SENTO;So;0;L;<square> 30BB 30F3 30C8;;;;N;SQUARED SENTO;;;;
+3324;SQUARE DAASU;So;0;L;<square> 30C0 30FC 30B9;;;;N;SQUARED DAASU;;;;
+3325;SQUARE DESI;So;0;L;<square> 30C7 30B7;;;;N;SQUARED DESI;;;;
+3326;SQUARE DORU;So;0;L;<square> 30C9 30EB;;;;N;SQUARED DORU;;;;
+3327;SQUARE TON;So;0;L;<square> 30C8 30F3;;;;N;SQUARED TON;;;;
+3328;SQUARE NANO;So;0;L;<square> 30CA 30CE;;;;N;SQUARED NANO;;;;
+3329;SQUARE NOTTO;So;0;L;<square> 30CE 30C3 30C8;;;;N;SQUARED NOTTO;;;;
+332A;SQUARE HAITU;So;0;L;<square> 30CF 30A4 30C4;;;;N;SQUARED HAITU;;;;
+332B;SQUARE PAASENTO;So;0;L;<square> 30D1 30FC 30BB 30F3 30C8;;;;N;SQUARED PAASENTO;;;;
+332C;SQUARE PAATU;So;0;L;<square> 30D1 30FC 30C4;;;;N;SQUARED PAATU;;;;
+332D;SQUARE BAARERU;So;0;L;<square> 30D0 30FC 30EC 30EB;;;;N;SQUARED BAARERU;;;;
+332E;SQUARE PIASUTORU;So;0;L;<square> 30D4 30A2 30B9 30C8 30EB;;;;N;SQUARED PIASUTORU;;;;
+332F;SQUARE PIKURU;So;0;L;<square> 30D4 30AF 30EB;;;;N;SQUARED PIKURU;;;;
+3330;SQUARE PIKO;So;0;L;<square> 30D4 30B3;;;;N;SQUARED PIKO;;;;
+3331;SQUARE BIRU;So;0;L;<square> 30D3 30EB;;;;N;SQUARED BIRU;;;;
+3332;SQUARE HUARADDO;So;0;L;<square> 30D5 30A1 30E9 30C3 30C9;;;;N;SQUARED HUARADDO;;;;
+3333;SQUARE HUIITO;So;0;L;<square> 30D5 30A3 30FC 30C8;;;;N;SQUARED HUIITO;;;;
+3334;SQUARE BUSSYERU;So;0;L;<square> 30D6 30C3 30B7 30A7 30EB;;;;N;SQUARED BUSSYERU;;;;
+3335;SQUARE HURAN;So;0;L;<square> 30D5 30E9 30F3;;;;N;SQUARED HURAN;;;;
+3336;SQUARE HEKUTAARU;So;0;L;<square> 30D8 30AF 30BF 30FC 30EB;;;;N;SQUARED HEKUTAARU;;;;
+3337;SQUARE PESO;So;0;L;<square> 30DA 30BD;;;;N;SQUARED PESO;;;;
+3338;SQUARE PENIHI;So;0;L;<square> 30DA 30CB 30D2;;;;N;SQUARED PENIHI;;;;
+3339;SQUARE HERUTU;So;0;L;<square> 30D8 30EB 30C4;;;;N;SQUARED HERUTU;;;;
+333A;SQUARE PENSU;So;0;L;<square> 30DA 30F3 30B9;;;;N;SQUARED PENSU;;;;
+333B;SQUARE PEEZI;So;0;L;<square> 30DA 30FC 30B8;;;;N;SQUARED PEEZI;;;;
+333C;SQUARE BEETA;So;0;L;<square> 30D9 30FC 30BF;;;;N;SQUARED BEETA;;;;
+333D;SQUARE POINTO;So;0;L;<square> 30DD 30A4 30F3 30C8;;;;N;SQUARED POINTO;;;;
+333E;SQUARE BORUTO;So;0;L;<square> 30DC 30EB 30C8;;;;N;SQUARED BORUTO;;;;
+333F;SQUARE HON;So;0;L;<square> 30DB 30F3;;;;N;SQUARED HON;;;;
+3340;SQUARE PONDO;So;0;L;<square> 30DD 30F3 30C9;;;;N;SQUARED PONDO;;;;
+3341;SQUARE HOORU;So;0;L;<square> 30DB 30FC 30EB;;;;N;SQUARED HOORU;;;;
+3342;SQUARE HOON;So;0;L;<square> 30DB 30FC 30F3;;;;N;SQUARED HOON;;;;
+3343;SQUARE MAIKURO;So;0;L;<square> 30DE 30A4 30AF 30ED;;;;N;SQUARED MAIKURO;;;;
+3344;SQUARE MAIRU;So;0;L;<square> 30DE 30A4 30EB;;;;N;SQUARED MAIRU;;;;
+3345;SQUARE MAHHA;So;0;L;<square> 30DE 30C3 30CF;;;;N;SQUARED MAHHA;;;;
+3346;SQUARE MARUKU;So;0;L;<square> 30DE 30EB 30AF;;;;N;SQUARED MARUKU;;;;
+3347;SQUARE MANSYON;So;0;L;<square> 30DE 30F3 30B7 30E7 30F3;;;;N;SQUARED MANSYON;;;;
+3348;SQUARE MIKURON;So;0;L;<square> 30DF 30AF 30ED 30F3;;;;N;SQUARED MIKURON;;;;
+3349;SQUARE MIRI;So;0;L;<square> 30DF 30EA;;;;N;SQUARED MIRI;;;;
+334A;SQUARE MIRIBAARU;So;0;L;<square> 30DF 30EA 30D0 30FC 30EB;;;;N;SQUARED MIRIBAARU;;;;
+334B;SQUARE MEGA;So;0;L;<square> 30E1 30AC;;;;N;SQUARED MEGA;;;;
+334C;SQUARE MEGATON;So;0;L;<square> 30E1 30AC 30C8 30F3;;;;N;SQUARED MEGATON;;;;
+334D;SQUARE MEETORU;So;0;L;<square> 30E1 30FC 30C8 30EB;;;;N;SQUARED MEETORU;;;;
+334E;SQUARE YAADO;So;0;L;<square> 30E4 30FC 30C9;;;;N;SQUARED YAADO;;;;
+334F;SQUARE YAARU;So;0;L;<square> 30E4 30FC 30EB;;;;N;SQUARED YAARU;;;;
+3350;SQUARE YUAN;So;0;L;<square> 30E6 30A2 30F3;;;;N;SQUARED YUAN;;;;
+3351;SQUARE RITTORU;So;0;L;<square> 30EA 30C3 30C8 30EB;;;;N;SQUARED RITTORU;;;;
+3352;SQUARE RIRA;So;0;L;<square> 30EA 30E9;;;;N;SQUARED RIRA;;;;
+3353;SQUARE RUPII;So;0;L;<square> 30EB 30D4 30FC;;;;N;SQUARED RUPII;;;;
+3354;SQUARE RUUBURU;So;0;L;<square> 30EB 30FC 30D6 30EB;;;;N;SQUARED RUUBURU;;;;
+3355;SQUARE REMU;So;0;L;<square> 30EC 30E0;;;;N;SQUARED REMU;;;;
+3356;SQUARE RENTOGEN;So;0;L;<square> 30EC 30F3 30C8 30B2 30F3;;;;N;SQUARED RENTOGEN;;;;
+3357;SQUARE WATTO;So;0;L;<square> 30EF 30C3 30C8;;;;N;SQUARED WATTO;;;;
+3358;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO;So;0;L;<compat> 0030 70B9;;;;N;;;;;
+3359;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE;So;0;L;<compat> 0031 70B9;;;;N;;;;;
+335A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO;So;0;L;<compat> 0032 70B9;;;;N;;;;;
+335B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE;So;0;L;<compat> 0033 70B9;;;;N;;;;;
+335C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR;So;0;L;<compat> 0034 70B9;;;;N;;;;;
+335D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE;So;0;L;<compat> 0035 70B9;;;;N;;;;;
+335E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX;So;0;L;<compat> 0036 70B9;;;;N;;;;;
+335F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN;So;0;L;<compat> 0037 70B9;;;;N;;;;;
+3360;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT;So;0;L;<compat> 0038 70B9;;;;N;;;;;
+3361;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE;So;0;L;<compat> 0039 70B9;;;;N;;;;;
+3362;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN;So;0;L;<compat> 0031 0030 70B9;;;;N;;;;;
+3363;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN;So;0;L;<compat> 0031 0031 70B9;;;;N;;;;;
+3364;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE;So;0;L;<compat> 0031 0032 70B9;;;;N;;;;;
+3365;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN;So;0;L;<compat> 0031 0033 70B9;;;;N;;;;;
+3366;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN;So;0;L;<compat> 0031 0034 70B9;;;;N;;;;;
+3367;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN;So;0;L;<compat> 0031 0035 70B9;;;;N;;;;;
+3368;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN;So;0;L;<compat> 0031 0036 70B9;;;;N;;;;;
+3369;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN;So;0;L;<compat> 0031 0037 70B9;;;;N;;;;;
+336A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN;So;0;L;<compat> 0031 0038 70B9;;;;N;;;;;
+336B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN;So;0;L;<compat> 0031 0039 70B9;;;;N;;;;;
+336C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY;So;0;L;<compat> 0032 0030 70B9;;;;N;;;;;
+336D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE;So;0;L;<compat> 0032 0031 70B9;;;;N;;;;;
+336E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO;So;0;L;<compat> 0032 0032 70B9;;;;N;;;;;
+336F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE;So;0;L;<compat> 0032 0033 70B9;;;;N;;;;;
+3370;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR;So;0;L;<compat> 0032 0034 70B9;;;;N;;;;;
+3371;SQUARE HPA;So;0;L;<square> 0068 0050 0061;;;;N;;;;;
+3372;SQUARE DA;So;0;L;<square> 0064 0061;;;;N;;;;;
+3373;SQUARE AU;So;0;L;<square> 0041 0055;;;;N;;;;;
+3374;SQUARE BAR;So;0;L;<square> 0062 0061 0072;;;;N;;;;;
+3375;SQUARE OV;So;0;L;<square> 006F 0056;;;;N;;;;;
+3376;SQUARE PC;So;0;L;<square> 0070 0063;;;;N;;;;;
+3377;SQUARE DM;So;0;ON;<square> 0064 006D;;;;N;;;;;
+3378;SQUARE DM SQUARED;So;0;ON;<square> 0064 006D 00B2;;;;N;;;;;
+3379;SQUARE DM CUBED;So;0;ON;<square> 0064 006D 00B3;;;;N;;;;;
+337A;SQUARE IU;So;0;ON;<square> 0049 0055;;;;N;;;;;
+337B;SQUARE ERA NAME HEISEI;So;0;L;<square> 5E73 6210;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME HEISEI;;;;
+337C;SQUARE ERA NAME SYOUWA;So;0;L;<square> 662D 548C;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME SYOUWA;;;;
+337D;SQUARE ERA NAME TAISYOU;So;0;L;<square> 5927 6B63;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME TAISYOU;;;;
+337E;SQUARE ERA NAME MEIZI;So;0;L;<square> 660E 6CBB;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME MEIZI;;;;
+337F;SQUARE CORPORATION;So;0;L;<square> 682A 5F0F 4F1A 793E;;;;N;SQUARED FOUR IDEOGRAPHS CORPORATION;;;;
+3380;SQUARE PA AMPS;So;0;L;<square> 0070 0041;;;;N;SQUARED PA AMPS;;;;
+3381;SQUARE NA;So;0;L;<square> 006E 0041;;;;N;SQUARED NA;;;;
+3382;SQUARE MU A;So;0;L;<square> 03BC 0041;;;;N;SQUARED MU A;;;;
+3383;SQUARE MA;So;0;L;<square> 006D 0041;;;;N;SQUARED MA;;;;
+3384;SQUARE KA;So;0;L;<square> 006B 0041;;;;N;SQUARED KA;;;;
+3385;SQUARE KB;So;0;L;<square> 004B 0042;;;;N;SQUARED KB;;;;
+3386;SQUARE MB;So;0;L;<square> 004D 0042;;;;N;SQUARED MB;;;;
+3387;SQUARE GB;So;0;L;<square> 0047 0042;;;;N;SQUARED GB;;;;
+3388;SQUARE CAL;So;0;L;<square> 0063 0061 006C;;;;N;SQUARED CAL;;;;
+3389;SQUARE KCAL;So;0;L;<square> 006B 0063 0061 006C;;;;N;SQUARED KCAL;;;;
+338A;SQUARE PF;So;0;L;<square> 0070 0046;;;;N;SQUARED PF;;;;
+338B;SQUARE NF;So;0;L;<square> 006E 0046;;;;N;SQUARED NF;;;;
+338C;SQUARE MU F;So;0;L;<square> 03BC 0046;;;;N;SQUARED MU F;;;;
+338D;SQUARE MU G;So;0;L;<square> 03BC 0067;;;;N;SQUARED MU G;;;;
+338E;SQUARE MG;So;0;L;<square> 006D 0067;;;;N;SQUARED MG;;;;
+338F;SQUARE KG;So;0;L;<square> 006B 0067;;;;N;SQUARED KG;;;;
+3390;SQUARE HZ;So;0;L;<square> 0048 007A;;;;N;SQUARED HZ;;;;
+3391;SQUARE KHZ;So;0;L;<square> 006B 0048 007A;;;;N;SQUARED KHZ;;;;
+3392;SQUARE MHZ;So;0;L;<square> 004D 0048 007A;;;;N;SQUARED MHZ;;;;
+3393;SQUARE GHZ;So;0;L;<square> 0047 0048 007A;;;;N;SQUARED GHZ;;;;
+3394;SQUARE THZ;So;0;L;<square> 0054 0048 007A;;;;N;SQUARED THZ;;;;
+3395;SQUARE MU L;So;0;L;<square> 03BC 2113;;;;N;SQUARED MU L;;;;
+3396;SQUARE ML;So;0;L;<square> 006D 2113;;;;N;SQUARED ML;;;;
+3397;SQUARE DL;So;0;L;<square> 0064 2113;;;;N;SQUARED DL;;;;
+3398;SQUARE KL;So;0;L;<square> 006B 2113;;;;N;SQUARED KL;;;;
+3399;SQUARE FM;So;0;L;<square> 0066 006D;;;;N;SQUARED FM;;;;
+339A;SQUARE NM;So;0;L;<square> 006E 006D;;;;N;SQUARED NM;;;;
+339B;SQUARE MU M;So;0;L;<square> 03BC 006D;;;;N;SQUARED MU M;;;;
+339C;SQUARE MM;So;0;L;<square> 006D 006D;;;;N;SQUARED MM;;;;
+339D;SQUARE CM;So;0;L;<square> 0063 006D;;;;N;SQUARED CM;;;;
+339E;SQUARE KM;So;0;L;<square> 006B 006D;;;;N;SQUARED KM;;;;
+339F;SQUARE MM SQUARED;So;0;L;<square> 006D 006D 00B2;;;;N;SQUARED MM SQUARED;;;;
+33A0;SQUARE CM SQUARED;So;0;L;<square> 0063 006D 00B2;;;;N;SQUARED CM SQUARED;;;;
+33A1;SQUARE M SQUARED;So;0;L;<square> 006D 00B2;;;;N;SQUARED M SQUARED;;;;
+33A2;SQUARE KM SQUARED;So;0;L;<square> 006B 006D 00B2;;;;N;SQUARED KM SQUARED;;;;
+33A3;SQUARE MM CUBED;So;0;L;<square> 006D 006D 00B3;;;;N;SQUARED MM CUBED;;;;
+33A4;SQUARE CM CUBED;So;0;L;<square> 0063 006D 00B3;;;;N;SQUARED CM CUBED;;;;
+33A5;SQUARE M CUBED;So;0;L;<square> 006D 00B3;;;;N;SQUARED M CUBED;;;;
+33A6;SQUARE KM CUBED;So;0;L;<square> 006B 006D 00B3;;;;N;SQUARED KM CUBED;;;;
+33A7;SQUARE M OVER S;So;0;L;<square> 006D 2215 0073;;;;N;SQUARED M OVER S;;;;
+33A8;SQUARE M OVER S SQUARED;So;0;L;<square> 006D 2215 0073 00B2;;;;N;SQUARED M OVER S SQUARED;;;;
+33A9;SQUARE PA;So;0;L;<square> 0050 0061;;;;N;SQUARED PA;;;;
+33AA;SQUARE KPA;So;0;L;<square> 006B 0050 0061;;;;N;SQUARED KPA;;;;
+33AB;SQUARE MPA;So;0;L;<square> 004D 0050 0061;;;;N;SQUARED MPA;;;;
+33AC;SQUARE GPA;So;0;L;<square> 0047 0050 0061;;;;N;SQUARED GPA;;;;
+33AD;SQUARE RAD;So;0;L;<square> 0072 0061 0064;;;;N;SQUARED RAD;;;;
+33AE;SQUARE RAD OVER S;So;0;L;<square> 0072 0061 0064 2215 0073;;;;N;SQUARED RAD OVER S;;;;
+33AF;SQUARE RAD OVER S SQUARED;So;0;L;<square> 0072 0061 0064 2215 0073 00B2;;;;N;SQUARED RAD OVER S SQUARED;;;;
+33B0;SQUARE PS;So;0;L;<square> 0070 0073;;;;N;SQUARED PS;;;;
+33B1;SQUARE NS;So;0;L;<square> 006E 0073;;;;N;SQUARED NS;;;;
+33B2;SQUARE MU S;So;0;L;<square> 03BC 0073;;;;N;SQUARED MU S;;;;
+33B3;SQUARE MS;So;0;L;<square> 006D 0073;;;;N;SQUARED MS;;;;
+33B4;SQUARE PV;So;0;L;<square> 0070 0056;;;;N;SQUARED PV;;;;
+33B5;SQUARE NV;So;0;L;<square> 006E 0056;;;;N;SQUARED NV;;;;
+33B6;SQUARE MU V;So;0;L;<square> 03BC 0056;;;;N;SQUARED MU V;;;;
+33B7;SQUARE MV;So;0;L;<square> 006D 0056;;;;N;SQUARED MV;;;;
+33B8;SQUARE KV;So;0;L;<square> 006B 0056;;;;N;SQUARED KV;;;;
+33B9;SQUARE MV MEGA;So;0;L;<square> 004D 0056;;;;N;SQUARED MV MEGA;;;;
+33BA;SQUARE PW;So;0;L;<square> 0070 0057;;;;N;SQUARED PW;;;;
+33BB;SQUARE NW;So;0;L;<square> 006E 0057;;;;N;SQUARED NW;;;;
+33BC;SQUARE MU W;So;0;L;<square> 03BC 0057;;;;N;SQUARED MU W;;;;
+33BD;SQUARE MW;So;0;L;<square> 006D 0057;;;;N;SQUARED MW;;;;
+33BE;SQUARE KW;So;0;L;<square> 006B 0057;;;;N;SQUARED KW;;;;
+33BF;SQUARE MW MEGA;So;0;L;<square> 004D 0057;;;;N;SQUARED MW MEGA;;;;
+33C0;SQUARE K OHM;So;0;L;<square> 006B 03A9;;;;N;SQUARED K OHM;;;;
+33C1;SQUARE M OHM;So;0;L;<square> 004D 03A9;;;;N;SQUARED M OHM;;;;
+33C2;SQUARE AM;So;0;L;<square> 0061 002E 006D 002E;;;;N;SQUARED AM;;;;
+33C3;SQUARE BQ;So;0;L;<square> 0042 0071;;;;N;SQUARED BQ;;;;
+33C4;SQUARE CC;So;0;L;<square> 0063 0063;;;;N;SQUARED CC;;;;
+33C5;SQUARE CD;So;0;L;<square> 0063 0064;;;;N;SQUARED CD;;;;
+33C6;SQUARE C OVER KG;So;0;L;<square> 0043 2215 006B 0067;;;;N;SQUARED C OVER KG;;;;
+33C7;SQUARE CO;So;0;L;<square> 0043 006F 002E;;;;N;SQUARED CO;;;;
+33C8;SQUARE DB;So;0;L;<square> 0064 0042;;;;N;SQUARED DB;;;;
+33C9;SQUARE GY;So;0;L;<square> 0047 0079;;;;N;SQUARED GY;;;;
+33CA;SQUARE HA;So;0;L;<square> 0068 0061;;;;N;SQUARED HA;;;;
+33CB;SQUARE HP;So;0;L;<square> 0048 0050;;;;N;SQUARED HP;;;;
+33CC;SQUARE IN;So;0;L;<square> 0069 006E;;;;N;SQUARED IN;;;;
+33CD;SQUARE KK;So;0;L;<square> 004B 004B;;;;N;SQUARED KK;;;;
+33CE;SQUARE KM CAPITAL;So;0;L;<square> 004B 004D;;;;N;SQUARED KM CAPITAL;;;;
+33CF;SQUARE KT;So;0;L;<square> 006B 0074;;;;N;SQUARED KT;;;;
+33D0;SQUARE LM;So;0;L;<square> 006C 006D;;;;N;SQUARED LM;;;;
+33D1;SQUARE LN;So;0;L;<square> 006C 006E;;;;N;SQUARED LN;;;;
+33D2;SQUARE LOG;So;0;L;<square> 006C 006F 0067;;;;N;SQUARED LOG;;;;
+33D3;SQUARE LX;So;0;L;<square> 006C 0078;;;;N;SQUARED LX;;;;
+33D4;SQUARE MB SMALL;So;0;L;<square> 006D 0062;;;;N;SQUARED MB SMALL;;;;
+33D5;SQUARE MIL;So;0;L;<square> 006D 0069 006C;;;;N;SQUARED MIL;;;;
+33D6;SQUARE MOL;So;0;L;<square> 006D 006F 006C;;;;N;SQUARED MOL;;;;
+33D7;SQUARE PH;So;0;L;<square> 0050 0048;;;;N;SQUARED PH;;;;
+33D8;SQUARE PM;So;0;L;<square> 0070 002E 006D 002E;;;;N;SQUARED PM;;;;
+33D9;SQUARE PPM;So;0;L;<square> 0050 0050 004D;;;;N;SQUARED PPM;;;;
+33DA;SQUARE PR;So;0;L;<square> 0050 0052;;;;N;SQUARED PR;;;;
+33DB;SQUARE SR;So;0;L;<square> 0073 0072;;;;N;SQUARED SR;;;;
+33DC;SQUARE SV;So;0;L;<square> 0053 0076;;;;N;SQUARED SV;;;;
+33DD;SQUARE WB;So;0;L;<square> 0057 0062;;;;N;SQUARED WB;;;;
+33DE;SQUARE V OVER M;So;0;ON;<square> 0056 2215 006D;;;;N;;;;;
+33DF;SQUARE A OVER M;So;0;ON;<square> 0041 2215 006D;;;;N;;;;;
+33E0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE;So;0;L;<compat> 0031 65E5;;;;N;;;;;
+33E1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO;So;0;L;<compat> 0032 65E5;;;;N;;;;;
+33E2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE;So;0;L;<compat> 0033 65E5;;;;N;;;;;
+33E3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR;So;0;L;<compat> 0034 65E5;;;;N;;;;;
+33E4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE;So;0;L;<compat> 0035 65E5;;;;N;;;;;
+33E5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX;So;0;L;<compat> 0036 65E5;;;;N;;;;;
+33E6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN;So;0;L;<compat> 0037 65E5;;;;N;;;;;
+33E7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT;So;0;L;<compat> 0038 65E5;;;;N;;;;;
+33E8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE;So;0;L;<compat> 0039 65E5;;;;N;;;;;
+33E9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN;So;0;L;<compat> 0031 0030 65E5;;;;N;;;;;
+33EA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN;So;0;L;<compat> 0031 0031 65E5;;;;N;;;;;
+33EB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE;So;0;L;<compat> 0031 0032 65E5;;;;N;;;;;
+33EC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN;So;0;L;<compat> 0031 0033 65E5;;;;N;;;;;
+33ED;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN;So;0;L;<compat> 0031 0034 65E5;;;;N;;;;;
+33EE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN;So;0;L;<compat> 0031 0035 65E5;;;;N;;;;;
+33EF;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN;So;0;L;<compat> 0031 0036 65E5;;;;N;;;;;
+33F0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN;So;0;L;<compat> 0031 0037 65E5;;;;N;;;;;
+33F1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN;So;0;L;<compat> 0031 0038 65E5;;;;N;;;;;
+33F2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN;So;0;L;<compat> 0031 0039 65E5;;;;N;;;;;
+33F3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY;So;0;L;<compat> 0032 0030 65E5;;;;N;;;;;
+33F4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE;So;0;L;<compat> 0032 0031 65E5;;;;N;;;;;
+33F5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO;So;0;L;<compat> 0032 0032 65E5;;;;N;;;;;
+33F6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE;So;0;L;<compat> 0032 0033 65E5;;;;N;;;;;
+33F7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR;So;0;L;<compat> 0032 0034 65E5;;;;N;;;;;
+33F8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE;So;0;L;<compat> 0032 0035 65E5;;;;N;;;;;
+33F9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX;So;0;L;<compat> 0032 0036 65E5;;;;N;;;;;
+33FA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN;So;0;L;<compat> 0032 0037 65E5;;;;N;;;;;
+33FB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT;So;0;L;<compat> 0032 0038 65E5;;;;N;;;;;
+33FC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE;So;0;L;<compat> 0032 0039 65E5;;;;N;;;;;
+33FD;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY;So;0;L;<compat> 0033 0030 65E5;;;;N;;;;;
+33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L;<compat> 0033 0031 65E5;;;;N;;;;;
+33FF;SQUARE GAL;So;0;ON;<square> 0067 0061 006C;;;;N;;;;;
+3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;
+4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;;
+4DC0;HEXAGRAM FOR THE CREATIVE HEAVEN;So;0;ON;;;;;N;;;;;
+4DC1;HEXAGRAM FOR THE RECEPTIVE EARTH;So;0;ON;;;;;N;;;;;
+4DC2;HEXAGRAM FOR DIFFICULTY AT THE BEGINNING;So;0;ON;;;;;N;;;;;
+4DC3;HEXAGRAM FOR YOUTHFUL FOLLY;So;0;ON;;;;;N;;;;;
+4DC4;HEXAGRAM FOR WAITING;So;0;ON;;;;;N;;;;;
+4DC5;HEXAGRAM FOR CONFLICT;So;0;ON;;;;;N;;;;;
+4DC6;HEXAGRAM FOR THE ARMY;So;0;ON;;;;;N;;;;;
+4DC7;HEXAGRAM FOR HOLDING TOGETHER;So;0;ON;;;;;N;;;;;
+4DC8;HEXAGRAM FOR SMALL TAMING;So;0;ON;;;;;N;;;;;
+4DC9;HEXAGRAM FOR TREADING;So;0;ON;;;;;N;;;;;
+4DCA;HEXAGRAM FOR PEACE;So;0;ON;;;;;N;;;;;
+4DCB;HEXAGRAM FOR STANDSTILL;So;0;ON;;;;;N;;;;;
+4DCC;HEXAGRAM FOR FELLOWSHIP;So;0;ON;;;;;N;;;;;
+4DCD;HEXAGRAM FOR GREAT POSSESSION;So;0;ON;;;;;N;;;;;
+4DCE;HEXAGRAM FOR MODESTY;So;0;ON;;;;;N;;;;;
+4DCF;HEXAGRAM FOR ENTHUSIASM;So;0;ON;;;;;N;;;;;
+4DD0;HEXAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;;
+4DD1;HEXAGRAM FOR WORK ON THE DECAYED;So;0;ON;;;;;N;;;;;
+4DD2;HEXAGRAM FOR APPROACH;So;0;ON;;;;;N;;;;;
+4DD3;HEXAGRAM FOR CONTEMPLATION;So;0;ON;;;;;N;;;;;
+4DD4;HEXAGRAM FOR BITING THROUGH;So;0;ON;;;;;N;;;;;
+4DD5;HEXAGRAM FOR GRACE;So;0;ON;;;;;N;;;;;
+4DD6;HEXAGRAM FOR SPLITTING APART;So;0;ON;;;;;N;;;;;
+4DD7;HEXAGRAM FOR RETURN;So;0;ON;;;;;N;;;;;
+4DD8;HEXAGRAM FOR INNOCENCE;So;0;ON;;;;;N;;;;;
+4DD9;HEXAGRAM FOR GREAT TAMING;So;0;ON;;;;;N;;;;;
+4DDA;HEXAGRAM FOR MOUTH CORNERS;So;0;ON;;;;;N;;;;;
+4DDB;HEXAGRAM FOR GREAT PREPONDERANCE;So;0;ON;;;;;N;;;;;
+4DDC;HEXAGRAM FOR THE ABYSMAL WATER;So;0;ON;;;;;N;;;;;
+4DDD;HEXAGRAM FOR THE CLINGING FIRE;So;0;ON;;;;;N;;;;;
+4DDE;HEXAGRAM FOR INFLUENCE;So;0;ON;;;;;N;;;;;
+4DDF;HEXAGRAM FOR DURATION;So;0;ON;;;;;N;;;;;
+4DE0;HEXAGRAM FOR RETREAT;So;0;ON;;;;;N;;;;;
+4DE1;HEXAGRAM FOR GREAT POWER;So;0;ON;;;;;N;;;;;
+4DE2;HEXAGRAM FOR PROGRESS;So;0;ON;;;;;N;;;;;
+4DE3;HEXAGRAM FOR DARKENING OF THE LIGHT;So;0;ON;;;;;N;;;;;
+4DE4;HEXAGRAM FOR THE FAMILY;So;0;ON;;;;;N;;;;;
+4DE5;HEXAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;;
+4DE6;HEXAGRAM FOR OBSTRUCTION;So;0;ON;;;;;N;;;;;
+4DE7;HEXAGRAM FOR DELIVERANCE;So;0;ON;;;;;N;;;;;
+4DE8;HEXAGRAM FOR DECREASE;So;0;ON;;;;;N;;;;;
+4DE9;HEXAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;;
+4DEA;HEXAGRAM FOR BREAKTHROUGH;So;0;ON;;;;;N;;;;;
+4DEB;HEXAGRAM FOR COMING TO MEET;So;0;ON;;;;;N;;;;;
+4DEC;HEXAGRAM FOR GATHERING TOGETHER;So;0;ON;;;;;N;;;;;
+4DED;HEXAGRAM FOR PUSHING UPWARD;So;0;ON;;;;;N;;;;;
+4DEE;HEXAGRAM FOR OPPRESSION;So;0;ON;;;;;N;;;;;
+4DEF;HEXAGRAM FOR THE WELL;So;0;ON;;;;;N;;;;;
+4DF0;HEXAGRAM FOR REVOLUTION;So;0;ON;;;;;N;;;;;
+4DF1;HEXAGRAM FOR THE CAULDRON;So;0;ON;;;;;N;;;;;
+4DF2;HEXAGRAM FOR THE AROUSING THUNDER;So;0;ON;;;;;N;;;;;
+4DF3;HEXAGRAM FOR THE KEEPING STILL MOUNTAIN;So;0;ON;;;;;N;;;;;
+4DF4;HEXAGRAM FOR DEVELOPMENT;So;0;ON;;;;;N;;;;;
+4DF5;HEXAGRAM FOR THE MARRYING MAIDEN;So;0;ON;;;;;N;;;;;
+4DF6;HEXAGRAM FOR ABUNDANCE;So;0;ON;;;;;N;;;;;
+4DF7;HEXAGRAM FOR THE WANDERER;So;0;ON;;;;;N;;;;;
+4DF8;HEXAGRAM FOR THE GENTLE WIND;So;0;ON;;;;;N;;;;;
+4DF9;HEXAGRAM FOR THE JOYOUS LAKE;So;0;ON;;;;;N;;;;;
+4DFA;HEXAGRAM FOR DISPERSION;So;0;ON;;;;;N;;;;;
+4DFB;HEXAGRAM FOR LIMITATION;So;0;ON;;;;;N;;;;;
+4DFC;HEXAGRAM FOR INNER TRUTH;So;0;ON;;;;;N;;;;;
+4DFD;HEXAGRAM FOR SMALL PREPONDERANCE;So;0;ON;;;;;N;;;;;
+4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;;
+4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;;
+4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
+9FD5;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
+A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;;
+A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;;
+A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;;
+A003;YI SYLLABLE IP;Lo;0;L;;;;;N;;;;;
+A004;YI SYLLABLE IET;Lo;0;L;;;;;N;;;;;
+A005;YI SYLLABLE IEX;Lo;0;L;;;;;N;;;;;
+A006;YI SYLLABLE IE;Lo;0;L;;;;;N;;;;;
+A007;YI SYLLABLE IEP;Lo;0;L;;;;;N;;;;;
+A008;YI SYLLABLE AT;Lo;0;L;;;;;N;;;;;
+A009;YI SYLLABLE AX;Lo;0;L;;;;;N;;;;;
+A00A;YI SYLLABLE A;Lo;0;L;;;;;N;;;;;
+A00B;YI SYLLABLE AP;Lo;0;L;;;;;N;;;;;
+A00C;YI SYLLABLE UOX;Lo;0;L;;;;;N;;;;;
+A00D;YI SYLLABLE UO;Lo;0;L;;;;;N;;;;;
+A00E;YI SYLLABLE UOP;Lo;0;L;;;;;N;;;;;
+A00F;YI SYLLABLE OT;Lo;0;L;;;;;N;;;;;
+A010;YI SYLLABLE OX;Lo;0;L;;;;;N;;;;;
+A011;YI SYLLABLE O;Lo;0;L;;;;;N;;;;;
+A012;YI SYLLABLE OP;Lo;0;L;;;;;N;;;;;
+A013;YI SYLLABLE EX;Lo;0;L;;;;;N;;;;;
+A014;YI SYLLABLE E;Lo;0;L;;;;;N;;;;;
+A015;YI SYLLABLE WU;Lm;0;L;;;;;N;;;;;
+A016;YI SYLLABLE BIT;Lo;0;L;;;;;N;;;;;
+A017;YI SYLLABLE BIX;Lo;0;L;;;;;N;;;;;
+A018;YI SYLLABLE BI;Lo;0;L;;;;;N;;;;;
+A019;YI SYLLABLE BIP;Lo;0;L;;;;;N;;;;;
+A01A;YI SYLLABLE BIET;Lo;0;L;;;;;N;;;;;
+A01B;YI SYLLABLE BIEX;Lo;0;L;;;;;N;;;;;
+A01C;YI SYLLABLE BIE;Lo;0;L;;;;;N;;;;;
+A01D;YI SYLLABLE BIEP;Lo;0;L;;;;;N;;;;;
+A01E;YI SYLLABLE BAT;Lo;0;L;;;;;N;;;;;
+A01F;YI SYLLABLE BAX;Lo;0;L;;;;;N;;;;;
+A020;YI SYLLABLE BA;Lo;0;L;;;;;N;;;;;
+A021;YI SYLLABLE BAP;Lo;0;L;;;;;N;;;;;
+A022;YI SYLLABLE BUOX;Lo;0;L;;;;;N;;;;;
+A023;YI SYLLABLE BUO;Lo;0;L;;;;;N;;;;;
+A024;YI SYLLABLE BUOP;Lo;0;L;;;;;N;;;;;
+A025;YI SYLLABLE BOT;Lo;0;L;;;;;N;;;;;
+A026;YI SYLLABLE BOX;Lo;0;L;;;;;N;;;;;
+A027;YI SYLLABLE BO;Lo;0;L;;;;;N;;;;;
+A028;YI SYLLABLE BOP;Lo;0;L;;;;;N;;;;;
+A029;YI SYLLABLE BEX;Lo;0;L;;;;;N;;;;;
+A02A;YI SYLLABLE BE;Lo;0;L;;;;;N;;;;;
+A02B;YI SYLLABLE BEP;Lo;0;L;;;;;N;;;;;
+A02C;YI SYLLABLE BUT;Lo;0;L;;;;;N;;;;;
+A02D;YI SYLLABLE BUX;Lo;0;L;;;;;N;;;;;
+A02E;YI SYLLABLE BU;Lo;0;L;;;;;N;;;;;
+A02F;YI SYLLABLE BUP;Lo;0;L;;;;;N;;;;;
+A030;YI SYLLABLE BURX;Lo;0;L;;;;;N;;;;;
+A031;YI SYLLABLE BUR;Lo;0;L;;;;;N;;;;;
+A032;YI SYLLABLE BYT;Lo;0;L;;;;;N;;;;;
+A033;YI SYLLABLE BYX;Lo;0;L;;;;;N;;;;;
+A034;YI SYLLABLE BY;Lo;0;L;;;;;N;;;;;
+A035;YI SYLLABLE BYP;Lo;0;L;;;;;N;;;;;
+A036;YI SYLLABLE BYRX;Lo;0;L;;;;;N;;;;;
+A037;YI SYLLABLE BYR;Lo;0;L;;;;;N;;;;;
+A038;YI SYLLABLE PIT;Lo;0;L;;;;;N;;;;;
+A039;YI SYLLABLE PIX;Lo;0;L;;;;;N;;;;;
+A03A;YI SYLLABLE PI;Lo;0;L;;;;;N;;;;;
+A03B;YI SYLLABLE PIP;Lo;0;L;;;;;N;;;;;
+A03C;YI SYLLABLE PIEX;Lo;0;L;;;;;N;;;;;
+A03D;YI SYLLABLE PIE;Lo;0;L;;;;;N;;;;;
+A03E;YI SYLLABLE PIEP;Lo;0;L;;;;;N;;;;;
+A03F;YI SYLLABLE PAT;Lo;0;L;;;;;N;;;;;
+A040;YI SYLLABLE PAX;Lo;0;L;;;;;N;;;;;
+A041;YI SYLLABLE PA;Lo;0;L;;;;;N;;;;;
+A042;YI SYLLABLE PAP;Lo;0;L;;;;;N;;;;;
+A043;YI SYLLABLE PUOX;Lo;0;L;;;;;N;;;;;
+A044;YI SYLLABLE PUO;Lo;0;L;;;;;N;;;;;
+A045;YI SYLLABLE PUOP;Lo;0;L;;;;;N;;;;;
+A046;YI SYLLABLE POT;Lo;0;L;;;;;N;;;;;
+A047;YI SYLLABLE POX;Lo;0;L;;;;;N;;;;;
+A048;YI SYLLABLE PO;Lo;0;L;;;;;N;;;;;
+A049;YI SYLLABLE POP;Lo;0;L;;;;;N;;;;;
+A04A;YI SYLLABLE PUT;Lo;0;L;;;;;N;;;;;
+A04B;YI SYLLABLE PUX;Lo;0;L;;;;;N;;;;;
+A04C;YI SYLLABLE PU;Lo;0;L;;;;;N;;;;;
+A04D;YI SYLLABLE PUP;Lo;0;L;;;;;N;;;;;
+A04E;YI SYLLABLE PURX;Lo;0;L;;;;;N;;;;;
+A04F;YI SYLLABLE PUR;Lo;0;L;;;;;N;;;;;
+A050;YI SYLLABLE PYT;Lo;0;L;;;;;N;;;;;
+A051;YI SYLLABLE PYX;Lo;0;L;;;;;N;;;;;
+A052;YI SYLLABLE PY;Lo;0;L;;;;;N;;;;;
+A053;YI SYLLABLE PYP;Lo;0;L;;;;;N;;;;;
+A054;YI SYLLABLE PYRX;Lo;0;L;;;;;N;;;;;
+A055;YI SYLLABLE PYR;Lo;0;L;;;;;N;;;;;
+A056;YI SYLLABLE BBIT;Lo;0;L;;;;;N;;;;;
+A057;YI SYLLABLE BBIX;Lo;0;L;;;;;N;;;;;
+A058;YI SYLLABLE BBI;Lo;0;L;;;;;N;;;;;
+A059;YI SYLLABLE BBIP;Lo;0;L;;;;;N;;;;;
+A05A;YI SYLLABLE BBIET;Lo;0;L;;;;;N;;;;;
+A05B;YI SYLLABLE BBIEX;Lo;0;L;;;;;N;;;;;
+A05C;YI SYLLABLE BBIE;Lo;0;L;;;;;N;;;;;
+A05D;YI SYLLABLE BBIEP;Lo;0;L;;;;;N;;;;;
+A05E;YI SYLLABLE BBAT;Lo;0;L;;;;;N;;;;;
+A05F;YI SYLLABLE BBAX;Lo;0;L;;;;;N;;;;;
+A060;YI SYLLABLE BBA;Lo;0;L;;;;;N;;;;;
+A061;YI SYLLABLE BBAP;Lo;0;L;;;;;N;;;;;
+A062;YI SYLLABLE BBUOX;Lo;0;L;;;;;N;;;;;
+A063;YI SYLLABLE BBUO;Lo;0;L;;;;;N;;;;;
+A064;YI SYLLABLE BBUOP;Lo;0;L;;;;;N;;;;;
+A065;YI SYLLABLE BBOT;Lo;0;L;;;;;N;;;;;
+A066;YI SYLLABLE BBOX;Lo;0;L;;;;;N;;;;;
+A067;YI SYLLABLE BBO;Lo;0;L;;;;;N;;;;;
+A068;YI SYLLABLE BBOP;Lo;0;L;;;;;N;;;;;
+A069;YI SYLLABLE BBEX;Lo;0;L;;;;;N;;;;;
+A06A;YI SYLLABLE BBE;Lo;0;L;;;;;N;;;;;
+A06B;YI SYLLABLE BBEP;Lo;0;L;;;;;N;;;;;
+A06C;YI SYLLABLE BBUT;Lo;0;L;;;;;N;;;;;
+A06D;YI SYLLABLE BBUX;Lo;0;L;;;;;N;;;;;
+A06E;YI SYLLABLE BBU;Lo;0;L;;;;;N;;;;;
+A06F;YI SYLLABLE BBUP;Lo;0;L;;;;;N;;;;;
+A070;YI SYLLABLE BBURX;Lo;0;L;;;;;N;;;;;
+A071;YI SYLLABLE BBUR;Lo;0;L;;;;;N;;;;;
+A072;YI SYLLABLE BBYT;Lo;0;L;;;;;N;;;;;
+A073;YI SYLLABLE BBYX;Lo;0;L;;;;;N;;;;;
+A074;YI SYLLABLE BBY;Lo;0;L;;;;;N;;;;;
+A075;YI SYLLABLE BBYP;Lo;0;L;;;;;N;;;;;
+A076;YI SYLLABLE NBIT;Lo;0;L;;;;;N;;;;;
+A077;YI SYLLABLE NBIX;Lo;0;L;;;;;N;;;;;
+A078;YI SYLLABLE NBI;Lo;0;L;;;;;N;;;;;
+A079;YI SYLLABLE NBIP;Lo;0;L;;;;;N;;;;;
+A07A;YI SYLLABLE NBIEX;Lo;0;L;;;;;N;;;;;
+A07B;YI SYLLABLE NBIE;Lo;0;L;;;;;N;;;;;
+A07C;YI SYLLABLE NBIEP;Lo;0;L;;;;;N;;;;;
+A07D;YI SYLLABLE NBAT;Lo;0;L;;;;;N;;;;;
+A07E;YI SYLLABLE NBAX;Lo;0;L;;;;;N;;;;;
+A07F;YI SYLLABLE NBA;Lo;0;L;;;;;N;;;;;
+A080;YI SYLLABLE NBAP;Lo;0;L;;;;;N;;;;;
+A081;YI SYLLABLE NBOT;Lo;0;L;;;;;N;;;;;
+A082;YI SYLLABLE NBOX;Lo;0;L;;;;;N;;;;;
+A083;YI SYLLABLE NBO;Lo;0;L;;;;;N;;;;;
+A084;YI SYLLABLE NBOP;Lo;0;L;;;;;N;;;;;
+A085;YI SYLLABLE NBUT;Lo;0;L;;;;;N;;;;;
+A086;YI SYLLABLE NBUX;Lo;0;L;;;;;N;;;;;
+A087;YI SYLLABLE NBU;Lo;0;L;;;;;N;;;;;
+A088;YI SYLLABLE NBUP;Lo;0;L;;;;;N;;;;;
+A089;YI SYLLABLE NBURX;Lo;0;L;;;;;N;;;;;
+A08A;YI SYLLABLE NBUR;Lo;0;L;;;;;N;;;;;
+A08B;YI SYLLABLE NBYT;Lo;0;L;;;;;N;;;;;
+A08C;YI SYLLABLE NBYX;Lo;0;L;;;;;N;;;;;
+A08D;YI SYLLABLE NBY;Lo;0;L;;;;;N;;;;;
+A08E;YI SYLLABLE NBYP;Lo;0;L;;;;;N;;;;;
+A08F;YI SYLLABLE NBYRX;Lo;0;L;;;;;N;;;;;
+A090;YI SYLLABLE NBYR;Lo;0;L;;;;;N;;;;;
+A091;YI SYLLABLE HMIT;Lo;0;L;;;;;N;;;;;
+A092;YI SYLLABLE HMIX;Lo;0;L;;;;;N;;;;;
+A093;YI SYLLABLE HMI;Lo;0;L;;;;;N;;;;;
+A094;YI SYLLABLE HMIP;Lo;0;L;;;;;N;;;;;
+A095;YI SYLLABLE HMIEX;Lo;0;L;;;;;N;;;;;
+A096;YI SYLLABLE HMIE;Lo;0;L;;;;;N;;;;;
+A097;YI SYLLABLE HMIEP;Lo;0;L;;;;;N;;;;;
+A098;YI SYLLABLE HMAT;Lo;0;L;;;;;N;;;;;
+A099;YI SYLLABLE HMAX;Lo;0;L;;;;;N;;;;;
+A09A;YI SYLLABLE HMA;Lo;0;L;;;;;N;;;;;
+A09B;YI SYLLABLE HMAP;Lo;0;L;;;;;N;;;;;
+A09C;YI SYLLABLE HMUOX;Lo;0;L;;;;;N;;;;;
+A09D;YI SYLLABLE HMUO;Lo;0;L;;;;;N;;;;;
+A09E;YI SYLLABLE HMUOP;Lo;0;L;;;;;N;;;;;
+A09F;YI SYLLABLE HMOT;Lo;0;L;;;;;N;;;;;
+A0A0;YI SYLLABLE HMOX;Lo;0;L;;;;;N;;;;;
+A0A1;YI SYLLABLE HMO;Lo;0;L;;;;;N;;;;;
+A0A2;YI SYLLABLE HMOP;Lo;0;L;;;;;N;;;;;
+A0A3;YI SYLLABLE HMUT;Lo;0;L;;;;;N;;;;;
+A0A4;YI SYLLABLE HMUX;Lo;0;L;;;;;N;;;;;
+A0A5;YI SYLLABLE HMU;Lo;0;L;;;;;N;;;;;
+A0A6;YI SYLLABLE HMUP;Lo;0;L;;;;;N;;;;;
+A0A7;YI SYLLABLE HMURX;Lo;0;L;;;;;N;;;;;
+A0A8;YI SYLLABLE HMUR;Lo;0;L;;;;;N;;;;;
+A0A9;YI SYLLABLE HMYX;Lo;0;L;;;;;N;;;;;
+A0AA;YI SYLLABLE HMY;Lo;0;L;;;;;N;;;;;
+A0AB;YI SYLLABLE HMYP;Lo;0;L;;;;;N;;;;;
+A0AC;YI SYLLABLE HMYRX;Lo;0;L;;;;;N;;;;;
+A0AD;YI SYLLABLE HMYR;Lo;0;L;;;;;N;;;;;
+A0AE;YI SYLLABLE MIT;Lo;0;L;;;;;N;;;;;
+A0AF;YI SYLLABLE MIX;Lo;0;L;;;;;N;;;;;
+A0B0;YI SYLLABLE MI;Lo;0;L;;;;;N;;;;;
+A0B1;YI SYLLABLE MIP;Lo;0;L;;;;;N;;;;;
+A0B2;YI SYLLABLE MIEX;Lo;0;L;;;;;N;;;;;
+A0B3;YI SYLLABLE MIE;Lo;0;L;;;;;N;;;;;
+A0B4;YI SYLLABLE MIEP;Lo;0;L;;;;;N;;;;;
+A0B5;YI SYLLABLE MAT;Lo;0;L;;;;;N;;;;;
+A0B6;YI SYLLABLE MAX;Lo;0;L;;;;;N;;;;;
+A0B7;YI SYLLABLE MA;Lo;0;L;;;;;N;;;;;
+A0B8;YI SYLLABLE MAP;Lo;0;L;;;;;N;;;;;
+A0B9;YI SYLLABLE MUOT;Lo;0;L;;;;;N;;;;;
+A0BA;YI SYLLABLE MUOX;Lo;0;L;;;;;N;;;;;
+A0BB;YI SYLLABLE MUO;Lo;0;L;;;;;N;;;;;
+A0BC;YI SYLLABLE MUOP;Lo;0;L;;;;;N;;;;;
+A0BD;YI SYLLABLE MOT;Lo;0;L;;;;;N;;;;;
+A0BE;YI SYLLABLE MOX;Lo;0;L;;;;;N;;;;;
+A0BF;YI SYLLABLE MO;Lo;0;L;;;;;N;;;;;
+A0C0;YI SYLLABLE MOP;Lo;0;L;;;;;N;;;;;
+A0C1;YI SYLLABLE MEX;Lo;0;L;;;;;N;;;;;
+A0C2;YI SYLLABLE ME;Lo;0;L;;;;;N;;;;;
+A0C3;YI SYLLABLE MUT;Lo;0;L;;;;;N;;;;;
+A0C4;YI SYLLABLE MUX;Lo;0;L;;;;;N;;;;;
+A0C5;YI SYLLABLE MU;Lo;0;L;;;;;N;;;;;
+A0C6;YI SYLLABLE MUP;Lo;0;L;;;;;N;;;;;
+A0C7;YI SYLLABLE MURX;Lo;0;L;;;;;N;;;;;
+A0C8;YI SYLLABLE MUR;Lo;0;L;;;;;N;;;;;
+A0C9;YI SYLLABLE MYT;Lo;0;L;;;;;N;;;;;
+A0CA;YI SYLLABLE MYX;Lo;0;L;;;;;N;;;;;
+A0CB;YI SYLLABLE MY;Lo;0;L;;;;;N;;;;;
+A0CC;YI SYLLABLE MYP;Lo;0;L;;;;;N;;;;;
+A0CD;YI SYLLABLE FIT;Lo;0;L;;;;;N;;;;;
+A0CE;YI SYLLABLE FIX;Lo;0;L;;;;;N;;;;;
+A0CF;YI SYLLABLE FI;Lo;0;L;;;;;N;;;;;
+A0D0;YI SYLLABLE FIP;Lo;0;L;;;;;N;;;;;
+A0D1;YI SYLLABLE FAT;Lo;0;L;;;;;N;;;;;
+A0D2;YI SYLLABLE FAX;Lo;0;L;;;;;N;;;;;
+A0D3;YI SYLLABLE FA;Lo;0;L;;;;;N;;;;;
+A0D4;YI SYLLABLE FAP;Lo;0;L;;;;;N;;;;;
+A0D5;YI SYLLABLE FOX;Lo;0;L;;;;;N;;;;;
+A0D6;YI SYLLABLE FO;Lo;0;L;;;;;N;;;;;
+A0D7;YI SYLLABLE FOP;Lo;0;L;;;;;N;;;;;
+A0D8;YI SYLLABLE FUT;Lo;0;L;;;;;N;;;;;
+A0D9;YI SYLLABLE FUX;Lo;0;L;;;;;N;;;;;
+A0DA;YI SYLLABLE FU;Lo;0;L;;;;;N;;;;;
+A0DB;YI SYLLABLE FUP;Lo;0;L;;;;;N;;;;;
+A0DC;YI SYLLABLE FURX;Lo;0;L;;;;;N;;;;;
+A0DD;YI SYLLABLE FUR;Lo;0;L;;;;;N;;;;;
+A0DE;YI SYLLABLE FYT;Lo;0;L;;;;;N;;;;;
+A0DF;YI SYLLABLE FYX;Lo;0;L;;;;;N;;;;;
+A0E0;YI SYLLABLE FY;Lo;0;L;;;;;N;;;;;
+A0E1;YI SYLLABLE FYP;Lo;0;L;;;;;N;;;;;
+A0E2;YI SYLLABLE VIT;Lo;0;L;;;;;N;;;;;
+A0E3;YI SYLLABLE VIX;Lo;0;L;;;;;N;;;;;
+A0E4;YI SYLLABLE VI;Lo;0;L;;;;;N;;;;;
+A0E5;YI SYLLABLE VIP;Lo;0;L;;;;;N;;;;;
+A0E6;YI SYLLABLE VIET;Lo;0;L;;;;;N;;;;;
+A0E7;YI SYLLABLE VIEX;Lo;0;L;;;;;N;;;;;
+A0E8;YI SYLLABLE VIE;Lo;0;L;;;;;N;;;;;
+A0E9;YI SYLLABLE VIEP;Lo;0;L;;;;;N;;;;;
+A0EA;YI SYLLABLE VAT;Lo;0;L;;;;;N;;;;;
+A0EB;YI SYLLABLE VAX;Lo;0;L;;;;;N;;;;;
+A0EC;YI SYLLABLE VA;Lo;0;L;;;;;N;;;;;
+A0ED;YI SYLLABLE VAP;Lo;0;L;;;;;N;;;;;
+A0EE;YI SYLLABLE VOT;Lo;0;L;;;;;N;;;;;
+A0EF;YI SYLLABLE VOX;Lo;0;L;;;;;N;;;;;
+A0F0;YI SYLLABLE VO;Lo;0;L;;;;;N;;;;;
+A0F1;YI SYLLABLE VOP;Lo;0;L;;;;;N;;;;;
+A0F2;YI SYLLABLE VEX;Lo;0;L;;;;;N;;;;;
+A0F3;YI SYLLABLE VEP;Lo;0;L;;;;;N;;;;;
+A0F4;YI SYLLABLE VUT;Lo;0;L;;;;;N;;;;;
+A0F5;YI SYLLABLE VUX;Lo;0;L;;;;;N;;;;;
+A0F6;YI SYLLABLE VU;Lo;0;L;;;;;N;;;;;
+A0F7;YI SYLLABLE VUP;Lo;0;L;;;;;N;;;;;
+A0F8;YI SYLLABLE VURX;Lo;0;L;;;;;N;;;;;
+A0F9;YI SYLLABLE VUR;Lo;0;L;;;;;N;;;;;
+A0FA;YI SYLLABLE VYT;Lo;0;L;;;;;N;;;;;
+A0FB;YI SYLLABLE VYX;Lo;0;L;;;;;N;;;;;
+A0FC;YI SYLLABLE VY;Lo;0;L;;;;;N;;;;;
+A0FD;YI SYLLABLE VYP;Lo;0;L;;;;;N;;;;;
+A0FE;YI SYLLABLE VYRX;Lo;0;L;;;;;N;;;;;
+A0FF;YI SYLLABLE VYR;Lo;0;L;;;;;N;;;;;
+A100;YI SYLLABLE DIT;Lo;0;L;;;;;N;;;;;
+A101;YI SYLLABLE DIX;Lo;0;L;;;;;N;;;;;
+A102;YI SYLLABLE DI;Lo;0;L;;;;;N;;;;;
+A103;YI SYLLABLE DIP;Lo;0;L;;;;;N;;;;;
+A104;YI SYLLABLE DIEX;Lo;0;L;;;;;N;;;;;
+A105;YI SYLLABLE DIE;Lo;0;L;;;;;N;;;;;
+A106;YI SYLLABLE DIEP;Lo;0;L;;;;;N;;;;;
+A107;YI SYLLABLE DAT;Lo;0;L;;;;;N;;;;;
+A108;YI SYLLABLE DAX;Lo;0;L;;;;;N;;;;;
+A109;YI SYLLABLE DA;Lo;0;L;;;;;N;;;;;
+A10A;YI SYLLABLE DAP;Lo;0;L;;;;;N;;;;;
+A10B;YI SYLLABLE DUOX;Lo;0;L;;;;;N;;;;;
+A10C;YI SYLLABLE DUO;Lo;0;L;;;;;N;;;;;
+A10D;YI SYLLABLE DOT;Lo;0;L;;;;;N;;;;;
+A10E;YI SYLLABLE DOX;Lo;0;L;;;;;N;;;;;
+A10F;YI SYLLABLE DO;Lo;0;L;;;;;N;;;;;
+A110;YI SYLLABLE DOP;Lo;0;L;;;;;N;;;;;
+A111;YI SYLLABLE DEX;Lo;0;L;;;;;N;;;;;
+A112;YI SYLLABLE DE;Lo;0;L;;;;;N;;;;;
+A113;YI SYLLABLE DEP;Lo;0;L;;;;;N;;;;;
+A114;YI SYLLABLE DUT;Lo;0;L;;;;;N;;;;;
+A115;YI SYLLABLE DUX;Lo;0;L;;;;;N;;;;;
+A116;YI SYLLABLE DU;Lo;0;L;;;;;N;;;;;
+A117;YI SYLLABLE DUP;Lo;0;L;;;;;N;;;;;
+A118;YI SYLLABLE DURX;Lo;0;L;;;;;N;;;;;
+A119;YI SYLLABLE DUR;Lo;0;L;;;;;N;;;;;
+A11A;YI SYLLABLE TIT;Lo;0;L;;;;;N;;;;;
+A11B;YI SYLLABLE TIX;Lo;0;L;;;;;N;;;;;
+A11C;YI SYLLABLE TI;Lo;0;L;;;;;N;;;;;
+A11D;YI SYLLABLE TIP;Lo;0;L;;;;;N;;;;;
+A11E;YI SYLLABLE TIEX;Lo;0;L;;;;;N;;;;;
+A11F;YI SYLLABLE TIE;Lo;0;L;;;;;N;;;;;
+A120;YI SYLLABLE TIEP;Lo;0;L;;;;;N;;;;;
+A121;YI SYLLABLE TAT;Lo;0;L;;;;;N;;;;;
+A122;YI SYLLABLE TAX;Lo;0;L;;;;;N;;;;;
+A123;YI SYLLABLE TA;Lo;0;L;;;;;N;;;;;
+A124;YI SYLLABLE TAP;Lo;0;L;;;;;N;;;;;
+A125;YI SYLLABLE TUOT;Lo;0;L;;;;;N;;;;;
+A126;YI SYLLABLE TUOX;Lo;0;L;;;;;N;;;;;
+A127;YI SYLLABLE TUO;Lo;0;L;;;;;N;;;;;
+A128;YI SYLLABLE TUOP;Lo;0;L;;;;;N;;;;;
+A129;YI SYLLABLE TOT;Lo;0;L;;;;;N;;;;;
+A12A;YI SYLLABLE TOX;Lo;0;L;;;;;N;;;;;
+A12B;YI SYLLABLE TO;Lo;0;L;;;;;N;;;;;
+A12C;YI SYLLABLE TOP;Lo;0;L;;;;;N;;;;;
+A12D;YI SYLLABLE TEX;Lo;0;L;;;;;N;;;;;
+A12E;YI SYLLABLE TE;Lo;0;L;;;;;N;;;;;
+A12F;YI SYLLABLE TEP;Lo;0;L;;;;;N;;;;;
+A130;YI SYLLABLE TUT;Lo;0;L;;;;;N;;;;;
+A131;YI SYLLABLE TUX;Lo;0;L;;;;;N;;;;;
+A132;YI SYLLABLE TU;Lo;0;L;;;;;N;;;;;
+A133;YI SYLLABLE TUP;Lo;0;L;;;;;N;;;;;
+A134;YI SYLLABLE TURX;Lo;0;L;;;;;N;;;;;
+A135;YI SYLLABLE TUR;Lo;0;L;;;;;N;;;;;
+A136;YI SYLLABLE DDIT;Lo;0;L;;;;;N;;;;;
+A137;YI SYLLABLE DDIX;Lo;0;L;;;;;N;;;;;
+A138;YI SYLLABLE DDI;Lo;0;L;;;;;N;;;;;
+A139;YI SYLLABLE DDIP;Lo;0;L;;;;;N;;;;;
+A13A;YI SYLLABLE DDIEX;Lo;0;L;;;;;N;;;;;
+A13B;YI SYLLABLE DDIE;Lo;0;L;;;;;N;;;;;
+A13C;YI SYLLABLE DDIEP;Lo;0;L;;;;;N;;;;;
+A13D;YI SYLLABLE DDAT;Lo;0;L;;;;;N;;;;;
+A13E;YI SYLLABLE DDAX;Lo;0;L;;;;;N;;;;;
+A13F;YI SYLLABLE DDA;Lo;0;L;;;;;N;;;;;
+A140;YI SYLLABLE DDAP;Lo;0;L;;;;;N;;;;;
+A141;YI SYLLABLE DDUOX;Lo;0;L;;;;;N;;;;;
+A142;YI SYLLABLE DDUO;Lo;0;L;;;;;N;;;;;
+A143;YI SYLLABLE DDUOP;Lo;0;L;;;;;N;;;;;
+A144;YI SYLLABLE DDOT;Lo;0;L;;;;;N;;;;;
+A145;YI SYLLABLE DDOX;Lo;0;L;;;;;N;;;;;
+A146;YI SYLLABLE DDO;Lo;0;L;;;;;N;;;;;
+A147;YI SYLLABLE DDOP;Lo;0;L;;;;;N;;;;;
+A148;YI SYLLABLE DDEX;Lo;0;L;;;;;N;;;;;
+A149;YI SYLLABLE DDE;Lo;0;L;;;;;N;;;;;
+A14A;YI SYLLABLE DDEP;Lo;0;L;;;;;N;;;;;
+A14B;YI SYLLABLE DDUT;Lo;0;L;;;;;N;;;;;
+A14C;YI SYLLABLE DDUX;Lo;0;L;;;;;N;;;;;
+A14D;YI SYLLABLE DDU;Lo;0;L;;;;;N;;;;;
+A14E;YI SYLLABLE DDUP;Lo;0;L;;;;;N;;;;;
+A14F;YI SYLLABLE DDURX;Lo;0;L;;;;;N;;;;;
+A150;YI SYLLABLE DDUR;Lo;0;L;;;;;N;;;;;
+A151;YI SYLLABLE NDIT;Lo;0;L;;;;;N;;;;;
+A152;YI SYLLABLE NDIX;Lo;0;L;;;;;N;;;;;
+A153;YI SYLLABLE NDI;Lo;0;L;;;;;N;;;;;
+A154;YI SYLLABLE NDIP;Lo;0;L;;;;;N;;;;;
+A155;YI SYLLABLE NDIEX;Lo;0;L;;;;;N;;;;;
+A156;YI SYLLABLE NDIE;Lo;0;L;;;;;N;;;;;
+A157;YI SYLLABLE NDAT;Lo;0;L;;;;;N;;;;;
+A158;YI SYLLABLE NDAX;Lo;0;L;;;;;N;;;;;
+A159;YI SYLLABLE NDA;Lo;0;L;;;;;N;;;;;
+A15A;YI SYLLABLE NDAP;Lo;0;L;;;;;N;;;;;
+A15B;YI SYLLABLE NDOT;Lo;0;L;;;;;N;;;;;
+A15C;YI SYLLABLE NDOX;Lo;0;L;;;;;N;;;;;
+A15D;YI SYLLABLE NDO;Lo;0;L;;;;;N;;;;;
+A15E;YI SYLLABLE NDOP;Lo;0;L;;;;;N;;;;;
+A15F;YI SYLLABLE NDEX;Lo;0;L;;;;;N;;;;;
+A160;YI SYLLABLE NDE;Lo;0;L;;;;;N;;;;;
+A161;YI SYLLABLE NDEP;Lo;0;L;;;;;N;;;;;
+A162;YI SYLLABLE NDUT;Lo;0;L;;;;;N;;;;;
+A163;YI SYLLABLE NDUX;Lo;0;L;;;;;N;;;;;
+A164;YI SYLLABLE NDU;Lo;0;L;;;;;N;;;;;
+A165;YI SYLLABLE NDUP;Lo;0;L;;;;;N;;;;;
+A166;YI SYLLABLE NDURX;Lo;0;L;;;;;N;;;;;
+A167;YI SYLLABLE NDUR;Lo;0;L;;;;;N;;;;;
+A168;YI SYLLABLE HNIT;Lo;0;L;;;;;N;;;;;
+A169;YI SYLLABLE HNIX;Lo;0;L;;;;;N;;;;;
+A16A;YI SYLLABLE HNI;Lo;0;L;;;;;N;;;;;
+A16B;YI SYLLABLE HNIP;Lo;0;L;;;;;N;;;;;
+A16C;YI SYLLABLE HNIET;Lo;0;L;;;;;N;;;;;
+A16D;YI SYLLABLE HNIEX;Lo;0;L;;;;;N;;;;;
+A16E;YI SYLLABLE HNIE;Lo;0;L;;;;;N;;;;;
+A16F;YI SYLLABLE HNIEP;Lo;0;L;;;;;N;;;;;
+A170;YI SYLLABLE HNAT;Lo;0;L;;;;;N;;;;;
+A171;YI SYLLABLE HNAX;Lo;0;L;;;;;N;;;;;
+A172;YI SYLLABLE HNA;Lo;0;L;;;;;N;;;;;
+A173;YI SYLLABLE HNAP;Lo;0;L;;;;;N;;;;;
+A174;YI SYLLABLE HNUOX;Lo;0;L;;;;;N;;;;;
+A175;YI SYLLABLE HNUO;Lo;0;L;;;;;N;;;;;
+A176;YI SYLLABLE HNOT;Lo;0;L;;;;;N;;;;;
+A177;YI SYLLABLE HNOX;Lo;0;L;;;;;N;;;;;
+A178;YI SYLLABLE HNOP;Lo;0;L;;;;;N;;;;;
+A179;YI SYLLABLE HNEX;Lo;0;L;;;;;N;;;;;
+A17A;YI SYLLABLE HNE;Lo;0;L;;;;;N;;;;;
+A17B;YI SYLLABLE HNEP;Lo;0;L;;;;;N;;;;;
+A17C;YI SYLLABLE HNUT;Lo;0;L;;;;;N;;;;;
+A17D;YI SYLLABLE NIT;Lo;0;L;;;;;N;;;;;
+A17E;YI SYLLABLE NIX;Lo;0;L;;;;;N;;;;;
+A17F;YI SYLLABLE NI;Lo;0;L;;;;;N;;;;;
+A180;YI SYLLABLE NIP;Lo;0;L;;;;;N;;;;;
+A181;YI SYLLABLE NIEX;Lo;0;L;;;;;N;;;;;
+A182;YI SYLLABLE NIE;Lo;0;L;;;;;N;;;;;
+A183;YI SYLLABLE NIEP;Lo;0;L;;;;;N;;;;;
+A184;YI SYLLABLE NAX;Lo;0;L;;;;;N;;;;;
+A185;YI SYLLABLE NA;Lo;0;L;;;;;N;;;;;
+A186;YI SYLLABLE NAP;Lo;0;L;;;;;N;;;;;
+A187;YI SYLLABLE NUOX;Lo;0;L;;;;;N;;;;;
+A188;YI SYLLABLE NUO;Lo;0;L;;;;;N;;;;;
+A189;YI SYLLABLE NUOP;Lo;0;L;;;;;N;;;;;
+A18A;YI SYLLABLE NOT;Lo;0;L;;;;;N;;;;;
+A18B;YI SYLLABLE NOX;Lo;0;L;;;;;N;;;;;
+A18C;YI SYLLABLE NO;Lo;0;L;;;;;N;;;;;
+A18D;YI SYLLABLE NOP;Lo;0;L;;;;;N;;;;;
+A18E;YI SYLLABLE NEX;Lo;0;L;;;;;N;;;;;
+A18F;YI SYLLABLE NE;Lo;0;L;;;;;N;;;;;
+A190;YI SYLLABLE NEP;Lo;0;L;;;;;N;;;;;
+A191;YI SYLLABLE NUT;Lo;0;L;;;;;N;;;;;
+A192;YI SYLLABLE NUX;Lo;0;L;;;;;N;;;;;
+A193;YI SYLLABLE NU;Lo;0;L;;;;;N;;;;;
+A194;YI SYLLABLE NUP;Lo;0;L;;;;;N;;;;;
+A195;YI SYLLABLE NURX;Lo;0;L;;;;;N;;;;;
+A196;YI SYLLABLE NUR;Lo;0;L;;;;;N;;;;;
+A197;YI SYLLABLE HLIT;Lo;0;L;;;;;N;;;;;
+A198;YI SYLLABLE HLIX;Lo;0;L;;;;;N;;;;;
+A199;YI SYLLABLE HLI;Lo;0;L;;;;;N;;;;;
+A19A;YI SYLLABLE HLIP;Lo;0;L;;;;;N;;;;;
+A19B;YI SYLLABLE HLIEX;Lo;0;L;;;;;N;;;;;
+A19C;YI SYLLABLE HLIE;Lo;0;L;;;;;N;;;;;
+A19D;YI SYLLABLE HLIEP;Lo;0;L;;;;;N;;;;;
+A19E;YI SYLLABLE HLAT;Lo;0;L;;;;;N;;;;;
+A19F;YI SYLLABLE HLAX;Lo;0;L;;;;;N;;;;;
+A1A0;YI SYLLABLE HLA;Lo;0;L;;;;;N;;;;;
+A1A1;YI SYLLABLE HLAP;Lo;0;L;;;;;N;;;;;
+A1A2;YI SYLLABLE HLUOX;Lo;0;L;;;;;N;;;;;
+A1A3;YI SYLLABLE HLUO;Lo;0;L;;;;;N;;;;;
+A1A4;YI SYLLABLE HLUOP;Lo;0;L;;;;;N;;;;;
+A1A5;YI SYLLABLE HLOX;Lo;0;L;;;;;N;;;;;
+A1A6;YI SYLLABLE HLO;Lo;0;L;;;;;N;;;;;
+A1A7;YI SYLLABLE HLOP;Lo;0;L;;;;;N;;;;;
+A1A8;YI SYLLABLE HLEX;Lo;0;L;;;;;N;;;;;
+A1A9;YI SYLLABLE HLE;Lo;0;L;;;;;N;;;;;
+A1AA;YI SYLLABLE HLEP;Lo;0;L;;;;;N;;;;;
+A1AB;YI SYLLABLE HLUT;Lo;0;L;;;;;N;;;;;
+A1AC;YI SYLLABLE HLUX;Lo;0;L;;;;;N;;;;;
+A1AD;YI SYLLABLE HLU;Lo;0;L;;;;;N;;;;;
+A1AE;YI SYLLABLE HLUP;Lo;0;L;;;;;N;;;;;
+A1AF;YI SYLLABLE HLURX;Lo;0;L;;;;;N;;;;;
+A1B0;YI SYLLABLE HLUR;Lo;0;L;;;;;N;;;;;
+A1B1;YI SYLLABLE HLYT;Lo;0;L;;;;;N;;;;;
+A1B2;YI SYLLABLE HLYX;Lo;0;L;;;;;N;;;;;
+A1B3;YI SYLLABLE HLY;Lo;0;L;;;;;N;;;;;
+A1B4;YI SYLLABLE HLYP;Lo;0;L;;;;;N;;;;;
+A1B5;YI SYLLABLE HLYRX;Lo;0;L;;;;;N;;;;;
+A1B6;YI SYLLABLE HLYR;Lo;0;L;;;;;N;;;;;
+A1B7;YI SYLLABLE LIT;Lo;0;L;;;;;N;;;;;
+A1B8;YI SYLLABLE LIX;Lo;0;L;;;;;N;;;;;
+A1B9;YI SYLLABLE LI;Lo;0;L;;;;;N;;;;;
+A1BA;YI SYLLABLE LIP;Lo;0;L;;;;;N;;;;;
+A1BB;YI SYLLABLE LIET;Lo;0;L;;;;;N;;;;;
+A1BC;YI SYLLABLE LIEX;Lo;0;L;;;;;N;;;;;
+A1BD;YI SYLLABLE LIE;Lo;0;L;;;;;N;;;;;
+A1BE;YI SYLLABLE LIEP;Lo;0;L;;;;;N;;;;;
+A1BF;YI SYLLABLE LAT;Lo;0;L;;;;;N;;;;;
+A1C0;YI SYLLABLE LAX;Lo;0;L;;;;;N;;;;;
+A1C1;YI SYLLABLE LA;Lo;0;L;;;;;N;;;;;
+A1C2;YI SYLLABLE LAP;Lo;0;L;;;;;N;;;;;
+A1C3;YI SYLLABLE LUOT;Lo;0;L;;;;;N;;;;;
+A1C4;YI SYLLABLE LUOX;Lo;0;L;;;;;N;;;;;
+A1C5;YI SYLLABLE LUO;Lo;0;L;;;;;N;;;;;
+A1C6;YI SYLLABLE LUOP;Lo;0;L;;;;;N;;;;;
+A1C7;YI SYLLABLE LOT;Lo;0;L;;;;;N;;;;;
+A1C8;YI SYLLABLE LOX;Lo;0;L;;;;;N;;;;;
+A1C9;YI SYLLABLE LO;Lo;0;L;;;;;N;;;;;
+A1CA;YI SYLLABLE LOP;Lo;0;L;;;;;N;;;;;
+A1CB;YI SYLLABLE LEX;Lo;0;L;;;;;N;;;;;
+A1CC;YI SYLLABLE LE;Lo;0;L;;;;;N;;;;;
+A1CD;YI SYLLABLE LEP;Lo;0;L;;;;;N;;;;;
+A1CE;YI SYLLABLE LUT;Lo;0;L;;;;;N;;;;;
+A1CF;YI SYLLABLE LUX;Lo;0;L;;;;;N;;;;;
+A1D0;YI SYLLABLE LU;Lo;0;L;;;;;N;;;;;
+A1D1;YI SYLLABLE LUP;Lo;0;L;;;;;N;;;;;
+A1D2;YI SYLLABLE LURX;Lo;0;L;;;;;N;;;;;
+A1D3;YI SYLLABLE LUR;Lo;0;L;;;;;N;;;;;
+A1D4;YI SYLLABLE LYT;Lo;0;L;;;;;N;;;;;
+A1D5;YI SYLLABLE LYX;Lo;0;L;;;;;N;;;;;
+A1D6;YI SYLLABLE LY;Lo;0;L;;;;;N;;;;;
+A1D7;YI SYLLABLE LYP;Lo;0;L;;;;;N;;;;;
+A1D8;YI SYLLABLE LYRX;Lo;0;L;;;;;N;;;;;
+A1D9;YI SYLLABLE LYR;Lo;0;L;;;;;N;;;;;
+A1DA;YI SYLLABLE GIT;Lo;0;L;;;;;N;;;;;
+A1DB;YI SYLLABLE GIX;Lo;0;L;;;;;N;;;;;
+A1DC;YI SYLLABLE GI;Lo;0;L;;;;;N;;;;;
+A1DD;YI SYLLABLE GIP;Lo;0;L;;;;;N;;;;;
+A1DE;YI SYLLABLE GIET;Lo;0;L;;;;;N;;;;;
+A1DF;YI SYLLABLE GIEX;Lo;0;L;;;;;N;;;;;
+A1E0;YI SYLLABLE GIE;Lo;0;L;;;;;N;;;;;
+A1E1;YI SYLLABLE GIEP;Lo;0;L;;;;;N;;;;;
+A1E2;YI SYLLABLE GAT;Lo;0;L;;;;;N;;;;;
+A1E3;YI SYLLABLE GAX;Lo;0;L;;;;;N;;;;;
+A1E4;YI SYLLABLE GA;Lo;0;L;;;;;N;;;;;
+A1E5;YI SYLLABLE GAP;Lo;0;L;;;;;N;;;;;
+A1E6;YI SYLLABLE GUOT;Lo;0;L;;;;;N;;;;;
+A1E7;YI SYLLABLE GUOX;Lo;0;L;;;;;N;;;;;
+A1E8;YI SYLLABLE GUO;Lo;0;L;;;;;N;;;;;
+A1E9;YI SYLLABLE GUOP;Lo;0;L;;;;;N;;;;;
+A1EA;YI SYLLABLE GOT;Lo;0;L;;;;;N;;;;;
+A1EB;YI SYLLABLE GOX;Lo;0;L;;;;;N;;;;;
+A1EC;YI SYLLABLE GO;Lo;0;L;;;;;N;;;;;
+A1ED;YI SYLLABLE GOP;Lo;0;L;;;;;N;;;;;
+A1EE;YI SYLLABLE GET;Lo;0;L;;;;;N;;;;;
+A1EF;YI SYLLABLE GEX;Lo;0;L;;;;;N;;;;;
+A1F0;YI SYLLABLE GE;Lo;0;L;;;;;N;;;;;
+A1F1;YI SYLLABLE GEP;Lo;0;L;;;;;N;;;;;
+A1F2;YI SYLLABLE GUT;Lo;0;L;;;;;N;;;;;
+A1F3;YI SYLLABLE GUX;Lo;0;L;;;;;N;;;;;
+A1F4;YI SYLLABLE GU;Lo;0;L;;;;;N;;;;;
+A1F5;YI SYLLABLE GUP;Lo;0;L;;;;;N;;;;;
+A1F6;YI SYLLABLE GURX;Lo;0;L;;;;;N;;;;;
+A1F7;YI SYLLABLE GUR;Lo;0;L;;;;;N;;;;;
+A1F8;YI SYLLABLE KIT;Lo;0;L;;;;;N;;;;;
+A1F9;YI SYLLABLE KIX;Lo;0;L;;;;;N;;;;;
+A1FA;YI SYLLABLE KI;Lo;0;L;;;;;N;;;;;
+A1FB;YI SYLLABLE KIP;Lo;0;L;;;;;N;;;;;
+A1FC;YI SYLLABLE KIEX;Lo;0;L;;;;;N;;;;;
+A1FD;YI SYLLABLE KIE;Lo;0;L;;;;;N;;;;;
+A1FE;YI SYLLABLE KIEP;Lo;0;L;;;;;N;;;;;
+A1FF;YI SYLLABLE KAT;Lo;0;L;;;;;N;;;;;
+A200;YI SYLLABLE KAX;Lo;0;L;;;;;N;;;;;
+A201;YI SYLLABLE KA;Lo;0;L;;;;;N;;;;;
+A202;YI SYLLABLE KAP;Lo;0;L;;;;;N;;;;;
+A203;YI SYLLABLE KUOX;Lo;0;L;;;;;N;;;;;
+A204;YI SYLLABLE KUO;Lo;0;L;;;;;N;;;;;
+A205;YI SYLLABLE KUOP;Lo;0;L;;;;;N;;;;;
+A206;YI SYLLABLE KOT;Lo;0;L;;;;;N;;;;;
+A207;YI SYLLABLE KOX;Lo;0;L;;;;;N;;;;;
+A208;YI SYLLABLE KO;Lo;0;L;;;;;N;;;;;
+A209;YI SYLLABLE KOP;Lo;0;L;;;;;N;;;;;
+A20A;YI SYLLABLE KET;Lo;0;L;;;;;N;;;;;
+A20B;YI SYLLABLE KEX;Lo;0;L;;;;;N;;;;;
+A20C;YI SYLLABLE KE;Lo;0;L;;;;;N;;;;;
+A20D;YI SYLLABLE KEP;Lo;0;L;;;;;N;;;;;
+A20E;YI SYLLABLE KUT;Lo;0;L;;;;;N;;;;;
+A20F;YI SYLLABLE KUX;Lo;0;L;;;;;N;;;;;
+A210;YI SYLLABLE KU;Lo;0;L;;;;;N;;;;;
+A211;YI SYLLABLE KUP;Lo;0;L;;;;;N;;;;;
+A212;YI SYLLABLE KURX;Lo;0;L;;;;;N;;;;;
+A213;YI SYLLABLE KUR;Lo;0;L;;;;;N;;;;;
+A214;YI SYLLABLE GGIT;Lo;0;L;;;;;N;;;;;
+A215;YI SYLLABLE GGIX;Lo;0;L;;;;;N;;;;;
+A216;YI SYLLABLE GGI;Lo;0;L;;;;;N;;;;;
+A217;YI SYLLABLE GGIEX;Lo;0;L;;;;;N;;;;;
+A218;YI SYLLABLE GGIE;Lo;0;L;;;;;N;;;;;
+A219;YI SYLLABLE GGIEP;Lo;0;L;;;;;N;;;;;
+A21A;YI SYLLABLE GGAT;Lo;0;L;;;;;N;;;;;
+A21B;YI SYLLABLE GGAX;Lo;0;L;;;;;N;;;;;
+A21C;YI SYLLABLE GGA;Lo;0;L;;;;;N;;;;;
+A21D;YI SYLLABLE GGAP;Lo;0;L;;;;;N;;;;;
+A21E;YI SYLLABLE GGUOT;Lo;0;L;;;;;N;;;;;
+A21F;YI SYLLABLE GGUOX;Lo;0;L;;;;;N;;;;;
+A220;YI SYLLABLE GGUO;Lo;0;L;;;;;N;;;;;
+A221;YI SYLLABLE GGUOP;Lo;0;L;;;;;N;;;;;
+A222;YI SYLLABLE GGOT;Lo;0;L;;;;;N;;;;;
+A223;YI SYLLABLE GGOX;Lo;0;L;;;;;N;;;;;
+A224;YI SYLLABLE GGO;Lo;0;L;;;;;N;;;;;
+A225;YI SYLLABLE GGOP;Lo;0;L;;;;;N;;;;;
+A226;YI SYLLABLE GGET;Lo;0;L;;;;;N;;;;;
+A227;YI SYLLABLE GGEX;Lo;0;L;;;;;N;;;;;
+A228;YI SYLLABLE GGE;Lo;0;L;;;;;N;;;;;
+A229;YI SYLLABLE GGEP;Lo;0;L;;;;;N;;;;;
+A22A;YI SYLLABLE GGUT;Lo;0;L;;;;;N;;;;;
+A22B;YI SYLLABLE GGUX;Lo;0;L;;;;;N;;;;;
+A22C;YI SYLLABLE GGU;Lo;0;L;;;;;N;;;;;
+A22D;YI SYLLABLE GGUP;Lo;0;L;;;;;N;;;;;
+A22E;YI SYLLABLE GGURX;Lo;0;L;;;;;N;;;;;
+A22F;YI SYLLABLE GGUR;Lo;0;L;;;;;N;;;;;
+A230;YI SYLLABLE MGIEX;Lo;0;L;;;;;N;;;;;
+A231;YI SYLLABLE MGIE;Lo;0;L;;;;;N;;;;;
+A232;YI SYLLABLE MGAT;Lo;0;L;;;;;N;;;;;
+A233;YI SYLLABLE MGAX;Lo;0;L;;;;;N;;;;;
+A234;YI SYLLABLE MGA;Lo;0;L;;;;;N;;;;;
+A235;YI SYLLABLE MGAP;Lo;0;L;;;;;N;;;;;
+A236;YI SYLLABLE MGUOX;Lo;0;L;;;;;N;;;;;
+A237;YI SYLLABLE MGUO;Lo;0;L;;;;;N;;;;;
+A238;YI SYLLABLE MGUOP;Lo;0;L;;;;;N;;;;;
+A239;YI SYLLABLE MGOT;Lo;0;L;;;;;N;;;;;
+A23A;YI SYLLABLE MGOX;Lo;0;L;;;;;N;;;;;
+A23B;YI SYLLABLE MGO;Lo;0;L;;;;;N;;;;;
+A23C;YI SYLLABLE MGOP;Lo;0;L;;;;;N;;;;;
+A23D;YI SYLLABLE MGEX;Lo;0;L;;;;;N;;;;;
+A23E;YI SYLLABLE MGE;Lo;0;L;;;;;N;;;;;
+A23F;YI SYLLABLE MGEP;Lo;0;L;;;;;N;;;;;
+A240;YI SYLLABLE MGUT;Lo;0;L;;;;;N;;;;;
+A241;YI SYLLABLE MGUX;Lo;0;L;;;;;N;;;;;
+A242;YI SYLLABLE MGU;Lo;0;L;;;;;N;;;;;
+A243;YI SYLLABLE MGUP;Lo;0;L;;;;;N;;;;;
+A244;YI SYLLABLE MGURX;Lo;0;L;;;;;N;;;;;
+A245;YI SYLLABLE MGUR;Lo;0;L;;;;;N;;;;;
+A246;YI SYLLABLE HXIT;Lo;0;L;;;;;N;;;;;
+A247;YI SYLLABLE HXIX;Lo;0;L;;;;;N;;;;;
+A248;YI SYLLABLE HXI;Lo;0;L;;;;;N;;;;;
+A249;YI SYLLABLE HXIP;Lo;0;L;;;;;N;;;;;
+A24A;YI SYLLABLE HXIET;Lo;0;L;;;;;N;;;;;
+A24B;YI SYLLABLE HXIEX;Lo;0;L;;;;;N;;;;;
+A24C;YI SYLLABLE HXIE;Lo;0;L;;;;;N;;;;;
+A24D;YI SYLLABLE HXIEP;Lo;0;L;;;;;N;;;;;
+A24E;YI SYLLABLE HXAT;Lo;0;L;;;;;N;;;;;
+A24F;YI SYLLABLE HXAX;Lo;0;L;;;;;N;;;;;
+A250;YI SYLLABLE HXA;Lo;0;L;;;;;N;;;;;
+A251;YI SYLLABLE HXAP;Lo;0;L;;;;;N;;;;;
+A252;YI SYLLABLE HXUOT;Lo;0;L;;;;;N;;;;;
+A253;YI SYLLABLE HXUOX;Lo;0;L;;;;;N;;;;;
+A254;YI SYLLABLE HXUO;Lo;0;L;;;;;N;;;;;
+A255;YI SYLLABLE HXUOP;Lo;0;L;;;;;N;;;;;
+A256;YI SYLLABLE HXOT;Lo;0;L;;;;;N;;;;;
+A257;YI SYLLABLE HXOX;Lo;0;L;;;;;N;;;;;
+A258;YI SYLLABLE HXO;Lo;0;L;;;;;N;;;;;
+A259;YI SYLLABLE HXOP;Lo;0;L;;;;;N;;;;;
+A25A;YI SYLLABLE HXEX;Lo;0;L;;;;;N;;;;;
+A25B;YI SYLLABLE HXE;Lo;0;L;;;;;N;;;;;
+A25C;YI SYLLABLE HXEP;Lo;0;L;;;;;N;;;;;
+A25D;YI SYLLABLE NGIEX;Lo;0;L;;;;;N;;;;;
+A25E;YI SYLLABLE NGIE;Lo;0;L;;;;;N;;;;;
+A25F;YI SYLLABLE NGIEP;Lo;0;L;;;;;N;;;;;
+A260;YI SYLLABLE NGAT;Lo;0;L;;;;;N;;;;;
+A261;YI SYLLABLE NGAX;Lo;0;L;;;;;N;;;;;
+A262;YI SYLLABLE NGA;Lo;0;L;;;;;N;;;;;
+A263;YI SYLLABLE NGAP;Lo;0;L;;;;;N;;;;;
+A264;YI SYLLABLE NGUOT;Lo;0;L;;;;;N;;;;;
+A265;YI SYLLABLE NGUOX;Lo;0;L;;;;;N;;;;;
+A266;YI SYLLABLE NGUO;Lo;0;L;;;;;N;;;;;
+A267;YI SYLLABLE NGOT;Lo;0;L;;;;;N;;;;;
+A268;YI SYLLABLE NGOX;Lo;0;L;;;;;N;;;;;
+A269;YI SYLLABLE NGO;Lo;0;L;;;;;N;;;;;
+A26A;YI SYLLABLE NGOP;Lo;0;L;;;;;N;;;;;
+A26B;YI SYLLABLE NGEX;Lo;0;L;;;;;N;;;;;
+A26C;YI SYLLABLE NGE;Lo;0;L;;;;;N;;;;;
+A26D;YI SYLLABLE NGEP;Lo;0;L;;;;;N;;;;;
+A26E;YI SYLLABLE HIT;Lo;0;L;;;;;N;;;;;
+A26F;YI SYLLABLE HIEX;Lo;0;L;;;;;N;;;;;
+A270;YI SYLLABLE HIE;Lo;0;L;;;;;N;;;;;
+A271;YI SYLLABLE HAT;Lo;0;L;;;;;N;;;;;
+A272;YI SYLLABLE HAX;Lo;0;L;;;;;N;;;;;
+A273;YI SYLLABLE HA;Lo;0;L;;;;;N;;;;;
+A274;YI SYLLABLE HAP;Lo;0;L;;;;;N;;;;;
+A275;YI SYLLABLE HUOT;Lo;0;L;;;;;N;;;;;
+A276;YI SYLLABLE HUOX;Lo;0;L;;;;;N;;;;;
+A277;YI SYLLABLE HUO;Lo;0;L;;;;;N;;;;;
+A278;YI SYLLABLE HUOP;Lo;0;L;;;;;N;;;;;
+A279;YI SYLLABLE HOT;Lo;0;L;;;;;N;;;;;
+A27A;YI SYLLABLE HOX;Lo;0;L;;;;;N;;;;;
+A27B;YI SYLLABLE HO;Lo;0;L;;;;;N;;;;;
+A27C;YI SYLLABLE HOP;Lo;0;L;;;;;N;;;;;
+A27D;YI SYLLABLE HEX;Lo;0;L;;;;;N;;;;;
+A27E;YI SYLLABLE HE;Lo;0;L;;;;;N;;;;;
+A27F;YI SYLLABLE HEP;Lo;0;L;;;;;N;;;;;
+A280;YI SYLLABLE WAT;Lo;0;L;;;;;N;;;;;
+A281;YI SYLLABLE WAX;Lo;0;L;;;;;N;;;;;
+A282;YI SYLLABLE WA;Lo;0;L;;;;;N;;;;;
+A283;YI SYLLABLE WAP;Lo;0;L;;;;;N;;;;;
+A284;YI SYLLABLE WUOX;Lo;0;L;;;;;N;;;;;
+A285;YI SYLLABLE WUO;Lo;0;L;;;;;N;;;;;
+A286;YI SYLLABLE WUOP;Lo;0;L;;;;;N;;;;;
+A287;YI SYLLABLE WOX;Lo;0;L;;;;;N;;;;;
+A288;YI SYLLABLE WO;Lo;0;L;;;;;N;;;;;
+A289;YI SYLLABLE WOP;Lo;0;L;;;;;N;;;;;
+A28A;YI SYLLABLE WEX;Lo;0;L;;;;;N;;;;;
+A28B;YI SYLLABLE WE;Lo;0;L;;;;;N;;;;;
+A28C;YI SYLLABLE WEP;Lo;0;L;;;;;N;;;;;
+A28D;YI SYLLABLE ZIT;Lo;0;L;;;;;N;;;;;
+A28E;YI SYLLABLE ZIX;Lo;0;L;;;;;N;;;;;
+A28F;YI SYLLABLE ZI;Lo;0;L;;;;;N;;;;;
+A290;YI SYLLABLE ZIP;Lo;0;L;;;;;N;;;;;
+A291;YI SYLLABLE ZIEX;Lo;0;L;;;;;N;;;;;
+A292;YI SYLLABLE ZIE;Lo;0;L;;;;;N;;;;;
+A293;YI SYLLABLE ZIEP;Lo;0;L;;;;;N;;;;;
+A294;YI SYLLABLE ZAT;Lo;0;L;;;;;N;;;;;
+A295;YI SYLLABLE ZAX;Lo;0;L;;;;;N;;;;;
+A296;YI SYLLABLE ZA;Lo;0;L;;;;;N;;;;;
+A297;YI SYLLABLE ZAP;Lo;0;L;;;;;N;;;;;
+A298;YI SYLLABLE ZUOX;Lo;0;L;;;;;N;;;;;
+A299;YI SYLLABLE ZUO;Lo;0;L;;;;;N;;;;;
+A29A;YI SYLLABLE ZUOP;Lo;0;L;;;;;N;;;;;
+A29B;YI SYLLABLE ZOT;Lo;0;L;;;;;N;;;;;
+A29C;YI SYLLABLE ZOX;Lo;0;L;;;;;N;;;;;
+A29D;YI SYLLABLE ZO;Lo;0;L;;;;;N;;;;;
+A29E;YI SYLLABLE ZOP;Lo;0;L;;;;;N;;;;;
+A29F;YI SYLLABLE ZEX;Lo;0;L;;;;;N;;;;;
+A2A0;YI SYLLABLE ZE;Lo;0;L;;;;;N;;;;;
+A2A1;YI SYLLABLE ZEP;Lo;0;L;;;;;N;;;;;
+A2A2;YI SYLLABLE ZUT;Lo;0;L;;;;;N;;;;;
+A2A3;YI SYLLABLE ZUX;Lo;0;L;;;;;N;;;;;
+A2A4;YI SYLLABLE ZU;Lo;0;L;;;;;N;;;;;
+A2A5;YI SYLLABLE ZUP;Lo;0;L;;;;;N;;;;;
+A2A6;YI SYLLABLE ZURX;Lo;0;L;;;;;N;;;;;
+A2A7;YI SYLLABLE ZUR;Lo;0;L;;;;;N;;;;;
+A2A8;YI SYLLABLE ZYT;Lo;0;L;;;;;N;;;;;
+A2A9;YI SYLLABLE ZYX;Lo;0;L;;;;;N;;;;;
+A2AA;YI SYLLABLE ZY;Lo;0;L;;;;;N;;;;;
+A2AB;YI SYLLABLE ZYP;Lo;0;L;;;;;N;;;;;
+A2AC;YI SYLLABLE ZYRX;Lo;0;L;;;;;N;;;;;
+A2AD;YI SYLLABLE ZYR;Lo;0;L;;;;;N;;;;;
+A2AE;YI SYLLABLE CIT;Lo;0;L;;;;;N;;;;;
+A2AF;YI SYLLABLE CIX;Lo;0;L;;;;;N;;;;;
+A2B0;YI SYLLABLE CI;Lo;0;L;;;;;N;;;;;
+A2B1;YI SYLLABLE CIP;Lo;0;L;;;;;N;;;;;
+A2B2;YI SYLLABLE CIET;Lo;0;L;;;;;N;;;;;
+A2B3;YI SYLLABLE CIEX;Lo;0;L;;;;;N;;;;;
+A2B4;YI SYLLABLE CIE;Lo;0;L;;;;;N;;;;;
+A2B5;YI SYLLABLE CIEP;Lo;0;L;;;;;N;;;;;
+A2B6;YI SYLLABLE CAT;Lo;0;L;;;;;N;;;;;
+A2B7;YI SYLLABLE CAX;Lo;0;L;;;;;N;;;;;
+A2B8;YI SYLLABLE CA;Lo;0;L;;;;;N;;;;;
+A2B9;YI SYLLABLE CAP;Lo;0;L;;;;;N;;;;;
+A2BA;YI SYLLABLE CUOX;Lo;0;L;;;;;N;;;;;
+A2BB;YI SYLLABLE CUO;Lo;0;L;;;;;N;;;;;
+A2BC;YI SYLLABLE CUOP;Lo;0;L;;;;;N;;;;;
+A2BD;YI SYLLABLE COT;Lo;0;L;;;;;N;;;;;
+A2BE;YI SYLLABLE COX;Lo;0;L;;;;;N;;;;;
+A2BF;YI SYLLABLE CO;Lo;0;L;;;;;N;;;;;
+A2C0;YI SYLLABLE COP;Lo;0;L;;;;;N;;;;;
+A2C1;YI SYLLABLE CEX;Lo;0;L;;;;;N;;;;;
+A2C2;YI SYLLABLE CE;Lo;0;L;;;;;N;;;;;
+A2C3;YI SYLLABLE CEP;Lo;0;L;;;;;N;;;;;
+A2C4;YI SYLLABLE CUT;Lo;0;L;;;;;N;;;;;
+A2C5;YI SYLLABLE CUX;Lo;0;L;;;;;N;;;;;
+A2C6;YI SYLLABLE CU;Lo;0;L;;;;;N;;;;;
+A2C7;YI SYLLABLE CUP;Lo;0;L;;;;;N;;;;;
+A2C8;YI SYLLABLE CURX;Lo;0;L;;;;;N;;;;;
+A2C9;YI SYLLABLE CUR;Lo;0;L;;;;;N;;;;;
+A2CA;YI SYLLABLE CYT;Lo;0;L;;;;;N;;;;;
+A2CB;YI SYLLABLE CYX;Lo;0;L;;;;;N;;;;;
+A2CC;YI SYLLABLE CY;Lo;0;L;;;;;N;;;;;
+A2CD;YI SYLLABLE CYP;Lo;0;L;;;;;N;;;;;
+A2CE;YI SYLLABLE CYRX;Lo;0;L;;;;;N;;;;;
+A2CF;YI SYLLABLE CYR;Lo;0;L;;;;;N;;;;;
+A2D0;YI SYLLABLE ZZIT;Lo;0;L;;;;;N;;;;;
+A2D1;YI SYLLABLE ZZIX;Lo;0;L;;;;;N;;;;;
+A2D2;YI SYLLABLE ZZI;Lo;0;L;;;;;N;;;;;
+A2D3;YI SYLLABLE ZZIP;Lo;0;L;;;;;N;;;;;
+A2D4;YI SYLLABLE ZZIET;Lo;0;L;;;;;N;;;;;
+A2D5;YI SYLLABLE ZZIEX;Lo;0;L;;;;;N;;;;;
+A2D6;YI SYLLABLE ZZIE;Lo;0;L;;;;;N;;;;;
+A2D7;YI SYLLABLE ZZIEP;Lo;0;L;;;;;N;;;;;
+A2D8;YI SYLLABLE ZZAT;Lo;0;L;;;;;N;;;;;
+A2D9;YI SYLLABLE ZZAX;Lo;0;L;;;;;N;;;;;
+A2DA;YI SYLLABLE ZZA;Lo;0;L;;;;;N;;;;;
+A2DB;YI SYLLABLE ZZAP;Lo;0;L;;;;;N;;;;;
+A2DC;YI SYLLABLE ZZOX;Lo;0;L;;;;;N;;;;;
+A2DD;YI SYLLABLE ZZO;Lo;0;L;;;;;N;;;;;
+A2DE;YI SYLLABLE ZZOP;Lo;0;L;;;;;N;;;;;
+A2DF;YI SYLLABLE ZZEX;Lo;0;L;;;;;N;;;;;
+A2E0;YI SYLLABLE ZZE;Lo;0;L;;;;;N;;;;;
+A2E1;YI SYLLABLE ZZEP;Lo;0;L;;;;;N;;;;;
+A2E2;YI SYLLABLE ZZUX;Lo;0;L;;;;;N;;;;;
+A2E3;YI SYLLABLE ZZU;Lo;0;L;;;;;N;;;;;
+A2E4;YI SYLLABLE ZZUP;Lo;0;L;;;;;N;;;;;
+A2E5;YI SYLLABLE ZZURX;Lo;0;L;;;;;N;;;;;
+A2E6;YI SYLLABLE ZZUR;Lo;0;L;;;;;N;;;;;
+A2E7;YI SYLLABLE ZZYT;Lo;0;L;;;;;N;;;;;
+A2E8;YI SYLLABLE ZZYX;Lo;0;L;;;;;N;;;;;
+A2E9;YI SYLLABLE ZZY;Lo;0;L;;;;;N;;;;;
+A2EA;YI SYLLABLE ZZYP;Lo;0;L;;;;;N;;;;;
+A2EB;YI SYLLABLE ZZYRX;Lo;0;L;;;;;N;;;;;
+A2EC;YI SYLLABLE ZZYR;Lo;0;L;;;;;N;;;;;
+A2ED;YI SYLLABLE NZIT;Lo;0;L;;;;;N;;;;;
+A2EE;YI SYLLABLE NZIX;Lo;0;L;;;;;N;;;;;
+A2EF;YI SYLLABLE NZI;Lo;0;L;;;;;N;;;;;
+A2F0;YI SYLLABLE NZIP;Lo;0;L;;;;;N;;;;;
+A2F1;YI SYLLABLE NZIEX;Lo;0;L;;;;;N;;;;;
+A2F2;YI SYLLABLE NZIE;Lo;0;L;;;;;N;;;;;
+A2F3;YI SYLLABLE NZIEP;Lo;0;L;;;;;N;;;;;
+A2F4;YI SYLLABLE NZAT;Lo;0;L;;;;;N;;;;;
+A2F5;YI SYLLABLE NZAX;Lo;0;L;;;;;N;;;;;
+A2F6;YI SYLLABLE NZA;Lo;0;L;;;;;N;;;;;
+A2F7;YI SYLLABLE NZAP;Lo;0;L;;;;;N;;;;;
+A2F8;YI SYLLABLE NZUOX;Lo;0;L;;;;;N;;;;;
+A2F9;YI SYLLABLE NZUO;Lo;0;L;;;;;N;;;;;
+A2FA;YI SYLLABLE NZOX;Lo;0;L;;;;;N;;;;;
+A2FB;YI SYLLABLE NZOP;Lo;0;L;;;;;N;;;;;
+A2FC;YI SYLLABLE NZEX;Lo;0;L;;;;;N;;;;;
+A2FD;YI SYLLABLE NZE;Lo;0;L;;;;;N;;;;;
+A2FE;YI SYLLABLE NZUX;Lo;0;L;;;;;N;;;;;
+A2FF;YI SYLLABLE NZU;Lo;0;L;;;;;N;;;;;
+A300;YI SYLLABLE NZUP;Lo;0;L;;;;;N;;;;;
+A301;YI SYLLABLE NZURX;Lo;0;L;;;;;N;;;;;
+A302;YI SYLLABLE NZUR;Lo;0;L;;;;;N;;;;;
+A303;YI SYLLABLE NZYT;Lo;0;L;;;;;N;;;;;
+A304;YI SYLLABLE NZYX;Lo;0;L;;;;;N;;;;;
+A305;YI SYLLABLE NZY;Lo;0;L;;;;;N;;;;;
+A306;YI SYLLABLE NZYP;Lo;0;L;;;;;N;;;;;
+A307;YI SYLLABLE NZYRX;Lo;0;L;;;;;N;;;;;
+A308;YI SYLLABLE NZYR;Lo;0;L;;;;;N;;;;;
+A309;YI SYLLABLE SIT;Lo;0;L;;;;;N;;;;;
+A30A;YI SYLLABLE SIX;Lo;0;L;;;;;N;;;;;
+A30B;YI SYLLABLE SI;Lo;0;L;;;;;N;;;;;
+A30C;YI SYLLABLE SIP;Lo;0;L;;;;;N;;;;;
+A30D;YI SYLLABLE SIEX;Lo;0;L;;;;;N;;;;;
+A30E;YI SYLLABLE SIE;Lo;0;L;;;;;N;;;;;
+A30F;YI SYLLABLE SIEP;Lo;0;L;;;;;N;;;;;
+A310;YI SYLLABLE SAT;Lo;0;L;;;;;N;;;;;
+A311;YI SYLLABLE SAX;Lo;0;L;;;;;N;;;;;
+A312;YI SYLLABLE SA;Lo;0;L;;;;;N;;;;;
+A313;YI SYLLABLE SAP;Lo;0;L;;;;;N;;;;;
+A314;YI SYLLABLE SUOX;Lo;0;L;;;;;N;;;;;
+A315;YI SYLLABLE SUO;Lo;0;L;;;;;N;;;;;
+A316;YI SYLLABLE SUOP;Lo;0;L;;;;;N;;;;;
+A317;YI SYLLABLE SOT;Lo;0;L;;;;;N;;;;;
+A318;YI SYLLABLE SOX;Lo;0;L;;;;;N;;;;;
+A319;YI SYLLABLE SO;Lo;0;L;;;;;N;;;;;
+A31A;YI SYLLABLE SOP;Lo;0;L;;;;;N;;;;;
+A31B;YI SYLLABLE SEX;Lo;0;L;;;;;N;;;;;
+A31C;YI SYLLABLE SE;Lo;0;L;;;;;N;;;;;
+A31D;YI SYLLABLE SEP;Lo;0;L;;;;;N;;;;;
+A31E;YI SYLLABLE SUT;Lo;0;L;;;;;N;;;;;
+A31F;YI SYLLABLE SUX;Lo;0;L;;;;;N;;;;;
+A320;YI SYLLABLE SU;Lo;0;L;;;;;N;;;;;
+A321;YI SYLLABLE SUP;Lo;0;L;;;;;N;;;;;
+A322;YI SYLLABLE SURX;Lo;0;L;;;;;N;;;;;
+A323;YI SYLLABLE SUR;Lo;0;L;;;;;N;;;;;
+A324;YI SYLLABLE SYT;Lo;0;L;;;;;N;;;;;
+A325;YI SYLLABLE SYX;Lo;0;L;;;;;N;;;;;
+A326;YI SYLLABLE SY;Lo;0;L;;;;;N;;;;;
+A327;YI SYLLABLE SYP;Lo;0;L;;;;;N;;;;;
+A328;YI SYLLABLE SYRX;Lo;0;L;;;;;N;;;;;
+A329;YI SYLLABLE SYR;Lo;0;L;;;;;N;;;;;
+A32A;YI SYLLABLE SSIT;Lo;0;L;;;;;N;;;;;
+A32B;YI SYLLABLE SSIX;Lo;0;L;;;;;N;;;;;
+A32C;YI SYLLABLE SSI;Lo;0;L;;;;;N;;;;;
+A32D;YI SYLLABLE SSIP;Lo;0;L;;;;;N;;;;;
+A32E;YI SYLLABLE SSIEX;Lo;0;L;;;;;N;;;;;
+A32F;YI SYLLABLE SSIE;Lo;0;L;;;;;N;;;;;
+A330;YI SYLLABLE SSIEP;Lo;0;L;;;;;N;;;;;
+A331;YI SYLLABLE SSAT;Lo;0;L;;;;;N;;;;;
+A332;YI SYLLABLE SSAX;Lo;0;L;;;;;N;;;;;
+A333;YI SYLLABLE SSA;Lo;0;L;;;;;N;;;;;
+A334;YI SYLLABLE SSAP;Lo;0;L;;;;;N;;;;;
+A335;YI SYLLABLE SSOT;Lo;0;L;;;;;N;;;;;
+A336;YI SYLLABLE SSOX;Lo;0;L;;;;;N;;;;;
+A337;YI SYLLABLE SSO;Lo;0;L;;;;;N;;;;;
+A338;YI SYLLABLE SSOP;Lo;0;L;;;;;N;;;;;
+A339;YI SYLLABLE SSEX;Lo;0;L;;;;;N;;;;;
+A33A;YI SYLLABLE SSE;Lo;0;L;;;;;N;;;;;
+A33B;YI SYLLABLE SSEP;Lo;0;L;;;;;N;;;;;
+A33C;YI SYLLABLE SSUT;Lo;0;L;;;;;N;;;;;
+A33D;YI SYLLABLE SSUX;Lo;0;L;;;;;N;;;;;
+A33E;YI SYLLABLE SSU;Lo;0;L;;;;;N;;;;;
+A33F;YI SYLLABLE SSUP;Lo;0;L;;;;;N;;;;;
+A340;YI SYLLABLE SSYT;Lo;0;L;;;;;N;;;;;
+A341;YI SYLLABLE SSYX;Lo;0;L;;;;;N;;;;;
+A342;YI SYLLABLE SSY;Lo;0;L;;;;;N;;;;;
+A343;YI SYLLABLE SSYP;Lo;0;L;;;;;N;;;;;
+A344;YI SYLLABLE SSYRX;Lo;0;L;;;;;N;;;;;
+A345;YI SYLLABLE SSYR;Lo;0;L;;;;;N;;;;;
+A346;YI SYLLABLE ZHAT;Lo;0;L;;;;;N;;;;;
+A347;YI SYLLABLE ZHAX;Lo;0;L;;;;;N;;;;;
+A348;YI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;
+A349;YI SYLLABLE ZHAP;Lo;0;L;;;;;N;;;;;
+A34A;YI SYLLABLE ZHUOX;Lo;0;L;;;;;N;;;;;
+A34B;YI SYLLABLE ZHUO;Lo;0;L;;;;;N;;;;;
+A34C;YI SYLLABLE ZHUOP;Lo;0;L;;;;;N;;;;;
+A34D;YI SYLLABLE ZHOT;Lo;0;L;;;;;N;;;;;
+A34E;YI SYLLABLE ZHOX;Lo;0;L;;;;;N;;;;;
+A34F;YI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;
+A350;YI SYLLABLE ZHOP;Lo;0;L;;;;;N;;;;;
+A351;YI SYLLABLE ZHET;Lo;0;L;;;;;N;;;;;
+A352;YI SYLLABLE ZHEX;Lo;0;L;;;;;N;;;;;
+A353;YI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;
+A354;YI SYLLABLE ZHEP;Lo;0;L;;;;;N;;;;;
+A355;YI SYLLABLE ZHUT;Lo;0;L;;;;;N;;;;;
+A356;YI SYLLABLE ZHUX;Lo;0;L;;;;;N;;;;;
+A357;YI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;
+A358;YI SYLLABLE ZHUP;Lo;0;L;;;;;N;;;;;
+A359;YI SYLLABLE ZHURX;Lo;0;L;;;;;N;;;;;
+A35A;YI SYLLABLE ZHUR;Lo;0;L;;;;;N;;;;;
+A35B;YI SYLLABLE ZHYT;Lo;0;L;;;;;N;;;;;
+A35C;YI SYLLABLE ZHYX;Lo;0;L;;;;;N;;;;;
+A35D;YI SYLLABLE ZHY;Lo;0;L;;;;;N;;;;;
+A35E;YI SYLLABLE ZHYP;Lo;0;L;;;;;N;;;;;
+A35F;YI SYLLABLE ZHYRX;Lo;0;L;;;;;N;;;;;
+A360;YI SYLLABLE ZHYR;Lo;0;L;;;;;N;;;;;
+A361;YI SYLLABLE CHAT;Lo;0;L;;;;;N;;;;;
+A362;YI SYLLABLE CHAX;Lo;0;L;;;;;N;;;;;
+A363;YI SYLLABLE CHA;Lo;0;L;;;;;N;;;;;
+A364;YI SYLLABLE CHAP;Lo;0;L;;;;;N;;;;;
+A365;YI SYLLABLE CHUOT;Lo;0;L;;;;;N;;;;;
+A366;YI SYLLABLE CHUOX;Lo;0;L;;;;;N;;;;;
+A367;YI SYLLABLE CHUO;Lo;0;L;;;;;N;;;;;
+A368;YI SYLLABLE CHUOP;Lo;0;L;;;;;N;;;;;
+A369;YI SYLLABLE CHOT;Lo;0;L;;;;;N;;;;;
+A36A;YI SYLLABLE CHOX;Lo;0;L;;;;;N;;;;;
+A36B;YI SYLLABLE CHO;Lo;0;L;;;;;N;;;;;
+A36C;YI SYLLABLE CHOP;Lo;0;L;;;;;N;;;;;
+A36D;YI SYLLABLE CHET;Lo;0;L;;;;;N;;;;;
+A36E;YI SYLLABLE CHEX;Lo;0;L;;;;;N;;;;;
+A36F;YI SYLLABLE CHE;Lo;0;L;;;;;N;;;;;
+A370;YI SYLLABLE CHEP;Lo;0;L;;;;;N;;;;;
+A371;YI SYLLABLE CHUX;Lo;0;L;;;;;N;;;;;
+A372;YI SYLLABLE CHU;Lo;0;L;;;;;N;;;;;
+A373;YI SYLLABLE CHUP;Lo;0;L;;;;;N;;;;;
+A374;YI SYLLABLE CHURX;Lo;0;L;;;;;N;;;;;
+A375;YI SYLLABLE CHUR;Lo;0;L;;;;;N;;;;;
+A376;YI SYLLABLE CHYT;Lo;0;L;;;;;N;;;;;
+A377;YI SYLLABLE CHYX;Lo;0;L;;;;;N;;;;;
+A378;YI SYLLABLE CHY;Lo;0;L;;;;;N;;;;;
+A379;YI SYLLABLE CHYP;Lo;0;L;;;;;N;;;;;
+A37A;YI SYLLABLE CHYRX;Lo;0;L;;;;;N;;;;;
+A37B;YI SYLLABLE CHYR;Lo;0;L;;;;;N;;;;;
+A37C;YI SYLLABLE RRAX;Lo;0;L;;;;;N;;;;;
+A37D;YI SYLLABLE RRA;Lo;0;L;;;;;N;;;;;
+A37E;YI SYLLABLE RRUOX;Lo;0;L;;;;;N;;;;;
+A37F;YI SYLLABLE RRUO;Lo;0;L;;;;;N;;;;;
+A380;YI SYLLABLE RROT;Lo;0;L;;;;;N;;;;;
+A381;YI SYLLABLE RROX;Lo;0;L;;;;;N;;;;;
+A382;YI SYLLABLE RRO;Lo;0;L;;;;;N;;;;;
+A383;YI SYLLABLE RROP;Lo;0;L;;;;;N;;;;;
+A384;YI SYLLABLE RRET;Lo;0;L;;;;;N;;;;;
+A385;YI SYLLABLE RREX;Lo;0;L;;;;;N;;;;;
+A386;YI SYLLABLE RRE;Lo;0;L;;;;;N;;;;;
+A387;YI SYLLABLE RREP;Lo;0;L;;;;;N;;;;;
+A388;YI SYLLABLE RRUT;Lo;0;L;;;;;N;;;;;
+A389;YI SYLLABLE RRUX;Lo;0;L;;;;;N;;;;;
+A38A;YI SYLLABLE RRU;Lo;0;L;;;;;N;;;;;
+A38B;YI SYLLABLE RRUP;Lo;0;L;;;;;N;;;;;
+A38C;YI SYLLABLE RRURX;Lo;0;L;;;;;N;;;;;
+A38D;YI SYLLABLE RRUR;Lo;0;L;;;;;N;;;;;
+A38E;YI SYLLABLE RRYT;Lo;0;L;;;;;N;;;;;
+A38F;YI SYLLABLE RRYX;Lo;0;L;;;;;N;;;;;
+A390;YI SYLLABLE RRY;Lo;0;L;;;;;N;;;;;
+A391;YI SYLLABLE RRYP;Lo;0;L;;;;;N;;;;;
+A392;YI SYLLABLE RRYRX;Lo;0;L;;;;;N;;;;;
+A393;YI SYLLABLE RRYR;Lo;0;L;;;;;N;;;;;
+A394;YI SYLLABLE NRAT;Lo;0;L;;;;;N;;;;;
+A395;YI SYLLABLE NRAX;Lo;0;L;;;;;N;;;;;
+A396;YI SYLLABLE NRA;Lo;0;L;;;;;N;;;;;
+A397;YI SYLLABLE NRAP;Lo;0;L;;;;;N;;;;;
+A398;YI SYLLABLE NROX;Lo;0;L;;;;;N;;;;;
+A399;YI SYLLABLE NRO;Lo;0;L;;;;;N;;;;;
+A39A;YI SYLLABLE NROP;Lo;0;L;;;;;N;;;;;
+A39B;YI SYLLABLE NRET;Lo;0;L;;;;;N;;;;;
+A39C;YI SYLLABLE NREX;Lo;0;L;;;;;N;;;;;
+A39D;YI SYLLABLE NRE;Lo;0;L;;;;;N;;;;;
+A39E;YI SYLLABLE NREP;Lo;0;L;;;;;N;;;;;
+A39F;YI SYLLABLE NRUT;Lo;0;L;;;;;N;;;;;
+A3A0;YI SYLLABLE NRUX;Lo;0;L;;;;;N;;;;;
+A3A1;YI SYLLABLE NRU;Lo;0;L;;;;;N;;;;;
+A3A2;YI SYLLABLE NRUP;Lo;0;L;;;;;N;;;;;
+A3A3;YI SYLLABLE NRURX;Lo;0;L;;;;;N;;;;;
+A3A4;YI SYLLABLE NRUR;Lo;0;L;;;;;N;;;;;
+A3A5;YI SYLLABLE NRYT;Lo;0;L;;;;;N;;;;;
+A3A6;YI SYLLABLE NRYX;Lo;0;L;;;;;N;;;;;
+A3A7;YI SYLLABLE NRY;Lo;0;L;;;;;N;;;;;
+A3A8;YI SYLLABLE NRYP;Lo;0;L;;;;;N;;;;;
+A3A9;YI SYLLABLE NRYRX;Lo;0;L;;;;;N;;;;;
+A3AA;YI SYLLABLE NRYR;Lo;0;L;;;;;N;;;;;
+A3AB;YI SYLLABLE SHAT;Lo;0;L;;;;;N;;;;;
+A3AC;YI SYLLABLE SHAX;Lo;0;L;;;;;N;;;;;
+A3AD;YI SYLLABLE SHA;Lo;0;L;;;;;N;;;;;
+A3AE;YI SYLLABLE SHAP;Lo;0;L;;;;;N;;;;;
+A3AF;YI SYLLABLE SHUOX;Lo;0;L;;;;;N;;;;;
+A3B0;YI SYLLABLE SHUO;Lo;0;L;;;;;N;;;;;
+A3B1;YI SYLLABLE SHUOP;Lo;0;L;;;;;N;;;;;
+A3B2;YI SYLLABLE SHOT;Lo;0;L;;;;;N;;;;;
+A3B3;YI SYLLABLE SHOX;Lo;0;L;;;;;N;;;;;
+A3B4;YI SYLLABLE SHO;Lo;0;L;;;;;N;;;;;
+A3B5;YI SYLLABLE SHOP;Lo;0;L;;;;;N;;;;;
+A3B6;YI SYLLABLE SHET;Lo;0;L;;;;;N;;;;;
+A3B7;YI SYLLABLE SHEX;Lo;0;L;;;;;N;;;;;
+A3B8;YI SYLLABLE SHE;Lo;0;L;;;;;N;;;;;
+A3B9;YI SYLLABLE SHEP;Lo;0;L;;;;;N;;;;;
+A3BA;YI SYLLABLE SHUT;Lo;0;L;;;;;N;;;;;
+A3BB;YI SYLLABLE SHUX;Lo;0;L;;;;;N;;;;;
+A3BC;YI SYLLABLE SHU;Lo;0;L;;;;;N;;;;;
+A3BD;YI SYLLABLE SHUP;Lo;0;L;;;;;N;;;;;
+A3BE;YI SYLLABLE SHURX;Lo;0;L;;;;;N;;;;;
+A3BF;YI SYLLABLE SHUR;Lo;0;L;;;;;N;;;;;
+A3C0;YI SYLLABLE SHYT;Lo;0;L;;;;;N;;;;;
+A3C1;YI SYLLABLE SHYX;Lo;0;L;;;;;N;;;;;
+A3C2;YI SYLLABLE SHY;Lo;0;L;;;;;N;;;;;
+A3C3;YI SYLLABLE SHYP;Lo;0;L;;;;;N;;;;;
+A3C4;YI SYLLABLE SHYRX;Lo;0;L;;;;;N;;;;;
+A3C5;YI SYLLABLE SHYR;Lo;0;L;;;;;N;;;;;
+A3C6;YI SYLLABLE RAT;Lo;0;L;;;;;N;;;;;
+A3C7;YI SYLLABLE RAX;Lo;0;L;;;;;N;;;;;
+A3C8;YI SYLLABLE RA;Lo;0;L;;;;;N;;;;;
+A3C9;YI SYLLABLE RAP;Lo;0;L;;;;;N;;;;;
+A3CA;YI SYLLABLE RUOX;Lo;0;L;;;;;N;;;;;
+A3CB;YI SYLLABLE RUO;Lo;0;L;;;;;N;;;;;
+A3CC;YI SYLLABLE RUOP;Lo;0;L;;;;;N;;;;;
+A3CD;YI SYLLABLE ROT;Lo;0;L;;;;;N;;;;;
+A3CE;YI SYLLABLE ROX;Lo;0;L;;;;;N;;;;;
+A3CF;YI SYLLABLE RO;Lo;0;L;;;;;N;;;;;
+A3D0;YI SYLLABLE ROP;Lo;0;L;;;;;N;;;;;
+A3D1;YI SYLLABLE REX;Lo;0;L;;;;;N;;;;;
+A3D2;YI SYLLABLE RE;Lo;0;L;;;;;N;;;;;
+A3D3;YI SYLLABLE REP;Lo;0;L;;;;;N;;;;;
+A3D4;YI SYLLABLE RUT;Lo;0;L;;;;;N;;;;;
+A3D5;YI SYLLABLE RUX;Lo;0;L;;;;;N;;;;;
+A3D6;YI SYLLABLE RU;Lo;0;L;;;;;N;;;;;
+A3D7;YI SYLLABLE RUP;Lo;0;L;;;;;N;;;;;
+A3D8;YI SYLLABLE RURX;Lo;0;L;;;;;N;;;;;
+A3D9;YI SYLLABLE RUR;Lo;0;L;;;;;N;;;;;
+A3DA;YI SYLLABLE RYT;Lo;0;L;;;;;N;;;;;
+A3DB;YI SYLLABLE RYX;Lo;0;L;;;;;N;;;;;
+A3DC;YI SYLLABLE RY;Lo;0;L;;;;;N;;;;;
+A3DD;YI SYLLABLE RYP;Lo;0;L;;;;;N;;;;;
+A3DE;YI SYLLABLE RYRX;Lo;0;L;;;;;N;;;;;
+A3DF;YI SYLLABLE RYR;Lo;0;L;;;;;N;;;;;
+A3E0;YI SYLLABLE JIT;Lo;0;L;;;;;N;;;;;
+A3E1;YI SYLLABLE JIX;Lo;0;L;;;;;N;;;;;
+A3E2;YI SYLLABLE JI;Lo;0;L;;;;;N;;;;;
+A3E3;YI SYLLABLE JIP;Lo;0;L;;;;;N;;;;;
+A3E4;YI SYLLABLE JIET;Lo;0;L;;;;;N;;;;;
+A3E5;YI SYLLABLE JIEX;Lo;0;L;;;;;N;;;;;
+A3E6;YI SYLLABLE JIE;Lo;0;L;;;;;N;;;;;
+A3E7;YI SYLLABLE JIEP;Lo;0;L;;;;;N;;;;;
+A3E8;YI SYLLABLE JUOT;Lo;0;L;;;;;N;;;;;
+A3E9;YI SYLLABLE JUOX;Lo;0;L;;;;;N;;;;;
+A3EA;YI SYLLABLE JUO;Lo;0;L;;;;;N;;;;;
+A3EB;YI SYLLABLE JUOP;Lo;0;L;;;;;N;;;;;
+A3EC;YI SYLLABLE JOT;Lo;0;L;;;;;N;;;;;
+A3ED;YI SYLLABLE JOX;Lo;0;L;;;;;N;;;;;
+A3EE;YI SYLLABLE JO;Lo;0;L;;;;;N;;;;;
+A3EF;YI SYLLABLE JOP;Lo;0;L;;;;;N;;;;;
+A3F0;YI SYLLABLE JUT;Lo;0;L;;;;;N;;;;;
+A3F1;YI SYLLABLE JUX;Lo;0;L;;;;;N;;;;;
+A3F2;YI SYLLABLE JU;Lo;0;L;;;;;N;;;;;
+A3F3;YI SYLLABLE JUP;Lo;0;L;;;;;N;;;;;
+A3F4;YI SYLLABLE JURX;Lo;0;L;;;;;N;;;;;
+A3F5;YI SYLLABLE JUR;Lo;0;L;;;;;N;;;;;
+A3F6;YI SYLLABLE JYT;Lo;0;L;;;;;N;;;;;
+A3F7;YI SYLLABLE JYX;Lo;0;L;;;;;N;;;;;
+A3F8;YI SYLLABLE JY;Lo;0;L;;;;;N;;;;;
+A3F9;YI SYLLABLE JYP;Lo;0;L;;;;;N;;;;;
+A3FA;YI SYLLABLE JYRX;Lo;0;L;;;;;N;;;;;
+A3FB;YI SYLLABLE JYR;Lo;0;L;;;;;N;;;;;
+A3FC;YI SYLLABLE QIT;Lo;0;L;;;;;N;;;;;
+A3FD;YI SYLLABLE QIX;Lo;0;L;;;;;N;;;;;
+A3FE;YI SYLLABLE QI;Lo;0;L;;;;;N;;;;;
+A3FF;YI SYLLABLE QIP;Lo;0;L;;;;;N;;;;;
+A400;YI SYLLABLE QIET;Lo;0;L;;;;;N;;;;;
+A401;YI SYLLABLE QIEX;Lo;0;L;;;;;N;;;;;
+A402;YI SYLLABLE QIE;Lo;0;L;;;;;N;;;;;
+A403;YI SYLLABLE QIEP;Lo;0;L;;;;;N;;;;;
+A404;YI SYLLABLE QUOT;Lo;0;L;;;;;N;;;;;
+A405;YI SYLLABLE QUOX;Lo;0;L;;;;;N;;;;;
+A406;YI SYLLABLE QUO;Lo;0;L;;;;;N;;;;;
+A407;YI SYLLABLE QUOP;Lo;0;L;;;;;N;;;;;
+A408;YI SYLLABLE QOT;Lo;0;L;;;;;N;;;;;
+A409;YI SYLLABLE QOX;Lo;0;L;;;;;N;;;;;
+A40A;YI SYLLABLE QO;Lo;0;L;;;;;N;;;;;
+A40B;YI SYLLABLE QOP;Lo;0;L;;;;;N;;;;;
+A40C;YI SYLLABLE QUT;Lo;0;L;;;;;N;;;;;
+A40D;YI SYLLABLE QUX;Lo;0;L;;;;;N;;;;;
+A40E;YI SYLLABLE QU;Lo;0;L;;;;;N;;;;;
+A40F;YI SYLLABLE QUP;Lo;0;L;;;;;N;;;;;
+A410;YI SYLLABLE QURX;Lo;0;L;;;;;N;;;;;
+A411;YI SYLLABLE QUR;Lo;0;L;;;;;N;;;;;
+A412;YI SYLLABLE QYT;Lo;0;L;;;;;N;;;;;
+A413;YI SYLLABLE QYX;Lo;0;L;;;;;N;;;;;
+A414;YI SYLLABLE QY;Lo;0;L;;;;;N;;;;;
+A415;YI SYLLABLE QYP;Lo;0;L;;;;;N;;;;;
+A416;YI SYLLABLE QYRX;Lo;0;L;;;;;N;;;;;
+A417;YI SYLLABLE QYR;Lo;0;L;;;;;N;;;;;
+A418;YI SYLLABLE JJIT;Lo;0;L;;;;;N;;;;;
+A419;YI SYLLABLE JJIX;Lo;0;L;;;;;N;;;;;
+A41A;YI SYLLABLE JJI;Lo;0;L;;;;;N;;;;;
+A41B;YI SYLLABLE JJIP;Lo;0;L;;;;;N;;;;;
+A41C;YI SYLLABLE JJIET;Lo;0;L;;;;;N;;;;;
+A41D;YI SYLLABLE JJIEX;Lo;0;L;;;;;N;;;;;
+A41E;YI SYLLABLE JJIE;Lo;0;L;;;;;N;;;;;
+A41F;YI SYLLABLE JJIEP;Lo;0;L;;;;;N;;;;;
+A420;YI SYLLABLE JJUOX;Lo;0;L;;;;;N;;;;;
+A421;YI SYLLABLE JJUO;Lo;0;L;;;;;N;;;;;
+A422;YI SYLLABLE JJUOP;Lo;0;L;;;;;N;;;;;
+A423;YI SYLLABLE JJOT;Lo;0;L;;;;;N;;;;;
+A424;YI SYLLABLE JJOX;Lo;0;L;;;;;N;;;;;
+A425;YI SYLLABLE JJO;Lo;0;L;;;;;N;;;;;
+A426;YI SYLLABLE JJOP;Lo;0;L;;;;;N;;;;;
+A427;YI SYLLABLE JJUT;Lo;0;L;;;;;N;;;;;
+A428;YI SYLLABLE JJUX;Lo;0;L;;;;;N;;;;;
+A429;YI SYLLABLE JJU;Lo;0;L;;;;;N;;;;;
+A42A;YI SYLLABLE JJUP;Lo;0;L;;;;;N;;;;;
+A42B;YI SYLLABLE JJURX;Lo;0;L;;;;;N;;;;;
+A42C;YI SYLLABLE JJUR;Lo;0;L;;;;;N;;;;;
+A42D;YI SYLLABLE JJYT;Lo;0;L;;;;;N;;;;;
+A42E;YI SYLLABLE JJYX;Lo;0;L;;;;;N;;;;;
+A42F;YI SYLLABLE JJY;Lo;0;L;;;;;N;;;;;
+A430;YI SYLLABLE JJYP;Lo;0;L;;;;;N;;;;;
+A431;YI SYLLABLE NJIT;Lo;0;L;;;;;N;;;;;
+A432;YI SYLLABLE NJIX;Lo;0;L;;;;;N;;;;;
+A433;YI SYLLABLE NJI;Lo;0;L;;;;;N;;;;;
+A434;YI SYLLABLE NJIP;Lo;0;L;;;;;N;;;;;
+A435;YI SYLLABLE NJIET;Lo;0;L;;;;;N;;;;;
+A436;YI SYLLABLE NJIEX;Lo;0;L;;;;;N;;;;;
+A437;YI SYLLABLE NJIE;Lo;0;L;;;;;N;;;;;
+A438;YI SYLLABLE NJIEP;Lo;0;L;;;;;N;;;;;
+A439;YI SYLLABLE NJUOX;Lo;0;L;;;;;N;;;;;
+A43A;YI SYLLABLE NJUO;Lo;0;L;;;;;N;;;;;
+A43B;YI SYLLABLE NJOT;Lo;0;L;;;;;N;;;;;
+A43C;YI SYLLABLE NJOX;Lo;0;L;;;;;N;;;;;
+A43D;YI SYLLABLE NJO;Lo;0;L;;;;;N;;;;;
+A43E;YI SYLLABLE NJOP;Lo;0;L;;;;;N;;;;;
+A43F;YI SYLLABLE NJUX;Lo;0;L;;;;;N;;;;;
+A440;YI SYLLABLE NJU;Lo;0;L;;;;;N;;;;;
+A441;YI SYLLABLE NJUP;Lo;0;L;;;;;N;;;;;
+A442;YI SYLLABLE NJURX;Lo;0;L;;;;;N;;;;;
+A443;YI SYLLABLE NJUR;Lo;0;L;;;;;N;;;;;
+A444;YI SYLLABLE NJYT;Lo;0;L;;;;;N;;;;;
+A445;YI SYLLABLE NJYX;Lo;0;L;;;;;N;;;;;
+A446;YI SYLLABLE NJY;Lo;0;L;;;;;N;;;;;
+A447;YI SYLLABLE NJYP;Lo;0;L;;;;;N;;;;;
+A448;YI SYLLABLE NJYRX;Lo;0;L;;;;;N;;;;;
+A449;YI SYLLABLE NJYR;Lo;0;L;;;;;N;;;;;
+A44A;YI SYLLABLE NYIT;Lo;0;L;;;;;N;;;;;
+A44B;YI SYLLABLE NYIX;Lo;0;L;;;;;N;;;;;
+A44C;YI SYLLABLE NYI;Lo;0;L;;;;;N;;;;;
+A44D;YI SYLLABLE NYIP;Lo;0;L;;;;;N;;;;;
+A44E;YI SYLLABLE NYIET;Lo;0;L;;;;;N;;;;;
+A44F;YI SYLLABLE NYIEX;Lo;0;L;;;;;N;;;;;
+A450;YI SYLLABLE NYIE;Lo;0;L;;;;;N;;;;;
+A451;YI SYLLABLE NYIEP;Lo;0;L;;;;;N;;;;;
+A452;YI SYLLABLE NYUOX;Lo;0;L;;;;;N;;;;;
+A453;YI SYLLABLE NYUO;Lo;0;L;;;;;N;;;;;
+A454;YI SYLLABLE NYUOP;Lo;0;L;;;;;N;;;;;
+A455;YI SYLLABLE NYOT;Lo;0;L;;;;;N;;;;;
+A456;YI SYLLABLE NYOX;Lo;0;L;;;;;N;;;;;
+A457;YI SYLLABLE NYO;Lo;0;L;;;;;N;;;;;
+A458;YI SYLLABLE NYOP;Lo;0;L;;;;;N;;;;;
+A459;YI SYLLABLE NYUT;Lo;0;L;;;;;N;;;;;
+A45A;YI SYLLABLE NYUX;Lo;0;L;;;;;N;;;;;
+A45B;YI SYLLABLE NYU;Lo;0;L;;;;;N;;;;;
+A45C;YI SYLLABLE NYUP;Lo;0;L;;;;;N;;;;;
+A45D;YI SYLLABLE XIT;Lo;0;L;;;;;N;;;;;
+A45E;YI SYLLABLE XIX;Lo;0;L;;;;;N;;;;;
+A45F;YI SYLLABLE XI;Lo;0;L;;;;;N;;;;;
+A460;YI SYLLABLE XIP;Lo;0;L;;;;;N;;;;;
+A461;YI SYLLABLE XIET;Lo;0;L;;;;;N;;;;;
+A462;YI SYLLABLE XIEX;Lo;0;L;;;;;N;;;;;
+A463;YI SYLLABLE XIE;Lo;0;L;;;;;N;;;;;
+A464;YI SYLLABLE XIEP;Lo;0;L;;;;;N;;;;;
+A465;YI SYLLABLE XUOX;Lo;0;L;;;;;N;;;;;
+A466;YI SYLLABLE XUO;Lo;0;L;;;;;N;;;;;
+A467;YI SYLLABLE XOT;Lo;0;L;;;;;N;;;;;
+A468;YI SYLLABLE XOX;Lo;0;L;;;;;N;;;;;
+A469;YI SYLLABLE XO;Lo;0;L;;;;;N;;;;;
+A46A;YI SYLLABLE XOP;Lo;0;L;;;;;N;;;;;
+A46B;YI SYLLABLE XYT;Lo;0;L;;;;;N;;;;;
+A46C;YI SYLLABLE XYX;Lo;0;L;;;;;N;;;;;
+A46D;YI SYLLABLE XY;Lo;0;L;;;;;N;;;;;
+A46E;YI SYLLABLE XYP;Lo;0;L;;;;;N;;;;;
+A46F;YI SYLLABLE XYRX;Lo;0;L;;;;;N;;;;;
+A470;YI SYLLABLE XYR;Lo;0;L;;;;;N;;;;;
+A471;YI SYLLABLE YIT;Lo;0;L;;;;;N;;;;;
+A472;YI SYLLABLE YIX;Lo;0;L;;;;;N;;;;;
+A473;YI SYLLABLE YI;Lo;0;L;;;;;N;;;;;
+A474;YI SYLLABLE YIP;Lo;0;L;;;;;N;;;;;
+A475;YI SYLLABLE YIET;Lo;0;L;;;;;N;;;;;
+A476;YI SYLLABLE YIEX;Lo;0;L;;;;;N;;;;;
+A477;YI SYLLABLE YIE;Lo;0;L;;;;;N;;;;;
+A478;YI SYLLABLE YIEP;Lo;0;L;;;;;N;;;;;
+A479;YI SYLLABLE YUOT;Lo;0;L;;;;;N;;;;;
+A47A;YI SYLLABLE YUOX;Lo;0;L;;;;;N;;;;;
+A47B;YI SYLLABLE YUO;Lo;0;L;;;;;N;;;;;
+A47C;YI SYLLABLE YUOP;Lo;0;L;;;;;N;;;;;
+A47D;YI SYLLABLE YOT;Lo;0;L;;;;;N;;;;;
+A47E;YI SYLLABLE YOX;Lo;0;L;;;;;N;;;;;
+A47F;YI SYLLABLE YO;Lo;0;L;;;;;N;;;;;
+A480;YI SYLLABLE YOP;Lo;0;L;;;;;N;;;;;
+A481;YI SYLLABLE YUT;Lo;0;L;;;;;N;;;;;
+A482;YI SYLLABLE YUX;Lo;0;L;;;;;N;;;;;
+A483;YI SYLLABLE YU;Lo;0;L;;;;;N;;;;;
+A484;YI SYLLABLE YUP;Lo;0;L;;;;;N;;;;;
+A485;YI SYLLABLE YURX;Lo;0;L;;;;;N;;;;;
+A486;YI SYLLABLE YUR;Lo;0;L;;;;;N;;;;;
+A487;YI SYLLABLE YYT;Lo;0;L;;;;;N;;;;;
+A488;YI SYLLABLE YYX;Lo;0;L;;;;;N;;;;;
+A489;YI SYLLABLE YY;Lo;0;L;;;;;N;;;;;
+A48A;YI SYLLABLE YYP;Lo;0;L;;;;;N;;;;;
+A48B;YI SYLLABLE YYRX;Lo;0;L;;;;;N;;;;;
+A48C;YI SYLLABLE YYR;Lo;0;L;;;;;N;;;;;
+A490;YI RADICAL QOT;So;0;ON;;;;;N;;;;;
+A491;YI RADICAL LI;So;0;ON;;;;;N;;;;;
+A492;YI RADICAL KIT;So;0;ON;;;;;N;;;;;
+A493;YI RADICAL NYIP;So;0;ON;;;;;N;;;;;
+A494;YI RADICAL CYP;So;0;ON;;;;;N;;;;;
+A495;YI RADICAL SSI;So;0;ON;;;;;N;;;;;
+A496;YI RADICAL GGOP;So;0;ON;;;;;N;;;;;
+A497;YI RADICAL GEP;So;0;ON;;;;;N;;;;;
+A498;YI RADICAL MI;So;0;ON;;;;;N;;;;;
+A499;YI RADICAL HXIT;So;0;ON;;;;;N;;;;;
+A49A;YI RADICAL LYR;So;0;ON;;;;;N;;;;;
+A49B;YI RADICAL BBUT;So;0;ON;;;;;N;;;;;
+A49C;YI RADICAL MOP;So;0;ON;;;;;N;;;;;
+A49D;YI RADICAL YO;So;0;ON;;;;;N;;;;;
+A49E;YI RADICAL PUT;So;0;ON;;;;;N;;;;;
+A49F;YI RADICAL HXUO;So;0;ON;;;;;N;;;;;
+A4A0;YI RADICAL TAT;So;0;ON;;;;;N;;;;;
+A4A1;YI RADICAL GA;So;0;ON;;;;;N;;;;;
+A4A2;YI RADICAL ZUP;So;0;ON;;;;;N;;;;;
+A4A3;YI RADICAL CYT;So;0;ON;;;;;N;;;;;
+A4A4;YI RADICAL DDUR;So;0;ON;;;;;N;;;;;
+A4A5;YI RADICAL BUR;So;0;ON;;;;;N;;;;;
+A4A6;YI RADICAL GGUO;So;0;ON;;;;;N;;;;;
+A4A7;YI RADICAL NYOP;So;0;ON;;;;;N;;;;;
+A4A8;YI RADICAL TU;So;0;ON;;;;;N;;;;;
+A4A9;YI RADICAL OP;So;0;ON;;;;;N;;;;;
+A4AA;YI RADICAL JJUT;So;0;ON;;;;;N;;;;;
+A4AB;YI RADICAL ZOT;So;0;ON;;;;;N;;;;;
+A4AC;YI RADICAL PYT;So;0;ON;;;;;N;;;;;
+A4AD;YI RADICAL HMO;So;0;ON;;;;;N;;;;;
+A4AE;YI RADICAL YIT;So;0;ON;;;;;N;;;;;
+A4AF;YI RADICAL VUR;So;0;ON;;;;;N;;;;;
+A4B0;YI RADICAL SHY;So;0;ON;;;;;N;;;;;
+A4B1;YI RADICAL VEP;So;0;ON;;;;;N;;;;;
+A4B2;YI RADICAL ZA;So;0;ON;;;;;N;;;;;
+A4B3;YI RADICAL JO;So;0;ON;;;;;N;;;;;
+A4B4;YI RADICAL NZUP;So;0;ON;;;;;N;;;;;
+A4B5;YI RADICAL JJY;So;0;ON;;;;;N;;;;;
+A4B6;YI RADICAL GOT;So;0;ON;;;;;N;;;;;
+A4B7;YI RADICAL JJIE;So;0;ON;;;;;N;;;;;
+A4B8;YI RADICAL WO;So;0;ON;;;;;N;;;;;
+A4B9;YI RADICAL DU;So;0;ON;;;;;N;;;;;
+A4BA;YI RADICAL SHUR;So;0;ON;;;;;N;;;;;
+A4BB;YI RADICAL LIE;So;0;ON;;;;;N;;;;;
+A4BC;YI RADICAL CY;So;0;ON;;;;;N;;;;;
+A4BD;YI RADICAL CUOP;So;0;ON;;;;;N;;;;;
+A4BE;YI RADICAL CIP;So;0;ON;;;;;N;;;;;
+A4BF;YI RADICAL HXOP;So;0;ON;;;;;N;;;;;
+A4C0;YI RADICAL SHAT;So;0;ON;;;;;N;;;;;
+A4C1;YI RADICAL ZUR;So;0;ON;;;;;N;;;;;
+A4C2;YI RADICAL SHOP;So;0;ON;;;;;N;;;;;
+A4C3;YI RADICAL CHE;So;0;ON;;;;;N;;;;;
+A4C4;YI RADICAL ZZIET;So;0;ON;;;;;N;;;;;
+A4C5;YI RADICAL NBIE;So;0;ON;;;;;N;;;;;
+A4C6;YI RADICAL KE;So;0;ON;;;;;N;;;;;
+A4D0;LISU LETTER BA;Lo;0;L;;;;;N;;;;;
+A4D1;LISU LETTER PA;Lo;0;L;;;;;N;;;;;
+A4D2;LISU LETTER PHA;Lo;0;L;;;;;N;;;;;
+A4D3;LISU LETTER DA;Lo;0;L;;;;;N;;;;;
+A4D4;LISU LETTER TA;Lo;0;L;;;;;N;;;;;
+A4D5;LISU LETTER THA;Lo;0;L;;;;;N;;;;;
+A4D6;LISU LETTER GA;Lo;0;L;;;;;N;;;;;
+A4D7;LISU LETTER KA;Lo;0;L;;;;;N;;;;;
+A4D8;LISU LETTER KHA;Lo;0;L;;;;;N;;;;;
+A4D9;LISU LETTER JA;Lo;0;L;;;;;N;;;;;
+A4DA;LISU LETTER CA;Lo;0;L;;;;;N;;;;;
+A4DB;LISU LETTER CHA;Lo;0;L;;;;;N;;;;;
+A4DC;LISU LETTER DZA;Lo;0;L;;;;;N;;;;;
+A4DD;LISU LETTER TSA;Lo;0;L;;;;;N;;;;;
+A4DE;LISU LETTER TSHA;Lo;0;L;;;;;N;;;;;
+A4DF;LISU LETTER MA;Lo;0;L;;;;;N;;;;;
+A4E0;LISU LETTER NA;Lo;0;L;;;;;N;;;;;
+A4E1;LISU LETTER LA;Lo;0;L;;;;;N;;;;;
+A4E2;LISU LETTER SA;Lo;0;L;;;;;N;;;;;
+A4E3;LISU LETTER ZHA;Lo;0;L;;;;;N;;;;;
+A4E4;LISU LETTER ZA;Lo;0;L;;;;;N;;;;;
+A4E5;LISU LETTER NGA;Lo;0;L;;;;;N;;;;;
+A4E6;LISU LETTER HA;Lo;0;L;;;;;N;;;;;
+A4E7;LISU LETTER XA;Lo;0;L;;;;;N;;;;;
+A4E8;LISU LETTER HHA;Lo;0;L;;;;;N;;;;;
+A4E9;LISU LETTER FA;Lo;0;L;;;;;N;;;;;
+A4EA;LISU LETTER WA;Lo;0;L;;;;;N;;;;;
+A4EB;LISU LETTER SHA;Lo;0;L;;;;;N;;;;;
+A4EC;LISU LETTER YA;Lo;0;L;;;;;N;;;;;
+A4ED;LISU LETTER GHA;Lo;0;L;;;;;N;;;;;
+A4EE;LISU LETTER A;Lo;0;L;;;;;N;;;;;
+A4EF;LISU LETTER AE;Lo;0;L;;;;;N;;;;;
+A4F0;LISU LETTER E;Lo;0;L;;;;;N;;;;;
+A4F1;LISU LETTER EU;Lo;0;L;;;;;N;;;;;
+A4F2;LISU LETTER I;Lo;0;L;;;;;N;;;;;
+A4F3;LISU LETTER O;Lo;0;L;;;;;N;;;;;
+A4F4;LISU LETTER U;Lo;0;L;;;;;N;;;;;
+A4F5;LISU LETTER UE;Lo;0;L;;;;;N;;;;;
+A4F6;LISU LETTER UH;Lo;0;L;;;;;N;;;;;
+A4F7;LISU LETTER OE;Lo;0;L;;;;;N;;;;;
+A4F8;LISU LETTER TONE MYA TI;Lm;0;L;;;;;N;;;;;
+A4F9;LISU LETTER TONE NA PO;Lm;0;L;;;;;N;;;;;
+A4FA;LISU LETTER TONE MYA CYA;Lm;0;L;;;;;N;;;;;
+A4FB;LISU LETTER TONE MYA BO;Lm;0;L;;;;;N;;;;;
+A4FC;LISU LETTER TONE MYA NA;Lm;0;L;;;;;N;;;;;
+A4FD;LISU LETTER TONE MYA JEU;Lm;0;L;;;;;N;;;;;
+A4FE;LISU PUNCTUATION COMMA;Po;0;L;;;;;N;;;;;
+A4FF;LISU PUNCTUATION FULL STOP;Po;0;L;;;;;N;;;;;
+A500;VAI SYLLABLE EE;Lo;0;L;;;;;N;;;;;
+A501;VAI SYLLABLE EEN;Lo;0;L;;;;;N;;;;;
+A502;VAI SYLLABLE HEE;Lo;0;L;;;;;N;;;;;
+A503;VAI SYLLABLE WEE;Lo;0;L;;;;;N;;;;;
+A504;VAI SYLLABLE WEEN;Lo;0;L;;;;;N;;;;;
+A505;VAI SYLLABLE PEE;Lo;0;L;;;;;N;;;;;
+A506;VAI SYLLABLE BHEE;Lo;0;L;;;;;N;;;;;
+A507;VAI SYLLABLE BEE;Lo;0;L;;;;;N;;;;;
+A508;VAI SYLLABLE MBEE;Lo;0;L;;;;;N;;;;;
+A509;VAI SYLLABLE KPEE;Lo;0;L;;;;;N;;;;;
+A50A;VAI SYLLABLE MGBEE;Lo;0;L;;;;;N;;;;;
+A50B;VAI SYLLABLE GBEE;Lo;0;L;;;;;N;;;;;
+A50C;VAI SYLLABLE FEE;Lo;0;L;;;;;N;;;;;
+A50D;VAI SYLLABLE VEE;Lo;0;L;;;;;N;;;;;
+A50E;VAI SYLLABLE TEE;Lo;0;L;;;;;N;;;;;
+A50F;VAI SYLLABLE THEE;Lo;0;L;;;;;N;;;;;
+A510;VAI SYLLABLE DHEE;Lo;0;L;;;;;N;;;;;
+A511;VAI SYLLABLE DHHEE;Lo;0;L;;;;;N;;;;;
+A512;VAI SYLLABLE LEE;Lo;0;L;;;;;N;;;;;
+A513;VAI SYLLABLE REE;Lo;0;L;;;;;N;;;;;
+A514;VAI SYLLABLE DEE;Lo;0;L;;;;;N;;;;;
+A515;VAI SYLLABLE NDEE;Lo;0;L;;;;;N;;;;;
+A516;VAI SYLLABLE SEE;Lo;0;L;;;;;N;;;;;
+A517;VAI SYLLABLE SHEE;Lo;0;L;;;;;N;;;;;
+A518;VAI SYLLABLE ZEE;Lo;0;L;;;;;N;;;;;
+A519;VAI SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;;
+A51A;VAI SYLLABLE CEE;Lo;0;L;;;;;N;;;;;
+A51B;VAI SYLLABLE JEE;Lo;0;L;;;;;N;;;;;
+A51C;VAI SYLLABLE NJEE;Lo;0;L;;;;;N;;;;;
+A51D;VAI SYLLABLE YEE;Lo;0;L;;;;;N;;;;;
+A51E;VAI SYLLABLE KEE;Lo;0;L;;;;;N;;;;;
+A51F;VAI SYLLABLE NGGEE;Lo;0;L;;;;;N;;;;;
+A520;VAI SYLLABLE GEE;Lo;0;L;;;;;N;;;;;
+A521;VAI SYLLABLE MEE;Lo;0;L;;;;;N;;;;;
+A522;VAI SYLLABLE NEE;Lo;0;L;;;;;N;;;;;
+A523;VAI SYLLABLE NYEE;Lo;0;L;;;;;N;;;;;
+A524;VAI SYLLABLE I;Lo;0;L;;;;;N;;;;;
+A525;VAI SYLLABLE IN;Lo;0;L;;;;;N;;;;;
+A526;VAI SYLLABLE HI;Lo;0;L;;;;;N;;;;;
+A527;VAI SYLLABLE HIN;Lo;0;L;;;;;N;;;;;
+A528;VAI SYLLABLE WI;Lo;0;L;;;;;N;;;;;
+A529;VAI SYLLABLE WIN;Lo;0;L;;;;;N;;;;;
+A52A;VAI SYLLABLE PI;Lo;0;L;;;;;N;;;;;
+A52B;VAI SYLLABLE BHI;Lo;0;L;;;;;N;;;;;
+A52C;VAI SYLLABLE BI;Lo;0;L;;;;;N;;;;;
+A52D;VAI SYLLABLE MBI;Lo;0;L;;;;;N;;;;;
+A52E;VAI SYLLABLE KPI;Lo;0;L;;;;;N;;;;;
+A52F;VAI SYLLABLE MGBI;Lo;0;L;;;;;N;;;;;
+A530;VAI SYLLABLE GBI;Lo;0;L;;;;;N;;;;;
+A531;VAI SYLLABLE FI;Lo;0;L;;;;;N;;;;;
+A532;VAI SYLLABLE VI;Lo;0;L;;;;;N;;;;;
+A533;VAI SYLLABLE TI;Lo;0;L;;;;;N;;;;;
+A534;VAI SYLLABLE THI;Lo;0;L;;;;;N;;;;;
+A535;VAI SYLLABLE DHI;Lo;0;L;;;;;N;;;;;
+A536;VAI SYLLABLE DHHI;Lo;0;L;;;;;N;;;;;
+A537;VAI SYLLABLE LI;Lo;0;L;;;;;N;;;;;
+A538;VAI SYLLABLE RI;Lo;0;L;;;;;N;;;;;
+A539;VAI SYLLABLE DI;Lo;0;L;;;;;N;;;;;
+A53A;VAI SYLLABLE NDI;Lo;0;L;;;;;N;;;;;
+A53B;VAI SYLLABLE SI;Lo;0;L;;;;;N;;;;;
+A53C;VAI SYLLABLE SHI;Lo;0;L;;;;;N;;;;;
+A53D;VAI SYLLABLE ZI;Lo;0;L;;;;;N;;;;;
+A53E;VAI SYLLABLE ZHI;Lo;0;L;;;;;N;;;;;
+A53F;VAI SYLLABLE CI;Lo;0;L;;;;;N;;;;;
+A540;VAI SYLLABLE JI;Lo;0;L;;;;;N;;;;;
+A541;VAI SYLLABLE NJI;Lo;0;L;;;;;N;;;;;
+A542;VAI SYLLABLE YI;Lo;0;L;;;;;N;;;;;
+A543;VAI SYLLABLE KI;Lo;0;L;;;;;N;;;;;
+A544;VAI SYLLABLE NGGI;Lo;0;L;;;;;N;;;;;
+A545;VAI SYLLABLE GI;Lo;0;L;;;;;N;;;;;
+A546;VAI SYLLABLE MI;Lo;0;L;;;;;N;;;;;
+A547;VAI SYLLABLE NI;Lo;0;L;;;;;N;;;;;
+A548;VAI SYLLABLE NYI;Lo;0;L;;;;;N;;;;;
+A549;VAI SYLLABLE A;Lo;0;L;;;;;N;;;;;
+A54A;VAI SYLLABLE AN;Lo;0;L;;;;;N;;;;;
+A54B;VAI SYLLABLE NGAN;Lo;0;L;;;;;N;;;;;
+A54C;VAI SYLLABLE HA;Lo;0;L;;;;;N;;;;;
+A54D;VAI SYLLABLE HAN;Lo;0;L;;;;;N;;;;;
+A54E;VAI SYLLABLE WA;Lo;0;L;;;;;N;;;;;
+A54F;VAI SYLLABLE WAN;Lo;0;L;;;;;N;;;;;
+A550;VAI SYLLABLE PA;Lo;0;L;;;;;N;;;;;
+A551;VAI SYLLABLE BHA;Lo;0;L;;;;;N;;;;;
+A552;VAI SYLLABLE BA;Lo;0;L;;;;;N;;;;;
+A553;VAI SYLLABLE MBA;Lo;0;L;;;;;N;;;;;
+A554;VAI SYLLABLE KPA;Lo;0;L;;;;;N;;;;;
+A555;VAI SYLLABLE KPAN;Lo;0;L;;;;;N;;;;;
+A556;VAI SYLLABLE MGBA;Lo;0;L;;;;;N;;;;;
+A557;VAI SYLLABLE GBA;Lo;0;L;;;;;N;;;;;
+A558;VAI SYLLABLE FA;Lo;0;L;;;;;N;;;;;
+A559;VAI SYLLABLE VA;Lo;0;L;;;;;N;;;;;
+A55A;VAI SYLLABLE TA;Lo;0;L;;;;;N;;;;;
+A55B;VAI SYLLABLE THA;Lo;0;L;;;;;N;;;;;
+A55C;VAI SYLLABLE DHA;Lo;0;L;;;;;N;;;;;
+A55D;VAI SYLLABLE DHHA;Lo;0;L;;;;;N;;;;;
+A55E;VAI SYLLABLE LA;Lo;0;L;;;;;N;;;;;
+A55F;VAI SYLLABLE RA;Lo;0;L;;;;;N;;;;;
+A560;VAI SYLLABLE DA;Lo;0;L;;;;;N;;;;;
+A561;VAI SYLLABLE NDA;Lo;0;L;;;;;N;;;;;
+A562;VAI SYLLABLE SA;Lo;0;L;;;;;N;;;;;
+A563;VAI SYLLABLE SHA;Lo;0;L;;;;;N;;;;;
+A564;VAI SYLLABLE ZA;Lo;0;L;;;;;N;;;;;
+A565;VAI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;
+A566;VAI SYLLABLE CA;Lo;0;L;;;;;N;;;;;
+A567;VAI SYLLABLE JA;Lo;0;L;;;;;N;;;;;
+A568;VAI SYLLABLE NJA;Lo;0;L;;;;;N;;;;;
+A569;VAI SYLLABLE YA;Lo;0;L;;;;;N;;;;;
+A56A;VAI SYLLABLE KA;Lo;0;L;;;;;N;;;;;
+A56B;VAI SYLLABLE KAN;Lo;0;L;;;;;N;;;;;
+A56C;VAI SYLLABLE NGGA;Lo;0;L;;;;;N;;;;;
+A56D;VAI SYLLABLE GA;Lo;0;L;;;;;N;;;;;
+A56E;VAI SYLLABLE MA;Lo;0;L;;;;;N;;;;;
+A56F;VAI SYLLABLE NA;Lo;0;L;;;;;N;;;;;
+A570;VAI SYLLABLE NYA;Lo;0;L;;;;;N;;;;;
+A571;VAI SYLLABLE OO;Lo;0;L;;;;;N;;;;;
+A572;VAI SYLLABLE OON;Lo;0;L;;;;;N;;;;;
+A573;VAI SYLLABLE HOO;Lo;0;L;;;;;N;;;;;
+A574;VAI SYLLABLE WOO;Lo;0;L;;;;;N;;;;;
+A575;VAI SYLLABLE WOON;Lo;0;L;;;;;N;;;;;
+A576;VAI SYLLABLE POO;Lo;0;L;;;;;N;;;;;
+A577;VAI SYLLABLE BHOO;Lo;0;L;;;;;N;;;;;
+A578;VAI SYLLABLE BOO;Lo;0;L;;;;;N;;;;;
+A579;VAI SYLLABLE MBOO;Lo;0;L;;;;;N;;;;;
+A57A;VAI SYLLABLE KPOO;Lo;0;L;;;;;N;;;;;
+A57B;VAI SYLLABLE MGBOO;Lo;0;L;;;;;N;;;;;
+A57C;VAI SYLLABLE GBOO;Lo;0;L;;;;;N;;;;;
+A57D;VAI SYLLABLE FOO;Lo;0;L;;;;;N;;;;;
+A57E;VAI SYLLABLE VOO;Lo;0;L;;;;;N;;;;;
+A57F;VAI SYLLABLE TOO;Lo;0;L;;;;;N;;;;;
+A580;VAI SYLLABLE THOO;Lo;0;L;;;;;N;;;;;
+A581;VAI SYLLABLE DHOO;Lo;0;L;;;;;N;;;;;
+A582;VAI SYLLABLE DHHOO;Lo;0;L;;;;;N;;;;;
+A583;VAI SYLLABLE LOO;Lo;0;L;;;;;N;;;;;
+A584;VAI SYLLABLE ROO;Lo;0;L;;;;;N;;;;;
+A585;VAI SYLLABLE DOO;Lo;0;L;;;;;N;;;;;
+A586;VAI SYLLABLE NDOO;Lo;0;L;;;;;N;;;;;
+A587;VAI SYLLABLE SOO;Lo;0;L;;;;;N;;;;;
+A588;VAI SYLLABLE SHOO;Lo;0;L;;;;;N;;;;;
+A589;VAI SYLLABLE ZOO;Lo;0;L;;;;;N;;;;;
+A58A;VAI SYLLABLE ZHOO;Lo;0;L;;;;;N;;;;;
+A58B;VAI SYLLABLE COO;Lo;0;L;;;;;N;;;;;
+A58C;VAI SYLLABLE JOO;Lo;0;L;;;;;N;;;;;
+A58D;VAI SYLLABLE NJOO;Lo;0;L;;;;;N;;;;;
+A58E;VAI SYLLABLE YOO;Lo;0;L;;;;;N;;;;;
+A58F;VAI SYLLABLE KOO;Lo;0;L;;;;;N;;;;;
+A590;VAI SYLLABLE NGGOO;Lo;0;L;;;;;N;;;;;
+A591;VAI SYLLABLE GOO;Lo;0;L;;;;;N;;;;;
+A592;VAI SYLLABLE MOO;Lo;0;L;;;;;N;;;;;
+A593;VAI SYLLABLE NOO;Lo;0;L;;;;;N;;;;;
+A594;VAI SYLLABLE NYOO;Lo;0;L;;;;;N;;;;;
+A595;VAI SYLLABLE U;Lo;0;L;;;;;N;;;;;
+A596;VAI SYLLABLE UN;Lo;0;L;;;;;N;;;;;
+A597;VAI SYLLABLE HU;Lo;0;L;;;;;N;;;;;
+A598;VAI SYLLABLE HUN;Lo;0;L;;;;;N;;;;;
+A599;VAI SYLLABLE WU;Lo;0;L;;;;;N;;;;;
+A59A;VAI SYLLABLE WUN;Lo;0;L;;;;;N;;;;;
+A59B;VAI SYLLABLE PU;Lo;0;L;;;;;N;;;;;
+A59C;VAI SYLLABLE BHU;Lo;0;L;;;;;N;;;;;
+A59D;VAI SYLLABLE BU;Lo;0;L;;;;;N;;;;;
+A59E;VAI SYLLABLE MBU;Lo;0;L;;;;;N;;;;;
+A59F;VAI SYLLABLE KPU;Lo;0;L;;;;;N;;;;;
+A5A0;VAI SYLLABLE MGBU;Lo;0;L;;;;;N;;;;;
+A5A1;VAI SYLLABLE GBU;Lo;0;L;;;;;N;;;;;
+A5A2;VAI SYLLABLE FU;Lo;0;L;;;;;N;;;;;
+A5A3;VAI SYLLABLE VU;Lo;0;L;;;;;N;;;;;
+A5A4;VAI SYLLABLE TU;Lo;0;L;;;;;N;;;;;
+A5A5;VAI SYLLABLE THU;Lo;0;L;;;;;N;;;;;
+A5A6;VAI SYLLABLE DHU;Lo;0;L;;;;;N;;;;;
+A5A7;VAI SYLLABLE DHHU;Lo;0;L;;;;;N;;;;;
+A5A8;VAI SYLLABLE LU;Lo;0;L;;;;;N;;;;;
+A5A9;VAI SYLLABLE RU;Lo;0;L;;;;;N;;;;;
+A5AA;VAI SYLLABLE DU;Lo;0;L;;;;;N;;;;;
+A5AB;VAI SYLLABLE NDU;Lo;0;L;;;;;N;;;;;
+A5AC;VAI SYLLABLE SU;Lo;0;L;;;;;N;;;;;
+A5AD;VAI SYLLABLE SHU;Lo;0;L;;;;;N;;;;;
+A5AE;VAI SYLLABLE ZU;Lo;0;L;;;;;N;;;;;
+A5AF;VAI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;
+A5B0;VAI SYLLABLE CU;Lo;0;L;;;;;N;;;;;
+A5B1;VAI SYLLABLE JU;Lo;0;L;;;;;N;;;;;
+A5B2;VAI SYLLABLE NJU;Lo;0;L;;;;;N;;;;;
+A5B3;VAI SYLLABLE YU;Lo;0;L;;;;;N;;;;;
+A5B4;VAI SYLLABLE KU;Lo;0;L;;;;;N;;;;;
+A5B5;VAI SYLLABLE NGGU;Lo;0;L;;;;;N;;;;;
+A5B6;VAI SYLLABLE GU;Lo;0;L;;;;;N;;;;;
+A5B7;VAI SYLLABLE MU;Lo;0;L;;;;;N;;;;;
+A5B8;VAI SYLLABLE NU;Lo;0;L;;;;;N;;;;;
+A5B9;VAI SYLLABLE NYU;Lo;0;L;;;;;N;;;;;
+A5BA;VAI SYLLABLE O;Lo;0;L;;;;;N;;;;;
+A5BB;VAI SYLLABLE ON;Lo;0;L;;;;;N;;;;;
+A5BC;VAI SYLLABLE NGON;Lo;0;L;;;;;N;;;;;
+A5BD;VAI SYLLABLE HO;Lo;0;L;;;;;N;;;;;
+A5BE;VAI SYLLABLE HON;Lo;0;L;;;;;N;;;;;
+A5BF;VAI SYLLABLE WO;Lo;0;L;;;;;N;;;;;
+A5C0;VAI SYLLABLE WON;Lo;0;L;;;;;N;;;;;
+A5C1;VAI SYLLABLE PO;Lo;0;L;;;;;N;;;;;
+A5C2;VAI SYLLABLE BHO;Lo;0;L;;;;;N;;;;;
+A5C3;VAI SYLLABLE BO;Lo;0;L;;;;;N;;;;;
+A5C4;VAI SYLLABLE MBO;Lo;0;L;;;;;N;;;;;
+A5C5;VAI SYLLABLE KPO;Lo;0;L;;;;;N;;;;;
+A5C6;VAI SYLLABLE MGBO;Lo;0;L;;;;;N;;;;;
+A5C7;VAI SYLLABLE GBO;Lo;0;L;;;;;N;;;;;
+A5C8;VAI SYLLABLE GBON;Lo;0;L;;;;;N;;;;;
+A5C9;VAI SYLLABLE FO;Lo;0;L;;;;;N;;;;;
+A5CA;VAI SYLLABLE VO;Lo;0;L;;;;;N;;;;;
+A5CB;VAI SYLLABLE TO;Lo;0;L;;;;;N;;;;;
+A5CC;VAI SYLLABLE THO;Lo;0;L;;;;;N;;;;;
+A5CD;VAI SYLLABLE DHO;Lo;0;L;;;;;N;;;;;
+A5CE;VAI SYLLABLE DHHO;Lo;0;L;;;;;N;;;;;
+A5CF;VAI SYLLABLE LO;Lo;0;L;;;;;N;;;;;
+A5D0;VAI SYLLABLE RO;Lo;0;L;;;;;N;;;;;
+A5D1;VAI SYLLABLE DO;Lo;0;L;;;;;N;;;;;
+A5D2;VAI SYLLABLE NDO;Lo;0;L;;;;;N;;;;;
+A5D3;VAI SYLLABLE SO;Lo;0;L;;;;;N;;;;;
+A5D4;VAI SYLLABLE SHO;Lo;0;L;;;;;N;;;;;
+A5D5;VAI SYLLABLE ZO;Lo;0;L;;;;;N;;;;;
+A5D6;VAI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;
+A5D7;VAI SYLLABLE CO;Lo;0;L;;;;;N;;;;;
+A5D8;VAI SYLLABLE JO;Lo;0;L;;;;;N;;;;;
+A5D9;VAI SYLLABLE NJO;Lo;0;L;;;;;N;;;;;
+A5DA;VAI SYLLABLE YO;Lo;0;L;;;;;N;;;;;
+A5DB;VAI SYLLABLE KO;Lo;0;L;;;;;N;;;;;
+A5DC;VAI SYLLABLE NGGO;Lo;0;L;;;;;N;;;;;
+A5DD;VAI SYLLABLE GO;Lo;0;L;;;;;N;;;;;
+A5DE;VAI SYLLABLE MO;Lo;0;L;;;;;N;;;;;
+A5DF;VAI SYLLABLE NO;Lo;0;L;;;;;N;;;;;
+A5E0;VAI SYLLABLE NYO;Lo;0;L;;;;;N;;;;;
+A5E1;VAI SYLLABLE E;Lo;0;L;;;;;N;;;;;
+A5E2;VAI SYLLABLE EN;Lo;0;L;;;;;N;;;;;
+A5E3;VAI SYLLABLE NGEN;Lo;0;L;;;;;N;;;;;
+A5E4;VAI SYLLABLE HE;Lo;0;L;;;;;N;;;;;
+A5E5;VAI SYLLABLE HEN;Lo;0;L;;;;;N;;;;;
+A5E6;VAI SYLLABLE WE;Lo;0;L;;;;;N;;;;;
+A5E7;VAI SYLLABLE WEN;Lo;0;L;;;;;N;;;;;
+A5E8;VAI SYLLABLE PE;Lo;0;L;;;;;N;;;;;
+A5E9;VAI SYLLABLE BHE;Lo;0;L;;;;;N;;;;;
+A5EA;VAI SYLLABLE BE;Lo;0;L;;;;;N;;;;;
+A5EB;VAI SYLLABLE MBE;Lo;0;L;;;;;N;;;;;
+A5EC;VAI SYLLABLE KPE;Lo;0;L;;;;;N;;;;;
+A5ED;VAI SYLLABLE KPEN;Lo;0;L;;;;;N;;;;;
+A5EE;VAI SYLLABLE MGBE;Lo;0;L;;;;;N;;;;;
+A5EF;VAI SYLLABLE GBE;Lo;0;L;;;;;N;;;;;
+A5F0;VAI SYLLABLE GBEN;Lo;0;L;;;;;N;;;;;
+A5F1;VAI SYLLABLE FE;Lo;0;L;;;;;N;;;;;
+A5F2;VAI SYLLABLE VE;Lo;0;L;;;;;N;;;;;
+A5F3;VAI SYLLABLE TE;Lo;0;L;;;;;N;;;;;
+A5F4;VAI SYLLABLE THE;Lo;0;L;;;;;N;;;;;
+A5F5;VAI SYLLABLE DHE;Lo;0;L;;;;;N;;;;;
+A5F6;VAI SYLLABLE DHHE;Lo;0;L;;;;;N;;;;;
+A5F7;VAI SYLLABLE LE;Lo;0;L;;;;;N;;;;;
+A5F8;VAI SYLLABLE RE;Lo;0;L;;;;;N;;;;;
+A5F9;VAI SYLLABLE DE;Lo;0;L;;;;;N;;;;;
+A5FA;VAI SYLLABLE NDE;Lo;0;L;;;;;N;;;;;
+A5FB;VAI SYLLABLE SE;Lo;0;L;;;;;N;;;;;
+A5FC;VAI SYLLABLE SHE;Lo;0;L;;;;;N;;;;;
+A5FD;VAI SYLLABLE ZE;Lo;0;L;;;;;N;;;;;
+A5FE;VAI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;
+A5FF;VAI SYLLABLE CE;Lo;0;L;;;;;N;;;;;
+A600;VAI SYLLABLE JE;Lo;0;L;;;;;N;;;;;
+A601;VAI SYLLABLE NJE;Lo;0;L;;;;;N;;;;;
+A602;VAI SYLLABLE YE;Lo;0;L;;;;;N;;;;;
+A603;VAI SYLLABLE KE;Lo;0;L;;;;;N;;;;;
+A604;VAI SYLLABLE NGGE;Lo;0;L;;;;;N;;;;;
+A605;VAI SYLLABLE NGGEN;Lo;0;L;;;;;N;;;;;
+A606;VAI SYLLABLE GE;Lo;0;L;;;;;N;;;;;
+A607;VAI SYLLABLE GEN;Lo;0;L;;;;;N;;;;;
+A608;VAI SYLLABLE ME;Lo;0;L;;;;;N;;;;;
+A609;VAI SYLLABLE NE;Lo;0;L;;;;;N;;;;;
+A60A;VAI SYLLABLE NYE;Lo;0;L;;;;;N;;;;;
+A60B;VAI SYLLABLE NG;Lo;0;L;;;;;N;;;;;
+A60C;VAI SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;;
+A60D;VAI COMMA;Po;0;ON;;;;;N;;;;;
+A60E;VAI FULL STOP;Po;0;ON;;;;;N;;;;;
+A60F;VAI QUESTION MARK;Po;0;ON;;;;;N;;;;;
+A610;VAI SYLLABLE NDOLE FA;Lo;0;L;;;;;N;;;;;
+A611;VAI SYLLABLE NDOLE KA;Lo;0;L;;;;;N;;;;;
+A612;VAI SYLLABLE NDOLE SOO;Lo;0;L;;;;;N;;;;;
+A613;VAI SYMBOL FEENG;Lo;0;L;;;;;N;;;;;
+A614;VAI SYMBOL KEENG;Lo;0;L;;;;;N;;;;;
+A615;VAI SYMBOL TING;Lo;0;L;;;;;N;;;;;
+A616;VAI SYMBOL NII;Lo;0;L;;;;;N;;;;;
+A617;VAI SYMBOL BANG;Lo;0;L;;;;;N;;;;;
+A618;VAI SYMBOL FAA;Lo;0;L;;;;;N;;;;;
+A619;VAI SYMBOL TAA;Lo;0;L;;;;;N;;;;;
+A61A;VAI SYMBOL DANG;Lo;0;L;;;;;N;;;;;
+A61B;VAI SYMBOL DOONG;Lo;0;L;;;;;N;;;;;
+A61C;VAI SYMBOL KUNG;Lo;0;L;;;;;N;;;;;
+A61D;VAI SYMBOL TONG;Lo;0;L;;;;;N;;;;;
+A61E;VAI SYMBOL DO-O;Lo;0;L;;;;;N;;;;;
+A61F;VAI SYMBOL JONG;Lo;0;L;;;;;N;;;;;
+A620;VAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+A621;VAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+A622;VAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+A623;VAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+A624;VAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+A625;VAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+A626;VAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+A627;VAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+A628;VAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+A629;VAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+A62A;VAI SYLLABLE NDOLE MA;Lo;0;L;;;;;N;;;;;
+A62B;VAI SYLLABLE NDOLE DO;Lo;0;L;;;;;N;;;;;
+A640;CYRILLIC CAPITAL LETTER ZEMLYA;Lu;0;L;;;;;N;;;;A641;
+A641;CYRILLIC SMALL LETTER ZEMLYA;Ll;0;L;;;;;N;;;A640;;A640
+A642;CYRILLIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;A643;
+A643;CYRILLIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;A642;;A642
+A644;CYRILLIC CAPITAL LETTER REVERSED DZE;Lu;0;L;;;;;N;;;;A645;
+A645;CYRILLIC SMALL LETTER REVERSED DZE;Ll;0;L;;;;;N;;;A644;;A644
+A646;CYRILLIC CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;A647;
+A647;CYRILLIC SMALL LETTER IOTA;Ll;0;L;;;;;N;;;A646;;A646
+A648;CYRILLIC CAPITAL LETTER DJERV;Lu;0;L;;;;;N;;;;A649;
+A649;CYRILLIC SMALL LETTER DJERV;Ll;0;L;;;;;N;;;A648;;A648
+A64A;CYRILLIC CAPITAL LETTER MONOGRAPH UK;Lu;0;L;;;;;N;;;;A64B;
+A64B;CYRILLIC SMALL LETTER MONOGRAPH UK;Ll;0;L;;;;;N;;;A64A;;A64A
+A64C;CYRILLIC CAPITAL LETTER BROAD OMEGA;Lu;0;L;;;;;N;;;;A64D;
+A64D;CYRILLIC SMALL LETTER BROAD OMEGA;Ll;0;L;;;;;N;;;A64C;;A64C
+A64E;CYRILLIC CAPITAL LETTER NEUTRAL YER;Lu;0;L;;;;;N;;;;A64F;
+A64F;CYRILLIC SMALL LETTER NEUTRAL YER;Ll;0;L;;;;;N;;;A64E;;A64E
+A650;CYRILLIC CAPITAL LETTER YERU WITH BACK YER;Lu;0;L;;;;;N;;;;A651;
+A651;CYRILLIC SMALL LETTER YERU WITH BACK YER;Ll;0;L;;;;;N;;;A650;;A650
+A652;CYRILLIC CAPITAL LETTER IOTIFIED YAT;Lu;0;L;;;;;N;;;;A653;
+A653;CYRILLIC SMALL LETTER IOTIFIED YAT;Ll;0;L;;;;;N;;;A652;;A652
+A654;CYRILLIC CAPITAL LETTER REVERSED YU;Lu;0;L;;;;;N;;;;A655;
+A655;CYRILLIC SMALL LETTER REVERSED YU;Ll;0;L;;;;;N;;;A654;;A654
+A656;CYRILLIC CAPITAL LETTER IOTIFIED A;Lu;0;L;;;;;N;;;;A657;
+A657;CYRILLIC SMALL LETTER IOTIFIED A;Ll;0;L;;;;;N;;;A656;;A656
+A658;CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A659;
+A659;CYRILLIC SMALL LETTER CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A658;;A658
+A65A;CYRILLIC CAPITAL LETTER BLENDED YUS;Lu;0;L;;;;;N;;;;A65B;
+A65B;CYRILLIC SMALL LETTER BLENDED YUS;Ll;0;L;;;;;N;;;A65A;;A65A
+A65C;CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A65D;
+A65D;CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A65C;;A65C
+A65E;CYRILLIC CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;A65F;
+A65F;CYRILLIC SMALL LETTER YN;Ll;0;L;;;;;N;;;A65E;;A65E
+A660;CYRILLIC CAPITAL LETTER REVERSED TSE;Lu;0;L;;;;;N;;;;A661;
+A661;CYRILLIC SMALL LETTER REVERSED TSE;Ll;0;L;;;;;N;;;A660;;A660
+A662;CYRILLIC CAPITAL LETTER SOFT DE;Lu;0;L;;;;;N;;;;A663;
+A663;CYRILLIC SMALL LETTER SOFT DE;Ll;0;L;;;;;N;;;A662;;A662
+A664;CYRILLIC CAPITAL LETTER SOFT EL;Lu;0;L;;;;;N;;;;A665;
+A665;CYRILLIC SMALL LETTER SOFT EL;Ll;0;L;;;;;N;;;A664;;A664
+A666;CYRILLIC CAPITAL LETTER SOFT EM;Lu;0;L;;;;;N;;;;A667;
+A667;CYRILLIC SMALL LETTER SOFT EM;Ll;0;L;;;;;N;;;A666;;A666
+A668;CYRILLIC CAPITAL LETTER MONOCULAR O;Lu;0;L;;;;;N;;;;A669;
+A669;CYRILLIC SMALL LETTER MONOCULAR O;Ll;0;L;;;;;N;;;A668;;A668
+A66A;CYRILLIC CAPITAL LETTER BINOCULAR O;Lu;0;L;;;;;N;;;;A66B;
+A66B;CYRILLIC SMALL LETTER BINOCULAR O;Ll;0;L;;;;;N;;;A66A;;A66A
+A66C;CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O;Lu;0;L;;;;;N;;;;A66D;
+A66D;CYRILLIC SMALL LETTER DOUBLE MONOCULAR O;Ll;0;L;;;;;N;;;A66C;;A66C
+A66E;CYRILLIC LETTER MULTIOCULAR O;Lo;0;L;;;;;N;;;;;
+A66F;COMBINING CYRILLIC VZMET;Mn;230;NSM;;;;;N;;;;;
+A670;COMBINING CYRILLIC TEN MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
+A671;COMBINING CYRILLIC HUNDRED MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
+A672;COMBINING CYRILLIC THOUSAND MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
+A673;SLAVONIC ASTERISK;Po;0;ON;;;;;N;;;;;
+A674;COMBINING CYRILLIC LETTER UKRAINIAN IE;Mn;230;NSM;;;;;N;;;;;
+A675;COMBINING CYRILLIC LETTER I;Mn;230;NSM;;;;;N;;;;;
+A676;COMBINING CYRILLIC LETTER YI;Mn;230;NSM;;;;;N;;;;;
+A677;COMBINING CYRILLIC LETTER U;Mn;230;NSM;;;;;N;;;;;
+A678;COMBINING CYRILLIC LETTER HARD SIGN;Mn;230;NSM;;;;;N;;;;;
+A679;COMBINING CYRILLIC LETTER YERU;Mn;230;NSM;;;;;N;;;;;
+A67A;COMBINING CYRILLIC LETTER SOFT SIGN;Mn;230;NSM;;;;;N;;;;;
+A67B;COMBINING CYRILLIC LETTER OMEGA;Mn;230;NSM;;;;;N;;;;;
+A67C;COMBINING CYRILLIC KAVYKA;Mn;230;NSM;;;;;N;;;;;
+A67D;COMBINING CYRILLIC PAYEROK;Mn;230;NSM;;;;;N;;;;;
+A67E;CYRILLIC KAVYKA;Po;0;ON;;;;;N;;;;;
+A67F;CYRILLIC PAYEROK;Lm;0;ON;;;;;N;;;;;
+A680;CYRILLIC CAPITAL LETTER DWE;Lu;0;L;;;;;N;;;;A681;
+A681;CYRILLIC SMALL LETTER DWE;Ll;0;L;;;;;N;;;A680;;A680
+A682;CYRILLIC CAPITAL LETTER DZWE;Lu;0;L;;;;;N;;;;A683;
+A683;CYRILLIC SMALL LETTER DZWE;Ll;0;L;;;;;N;;;A682;;A682
+A684;CYRILLIC CAPITAL LETTER ZHWE;Lu;0;L;;;;;N;;;;A685;
+A685;CYRILLIC SMALL LETTER ZHWE;Ll;0;L;;;;;N;;;A684;;A684
+A686;CYRILLIC CAPITAL LETTER CCHE;Lu;0;L;;;;;N;;;;A687;
+A687;CYRILLIC SMALL LETTER CCHE;Ll;0;L;;;;;N;;;A686;;A686
+A688;CYRILLIC CAPITAL LETTER DZZE;Lu;0;L;;;;;N;;;;A689;
+A689;CYRILLIC SMALL LETTER DZZE;Ll;0;L;;;;;N;;;A688;;A688
+A68A;CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;A68B;
+A68B;CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;A68A;;A68A
+A68C;CYRILLIC CAPITAL LETTER TWE;Lu;0;L;;;;;N;;;;A68D;
+A68D;CYRILLIC SMALL LETTER TWE;Ll;0;L;;;;;N;;;A68C;;A68C
+A68E;CYRILLIC CAPITAL LETTER TSWE;Lu;0;L;;;;;N;;;;A68F;
+A68F;CYRILLIC SMALL LETTER TSWE;Ll;0;L;;;;;N;;;A68E;;A68E
+A690;CYRILLIC CAPITAL LETTER TSSE;Lu;0;L;;;;;N;;;;A691;
+A691;CYRILLIC SMALL LETTER TSSE;Ll;0;L;;;;;N;;;A690;;A690
+A692;CYRILLIC CAPITAL LETTER TCHE;Lu;0;L;;;;;N;;;;A693;
+A693;CYRILLIC SMALL LETTER TCHE;Ll;0;L;;;;;N;;;A692;;A692
+A694;CYRILLIC CAPITAL LETTER HWE;Lu;0;L;;;;;N;;;;A695;
+A695;CYRILLIC SMALL LETTER HWE;Ll;0;L;;;;;N;;;A694;;A694
+A696;CYRILLIC CAPITAL LETTER SHWE;Lu;0;L;;;;;N;;;;A697;
+A697;CYRILLIC SMALL LETTER SHWE;Ll;0;L;;;;;N;;;A696;;A696
+A698;CYRILLIC CAPITAL LETTER DOUBLE O;Lu;0;L;;;;;N;;;;A699;
+A699;CYRILLIC SMALL LETTER DOUBLE O;Ll;0;L;;;;;N;;;A698;;A698
+A69A;CYRILLIC CAPITAL LETTER CROSSED O;Lu;0;L;;;;;N;;;;A69B;
+A69B;CYRILLIC SMALL LETTER CROSSED O;Ll;0;L;;;;;N;;;A69A;;A69A
+A69C;MODIFIER LETTER CYRILLIC HARD SIGN;Lm;0;L;<super> 044A;;;;N;;;;;
+A69D;MODIFIER LETTER CYRILLIC SOFT SIGN;Lm;0;L;<super> 044C;;;;N;;;;;
+A69E;COMBINING CYRILLIC LETTER EF;Mn;230;NSM;;;;;N;;;;;
+A69F;COMBINING CYRILLIC LETTER IOTIFIED E;Mn;230;NSM;;;;;N;;;;;
+A6A0;BAMUM LETTER A;Lo;0;L;;;;;N;;;;;
+A6A1;BAMUM LETTER KA;Lo;0;L;;;;;N;;;;;
+A6A2;BAMUM LETTER U;Lo;0;L;;;;;N;;;;;
+A6A3;BAMUM LETTER KU;Lo;0;L;;;;;N;;;;;
+A6A4;BAMUM LETTER EE;Lo;0;L;;;;;N;;;;;
+A6A5;BAMUM LETTER REE;Lo;0;L;;;;;N;;;;;
+A6A6;BAMUM LETTER TAE;Lo;0;L;;;;;N;;;;;
+A6A7;BAMUM LETTER O;Lo;0;L;;;;;N;;;;;
+A6A8;BAMUM LETTER NYI;Lo;0;L;;;;;N;;;;;
+A6A9;BAMUM LETTER I;Lo;0;L;;;;;N;;;;;
+A6AA;BAMUM LETTER LA;Lo;0;L;;;;;N;;;;;
+A6AB;BAMUM LETTER PA;Lo;0;L;;;;;N;;;;;
+A6AC;BAMUM LETTER RII;Lo;0;L;;;;;N;;;;;
+A6AD;BAMUM LETTER RIEE;Lo;0;L;;;;;N;;;;;
+A6AE;BAMUM LETTER LEEEE;Lo;0;L;;;;;N;;;;;
+A6AF;BAMUM LETTER MEEEE;Lo;0;L;;;;;N;;;;;
+A6B0;BAMUM LETTER TAA;Lo;0;L;;;;;N;;;;;
+A6B1;BAMUM LETTER NDAA;Lo;0;L;;;;;N;;;;;
+A6B2;BAMUM LETTER NJAEM;Lo;0;L;;;;;N;;;;;
+A6B3;BAMUM LETTER M;Lo;0;L;;;;;N;;;;;
+A6B4;BAMUM LETTER SUU;Lo;0;L;;;;;N;;;;;
+A6B5;BAMUM LETTER MU;Lo;0;L;;;;;N;;;;;
+A6B6;BAMUM LETTER SHII;Lo;0;L;;;;;N;;;;;
+A6B7;BAMUM LETTER SI;Lo;0;L;;;;;N;;;;;
+A6B8;BAMUM LETTER SHEUX;Lo;0;L;;;;;N;;;;;
+A6B9;BAMUM LETTER SEUX;Lo;0;L;;;;;N;;;;;
+A6BA;BAMUM LETTER KYEE;Lo;0;L;;;;;N;;;;;
+A6BB;BAMUM LETTER KET;Lo;0;L;;;;;N;;;;;
+A6BC;BAMUM LETTER NUAE;Lo;0;L;;;;;N;;;;;
+A6BD;BAMUM LETTER NU;Lo;0;L;;;;;N;;;;;
+A6BE;BAMUM LETTER NJUAE;Lo;0;L;;;;;N;;;;;
+A6BF;BAMUM LETTER YOQ;Lo;0;L;;;;;N;;;;;
+A6C0;BAMUM LETTER SHU;Lo;0;L;;;;;N;;;;;
+A6C1;BAMUM LETTER YUQ;Lo;0;L;;;;;N;;;;;
+A6C2;BAMUM LETTER YA;Lo;0;L;;;;;N;;;;;
+A6C3;BAMUM LETTER NSHA;Lo;0;L;;;;;N;;;;;
+A6C4;BAMUM LETTER KEUX;Lo;0;L;;;;;N;;;;;
+A6C5;BAMUM LETTER PEUX;Lo;0;L;;;;;N;;;;;
+A6C6;BAMUM LETTER NJEE;Lo;0;L;;;;;N;;;;;
+A6C7;BAMUM LETTER NTEE;Lo;0;L;;;;;N;;;;;
+A6C8;BAMUM LETTER PUE;Lo;0;L;;;;;N;;;;;
+A6C9;BAMUM LETTER WUE;Lo;0;L;;;;;N;;;;;
+A6CA;BAMUM LETTER PEE;Lo;0;L;;;;;N;;;;;
+A6CB;BAMUM LETTER FEE;Lo;0;L;;;;;N;;;;;
+A6CC;BAMUM LETTER RU;Lo;0;L;;;;;N;;;;;
+A6CD;BAMUM LETTER LU;Lo;0;L;;;;;N;;;;;
+A6CE;BAMUM LETTER MI;Lo;0;L;;;;;N;;;;;
+A6CF;BAMUM LETTER NI;Lo;0;L;;;;;N;;;;;
+A6D0;BAMUM LETTER REUX;Lo;0;L;;;;;N;;;;;
+A6D1;BAMUM LETTER RAE;Lo;0;L;;;;;N;;;;;
+A6D2;BAMUM LETTER KEN;Lo;0;L;;;;;N;;;;;
+A6D3;BAMUM LETTER NGKWAEN;Lo;0;L;;;;;N;;;;;
+A6D4;BAMUM LETTER NGGA;Lo;0;L;;;;;N;;;;;
+A6D5;BAMUM LETTER NGA;Lo;0;L;;;;;N;;;;;
+A6D6;BAMUM LETTER SHO;Lo;0;L;;;;;N;;;;;
+A6D7;BAMUM LETTER PUAE;Lo;0;L;;;;;N;;;;;
+A6D8;BAMUM LETTER FU;Lo;0;L;;;;;N;;;;;
+A6D9;BAMUM LETTER FOM;Lo;0;L;;;;;N;;;;;
+A6DA;BAMUM LETTER WA;Lo;0;L;;;;;N;;;;;
+A6DB;BAMUM LETTER NA;Lo;0;L;;;;;N;;;;;
+A6DC;BAMUM LETTER LI;Lo;0;L;;;;;N;;;;;
+A6DD;BAMUM LETTER PI;Lo;0;L;;;;;N;;;;;
+A6DE;BAMUM LETTER LOQ;Lo;0;L;;;;;N;;;;;
+A6DF;BAMUM LETTER KO;Lo;0;L;;;;;N;;;;;
+A6E0;BAMUM LETTER MBEN;Lo;0;L;;;;;N;;;;;
+A6E1;BAMUM LETTER REN;Lo;0;L;;;;;N;;;;;
+A6E2;BAMUM LETTER MEN;Lo;0;L;;;;;N;;;;;
+A6E3;BAMUM LETTER MA;Lo;0;L;;;;;N;;;;;
+A6E4;BAMUM LETTER TI;Lo;0;L;;;;;N;;;;;
+A6E5;BAMUM LETTER KI;Lo;0;L;;;;;N;;;;;
+A6E6;BAMUM LETTER MO;Nl;0;L;;;;1;N;;;;;
+A6E7;BAMUM LETTER MBAA;Nl;0;L;;;;2;N;;;;;
+A6E8;BAMUM LETTER TET;Nl;0;L;;;;3;N;;;;;
+A6E9;BAMUM LETTER KPA;Nl;0;L;;;;4;N;;;;;
+A6EA;BAMUM LETTER TEN;Nl;0;L;;;;5;N;;;;;
+A6EB;BAMUM LETTER NTUU;Nl;0;L;;;;6;N;;;;;
+A6EC;BAMUM LETTER SAMBA;Nl;0;L;;;;7;N;;;;;
+A6ED;BAMUM LETTER FAAMAE;Nl;0;L;;;;8;N;;;;;
+A6EE;BAMUM LETTER KOVUU;Nl;0;L;;;;9;N;;;;;
+A6EF;BAMUM LETTER KOGHOM;Nl;0;L;;;;0;N;;;;;
+A6F0;BAMUM COMBINING MARK KOQNDON;Mn;230;NSM;;;;;N;;;;;
+A6F1;BAMUM COMBINING MARK TUKWENTIS;Mn;230;NSM;;;;;N;;;;;
+A6F2;BAMUM NJAEMLI;Po;0;L;;;;;N;;;;;
+A6F3;BAMUM FULL STOP;Po;0;L;;;;;N;;;;;
+A6F4;BAMUM COLON;Po;0;L;;;;;N;;;;;
+A6F5;BAMUM COMMA;Po;0;L;;;;;N;;;;;
+A6F6;BAMUM SEMICOLON;Po;0;L;;;;;N;;;;;
+A6F7;BAMUM QUESTION MARK;Po;0;L;;;;;N;;;;;
+A700;MODIFIER LETTER CHINESE TONE YIN PING;Sk;0;ON;;;;;N;;;;;
+A701;MODIFIER LETTER CHINESE TONE YANG PING;Sk;0;ON;;;;;N;;;;;
+A702;MODIFIER LETTER CHINESE TONE YIN SHANG;Sk;0;ON;;;;;N;;;;;
+A703;MODIFIER LETTER CHINESE TONE YANG SHANG;Sk;0;ON;;;;;N;;;;;
+A704;MODIFIER LETTER CHINESE TONE YIN QU;Sk;0;ON;;;;;N;;;;;
+A705;MODIFIER LETTER CHINESE TONE YANG QU;Sk;0;ON;;;;;N;;;;;
+A706;MODIFIER LETTER CHINESE TONE YIN RU;Sk;0;ON;;;;;N;;;;;
+A707;MODIFIER LETTER CHINESE TONE YANG RU;Sk;0;ON;;;;;N;;;;;
+A708;MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
+A709;MODIFIER LETTER HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70A;MODIFIER LETTER MID DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70B;MODIFIER LETTER LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70C;MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70D;MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70E;MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A70F;MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A710;MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A711;MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A712;MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A713;MODIFIER LETTER HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A714;MODIFIER LETTER MID LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A715;MODIFIER LETTER LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A716;MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
+A717;MODIFIER LETTER DOT VERTICAL BAR;Lm;0;ON;;;;;N;;;;;
+A718;MODIFIER LETTER DOT SLASH;Lm;0;ON;;;;;N;;;;;
+A719;MODIFIER LETTER DOT HORIZONTAL BAR;Lm;0;ON;;;;;N;;;;;
+A71A;MODIFIER LETTER LOWER RIGHT CORNER ANGLE;Lm;0;ON;;;;;N;;;;;
+A71B;MODIFIER LETTER RAISED UP ARROW;Lm;0;ON;;;;;N;;;;;
+A71C;MODIFIER LETTER RAISED DOWN ARROW;Lm;0;ON;;;;;N;;;;;
+A71D;MODIFIER LETTER RAISED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;
+A71E;MODIFIER LETTER RAISED INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;
+A71F;MODIFIER LETTER LOW INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;
+A720;MODIFIER LETTER STRESS AND HIGH TONE;Sk;0;ON;;;;;N;;;;;
+A721;MODIFIER LETTER STRESS AND LOW TONE;Sk;0;ON;;;;;N;;;;;
+A722;LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF;Lu;0;L;;;;;N;;;;A723;
+A723;LATIN SMALL LETTER EGYPTOLOGICAL ALEF;Ll;0;L;;;;;N;;;A722;;A722
+A724;LATIN CAPITAL LETTER EGYPTOLOGICAL AIN;Lu;0;L;;;;;N;;;;A725;
+A725;LATIN SMALL LETTER EGYPTOLOGICAL AIN;Ll;0;L;;;;;N;;;A724;;A724
+A726;LATIN CAPITAL LETTER HENG;Lu;0;L;;;;;N;;;;A727;
+A727;LATIN SMALL LETTER HENG;Ll;0;L;;;;;N;;;A726;;A726
+A728;LATIN CAPITAL LETTER TZ;Lu;0;L;;;;;N;;;;A729;
+A729;LATIN SMALL LETTER TZ;Ll;0;L;;;;;N;;;A728;;A728
+A72A;LATIN CAPITAL LETTER TRESILLO;Lu;0;L;;;;;N;;;;A72B;
+A72B;LATIN SMALL LETTER TRESILLO;Ll;0;L;;;;;N;;;A72A;;A72A
+A72C;LATIN CAPITAL LETTER CUATRILLO;Lu;0;L;;;;;N;;;;A72D;
+A72D;LATIN SMALL LETTER CUATRILLO;Ll;0;L;;;;;N;;;A72C;;A72C
+A72E;LATIN CAPITAL LETTER CUATRILLO WITH COMMA;Lu;0;L;;;;;N;;;;A72F;
+A72F;LATIN SMALL LETTER CUATRILLO WITH COMMA;Ll;0;L;;;;;N;;;A72E;;A72E
+A730;LATIN LETTER SMALL CAPITAL F;Ll;0;L;;;;;N;;;;;
+A731;LATIN LETTER SMALL CAPITAL S;Ll;0;L;;;;;N;;;;;
+A732;LATIN CAPITAL LETTER AA;Lu;0;L;;;;;N;;;;A733;
+A733;LATIN SMALL LETTER AA;Ll;0;L;;;;;N;;;A732;;A732
+A734;LATIN CAPITAL LETTER AO;Lu;0;L;;;;;N;;;;A735;
+A735;LATIN SMALL LETTER AO;Ll;0;L;;;;;N;;;A734;;A734
+A736;LATIN CAPITAL LETTER AU;Lu;0;L;;;;;N;;;;A737;
+A737;LATIN SMALL LETTER AU;Ll;0;L;;;;;N;;;A736;;A736
+A738;LATIN CAPITAL LETTER AV;Lu;0;L;;;;;N;;;;A739;
+A739;LATIN SMALL LETTER AV;Ll;0;L;;;;;N;;;A738;;A738
+A73A;LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR;Lu;0;L;;;;;N;;;;A73B;
+A73B;LATIN SMALL LETTER AV WITH HORIZONTAL BAR;Ll;0;L;;;;;N;;;A73A;;A73A
+A73C;LATIN CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;A73D;
+A73D;LATIN SMALL LETTER AY;Ll;0;L;;;;;N;;;A73C;;A73C
+A73E;LATIN CAPITAL LETTER REVERSED C WITH DOT;Lu;0;L;;;;;N;;;;A73F;
+A73F;LATIN SMALL LETTER REVERSED C WITH DOT;Ll;0;L;;;;;N;;;A73E;;A73E
+A740;LATIN CAPITAL LETTER K WITH STROKE;Lu;0;L;;;;;N;;;;A741;
+A741;LATIN SMALL LETTER K WITH STROKE;Ll;0;L;;;;;N;;;A740;;A740
+A742;LATIN CAPITAL LETTER K WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A743;
+A743;LATIN SMALL LETTER K WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A742;;A742
+A744;LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A745;
+A745;LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE;Ll;0;L;;;;;N;;;A744;;A744
+A746;LATIN CAPITAL LETTER BROKEN L;Lu;0;L;;;;;N;;;;A747;
+A747;LATIN SMALL LETTER BROKEN L;Ll;0;L;;;;;N;;;A746;;A746
+A748;LATIN CAPITAL LETTER L WITH HIGH STROKE;Lu;0;L;;;;;N;;;;A749;
+A749;LATIN SMALL LETTER L WITH HIGH STROKE;Ll;0;L;;;;;N;;;A748;;A748
+A74A;LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY;Lu;0;L;;;;;N;;;;A74B;
+A74B;LATIN SMALL LETTER O WITH LONG STROKE OVERLAY;Ll;0;L;;;;;N;;;A74A;;A74A
+A74C;LATIN CAPITAL LETTER O WITH LOOP;Lu;0;L;;;;;N;;;;A74D;
+A74D;LATIN SMALL LETTER O WITH LOOP;Ll;0;L;;;;;N;;;A74C;;A74C
+A74E;LATIN CAPITAL LETTER OO;Lu;0;L;;;;;N;;;;A74F;
+A74F;LATIN SMALL LETTER OO;Ll;0;L;;;;;N;;;A74E;;A74E
+A750;LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A751;
+A751;LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A750;;A750
+A752;LATIN CAPITAL LETTER P WITH FLOURISH;Lu;0;L;;;;;N;;;;A753;
+A753;LATIN SMALL LETTER P WITH FLOURISH;Ll;0;L;;;;;N;;;A752;;A752
+A754;LATIN CAPITAL LETTER P WITH SQUIRREL TAIL;Lu;0;L;;;;;N;;;;A755;
+A755;LATIN SMALL LETTER P WITH SQUIRREL TAIL;Ll;0;L;;;;;N;;;A754;;A754
+A756;LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A757;
+A757;LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A756;;A756
+A758;LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A759;
+A759;LATIN SMALL LETTER Q WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A758;;A758
+A75A;LATIN CAPITAL LETTER R ROTUNDA;Lu;0;L;;;;;N;;;;A75B;
+A75B;LATIN SMALL LETTER R ROTUNDA;Ll;0;L;;;;;N;;;A75A;;A75A
+A75C;LATIN CAPITAL LETTER RUM ROTUNDA;Lu;0;L;;;;;N;;;;A75D;
+A75D;LATIN SMALL LETTER RUM ROTUNDA;Ll;0;L;;;;;N;;;A75C;;A75C
+A75E;LATIN CAPITAL LETTER V WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A75F;
+A75F;LATIN SMALL LETTER V WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A75E;;A75E
+A760;LATIN CAPITAL LETTER VY;Lu;0;L;;;;;N;;;;A761;
+A761;LATIN SMALL LETTER VY;Ll;0;L;;;;;N;;;A760;;A760
+A762;LATIN CAPITAL LETTER VISIGOTHIC Z;Lu;0;L;;;;;N;;;;A763;
+A763;LATIN SMALL LETTER VISIGOTHIC Z;Ll;0;L;;;;;N;;;A762;;A762
+A764;LATIN CAPITAL LETTER THORN WITH STROKE;Lu;0;L;;;;;N;;;;A765;
+A765;LATIN SMALL LETTER THORN WITH STROKE;Ll;0;L;;;;;N;;;A764;;A764
+A766;LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A767;
+A767;LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A766;;A766
+A768;LATIN CAPITAL LETTER VEND;Lu;0;L;;;;;N;;;;A769;
+A769;LATIN SMALL LETTER VEND;Ll;0;L;;;;;N;;;A768;;A768
+A76A;LATIN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;A76B;
+A76B;LATIN SMALL LETTER ET;Ll;0;L;;;;;N;;;A76A;;A76A
+A76C;LATIN CAPITAL LETTER IS;Lu;0;L;;;;;N;;;;A76D;
+A76D;LATIN SMALL LETTER IS;Ll;0;L;;;;;N;;;A76C;;A76C
+A76E;LATIN CAPITAL LETTER CON;Lu;0;L;;;;;N;;;;A76F;
+A76F;LATIN SMALL LETTER CON;Ll;0;L;;;;;N;;;A76E;;A76E
+A770;MODIFIER LETTER US;Lm;0;L;<super> A76F;;;;N;;;;;
+A771;LATIN SMALL LETTER DUM;Ll;0;L;;;;;N;;;;;
+A772;LATIN SMALL LETTER LUM;Ll;0;L;;;;;N;;;;;
+A773;LATIN SMALL LETTER MUM;Ll;0;L;;;;;N;;;;;
+A774;LATIN SMALL LETTER NUM;Ll;0;L;;;;;N;;;;;
+A775;LATIN SMALL LETTER RUM;Ll;0;L;;;;;N;;;;;
+A776;LATIN LETTER SMALL CAPITAL RUM;Ll;0;L;;;;;N;;;;;
+A777;LATIN SMALL LETTER TUM;Ll;0;L;;;;;N;;;;;
+A778;LATIN SMALL LETTER UM;Ll;0;L;;;;;N;;;;;
+A779;LATIN CAPITAL LETTER INSULAR D;Lu;0;L;;;;;N;;;;A77A;
+A77A;LATIN SMALL LETTER INSULAR D;Ll;0;L;;;;;N;;;A779;;A779
+A77B;LATIN CAPITAL LETTER INSULAR F;Lu;0;L;;;;;N;;;;A77C;
+A77C;LATIN SMALL LETTER INSULAR F;Ll;0;L;;;;;N;;;A77B;;A77B
+A77D;LATIN CAPITAL LETTER INSULAR G;Lu;0;L;;;;;N;;;;1D79;
+A77E;LATIN CAPITAL LETTER TURNED INSULAR G;Lu;0;L;;;;;N;;;;A77F;
+A77F;LATIN SMALL LETTER TURNED INSULAR G;Ll;0;L;;;;;N;;;A77E;;A77E
+A780;LATIN CAPITAL LETTER TURNED L;Lu;0;L;;;;;N;;;;A781;
+A781;LATIN SMALL LETTER TURNED L;Ll;0;L;;;;;N;;;A780;;A780
+A782;LATIN CAPITAL LETTER INSULAR R;Lu;0;L;;;;;N;;;;A783;
+A783;LATIN SMALL LETTER INSULAR R;Ll;0;L;;;;;N;;;A782;;A782
+A784;LATIN CAPITAL LETTER INSULAR S;Lu;0;L;;;;;N;;;;A785;
+A785;LATIN SMALL LETTER INSULAR S;Ll;0;L;;;;;N;;;A784;;A784
+A786;LATIN CAPITAL LETTER INSULAR T;Lu;0;L;;;;;N;;;;A787;
+A787;LATIN SMALL LETTER INSULAR T;Ll;0;L;;;;;N;;;A786;;A786
+A788;MODIFIER LETTER LOW CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;;;;;
+A789;MODIFIER LETTER COLON;Sk;0;L;;;;;N;;;;;
+A78A;MODIFIER LETTER SHORT EQUALS SIGN;Sk;0;L;;;;;N;;;;;
+A78B;LATIN CAPITAL LETTER SALTILLO;Lu;0;L;;;;;N;;;;A78C;
+A78C;LATIN SMALL LETTER SALTILLO;Ll;0;L;;;;;N;;;A78B;;A78B
+A78D;LATIN CAPITAL LETTER TURNED H;Lu;0;L;;;;;N;;;;0265;
+A78E;LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT;Ll;0;L;;;;;N;;;;;
+A78F;LATIN LETTER SINOLOGICAL DOT;Lo;0;L;;;;;N;;;;;
+A790;LATIN CAPITAL LETTER N WITH DESCENDER;Lu;0;L;;;;;N;;;;A791;
+A791;LATIN SMALL LETTER N WITH DESCENDER;Ll;0;L;;;;;N;;;A790;;A790
+A792;LATIN CAPITAL LETTER C WITH BAR;Lu;0;L;;;;;N;;;;A793;
+A793;LATIN SMALL LETTER C WITH BAR;Ll;0;L;;;;;N;;;A792;;A792
+A794;LATIN SMALL LETTER C WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+A795;LATIN SMALL LETTER H WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+A796;LATIN CAPITAL LETTER B WITH FLOURISH;Lu;0;L;;;;;N;;;;A797;
+A797;LATIN SMALL LETTER B WITH FLOURISH;Ll;0;L;;;;;N;;;A796;;A796
+A798;LATIN CAPITAL LETTER F WITH STROKE;Lu;0;L;;;;;N;;;;A799;
+A799;LATIN SMALL LETTER F WITH STROKE;Ll;0;L;;;;;N;;;A798;;A798
+A79A;LATIN CAPITAL LETTER VOLAPUK AE;Lu;0;L;;;;;N;;;;A79B;
+A79B;LATIN SMALL LETTER VOLAPUK AE;Ll;0;L;;;;;N;;;A79A;;A79A
+A79C;LATIN CAPITAL LETTER VOLAPUK OE;Lu;0;L;;;;;N;;;;A79D;
+A79D;LATIN SMALL LETTER VOLAPUK OE;Ll;0;L;;;;;N;;;A79C;;A79C
+A79E;LATIN CAPITAL LETTER VOLAPUK UE;Lu;0;L;;;;;N;;;;A79F;
+A79F;LATIN SMALL LETTER VOLAPUK UE;Ll;0;L;;;;;N;;;A79E;;A79E
+A7A0;LATIN CAPITAL LETTER G WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A1;
+A7A1;LATIN SMALL LETTER G WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A0;;A7A0
+A7A2;LATIN CAPITAL LETTER K WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A3;
+A7A3;LATIN SMALL LETTER K WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A2;;A7A2
+A7A4;LATIN CAPITAL LETTER N WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A5;
+A7A5;LATIN SMALL LETTER N WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A4;;A7A4
+A7A6;LATIN CAPITAL LETTER R WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A7;
+A7A7;LATIN SMALL LETTER R WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A6;;A7A6
+A7A8;LATIN CAPITAL LETTER S WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A9;
+A7A9;LATIN SMALL LETTER S WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A8;;A7A8
+A7AA;LATIN CAPITAL LETTER H WITH HOOK;Lu;0;L;;;;;N;;;;0266;
+A7AB;LATIN CAPITAL LETTER REVERSED OPEN E;Lu;0;L;;;;;N;;;;025C;
+A7AC;LATIN CAPITAL LETTER SCRIPT G;Lu;0;L;;;;;N;;;;0261;
+A7AD;LATIN CAPITAL LETTER L WITH BELT;Lu;0;L;;;;;N;;;;026C;
+A7AE;LATIN CAPITAL LETTER SMALL CAPITAL I;Lu;0;L;;;;;N;;;;026A;
+A7B0;LATIN CAPITAL LETTER TURNED K;Lu;0;L;;;;;N;;;;029E;
+A7B1;LATIN CAPITAL LETTER TURNED T;Lu;0;L;;;;;N;;;;0287;
+A7B2;LATIN CAPITAL LETTER J WITH CROSSED-TAIL;Lu;0;L;;;;;N;;;;029D;
+A7B3;LATIN CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;AB53;
+A7B4;LATIN CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;A7B5;
+A7B5;LATIN SMALL LETTER BETA;Ll;0;L;;;;;N;;;A7B4;;A7B4
+A7B6;LATIN CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;A7B7;
+A7B7;LATIN SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;A7B6;;A7B6
+A7F7;LATIN EPIGRAPHIC LETTER SIDEWAYS I;Lo;0;L;;;;;N;;;;;
+A7F8;MODIFIER LETTER CAPITAL H WITH STROKE;Lm;0;L;<super> 0126;;;;N;;;;;
+A7F9;MODIFIER LETTER SMALL LIGATURE OE;Lm;0;L;<super> 0153;;;;N;;;;;
+A7FA;LATIN LETTER SMALL CAPITAL TURNED M;Ll;0;L;;;;;N;;;;;
+A7FB;LATIN EPIGRAPHIC LETTER REVERSED F;Lo;0;L;;;;;N;;;;;
+A7FC;LATIN EPIGRAPHIC LETTER REVERSED P;Lo;0;L;;;;;N;;;;;
+A7FD;LATIN EPIGRAPHIC LETTER INVERTED M;Lo;0;L;;;;;N;;;;;
+A7FE;LATIN EPIGRAPHIC LETTER I LONGA;Lo;0;L;;;;;N;;;;;
+A7FF;LATIN EPIGRAPHIC LETTER ARCHAIC M;Lo;0;L;;;;;N;;;;;
+A800;SYLOTI NAGRI LETTER A;Lo;0;L;;;;;N;;;;;
+A801;SYLOTI NAGRI LETTER I;Lo;0;L;;;;;N;;;;;
+A802;SYLOTI NAGRI SIGN DVISVARA;Mn;0;NSM;;;;;N;;;;;
+A803;SYLOTI NAGRI LETTER U;Lo;0;L;;;;;N;;;;;
+A804;SYLOTI NAGRI LETTER E;Lo;0;L;;;;;N;;;;;
+A805;SYLOTI NAGRI LETTER O;Lo;0;L;;;;;N;;;;;
+A806;SYLOTI NAGRI SIGN HASANTA;Mn;9;NSM;;;;;N;;;;;
+A807;SYLOTI NAGRI LETTER KO;Lo;0;L;;;;;N;;;;;
+A808;SYLOTI NAGRI LETTER KHO;Lo;0;L;;;;;N;;;;;
+A809;SYLOTI NAGRI LETTER GO;Lo;0;L;;;;;N;;;;;
+A80A;SYLOTI NAGRI LETTER GHO;Lo;0;L;;;;;N;;;;;
+A80B;SYLOTI NAGRI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+A80C;SYLOTI NAGRI LETTER CO;Lo;0;L;;;;;N;;;;;
+A80D;SYLOTI NAGRI LETTER CHO;Lo;0;L;;;;;N;;;;;
+A80E;SYLOTI NAGRI LETTER JO;Lo;0;L;;;;;N;;;;;
+A80F;SYLOTI NAGRI LETTER JHO;Lo;0;L;;;;;N;;;;;
+A810;SYLOTI NAGRI LETTER TTO;Lo;0;L;;;;;N;;;;;
+A811;SYLOTI NAGRI LETTER TTHO;Lo;0;L;;;;;N;;;;;
+A812;SYLOTI NAGRI LETTER DDO;Lo;0;L;;;;;N;;;;;
+A813;SYLOTI NAGRI LETTER DDHO;Lo;0;L;;;;;N;;;;;
+A814;SYLOTI NAGRI LETTER TO;Lo;0;L;;;;;N;;;;;
+A815;SYLOTI NAGRI LETTER THO;Lo;0;L;;;;;N;;;;;
+A816;SYLOTI NAGRI LETTER DO;Lo;0;L;;;;;N;;;;;
+A817;SYLOTI NAGRI LETTER DHO;Lo;0;L;;;;;N;;;;;
+A818;SYLOTI NAGRI LETTER NO;Lo;0;L;;;;;N;;;;;
+A819;SYLOTI NAGRI LETTER PO;Lo;0;L;;;;;N;;;;;
+A81A;SYLOTI NAGRI LETTER PHO;Lo;0;L;;;;;N;;;;;
+A81B;SYLOTI NAGRI LETTER BO;Lo;0;L;;;;;N;;;;;
+A81C;SYLOTI NAGRI LETTER BHO;Lo;0;L;;;;;N;;;;;
+A81D;SYLOTI NAGRI LETTER MO;Lo;0;L;;;;;N;;;;;
+A81E;SYLOTI NAGRI LETTER RO;Lo;0;L;;;;;N;;;;;
+A81F;SYLOTI NAGRI LETTER LO;Lo;0;L;;;;;N;;;;;
+A820;SYLOTI NAGRI LETTER RRO;Lo;0;L;;;;;N;;;;;
+A821;SYLOTI NAGRI LETTER SO;Lo;0;L;;;;;N;;;;;
+A822;SYLOTI NAGRI LETTER HO;Lo;0;L;;;;;N;;;;;
+A823;SYLOTI NAGRI VOWEL SIGN A;Mc;0;L;;;;;N;;;;;
+A824;SYLOTI NAGRI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+A825;SYLOTI NAGRI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+A826;SYLOTI NAGRI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+A827;SYLOTI NAGRI VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+A828;SYLOTI NAGRI POETRY MARK-1;So;0;ON;;;;;N;;;;;
+A829;SYLOTI NAGRI POETRY MARK-2;So;0;ON;;;;;N;;;;;
+A82A;SYLOTI NAGRI POETRY MARK-3;So;0;ON;;;;;N;;;;;
+A82B;SYLOTI NAGRI POETRY MARK-4;So;0;ON;;;;;N;;;;;
+A830;NORTH INDIC FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;
+A831;NORTH INDIC FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;
+A832;NORTH INDIC FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;
+A833;NORTH INDIC FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;;
+A834;NORTH INDIC FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;
+A835;NORTH INDIC FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;
+A836;NORTH INDIC QUARTER MARK;So;0;L;;;;;N;;;;;
+A837;NORTH INDIC PLACEHOLDER MARK;So;0;L;;;;;N;;;;;
+A838;NORTH INDIC RUPEE MARK;Sc;0;ET;;;;;N;;;;;
+A839;NORTH INDIC QUANTITY MARK;So;0;ET;;;;;N;;;;;
+A840;PHAGS-PA LETTER KA;Lo;0;L;;;;;N;;;;;
+A841;PHAGS-PA LETTER KHA;Lo;0;L;;;;;N;;;;;
+A842;PHAGS-PA LETTER GA;Lo;0;L;;;;;N;;;;;
+A843;PHAGS-PA LETTER NGA;Lo;0;L;;;;;N;;;;;
+A844;PHAGS-PA LETTER CA;Lo;0;L;;;;;N;;;;;
+A845;PHAGS-PA LETTER CHA;Lo;0;L;;;;;N;;;;;
+A846;PHAGS-PA LETTER JA;Lo;0;L;;;;;N;;;;;
+A847;PHAGS-PA LETTER NYA;Lo;0;L;;;;;N;;;;;
+A848;PHAGS-PA LETTER TA;Lo;0;L;;;;;N;;;;;
+A849;PHAGS-PA LETTER THA;Lo;0;L;;;;;N;;;;;
+A84A;PHAGS-PA LETTER DA;Lo;0;L;;;;;N;;;;;
+A84B;PHAGS-PA LETTER NA;Lo;0;L;;;;;N;;;;;
+A84C;PHAGS-PA LETTER PA;Lo;0;L;;;;;N;;;;;
+A84D;PHAGS-PA LETTER PHA;Lo;0;L;;;;;N;;;;;
+A84E;PHAGS-PA LETTER BA;Lo;0;L;;;;;N;;;;;
+A84F;PHAGS-PA LETTER MA;Lo;0;L;;;;;N;;;;;
+A850;PHAGS-PA LETTER TSA;Lo;0;L;;;;;N;;;;;
+A851;PHAGS-PA LETTER TSHA;Lo;0;L;;;;;N;;;;;
+A852;PHAGS-PA LETTER DZA;Lo;0;L;;;;;N;;;;;
+A853;PHAGS-PA LETTER WA;Lo;0;L;;;;;N;;;;;
+A854;PHAGS-PA LETTER ZHA;Lo;0;L;;;;;N;;;;;
+A855;PHAGS-PA LETTER ZA;Lo;0;L;;;;;N;;;;;
+A856;PHAGS-PA LETTER SMALL A;Lo;0;L;;;;;N;;;;;
+A857;PHAGS-PA LETTER YA;Lo;0;L;;;;;N;;;;;
+A858;PHAGS-PA LETTER RA;Lo;0;L;;;;;N;;;;;
+A859;PHAGS-PA LETTER LA;Lo;0;L;;;;;N;;;;;
+A85A;PHAGS-PA LETTER SHA;Lo;0;L;;;;;N;;;;;
+A85B;PHAGS-PA LETTER SA;Lo;0;L;;;;;N;;;;;
+A85C;PHAGS-PA LETTER HA;Lo;0;L;;;;;N;;;;;
+A85D;PHAGS-PA LETTER A;Lo;0;L;;;;;N;;;;;
+A85E;PHAGS-PA LETTER I;Lo;0;L;;;;;N;;;;;
+A85F;PHAGS-PA LETTER U;Lo;0;L;;;;;N;;;;;
+A860;PHAGS-PA LETTER E;Lo;0;L;;;;;N;;;;;
+A861;PHAGS-PA LETTER O;Lo;0;L;;;;;N;;;;;
+A862;PHAGS-PA LETTER QA;Lo;0;L;;;;;N;;;;;
+A863;PHAGS-PA LETTER XA;Lo;0;L;;;;;N;;;;;
+A864;PHAGS-PA LETTER FA;Lo;0;L;;;;;N;;;;;
+A865;PHAGS-PA LETTER GGA;Lo;0;L;;;;;N;;;;;
+A866;PHAGS-PA LETTER EE;Lo;0;L;;;;;N;;;;;
+A867;PHAGS-PA SUBJOINED LETTER WA;Lo;0;L;;;;;N;;;;;
+A868;PHAGS-PA SUBJOINED LETTER YA;Lo;0;L;;;;;N;;;;;
+A869;PHAGS-PA LETTER TTA;Lo;0;L;;;;;N;;;;;
+A86A;PHAGS-PA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+A86B;PHAGS-PA LETTER DDA;Lo;0;L;;;;;N;;;;;
+A86C;PHAGS-PA LETTER NNA;Lo;0;L;;;;;N;;;;;
+A86D;PHAGS-PA LETTER ALTERNATE YA;Lo;0;L;;;;;N;;;;;
+A86E;PHAGS-PA LETTER VOICELESS SHA;Lo;0;L;;;;;N;;;;;
+A86F;PHAGS-PA LETTER VOICED HA;Lo;0;L;;;;;N;;;;;
+A870;PHAGS-PA LETTER ASPIRATED FA;Lo;0;L;;;;;N;;;;;
+A871;PHAGS-PA SUBJOINED LETTER RA;Lo;0;L;;;;;N;;;;;
+A872;PHAGS-PA SUPERFIXED LETTER RA;Lo;0;L;;;;;N;;;;;
+A873;PHAGS-PA LETTER CANDRABINDU;Lo;0;L;;;;;N;;;;;
+A874;PHAGS-PA SINGLE HEAD MARK;Po;0;ON;;;;;N;;;;;
+A875;PHAGS-PA DOUBLE HEAD MARK;Po;0;ON;;;;;N;;;;;
+A876;PHAGS-PA MARK SHAD;Po;0;ON;;;;;N;;;;;
+A877;PHAGS-PA MARK DOUBLE SHAD;Po;0;ON;;;;;N;;;;;
+A880;SAURASHTRA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+A881;SAURASHTRA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+A882;SAURASHTRA LETTER A;Lo;0;L;;;;;N;;;;;
+A883;SAURASHTRA LETTER AA;Lo;0;L;;;;;N;;;;;
+A884;SAURASHTRA LETTER I;Lo;0;L;;;;;N;;;;;
+A885;SAURASHTRA LETTER II;Lo;0;L;;;;;N;;;;;
+A886;SAURASHTRA LETTER U;Lo;0;L;;;;;N;;;;;
+A887;SAURASHTRA LETTER UU;Lo;0;L;;;;;N;;;;;
+A888;SAURASHTRA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+A889;SAURASHTRA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+A88A;SAURASHTRA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+A88B;SAURASHTRA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+A88C;SAURASHTRA LETTER E;Lo;0;L;;;;;N;;;;;
+A88D;SAURASHTRA LETTER EE;Lo;0;L;;;;;N;;;;;
+A88E;SAURASHTRA LETTER AI;Lo;0;L;;;;;N;;;;;
+A88F;SAURASHTRA LETTER O;Lo;0;L;;;;;N;;;;;
+A890;SAURASHTRA LETTER OO;Lo;0;L;;;;;N;;;;;
+A891;SAURASHTRA LETTER AU;Lo;0;L;;;;;N;;;;;
+A892;SAURASHTRA LETTER KA;Lo;0;L;;;;;N;;;;;
+A893;SAURASHTRA LETTER KHA;Lo;0;L;;;;;N;;;;;
+A894;SAURASHTRA LETTER GA;Lo;0;L;;;;;N;;;;;
+A895;SAURASHTRA LETTER GHA;Lo;0;L;;;;;N;;;;;
+A896;SAURASHTRA LETTER NGA;Lo;0;L;;;;;N;;;;;
+A897;SAURASHTRA LETTER CA;Lo;0;L;;;;;N;;;;;
+A898;SAURASHTRA LETTER CHA;Lo;0;L;;;;;N;;;;;
+A899;SAURASHTRA LETTER JA;Lo;0;L;;;;;N;;;;;
+A89A;SAURASHTRA LETTER JHA;Lo;0;L;;;;;N;;;;;
+A89B;SAURASHTRA LETTER NYA;Lo;0;L;;;;;N;;;;;
+A89C;SAURASHTRA LETTER TTA;Lo;0;L;;;;;N;;;;;
+A89D;SAURASHTRA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+A89E;SAURASHTRA LETTER DDA;Lo;0;L;;;;;N;;;;;
+A89F;SAURASHTRA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+A8A0;SAURASHTRA LETTER NNA;Lo;0;L;;;;;N;;;;;
+A8A1;SAURASHTRA LETTER TA;Lo;0;L;;;;;N;;;;;
+A8A2;SAURASHTRA LETTER THA;Lo;0;L;;;;;N;;;;;
+A8A3;SAURASHTRA LETTER DA;Lo;0;L;;;;;N;;;;;
+A8A4;SAURASHTRA LETTER DHA;Lo;0;L;;;;;N;;;;;
+A8A5;SAURASHTRA LETTER NA;Lo;0;L;;;;;N;;;;;
+A8A6;SAURASHTRA LETTER PA;Lo;0;L;;;;;N;;;;;
+A8A7;SAURASHTRA LETTER PHA;Lo;0;L;;;;;N;;;;;
+A8A8;SAURASHTRA LETTER BA;Lo;0;L;;;;;N;;;;;
+A8A9;SAURASHTRA LETTER BHA;Lo;0;L;;;;;N;;;;;
+A8AA;SAURASHTRA LETTER MA;Lo;0;L;;;;;N;;;;;
+A8AB;SAURASHTRA LETTER YA;Lo;0;L;;;;;N;;;;;
+A8AC;SAURASHTRA LETTER RA;Lo;0;L;;;;;N;;;;;
+A8AD;SAURASHTRA LETTER LA;Lo;0;L;;;;;N;;;;;
+A8AE;SAURASHTRA LETTER VA;Lo;0;L;;;;;N;;;;;
+A8AF;SAURASHTRA LETTER SHA;Lo;0;L;;;;;N;;;;;
+A8B0;SAURASHTRA LETTER SSA;Lo;0;L;;;;;N;;;;;
+A8B1;SAURASHTRA LETTER SA;Lo;0;L;;;;;N;;;;;
+A8B2;SAURASHTRA LETTER HA;Lo;0;L;;;;;N;;;;;
+A8B3;SAURASHTRA LETTER LLA;Lo;0;L;;;;;N;;;;;
+A8B4;SAURASHTRA CONSONANT SIGN HAARU;Mc;0;L;;;;;N;;;;;
+A8B5;SAURASHTRA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+A8B6;SAURASHTRA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+A8B7;SAURASHTRA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+A8B8;SAURASHTRA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+A8B9;SAURASHTRA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+A8BA;SAURASHTRA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+A8BB;SAURASHTRA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+A8BC;SAURASHTRA VOWEL SIGN VOCALIC L;Mc;0;L;;;;;N;;;;;
+A8BD;SAURASHTRA VOWEL SIGN VOCALIC LL;Mc;0;L;;;;;N;;;;;
+A8BE;SAURASHTRA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+A8BF;SAURASHTRA VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+A8C0;SAURASHTRA VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+A8C1;SAURASHTRA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+A8C2;SAURASHTRA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+A8C3;SAURASHTRA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+A8C4;SAURASHTRA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+A8C5;SAURASHTRA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+A8CE;SAURASHTRA DANDA;Po;0;L;;;;;N;;;;;
+A8CF;SAURASHTRA DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+A8D0;SAURASHTRA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+A8D1;SAURASHTRA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+A8D2;SAURASHTRA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+A8D3;SAURASHTRA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+A8D4;SAURASHTRA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+A8D5;SAURASHTRA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+A8D6;SAURASHTRA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+A8D7;SAURASHTRA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+A8D8;SAURASHTRA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+A8D9;SAURASHTRA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+A8E0;COMBINING DEVANAGARI DIGIT ZERO;Mn;230;NSM;;;;;N;;;;;
+A8E1;COMBINING DEVANAGARI DIGIT ONE;Mn;230;NSM;;;;;N;;;;;
+A8E2;COMBINING DEVANAGARI DIGIT TWO;Mn;230;NSM;;;;;N;;;;;
+A8E3;COMBINING DEVANAGARI DIGIT THREE;Mn;230;NSM;;;;;N;;;;;
+A8E4;COMBINING DEVANAGARI DIGIT FOUR;Mn;230;NSM;;;;;N;;;;;
+A8E5;COMBINING DEVANAGARI DIGIT FIVE;Mn;230;NSM;;;;;N;;;;;
+A8E6;COMBINING DEVANAGARI DIGIT SIX;Mn;230;NSM;;;;;N;;;;;
+A8E7;COMBINING DEVANAGARI DIGIT SEVEN;Mn;230;NSM;;;;;N;;;;;
+A8E8;COMBINING DEVANAGARI DIGIT EIGHT;Mn;230;NSM;;;;;N;;;;;
+A8E9;COMBINING DEVANAGARI DIGIT NINE;Mn;230;NSM;;;;;N;;;;;
+A8EA;COMBINING DEVANAGARI LETTER A;Mn;230;NSM;;;;;N;;;;;
+A8EB;COMBINING DEVANAGARI LETTER U;Mn;230;NSM;;;;;N;;;;;
+A8EC;COMBINING DEVANAGARI LETTER KA;Mn;230;NSM;;;;;N;;;;;
+A8ED;COMBINING DEVANAGARI LETTER NA;Mn;230;NSM;;;;;N;;;;;
+A8EE;COMBINING DEVANAGARI LETTER PA;Mn;230;NSM;;;;;N;;;;;
+A8EF;COMBINING DEVANAGARI LETTER RA;Mn;230;NSM;;;;;N;;;;;
+A8F0;COMBINING DEVANAGARI LETTER VI;Mn;230;NSM;;;;;N;;;;;
+A8F1;COMBINING DEVANAGARI SIGN AVAGRAHA;Mn;230;NSM;;;;;N;;;;;
+A8F2;DEVANAGARI SIGN SPACING CANDRABINDU;Lo;0;L;;;;;N;;;;;
+A8F3;DEVANAGARI SIGN CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;;
+A8F4;DEVANAGARI SIGN DOUBLE CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;;
+A8F5;DEVANAGARI SIGN CANDRABINDU TWO;Lo;0;L;;;;;N;;;;;
+A8F6;DEVANAGARI SIGN CANDRABINDU THREE;Lo;0;L;;;;;N;;;;;
+A8F7;DEVANAGARI SIGN CANDRABINDU AVAGRAHA;Lo;0;L;;;;;N;;;;;
+A8F8;DEVANAGARI SIGN PUSHPIKA;Po;0;L;;;;;N;;;;;
+A8F9;DEVANAGARI GAP FILLER;Po;0;L;;;;;N;;;;;
+A8FA;DEVANAGARI CARET;Po;0;L;;;;;N;;;;;
+A8FB;DEVANAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;;
+A8FC;DEVANAGARI SIGN SIDDHAM;Po;0;L;;;;;N;;;;;
+A8FD;DEVANAGARI JAIN OM;Lo;0;L;;;;;N;;;;;
+A900;KAYAH LI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+A901;KAYAH LI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+A902;KAYAH LI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+A903;KAYAH LI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+A904;KAYAH LI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+A905;KAYAH LI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+A906;KAYAH LI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+A907;KAYAH LI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+A908;KAYAH LI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+A909;KAYAH LI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+A90A;KAYAH LI LETTER KA;Lo;0;L;;;;;N;;;;;
+A90B;KAYAH LI LETTER KHA;Lo;0;L;;;;;N;;;;;
+A90C;KAYAH LI LETTER GA;Lo;0;L;;;;;N;;;;;
+A90D;KAYAH LI LETTER NGA;Lo;0;L;;;;;N;;;;;
+A90E;KAYAH LI LETTER SA;Lo;0;L;;;;;N;;;;;
+A90F;KAYAH LI LETTER SHA;Lo;0;L;;;;;N;;;;;
+A910;KAYAH LI LETTER ZA;Lo;0;L;;;;;N;;;;;
+A911;KAYAH LI LETTER NYA;Lo;0;L;;;;;N;;;;;
+A912;KAYAH LI LETTER TA;Lo;0;L;;;;;N;;;;;
+A913;KAYAH LI LETTER HTA;Lo;0;L;;;;;N;;;;;
+A914;KAYAH LI LETTER NA;Lo;0;L;;;;;N;;;;;
+A915;KAYAH LI LETTER PA;Lo;0;L;;;;;N;;;;;
+A916;KAYAH LI LETTER PHA;Lo;0;L;;;;;N;;;;;
+A917;KAYAH LI LETTER MA;Lo;0;L;;;;;N;;;;;
+A918;KAYAH LI LETTER DA;Lo;0;L;;;;;N;;;;;
+A919;KAYAH LI LETTER BA;Lo;0;L;;;;;N;;;;;
+A91A;KAYAH LI LETTER RA;Lo;0;L;;;;;N;;;;;
+A91B;KAYAH LI LETTER YA;Lo;0;L;;;;;N;;;;;
+A91C;KAYAH LI LETTER LA;Lo;0;L;;;;;N;;;;;
+A91D;KAYAH LI LETTER WA;Lo;0;L;;;;;N;;;;;
+A91E;KAYAH LI LETTER THA;Lo;0;L;;;;;N;;;;;
+A91F;KAYAH LI LETTER HA;Lo;0;L;;;;;N;;;;;
+A920;KAYAH LI LETTER VA;Lo;0;L;;;;;N;;;;;
+A921;KAYAH LI LETTER CA;Lo;0;L;;;;;N;;;;;
+A922;KAYAH LI LETTER A;Lo;0;L;;;;;N;;;;;
+A923;KAYAH LI LETTER OE;Lo;0;L;;;;;N;;;;;
+A924;KAYAH LI LETTER I;Lo;0;L;;;;;N;;;;;
+A925;KAYAH LI LETTER OO;Lo;0;L;;;;;N;;;;;
+A926;KAYAH LI VOWEL UE;Mn;0;NSM;;;;;N;;;;;
+A927;KAYAH LI VOWEL E;Mn;0;NSM;;;;;N;;;;;
+A928;KAYAH LI VOWEL U;Mn;0;NSM;;;;;N;;;;;
+A929;KAYAH LI VOWEL EE;Mn;0;NSM;;;;;N;;;;;
+A92A;KAYAH LI VOWEL O;Mn;0;NSM;;;;;N;;;;;
+A92B;KAYAH LI TONE PLOPHU;Mn;220;NSM;;;;;N;;;;;
+A92C;KAYAH LI TONE CALYA;Mn;220;NSM;;;;;N;;;;;
+A92D;KAYAH LI TONE CALYA PLOPHU;Mn;220;NSM;;;;;N;;;;;
+A92E;KAYAH LI SIGN CWI;Po;0;L;;;;;N;;;;;
+A92F;KAYAH LI SIGN SHYA;Po;0;L;;;;;N;;;;;
+A930;REJANG LETTER KA;Lo;0;L;;;;;N;;;;;
+A931;REJANG LETTER GA;Lo;0;L;;;;;N;;;;;
+A932;REJANG LETTER NGA;Lo;0;L;;;;;N;;;;;
+A933;REJANG LETTER TA;Lo;0;L;;;;;N;;;;;
+A934;REJANG LETTER DA;Lo;0;L;;;;;N;;;;;
+A935;REJANG LETTER NA;Lo;0;L;;;;;N;;;;;
+A936;REJANG LETTER PA;Lo;0;L;;;;;N;;;;;
+A937;REJANG LETTER BA;Lo;0;L;;;;;N;;;;;
+A938;REJANG LETTER MA;Lo;0;L;;;;;N;;;;;
+A939;REJANG LETTER CA;Lo;0;L;;;;;N;;;;;
+A93A;REJANG LETTER JA;Lo;0;L;;;;;N;;;;;
+A93B;REJANG LETTER NYA;Lo;0;L;;;;;N;;;;;
+A93C;REJANG LETTER SA;Lo;0;L;;;;;N;;;;;
+A93D;REJANG LETTER RA;Lo;0;L;;;;;N;;;;;
+A93E;REJANG LETTER LA;Lo;0;L;;;;;N;;;;;
+A93F;REJANG LETTER YA;Lo;0;L;;;;;N;;;;;
+A940;REJANG LETTER WA;Lo;0;L;;;;;N;;;;;
+A941;REJANG LETTER HA;Lo;0;L;;;;;N;;;;;
+A942;REJANG LETTER MBA;Lo;0;L;;;;;N;;;;;
+A943;REJANG LETTER NGGA;Lo;0;L;;;;;N;;;;;
+A944;REJANG LETTER NDA;Lo;0;L;;;;;N;;;;;
+A945;REJANG LETTER NYJA;Lo;0;L;;;;;N;;;;;
+A946;REJANG LETTER A;Lo;0;L;;;;;N;;;;;
+A947;REJANG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+A948;REJANG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+A949;REJANG VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+A94A;REJANG VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+A94B;REJANG VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+A94C;REJANG VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+A94D;REJANG VOWEL SIGN EU;Mn;0;NSM;;;;;N;;;;;
+A94E;REJANG VOWEL SIGN EA;Mn;0;NSM;;;;;N;;;;;
+A94F;REJANG CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;;
+A950;REJANG CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;;
+A951;REJANG CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;;
+A952;REJANG CONSONANT SIGN H;Mc;0;L;;;;;N;;;;;
+A953;REJANG VIRAMA;Mc;9;L;;;;;N;;;;;
+A95F;REJANG SECTION MARK;Po;0;L;;;;;N;;;;;
+A960;HANGUL CHOSEONG TIKEUT-MIEUM;Lo;0;L;;;;;N;;;;;
+A961;HANGUL CHOSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;;
+A962;HANGUL CHOSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;;
+A963;HANGUL CHOSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;;
+A964;HANGUL CHOSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;;
+A965;HANGUL CHOSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
+A966;HANGUL CHOSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;;
+A967;HANGUL CHOSEONG RIEUL-SSANGTIKEUT;Lo;0;L;;;;;N;;;;;
+A968;HANGUL CHOSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;;
+A969;HANGUL CHOSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;;
+A96A;HANGUL CHOSEONG RIEUL-SSANGPIEUP;Lo;0;L;;;;;N;;;;;
+A96B;HANGUL CHOSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+A96C;HANGUL CHOSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;;
+A96D;HANGUL CHOSEONG RIEUL-CIEUC;Lo;0;L;;;;;N;;;;;
+A96E;HANGUL CHOSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;;
+A96F;HANGUL CHOSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;
+A970;HANGUL CHOSEONG MIEUM-TIKEUT;Lo;0;L;;;;;N;;;;;
+A971;HANGUL CHOSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;;
+A972;HANGUL CHOSEONG PIEUP-SIOS-THIEUTH;Lo;0;L;;;;;N;;;;;
+A973;HANGUL CHOSEONG PIEUP-KHIEUKH;Lo;0;L;;;;;N;;;;;
+A974;HANGUL CHOSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;
+A975;HANGUL CHOSEONG SSANGSIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+A976;HANGUL CHOSEONG IEUNG-RIEUL;Lo;0;L;;;;;N;;;;;
+A977;HANGUL CHOSEONG IEUNG-HIEUH;Lo;0;L;;;;;N;;;;;
+A978;HANGUL CHOSEONG SSANGCIEUC-HIEUH;Lo;0;L;;;;;N;;;;;
+A979;HANGUL CHOSEONG SSANGTHIEUTH;Lo;0;L;;;;;N;;;;;
+A97A;HANGUL CHOSEONG PHIEUPH-HIEUH;Lo;0;L;;;;;N;;;;;
+A97B;HANGUL CHOSEONG HIEUH-SIOS;Lo;0;L;;;;;N;;;;;
+A97C;HANGUL CHOSEONG SSANGYEORINHIEUH;Lo;0;L;;;;;N;;;;;
+A980;JAVANESE SIGN PANYANGGA;Mn;0;NSM;;;;;N;;;;;
+A981;JAVANESE SIGN CECAK;Mn;0;NSM;;;;;N;;;;;
+A982;JAVANESE SIGN LAYAR;Mn;0;NSM;;;;;N;;;;;
+A983;JAVANESE SIGN WIGNYAN;Mc;0;L;;;;;N;;;;;
+A984;JAVANESE LETTER A;Lo;0;L;;;;;N;;;;;
+A985;JAVANESE LETTER I KAWI;Lo;0;L;;;;;N;;;;;
+A986;JAVANESE LETTER I;Lo;0;L;;;;;N;;;;;
+A987;JAVANESE LETTER II;Lo;0;L;;;;;N;;;;;
+A988;JAVANESE LETTER U;Lo;0;L;;;;;N;;;;;
+A989;JAVANESE LETTER PA CEREK;Lo;0;L;;;;;N;;;;;
+A98A;JAVANESE LETTER NGA LELET;Lo;0;L;;;;;N;;;;;
+A98B;JAVANESE LETTER NGA LELET RASWADI;Lo;0;L;;;;;N;;;;;
+A98C;JAVANESE LETTER E;Lo;0;L;;;;;N;;;;;
+A98D;JAVANESE LETTER AI;Lo;0;L;;;;;N;;;;;
+A98E;JAVANESE LETTER O;Lo;0;L;;;;;N;;;;;
+A98F;JAVANESE LETTER KA;Lo;0;L;;;;;N;;;;;
+A990;JAVANESE LETTER KA SASAK;Lo;0;L;;;;;N;;;;;
+A991;JAVANESE LETTER KA MURDA;Lo;0;L;;;;;N;;;;;
+A992;JAVANESE LETTER GA;Lo;0;L;;;;;N;;;;;
+A993;JAVANESE LETTER GA MURDA;Lo;0;L;;;;;N;;;;;
+A994;JAVANESE LETTER NGA;Lo;0;L;;;;;N;;;;;
+A995;JAVANESE LETTER CA;Lo;0;L;;;;;N;;;;;
+A996;JAVANESE LETTER CA MURDA;Lo;0;L;;;;;N;;;;;
+A997;JAVANESE LETTER JA;Lo;0;L;;;;;N;;;;;
+A998;JAVANESE LETTER NYA MURDA;Lo;0;L;;;;;N;;;;;
+A999;JAVANESE LETTER JA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+A99A;JAVANESE LETTER NYA;Lo;0;L;;;;;N;;;;;
+A99B;JAVANESE LETTER TTA;Lo;0;L;;;;;N;;;;;
+A99C;JAVANESE LETTER TTA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+A99D;JAVANESE LETTER DDA;Lo;0;L;;;;;N;;;;;
+A99E;JAVANESE LETTER DDA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+A99F;JAVANESE LETTER NA MURDA;Lo;0;L;;;;;N;;;;;
+A9A0;JAVANESE LETTER TA;Lo;0;L;;;;;N;;;;;
+A9A1;JAVANESE LETTER TA MURDA;Lo;0;L;;;;;N;;;;;
+A9A2;JAVANESE LETTER DA;Lo;0;L;;;;;N;;;;;
+A9A3;JAVANESE LETTER DA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+A9A4;JAVANESE LETTER NA;Lo;0;L;;;;;N;;;;;
+A9A5;JAVANESE LETTER PA;Lo;0;L;;;;;N;;;;;
+A9A6;JAVANESE LETTER PA MURDA;Lo;0;L;;;;;N;;;;;
+A9A7;JAVANESE LETTER BA;Lo;0;L;;;;;N;;;;;
+A9A8;JAVANESE LETTER BA MURDA;Lo;0;L;;;;;N;;;;;
+A9A9;JAVANESE LETTER MA;Lo;0;L;;;;;N;;;;;
+A9AA;JAVANESE LETTER YA;Lo;0;L;;;;;N;;;;;
+A9AB;JAVANESE LETTER RA;Lo;0;L;;;;;N;;;;;
+A9AC;JAVANESE LETTER RA AGUNG;Lo;0;L;;;;;N;;;;;
+A9AD;JAVANESE LETTER LA;Lo;0;L;;;;;N;;;;;
+A9AE;JAVANESE LETTER WA;Lo;0;L;;;;;N;;;;;
+A9AF;JAVANESE LETTER SA MURDA;Lo;0;L;;;;;N;;;;;
+A9B0;JAVANESE LETTER SA MAHAPRANA;Lo;0;L;;;;;N;;;;;
+A9B1;JAVANESE LETTER SA;Lo;0;L;;;;;N;;;;;
+A9B2;JAVANESE LETTER HA;Lo;0;L;;;;;N;;;;;
+A9B3;JAVANESE SIGN CECAK TELU;Mn;7;NSM;;;;;N;;;;;
+A9B4;JAVANESE VOWEL SIGN TARUNG;Mc;0;L;;;;;N;;;;;
+A9B5;JAVANESE VOWEL SIGN TOLONG;Mc;0;L;;;;;N;;;;;
+A9B6;JAVANESE VOWEL SIGN WULU;Mn;0;NSM;;;;;N;;;;;
+A9B7;JAVANESE VOWEL SIGN WULU MELIK;Mn;0;NSM;;;;;N;;;;;
+A9B8;JAVANESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;;
+A9B9;JAVANESE VOWEL SIGN SUKU MENDUT;Mn;0;NSM;;;;;N;;;;;
+A9BA;JAVANESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;;
+A9BB;JAVANESE VOWEL SIGN DIRGA MURE;Mc;0;L;;;;;N;;;;;
+A9BC;JAVANESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;;
+A9BD;JAVANESE CONSONANT SIGN KERET;Mc;0;L;;;;;N;;;;;
+A9BE;JAVANESE CONSONANT SIGN PENGKAL;Mc;0;L;;;;;N;;;;;
+A9BF;JAVANESE CONSONANT SIGN CAKRA;Mc;0;L;;;;;N;;;;;
+A9C0;JAVANESE PANGKON;Mc;9;L;;;;;N;;;;;
+A9C1;JAVANESE LEFT RERENGGAN;Po;0;L;;;;;N;;;;;
+A9C2;JAVANESE RIGHT RERENGGAN;Po;0;L;;;;;N;;;;;
+A9C3;JAVANESE PADA ANDAP;Po;0;L;;;;;N;;;;;
+A9C4;JAVANESE PADA MADYA;Po;0;L;;;;;N;;;;;
+A9C5;JAVANESE PADA LUHUR;Po;0;L;;;;;N;;;;;
+A9C6;JAVANESE PADA WINDU;Po;0;L;;;;;N;;;;;
+A9C7;JAVANESE PADA PANGKAT;Po;0;L;;;;;N;;;;;
+A9C8;JAVANESE PADA LINGSA;Po;0;L;;;;;N;;;;;
+A9C9;JAVANESE PADA LUNGSI;Po;0;L;;;;;N;;;;;
+A9CA;JAVANESE PADA ADEG;Po;0;L;;;;;N;;;;;
+A9CB;JAVANESE PADA ADEG ADEG;Po;0;L;;;;;N;;;;;
+A9CC;JAVANESE PADA PISELEH;Po;0;L;;;;;N;;;;;
+A9CD;JAVANESE TURNED PADA PISELEH;Po;0;L;;;;;N;;;;;
+A9CF;JAVANESE PANGRANGKEP;Lm;0;L;;;;;N;;;;;
+A9D0;JAVANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+A9D1;JAVANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+A9D2;JAVANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+A9D3;JAVANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+A9D4;JAVANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+A9D5;JAVANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+A9D6;JAVANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+A9D7;JAVANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+A9D8;JAVANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+A9D9;JAVANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+A9DE;JAVANESE PADA TIRTA TUMETES;Po;0;L;;;;;N;;;;;
+A9DF;JAVANESE PADA ISEN-ISEN;Po;0;L;;;;;N;;;;;
+A9E0;MYANMAR LETTER SHAN GHA;Lo;0;L;;;;;N;;;;;
+A9E1;MYANMAR LETTER SHAN CHA;Lo;0;L;;;;;N;;;;;
+A9E2;MYANMAR LETTER SHAN JHA;Lo;0;L;;;;;N;;;;;
+A9E3;MYANMAR LETTER SHAN NNA;Lo;0;L;;;;;N;;;;;
+A9E4;MYANMAR LETTER SHAN BHA;Lo;0;L;;;;;N;;;;;
+A9E5;MYANMAR SIGN SHAN SAW;Mn;0;NSM;;;;;N;;;;;
+A9E6;MYANMAR MODIFIER LETTER SHAN REDUPLICATION;Lm;0;L;;;;;N;;;;;
+A9E7;MYANMAR LETTER TAI LAING NYA;Lo;0;L;;;;;N;;;;;
+A9E8;MYANMAR LETTER TAI LAING FA;Lo;0;L;;;;;N;;;;;
+A9E9;MYANMAR LETTER TAI LAING GA;Lo;0;L;;;;;N;;;;;
+A9EA;MYANMAR LETTER TAI LAING GHA;Lo;0;L;;;;;N;;;;;
+A9EB;MYANMAR LETTER TAI LAING JA;Lo;0;L;;;;;N;;;;;
+A9EC;MYANMAR LETTER TAI LAING JHA;Lo;0;L;;;;;N;;;;;
+A9ED;MYANMAR LETTER TAI LAING DDA;Lo;0;L;;;;;N;;;;;
+A9EE;MYANMAR LETTER TAI LAING DDHA;Lo;0;L;;;;;N;;;;;
+A9EF;MYANMAR LETTER TAI LAING NNA;Lo;0;L;;;;;N;;;;;
+A9F0;MYANMAR TAI LAING DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+A9F1;MYANMAR TAI LAING DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+A9F2;MYANMAR TAI LAING DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+A9F3;MYANMAR TAI LAING DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+A9F4;MYANMAR TAI LAING DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+A9F5;MYANMAR TAI LAING DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+A9F6;MYANMAR TAI LAING DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+A9F7;MYANMAR TAI LAING DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+A9F8;MYANMAR TAI LAING DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+A9F9;MYANMAR TAI LAING DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+A9FA;MYANMAR LETTER TAI LAING LLA;Lo;0;L;;;;;N;;;;;
+A9FB;MYANMAR LETTER TAI LAING DA;Lo;0;L;;;;;N;;;;;
+A9FC;MYANMAR LETTER TAI LAING DHA;Lo;0;L;;;;;N;;;;;
+A9FD;MYANMAR LETTER TAI LAING BA;Lo;0;L;;;;;N;;;;;
+A9FE;MYANMAR LETTER TAI LAING BHA;Lo;0;L;;;;;N;;;;;
+AA00;CHAM LETTER A;Lo;0;L;;;;;N;;;;;
+AA01;CHAM LETTER I;Lo;0;L;;;;;N;;;;;
+AA02;CHAM LETTER U;Lo;0;L;;;;;N;;;;;
+AA03;CHAM LETTER E;Lo;0;L;;;;;N;;;;;
+AA04;CHAM LETTER AI;Lo;0;L;;;;;N;;;;;
+AA05;CHAM LETTER O;Lo;0;L;;;;;N;;;;;
+AA06;CHAM LETTER KA;Lo;0;L;;;;;N;;;;;
+AA07;CHAM LETTER KHA;Lo;0;L;;;;;N;;;;;
+AA08;CHAM LETTER GA;Lo;0;L;;;;;N;;;;;
+AA09;CHAM LETTER GHA;Lo;0;L;;;;;N;;;;;
+AA0A;CHAM LETTER NGUE;Lo;0;L;;;;;N;;;;;
+AA0B;CHAM LETTER NGA;Lo;0;L;;;;;N;;;;;
+AA0C;CHAM LETTER CHA;Lo;0;L;;;;;N;;;;;
+AA0D;CHAM LETTER CHHA;Lo;0;L;;;;;N;;;;;
+AA0E;CHAM LETTER JA;Lo;0;L;;;;;N;;;;;
+AA0F;CHAM LETTER JHA;Lo;0;L;;;;;N;;;;;
+AA10;CHAM LETTER NHUE;Lo;0;L;;;;;N;;;;;
+AA11;CHAM LETTER NHA;Lo;0;L;;;;;N;;;;;
+AA12;CHAM LETTER NHJA;Lo;0;L;;;;;N;;;;;
+AA13;CHAM LETTER TA;Lo;0;L;;;;;N;;;;;
+AA14;CHAM LETTER THA;Lo;0;L;;;;;N;;;;;
+AA15;CHAM LETTER DA;Lo;0;L;;;;;N;;;;;
+AA16;CHAM LETTER DHA;Lo;0;L;;;;;N;;;;;
+AA17;CHAM LETTER NUE;Lo;0;L;;;;;N;;;;;
+AA18;CHAM LETTER NA;Lo;0;L;;;;;N;;;;;
+AA19;CHAM LETTER DDA;Lo;0;L;;;;;N;;;;;
+AA1A;CHAM LETTER PA;Lo;0;L;;;;;N;;;;;
+AA1B;CHAM LETTER PPA;Lo;0;L;;;;;N;;;;;
+AA1C;CHAM LETTER PHA;Lo;0;L;;;;;N;;;;;
+AA1D;CHAM LETTER BA;Lo;0;L;;;;;N;;;;;
+AA1E;CHAM LETTER BHA;Lo;0;L;;;;;N;;;;;
+AA1F;CHAM LETTER MUE;Lo;0;L;;;;;N;;;;;
+AA20;CHAM LETTER MA;Lo;0;L;;;;;N;;;;;
+AA21;CHAM LETTER BBA;Lo;0;L;;;;;N;;;;;
+AA22;CHAM LETTER YA;Lo;0;L;;;;;N;;;;;
+AA23;CHAM LETTER RA;Lo;0;L;;;;;N;;;;;
+AA24;CHAM LETTER LA;Lo;0;L;;;;;N;;;;;
+AA25;CHAM LETTER VA;Lo;0;L;;;;;N;;;;;
+AA26;CHAM LETTER SSA;Lo;0;L;;;;;N;;;;;
+AA27;CHAM LETTER SA;Lo;0;L;;;;;N;;;;;
+AA28;CHAM LETTER HA;Lo;0;L;;;;;N;;;;;
+AA29;CHAM VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+AA2A;CHAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+AA2B;CHAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+AA2C;CHAM VOWEL SIGN EI;Mn;0;NSM;;;;;N;;;;;
+AA2D;CHAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+AA2E;CHAM VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;
+AA2F;CHAM VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+AA30;CHAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+AA31;CHAM VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+AA32;CHAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
+AA33;CHAM CONSONANT SIGN YA;Mc;0;L;;;;;N;;;;;
+AA34;CHAM CONSONANT SIGN RA;Mc;0;L;;;;;N;;;;;
+AA35;CHAM CONSONANT SIGN LA;Mn;0;NSM;;;;;N;;;;;
+AA36;CHAM CONSONANT SIGN WA;Mn;0;NSM;;;;;N;;;;;
+AA40;CHAM LETTER FINAL K;Lo;0;L;;;;;N;;;;;
+AA41;CHAM LETTER FINAL G;Lo;0;L;;;;;N;;;;;
+AA42;CHAM LETTER FINAL NG;Lo;0;L;;;;;N;;;;;
+AA43;CHAM CONSONANT SIGN FINAL NG;Mn;0;NSM;;;;;N;;;;;
+AA44;CHAM LETTER FINAL CH;Lo;0;L;;;;;N;;;;;
+AA45;CHAM LETTER FINAL T;Lo;0;L;;;;;N;;;;;
+AA46;CHAM LETTER FINAL N;Lo;0;L;;;;;N;;;;;
+AA47;CHAM LETTER FINAL P;Lo;0;L;;;;;N;;;;;
+AA48;CHAM LETTER FINAL Y;Lo;0;L;;;;;N;;;;;
+AA49;CHAM LETTER FINAL R;Lo;0;L;;;;;N;;;;;
+AA4A;CHAM LETTER FINAL L;Lo;0;L;;;;;N;;;;;
+AA4B;CHAM LETTER FINAL SS;Lo;0;L;;;;;N;;;;;
+AA4C;CHAM CONSONANT SIGN FINAL M;Mn;0;NSM;;;;;N;;;;;
+AA4D;CHAM CONSONANT SIGN FINAL H;Mc;0;L;;;;;N;;;;;
+AA50;CHAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+AA51;CHAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+AA52;CHAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+AA53;CHAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+AA54;CHAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+AA55;CHAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+AA56;CHAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+AA57;CHAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+AA58;CHAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+AA59;CHAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+AA5C;CHAM PUNCTUATION SPIRAL;Po;0;L;;;;;N;;;;;
+AA5D;CHAM PUNCTUATION DANDA;Po;0;L;;;;;N;;;;;
+AA5E;CHAM PUNCTUATION DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+AA5F;CHAM PUNCTUATION TRIPLE DANDA;Po;0;L;;;;;N;;;;;
+AA60;MYANMAR LETTER KHAMTI GA;Lo;0;L;;;;;N;;;;;
+AA61;MYANMAR LETTER KHAMTI CA;Lo;0;L;;;;;N;;;;;
+AA62;MYANMAR LETTER KHAMTI CHA;Lo;0;L;;;;;N;;;;;
+AA63;MYANMAR LETTER KHAMTI JA;Lo;0;L;;;;;N;;;;;
+AA64;MYANMAR LETTER KHAMTI JHA;Lo;0;L;;;;;N;;;;;
+AA65;MYANMAR LETTER KHAMTI NYA;Lo;0;L;;;;;N;;;;;
+AA66;MYANMAR LETTER KHAMTI TTA;Lo;0;L;;;;;N;;;;;
+AA67;MYANMAR LETTER KHAMTI TTHA;Lo;0;L;;;;;N;;;;;
+AA68;MYANMAR LETTER KHAMTI DDA;Lo;0;L;;;;;N;;;;;
+AA69;MYANMAR LETTER KHAMTI DDHA;Lo;0;L;;;;;N;;;;;
+AA6A;MYANMAR LETTER KHAMTI DHA;Lo;0;L;;;;;N;;;;;
+AA6B;MYANMAR LETTER KHAMTI NA;Lo;0;L;;;;;N;;;;;
+AA6C;MYANMAR LETTER KHAMTI SA;Lo;0;L;;;;;N;;;;;
+AA6D;MYANMAR LETTER KHAMTI HA;Lo;0;L;;;;;N;;;;;
+AA6E;MYANMAR LETTER KHAMTI HHA;Lo;0;L;;;;;N;;;;;
+AA6F;MYANMAR LETTER KHAMTI FA;Lo;0;L;;;;;N;;;;;
+AA70;MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION;Lm;0;L;;;;;N;;;;;
+AA71;MYANMAR LETTER KHAMTI XA;Lo;0;L;;;;;N;;;;;
+AA72;MYANMAR LETTER KHAMTI ZA;Lo;0;L;;;;;N;;;;;
+AA73;MYANMAR LETTER KHAMTI RA;Lo;0;L;;;;;N;;;;;
+AA74;MYANMAR LOGOGRAM KHAMTI OAY;Lo;0;L;;;;;N;;;;;
+AA75;MYANMAR LOGOGRAM KHAMTI QN;Lo;0;L;;;;;N;;;;;
+AA76;MYANMAR LOGOGRAM KHAMTI HM;Lo;0;L;;;;;N;;;;;
+AA77;MYANMAR SYMBOL AITON EXCLAMATION;So;0;L;;;;;N;;;;;
+AA78;MYANMAR SYMBOL AITON ONE;So;0;L;;;;;N;;;;;
+AA79;MYANMAR SYMBOL AITON TWO;So;0;L;;;;;N;;;;;
+AA7A;MYANMAR LETTER AITON RA;Lo;0;L;;;;;N;;;;;
+AA7B;MYANMAR SIGN PAO KAREN TONE;Mc;0;L;;;;;N;;;;;
+AA7C;MYANMAR SIGN TAI LAING TONE-2;Mn;0;NSM;;;;;N;;;;;
+AA7D;MYANMAR SIGN TAI LAING TONE-5;Mc;0;L;;;;;N;;;;;
+AA7E;MYANMAR LETTER SHWE PALAUNG CHA;Lo;0;L;;;;;N;;;;;
+AA7F;MYANMAR LETTER SHWE PALAUNG SHA;Lo;0;L;;;;;N;;;;;
+AA80;TAI VIET LETTER LOW KO;Lo;0;L;;;;;N;;;;;
+AA81;TAI VIET LETTER HIGH KO;Lo;0;L;;;;;N;;;;;
+AA82;TAI VIET LETTER LOW KHO;Lo;0;L;;;;;N;;;;;
+AA83;TAI VIET LETTER HIGH KHO;Lo;0;L;;;;;N;;;;;
+AA84;TAI VIET LETTER LOW KHHO;Lo;0;L;;;;;N;;;;;
+AA85;TAI VIET LETTER HIGH KHHO;Lo;0;L;;;;;N;;;;;
+AA86;TAI VIET LETTER LOW GO;Lo;0;L;;;;;N;;;;;
+AA87;TAI VIET LETTER HIGH GO;Lo;0;L;;;;;N;;;;;
+AA88;TAI VIET LETTER LOW NGO;Lo;0;L;;;;;N;;;;;
+AA89;TAI VIET LETTER HIGH NGO;Lo;0;L;;;;;N;;;;;
+AA8A;TAI VIET LETTER LOW CO;Lo;0;L;;;;;N;;;;;
+AA8B;TAI VIET LETTER HIGH CO;Lo;0;L;;;;;N;;;;;
+AA8C;TAI VIET LETTER LOW CHO;Lo;0;L;;;;;N;;;;;
+AA8D;TAI VIET LETTER HIGH CHO;Lo;0;L;;;;;N;;;;;
+AA8E;TAI VIET LETTER LOW SO;Lo;0;L;;;;;N;;;;;
+AA8F;TAI VIET LETTER HIGH SO;Lo;0;L;;;;;N;;;;;
+AA90;TAI VIET LETTER LOW NYO;Lo;0;L;;;;;N;;;;;
+AA91;TAI VIET LETTER HIGH NYO;Lo;0;L;;;;;N;;;;;
+AA92;TAI VIET LETTER LOW DO;Lo;0;L;;;;;N;;;;;
+AA93;TAI VIET LETTER HIGH DO;Lo;0;L;;;;;N;;;;;
+AA94;TAI VIET LETTER LOW TO;Lo;0;L;;;;;N;;;;;
+AA95;TAI VIET LETTER HIGH TO;Lo;0;L;;;;;N;;;;;
+AA96;TAI VIET LETTER LOW THO;Lo;0;L;;;;;N;;;;;
+AA97;TAI VIET LETTER HIGH THO;Lo;0;L;;;;;N;;;;;
+AA98;TAI VIET LETTER LOW NO;Lo;0;L;;;;;N;;;;;
+AA99;TAI VIET LETTER HIGH NO;Lo;0;L;;;;;N;;;;;
+AA9A;TAI VIET LETTER LOW BO;Lo;0;L;;;;;N;;;;;
+AA9B;TAI VIET LETTER HIGH BO;Lo;0;L;;;;;N;;;;;
+AA9C;TAI VIET LETTER LOW PO;Lo;0;L;;;;;N;;;;;
+AA9D;TAI VIET LETTER HIGH PO;Lo;0;L;;;;;N;;;;;
+AA9E;TAI VIET LETTER LOW PHO;Lo;0;L;;;;;N;;;;;
+AA9F;TAI VIET LETTER HIGH PHO;Lo;0;L;;;;;N;;;;;
+AAA0;TAI VIET LETTER LOW FO;Lo;0;L;;;;;N;;;;;
+AAA1;TAI VIET LETTER HIGH FO;Lo;0;L;;;;;N;;;;;
+AAA2;TAI VIET LETTER LOW MO;Lo;0;L;;;;;N;;;;;
+AAA3;TAI VIET LETTER HIGH MO;Lo;0;L;;;;;N;;;;;
+AAA4;TAI VIET LETTER LOW YO;Lo;0;L;;;;;N;;;;;
+AAA5;TAI VIET LETTER HIGH YO;Lo;0;L;;;;;N;;;;;
+AAA6;TAI VIET LETTER LOW RO;Lo;0;L;;;;;N;;;;;
+AAA7;TAI VIET LETTER HIGH RO;Lo;0;L;;;;;N;;;;;
+AAA8;TAI VIET LETTER LOW LO;Lo;0;L;;;;;N;;;;;
+AAA9;TAI VIET LETTER HIGH LO;Lo;0;L;;;;;N;;;;;
+AAAA;TAI VIET LETTER LOW VO;Lo;0;L;;;;;N;;;;;
+AAAB;TAI VIET LETTER HIGH VO;Lo;0;L;;;;;N;;;;;
+AAAC;TAI VIET LETTER LOW HO;Lo;0;L;;;;;N;;;;;
+AAAD;TAI VIET LETTER HIGH HO;Lo;0;L;;;;;N;;;;;
+AAAE;TAI VIET LETTER LOW O;Lo;0;L;;;;;N;;;;;
+AAAF;TAI VIET LETTER HIGH O;Lo;0;L;;;;;N;;;;;
+AAB0;TAI VIET MAI KANG;Mn;230;NSM;;;;;N;;;;;
+AAB1;TAI VIET VOWEL AA;Lo;0;L;;;;;N;;;;;
+AAB2;TAI VIET VOWEL I;Mn;230;NSM;;;;;N;;;;;
+AAB3;TAI VIET VOWEL UE;Mn;230;NSM;;;;;N;;;;;
+AAB4;TAI VIET VOWEL U;Mn;220;NSM;;;;;N;;;;;
+AAB5;TAI VIET VOWEL E;Lo;0;L;;;;;N;;;;;
+AAB6;TAI VIET VOWEL O;Lo;0;L;;;;;N;;;;;
+AAB7;TAI VIET MAI KHIT;Mn;230;NSM;;;;;N;;;;;
+AAB8;TAI VIET VOWEL IA;Mn;230;NSM;;;;;N;;;;;
+AAB9;TAI VIET VOWEL UEA;Lo;0;L;;;;;N;;;;;
+AABA;TAI VIET VOWEL UA;Lo;0;L;;;;;N;;;;;
+AABB;TAI VIET VOWEL AUE;Lo;0;L;;;;;N;;;;;
+AABC;TAI VIET VOWEL AY;Lo;0;L;;;;;N;;;;;
+AABD;TAI VIET VOWEL AN;Lo;0;L;;;;;N;;;;;
+AABE;TAI VIET VOWEL AM;Mn;230;NSM;;;;;N;;;;;
+AABF;TAI VIET TONE MAI EK;Mn;230;NSM;;;;;N;;;;;
+AAC0;TAI VIET TONE MAI NUENG;Lo;0;L;;;;;N;;;;;
+AAC1;TAI VIET TONE MAI THO;Mn;230;NSM;;;;;N;;;;;
+AAC2;TAI VIET TONE MAI SONG;Lo;0;L;;;;;N;;;;;
+AADB;TAI VIET SYMBOL KON;Lo;0;L;;;;;N;;;;;
+AADC;TAI VIET SYMBOL NUENG;Lo;0;L;;;;;N;;;;;
+AADD;TAI VIET SYMBOL SAM;Lm;0;L;;;;;N;;;;;
+AADE;TAI VIET SYMBOL HO HOI;Po;0;L;;;;;N;;;;;
+AADF;TAI VIET SYMBOL KOI KOI;Po;0;L;;;;;N;;;;;
+AAE0;MEETEI MAYEK LETTER E;Lo;0;L;;;;;N;;;;;
+AAE1;MEETEI MAYEK LETTER O;Lo;0;L;;;;;N;;;;;
+AAE2;MEETEI MAYEK LETTER CHA;Lo;0;L;;;;;N;;;;;
+AAE3;MEETEI MAYEK LETTER NYA;Lo;0;L;;;;;N;;;;;
+AAE4;MEETEI MAYEK LETTER TTA;Lo;0;L;;;;;N;;;;;
+AAE5;MEETEI MAYEK LETTER TTHA;Lo;0;L;;;;;N;;;;;
+AAE6;MEETEI MAYEK LETTER DDA;Lo;0;L;;;;;N;;;;;
+AAE7;MEETEI MAYEK LETTER DDHA;Lo;0;L;;;;;N;;;;;
+AAE8;MEETEI MAYEK LETTER NNA;Lo;0;L;;;;;N;;;;;
+AAE9;MEETEI MAYEK LETTER SHA;Lo;0;L;;;;;N;;;;;
+AAEA;MEETEI MAYEK LETTER SSA;Lo;0;L;;;;;N;;;;;
+AAEB;MEETEI MAYEK VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+AAEC;MEETEI MAYEK VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+AAED;MEETEI MAYEK VOWEL SIGN AAI;Mn;0;NSM;;;;;N;;;;;
+AAEE;MEETEI MAYEK VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+AAEF;MEETEI MAYEK VOWEL SIGN AAU;Mc;0;L;;;;;N;;;;;
+AAF0;MEETEI MAYEK CHEIKHAN;Po;0;L;;;;;N;;;;;
+AAF1;MEETEI MAYEK AHANG KHUDAM;Po;0;L;;;;;N;;;;;
+AAF2;MEETEI MAYEK ANJI;Lo;0;L;;;;;N;;;;;
+AAF3;MEETEI MAYEK SYLLABLE REPETITION MARK;Lm;0;L;;;;;N;;;;;
+AAF4;MEETEI MAYEK WORD REPETITION MARK;Lm;0;L;;;;;N;;;;;
+AAF5;MEETEI MAYEK VOWEL SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+AAF6;MEETEI MAYEK VIRAMA;Mn;9;NSM;;;;;N;;;;;
+AB01;ETHIOPIC SYLLABLE TTHU;Lo;0;L;;;;;N;;;;;
+AB02;ETHIOPIC SYLLABLE TTHI;Lo;0;L;;;;;N;;;;;
+AB03;ETHIOPIC SYLLABLE TTHAA;Lo;0;L;;;;;N;;;;;
+AB04;ETHIOPIC SYLLABLE TTHEE;Lo;0;L;;;;;N;;;;;
+AB05;ETHIOPIC SYLLABLE TTHE;Lo;0;L;;;;;N;;;;;
+AB06;ETHIOPIC SYLLABLE TTHO;Lo;0;L;;;;;N;;;;;
+AB09;ETHIOPIC SYLLABLE DDHU;Lo;0;L;;;;;N;;;;;
+AB0A;ETHIOPIC SYLLABLE DDHI;Lo;0;L;;;;;N;;;;;
+AB0B;ETHIOPIC SYLLABLE DDHAA;Lo;0;L;;;;;N;;;;;
+AB0C;ETHIOPIC SYLLABLE DDHEE;Lo;0;L;;;;;N;;;;;
+AB0D;ETHIOPIC SYLLABLE DDHE;Lo;0;L;;;;;N;;;;;
+AB0E;ETHIOPIC SYLLABLE DDHO;Lo;0;L;;;;;N;;;;;
+AB11;ETHIOPIC SYLLABLE DZU;Lo;0;L;;;;;N;;;;;
+AB12;ETHIOPIC SYLLABLE DZI;Lo;0;L;;;;;N;;;;;
+AB13;ETHIOPIC SYLLABLE DZAA;Lo;0;L;;;;;N;;;;;
+AB14;ETHIOPIC SYLLABLE DZEE;Lo;0;L;;;;;N;;;;;
+AB15;ETHIOPIC SYLLABLE DZE;Lo;0;L;;;;;N;;;;;
+AB16;ETHIOPIC SYLLABLE DZO;Lo;0;L;;;;;N;;;;;
+AB20;ETHIOPIC SYLLABLE CCHHA;Lo;0;L;;;;;N;;;;;
+AB21;ETHIOPIC SYLLABLE CCHHU;Lo;0;L;;;;;N;;;;;
+AB22;ETHIOPIC SYLLABLE CCHHI;Lo;0;L;;;;;N;;;;;
+AB23;ETHIOPIC SYLLABLE CCHHAA;Lo;0;L;;;;;N;;;;;
+AB24;ETHIOPIC SYLLABLE CCHHEE;Lo;0;L;;;;;N;;;;;
+AB25;ETHIOPIC SYLLABLE CCHHE;Lo;0;L;;;;;N;;;;;
+AB26;ETHIOPIC SYLLABLE CCHHO;Lo;0;L;;;;;N;;;;;
+AB28;ETHIOPIC SYLLABLE BBA;Lo;0;L;;;;;N;;;;;
+AB29;ETHIOPIC SYLLABLE BBU;Lo;0;L;;;;;N;;;;;
+AB2A;ETHIOPIC SYLLABLE BBI;Lo;0;L;;;;;N;;;;;
+AB2B;ETHIOPIC SYLLABLE BBAA;Lo;0;L;;;;;N;;;;;
+AB2C;ETHIOPIC SYLLABLE BBEE;Lo;0;L;;;;;N;;;;;
+AB2D;ETHIOPIC SYLLABLE BBE;Lo;0;L;;;;;N;;;;;
+AB2E;ETHIOPIC SYLLABLE BBO;Lo;0;L;;;;;N;;;;;
+AB30;LATIN SMALL LETTER BARRED ALPHA;Ll;0;L;;;;;N;;;;;
+AB31;LATIN SMALL LETTER A REVERSED-SCHWA;Ll;0;L;;;;;N;;;;;
+AB32;LATIN SMALL LETTER BLACKLETTER E;Ll;0;L;;;;;N;;;;;
+AB33;LATIN SMALL LETTER BARRED E;Ll;0;L;;;;;N;;;;;
+AB34;LATIN SMALL LETTER E WITH FLOURISH;Ll;0;L;;;;;N;;;;;
+AB35;LATIN SMALL LETTER LENIS F;Ll;0;L;;;;;N;;;;;
+AB36;LATIN SMALL LETTER SCRIPT G WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB37;LATIN SMALL LETTER L WITH INVERTED LAZY S;Ll;0;L;;;;;N;;;;;
+AB38;LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
+AB39;LATIN SMALL LETTER L WITH MIDDLE RING;Ll;0;L;;;;;N;;;;;
+AB3A;LATIN SMALL LETTER M WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB3B;LATIN SMALL LETTER N WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB3C;LATIN SMALL LETTER ENG WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB3D;LATIN SMALL LETTER BLACKLETTER O;Ll;0;L;;;;;N;;;;;
+AB3E;LATIN SMALL LETTER BLACKLETTER O WITH STROKE;Ll;0;L;;;;;N;;;;;
+AB3F;LATIN SMALL LETTER OPEN O WITH STROKE;Ll;0;L;;;;;N;;;;;
+AB40;LATIN SMALL LETTER INVERTED OE;Ll;0;L;;;;;N;;;;;
+AB41;LATIN SMALL LETTER TURNED OE WITH STROKE;Ll;0;L;;;;;N;;;;;
+AB42;LATIN SMALL LETTER TURNED OE WITH HORIZONTAL STROKE;Ll;0;L;;;;;N;;;;;
+AB43;LATIN SMALL LETTER TURNED O OPEN-O;Ll;0;L;;;;;N;;;;;
+AB44;LATIN SMALL LETTER TURNED O OPEN-O WITH STROKE;Ll;0;L;;;;;N;;;;;
+AB45;LATIN SMALL LETTER STIRRUP R;Ll;0;L;;;;;N;;;;;
+AB46;LATIN LETTER SMALL CAPITAL R WITH RIGHT LEG;Ll;0;L;;;;;N;;;;;
+AB47;LATIN SMALL LETTER R WITHOUT HANDLE;Ll;0;L;;;;;N;;;;;
+AB48;LATIN SMALL LETTER DOUBLE R;Ll;0;L;;;;;N;;;;;
+AB49;LATIN SMALL LETTER R WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB4A;LATIN SMALL LETTER DOUBLE R WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;
+AB4B;LATIN SMALL LETTER SCRIPT R;Ll;0;L;;;;;N;;;;;
+AB4C;LATIN SMALL LETTER SCRIPT R WITH RING;Ll;0;L;;;;;N;;;;;
+AB4D;LATIN SMALL LETTER BASELINE ESH;Ll;0;L;;;;;N;;;;;
+AB4E;LATIN SMALL LETTER U WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;;
+AB4F;LATIN SMALL LETTER U BAR WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;;
+AB50;LATIN SMALL LETTER UI;Ll;0;L;;;;;N;;;;;
+AB51;LATIN SMALL LETTER TURNED UI;Ll;0;L;;;;;N;;;;;
+AB52;LATIN SMALL LETTER U WITH LEFT HOOK;Ll;0;L;;;;;N;;;;;
+AB53;LATIN SMALL LETTER CHI;Ll;0;L;;;;;N;;;A7B3;;A7B3
+AB54;LATIN SMALL LETTER CHI WITH LOW RIGHT RING;Ll;0;L;;;;;N;;;;;
+AB55;LATIN SMALL LETTER CHI WITH LOW LEFT SERIF;Ll;0;L;;;;;N;;;;;
+AB56;LATIN SMALL LETTER X WITH LOW RIGHT RING;Ll;0;L;;;;;N;;;;;
+AB57;LATIN SMALL LETTER X WITH LONG LEFT LEG;Ll;0;L;;;;;N;;;;;
+AB58;LATIN SMALL LETTER X WITH LONG LEFT LEG AND LOW RIGHT RING;Ll;0;L;;;;;N;;;;;
+AB59;LATIN SMALL LETTER X WITH LONG LEFT LEG WITH SERIF;Ll;0;L;;;;;N;;;;;
+AB5A;LATIN SMALL LETTER Y WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;;
+AB5B;MODIFIER BREVE WITH INVERTED BREVE;Sk;0;L;;;;;N;;;;;
+AB5C;MODIFIER LETTER SMALL HENG;Lm;0;L;<super> A727;;;;N;;;;;
+AB5D;MODIFIER LETTER SMALL L WITH INVERTED LAZY S;Lm;0;L;<super> AB37;;;;N;;;;;
+AB5E;MODIFIER LETTER SMALL L WITH MIDDLE TILDE;Lm;0;L;<super> 026B;;;;N;;;;;
+AB5F;MODIFIER LETTER SMALL U WITH LEFT HOOK;Lm;0;L;<super> AB52;;;;N;;;;;
+AB60;LATIN SMALL LETTER SAKHA YAT;Ll;0;L;;;;;N;;;;;
+AB61;LATIN SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;;;
+AB62;LATIN SMALL LETTER OPEN OE;Ll;0;L;;;;;N;;;;;
+AB63;LATIN SMALL LETTER UO;Ll;0;L;;;;;N;;;;;
+AB64;LATIN SMALL LETTER INVERTED ALPHA;Ll;0;L;;;;;N;;;;;
+AB65;GREEK LETTER SMALL CAPITAL OMEGA;Ll;0;L;;;;;N;;;;;
+AB70;CHEROKEE SMALL LETTER A;Ll;0;L;;;;;N;;;13A0;;13A0
+AB71;CHEROKEE SMALL LETTER E;Ll;0;L;;;;;N;;;13A1;;13A1
+AB72;CHEROKEE SMALL LETTER I;Ll;0;L;;;;;N;;;13A2;;13A2
+AB73;CHEROKEE SMALL LETTER O;Ll;0;L;;;;;N;;;13A3;;13A3
+AB74;CHEROKEE SMALL LETTER U;Ll;0;L;;;;;N;;;13A4;;13A4
+AB75;CHEROKEE SMALL LETTER V;Ll;0;L;;;;;N;;;13A5;;13A5
+AB76;CHEROKEE SMALL LETTER GA;Ll;0;L;;;;;N;;;13A6;;13A6
+AB77;CHEROKEE SMALL LETTER KA;Ll;0;L;;;;;N;;;13A7;;13A7
+AB78;CHEROKEE SMALL LETTER GE;Ll;0;L;;;;;N;;;13A8;;13A8
+AB79;CHEROKEE SMALL LETTER GI;Ll;0;L;;;;;N;;;13A9;;13A9
+AB7A;CHEROKEE SMALL LETTER GO;Ll;0;L;;;;;N;;;13AA;;13AA
+AB7B;CHEROKEE SMALL LETTER GU;Ll;0;L;;;;;N;;;13AB;;13AB
+AB7C;CHEROKEE SMALL LETTER GV;Ll;0;L;;;;;N;;;13AC;;13AC
+AB7D;CHEROKEE SMALL LETTER HA;Ll;0;L;;;;;N;;;13AD;;13AD
+AB7E;CHEROKEE SMALL LETTER HE;Ll;0;L;;;;;N;;;13AE;;13AE
+AB7F;CHEROKEE SMALL LETTER HI;Ll;0;L;;;;;N;;;13AF;;13AF
+AB80;CHEROKEE SMALL LETTER HO;Ll;0;L;;;;;N;;;13B0;;13B0
+AB81;CHEROKEE SMALL LETTER HU;Ll;0;L;;;;;N;;;13B1;;13B1
+AB82;CHEROKEE SMALL LETTER HV;Ll;0;L;;;;;N;;;13B2;;13B2
+AB83;CHEROKEE SMALL LETTER LA;Ll;0;L;;;;;N;;;13B3;;13B3
+AB84;CHEROKEE SMALL LETTER LE;Ll;0;L;;;;;N;;;13B4;;13B4
+AB85;CHEROKEE SMALL LETTER LI;Ll;0;L;;;;;N;;;13B5;;13B5
+AB86;CHEROKEE SMALL LETTER LO;Ll;0;L;;;;;N;;;13B6;;13B6
+AB87;CHEROKEE SMALL LETTER LU;Ll;0;L;;;;;N;;;13B7;;13B7
+AB88;CHEROKEE SMALL LETTER LV;Ll;0;L;;;;;N;;;13B8;;13B8
+AB89;CHEROKEE SMALL LETTER MA;Ll;0;L;;;;;N;;;13B9;;13B9
+AB8A;CHEROKEE SMALL LETTER ME;Ll;0;L;;;;;N;;;13BA;;13BA
+AB8B;CHEROKEE SMALL LETTER MI;Ll;0;L;;;;;N;;;13BB;;13BB
+AB8C;CHEROKEE SMALL LETTER MO;Ll;0;L;;;;;N;;;13BC;;13BC
+AB8D;CHEROKEE SMALL LETTER MU;Ll;0;L;;;;;N;;;13BD;;13BD
+AB8E;CHEROKEE SMALL LETTER NA;Ll;0;L;;;;;N;;;13BE;;13BE
+AB8F;CHEROKEE SMALL LETTER HNA;Ll;0;L;;;;;N;;;13BF;;13BF
+AB90;CHEROKEE SMALL LETTER NAH;Ll;0;L;;;;;N;;;13C0;;13C0
+AB91;CHEROKEE SMALL LETTER NE;Ll;0;L;;;;;N;;;13C1;;13C1
+AB92;CHEROKEE SMALL LETTER NI;Ll;0;L;;;;;N;;;13C2;;13C2
+AB93;CHEROKEE SMALL LETTER NO;Ll;0;L;;;;;N;;;13C3;;13C3
+AB94;CHEROKEE SMALL LETTER NU;Ll;0;L;;;;;N;;;13C4;;13C4
+AB95;CHEROKEE SMALL LETTER NV;Ll;0;L;;;;;N;;;13C5;;13C5
+AB96;CHEROKEE SMALL LETTER QUA;Ll;0;L;;;;;N;;;13C6;;13C6
+AB97;CHEROKEE SMALL LETTER QUE;Ll;0;L;;;;;N;;;13C7;;13C7
+AB98;CHEROKEE SMALL LETTER QUI;Ll;0;L;;;;;N;;;13C8;;13C8
+AB99;CHEROKEE SMALL LETTER QUO;Ll;0;L;;;;;N;;;13C9;;13C9
+AB9A;CHEROKEE SMALL LETTER QUU;Ll;0;L;;;;;N;;;13CA;;13CA
+AB9B;CHEROKEE SMALL LETTER QUV;Ll;0;L;;;;;N;;;13CB;;13CB
+AB9C;CHEROKEE SMALL LETTER SA;Ll;0;L;;;;;N;;;13CC;;13CC
+AB9D;CHEROKEE SMALL LETTER S;Ll;0;L;;;;;N;;;13CD;;13CD
+AB9E;CHEROKEE SMALL LETTER SE;Ll;0;L;;;;;N;;;13CE;;13CE
+AB9F;CHEROKEE SMALL LETTER SI;Ll;0;L;;;;;N;;;13CF;;13CF
+ABA0;CHEROKEE SMALL LETTER SO;Ll;0;L;;;;;N;;;13D0;;13D0
+ABA1;CHEROKEE SMALL LETTER SU;Ll;0;L;;;;;N;;;13D1;;13D1
+ABA2;CHEROKEE SMALL LETTER SV;Ll;0;L;;;;;N;;;13D2;;13D2
+ABA3;CHEROKEE SMALL LETTER DA;Ll;0;L;;;;;N;;;13D3;;13D3
+ABA4;CHEROKEE SMALL LETTER TA;Ll;0;L;;;;;N;;;13D4;;13D4
+ABA5;CHEROKEE SMALL LETTER DE;Ll;0;L;;;;;N;;;13D5;;13D5
+ABA6;CHEROKEE SMALL LETTER TE;Ll;0;L;;;;;N;;;13D6;;13D6
+ABA7;CHEROKEE SMALL LETTER DI;Ll;0;L;;;;;N;;;13D7;;13D7
+ABA8;CHEROKEE SMALL LETTER TI;Ll;0;L;;;;;N;;;13D8;;13D8
+ABA9;CHEROKEE SMALL LETTER DO;Ll;0;L;;;;;N;;;13D9;;13D9
+ABAA;CHEROKEE SMALL LETTER DU;Ll;0;L;;;;;N;;;13DA;;13DA
+ABAB;CHEROKEE SMALL LETTER DV;Ll;0;L;;;;;N;;;13DB;;13DB
+ABAC;CHEROKEE SMALL LETTER DLA;Ll;0;L;;;;;N;;;13DC;;13DC
+ABAD;CHEROKEE SMALL LETTER TLA;Ll;0;L;;;;;N;;;13DD;;13DD
+ABAE;CHEROKEE SMALL LETTER TLE;Ll;0;L;;;;;N;;;13DE;;13DE
+ABAF;CHEROKEE SMALL LETTER TLI;Ll;0;L;;;;;N;;;13DF;;13DF
+ABB0;CHEROKEE SMALL LETTER TLO;Ll;0;L;;;;;N;;;13E0;;13E0
+ABB1;CHEROKEE SMALL LETTER TLU;Ll;0;L;;;;;N;;;13E1;;13E1
+ABB2;CHEROKEE SMALL LETTER TLV;Ll;0;L;;;;;N;;;13E2;;13E2
+ABB3;CHEROKEE SMALL LETTER TSA;Ll;0;L;;;;;N;;;13E3;;13E3
+ABB4;CHEROKEE SMALL LETTER TSE;Ll;0;L;;;;;N;;;13E4;;13E4
+ABB5;CHEROKEE SMALL LETTER TSI;Ll;0;L;;;;;N;;;13E5;;13E5
+ABB6;CHEROKEE SMALL LETTER TSO;Ll;0;L;;;;;N;;;13E6;;13E6
+ABB7;CHEROKEE SMALL LETTER TSU;Ll;0;L;;;;;N;;;13E7;;13E7
+ABB8;CHEROKEE SMALL LETTER TSV;Ll;0;L;;;;;N;;;13E8;;13E8
+ABB9;CHEROKEE SMALL LETTER WA;Ll;0;L;;;;;N;;;13E9;;13E9
+ABBA;CHEROKEE SMALL LETTER WE;Ll;0;L;;;;;N;;;13EA;;13EA
+ABBB;CHEROKEE SMALL LETTER WI;Ll;0;L;;;;;N;;;13EB;;13EB
+ABBC;CHEROKEE SMALL LETTER WO;Ll;0;L;;;;;N;;;13EC;;13EC
+ABBD;CHEROKEE SMALL LETTER WU;Ll;0;L;;;;;N;;;13ED;;13ED
+ABBE;CHEROKEE SMALL LETTER WV;Ll;0;L;;;;;N;;;13EE;;13EE
+ABBF;CHEROKEE SMALL LETTER YA;Ll;0;L;;;;;N;;;13EF;;13EF
+ABC0;MEETEI MAYEK LETTER KOK;Lo;0;L;;;;;N;;;;;
+ABC1;MEETEI MAYEK LETTER SAM;Lo;0;L;;;;;N;;;;;
+ABC2;MEETEI MAYEK LETTER LAI;Lo;0;L;;;;;N;;;;;
+ABC3;MEETEI MAYEK LETTER MIT;Lo;0;L;;;;;N;;;;;
+ABC4;MEETEI MAYEK LETTER PA;Lo;0;L;;;;;N;;;;;
+ABC5;MEETEI MAYEK LETTER NA;Lo;0;L;;;;;N;;;;;
+ABC6;MEETEI MAYEK LETTER CHIL;Lo;0;L;;;;;N;;;;;
+ABC7;MEETEI MAYEK LETTER TIL;Lo;0;L;;;;;N;;;;;
+ABC8;MEETEI MAYEK LETTER KHOU;Lo;0;L;;;;;N;;;;;
+ABC9;MEETEI MAYEK LETTER NGOU;Lo;0;L;;;;;N;;;;;
+ABCA;MEETEI MAYEK LETTER THOU;Lo;0;L;;;;;N;;;;;
+ABCB;MEETEI MAYEK LETTER WAI;Lo;0;L;;;;;N;;;;;
+ABCC;MEETEI MAYEK LETTER YANG;Lo;0;L;;;;;N;;;;;
+ABCD;MEETEI MAYEK LETTER HUK;Lo;0;L;;;;;N;;;;;
+ABCE;MEETEI MAYEK LETTER UN;Lo;0;L;;;;;N;;;;;
+ABCF;MEETEI MAYEK LETTER I;Lo;0;L;;;;;N;;;;;
+ABD0;MEETEI MAYEK LETTER PHAM;Lo;0;L;;;;;N;;;;;
+ABD1;MEETEI MAYEK LETTER ATIYA;Lo;0;L;;;;;N;;;;;
+ABD2;MEETEI MAYEK LETTER GOK;Lo;0;L;;;;;N;;;;;
+ABD3;MEETEI MAYEK LETTER JHAM;Lo;0;L;;;;;N;;;;;
+ABD4;MEETEI MAYEK LETTER RAI;Lo;0;L;;;;;N;;;;;
+ABD5;MEETEI MAYEK LETTER BA;Lo;0;L;;;;;N;;;;;
+ABD6;MEETEI MAYEK LETTER JIL;Lo;0;L;;;;;N;;;;;
+ABD7;MEETEI MAYEK LETTER DIL;Lo;0;L;;;;;N;;;;;
+ABD8;MEETEI MAYEK LETTER GHOU;Lo;0;L;;;;;N;;;;;
+ABD9;MEETEI MAYEK LETTER DHOU;Lo;0;L;;;;;N;;;;;
+ABDA;MEETEI MAYEK LETTER BHAM;Lo;0;L;;;;;N;;;;;
+ABDB;MEETEI MAYEK LETTER KOK LONSUM;Lo;0;L;;;;;N;;;;;
+ABDC;MEETEI MAYEK LETTER LAI LONSUM;Lo;0;L;;;;;N;;;;;
+ABDD;MEETEI MAYEK LETTER MIT LONSUM;Lo;0;L;;;;;N;;;;;
+ABDE;MEETEI MAYEK LETTER PA LONSUM;Lo;0;L;;;;;N;;;;;
+ABDF;MEETEI MAYEK LETTER NA LONSUM;Lo;0;L;;;;;N;;;;;
+ABE0;MEETEI MAYEK LETTER TIL LONSUM;Lo;0;L;;;;;N;;;;;
+ABE1;MEETEI MAYEK LETTER NGOU LONSUM;Lo;0;L;;;;;N;;;;;
+ABE2;MEETEI MAYEK LETTER I LONSUM;Lo;0;L;;;;;N;;;;;
+ABE3;MEETEI MAYEK VOWEL SIGN ONAP;Mc;0;L;;;;;N;;;;;
+ABE4;MEETEI MAYEK VOWEL SIGN INAP;Mc;0;L;;;;;N;;;;;
+ABE5;MEETEI MAYEK VOWEL SIGN ANAP;Mn;0;NSM;;;;;N;;;;;
+ABE6;MEETEI MAYEK VOWEL SIGN YENAP;Mc;0;L;;;;;N;;;;;
+ABE7;MEETEI MAYEK VOWEL SIGN SOUNAP;Mc;0;L;;;;;N;;;;;
+ABE8;MEETEI MAYEK VOWEL SIGN UNAP;Mn;0;NSM;;;;;N;;;;;
+ABE9;MEETEI MAYEK VOWEL SIGN CHEINAP;Mc;0;L;;;;;N;;;;;
+ABEA;MEETEI MAYEK VOWEL SIGN NUNG;Mc;0;L;;;;;N;;;;;
+ABEB;MEETEI MAYEK CHEIKHEI;Po;0;L;;;;;N;;;;;
+ABEC;MEETEI MAYEK LUM IYEK;Mc;0;L;;;;;N;;;;;
+ABED;MEETEI MAYEK APUN IYEK;Mn;9;NSM;;;;;N;;;;;
+ABF0;MEETEI MAYEK DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+ABF1;MEETEI MAYEK DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+ABF2;MEETEI MAYEK DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+ABF3;MEETEI MAYEK DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+ABF4;MEETEI MAYEK DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+ABF5;MEETEI MAYEK DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+ABF6;MEETEI MAYEK DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+ABF7;MEETEI MAYEK DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+ABF8;MEETEI MAYEK DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+ABF9;MEETEI MAYEK DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+AC00;<Hangul Syllable, First>;Lo;0;L;;;;;N;;;;;
+D7A3;<Hangul Syllable, Last>;Lo;0;L;;;;;N;;;;;
+D7B0;HANGUL JUNGSEONG O-YEO;Lo;0;L;;;;;N;;;;;
+D7B1;HANGUL JUNGSEONG O-O-I;Lo;0;L;;;;;N;;;;;
+D7B2;HANGUL JUNGSEONG YO-A;Lo;0;L;;;;;N;;;;;
+D7B3;HANGUL JUNGSEONG YO-AE;Lo;0;L;;;;;N;;;;;
+D7B4;HANGUL JUNGSEONG YO-EO;Lo;0;L;;;;;N;;;;;
+D7B5;HANGUL JUNGSEONG U-YEO;Lo;0;L;;;;;N;;;;;
+D7B6;HANGUL JUNGSEONG U-I-I;Lo;0;L;;;;;N;;;;;
+D7B7;HANGUL JUNGSEONG YU-AE;Lo;0;L;;;;;N;;;;;
+D7B8;HANGUL JUNGSEONG YU-O;Lo;0;L;;;;;N;;;;;
+D7B9;HANGUL JUNGSEONG EU-A;Lo;0;L;;;;;N;;;;;
+D7BA;HANGUL JUNGSEONG EU-EO;Lo;0;L;;;;;N;;;;;
+D7BB;HANGUL JUNGSEONG EU-E;Lo;0;L;;;;;N;;;;;
+D7BC;HANGUL JUNGSEONG EU-O;Lo;0;L;;;;;N;;;;;
+D7BD;HANGUL JUNGSEONG I-YA-O;Lo;0;L;;;;;N;;;;;
+D7BE;HANGUL JUNGSEONG I-YAE;Lo;0;L;;;;;N;;;;;
+D7BF;HANGUL JUNGSEONG I-YEO;Lo;0;L;;;;;N;;;;;
+D7C0;HANGUL JUNGSEONG I-YE;Lo;0;L;;;;;N;;;;;
+D7C1;HANGUL JUNGSEONG I-O-I;Lo;0;L;;;;;N;;;;;
+D7C2;HANGUL JUNGSEONG I-YO;Lo;0;L;;;;;N;;;;;
+D7C3;HANGUL JUNGSEONG I-YU;Lo;0;L;;;;;N;;;;;
+D7C4;HANGUL JUNGSEONG I-I;Lo;0;L;;;;;N;;;;;
+D7C5;HANGUL JUNGSEONG ARAEA-A;Lo;0;L;;;;;N;;;;;
+D7C6;HANGUL JUNGSEONG ARAEA-E;Lo;0;L;;;;;N;;;;;
+D7CB;HANGUL JONGSEONG NIEUN-RIEUL;Lo;0;L;;;;;N;;;;;
+D7CC;HANGUL JONGSEONG NIEUN-CHIEUCH;Lo;0;L;;;;;N;;;;;
+D7CD;HANGUL JONGSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;;
+D7CE;HANGUL JONGSEONG SSANGTIKEUT-PIEUP;Lo;0;L;;;;;N;;;;;
+D7CF;HANGUL JONGSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;;
+D7D0;HANGUL JONGSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;;
+D7D1;HANGUL JONGSEONG TIKEUT-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+D7D2;HANGUL JONGSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;;
+D7D3;HANGUL JONGSEONG TIKEUT-CHIEUCH;Lo;0;L;;;;;N;;;;;
+D7D4;HANGUL JONGSEONG TIKEUT-THIEUTH;Lo;0;L;;;;;N;;;;;
+D7D5;HANGUL JONGSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
+D7D6;HANGUL JONGSEONG RIEUL-KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;;
+D7D7;HANGUL JONGSEONG SSANGRIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;;
+D7D8;HANGUL JONGSEONG RIEUL-MIEUM-HIEUH;Lo;0;L;;;;;N;;;;;
+D7D9;HANGUL JONGSEONG RIEUL-PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;;
+D7DA;HANGUL JONGSEONG RIEUL-PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;
+D7DB;HANGUL JONGSEONG RIEUL-YESIEUNG;Lo;0;L;;;;;N;;;;;
+D7DC;HANGUL JONGSEONG RIEUL-YEORINHIEUH-HIEUH;Lo;0;L;;;;;N;;;;;
+D7DD;HANGUL JONGSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;;
+D7DE;HANGUL JONGSEONG MIEUM-NIEUN;Lo;0;L;;;;;N;;;;;
+D7DF;HANGUL JONGSEONG MIEUM-SSANGNIEUN;Lo;0;L;;;;;N;;;;;
+D7E0;HANGUL JONGSEONG SSANGMIEUM;Lo;0;L;;;;;N;;;;;
+D7E1;HANGUL JONGSEONG MIEUM-PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
+D7E2;HANGUL JONGSEONG MIEUM-CIEUC;Lo;0;L;;;;;N;;;;;
+D7E3;HANGUL JONGSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;;
+D7E4;HANGUL JONGSEONG PIEUP-RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;;
+D7E5;HANGUL JONGSEONG PIEUP-MIEUM;Lo;0;L;;;;;N;;;;;
+D7E6;HANGUL JONGSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;;
+D7E7;HANGUL JONGSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+D7E8;HANGUL JONGSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;;
+D7E9;HANGUL JONGSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;;
+D7EA;HANGUL JONGSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;;
+D7EB;HANGUL JONGSEONG SIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+D7EC;HANGUL JONGSEONG SSANGSIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
+D7ED;HANGUL JONGSEONG SSANGSIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
+D7EE;HANGUL JONGSEONG SIOS-PANSIOS;Lo;0;L;;;;;N;;;;;
+D7EF;HANGUL JONGSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;;
+D7F0;HANGUL JONGSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;;
+D7F1;HANGUL JONGSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;;
+D7F2;HANGUL JONGSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;;
+D7F3;HANGUL JONGSEONG PANSIOS-PIEUP;Lo;0;L;;;;;N;;;;;
+D7F4;HANGUL JONGSEONG PANSIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
+D7F5;HANGUL JONGSEONG YESIEUNG-MIEUM;Lo;0;L;;;;;N;;;;;
+D7F6;HANGUL JONGSEONG YESIEUNG-HIEUH;Lo;0;L;;;;;N;;;;;
+D7F7;HANGUL JONGSEONG CIEUC-PIEUP;Lo;0;L;;;;;N;;;;;
+D7F8;HANGUL JONGSEONG CIEUC-SSANGPIEUP;Lo;0;L;;;;;N;;;;;
+D7F9;HANGUL JONGSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;;
+D7FA;HANGUL JONGSEONG PHIEUPH-SIOS;Lo;0;L;;;;;N;;;;;
+D7FB;HANGUL JONGSEONG PHIEUPH-THIEUTH;Lo;0;L;;;;;N;;;;;
+D800;<Non Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;
+DB7F;<Non Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;
+DB80;<Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;
+DBFF;<Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;
+DC00;<Low Surrogate, First>;Cs;0;L;;;;;N;;;;;
+DFFF;<Low Surrogate, Last>;Cs;0;L;;;;;N;;;;;
+E000;<Private Use, First>;Co;0;L;;;;;N;;;;;
+F8FF;<Private Use, Last>;Co;0;L;;;;;N;;;;;
+F900;CJK COMPATIBILITY IDEOGRAPH-F900;Lo;0;L;8C48;;;;N;;;;;
+F901;CJK COMPATIBILITY IDEOGRAPH-F901;Lo;0;L;66F4;;;;N;;;;;
+F902;CJK COMPATIBILITY IDEOGRAPH-F902;Lo;0;L;8ECA;;;;N;;;;;
+F903;CJK COMPATIBILITY IDEOGRAPH-F903;Lo;0;L;8CC8;;;;N;;;;;
+F904;CJK COMPATIBILITY IDEOGRAPH-F904;Lo;0;L;6ED1;;;;N;;;;;
+F905;CJK COMPATIBILITY IDEOGRAPH-F905;Lo;0;L;4E32;;;;N;;;;;
+F906;CJK COMPATIBILITY IDEOGRAPH-F906;Lo;0;L;53E5;;;;N;;;;;
+F907;CJK COMPATIBILITY IDEOGRAPH-F907;Lo;0;L;9F9C;;;;N;;;;;
+F908;CJK COMPATIBILITY IDEOGRAPH-F908;Lo;0;L;9F9C;;;;N;;;;;
+F909;CJK COMPATIBILITY IDEOGRAPH-F909;Lo;0;L;5951;;;;N;;;;;
+F90A;CJK COMPATIBILITY IDEOGRAPH-F90A;Lo;0;L;91D1;;;;N;;;;;
+F90B;CJK COMPATIBILITY IDEOGRAPH-F90B;Lo;0;L;5587;;;;N;;;;;
+F90C;CJK COMPATIBILITY IDEOGRAPH-F90C;Lo;0;L;5948;;;;N;;;;;
+F90D;CJK COMPATIBILITY IDEOGRAPH-F90D;Lo;0;L;61F6;;;;N;;;;;
+F90E;CJK COMPATIBILITY IDEOGRAPH-F90E;Lo;0;L;7669;;;;N;;;;;
+F90F;CJK COMPATIBILITY IDEOGRAPH-F90F;Lo;0;L;7F85;;;;N;;;;;
+F910;CJK COMPATIBILITY IDEOGRAPH-F910;Lo;0;L;863F;;;;N;;;;;
+F911;CJK COMPATIBILITY IDEOGRAPH-F911;Lo;0;L;87BA;;;;N;;;;;
+F912;CJK COMPATIBILITY IDEOGRAPH-F912;Lo;0;L;88F8;;;;N;;;;;
+F913;CJK COMPATIBILITY IDEOGRAPH-F913;Lo;0;L;908F;;;;N;;;;;
+F914;CJK COMPATIBILITY IDEOGRAPH-F914;Lo;0;L;6A02;;;;N;;;;;
+F915;CJK COMPATIBILITY IDEOGRAPH-F915;Lo;0;L;6D1B;;;;N;;;;;
+F916;CJK COMPATIBILITY IDEOGRAPH-F916;Lo;0;L;70D9;;;;N;;;;;
+F917;CJK COMPATIBILITY IDEOGRAPH-F917;Lo;0;L;73DE;;;;N;;;;;
+F918;CJK COMPATIBILITY IDEOGRAPH-F918;Lo;0;L;843D;;;;N;;;;;
+F919;CJK COMPATIBILITY IDEOGRAPH-F919;Lo;0;L;916A;;;;N;;;;;
+F91A;CJK COMPATIBILITY IDEOGRAPH-F91A;Lo;0;L;99F1;;;;N;;;;;
+F91B;CJK COMPATIBILITY IDEOGRAPH-F91B;Lo;0;L;4E82;;;;N;;;;;
+F91C;CJK COMPATIBILITY IDEOGRAPH-F91C;Lo;0;L;5375;;;;N;;;;;
+F91D;CJK COMPATIBILITY IDEOGRAPH-F91D;Lo;0;L;6B04;;;;N;;;;;
+F91E;CJK COMPATIBILITY IDEOGRAPH-F91E;Lo;0;L;721B;;;;N;;;;;
+F91F;CJK COMPATIBILITY IDEOGRAPH-F91F;Lo;0;L;862D;;;;N;;;;;
+F920;CJK COMPATIBILITY IDEOGRAPH-F920;Lo;0;L;9E1E;;;;N;;;;;
+F921;CJK COMPATIBILITY IDEOGRAPH-F921;Lo;0;L;5D50;;;;N;;;;;
+F922;CJK COMPATIBILITY IDEOGRAPH-F922;Lo;0;L;6FEB;;;;N;;;;;
+F923;CJK COMPATIBILITY IDEOGRAPH-F923;Lo;0;L;85CD;;;;N;;;;;
+F924;CJK COMPATIBILITY IDEOGRAPH-F924;Lo;0;L;8964;;;;N;;;;;
+F925;CJK COMPATIBILITY IDEOGRAPH-F925;Lo;0;L;62C9;;;;N;;;;;
+F926;CJK COMPATIBILITY IDEOGRAPH-F926;Lo;0;L;81D8;;;;N;;;;;
+F927;CJK COMPATIBILITY IDEOGRAPH-F927;Lo;0;L;881F;;;;N;;;;;
+F928;CJK COMPATIBILITY IDEOGRAPH-F928;Lo;0;L;5ECA;;;;N;;;;;
+F929;CJK COMPATIBILITY IDEOGRAPH-F929;Lo;0;L;6717;;;;N;;;;;
+F92A;CJK COMPATIBILITY IDEOGRAPH-F92A;Lo;0;L;6D6A;;;;N;;;;;
+F92B;CJK COMPATIBILITY IDEOGRAPH-F92B;Lo;0;L;72FC;;;;N;;;;;
+F92C;CJK COMPATIBILITY IDEOGRAPH-F92C;Lo;0;L;90CE;;;;N;;;;;
+F92D;CJK COMPATIBILITY IDEOGRAPH-F92D;Lo;0;L;4F86;;;;N;;;;;
+F92E;CJK COMPATIBILITY IDEOGRAPH-F92E;Lo;0;L;51B7;;;;N;;;;;
+F92F;CJK COMPATIBILITY IDEOGRAPH-F92F;Lo;0;L;52DE;;;;N;;;;;
+F930;CJK COMPATIBILITY IDEOGRAPH-F930;Lo;0;L;64C4;;;;N;;;;;
+F931;CJK COMPATIBILITY IDEOGRAPH-F931;Lo;0;L;6AD3;;;;N;;;;;
+F932;CJK COMPATIBILITY IDEOGRAPH-F932;Lo;0;L;7210;;;;N;;;;;
+F933;CJK COMPATIBILITY IDEOGRAPH-F933;Lo;0;L;76E7;;;;N;;;;;
+F934;CJK COMPATIBILITY IDEOGRAPH-F934;Lo;0;L;8001;;;;N;;;;;
+F935;CJK COMPATIBILITY IDEOGRAPH-F935;Lo;0;L;8606;;;;N;;;;;
+F936;CJK COMPATIBILITY IDEOGRAPH-F936;Lo;0;L;865C;;;;N;;;;;
+F937;CJK COMPATIBILITY IDEOGRAPH-F937;Lo;0;L;8DEF;;;;N;;;;;
+F938;CJK COMPATIBILITY IDEOGRAPH-F938;Lo;0;L;9732;;;;N;;;;;
+F939;CJK COMPATIBILITY IDEOGRAPH-F939;Lo;0;L;9B6F;;;;N;;;;;
+F93A;CJK COMPATIBILITY IDEOGRAPH-F93A;Lo;0;L;9DFA;;;;N;;;;;
+F93B;CJK COMPATIBILITY IDEOGRAPH-F93B;Lo;0;L;788C;;;;N;;;;;
+F93C;CJK COMPATIBILITY IDEOGRAPH-F93C;Lo;0;L;797F;;;;N;;;;;
+F93D;CJK COMPATIBILITY IDEOGRAPH-F93D;Lo;0;L;7DA0;;;;N;;;;;
+F93E;CJK COMPATIBILITY IDEOGRAPH-F93E;Lo;0;L;83C9;;;;N;;;;;
+F93F;CJK COMPATIBILITY IDEOGRAPH-F93F;Lo;0;L;9304;;;;N;;;;;
+F940;CJK COMPATIBILITY IDEOGRAPH-F940;Lo;0;L;9E7F;;;;N;;;;;
+F941;CJK COMPATIBILITY IDEOGRAPH-F941;Lo;0;L;8AD6;;;;N;;;;;
+F942;CJK COMPATIBILITY IDEOGRAPH-F942;Lo;0;L;58DF;;;;N;;;;;
+F943;CJK COMPATIBILITY IDEOGRAPH-F943;Lo;0;L;5F04;;;;N;;;;;
+F944;CJK COMPATIBILITY IDEOGRAPH-F944;Lo;0;L;7C60;;;;N;;;;;
+F945;CJK COMPATIBILITY IDEOGRAPH-F945;Lo;0;L;807E;;;;N;;;;;
+F946;CJK COMPATIBILITY IDEOGRAPH-F946;Lo;0;L;7262;;;;N;;;;;
+F947;CJK COMPATIBILITY IDEOGRAPH-F947;Lo;0;L;78CA;;;;N;;;;;
+F948;CJK COMPATIBILITY IDEOGRAPH-F948;Lo;0;L;8CC2;;;;N;;;;;
+F949;CJK COMPATIBILITY IDEOGRAPH-F949;Lo;0;L;96F7;;;;N;;;;;
+F94A;CJK COMPATIBILITY IDEOGRAPH-F94A;Lo;0;L;58D8;;;;N;;;;;
+F94B;CJK COMPATIBILITY IDEOGRAPH-F94B;Lo;0;L;5C62;;;;N;;;;;
+F94C;CJK COMPATIBILITY IDEOGRAPH-F94C;Lo;0;L;6A13;;;;N;;;;;
+F94D;CJK COMPATIBILITY IDEOGRAPH-F94D;Lo;0;L;6DDA;;;;N;;;;;
+F94E;CJK COMPATIBILITY IDEOGRAPH-F94E;Lo;0;L;6F0F;;;;N;;;;;
+F94F;CJK COMPATIBILITY IDEOGRAPH-F94F;Lo;0;L;7D2F;;;;N;;;;;
+F950;CJK COMPATIBILITY IDEOGRAPH-F950;Lo;0;L;7E37;;;;N;;;;;
+F951;CJK COMPATIBILITY IDEOGRAPH-F951;Lo;0;L;964B;;;;N;;;;;
+F952;CJK COMPATIBILITY IDEOGRAPH-F952;Lo;0;L;52D2;;;;N;;;;;
+F953;CJK COMPATIBILITY IDEOGRAPH-F953;Lo;0;L;808B;;;;N;;;;;
+F954;CJK COMPATIBILITY IDEOGRAPH-F954;Lo;0;L;51DC;;;;N;;;;;
+F955;CJK COMPATIBILITY IDEOGRAPH-F955;Lo;0;L;51CC;;;;N;;;;;
+F956;CJK COMPATIBILITY IDEOGRAPH-F956;Lo;0;L;7A1C;;;;N;;;;;
+F957;CJK COMPATIBILITY IDEOGRAPH-F957;Lo;0;L;7DBE;;;;N;;;;;
+F958;CJK COMPATIBILITY IDEOGRAPH-F958;Lo;0;L;83F1;;;;N;;;;;
+F959;CJK COMPATIBILITY IDEOGRAPH-F959;Lo;0;L;9675;;;;N;;;;;
+F95A;CJK COMPATIBILITY IDEOGRAPH-F95A;Lo;0;L;8B80;;;;N;;;;;
+F95B;CJK COMPATIBILITY IDEOGRAPH-F95B;Lo;0;L;62CF;;;;N;;;;;
+F95C;CJK COMPATIBILITY IDEOGRAPH-F95C;Lo;0;L;6A02;;;;N;;;;;
+F95D;CJK COMPATIBILITY IDEOGRAPH-F95D;Lo;0;L;8AFE;;;;N;;;;;
+F95E;CJK COMPATIBILITY IDEOGRAPH-F95E;Lo;0;L;4E39;;;;N;;;;;
+F95F;CJK COMPATIBILITY IDEOGRAPH-F95F;Lo;0;L;5BE7;;;;N;;;;;
+F960;CJK COMPATIBILITY IDEOGRAPH-F960;Lo;0;L;6012;;;;N;;;;;
+F961;CJK COMPATIBILITY IDEOGRAPH-F961;Lo;0;L;7387;;;;N;;;;;
+F962;CJK COMPATIBILITY IDEOGRAPH-F962;Lo;0;L;7570;;;;N;;;;;
+F963;CJK COMPATIBILITY IDEOGRAPH-F963;Lo;0;L;5317;;;;N;;;;;
+F964;CJK COMPATIBILITY IDEOGRAPH-F964;Lo;0;L;78FB;;;;N;;;;;
+F965;CJK COMPATIBILITY IDEOGRAPH-F965;Lo;0;L;4FBF;;;;N;;;;;
+F966;CJK COMPATIBILITY IDEOGRAPH-F966;Lo;0;L;5FA9;;;;N;;;;;
+F967;CJK COMPATIBILITY IDEOGRAPH-F967;Lo;0;L;4E0D;;;;N;;;;;
+F968;CJK COMPATIBILITY IDEOGRAPH-F968;Lo;0;L;6CCC;;;;N;;;;;
+F969;CJK COMPATIBILITY IDEOGRAPH-F969;Lo;0;L;6578;;;;N;;;;;
+F96A;CJK COMPATIBILITY IDEOGRAPH-F96A;Lo;0;L;7D22;;;;N;;;;;
+F96B;CJK COMPATIBILITY IDEOGRAPH-F96B;Lo;0;L;53C3;;;3;N;;;;;
+F96C;CJK COMPATIBILITY IDEOGRAPH-F96C;Lo;0;L;585E;;;;N;;;;;
+F96D;CJK COMPATIBILITY IDEOGRAPH-F96D;Lo;0;L;7701;;;;N;;;;;
+F96E;CJK COMPATIBILITY IDEOGRAPH-F96E;Lo;0;L;8449;;;;N;;;;;
+F96F;CJK COMPATIBILITY IDEOGRAPH-F96F;Lo;0;L;8AAA;;;;N;;;;;
+F970;CJK COMPATIBILITY IDEOGRAPH-F970;Lo;0;L;6BBA;;;;N;;;;;
+F971;CJK COMPATIBILITY IDEOGRAPH-F971;Lo;0;L;8FB0;;;;N;;;;;
+F972;CJK COMPATIBILITY IDEOGRAPH-F972;Lo;0;L;6C88;;;;N;;;;;
+F973;CJK COMPATIBILITY IDEOGRAPH-F973;Lo;0;L;62FE;;;10;N;;;;;
+F974;CJK COMPATIBILITY IDEOGRAPH-F974;Lo;0;L;82E5;;;;N;;;;;
+F975;CJK COMPATIBILITY IDEOGRAPH-F975;Lo;0;L;63A0;;;;N;;;;;
+F976;CJK COMPATIBILITY IDEOGRAPH-F976;Lo;0;L;7565;;;;N;;;;;
+F977;CJK COMPATIBILITY IDEOGRAPH-F977;Lo;0;L;4EAE;;;;N;;;;;
+F978;CJK COMPATIBILITY IDEOGRAPH-F978;Lo;0;L;5169;;;2;N;;;;;
+F979;CJK COMPATIBILITY IDEOGRAPH-F979;Lo;0;L;51C9;;;;N;;;;;
+F97A;CJK COMPATIBILITY IDEOGRAPH-F97A;Lo;0;L;6881;;;;N;;;;;
+F97B;CJK COMPATIBILITY IDEOGRAPH-F97B;Lo;0;L;7CE7;;;;N;;;;;
+F97C;CJK COMPATIBILITY IDEOGRAPH-F97C;Lo;0;L;826F;;;;N;;;;;
+F97D;CJK COMPATIBILITY IDEOGRAPH-F97D;Lo;0;L;8AD2;;;;N;;;;;
+F97E;CJK COMPATIBILITY IDEOGRAPH-F97E;Lo;0;L;91CF;;;;N;;;;;
+F97F;CJK COMPATIBILITY IDEOGRAPH-F97F;Lo;0;L;52F5;;;;N;;;;;
+F980;CJK COMPATIBILITY IDEOGRAPH-F980;Lo;0;L;5442;;;;N;;;;;
+F981;CJK COMPATIBILITY IDEOGRAPH-F981;Lo;0;L;5973;;;;N;;;;;
+F982;CJK COMPATIBILITY IDEOGRAPH-F982;Lo;0;L;5EEC;;;;N;;;;;
+F983;CJK COMPATIBILITY IDEOGRAPH-F983;Lo;0;L;65C5;;;;N;;;;;
+F984;CJK COMPATIBILITY IDEOGRAPH-F984;Lo;0;L;6FFE;;;;N;;;;;
+F985;CJK COMPATIBILITY IDEOGRAPH-F985;Lo;0;L;792A;;;;N;;;;;
+F986;CJK COMPATIBILITY IDEOGRAPH-F986;Lo;0;L;95AD;;;;N;;;;;
+F987;CJK COMPATIBILITY IDEOGRAPH-F987;Lo;0;L;9A6A;;;;N;;;;;
+F988;CJK COMPATIBILITY IDEOGRAPH-F988;Lo;0;L;9E97;;;;N;;;;;
+F989;CJK COMPATIBILITY IDEOGRAPH-F989;Lo;0;L;9ECE;;;;N;;;;;
+F98A;CJK COMPATIBILITY IDEOGRAPH-F98A;Lo;0;L;529B;;;;N;;;;;
+F98B;CJK COMPATIBILITY IDEOGRAPH-F98B;Lo;0;L;66C6;;;;N;;;;;
+F98C;CJK COMPATIBILITY IDEOGRAPH-F98C;Lo;0;L;6B77;;;;N;;;;;
+F98D;CJK COMPATIBILITY IDEOGRAPH-F98D;Lo;0;L;8F62;;;;N;;;;;
+F98E;CJK COMPATIBILITY IDEOGRAPH-F98E;Lo;0;L;5E74;;;;N;;;;;
+F98F;CJK COMPATIBILITY IDEOGRAPH-F98F;Lo;0;L;6190;;;;N;;;;;
+F990;CJK COMPATIBILITY IDEOGRAPH-F990;Lo;0;L;6200;;;;N;;;;;
+F991;CJK COMPATIBILITY IDEOGRAPH-F991;Lo;0;L;649A;;;;N;;;;;
+F992;CJK COMPATIBILITY IDEOGRAPH-F992;Lo;0;L;6F23;;;;N;;;;;
+F993;CJK COMPATIBILITY IDEOGRAPH-F993;Lo;0;L;7149;;;;N;;;;;
+F994;CJK COMPATIBILITY IDEOGRAPH-F994;Lo;0;L;7489;;;;N;;;;;
+F995;CJK COMPATIBILITY IDEOGRAPH-F995;Lo;0;L;79CA;;;;N;;;;;
+F996;CJK COMPATIBILITY IDEOGRAPH-F996;Lo;0;L;7DF4;;;;N;;;;;
+F997;CJK COMPATIBILITY IDEOGRAPH-F997;Lo;0;L;806F;;;;N;;;;;
+F998;CJK COMPATIBILITY IDEOGRAPH-F998;Lo;0;L;8F26;;;;N;;;;;
+F999;CJK COMPATIBILITY IDEOGRAPH-F999;Lo;0;L;84EE;;;;N;;;;;
+F99A;CJK COMPATIBILITY IDEOGRAPH-F99A;Lo;0;L;9023;;;;N;;;;;
+F99B;CJK COMPATIBILITY IDEOGRAPH-F99B;Lo;0;L;934A;;;;N;;;;;
+F99C;CJK COMPATIBILITY IDEOGRAPH-F99C;Lo;0;L;5217;;;;N;;;;;
+F99D;CJK COMPATIBILITY IDEOGRAPH-F99D;Lo;0;L;52A3;;;;N;;;;;
+F99E;CJK COMPATIBILITY IDEOGRAPH-F99E;Lo;0;L;54BD;;;;N;;;;;
+F99F;CJK COMPATIBILITY IDEOGRAPH-F99F;Lo;0;L;70C8;;;;N;;;;;
+F9A0;CJK COMPATIBILITY IDEOGRAPH-F9A0;Lo;0;L;88C2;;;;N;;;;;
+F9A1;CJK COMPATIBILITY IDEOGRAPH-F9A1;Lo;0;L;8AAA;;;;N;;;;;
+F9A2;CJK COMPATIBILITY IDEOGRAPH-F9A2;Lo;0;L;5EC9;;;;N;;;;;
+F9A3;CJK COMPATIBILITY IDEOGRAPH-F9A3;Lo;0;L;5FF5;;;;N;;;;;
+F9A4;CJK COMPATIBILITY IDEOGRAPH-F9A4;Lo;0;L;637B;;;;N;;;;;
+F9A5;CJK COMPATIBILITY IDEOGRAPH-F9A5;Lo;0;L;6BAE;;;;N;;;;;
+F9A6;CJK COMPATIBILITY IDEOGRAPH-F9A6;Lo;0;L;7C3E;;;;N;;;;;
+F9A7;CJK COMPATIBILITY IDEOGRAPH-F9A7;Lo;0;L;7375;;;;N;;;;;
+F9A8;CJK COMPATIBILITY IDEOGRAPH-F9A8;Lo;0;L;4EE4;;;;N;;;;;
+F9A9;CJK COMPATIBILITY IDEOGRAPH-F9A9;Lo;0;L;56F9;;;;N;;;;;
+F9AA;CJK COMPATIBILITY IDEOGRAPH-F9AA;Lo;0;L;5BE7;;;;N;;;;;
+F9AB;CJK COMPATIBILITY IDEOGRAPH-F9AB;Lo;0;L;5DBA;;;;N;;;;;
+F9AC;CJK COMPATIBILITY IDEOGRAPH-F9AC;Lo;0;L;601C;;;;N;;;;;
+F9AD;CJK COMPATIBILITY IDEOGRAPH-F9AD;Lo;0;L;73B2;;;;N;;;;;
+F9AE;CJK COMPATIBILITY IDEOGRAPH-F9AE;Lo;0;L;7469;;;;N;;;;;
+F9AF;CJK COMPATIBILITY IDEOGRAPH-F9AF;Lo;0;L;7F9A;;;;N;;;;;
+F9B0;CJK COMPATIBILITY IDEOGRAPH-F9B0;Lo;0;L;8046;;;;N;;;;;
+F9B1;CJK COMPATIBILITY IDEOGRAPH-F9B1;Lo;0;L;9234;;;;N;;;;;
+F9B2;CJK COMPATIBILITY IDEOGRAPH-F9B2;Lo;0;L;96F6;;;0;N;;;;;
+F9B3;CJK COMPATIBILITY IDEOGRAPH-F9B3;Lo;0;L;9748;;;;N;;;;;
+F9B4;CJK COMPATIBILITY IDEOGRAPH-F9B4;Lo;0;L;9818;;;;N;;;;;
+F9B5;CJK COMPATIBILITY IDEOGRAPH-F9B5;Lo;0;L;4F8B;;;;N;;;;;
+F9B6;CJK COMPATIBILITY IDEOGRAPH-F9B6;Lo;0;L;79AE;;;;N;;;;;
+F9B7;CJK COMPATIBILITY IDEOGRAPH-F9B7;Lo;0;L;91B4;;;;N;;;;;
+F9B8;CJK COMPATIBILITY IDEOGRAPH-F9B8;Lo;0;L;96B8;;;;N;;;;;
+F9B9;CJK COMPATIBILITY IDEOGRAPH-F9B9;Lo;0;L;60E1;;;;N;;;;;
+F9BA;CJK COMPATIBILITY IDEOGRAPH-F9BA;Lo;0;L;4E86;;;;N;;;;;
+F9BB;CJK COMPATIBILITY IDEOGRAPH-F9BB;Lo;0;L;50DA;;;;N;;;;;
+F9BC;CJK COMPATIBILITY IDEOGRAPH-F9BC;Lo;0;L;5BEE;;;;N;;;;;
+F9BD;CJK COMPATIBILITY IDEOGRAPH-F9BD;Lo;0;L;5C3F;;;;N;;;;;
+F9BE;CJK COMPATIBILITY IDEOGRAPH-F9BE;Lo;0;L;6599;;;;N;;;;;
+F9BF;CJK COMPATIBILITY IDEOGRAPH-F9BF;Lo;0;L;6A02;;;;N;;;;;
+F9C0;CJK COMPATIBILITY IDEOGRAPH-F9C0;Lo;0;L;71CE;;;;N;;;;;
+F9C1;CJK COMPATIBILITY IDEOGRAPH-F9C1;Lo;0;L;7642;;;;N;;;;;
+F9C2;CJK COMPATIBILITY IDEOGRAPH-F9C2;Lo;0;L;84FC;;;;N;;;;;
+F9C3;CJK COMPATIBILITY IDEOGRAPH-F9C3;Lo;0;L;907C;;;;N;;;;;
+F9C4;CJK COMPATIBILITY IDEOGRAPH-F9C4;Lo;0;L;9F8D;;;;N;;;;;
+F9C5;CJK COMPATIBILITY IDEOGRAPH-F9C5;Lo;0;L;6688;;;;N;;;;;
+F9C6;CJK COMPATIBILITY IDEOGRAPH-F9C6;Lo;0;L;962E;;;;N;;;;;
+F9C7;CJK COMPATIBILITY IDEOGRAPH-F9C7;Lo;0;L;5289;;;;N;;;;;
+F9C8;CJK COMPATIBILITY IDEOGRAPH-F9C8;Lo;0;L;677B;;;;N;;;;;
+F9C9;CJK COMPATIBILITY IDEOGRAPH-F9C9;Lo;0;L;67F3;;;;N;;;;;
+F9CA;CJK COMPATIBILITY IDEOGRAPH-F9CA;Lo;0;L;6D41;;;;N;;;;;
+F9CB;CJK COMPATIBILITY IDEOGRAPH-F9CB;Lo;0;L;6E9C;;;;N;;;;;
+F9CC;CJK COMPATIBILITY IDEOGRAPH-F9CC;Lo;0;L;7409;;;;N;;;;;
+F9CD;CJK COMPATIBILITY IDEOGRAPH-F9CD;Lo;0;L;7559;;;;N;;;;;
+F9CE;CJK COMPATIBILITY IDEOGRAPH-F9CE;Lo;0;L;786B;;;;N;;;;;
+F9CF;CJK COMPATIBILITY IDEOGRAPH-F9CF;Lo;0;L;7D10;;;;N;;;;;
+F9D0;CJK COMPATIBILITY IDEOGRAPH-F9D0;Lo;0;L;985E;;;;N;;;;;
+F9D1;CJK COMPATIBILITY IDEOGRAPH-F9D1;Lo;0;L;516D;;;6;N;;;;;
+F9D2;CJK COMPATIBILITY IDEOGRAPH-F9D2;Lo;0;L;622E;;;;N;;;;;
+F9D3;CJK COMPATIBILITY IDEOGRAPH-F9D3;Lo;0;L;9678;;;6;N;;;;;
+F9D4;CJK COMPATIBILITY IDEOGRAPH-F9D4;Lo;0;L;502B;;;;N;;;;;
+F9D5;CJK COMPATIBILITY IDEOGRAPH-F9D5;Lo;0;L;5D19;;;;N;;;;;
+F9D6;CJK COMPATIBILITY IDEOGRAPH-F9D6;Lo;0;L;6DEA;;;;N;;;;;
+F9D7;CJK COMPATIBILITY IDEOGRAPH-F9D7;Lo;0;L;8F2A;;;;N;;;;;
+F9D8;CJK COMPATIBILITY IDEOGRAPH-F9D8;Lo;0;L;5F8B;;;;N;;;;;
+F9D9;CJK COMPATIBILITY IDEOGRAPH-F9D9;Lo;0;L;6144;;;;N;;;;;
+F9DA;CJK COMPATIBILITY IDEOGRAPH-F9DA;Lo;0;L;6817;;;;N;;;;;
+F9DB;CJK COMPATIBILITY IDEOGRAPH-F9DB;Lo;0;L;7387;;;;N;;;;;
+F9DC;CJK COMPATIBILITY IDEOGRAPH-F9DC;Lo;0;L;9686;;;;N;;;;;
+F9DD;CJK COMPATIBILITY IDEOGRAPH-F9DD;Lo;0;L;5229;;;;N;;;;;
+F9DE;CJK COMPATIBILITY IDEOGRAPH-F9DE;Lo;0;L;540F;;;;N;;;;;
+F9DF;CJK COMPATIBILITY IDEOGRAPH-F9DF;Lo;0;L;5C65;;;;N;;;;;
+F9E0;CJK COMPATIBILITY IDEOGRAPH-F9E0;Lo;0;L;6613;;;;N;;;;;
+F9E1;CJK COMPATIBILITY IDEOGRAPH-F9E1;Lo;0;L;674E;;;;N;;;;;
+F9E2;CJK COMPATIBILITY IDEOGRAPH-F9E2;Lo;0;L;68A8;;;;N;;;;;
+F9E3;CJK COMPATIBILITY IDEOGRAPH-F9E3;Lo;0;L;6CE5;;;;N;;;;;
+F9E4;CJK COMPATIBILITY IDEOGRAPH-F9E4;Lo;0;L;7406;;;;N;;;;;
+F9E5;CJK COMPATIBILITY IDEOGRAPH-F9E5;Lo;0;L;75E2;;;;N;;;;;
+F9E6;CJK COMPATIBILITY IDEOGRAPH-F9E6;Lo;0;L;7F79;;;;N;;;;;
+F9E7;CJK COMPATIBILITY IDEOGRAPH-F9E7;Lo;0;L;88CF;;;;N;;;;;
+F9E8;CJK COMPATIBILITY IDEOGRAPH-F9E8;Lo;0;L;88E1;;;;N;;;;;
+F9E9;CJK COMPATIBILITY IDEOGRAPH-F9E9;Lo;0;L;91CC;;;;N;;;;;
+F9EA;CJK COMPATIBILITY IDEOGRAPH-F9EA;Lo;0;L;96E2;;;;N;;;;;
+F9EB;CJK COMPATIBILITY IDEOGRAPH-F9EB;Lo;0;L;533F;;;;N;;;;;
+F9EC;CJK COMPATIBILITY IDEOGRAPH-F9EC;Lo;0;L;6EBA;;;;N;;;;;
+F9ED;CJK COMPATIBILITY IDEOGRAPH-F9ED;Lo;0;L;541D;;;;N;;;;;
+F9EE;CJK COMPATIBILITY IDEOGRAPH-F9EE;Lo;0;L;71D0;;;;N;;;;;
+F9EF;CJK COMPATIBILITY IDEOGRAPH-F9EF;Lo;0;L;7498;;;;N;;;;;
+F9F0;CJK COMPATIBILITY IDEOGRAPH-F9F0;Lo;0;L;85FA;;;;N;;;;;
+F9F1;CJK COMPATIBILITY IDEOGRAPH-F9F1;Lo;0;L;96A3;;;;N;;;;;
+F9F2;CJK COMPATIBILITY IDEOGRAPH-F9F2;Lo;0;L;9C57;;;;N;;;;;
+F9F3;CJK COMPATIBILITY IDEOGRAPH-F9F3;Lo;0;L;9E9F;;;;N;;;;;
+F9F4;CJK COMPATIBILITY IDEOGRAPH-F9F4;Lo;0;L;6797;;;;N;;;;;
+F9F5;CJK COMPATIBILITY IDEOGRAPH-F9F5;Lo;0;L;6DCB;;;;N;;;;;
+F9F6;CJK COMPATIBILITY IDEOGRAPH-F9F6;Lo;0;L;81E8;;;;N;;;;;
+F9F7;CJK COMPATIBILITY IDEOGRAPH-F9F7;Lo;0;L;7ACB;;;;N;;;;;
+F9F8;CJK COMPATIBILITY IDEOGRAPH-F9F8;Lo;0;L;7B20;;;;N;;;;;
+F9F9;CJK COMPATIBILITY IDEOGRAPH-F9F9;Lo;0;L;7C92;;;;N;;;;;
+F9FA;CJK COMPATIBILITY IDEOGRAPH-F9FA;Lo;0;L;72C0;;;;N;;;;;
+F9FB;CJK COMPATIBILITY IDEOGRAPH-F9FB;Lo;0;L;7099;;;;N;;;;;
+F9FC;CJK COMPATIBILITY IDEOGRAPH-F9FC;Lo;0;L;8B58;;;;N;;;;;
+F9FD;CJK COMPATIBILITY IDEOGRAPH-F9FD;Lo;0;L;4EC0;;;10;N;;;;;
+F9FE;CJK COMPATIBILITY IDEOGRAPH-F9FE;Lo;0;L;8336;;;;N;;;;;
+F9FF;CJK COMPATIBILITY IDEOGRAPH-F9FF;Lo;0;L;523A;;;;N;;;;;
+FA00;CJK COMPATIBILITY IDEOGRAPH-FA00;Lo;0;L;5207;;;;N;;;;;
+FA01;CJK COMPATIBILITY IDEOGRAPH-FA01;Lo;0;L;5EA6;;;;N;;;;;
+FA02;CJK COMPATIBILITY IDEOGRAPH-FA02;Lo;0;L;62D3;;;;N;;;;;
+FA03;CJK COMPATIBILITY IDEOGRAPH-FA03;Lo;0;L;7CD6;;;;N;;;;;
+FA04;CJK COMPATIBILITY IDEOGRAPH-FA04;Lo;0;L;5B85;;;;N;;;;;
+FA05;CJK COMPATIBILITY IDEOGRAPH-FA05;Lo;0;L;6D1E;;;;N;;;;;
+FA06;CJK COMPATIBILITY IDEOGRAPH-FA06;Lo;0;L;66B4;;;;N;;;;;
+FA07;CJK COMPATIBILITY IDEOGRAPH-FA07;Lo;0;L;8F3B;;;;N;;;;;
+FA08;CJK COMPATIBILITY IDEOGRAPH-FA08;Lo;0;L;884C;;;;N;;;;;
+FA09;CJK COMPATIBILITY IDEOGRAPH-FA09;Lo;0;L;964D;;;;N;;;;;
+FA0A;CJK COMPATIBILITY IDEOGRAPH-FA0A;Lo;0;L;898B;;;;N;;;;;
+FA0B;CJK COMPATIBILITY IDEOGRAPH-FA0B;Lo;0;L;5ED3;;;;N;;;;;
+FA0C;CJK COMPATIBILITY IDEOGRAPH-FA0C;Lo;0;L;5140;;;;N;;;;;
+FA0D;CJK COMPATIBILITY IDEOGRAPH-FA0D;Lo;0;L;55C0;;;;N;;;;;
+FA0E;CJK COMPATIBILITY IDEOGRAPH-FA0E;Lo;0;L;;;;;N;;;;;
+FA0F;CJK COMPATIBILITY IDEOGRAPH-FA0F;Lo;0;L;;;;;N;;;;;
+FA10;CJK COMPATIBILITY IDEOGRAPH-FA10;Lo;0;L;585A;;;;N;;;;;
+FA11;CJK COMPATIBILITY IDEOGRAPH-FA11;Lo;0;L;;;;;N;;;;;
+FA12;CJK COMPATIBILITY IDEOGRAPH-FA12;Lo;0;L;6674;;;;N;;;;;
+FA13;CJK COMPATIBILITY IDEOGRAPH-FA13;Lo;0;L;;;;;N;;;;;
+FA14;CJK COMPATIBILITY IDEOGRAPH-FA14;Lo;0;L;;;;;N;;;;;
+FA15;CJK COMPATIBILITY IDEOGRAPH-FA15;Lo;0;L;51DE;;;;N;;;;;
+FA16;CJK COMPATIBILITY IDEOGRAPH-FA16;Lo;0;L;732A;;;;N;;;;;
+FA17;CJK COMPATIBILITY IDEOGRAPH-FA17;Lo;0;L;76CA;;;;N;;;;;
+FA18;CJK COMPATIBILITY IDEOGRAPH-FA18;Lo;0;L;793C;;;;N;;;;;
+FA19;CJK COMPATIBILITY IDEOGRAPH-FA19;Lo;0;L;795E;;;;N;;;;;
+FA1A;CJK COMPATIBILITY IDEOGRAPH-FA1A;Lo;0;L;7965;;;;N;;;;;
+FA1B;CJK COMPATIBILITY IDEOGRAPH-FA1B;Lo;0;L;798F;;;;N;;;;;
+FA1C;CJK COMPATIBILITY IDEOGRAPH-FA1C;Lo;0;L;9756;;;;N;;;;;
+FA1D;CJK COMPATIBILITY IDEOGRAPH-FA1D;Lo;0;L;7CBE;;;;N;;;;;
+FA1E;CJK COMPATIBILITY IDEOGRAPH-FA1E;Lo;0;L;7FBD;;;;N;;;;;
+FA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;;;;
+FA20;CJK COMPATIBILITY IDEOGRAPH-FA20;Lo;0;L;8612;;;;N;;;;;
+FA21;CJK COMPATIBILITY IDEOGRAPH-FA21;Lo;0;L;;;;;N;;;;;
+FA22;CJK COMPATIBILITY IDEOGRAPH-FA22;Lo;0;L;8AF8;;;;N;;;;;
+FA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;;;;
+FA24;CJK COMPATIBILITY IDEOGRAPH-FA24;Lo;0;L;;;;;N;;;;;
+FA25;CJK COMPATIBILITY IDEOGRAPH-FA25;Lo;0;L;9038;;;;N;;;;;
+FA26;CJK COMPATIBILITY IDEOGRAPH-FA26;Lo;0;L;90FD;;;;N;;;;;
+FA27;CJK COMPATIBILITY IDEOGRAPH-FA27;Lo;0;L;;;;;N;;;;;
+FA28;CJK COMPATIBILITY IDEOGRAPH-FA28;Lo;0;L;;;;;N;;;;;
+FA29;CJK COMPATIBILITY IDEOGRAPH-FA29;Lo;0;L;;;;;N;;;;;
+FA2A;CJK COMPATIBILITY IDEOGRAPH-FA2A;Lo;0;L;98EF;;;;N;;;;;
+FA2B;CJK COMPATIBILITY IDEOGRAPH-FA2B;Lo;0;L;98FC;;;;N;;;;;
+FA2C;CJK COMPATIBILITY IDEOGRAPH-FA2C;Lo;0;L;9928;;;;N;;;;;
+FA2D;CJK COMPATIBILITY IDEOGRAPH-FA2D;Lo;0;L;9DB4;;;;N;;;;;
+FA2E;CJK COMPATIBILITY IDEOGRAPH-FA2E;Lo;0;L;90DE;;;;N;;;;;
+FA2F;CJK COMPATIBILITY IDEOGRAPH-FA2F;Lo;0;L;96B7;;;;N;;;;;
+FA30;CJK COMPATIBILITY IDEOGRAPH-FA30;Lo;0;L;4FAE;;;;N;;;;;
+FA31;CJK COMPATIBILITY IDEOGRAPH-FA31;Lo;0;L;50E7;;;;N;;;;;
+FA32;CJK COMPATIBILITY IDEOGRAPH-FA32;Lo;0;L;514D;;;;N;;;;;
+FA33;CJK COMPATIBILITY IDEOGRAPH-FA33;Lo;0;L;52C9;;;;N;;;;;
+FA34;CJK COMPATIBILITY IDEOGRAPH-FA34;Lo;0;L;52E4;;;;N;;;;;
+FA35;CJK COMPATIBILITY IDEOGRAPH-FA35;Lo;0;L;5351;;;;N;;;;;
+FA36;CJK COMPATIBILITY IDEOGRAPH-FA36;Lo;0;L;559D;;;;N;;;;;
+FA37;CJK COMPATIBILITY IDEOGRAPH-FA37;Lo;0;L;5606;;;;N;;;;;
+FA38;CJK COMPATIBILITY IDEOGRAPH-FA38;Lo;0;L;5668;;;;N;;;;;
+FA39;CJK COMPATIBILITY IDEOGRAPH-FA39;Lo;0;L;5840;;;;N;;;;;
+FA3A;CJK COMPATIBILITY IDEOGRAPH-FA3A;Lo;0;L;58A8;;;;N;;;;;
+FA3B;CJK COMPATIBILITY IDEOGRAPH-FA3B;Lo;0;L;5C64;;;;N;;;;;
+FA3C;CJK COMPATIBILITY IDEOGRAPH-FA3C;Lo;0;L;5C6E;;;;N;;;;;
+FA3D;CJK COMPATIBILITY IDEOGRAPH-FA3D;Lo;0;L;6094;;;;N;;;;;
+FA3E;CJK COMPATIBILITY IDEOGRAPH-FA3E;Lo;0;L;6168;;;;N;;;;;
+FA3F;CJK COMPATIBILITY IDEOGRAPH-FA3F;Lo;0;L;618E;;;;N;;;;;
+FA40;CJK COMPATIBILITY IDEOGRAPH-FA40;Lo;0;L;61F2;;;;N;;;;;
+FA41;CJK COMPATIBILITY IDEOGRAPH-FA41;Lo;0;L;654F;;;;N;;;;;
+FA42;CJK COMPATIBILITY IDEOGRAPH-FA42;Lo;0;L;65E2;;;;N;;;;;
+FA43;CJK COMPATIBILITY IDEOGRAPH-FA43;Lo;0;L;6691;;;;N;;;;;
+FA44;CJK COMPATIBILITY IDEOGRAPH-FA44;Lo;0;L;6885;;;;N;;;;;
+FA45;CJK COMPATIBILITY IDEOGRAPH-FA45;Lo;0;L;6D77;;;;N;;;;;
+FA46;CJK COMPATIBILITY IDEOGRAPH-FA46;Lo;0;L;6E1A;;;;N;;;;;
+FA47;CJK COMPATIBILITY IDEOGRAPH-FA47;Lo;0;L;6F22;;;;N;;;;;
+FA48;CJK COMPATIBILITY IDEOGRAPH-FA48;Lo;0;L;716E;;;;N;;;;;
+FA49;CJK COMPATIBILITY IDEOGRAPH-FA49;Lo;0;L;722B;;;;N;;;;;
+FA4A;CJK COMPATIBILITY IDEOGRAPH-FA4A;Lo;0;L;7422;;;;N;;;;;
+FA4B;CJK COMPATIBILITY IDEOGRAPH-FA4B;Lo;0;L;7891;;;;N;;;;;
+FA4C;CJK COMPATIBILITY IDEOGRAPH-FA4C;Lo;0;L;793E;;;;N;;;;;
+FA4D;CJK COMPATIBILITY IDEOGRAPH-FA4D;Lo;0;L;7949;;;;N;;;;;
+FA4E;CJK COMPATIBILITY IDEOGRAPH-FA4E;Lo;0;L;7948;;;;N;;;;;
+FA4F;CJK COMPATIBILITY IDEOGRAPH-FA4F;Lo;0;L;7950;;;;N;;;;;
+FA50;CJK COMPATIBILITY IDEOGRAPH-FA50;Lo;0;L;7956;;;;N;;;;;
+FA51;CJK COMPATIBILITY IDEOGRAPH-FA51;Lo;0;L;795D;;;;N;;;;;
+FA52;CJK COMPATIBILITY IDEOGRAPH-FA52;Lo;0;L;798D;;;;N;;;;;
+FA53;CJK COMPATIBILITY IDEOGRAPH-FA53;Lo;0;L;798E;;;;N;;;;;
+FA54;CJK COMPATIBILITY IDEOGRAPH-FA54;Lo;0;L;7A40;;;;N;;;;;
+FA55;CJK COMPATIBILITY IDEOGRAPH-FA55;Lo;0;L;7A81;;;;N;;;;;
+FA56;CJK COMPATIBILITY IDEOGRAPH-FA56;Lo;0;L;7BC0;;;;N;;;;;
+FA57;CJK COMPATIBILITY IDEOGRAPH-FA57;Lo;0;L;7DF4;;;;N;;;;;
+FA58;CJK COMPATIBILITY IDEOGRAPH-FA58;Lo;0;L;7E09;;;;N;;;;;
+FA59;CJK COMPATIBILITY IDEOGRAPH-FA59;Lo;0;L;7E41;;;;N;;;;;
+FA5A;CJK COMPATIBILITY IDEOGRAPH-FA5A;Lo;0;L;7F72;;;;N;;;;;
+FA5B;CJK COMPATIBILITY IDEOGRAPH-FA5B;Lo;0;L;8005;;;;N;;;;;
+FA5C;CJK COMPATIBILITY IDEOGRAPH-FA5C;Lo;0;L;81ED;;;;N;;;;;
+FA5D;CJK COMPATIBILITY IDEOGRAPH-FA5D;Lo;0;L;8279;;;;N;;;;;
+FA5E;CJK COMPATIBILITY IDEOGRAPH-FA5E;Lo;0;L;8279;;;;N;;;;;
+FA5F;CJK COMPATIBILITY IDEOGRAPH-FA5F;Lo;0;L;8457;;;;N;;;;;
+FA60;CJK COMPATIBILITY IDEOGRAPH-FA60;Lo;0;L;8910;;;;N;;;;;
+FA61;CJK COMPATIBILITY IDEOGRAPH-FA61;Lo;0;L;8996;;;;N;;;;;
+FA62;CJK COMPATIBILITY IDEOGRAPH-FA62;Lo;0;L;8B01;;;;N;;;;;
+FA63;CJK COMPATIBILITY IDEOGRAPH-FA63;Lo;0;L;8B39;;;;N;;;;;
+FA64;CJK COMPATIBILITY IDEOGRAPH-FA64;Lo;0;L;8CD3;;;;N;;;;;
+FA65;CJK COMPATIBILITY IDEOGRAPH-FA65;Lo;0;L;8D08;;;;N;;;;;
+FA66;CJK COMPATIBILITY IDEOGRAPH-FA66;Lo;0;L;8FB6;;;;N;;;;;
+FA67;CJK COMPATIBILITY IDEOGRAPH-FA67;Lo;0;L;9038;;;;N;;;;;
+FA68;CJK COMPATIBILITY IDEOGRAPH-FA68;Lo;0;L;96E3;;;;N;;;;;
+FA69;CJK COMPATIBILITY IDEOGRAPH-FA69;Lo;0;L;97FF;;;;N;;;;;
+FA6A;CJK COMPATIBILITY IDEOGRAPH-FA6A;Lo;0;L;983B;;;;N;;;;;
+FA6B;CJK COMPATIBILITY IDEOGRAPH-FA6B;Lo;0;L;6075;;;;N;;;;;
+FA6C;CJK COMPATIBILITY IDEOGRAPH-FA6C;Lo;0;L;242EE;;;;N;;;;;
+FA6D;CJK COMPATIBILITY IDEOGRAPH-FA6D;Lo;0;L;8218;;;;N;;;;;
+FA70;CJK COMPATIBILITY IDEOGRAPH-FA70;Lo;0;L;4E26;;;;N;;;;;
+FA71;CJK COMPATIBILITY IDEOGRAPH-FA71;Lo;0;L;51B5;;;;N;;;;;
+FA72;CJK COMPATIBILITY IDEOGRAPH-FA72;Lo;0;L;5168;;;;N;;;;;
+FA73;CJK COMPATIBILITY IDEOGRAPH-FA73;Lo;0;L;4F80;;;;N;;;;;
+FA74;CJK COMPATIBILITY IDEOGRAPH-FA74;Lo;0;L;5145;;;;N;;;;;
+FA75;CJK COMPATIBILITY IDEOGRAPH-FA75;Lo;0;L;5180;;;;N;;;;;
+FA76;CJK COMPATIBILITY IDEOGRAPH-FA76;Lo;0;L;52C7;;;;N;;;;;
+FA77;CJK COMPATIBILITY IDEOGRAPH-FA77;Lo;0;L;52FA;;;;N;;;;;
+FA78;CJK COMPATIBILITY IDEOGRAPH-FA78;Lo;0;L;559D;;;;N;;;;;
+FA79;CJK COMPATIBILITY IDEOGRAPH-FA79;Lo;0;L;5555;;;;N;;;;;
+FA7A;CJK COMPATIBILITY IDEOGRAPH-FA7A;Lo;0;L;5599;;;;N;;;;;
+FA7B;CJK COMPATIBILITY IDEOGRAPH-FA7B;Lo;0;L;55E2;;;;N;;;;;
+FA7C;CJK COMPATIBILITY IDEOGRAPH-FA7C;Lo;0;L;585A;;;;N;;;;;
+FA7D;CJK COMPATIBILITY IDEOGRAPH-FA7D;Lo;0;L;58B3;;;;N;;;;;
+FA7E;CJK COMPATIBILITY IDEOGRAPH-FA7E;Lo;0;L;5944;;;;N;;;;;
+FA7F;CJK COMPATIBILITY IDEOGRAPH-FA7F;Lo;0;L;5954;;;;N;;;;;
+FA80;CJK COMPATIBILITY IDEOGRAPH-FA80;Lo;0;L;5A62;;;;N;;;;;
+FA81;CJK COMPATIBILITY IDEOGRAPH-FA81;Lo;0;L;5B28;;;;N;;;;;
+FA82;CJK COMPATIBILITY IDEOGRAPH-FA82;Lo;0;L;5ED2;;;;N;;;;;
+FA83;CJK COMPATIBILITY IDEOGRAPH-FA83;Lo;0;L;5ED9;;;;N;;;;;
+FA84;CJK COMPATIBILITY IDEOGRAPH-FA84;Lo;0;L;5F69;;;;N;;;;;
+FA85;CJK COMPATIBILITY IDEOGRAPH-FA85;Lo;0;L;5FAD;;;;N;;;;;
+FA86;CJK COMPATIBILITY IDEOGRAPH-FA86;Lo;0;L;60D8;;;;N;;;;;
+FA87;CJK COMPATIBILITY IDEOGRAPH-FA87;Lo;0;L;614E;;;;N;;;;;
+FA88;CJK COMPATIBILITY IDEOGRAPH-FA88;Lo;0;L;6108;;;;N;;;;;
+FA89;CJK COMPATIBILITY IDEOGRAPH-FA89;Lo;0;L;618E;;;;N;;;;;
+FA8A;CJK COMPATIBILITY IDEOGRAPH-FA8A;Lo;0;L;6160;;;;N;;;;;
+FA8B;CJK COMPATIBILITY IDEOGRAPH-FA8B;Lo;0;L;61F2;;;;N;;;;;
+FA8C;CJK COMPATIBILITY IDEOGRAPH-FA8C;Lo;0;L;6234;;;;N;;;;;
+FA8D;CJK COMPATIBILITY IDEOGRAPH-FA8D;Lo;0;L;63C4;;;;N;;;;;
+FA8E;CJK COMPATIBILITY IDEOGRAPH-FA8E;Lo;0;L;641C;;;;N;;;;;
+FA8F;CJK COMPATIBILITY IDEOGRAPH-FA8F;Lo;0;L;6452;;;;N;;;;;
+FA90;CJK COMPATIBILITY IDEOGRAPH-FA90;Lo;0;L;6556;;;;N;;;;;
+FA91;CJK COMPATIBILITY IDEOGRAPH-FA91;Lo;0;L;6674;;;;N;;;;;
+FA92;CJK COMPATIBILITY IDEOGRAPH-FA92;Lo;0;L;6717;;;;N;;;;;
+FA93;CJK COMPATIBILITY IDEOGRAPH-FA93;Lo;0;L;671B;;;;N;;;;;
+FA94;CJK COMPATIBILITY IDEOGRAPH-FA94;Lo;0;L;6756;;;;N;;;;;
+FA95;CJK COMPATIBILITY IDEOGRAPH-FA95;Lo;0;L;6B79;;;;N;;;;;
+FA96;CJK COMPATIBILITY IDEOGRAPH-FA96;Lo;0;L;6BBA;;;;N;;;;;
+FA97;CJK COMPATIBILITY IDEOGRAPH-FA97;Lo;0;L;6D41;;;;N;;;;;
+FA98;CJK COMPATIBILITY IDEOGRAPH-FA98;Lo;0;L;6EDB;;;;N;;;;;
+FA99;CJK COMPATIBILITY IDEOGRAPH-FA99;Lo;0;L;6ECB;;;;N;;;;;
+FA9A;CJK COMPATIBILITY IDEOGRAPH-FA9A;Lo;0;L;6F22;;;;N;;;;;
+FA9B;CJK COMPATIBILITY IDEOGRAPH-FA9B;Lo;0;L;701E;;;;N;;;;;
+FA9C;CJK COMPATIBILITY IDEOGRAPH-FA9C;Lo;0;L;716E;;;;N;;;;;
+FA9D;CJK COMPATIBILITY IDEOGRAPH-FA9D;Lo;0;L;77A7;;;;N;;;;;
+FA9E;CJK COMPATIBILITY IDEOGRAPH-FA9E;Lo;0;L;7235;;;;N;;;;;
+FA9F;CJK COMPATIBILITY IDEOGRAPH-FA9F;Lo;0;L;72AF;;;;N;;;;;
+FAA0;CJK COMPATIBILITY IDEOGRAPH-FAA0;Lo;0;L;732A;;;;N;;;;;
+FAA1;CJK COMPATIBILITY IDEOGRAPH-FAA1;Lo;0;L;7471;;;;N;;;;;
+FAA2;CJK COMPATIBILITY IDEOGRAPH-FAA2;Lo;0;L;7506;;;;N;;;;;
+FAA3;CJK COMPATIBILITY IDEOGRAPH-FAA3;Lo;0;L;753B;;;;N;;;;;
+FAA4;CJK COMPATIBILITY IDEOGRAPH-FAA4;Lo;0;L;761D;;;;N;;;;;
+FAA5;CJK COMPATIBILITY IDEOGRAPH-FAA5;Lo;0;L;761F;;;;N;;;;;
+FAA6;CJK COMPATIBILITY IDEOGRAPH-FAA6;Lo;0;L;76CA;;;;N;;;;;
+FAA7;CJK COMPATIBILITY IDEOGRAPH-FAA7;Lo;0;L;76DB;;;;N;;;;;
+FAA8;CJK COMPATIBILITY IDEOGRAPH-FAA8;Lo;0;L;76F4;;;;N;;;;;
+FAA9;CJK COMPATIBILITY IDEOGRAPH-FAA9;Lo;0;L;774A;;;;N;;;;;
+FAAA;CJK COMPATIBILITY IDEOGRAPH-FAAA;Lo;0;L;7740;;;;N;;;;;
+FAAB;CJK COMPATIBILITY IDEOGRAPH-FAAB;Lo;0;L;78CC;;;;N;;;;;
+FAAC;CJK COMPATIBILITY IDEOGRAPH-FAAC;Lo;0;L;7AB1;;;;N;;;;;
+FAAD;CJK COMPATIBILITY IDEOGRAPH-FAAD;Lo;0;L;7BC0;;;;N;;;;;
+FAAE;CJK COMPATIBILITY IDEOGRAPH-FAAE;Lo;0;L;7C7B;;;;N;;;;;
+FAAF;CJK COMPATIBILITY IDEOGRAPH-FAAF;Lo;0;L;7D5B;;;;N;;;;;
+FAB0;CJK COMPATIBILITY IDEOGRAPH-FAB0;Lo;0;L;7DF4;;;;N;;;;;
+FAB1;CJK COMPATIBILITY IDEOGRAPH-FAB1;Lo;0;L;7F3E;;;;N;;;;;
+FAB2;CJK COMPATIBILITY IDEOGRAPH-FAB2;Lo;0;L;8005;;;;N;;;;;
+FAB3;CJK COMPATIBILITY IDEOGRAPH-FAB3;Lo;0;L;8352;;;;N;;;;;
+FAB4;CJK COMPATIBILITY IDEOGRAPH-FAB4;Lo;0;L;83EF;;;;N;;;;;
+FAB5;CJK COMPATIBILITY IDEOGRAPH-FAB5;Lo;0;L;8779;;;;N;;;;;
+FAB6;CJK COMPATIBILITY IDEOGRAPH-FAB6;Lo;0;L;8941;;;;N;;;;;
+FAB7;CJK COMPATIBILITY IDEOGRAPH-FAB7;Lo;0;L;8986;;;;N;;;;;
+FAB8;CJK COMPATIBILITY IDEOGRAPH-FAB8;Lo;0;L;8996;;;;N;;;;;
+FAB9;CJK COMPATIBILITY IDEOGRAPH-FAB9;Lo;0;L;8ABF;;;;N;;;;;
+FABA;CJK COMPATIBILITY IDEOGRAPH-FABA;Lo;0;L;8AF8;;;;N;;;;;
+FABB;CJK COMPATIBILITY IDEOGRAPH-FABB;Lo;0;L;8ACB;;;;N;;;;;
+FABC;CJK COMPATIBILITY IDEOGRAPH-FABC;Lo;0;L;8B01;;;;N;;;;;
+FABD;CJK COMPATIBILITY IDEOGRAPH-FABD;Lo;0;L;8AFE;;;;N;;;;;
+FABE;CJK COMPATIBILITY IDEOGRAPH-FABE;Lo;0;L;8AED;;;;N;;;;;
+FABF;CJK COMPATIBILITY IDEOGRAPH-FABF;Lo;0;L;8B39;;;;N;;;;;
+FAC0;CJK COMPATIBILITY IDEOGRAPH-FAC0;Lo;0;L;8B8A;;;;N;;;;;
+FAC1;CJK COMPATIBILITY IDEOGRAPH-FAC1;Lo;0;L;8D08;;;;N;;;;;
+FAC2;CJK COMPATIBILITY IDEOGRAPH-FAC2;Lo;0;L;8F38;;;;N;;;;;
+FAC3;CJK COMPATIBILITY IDEOGRAPH-FAC3;Lo;0;L;9072;;;;N;;;;;
+FAC4;CJK COMPATIBILITY IDEOGRAPH-FAC4;Lo;0;L;9199;;;;N;;;;;
+FAC5;CJK COMPATIBILITY IDEOGRAPH-FAC5;Lo;0;L;9276;;;;N;;;;;
+FAC6;CJK COMPATIBILITY IDEOGRAPH-FAC6;Lo;0;L;967C;;;;N;;;;;
+FAC7;CJK COMPATIBILITY IDEOGRAPH-FAC7;Lo;0;L;96E3;;;;N;;;;;
+FAC8;CJK COMPATIBILITY IDEOGRAPH-FAC8;Lo;0;L;9756;;;;N;;;;;
+FAC9;CJK COMPATIBILITY IDEOGRAPH-FAC9;Lo;0;L;97DB;;;;N;;;;;
+FACA;CJK COMPATIBILITY IDEOGRAPH-FACA;Lo;0;L;97FF;;;;N;;;;;
+FACB;CJK COMPATIBILITY IDEOGRAPH-FACB;Lo;0;L;980B;;;;N;;;;;
+FACC;CJK COMPATIBILITY IDEOGRAPH-FACC;Lo;0;L;983B;;;;N;;;;;
+FACD;CJK COMPATIBILITY IDEOGRAPH-FACD;Lo;0;L;9B12;;;;N;;;;;
+FACE;CJK COMPATIBILITY IDEOGRAPH-FACE;Lo;0;L;9F9C;;;;N;;;;;
+FACF;CJK COMPATIBILITY IDEOGRAPH-FACF;Lo;0;L;2284A;;;;N;;;;;
+FAD0;CJK COMPATIBILITY IDEOGRAPH-FAD0;Lo;0;L;22844;;;;N;;;;;
+FAD1;CJK COMPATIBILITY IDEOGRAPH-FAD1;Lo;0;L;233D5;;;;N;;;;;
+FAD2;CJK COMPATIBILITY IDEOGRAPH-FAD2;Lo;0;L;3B9D;;;;N;;;;;
+FAD3;CJK COMPATIBILITY IDEOGRAPH-FAD3;Lo;0;L;4018;;;;N;;;;;
+FAD4;CJK COMPATIBILITY IDEOGRAPH-FAD4;Lo;0;L;4039;;;;N;;;;;
+FAD5;CJK COMPATIBILITY IDEOGRAPH-FAD5;Lo;0;L;25249;;;;N;;;;;
+FAD6;CJK COMPATIBILITY IDEOGRAPH-FAD6;Lo;0;L;25CD0;;;;N;;;;;
+FAD7;CJK COMPATIBILITY IDEOGRAPH-FAD7;Lo;0;L;27ED3;;;;N;;;;;
+FAD8;CJK COMPATIBILITY IDEOGRAPH-FAD8;Lo;0;L;9F43;;;;N;;;;;
+FAD9;CJK COMPATIBILITY IDEOGRAPH-FAD9;Lo;0;L;9F8E;;;;N;;;;;
+FB00;LATIN SMALL LIGATURE FF;Ll;0;L;<compat> 0066 0066;;;;N;;;;;
+FB01;LATIN SMALL LIGATURE FI;Ll;0;L;<compat> 0066 0069;;;;N;;;;;
+FB02;LATIN SMALL LIGATURE FL;Ll;0;L;<compat> 0066 006C;;;;N;;;;;
+FB03;LATIN SMALL LIGATURE FFI;Ll;0;L;<compat> 0066 0066 0069;;;;N;;;;;
+FB04;LATIN SMALL LIGATURE FFL;Ll;0;L;<compat> 0066 0066 006C;;;;N;;;;;
+FB05;LATIN SMALL LIGATURE LONG S T;Ll;0;L;<compat> 017F 0074;;;;N;;;;;
+FB06;LATIN SMALL LIGATURE ST;Ll;0;L;<compat> 0073 0074;;;;N;;;;;
+FB13;ARMENIAN SMALL LIGATURE MEN NOW;Ll;0;L;<compat> 0574 0576;;;;N;;;;;
+FB14;ARMENIAN SMALL LIGATURE MEN ECH;Ll;0;L;<compat> 0574 0565;;;;N;;;;;
+FB15;ARMENIAN SMALL LIGATURE MEN INI;Ll;0;L;<compat> 0574 056B;;;;N;;;;;
+FB16;ARMENIAN SMALL LIGATURE VEW NOW;Ll;0;L;<compat> 057E 0576;;;;N;;;;;
+FB17;ARMENIAN SMALL LIGATURE MEN XEH;Ll;0;L;<compat> 0574 056D;;;;N;;;;;
+FB1D;HEBREW LETTER YOD WITH HIRIQ;Lo;0;R;05D9 05B4;;;;N;;;;;
+FB1E;HEBREW POINT JUDEO-SPANISH VARIKA;Mn;26;NSM;;;;;N;HEBREW POINT VARIKA;;;;
+FB1F;HEBREW LIGATURE YIDDISH YOD YOD PATAH;Lo;0;R;05F2 05B7;;;;N;;;;;
+FB20;HEBREW LETTER ALTERNATIVE AYIN;Lo;0;R;<font> 05E2;;;;N;;;;;
+FB21;HEBREW LETTER WIDE ALEF;Lo;0;R;<font> 05D0;;;;N;;;;;
+FB22;HEBREW LETTER WIDE DALET;Lo;0;R;<font> 05D3;;;;N;;;;;
+FB23;HEBREW LETTER WIDE HE;Lo;0;R;<font> 05D4;;;;N;;;;;
+FB24;HEBREW LETTER WIDE KAF;Lo;0;R;<font> 05DB;;;;N;;;;;
+FB25;HEBREW LETTER WIDE LAMED;Lo;0;R;<font> 05DC;;;;N;;;;;
+FB26;HEBREW LETTER WIDE FINAL MEM;Lo;0;R;<font> 05DD;;;;N;;;;;
+FB27;HEBREW LETTER WIDE RESH;Lo;0;R;<font> 05E8;;;;N;;;;;
+FB28;HEBREW LETTER WIDE TAV;Lo;0;R;<font> 05EA;;;;N;;;;;
+FB29;HEBREW LETTER ALTERNATIVE PLUS SIGN;Sm;0;ES;<font> 002B;;;;N;;;;;
+FB2A;HEBREW LETTER SHIN WITH SHIN DOT;Lo;0;R;05E9 05C1;;;;N;;;;;
+FB2B;HEBREW LETTER SHIN WITH SIN DOT;Lo;0;R;05E9 05C2;;;;N;;;;;
+FB2C;HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT;Lo;0;R;FB49 05C1;;;;N;;;;;
+FB2D;HEBREW LETTER SHIN WITH DAGESH AND SIN DOT;Lo;0;R;FB49 05C2;;;;N;;;;;
+FB2E;HEBREW LETTER ALEF WITH PATAH;Lo;0;R;05D0 05B7;;;;N;;;;;
+FB2F;HEBREW LETTER ALEF WITH QAMATS;Lo;0;R;05D0 05B8;;;;N;;;;;
+FB30;HEBREW LETTER ALEF WITH MAPIQ;Lo;0;R;05D0 05BC;;;;N;;;;;
+FB31;HEBREW LETTER BET WITH DAGESH;Lo;0;R;05D1 05BC;;;;N;;;;;
+FB32;HEBREW LETTER GIMEL WITH DAGESH;Lo;0;R;05D2 05BC;;;;N;;;;;
+FB33;HEBREW LETTER DALET WITH DAGESH;Lo;0;R;05D3 05BC;;;;N;;;;;
+FB34;HEBREW LETTER HE WITH MAPIQ;Lo;0;R;05D4 05BC;;;;N;;;;;
+FB35;HEBREW LETTER VAV WITH DAGESH;Lo;0;R;05D5 05BC;;;;N;;;;;
+FB36;HEBREW LETTER ZAYIN WITH DAGESH;Lo;0;R;05D6 05BC;;;;N;;;;;
+FB38;HEBREW LETTER TET WITH DAGESH;Lo;0;R;05D8 05BC;;;;N;;;;;
+FB39;HEBREW LETTER YOD WITH DAGESH;Lo;0;R;05D9 05BC;;;;N;;;;;
+FB3A;HEBREW LETTER FINAL KAF WITH DAGESH;Lo;0;R;05DA 05BC;;;;N;;;;;
+FB3B;HEBREW LETTER KAF WITH DAGESH;Lo;0;R;05DB 05BC;;;;N;;;;;
+FB3C;HEBREW LETTER LAMED WITH DAGESH;Lo;0;R;05DC 05BC;;;;N;;;;;
+FB3E;HEBREW LETTER MEM WITH DAGESH;Lo;0;R;05DE 05BC;;;;N;;;;;
+FB40;HEBREW LETTER NUN WITH DAGESH;Lo;0;R;05E0 05BC;;;;N;;;;;
+FB41;HEBREW LETTER SAMEKH WITH DAGESH;Lo;0;R;05E1 05BC;;;;N;;;;;
+FB43;HEBREW LETTER FINAL PE WITH DAGESH;Lo;0;R;05E3 05BC;;;;N;;;;;
+FB44;HEBREW LETTER PE WITH DAGESH;Lo;0;R;05E4 05BC;;;;N;;;;;
+FB46;HEBREW LETTER TSADI WITH DAGESH;Lo;0;R;05E6 05BC;;;;N;;;;;
+FB47;HEBREW LETTER QOF WITH DAGESH;Lo;0;R;05E7 05BC;;;;N;;;;;
+FB48;HEBREW LETTER RESH WITH DAGESH;Lo;0;R;05E8 05BC;;;;N;;;;;
+FB49;HEBREW LETTER SHIN WITH DAGESH;Lo;0;R;05E9 05BC;;;;N;;;;;
+FB4A;HEBREW LETTER TAV WITH DAGESH;Lo;0;R;05EA 05BC;;;;N;;;;;
+FB4B;HEBREW LETTER VAV WITH HOLAM;Lo;0;R;05D5 05B9;;;;N;;;;;
+FB4C;HEBREW LETTER BET WITH RAFE;Lo;0;R;05D1 05BF;;;;N;;;;;
+FB4D;HEBREW LETTER KAF WITH RAFE;Lo;0;R;05DB 05BF;;;;N;;;;;
+FB4E;HEBREW LETTER PE WITH RAFE;Lo;0;R;05E4 05BF;;;;N;;;;;
+FB4F;HEBREW LIGATURE ALEF LAMED;Lo;0;R;<compat> 05D0 05DC;;;;N;;;;;
+FB50;ARABIC LETTER ALEF WASLA ISOLATED FORM;Lo;0;AL;<isolated> 0671;;;;N;;;;;
+FB51;ARABIC LETTER ALEF WASLA FINAL FORM;Lo;0;AL;<final> 0671;;;;N;;;;;
+FB52;ARABIC LETTER BEEH ISOLATED FORM;Lo;0;AL;<isolated> 067B;;;;N;;;;;
+FB53;ARABIC LETTER BEEH FINAL FORM;Lo;0;AL;<final> 067B;;;;N;;;;;
+FB54;ARABIC LETTER BEEH INITIAL FORM;Lo;0;AL;<initial> 067B;;;;N;;;;;
+FB55;ARABIC LETTER BEEH MEDIAL FORM;Lo;0;AL;<medial> 067B;;;;N;;;;;
+FB56;ARABIC LETTER PEH ISOLATED FORM;Lo;0;AL;<isolated> 067E;;;;N;;;;;
+FB57;ARABIC LETTER PEH FINAL FORM;Lo;0;AL;<final> 067E;;;;N;;;;;
+FB58;ARABIC LETTER PEH INITIAL FORM;Lo;0;AL;<initial> 067E;;;;N;;;;;
+FB59;ARABIC LETTER PEH MEDIAL FORM;Lo;0;AL;<medial> 067E;;;;N;;;;;
+FB5A;ARABIC LETTER BEHEH ISOLATED FORM;Lo;0;AL;<isolated> 0680;;;;N;;;;;
+FB5B;ARABIC LETTER BEHEH FINAL FORM;Lo;0;AL;<final> 0680;;;;N;;;;;
+FB5C;ARABIC LETTER BEHEH INITIAL FORM;Lo;0;AL;<initial> 0680;;;;N;;;;;
+FB5D;ARABIC LETTER BEHEH MEDIAL FORM;Lo;0;AL;<medial> 0680;;;;N;;;;;
+FB5E;ARABIC LETTER TTEHEH ISOLATED FORM;Lo;0;AL;<isolated> 067A;;;;N;;;;;
+FB5F;ARABIC LETTER TTEHEH FINAL FORM;Lo;0;AL;<final> 067A;;;;N;;;;;
+FB60;ARABIC LETTER TTEHEH INITIAL FORM;Lo;0;AL;<initial> 067A;;;;N;;;;;
+FB61;ARABIC LETTER TTEHEH MEDIAL FORM;Lo;0;AL;<medial> 067A;;;;N;;;;;
+FB62;ARABIC LETTER TEHEH ISOLATED FORM;Lo;0;AL;<isolated> 067F;;;;N;;;;;
+FB63;ARABIC LETTER TEHEH FINAL FORM;Lo;0;AL;<final> 067F;;;;N;;;;;
+FB64;ARABIC LETTER TEHEH INITIAL FORM;Lo;0;AL;<initial> 067F;;;;N;;;;;
+FB65;ARABIC LETTER TEHEH MEDIAL FORM;Lo;0;AL;<medial> 067F;;;;N;;;;;
+FB66;ARABIC LETTER TTEH ISOLATED FORM;Lo;0;AL;<isolated> 0679;;;;N;;;;;
+FB67;ARABIC LETTER TTEH FINAL FORM;Lo;0;AL;<final> 0679;;;;N;;;;;
+FB68;ARABIC LETTER TTEH INITIAL FORM;Lo;0;AL;<initial> 0679;;;;N;;;;;
+FB69;ARABIC LETTER TTEH MEDIAL FORM;Lo;0;AL;<medial> 0679;;;;N;;;;;
+FB6A;ARABIC LETTER VEH ISOLATED FORM;Lo;0;AL;<isolated> 06A4;;;;N;;;;;
+FB6B;ARABIC LETTER VEH FINAL FORM;Lo;0;AL;<final> 06A4;;;;N;;;;;
+FB6C;ARABIC LETTER VEH INITIAL FORM;Lo;0;AL;<initial> 06A4;;;;N;;;;;
+FB6D;ARABIC LETTER VEH MEDIAL FORM;Lo;0;AL;<medial> 06A4;;;;N;;;;;
+FB6E;ARABIC LETTER PEHEH ISOLATED FORM;Lo;0;AL;<isolated> 06A6;;;;N;;;;;
+FB6F;ARABIC LETTER PEHEH FINAL FORM;Lo;0;AL;<final> 06A6;;;;N;;;;;
+FB70;ARABIC LETTER PEHEH INITIAL FORM;Lo;0;AL;<initial> 06A6;;;;N;;;;;
+FB71;ARABIC LETTER PEHEH MEDIAL FORM;Lo;0;AL;<medial> 06A6;;;;N;;;;;
+FB72;ARABIC LETTER DYEH ISOLATED FORM;Lo;0;AL;<isolated> 0684;;;;N;;;;;
+FB73;ARABIC LETTER DYEH FINAL FORM;Lo;0;AL;<final> 0684;;;;N;;;;;
+FB74;ARABIC LETTER DYEH INITIAL FORM;Lo;0;AL;<initial> 0684;;;;N;;;;;
+FB75;ARABIC LETTER DYEH MEDIAL FORM;Lo;0;AL;<medial> 0684;;;;N;;;;;
+FB76;ARABIC LETTER NYEH ISOLATED FORM;Lo;0;AL;<isolated> 0683;;;;N;;;;;
+FB77;ARABIC LETTER NYEH FINAL FORM;Lo;0;AL;<final> 0683;;;;N;;;;;
+FB78;ARABIC LETTER NYEH INITIAL FORM;Lo;0;AL;<initial> 0683;;;;N;;;;;
+FB79;ARABIC LETTER NYEH MEDIAL FORM;Lo;0;AL;<medial> 0683;;;;N;;;;;
+FB7A;ARABIC LETTER TCHEH ISOLATED FORM;Lo;0;AL;<isolated> 0686;;;;N;;;;;
+FB7B;ARABIC LETTER TCHEH FINAL FORM;Lo;0;AL;<final> 0686;;;;N;;;;;
+FB7C;ARABIC LETTER TCHEH INITIAL FORM;Lo;0;AL;<initial> 0686;;;;N;;;;;
+FB7D;ARABIC LETTER TCHEH MEDIAL FORM;Lo;0;AL;<medial> 0686;;;;N;;;;;
+FB7E;ARABIC LETTER TCHEHEH ISOLATED FORM;Lo;0;AL;<isolated> 0687;;;;N;;;;;
+FB7F;ARABIC LETTER TCHEHEH FINAL FORM;Lo;0;AL;<final> 0687;;;;N;;;;;
+FB80;ARABIC LETTER TCHEHEH INITIAL FORM;Lo;0;AL;<initial> 0687;;;;N;;;;;
+FB81;ARABIC LETTER TCHEHEH MEDIAL FORM;Lo;0;AL;<medial> 0687;;;;N;;;;;
+FB82;ARABIC LETTER DDAHAL ISOLATED FORM;Lo;0;AL;<isolated> 068D;;;;N;;;;;
+FB83;ARABIC LETTER DDAHAL FINAL FORM;Lo;0;AL;<final> 068D;;;;N;;;;;
+FB84;ARABIC LETTER DAHAL ISOLATED FORM;Lo;0;AL;<isolated> 068C;;;;N;;;;;
+FB85;ARABIC LETTER DAHAL FINAL FORM;Lo;0;AL;<final> 068C;;;;N;;;;;
+FB86;ARABIC LETTER DUL ISOLATED FORM;Lo;0;AL;<isolated> 068E;;;;N;;;;;
+FB87;ARABIC LETTER DUL FINAL FORM;Lo;0;AL;<final> 068E;;;;N;;;;;
+FB88;ARABIC LETTER DDAL ISOLATED FORM;Lo;0;AL;<isolated> 0688;;;;N;;;;;
+FB89;ARABIC LETTER DDAL FINAL FORM;Lo;0;AL;<final> 0688;;;;N;;;;;
+FB8A;ARABIC LETTER JEH ISOLATED FORM;Lo;0;AL;<isolated> 0698;;;;N;;;;;
+FB8B;ARABIC LETTER JEH FINAL FORM;Lo;0;AL;<final> 0698;;;;N;;;;;
+FB8C;ARABIC LETTER RREH ISOLATED FORM;Lo;0;AL;<isolated> 0691;;;;N;;;;;
+FB8D;ARABIC LETTER RREH FINAL FORM;Lo;0;AL;<final> 0691;;;;N;;;;;
+FB8E;ARABIC LETTER KEHEH ISOLATED FORM;Lo;0;AL;<isolated> 06A9;;;;N;;;;;
+FB8F;ARABIC LETTER KEHEH FINAL FORM;Lo;0;AL;<final> 06A9;;;;N;;;;;
+FB90;ARABIC LETTER KEHEH INITIAL FORM;Lo;0;AL;<initial> 06A9;;;;N;;;;;
+FB91;ARABIC LETTER KEHEH MEDIAL FORM;Lo;0;AL;<medial> 06A9;;;;N;;;;;
+FB92;ARABIC LETTER GAF ISOLATED FORM;Lo;0;AL;<isolated> 06AF;;;;N;;;;;
+FB93;ARABIC LETTER GAF FINAL FORM;Lo;0;AL;<final> 06AF;;;;N;;;;;
+FB94;ARABIC LETTER GAF INITIAL FORM;Lo;0;AL;<initial> 06AF;;;;N;;;;;
+FB95;ARABIC LETTER GAF MEDIAL FORM;Lo;0;AL;<medial> 06AF;;;;N;;;;;
+FB96;ARABIC LETTER GUEH ISOLATED FORM;Lo;0;AL;<isolated> 06B3;;;;N;;;;;
+FB97;ARABIC LETTER GUEH FINAL FORM;Lo;0;AL;<final> 06B3;;;;N;;;;;
+FB98;ARABIC LETTER GUEH INITIAL FORM;Lo;0;AL;<initial> 06B3;;;;N;;;;;
+FB99;ARABIC LETTER GUEH MEDIAL FORM;Lo;0;AL;<medial> 06B3;;;;N;;;;;
+FB9A;ARABIC LETTER NGOEH ISOLATED FORM;Lo;0;AL;<isolated> 06B1;;;;N;;;;;
+FB9B;ARABIC LETTER NGOEH FINAL FORM;Lo;0;AL;<final> 06B1;;;;N;;;;;
+FB9C;ARABIC LETTER NGOEH INITIAL FORM;Lo;0;AL;<initial> 06B1;;;;N;;;;;
+FB9D;ARABIC LETTER NGOEH MEDIAL FORM;Lo;0;AL;<medial> 06B1;;;;N;;;;;
+FB9E;ARABIC LETTER NOON GHUNNA ISOLATED FORM;Lo;0;AL;<isolated> 06BA;;;;N;;;;;
+FB9F;ARABIC LETTER NOON GHUNNA FINAL FORM;Lo;0;AL;<final> 06BA;;;;N;;;;;
+FBA0;ARABIC LETTER RNOON ISOLATED FORM;Lo;0;AL;<isolated> 06BB;;;;N;;;;;
+FBA1;ARABIC LETTER RNOON FINAL FORM;Lo;0;AL;<final> 06BB;;;;N;;;;;
+FBA2;ARABIC LETTER RNOON INITIAL FORM;Lo;0;AL;<initial> 06BB;;;;N;;;;;
+FBA3;ARABIC LETTER RNOON MEDIAL FORM;Lo;0;AL;<medial> 06BB;;;;N;;;;;
+FBA4;ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 06C0;;;;N;;;;;
+FBA5;ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM;Lo;0;AL;<final> 06C0;;;;N;;;;;
+FBA6;ARABIC LETTER HEH GOAL ISOLATED FORM;Lo;0;AL;<isolated> 06C1;;;;N;;;;;
+FBA7;ARABIC LETTER HEH GOAL FINAL FORM;Lo;0;AL;<final> 06C1;;;;N;;;;;
+FBA8;ARABIC LETTER HEH GOAL INITIAL FORM;Lo;0;AL;<initial> 06C1;;;;N;;;;;
+FBA9;ARABIC LETTER HEH GOAL MEDIAL FORM;Lo;0;AL;<medial> 06C1;;;;N;;;;;
+FBAA;ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM;Lo;0;AL;<isolated> 06BE;;;;N;;;;;
+FBAB;ARABIC LETTER HEH DOACHASHMEE FINAL FORM;Lo;0;AL;<final> 06BE;;;;N;;;;;
+FBAC;ARABIC LETTER HEH DOACHASHMEE INITIAL FORM;Lo;0;AL;<initial> 06BE;;;;N;;;;;
+FBAD;ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM;Lo;0;AL;<medial> 06BE;;;;N;;;;;
+FBAE;ARABIC LETTER YEH BARREE ISOLATED FORM;Lo;0;AL;<isolated> 06D2;;;;N;;;;;
+FBAF;ARABIC LETTER YEH BARREE FINAL FORM;Lo;0;AL;<final> 06D2;;;;N;;;;;
+FBB0;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 06D3;;;;N;;;;;
+FBB1;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 06D3;;;;N;;;;;
+FBB2;ARABIC SYMBOL DOT ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB3;ARABIC SYMBOL DOT BELOW;Sk;0;AL;;;;;N;;;;;
+FBB4;ARABIC SYMBOL TWO DOTS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB5;ARABIC SYMBOL TWO DOTS BELOW;Sk;0;AL;;;;;N;;;;;
+FBB6;ARABIC SYMBOL THREE DOTS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB7;ARABIC SYMBOL THREE DOTS BELOW;Sk;0;AL;;;;;N;;;;;
+FBB8;ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBB9;ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS BELOW;Sk;0;AL;;;;;N;;;;;
+FBBA;ARABIC SYMBOL FOUR DOTS ABOVE;Sk;0;AL;;;;;N;;;;;
+FBBB;ARABIC SYMBOL FOUR DOTS BELOW;Sk;0;AL;;;;;N;;;;;
+FBBC;ARABIC SYMBOL DOUBLE VERTICAL BAR BELOW;Sk;0;AL;;;;;N;;;;;
+FBBD;ARABIC SYMBOL TWO DOTS VERTICALLY ABOVE;Sk;0;AL;;;;;N;;;;;
+FBBE;ARABIC SYMBOL TWO DOTS VERTICALLY BELOW;Sk;0;AL;;;;;N;;;;;
+FBBF;ARABIC SYMBOL RING;Sk;0;AL;;;;;N;;;;;
+FBC0;ARABIC SYMBOL SMALL TAH ABOVE;Sk;0;AL;;;;;N;;;;;
+FBC1;ARABIC SYMBOL SMALL TAH BELOW;Sk;0;AL;;;;;N;;;;;
+FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL;<isolated> 06AD;;;;N;;;;;
+FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL;<final> 06AD;;;;N;;;;;
+FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL;<initial> 06AD;;;;N;;;;;
+FBD6;ARABIC LETTER NG MEDIAL FORM;Lo;0;AL;<medial> 06AD;;;;N;;;;;
+FBD7;ARABIC LETTER U ISOLATED FORM;Lo;0;AL;<isolated> 06C7;;;;N;;;;;
+FBD8;ARABIC LETTER U FINAL FORM;Lo;0;AL;<final> 06C7;;;;N;;;;;
+FBD9;ARABIC LETTER OE ISOLATED FORM;Lo;0;AL;<isolated> 06C6;;;;N;;;;;
+FBDA;ARABIC LETTER OE FINAL FORM;Lo;0;AL;<final> 06C6;;;;N;;;;;
+FBDB;ARABIC LETTER YU ISOLATED FORM;Lo;0;AL;<isolated> 06C8;;;;N;;;;;
+FBDC;ARABIC LETTER YU FINAL FORM;Lo;0;AL;<final> 06C8;;;;N;;;;;
+FBDD;ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0677;;;;N;;;;;
+FBDE;ARABIC LETTER VE ISOLATED FORM;Lo;0;AL;<isolated> 06CB;;;;N;;;;;
+FBDF;ARABIC LETTER VE FINAL FORM;Lo;0;AL;<final> 06CB;;;;N;;;;;
+FBE0;ARABIC LETTER KIRGHIZ OE ISOLATED FORM;Lo;0;AL;<isolated> 06C5;;;;N;;;;;
+FBE1;ARABIC LETTER KIRGHIZ OE FINAL FORM;Lo;0;AL;<final> 06C5;;;;N;;;;;
+FBE2;ARABIC LETTER KIRGHIZ YU ISOLATED FORM;Lo;0;AL;<isolated> 06C9;;;;N;;;;;
+FBE3;ARABIC LETTER KIRGHIZ YU FINAL FORM;Lo;0;AL;<final> 06C9;;;;N;;;;;
+FBE4;ARABIC LETTER E ISOLATED FORM;Lo;0;AL;<isolated> 06D0;;;;N;;;;;
+FBE5;ARABIC LETTER E FINAL FORM;Lo;0;AL;<final> 06D0;;;;N;;;;;
+FBE6;ARABIC LETTER E INITIAL FORM;Lo;0;AL;<initial> 06D0;;;;N;;;;;
+FBE7;ARABIC LETTER E MEDIAL FORM;Lo;0;AL;<medial> 06D0;;;;N;;;;;
+FBE8;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM;Lo;0;AL;<initial> 0649;;;;N;;;;;
+FBE9;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM;Lo;0;AL;<medial> 0649;;;;N;;;;;
+FBEA;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0626 0627;;;;N;;;;;
+FBEB;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM;Lo;0;AL;<final> 0626 0627;;;;N;;;;;
+FBEC;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM;Lo;0;AL;<isolated> 0626 06D5;;;;N;;;;;
+FBED;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM;Lo;0;AL;<final> 0626 06D5;;;;N;;;;;
+FBEE;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM;Lo;0;AL;<isolated> 0626 0648;;;;N;;;;;
+FBEF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM;Lo;0;AL;<final> 0626 0648;;;;N;;;;;
+FBF0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C7;;;;N;;;;;
+FBF1;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM;Lo;0;AL;<final> 0626 06C7;;;;N;;;;;
+FBF2;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C6;;;;N;;;;;
+FBF3;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM;Lo;0;AL;<final> 0626 06C6;;;;N;;;;;
+FBF4;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C8;;;;N;;;;;
+FBF5;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM;Lo;0;AL;<final> 0626 06C8;;;;N;;;;;
+FBF6;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM;Lo;0;AL;<isolated> 0626 06D0;;;;N;;;;;
+FBF7;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM;Lo;0;AL;<final> 0626 06D0;;;;N;;;;;
+FBF8;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM;Lo;0;AL;<initial> 0626 06D0;;;;N;;;;;
+FBF9;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0626 0649;;;;N;;;;;
+FBFA;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0626 0649;;;;N;;;;;
+FBFB;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM;Lo;0;AL;<initial> 0626 0649;;;;N;;;;;
+FBFC;ARABIC LETTER FARSI YEH ISOLATED FORM;Lo;0;AL;<isolated> 06CC;;;;N;;;;;
+FBFD;ARABIC LETTER FARSI YEH FINAL FORM;Lo;0;AL;<final> 06CC;;;;N;;;;;
+FBFE;ARABIC LETTER FARSI YEH INITIAL FORM;Lo;0;AL;<initial> 06CC;;;;N;;;;;
+FBFF;ARABIC LETTER FARSI YEH MEDIAL FORM;Lo;0;AL;<medial> 06CC;;;;N;;;;;
+FC00;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0626 062C;;;;N;;;;;
+FC01;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0626 062D;;;;N;;;;;
+FC02;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0626 0645;;;;N;;;;;
+FC03;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0626 0649;;;;N;;;;;
+FC04;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0626 064A;;;;N;;;;;
+FC05;ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0628 062C;;;;N;;;;;
+FC06;ARABIC LIGATURE BEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0628 062D;;;;N;;;;;
+FC07;ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0628 062E;;;;N;;;;;
+FC08;ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0628 0645;;;;N;;;;;
+FC09;ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0628 0649;;;;N;;;;;
+FC0A;ARABIC LIGATURE BEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0628 064A;;;;N;;;;;
+FC0B;ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062A 062C;;;;N;;;;;
+FC0C;ARABIC LIGATURE TEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062A 062D;;;;N;;;;;
+FC0D;ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 062A 062E;;;;N;;;;;
+FC0E;ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062A 0645;;;;N;;;;;
+FC0F;ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062A 0649;;;;N;;;;;
+FC10;ARABIC LIGATURE TEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062A 064A;;;;N;;;;;
+FC11;ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062B 062C;;;;N;;;;;
+FC12;ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062B 0645;;;;N;;;;;
+FC13;ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062B 0649;;;;N;;;;;
+FC14;ARABIC LIGATURE THEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062B 064A;;;;N;;;;;
+FC15;ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062C 062D;;;;N;;;;;
+FC16;ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062C 0645;;;;N;;;;;
+FC17;ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062D 062C;;;;N;;;;;
+FC18;ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062D 0645;;;;N;;;;;
+FC19;ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062E 062C;;;;N;;;;;
+FC1A;ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062E 062D;;;;N;;;;;
+FC1B;ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062E 0645;;;;N;;;;;
+FC1C;ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0633 062C;;;;N;;;;;
+FC1D;ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0633 062D;;;;N;;;;;
+FC1E;ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0633 062E;;;;N;;;;;
+FC1F;ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0633 0645;;;;N;;;;;
+FC20;ARABIC LIGATURE SAD WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0635 062D;;;;N;;;;;
+FC21;ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0635 0645;;;;N;;;;;
+FC22;ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0636 062C;;;;N;;;;;
+FC23;ARABIC LIGATURE DAD WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0636 062D;;;;N;;;;;
+FC24;ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0636 062E;;;;N;;;;;
+FC25;ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0636 0645;;;;N;;;;;
+FC26;ARABIC LIGATURE TAH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0637 062D;;;;N;;;;;
+FC27;ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0637 0645;;;;N;;;;;
+FC28;ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0638 0645;;;;N;;;;;
+FC29;ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0639 062C;;;;N;;;;;
+FC2A;ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0639 0645;;;;N;;;;;
+FC2B;ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 063A 062C;;;;N;;;;;
+FC2C;ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 063A 0645;;;;N;;;;;
+FC2D;ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0641 062C;;;;N;;;;;
+FC2E;ARABIC LIGATURE FEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0641 062D;;;;N;;;;;
+FC2F;ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0641 062E;;;;N;;;;;
+FC30;ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0641 0645;;;;N;;;;;
+FC31;ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0641 0649;;;;N;;;;;
+FC32;ARABIC LIGATURE FEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0641 064A;;;;N;;;;;
+FC33;ARABIC LIGATURE QAF WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0642 062D;;;;N;;;;;
+FC34;ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0642 0645;;;;N;;;;;
+FC35;ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0642 0649;;;;N;;;;;
+FC36;ARABIC LIGATURE QAF WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0642 064A;;;;N;;;;;
+FC37;ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0643 0627;;;;N;;;;;
+FC38;ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0643 062C;;;;N;;;;;
+FC39;ARABIC LIGATURE KAF WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0643 062D;;;;N;;;;;
+FC3A;ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0643 062E;;;;N;;;;;
+FC3B;ARABIC LIGATURE KAF WITH LAM ISOLATED FORM;Lo;0;AL;<isolated> 0643 0644;;;;N;;;;;
+FC3C;ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0643 0645;;;;N;;;;;
+FC3D;ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0643 0649;;;;N;;;;;
+FC3E;ARABIC LIGATURE KAF WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0643 064A;;;;N;;;;;
+FC3F;ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0644 062C;;;;N;;;;;
+FC40;ARABIC LIGATURE LAM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 062D;;;;N;;;;;
+FC41;ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 062E;;;;N;;;;;
+FC42;ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0644 0645;;;;N;;;;;
+FC43;ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0644 0649;;;;N;;;;;
+FC44;ARABIC LIGATURE LAM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0644 064A;;;;N;;;;;
+FC45;ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645 062C;;;;N;;;;;
+FC46;ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0645 062D;;;;N;;;;;
+FC47;ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0645 062E;;;;N;;;;;
+FC48;ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645 0645;;;;N;;;;;
+FC49;ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0645 0649;;;;N;;;;;
+FC4A;ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0645 064A;;;;N;;;;;
+FC4B;ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0646 062C;;;;N;;;;;
+FC4C;ARABIC LIGATURE NOON WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0646 062D;;;;N;;;;;
+FC4D;ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0646 062E;;;;N;;;;;
+FC4E;ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0646 0645;;;;N;;;;;
+FC4F;ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0646 0649;;;;N;;;;;
+FC50;ARABIC LIGATURE NOON WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0646 064A;;;;N;;;;;
+FC51;ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0647 062C;;;;N;;;;;
+FC52;ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0647 0645;;;;N;;;;;
+FC53;ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0647 0649;;;;N;;;;;
+FC54;ARABIC LIGATURE HEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0647 064A;;;;N;;;;;
+FC55;ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 064A 062C;;;;N;;;;;
+FC56;ARABIC LIGATURE YEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 064A 062D;;;;N;;;;;
+FC57;ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 064A 062E;;;;N;;;;;
+FC58;ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 064A 0645;;;;N;;;;;
+FC59;ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 064A 0649;;;;N;;;;;
+FC5A;ARABIC LIGATURE YEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 064A 064A;;;;N;;;;;
+FC5B;ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0630 0670;;;;N;;;;;
+FC5C;ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0631 0670;;;;N;;;;;
+FC5D;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0649 0670;;;;N;;;;;
+FC5E;ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064C 0651;;;;N;;;;;
+FC5F;ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064D 0651;;;;N;;;;;
+FC60;ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064E 0651;;;;N;;;;;
+FC61;ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064F 0651;;;;N;;;;;
+FC62;ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0650 0651;;;;N;;;;;
+FC63;ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0020 0651 0670;;;;N;;;;;
+FC64;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM;Lo;0;AL;<final> 0626 0631;;;;N;;;;;
+FC65;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0626 0632;;;;N;;;;;
+FC66;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM;Lo;0;AL;<final> 0626 0645;;;;N;;;;;
+FC67;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM;Lo;0;AL;<final> 0626 0646;;;;N;;;;;
+FC68;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0626 0649;;;;N;;;;;
+FC69;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM;Lo;0;AL;<final> 0626 064A;;;;N;;;;;
+FC6A;ARABIC LIGATURE BEH WITH REH FINAL FORM;Lo;0;AL;<final> 0628 0631;;;;N;;;;;
+FC6B;ARABIC LIGATURE BEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0628 0632;;;;N;;;;;
+FC6C;ARABIC LIGATURE BEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0628 0645;;;;N;;;;;
+FC6D;ARABIC LIGATURE BEH WITH NOON FINAL FORM;Lo;0;AL;<final> 0628 0646;;;;N;;;;;
+FC6E;ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0628 0649;;;;N;;;;;
+FC6F;ARABIC LIGATURE BEH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 064A;;;;N;;;;;
+FC70;ARABIC LIGATURE TEH WITH REH FINAL FORM;Lo;0;AL;<final> 062A 0631;;;;N;;;;;
+FC71;ARABIC LIGATURE TEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 062A 0632;;;;N;;;;;
+FC72;ARABIC LIGATURE TEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 062A 0645;;;;N;;;;;
+FC73;ARABIC LIGATURE TEH WITH NOON FINAL FORM;Lo;0;AL;<final> 062A 0646;;;;N;;;;;
+FC74;ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 0649;;;;N;;;;;
+FC75;ARABIC LIGATURE TEH WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 064A;;;;N;;;;;
+FC76;ARABIC LIGATURE THEH WITH REH FINAL FORM;Lo;0;AL;<final> 062B 0631;;;;N;;;;;
+FC77;ARABIC LIGATURE THEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 062B 0632;;;;N;;;;;
+FC78;ARABIC LIGATURE THEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 062B 0645;;;;N;;;;;
+FC79;ARABIC LIGATURE THEH WITH NOON FINAL FORM;Lo;0;AL;<final> 062B 0646;;;;N;;;;;
+FC7A;ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062B 0649;;;;N;;;;;
+FC7B;ARABIC LIGATURE THEH WITH YEH FINAL FORM;Lo;0;AL;<final> 062B 064A;;;;N;;;;;
+FC7C;ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0641 0649;;;;N;;;;;
+FC7D;ARABIC LIGATURE FEH WITH YEH FINAL FORM;Lo;0;AL;<final> 0641 064A;;;;N;;;;;
+FC7E;ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0642 0649;;;;N;;;;;
+FC7F;ARABIC LIGATURE QAF WITH YEH FINAL FORM;Lo;0;AL;<final> 0642 064A;;;;N;;;;;
+FC80;ARABIC LIGATURE KAF WITH ALEF FINAL FORM;Lo;0;AL;<final> 0643 0627;;;;N;;;;;
+FC81;ARABIC LIGATURE KAF WITH LAM FINAL FORM;Lo;0;AL;<final> 0643 0644;;;;N;;;;;
+FC82;ARABIC LIGATURE KAF WITH MEEM FINAL FORM;Lo;0;AL;<final> 0643 0645;;;;N;;;;;
+FC83;ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0643 0649;;;;N;;;;;
+FC84;ARABIC LIGATURE KAF WITH YEH FINAL FORM;Lo;0;AL;<final> 0643 064A;;;;N;;;;;
+FC85;ARABIC LIGATURE LAM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 0645;;;;N;;;;;
+FC86;ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0644 0649;;;;N;;;;;
+FC87;ARABIC LIGATURE LAM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 064A;;;;N;;;;;
+FC88;ARABIC LIGATURE MEEM WITH ALEF FINAL FORM;Lo;0;AL;<final> 0645 0627;;;;N;;;;;
+FC89;ARABIC LIGATURE MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0645 0645;;;;N;;;;;
+FC8A;ARABIC LIGATURE NOON WITH REH FINAL FORM;Lo;0;AL;<final> 0646 0631;;;;N;;;;;
+FC8B;ARABIC LIGATURE NOON WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0646 0632;;;;N;;;;;
+FC8C;ARABIC LIGATURE NOON WITH MEEM FINAL FORM;Lo;0;AL;<final> 0646 0645;;;;N;;;;;
+FC8D;ARABIC LIGATURE NOON WITH NOON FINAL FORM;Lo;0;AL;<final> 0646 0646;;;;N;;;;;
+FC8E;ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 0649;;;;N;;;;;
+FC8F;ARABIC LIGATURE NOON WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 064A;;;;N;;;;;
+FC90;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM;Lo;0;AL;<final> 0649 0670;;;;N;;;;;
+FC91;ARABIC LIGATURE YEH WITH REH FINAL FORM;Lo;0;AL;<final> 064A 0631;;;;N;;;;;
+FC92;ARABIC LIGATURE YEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 064A 0632;;;;N;;;;;
+FC93;ARABIC LIGATURE YEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 064A 0645;;;;N;;;;;
+FC94;ARABIC LIGATURE YEH WITH NOON FINAL FORM;Lo;0;AL;<final> 064A 0646;;;;N;;;;;
+FC95;ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 064A 0649;;;;N;;;;;
+FC96;ARABIC LIGATURE YEH WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 064A;;;;N;;;;;
+FC97;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0626 062C;;;;N;;;;;
+FC98;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0626 062D;;;;N;;;;;
+FC99;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0626 062E;;;;N;;;;;
+FC9A;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0626 0645;;;;N;;;;;
+FC9B;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0626 0647;;;;N;;;;;
+FC9C;ARABIC LIGATURE BEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0628 062C;;;;N;;;;;
+FC9D;ARABIC LIGATURE BEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0628 062D;;;;N;;;;;
+FC9E;ARABIC LIGATURE BEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0628 062E;;;;N;;;;;
+FC9F;ARABIC LIGATURE BEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0628 0645;;;;N;;;;;
+FCA0;ARABIC LIGATURE BEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0628 0647;;;;N;;;;;
+FCA1;ARABIC LIGATURE TEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C;;;;N;;;;;
+FCA2;ARABIC LIGATURE TEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062A 062D;;;;N;;;;;
+FCA3;ARABIC LIGATURE TEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 062A 062E;;;;N;;;;;
+FCA4;ARABIC LIGATURE TEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 0645;;;;N;;;;;
+FCA5;ARABIC LIGATURE TEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 062A 0647;;;;N;;;;;
+FCA6;ARABIC LIGATURE THEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062B 0645;;;;N;;;;;
+FCA7;ARABIC LIGATURE JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062C 062D;;;;N;;;;;
+FCA8;ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062C 0645;;;;N;;;;;
+FCA9;ARABIC LIGATURE HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062D 062C;;;;N;;;;;
+FCAA;ARABIC LIGATURE HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062D 0645;;;;N;;;;;
+FCAB;ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062E 062C;;;;N;;;;;
+FCAC;ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062E 0645;;;;N;;;;;
+FCAD;ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 062C;;;;N;;;;;
+FCAE;ARABIC LIGATURE SEEN WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 062D;;;;N;;;;;
+FCAF;ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0633 062E;;;;N;;;;;
+FCB0;ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645;;;;N;;;;;
+FCB1;ARABIC LIGATURE SAD WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0635 062D;;;;N;;;;;
+FCB2;ARABIC LIGATURE SAD WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0635 062E;;;;N;;;;;
+FCB3;ARABIC LIGATURE SAD WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645;;;;N;;;;;
+FCB4;ARABIC LIGATURE DAD WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0636 062C;;;;N;;;;;
+FCB5;ARABIC LIGATURE DAD WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0636 062D;;;;N;;;;;
+FCB6;ARABIC LIGATURE DAD WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0636 062E;;;;N;;;;;
+FCB7;ARABIC LIGATURE DAD WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0636 0645;;;;N;;;;;
+FCB8;ARABIC LIGATURE TAH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0637 062D;;;;N;;;;;
+FCB9;ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0638 0645;;;;N;;;;;
+FCBA;ARABIC LIGATURE AIN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0639 062C;;;;N;;;;;
+FCBB;ARABIC LIGATURE AIN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 0645;;;;N;;;;;
+FCBC;ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 063A 062C;;;;N;;;;;
+FCBD;ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 063A 0645;;;;N;;;;;
+FCBE;ARABIC LIGATURE FEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0641 062C;;;;N;;;;;
+FCBF;ARABIC LIGATURE FEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0641 062D;;;;N;;;;;
+FCC0;ARABIC LIGATURE FEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0641 062E;;;;N;;;;;
+FCC1;ARABIC LIGATURE FEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0641 0645;;;;N;;;;;
+FCC2;ARABIC LIGATURE QAF WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0642 062D;;;;N;;;;;
+FCC3;ARABIC LIGATURE QAF WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0642 0645;;;;N;;;;;
+FCC4;ARABIC LIGATURE KAF WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0643 062C;;;;N;;;;;
+FCC5;ARABIC LIGATURE KAF WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0643 062D;;;;N;;;;;
+FCC6;ARABIC LIGATURE KAF WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0643 062E;;;;N;;;;;
+FCC7;ARABIC LIGATURE KAF WITH LAM INITIAL FORM;Lo;0;AL;<initial> 0643 0644;;;;N;;;;;
+FCC8;ARABIC LIGATURE KAF WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0643 0645;;;;N;;;;;
+FCC9;ARABIC LIGATURE LAM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C;;;;N;;;;;
+FCCA;ARABIC LIGATURE LAM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0644 062D;;;;N;;;;;
+FCCB;ARABIC LIGATURE LAM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0644 062E;;;;N;;;;;
+FCCC;ARABIC LIGATURE LAM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 0645;;;;N;;;;;
+FCCD;ARABIC LIGATURE LAM WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0644 0647;;;;N;;;;;
+FCCE;ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062C;;;;N;;;;;
+FCCF;ARABIC LIGATURE MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0645 062D;;;;N;;;;;
+FCD0;ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0645 062E;;;;N;;;;;
+FCD1;ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 0645;;;;N;;;;;
+FCD2;ARABIC LIGATURE NOON WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062C;;;;N;;;;;
+FCD3;ARABIC LIGATURE NOON WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0646 062D;;;;N;;;;;
+FCD4;ARABIC LIGATURE NOON WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0646 062E;;;;N;;;;;
+FCD5;ARABIC LIGATURE NOON WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 0645;;;;N;;;;;
+FCD6;ARABIC LIGATURE NOON WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0646 0647;;;;N;;;;;
+FCD7;ARABIC LIGATURE HEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0647 062C;;;;N;;;;;
+FCD8;ARABIC LIGATURE HEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645;;;;N;;;;;
+FCD9;ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM;Lo;0;AL;<initial> 0647 0670;;;;N;;;;;
+FCDA;ARABIC LIGATURE YEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 064A 062C;;;;N;;;;;
+FCDB;ARABIC LIGATURE YEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 064A 062D;;;;N;;;;;
+FCDC;ARABIC LIGATURE YEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 064A 062E;;;;N;;;;;
+FCDD;ARABIC LIGATURE YEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 064A 0645;;;;N;;;;;
+FCDE;ARABIC LIGATURE YEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 064A 0647;;;;N;;;;;
+FCDF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0626 0645;;;;N;;;;;
+FCE0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0626 0647;;;;N;;;;;
+FCE1;ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0628 0645;;;;N;;;;;
+FCE2;ARABIC LIGATURE BEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0628 0647;;;;N;;;;;
+FCE3;ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 062A 0645;;;;N;;;;;
+FCE4;ARABIC LIGATURE TEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 062A 0647;;;;N;;;;;
+FCE5;ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 062B 0645;;;;N;;;;;
+FCE6;ARABIC LIGATURE THEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 062B 0647;;;;N;;;;;
+FCE7;ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0633 0645;;;;N;;;;;
+FCE8;ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0633 0647;;;;N;;;;;
+FCE9;ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0634 0645;;;;N;;;;;
+FCEA;ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0634 0647;;;;N;;;;;
+FCEB;ARABIC LIGATURE KAF WITH LAM MEDIAL FORM;Lo;0;AL;<medial> 0643 0644;;;;N;;;;;
+FCEC;ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0643 0645;;;;N;;;;;
+FCED;ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0644 0645;;;;N;;;;;
+FCEE;ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0646 0645;;;;N;;;;;
+FCEF;ARABIC LIGATURE NOON WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0646 0647;;;;N;;;;;
+FCF0;ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 064A 0645;;;;N;;;;;
+FCF1;ARABIC LIGATURE YEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 064A 0647;;;;N;;;;;
+FCF2;ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM;Lo;0;AL;<medial> 0640 064E 0651;;;;N;;;;;
+FCF3;ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM;Lo;0;AL;<medial> 0640 064F 0651;;;;N;;;;;
+FCF4;ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM;Lo;0;AL;<medial> 0640 0650 0651;;;;N;;;;;
+FCF5;ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0637 0649;;;;N;;;;;
+FCF6;ARABIC LIGATURE TAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0637 064A;;;;N;;;;;
+FCF7;ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0639 0649;;;;N;;;;;
+FCF8;ARABIC LIGATURE AIN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0639 064A;;;;N;;;;;
+FCF9;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 063A 0649;;;;N;;;;;
+FCFA;ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 063A 064A;;;;N;;;;;
+FCFB;ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0633 0649;;;;N;;;;;
+FCFC;ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0633 064A;;;;N;;;;;
+FCFD;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0634 0649;;;;N;;;;;
+FCFE;ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0634 064A;;;;N;;;;;
+FCFF;ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062D 0649;;;;N;;;;;
+FD00;ARABIC LIGATURE HAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062D 064A;;;;N;;;;;
+FD01;ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062C 0649;;;;N;;;;;
+FD02;ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062C 064A;;;;N;;;;;
+FD03;ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062E 0649;;;;N;;;;;
+FD04;ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062E 064A;;;;N;;;;;
+FD05;ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0635 0649;;;;N;;;;;
+FD06;ARABIC LIGATURE SAD WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0635 064A;;;;N;;;;;
+FD07;ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0636 0649;;;;N;;;;;
+FD08;ARABIC LIGATURE DAD WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0636 064A;;;;N;;;;;
+FD09;ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0634 062C;;;;N;;;;;
+FD0A;ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0634 062D;;;;N;;;;;
+FD0B;ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0634 062E;;;;N;;;;;
+FD0C;ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0634 0645;;;;N;;;;;
+FD0D;ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0634 0631;;;;N;;;;;
+FD0E;ARABIC LIGATURE SEEN WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0633 0631;;;;N;;;;;
+FD0F;ARABIC LIGATURE SAD WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0635 0631;;;;N;;;;;
+FD10;ARABIC LIGATURE DAD WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0636 0631;;;;N;;;;;
+FD11;ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0637 0649;;;;N;;;;;
+FD12;ARABIC LIGATURE TAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0637 064A;;;;N;;;;;
+FD13;ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0639 0649;;;;N;;;;;
+FD14;ARABIC LIGATURE AIN WITH YEH FINAL FORM;Lo;0;AL;<final> 0639 064A;;;;N;;;;;
+FD15;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 063A 0649;;;;N;;;;;
+FD16;ARABIC LIGATURE GHAIN WITH YEH FINAL FORM;Lo;0;AL;<final> 063A 064A;;;;N;;;;;
+FD17;ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 0649;;;;N;;;;;
+FD18;ARABIC LIGATURE SEEN WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 064A;;;;N;;;;;
+FD19;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0634 0649;;;;N;;;;;
+FD1A;ARABIC LIGATURE SHEEN WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 064A;;;;N;;;;;
+FD1B;ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062D 0649;;;;N;;;;;
+FD1C;ARABIC LIGATURE HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 064A;;;;N;;;;;
+FD1D;ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 0649;;;;N;;;;;
+FD1E;ARABIC LIGATURE JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 064A;;;;N;;;;;
+FD1F;ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062E 0649;;;;N;;;;;
+FD20;ARABIC LIGATURE KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062E 064A;;;;N;;;;;
+FD21;ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0635 0649;;;;N;;;;;
+FD22;ARABIC LIGATURE SAD WITH YEH FINAL FORM;Lo;0;AL;<final> 0635 064A;;;;N;;;;;
+FD23;ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0636 0649;;;;N;;;;;
+FD24;ARABIC LIGATURE DAD WITH YEH FINAL FORM;Lo;0;AL;<final> 0636 064A;;;;N;;;;;
+FD25;ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM;Lo;0;AL;<final> 0634 062C;;;;N;;;;;
+FD26;ARABIC LIGATURE SHEEN WITH HAH FINAL FORM;Lo;0;AL;<final> 0634 062D;;;;N;;;;;
+FD27;ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM;Lo;0;AL;<final> 0634 062E;;;;N;;;;;
+FD28;ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 0645;;;;N;;;;;
+FD29;ARABIC LIGATURE SHEEN WITH REH FINAL FORM;Lo;0;AL;<final> 0634 0631;;;;N;;;;;
+FD2A;ARABIC LIGATURE SEEN WITH REH FINAL FORM;Lo;0;AL;<final> 0633 0631;;;;N;;;;;
+FD2B;ARABIC LIGATURE SAD WITH REH FINAL FORM;Lo;0;AL;<final> 0635 0631;;;;N;;;;;
+FD2C;ARABIC LIGATURE DAD WITH REH FINAL FORM;Lo;0;AL;<final> 0636 0631;;;;N;;;;;
+FD2D;ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0634 062C;;;;N;;;;;
+FD2E;ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0634 062D;;;;N;;;;;
+FD2F;ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0634 062E;;;;N;;;;;
+FD30;ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 0645;;;;N;;;;;
+FD31;ARABIC LIGATURE SEEN WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0633 0647;;;;N;;;;;
+FD32;ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0634 0647;;;;N;;;;;
+FD33;ARABIC LIGATURE TAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0637 0645;;;;N;;;;;
+FD34;ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM;Lo;0;AL;<medial> 0633 062C;;;;N;;;;;
+FD35;ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM;Lo;0;AL;<medial> 0633 062D;;;;N;;;;;
+FD36;ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM;Lo;0;AL;<medial> 0633 062E;;;;N;;;;;
+FD37;ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM;Lo;0;AL;<medial> 0634 062C;;;;N;;;;;
+FD38;ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM;Lo;0;AL;<medial> 0634 062D;;;;N;;;;;
+FD39;ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM;Lo;0;AL;<medial> 0634 062E;;;;N;;;;;
+FD3A;ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0637 0645;;;;N;;;;;
+FD3B;ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0638 0645;;;;N;;;;;
+FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL;<final> 0627 064B;;;;N;;;;;
+FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0627 064B;;;;N;;;;;
+FD3E;ORNATE LEFT PARENTHESIS;Pe;0;ON;;;;;N;;;;;
+FD3F;ORNATE RIGHT PARENTHESIS;Ps;0;ON;;;;;N;;;;;
+FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C 0645;;;;N;;;;;
+FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL;<final> 062A 062D 062C;;;;N;;;;;
+FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 062C;;;;N;;;;;
+FD53;ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 0645;;;;N;;;;;
+FD54;ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062E 0645;;;;N;;;;;
+FD55;ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062C;;;;N;;;;;
+FD56;ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062D;;;;N;;;;;
+FD57;ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062E;;;;N;;;;;
+FD58;ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 062C 0645 062D;;;;N;;;;;
+FD59;ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062C 0645 062D;;;;N;;;;;
+FD5A;ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 0645 064A;;;;N;;;;;
+FD5B;ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062D 0645 0649;;;;N;;;;;
+FD5C;ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 062D 062C;;;;N;;;;;
+FD5D;ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 062C 062D;;;;N;;;;;
+FD5E;ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 062C 0649;;;;N;;;;;
+FD5F;ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0633 0645 062D;;;;N;;;;;
+FD60;ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 0645 062D;;;;N;;;;;
+FD61;ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645 062C;;;;N;;;;;
+FD62;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0633 0645 0645;;;;N;;;;;
+FD63;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645 0645;;;;N;;;;;
+FD64;ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM;Lo;0;AL;<final> 0635 062D 062D;;;;N;;;;;
+FD65;ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0635 062D 062D;;;;N;;;;;
+FD66;ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0635 0645 0645;;;;N;;;;;
+FD67;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 062D 0645;;;;N;;;;;
+FD68;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 062D 0645;;;;N;;;;;
+FD69;ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 062C 064A;;;;N;;;;;
+FD6A;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM;Lo;0;AL;<final> 0634 0645 062E;;;;N;;;;;
+FD6B;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0634 0645 062E;;;;N;;;;;
+FD6C;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 0645 0645;;;;N;;;;;
+FD6D;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 0645 0645;;;;N;;;;;
+FD6E;ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0636 062D 0649;;;;N;;;;;
+FD6F;ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0636 062E 0645;;;;N;;;;;
+FD70;ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0636 062E 0645;;;;N;;;;;
+FD71;ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0637 0645 062D;;;;N;;;;;
+FD72;ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0637 0645 062D;;;;N;;;;;
+FD73;ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0637 0645 0645;;;;N;;;;;
+FD74;ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0637 0645 064A;;;;N;;;;;
+FD75;ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0639 062C 0645;;;;N;;;;;
+FD76;ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0639 0645 0645;;;;N;;;;;
+FD77;ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 0645 0645;;;;N;;;;;
+FD78;ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0639 0645 0649;;;;N;;;;;
+FD79;ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 063A 0645 0645;;;;N;;;;;
+FD7A;ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 063A 0645 064A;;;;N;;;;;
+FD7B;ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 063A 0645 0649;;;;N;;;;;
+FD7C;ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0641 062E 0645;;;;N;;;;;
+FD7D;ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0641 062E 0645;;;;N;;;;;
+FD7E;ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0642 0645 062D;;;;N;;;;;
+FD7F;ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0642 0645 0645;;;;N;;;;;
+FD80;ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062D 0645;;;;N;;;;;
+FD81;ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 062D 064A;;;;N;;;;;
+FD82;ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0644 062D 0649;;;;N;;;;;
+FD83;ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C 062C;;;;N;;;;;
+FD84;ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM;Lo;0;AL;<final> 0644 062C 062C;;;;N;;;;;
+FD85;ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062E 0645;;;;N;;;;;
+FD86;ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062E 0645;;;;N;;;;;
+FD87;ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0644 0645 062D;;;;N;;;;;
+FD88;ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0644 0645 062D;;;;N;;;;;
+FD89;ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062D 062C;;;;N;;;;;
+FD8A;ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062D 0645;;;;N;;;;;
+FD8B;ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062D 064A;;;;N;;;;;
+FD8C;ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0645 062C 062D;;;;N;;;;;
+FD8D;ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062C 0645;;;;N;;;;;
+FD8E;ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062E 062C;;;;N;;;;;
+FD8F;ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062E 0645;;;;N;;;;;
+FD92;ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0645 062C 062E;;;;N;;;;;
+FD93;ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645 062C;;;;N;;;;;
+FD94;ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645 0645;;;;N;;;;;
+FD95;ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062D 0645;;;;N;;;;;
+FD96;ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 062D 0649;;;;N;;;;;
+FD97;ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0646 062C 0645;;;;N;;;;;
+FD98;ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062C 0645;;;;N;;;;;
+FD99;ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 062C 0649;;;;N;;;;;
+FD9A;ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 0645 064A;;;;N;;;;;
+FD9B;ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 0645 0649;;;;N;;;;;
+FD9C;ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 064A 0645 0645;;;;N;;;;;
+FD9D;ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 064A 0645 0645;;;;N;;;;;
+FD9E;ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 062E 064A;;;;N;;;;;
+FD9F;ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 062C 064A;;;;N;;;;;
+FDA0;ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 062C 0649;;;;N;;;;;
+FDA1;ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 062E 064A;;;;N;;;;;
+FDA2;ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 062E 0649;;;;N;;;;;
+FDA3;ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 0645 064A;;;;N;;;;;
+FDA4;ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 0645 0649;;;;N;;;;;
+FDA5;ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 0645 064A;;;;N;;;;;
+FDA6;ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 062D 0649;;;;N;;;;;
+FDA7;ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 0645 0649;;;;N;;;;;
+FDA8;ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 062E 0649;;;;N;;;;;
+FDA9;ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0635 062D 064A;;;;N;;;;;
+FDAA;ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 062D 064A;;;;N;;;;;
+FDAB;ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0636 062D 064A;;;;N;;;;;
+FDAC;ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 062C 064A;;;;N;;;;;
+FDAD;ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 0645 064A;;;;N;;;;;
+FDAE;ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 062D 064A;;;;N;;;;;
+FDAF;ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 062C 064A;;;;N;;;;;
+FDB0;ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 0645 064A;;;;N;;;;;
+FDB1;ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 0645 064A;;;;N;;;;;
+FDB2;ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0642 0645 064A;;;;N;;;;;
+FDB3;ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062D 064A;;;;N;;;;;
+FDB4;ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0642 0645 062D;;;;N;;;;;
+FDB5;ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062D 0645;;;;N;;;;;
+FDB6;ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0639 0645 064A;;;;N;;;;;
+FDB7;ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0643 0645 064A;;;;N;;;;;
+FDB8;ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0646 062C 062D;;;;N;;;;;
+FDB9;ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062E 064A;;;;N;;;;;
+FDBA;ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C 0645;;;;N;;;;;
+FDBB;ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0643 0645 0645;;;;N;;;;;
+FDBC;ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062C 0645;;;;N;;;;;
+FDBD;ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0646 062C 062D;;;;N;;;;;
+FDBE;ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 062D 064A;;;;N;;;;;
+FDBF;ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 062C 064A;;;;N;;;;;
+FDC0;ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062C 064A;;;;N;;;;;
+FDC1;ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0641 0645 064A;;;;N;;;;;
+FDC2;ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 062D 064A;;;;N;;;;;
+FDC3;ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0643 0645 0645;;;;N;;;;;
+FDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 062C 0645;;;;N;;;;;
+FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645 0645;;;;N;;;;;
+FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 062E 064A;;;;N;;;;;
+FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062C 064A;;;;N;;;;;
+FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 06D2;;;;N;;;;;
+FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0642 0644 06D2;;;;N;;;;;
+FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL;<isolated> 0627 0644 0644 0647;;;;N;;;;;
+FDF3;ARABIC LIGATURE AKBAR ISOLATED FORM;Lo;0;AL;<isolated> 0627 0643 0628 0631;;;;N;;;;;
+FDF4;ARABIC LIGATURE MOHAMMAD ISOLATED FORM;Lo;0;AL;<isolated> 0645 062D 0645 062F;;;;N;;;;;
+FDF5;ARABIC LIGATURE SALAM ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 0639 0645;;;;N;;;;;
+FDF6;ARABIC LIGATURE RASOUL ISOLATED FORM;Lo;0;AL;<isolated> 0631 0633 0648 0644;;;;N;;;;;
+FDF7;ARABIC LIGATURE ALAYHE ISOLATED FORM;Lo;0;AL;<isolated> 0639 0644 064A 0647;;;;N;;;;;
+FDF8;ARABIC LIGATURE WASALLAM ISOLATED FORM;Lo;0;AL;<isolated> 0648 0633 0644 0645;;;;N;;;;;
+FDF9;ARABIC LIGATURE SALLA ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 0649;;;;N;;;;;
+FDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL;<isolated> 0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;;;;N;ARABIC LETTER SALLALLAHOU ALAYHE WASALLAM;;;;
+FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL;<isolated> 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;;
+FDFC;RIAL SIGN;Sc;0;AL;<isolated> 0631 06CC 0627 0644;;;;N;;;;;
+FDFD;ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM;So;0;ON;;;;;N;;;;;
+FE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;;
+FE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;;
+FE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;;
+FE03;VARIATION SELECTOR-4;Mn;0;NSM;;;;;N;;;;;
+FE04;VARIATION SELECTOR-5;Mn;0;NSM;;;;;N;;;;;
+FE05;VARIATION SELECTOR-6;Mn;0;NSM;;;;;N;;;;;
+FE06;VARIATION SELECTOR-7;Mn;0;NSM;;;;;N;;;;;
+FE07;VARIATION SELECTOR-8;Mn;0;NSM;;;;;N;;;;;
+FE08;VARIATION SELECTOR-9;Mn;0;NSM;;;;;N;;;;;
+FE09;VARIATION SELECTOR-10;Mn;0;NSM;;;;;N;;;;;
+FE0A;VARIATION SELECTOR-11;Mn;0;NSM;;;;;N;;;;;
+FE0B;VARIATION SELECTOR-12;Mn;0;NSM;;;;;N;;;;;
+FE0C;VARIATION SELECTOR-13;Mn;0;NSM;;;;;N;;;;;
+FE0D;VARIATION SELECTOR-14;Mn;0;NSM;;;;;N;;;;;
+FE0E;VARIATION SELECTOR-15;Mn;0;NSM;;;;;N;;;;;
+FE0F;VARIATION SELECTOR-16;Mn;0;NSM;;;;;N;;;;;
+FE10;PRESENTATION FORM FOR VERTICAL COMMA;Po;0;ON;<vertical> 002C;;;;N;;;;;
+FE11;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA;Po;0;ON;<vertical> 3001;;;;N;;;;;
+FE12;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP;Po;0;ON;<vertical> 3002;;;;N;;;;;
+FE13;PRESENTATION FORM FOR VERTICAL COLON;Po;0;ON;<vertical> 003A;;;;N;;;;;
+FE14;PRESENTATION FORM FOR VERTICAL SEMICOLON;Po;0;ON;<vertical> 003B;;;;N;;;;;
+FE15;PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK;Po;0;ON;<vertical> 0021;;;;N;;;;;
+FE16;PRESENTATION FORM FOR VERTICAL QUESTION MARK;Po;0;ON;<vertical> 003F;;;;N;;;;;
+FE17;PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;<vertical> 3016;;;;N;;;;;
+FE18;PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET;Pe;0;ON;<vertical> 3017;;;;N;;;;;
+FE19;PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS;Po;0;ON;<vertical> 2026;;;;N;;;;;
+FE20;COMBINING LIGATURE LEFT HALF;Mn;230;NSM;;;;;N;;;;;
+FE21;COMBINING LIGATURE RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
+FE22;COMBINING DOUBLE TILDE LEFT HALF;Mn;230;NSM;;;;;N;;;;;
+FE23;COMBINING DOUBLE TILDE RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
+FE24;COMBINING MACRON LEFT HALF;Mn;230;NSM;;;;;N;;;;;
+FE25;COMBINING MACRON RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
+FE26;COMBINING CONJOINING MACRON;Mn;230;NSM;;;;;N;;;;;
+FE27;COMBINING LIGATURE LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE28;COMBINING LIGATURE RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE29;COMBINING TILDE LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE2A;COMBINING TILDE RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE2B;COMBINING MACRON LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE2C;COMBINING MACRON RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;;
+FE2D;COMBINING CONJOINING MACRON BELOW;Mn;220;NSM;;;;;N;;;;;
+FE2E;COMBINING CYRILLIC TITLO LEFT HALF;Mn;230;NSM;;;;;N;;;;;
+FE2F;COMBINING CYRILLIC TITLO RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
+FE30;PRESENTATION FORM FOR VERTICAL TWO DOT LEADER;Po;0;ON;<vertical> 2025;;;;N;GLYPH FOR VERTICAL TWO DOT LEADER;;;;
+FE31;PRESENTATION FORM FOR VERTICAL EM DASH;Pd;0;ON;<vertical> 2014;;;;N;GLYPH FOR VERTICAL EM DASH;;;;
+FE32;PRESENTATION FORM FOR VERTICAL EN DASH;Pd;0;ON;<vertical> 2013;;;;N;GLYPH FOR VERTICAL EN DASH;;;;
+FE33;PRESENTATION FORM FOR VERTICAL LOW LINE;Pc;0;ON;<vertical> 005F;;;;N;GLYPH FOR VERTICAL SPACING UNDERSCORE;;;;
+FE34;PRESENTATION FORM FOR VERTICAL WAVY LOW LINE;Pc;0;ON;<vertical> 005F;;;;N;GLYPH FOR VERTICAL SPACING WAVY UNDERSCORE;;;;
+FE35;PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS;Ps;0;ON;<vertical> 0028;;;;N;GLYPH FOR VERTICAL OPENING PARENTHESIS;;;;
+FE36;PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS;Pe;0;ON;<vertical> 0029;;;;N;GLYPH FOR VERTICAL CLOSING PARENTHESIS;;;;
+FE37;PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET;Ps;0;ON;<vertical> 007B;;;;N;GLYPH FOR VERTICAL OPENING CURLY BRACKET;;;;
+FE38;PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET;Pe;0;ON;<vertical> 007D;;;;N;GLYPH FOR VERTICAL CLOSING CURLY BRACKET;;;;
+FE39;PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET;Ps;0;ON;<vertical> 3014;;;;N;GLYPH FOR VERTICAL OPENING TORTOISE SHELL BRACKET;;;;
+FE3A;PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;<vertical> 3015;;;;N;GLYPH FOR VERTICAL CLOSING TORTOISE SHELL BRACKET;;;;
+FE3B;PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;<vertical> 3010;;;;N;GLYPH FOR VERTICAL OPENING BLACK LENTICULAR BRACKET;;;;
+FE3C;PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;<vertical> 3011;;;;N;GLYPH FOR VERTICAL CLOSING BLACK LENTICULAR BRACKET;;;;
+FE3D;PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;<vertical> 300A;;;;N;GLYPH FOR VERTICAL OPENING DOUBLE ANGLE BRACKET;;;;
+FE3E;PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;<vertical> 300B;;;;N;GLYPH FOR VERTICAL CLOSING DOUBLE ANGLE BRACKET;;;;
+FE3F;PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET;Ps;0;ON;<vertical> 3008;;;;N;GLYPH FOR VERTICAL OPENING ANGLE BRACKET;;;;
+FE40;PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET;Pe;0;ON;<vertical> 3009;;;;N;GLYPH FOR VERTICAL CLOSING ANGLE BRACKET;;;;
+FE41;PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET;Ps;0;ON;<vertical> 300C;;;;N;GLYPH FOR VERTICAL OPENING CORNER BRACKET;;;;
+FE42;PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET;Pe;0;ON;<vertical> 300D;;;;N;GLYPH FOR VERTICAL CLOSING CORNER BRACKET;;;;
+FE43;PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET;Ps;0;ON;<vertical> 300E;;;;N;GLYPH FOR VERTICAL OPENING WHITE CORNER BRACKET;;;;
+FE44;PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET;Pe;0;ON;<vertical> 300F;;;;N;GLYPH FOR VERTICAL CLOSING WHITE CORNER BRACKET;;;;
+FE45;SESAME DOT;Po;0;ON;;;;;N;;;;;
+FE46;WHITE SESAME DOT;Po;0;ON;;;;;N;;;;;
+FE47;PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET;Ps;0;ON;<vertical> 005B;;;;N;;;;;
+FE48;PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET;Pe;0;ON;<vertical> 005D;;;;N;;;;;
+FE49;DASHED OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING DASHED OVERSCORE;;;;
+FE4A;CENTRELINE OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING CENTERLINE OVERSCORE;;;;
+FE4B;WAVY OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING WAVY OVERSCORE;;;;
+FE4C;DOUBLE WAVY OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING DOUBLE WAVY OVERSCORE;;;;
+FE4D;DASHED LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING DASHED UNDERSCORE;;;;
+FE4E;CENTRELINE LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING CENTERLINE UNDERSCORE;;;;
+FE4F;WAVY LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING WAVY UNDERSCORE;;;;
+FE50;SMALL COMMA;Po;0;CS;<small> 002C;;;;N;;;;;
+FE51;SMALL IDEOGRAPHIC COMMA;Po;0;ON;<small> 3001;;;;N;;;;;
+FE52;SMALL FULL STOP;Po;0;CS;<small> 002E;;;;N;SMALL PERIOD;;;;
+FE54;SMALL SEMICOLON;Po;0;ON;<small> 003B;;;;N;;;;;
+FE55;SMALL COLON;Po;0;CS;<small> 003A;;;;N;;;;;
+FE56;SMALL QUESTION MARK;Po;0;ON;<small> 003F;;;;N;;;;;
+FE57;SMALL EXCLAMATION MARK;Po;0;ON;<small> 0021;;;;N;;;;;
+FE58;SMALL EM DASH;Pd;0;ON;<small> 2014;;;;N;;;;;
+FE59;SMALL LEFT PARENTHESIS;Ps;0;ON;<small> 0028;;;;Y;SMALL OPENING PARENTHESIS;;;;
+FE5A;SMALL RIGHT PARENTHESIS;Pe;0;ON;<small> 0029;;;;Y;SMALL CLOSING PARENTHESIS;;;;
+FE5B;SMALL LEFT CURLY BRACKET;Ps;0;ON;<small> 007B;;;;Y;SMALL OPENING CURLY BRACKET;;;;
+FE5C;SMALL RIGHT CURLY BRACKET;Pe;0;ON;<small> 007D;;;;Y;SMALL CLOSING CURLY BRACKET;;;;
+FE5D;SMALL LEFT TORTOISE SHELL BRACKET;Ps;0;ON;<small> 3014;;;;Y;SMALL OPENING TORTOISE SHELL BRACKET;;;;
+FE5E;SMALL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;<small> 3015;;;;Y;SMALL CLOSING TORTOISE SHELL BRACKET;;;;
+FE5F;SMALL NUMBER SIGN;Po;0;ET;<small> 0023;;;;N;;;;;
+FE60;SMALL AMPERSAND;Po;0;ON;<small> 0026;;;;N;;;;;
+FE61;SMALL ASTERISK;Po;0;ON;<small> 002A;;;;N;;;;;
+FE62;SMALL PLUS SIGN;Sm;0;ES;<small> 002B;;;;N;;;;;
+FE63;SMALL HYPHEN-MINUS;Pd;0;ES;<small> 002D;;;;N;;;;;
+FE64;SMALL LESS-THAN SIGN;Sm;0;ON;<small> 003C;;;;Y;;;;;
+FE65;SMALL GREATER-THAN SIGN;Sm;0;ON;<small> 003E;;;;Y;;;;;
+FE66;SMALL EQUALS SIGN;Sm;0;ON;<small> 003D;;;;N;;;;;
+FE68;SMALL REVERSE SOLIDUS;Po;0;ON;<small> 005C;;;;N;SMALL BACKSLASH;;;;
+FE69;SMALL DOLLAR SIGN;Sc;0;ET;<small> 0024;;;;N;;;;;
+FE6A;SMALL PERCENT SIGN;Po;0;ET;<small> 0025;;;;N;;;;;
+FE6B;SMALL COMMERCIAL AT;Po;0;ON;<small> 0040;;;;N;;;;;
+FE70;ARABIC FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064B;;;;N;ARABIC SPACING FATHATAN;;;;
+FE71;ARABIC TATWEEL WITH FATHATAN ABOVE;Lo;0;AL;<medial> 0640 064B;;;;N;ARABIC FATHATAN ON TATWEEL;;;;
+FE72;ARABIC DAMMATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064C;;;;N;ARABIC SPACING DAMMATAN;;;;
+FE73;ARABIC TAIL FRAGMENT;Lo;0;AL;;;;;N;;;;;
+FE74;ARABIC KASRATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064D;;;;N;ARABIC SPACING KASRATAN;;;;
+FE76;ARABIC FATHA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064E;;;;N;ARABIC SPACING FATHAH;;;;
+FE77;ARABIC FATHA MEDIAL FORM;Lo;0;AL;<medial> 0640 064E;;;;N;ARABIC FATHAH ON TATWEEL;;;;
+FE78;ARABIC DAMMA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064F;;;;N;ARABIC SPACING DAMMAH;;;;
+FE79;ARABIC DAMMA MEDIAL FORM;Lo;0;AL;<medial> 0640 064F;;;;N;ARABIC DAMMAH ON TATWEEL;;;;
+FE7A;ARABIC KASRA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0650;;;;N;ARABIC SPACING KASRAH;;;;
+FE7B;ARABIC KASRA MEDIAL FORM;Lo;0;AL;<medial> 0640 0650;;;;N;ARABIC KASRAH ON TATWEEL;;;;
+FE7C;ARABIC SHADDA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0651;;;;N;ARABIC SPACING SHADDAH;;;;
+FE7D;ARABIC SHADDA MEDIAL FORM;Lo;0;AL;<medial> 0640 0651;;;;N;ARABIC SHADDAH ON TATWEEL;;;;
+FE7E;ARABIC SUKUN ISOLATED FORM;Lo;0;AL;<isolated> 0020 0652;;;;N;ARABIC SPACING SUKUN;;;;
+FE7F;ARABIC SUKUN MEDIAL FORM;Lo;0;AL;<medial> 0640 0652;;;;N;ARABIC SUKUN ON TATWEEL;;;;
+FE80;ARABIC LETTER HAMZA ISOLATED FORM;Lo;0;AL;<isolated> 0621;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH;;;;
+FE81;ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON ALEF;;;;
+FE82;ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL;<final> 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON ALEF;;;;
+FE83;ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON ALEF;;;;
+FE84;ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON ALEF;;;;
+FE85;ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0624;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON WAW;;;;
+FE86;ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0624;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON WAW;;;;
+FE87;ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL;<isolated> 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER ALEF;;;;
+FE88;ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL;<final> 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER ALEF;;;;
+FE89;ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0626;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON YA;;;;
+FE8A;ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0626;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON YA;;;;
+FE8B;ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM;Lo;0;AL;<initial> 0626;;;;N;GLYPH FOR INITIAL ARABIC HAMZAH ON YA;;;;
+FE8C;ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM;Lo;0;AL;<medial> 0626;;;;N;GLYPH FOR MEDIAL ARABIC HAMZAH ON YA;;;;
+FE8D;ARABIC LETTER ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0627;;;;N;GLYPH FOR ISOLATE ARABIC ALEF;;;;
+FE8E;ARABIC LETTER ALEF FINAL FORM;Lo;0;AL;<final> 0627;;;;N;GLYPH FOR FINAL ARABIC ALEF;;;;
+FE8F;ARABIC LETTER BEH ISOLATED FORM;Lo;0;AL;<isolated> 0628;;;;N;GLYPH FOR ISOLATE ARABIC BAA;;;;
+FE90;ARABIC LETTER BEH FINAL FORM;Lo;0;AL;<final> 0628;;;;N;GLYPH FOR FINAL ARABIC BAA;;;;
+FE91;ARABIC LETTER BEH INITIAL FORM;Lo;0;AL;<initial> 0628;;;;N;GLYPH FOR INITIAL ARABIC BAA;;;;
+FE92;ARABIC LETTER BEH MEDIAL FORM;Lo;0;AL;<medial> 0628;;;;N;GLYPH FOR MEDIAL ARABIC BAA;;;;
+FE93;ARABIC LETTER TEH MARBUTA ISOLATED FORM;Lo;0;AL;<isolated> 0629;;;;N;GLYPH FOR ISOLATE ARABIC TAA MARBUTAH;;;;
+FE94;ARABIC LETTER TEH MARBUTA FINAL FORM;Lo;0;AL;<final> 0629;;;;N;GLYPH FOR FINAL ARABIC TAA MARBUTAH;;;;
+FE95;ARABIC LETTER TEH ISOLATED FORM;Lo;0;AL;<isolated> 062A;;;;N;GLYPH FOR ISOLATE ARABIC TAA;;;;
+FE96;ARABIC LETTER TEH FINAL FORM;Lo;0;AL;<final> 062A;;;;N;GLYPH FOR FINAL ARABIC TAA;;;;
+FE97;ARABIC LETTER TEH INITIAL FORM;Lo;0;AL;<initial> 062A;;;;N;GLYPH FOR INITIAL ARABIC TAA;;;;
+FE98;ARABIC LETTER TEH MEDIAL FORM;Lo;0;AL;<medial> 062A;;;;N;GLYPH FOR MEDIAL ARABIC TAA;;;;
+FE99;ARABIC LETTER THEH ISOLATED FORM;Lo;0;AL;<isolated> 062B;;;;N;GLYPH FOR ISOLATE ARABIC THAA;;;;
+FE9A;ARABIC LETTER THEH FINAL FORM;Lo;0;AL;<final> 062B;;;;N;GLYPH FOR FINAL ARABIC THAA;;;;
+FE9B;ARABIC LETTER THEH INITIAL FORM;Lo;0;AL;<initial> 062B;;;;N;GLYPH FOR INITIAL ARABIC THAA;;;;
+FE9C;ARABIC LETTER THEH MEDIAL FORM;Lo;0;AL;<medial> 062B;;;;N;GLYPH FOR MEDIAL ARABIC THAA;;;;
+FE9D;ARABIC LETTER JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062C;;;;N;GLYPH FOR ISOLATE ARABIC JEEM;;;;
+FE9E;ARABIC LETTER JEEM FINAL FORM;Lo;0;AL;<final> 062C;;;;N;GLYPH FOR FINAL ARABIC JEEM;;;;
+FE9F;ARABIC LETTER JEEM INITIAL FORM;Lo;0;AL;<initial> 062C;;;;N;GLYPH FOR INITIAL ARABIC JEEM;;;;
+FEA0;ARABIC LETTER JEEM MEDIAL FORM;Lo;0;AL;<medial> 062C;;;;N;GLYPH FOR MEDIAL ARABIC JEEM;;;;
+FEA1;ARABIC LETTER HAH ISOLATED FORM;Lo;0;AL;<isolated> 062D;;;;N;GLYPH FOR ISOLATE ARABIC HAA;;;;
+FEA2;ARABIC LETTER HAH FINAL FORM;Lo;0;AL;<final> 062D;;;;N;GLYPH FOR FINAL ARABIC HAA;;;;
+FEA3;ARABIC LETTER HAH INITIAL FORM;Lo;0;AL;<initial> 062D;;;;N;GLYPH FOR INITIAL ARABIC HAA;;;;
+FEA4;ARABIC LETTER HAH MEDIAL FORM;Lo;0;AL;<medial> 062D;;;;N;GLYPH FOR MEDIAL ARABIC HAA;;;;
+FEA5;ARABIC LETTER KHAH ISOLATED FORM;Lo;0;AL;<isolated> 062E;;;;N;GLYPH FOR ISOLATE ARABIC KHAA;;;;
+FEA6;ARABIC LETTER KHAH FINAL FORM;Lo;0;AL;<final> 062E;;;;N;GLYPH FOR FINAL ARABIC KHAA;;;;
+FEA7;ARABIC LETTER KHAH INITIAL FORM;Lo;0;AL;<initial> 062E;;;;N;GLYPH FOR INITIAL ARABIC KHAA;;;;
+FEA8;ARABIC LETTER KHAH MEDIAL FORM;Lo;0;AL;<medial> 062E;;;;N;GLYPH FOR MEDIAL ARABIC KHAA;;;;
+FEA9;ARABIC LETTER DAL ISOLATED FORM;Lo;0;AL;<isolated> 062F;;;;N;GLYPH FOR ISOLATE ARABIC DAL;;;;
+FEAA;ARABIC LETTER DAL FINAL FORM;Lo;0;AL;<final> 062F;;;;N;GLYPH FOR FINAL ARABIC DAL;;;;
+FEAB;ARABIC LETTER THAL ISOLATED FORM;Lo;0;AL;<isolated> 0630;;;;N;GLYPH FOR ISOLATE ARABIC THAL;;;;
+FEAC;ARABIC LETTER THAL FINAL FORM;Lo;0;AL;<final> 0630;;;;N;GLYPH FOR FINAL ARABIC THAL;;;;
+FEAD;ARABIC LETTER REH ISOLATED FORM;Lo;0;AL;<isolated> 0631;;;;N;GLYPH FOR ISOLATE ARABIC RA;;;;
+FEAE;ARABIC LETTER REH FINAL FORM;Lo;0;AL;<final> 0631;;;;N;GLYPH FOR FINAL ARABIC RA;;;;
+FEAF;ARABIC LETTER ZAIN ISOLATED FORM;Lo;0;AL;<isolated> 0632;;;;N;GLYPH FOR ISOLATE ARABIC ZAIN;;;;
+FEB0;ARABIC LETTER ZAIN FINAL FORM;Lo;0;AL;<final> 0632;;;;N;GLYPH FOR FINAL ARABIC ZAIN;;;;
+FEB1;ARABIC LETTER SEEN ISOLATED FORM;Lo;0;AL;<isolated> 0633;;;;N;GLYPH FOR ISOLATE ARABIC SEEN;;;;
+FEB2;ARABIC LETTER SEEN FINAL FORM;Lo;0;AL;<final> 0633;;;;N;GLYPH FOR FINAL ARABIC SEEN;;;;
+FEB3;ARABIC LETTER SEEN INITIAL FORM;Lo;0;AL;<initial> 0633;;;;N;GLYPH FOR INITIAL ARABIC SEEN;;;;
+FEB4;ARABIC LETTER SEEN MEDIAL FORM;Lo;0;AL;<medial> 0633;;;;N;GLYPH FOR MEDIAL ARABIC SEEN;;;;
+FEB5;ARABIC LETTER SHEEN ISOLATED FORM;Lo;0;AL;<isolated> 0634;;;;N;GLYPH FOR ISOLATE ARABIC SHEEN;;;;
+FEB6;ARABIC LETTER SHEEN FINAL FORM;Lo;0;AL;<final> 0634;;;;N;GLYPH FOR FINAL ARABIC SHEEN;;;;
+FEB7;ARABIC LETTER SHEEN INITIAL FORM;Lo;0;AL;<initial> 0634;;;;N;GLYPH FOR INITIAL ARABIC SHEEN;;;;
+FEB8;ARABIC LETTER SHEEN MEDIAL FORM;Lo;0;AL;<medial> 0634;;;;N;GLYPH FOR MEDIAL ARABIC SHEEN;;;;
+FEB9;ARABIC LETTER SAD ISOLATED FORM;Lo;0;AL;<isolated> 0635;;;;N;GLYPH FOR ISOLATE ARABIC SAD;;;;
+FEBA;ARABIC LETTER SAD FINAL FORM;Lo;0;AL;<final> 0635;;;;N;GLYPH FOR FINAL ARABIC SAD;;;;
+FEBB;ARABIC LETTER SAD INITIAL FORM;Lo;0;AL;<initial> 0635;;;;N;GLYPH FOR INITIAL ARABIC SAD;;;;
+FEBC;ARABIC LETTER SAD MEDIAL FORM;Lo;0;AL;<medial> 0635;;;;N;GLYPH FOR MEDIAL ARABIC SAD;;;;
+FEBD;ARABIC LETTER DAD ISOLATED FORM;Lo;0;AL;<isolated> 0636;;;;N;GLYPH FOR ISOLATE ARABIC DAD;;;;
+FEBE;ARABIC LETTER DAD FINAL FORM;Lo;0;AL;<final> 0636;;;;N;GLYPH FOR FINAL ARABIC DAD;;;;
+FEBF;ARABIC LETTER DAD INITIAL FORM;Lo;0;AL;<initial> 0636;;;;N;GLYPH FOR INITIAL ARABIC DAD;;;;
+FEC0;ARABIC LETTER DAD MEDIAL FORM;Lo;0;AL;<medial> 0636;;;;N;GLYPH FOR MEDIAL ARABIC DAD;;;;
+FEC1;ARABIC LETTER TAH ISOLATED FORM;Lo;0;AL;<isolated> 0637;;;;N;GLYPH FOR ISOLATE ARABIC TAH;;;;
+FEC2;ARABIC LETTER TAH FINAL FORM;Lo;0;AL;<final> 0637;;;;N;GLYPH FOR FINAL ARABIC TAH;;;;
+FEC3;ARABIC LETTER TAH INITIAL FORM;Lo;0;AL;<initial> 0637;;;;N;GLYPH FOR INITIAL ARABIC TAH;;;;
+FEC4;ARABIC LETTER TAH MEDIAL FORM;Lo;0;AL;<medial> 0637;;;;N;GLYPH FOR MEDIAL ARABIC TAH;;;;
+FEC5;ARABIC LETTER ZAH ISOLATED FORM;Lo;0;AL;<isolated> 0638;;;;N;GLYPH FOR ISOLATE ARABIC DHAH;;;;
+FEC6;ARABIC LETTER ZAH FINAL FORM;Lo;0;AL;<final> 0638;;;;N;GLYPH FOR FINAL ARABIC DHAH;;;;
+FEC7;ARABIC LETTER ZAH INITIAL FORM;Lo;0;AL;<initial> 0638;;;;N;GLYPH FOR INITIAL ARABIC DHAH;;;;
+FEC8;ARABIC LETTER ZAH MEDIAL FORM;Lo;0;AL;<medial> 0638;;;;N;GLYPH FOR MEDIAL ARABIC DHAH;;;;
+FEC9;ARABIC LETTER AIN ISOLATED FORM;Lo;0;AL;<isolated> 0639;;;;N;GLYPH FOR ISOLATE ARABIC AIN;;;;
+FECA;ARABIC LETTER AIN FINAL FORM;Lo;0;AL;<final> 0639;;;;N;GLYPH FOR FINAL ARABIC AIN;;;;
+FECB;ARABIC LETTER AIN INITIAL FORM;Lo;0;AL;<initial> 0639;;;;N;GLYPH FOR INITIAL ARABIC AIN;;;;
+FECC;ARABIC LETTER AIN MEDIAL FORM;Lo;0;AL;<medial> 0639;;;;N;GLYPH FOR MEDIAL ARABIC AIN;;;;
+FECD;ARABIC LETTER GHAIN ISOLATED FORM;Lo;0;AL;<isolated> 063A;;;;N;GLYPH FOR ISOLATE ARABIC GHAIN;;;;
+FECE;ARABIC LETTER GHAIN FINAL FORM;Lo;0;AL;<final> 063A;;;;N;GLYPH FOR FINAL ARABIC GHAIN;;;;
+FECF;ARABIC LETTER GHAIN INITIAL FORM;Lo;0;AL;<initial> 063A;;;;N;GLYPH FOR INITIAL ARABIC GHAIN;;;;
+FED0;ARABIC LETTER GHAIN MEDIAL FORM;Lo;0;AL;<medial> 063A;;;;N;GLYPH FOR MEDIAL ARABIC GHAIN;;;;
+FED1;ARABIC LETTER FEH ISOLATED FORM;Lo;0;AL;<isolated> 0641;;;;N;GLYPH FOR ISOLATE ARABIC FA;;;;
+FED2;ARABIC LETTER FEH FINAL FORM;Lo;0;AL;<final> 0641;;;;N;GLYPH FOR FINAL ARABIC FA;;;;
+FED3;ARABIC LETTER FEH INITIAL FORM;Lo;0;AL;<initial> 0641;;;;N;GLYPH FOR INITIAL ARABIC FA;;;;
+FED4;ARABIC LETTER FEH MEDIAL FORM;Lo;0;AL;<medial> 0641;;;;N;GLYPH FOR MEDIAL ARABIC FA;;;;
+FED5;ARABIC LETTER QAF ISOLATED FORM;Lo;0;AL;<isolated> 0642;;;;N;GLYPH FOR ISOLATE ARABIC QAF;;;;
+FED6;ARABIC LETTER QAF FINAL FORM;Lo;0;AL;<final> 0642;;;;N;GLYPH FOR FINAL ARABIC QAF;;;;
+FED7;ARABIC LETTER QAF INITIAL FORM;Lo;0;AL;<initial> 0642;;;;N;GLYPH FOR INITIAL ARABIC QAF;;;;
+FED8;ARABIC LETTER QAF MEDIAL FORM;Lo;0;AL;<medial> 0642;;;;N;GLYPH FOR MEDIAL ARABIC QAF;;;;
+FED9;ARABIC LETTER KAF ISOLATED FORM;Lo;0;AL;<isolated> 0643;;;;N;GLYPH FOR ISOLATE ARABIC CAF;;;;
+FEDA;ARABIC LETTER KAF FINAL FORM;Lo;0;AL;<final> 0643;;;;N;GLYPH FOR FINAL ARABIC CAF;;;;
+FEDB;ARABIC LETTER KAF INITIAL FORM;Lo;0;AL;<initial> 0643;;;;N;GLYPH FOR INITIAL ARABIC CAF;;;;
+FEDC;ARABIC LETTER KAF MEDIAL FORM;Lo;0;AL;<medial> 0643;;;;N;GLYPH FOR MEDIAL ARABIC CAF;;;;
+FEDD;ARABIC LETTER LAM ISOLATED FORM;Lo;0;AL;<isolated> 0644;;;;N;GLYPH FOR ISOLATE ARABIC LAM;;;;
+FEDE;ARABIC LETTER LAM FINAL FORM;Lo;0;AL;<final> 0644;;;;N;GLYPH FOR FINAL ARABIC LAM;;;;
+FEDF;ARABIC LETTER LAM INITIAL FORM;Lo;0;AL;<initial> 0644;;;;N;GLYPH FOR INITIAL ARABIC LAM;;;;
+FEE0;ARABIC LETTER LAM MEDIAL FORM;Lo;0;AL;<medial> 0644;;;;N;GLYPH FOR MEDIAL ARABIC LAM;;;;
+FEE1;ARABIC LETTER MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645;;;;N;GLYPH FOR ISOLATE ARABIC MEEM;;;;
+FEE2;ARABIC LETTER MEEM FINAL FORM;Lo;0;AL;<final> 0645;;;;N;GLYPH FOR FINAL ARABIC MEEM;;;;
+FEE3;ARABIC LETTER MEEM INITIAL FORM;Lo;0;AL;<initial> 0645;;;;N;GLYPH FOR INITIAL ARABIC MEEM;;;;
+FEE4;ARABIC LETTER MEEM MEDIAL FORM;Lo;0;AL;<medial> 0645;;;;N;GLYPH FOR MEDIAL ARABIC MEEM;;;;
+FEE5;ARABIC LETTER NOON ISOLATED FORM;Lo;0;AL;<isolated> 0646;;;;N;GLYPH FOR ISOLATE ARABIC NOON;;;;
+FEE6;ARABIC LETTER NOON FINAL FORM;Lo;0;AL;<final> 0646;;;;N;GLYPH FOR FINAL ARABIC NOON;;;;
+FEE7;ARABIC LETTER NOON INITIAL FORM;Lo;0;AL;<initial> 0646;;;;N;GLYPH FOR INITIAL ARABIC NOON;;;;
+FEE8;ARABIC LETTER NOON MEDIAL FORM;Lo;0;AL;<medial> 0646;;;;N;GLYPH FOR MEDIAL ARABIC NOON;;;;
+FEE9;ARABIC LETTER HEH ISOLATED FORM;Lo;0;AL;<isolated> 0647;;;;N;GLYPH FOR ISOLATE ARABIC HA;;;;
+FEEA;ARABIC LETTER HEH FINAL FORM;Lo;0;AL;<final> 0647;;;;N;GLYPH FOR FINAL ARABIC HA;;;;
+FEEB;ARABIC LETTER HEH INITIAL FORM;Lo;0;AL;<initial> 0647;;;;N;GLYPH FOR INITIAL ARABIC HA;;;;
+FEEC;ARABIC LETTER HEH MEDIAL FORM;Lo;0;AL;<medial> 0647;;;;N;GLYPH FOR MEDIAL ARABIC HA;;;;
+FEED;ARABIC LETTER WAW ISOLATED FORM;Lo;0;AL;<isolated> 0648;;;;N;GLYPH FOR ISOLATE ARABIC WAW;;;;
+FEEE;ARABIC LETTER WAW FINAL FORM;Lo;0;AL;<final> 0648;;;;N;GLYPH FOR FINAL ARABIC WAW;;;;
+FEEF;ARABIC LETTER ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0649;;;;N;GLYPH FOR ISOLATE ARABIC ALEF MAQSURAH;;;;
+FEF0;ARABIC LETTER ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0649;;;;N;GLYPH FOR FINAL ARABIC ALEF MAQSURAH;;;;
+FEF1;ARABIC LETTER YEH ISOLATED FORM;Lo;0;AL;<isolated> 064A;;;;N;GLYPH FOR ISOLATE ARABIC YA;;;;
+FEF2;ARABIC LETTER YEH FINAL FORM;Lo;0;AL;<final> 064A;;;;N;GLYPH FOR FINAL ARABIC YA;;;;
+FEF3;ARABIC LETTER YEH INITIAL FORM;Lo;0;AL;<initial> 064A;;;;N;GLYPH FOR INITIAL ARABIC YA;;;;
+FEF4;ARABIC LETTER YEH MEDIAL FORM;Lo;0;AL;<medial> 064A;;;;N;GLYPH FOR MEDIAL ARABIC YA;;;;
+FEF5;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0644 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON LIGATURE LAM ALEF;;;;
+FEF6;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL;<final> 0644 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON LIGATURE LAM ALEF;;;;
+FEF7;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0644 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON LIGATURE LAM ALEF;;;;
+FEF8;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0644 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON LIGATURE LAM ALEF;;;;
+FEF9;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL;<isolated> 0644 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;;
+FEFA;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL;<final> 0644 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;;
+FEFB;ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0644 0627;;;;N;GLYPH FOR ISOLATE ARABIC LIGATURE LAM ALEF;;;;
+FEFC;ARABIC LIGATURE LAM WITH ALEF FINAL FORM;Lo;0;AL;<final> 0644 0627;;;;N;GLYPH FOR FINAL ARABIC LIGATURE LAM ALEF;;;;
+FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;;
+FF01;FULLWIDTH EXCLAMATION MARK;Po;0;ON;<wide> 0021;;;;N;;;;;
+FF02;FULLWIDTH QUOTATION MARK;Po;0;ON;<wide> 0022;;;;N;;;;;
+FF03;FULLWIDTH NUMBER SIGN;Po;0;ET;<wide> 0023;;;;N;;;;;
+FF04;FULLWIDTH DOLLAR SIGN;Sc;0;ET;<wide> 0024;;;;N;;;;;
+FF05;FULLWIDTH PERCENT SIGN;Po;0;ET;<wide> 0025;;;;N;;;;;
+FF06;FULLWIDTH AMPERSAND;Po;0;ON;<wide> 0026;;;;N;;;;;
+FF07;FULLWIDTH APOSTROPHE;Po;0;ON;<wide> 0027;;;;N;;;;;
+FF08;FULLWIDTH LEFT PARENTHESIS;Ps;0;ON;<wide> 0028;;;;Y;FULLWIDTH OPENING PARENTHESIS;;;;
+FF09;FULLWIDTH RIGHT PARENTHESIS;Pe;0;ON;<wide> 0029;;;;Y;FULLWIDTH CLOSING PARENTHESIS;;;;
+FF0A;FULLWIDTH ASTERISK;Po;0;ON;<wide> 002A;;;;N;;;;;
+FF0B;FULLWIDTH PLUS SIGN;Sm;0;ES;<wide> 002B;;;;N;;;;;
+FF0C;FULLWIDTH COMMA;Po;0;CS;<wide> 002C;;;;N;;;;;
+FF0D;FULLWIDTH HYPHEN-MINUS;Pd;0;ES;<wide> 002D;;;;N;;;;;
+FF0E;FULLWIDTH FULL STOP;Po;0;CS;<wide> 002E;;;;N;FULLWIDTH PERIOD;;;;
+FF0F;FULLWIDTH SOLIDUS;Po;0;CS;<wide> 002F;;;;N;FULLWIDTH SLASH;;;;
+FF10;FULLWIDTH DIGIT ZERO;Nd;0;EN;<wide> 0030;0;0;0;N;;;;;
+FF11;FULLWIDTH DIGIT ONE;Nd;0;EN;<wide> 0031;1;1;1;N;;;;;
+FF12;FULLWIDTH DIGIT TWO;Nd;0;EN;<wide> 0032;2;2;2;N;;;;;
+FF13;FULLWIDTH DIGIT THREE;Nd;0;EN;<wide> 0033;3;3;3;N;;;;;
+FF14;FULLWIDTH DIGIT FOUR;Nd;0;EN;<wide> 0034;4;4;4;N;;;;;
+FF15;FULLWIDTH DIGIT FIVE;Nd;0;EN;<wide> 0035;5;5;5;N;;;;;
+FF16;FULLWIDTH DIGIT SIX;Nd;0;EN;<wide> 0036;6;6;6;N;;;;;
+FF17;FULLWIDTH DIGIT SEVEN;Nd;0;EN;<wide> 0037;7;7;7;N;;;;;
+FF18;FULLWIDTH DIGIT EIGHT;Nd;0;EN;<wide> 0038;8;8;8;N;;;;;
+FF19;FULLWIDTH DIGIT NINE;Nd;0;EN;<wide> 0039;9;9;9;N;;;;;
+FF1A;FULLWIDTH COLON;Po;0;CS;<wide> 003A;;;;N;;;;;
+FF1B;FULLWIDTH SEMICOLON;Po;0;ON;<wide> 003B;;;;N;;;;;
+FF1C;FULLWIDTH LESS-THAN SIGN;Sm;0;ON;<wide> 003C;;;;Y;;;;;
+FF1D;FULLWIDTH EQUALS SIGN;Sm;0;ON;<wide> 003D;;;;N;;;;;
+FF1E;FULLWIDTH GREATER-THAN SIGN;Sm;0;ON;<wide> 003E;;;;Y;;;;;
+FF1F;FULLWIDTH QUESTION MARK;Po;0;ON;<wide> 003F;;;;N;;;;;
+FF20;FULLWIDTH COMMERCIAL AT;Po;0;ON;<wide> 0040;;;;N;;;;;
+FF21;FULLWIDTH LATIN CAPITAL LETTER A;Lu;0;L;<wide> 0041;;;;N;;;;FF41;
+FF22;FULLWIDTH LATIN CAPITAL LETTER B;Lu;0;L;<wide> 0042;;;;N;;;;FF42;
+FF23;FULLWIDTH LATIN CAPITAL LETTER C;Lu;0;L;<wide> 0043;;;;N;;;;FF43;
+FF24;FULLWIDTH LATIN CAPITAL LETTER D;Lu;0;L;<wide> 0044;;;;N;;;;FF44;
+FF25;FULLWIDTH LATIN CAPITAL LETTER E;Lu;0;L;<wide> 0045;;;;N;;;;FF45;
+FF26;FULLWIDTH LATIN CAPITAL LETTER F;Lu;0;L;<wide> 0046;;;;N;;;;FF46;
+FF27;FULLWIDTH LATIN CAPITAL LETTER G;Lu;0;L;<wide> 0047;;;;N;;;;FF47;
+FF28;FULLWIDTH LATIN CAPITAL LETTER H;Lu;0;L;<wide> 0048;;;;N;;;;FF48;
+FF29;FULLWIDTH LATIN CAPITAL LETTER I;Lu;0;L;<wide> 0049;;;;N;;;;FF49;
+FF2A;FULLWIDTH LATIN CAPITAL LETTER J;Lu;0;L;<wide> 004A;;;;N;;;;FF4A;
+FF2B;FULLWIDTH LATIN CAPITAL LETTER K;Lu;0;L;<wide> 004B;;;;N;;;;FF4B;
+FF2C;FULLWIDTH LATIN CAPITAL LETTER L;Lu;0;L;<wide> 004C;;;;N;;;;FF4C;
+FF2D;FULLWIDTH LATIN CAPITAL LETTER M;Lu;0;L;<wide> 004D;;;;N;;;;FF4D;
+FF2E;FULLWIDTH LATIN CAPITAL LETTER N;Lu;0;L;<wide> 004E;;;;N;;;;FF4E;
+FF2F;FULLWIDTH LATIN CAPITAL LETTER O;Lu;0;L;<wide> 004F;;;;N;;;;FF4F;
+FF30;FULLWIDTH LATIN CAPITAL LETTER P;Lu;0;L;<wide> 0050;;;;N;;;;FF50;
+FF31;FULLWIDTH LATIN CAPITAL LETTER Q;Lu;0;L;<wide> 0051;;;;N;;;;FF51;
+FF32;FULLWIDTH LATIN CAPITAL LETTER R;Lu;0;L;<wide> 0052;;;;N;;;;FF52;
+FF33;FULLWIDTH LATIN CAPITAL LETTER S;Lu;0;L;<wide> 0053;;;;N;;;;FF53;
+FF34;FULLWIDTH LATIN CAPITAL LETTER T;Lu;0;L;<wide> 0054;;;;N;;;;FF54;
+FF35;FULLWIDTH LATIN CAPITAL LETTER U;Lu;0;L;<wide> 0055;;;;N;;;;FF55;
+FF36;FULLWIDTH LATIN CAPITAL LETTER V;Lu;0;L;<wide> 0056;;;;N;;;;FF56;
+FF37;FULLWIDTH LATIN CAPITAL LETTER W;Lu;0;L;<wide> 0057;;;;N;;;;FF57;
+FF38;FULLWIDTH LATIN CAPITAL LETTER X;Lu;0;L;<wide> 0058;;;;N;;;;FF58;
+FF39;FULLWIDTH LATIN CAPITAL LETTER Y;Lu;0;L;<wide> 0059;;;;N;;;;FF59;
+FF3A;FULLWIDTH LATIN CAPITAL LETTER Z;Lu;0;L;<wide> 005A;;;;N;;;;FF5A;
+FF3B;FULLWIDTH LEFT SQUARE BRACKET;Ps;0;ON;<wide> 005B;;;;Y;FULLWIDTH OPENING SQUARE BRACKET;;;;
+FF3C;FULLWIDTH REVERSE SOLIDUS;Po;0;ON;<wide> 005C;;;;N;FULLWIDTH BACKSLASH;;;;
+FF3D;FULLWIDTH RIGHT SQUARE BRACKET;Pe;0;ON;<wide> 005D;;;;Y;FULLWIDTH CLOSING SQUARE BRACKET;;;;
+FF3E;FULLWIDTH CIRCUMFLEX ACCENT;Sk;0;ON;<wide> 005E;;;;N;FULLWIDTH SPACING CIRCUMFLEX;;;;
+FF3F;FULLWIDTH LOW LINE;Pc;0;ON;<wide> 005F;;;;N;FULLWIDTH SPACING UNDERSCORE;;;;
+FF40;FULLWIDTH GRAVE ACCENT;Sk;0;ON;<wide> 0060;;;;N;FULLWIDTH SPACING GRAVE;;;;
+FF41;FULLWIDTH LATIN SMALL LETTER A;Ll;0;L;<wide> 0061;;;;N;;;FF21;;FF21
+FF42;FULLWIDTH LATIN SMALL LETTER B;Ll;0;L;<wide> 0062;;;;N;;;FF22;;FF22
+FF43;FULLWIDTH LATIN SMALL LETTER C;Ll;0;L;<wide> 0063;;;;N;;;FF23;;FF23
+FF44;FULLWIDTH LATIN SMALL LETTER D;Ll;0;L;<wide> 0064;;;;N;;;FF24;;FF24
+FF45;FULLWIDTH LATIN SMALL LETTER E;Ll;0;L;<wide> 0065;;;;N;;;FF25;;FF25
+FF46;FULLWIDTH LATIN SMALL LETTER F;Ll;0;L;<wide> 0066;;;;N;;;FF26;;FF26
+FF47;FULLWIDTH LATIN SMALL LETTER G;Ll;0;L;<wide> 0067;;;;N;;;FF27;;FF27
+FF48;FULLWIDTH LATIN SMALL LETTER H;Ll;0;L;<wide> 0068;;;;N;;;FF28;;FF28
+FF49;FULLWIDTH LATIN SMALL LETTER I;Ll;0;L;<wide> 0069;;;;N;;;FF29;;FF29
+FF4A;FULLWIDTH LATIN SMALL LETTER J;Ll;0;L;<wide> 006A;;;;N;;;FF2A;;FF2A
+FF4B;FULLWIDTH LATIN SMALL LETTER K;Ll;0;L;<wide> 006B;;;;N;;;FF2B;;FF2B
+FF4C;FULLWIDTH LATIN SMALL LETTER L;Ll;0;L;<wide> 006C;;;;N;;;FF2C;;FF2C
+FF4D;FULLWIDTH LATIN SMALL LETTER M;Ll;0;L;<wide> 006D;;;;N;;;FF2D;;FF2D
+FF4E;FULLWIDTH LATIN SMALL LETTER N;Ll;0;L;<wide> 006E;;;;N;;;FF2E;;FF2E
+FF4F;FULLWIDTH LATIN SMALL LETTER O;Ll;0;L;<wide> 006F;;;;N;;;FF2F;;FF2F
+FF50;FULLWIDTH LATIN SMALL LETTER P;Ll;0;L;<wide> 0070;;;;N;;;FF30;;FF30
+FF51;FULLWIDTH LATIN SMALL LETTER Q;Ll;0;L;<wide> 0071;;;;N;;;FF31;;FF31
+FF52;FULLWIDTH LATIN SMALL LETTER R;Ll;0;L;<wide> 0072;;;;N;;;FF32;;FF32
+FF53;FULLWIDTH LATIN SMALL LETTER S;Ll;0;L;<wide> 0073;;;;N;;;FF33;;FF33
+FF54;FULLWIDTH LATIN SMALL LETTER T;Ll;0;L;<wide> 0074;;;;N;;;FF34;;FF34
+FF55;FULLWIDTH LATIN SMALL LETTER U;Ll;0;L;<wide> 0075;;;;N;;;FF35;;FF35
+FF56;FULLWIDTH LATIN SMALL LETTER V;Ll;0;L;<wide> 0076;;;;N;;;FF36;;FF36
+FF57;FULLWIDTH LATIN SMALL LETTER W;Ll;0;L;<wide> 0077;;;;N;;;FF37;;FF37
+FF58;FULLWIDTH LATIN SMALL LETTER X;Ll;0;L;<wide> 0078;;;;N;;;FF38;;FF38
+FF59;FULLWIDTH LATIN SMALL LETTER Y;Ll;0;L;<wide> 0079;;;;N;;;FF39;;FF39
+FF5A;FULLWIDTH LATIN SMALL LETTER Z;Ll;0;L;<wide> 007A;;;;N;;;FF3A;;FF3A
+FF5B;FULLWIDTH LEFT CURLY BRACKET;Ps;0;ON;<wide> 007B;;;;Y;FULLWIDTH OPENING CURLY BRACKET;;;;
+FF5C;FULLWIDTH VERTICAL LINE;Sm;0;ON;<wide> 007C;;;;N;FULLWIDTH VERTICAL BAR;;;;
+FF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe;0;ON;<wide> 007D;;;;Y;FULLWIDTH CLOSING CURLY BRACKET;;;;
+FF5E;FULLWIDTH TILDE;Sm;0;ON;<wide> 007E;;;;N;FULLWIDTH SPACING TILDE;;;;
+FF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps;0;ON;<wide> 2985;;;;Y;;;;;
+FF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe;0;ON;<wide> 2986;;;;Y;;;;;
+FF61;HALFWIDTH IDEOGRAPHIC FULL STOP;Po;0;ON;<narrow> 3002;;;;N;HALFWIDTH IDEOGRAPHIC PERIOD;;;;
+FF62;HALFWIDTH LEFT CORNER BRACKET;Ps;0;ON;<narrow> 300C;;;;Y;HALFWIDTH OPENING CORNER BRACKET;;;;
+FF63;HALFWIDTH RIGHT CORNER BRACKET;Pe;0;ON;<narrow> 300D;;;;Y;HALFWIDTH CLOSING CORNER BRACKET;;;;
+FF64;HALFWIDTH IDEOGRAPHIC COMMA;Po;0;ON;<narrow> 3001;;;;N;;;;;
+FF65;HALFWIDTH KATAKANA MIDDLE DOT;Po;0;ON;<narrow> 30FB;;;;N;;;;;
+FF66;HALFWIDTH KATAKANA LETTER WO;Lo;0;L;<narrow> 30F2;;;;N;;;;;
+FF67;HALFWIDTH KATAKANA LETTER SMALL A;Lo;0;L;<narrow> 30A1;;;;N;;;;;
+FF68;HALFWIDTH KATAKANA LETTER SMALL I;Lo;0;L;<narrow> 30A3;;;;N;;;;;
+FF69;HALFWIDTH KATAKANA LETTER SMALL U;Lo;0;L;<narrow> 30A5;;;;N;;;;;
+FF6A;HALFWIDTH KATAKANA LETTER SMALL E;Lo;0;L;<narrow> 30A7;;;;N;;;;;
+FF6B;HALFWIDTH KATAKANA LETTER SMALL O;Lo;0;L;<narrow> 30A9;;;;N;;;;;
+FF6C;HALFWIDTH KATAKANA LETTER SMALL YA;Lo;0;L;<narrow> 30E3;;;;N;;;;;
+FF6D;HALFWIDTH KATAKANA LETTER SMALL YU;Lo;0;L;<narrow> 30E5;;;;N;;;;;
+FF6E;HALFWIDTH KATAKANA LETTER SMALL YO;Lo;0;L;<narrow> 30E7;;;;N;;;;;
+FF6F;HALFWIDTH KATAKANA LETTER SMALL TU;Lo;0;L;<narrow> 30C3;;;;N;;;;;
+FF70;HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;<narrow> 30FC;;;;N;;;;;
+FF71;HALFWIDTH KATAKANA LETTER A;Lo;0;L;<narrow> 30A2;;;;N;;;;;
+FF72;HALFWIDTH KATAKANA LETTER I;Lo;0;L;<narrow> 30A4;;;;N;;;;;
+FF73;HALFWIDTH KATAKANA LETTER U;Lo;0;L;<narrow> 30A6;;;;N;;;;;
+FF74;HALFWIDTH KATAKANA LETTER E;Lo;0;L;<narrow> 30A8;;;;N;;;;;
+FF75;HALFWIDTH KATAKANA LETTER O;Lo;0;L;<narrow> 30AA;;;;N;;;;;
+FF76;HALFWIDTH KATAKANA LETTER KA;Lo;0;L;<narrow> 30AB;;;;N;;;;;
+FF77;HALFWIDTH KATAKANA LETTER KI;Lo;0;L;<narrow> 30AD;;;;N;;;;;
+FF78;HALFWIDTH KATAKANA LETTER KU;Lo;0;L;<narrow> 30AF;;;;N;;;;;
+FF79;HALFWIDTH KATAKANA LETTER KE;Lo;0;L;<narrow> 30B1;;;;N;;;;;
+FF7A;HALFWIDTH KATAKANA LETTER KO;Lo;0;L;<narrow> 30B3;;;;N;;;;;
+FF7B;HALFWIDTH KATAKANA LETTER SA;Lo;0;L;<narrow> 30B5;;;;N;;;;;
+FF7C;HALFWIDTH KATAKANA LETTER SI;Lo;0;L;<narrow> 30B7;;;;N;;;;;
+FF7D;HALFWIDTH KATAKANA LETTER SU;Lo;0;L;<narrow> 30B9;;;;N;;;;;
+FF7E;HALFWIDTH KATAKANA LETTER SE;Lo;0;L;<narrow> 30BB;;;;N;;;;;
+FF7F;HALFWIDTH KATAKANA LETTER SO;Lo;0;L;<narrow> 30BD;;;;N;;;;;
+FF80;HALFWIDTH KATAKANA LETTER TA;Lo;0;L;<narrow> 30BF;;;;N;;;;;
+FF81;HALFWIDTH KATAKANA LETTER TI;Lo;0;L;<narrow> 30C1;;;;N;;;;;
+FF82;HALFWIDTH KATAKANA LETTER TU;Lo;0;L;<narrow> 30C4;;;;N;;;;;
+FF83;HALFWIDTH KATAKANA LETTER TE;Lo;0;L;<narrow> 30C6;;;;N;;;;;
+FF84;HALFWIDTH KATAKANA LETTER TO;Lo;0;L;<narrow> 30C8;;;;N;;;;;
+FF85;HALFWIDTH KATAKANA LETTER NA;Lo;0;L;<narrow> 30CA;;;;N;;;;;
+FF86;HALFWIDTH KATAKANA LETTER NI;Lo;0;L;<narrow> 30CB;;;;N;;;;;
+FF87;HALFWIDTH KATAKANA LETTER NU;Lo;0;L;<narrow> 30CC;;;;N;;;;;
+FF88;HALFWIDTH KATAKANA LETTER NE;Lo;0;L;<narrow> 30CD;;;;N;;;;;
+FF89;HALFWIDTH KATAKANA LETTER NO;Lo;0;L;<narrow> 30CE;;;;N;;;;;
+FF8A;HALFWIDTH KATAKANA LETTER HA;Lo;0;L;<narrow> 30CF;;;;N;;;;;
+FF8B;HALFWIDTH KATAKANA LETTER HI;Lo;0;L;<narrow> 30D2;;;;N;;;;;
+FF8C;HALFWIDTH KATAKANA LETTER HU;Lo;0;L;<narrow> 30D5;;;;N;;;;;
+FF8D;HALFWIDTH KATAKANA LETTER HE;Lo;0;L;<narrow> 30D8;;;;N;;;;;
+FF8E;HALFWIDTH KATAKANA LETTER HO;Lo;0;L;<narrow> 30DB;;;;N;;;;;
+FF8F;HALFWIDTH KATAKANA LETTER MA;Lo;0;L;<narrow> 30DE;;;;N;;;;;
+FF90;HALFWIDTH KATAKANA LETTER MI;Lo;0;L;<narrow> 30DF;;;;N;;;;;
+FF91;HALFWIDTH KATAKANA LETTER MU;Lo;0;L;<narrow> 30E0;;;;N;;;;;
+FF92;HALFWIDTH KATAKANA LETTER ME;Lo;0;L;<narrow> 30E1;;;;N;;;;;
+FF93;HALFWIDTH KATAKANA LETTER MO;Lo;0;L;<narrow> 30E2;;;;N;;;;;
+FF94;HALFWIDTH KATAKANA LETTER YA;Lo;0;L;<narrow> 30E4;;;;N;;;;;
+FF95;HALFWIDTH KATAKANA LETTER YU;Lo;0;L;<narrow> 30E6;;;;N;;;;;
+FF96;HALFWIDTH KATAKANA LETTER YO;Lo;0;L;<narrow> 30E8;;;;N;;;;;
+FF97;HALFWIDTH KATAKANA LETTER RA;Lo;0;L;<narrow> 30E9;;;;N;;;;;
+FF98;HALFWIDTH KATAKANA LETTER RI;Lo;0;L;<narrow> 30EA;;;;N;;;;;
+FF99;HALFWIDTH KATAKANA LETTER RU;Lo;0;L;<narrow> 30EB;;;;N;;;;;
+FF9A;HALFWIDTH KATAKANA LETTER RE;Lo;0;L;<narrow> 30EC;;;;N;;;;;
+FF9B;HALFWIDTH KATAKANA LETTER RO;Lo;0;L;<narrow> 30ED;;;;N;;;;;
+FF9C;HALFWIDTH KATAKANA LETTER WA;Lo;0;L;<narrow> 30EF;;;;N;;;;;
+FF9D;HALFWIDTH KATAKANA LETTER N;Lo;0;L;<narrow> 30F3;;;;N;;;;;
+FF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L;<narrow> 3099;;;;N;;;;;
+FF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L;<narrow> 309A;;;;N;;;;;
+FFA0;HALFWIDTH HANGUL FILLER;Lo;0;L;<narrow> 3164;;;;N;HALFWIDTH HANGUL CAE OM;;;;
+FFA1;HALFWIDTH HANGUL LETTER KIYEOK;Lo;0;L;<narrow> 3131;;;;N;HALFWIDTH HANGUL LETTER GIYEOG;;;;
+FFA2;HALFWIDTH HANGUL LETTER SSANGKIYEOK;Lo;0;L;<narrow> 3132;;;;N;HALFWIDTH HANGUL LETTER SSANG GIYEOG;;;;
+FFA3;HALFWIDTH HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<narrow> 3133;;;;N;HALFWIDTH HANGUL LETTER GIYEOG SIOS;;;;
+FFA4;HALFWIDTH HANGUL LETTER NIEUN;Lo;0;L;<narrow> 3134;;;;N;;;;;
+FFA5;HALFWIDTH HANGUL LETTER NIEUN-CIEUC;Lo;0;L;<narrow> 3135;;;;N;HALFWIDTH HANGUL LETTER NIEUN JIEUJ;;;;
+FFA6;HALFWIDTH HANGUL LETTER NIEUN-HIEUH;Lo;0;L;<narrow> 3136;;;;N;HALFWIDTH HANGUL LETTER NIEUN HIEUH;;;;
+FFA7;HALFWIDTH HANGUL LETTER TIKEUT;Lo;0;L;<narrow> 3137;;;;N;HALFWIDTH HANGUL LETTER DIGEUD;;;;
+FFA8;HALFWIDTH HANGUL LETTER SSANGTIKEUT;Lo;0;L;<narrow> 3138;;;;N;HALFWIDTH HANGUL LETTER SSANG DIGEUD;;;;
+FFA9;HALFWIDTH HANGUL LETTER RIEUL;Lo;0;L;<narrow> 3139;;;;N;HALFWIDTH HANGUL LETTER LIEUL;;;;
+FFAA;HALFWIDTH HANGUL LETTER RIEUL-KIYEOK;Lo;0;L;<narrow> 313A;;;;N;HALFWIDTH HANGUL LETTER LIEUL GIYEOG;;;;
+FFAB;HALFWIDTH HANGUL LETTER RIEUL-MIEUM;Lo;0;L;<narrow> 313B;;;;N;HALFWIDTH HANGUL LETTER LIEUL MIEUM;;;;
+FFAC;HALFWIDTH HANGUL LETTER RIEUL-PIEUP;Lo;0;L;<narrow> 313C;;;;N;HALFWIDTH HANGUL LETTER LIEUL BIEUB;;;;
+FFAD;HALFWIDTH HANGUL LETTER RIEUL-SIOS;Lo;0;L;<narrow> 313D;;;;N;HALFWIDTH HANGUL LETTER LIEUL SIOS;;;;
+FFAE;HALFWIDTH HANGUL LETTER RIEUL-THIEUTH;Lo;0;L;<narrow> 313E;;;;N;HALFWIDTH HANGUL LETTER LIEUL TIEUT;;;;
+FFAF;HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L;<narrow> 313F;;;;N;HALFWIDTH HANGUL LETTER LIEUL PIEUP;;;;
+FFB0;HALFWIDTH HANGUL LETTER RIEUL-HIEUH;Lo;0;L;<narrow> 3140;;;;N;HALFWIDTH HANGUL LETTER LIEUL HIEUH;;;;
+FFB1;HALFWIDTH HANGUL LETTER MIEUM;Lo;0;L;<narrow> 3141;;;;N;;;;;
+FFB2;HALFWIDTH HANGUL LETTER PIEUP;Lo;0;L;<narrow> 3142;;;;N;HALFWIDTH HANGUL LETTER BIEUB;;;;
+FFB3;HALFWIDTH HANGUL LETTER SSANGPIEUP;Lo;0;L;<narrow> 3143;;;;N;HALFWIDTH HANGUL LETTER SSANG BIEUB;;;;
+FFB4;HALFWIDTH HANGUL LETTER PIEUP-SIOS;Lo;0;L;<narrow> 3144;;;;N;HALFWIDTH HANGUL LETTER BIEUB SIOS;;;;
+FFB5;HALFWIDTH HANGUL LETTER SIOS;Lo;0;L;<narrow> 3145;;;;N;;;;;
+FFB6;HALFWIDTH HANGUL LETTER SSANGSIOS;Lo;0;L;<narrow> 3146;;;;N;HALFWIDTH HANGUL LETTER SSANG SIOS;;;;
+FFB7;HALFWIDTH HANGUL LETTER IEUNG;Lo;0;L;<narrow> 3147;;;;N;;;;;
+FFB8;HALFWIDTH HANGUL LETTER CIEUC;Lo;0;L;<narrow> 3148;;;;N;HALFWIDTH HANGUL LETTER JIEUJ;;;;
+FFB9;HALFWIDTH HANGUL LETTER SSANGCIEUC;Lo;0;L;<narrow> 3149;;;;N;HALFWIDTH HANGUL LETTER SSANG JIEUJ;;;;
+FFBA;HALFWIDTH HANGUL LETTER CHIEUCH;Lo;0;L;<narrow> 314A;;;;N;HALFWIDTH HANGUL LETTER CIEUC;;;;
+FFBB;HALFWIDTH HANGUL LETTER KHIEUKH;Lo;0;L;<narrow> 314B;;;;N;HALFWIDTH HANGUL LETTER KIYEOK;;;;
+FFBC;HALFWIDTH HANGUL LETTER THIEUTH;Lo;0;L;<narrow> 314C;;;;N;HALFWIDTH HANGUL LETTER TIEUT;;;;
+FFBD;HALFWIDTH HANGUL LETTER PHIEUPH;Lo;0;L;<narrow> 314D;;;;N;HALFWIDTH HANGUL LETTER PIEUP;;;;
+FFBE;HALFWIDTH HANGUL LETTER HIEUH;Lo;0;L;<narrow> 314E;;;;N;;;;;
+FFC2;HALFWIDTH HANGUL LETTER A;Lo;0;L;<narrow> 314F;;;;N;;;;;
+FFC3;HALFWIDTH HANGUL LETTER AE;Lo;0;L;<narrow> 3150;;;;N;;;;;
+FFC4;HALFWIDTH HANGUL LETTER YA;Lo;0;L;<narrow> 3151;;;;N;;;;;
+FFC5;HALFWIDTH HANGUL LETTER YAE;Lo;0;L;<narrow> 3152;;;;N;;;;;
+FFC6;HALFWIDTH HANGUL LETTER EO;Lo;0;L;<narrow> 3153;;;;N;;;;;
+FFC7;HALFWIDTH HANGUL LETTER E;Lo;0;L;<narrow> 3154;;;;N;;;;;
+FFCA;HALFWIDTH HANGUL LETTER YEO;Lo;0;L;<narrow> 3155;;;;N;;;;;
+FFCB;HALFWIDTH HANGUL LETTER YE;Lo;0;L;<narrow> 3156;;;;N;;;;;
+FFCC;HALFWIDTH HANGUL LETTER O;Lo;0;L;<narrow> 3157;;;;N;;;;;
+FFCD;HALFWIDTH HANGUL LETTER WA;Lo;0;L;<narrow> 3158;;;;N;;;;;
+FFCE;HALFWIDTH HANGUL LETTER WAE;Lo;0;L;<narrow> 3159;;;;N;;;;;
+FFCF;HALFWIDTH HANGUL LETTER OE;Lo;0;L;<narrow> 315A;;;;N;;;;;
+FFD2;HALFWIDTH HANGUL LETTER YO;Lo;0;L;<narrow> 315B;;;;N;;;;;
+FFD3;HALFWIDTH HANGUL LETTER U;Lo;0;L;<narrow> 315C;;;;N;;;;;
+FFD4;HALFWIDTH HANGUL LETTER WEO;Lo;0;L;<narrow> 315D;;;;N;;;;;
+FFD5;HALFWIDTH HANGUL LETTER WE;Lo;0;L;<narrow> 315E;;;;N;;;;;
+FFD6;HALFWIDTH HANGUL LETTER WI;Lo;0;L;<narrow> 315F;;;;N;;;;;
+FFD7;HALFWIDTH HANGUL LETTER YU;Lo;0;L;<narrow> 3160;;;;N;;;;;
+FFDA;HALFWIDTH HANGUL LETTER EU;Lo;0;L;<narrow> 3161;;;;N;;;;;
+FFDB;HALFWIDTH HANGUL LETTER YI;Lo;0;L;<narrow> 3162;;;;N;;;;;
+FFDC;HALFWIDTH HANGUL LETTER I;Lo;0;L;<narrow> 3163;;;;N;;;;;
+FFE0;FULLWIDTH CENT SIGN;Sc;0;ET;<wide> 00A2;;;;N;;;;;
+FFE1;FULLWIDTH POUND SIGN;Sc;0;ET;<wide> 00A3;;;;N;;;;;
+FFE2;FULLWIDTH NOT SIGN;Sm;0;ON;<wide> 00AC;;;;N;;;;;
+FFE3;FULLWIDTH MACRON;Sk;0;ON;<wide> 00AF;;;;N;FULLWIDTH SPACING MACRON;;;;
+FFE4;FULLWIDTH BROKEN BAR;So;0;ON;<wide> 00A6;;;;N;FULLWIDTH BROKEN VERTICAL BAR;;;;
+FFE5;FULLWIDTH YEN SIGN;Sc;0;ET;<wide> 00A5;;;;N;;;;;
+FFE6;FULLWIDTH WON SIGN;Sc;0;ET;<wide> 20A9;;;;N;;;;;
+FFE8;HALFWIDTH FORMS LIGHT VERTICAL;So;0;ON;<narrow> 2502;;;;N;;;;;
+FFE9;HALFWIDTH LEFTWARDS ARROW;Sm;0;ON;<narrow> 2190;;;;N;;;;;
+FFEA;HALFWIDTH UPWARDS ARROW;Sm;0;ON;<narrow> 2191;;;;N;;;;;
+FFEB;HALFWIDTH RIGHTWARDS ARROW;Sm;0;ON;<narrow> 2192;;;;N;;;;;
+FFEC;HALFWIDTH DOWNWARDS ARROW;Sm;0;ON;<narrow> 2193;;;;N;;;;;
+FFED;HALFWIDTH BLACK SQUARE;So;0;ON;<narrow> 25A0;;;;N;;;;;
+FFEE;HALFWIDTH WHITE CIRCLE;So;0;ON;<narrow> 25CB;;;;N;;;;;
+FFF9;INTERLINEAR ANNOTATION ANCHOR;Cf;0;ON;;;;;N;;;;;
+FFFA;INTERLINEAR ANNOTATION SEPARATOR;Cf;0;ON;;;;;N;;;;;
+FFFB;INTERLINEAR ANNOTATION TERMINATOR;Cf;0;ON;;;;;N;;;;;
+FFFC;OBJECT REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
+FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
+10000;LINEAR B SYLLABLE B008 A;Lo;0;L;;;;;N;;;;;
+10001;LINEAR B SYLLABLE B038 E;Lo;0;L;;;;;N;;;;;
+10002;LINEAR B SYLLABLE B028 I;Lo;0;L;;;;;N;;;;;
+10003;LINEAR B SYLLABLE B061 O;Lo;0;L;;;;;N;;;;;
+10004;LINEAR B SYLLABLE B010 U;Lo;0;L;;;;;N;;;;;
+10005;LINEAR B SYLLABLE B001 DA;Lo;0;L;;;;;N;;;;;
+10006;LINEAR B SYLLABLE B045 DE;Lo;0;L;;;;;N;;;;;
+10007;LINEAR B SYLLABLE B007 DI;Lo;0;L;;;;;N;;;;;
+10008;LINEAR B SYLLABLE B014 DO;Lo;0;L;;;;;N;;;;;
+10009;LINEAR B SYLLABLE B051 DU;Lo;0;L;;;;;N;;;;;
+1000A;LINEAR B SYLLABLE B057 JA;Lo;0;L;;;;;N;;;;;
+1000B;LINEAR B SYLLABLE B046 JE;Lo;0;L;;;;;N;;;;;
+1000D;LINEAR B SYLLABLE B036 JO;Lo;0;L;;;;;N;;;;;
+1000E;LINEAR B SYLLABLE B065 JU;Lo;0;L;;;;;N;;;;;
+1000F;LINEAR B SYLLABLE B077 KA;Lo;0;L;;;;;N;;;;;
+10010;LINEAR B SYLLABLE B044 KE;Lo;0;L;;;;;N;;;;;
+10011;LINEAR B SYLLABLE B067 KI;Lo;0;L;;;;;N;;;;;
+10012;LINEAR B SYLLABLE B070 KO;Lo;0;L;;;;;N;;;;;
+10013;LINEAR B SYLLABLE B081 KU;Lo;0;L;;;;;N;;;;;
+10014;LINEAR B SYLLABLE B080 MA;Lo;0;L;;;;;N;;;;;
+10015;LINEAR B SYLLABLE B013 ME;Lo;0;L;;;;;N;;;;;
+10016;LINEAR B SYLLABLE B073 MI;Lo;0;L;;;;;N;;;;;
+10017;LINEAR B SYLLABLE B015 MO;Lo;0;L;;;;;N;;;;;
+10018;LINEAR B SYLLABLE B023 MU;Lo;0;L;;;;;N;;;;;
+10019;LINEAR B SYLLABLE B006 NA;Lo;0;L;;;;;N;;;;;
+1001A;LINEAR B SYLLABLE B024 NE;Lo;0;L;;;;;N;;;;;
+1001B;LINEAR B SYLLABLE B030 NI;Lo;0;L;;;;;N;;;;;
+1001C;LINEAR B SYLLABLE B052 NO;Lo;0;L;;;;;N;;;;;
+1001D;LINEAR B SYLLABLE B055 NU;Lo;0;L;;;;;N;;;;;
+1001E;LINEAR B SYLLABLE B003 PA;Lo;0;L;;;;;N;;;;;
+1001F;LINEAR B SYLLABLE B072 PE;Lo;0;L;;;;;N;;;;;
+10020;LINEAR B SYLLABLE B039 PI;Lo;0;L;;;;;N;;;;;
+10021;LINEAR B SYLLABLE B011 PO;Lo;0;L;;;;;N;;;;;
+10022;LINEAR B SYLLABLE B050 PU;Lo;0;L;;;;;N;;;;;
+10023;LINEAR B SYLLABLE B016 QA;Lo;0;L;;;;;N;;;;;
+10024;LINEAR B SYLLABLE B078 QE;Lo;0;L;;;;;N;;;;;
+10025;LINEAR B SYLLABLE B021 QI;Lo;0;L;;;;;N;;;;;
+10026;LINEAR B SYLLABLE B032 QO;Lo;0;L;;;;;N;;;;;
+10028;LINEAR B SYLLABLE B060 RA;Lo;0;L;;;;;N;;;;;
+10029;LINEAR B SYLLABLE B027 RE;Lo;0;L;;;;;N;;;;;
+1002A;LINEAR B SYLLABLE B053 RI;Lo;0;L;;;;;N;;;;;
+1002B;LINEAR B SYLLABLE B002 RO;Lo;0;L;;;;;N;;;;;
+1002C;LINEAR B SYLLABLE B026 RU;Lo;0;L;;;;;N;;;;;
+1002D;LINEAR B SYLLABLE B031 SA;Lo;0;L;;;;;N;;;;;
+1002E;LINEAR B SYLLABLE B009 SE;Lo;0;L;;;;;N;;;;;
+1002F;LINEAR B SYLLABLE B041 SI;Lo;0;L;;;;;N;;;;;
+10030;LINEAR B SYLLABLE B012 SO;Lo;0;L;;;;;N;;;;;
+10031;LINEAR B SYLLABLE B058 SU;Lo;0;L;;;;;N;;;;;
+10032;LINEAR B SYLLABLE B059 TA;Lo;0;L;;;;;N;;;;;
+10033;LINEAR B SYLLABLE B004 TE;Lo;0;L;;;;;N;;;;;
+10034;LINEAR B SYLLABLE B037 TI;Lo;0;L;;;;;N;;;;;
+10035;LINEAR B SYLLABLE B005 TO;Lo;0;L;;;;;N;;;;;
+10036;LINEAR B SYLLABLE B069 TU;Lo;0;L;;;;;N;;;;;
+10037;LINEAR B SYLLABLE B054 WA;Lo;0;L;;;;;N;;;;;
+10038;LINEAR B SYLLABLE B075 WE;Lo;0;L;;;;;N;;;;;
+10039;LINEAR B SYLLABLE B040 WI;Lo;0;L;;;;;N;;;;;
+1003A;LINEAR B SYLLABLE B042 WO;Lo;0;L;;;;;N;;;;;
+1003C;LINEAR B SYLLABLE B017 ZA;Lo;0;L;;;;;N;;;;;
+1003D;LINEAR B SYLLABLE B074 ZE;Lo;0;L;;;;;N;;;;;
+1003F;LINEAR B SYLLABLE B020 ZO;Lo;0;L;;;;;N;;;;;
+10040;LINEAR B SYLLABLE B025 A2;Lo;0;L;;;;;N;;;;;
+10041;LINEAR B SYLLABLE B043 A3;Lo;0;L;;;;;N;;;;;
+10042;LINEAR B SYLLABLE B085 AU;Lo;0;L;;;;;N;;;;;
+10043;LINEAR B SYLLABLE B071 DWE;Lo;0;L;;;;;N;;;;;
+10044;LINEAR B SYLLABLE B090 DWO;Lo;0;L;;;;;N;;;;;
+10045;LINEAR B SYLLABLE B048 NWA;Lo;0;L;;;;;N;;;;;
+10046;LINEAR B SYLLABLE B029 PU2;Lo;0;L;;;;;N;;;;;
+10047;LINEAR B SYLLABLE B062 PTE;Lo;0;L;;;;;N;;;;;
+10048;LINEAR B SYLLABLE B076 RA2;Lo;0;L;;;;;N;;;;;
+10049;LINEAR B SYLLABLE B033 RA3;Lo;0;L;;;;;N;;;;;
+1004A;LINEAR B SYLLABLE B068 RO2;Lo;0;L;;;;;N;;;;;
+1004B;LINEAR B SYLLABLE B066 TA2;Lo;0;L;;;;;N;;;;;
+1004C;LINEAR B SYLLABLE B087 TWE;Lo;0;L;;;;;N;;;;;
+1004D;LINEAR B SYLLABLE B091 TWO;Lo;0;L;;;;;N;;;;;
+10050;LINEAR B SYMBOL B018;Lo;0;L;;;;;N;;;;;
+10051;LINEAR B SYMBOL B019;Lo;0;L;;;;;N;;;;;
+10052;LINEAR B SYMBOL B022;Lo;0;L;;;;;N;;;;;
+10053;LINEAR B SYMBOL B034;Lo;0;L;;;;;N;;;;;
+10054;LINEAR B SYMBOL B047;Lo;0;L;;;;;N;;;;;
+10055;LINEAR B SYMBOL B049;Lo;0;L;;;;;N;;;;;
+10056;LINEAR B SYMBOL B056;Lo;0;L;;;;;N;;;;;
+10057;LINEAR B SYMBOL B063;Lo;0;L;;;;;N;;;;;
+10058;LINEAR B SYMBOL B064;Lo;0;L;;;;;N;;;;;
+10059;LINEAR B SYMBOL B079;Lo;0;L;;;;;N;;;;;
+1005A;LINEAR B SYMBOL B082;Lo;0;L;;;;;N;;;;;
+1005B;LINEAR B SYMBOL B083;Lo;0;L;;;;;N;;;;;
+1005C;LINEAR B SYMBOL B086;Lo;0;L;;;;;N;;;;;
+1005D;LINEAR B SYMBOL B089;Lo;0;L;;;;;N;;;;;
+10080;LINEAR B IDEOGRAM B100 MAN;Lo;0;L;;;;;N;;;;;
+10081;LINEAR B IDEOGRAM B102 WOMAN;Lo;0;L;;;;;N;;;;;
+10082;LINEAR B IDEOGRAM B104 DEER;Lo;0;L;;;;;N;;;;;
+10083;LINEAR B IDEOGRAM B105 EQUID;Lo;0;L;;;;;N;;;;;
+10084;LINEAR B IDEOGRAM B105F MARE;Lo;0;L;;;;;N;;;;;
+10085;LINEAR B IDEOGRAM B105M STALLION;Lo;0;L;;;;;N;;;;;
+10086;LINEAR B IDEOGRAM B106F EWE;Lo;0;L;;;;;N;;;;;
+10087;LINEAR B IDEOGRAM B106M RAM;Lo;0;L;;;;;N;;;;;
+10088;LINEAR B IDEOGRAM B107F SHE-GOAT;Lo;0;L;;;;;N;;;;;
+10089;LINEAR B IDEOGRAM B107M HE-GOAT;Lo;0;L;;;;;N;;;;;
+1008A;LINEAR B IDEOGRAM B108F SOW;Lo;0;L;;;;;N;;;;;
+1008B;LINEAR B IDEOGRAM B108M BOAR;Lo;0;L;;;;;N;;;;;
+1008C;LINEAR B IDEOGRAM B109F COW;Lo;0;L;;;;;N;;;;;
+1008D;LINEAR B IDEOGRAM B109M BULL;Lo;0;L;;;;;N;;;;;
+1008E;LINEAR B IDEOGRAM B120 WHEAT;Lo;0;L;;;;;N;;;;;
+1008F;LINEAR B IDEOGRAM B121 BARLEY;Lo;0;L;;;;;N;;;;;
+10090;LINEAR B IDEOGRAM B122 OLIVE;Lo;0;L;;;;;N;;;;;
+10091;LINEAR B IDEOGRAM B123 SPICE;Lo;0;L;;;;;N;;;;;
+10092;LINEAR B IDEOGRAM B125 CYPERUS;Lo;0;L;;;;;N;;;;;
+10093;LINEAR B MONOGRAM B127 KAPO;Lo;0;L;;;;;N;;;;;
+10094;LINEAR B MONOGRAM B128 KANAKO;Lo;0;L;;;;;N;;;;;
+10095;LINEAR B IDEOGRAM B130 OIL;Lo;0;L;;;;;N;;;;;
+10096;LINEAR B IDEOGRAM B131 WINE;Lo;0;L;;;;;N;;;;;
+10097;LINEAR B IDEOGRAM B132;Lo;0;L;;;;;N;;;;;
+10098;LINEAR B MONOGRAM B133 AREPA;Lo;0;L;;;;;N;;;;;
+10099;LINEAR B MONOGRAM B135 MERI;Lo;0;L;;;;;N;;;;;
+1009A;LINEAR B IDEOGRAM B140 BRONZE;Lo;0;L;;;;;N;;;;;
+1009B;LINEAR B IDEOGRAM B141 GOLD;Lo;0;L;;;;;N;;;;;
+1009C;LINEAR B IDEOGRAM B142;Lo;0;L;;;;;N;;;;;
+1009D;LINEAR B IDEOGRAM B145 WOOL;Lo;0;L;;;;;N;;;;;
+1009E;LINEAR B IDEOGRAM B146;Lo;0;L;;;;;N;;;;;
+1009F;LINEAR B IDEOGRAM B150;Lo;0;L;;;;;N;;;;;
+100A0;LINEAR B IDEOGRAM B151 HORN;Lo;0;L;;;;;N;;;;;
+100A1;LINEAR B IDEOGRAM B152;Lo;0;L;;;;;N;;;;;
+100A2;LINEAR B IDEOGRAM B153;Lo;0;L;;;;;N;;;;;
+100A3;LINEAR B IDEOGRAM B154;Lo;0;L;;;;;N;;;;;
+100A4;LINEAR B MONOGRAM B156 TURO2;Lo;0;L;;;;;N;;;;;
+100A5;LINEAR B IDEOGRAM B157;Lo;0;L;;;;;N;;;;;
+100A6;LINEAR B IDEOGRAM B158;Lo;0;L;;;;;N;;;;;
+100A7;LINEAR B IDEOGRAM B159 CLOTH;Lo;0;L;;;;;N;;;;;
+100A8;LINEAR B IDEOGRAM B160;Lo;0;L;;;;;N;;;;;
+100A9;LINEAR B IDEOGRAM B161;Lo;0;L;;;;;N;;;;;
+100AA;LINEAR B IDEOGRAM B162 GARMENT;Lo;0;L;;;;;N;;;;;
+100AB;LINEAR B IDEOGRAM B163 ARMOUR;Lo;0;L;;;;;N;;;;;
+100AC;LINEAR B IDEOGRAM B164;Lo;0;L;;;;;N;;;;;
+100AD;LINEAR B IDEOGRAM B165;Lo;0;L;;;;;N;;;;;
+100AE;LINEAR B IDEOGRAM B166;Lo;0;L;;;;;N;;;;;
+100AF;LINEAR B IDEOGRAM B167;Lo;0;L;;;;;N;;;;;
+100B0;LINEAR B IDEOGRAM B168;Lo;0;L;;;;;N;;;;;
+100B1;LINEAR B IDEOGRAM B169;Lo;0;L;;;;;N;;;;;
+100B2;LINEAR B IDEOGRAM B170;Lo;0;L;;;;;N;;;;;
+100B3;LINEAR B IDEOGRAM B171;Lo;0;L;;;;;N;;;;;
+100B4;LINEAR B IDEOGRAM B172;Lo;0;L;;;;;N;;;;;
+100B5;LINEAR B IDEOGRAM B173 MONTH;Lo;0;L;;;;;N;;;;;
+100B6;LINEAR B IDEOGRAM B174;Lo;0;L;;;;;N;;;;;
+100B7;LINEAR B IDEOGRAM B176 TREE;Lo;0;L;;;;;N;;;;;
+100B8;LINEAR B IDEOGRAM B177;Lo;0;L;;;;;N;;;;;
+100B9;LINEAR B IDEOGRAM B178;Lo;0;L;;;;;N;;;;;
+100BA;LINEAR B IDEOGRAM B179;Lo;0;L;;;;;N;;;;;
+100BB;LINEAR B IDEOGRAM B180;Lo;0;L;;;;;N;;;;;
+100BC;LINEAR B IDEOGRAM B181;Lo;0;L;;;;;N;;;;;
+100BD;LINEAR B IDEOGRAM B182;Lo;0;L;;;;;N;;;;;
+100BE;LINEAR B IDEOGRAM B183;Lo;0;L;;;;;N;;;;;
+100BF;LINEAR B IDEOGRAM B184;Lo;0;L;;;;;N;;;;;
+100C0;LINEAR B IDEOGRAM B185;Lo;0;L;;;;;N;;;;;
+100C1;LINEAR B IDEOGRAM B189;Lo;0;L;;;;;N;;;;;
+100C2;LINEAR B IDEOGRAM B190;Lo;0;L;;;;;N;;;;;
+100C3;LINEAR B IDEOGRAM B191 HELMET;Lo;0;L;;;;;N;;;;;
+100C4;LINEAR B IDEOGRAM B220 FOOTSTOOL;Lo;0;L;;;;;N;;;;;
+100C5;LINEAR B IDEOGRAM B225 BATHTUB;Lo;0;L;;;;;N;;;;;
+100C6;LINEAR B IDEOGRAM B230 SPEAR;Lo;0;L;;;;;N;;;;;
+100C7;LINEAR B IDEOGRAM B231 ARROW;Lo;0;L;;;;;N;;;;;
+100C8;LINEAR B IDEOGRAM B232;Lo;0;L;;;;;N;;;;;
+100C9;LINEAR B IDEOGRAM B233 SWORD;Lo;0;L;;;;;N;;;;;
+100CA;LINEAR B IDEOGRAM B234;Lo;0;L;;;;;N;;;;;
+100CB;LINEAR B IDEOGRAM B236;Lo;0;L;;;;;N;;;;;
+100CC;LINEAR B IDEOGRAM B240 WHEELED CHARIOT;Lo;0;L;;;;;N;;;;;
+100CD;LINEAR B IDEOGRAM B241 CHARIOT;Lo;0;L;;;;;N;;;;;
+100CE;LINEAR B IDEOGRAM B242 CHARIOT FRAME;Lo;0;L;;;;;N;;;;;
+100CF;LINEAR B IDEOGRAM B243 WHEEL;Lo;0;L;;;;;N;;;;;
+100D0;LINEAR B IDEOGRAM B245;Lo;0;L;;;;;N;;;;;
+100D1;LINEAR B IDEOGRAM B246;Lo;0;L;;;;;N;;;;;
+100D2;LINEAR B MONOGRAM B247 DIPTE;Lo;0;L;;;;;N;;;;;
+100D3;LINEAR B IDEOGRAM B248;Lo;0;L;;;;;N;;;;;
+100D4;LINEAR B IDEOGRAM B249;Lo;0;L;;;;;N;;;;;
+100D5;LINEAR B IDEOGRAM B251;Lo;0;L;;;;;N;;;;;
+100D6;LINEAR B IDEOGRAM B252;Lo;0;L;;;;;N;;;;;
+100D7;LINEAR B IDEOGRAM B253;Lo;0;L;;;;;N;;;;;
+100D8;LINEAR B IDEOGRAM B254 DART;Lo;0;L;;;;;N;;;;;
+100D9;LINEAR B IDEOGRAM B255;Lo;0;L;;;;;N;;;;;
+100DA;LINEAR B IDEOGRAM B256;Lo;0;L;;;;;N;;;;;
+100DB;LINEAR B IDEOGRAM B257;Lo;0;L;;;;;N;;;;;
+100DC;LINEAR B IDEOGRAM B258;Lo;0;L;;;;;N;;;;;
+100DD;LINEAR B IDEOGRAM B259;Lo;0;L;;;;;N;;;;;
+100DE;LINEAR B IDEOGRAM VESSEL B155;Lo;0;L;;;;;N;;;;;
+100DF;LINEAR B IDEOGRAM VESSEL B200;Lo;0;L;;;;;N;;;;;
+100E0;LINEAR B IDEOGRAM VESSEL B201;Lo;0;L;;;;;N;;;;;
+100E1;LINEAR B IDEOGRAM VESSEL B202;Lo;0;L;;;;;N;;;;;
+100E2;LINEAR B IDEOGRAM VESSEL B203;Lo;0;L;;;;;N;;;;;
+100E3;LINEAR B IDEOGRAM VESSEL B204;Lo;0;L;;;;;N;;;;;
+100E4;LINEAR B IDEOGRAM VESSEL B205;Lo;0;L;;;;;N;;;;;
+100E5;LINEAR B IDEOGRAM VESSEL B206;Lo;0;L;;;;;N;;;;;
+100E6;LINEAR B IDEOGRAM VESSEL B207;Lo;0;L;;;;;N;;;;;
+100E7;LINEAR B IDEOGRAM VESSEL B208;Lo;0;L;;;;;N;;;;;
+100E8;LINEAR B IDEOGRAM VESSEL B209;Lo;0;L;;;;;N;;;;;
+100E9;LINEAR B IDEOGRAM VESSEL B210;Lo;0;L;;;;;N;;;;;
+100EA;LINEAR B IDEOGRAM VESSEL B211;Lo;0;L;;;;;N;;;;;
+100EB;LINEAR B IDEOGRAM VESSEL B212;Lo;0;L;;;;;N;;;;;
+100EC;LINEAR B IDEOGRAM VESSEL B213;Lo;0;L;;;;;N;;;;;
+100ED;LINEAR B IDEOGRAM VESSEL B214;Lo;0;L;;;;;N;;;;;
+100EE;LINEAR B IDEOGRAM VESSEL B215;Lo;0;L;;;;;N;;;;;
+100EF;LINEAR B IDEOGRAM VESSEL B216;Lo;0;L;;;;;N;;;;;
+100F0;LINEAR B IDEOGRAM VESSEL B217;Lo;0;L;;;;;N;;;;;
+100F1;LINEAR B IDEOGRAM VESSEL B218;Lo;0;L;;;;;N;;;;;
+100F2;LINEAR B IDEOGRAM VESSEL B219;Lo;0;L;;;;;N;;;;;
+100F3;LINEAR B IDEOGRAM VESSEL B221;Lo;0;L;;;;;N;;;;;
+100F4;LINEAR B IDEOGRAM VESSEL B222;Lo;0;L;;;;;N;;;;;
+100F5;LINEAR B IDEOGRAM VESSEL B226;Lo;0;L;;;;;N;;;;;
+100F6;LINEAR B IDEOGRAM VESSEL B227;Lo;0;L;;;;;N;;;;;
+100F7;LINEAR B IDEOGRAM VESSEL B228;Lo;0;L;;;;;N;;;;;
+100F8;LINEAR B IDEOGRAM VESSEL B229;Lo;0;L;;;;;N;;;;;
+100F9;LINEAR B IDEOGRAM VESSEL B250;Lo;0;L;;;;;N;;;;;
+100FA;LINEAR B IDEOGRAM VESSEL B305;Lo;0;L;;;;;N;;;;;
+10100;AEGEAN WORD SEPARATOR LINE;Po;0;L;;;;;N;;;;;
+10101;AEGEAN WORD SEPARATOR DOT;Po;0;ON;;;;;N;;;;;
+10102;AEGEAN CHECK MARK;Po;0;L;;;;;N;;;;;
+10107;AEGEAN NUMBER ONE;No;0;L;;;;1;N;;;;;
+10108;AEGEAN NUMBER TWO;No;0;L;;;;2;N;;;;;
+10109;AEGEAN NUMBER THREE;No;0;L;;;;3;N;;;;;
+1010A;AEGEAN NUMBER FOUR;No;0;L;;;;4;N;;;;;
+1010B;AEGEAN NUMBER FIVE;No;0;L;;;;5;N;;;;;
+1010C;AEGEAN NUMBER SIX;No;0;L;;;;6;N;;;;;
+1010D;AEGEAN NUMBER SEVEN;No;0;L;;;;7;N;;;;;
+1010E;AEGEAN NUMBER EIGHT;No;0;L;;;;8;N;;;;;
+1010F;AEGEAN NUMBER NINE;No;0;L;;;;9;N;;;;;
+10110;AEGEAN NUMBER TEN;No;0;L;;;;10;N;;;;;
+10111;AEGEAN NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+10112;AEGEAN NUMBER THIRTY;No;0;L;;;;30;N;;;;;
+10113;AEGEAN NUMBER FORTY;No;0;L;;;;40;N;;;;;
+10114;AEGEAN NUMBER FIFTY;No;0;L;;;;50;N;;;;;
+10115;AEGEAN NUMBER SIXTY;No;0;L;;;;60;N;;;;;
+10116;AEGEAN NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
+10117;AEGEAN NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
+10118;AEGEAN NUMBER NINETY;No;0;L;;;;90;N;;;;;
+10119;AEGEAN NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
+1011A;AEGEAN NUMBER TWO HUNDRED;No;0;L;;;;200;N;;;;;
+1011B;AEGEAN NUMBER THREE HUNDRED;No;0;L;;;;300;N;;;;;
+1011C;AEGEAN NUMBER FOUR HUNDRED;No;0;L;;;;400;N;;;;;
+1011D;AEGEAN NUMBER FIVE HUNDRED;No;0;L;;;;500;N;;;;;
+1011E;AEGEAN NUMBER SIX HUNDRED;No;0;L;;;;600;N;;;;;
+1011F;AEGEAN NUMBER SEVEN HUNDRED;No;0;L;;;;700;N;;;;;
+10120;AEGEAN NUMBER EIGHT HUNDRED;No;0;L;;;;800;N;;;;;
+10121;AEGEAN NUMBER NINE HUNDRED;No;0;L;;;;900;N;;;;;
+10122;AEGEAN NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
+10123;AEGEAN NUMBER TWO THOUSAND;No;0;L;;;;2000;N;;;;;
+10124;AEGEAN NUMBER THREE THOUSAND;No;0;L;;;;3000;N;;;;;
+10125;AEGEAN NUMBER FOUR THOUSAND;No;0;L;;;;4000;N;;;;;
+10126;AEGEAN NUMBER FIVE THOUSAND;No;0;L;;;;5000;N;;;;;
+10127;AEGEAN NUMBER SIX THOUSAND;No;0;L;;;;6000;N;;;;;
+10128;AEGEAN NUMBER SEVEN THOUSAND;No;0;L;;;;7000;N;;;;;
+10129;AEGEAN NUMBER EIGHT THOUSAND;No;0;L;;;;8000;N;;;;;
+1012A;AEGEAN NUMBER NINE THOUSAND;No;0;L;;;;9000;N;;;;;
+1012B;AEGEAN NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;;
+1012C;AEGEAN NUMBER TWENTY THOUSAND;No;0;L;;;;20000;N;;;;;
+1012D;AEGEAN NUMBER THIRTY THOUSAND;No;0;L;;;;30000;N;;;;;
+1012E;AEGEAN NUMBER FORTY THOUSAND;No;0;L;;;;40000;N;;;;;
+1012F;AEGEAN NUMBER FIFTY THOUSAND;No;0;L;;;;50000;N;;;;;
+10130;AEGEAN NUMBER SIXTY THOUSAND;No;0;L;;;;60000;N;;;;;
+10131;AEGEAN NUMBER SEVENTY THOUSAND;No;0;L;;;;70000;N;;;;;
+10132;AEGEAN NUMBER EIGHTY THOUSAND;No;0;L;;;;80000;N;;;;;
+10133;AEGEAN NUMBER NINETY THOUSAND;No;0;L;;;;90000;N;;;;;
+10137;AEGEAN WEIGHT BASE UNIT;So;0;L;;;;;N;;;;;
+10138;AEGEAN WEIGHT FIRST SUBUNIT;So;0;L;;;;;N;;;;;
+10139;AEGEAN WEIGHT SECOND SUBUNIT;So;0;L;;;;;N;;;;;
+1013A;AEGEAN WEIGHT THIRD SUBUNIT;So;0;L;;;;;N;;;;;
+1013B;AEGEAN WEIGHT FOURTH SUBUNIT;So;0;L;;;;;N;;;;;
+1013C;AEGEAN DRY MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;;
+1013D;AEGEAN LIQUID MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;;
+1013E;AEGEAN MEASURE SECOND SUBUNIT;So;0;L;;;;;N;;;;;
+1013F;AEGEAN MEASURE THIRD SUBUNIT;So;0;L;;;;;N;;;;;
+10140;GREEK ACROPHONIC ATTIC ONE QUARTER;Nl;0;ON;;;;1/4;N;;;;;
+10141;GREEK ACROPHONIC ATTIC ONE HALF;Nl;0;ON;;;;1/2;N;;;;;
+10142;GREEK ACROPHONIC ATTIC ONE DRACHMA;Nl;0;ON;;;;1;N;;;;;
+10143;GREEK ACROPHONIC ATTIC FIVE;Nl;0;ON;;;;5;N;;;;;
+10144;GREEK ACROPHONIC ATTIC FIFTY;Nl;0;ON;;;;50;N;;;;;
+10145;GREEK ACROPHONIC ATTIC FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+10146;GREEK ACROPHONIC ATTIC FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;;
+10147;GREEK ACROPHONIC ATTIC FIFTY THOUSAND;Nl;0;ON;;;;50000;N;;;;;
+10148;GREEK ACROPHONIC ATTIC FIVE TALENTS;Nl;0;ON;;;;5;N;;;;;
+10149;GREEK ACROPHONIC ATTIC TEN TALENTS;Nl;0;ON;;;;10;N;;;;;
+1014A;GREEK ACROPHONIC ATTIC FIFTY TALENTS;Nl;0;ON;;;;50;N;;;;;
+1014B;GREEK ACROPHONIC ATTIC ONE HUNDRED TALENTS;Nl;0;ON;;;;100;N;;;;;
+1014C;GREEK ACROPHONIC ATTIC FIVE HUNDRED TALENTS;Nl;0;ON;;;;500;N;;;;;
+1014D;GREEK ACROPHONIC ATTIC ONE THOUSAND TALENTS;Nl;0;ON;;;;1000;N;;;;;
+1014E;GREEK ACROPHONIC ATTIC FIVE THOUSAND TALENTS;Nl;0;ON;;;;5000;N;;;;;
+1014F;GREEK ACROPHONIC ATTIC FIVE STATERS;Nl;0;ON;;;;5;N;;;;;
+10150;GREEK ACROPHONIC ATTIC TEN STATERS;Nl;0;ON;;;;10;N;;;;;
+10151;GREEK ACROPHONIC ATTIC FIFTY STATERS;Nl;0;ON;;;;50;N;;;;;
+10152;GREEK ACROPHONIC ATTIC ONE HUNDRED STATERS;Nl;0;ON;;;;100;N;;;;;
+10153;GREEK ACROPHONIC ATTIC FIVE HUNDRED STATERS;Nl;0;ON;;;;500;N;;;;;
+10154;GREEK ACROPHONIC ATTIC ONE THOUSAND STATERS;Nl;0;ON;;;;1000;N;;;;;
+10155;GREEK ACROPHONIC ATTIC TEN THOUSAND STATERS;Nl;0;ON;;;;10000;N;;;;;
+10156;GREEK ACROPHONIC ATTIC FIFTY THOUSAND STATERS;Nl;0;ON;;;;50000;N;;;;;
+10157;GREEK ACROPHONIC ATTIC TEN MNAS;Nl;0;ON;;;;10;N;;;;;
+10158;GREEK ACROPHONIC HERAEUM ONE PLETHRON;Nl;0;ON;;;;1;N;;;;;
+10159;GREEK ACROPHONIC THESPIAN ONE;Nl;0;ON;;;;1;N;;;;;
+1015A;GREEK ACROPHONIC HERMIONIAN ONE;Nl;0;ON;;;;1;N;;;;;
+1015B;GREEK ACROPHONIC EPIDAUREAN TWO;Nl;0;ON;;;;2;N;;;;;
+1015C;GREEK ACROPHONIC THESPIAN TWO;Nl;0;ON;;;;2;N;;;;;
+1015D;GREEK ACROPHONIC CYRENAIC TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;;
+1015E;GREEK ACROPHONIC EPIDAUREAN TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;;
+1015F;GREEK ACROPHONIC TROEZENIAN FIVE;Nl;0;ON;;;;5;N;;;;;
+10160;GREEK ACROPHONIC TROEZENIAN TEN;Nl;0;ON;;;;10;N;;;;;
+10161;GREEK ACROPHONIC TROEZENIAN TEN ALTERNATE FORM;Nl;0;ON;;;;10;N;;;;;
+10162;GREEK ACROPHONIC HERMIONIAN TEN;Nl;0;ON;;;;10;N;;;;;
+10163;GREEK ACROPHONIC MESSENIAN TEN;Nl;0;ON;;;;10;N;;;;;
+10164;GREEK ACROPHONIC THESPIAN TEN;Nl;0;ON;;;;10;N;;;;;
+10165;GREEK ACROPHONIC THESPIAN THIRTY;Nl;0;ON;;;;30;N;;;;;
+10166;GREEK ACROPHONIC TROEZENIAN FIFTY;Nl;0;ON;;;;50;N;;;;;
+10167;GREEK ACROPHONIC TROEZENIAN FIFTY ALTERNATE FORM;Nl;0;ON;;;;50;N;;;;;
+10168;GREEK ACROPHONIC HERMIONIAN FIFTY;Nl;0;ON;;;;50;N;;;;;
+10169;GREEK ACROPHONIC THESPIAN FIFTY;Nl;0;ON;;;;50;N;;;;;
+1016A;GREEK ACROPHONIC THESPIAN ONE HUNDRED;Nl;0;ON;;;;100;N;;;;;
+1016B;GREEK ACROPHONIC THESPIAN THREE HUNDRED;Nl;0;ON;;;;300;N;;;;;
+1016C;GREEK ACROPHONIC EPIDAUREAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+1016D;GREEK ACROPHONIC TROEZENIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+1016E;GREEK ACROPHONIC THESPIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+1016F;GREEK ACROPHONIC CARYSTIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+10170;GREEK ACROPHONIC NAXIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
+10171;GREEK ACROPHONIC THESPIAN ONE THOUSAND;Nl;0;ON;;;;1000;N;;;;;
+10172;GREEK ACROPHONIC THESPIAN FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;;
+10173;GREEK ACROPHONIC DELPHIC FIVE MNAS;Nl;0;ON;;;;5;N;;;;;
+10174;GREEK ACROPHONIC STRATIAN FIFTY MNAS;Nl;0;ON;;;;50;N;;;;;
+10175;GREEK ONE HALF SIGN;No;0;ON;;;;1/2;N;;;;;
+10176;GREEK ONE HALF SIGN ALTERNATE FORM;No;0;ON;;;;1/2;N;;;;;
+10177;GREEK TWO THIRDS SIGN;No;0;ON;;;;2/3;N;;;;;
+10178;GREEK THREE QUARTERS SIGN;No;0;ON;;;;3/4;N;;;;;
+10179;GREEK YEAR SIGN;So;0;ON;;;;;N;;;;;
+1017A;GREEK TALENT SIGN;So;0;ON;;;;;N;;;;;
+1017B;GREEK DRACHMA SIGN;So;0;ON;;;;;N;;;;;
+1017C;GREEK OBOL SIGN;So;0;ON;;;;;N;;;;;
+1017D;GREEK TWO OBOLS SIGN;So;0;ON;;;;;N;;;;;
+1017E;GREEK THREE OBOLS SIGN;So;0;ON;;;;;N;;;;;
+1017F;GREEK FOUR OBOLS SIGN;So;0;ON;;;;;N;;;;;
+10180;GREEK FIVE OBOLS SIGN;So;0;ON;;;;;N;;;;;
+10181;GREEK METRETES SIGN;So;0;ON;;;;;N;;;;;
+10182;GREEK KYATHOS BASE SIGN;So;0;ON;;;;;N;;;;;
+10183;GREEK LITRA SIGN;So;0;ON;;;;;N;;;;;
+10184;GREEK OUNKIA SIGN;So;0;ON;;;;;N;;;;;
+10185;GREEK XESTES SIGN;So;0;ON;;;;;N;;;;;
+10186;GREEK ARTABE SIGN;So;0;ON;;;;;N;;;;;
+10187;GREEK AROURA SIGN;So;0;ON;;;;;N;;;;;
+10188;GREEK GRAMMA SIGN;So;0;ON;;;;;N;;;;;
+10189;GREEK TRYBLION BASE SIGN;So;0;ON;;;;;N;;;;;
+1018A;GREEK ZERO SIGN;No;0;ON;;;;0;N;;;;;
+1018B;GREEK ONE QUARTER SIGN;No;0;ON;;;;1/4;N;;;;;
+1018C;GREEK SINUSOID SIGN;So;0;ON;;;;;N;;;;;
+1018D;GREEK INDICTION SIGN;So;0;L;;;;;N;;;;;
+1018E;NOMISMA SIGN;So;0;L;;;;;N;;;;;
+10190;ROMAN SEXTANS SIGN;So;0;ON;;;;;N;;;;;
+10191;ROMAN UNCIA SIGN;So;0;ON;;;;;N;;;;;
+10192;ROMAN SEMUNCIA SIGN;So;0;ON;;;;;N;;;;;
+10193;ROMAN SEXTULA SIGN;So;0;ON;;;;;N;;;;;
+10194;ROMAN DIMIDIA SEXTULA SIGN;So;0;ON;;;;;N;;;;;
+10195;ROMAN SILIQUA SIGN;So;0;ON;;;;;N;;;;;
+10196;ROMAN DENARIUS SIGN;So;0;ON;;;;;N;;;;;
+10197;ROMAN QUINARIUS SIGN;So;0;ON;;;;;N;;;;;
+10198;ROMAN SESTERTIUS SIGN;So;0;ON;;;;;N;;;;;
+10199;ROMAN DUPONDIUS SIGN;So;0;ON;;;;;N;;;;;
+1019A;ROMAN AS SIGN;So;0;ON;;;;;N;;;;;
+1019B;ROMAN CENTURIAL SIGN;So;0;ON;;;;;N;;;;;
+101A0;GREEK SYMBOL TAU RHO;So;0;ON;;;;;N;;;;;
+101D0;PHAISTOS DISC SIGN PEDESTRIAN;So;0;L;;;;;N;;;;;
+101D1;PHAISTOS DISC SIGN PLUMED HEAD;So;0;L;;;;;N;;;;;
+101D2;PHAISTOS DISC SIGN TATTOOED HEAD;So;0;L;;;;;N;;;;;
+101D3;PHAISTOS DISC SIGN CAPTIVE;So;0;L;;;;;N;;;;;
+101D4;PHAISTOS DISC SIGN CHILD;So;0;L;;;;;N;;;;;
+101D5;PHAISTOS DISC SIGN WOMAN;So;0;L;;;;;N;;;;;
+101D6;PHAISTOS DISC SIGN HELMET;So;0;L;;;;;N;;;;;
+101D7;PHAISTOS DISC SIGN GAUNTLET;So;0;L;;;;;N;;;;;
+101D8;PHAISTOS DISC SIGN TIARA;So;0;L;;;;;N;;;;;
+101D9;PHAISTOS DISC SIGN ARROW;So;0;L;;;;;N;;;;;
+101DA;PHAISTOS DISC SIGN BOW;So;0;L;;;;;N;;;;;
+101DB;PHAISTOS DISC SIGN SHIELD;So;0;L;;;;;N;;;;;
+101DC;PHAISTOS DISC SIGN CLUB;So;0;L;;;;;N;;;;;
+101DD;PHAISTOS DISC SIGN MANACLES;So;0;L;;;;;N;;;;;
+101DE;PHAISTOS DISC SIGN MATTOCK;So;0;L;;;;;N;;;;;
+101DF;PHAISTOS DISC SIGN SAW;So;0;L;;;;;N;;;;;
+101E0;PHAISTOS DISC SIGN LID;So;0;L;;;;;N;;;;;
+101E1;PHAISTOS DISC SIGN BOOMERANG;So;0;L;;;;;N;;;;;
+101E2;PHAISTOS DISC SIGN CARPENTRY PLANE;So;0;L;;;;;N;;;;;
+101E3;PHAISTOS DISC SIGN DOLIUM;So;0;L;;;;;N;;;;;
+101E4;PHAISTOS DISC SIGN COMB;So;0;L;;;;;N;;;;;
+101E5;PHAISTOS DISC SIGN SLING;So;0;L;;;;;N;;;;;
+101E6;PHAISTOS DISC SIGN COLUMN;So;0;L;;;;;N;;;;;
+101E7;PHAISTOS DISC SIGN BEEHIVE;So;0;L;;;;;N;;;;;
+101E8;PHAISTOS DISC SIGN SHIP;So;0;L;;;;;N;;;;;
+101E9;PHAISTOS DISC SIGN HORN;So;0;L;;;;;N;;;;;
+101EA;PHAISTOS DISC SIGN HIDE;So;0;L;;;;;N;;;;;
+101EB;PHAISTOS DISC SIGN BULLS LEG;So;0;L;;;;;N;;;;;
+101EC;PHAISTOS DISC SIGN CAT;So;0;L;;;;;N;;;;;
+101ED;PHAISTOS DISC SIGN RAM;So;0;L;;;;;N;;;;;
+101EE;PHAISTOS DISC SIGN EAGLE;So;0;L;;;;;N;;;;;
+101EF;PHAISTOS DISC SIGN DOVE;So;0;L;;;;;N;;;;;
+101F0;PHAISTOS DISC SIGN TUNNY;So;0;L;;;;;N;;;;;
+101F1;PHAISTOS DISC SIGN BEE;So;0;L;;;;;N;;;;;
+101F2;PHAISTOS DISC SIGN PLANE TREE;So;0;L;;;;;N;;;;;
+101F3;PHAISTOS DISC SIGN VINE;So;0;L;;;;;N;;;;;
+101F4;PHAISTOS DISC SIGN PAPYRUS;So;0;L;;;;;N;;;;;
+101F5;PHAISTOS DISC SIGN ROSETTE;So;0;L;;;;;N;;;;;
+101F6;PHAISTOS DISC SIGN LILY;So;0;L;;;;;N;;;;;
+101F7;PHAISTOS DISC SIGN OX BACK;So;0;L;;;;;N;;;;;
+101F8;PHAISTOS DISC SIGN FLUTE;So;0;L;;;;;N;;;;;
+101F9;PHAISTOS DISC SIGN GRATER;So;0;L;;;;;N;;;;;
+101FA;PHAISTOS DISC SIGN STRAINER;So;0;L;;;;;N;;;;;
+101FB;PHAISTOS DISC SIGN SMALL AXE;So;0;L;;;;;N;;;;;
+101FC;PHAISTOS DISC SIGN WAVY BAND;So;0;L;;;;;N;;;;;
+101FD;PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE;Mn;220;NSM;;;;;N;;;;;
+10280;LYCIAN LETTER A;Lo;0;L;;;;;N;;;;;
+10281;LYCIAN LETTER E;Lo;0;L;;;;;N;;;;;
+10282;LYCIAN LETTER B;Lo;0;L;;;;;N;;;;;
+10283;LYCIAN LETTER BH;Lo;0;L;;;;;N;;;;;
+10284;LYCIAN LETTER G;Lo;0;L;;;;;N;;;;;
+10285;LYCIAN LETTER D;Lo;0;L;;;;;N;;;;;
+10286;LYCIAN LETTER I;Lo;0;L;;;;;N;;;;;
+10287;LYCIAN LETTER W;Lo;0;L;;;;;N;;;;;
+10288;LYCIAN LETTER Z;Lo;0;L;;;;;N;;;;;
+10289;LYCIAN LETTER TH;Lo;0;L;;;;;N;;;;;
+1028A;LYCIAN LETTER J;Lo;0;L;;;;;N;;;;;
+1028B;LYCIAN LETTER K;Lo;0;L;;;;;N;;;;;
+1028C;LYCIAN LETTER Q;Lo;0;L;;;;;N;;;;;
+1028D;LYCIAN LETTER L;Lo;0;L;;;;;N;;;;;
+1028E;LYCIAN LETTER M;Lo;0;L;;;;;N;;;;;
+1028F;LYCIAN LETTER N;Lo;0;L;;;;;N;;;;;
+10290;LYCIAN LETTER MM;Lo;0;L;;;;;N;;;;;
+10291;LYCIAN LETTER NN;Lo;0;L;;;;;N;;;;;
+10292;LYCIAN LETTER U;Lo;0;L;;;;;N;;;;;
+10293;LYCIAN LETTER P;Lo;0;L;;;;;N;;;;;
+10294;LYCIAN LETTER KK;Lo;0;L;;;;;N;;;;;
+10295;LYCIAN LETTER R;Lo;0;L;;;;;N;;;;;
+10296;LYCIAN LETTER S;Lo;0;L;;;;;N;;;;;
+10297;LYCIAN LETTER T;Lo;0;L;;;;;N;;;;;
+10298;LYCIAN LETTER TT;Lo;0;L;;;;;N;;;;;
+10299;LYCIAN LETTER AN;Lo;0;L;;;;;N;;;;;
+1029A;LYCIAN LETTER EN;Lo;0;L;;;;;N;;;;;
+1029B;LYCIAN LETTER H;Lo;0;L;;;;;N;;;;;
+1029C;LYCIAN LETTER X;Lo;0;L;;;;;N;;;;;
+102A0;CARIAN LETTER A;Lo;0;L;;;;;N;;;;;
+102A1;CARIAN LETTER P2;Lo;0;L;;;;;N;;;;;
+102A2;CARIAN LETTER D;Lo;0;L;;;;;N;;;;;
+102A3;CARIAN LETTER L;Lo;0;L;;;;;N;;;;;
+102A4;CARIAN LETTER UUU;Lo;0;L;;;;;N;;;;;
+102A5;CARIAN LETTER R;Lo;0;L;;;;;N;;;;;
+102A6;CARIAN LETTER LD;Lo;0;L;;;;;N;;;;;
+102A7;CARIAN LETTER A2;Lo;0;L;;;;;N;;;;;
+102A8;CARIAN LETTER Q;Lo;0;L;;;;;N;;;;;
+102A9;CARIAN LETTER B;Lo;0;L;;;;;N;;;;;
+102AA;CARIAN LETTER M;Lo;0;L;;;;;N;;;;;
+102AB;CARIAN LETTER O;Lo;0;L;;;;;N;;;;;
+102AC;CARIAN LETTER D2;Lo;0;L;;;;;N;;;;;
+102AD;CARIAN LETTER T;Lo;0;L;;;;;N;;;;;
+102AE;CARIAN LETTER SH;Lo;0;L;;;;;N;;;;;
+102AF;CARIAN LETTER SH2;Lo;0;L;;;;;N;;;;;
+102B0;CARIAN LETTER S;Lo;0;L;;;;;N;;;;;
+102B1;CARIAN LETTER C-18;Lo;0;L;;;;;N;;;;;
+102B2;CARIAN LETTER U;Lo;0;L;;;;;N;;;;;
+102B3;CARIAN LETTER NN;Lo;0;L;;;;;N;;;;;
+102B4;CARIAN LETTER X;Lo;0;L;;;;;N;;;;;
+102B5;CARIAN LETTER N;Lo;0;L;;;;;N;;;;;
+102B6;CARIAN LETTER TT2;Lo;0;L;;;;;N;;;;;
+102B7;CARIAN LETTER P;Lo;0;L;;;;;N;;;;;
+102B8;CARIAN LETTER SS;Lo;0;L;;;;;N;;;;;
+102B9;CARIAN LETTER I;Lo;0;L;;;;;N;;;;;
+102BA;CARIAN LETTER E;Lo;0;L;;;;;N;;;;;
+102BB;CARIAN LETTER UUUU;Lo;0;L;;;;;N;;;;;
+102BC;CARIAN LETTER K;Lo;0;L;;;;;N;;;;;
+102BD;CARIAN LETTER K2;Lo;0;L;;;;;N;;;;;
+102BE;CARIAN LETTER ND;Lo;0;L;;;;;N;;;;;
+102BF;CARIAN LETTER UU;Lo;0;L;;;;;N;;;;;
+102C0;CARIAN LETTER G;Lo;0;L;;;;;N;;;;;
+102C1;CARIAN LETTER G2;Lo;0;L;;;;;N;;;;;
+102C2;CARIAN LETTER ST;Lo;0;L;;;;;N;;;;;
+102C3;CARIAN LETTER ST2;Lo;0;L;;;;;N;;;;;
+102C4;CARIAN LETTER NG;Lo;0;L;;;;;N;;;;;
+102C5;CARIAN LETTER II;Lo;0;L;;;;;N;;;;;
+102C6;CARIAN LETTER C-39;Lo;0;L;;;;;N;;;;;
+102C7;CARIAN LETTER TT;Lo;0;L;;;;;N;;;;;
+102C8;CARIAN LETTER UUU2;Lo;0;L;;;;;N;;;;;
+102C9;CARIAN LETTER RR;Lo;0;L;;;;;N;;;;;
+102CA;CARIAN LETTER MB;Lo;0;L;;;;;N;;;;;
+102CB;CARIAN LETTER MB2;Lo;0;L;;;;;N;;;;;
+102CC;CARIAN LETTER MB3;Lo;0;L;;;;;N;;;;;
+102CD;CARIAN LETTER MB4;Lo;0;L;;;;;N;;;;;
+102CE;CARIAN LETTER LD2;Lo;0;L;;;;;N;;;;;
+102CF;CARIAN LETTER E2;Lo;0;L;;;;;N;;;;;
+102D0;CARIAN LETTER UUU3;Lo;0;L;;;;;N;;;;;
+102E0;COPTIC EPACT THOUSANDS MARK;Mn;220;NSM;;;;;N;;;;;
+102E1;COPTIC EPACT DIGIT ONE;No;0;EN;;;;1;N;;;;;
+102E2;COPTIC EPACT DIGIT TWO;No;0;EN;;;;2;N;;;;;
+102E3;COPTIC EPACT DIGIT THREE;No;0;EN;;;;3;N;;;;;
+102E4;COPTIC EPACT DIGIT FOUR;No;0;EN;;;;4;N;;;;;
+102E5;COPTIC EPACT DIGIT FIVE;No;0;EN;;;;5;N;;;;;
+102E6;COPTIC EPACT DIGIT SIX;No;0;EN;;;;6;N;;;;;
+102E7;COPTIC EPACT DIGIT SEVEN;No;0;EN;;;;7;N;;;;;
+102E8;COPTIC EPACT DIGIT EIGHT;No;0;EN;;;;8;N;;;;;
+102E9;COPTIC EPACT DIGIT NINE;No;0;EN;;;;9;N;;;;;
+102EA;COPTIC EPACT NUMBER TEN;No;0;EN;;;;10;N;;;;;
+102EB;COPTIC EPACT NUMBER TWENTY;No;0;EN;;;;20;N;;;;;
+102EC;COPTIC EPACT NUMBER THIRTY;No;0;EN;;;;30;N;;;;;
+102ED;COPTIC EPACT NUMBER FORTY;No;0;EN;;;;40;N;;;;;
+102EE;COPTIC EPACT NUMBER FIFTY;No;0;EN;;;;50;N;;;;;
+102EF;COPTIC EPACT NUMBER SIXTY;No;0;EN;;;;60;N;;;;;
+102F0;COPTIC EPACT NUMBER SEVENTY;No;0;EN;;;;70;N;;;;;
+102F1;COPTIC EPACT NUMBER EIGHTY;No;0;EN;;;;80;N;;;;;
+102F2;COPTIC EPACT NUMBER NINETY;No;0;EN;;;;90;N;;;;;
+102F3;COPTIC EPACT NUMBER ONE HUNDRED;No;0;EN;;;;100;N;;;;;
+102F4;COPTIC EPACT NUMBER TWO HUNDRED;No;0;EN;;;;200;N;;;;;
+102F5;COPTIC EPACT NUMBER THREE HUNDRED;No;0;EN;;;;300;N;;;;;
+102F6;COPTIC EPACT NUMBER FOUR HUNDRED;No;0;EN;;;;400;N;;;;;
+102F7;COPTIC EPACT NUMBER FIVE HUNDRED;No;0;EN;;;;500;N;;;;;
+102F8;COPTIC EPACT NUMBER SIX HUNDRED;No;0;EN;;;;600;N;;;;;
+102F9;COPTIC EPACT NUMBER SEVEN HUNDRED;No;0;EN;;;;700;N;;;;;
+102FA;COPTIC EPACT NUMBER EIGHT HUNDRED;No;0;EN;;;;800;N;;;;;
+102FB;COPTIC EPACT NUMBER NINE HUNDRED;No;0;EN;;;;900;N;;;;;
+10300;OLD ITALIC LETTER A;Lo;0;L;;;;;N;;;;;
+10301;OLD ITALIC LETTER BE;Lo;0;L;;;;;N;;;;;
+10302;OLD ITALIC LETTER KE;Lo;0;L;;;;;N;;;;;
+10303;OLD ITALIC LETTER DE;Lo;0;L;;;;;N;;;;;
+10304;OLD ITALIC LETTER E;Lo;0;L;;;;;N;;;;;
+10305;OLD ITALIC LETTER VE;Lo;0;L;;;;;N;;;;;
+10306;OLD ITALIC LETTER ZE;Lo;0;L;;;;;N;;;;;
+10307;OLD ITALIC LETTER HE;Lo;0;L;;;;;N;;;;;
+10308;OLD ITALIC LETTER THE;Lo;0;L;;;;;N;;;;;
+10309;OLD ITALIC LETTER I;Lo;0;L;;;;;N;;;;;
+1030A;OLD ITALIC LETTER KA;Lo;0;L;;;;;N;;;;;
+1030B;OLD ITALIC LETTER EL;Lo;0;L;;;;;N;;;;;
+1030C;OLD ITALIC LETTER EM;Lo;0;L;;;;;N;;;;;
+1030D;OLD ITALIC LETTER EN;Lo;0;L;;;;;N;;;;;
+1030E;OLD ITALIC LETTER ESH;Lo;0;L;;;;;N;;;;;
+1030F;OLD ITALIC LETTER O;Lo;0;L;;;;;N;;;;;
+10310;OLD ITALIC LETTER PE;Lo;0;L;;;;;N;;;;;
+10311;OLD ITALIC LETTER SHE;Lo;0;L;;;;;N;;;;;
+10312;OLD ITALIC LETTER KU;Lo;0;L;;;;;N;;;;;
+10313;OLD ITALIC LETTER ER;Lo;0;L;;;;;N;;;;;
+10314;OLD ITALIC LETTER ES;Lo;0;L;;;;;N;;;;;
+10315;OLD ITALIC LETTER TE;Lo;0;L;;;;;N;;;;;
+10316;OLD ITALIC LETTER U;Lo;0;L;;;;;N;;;;;
+10317;OLD ITALIC LETTER EKS;Lo;0;L;;;;;N;;;;;
+10318;OLD ITALIC LETTER PHE;Lo;0;L;;;;;N;;;;;
+10319;OLD ITALIC LETTER KHE;Lo;0;L;;;;;N;;;;;
+1031A;OLD ITALIC LETTER EF;Lo;0;L;;;;;N;;;;;
+1031B;OLD ITALIC LETTER ERS;Lo;0;L;;;;;N;;;;;
+1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;;;;
+1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;;;;
+1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;;;;
+1031F;OLD ITALIC LETTER ESS;Lo;0;L;;;;;N;;;;;
+10320;OLD ITALIC NUMERAL ONE;No;0;L;;;;1;N;;;;;
+10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;;
+10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;;
+10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;;
+10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;;
+10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;;
+10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;;
+10333;GOTHIC LETTER DAGS;Lo;0;L;;;;;N;;;;;
+10334;GOTHIC LETTER AIHVUS;Lo;0;L;;;;;N;;;;;
+10335;GOTHIC LETTER QAIRTHRA;Lo;0;L;;;;;N;;;;;
+10336;GOTHIC LETTER IUJA;Lo;0;L;;;;;N;;;;;
+10337;GOTHIC LETTER HAGL;Lo;0;L;;;;;N;;;;;
+10338;GOTHIC LETTER THIUTH;Lo;0;L;;;;;N;;;;;
+10339;GOTHIC LETTER EIS;Lo;0;L;;;;;N;;;;;
+1033A;GOTHIC LETTER KUSMA;Lo;0;L;;;;;N;;;;;
+1033B;GOTHIC LETTER LAGUS;Lo;0;L;;;;;N;;;;;
+1033C;GOTHIC LETTER MANNA;Lo;0;L;;;;;N;;;;;
+1033D;GOTHIC LETTER NAUTHS;Lo;0;L;;;;;N;;;;;
+1033E;GOTHIC LETTER JER;Lo;0;L;;;;;N;;;;;
+1033F;GOTHIC LETTER URUS;Lo;0;L;;;;;N;;;;;
+10340;GOTHIC LETTER PAIRTHRA;Lo;0;L;;;;;N;;;;;
+10341;GOTHIC LETTER NINETY;Nl;0;L;;;;90;N;;;;;
+10342;GOTHIC LETTER RAIDA;Lo;0;L;;;;;N;;;;;
+10343;GOTHIC LETTER SAUIL;Lo;0;L;;;;;N;;;;;
+10344;GOTHIC LETTER TEIWS;Lo;0;L;;;;;N;;;;;
+10345;GOTHIC LETTER WINJA;Lo;0;L;;;;;N;;;;;
+10346;GOTHIC LETTER FAIHU;Lo;0;L;;;;;N;;;;;
+10347;GOTHIC LETTER IGGWS;Lo;0;L;;;;;N;;;;;
+10348;GOTHIC LETTER HWAIR;Lo;0;L;;;;;N;;;;;
+10349;GOTHIC LETTER OTHAL;Lo;0;L;;;;;N;;;;;
+1034A;GOTHIC LETTER NINE HUNDRED;Nl;0;L;;;;900;N;;;;;
+10350;OLD PERMIC LETTER AN;Lo;0;L;;;;;N;;;;;
+10351;OLD PERMIC LETTER BUR;Lo;0;L;;;;;N;;;;;
+10352;OLD PERMIC LETTER GAI;Lo;0;L;;;;;N;;;;;
+10353;OLD PERMIC LETTER DOI;Lo;0;L;;;;;N;;;;;
+10354;OLD PERMIC LETTER E;Lo;0;L;;;;;N;;;;;
+10355;OLD PERMIC LETTER ZHOI;Lo;0;L;;;;;N;;;;;
+10356;OLD PERMIC LETTER DZHOI;Lo;0;L;;;;;N;;;;;
+10357;OLD PERMIC LETTER ZATA;Lo;0;L;;;;;N;;;;;
+10358;OLD PERMIC LETTER DZITA;Lo;0;L;;;;;N;;;;;
+10359;OLD PERMIC LETTER I;Lo;0;L;;;;;N;;;;;
+1035A;OLD PERMIC LETTER KOKE;Lo;0;L;;;;;N;;;;;
+1035B;OLD PERMIC LETTER LEI;Lo;0;L;;;;;N;;;;;
+1035C;OLD PERMIC LETTER MENOE;Lo;0;L;;;;;N;;;;;
+1035D;OLD PERMIC LETTER NENOE;Lo;0;L;;;;;N;;;;;
+1035E;OLD PERMIC LETTER VOOI;Lo;0;L;;;;;N;;;;;
+1035F;OLD PERMIC LETTER PEEI;Lo;0;L;;;;;N;;;;;
+10360;OLD PERMIC LETTER REI;Lo;0;L;;;;;N;;;;;
+10361;OLD PERMIC LETTER SII;Lo;0;L;;;;;N;;;;;
+10362;OLD PERMIC LETTER TAI;Lo;0;L;;;;;N;;;;;
+10363;OLD PERMIC LETTER U;Lo;0;L;;;;;N;;;;;
+10364;OLD PERMIC LETTER CHERY;Lo;0;L;;;;;N;;;;;
+10365;OLD PERMIC LETTER SHOOI;Lo;0;L;;;;;N;;;;;
+10366;OLD PERMIC LETTER SHCHOOI;Lo;0;L;;;;;N;;;;;
+10367;OLD PERMIC LETTER YRY;Lo;0;L;;;;;N;;;;;
+10368;OLD PERMIC LETTER YERU;Lo;0;L;;;;;N;;;;;
+10369;OLD PERMIC LETTER O;Lo;0;L;;;;;N;;;;;
+1036A;OLD PERMIC LETTER OO;Lo;0;L;;;;;N;;;;;
+1036B;OLD PERMIC LETTER EF;Lo;0;L;;;;;N;;;;;
+1036C;OLD PERMIC LETTER HA;Lo;0;L;;;;;N;;;;;
+1036D;OLD PERMIC LETTER TSIU;Lo;0;L;;;;;N;;;;;
+1036E;OLD PERMIC LETTER VER;Lo;0;L;;;;;N;;;;;
+1036F;OLD PERMIC LETTER YER;Lo;0;L;;;;;N;;;;;
+10370;OLD PERMIC LETTER YERI;Lo;0;L;;;;;N;;;;;
+10371;OLD PERMIC LETTER YAT;Lo;0;L;;;;;N;;;;;
+10372;OLD PERMIC LETTER IE;Lo;0;L;;;;;N;;;;;
+10373;OLD PERMIC LETTER YU;Lo;0;L;;;;;N;;;;;
+10374;OLD PERMIC LETTER YA;Lo;0;L;;;;;N;;;;;
+10375;OLD PERMIC LETTER IA;Lo;0;L;;;;;N;;;;;
+10376;COMBINING OLD PERMIC LETTER AN;Mn;230;NSM;;;;;N;;;;;
+10377;COMBINING OLD PERMIC LETTER DOI;Mn;230;NSM;;;;;N;;;;;
+10378;COMBINING OLD PERMIC LETTER ZATA;Mn;230;NSM;;;;;N;;;;;
+10379;COMBINING OLD PERMIC LETTER NENOE;Mn;230;NSM;;;;;N;;;;;
+1037A;COMBINING OLD PERMIC LETTER SII;Mn;230;NSM;;;;;N;;;;;
+10380;UGARITIC LETTER ALPA;Lo;0;L;;;;;N;;;;;
+10381;UGARITIC LETTER BETA;Lo;0;L;;;;;N;;;;;
+10382;UGARITIC LETTER GAMLA;Lo;0;L;;;;;N;;;;;
+10383;UGARITIC LETTER KHA;Lo;0;L;;;;;N;;;;;
+10384;UGARITIC LETTER DELTA;Lo;0;L;;;;;N;;;;;
+10385;UGARITIC LETTER HO;Lo;0;L;;;;;N;;;;;
+10386;UGARITIC LETTER WO;Lo;0;L;;;;;N;;;;;
+10387;UGARITIC LETTER ZETA;Lo;0;L;;;;;N;;;;;
+10388;UGARITIC LETTER HOTA;Lo;0;L;;;;;N;;;;;
+10389;UGARITIC LETTER TET;Lo;0;L;;;;;N;;;;;
+1038A;UGARITIC LETTER YOD;Lo;0;L;;;;;N;;;;;
+1038B;UGARITIC LETTER KAF;Lo;0;L;;;;;N;;;;;
+1038C;UGARITIC LETTER SHIN;Lo;0;L;;;;;N;;;;;
+1038D;UGARITIC LETTER LAMDA;Lo;0;L;;;;;N;;;;;
+1038E;UGARITIC LETTER MEM;Lo;0;L;;;;;N;;;;;
+1038F;UGARITIC LETTER DHAL;Lo;0;L;;;;;N;;;;;
+10390;UGARITIC LETTER NUN;Lo;0;L;;;;;N;;;;;
+10391;UGARITIC LETTER ZU;Lo;0;L;;;;;N;;;;;
+10392;UGARITIC LETTER SAMKA;Lo;0;L;;;;;N;;;;;
+10393;UGARITIC LETTER AIN;Lo;0;L;;;;;N;;;;;
+10394;UGARITIC LETTER PU;Lo;0;L;;;;;N;;;;;
+10395;UGARITIC LETTER SADE;Lo;0;L;;;;;N;;;;;
+10396;UGARITIC LETTER QOPA;Lo;0;L;;;;;N;;;;;
+10397;UGARITIC LETTER RASHA;Lo;0;L;;;;;N;;;;;
+10398;UGARITIC LETTER THANNA;Lo;0;L;;;;;N;;;;;
+10399;UGARITIC LETTER GHAIN;Lo;0;L;;;;;N;;;;;
+1039A;UGARITIC LETTER TO;Lo;0;L;;;;;N;;;;;
+1039B;UGARITIC LETTER I;Lo;0;L;;;;;N;;;;;
+1039C;UGARITIC LETTER U;Lo;0;L;;;;;N;;;;;
+1039D;UGARITIC LETTER SSU;Lo;0;L;;;;;N;;;;;
+1039F;UGARITIC WORD DIVIDER;Po;0;L;;;;;N;;;;;
+103A0;OLD PERSIAN SIGN A;Lo;0;L;;;;;N;;;;;
+103A1;OLD PERSIAN SIGN I;Lo;0;L;;;;;N;;;;;
+103A2;OLD PERSIAN SIGN U;Lo;0;L;;;;;N;;;;;
+103A3;OLD PERSIAN SIGN KA;Lo;0;L;;;;;N;;;;;
+103A4;OLD PERSIAN SIGN KU;Lo;0;L;;;;;N;;;;;
+103A5;OLD PERSIAN SIGN GA;Lo;0;L;;;;;N;;;;;
+103A6;OLD PERSIAN SIGN GU;Lo;0;L;;;;;N;;;;;
+103A7;OLD PERSIAN SIGN XA;Lo;0;L;;;;;N;;;;;
+103A8;OLD PERSIAN SIGN CA;Lo;0;L;;;;;N;;;;;
+103A9;OLD PERSIAN SIGN JA;Lo;0;L;;;;;N;;;;;
+103AA;OLD PERSIAN SIGN JI;Lo;0;L;;;;;N;;;;;
+103AB;OLD PERSIAN SIGN TA;Lo;0;L;;;;;N;;;;;
+103AC;OLD PERSIAN SIGN TU;Lo;0;L;;;;;N;;;;;
+103AD;OLD PERSIAN SIGN DA;Lo;0;L;;;;;N;;;;;
+103AE;OLD PERSIAN SIGN DI;Lo;0;L;;;;;N;;;;;
+103AF;OLD PERSIAN SIGN DU;Lo;0;L;;;;;N;;;;;
+103B0;OLD PERSIAN SIGN THA;Lo;0;L;;;;;N;;;;;
+103B1;OLD PERSIAN SIGN PA;Lo;0;L;;;;;N;;;;;
+103B2;OLD PERSIAN SIGN BA;Lo;0;L;;;;;N;;;;;
+103B3;OLD PERSIAN SIGN FA;Lo;0;L;;;;;N;;;;;
+103B4;OLD PERSIAN SIGN NA;Lo;0;L;;;;;N;;;;;
+103B5;OLD PERSIAN SIGN NU;Lo;0;L;;;;;N;;;;;
+103B6;OLD PERSIAN SIGN MA;Lo;0;L;;;;;N;;;;;
+103B7;OLD PERSIAN SIGN MI;Lo;0;L;;;;;N;;;;;
+103B8;OLD PERSIAN SIGN MU;Lo;0;L;;;;;N;;;;;
+103B9;OLD PERSIAN SIGN YA;Lo;0;L;;;;;N;;;;;
+103BA;OLD PERSIAN SIGN VA;Lo;0;L;;;;;N;;;;;
+103BB;OLD PERSIAN SIGN VI;Lo;0;L;;;;;N;;;;;
+103BC;OLD PERSIAN SIGN RA;Lo;0;L;;;;;N;;;;;
+103BD;OLD PERSIAN SIGN RU;Lo;0;L;;;;;N;;;;;
+103BE;OLD PERSIAN SIGN LA;Lo;0;L;;;;;N;;;;;
+103BF;OLD PERSIAN SIGN SA;Lo;0;L;;;;;N;;;;;
+103C0;OLD PERSIAN SIGN ZA;Lo;0;L;;;;;N;;;;;
+103C1;OLD PERSIAN SIGN SHA;Lo;0;L;;;;;N;;;;;
+103C2;OLD PERSIAN SIGN SSA;Lo;0;L;;;;;N;;;;;
+103C3;OLD PERSIAN SIGN HA;Lo;0;L;;;;;N;;;;;
+103C8;OLD PERSIAN SIGN AURAMAZDAA;Lo;0;L;;;;;N;;;;;
+103C9;OLD PERSIAN SIGN AURAMAZDAA-2;Lo;0;L;;;;;N;;;;;
+103CA;OLD PERSIAN SIGN AURAMAZDAAHA;Lo;0;L;;;;;N;;;;;
+103CB;OLD PERSIAN SIGN XSHAAYATHIYA;Lo;0;L;;;;;N;;;;;
+103CC;OLD PERSIAN SIGN DAHYAAUSH;Lo;0;L;;;;;N;;;;;
+103CD;OLD PERSIAN SIGN DAHYAAUSH-2;Lo;0;L;;;;;N;;;;;
+103CE;OLD PERSIAN SIGN BAGA;Lo;0;L;;;;;N;;;;;
+103CF;OLD PERSIAN SIGN BUUMISH;Lo;0;L;;;;;N;;;;;
+103D0;OLD PERSIAN WORD DIVIDER;Po;0;L;;;;;N;;;;;
+103D1;OLD PERSIAN NUMBER ONE;Nl;0;L;;;;1;N;;;;;
+103D2;OLD PERSIAN NUMBER TWO;Nl;0;L;;;;2;N;;;;;
+103D3;OLD PERSIAN NUMBER TEN;Nl;0;L;;;;10;N;;;;;
+103D4;OLD PERSIAN NUMBER TWENTY;Nl;0;L;;;;20;N;;;;;
+103D5;OLD PERSIAN NUMBER HUNDRED;Nl;0;L;;;;100;N;;;;;
+10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428;
+10401;DESERET CAPITAL LETTER LONG E;Lu;0;L;;;;;N;;;;10429;
+10402;DESERET CAPITAL LETTER LONG A;Lu;0;L;;;;;N;;;;1042A;
+10403;DESERET CAPITAL LETTER LONG AH;Lu;0;L;;;;;N;;;;1042B;
+10404;DESERET CAPITAL LETTER LONG O;Lu;0;L;;;;;N;;;;1042C;
+10405;DESERET CAPITAL LETTER LONG OO;Lu;0;L;;;;;N;;;;1042D;
+10406;DESERET CAPITAL LETTER SHORT I;Lu;0;L;;;;;N;;;;1042E;
+10407;DESERET CAPITAL LETTER SHORT E;Lu;0;L;;;;;N;;;;1042F;
+10408;DESERET CAPITAL LETTER SHORT A;Lu;0;L;;;;;N;;;;10430;
+10409;DESERET CAPITAL LETTER SHORT AH;Lu;0;L;;;;;N;;;;10431;
+1040A;DESERET CAPITAL LETTER SHORT O;Lu;0;L;;;;;N;;;;10432;
+1040B;DESERET CAPITAL LETTER SHORT OO;Lu;0;L;;;;;N;;;;10433;
+1040C;DESERET CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;10434;
+1040D;DESERET CAPITAL LETTER OW;Lu;0;L;;;;;N;;;;10435;
+1040E;DESERET CAPITAL LETTER WU;Lu;0;L;;;;;N;;;;10436;
+1040F;DESERET CAPITAL LETTER YEE;Lu;0;L;;;;;N;;;;10437;
+10410;DESERET CAPITAL LETTER H;Lu;0;L;;;;;N;;;;10438;
+10411;DESERET CAPITAL LETTER PEE;Lu;0;L;;;;;N;;;;10439;
+10412;DESERET CAPITAL LETTER BEE;Lu;0;L;;;;;N;;;;1043A;
+10413;DESERET CAPITAL LETTER TEE;Lu;0;L;;;;;N;;;;1043B;
+10414;DESERET CAPITAL LETTER DEE;Lu;0;L;;;;;N;;;;1043C;
+10415;DESERET CAPITAL LETTER CHEE;Lu;0;L;;;;;N;;;;1043D;
+10416;DESERET CAPITAL LETTER JEE;Lu;0;L;;;;;N;;;;1043E;
+10417;DESERET CAPITAL LETTER KAY;Lu;0;L;;;;;N;;;;1043F;
+10418;DESERET CAPITAL LETTER GAY;Lu;0;L;;;;;N;;;;10440;
+10419;DESERET CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;10441;
+1041A;DESERET CAPITAL LETTER VEE;Lu;0;L;;;;;N;;;;10442;
+1041B;DESERET CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;10443;
+1041C;DESERET CAPITAL LETTER THEE;Lu;0;L;;;;;N;;;;10444;
+1041D;DESERET CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;10445;
+1041E;DESERET CAPITAL LETTER ZEE;Lu;0;L;;;;;N;;;;10446;
+1041F;DESERET CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;10447;
+10420;DESERET CAPITAL LETTER ZHEE;Lu;0;L;;;;;N;;;;10448;
+10421;DESERET CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;10449;
+10422;DESERET CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;1044A;
+10423;DESERET CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;1044B;
+10424;DESERET CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;1044C;
+10425;DESERET CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;1044D;
+10426;DESERET CAPITAL LETTER OI;Lu;0;L;;;;;N;;;;1044E;
+10427;DESERET CAPITAL LETTER EW;Lu;0;L;;;;;N;;;;1044F;
+10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400
+10429;DESERET SMALL LETTER LONG E;Ll;0;L;;;;;N;;;10401;;10401
+1042A;DESERET SMALL LETTER LONG A;Ll;0;L;;;;;N;;;10402;;10402
+1042B;DESERET SMALL LETTER LONG AH;Ll;0;L;;;;;N;;;10403;;10403
+1042C;DESERET SMALL LETTER LONG O;Ll;0;L;;;;;N;;;10404;;10404
+1042D;DESERET SMALL LETTER LONG OO;Ll;0;L;;;;;N;;;10405;;10405
+1042E;DESERET SMALL LETTER SHORT I;Ll;0;L;;;;;N;;;10406;;10406
+1042F;DESERET SMALL LETTER SHORT E;Ll;0;L;;;;;N;;;10407;;10407
+10430;DESERET SMALL LETTER SHORT A;Ll;0;L;;;;;N;;;10408;;10408
+10431;DESERET SMALL LETTER SHORT AH;Ll;0;L;;;;;N;;;10409;;10409
+10432;DESERET SMALL LETTER SHORT O;Ll;0;L;;;;;N;;;1040A;;1040A
+10433;DESERET SMALL LETTER SHORT OO;Ll;0;L;;;;;N;;;1040B;;1040B
+10434;DESERET SMALL LETTER AY;Ll;0;L;;;;;N;;;1040C;;1040C
+10435;DESERET SMALL LETTER OW;Ll;0;L;;;;;N;;;1040D;;1040D
+10436;DESERET SMALL LETTER WU;Ll;0;L;;;;;N;;;1040E;;1040E
+10437;DESERET SMALL LETTER YEE;Ll;0;L;;;;;N;;;1040F;;1040F
+10438;DESERET SMALL LETTER H;Ll;0;L;;;;;N;;;10410;;10410
+10439;DESERET SMALL LETTER PEE;Ll;0;L;;;;;N;;;10411;;10411
+1043A;DESERET SMALL LETTER BEE;Ll;0;L;;;;;N;;;10412;;10412
+1043B;DESERET SMALL LETTER TEE;Ll;0;L;;;;;N;;;10413;;10413
+1043C;DESERET SMALL LETTER DEE;Ll;0;L;;;;;N;;;10414;;10414
+1043D;DESERET SMALL LETTER CHEE;Ll;0;L;;;;;N;;;10415;;10415
+1043E;DESERET SMALL LETTER JEE;Ll;0;L;;;;;N;;;10416;;10416
+1043F;DESERET SMALL LETTER KAY;Ll;0;L;;;;;N;;;10417;;10417
+10440;DESERET SMALL LETTER GAY;Ll;0;L;;;;;N;;;10418;;10418
+10441;DESERET SMALL LETTER EF;Ll;0;L;;;;;N;;;10419;;10419
+10442;DESERET SMALL LETTER VEE;Ll;0;L;;;;;N;;;1041A;;1041A
+10443;DESERET SMALL LETTER ETH;Ll;0;L;;;;;N;;;1041B;;1041B
+10444;DESERET SMALL LETTER THEE;Ll;0;L;;;;;N;;;1041C;;1041C
+10445;DESERET SMALL LETTER ES;Ll;0;L;;;;;N;;;1041D;;1041D
+10446;DESERET SMALL LETTER ZEE;Ll;0;L;;;;;N;;;1041E;;1041E
+10447;DESERET SMALL LETTER ESH;Ll;0;L;;;;;N;;;1041F;;1041F
+10448;DESERET SMALL LETTER ZHEE;Ll;0;L;;;;;N;;;10420;;10420
+10449;DESERET SMALL LETTER ER;Ll;0;L;;;;;N;;;10421;;10421
+1044A;DESERET SMALL LETTER EL;Ll;0;L;;;;;N;;;10422;;10422
+1044B;DESERET SMALL LETTER EM;Ll;0;L;;;;;N;;;10423;;10423
+1044C;DESERET SMALL LETTER EN;Ll;0;L;;;;;N;;;10424;;10424
+1044D;DESERET SMALL LETTER ENG;Ll;0;L;;;;;N;;;10425;;10425
+1044E;DESERET SMALL LETTER OI;Ll;0;L;;;;;N;;;10426;;10426
+1044F;DESERET SMALL LETTER EW;Ll;0;L;;;;;N;;;10427;;10427
+10450;SHAVIAN LETTER PEEP;Lo;0;L;;;;;N;;;;;
+10451;SHAVIAN LETTER TOT;Lo;0;L;;;;;N;;;;;
+10452;SHAVIAN LETTER KICK;Lo;0;L;;;;;N;;;;;
+10453;SHAVIAN LETTER FEE;Lo;0;L;;;;;N;;;;;
+10454;SHAVIAN LETTER THIGH;Lo;0;L;;;;;N;;;;;
+10455;SHAVIAN LETTER SO;Lo;0;L;;;;;N;;;;;
+10456;SHAVIAN LETTER SURE;Lo;0;L;;;;;N;;;;;
+10457;SHAVIAN LETTER CHURCH;Lo;0;L;;;;;N;;;;;
+10458;SHAVIAN LETTER YEA;Lo;0;L;;;;;N;;;;;
+10459;SHAVIAN LETTER HUNG;Lo;0;L;;;;;N;;;;;
+1045A;SHAVIAN LETTER BIB;Lo;0;L;;;;;N;;;;;
+1045B;SHAVIAN LETTER DEAD;Lo;0;L;;;;;N;;;;;
+1045C;SHAVIAN LETTER GAG;Lo;0;L;;;;;N;;;;;
+1045D;SHAVIAN LETTER VOW;Lo;0;L;;;;;N;;;;;
+1045E;SHAVIAN LETTER THEY;Lo;0;L;;;;;N;;;;;
+1045F;SHAVIAN LETTER ZOO;Lo;0;L;;;;;N;;;;;
+10460;SHAVIAN LETTER MEASURE;Lo;0;L;;;;;N;;;;;
+10461;SHAVIAN LETTER JUDGE;Lo;0;L;;;;;N;;;;;
+10462;SHAVIAN LETTER WOE;Lo;0;L;;;;;N;;;;;
+10463;SHAVIAN LETTER HA-HA;Lo;0;L;;;;;N;;;;;
+10464;SHAVIAN LETTER LOLL;Lo;0;L;;;;;N;;;;;
+10465;SHAVIAN LETTER MIME;Lo;0;L;;;;;N;;;;;
+10466;SHAVIAN LETTER IF;Lo;0;L;;;;;N;;;;;
+10467;SHAVIAN LETTER EGG;Lo;0;L;;;;;N;;;;;
+10468;SHAVIAN LETTER ASH;Lo;0;L;;;;;N;;;;;
+10469;SHAVIAN LETTER ADO;Lo;0;L;;;;;N;;;;;
+1046A;SHAVIAN LETTER ON;Lo;0;L;;;;;N;;;;;
+1046B;SHAVIAN LETTER WOOL;Lo;0;L;;;;;N;;;;;
+1046C;SHAVIAN LETTER OUT;Lo;0;L;;;;;N;;;;;
+1046D;SHAVIAN LETTER AH;Lo;0;L;;;;;N;;;;;
+1046E;SHAVIAN LETTER ROAR;Lo;0;L;;;;;N;;;;;
+1046F;SHAVIAN LETTER NUN;Lo;0;L;;;;;N;;;;;
+10470;SHAVIAN LETTER EAT;Lo;0;L;;;;;N;;;;;
+10471;SHAVIAN LETTER AGE;Lo;0;L;;;;;N;;;;;
+10472;SHAVIAN LETTER ICE;Lo;0;L;;;;;N;;;;;
+10473;SHAVIAN LETTER UP;Lo;0;L;;;;;N;;;;;
+10474;SHAVIAN LETTER OAK;Lo;0;L;;;;;N;;;;;
+10475;SHAVIAN LETTER OOZE;Lo;0;L;;;;;N;;;;;
+10476;SHAVIAN LETTER OIL;Lo;0;L;;;;;N;;;;;
+10477;SHAVIAN LETTER AWE;Lo;0;L;;;;;N;;;;;
+10478;SHAVIAN LETTER ARE;Lo;0;L;;;;;N;;;;;
+10479;SHAVIAN LETTER OR;Lo;0;L;;;;;N;;;;;
+1047A;SHAVIAN LETTER AIR;Lo;0;L;;;;;N;;;;;
+1047B;SHAVIAN LETTER ERR;Lo;0;L;;;;;N;;;;;
+1047C;SHAVIAN LETTER ARRAY;Lo;0;L;;;;;N;;;;;
+1047D;SHAVIAN LETTER EAR;Lo;0;L;;;;;N;;;;;
+1047E;SHAVIAN LETTER IAN;Lo;0;L;;;;;N;;;;;
+1047F;SHAVIAN LETTER YEW;Lo;0;L;;;;;N;;;;;
+10480;OSMANYA LETTER ALEF;Lo;0;L;;;;;N;;;;;
+10481;OSMANYA LETTER BA;Lo;0;L;;;;;N;;;;;
+10482;OSMANYA LETTER TA;Lo;0;L;;;;;N;;;;;
+10483;OSMANYA LETTER JA;Lo;0;L;;;;;N;;;;;
+10484;OSMANYA LETTER XA;Lo;0;L;;;;;N;;;;;
+10485;OSMANYA LETTER KHA;Lo;0;L;;;;;N;;;;;
+10486;OSMANYA LETTER DEEL;Lo;0;L;;;;;N;;;;;
+10487;OSMANYA LETTER RA;Lo;0;L;;;;;N;;;;;
+10488;OSMANYA LETTER SA;Lo;0;L;;;;;N;;;;;
+10489;OSMANYA LETTER SHIIN;Lo;0;L;;;;;N;;;;;
+1048A;OSMANYA LETTER DHA;Lo;0;L;;;;;N;;;;;
+1048B;OSMANYA LETTER CAYN;Lo;0;L;;;;;N;;;;;
+1048C;OSMANYA LETTER GA;Lo;0;L;;;;;N;;;;;
+1048D;OSMANYA LETTER FA;Lo;0;L;;;;;N;;;;;
+1048E;OSMANYA LETTER QAAF;Lo;0;L;;;;;N;;;;;
+1048F;OSMANYA LETTER KAAF;Lo;0;L;;;;;N;;;;;
+10490;OSMANYA LETTER LAAN;Lo;0;L;;;;;N;;;;;
+10491;OSMANYA LETTER MIIN;Lo;0;L;;;;;N;;;;;
+10492;OSMANYA LETTER NUUN;Lo;0;L;;;;;N;;;;;
+10493;OSMANYA LETTER WAW;Lo;0;L;;;;;N;;;;;
+10494;OSMANYA LETTER HA;Lo;0;L;;;;;N;;;;;
+10495;OSMANYA LETTER YA;Lo;0;L;;;;;N;;;;;
+10496;OSMANYA LETTER A;Lo;0;L;;;;;N;;;;;
+10497;OSMANYA LETTER E;Lo;0;L;;;;;N;;;;;
+10498;OSMANYA LETTER I;Lo;0;L;;;;;N;;;;;
+10499;OSMANYA LETTER O;Lo;0;L;;;;;N;;;;;
+1049A;OSMANYA LETTER U;Lo;0;L;;;;;N;;;;;
+1049B;OSMANYA LETTER AA;Lo;0;L;;;;;N;;;;;
+1049C;OSMANYA LETTER EE;Lo;0;L;;;;;N;;;;;
+1049D;OSMANYA LETTER OO;Lo;0;L;;;;;N;;;;;
+104A0;OSMANYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+104A1;OSMANYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+104A2;OSMANYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+104A3;OSMANYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+104A4;OSMANYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+104A5;OSMANYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+104A6;OSMANYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+104A7;OSMANYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+104A8;OSMANYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+104A9;OSMANYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+104B0;OSAGE CAPITAL LETTER A;Lu;0;L;;;;;N;;;;104D8;
+104B1;OSAGE CAPITAL LETTER AI;Lu;0;L;;;;;N;;;;104D9;
+104B2;OSAGE CAPITAL LETTER AIN;Lu;0;L;;;;;N;;;;104DA;
+104B3;OSAGE CAPITAL LETTER AH;Lu;0;L;;;;;N;;;;104DB;
+104B4;OSAGE CAPITAL LETTER BRA;Lu;0;L;;;;;N;;;;104DC;
+104B5;OSAGE CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;104DD;
+104B6;OSAGE CAPITAL LETTER EHCHA;Lu;0;L;;;;;N;;;;104DE;
+104B7;OSAGE CAPITAL LETTER E;Lu;0;L;;;;;N;;;;104DF;
+104B8;OSAGE CAPITAL LETTER EIN;Lu;0;L;;;;;N;;;;104E0;
+104B9;OSAGE CAPITAL LETTER HA;Lu;0;L;;;;;N;;;;104E1;
+104BA;OSAGE CAPITAL LETTER HYA;Lu;0;L;;;;;N;;;;104E2;
+104BB;OSAGE CAPITAL LETTER I;Lu;0;L;;;;;N;;;;104E3;
+104BC;OSAGE CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;104E4;
+104BD;OSAGE CAPITAL LETTER EHKA;Lu;0;L;;;;;N;;;;104E5;
+104BE;OSAGE CAPITAL LETTER KYA;Lu;0;L;;;;;N;;;;104E6;
+104BF;OSAGE CAPITAL LETTER LA;Lu;0;L;;;;;N;;;;104E7;
+104C0;OSAGE CAPITAL LETTER MA;Lu;0;L;;;;;N;;;;104E8;
+104C1;OSAGE CAPITAL LETTER NA;Lu;0;L;;;;;N;;;;104E9;
+104C2;OSAGE CAPITAL LETTER O;Lu;0;L;;;;;N;;;;104EA;
+104C3;OSAGE CAPITAL LETTER OIN;Lu;0;L;;;;;N;;;;104EB;
+104C4;OSAGE CAPITAL LETTER PA;Lu;0;L;;;;;N;;;;104EC;
+104C5;OSAGE CAPITAL LETTER EHPA;Lu;0;L;;;;;N;;;;104ED;
+104C6;OSAGE CAPITAL LETTER SA;Lu;0;L;;;;;N;;;;104EE;
+104C7;OSAGE CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;104EF;
+104C8;OSAGE CAPITAL LETTER TA;Lu;0;L;;;;;N;;;;104F0;
+104C9;OSAGE CAPITAL LETTER EHTA;Lu;0;L;;;;;N;;;;104F1;
+104CA;OSAGE CAPITAL LETTER TSA;Lu;0;L;;;;;N;;;;104F2;
+104CB;OSAGE CAPITAL LETTER EHTSA;Lu;0;L;;;;;N;;;;104F3;
+104CC;OSAGE CAPITAL LETTER TSHA;Lu;0;L;;;;;N;;;;104F4;
+104CD;OSAGE CAPITAL LETTER DHA;Lu;0;L;;;;;N;;;;104F5;
+104CE;OSAGE CAPITAL LETTER U;Lu;0;L;;;;;N;;;;104F6;
+104CF;OSAGE CAPITAL LETTER WA;Lu;0;L;;;;;N;;;;104F7;
+104D0;OSAGE CAPITAL LETTER KHA;Lu;0;L;;;;;N;;;;104F8;
+104D1;OSAGE CAPITAL LETTER GHA;Lu;0;L;;;;;N;;;;104F9;
+104D2;OSAGE CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;104FA;
+104D3;OSAGE CAPITAL LETTER ZHA;Lu;0;L;;;;;N;;;;104FB;
+104D8;OSAGE SMALL LETTER A;Ll;0;L;;;;;N;;;104B0;;104B0
+104D9;OSAGE SMALL LETTER AI;Ll;0;L;;;;;N;;;104B1;;104B1
+104DA;OSAGE SMALL LETTER AIN;Ll;0;L;;;;;N;;;104B2;;104B2
+104DB;OSAGE SMALL LETTER AH;Ll;0;L;;;;;N;;;104B3;;104B3
+104DC;OSAGE SMALL LETTER BRA;Ll;0;L;;;;;N;;;104B4;;104B4
+104DD;OSAGE SMALL LETTER CHA;Ll;0;L;;;;;N;;;104B5;;104B5
+104DE;OSAGE SMALL LETTER EHCHA;Ll;0;L;;;;;N;;;104B6;;104B6
+104DF;OSAGE SMALL LETTER E;Ll;0;L;;;;;N;;;104B7;;104B7
+104E0;OSAGE SMALL LETTER EIN;Ll;0;L;;;;;N;;;104B8;;104B8
+104E1;OSAGE SMALL LETTER HA;Ll;0;L;;;;;N;;;104B9;;104B9
+104E2;OSAGE SMALL LETTER HYA;Ll;0;L;;;;;N;;;104BA;;104BA
+104E3;OSAGE SMALL LETTER I;Ll;0;L;;;;;N;;;104BB;;104BB
+104E4;OSAGE SMALL LETTER KA;Ll;0;L;;;;;N;;;104BC;;104BC
+104E5;OSAGE SMALL LETTER EHKA;Ll;0;L;;;;;N;;;104BD;;104BD
+104E6;OSAGE SMALL LETTER KYA;Ll;0;L;;;;;N;;;104BE;;104BE
+104E7;OSAGE SMALL LETTER LA;Ll;0;L;;;;;N;;;104BF;;104BF
+104E8;OSAGE SMALL LETTER MA;Ll;0;L;;;;;N;;;104C0;;104C0
+104E9;OSAGE SMALL LETTER NA;Ll;0;L;;;;;N;;;104C1;;104C1
+104EA;OSAGE SMALL LETTER O;Ll;0;L;;;;;N;;;104C2;;104C2
+104EB;OSAGE SMALL LETTER OIN;Ll;0;L;;;;;N;;;104C3;;104C3
+104EC;OSAGE SMALL LETTER PA;Ll;0;L;;;;;N;;;104C4;;104C4
+104ED;OSAGE SMALL LETTER EHPA;Ll;0;L;;;;;N;;;104C5;;104C5
+104EE;OSAGE SMALL LETTER SA;Ll;0;L;;;;;N;;;104C6;;104C6
+104EF;OSAGE SMALL LETTER SHA;Ll;0;L;;;;;N;;;104C7;;104C7
+104F0;OSAGE SMALL LETTER TA;Ll;0;L;;;;;N;;;104C8;;104C8
+104F1;OSAGE SMALL LETTER EHTA;Ll;0;L;;;;;N;;;104C9;;104C9
+104F2;OSAGE SMALL LETTER TSA;Ll;0;L;;;;;N;;;104CA;;104CA
+104F3;OSAGE SMALL LETTER EHTSA;Ll;0;L;;;;;N;;;104CB;;104CB
+104F4;OSAGE SMALL LETTER TSHA;Ll;0;L;;;;;N;;;104CC;;104CC
+104F5;OSAGE SMALL LETTER DHA;Ll;0;L;;;;;N;;;104CD;;104CD
+104F6;OSAGE SMALL LETTER U;Ll;0;L;;;;;N;;;104CE;;104CE
+104F7;OSAGE SMALL LETTER WA;Ll;0;L;;;;;N;;;104CF;;104CF
+104F8;OSAGE SMALL LETTER KHA;Ll;0;L;;;;;N;;;104D0;;104D0
+104F9;OSAGE SMALL LETTER GHA;Ll;0;L;;;;;N;;;104D1;;104D1
+104FA;OSAGE SMALL LETTER ZA;Ll;0;L;;;;;N;;;104D2;;104D2
+104FB;OSAGE SMALL LETTER ZHA;Ll;0;L;;;;;N;;;104D3;;104D3
+10500;ELBASAN LETTER A;Lo;0;L;;;;;N;;;;;
+10501;ELBASAN LETTER BE;Lo;0;L;;;;;N;;;;;
+10502;ELBASAN LETTER CE;Lo;0;L;;;;;N;;;;;
+10503;ELBASAN LETTER CHE;Lo;0;L;;;;;N;;;;;
+10504;ELBASAN LETTER DE;Lo;0;L;;;;;N;;;;;
+10505;ELBASAN LETTER NDE;Lo;0;L;;;;;N;;;;;
+10506;ELBASAN LETTER DHE;Lo;0;L;;;;;N;;;;;
+10507;ELBASAN LETTER EI;Lo;0;L;;;;;N;;;;;
+10508;ELBASAN LETTER E;Lo;0;L;;;;;N;;;;;
+10509;ELBASAN LETTER FE;Lo;0;L;;;;;N;;;;;
+1050A;ELBASAN LETTER GE;Lo;0;L;;;;;N;;;;;
+1050B;ELBASAN LETTER GJE;Lo;0;L;;;;;N;;;;;
+1050C;ELBASAN LETTER HE;Lo;0;L;;;;;N;;;;;
+1050D;ELBASAN LETTER I;Lo;0;L;;;;;N;;;;;
+1050E;ELBASAN LETTER JE;Lo;0;L;;;;;N;;;;;
+1050F;ELBASAN LETTER KE;Lo;0;L;;;;;N;;;;;
+10510;ELBASAN LETTER LE;Lo;0;L;;;;;N;;;;;
+10511;ELBASAN LETTER LLE;Lo;0;L;;;;;N;;;;;
+10512;ELBASAN LETTER ME;Lo;0;L;;;;;N;;;;;
+10513;ELBASAN LETTER NE;Lo;0;L;;;;;N;;;;;
+10514;ELBASAN LETTER NA;Lo;0;L;;;;;N;;;;;
+10515;ELBASAN LETTER NJE;Lo;0;L;;;;;N;;;;;
+10516;ELBASAN LETTER O;Lo;0;L;;;;;N;;;;;
+10517;ELBASAN LETTER PE;Lo;0;L;;;;;N;;;;;
+10518;ELBASAN LETTER QE;Lo;0;L;;;;;N;;;;;
+10519;ELBASAN LETTER RE;Lo;0;L;;;;;N;;;;;
+1051A;ELBASAN LETTER RRE;Lo;0;L;;;;;N;;;;;
+1051B;ELBASAN LETTER SE;Lo;0;L;;;;;N;;;;;
+1051C;ELBASAN LETTER SHE;Lo;0;L;;;;;N;;;;;
+1051D;ELBASAN LETTER TE;Lo;0;L;;;;;N;;;;;
+1051E;ELBASAN LETTER THE;Lo;0;L;;;;;N;;;;;
+1051F;ELBASAN LETTER U;Lo;0;L;;;;;N;;;;;
+10520;ELBASAN LETTER VE;Lo;0;L;;;;;N;;;;;
+10521;ELBASAN LETTER XE;Lo;0;L;;;;;N;;;;;
+10522;ELBASAN LETTER Y;Lo;0;L;;;;;N;;;;;
+10523;ELBASAN LETTER ZE;Lo;0;L;;;;;N;;;;;
+10524;ELBASAN LETTER ZHE;Lo;0;L;;;;;N;;;;;
+10525;ELBASAN LETTER GHE;Lo;0;L;;;;;N;;;;;
+10526;ELBASAN LETTER GHAMMA;Lo;0;L;;;;;N;;;;;
+10527;ELBASAN LETTER KHE;Lo;0;L;;;;;N;;;;;
+10530;CAUCASIAN ALBANIAN LETTER ALT;Lo;0;L;;;;;N;;;;;
+10531;CAUCASIAN ALBANIAN LETTER BET;Lo;0;L;;;;;N;;;;;
+10532;CAUCASIAN ALBANIAN LETTER GIM;Lo;0;L;;;;;N;;;;;
+10533;CAUCASIAN ALBANIAN LETTER DAT;Lo;0;L;;;;;N;;;;;
+10534;CAUCASIAN ALBANIAN LETTER EB;Lo;0;L;;;;;N;;;;;
+10535;CAUCASIAN ALBANIAN LETTER ZARL;Lo;0;L;;;;;N;;;;;
+10536;CAUCASIAN ALBANIAN LETTER EYN;Lo;0;L;;;;;N;;;;;
+10537;CAUCASIAN ALBANIAN LETTER ZHIL;Lo;0;L;;;;;N;;;;;
+10538;CAUCASIAN ALBANIAN LETTER TAS;Lo;0;L;;;;;N;;;;;
+10539;CAUCASIAN ALBANIAN LETTER CHA;Lo;0;L;;;;;N;;;;;
+1053A;CAUCASIAN ALBANIAN LETTER YOWD;Lo;0;L;;;;;N;;;;;
+1053B;CAUCASIAN ALBANIAN LETTER ZHA;Lo;0;L;;;;;N;;;;;
+1053C;CAUCASIAN ALBANIAN LETTER IRB;Lo;0;L;;;;;N;;;;;
+1053D;CAUCASIAN ALBANIAN LETTER SHA;Lo;0;L;;;;;N;;;;;
+1053E;CAUCASIAN ALBANIAN LETTER LAN;Lo;0;L;;;;;N;;;;;
+1053F;CAUCASIAN ALBANIAN LETTER INYA;Lo;0;L;;;;;N;;;;;
+10540;CAUCASIAN ALBANIAN LETTER XEYN;Lo;0;L;;;;;N;;;;;
+10541;CAUCASIAN ALBANIAN LETTER DYAN;Lo;0;L;;;;;N;;;;;
+10542;CAUCASIAN ALBANIAN LETTER CAR;Lo;0;L;;;;;N;;;;;
+10543;CAUCASIAN ALBANIAN LETTER JHOX;Lo;0;L;;;;;N;;;;;
+10544;CAUCASIAN ALBANIAN LETTER KAR;Lo;0;L;;;;;N;;;;;
+10545;CAUCASIAN ALBANIAN LETTER LYIT;Lo;0;L;;;;;N;;;;;
+10546;CAUCASIAN ALBANIAN LETTER HEYT;Lo;0;L;;;;;N;;;;;
+10547;CAUCASIAN ALBANIAN LETTER QAY;Lo;0;L;;;;;N;;;;;
+10548;CAUCASIAN ALBANIAN LETTER AOR;Lo;0;L;;;;;N;;;;;
+10549;CAUCASIAN ALBANIAN LETTER CHOY;Lo;0;L;;;;;N;;;;;
+1054A;CAUCASIAN ALBANIAN LETTER CHI;Lo;0;L;;;;;N;;;;;
+1054B;CAUCASIAN ALBANIAN LETTER CYAY;Lo;0;L;;;;;N;;;;;
+1054C;CAUCASIAN ALBANIAN LETTER MAQ;Lo;0;L;;;;;N;;;;;
+1054D;CAUCASIAN ALBANIAN LETTER QAR;Lo;0;L;;;;;N;;;;;
+1054E;CAUCASIAN ALBANIAN LETTER NOWC;Lo;0;L;;;;;N;;;;;
+1054F;CAUCASIAN ALBANIAN LETTER DZYAY;Lo;0;L;;;;;N;;;;;
+10550;CAUCASIAN ALBANIAN LETTER SHAK;Lo;0;L;;;;;N;;;;;
+10551;CAUCASIAN ALBANIAN LETTER JAYN;Lo;0;L;;;;;N;;;;;
+10552;CAUCASIAN ALBANIAN LETTER ON;Lo;0;L;;;;;N;;;;;
+10553;CAUCASIAN ALBANIAN LETTER TYAY;Lo;0;L;;;;;N;;;;;
+10554;CAUCASIAN ALBANIAN LETTER FAM;Lo;0;L;;;;;N;;;;;
+10555;CAUCASIAN ALBANIAN LETTER DZAY;Lo;0;L;;;;;N;;;;;
+10556;CAUCASIAN ALBANIAN LETTER CHAT;Lo;0;L;;;;;N;;;;;
+10557;CAUCASIAN ALBANIAN LETTER PEN;Lo;0;L;;;;;N;;;;;
+10558;CAUCASIAN ALBANIAN LETTER GHEYS;Lo;0;L;;;;;N;;;;;
+10559;CAUCASIAN ALBANIAN LETTER RAT;Lo;0;L;;;;;N;;;;;
+1055A;CAUCASIAN ALBANIAN LETTER SEYK;Lo;0;L;;;;;N;;;;;
+1055B;CAUCASIAN ALBANIAN LETTER VEYZ;Lo;0;L;;;;;N;;;;;
+1055C;CAUCASIAN ALBANIAN LETTER TIWR;Lo;0;L;;;;;N;;;;;
+1055D;CAUCASIAN ALBANIAN LETTER SHOY;Lo;0;L;;;;;N;;;;;
+1055E;CAUCASIAN ALBANIAN LETTER IWN;Lo;0;L;;;;;N;;;;;
+1055F;CAUCASIAN ALBANIAN LETTER CYAW;Lo;0;L;;;;;N;;;;;
+10560;CAUCASIAN ALBANIAN LETTER CAYN;Lo;0;L;;;;;N;;;;;
+10561;CAUCASIAN ALBANIAN LETTER YAYD;Lo;0;L;;;;;N;;;;;
+10562;CAUCASIAN ALBANIAN LETTER PIWR;Lo;0;L;;;;;N;;;;;
+10563;CAUCASIAN ALBANIAN LETTER KIW;Lo;0;L;;;;;N;;;;;
+1056F;CAUCASIAN ALBANIAN CITATION MARK;Po;0;L;;;;;N;;;;;
+10600;LINEAR A SIGN AB001;Lo;0;L;;;;;N;;;;;
+10601;LINEAR A SIGN AB002;Lo;0;L;;;;;N;;;;;
+10602;LINEAR A SIGN AB003;Lo;0;L;;;;;N;;;;;
+10603;LINEAR A SIGN AB004;Lo;0;L;;;;;N;;;;;
+10604;LINEAR A SIGN AB005;Lo;0;L;;;;;N;;;;;
+10605;LINEAR A SIGN AB006;Lo;0;L;;;;;N;;;;;
+10606;LINEAR A SIGN AB007;Lo;0;L;;;;;N;;;;;
+10607;LINEAR A SIGN AB008;Lo;0;L;;;;;N;;;;;
+10608;LINEAR A SIGN AB009;Lo;0;L;;;;;N;;;;;
+10609;LINEAR A SIGN AB010;Lo;0;L;;;;;N;;;;;
+1060A;LINEAR A SIGN AB011;Lo;0;L;;;;;N;;;;;
+1060B;LINEAR A SIGN AB013;Lo;0;L;;;;;N;;;;;
+1060C;LINEAR A SIGN AB016;Lo;0;L;;;;;N;;;;;
+1060D;LINEAR A SIGN AB017;Lo;0;L;;;;;N;;;;;
+1060E;LINEAR A SIGN AB020;Lo;0;L;;;;;N;;;;;
+1060F;LINEAR A SIGN AB021;Lo;0;L;;;;;N;;;;;
+10610;LINEAR A SIGN AB021F;Lo;0;L;;;;;N;;;;;
+10611;LINEAR A SIGN AB021M;Lo;0;L;;;;;N;;;;;
+10612;LINEAR A SIGN AB022;Lo;0;L;;;;;N;;;;;
+10613;LINEAR A SIGN AB022F;Lo;0;L;;;;;N;;;;;
+10614;LINEAR A SIGN AB022M;Lo;0;L;;;;;N;;;;;
+10615;LINEAR A SIGN AB023;Lo;0;L;;;;;N;;;;;
+10616;LINEAR A SIGN AB023M;Lo;0;L;;;;;N;;;;;
+10617;LINEAR A SIGN AB024;Lo;0;L;;;;;N;;;;;
+10618;LINEAR A SIGN AB026;Lo;0;L;;;;;N;;;;;
+10619;LINEAR A SIGN AB027;Lo;0;L;;;;;N;;;;;
+1061A;LINEAR A SIGN AB028;Lo;0;L;;;;;N;;;;;
+1061B;LINEAR A SIGN A028B;Lo;0;L;;;;;N;;;;;
+1061C;LINEAR A SIGN AB029;Lo;0;L;;;;;N;;;;;
+1061D;LINEAR A SIGN AB030;Lo;0;L;;;;;N;;;;;
+1061E;LINEAR A SIGN AB031;Lo;0;L;;;;;N;;;;;
+1061F;LINEAR A SIGN AB034;Lo;0;L;;;;;N;;;;;
+10620;LINEAR A SIGN AB037;Lo;0;L;;;;;N;;;;;
+10621;LINEAR A SIGN AB038;Lo;0;L;;;;;N;;;;;
+10622;LINEAR A SIGN AB039;Lo;0;L;;;;;N;;;;;
+10623;LINEAR A SIGN AB040;Lo;0;L;;;;;N;;;;;
+10624;LINEAR A SIGN AB041;Lo;0;L;;;;;N;;;;;
+10625;LINEAR A SIGN AB044;Lo;0;L;;;;;N;;;;;
+10626;LINEAR A SIGN AB045;Lo;0;L;;;;;N;;;;;
+10627;LINEAR A SIGN AB046;Lo;0;L;;;;;N;;;;;
+10628;LINEAR A SIGN AB047;Lo;0;L;;;;;N;;;;;
+10629;LINEAR A SIGN AB048;Lo;0;L;;;;;N;;;;;
+1062A;LINEAR A SIGN AB049;Lo;0;L;;;;;N;;;;;
+1062B;LINEAR A SIGN AB050;Lo;0;L;;;;;N;;;;;
+1062C;LINEAR A SIGN AB051;Lo;0;L;;;;;N;;;;;
+1062D;LINEAR A SIGN AB053;Lo;0;L;;;;;N;;;;;
+1062E;LINEAR A SIGN AB054;Lo;0;L;;;;;N;;;;;
+1062F;LINEAR A SIGN AB055;Lo;0;L;;;;;N;;;;;
+10630;LINEAR A SIGN AB056;Lo;0;L;;;;;N;;;;;
+10631;LINEAR A SIGN AB057;Lo;0;L;;;;;N;;;;;
+10632;LINEAR A SIGN AB058;Lo;0;L;;;;;N;;;;;
+10633;LINEAR A SIGN AB059;Lo;0;L;;;;;N;;;;;
+10634;LINEAR A SIGN AB060;Lo;0;L;;;;;N;;;;;
+10635;LINEAR A SIGN AB061;Lo;0;L;;;;;N;;;;;
+10636;LINEAR A SIGN AB065;Lo;0;L;;;;;N;;;;;
+10637;LINEAR A SIGN AB066;Lo;0;L;;;;;N;;;;;
+10638;LINEAR A SIGN AB067;Lo;0;L;;;;;N;;;;;
+10639;LINEAR A SIGN AB069;Lo;0;L;;;;;N;;;;;
+1063A;LINEAR A SIGN AB070;Lo;0;L;;;;;N;;;;;
+1063B;LINEAR A SIGN AB073;Lo;0;L;;;;;N;;;;;
+1063C;LINEAR A SIGN AB074;Lo;0;L;;;;;N;;;;;
+1063D;LINEAR A SIGN AB076;Lo;0;L;;;;;N;;;;;
+1063E;LINEAR A SIGN AB077;Lo;0;L;;;;;N;;;;;
+1063F;LINEAR A SIGN AB078;Lo;0;L;;;;;N;;;;;
+10640;LINEAR A SIGN AB079;Lo;0;L;;;;;N;;;;;
+10641;LINEAR A SIGN AB080;Lo;0;L;;;;;N;;;;;
+10642;LINEAR A SIGN AB081;Lo;0;L;;;;;N;;;;;
+10643;LINEAR A SIGN AB082;Lo;0;L;;;;;N;;;;;
+10644;LINEAR A SIGN AB085;Lo;0;L;;;;;N;;;;;
+10645;LINEAR A SIGN AB086;Lo;0;L;;;;;N;;;;;
+10646;LINEAR A SIGN AB087;Lo;0;L;;;;;N;;;;;
+10647;LINEAR A SIGN A100-102;Lo;0;L;;;;;N;;;;;
+10648;LINEAR A SIGN AB118;Lo;0;L;;;;;N;;;;;
+10649;LINEAR A SIGN AB120;Lo;0;L;;;;;N;;;;;
+1064A;LINEAR A SIGN A120B;Lo;0;L;;;;;N;;;;;
+1064B;LINEAR A SIGN AB122;Lo;0;L;;;;;N;;;;;
+1064C;LINEAR A SIGN AB123;Lo;0;L;;;;;N;;;;;
+1064D;LINEAR A SIGN AB131A;Lo;0;L;;;;;N;;;;;
+1064E;LINEAR A SIGN AB131B;Lo;0;L;;;;;N;;;;;
+1064F;LINEAR A SIGN A131C;Lo;0;L;;;;;N;;;;;
+10650;LINEAR A SIGN AB164;Lo;0;L;;;;;N;;;;;
+10651;LINEAR A SIGN AB171;Lo;0;L;;;;;N;;;;;
+10652;LINEAR A SIGN AB180;Lo;0;L;;;;;N;;;;;
+10653;LINEAR A SIGN AB188;Lo;0;L;;;;;N;;;;;
+10654;LINEAR A SIGN AB191;Lo;0;L;;;;;N;;;;;
+10655;LINEAR A SIGN A301;Lo;0;L;;;;;N;;;;;
+10656;LINEAR A SIGN A302;Lo;0;L;;;;;N;;;;;
+10657;LINEAR A SIGN A303;Lo;0;L;;;;;N;;;;;
+10658;LINEAR A SIGN A304;Lo;0;L;;;;;N;;;;;
+10659;LINEAR A SIGN A305;Lo;0;L;;;;;N;;;;;
+1065A;LINEAR A SIGN A306;Lo;0;L;;;;;N;;;;;
+1065B;LINEAR A SIGN A307;Lo;0;L;;;;;N;;;;;
+1065C;LINEAR A SIGN A308;Lo;0;L;;;;;N;;;;;
+1065D;LINEAR A SIGN A309A;Lo;0;L;;;;;N;;;;;
+1065E;LINEAR A SIGN A309B;Lo;0;L;;;;;N;;;;;
+1065F;LINEAR A SIGN A309C;Lo;0;L;;;;;N;;;;;
+10660;LINEAR A SIGN A310;Lo;0;L;;;;;N;;;;;
+10661;LINEAR A SIGN A311;Lo;0;L;;;;;N;;;;;
+10662;LINEAR A SIGN A312;Lo;0;L;;;;;N;;;;;
+10663;LINEAR A SIGN A313A;Lo;0;L;;;;;N;;;;;
+10664;LINEAR A SIGN A313B;Lo;0;L;;;;;N;;;;;
+10665;LINEAR A SIGN A313C;Lo;0;L;;;;;N;;;;;
+10666;LINEAR A SIGN A314;Lo;0;L;;;;;N;;;;;
+10667;LINEAR A SIGN A315;Lo;0;L;;;;;N;;;;;
+10668;LINEAR A SIGN A316;Lo;0;L;;;;;N;;;;;
+10669;LINEAR A SIGN A317;Lo;0;L;;;;;N;;;;;
+1066A;LINEAR A SIGN A318;Lo;0;L;;;;;N;;;;;
+1066B;LINEAR A SIGN A319;Lo;0;L;;;;;N;;;;;
+1066C;LINEAR A SIGN A320;Lo;0;L;;;;;N;;;;;
+1066D;LINEAR A SIGN A321;Lo;0;L;;;;;N;;;;;
+1066E;LINEAR A SIGN A322;Lo;0;L;;;;;N;;;;;
+1066F;LINEAR A SIGN A323;Lo;0;L;;;;;N;;;;;
+10670;LINEAR A SIGN A324;Lo;0;L;;;;;N;;;;;
+10671;LINEAR A SIGN A325;Lo;0;L;;;;;N;;;;;
+10672;LINEAR A SIGN A326;Lo;0;L;;;;;N;;;;;
+10673;LINEAR A SIGN A327;Lo;0;L;;;;;N;;;;;
+10674;LINEAR A SIGN A328;Lo;0;L;;;;;N;;;;;
+10675;LINEAR A SIGN A329;Lo;0;L;;;;;N;;;;;
+10676;LINEAR A SIGN A330;Lo;0;L;;;;;N;;;;;
+10677;LINEAR A SIGN A331;Lo;0;L;;;;;N;;;;;
+10678;LINEAR A SIGN A332;Lo;0;L;;;;;N;;;;;
+10679;LINEAR A SIGN A333;Lo;0;L;;;;;N;;;;;
+1067A;LINEAR A SIGN A334;Lo;0;L;;;;;N;;;;;
+1067B;LINEAR A SIGN A335;Lo;0;L;;;;;N;;;;;
+1067C;LINEAR A SIGN A336;Lo;0;L;;;;;N;;;;;
+1067D;LINEAR A SIGN A337;Lo;0;L;;;;;N;;;;;
+1067E;LINEAR A SIGN A338;Lo;0;L;;;;;N;;;;;
+1067F;LINEAR A SIGN A339;Lo;0;L;;;;;N;;;;;
+10680;LINEAR A SIGN A340;Lo;0;L;;;;;N;;;;;
+10681;LINEAR A SIGN A341;Lo;0;L;;;;;N;;;;;
+10682;LINEAR A SIGN A342;Lo;0;L;;;;;N;;;;;
+10683;LINEAR A SIGN A343;Lo;0;L;;;;;N;;;;;
+10684;LINEAR A SIGN A344;Lo;0;L;;;;;N;;;;;
+10685;LINEAR A SIGN A345;Lo;0;L;;;;;N;;;;;
+10686;LINEAR A SIGN A346;Lo;0;L;;;;;N;;;;;
+10687;LINEAR A SIGN A347;Lo;0;L;;;;;N;;;;;
+10688;LINEAR A SIGN A348;Lo;0;L;;;;;N;;;;;
+10689;LINEAR A SIGN A349;Lo;0;L;;;;;N;;;;;
+1068A;LINEAR A SIGN A350;Lo;0;L;;;;;N;;;;;
+1068B;LINEAR A SIGN A351;Lo;0;L;;;;;N;;;;;
+1068C;LINEAR A SIGN A352;Lo;0;L;;;;;N;;;;;
+1068D;LINEAR A SIGN A353;Lo;0;L;;;;;N;;;;;
+1068E;LINEAR A SIGN A354;Lo;0;L;;;;;N;;;;;
+1068F;LINEAR A SIGN A355;Lo;0;L;;;;;N;;;;;
+10690;LINEAR A SIGN A356;Lo;0;L;;;;;N;;;;;
+10691;LINEAR A SIGN A357;Lo;0;L;;;;;N;;;;;
+10692;LINEAR A SIGN A358;Lo;0;L;;;;;N;;;;;
+10693;LINEAR A SIGN A359;Lo;0;L;;;;;N;;;;;
+10694;LINEAR A SIGN A360;Lo;0;L;;;;;N;;;;;
+10695;LINEAR A SIGN A361;Lo;0;L;;;;;N;;;;;
+10696;LINEAR A SIGN A362;Lo;0;L;;;;;N;;;;;
+10697;LINEAR A SIGN A363;Lo;0;L;;;;;N;;;;;
+10698;LINEAR A SIGN A364;Lo;0;L;;;;;N;;;;;
+10699;LINEAR A SIGN A365;Lo;0;L;;;;;N;;;;;
+1069A;LINEAR A SIGN A366;Lo;0;L;;;;;N;;;;;
+1069B;LINEAR A SIGN A367;Lo;0;L;;;;;N;;;;;
+1069C;LINEAR A SIGN A368;Lo;0;L;;;;;N;;;;;
+1069D;LINEAR A SIGN A369;Lo;0;L;;;;;N;;;;;
+1069E;LINEAR A SIGN A370;Lo;0;L;;;;;N;;;;;
+1069F;LINEAR A SIGN A371;Lo;0;L;;;;;N;;;;;
+106A0;LINEAR A SIGN A400-VAS;Lo;0;L;;;;;N;;;;;
+106A1;LINEAR A SIGN A401-VAS;Lo;0;L;;;;;N;;;;;
+106A2;LINEAR A SIGN A402-VAS;Lo;0;L;;;;;N;;;;;
+106A3;LINEAR A SIGN A403-VAS;Lo;0;L;;;;;N;;;;;
+106A4;LINEAR A SIGN A404-VAS;Lo;0;L;;;;;N;;;;;
+106A5;LINEAR A SIGN A405-VAS;Lo;0;L;;;;;N;;;;;
+106A6;LINEAR A SIGN A406-VAS;Lo;0;L;;;;;N;;;;;
+106A7;LINEAR A SIGN A407-VAS;Lo;0;L;;;;;N;;;;;
+106A8;LINEAR A SIGN A408-VAS;Lo;0;L;;;;;N;;;;;
+106A9;LINEAR A SIGN A409-VAS;Lo;0;L;;;;;N;;;;;
+106AA;LINEAR A SIGN A410-VAS;Lo;0;L;;;;;N;;;;;
+106AB;LINEAR A SIGN A411-VAS;Lo;0;L;;;;;N;;;;;
+106AC;LINEAR A SIGN A412-VAS;Lo;0;L;;;;;N;;;;;
+106AD;LINEAR A SIGN A413-VAS;Lo;0;L;;;;;N;;;;;
+106AE;LINEAR A SIGN A414-VAS;Lo;0;L;;;;;N;;;;;
+106AF;LINEAR A SIGN A415-VAS;Lo;0;L;;;;;N;;;;;
+106B0;LINEAR A SIGN A416-VAS;Lo;0;L;;;;;N;;;;;
+106B1;LINEAR A SIGN A417-VAS;Lo;0;L;;;;;N;;;;;
+106B2;LINEAR A SIGN A418-VAS;Lo;0;L;;;;;N;;;;;
+106B3;LINEAR A SIGN A501;Lo;0;L;;;;;N;;;;;
+106B4;LINEAR A SIGN A502;Lo;0;L;;;;;N;;;;;
+106B5;LINEAR A SIGN A503;Lo;0;L;;;;;N;;;;;
+106B6;LINEAR A SIGN A504;Lo;0;L;;;;;N;;;;;
+106B7;LINEAR A SIGN A505;Lo;0;L;;;;;N;;;;;
+106B8;LINEAR A SIGN A506;Lo;0;L;;;;;N;;;;;
+106B9;LINEAR A SIGN A508;Lo;0;L;;;;;N;;;;;
+106BA;LINEAR A SIGN A509;Lo;0;L;;;;;N;;;;;
+106BB;LINEAR A SIGN A510;Lo;0;L;;;;;N;;;;;
+106BC;LINEAR A SIGN A511;Lo;0;L;;;;;N;;;;;
+106BD;LINEAR A SIGN A512;Lo;0;L;;;;;N;;;;;
+106BE;LINEAR A SIGN A513;Lo;0;L;;;;;N;;;;;
+106BF;LINEAR A SIGN A515;Lo;0;L;;;;;N;;;;;
+106C0;LINEAR A SIGN A516;Lo;0;L;;;;;N;;;;;
+106C1;LINEAR A SIGN A520;Lo;0;L;;;;;N;;;;;
+106C2;LINEAR A SIGN A521;Lo;0;L;;;;;N;;;;;
+106C3;LINEAR A SIGN A523;Lo;0;L;;;;;N;;;;;
+106C4;LINEAR A SIGN A524;Lo;0;L;;;;;N;;;;;
+106C5;LINEAR A SIGN A525;Lo;0;L;;;;;N;;;;;
+106C6;LINEAR A SIGN A526;Lo;0;L;;;;;N;;;;;
+106C7;LINEAR A SIGN A527;Lo;0;L;;;;;N;;;;;
+106C8;LINEAR A SIGN A528;Lo;0;L;;;;;N;;;;;
+106C9;LINEAR A SIGN A529;Lo;0;L;;;;;N;;;;;
+106CA;LINEAR A SIGN A530;Lo;0;L;;;;;N;;;;;
+106CB;LINEAR A SIGN A531;Lo;0;L;;;;;N;;;;;
+106CC;LINEAR A SIGN A532;Lo;0;L;;;;;N;;;;;
+106CD;LINEAR A SIGN A534;Lo;0;L;;;;;N;;;;;
+106CE;LINEAR A SIGN A535;Lo;0;L;;;;;N;;;;;
+106CF;LINEAR A SIGN A536;Lo;0;L;;;;;N;;;;;
+106D0;LINEAR A SIGN A537;Lo;0;L;;;;;N;;;;;
+106D1;LINEAR A SIGN A538;Lo;0;L;;;;;N;;;;;
+106D2;LINEAR A SIGN A539;Lo;0;L;;;;;N;;;;;
+106D3;LINEAR A SIGN A540;Lo;0;L;;;;;N;;;;;
+106D4;LINEAR A SIGN A541;Lo;0;L;;;;;N;;;;;
+106D5;LINEAR A SIGN A542;Lo;0;L;;;;;N;;;;;
+106D6;LINEAR A SIGN A545;Lo;0;L;;;;;N;;;;;
+106D7;LINEAR A SIGN A547;Lo;0;L;;;;;N;;;;;
+106D8;LINEAR A SIGN A548;Lo;0;L;;;;;N;;;;;
+106D9;LINEAR A SIGN A549;Lo;0;L;;;;;N;;;;;
+106DA;LINEAR A SIGN A550;Lo;0;L;;;;;N;;;;;
+106DB;LINEAR A SIGN A551;Lo;0;L;;;;;N;;;;;
+106DC;LINEAR A SIGN A552;Lo;0;L;;;;;N;;;;;
+106DD;LINEAR A SIGN A553;Lo;0;L;;;;;N;;;;;
+106DE;LINEAR A SIGN A554;Lo;0;L;;;;;N;;;;;
+106DF;LINEAR A SIGN A555;Lo;0;L;;;;;N;;;;;
+106E0;LINEAR A SIGN A556;Lo;0;L;;;;;N;;;;;
+106E1;LINEAR A SIGN A557;Lo;0;L;;;;;N;;;;;
+106E2;LINEAR A SIGN A559;Lo;0;L;;;;;N;;;;;
+106E3;LINEAR A SIGN A563;Lo;0;L;;;;;N;;;;;
+106E4;LINEAR A SIGN A564;Lo;0;L;;;;;N;;;;;
+106E5;LINEAR A SIGN A565;Lo;0;L;;;;;N;;;;;
+106E6;LINEAR A SIGN A566;Lo;0;L;;;;;N;;;;;
+106E7;LINEAR A SIGN A568;Lo;0;L;;;;;N;;;;;
+106E8;LINEAR A SIGN A569;Lo;0;L;;;;;N;;;;;
+106E9;LINEAR A SIGN A570;Lo;0;L;;;;;N;;;;;
+106EA;LINEAR A SIGN A571;Lo;0;L;;;;;N;;;;;
+106EB;LINEAR A SIGN A572;Lo;0;L;;;;;N;;;;;
+106EC;LINEAR A SIGN A573;Lo;0;L;;;;;N;;;;;
+106ED;LINEAR A SIGN A574;Lo;0;L;;;;;N;;;;;
+106EE;LINEAR A SIGN A575;Lo;0;L;;;;;N;;;;;
+106EF;LINEAR A SIGN A576;Lo;0;L;;;;;N;;;;;
+106F0;LINEAR A SIGN A577;Lo;0;L;;;;;N;;;;;
+106F1;LINEAR A SIGN A578;Lo;0;L;;;;;N;;;;;
+106F2;LINEAR A SIGN A579;Lo;0;L;;;;;N;;;;;
+106F3;LINEAR A SIGN A580;Lo;0;L;;;;;N;;;;;
+106F4;LINEAR A SIGN A581;Lo;0;L;;;;;N;;;;;
+106F5;LINEAR A SIGN A582;Lo;0;L;;;;;N;;;;;
+106F6;LINEAR A SIGN A583;Lo;0;L;;;;;N;;;;;
+106F7;LINEAR A SIGN A584;Lo;0;L;;;;;N;;;;;
+106F8;LINEAR A SIGN A585;Lo;0;L;;;;;N;;;;;
+106F9;LINEAR A SIGN A586;Lo;0;L;;;;;N;;;;;
+106FA;LINEAR A SIGN A587;Lo;0;L;;;;;N;;;;;
+106FB;LINEAR A SIGN A588;Lo;0;L;;;;;N;;;;;
+106FC;LINEAR A SIGN A589;Lo;0;L;;;;;N;;;;;
+106FD;LINEAR A SIGN A591;Lo;0;L;;;;;N;;;;;
+106FE;LINEAR A SIGN A592;Lo;0;L;;;;;N;;;;;
+106FF;LINEAR A SIGN A594;Lo;0;L;;;;;N;;;;;
+10700;LINEAR A SIGN A595;Lo;0;L;;;;;N;;;;;
+10701;LINEAR A SIGN A596;Lo;0;L;;;;;N;;;;;
+10702;LINEAR A SIGN A598;Lo;0;L;;;;;N;;;;;
+10703;LINEAR A SIGN A600;Lo;0;L;;;;;N;;;;;
+10704;LINEAR A SIGN A601;Lo;0;L;;;;;N;;;;;
+10705;LINEAR A SIGN A602;Lo;0;L;;;;;N;;;;;
+10706;LINEAR A SIGN A603;Lo;0;L;;;;;N;;;;;
+10707;LINEAR A SIGN A604;Lo;0;L;;;;;N;;;;;
+10708;LINEAR A SIGN A606;Lo;0;L;;;;;N;;;;;
+10709;LINEAR A SIGN A608;Lo;0;L;;;;;N;;;;;
+1070A;LINEAR A SIGN A609;Lo;0;L;;;;;N;;;;;
+1070B;LINEAR A SIGN A610;Lo;0;L;;;;;N;;;;;
+1070C;LINEAR A SIGN A611;Lo;0;L;;;;;N;;;;;
+1070D;LINEAR A SIGN A612;Lo;0;L;;;;;N;;;;;
+1070E;LINEAR A SIGN A613;Lo;0;L;;;;;N;;;;;
+1070F;LINEAR A SIGN A614;Lo;0;L;;;;;N;;;;;
+10710;LINEAR A SIGN A615;Lo;0;L;;;;;N;;;;;
+10711;LINEAR A SIGN A616;Lo;0;L;;;;;N;;;;;
+10712;LINEAR A SIGN A617;Lo;0;L;;;;;N;;;;;
+10713;LINEAR A SIGN A618;Lo;0;L;;;;;N;;;;;
+10714;LINEAR A SIGN A619;Lo;0;L;;;;;N;;;;;
+10715;LINEAR A SIGN A620;Lo;0;L;;;;;N;;;;;
+10716;LINEAR A SIGN A621;Lo;0;L;;;;;N;;;;;
+10717;LINEAR A SIGN A622;Lo;0;L;;;;;N;;;;;
+10718;LINEAR A SIGN A623;Lo;0;L;;;;;N;;;;;
+10719;LINEAR A SIGN A624;Lo;0;L;;;;;N;;;;;
+1071A;LINEAR A SIGN A626;Lo;0;L;;;;;N;;;;;
+1071B;LINEAR A SIGN A627;Lo;0;L;;;;;N;;;;;
+1071C;LINEAR A SIGN A628;Lo;0;L;;;;;N;;;;;
+1071D;LINEAR A SIGN A629;Lo;0;L;;;;;N;;;;;
+1071E;LINEAR A SIGN A634;Lo;0;L;;;;;N;;;;;
+1071F;LINEAR A SIGN A637;Lo;0;L;;;;;N;;;;;
+10720;LINEAR A SIGN A638;Lo;0;L;;;;;N;;;;;
+10721;LINEAR A SIGN A640;Lo;0;L;;;;;N;;;;;
+10722;LINEAR A SIGN A642;Lo;0;L;;;;;N;;;;;
+10723;LINEAR A SIGN A643;Lo;0;L;;;;;N;;;;;
+10724;LINEAR A SIGN A644;Lo;0;L;;;;;N;;;;;
+10725;LINEAR A SIGN A645;Lo;0;L;;;;;N;;;;;
+10726;LINEAR A SIGN A646;Lo;0;L;;;;;N;;;;;
+10727;LINEAR A SIGN A648;Lo;0;L;;;;;N;;;;;
+10728;LINEAR A SIGN A649;Lo;0;L;;;;;N;;;;;
+10729;LINEAR A SIGN A651;Lo;0;L;;;;;N;;;;;
+1072A;LINEAR A SIGN A652;Lo;0;L;;;;;N;;;;;
+1072B;LINEAR A SIGN A653;Lo;0;L;;;;;N;;;;;
+1072C;LINEAR A SIGN A654;Lo;0;L;;;;;N;;;;;
+1072D;LINEAR A SIGN A655;Lo;0;L;;;;;N;;;;;
+1072E;LINEAR A SIGN A656;Lo;0;L;;;;;N;;;;;
+1072F;LINEAR A SIGN A657;Lo;0;L;;;;;N;;;;;
+10730;LINEAR A SIGN A658;Lo;0;L;;;;;N;;;;;
+10731;LINEAR A SIGN A659;Lo;0;L;;;;;N;;;;;
+10732;LINEAR A SIGN A660;Lo;0;L;;;;;N;;;;;
+10733;LINEAR A SIGN A661;Lo;0;L;;;;;N;;;;;
+10734;LINEAR A SIGN A662;Lo;0;L;;;;;N;;;;;
+10735;LINEAR A SIGN A663;Lo;0;L;;;;;N;;;;;
+10736;LINEAR A SIGN A664;Lo;0;L;;;;;N;;;;;
+10740;LINEAR A SIGN A701 A;Lo;0;L;;;;;N;;;;;
+10741;LINEAR A SIGN A702 B;Lo;0;L;;;;;N;;;;;
+10742;LINEAR A SIGN A703 D;Lo;0;L;;;;;N;;;;;
+10743;LINEAR A SIGN A704 E;Lo;0;L;;;;;N;;;;;
+10744;LINEAR A SIGN A705 F;Lo;0;L;;;;;N;;;;;
+10745;LINEAR A SIGN A706 H;Lo;0;L;;;;;N;;;;;
+10746;LINEAR A SIGN A707 J;Lo;0;L;;;;;N;;;;;
+10747;LINEAR A SIGN A708 K;Lo;0;L;;;;;N;;;;;
+10748;LINEAR A SIGN A709 L;Lo;0;L;;;;;N;;;;;
+10749;LINEAR A SIGN A709-2 L2;Lo;0;L;;;;;N;;;;;
+1074A;LINEAR A SIGN A709-3 L3;Lo;0;L;;;;;N;;;;;
+1074B;LINEAR A SIGN A709-4 L4;Lo;0;L;;;;;N;;;;;
+1074C;LINEAR A SIGN A709-6 L6;Lo;0;L;;;;;N;;;;;
+1074D;LINEAR A SIGN A710 W;Lo;0;L;;;;;N;;;;;
+1074E;LINEAR A SIGN A711 X;Lo;0;L;;;;;N;;;;;
+1074F;LINEAR A SIGN A712 Y;Lo;0;L;;;;;N;;;;;
+10750;LINEAR A SIGN A713 OMEGA;Lo;0;L;;;;;N;;;;;
+10751;LINEAR A SIGN A714 ABB;Lo;0;L;;;;;N;;;;;
+10752;LINEAR A SIGN A715 BB;Lo;0;L;;;;;N;;;;;
+10753;LINEAR A SIGN A717 DD;Lo;0;L;;;;;N;;;;;
+10754;LINEAR A SIGN A726 EYYY;Lo;0;L;;;;;N;;;;;
+10755;LINEAR A SIGN A732 JE;Lo;0;L;;;;;N;;;;;
+10760;LINEAR A SIGN A800;Lo;0;L;;;;;N;;;;;
+10761;LINEAR A SIGN A801;Lo;0;L;;;;;N;;;;;
+10762;LINEAR A SIGN A802;Lo;0;L;;;;;N;;;;;
+10763;LINEAR A SIGN A803;Lo;0;L;;;;;N;;;;;
+10764;LINEAR A SIGN A804;Lo;0;L;;;;;N;;;;;
+10765;LINEAR A SIGN A805;Lo;0;L;;;;;N;;;;;
+10766;LINEAR A SIGN A806;Lo;0;L;;;;;N;;;;;
+10767;LINEAR A SIGN A807;Lo;0;L;;;;;N;;;;;
+10800;CYPRIOT SYLLABLE A;Lo;0;R;;;;;N;;;;;
+10801;CYPRIOT SYLLABLE E;Lo;0;R;;;;;N;;;;;
+10802;CYPRIOT SYLLABLE I;Lo;0;R;;;;;N;;;;;
+10803;CYPRIOT SYLLABLE O;Lo;0;R;;;;;N;;;;;
+10804;CYPRIOT SYLLABLE U;Lo;0;R;;;;;N;;;;;
+10805;CYPRIOT SYLLABLE JA;Lo;0;R;;;;;N;;;;;
+10808;CYPRIOT SYLLABLE JO;Lo;0;R;;;;;N;;;;;
+1080A;CYPRIOT SYLLABLE KA;Lo;0;R;;;;;N;;;;;
+1080B;CYPRIOT SYLLABLE KE;Lo;0;R;;;;;N;;;;;
+1080C;CYPRIOT SYLLABLE KI;Lo;0;R;;;;;N;;;;;
+1080D;CYPRIOT SYLLABLE KO;Lo;0;R;;;;;N;;;;;
+1080E;CYPRIOT SYLLABLE KU;Lo;0;R;;;;;N;;;;;
+1080F;CYPRIOT SYLLABLE LA;Lo;0;R;;;;;N;;;;;
+10810;CYPRIOT SYLLABLE LE;Lo;0;R;;;;;N;;;;;
+10811;CYPRIOT SYLLABLE LI;Lo;0;R;;;;;N;;;;;
+10812;CYPRIOT SYLLABLE LO;Lo;0;R;;;;;N;;;;;
+10813;CYPRIOT SYLLABLE LU;Lo;0;R;;;;;N;;;;;
+10814;CYPRIOT SYLLABLE MA;Lo;0;R;;;;;N;;;;;
+10815;CYPRIOT SYLLABLE ME;Lo;0;R;;;;;N;;;;;
+10816;CYPRIOT SYLLABLE MI;Lo;0;R;;;;;N;;;;;
+10817;CYPRIOT SYLLABLE MO;Lo;0;R;;;;;N;;;;;
+10818;CYPRIOT SYLLABLE MU;Lo;0;R;;;;;N;;;;;
+10819;CYPRIOT SYLLABLE NA;Lo;0;R;;;;;N;;;;;
+1081A;CYPRIOT SYLLABLE NE;Lo;0;R;;;;;N;;;;;
+1081B;CYPRIOT SYLLABLE NI;Lo;0;R;;;;;N;;;;;
+1081C;CYPRIOT SYLLABLE NO;Lo;0;R;;;;;N;;;;;
+1081D;CYPRIOT SYLLABLE NU;Lo;0;R;;;;;N;;;;;
+1081E;CYPRIOT SYLLABLE PA;Lo;0;R;;;;;N;;;;;
+1081F;CYPRIOT SYLLABLE PE;Lo;0;R;;;;;N;;;;;
+10820;CYPRIOT SYLLABLE PI;Lo;0;R;;;;;N;;;;;
+10821;CYPRIOT SYLLABLE PO;Lo;0;R;;;;;N;;;;;
+10822;CYPRIOT SYLLABLE PU;Lo;0;R;;;;;N;;;;;
+10823;CYPRIOT SYLLABLE RA;Lo;0;R;;;;;N;;;;;
+10824;CYPRIOT SYLLABLE RE;Lo;0;R;;;;;N;;;;;
+10825;CYPRIOT SYLLABLE RI;Lo;0;R;;;;;N;;;;;
+10826;CYPRIOT SYLLABLE RO;Lo;0;R;;;;;N;;;;;
+10827;CYPRIOT SYLLABLE RU;Lo;0;R;;;;;N;;;;;
+10828;CYPRIOT SYLLABLE SA;Lo;0;R;;;;;N;;;;;
+10829;CYPRIOT SYLLABLE SE;Lo;0;R;;;;;N;;;;;
+1082A;CYPRIOT SYLLABLE SI;Lo;0;R;;;;;N;;;;;
+1082B;CYPRIOT SYLLABLE SO;Lo;0;R;;;;;N;;;;;
+1082C;CYPRIOT SYLLABLE SU;Lo;0;R;;;;;N;;;;;
+1082D;CYPRIOT SYLLABLE TA;Lo;0;R;;;;;N;;;;;
+1082E;CYPRIOT SYLLABLE TE;Lo;0;R;;;;;N;;;;;
+1082F;CYPRIOT SYLLABLE TI;Lo;0;R;;;;;N;;;;;
+10830;CYPRIOT SYLLABLE TO;Lo;0;R;;;;;N;;;;;
+10831;CYPRIOT SYLLABLE TU;Lo;0;R;;;;;N;;;;;
+10832;CYPRIOT SYLLABLE WA;Lo;0;R;;;;;N;;;;;
+10833;CYPRIOT SYLLABLE WE;Lo;0;R;;;;;N;;;;;
+10834;CYPRIOT SYLLABLE WI;Lo;0;R;;;;;N;;;;;
+10835;CYPRIOT SYLLABLE WO;Lo;0;R;;;;;N;;;;;
+10837;CYPRIOT SYLLABLE XA;Lo;0;R;;;;;N;;;;;
+10838;CYPRIOT SYLLABLE XE;Lo;0;R;;;;;N;;;;;
+1083C;CYPRIOT SYLLABLE ZA;Lo;0;R;;;;;N;;;;;
+1083F;CYPRIOT SYLLABLE ZO;Lo;0;R;;;;;N;;;;;
+10840;IMPERIAL ARAMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10841;IMPERIAL ARAMAIC LETTER BETH;Lo;0;R;;;;;N;;;;;
+10842;IMPERIAL ARAMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10843;IMPERIAL ARAMAIC LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10844;IMPERIAL ARAMAIC LETTER HE;Lo;0;R;;;;;N;;;;;
+10845;IMPERIAL ARAMAIC LETTER WAW;Lo;0;R;;;;;N;;;;;
+10846;IMPERIAL ARAMAIC LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10847;IMPERIAL ARAMAIC LETTER HETH;Lo;0;R;;;;;N;;;;;
+10848;IMPERIAL ARAMAIC LETTER TETH;Lo;0;R;;;;;N;;;;;
+10849;IMPERIAL ARAMAIC LETTER YODH;Lo;0;R;;;;;N;;;;;
+1084A;IMPERIAL ARAMAIC LETTER KAPH;Lo;0;R;;;;;N;;;;;
+1084B;IMPERIAL ARAMAIC LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+1084C;IMPERIAL ARAMAIC LETTER MEM;Lo;0;R;;;;;N;;;;;
+1084D;IMPERIAL ARAMAIC LETTER NUN;Lo;0;R;;;;;N;;;;;
+1084E;IMPERIAL ARAMAIC LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+1084F;IMPERIAL ARAMAIC LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10850;IMPERIAL ARAMAIC LETTER PE;Lo;0;R;;;;;N;;;;;
+10851;IMPERIAL ARAMAIC LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10852;IMPERIAL ARAMAIC LETTER QOPH;Lo;0;R;;;;;N;;;;;
+10853;IMPERIAL ARAMAIC LETTER RESH;Lo;0;R;;;;;N;;;;;
+10854;IMPERIAL ARAMAIC LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10855;IMPERIAL ARAMAIC LETTER TAW;Lo;0;R;;;;;N;;;;;
+10857;IMPERIAL ARAMAIC SECTION SIGN;Po;0;R;;;;;N;;;;;
+10858;IMPERIAL ARAMAIC NUMBER ONE;No;0;R;;;;1;N;;;;;
+10859;IMPERIAL ARAMAIC NUMBER TWO;No;0;R;;;;2;N;;;;;
+1085A;IMPERIAL ARAMAIC NUMBER THREE;No;0;R;;;;3;N;;;;;
+1085B;IMPERIAL ARAMAIC NUMBER TEN;No;0;R;;;;10;N;;;;;
+1085C;IMPERIAL ARAMAIC NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+1085D;IMPERIAL ARAMAIC NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+1085E;IMPERIAL ARAMAIC NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+1085F;IMPERIAL ARAMAIC NUMBER TEN THOUSAND;No;0;R;;;;10000;N;;;;;
+10860;PALMYRENE LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10861;PALMYRENE LETTER BETH;Lo;0;R;;;;;N;;;;;
+10862;PALMYRENE LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10863;PALMYRENE LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10864;PALMYRENE LETTER HE;Lo;0;R;;;;;N;;;;;
+10865;PALMYRENE LETTER WAW;Lo;0;R;;;;;N;;;;;
+10866;PALMYRENE LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10867;PALMYRENE LETTER HETH;Lo;0;R;;;;;N;;;;;
+10868;PALMYRENE LETTER TETH;Lo;0;R;;;;;N;;;;;
+10869;PALMYRENE LETTER YODH;Lo;0;R;;;;;N;;;;;
+1086A;PALMYRENE LETTER KAPH;Lo;0;R;;;;;N;;;;;
+1086B;PALMYRENE LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+1086C;PALMYRENE LETTER MEM;Lo;0;R;;;;;N;;;;;
+1086D;PALMYRENE LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;
+1086E;PALMYRENE LETTER NUN;Lo;0;R;;;;;N;;;;;
+1086F;PALMYRENE LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10870;PALMYRENE LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10871;PALMYRENE LETTER PE;Lo;0;R;;;;;N;;;;;
+10872;PALMYRENE LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10873;PALMYRENE LETTER QOPH;Lo;0;R;;;;;N;;;;;
+10874;PALMYRENE LETTER RESH;Lo;0;R;;;;;N;;;;;
+10875;PALMYRENE LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10876;PALMYRENE LETTER TAW;Lo;0;R;;;;;N;;;;;
+10877;PALMYRENE LEFT-POINTING FLEURON;So;0;R;;;;;N;;;;;
+10878;PALMYRENE RIGHT-POINTING FLEURON;So;0;R;;;;;N;;;;;
+10879;PALMYRENE NUMBER ONE;No;0;R;;;;1;N;;;;;
+1087A;PALMYRENE NUMBER TWO;No;0;R;;;;2;N;;;;;
+1087B;PALMYRENE NUMBER THREE;No;0;R;;;;3;N;;;;;
+1087C;PALMYRENE NUMBER FOUR;No;0;R;;;;4;N;;;;;
+1087D;PALMYRENE NUMBER FIVE;No;0;R;;;;5;N;;;;;
+1087E;PALMYRENE NUMBER TEN;No;0;R;;;;10;N;;;;;
+1087F;PALMYRENE NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10880;NABATAEAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;;
+10881;NABATAEAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10882;NABATAEAN LETTER FINAL BETH;Lo;0;R;;;;;N;;;;;
+10883;NABATAEAN LETTER BETH;Lo;0;R;;;;;N;;;;;
+10884;NABATAEAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10885;NABATAEAN LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10886;NABATAEAN LETTER FINAL HE;Lo;0;R;;;;;N;;;;;
+10887;NABATAEAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10888;NABATAEAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+10889;NABATAEAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+1088A;NABATAEAN LETTER HETH;Lo;0;R;;;;;N;;;;;
+1088B;NABATAEAN LETTER TETH;Lo;0;R;;;;;N;;;;;
+1088C;NABATAEAN LETTER FINAL YODH;Lo;0;R;;;;;N;;;;;
+1088D;NABATAEAN LETTER YODH;Lo;0;R;;;;;N;;;;;
+1088E;NABATAEAN LETTER FINAL KAPH;Lo;0;R;;;;;N;;;;;
+1088F;NABATAEAN LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10890;NABATAEAN LETTER FINAL LAMEDH;Lo;0;R;;;;;N;;;;;
+10891;NABATAEAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10892;NABATAEAN LETTER FINAL MEM;Lo;0;R;;;;;N;;;;;
+10893;NABATAEAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+10894;NABATAEAN LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;
+10895;NABATAEAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+10896;NABATAEAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10897;NABATAEAN LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10898;NABATAEAN LETTER PE;Lo;0;R;;;;;N;;;;;
+10899;NABATAEAN LETTER SADHE;Lo;0;R;;;;;N;;;;;
+1089A;NABATAEAN LETTER QOPH;Lo;0;R;;;;;N;;;;;
+1089B;NABATAEAN LETTER RESH;Lo;0;R;;;;;N;;;;;
+1089C;NABATAEAN LETTER FINAL SHIN;Lo;0;R;;;;;N;;;;;
+1089D;NABATAEAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+1089E;NABATAEAN LETTER TAW;Lo;0;R;;;;;N;;;;;
+108A7;NABATAEAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+108A8;NABATAEAN NUMBER TWO;No;0;R;;;;2;N;;;;;
+108A9;NABATAEAN NUMBER THREE;No;0;R;;;;3;N;;;;;
+108AA;NABATAEAN NUMBER FOUR;No;0;R;;;;4;N;;;;;
+108AB;NABATAEAN CRUCIFORM NUMBER FOUR;No;0;R;;;;4;N;;;;;
+108AC;NABATAEAN NUMBER FIVE;No;0;R;;;;5;N;;;;;
+108AD;NABATAEAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+108AE;NABATAEAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+108AF;NABATAEAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+108E0;HATRAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+108E1;HATRAN LETTER BETH;Lo;0;R;;;;;N;;;;;
+108E2;HATRAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+108E3;HATRAN LETTER DALETH-RESH;Lo;0;R;;;;;N;;;;;
+108E4;HATRAN LETTER HE;Lo;0;R;;;;;N;;;;;
+108E5;HATRAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+108E6;HATRAN LETTER ZAYN;Lo;0;R;;;;;N;;;;;
+108E7;HATRAN LETTER HETH;Lo;0;R;;;;;N;;;;;
+108E8;HATRAN LETTER TETH;Lo;0;R;;;;;N;;;;;
+108E9;HATRAN LETTER YODH;Lo;0;R;;;;;N;;;;;
+108EA;HATRAN LETTER KAPH;Lo;0;R;;;;;N;;;;;
+108EB;HATRAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+108EC;HATRAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+108ED;HATRAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+108EE;HATRAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+108EF;HATRAN LETTER AYN;Lo;0;R;;;;;N;;;;;
+108F0;HATRAN LETTER PE;Lo;0;R;;;;;N;;;;;
+108F1;HATRAN LETTER SADHE;Lo;0;R;;;;;N;;;;;
+108F2;HATRAN LETTER QOPH;Lo;0;R;;;;;N;;;;;
+108F4;HATRAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+108F5;HATRAN LETTER TAW;Lo;0;R;;;;;N;;;;;
+108FB;HATRAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+108FC;HATRAN NUMBER FIVE;No;0;R;;;;5;N;;;;;
+108FD;HATRAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+108FE;HATRAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+108FF;HATRAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10900;PHOENICIAN LETTER ALF;Lo;0;R;;;;;N;;;;;
+10901;PHOENICIAN LETTER BET;Lo;0;R;;;;;N;;;;;
+10902;PHOENICIAN LETTER GAML;Lo;0;R;;;;;N;;;;;
+10903;PHOENICIAN LETTER DELT;Lo;0;R;;;;;N;;;;;
+10904;PHOENICIAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10905;PHOENICIAN LETTER WAU;Lo;0;R;;;;;N;;;;;
+10906;PHOENICIAN LETTER ZAI;Lo;0;R;;;;;N;;;;;
+10907;PHOENICIAN LETTER HET;Lo;0;R;;;;;N;;;;;
+10908;PHOENICIAN LETTER TET;Lo;0;R;;;;;N;;;;;
+10909;PHOENICIAN LETTER YOD;Lo;0;R;;;;;N;;;;;
+1090A;PHOENICIAN LETTER KAF;Lo;0;R;;;;;N;;;;;
+1090B;PHOENICIAN LETTER LAMD;Lo;0;R;;;;;N;;;;;
+1090C;PHOENICIAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+1090D;PHOENICIAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+1090E;PHOENICIAN LETTER SEMK;Lo;0;R;;;;;N;;;;;
+1090F;PHOENICIAN LETTER AIN;Lo;0;R;;;;;N;;;;;
+10910;PHOENICIAN LETTER PE;Lo;0;R;;;;;N;;;;;
+10911;PHOENICIAN LETTER SADE;Lo;0;R;;;;;N;;;;;
+10912;PHOENICIAN LETTER QOF;Lo;0;R;;;;;N;;;;;
+10913;PHOENICIAN LETTER ROSH;Lo;0;R;;;;;N;;;;;
+10914;PHOENICIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10915;PHOENICIAN LETTER TAU;Lo;0;R;;;;;N;;;;;
+10916;PHOENICIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10917;PHOENICIAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+10918;PHOENICIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10919;PHOENICIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+1091A;PHOENICIAN NUMBER TWO;No;0;R;;;;2;N;;;;;
+1091B;PHOENICIAN NUMBER THREE;No;0;R;;;;3;N;;;;;
+1091F;PHOENICIAN WORD SEPARATOR;Po;0;ON;;;;;N;;;;;
+10920;LYDIAN LETTER A;Lo;0;R;;;;;N;;;;;
+10921;LYDIAN LETTER B;Lo;0;R;;;;;N;;;;;
+10922;LYDIAN LETTER G;Lo;0;R;;;;;N;;;;;
+10923;LYDIAN LETTER D;Lo;0;R;;;;;N;;;;;
+10924;LYDIAN LETTER E;Lo;0;R;;;;;N;;;;;
+10925;LYDIAN LETTER V;Lo;0;R;;;;;N;;;;;
+10926;LYDIAN LETTER I;Lo;0;R;;;;;N;;;;;
+10927;LYDIAN LETTER Y;Lo;0;R;;;;;N;;;;;
+10928;LYDIAN LETTER K;Lo;0;R;;;;;N;;;;;
+10929;LYDIAN LETTER L;Lo;0;R;;;;;N;;;;;
+1092A;LYDIAN LETTER M;Lo;0;R;;;;;N;;;;;
+1092B;LYDIAN LETTER N;Lo;0;R;;;;;N;;;;;
+1092C;LYDIAN LETTER O;Lo;0;R;;;;;N;;;;;
+1092D;LYDIAN LETTER R;Lo;0;R;;;;;N;;;;;
+1092E;LYDIAN LETTER SS;Lo;0;R;;;;;N;;;;;
+1092F;LYDIAN LETTER T;Lo;0;R;;;;;N;;;;;
+10930;LYDIAN LETTER U;Lo;0;R;;;;;N;;;;;
+10931;LYDIAN LETTER F;Lo;0;R;;;;;N;;;;;
+10932;LYDIAN LETTER Q;Lo;0;R;;;;;N;;;;;
+10933;LYDIAN LETTER S;Lo;0;R;;;;;N;;;;;
+10934;LYDIAN LETTER TT;Lo;0;R;;;;;N;;;;;
+10935;LYDIAN LETTER AN;Lo;0;R;;;;;N;;;;;
+10936;LYDIAN LETTER EN;Lo;0;R;;;;;N;;;;;
+10937;LYDIAN LETTER LY;Lo;0;R;;;;;N;;;;;
+10938;LYDIAN LETTER NN;Lo;0;R;;;;;N;;;;;
+10939;LYDIAN LETTER C;Lo;0;R;;;;;N;;;;;
+1093F;LYDIAN TRIANGULAR MARK;Po;0;R;;;;;N;;;;;
+10980;MEROITIC HIEROGLYPHIC LETTER A;Lo;0;R;;;;;N;;;;;
+10981;MEROITIC HIEROGLYPHIC LETTER E;Lo;0;R;;;;;N;;;;;
+10982;MEROITIC HIEROGLYPHIC LETTER I;Lo;0;R;;;;;N;;;;;
+10983;MEROITIC HIEROGLYPHIC LETTER O;Lo;0;R;;;;;N;;;;;
+10984;MEROITIC HIEROGLYPHIC LETTER YA;Lo;0;R;;;;;N;;;;;
+10985;MEROITIC HIEROGLYPHIC LETTER WA;Lo;0;R;;;;;N;;;;;
+10986;MEROITIC HIEROGLYPHIC LETTER BA;Lo;0;R;;;;;N;;;;;
+10987;MEROITIC HIEROGLYPHIC LETTER BA-2;Lo;0;R;;;;;N;;;;;
+10988;MEROITIC HIEROGLYPHIC LETTER PA;Lo;0;R;;;;;N;;;;;
+10989;MEROITIC HIEROGLYPHIC LETTER MA;Lo;0;R;;;;;N;;;;;
+1098A;MEROITIC HIEROGLYPHIC LETTER NA;Lo;0;R;;;;;N;;;;;
+1098B;MEROITIC HIEROGLYPHIC LETTER NA-2;Lo;0;R;;;;;N;;;;;
+1098C;MEROITIC HIEROGLYPHIC LETTER NE;Lo;0;R;;;;;N;;;;;
+1098D;MEROITIC HIEROGLYPHIC LETTER NE-2;Lo;0;R;;;;;N;;;;;
+1098E;MEROITIC HIEROGLYPHIC LETTER RA;Lo;0;R;;;;;N;;;;;
+1098F;MEROITIC HIEROGLYPHIC LETTER RA-2;Lo;0;R;;;;;N;;;;;
+10990;MEROITIC HIEROGLYPHIC LETTER LA;Lo;0;R;;;;;N;;;;;
+10991;MEROITIC HIEROGLYPHIC LETTER KHA;Lo;0;R;;;;;N;;;;;
+10992;MEROITIC HIEROGLYPHIC LETTER HHA;Lo;0;R;;;;;N;;;;;
+10993;MEROITIC HIEROGLYPHIC LETTER SA;Lo;0;R;;;;;N;;;;;
+10994;MEROITIC HIEROGLYPHIC LETTER SA-2;Lo;0;R;;;;;N;;;;;
+10995;MEROITIC HIEROGLYPHIC LETTER SE;Lo;0;R;;;;;N;;;;;
+10996;MEROITIC HIEROGLYPHIC LETTER KA;Lo;0;R;;;;;N;;;;;
+10997;MEROITIC HIEROGLYPHIC LETTER QA;Lo;0;R;;;;;N;;;;;
+10998;MEROITIC HIEROGLYPHIC LETTER TA;Lo;0;R;;;;;N;;;;;
+10999;MEROITIC HIEROGLYPHIC LETTER TA-2;Lo;0;R;;;;;N;;;;;
+1099A;MEROITIC HIEROGLYPHIC LETTER TE;Lo;0;R;;;;;N;;;;;
+1099B;MEROITIC HIEROGLYPHIC LETTER TE-2;Lo;0;R;;;;;N;;;;;
+1099C;MEROITIC HIEROGLYPHIC LETTER TO;Lo;0;R;;;;;N;;;;;
+1099D;MEROITIC HIEROGLYPHIC LETTER DA;Lo;0;R;;;;;N;;;;;
+1099E;MEROITIC HIEROGLYPHIC SYMBOL VIDJ;Lo;0;R;;;;;N;;;;;
+1099F;MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2;Lo;0;R;;;;;N;;;;;
+109A0;MEROITIC CURSIVE LETTER A;Lo;0;R;;;;;N;;;;;
+109A1;MEROITIC CURSIVE LETTER E;Lo;0;R;;;;;N;;;;;
+109A2;MEROITIC CURSIVE LETTER I;Lo;0;R;;;;;N;;;;;
+109A3;MEROITIC CURSIVE LETTER O;Lo;0;R;;;;;N;;;;;
+109A4;MEROITIC CURSIVE LETTER YA;Lo;0;R;;;;;N;;;;;
+109A5;MEROITIC CURSIVE LETTER WA;Lo;0;R;;;;;N;;;;;
+109A6;MEROITIC CURSIVE LETTER BA;Lo;0;R;;;;;N;;;;;
+109A7;MEROITIC CURSIVE LETTER PA;Lo;0;R;;;;;N;;;;;
+109A8;MEROITIC CURSIVE LETTER MA;Lo;0;R;;;;;N;;;;;
+109A9;MEROITIC CURSIVE LETTER NA;Lo;0;R;;;;;N;;;;;
+109AA;MEROITIC CURSIVE LETTER NE;Lo;0;R;;;;;N;;;;;
+109AB;MEROITIC CURSIVE LETTER RA;Lo;0;R;;;;;N;;;;;
+109AC;MEROITIC CURSIVE LETTER LA;Lo;0;R;;;;;N;;;;;
+109AD;MEROITIC CURSIVE LETTER KHA;Lo;0;R;;;;;N;;;;;
+109AE;MEROITIC CURSIVE LETTER HHA;Lo;0;R;;;;;N;;;;;
+109AF;MEROITIC CURSIVE LETTER SA;Lo;0;R;;;;;N;;;;;
+109B0;MEROITIC CURSIVE LETTER ARCHAIC SA;Lo;0;R;;;;;N;;;;;
+109B1;MEROITIC CURSIVE LETTER SE;Lo;0;R;;;;;N;;;;;
+109B2;MEROITIC CURSIVE LETTER KA;Lo;0;R;;;;;N;;;;;
+109B3;MEROITIC CURSIVE LETTER QA;Lo;0;R;;;;;N;;;;;
+109B4;MEROITIC CURSIVE LETTER TA;Lo;0;R;;;;;N;;;;;
+109B5;MEROITIC CURSIVE LETTER TE;Lo;0;R;;;;;N;;;;;
+109B6;MEROITIC CURSIVE LETTER TO;Lo;0;R;;;;;N;;;;;
+109B7;MEROITIC CURSIVE LETTER DA;Lo;0;R;;;;;N;;;;;
+109BC;MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS;No;0;R;;;;11/12;N;;;;;
+109BD;MEROITIC CURSIVE FRACTION ONE HALF;No;0;R;;;;1/2;N;;;;;
+109BE;MEROITIC CURSIVE LOGOGRAM RMT;Lo;0;R;;;;;N;;;;;
+109BF;MEROITIC CURSIVE LOGOGRAM IMN;Lo;0;R;;;;;N;;;;;
+109C0;MEROITIC CURSIVE NUMBER ONE;No;0;R;;;;1;N;;;;;
+109C1;MEROITIC CURSIVE NUMBER TWO;No;0;R;;;;2;N;;;;;
+109C2;MEROITIC CURSIVE NUMBER THREE;No;0;R;;;;3;N;;;;;
+109C3;MEROITIC CURSIVE NUMBER FOUR;No;0;R;;;;4;N;;;;;
+109C4;MEROITIC CURSIVE NUMBER FIVE;No;0;R;;;;5;N;;;;;
+109C5;MEROITIC CURSIVE NUMBER SIX;No;0;R;;;;6;N;;;;;
+109C6;MEROITIC CURSIVE NUMBER SEVEN;No;0;R;;;;7;N;;;;;
+109C7;MEROITIC CURSIVE NUMBER EIGHT;No;0;R;;;;8;N;;;;;
+109C8;MEROITIC CURSIVE NUMBER NINE;No;0;R;;;;9;N;;;;;
+109C9;MEROITIC CURSIVE NUMBER TEN;No;0;R;;;;10;N;;;;;
+109CA;MEROITIC CURSIVE NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+109CB;MEROITIC CURSIVE NUMBER THIRTY;No;0;R;;;;30;N;;;;;
+109CC;MEROITIC CURSIVE NUMBER FORTY;No;0;R;;;;40;N;;;;;
+109CD;MEROITIC CURSIVE NUMBER FIFTY;No;0;R;;;;50;N;;;;;
+109CE;MEROITIC CURSIVE NUMBER SIXTY;No;0;R;;;;60;N;;;;;
+109CF;MEROITIC CURSIVE NUMBER SEVENTY;No;0;R;;;;70;N;;;;;
+109D2;MEROITIC CURSIVE NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+109D3;MEROITIC CURSIVE NUMBER TWO HUNDRED;No;0;R;;;;200;N;;;;;
+109D4;MEROITIC CURSIVE NUMBER THREE HUNDRED;No;0;R;;;;300;N;;;;;
+109D5;MEROITIC CURSIVE NUMBER FOUR HUNDRED;No;0;R;;;;400;N;;;;;
+109D6;MEROITIC CURSIVE NUMBER FIVE HUNDRED;No;0;R;;;;500;N;;;;;
+109D7;MEROITIC CURSIVE NUMBER SIX HUNDRED;No;0;R;;;;600;N;;;;;
+109D8;MEROITIC CURSIVE NUMBER SEVEN HUNDRED;No;0;R;;;;700;N;;;;;
+109D9;MEROITIC CURSIVE NUMBER EIGHT HUNDRED;No;0;R;;;;800;N;;;;;
+109DA;MEROITIC CURSIVE NUMBER NINE HUNDRED;No;0;R;;;;900;N;;;;;
+109DB;MEROITIC CURSIVE NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+109DC;MEROITIC CURSIVE NUMBER TWO THOUSAND;No;0;R;;;;2000;N;;;;;
+109DD;MEROITIC CURSIVE NUMBER THREE THOUSAND;No;0;R;;;;3000;N;;;;;
+109DE;MEROITIC CURSIVE NUMBER FOUR THOUSAND;No;0;R;;;;4000;N;;;;;
+109DF;MEROITIC CURSIVE NUMBER FIVE THOUSAND;No;0;R;;;;5000;N;;;;;
+109E0;MEROITIC CURSIVE NUMBER SIX THOUSAND;No;0;R;;;;6000;N;;;;;
+109E1;MEROITIC CURSIVE NUMBER SEVEN THOUSAND;No;0;R;;;;7000;N;;;;;
+109E2;MEROITIC CURSIVE NUMBER EIGHT THOUSAND;No;0;R;;;;8000;N;;;;;
+109E3;MEROITIC CURSIVE NUMBER NINE THOUSAND;No;0;R;;;;9000;N;;;;;
+109E4;MEROITIC CURSIVE NUMBER TEN THOUSAND;No;0;R;;;;10000;N;;;;;
+109E5;MEROITIC CURSIVE NUMBER TWENTY THOUSAND;No;0;R;;;;20000;N;;;;;
+109E6;MEROITIC CURSIVE NUMBER THIRTY THOUSAND;No;0;R;;;;30000;N;;;;;
+109E7;MEROITIC CURSIVE NUMBER FORTY THOUSAND;No;0;R;;;;40000;N;;;;;
+109E8;MEROITIC CURSIVE NUMBER FIFTY THOUSAND;No;0;R;;;;50000;N;;;;;
+109E9;MEROITIC CURSIVE NUMBER SIXTY THOUSAND;No;0;R;;;;60000;N;;;;;
+109EA;MEROITIC CURSIVE NUMBER SEVENTY THOUSAND;No;0;R;;;;70000;N;;;;;
+109EB;MEROITIC CURSIVE NUMBER EIGHTY THOUSAND;No;0;R;;;;80000;N;;;;;
+109EC;MEROITIC CURSIVE NUMBER NINETY THOUSAND;No;0;R;;;;90000;N;;;;;
+109ED;MEROITIC CURSIVE NUMBER ONE HUNDRED THOUSAND;No;0;R;;;;100000;N;;;;;
+109EE;MEROITIC CURSIVE NUMBER TWO HUNDRED THOUSAND;No;0;R;;;;200000;N;;;;;
+109EF;MEROITIC CURSIVE NUMBER THREE HUNDRED THOUSAND;No;0;R;;;;300000;N;;;;;
+109F0;MEROITIC CURSIVE NUMBER FOUR HUNDRED THOUSAND;No;0;R;;;;400000;N;;;;;
+109F1;MEROITIC CURSIVE NUMBER FIVE HUNDRED THOUSAND;No;0;R;;;;500000;N;;;;;
+109F2;MEROITIC CURSIVE NUMBER SIX HUNDRED THOUSAND;No;0;R;;;;600000;N;;;;;
+109F3;MEROITIC CURSIVE NUMBER SEVEN HUNDRED THOUSAND;No;0;R;;;;700000;N;;;;;
+109F4;MEROITIC CURSIVE NUMBER EIGHT HUNDRED THOUSAND;No;0;R;;;;800000;N;;;;;
+109F5;MEROITIC CURSIVE NUMBER NINE HUNDRED THOUSAND;No;0;R;;;;900000;N;;;;;
+109F6;MEROITIC CURSIVE FRACTION ONE TWELFTH;No;0;R;;;;1/12;N;;;;;
+109F7;MEROITIC CURSIVE FRACTION TWO TWELFTHS;No;0;R;;;;2/12;N;;;;;
+109F8;MEROITIC CURSIVE FRACTION THREE TWELFTHS;No;0;R;;;;3/12;N;;;;;
+109F9;MEROITIC CURSIVE FRACTION FOUR TWELFTHS;No;0;R;;;;4/12;N;;;;;
+109FA;MEROITIC CURSIVE FRACTION FIVE TWELFTHS;No;0;R;;;;5/12;N;;;;;
+109FB;MEROITIC CURSIVE FRACTION SIX TWELFTHS;No;0;R;;;;6/12;N;;;;;
+109FC;MEROITIC CURSIVE FRACTION SEVEN TWELFTHS;No;0;R;;;;7/12;N;;;;;
+109FD;MEROITIC CURSIVE FRACTION EIGHT TWELFTHS;No;0;R;;;;8/12;N;;;;;
+109FE;MEROITIC CURSIVE FRACTION NINE TWELFTHS;No;0;R;;;;9/12;N;;;;;
+109FF;MEROITIC CURSIVE FRACTION TEN TWELFTHS;No;0;R;;;;10/12;N;;;;;
+10A00;KHAROSHTHI LETTER A;Lo;0;R;;;;;N;;;;;
+10A01;KHAROSHTHI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+10A02;KHAROSHTHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+10A03;KHAROSHTHI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+10A05;KHAROSHTHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+10A06;KHAROSHTHI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+10A0C;KHAROSHTHI VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
+10A0D;KHAROSHTHI SIGN DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;;
+10A0E;KHAROSHTHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+10A0F;KHAROSHTHI SIGN VISARGA;Mn;230;NSM;;;;;N;;;;;
+10A10;KHAROSHTHI LETTER KA;Lo;0;R;;;;;N;;;;;
+10A11;KHAROSHTHI LETTER KHA;Lo;0;R;;;;;N;;;;;
+10A12;KHAROSHTHI LETTER GA;Lo;0;R;;;;;N;;;;;
+10A13;KHAROSHTHI LETTER GHA;Lo;0;R;;;;;N;;;;;
+10A15;KHAROSHTHI LETTER CA;Lo;0;R;;;;;N;;;;;
+10A16;KHAROSHTHI LETTER CHA;Lo;0;R;;;;;N;;;;;
+10A17;KHAROSHTHI LETTER JA;Lo;0;R;;;;;N;;;;;
+10A19;KHAROSHTHI LETTER NYA;Lo;0;R;;;;;N;;;;;
+10A1A;KHAROSHTHI LETTER TTA;Lo;0;R;;;;;N;;;;;
+10A1B;KHAROSHTHI LETTER TTHA;Lo;0;R;;;;;N;;;;;
+10A1C;KHAROSHTHI LETTER DDA;Lo;0;R;;;;;N;;;;;
+10A1D;KHAROSHTHI LETTER DDHA;Lo;0;R;;;;;N;;;;;
+10A1E;KHAROSHTHI LETTER NNA;Lo;0;R;;;;;N;;;;;
+10A1F;KHAROSHTHI LETTER TA;Lo;0;R;;;;;N;;;;;
+10A20;KHAROSHTHI LETTER THA;Lo;0;R;;;;;N;;;;;
+10A21;KHAROSHTHI LETTER DA;Lo;0;R;;;;;N;;;;;
+10A22;KHAROSHTHI LETTER DHA;Lo;0;R;;;;;N;;;;;
+10A23;KHAROSHTHI LETTER NA;Lo;0;R;;;;;N;;;;;
+10A24;KHAROSHTHI LETTER PA;Lo;0;R;;;;;N;;;;;
+10A25;KHAROSHTHI LETTER PHA;Lo;0;R;;;;;N;;;;;
+10A26;KHAROSHTHI LETTER BA;Lo;0;R;;;;;N;;;;;
+10A27;KHAROSHTHI LETTER BHA;Lo;0;R;;;;;N;;;;;
+10A28;KHAROSHTHI LETTER MA;Lo;0;R;;;;;N;;;;;
+10A29;KHAROSHTHI LETTER YA;Lo;0;R;;;;;N;;;;;
+10A2A;KHAROSHTHI LETTER RA;Lo;0;R;;;;;N;;;;;
+10A2B;KHAROSHTHI LETTER LA;Lo;0;R;;;;;N;;;;;
+10A2C;KHAROSHTHI LETTER VA;Lo;0;R;;;;;N;;;;;
+10A2D;KHAROSHTHI LETTER SHA;Lo;0;R;;;;;N;;;;;
+10A2E;KHAROSHTHI LETTER SSA;Lo;0;R;;;;;N;;;;;
+10A2F;KHAROSHTHI LETTER SA;Lo;0;R;;;;;N;;;;;
+10A30;KHAROSHTHI LETTER ZA;Lo;0;R;;;;;N;;;;;
+10A31;KHAROSHTHI LETTER HA;Lo;0;R;;;;;N;;;;;
+10A32;KHAROSHTHI LETTER KKA;Lo;0;R;;;;;N;;;;;
+10A33;KHAROSHTHI LETTER TTTHA;Lo;0;R;;;;;N;;;;;
+10A38;KHAROSHTHI SIGN BAR ABOVE;Mn;230;NSM;;;;;N;;;;;
+10A39;KHAROSHTHI SIGN CAUDA;Mn;1;NSM;;;;;N;;;;;
+10A3A;KHAROSHTHI SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;;
+10A3F;KHAROSHTHI VIRAMA;Mn;9;NSM;;;;;N;;;;;
+10A40;KHAROSHTHI DIGIT ONE;No;0;R;;;1;1;N;;;;;
+10A41;KHAROSHTHI DIGIT TWO;No;0;R;;;2;2;N;;;;;
+10A42;KHAROSHTHI DIGIT THREE;No;0;R;;;3;3;N;;;;;
+10A43;KHAROSHTHI DIGIT FOUR;No;0;R;;;4;4;N;;;;;
+10A44;KHAROSHTHI NUMBER TEN;No;0;R;;;;10;N;;;;;
+10A45;KHAROSHTHI NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10A46;KHAROSHTHI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10A47;KHAROSHTHI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+10A50;KHAROSHTHI PUNCTUATION DOT;Po;0;R;;;;;N;;;;;
+10A51;KHAROSHTHI PUNCTUATION SMALL CIRCLE;Po;0;R;;;;;N;;;;;
+10A52;KHAROSHTHI PUNCTUATION CIRCLE;Po;0;R;;;;;N;;;;;
+10A53;KHAROSHTHI PUNCTUATION CRESCENT BAR;Po;0;R;;;;;N;;;;;
+10A54;KHAROSHTHI PUNCTUATION MANGALAM;Po;0;R;;;;;N;;;;;
+10A55;KHAROSHTHI PUNCTUATION LOTUS;Po;0;R;;;;;N;;;;;
+10A56;KHAROSHTHI PUNCTUATION DANDA;Po;0;R;;;;;N;;;;;
+10A57;KHAROSHTHI PUNCTUATION DOUBLE DANDA;Po;0;R;;;;;N;;;;;
+10A58;KHAROSHTHI PUNCTUATION LINES;Po;0;R;;;;;N;;;;;
+10A60;OLD SOUTH ARABIAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10A61;OLD SOUTH ARABIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10A62;OLD SOUTH ARABIAN LETTER HETH;Lo;0;R;;;;;N;;;;;
+10A63;OLD SOUTH ARABIAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+10A64;OLD SOUTH ARABIAN LETTER QOPH;Lo;0;R;;;;;N;;;;;
+10A65;OLD SOUTH ARABIAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+10A66;OLD SOUTH ARABIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10A67;OLD SOUTH ARABIAN LETTER RESH;Lo;0;R;;;;;N;;;;;
+10A68;OLD SOUTH ARABIAN LETTER BETH;Lo;0;R;;;;;N;;;;;
+10A69;OLD SOUTH ARABIAN LETTER TAW;Lo;0;R;;;;;N;;;;;
+10A6A;OLD SOUTH ARABIAN LETTER SAT;Lo;0;R;;;;;N;;;;;
+10A6B;OLD SOUTH ARABIAN LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10A6C;OLD SOUTH ARABIAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+10A6D;OLD SOUTH ARABIAN LETTER KHETH;Lo;0;R;;;;;N;;;;;
+10A6E;OLD SOUTH ARABIAN LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10A6F;OLD SOUTH ARABIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10A70;OLD SOUTH ARABIAN LETTER FE;Lo;0;R;;;;;N;;;;;
+10A71;OLD SOUTH ARABIAN LETTER ALEF;Lo;0;R;;;;;N;;;;;
+10A72;OLD SOUTH ARABIAN LETTER AYN;Lo;0;R;;;;;N;;;;;
+10A73;OLD SOUTH ARABIAN LETTER DHADHE;Lo;0;R;;;;;N;;;;;
+10A74;OLD SOUTH ARABIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10A75;OLD SOUTH ARABIAN LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10A76;OLD SOUTH ARABIAN LETTER GHAYN;Lo;0;R;;;;;N;;;;;
+10A77;OLD SOUTH ARABIAN LETTER TETH;Lo;0;R;;;;;N;;;;;
+10A78;OLD SOUTH ARABIAN LETTER ZAYN;Lo;0;R;;;;;N;;;;;
+10A79;OLD SOUTH ARABIAN LETTER DHALETH;Lo;0;R;;;;;N;;;;;
+10A7A;OLD SOUTH ARABIAN LETTER YODH;Lo;0;R;;;;;N;;;;;
+10A7B;OLD SOUTH ARABIAN LETTER THAW;Lo;0;R;;;;;N;;;;;
+10A7C;OLD SOUTH ARABIAN LETTER THETH;Lo;0;R;;;;;N;;;;;
+10A7D;OLD SOUTH ARABIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10A7E;OLD SOUTH ARABIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;;
+10A7F;OLD SOUTH ARABIAN NUMERIC INDICATOR;Po;0;R;;;;;N;;;;;
+10A80;OLD NORTH ARABIAN LETTER HEH;Lo;0;R;;;;;N;;;;;
+10A81;OLD NORTH ARABIAN LETTER LAM;Lo;0;R;;;;;N;;;;;
+10A82;OLD NORTH ARABIAN LETTER HAH;Lo;0;R;;;;;N;;;;;
+10A83;OLD NORTH ARABIAN LETTER MEEM;Lo;0;R;;;;;N;;;;;
+10A84;OLD NORTH ARABIAN LETTER QAF;Lo;0;R;;;;;N;;;;;
+10A85;OLD NORTH ARABIAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+10A86;OLD NORTH ARABIAN LETTER ES-2;Lo;0;R;;;;;N;;;;;
+10A87;OLD NORTH ARABIAN LETTER REH;Lo;0;R;;;;;N;;;;;
+10A88;OLD NORTH ARABIAN LETTER BEH;Lo;0;R;;;;;N;;;;;
+10A89;OLD NORTH ARABIAN LETTER TEH;Lo;0;R;;;;;N;;;;;
+10A8A;OLD NORTH ARABIAN LETTER ES-1;Lo;0;R;;;;;N;;;;;
+10A8B;OLD NORTH ARABIAN LETTER KAF;Lo;0;R;;;;;N;;;;;
+10A8C;OLD NORTH ARABIAN LETTER NOON;Lo;0;R;;;;;N;;;;;
+10A8D;OLD NORTH ARABIAN LETTER KHAH;Lo;0;R;;;;;N;;;;;
+10A8E;OLD NORTH ARABIAN LETTER SAD;Lo;0;R;;;;;N;;;;;
+10A8F;OLD NORTH ARABIAN LETTER ES-3;Lo;0;R;;;;;N;;;;;
+10A90;OLD NORTH ARABIAN LETTER FEH;Lo;0;R;;;;;N;;;;;
+10A91;OLD NORTH ARABIAN LETTER ALEF;Lo;0;R;;;;;N;;;;;
+10A92;OLD NORTH ARABIAN LETTER AIN;Lo;0;R;;;;;N;;;;;
+10A93;OLD NORTH ARABIAN LETTER DAD;Lo;0;R;;;;;N;;;;;
+10A94;OLD NORTH ARABIAN LETTER GEEM;Lo;0;R;;;;;N;;;;;
+10A95;OLD NORTH ARABIAN LETTER DAL;Lo;0;R;;;;;N;;;;;
+10A96;OLD NORTH ARABIAN LETTER GHAIN;Lo;0;R;;;;;N;;;;;
+10A97;OLD NORTH ARABIAN LETTER TAH;Lo;0;R;;;;;N;;;;;
+10A98;OLD NORTH ARABIAN LETTER ZAIN;Lo;0;R;;;;;N;;;;;
+10A99;OLD NORTH ARABIAN LETTER THAL;Lo;0;R;;;;;N;;;;;
+10A9A;OLD NORTH ARABIAN LETTER YEH;Lo;0;R;;;;;N;;;;;
+10A9B;OLD NORTH ARABIAN LETTER THEH;Lo;0;R;;;;;N;;;;;
+10A9C;OLD NORTH ARABIAN LETTER ZAH;Lo;0;R;;;;;N;;;;;
+10A9D;OLD NORTH ARABIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10A9E;OLD NORTH ARABIAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+10A9F;OLD NORTH ARABIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10AC0;MANICHAEAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10AC1;MANICHAEAN LETTER BETH;Lo;0;R;;;;;N;;;;;
+10AC2;MANICHAEAN LETTER BHETH;Lo;0;R;;;;;N;;;;;
+10AC3;MANICHAEAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10AC4;MANICHAEAN LETTER GHIMEL;Lo;0;R;;;;;N;;;;;
+10AC5;MANICHAEAN LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10AC6;MANICHAEAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10AC7;MANICHAEAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+10AC8;MANICHAEAN SIGN UD;So;0;R;;;;;N;;;;;
+10AC9;MANICHAEAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10ACA;MANICHAEAN LETTER ZHAYIN;Lo;0;R;;;;;N;;;;;
+10ACB;MANICHAEAN LETTER JAYIN;Lo;0;R;;;;;N;;;;;
+10ACC;MANICHAEAN LETTER JHAYIN;Lo;0;R;;;;;N;;;;;
+10ACD;MANICHAEAN LETTER HETH;Lo;0;R;;;;;N;;;;;
+10ACE;MANICHAEAN LETTER TETH;Lo;0;R;;;;;N;;;;;
+10ACF;MANICHAEAN LETTER YODH;Lo;0;R;;;;;N;;;;;
+10AD0;MANICHAEAN LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10AD1;MANICHAEAN LETTER XAPH;Lo;0;R;;;;;N;;;;;
+10AD2;MANICHAEAN LETTER KHAPH;Lo;0;R;;;;;N;;;;;
+10AD3;MANICHAEAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10AD4;MANICHAEAN LETTER DHAMEDH;Lo;0;R;;;;;N;;;;;
+10AD5;MANICHAEAN LETTER THAMEDH;Lo;0;R;;;;;N;;;;;
+10AD6;MANICHAEAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+10AD7;MANICHAEAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+10AD8;MANICHAEAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10AD9;MANICHAEAN LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10ADA;MANICHAEAN LETTER AAYIN;Lo;0;R;;;;;N;;;;;
+10ADB;MANICHAEAN LETTER PE;Lo;0;R;;;;;N;;;;;
+10ADC;MANICHAEAN LETTER FE;Lo;0;R;;;;;N;;;;;
+10ADD;MANICHAEAN LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10ADE;MANICHAEAN LETTER QOPH;Lo;0;R;;;;;N;;;;;
+10ADF;MANICHAEAN LETTER XOPH;Lo;0;R;;;;;N;;;;;
+10AE0;MANICHAEAN LETTER QHOPH;Lo;0;R;;;;;N;;;;;
+10AE1;MANICHAEAN LETTER RESH;Lo;0;R;;;;;N;;;;;
+10AE2;MANICHAEAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10AE3;MANICHAEAN LETTER SSHIN;Lo;0;R;;;;;N;;;;;
+10AE4;MANICHAEAN LETTER TAW;Lo;0;R;;;;;N;;;;;
+10AE5;MANICHAEAN ABBREVIATION MARK ABOVE;Mn;230;NSM;;;;;N;;;;;
+10AE6;MANICHAEAN ABBREVIATION MARK BELOW;Mn;220;NSM;;;;;N;;;;;
+10AEB;MANICHAEAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10AEC;MANICHAEAN NUMBER FIVE;No;0;R;;;;5;N;;;;;
+10AED;MANICHAEAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+10AEE;MANICHAEAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10AEF;MANICHAEAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10AF0;MANICHAEAN PUNCTUATION STAR;Po;0;R;;;;;N;;;;;
+10AF1;MANICHAEAN PUNCTUATION FLEURON;Po;0;R;;;;;N;;;;;
+10AF2;MANICHAEAN PUNCTUATION DOUBLE DOT WITHIN DOT;Po;0;R;;;;;N;;;;;
+10AF3;MANICHAEAN PUNCTUATION DOT WITHIN DOT;Po;0;R;;;;;N;;;;;
+10AF4;MANICHAEAN PUNCTUATION DOT;Po;0;R;;;;;N;;;;;
+10AF5;MANICHAEAN PUNCTUATION TWO DOTS;Po;0;R;;;;;N;;;;;
+10AF6;MANICHAEAN PUNCTUATION LINE FILLER;Po;0;R;;;;;N;;;;;
+10B00;AVESTAN LETTER A;Lo;0;R;;;;;N;;;;;
+10B01;AVESTAN LETTER AA;Lo;0;R;;;;;N;;;;;
+10B02;AVESTAN LETTER AO;Lo;0;R;;;;;N;;;;;
+10B03;AVESTAN LETTER AAO;Lo;0;R;;;;;N;;;;;
+10B04;AVESTAN LETTER AN;Lo;0;R;;;;;N;;;;;
+10B05;AVESTAN LETTER AAN;Lo;0;R;;;;;N;;;;;
+10B06;AVESTAN LETTER AE;Lo;0;R;;;;;N;;;;;
+10B07;AVESTAN LETTER AEE;Lo;0;R;;;;;N;;;;;
+10B08;AVESTAN LETTER E;Lo;0;R;;;;;N;;;;;
+10B09;AVESTAN LETTER EE;Lo;0;R;;;;;N;;;;;
+10B0A;AVESTAN LETTER O;Lo;0;R;;;;;N;;;;;
+10B0B;AVESTAN LETTER OO;Lo;0;R;;;;;N;;;;;
+10B0C;AVESTAN LETTER I;Lo;0;R;;;;;N;;;;;
+10B0D;AVESTAN LETTER II;Lo;0;R;;;;;N;;;;;
+10B0E;AVESTAN LETTER U;Lo;0;R;;;;;N;;;;;
+10B0F;AVESTAN LETTER UU;Lo;0;R;;;;;N;;;;;
+10B10;AVESTAN LETTER KE;Lo;0;R;;;;;N;;;;;
+10B11;AVESTAN LETTER XE;Lo;0;R;;;;;N;;;;;
+10B12;AVESTAN LETTER XYE;Lo;0;R;;;;;N;;;;;
+10B13;AVESTAN LETTER XVE;Lo;0;R;;;;;N;;;;;
+10B14;AVESTAN LETTER GE;Lo;0;R;;;;;N;;;;;
+10B15;AVESTAN LETTER GGE;Lo;0;R;;;;;N;;;;;
+10B16;AVESTAN LETTER GHE;Lo;0;R;;;;;N;;;;;
+10B17;AVESTAN LETTER CE;Lo;0;R;;;;;N;;;;;
+10B18;AVESTAN LETTER JE;Lo;0;R;;;;;N;;;;;
+10B19;AVESTAN LETTER TE;Lo;0;R;;;;;N;;;;;
+10B1A;AVESTAN LETTER THE;Lo;0;R;;;;;N;;;;;
+10B1B;AVESTAN LETTER DE;Lo;0;R;;;;;N;;;;;
+10B1C;AVESTAN LETTER DHE;Lo;0;R;;;;;N;;;;;
+10B1D;AVESTAN LETTER TTE;Lo;0;R;;;;;N;;;;;
+10B1E;AVESTAN LETTER PE;Lo;0;R;;;;;N;;;;;
+10B1F;AVESTAN LETTER FE;Lo;0;R;;;;;N;;;;;
+10B20;AVESTAN LETTER BE;Lo;0;R;;;;;N;;;;;
+10B21;AVESTAN LETTER BHE;Lo;0;R;;;;;N;;;;;
+10B22;AVESTAN LETTER NGE;Lo;0;R;;;;;N;;;;;
+10B23;AVESTAN LETTER NGYE;Lo;0;R;;;;;N;;;;;
+10B24;AVESTAN LETTER NGVE;Lo;0;R;;;;;N;;;;;
+10B25;AVESTAN LETTER NE;Lo;0;R;;;;;N;;;;;
+10B26;AVESTAN LETTER NYE;Lo;0;R;;;;;N;;;;;
+10B27;AVESTAN LETTER NNE;Lo;0;R;;;;;N;;;;;
+10B28;AVESTAN LETTER ME;Lo;0;R;;;;;N;;;;;
+10B29;AVESTAN LETTER HME;Lo;0;R;;;;;N;;;;;
+10B2A;AVESTAN LETTER YYE;Lo;0;R;;;;;N;;;;;
+10B2B;AVESTAN LETTER YE;Lo;0;R;;;;;N;;;;;
+10B2C;AVESTAN LETTER VE;Lo;0;R;;;;;N;;;;;
+10B2D;AVESTAN LETTER RE;Lo;0;R;;;;;N;;;;;
+10B2E;AVESTAN LETTER LE;Lo;0;R;;;;;N;;;;;
+10B2F;AVESTAN LETTER SE;Lo;0;R;;;;;N;;;;;
+10B30;AVESTAN LETTER ZE;Lo;0;R;;;;;N;;;;;
+10B31;AVESTAN LETTER SHE;Lo;0;R;;;;;N;;;;;
+10B32;AVESTAN LETTER ZHE;Lo;0;R;;;;;N;;;;;
+10B33;AVESTAN LETTER SHYE;Lo;0;R;;;;;N;;;;;
+10B34;AVESTAN LETTER SSHE;Lo;0;R;;;;;N;;;;;
+10B35;AVESTAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10B39;AVESTAN ABBREVIATION MARK;Po;0;ON;;;;;N;;;;;
+10B3A;TINY TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B3B;SMALL TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B3C;LARGE TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B3D;LARGE ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B3E;LARGE TWO RINGS OVER ONE RING PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B3F;LARGE ONE RING OVER TWO RINGS PUNCTUATION;Po;0;ON;;;;;N;;;;;
+10B40;INSCRIPTIONAL PARTHIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10B41;INSCRIPTIONAL PARTHIAN LETTER BETH;Lo;0;R;;;;;N;;;;;
+10B42;INSCRIPTIONAL PARTHIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10B43;INSCRIPTIONAL PARTHIAN LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10B44;INSCRIPTIONAL PARTHIAN LETTER HE;Lo;0;R;;;;;N;;;;;
+10B45;INSCRIPTIONAL PARTHIAN LETTER WAW;Lo;0;R;;;;;N;;;;;
+10B46;INSCRIPTIONAL PARTHIAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10B47;INSCRIPTIONAL PARTHIAN LETTER HETH;Lo;0;R;;;;;N;;;;;
+10B48;INSCRIPTIONAL PARTHIAN LETTER TETH;Lo;0;R;;;;;N;;;;;
+10B49;INSCRIPTIONAL PARTHIAN LETTER YODH;Lo;0;R;;;;;N;;;;;
+10B4A;INSCRIPTIONAL PARTHIAN LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10B4B;INSCRIPTIONAL PARTHIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10B4C;INSCRIPTIONAL PARTHIAN LETTER MEM;Lo;0;R;;;;;N;;;;;
+10B4D;INSCRIPTIONAL PARTHIAN LETTER NUN;Lo;0;R;;;;;N;;;;;
+10B4E;INSCRIPTIONAL PARTHIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10B4F;INSCRIPTIONAL PARTHIAN LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10B50;INSCRIPTIONAL PARTHIAN LETTER PE;Lo;0;R;;;;;N;;;;;
+10B51;INSCRIPTIONAL PARTHIAN LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10B52;INSCRIPTIONAL PARTHIAN LETTER QOPH;Lo;0;R;;;;;N;;;;;
+10B53;INSCRIPTIONAL PARTHIAN LETTER RESH;Lo;0;R;;;;;N;;;;;
+10B54;INSCRIPTIONAL PARTHIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10B55;INSCRIPTIONAL PARTHIAN LETTER TAW;Lo;0;R;;;;;N;;;;;
+10B58;INSCRIPTIONAL PARTHIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10B59;INSCRIPTIONAL PARTHIAN NUMBER TWO;No;0;R;;;;2;N;;;;;
+10B5A;INSCRIPTIONAL PARTHIAN NUMBER THREE;No;0;R;;;;3;N;;;;;
+10B5B;INSCRIPTIONAL PARTHIAN NUMBER FOUR;No;0;R;;;;4;N;;;;;
+10B5C;INSCRIPTIONAL PARTHIAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+10B5D;INSCRIPTIONAL PARTHIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10B5E;INSCRIPTIONAL PARTHIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10B5F;INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+10B60;INSCRIPTIONAL PAHLAVI LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10B61;INSCRIPTIONAL PAHLAVI LETTER BETH;Lo;0;R;;;;;N;;;;;
+10B62;INSCRIPTIONAL PAHLAVI LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10B63;INSCRIPTIONAL PAHLAVI LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10B64;INSCRIPTIONAL PAHLAVI LETTER HE;Lo;0;R;;;;;N;;;;;
+10B65;INSCRIPTIONAL PAHLAVI LETTER WAW-AYIN-RESH;Lo;0;R;;;;;N;;;;;
+10B66;INSCRIPTIONAL PAHLAVI LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10B67;INSCRIPTIONAL PAHLAVI LETTER HETH;Lo;0;R;;;;;N;;;;;
+10B68;INSCRIPTIONAL PAHLAVI LETTER TETH;Lo;0;R;;;;;N;;;;;
+10B69;INSCRIPTIONAL PAHLAVI LETTER YODH;Lo;0;R;;;;;N;;;;;
+10B6A;INSCRIPTIONAL PAHLAVI LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10B6B;INSCRIPTIONAL PAHLAVI LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10B6C;INSCRIPTIONAL PAHLAVI LETTER MEM-QOPH;Lo;0;R;;;;;N;;;;;
+10B6D;INSCRIPTIONAL PAHLAVI LETTER NUN;Lo;0;R;;;;;N;;;;;
+10B6E;INSCRIPTIONAL PAHLAVI LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10B6F;INSCRIPTIONAL PAHLAVI LETTER PE;Lo;0;R;;;;;N;;;;;
+10B70;INSCRIPTIONAL PAHLAVI LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10B71;INSCRIPTIONAL PAHLAVI LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10B72;INSCRIPTIONAL PAHLAVI LETTER TAW;Lo;0;R;;;;;N;;;;;
+10B78;INSCRIPTIONAL PAHLAVI NUMBER ONE;No;0;R;;;;1;N;;;;;
+10B79;INSCRIPTIONAL PAHLAVI NUMBER TWO;No;0;R;;;;2;N;;;;;
+10B7A;INSCRIPTIONAL PAHLAVI NUMBER THREE;No;0;R;;;;3;N;;;;;
+10B7B;INSCRIPTIONAL PAHLAVI NUMBER FOUR;No;0;R;;;;4;N;;;;;
+10B7C;INSCRIPTIONAL PAHLAVI NUMBER TEN;No;0;R;;;;10;N;;;;;
+10B7D;INSCRIPTIONAL PAHLAVI NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10B7E;INSCRIPTIONAL PAHLAVI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10B7F;INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+10B80;PSALTER PAHLAVI LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10B81;PSALTER PAHLAVI LETTER BETH;Lo;0;R;;;;;N;;;;;
+10B82;PSALTER PAHLAVI LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10B83;PSALTER PAHLAVI LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10B84;PSALTER PAHLAVI LETTER HE;Lo;0;R;;;;;N;;;;;
+10B85;PSALTER PAHLAVI LETTER WAW-AYIN-RESH;Lo;0;R;;;;;N;;;;;
+10B86;PSALTER PAHLAVI LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10B87;PSALTER PAHLAVI LETTER HETH;Lo;0;R;;;;;N;;;;;
+10B88;PSALTER PAHLAVI LETTER YODH;Lo;0;R;;;;;N;;;;;
+10B89;PSALTER PAHLAVI LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10B8A;PSALTER PAHLAVI LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10B8B;PSALTER PAHLAVI LETTER MEM-QOPH;Lo;0;R;;;;;N;;;;;
+10B8C;PSALTER PAHLAVI LETTER NUN;Lo;0;R;;;;;N;;;;;
+10B8D;PSALTER PAHLAVI LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10B8E;PSALTER PAHLAVI LETTER PE;Lo;0;R;;;;;N;;;;;
+10B8F;PSALTER PAHLAVI LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10B90;PSALTER PAHLAVI LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10B91;PSALTER PAHLAVI LETTER TAW;Lo;0;R;;;;;N;;;;;
+10B99;PSALTER PAHLAVI SECTION MARK;Po;0;R;;;;;N;;;;;
+10B9A;PSALTER PAHLAVI TURNED SECTION MARK;Po;0;R;;;;;N;;;;;
+10B9B;PSALTER PAHLAVI FOUR DOTS WITH CROSS;Po;0;R;;;;;N;;;;;
+10B9C;PSALTER PAHLAVI FOUR DOTS WITH DOT;Po;0;R;;;;;N;;;;;
+10BA9;PSALTER PAHLAVI NUMBER ONE;No;0;R;;;;1;N;;;;;
+10BAA;PSALTER PAHLAVI NUMBER TWO;No;0;R;;;;2;N;;;;;
+10BAB;PSALTER PAHLAVI NUMBER THREE;No;0;R;;;;3;N;;;;;
+10BAC;PSALTER PAHLAVI NUMBER FOUR;No;0;R;;;;4;N;;;;;
+10BAD;PSALTER PAHLAVI NUMBER TEN;No;0;R;;;;10;N;;;;;
+10BAE;PSALTER PAHLAVI NUMBER TWENTY;No;0;R;;;;20;N;;;;;
+10BAF;PSALTER PAHLAVI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10C00;OLD TURKIC LETTER ORKHON A;Lo;0;R;;;;;N;;;;;
+10C01;OLD TURKIC LETTER YENISEI A;Lo;0;R;;;;;N;;;;;
+10C02;OLD TURKIC LETTER YENISEI AE;Lo;0;R;;;;;N;;;;;
+10C03;OLD TURKIC LETTER ORKHON I;Lo;0;R;;;;;N;;;;;
+10C04;OLD TURKIC LETTER YENISEI I;Lo;0;R;;;;;N;;;;;
+10C05;OLD TURKIC LETTER YENISEI E;Lo;0;R;;;;;N;;;;;
+10C06;OLD TURKIC LETTER ORKHON O;Lo;0;R;;;;;N;;;;;
+10C07;OLD TURKIC LETTER ORKHON OE;Lo;0;R;;;;;N;;;;;
+10C08;OLD TURKIC LETTER YENISEI OE;Lo;0;R;;;;;N;;;;;
+10C09;OLD TURKIC LETTER ORKHON AB;Lo;0;R;;;;;N;;;;;
+10C0A;OLD TURKIC LETTER YENISEI AB;Lo;0;R;;;;;N;;;;;
+10C0B;OLD TURKIC LETTER ORKHON AEB;Lo;0;R;;;;;N;;;;;
+10C0C;OLD TURKIC LETTER YENISEI AEB;Lo;0;R;;;;;N;;;;;
+10C0D;OLD TURKIC LETTER ORKHON AG;Lo;0;R;;;;;N;;;;;
+10C0E;OLD TURKIC LETTER YENISEI AG;Lo;0;R;;;;;N;;;;;
+10C0F;OLD TURKIC LETTER ORKHON AEG;Lo;0;R;;;;;N;;;;;
+10C10;OLD TURKIC LETTER YENISEI AEG;Lo;0;R;;;;;N;;;;;
+10C11;OLD TURKIC LETTER ORKHON AD;Lo;0;R;;;;;N;;;;;
+10C12;OLD TURKIC LETTER YENISEI AD;Lo;0;R;;;;;N;;;;;
+10C13;OLD TURKIC LETTER ORKHON AED;Lo;0;R;;;;;N;;;;;
+10C14;OLD TURKIC LETTER ORKHON EZ;Lo;0;R;;;;;N;;;;;
+10C15;OLD TURKIC LETTER YENISEI EZ;Lo;0;R;;;;;N;;;;;
+10C16;OLD TURKIC LETTER ORKHON AY;Lo;0;R;;;;;N;;;;;
+10C17;OLD TURKIC LETTER YENISEI AY;Lo;0;R;;;;;N;;;;;
+10C18;OLD TURKIC LETTER ORKHON AEY;Lo;0;R;;;;;N;;;;;
+10C19;OLD TURKIC LETTER YENISEI AEY;Lo;0;R;;;;;N;;;;;
+10C1A;OLD TURKIC LETTER ORKHON AEK;Lo;0;R;;;;;N;;;;;
+10C1B;OLD TURKIC LETTER YENISEI AEK;Lo;0;R;;;;;N;;;;;
+10C1C;OLD TURKIC LETTER ORKHON OEK;Lo;0;R;;;;;N;;;;;
+10C1D;OLD TURKIC LETTER YENISEI OEK;Lo;0;R;;;;;N;;;;;
+10C1E;OLD TURKIC LETTER ORKHON AL;Lo;0;R;;;;;N;;;;;
+10C1F;OLD TURKIC LETTER YENISEI AL;Lo;0;R;;;;;N;;;;;
+10C20;OLD TURKIC LETTER ORKHON AEL;Lo;0;R;;;;;N;;;;;
+10C21;OLD TURKIC LETTER ORKHON ELT;Lo;0;R;;;;;N;;;;;
+10C22;OLD TURKIC LETTER ORKHON EM;Lo;0;R;;;;;N;;;;;
+10C23;OLD TURKIC LETTER ORKHON AN;Lo;0;R;;;;;N;;;;;
+10C24;OLD TURKIC LETTER ORKHON AEN;Lo;0;R;;;;;N;;;;;
+10C25;OLD TURKIC LETTER YENISEI AEN;Lo;0;R;;;;;N;;;;;
+10C26;OLD TURKIC LETTER ORKHON ENT;Lo;0;R;;;;;N;;;;;
+10C27;OLD TURKIC LETTER YENISEI ENT;Lo;0;R;;;;;N;;;;;
+10C28;OLD TURKIC LETTER ORKHON ENC;Lo;0;R;;;;;N;;;;;
+10C29;OLD TURKIC LETTER YENISEI ENC;Lo;0;R;;;;;N;;;;;
+10C2A;OLD TURKIC LETTER ORKHON ENY;Lo;0;R;;;;;N;;;;;
+10C2B;OLD TURKIC LETTER YENISEI ENY;Lo;0;R;;;;;N;;;;;
+10C2C;OLD TURKIC LETTER YENISEI ANG;Lo;0;R;;;;;N;;;;;
+10C2D;OLD TURKIC LETTER ORKHON ENG;Lo;0;R;;;;;N;;;;;
+10C2E;OLD TURKIC LETTER YENISEI AENG;Lo;0;R;;;;;N;;;;;
+10C2F;OLD TURKIC LETTER ORKHON EP;Lo;0;R;;;;;N;;;;;
+10C30;OLD TURKIC LETTER ORKHON OP;Lo;0;R;;;;;N;;;;;
+10C31;OLD TURKIC LETTER ORKHON IC;Lo;0;R;;;;;N;;;;;
+10C32;OLD TURKIC LETTER ORKHON EC;Lo;0;R;;;;;N;;;;;
+10C33;OLD TURKIC LETTER YENISEI EC;Lo;0;R;;;;;N;;;;;
+10C34;OLD TURKIC LETTER ORKHON AQ;Lo;0;R;;;;;N;;;;;
+10C35;OLD TURKIC LETTER YENISEI AQ;Lo;0;R;;;;;N;;;;;
+10C36;OLD TURKIC LETTER ORKHON IQ;Lo;0;R;;;;;N;;;;;
+10C37;OLD TURKIC LETTER YENISEI IQ;Lo;0;R;;;;;N;;;;;
+10C38;OLD TURKIC LETTER ORKHON OQ;Lo;0;R;;;;;N;;;;;
+10C39;OLD TURKIC LETTER YENISEI OQ;Lo;0;R;;;;;N;;;;;
+10C3A;OLD TURKIC LETTER ORKHON AR;Lo;0;R;;;;;N;;;;;
+10C3B;OLD TURKIC LETTER YENISEI AR;Lo;0;R;;;;;N;;;;;
+10C3C;OLD TURKIC LETTER ORKHON AER;Lo;0;R;;;;;N;;;;;
+10C3D;OLD TURKIC LETTER ORKHON AS;Lo;0;R;;;;;N;;;;;
+10C3E;OLD TURKIC LETTER ORKHON AES;Lo;0;R;;;;;N;;;;;
+10C3F;OLD TURKIC LETTER ORKHON ASH;Lo;0;R;;;;;N;;;;;
+10C40;OLD TURKIC LETTER YENISEI ASH;Lo;0;R;;;;;N;;;;;
+10C41;OLD TURKIC LETTER ORKHON ESH;Lo;0;R;;;;;N;;;;;
+10C42;OLD TURKIC LETTER YENISEI ESH;Lo;0;R;;;;;N;;;;;
+10C43;OLD TURKIC LETTER ORKHON AT;Lo;0;R;;;;;N;;;;;
+10C44;OLD TURKIC LETTER YENISEI AT;Lo;0;R;;;;;N;;;;;
+10C45;OLD TURKIC LETTER ORKHON AET;Lo;0;R;;;;;N;;;;;
+10C46;OLD TURKIC LETTER YENISEI AET;Lo;0;R;;;;;N;;;;;
+10C47;OLD TURKIC LETTER ORKHON OT;Lo;0;R;;;;;N;;;;;
+10C48;OLD TURKIC LETTER ORKHON BASH;Lo;0;R;;;;;N;;;;;
+10C80;OLD HUNGARIAN CAPITAL LETTER A;Lu;0;R;;;;;N;;;;10CC0;
+10C81;OLD HUNGARIAN CAPITAL LETTER AA;Lu;0;R;;;;;N;;;;10CC1;
+10C82;OLD HUNGARIAN CAPITAL LETTER EB;Lu;0;R;;;;;N;;;;10CC2;
+10C83;OLD HUNGARIAN CAPITAL LETTER AMB;Lu;0;R;;;;;N;;;;10CC3;
+10C84;OLD HUNGARIAN CAPITAL LETTER EC;Lu;0;R;;;;;N;;;;10CC4;
+10C85;OLD HUNGARIAN CAPITAL LETTER ENC;Lu;0;R;;;;;N;;;;10CC5;
+10C86;OLD HUNGARIAN CAPITAL LETTER ECS;Lu;0;R;;;;;N;;;;10CC6;
+10C87;OLD HUNGARIAN CAPITAL LETTER ED;Lu;0;R;;;;;N;;;;10CC7;
+10C88;OLD HUNGARIAN CAPITAL LETTER AND;Lu;0;R;;;;;N;;;;10CC8;
+10C89;OLD HUNGARIAN CAPITAL LETTER E;Lu;0;R;;;;;N;;;;10CC9;
+10C8A;OLD HUNGARIAN CAPITAL LETTER CLOSE E;Lu;0;R;;;;;N;;;;10CCA;
+10C8B;OLD HUNGARIAN CAPITAL LETTER EE;Lu;0;R;;;;;N;;;;10CCB;
+10C8C;OLD HUNGARIAN CAPITAL LETTER EF;Lu;0;R;;;;;N;;;;10CCC;
+10C8D;OLD HUNGARIAN CAPITAL LETTER EG;Lu;0;R;;;;;N;;;;10CCD;
+10C8E;OLD HUNGARIAN CAPITAL LETTER EGY;Lu;0;R;;;;;N;;;;10CCE;
+10C8F;OLD HUNGARIAN CAPITAL LETTER EH;Lu;0;R;;;;;N;;;;10CCF;
+10C90;OLD HUNGARIAN CAPITAL LETTER I;Lu;0;R;;;;;N;;;;10CD0;
+10C91;OLD HUNGARIAN CAPITAL LETTER II;Lu;0;R;;;;;N;;;;10CD1;
+10C92;OLD HUNGARIAN CAPITAL LETTER EJ;Lu;0;R;;;;;N;;;;10CD2;
+10C93;OLD HUNGARIAN CAPITAL LETTER EK;Lu;0;R;;;;;N;;;;10CD3;
+10C94;OLD HUNGARIAN CAPITAL LETTER AK;Lu;0;R;;;;;N;;;;10CD4;
+10C95;OLD HUNGARIAN CAPITAL LETTER UNK;Lu;0;R;;;;;N;;;;10CD5;
+10C96;OLD HUNGARIAN CAPITAL LETTER EL;Lu;0;R;;;;;N;;;;10CD6;
+10C97;OLD HUNGARIAN CAPITAL LETTER ELY;Lu;0;R;;;;;N;;;;10CD7;
+10C98;OLD HUNGARIAN CAPITAL LETTER EM;Lu;0;R;;;;;N;;;;10CD8;
+10C99;OLD HUNGARIAN CAPITAL LETTER EN;Lu;0;R;;;;;N;;;;10CD9;
+10C9A;OLD HUNGARIAN CAPITAL LETTER ENY;Lu;0;R;;;;;N;;;;10CDA;
+10C9B;OLD HUNGARIAN CAPITAL LETTER O;Lu;0;R;;;;;N;;;;10CDB;
+10C9C;OLD HUNGARIAN CAPITAL LETTER OO;Lu;0;R;;;;;N;;;;10CDC;
+10C9D;OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE;Lu;0;R;;;;;N;;;;10CDD;
+10C9E;OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE;Lu;0;R;;;;;N;;;;10CDE;
+10C9F;OLD HUNGARIAN CAPITAL LETTER OEE;Lu;0;R;;;;;N;;;;10CDF;
+10CA0;OLD HUNGARIAN CAPITAL LETTER EP;Lu;0;R;;;;;N;;;;10CE0;
+10CA1;OLD HUNGARIAN CAPITAL LETTER EMP;Lu;0;R;;;;;N;;;;10CE1;
+10CA2;OLD HUNGARIAN CAPITAL LETTER ER;Lu;0;R;;;;;N;;;;10CE2;
+10CA3;OLD HUNGARIAN CAPITAL LETTER SHORT ER;Lu;0;R;;;;;N;;;;10CE3;
+10CA4;OLD HUNGARIAN CAPITAL LETTER ES;Lu;0;R;;;;;N;;;;10CE4;
+10CA5;OLD HUNGARIAN CAPITAL LETTER ESZ;Lu;0;R;;;;;N;;;;10CE5;
+10CA6;OLD HUNGARIAN CAPITAL LETTER ET;Lu;0;R;;;;;N;;;;10CE6;
+10CA7;OLD HUNGARIAN CAPITAL LETTER ENT;Lu;0;R;;;;;N;;;;10CE7;
+10CA8;OLD HUNGARIAN CAPITAL LETTER ETY;Lu;0;R;;;;;N;;;;10CE8;
+10CA9;OLD HUNGARIAN CAPITAL LETTER ECH;Lu;0;R;;;;;N;;;;10CE9;
+10CAA;OLD HUNGARIAN CAPITAL LETTER U;Lu;0;R;;;;;N;;;;10CEA;
+10CAB;OLD HUNGARIAN CAPITAL LETTER UU;Lu;0;R;;;;;N;;;;10CEB;
+10CAC;OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE;Lu;0;R;;;;;N;;;;10CEC;
+10CAD;OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE;Lu;0;R;;;;;N;;;;10CED;
+10CAE;OLD HUNGARIAN CAPITAL LETTER EV;Lu;0;R;;;;;N;;;;10CEE;
+10CAF;OLD HUNGARIAN CAPITAL LETTER EZ;Lu;0;R;;;;;N;;;;10CEF;
+10CB0;OLD HUNGARIAN CAPITAL LETTER EZS;Lu;0;R;;;;;N;;;;10CF0;
+10CB1;OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN;Lu;0;R;;;;;N;;;;10CF1;
+10CB2;OLD HUNGARIAN CAPITAL LETTER US;Lu;0;R;;;;;N;;;;10CF2;
+10CC0;OLD HUNGARIAN SMALL LETTER A;Ll;0;R;;;;;N;;;10C80;;10C80
+10CC1;OLD HUNGARIAN SMALL LETTER AA;Ll;0;R;;;;;N;;;10C81;;10C81
+10CC2;OLD HUNGARIAN SMALL LETTER EB;Ll;0;R;;;;;N;;;10C82;;10C82
+10CC3;OLD HUNGARIAN SMALL LETTER AMB;Ll;0;R;;;;;N;;;10C83;;10C83
+10CC4;OLD HUNGARIAN SMALL LETTER EC;Ll;0;R;;;;;N;;;10C84;;10C84
+10CC5;OLD HUNGARIAN SMALL LETTER ENC;Ll;0;R;;;;;N;;;10C85;;10C85
+10CC6;OLD HUNGARIAN SMALL LETTER ECS;Ll;0;R;;;;;N;;;10C86;;10C86
+10CC7;OLD HUNGARIAN SMALL LETTER ED;Ll;0;R;;;;;N;;;10C87;;10C87
+10CC8;OLD HUNGARIAN SMALL LETTER AND;Ll;0;R;;;;;N;;;10C88;;10C88
+10CC9;OLD HUNGARIAN SMALL LETTER E;Ll;0;R;;;;;N;;;10C89;;10C89
+10CCA;OLD HUNGARIAN SMALL LETTER CLOSE E;Ll;0;R;;;;;N;;;10C8A;;10C8A
+10CCB;OLD HUNGARIAN SMALL LETTER EE;Ll;0;R;;;;;N;;;10C8B;;10C8B
+10CCC;OLD HUNGARIAN SMALL LETTER EF;Ll;0;R;;;;;N;;;10C8C;;10C8C
+10CCD;OLD HUNGARIAN SMALL LETTER EG;Ll;0;R;;;;;N;;;10C8D;;10C8D
+10CCE;OLD HUNGARIAN SMALL LETTER EGY;Ll;0;R;;;;;N;;;10C8E;;10C8E
+10CCF;OLD HUNGARIAN SMALL LETTER EH;Ll;0;R;;;;;N;;;10C8F;;10C8F
+10CD0;OLD HUNGARIAN SMALL LETTER I;Ll;0;R;;;;;N;;;10C90;;10C90
+10CD1;OLD HUNGARIAN SMALL LETTER II;Ll;0;R;;;;;N;;;10C91;;10C91
+10CD2;OLD HUNGARIAN SMALL LETTER EJ;Ll;0;R;;;;;N;;;10C92;;10C92
+10CD3;OLD HUNGARIAN SMALL LETTER EK;Ll;0;R;;;;;N;;;10C93;;10C93
+10CD4;OLD HUNGARIAN SMALL LETTER AK;Ll;0;R;;;;;N;;;10C94;;10C94
+10CD5;OLD HUNGARIAN SMALL LETTER UNK;Ll;0;R;;;;;N;;;10C95;;10C95
+10CD6;OLD HUNGARIAN SMALL LETTER EL;Ll;0;R;;;;;N;;;10C96;;10C96
+10CD7;OLD HUNGARIAN SMALL LETTER ELY;Ll;0;R;;;;;N;;;10C97;;10C97
+10CD8;OLD HUNGARIAN SMALL LETTER EM;Ll;0;R;;;;;N;;;10C98;;10C98
+10CD9;OLD HUNGARIAN SMALL LETTER EN;Ll;0;R;;;;;N;;;10C99;;10C99
+10CDA;OLD HUNGARIAN SMALL LETTER ENY;Ll;0;R;;;;;N;;;10C9A;;10C9A
+10CDB;OLD HUNGARIAN SMALL LETTER O;Ll;0;R;;;;;N;;;10C9B;;10C9B
+10CDC;OLD HUNGARIAN SMALL LETTER OO;Ll;0;R;;;;;N;;;10C9C;;10C9C
+10CDD;OLD HUNGARIAN SMALL LETTER NIKOLSBURG OE;Ll;0;R;;;;;N;;;10C9D;;10C9D
+10CDE;OLD HUNGARIAN SMALL LETTER RUDIMENTA OE;Ll;0;R;;;;;N;;;10C9E;;10C9E
+10CDF;OLD HUNGARIAN SMALL LETTER OEE;Ll;0;R;;;;;N;;;10C9F;;10C9F
+10CE0;OLD HUNGARIAN SMALL LETTER EP;Ll;0;R;;;;;N;;;10CA0;;10CA0
+10CE1;OLD HUNGARIAN SMALL LETTER EMP;Ll;0;R;;;;;N;;;10CA1;;10CA1
+10CE2;OLD HUNGARIAN SMALL LETTER ER;Ll;0;R;;;;;N;;;10CA2;;10CA2
+10CE3;OLD HUNGARIAN SMALL LETTER SHORT ER;Ll;0;R;;;;;N;;;10CA3;;10CA3
+10CE4;OLD HUNGARIAN SMALL LETTER ES;Ll;0;R;;;;;N;;;10CA4;;10CA4
+10CE5;OLD HUNGARIAN SMALL LETTER ESZ;Ll;0;R;;;;;N;;;10CA5;;10CA5
+10CE6;OLD HUNGARIAN SMALL LETTER ET;Ll;0;R;;;;;N;;;10CA6;;10CA6
+10CE7;OLD HUNGARIAN SMALL LETTER ENT;Ll;0;R;;;;;N;;;10CA7;;10CA7
+10CE8;OLD HUNGARIAN SMALL LETTER ETY;Ll;0;R;;;;;N;;;10CA8;;10CA8
+10CE9;OLD HUNGARIAN SMALL LETTER ECH;Ll;0;R;;;;;N;;;10CA9;;10CA9
+10CEA;OLD HUNGARIAN SMALL LETTER U;Ll;0;R;;;;;N;;;10CAA;;10CAA
+10CEB;OLD HUNGARIAN SMALL LETTER UU;Ll;0;R;;;;;N;;;10CAB;;10CAB
+10CEC;OLD HUNGARIAN SMALL LETTER NIKOLSBURG UE;Ll;0;R;;;;;N;;;10CAC;;10CAC
+10CED;OLD HUNGARIAN SMALL LETTER RUDIMENTA UE;Ll;0;R;;;;;N;;;10CAD;;10CAD
+10CEE;OLD HUNGARIAN SMALL LETTER EV;Ll;0;R;;;;;N;;;10CAE;;10CAE
+10CEF;OLD HUNGARIAN SMALL LETTER EZ;Ll;0;R;;;;;N;;;10CAF;;10CAF
+10CF0;OLD HUNGARIAN SMALL LETTER EZS;Ll;0;R;;;;;N;;;10CB0;;10CB0
+10CF1;OLD HUNGARIAN SMALL LETTER ENT-SHAPED SIGN;Ll;0;R;;;;;N;;;10CB1;;10CB1
+10CF2;OLD HUNGARIAN SMALL LETTER US;Ll;0;R;;;;;N;;;10CB2;;10CB2
+10CFA;OLD HUNGARIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
+10CFB;OLD HUNGARIAN NUMBER FIVE;No;0;R;;;;5;N;;;;;
+10CFC;OLD HUNGARIAN NUMBER TEN;No;0;R;;;;10;N;;;;;
+10CFD;OLD HUNGARIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;;
+10CFE;OLD HUNGARIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
+10CFF;OLD HUNGARIAN NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
+10E60;RUMI DIGIT ONE;No;0;AN;;;1;1;N;;;;;
+10E61;RUMI DIGIT TWO;No;0;AN;;;2;2;N;;;;;
+10E62;RUMI DIGIT THREE;No;0;AN;;;3;3;N;;;;;
+10E63;RUMI DIGIT FOUR;No;0;AN;;;4;4;N;;;;;
+10E64;RUMI DIGIT FIVE;No;0;AN;;;5;5;N;;;;;
+10E65;RUMI DIGIT SIX;No;0;AN;;;6;6;N;;;;;
+10E66;RUMI DIGIT SEVEN;No;0;AN;;;7;7;N;;;;;
+10E67;RUMI DIGIT EIGHT;No;0;AN;;;8;8;N;;;;;
+10E68;RUMI DIGIT NINE;No;0;AN;;;9;9;N;;;;;
+10E69;RUMI NUMBER TEN;No;0;AN;;;;10;N;;;;;
+10E6A;RUMI NUMBER TWENTY;No;0;AN;;;;20;N;;;;;
+10E6B;RUMI NUMBER THIRTY;No;0;AN;;;;30;N;;;;;
+10E6C;RUMI NUMBER FORTY;No;0;AN;;;;40;N;;;;;
+10E6D;RUMI NUMBER FIFTY;No;0;AN;;;;50;N;;;;;
+10E6E;RUMI NUMBER SIXTY;No;0;AN;;;;60;N;;;;;
+10E6F;RUMI NUMBER SEVENTY;No;0;AN;;;;70;N;;;;;
+10E70;RUMI NUMBER EIGHTY;No;0;AN;;;;80;N;;;;;
+10E71;RUMI NUMBER NINETY;No;0;AN;;;;90;N;;;;;
+10E72;RUMI NUMBER ONE HUNDRED;No;0;AN;;;;100;N;;;;;
+10E73;RUMI NUMBER TWO HUNDRED;No;0;AN;;;;200;N;;;;;
+10E74;RUMI NUMBER THREE HUNDRED;No;0;AN;;;;300;N;;;;;
+10E75;RUMI NUMBER FOUR HUNDRED;No;0;AN;;;;400;N;;;;;
+10E76;RUMI NUMBER FIVE HUNDRED;No;0;AN;;;;500;N;;;;;
+10E77;RUMI NUMBER SIX HUNDRED;No;0;AN;;;;600;N;;;;;
+10E78;RUMI NUMBER SEVEN HUNDRED;No;0;AN;;;;700;N;;;;;
+10E79;RUMI NUMBER EIGHT HUNDRED;No;0;AN;;;;800;N;;;;;
+10E7A;RUMI NUMBER NINE HUNDRED;No;0;AN;;;;900;N;;;;;
+10E7B;RUMI FRACTION ONE HALF;No;0;AN;;;;1/2;N;;;;;
+10E7C;RUMI FRACTION ONE QUARTER;No;0;AN;;;;1/4;N;;;;;
+10E7D;RUMI FRACTION ONE THIRD;No;0;AN;;;;1/3;N;;;;;
+10E7E;RUMI FRACTION TWO THIRDS;No;0;AN;;;;2/3;N;;;;;
+11000;BRAHMI SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;;
+11001;BRAHMI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11002;BRAHMI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11003;BRAHMI SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+11004;BRAHMI SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+11005;BRAHMI LETTER A;Lo;0;L;;;;;N;;;;;
+11006;BRAHMI LETTER AA;Lo;0;L;;;;;N;;;;;
+11007;BRAHMI LETTER I;Lo;0;L;;;;;N;;;;;
+11008;BRAHMI LETTER II;Lo;0;L;;;;;N;;;;;
+11009;BRAHMI LETTER U;Lo;0;L;;;;;N;;;;;
+1100A;BRAHMI LETTER UU;Lo;0;L;;;;;N;;;;;
+1100B;BRAHMI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+1100C;BRAHMI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+1100D;BRAHMI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1100E;BRAHMI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1100F;BRAHMI LETTER E;Lo;0;L;;;;;N;;;;;
+11010;BRAHMI LETTER AI;Lo;0;L;;;;;N;;;;;
+11011;BRAHMI LETTER O;Lo;0;L;;;;;N;;;;;
+11012;BRAHMI LETTER AU;Lo;0;L;;;;;N;;;;;
+11013;BRAHMI LETTER KA;Lo;0;L;;;;;N;;;;;
+11014;BRAHMI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11015;BRAHMI LETTER GA;Lo;0;L;;;;;N;;;;;
+11016;BRAHMI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11017;BRAHMI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11018;BRAHMI LETTER CA;Lo;0;L;;;;;N;;;;;
+11019;BRAHMI LETTER CHA;Lo;0;L;;;;;N;;;;;
+1101A;BRAHMI LETTER JA;Lo;0;L;;;;;N;;;;;
+1101B;BRAHMI LETTER JHA;Lo;0;L;;;;;N;;;;;
+1101C;BRAHMI LETTER NYA;Lo;0;L;;;;;N;;;;;
+1101D;BRAHMI LETTER TTA;Lo;0;L;;;;;N;;;;;
+1101E;BRAHMI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1101F;BRAHMI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11020;BRAHMI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11021;BRAHMI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11022;BRAHMI LETTER TA;Lo;0;L;;;;;N;;;;;
+11023;BRAHMI LETTER THA;Lo;0;L;;;;;N;;;;;
+11024;BRAHMI LETTER DA;Lo;0;L;;;;;N;;;;;
+11025;BRAHMI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11026;BRAHMI LETTER NA;Lo;0;L;;;;;N;;;;;
+11027;BRAHMI LETTER PA;Lo;0;L;;;;;N;;;;;
+11028;BRAHMI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11029;BRAHMI LETTER BA;Lo;0;L;;;;;N;;;;;
+1102A;BRAHMI LETTER BHA;Lo;0;L;;;;;N;;;;;
+1102B;BRAHMI LETTER MA;Lo;0;L;;;;;N;;;;;
+1102C;BRAHMI LETTER YA;Lo;0;L;;;;;N;;;;;
+1102D;BRAHMI LETTER RA;Lo;0;L;;;;;N;;;;;
+1102E;BRAHMI LETTER LA;Lo;0;L;;;;;N;;;;;
+1102F;BRAHMI LETTER VA;Lo;0;L;;;;;N;;;;;
+11030;BRAHMI LETTER SHA;Lo;0;L;;;;;N;;;;;
+11031;BRAHMI LETTER SSA;Lo;0;L;;;;;N;;;;;
+11032;BRAHMI LETTER SA;Lo;0;L;;;;;N;;;;;
+11033;BRAHMI LETTER HA;Lo;0;L;;;;;N;;;;;
+11034;BRAHMI LETTER LLA;Lo;0;L;;;;;N;;;;;
+11035;BRAHMI LETTER OLD TAMIL LLLA;Lo;0;L;;;;;N;;;;;
+11036;BRAHMI LETTER OLD TAMIL RRA;Lo;0;L;;;;;N;;;;;
+11037;BRAHMI LETTER OLD TAMIL NNNA;Lo;0;L;;;;;N;;;;;
+11038;BRAHMI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+11039;BRAHMI VOWEL SIGN BHATTIPROLU AA;Mn;0;NSM;;;;;N;;;;;
+1103A;BRAHMI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+1103B;BRAHMI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+1103C;BRAHMI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1103D;BRAHMI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1103E;BRAHMI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+1103F;BRAHMI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+11040;BRAHMI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+11041;BRAHMI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+11042;BRAHMI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11043;BRAHMI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+11044;BRAHMI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11045;BRAHMI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+11046;BRAHMI VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11047;BRAHMI DANDA;Po;0;L;;;;;N;;;;;
+11048;BRAHMI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+11049;BRAHMI PUNCTUATION DOT;Po;0;L;;;;;N;;;;;
+1104A;BRAHMI PUNCTUATION DOUBLE DOT;Po;0;L;;;;;N;;;;;
+1104B;BRAHMI PUNCTUATION LINE;Po;0;L;;;;;N;;;;;
+1104C;BRAHMI PUNCTUATION CRESCENT BAR;Po;0;L;;;;;N;;;;;
+1104D;BRAHMI PUNCTUATION LOTUS;Po;0;L;;;;;N;;;;;
+11052;BRAHMI NUMBER ONE;No;0;ON;;;1;1;N;;;;;
+11053;BRAHMI NUMBER TWO;No;0;ON;;;2;2;N;;;;;
+11054;BRAHMI NUMBER THREE;No;0;ON;;;3;3;N;;;;;
+11055;BRAHMI NUMBER FOUR;No;0;ON;;;4;4;N;;;;;
+11056;BRAHMI NUMBER FIVE;No;0;ON;;;5;5;N;;;;;
+11057;BRAHMI NUMBER SIX;No;0;ON;;;6;6;N;;;;;
+11058;BRAHMI NUMBER SEVEN;No;0;ON;;;7;7;N;;;;;
+11059;BRAHMI NUMBER EIGHT;No;0;ON;;;8;8;N;;;;;
+1105A;BRAHMI NUMBER NINE;No;0;ON;;;9;9;N;;;;;
+1105B;BRAHMI NUMBER TEN;No;0;ON;;;;10;N;;;;;
+1105C;BRAHMI NUMBER TWENTY;No;0;ON;;;;20;N;;;;;
+1105D;BRAHMI NUMBER THIRTY;No;0;ON;;;;30;N;;;;;
+1105E;BRAHMI NUMBER FORTY;No;0;ON;;;;40;N;;;;;
+1105F;BRAHMI NUMBER FIFTY;No;0;ON;;;;50;N;;;;;
+11060;BRAHMI NUMBER SIXTY;No;0;ON;;;;60;N;;;;;
+11061;BRAHMI NUMBER SEVENTY;No;0;ON;;;;70;N;;;;;
+11062;BRAHMI NUMBER EIGHTY;No;0;ON;;;;80;N;;;;;
+11063;BRAHMI NUMBER NINETY;No;0;ON;;;;90;N;;;;;
+11064;BRAHMI NUMBER ONE HUNDRED;No;0;ON;;;;100;N;;;;;
+11065;BRAHMI NUMBER ONE THOUSAND;No;0;ON;;;;1000;N;;;;;
+11066;BRAHMI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11067;BRAHMI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11068;BRAHMI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11069;BRAHMI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1106A;BRAHMI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1106B;BRAHMI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1106C;BRAHMI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1106D;BRAHMI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1106E;BRAHMI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1106F;BRAHMI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1107F;BRAHMI NUMBER JOINER;Mn;9;NSM;;;;;N;;;;;
+11080;KAITHI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11081;KAITHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11082;KAITHI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11083;KAITHI LETTER A;Lo;0;L;;;;;N;;;;;
+11084;KAITHI LETTER AA;Lo;0;L;;;;;N;;;;;
+11085;KAITHI LETTER I;Lo;0;L;;;;;N;;;;;
+11086;KAITHI LETTER II;Lo;0;L;;;;;N;;;;;
+11087;KAITHI LETTER U;Lo;0;L;;;;;N;;;;;
+11088;KAITHI LETTER UU;Lo;0;L;;;;;N;;;;;
+11089;KAITHI LETTER E;Lo;0;L;;;;;N;;;;;
+1108A;KAITHI LETTER AI;Lo;0;L;;;;;N;;;;;
+1108B;KAITHI LETTER O;Lo;0;L;;;;;N;;;;;
+1108C;KAITHI LETTER AU;Lo;0;L;;;;;N;;;;;
+1108D;KAITHI LETTER KA;Lo;0;L;;;;;N;;;;;
+1108E;KAITHI LETTER KHA;Lo;0;L;;;;;N;;;;;
+1108F;KAITHI LETTER GA;Lo;0;L;;;;;N;;;;;
+11090;KAITHI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11091;KAITHI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11092;KAITHI LETTER CA;Lo;0;L;;;;;N;;;;;
+11093;KAITHI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11094;KAITHI LETTER JA;Lo;0;L;;;;;N;;;;;
+11095;KAITHI LETTER JHA;Lo;0;L;;;;;N;;;;;
+11096;KAITHI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11097;KAITHI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11098;KAITHI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11099;KAITHI LETTER DDA;Lo;0;L;;;;;N;;;;;
+1109A;KAITHI LETTER DDDHA;Lo;0;L;11099 110BA;;;;N;;;;;
+1109B;KAITHI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1109C;KAITHI LETTER RHA;Lo;0;L;1109B 110BA;;;;N;;;;;
+1109D;KAITHI LETTER NNA;Lo;0;L;;;;;N;;;;;
+1109E;KAITHI LETTER TA;Lo;0;L;;;;;N;;;;;
+1109F;KAITHI LETTER THA;Lo;0;L;;;;;N;;;;;
+110A0;KAITHI LETTER DA;Lo;0;L;;;;;N;;;;;
+110A1;KAITHI LETTER DHA;Lo;0;L;;;;;N;;;;;
+110A2;KAITHI LETTER NA;Lo;0;L;;;;;N;;;;;
+110A3;KAITHI LETTER PA;Lo;0;L;;;;;N;;;;;
+110A4;KAITHI LETTER PHA;Lo;0;L;;;;;N;;;;;
+110A5;KAITHI LETTER BA;Lo;0;L;;;;;N;;;;;
+110A6;KAITHI LETTER BHA;Lo;0;L;;;;;N;;;;;
+110A7;KAITHI LETTER MA;Lo;0;L;;;;;N;;;;;
+110A8;KAITHI LETTER YA;Lo;0;L;;;;;N;;;;;
+110A9;KAITHI LETTER RA;Lo;0;L;;;;;N;;;;;
+110AA;KAITHI LETTER LA;Lo;0;L;;;;;N;;;;;
+110AB;KAITHI LETTER VA;Lo;0;L;110A5 110BA;;;;N;;;;;
+110AC;KAITHI LETTER SHA;Lo;0;L;;;;;N;;;;;
+110AD;KAITHI LETTER SSA;Lo;0;L;;;;;N;;;;;
+110AE;KAITHI LETTER SA;Lo;0;L;;;;;N;;;;;
+110AF;KAITHI LETTER HA;Lo;0;L;;;;;N;;;;;
+110B0;KAITHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+110B1;KAITHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+110B2;KAITHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+110B3;KAITHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+110B4;KAITHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+110B5;KAITHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+110B6;KAITHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+110B7;KAITHI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+110B8;KAITHI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+110B9;KAITHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+110BA;KAITHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+110BB;KAITHI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+110BC;KAITHI ENUMERATION SIGN;Po;0;L;;;;;N;;;;;
+110BD;KAITHI NUMBER SIGN;Cf;0;L;;;;;N;;;;;
+110BE;KAITHI SECTION MARK;Po;0;L;;;;;N;;;;;
+110BF;KAITHI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;
+110C0;KAITHI DANDA;Po;0;L;;;;;N;;;;;
+110C1;KAITHI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+110D0;SORA SOMPENG LETTER SAH;Lo;0;L;;;;;N;;;;;
+110D1;SORA SOMPENG LETTER TAH;Lo;0;L;;;;;N;;;;;
+110D2;SORA SOMPENG LETTER BAH;Lo;0;L;;;;;N;;;;;
+110D3;SORA SOMPENG LETTER CAH;Lo;0;L;;;;;N;;;;;
+110D4;SORA SOMPENG LETTER DAH;Lo;0;L;;;;;N;;;;;
+110D5;SORA SOMPENG LETTER GAH;Lo;0;L;;;;;N;;;;;
+110D6;SORA SOMPENG LETTER MAH;Lo;0;L;;;;;N;;;;;
+110D7;SORA SOMPENG LETTER NGAH;Lo;0;L;;;;;N;;;;;
+110D8;SORA SOMPENG LETTER LAH;Lo;0;L;;;;;N;;;;;
+110D9;SORA SOMPENG LETTER NAH;Lo;0;L;;;;;N;;;;;
+110DA;SORA SOMPENG LETTER VAH;Lo;0;L;;;;;N;;;;;
+110DB;SORA SOMPENG LETTER PAH;Lo;0;L;;;;;N;;;;;
+110DC;SORA SOMPENG LETTER YAH;Lo;0;L;;;;;N;;;;;
+110DD;SORA SOMPENG LETTER RAH;Lo;0;L;;;;;N;;;;;
+110DE;SORA SOMPENG LETTER HAH;Lo;0;L;;;;;N;;;;;
+110DF;SORA SOMPENG LETTER KAH;Lo;0;L;;;;;N;;;;;
+110E0;SORA SOMPENG LETTER JAH;Lo;0;L;;;;;N;;;;;
+110E1;SORA SOMPENG LETTER NYAH;Lo;0;L;;;;;N;;;;;
+110E2;SORA SOMPENG LETTER AH;Lo;0;L;;;;;N;;;;;
+110E3;SORA SOMPENG LETTER EEH;Lo;0;L;;;;;N;;;;;
+110E4;SORA SOMPENG LETTER IH;Lo;0;L;;;;;N;;;;;
+110E5;SORA SOMPENG LETTER UH;Lo;0;L;;;;;N;;;;;
+110E6;SORA SOMPENG LETTER OH;Lo;0;L;;;;;N;;;;;
+110E7;SORA SOMPENG LETTER EH;Lo;0;L;;;;;N;;;;;
+110E8;SORA SOMPENG LETTER MAE;Lo;0;L;;;;;N;;;;;
+110F0;SORA SOMPENG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+110F1;SORA SOMPENG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+110F2;SORA SOMPENG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+110F3;SORA SOMPENG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+110F4;SORA SOMPENG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+110F5;SORA SOMPENG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+110F6;SORA SOMPENG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+110F7;SORA SOMPENG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+110F8;SORA SOMPENG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+110F9;SORA SOMPENG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11100;CHAKMA SIGN CANDRABINDU;Mn;230;NSM;;;;;N;;;;;
+11101;CHAKMA SIGN ANUSVARA;Mn;230;NSM;;;;;N;;;;;
+11102;CHAKMA SIGN VISARGA;Mn;230;NSM;;;;;N;;;;;
+11103;CHAKMA LETTER AA;Lo;0;L;;;;;N;;;;;
+11104;CHAKMA LETTER I;Lo;0;L;;;;;N;;;;;
+11105;CHAKMA LETTER U;Lo;0;L;;;;;N;;;;;
+11106;CHAKMA LETTER E;Lo;0;L;;;;;N;;;;;
+11107;CHAKMA LETTER KAA;Lo;0;L;;;;;N;;;;;
+11108;CHAKMA LETTER KHAA;Lo;0;L;;;;;N;;;;;
+11109;CHAKMA LETTER GAA;Lo;0;L;;;;;N;;;;;
+1110A;CHAKMA LETTER GHAA;Lo;0;L;;;;;N;;;;;
+1110B;CHAKMA LETTER NGAA;Lo;0;L;;;;;N;;;;;
+1110C;CHAKMA LETTER CAA;Lo;0;L;;;;;N;;;;;
+1110D;CHAKMA LETTER CHAA;Lo;0;L;;;;;N;;;;;
+1110E;CHAKMA LETTER JAA;Lo;0;L;;;;;N;;;;;
+1110F;CHAKMA LETTER JHAA;Lo;0;L;;;;;N;;;;;
+11110;CHAKMA LETTER NYAA;Lo;0;L;;;;;N;;;;;
+11111;CHAKMA LETTER TTAA;Lo;0;L;;;;;N;;;;;
+11112;CHAKMA LETTER TTHAA;Lo;0;L;;;;;N;;;;;
+11113;CHAKMA LETTER DDAA;Lo;0;L;;;;;N;;;;;
+11114;CHAKMA LETTER DDHAA;Lo;0;L;;;;;N;;;;;
+11115;CHAKMA LETTER NNAA;Lo;0;L;;;;;N;;;;;
+11116;CHAKMA LETTER TAA;Lo;0;L;;;;;N;;;;;
+11117;CHAKMA LETTER THAA;Lo;0;L;;;;;N;;;;;
+11118;CHAKMA LETTER DAA;Lo;0;L;;;;;N;;;;;
+11119;CHAKMA LETTER DHAA;Lo;0;L;;;;;N;;;;;
+1111A;CHAKMA LETTER NAA;Lo;0;L;;;;;N;;;;;
+1111B;CHAKMA LETTER PAA;Lo;0;L;;;;;N;;;;;
+1111C;CHAKMA LETTER PHAA;Lo;0;L;;;;;N;;;;;
+1111D;CHAKMA LETTER BAA;Lo;0;L;;;;;N;;;;;
+1111E;CHAKMA LETTER BHAA;Lo;0;L;;;;;N;;;;;
+1111F;CHAKMA LETTER MAA;Lo;0;L;;;;;N;;;;;
+11120;CHAKMA LETTER YYAA;Lo;0;L;;;;;N;;;;;
+11121;CHAKMA LETTER YAA;Lo;0;L;;;;;N;;;;;
+11122;CHAKMA LETTER RAA;Lo;0;L;;;;;N;;;;;
+11123;CHAKMA LETTER LAA;Lo;0;L;;;;;N;;;;;
+11124;CHAKMA LETTER WAA;Lo;0;L;;;;;N;;;;;
+11125;CHAKMA LETTER SAA;Lo;0;L;;;;;N;;;;;
+11126;CHAKMA LETTER HAA;Lo;0;L;;;;;N;;;;;
+11127;CHAKMA VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;;
+11128;CHAKMA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11129;CHAKMA VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+1112A;CHAKMA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+1112B;CHAKMA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1112C;CHAKMA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+1112D;CHAKMA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+1112E;CHAKMA VOWEL SIGN O;Mn;0;NSM;11131 11127;;;;N;;;;;
+1112F;CHAKMA VOWEL SIGN AU;Mn;0;NSM;11132 11127;;;;N;;;;;
+11130;CHAKMA VOWEL SIGN OI;Mn;0;NSM;;;;;N;;;;;
+11131;CHAKMA O MARK;Mn;0;NSM;;;;;N;;;;;
+11132;CHAKMA AU MARK;Mn;0;NSM;;;;;N;;;;;
+11133;CHAKMA VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11134;CHAKMA MAAYYAA;Mn;9;NSM;;;;;N;;;;;
+11136;CHAKMA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11137;CHAKMA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11138;CHAKMA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11139;CHAKMA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1113A;CHAKMA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1113B;CHAKMA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1113C;CHAKMA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1113D;CHAKMA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1113E;CHAKMA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1113F;CHAKMA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11140;CHAKMA SECTION MARK;Po;0;L;;;;;N;;;;;
+11141;CHAKMA DANDA;Po;0;L;;;;;N;;;;;
+11142;CHAKMA DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+11143;CHAKMA QUESTION MARK;Po;0;L;;;;;N;;;;;
+11150;MAHAJANI LETTER A;Lo;0;L;;;;;N;;;;;
+11151;MAHAJANI LETTER I;Lo;0;L;;;;;N;;;;;
+11152;MAHAJANI LETTER U;Lo;0;L;;;;;N;;;;;
+11153;MAHAJANI LETTER E;Lo;0;L;;;;;N;;;;;
+11154;MAHAJANI LETTER O;Lo;0;L;;;;;N;;;;;
+11155;MAHAJANI LETTER KA;Lo;0;L;;;;;N;;;;;
+11156;MAHAJANI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11157;MAHAJANI LETTER GA;Lo;0;L;;;;;N;;;;;
+11158;MAHAJANI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11159;MAHAJANI LETTER CA;Lo;0;L;;;;;N;;;;;
+1115A;MAHAJANI LETTER CHA;Lo;0;L;;;;;N;;;;;
+1115B;MAHAJANI LETTER JA;Lo;0;L;;;;;N;;;;;
+1115C;MAHAJANI LETTER JHA;Lo;0;L;;;;;N;;;;;
+1115D;MAHAJANI LETTER NYA;Lo;0;L;;;;;N;;;;;
+1115E;MAHAJANI LETTER TTA;Lo;0;L;;;;;N;;;;;
+1115F;MAHAJANI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11160;MAHAJANI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11161;MAHAJANI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11162;MAHAJANI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11163;MAHAJANI LETTER TA;Lo;0;L;;;;;N;;;;;
+11164;MAHAJANI LETTER THA;Lo;0;L;;;;;N;;;;;
+11165;MAHAJANI LETTER DA;Lo;0;L;;;;;N;;;;;
+11166;MAHAJANI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11167;MAHAJANI LETTER NA;Lo;0;L;;;;;N;;;;;
+11168;MAHAJANI LETTER PA;Lo;0;L;;;;;N;;;;;
+11169;MAHAJANI LETTER PHA;Lo;0;L;;;;;N;;;;;
+1116A;MAHAJANI LETTER BA;Lo;0;L;;;;;N;;;;;
+1116B;MAHAJANI LETTER BHA;Lo;0;L;;;;;N;;;;;
+1116C;MAHAJANI LETTER MA;Lo;0;L;;;;;N;;;;;
+1116D;MAHAJANI LETTER RA;Lo;0;L;;;;;N;;;;;
+1116E;MAHAJANI LETTER LA;Lo;0;L;;;;;N;;;;;
+1116F;MAHAJANI LETTER VA;Lo;0;L;;;;;N;;;;;
+11170;MAHAJANI LETTER SA;Lo;0;L;;;;;N;;;;;
+11171;MAHAJANI LETTER HA;Lo;0;L;;;;;N;;;;;
+11172;MAHAJANI LETTER RRA;Lo;0;L;;;;;N;;;;;
+11173;MAHAJANI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+11174;MAHAJANI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+11175;MAHAJANI SECTION MARK;Po;0;L;;;;;N;;;;;
+11176;MAHAJANI LIGATURE SHRI;Lo;0;L;;;;;N;;;;;
+11180;SHARADA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11181;SHARADA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11182;SHARADA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11183;SHARADA LETTER A;Lo;0;L;;;;;N;;;;;
+11184;SHARADA LETTER AA;Lo;0;L;;;;;N;;;;;
+11185;SHARADA LETTER I;Lo;0;L;;;;;N;;;;;
+11186;SHARADA LETTER II;Lo;0;L;;;;;N;;;;;
+11187;SHARADA LETTER U;Lo;0;L;;;;;N;;;;;
+11188;SHARADA LETTER UU;Lo;0;L;;;;;N;;;;;
+11189;SHARADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+1118A;SHARADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+1118B;SHARADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1118C;SHARADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1118D;SHARADA LETTER E;Lo;0;L;;;;;N;;;;;
+1118E;SHARADA LETTER AI;Lo;0;L;;;;;N;;;;;
+1118F;SHARADA LETTER O;Lo;0;L;;;;;N;;;;;
+11190;SHARADA LETTER AU;Lo;0;L;;;;;N;;;;;
+11191;SHARADA LETTER KA;Lo;0;L;;;;;N;;;;;
+11192;SHARADA LETTER KHA;Lo;0;L;;;;;N;;;;;
+11193;SHARADA LETTER GA;Lo;0;L;;;;;N;;;;;
+11194;SHARADA LETTER GHA;Lo;0;L;;;;;N;;;;;
+11195;SHARADA LETTER NGA;Lo;0;L;;;;;N;;;;;
+11196;SHARADA LETTER CA;Lo;0;L;;;;;N;;;;;
+11197;SHARADA LETTER CHA;Lo;0;L;;;;;N;;;;;
+11198;SHARADA LETTER JA;Lo;0;L;;;;;N;;;;;
+11199;SHARADA LETTER JHA;Lo;0;L;;;;;N;;;;;
+1119A;SHARADA LETTER NYA;Lo;0;L;;;;;N;;;;;
+1119B;SHARADA LETTER TTA;Lo;0;L;;;;;N;;;;;
+1119C;SHARADA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1119D;SHARADA LETTER DDA;Lo;0;L;;;;;N;;;;;
+1119E;SHARADA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1119F;SHARADA LETTER NNA;Lo;0;L;;;;;N;;;;;
+111A0;SHARADA LETTER TA;Lo;0;L;;;;;N;;;;;
+111A1;SHARADA LETTER THA;Lo;0;L;;;;;N;;;;;
+111A2;SHARADA LETTER DA;Lo;0;L;;;;;N;;;;;
+111A3;SHARADA LETTER DHA;Lo;0;L;;;;;N;;;;;
+111A4;SHARADA LETTER NA;Lo;0;L;;;;;N;;;;;
+111A5;SHARADA LETTER PA;Lo;0;L;;;;;N;;;;;
+111A6;SHARADA LETTER PHA;Lo;0;L;;;;;N;;;;;
+111A7;SHARADA LETTER BA;Lo;0;L;;;;;N;;;;;
+111A8;SHARADA LETTER BHA;Lo;0;L;;;;;N;;;;;
+111A9;SHARADA LETTER MA;Lo;0;L;;;;;N;;;;;
+111AA;SHARADA LETTER YA;Lo;0;L;;;;;N;;;;;
+111AB;SHARADA LETTER RA;Lo;0;L;;;;;N;;;;;
+111AC;SHARADA LETTER LA;Lo;0;L;;;;;N;;;;;
+111AD;SHARADA LETTER LLA;Lo;0;L;;;;;N;;;;;
+111AE;SHARADA LETTER VA;Lo;0;L;;;;;N;;;;;
+111AF;SHARADA LETTER SHA;Lo;0;L;;;;;N;;;;;
+111B0;SHARADA LETTER SSA;Lo;0;L;;;;;N;;;;;
+111B1;SHARADA LETTER SA;Lo;0;L;;;;;N;;;;;
+111B2;SHARADA LETTER HA;Lo;0;L;;;;;N;;;;;
+111B3;SHARADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+111B4;SHARADA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+111B5;SHARADA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+111B6;SHARADA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+111B7;SHARADA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+111B8;SHARADA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+111B9;SHARADA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+111BA;SHARADA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+111BB;SHARADA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+111BC;SHARADA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+111BD;SHARADA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+111BE;SHARADA VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+111BF;SHARADA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+111C0;SHARADA SIGN VIRAMA;Mc;9;L;;;;;N;;;;;
+111C1;SHARADA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+111C2;SHARADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+111C3;SHARADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+111C4;SHARADA OM;Lo;0;L;;;;;N;;;;;
+111C5;SHARADA DANDA;Po;0;L;;;;;N;;;;;
+111C6;SHARADA DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+111C7;SHARADA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+111C8;SHARADA SEPARATOR;Po;0;L;;;;;N;;;;;
+111C9;SHARADA SANDHI MARK;Po;0;L;;;;;N;;;;;
+111CA;SHARADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+111CB;SHARADA VOWEL MODIFIER MARK;Mn;0;NSM;;;;;N;;;;;
+111CC;SHARADA EXTRA SHORT VOWEL MARK;Mn;0;NSM;;;;;N;;;;;
+111CD;SHARADA SUTRA MARK;Po;0;L;;;;;N;;;;;
+111D0;SHARADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+111D1;SHARADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+111D2;SHARADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+111D3;SHARADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+111D4;SHARADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+111D5;SHARADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+111D6;SHARADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+111D7;SHARADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+111D8;SHARADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+111D9;SHARADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+111DA;SHARADA EKAM;Lo;0;L;;;;;N;;;;;
+111DB;SHARADA SIGN SIDDHAM;Po;0;L;;;;;N;;;;;
+111DC;SHARADA HEADSTROKE;Lo;0;L;;;;;N;;;;;
+111DD;SHARADA CONTINUATION SIGN;Po;0;L;;;;;N;;;;;
+111DE;SHARADA SECTION MARK-1;Po;0;L;;;;;N;;;;;
+111DF;SHARADA SECTION MARK-2;Po;0;L;;;;;N;;;;;
+111E1;SINHALA ARCHAIC DIGIT ONE;No;0;L;;;;1;N;;;;;
+111E2;SINHALA ARCHAIC DIGIT TWO;No;0;L;;;;2;N;;;;;
+111E3;SINHALA ARCHAIC DIGIT THREE;No;0;L;;;;3;N;;;;;
+111E4;SINHALA ARCHAIC DIGIT FOUR;No;0;L;;;;4;N;;;;;
+111E5;SINHALA ARCHAIC DIGIT FIVE;No;0;L;;;;5;N;;;;;
+111E6;SINHALA ARCHAIC DIGIT SIX;No;0;L;;;;6;N;;;;;
+111E7;SINHALA ARCHAIC DIGIT SEVEN;No;0;L;;;;7;N;;;;;
+111E8;SINHALA ARCHAIC DIGIT EIGHT;No;0;L;;;;8;N;;;;;
+111E9;SINHALA ARCHAIC DIGIT NINE;No;0;L;;;;9;N;;;;;
+111EA;SINHALA ARCHAIC NUMBER TEN;No;0;L;;;;10;N;;;;;
+111EB;SINHALA ARCHAIC NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+111EC;SINHALA ARCHAIC NUMBER THIRTY;No;0;L;;;;30;N;;;;;
+111ED;SINHALA ARCHAIC NUMBER FORTY;No;0;L;;;;40;N;;;;;
+111EE;SINHALA ARCHAIC NUMBER FIFTY;No;0;L;;;;50;N;;;;;
+111EF;SINHALA ARCHAIC NUMBER SIXTY;No;0;L;;;;60;N;;;;;
+111F0;SINHALA ARCHAIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
+111F1;SINHALA ARCHAIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
+111F2;SINHALA ARCHAIC NUMBER NINETY;No;0;L;;;;90;N;;;;;
+111F3;SINHALA ARCHAIC NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
+111F4;SINHALA ARCHAIC NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
+11200;KHOJKI LETTER A;Lo;0;L;;;;;N;;;;;
+11201;KHOJKI LETTER AA;Lo;0;L;;;;;N;;;;;
+11202;KHOJKI LETTER I;Lo;0;L;;;;;N;;;;;
+11203;KHOJKI LETTER U;Lo;0;L;;;;;N;;;;;
+11204;KHOJKI LETTER E;Lo;0;L;;;;;N;;;;;
+11205;KHOJKI LETTER AI;Lo;0;L;;;;;N;;;;;
+11206;KHOJKI LETTER O;Lo;0;L;;;;;N;;;;;
+11207;KHOJKI LETTER AU;Lo;0;L;;;;;N;;;;;
+11208;KHOJKI LETTER KA;Lo;0;L;;;;;N;;;;;
+11209;KHOJKI LETTER KHA;Lo;0;L;;;;;N;;;;;
+1120A;KHOJKI LETTER GA;Lo;0;L;;;;;N;;;;;
+1120B;KHOJKI LETTER GGA;Lo;0;L;;;;;N;;;;;
+1120C;KHOJKI LETTER GHA;Lo;0;L;;;;;N;;;;;
+1120D;KHOJKI LETTER NGA;Lo;0;L;;;;;N;;;;;
+1120E;KHOJKI LETTER CA;Lo;0;L;;;;;N;;;;;
+1120F;KHOJKI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11210;KHOJKI LETTER JA;Lo;0;L;;;;;N;;;;;
+11211;KHOJKI LETTER JJA;Lo;0;L;;;;;N;;;;;
+11213;KHOJKI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11214;KHOJKI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11215;KHOJKI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11216;KHOJKI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11217;KHOJKI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11218;KHOJKI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11219;KHOJKI LETTER TA;Lo;0;L;;;;;N;;;;;
+1121A;KHOJKI LETTER THA;Lo;0;L;;;;;N;;;;;
+1121B;KHOJKI LETTER DA;Lo;0;L;;;;;N;;;;;
+1121C;KHOJKI LETTER DDDA;Lo;0;L;;;;;N;;;;;
+1121D;KHOJKI LETTER DHA;Lo;0;L;;;;;N;;;;;
+1121E;KHOJKI LETTER NA;Lo;0;L;;;;;N;;;;;
+1121F;KHOJKI LETTER PA;Lo;0;L;;;;;N;;;;;
+11220;KHOJKI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11221;KHOJKI LETTER BA;Lo;0;L;;;;;N;;;;;
+11222;KHOJKI LETTER BBA;Lo;0;L;;;;;N;;;;;
+11223;KHOJKI LETTER BHA;Lo;0;L;;;;;N;;;;;
+11224;KHOJKI LETTER MA;Lo;0;L;;;;;N;;;;;
+11225;KHOJKI LETTER YA;Lo;0;L;;;;;N;;;;;
+11226;KHOJKI LETTER RA;Lo;0;L;;;;;N;;;;;
+11227;KHOJKI LETTER LA;Lo;0;L;;;;;N;;;;;
+11228;KHOJKI LETTER VA;Lo;0;L;;;;;N;;;;;
+11229;KHOJKI LETTER SA;Lo;0;L;;;;;N;;;;;
+1122A;KHOJKI LETTER HA;Lo;0;L;;;;;N;;;;;
+1122B;KHOJKI LETTER LLA;Lo;0;L;;;;;N;;;;;
+1122C;KHOJKI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+1122D;KHOJKI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+1122E;KHOJKI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+1122F;KHOJKI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11230;KHOJKI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11231;KHOJKI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+11232;KHOJKI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+11233;KHOJKI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+11234;KHOJKI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11235;KHOJKI SIGN VIRAMA;Mc;9;L;;;;;N;;;;;
+11236;KHOJKI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+11237;KHOJKI SIGN SHADDA;Mn;0;NSM;;;;;N;;;;;
+11238;KHOJKI DANDA;Po;0;L;;;;;N;;;;;
+11239;KHOJKI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+1123A;KHOJKI WORD SEPARATOR;Po;0;L;;;;;N;;;;;
+1123B;KHOJKI SECTION MARK;Po;0;L;;;;;N;;;;;
+1123C;KHOJKI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;
+1123D;KHOJKI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+1123E;KHOJKI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;;
+11280;MULTANI LETTER A;Lo;0;L;;;;;N;;;;;
+11281;MULTANI LETTER I;Lo;0;L;;;;;N;;;;;
+11282;MULTANI LETTER U;Lo;0;L;;;;;N;;;;;
+11283;MULTANI LETTER E;Lo;0;L;;;;;N;;;;;
+11284;MULTANI LETTER KA;Lo;0;L;;;;;N;;;;;
+11285;MULTANI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11286;MULTANI LETTER GA;Lo;0;L;;;;;N;;;;;
+11288;MULTANI LETTER GHA;Lo;0;L;;;;;N;;;;;
+1128A;MULTANI LETTER CA;Lo;0;L;;;;;N;;;;;
+1128B;MULTANI LETTER CHA;Lo;0;L;;;;;N;;;;;
+1128C;MULTANI LETTER JA;Lo;0;L;;;;;N;;;;;
+1128D;MULTANI LETTER JJA;Lo;0;L;;;;;N;;;;;
+1128F;MULTANI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11290;MULTANI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11291;MULTANI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11292;MULTANI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11293;MULTANI LETTER DDDA;Lo;0;L;;;;;N;;;;;
+11294;MULTANI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11295;MULTANI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11296;MULTANI LETTER TA;Lo;0;L;;;;;N;;;;;
+11297;MULTANI LETTER THA;Lo;0;L;;;;;N;;;;;
+11298;MULTANI LETTER DA;Lo;0;L;;;;;N;;;;;
+11299;MULTANI LETTER DHA;Lo;0;L;;;;;N;;;;;
+1129A;MULTANI LETTER NA;Lo;0;L;;;;;N;;;;;
+1129B;MULTANI LETTER PA;Lo;0;L;;;;;N;;;;;
+1129C;MULTANI LETTER PHA;Lo;0;L;;;;;N;;;;;
+1129D;MULTANI LETTER BA;Lo;0;L;;;;;N;;;;;
+1129F;MULTANI LETTER BHA;Lo;0;L;;;;;N;;;;;
+112A0;MULTANI LETTER MA;Lo;0;L;;;;;N;;;;;
+112A1;MULTANI LETTER YA;Lo;0;L;;;;;N;;;;;
+112A2;MULTANI LETTER RA;Lo;0;L;;;;;N;;;;;
+112A3;MULTANI LETTER LA;Lo;0;L;;;;;N;;;;;
+112A4;MULTANI LETTER VA;Lo;0;L;;;;;N;;;;;
+112A5;MULTANI LETTER SA;Lo;0;L;;;;;N;;;;;
+112A6;MULTANI LETTER HA;Lo;0;L;;;;;N;;;;;
+112A7;MULTANI LETTER RRA;Lo;0;L;;;;;N;;;;;
+112A8;MULTANI LETTER RHA;Lo;0;L;;;;;N;;;;;
+112A9;MULTANI SECTION MARK;Po;0;L;;;;;N;;;;;
+112B0;KHUDAWADI LETTER A;Lo;0;L;;;;;N;;;;;
+112B1;KHUDAWADI LETTER AA;Lo;0;L;;;;;N;;;;;
+112B2;KHUDAWADI LETTER I;Lo;0;L;;;;;N;;;;;
+112B3;KHUDAWADI LETTER II;Lo;0;L;;;;;N;;;;;
+112B4;KHUDAWADI LETTER U;Lo;0;L;;;;;N;;;;;
+112B5;KHUDAWADI LETTER UU;Lo;0;L;;;;;N;;;;;
+112B6;KHUDAWADI LETTER E;Lo;0;L;;;;;N;;;;;
+112B7;KHUDAWADI LETTER AI;Lo;0;L;;;;;N;;;;;
+112B8;KHUDAWADI LETTER O;Lo;0;L;;;;;N;;;;;
+112B9;KHUDAWADI LETTER AU;Lo;0;L;;;;;N;;;;;
+112BA;KHUDAWADI LETTER KA;Lo;0;L;;;;;N;;;;;
+112BB;KHUDAWADI LETTER KHA;Lo;0;L;;;;;N;;;;;
+112BC;KHUDAWADI LETTER GA;Lo;0;L;;;;;N;;;;;
+112BD;KHUDAWADI LETTER GGA;Lo;0;L;;;;;N;;;;;
+112BE;KHUDAWADI LETTER GHA;Lo;0;L;;;;;N;;;;;
+112BF;KHUDAWADI LETTER NGA;Lo;0;L;;;;;N;;;;;
+112C0;KHUDAWADI LETTER CA;Lo;0;L;;;;;N;;;;;
+112C1;KHUDAWADI LETTER CHA;Lo;0;L;;;;;N;;;;;
+112C2;KHUDAWADI LETTER JA;Lo;0;L;;;;;N;;;;;
+112C3;KHUDAWADI LETTER JJA;Lo;0;L;;;;;N;;;;;
+112C4;KHUDAWADI LETTER JHA;Lo;0;L;;;;;N;;;;;
+112C5;KHUDAWADI LETTER NYA;Lo;0;L;;;;;N;;;;;
+112C6;KHUDAWADI LETTER TTA;Lo;0;L;;;;;N;;;;;
+112C7;KHUDAWADI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+112C8;KHUDAWADI LETTER DDA;Lo;0;L;;;;;N;;;;;
+112C9;KHUDAWADI LETTER DDDA;Lo;0;L;;;;;N;;;;;
+112CA;KHUDAWADI LETTER RRA;Lo;0;L;;;;;N;;;;;
+112CB;KHUDAWADI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+112CC;KHUDAWADI LETTER NNA;Lo;0;L;;;;;N;;;;;
+112CD;KHUDAWADI LETTER TA;Lo;0;L;;;;;N;;;;;
+112CE;KHUDAWADI LETTER THA;Lo;0;L;;;;;N;;;;;
+112CF;KHUDAWADI LETTER DA;Lo;0;L;;;;;N;;;;;
+112D0;KHUDAWADI LETTER DHA;Lo;0;L;;;;;N;;;;;
+112D1;KHUDAWADI LETTER NA;Lo;0;L;;;;;N;;;;;
+112D2;KHUDAWADI LETTER PA;Lo;0;L;;;;;N;;;;;
+112D3;KHUDAWADI LETTER PHA;Lo;0;L;;;;;N;;;;;
+112D4;KHUDAWADI LETTER BA;Lo;0;L;;;;;N;;;;;
+112D5;KHUDAWADI LETTER BBA;Lo;0;L;;;;;N;;;;;
+112D6;KHUDAWADI LETTER BHA;Lo;0;L;;;;;N;;;;;
+112D7;KHUDAWADI LETTER MA;Lo;0;L;;;;;N;;;;;
+112D8;KHUDAWADI LETTER YA;Lo;0;L;;;;;N;;;;;
+112D9;KHUDAWADI LETTER RA;Lo;0;L;;;;;N;;;;;
+112DA;KHUDAWADI LETTER LA;Lo;0;L;;;;;N;;;;;
+112DB;KHUDAWADI LETTER VA;Lo;0;L;;;;;N;;;;;
+112DC;KHUDAWADI LETTER SHA;Lo;0;L;;;;;N;;;;;
+112DD;KHUDAWADI LETTER SA;Lo;0;L;;;;;N;;;;;
+112DE;KHUDAWADI LETTER HA;Lo;0;L;;;;;N;;;;;
+112DF;KHUDAWADI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+112E0;KHUDAWADI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+112E1;KHUDAWADI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+112E2;KHUDAWADI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+112E3;KHUDAWADI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+112E4;KHUDAWADI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+112E5;KHUDAWADI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+112E6;KHUDAWADI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+112E7;KHUDAWADI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+112E8;KHUDAWADI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+112E9;KHUDAWADI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+112EA;KHUDAWADI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+112F0;KHUDAWADI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+112F1;KHUDAWADI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+112F2;KHUDAWADI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+112F3;KHUDAWADI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+112F4;KHUDAWADI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+112F5;KHUDAWADI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+112F6;KHUDAWADI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+112F7;KHUDAWADI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+112F8;KHUDAWADI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+112F9;KHUDAWADI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11300;GRANTHA SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;;
+11301;GRANTHA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11302;GRANTHA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+11303;GRANTHA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11305;GRANTHA LETTER A;Lo;0;L;;;;;N;;;;;
+11306;GRANTHA LETTER AA;Lo;0;L;;;;;N;;;;;
+11307;GRANTHA LETTER I;Lo;0;L;;;;;N;;;;;
+11308;GRANTHA LETTER II;Lo;0;L;;;;;N;;;;;
+11309;GRANTHA LETTER U;Lo;0;L;;;;;N;;;;;
+1130A;GRANTHA LETTER UU;Lo;0;L;;;;;N;;;;;
+1130B;GRANTHA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+1130C;GRANTHA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1130F;GRANTHA LETTER EE;Lo;0;L;;;;;N;;;;;
+11310;GRANTHA LETTER AI;Lo;0;L;;;;;N;;;;;
+11313;GRANTHA LETTER OO;Lo;0;L;;;;;N;;;;;
+11314;GRANTHA LETTER AU;Lo;0;L;;;;;N;;;;;
+11315;GRANTHA LETTER KA;Lo;0;L;;;;;N;;;;;
+11316;GRANTHA LETTER KHA;Lo;0;L;;;;;N;;;;;
+11317;GRANTHA LETTER GA;Lo;0;L;;;;;N;;;;;
+11318;GRANTHA LETTER GHA;Lo;0;L;;;;;N;;;;;
+11319;GRANTHA LETTER NGA;Lo;0;L;;;;;N;;;;;
+1131A;GRANTHA LETTER CA;Lo;0;L;;;;;N;;;;;
+1131B;GRANTHA LETTER CHA;Lo;0;L;;;;;N;;;;;
+1131C;GRANTHA LETTER JA;Lo;0;L;;;;;N;;;;;
+1131D;GRANTHA LETTER JHA;Lo;0;L;;;;;N;;;;;
+1131E;GRANTHA LETTER NYA;Lo;0;L;;;;;N;;;;;
+1131F;GRANTHA LETTER TTA;Lo;0;L;;;;;N;;;;;
+11320;GRANTHA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11321;GRANTHA LETTER DDA;Lo;0;L;;;;;N;;;;;
+11322;GRANTHA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11323;GRANTHA LETTER NNA;Lo;0;L;;;;;N;;;;;
+11324;GRANTHA LETTER TA;Lo;0;L;;;;;N;;;;;
+11325;GRANTHA LETTER THA;Lo;0;L;;;;;N;;;;;
+11326;GRANTHA LETTER DA;Lo;0;L;;;;;N;;;;;
+11327;GRANTHA LETTER DHA;Lo;0;L;;;;;N;;;;;
+11328;GRANTHA LETTER NA;Lo;0;L;;;;;N;;;;;
+1132A;GRANTHA LETTER PA;Lo;0;L;;;;;N;;;;;
+1132B;GRANTHA LETTER PHA;Lo;0;L;;;;;N;;;;;
+1132C;GRANTHA LETTER BA;Lo;0;L;;;;;N;;;;;
+1132D;GRANTHA LETTER BHA;Lo;0;L;;;;;N;;;;;
+1132E;GRANTHA LETTER MA;Lo;0;L;;;;;N;;;;;
+1132F;GRANTHA LETTER YA;Lo;0;L;;;;;N;;;;;
+11330;GRANTHA LETTER RA;Lo;0;L;;;;;N;;;;;
+11332;GRANTHA LETTER LA;Lo;0;L;;;;;N;;;;;
+11333;GRANTHA LETTER LLA;Lo;0;L;;;;;N;;;;;
+11335;GRANTHA LETTER VA;Lo;0;L;;;;;N;;;;;
+11336;GRANTHA LETTER SHA;Lo;0;L;;;;;N;;;;;
+11337;GRANTHA LETTER SSA;Lo;0;L;;;;;N;;;;;
+11338;GRANTHA LETTER SA;Lo;0;L;;;;;N;;;;;
+11339;GRANTHA LETTER HA;Lo;0;L;;;;;N;;;;;
+1133C;GRANTHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+1133D;GRANTHA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+1133E;GRANTHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+1133F;GRANTHA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+11340;GRANTHA VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+11341;GRANTHA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+11342;GRANTHA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+11343;GRANTHA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
+11344;GRANTHA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
+11347;GRANTHA VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
+11348;GRANTHA VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+1134B;GRANTHA VOWEL SIGN OO;Mc;0;L;11347 1133E;;;;N;;;;;
+1134C;GRANTHA VOWEL SIGN AU;Mc;0;L;11347 11357;;;;N;;;;;
+1134D;GRANTHA SIGN VIRAMA;Mc;9;L;;;;;N;;;;;
+11350;GRANTHA OM;Lo;0;L;;;;;N;;;;;
+11357;GRANTHA AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
+1135D;GRANTHA SIGN PLUTA;Lo;0;L;;;;;N;;;;;
+1135E;GRANTHA LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;;
+1135F;GRANTHA LETTER VEDIC DOUBLE ANUSVARA;Lo;0;L;;;;;N;;;;;
+11360;GRANTHA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11361;GRANTHA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+11362;GRANTHA VOWEL SIGN VOCALIC L;Mc;0;L;;;;;N;;;;;
+11363;GRANTHA VOWEL SIGN VOCALIC LL;Mc;0;L;;;;;N;;;;;
+11366;COMBINING GRANTHA DIGIT ZERO;Mn;230;NSM;;;;;N;;;;;
+11367;COMBINING GRANTHA DIGIT ONE;Mn;230;NSM;;;;;N;;;;;
+11368;COMBINING GRANTHA DIGIT TWO;Mn;230;NSM;;;;;N;;;;;
+11369;COMBINING GRANTHA DIGIT THREE;Mn;230;NSM;;;;;N;;;;;
+1136A;COMBINING GRANTHA DIGIT FOUR;Mn;230;NSM;;;;;N;;;;;
+1136B;COMBINING GRANTHA DIGIT FIVE;Mn;230;NSM;;;;;N;;;;;
+1136C;COMBINING GRANTHA DIGIT SIX;Mn;230;NSM;;;;;N;;;;;
+11370;COMBINING GRANTHA LETTER A;Mn;230;NSM;;;;;N;;;;;
+11371;COMBINING GRANTHA LETTER KA;Mn;230;NSM;;;;;N;;;;;
+11372;COMBINING GRANTHA LETTER NA;Mn;230;NSM;;;;;N;;;;;
+11373;COMBINING GRANTHA LETTER VI;Mn;230;NSM;;;;;N;;;;;
+11374;COMBINING GRANTHA LETTER PA;Mn;230;NSM;;;;;N;;;;;
+11400;NEWA LETTER A;Lo;0;L;;;;;N;;;;;
+11401;NEWA LETTER AA;Lo;0;L;;;;;N;;;;;
+11402;NEWA LETTER I;Lo;0;L;;;;;N;;;;;
+11403;NEWA LETTER II;Lo;0;L;;;;;N;;;;;
+11404;NEWA LETTER U;Lo;0;L;;;;;N;;;;;
+11405;NEWA LETTER UU;Lo;0;L;;;;;N;;;;;
+11406;NEWA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+11407;NEWA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11408;NEWA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+11409;NEWA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1140A;NEWA LETTER E;Lo;0;L;;;;;N;;;;;
+1140B;NEWA LETTER AI;Lo;0;L;;;;;N;;;;;
+1140C;NEWA LETTER O;Lo;0;L;;;;;N;;;;;
+1140D;NEWA LETTER AU;Lo;0;L;;;;;N;;;;;
+1140E;NEWA LETTER KA;Lo;0;L;;;;;N;;;;;
+1140F;NEWA LETTER KHA;Lo;0;L;;;;;N;;;;;
+11410;NEWA LETTER GA;Lo;0;L;;;;;N;;;;;
+11411;NEWA LETTER GHA;Lo;0;L;;;;;N;;;;;
+11412;NEWA LETTER NGA;Lo;0;L;;;;;N;;;;;
+11413;NEWA LETTER NGHA;Lo;0;L;;;;;N;;;;;
+11414;NEWA LETTER CA;Lo;0;L;;;;;N;;;;;
+11415;NEWA LETTER CHA;Lo;0;L;;;;;N;;;;;
+11416;NEWA LETTER JA;Lo;0;L;;;;;N;;;;;
+11417;NEWA LETTER JHA;Lo;0;L;;;;;N;;;;;
+11418;NEWA LETTER NYA;Lo;0;L;;;;;N;;;;;
+11419;NEWA LETTER NYHA;Lo;0;L;;;;;N;;;;;
+1141A;NEWA LETTER TTA;Lo;0;L;;;;;N;;;;;
+1141B;NEWA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1141C;NEWA LETTER DDA;Lo;0;L;;;;;N;;;;;
+1141D;NEWA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1141E;NEWA LETTER NNA;Lo;0;L;;;;;N;;;;;
+1141F;NEWA LETTER TA;Lo;0;L;;;;;N;;;;;
+11420;NEWA LETTER THA;Lo;0;L;;;;;N;;;;;
+11421;NEWA LETTER DA;Lo;0;L;;;;;N;;;;;
+11422;NEWA LETTER DHA;Lo;0;L;;;;;N;;;;;
+11423;NEWA LETTER NA;Lo;0;L;;;;;N;;;;;
+11424;NEWA LETTER NHA;Lo;0;L;;;;;N;;;;;
+11425;NEWA LETTER PA;Lo;0;L;;;;;N;;;;;
+11426;NEWA LETTER PHA;Lo;0;L;;;;;N;;;;;
+11427;NEWA LETTER BA;Lo;0;L;;;;;N;;;;;
+11428;NEWA LETTER BHA;Lo;0;L;;;;;N;;;;;
+11429;NEWA LETTER MA;Lo;0;L;;;;;N;;;;;
+1142A;NEWA LETTER MHA;Lo;0;L;;;;;N;;;;;
+1142B;NEWA LETTER YA;Lo;0;L;;;;;N;;;;;
+1142C;NEWA LETTER RA;Lo;0;L;;;;;N;;;;;
+1142D;NEWA LETTER RHA;Lo;0;L;;;;;N;;;;;
+1142E;NEWA LETTER LA;Lo;0;L;;;;;N;;;;;
+1142F;NEWA LETTER LHA;Lo;0;L;;;;;N;;;;;
+11430;NEWA LETTER WA;Lo;0;L;;;;;N;;;;;
+11431;NEWA LETTER SHA;Lo;0;L;;;;;N;;;;;
+11432;NEWA LETTER SSA;Lo;0;L;;;;;N;;;;;
+11433;NEWA LETTER SA;Lo;0;L;;;;;N;;;;;
+11434;NEWA LETTER HA;Lo;0;L;;;;;N;;;;;
+11435;NEWA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+11436;NEWA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+11437;NEWA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+11438;NEWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11439;NEWA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+1143A;NEWA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+1143B;NEWA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+1143C;NEWA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+1143D;NEWA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+1143E;NEWA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+1143F;NEWA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+11440;NEWA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+11441;NEWA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+11442;NEWA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11443;NEWA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11444;NEWA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11445;NEWA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11446;NEWA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+11447;NEWA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+11448;NEWA SIGN FINAL ANUSVARA;Lo;0;L;;;;;N;;;;;
+11449;NEWA OM;Lo;0;L;;;;;N;;;;;
+1144A;NEWA SIDDHI;Lo;0;L;;;;;N;;;;;
+1144B;NEWA DANDA;Po;0;L;;;;;N;;;;;
+1144C;NEWA DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+1144D;NEWA COMMA;Po;0;L;;;;;N;;;;;
+1144E;NEWA GAP FILLER;Po;0;L;;;;;N;;;;;
+1144F;NEWA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+11450;NEWA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11451;NEWA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11452;NEWA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11453;NEWA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11454;NEWA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11455;NEWA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11456;NEWA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11457;NEWA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11458;NEWA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11459;NEWA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1145B;NEWA PLACEHOLDER MARK;Po;0;L;;;;;N;;;;;
+1145D;NEWA INSERTION SIGN;Po;0;L;;;;;N;;;;;
+11480;TIRHUTA ANJI;Lo;0;L;;;;;N;;;;;
+11481;TIRHUTA LETTER A;Lo;0;L;;;;;N;;;;;
+11482;TIRHUTA LETTER AA;Lo;0;L;;;;;N;;;;;
+11483;TIRHUTA LETTER I;Lo;0;L;;;;;N;;;;;
+11484;TIRHUTA LETTER II;Lo;0;L;;;;;N;;;;;
+11485;TIRHUTA LETTER U;Lo;0;L;;;;;N;;;;;
+11486;TIRHUTA LETTER UU;Lo;0;L;;;;;N;;;;;
+11487;TIRHUTA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+11488;TIRHUTA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11489;TIRHUTA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+1148A;TIRHUTA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1148B;TIRHUTA LETTER E;Lo;0;L;;;;;N;;;;;
+1148C;TIRHUTA LETTER AI;Lo;0;L;;;;;N;;;;;
+1148D;TIRHUTA LETTER O;Lo;0;L;;;;;N;;;;;
+1148E;TIRHUTA LETTER AU;Lo;0;L;;;;;N;;;;;
+1148F;TIRHUTA LETTER KA;Lo;0;L;;;;;N;;;;;
+11490;TIRHUTA LETTER KHA;Lo;0;L;;;;;N;;;;;
+11491;TIRHUTA LETTER GA;Lo;0;L;;;;;N;;;;;
+11492;TIRHUTA LETTER GHA;Lo;0;L;;;;;N;;;;;
+11493;TIRHUTA LETTER NGA;Lo;0;L;;;;;N;;;;;
+11494;TIRHUTA LETTER CA;Lo;0;L;;;;;N;;;;;
+11495;TIRHUTA LETTER CHA;Lo;0;L;;;;;N;;;;;
+11496;TIRHUTA LETTER JA;Lo;0;L;;;;;N;;;;;
+11497;TIRHUTA LETTER JHA;Lo;0;L;;;;;N;;;;;
+11498;TIRHUTA LETTER NYA;Lo;0;L;;;;;N;;;;;
+11499;TIRHUTA LETTER TTA;Lo;0;L;;;;;N;;;;;
+1149A;TIRHUTA LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1149B;TIRHUTA LETTER DDA;Lo;0;L;;;;;N;;;;;
+1149C;TIRHUTA LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1149D;TIRHUTA LETTER NNA;Lo;0;L;;;;;N;;;;;
+1149E;TIRHUTA LETTER TA;Lo;0;L;;;;;N;;;;;
+1149F;TIRHUTA LETTER THA;Lo;0;L;;;;;N;;;;;
+114A0;TIRHUTA LETTER DA;Lo;0;L;;;;;N;;;;;
+114A1;TIRHUTA LETTER DHA;Lo;0;L;;;;;N;;;;;
+114A2;TIRHUTA LETTER NA;Lo;0;L;;;;;N;;;;;
+114A3;TIRHUTA LETTER PA;Lo;0;L;;;;;N;;;;;
+114A4;TIRHUTA LETTER PHA;Lo;0;L;;;;;N;;;;;
+114A5;TIRHUTA LETTER BA;Lo;0;L;;;;;N;;;;;
+114A6;TIRHUTA LETTER BHA;Lo;0;L;;;;;N;;;;;
+114A7;TIRHUTA LETTER MA;Lo;0;L;;;;;N;;;;;
+114A8;TIRHUTA LETTER YA;Lo;0;L;;;;;N;;;;;
+114A9;TIRHUTA LETTER RA;Lo;0;L;;;;;N;;;;;
+114AA;TIRHUTA LETTER LA;Lo;0;L;;;;;N;;;;;
+114AB;TIRHUTA LETTER VA;Lo;0;L;;;;;N;;;;;
+114AC;TIRHUTA LETTER SHA;Lo;0;L;;;;;N;;;;;
+114AD;TIRHUTA LETTER SSA;Lo;0;L;;;;;N;;;;;
+114AE;TIRHUTA LETTER SA;Lo;0;L;;;;;N;;;;;
+114AF;TIRHUTA LETTER HA;Lo;0;L;;;;;N;;;;;
+114B0;TIRHUTA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+114B1;TIRHUTA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+114B2;TIRHUTA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+114B3;TIRHUTA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+114B4;TIRHUTA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+114B5;TIRHUTA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+114B6;TIRHUTA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+114B7;TIRHUTA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+114B8;TIRHUTA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+114B9;TIRHUTA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+114BA;TIRHUTA VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;;
+114BB;TIRHUTA VOWEL SIGN AI;Mc;0;L;114B9 114BA;;;;N;;;;;
+114BC;TIRHUTA VOWEL SIGN O;Mc;0;L;114B9 114B0;;;;N;;;;;
+114BD;TIRHUTA VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;;
+114BE;TIRHUTA VOWEL SIGN AU;Mc;0;L;114B9 114BD;;;;N;;;;;
+114BF;TIRHUTA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+114C0;TIRHUTA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+114C1;TIRHUTA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+114C2;TIRHUTA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+114C3;TIRHUTA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+114C4;TIRHUTA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+114C5;TIRHUTA GVANG;Lo;0;L;;;;;N;;;;;
+114C6;TIRHUTA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+114C7;TIRHUTA OM;Lo;0;L;;;;;N;;;;;
+114D0;TIRHUTA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+114D1;TIRHUTA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+114D2;TIRHUTA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+114D3;TIRHUTA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+114D4;TIRHUTA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+114D5;TIRHUTA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+114D6;TIRHUTA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+114D7;TIRHUTA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+114D8;TIRHUTA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+114D9;TIRHUTA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11580;SIDDHAM LETTER A;Lo;0;L;;;;;N;;;;;
+11581;SIDDHAM LETTER AA;Lo;0;L;;;;;N;;;;;
+11582;SIDDHAM LETTER I;Lo;0;L;;;;;N;;;;;
+11583;SIDDHAM LETTER II;Lo;0;L;;;;;N;;;;;
+11584;SIDDHAM LETTER U;Lo;0;L;;;;;N;;;;;
+11585;SIDDHAM LETTER UU;Lo;0;L;;;;;N;;;;;
+11586;SIDDHAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+11587;SIDDHAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11588;SIDDHAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+11589;SIDDHAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1158A;SIDDHAM LETTER E;Lo;0;L;;;;;N;;;;;
+1158B;SIDDHAM LETTER AI;Lo;0;L;;;;;N;;;;;
+1158C;SIDDHAM LETTER O;Lo;0;L;;;;;N;;;;;
+1158D;SIDDHAM LETTER AU;Lo;0;L;;;;;N;;;;;
+1158E;SIDDHAM LETTER KA;Lo;0;L;;;;;N;;;;;
+1158F;SIDDHAM LETTER KHA;Lo;0;L;;;;;N;;;;;
+11590;SIDDHAM LETTER GA;Lo;0;L;;;;;N;;;;;
+11591;SIDDHAM LETTER GHA;Lo;0;L;;;;;N;;;;;
+11592;SIDDHAM LETTER NGA;Lo;0;L;;;;;N;;;;;
+11593;SIDDHAM LETTER CA;Lo;0;L;;;;;N;;;;;
+11594;SIDDHAM LETTER CHA;Lo;0;L;;;;;N;;;;;
+11595;SIDDHAM LETTER JA;Lo;0;L;;;;;N;;;;;
+11596;SIDDHAM LETTER JHA;Lo;0;L;;;;;N;;;;;
+11597;SIDDHAM LETTER NYA;Lo;0;L;;;;;N;;;;;
+11598;SIDDHAM LETTER TTA;Lo;0;L;;;;;N;;;;;
+11599;SIDDHAM LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1159A;SIDDHAM LETTER DDA;Lo;0;L;;;;;N;;;;;
+1159B;SIDDHAM LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1159C;SIDDHAM LETTER NNA;Lo;0;L;;;;;N;;;;;
+1159D;SIDDHAM LETTER TA;Lo;0;L;;;;;N;;;;;
+1159E;SIDDHAM LETTER THA;Lo;0;L;;;;;N;;;;;
+1159F;SIDDHAM LETTER DA;Lo;0;L;;;;;N;;;;;
+115A0;SIDDHAM LETTER DHA;Lo;0;L;;;;;N;;;;;
+115A1;SIDDHAM LETTER NA;Lo;0;L;;;;;N;;;;;
+115A2;SIDDHAM LETTER PA;Lo;0;L;;;;;N;;;;;
+115A3;SIDDHAM LETTER PHA;Lo;0;L;;;;;N;;;;;
+115A4;SIDDHAM LETTER BA;Lo;0;L;;;;;N;;;;;
+115A5;SIDDHAM LETTER BHA;Lo;0;L;;;;;N;;;;;
+115A6;SIDDHAM LETTER MA;Lo;0;L;;;;;N;;;;;
+115A7;SIDDHAM LETTER YA;Lo;0;L;;;;;N;;;;;
+115A8;SIDDHAM LETTER RA;Lo;0;L;;;;;N;;;;;
+115A9;SIDDHAM LETTER LA;Lo;0;L;;;;;N;;;;;
+115AA;SIDDHAM LETTER VA;Lo;0;L;;;;;N;;;;;
+115AB;SIDDHAM LETTER SHA;Lo;0;L;;;;;N;;;;;
+115AC;SIDDHAM LETTER SSA;Lo;0;L;;;;;N;;;;;
+115AD;SIDDHAM LETTER SA;Lo;0;L;;;;;N;;;;;
+115AE;SIDDHAM LETTER HA;Lo;0;L;;;;;N;;;;;
+115AF;SIDDHAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+115B0;SIDDHAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+115B1;SIDDHAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+115B2;SIDDHAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+115B3;SIDDHAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+115B4;SIDDHAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+115B5;SIDDHAM VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+115B8;SIDDHAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+115B9;SIDDHAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+115BA;SIDDHAM VOWEL SIGN O;Mc;0;L;115B8 115AF;;;;N;;;;;
+115BB;SIDDHAM VOWEL SIGN AU;Mc;0;L;115B9 115AF;;;;N;;;;;
+115BC;SIDDHAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+115BD;SIDDHAM SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+115BE;SIDDHAM SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+115BF;SIDDHAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+115C0;SIDDHAM SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+115C1;SIDDHAM SIGN SIDDHAM;Po;0;L;;;;;N;;;;;
+115C2;SIDDHAM DANDA;Po;0;L;;;;;N;;;;;
+115C3;SIDDHAM DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+115C4;SIDDHAM SEPARATOR DOT;Po;0;L;;;;;N;;;;;
+115C5;SIDDHAM SEPARATOR BAR;Po;0;L;;;;;N;;;;;
+115C6;SIDDHAM REPETITION MARK-1;Po;0;L;;;;;N;;;;;
+115C7;SIDDHAM REPETITION MARK-2;Po;0;L;;;;;N;;;;;
+115C8;SIDDHAM REPETITION MARK-3;Po;0;L;;;;;N;;;;;
+115C9;SIDDHAM END OF TEXT MARK;Po;0;L;;;;;N;;;;;
+115CA;SIDDHAM SECTION MARK WITH TRIDENT AND U-SHAPED ORNAMENTS;Po;0;L;;;;;N;;;;;
+115CB;SIDDHAM SECTION MARK WITH TRIDENT AND DOTTED CRESCENTS;Po;0;L;;;;;N;;;;;
+115CC;SIDDHAM SECTION MARK WITH RAYS AND DOTTED CRESCENTS;Po;0;L;;;;;N;;;;;
+115CD;SIDDHAM SECTION MARK WITH RAYS AND DOTTED DOUBLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115CE;SIDDHAM SECTION MARK WITH RAYS AND DOTTED TRIPLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115CF;SIDDHAM SECTION MARK DOUBLE RING;Po;0;L;;;;;N;;;;;
+115D0;SIDDHAM SECTION MARK DOUBLE RING WITH RAYS;Po;0;L;;;;;N;;;;;
+115D1;SIDDHAM SECTION MARK WITH DOUBLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115D2;SIDDHAM SECTION MARK WITH TRIPLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115D3;SIDDHAM SECTION MARK WITH QUADRUPLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115D4;SIDDHAM SECTION MARK WITH SEPTUPLE CRESCENTS;Po;0;L;;;;;N;;;;;
+115D5;SIDDHAM SECTION MARK WITH CIRCLES AND RAYS;Po;0;L;;;;;N;;;;;
+115D6;SIDDHAM SECTION MARK WITH CIRCLES AND TWO ENCLOSURES;Po;0;L;;;;;N;;;;;
+115D7;SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES;Po;0;L;;;;;N;;;;;
+115D8;SIDDHAM LETTER THREE-CIRCLE ALTERNATE I;Lo;0;L;;;;;N;;;;;
+115D9;SIDDHAM LETTER TWO-CIRCLE ALTERNATE I;Lo;0;L;;;;;N;;;;;
+115DA;SIDDHAM LETTER TWO-CIRCLE ALTERNATE II;Lo;0;L;;;;;N;;;;;
+115DB;SIDDHAM LETTER ALTERNATE U;Lo;0;L;;;;;N;;;;;
+115DC;SIDDHAM VOWEL SIGN ALTERNATE U;Mn;0;NSM;;;;;N;;;;;
+115DD;SIDDHAM VOWEL SIGN ALTERNATE UU;Mn;0;NSM;;;;;N;;;;;
+11600;MODI LETTER A;Lo;0;L;;;;;N;;;;;
+11601;MODI LETTER AA;Lo;0;L;;;;;N;;;;;
+11602;MODI LETTER I;Lo;0;L;;;;;N;;;;;
+11603;MODI LETTER II;Lo;0;L;;;;;N;;;;;
+11604;MODI LETTER U;Lo;0;L;;;;;N;;;;;
+11605;MODI LETTER UU;Lo;0;L;;;;;N;;;;;
+11606;MODI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+11607;MODI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11608;MODI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+11609;MODI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+1160A;MODI LETTER E;Lo;0;L;;;;;N;;;;;
+1160B;MODI LETTER AI;Lo;0;L;;;;;N;;;;;
+1160C;MODI LETTER O;Lo;0;L;;;;;N;;;;;
+1160D;MODI LETTER AU;Lo;0;L;;;;;N;;;;;
+1160E;MODI LETTER KA;Lo;0;L;;;;;N;;;;;
+1160F;MODI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11610;MODI LETTER GA;Lo;0;L;;;;;N;;;;;
+11611;MODI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11612;MODI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11613;MODI LETTER CA;Lo;0;L;;;;;N;;;;;
+11614;MODI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11615;MODI LETTER JA;Lo;0;L;;;;;N;;;;;
+11616;MODI LETTER JHA;Lo;0;L;;;;;N;;;;;
+11617;MODI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11618;MODI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11619;MODI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+1161A;MODI LETTER DDA;Lo;0;L;;;;;N;;;;;
+1161B;MODI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+1161C;MODI LETTER NNA;Lo;0;L;;;;;N;;;;;
+1161D;MODI LETTER TA;Lo;0;L;;;;;N;;;;;
+1161E;MODI LETTER THA;Lo;0;L;;;;;N;;;;;
+1161F;MODI LETTER DA;Lo;0;L;;;;;N;;;;;
+11620;MODI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11621;MODI LETTER NA;Lo;0;L;;;;;N;;;;;
+11622;MODI LETTER PA;Lo;0;L;;;;;N;;;;;
+11623;MODI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11624;MODI LETTER BA;Lo;0;L;;;;;N;;;;;
+11625;MODI LETTER BHA;Lo;0;L;;;;;N;;;;;
+11626;MODI LETTER MA;Lo;0;L;;;;;N;;;;;
+11627;MODI LETTER YA;Lo;0;L;;;;;N;;;;;
+11628;MODI LETTER RA;Lo;0;L;;;;;N;;;;;
+11629;MODI LETTER LA;Lo;0;L;;;;;N;;;;;
+1162A;MODI LETTER VA;Lo;0;L;;;;;N;;;;;
+1162B;MODI LETTER SHA;Lo;0;L;;;;;N;;;;;
+1162C;MODI LETTER SSA;Lo;0;L;;;;;N;;;;;
+1162D;MODI LETTER SA;Lo;0;L;;;;;N;;;;;
+1162E;MODI LETTER HA;Lo;0;L;;;;;N;;;;;
+1162F;MODI LETTER LLA;Lo;0;L;;;;;N;;;;;
+11630;MODI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+11631;MODI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+11632;MODI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+11633;MODI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11634;MODI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+11635;MODI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+11636;MODI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+11637;MODI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+11638;MODI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
+11639;MODI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+1163A;MODI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+1163B;MODI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+1163C;MODI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+1163D;MODI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+1163E;MODI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+1163F;MODI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11640;MODI SIGN ARDHACANDRA;Mn;0;NSM;;;;;N;;;;;
+11641;MODI DANDA;Po;0;L;;;;;N;;;;;
+11642;MODI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+11643;MODI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
+11644;MODI SIGN HUVA;Lo;0;L;;;;;N;;;;;
+11650;MODI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11651;MODI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11652;MODI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11653;MODI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11654;MODI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11655;MODI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11656;MODI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11657;MODI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11658;MODI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11659;MODI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11660;MONGOLIAN BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;
+11661;MONGOLIAN ROTATED BIRGA;Po;0;ON;;;;;N;;;;;
+11662;MONGOLIAN DOUBLE BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;
+11663;MONGOLIAN TRIPLE BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;
+11664;MONGOLIAN BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;
+11665;MONGOLIAN ROTATED BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;
+11666;MONGOLIAN ROTATED BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;
+11667;MONGOLIAN INVERTED BIRGA;Po;0;ON;;;;;N;;;;;
+11668;MONGOLIAN INVERTED BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;
+11669;MONGOLIAN SWIRL BIRGA;Po;0;ON;;;;;N;;;;;
+1166A;MONGOLIAN SWIRL BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;
+1166B;MONGOLIAN SWIRL BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;
+1166C;MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;
+11680;TAKRI LETTER A;Lo;0;L;;;;;N;;;;;
+11681;TAKRI LETTER AA;Lo;0;L;;;;;N;;;;;
+11682;TAKRI LETTER I;Lo;0;L;;;;;N;;;;;
+11683;TAKRI LETTER II;Lo;0;L;;;;;N;;;;;
+11684;TAKRI LETTER U;Lo;0;L;;;;;N;;;;;
+11685;TAKRI LETTER UU;Lo;0;L;;;;;N;;;;;
+11686;TAKRI LETTER E;Lo;0;L;;;;;N;;;;;
+11687;TAKRI LETTER AI;Lo;0;L;;;;;N;;;;;
+11688;TAKRI LETTER O;Lo;0;L;;;;;N;;;;;
+11689;TAKRI LETTER AU;Lo;0;L;;;;;N;;;;;
+1168A;TAKRI LETTER KA;Lo;0;L;;;;;N;;;;;
+1168B;TAKRI LETTER KHA;Lo;0;L;;;;;N;;;;;
+1168C;TAKRI LETTER GA;Lo;0;L;;;;;N;;;;;
+1168D;TAKRI LETTER GHA;Lo;0;L;;;;;N;;;;;
+1168E;TAKRI LETTER NGA;Lo;0;L;;;;;N;;;;;
+1168F;TAKRI LETTER CA;Lo;0;L;;;;;N;;;;;
+11690;TAKRI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11691;TAKRI LETTER JA;Lo;0;L;;;;;N;;;;;
+11692;TAKRI LETTER JHA;Lo;0;L;;;;;N;;;;;
+11693;TAKRI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11694;TAKRI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11695;TAKRI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11696;TAKRI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11697;TAKRI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11698;TAKRI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11699;TAKRI LETTER TA;Lo;0;L;;;;;N;;;;;
+1169A;TAKRI LETTER THA;Lo;0;L;;;;;N;;;;;
+1169B;TAKRI LETTER DA;Lo;0;L;;;;;N;;;;;
+1169C;TAKRI LETTER DHA;Lo;0;L;;;;;N;;;;;
+1169D;TAKRI LETTER NA;Lo;0;L;;;;;N;;;;;
+1169E;TAKRI LETTER PA;Lo;0;L;;;;;N;;;;;
+1169F;TAKRI LETTER PHA;Lo;0;L;;;;;N;;;;;
+116A0;TAKRI LETTER BA;Lo;0;L;;;;;N;;;;;
+116A1;TAKRI LETTER BHA;Lo;0;L;;;;;N;;;;;
+116A2;TAKRI LETTER MA;Lo;0;L;;;;;N;;;;;
+116A3;TAKRI LETTER YA;Lo;0;L;;;;;N;;;;;
+116A4;TAKRI LETTER RA;Lo;0;L;;;;;N;;;;;
+116A5;TAKRI LETTER LA;Lo;0;L;;;;;N;;;;;
+116A6;TAKRI LETTER VA;Lo;0;L;;;;;N;;;;;
+116A7;TAKRI LETTER SHA;Lo;0;L;;;;;N;;;;;
+116A8;TAKRI LETTER SA;Lo;0;L;;;;;N;;;;;
+116A9;TAKRI LETTER HA;Lo;0;L;;;;;N;;;;;
+116AA;TAKRI LETTER RRA;Lo;0;L;;;;;N;;;;;
+116AB;TAKRI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+116AC;TAKRI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+116AD;TAKRI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+116AE;TAKRI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+116AF;TAKRI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+116B0;TAKRI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+116B1;TAKRI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+116B2;TAKRI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+116B3;TAKRI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+116B4;TAKRI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+116B5;TAKRI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+116B6;TAKRI SIGN VIRAMA;Mc;9;L;;;;;N;;;;;
+116B7;TAKRI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+116C0;TAKRI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+116C1;TAKRI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+116C2;TAKRI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+116C3;TAKRI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+116C4;TAKRI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+116C5;TAKRI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+116C6;TAKRI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+116C7;TAKRI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+116C8;TAKRI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+116C9;TAKRI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11700;AHOM LETTER KA;Lo;0;L;;;;;N;;;;;
+11701;AHOM LETTER KHA;Lo;0;L;;;;;N;;;;;
+11702;AHOM LETTER NGA;Lo;0;L;;;;;N;;;;;
+11703;AHOM LETTER NA;Lo;0;L;;;;;N;;;;;
+11704;AHOM LETTER TA;Lo;0;L;;;;;N;;;;;
+11705;AHOM LETTER ALTERNATE TA;Lo;0;L;;;;;N;;;;;
+11706;AHOM LETTER PA;Lo;0;L;;;;;N;;;;;
+11707;AHOM LETTER PHA;Lo;0;L;;;;;N;;;;;
+11708;AHOM LETTER BA;Lo;0;L;;;;;N;;;;;
+11709;AHOM LETTER MA;Lo;0;L;;;;;N;;;;;
+1170A;AHOM LETTER JA;Lo;0;L;;;;;N;;;;;
+1170B;AHOM LETTER CHA;Lo;0;L;;;;;N;;;;;
+1170C;AHOM LETTER THA;Lo;0;L;;;;;N;;;;;
+1170D;AHOM LETTER RA;Lo;0;L;;;;;N;;;;;
+1170E;AHOM LETTER LA;Lo;0;L;;;;;N;;;;;
+1170F;AHOM LETTER SA;Lo;0;L;;;;;N;;;;;
+11710;AHOM LETTER NYA;Lo;0;L;;;;;N;;;;;
+11711;AHOM LETTER HA;Lo;0;L;;;;;N;;;;;
+11712;AHOM LETTER A;Lo;0;L;;;;;N;;;;;
+11713;AHOM LETTER DA;Lo;0;L;;;;;N;;;;;
+11714;AHOM LETTER DHA;Lo;0;L;;;;;N;;;;;
+11715;AHOM LETTER GA;Lo;0;L;;;;;N;;;;;
+11716;AHOM LETTER ALTERNATE GA;Lo;0;L;;;;;N;;;;;
+11717;AHOM LETTER GHA;Lo;0;L;;;;;N;;;;;
+11718;AHOM LETTER BHA;Lo;0;L;;;;;N;;;;;
+11719;AHOM LETTER JHA;Lo;0;L;;;;;N;;;;;
+1171D;AHOM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;;
+1171E;AHOM CONSONANT SIGN MEDIAL RA;Mn;0;NSM;;;;;N;;;;;
+1171F;AHOM CONSONANT SIGN MEDIAL LIGATING RA;Mn;0;NSM;;;;;N;;;;;
+11720;AHOM VOWEL SIGN A;Mc;0;L;;;;;N;;;;;
+11721;AHOM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+11722;AHOM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11723;AHOM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+11724;AHOM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11725;AHOM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+11726;AHOM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+11727;AHOM VOWEL SIGN AW;Mn;0;NSM;;;;;N;;;;;
+11728;AHOM VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11729;AHOM VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+1172A;AHOM VOWEL SIGN AM;Mn;0;NSM;;;;;N;;;;;
+1172B;AHOM SIGN KILLER;Mn;9;NSM;;;;;N;;;;;
+11730;AHOM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11731;AHOM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11732;AHOM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11733;AHOM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11734;AHOM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11735;AHOM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11736;AHOM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11737;AHOM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11738;AHOM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11739;AHOM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1173A;AHOM NUMBER TEN;No;0;L;;;;10;N;;;;;
+1173B;AHOM NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+1173C;AHOM SIGN SMALL SECTION;Po;0;L;;;;;N;;;;;
+1173D;AHOM SIGN SECTION;Po;0;L;;;;;N;;;;;
+1173E;AHOM SIGN RULAI;Po;0;L;;;;;N;;;;;
+1173F;AHOM SYMBOL VI;So;0;L;;;;;N;;;;;
+118A0;WARANG CITI CAPITAL LETTER NGAA;Lu;0;L;;;;;N;;;;118C0;
+118A1;WARANG CITI CAPITAL LETTER A;Lu;0;L;;;;;N;;;;118C1;
+118A2;WARANG CITI CAPITAL LETTER WI;Lu;0;L;;;;;N;;;;118C2;
+118A3;WARANG CITI CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;118C3;
+118A4;WARANG CITI CAPITAL LETTER YA;Lu;0;L;;;;;N;;;;118C4;
+118A5;WARANG CITI CAPITAL LETTER YO;Lu;0;L;;;;;N;;;;118C5;
+118A6;WARANG CITI CAPITAL LETTER II;Lu;0;L;;;;;N;;;;118C6;
+118A7;WARANG CITI CAPITAL LETTER UU;Lu;0;L;;;;;N;;;;118C7;
+118A8;WARANG CITI CAPITAL LETTER E;Lu;0;L;;;;;N;;;;118C8;
+118A9;WARANG CITI CAPITAL LETTER O;Lu;0;L;;;;;N;;;;118C9;
+118AA;WARANG CITI CAPITAL LETTER ANG;Lu;0;L;;;;;N;;;;118CA;
+118AB;WARANG CITI CAPITAL LETTER GA;Lu;0;L;;;;;N;;;;118CB;
+118AC;WARANG CITI CAPITAL LETTER KO;Lu;0;L;;;;;N;;;;118CC;
+118AD;WARANG CITI CAPITAL LETTER ENY;Lu;0;L;;;;;N;;;;118CD;
+118AE;WARANG CITI CAPITAL LETTER YUJ;Lu;0;L;;;;;N;;;;118CE;
+118AF;WARANG CITI CAPITAL LETTER UC;Lu;0;L;;;;;N;;;;118CF;
+118B0;WARANG CITI CAPITAL LETTER ENN;Lu;0;L;;;;;N;;;;118D0;
+118B1;WARANG CITI CAPITAL LETTER ODD;Lu;0;L;;;;;N;;;;118D1;
+118B2;WARANG CITI CAPITAL LETTER TTE;Lu;0;L;;;;;N;;;;118D2;
+118B3;WARANG CITI CAPITAL LETTER NUNG;Lu;0;L;;;;;N;;;;118D3;
+118B4;WARANG CITI CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;118D4;
+118B5;WARANG CITI CAPITAL LETTER AT;Lu;0;L;;;;;N;;;;118D5;
+118B6;WARANG CITI CAPITAL LETTER AM;Lu;0;L;;;;;N;;;;118D6;
+118B7;WARANG CITI CAPITAL LETTER BU;Lu;0;L;;;;;N;;;;118D7;
+118B8;WARANG CITI CAPITAL LETTER PU;Lu;0;L;;;;;N;;;;118D8;
+118B9;WARANG CITI CAPITAL LETTER HIYO;Lu;0;L;;;;;N;;;;118D9;
+118BA;WARANG CITI CAPITAL LETTER HOLO;Lu;0;L;;;;;N;;;;118DA;
+118BB;WARANG CITI CAPITAL LETTER HORR;Lu;0;L;;;;;N;;;;118DB;
+118BC;WARANG CITI CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;118DC;
+118BD;WARANG CITI CAPITAL LETTER SSUU;Lu;0;L;;;;;N;;;;118DD;
+118BE;WARANG CITI CAPITAL LETTER SII;Lu;0;L;;;;;N;;;;118DE;
+118BF;WARANG CITI CAPITAL LETTER VIYO;Lu;0;L;;;;;N;;;;118DF;
+118C0;WARANG CITI SMALL LETTER NGAA;Ll;0;L;;;;;N;;;118A0;;118A0
+118C1;WARANG CITI SMALL LETTER A;Ll;0;L;;;;;N;;;118A1;;118A1
+118C2;WARANG CITI SMALL LETTER WI;Ll;0;L;;;;;N;;;118A2;;118A2
+118C3;WARANG CITI SMALL LETTER YU;Ll;0;L;;;;;N;;;118A3;;118A3
+118C4;WARANG CITI SMALL LETTER YA;Ll;0;L;;;;;N;;;118A4;;118A4
+118C5;WARANG CITI SMALL LETTER YO;Ll;0;L;;;;;N;;;118A5;;118A5
+118C6;WARANG CITI SMALL LETTER II;Ll;0;L;;;;;N;;;118A6;;118A6
+118C7;WARANG CITI SMALL LETTER UU;Ll;0;L;;;;;N;;;118A7;;118A7
+118C8;WARANG CITI SMALL LETTER E;Ll;0;L;;;;;N;;;118A8;;118A8
+118C9;WARANG CITI SMALL LETTER O;Ll;0;L;;;;;N;;;118A9;;118A9
+118CA;WARANG CITI SMALL LETTER ANG;Ll;0;L;;;;;N;;;118AA;;118AA
+118CB;WARANG CITI SMALL LETTER GA;Ll;0;L;;;;;N;;;118AB;;118AB
+118CC;WARANG CITI SMALL LETTER KO;Ll;0;L;;;;;N;;;118AC;;118AC
+118CD;WARANG CITI SMALL LETTER ENY;Ll;0;L;;;;;N;;;118AD;;118AD
+118CE;WARANG CITI SMALL LETTER YUJ;Ll;0;L;;;;;N;;;118AE;;118AE
+118CF;WARANG CITI SMALL LETTER UC;Ll;0;L;;;;;N;;;118AF;;118AF
+118D0;WARANG CITI SMALL LETTER ENN;Ll;0;L;;;;;N;;;118B0;;118B0
+118D1;WARANG CITI SMALL LETTER ODD;Ll;0;L;;;;;N;;;118B1;;118B1
+118D2;WARANG CITI SMALL LETTER TTE;Ll;0;L;;;;;N;;;118B2;;118B2
+118D3;WARANG CITI SMALL LETTER NUNG;Ll;0;L;;;;;N;;;118B3;;118B3
+118D4;WARANG CITI SMALL LETTER DA;Ll;0;L;;;;;N;;;118B4;;118B4
+118D5;WARANG CITI SMALL LETTER AT;Ll;0;L;;;;;N;;;118B5;;118B5
+118D6;WARANG CITI SMALL LETTER AM;Ll;0;L;;;;;N;;;118B6;;118B6
+118D7;WARANG CITI SMALL LETTER BU;Ll;0;L;;;;;N;;;118B7;;118B7
+118D8;WARANG CITI SMALL LETTER PU;Ll;0;L;;;;;N;;;118B8;;118B8
+118D9;WARANG CITI SMALL LETTER HIYO;Ll;0;L;;;;;N;;;118B9;;118B9
+118DA;WARANG CITI SMALL LETTER HOLO;Ll;0;L;;;;;N;;;118BA;;118BA
+118DB;WARANG CITI SMALL LETTER HORR;Ll;0;L;;;;;N;;;118BB;;118BB
+118DC;WARANG CITI SMALL LETTER HAR;Ll;0;L;;;;;N;;;118BC;;118BC
+118DD;WARANG CITI SMALL LETTER SSUU;Ll;0;L;;;;;N;;;118BD;;118BD
+118DE;WARANG CITI SMALL LETTER SII;Ll;0;L;;;;;N;;;118BE;;118BE
+118DF;WARANG CITI SMALL LETTER VIYO;Ll;0;L;;;;;N;;;118BF;;118BF
+118E0;WARANG CITI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+118E1;WARANG CITI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+118E2;WARANG CITI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+118E3;WARANG CITI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+118E4;WARANG CITI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+118E5;WARANG CITI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+118E6;WARANG CITI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+118E7;WARANG CITI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+118E8;WARANG CITI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+118E9;WARANG CITI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+118EA;WARANG CITI NUMBER TEN;No;0;L;;;;10;N;;;;;
+118EB;WARANG CITI NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+118EC;WARANG CITI NUMBER THIRTY;No;0;L;;;;30;N;;;;;
+118ED;WARANG CITI NUMBER FORTY;No;0;L;;;;40;N;;;;;
+118EE;WARANG CITI NUMBER FIFTY;No;0;L;;;;50;N;;;;;
+118EF;WARANG CITI NUMBER SIXTY;No;0;L;;;;60;N;;;;;
+118F0;WARANG CITI NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
+118F1;WARANG CITI NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
+118F2;WARANG CITI NUMBER NINETY;No;0;L;;;;90;N;;;;;
+118FF;WARANG CITI OM;Lo;0;L;;;;;N;;;;;
+11AC0;PAU CIN HAU LETTER PA;Lo;0;L;;;;;N;;;;;
+11AC1;PAU CIN HAU LETTER KA;Lo;0;L;;;;;N;;;;;
+11AC2;PAU CIN HAU LETTER LA;Lo;0;L;;;;;N;;;;;
+11AC3;PAU CIN HAU LETTER MA;Lo;0;L;;;;;N;;;;;
+11AC4;PAU CIN HAU LETTER DA;Lo;0;L;;;;;N;;;;;
+11AC5;PAU CIN HAU LETTER ZA;Lo;0;L;;;;;N;;;;;
+11AC6;PAU CIN HAU LETTER VA;Lo;0;L;;;;;N;;;;;
+11AC7;PAU CIN HAU LETTER NGA;Lo;0;L;;;;;N;;;;;
+11AC8;PAU CIN HAU LETTER HA;Lo;0;L;;;;;N;;;;;
+11AC9;PAU CIN HAU LETTER GA;Lo;0;L;;;;;N;;;;;
+11ACA;PAU CIN HAU LETTER KHA;Lo;0;L;;;;;N;;;;;
+11ACB;PAU CIN HAU LETTER SA;Lo;0;L;;;;;N;;;;;
+11ACC;PAU CIN HAU LETTER BA;Lo;0;L;;;;;N;;;;;
+11ACD;PAU CIN HAU LETTER CA;Lo;0;L;;;;;N;;;;;
+11ACE;PAU CIN HAU LETTER TA;Lo;0;L;;;;;N;;;;;
+11ACF;PAU CIN HAU LETTER THA;Lo;0;L;;;;;N;;;;;
+11AD0;PAU CIN HAU LETTER NA;Lo;0;L;;;;;N;;;;;
+11AD1;PAU CIN HAU LETTER PHA;Lo;0;L;;;;;N;;;;;
+11AD2;PAU CIN HAU LETTER RA;Lo;0;L;;;;;N;;;;;
+11AD3;PAU CIN HAU LETTER FA;Lo;0;L;;;;;N;;;;;
+11AD4;PAU CIN HAU LETTER CHA;Lo;0;L;;;;;N;;;;;
+11AD5;PAU CIN HAU LETTER A;Lo;0;L;;;;;N;;;;;
+11AD6;PAU CIN HAU LETTER E;Lo;0;L;;;;;N;;;;;
+11AD7;PAU CIN HAU LETTER I;Lo;0;L;;;;;N;;;;;
+11AD8;PAU CIN HAU LETTER O;Lo;0;L;;;;;N;;;;;
+11AD9;PAU CIN HAU LETTER U;Lo;0;L;;;;;N;;;;;
+11ADA;PAU CIN HAU LETTER UA;Lo;0;L;;;;;N;;;;;
+11ADB;PAU CIN HAU LETTER IA;Lo;0;L;;;;;N;;;;;
+11ADC;PAU CIN HAU LETTER FINAL P;Lo;0;L;;;;;N;;;;;
+11ADD;PAU CIN HAU LETTER FINAL K;Lo;0;L;;;;;N;;;;;
+11ADE;PAU CIN HAU LETTER FINAL T;Lo;0;L;;;;;N;;;;;
+11ADF;PAU CIN HAU LETTER FINAL M;Lo;0;L;;;;;N;;;;;
+11AE0;PAU CIN HAU LETTER FINAL N;Lo;0;L;;;;;N;;;;;
+11AE1;PAU CIN HAU LETTER FINAL L;Lo;0;L;;;;;N;;;;;
+11AE2;PAU CIN HAU LETTER FINAL W;Lo;0;L;;;;;N;;;;;
+11AE3;PAU CIN HAU LETTER FINAL NG;Lo;0;L;;;;;N;;;;;
+11AE4;PAU CIN HAU LETTER FINAL Y;Lo;0;L;;;;;N;;;;;
+11AE5;PAU CIN HAU RISING TONE LONG;Lo;0;L;;;;;N;;;;;
+11AE6;PAU CIN HAU RISING TONE;Lo;0;L;;;;;N;;;;;
+11AE7;PAU CIN HAU SANDHI GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
+11AE8;PAU CIN HAU RISING TONE LONG FINAL;Lo;0;L;;;;;N;;;;;
+11AE9;PAU CIN HAU RISING TONE FINAL;Lo;0;L;;;;;N;;;;;
+11AEA;PAU CIN HAU SANDHI GLOTTAL STOP FINAL;Lo;0;L;;;;;N;;;;;
+11AEB;PAU CIN HAU SANDHI TONE LONG;Lo;0;L;;;;;N;;;;;
+11AEC;PAU CIN HAU SANDHI TONE;Lo;0;L;;;;;N;;;;;
+11AED;PAU CIN HAU SANDHI TONE LONG FINAL;Lo;0;L;;;;;N;;;;;
+11AEE;PAU CIN HAU SANDHI TONE FINAL;Lo;0;L;;;;;N;;;;;
+11AEF;PAU CIN HAU MID-LEVEL TONE;Lo;0;L;;;;;N;;;;;
+11AF0;PAU CIN HAU GLOTTAL STOP VARIANT;Lo;0;L;;;;;N;;;;;
+11AF1;PAU CIN HAU MID-LEVEL TONE LONG FINAL;Lo;0;L;;;;;N;;;;;
+11AF2;PAU CIN HAU MID-LEVEL TONE FINAL;Lo;0;L;;;;;N;;;;;
+11AF3;PAU CIN HAU LOW-FALLING TONE LONG;Lo;0;L;;;;;N;;;;;
+11AF4;PAU CIN HAU LOW-FALLING TONE;Lo;0;L;;;;;N;;;;;
+11AF5;PAU CIN HAU GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
+11AF6;PAU CIN HAU LOW-FALLING TONE LONG FINAL;Lo;0;L;;;;;N;;;;;
+11AF7;PAU CIN HAU LOW-FALLING TONE FINAL;Lo;0;L;;;;;N;;;;;
+11AF8;PAU CIN HAU GLOTTAL STOP FINAL;Lo;0;L;;;;;N;;;;;
+11C00;BHAIKSUKI LETTER A;Lo;0;L;;;;;N;;;;;
+11C01;BHAIKSUKI LETTER AA;Lo;0;L;;;;;N;;;;;
+11C02;BHAIKSUKI LETTER I;Lo;0;L;;;;;N;;;;;
+11C03;BHAIKSUKI LETTER II;Lo;0;L;;;;;N;;;;;
+11C04;BHAIKSUKI LETTER U;Lo;0;L;;;;;N;;;;;
+11C05;BHAIKSUKI LETTER UU;Lo;0;L;;;;;N;;;;;
+11C06;BHAIKSUKI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+11C07;BHAIKSUKI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11C08;BHAIKSUKI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+11C0A;BHAIKSUKI LETTER E;Lo;0;L;;;;;N;;;;;
+11C0B;BHAIKSUKI LETTER AI;Lo;0;L;;;;;N;;;;;
+11C0C;BHAIKSUKI LETTER O;Lo;0;L;;;;;N;;;;;
+11C0D;BHAIKSUKI LETTER AU;Lo;0;L;;;;;N;;;;;
+11C0E;BHAIKSUKI LETTER KA;Lo;0;L;;;;;N;;;;;
+11C0F;BHAIKSUKI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11C10;BHAIKSUKI LETTER GA;Lo;0;L;;;;;N;;;;;
+11C11;BHAIKSUKI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11C12;BHAIKSUKI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11C13;BHAIKSUKI LETTER CA;Lo;0;L;;;;;N;;;;;
+11C14;BHAIKSUKI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11C15;BHAIKSUKI LETTER JA;Lo;0;L;;;;;N;;;;;
+11C16;BHAIKSUKI LETTER JHA;Lo;0;L;;;;;N;;;;;
+11C17;BHAIKSUKI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11C18;BHAIKSUKI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11C19;BHAIKSUKI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11C1A;BHAIKSUKI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11C1B;BHAIKSUKI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11C1C;BHAIKSUKI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11C1D;BHAIKSUKI LETTER TA;Lo;0;L;;;;;N;;;;;
+11C1E;BHAIKSUKI LETTER THA;Lo;0;L;;;;;N;;;;;
+11C1F;BHAIKSUKI LETTER DA;Lo;0;L;;;;;N;;;;;
+11C20;BHAIKSUKI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11C21;BHAIKSUKI LETTER NA;Lo;0;L;;;;;N;;;;;
+11C22;BHAIKSUKI LETTER PA;Lo;0;L;;;;;N;;;;;
+11C23;BHAIKSUKI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11C24;BHAIKSUKI LETTER BA;Lo;0;L;;;;;N;;;;;
+11C25;BHAIKSUKI LETTER BHA;Lo;0;L;;;;;N;;;;;
+11C26;BHAIKSUKI LETTER MA;Lo;0;L;;;;;N;;;;;
+11C27;BHAIKSUKI LETTER YA;Lo;0;L;;;;;N;;;;;
+11C28;BHAIKSUKI LETTER RA;Lo;0;L;;;;;N;;;;;
+11C29;BHAIKSUKI LETTER LA;Lo;0;L;;;;;N;;;;;
+11C2A;BHAIKSUKI LETTER VA;Lo;0;L;;;;;N;;;;;
+11C2B;BHAIKSUKI LETTER SHA;Lo;0;L;;;;;N;;;;;
+11C2C;BHAIKSUKI LETTER SSA;Lo;0;L;;;;;N;;;;;
+11C2D;BHAIKSUKI LETTER SA;Lo;0;L;;;;;N;;;;;
+11C2E;BHAIKSUKI LETTER HA;Lo;0;L;;;;;N;;;;;
+11C2F;BHAIKSUKI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+11C30;BHAIKSUKI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11C31;BHAIKSUKI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+11C32;BHAIKSUKI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11C33;BHAIKSUKI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+11C34;BHAIKSUKI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+11C35;BHAIKSUKI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+11C36;BHAIKSUKI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+11C38;BHAIKSUKI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11C39;BHAIKSUKI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+11C3A;BHAIKSUKI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11C3B;BHAIKSUKI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+11C3C;BHAIKSUKI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11C3D;BHAIKSUKI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11C3E;BHAIKSUKI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11C3F;BHAIKSUKI SIGN VIRAMA;Mn;9;L;;;;;N;;;;;
+11C40;BHAIKSUKI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+11C41;BHAIKSUKI DANDA;Po;0;L;;;;;N;;;;;
+11C42;BHAIKSUKI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+11C43;BHAIKSUKI WORD SEPARATOR;Po;0;L;;;;;N;;;;;
+11C44;BHAIKSUKI GAP FILLER-1;Po;0;L;;;;;N;;;;;
+11C45;BHAIKSUKI GAP FILLER-2;Po;0;L;;;;;N;;;;;
+11C50;BHAIKSUKI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11C51;BHAIKSUKI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11C52;BHAIKSUKI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11C53;BHAIKSUKI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11C54;BHAIKSUKI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11C55;BHAIKSUKI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11C56;BHAIKSUKI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11C57;BHAIKSUKI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11C58;BHAIKSUKI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11C59;BHAIKSUKI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+11C5A;BHAIKSUKI NUMBER ONE;No;0;L;;;;1;N;;;;;
+11C5B;BHAIKSUKI NUMBER TWO;No;0;L;;;;2;N;;;;;
+11C5C;BHAIKSUKI NUMBER THREE;No;0;L;;;;3;N;;;;;
+11C5D;BHAIKSUKI NUMBER FOUR;No;0;L;;;;4;N;;;;;
+11C5E;BHAIKSUKI NUMBER FIVE;No;0;L;;;;5;N;;;;;
+11C5F;BHAIKSUKI NUMBER SIX;No;0;L;;;;6;N;;;;;
+11C60;BHAIKSUKI NUMBER SEVEN;No;0;L;;;;7;N;;;;;
+11C61;BHAIKSUKI NUMBER EIGHT;No;0;L;;;;8;N;;;;;
+11C62;BHAIKSUKI NUMBER NINE;No;0;L;;;;9;N;;;;;
+11C63;BHAIKSUKI NUMBER TEN;No;0;L;;;;10;N;;;;;
+11C64;BHAIKSUKI NUMBER TWENTY;No;0;L;;;;20;N;;;;;
+11C65;BHAIKSUKI NUMBER THIRTY;No;0;L;;;;30;N;;;;;
+11C66;BHAIKSUKI NUMBER FORTY;No;0;L;;;;40;N;;;;;
+11C67;BHAIKSUKI NUMBER FIFTY;No;0;L;;;;50;N;;;;;
+11C68;BHAIKSUKI NUMBER SIXTY;No;0;L;;;;60;N;;;;;
+11C69;BHAIKSUKI NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
+11C6A;BHAIKSUKI NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
+11C6B;BHAIKSUKI NUMBER NINETY;No;0;L;;;;90;N;;;;;
+11C6C;BHAIKSUKI HUNDREDS UNIT MARK;No;0;L;;;;100;N;;;;;
+11C70;MARCHEN HEAD MARK;Po;0;L;;;;;N;;;;;
+11C71;MARCHEN MARK SHAD;Po;0;L;;;;;N;;;;;
+11C72;MARCHEN LETTER KA;Lo;0;L;;;;;N;;;;;
+11C73;MARCHEN LETTER KHA;Lo;0;L;;;;;N;;;;;
+11C74;MARCHEN LETTER GA;Lo;0;L;;;;;N;;;;;
+11C75;MARCHEN LETTER NGA;Lo;0;L;;;;;N;;;;;
+11C76;MARCHEN LETTER CA;Lo;0;L;;;;;N;;;;;
+11C77;MARCHEN LETTER CHA;Lo;0;L;;;;;N;;;;;
+11C78;MARCHEN LETTER JA;Lo;0;L;;;;;N;;;;;
+11C79;MARCHEN LETTER NYA;Lo;0;L;;;;;N;;;;;
+11C7A;MARCHEN LETTER TA;Lo;0;L;;;;;N;;;;;
+11C7B;MARCHEN LETTER THA;Lo;0;L;;;;;N;;;;;
+11C7C;MARCHEN LETTER DA;Lo;0;L;;;;;N;;;;;
+11C7D;MARCHEN LETTER NA;Lo;0;L;;;;;N;;;;;
+11C7E;MARCHEN LETTER PA;Lo;0;L;;;;;N;;;;;
+11C7F;MARCHEN LETTER PHA;Lo;0;L;;;;;N;;;;;
+11C80;MARCHEN LETTER BA;Lo;0;L;;;;;N;;;;;
+11C81;MARCHEN LETTER MA;Lo;0;L;;;;;N;;;;;
+11C82;MARCHEN LETTER TSA;Lo;0;L;;;;;N;;;;;
+11C83;MARCHEN LETTER TSHA;Lo;0;L;;;;;N;;;;;
+11C84;MARCHEN LETTER DZA;Lo;0;L;;;;;N;;;;;
+11C85;MARCHEN LETTER WA;Lo;0;L;;;;;N;;;;;
+11C86;MARCHEN LETTER ZHA;Lo;0;L;;;;;N;;;;;
+11C87;MARCHEN LETTER ZA;Lo;0;L;;;;;N;;;;;
+11C88;MARCHEN LETTER -A;Lo;0;L;;;;;N;;;;;
+11C89;MARCHEN LETTER YA;Lo;0;L;;;;;N;;;;;
+11C8A;MARCHEN LETTER RA;Lo;0;L;;;;;N;;;;;
+11C8B;MARCHEN LETTER LA;Lo;0;L;;;;;N;;;;;
+11C8C;MARCHEN LETTER SHA;Lo;0;L;;;;;N;;;;;
+11C8D;MARCHEN LETTER SA;Lo;0;L;;;;;N;;;;;
+11C8E;MARCHEN LETTER HA;Lo;0;L;;;;;N;;;;;
+11C8F;MARCHEN LETTER A;Lo;0;L;;;;;N;;;;;
+11C92;MARCHEN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;;
+11C93;MARCHEN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;;
+11C94;MARCHEN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;;
+11C95;MARCHEN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;;
+11C96;MARCHEN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;;
+11C97;MARCHEN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;;
+11C98;MARCHEN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;;
+11C99;MARCHEN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;;
+11C9A;MARCHEN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;;
+11C9B;MARCHEN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;;
+11C9C;MARCHEN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;;
+11C9D;MARCHEN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;;
+11C9E;MARCHEN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;;
+11C9F;MARCHEN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;;
+11CA0;MARCHEN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;;
+11CA1;MARCHEN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;;
+11CA2;MARCHEN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;;
+11CA3;MARCHEN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;;
+11CA4;MARCHEN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;;
+11CA5;MARCHEN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;;;;
+11CA6;MARCHEN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;;
+11CA7;MARCHEN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;;
+11CA9;MARCHEN SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;;
+11CAA;MARCHEN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;;;;
+11CAB;MARCHEN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;;
+11CAC;MARCHEN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;;
+11CAD;MARCHEN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;;
+11CAE;MARCHEN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;;
+11CAF;MARCHEN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;;
+11CB0;MARCHEN VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+11CB1;MARCHEN VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+11CB2;MARCHEN VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11CB3;MARCHEN VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11CB4;MARCHEN VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+11CB5;MARCHEN SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11CB6;MARCHEN SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;;
+12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;;
+12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;;
+12003;CUNEIFORM SIGN A TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12004;CUNEIFORM SIGN A TIMES HA;Lo;0;L;;;;;N;;;;;
+12005;CUNEIFORM SIGN A TIMES IGI;Lo;0;L;;;;;N;;;;;
+12006;CUNEIFORM SIGN A TIMES LAGAR GUNU;Lo;0;L;;;;;N;;;;;
+12007;CUNEIFORM SIGN A TIMES MUSH;Lo;0;L;;;;;N;;;;;
+12008;CUNEIFORM SIGN A TIMES SAG;Lo;0;L;;;;;N;;;;;
+12009;CUNEIFORM SIGN A2;Lo;0;L;;;;;N;;;;;
+1200A;CUNEIFORM SIGN AB;Lo;0;L;;;;;N;;;;;
+1200B;CUNEIFORM SIGN AB TIMES ASH2;Lo;0;L;;;;;N;;;;;
+1200C;CUNEIFORM SIGN AB TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;;
+1200D;CUNEIFORM SIGN AB TIMES GAL;Lo;0;L;;;;;N;;;;;
+1200E;CUNEIFORM SIGN AB TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1200F;CUNEIFORM SIGN AB TIMES HA;Lo;0;L;;;;;N;;;;;
+12010;CUNEIFORM SIGN AB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+12011;CUNEIFORM SIGN AB TIMES IMIN;Lo;0;L;;;;;N;;;;;
+12012;CUNEIFORM SIGN AB TIMES LAGAB;Lo;0;L;;;;;N;;;;;
+12013;CUNEIFORM SIGN AB TIMES SHESH;Lo;0;L;;;;;N;;;;;
+12014;CUNEIFORM SIGN AB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;
+12015;CUNEIFORM SIGN AB GUNU;Lo;0;L;;;;;N;;;;;
+12016;CUNEIFORM SIGN AB2;Lo;0;L;;;;;N;;;;;
+12017;CUNEIFORM SIGN AB2 TIMES BALAG;Lo;0;L;;;;;N;;;;;
+12018;CUNEIFORM SIGN AB2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12019;CUNEIFORM SIGN AB2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
+1201A;CUNEIFORM SIGN AB2 TIMES SHA3;Lo;0;L;;;;;N;;;;;
+1201B;CUNEIFORM SIGN AB2 TIMES TAK4;Lo;0;L;;;;;N;;;;;
+1201C;CUNEIFORM SIGN AD;Lo;0;L;;;;;N;;;;;
+1201D;CUNEIFORM SIGN AK;Lo;0;L;;;;;N;;;;;
+1201E;CUNEIFORM SIGN AK TIMES ERIN2;Lo;0;L;;;;;N;;;;;
+1201F;CUNEIFORM SIGN AK TIMES SHITA PLUS GISH;Lo;0;L;;;;;N;;;;;
+12020;CUNEIFORM SIGN AL;Lo;0;L;;;;;N;;;;;
+12021;CUNEIFORM SIGN AL TIMES AL;Lo;0;L;;;;;N;;;;;
+12022;CUNEIFORM SIGN AL TIMES DIM2;Lo;0;L;;;;;N;;;;;
+12023;CUNEIFORM SIGN AL TIMES GISH;Lo;0;L;;;;;N;;;;;
+12024;CUNEIFORM SIGN AL TIMES HA;Lo;0;L;;;;;N;;;;;
+12025;CUNEIFORM SIGN AL TIMES KAD3;Lo;0;L;;;;;N;;;;;
+12026;CUNEIFORM SIGN AL TIMES KI;Lo;0;L;;;;;N;;;;;
+12027;CUNEIFORM SIGN AL TIMES SHE;Lo;0;L;;;;;N;;;;;
+12028;CUNEIFORM SIGN AL TIMES USH;Lo;0;L;;;;;N;;;;;
+12029;CUNEIFORM SIGN ALAN;Lo;0;L;;;;;N;;;;;
+1202A;CUNEIFORM SIGN ALEPH;Lo;0;L;;;;;N;;;;;
+1202B;CUNEIFORM SIGN AMAR;Lo;0;L;;;;;N;;;;;
+1202C;CUNEIFORM SIGN AMAR TIMES SHE;Lo;0;L;;;;;N;;;;;
+1202D;CUNEIFORM SIGN AN;Lo;0;L;;;;;N;;;;;
+1202E;CUNEIFORM SIGN AN OVER AN;Lo;0;L;;;;;N;;;;;
+1202F;CUNEIFORM SIGN AN THREE TIMES;Lo;0;L;;;;;N;;;;;
+12030;CUNEIFORM SIGN AN PLUS NAGA OPPOSING AN PLUS NAGA;Lo;0;L;;;;;N;;;;;
+12031;CUNEIFORM SIGN AN PLUS NAGA SQUARED;Lo;0;L;;;;;N;;;;;
+12032;CUNEIFORM SIGN ANSHE;Lo;0;L;;;;;N;;;;;
+12033;CUNEIFORM SIGN APIN;Lo;0;L;;;;;N;;;;;
+12034;CUNEIFORM SIGN ARAD;Lo;0;L;;;;;N;;;;;
+12035;CUNEIFORM SIGN ARAD TIMES KUR;Lo;0;L;;;;;N;;;;;
+12036;CUNEIFORM SIGN ARKAB;Lo;0;L;;;;;N;;;;;
+12037;CUNEIFORM SIGN ASAL2;Lo;0;L;;;;;N;;;;;
+12038;CUNEIFORM SIGN ASH;Lo;0;L;;;;;N;;;;;
+12039;CUNEIFORM SIGN ASH ZIDA TENU;Lo;0;L;;;;;N;;;;;
+1203A;CUNEIFORM SIGN ASH KABA TENU;Lo;0;L;;;;;N;;;;;
+1203B;CUNEIFORM SIGN ASH OVER ASH TUG2 OVER TUG2 TUG2 OVER TUG2 PAP;Lo;0;L;;;;;N;;;;;
+1203C;CUNEIFORM SIGN ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;;
+1203D;CUNEIFORM SIGN ASH OVER ASH OVER ASH CROSSING ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;;
+1203E;CUNEIFORM SIGN ASH2;Lo;0;L;;;;;N;;;;;
+1203F;CUNEIFORM SIGN ASHGAB;Lo;0;L;;;;;N;;;;;
+12040;CUNEIFORM SIGN BA;Lo;0;L;;;;;N;;;;;
+12041;CUNEIFORM SIGN BAD;Lo;0;L;;;;;N;;;;;
+12042;CUNEIFORM SIGN BAG3;Lo;0;L;;;;;N;;;;;
+12043;CUNEIFORM SIGN BAHAR2;Lo;0;L;;;;;N;;;;;
+12044;CUNEIFORM SIGN BAL;Lo;0;L;;;;;N;;;;;
+12045;CUNEIFORM SIGN BAL OVER BAL;Lo;0;L;;;;;N;;;;;
+12046;CUNEIFORM SIGN BALAG;Lo;0;L;;;;;N;;;;;
+12047;CUNEIFORM SIGN BAR;Lo;0;L;;;;;N;;;;;
+12048;CUNEIFORM SIGN BARA2;Lo;0;L;;;;;N;;;;;
+12049;CUNEIFORM SIGN BI;Lo;0;L;;;;;N;;;;;
+1204A;CUNEIFORM SIGN BI TIMES A;Lo;0;L;;;;;N;;;;;
+1204B;CUNEIFORM SIGN BI TIMES GAR;Lo;0;L;;;;;N;;;;;
+1204C;CUNEIFORM SIGN BI TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+1204D;CUNEIFORM SIGN BU;Lo;0;L;;;;;N;;;;;
+1204E;CUNEIFORM SIGN BU OVER BU AB;Lo;0;L;;;;;N;;;;;
+1204F;CUNEIFORM SIGN BU OVER BU UN;Lo;0;L;;;;;N;;;;;
+12050;CUNEIFORM SIGN BU CROSSING BU;Lo;0;L;;;;;N;;;;;
+12051;CUNEIFORM SIGN BULUG;Lo;0;L;;;;;N;;;;;
+12052;CUNEIFORM SIGN BULUG OVER BULUG;Lo;0;L;;;;;N;;;;;
+12053;CUNEIFORM SIGN BUR;Lo;0;L;;;;;N;;;;;
+12054;CUNEIFORM SIGN BUR2;Lo;0;L;;;;;N;;;;;
+12055;CUNEIFORM SIGN DA;Lo;0;L;;;;;N;;;;;
+12056;CUNEIFORM SIGN DAG;Lo;0;L;;;;;N;;;;;
+12057;CUNEIFORM SIGN DAG KISIM5 TIMES A PLUS MASH;Lo;0;L;;;;;N;;;;;
+12058;CUNEIFORM SIGN DAG KISIM5 TIMES AMAR;Lo;0;L;;;;;N;;;;;
+12059;CUNEIFORM SIGN DAG KISIM5 TIMES BALAG;Lo;0;L;;;;;N;;;;;
+1205A;CUNEIFORM SIGN DAG KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;;
+1205B;CUNEIFORM SIGN DAG KISIM5 TIMES GA;Lo;0;L;;;;;N;;;;;
+1205C;CUNEIFORM SIGN DAG KISIM5 TIMES GA PLUS MASH;Lo;0;L;;;;;N;;;;;
+1205D;CUNEIFORM SIGN DAG KISIM5 TIMES GI;Lo;0;L;;;;;N;;;;;
+1205E;CUNEIFORM SIGN DAG KISIM5 TIMES GIR2;Lo;0;L;;;;;N;;;;;
+1205F;CUNEIFORM SIGN DAG KISIM5 TIMES GUD;Lo;0;L;;;;;N;;;;;
+12060;CUNEIFORM SIGN DAG KISIM5 TIMES HA;Lo;0;L;;;;;N;;;;;
+12061;CUNEIFORM SIGN DAG KISIM5 TIMES IR;Lo;0;L;;;;;N;;;;;
+12062;CUNEIFORM SIGN DAG KISIM5 TIMES IR PLUS LU;Lo;0;L;;;;;N;;;;;
+12063;CUNEIFORM SIGN DAG KISIM5 TIMES KAK;Lo;0;L;;;;;N;;;;;
+12064;CUNEIFORM SIGN DAG KISIM5 TIMES LA;Lo;0;L;;;;;N;;;;;
+12065;CUNEIFORM SIGN DAG KISIM5 TIMES LU;Lo;0;L;;;;;N;;;;;
+12066;CUNEIFORM SIGN DAG KISIM5 TIMES LU PLUS MASH2;Lo;0;L;;;;;N;;;;;
+12067;CUNEIFORM SIGN DAG KISIM5 TIMES LUM;Lo;0;L;;;;;N;;;;;
+12068;CUNEIFORM SIGN DAG KISIM5 TIMES NE;Lo;0;L;;;;;N;;;;;
+12069;CUNEIFORM SIGN DAG KISIM5 TIMES PAP PLUS PAP;Lo;0;L;;;;;N;;;;;
+1206A;CUNEIFORM SIGN DAG KISIM5 TIMES SI;Lo;0;L;;;;;N;;;;;
+1206B;CUNEIFORM SIGN DAG KISIM5 TIMES TAK4;Lo;0;L;;;;;N;;;;;
+1206C;CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS GIR2;Lo;0;L;;;;;N;;;;;
+1206D;CUNEIFORM SIGN DAG KISIM5 TIMES USH;Lo;0;L;;;;;N;;;;;
+1206E;CUNEIFORM SIGN DAM;Lo;0;L;;;;;N;;;;;
+1206F;CUNEIFORM SIGN DAR;Lo;0;L;;;;;N;;;;;
+12070;CUNEIFORM SIGN DARA3;Lo;0;L;;;;;N;;;;;
+12071;CUNEIFORM SIGN DARA4;Lo;0;L;;;;;N;;;;;
+12072;CUNEIFORM SIGN DI;Lo;0;L;;;;;N;;;;;
+12073;CUNEIFORM SIGN DIB;Lo;0;L;;;;;N;;;;;
+12074;CUNEIFORM SIGN DIM;Lo;0;L;;;;;N;;;;;
+12075;CUNEIFORM SIGN DIM TIMES SHE;Lo;0;L;;;;;N;;;;;
+12076;CUNEIFORM SIGN DIM2;Lo;0;L;;;;;N;;;;;
+12077;CUNEIFORM SIGN DIN;Lo;0;L;;;;;N;;;;;
+12078;CUNEIFORM SIGN DIN KASKAL U GUNU DISH;Lo;0;L;;;;;N;;;;;
+12079;CUNEIFORM SIGN DISH;Lo;0;L;;;;;N;;;;;
+1207A;CUNEIFORM SIGN DU;Lo;0;L;;;;;N;;;;;
+1207B;CUNEIFORM SIGN DU OVER DU;Lo;0;L;;;;;N;;;;;
+1207C;CUNEIFORM SIGN DU GUNU;Lo;0;L;;;;;N;;;;;
+1207D;CUNEIFORM SIGN DU SHESHIG;Lo;0;L;;;;;N;;;;;
+1207E;CUNEIFORM SIGN DUB;Lo;0;L;;;;;N;;;;;
+1207F;CUNEIFORM SIGN DUB TIMES ESH2;Lo;0;L;;;;;N;;;;;
+12080;CUNEIFORM SIGN DUB2;Lo;0;L;;;;;N;;;;;
+12081;CUNEIFORM SIGN DUG;Lo;0;L;;;;;N;;;;;
+12082;CUNEIFORM SIGN DUGUD;Lo;0;L;;;;;N;;;;;
+12083;CUNEIFORM SIGN DUH;Lo;0;L;;;;;N;;;;;
+12084;CUNEIFORM SIGN DUN;Lo;0;L;;;;;N;;;;;
+12085;CUNEIFORM SIGN DUN3;Lo;0;L;;;;;N;;;;;
+12086;CUNEIFORM SIGN DUN3 GUNU;Lo;0;L;;;;;N;;;;;
+12087;CUNEIFORM SIGN DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;;
+12088;CUNEIFORM SIGN DUN4;Lo;0;L;;;;;N;;;;;
+12089;CUNEIFORM SIGN DUR2;Lo;0;L;;;;;N;;;;;
+1208A;CUNEIFORM SIGN E;Lo;0;L;;;;;N;;;;;
+1208B;CUNEIFORM SIGN E TIMES PAP;Lo;0;L;;;;;N;;;;;
+1208C;CUNEIFORM SIGN E OVER E NUN OVER NUN;Lo;0;L;;;;;N;;;;;
+1208D;CUNEIFORM SIGN E2;Lo;0;L;;;;;N;;;;;
+1208E;CUNEIFORM SIGN E2 TIMES A PLUS HA PLUS DA;Lo;0;L;;;;;N;;;;;
+1208F;CUNEIFORM SIGN E2 TIMES GAR;Lo;0;L;;;;;N;;;;;
+12090;CUNEIFORM SIGN E2 TIMES MI;Lo;0;L;;;;;N;;;;;
+12091;CUNEIFORM SIGN E2 TIMES SAL;Lo;0;L;;;;;N;;;;;
+12092;CUNEIFORM SIGN E2 TIMES SHE;Lo;0;L;;;;;N;;;;;
+12093;CUNEIFORM SIGN E2 TIMES U;Lo;0;L;;;;;N;;;;;
+12094;CUNEIFORM SIGN EDIN;Lo;0;L;;;;;N;;;;;
+12095;CUNEIFORM SIGN EGIR;Lo;0;L;;;;;N;;;;;
+12096;CUNEIFORM SIGN EL;Lo;0;L;;;;;N;;;;;
+12097;CUNEIFORM SIGN EN;Lo;0;L;;;;;N;;;;;
+12098;CUNEIFORM SIGN EN TIMES GAN2;Lo;0;L;;;;;N;;;;;
+12099;CUNEIFORM SIGN EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1209A;CUNEIFORM SIGN EN TIMES ME;Lo;0;L;;;;;N;;;;;
+1209B;CUNEIFORM SIGN EN CROSSING EN;Lo;0;L;;;;;N;;;;;
+1209C;CUNEIFORM SIGN EN OPPOSING EN;Lo;0;L;;;;;N;;;;;
+1209D;CUNEIFORM SIGN EN SQUARED;Lo;0;L;;;;;N;;;;;
+1209E;CUNEIFORM SIGN EREN;Lo;0;L;;;;;N;;;;;
+1209F;CUNEIFORM SIGN ERIN2;Lo;0;L;;;;;N;;;;;
+120A0;CUNEIFORM SIGN ESH2;Lo;0;L;;;;;N;;;;;
+120A1;CUNEIFORM SIGN EZEN;Lo;0;L;;;;;N;;;;;
+120A2;CUNEIFORM SIGN EZEN TIMES A;Lo;0;L;;;;;N;;;;;
+120A3;CUNEIFORM SIGN EZEN TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;;
+120A4;CUNEIFORM SIGN EZEN TIMES A PLUS LAL TIMES LAL;Lo;0;L;;;;;N;;;;;
+120A5;CUNEIFORM SIGN EZEN TIMES AN;Lo;0;L;;;;;N;;;;;
+120A6;CUNEIFORM SIGN EZEN TIMES BAD;Lo;0;L;;;;;N;;;;;
+120A7;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;;
+120A8;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;;
+120A9;CUNEIFORM SIGN EZEN TIMES HA;Lo;0;L;;;;;N;;;;;
+120AA;CUNEIFORM SIGN EZEN TIMES HA GUNU;Lo;0;L;;;;;N;;;;;
+120AB;CUNEIFORM SIGN EZEN TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+120AC;CUNEIFORM SIGN EZEN TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+120AD;CUNEIFORM SIGN EZEN TIMES KASKAL SQUARED;Lo;0;L;;;;;N;;;;;
+120AE;CUNEIFORM SIGN EZEN TIMES KU3;Lo;0;L;;;;;N;;;;;
+120AF;CUNEIFORM SIGN EZEN TIMES LA;Lo;0;L;;;;;N;;;;;
+120B0;CUNEIFORM SIGN EZEN TIMES LAL TIMES LAL;Lo;0;L;;;;;N;;;;;
+120B1;CUNEIFORM SIGN EZEN TIMES LI;Lo;0;L;;;;;N;;;;;
+120B2;CUNEIFORM SIGN EZEN TIMES LU;Lo;0;L;;;;;N;;;;;
+120B3;CUNEIFORM SIGN EZEN TIMES U2;Lo;0;L;;;;;N;;;;;
+120B4;CUNEIFORM SIGN EZEN TIMES UD;Lo;0;L;;;;;N;;;;;
+120B5;CUNEIFORM SIGN GA;Lo;0;L;;;;;N;;;;;
+120B6;CUNEIFORM SIGN GA GUNU;Lo;0;L;;;;;N;;;;;
+120B7;CUNEIFORM SIGN GA2;Lo;0;L;;;;;N;;;;;
+120B8;CUNEIFORM SIGN GA2 TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;;
+120B9;CUNEIFORM SIGN GA2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;;
+120BA;CUNEIFORM SIGN GA2 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;;
+120BB;CUNEIFORM SIGN GA2 TIMES AB2 TENU PLUS TAB;Lo;0;L;;;;;N;;;;;
+120BC;CUNEIFORM SIGN GA2 TIMES AN;Lo;0;L;;;;;N;;;;;
+120BD;CUNEIFORM SIGN GA2 TIMES ASH;Lo;0;L;;;;;N;;;;;
+120BE;CUNEIFORM SIGN GA2 TIMES ASH2 PLUS GAL;Lo;0;L;;;;;N;;;;;
+120BF;CUNEIFORM SIGN GA2 TIMES BAD;Lo;0;L;;;;;N;;;;;
+120C0;CUNEIFORM SIGN GA2 TIMES BAR PLUS RA;Lo;0;L;;;;;N;;;;;
+120C1;CUNEIFORM SIGN GA2 TIMES BUR;Lo;0;L;;;;;N;;;;;
+120C2;CUNEIFORM SIGN GA2 TIMES BUR PLUS RA;Lo;0;L;;;;;N;;;;;
+120C3;CUNEIFORM SIGN GA2 TIMES DA;Lo;0;L;;;;;N;;;;;
+120C4;CUNEIFORM SIGN GA2 TIMES DI;Lo;0;L;;;;;N;;;;;
+120C5;CUNEIFORM SIGN GA2 TIMES DIM TIMES SHE;Lo;0;L;;;;;N;;;;;
+120C6;CUNEIFORM SIGN GA2 TIMES DUB;Lo;0;L;;;;;N;;;;;
+120C7;CUNEIFORM SIGN GA2 TIMES EL;Lo;0;L;;;;;N;;;;;
+120C8;CUNEIFORM SIGN GA2 TIMES EL PLUS LA;Lo;0;L;;;;;N;;;;;
+120C9;CUNEIFORM SIGN GA2 TIMES EN;Lo;0;L;;;;;N;;;;;
+120CA;CUNEIFORM SIGN GA2 TIMES EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+120CB;CUNEIFORM SIGN GA2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+120CC;CUNEIFORM SIGN GA2 TIMES GAR;Lo;0;L;;;;;N;;;;;
+120CD;CUNEIFORM SIGN GA2 TIMES GI;Lo;0;L;;;;;N;;;;;
+120CE;CUNEIFORM SIGN GA2 TIMES GI4;Lo;0;L;;;;;N;;;;;
+120CF;CUNEIFORM SIGN GA2 TIMES GI4 PLUS A;Lo;0;L;;;;;N;;;;;
+120D0;CUNEIFORM SIGN GA2 TIMES GIR2 PLUS SU;Lo;0;L;;;;;N;;;;;
+120D1;CUNEIFORM SIGN GA2 TIMES HA PLUS LU PLUS ESH2;Lo;0;L;;;;;N;;;;;
+120D2;CUNEIFORM SIGN GA2 TIMES HAL;Lo;0;L;;;;;N;;;;;
+120D3;CUNEIFORM SIGN GA2 TIMES HAL PLUS LA;Lo;0;L;;;;;N;;;;;
+120D4;CUNEIFORM SIGN GA2 TIMES HI PLUS LI;Lo;0;L;;;;;N;;;;;
+120D5;CUNEIFORM SIGN GA2 TIMES HUB2;Lo;0;L;;;;;N;;;;;
+120D6;CUNEIFORM SIGN GA2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+120D7;CUNEIFORM SIGN GA2 TIMES ISH PLUS HU PLUS ASH;Lo;0;L;;;;;N;;;;;
+120D8;CUNEIFORM SIGN GA2 TIMES KAK;Lo;0;L;;;;;N;;;;;
+120D9;CUNEIFORM SIGN GA2 TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+120DA;CUNEIFORM SIGN GA2 TIMES KID;Lo;0;L;;;;;N;;;;;
+120DB;CUNEIFORM SIGN GA2 TIMES KID PLUS LAL;Lo;0;L;;;;;N;;;;;
+120DC;CUNEIFORM SIGN GA2 TIMES KU3 PLUS AN;Lo;0;L;;;;;N;;;;;
+120DD;CUNEIFORM SIGN GA2 TIMES LA;Lo;0;L;;;;;N;;;;;
+120DE;CUNEIFORM SIGN GA2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
+120DF;CUNEIFORM SIGN GA2 TIMES MI;Lo;0;L;;;;;N;;;;;
+120E0;CUNEIFORM SIGN GA2 TIMES NUN;Lo;0;L;;;;;N;;;;;
+120E1;CUNEIFORM SIGN GA2 TIMES NUN OVER NUN;Lo;0;L;;;;;N;;;;;
+120E2;CUNEIFORM SIGN GA2 TIMES PA;Lo;0;L;;;;;N;;;;;
+120E3;CUNEIFORM SIGN GA2 TIMES SAL;Lo;0;L;;;;;N;;;;;
+120E4;CUNEIFORM SIGN GA2 TIMES SAR;Lo;0;L;;;;;N;;;;;
+120E5;CUNEIFORM SIGN GA2 TIMES SHE;Lo;0;L;;;;;N;;;;;
+120E6;CUNEIFORM SIGN GA2 TIMES SHE PLUS TUR;Lo;0;L;;;;;N;;;;;
+120E7;CUNEIFORM SIGN GA2 TIMES SHID;Lo;0;L;;;;;N;;;;;
+120E8;CUNEIFORM SIGN GA2 TIMES SUM;Lo;0;L;;;;;N;;;;;
+120E9;CUNEIFORM SIGN GA2 TIMES TAK4;Lo;0;L;;;;;N;;;;;
+120EA;CUNEIFORM SIGN GA2 TIMES U;Lo;0;L;;;;;N;;;;;
+120EB;CUNEIFORM SIGN GA2 TIMES UD;Lo;0;L;;;;;N;;;;;
+120EC;CUNEIFORM SIGN GA2 TIMES UD PLUS DU;Lo;0;L;;;;;N;;;;;
+120ED;CUNEIFORM SIGN GA2 OVER GA2;Lo;0;L;;;;;N;;;;;
+120EE;CUNEIFORM SIGN GABA;Lo;0;L;;;;;N;;;;;
+120EF;CUNEIFORM SIGN GABA CROSSING GABA;Lo;0;L;;;;;N;;;;;
+120F0;CUNEIFORM SIGN GAD;Lo;0;L;;;;;N;;;;;
+120F1;CUNEIFORM SIGN GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+120F2;CUNEIFORM SIGN GAL;Lo;0;L;;;;;N;;;;;
+120F3;CUNEIFORM SIGN GAL GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+120F4;CUNEIFORM SIGN GALAM;Lo;0;L;;;;;N;;;;;
+120F5;CUNEIFORM SIGN GAM;Lo;0;L;;;;;N;;;;;
+120F6;CUNEIFORM SIGN GAN;Lo;0;L;;;;;N;;;;;
+120F7;CUNEIFORM SIGN GAN2;Lo;0;L;;;;;N;;;;;
+120F8;CUNEIFORM SIGN GAN2 TENU;Lo;0;L;;;;;N;;;;;
+120F9;CUNEIFORM SIGN GAN2 OVER GAN2;Lo;0;L;;;;;N;;;;;
+120FA;CUNEIFORM SIGN GAN2 CROSSING GAN2;Lo;0;L;;;;;N;;;;;
+120FB;CUNEIFORM SIGN GAR;Lo;0;L;;;;;N;;;;;
+120FC;CUNEIFORM SIGN GAR3;Lo;0;L;;;;;N;;;;;
+120FD;CUNEIFORM SIGN GASHAN;Lo;0;L;;;;;N;;;;;
+120FE;CUNEIFORM SIGN GESHTIN;Lo;0;L;;;;;N;;;;;
+120FF;CUNEIFORM SIGN GESHTIN TIMES KUR;Lo;0;L;;;;;N;;;;;
+12100;CUNEIFORM SIGN GI;Lo;0;L;;;;;N;;;;;
+12101;CUNEIFORM SIGN GI TIMES E;Lo;0;L;;;;;N;;;;;
+12102;CUNEIFORM SIGN GI TIMES U;Lo;0;L;;;;;N;;;;;
+12103;CUNEIFORM SIGN GI CROSSING GI;Lo;0;L;;;;;N;;;;;
+12104;CUNEIFORM SIGN GI4;Lo;0;L;;;;;N;;;;;
+12105;CUNEIFORM SIGN GI4 OVER GI4;Lo;0;L;;;;;N;;;;;
+12106;CUNEIFORM SIGN GI4 CROSSING GI4;Lo;0;L;;;;;N;;;;;
+12107;CUNEIFORM SIGN GIDIM;Lo;0;L;;;;;N;;;;;
+12108;CUNEIFORM SIGN GIR2;Lo;0;L;;;;;N;;;;;
+12109;CUNEIFORM SIGN GIR2 GUNU;Lo;0;L;;;;;N;;;;;
+1210A;CUNEIFORM SIGN GIR3;Lo;0;L;;;;;N;;;;;
+1210B;CUNEIFORM SIGN GIR3 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;;
+1210C;CUNEIFORM SIGN GIR3 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1210D;CUNEIFORM SIGN GIR3 TIMES IGI;Lo;0;L;;;;;N;;;;;
+1210E;CUNEIFORM SIGN GIR3 TIMES LU PLUS IGI;Lo;0;L;;;;;N;;;;;
+1210F;CUNEIFORM SIGN GIR3 TIMES PA;Lo;0;L;;;;;N;;;;;
+12110;CUNEIFORM SIGN GISAL;Lo;0;L;;;;;N;;;;;
+12111;CUNEIFORM SIGN GISH;Lo;0;L;;;;;N;;;;;
+12112;CUNEIFORM SIGN GISH CROSSING GISH;Lo;0;L;;;;;N;;;;;
+12113;CUNEIFORM SIGN GISH TIMES BAD;Lo;0;L;;;;;N;;;;;
+12114;CUNEIFORM SIGN GISH TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12115;CUNEIFORM SIGN GISH TENU;Lo;0;L;;;;;N;;;;;
+12116;CUNEIFORM SIGN GU;Lo;0;L;;;;;N;;;;;
+12117;CUNEIFORM SIGN GU CROSSING GU;Lo;0;L;;;;;N;;;;;
+12118;CUNEIFORM SIGN GU2;Lo;0;L;;;;;N;;;;;
+12119;CUNEIFORM SIGN GU2 TIMES KAK;Lo;0;L;;;;;N;;;;;
+1211A;CUNEIFORM SIGN GU2 TIMES KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+1211B;CUNEIFORM SIGN GU2 TIMES NUN;Lo;0;L;;;;;N;;;;;
+1211C;CUNEIFORM SIGN GU2 TIMES SAL PLUS TUG2;Lo;0;L;;;;;N;;;;;
+1211D;CUNEIFORM SIGN GU2 GUNU;Lo;0;L;;;;;N;;;;;
+1211E;CUNEIFORM SIGN GUD;Lo;0;L;;;;;N;;;;;
+1211F;CUNEIFORM SIGN GUD TIMES A PLUS KUR;Lo;0;L;;;;;N;;;;;
+12120;CUNEIFORM SIGN GUD TIMES KUR;Lo;0;L;;;;;N;;;;;
+12121;CUNEIFORM SIGN GUD OVER GUD LUGAL;Lo;0;L;;;;;N;;;;;
+12122;CUNEIFORM SIGN GUL;Lo;0;L;;;;;N;;;;;
+12123;CUNEIFORM SIGN GUM;Lo;0;L;;;;;N;;;;;
+12124;CUNEIFORM SIGN GUM TIMES SHE;Lo;0;L;;;;;N;;;;;
+12125;CUNEIFORM SIGN GUR;Lo;0;L;;;;;N;;;;;
+12126;CUNEIFORM SIGN GUR7;Lo;0;L;;;;;N;;;;;
+12127;CUNEIFORM SIGN GURUN;Lo;0;L;;;;;N;;;;;
+12128;CUNEIFORM SIGN GURUSH;Lo;0;L;;;;;N;;;;;
+12129;CUNEIFORM SIGN HA;Lo;0;L;;;;;N;;;;;
+1212A;CUNEIFORM SIGN HA TENU;Lo;0;L;;;;;N;;;;;
+1212B;CUNEIFORM SIGN HA GUNU;Lo;0;L;;;;;N;;;;;
+1212C;CUNEIFORM SIGN HAL;Lo;0;L;;;;;N;;;;;
+1212D;CUNEIFORM SIGN HI;Lo;0;L;;;;;N;;;;;
+1212E;CUNEIFORM SIGN HI TIMES ASH;Lo;0;L;;;;;N;;;;;
+1212F;CUNEIFORM SIGN HI TIMES ASH2;Lo;0;L;;;;;N;;;;;
+12130;CUNEIFORM SIGN HI TIMES BAD;Lo;0;L;;;;;N;;;;;
+12131;CUNEIFORM SIGN HI TIMES DISH;Lo;0;L;;;;;N;;;;;
+12132;CUNEIFORM SIGN HI TIMES GAD;Lo;0;L;;;;;N;;;;;
+12133;CUNEIFORM SIGN HI TIMES KIN;Lo;0;L;;;;;N;;;;;
+12134;CUNEIFORM SIGN HI TIMES NUN;Lo;0;L;;;;;N;;;;;
+12135;CUNEIFORM SIGN HI TIMES SHE;Lo;0;L;;;;;N;;;;;
+12136;CUNEIFORM SIGN HI TIMES U;Lo;0;L;;;;;N;;;;;
+12137;CUNEIFORM SIGN HU;Lo;0;L;;;;;N;;;;;
+12138;CUNEIFORM SIGN HUB2;Lo;0;L;;;;;N;;;;;
+12139;CUNEIFORM SIGN HUB2 TIMES AN;Lo;0;L;;;;;N;;;;;
+1213A;CUNEIFORM SIGN HUB2 TIMES HAL;Lo;0;L;;;;;N;;;;;
+1213B;CUNEIFORM SIGN HUB2 TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+1213C;CUNEIFORM SIGN HUB2 TIMES LISH;Lo;0;L;;;;;N;;;;;
+1213D;CUNEIFORM SIGN HUB2 TIMES UD;Lo;0;L;;;;;N;;;;;
+1213E;CUNEIFORM SIGN HUL2;Lo;0;L;;;;;N;;;;;
+1213F;CUNEIFORM SIGN I;Lo;0;L;;;;;N;;;;;
+12140;CUNEIFORM SIGN I A;Lo;0;L;;;;;N;;;;;
+12141;CUNEIFORM SIGN IB;Lo;0;L;;;;;N;;;;;
+12142;CUNEIFORM SIGN IDIM;Lo;0;L;;;;;N;;;;;
+12143;CUNEIFORM SIGN IDIM OVER IDIM BUR;Lo;0;L;;;;;N;;;;;
+12144;CUNEIFORM SIGN IDIM OVER IDIM SQUARED;Lo;0;L;;;;;N;;;;;
+12145;CUNEIFORM SIGN IG;Lo;0;L;;;;;N;;;;;
+12146;CUNEIFORM SIGN IGI;Lo;0;L;;;;;N;;;;;
+12147;CUNEIFORM SIGN IGI DIB;Lo;0;L;;;;;N;;;;;
+12148;CUNEIFORM SIGN IGI RI;Lo;0;L;;;;;N;;;;;
+12149;CUNEIFORM SIGN IGI OVER IGI SHIR OVER SHIR UD OVER UD;Lo;0;L;;;;;N;;;;;
+1214A;CUNEIFORM SIGN IGI GUNU;Lo;0;L;;;;;N;;;;;
+1214B;CUNEIFORM SIGN IL;Lo;0;L;;;;;N;;;;;
+1214C;CUNEIFORM SIGN IL TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1214D;CUNEIFORM SIGN IL2;Lo;0;L;;;;;N;;;;;
+1214E;CUNEIFORM SIGN IM;Lo;0;L;;;;;N;;;;;
+1214F;CUNEIFORM SIGN IM TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12150;CUNEIFORM SIGN IM CROSSING IM;Lo;0;L;;;;;N;;;;;
+12151;CUNEIFORM SIGN IM OPPOSING IM;Lo;0;L;;;;;N;;;;;
+12152;CUNEIFORM SIGN IM SQUARED;Lo;0;L;;;;;N;;;;;
+12153;CUNEIFORM SIGN IMIN;Lo;0;L;;;;;N;;;;;
+12154;CUNEIFORM SIGN IN;Lo;0;L;;;;;N;;;;;
+12155;CUNEIFORM SIGN IR;Lo;0;L;;;;;N;;;;;
+12156;CUNEIFORM SIGN ISH;Lo;0;L;;;;;N;;;;;
+12157;CUNEIFORM SIGN KA;Lo;0;L;;;;;N;;;;;
+12158;CUNEIFORM SIGN KA TIMES A;Lo;0;L;;;;;N;;;;;
+12159;CUNEIFORM SIGN KA TIMES AD;Lo;0;L;;;;;N;;;;;
+1215A;CUNEIFORM SIGN KA TIMES AD PLUS KU3;Lo;0;L;;;;;N;;;;;
+1215B;CUNEIFORM SIGN KA TIMES ASH2;Lo;0;L;;;;;N;;;;;
+1215C;CUNEIFORM SIGN KA TIMES BAD;Lo;0;L;;;;;N;;;;;
+1215D;CUNEIFORM SIGN KA TIMES BALAG;Lo;0;L;;;;;N;;;;;
+1215E;CUNEIFORM SIGN KA TIMES BAR;Lo;0;L;;;;;N;;;;;
+1215F;CUNEIFORM SIGN KA TIMES BI;Lo;0;L;;;;;N;;;;;
+12160;CUNEIFORM SIGN KA TIMES ERIN2;Lo;0;L;;;;;N;;;;;
+12161;CUNEIFORM SIGN KA TIMES ESH2;Lo;0;L;;;;;N;;;;;
+12162;CUNEIFORM SIGN KA TIMES GA;Lo;0;L;;;;;N;;;;;
+12163;CUNEIFORM SIGN KA TIMES GAL;Lo;0;L;;;;;N;;;;;
+12164;CUNEIFORM SIGN KA TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12165;CUNEIFORM SIGN KA TIMES GAR;Lo;0;L;;;;;N;;;;;
+12166;CUNEIFORM SIGN KA TIMES GAR PLUS SHA3 PLUS A;Lo;0;L;;;;;N;;;;;
+12167;CUNEIFORM SIGN KA TIMES GI;Lo;0;L;;;;;N;;;;;
+12168;CUNEIFORM SIGN KA TIMES GIR2;Lo;0;L;;;;;N;;;;;
+12169;CUNEIFORM SIGN KA TIMES GISH PLUS SAR;Lo;0;L;;;;;N;;;;;
+1216A;CUNEIFORM SIGN KA TIMES GISH CROSSING GISH;Lo;0;L;;;;;N;;;;;
+1216B;CUNEIFORM SIGN KA TIMES GU;Lo;0;L;;;;;N;;;;;
+1216C;CUNEIFORM SIGN KA TIMES GUR7;Lo;0;L;;;;;N;;;;;
+1216D;CUNEIFORM SIGN KA TIMES IGI;Lo;0;L;;;;;N;;;;;
+1216E;CUNEIFORM SIGN KA TIMES IM;Lo;0;L;;;;;N;;;;;
+1216F;CUNEIFORM SIGN KA TIMES KAK;Lo;0;L;;;;;N;;;;;
+12170;CUNEIFORM SIGN KA TIMES KI;Lo;0;L;;;;;N;;;;;
+12171;CUNEIFORM SIGN KA TIMES KID;Lo;0;L;;;;;N;;;;;
+12172;CUNEIFORM SIGN KA TIMES LI;Lo;0;L;;;;;N;;;;;
+12173;CUNEIFORM SIGN KA TIMES LU;Lo;0;L;;;;;N;;;;;
+12174;CUNEIFORM SIGN KA TIMES ME;Lo;0;L;;;;;N;;;;;
+12175;CUNEIFORM SIGN KA TIMES ME PLUS DU;Lo;0;L;;;;;N;;;;;
+12176;CUNEIFORM SIGN KA TIMES ME PLUS GI;Lo;0;L;;;;;N;;;;;
+12177;CUNEIFORM SIGN KA TIMES ME PLUS TE;Lo;0;L;;;;;N;;;;;
+12178;CUNEIFORM SIGN KA TIMES MI;Lo;0;L;;;;;N;;;;;
+12179;CUNEIFORM SIGN KA TIMES MI PLUS NUNUZ;Lo;0;L;;;;;N;;;;;
+1217A;CUNEIFORM SIGN KA TIMES NE;Lo;0;L;;;;;N;;;;;
+1217B;CUNEIFORM SIGN KA TIMES NUN;Lo;0;L;;;;;N;;;;;
+1217C;CUNEIFORM SIGN KA TIMES PI;Lo;0;L;;;;;N;;;;;
+1217D;CUNEIFORM SIGN KA TIMES RU;Lo;0;L;;;;;N;;;;;
+1217E;CUNEIFORM SIGN KA TIMES SA;Lo;0;L;;;;;N;;;;;
+1217F;CUNEIFORM SIGN KA TIMES SAR;Lo;0;L;;;;;N;;;;;
+12180;CUNEIFORM SIGN KA TIMES SHA;Lo;0;L;;;;;N;;;;;
+12181;CUNEIFORM SIGN KA TIMES SHE;Lo;0;L;;;;;N;;;;;
+12182;CUNEIFORM SIGN KA TIMES SHID;Lo;0;L;;;;;N;;;;;
+12183;CUNEIFORM SIGN KA TIMES SHU;Lo;0;L;;;;;N;;;;;
+12184;CUNEIFORM SIGN KA TIMES SIG;Lo;0;L;;;;;N;;;;;
+12185;CUNEIFORM SIGN KA TIMES SUHUR;Lo;0;L;;;;;N;;;;;
+12186;CUNEIFORM SIGN KA TIMES TAR;Lo;0;L;;;;;N;;;;;
+12187;CUNEIFORM SIGN KA TIMES U;Lo;0;L;;;;;N;;;;;
+12188;CUNEIFORM SIGN KA TIMES U2;Lo;0;L;;;;;N;;;;;
+12189;CUNEIFORM SIGN KA TIMES UD;Lo;0;L;;;;;N;;;;;
+1218A;CUNEIFORM SIGN KA TIMES UMUM TIMES PA;Lo;0;L;;;;;N;;;;;
+1218B;CUNEIFORM SIGN KA TIMES USH;Lo;0;L;;;;;N;;;;;
+1218C;CUNEIFORM SIGN KA TIMES ZI;Lo;0;L;;;;;N;;;;;
+1218D;CUNEIFORM SIGN KA2;Lo;0;L;;;;;N;;;;;
+1218E;CUNEIFORM SIGN KA2 CROSSING KA2;Lo;0;L;;;;;N;;;;;
+1218F;CUNEIFORM SIGN KAB;Lo;0;L;;;;;N;;;;;
+12190;CUNEIFORM SIGN KAD2;Lo;0;L;;;;;N;;;;;
+12191;CUNEIFORM SIGN KAD3;Lo;0;L;;;;;N;;;;;
+12192;CUNEIFORM SIGN KAD4;Lo;0;L;;;;;N;;;;;
+12193;CUNEIFORM SIGN KAD5;Lo;0;L;;;;;N;;;;;
+12194;CUNEIFORM SIGN KAD5 OVER KAD5;Lo;0;L;;;;;N;;;;;
+12195;CUNEIFORM SIGN KAK;Lo;0;L;;;;;N;;;;;
+12196;CUNEIFORM SIGN KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+12197;CUNEIFORM SIGN KAL;Lo;0;L;;;;;N;;;;;
+12198;CUNEIFORM SIGN KAL TIMES BAD;Lo;0;L;;;;;N;;;;;
+12199;CUNEIFORM SIGN KAL CROSSING KAL;Lo;0;L;;;;;N;;;;;
+1219A;CUNEIFORM SIGN KAM2;Lo;0;L;;;;;N;;;;;
+1219B;CUNEIFORM SIGN KAM4;Lo;0;L;;;;;N;;;;;
+1219C;CUNEIFORM SIGN KASKAL;Lo;0;L;;;;;N;;;;;
+1219D;CUNEIFORM SIGN KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;;
+1219E;CUNEIFORM SIGN KASKAL OVER KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;;
+1219F;CUNEIFORM SIGN KESH2;Lo;0;L;;;;;N;;;;;
+121A0;CUNEIFORM SIGN KI;Lo;0;L;;;;;N;;;;;
+121A1;CUNEIFORM SIGN KI TIMES BAD;Lo;0;L;;;;;N;;;;;
+121A2;CUNEIFORM SIGN KI TIMES U;Lo;0;L;;;;;N;;;;;
+121A3;CUNEIFORM SIGN KI TIMES UD;Lo;0;L;;;;;N;;;;;
+121A4;CUNEIFORM SIGN KID;Lo;0;L;;;;;N;;;;;
+121A5;CUNEIFORM SIGN KIN;Lo;0;L;;;;;N;;;;;
+121A6;CUNEIFORM SIGN KISAL;Lo;0;L;;;;;N;;;;;
+121A7;CUNEIFORM SIGN KISH;Lo;0;L;;;;;N;;;;;
+121A8;CUNEIFORM SIGN KISIM5;Lo;0;L;;;;;N;;;;;
+121A9;CUNEIFORM SIGN KISIM5 OVER KISIM5;Lo;0;L;;;;;N;;;;;
+121AA;CUNEIFORM SIGN KU;Lo;0;L;;;;;N;;;;;
+121AB;CUNEIFORM SIGN KU OVER HI TIMES ASH2 KU OVER HI TIMES ASH2;Lo;0;L;;;;;N;;;;;
+121AC;CUNEIFORM SIGN KU3;Lo;0;L;;;;;N;;;;;
+121AD;CUNEIFORM SIGN KU4;Lo;0;L;;;;;N;;;;;
+121AE;CUNEIFORM SIGN KU4 VARIANT FORM;Lo;0;L;;;;;N;;;;;
+121AF;CUNEIFORM SIGN KU7;Lo;0;L;;;;;N;;;;;
+121B0;CUNEIFORM SIGN KUL;Lo;0;L;;;;;N;;;;;
+121B1;CUNEIFORM SIGN KUL GUNU;Lo;0;L;;;;;N;;;;;
+121B2;CUNEIFORM SIGN KUN;Lo;0;L;;;;;N;;;;;
+121B3;CUNEIFORM SIGN KUR;Lo;0;L;;;;;N;;;;;
+121B4;CUNEIFORM SIGN KUR OPPOSING KUR;Lo;0;L;;;;;N;;;;;
+121B5;CUNEIFORM SIGN KUSHU2;Lo;0;L;;;;;N;;;;;
+121B6;CUNEIFORM SIGN KWU318;Lo;0;L;;;;;N;;;;;
+121B7;CUNEIFORM SIGN LA;Lo;0;L;;;;;N;;;;;
+121B8;CUNEIFORM SIGN LAGAB;Lo;0;L;;;;;N;;;;;
+121B9;CUNEIFORM SIGN LAGAB TIMES A;Lo;0;L;;;;;N;;;;;
+121BA;CUNEIFORM SIGN LAGAB TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;;
+121BB;CUNEIFORM SIGN LAGAB TIMES A PLUS GAR;Lo;0;L;;;;;N;;;;;
+121BC;CUNEIFORM SIGN LAGAB TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;;
+121BD;CUNEIFORM SIGN LAGAB TIMES AL;Lo;0;L;;;;;N;;;;;
+121BE;CUNEIFORM SIGN LAGAB TIMES AN;Lo;0;L;;;;;N;;;;;
+121BF;CUNEIFORM SIGN LAGAB TIMES ASH ZIDA TENU;Lo;0;L;;;;;N;;;;;
+121C0;CUNEIFORM SIGN LAGAB TIMES BAD;Lo;0;L;;;;;N;;;;;
+121C1;CUNEIFORM SIGN LAGAB TIMES BI;Lo;0;L;;;;;N;;;;;
+121C2;CUNEIFORM SIGN LAGAB TIMES DAR;Lo;0;L;;;;;N;;;;;
+121C3;CUNEIFORM SIGN LAGAB TIMES EN;Lo;0;L;;;;;N;;;;;
+121C4;CUNEIFORM SIGN LAGAB TIMES GA;Lo;0;L;;;;;N;;;;;
+121C5;CUNEIFORM SIGN LAGAB TIMES GAR;Lo;0;L;;;;;N;;;;;
+121C6;CUNEIFORM SIGN LAGAB TIMES GUD;Lo;0;L;;;;;N;;;;;
+121C7;CUNEIFORM SIGN LAGAB TIMES GUD PLUS GUD;Lo;0;L;;;;;N;;;;;
+121C8;CUNEIFORM SIGN LAGAB TIMES HA;Lo;0;L;;;;;N;;;;;
+121C9;CUNEIFORM SIGN LAGAB TIMES HAL;Lo;0;L;;;;;N;;;;;
+121CA;CUNEIFORM SIGN LAGAB TIMES HI TIMES NUN;Lo;0;L;;;;;N;;;;;
+121CB;CUNEIFORM SIGN LAGAB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+121CC;CUNEIFORM SIGN LAGAB TIMES IM;Lo;0;L;;;;;N;;;;;
+121CD;CUNEIFORM SIGN LAGAB TIMES IM PLUS HA;Lo;0;L;;;;;N;;;;;
+121CE;CUNEIFORM SIGN LAGAB TIMES IM PLUS LU;Lo;0;L;;;;;N;;;;;
+121CF;CUNEIFORM SIGN LAGAB TIMES KI;Lo;0;L;;;;;N;;;;;
+121D0;CUNEIFORM SIGN LAGAB TIMES KIN;Lo;0;L;;;;;N;;;;;
+121D1;CUNEIFORM SIGN LAGAB TIMES KU3;Lo;0;L;;;;;N;;;;;
+121D2;CUNEIFORM SIGN LAGAB TIMES KUL;Lo;0;L;;;;;N;;;;;
+121D3;CUNEIFORM SIGN LAGAB TIMES KUL PLUS HI PLUS A;Lo;0;L;;;;;N;;;;;
+121D4;CUNEIFORM SIGN LAGAB TIMES LAGAB;Lo;0;L;;;;;N;;;;;
+121D5;CUNEIFORM SIGN LAGAB TIMES LISH;Lo;0;L;;;;;N;;;;;
+121D6;CUNEIFORM SIGN LAGAB TIMES LU;Lo;0;L;;;;;N;;;;;
+121D7;CUNEIFORM SIGN LAGAB TIMES LUL;Lo;0;L;;;;;N;;;;;
+121D8;CUNEIFORM SIGN LAGAB TIMES ME;Lo;0;L;;;;;N;;;;;
+121D9;CUNEIFORM SIGN LAGAB TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
+121DA;CUNEIFORM SIGN LAGAB TIMES MUSH;Lo;0;L;;;;;N;;;;;
+121DB;CUNEIFORM SIGN LAGAB TIMES NE;Lo;0;L;;;;;N;;;;;
+121DC;CUNEIFORM SIGN LAGAB TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;;
+121DD;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH PLUS ERIN2;Lo;0;L;;;;;N;;;;;
+121DE;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH TENU;Lo;0;L;;;;;N;;;;;
+121DF;CUNEIFORM SIGN LAGAB TIMES SHU2;Lo;0;L;;;;;N;;;;;
+121E0;CUNEIFORM SIGN LAGAB TIMES SHU2 PLUS SHU2;Lo;0;L;;;;;N;;;;;
+121E1;CUNEIFORM SIGN LAGAB TIMES SUM;Lo;0;L;;;;;N;;;;;
+121E2;CUNEIFORM SIGN LAGAB TIMES TAG;Lo;0;L;;;;;N;;;;;
+121E3;CUNEIFORM SIGN LAGAB TIMES TAK4;Lo;0;L;;;;;N;;;;;
+121E4;CUNEIFORM SIGN LAGAB TIMES TE PLUS A PLUS SU PLUS NA;Lo;0;L;;;;;N;;;;;
+121E5;CUNEIFORM SIGN LAGAB TIMES U;Lo;0;L;;;;;N;;;;;
+121E6;CUNEIFORM SIGN LAGAB TIMES U PLUS A;Lo;0;L;;;;;N;;;;;
+121E7;CUNEIFORM SIGN LAGAB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;
+121E8;CUNEIFORM SIGN LAGAB TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;
+121E9;CUNEIFORM SIGN LAGAB TIMES UD;Lo;0;L;;;;;N;;;;;
+121EA;CUNEIFORM SIGN LAGAB TIMES USH;Lo;0;L;;;;;N;;;;;
+121EB;CUNEIFORM SIGN LAGAB SQUARED;Lo;0;L;;;;;N;;;;;
+121EC;CUNEIFORM SIGN LAGAR;Lo;0;L;;;;;N;;;;;
+121ED;CUNEIFORM SIGN LAGAR TIMES SHE;Lo;0;L;;;;;N;;;;;
+121EE;CUNEIFORM SIGN LAGAR TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;;
+121EF;CUNEIFORM SIGN LAGAR GUNU;Lo;0;L;;;;;N;;;;;
+121F0;CUNEIFORM SIGN LAGAR GUNU OVER LAGAR GUNU SHE;Lo;0;L;;;;;N;;;;;
+121F1;CUNEIFORM SIGN LAHSHU;Lo;0;L;;;;;N;;;;;
+121F2;CUNEIFORM SIGN LAL;Lo;0;L;;;;;N;;;;;
+121F3;CUNEIFORM SIGN LAL TIMES LAL;Lo;0;L;;;;;N;;;;;
+121F4;CUNEIFORM SIGN LAM;Lo;0;L;;;;;N;;;;;
+121F5;CUNEIFORM SIGN LAM TIMES KUR;Lo;0;L;;;;;N;;;;;
+121F6;CUNEIFORM SIGN LAM TIMES KUR PLUS RU;Lo;0;L;;;;;N;;;;;
+121F7;CUNEIFORM SIGN LI;Lo;0;L;;;;;N;;;;;
+121F8;CUNEIFORM SIGN LIL;Lo;0;L;;;;;N;;;;;
+121F9;CUNEIFORM SIGN LIMMU2;Lo;0;L;;;;;N;;;;;
+121FA;CUNEIFORM SIGN LISH;Lo;0;L;;;;;N;;;;;
+121FB;CUNEIFORM SIGN LU;Lo;0;L;;;;;N;;;;;
+121FC;CUNEIFORM SIGN LU TIMES BAD;Lo;0;L;;;;;N;;;;;
+121FD;CUNEIFORM SIGN LU2;Lo;0;L;;;;;N;;;;;
+121FE;CUNEIFORM SIGN LU2 TIMES AL;Lo;0;L;;;;;N;;;;;
+121FF;CUNEIFORM SIGN LU2 TIMES BAD;Lo;0;L;;;;;N;;;;;
+12200;CUNEIFORM SIGN LU2 TIMES ESH2;Lo;0;L;;;;;N;;;;;
+12201;CUNEIFORM SIGN LU2 TIMES ESH2 TENU;Lo;0;L;;;;;N;;;;;
+12202;CUNEIFORM SIGN LU2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12203;CUNEIFORM SIGN LU2 TIMES HI TIMES BAD;Lo;0;L;;;;;N;;;;;
+12204;CUNEIFORM SIGN LU2 TIMES IM;Lo;0;L;;;;;N;;;;;
+12205;CUNEIFORM SIGN LU2 TIMES KAD2;Lo;0;L;;;;;N;;;;;
+12206;CUNEIFORM SIGN LU2 TIMES KAD3;Lo;0;L;;;;;N;;;;;
+12207;CUNEIFORM SIGN LU2 TIMES KAD3 PLUS ASH;Lo;0;L;;;;;N;;;;;
+12208;CUNEIFORM SIGN LU2 TIMES KI;Lo;0;L;;;;;N;;;;;
+12209;CUNEIFORM SIGN LU2 TIMES LA PLUS ASH;Lo;0;L;;;;;N;;;;;
+1220A;CUNEIFORM SIGN LU2 TIMES LAGAB;Lo;0;L;;;;;N;;;;;
+1220B;CUNEIFORM SIGN LU2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
+1220C;CUNEIFORM SIGN LU2 TIMES NE;Lo;0;L;;;;;N;;;;;
+1220D;CUNEIFORM SIGN LU2 TIMES NU;Lo;0;L;;;;;N;;;;;
+1220E;CUNEIFORM SIGN LU2 TIMES SI PLUS ASH;Lo;0;L;;;;;N;;;;;
+1220F;CUNEIFORM SIGN LU2 TIMES SIK2 PLUS BU;Lo;0;L;;;;;N;;;;;
+12210;CUNEIFORM SIGN LU2 TIMES TUG2;Lo;0;L;;;;;N;;;;;
+12211;CUNEIFORM SIGN LU2 TENU;Lo;0;L;;;;;N;;;;;
+12212;CUNEIFORM SIGN LU2 CROSSING LU2;Lo;0;L;;;;;N;;;;;
+12213;CUNEIFORM SIGN LU2 OPPOSING LU2;Lo;0;L;;;;;N;;;;;
+12214;CUNEIFORM SIGN LU2 SQUARED;Lo;0;L;;;;;N;;;;;
+12215;CUNEIFORM SIGN LU2 SHESHIG;Lo;0;L;;;;;N;;;;;
+12216;CUNEIFORM SIGN LU3;Lo;0;L;;;;;N;;;;;
+12217;CUNEIFORM SIGN LUGAL;Lo;0;L;;;;;N;;;;;
+12218;CUNEIFORM SIGN LUGAL OVER LUGAL;Lo;0;L;;;;;N;;;;;
+12219;CUNEIFORM SIGN LUGAL OPPOSING LUGAL;Lo;0;L;;;;;N;;;;;
+1221A;CUNEIFORM SIGN LUGAL SHESHIG;Lo;0;L;;;;;N;;;;;
+1221B;CUNEIFORM SIGN LUH;Lo;0;L;;;;;N;;;;;
+1221C;CUNEIFORM SIGN LUL;Lo;0;L;;;;;N;;;;;
+1221D;CUNEIFORM SIGN LUM;Lo;0;L;;;;;N;;;;;
+1221E;CUNEIFORM SIGN LUM OVER LUM;Lo;0;L;;;;;N;;;;;
+1221F;CUNEIFORM SIGN LUM OVER LUM GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+12220;CUNEIFORM SIGN MA;Lo;0;L;;;;;N;;;;;
+12221;CUNEIFORM SIGN MA TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12222;CUNEIFORM SIGN MA GUNU;Lo;0;L;;;;;N;;;;;
+12223;CUNEIFORM SIGN MA2;Lo;0;L;;;;;N;;;;;
+12224;CUNEIFORM SIGN MAH;Lo;0;L;;;;;N;;;;;
+12225;CUNEIFORM SIGN MAR;Lo;0;L;;;;;N;;;;;
+12226;CUNEIFORM SIGN MASH;Lo;0;L;;;;;N;;;;;
+12227;CUNEIFORM SIGN MASH2;Lo;0;L;;;;;N;;;;;
+12228;CUNEIFORM SIGN ME;Lo;0;L;;;;;N;;;;;
+12229;CUNEIFORM SIGN MES;Lo;0;L;;;;;N;;;;;
+1222A;CUNEIFORM SIGN MI;Lo;0;L;;;;;N;;;;;
+1222B;CUNEIFORM SIGN MIN;Lo;0;L;;;;;N;;;;;
+1222C;CUNEIFORM SIGN MU;Lo;0;L;;;;;N;;;;;
+1222D;CUNEIFORM SIGN MU OVER MU;Lo;0;L;;;;;N;;;;;
+1222E;CUNEIFORM SIGN MUG;Lo;0;L;;;;;N;;;;;
+1222F;CUNEIFORM SIGN MUG GUNU;Lo;0;L;;;;;N;;;;;
+12230;CUNEIFORM SIGN MUNSUB;Lo;0;L;;;;;N;;;;;
+12231;CUNEIFORM SIGN MURGU2;Lo;0;L;;;;;N;;;;;
+12232;CUNEIFORM SIGN MUSH;Lo;0;L;;;;;N;;;;;
+12233;CUNEIFORM SIGN MUSH TIMES A;Lo;0;L;;;;;N;;;;;
+12234;CUNEIFORM SIGN MUSH TIMES KUR;Lo;0;L;;;;;N;;;;;
+12235;CUNEIFORM SIGN MUSH TIMES ZA;Lo;0;L;;;;;N;;;;;
+12236;CUNEIFORM SIGN MUSH OVER MUSH;Lo;0;L;;;;;N;;;;;
+12237;CUNEIFORM SIGN MUSH OVER MUSH TIMES A PLUS NA;Lo;0;L;;;;;N;;;;;
+12238;CUNEIFORM SIGN MUSH CROSSING MUSH;Lo;0;L;;;;;N;;;;;
+12239;CUNEIFORM SIGN MUSH3;Lo;0;L;;;;;N;;;;;
+1223A;CUNEIFORM SIGN MUSH3 TIMES A;Lo;0;L;;;;;N;;;;;
+1223B;CUNEIFORM SIGN MUSH3 TIMES A PLUS DI;Lo;0;L;;;;;N;;;;;
+1223C;CUNEIFORM SIGN MUSH3 TIMES DI;Lo;0;L;;;;;N;;;;;
+1223D;CUNEIFORM SIGN MUSH3 GUNU;Lo;0;L;;;;;N;;;;;
+1223E;CUNEIFORM SIGN NA;Lo;0;L;;;;;N;;;;;
+1223F;CUNEIFORM SIGN NA2;Lo;0;L;;;;;N;;;;;
+12240;CUNEIFORM SIGN NAGA;Lo;0;L;;;;;N;;;;;
+12241;CUNEIFORM SIGN NAGA INVERTED;Lo;0;L;;;;;N;;;;;
+12242;CUNEIFORM SIGN NAGA TIMES SHU TENU;Lo;0;L;;;;;N;;;;;
+12243;CUNEIFORM SIGN NAGA OPPOSING NAGA;Lo;0;L;;;;;N;;;;;
+12244;CUNEIFORM SIGN NAGAR;Lo;0;L;;;;;N;;;;;
+12245;CUNEIFORM SIGN NAM NUTILLU;Lo;0;L;;;;;N;;;;;
+12246;CUNEIFORM SIGN NAM;Lo;0;L;;;;;N;;;;;
+12247;CUNEIFORM SIGN NAM2;Lo;0;L;;;;;N;;;;;
+12248;CUNEIFORM SIGN NE;Lo;0;L;;;;;N;;;;;
+12249;CUNEIFORM SIGN NE TIMES A;Lo;0;L;;;;;N;;;;;
+1224A;CUNEIFORM SIGN NE TIMES UD;Lo;0;L;;;;;N;;;;;
+1224B;CUNEIFORM SIGN NE SHESHIG;Lo;0;L;;;;;N;;;;;
+1224C;CUNEIFORM SIGN NI;Lo;0;L;;;;;N;;;;;
+1224D;CUNEIFORM SIGN NI TIMES E;Lo;0;L;;;;;N;;;;;
+1224E;CUNEIFORM SIGN NI2;Lo;0;L;;;;;N;;;;;
+1224F;CUNEIFORM SIGN NIM;Lo;0;L;;;;;N;;;;;
+12250;CUNEIFORM SIGN NIM TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12251;CUNEIFORM SIGN NIM TIMES GAR PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12252;CUNEIFORM SIGN NINDA2;Lo;0;L;;;;;N;;;;;
+12253;CUNEIFORM SIGN NINDA2 TIMES AN;Lo;0;L;;;;;N;;;;;
+12254;CUNEIFORM SIGN NINDA2 TIMES ASH;Lo;0;L;;;;;N;;;;;
+12255;CUNEIFORM SIGN NINDA2 TIMES ASH PLUS ASH;Lo;0;L;;;;;N;;;;;
+12256;CUNEIFORM SIGN NINDA2 TIMES GUD;Lo;0;L;;;;;N;;;;;
+12257;CUNEIFORM SIGN NINDA2 TIMES ME PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;;
+12258;CUNEIFORM SIGN NINDA2 TIMES NE;Lo;0;L;;;;;N;;;;;
+12259;CUNEIFORM SIGN NINDA2 TIMES NUN;Lo;0;L;;;;;N;;;;;
+1225A;CUNEIFORM SIGN NINDA2 TIMES SHE;Lo;0;L;;;;;N;;;;;
+1225B;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS A AN;Lo;0;L;;;;;N;;;;;
+1225C;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH;Lo;0;L;;;;;N;;;;;
+1225D;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH PLUS ASH;Lo;0;L;;;;;N;;;;;
+1225E;CUNEIFORM SIGN NINDA2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;
+1225F;CUNEIFORM SIGN NINDA2 TIMES USH;Lo;0;L;;;;;N;;;;;
+12260;CUNEIFORM SIGN NISAG;Lo;0;L;;;;;N;;;;;
+12261;CUNEIFORM SIGN NU;Lo;0;L;;;;;N;;;;;
+12262;CUNEIFORM SIGN NU11;Lo;0;L;;;;;N;;;;;
+12263;CUNEIFORM SIGN NUN;Lo;0;L;;;;;N;;;;;
+12264;CUNEIFORM SIGN NUN LAGAR TIMES GAR;Lo;0;L;;;;;N;;;;;
+12265;CUNEIFORM SIGN NUN LAGAR TIMES MASH;Lo;0;L;;;;;N;;;;;
+12266;CUNEIFORM SIGN NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;;
+12267;CUNEIFORM SIGN NUN LAGAR TIMES SAL OVER NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;;
+12268;CUNEIFORM SIGN NUN LAGAR TIMES USH;Lo;0;L;;;;;N;;;;;
+12269;CUNEIFORM SIGN NUN TENU;Lo;0;L;;;;;N;;;;;
+1226A;CUNEIFORM SIGN NUN OVER NUN;Lo;0;L;;;;;N;;;;;
+1226B;CUNEIFORM SIGN NUN CROSSING NUN;Lo;0;L;;;;;N;;;;;
+1226C;CUNEIFORM SIGN NUN CROSSING NUN LAGAR OVER LAGAR;Lo;0;L;;;;;N;;;;;
+1226D;CUNEIFORM SIGN NUNUZ;Lo;0;L;;;;;N;;;;;
+1226E;CUNEIFORM SIGN NUNUZ AB2 TIMES ASHGAB;Lo;0;L;;;;;N;;;;;
+1226F;CUNEIFORM SIGN NUNUZ AB2 TIMES BI;Lo;0;L;;;;;N;;;;;
+12270;CUNEIFORM SIGN NUNUZ AB2 TIMES DUG;Lo;0;L;;;;;N;;;;;
+12271;CUNEIFORM SIGN NUNUZ AB2 TIMES GUD;Lo;0;L;;;;;N;;;;;
+12272;CUNEIFORM SIGN NUNUZ AB2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+12273;CUNEIFORM SIGN NUNUZ AB2 TIMES KAD3;Lo;0;L;;;;;N;;;;;
+12274;CUNEIFORM SIGN NUNUZ AB2 TIMES LA;Lo;0;L;;;;;N;;;;;
+12275;CUNEIFORM SIGN NUNUZ AB2 TIMES NE;Lo;0;L;;;;;N;;;;;
+12276;CUNEIFORM SIGN NUNUZ AB2 TIMES SILA3;Lo;0;L;;;;;N;;;;;
+12277;CUNEIFORM SIGN NUNUZ AB2 TIMES U2;Lo;0;L;;;;;N;;;;;
+12278;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;;
+12279;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI U;Lo;0;L;;;;;N;;;;;
+1227A;CUNEIFORM SIGN PA;Lo;0;L;;;;;N;;;;;
+1227B;CUNEIFORM SIGN PAD;Lo;0;L;;;;;N;;;;;
+1227C;CUNEIFORM SIGN PAN;Lo;0;L;;;;;N;;;;;
+1227D;CUNEIFORM SIGN PAP;Lo;0;L;;;;;N;;;;;
+1227E;CUNEIFORM SIGN PESH2;Lo;0;L;;;;;N;;;;;
+1227F;CUNEIFORM SIGN PI;Lo;0;L;;;;;N;;;;;
+12280;CUNEIFORM SIGN PI TIMES A;Lo;0;L;;;;;N;;;;;
+12281;CUNEIFORM SIGN PI TIMES AB;Lo;0;L;;;;;N;;;;;
+12282;CUNEIFORM SIGN PI TIMES BI;Lo;0;L;;;;;N;;;;;
+12283;CUNEIFORM SIGN PI TIMES BU;Lo;0;L;;;;;N;;;;;
+12284;CUNEIFORM SIGN PI TIMES E;Lo;0;L;;;;;N;;;;;
+12285;CUNEIFORM SIGN PI TIMES I;Lo;0;L;;;;;N;;;;;
+12286;CUNEIFORM SIGN PI TIMES IB;Lo;0;L;;;;;N;;;;;
+12287;CUNEIFORM SIGN PI TIMES U;Lo;0;L;;;;;N;;;;;
+12288;CUNEIFORM SIGN PI TIMES U2;Lo;0;L;;;;;N;;;;;
+12289;CUNEIFORM SIGN PI CROSSING PI;Lo;0;L;;;;;N;;;;;
+1228A;CUNEIFORM SIGN PIRIG;Lo;0;L;;;;;N;;;;;
+1228B;CUNEIFORM SIGN PIRIG TIMES KAL;Lo;0;L;;;;;N;;;;;
+1228C;CUNEIFORM SIGN PIRIG TIMES UD;Lo;0;L;;;;;N;;;;;
+1228D;CUNEIFORM SIGN PIRIG TIMES ZA;Lo;0;L;;;;;N;;;;;
+1228E;CUNEIFORM SIGN PIRIG OPPOSING PIRIG;Lo;0;L;;;;;N;;;;;
+1228F;CUNEIFORM SIGN RA;Lo;0;L;;;;;N;;;;;
+12290;CUNEIFORM SIGN RAB;Lo;0;L;;;;;N;;;;;
+12291;CUNEIFORM SIGN RI;Lo;0;L;;;;;N;;;;;
+12292;CUNEIFORM SIGN RU;Lo;0;L;;;;;N;;;;;
+12293;CUNEIFORM SIGN SA;Lo;0;L;;;;;N;;;;;
+12294;CUNEIFORM SIGN SAG NUTILLU;Lo;0;L;;;;;N;;;;;
+12295;CUNEIFORM SIGN SAG;Lo;0;L;;;;;N;;;;;
+12296;CUNEIFORM SIGN SAG TIMES A;Lo;0;L;;;;;N;;;;;
+12297;CUNEIFORM SIGN SAG TIMES DU;Lo;0;L;;;;;N;;;;;
+12298;CUNEIFORM SIGN SAG TIMES DUB;Lo;0;L;;;;;N;;;;;
+12299;CUNEIFORM SIGN SAG TIMES HA;Lo;0;L;;;;;N;;;;;
+1229A;CUNEIFORM SIGN SAG TIMES KAK;Lo;0;L;;;;;N;;;;;
+1229B;CUNEIFORM SIGN SAG TIMES KUR;Lo;0;L;;;;;N;;;;;
+1229C;CUNEIFORM SIGN SAG TIMES LUM;Lo;0;L;;;;;N;;;;;
+1229D;CUNEIFORM SIGN SAG TIMES MI;Lo;0;L;;;;;N;;;;;
+1229E;CUNEIFORM SIGN SAG TIMES NUN;Lo;0;L;;;;;N;;;;;
+1229F;CUNEIFORM SIGN SAG TIMES SAL;Lo;0;L;;;;;N;;;;;
+122A0;CUNEIFORM SIGN SAG TIMES SHID;Lo;0;L;;;;;N;;;;;
+122A1;CUNEIFORM SIGN SAG TIMES TAB;Lo;0;L;;;;;N;;;;;
+122A2;CUNEIFORM SIGN SAG TIMES U2;Lo;0;L;;;;;N;;;;;
+122A3;CUNEIFORM SIGN SAG TIMES UB;Lo;0;L;;;;;N;;;;;
+122A4;CUNEIFORM SIGN SAG TIMES UM;Lo;0;L;;;;;N;;;;;
+122A5;CUNEIFORM SIGN SAG TIMES UR;Lo;0;L;;;;;N;;;;;
+122A6;CUNEIFORM SIGN SAG TIMES USH;Lo;0;L;;;;;N;;;;;
+122A7;CUNEIFORM SIGN SAG OVER SAG;Lo;0;L;;;;;N;;;;;
+122A8;CUNEIFORM SIGN SAG GUNU;Lo;0;L;;;;;N;;;;;
+122A9;CUNEIFORM SIGN SAL;Lo;0;L;;;;;N;;;;;
+122AA;CUNEIFORM SIGN SAL LAGAB TIMES ASH2;Lo;0;L;;;;;N;;;;;
+122AB;CUNEIFORM SIGN SANGA2;Lo;0;L;;;;;N;;;;;
+122AC;CUNEIFORM SIGN SAR;Lo;0;L;;;;;N;;;;;
+122AD;CUNEIFORM SIGN SHA;Lo;0;L;;;;;N;;;;;
+122AE;CUNEIFORM SIGN SHA3;Lo;0;L;;;;;N;;;;;
+122AF;CUNEIFORM SIGN SHA3 TIMES A;Lo;0;L;;;;;N;;;;;
+122B0;CUNEIFORM SIGN SHA3 TIMES BAD;Lo;0;L;;;;;N;;;;;
+122B1;CUNEIFORM SIGN SHA3 TIMES GISH;Lo;0;L;;;;;N;;;;;
+122B2;CUNEIFORM SIGN SHA3 TIMES NE;Lo;0;L;;;;;N;;;;;
+122B3;CUNEIFORM SIGN SHA3 TIMES SHU2;Lo;0;L;;;;;N;;;;;
+122B4;CUNEIFORM SIGN SHA3 TIMES TUR;Lo;0;L;;;;;N;;;;;
+122B5;CUNEIFORM SIGN SHA3 TIMES U;Lo;0;L;;;;;N;;;;;
+122B6;CUNEIFORM SIGN SHA3 TIMES U PLUS A;Lo;0;L;;;;;N;;;;;
+122B7;CUNEIFORM SIGN SHA6;Lo;0;L;;;;;N;;;;;
+122B8;CUNEIFORM SIGN SHAB6;Lo;0;L;;;;;N;;;;;
+122B9;CUNEIFORM SIGN SHAR2;Lo;0;L;;;;;N;;;;;
+122BA;CUNEIFORM SIGN SHE;Lo;0;L;;;;;N;;;;;
+122BB;CUNEIFORM SIGN SHE HU;Lo;0;L;;;;;N;;;;;
+122BC;CUNEIFORM SIGN SHE OVER SHE GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+122BD;CUNEIFORM SIGN SHE OVER SHE TAB OVER TAB GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+122BE;CUNEIFORM SIGN SHEG9;Lo;0;L;;;;;N;;;;;
+122BF;CUNEIFORM SIGN SHEN;Lo;0;L;;;;;N;;;;;
+122C0;CUNEIFORM SIGN SHESH;Lo;0;L;;;;;N;;;;;
+122C1;CUNEIFORM SIGN SHESH2;Lo;0;L;;;;;N;;;;;
+122C2;CUNEIFORM SIGN SHESHLAM;Lo;0;L;;;;;N;;;;;
+122C3;CUNEIFORM SIGN SHID;Lo;0;L;;;;;N;;;;;
+122C4;CUNEIFORM SIGN SHID TIMES A;Lo;0;L;;;;;N;;;;;
+122C5;CUNEIFORM SIGN SHID TIMES IM;Lo;0;L;;;;;N;;;;;
+122C6;CUNEIFORM SIGN SHIM;Lo;0;L;;;;;N;;;;;
+122C7;CUNEIFORM SIGN SHIM TIMES A;Lo;0;L;;;;;N;;;;;
+122C8;CUNEIFORM SIGN SHIM TIMES BAL;Lo;0;L;;;;;N;;;;;
+122C9;CUNEIFORM SIGN SHIM TIMES BULUG;Lo;0;L;;;;;N;;;;;
+122CA;CUNEIFORM SIGN SHIM TIMES DIN;Lo;0;L;;;;;N;;;;;
+122CB;CUNEIFORM SIGN SHIM TIMES GAR;Lo;0;L;;;;;N;;;;;
+122CC;CUNEIFORM SIGN SHIM TIMES IGI;Lo;0;L;;;;;N;;;;;
+122CD;CUNEIFORM SIGN SHIM TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+122CE;CUNEIFORM SIGN SHIM TIMES KUSHU2;Lo;0;L;;;;;N;;;;;
+122CF;CUNEIFORM SIGN SHIM TIMES LUL;Lo;0;L;;;;;N;;;;;
+122D0;CUNEIFORM SIGN SHIM TIMES MUG;Lo;0;L;;;;;N;;;;;
+122D1;CUNEIFORM SIGN SHIM TIMES SAL;Lo;0;L;;;;;N;;;;;
+122D2;CUNEIFORM SIGN SHINIG;Lo;0;L;;;;;N;;;;;
+122D3;CUNEIFORM SIGN SHIR;Lo;0;L;;;;;N;;;;;
+122D4;CUNEIFORM SIGN SHIR TENU;Lo;0;L;;;;;N;;;;;
+122D5;CUNEIFORM SIGN SHIR OVER SHIR BUR OVER BUR;Lo;0;L;;;;;N;;;;;
+122D6;CUNEIFORM SIGN SHITA;Lo;0;L;;;;;N;;;;;
+122D7;CUNEIFORM SIGN SHU;Lo;0;L;;;;;N;;;;;
+122D8;CUNEIFORM SIGN SHU OVER INVERTED SHU;Lo;0;L;;;;;N;;;;;
+122D9;CUNEIFORM SIGN SHU2;Lo;0;L;;;;;N;;;;;
+122DA;CUNEIFORM SIGN SHUBUR;Lo;0;L;;;;;N;;;;;
+122DB;CUNEIFORM SIGN SI;Lo;0;L;;;;;N;;;;;
+122DC;CUNEIFORM SIGN SI GUNU;Lo;0;L;;;;;N;;;;;
+122DD;CUNEIFORM SIGN SIG;Lo;0;L;;;;;N;;;;;
+122DE;CUNEIFORM SIGN SIG4;Lo;0;L;;;;;N;;;;;
+122DF;CUNEIFORM SIGN SIG4 OVER SIG4 SHU2;Lo;0;L;;;;;N;;;;;
+122E0;CUNEIFORM SIGN SIK2;Lo;0;L;;;;;N;;;;;
+122E1;CUNEIFORM SIGN SILA3;Lo;0;L;;;;;N;;;;;
+122E2;CUNEIFORM SIGN SU;Lo;0;L;;;;;N;;;;;
+122E3;CUNEIFORM SIGN SU OVER SU;Lo;0;L;;;;;N;;;;;
+122E4;CUNEIFORM SIGN SUD;Lo;0;L;;;;;N;;;;;
+122E5;CUNEIFORM SIGN SUD2;Lo;0;L;;;;;N;;;;;
+122E6;CUNEIFORM SIGN SUHUR;Lo;0;L;;;;;N;;;;;
+122E7;CUNEIFORM SIGN SUM;Lo;0;L;;;;;N;;;;;
+122E8;CUNEIFORM SIGN SUMASH;Lo;0;L;;;;;N;;;;;
+122E9;CUNEIFORM SIGN SUR;Lo;0;L;;;;;N;;;;;
+122EA;CUNEIFORM SIGN SUR9;Lo;0;L;;;;;N;;;;;
+122EB;CUNEIFORM SIGN TA;Lo;0;L;;;;;N;;;;;
+122EC;CUNEIFORM SIGN TA ASTERISK;Lo;0;L;;;;;N;;;;;
+122ED;CUNEIFORM SIGN TA TIMES HI;Lo;0;L;;;;;N;;;;;
+122EE;CUNEIFORM SIGN TA TIMES MI;Lo;0;L;;;;;N;;;;;
+122EF;CUNEIFORM SIGN TA GUNU;Lo;0;L;;;;;N;;;;;
+122F0;CUNEIFORM SIGN TAB;Lo;0;L;;;;;N;;;;;
+122F1;CUNEIFORM SIGN TAB OVER TAB NI OVER NI DISH OVER DISH;Lo;0;L;;;;;N;;;;;
+122F2;CUNEIFORM SIGN TAB SQUARED;Lo;0;L;;;;;N;;;;;
+122F3;CUNEIFORM SIGN TAG;Lo;0;L;;;;;N;;;;;
+122F4;CUNEIFORM SIGN TAG TIMES BI;Lo;0;L;;;;;N;;;;;
+122F5;CUNEIFORM SIGN TAG TIMES GUD;Lo;0;L;;;;;N;;;;;
+122F6;CUNEIFORM SIGN TAG TIMES SHE;Lo;0;L;;;;;N;;;;;
+122F7;CUNEIFORM SIGN TAG TIMES SHU;Lo;0;L;;;;;N;;;;;
+122F8;CUNEIFORM SIGN TAG TIMES TUG2;Lo;0;L;;;;;N;;;;;
+122F9;CUNEIFORM SIGN TAG TIMES UD;Lo;0;L;;;;;N;;;;;
+122FA;CUNEIFORM SIGN TAK4;Lo;0;L;;;;;N;;;;;
+122FB;CUNEIFORM SIGN TAR;Lo;0;L;;;;;N;;;;;
+122FC;CUNEIFORM SIGN TE;Lo;0;L;;;;;N;;;;;
+122FD;CUNEIFORM SIGN TE GUNU;Lo;0;L;;;;;N;;;;;
+122FE;CUNEIFORM SIGN TI;Lo;0;L;;;;;N;;;;;
+122FF;CUNEIFORM SIGN TI TENU;Lo;0;L;;;;;N;;;;;
+12300;CUNEIFORM SIGN TIL;Lo;0;L;;;;;N;;;;;
+12301;CUNEIFORM SIGN TIR;Lo;0;L;;;;;N;;;;;
+12302;CUNEIFORM SIGN TIR TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12303;CUNEIFORM SIGN TIR OVER TIR;Lo;0;L;;;;;N;;;;;
+12304;CUNEIFORM SIGN TIR OVER TIR GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+12305;CUNEIFORM SIGN TU;Lo;0;L;;;;;N;;;;;
+12306;CUNEIFORM SIGN TUG2;Lo;0;L;;;;;N;;;;;
+12307;CUNEIFORM SIGN TUK;Lo;0;L;;;;;N;;;;;
+12308;CUNEIFORM SIGN TUM;Lo;0;L;;;;;N;;;;;
+12309;CUNEIFORM SIGN TUR;Lo;0;L;;;;;N;;;;;
+1230A;CUNEIFORM SIGN TUR OVER TUR ZA OVER ZA;Lo;0;L;;;;;N;;;;;
+1230B;CUNEIFORM SIGN U;Lo;0;L;;;;;N;;;;;
+1230C;CUNEIFORM SIGN U GUD;Lo;0;L;;;;;N;;;;;
+1230D;CUNEIFORM SIGN U U U;Lo;0;L;;;;;N;;;;;
+1230E;CUNEIFORM SIGN U OVER U PA OVER PA GAR OVER GAR;Lo;0;L;;;;;N;;;;;
+1230F;CUNEIFORM SIGN U OVER U SUR OVER SUR;Lo;0;L;;;;;N;;;;;
+12310;CUNEIFORM SIGN U OVER U U REVERSED OVER U REVERSED;Lo;0;L;;;;;N;;;;;
+12311;CUNEIFORM SIGN U2;Lo;0;L;;;;;N;;;;;
+12312;CUNEIFORM SIGN UB;Lo;0;L;;;;;N;;;;;
+12313;CUNEIFORM SIGN UD;Lo;0;L;;;;;N;;;;;
+12314;CUNEIFORM SIGN UD KUSHU2;Lo;0;L;;;;;N;;;;;
+12315;CUNEIFORM SIGN UD TIMES BAD;Lo;0;L;;;;;N;;;;;
+12316;CUNEIFORM SIGN UD TIMES MI;Lo;0;L;;;;;N;;;;;
+12317;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;
+12318;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U GUNU;Lo;0;L;;;;;N;;;;;
+12319;CUNEIFORM SIGN UD GUNU;Lo;0;L;;;;;N;;;;;
+1231A;CUNEIFORM SIGN UD SHESHIG;Lo;0;L;;;;;N;;;;;
+1231B;CUNEIFORM SIGN UD SHESHIG TIMES BAD;Lo;0;L;;;;;N;;;;;
+1231C;CUNEIFORM SIGN UDUG;Lo;0;L;;;;;N;;;;;
+1231D;CUNEIFORM SIGN UM;Lo;0;L;;;;;N;;;;;
+1231E;CUNEIFORM SIGN UM TIMES LAGAB;Lo;0;L;;;;;N;;;;;
+1231F;CUNEIFORM SIGN UM TIMES ME PLUS DA;Lo;0;L;;;;;N;;;;;
+12320;CUNEIFORM SIGN UM TIMES SHA3;Lo;0;L;;;;;N;;;;;
+12321;CUNEIFORM SIGN UM TIMES U;Lo;0;L;;;;;N;;;;;
+12322;CUNEIFORM SIGN UMBIN;Lo;0;L;;;;;N;;;;;
+12323;CUNEIFORM SIGN UMUM;Lo;0;L;;;;;N;;;;;
+12324;CUNEIFORM SIGN UMUM TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+12325;CUNEIFORM SIGN UMUM TIMES PA;Lo;0;L;;;;;N;;;;;
+12326;CUNEIFORM SIGN UN;Lo;0;L;;;;;N;;;;;
+12327;CUNEIFORM SIGN UN GUNU;Lo;0;L;;;;;N;;;;;
+12328;CUNEIFORM SIGN UR;Lo;0;L;;;;;N;;;;;
+12329;CUNEIFORM SIGN UR CROSSING UR;Lo;0;L;;;;;N;;;;;
+1232A;CUNEIFORM SIGN UR SHESHIG;Lo;0;L;;;;;N;;;;;
+1232B;CUNEIFORM SIGN UR2;Lo;0;L;;;;;N;;;;;
+1232C;CUNEIFORM SIGN UR2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;;
+1232D;CUNEIFORM SIGN UR2 TIMES A PLUS NA;Lo;0;L;;;;;N;;;;;
+1232E;CUNEIFORM SIGN UR2 TIMES AL;Lo;0;L;;;;;N;;;;;
+1232F;CUNEIFORM SIGN UR2 TIMES HA;Lo;0;L;;;;;N;;;;;
+12330;CUNEIFORM SIGN UR2 TIMES NUN;Lo;0;L;;;;;N;;;;;
+12331;CUNEIFORM SIGN UR2 TIMES U2;Lo;0;L;;;;;N;;;;;
+12332;CUNEIFORM SIGN UR2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;
+12333;CUNEIFORM SIGN UR2 TIMES U2 PLUS BI;Lo;0;L;;;;;N;;;;;
+12334;CUNEIFORM SIGN UR4;Lo;0;L;;;;;N;;;;;
+12335;CUNEIFORM SIGN URI;Lo;0;L;;;;;N;;;;;
+12336;CUNEIFORM SIGN URI3;Lo;0;L;;;;;N;;;;;
+12337;CUNEIFORM SIGN URU;Lo;0;L;;;;;N;;;;;
+12338;CUNEIFORM SIGN URU TIMES A;Lo;0;L;;;;;N;;;;;
+12339;CUNEIFORM SIGN URU TIMES ASHGAB;Lo;0;L;;;;;N;;;;;
+1233A;CUNEIFORM SIGN URU TIMES BAR;Lo;0;L;;;;;N;;;;;
+1233B;CUNEIFORM SIGN URU TIMES DUN;Lo;0;L;;;;;N;;;;;
+1233C;CUNEIFORM SIGN URU TIMES GA;Lo;0;L;;;;;N;;;;;
+1233D;CUNEIFORM SIGN URU TIMES GAL;Lo;0;L;;;;;N;;;;;
+1233E;CUNEIFORM SIGN URU TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1233F;CUNEIFORM SIGN URU TIMES GAR;Lo;0;L;;;;;N;;;;;
+12340;CUNEIFORM SIGN URU TIMES GU;Lo;0;L;;;;;N;;;;;
+12341;CUNEIFORM SIGN URU TIMES HA;Lo;0;L;;;;;N;;;;;
+12342;CUNEIFORM SIGN URU TIMES IGI;Lo;0;L;;;;;N;;;;;
+12343;CUNEIFORM SIGN URU TIMES IM;Lo;0;L;;;;;N;;;;;
+12344;CUNEIFORM SIGN URU TIMES ISH;Lo;0;L;;;;;N;;;;;
+12345;CUNEIFORM SIGN URU TIMES KI;Lo;0;L;;;;;N;;;;;
+12346;CUNEIFORM SIGN URU TIMES LUM;Lo;0;L;;;;;N;;;;;
+12347;CUNEIFORM SIGN URU TIMES MIN;Lo;0;L;;;;;N;;;;;
+12348;CUNEIFORM SIGN URU TIMES PA;Lo;0;L;;;;;N;;;;;
+12349;CUNEIFORM SIGN URU TIMES SHE;Lo;0;L;;;;;N;;;;;
+1234A;CUNEIFORM SIGN URU TIMES SIG4;Lo;0;L;;;;;N;;;;;
+1234B;CUNEIFORM SIGN URU TIMES TU;Lo;0;L;;;;;N;;;;;
+1234C;CUNEIFORM SIGN URU TIMES U PLUS GUD;Lo;0;L;;;;;N;;;;;
+1234D;CUNEIFORM SIGN URU TIMES UD;Lo;0;L;;;;;N;;;;;
+1234E;CUNEIFORM SIGN URU TIMES URUDA;Lo;0;L;;;;;N;;;;;
+1234F;CUNEIFORM SIGN URUDA;Lo;0;L;;;;;N;;;;;
+12350;CUNEIFORM SIGN URUDA TIMES U;Lo;0;L;;;;;N;;;;;
+12351;CUNEIFORM SIGN USH;Lo;0;L;;;;;N;;;;;
+12352;CUNEIFORM SIGN USH TIMES A;Lo;0;L;;;;;N;;;;;
+12353;CUNEIFORM SIGN USH TIMES KU;Lo;0;L;;;;;N;;;;;
+12354;CUNEIFORM SIGN USH TIMES KUR;Lo;0;L;;;;;N;;;;;
+12355;CUNEIFORM SIGN USH TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12356;CUNEIFORM SIGN USHX;Lo;0;L;;;;;N;;;;;
+12357;CUNEIFORM SIGN USH2;Lo;0;L;;;;;N;;;;;
+12358;CUNEIFORM SIGN USHUMX;Lo;0;L;;;;;N;;;;;
+12359;CUNEIFORM SIGN UTUKI;Lo;0;L;;;;;N;;;;;
+1235A;CUNEIFORM SIGN UZ3;Lo;0;L;;;;;N;;;;;
+1235B;CUNEIFORM SIGN UZ3 TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+1235C;CUNEIFORM SIGN UZU;Lo;0;L;;;;;N;;;;;
+1235D;CUNEIFORM SIGN ZA;Lo;0;L;;;;;N;;;;;
+1235E;CUNEIFORM SIGN ZA TENU;Lo;0;L;;;;;N;;;;;
+1235F;CUNEIFORM SIGN ZA SQUARED TIMES KUR;Lo;0;L;;;;;N;;;;;
+12360;CUNEIFORM SIGN ZAG;Lo;0;L;;;;;N;;;;;
+12361;CUNEIFORM SIGN ZAMX;Lo;0;L;;;;;N;;;;;
+12362;CUNEIFORM SIGN ZE2;Lo;0;L;;;;;N;;;;;
+12363;CUNEIFORM SIGN ZI;Lo;0;L;;;;;N;;;;;
+12364;CUNEIFORM SIGN ZI OVER ZI;Lo;0;L;;;;;N;;;;;
+12365;CUNEIFORM SIGN ZI3;Lo;0;L;;;;;N;;;;;
+12366;CUNEIFORM SIGN ZIB;Lo;0;L;;;;;N;;;;;
+12367;CUNEIFORM SIGN ZIB KABA TENU;Lo;0;L;;;;;N;;;;;
+12368;CUNEIFORM SIGN ZIG;Lo;0;L;;;;;N;;;;;
+12369;CUNEIFORM SIGN ZIZ2;Lo;0;L;;;;;N;;;;;
+1236A;CUNEIFORM SIGN ZU;Lo;0;L;;;;;N;;;;;
+1236B;CUNEIFORM SIGN ZU5;Lo;0;L;;;;;N;;;;;
+1236C;CUNEIFORM SIGN ZU5 TIMES A;Lo;0;L;;;;;N;;;;;
+1236D;CUNEIFORM SIGN ZUBUR;Lo;0;L;;;;;N;;;;;
+1236E;CUNEIFORM SIGN ZUM;Lo;0;L;;;;;N;;;;;
+1236F;CUNEIFORM SIGN KAP ELAMITE;Lo;0;L;;;;;N;;;;;
+12370;CUNEIFORM SIGN AB TIMES NUN;Lo;0;L;;;;;N;;;;;
+12371;CUNEIFORM SIGN AB2 TIMES A;Lo;0;L;;;;;N;;;;;
+12372;CUNEIFORM SIGN AMAR TIMES KUG;Lo;0;L;;;;;N;;;;;
+12373;CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS MASH;Lo;0;L;;;;;N;;;;;
+12374;CUNEIFORM SIGN DAG3;Lo;0;L;;;;;N;;;;;
+12375;CUNEIFORM SIGN DISH PLUS SHU;Lo;0;L;;;;;N;;;;;
+12376;CUNEIFORM SIGN DUB TIMES SHE;Lo;0;L;;;;;N;;;;;
+12377;CUNEIFORM SIGN EZEN TIMES GUD;Lo;0;L;;;;;N;;;;;
+12378;CUNEIFORM SIGN EZEN TIMES SHE;Lo;0;L;;;;;N;;;;;
+12379;CUNEIFORM SIGN GA2 TIMES AN PLUS KAK PLUS A;Lo;0;L;;;;;N;;;;;
+1237A;CUNEIFORM SIGN GA2 TIMES ASH2;Lo;0;L;;;;;N;;;;;
+1237B;CUNEIFORM SIGN GE22;Lo;0;L;;;;;N;;;;;
+1237C;CUNEIFORM SIGN GIG;Lo;0;L;;;;;N;;;;;
+1237D;CUNEIFORM SIGN HUSH;Lo;0;L;;;;;N;;;;;
+1237E;CUNEIFORM SIGN KA TIMES ANSHE;Lo;0;L;;;;;N;;;;;
+1237F;CUNEIFORM SIGN KA TIMES ASH3;Lo;0;L;;;;;N;;;;;
+12380;CUNEIFORM SIGN KA TIMES GISH;Lo;0;L;;;;;N;;;;;
+12381;CUNEIFORM SIGN KA TIMES GUD;Lo;0;L;;;;;N;;;;;
+12382;CUNEIFORM SIGN KA TIMES HI TIMES ASH2;Lo;0;L;;;;;N;;;;;
+12383;CUNEIFORM SIGN KA TIMES LUM;Lo;0;L;;;;;N;;;;;
+12384;CUNEIFORM SIGN KA TIMES PA;Lo;0;L;;;;;N;;;;;
+12385;CUNEIFORM SIGN KA TIMES SHUL;Lo;0;L;;;;;N;;;;;
+12386;CUNEIFORM SIGN KA TIMES TU;Lo;0;L;;;;;N;;;;;
+12387;CUNEIFORM SIGN KA TIMES UR2;Lo;0;L;;;;;N;;;;;
+12388;CUNEIFORM SIGN LAGAB TIMES GI;Lo;0;L;;;;;N;;;;;
+12389;CUNEIFORM SIGN LU2 SHESHIG TIMES BAD;Lo;0;L;;;;;N;;;;;
+1238A;CUNEIFORM SIGN LU2 TIMES ESH2 PLUS LAL;Lo;0;L;;;;;N;;;;;
+1238B;CUNEIFORM SIGN LU2 TIMES SHU;Lo;0;L;;;;;N;;;;;
+1238C;CUNEIFORM SIGN MESH;Lo;0;L;;;;;N;;;;;
+1238D;CUNEIFORM SIGN MUSH3 TIMES ZA;Lo;0;L;;;;;N;;;;;
+1238E;CUNEIFORM SIGN NA4;Lo;0;L;;;;;N;;;;;
+1238F;CUNEIFORM SIGN NIN;Lo;0;L;;;;;N;;;;;
+12390;CUNEIFORM SIGN NIN9;Lo;0;L;;;;;N;;;;;
+12391;CUNEIFORM SIGN NINDA2 TIMES BAL;Lo;0;L;;;;;N;;;;;
+12392;CUNEIFORM SIGN NINDA2 TIMES GI;Lo;0;L;;;;;N;;;;;
+12393;CUNEIFORM SIGN NU11 ROTATED NINETY DEGREES;Lo;0;L;;;;;N;;;;;
+12394;CUNEIFORM SIGN PESH2 ASTERISK;Lo;0;L;;;;;N;;;;;
+12395;CUNEIFORM SIGN PIR2;Lo;0;L;;;;;N;;;;;
+12396;CUNEIFORM SIGN SAG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+12397;CUNEIFORM SIGN TI2;Lo;0;L;;;;;N;;;;;
+12398;CUNEIFORM SIGN UM TIMES ME;Lo;0;L;;;;;N;;;;;
+12399;CUNEIFORM SIGN U U;Lo;0;L;;;;;N;;;;;
+12400;CUNEIFORM NUMERIC SIGN TWO ASH;Nl;0;L;;;;2;N;;;;;
+12401;CUNEIFORM NUMERIC SIGN THREE ASH;Nl;0;L;;;;3;N;;;;;
+12402;CUNEIFORM NUMERIC SIGN FOUR ASH;Nl;0;L;;;;4;N;;;;;
+12403;CUNEIFORM NUMERIC SIGN FIVE ASH;Nl;0;L;;;;5;N;;;;;
+12404;CUNEIFORM NUMERIC SIGN SIX ASH;Nl;0;L;;;;6;N;;;;;
+12405;CUNEIFORM NUMERIC SIGN SEVEN ASH;Nl;0;L;;;;7;N;;;;;
+12406;CUNEIFORM NUMERIC SIGN EIGHT ASH;Nl;0;L;;;;8;N;;;;;
+12407;CUNEIFORM NUMERIC SIGN NINE ASH;Nl;0;L;;;;9;N;;;;;
+12408;CUNEIFORM NUMERIC SIGN THREE DISH;Nl;0;L;;;;3;N;;;;;
+12409;CUNEIFORM NUMERIC SIGN FOUR DISH;Nl;0;L;;;;4;N;;;;;
+1240A;CUNEIFORM NUMERIC SIGN FIVE DISH;Nl;0;L;;;;5;N;;;;;
+1240B;CUNEIFORM NUMERIC SIGN SIX DISH;Nl;0;L;;;;6;N;;;;;
+1240C;CUNEIFORM NUMERIC SIGN SEVEN DISH;Nl;0;L;;;;7;N;;;;;
+1240D;CUNEIFORM NUMERIC SIGN EIGHT DISH;Nl;0;L;;;;8;N;;;;;
+1240E;CUNEIFORM NUMERIC SIGN NINE DISH;Nl;0;L;;;;9;N;;;;;
+1240F;CUNEIFORM NUMERIC SIGN FOUR U;Nl;0;L;;;;4;N;;;;;
+12410;CUNEIFORM NUMERIC SIGN FIVE U;Nl;0;L;;;;5;N;;;;;
+12411;CUNEIFORM NUMERIC SIGN SIX U;Nl;0;L;;;;6;N;;;;;
+12412;CUNEIFORM NUMERIC SIGN SEVEN U;Nl;0;L;;;;7;N;;;;;
+12413;CUNEIFORM NUMERIC SIGN EIGHT U;Nl;0;L;;;;8;N;;;;;
+12414;CUNEIFORM NUMERIC SIGN NINE U;Nl;0;L;;;;9;N;;;;;
+12415;CUNEIFORM NUMERIC SIGN ONE GESH2;Nl;0;L;;;;1;N;;;;;
+12416;CUNEIFORM NUMERIC SIGN TWO GESH2;Nl;0;L;;;;2;N;;;;;
+12417;CUNEIFORM NUMERIC SIGN THREE GESH2;Nl;0;L;;;;3;N;;;;;
+12418;CUNEIFORM NUMERIC SIGN FOUR GESH2;Nl;0;L;;;;4;N;;;;;
+12419;CUNEIFORM NUMERIC SIGN FIVE GESH2;Nl;0;L;;;;5;N;;;;;
+1241A;CUNEIFORM NUMERIC SIGN SIX GESH2;Nl;0;L;;;;6;N;;;;;
+1241B;CUNEIFORM NUMERIC SIGN SEVEN GESH2;Nl;0;L;;;;7;N;;;;;
+1241C;CUNEIFORM NUMERIC SIGN EIGHT GESH2;Nl;0;L;;;;8;N;;;;;
+1241D;CUNEIFORM NUMERIC SIGN NINE GESH2;Nl;0;L;;;;9;N;;;;;
+1241E;CUNEIFORM NUMERIC SIGN ONE GESHU;Nl;0;L;;;;1;N;;;;;
+1241F;CUNEIFORM NUMERIC SIGN TWO GESHU;Nl;0;L;;;;2;N;;;;;
+12420;CUNEIFORM NUMERIC SIGN THREE GESHU;Nl;0;L;;;;3;N;;;;;
+12421;CUNEIFORM NUMERIC SIGN FOUR GESHU;Nl;0;L;;;;4;N;;;;;
+12422;CUNEIFORM NUMERIC SIGN FIVE GESHU;Nl;0;L;;;;5;N;;;;;
+12423;CUNEIFORM NUMERIC SIGN TWO SHAR2;Nl;0;L;;;;2;N;;;;;
+12424;CUNEIFORM NUMERIC SIGN THREE SHAR2;Nl;0;L;;;;3;N;;;;;
+12425;CUNEIFORM NUMERIC SIGN THREE SHAR2 VARIANT FORM;Nl;0;L;;;;3;N;;;;;
+12426;CUNEIFORM NUMERIC SIGN FOUR SHAR2;Nl;0;L;;;;4;N;;;;;
+12427;CUNEIFORM NUMERIC SIGN FIVE SHAR2;Nl;0;L;;;;5;N;;;;;
+12428;CUNEIFORM NUMERIC SIGN SIX SHAR2;Nl;0;L;;;;6;N;;;;;
+12429;CUNEIFORM NUMERIC SIGN SEVEN SHAR2;Nl;0;L;;;;7;N;;;;;
+1242A;CUNEIFORM NUMERIC SIGN EIGHT SHAR2;Nl;0;L;;;;8;N;;;;;
+1242B;CUNEIFORM NUMERIC SIGN NINE SHAR2;Nl;0;L;;;;9;N;;;;;
+1242C;CUNEIFORM NUMERIC SIGN ONE SHARU;Nl;0;L;;;;1;N;;;;;
+1242D;CUNEIFORM NUMERIC SIGN TWO SHARU;Nl;0;L;;;;2;N;;;;;
+1242E;CUNEIFORM NUMERIC SIGN THREE SHARU;Nl;0;L;;;;3;N;;;;;
+1242F;CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM;Nl;0;L;;;;3;N;;;;;
+12430;CUNEIFORM NUMERIC SIGN FOUR SHARU;Nl;0;L;;;;4;N;;;;;
+12431;CUNEIFORM NUMERIC SIGN FIVE SHARU;Nl;0;L;;;;5;N;;;;;
+12432;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH;Nl;0;L;;;;216000;N;;;;;
+12433;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN;Nl;0;L;;;;432000;N;;;;;
+12434;CUNEIFORM NUMERIC SIGN ONE BURU;Nl;0;L;;;;1;N;;;;;
+12435;CUNEIFORM NUMERIC SIGN TWO BURU;Nl;0;L;;;;2;N;;;;;
+12436;CUNEIFORM NUMERIC SIGN THREE BURU;Nl;0;L;;;;3;N;;;;;
+12437;CUNEIFORM NUMERIC SIGN THREE BURU VARIANT FORM;Nl;0;L;;;;3;N;;;;;
+12438;CUNEIFORM NUMERIC SIGN FOUR BURU;Nl;0;L;;;;4;N;;;;;
+12439;CUNEIFORM NUMERIC SIGN FIVE BURU;Nl;0;L;;;;5;N;;;;;
+1243A;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH16;Nl;0;L;;;;3;N;;;;;
+1243B;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH21;Nl;0;L;;;;3;N;;;;;
+1243C;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU;Nl;0;L;;;;4;N;;;;;
+1243D;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU4;Nl;0;L;;;;4;N;;;;;
+1243E;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU A;Nl;0;L;;;;4;N;;;;;
+1243F;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU B;Nl;0;L;;;;4;N;;;;;
+12440;CUNEIFORM NUMERIC SIGN SIX VARIANT FORM ASH9;Nl;0;L;;;;6;N;;;;;
+12441;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN3;Nl;0;L;;;;7;N;;;;;
+12442;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN A;Nl;0;L;;;;7;N;;;;;
+12443;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN B;Nl;0;L;;;;7;N;;;;;
+12444;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU;Nl;0;L;;;;8;N;;;;;
+12445;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU3;Nl;0;L;;;;8;N;;;;;
+12446;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU;Nl;0;L;;;;9;N;;;;;
+12447;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU3;Nl;0;L;;;;9;N;;;;;
+12448;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU4;Nl;0;L;;;;9;N;;;;;
+12449;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU A;Nl;0;L;;;;9;N;;;;;
+1244A;CUNEIFORM NUMERIC SIGN TWO ASH TENU;Nl;0;L;;;;2;N;;;;;
+1244B;CUNEIFORM NUMERIC SIGN THREE ASH TENU;Nl;0;L;;;;3;N;;;;;
+1244C;CUNEIFORM NUMERIC SIGN FOUR ASH TENU;Nl;0;L;;;;4;N;;;;;
+1244D;CUNEIFORM NUMERIC SIGN FIVE ASH TENU;Nl;0;L;;;;5;N;;;;;
+1244E;CUNEIFORM NUMERIC SIGN SIX ASH TENU;Nl;0;L;;;;6;N;;;;;
+1244F;CUNEIFORM NUMERIC SIGN ONE BAN2;Nl;0;L;;;;1;N;;;;;
+12450;CUNEIFORM NUMERIC SIGN TWO BAN2;Nl;0;L;;;;2;N;;;;;
+12451;CUNEIFORM NUMERIC SIGN THREE BAN2;Nl;0;L;;;;3;N;;;;;
+12452;CUNEIFORM NUMERIC SIGN FOUR BAN2;Nl;0;L;;;;4;N;;;;;
+12453;CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM;Nl;0;L;;;;4;N;;;;;
+12454;CUNEIFORM NUMERIC SIGN FIVE BAN2;Nl;0;L;;;;5;N;;;;;
+12455;CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM;Nl;0;L;;;;5;N;;;;;
+12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;2;N;;;;;
+12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;3;N;;;;;
+12458;CUNEIFORM NUMERIC SIGN ONE ESHE3;Nl;0;L;;;;1;N;;;;;
+12459;CUNEIFORM NUMERIC SIGN TWO ESHE3;Nl;0;L;;;;2;N;;;;;
+1245A;CUNEIFORM NUMERIC SIGN ONE THIRD DISH;Nl;0;L;;;;1/3;N;;;;;
+1245B;CUNEIFORM NUMERIC SIGN TWO THIRDS DISH;Nl;0;L;;;;2/3;N;;;;;
+1245C;CUNEIFORM NUMERIC SIGN FIVE SIXTHS DISH;Nl;0;L;;;;5/6;N;;;;;
+1245D;CUNEIFORM NUMERIC SIGN ONE THIRD VARIANT FORM A;Nl;0;L;;;;1/3;N;;;;;
+1245E;CUNEIFORM NUMERIC SIGN TWO THIRDS VARIANT FORM A;Nl;0;L;;;;2/3;N;;;;;
+1245F;CUNEIFORM NUMERIC SIGN ONE EIGHTH ASH;Nl;0;L;;;;1/8;N;;;;;
+12460;CUNEIFORM NUMERIC SIGN ONE QUARTER ASH;Nl;0;L;;;;1/4;N;;;;;
+12461;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH;Nl;0;L;;;;1/6;N;;;;;
+12462;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER;Nl;0;L;;;;1/4;N;;;;;
+12463;CUNEIFORM NUMERIC SIGN ONE QUARTER GUR;Nl;0;L;;;;1/4;N;;;;;
+12464;CUNEIFORM NUMERIC SIGN ONE HALF GUR;Nl;0;L;;;;1/2;N;;;;;
+12465;CUNEIFORM NUMERIC SIGN ELAMITE ONE THIRD;Nl;0;L;;;;1/3;N;;;;;
+12466;CUNEIFORM NUMERIC SIGN ELAMITE TWO THIRDS;Nl;0;L;;;;2/3;N;;;;;
+12467;CUNEIFORM NUMERIC SIGN ELAMITE FORTY;Nl;0;L;;;;40;N;;;;;
+12468;CUNEIFORM NUMERIC SIGN ELAMITE FIFTY;Nl;0;L;;;;50;N;;;;;
+12469;CUNEIFORM NUMERIC SIGN FOUR U VARIANT FORM;Nl;0;L;;;;4;N;;;;;
+1246A;CUNEIFORM NUMERIC SIGN FIVE U VARIANT FORM;Nl;0;L;;;;5;N;;;;;
+1246B;CUNEIFORM NUMERIC SIGN SIX U VARIANT FORM;Nl;0;L;;;;6;N;;;;;
+1246C;CUNEIFORM NUMERIC SIGN SEVEN U VARIANT FORM;Nl;0;L;;;;7;N;;;;;
+1246D;CUNEIFORM NUMERIC SIGN EIGHT U VARIANT FORM;Nl;0;L;;;;8;N;;;;;
+1246E;CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM;Nl;0;L;;;;9;N;;;;;
+12470;CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER;Po;0;L;;;;;N;;;;;
+12471;CUNEIFORM PUNCTUATION SIGN VERTICAL COLON;Po;0;L;;;;;N;;;;;
+12472;CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON;Po;0;L;;;;;N;;;;;
+12473;CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON;Po;0;L;;;;;N;;;;;
+12474;CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON;Po;0;L;;;;;N;;;;;
+12480;CUNEIFORM SIGN AB TIMES NUN TENU;Lo;0;L;;;;;N;;;;;
+12481;CUNEIFORM SIGN AB TIMES SHU2;Lo;0;L;;;;;N;;;;;
+12482;CUNEIFORM SIGN AD TIMES ESH2;Lo;0;L;;;;;N;;;;;
+12483;CUNEIFORM SIGN BAD TIMES DISH TENU;Lo;0;L;;;;;N;;;;;
+12484;CUNEIFORM SIGN BAHAR2 TIMES AB2;Lo;0;L;;;;;N;;;;;
+12485;CUNEIFORM SIGN BAHAR2 TIMES NI;Lo;0;L;;;;;N;;;;;
+12486;CUNEIFORM SIGN BAHAR2 TIMES ZA;Lo;0;L;;;;;N;;;;;
+12487;CUNEIFORM SIGN BU OVER BU TIMES NA2;Lo;0;L;;;;;N;;;;;
+12488;CUNEIFORM SIGN DA TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12489;CUNEIFORM SIGN DAG TIMES KUR;Lo;0;L;;;;;N;;;;;
+1248A;CUNEIFORM SIGN DIM TIMES IGI;Lo;0;L;;;;;N;;;;;
+1248B;CUNEIFORM SIGN DIM TIMES U U U;Lo;0;L;;;;;N;;;;;
+1248C;CUNEIFORM SIGN DIM2 TIMES UD;Lo;0;L;;;;;N;;;;;
+1248D;CUNEIFORM SIGN DUG TIMES ANSHE;Lo;0;L;;;;;N;;;;;
+1248E;CUNEIFORM SIGN DUG TIMES ASH;Lo;0;L;;;;;N;;;;;
+1248F;CUNEIFORM SIGN DUG TIMES ASH AT LEFT;Lo;0;L;;;;;N;;;;;
+12490;CUNEIFORM SIGN DUG TIMES DIN;Lo;0;L;;;;;N;;;;;
+12491;CUNEIFORM SIGN DUG TIMES DUN;Lo;0;L;;;;;N;;;;;
+12492;CUNEIFORM SIGN DUG TIMES ERIN2;Lo;0;L;;;;;N;;;;;
+12493;CUNEIFORM SIGN DUG TIMES GA;Lo;0;L;;;;;N;;;;;
+12494;CUNEIFORM SIGN DUG TIMES GI;Lo;0;L;;;;;N;;;;;
+12495;CUNEIFORM SIGN DUG TIMES GIR2 GUNU;Lo;0;L;;;;;N;;;;;
+12496;CUNEIFORM SIGN DUG TIMES GISH;Lo;0;L;;;;;N;;;;;
+12497;CUNEIFORM SIGN DUG TIMES HA;Lo;0;L;;;;;N;;;;;
+12498;CUNEIFORM SIGN DUG TIMES HI;Lo;0;L;;;;;N;;;;;
+12499;CUNEIFORM SIGN DUG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+1249A;CUNEIFORM SIGN DUG TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+1249B;CUNEIFORM SIGN DUG TIMES KUR;Lo;0;L;;;;;N;;;;;
+1249C;CUNEIFORM SIGN DUG TIMES KUSHU2;Lo;0;L;;;;;N;;;;;
+1249D;CUNEIFORM SIGN DUG TIMES KUSHU2 PLUS KASKAL;Lo;0;L;;;;;N;;;;;
+1249E;CUNEIFORM SIGN DUG TIMES LAK-020;Lo;0;L;;;;;N;;;;;
+1249F;CUNEIFORM SIGN DUG TIMES LAM;Lo;0;L;;;;;N;;;;;
+124A0;CUNEIFORM SIGN DUG TIMES LAM TIMES KUR;Lo;0;L;;;;;N;;;;;
+124A1;CUNEIFORM SIGN DUG TIMES LUH PLUS GISH;Lo;0;L;;;;;N;;;;;
+124A2;CUNEIFORM SIGN DUG TIMES MASH;Lo;0;L;;;;;N;;;;;
+124A3;CUNEIFORM SIGN DUG TIMES MES;Lo;0;L;;;;;N;;;;;
+124A4;CUNEIFORM SIGN DUG TIMES MI;Lo;0;L;;;;;N;;;;;
+124A5;CUNEIFORM SIGN DUG TIMES NI;Lo;0;L;;;;;N;;;;;
+124A6;CUNEIFORM SIGN DUG TIMES PI;Lo;0;L;;;;;N;;;;;
+124A7;CUNEIFORM SIGN DUG TIMES SHE;Lo;0;L;;;;;N;;;;;
+124A8;CUNEIFORM SIGN DUG TIMES SI GUNU;Lo;0;L;;;;;N;;;;;
+124A9;CUNEIFORM SIGN E2 TIMES KUR;Lo;0;L;;;;;N;;;;;
+124AA;CUNEIFORM SIGN E2 TIMES PAP;Lo;0;L;;;;;N;;;;;
+124AB;CUNEIFORM SIGN ERIN2 X;Lo;0;L;;;;;N;;;;;
+124AC;CUNEIFORM SIGN ESH2 CROSSING ESH2;Lo;0;L;;;;;N;;;;;
+124AD;CUNEIFORM SIGN EZEN SHESHIG TIMES ASH;Lo;0;L;;;;;N;;;;;
+124AE;CUNEIFORM SIGN EZEN SHESHIG TIMES HI;Lo;0;L;;;;;N;;;;;
+124AF;CUNEIFORM SIGN EZEN SHESHIG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+124B0;CUNEIFORM SIGN EZEN SHESHIG TIMES LA;Lo;0;L;;;;;N;;;;;
+124B1;CUNEIFORM SIGN EZEN SHESHIG TIMES LAL;Lo;0;L;;;;;N;;;;;
+124B2;CUNEIFORM SIGN EZEN SHESHIG TIMES ME;Lo;0;L;;;;;N;;;;;
+124B3;CUNEIFORM SIGN EZEN SHESHIG TIMES MES;Lo;0;L;;;;;N;;;;;
+124B4;CUNEIFORM SIGN EZEN SHESHIG TIMES SU;Lo;0;L;;;;;N;;;;;
+124B5;CUNEIFORM SIGN EZEN TIMES SU;Lo;0;L;;;;;N;;;;;
+124B6;CUNEIFORM SIGN GA2 TIMES BAHAR2;Lo;0;L;;;;;N;;;;;
+124B7;CUNEIFORM SIGN GA2 TIMES DIM GUNU;Lo;0;L;;;;;N;;;;;
+124B8;CUNEIFORM SIGN GA2 TIMES DUG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+124B9;CUNEIFORM SIGN GA2 TIMES DUG TIMES KASKAL;Lo;0;L;;;;;N;;;;;
+124BA;CUNEIFORM SIGN GA2 TIMES EREN;Lo;0;L;;;;;N;;;;;
+124BB;CUNEIFORM SIGN GA2 TIMES GA;Lo;0;L;;;;;N;;;;;
+124BC;CUNEIFORM SIGN GA2 TIMES GAR PLUS DI;Lo;0;L;;;;;N;;;;;
+124BD;CUNEIFORM SIGN GA2 TIMES GAR PLUS NE;Lo;0;L;;;;;N;;;;;
+124BE;CUNEIFORM SIGN GA2 TIMES HA PLUS A;Lo;0;L;;;;;N;;;;;
+124BF;CUNEIFORM SIGN GA2 TIMES KUSHU2 PLUS KASKAL;Lo;0;L;;;;;N;;;;;
+124C0;CUNEIFORM SIGN GA2 TIMES LAM;Lo;0;L;;;;;N;;;;;
+124C1;CUNEIFORM SIGN GA2 TIMES LAM TIMES KUR;Lo;0;L;;;;;N;;;;;
+124C2;CUNEIFORM SIGN GA2 TIMES LUH;Lo;0;L;;;;;N;;;;;
+124C3;CUNEIFORM SIGN GA2 TIMES MUSH;Lo;0;L;;;;;N;;;;;
+124C4;CUNEIFORM SIGN GA2 TIMES NE;Lo;0;L;;;;;N;;;;;
+124C5;CUNEIFORM SIGN GA2 TIMES NE PLUS E2;Lo;0;L;;;;;N;;;;;
+124C6;CUNEIFORM SIGN GA2 TIMES NE PLUS GI;Lo;0;L;;;;;N;;;;;
+124C7;CUNEIFORM SIGN GA2 TIMES SHIM;Lo;0;L;;;;;N;;;;;
+124C8;CUNEIFORM SIGN GA2 TIMES ZIZ2;Lo;0;L;;;;;N;;;;;
+124C9;CUNEIFORM SIGN GABA ROTATED NINETY DEGREES;Lo;0;L;;;;;N;;;;;
+124CA;CUNEIFORM SIGN GESHTIN TIMES U;Lo;0;L;;;;;N;;;;;
+124CB;CUNEIFORM SIGN GISH TIMES GISH CROSSING GISH;Lo;0;L;;;;;N;;;;;
+124CC;CUNEIFORM SIGN GU2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+124CD;CUNEIFORM SIGN GUD PLUS GISH TIMES TAK4;Lo;0;L;;;;;N;;;;;
+124CE;CUNEIFORM SIGN HA TENU GUNU;Lo;0;L;;;;;N;;;;;
+124CF;CUNEIFORM SIGN HI TIMES ASH OVER HI TIMES ASH;Lo;0;L;;;;;N;;;;;
+124D0;CUNEIFORM SIGN KA TIMES BU;Lo;0;L;;;;;N;;;;;
+124D1;CUNEIFORM SIGN KA TIMES KA;Lo;0;L;;;;;N;;;;;
+124D2;CUNEIFORM SIGN KA TIMES U U U;Lo;0;L;;;;;N;;;;;
+124D3;CUNEIFORM SIGN KA TIMES UR;Lo;0;L;;;;;N;;;;;
+124D4;CUNEIFORM SIGN LAGAB TIMES ZU OVER ZU;Lo;0;L;;;;;N;;;;;
+124D5;CUNEIFORM SIGN LAK-003;Lo;0;L;;;;;N;;;;;
+124D6;CUNEIFORM SIGN LAK-021;Lo;0;L;;;;;N;;;;;
+124D7;CUNEIFORM SIGN LAK-025;Lo;0;L;;;;;N;;;;;
+124D8;CUNEIFORM SIGN LAK-030;Lo;0;L;;;;;N;;;;;
+124D9;CUNEIFORM SIGN LAK-050;Lo;0;L;;;;;N;;;;;
+124DA;CUNEIFORM SIGN LAK-051;Lo;0;L;;;;;N;;;;;
+124DB;CUNEIFORM SIGN LAK-062;Lo;0;L;;;;;N;;;;;
+124DC;CUNEIFORM SIGN LAK-079 OVER LAK-079 GUNU;Lo;0;L;;;;;N;;;;;
+124DD;CUNEIFORM SIGN LAK-080;Lo;0;L;;;;;N;;;;;
+124DE;CUNEIFORM SIGN LAK-081 OVER LAK-081;Lo;0;L;;;;;N;;;;;
+124DF;CUNEIFORM SIGN LAK-092;Lo;0;L;;;;;N;;;;;
+124E0;CUNEIFORM SIGN LAK-130;Lo;0;L;;;;;N;;;;;
+124E1;CUNEIFORM SIGN LAK-142;Lo;0;L;;;;;N;;;;;
+124E2;CUNEIFORM SIGN LAK-210;Lo;0;L;;;;;N;;;;;
+124E3;CUNEIFORM SIGN LAK-219;Lo;0;L;;;;;N;;;;;
+124E4;CUNEIFORM SIGN LAK-220;Lo;0;L;;;;;N;;;;;
+124E5;CUNEIFORM SIGN LAK-225;Lo;0;L;;;;;N;;;;;
+124E6;CUNEIFORM SIGN LAK-228;Lo;0;L;;;;;N;;;;;
+124E7;CUNEIFORM SIGN LAK-238;Lo;0;L;;;;;N;;;;;
+124E8;CUNEIFORM SIGN LAK-265;Lo;0;L;;;;;N;;;;;
+124E9;CUNEIFORM SIGN LAK-266;Lo;0;L;;;;;N;;;;;
+124EA;CUNEIFORM SIGN LAK-343;Lo;0;L;;;;;N;;;;;
+124EB;CUNEIFORM SIGN LAK-347;Lo;0;L;;;;;N;;;;;
+124EC;CUNEIFORM SIGN LAK-348;Lo;0;L;;;;;N;;;;;
+124ED;CUNEIFORM SIGN LAK-383;Lo;0;L;;;;;N;;;;;
+124EE;CUNEIFORM SIGN LAK-384;Lo;0;L;;;;;N;;;;;
+124EF;CUNEIFORM SIGN LAK-390;Lo;0;L;;;;;N;;;;;
+124F0;CUNEIFORM SIGN LAK-441;Lo;0;L;;;;;N;;;;;
+124F1;CUNEIFORM SIGN LAK-449;Lo;0;L;;;;;N;;;;;
+124F2;CUNEIFORM SIGN LAK-449 TIMES GU;Lo;0;L;;;;;N;;;;;
+124F3;CUNEIFORM SIGN LAK-449 TIMES IGI;Lo;0;L;;;;;N;;;;;
+124F4;CUNEIFORM SIGN LAK-449 TIMES PAP PLUS LU3;Lo;0;L;;;;;N;;;;;
+124F5;CUNEIFORM SIGN LAK-449 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;;
+124F6;CUNEIFORM SIGN LAK-449 TIMES U2 PLUS BA;Lo;0;L;;;;;N;;;;;
+124F7;CUNEIFORM SIGN LAK-450;Lo;0;L;;;;;N;;;;;
+124F8;CUNEIFORM SIGN LAK-457;Lo;0;L;;;;;N;;;;;
+124F9;CUNEIFORM SIGN LAK-470;Lo;0;L;;;;;N;;;;;
+124FA;CUNEIFORM SIGN LAK-483;Lo;0;L;;;;;N;;;;;
+124FB;CUNEIFORM SIGN LAK-490;Lo;0;L;;;;;N;;;;;
+124FC;CUNEIFORM SIGN LAK-492;Lo;0;L;;;;;N;;;;;
+124FD;CUNEIFORM SIGN LAK-493;Lo;0;L;;;;;N;;;;;
+124FE;CUNEIFORM SIGN LAK-495;Lo;0;L;;;;;N;;;;;
+124FF;CUNEIFORM SIGN LAK-550;Lo;0;L;;;;;N;;;;;
+12500;CUNEIFORM SIGN LAK-608;Lo;0;L;;;;;N;;;;;
+12501;CUNEIFORM SIGN LAK-617;Lo;0;L;;;;;N;;;;;
+12502;CUNEIFORM SIGN LAK-617 TIMES ASH;Lo;0;L;;;;;N;;;;;
+12503;CUNEIFORM SIGN LAK-617 TIMES BAD;Lo;0;L;;;;;N;;;;;
+12504;CUNEIFORM SIGN LAK-617 TIMES DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;;
+12505;CUNEIFORM SIGN LAK-617 TIMES KU3;Lo;0;L;;;;;N;;;;;
+12506;CUNEIFORM SIGN LAK-617 TIMES LA;Lo;0;L;;;;;N;;;;;
+12507;CUNEIFORM SIGN LAK-617 TIMES TAR;Lo;0;L;;;;;N;;;;;
+12508;CUNEIFORM SIGN LAK-617 TIMES TE;Lo;0;L;;;;;N;;;;;
+12509;CUNEIFORM SIGN LAK-617 TIMES U2;Lo;0;L;;;;;N;;;;;
+1250A;CUNEIFORM SIGN LAK-617 TIMES UD;Lo;0;L;;;;;N;;;;;
+1250B;CUNEIFORM SIGN LAK-617 TIMES URUDA;Lo;0;L;;;;;N;;;;;
+1250C;CUNEIFORM SIGN LAK-636;Lo;0;L;;;;;N;;;;;
+1250D;CUNEIFORM SIGN LAK-648;Lo;0;L;;;;;N;;;;;
+1250E;CUNEIFORM SIGN LAK-648 TIMES DUB;Lo;0;L;;;;;N;;;;;
+1250F;CUNEIFORM SIGN LAK-648 TIMES GA;Lo;0;L;;;;;N;;;;;
+12510;CUNEIFORM SIGN LAK-648 TIMES IGI;Lo;0;L;;;;;N;;;;;
+12511;CUNEIFORM SIGN LAK-648 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
+12512;CUNEIFORM SIGN LAK-648 TIMES NI;Lo;0;L;;;;;N;;;;;
+12513;CUNEIFORM SIGN LAK-648 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;;
+12514;CUNEIFORM SIGN LAK-648 TIMES SHESH PLUS KI;Lo;0;L;;;;;N;;;;;
+12515;CUNEIFORM SIGN LAK-648 TIMES UD;Lo;0;L;;;;;N;;;;;
+12516;CUNEIFORM SIGN LAK-648 TIMES URUDA;Lo;0;L;;;;;N;;;;;
+12517;CUNEIFORM SIGN LAK-724;Lo;0;L;;;;;N;;;;;
+12518;CUNEIFORM SIGN LAK-749;Lo;0;L;;;;;N;;;;;
+12519;CUNEIFORM SIGN LU2 GUNU TIMES ASH;Lo;0;L;;;;;N;;;;;
+1251A;CUNEIFORM SIGN LU2 TIMES DISH;Lo;0;L;;;;;N;;;;;
+1251B;CUNEIFORM SIGN LU2 TIMES HAL;Lo;0;L;;;;;N;;;;;
+1251C;CUNEIFORM SIGN LU2 TIMES PAP;Lo;0;L;;;;;N;;;;;
+1251D;CUNEIFORM SIGN LU2 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;;
+1251E;CUNEIFORM SIGN LU2 TIMES TAK4;Lo;0;L;;;;;N;;;;;
+1251F;CUNEIFORM SIGN MI PLUS ZA7;Lo;0;L;;;;;N;;;;;
+12520;CUNEIFORM SIGN MUSH OVER MUSH TIMES GA;Lo;0;L;;;;;N;;;;;
+12521;CUNEIFORM SIGN MUSH OVER MUSH TIMES KAK;Lo;0;L;;;;;N;;;;;
+12522;CUNEIFORM SIGN NINDA2 TIMES DIM GUNU;Lo;0;L;;;;;N;;;;;
+12523;CUNEIFORM SIGN NINDA2 TIMES GISH;Lo;0;L;;;;;N;;;;;
+12524;CUNEIFORM SIGN NINDA2 TIMES GUL;Lo;0;L;;;;;N;;;;;
+12525;CUNEIFORM SIGN NINDA2 TIMES HI;Lo;0;L;;;;;N;;;;;
+12526;CUNEIFORM SIGN NINDA2 TIMES KESH2;Lo;0;L;;;;;N;;;;;
+12527;CUNEIFORM SIGN NINDA2 TIMES LAK-050;Lo;0;L;;;;;N;;;;;
+12528;CUNEIFORM SIGN NINDA2 TIMES MASH;Lo;0;L;;;;;N;;;;;
+12529;CUNEIFORM SIGN NINDA2 TIMES PAP PLUS PAP;Lo;0;L;;;;;N;;;;;
+1252A;CUNEIFORM SIGN NINDA2 TIMES U;Lo;0;L;;;;;N;;;;;
+1252B;CUNEIFORM SIGN NINDA2 TIMES U PLUS U;Lo;0;L;;;;;N;;;;;
+1252C;CUNEIFORM SIGN NINDA2 TIMES URUDA;Lo;0;L;;;;;N;;;;;
+1252D;CUNEIFORM SIGN SAG GUNU TIMES HA;Lo;0;L;;;;;N;;;;;
+1252E;CUNEIFORM SIGN SAG TIMES EN;Lo;0;L;;;;;N;;;;;
+1252F;CUNEIFORM SIGN SAG TIMES SHE AT LEFT;Lo;0;L;;;;;N;;;;;
+12530;CUNEIFORM SIGN SAG TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12531;CUNEIFORM SIGN SHA6 TENU;Lo;0;L;;;;;N;;;;;
+12532;CUNEIFORM SIGN SHE OVER SHE;Lo;0;L;;;;;N;;;;;
+12533;CUNEIFORM SIGN SHE PLUS HUB2;Lo;0;L;;;;;N;;;;;
+12534;CUNEIFORM SIGN SHE PLUS NAM2;Lo;0;L;;;;;N;;;;;
+12535;CUNEIFORM SIGN SHE PLUS SAR;Lo;0;L;;;;;N;;;;;
+12536;CUNEIFORM SIGN SHU2 PLUS DUG TIMES NI;Lo;0;L;;;;;N;;;;;
+12537;CUNEIFORM SIGN SHU2 PLUS E2 TIMES AN;Lo;0;L;;;;;N;;;;;
+12538;CUNEIFORM SIGN SI TIMES TAK4;Lo;0;L;;;;;N;;;;;
+12539;CUNEIFORM SIGN TAK4 PLUS SAG;Lo;0;L;;;;;N;;;;;
+1253A;CUNEIFORM SIGN TUM TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
+1253B;CUNEIFORM SIGN TUM TIMES THREE DISH;Lo;0;L;;;;;N;;;;;
+1253C;CUNEIFORM SIGN UR2 INVERTED;Lo;0;L;;;;;N;;;;;
+1253D;CUNEIFORM SIGN UR2 TIMES UD;Lo;0;L;;;;;N;;;;;
+1253E;CUNEIFORM SIGN URU TIMES DARA3;Lo;0;L;;;;;N;;;;;
+1253F;CUNEIFORM SIGN URU TIMES LAK-668;Lo;0;L;;;;;N;;;;;
+12540;CUNEIFORM SIGN URU TIMES LU3;Lo;0;L;;;;;N;;;;;
+12541;CUNEIFORM SIGN ZA7;Lo;0;L;;;;;N;;;;;
+12542;CUNEIFORM SIGN ZU OVER ZU PLUS SAR;Lo;0;L;;;;;N;;;;;
+12543;CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU;Lo;0;L;;;;;N;;;;;
+13000;EGYPTIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;
+13001;EGYPTIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;
+13002;EGYPTIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;
+13003;EGYPTIAN HIEROGLYPH A004;Lo;0;L;;;;;N;;;;;
+13004;EGYPTIAN HIEROGLYPH A005;Lo;0;L;;;;;N;;;;;
+13005;EGYPTIAN HIEROGLYPH A005A;Lo;0;L;;;;;N;;;;;
+13006;EGYPTIAN HIEROGLYPH A006;Lo;0;L;;;;;N;;;;;
+13007;EGYPTIAN HIEROGLYPH A006A;Lo;0;L;;;;;N;;;;;
+13008;EGYPTIAN HIEROGLYPH A006B;Lo;0;L;;;;;N;;;;;
+13009;EGYPTIAN HIEROGLYPH A007;Lo;0;L;;;;;N;;;;;
+1300A;EGYPTIAN HIEROGLYPH A008;Lo;0;L;;;;;N;;;;;
+1300B;EGYPTIAN HIEROGLYPH A009;Lo;0;L;;;;;N;;;;;
+1300C;EGYPTIAN HIEROGLYPH A010;Lo;0;L;;;;;N;;;;;
+1300D;EGYPTIAN HIEROGLYPH A011;Lo;0;L;;;;;N;;;;;
+1300E;EGYPTIAN HIEROGLYPH A012;Lo;0;L;;;;;N;;;;;
+1300F;EGYPTIAN HIEROGLYPH A013;Lo;0;L;;;;;N;;;;;
+13010;EGYPTIAN HIEROGLYPH A014;Lo;0;L;;;;;N;;;;;
+13011;EGYPTIAN HIEROGLYPH A014A;Lo;0;L;;;;;N;;;;;
+13012;EGYPTIAN HIEROGLYPH A015;Lo;0;L;;;;;N;;;;;
+13013;EGYPTIAN HIEROGLYPH A016;Lo;0;L;;;;;N;;;;;
+13014;EGYPTIAN HIEROGLYPH A017;Lo;0;L;;;;;N;;;;;
+13015;EGYPTIAN HIEROGLYPH A017A;Lo;0;L;;;;;N;;;;;
+13016;EGYPTIAN HIEROGLYPH A018;Lo;0;L;;;;;N;;;;;
+13017;EGYPTIAN HIEROGLYPH A019;Lo;0;L;;;;;N;;;;;
+13018;EGYPTIAN HIEROGLYPH A020;Lo;0;L;;;;;N;;;;;
+13019;EGYPTIAN HIEROGLYPH A021;Lo;0;L;;;;;N;;;;;
+1301A;EGYPTIAN HIEROGLYPH A022;Lo;0;L;;;;;N;;;;;
+1301B;EGYPTIAN HIEROGLYPH A023;Lo;0;L;;;;;N;;;;;
+1301C;EGYPTIAN HIEROGLYPH A024;Lo;0;L;;;;;N;;;;;
+1301D;EGYPTIAN HIEROGLYPH A025;Lo;0;L;;;;;N;;;;;
+1301E;EGYPTIAN HIEROGLYPH A026;Lo;0;L;;;;;N;;;;;
+1301F;EGYPTIAN HIEROGLYPH A027;Lo;0;L;;;;;N;;;;;
+13020;EGYPTIAN HIEROGLYPH A028;Lo;0;L;;;;;N;;;;;
+13021;EGYPTIAN HIEROGLYPH A029;Lo;0;L;;;;;N;;;;;
+13022;EGYPTIAN HIEROGLYPH A030;Lo;0;L;;;;;N;;;;;
+13023;EGYPTIAN HIEROGLYPH A031;Lo;0;L;;;;;N;;;;;
+13024;EGYPTIAN HIEROGLYPH A032;Lo;0;L;;;;;N;;;;;
+13025;EGYPTIAN HIEROGLYPH A032A;Lo;0;L;;;;;N;;;;;
+13026;EGYPTIAN HIEROGLYPH A033;Lo;0;L;;;;;N;;;;;
+13027;EGYPTIAN HIEROGLYPH A034;Lo;0;L;;;;;N;;;;;
+13028;EGYPTIAN HIEROGLYPH A035;Lo;0;L;;;;;N;;;;;
+13029;EGYPTIAN HIEROGLYPH A036;Lo;0;L;;;;;N;;;;;
+1302A;EGYPTIAN HIEROGLYPH A037;Lo;0;L;;;;;N;;;;;
+1302B;EGYPTIAN HIEROGLYPH A038;Lo;0;L;;;;;N;;;;;
+1302C;EGYPTIAN HIEROGLYPH A039;Lo;0;L;;;;;N;;;;;
+1302D;EGYPTIAN HIEROGLYPH A040;Lo;0;L;;;;;N;;;;;
+1302E;EGYPTIAN HIEROGLYPH A040A;Lo;0;L;;;;;N;;;;;
+1302F;EGYPTIAN HIEROGLYPH A041;Lo;0;L;;;;;N;;;;;
+13030;EGYPTIAN HIEROGLYPH A042;Lo;0;L;;;;;N;;;;;
+13031;EGYPTIAN HIEROGLYPH A042A;Lo;0;L;;;;;N;;;;;
+13032;EGYPTIAN HIEROGLYPH A043;Lo;0;L;;;;;N;;;;;
+13033;EGYPTIAN HIEROGLYPH A043A;Lo;0;L;;;;;N;;;;;
+13034;EGYPTIAN HIEROGLYPH A044;Lo;0;L;;;;;N;;;;;
+13035;EGYPTIAN HIEROGLYPH A045;Lo;0;L;;;;;N;;;;;
+13036;EGYPTIAN HIEROGLYPH A045A;Lo;0;L;;;;;N;;;;;
+13037;EGYPTIAN HIEROGLYPH A046;Lo;0;L;;;;;N;;;;;
+13038;EGYPTIAN HIEROGLYPH A047;Lo;0;L;;;;;N;;;;;
+13039;EGYPTIAN HIEROGLYPH A048;Lo;0;L;;;;;N;;;;;
+1303A;EGYPTIAN HIEROGLYPH A049;Lo;0;L;;;;;N;;;;;
+1303B;EGYPTIAN HIEROGLYPH A050;Lo;0;L;;;;;N;;;;;
+1303C;EGYPTIAN HIEROGLYPH A051;Lo;0;L;;;;;N;;;;;
+1303D;EGYPTIAN HIEROGLYPH A052;Lo;0;L;;;;;N;;;;;
+1303E;EGYPTIAN HIEROGLYPH A053;Lo;0;L;;;;;N;;;;;
+1303F;EGYPTIAN HIEROGLYPH A054;Lo;0;L;;;;;N;;;;;
+13040;EGYPTIAN HIEROGLYPH A055;Lo;0;L;;;;;N;;;;;
+13041;EGYPTIAN HIEROGLYPH A056;Lo;0;L;;;;;N;;;;;
+13042;EGYPTIAN HIEROGLYPH A057;Lo;0;L;;;;;N;;;;;
+13043;EGYPTIAN HIEROGLYPH A058;Lo;0;L;;;;;N;;;;;
+13044;EGYPTIAN HIEROGLYPH A059;Lo;0;L;;;;;N;;;;;
+13045;EGYPTIAN HIEROGLYPH A060;Lo;0;L;;;;;N;;;;;
+13046;EGYPTIAN HIEROGLYPH A061;Lo;0;L;;;;;N;;;;;
+13047;EGYPTIAN HIEROGLYPH A062;Lo;0;L;;;;;N;;;;;
+13048;EGYPTIAN HIEROGLYPH A063;Lo;0;L;;;;;N;;;;;
+13049;EGYPTIAN HIEROGLYPH A064;Lo;0;L;;;;;N;;;;;
+1304A;EGYPTIAN HIEROGLYPH A065;Lo;0;L;;;;;N;;;;;
+1304B;EGYPTIAN HIEROGLYPH A066;Lo;0;L;;;;;N;;;;;
+1304C;EGYPTIAN HIEROGLYPH A067;Lo;0;L;;;;;N;;;;;
+1304D;EGYPTIAN HIEROGLYPH A068;Lo;0;L;;;;;N;;;;;
+1304E;EGYPTIAN HIEROGLYPH A069;Lo;0;L;;;;;N;;;;;
+1304F;EGYPTIAN HIEROGLYPH A070;Lo;0;L;;;;;N;;;;;
+13050;EGYPTIAN HIEROGLYPH B001;Lo;0;L;;;;;N;;;;;
+13051;EGYPTIAN HIEROGLYPH B002;Lo;0;L;;;;;N;;;;;
+13052;EGYPTIAN HIEROGLYPH B003;Lo;0;L;;;;;N;;;;;
+13053;EGYPTIAN HIEROGLYPH B004;Lo;0;L;;;;;N;;;;;
+13054;EGYPTIAN HIEROGLYPH B005;Lo;0;L;;;;;N;;;;;
+13055;EGYPTIAN HIEROGLYPH B005A;Lo;0;L;;;;;N;;;;;
+13056;EGYPTIAN HIEROGLYPH B006;Lo;0;L;;;;;N;;;;;
+13057;EGYPTIAN HIEROGLYPH B007;Lo;0;L;;;;;N;;;;;
+13058;EGYPTIAN HIEROGLYPH B008;Lo;0;L;;;;;N;;;;;
+13059;EGYPTIAN HIEROGLYPH B009;Lo;0;L;;;;;N;;;;;
+1305A;EGYPTIAN HIEROGLYPH C001;Lo;0;L;;;;;N;;;;;
+1305B;EGYPTIAN HIEROGLYPH C002;Lo;0;L;;;;;N;;;;;
+1305C;EGYPTIAN HIEROGLYPH C002A;Lo;0;L;;;;;N;;;;;
+1305D;EGYPTIAN HIEROGLYPH C002B;Lo;0;L;;;;;N;;;;;
+1305E;EGYPTIAN HIEROGLYPH C002C;Lo;0;L;;;;;N;;;;;
+1305F;EGYPTIAN HIEROGLYPH C003;Lo;0;L;;;;;N;;;;;
+13060;EGYPTIAN HIEROGLYPH C004;Lo;0;L;;;;;N;;;;;
+13061;EGYPTIAN HIEROGLYPH C005;Lo;0;L;;;;;N;;;;;
+13062;EGYPTIAN HIEROGLYPH C006;Lo;0;L;;;;;N;;;;;
+13063;EGYPTIAN HIEROGLYPH C007;Lo;0;L;;;;;N;;;;;
+13064;EGYPTIAN HIEROGLYPH C008;Lo;0;L;;;;;N;;;;;
+13065;EGYPTIAN HIEROGLYPH C009;Lo;0;L;;;;;N;;;;;
+13066;EGYPTIAN HIEROGLYPH C010;Lo;0;L;;;;;N;;;;;
+13067;EGYPTIAN HIEROGLYPH C010A;Lo;0;L;;;;;N;;;;;
+13068;EGYPTIAN HIEROGLYPH C011;Lo;0;L;;;;;N;;;;;
+13069;EGYPTIAN HIEROGLYPH C012;Lo;0;L;;;;;N;;;;;
+1306A;EGYPTIAN HIEROGLYPH C013;Lo;0;L;;;;;N;;;;;
+1306B;EGYPTIAN HIEROGLYPH C014;Lo;0;L;;;;;N;;;;;
+1306C;EGYPTIAN HIEROGLYPH C015;Lo;0;L;;;;;N;;;;;
+1306D;EGYPTIAN HIEROGLYPH C016;Lo;0;L;;;;;N;;;;;
+1306E;EGYPTIAN HIEROGLYPH C017;Lo;0;L;;;;;N;;;;;
+1306F;EGYPTIAN HIEROGLYPH C018;Lo;0;L;;;;;N;;;;;
+13070;EGYPTIAN HIEROGLYPH C019;Lo;0;L;;;;;N;;;;;
+13071;EGYPTIAN HIEROGLYPH C020;Lo;0;L;;;;;N;;;;;
+13072;EGYPTIAN HIEROGLYPH C021;Lo;0;L;;;;;N;;;;;
+13073;EGYPTIAN HIEROGLYPH C022;Lo;0;L;;;;;N;;;;;
+13074;EGYPTIAN HIEROGLYPH C023;Lo;0;L;;;;;N;;;;;
+13075;EGYPTIAN HIEROGLYPH C024;Lo;0;L;;;;;N;;;;;
+13076;EGYPTIAN HIEROGLYPH D001;Lo;0;L;;;;;N;;;;;
+13077;EGYPTIAN HIEROGLYPH D002;Lo;0;L;;;;;N;;;;;
+13078;EGYPTIAN HIEROGLYPH D003;Lo;0;L;;;;;N;;;;;
+13079;EGYPTIAN HIEROGLYPH D004;Lo;0;L;;;;;N;;;;;
+1307A;EGYPTIAN HIEROGLYPH D005;Lo;0;L;;;;;N;;;;;
+1307B;EGYPTIAN HIEROGLYPH D006;Lo;0;L;;;;;N;;;;;
+1307C;EGYPTIAN HIEROGLYPH D007;Lo;0;L;;;;;N;;;;;
+1307D;EGYPTIAN HIEROGLYPH D008;Lo;0;L;;;;;N;;;;;
+1307E;EGYPTIAN HIEROGLYPH D008A;Lo;0;L;;;;;N;;;;;
+1307F;EGYPTIAN HIEROGLYPH D009;Lo;0;L;;;;;N;;;;;
+13080;EGYPTIAN HIEROGLYPH D010;Lo;0;L;;;;;N;;;;;
+13081;EGYPTIAN HIEROGLYPH D011;Lo;0;L;;;;;N;;;;;
+13082;EGYPTIAN HIEROGLYPH D012;Lo;0;L;;;;;N;;;;;
+13083;EGYPTIAN HIEROGLYPH D013;Lo;0;L;;;;;N;;;;;
+13084;EGYPTIAN HIEROGLYPH D014;Lo;0;L;;;;;N;;;;;
+13085;EGYPTIAN HIEROGLYPH D015;Lo;0;L;;;;;N;;;;;
+13086;EGYPTIAN HIEROGLYPH D016;Lo;0;L;;;;;N;;;;;
+13087;EGYPTIAN HIEROGLYPH D017;Lo;0;L;;;;;N;;;;;
+13088;EGYPTIAN HIEROGLYPH D018;Lo;0;L;;;;;N;;;;;
+13089;EGYPTIAN HIEROGLYPH D019;Lo;0;L;;;;;N;;;;;
+1308A;EGYPTIAN HIEROGLYPH D020;Lo;0;L;;;;;N;;;;;
+1308B;EGYPTIAN HIEROGLYPH D021;Lo;0;L;;;;;N;;;;;
+1308C;EGYPTIAN HIEROGLYPH D022;Lo;0;L;;;;;N;;;;;
+1308D;EGYPTIAN HIEROGLYPH D023;Lo;0;L;;;;;N;;;;;
+1308E;EGYPTIAN HIEROGLYPH D024;Lo;0;L;;;;;N;;;;;
+1308F;EGYPTIAN HIEROGLYPH D025;Lo;0;L;;;;;N;;;;;
+13090;EGYPTIAN HIEROGLYPH D026;Lo;0;L;;;;;N;;;;;
+13091;EGYPTIAN HIEROGLYPH D027;Lo;0;L;;;;;N;;;;;
+13092;EGYPTIAN HIEROGLYPH D027A;Lo;0;L;;;;;N;;;;;
+13093;EGYPTIAN HIEROGLYPH D028;Lo;0;L;;;;;N;;;;;
+13094;EGYPTIAN HIEROGLYPH D029;Lo;0;L;;;;;N;;;;;
+13095;EGYPTIAN HIEROGLYPH D030;Lo;0;L;;;;;N;;;;;
+13096;EGYPTIAN HIEROGLYPH D031;Lo;0;L;;;;;N;;;;;
+13097;EGYPTIAN HIEROGLYPH D031A;Lo;0;L;;;;;N;;;;;
+13098;EGYPTIAN HIEROGLYPH D032;Lo;0;L;;;;;N;;;;;
+13099;EGYPTIAN HIEROGLYPH D033;Lo;0;L;;;;;N;;;;;
+1309A;EGYPTIAN HIEROGLYPH D034;Lo;0;L;;;;;N;;;;;
+1309B;EGYPTIAN HIEROGLYPH D034A;Lo;0;L;;;;;N;;;;;
+1309C;EGYPTIAN HIEROGLYPH D035;Lo;0;L;;;;;N;;;;;
+1309D;EGYPTIAN HIEROGLYPH D036;Lo;0;L;;;;;N;;;;;
+1309E;EGYPTIAN HIEROGLYPH D037;Lo;0;L;;;;;N;;;;;
+1309F;EGYPTIAN HIEROGLYPH D038;Lo;0;L;;;;;N;;;;;
+130A0;EGYPTIAN HIEROGLYPH D039;Lo;0;L;;;;;N;;;;;
+130A1;EGYPTIAN HIEROGLYPH D040;Lo;0;L;;;;;N;;;;;
+130A2;EGYPTIAN HIEROGLYPH D041;Lo;0;L;;;;;N;;;;;
+130A3;EGYPTIAN HIEROGLYPH D042;Lo;0;L;;;;;N;;;;;
+130A4;EGYPTIAN HIEROGLYPH D043;Lo;0;L;;;;;N;;;;;
+130A5;EGYPTIAN HIEROGLYPH D044;Lo;0;L;;;;;N;;;;;
+130A6;EGYPTIAN HIEROGLYPH D045;Lo;0;L;;;;;N;;;;;
+130A7;EGYPTIAN HIEROGLYPH D046;Lo;0;L;;;;;N;;;;;
+130A8;EGYPTIAN HIEROGLYPH D046A;Lo;0;L;;;;;N;;;;;
+130A9;EGYPTIAN HIEROGLYPH D047;Lo;0;L;;;;;N;;;;;
+130AA;EGYPTIAN HIEROGLYPH D048;Lo;0;L;;;;;N;;;;;
+130AB;EGYPTIAN HIEROGLYPH D048A;Lo;0;L;;;;;N;;;;;
+130AC;EGYPTIAN HIEROGLYPH D049;Lo;0;L;;;;;N;;;;;
+130AD;EGYPTIAN HIEROGLYPH D050;Lo;0;L;;;;;N;;;;;
+130AE;EGYPTIAN HIEROGLYPH D050A;Lo;0;L;;;;;N;;;;;
+130AF;EGYPTIAN HIEROGLYPH D050B;Lo;0;L;;;;;N;;;;;
+130B0;EGYPTIAN HIEROGLYPH D050C;Lo;0;L;;;;;N;;;;;
+130B1;EGYPTIAN HIEROGLYPH D050D;Lo;0;L;;;;;N;;;;;
+130B2;EGYPTIAN HIEROGLYPH D050E;Lo;0;L;;;;;N;;;;;
+130B3;EGYPTIAN HIEROGLYPH D050F;Lo;0;L;;;;;N;;;;;
+130B4;EGYPTIAN HIEROGLYPH D050G;Lo;0;L;;;;;N;;;;;
+130B5;EGYPTIAN HIEROGLYPH D050H;Lo;0;L;;;;;N;;;;;
+130B6;EGYPTIAN HIEROGLYPH D050I;Lo;0;L;;;;;N;;;;;
+130B7;EGYPTIAN HIEROGLYPH D051;Lo;0;L;;;;;N;;;;;
+130B8;EGYPTIAN HIEROGLYPH D052;Lo;0;L;;;;;N;;;;;
+130B9;EGYPTIAN HIEROGLYPH D052A;Lo;0;L;;;;;N;;;;;
+130BA;EGYPTIAN HIEROGLYPH D053;Lo;0;L;;;;;N;;;;;
+130BB;EGYPTIAN HIEROGLYPH D054;Lo;0;L;;;;;N;;;;;
+130BC;EGYPTIAN HIEROGLYPH D054A;Lo;0;L;;;;;N;;;;;
+130BD;EGYPTIAN HIEROGLYPH D055;Lo;0;L;;;;;N;;;;;
+130BE;EGYPTIAN HIEROGLYPH D056;Lo;0;L;;;;;N;;;;;
+130BF;EGYPTIAN HIEROGLYPH D057;Lo;0;L;;;;;N;;;;;
+130C0;EGYPTIAN HIEROGLYPH D058;Lo;0;L;;;;;N;;;;;
+130C1;EGYPTIAN HIEROGLYPH D059;Lo;0;L;;;;;N;;;;;
+130C2;EGYPTIAN HIEROGLYPH D060;Lo;0;L;;;;;N;;;;;
+130C3;EGYPTIAN HIEROGLYPH D061;Lo;0;L;;;;;N;;;;;
+130C4;EGYPTIAN HIEROGLYPH D062;Lo;0;L;;;;;N;;;;;
+130C5;EGYPTIAN HIEROGLYPH D063;Lo;0;L;;;;;N;;;;;
+130C6;EGYPTIAN HIEROGLYPH D064;Lo;0;L;;;;;N;;;;;
+130C7;EGYPTIAN HIEROGLYPH D065;Lo;0;L;;;;;N;;;;;
+130C8;EGYPTIAN HIEROGLYPH D066;Lo;0;L;;;;;N;;;;;
+130C9;EGYPTIAN HIEROGLYPH D067;Lo;0;L;;;;;N;;;;;
+130CA;EGYPTIAN HIEROGLYPH D067A;Lo;0;L;;;;;N;;;;;
+130CB;EGYPTIAN HIEROGLYPH D067B;Lo;0;L;;;;;N;;;;;
+130CC;EGYPTIAN HIEROGLYPH D067C;Lo;0;L;;;;;N;;;;;
+130CD;EGYPTIAN HIEROGLYPH D067D;Lo;0;L;;;;;N;;;;;
+130CE;EGYPTIAN HIEROGLYPH D067E;Lo;0;L;;;;;N;;;;;
+130CF;EGYPTIAN HIEROGLYPH D067F;Lo;0;L;;;;;N;;;;;
+130D0;EGYPTIAN HIEROGLYPH D067G;Lo;0;L;;;;;N;;;;;
+130D1;EGYPTIAN HIEROGLYPH D067H;Lo;0;L;;;;;N;;;;;
+130D2;EGYPTIAN HIEROGLYPH E001;Lo;0;L;;;;;N;;;;;
+130D3;EGYPTIAN HIEROGLYPH E002;Lo;0;L;;;;;N;;;;;
+130D4;EGYPTIAN HIEROGLYPH E003;Lo;0;L;;;;;N;;;;;
+130D5;EGYPTIAN HIEROGLYPH E004;Lo;0;L;;;;;N;;;;;
+130D6;EGYPTIAN HIEROGLYPH E005;Lo;0;L;;;;;N;;;;;
+130D7;EGYPTIAN HIEROGLYPH E006;Lo;0;L;;;;;N;;;;;
+130D8;EGYPTIAN HIEROGLYPH E007;Lo;0;L;;;;;N;;;;;
+130D9;EGYPTIAN HIEROGLYPH E008;Lo;0;L;;;;;N;;;;;
+130DA;EGYPTIAN HIEROGLYPH E008A;Lo;0;L;;;;;N;;;;;
+130DB;EGYPTIAN HIEROGLYPH E009;Lo;0;L;;;;;N;;;;;
+130DC;EGYPTIAN HIEROGLYPH E009A;Lo;0;L;;;;;N;;;;;
+130DD;EGYPTIAN HIEROGLYPH E010;Lo;0;L;;;;;N;;;;;
+130DE;EGYPTIAN HIEROGLYPH E011;Lo;0;L;;;;;N;;;;;
+130DF;EGYPTIAN HIEROGLYPH E012;Lo;0;L;;;;;N;;;;;
+130E0;EGYPTIAN HIEROGLYPH E013;Lo;0;L;;;;;N;;;;;
+130E1;EGYPTIAN HIEROGLYPH E014;Lo;0;L;;;;;N;;;;;
+130E2;EGYPTIAN HIEROGLYPH E015;Lo;0;L;;;;;N;;;;;
+130E3;EGYPTIAN HIEROGLYPH E016;Lo;0;L;;;;;N;;;;;
+130E4;EGYPTIAN HIEROGLYPH E016A;Lo;0;L;;;;;N;;;;;
+130E5;EGYPTIAN HIEROGLYPH E017;Lo;0;L;;;;;N;;;;;
+130E6;EGYPTIAN HIEROGLYPH E017A;Lo;0;L;;;;;N;;;;;
+130E7;EGYPTIAN HIEROGLYPH E018;Lo;0;L;;;;;N;;;;;
+130E8;EGYPTIAN HIEROGLYPH E019;Lo;0;L;;;;;N;;;;;
+130E9;EGYPTIAN HIEROGLYPH E020;Lo;0;L;;;;;N;;;;;
+130EA;EGYPTIAN HIEROGLYPH E020A;Lo;0;L;;;;;N;;;;;
+130EB;EGYPTIAN HIEROGLYPH E021;Lo;0;L;;;;;N;;;;;
+130EC;EGYPTIAN HIEROGLYPH E022;Lo;0;L;;;;;N;;;;;
+130ED;EGYPTIAN HIEROGLYPH E023;Lo;0;L;;;;;N;;;;;
+130EE;EGYPTIAN HIEROGLYPH E024;Lo;0;L;;;;;N;;;;;
+130EF;EGYPTIAN HIEROGLYPH E025;Lo;0;L;;;;;N;;;;;
+130F0;EGYPTIAN HIEROGLYPH E026;Lo;0;L;;;;;N;;;;;
+130F1;EGYPTIAN HIEROGLYPH E027;Lo;0;L;;;;;N;;;;;
+130F2;EGYPTIAN HIEROGLYPH E028;Lo;0;L;;;;;N;;;;;
+130F3;EGYPTIAN HIEROGLYPH E028A;Lo;0;L;;;;;N;;;;;
+130F4;EGYPTIAN HIEROGLYPH E029;Lo;0;L;;;;;N;;;;;
+130F5;EGYPTIAN HIEROGLYPH E030;Lo;0;L;;;;;N;;;;;
+130F6;EGYPTIAN HIEROGLYPH E031;Lo;0;L;;;;;N;;;;;
+130F7;EGYPTIAN HIEROGLYPH E032;Lo;0;L;;;;;N;;;;;
+130F8;EGYPTIAN HIEROGLYPH E033;Lo;0;L;;;;;N;;;;;
+130F9;EGYPTIAN HIEROGLYPH E034;Lo;0;L;;;;;N;;;;;
+130FA;EGYPTIAN HIEROGLYPH E034A;Lo;0;L;;;;;N;;;;;
+130FB;EGYPTIAN HIEROGLYPH E036;Lo;0;L;;;;;N;;;;;
+130FC;EGYPTIAN HIEROGLYPH E037;Lo;0;L;;;;;N;;;;;
+130FD;EGYPTIAN HIEROGLYPH E038;Lo;0;L;;;;;N;;;;;
+130FE;EGYPTIAN HIEROGLYPH F001;Lo;0;L;;;;;N;;;;;
+130FF;EGYPTIAN HIEROGLYPH F001A;Lo;0;L;;;;;N;;;;;
+13100;EGYPTIAN HIEROGLYPH F002;Lo;0;L;;;;;N;;;;;
+13101;EGYPTIAN HIEROGLYPH F003;Lo;0;L;;;;;N;;;;;
+13102;EGYPTIAN HIEROGLYPH F004;Lo;0;L;;;;;N;;;;;
+13103;EGYPTIAN HIEROGLYPH F005;Lo;0;L;;;;;N;;;;;
+13104;EGYPTIAN HIEROGLYPH F006;Lo;0;L;;;;;N;;;;;
+13105;EGYPTIAN HIEROGLYPH F007;Lo;0;L;;;;;N;;;;;
+13106;EGYPTIAN HIEROGLYPH F008;Lo;0;L;;;;;N;;;;;
+13107;EGYPTIAN HIEROGLYPH F009;Lo;0;L;;;;;N;;;;;
+13108;EGYPTIAN HIEROGLYPH F010;Lo;0;L;;;;;N;;;;;
+13109;EGYPTIAN HIEROGLYPH F011;Lo;0;L;;;;;N;;;;;
+1310A;EGYPTIAN HIEROGLYPH F012;Lo;0;L;;;;;N;;;;;
+1310B;EGYPTIAN HIEROGLYPH F013;Lo;0;L;;;;;N;;;;;
+1310C;EGYPTIAN HIEROGLYPH F013A;Lo;0;L;;;;;N;;;;;
+1310D;EGYPTIAN HIEROGLYPH F014;Lo;0;L;;;;;N;;;;;
+1310E;EGYPTIAN HIEROGLYPH F015;Lo;0;L;;;;;N;;;;;
+1310F;EGYPTIAN HIEROGLYPH F016;Lo;0;L;;;;;N;;;;;
+13110;EGYPTIAN HIEROGLYPH F017;Lo;0;L;;;;;N;;;;;
+13111;EGYPTIAN HIEROGLYPH F018;Lo;0;L;;;;;N;;;;;
+13112;EGYPTIAN HIEROGLYPH F019;Lo;0;L;;;;;N;;;;;
+13113;EGYPTIAN HIEROGLYPH F020;Lo;0;L;;;;;N;;;;;
+13114;EGYPTIAN HIEROGLYPH F021;Lo;0;L;;;;;N;;;;;
+13115;EGYPTIAN HIEROGLYPH F021A;Lo;0;L;;;;;N;;;;;
+13116;EGYPTIAN HIEROGLYPH F022;Lo;0;L;;;;;N;;;;;
+13117;EGYPTIAN HIEROGLYPH F023;Lo;0;L;;;;;N;;;;;
+13118;EGYPTIAN HIEROGLYPH F024;Lo;0;L;;;;;N;;;;;
+13119;EGYPTIAN HIEROGLYPH F025;Lo;0;L;;;;;N;;;;;
+1311A;EGYPTIAN HIEROGLYPH F026;Lo;0;L;;;;;N;;;;;
+1311B;EGYPTIAN HIEROGLYPH F027;Lo;0;L;;;;;N;;;;;
+1311C;EGYPTIAN HIEROGLYPH F028;Lo;0;L;;;;;N;;;;;
+1311D;EGYPTIAN HIEROGLYPH F029;Lo;0;L;;;;;N;;;;;
+1311E;EGYPTIAN HIEROGLYPH F030;Lo;0;L;;;;;N;;;;;
+1311F;EGYPTIAN HIEROGLYPH F031;Lo;0;L;;;;;N;;;;;
+13120;EGYPTIAN HIEROGLYPH F031A;Lo;0;L;;;;;N;;;;;
+13121;EGYPTIAN HIEROGLYPH F032;Lo;0;L;;;;;N;;;;;
+13122;EGYPTIAN HIEROGLYPH F033;Lo;0;L;;;;;N;;;;;
+13123;EGYPTIAN HIEROGLYPH F034;Lo;0;L;;;;;N;;;;;
+13124;EGYPTIAN HIEROGLYPH F035;Lo;0;L;;;;;N;;;;;
+13125;EGYPTIAN HIEROGLYPH F036;Lo;0;L;;;;;N;;;;;
+13126;EGYPTIAN HIEROGLYPH F037;Lo;0;L;;;;;N;;;;;
+13127;EGYPTIAN HIEROGLYPH F037A;Lo;0;L;;;;;N;;;;;
+13128;EGYPTIAN HIEROGLYPH F038;Lo;0;L;;;;;N;;;;;
+13129;EGYPTIAN HIEROGLYPH F038A;Lo;0;L;;;;;N;;;;;
+1312A;EGYPTIAN HIEROGLYPH F039;Lo;0;L;;;;;N;;;;;
+1312B;EGYPTIAN HIEROGLYPH F040;Lo;0;L;;;;;N;;;;;
+1312C;EGYPTIAN HIEROGLYPH F041;Lo;0;L;;;;;N;;;;;
+1312D;EGYPTIAN HIEROGLYPH F042;Lo;0;L;;;;;N;;;;;
+1312E;EGYPTIAN HIEROGLYPH F043;Lo;0;L;;;;;N;;;;;
+1312F;EGYPTIAN HIEROGLYPH F044;Lo;0;L;;;;;N;;;;;
+13130;EGYPTIAN HIEROGLYPH F045;Lo;0;L;;;;;N;;;;;
+13131;EGYPTIAN HIEROGLYPH F045A;Lo;0;L;;;;;N;;;;;
+13132;EGYPTIAN HIEROGLYPH F046;Lo;0;L;;;;;N;;;;;
+13133;EGYPTIAN HIEROGLYPH F046A;Lo;0;L;;;;;N;;;;;
+13134;EGYPTIAN HIEROGLYPH F047;Lo;0;L;;;;;N;;;;;
+13135;EGYPTIAN HIEROGLYPH F047A;Lo;0;L;;;;;N;;;;;
+13136;EGYPTIAN HIEROGLYPH F048;Lo;0;L;;;;;N;;;;;
+13137;EGYPTIAN HIEROGLYPH F049;Lo;0;L;;;;;N;;;;;
+13138;EGYPTIAN HIEROGLYPH F050;Lo;0;L;;;;;N;;;;;
+13139;EGYPTIAN HIEROGLYPH F051;Lo;0;L;;;;;N;;;;;
+1313A;EGYPTIAN HIEROGLYPH F051A;Lo;0;L;;;;;N;;;;;
+1313B;EGYPTIAN HIEROGLYPH F051B;Lo;0;L;;;;;N;;;;;
+1313C;EGYPTIAN HIEROGLYPH F051C;Lo;0;L;;;;;N;;;;;
+1313D;EGYPTIAN HIEROGLYPH F052;Lo;0;L;;;;;N;;;;;
+1313E;EGYPTIAN HIEROGLYPH F053;Lo;0;L;;;;;N;;;;;
+1313F;EGYPTIAN HIEROGLYPH G001;Lo;0;L;;;;;N;;;;;
+13140;EGYPTIAN HIEROGLYPH G002;Lo;0;L;;;;;N;;;;;
+13141;EGYPTIAN HIEROGLYPH G003;Lo;0;L;;;;;N;;;;;
+13142;EGYPTIAN HIEROGLYPH G004;Lo;0;L;;;;;N;;;;;
+13143;EGYPTIAN HIEROGLYPH G005;Lo;0;L;;;;;N;;;;;
+13144;EGYPTIAN HIEROGLYPH G006;Lo;0;L;;;;;N;;;;;
+13145;EGYPTIAN HIEROGLYPH G006A;Lo;0;L;;;;;N;;;;;
+13146;EGYPTIAN HIEROGLYPH G007;Lo;0;L;;;;;N;;;;;
+13147;EGYPTIAN HIEROGLYPH G007A;Lo;0;L;;;;;N;;;;;
+13148;EGYPTIAN HIEROGLYPH G007B;Lo;0;L;;;;;N;;;;;
+13149;EGYPTIAN HIEROGLYPH G008;Lo;0;L;;;;;N;;;;;
+1314A;EGYPTIAN HIEROGLYPH G009;Lo;0;L;;;;;N;;;;;
+1314B;EGYPTIAN HIEROGLYPH G010;Lo;0;L;;;;;N;;;;;
+1314C;EGYPTIAN HIEROGLYPH G011;Lo;0;L;;;;;N;;;;;
+1314D;EGYPTIAN HIEROGLYPH G011A;Lo;0;L;;;;;N;;;;;
+1314E;EGYPTIAN HIEROGLYPH G012;Lo;0;L;;;;;N;;;;;
+1314F;EGYPTIAN HIEROGLYPH G013;Lo;0;L;;;;;N;;;;;
+13150;EGYPTIAN HIEROGLYPH G014;Lo;0;L;;;;;N;;;;;
+13151;EGYPTIAN HIEROGLYPH G015;Lo;0;L;;;;;N;;;;;
+13152;EGYPTIAN HIEROGLYPH G016;Lo;0;L;;;;;N;;;;;
+13153;EGYPTIAN HIEROGLYPH G017;Lo;0;L;;;;;N;;;;;
+13154;EGYPTIAN HIEROGLYPH G018;Lo;0;L;;;;;N;;;;;
+13155;EGYPTIAN HIEROGLYPH G019;Lo;0;L;;;;;N;;;;;
+13156;EGYPTIAN HIEROGLYPH G020;Lo;0;L;;;;;N;;;;;
+13157;EGYPTIAN HIEROGLYPH G020A;Lo;0;L;;;;;N;;;;;
+13158;EGYPTIAN HIEROGLYPH G021;Lo;0;L;;;;;N;;;;;
+13159;EGYPTIAN HIEROGLYPH G022;Lo;0;L;;;;;N;;;;;
+1315A;EGYPTIAN HIEROGLYPH G023;Lo;0;L;;;;;N;;;;;
+1315B;EGYPTIAN HIEROGLYPH G024;Lo;0;L;;;;;N;;;;;
+1315C;EGYPTIAN HIEROGLYPH G025;Lo;0;L;;;;;N;;;;;
+1315D;EGYPTIAN HIEROGLYPH G026;Lo;0;L;;;;;N;;;;;
+1315E;EGYPTIAN HIEROGLYPH G026A;Lo;0;L;;;;;N;;;;;
+1315F;EGYPTIAN HIEROGLYPH G027;Lo;0;L;;;;;N;;;;;
+13160;EGYPTIAN HIEROGLYPH G028;Lo;0;L;;;;;N;;;;;
+13161;EGYPTIAN HIEROGLYPH G029;Lo;0;L;;;;;N;;;;;
+13162;EGYPTIAN HIEROGLYPH G030;Lo;0;L;;;;;N;;;;;
+13163;EGYPTIAN HIEROGLYPH G031;Lo;0;L;;;;;N;;;;;
+13164;EGYPTIAN HIEROGLYPH G032;Lo;0;L;;;;;N;;;;;
+13165;EGYPTIAN HIEROGLYPH G033;Lo;0;L;;;;;N;;;;;
+13166;EGYPTIAN HIEROGLYPH G034;Lo;0;L;;;;;N;;;;;
+13167;EGYPTIAN HIEROGLYPH G035;Lo;0;L;;;;;N;;;;;
+13168;EGYPTIAN HIEROGLYPH G036;Lo;0;L;;;;;N;;;;;
+13169;EGYPTIAN HIEROGLYPH G036A;Lo;0;L;;;;;N;;;;;
+1316A;EGYPTIAN HIEROGLYPH G037;Lo;0;L;;;;;N;;;;;
+1316B;EGYPTIAN HIEROGLYPH G037A;Lo;0;L;;;;;N;;;;;
+1316C;EGYPTIAN HIEROGLYPH G038;Lo;0;L;;;;;N;;;;;
+1316D;EGYPTIAN HIEROGLYPH G039;Lo;0;L;;;;;N;;;;;
+1316E;EGYPTIAN HIEROGLYPH G040;Lo;0;L;;;;;N;;;;;
+1316F;EGYPTIAN HIEROGLYPH G041;Lo;0;L;;;;;N;;;;;
+13170;EGYPTIAN HIEROGLYPH G042;Lo;0;L;;;;;N;;;;;
+13171;EGYPTIAN HIEROGLYPH G043;Lo;0;L;;;;;N;;;;;
+13172;EGYPTIAN HIEROGLYPH G043A;Lo;0;L;;;;;N;;;;;
+13173;EGYPTIAN HIEROGLYPH G044;Lo;0;L;;;;;N;;;;;
+13174;EGYPTIAN HIEROGLYPH G045;Lo;0;L;;;;;N;;;;;
+13175;EGYPTIAN HIEROGLYPH G045A;Lo;0;L;;;;;N;;;;;
+13176;EGYPTIAN HIEROGLYPH G046;Lo;0;L;;;;;N;;;;;
+13177;EGYPTIAN HIEROGLYPH G047;Lo;0;L;;;;;N;;;;;
+13178;EGYPTIAN HIEROGLYPH G048;Lo;0;L;;;;;N;;;;;
+13179;EGYPTIAN HIEROGLYPH G049;Lo;0;L;;;;;N;;;;;
+1317A;EGYPTIAN HIEROGLYPH G050;Lo;0;L;;;;;N;;;;;
+1317B;EGYPTIAN HIEROGLYPH G051;Lo;0;L;;;;;N;;;;;
+1317C;EGYPTIAN HIEROGLYPH G052;Lo;0;L;;;;;N;;;;;
+1317D;EGYPTIAN HIEROGLYPH G053;Lo;0;L;;;;;N;;;;;
+1317E;EGYPTIAN HIEROGLYPH G054;Lo;0;L;;;;;N;;;;;
+1317F;EGYPTIAN HIEROGLYPH H001;Lo;0;L;;;;;N;;;;;
+13180;EGYPTIAN HIEROGLYPH H002;Lo;0;L;;;;;N;;;;;
+13181;EGYPTIAN HIEROGLYPH H003;Lo;0;L;;;;;N;;;;;
+13182;EGYPTIAN HIEROGLYPH H004;Lo;0;L;;;;;N;;;;;
+13183;EGYPTIAN HIEROGLYPH H005;Lo;0;L;;;;;N;;;;;
+13184;EGYPTIAN HIEROGLYPH H006;Lo;0;L;;;;;N;;;;;
+13185;EGYPTIAN HIEROGLYPH H006A;Lo;0;L;;;;;N;;;;;
+13186;EGYPTIAN HIEROGLYPH H007;Lo;0;L;;;;;N;;;;;
+13187;EGYPTIAN HIEROGLYPH H008;Lo;0;L;;;;;N;;;;;
+13188;EGYPTIAN HIEROGLYPH I001;Lo;0;L;;;;;N;;;;;
+13189;EGYPTIAN HIEROGLYPH I002;Lo;0;L;;;;;N;;;;;
+1318A;EGYPTIAN HIEROGLYPH I003;Lo;0;L;;;;;N;;;;;
+1318B;EGYPTIAN HIEROGLYPH I004;Lo;0;L;;;;;N;;;;;
+1318C;EGYPTIAN HIEROGLYPH I005;Lo;0;L;;;;;N;;;;;
+1318D;EGYPTIAN HIEROGLYPH I005A;Lo;0;L;;;;;N;;;;;
+1318E;EGYPTIAN HIEROGLYPH I006;Lo;0;L;;;;;N;;;;;
+1318F;EGYPTIAN HIEROGLYPH I007;Lo;0;L;;;;;N;;;;;
+13190;EGYPTIAN HIEROGLYPH I008;Lo;0;L;;;;;N;;;;;
+13191;EGYPTIAN HIEROGLYPH I009;Lo;0;L;;;;;N;;;;;
+13192;EGYPTIAN HIEROGLYPH I009A;Lo;0;L;;;;;N;;;;;
+13193;EGYPTIAN HIEROGLYPH I010;Lo;0;L;;;;;N;;;;;
+13194;EGYPTIAN HIEROGLYPH I010A;Lo;0;L;;;;;N;;;;;
+13195;EGYPTIAN HIEROGLYPH I011;Lo;0;L;;;;;N;;;;;
+13196;EGYPTIAN HIEROGLYPH I011A;Lo;0;L;;;;;N;;;;;
+13197;EGYPTIAN HIEROGLYPH I012;Lo;0;L;;;;;N;;;;;
+13198;EGYPTIAN HIEROGLYPH I013;Lo;0;L;;;;;N;;;;;
+13199;EGYPTIAN HIEROGLYPH I014;Lo;0;L;;;;;N;;;;;
+1319A;EGYPTIAN HIEROGLYPH I015;Lo;0;L;;;;;N;;;;;
+1319B;EGYPTIAN HIEROGLYPH K001;Lo;0;L;;;;;N;;;;;
+1319C;EGYPTIAN HIEROGLYPH K002;Lo;0;L;;;;;N;;;;;
+1319D;EGYPTIAN HIEROGLYPH K003;Lo;0;L;;;;;N;;;;;
+1319E;EGYPTIAN HIEROGLYPH K004;Lo;0;L;;;;;N;;;;;
+1319F;EGYPTIAN HIEROGLYPH K005;Lo;0;L;;;;;N;;;;;
+131A0;EGYPTIAN HIEROGLYPH K006;Lo;0;L;;;;;N;;;;;
+131A1;EGYPTIAN HIEROGLYPH K007;Lo;0;L;;;;;N;;;;;
+131A2;EGYPTIAN HIEROGLYPH K008;Lo;0;L;;;;;N;;;;;
+131A3;EGYPTIAN HIEROGLYPH L001;Lo;0;L;;;;;N;;;;;
+131A4;EGYPTIAN HIEROGLYPH L002;Lo;0;L;;;;;N;;;;;
+131A5;EGYPTIAN HIEROGLYPH L002A;Lo;0;L;;;;;N;;;;;
+131A6;EGYPTIAN HIEROGLYPH L003;Lo;0;L;;;;;N;;;;;
+131A7;EGYPTIAN HIEROGLYPH L004;Lo;0;L;;;;;N;;;;;
+131A8;EGYPTIAN HIEROGLYPH L005;Lo;0;L;;;;;N;;;;;
+131A9;EGYPTIAN HIEROGLYPH L006;Lo;0;L;;;;;N;;;;;
+131AA;EGYPTIAN HIEROGLYPH L006A;Lo;0;L;;;;;N;;;;;
+131AB;EGYPTIAN HIEROGLYPH L007;Lo;0;L;;;;;N;;;;;
+131AC;EGYPTIAN HIEROGLYPH L008;Lo;0;L;;;;;N;;;;;
+131AD;EGYPTIAN HIEROGLYPH M001;Lo;0;L;;;;;N;;;;;
+131AE;EGYPTIAN HIEROGLYPH M001A;Lo;0;L;;;;;N;;;;;
+131AF;EGYPTIAN HIEROGLYPH M001B;Lo;0;L;;;;;N;;;;;
+131B0;EGYPTIAN HIEROGLYPH M002;Lo;0;L;;;;;N;;;;;
+131B1;EGYPTIAN HIEROGLYPH M003;Lo;0;L;;;;;N;;;;;
+131B2;EGYPTIAN HIEROGLYPH M003A;Lo;0;L;;;;;N;;;;;
+131B3;EGYPTIAN HIEROGLYPH M004;Lo;0;L;;;;;N;;;;;
+131B4;EGYPTIAN HIEROGLYPH M005;Lo;0;L;;;;;N;;;;;
+131B5;EGYPTIAN HIEROGLYPH M006;Lo;0;L;;;;;N;;;;;
+131B6;EGYPTIAN HIEROGLYPH M007;Lo;0;L;;;;;N;;;;;
+131B7;EGYPTIAN HIEROGLYPH M008;Lo;0;L;;;;;N;;;;;
+131B8;EGYPTIAN HIEROGLYPH M009;Lo;0;L;;;;;N;;;;;
+131B9;EGYPTIAN HIEROGLYPH M010;Lo;0;L;;;;;N;;;;;
+131BA;EGYPTIAN HIEROGLYPH M010A;Lo;0;L;;;;;N;;;;;
+131BB;EGYPTIAN HIEROGLYPH M011;Lo;0;L;;;;;N;;;;;
+131BC;EGYPTIAN HIEROGLYPH M012;Lo;0;L;;;;;N;;;;;
+131BD;EGYPTIAN HIEROGLYPH M012A;Lo;0;L;;;;;N;;;;;
+131BE;EGYPTIAN HIEROGLYPH M012B;Lo;0;L;;;;;N;;;;;
+131BF;EGYPTIAN HIEROGLYPH M012C;Lo;0;L;;;;;N;;;;;
+131C0;EGYPTIAN HIEROGLYPH M012D;Lo;0;L;;;;;N;;;;;
+131C1;EGYPTIAN HIEROGLYPH M012E;Lo;0;L;;;;;N;;;;;
+131C2;EGYPTIAN HIEROGLYPH M012F;Lo;0;L;;;;;N;;;;;
+131C3;EGYPTIAN HIEROGLYPH M012G;Lo;0;L;;;;;N;;;;;
+131C4;EGYPTIAN HIEROGLYPH M012H;Lo;0;L;;;;;N;;;;;
+131C5;EGYPTIAN HIEROGLYPH M013;Lo;0;L;;;;;N;;;;;
+131C6;EGYPTIAN HIEROGLYPH M014;Lo;0;L;;;;;N;;;;;
+131C7;EGYPTIAN HIEROGLYPH M015;Lo;0;L;;;;;N;;;;;
+131C8;EGYPTIAN HIEROGLYPH M015A;Lo;0;L;;;;;N;;;;;
+131C9;EGYPTIAN HIEROGLYPH M016;Lo;0;L;;;;;N;;;;;
+131CA;EGYPTIAN HIEROGLYPH M016A;Lo;0;L;;;;;N;;;;;
+131CB;EGYPTIAN HIEROGLYPH M017;Lo;0;L;;;;;N;;;;;
+131CC;EGYPTIAN HIEROGLYPH M017A;Lo;0;L;;;;;N;;;;;
+131CD;EGYPTIAN HIEROGLYPH M018;Lo;0;L;;;;;N;;;;;
+131CE;EGYPTIAN HIEROGLYPH M019;Lo;0;L;;;;;N;;;;;
+131CF;EGYPTIAN HIEROGLYPH M020;Lo;0;L;;;;;N;;;;;
+131D0;EGYPTIAN HIEROGLYPH M021;Lo;0;L;;;;;N;;;;;
+131D1;EGYPTIAN HIEROGLYPH M022;Lo;0;L;;;;;N;;;;;
+131D2;EGYPTIAN HIEROGLYPH M022A;Lo;0;L;;;;;N;;;;;
+131D3;EGYPTIAN HIEROGLYPH M023;Lo;0;L;;;;;N;;;;;
+131D4;EGYPTIAN HIEROGLYPH M024;Lo;0;L;;;;;N;;;;;
+131D5;EGYPTIAN HIEROGLYPH M024A;Lo;0;L;;;;;N;;;;;
+131D6;EGYPTIAN HIEROGLYPH M025;Lo;0;L;;;;;N;;;;;
+131D7;EGYPTIAN HIEROGLYPH M026;Lo;0;L;;;;;N;;;;;
+131D8;EGYPTIAN HIEROGLYPH M027;Lo;0;L;;;;;N;;;;;
+131D9;EGYPTIAN HIEROGLYPH M028;Lo;0;L;;;;;N;;;;;
+131DA;EGYPTIAN HIEROGLYPH M028A;Lo;0;L;;;;;N;;;;;
+131DB;EGYPTIAN HIEROGLYPH M029;Lo;0;L;;;;;N;;;;;
+131DC;EGYPTIAN HIEROGLYPH M030;Lo;0;L;;;;;N;;;;;
+131DD;EGYPTIAN HIEROGLYPH M031;Lo;0;L;;;;;N;;;;;
+131DE;EGYPTIAN HIEROGLYPH M031A;Lo;0;L;;;;;N;;;;;
+131DF;EGYPTIAN HIEROGLYPH M032;Lo;0;L;;;;;N;;;;;
+131E0;EGYPTIAN HIEROGLYPH M033;Lo;0;L;;;;;N;;;;;
+131E1;EGYPTIAN HIEROGLYPH M033A;Lo;0;L;;;;;N;;;;;
+131E2;EGYPTIAN HIEROGLYPH M033B;Lo;0;L;;;;;N;;;;;
+131E3;EGYPTIAN HIEROGLYPH M034;Lo;0;L;;;;;N;;;;;
+131E4;EGYPTIAN HIEROGLYPH M035;Lo;0;L;;;;;N;;;;;
+131E5;EGYPTIAN HIEROGLYPH M036;Lo;0;L;;;;;N;;;;;
+131E6;EGYPTIAN HIEROGLYPH M037;Lo;0;L;;;;;N;;;;;
+131E7;EGYPTIAN HIEROGLYPH M038;Lo;0;L;;;;;N;;;;;
+131E8;EGYPTIAN HIEROGLYPH M039;Lo;0;L;;;;;N;;;;;
+131E9;EGYPTIAN HIEROGLYPH M040;Lo;0;L;;;;;N;;;;;
+131EA;EGYPTIAN HIEROGLYPH M040A;Lo;0;L;;;;;N;;;;;
+131EB;EGYPTIAN HIEROGLYPH M041;Lo;0;L;;;;;N;;;;;
+131EC;EGYPTIAN HIEROGLYPH M042;Lo;0;L;;;;;N;;;;;
+131ED;EGYPTIAN HIEROGLYPH M043;Lo;0;L;;;;;N;;;;;
+131EE;EGYPTIAN HIEROGLYPH M044;Lo;0;L;;;;;N;;;;;
+131EF;EGYPTIAN HIEROGLYPH N001;Lo;0;L;;;;;N;;;;;
+131F0;EGYPTIAN HIEROGLYPH N002;Lo;0;L;;;;;N;;;;;
+131F1;EGYPTIAN HIEROGLYPH N003;Lo;0;L;;;;;N;;;;;
+131F2;EGYPTIAN HIEROGLYPH N004;Lo;0;L;;;;;N;;;;;
+131F3;EGYPTIAN HIEROGLYPH N005;Lo;0;L;;;;;N;;;;;
+131F4;EGYPTIAN HIEROGLYPH N006;Lo;0;L;;;;;N;;;;;
+131F5;EGYPTIAN HIEROGLYPH N007;Lo;0;L;;;;;N;;;;;
+131F6;EGYPTIAN HIEROGLYPH N008;Lo;0;L;;;;;N;;;;;
+131F7;EGYPTIAN HIEROGLYPH N009;Lo;0;L;;;;;N;;;;;
+131F8;EGYPTIAN HIEROGLYPH N010;Lo;0;L;;;;;N;;;;;
+131F9;EGYPTIAN HIEROGLYPH N011;Lo;0;L;;;;;N;;;;;
+131FA;EGYPTIAN HIEROGLYPH N012;Lo;0;L;;;;;N;;;;;
+131FB;EGYPTIAN HIEROGLYPH N013;Lo;0;L;;;;;N;;;;;
+131FC;EGYPTIAN HIEROGLYPH N014;Lo;0;L;;;;;N;;;;;
+131FD;EGYPTIAN HIEROGLYPH N015;Lo;0;L;;;;;N;;;;;
+131FE;EGYPTIAN HIEROGLYPH N016;Lo;0;L;;;;;N;;;;;
+131FF;EGYPTIAN HIEROGLYPH N017;Lo;0;L;;;;;N;;;;;
+13200;EGYPTIAN HIEROGLYPH N018;Lo;0;L;;;;;N;;;;;
+13201;EGYPTIAN HIEROGLYPH N018A;Lo;0;L;;;;;N;;;;;
+13202;EGYPTIAN HIEROGLYPH N018B;Lo;0;L;;;;;N;;;;;
+13203;EGYPTIAN HIEROGLYPH N019;Lo;0;L;;;;;N;;;;;
+13204;EGYPTIAN HIEROGLYPH N020;Lo;0;L;;;;;N;;;;;
+13205;EGYPTIAN HIEROGLYPH N021;Lo;0;L;;;;;N;;;;;
+13206;EGYPTIAN HIEROGLYPH N022;Lo;0;L;;;;;N;;;;;
+13207;EGYPTIAN HIEROGLYPH N023;Lo;0;L;;;;;N;;;;;
+13208;EGYPTIAN HIEROGLYPH N024;Lo;0;L;;;;;N;;;;;
+13209;EGYPTIAN HIEROGLYPH N025;Lo;0;L;;;;;N;;;;;
+1320A;EGYPTIAN HIEROGLYPH N025A;Lo;0;L;;;;;N;;;;;
+1320B;EGYPTIAN HIEROGLYPH N026;Lo;0;L;;;;;N;;;;;
+1320C;EGYPTIAN HIEROGLYPH N027;Lo;0;L;;;;;N;;;;;
+1320D;EGYPTIAN HIEROGLYPH N028;Lo;0;L;;;;;N;;;;;
+1320E;EGYPTIAN HIEROGLYPH N029;Lo;0;L;;;;;N;;;;;
+1320F;EGYPTIAN HIEROGLYPH N030;Lo;0;L;;;;;N;;;;;
+13210;EGYPTIAN HIEROGLYPH N031;Lo;0;L;;;;;N;;;;;
+13211;EGYPTIAN HIEROGLYPH N032;Lo;0;L;;;;;N;;;;;
+13212;EGYPTIAN HIEROGLYPH N033;Lo;0;L;;;;;N;;;;;
+13213;EGYPTIAN HIEROGLYPH N033A;Lo;0;L;;;;;N;;;;;
+13214;EGYPTIAN HIEROGLYPH N034;Lo;0;L;;;;;N;;;;;
+13215;EGYPTIAN HIEROGLYPH N034A;Lo;0;L;;;;;N;;;;;
+13216;EGYPTIAN HIEROGLYPH N035;Lo;0;L;;;;;N;;;;;
+13217;EGYPTIAN HIEROGLYPH N035A;Lo;0;L;;;;;N;;;;;
+13218;EGYPTIAN HIEROGLYPH N036;Lo;0;L;;;;;N;;;;;
+13219;EGYPTIAN HIEROGLYPH N037;Lo;0;L;;;;;N;;;;;
+1321A;EGYPTIAN HIEROGLYPH N037A;Lo;0;L;;;;;N;;;;;
+1321B;EGYPTIAN HIEROGLYPH N038;Lo;0;L;;;;;N;;;;;
+1321C;EGYPTIAN HIEROGLYPH N039;Lo;0;L;;;;;N;;;;;
+1321D;EGYPTIAN HIEROGLYPH N040;Lo;0;L;;;;;N;;;;;
+1321E;EGYPTIAN HIEROGLYPH N041;Lo;0;L;;;;;N;;;;;
+1321F;EGYPTIAN HIEROGLYPH N042;Lo;0;L;;;;;N;;;;;
+13220;EGYPTIAN HIEROGLYPH NL001;Lo;0;L;;;;;N;;;;;
+13221;EGYPTIAN HIEROGLYPH NL002;Lo;0;L;;;;;N;;;;;
+13222;EGYPTIAN HIEROGLYPH NL003;Lo;0;L;;;;;N;;;;;
+13223;EGYPTIAN HIEROGLYPH NL004;Lo;0;L;;;;;N;;;;;
+13224;EGYPTIAN HIEROGLYPH NL005;Lo;0;L;;;;;N;;;;;
+13225;EGYPTIAN HIEROGLYPH NL005A;Lo;0;L;;;;;N;;;;;
+13226;EGYPTIAN HIEROGLYPH NL006;Lo;0;L;;;;;N;;;;;
+13227;EGYPTIAN HIEROGLYPH NL007;Lo;0;L;;;;;N;;;;;
+13228;EGYPTIAN HIEROGLYPH NL008;Lo;0;L;;;;;N;;;;;
+13229;EGYPTIAN HIEROGLYPH NL009;Lo;0;L;;;;;N;;;;;
+1322A;EGYPTIAN HIEROGLYPH NL010;Lo;0;L;;;;;N;;;;;
+1322B;EGYPTIAN HIEROGLYPH NL011;Lo;0;L;;;;;N;;;;;
+1322C;EGYPTIAN HIEROGLYPH NL012;Lo;0;L;;;;;N;;;;;
+1322D;EGYPTIAN HIEROGLYPH NL013;Lo;0;L;;;;;N;;;;;
+1322E;EGYPTIAN HIEROGLYPH NL014;Lo;0;L;;;;;N;;;;;
+1322F;EGYPTIAN HIEROGLYPH NL015;Lo;0;L;;;;;N;;;;;
+13230;EGYPTIAN HIEROGLYPH NL016;Lo;0;L;;;;;N;;;;;
+13231;EGYPTIAN HIEROGLYPH NL017;Lo;0;L;;;;;N;;;;;
+13232;EGYPTIAN HIEROGLYPH NL017A;Lo;0;L;;;;;N;;;;;
+13233;EGYPTIAN HIEROGLYPH NL018;Lo;0;L;;;;;N;;;;;
+13234;EGYPTIAN HIEROGLYPH NL019;Lo;0;L;;;;;N;;;;;
+13235;EGYPTIAN HIEROGLYPH NL020;Lo;0;L;;;;;N;;;;;
+13236;EGYPTIAN HIEROGLYPH NU001;Lo;0;L;;;;;N;;;;;
+13237;EGYPTIAN HIEROGLYPH NU002;Lo;0;L;;;;;N;;;;;
+13238;EGYPTIAN HIEROGLYPH NU003;Lo;0;L;;;;;N;;;;;
+13239;EGYPTIAN HIEROGLYPH NU004;Lo;0;L;;;;;N;;;;;
+1323A;EGYPTIAN HIEROGLYPH NU005;Lo;0;L;;;;;N;;;;;
+1323B;EGYPTIAN HIEROGLYPH NU006;Lo;0;L;;;;;N;;;;;
+1323C;EGYPTIAN HIEROGLYPH NU007;Lo;0;L;;;;;N;;;;;
+1323D;EGYPTIAN HIEROGLYPH NU008;Lo;0;L;;;;;N;;;;;
+1323E;EGYPTIAN HIEROGLYPH NU009;Lo;0;L;;;;;N;;;;;
+1323F;EGYPTIAN HIEROGLYPH NU010;Lo;0;L;;;;;N;;;;;
+13240;EGYPTIAN HIEROGLYPH NU010A;Lo;0;L;;;;;N;;;;;
+13241;EGYPTIAN HIEROGLYPH NU011;Lo;0;L;;;;;N;;;;;
+13242;EGYPTIAN HIEROGLYPH NU011A;Lo;0;L;;;;;N;;;;;
+13243;EGYPTIAN HIEROGLYPH NU012;Lo;0;L;;;;;N;;;;;
+13244;EGYPTIAN HIEROGLYPH NU013;Lo;0;L;;;;;N;;;;;
+13245;EGYPTIAN HIEROGLYPH NU014;Lo;0;L;;;;;N;;;;;
+13246;EGYPTIAN HIEROGLYPH NU015;Lo;0;L;;;;;N;;;;;
+13247;EGYPTIAN HIEROGLYPH NU016;Lo;0;L;;;;;N;;;;;
+13248;EGYPTIAN HIEROGLYPH NU017;Lo;0;L;;;;;N;;;;;
+13249;EGYPTIAN HIEROGLYPH NU018;Lo;0;L;;;;;N;;;;;
+1324A;EGYPTIAN HIEROGLYPH NU018A;Lo;0;L;;;;;N;;;;;
+1324B;EGYPTIAN HIEROGLYPH NU019;Lo;0;L;;;;;N;;;;;
+1324C;EGYPTIAN HIEROGLYPH NU020;Lo;0;L;;;;;N;;;;;
+1324D;EGYPTIAN HIEROGLYPH NU021;Lo;0;L;;;;;N;;;;;
+1324E;EGYPTIAN HIEROGLYPH NU022;Lo;0;L;;;;;N;;;;;
+1324F;EGYPTIAN HIEROGLYPH NU022A;Lo;0;L;;;;;N;;;;;
+13250;EGYPTIAN HIEROGLYPH O001;Lo;0;L;;;;;N;;;;;
+13251;EGYPTIAN HIEROGLYPH O001A;Lo;0;L;;;;;N;;;;;
+13252;EGYPTIAN HIEROGLYPH O002;Lo;0;L;;;;;N;;;;;
+13253;EGYPTIAN HIEROGLYPH O003;Lo;0;L;;;;;N;;;;;
+13254;EGYPTIAN HIEROGLYPH O004;Lo;0;L;;;;;N;;;;;
+13255;EGYPTIAN HIEROGLYPH O005;Lo;0;L;;;;;N;;;;;
+13256;EGYPTIAN HIEROGLYPH O005A;Lo;0;L;;;;;N;;;;;
+13257;EGYPTIAN HIEROGLYPH O006;Lo;0;L;;;;;N;;;;;
+13258;EGYPTIAN HIEROGLYPH O006A;Lo;0;L;;;;;N;;;;;
+13259;EGYPTIAN HIEROGLYPH O006B;Lo;0;L;;;;;N;;;;;
+1325A;EGYPTIAN HIEROGLYPH O006C;Lo;0;L;;;;;N;;;;;
+1325B;EGYPTIAN HIEROGLYPH O006D;Lo;0;L;;;;;N;;;;;
+1325C;EGYPTIAN HIEROGLYPH O006E;Lo;0;L;;;;;N;;;;;
+1325D;EGYPTIAN HIEROGLYPH O006F;Lo;0;L;;;;;N;;;;;
+1325E;EGYPTIAN HIEROGLYPH O007;Lo;0;L;;;;;N;;;;;
+1325F;EGYPTIAN HIEROGLYPH O008;Lo;0;L;;;;;N;;;;;
+13260;EGYPTIAN HIEROGLYPH O009;Lo;0;L;;;;;N;;;;;
+13261;EGYPTIAN HIEROGLYPH O010;Lo;0;L;;;;;N;;;;;
+13262;EGYPTIAN HIEROGLYPH O010A;Lo;0;L;;;;;N;;;;;
+13263;EGYPTIAN HIEROGLYPH O010B;Lo;0;L;;;;;N;;;;;
+13264;EGYPTIAN HIEROGLYPH O010C;Lo;0;L;;;;;N;;;;;
+13265;EGYPTIAN HIEROGLYPH O011;Lo;0;L;;;;;N;;;;;
+13266;EGYPTIAN HIEROGLYPH O012;Lo;0;L;;;;;N;;;;;
+13267;EGYPTIAN HIEROGLYPH O013;Lo;0;L;;;;;N;;;;;
+13268;EGYPTIAN HIEROGLYPH O014;Lo;0;L;;;;;N;;;;;
+13269;EGYPTIAN HIEROGLYPH O015;Lo;0;L;;;;;N;;;;;
+1326A;EGYPTIAN HIEROGLYPH O016;Lo;0;L;;;;;N;;;;;
+1326B;EGYPTIAN HIEROGLYPH O017;Lo;0;L;;;;;N;;;;;
+1326C;EGYPTIAN HIEROGLYPH O018;Lo;0;L;;;;;N;;;;;
+1326D;EGYPTIAN HIEROGLYPH O019;Lo;0;L;;;;;N;;;;;
+1326E;EGYPTIAN HIEROGLYPH O019A;Lo;0;L;;;;;N;;;;;
+1326F;EGYPTIAN HIEROGLYPH O020;Lo;0;L;;;;;N;;;;;
+13270;EGYPTIAN HIEROGLYPH O020A;Lo;0;L;;;;;N;;;;;
+13271;EGYPTIAN HIEROGLYPH O021;Lo;0;L;;;;;N;;;;;
+13272;EGYPTIAN HIEROGLYPH O022;Lo;0;L;;;;;N;;;;;
+13273;EGYPTIAN HIEROGLYPH O023;Lo;0;L;;;;;N;;;;;
+13274;EGYPTIAN HIEROGLYPH O024;Lo;0;L;;;;;N;;;;;
+13275;EGYPTIAN HIEROGLYPH O024A;Lo;0;L;;;;;N;;;;;
+13276;EGYPTIAN HIEROGLYPH O025;Lo;0;L;;;;;N;;;;;
+13277;EGYPTIAN HIEROGLYPH O025A;Lo;0;L;;;;;N;;;;;
+13278;EGYPTIAN HIEROGLYPH O026;Lo;0;L;;;;;N;;;;;
+13279;EGYPTIAN HIEROGLYPH O027;Lo;0;L;;;;;N;;;;;
+1327A;EGYPTIAN HIEROGLYPH O028;Lo;0;L;;;;;N;;;;;
+1327B;EGYPTIAN HIEROGLYPH O029;Lo;0;L;;;;;N;;;;;
+1327C;EGYPTIAN HIEROGLYPH O029A;Lo;0;L;;;;;N;;;;;
+1327D;EGYPTIAN HIEROGLYPH O030;Lo;0;L;;;;;N;;;;;
+1327E;EGYPTIAN HIEROGLYPH O030A;Lo;0;L;;;;;N;;;;;
+1327F;EGYPTIAN HIEROGLYPH O031;Lo;0;L;;;;;N;;;;;
+13280;EGYPTIAN HIEROGLYPH O032;Lo;0;L;;;;;N;;;;;
+13281;EGYPTIAN HIEROGLYPH O033;Lo;0;L;;;;;N;;;;;
+13282;EGYPTIAN HIEROGLYPH O033A;Lo;0;L;;;;;N;;;;;
+13283;EGYPTIAN HIEROGLYPH O034;Lo;0;L;;;;;N;;;;;
+13284;EGYPTIAN HIEROGLYPH O035;Lo;0;L;;;;;N;;;;;
+13285;EGYPTIAN HIEROGLYPH O036;Lo;0;L;;;;;N;;;;;
+13286;EGYPTIAN HIEROGLYPH O036A;Lo;0;L;;;;;N;;;;;
+13287;EGYPTIAN HIEROGLYPH O036B;Lo;0;L;;;;;N;;;;;
+13288;EGYPTIAN HIEROGLYPH O036C;Lo;0;L;;;;;N;;;;;
+13289;EGYPTIAN HIEROGLYPH O036D;Lo;0;L;;;;;N;;;;;
+1328A;EGYPTIAN HIEROGLYPH O037;Lo;0;L;;;;;N;;;;;
+1328B;EGYPTIAN HIEROGLYPH O038;Lo;0;L;;;;;N;;;;;
+1328C;EGYPTIAN HIEROGLYPH O039;Lo;0;L;;;;;N;;;;;
+1328D;EGYPTIAN HIEROGLYPH O040;Lo;0;L;;;;;N;;;;;
+1328E;EGYPTIAN HIEROGLYPH O041;Lo;0;L;;;;;N;;;;;
+1328F;EGYPTIAN HIEROGLYPH O042;Lo;0;L;;;;;N;;;;;
+13290;EGYPTIAN HIEROGLYPH O043;Lo;0;L;;;;;N;;;;;
+13291;EGYPTIAN HIEROGLYPH O044;Lo;0;L;;;;;N;;;;;
+13292;EGYPTIAN HIEROGLYPH O045;Lo;0;L;;;;;N;;;;;
+13293;EGYPTIAN HIEROGLYPH O046;Lo;0;L;;;;;N;;;;;
+13294;EGYPTIAN HIEROGLYPH O047;Lo;0;L;;;;;N;;;;;
+13295;EGYPTIAN HIEROGLYPH O048;Lo;0;L;;;;;N;;;;;
+13296;EGYPTIAN HIEROGLYPH O049;Lo;0;L;;;;;N;;;;;
+13297;EGYPTIAN HIEROGLYPH O050;Lo;0;L;;;;;N;;;;;
+13298;EGYPTIAN HIEROGLYPH O050A;Lo;0;L;;;;;N;;;;;
+13299;EGYPTIAN HIEROGLYPH O050B;Lo;0;L;;;;;N;;;;;
+1329A;EGYPTIAN HIEROGLYPH O051;Lo;0;L;;;;;N;;;;;
+1329B;EGYPTIAN HIEROGLYPH P001;Lo;0;L;;;;;N;;;;;
+1329C;EGYPTIAN HIEROGLYPH P001A;Lo;0;L;;;;;N;;;;;
+1329D;EGYPTIAN HIEROGLYPH P002;Lo;0;L;;;;;N;;;;;
+1329E;EGYPTIAN HIEROGLYPH P003;Lo;0;L;;;;;N;;;;;
+1329F;EGYPTIAN HIEROGLYPH P003A;Lo;0;L;;;;;N;;;;;
+132A0;EGYPTIAN HIEROGLYPH P004;Lo;0;L;;;;;N;;;;;
+132A1;EGYPTIAN HIEROGLYPH P005;Lo;0;L;;;;;N;;;;;
+132A2;EGYPTIAN HIEROGLYPH P006;Lo;0;L;;;;;N;;;;;
+132A3;EGYPTIAN HIEROGLYPH P007;Lo;0;L;;;;;N;;;;;
+132A4;EGYPTIAN HIEROGLYPH P008;Lo;0;L;;;;;N;;;;;
+132A5;EGYPTIAN HIEROGLYPH P009;Lo;0;L;;;;;N;;;;;
+132A6;EGYPTIAN HIEROGLYPH P010;Lo;0;L;;;;;N;;;;;
+132A7;EGYPTIAN HIEROGLYPH P011;Lo;0;L;;;;;N;;;;;
+132A8;EGYPTIAN HIEROGLYPH Q001;Lo;0;L;;;;;N;;;;;
+132A9;EGYPTIAN HIEROGLYPH Q002;Lo;0;L;;;;;N;;;;;
+132AA;EGYPTIAN HIEROGLYPH Q003;Lo;0;L;;;;;N;;;;;
+132AB;EGYPTIAN HIEROGLYPH Q004;Lo;0;L;;;;;N;;;;;
+132AC;EGYPTIAN HIEROGLYPH Q005;Lo;0;L;;;;;N;;;;;
+132AD;EGYPTIAN HIEROGLYPH Q006;Lo;0;L;;;;;N;;;;;
+132AE;EGYPTIAN HIEROGLYPH Q007;Lo;0;L;;;;;N;;;;;
+132AF;EGYPTIAN HIEROGLYPH R001;Lo;0;L;;;;;N;;;;;
+132B0;EGYPTIAN HIEROGLYPH R002;Lo;0;L;;;;;N;;;;;
+132B1;EGYPTIAN HIEROGLYPH R002A;Lo;0;L;;;;;N;;;;;
+132B2;EGYPTIAN HIEROGLYPH R003;Lo;0;L;;;;;N;;;;;
+132B3;EGYPTIAN HIEROGLYPH R003A;Lo;0;L;;;;;N;;;;;
+132B4;EGYPTIAN HIEROGLYPH R003B;Lo;0;L;;;;;N;;;;;
+132B5;EGYPTIAN HIEROGLYPH R004;Lo;0;L;;;;;N;;;;;
+132B6;EGYPTIAN HIEROGLYPH R005;Lo;0;L;;;;;N;;;;;
+132B7;EGYPTIAN HIEROGLYPH R006;Lo;0;L;;;;;N;;;;;
+132B8;EGYPTIAN HIEROGLYPH R007;Lo;0;L;;;;;N;;;;;
+132B9;EGYPTIAN HIEROGLYPH R008;Lo;0;L;;;;;N;;;;;
+132BA;EGYPTIAN HIEROGLYPH R009;Lo;0;L;;;;;N;;;;;
+132BB;EGYPTIAN HIEROGLYPH R010;Lo;0;L;;;;;N;;;;;
+132BC;EGYPTIAN HIEROGLYPH R010A;Lo;0;L;;;;;N;;;;;
+132BD;EGYPTIAN HIEROGLYPH R011;Lo;0;L;;;;;N;;;;;
+132BE;EGYPTIAN HIEROGLYPH R012;Lo;0;L;;;;;N;;;;;
+132BF;EGYPTIAN HIEROGLYPH R013;Lo;0;L;;;;;N;;;;;
+132C0;EGYPTIAN HIEROGLYPH R014;Lo;0;L;;;;;N;;;;;
+132C1;EGYPTIAN HIEROGLYPH R015;Lo;0;L;;;;;N;;;;;
+132C2;EGYPTIAN HIEROGLYPH R016;Lo;0;L;;;;;N;;;;;
+132C3;EGYPTIAN HIEROGLYPH R016A;Lo;0;L;;;;;N;;;;;
+132C4;EGYPTIAN HIEROGLYPH R017;Lo;0;L;;;;;N;;;;;
+132C5;EGYPTIAN HIEROGLYPH R018;Lo;0;L;;;;;N;;;;;
+132C6;EGYPTIAN HIEROGLYPH R019;Lo;0;L;;;;;N;;;;;
+132C7;EGYPTIAN HIEROGLYPH R020;Lo;0;L;;;;;N;;;;;
+132C8;EGYPTIAN HIEROGLYPH R021;Lo;0;L;;;;;N;;;;;
+132C9;EGYPTIAN HIEROGLYPH R022;Lo;0;L;;;;;N;;;;;
+132CA;EGYPTIAN HIEROGLYPH R023;Lo;0;L;;;;;N;;;;;
+132CB;EGYPTIAN HIEROGLYPH R024;Lo;0;L;;;;;N;;;;;
+132CC;EGYPTIAN HIEROGLYPH R025;Lo;0;L;;;;;N;;;;;
+132CD;EGYPTIAN HIEROGLYPH R026;Lo;0;L;;;;;N;;;;;
+132CE;EGYPTIAN HIEROGLYPH R027;Lo;0;L;;;;;N;;;;;
+132CF;EGYPTIAN HIEROGLYPH R028;Lo;0;L;;;;;N;;;;;
+132D0;EGYPTIAN HIEROGLYPH R029;Lo;0;L;;;;;N;;;;;
+132D1;EGYPTIAN HIEROGLYPH S001;Lo;0;L;;;;;N;;;;;
+132D2;EGYPTIAN HIEROGLYPH S002;Lo;0;L;;;;;N;;;;;
+132D3;EGYPTIAN HIEROGLYPH S002A;Lo;0;L;;;;;N;;;;;
+132D4;EGYPTIAN HIEROGLYPH S003;Lo;0;L;;;;;N;;;;;
+132D5;EGYPTIAN HIEROGLYPH S004;Lo;0;L;;;;;N;;;;;
+132D6;EGYPTIAN HIEROGLYPH S005;Lo;0;L;;;;;N;;;;;
+132D7;EGYPTIAN HIEROGLYPH S006;Lo;0;L;;;;;N;;;;;
+132D8;EGYPTIAN HIEROGLYPH S006A;Lo;0;L;;;;;N;;;;;
+132D9;EGYPTIAN HIEROGLYPH S007;Lo;0;L;;;;;N;;;;;
+132DA;EGYPTIAN HIEROGLYPH S008;Lo;0;L;;;;;N;;;;;
+132DB;EGYPTIAN HIEROGLYPH S009;Lo;0;L;;;;;N;;;;;
+132DC;EGYPTIAN HIEROGLYPH S010;Lo;0;L;;;;;N;;;;;
+132DD;EGYPTIAN HIEROGLYPH S011;Lo;0;L;;;;;N;;;;;
+132DE;EGYPTIAN HIEROGLYPH S012;Lo;0;L;;;;;N;;;;;
+132DF;EGYPTIAN HIEROGLYPH S013;Lo;0;L;;;;;N;;;;;
+132E0;EGYPTIAN HIEROGLYPH S014;Lo;0;L;;;;;N;;;;;
+132E1;EGYPTIAN HIEROGLYPH S014A;Lo;0;L;;;;;N;;;;;
+132E2;EGYPTIAN HIEROGLYPH S014B;Lo;0;L;;;;;N;;;;;
+132E3;EGYPTIAN HIEROGLYPH S015;Lo;0;L;;;;;N;;;;;
+132E4;EGYPTIAN HIEROGLYPH S016;Lo;0;L;;;;;N;;;;;
+132E5;EGYPTIAN HIEROGLYPH S017;Lo;0;L;;;;;N;;;;;
+132E6;EGYPTIAN HIEROGLYPH S017A;Lo;0;L;;;;;N;;;;;
+132E7;EGYPTIAN HIEROGLYPH S018;Lo;0;L;;;;;N;;;;;
+132E8;EGYPTIAN HIEROGLYPH S019;Lo;0;L;;;;;N;;;;;
+132E9;EGYPTIAN HIEROGLYPH S020;Lo;0;L;;;;;N;;;;;
+132EA;EGYPTIAN HIEROGLYPH S021;Lo;0;L;;;;;N;;;;;
+132EB;EGYPTIAN HIEROGLYPH S022;Lo;0;L;;;;;N;;;;;
+132EC;EGYPTIAN HIEROGLYPH S023;Lo;0;L;;;;;N;;;;;
+132ED;EGYPTIAN HIEROGLYPH S024;Lo;0;L;;;;;N;;;;;
+132EE;EGYPTIAN HIEROGLYPH S025;Lo;0;L;;;;;N;;;;;
+132EF;EGYPTIAN HIEROGLYPH S026;Lo;0;L;;;;;N;;;;;
+132F0;EGYPTIAN HIEROGLYPH S026A;Lo;0;L;;;;;N;;;;;
+132F1;EGYPTIAN HIEROGLYPH S026B;Lo;0;L;;;;;N;;;;;
+132F2;EGYPTIAN HIEROGLYPH S027;Lo;0;L;;;;;N;;;;;
+132F3;EGYPTIAN HIEROGLYPH S028;Lo;0;L;;;;;N;;;;;
+132F4;EGYPTIAN HIEROGLYPH S029;Lo;0;L;;;;;N;;;;;
+132F5;EGYPTIAN HIEROGLYPH S030;Lo;0;L;;;;;N;;;;;
+132F6;EGYPTIAN HIEROGLYPH S031;Lo;0;L;;;;;N;;;;;
+132F7;EGYPTIAN HIEROGLYPH S032;Lo;0;L;;;;;N;;;;;
+132F8;EGYPTIAN HIEROGLYPH S033;Lo;0;L;;;;;N;;;;;
+132F9;EGYPTIAN HIEROGLYPH S034;Lo;0;L;;;;;N;;;;;
+132FA;EGYPTIAN HIEROGLYPH S035;Lo;0;L;;;;;N;;;;;
+132FB;EGYPTIAN HIEROGLYPH S035A;Lo;0;L;;;;;N;;;;;
+132FC;EGYPTIAN HIEROGLYPH S036;Lo;0;L;;;;;N;;;;;
+132FD;EGYPTIAN HIEROGLYPH S037;Lo;0;L;;;;;N;;;;;
+132FE;EGYPTIAN HIEROGLYPH S038;Lo;0;L;;;;;N;;;;;
+132FF;EGYPTIAN HIEROGLYPH S039;Lo;0;L;;;;;N;;;;;
+13300;EGYPTIAN HIEROGLYPH S040;Lo;0;L;;;;;N;;;;;
+13301;EGYPTIAN HIEROGLYPH S041;Lo;0;L;;;;;N;;;;;
+13302;EGYPTIAN HIEROGLYPH S042;Lo;0;L;;;;;N;;;;;
+13303;EGYPTIAN HIEROGLYPH S043;Lo;0;L;;;;;N;;;;;
+13304;EGYPTIAN HIEROGLYPH S044;Lo;0;L;;;;;N;;;;;
+13305;EGYPTIAN HIEROGLYPH S045;Lo;0;L;;;;;N;;;;;
+13306;EGYPTIAN HIEROGLYPH S046;Lo;0;L;;;;;N;;;;;
+13307;EGYPTIAN HIEROGLYPH T001;Lo;0;L;;;;;N;;;;;
+13308;EGYPTIAN HIEROGLYPH T002;Lo;0;L;;;;;N;;;;;
+13309;EGYPTIAN HIEROGLYPH T003;Lo;0;L;;;;;N;;;;;
+1330A;EGYPTIAN HIEROGLYPH T003A;Lo;0;L;;;;;N;;;;;
+1330B;EGYPTIAN HIEROGLYPH T004;Lo;0;L;;;;;N;;;;;
+1330C;EGYPTIAN HIEROGLYPH T005;Lo;0;L;;;;;N;;;;;
+1330D;EGYPTIAN HIEROGLYPH T006;Lo;0;L;;;;;N;;;;;
+1330E;EGYPTIAN HIEROGLYPH T007;Lo;0;L;;;;;N;;;;;
+1330F;EGYPTIAN HIEROGLYPH T007A;Lo;0;L;;;;;N;;;;;
+13310;EGYPTIAN HIEROGLYPH T008;Lo;0;L;;;;;N;;;;;
+13311;EGYPTIAN HIEROGLYPH T008A;Lo;0;L;;;;;N;;;;;
+13312;EGYPTIAN HIEROGLYPH T009;Lo;0;L;;;;;N;;;;;
+13313;EGYPTIAN HIEROGLYPH T009A;Lo;0;L;;;;;N;;;;;
+13314;EGYPTIAN HIEROGLYPH T010;Lo;0;L;;;;;N;;;;;
+13315;EGYPTIAN HIEROGLYPH T011;Lo;0;L;;;;;N;;;;;
+13316;EGYPTIAN HIEROGLYPH T011A;Lo;0;L;;;;;N;;;;;
+13317;EGYPTIAN HIEROGLYPH T012;Lo;0;L;;;;;N;;;;;
+13318;EGYPTIAN HIEROGLYPH T013;Lo;0;L;;;;;N;;;;;
+13319;EGYPTIAN HIEROGLYPH T014;Lo;0;L;;;;;N;;;;;
+1331A;EGYPTIAN HIEROGLYPH T015;Lo;0;L;;;;;N;;;;;
+1331B;EGYPTIAN HIEROGLYPH T016;Lo;0;L;;;;;N;;;;;
+1331C;EGYPTIAN HIEROGLYPH T016A;Lo;0;L;;;;;N;;;;;
+1331D;EGYPTIAN HIEROGLYPH T017;Lo;0;L;;;;;N;;;;;
+1331E;EGYPTIAN HIEROGLYPH T018;Lo;0;L;;;;;N;;;;;
+1331F;EGYPTIAN HIEROGLYPH T019;Lo;0;L;;;;;N;;;;;
+13320;EGYPTIAN HIEROGLYPH T020;Lo;0;L;;;;;N;;;;;
+13321;EGYPTIAN HIEROGLYPH T021;Lo;0;L;;;;;N;;;;;
+13322;EGYPTIAN HIEROGLYPH T022;Lo;0;L;;;;;N;;;;;
+13323;EGYPTIAN HIEROGLYPH T023;Lo;0;L;;;;;N;;;;;
+13324;EGYPTIAN HIEROGLYPH T024;Lo;0;L;;;;;N;;;;;
+13325;EGYPTIAN HIEROGLYPH T025;Lo;0;L;;;;;N;;;;;
+13326;EGYPTIAN HIEROGLYPH T026;Lo;0;L;;;;;N;;;;;
+13327;EGYPTIAN HIEROGLYPH T027;Lo;0;L;;;;;N;;;;;
+13328;EGYPTIAN HIEROGLYPH T028;Lo;0;L;;;;;N;;;;;
+13329;EGYPTIAN HIEROGLYPH T029;Lo;0;L;;;;;N;;;;;
+1332A;EGYPTIAN HIEROGLYPH T030;Lo;0;L;;;;;N;;;;;
+1332B;EGYPTIAN HIEROGLYPH T031;Lo;0;L;;;;;N;;;;;
+1332C;EGYPTIAN HIEROGLYPH T032;Lo;0;L;;;;;N;;;;;
+1332D;EGYPTIAN HIEROGLYPH T032A;Lo;0;L;;;;;N;;;;;
+1332E;EGYPTIAN HIEROGLYPH T033;Lo;0;L;;;;;N;;;;;
+1332F;EGYPTIAN HIEROGLYPH T033A;Lo;0;L;;;;;N;;;;;
+13330;EGYPTIAN HIEROGLYPH T034;Lo;0;L;;;;;N;;;;;
+13331;EGYPTIAN HIEROGLYPH T035;Lo;0;L;;;;;N;;;;;
+13332;EGYPTIAN HIEROGLYPH T036;Lo;0;L;;;;;N;;;;;
+13333;EGYPTIAN HIEROGLYPH U001;Lo;0;L;;;;;N;;;;;
+13334;EGYPTIAN HIEROGLYPH U002;Lo;0;L;;;;;N;;;;;
+13335;EGYPTIAN HIEROGLYPH U003;Lo;0;L;;;;;N;;;;;
+13336;EGYPTIAN HIEROGLYPH U004;Lo;0;L;;;;;N;;;;;
+13337;EGYPTIAN HIEROGLYPH U005;Lo;0;L;;;;;N;;;;;
+13338;EGYPTIAN HIEROGLYPH U006;Lo;0;L;;;;;N;;;;;
+13339;EGYPTIAN HIEROGLYPH U006A;Lo;0;L;;;;;N;;;;;
+1333A;EGYPTIAN HIEROGLYPH U006B;Lo;0;L;;;;;N;;;;;
+1333B;EGYPTIAN HIEROGLYPH U007;Lo;0;L;;;;;N;;;;;
+1333C;EGYPTIAN HIEROGLYPH U008;Lo;0;L;;;;;N;;;;;
+1333D;EGYPTIAN HIEROGLYPH U009;Lo;0;L;;;;;N;;;;;
+1333E;EGYPTIAN HIEROGLYPH U010;Lo;0;L;;;;;N;;;;;
+1333F;EGYPTIAN HIEROGLYPH U011;Lo;0;L;;;;;N;;;;;
+13340;EGYPTIAN HIEROGLYPH U012;Lo;0;L;;;;;N;;;;;
+13341;EGYPTIAN HIEROGLYPH U013;Lo;0;L;;;;;N;;;;;
+13342;EGYPTIAN HIEROGLYPH U014;Lo;0;L;;;;;N;;;;;
+13343;EGYPTIAN HIEROGLYPH U015;Lo;0;L;;;;;N;;;;;
+13344;EGYPTIAN HIEROGLYPH U016;Lo;0;L;;;;;N;;;;;
+13345;EGYPTIAN HIEROGLYPH U017;Lo;0;L;;;;;N;;;;;
+13346;EGYPTIAN HIEROGLYPH U018;Lo;0;L;;;;;N;;;;;
+13347;EGYPTIAN HIEROGLYPH U019;Lo;0;L;;;;;N;;;;;
+13348;EGYPTIAN HIEROGLYPH U020;Lo;0;L;;;;;N;;;;;
+13349;EGYPTIAN HIEROGLYPH U021;Lo;0;L;;;;;N;;;;;
+1334A;EGYPTIAN HIEROGLYPH U022;Lo;0;L;;;;;N;;;;;
+1334B;EGYPTIAN HIEROGLYPH U023;Lo;0;L;;;;;N;;;;;
+1334C;EGYPTIAN HIEROGLYPH U023A;Lo;0;L;;;;;N;;;;;
+1334D;EGYPTIAN HIEROGLYPH U024;Lo;0;L;;;;;N;;;;;
+1334E;EGYPTIAN HIEROGLYPH U025;Lo;0;L;;;;;N;;;;;
+1334F;EGYPTIAN HIEROGLYPH U026;Lo;0;L;;;;;N;;;;;
+13350;EGYPTIAN HIEROGLYPH U027;Lo;0;L;;;;;N;;;;;
+13351;EGYPTIAN HIEROGLYPH U028;Lo;0;L;;;;;N;;;;;
+13352;EGYPTIAN HIEROGLYPH U029;Lo;0;L;;;;;N;;;;;
+13353;EGYPTIAN HIEROGLYPH U029A;Lo;0;L;;;;;N;;;;;
+13354;EGYPTIAN HIEROGLYPH U030;Lo;0;L;;;;;N;;;;;
+13355;EGYPTIAN HIEROGLYPH U031;Lo;0;L;;;;;N;;;;;
+13356;EGYPTIAN HIEROGLYPH U032;Lo;0;L;;;;;N;;;;;
+13357;EGYPTIAN HIEROGLYPH U032A;Lo;0;L;;;;;N;;;;;
+13358;EGYPTIAN HIEROGLYPH U033;Lo;0;L;;;;;N;;;;;
+13359;EGYPTIAN HIEROGLYPH U034;Lo;0;L;;;;;N;;;;;
+1335A;EGYPTIAN HIEROGLYPH U035;Lo;0;L;;;;;N;;;;;
+1335B;EGYPTIAN HIEROGLYPH U036;Lo;0;L;;;;;N;;;;;
+1335C;EGYPTIAN HIEROGLYPH U037;Lo;0;L;;;;;N;;;;;
+1335D;EGYPTIAN HIEROGLYPH U038;Lo;0;L;;;;;N;;;;;
+1335E;EGYPTIAN HIEROGLYPH U039;Lo;0;L;;;;;N;;;;;
+1335F;EGYPTIAN HIEROGLYPH U040;Lo;0;L;;;;;N;;;;;
+13360;EGYPTIAN HIEROGLYPH U041;Lo;0;L;;;;;N;;;;;
+13361;EGYPTIAN HIEROGLYPH U042;Lo;0;L;;;;;N;;;;;
+13362;EGYPTIAN HIEROGLYPH V001;Lo;0;L;;;;;N;;;;;
+13363;EGYPTIAN HIEROGLYPH V001A;Lo;0;L;;;;;N;;;;;
+13364;EGYPTIAN HIEROGLYPH V001B;Lo;0;L;;;;;N;;;;;
+13365;EGYPTIAN HIEROGLYPH V001C;Lo;0;L;;;;;N;;;;;
+13366;EGYPTIAN HIEROGLYPH V001D;Lo;0;L;;;;;N;;;;;
+13367;EGYPTIAN HIEROGLYPH V001E;Lo;0;L;;;;;N;;;;;
+13368;EGYPTIAN HIEROGLYPH V001F;Lo;0;L;;;;;N;;;;;
+13369;EGYPTIAN HIEROGLYPH V001G;Lo;0;L;;;;;N;;;;;
+1336A;EGYPTIAN HIEROGLYPH V001H;Lo;0;L;;;;;N;;;;;
+1336B;EGYPTIAN HIEROGLYPH V001I;Lo;0;L;;;;;N;;;;;
+1336C;EGYPTIAN HIEROGLYPH V002;Lo;0;L;;;;;N;;;;;
+1336D;EGYPTIAN HIEROGLYPH V002A;Lo;0;L;;;;;N;;;;;
+1336E;EGYPTIAN HIEROGLYPH V003;Lo;0;L;;;;;N;;;;;
+1336F;EGYPTIAN HIEROGLYPH V004;Lo;0;L;;;;;N;;;;;
+13370;EGYPTIAN HIEROGLYPH V005;Lo;0;L;;;;;N;;;;;
+13371;EGYPTIAN HIEROGLYPH V006;Lo;0;L;;;;;N;;;;;
+13372;EGYPTIAN HIEROGLYPH V007;Lo;0;L;;;;;N;;;;;
+13373;EGYPTIAN HIEROGLYPH V007A;Lo;0;L;;;;;N;;;;;
+13374;EGYPTIAN HIEROGLYPH V007B;Lo;0;L;;;;;N;;;;;
+13375;EGYPTIAN HIEROGLYPH V008;Lo;0;L;;;;;N;;;;;
+13376;EGYPTIAN HIEROGLYPH V009;Lo;0;L;;;;;N;;;;;
+13377;EGYPTIAN HIEROGLYPH V010;Lo;0;L;;;;;N;;;;;
+13378;EGYPTIAN HIEROGLYPH V011;Lo;0;L;;;;;N;;;;;
+13379;EGYPTIAN HIEROGLYPH V011A;Lo;0;L;;;;;N;;;;;
+1337A;EGYPTIAN HIEROGLYPH V011B;Lo;0;L;;;;;N;;;;;
+1337B;EGYPTIAN HIEROGLYPH V011C;Lo;0;L;;;;;N;;;;;
+1337C;EGYPTIAN HIEROGLYPH V012;Lo;0;L;;;;;N;;;;;
+1337D;EGYPTIAN HIEROGLYPH V012A;Lo;0;L;;;;;N;;;;;
+1337E;EGYPTIAN HIEROGLYPH V012B;Lo;0;L;;;;;N;;;;;
+1337F;EGYPTIAN HIEROGLYPH V013;Lo;0;L;;;;;N;;;;;
+13380;EGYPTIAN HIEROGLYPH V014;Lo;0;L;;;;;N;;;;;
+13381;EGYPTIAN HIEROGLYPH V015;Lo;0;L;;;;;N;;;;;
+13382;EGYPTIAN HIEROGLYPH V016;Lo;0;L;;;;;N;;;;;
+13383;EGYPTIAN HIEROGLYPH V017;Lo;0;L;;;;;N;;;;;
+13384;EGYPTIAN HIEROGLYPH V018;Lo;0;L;;;;;N;;;;;
+13385;EGYPTIAN HIEROGLYPH V019;Lo;0;L;;;;;N;;;;;
+13386;EGYPTIAN HIEROGLYPH V020;Lo;0;L;;;;;N;;;;;
+13387;EGYPTIAN HIEROGLYPH V020A;Lo;0;L;;;;;N;;;;;
+13388;EGYPTIAN HIEROGLYPH V020B;Lo;0;L;;;;;N;;;;;
+13389;EGYPTIAN HIEROGLYPH V020C;Lo;0;L;;;;;N;;;;;
+1338A;EGYPTIAN HIEROGLYPH V020D;Lo;0;L;;;;;N;;;;;
+1338B;EGYPTIAN HIEROGLYPH V020E;Lo;0;L;;;;;N;;;;;
+1338C;EGYPTIAN HIEROGLYPH V020F;Lo;0;L;;;;;N;;;;;
+1338D;EGYPTIAN HIEROGLYPH V020G;Lo;0;L;;;;;N;;;;;
+1338E;EGYPTIAN HIEROGLYPH V020H;Lo;0;L;;;;;N;;;;;
+1338F;EGYPTIAN HIEROGLYPH V020I;Lo;0;L;;;;;N;;;;;
+13390;EGYPTIAN HIEROGLYPH V020J;Lo;0;L;;;;;N;;;;;
+13391;EGYPTIAN HIEROGLYPH V020K;Lo;0;L;;;;;N;;;;;
+13392;EGYPTIAN HIEROGLYPH V020L;Lo;0;L;;;;;N;;;;;
+13393;EGYPTIAN HIEROGLYPH V021;Lo;0;L;;;;;N;;;;;
+13394;EGYPTIAN HIEROGLYPH V022;Lo;0;L;;;;;N;;;;;
+13395;EGYPTIAN HIEROGLYPH V023;Lo;0;L;;;;;N;;;;;
+13396;EGYPTIAN HIEROGLYPH V023A;Lo;0;L;;;;;N;;;;;
+13397;EGYPTIAN HIEROGLYPH V024;Lo;0;L;;;;;N;;;;;
+13398;EGYPTIAN HIEROGLYPH V025;Lo;0;L;;;;;N;;;;;
+13399;EGYPTIAN HIEROGLYPH V026;Lo;0;L;;;;;N;;;;;
+1339A;EGYPTIAN HIEROGLYPH V027;Lo;0;L;;;;;N;;;;;
+1339B;EGYPTIAN HIEROGLYPH V028;Lo;0;L;;;;;N;;;;;
+1339C;EGYPTIAN HIEROGLYPH V028A;Lo;0;L;;;;;N;;;;;
+1339D;EGYPTIAN HIEROGLYPH V029;Lo;0;L;;;;;N;;;;;
+1339E;EGYPTIAN HIEROGLYPH V029A;Lo;0;L;;;;;N;;;;;
+1339F;EGYPTIAN HIEROGLYPH V030;Lo;0;L;;;;;N;;;;;
+133A0;EGYPTIAN HIEROGLYPH V030A;Lo;0;L;;;;;N;;;;;
+133A1;EGYPTIAN HIEROGLYPH V031;Lo;0;L;;;;;N;;;;;
+133A2;EGYPTIAN HIEROGLYPH V031A;Lo;0;L;;;;;N;;;;;
+133A3;EGYPTIAN HIEROGLYPH V032;Lo;0;L;;;;;N;;;;;
+133A4;EGYPTIAN HIEROGLYPH V033;Lo;0;L;;;;;N;;;;;
+133A5;EGYPTIAN HIEROGLYPH V033A;Lo;0;L;;;;;N;;;;;
+133A6;EGYPTIAN HIEROGLYPH V034;Lo;0;L;;;;;N;;;;;
+133A7;EGYPTIAN HIEROGLYPH V035;Lo;0;L;;;;;N;;;;;
+133A8;EGYPTIAN HIEROGLYPH V036;Lo;0;L;;;;;N;;;;;
+133A9;EGYPTIAN HIEROGLYPH V037;Lo;0;L;;;;;N;;;;;
+133AA;EGYPTIAN HIEROGLYPH V037A;Lo;0;L;;;;;N;;;;;
+133AB;EGYPTIAN HIEROGLYPH V038;Lo;0;L;;;;;N;;;;;
+133AC;EGYPTIAN HIEROGLYPH V039;Lo;0;L;;;;;N;;;;;
+133AD;EGYPTIAN HIEROGLYPH V040;Lo;0;L;;;;;N;;;;;
+133AE;EGYPTIAN HIEROGLYPH V040A;Lo;0;L;;;;;N;;;;;
+133AF;EGYPTIAN HIEROGLYPH W001;Lo;0;L;;;;;N;;;;;
+133B0;EGYPTIAN HIEROGLYPH W002;Lo;0;L;;;;;N;;;;;
+133B1;EGYPTIAN HIEROGLYPH W003;Lo;0;L;;;;;N;;;;;
+133B2;EGYPTIAN HIEROGLYPH W003A;Lo;0;L;;;;;N;;;;;
+133B3;EGYPTIAN HIEROGLYPH W004;Lo;0;L;;;;;N;;;;;
+133B4;EGYPTIAN HIEROGLYPH W005;Lo;0;L;;;;;N;;;;;
+133B5;EGYPTIAN HIEROGLYPH W006;Lo;0;L;;;;;N;;;;;
+133B6;EGYPTIAN HIEROGLYPH W007;Lo;0;L;;;;;N;;;;;
+133B7;EGYPTIAN HIEROGLYPH W008;Lo;0;L;;;;;N;;;;;
+133B8;EGYPTIAN HIEROGLYPH W009;Lo;0;L;;;;;N;;;;;
+133B9;EGYPTIAN HIEROGLYPH W009A;Lo;0;L;;;;;N;;;;;
+133BA;EGYPTIAN HIEROGLYPH W010;Lo;0;L;;;;;N;;;;;
+133BB;EGYPTIAN HIEROGLYPH W010A;Lo;0;L;;;;;N;;;;;
+133BC;EGYPTIAN HIEROGLYPH W011;Lo;0;L;;;;;N;;;;;
+133BD;EGYPTIAN HIEROGLYPH W012;Lo;0;L;;;;;N;;;;;
+133BE;EGYPTIAN HIEROGLYPH W013;Lo;0;L;;;;;N;;;;;
+133BF;EGYPTIAN HIEROGLYPH W014;Lo;0;L;;;;;N;;;;;
+133C0;EGYPTIAN HIEROGLYPH W014A;Lo;0;L;;;;;N;;;;;
+133C1;EGYPTIAN HIEROGLYPH W015;Lo;0;L;;;;;N;;;;;
+133C2;EGYPTIAN HIEROGLYPH W016;Lo;0;L;;;;;N;;;;;
+133C3;EGYPTIAN HIEROGLYPH W017;Lo;0;L;;;;;N;;;;;
+133C4;EGYPTIAN HIEROGLYPH W017A;Lo;0;L;;;;;N;;;;;
+133C5;EGYPTIAN HIEROGLYPH W018;Lo;0;L;;;;;N;;;;;
+133C6;EGYPTIAN HIEROGLYPH W018A;Lo;0;L;;;;;N;;;;;
+133C7;EGYPTIAN HIEROGLYPH W019;Lo;0;L;;;;;N;;;;;
+133C8;EGYPTIAN HIEROGLYPH W020;Lo;0;L;;;;;N;;;;;
+133C9;EGYPTIAN HIEROGLYPH W021;Lo;0;L;;;;;N;;;;;
+133CA;EGYPTIAN HIEROGLYPH W022;Lo;0;L;;;;;N;;;;;
+133CB;EGYPTIAN HIEROGLYPH W023;Lo;0;L;;;;;N;;;;;
+133CC;EGYPTIAN HIEROGLYPH W024;Lo;0;L;;;;;N;;;;;
+133CD;EGYPTIAN HIEROGLYPH W024A;Lo;0;L;;;;;N;;;;;
+133CE;EGYPTIAN HIEROGLYPH W025;Lo;0;L;;;;;N;;;;;
+133CF;EGYPTIAN HIEROGLYPH X001;Lo;0;L;;;;;N;;;;;
+133D0;EGYPTIAN HIEROGLYPH X002;Lo;0;L;;;;;N;;;;;
+133D1;EGYPTIAN HIEROGLYPH X003;Lo;0;L;;;;;N;;;;;
+133D2;EGYPTIAN HIEROGLYPH X004;Lo;0;L;;;;;N;;;;;
+133D3;EGYPTIAN HIEROGLYPH X004A;Lo;0;L;;;;;N;;;;;
+133D4;EGYPTIAN HIEROGLYPH X004B;Lo;0;L;;;;;N;;;;;
+133D5;EGYPTIAN HIEROGLYPH X005;Lo;0;L;;;;;N;;;;;
+133D6;EGYPTIAN HIEROGLYPH X006;Lo;0;L;;;;;N;;;;;
+133D7;EGYPTIAN HIEROGLYPH X006A;Lo;0;L;;;;;N;;;;;
+133D8;EGYPTIAN HIEROGLYPH X007;Lo;0;L;;;;;N;;;;;
+133D9;EGYPTIAN HIEROGLYPH X008;Lo;0;L;;;;;N;;;;;
+133DA;EGYPTIAN HIEROGLYPH X008A;Lo;0;L;;;;;N;;;;;
+133DB;EGYPTIAN HIEROGLYPH Y001;Lo;0;L;;;;;N;;;;;
+133DC;EGYPTIAN HIEROGLYPH Y001A;Lo;0;L;;;;;N;;;;;
+133DD;EGYPTIAN HIEROGLYPH Y002;Lo;0;L;;;;;N;;;;;
+133DE;EGYPTIAN HIEROGLYPH Y003;Lo;0;L;;;;;N;;;;;
+133DF;EGYPTIAN HIEROGLYPH Y004;Lo;0;L;;;;;N;;;;;
+133E0;EGYPTIAN HIEROGLYPH Y005;Lo;0;L;;;;;N;;;;;
+133E1;EGYPTIAN HIEROGLYPH Y006;Lo;0;L;;;;;N;;;;;
+133E2;EGYPTIAN HIEROGLYPH Y007;Lo;0;L;;;;;N;;;;;
+133E3;EGYPTIAN HIEROGLYPH Y008;Lo;0;L;;;;;N;;;;;
+133E4;EGYPTIAN HIEROGLYPH Z001;Lo;0;L;;;;;N;;;;;
+133E5;EGYPTIAN HIEROGLYPH Z002;Lo;0;L;;;;;N;;;;;
+133E6;EGYPTIAN HIEROGLYPH Z002A;Lo;0;L;;;;;N;;;;;
+133E7;EGYPTIAN HIEROGLYPH Z002B;Lo;0;L;;;;;N;;;;;
+133E8;EGYPTIAN HIEROGLYPH Z002C;Lo;0;L;;;;;N;;;;;
+133E9;EGYPTIAN HIEROGLYPH Z002D;Lo;0;L;;;;;N;;;;;
+133EA;EGYPTIAN HIEROGLYPH Z003;Lo;0;L;;;;;N;;;;;
+133EB;EGYPTIAN HIEROGLYPH Z003A;Lo;0;L;;;;;N;;;;;
+133EC;EGYPTIAN HIEROGLYPH Z003B;Lo;0;L;;;;;N;;;;;
+133ED;EGYPTIAN HIEROGLYPH Z004;Lo;0;L;;;;;N;;;;;
+133EE;EGYPTIAN HIEROGLYPH Z004A;Lo;0;L;;;;;N;;;;;
+133EF;EGYPTIAN HIEROGLYPH Z005;Lo;0;L;;;;;N;;;;;
+133F0;EGYPTIAN HIEROGLYPH Z005A;Lo;0;L;;;;;N;;;;;
+133F1;EGYPTIAN HIEROGLYPH Z006;Lo;0;L;;;;;N;;;;;
+133F2;EGYPTIAN HIEROGLYPH Z007;Lo;0;L;;;;;N;;;;;
+133F3;EGYPTIAN HIEROGLYPH Z008;Lo;0;L;;;;;N;;;;;
+133F4;EGYPTIAN HIEROGLYPH Z009;Lo;0;L;;;;;N;;;;;
+133F5;EGYPTIAN HIEROGLYPH Z010;Lo;0;L;;;;;N;;;;;
+133F6;EGYPTIAN HIEROGLYPH Z011;Lo;0;L;;;;;N;;;;;
+133F7;EGYPTIAN HIEROGLYPH Z012;Lo;0;L;;;;;N;;;;;
+133F8;EGYPTIAN HIEROGLYPH Z013;Lo;0;L;;;;;N;;;;;
+133F9;EGYPTIAN HIEROGLYPH Z014;Lo;0;L;;;;;N;;;;;
+133FA;EGYPTIAN HIEROGLYPH Z015;Lo;0;L;;;;;N;;;;;
+133FB;EGYPTIAN HIEROGLYPH Z015A;Lo;0;L;;;;;N;;;;;
+133FC;EGYPTIAN HIEROGLYPH Z015B;Lo;0;L;;;;;N;;;;;
+133FD;EGYPTIAN HIEROGLYPH Z015C;Lo;0;L;;;;;N;;;;;
+133FE;EGYPTIAN HIEROGLYPH Z015D;Lo;0;L;;;;;N;;;;;
+133FF;EGYPTIAN HIEROGLYPH Z015E;Lo;0;L;;;;;N;;;;;
+13400;EGYPTIAN HIEROGLYPH Z015F;Lo;0;L;;;;;N;;;;;
+13401;EGYPTIAN HIEROGLYPH Z015G;Lo;0;L;;;;;N;;;;;
+13402;EGYPTIAN HIEROGLYPH Z015H;Lo;0;L;;;;;N;;;;;
+13403;EGYPTIAN HIEROGLYPH Z015I;Lo;0;L;;;;;N;;;;;
+13404;EGYPTIAN HIEROGLYPH Z016;Lo;0;L;;;;;N;;;;;
+13405;EGYPTIAN HIEROGLYPH Z016A;Lo;0;L;;;;;N;;;;;
+13406;EGYPTIAN HIEROGLYPH Z016B;Lo;0;L;;;;;N;;;;;
+13407;EGYPTIAN HIEROGLYPH Z016C;Lo;0;L;;;;;N;;;;;
+13408;EGYPTIAN HIEROGLYPH Z016D;Lo;0;L;;;;;N;;;;;
+13409;EGYPTIAN HIEROGLYPH Z016E;Lo;0;L;;;;;N;;;;;
+1340A;EGYPTIAN HIEROGLYPH Z016F;Lo;0;L;;;;;N;;;;;
+1340B;EGYPTIAN HIEROGLYPH Z016G;Lo;0;L;;;;;N;;;;;
+1340C;EGYPTIAN HIEROGLYPH Z016H;Lo;0;L;;;;;N;;;;;
+1340D;EGYPTIAN HIEROGLYPH AA001;Lo;0;L;;;;;N;;;;;
+1340E;EGYPTIAN HIEROGLYPH AA002;Lo;0;L;;;;;N;;;;;
+1340F;EGYPTIAN HIEROGLYPH AA003;Lo;0;L;;;;;N;;;;;
+13410;EGYPTIAN HIEROGLYPH AA004;Lo;0;L;;;;;N;;;;;
+13411;EGYPTIAN HIEROGLYPH AA005;Lo;0;L;;;;;N;;;;;
+13412;EGYPTIAN HIEROGLYPH AA006;Lo;0;L;;;;;N;;;;;
+13413;EGYPTIAN HIEROGLYPH AA007;Lo;0;L;;;;;N;;;;;
+13414;EGYPTIAN HIEROGLYPH AA007A;Lo;0;L;;;;;N;;;;;
+13415;EGYPTIAN HIEROGLYPH AA007B;Lo;0;L;;;;;N;;;;;
+13416;EGYPTIAN HIEROGLYPH AA008;Lo;0;L;;;;;N;;;;;
+13417;EGYPTIAN HIEROGLYPH AA009;Lo;0;L;;;;;N;;;;;
+13418;EGYPTIAN HIEROGLYPH AA010;Lo;0;L;;;;;N;;;;;
+13419;EGYPTIAN HIEROGLYPH AA011;Lo;0;L;;;;;N;;;;;
+1341A;EGYPTIAN HIEROGLYPH AA012;Lo;0;L;;;;;N;;;;;
+1341B;EGYPTIAN HIEROGLYPH AA013;Lo;0;L;;;;;N;;;;;
+1341C;EGYPTIAN HIEROGLYPH AA014;Lo;0;L;;;;;N;;;;;
+1341D;EGYPTIAN HIEROGLYPH AA015;Lo;0;L;;;;;N;;;;;
+1341E;EGYPTIAN HIEROGLYPH AA016;Lo;0;L;;;;;N;;;;;
+1341F;EGYPTIAN HIEROGLYPH AA017;Lo;0;L;;;;;N;;;;;
+13420;EGYPTIAN HIEROGLYPH AA018;Lo;0;L;;;;;N;;;;;
+13421;EGYPTIAN HIEROGLYPH AA019;Lo;0;L;;;;;N;;;;;
+13422;EGYPTIAN HIEROGLYPH AA020;Lo;0;L;;;;;N;;;;;
+13423;EGYPTIAN HIEROGLYPH AA021;Lo;0;L;;;;;N;;;;;
+13424;EGYPTIAN HIEROGLYPH AA022;Lo;0;L;;;;;N;;;;;
+13425;EGYPTIAN HIEROGLYPH AA023;Lo;0;L;;;;;N;;;;;
+13426;EGYPTIAN HIEROGLYPH AA024;Lo;0;L;;;;;N;;;;;
+13427;EGYPTIAN HIEROGLYPH AA025;Lo;0;L;;;;;N;;;;;
+13428;EGYPTIAN HIEROGLYPH AA026;Lo;0;L;;;;;N;;;;;
+13429;EGYPTIAN HIEROGLYPH AA027;Lo;0;L;;;;;N;;;;;
+1342A;EGYPTIAN HIEROGLYPH AA028;Lo;0;L;;;;;N;;;;;
+1342B;EGYPTIAN HIEROGLYPH AA029;Lo;0;L;;;;;N;;;;;
+1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;;
+1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;;
+1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;;
+14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;
+14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;
+14402;ANATOLIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;
+14403;ANATOLIAN HIEROGLYPH A004;Lo;0;L;;;;;N;;;;;
+14404;ANATOLIAN HIEROGLYPH A005;Lo;0;L;;;;;N;;;;;
+14405;ANATOLIAN HIEROGLYPH A006;Lo;0;L;;;;;N;;;;;
+14406;ANATOLIAN HIEROGLYPH A007;Lo;0;L;;;;;N;;;;;
+14407;ANATOLIAN HIEROGLYPH A008;Lo;0;L;;;;;N;;;;;
+14408;ANATOLIAN HIEROGLYPH A009;Lo;0;L;;;;;N;;;;;
+14409;ANATOLIAN HIEROGLYPH A010;Lo;0;L;;;;;N;;;;;
+1440A;ANATOLIAN HIEROGLYPH A010A;Lo;0;L;;;;;N;;;;;
+1440B;ANATOLIAN HIEROGLYPH A011;Lo;0;L;;;;;N;;;;;
+1440C;ANATOLIAN HIEROGLYPH A012;Lo;0;L;;;;;N;;;;;
+1440D;ANATOLIAN HIEROGLYPH A013;Lo;0;L;;;;;N;;;;;
+1440E;ANATOLIAN HIEROGLYPH A014;Lo;0;L;;;;;N;;;;;
+1440F;ANATOLIAN HIEROGLYPH A015;Lo;0;L;;;;;N;;;;;
+14410;ANATOLIAN HIEROGLYPH A016;Lo;0;L;;;;;N;;;;;
+14411;ANATOLIAN HIEROGLYPH A017;Lo;0;L;;;;;N;;;;;
+14412;ANATOLIAN HIEROGLYPH A018;Lo;0;L;;;;;N;;;;;
+14413;ANATOLIAN HIEROGLYPH A019;Lo;0;L;;;;;N;;;;;
+14414;ANATOLIAN HIEROGLYPH A020;Lo;0;L;;;;;N;;;;;
+14415;ANATOLIAN HIEROGLYPH A021;Lo;0;L;;;;;N;;;;;
+14416;ANATOLIAN HIEROGLYPH A022;Lo;0;L;;;;;N;;;;;
+14417;ANATOLIAN HIEROGLYPH A023;Lo;0;L;;;;;N;;;;;
+14418;ANATOLIAN HIEROGLYPH A024;Lo;0;L;;;;;N;;;;;
+14419;ANATOLIAN HIEROGLYPH A025;Lo;0;L;;;;;N;;;;;
+1441A;ANATOLIAN HIEROGLYPH A026;Lo;0;L;;;;;N;;;;;
+1441B;ANATOLIAN HIEROGLYPH A026A;Lo;0;L;;;;;N;;;;;
+1441C;ANATOLIAN HIEROGLYPH A027;Lo;0;L;;;;;N;;;;;
+1441D;ANATOLIAN HIEROGLYPH A028;Lo;0;L;;;;;N;;;;;
+1441E;ANATOLIAN HIEROGLYPH A029;Lo;0;L;;;;;N;;;;;
+1441F;ANATOLIAN HIEROGLYPH A030;Lo;0;L;;;;;N;;;;;
+14420;ANATOLIAN HIEROGLYPH A031;Lo;0;L;;;;;N;;;;;
+14421;ANATOLIAN HIEROGLYPH A032;Lo;0;L;;;;;N;;;;;
+14422;ANATOLIAN HIEROGLYPH A033;Lo;0;L;;;;;N;;;;;
+14423;ANATOLIAN HIEROGLYPH A034;Lo;0;L;;;;;N;;;;;
+14424;ANATOLIAN HIEROGLYPH A035;Lo;0;L;;;;;N;;;;;
+14425;ANATOLIAN HIEROGLYPH A036;Lo;0;L;;;;;N;;;;;
+14426;ANATOLIAN HIEROGLYPH A037;Lo;0;L;;;;;N;;;;;
+14427;ANATOLIAN HIEROGLYPH A038;Lo;0;L;;;;;N;;;;;
+14428;ANATOLIAN HIEROGLYPH A039;Lo;0;L;;;;;N;;;;;
+14429;ANATOLIAN HIEROGLYPH A039A;Lo;0;L;;;;;N;;;;;
+1442A;ANATOLIAN HIEROGLYPH A040;Lo;0;L;;;;;N;;;;;
+1442B;ANATOLIAN HIEROGLYPH A041;Lo;0;L;;;;;N;;;;;
+1442C;ANATOLIAN HIEROGLYPH A041A;Lo;0;L;;;;;N;;;;;
+1442D;ANATOLIAN HIEROGLYPH A042;Lo;0;L;;;;;N;;;;;
+1442E;ANATOLIAN HIEROGLYPH A043;Lo;0;L;;;;;N;;;;;
+1442F;ANATOLIAN HIEROGLYPH A044;Lo;0;L;;;;;N;;;;;
+14430;ANATOLIAN HIEROGLYPH A045;Lo;0;L;;;;;N;;;;;
+14431;ANATOLIAN HIEROGLYPH A045A;Lo;0;L;;;;;N;;;;;
+14432;ANATOLIAN HIEROGLYPH A046;Lo;0;L;;;;;N;;;;;
+14433;ANATOLIAN HIEROGLYPH A046A;Lo;0;L;;;;;N;;;;;
+14434;ANATOLIAN HIEROGLYPH A046B;Lo;0;L;;;;;N;;;;;
+14435;ANATOLIAN HIEROGLYPH A047;Lo;0;L;;;;;N;;;;;
+14436;ANATOLIAN HIEROGLYPH A048;Lo;0;L;;;;;N;;;;;
+14437;ANATOLIAN HIEROGLYPH A049;Lo;0;L;;;;;N;;;;;
+14438;ANATOLIAN HIEROGLYPH A050;Lo;0;L;;;;;N;;;;;
+14439;ANATOLIAN HIEROGLYPH A051;Lo;0;L;;;;;N;;;;;
+1443A;ANATOLIAN HIEROGLYPH A052;Lo;0;L;;;;;N;;;;;
+1443B;ANATOLIAN HIEROGLYPH A053;Lo;0;L;;;;;N;;;;;
+1443C;ANATOLIAN HIEROGLYPH A054;Lo;0;L;;;;;N;;;;;
+1443D;ANATOLIAN HIEROGLYPH A055;Lo;0;L;;;;;N;;;;;
+1443E;ANATOLIAN HIEROGLYPH A056;Lo;0;L;;;;;N;;;;;
+1443F;ANATOLIAN HIEROGLYPH A057;Lo;0;L;;;;;N;;;;;
+14440;ANATOLIAN HIEROGLYPH A058;Lo;0;L;;;;;N;;;;;
+14441;ANATOLIAN HIEROGLYPH A059;Lo;0;L;;;;;N;;;;;
+14442;ANATOLIAN HIEROGLYPH A060;Lo;0;L;;;;;N;;;;;
+14443;ANATOLIAN HIEROGLYPH A061;Lo;0;L;;;;;N;;;;;
+14444;ANATOLIAN HIEROGLYPH A062;Lo;0;L;;;;;N;;;;;
+14445;ANATOLIAN HIEROGLYPH A063;Lo;0;L;;;;;N;;;;;
+14446;ANATOLIAN HIEROGLYPH A064;Lo;0;L;;;;;N;;;;;
+14447;ANATOLIAN HIEROGLYPH A065;Lo;0;L;;;;;N;;;;;
+14448;ANATOLIAN HIEROGLYPH A066;Lo;0;L;;;;;N;;;;;
+14449;ANATOLIAN HIEROGLYPH A066A;Lo;0;L;;;;;N;;;;;
+1444A;ANATOLIAN HIEROGLYPH A066B;Lo;0;L;;;;;N;;;;;
+1444B;ANATOLIAN HIEROGLYPH A066C;Lo;0;L;;;;;N;;;;;
+1444C;ANATOLIAN HIEROGLYPH A067;Lo;0;L;;;;;N;;;;;
+1444D;ANATOLIAN HIEROGLYPH A068;Lo;0;L;;;;;N;;;;;
+1444E;ANATOLIAN HIEROGLYPH A069;Lo;0;L;;;;;N;;;;;
+1444F;ANATOLIAN HIEROGLYPH A070;Lo;0;L;;;;;N;;;;;
+14450;ANATOLIAN HIEROGLYPH A071;Lo;0;L;;;;;N;;;;;
+14451;ANATOLIAN HIEROGLYPH A072;Lo;0;L;;;;;N;;;;;
+14452;ANATOLIAN HIEROGLYPH A073;Lo;0;L;;;;;N;;;;;
+14453;ANATOLIAN HIEROGLYPH A074;Lo;0;L;;;;;N;;;;;
+14454;ANATOLIAN HIEROGLYPH A075;Lo;0;L;;;;;N;;;;;
+14455;ANATOLIAN HIEROGLYPH A076;Lo;0;L;;;;;N;;;;;
+14456;ANATOLIAN HIEROGLYPH A077;Lo;0;L;;;;;N;;;;;
+14457;ANATOLIAN HIEROGLYPH A078;Lo;0;L;;;;;N;;;;;
+14458;ANATOLIAN HIEROGLYPH A079;Lo;0;L;;;;;N;;;;;
+14459;ANATOLIAN HIEROGLYPH A080;Lo;0;L;;;;;N;;;;;
+1445A;ANATOLIAN HIEROGLYPH A081;Lo;0;L;;;;;N;;;;;
+1445B;ANATOLIAN HIEROGLYPH A082;Lo;0;L;;;;;N;;;;;
+1445C;ANATOLIAN HIEROGLYPH A083;Lo;0;L;;;;;N;;;;;
+1445D;ANATOLIAN HIEROGLYPH A084;Lo;0;L;;;;;N;;;;;
+1445E;ANATOLIAN HIEROGLYPH A085;Lo;0;L;;;;;N;;;;;
+1445F;ANATOLIAN HIEROGLYPH A086;Lo;0;L;;;;;N;;;;;
+14460;ANATOLIAN HIEROGLYPH A087;Lo;0;L;;;;;N;;;;;
+14461;ANATOLIAN HIEROGLYPH A088;Lo;0;L;;;;;N;;;;;
+14462;ANATOLIAN HIEROGLYPH A089;Lo;0;L;;;;;N;;;;;
+14463;ANATOLIAN HIEROGLYPH A090;Lo;0;L;;;;;N;;;;;
+14464;ANATOLIAN HIEROGLYPH A091;Lo;0;L;;;;;N;;;;;
+14465;ANATOLIAN HIEROGLYPH A092;Lo;0;L;;;;;N;;;;;
+14466;ANATOLIAN HIEROGLYPH A093;Lo;0;L;;;;;N;;;;;
+14467;ANATOLIAN HIEROGLYPH A094;Lo;0;L;;;;;N;;;;;
+14468;ANATOLIAN HIEROGLYPH A095;Lo;0;L;;;;;N;;;;;
+14469;ANATOLIAN HIEROGLYPH A096;Lo;0;L;;;;;N;;;;;
+1446A;ANATOLIAN HIEROGLYPH A097;Lo;0;L;;;;;N;;;;;
+1446B;ANATOLIAN HIEROGLYPH A097A;Lo;0;L;;;;;N;;;;;
+1446C;ANATOLIAN HIEROGLYPH A098;Lo;0;L;;;;;N;;;;;
+1446D;ANATOLIAN HIEROGLYPH A098A;Lo;0;L;;;;;N;;;;;
+1446E;ANATOLIAN HIEROGLYPH A099;Lo;0;L;;;;;N;;;;;
+1446F;ANATOLIAN HIEROGLYPH A100;Lo;0;L;;;;;N;;;;;
+14470;ANATOLIAN HIEROGLYPH A100A;Lo;0;L;;;;;N;;;;;
+14471;ANATOLIAN HIEROGLYPH A101;Lo;0;L;;;;;N;;;;;
+14472;ANATOLIAN HIEROGLYPH A101A;Lo;0;L;;;;;N;;;;;
+14473;ANATOLIAN HIEROGLYPH A102;Lo;0;L;;;;;N;;;;;
+14474;ANATOLIAN HIEROGLYPH A102A;Lo;0;L;;;;;N;;;;;
+14475;ANATOLIAN HIEROGLYPH A103;Lo;0;L;;;;;N;;;;;
+14476;ANATOLIAN HIEROGLYPH A104;Lo;0;L;;;;;N;;;;;
+14477;ANATOLIAN HIEROGLYPH A104A;Lo;0;L;;;;;N;;;;;
+14478;ANATOLIAN HIEROGLYPH A104B;Lo;0;L;;;;;N;;;;;
+14479;ANATOLIAN HIEROGLYPH A104C;Lo;0;L;;;;;N;;;;;
+1447A;ANATOLIAN HIEROGLYPH A105;Lo;0;L;;;;;N;;;;;
+1447B;ANATOLIAN HIEROGLYPH A105A;Lo;0;L;;;;;N;;;;;
+1447C;ANATOLIAN HIEROGLYPH A105B;Lo;0;L;;;;;N;;;;;
+1447D;ANATOLIAN HIEROGLYPH A106;Lo;0;L;;;;;N;;;;;
+1447E;ANATOLIAN HIEROGLYPH A107;Lo;0;L;;;;;N;;;;;
+1447F;ANATOLIAN HIEROGLYPH A107A;Lo;0;L;;;;;N;;;;;
+14480;ANATOLIAN HIEROGLYPH A107B;Lo;0;L;;;;;N;;;;;
+14481;ANATOLIAN HIEROGLYPH A107C;Lo;0;L;;;;;N;;;;;
+14482;ANATOLIAN HIEROGLYPH A108;Lo;0;L;;;;;N;;;;;
+14483;ANATOLIAN HIEROGLYPH A109;Lo;0;L;;;;;N;;;;;
+14484;ANATOLIAN HIEROGLYPH A110;Lo;0;L;;;;;N;;;;;
+14485;ANATOLIAN HIEROGLYPH A110A;Lo;0;L;;;;;N;;;;;
+14486;ANATOLIAN HIEROGLYPH A110B;Lo;0;L;;;;;N;;;;;
+14487;ANATOLIAN HIEROGLYPH A111;Lo;0;L;;;;;N;;;;;
+14488;ANATOLIAN HIEROGLYPH A112;Lo;0;L;;;;;N;;;;;
+14489;ANATOLIAN HIEROGLYPH A113;Lo;0;L;;;;;N;;;;;
+1448A;ANATOLIAN HIEROGLYPH A114;Lo;0;L;;;;;N;;;;;
+1448B;ANATOLIAN HIEROGLYPH A115;Lo;0;L;;;;;N;;;;;
+1448C;ANATOLIAN HIEROGLYPH A115A;Lo;0;L;;;;;N;;;;;
+1448D;ANATOLIAN HIEROGLYPH A116;Lo;0;L;;;;;N;;;;;
+1448E;ANATOLIAN HIEROGLYPH A117;Lo;0;L;;;;;N;;;;;
+1448F;ANATOLIAN HIEROGLYPH A118;Lo;0;L;;;;;N;;;;;
+14490;ANATOLIAN HIEROGLYPH A119;Lo;0;L;;;;;N;;;;;
+14491;ANATOLIAN HIEROGLYPH A120;Lo;0;L;;;;;N;;;;;
+14492;ANATOLIAN HIEROGLYPH A121;Lo;0;L;;;;;N;;;;;
+14493;ANATOLIAN HIEROGLYPH A122;Lo;0;L;;;;;N;;;;;
+14494;ANATOLIAN HIEROGLYPH A123;Lo;0;L;;;;;N;;;;;
+14495;ANATOLIAN HIEROGLYPH A124;Lo;0;L;;;;;N;;;;;
+14496;ANATOLIAN HIEROGLYPH A125;Lo;0;L;;;;;N;;;;;
+14497;ANATOLIAN HIEROGLYPH A125A;Lo;0;L;;;;;N;;;;;
+14498;ANATOLIAN HIEROGLYPH A126;Lo;0;L;;;;;N;;;;;
+14499;ANATOLIAN HIEROGLYPH A127;Lo;0;L;;;;;N;;;;;
+1449A;ANATOLIAN HIEROGLYPH A128;Lo;0;L;;;;;N;;;;;
+1449B;ANATOLIAN HIEROGLYPH A129;Lo;0;L;;;;;N;;;;;
+1449C;ANATOLIAN HIEROGLYPH A130;Lo;0;L;;;;;N;;;;;
+1449D;ANATOLIAN HIEROGLYPH A131;Lo;0;L;;;;;N;;;;;
+1449E;ANATOLIAN HIEROGLYPH A132;Lo;0;L;;;;;N;;;;;
+1449F;ANATOLIAN HIEROGLYPH A133;Lo;0;L;;;;;N;;;;;
+144A0;ANATOLIAN HIEROGLYPH A134;Lo;0;L;;;;;N;;;;;
+144A1;ANATOLIAN HIEROGLYPH A135;Lo;0;L;;;;;N;;;;;
+144A2;ANATOLIAN HIEROGLYPH A135A;Lo;0;L;;;;;N;;;;;
+144A3;ANATOLIAN HIEROGLYPH A136;Lo;0;L;;;;;N;;;;;
+144A4;ANATOLIAN HIEROGLYPH A137;Lo;0;L;;;;;N;;;;;
+144A5;ANATOLIAN HIEROGLYPH A138;Lo;0;L;;;;;N;;;;;
+144A6;ANATOLIAN HIEROGLYPH A139;Lo;0;L;;;;;N;;;;;
+144A7;ANATOLIAN HIEROGLYPH A140;Lo;0;L;;;;;N;;;;;
+144A8;ANATOLIAN HIEROGLYPH A141;Lo;0;L;;;;;N;;;;;
+144A9;ANATOLIAN HIEROGLYPH A142;Lo;0;L;;;;;N;;;;;
+144AA;ANATOLIAN HIEROGLYPH A143;Lo;0;L;;;;;N;;;;;
+144AB;ANATOLIAN HIEROGLYPH A144;Lo;0;L;;;;;N;;;;;
+144AC;ANATOLIAN HIEROGLYPH A145;Lo;0;L;;;;;N;;;;;
+144AD;ANATOLIAN HIEROGLYPH A146;Lo;0;L;;;;;N;;;;;
+144AE;ANATOLIAN HIEROGLYPH A147;Lo;0;L;;;;;N;;;;;
+144AF;ANATOLIAN HIEROGLYPH A148;Lo;0;L;;;;;N;;;;;
+144B0;ANATOLIAN HIEROGLYPH A149;Lo;0;L;;;;;N;;;;;
+144B1;ANATOLIAN HIEROGLYPH A150;Lo;0;L;;;;;N;;;;;
+144B2;ANATOLIAN HIEROGLYPH A151;Lo;0;L;;;;;N;;;;;
+144B3;ANATOLIAN HIEROGLYPH A152;Lo;0;L;;;;;N;;;;;
+144B4;ANATOLIAN HIEROGLYPH A153;Lo;0;L;;;;;N;;;;;
+144B5;ANATOLIAN HIEROGLYPH A154;Lo;0;L;;;;;N;;;;;
+144B6;ANATOLIAN HIEROGLYPH A155;Lo;0;L;;;;;N;;;;;
+144B7;ANATOLIAN HIEROGLYPH A156;Lo;0;L;;;;;N;;;;;
+144B8;ANATOLIAN HIEROGLYPH A157;Lo;0;L;;;;;N;;;;;
+144B9;ANATOLIAN HIEROGLYPH A158;Lo;0;L;;;;;N;;;;;
+144BA;ANATOLIAN HIEROGLYPH A159;Lo;0;L;;;;;N;;;;;
+144BB;ANATOLIAN HIEROGLYPH A160;Lo;0;L;;;;;N;;;;;
+144BC;ANATOLIAN HIEROGLYPH A161;Lo;0;L;;;;;N;;;;;
+144BD;ANATOLIAN HIEROGLYPH A162;Lo;0;L;;;;;N;;;;;
+144BE;ANATOLIAN HIEROGLYPH A163;Lo;0;L;;;;;N;;;;;
+144BF;ANATOLIAN HIEROGLYPH A164;Lo;0;L;;;;;N;;;;;
+144C0;ANATOLIAN HIEROGLYPH A165;Lo;0;L;;;;;N;;;;;
+144C1;ANATOLIAN HIEROGLYPH A166;Lo;0;L;;;;;N;;;;;
+144C2;ANATOLIAN HIEROGLYPH A167;Lo;0;L;;;;;N;;;;;
+144C3;ANATOLIAN HIEROGLYPH A168;Lo;0;L;;;;;N;;;;;
+144C4;ANATOLIAN HIEROGLYPH A169;Lo;0;L;;;;;N;;;;;
+144C5;ANATOLIAN HIEROGLYPH A170;Lo;0;L;;;;;N;;;;;
+144C6;ANATOLIAN HIEROGLYPH A171;Lo;0;L;;;;;N;;;;;
+144C7;ANATOLIAN HIEROGLYPH A172;Lo;0;L;;;;;N;;;;;
+144C8;ANATOLIAN HIEROGLYPH A173;Lo;0;L;;;;;N;;;;;
+144C9;ANATOLIAN HIEROGLYPH A174;Lo;0;L;;;;;N;;;;;
+144CA;ANATOLIAN HIEROGLYPH A175;Lo;0;L;;;;;N;;;;;
+144CB;ANATOLIAN HIEROGLYPH A176;Lo;0;L;;;;;N;;;;;
+144CC;ANATOLIAN HIEROGLYPH A177;Lo;0;L;;;;;N;;;;;
+144CD;ANATOLIAN HIEROGLYPH A178;Lo;0;L;;;;;N;;;;;
+144CE;ANATOLIAN HIEROGLYPH A179;Lo;0;L;;;;;N;;;;;
+144CF;ANATOLIAN HIEROGLYPH A180;Lo;0;L;;;;;N;;;;;
+144D0;ANATOLIAN HIEROGLYPH A181;Lo;0;L;;;;;N;;;;;
+144D1;ANATOLIAN HIEROGLYPH A182;Lo;0;L;;;;;N;;;;;
+144D2;ANATOLIAN HIEROGLYPH A183;Lo;0;L;;;;;N;;;;;
+144D3;ANATOLIAN HIEROGLYPH A184;Lo;0;L;;;;;N;;;;;
+144D4;ANATOLIAN HIEROGLYPH A185;Lo;0;L;;;;;N;;;;;
+144D5;ANATOLIAN HIEROGLYPH A186;Lo;0;L;;;;;N;;;;;
+144D6;ANATOLIAN HIEROGLYPH A187;Lo;0;L;;;;;N;;;;;
+144D7;ANATOLIAN HIEROGLYPH A188;Lo;0;L;;;;;N;;;;;
+144D8;ANATOLIAN HIEROGLYPH A189;Lo;0;L;;;;;N;;;;;
+144D9;ANATOLIAN HIEROGLYPH A190;Lo;0;L;;;;;N;;;;;
+144DA;ANATOLIAN HIEROGLYPH A191;Lo;0;L;;;;;N;;;;;
+144DB;ANATOLIAN HIEROGLYPH A192;Lo;0;L;;;;;N;;;;;
+144DC;ANATOLIAN HIEROGLYPH A193;Lo;0;L;;;;;N;;;;;
+144DD;ANATOLIAN HIEROGLYPH A194;Lo;0;L;;;;;N;;;;;
+144DE;ANATOLIAN HIEROGLYPH A195;Lo;0;L;;;;;N;;;;;
+144DF;ANATOLIAN HIEROGLYPH A196;Lo;0;L;;;;;N;;;;;
+144E0;ANATOLIAN HIEROGLYPH A197;Lo;0;L;;;;;N;;;;;
+144E1;ANATOLIAN HIEROGLYPH A198;Lo;0;L;;;;;N;;;;;
+144E2;ANATOLIAN HIEROGLYPH A199;Lo;0;L;;;;;N;;;;;
+144E3;ANATOLIAN HIEROGLYPH A200;Lo;0;L;;;;;N;;;;;
+144E4;ANATOLIAN HIEROGLYPH A201;Lo;0;L;;;;;N;;;;;
+144E5;ANATOLIAN HIEROGLYPH A202;Lo;0;L;;;;;N;;;;;
+144E6;ANATOLIAN HIEROGLYPH A202A;Lo;0;L;;;;;N;;;;;
+144E7;ANATOLIAN HIEROGLYPH A202B;Lo;0;L;;;;;N;;;;;
+144E8;ANATOLIAN HIEROGLYPH A203;Lo;0;L;;;;;N;;;;;
+144E9;ANATOLIAN HIEROGLYPH A204;Lo;0;L;;;;;N;;;;;
+144EA;ANATOLIAN HIEROGLYPH A205;Lo;0;L;;;;;N;;;;;
+144EB;ANATOLIAN HIEROGLYPH A206;Lo;0;L;;;;;N;;;;;
+144EC;ANATOLIAN HIEROGLYPH A207;Lo;0;L;;;;;N;;;;;
+144ED;ANATOLIAN HIEROGLYPH A207A;Lo;0;L;;;;;N;;;;;
+144EE;ANATOLIAN HIEROGLYPH A208;Lo;0;L;;;;;N;;;;;
+144EF;ANATOLIAN HIEROGLYPH A209;Lo;0;L;;;;;N;;;;;
+144F0;ANATOLIAN HIEROGLYPH A209A;Lo;0;L;;;;;N;;;;;
+144F1;ANATOLIAN HIEROGLYPH A210;Lo;0;L;;;;;N;;;;;
+144F2;ANATOLIAN HIEROGLYPH A211;Lo;0;L;;;;;N;;;;;
+144F3;ANATOLIAN HIEROGLYPH A212;Lo;0;L;;;;;N;;;;;
+144F4;ANATOLIAN HIEROGLYPH A213;Lo;0;L;;;;;N;;;;;
+144F5;ANATOLIAN HIEROGLYPH A214;Lo;0;L;;;;;N;;;;;
+144F6;ANATOLIAN HIEROGLYPH A215;Lo;0;L;;;;;N;;;;;
+144F7;ANATOLIAN HIEROGLYPH A215A;Lo;0;L;;;;;N;;;;;
+144F8;ANATOLIAN HIEROGLYPH A216;Lo;0;L;;;;;N;;;;;
+144F9;ANATOLIAN HIEROGLYPH A216A;Lo;0;L;;;;;N;;;;;
+144FA;ANATOLIAN HIEROGLYPH A217;Lo;0;L;;;;;N;;;;;
+144FB;ANATOLIAN HIEROGLYPH A218;Lo;0;L;;;;;N;;;;;
+144FC;ANATOLIAN HIEROGLYPH A219;Lo;0;L;;;;;N;;;;;
+144FD;ANATOLIAN HIEROGLYPH A220;Lo;0;L;;;;;N;;;;;
+144FE;ANATOLIAN HIEROGLYPH A221;Lo;0;L;;;;;N;;;;;
+144FF;ANATOLIAN HIEROGLYPH A222;Lo;0;L;;;;;N;;;;;
+14500;ANATOLIAN HIEROGLYPH A223;Lo;0;L;;;;;N;;;;;
+14501;ANATOLIAN HIEROGLYPH A224;Lo;0;L;;;;;N;;;;;
+14502;ANATOLIAN HIEROGLYPH A225;Lo;0;L;;;;;N;;;;;
+14503;ANATOLIAN HIEROGLYPH A226;Lo;0;L;;;;;N;;;;;
+14504;ANATOLIAN HIEROGLYPH A227;Lo;0;L;;;;;N;;;;;
+14505;ANATOLIAN HIEROGLYPH A227A;Lo;0;L;;;;;N;;;;;
+14506;ANATOLIAN HIEROGLYPH A228;Lo;0;L;;;;;N;;;;;
+14507;ANATOLIAN HIEROGLYPH A229;Lo;0;L;;;;;N;;;;;
+14508;ANATOLIAN HIEROGLYPH A230;Lo;0;L;;;;;N;;;;;
+14509;ANATOLIAN HIEROGLYPH A231;Lo;0;L;;;;;N;;;;;
+1450A;ANATOLIAN HIEROGLYPH A232;Lo;0;L;;;;;N;;;;;
+1450B;ANATOLIAN HIEROGLYPH A233;Lo;0;L;;;;;N;;;;;
+1450C;ANATOLIAN HIEROGLYPH A234;Lo;0;L;;;;;N;;;;;
+1450D;ANATOLIAN HIEROGLYPH A235;Lo;0;L;;;;;N;;;;;
+1450E;ANATOLIAN HIEROGLYPH A236;Lo;0;L;;;;;N;;;;;
+1450F;ANATOLIAN HIEROGLYPH A237;Lo;0;L;;;;;N;;;;;
+14510;ANATOLIAN HIEROGLYPH A238;Lo;0;L;;;;;N;;;;;
+14511;ANATOLIAN HIEROGLYPH A239;Lo;0;L;;;;;N;;;;;
+14512;ANATOLIAN HIEROGLYPH A240;Lo;0;L;;;;;N;;;;;
+14513;ANATOLIAN HIEROGLYPH A241;Lo;0;L;;;;;N;;;;;
+14514;ANATOLIAN HIEROGLYPH A242;Lo;0;L;;;;;N;;;;;
+14515;ANATOLIAN HIEROGLYPH A243;Lo;0;L;;;;;N;;;;;
+14516;ANATOLIAN HIEROGLYPH A244;Lo;0;L;;;;;N;;;;;
+14517;ANATOLIAN HIEROGLYPH A245;Lo;0;L;;;;;N;;;;;
+14518;ANATOLIAN HIEROGLYPH A246;Lo;0;L;;;;;N;;;;;
+14519;ANATOLIAN HIEROGLYPH A247;Lo;0;L;;;;;N;;;;;
+1451A;ANATOLIAN HIEROGLYPH A248;Lo;0;L;;;;;N;;;;;
+1451B;ANATOLIAN HIEROGLYPH A249;Lo;0;L;;;;;N;;;;;
+1451C;ANATOLIAN HIEROGLYPH A250;Lo;0;L;;;;;N;;;;;
+1451D;ANATOLIAN HIEROGLYPH A251;Lo;0;L;;;;;N;;;;;
+1451E;ANATOLIAN HIEROGLYPH A252;Lo;0;L;;;;;N;;;;;
+1451F;ANATOLIAN HIEROGLYPH A253;Lo;0;L;;;;;N;;;;;
+14520;ANATOLIAN HIEROGLYPH A254;Lo;0;L;;;;;N;;;;;
+14521;ANATOLIAN HIEROGLYPH A255;Lo;0;L;;;;;N;;;;;
+14522;ANATOLIAN HIEROGLYPH A256;Lo;0;L;;;;;N;;;;;
+14523;ANATOLIAN HIEROGLYPH A257;Lo;0;L;;;;;N;;;;;
+14524;ANATOLIAN HIEROGLYPH A258;Lo;0;L;;;;;N;;;;;
+14525;ANATOLIAN HIEROGLYPH A259;Lo;0;L;;;;;N;;;;;
+14526;ANATOLIAN HIEROGLYPH A260;Lo;0;L;;;;;N;;;;;
+14527;ANATOLIAN HIEROGLYPH A261;Lo;0;L;;;;;N;;;;;
+14528;ANATOLIAN HIEROGLYPH A262;Lo;0;L;;;;;N;;;;;
+14529;ANATOLIAN HIEROGLYPH A263;Lo;0;L;;;;;N;;;;;
+1452A;ANATOLIAN HIEROGLYPH A264;Lo;0;L;;;;;N;;;;;
+1452B;ANATOLIAN HIEROGLYPH A265;Lo;0;L;;;;;N;;;;;
+1452C;ANATOLIAN HIEROGLYPH A266;Lo;0;L;;;;;N;;;;;
+1452D;ANATOLIAN HIEROGLYPH A267;Lo;0;L;;;;;N;;;;;
+1452E;ANATOLIAN HIEROGLYPH A267A;Lo;0;L;;;;;N;;;;;
+1452F;ANATOLIAN HIEROGLYPH A268;Lo;0;L;;;;;N;;;;;
+14530;ANATOLIAN HIEROGLYPH A269;Lo;0;L;;;;;N;;;;;
+14531;ANATOLIAN HIEROGLYPH A270;Lo;0;L;;;;;N;;;;;
+14532;ANATOLIAN HIEROGLYPH A271;Lo;0;L;;;;;N;;;;;
+14533;ANATOLIAN HIEROGLYPH A272;Lo;0;L;;;;;N;;;;;
+14534;ANATOLIAN HIEROGLYPH A273;Lo;0;L;;;;;N;;;;;
+14535;ANATOLIAN HIEROGLYPH A274;Lo;0;L;;;;;N;;;;;
+14536;ANATOLIAN HIEROGLYPH A275;Lo;0;L;;;;;N;;;;;
+14537;ANATOLIAN HIEROGLYPH A276;Lo;0;L;;;;;N;;;;;
+14538;ANATOLIAN HIEROGLYPH A277;Lo;0;L;;;;;N;;;;;
+14539;ANATOLIAN HIEROGLYPH A278;Lo;0;L;;;;;N;;;;;
+1453A;ANATOLIAN HIEROGLYPH A279;Lo;0;L;;;;;N;;;;;
+1453B;ANATOLIAN HIEROGLYPH A280;Lo;0;L;;;;;N;;;;;
+1453C;ANATOLIAN HIEROGLYPH A281;Lo;0;L;;;;;N;;;;;
+1453D;ANATOLIAN HIEROGLYPH A282;Lo;0;L;;;;;N;;;;;
+1453E;ANATOLIAN HIEROGLYPH A283;Lo;0;L;;;;;N;;;;;
+1453F;ANATOLIAN HIEROGLYPH A284;Lo;0;L;;;;;N;;;;;
+14540;ANATOLIAN HIEROGLYPH A285;Lo;0;L;;;;;N;;;;;
+14541;ANATOLIAN HIEROGLYPH A286;Lo;0;L;;;;;N;;;;;
+14542;ANATOLIAN HIEROGLYPH A287;Lo;0;L;;;;;N;;;;;
+14543;ANATOLIAN HIEROGLYPH A288;Lo;0;L;;;;;N;;;;;
+14544;ANATOLIAN HIEROGLYPH A289;Lo;0;L;;;;;N;;;;;
+14545;ANATOLIAN HIEROGLYPH A289A;Lo;0;L;;;;;N;;;;;
+14546;ANATOLIAN HIEROGLYPH A290;Lo;0;L;;;;;N;;;;;
+14547;ANATOLIAN HIEROGLYPH A291;Lo;0;L;;;;;N;;;;;
+14548;ANATOLIAN HIEROGLYPH A292;Lo;0;L;;;;;N;;;;;
+14549;ANATOLIAN HIEROGLYPH A293;Lo;0;L;;;;;N;;;;;
+1454A;ANATOLIAN HIEROGLYPH A294;Lo;0;L;;;;;N;;;;;
+1454B;ANATOLIAN HIEROGLYPH A294A;Lo;0;L;;;;;N;;;;;
+1454C;ANATOLIAN HIEROGLYPH A295;Lo;0;L;;;;;N;;;;;
+1454D;ANATOLIAN HIEROGLYPH A296;Lo;0;L;;;;;N;;;;;
+1454E;ANATOLIAN HIEROGLYPH A297;Lo;0;L;;;;;N;;;;;
+1454F;ANATOLIAN HIEROGLYPH A298;Lo;0;L;;;;;N;;;;;
+14550;ANATOLIAN HIEROGLYPH A299;Lo;0;L;;;;;N;;;;;
+14551;ANATOLIAN HIEROGLYPH A299A;Lo;0;L;;;;;N;;;;;
+14552;ANATOLIAN HIEROGLYPH A300;Lo;0;L;;;;;N;;;;;
+14553;ANATOLIAN HIEROGLYPH A301;Lo;0;L;;;;;N;;;;;
+14554;ANATOLIAN HIEROGLYPH A302;Lo;0;L;;;;;N;;;;;
+14555;ANATOLIAN HIEROGLYPH A303;Lo;0;L;;;;;N;;;;;
+14556;ANATOLIAN HIEROGLYPH A304;Lo;0;L;;;;;N;;;;;
+14557;ANATOLIAN HIEROGLYPH A305;Lo;0;L;;;;;N;;;;;
+14558;ANATOLIAN HIEROGLYPH A306;Lo;0;L;;;;;N;;;;;
+14559;ANATOLIAN HIEROGLYPH A307;Lo;0;L;;;;;N;;;;;
+1455A;ANATOLIAN HIEROGLYPH A308;Lo;0;L;;;;;N;;;;;
+1455B;ANATOLIAN HIEROGLYPH A309;Lo;0;L;;;;;N;;;;;
+1455C;ANATOLIAN HIEROGLYPH A309A;Lo;0;L;;;;;N;;;;;
+1455D;ANATOLIAN HIEROGLYPH A310;Lo;0;L;;;;;N;;;;;
+1455E;ANATOLIAN HIEROGLYPH A311;Lo;0;L;;;;;N;;;;;
+1455F;ANATOLIAN HIEROGLYPH A312;Lo;0;L;;;;;N;;;;;
+14560;ANATOLIAN HIEROGLYPH A313;Lo;0;L;;;;;N;;;;;
+14561;ANATOLIAN HIEROGLYPH A314;Lo;0;L;;;;;N;;;;;
+14562;ANATOLIAN HIEROGLYPH A315;Lo;0;L;;;;;N;;;;;
+14563;ANATOLIAN HIEROGLYPH A316;Lo;0;L;;;;;N;;;;;
+14564;ANATOLIAN HIEROGLYPH A317;Lo;0;L;;;;;N;;;;;
+14565;ANATOLIAN HIEROGLYPH A318;Lo;0;L;;;;;N;;;;;
+14566;ANATOLIAN HIEROGLYPH A319;Lo;0;L;;;;;N;;;;;
+14567;ANATOLIAN HIEROGLYPH A320;Lo;0;L;;;;;N;;;;;
+14568;ANATOLIAN HIEROGLYPH A321;Lo;0;L;;;;;N;;;;;
+14569;ANATOLIAN HIEROGLYPH A322;Lo;0;L;;;;;N;;;;;
+1456A;ANATOLIAN HIEROGLYPH A323;Lo;0;L;;;;;N;;;;;
+1456B;ANATOLIAN HIEROGLYPH A324;Lo;0;L;;;;;N;;;;;
+1456C;ANATOLIAN HIEROGLYPH A325;Lo;0;L;;;;;N;;;;;
+1456D;ANATOLIAN HIEROGLYPH A326;Lo;0;L;;;;;N;;;;;
+1456E;ANATOLIAN HIEROGLYPH A327;Lo;0;L;;;;;N;;;;;
+1456F;ANATOLIAN HIEROGLYPH A328;Lo;0;L;;;;;N;;;;;
+14570;ANATOLIAN HIEROGLYPH A329;Lo;0;L;;;;;N;;;;;
+14571;ANATOLIAN HIEROGLYPH A329A;Lo;0;L;;;;;N;;;;;
+14572;ANATOLIAN HIEROGLYPH A330;Lo;0;L;;;;;N;;;;;
+14573;ANATOLIAN HIEROGLYPH A331;Lo;0;L;;;;;N;;;;;
+14574;ANATOLIAN HIEROGLYPH A332A;Lo;0;L;;;;;N;;;;;
+14575;ANATOLIAN HIEROGLYPH A332B;Lo;0;L;;;;;N;;;;;
+14576;ANATOLIAN HIEROGLYPH A332C;Lo;0;L;;;;;N;;;;;
+14577;ANATOLIAN HIEROGLYPH A333;Lo;0;L;;;;;N;;;;;
+14578;ANATOLIAN HIEROGLYPH A334;Lo;0;L;;;;;N;;;;;
+14579;ANATOLIAN HIEROGLYPH A335;Lo;0;L;;;;;N;;;;;
+1457A;ANATOLIAN HIEROGLYPH A336;Lo;0;L;;;;;N;;;;;
+1457B;ANATOLIAN HIEROGLYPH A336A;Lo;0;L;;;;;N;;;;;
+1457C;ANATOLIAN HIEROGLYPH A336B;Lo;0;L;;;;;N;;;;;
+1457D;ANATOLIAN HIEROGLYPH A336C;Lo;0;L;;;;;N;;;;;
+1457E;ANATOLIAN HIEROGLYPH A337;Lo;0;L;;;;;N;;;;;
+1457F;ANATOLIAN HIEROGLYPH A338;Lo;0;L;;;;;N;;;;;
+14580;ANATOLIAN HIEROGLYPH A339;Lo;0;L;;;;;N;;;;;
+14581;ANATOLIAN HIEROGLYPH A340;Lo;0;L;;;;;N;;;;;
+14582;ANATOLIAN HIEROGLYPH A341;Lo;0;L;;;;;N;;;;;
+14583;ANATOLIAN HIEROGLYPH A342;Lo;0;L;;;;;N;;;;;
+14584;ANATOLIAN HIEROGLYPH A343;Lo;0;L;;;;;N;;;;;
+14585;ANATOLIAN HIEROGLYPH A344;Lo;0;L;;;;;N;;;;;
+14586;ANATOLIAN HIEROGLYPH A345;Lo;0;L;;;;;N;;;;;
+14587;ANATOLIAN HIEROGLYPH A346;Lo;0;L;;;;;N;;;;;
+14588;ANATOLIAN HIEROGLYPH A347;Lo;0;L;;;;;N;;;;;
+14589;ANATOLIAN HIEROGLYPH A348;Lo;0;L;;;;;N;;;;;
+1458A;ANATOLIAN HIEROGLYPH A349;Lo;0;L;;;;;N;;;;;
+1458B;ANATOLIAN HIEROGLYPH A350;Lo;0;L;;;;;N;;;;;
+1458C;ANATOLIAN HIEROGLYPH A351;Lo;0;L;;;;;N;;;;;
+1458D;ANATOLIAN HIEROGLYPH A352;Lo;0;L;;;;;N;;;;;
+1458E;ANATOLIAN HIEROGLYPH A353;Lo;0;L;;;;;N;;;;;
+1458F;ANATOLIAN HIEROGLYPH A354;Lo;0;L;;;;;N;;;;;
+14590;ANATOLIAN HIEROGLYPH A355;Lo;0;L;;;;;N;;;;;
+14591;ANATOLIAN HIEROGLYPH A356;Lo;0;L;;;;;N;;;;;
+14592;ANATOLIAN HIEROGLYPH A357;Lo;0;L;;;;;N;;;;;
+14593;ANATOLIAN HIEROGLYPH A358;Lo;0;L;;;;;N;;;;;
+14594;ANATOLIAN HIEROGLYPH A359;Lo;0;L;;;;;N;;;;;
+14595;ANATOLIAN HIEROGLYPH A359A;Lo;0;L;;;;;N;;;;;
+14596;ANATOLIAN HIEROGLYPH A360;Lo;0;L;;;;;N;;;;;
+14597;ANATOLIAN HIEROGLYPH A361;Lo;0;L;;;;;N;;;;;
+14598;ANATOLIAN HIEROGLYPH A362;Lo;0;L;;;;;N;;;;;
+14599;ANATOLIAN HIEROGLYPH A363;Lo;0;L;;;;;N;;;;;
+1459A;ANATOLIAN HIEROGLYPH A364;Lo;0;L;;;;;N;;;;;
+1459B;ANATOLIAN HIEROGLYPH A364A;Lo;0;L;;;;;N;;;;;
+1459C;ANATOLIAN HIEROGLYPH A365;Lo;0;L;;;;;N;;;;;
+1459D;ANATOLIAN HIEROGLYPH A366;Lo;0;L;;;;;N;;;;;
+1459E;ANATOLIAN HIEROGLYPH A367;Lo;0;L;;;;;N;;;;;
+1459F;ANATOLIAN HIEROGLYPH A368;Lo;0;L;;;;;N;;;;;
+145A0;ANATOLIAN HIEROGLYPH A368A;Lo;0;L;;;;;N;;;;;
+145A1;ANATOLIAN HIEROGLYPH A369;Lo;0;L;;;;;N;;;;;
+145A2;ANATOLIAN HIEROGLYPH A370;Lo;0;L;;;;;N;;;;;
+145A3;ANATOLIAN HIEROGLYPH A371;Lo;0;L;;;;;N;;;;;
+145A4;ANATOLIAN HIEROGLYPH A371A;Lo;0;L;;;;;N;;;;;
+145A5;ANATOLIAN HIEROGLYPH A372;Lo;0;L;;;;;N;;;;;
+145A6;ANATOLIAN HIEROGLYPH A373;Lo;0;L;;;;;N;;;;;
+145A7;ANATOLIAN HIEROGLYPH A374;Lo;0;L;;;;;N;;;;;
+145A8;ANATOLIAN HIEROGLYPH A375;Lo;0;L;;;;;N;;;;;
+145A9;ANATOLIAN HIEROGLYPH A376;Lo;0;L;;;;;N;;;;;
+145AA;ANATOLIAN HIEROGLYPH A377;Lo;0;L;;;;;N;;;;;
+145AB;ANATOLIAN HIEROGLYPH A378;Lo;0;L;;;;;N;;;;;
+145AC;ANATOLIAN HIEROGLYPH A379;Lo;0;L;;;;;N;;;;;
+145AD;ANATOLIAN HIEROGLYPH A380;Lo;0;L;;;;;N;;;;;
+145AE;ANATOLIAN HIEROGLYPH A381;Lo;0;L;;;;;N;;;;;
+145AF;ANATOLIAN HIEROGLYPH A381A;Lo;0;L;;;;;N;;;;;
+145B0;ANATOLIAN HIEROGLYPH A382;Lo;0;L;;;;;N;;;;;
+145B1;ANATOLIAN HIEROGLYPH A383 RA OR RI;Lo;0;L;;;;;N;;;;;
+145B2;ANATOLIAN HIEROGLYPH A383A;Lo;0;L;;;;;N;;;;;
+145B3;ANATOLIAN HIEROGLYPH A384;Lo;0;L;;;;;N;;;;;
+145B4;ANATOLIAN HIEROGLYPH A385;Lo;0;L;;;;;N;;;;;
+145B5;ANATOLIAN HIEROGLYPH A386;Lo;0;L;;;;;N;;;;;
+145B6;ANATOLIAN HIEROGLYPH A386A;Lo;0;L;;;;;N;;;;;
+145B7;ANATOLIAN HIEROGLYPH A387;Lo;0;L;;;;;N;;;;;
+145B8;ANATOLIAN HIEROGLYPH A388;Lo;0;L;;;;;N;;;;;
+145B9;ANATOLIAN HIEROGLYPH A389;Lo;0;L;;;;;N;;;;;
+145BA;ANATOLIAN HIEROGLYPH A390;Lo;0;L;;;;;N;;;;;
+145BB;ANATOLIAN HIEROGLYPH A391;Lo;0;L;;;;;N;;;;;
+145BC;ANATOLIAN HIEROGLYPH A392;Lo;0;L;;;;;N;;;;;
+145BD;ANATOLIAN HIEROGLYPH A393 EIGHT;Lo;0;L;;;;;N;;;;;
+145BE;ANATOLIAN HIEROGLYPH A394;Lo;0;L;;;;;N;;;;;
+145BF;ANATOLIAN HIEROGLYPH A395;Lo;0;L;;;;;N;;;;;
+145C0;ANATOLIAN HIEROGLYPH A396;Lo;0;L;;;;;N;;;;;
+145C1;ANATOLIAN HIEROGLYPH A397;Lo;0;L;;;;;N;;;;;
+145C2;ANATOLIAN HIEROGLYPH A398;Lo;0;L;;;;;N;;;;;
+145C3;ANATOLIAN HIEROGLYPH A399;Lo;0;L;;;;;N;;;;;
+145C4;ANATOLIAN HIEROGLYPH A400;Lo;0;L;;;;;N;;;;;
+145C5;ANATOLIAN HIEROGLYPH A401;Lo;0;L;;;;;N;;;;;
+145C6;ANATOLIAN HIEROGLYPH A402;Lo;0;L;;;;;N;;;;;
+145C7;ANATOLIAN HIEROGLYPH A403;Lo;0;L;;;;;N;;;;;
+145C8;ANATOLIAN HIEROGLYPH A404;Lo;0;L;;;;;N;;;;;
+145C9;ANATOLIAN HIEROGLYPH A405;Lo;0;L;;;;;N;;;;;
+145CA;ANATOLIAN HIEROGLYPH A406;Lo;0;L;;;;;N;;;;;
+145CB;ANATOLIAN HIEROGLYPH A407;Lo;0;L;;;;;N;;;;;
+145CC;ANATOLIAN HIEROGLYPH A408;Lo;0;L;;;;;N;;;;;
+145CD;ANATOLIAN HIEROGLYPH A409;Lo;0;L;;;;;N;;;;;
+145CE;ANATOLIAN HIEROGLYPH A410 BEGIN LOGOGRAM MARK;Lo;0;L;;;;;N;;;;;
+145CF;ANATOLIAN HIEROGLYPH A410A END LOGOGRAM MARK;Lo;0;L;;;;;N;;;;;
+145D0;ANATOLIAN HIEROGLYPH A411;Lo;0;L;;;;;N;;;;;
+145D1;ANATOLIAN HIEROGLYPH A412;Lo;0;L;;;;;N;;;;;
+145D2;ANATOLIAN HIEROGLYPH A413;Lo;0;L;;;;;N;;;;;
+145D3;ANATOLIAN HIEROGLYPH A414;Lo;0;L;;;;;N;;;;;
+145D4;ANATOLIAN HIEROGLYPH A415;Lo;0;L;;;;;N;;;;;
+145D5;ANATOLIAN HIEROGLYPH A416;Lo;0;L;;;;;N;;;;;
+145D6;ANATOLIAN HIEROGLYPH A417;Lo;0;L;;;;;N;;;;;
+145D7;ANATOLIAN HIEROGLYPH A418;Lo;0;L;;;;;N;;;;;
+145D8;ANATOLIAN HIEROGLYPH A419;Lo;0;L;;;;;N;;;;;
+145D9;ANATOLIAN HIEROGLYPH A420;Lo;0;L;;;;;N;;;;;
+145DA;ANATOLIAN HIEROGLYPH A421;Lo;0;L;;;;;N;;;;;
+145DB;ANATOLIAN HIEROGLYPH A422;Lo;0;L;;;;;N;;;;;
+145DC;ANATOLIAN HIEROGLYPH A423;Lo;0;L;;;;;N;;;;;
+145DD;ANATOLIAN HIEROGLYPH A424;Lo;0;L;;;;;N;;;;;
+145DE;ANATOLIAN HIEROGLYPH A425;Lo;0;L;;;;;N;;;;;
+145DF;ANATOLIAN HIEROGLYPH A426;Lo;0;L;;;;;N;;;;;
+145E0;ANATOLIAN HIEROGLYPH A427;Lo;0;L;;;;;N;;;;;
+145E1;ANATOLIAN HIEROGLYPH A428;Lo;0;L;;;;;N;;;;;
+145E2;ANATOLIAN HIEROGLYPH A429;Lo;0;L;;;;;N;;;;;
+145E3;ANATOLIAN HIEROGLYPH A430;Lo;0;L;;;;;N;;;;;
+145E4;ANATOLIAN HIEROGLYPH A431;Lo;0;L;;;;;N;;;;;
+145E5;ANATOLIAN HIEROGLYPH A432;Lo;0;L;;;;;N;;;;;
+145E6;ANATOLIAN HIEROGLYPH A433;Lo;0;L;;;;;N;;;;;
+145E7;ANATOLIAN HIEROGLYPH A434;Lo;0;L;;;;;N;;;;;
+145E8;ANATOLIAN HIEROGLYPH A435;Lo;0;L;;;;;N;;;;;
+145E9;ANATOLIAN HIEROGLYPH A436;Lo;0;L;;;;;N;;;;;
+145EA;ANATOLIAN HIEROGLYPH A437;Lo;0;L;;;;;N;;;;;
+145EB;ANATOLIAN HIEROGLYPH A438;Lo;0;L;;;;;N;;;;;
+145EC;ANATOLIAN HIEROGLYPH A439;Lo;0;L;;;;;N;;;;;
+145ED;ANATOLIAN HIEROGLYPH A440;Lo;0;L;;;;;N;;;;;
+145EE;ANATOLIAN HIEROGLYPH A441;Lo;0;L;;;;;N;;;;;
+145EF;ANATOLIAN HIEROGLYPH A442;Lo;0;L;;;;;N;;;;;
+145F0;ANATOLIAN HIEROGLYPH A443;Lo;0;L;;;;;N;;;;;
+145F1;ANATOLIAN HIEROGLYPH A444;Lo;0;L;;;;;N;;;;;
+145F2;ANATOLIAN HIEROGLYPH A445;Lo;0;L;;;;;N;;;;;
+145F3;ANATOLIAN HIEROGLYPH A446;Lo;0;L;;;;;N;;;;;
+145F4;ANATOLIAN HIEROGLYPH A447;Lo;0;L;;;;;N;;;;;
+145F5;ANATOLIAN HIEROGLYPH A448;Lo;0;L;;;;;N;;;;;
+145F6;ANATOLIAN HIEROGLYPH A449;Lo;0;L;;;;;N;;;;;
+145F7;ANATOLIAN HIEROGLYPH A450;Lo;0;L;;;;;N;;;;;
+145F8;ANATOLIAN HIEROGLYPH A450A;Lo;0;L;;;;;N;;;;;
+145F9;ANATOLIAN HIEROGLYPH A451;Lo;0;L;;;;;N;;;;;
+145FA;ANATOLIAN HIEROGLYPH A452;Lo;0;L;;;;;N;;;;;
+145FB;ANATOLIAN HIEROGLYPH A453;Lo;0;L;;;;;N;;;;;
+145FC;ANATOLIAN HIEROGLYPH A454;Lo;0;L;;;;;N;;;;;
+145FD;ANATOLIAN HIEROGLYPH A455;Lo;0;L;;;;;N;;;;;
+145FE;ANATOLIAN HIEROGLYPH A456;Lo;0;L;;;;;N;;;;;
+145FF;ANATOLIAN HIEROGLYPH A457;Lo;0;L;;;;;N;;;;;
+14600;ANATOLIAN HIEROGLYPH A457A;Lo;0;L;;;;;N;;;;;
+14601;ANATOLIAN HIEROGLYPH A458;Lo;0;L;;;;;N;;;;;
+14602;ANATOLIAN HIEROGLYPH A459;Lo;0;L;;;;;N;;;;;
+14603;ANATOLIAN HIEROGLYPH A460;Lo;0;L;;;;;N;;;;;
+14604;ANATOLIAN HIEROGLYPH A461;Lo;0;L;;;;;N;;;;;
+14605;ANATOLIAN HIEROGLYPH A462;Lo;0;L;;;;;N;;;;;
+14606;ANATOLIAN HIEROGLYPH A463;Lo;0;L;;;;;N;;;;;
+14607;ANATOLIAN HIEROGLYPH A464;Lo;0;L;;;;;N;;;;;
+14608;ANATOLIAN HIEROGLYPH A465;Lo;0;L;;;;;N;;;;;
+14609;ANATOLIAN HIEROGLYPH A466;Lo;0;L;;;;;N;;;;;
+1460A;ANATOLIAN HIEROGLYPH A467;Lo;0;L;;;;;N;;;;;
+1460B;ANATOLIAN HIEROGLYPH A468;Lo;0;L;;;;;N;;;;;
+1460C;ANATOLIAN HIEROGLYPH A469;Lo;0;L;;;;;N;;;;;
+1460D;ANATOLIAN HIEROGLYPH A470;Lo;0;L;;;;;N;;;;;
+1460E;ANATOLIAN HIEROGLYPH A471;Lo;0;L;;;;;N;;;;;
+1460F;ANATOLIAN HIEROGLYPH A472;Lo;0;L;;;;;N;;;;;
+14610;ANATOLIAN HIEROGLYPH A473;Lo;0;L;;;;;N;;;;;
+14611;ANATOLIAN HIEROGLYPH A474;Lo;0;L;;;;;N;;;;;
+14612;ANATOLIAN HIEROGLYPH A475;Lo;0;L;;;;;N;;;;;
+14613;ANATOLIAN HIEROGLYPH A476;Lo;0;L;;;;;N;;;;;
+14614;ANATOLIAN HIEROGLYPH A477;Lo;0;L;;;;;N;;;;;
+14615;ANATOLIAN HIEROGLYPH A478;Lo;0;L;;;;;N;;;;;
+14616;ANATOLIAN HIEROGLYPH A479;Lo;0;L;;;;;N;;;;;
+14617;ANATOLIAN HIEROGLYPH A480;Lo;0;L;;;;;N;;;;;
+14618;ANATOLIAN HIEROGLYPH A481;Lo;0;L;;;;;N;;;;;
+14619;ANATOLIAN HIEROGLYPH A482;Lo;0;L;;;;;N;;;;;
+1461A;ANATOLIAN HIEROGLYPH A483;Lo;0;L;;;;;N;;;;;
+1461B;ANATOLIAN HIEROGLYPH A484;Lo;0;L;;;;;N;;;;;
+1461C;ANATOLIAN HIEROGLYPH A485;Lo;0;L;;;;;N;;;;;
+1461D;ANATOLIAN HIEROGLYPH A486;Lo;0;L;;;;;N;;;;;
+1461E;ANATOLIAN HIEROGLYPH A487;Lo;0;L;;;;;N;;;;;
+1461F;ANATOLIAN HIEROGLYPH A488;Lo;0;L;;;;;N;;;;;
+14620;ANATOLIAN HIEROGLYPH A489;Lo;0;L;;;;;N;;;;;
+14621;ANATOLIAN HIEROGLYPH A490;Lo;0;L;;;;;N;;;;;
+14622;ANATOLIAN HIEROGLYPH A491;Lo;0;L;;;;;N;;;;;
+14623;ANATOLIAN HIEROGLYPH A492;Lo;0;L;;;;;N;;;;;
+14624;ANATOLIAN HIEROGLYPH A493;Lo;0;L;;;;;N;;;;;
+14625;ANATOLIAN HIEROGLYPH A494;Lo;0;L;;;;;N;;;;;
+14626;ANATOLIAN HIEROGLYPH A495;Lo;0;L;;;;;N;;;;;
+14627;ANATOLIAN HIEROGLYPH A496;Lo;0;L;;;;;N;;;;;
+14628;ANATOLIAN HIEROGLYPH A497;Lo;0;L;;;;;N;;;;;
+14629;ANATOLIAN HIEROGLYPH A501;Lo;0;L;;;;;N;;;;;
+1462A;ANATOLIAN HIEROGLYPH A502;Lo;0;L;;;;;N;;;;;
+1462B;ANATOLIAN HIEROGLYPH A503;Lo;0;L;;;;;N;;;;;
+1462C;ANATOLIAN HIEROGLYPH A504;Lo;0;L;;;;;N;;;;;
+1462D;ANATOLIAN HIEROGLYPH A505;Lo;0;L;;;;;N;;;;;
+1462E;ANATOLIAN HIEROGLYPH A506;Lo;0;L;;;;;N;;;;;
+1462F;ANATOLIAN HIEROGLYPH A507;Lo;0;L;;;;;N;;;;;
+14630;ANATOLIAN HIEROGLYPH A508;Lo;0;L;;;;;N;;;;;
+14631;ANATOLIAN HIEROGLYPH A509;Lo;0;L;;;;;N;;;;;
+14632;ANATOLIAN HIEROGLYPH A510;Lo;0;L;;;;;N;;;;;
+14633;ANATOLIAN HIEROGLYPH A511;Lo;0;L;;;;;N;;;;;
+14634;ANATOLIAN HIEROGLYPH A512;Lo;0;L;;;;;N;;;;;
+14635;ANATOLIAN HIEROGLYPH A513;Lo;0;L;;;;;N;;;;;
+14636;ANATOLIAN HIEROGLYPH A514;Lo;0;L;;;;;N;;;;;
+14637;ANATOLIAN HIEROGLYPH A515;Lo;0;L;;;;;N;;;;;
+14638;ANATOLIAN HIEROGLYPH A516;Lo;0;L;;;;;N;;;;;
+14639;ANATOLIAN HIEROGLYPH A517;Lo;0;L;;;;;N;;;;;
+1463A;ANATOLIAN HIEROGLYPH A518;Lo;0;L;;;;;N;;;;;
+1463B;ANATOLIAN HIEROGLYPH A519;Lo;0;L;;;;;N;;;;;
+1463C;ANATOLIAN HIEROGLYPH A520;Lo;0;L;;;;;N;;;;;
+1463D;ANATOLIAN HIEROGLYPH A521;Lo;0;L;;;;;N;;;;;
+1463E;ANATOLIAN HIEROGLYPH A522;Lo;0;L;;;;;N;;;;;
+1463F;ANATOLIAN HIEROGLYPH A523;Lo;0;L;;;;;N;;;;;
+14640;ANATOLIAN HIEROGLYPH A524;Lo;0;L;;;;;N;;;;;
+14641;ANATOLIAN HIEROGLYPH A525;Lo;0;L;;;;;N;;;;;
+14642;ANATOLIAN HIEROGLYPH A526;Lo;0;L;;;;;N;;;;;
+14643;ANATOLIAN HIEROGLYPH A527;Lo;0;L;;;;;N;;;;;
+14644;ANATOLIAN HIEROGLYPH A528;Lo;0;L;;;;;N;;;;;
+14645;ANATOLIAN HIEROGLYPH A529;Lo;0;L;;;;;N;;;;;
+14646;ANATOLIAN HIEROGLYPH A530;Lo;0;L;;;;;N;;;;;
+16800;BAMUM LETTER PHASE-A NGKUE MFON;Lo;0;L;;;;;N;;;;;
+16801;BAMUM LETTER PHASE-A GBIEE FON;Lo;0;L;;;;;N;;;;;
+16802;BAMUM LETTER PHASE-A PON MFON PIPAEMGBIEE;Lo;0;L;;;;;N;;;;;
+16803;BAMUM LETTER PHASE-A PON MFON PIPAEMBA;Lo;0;L;;;;;N;;;;;
+16804;BAMUM LETTER PHASE-A NAA MFON;Lo;0;L;;;;;N;;;;;
+16805;BAMUM LETTER PHASE-A SHUENSHUET;Lo;0;L;;;;;N;;;;;
+16806;BAMUM LETTER PHASE-A TITA MFON;Lo;0;L;;;;;N;;;;;
+16807;BAMUM LETTER PHASE-A NZA MFON;Lo;0;L;;;;;N;;;;;
+16808;BAMUM LETTER PHASE-A SHINDA PA NJI;Lo;0;L;;;;;N;;;;;
+16809;BAMUM LETTER PHASE-A PON PA NJI PIPAEMGBIEE;Lo;0;L;;;;;N;;;;;
+1680A;BAMUM LETTER PHASE-A PON PA NJI PIPAEMBA;Lo;0;L;;;;;N;;;;;
+1680B;BAMUM LETTER PHASE-A MAEMBGBIEE;Lo;0;L;;;;;N;;;;;
+1680C;BAMUM LETTER PHASE-A TU MAEMBA;Lo;0;L;;;;;N;;;;;
+1680D;BAMUM LETTER PHASE-A NGANGU;Lo;0;L;;;;;N;;;;;
+1680E;BAMUM LETTER PHASE-A MAEMVEUX;Lo;0;L;;;;;N;;;;;
+1680F;BAMUM LETTER PHASE-A MANSUAE;Lo;0;L;;;;;N;;;;;
+16810;BAMUM LETTER PHASE-A MVEUAENGAM;Lo;0;L;;;;;N;;;;;
+16811;BAMUM LETTER PHASE-A SEUNYAM;Lo;0;L;;;;;N;;;;;
+16812;BAMUM LETTER PHASE-A NTOQPEN;Lo;0;L;;;;;N;;;;;
+16813;BAMUM LETTER PHASE-A KEUKEUTNDA;Lo;0;L;;;;;N;;;;;
+16814;BAMUM LETTER PHASE-A NKINDI;Lo;0;L;;;;;N;;;;;
+16815;BAMUM LETTER PHASE-A SUU;Lo;0;L;;;;;N;;;;;
+16816;BAMUM LETTER PHASE-A NGKUENZEUM;Lo;0;L;;;;;N;;;;;
+16817;BAMUM LETTER PHASE-A LAPAQ;Lo;0;L;;;;;N;;;;;
+16818;BAMUM LETTER PHASE-A LET KUT;Lo;0;L;;;;;N;;;;;
+16819;BAMUM LETTER PHASE-A NTAP MFAA;Lo;0;L;;;;;N;;;;;
+1681A;BAMUM LETTER PHASE-A MAEKEUP;Lo;0;L;;;;;N;;;;;
+1681B;BAMUM LETTER PHASE-A PASHAE;Lo;0;L;;;;;N;;;;;
+1681C;BAMUM LETTER PHASE-A GHEUAERAE;Lo;0;L;;;;;N;;;;;
+1681D;BAMUM LETTER PHASE-A PAMSHAE;Lo;0;L;;;;;N;;;;;
+1681E;BAMUM LETTER PHASE-A MON NGGEUAET;Lo;0;L;;;;;N;;;;;
+1681F;BAMUM LETTER PHASE-A NZUN MEUT;Lo;0;L;;;;;N;;;;;
+16820;BAMUM LETTER PHASE-A U YUQ NAE;Lo;0;L;;;;;N;;;;;
+16821;BAMUM LETTER PHASE-A GHEUAEGHEUAE;Lo;0;L;;;;;N;;;;;
+16822;BAMUM LETTER PHASE-A NTAP NTAA;Lo;0;L;;;;;N;;;;;
+16823;BAMUM LETTER PHASE-A SISA;Lo;0;L;;;;;N;;;;;
+16824;BAMUM LETTER PHASE-A MGBASA;Lo;0;L;;;;;N;;;;;
+16825;BAMUM LETTER PHASE-A MEUNJOMNDEUQ;Lo;0;L;;;;;N;;;;;
+16826;BAMUM LETTER PHASE-A MOOMPUQ;Lo;0;L;;;;;N;;;;;
+16827;BAMUM LETTER PHASE-A KAFA;Lo;0;L;;;;;N;;;;;
+16828;BAMUM LETTER PHASE-A PA LEERAEWA;Lo;0;L;;;;;N;;;;;
+16829;BAMUM LETTER PHASE-A NDA LEERAEWA;Lo;0;L;;;;;N;;;;;
+1682A;BAMUM LETTER PHASE-A PET;Lo;0;L;;;;;N;;;;;
+1682B;BAMUM LETTER PHASE-A MAEMKPEN;Lo;0;L;;;;;N;;;;;
+1682C;BAMUM LETTER PHASE-A NIKA;Lo;0;L;;;;;N;;;;;
+1682D;BAMUM LETTER PHASE-A PUP;Lo;0;L;;;;;N;;;;;
+1682E;BAMUM LETTER PHASE-A TUAEP;Lo;0;L;;;;;N;;;;;
+1682F;BAMUM LETTER PHASE-A LUAEP;Lo;0;L;;;;;N;;;;;
+16830;BAMUM LETTER PHASE-A SONJAM;Lo;0;L;;;;;N;;;;;
+16831;BAMUM LETTER PHASE-A TEUTEUWEN;Lo;0;L;;;;;N;;;;;
+16832;BAMUM LETTER PHASE-A MAENYI;Lo;0;L;;;;;N;;;;;
+16833;BAMUM LETTER PHASE-A KET;Lo;0;L;;;;;N;;;;;
+16834;BAMUM LETTER PHASE-A NDAANGGEUAET;Lo;0;L;;;;;N;;;;;
+16835;BAMUM LETTER PHASE-A KUOQ;Lo;0;L;;;;;N;;;;;
+16836;BAMUM LETTER PHASE-A MOOMEUT;Lo;0;L;;;;;N;;;;;
+16837;BAMUM LETTER PHASE-A SHUM;Lo;0;L;;;;;N;;;;;
+16838;BAMUM LETTER PHASE-A LOMMAE;Lo;0;L;;;;;N;;;;;
+16839;BAMUM LETTER PHASE-A FIRI;Lo;0;L;;;;;N;;;;;
+1683A;BAMUM LETTER PHASE-A ROM;Lo;0;L;;;;;N;;;;;
+1683B;BAMUM LETTER PHASE-A KPOQ;Lo;0;L;;;;;N;;;;;
+1683C;BAMUM LETTER PHASE-A SOQ;Lo;0;L;;;;;N;;;;;
+1683D;BAMUM LETTER PHASE-A MAP PIEET;Lo;0;L;;;;;N;;;;;
+1683E;BAMUM LETTER PHASE-A SHIRAE;Lo;0;L;;;;;N;;;;;
+1683F;BAMUM LETTER PHASE-A NTAP;Lo;0;L;;;;;N;;;;;
+16840;BAMUM LETTER PHASE-A SHOQ NSHUT YUM;Lo;0;L;;;;;N;;;;;
+16841;BAMUM LETTER PHASE-A NYIT MONGKEUAEQ;Lo;0;L;;;;;N;;;;;
+16842;BAMUM LETTER PHASE-A PAARAE;Lo;0;L;;;;;N;;;;;
+16843;BAMUM LETTER PHASE-A NKAARAE;Lo;0;L;;;;;N;;;;;
+16844;BAMUM LETTER PHASE-A UNKNOWN;Lo;0;L;;;;;N;;;;;
+16845;BAMUM LETTER PHASE-A NGGEN;Lo;0;L;;;;;N;;;;;
+16846;BAMUM LETTER PHASE-A MAESI;Lo;0;L;;;;;N;;;;;
+16847;BAMUM LETTER PHASE-A NJAM;Lo;0;L;;;;;N;;;;;
+16848;BAMUM LETTER PHASE-A MBANYI;Lo;0;L;;;;;N;;;;;
+16849;BAMUM LETTER PHASE-A NYET;Lo;0;L;;;;;N;;;;;
+1684A;BAMUM LETTER PHASE-A TEUAEN;Lo;0;L;;;;;N;;;;;
+1684B;BAMUM LETTER PHASE-A SOT;Lo;0;L;;;;;N;;;;;
+1684C;BAMUM LETTER PHASE-A PAAM;Lo;0;L;;;;;N;;;;;
+1684D;BAMUM LETTER PHASE-A NSHIEE;Lo;0;L;;;;;N;;;;;
+1684E;BAMUM LETTER PHASE-A MAEM;Lo;0;L;;;;;N;;;;;
+1684F;BAMUM LETTER PHASE-A NYI;Lo;0;L;;;;;N;;;;;
+16850;BAMUM LETTER PHASE-A KAQ;Lo;0;L;;;;;N;;;;;
+16851;BAMUM LETTER PHASE-A NSHA;Lo;0;L;;;;;N;;;;;
+16852;BAMUM LETTER PHASE-A VEE;Lo;0;L;;;;;N;;;;;
+16853;BAMUM LETTER PHASE-A LU;Lo;0;L;;;;;N;;;;;
+16854;BAMUM LETTER PHASE-A NEN;Lo;0;L;;;;;N;;;;;
+16855;BAMUM LETTER PHASE-A NAQ;Lo;0;L;;;;;N;;;;;
+16856;BAMUM LETTER PHASE-A MBAQ;Lo;0;L;;;;;N;;;;;
+16857;BAMUM LETTER PHASE-B NSHUET;Lo;0;L;;;;;N;;;;;
+16858;BAMUM LETTER PHASE-B TU MAEMGBIEE;Lo;0;L;;;;;N;;;;;
+16859;BAMUM LETTER PHASE-B SIEE;Lo;0;L;;;;;N;;;;;
+1685A;BAMUM LETTER PHASE-B SET TU;Lo;0;L;;;;;N;;;;;
+1685B;BAMUM LETTER PHASE-B LOM NTEUM;Lo;0;L;;;;;N;;;;;
+1685C;BAMUM LETTER PHASE-B MBA MAELEE;Lo;0;L;;;;;N;;;;;
+1685D;BAMUM LETTER PHASE-B KIEEM;Lo;0;L;;;;;N;;;;;
+1685E;BAMUM LETTER PHASE-B YEURAE;Lo;0;L;;;;;N;;;;;
+1685F;BAMUM LETTER PHASE-B MBAARAE;Lo;0;L;;;;;N;;;;;
+16860;BAMUM LETTER PHASE-B KAM;Lo;0;L;;;;;N;;;;;
+16861;BAMUM LETTER PHASE-B PEESHI;Lo;0;L;;;;;N;;;;;
+16862;BAMUM LETTER PHASE-B YAFU LEERAEWA;Lo;0;L;;;;;N;;;;;
+16863;BAMUM LETTER PHASE-B LAM NSHUT NYAM;Lo;0;L;;;;;N;;;;;
+16864;BAMUM LETTER PHASE-B NTIEE SHEUOQ;Lo;0;L;;;;;N;;;;;
+16865;BAMUM LETTER PHASE-B NDU NJAA;Lo;0;L;;;;;N;;;;;
+16866;BAMUM LETTER PHASE-B GHEUGHEUAEM;Lo;0;L;;;;;N;;;;;
+16867;BAMUM LETTER PHASE-B PIT;Lo;0;L;;;;;N;;;;;
+16868;BAMUM LETTER PHASE-B TU NSIEE;Lo;0;L;;;;;N;;;;;
+16869;BAMUM LETTER PHASE-B SHET NJAQ;Lo;0;L;;;;;N;;;;;
+1686A;BAMUM LETTER PHASE-B SHEUAEQTU;Lo;0;L;;;;;N;;;;;
+1686B;BAMUM LETTER PHASE-B MFON TEUAEQ;Lo;0;L;;;;;N;;;;;
+1686C;BAMUM LETTER PHASE-B MBIT MBAAKET;Lo;0;L;;;;;N;;;;;
+1686D;BAMUM LETTER PHASE-B NYI NTEUM;Lo;0;L;;;;;N;;;;;
+1686E;BAMUM LETTER PHASE-B KEUPUQ;Lo;0;L;;;;;N;;;;;
+1686F;BAMUM LETTER PHASE-B GHEUGHEN;Lo;0;L;;;;;N;;;;;
+16870;BAMUM LETTER PHASE-B KEUYEUX;Lo;0;L;;;;;N;;;;;
+16871;BAMUM LETTER PHASE-B LAANAE;Lo;0;L;;;;;N;;;;;
+16872;BAMUM LETTER PHASE-B PARUM;Lo;0;L;;;;;N;;;;;
+16873;BAMUM LETTER PHASE-B VEUM;Lo;0;L;;;;;N;;;;;
+16874;BAMUM LETTER PHASE-B NGKINDI MVOP;Lo;0;L;;;;;N;;;;;
+16875;BAMUM LETTER PHASE-B NGGEU MBU;Lo;0;L;;;;;N;;;;;
+16876;BAMUM LETTER PHASE-B WUAET;Lo;0;L;;;;;N;;;;;
+16877;BAMUM LETTER PHASE-B SAKEUAE;Lo;0;L;;;;;N;;;;;
+16878;BAMUM LETTER PHASE-B TAAM;Lo;0;L;;;;;N;;;;;
+16879;BAMUM LETTER PHASE-B MEUQ;Lo;0;L;;;;;N;;;;;
+1687A;BAMUM LETTER PHASE-B NGGUOQ;Lo;0;L;;;;;N;;;;;
+1687B;BAMUM LETTER PHASE-B NGGUOQ LARGE;Lo;0;L;;;;;N;;;;;
+1687C;BAMUM LETTER PHASE-B MFIYAQ;Lo;0;L;;;;;N;;;;;
+1687D;BAMUM LETTER PHASE-B SUE;Lo;0;L;;;;;N;;;;;
+1687E;BAMUM LETTER PHASE-B MBEURI;Lo;0;L;;;;;N;;;;;
+1687F;BAMUM LETTER PHASE-B MONTIEEN;Lo;0;L;;;;;N;;;;;
+16880;BAMUM LETTER PHASE-B NYAEMAE;Lo;0;L;;;;;N;;;;;
+16881;BAMUM LETTER PHASE-B PUNGAAM;Lo;0;L;;;;;N;;;;;
+16882;BAMUM LETTER PHASE-B MEUT NGGEET;Lo;0;L;;;;;N;;;;;
+16883;BAMUM LETTER PHASE-B FEUX;Lo;0;L;;;;;N;;;;;
+16884;BAMUM LETTER PHASE-B MBUOQ;Lo;0;L;;;;;N;;;;;
+16885;BAMUM LETTER PHASE-B FEE;Lo;0;L;;;;;N;;;;;
+16886;BAMUM LETTER PHASE-B KEUAEM;Lo;0;L;;;;;N;;;;;
+16887;BAMUM LETTER PHASE-B MA NJEUAENA;Lo;0;L;;;;;N;;;;;
+16888;BAMUM LETTER PHASE-B MA NJUQA;Lo;0;L;;;;;N;;;;;
+16889;BAMUM LETTER PHASE-B LET;Lo;0;L;;;;;N;;;;;
+1688A;BAMUM LETTER PHASE-B NGGAAM;Lo;0;L;;;;;N;;;;;
+1688B;BAMUM LETTER PHASE-B NSEN;Lo;0;L;;;;;N;;;;;
+1688C;BAMUM LETTER PHASE-B MA;Lo;0;L;;;;;N;;;;;
+1688D;BAMUM LETTER PHASE-B KIQ;Lo;0;L;;;;;N;;;;;
+1688E;BAMUM LETTER PHASE-B NGOM;Lo;0;L;;;;;N;;;;;
+1688F;BAMUM LETTER PHASE-C NGKUE MAEMBA;Lo;0;L;;;;;N;;;;;
+16890;BAMUM LETTER PHASE-C NZA;Lo;0;L;;;;;N;;;;;
+16891;BAMUM LETTER PHASE-C YUM;Lo;0;L;;;;;N;;;;;
+16892;BAMUM LETTER PHASE-C WANGKUOQ;Lo;0;L;;;;;N;;;;;
+16893;BAMUM LETTER PHASE-C NGGEN;Lo;0;L;;;;;N;;;;;
+16894;BAMUM LETTER PHASE-C NDEUAEREE;Lo;0;L;;;;;N;;;;;
+16895;BAMUM LETTER PHASE-C NGKAQ;Lo;0;L;;;;;N;;;;;
+16896;BAMUM LETTER PHASE-C GHARAE;Lo;0;L;;;;;N;;;;;
+16897;BAMUM LETTER PHASE-C MBEEKEET;Lo;0;L;;;;;N;;;;;
+16898;BAMUM LETTER PHASE-C GBAYI;Lo;0;L;;;;;N;;;;;
+16899;BAMUM LETTER PHASE-C NYIR MKPARAQ MEUN;Lo;0;L;;;;;N;;;;;
+1689A;BAMUM LETTER PHASE-C NTU MBIT;Lo;0;L;;;;;N;;;;;
+1689B;BAMUM LETTER PHASE-C MBEUM;Lo;0;L;;;;;N;;;;;
+1689C;BAMUM LETTER PHASE-C PIRIEEN;Lo;0;L;;;;;N;;;;;
+1689D;BAMUM LETTER PHASE-C NDOMBU;Lo;0;L;;;;;N;;;;;
+1689E;BAMUM LETTER PHASE-C MBAA CABBAGE-TREE;Lo;0;L;;;;;N;;;;;
+1689F;BAMUM LETTER PHASE-C KEUSHEUAEP;Lo;0;L;;;;;N;;;;;
+168A0;BAMUM LETTER PHASE-C GHAP;Lo;0;L;;;;;N;;;;;
+168A1;BAMUM LETTER PHASE-C KEUKAQ;Lo;0;L;;;;;N;;;;;
+168A2;BAMUM LETTER PHASE-C YU MUOMAE;Lo;0;L;;;;;N;;;;;
+168A3;BAMUM LETTER PHASE-C NZEUM;Lo;0;L;;;;;N;;;;;
+168A4;BAMUM LETTER PHASE-C MBUE;Lo;0;L;;;;;N;;;;;
+168A5;BAMUM LETTER PHASE-C NSEUAEN;Lo;0;L;;;;;N;;;;;
+168A6;BAMUM LETTER PHASE-C MBIT;Lo;0;L;;;;;N;;;;;
+168A7;BAMUM LETTER PHASE-C YEUQ;Lo;0;L;;;;;N;;;;;
+168A8;BAMUM LETTER PHASE-C KPARAQ;Lo;0;L;;;;;N;;;;;
+168A9;BAMUM LETTER PHASE-C KAA;Lo;0;L;;;;;N;;;;;
+168AA;BAMUM LETTER PHASE-C SEUX;Lo;0;L;;;;;N;;;;;
+168AB;BAMUM LETTER PHASE-C NDIDA;Lo;0;L;;;;;N;;;;;
+168AC;BAMUM LETTER PHASE-C TAASHAE;Lo;0;L;;;;;N;;;;;
+168AD;BAMUM LETTER PHASE-C NJUEQ;Lo;0;L;;;;;N;;;;;
+168AE;BAMUM LETTER PHASE-C TITA YUE;Lo;0;L;;;;;N;;;;;
+168AF;BAMUM LETTER PHASE-C SUAET;Lo;0;L;;;;;N;;;;;
+168B0;BAMUM LETTER PHASE-C NGGUAEN NYAM;Lo;0;L;;;;;N;;;;;
+168B1;BAMUM LETTER PHASE-C VEUX;Lo;0;L;;;;;N;;;;;
+168B2;BAMUM LETTER PHASE-C NANSANAQ;Lo;0;L;;;;;N;;;;;
+168B3;BAMUM LETTER PHASE-C MA KEUAERI;Lo;0;L;;;;;N;;;;;
+168B4;BAMUM LETTER PHASE-C NTAA;Lo;0;L;;;;;N;;;;;
+168B5;BAMUM LETTER PHASE-C NGGUON;Lo;0;L;;;;;N;;;;;
+168B6;BAMUM LETTER PHASE-C LAP;Lo;0;L;;;;;N;;;;;
+168B7;BAMUM LETTER PHASE-C MBIRIEEN;Lo;0;L;;;;;N;;;;;
+168B8;BAMUM LETTER PHASE-C MGBASAQ;Lo;0;L;;;;;N;;;;;
+168B9;BAMUM LETTER PHASE-C NTEUNGBA;Lo;0;L;;;;;N;;;;;
+168BA;BAMUM LETTER PHASE-C TEUTEUX;Lo;0;L;;;;;N;;;;;
+168BB;BAMUM LETTER PHASE-C NGGUM;Lo;0;L;;;;;N;;;;;
+168BC;BAMUM LETTER PHASE-C FUE;Lo;0;L;;;;;N;;;;;
+168BD;BAMUM LETTER PHASE-C NDEUT;Lo;0;L;;;;;N;;;;;
+168BE;BAMUM LETTER PHASE-C NSA;Lo;0;L;;;;;N;;;;;
+168BF;BAMUM LETTER PHASE-C NSHAQ;Lo;0;L;;;;;N;;;;;
+168C0;BAMUM LETTER PHASE-C BUNG;Lo;0;L;;;;;N;;;;;
+168C1;BAMUM LETTER PHASE-C VEUAEPEN;Lo;0;L;;;;;N;;;;;
+168C2;BAMUM LETTER PHASE-C MBERAE;Lo;0;L;;;;;N;;;;;
+168C3;BAMUM LETTER PHASE-C RU;Lo;0;L;;;;;N;;;;;
+168C4;BAMUM LETTER PHASE-C NJAEM;Lo;0;L;;;;;N;;;;;
+168C5;BAMUM LETTER PHASE-C LAM;Lo;0;L;;;;;N;;;;;
+168C6;BAMUM LETTER PHASE-C TITUAEP;Lo;0;L;;;;;N;;;;;
+168C7;BAMUM LETTER PHASE-C NSUOT NGOM;Lo;0;L;;;;;N;;;;;
+168C8;BAMUM LETTER PHASE-C NJEEEE;Lo;0;L;;;;;N;;;;;
+168C9;BAMUM LETTER PHASE-C KET;Lo;0;L;;;;;N;;;;;
+168CA;BAMUM LETTER PHASE-C NGGU;Lo;0;L;;;;;N;;;;;
+168CB;BAMUM LETTER PHASE-C MAESI;Lo;0;L;;;;;N;;;;;
+168CC;BAMUM LETTER PHASE-C MBUAEM;Lo;0;L;;;;;N;;;;;
+168CD;BAMUM LETTER PHASE-C LU;Lo;0;L;;;;;N;;;;;
+168CE;BAMUM LETTER PHASE-C KUT;Lo;0;L;;;;;N;;;;;
+168CF;BAMUM LETTER PHASE-C NJAM;Lo;0;L;;;;;N;;;;;
+168D0;BAMUM LETTER PHASE-C NGOM;Lo;0;L;;;;;N;;;;;
+168D1;BAMUM LETTER PHASE-C WUP;Lo;0;L;;;;;N;;;;;
+168D2;BAMUM LETTER PHASE-C NGGUEET;Lo;0;L;;;;;N;;;;;
+168D3;BAMUM LETTER PHASE-C NSOM;Lo;0;L;;;;;N;;;;;
+168D4;BAMUM LETTER PHASE-C NTEN;Lo;0;L;;;;;N;;;;;
+168D5;BAMUM LETTER PHASE-C KUOP NKAARAE;Lo;0;L;;;;;N;;;;;
+168D6;BAMUM LETTER PHASE-C NSUN;Lo;0;L;;;;;N;;;;;
+168D7;BAMUM LETTER PHASE-C NDAM;Lo;0;L;;;;;N;;;;;
+168D8;BAMUM LETTER PHASE-C MA NSIEE;Lo;0;L;;;;;N;;;;;
+168D9;BAMUM LETTER PHASE-C YAA;Lo;0;L;;;;;N;;;;;
+168DA;BAMUM LETTER PHASE-C NDAP;Lo;0;L;;;;;N;;;;;
+168DB;BAMUM LETTER PHASE-C SHUEQ;Lo;0;L;;;;;N;;;;;
+168DC;BAMUM LETTER PHASE-C SETFON;Lo;0;L;;;;;N;;;;;
+168DD;BAMUM LETTER PHASE-C MBI;Lo;0;L;;;;;N;;;;;
+168DE;BAMUM LETTER PHASE-C MAEMBA;Lo;0;L;;;;;N;;;;;
+168DF;BAMUM LETTER PHASE-C MBANYI;Lo;0;L;;;;;N;;;;;
+168E0;BAMUM LETTER PHASE-C KEUSEUX;Lo;0;L;;;;;N;;;;;
+168E1;BAMUM LETTER PHASE-C MBEUX;Lo;0;L;;;;;N;;;;;
+168E2;BAMUM LETTER PHASE-C KEUM;Lo;0;L;;;;;N;;;;;
+168E3;BAMUM LETTER PHASE-C MBAA PICKET;Lo;0;L;;;;;N;;;;;
+168E4;BAMUM LETTER PHASE-C YUWOQ;Lo;0;L;;;;;N;;;;;
+168E5;BAMUM LETTER PHASE-C NJEUX;Lo;0;L;;;;;N;;;;;
+168E6;BAMUM LETTER PHASE-C MIEE;Lo;0;L;;;;;N;;;;;
+168E7;BAMUM LETTER PHASE-C MUAE;Lo;0;L;;;;;N;;;;;
+168E8;BAMUM LETTER PHASE-C SHIQ;Lo;0;L;;;;;N;;;;;
+168E9;BAMUM LETTER PHASE-C KEN LAW;Lo;0;L;;;;;N;;;;;
+168EA;BAMUM LETTER PHASE-C KEN FATIGUE;Lo;0;L;;;;;N;;;;;
+168EB;BAMUM LETTER PHASE-C NGAQ;Lo;0;L;;;;;N;;;;;
+168EC;BAMUM LETTER PHASE-C NAQ;Lo;0;L;;;;;N;;;;;
+168ED;BAMUM LETTER PHASE-C LIQ;Lo;0;L;;;;;N;;;;;
+168EE;BAMUM LETTER PHASE-C PIN;Lo;0;L;;;;;N;;;;;
+168EF;BAMUM LETTER PHASE-C PEN;Lo;0;L;;;;;N;;;;;
+168F0;BAMUM LETTER PHASE-C TET;Lo;0;L;;;;;N;;;;;
+168F1;BAMUM LETTER PHASE-D MBUO;Lo;0;L;;;;;N;;;;;
+168F2;BAMUM LETTER PHASE-D WAP;Lo;0;L;;;;;N;;;;;
+168F3;BAMUM LETTER PHASE-D NJI;Lo;0;L;;;;;N;;;;;
+168F4;BAMUM LETTER PHASE-D MFON;Lo;0;L;;;;;N;;;;;
+168F5;BAMUM LETTER PHASE-D NJIEE;Lo;0;L;;;;;N;;;;;
+168F6;BAMUM LETTER PHASE-D LIEE;Lo;0;L;;;;;N;;;;;
+168F7;BAMUM LETTER PHASE-D NJEUT;Lo;0;L;;;;;N;;;;;
+168F8;BAMUM LETTER PHASE-D NSHEE;Lo;0;L;;;;;N;;;;;
+168F9;BAMUM LETTER PHASE-D NGGAAMAE;Lo;0;L;;;;;N;;;;;
+168FA;BAMUM LETTER PHASE-D NYAM;Lo;0;L;;;;;N;;;;;
+168FB;BAMUM LETTER PHASE-D WUAEN;Lo;0;L;;;;;N;;;;;
+168FC;BAMUM LETTER PHASE-D NGKUN;Lo;0;L;;;;;N;;;;;
+168FD;BAMUM LETTER PHASE-D SHEE;Lo;0;L;;;;;N;;;;;
+168FE;BAMUM LETTER PHASE-D NGKAP;Lo;0;L;;;;;N;;;;;
+168FF;BAMUM LETTER PHASE-D KEUAETMEUN;Lo;0;L;;;;;N;;;;;
+16900;BAMUM LETTER PHASE-D TEUT;Lo;0;L;;;;;N;;;;;
+16901;BAMUM LETTER PHASE-D SHEUAE;Lo;0;L;;;;;N;;;;;
+16902;BAMUM LETTER PHASE-D NJAP;Lo;0;L;;;;;N;;;;;
+16903;BAMUM LETTER PHASE-D SUE;Lo;0;L;;;;;N;;;;;
+16904;BAMUM LETTER PHASE-D KET;Lo;0;L;;;;;N;;;;;
+16905;BAMUM LETTER PHASE-D YAEMMAE;Lo;0;L;;;;;N;;;;;
+16906;BAMUM LETTER PHASE-D KUOM;Lo;0;L;;;;;N;;;;;
+16907;BAMUM LETTER PHASE-D SAP;Lo;0;L;;;;;N;;;;;
+16908;BAMUM LETTER PHASE-D MFEUT;Lo;0;L;;;;;N;;;;;
+16909;BAMUM LETTER PHASE-D NDEUX;Lo;0;L;;;;;N;;;;;
+1690A;BAMUM LETTER PHASE-D MALEERI;Lo;0;L;;;;;N;;;;;
+1690B;BAMUM LETTER PHASE-D MEUT;Lo;0;L;;;;;N;;;;;
+1690C;BAMUM LETTER PHASE-D SEUAEQ;Lo;0;L;;;;;N;;;;;
+1690D;BAMUM LETTER PHASE-D YEN;Lo;0;L;;;;;N;;;;;
+1690E;BAMUM LETTER PHASE-D NJEUAEM;Lo;0;L;;;;;N;;;;;
+1690F;BAMUM LETTER PHASE-D KEUOT MBUAE;Lo;0;L;;;;;N;;;;;
+16910;BAMUM LETTER PHASE-D NGKEURI;Lo;0;L;;;;;N;;;;;
+16911;BAMUM LETTER PHASE-D TU;Lo;0;L;;;;;N;;;;;
+16912;BAMUM LETTER PHASE-D GHAA;Lo;0;L;;;;;N;;;;;
+16913;BAMUM LETTER PHASE-D NGKYEE;Lo;0;L;;;;;N;;;;;
+16914;BAMUM LETTER PHASE-D FEUFEUAET;Lo;0;L;;;;;N;;;;;
+16915;BAMUM LETTER PHASE-D NDEE;Lo;0;L;;;;;N;;;;;
+16916;BAMUM LETTER PHASE-D MGBOFUM;Lo;0;L;;;;;N;;;;;
+16917;BAMUM LETTER PHASE-D LEUAEP;Lo;0;L;;;;;N;;;;;
+16918;BAMUM LETTER PHASE-D NDON;Lo;0;L;;;;;N;;;;;
+16919;BAMUM LETTER PHASE-D MONI;Lo;0;L;;;;;N;;;;;
+1691A;BAMUM LETTER PHASE-D MGBEUN;Lo;0;L;;;;;N;;;;;
+1691B;BAMUM LETTER PHASE-D PUUT;Lo;0;L;;;;;N;;;;;
+1691C;BAMUM LETTER PHASE-D MGBIEE;Lo;0;L;;;;;N;;;;;
+1691D;BAMUM LETTER PHASE-D MFO;Lo;0;L;;;;;N;;;;;
+1691E;BAMUM LETTER PHASE-D LUM;Lo;0;L;;;;;N;;;;;
+1691F;BAMUM LETTER PHASE-D NSIEEP;Lo;0;L;;;;;N;;;;;
+16920;BAMUM LETTER PHASE-D MBAA;Lo;0;L;;;;;N;;;;;
+16921;BAMUM LETTER PHASE-D KWAET;Lo;0;L;;;;;N;;;;;
+16922;BAMUM LETTER PHASE-D NYET;Lo;0;L;;;;;N;;;;;
+16923;BAMUM LETTER PHASE-D TEUAEN;Lo;0;L;;;;;N;;;;;
+16924;BAMUM LETTER PHASE-D SOT;Lo;0;L;;;;;N;;;;;
+16925;BAMUM LETTER PHASE-D YUWOQ;Lo;0;L;;;;;N;;;;;
+16926;BAMUM LETTER PHASE-D KEUM;Lo;0;L;;;;;N;;;;;
+16927;BAMUM LETTER PHASE-D RAEM;Lo;0;L;;;;;N;;;;;
+16928;BAMUM LETTER PHASE-D TEEEE;Lo;0;L;;;;;N;;;;;
+16929;BAMUM LETTER PHASE-D NGKEUAEQ;Lo;0;L;;;;;N;;;;;
+1692A;BAMUM LETTER PHASE-D MFEUAE;Lo;0;L;;;;;N;;;;;
+1692B;BAMUM LETTER PHASE-D NSIEET;Lo;0;L;;;;;N;;;;;
+1692C;BAMUM LETTER PHASE-D KEUP;Lo;0;L;;;;;N;;;;;
+1692D;BAMUM LETTER PHASE-D PIP;Lo;0;L;;;;;N;;;;;
+1692E;BAMUM LETTER PHASE-D PEUTAE;Lo;0;L;;;;;N;;;;;
+1692F;BAMUM LETTER PHASE-D NYUE;Lo;0;L;;;;;N;;;;;
+16930;BAMUM LETTER PHASE-D LET;Lo;0;L;;;;;N;;;;;
+16931;BAMUM LETTER PHASE-D NGGAAM;Lo;0;L;;;;;N;;;;;
+16932;BAMUM LETTER PHASE-D MFIEE;Lo;0;L;;;;;N;;;;;
+16933;BAMUM LETTER PHASE-D NGGWAEN;Lo;0;L;;;;;N;;;;;
+16934;BAMUM LETTER PHASE-D YUOM;Lo;0;L;;;;;N;;;;;
+16935;BAMUM LETTER PHASE-D PAP;Lo;0;L;;;;;N;;;;;
+16936;BAMUM LETTER PHASE-D YUOP;Lo;0;L;;;;;N;;;;;
+16937;BAMUM LETTER PHASE-D NDAM;Lo;0;L;;;;;N;;;;;
+16938;BAMUM LETTER PHASE-D NTEUM;Lo;0;L;;;;;N;;;;;
+16939;BAMUM LETTER PHASE-D SUAE;Lo;0;L;;;;;N;;;;;
+1693A;BAMUM LETTER PHASE-D KUN;Lo;0;L;;;;;N;;;;;
+1693B;BAMUM LETTER PHASE-D NGGEUX;Lo;0;L;;;;;N;;;;;
+1693C;BAMUM LETTER PHASE-D NGKIEE;Lo;0;L;;;;;N;;;;;
+1693D;BAMUM LETTER PHASE-D TUOT;Lo;0;L;;;;;N;;;;;
+1693E;BAMUM LETTER PHASE-D MEUN;Lo;0;L;;;;;N;;;;;
+1693F;BAMUM LETTER PHASE-D KUQ;Lo;0;L;;;;;N;;;;;
+16940;BAMUM LETTER PHASE-D NSUM;Lo;0;L;;;;;N;;;;;
+16941;BAMUM LETTER PHASE-D TEUN;Lo;0;L;;;;;N;;;;;
+16942;BAMUM LETTER PHASE-D MAENJET;Lo;0;L;;;;;N;;;;;
+16943;BAMUM LETTER PHASE-D NGGAP;Lo;0;L;;;;;N;;;;;
+16944;BAMUM LETTER PHASE-D LEUM;Lo;0;L;;;;;N;;;;;
+16945;BAMUM LETTER PHASE-D NGGUOM;Lo;0;L;;;;;N;;;;;
+16946;BAMUM LETTER PHASE-D NSHUT;Lo;0;L;;;;;N;;;;;
+16947;BAMUM LETTER PHASE-D NJUEQ;Lo;0;L;;;;;N;;;;;
+16948;BAMUM LETTER PHASE-D GHEUAE;Lo;0;L;;;;;N;;;;;
+16949;BAMUM LETTER PHASE-D KU;Lo;0;L;;;;;N;;;;;
+1694A;BAMUM LETTER PHASE-D REN OLD;Lo;0;L;;;;;N;;;;;
+1694B;BAMUM LETTER PHASE-D TAE;Lo;0;L;;;;;N;;;;;
+1694C;BAMUM LETTER PHASE-D TOQ;Lo;0;L;;;;;N;;;;;
+1694D;BAMUM LETTER PHASE-D NYI;Lo;0;L;;;;;N;;;;;
+1694E;BAMUM LETTER PHASE-D RII;Lo;0;L;;;;;N;;;;;
+1694F;BAMUM LETTER PHASE-D LEEEE;Lo;0;L;;;;;N;;;;;
+16950;BAMUM LETTER PHASE-D MEEEE;Lo;0;L;;;;;N;;;;;
+16951;BAMUM LETTER PHASE-D M;Lo;0;L;;;;;N;;;;;
+16952;BAMUM LETTER PHASE-D SUU;Lo;0;L;;;;;N;;;;;
+16953;BAMUM LETTER PHASE-D MU;Lo;0;L;;;;;N;;;;;
+16954;BAMUM LETTER PHASE-D SHII;Lo;0;L;;;;;N;;;;;
+16955;BAMUM LETTER PHASE-D SHEUX;Lo;0;L;;;;;N;;;;;
+16956;BAMUM LETTER PHASE-D KYEE;Lo;0;L;;;;;N;;;;;
+16957;BAMUM LETTER PHASE-D NU;Lo;0;L;;;;;N;;;;;
+16958;BAMUM LETTER PHASE-D SHU;Lo;0;L;;;;;N;;;;;
+16959;BAMUM LETTER PHASE-D NTEE;Lo;0;L;;;;;N;;;;;
+1695A;BAMUM LETTER PHASE-D PEE;Lo;0;L;;;;;N;;;;;
+1695B;BAMUM LETTER PHASE-D NI;Lo;0;L;;;;;N;;;;;
+1695C;BAMUM LETTER PHASE-D SHOQ;Lo;0;L;;;;;N;;;;;
+1695D;BAMUM LETTER PHASE-D PUQ;Lo;0;L;;;;;N;;;;;
+1695E;BAMUM LETTER PHASE-D MVOP;Lo;0;L;;;;;N;;;;;
+1695F;BAMUM LETTER PHASE-D LOQ;Lo;0;L;;;;;N;;;;;
+16960;BAMUM LETTER PHASE-D REN MUCH;Lo;0;L;;;;;N;;;;;
+16961;BAMUM LETTER PHASE-D TI;Lo;0;L;;;;;N;;;;;
+16962;BAMUM LETTER PHASE-D NTUU;Lo;0;L;;;;;N;;;;;
+16963;BAMUM LETTER PHASE-D MBAA SEVEN;Lo;0;L;;;;;N;;;;;
+16964;BAMUM LETTER PHASE-D SAQ;Lo;0;L;;;;;N;;;;;
+16965;BAMUM LETTER PHASE-D FAA;Lo;0;L;;;;;N;;;;;
+16966;BAMUM LETTER PHASE-E NDAP;Lo;0;L;;;;;N;;;;;
+16967;BAMUM LETTER PHASE-E TOON;Lo;0;L;;;;;N;;;;;
+16968;BAMUM LETTER PHASE-E MBEUM;Lo;0;L;;;;;N;;;;;
+16969;BAMUM LETTER PHASE-E LAP;Lo;0;L;;;;;N;;;;;
+1696A;BAMUM LETTER PHASE-E VOM;Lo;0;L;;;;;N;;;;;
+1696B;BAMUM LETTER PHASE-E LOON;Lo;0;L;;;;;N;;;;;
+1696C;BAMUM LETTER PHASE-E PAA;Lo;0;L;;;;;N;;;;;
+1696D;BAMUM LETTER PHASE-E SOM;Lo;0;L;;;;;N;;;;;
+1696E;BAMUM LETTER PHASE-E RAQ;Lo;0;L;;;;;N;;;;;
+1696F;BAMUM LETTER PHASE-E NSHUOP;Lo;0;L;;;;;N;;;;;
+16970;BAMUM LETTER PHASE-E NDUN;Lo;0;L;;;;;N;;;;;
+16971;BAMUM LETTER PHASE-E PUAE;Lo;0;L;;;;;N;;;;;
+16972;BAMUM LETTER PHASE-E TAM;Lo;0;L;;;;;N;;;;;
+16973;BAMUM LETTER PHASE-E NGKA;Lo;0;L;;;;;N;;;;;
+16974;BAMUM LETTER PHASE-E KPEUX;Lo;0;L;;;;;N;;;;;
+16975;BAMUM LETTER PHASE-E WUO;Lo;0;L;;;;;N;;;;;
+16976;BAMUM LETTER PHASE-E SEE;Lo;0;L;;;;;N;;;;;
+16977;BAMUM LETTER PHASE-E NGGEUAET;Lo;0;L;;;;;N;;;;;
+16978;BAMUM LETTER PHASE-E PAAM;Lo;0;L;;;;;N;;;;;
+16979;BAMUM LETTER PHASE-E TOO;Lo;0;L;;;;;N;;;;;
+1697A;BAMUM LETTER PHASE-E KUOP;Lo;0;L;;;;;N;;;;;
+1697B;BAMUM LETTER PHASE-E LOM;Lo;0;L;;;;;N;;;;;
+1697C;BAMUM LETTER PHASE-E NSHIEE;Lo;0;L;;;;;N;;;;;
+1697D;BAMUM LETTER PHASE-E NGOP;Lo;0;L;;;;;N;;;;;
+1697E;BAMUM LETTER PHASE-E MAEM;Lo;0;L;;;;;N;;;;;
+1697F;BAMUM LETTER PHASE-E NGKEUX;Lo;0;L;;;;;N;;;;;
+16980;BAMUM LETTER PHASE-E NGOQ;Lo;0;L;;;;;N;;;;;
+16981;BAMUM LETTER PHASE-E NSHUE;Lo;0;L;;;;;N;;;;;
+16982;BAMUM LETTER PHASE-E RIMGBA;Lo;0;L;;;;;N;;;;;
+16983;BAMUM LETTER PHASE-E NJEUX;Lo;0;L;;;;;N;;;;;
+16984;BAMUM LETTER PHASE-E PEEM;Lo;0;L;;;;;N;;;;;
+16985;BAMUM LETTER PHASE-E SAA;Lo;0;L;;;;;N;;;;;
+16986;BAMUM LETTER PHASE-E NGGURAE;Lo;0;L;;;;;N;;;;;
+16987;BAMUM LETTER PHASE-E MGBA;Lo;0;L;;;;;N;;;;;
+16988;BAMUM LETTER PHASE-E GHEUX;Lo;0;L;;;;;N;;;;;
+16989;BAMUM LETTER PHASE-E NGKEUAEM;Lo;0;L;;;;;N;;;;;
+1698A;BAMUM LETTER PHASE-E NJAEMLI;Lo;0;L;;;;;N;;;;;
+1698B;BAMUM LETTER PHASE-E MAP;Lo;0;L;;;;;N;;;;;
+1698C;BAMUM LETTER PHASE-E LOOT;Lo;0;L;;;;;N;;;;;
+1698D;BAMUM LETTER PHASE-E NGGEEEE;Lo;0;L;;;;;N;;;;;
+1698E;BAMUM LETTER PHASE-E NDIQ;Lo;0;L;;;;;N;;;;;
+1698F;BAMUM LETTER PHASE-E TAEN NTEUM;Lo;0;L;;;;;N;;;;;
+16990;BAMUM LETTER PHASE-E SET;Lo;0;L;;;;;N;;;;;
+16991;BAMUM LETTER PHASE-E PUM;Lo;0;L;;;;;N;;;;;
+16992;BAMUM LETTER PHASE-E NDAA SOFTNESS;Lo;0;L;;;;;N;;;;;
+16993;BAMUM LETTER PHASE-E NGGUAESHAE NYAM;Lo;0;L;;;;;N;;;;;
+16994;BAMUM LETTER PHASE-E YIEE;Lo;0;L;;;;;N;;;;;
+16995;BAMUM LETTER PHASE-E GHEUN;Lo;0;L;;;;;N;;;;;
+16996;BAMUM LETTER PHASE-E TUAE;Lo;0;L;;;;;N;;;;;
+16997;BAMUM LETTER PHASE-E YEUAE;Lo;0;L;;;;;N;;;;;
+16998;BAMUM LETTER PHASE-E PO;Lo;0;L;;;;;N;;;;;
+16999;BAMUM LETTER PHASE-E TUMAE;Lo;0;L;;;;;N;;;;;
+1699A;BAMUM LETTER PHASE-E KEUAE;Lo;0;L;;;;;N;;;;;
+1699B;BAMUM LETTER PHASE-E SUAEN;Lo;0;L;;;;;N;;;;;
+1699C;BAMUM LETTER PHASE-E TEUAEQ;Lo;0;L;;;;;N;;;;;
+1699D;BAMUM LETTER PHASE-E VEUAE;Lo;0;L;;;;;N;;;;;
+1699E;BAMUM LETTER PHASE-E WEUX;Lo;0;L;;;;;N;;;;;
+1699F;BAMUM LETTER PHASE-E LAAM;Lo;0;L;;;;;N;;;;;
+169A0;BAMUM LETTER PHASE-E PU;Lo;0;L;;;;;N;;;;;
+169A1;BAMUM LETTER PHASE-E TAAQ;Lo;0;L;;;;;N;;;;;
+169A2;BAMUM LETTER PHASE-E GHAAMAE;Lo;0;L;;;;;N;;;;;
+169A3;BAMUM LETTER PHASE-E NGEUREUT;Lo;0;L;;;;;N;;;;;
+169A4;BAMUM LETTER PHASE-E SHEUAEQ;Lo;0;L;;;;;N;;;;;
+169A5;BAMUM LETTER PHASE-E MGBEN;Lo;0;L;;;;;N;;;;;
+169A6;BAMUM LETTER PHASE-E MBEE;Lo;0;L;;;;;N;;;;;
+169A7;BAMUM LETTER PHASE-E NZAQ;Lo;0;L;;;;;N;;;;;
+169A8;BAMUM LETTER PHASE-E NKOM;Lo;0;L;;;;;N;;;;;
+169A9;BAMUM LETTER PHASE-E GBET;Lo;0;L;;;;;N;;;;;
+169AA;BAMUM LETTER PHASE-E TUM;Lo;0;L;;;;;N;;;;;
+169AB;BAMUM LETTER PHASE-E KUET;Lo;0;L;;;;;N;;;;;
+169AC;BAMUM LETTER PHASE-E YAP;Lo;0;L;;;;;N;;;;;
+169AD;BAMUM LETTER PHASE-E NYI CLEAVER;Lo;0;L;;;;;N;;;;;
+169AE;BAMUM LETTER PHASE-E YIT;Lo;0;L;;;;;N;;;;;
+169AF;BAMUM LETTER PHASE-E MFEUQ;Lo;0;L;;;;;N;;;;;
+169B0;BAMUM LETTER PHASE-E NDIAQ;Lo;0;L;;;;;N;;;;;
+169B1;BAMUM LETTER PHASE-E PIEEQ;Lo;0;L;;;;;N;;;;;
+169B2;BAMUM LETTER PHASE-E YUEQ;Lo;0;L;;;;;N;;;;;
+169B3;BAMUM LETTER PHASE-E LEUAEM;Lo;0;L;;;;;N;;;;;
+169B4;BAMUM LETTER PHASE-E FUE;Lo;0;L;;;;;N;;;;;
+169B5;BAMUM LETTER PHASE-E GBEUX;Lo;0;L;;;;;N;;;;;
+169B6;BAMUM LETTER PHASE-E NGKUP;Lo;0;L;;;;;N;;;;;
+169B7;BAMUM LETTER PHASE-E KET;Lo;0;L;;;;;N;;;;;
+169B8;BAMUM LETTER PHASE-E MAE;Lo;0;L;;;;;N;;;;;
+169B9;BAMUM LETTER PHASE-E NGKAAMI;Lo;0;L;;;;;N;;;;;
+169BA;BAMUM LETTER PHASE-E GHET;Lo;0;L;;;;;N;;;;;
+169BB;BAMUM LETTER PHASE-E FA;Lo;0;L;;;;;N;;;;;
+169BC;BAMUM LETTER PHASE-E NTUM;Lo;0;L;;;;;N;;;;;
+169BD;BAMUM LETTER PHASE-E PEUT;Lo;0;L;;;;;N;;;;;
+169BE;BAMUM LETTER PHASE-E YEUM;Lo;0;L;;;;;N;;;;;
+169BF;BAMUM LETTER PHASE-E NGGEUAE;Lo;0;L;;;;;N;;;;;
+169C0;BAMUM LETTER PHASE-E NYI BETWEEN;Lo;0;L;;;;;N;;;;;
+169C1;BAMUM LETTER PHASE-E NZUQ;Lo;0;L;;;;;N;;;;;
+169C2;BAMUM LETTER PHASE-E POON;Lo;0;L;;;;;N;;;;;
+169C3;BAMUM LETTER PHASE-E MIEE;Lo;0;L;;;;;N;;;;;
+169C4;BAMUM LETTER PHASE-E FUET;Lo;0;L;;;;;N;;;;;
+169C5;BAMUM LETTER PHASE-E NAE;Lo;0;L;;;;;N;;;;;
+169C6;BAMUM LETTER PHASE-E MUAE;Lo;0;L;;;;;N;;;;;
+169C7;BAMUM LETTER PHASE-E GHEUAE;Lo;0;L;;;;;N;;;;;
+169C8;BAMUM LETTER PHASE-E FU I;Lo;0;L;;;;;N;;;;;
+169C9;BAMUM LETTER PHASE-E MVI;Lo;0;L;;;;;N;;;;;
+169CA;BAMUM LETTER PHASE-E PUAQ;Lo;0;L;;;;;N;;;;;
+169CB;BAMUM LETTER PHASE-E NGKUM;Lo;0;L;;;;;N;;;;;
+169CC;BAMUM LETTER PHASE-E KUT;Lo;0;L;;;;;N;;;;;
+169CD;BAMUM LETTER PHASE-E PIET;Lo;0;L;;;;;N;;;;;
+169CE;BAMUM LETTER PHASE-E NTAP;Lo;0;L;;;;;N;;;;;
+169CF;BAMUM LETTER PHASE-E YEUAET;Lo;0;L;;;;;N;;;;;
+169D0;BAMUM LETTER PHASE-E NGGUP;Lo;0;L;;;;;N;;;;;
+169D1;BAMUM LETTER PHASE-E PA PEOPLE;Lo;0;L;;;;;N;;;;;
+169D2;BAMUM LETTER PHASE-E FU CALL;Lo;0;L;;;;;N;;;;;
+169D3;BAMUM LETTER PHASE-E FOM;Lo;0;L;;;;;N;;;;;
+169D4;BAMUM LETTER PHASE-E NJEE;Lo;0;L;;;;;N;;;;;
+169D5;BAMUM LETTER PHASE-E A;Lo;0;L;;;;;N;;;;;
+169D6;BAMUM LETTER PHASE-E TOQ;Lo;0;L;;;;;N;;;;;
+169D7;BAMUM LETTER PHASE-E O;Lo;0;L;;;;;N;;;;;
+169D8;BAMUM LETTER PHASE-E I;Lo;0;L;;;;;N;;;;;
+169D9;BAMUM LETTER PHASE-E LAQ;Lo;0;L;;;;;N;;;;;
+169DA;BAMUM LETTER PHASE-E PA PLURAL;Lo;0;L;;;;;N;;;;;
+169DB;BAMUM LETTER PHASE-E TAA;Lo;0;L;;;;;N;;;;;
+169DC;BAMUM LETTER PHASE-E TAQ;Lo;0;L;;;;;N;;;;;
+169DD;BAMUM LETTER PHASE-E NDAA MY HOUSE;Lo;0;L;;;;;N;;;;;
+169DE;BAMUM LETTER PHASE-E SHIQ;Lo;0;L;;;;;N;;;;;
+169DF;BAMUM LETTER PHASE-E YEUX;Lo;0;L;;;;;N;;;;;
+169E0;BAMUM LETTER PHASE-E NGUAE;Lo;0;L;;;;;N;;;;;
+169E1;BAMUM LETTER PHASE-E YUAEN;Lo;0;L;;;;;N;;;;;
+169E2;BAMUM LETTER PHASE-E YOQ SWIMMING;Lo;0;L;;;;;N;;;;;
+169E3;BAMUM LETTER PHASE-E YOQ COVER;Lo;0;L;;;;;N;;;;;
+169E4;BAMUM LETTER PHASE-E YUQ;Lo;0;L;;;;;N;;;;;
+169E5;BAMUM LETTER PHASE-E YUN;Lo;0;L;;;;;N;;;;;
+169E6;BAMUM LETTER PHASE-E KEUX;Lo;0;L;;;;;N;;;;;
+169E7;BAMUM LETTER PHASE-E PEUX;Lo;0;L;;;;;N;;;;;
+169E8;BAMUM LETTER PHASE-E NJEE EPOCH;Lo;0;L;;;;;N;;;;;
+169E9;BAMUM LETTER PHASE-E PUE;Lo;0;L;;;;;N;;;;;
+169EA;BAMUM LETTER PHASE-E WUE;Lo;0;L;;;;;N;;;;;
+169EB;BAMUM LETTER PHASE-E FEE;Lo;0;L;;;;;N;;;;;
+169EC;BAMUM LETTER PHASE-E VEE;Lo;0;L;;;;;N;;;;;
+169ED;BAMUM LETTER PHASE-E LU;Lo;0;L;;;;;N;;;;;
+169EE;BAMUM LETTER PHASE-E MI;Lo;0;L;;;;;N;;;;;
+169EF;BAMUM LETTER PHASE-E REUX;Lo;0;L;;;;;N;;;;;
+169F0;BAMUM LETTER PHASE-E RAE;Lo;0;L;;;;;N;;;;;
+169F1;BAMUM LETTER PHASE-E NGUAET;Lo;0;L;;;;;N;;;;;
+169F2;BAMUM LETTER PHASE-E NGA;Lo;0;L;;;;;N;;;;;
+169F3;BAMUM LETTER PHASE-E SHO;Lo;0;L;;;;;N;;;;;
+169F4;BAMUM LETTER PHASE-E SHOQ;Lo;0;L;;;;;N;;;;;
+169F5;BAMUM LETTER PHASE-E FU REMEDY;Lo;0;L;;;;;N;;;;;
+169F6;BAMUM LETTER PHASE-E NA;Lo;0;L;;;;;N;;;;;
+169F7;BAMUM LETTER PHASE-E PI;Lo;0;L;;;;;N;;;;;
+169F8;BAMUM LETTER PHASE-E LOQ;Lo;0;L;;;;;N;;;;;
+169F9;BAMUM LETTER PHASE-E KO;Lo;0;L;;;;;N;;;;;
+169FA;BAMUM LETTER PHASE-E MEN;Lo;0;L;;;;;N;;;;;
+169FB;BAMUM LETTER PHASE-E MA;Lo;0;L;;;;;N;;;;;
+169FC;BAMUM LETTER PHASE-E MAQ;Lo;0;L;;;;;N;;;;;
+169FD;BAMUM LETTER PHASE-E TEU;Lo;0;L;;;;;N;;;;;
+169FE;BAMUM LETTER PHASE-E KI;Lo;0;L;;;;;N;;;;;
+169FF;BAMUM LETTER PHASE-E MON;Lo;0;L;;;;;N;;;;;
+16A00;BAMUM LETTER PHASE-E TEN;Lo;0;L;;;;;N;;;;;
+16A01;BAMUM LETTER PHASE-E FAQ;Lo;0;L;;;;;N;;;;;
+16A02;BAMUM LETTER PHASE-E GHOM;Lo;0;L;;;;;N;;;;;
+16A03;BAMUM LETTER PHASE-F KA;Lo;0;L;;;;;N;;;;;
+16A04;BAMUM LETTER PHASE-F U;Lo;0;L;;;;;N;;;;;
+16A05;BAMUM LETTER PHASE-F KU;Lo;0;L;;;;;N;;;;;
+16A06;BAMUM LETTER PHASE-F EE;Lo;0;L;;;;;N;;;;;
+16A07;BAMUM LETTER PHASE-F REE;Lo;0;L;;;;;N;;;;;
+16A08;BAMUM LETTER PHASE-F TAE;Lo;0;L;;;;;N;;;;;
+16A09;BAMUM LETTER PHASE-F NYI;Lo;0;L;;;;;N;;;;;
+16A0A;BAMUM LETTER PHASE-F LA;Lo;0;L;;;;;N;;;;;
+16A0B;BAMUM LETTER PHASE-F RII;Lo;0;L;;;;;N;;;;;
+16A0C;BAMUM LETTER PHASE-F RIEE;Lo;0;L;;;;;N;;;;;
+16A0D;BAMUM LETTER PHASE-F MEEEE;Lo;0;L;;;;;N;;;;;
+16A0E;BAMUM LETTER PHASE-F TAA;Lo;0;L;;;;;N;;;;;
+16A0F;BAMUM LETTER PHASE-F NDAA;Lo;0;L;;;;;N;;;;;
+16A10;BAMUM LETTER PHASE-F NJAEM;Lo;0;L;;;;;N;;;;;
+16A11;BAMUM LETTER PHASE-F M;Lo;0;L;;;;;N;;;;;
+16A12;BAMUM LETTER PHASE-F SUU;Lo;0;L;;;;;N;;;;;
+16A13;BAMUM LETTER PHASE-F SHII;Lo;0;L;;;;;N;;;;;
+16A14;BAMUM LETTER PHASE-F SI;Lo;0;L;;;;;N;;;;;
+16A15;BAMUM LETTER PHASE-F SEUX;Lo;0;L;;;;;N;;;;;
+16A16;BAMUM LETTER PHASE-F KYEE;Lo;0;L;;;;;N;;;;;
+16A17;BAMUM LETTER PHASE-F KET;Lo;0;L;;;;;N;;;;;
+16A18;BAMUM LETTER PHASE-F NUAE;Lo;0;L;;;;;N;;;;;
+16A19;BAMUM LETTER PHASE-F NU;Lo;0;L;;;;;N;;;;;
+16A1A;BAMUM LETTER PHASE-F NJUAE;Lo;0;L;;;;;N;;;;;
+16A1B;BAMUM LETTER PHASE-F YOQ;Lo;0;L;;;;;N;;;;;
+16A1C;BAMUM LETTER PHASE-F SHU;Lo;0;L;;;;;N;;;;;
+16A1D;BAMUM LETTER PHASE-F YA;Lo;0;L;;;;;N;;;;;
+16A1E;BAMUM LETTER PHASE-F NSHA;Lo;0;L;;;;;N;;;;;
+16A1F;BAMUM LETTER PHASE-F PEUX;Lo;0;L;;;;;N;;;;;
+16A20;BAMUM LETTER PHASE-F NTEE;Lo;0;L;;;;;N;;;;;
+16A21;BAMUM LETTER PHASE-F WUE;Lo;0;L;;;;;N;;;;;
+16A22;BAMUM LETTER PHASE-F PEE;Lo;0;L;;;;;N;;;;;
+16A23;BAMUM LETTER PHASE-F RU;Lo;0;L;;;;;N;;;;;
+16A24;BAMUM LETTER PHASE-F NI;Lo;0;L;;;;;N;;;;;
+16A25;BAMUM LETTER PHASE-F REUX;Lo;0;L;;;;;N;;;;;
+16A26;BAMUM LETTER PHASE-F KEN;Lo;0;L;;;;;N;;;;;
+16A27;BAMUM LETTER PHASE-F NGKWAEN;Lo;0;L;;;;;N;;;;;
+16A28;BAMUM LETTER PHASE-F NGGA;Lo;0;L;;;;;N;;;;;
+16A29;BAMUM LETTER PHASE-F SHO;Lo;0;L;;;;;N;;;;;
+16A2A;BAMUM LETTER PHASE-F PUAE;Lo;0;L;;;;;N;;;;;
+16A2B;BAMUM LETTER PHASE-F FOM;Lo;0;L;;;;;N;;;;;
+16A2C;BAMUM LETTER PHASE-F WA;Lo;0;L;;;;;N;;;;;
+16A2D;BAMUM LETTER PHASE-F LI;Lo;0;L;;;;;N;;;;;
+16A2E;BAMUM LETTER PHASE-F LOQ;Lo;0;L;;;;;N;;;;;
+16A2F;BAMUM LETTER PHASE-F KO;Lo;0;L;;;;;N;;;;;
+16A30;BAMUM LETTER PHASE-F MBEN;Lo;0;L;;;;;N;;;;;
+16A31;BAMUM LETTER PHASE-F REN;Lo;0;L;;;;;N;;;;;
+16A32;BAMUM LETTER PHASE-F MA;Lo;0;L;;;;;N;;;;;
+16A33;BAMUM LETTER PHASE-F MO;Lo;0;L;;;;;N;;;;;
+16A34;BAMUM LETTER PHASE-F MBAA;Lo;0;L;;;;;N;;;;;
+16A35;BAMUM LETTER PHASE-F TET;Lo;0;L;;;;;N;;;;;
+16A36;BAMUM LETTER PHASE-F KPA;Lo;0;L;;;;;N;;;;;
+16A37;BAMUM LETTER PHASE-F SAMBA;Lo;0;L;;;;;N;;;;;
+16A38;BAMUM LETTER PHASE-F VUEQ;Lo;0;L;;;;;N;;;;;
+16A40;MRO LETTER TA;Lo;0;L;;;;;N;;;;;
+16A41;MRO LETTER NGI;Lo;0;L;;;;;N;;;;;
+16A42;MRO LETTER YO;Lo;0;L;;;;;N;;;;;
+16A43;MRO LETTER MIM;Lo;0;L;;;;;N;;;;;
+16A44;MRO LETTER BA;Lo;0;L;;;;;N;;;;;
+16A45;MRO LETTER DA;Lo;0;L;;;;;N;;;;;
+16A46;MRO LETTER A;Lo;0;L;;;;;N;;;;;
+16A47;MRO LETTER PHI;Lo;0;L;;;;;N;;;;;
+16A48;MRO LETTER KHAI;Lo;0;L;;;;;N;;;;;
+16A49;MRO LETTER HAO;Lo;0;L;;;;;N;;;;;
+16A4A;MRO LETTER DAI;Lo;0;L;;;;;N;;;;;
+16A4B;MRO LETTER CHU;Lo;0;L;;;;;N;;;;;
+16A4C;MRO LETTER KEAAE;Lo;0;L;;;;;N;;;;;
+16A4D;MRO LETTER OL;Lo;0;L;;;;;N;;;;;
+16A4E;MRO LETTER MAEM;Lo;0;L;;;;;N;;;;;
+16A4F;MRO LETTER NIN;Lo;0;L;;;;;N;;;;;
+16A50;MRO LETTER PA;Lo;0;L;;;;;N;;;;;
+16A51;MRO LETTER OO;Lo;0;L;;;;;N;;;;;
+16A52;MRO LETTER O;Lo;0;L;;;;;N;;;;;
+16A53;MRO LETTER RO;Lo;0;L;;;;;N;;;;;
+16A54;MRO LETTER SHI;Lo;0;L;;;;;N;;;;;
+16A55;MRO LETTER THEA;Lo;0;L;;;;;N;;;;;
+16A56;MRO LETTER EA;Lo;0;L;;;;;N;;;;;
+16A57;MRO LETTER WA;Lo;0;L;;;;;N;;;;;
+16A58;MRO LETTER E;Lo;0;L;;;;;N;;;;;
+16A59;MRO LETTER KO;Lo;0;L;;;;;N;;;;;
+16A5A;MRO LETTER LAN;Lo;0;L;;;;;N;;;;;
+16A5B;MRO LETTER LA;Lo;0;L;;;;;N;;;;;
+16A5C;MRO LETTER HAI;Lo;0;L;;;;;N;;;;;
+16A5D;MRO LETTER RI;Lo;0;L;;;;;N;;;;;
+16A5E;MRO LETTER TEK;Lo;0;L;;;;;N;;;;;
+16A60;MRO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+16A61;MRO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+16A62;MRO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+16A63;MRO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+16A64;MRO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+16A65;MRO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+16A66;MRO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+16A67;MRO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+16A68;MRO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+16A69;MRO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+16A6E;MRO DANDA;Po;0;L;;;;;N;;;;;
+16A6F;MRO DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+16AD0;BASSA VAH LETTER ENNI;Lo;0;L;;;;;N;;;;;
+16AD1;BASSA VAH LETTER KA;Lo;0;L;;;;;N;;;;;
+16AD2;BASSA VAH LETTER SE;Lo;0;L;;;;;N;;;;;
+16AD3;BASSA VAH LETTER FA;Lo;0;L;;;;;N;;;;;
+16AD4;BASSA VAH LETTER MBE;Lo;0;L;;;;;N;;;;;
+16AD5;BASSA VAH LETTER YIE;Lo;0;L;;;;;N;;;;;
+16AD6;BASSA VAH LETTER GAH;Lo;0;L;;;;;N;;;;;
+16AD7;BASSA VAH LETTER DHII;Lo;0;L;;;;;N;;;;;
+16AD8;BASSA VAH LETTER KPAH;Lo;0;L;;;;;N;;;;;
+16AD9;BASSA VAH LETTER JO;Lo;0;L;;;;;N;;;;;
+16ADA;BASSA VAH LETTER HWAH;Lo;0;L;;;;;N;;;;;
+16ADB;BASSA VAH LETTER WA;Lo;0;L;;;;;N;;;;;
+16ADC;BASSA VAH LETTER ZO;Lo;0;L;;;;;N;;;;;
+16ADD;BASSA VAH LETTER GBU;Lo;0;L;;;;;N;;;;;
+16ADE;BASSA VAH LETTER DO;Lo;0;L;;;;;N;;;;;
+16ADF;BASSA VAH LETTER CE;Lo;0;L;;;;;N;;;;;
+16AE0;BASSA VAH LETTER UWU;Lo;0;L;;;;;N;;;;;
+16AE1;BASSA VAH LETTER TO;Lo;0;L;;;;;N;;;;;
+16AE2;BASSA VAH LETTER BA;Lo;0;L;;;;;N;;;;;
+16AE3;BASSA VAH LETTER VU;Lo;0;L;;;;;N;;;;;
+16AE4;BASSA VAH LETTER YEIN;Lo;0;L;;;;;N;;;;;
+16AE5;BASSA VAH LETTER PA;Lo;0;L;;;;;N;;;;;
+16AE6;BASSA VAH LETTER WADDA;Lo;0;L;;;;;N;;;;;
+16AE7;BASSA VAH LETTER A;Lo;0;L;;;;;N;;;;;
+16AE8;BASSA VAH LETTER O;Lo;0;L;;;;;N;;;;;
+16AE9;BASSA VAH LETTER OO;Lo;0;L;;;;;N;;;;;
+16AEA;BASSA VAH LETTER U;Lo;0;L;;;;;N;;;;;
+16AEB;BASSA VAH LETTER EE;Lo;0;L;;;;;N;;;;;
+16AEC;BASSA VAH LETTER E;Lo;0;L;;;;;N;;;;;
+16AED;BASSA VAH LETTER I;Lo;0;L;;;;;N;;;;;
+16AF0;BASSA VAH COMBINING HIGH TONE;Mn;1;NSM;;;;;N;;;;;
+16AF1;BASSA VAH COMBINING LOW TONE;Mn;1;NSM;;;;;N;;;;;
+16AF2;BASSA VAH COMBINING MID TONE;Mn;1;NSM;;;;;N;;;;;
+16AF3;BASSA VAH COMBINING LOW-MID TONE;Mn;1;NSM;;;;;N;;;;;
+16AF4;BASSA VAH COMBINING HIGH-LOW TONE;Mn;1;NSM;;;;;N;;;;;
+16AF5;BASSA VAH FULL STOP;Po;0;L;;;;;N;;;;;
+16B00;PAHAWH HMONG VOWEL KEEB;Lo;0;L;;;;;N;;;;;
+16B01;PAHAWH HMONG VOWEL KEEV;Lo;0;L;;;;;N;;;;;
+16B02;PAHAWH HMONG VOWEL KIB;Lo;0;L;;;;;N;;;;;
+16B03;PAHAWH HMONG VOWEL KIV;Lo;0;L;;;;;N;;;;;
+16B04;PAHAWH HMONG VOWEL KAUB;Lo;0;L;;;;;N;;;;;
+16B05;PAHAWH HMONG VOWEL KAUV;Lo;0;L;;;;;N;;;;;
+16B06;PAHAWH HMONG VOWEL KUB;Lo;0;L;;;;;N;;;;;
+16B07;PAHAWH HMONG VOWEL KUV;Lo;0;L;;;;;N;;;;;
+16B08;PAHAWH HMONG VOWEL KEB;Lo;0;L;;;;;N;;;;;
+16B09;PAHAWH HMONG VOWEL KEV;Lo;0;L;;;;;N;;;;;
+16B0A;PAHAWH HMONG VOWEL KAIB;Lo;0;L;;;;;N;;;;;
+16B0B;PAHAWH HMONG VOWEL KAIV;Lo;0;L;;;;;N;;;;;
+16B0C;PAHAWH HMONG VOWEL KOOB;Lo;0;L;;;;;N;;;;;
+16B0D;PAHAWH HMONG VOWEL KOOV;Lo;0;L;;;;;N;;;;;
+16B0E;PAHAWH HMONG VOWEL KAWB;Lo;0;L;;;;;N;;;;;
+16B0F;PAHAWH HMONG VOWEL KAWV;Lo;0;L;;;;;N;;;;;
+16B10;PAHAWH HMONG VOWEL KUAB;Lo;0;L;;;;;N;;;;;
+16B11;PAHAWH HMONG VOWEL KUAV;Lo;0;L;;;;;N;;;;;
+16B12;PAHAWH HMONG VOWEL KOB;Lo;0;L;;;;;N;;;;;
+16B13;PAHAWH HMONG VOWEL KOV;Lo;0;L;;;;;N;;;;;
+16B14;PAHAWH HMONG VOWEL KIAB;Lo;0;L;;;;;N;;;;;
+16B15;PAHAWH HMONG VOWEL KIAV;Lo;0;L;;;;;N;;;;;
+16B16;PAHAWH HMONG VOWEL KAB;Lo;0;L;;;;;N;;;;;
+16B17;PAHAWH HMONG VOWEL KAV;Lo;0;L;;;;;N;;;;;
+16B18;PAHAWH HMONG VOWEL KWB;Lo;0;L;;;;;N;;;;;
+16B19;PAHAWH HMONG VOWEL KWV;Lo;0;L;;;;;N;;;;;
+16B1A;PAHAWH HMONG VOWEL KAAB;Lo;0;L;;;;;N;;;;;
+16B1B;PAHAWH HMONG VOWEL KAAV;Lo;0;L;;;;;N;;;;;
+16B1C;PAHAWH HMONG CONSONANT VAU;Lo;0;L;;;;;N;;;;;
+16B1D;PAHAWH HMONG CONSONANT NTSAU;Lo;0;L;;;;;N;;;;;
+16B1E;PAHAWH HMONG CONSONANT LAU;Lo;0;L;;;;;N;;;;;
+16B1F;PAHAWH HMONG CONSONANT HAU;Lo;0;L;;;;;N;;;;;
+16B20;PAHAWH HMONG CONSONANT NLAU;Lo;0;L;;;;;N;;;;;
+16B21;PAHAWH HMONG CONSONANT RAU;Lo;0;L;;;;;N;;;;;
+16B22;PAHAWH HMONG CONSONANT NKAU;Lo;0;L;;;;;N;;;;;
+16B23;PAHAWH HMONG CONSONANT QHAU;Lo;0;L;;;;;N;;;;;
+16B24;PAHAWH HMONG CONSONANT YAU;Lo;0;L;;;;;N;;;;;
+16B25;PAHAWH HMONG CONSONANT HLAU;Lo;0;L;;;;;N;;;;;
+16B26;PAHAWH HMONG CONSONANT MAU;Lo;0;L;;;;;N;;;;;
+16B27;PAHAWH HMONG CONSONANT CHAU;Lo;0;L;;;;;N;;;;;
+16B28;PAHAWH HMONG CONSONANT NCHAU;Lo;0;L;;;;;N;;;;;
+16B29;PAHAWH HMONG CONSONANT HNAU;Lo;0;L;;;;;N;;;;;
+16B2A;PAHAWH HMONG CONSONANT PLHAU;Lo;0;L;;;;;N;;;;;
+16B2B;PAHAWH HMONG CONSONANT NTHAU;Lo;0;L;;;;;N;;;;;
+16B2C;PAHAWH HMONG CONSONANT NAU;Lo;0;L;;;;;N;;;;;
+16B2D;PAHAWH HMONG CONSONANT AU;Lo;0;L;;;;;N;;;;;
+16B2E;PAHAWH HMONG CONSONANT XAU;Lo;0;L;;;;;N;;;;;
+16B2F;PAHAWH HMONG CONSONANT CAU;Lo;0;L;;;;;N;;;;;
+16B30;PAHAWH HMONG MARK CIM TUB;Mn;230;NSM;;;;;N;;;;;
+16B31;PAHAWH HMONG MARK CIM SO;Mn;230;NSM;;;;;N;;;;;
+16B32;PAHAWH HMONG MARK CIM KES;Mn;230;NSM;;;;;N;;;;;
+16B33;PAHAWH HMONG MARK CIM KHAV;Mn;230;NSM;;;;;N;;;;;
+16B34;PAHAWH HMONG MARK CIM SUAM;Mn;230;NSM;;;;;N;;;;;
+16B35;PAHAWH HMONG MARK CIM HOM;Mn;230;NSM;;;;;N;;;;;
+16B36;PAHAWH HMONG MARK CIM TAUM;Mn;230;NSM;;;;;N;;;;;
+16B37;PAHAWH HMONG SIGN VOS THOM;Po;0;L;;;;;N;;;;;
+16B38;PAHAWH HMONG SIGN VOS TSHAB CEEB;Po;0;L;;;;;N;;;;;
+16B39;PAHAWH HMONG SIGN CIM CHEEM;Po;0;L;;;;;N;;;;;
+16B3A;PAHAWH HMONG SIGN VOS THIAB;Po;0;L;;;;;N;;;;;
+16B3B;PAHAWH HMONG SIGN VOS FEEM;Po;0;L;;;;;N;;;;;
+16B3C;PAHAWH HMONG SIGN XYEEM NTXIV;So;0;L;;;;;N;;;;;
+16B3D;PAHAWH HMONG SIGN XYEEM RHO;So;0;L;;;;;N;;;;;
+16B3E;PAHAWH HMONG SIGN XYEEM TOV;So;0;L;;;;;N;;;;;
+16B3F;PAHAWH HMONG SIGN XYEEM FAIB;So;0;L;;;;;N;;;;;
+16B40;PAHAWH HMONG SIGN VOS SEEV;Lm;0;L;;;;;N;;;;;
+16B41;PAHAWH HMONG SIGN MEEJ SUAB;Lm;0;L;;;;;N;;;;;
+16B42;PAHAWH HMONG SIGN VOS NRUA;Lm;0;L;;;;;N;;;;;
+16B43;PAHAWH HMONG SIGN IB YAM;Lm;0;L;;;;;N;;;;;
+16B44;PAHAWH HMONG SIGN XAUS;Po;0;L;;;;;N;;;;;
+16B45;PAHAWH HMONG SIGN CIM TSOV ROG;So;0;L;;;;;N;;;;;
+16B50;PAHAWH HMONG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+16B51;PAHAWH HMONG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+16B52;PAHAWH HMONG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+16B53;PAHAWH HMONG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+16B54;PAHAWH HMONG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+16B55;PAHAWH HMONG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+16B56;PAHAWH HMONG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+16B57;PAHAWH HMONG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+16B58;PAHAWH HMONG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+16B59;PAHAWH HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+16B5B;PAHAWH HMONG NUMBER TENS;No;0;L;;;;10;N;;;;;
+16B5C;PAHAWH HMONG NUMBER HUNDREDS;No;0;L;;;;100;N;;;;;
+16B5D;PAHAWH HMONG NUMBER TEN THOUSANDS;No;0;L;;;;10000;N;;;;;
+16B5E;PAHAWH HMONG NUMBER MILLIONS;No;0;L;;;;1000000;N;;;;;
+16B5F;PAHAWH HMONG NUMBER HUNDRED MILLIONS;No;0;L;;;;100000000;N;;;;;
+16B60;PAHAWH HMONG NUMBER TEN BILLIONS;No;0;L;;;;10000000000;N;;;;;
+16B61;PAHAWH HMONG NUMBER TRILLIONS;No;0;L;;;;1000000000000;N;;;;;
+16B63;PAHAWH HMONG SIGN VOS LUB;Lo;0;L;;;;;N;;;;;
+16B64;PAHAWH HMONG SIGN XYOO;Lo;0;L;;;;;N;;;;;
+16B65;PAHAWH HMONG SIGN HLI;Lo;0;L;;;;;N;;;;;
+16B66;PAHAWH HMONG SIGN THIRD-STAGE HLI;Lo;0;L;;;;;N;;;;;
+16B67;PAHAWH HMONG SIGN ZWJ THAJ;Lo;0;L;;;;;N;;;;;
+16B68;PAHAWH HMONG SIGN HNUB;Lo;0;L;;;;;N;;;;;
+16B69;PAHAWH HMONG SIGN NQIG;Lo;0;L;;;;;N;;;;;
+16B6A;PAHAWH HMONG SIGN XIAB;Lo;0;L;;;;;N;;;;;
+16B6B;PAHAWH HMONG SIGN NTUJ;Lo;0;L;;;;;N;;;;;
+16B6C;PAHAWH HMONG SIGN AV;Lo;0;L;;;;;N;;;;;
+16B6D;PAHAWH HMONG SIGN TXHEEJ CEEV;Lo;0;L;;;;;N;;;;;
+16B6E;PAHAWH HMONG SIGN MEEJ TSEEB;Lo;0;L;;;;;N;;;;;
+16B6F;PAHAWH HMONG SIGN TAU;Lo;0;L;;;;;N;;;;;
+16B70;PAHAWH HMONG SIGN LOS;Lo;0;L;;;;;N;;;;;
+16B71;PAHAWH HMONG SIGN MUS;Lo;0;L;;;;;N;;;;;
+16B72;PAHAWH HMONG SIGN CIM HAIS LUS NTOG NTOG;Lo;0;L;;;;;N;;;;;
+16B73;PAHAWH HMONG SIGN CIM CUAM TSHOOJ;Lo;0;L;;;;;N;;;;;
+16B74;PAHAWH HMONG SIGN CIM TXWV;Lo;0;L;;;;;N;;;;;
+16B75;PAHAWH HMONG SIGN CIM TXWV CHWV;Lo;0;L;;;;;N;;;;;
+16B76;PAHAWH HMONG SIGN CIM PUB DAWB;Lo;0;L;;;;;N;;;;;
+16B77;PAHAWH HMONG SIGN CIM NRES TOS;Lo;0;L;;;;;N;;;;;
+16B7D;PAHAWH HMONG CLAN SIGN TSHEEJ;Lo;0;L;;;;;N;;;;;
+16B7E;PAHAWH HMONG CLAN SIGN YEEG;Lo;0;L;;;;;N;;;;;
+16B7F;PAHAWH HMONG CLAN SIGN LIS;Lo;0;L;;;;;N;;;;;
+16B80;PAHAWH HMONG CLAN SIGN LAUJ;Lo;0;L;;;;;N;;;;;
+16B81;PAHAWH HMONG CLAN SIGN XYOOJ;Lo;0;L;;;;;N;;;;;
+16B82;PAHAWH HMONG CLAN SIGN KOO;Lo;0;L;;;;;N;;;;;
+16B83;PAHAWH HMONG CLAN SIGN HAWJ;Lo;0;L;;;;;N;;;;;
+16B84;PAHAWH HMONG CLAN SIGN MUAS;Lo;0;L;;;;;N;;;;;
+16B85;PAHAWH HMONG CLAN SIGN THOJ;Lo;0;L;;;;;N;;;;;
+16B86;PAHAWH HMONG CLAN SIGN TSAB;Lo;0;L;;;;;N;;;;;
+16B87;PAHAWH HMONG CLAN SIGN PHAB;Lo;0;L;;;;;N;;;;;
+16B88;PAHAWH HMONG CLAN SIGN KHAB;Lo;0;L;;;;;N;;;;;
+16B89;PAHAWH HMONG CLAN SIGN HAM;Lo;0;L;;;;;N;;;;;
+16B8A;PAHAWH HMONG CLAN SIGN VAJ;Lo;0;L;;;;;N;;;;;
+16B8B;PAHAWH HMONG CLAN SIGN FAJ;Lo;0;L;;;;;N;;;;;
+16B8C;PAHAWH HMONG CLAN SIGN YAJ;Lo;0;L;;;;;N;;;;;
+16B8D;PAHAWH HMONG CLAN SIGN TSWB;Lo;0;L;;;;;N;;;;;
+16B8E;PAHAWH HMONG CLAN SIGN KWM;Lo;0;L;;;;;N;;;;;
+16B8F;PAHAWH HMONG CLAN SIGN VWJ;Lo;0;L;;;;;N;;;;;
+16F00;MIAO LETTER PA;Lo;0;L;;;;;N;;;;;
+16F01;MIAO LETTER BA;Lo;0;L;;;;;N;;;;;
+16F02;MIAO LETTER YI PA;Lo;0;L;;;;;N;;;;;
+16F03;MIAO LETTER PLA;Lo;0;L;;;;;N;;;;;
+16F04;MIAO LETTER MA;Lo;0;L;;;;;N;;;;;
+16F05;MIAO LETTER MHA;Lo;0;L;;;;;N;;;;;
+16F06;MIAO LETTER ARCHAIC MA;Lo;0;L;;;;;N;;;;;
+16F07;MIAO LETTER FA;Lo;0;L;;;;;N;;;;;
+16F08;MIAO LETTER VA;Lo;0;L;;;;;N;;;;;
+16F09;MIAO LETTER VFA;Lo;0;L;;;;;N;;;;;
+16F0A;MIAO LETTER TA;Lo;0;L;;;;;N;;;;;
+16F0B;MIAO LETTER DA;Lo;0;L;;;;;N;;;;;
+16F0C;MIAO LETTER YI TTA;Lo;0;L;;;;;N;;;;;
+16F0D;MIAO LETTER YI TA;Lo;0;L;;;;;N;;;;;
+16F0E;MIAO LETTER TTA;Lo;0;L;;;;;N;;;;;
+16F0F;MIAO LETTER DDA;Lo;0;L;;;;;N;;;;;
+16F10;MIAO LETTER NA;Lo;0;L;;;;;N;;;;;
+16F11;MIAO LETTER NHA;Lo;0;L;;;;;N;;;;;
+16F12;MIAO LETTER YI NNA;Lo;0;L;;;;;N;;;;;
+16F13;MIAO LETTER ARCHAIC NA;Lo;0;L;;;;;N;;;;;
+16F14;MIAO LETTER NNA;Lo;0;L;;;;;N;;;;;
+16F15;MIAO LETTER NNHA;Lo;0;L;;;;;N;;;;;
+16F16;MIAO LETTER LA;Lo;0;L;;;;;N;;;;;
+16F17;MIAO LETTER LYA;Lo;0;L;;;;;N;;;;;
+16F18;MIAO LETTER LHA;Lo;0;L;;;;;N;;;;;
+16F19;MIAO LETTER LHYA;Lo;0;L;;;;;N;;;;;
+16F1A;MIAO LETTER TLHA;Lo;0;L;;;;;N;;;;;
+16F1B;MIAO LETTER DLHA;Lo;0;L;;;;;N;;;;;
+16F1C;MIAO LETTER TLHYA;Lo;0;L;;;;;N;;;;;
+16F1D;MIAO LETTER DLHYA;Lo;0;L;;;;;N;;;;;
+16F1E;MIAO LETTER KA;Lo;0;L;;;;;N;;;;;
+16F1F;MIAO LETTER GA;Lo;0;L;;;;;N;;;;;
+16F20;MIAO LETTER YI KA;Lo;0;L;;;;;N;;;;;
+16F21;MIAO LETTER QA;Lo;0;L;;;;;N;;;;;
+16F22;MIAO LETTER QGA;Lo;0;L;;;;;N;;;;;
+16F23;MIAO LETTER NGA;Lo;0;L;;;;;N;;;;;
+16F24;MIAO LETTER NGHA;Lo;0;L;;;;;N;;;;;
+16F25;MIAO LETTER ARCHAIC NGA;Lo;0;L;;;;;N;;;;;
+16F26;MIAO LETTER HA;Lo;0;L;;;;;N;;;;;
+16F27;MIAO LETTER XA;Lo;0;L;;;;;N;;;;;
+16F28;MIAO LETTER GHA;Lo;0;L;;;;;N;;;;;
+16F29;MIAO LETTER GHHA;Lo;0;L;;;;;N;;;;;
+16F2A;MIAO LETTER TSSA;Lo;0;L;;;;;N;;;;;
+16F2B;MIAO LETTER DZZA;Lo;0;L;;;;;N;;;;;
+16F2C;MIAO LETTER NYA;Lo;0;L;;;;;N;;;;;
+16F2D;MIAO LETTER NYHA;Lo;0;L;;;;;N;;;;;
+16F2E;MIAO LETTER TSHA;Lo;0;L;;;;;N;;;;;
+16F2F;MIAO LETTER DZHA;Lo;0;L;;;;;N;;;;;
+16F30;MIAO LETTER YI TSHA;Lo;0;L;;;;;N;;;;;
+16F31;MIAO LETTER YI DZHA;Lo;0;L;;;;;N;;;;;
+16F32;MIAO LETTER REFORMED TSHA;Lo;0;L;;;;;N;;;;;
+16F33;MIAO LETTER SHA;Lo;0;L;;;;;N;;;;;
+16F34;MIAO LETTER SSA;Lo;0;L;;;;;N;;;;;
+16F35;MIAO LETTER ZHA;Lo;0;L;;;;;N;;;;;
+16F36;MIAO LETTER ZSHA;Lo;0;L;;;;;N;;;;;
+16F37;MIAO LETTER TSA;Lo;0;L;;;;;N;;;;;
+16F38;MIAO LETTER DZA;Lo;0;L;;;;;N;;;;;
+16F39;MIAO LETTER YI TSA;Lo;0;L;;;;;N;;;;;
+16F3A;MIAO LETTER SA;Lo;0;L;;;;;N;;;;;
+16F3B;MIAO LETTER ZA;Lo;0;L;;;;;N;;;;;
+16F3C;MIAO LETTER ZSA;Lo;0;L;;;;;N;;;;;
+16F3D;MIAO LETTER ZZA;Lo;0;L;;;;;N;;;;;
+16F3E;MIAO LETTER ZZSA;Lo;0;L;;;;;N;;;;;
+16F3F;MIAO LETTER ARCHAIC ZZA;Lo;0;L;;;;;N;;;;;
+16F40;MIAO LETTER ZZYA;Lo;0;L;;;;;N;;;;;
+16F41;MIAO LETTER ZZSYA;Lo;0;L;;;;;N;;;;;
+16F42;MIAO LETTER WA;Lo;0;L;;;;;N;;;;;
+16F43;MIAO LETTER AH;Lo;0;L;;;;;N;;;;;
+16F44;MIAO LETTER HHA;Lo;0;L;;;;;N;;;;;
+16F50;MIAO LETTER NASALIZATION;Lo;0;L;;;;;N;;;;;
+16F51;MIAO SIGN ASPIRATION;Mc;0;L;;;;;N;;;;;
+16F52;MIAO SIGN REFORMED VOICING;Mc;0;L;;;;;N;;;;;
+16F53;MIAO SIGN REFORMED ASPIRATION;Mc;0;L;;;;;N;;;;;
+16F54;MIAO VOWEL SIGN A;Mc;0;L;;;;;N;;;;;
+16F55;MIAO VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+16F56;MIAO VOWEL SIGN AHH;Mc;0;L;;;;;N;;;;;
+16F57;MIAO VOWEL SIGN AN;Mc;0;L;;;;;N;;;;;
+16F58;MIAO VOWEL SIGN ANG;Mc;0;L;;;;;N;;;;;
+16F59;MIAO VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+16F5A;MIAO VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
+16F5B;MIAO VOWEL SIGN WO;Mc;0;L;;;;;N;;;;;
+16F5C;MIAO VOWEL SIGN W;Mc;0;L;;;;;N;;;;;
+16F5D;MIAO VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+16F5E;MIAO VOWEL SIGN EN;Mc;0;L;;;;;N;;;;;
+16F5F;MIAO VOWEL SIGN ENG;Mc;0;L;;;;;N;;;;;
+16F60;MIAO VOWEL SIGN OEY;Mc;0;L;;;;;N;;;;;
+16F61;MIAO VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+16F62;MIAO VOWEL SIGN IA;Mc;0;L;;;;;N;;;;;
+16F63;MIAO VOWEL SIGN IAN;Mc;0;L;;;;;N;;;;;
+16F64;MIAO VOWEL SIGN IANG;Mc;0;L;;;;;N;;;;;
+16F65;MIAO VOWEL SIGN IO;Mc;0;L;;;;;N;;;;;
+16F66;MIAO VOWEL SIGN IE;Mc;0;L;;;;;N;;;;;
+16F67;MIAO VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+16F68;MIAO VOWEL SIGN IU;Mc;0;L;;;;;N;;;;;
+16F69;MIAO VOWEL SIGN ING;Mc;0;L;;;;;N;;;;;
+16F6A;MIAO VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
+16F6B;MIAO VOWEL SIGN UA;Mc;0;L;;;;;N;;;;;
+16F6C;MIAO VOWEL SIGN UAN;Mc;0;L;;;;;N;;;;;
+16F6D;MIAO VOWEL SIGN UANG;Mc;0;L;;;;;N;;;;;
+16F6E;MIAO VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
+16F6F;MIAO VOWEL SIGN UEI;Mc;0;L;;;;;N;;;;;
+16F70;MIAO VOWEL SIGN UNG;Mc;0;L;;;;;N;;;;;
+16F71;MIAO VOWEL SIGN Y;Mc;0;L;;;;;N;;;;;
+16F72;MIAO VOWEL SIGN YI;Mc;0;L;;;;;N;;;;;
+16F73;MIAO VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
+16F74;MIAO VOWEL SIGN AEE;Mc;0;L;;;;;N;;;;;
+16F75;MIAO VOWEL SIGN ERR;Mc;0;L;;;;;N;;;;;
+16F76;MIAO VOWEL SIGN ROUNDED ERR;Mc;0;L;;;;;N;;;;;
+16F77;MIAO VOWEL SIGN ER;Mc;0;L;;;;;N;;;;;
+16F78;MIAO VOWEL SIGN ROUNDED ER;Mc;0;L;;;;;N;;;;;
+16F79;MIAO VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+16F7A;MIAO VOWEL SIGN EI;Mc;0;L;;;;;N;;;;;
+16F7B;MIAO VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+16F7C;MIAO VOWEL SIGN OU;Mc;0;L;;;;;N;;;;;
+16F7D;MIAO VOWEL SIGN N;Mc;0;L;;;;;N;;;;;
+16F7E;MIAO VOWEL SIGN NG;Mc;0;L;;;;;N;;;;;
+16F8F;MIAO TONE RIGHT;Mn;0;NSM;;;;;N;;;;;
+16F90;MIAO TONE TOP RIGHT;Mn;0;NSM;;;;;N;;;;;
+16F91;MIAO TONE ABOVE;Mn;0;NSM;;;;;N;;;;;
+16F92;MIAO TONE BELOW;Mn;0;NSM;;;;;N;;;;;
+16F93;MIAO LETTER TONE-2;Lm;0;L;;;;;N;;;;;
+16F94;MIAO LETTER TONE-3;Lm;0;L;;;;;N;;;;;
+16F95;MIAO LETTER TONE-4;Lm;0;L;;;;;N;;;;;
+16F96;MIAO LETTER TONE-5;Lm;0;L;;;;;N;;;;;
+16F97;MIAO LETTER TONE-6;Lm;0;L;;;;;N;;;;;
+16F98;MIAO LETTER TONE-7;Lm;0;L;;;;;N;;;;;
+16F99;MIAO LETTER TONE-8;Lm;0;L;;;;;N;;;;;
+16F9A;MIAO LETTER REFORMED TONE-1;Lm;0;L;;;;;N;;;;;
+16F9B;MIAO LETTER REFORMED TONE-2;Lm;0;L;;;;;N;;;;;
+16F9C;MIAO LETTER REFORMED TONE-4;Lm;0;L;;;;;N;;;;;
+16F9D;MIAO LETTER REFORMED TONE-5;Lm;0;L;;;;;N;;;;;
+16F9E;MIAO LETTER REFORMED TONE-6;Lm;0;L;;;;;N;;;;;
+16F9F;MIAO LETTER REFORMED TONE-8;Lm;0;L;;;;;N;;;;;
+16FE0;TANGUT ITERATION MARK;Lm;0;L;;;;;N;;;;;
+17000;<Tangut Ideograph, First>;Lo;0;L;;;;;N;;;;;
+187EC;<Tangut Ideograph, Last>;Lo;0;L;;;;;N;;;;;
+18800;TANGUT COMPONENT-001;Lo;0;L;;;;;N;;;;;
+18801;TANGUT COMPONENT-002;Lo;0;L;;;;;N;;;;;
+18802;TANGUT COMPONENT-003;Lo;0;L;;;;;N;;;;;
+18803;TANGUT COMPONENT-004;Lo;0;L;;;;;N;;;;;
+18804;TANGUT COMPONENT-005;Lo;0;L;;;;;N;;;;;
+18805;TANGUT COMPONENT-006;Lo;0;L;;;;;N;;;;;
+18806;TANGUT COMPONENT-007;Lo;0;L;;;;;N;;;;;
+18807;TANGUT COMPONENT-008;Lo;0;L;;;;;N;;;;;
+18808;TANGUT COMPONENT-009;Lo;0;L;;;;;N;;;;;
+18809;TANGUT COMPONENT-010;Lo;0;L;;;;;N;;;;;
+1880A;TANGUT COMPONENT-011;Lo;0;L;;;;;N;;;;;
+1880B;TANGUT COMPONENT-012;Lo;0;L;;;;;N;;;;;
+1880C;TANGUT COMPONENT-013;Lo;0;L;;;;;N;;;;;
+1880D;TANGUT COMPONENT-014;Lo;0;L;;;;;N;;;;;
+1880E;TANGUT COMPONENT-015;Lo;0;L;;;;;N;;;;;
+1880F;TANGUT COMPONENT-016;Lo;0;L;;;;;N;;;;;
+18810;TANGUT COMPONENT-017;Lo;0;L;;;;;N;;;;;
+18811;TANGUT COMPONENT-018;Lo;0;L;;;;;N;;;;;
+18812;TANGUT COMPONENT-019;Lo;0;L;;;;;N;;;;;
+18813;TANGUT COMPONENT-020;Lo;0;L;;;;;N;;;;;
+18814;TANGUT COMPONENT-021;Lo;0;L;;;;;N;;;;;
+18815;TANGUT COMPONENT-022;Lo;0;L;;;;;N;;;;;
+18816;TANGUT COMPONENT-023;Lo;0;L;;;;;N;;;;;
+18817;TANGUT COMPONENT-024;Lo;0;L;;;;;N;;;;;
+18818;TANGUT COMPONENT-025;Lo;0;L;;;;;N;;;;;
+18819;TANGUT COMPONENT-026;Lo;0;L;;;;;N;;;;;
+1881A;TANGUT COMPONENT-027;Lo;0;L;;;;;N;;;;;
+1881B;TANGUT COMPONENT-028;Lo;0;L;;;;;N;;;;;
+1881C;TANGUT COMPONENT-029;Lo;0;L;;;;;N;;;;;
+1881D;TANGUT COMPONENT-030;Lo;0;L;;;;;N;;;;;
+1881E;TANGUT COMPONENT-031;Lo;0;L;;;;;N;;;;;
+1881F;TANGUT COMPONENT-032;Lo;0;L;;;;;N;;;;;
+18820;TANGUT COMPONENT-033;Lo;0;L;;;;;N;;;;;
+18821;TANGUT COMPONENT-034;Lo;0;L;;;;;N;;;;;
+18822;TANGUT COMPONENT-035;Lo;0;L;;;;;N;;;;;
+18823;TANGUT COMPONENT-036;Lo;0;L;;;;;N;;;;;
+18824;TANGUT COMPONENT-037;Lo;0;L;;;;;N;;;;;
+18825;TANGUT COMPONENT-038;Lo;0;L;;;;;N;;;;;
+18826;TANGUT COMPONENT-039;Lo;0;L;;;;;N;;;;;
+18827;TANGUT COMPONENT-040;Lo;0;L;;;;;N;;;;;
+18828;TANGUT COMPONENT-041;Lo;0;L;;;;;N;;;;;
+18829;TANGUT COMPONENT-042;Lo;0;L;;;;;N;;;;;
+1882A;TANGUT COMPONENT-043;Lo;0;L;;;;;N;;;;;
+1882B;TANGUT COMPONENT-044;Lo;0;L;;;;;N;;;;;
+1882C;TANGUT COMPONENT-045;Lo;0;L;;;;;N;;;;;
+1882D;TANGUT COMPONENT-046;Lo;0;L;;;;;N;;;;;
+1882E;TANGUT COMPONENT-047;Lo;0;L;;;;;N;;;;;
+1882F;TANGUT COMPONENT-048;Lo;0;L;;;;;N;;;;;
+18830;TANGUT COMPONENT-049;Lo;0;L;;;;;N;;;;;
+18831;TANGUT COMPONENT-050;Lo;0;L;;;;;N;;;;;
+18832;TANGUT COMPONENT-051;Lo;0;L;;;;;N;;;;;
+18833;TANGUT COMPONENT-052;Lo;0;L;;;;;N;;;;;
+18834;TANGUT COMPONENT-053;Lo;0;L;;;;;N;;;;;
+18835;TANGUT COMPONENT-054;Lo;0;L;;;;;N;;;;;
+18836;TANGUT COMPONENT-055;Lo;0;L;;;;;N;;;;;
+18837;TANGUT COMPONENT-056;Lo;0;L;;;;;N;;;;;
+18838;TANGUT COMPONENT-057;Lo;0;L;;;;;N;;;;;
+18839;TANGUT COMPONENT-058;Lo;0;L;;;;;N;;;;;
+1883A;TANGUT COMPONENT-059;Lo;0;L;;;;;N;;;;;
+1883B;TANGUT COMPONENT-060;Lo;0;L;;;;;N;;;;;
+1883C;TANGUT COMPONENT-061;Lo;0;L;;;;;N;;;;;
+1883D;TANGUT COMPONENT-062;Lo;0;L;;;;;N;;;;;
+1883E;TANGUT COMPONENT-063;Lo;0;L;;;;;N;;;;;
+1883F;TANGUT COMPONENT-064;Lo;0;L;;;;;N;;;;;
+18840;TANGUT COMPONENT-065;Lo;0;L;;;;;N;;;;;
+18841;TANGUT COMPONENT-066;Lo;0;L;;;;;N;;;;;
+18842;TANGUT COMPONENT-067;Lo;0;L;;;;;N;;;;;
+18843;TANGUT COMPONENT-068;Lo;0;L;;;;;N;;;;;
+18844;TANGUT COMPONENT-069;Lo;0;L;;;;;N;;;;;
+18845;TANGUT COMPONENT-070;Lo;0;L;;;;;N;;;;;
+18846;TANGUT COMPONENT-071;Lo;0;L;;;;;N;;;;;
+18847;TANGUT COMPONENT-072;Lo;0;L;;;;;N;;;;;
+18848;TANGUT COMPONENT-073;Lo;0;L;;;;;N;;;;;
+18849;TANGUT COMPONENT-074;Lo;0;L;;;;;N;;;;;
+1884A;TANGUT COMPONENT-075;Lo;0;L;;;;;N;;;;;
+1884B;TANGUT COMPONENT-076;Lo;0;L;;;;;N;;;;;
+1884C;TANGUT COMPONENT-077;Lo;0;L;;;;;N;;;;;
+1884D;TANGUT COMPONENT-078;Lo;0;L;;;;;N;;;;;
+1884E;TANGUT COMPONENT-079;Lo;0;L;;;;;N;;;;;
+1884F;TANGUT COMPONENT-080;Lo;0;L;;;;;N;;;;;
+18850;TANGUT COMPONENT-081;Lo;0;L;;;;;N;;;;;
+18851;TANGUT COMPONENT-082;Lo;0;L;;;;;N;;;;;
+18852;TANGUT COMPONENT-083;Lo;0;L;;;;;N;;;;;
+18853;TANGUT COMPONENT-084;Lo;0;L;;;;;N;;;;;
+18854;TANGUT COMPONENT-085;Lo;0;L;;;;;N;;;;;
+18855;TANGUT COMPONENT-086;Lo;0;L;;;;;N;;;;;
+18856;TANGUT COMPONENT-087;Lo;0;L;;;;;N;;;;;
+18857;TANGUT COMPONENT-088;Lo;0;L;;;;;N;;;;;
+18858;TANGUT COMPONENT-089;Lo;0;L;;;;;N;;;;;
+18859;TANGUT COMPONENT-090;Lo;0;L;;;;;N;;;;;
+1885A;TANGUT COMPONENT-091;Lo;0;L;;;;;N;;;;;
+1885B;TANGUT COMPONENT-092;Lo;0;L;;;;;N;;;;;
+1885C;TANGUT COMPONENT-093;Lo;0;L;;;;;N;;;;;
+1885D;TANGUT COMPONENT-094;Lo;0;L;;;;;N;;;;;
+1885E;TANGUT COMPONENT-095;Lo;0;L;;;;;N;;;;;
+1885F;TANGUT COMPONENT-096;Lo;0;L;;;;;N;;;;;
+18860;TANGUT COMPONENT-097;Lo;0;L;;;;;N;;;;;
+18861;TANGUT COMPONENT-098;Lo;0;L;;;;;N;;;;;
+18862;TANGUT COMPONENT-099;Lo;0;L;;;;;N;;;;;
+18863;TANGUT COMPONENT-100;Lo;0;L;;;;;N;;;;;
+18864;TANGUT COMPONENT-101;Lo;0;L;;;;;N;;;;;
+18865;TANGUT COMPONENT-102;Lo;0;L;;;;;N;;;;;
+18866;TANGUT COMPONENT-103;Lo;0;L;;;;;N;;;;;
+18867;TANGUT COMPONENT-104;Lo;0;L;;;;;N;;;;;
+18868;TANGUT COMPONENT-105;Lo;0;L;;;;;N;;;;;
+18869;TANGUT COMPONENT-106;Lo;0;L;;;;;N;;;;;
+1886A;TANGUT COMPONENT-107;Lo;0;L;;;;;N;;;;;
+1886B;TANGUT COMPONENT-108;Lo;0;L;;;;;N;;;;;
+1886C;TANGUT COMPONENT-109;Lo;0;L;;;;;N;;;;;
+1886D;TANGUT COMPONENT-110;Lo;0;L;;;;;N;;;;;
+1886E;TANGUT COMPONENT-111;Lo;0;L;;;;;N;;;;;
+1886F;TANGUT COMPONENT-112;Lo;0;L;;;;;N;;;;;
+18870;TANGUT COMPONENT-113;Lo;0;L;;;;;N;;;;;
+18871;TANGUT COMPONENT-114;Lo;0;L;;;;;N;;;;;
+18872;TANGUT COMPONENT-115;Lo;0;L;;;;;N;;;;;
+18873;TANGUT COMPONENT-116;Lo;0;L;;;;;N;;;;;
+18874;TANGUT COMPONENT-117;Lo;0;L;;;;;N;;;;;
+18875;TANGUT COMPONENT-118;Lo;0;L;;;;;N;;;;;
+18876;TANGUT COMPONENT-119;Lo;0;L;;;;;N;;;;;
+18877;TANGUT COMPONENT-120;Lo;0;L;;;;;N;;;;;
+18878;TANGUT COMPONENT-121;Lo;0;L;;;;;N;;;;;
+18879;TANGUT COMPONENT-122;Lo;0;L;;;;;N;;;;;
+1887A;TANGUT COMPONENT-123;Lo;0;L;;;;;N;;;;;
+1887B;TANGUT COMPONENT-124;Lo;0;L;;;;;N;;;;;
+1887C;TANGUT COMPONENT-125;Lo;0;L;;;;;N;;;;;
+1887D;TANGUT COMPONENT-126;Lo;0;L;;;;;N;;;;;
+1887E;TANGUT COMPONENT-127;Lo;0;L;;;;;N;;;;;
+1887F;TANGUT COMPONENT-128;Lo;0;L;;;;;N;;;;;
+18880;TANGUT COMPONENT-129;Lo;0;L;;;;;N;;;;;
+18881;TANGUT COMPONENT-130;Lo;0;L;;;;;N;;;;;
+18882;TANGUT COMPONENT-131;Lo;0;L;;;;;N;;;;;
+18883;TANGUT COMPONENT-132;Lo;0;L;;;;;N;;;;;
+18884;TANGUT COMPONENT-133;Lo;0;L;;;;;N;;;;;
+18885;TANGUT COMPONENT-134;Lo;0;L;;;;;N;;;;;
+18886;TANGUT COMPONENT-135;Lo;0;L;;;;;N;;;;;
+18887;TANGUT COMPONENT-136;Lo;0;L;;;;;N;;;;;
+18888;TANGUT COMPONENT-137;Lo;0;L;;;;;N;;;;;
+18889;TANGUT COMPONENT-138;Lo;0;L;;;;;N;;;;;
+1888A;TANGUT COMPONENT-139;Lo;0;L;;;;;N;;;;;
+1888B;TANGUT COMPONENT-140;Lo;0;L;;;;;N;;;;;
+1888C;TANGUT COMPONENT-141;Lo;0;L;;;;;N;;;;;
+1888D;TANGUT COMPONENT-142;Lo;0;L;;;;;N;;;;;
+1888E;TANGUT COMPONENT-143;Lo;0;L;;;;;N;;;;;
+1888F;TANGUT COMPONENT-144;Lo;0;L;;;;;N;;;;;
+18890;TANGUT COMPONENT-145;Lo;0;L;;;;;N;;;;;
+18891;TANGUT COMPONENT-146;Lo;0;L;;;;;N;;;;;
+18892;TANGUT COMPONENT-147;Lo;0;L;;;;;N;;;;;
+18893;TANGUT COMPONENT-148;Lo;0;L;;;;;N;;;;;
+18894;TANGUT COMPONENT-149;Lo;0;L;;;;;N;;;;;
+18895;TANGUT COMPONENT-150;Lo;0;L;;;;;N;;;;;
+18896;TANGUT COMPONENT-151;Lo;0;L;;;;;N;;;;;
+18897;TANGUT COMPONENT-152;Lo;0;L;;;;;N;;;;;
+18898;TANGUT COMPONENT-153;Lo;0;L;;;;;N;;;;;
+18899;TANGUT COMPONENT-154;Lo;0;L;;;;;N;;;;;
+1889A;TANGUT COMPONENT-155;Lo;0;L;;;;;N;;;;;
+1889B;TANGUT COMPONENT-156;Lo;0;L;;;;;N;;;;;
+1889C;TANGUT COMPONENT-157;Lo;0;L;;;;;N;;;;;
+1889D;TANGUT COMPONENT-158;Lo;0;L;;;;;N;;;;;
+1889E;TANGUT COMPONENT-159;Lo;0;L;;;;;N;;;;;
+1889F;TANGUT COMPONENT-160;Lo;0;L;;;;;N;;;;;
+188A0;TANGUT COMPONENT-161;Lo;0;L;;;;;N;;;;;
+188A1;TANGUT COMPONENT-162;Lo;0;L;;;;;N;;;;;
+188A2;TANGUT COMPONENT-163;Lo;0;L;;;;;N;;;;;
+188A3;TANGUT COMPONENT-164;Lo;0;L;;;;;N;;;;;
+188A4;TANGUT COMPONENT-165;Lo;0;L;;;;;N;;;;;
+188A5;TANGUT COMPONENT-166;Lo;0;L;;;;;N;;;;;
+188A6;TANGUT COMPONENT-167;Lo;0;L;;;;;N;;;;;
+188A7;TANGUT COMPONENT-168;Lo;0;L;;;;;N;;;;;
+188A8;TANGUT COMPONENT-169;Lo;0;L;;;;;N;;;;;
+188A9;TANGUT COMPONENT-170;Lo;0;L;;;;;N;;;;;
+188AA;TANGUT COMPONENT-171;Lo;0;L;;;;;N;;;;;
+188AB;TANGUT COMPONENT-172;Lo;0;L;;;;;N;;;;;
+188AC;TANGUT COMPONENT-173;Lo;0;L;;;;;N;;;;;
+188AD;TANGUT COMPONENT-174;Lo;0;L;;;;;N;;;;;
+188AE;TANGUT COMPONENT-175;Lo;0;L;;;;;N;;;;;
+188AF;TANGUT COMPONENT-176;Lo;0;L;;;;;N;;;;;
+188B0;TANGUT COMPONENT-177;Lo;0;L;;;;;N;;;;;
+188B1;TANGUT COMPONENT-178;Lo;0;L;;;;;N;;;;;
+188B2;TANGUT COMPONENT-179;Lo;0;L;;;;;N;;;;;
+188B3;TANGUT COMPONENT-180;Lo;0;L;;;;;N;;;;;
+188B4;TANGUT COMPONENT-181;Lo;0;L;;;;;N;;;;;
+188B5;TANGUT COMPONENT-182;Lo;0;L;;;;;N;;;;;
+188B6;TANGUT COMPONENT-183;Lo;0;L;;;;;N;;;;;
+188B7;TANGUT COMPONENT-184;Lo;0;L;;;;;N;;;;;
+188B8;TANGUT COMPONENT-185;Lo;0;L;;;;;N;;;;;
+188B9;TANGUT COMPONENT-186;Lo;0;L;;;;;N;;;;;
+188BA;TANGUT COMPONENT-187;Lo;0;L;;;;;N;;;;;
+188BB;TANGUT COMPONENT-188;Lo;0;L;;;;;N;;;;;
+188BC;TANGUT COMPONENT-189;Lo;0;L;;;;;N;;;;;
+188BD;TANGUT COMPONENT-190;Lo;0;L;;;;;N;;;;;
+188BE;TANGUT COMPONENT-191;Lo;0;L;;;;;N;;;;;
+188BF;TANGUT COMPONENT-192;Lo;0;L;;;;;N;;;;;
+188C0;TANGUT COMPONENT-193;Lo;0;L;;;;;N;;;;;
+188C1;TANGUT COMPONENT-194;Lo;0;L;;;;;N;;;;;
+188C2;TANGUT COMPONENT-195;Lo;0;L;;;;;N;;;;;
+188C3;TANGUT COMPONENT-196;Lo;0;L;;;;;N;;;;;
+188C4;TANGUT COMPONENT-197;Lo;0;L;;;;;N;;;;;
+188C5;TANGUT COMPONENT-198;Lo;0;L;;;;;N;;;;;
+188C6;TANGUT COMPONENT-199;Lo;0;L;;;;;N;;;;;
+188C7;TANGUT COMPONENT-200;Lo;0;L;;;;;N;;;;;
+188C8;TANGUT COMPONENT-201;Lo;0;L;;;;;N;;;;;
+188C9;TANGUT COMPONENT-202;Lo;0;L;;;;;N;;;;;
+188CA;TANGUT COMPONENT-203;Lo;0;L;;;;;N;;;;;
+188CB;TANGUT COMPONENT-204;Lo;0;L;;;;;N;;;;;
+188CC;TANGUT COMPONENT-205;Lo;0;L;;;;;N;;;;;
+188CD;TANGUT COMPONENT-206;Lo;0;L;;;;;N;;;;;
+188CE;TANGUT COMPONENT-207;Lo;0;L;;;;;N;;;;;
+188CF;TANGUT COMPONENT-208;Lo;0;L;;;;;N;;;;;
+188D0;TANGUT COMPONENT-209;Lo;0;L;;;;;N;;;;;
+188D1;TANGUT COMPONENT-210;Lo;0;L;;;;;N;;;;;
+188D2;TANGUT COMPONENT-211;Lo;0;L;;;;;N;;;;;
+188D3;TANGUT COMPONENT-212;Lo;0;L;;;;;N;;;;;
+188D4;TANGUT COMPONENT-213;Lo;0;L;;;;;N;;;;;
+188D5;TANGUT COMPONENT-214;Lo;0;L;;;;;N;;;;;
+188D6;TANGUT COMPONENT-215;Lo;0;L;;;;;N;;;;;
+188D7;TANGUT COMPONENT-216;Lo;0;L;;;;;N;;;;;
+188D8;TANGUT COMPONENT-217;Lo;0;L;;;;;N;;;;;
+188D9;TANGUT COMPONENT-218;Lo;0;L;;;;;N;;;;;
+188DA;TANGUT COMPONENT-219;Lo;0;L;;;;;N;;;;;
+188DB;TANGUT COMPONENT-220;Lo;0;L;;;;;N;;;;;
+188DC;TANGUT COMPONENT-221;Lo;0;L;;;;;N;;;;;
+188DD;TANGUT COMPONENT-222;Lo;0;L;;;;;N;;;;;
+188DE;TANGUT COMPONENT-223;Lo;0;L;;;;;N;;;;;
+188DF;TANGUT COMPONENT-224;Lo;0;L;;;;;N;;;;;
+188E0;TANGUT COMPONENT-225;Lo;0;L;;;;;N;;;;;
+188E1;TANGUT COMPONENT-226;Lo;0;L;;;;;N;;;;;
+188E2;TANGUT COMPONENT-227;Lo;0;L;;;;;N;;;;;
+188E3;TANGUT COMPONENT-228;Lo;0;L;;;;;N;;;;;
+188E4;TANGUT COMPONENT-229;Lo;0;L;;;;;N;;;;;
+188E5;TANGUT COMPONENT-230;Lo;0;L;;;;;N;;;;;
+188E6;TANGUT COMPONENT-231;Lo;0;L;;;;;N;;;;;
+188E7;TANGUT COMPONENT-232;Lo;0;L;;;;;N;;;;;
+188E8;TANGUT COMPONENT-233;Lo;0;L;;;;;N;;;;;
+188E9;TANGUT COMPONENT-234;Lo;0;L;;;;;N;;;;;
+188EA;TANGUT COMPONENT-235;Lo;0;L;;;;;N;;;;;
+188EB;TANGUT COMPONENT-236;Lo;0;L;;;;;N;;;;;
+188EC;TANGUT COMPONENT-237;Lo;0;L;;;;;N;;;;;
+188ED;TANGUT COMPONENT-238;Lo;0;L;;;;;N;;;;;
+188EE;TANGUT COMPONENT-239;Lo;0;L;;;;;N;;;;;
+188EF;TANGUT COMPONENT-240;Lo;0;L;;;;;N;;;;;
+188F0;TANGUT COMPONENT-241;Lo;0;L;;;;;N;;;;;
+188F1;TANGUT COMPONENT-242;Lo;0;L;;;;;N;;;;;
+188F2;TANGUT COMPONENT-243;Lo;0;L;;;;;N;;;;;
+188F3;TANGUT COMPONENT-244;Lo;0;L;;;;;N;;;;;
+188F4;TANGUT COMPONENT-245;Lo;0;L;;;;;N;;;;;
+188F5;TANGUT COMPONENT-246;Lo;0;L;;;;;N;;;;;
+188F6;TANGUT COMPONENT-247;Lo;0;L;;;;;N;;;;;
+188F7;TANGUT COMPONENT-248;Lo;0;L;;;;;N;;;;;
+188F8;TANGUT COMPONENT-249;Lo;0;L;;;;;N;;;;;
+188F9;TANGUT COMPONENT-250;Lo;0;L;;;;;N;;;;;
+188FA;TANGUT COMPONENT-251;Lo;0;L;;;;;N;;;;;
+188FB;TANGUT COMPONENT-252;Lo;0;L;;;;;N;;;;;
+188FC;TANGUT COMPONENT-253;Lo;0;L;;;;;N;;;;;
+188FD;TANGUT COMPONENT-254;Lo;0;L;;;;;N;;;;;
+188FE;TANGUT COMPONENT-255;Lo;0;L;;;;;N;;;;;
+188FF;TANGUT COMPONENT-256;Lo;0;L;;;;;N;;;;;
+18900;TANGUT COMPONENT-257;Lo;0;L;;;;;N;;;;;
+18901;TANGUT COMPONENT-258;Lo;0;L;;;;;N;;;;;
+18902;TANGUT COMPONENT-259;Lo;0;L;;;;;N;;;;;
+18903;TANGUT COMPONENT-260;Lo;0;L;;;;;N;;;;;
+18904;TANGUT COMPONENT-261;Lo;0;L;;;;;N;;;;;
+18905;TANGUT COMPONENT-262;Lo;0;L;;;;;N;;;;;
+18906;TANGUT COMPONENT-263;Lo;0;L;;;;;N;;;;;
+18907;TANGUT COMPONENT-264;Lo;0;L;;;;;N;;;;;
+18908;TANGUT COMPONENT-265;Lo;0;L;;;;;N;;;;;
+18909;TANGUT COMPONENT-266;Lo;0;L;;;;;N;;;;;
+1890A;TANGUT COMPONENT-267;Lo;0;L;;;;;N;;;;;
+1890B;TANGUT COMPONENT-268;Lo;0;L;;;;;N;;;;;
+1890C;TANGUT COMPONENT-269;Lo;0;L;;;;;N;;;;;
+1890D;TANGUT COMPONENT-270;Lo;0;L;;;;;N;;;;;
+1890E;TANGUT COMPONENT-271;Lo;0;L;;;;;N;;;;;
+1890F;TANGUT COMPONENT-272;Lo;0;L;;;;;N;;;;;
+18910;TANGUT COMPONENT-273;Lo;0;L;;;;;N;;;;;
+18911;TANGUT COMPONENT-274;Lo;0;L;;;;;N;;;;;
+18912;TANGUT COMPONENT-275;Lo;0;L;;;;;N;;;;;
+18913;TANGUT COMPONENT-276;Lo;0;L;;;;;N;;;;;
+18914;TANGUT COMPONENT-277;Lo;0;L;;;;;N;;;;;
+18915;TANGUT COMPONENT-278;Lo;0;L;;;;;N;;;;;
+18916;TANGUT COMPONENT-279;Lo;0;L;;;;;N;;;;;
+18917;TANGUT COMPONENT-280;Lo;0;L;;;;;N;;;;;
+18918;TANGUT COMPONENT-281;Lo;0;L;;;;;N;;;;;
+18919;TANGUT COMPONENT-282;Lo;0;L;;;;;N;;;;;
+1891A;TANGUT COMPONENT-283;Lo;0;L;;;;;N;;;;;
+1891B;TANGUT COMPONENT-284;Lo;0;L;;;;;N;;;;;
+1891C;TANGUT COMPONENT-285;Lo;0;L;;;;;N;;;;;
+1891D;TANGUT COMPONENT-286;Lo;0;L;;;;;N;;;;;
+1891E;TANGUT COMPONENT-287;Lo;0;L;;;;;N;;;;;
+1891F;TANGUT COMPONENT-288;Lo;0;L;;;;;N;;;;;
+18920;TANGUT COMPONENT-289;Lo;0;L;;;;;N;;;;;
+18921;TANGUT COMPONENT-290;Lo;0;L;;;;;N;;;;;
+18922;TANGUT COMPONENT-291;Lo;0;L;;;;;N;;;;;
+18923;TANGUT COMPONENT-292;Lo;0;L;;;;;N;;;;;
+18924;TANGUT COMPONENT-293;Lo;0;L;;;;;N;;;;;
+18925;TANGUT COMPONENT-294;Lo;0;L;;;;;N;;;;;
+18926;TANGUT COMPONENT-295;Lo;0;L;;;;;N;;;;;
+18927;TANGUT COMPONENT-296;Lo;0;L;;;;;N;;;;;
+18928;TANGUT COMPONENT-297;Lo;0;L;;;;;N;;;;;
+18929;TANGUT COMPONENT-298;Lo;0;L;;;;;N;;;;;
+1892A;TANGUT COMPONENT-299;Lo;0;L;;;;;N;;;;;
+1892B;TANGUT COMPONENT-300;Lo;0;L;;;;;N;;;;;
+1892C;TANGUT COMPONENT-301;Lo;0;L;;;;;N;;;;;
+1892D;TANGUT COMPONENT-302;Lo;0;L;;;;;N;;;;;
+1892E;TANGUT COMPONENT-303;Lo;0;L;;;;;N;;;;;
+1892F;TANGUT COMPONENT-304;Lo;0;L;;;;;N;;;;;
+18930;TANGUT COMPONENT-305;Lo;0;L;;;;;N;;;;;
+18931;TANGUT COMPONENT-306;Lo;0;L;;;;;N;;;;;
+18932;TANGUT COMPONENT-307;Lo;0;L;;;;;N;;;;;
+18933;TANGUT COMPONENT-308;Lo;0;L;;;;;N;;;;;
+18934;TANGUT COMPONENT-309;Lo;0;L;;;;;N;;;;;
+18935;TANGUT COMPONENT-310;Lo;0;L;;;;;N;;;;;
+18936;TANGUT COMPONENT-311;Lo;0;L;;;;;N;;;;;
+18937;TANGUT COMPONENT-312;Lo;0;L;;;;;N;;;;;
+18938;TANGUT COMPONENT-313;Lo;0;L;;;;;N;;;;;
+18939;TANGUT COMPONENT-314;Lo;0;L;;;;;N;;;;;
+1893A;TANGUT COMPONENT-315;Lo;0;L;;;;;N;;;;;
+1893B;TANGUT COMPONENT-316;Lo;0;L;;;;;N;;;;;
+1893C;TANGUT COMPONENT-317;Lo;0;L;;;;;N;;;;;
+1893D;TANGUT COMPONENT-318;Lo;0;L;;;;;N;;;;;
+1893E;TANGUT COMPONENT-319;Lo;0;L;;;;;N;;;;;
+1893F;TANGUT COMPONENT-320;Lo;0;L;;;;;N;;;;;
+18940;TANGUT COMPONENT-321;Lo;0;L;;;;;N;;;;;
+18941;TANGUT COMPONENT-322;Lo;0;L;;;;;N;;;;;
+18942;TANGUT COMPONENT-323;Lo;0;L;;;;;N;;;;;
+18943;TANGUT COMPONENT-324;Lo;0;L;;;;;N;;;;;
+18944;TANGUT COMPONENT-325;Lo;0;L;;;;;N;;;;;
+18945;TANGUT COMPONENT-326;Lo;0;L;;;;;N;;;;;
+18946;TANGUT COMPONENT-327;Lo;0;L;;;;;N;;;;;
+18947;TANGUT COMPONENT-328;Lo;0;L;;;;;N;;;;;
+18948;TANGUT COMPONENT-329;Lo;0;L;;;;;N;;;;;
+18949;TANGUT COMPONENT-330;Lo;0;L;;;;;N;;;;;
+1894A;TANGUT COMPONENT-331;Lo;0;L;;;;;N;;;;;
+1894B;TANGUT COMPONENT-332;Lo;0;L;;;;;N;;;;;
+1894C;TANGUT COMPONENT-333;Lo;0;L;;;;;N;;;;;
+1894D;TANGUT COMPONENT-334;Lo;0;L;;;;;N;;;;;
+1894E;TANGUT COMPONENT-335;Lo;0;L;;;;;N;;;;;
+1894F;TANGUT COMPONENT-336;Lo;0;L;;;;;N;;;;;
+18950;TANGUT COMPONENT-337;Lo;0;L;;;;;N;;;;;
+18951;TANGUT COMPONENT-338;Lo;0;L;;;;;N;;;;;
+18952;TANGUT COMPONENT-339;Lo;0;L;;;;;N;;;;;
+18953;TANGUT COMPONENT-340;Lo;0;L;;;;;N;;;;;
+18954;TANGUT COMPONENT-341;Lo;0;L;;;;;N;;;;;
+18955;TANGUT COMPONENT-342;Lo;0;L;;;;;N;;;;;
+18956;TANGUT COMPONENT-343;Lo;0;L;;;;;N;;;;;
+18957;TANGUT COMPONENT-344;Lo;0;L;;;;;N;;;;;
+18958;TANGUT COMPONENT-345;Lo;0;L;;;;;N;;;;;
+18959;TANGUT COMPONENT-346;Lo;0;L;;;;;N;;;;;
+1895A;TANGUT COMPONENT-347;Lo;0;L;;;;;N;;;;;
+1895B;TANGUT COMPONENT-348;Lo;0;L;;;;;N;;;;;
+1895C;TANGUT COMPONENT-349;Lo;0;L;;;;;N;;;;;
+1895D;TANGUT COMPONENT-350;Lo;0;L;;;;;N;;;;;
+1895E;TANGUT COMPONENT-351;Lo;0;L;;;;;N;;;;;
+1895F;TANGUT COMPONENT-352;Lo;0;L;;;;;N;;;;;
+18960;TANGUT COMPONENT-353;Lo;0;L;;;;;N;;;;;
+18961;TANGUT COMPONENT-354;Lo;0;L;;;;;N;;;;;
+18962;TANGUT COMPONENT-355;Lo;0;L;;;;;N;;;;;
+18963;TANGUT COMPONENT-356;Lo;0;L;;;;;N;;;;;
+18964;TANGUT COMPONENT-357;Lo;0;L;;;;;N;;;;;
+18965;TANGUT COMPONENT-358;Lo;0;L;;;;;N;;;;;
+18966;TANGUT COMPONENT-359;Lo;0;L;;;;;N;;;;;
+18967;TANGUT COMPONENT-360;Lo;0;L;;;;;N;;;;;
+18968;TANGUT COMPONENT-361;Lo;0;L;;;;;N;;;;;
+18969;TANGUT COMPONENT-362;Lo;0;L;;;;;N;;;;;
+1896A;TANGUT COMPONENT-363;Lo;0;L;;;;;N;;;;;
+1896B;TANGUT COMPONENT-364;Lo;0;L;;;;;N;;;;;
+1896C;TANGUT COMPONENT-365;Lo;0;L;;;;;N;;;;;
+1896D;TANGUT COMPONENT-366;Lo;0;L;;;;;N;;;;;
+1896E;TANGUT COMPONENT-367;Lo;0;L;;;;;N;;;;;
+1896F;TANGUT COMPONENT-368;Lo;0;L;;;;;N;;;;;
+18970;TANGUT COMPONENT-369;Lo;0;L;;;;;N;;;;;
+18971;TANGUT COMPONENT-370;Lo;0;L;;;;;N;;;;;
+18972;TANGUT COMPONENT-371;Lo;0;L;;;;;N;;;;;
+18973;TANGUT COMPONENT-372;Lo;0;L;;;;;N;;;;;
+18974;TANGUT COMPONENT-373;Lo;0;L;;;;;N;;;;;
+18975;TANGUT COMPONENT-374;Lo;0;L;;;;;N;;;;;
+18976;TANGUT COMPONENT-375;Lo;0;L;;;;;N;;;;;
+18977;TANGUT COMPONENT-376;Lo;0;L;;;;;N;;;;;
+18978;TANGUT COMPONENT-377;Lo;0;L;;;;;N;;;;;
+18979;TANGUT COMPONENT-378;Lo;0;L;;;;;N;;;;;
+1897A;TANGUT COMPONENT-379;Lo;0;L;;;;;N;;;;;
+1897B;TANGUT COMPONENT-380;Lo;0;L;;;;;N;;;;;
+1897C;TANGUT COMPONENT-381;Lo;0;L;;;;;N;;;;;
+1897D;TANGUT COMPONENT-382;Lo;0;L;;;;;N;;;;;
+1897E;TANGUT COMPONENT-383;Lo;0;L;;;;;N;;;;;
+1897F;TANGUT COMPONENT-384;Lo;0;L;;;;;N;;;;;
+18980;TANGUT COMPONENT-385;Lo;0;L;;;;;N;;;;;
+18981;TANGUT COMPONENT-386;Lo;0;L;;;;;N;;;;;
+18982;TANGUT COMPONENT-387;Lo;0;L;;;;;N;;;;;
+18983;TANGUT COMPONENT-388;Lo;0;L;;;;;N;;;;;
+18984;TANGUT COMPONENT-389;Lo;0;L;;;;;N;;;;;
+18985;TANGUT COMPONENT-390;Lo;0;L;;;;;N;;;;;
+18986;TANGUT COMPONENT-391;Lo;0;L;;;;;N;;;;;
+18987;TANGUT COMPONENT-392;Lo;0;L;;;;;N;;;;;
+18988;TANGUT COMPONENT-393;Lo;0;L;;;;;N;;;;;
+18989;TANGUT COMPONENT-394;Lo;0;L;;;;;N;;;;;
+1898A;TANGUT COMPONENT-395;Lo;0;L;;;;;N;;;;;
+1898B;TANGUT COMPONENT-396;Lo;0;L;;;;;N;;;;;
+1898C;TANGUT COMPONENT-397;Lo;0;L;;;;;N;;;;;
+1898D;TANGUT COMPONENT-398;Lo;0;L;;;;;N;;;;;
+1898E;TANGUT COMPONENT-399;Lo;0;L;;;;;N;;;;;
+1898F;TANGUT COMPONENT-400;Lo;0;L;;;;;N;;;;;
+18990;TANGUT COMPONENT-401;Lo;0;L;;;;;N;;;;;
+18991;TANGUT COMPONENT-402;Lo;0;L;;;;;N;;;;;
+18992;TANGUT COMPONENT-403;Lo;0;L;;;;;N;;;;;
+18993;TANGUT COMPONENT-404;Lo;0;L;;;;;N;;;;;
+18994;TANGUT COMPONENT-405;Lo;0;L;;;;;N;;;;;
+18995;TANGUT COMPONENT-406;Lo;0;L;;;;;N;;;;;
+18996;TANGUT COMPONENT-407;Lo;0;L;;;;;N;;;;;
+18997;TANGUT COMPONENT-408;Lo;0;L;;;;;N;;;;;
+18998;TANGUT COMPONENT-409;Lo;0;L;;;;;N;;;;;
+18999;TANGUT COMPONENT-410;Lo;0;L;;;;;N;;;;;
+1899A;TANGUT COMPONENT-411;Lo;0;L;;;;;N;;;;;
+1899B;TANGUT COMPONENT-412;Lo;0;L;;;;;N;;;;;
+1899C;TANGUT COMPONENT-413;Lo;0;L;;;;;N;;;;;
+1899D;TANGUT COMPONENT-414;Lo;0;L;;;;;N;;;;;
+1899E;TANGUT COMPONENT-415;Lo;0;L;;;;;N;;;;;
+1899F;TANGUT COMPONENT-416;Lo;0;L;;;;;N;;;;;
+189A0;TANGUT COMPONENT-417;Lo;0;L;;;;;N;;;;;
+189A1;TANGUT COMPONENT-418;Lo;0;L;;;;;N;;;;;
+189A2;TANGUT COMPONENT-419;Lo;0;L;;;;;N;;;;;
+189A3;TANGUT COMPONENT-420;Lo;0;L;;;;;N;;;;;
+189A4;TANGUT COMPONENT-421;Lo;0;L;;;;;N;;;;;
+189A5;TANGUT COMPONENT-422;Lo;0;L;;;;;N;;;;;
+189A6;TANGUT COMPONENT-423;Lo;0;L;;;;;N;;;;;
+189A7;TANGUT COMPONENT-424;Lo;0;L;;;;;N;;;;;
+189A8;TANGUT COMPONENT-425;Lo;0;L;;;;;N;;;;;
+189A9;TANGUT COMPONENT-426;Lo;0;L;;;;;N;;;;;
+189AA;TANGUT COMPONENT-427;Lo;0;L;;;;;N;;;;;
+189AB;TANGUT COMPONENT-428;Lo;0;L;;;;;N;;;;;
+189AC;TANGUT COMPONENT-429;Lo;0;L;;;;;N;;;;;
+189AD;TANGUT COMPONENT-430;Lo;0;L;;;;;N;;;;;
+189AE;TANGUT COMPONENT-431;Lo;0;L;;;;;N;;;;;
+189AF;TANGUT COMPONENT-432;Lo;0;L;;;;;N;;;;;
+189B0;TANGUT COMPONENT-433;Lo;0;L;;;;;N;;;;;
+189B1;TANGUT COMPONENT-434;Lo;0;L;;;;;N;;;;;
+189B2;TANGUT COMPONENT-435;Lo;0;L;;;;;N;;;;;
+189B3;TANGUT COMPONENT-436;Lo;0;L;;;;;N;;;;;
+189B4;TANGUT COMPONENT-437;Lo;0;L;;;;;N;;;;;
+189B5;TANGUT COMPONENT-438;Lo;0;L;;;;;N;;;;;
+189B6;TANGUT COMPONENT-439;Lo;0;L;;;;;N;;;;;
+189B7;TANGUT COMPONENT-440;Lo;0;L;;;;;N;;;;;
+189B8;TANGUT COMPONENT-441;Lo;0;L;;;;;N;;;;;
+189B9;TANGUT COMPONENT-442;Lo;0;L;;;;;N;;;;;
+189BA;TANGUT COMPONENT-443;Lo;0;L;;;;;N;;;;;
+189BB;TANGUT COMPONENT-444;Lo;0;L;;;;;N;;;;;
+189BC;TANGUT COMPONENT-445;Lo;0;L;;;;;N;;;;;
+189BD;TANGUT COMPONENT-446;Lo;0;L;;;;;N;;;;;
+189BE;TANGUT COMPONENT-447;Lo;0;L;;;;;N;;;;;
+189BF;TANGUT COMPONENT-448;Lo;0;L;;;;;N;;;;;
+189C0;TANGUT COMPONENT-449;Lo;0;L;;;;;N;;;;;
+189C1;TANGUT COMPONENT-450;Lo;0;L;;;;;N;;;;;
+189C2;TANGUT COMPONENT-451;Lo;0;L;;;;;N;;;;;
+189C3;TANGUT COMPONENT-452;Lo;0;L;;;;;N;;;;;
+189C4;TANGUT COMPONENT-453;Lo;0;L;;;;;N;;;;;
+189C5;TANGUT COMPONENT-454;Lo;0;L;;;;;N;;;;;
+189C6;TANGUT COMPONENT-455;Lo;0;L;;;;;N;;;;;
+189C7;TANGUT COMPONENT-456;Lo;0;L;;;;;N;;;;;
+189C8;TANGUT COMPONENT-457;Lo;0;L;;;;;N;;;;;
+189C9;TANGUT COMPONENT-458;Lo;0;L;;;;;N;;;;;
+189CA;TANGUT COMPONENT-459;Lo;0;L;;;;;N;;;;;
+189CB;TANGUT COMPONENT-460;Lo;0;L;;;;;N;;;;;
+189CC;TANGUT COMPONENT-461;Lo;0;L;;;;;N;;;;;
+189CD;TANGUT COMPONENT-462;Lo;0;L;;;;;N;;;;;
+189CE;TANGUT COMPONENT-463;Lo;0;L;;;;;N;;;;;
+189CF;TANGUT COMPONENT-464;Lo;0;L;;;;;N;;;;;
+189D0;TANGUT COMPONENT-465;Lo;0;L;;;;;N;;;;;
+189D1;TANGUT COMPONENT-466;Lo;0;L;;;;;N;;;;;
+189D2;TANGUT COMPONENT-467;Lo;0;L;;;;;N;;;;;
+189D3;TANGUT COMPONENT-468;Lo;0;L;;;;;N;;;;;
+189D4;TANGUT COMPONENT-469;Lo;0;L;;;;;N;;;;;
+189D5;TANGUT COMPONENT-470;Lo;0;L;;;;;N;;;;;
+189D6;TANGUT COMPONENT-471;Lo;0;L;;;;;N;;;;;
+189D7;TANGUT COMPONENT-472;Lo;0;L;;;;;N;;;;;
+189D8;TANGUT COMPONENT-473;Lo;0;L;;;;;N;;;;;
+189D9;TANGUT COMPONENT-474;Lo;0;L;;;;;N;;;;;
+189DA;TANGUT COMPONENT-475;Lo;0;L;;;;;N;;;;;
+189DB;TANGUT COMPONENT-476;Lo;0;L;;;;;N;;;;;
+189DC;TANGUT COMPONENT-477;Lo;0;L;;;;;N;;;;;
+189DD;TANGUT COMPONENT-478;Lo;0;L;;;;;N;;;;;
+189DE;TANGUT COMPONENT-479;Lo;0;L;;;;;N;;;;;
+189DF;TANGUT COMPONENT-480;Lo;0;L;;;;;N;;;;;
+189E0;TANGUT COMPONENT-481;Lo;0;L;;;;;N;;;;;
+189E1;TANGUT COMPONENT-482;Lo;0;L;;;;;N;;;;;
+189E2;TANGUT COMPONENT-483;Lo;0;L;;;;;N;;;;;
+189E3;TANGUT COMPONENT-484;Lo;0;L;;;;;N;;;;;
+189E4;TANGUT COMPONENT-485;Lo;0;L;;;;;N;;;;;
+189E5;TANGUT COMPONENT-486;Lo;0;L;;;;;N;;;;;
+189E6;TANGUT COMPONENT-487;Lo;0;L;;;;;N;;;;;
+189E7;TANGUT COMPONENT-488;Lo;0;L;;;;;N;;;;;
+189E8;TANGUT COMPONENT-489;Lo;0;L;;;;;N;;;;;
+189E9;TANGUT COMPONENT-490;Lo;0;L;;;;;N;;;;;
+189EA;TANGUT COMPONENT-491;Lo;0;L;;;;;N;;;;;
+189EB;TANGUT COMPONENT-492;Lo;0;L;;;;;N;;;;;
+189EC;TANGUT COMPONENT-493;Lo;0;L;;;;;N;;;;;
+189ED;TANGUT COMPONENT-494;Lo;0;L;;;;;N;;;;;
+189EE;TANGUT COMPONENT-495;Lo;0;L;;;;;N;;;;;
+189EF;TANGUT COMPONENT-496;Lo;0;L;;;;;N;;;;;
+189F0;TANGUT COMPONENT-497;Lo;0;L;;;;;N;;;;;
+189F1;TANGUT COMPONENT-498;Lo;0;L;;;;;N;;;;;
+189F2;TANGUT COMPONENT-499;Lo;0;L;;;;;N;;;;;
+189F3;TANGUT COMPONENT-500;Lo;0;L;;;;;N;;;;;
+189F4;TANGUT COMPONENT-501;Lo;0;L;;;;;N;;;;;
+189F5;TANGUT COMPONENT-502;Lo;0;L;;;;;N;;;;;
+189F6;TANGUT COMPONENT-503;Lo;0;L;;;;;N;;;;;
+189F7;TANGUT COMPONENT-504;Lo;0;L;;;;;N;;;;;
+189F8;TANGUT COMPONENT-505;Lo;0;L;;;;;N;;;;;
+189F9;TANGUT COMPONENT-506;Lo;0;L;;;;;N;;;;;
+189FA;TANGUT COMPONENT-507;Lo;0;L;;;;;N;;;;;
+189FB;TANGUT COMPONENT-508;Lo;0;L;;;;;N;;;;;
+189FC;TANGUT COMPONENT-509;Lo;0;L;;;;;N;;;;;
+189FD;TANGUT COMPONENT-510;Lo;0;L;;;;;N;;;;;
+189FE;TANGUT COMPONENT-511;Lo;0;L;;;;;N;;;;;
+189FF;TANGUT COMPONENT-512;Lo;0;L;;;;;N;;;;;
+18A00;TANGUT COMPONENT-513;Lo;0;L;;;;;N;;;;;
+18A01;TANGUT COMPONENT-514;Lo;0;L;;;;;N;;;;;
+18A02;TANGUT COMPONENT-515;Lo;0;L;;;;;N;;;;;
+18A03;TANGUT COMPONENT-516;Lo;0;L;;;;;N;;;;;
+18A04;TANGUT COMPONENT-517;Lo;0;L;;;;;N;;;;;
+18A05;TANGUT COMPONENT-518;Lo;0;L;;;;;N;;;;;
+18A06;TANGUT COMPONENT-519;Lo;0;L;;;;;N;;;;;
+18A07;TANGUT COMPONENT-520;Lo;0;L;;;;;N;;;;;
+18A08;TANGUT COMPONENT-521;Lo;0;L;;;;;N;;;;;
+18A09;TANGUT COMPONENT-522;Lo;0;L;;;;;N;;;;;
+18A0A;TANGUT COMPONENT-523;Lo;0;L;;;;;N;;;;;
+18A0B;TANGUT COMPONENT-524;Lo;0;L;;;;;N;;;;;
+18A0C;TANGUT COMPONENT-525;Lo;0;L;;;;;N;;;;;
+18A0D;TANGUT COMPONENT-526;Lo;0;L;;;;;N;;;;;
+18A0E;TANGUT COMPONENT-527;Lo;0;L;;;;;N;;;;;
+18A0F;TANGUT COMPONENT-528;Lo;0;L;;;;;N;;;;;
+18A10;TANGUT COMPONENT-529;Lo;0;L;;;;;N;;;;;
+18A11;TANGUT COMPONENT-530;Lo;0;L;;;;;N;;;;;
+18A12;TANGUT COMPONENT-531;Lo;0;L;;;;;N;;;;;
+18A13;TANGUT COMPONENT-532;Lo;0;L;;;;;N;;;;;
+18A14;TANGUT COMPONENT-533;Lo;0;L;;;;;N;;;;;
+18A15;TANGUT COMPONENT-534;Lo;0;L;;;;;N;;;;;
+18A16;TANGUT COMPONENT-535;Lo;0;L;;;;;N;;;;;
+18A17;TANGUT COMPONENT-536;Lo;0;L;;;;;N;;;;;
+18A18;TANGUT COMPONENT-537;Lo;0;L;;;;;N;;;;;
+18A19;TANGUT COMPONENT-538;Lo;0;L;;;;;N;;;;;
+18A1A;TANGUT COMPONENT-539;Lo;0;L;;;;;N;;;;;
+18A1B;TANGUT COMPONENT-540;Lo;0;L;;;;;N;;;;;
+18A1C;TANGUT COMPONENT-541;Lo;0;L;;;;;N;;;;;
+18A1D;TANGUT COMPONENT-542;Lo;0;L;;;;;N;;;;;
+18A1E;TANGUT COMPONENT-543;Lo;0;L;;;;;N;;;;;
+18A1F;TANGUT COMPONENT-544;Lo;0;L;;;;;N;;;;;
+18A20;TANGUT COMPONENT-545;Lo;0;L;;;;;N;;;;;
+18A21;TANGUT COMPONENT-546;Lo;0;L;;;;;N;;;;;
+18A22;TANGUT COMPONENT-547;Lo;0;L;;;;;N;;;;;
+18A23;TANGUT COMPONENT-548;Lo;0;L;;;;;N;;;;;
+18A24;TANGUT COMPONENT-549;Lo;0;L;;;;;N;;;;;
+18A25;TANGUT COMPONENT-550;Lo;0;L;;;;;N;;;;;
+18A26;TANGUT COMPONENT-551;Lo;0;L;;;;;N;;;;;
+18A27;TANGUT COMPONENT-552;Lo;0;L;;;;;N;;;;;
+18A28;TANGUT COMPONENT-553;Lo;0;L;;;;;N;;;;;
+18A29;TANGUT COMPONENT-554;Lo;0;L;;;;;N;;;;;
+18A2A;TANGUT COMPONENT-555;Lo;0;L;;;;;N;;;;;
+18A2B;TANGUT COMPONENT-556;Lo;0;L;;;;;N;;;;;
+18A2C;TANGUT COMPONENT-557;Lo;0;L;;;;;N;;;;;
+18A2D;TANGUT COMPONENT-558;Lo;0;L;;;;;N;;;;;
+18A2E;TANGUT COMPONENT-559;Lo;0;L;;;;;N;;;;;
+18A2F;TANGUT COMPONENT-560;Lo;0;L;;;;;N;;;;;
+18A30;TANGUT COMPONENT-561;Lo;0;L;;;;;N;;;;;
+18A31;TANGUT COMPONENT-562;Lo;0;L;;;;;N;;;;;
+18A32;TANGUT COMPONENT-563;Lo;0;L;;;;;N;;;;;
+18A33;TANGUT COMPONENT-564;Lo;0;L;;;;;N;;;;;
+18A34;TANGUT COMPONENT-565;Lo;0;L;;;;;N;;;;;
+18A35;TANGUT COMPONENT-566;Lo;0;L;;;;;N;;;;;
+18A36;TANGUT COMPONENT-567;Lo;0;L;;;;;N;;;;;
+18A37;TANGUT COMPONENT-568;Lo;0;L;;;;;N;;;;;
+18A38;TANGUT COMPONENT-569;Lo;0;L;;;;;N;;;;;
+18A39;TANGUT COMPONENT-570;Lo;0;L;;;;;N;;;;;
+18A3A;TANGUT COMPONENT-571;Lo;0;L;;;;;N;;;;;
+18A3B;TANGUT COMPONENT-572;Lo;0;L;;;;;N;;;;;
+18A3C;TANGUT COMPONENT-573;Lo;0;L;;;;;N;;;;;
+18A3D;TANGUT COMPONENT-574;Lo;0;L;;;;;N;;;;;
+18A3E;TANGUT COMPONENT-575;Lo;0;L;;;;;N;;;;;
+18A3F;TANGUT COMPONENT-576;Lo;0;L;;;;;N;;;;;
+18A40;TANGUT COMPONENT-577;Lo;0;L;;;;;N;;;;;
+18A41;TANGUT COMPONENT-578;Lo;0;L;;;;;N;;;;;
+18A42;TANGUT COMPONENT-579;Lo;0;L;;;;;N;;;;;
+18A43;TANGUT COMPONENT-580;Lo;0;L;;;;;N;;;;;
+18A44;TANGUT COMPONENT-581;Lo;0;L;;;;;N;;;;;
+18A45;TANGUT COMPONENT-582;Lo;0;L;;;;;N;;;;;
+18A46;TANGUT COMPONENT-583;Lo;0;L;;;;;N;;;;;
+18A47;TANGUT COMPONENT-584;Lo;0;L;;;;;N;;;;;
+18A48;TANGUT COMPONENT-585;Lo;0;L;;;;;N;;;;;
+18A49;TANGUT COMPONENT-586;Lo;0;L;;;;;N;;;;;
+18A4A;TANGUT COMPONENT-587;Lo;0;L;;;;;N;;;;;
+18A4B;TANGUT COMPONENT-588;Lo;0;L;;;;;N;;;;;
+18A4C;TANGUT COMPONENT-589;Lo;0;L;;;;;N;;;;;
+18A4D;TANGUT COMPONENT-590;Lo;0;L;;;;;N;;;;;
+18A4E;TANGUT COMPONENT-591;Lo;0;L;;;;;N;;;;;
+18A4F;TANGUT COMPONENT-592;Lo;0;L;;;;;N;;;;;
+18A50;TANGUT COMPONENT-593;Lo;0;L;;;;;N;;;;;
+18A51;TANGUT COMPONENT-594;Lo;0;L;;;;;N;;;;;
+18A52;TANGUT COMPONENT-595;Lo;0;L;;;;;N;;;;;
+18A53;TANGUT COMPONENT-596;Lo;0;L;;;;;N;;;;;
+18A54;TANGUT COMPONENT-597;Lo;0;L;;;;;N;;;;;
+18A55;TANGUT COMPONENT-598;Lo;0;L;;;;;N;;;;;
+18A56;TANGUT COMPONENT-599;Lo;0;L;;;;;N;;;;;
+18A57;TANGUT COMPONENT-600;Lo;0;L;;;;;N;;;;;
+18A58;TANGUT COMPONENT-601;Lo;0;L;;;;;N;;;;;
+18A59;TANGUT COMPONENT-602;Lo;0;L;;;;;N;;;;;
+18A5A;TANGUT COMPONENT-603;Lo;0;L;;;;;N;;;;;
+18A5B;TANGUT COMPONENT-604;Lo;0;L;;;;;N;;;;;
+18A5C;TANGUT COMPONENT-605;Lo;0;L;;;;;N;;;;;
+18A5D;TANGUT COMPONENT-606;Lo;0;L;;;;;N;;;;;
+18A5E;TANGUT COMPONENT-607;Lo;0;L;;;;;N;;;;;
+18A5F;TANGUT COMPONENT-608;Lo;0;L;;;;;N;;;;;
+18A60;TANGUT COMPONENT-609;Lo;0;L;;;;;N;;;;;
+18A61;TANGUT COMPONENT-610;Lo;0;L;;;;;N;;;;;
+18A62;TANGUT COMPONENT-611;Lo;0;L;;;;;N;;;;;
+18A63;TANGUT COMPONENT-612;Lo;0;L;;;;;N;;;;;
+18A64;TANGUT COMPONENT-613;Lo;0;L;;;;;N;;;;;
+18A65;TANGUT COMPONENT-614;Lo;0;L;;;;;N;;;;;
+18A66;TANGUT COMPONENT-615;Lo;0;L;;;;;N;;;;;
+18A67;TANGUT COMPONENT-616;Lo;0;L;;;;;N;;;;;
+18A68;TANGUT COMPONENT-617;Lo;0;L;;;;;N;;;;;
+18A69;TANGUT COMPONENT-618;Lo;0;L;;;;;N;;;;;
+18A6A;TANGUT COMPONENT-619;Lo;0;L;;;;;N;;;;;
+18A6B;TANGUT COMPONENT-620;Lo;0;L;;;;;N;;;;;
+18A6C;TANGUT COMPONENT-621;Lo;0;L;;;;;N;;;;;
+18A6D;TANGUT COMPONENT-622;Lo;0;L;;;;;N;;;;;
+18A6E;TANGUT COMPONENT-623;Lo;0;L;;;;;N;;;;;
+18A6F;TANGUT COMPONENT-624;Lo;0;L;;;;;N;;;;;
+18A70;TANGUT COMPONENT-625;Lo;0;L;;;;;N;;;;;
+18A71;TANGUT COMPONENT-626;Lo;0;L;;;;;N;;;;;
+18A72;TANGUT COMPONENT-627;Lo;0;L;;;;;N;;;;;
+18A73;TANGUT COMPONENT-628;Lo;0;L;;;;;N;;;;;
+18A74;TANGUT COMPONENT-629;Lo;0;L;;;;;N;;;;;
+18A75;TANGUT COMPONENT-630;Lo;0;L;;;;;N;;;;;
+18A76;TANGUT COMPONENT-631;Lo;0;L;;;;;N;;;;;
+18A77;TANGUT COMPONENT-632;Lo;0;L;;;;;N;;;;;
+18A78;TANGUT COMPONENT-633;Lo;0;L;;;;;N;;;;;
+18A79;TANGUT COMPONENT-634;Lo;0;L;;;;;N;;;;;
+18A7A;TANGUT COMPONENT-635;Lo;0;L;;;;;N;;;;;
+18A7B;TANGUT COMPONENT-636;Lo;0;L;;;;;N;;;;;
+18A7C;TANGUT COMPONENT-637;Lo;0;L;;;;;N;;;;;
+18A7D;TANGUT COMPONENT-638;Lo;0;L;;;;;N;;;;;
+18A7E;TANGUT COMPONENT-639;Lo;0;L;;;;;N;;;;;
+18A7F;TANGUT COMPONENT-640;Lo;0;L;;;;;N;;;;;
+18A80;TANGUT COMPONENT-641;Lo;0;L;;;;;N;;;;;
+18A81;TANGUT COMPONENT-642;Lo;0;L;;;;;N;;;;;
+18A82;TANGUT COMPONENT-643;Lo;0;L;;;;;N;;;;;
+18A83;TANGUT COMPONENT-644;Lo;0;L;;;;;N;;;;;
+18A84;TANGUT COMPONENT-645;Lo;0;L;;;;;N;;;;;
+18A85;TANGUT COMPONENT-646;Lo;0;L;;;;;N;;;;;
+18A86;TANGUT COMPONENT-647;Lo;0;L;;;;;N;;;;;
+18A87;TANGUT COMPONENT-648;Lo;0;L;;;;;N;;;;;
+18A88;TANGUT COMPONENT-649;Lo;0;L;;;;;N;;;;;
+18A89;TANGUT COMPONENT-650;Lo;0;L;;;;;N;;;;;
+18A8A;TANGUT COMPONENT-651;Lo;0;L;;;;;N;;;;;
+18A8B;TANGUT COMPONENT-652;Lo;0;L;;;;;N;;;;;
+18A8C;TANGUT COMPONENT-653;Lo;0;L;;;;;N;;;;;
+18A8D;TANGUT COMPONENT-654;Lo;0;L;;;;;N;;;;;
+18A8E;TANGUT COMPONENT-655;Lo;0;L;;;;;N;;;;;
+18A8F;TANGUT COMPONENT-656;Lo;0;L;;;;;N;;;;;
+18A90;TANGUT COMPONENT-657;Lo;0;L;;;;;N;;;;;
+18A91;TANGUT COMPONENT-658;Lo;0;L;;;;;N;;;;;
+18A92;TANGUT COMPONENT-659;Lo;0;L;;;;;N;;;;;
+18A93;TANGUT COMPONENT-660;Lo;0;L;;;;;N;;;;;
+18A94;TANGUT COMPONENT-661;Lo;0;L;;;;;N;;;;;
+18A95;TANGUT COMPONENT-662;Lo;0;L;;;;;N;;;;;
+18A96;TANGUT COMPONENT-663;Lo;0;L;;;;;N;;;;;
+18A97;TANGUT COMPONENT-664;Lo;0;L;;;;;N;;;;;
+18A98;TANGUT COMPONENT-665;Lo;0;L;;;;;N;;;;;
+18A99;TANGUT COMPONENT-666;Lo;0;L;;;;;N;;;;;
+18A9A;TANGUT COMPONENT-667;Lo;0;L;;;;;N;;;;;
+18A9B;TANGUT COMPONENT-668;Lo;0;L;;;;;N;;;;;
+18A9C;TANGUT COMPONENT-669;Lo;0;L;;;;;N;;;;;
+18A9D;TANGUT COMPONENT-670;Lo;0;L;;;;;N;;;;;
+18A9E;TANGUT COMPONENT-671;Lo;0;L;;;;;N;;;;;
+18A9F;TANGUT COMPONENT-672;Lo;0;L;;;;;N;;;;;
+18AA0;TANGUT COMPONENT-673;Lo;0;L;;;;;N;;;;;
+18AA1;TANGUT COMPONENT-674;Lo;0;L;;;;;N;;;;;
+18AA2;TANGUT COMPONENT-675;Lo;0;L;;;;;N;;;;;
+18AA3;TANGUT COMPONENT-676;Lo;0;L;;;;;N;;;;;
+18AA4;TANGUT COMPONENT-677;Lo;0;L;;;;;N;;;;;
+18AA5;TANGUT COMPONENT-678;Lo;0;L;;;;;N;;;;;
+18AA6;TANGUT COMPONENT-679;Lo;0;L;;;;;N;;;;;
+18AA7;TANGUT COMPONENT-680;Lo;0;L;;;;;N;;;;;
+18AA8;TANGUT COMPONENT-681;Lo;0;L;;;;;N;;;;;
+18AA9;TANGUT COMPONENT-682;Lo;0;L;;;;;N;;;;;
+18AAA;TANGUT COMPONENT-683;Lo;0;L;;;;;N;;;;;
+18AAB;TANGUT COMPONENT-684;Lo;0;L;;;;;N;;;;;
+18AAC;TANGUT COMPONENT-685;Lo;0;L;;;;;N;;;;;
+18AAD;TANGUT COMPONENT-686;Lo;0;L;;;;;N;;;;;
+18AAE;TANGUT COMPONENT-687;Lo;0;L;;;;;N;;;;;
+18AAF;TANGUT COMPONENT-688;Lo;0;L;;;;;N;;;;;
+18AB0;TANGUT COMPONENT-689;Lo;0;L;;;;;N;;;;;
+18AB1;TANGUT COMPONENT-690;Lo;0;L;;;;;N;;;;;
+18AB2;TANGUT COMPONENT-691;Lo;0;L;;;;;N;;;;;
+18AB3;TANGUT COMPONENT-692;Lo;0;L;;;;;N;;;;;
+18AB4;TANGUT COMPONENT-693;Lo;0;L;;;;;N;;;;;
+18AB5;TANGUT COMPONENT-694;Lo;0;L;;;;;N;;;;;
+18AB6;TANGUT COMPONENT-695;Lo;0;L;;;;;N;;;;;
+18AB7;TANGUT COMPONENT-696;Lo;0;L;;;;;N;;;;;
+18AB8;TANGUT COMPONENT-697;Lo;0;L;;;;;N;;;;;
+18AB9;TANGUT COMPONENT-698;Lo;0;L;;;;;N;;;;;
+18ABA;TANGUT COMPONENT-699;Lo;0;L;;;;;N;;;;;
+18ABB;TANGUT COMPONENT-700;Lo;0;L;;;;;N;;;;;
+18ABC;TANGUT COMPONENT-701;Lo;0;L;;;;;N;;;;;
+18ABD;TANGUT COMPONENT-702;Lo;0;L;;;;;N;;;;;
+18ABE;TANGUT COMPONENT-703;Lo;0;L;;;;;N;;;;;
+18ABF;TANGUT COMPONENT-704;Lo;0;L;;;;;N;;;;;
+18AC0;TANGUT COMPONENT-705;Lo;0;L;;;;;N;;;;;
+18AC1;TANGUT COMPONENT-706;Lo;0;L;;;;;N;;;;;
+18AC2;TANGUT COMPONENT-707;Lo;0;L;;;;;N;;;;;
+18AC3;TANGUT COMPONENT-708;Lo;0;L;;;;;N;;;;;
+18AC4;TANGUT COMPONENT-709;Lo;0;L;;;;;N;;;;;
+18AC5;TANGUT COMPONENT-710;Lo;0;L;;;;;N;;;;;
+18AC6;TANGUT COMPONENT-711;Lo;0;L;;;;;N;;;;;
+18AC7;TANGUT COMPONENT-712;Lo;0;L;;;;;N;;;;;
+18AC8;TANGUT COMPONENT-713;Lo;0;L;;;;;N;;;;;
+18AC9;TANGUT COMPONENT-714;Lo;0;L;;;;;N;;;;;
+18ACA;TANGUT COMPONENT-715;Lo;0;L;;;;;N;;;;;
+18ACB;TANGUT COMPONENT-716;Lo;0;L;;;;;N;;;;;
+18ACC;TANGUT COMPONENT-717;Lo;0;L;;;;;N;;;;;
+18ACD;TANGUT COMPONENT-718;Lo;0;L;;;;;N;;;;;
+18ACE;TANGUT COMPONENT-719;Lo;0;L;;;;;N;;;;;
+18ACF;TANGUT COMPONENT-720;Lo;0;L;;;;;N;;;;;
+18AD0;TANGUT COMPONENT-721;Lo;0;L;;;;;N;;;;;
+18AD1;TANGUT COMPONENT-722;Lo;0;L;;;;;N;;;;;
+18AD2;TANGUT COMPONENT-723;Lo;0;L;;;;;N;;;;;
+18AD3;TANGUT COMPONENT-724;Lo;0;L;;;;;N;;;;;
+18AD4;TANGUT COMPONENT-725;Lo;0;L;;;;;N;;;;;
+18AD5;TANGUT COMPONENT-726;Lo;0;L;;;;;N;;;;;
+18AD6;TANGUT COMPONENT-727;Lo;0;L;;;;;N;;;;;
+18AD7;TANGUT COMPONENT-728;Lo;0;L;;;;;N;;;;;
+18AD8;TANGUT COMPONENT-729;Lo;0;L;;;;;N;;;;;
+18AD9;TANGUT COMPONENT-730;Lo;0;L;;;;;N;;;;;
+18ADA;TANGUT COMPONENT-731;Lo;0;L;;;;;N;;;;;
+18ADB;TANGUT COMPONENT-732;Lo;0;L;;;;;N;;;;;
+18ADC;TANGUT COMPONENT-733;Lo;0;L;;;;;N;;;;;
+18ADD;TANGUT COMPONENT-734;Lo;0;L;;;;;N;;;;;
+18ADE;TANGUT COMPONENT-735;Lo;0;L;;;;;N;;;;;
+18ADF;TANGUT COMPONENT-736;Lo;0;L;;;;;N;;;;;
+18AE0;TANGUT COMPONENT-737;Lo;0;L;;;;;N;;;;;
+18AE1;TANGUT COMPONENT-738;Lo;0;L;;;;;N;;;;;
+18AE2;TANGUT COMPONENT-739;Lo;0;L;;;;;N;;;;;
+18AE3;TANGUT COMPONENT-740;Lo;0;L;;;;;N;;;;;
+18AE4;TANGUT COMPONENT-741;Lo;0;L;;;;;N;;;;;
+18AE5;TANGUT COMPONENT-742;Lo;0;L;;;;;N;;;;;
+18AE6;TANGUT COMPONENT-743;Lo;0;L;;;;;N;;;;;
+18AE7;TANGUT COMPONENT-744;Lo;0;L;;;;;N;;;;;
+18AE8;TANGUT COMPONENT-745;Lo;0;L;;;;;N;;;;;
+18AE9;TANGUT COMPONENT-746;Lo;0;L;;;;;N;;;;;
+18AEA;TANGUT COMPONENT-747;Lo;0;L;;;;;N;;;;;
+18AEB;TANGUT COMPONENT-748;Lo;0;L;;;;;N;;;;;
+18AEC;TANGUT COMPONENT-749;Lo;0;L;;;;;N;;;;;
+18AED;TANGUT COMPONENT-750;Lo;0;L;;;;;N;;;;;
+18AEE;TANGUT COMPONENT-751;Lo;0;L;;;;;N;;;;;
+18AEF;TANGUT COMPONENT-752;Lo;0;L;;;;;N;;;;;
+18AF0;TANGUT COMPONENT-753;Lo;0;L;;;;;N;;;;;
+18AF1;TANGUT COMPONENT-754;Lo;0;L;;;;;N;;;;;
+18AF2;TANGUT COMPONENT-755;Lo;0;L;;;;;N;;;;;
+1B000;KATAKANA LETTER ARCHAIC E;Lo;0;L;;;;;N;;;;;
+1B001;HIRAGANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;
+1BC00;DUPLOYAN LETTER H;Lo;0;L;;;;;N;;;;;
+1BC01;DUPLOYAN LETTER X;Lo;0;L;;;;;N;;;;;
+1BC02;DUPLOYAN LETTER P;Lo;0;L;;;;;N;;;;;
+1BC03;DUPLOYAN LETTER T;Lo;0;L;;;;;N;;;;;
+1BC04;DUPLOYAN LETTER F;Lo;0;L;;;;;N;;;;;
+1BC05;DUPLOYAN LETTER K;Lo;0;L;;;;;N;;;;;
+1BC06;DUPLOYAN LETTER L;Lo;0;L;;;;;N;;;;;
+1BC07;DUPLOYAN LETTER B;Lo;0;L;;;;;N;;;;;
+1BC08;DUPLOYAN LETTER D;Lo;0;L;;;;;N;;;;;
+1BC09;DUPLOYAN LETTER V;Lo;0;L;;;;;N;;;;;
+1BC0A;DUPLOYAN LETTER G;Lo;0;L;;;;;N;;;;;
+1BC0B;DUPLOYAN LETTER R;Lo;0;L;;;;;N;;;;;
+1BC0C;DUPLOYAN LETTER P N;Lo;0;L;;;;;N;;;;;
+1BC0D;DUPLOYAN LETTER D S;Lo;0;L;;;;;N;;;;;
+1BC0E;DUPLOYAN LETTER F N;Lo;0;L;;;;;N;;;;;
+1BC0F;DUPLOYAN LETTER K M;Lo;0;L;;;;;N;;;;;
+1BC10;DUPLOYAN LETTER R S;Lo;0;L;;;;;N;;;;;
+1BC11;DUPLOYAN LETTER TH;Lo;0;L;;;;;N;;;;;
+1BC12;DUPLOYAN LETTER SLOAN DH;Lo;0;L;;;;;N;;;;;
+1BC13;DUPLOYAN LETTER DH;Lo;0;L;;;;;N;;;;;
+1BC14;DUPLOYAN LETTER KK;Lo;0;L;;;;;N;;;;;
+1BC15;DUPLOYAN LETTER SLOAN J;Lo;0;L;;;;;N;;;;;
+1BC16;DUPLOYAN LETTER HL;Lo;0;L;;;;;N;;;;;
+1BC17;DUPLOYAN LETTER LH;Lo;0;L;;;;;N;;;;;
+1BC18;DUPLOYAN LETTER RH;Lo;0;L;;;;;N;;;;;
+1BC19;DUPLOYAN LETTER M;Lo;0;L;;;;;N;;;;;
+1BC1A;DUPLOYAN LETTER N;Lo;0;L;;;;;N;;;;;
+1BC1B;DUPLOYAN LETTER J;Lo;0;L;;;;;N;;;;;
+1BC1C;DUPLOYAN LETTER S;Lo;0;L;;;;;N;;;;;
+1BC1D;DUPLOYAN LETTER M N;Lo;0;L;;;;;N;;;;;
+1BC1E;DUPLOYAN LETTER N M;Lo;0;L;;;;;N;;;;;
+1BC1F;DUPLOYAN LETTER J M;Lo;0;L;;;;;N;;;;;
+1BC20;DUPLOYAN LETTER S J;Lo;0;L;;;;;N;;;;;
+1BC21;DUPLOYAN LETTER M WITH DOT;Lo;0;L;;;;;N;;;;;
+1BC22;DUPLOYAN LETTER N WITH DOT;Lo;0;L;;;;;N;;;;;
+1BC23;DUPLOYAN LETTER J WITH DOT;Lo;0;L;;;;;N;;;;;
+1BC24;DUPLOYAN LETTER J WITH DOTS INSIDE AND ABOVE;Lo;0;L;;;;;N;;;;;
+1BC25;DUPLOYAN LETTER S WITH DOT;Lo;0;L;;;;;N;;;;;
+1BC26;DUPLOYAN LETTER S WITH DOT BELOW;Lo;0;L;;;;;N;;;;;
+1BC27;DUPLOYAN LETTER M S;Lo;0;L;;;;;N;;;;;
+1BC28;DUPLOYAN LETTER N S;Lo;0;L;;;;;N;;;;;
+1BC29;DUPLOYAN LETTER J S;Lo;0;L;;;;;N;;;;;
+1BC2A;DUPLOYAN LETTER S S;Lo;0;L;;;;;N;;;;;
+1BC2B;DUPLOYAN LETTER M N S;Lo;0;L;;;;;N;;;;;
+1BC2C;DUPLOYAN LETTER N M S;Lo;0;L;;;;;N;;;;;
+1BC2D;DUPLOYAN LETTER J M S;Lo;0;L;;;;;N;;;;;
+1BC2E;DUPLOYAN LETTER S J S;Lo;0;L;;;;;N;;;;;
+1BC2F;DUPLOYAN LETTER J S WITH DOT;Lo;0;L;;;;;N;;;;;
+1BC30;DUPLOYAN LETTER J N;Lo;0;L;;;;;N;;;;;
+1BC31;DUPLOYAN LETTER J N S;Lo;0;L;;;;;N;;;;;
+1BC32;DUPLOYAN LETTER S T;Lo;0;L;;;;;N;;;;;
+1BC33;DUPLOYAN LETTER S T R;Lo;0;L;;;;;N;;;;;
+1BC34;DUPLOYAN LETTER S P;Lo;0;L;;;;;N;;;;;
+1BC35;DUPLOYAN LETTER S P R;Lo;0;L;;;;;N;;;;;
+1BC36;DUPLOYAN LETTER T S;Lo;0;L;;;;;N;;;;;
+1BC37;DUPLOYAN LETTER T R S;Lo;0;L;;;;;N;;;;;
+1BC38;DUPLOYAN LETTER W;Lo;0;L;;;;;N;;;;;
+1BC39;DUPLOYAN LETTER WH;Lo;0;L;;;;;N;;;;;
+1BC3A;DUPLOYAN LETTER W R;Lo;0;L;;;;;N;;;;;
+1BC3B;DUPLOYAN LETTER S N;Lo;0;L;;;;;N;;;;;
+1BC3C;DUPLOYAN LETTER S M;Lo;0;L;;;;;N;;;;;
+1BC3D;DUPLOYAN LETTER K R S;Lo;0;L;;;;;N;;;;;
+1BC3E;DUPLOYAN LETTER G R S;Lo;0;L;;;;;N;;;;;
+1BC3F;DUPLOYAN LETTER S K;Lo;0;L;;;;;N;;;;;
+1BC40;DUPLOYAN LETTER S K R;Lo;0;L;;;;;N;;;;;
+1BC41;DUPLOYAN LETTER A;Lo;0;L;;;;;N;;;;;
+1BC42;DUPLOYAN LETTER SLOAN OW;Lo;0;L;;;;;N;;;;;
+1BC43;DUPLOYAN LETTER OA;Lo;0;L;;;;;N;;;;;
+1BC44;DUPLOYAN LETTER O;Lo;0;L;;;;;N;;;;;
+1BC45;DUPLOYAN LETTER AOU;Lo;0;L;;;;;N;;;;;
+1BC46;DUPLOYAN LETTER I;Lo;0;L;;;;;N;;;;;
+1BC47;DUPLOYAN LETTER E;Lo;0;L;;;;;N;;;;;
+1BC48;DUPLOYAN LETTER IE;Lo;0;L;;;;;N;;;;;
+1BC49;DUPLOYAN LETTER SHORT I;Lo;0;L;;;;;N;;;;;
+1BC4A;DUPLOYAN LETTER UI;Lo;0;L;;;;;N;;;;;
+1BC4B;DUPLOYAN LETTER EE;Lo;0;L;;;;;N;;;;;
+1BC4C;DUPLOYAN LETTER SLOAN EH;Lo;0;L;;;;;N;;;;;
+1BC4D;DUPLOYAN LETTER ROMANIAN I;Lo;0;L;;;;;N;;;;;
+1BC4E;DUPLOYAN LETTER SLOAN EE;Lo;0;L;;;;;N;;;;;
+1BC4F;DUPLOYAN LETTER LONG I;Lo;0;L;;;;;N;;;;;
+1BC50;DUPLOYAN LETTER YE;Lo;0;L;;;;;N;;;;;
+1BC51;DUPLOYAN LETTER U;Lo;0;L;;;;;N;;;;;
+1BC52;DUPLOYAN LETTER EU;Lo;0;L;;;;;N;;;;;
+1BC53;DUPLOYAN LETTER XW;Lo;0;L;;;;;N;;;;;
+1BC54;DUPLOYAN LETTER U N;Lo;0;L;;;;;N;;;;;
+1BC55;DUPLOYAN LETTER LONG U;Lo;0;L;;;;;N;;;;;
+1BC56;DUPLOYAN LETTER ROMANIAN U;Lo;0;L;;;;;N;;;;;
+1BC57;DUPLOYAN LETTER UH;Lo;0;L;;;;;N;;;;;
+1BC58;DUPLOYAN LETTER SLOAN U;Lo;0;L;;;;;N;;;;;
+1BC59;DUPLOYAN LETTER OOH;Lo;0;L;;;;;N;;;;;
+1BC5A;DUPLOYAN LETTER OW;Lo;0;L;;;;;N;;;;;
+1BC5B;DUPLOYAN LETTER OU;Lo;0;L;;;;;N;;;;;
+1BC5C;DUPLOYAN LETTER WA;Lo;0;L;;;;;N;;;;;
+1BC5D;DUPLOYAN LETTER WO;Lo;0;L;;;;;N;;;;;
+1BC5E;DUPLOYAN LETTER WI;Lo;0;L;;;;;N;;;;;
+1BC5F;DUPLOYAN LETTER WEI;Lo;0;L;;;;;N;;;;;
+1BC60;DUPLOYAN LETTER WOW;Lo;0;L;;;;;N;;;;;
+1BC61;DUPLOYAN LETTER NASAL U;Lo;0;L;;;;;N;;;;;
+1BC62;DUPLOYAN LETTER NASAL O;Lo;0;L;;;;;N;;;;;
+1BC63;DUPLOYAN LETTER NASAL I;Lo;0;L;;;;;N;;;;;
+1BC64;DUPLOYAN LETTER NASAL A;Lo;0;L;;;;;N;;;;;
+1BC65;DUPLOYAN LETTER PERNIN AN;Lo;0;L;;;;;N;;;;;
+1BC66;DUPLOYAN LETTER PERNIN AM;Lo;0;L;;;;;N;;;;;
+1BC67;DUPLOYAN LETTER SLOAN EN;Lo;0;L;;;;;N;;;;;
+1BC68;DUPLOYAN LETTER SLOAN AN;Lo;0;L;;;;;N;;;;;
+1BC69;DUPLOYAN LETTER SLOAN ON;Lo;0;L;;;;;N;;;;;
+1BC6A;DUPLOYAN LETTER VOCALIC M;Lo;0;L;;;;;N;;;;;
+1BC70;DUPLOYAN AFFIX LEFT HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC71;DUPLOYAN AFFIX MID HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC72;DUPLOYAN AFFIX RIGHT HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC73;DUPLOYAN AFFIX LOW VERTICAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC74;DUPLOYAN AFFIX MID VERTICAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC75;DUPLOYAN AFFIX HIGH VERTICAL SECANT;Lo;0;L;;;;;N;;;;;
+1BC76;DUPLOYAN AFFIX ATTACHED SECANT;Lo;0;L;;;;;N;;;;;
+1BC77;DUPLOYAN AFFIX ATTACHED LEFT-TO-RIGHT SECANT;Lo;0;L;;;;;N;;;;;
+1BC78;DUPLOYAN AFFIX ATTACHED TANGENT;Lo;0;L;;;;;N;;;;;
+1BC79;DUPLOYAN AFFIX ATTACHED TAIL;Lo;0;L;;;;;N;;;;;
+1BC7A;DUPLOYAN AFFIX ATTACHED E HOOK;Lo;0;L;;;;;N;;;;;
+1BC7B;DUPLOYAN AFFIX ATTACHED I HOOK;Lo;0;L;;;;;N;;;;;
+1BC7C;DUPLOYAN AFFIX ATTACHED TANGENT HOOK;Lo;0;L;;;;;N;;;;;
+1BC80;DUPLOYAN AFFIX HIGH ACUTE;Lo;0;L;;;;;N;;;;;
+1BC81;DUPLOYAN AFFIX HIGH TIGHT ACUTE;Lo;0;L;;;;;N;;;;;
+1BC82;DUPLOYAN AFFIX HIGH GRAVE;Lo;0;L;;;;;N;;;;;
+1BC83;DUPLOYAN AFFIX HIGH LONG GRAVE;Lo;0;L;;;;;N;;;;;
+1BC84;DUPLOYAN AFFIX HIGH DOT;Lo;0;L;;;;;N;;;;;
+1BC85;DUPLOYAN AFFIX HIGH CIRCLE;Lo;0;L;;;;;N;;;;;
+1BC86;DUPLOYAN AFFIX HIGH LINE;Lo;0;L;;;;;N;;;;;
+1BC87;DUPLOYAN AFFIX HIGH WAVE;Lo;0;L;;;;;N;;;;;
+1BC88;DUPLOYAN AFFIX HIGH VERTICAL;Lo;0;L;;;;;N;;;;;
+1BC90;DUPLOYAN AFFIX LOW ACUTE;Lo;0;L;;;;;N;;;;;
+1BC91;DUPLOYAN AFFIX LOW TIGHT ACUTE;Lo;0;L;;;;;N;;;;;
+1BC92;DUPLOYAN AFFIX LOW GRAVE;Lo;0;L;;;;;N;;;;;
+1BC93;DUPLOYAN AFFIX LOW LONG GRAVE;Lo;0;L;;;;;N;;;;;
+1BC94;DUPLOYAN AFFIX LOW DOT;Lo;0;L;;;;;N;;;;;
+1BC95;DUPLOYAN AFFIX LOW CIRCLE;Lo;0;L;;;;;N;;;;;
+1BC96;DUPLOYAN AFFIX LOW LINE;Lo;0;L;;;;;N;;;;;
+1BC97;DUPLOYAN AFFIX LOW WAVE;Lo;0;L;;;;;N;;;;;
+1BC98;DUPLOYAN AFFIX LOW VERTICAL;Lo;0;L;;;;;N;;;;;
+1BC99;DUPLOYAN AFFIX LOW ARROW;Lo;0;L;;;;;N;;;;;
+1BC9C;DUPLOYAN SIGN O WITH CROSS;So;0;L;;;;;N;;;;;
+1BC9D;DUPLOYAN THICK LETTER SELECTOR;Mn;0;NSM;;;;;N;;;;;
+1BC9E;DUPLOYAN DOUBLE MARK;Mn;1;NSM;;;;;N;;;;;
+1BC9F;DUPLOYAN PUNCTUATION CHINOOK FULL STOP;Po;0;L;;;;;N;;;;;
+1BCA0;SHORTHAND FORMAT LETTER OVERLAP;Cf;0;BN;;;;;N;;;;;
+1BCA1;SHORTHAND FORMAT CONTINUING OVERLAP;Cf;0;BN;;;;;N;;;;;
+1BCA2;SHORTHAND FORMAT DOWN STEP;Cf;0;BN;;;;;N;;;;;
+1BCA3;SHORTHAND FORMAT UP STEP;Cf;0;BN;;;;;N;;;;;
+1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;;
+1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;;
+1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;;
+1D003;BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON;So;0;L;;;;;N;;;;;
+1D004;BYZANTINE MUSICAL SYMBOL OXEIA DIPLI;So;0;L;;;;;N;;;;;
+1D005;BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON;So;0;L;;;;;N;;;;;
+1D006;BYZANTINE MUSICAL SYMBOL VAREIA DIPLI;So;0;L;;;;;N;;;;;
+1D007;BYZANTINE MUSICAL SYMBOL KATHISTI;So;0;L;;;;;N;;;;;
+1D008;BYZANTINE MUSICAL SYMBOL SYRMATIKI;So;0;L;;;;;N;;;;;
+1D009;BYZANTINE MUSICAL SYMBOL PARAKLITIKI;So;0;L;;;;;N;;;;;
+1D00A;BYZANTINE MUSICAL SYMBOL YPOKRISIS;So;0;L;;;;;N;;;;;
+1D00B;BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI;So;0;L;;;;;N;;;;;
+1D00C;BYZANTINE MUSICAL SYMBOL KREMASTI;So;0;L;;;;;N;;;;;
+1D00D;BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON;So;0;L;;;;;N;;;;;
+1D00E;BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON;So;0;L;;;;;N;;;;;
+1D00F;BYZANTINE MUSICAL SYMBOL TELEIA;So;0;L;;;;;N;;;;;
+1D010;BYZANTINE MUSICAL SYMBOL KENTIMATA;So;0;L;;;;;N;;;;;
+1D011;BYZANTINE MUSICAL SYMBOL APOSTROFOS;So;0;L;;;;;N;;;;;
+1D012;BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI;So;0;L;;;;;N;;;;;
+1D013;BYZANTINE MUSICAL SYMBOL SYNEVMA;So;0;L;;;;;N;;;;;
+1D014;BYZANTINE MUSICAL SYMBOL THITA;So;0;L;;;;;N;;;;;
+1D015;BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION;So;0;L;;;;;N;;;;;
+1D016;BYZANTINE MUSICAL SYMBOL GORGON ARCHAION;So;0;L;;;;;N;;;;;
+1D017;BYZANTINE MUSICAL SYMBOL PSILON;So;0;L;;;;;N;;;;;
+1D018;BYZANTINE MUSICAL SYMBOL CHAMILON;So;0;L;;;;;N;;;;;
+1D019;BYZANTINE MUSICAL SYMBOL VATHY;So;0;L;;;;;N;;;;;
+1D01A;BYZANTINE MUSICAL SYMBOL ISON ARCHAION;So;0;L;;;;;N;;;;;
+1D01B;BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION;So;0;L;;;;;N;;;;;
+1D01C;BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION;So;0;L;;;;;N;;;;;
+1D01D;BYZANTINE MUSICAL SYMBOL SAXIMATA;So;0;L;;;;;N;;;;;
+1D01E;BYZANTINE MUSICAL SYMBOL PARICHON;So;0;L;;;;;N;;;;;
+1D01F;BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA;So;0;L;;;;;N;;;;;
+1D020;BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION;So;0;L;;;;;N;;;;;
+1D021;BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION;So;0;L;;;;;N;;;;;
+1D022;BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION;So;0;L;;;;;N;;;;;
+1D023;BYZANTINE MUSICAL SYMBOL APOTHEMA;So;0;L;;;;;N;;;;;
+1D024;BYZANTINE MUSICAL SYMBOL KLASMA;So;0;L;;;;;N;;;;;
+1D025;BYZANTINE MUSICAL SYMBOL REVMA;So;0;L;;;;;N;;;;;
+1D026;BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION;So;0;L;;;;;N;;;;;
+1D027;BYZANTINE MUSICAL SYMBOL TINAGMA;So;0;L;;;;;N;;;;;
+1D028;BYZANTINE MUSICAL SYMBOL ANATRICHISMA;So;0;L;;;;;N;;;;;
+1D029;BYZANTINE MUSICAL SYMBOL SEISMA;So;0;L;;;;;N;;;;;
+1D02A;BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION;So;0;L;;;;;N;;;;;
+1D02B;BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU;So;0;L;;;;;N;;;;;
+1D02C;BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION;So;0;L;;;;;N;;;;;
+1D02D;BYZANTINE MUSICAL SYMBOL THEMA;So;0;L;;;;;N;;;;;
+1D02E;BYZANTINE MUSICAL SYMBOL LEMOI;So;0;L;;;;;N;;;;;
+1D02F;BYZANTINE MUSICAL SYMBOL DYO;So;0;L;;;;;N;;;;;
+1D030;BYZANTINE MUSICAL SYMBOL TRIA;So;0;L;;;;;N;;;;;
+1D031;BYZANTINE MUSICAL SYMBOL TESSERA;So;0;L;;;;;N;;;;;
+1D032;BYZANTINE MUSICAL SYMBOL KRATIMATA;So;0;L;;;;;N;;;;;
+1D033;BYZANTINE MUSICAL SYMBOL APESO EXO NEO;So;0;L;;;;;N;;;;;
+1D034;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION;So;0;L;;;;;N;;;;;
+1D035;BYZANTINE MUSICAL SYMBOL IMIFTHORA;So;0;L;;;;;N;;;;;
+1D036;BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION;So;0;L;;;;;N;;;;;
+1D037;BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON;So;0;L;;;;;N;;;;;
+1D038;BYZANTINE MUSICAL SYMBOL PELASTON;So;0;L;;;;;N;;;;;
+1D039;BYZANTINE MUSICAL SYMBOL PSIFISTON;So;0;L;;;;;N;;;;;
+1D03A;BYZANTINE MUSICAL SYMBOL KONTEVMA;So;0;L;;;;;N;;;;;
+1D03B;BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION;So;0;L;;;;;N;;;;;
+1D03C;BYZANTINE MUSICAL SYMBOL RAPISMA;So;0;L;;;;;N;;;;;
+1D03D;BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION;So;0;L;;;;;N;;;;;
+1D03E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION;So;0;L;;;;;N;;;;;
+1D03F;BYZANTINE MUSICAL SYMBOL ICHADIN;So;0;L;;;;;N;;;;;
+1D040;BYZANTINE MUSICAL SYMBOL NANA;So;0;L;;;;;N;;;;;
+1D041;BYZANTINE MUSICAL SYMBOL PETASMA;So;0;L;;;;;N;;;;;
+1D042;BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO;So;0;L;;;;;N;;;;;
+1D043;BYZANTINE MUSICAL SYMBOL TROMIKON ALLO;So;0;L;;;;;N;;;;;
+1D044;BYZANTINE MUSICAL SYMBOL STRAGGISMATA;So;0;L;;;;;N;;;;;
+1D045;BYZANTINE MUSICAL SYMBOL GRONTHISMATA;So;0;L;;;;;N;;;;;
+1D046;BYZANTINE MUSICAL SYMBOL ISON NEO;So;0;L;;;;;N;;;;;
+1D047;BYZANTINE MUSICAL SYMBOL OLIGON NEO;So;0;L;;;;;N;;;;;
+1D048;BYZANTINE MUSICAL SYMBOL OXEIA NEO;So;0;L;;;;;N;;;;;
+1D049;BYZANTINE MUSICAL SYMBOL PETASTI;So;0;L;;;;;N;;;;;
+1D04A;BYZANTINE MUSICAL SYMBOL KOUFISMA;So;0;L;;;;;N;;;;;
+1D04B;BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA;So;0;L;;;;;N;;;;;
+1D04C;BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA;So;0;L;;;;;N;;;;;
+1D04D;BYZANTINE MUSICAL SYMBOL PELASTON NEO;So;0;L;;;;;N;;;;;
+1D04E;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO;So;0;L;;;;;N;;;;;
+1D04F;BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO;So;0;L;;;;;N;;;;;
+1D050;BYZANTINE MUSICAL SYMBOL YPSILI;So;0;L;;;;;N;;;;;
+1D051;BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO;So;0;L;;;;;N;;;;;
+1D052;BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO;So;0;L;;;;;N;;;;;
+1D053;BYZANTINE MUSICAL SYMBOL YPORROI;So;0;L;;;;;N;;;;;
+1D054;BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON;So;0;L;;;;;N;;;;;
+1D055;BYZANTINE MUSICAL SYMBOL ELAFRON;So;0;L;;;;;N;;;;;
+1D056;BYZANTINE MUSICAL SYMBOL CHAMILI;So;0;L;;;;;N;;;;;
+1D057;BYZANTINE MUSICAL SYMBOL MIKRON ISON;So;0;L;;;;;N;;;;;
+1D058;BYZANTINE MUSICAL SYMBOL VAREIA NEO;So;0;L;;;;;N;;;;;
+1D059;BYZANTINE MUSICAL SYMBOL PIASMA NEO;So;0;L;;;;;N;;;;;
+1D05A;BYZANTINE MUSICAL SYMBOL PSIFISTON NEO;So;0;L;;;;;N;;;;;
+1D05B;BYZANTINE MUSICAL SYMBOL OMALON;So;0;L;;;;;N;;;;;
+1D05C;BYZANTINE MUSICAL SYMBOL ANTIKENOMA;So;0;L;;;;;N;;;;;
+1D05D;BYZANTINE MUSICAL SYMBOL LYGISMA;So;0;L;;;;;N;;;;;
+1D05E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO;So;0;L;;;;;N;;;;;
+1D05F;BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO;So;0;L;;;;;N;;;;;
+1D060;BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA;So;0;L;;;;;N;;;;;
+1D061;BYZANTINE MUSICAL SYMBOL KYLISMA;So;0;L;;;;;N;;;;;
+1D062;BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA;So;0;L;;;;;N;;;;;
+1D063;BYZANTINE MUSICAL SYMBOL TROMIKON NEO;So;0;L;;;;;N;;;;;
+1D064;BYZANTINE MUSICAL SYMBOL EKSTREPTON;So;0;L;;;;;N;;;;;
+1D065;BYZANTINE MUSICAL SYMBOL SYNAGMA NEO;So;0;L;;;;;N;;;;;
+1D066;BYZANTINE MUSICAL SYMBOL SYRMA;So;0;L;;;;;N;;;;;
+1D067;BYZANTINE MUSICAL SYMBOL CHOREVMA NEO;So;0;L;;;;;N;;;;;
+1D068;BYZANTINE MUSICAL SYMBOL EPEGERMA;So;0;L;;;;;N;;;;;
+1D069;BYZANTINE MUSICAL SYMBOL SEISMA NEO;So;0;L;;;;;N;;;;;
+1D06A;BYZANTINE MUSICAL SYMBOL XIRON KLASMA;So;0;L;;;;;N;;;;;
+1D06B;BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON;So;0;L;;;;;N;;;;;
+1D06C;BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA;So;0;L;;;;;N;;;;;
+1D06D;BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA;So;0;L;;;;;N;;;;;
+1D06E;BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA;So;0;L;;;;;N;;;;;
+1D06F;BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA;So;0;L;;;;;N;;;;;
+1D070;BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA;So;0;L;;;;;N;;;;;
+1D071;BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA;So;0;L;;;;;N;;;;;
+1D072;BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON;So;0;L;;;;;N;;;;;
+1D073;BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON;So;0;L;;;;;N;;;;;
+1D074;BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON;So;0;L;;;;;N;;;;;
+1D075;BYZANTINE MUSICAL SYMBOL OYRANISMA NEO;So;0;L;;;;;N;;;;;
+1D076;BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO;So;0;L;;;;;N;;;;;
+1D077;BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO;So;0;L;;;;;N;;;;;
+1D078;BYZANTINE MUSICAL SYMBOL THEMA APLOUN;So;0;L;;;;;N;;;;;
+1D079;BYZANTINE MUSICAL SYMBOL THES KAI APOTHES;So;0;L;;;;;N;;;;;
+1D07A;BYZANTINE MUSICAL SYMBOL KATAVASMA;So;0;L;;;;;N;;;;;
+1D07B;BYZANTINE MUSICAL SYMBOL ENDOFONON;So;0;L;;;;;N;;;;;
+1D07C;BYZANTINE MUSICAL SYMBOL YFEN KATO;So;0;L;;;;;N;;;;;
+1D07D;BYZANTINE MUSICAL SYMBOL YFEN ANO;So;0;L;;;;;N;;;;;
+1D07E;BYZANTINE MUSICAL SYMBOL STAVROS;So;0;L;;;;;N;;;;;
+1D07F;BYZANTINE MUSICAL SYMBOL KLASMA ANO;So;0;L;;;;;N;;;;;
+1D080;BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION;So;0;L;;;;;N;;;;;
+1D081;BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION;So;0;L;;;;;N;;;;;
+1D082;BYZANTINE MUSICAL SYMBOL KRATIMA ALLO;So;0;L;;;;;N;;;;;
+1D083;BYZANTINE MUSICAL SYMBOL KRATIMA NEO;So;0;L;;;;;N;;;;;
+1D084;BYZANTINE MUSICAL SYMBOL APODERMA NEO;So;0;L;;;;;N;;;;;
+1D085;BYZANTINE MUSICAL SYMBOL APLI;So;0;L;;;;;N;;;;;
+1D086;BYZANTINE MUSICAL SYMBOL DIPLI;So;0;L;;;;;N;;;;;
+1D087;BYZANTINE MUSICAL SYMBOL TRIPLI;So;0;L;;;;;N;;;;;
+1D088;BYZANTINE MUSICAL SYMBOL TETRAPLI;So;0;L;;;;;N;;;;;
+1D089;BYZANTINE MUSICAL SYMBOL KORONIS;So;0;L;;;;;N;;;;;
+1D08A;BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU;So;0;L;;;;;N;;;;;
+1D08B;BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON;So;0;L;;;;;N;;;;;
+1D08C;BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON;So;0;L;;;;;N;;;;;
+1D08D;BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON;So;0;L;;;;;N;;;;;
+1D08E;BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU;So;0;L;;;;;N;;;;;
+1D08F;BYZANTINE MUSICAL SYMBOL GORGON NEO ANO;So;0;L;;;;;N;;;;;
+1D090;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA;So;0;L;;;;;N;;;;;
+1D091;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;;
+1D092;BYZANTINE MUSICAL SYMBOL DIGORGON;So;0;L;;;;;N;;;;;
+1D093;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO;So;0;L;;;;;N;;;;;
+1D094;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO;So;0;L;;;;;N;;;;;
+1D095;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;;
+1D096;BYZANTINE MUSICAL SYMBOL TRIGORGON;So;0;L;;;;;N;;;;;
+1D097;BYZANTINE MUSICAL SYMBOL ARGON;So;0;L;;;;;N;;;;;
+1D098;BYZANTINE MUSICAL SYMBOL IMIDIARGON;So;0;L;;;;;N;;;;;
+1D099;BYZANTINE MUSICAL SYMBOL DIARGON;So;0;L;;;;;N;;;;;
+1D09A;BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI;So;0;L;;;;;N;;;;;
+1D09B;BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI;So;0;L;;;;;N;;;;;
+1D09C;BYZANTINE MUSICAL SYMBOL AGOGI ARGI;So;0;L;;;;;N;;;;;
+1D09D;BYZANTINE MUSICAL SYMBOL AGOGI METRIA;So;0;L;;;;;N;;;;;
+1D09E;BYZANTINE MUSICAL SYMBOL AGOGI MESI;So;0;L;;;;;N;;;;;
+1D09F;BYZANTINE MUSICAL SYMBOL AGOGI GORGI;So;0;L;;;;;N;;;;;
+1D0A0;BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI;So;0;L;;;;;N;;;;;
+1D0A1;BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI;So;0;L;;;;;N;;;;;
+1D0A2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS;So;0;L;;;;;N;;;;;
+1D0A3;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS;So;0;L;;;;;N;;;;;
+1D0A4;BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS;So;0;L;;;;;N;;;;;
+1D0A5;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS;So;0;L;;;;;N;;;;;
+1D0A6;BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS;So;0;L;;;;;N;;;;;
+1D0A7;BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS;So;0;L;;;;;N;;;;;
+1D0A8;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS;So;0;L;;;;;N;;;;;
+1D0A9;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS;So;0;L;;;;;N;;;;;
+1D0AA;BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS;So;0;L;;;;;N;;;;;
+1D0AB;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS;So;0;L;;;;;N;;;;;
+1D0AC;BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS;So;0;L;;;;;N;;;;;
+1D0AD;BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS;So;0;L;;;;;N;;;;;
+1D0AE;BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS;So;0;L;;;;;N;;;;;
+1D0AF;BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS;So;0;L;;;;;N;;;;;
+1D0B0;BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS;So;0;L;;;;;N;;;;;
+1D0B1;BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS;So;0;L;;;;;N;;;;;
+1D0B2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS;So;0;L;;;;;N;;;;;
+1D0B3;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS;So;0;L;;;;;N;;;;;
+1D0B4;BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN;So;0;L;;;;;N;;;;;
+1D0B5;BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN;So;0;L;;;;;N;;;;;
+1D0B6;BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU;So;0;L;;;;;N;;;;;
+1D0B7;BYZANTINE MUSICAL SYMBOL IMIFONON;So;0;L;;;;;N;;;;;
+1D0B8;BYZANTINE MUSICAL SYMBOL IMIFTHORON;So;0;L;;;;;N;;;;;
+1D0B9;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU;So;0;L;;;;;N;;;;;
+1D0BA;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA;So;0;L;;;;;N;;;;;
+1D0BB;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA;So;0;L;;;;;N;;;;;
+1D0BC;BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS;So;0;L;;;;;N;;;;;
+1D0BD;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI;So;0;L;;;;;N;;;;;
+1D0BE;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI;So;0;L;;;;;N;;;;;
+1D0BF;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE;So;0;L;;;;;N;;;;;
+1D0C0;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO;So;0;L;;;;;N;;;;;
+1D0C1;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO;So;0;L;;;;;N;;;;;
+1D0C2;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO;So;0;L;;;;;N;;;;;
+1D0C3;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS;So;0;L;;;;;N;;;;;
+1D0C4;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS;So;0;L;;;;;N;;;;;
+1D0C5;BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS;So;0;L;;;;;N;;;;;
+1D0C6;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI;So;0;L;;;;;N;;;;;
+1D0C7;BYZANTINE MUSICAL SYMBOL FTHORA NENANO;So;0;L;;;;;N;;;;;
+1D0C8;BYZANTINE MUSICAL SYMBOL CHROA ZYGOS;So;0;L;;;;;N;;;;;
+1D0C9;BYZANTINE MUSICAL SYMBOL CHROA KLITON;So;0;L;;;;;N;;;;;
+1D0CA;BYZANTINE MUSICAL SYMBOL CHROA SPATHI;So;0;L;;;;;N;;;;;
+1D0CB;BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION;So;0;L;;;;;N;;;;;
+1D0CC;BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA;So;0;L;;;;;N;;;;;
+1D0CD;BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION;So;0;L;;;;;N;;;;;
+1D0CE;BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION;So;0;L;;;;;N;;;;;
+1D0CF;BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION;So;0;L;;;;;N;;;;;
+1D0D0;BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;;
+1D0D1;BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;;
+1D0D2;BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;;
+1D0D3;BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;;
+1D0D4;BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;;
+1D0D5;BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;;
+1D0D6;BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;;
+1D0D7;BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;;
+1D0D8;BYZANTINE MUSICAL SYMBOL GENIKI DIESIS;So;0;L;;;;;N;;;;;
+1D0D9;BYZANTINE MUSICAL SYMBOL GENIKI YFESIS;So;0;L;;;;;N;;;;;
+1D0DA;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI;So;0;L;;;;;N;;;;;
+1D0DB;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI;So;0;L;;;;;N;;;;;
+1D0DC;BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI;So;0;L;;;;;N;;;;;
+1D0DD;BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS;So;0;L;;;;;N;;;;;
+1D0DE;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS;So;0;L;;;;;N;;;;;
+1D0DF;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU;So;0;L;;;;;N;;;;;
+1D0E0;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU;So;0;L;;;;;N;;;;;
+1D0E1;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU;So;0;L;;;;;N;;;;;
+1D0E2;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS;So;0;L;;;;;N;;;;;
+1D0E3;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU;So;0;L;;;;;N;;;;;
+1D0E4;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU;So;0;L;;;;;N;;;;;
+1D0E5;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU;So;0;L;;;;;N;;;;;
+1D0E6;BYZANTINE MUSICAL SYMBOL DIGRAMMA GG;So;0;L;;;;;N;;;;;
+1D0E7;BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU;So;0;L;;;;;N;;;;;
+1D0E8;BYZANTINE MUSICAL SYMBOL STIGMA;So;0;L;;;;;N;;;;;
+1D0E9;BYZANTINE MUSICAL SYMBOL ARKTIKO PA;So;0;L;;;;;N;;;;;
+1D0EA;BYZANTINE MUSICAL SYMBOL ARKTIKO VOU;So;0;L;;;;;N;;;;;
+1D0EB;BYZANTINE MUSICAL SYMBOL ARKTIKO GA;So;0;L;;;;;N;;;;;
+1D0EC;BYZANTINE MUSICAL SYMBOL ARKTIKO DI;So;0;L;;;;;N;;;;;
+1D0ED;BYZANTINE MUSICAL SYMBOL ARKTIKO KE;So;0;L;;;;;N;;;;;
+1D0EE;BYZANTINE MUSICAL SYMBOL ARKTIKO ZO;So;0;L;;;;;N;;;;;
+1D0EF;BYZANTINE MUSICAL SYMBOL ARKTIKO NI;So;0;L;;;;;N;;;;;
+1D0F0;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO;So;0;L;;;;;N;;;;;
+1D0F1;BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO;So;0;L;;;;;N;;;;;
+1D0F2;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO;So;0;L;;;;;N;;;;;
+1D0F3;BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO;So;0;L;;;;;N;;;;;
+1D0F4;BYZANTINE MUSICAL SYMBOL KLASMA KATO;So;0;L;;;;;N;;;;;
+1D0F5;BYZANTINE MUSICAL SYMBOL GORGON NEO KATO;So;0;L;;;;;N;;;;;
+1D100;MUSICAL SYMBOL SINGLE BARLINE;So;0;L;;;;;N;;;;;
+1D101;MUSICAL SYMBOL DOUBLE BARLINE;So;0;L;;;;;N;;;;;
+1D102;MUSICAL SYMBOL FINAL BARLINE;So;0;L;;;;;N;;;;;
+1D103;MUSICAL SYMBOL REVERSE FINAL BARLINE;So;0;L;;;;;N;;;;;
+1D104;MUSICAL SYMBOL DASHED BARLINE;So;0;L;;;;;N;;;;;
+1D105;MUSICAL SYMBOL SHORT BARLINE;So;0;L;;;;;N;;;;;
+1D106;MUSICAL SYMBOL LEFT REPEAT SIGN;So;0;L;;;;;N;;;;;
+1D107;MUSICAL SYMBOL RIGHT REPEAT SIGN;So;0;L;;;;;N;;;;;
+1D108;MUSICAL SYMBOL REPEAT DOTS;So;0;L;;;;;N;;;;;
+1D109;MUSICAL SYMBOL DAL SEGNO;So;0;L;;;;;N;;;;;
+1D10A;MUSICAL SYMBOL DA CAPO;So;0;L;;;;;N;;;;;
+1D10B;MUSICAL SYMBOL SEGNO;So;0;L;;;;;N;;;;;
+1D10C;MUSICAL SYMBOL CODA;So;0;L;;;;;N;;;;;
+1D10D;MUSICAL SYMBOL REPEATED FIGURE-1;So;0;L;;;;;N;;;;;
+1D10E;MUSICAL SYMBOL REPEATED FIGURE-2;So;0;L;;;;;N;;;;;
+1D10F;MUSICAL SYMBOL REPEATED FIGURE-3;So;0;L;;;;;N;;;;;
+1D110;MUSICAL SYMBOL FERMATA;So;0;L;;;;;N;;;;;
+1D111;MUSICAL SYMBOL FERMATA BELOW;So;0;L;;;;;N;;;;;
+1D112;MUSICAL SYMBOL BREATH MARK;So;0;L;;;;;N;;;;;
+1D113;MUSICAL SYMBOL CAESURA;So;0;L;;;;;N;;;;;
+1D114;MUSICAL SYMBOL BRACE;So;0;L;;;;;N;;;;;
+1D115;MUSICAL SYMBOL BRACKET;So;0;L;;;;;N;;;;;
+1D116;MUSICAL SYMBOL ONE-LINE STAFF;So;0;L;;;;;N;;;;;
+1D117;MUSICAL SYMBOL TWO-LINE STAFF;So;0;L;;;;;N;;;;;
+1D118;MUSICAL SYMBOL THREE-LINE STAFF;So;0;L;;;;;N;;;;;
+1D119;MUSICAL SYMBOL FOUR-LINE STAFF;So;0;L;;;;;N;;;;;
+1D11A;MUSICAL SYMBOL FIVE-LINE STAFF;So;0;L;;;;;N;;;;;
+1D11B;MUSICAL SYMBOL SIX-LINE STAFF;So;0;L;;;;;N;;;;;
+1D11C;MUSICAL SYMBOL SIX-STRING FRETBOARD;So;0;L;;;;;N;;;;;
+1D11D;MUSICAL SYMBOL FOUR-STRING FRETBOARD;So;0;L;;;;;N;;;;;
+1D11E;MUSICAL SYMBOL G CLEF;So;0;L;;;;;N;;;;;
+1D11F;MUSICAL SYMBOL G CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;;
+1D120;MUSICAL SYMBOL G CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;;
+1D121;MUSICAL SYMBOL C CLEF;So;0;L;;;;;N;;;;;
+1D122;MUSICAL SYMBOL F CLEF;So;0;L;;;;;N;;;;;
+1D123;MUSICAL SYMBOL F CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;;
+1D124;MUSICAL SYMBOL F CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;;
+1D125;MUSICAL SYMBOL DRUM CLEF-1;So;0;L;;;;;N;;;;;
+1D126;MUSICAL SYMBOL DRUM CLEF-2;So;0;L;;;;;N;;;;;
+1D129;MUSICAL SYMBOL MULTIPLE MEASURE REST;So;0;L;;;;;N;;;;;
+1D12A;MUSICAL SYMBOL DOUBLE SHARP;So;0;L;;;;;N;;;;;
+1D12B;MUSICAL SYMBOL DOUBLE FLAT;So;0;L;;;;;N;;;;;
+1D12C;MUSICAL SYMBOL FLAT UP;So;0;L;;;;;N;;;;;
+1D12D;MUSICAL SYMBOL FLAT DOWN;So;0;L;;;;;N;;;;;
+1D12E;MUSICAL SYMBOL NATURAL UP;So;0;L;;;;;N;;;;;
+1D12F;MUSICAL SYMBOL NATURAL DOWN;So;0;L;;;;;N;;;;;
+1D130;MUSICAL SYMBOL SHARP UP;So;0;L;;;;;N;;;;;
+1D131;MUSICAL SYMBOL SHARP DOWN;So;0;L;;;;;N;;;;;
+1D132;MUSICAL SYMBOL QUARTER TONE SHARP;So;0;L;;;;;N;;;;;
+1D133;MUSICAL SYMBOL QUARTER TONE FLAT;So;0;L;;;;;N;;;;;
+1D134;MUSICAL SYMBOL COMMON TIME;So;0;L;;;;;N;;;;;
+1D135;MUSICAL SYMBOL CUT TIME;So;0;L;;;;;N;;;;;
+1D136;MUSICAL SYMBOL OTTAVA ALTA;So;0;L;;;;;N;;;;;
+1D137;MUSICAL SYMBOL OTTAVA BASSA;So;0;L;;;;;N;;;;;
+1D138;MUSICAL SYMBOL QUINDICESIMA ALTA;So;0;L;;;;;N;;;;;
+1D139;MUSICAL SYMBOL QUINDICESIMA BASSA;So;0;L;;;;;N;;;;;
+1D13A;MUSICAL SYMBOL MULTI REST;So;0;L;;;;;N;;;;;
+1D13B;MUSICAL SYMBOL WHOLE REST;So;0;L;;;;;N;;;;;
+1D13C;MUSICAL SYMBOL HALF REST;So;0;L;;;;;N;;;;;
+1D13D;MUSICAL SYMBOL QUARTER REST;So;0;L;;;;;N;;;;;
+1D13E;MUSICAL SYMBOL EIGHTH REST;So;0;L;;;;;N;;;;;
+1D13F;MUSICAL SYMBOL SIXTEENTH REST;So;0;L;;;;;N;;;;;
+1D140;MUSICAL SYMBOL THIRTY-SECOND REST;So;0;L;;;;;N;;;;;
+1D141;MUSICAL SYMBOL SIXTY-FOURTH REST;So;0;L;;;;;N;;;;;
+1D142;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST;So;0;L;;;;;N;;;;;
+1D143;MUSICAL SYMBOL X NOTEHEAD;So;0;L;;;;;N;;;;;
+1D144;MUSICAL SYMBOL PLUS NOTEHEAD;So;0;L;;;;;N;;;;;
+1D145;MUSICAL SYMBOL CIRCLE X NOTEHEAD;So;0;L;;;;;N;;;;;
+1D146;MUSICAL SYMBOL SQUARE NOTEHEAD WHITE;So;0;L;;;;;N;;;;;
+1D147;MUSICAL SYMBOL SQUARE NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
+1D148;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE;So;0;L;;;;;N;;;;;
+1D149;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK;So;0;L;;;;;N;;;;;
+1D14A;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE;So;0;L;;;;;N;;;;;
+1D14B;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK;So;0;L;;;;;N;;;;;
+1D14C;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE;So;0;L;;;;;N;;;;;
+1D14D;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK;So;0;L;;;;;N;;;;;
+1D14E;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;;
+1D14F;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;;
+1D150;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE;So;0;L;;;;;N;;;;;
+1D151;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK;So;0;L;;;;;N;;;;;
+1D152;MUSICAL SYMBOL MOON NOTEHEAD WHITE;So;0;L;;;;;N;;;;;
+1D153;MUSICAL SYMBOL MOON NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
+1D154;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;;
+1D155;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;;
+1D156;MUSICAL SYMBOL PARENTHESIS NOTEHEAD;So;0;L;;;;;N;;;;;
+1D157;MUSICAL SYMBOL VOID NOTEHEAD;So;0;L;;;;;N;;;;;
+1D158;MUSICAL SYMBOL NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
+1D159;MUSICAL SYMBOL NULL NOTEHEAD;So;0;L;;;;;N;;;;;
+1D15A;MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE;So;0;L;;;;;N;;;;;
+1D15B;MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
+1D15C;MUSICAL SYMBOL BREVE;So;0;L;;;;;N;;;;;
+1D15D;MUSICAL SYMBOL WHOLE NOTE;So;0;L;;;;;N;;;;;
+1D15E;MUSICAL SYMBOL HALF NOTE;So;0;L;1D157 1D165;;;;N;;;;;
+1D15F;MUSICAL SYMBOL QUARTER NOTE;So;0;L;1D158 1D165;;;;N;;;;;
+1D160;MUSICAL SYMBOL EIGHTH NOTE;So;0;L;1D15F 1D16E;;;;N;;;;;
+1D161;MUSICAL SYMBOL SIXTEENTH NOTE;So;0;L;1D15F 1D16F;;;;N;;;;;
+1D162;MUSICAL SYMBOL THIRTY-SECOND NOTE;So;0;L;1D15F 1D170;;;;N;;;;;
+1D163;MUSICAL SYMBOL SIXTY-FOURTH NOTE;So;0;L;1D15F 1D171;;;;N;;;;;
+1D164;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE;So;0;L;1D15F 1D172;;;;N;;;;;
+1D165;MUSICAL SYMBOL COMBINING STEM;Mc;216;L;;;;;N;;;;;
+1D166;MUSICAL SYMBOL COMBINING SPRECHGESANG STEM;Mc;216;L;;;;;N;;;;;
+1D167;MUSICAL SYMBOL COMBINING TREMOLO-1;Mn;1;NSM;;;;;N;;;;;
+1D168;MUSICAL SYMBOL COMBINING TREMOLO-2;Mn;1;NSM;;;;;N;;;;;
+1D169;MUSICAL SYMBOL COMBINING TREMOLO-3;Mn;1;NSM;;;;;N;;;;;
+1D16A;MUSICAL SYMBOL FINGERED TREMOLO-1;So;0;L;;;;;N;;;;;
+1D16B;MUSICAL SYMBOL FINGERED TREMOLO-2;So;0;L;;;;;N;;;;;
+1D16C;MUSICAL SYMBOL FINGERED TREMOLO-3;So;0;L;;;;;N;;;;;
+1D16D;MUSICAL SYMBOL COMBINING AUGMENTATION DOT;Mc;226;L;;;;;N;;;;;
+1D16E;MUSICAL SYMBOL COMBINING FLAG-1;Mc;216;L;;;;;N;;;;;
+1D16F;MUSICAL SYMBOL COMBINING FLAG-2;Mc;216;L;;;;;N;;;;;
+1D170;MUSICAL SYMBOL COMBINING FLAG-3;Mc;216;L;;;;;N;;;;;
+1D171;MUSICAL SYMBOL COMBINING FLAG-4;Mc;216;L;;;;;N;;;;;
+1D172;MUSICAL SYMBOL COMBINING FLAG-5;Mc;216;L;;;;;N;;;;;
+1D173;MUSICAL SYMBOL BEGIN BEAM;Cf;0;BN;;;;;N;;;;;
+1D174;MUSICAL SYMBOL END BEAM;Cf;0;BN;;;;;N;;;;;
+1D175;MUSICAL SYMBOL BEGIN TIE;Cf;0;BN;;;;;N;;;;;
+1D176;MUSICAL SYMBOL END TIE;Cf;0;BN;;;;;N;;;;;
+1D177;MUSICAL SYMBOL BEGIN SLUR;Cf;0;BN;;;;;N;;;;;
+1D178;MUSICAL SYMBOL END SLUR;Cf;0;BN;;;;;N;;;;;
+1D179;MUSICAL SYMBOL BEGIN PHRASE;Cf;0;BN;;;;;N;;;;;
+1D17A;MUSICAL SYMBOL END PHRASE;Cf;0;BN;;;;;N;;;;;
+1D17B;MUSICAL SYMBOL COMBINING ACCENT;Mn;220;NSM;;;;;N;;;;;
+1D17C;MUSICAL SYMBOL COMBINING STACCATO;Mn;220;NSM;;;;;N;;;;;
+1D17D;MUSICAL SYMBOL COMBINING TENUTO;Mn;220;NSM;;;;;N;;;;;
+1D17E;MUSICAL SYMBOL COMBINING STACCATISSIMO;Mn;220;NSM;;;;;N;;;;;
+1D17F;MUSICAL SYMBOL COMBINING MARCATO;Mn;220;NSM;;;;;N;;;;;
+1D180;MUSICAL SYMBOL COMBINING MARCATO-STACCATO;Mn;220;NSM;;;;;N;;;;;
+1D181;MUSICAL SYMBOL COMBINING ACCENT-STACCATO;Mn;220;NSM;;;;;N;;;;;
+1D182;MUSICAL SYMBOL COMBINING LOURE;Mn;220;NSM;;;;;N;;;;;
+1D183;MUSICAL SYMBOL ARPEGGIATO UP;So;0;L;;;;;N;;;;;
+1D184;MUSICAL SYMBOL ARPEGGIATO DOWN;So;0;L;;;;;N;;;;;
+1D185;MUSICAL SYMBOL COMBINING DOIT;Mn;230;NSM;;;;;N;;;;;
+1D186;MUSICAL SYMBOL COMBINING RIP;Mn;230;NSM;;;;;N;;;;;
+1D187;MUSICAL SYMBOL COMBINING FLIP;Mn;230;NSM;;;;;N;;;;;
+1D188;MUSICAL SYMBOL COMBINING SMEAR;Mn;230;NSM;;;;;N;;;;;
+1D189;MUSICAL SYMBOL COMBINING BEND;Mn;230;NSM;;;;;N;;;;;
+1D18A;MUSICAL SYMBOL COMBINING DOUBLE TONGUE;Mn;220;NSM;;;;;N;;;;;
+1D18B;MUSICAL SYMBOL COMBINING TRIPLE TONGUE;Mn;220;NSM;;;;;N;;;;;
+1D18C;MUSICAL SYMBOL RINFORZANDO;So;0;L;;;;;N;;;;;
+1D18D;MUSICAL SYMBOL SUBITO;So;0;L;;;;;N;;;;;
+1D18E;MUSICAL SYMBOL Z;So;0;L;;;;;N;;;;;
+1D18F;MUSICAL SYMBOL PIANO;So;0;L;;;;;N;;;;;
+1D190;MUSICAL SYMBOL MEZZO;So;0;L;;;;;N;;;;;
+1D191;MUSICAL SYMBOL FORTE;So;0;L;;;;;N;;;;;
+1D192;MUSICAL SYMBOL CRESCENDO;So;0;L;;;;;N;;;;;
+1D193;MUSICAL SYMBOL DECRESCENDO;So;0;L;;;;;N;;;;;
+1D194;MUSICAL SYMBOL GRACE NOTE SLASH;So;0;L;;;;;N;;;;;
+1D195;MUSICAL SYMBOL GRACE NOTE NO SLASH;So;0;L;;;;;N;;;;;
+1D196;MUSICAL SYMBOL TR;So;0;L;;;;;N;;;;;
+1D197;MUSICAL SYMBOL TURN;So;0;L;;;;;N;;;;;
+1D198;MUSICAL SYMBOL INVERTED TURN;So;0;L;;;;;N;;;;;
+1D199;MUSICAL SYMBOL TURN SLASH;So;0;L;;;;;N;;;;;
+1D19A;MUSICAL SYMBOL TURN UP;So;0;L;;;;;N;;;;;
+1D19B;MUSICAL SYMBOL ORNAMENT STROKE-1;So;0;L;;;;;N;;;;;
+1D19C;MUSICAL SYMBOL ORNAMENT STROKE-2;So;0;L;;;;;N;;;;;
+1D19D;MUSICAL SYMBOL ORNAMENT STROKE-3;So;0;L;;;;;N;;;;;
+1D19E;MUSICAL SYMBOL ORNAMENT STROKE-4;So;0;L;;;;;N;;;;;
+1D19F;MUSICAL SYMBOL ORNAMENT STROKE-5;So;0;L;;;;;N;;;;;
+1D1A0;MUSICAL SYMBOL ORNAMENT STROKE-6;So;0;L;;;;;N;;;;;
+1D1A1;MUSICAL SYMBOL ORNAMENT STROKE-7;So;0;L;;;;;N;;;;;
+1D1A2;MUSICAL SYMBOL ORNAMENT STROKE-8;So;0;L;;;;;N;;;;;
+1D1A3;MUSICAL SYMBOL ORNAMENT STROKE-9;So;0;L;;;;;N;;;;;
+1D1A4;MUSICAL SYMBOL ORNAMENT STROKE-10;So;0;L;;;;;N;;;;;
+1D1A5;MUSICAL SYMBOL ORNAMENT STROKE-11;So;0;L;;;;;N;;;;;
+1D1A6;MUSICAL SYMBOL HAUPTSTIMME;So;0;L;;;;;N;;;;;
+1D1A7;MUSICAL SYMBOL NEBENSTIMME;So;0;L;;;;;N;;;;;
+1D1A8;MUSICAL SYMBOL END OF STIMME;So;0;L;;;;;N;;;;;
+1D1A9;MUSICAL SYMBOL DEGREE SLASH;So;0;L;;;;;N;;;;;
+1D1AA;MUSICAL SYMBOL COMBINING DOWN BOW;Mn;230;NSM;;;;;N;;;;;
+1D1AB;MUSICAL SYMBOL COMBINING UP BOW;Mn;230;NSM;;;;;N;;;;;
+1D1AC;MUSICAL SYMBOL COMBINING HARMONIC;Mn;230;NSM;;;;;N;;;;;
+1D1AD;MUSICAL SYMBOL COMBINING SNAP PIZZICATO;Mn;230;NSM;;;;;N;;;;;
+1D1AE;MUSICAL SYMBOL PEDAL MARK;So;0;L;;;;;N;;;;;
+1D1AF;MUSICAL SYMBOL PEDAL UP MARK;So;0;L;;;;;N;;;;;
+1D1B0;MUSICAL SYMBOL HALF PEDAL MARK;So;0;L;;;;;N;;;;;
+1D1B1;MUSICAL SYMBOL GLISSANDO UP;So;0;L;;;;;N;;;;;
+1D1B2;MUSICAL SYMBOL GLISSANDO DOWN;So;0;L;;;;;N;;;;;
+1D1B3;MUSICAL SYMBOL WITH FINGERNAILS;So;0;L;;;;;N;;;;;
+1D1B4;MUSICAL SYMBOL DAMP;So;0;L;;;;;N;;;;;
+1D1B5;MUSICAL SYMBOL DAMP ALL;So;0;L;;;;;N;;;;;
+1D1B6;MUSICAL SYMBOL MAXIMA;So;0;L;;;;;N;;;;;
+1D1B7;MUSICAL SYMBOL LONGA;So;0;L;;;;;N;;;;;
+1D1B8;MUSICAL SYMBOL BREVIS;So;0;L;;;;;N;;;;;
+1D1B9;MUSICAL SYMBOL SEMIBREVIS WHITE;So;0;L;;;;;N;;;;;
+1D1BA;MUSICAL SYMBOL SEMIBREVIS BLACK;So;0;L;;;;;N;;;;;
+1D1BB;MUSICAL SYMBOL MINIMA;So;0;L;1D1B9 1D165;;;;N;;;;;
+1D1BC;MUSICAL SYMBOL MINIMA BLACK;So;0;L;1D1BA 1D165;;;;N;;;;;
+1D1BD;MUSICAL SYMBOL SEMIMINIMA WHITE;So;0;L;1D1BB 1D16E;;;;N;;;;;
+1D1BE;MUSICAL SYMBOL SEMIMINIMA BLACK;So;0;L;1D1BC 1D16E;;;;N;;;;;
+1D1BF;MUSICAL SYMBOL FUSA WHITE;So;0;L;1D1BB 1D16F;;;;N;;;;;
+1D1C0;MUSICAL SYMBOL FUSA BLACK;So;0;L;1D1BC 1D16F;;;;N;;;;;
+1D1C1;MUSICAL SYMBOL LONGA PERFECTA REST;So;0;L;;;;;N;;;;;
+1D1C2;MUSICAL SYMBOL LONGA IMPERFECTA REST;So;0;L;;;;;N;;;;;
+1D1C3;MUSICAL SYMBOL BREVIS REST;So;0;L;;;;;N;;;;;
+1D1C4;MUSICAL SYMBOL SEMIBREVIS REST;So;0;L;;;;;N;;;;;
+1D1C5;MUSICAL SYMBOL MINIMA REST;So;0;L;;;;;N;;;;;
+1D1C6;MUSICAL SYMBOL SEMIMINIMA REST;So;0;L;;;;;N;;;;;
+1D1C7;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;;
+1D1C8;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;;
+1D1C9;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;;
+1D1CA;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;;
+1D1CB;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;;
+1D1CC;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;;
+1D1CD;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-2;So;0;L;;;;;N;;;;;
+1D1CE;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-3;So;0;L;;;;;N;;;;;
+1D1CF;MUSICAL SYMBOL CROIX;So;0;L;;;;;N;;;;;
+1D1D0;MUSICAL SYMBOL GREGORIAN C CLEF;So;0;L;;;;;N;;;;;
+1D1D1;MUSICAL SYMBOL GREGORIAN F CLEF;So;0;L;;;;;N;;;;;
+1D1D2;MUSICAL SYMBOL SQUARE B;So;0;L;;;;;N;;;;;
+1D1D3;MUSICAL SYMBOL VIRGA;So;0;L;;;;;N;;;;;
+1D1D4;MUSICAL SYMBOL PODATUS;So;0;L;;;;;N;;;;;
+1D1D5;MUSICAL SYMBOL CLIVIS;So;0;L;;;;;N;;;;;
+1D1D6;MUSICAL SYMBOL SCANDICUS;So;0;L;;;;;N;;;;;
+1D1D7;MUSICAL SYMBOL CLIMACUS;So;0;L;;;;;N;;;;;
+1D1D8;MUSICAL SYMBOL TORCULUS;So;0;L;;;;;N;;;;;
+1D1D9;MUSICAL SYMBOL PORRECTUS;So;0;L;;;;;N;;;;;
+1D1DA;MUSICAL SYMBOL PORRECTUS FLEXUS;So;0;L;;;;;N;;;;;
+1D1DB;MUSICAL SYMBOL SCANDICUS FLEXUS;So;0;L;;;;;N;;;;;
+1D1DC;MUSICAL SYMBOL TORCULUS RESUPINUS;So;0;L;;;;;N;;;;;
+1D1DD;MUSICAL SYMBOL PES SUBPUNCTIS;So;0;L;;;;;N;;;;;
+1D1DE;MUSICAL SYMBOL KIEVAN C CLEF;So;0;L;;;;;N;;;;;
+1D1DF;MUSICAL SYMBOL KIEVAN END OF PIECE;So;0;L;;;;;N;;;;;
+1D1E0;MUSICAL SYMBOL KIEVAN FINAL NOTE;So;0;L;;;;;N;;;;;
+1D1E1;MUSICAL SYMBOL KIEVAN RECITATIVE MARK;So;0;L;;;;;N;;;;;
+1D1E2;MUSICAL SYMBOL KIEVAN WHOLE NOTE;So;0;L;;;;;N;;;;;
+1D1E3;MUSICAL SYMBOL KIEVAN HALF NOTE;So;0;L;;;;;N;;;;;
+1D1E4;MUSICAL SYMBOL KIEVAN QUARTER NOTE STEM DOWN;So;0;L;;;;;N;;;;;
+1D1E5;MUSICAL SYMBOL KIEVAN QUARTER NOTE STEM UP;So;0;L;;;;;N;;;;;
+1D1E6;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM DOWN;So;0;L;;;;;N;;;;;
+1D1E7;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM UP;So;0;L;;;;;N;;;;;
+1D1E8;MUSICAL SYMBOL KIEVAN FLAT SIGN;So;0;L;;;;;N;;;;;
+1D200;GREEK VOCAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;;
+1D201;GREEK VOCAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;;
+1D202;GREEK VOCAL NOTATION SYMBOL-3;So;0;ON;;;;;N;;;;;
+1D203;GREEK VOCAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;;
+1D204;GREEK VOCAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;;
+1D205;GREEK VOCAL NOTATION SYMBOL-6;So;0;ON;;;;;N;;;;;
+1D206;GREEK VOCAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;;
+1D207;GREEK VOCAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;;
+1D208;GREEK VOCAL NOTATION SYMBOL-9;So;0;ON;;;;;N;;;;;
+1D209;GREEK VOCAL NOTATION SYMBOL-10;So;0;ON;;;;;N;;;;;
+1D20A;GREEK VOCAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;;
+1D20B;GREEK VOCAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;;
+1D20C;GREEK VOCAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;;
+1D20D;GREEK VOCAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;;
+1D20E;GREEK VOCAL NOTATION SYMBOL-15;So;0;ON;;;;;N;;;;;
+1D20F;GREEK VOCAL NOTATION SYMBOL-16;So;0;ON;;;;;N;;;;;
+1D210;GREEK VOCAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;;
+1D211;GREEK VOCAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;;
+1D212;GREEK VOCAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;;
+1D213;GREEK VOCAL NOTATION SYMBOL-20;So;0;ON;;;;;N;;;;;
+1D214;GREEK VOCAL NOTATION SYMBOL-21;So;0;ON;;;;;N;;;;;
+1D215;GREEK VOCAL NOTATION SYMBOL-22;So;0;ON;;;;;N;;;;;
+1D216;GREEK VOCAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;;
+1D217;GREEK VOCAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;;
+1D218;GREEK VOCAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;;
+1D219;GREEK VOCAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;;
+1D21A;GREEK VOCAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;;
+1D21B;GREEK VOCAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;;
+1D21C;GREEK VOCAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;;
+1D21D;GREEK INSTRUMENTAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;;
+1D21E;GREEK INSTRUMENTAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;;
+1D21F;GREEK INSTRUMENTAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;;
+1D220;GREEK INSTRUMENTAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;;
+1D221;GREEK INSTRUMENTAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;;
+1D222;GREEK INSTRUMENTAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;;
+1D223;GREEK INSTRUMENTAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;;
+1D224;GREEK INSTRUMENTAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;;
+1D225;GREEK INSTRUMENTAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;;
+1D226;GREEK INSTRUMENTAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;;
+1D227;GREEK INSTRUMENTAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;;
+1D228;GREEK INSTRUMENTAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;;
+1D229;GREEK INSTRUMENTAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;;
+1D22A;GREEK INSTRUMENTAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;;
+1D22B;GREEK INSTRUMENTAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;;
+1D22C;GREEK INSTRUMENTAL NOTATION SYMBOL-25;So;0;ON;;;;;N;;;;;
+1D22D;GREEK INSTRUMENTAL NOTATION SYMBOL-26;So;0;ON;;;;;N;;;;;
+1D22E;GREEK INSTRUMENTAL NOTATION SYMBOL-27;So;0;ON;;;;;N;;;;;
+1D22F;GREEK INSTRUMENTAL NOTATION SYMBOL-29;So;0;ON;;;;;N;;;;;
+1D230;GREEK INSTRUMENTAL NOTATION SYMBOL-30;So;0;ON;;;;;N;;;;;
+1D231;GREEK INSTRUMENTAL NOTATION SYMBOL-32;So;0;ON;;;;;N;;;;;
+1D232;GREEK INSTRUMENTAL NOTATION SYMBOL-36;So;0;ON;;;;;N;;;;;
+1D233;GREEK INSTRUMENTAL NOTATION SYMBOL-37;So;0;ON;;;;;N;;;;;
+1D234;GREEK INSTRUMENTAL NOTATION SYMBOL-38;So;0;ON;;;;;N;;;;;
+1D235;GREEK INSTRUMENTAL NOTATION SYMBOL-39;So;0;ON;;;;;N;;;;;
+1D236;GREEK INSTRUMENTAL NOTATION SYMBOL-40;So;0;ON;;;;;N;;;;;
+1D237;GREEK INSTRUMENTAL NOTATION SYMBOL-42;So;0;ON;;;;;N;;;;;
+1D238;GREEK INSTRUMENTAL NOTATION SYMBOL-43;So;0;ON;;;;;N;;;;;
+1D239;GREEK INSTRUMENTAL NOTATION SYMBOL-45;So;0;ON;;;;;N;;;;;
+1D23A;GREEK INSTRUMENTAL NOTATION SYMBOL-47;So;0;ON;;;;;N;;;;;
+1D23B;GREEK INSTRUMENTAL NOTATION SYMBOL-48;So;0;ON;;;;;N;;;;;
+1D23C;GREEK INSTRUMENTAL NOTATION SYMBOL-49;So;0;ON;;;;;N;;;;;
+1D23D;GREEK INSTRUMENTAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;;
+1D23E;GREEK INSTRUMENTAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;;
+1D23F;GREEK INSTRUMENTAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;;
+1D240;GREEK INSTRUMENTAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;;
+1D241;GREEK INSTRUMENTAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;;
+1D242;COMBINING GREEK MUSICAL TRISEME;Mn;230;NSM;;;;;N;;;;;
+1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;;
+1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;;
+1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;;
+1D300;MONOGRAM FOR EARTH;So;0;ON;;;;;N;;;;;
+1D301;DIGRAM FOR HEAVENLY EARTH;So;0;ON;;;;;N;;;;;
+1D302;DIGRAM FOR HUMAN EARTH;So;0;ON;;;;;N;;;;;
+1D303;DIGRAM FOR EARTHLY HEAVEN;So;0;ON;;;;;N;;;;;
+1D304;DIGRAM FOR EARTHLY HUMAN;So;0;ON;;;;;N;;;;;
+1D305;DIGRAM FOR EARTH;So;0;ON;;;;;N;;;;;
+1D306;TETRAGRAM FOR CENTRE;So;0;ON;;;;;N;;;;;
+1D307;TETRAGRAM FOR FULL CIRCLE;So;0;ON;;;;;N;;;;;
+1D308;TETRAGRAM FOR MIRED;So;0;ON;;;;;N;;;;;
+1D309;TETRAGRAM FOR BARRIER;So;0;ON;;;;;N;;;;;
+1D30A;TETRAGRAM FOR KEEPING SMALL;So;0;ON;;;;;N;;;;;
+1D30B;TETRAGRAM FOR CONTRARIETY;So;0;ON;;;;;N;;;;;
+1D30C;TETRAGRAM FOR ASCENT;So;0;ON;;;;;N;;;;;
+1D30D;TETRAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;;
+1D30E;TETRAGRAM FOR BRANCHING OUT;So;0;ON;;;;;N;;;;;
+1D30F;TETRAGRAM FOR DEFECTIVENESS OR DISTORTION;So;0;ON;;;;;N;;;;;
+1D310;TETRAGRAM FOR DIVERGENCE;So;0;ON;;;;;N;;;;;
+1D311;TETRAGRAM FOR YOUTHFULNESS;So;0;ON;;;;;N;;;;;
+1D312;TETRAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;;
+1D313;TETRAGRAM FOR PENETRATION;So;0;ON;;;;;N;;;;;
+1D314;TETRAGRAM FOR REACH;So;0;ON;;;;;N;;;;;
+1D315;TETRAGRAM FOR CONTACT;So;0;ON;;;;;N;;;;;
+1D316;TETRAGRAM FOR HOLDING BACK;So;0;ON;;;;;N;;;;;
+1D317;TETRAGRAM FOR WAITING;So;0;ON;;;;;N;;;;;
+1D318;TETRAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;;
+1D319;TETRAGRAM FOR ADVANCE;So;0;ON;;;;;N;;;;;
+1D31A;TETRAGRAM FOR RELEASE;So;0;ON;;;;;N;;;;;
+1D31B;TETRAGRAM FOR RESISTANCE;So;0;ON;;;;;N;;;;;
+1D31C;TETRAGRAM FOR EASE;So;0;ON;;;;;N;;;;;
+1D31D;TETRAGRAM FOR JOY;So;0;ON;;;;;N;;;;;
+1D31E;TETRAGRAM FOR CONTENTION;So;0;ON;;;;;N;;;;;
+1D31F;TETRAGRAM FOR ENDEAVOUR;So;0;ON;;;;;N;;;;;
+1D320;TETRAGRAM FOR DUTIES;So;0;ON;;;;;N;;;;;
+1D321;TETRAGRAM FOR CHANGE;So;0;ON;;;;;N;;;;;
+1D322;TETRAGRAM FOR DECISIVENESS;So;0;ON;;;;;N;;;;;
+1D323;TETRAGRAM FOR BOLD RESOLUTION;So;0;ON;;;;;N;;;;;
+1D324;TETRAGRAM FOR PACKING;So;0;ON;;;;;N;;;;;
+1D325;TETRAGRAM FOR LEGION;So;0;ON;;;;;N;;;;;
+1D326;TETRAGRAM FOR CLOSENESS;So;0;ON;;;;;N;;;;;
+1D327;TETRAGRAM FOR KINSHIP;So;0;ON;;;;;N;;;;;
+1D328;TETRAGRAM FOR GATHERING;So;0;ON;;;;;N;;;;;
+1D329;TETRAGRAM FOR STRENGTH;So;0;ON;;;;;N;;;;;
+1D32A;TETRAGRAM FOR PURITY;So;0;ON;;;;;N;;;;;
+1D32B;TETRAGRAM FOR FULLNESS;So;0;ON;;;;;N;;;;;
+1D32C;TETRAGRAM FOR RESIDENCE;So;0;ON;;;;;N;;;;;
+1D32D;TETRAGRAM FOR LAW OR MODEL;So;0;ON;;;;;N;;;;;
+1D32E;TETRAGRAM FOR RESPONSE;So;0;ON;;;;;N;;;;;
+1D32F;TETRAGRAM FOR GOING TO MEET;So;0;ON;;;;;N;;;;;
+1D330;TETRAGRAM FOR ENCOUNTERS;So;0;ON;;;;;N;;;;;
+1D331;TETRAGRAM FOR STOVE;So;0;ON;;;;;N;;;;;
+1D332;TETRAGRAM FOR GREATNESS;So;0;ON;;;;;N;;;;;
+1D333;TETRAGRAM FOR ENLARGEMENT;So;0;ON;;;;;N;;;;;
+1D334;TETRAGRAM FOR PATTERN;So;0;ON;;;;;N;;;;;
+1D335;TETRAGRAM FOR RITUAL;So;0;ON;;;;;N;;;;;
+1D336;TETRAGRAM FOR FLIGHT;So;0;ON;;;;;N;;;;;
+1D337;TETRAGRAM FOR VASTNESS OR WASTING;So;0;ON;;;;;N;;;;;
+1D338;TETRAGRAM FOR CONSTANCY;So;0;ON;;;;;N;;;;;
+1D339;TETRAGRAM FOR MEASURE;So;0;ON;;;;;N;;;;;
+1D33A;TETRAGRAM FOR ETERNITY;So;0;ON;;;;;N;;;;;
+1D33B;TETRAGRAM FOR UNITY;So;0;ON;;;;;N;;;;;
+1D33C;TETRAGRAM FOR DIMINISHMENT;So;0;ON;;;;;N;;;;;
+1D33D;TETRAGRAM FOR CLOSED MOUTH;So;0;ON;;;;;N;;;;;
+1D33E;TETRAGRAM FOR GUARDEDNESS;So;0;ON;;;;;N;;;;;
+1D33F;TETRAGRAM FOR GATHERING IN;So;0;ON;;;;;N;;;;;
+1D340;TETRAGRAM FOR MASSING;So;0;ON;;;;;N;;;;;
+1D341;TETRAGRAM FOR ACCUMULATION;So;0;ON;;;;;N;;;;;
+1D342;TETRAGRAM FOR EMBELLISHMENT;So;0;ON;;;;;N;;;;;
+1D343;TETRAGRAM FOR DOUBT;So;0;ON;;;;;N;;;;;
+1D344;TETRAGRAM FOR WATCH;So;0;ON;;;;;N;;;;;
+1D345;TETRAGRAM FOR SINKING;So;0;ON;;;;;N;;;;;
+1D346;TETRAGRAM FOR INNER;So;0;ON;;;;;N;;;;;
+1D347;TETRAGRAM FOR DEPARTURE;So;0;ON;;;;;N;;;;;
+1D348;TETRAGRAM FOR DARKENING;So;0;ON;;;;;N;;;;;
+1D349;TETRAGRAM FOR DIMMING;So;0;ON;;;;;N;;;;;
+1D34A;TETRAGRAM FOR EXHAUSTION;So;0;ON;;;;;N;;;;;
+1D34B;TETRAGRAM FOR SEVERANCE;So;0;ON;;;;;N;;;;;
+1D34C;TETRAGRAM FOR STOPPAGE;So;0;ON;;;;;N;;;;;
+1D34D;TETRAGRAM FOR HARDNESS;So;0;ON;;;;;N;;;;;
+1D34E;TETRAGRAM FOR COMPLETION;So;0;ON;;;;;N;;;;;
+1D34F;TETRAGRAM FOR CLOSURE;So;0;ON;;;;;N;;;;;
+1D350;TETRAGRAM FOR FAILURE;So;0;ON;;;;;N;;;;;
+1D351;TETRAGRAM FOR AGGRAVATION;So;0;ON;;;;;N;;;;;
+1D352;TETRAGRAM FOR COMPLIANCE;So;0;ON;;;;;N;;;;;
+1D353;TETRAGRAM FOR ON THE VERGE;So;0;ON;;;;;N;;;;;
+1D354;TETRAGRAM FOR DIFFICULTIES;So;0;ON;;;;;N;;;;;
+1D355;TETRAGRAM FOR LABOURING;So;0;ON;;;;;N;;;;;
+1D356;TETRAGRAM FOR FOSTERING;So;0;ON;;;;;N;;;;;
+1D360;COUNTING ROD UNIT DIGIT ONE;No;0;L;;;;1;N;;;;;
+1D361;COUNTING ROD UNIT DIGIT TWO;No;0;L;;;;2;N;;;;;
+1D362;COUNTING ROD UNIT DIGIT THREE;No;0;L;;;;3;N;;;;;
+1D363;COUNTING ROD UNIT DIGIT FOUR;No;0;L;;;;4;N;;;;;
+1D364;COUNTING ROD UNIT DIGIT FIVE;No;0;L;;;;5;N;;;;;
+1D365;COUNTING ROD UNIT DIGIT SIX;No;0;L;;;;6;N;;;;;
+1D366;COUNTING ROD UNIT DIGIT SEVEN;No;0;L;;;;7;N;;;;;
+1D367;COUNTING ROD UNIT DIGIT EIGHT;No;0;L;;;;8;N;;;;;
+1D368;COUNTING ROD UNIT DIGIT NINE;No;0;L;;;;9;N;;;;;
+1D369;COUNTING ROD TENS DIGIT ONE;No;0;L;;;;10;N;;;;;
+1D36A;COUNTING ROD TENS DIGIT TWO;No;0;L;;;;20;N;;;;;
+1D36B;COUNTING ROD TENS DIGIT THREE;No;0;L;;;;30;N;;;;;
+1D36C;COUNTING ROD TENS DIGIT FOUR;No;0;L;;;;40;N;;;;;
+1D36D;COUNTING ROD TENS DIGIT FIVE;No;0;L;;;;50;N;;;;;
+1D36E;COUNTING ROD TENS DIGIT SIX;No;0;L;;;;60;N;;;;;
+1D36F;COUNTING ROD TENS DIGIT SEVEN;No;0;L;;;;70;N;;;;;
+1D370;COUNTING ROD TENS DIGIT EIGHT;No;0;L;;;;80;N;;;;;
+1D371;COUNTING ROD TENS DIGIT NINE;No;0;L;;;;90;N;;;;;
+1D400;MATHEMATICAL BOLD CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D401;MATHEMATICAL BOLD CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D402;MATHEMATICAL BOLD CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D403;MATHEMATICAL BOLD CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D404;MATHEMATICAL BOLD CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D405;MATHEMATICAL BOLD CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D406;MATHEMATICAL BOLD CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D407;MATHEMATICAL BOLD CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D408;MATHEMATICAL BOLD CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D409;MATHEMATICAL BOLD CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D40A;MATHEMATICAL BOLD CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D40B;MATHEMATICAL BOLD CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D40C;MATHEMATICAL BOLD CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D40D;MATHEMATICAL BOLD CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D40E;MATHEMATICAL BOLD CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D40F;MATHEMATICAL BOLD CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D410;MATHEMATICAL BOLD CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D411;MATHEMATICAL BOLD CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D412;MATHEMATICAL BOLD CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D413;MATHEMATICAL BOLD CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D414;MATHEMATICAL BOLD CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D415;MATHEMATICAL BOLD CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D416;MATHEMATICAL BOLD CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D417;MATHEMATICAL BOLD CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D418;MATHEMATICAL BOLD CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D419;MATHEMATICAL BOLD CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D41A;MATHEMATICAL BOLD SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D41B;MATHEMATICAL BOLD SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D41C;MATHEMATICAL BOLD SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D41D;MATHEMATICAL BOLD SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D41E;MATHEMATICAL BOLD SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D41F;MATHEMATICAL BOLD SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D420;MATHEMATICAL BOLD SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D421;MATHEMATICAL BOLD SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D422;MATHEMATICAL BOLD SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D423;MATHEMATICAL BOLD SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D424;MATHEMATICAL BOLD SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D425;MATHEMATICAL BOLD SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D426;MATHEMATICAL BOLD SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D427;MATHEMATICAL BOLD SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D428;MATHEMATICAL BOLD SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D429;MATHEMATICAL BOLD SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D42A;MATHEMATICAL BOLD SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D42B;MATHEMATICAL BOLD SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D42C;MATHEMATICAL BOLD SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D42D;MATHEMATICAL BOLD SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D42E;MATHEMATICAL BOLD SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D42F;MATHEMATICAL BOLD SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D430;MATHEMATICAL BOLD SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D431;MATHEMATICAL BOLD SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D432;MATHEMATICAL BOLD SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D433;MATHEMATICAL BOLD SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D434;MATHEMATICAL ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D435;MATHEMATICAL ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D436;MATHEMATICAL ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D437;MATHEMATICAL ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D438;MATHEMATICAL ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D439;MATHEMATICAL ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D43A;MATHEMATICAL ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D43B;MATHEMATICAL ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D43C;MATHEMATICAL ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D43D;MATHEMATICAL ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D43E;MATHEMATICAL ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D43F;MATHEMATICAL ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D440;MATHEMATICAL ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D441;MATHEMATICAL ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D442;MATHEMATICAL ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D443;MATHEMATICAL ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D444;MATHEMATICAL ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D445;MATHEMATICAL ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D446;MATHEMATICAL ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D447;MATHEMATICAL ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D448;MATHEMATICAL ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D449;MATHEMATICAL ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D44A;MATHEMATICAL ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D44B;MATHEMATICAL ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D44C;MATHEMATICAL ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D44D;MATHEMATICAL ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D44E;MATHEMATICAL ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D44F;MATHEMATICAL ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D450;MATHEMATICAL ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D451;MATHEMATICAL ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D452;MATHEMATICAL ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D453;MATHEMATICAL ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D454;MATHEMATICAL ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D456;MATHEMATICAL ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D457;MATHEMATICAL ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D458;MATHEMATICAL ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D459;MATHEMATICAL ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D45A;MATHEMATICAL ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D45B;MATHEMATICAL ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D45C;MATHEMATICAL ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D45D;MATHEMATICAL ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D45E;MATHEMATICAL ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D45F;MATHEMATICAL ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D460;MATHEMATICAL ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D461;MATHEMATICAL ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D462;MATHEMATICAL ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D463;MATHEMATICAL ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D464;MATHEMATICAL ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D465;MATHEMATICAL ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D466;MATHEMATICAL ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D467;MATHEMATICAL ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D468;MATHEMATICAL BOLD ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D469;MATHEMATICAL BOLD ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D46A;MATHEMATICAL BOLD ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D46B;MATHEMATICAL BOLD ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D46C;MATHEMATICAL BOLD ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D46D;MATHEMATICAL BOLD ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D46E;MATHEMATICAL BOLD ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D46F;MATHEMATICAL BOLD ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D470;MATHEMATICAL BOLD ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D471;MATHEMATICAL BOLD ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D472;MATHEMATICAL BOLD ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D473;MATHEMATICAL BOLD ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D474;MATHEMATICAL BOLD ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D475;MATHEMATICAL BOLD ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D476;MATHEMATICAL BOLD ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D477;MATHEMATICAL BOLD ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D478;MATHEMATICAL BOLD ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D479;MATHEMATICAL BOLD ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D47A;MATHEMATICAL BOLD ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D47B;MATHEMATICAL BOLD ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D47C;MATHEMATICAL BOLD ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D47D;MATHEMATICAL BOLD ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D47E;MATHEMATICAL BOLD ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D47F;MATHEMATICAL BOLD ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D480;MATHEMATICAL BOLD ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D481;MATHEMATICAL BOLD ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D482;MATHEMATICAL BOLD ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D483;MATHEMATICAL BOLD ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D484;MATHEMATICAL BOLD ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D485;MATHEMATICAL BOLD ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D486;MATHEMATICAL BOLD ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D487;MATHEMATICAL BOLD ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D488;MATHEMATICAL BOLD ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D489;MATHEMATICAL BOLD ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D48A;MATHEMATICAL BOLD ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D48B;MATHEMATICAL BOLD ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D48C;MATHEMATICAL BOLD ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D48D;MATHEMATICAL BOLD ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D48E;MATHEMATICAL BOLD ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D48F;MATHEMATICAL BOLD ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D490;MATHEMATICAL BOLD ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D491;MATHEMATICAL BOLD ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D492;MATHEMATICAL BOLD ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D493;MATHEMATICAL BOLD ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D494;MATHEMATICAL BOLD ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D495;MATHEMATICAL BOLD ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D496;MATHEMATICAL BOLD ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D497;MATHEMATICAL BOLD ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D498;MATHEMATICAL BOLD ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D499;MATHEMATICAL BOLD ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D49A;MATHEMATICAL BOLD ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D49B;MATHEMATICAL BOLD ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D49C;MATHEMATICAL SCRIPT CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D49E;MATHEMATICAL SCRIPT CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D49F;MATHEMATICAL SCRIPT CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D4A2;MATHEMATICAL SCRIPT CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D4A5;MATHEMATICAL SCRIPT CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D4A6;MATHEMATICAL SCRIPT CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D4A9;MATHEMATICAL SCRIPT CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D4AA;MATHEMATICAL SCRIPT CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D4AB;MATHEMATICAL SCRIPT CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D4AC;MATHEMATICAL SCRIPT CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D4AE;MATHEMATICAL SCRIPT CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D4AF;MATHEMATICAL SCRIPT CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D4B0;MATHEMATICAL SCRIPT CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D4B1;MATHEMATICAL SCRIPT CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D4B2;MATHEMATICAL SCRIPT CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D4B3;MATHEMATICAL SCRIPT CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D4B4;MATHEMATICAL SCRIPT CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D4B5;MATHEMATICAL SCRIPT CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D4B6;MATHEMATICAL SCRIPT SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D4B7;MATHEMATICAL SCRIPT SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D4B8;MATHEMATICAL SCRIPT SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D4B9;MATHEMATICAL SCRIPT SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D4BB;MATHEMATICAL SCRIPT SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D4BD;MATHEMATICAL SCRIPT SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D4BE;MATHEMATICAL SCRIPT SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D4BF;MATHEMATICAL SCRIPT SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D4C0;MATHEMATICAL SCRIPT SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D4C1;MATHEMATICAL SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D4C2;MATHEMATICAL SCRIPT SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D4C3;MATHEMATICAL SCRIPT SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D4C5;MATHEMATICAL SCRIPT SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D4C6;MATHEMATICAL SCRIPT SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D4C7;MATHEMATICAL SCRIPT SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D4C8;MATHEMATICAL SCRIPT SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D4C9;MATHEMATICAL SCRIPT SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D4CA;MATHEMATICAL SCRIPT SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D4CB;MATHEMATICAL SCRIPT SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D4CC;MATHEMATICAL SCRIPT SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D4CD;MATHEMATICAL SCRIPT SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D4CE;MATHEMATICAL SCRIPT SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D4CF;MATHEMATICAL SCRIPT SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D4D0;MATHEMATICAL BOLD SCRIPT CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D4D1;MATHEMATICAL BOLD SCRIPT CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D4D2;MATHEMATICAL BOLD SCRIPT CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D4D3;MATHEMATICAL BOLD SCRIPT CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D4D4;MATHEMATICAL BOLD SCRIPT CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D4D5;MATHEMATICAL BOLD SCRIPT CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D4D6;MATHEMATICAL BOLD SCRIPT CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D4D7;MATHEMATICAL BOLD SCRIPT CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D4D8;MATHEMATICAL BOLD SCRIPT CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D4D9;MATHEMATICAL BOLD SCRIPT CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D4DA;MATHEMATICAL BOLD SCRIPT CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D4DB;MATHEMATICAL BOLD SCRIPT CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D4DC;MATHEMATICAL BOLD SCRIPT CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D4DD;MATHEMATICAL BOLD SCRIPT CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D4DE;MATHEMATICAL BOLD SCRIPT CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D4DF;MATHEMATICAL BOLD SCRIPT CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D4E0;MATHEMATICAL BOLD SCRIPT CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D4E1;MATHEMATICAL BOLD SCRIPT CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D4E2;MATHEMATICAL BOLD SCRIPT CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D4E3;MATHEMATICAL BOLD SCRIPT CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D4E4;MATHEMATICAL BOLD SCRIPT CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D4E5;MATHEMATICAL BOLD SCRIPT CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D4E6;MATHEMATICAL BOLD SCRIPT CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D4E7;MATHEMATICAL BOLD SCRIPT CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D4E8;MATHEMATICAL BOLD SCRIPT CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D4E9;MATHEMATICAL BOLD SCRIPT CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D4EA;MATHEMATICAL BOLD SCRIPT SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D4EB;MATHEMATICAL BOLD SCRIPT SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D4EC;MATHEMATICAL BOLD SCRIPT SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D4ED;MATHEMATICAL BOLD SCRIPT SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D4EE;MATHEMATICAL BOLD SCRIPT SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D4EF;MATHEMATICAL BOLD SCRIPT SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D4F0;MATHEMATICAL BOLD SCRIPT SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D4F1;MATHEMATICAL BOLD SCRIPT SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D4F2;MATHEMATICAL BOLD SCRIPT SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D4F3;MATHEMATICAL BOLD SCRIPT SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D4F4;MATHEMATICAL BOLD SCRIPT SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D4F5;MATHEMATICAL BOLD SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D4F6;MATHEMATICAL BOLD SCRIPT SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D4F7;MATHEMATICAL BOLD SCRIPT SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D4F8;MATHEMATICAL BOLD SCRIPT SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D4F9;MATHEMATICAL BOLD SCRIPT SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D4FA;MATHEMATICAL BOLD SCRIPT SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D4FB;MATHEMATICAL BOLD SCRIPT SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D4FC;MATHEMATICAL BOLD SCRIPT SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D4FD;MATHEMATICAL BOLD SCRIPT SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D4FE;MATHEMATICAL BOLD SCRIPT SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D4FF;MATHEMATICAL BOLD SCRIPT SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D500;MATHEMATICAL BOLD SCRIPT SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D501;MATHEMATICAL BOLD SCRIPT SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D502;MATHEMATICAL BOLD SCRIPT SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D503;MATHEMATICAL BOLD SCRIPT SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D504;MATHEMATICAL FRAKTUR CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D505;MATHEMATICAL FRAKTUR CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D507;MATHEMATICAL FRAKTUR CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D508;MATHEMATICAL FRAKTUR CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D509;MATHEMATICAL FRAKTUR CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D50A;MATHEMATICAL FRAKTUR CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D50D;MATHEMATICAL FRAKTUR CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D50E;MATHEMATICAL FRAKTUR CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D50F;MATHEMATICAL FRAKTUR CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D510;MATHEMATICAL FRAKTUR CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D511;MATHEMATICAL FRAKTUR CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D512;MATHEMATICAL FRAKTUR CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D513;MATHEMATICAL FRAKTUR CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D514;MATHEMATICAL FRAKTUR CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D516;MATHEMATICAL FRAKTUR CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D517;MATHEMATICAL FRAKTUR CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D518;MATHEMATICAL FRAKTUR CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D519;MATHEMATICAL FRAKTUR CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D51A;MATHEMATICAL FRAKTUR CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D51B;MATHEMATICAL FRAKTUR CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D51C;MATHEMATICAL FRAKTUR CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D51E;MATHEMATICAL FRAKTUR SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D51F;MATHEMATICAL FRAKTUR SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D520;MATHEMATICAL FRAKTUR SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D521;MATHEMATICAL FRAKTUR SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D522;MATHEMATICAL FRAKTUR SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D523;MATHEMATICAL FRAKTUR SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D524;MATHEMATICAL FRAKTUR SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D525;MATHEMATICAL FRAKTUR SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D526;MATHEMATICAL FRAKTUR SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D527;MATHEMATICAL FRAKTUR SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D528;MATHEMATICAL FRAKTUR SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D529;MATHEMATICAL FRAKTUR SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D52A;MATHEMATICAL FRAKTUR SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D52B;MATHEMATICAL FRAKTUR SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D52C;MATHEMATICAL FRAKTUR SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D52D;MATHEMATICAL FRAKTUR SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D52E;MATHEMATICAL FRAKTUR SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D52F;MATHEMATICAL FRAKTUR SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D530;MATHEMATICAL FRAKTUR SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D531;MATHEMATICAL FRAKTUR SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D532;MATHEMATICAL FRAKTUR SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D533;MATHEMATICAL FRAKTUR SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D534;MATHEMATICAL FRAKTUR SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D535;MATHEMATICAL FRAKTUR SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D536;MATHEMATICAL FRAKTUR SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D537;MATHEMATICAL FRAKTUR SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D538;MATHEMATICAL DOUBLE-STRUCK CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D539;MATHEMATICAL DOUBLE-STRUCK CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D53B;MATHEMATICAL DOUBLE-STRUCK CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D53C;MATHEMATICAL DOUBLE-STRUCK CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D53D;MATHEMATICAL DOUBLE-STRUCK CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D53E;MATHEMATICAL DOUBLE-STRUCK CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D540;MATHEMATICAL DOUBLE-STRUCK CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D541;MATHEMATICAL DOUBLE-STRUCK CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D542;MATHEMATICAL DOUBLE-STRUCK CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D543;MATHEMATICAL DOUBLE-STRUCK CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D544;MATHEMATICAL DOUBLE-STRUCK CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D546;MATHEMATICAL DOUBLE-STRUCK CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D54A;MATHEMATICAL DOUBLE-STRUCK CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D54B;MATHEMATICAL DOUBLE-STRUCK CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D54C;MATHEMATICAL DOUBLE-STRUCK CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D54D;MATHEMATICAL DOUBLE-STRUCK CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D54E;MATHEMATICAL DOUBLE-STRUCK CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D54F;MATHEMATICAL DOUBLE-STRUCK CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D550;MATHEMATICAL DOUBLE-STRUCK CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D552;MATHEMATICAL DOUBLE-STRUCK SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D553;MATHEMATICAL DOUBLE-STRUCK SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D554;MATHEMATICAL DOUBLE-STRUCK SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D555;MATHEMATICAL DOUBLE-STRUCK SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D556;MATHEMATICAL DOUBLE-STRUCK SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D557;MATHEMATICAL DOUBLE-STRUCK SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D558;MATHEMATICAL DOUBLE-STRUCK SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D559;MATHEMATICAL DOUBLE-STRUCK SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D55A;MATHEMATICAL DOUBLE-STRUCK SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D55B;MATHEMATICAL DOUBLE-STRUCK SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D55C;MATHEMATICAL DOUBLE-STRUCK SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D55D;MATHEMATICAL DOUBLE-STRUCK SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D55E;MATHEMATICAL DOUBLE-STRUCK SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D55F;MATHEMATICAL DOUBLE-STRUCK SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D560;MATHEMATICAL DOUBLE-STRUCK SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D561;MATHEMATICAL DOUBLE-STRUCK SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D562;MATHEMATICAL DOUBLE-STRUCK SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D563;MATHEMATICAL DOUBLE-STRUCK SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D564;MATHEMATICAL DOUBLE-STRUCK SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D565;MATHEMATICAL DOUBLE-STRUCK SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D566;MATHEMATICAL DOUBLE-STRUCK SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D567;MATHEMATICAL DOUBLE-STRUCK SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D568;MATHEMATICAL DOUBLE-STRUCK SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D569;MATHEMATICAL DOUBLE-STRUCK SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D56A;MATHEMATICAL DOUBLE-STRUCK SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D56B;MATHEMATICAL DOUBLE-STRUCK SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D56C;MATHEMATICAL BOLD FRAKTUR CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D56D;MATHEMATICAL BOLD FRAKTUR CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D56E;MATHEMATICAL BOLD FRAKTUR CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D56F;MATHEMATICAL BOLD FRAKTUR CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D570;MATHEMATICAL BOLD FRAKTUR CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D571;MATHEMATICAL BOLD FRAKTUR CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D572;MATHEMATICAL BOLD FRAKTUR CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D573;MATHEMATICAL BOLD FRAKTUR CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D574;MATHEMATICAL BOLD FRAKTUR CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D575;MATHEMATICAL BOLD FRAKTUR CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D576;MATHEMATICAL BOLD FRAKTUR CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D577;MATHEMATICAL BOLD FRAKTUR CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D578;MATHEMATICAL BOLD FRAKTUR CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D579;MATHEMATICAL BOLD FRAKTUR CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D57A;MATHEMATICAL BOLD FRAKTUR CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D57B;MATHEMATICAL BOLD FRAKTUR CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D57C;MATHEMATICAL BOLD FRAKTUR CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D57D;MATHEMATICAL BOLD FRAKTUR CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D57E;MATHEMATICAL BOLD FRAKTUR CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D57F;MATHEMATICAL BOLD FRAKTUR CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D580;MATHEMATICAL BOLD FRAKTUR CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D581;MATHEMATICAL BOLD FRAKTUR CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D582;MATHEMATICAL BOLD FRAKTUR CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D583;MATHEMATICAL BOLD FRAKTUR CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D584;MATHEMATICAL BOLD FRAKTUR CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D585;MATHEMATICAL BOLD FRAKTUR CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D586;MATHEMATICAL BOLD FRAKTUR SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D587;MATHEMATICAL BOLD FRAKTUR SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D588;MATHEMATICAL BOLD FRAKTUR SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D589;MATHEMATICAL BOLD FRAKTUR SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D58A;MATHEMATICAL BOLD FRAKTUR SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D58B;MATHEMATICAL BOLD FRAKTUR SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D58C;MATHEMATICAL BOLD FRAKTUR SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D58D;MATHEMATICAL BOLD FRAKTUR SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D58E;MATHEMATICAL BOLD FRAKTUR SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D58F;MATHEMATICAL BOLD FRAKTUR SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D590;MATHEMATICAL BOLD FRAKTUR SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D591;MATHEMATICAL BOLD FRAKTUR SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D592;MATHEMATICAL BOLD FRAKTUR SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D593;MATHEMATICAL BOLD FRAKTUR SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D594;MATHEMATICAL BOLD FRAKTUR SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D595;MATHEMATICAL BOLD FRAKTUR SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D596;MATHEMATICAL BOLD FRAKTUR SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D597;MATHEMATICAL BOLD FRAKTUR SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D598;MATHEMATICAL BOLD FRAKTUR SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D599;MATHEMATICAL BOLD FRAKTUR SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D59A;MATHEMATICAL BOLD FRAKTUR SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D59B;MATHEMATICAL BOLD FRAKTUR SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D59C;MATHEMATICAL BOLD FRAKTUR SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D59D;MATHEMATICAL BOLD FRAKTUR SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D59E;MATHEMATICAL BOLD FRAKTUR SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D59F;MATHEMATICAL BOLD FRAKTUR SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D5A0;MATHEMATICAL SANS-SERIF CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D5A1;MATHEMATICAL SANS-SERIF CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D5A2;MATHEMATICAL SANS-SERIF CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D5A3;MATHEMATICAL SANS-SERIF CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D5A4;MATHEMATICAL SANS-SERIF CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D5A5;MATHEMATICAL SANS-SERIF CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D5A6;MATHEMATICAL SANS-SERIF CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D5A7;MATHEMATICAL SANS-SERIF CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D5A8;MATHEMATICAL SANS-SERIF CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D5A9;MATHEMATICAL SANS-SERIF CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D5AA;MATHEMATICAL SANS-SERIF CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D5AB;MATHEMATICAL SANS-SERIF CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D5AC;MATHEMATICAL SANS-SERIF CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D5AD;MATHEMATICAL SANS-SERIF CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D5AE;MATHEMATICAL SANS-SERIF CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D5AF;MATHEMATICAL SANS-SERIF CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D5B0;MATHEMATICAL SANS-SERIF CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D5B1;MATHEMATICAL SANS-SERIF CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D5B2;MATHEMATICAL SANS-SERIF CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D5B3;MATHEMATICAL SANS-SERIF CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D5B4;MATHEMATICAL SANS-SERIF CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D5B5;MATHEMATICAL SANS-SERIF CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D5B6;MATHEMATICAL SANS-SERIF CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D5B7;MATHEMATICAL SANS-SERIF CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D5B8;MATHEMATICAL SANS-SERIF CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D5B9;MATHEMATICAL SANS-SERIF CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D5BA;MATHEMATICAL SANS-SERIF SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D5BB;MATHEMATICAL SANS-SERIF SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D5BC;MATHEMATICAL SANS-SERIF SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D5BD;MATHEMATICAL SANS-SERIF SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D5BE;MATHEMATICAL SANS-SERIF SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D5BF;MATHEMATICAL SANS-SERIF SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D5C0;MATHEMATICAL SANS-SERIF SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D5C1;MATHEMATICAL SANS-SERIF SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D5C2;MATHEMATICAL SANS-SERIF SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D5C3;MATHEMATICAL SANS-SERIF SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D5C4;MATHEMATICAL SANS-SERIF SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D5C5;MATHEMATICAL SANS-SERIF SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D5C6;MATHEMATICAL SANS-SERIF SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D5C7;MATHEMATICAL SANS-SERIF SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D5C8;MATHEMATICAL SANS-SERIF SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D5C9;MATHEMATICAL SANS-SERIF SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D5CA;MATHEMATICAL SANS-SERIF SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D5CB;MATHEMATICAL SANS-SERIF SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D5CC;MATHEMATICAL SANS-SERIF SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D5CD;MATHEMATICAL SANS-SERIF SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D5CE;MATHEMATICAL SANS-SERIF SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D5CF;MATHEMATICAL SANS-SERIF SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D5D0;MATHEMATICAL SANS-SERIF SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D5D1;MATHEMATICAL SANS-SERIF SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D5D2;MATHEMATICAL SANS-SERIF SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D5D3;MATHEMATICAL SANS-SERIF SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D5D4;MATHEMATICAL SANS-SERIF BOLD CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D5D5;MATHEMATICAL SANS-SERIF BOLD CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D5D6;MATHEMATICAL SANS-SERIF BOLD CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D5D7;MATHEMATICAL SANS-SERIF BOLD CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D5D8;MATHEMATICAL SANS-SERIF BOLD CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D5D9;MATHEMATICAL SANS-SERIF BOLD CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D5DA;MATHEMATICAL SANS-SERIF BOLD CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D5DB;MATHEMATICAL SANS-SERIF BOLD CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D5DC;MATHEMATICAL SANS-SERIF BOLD CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D5DD;MATHEMATICAL SANS-SERIF BOLD CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D5DE;MATHEMATICAL SANS-SERIF BOLD CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D5DF;MATHEMATICAL SANS-SERIF BOLD CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D5E0;MATHEMATICAL SANS-SERIF BOLD CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D5E1;MATHEMATICAL SANS-SERIF BOLD CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D5E2;MATHEMATICAL SANS-SERIF BOLD CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D5E3;MATHEMATICAL SANS-SERIF BOLD CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D5E4;MATHEMATICAL SANS-SERIF BOLD CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D5E5;MATHEMATICAL SANS-SERIF BOLD CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D5E6;MATHEMATICAL SANS-SERIF BOLD CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D5E7;MATHEMATICAL SANS-SERIF BOLD CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D5E8;MATHEMATICAL SANS-SERIF BOLD CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D5E9;MATHEMATICAL SANS-SERIF BOLD CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D5EA;MATHEMATICAL SANS-SERIF BOLD CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D5EB;MATHEMATICAL SANS-SERIF BOLD CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D5EC;MATHEMATICAL SANS-SERIF BOLD CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D5ED;MATHEMATICAL SANS-SERIF BOLD CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D5EE;MATHEMATICAL SANS-SERIF BOLD SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D5EF;MATHEMATICAL SANS-SERIF BOLD SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D5F0;MATHEMATICAL SANS-SERIF BOLD SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D5F1;MATHEMATICAL SANS-SERIF BOLD SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D5F2;MATHEMATICAL SANS-SERIF BOLD SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D5F3;MATHEMATICAL SANS-SERIF BOLD SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D5F4;MATHEMATICAL SANS-SERIF BOLD SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D5F5;MATHEMATICAL SANS-SERIF BOLD SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D5F6;MATHEMATICAL SANS-SERIF BOLD SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D5F7;MATHEMATICAL SANS-SERIF BOLD SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D5F8;MATHEMATICAL SANS-SERIF BOLD SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D5F9;MATHEMATICAL SANS-SERIF BOLD SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D5FA;MATHEMATICAL SANS-SERIF BOLD SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D5FB;MATHEMATICAL SANS-SERIF BOLD SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D5FC;MATHEMATICAL SANS-SERIF BOLD SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D5FD;MATHEMATICAL SANS-SERIF BOLD SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D5FE;MATHEMATICAL SANS-SERIF BOLD SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D5FF;MATHEMATICAL SANS-SERIF BOLD SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D600;MATHEMATICAL SANS-SERIF BOLD SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D601;MATHEMATICAL SANS-SERIF BOLD SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D602;MATHEMATICAL SANS-SERIF BOLD SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D603;MATHEMATICAL SANS-SERIF BOLD SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D604;MATHEMATICAL SANS-SERIF BOLD SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D605;MATHEMATICAL SANS-SERIF BOLD SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D606;MATHEMATICAL SANS-SERIF BOLD SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D607;MATHEMATICAL SANS-SERIF BOLD SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D608;MATHEMATICAL SANS-SERIF ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D609;MATHEMATICAL SANS-SERIF ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D60A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D60B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D60C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D60D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D60E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D60F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D610;MATHEMATICAL SANS-SERIF ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D611;MATHEMATICAL SANS-SERIF ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D612;MATHEMATICAL SANS-SERIF ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D613;MATHEMATICAL SANS-SERIF ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D614;MATHEMATICAL SANS-SERIF ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D615;MATHEMATICAL SANS-SERIF ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D616;MATHEMATICAL SANS-SERIF ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D617;MATHEMATICAL SANS-SERIF ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D618;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D619;MATHEMATICAL SANS-SERIF ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D61A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D61B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D61C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D61D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D61E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D61F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D620;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D621;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D622;MATHEMATICAL SANS-SERIF ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D623;MATHEMATICAL SANS-SERIF ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D624;MATHEMATICAL SANS-SERIF ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D625;MATHEMATICAL SANS-SERIF ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D626;MATHEMATICAL SANS-SERIF ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D627;MATHEMATICAL SANS-SERIF ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D628;MATHEMATICAL SANS-SERIF ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D629;MATHEMATICAL SANS-SERIF ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D62A;MATHEMATICAL SANS-SERIF ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D62B;MATHEMATICAL SANS-SERIF ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D62C;MATHEMATICAL SANS-SERIF ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D62D;MATHEMATICAL SANS-SERIF ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D62E;MATHEMATICAL SANS-SERIF ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D62F;MATHEMATICAL SANS-SERIF ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D630;MATHEMATICAL SANS-SERIF ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D631;MATHEMATICAL SANS-SERIF ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D632;MATHEMATICAL SANS-SERIF ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D633;MATHEMATICAL SANS-SERIF ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D634;MATHEMATICAL SANS-SERIF ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D635;MATHEMATICAL SANS-SERIF ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D636;MATHEMATICAL SANS-SERIF ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D637;MATHEMATICAL SANS-SERIF ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D638;MATHEMATICAL SANS-SERIF ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D639;MATHEMATICAL SANS-SERIF ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D63A;MATHEMATICAL SANS-SERIF ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D63B;MATHEMATICAL SANS-SERIF ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D63C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D63D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D63E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D63F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D640;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D641;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D642;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D643;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D644;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D645;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D646;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D647;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D648;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D649;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D64A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D64B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D64C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D64D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D64E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D64F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D650;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D651;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D652;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D653;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D654;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D655;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D656;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D657;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D658;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D659;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D65A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D65B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D65C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D65D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D65E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D65F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D660;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D661;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D662;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D663;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D664;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D665;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D666;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D667;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D668;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D669;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D66A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D66B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D66C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D66D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D66E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D66F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D670;MATHEMATICAL MONOSPACE CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
+1D671;MATHEMATICAL MONOSPACE CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
+1D672;MATHEMATICAL MONOSPACE CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
+1D673;MATHEMATICAL MONOSPACE CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
+1D674;MATHEMATICAL MONOSPACE CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
+1D675;MATHEMATICAL MONOSPACE CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
+1D676;MATHEMATICAL MONOSPACE CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
+1D677;MATHEMATICAL MONOSPACE CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
+1D678;MATHEMATICAL MONOSPACE CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
+1D679;MATHEMATICAL MONOSPACE CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
+1D67A;MATHEMATICAL MONOSPACE CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
+1D67B;MATHEMATICAL MONOSPACE CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
+1D67C;MATHEMATICAL MONOSPACE CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
+1D67D;MATHEMATICAL MONOSPACE CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
+1D67E;MATHEMATICAL MONOSPACE CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
+1D67F;MATHEMATICAL MONOSPACE CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
+1D680;MATHEMATICAL MONOSPACE CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
+1D681;MATHEMATICAL MONOSPACE CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
+1D682;MATHEMATICAL MONOSPACE CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
+1D683;MATHEMATICAL MONOSPACE CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
+1D684;MATHEMATICAL MONOSPACE CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
+1D685;MATHEMATICAL MONOSPACE CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
+1D686;MATHEMATICAL MONOSPACE CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
+1D687;MATHEMATICAL MONOSPACE CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
+1D688;MATHEMATICAL MONOSPACE CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
+1D689;MATHEMATICAL MONOSPACE CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
+1D68A;MATHEMATICAL MONOSPACE SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
+1D68B;MATHEMATICAL MONOSPACE SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
+1D68C;MATHEMATICAL MONOSPACE SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
+1D68D;MATHEMATICAL MONOSPACE SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
+1D68E;MATHEMATICAL MONOSPACE SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
+1D68F;MATHEMATICAL MONOSPACE SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
+1D690;MATHEMATICAL MONOSPACE SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
+1D691;MATHEMATICAL MONOSPACE SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
+1D692;MATHEMATICAL MONOSPACE SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
+1D693;MATHEMATICAL MONOSPACE SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
+1D694;MATHEMATICAL MONOSPACE SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
+1D695;MATHEMATICAL MONOSPACE SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
+1D696;MATHEMATICAL MONOSPACE SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
+1D697;MATHEMATICAL MONOSPACE SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
+1D698;MATHEMATICAL MONOSPACE SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
+1D699;MATHEMATICAL MONOSPACE SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
+1D69A;MATHEMATICAL MONOSPACE SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
+1D69B;MATHEMATICAL MONOSPACE SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
+1D69C;MATHEMATICAL MONOSPACE SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
+1D69D;MATHEMATICAL MONOSPACE SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
+1D69E;MATHEMATICAL MONOSPACE SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
+1D69F;MATHEMATICAL MONOSPACE SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
+1D6A0;MATHEMATICAL MONOSPACE SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
+1D6A1;MATHEMATICAL MONOSPACE SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
+1D6A2;MATHEMATICAL MONOSPACE SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
+1D6A3;MATHEMATICAL MONOSPACE SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
+1D6A4;MATHEMATICAL ITALIC SMALL DOTLESS I;Ll;0;L;<font> 0131;;;;N;;;;;
+1D6A5;MATHEMATICAL ITALIC SMALL DOTLESS J;Ll;0;L;<font> 0237;;;;N;;;;;
+1D6A8;MATHEMATICAL BOLD CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
+1D6A9;MATHEMATICAL BOLD CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
+1D6AA;MATHEMATICAL BOLD CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+1D6AB;MATHEMATICAL BOLD CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
+1D6AC;MATHEMATICAL BOLD CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
+1D6AD;MATHEMATICAL BOLD CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
+1D6AE;MATHEMATICAL BOLD CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
+1D6AF;MATHEMATICAL BOLD CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
+1D6B0;MATHEMATICAL BOLD CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
+1D6B1;MATHEMATICAL BOLD CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
+1D6B2;MATHEMATICAL BOLD CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
+1D6B3;MATHEMATICAL BOLD CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
+1D6B4;MATHEMATICAL BOLD CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
+1D6B5;MATHEMATICAL BOLD CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
+1D6B6;MATHEMATICAL BOLD CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
+1D6B7;MATHEMATICAL BOLD CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+1D6B8;MATHEMATICAL BOLD CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
+1D6B9;MATHEMATICAL BOLD CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
+1D6BA;MATHEMATICAL BOLD CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
+1D6BB;MATHEMATICAL BOLD CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
+1D6BC;MATHEMATICAL BOLD CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
+1D6BD;MATHEMATICAL BOLD CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
+1D6BE;MATHEMATICAL BOLD CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
+1D6BF;MATHEMATICAL BOLD CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
+1D6C0;MATHEMATICAL BOLD CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
+1D6C1;MATHEMATICAL BOLD NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
+1D6C2;MATHEMATICAL BOLD SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
+1D6C3;MATHEMATICAL BOLD SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
+1D6C4;MATHEMATICAL BOLD SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+1D6C5;MATHEMATICAL BOLD SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
+1D6C6;MATHEMATICAL BOLD SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
+1D6C7;MATHEMATICAL BOLD SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
+1D6C8;MATHEMATICAL BOLD SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
+1D6C9;MATHEMATICAL BOLD SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
+1D6CA;MATHEMATICAL BOLD SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
+1D6CB;MATHEMATICAL BOLD SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
+1D6CC;MATHEMATICAL BOLD SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
+1D6CD;MATHEMATICAL BOLD SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
+1D6CE;MATHEMATICAL BOLD SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
+1D6CF;MATHEMATICAL BOLD SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
+1D6D0;MATHEMATICAL BOLD SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
+1D6D1;MATHEMATICAL BOLD SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+1D6D2;MATHEMATICAL BOLD SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
+1D6D3;MATHEMATICAL BOLD SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
+1D6D4;MATHEMATICAL BOLD SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
+1D6D5;MATHEMATICAL BOLD SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
+1D6D6;MATHEMATICAL BOLD SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
+1D6D7;MATHEMATICAL BOLD SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
+1D6D8;MATHEMATICAL BOLD SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
+1D6D9;MATHEMATICAL BOLD SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
+1D6DA;MATHEMATICAL BOLD SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
+1D6DB;MATHEMATICAL BOLD PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;
+1D6DC;MATHEMATICAL BOLD EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
+1D6DD;MATHEMATICAL BOLD THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
+1D6DE;MATHEMATICAL BOLD KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
+1D6DF;MATHEMATICAL BOLD PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
+1D6E0;MATHEMATICAL BOLD RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
+1D6E1;MATHEMATICAL BOLD PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
+1D6E2;MATHEMATICAL ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
+1D6E3;MATHEMATICAL ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
+1D6E4;MATHEMATICAL ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+1D6E5;MATHEMATICAL ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
+1D6E6;MATHEMATICAL ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
+1D6E7;MATHEMATICAL ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
+1D6E8;MATHEMATICAL ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
+1D6E9;MATHEMATICAL ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
+1D6EA;MATHEMATICAL ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
+1D6EB;MATHEMATICAL ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
+1D6EC;MATHEMATICAL ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
+1D6ED;MATHEMATICAL ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
+1D6EE;MATHEMATICAL ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
+1D6EF;MATHEMATICAL ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
+1D6F0;MATHEMATICAL ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
+1D6F1;MATHEMATICAL ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+1D6F2;MATHEMATICAL ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
+1D6F3;MATHEMATICAL ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
+1D6F4;MATHEMATICAL ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
+1D6F5;MATHEMATICAL ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
+1D6F6;MATHEMATICAL ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
+1D6F7;MATHEMATICAL ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
+1D6F8;MATHEMATICAL ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
+1D6F9;MATHEMATICAL ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
+1D6FA;MATHEMATICAL ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
+1D6FB;MATHEMATICAL ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
+1D6FC;MATHEMATICAL ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
+1D6FD;MATHEMATICAL ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
+1D6FE;MATHEMATICAL ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+1D6FF;MATHEMATICAL ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
+1D700;MATHEMATICAL ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
+1D701;MATHEMATICAL ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
+1D702;MATHEMATICAL ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
+1D703;MATHEMATICAL ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
+1D704;MATHEMATICAL ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
+1D705;MATHEMATICAL ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
+1D706;MATHEMATICAL ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
+1D707;MATHEMATICAL ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
+1D708;MATHEMATICAL ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
+1D709;MATHEMATICAL ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
+1D70A;MATHEMATICAL ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
+1D70B;MATHEMATICAL ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+1D70C;MATHEMATICAL ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
+1D70D;MATHEMATICAL ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
+1D70E;MATHEMATICAL ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
+1D70F;MATHEMATICAL ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
+1D710;MATHEMATICAL ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
+1D711;MATHEMATICAL ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
+1D712;MATHEMATICAL ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
+1D713;MATHEMATICAL ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
+1D714;MATHEMATICAL ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
+1D715;MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;
+1D716;MATHEMATICAL ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
+1D717;MATHEMATICAL ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
+1D718;MATHEMATICAL ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
+1D719;MATHEMATICAL ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
+1D71A;MATHEMATICAL ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
+1D71B;MATHEMATICAL ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
+1D71C;MATHEMATICAL BOLD ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
+1D71D;MATHEMATICAL BOLD ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
+1D71E;MATHEMATICAL BOLD ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+1D71F;MATHEMATICAL BOLD ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
+1D720;MATHEMATICAL BOLD ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
+1D721;MATHEMATICAL BOLD ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
+1D722;MATHEMATICAL BOLD ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
+1D723;MATHEMATICAL BOLD ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
+1D724;MATHEMATICAL BOLD ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
+1D725;MATHEMATICAL BOLD ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
+1D726;MATHEMATICAL BOLD ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
+1D727;MATHEMATICAL BOLD ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
+1D728;MATHEMATICAL BOLD ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
+1D729;MATHEMATICAL BOLD ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
+1D72A;MATHEMATICAL BOLD ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
+1D72B;MATHEMATICAL BOLD ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+1D72C;MATHEMATICAL BOLD ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
+1D72D;MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
+1D72E;MATHEMATICAL BOLD ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
+1D72F;MATHEMATICAL BOLD ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
+1D730;MATHEMATICAL BOLD ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
+1D731;MATHEMATICAL BOLD ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
+1D732;MATHEMATICAL BOLD ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
+1D733;MATHEMATICAL BOLD ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
+1D734;MATHEMATICAL BOLD ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
+1D735;MATHEMATICAL BOLD ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
+1D736;MATHEMATICAL BOLD ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
+1D737;MATHEMATICAL BOLD ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
+1D738;MATHEMATICAL BOLD ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+1D739;MATHEMATICAL BOLD ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
+1D73A;MATHEMATICAL BOLD ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
+1D73B;MATHEMATICAL BOLD ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
+1D73C;MATHEMATICAL BOLD ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
+1D73D;MATHEMATICAL BOLD ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
+1D73E;MATHEMATICAL BOLD ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
+1D73F;MATHEMATICAL BOLD ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
+1D740;MATHEMATICAL BOLD ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
+1D741;MATHEMATICAL BOLD ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
+1D742;MATHEMATICAL BOLD ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
+1D743;MATHEMATICAL BOLD ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
+1D744;MATHEMATICAL BOLD ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
+1D745;MATHEMATICAL BOLD ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+1D746;MATHEMATICAL BOLD ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
+1D747;MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
+1D748;MATHEMATICAL BOLD ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
+1D749;MATHEMATICAL BOLD ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
+1D74A;MATHEMATICAL BOLD ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
+1D74B;MATHEMATICAL BOLD ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
+1D74C;MATHEMATICAL BOLD ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
+1D74D;MATHEMATICAL BOLD ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
+1D74E;MATHEMATICAL BOLD ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
+1D74F;MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;
+1D750;MATHEMATICAL BOLD ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
+1D751;MATHEMATICAL BOLD ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
+1D752;MATHEMATICAL BOLD ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
+1D753;MATHEMATICAL BOLD ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
+1D754;MATHEMATICAL BOLD ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
+1D755;MATHEMATICAL BOLD ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
+1D756;MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
+1D757;MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
+1D758;MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+1D759;MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
+1D75A;MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
+1D75B;MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
+1D75C;MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
+1D75D;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
+1D75E;MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
+1D75F;MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
+1D760;MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
+1D761;MATHEMATICAL SANS-SERIF BOLD CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
+1D762;MATHEMATICAL SANS-SERIF BOLD CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
+1D763;MATHEMATICAL SANS-SERIF BOLD CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
+1D764;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
+1D765;MATHEMATICAL SANS-SERIF BOLD CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+1D766;MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
+1D767;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
+1D768;MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
+1D769;MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
+1D76A;MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
+1D76B;MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
+1D76C;MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
+1D76D;MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
+1D76E;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
+1D76F;MATHEMATICAL SANS-SERIF BOLD NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
+1D770;MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
+1D771;MATHEMATICAL SANS-SERIF BOLD SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
+1D772;MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+1D773;MATHEMATICAL SANS-SERIF BOLD SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
+1D774;MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
+1D775;MATHEMATICAL SANS-SERIF BOLD SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
+1D776;MATHEMATICAL SANS-SERIF BOLD SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
+1D777;MATHEMATICAL SANS-SERIF BOLD SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
+1D778;MATHEMATICAL SANS-SERIF BOLD SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
+1D779;MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
+1D77A;MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
+1D77B;MATHEMATICAL SANS-SERIF BOLD SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
+1D77C;MATHEMATICAL SANS-SERIF BOLD SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
+1D77D;MATHEMATICAL SANS-SERIF BOLD SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
+1D77E;MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
+1D77F;MATHEMATICAL SANS-SERIF BOLD SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+1D780;MATHEMATICAL SANS-SERIF BOLD SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
+1D781;MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
+1D782;MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
+1D783;MATHEMATICAL SANS-SERIF BOLD SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
+1D784;MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
+1D785;MATHEMATICAL SANS-SERIF BOLD SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
+1D786;MATHEMATICAL SANS-SERIF BOLD SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
+1D787;MATHEMATICAL SANS-SERIF BOLD SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
+1D788;MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
+1D789;MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;
+1D78A;MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
+1D78B;MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
+1D78C;MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
+1D78D;MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
+1D78E;MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
+1D78F;MATHEMATICAL SANS-SERIF BOLD PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
+1D790;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
+1D791;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
+1D792;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
+1D793;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
+1D794;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
+1D795;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
+1D796;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
+1D797;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
+1D798;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
+1D799;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
+1D79A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
+1D79B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
+1D79C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
+1D79D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
+1D79E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
+1D79F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
+1D7A0;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
+1D7A1;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
+1D7A2;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
+1D7A3;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
+1D7A4;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
+1D7A5;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
+1D7A6;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
+1D7A7;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
+1D7A8;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
+1D7A9;MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
+1D7AA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
+1D7AB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
+1D7AC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
+1D7AD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
+1D7AE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
+1D7AF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
+1D7B0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
+1D7B1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
+1D7B2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
+1D7B3;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
+1D7B4;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
+1D7B5;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
+1D7B6;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
+1D7B7;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
+1D7B8;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
+1D7B9;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
+1D7BA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
+1D7BB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
+1D7BC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
+1D7BD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
+1D7BE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
+1D7BF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
+1D7C0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
+1D7C1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
+1D7C2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
+1D7C3;MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;
+1D7C4;MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
+1D7C5;MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
+1D7C6;MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
+1D7C7;MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
+1D7C8;MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
+1D7C9;MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
+1D7CA;MATHEMATICAL BOLD CAPITAL DIGAMMA;Lu;0;L;<font> 03DC;;;;N;;;;;
+1D7CB;MATHEMATICAL BOLD SMALL DIGAMMA;Ll;0;L;<font> 03DD;;;;N;;;;;
+1D7CE;MATHEMATICAL BOLD DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
+1D7CF;MATHEMATICAL BOLD DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
+1D7D0;MATHEMATICAL BOLD DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
+1D7D1;MATHEMATICAL BOLD DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
+1D7D2;MATHEMATICAL BOLD DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
+1D7D3;MATHEMATICAL BOLD DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
+1D7D4;MATHEMATICAL BOLD DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
+1D7D5;MATHEMATICAL BOLD DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
+1D7D6;MATHEMATICAL BOLD DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
+1D7D7;MATHEMATICAL BOLD DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+1D7D8;MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
+1D7D9;MATHEMATICAL DOUBLE-STRUCK DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
+1D7DA;MATHEMATICAL DOUBLE-STRUCK DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
+1D7DB;MATHEMATICAL DOUBLE-STRUCK DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
+1D7DC;MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
+1D7DD;MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
+1D7DE;MATHEMATICAL DOUBLE-STRUCK DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
+1D7DF;MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
+1D7E0;MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
+1D7E1;MATHEMATICAL DOUBLE-STRUCK DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+1D7E2;MATHEMATICAL SANS-SERIF DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
+1D7E3;MATHEMATICAL SANS-SERIF DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
+1D7E4;MATHEMATICAL SANS-SERIF DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
+1D7E5;MATHEMATICAL SANS-SERIF DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
+1D7E6;MATHEMATICAL SANS-SERIF DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
+1D7E7;MATHEMATICAL SANS-SERIF DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
+1D7E8;MATHEMATICAL SANS-SERIF DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
+1D7E9;MATHEMATICAL SANS-SERIF DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
+1D7EA;MATHEMATICAL SANS-SERIF DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
+1D7EB;MATHEMATICAL SANS-SERIF DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+1D7EC;MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
+1D7ED;MATHEMATICAL SANS-SERIF BOLD DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
+1D7EE;MATHEMATICAL SANS-SERIF BOLD DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
+1D7EF;MATHEMATICAL SANS-SERIF BOLD DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
+1D7F0;MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
+1D7F1;MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
+1D7F2;MATHEMATICAL SANS-SERIF BOLD DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
+1D7F3;MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
+1D7F4;MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
+1D7F5;MATHEMATICAL SANS-SERIF BOLD DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+1D7F6;MATHEMATICAL MONOSPACE DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
+1D7F7;MATHEMATICAL MONOSPACE DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
+1D7F8;MATHEMATICAL MONOSPACE DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
+1D7F9;MATHEMATICAL MONOSPACE DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
+1D7FA;MATHEMATICAL MONOSPACE DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
+1D7FB;MATHEMATICAL MONOSPACE DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
+1D7FC;MATHEMATICAL MONOSPACE DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
+1D7FD;MATHEMATICAL MONOSPACE DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
+1D7FE;MATHEMATICAL MONOSPACE DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
+1D7FF;MATHEMATICAL MONOSPACE DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
+1D800;SIGNWRITING HAND-FIST INDEX;So;0;L;;;;;N;;;;;
+1D801;SIGNWRITING HAND-CIRCLE INDEX;So;0;L;;;;;N;;;;;
+1D802;SIGNWRITING HAND-CUP INDEX;So;0;L;;;;;N;;;;;
+1D803;SIGNWRITING HAND-OVAL INDEX;So;0;L;;;;;N;;;;;
+1D804;SIGNWRITING HAND-HINGE INDEX;So;0;L;;;;;N;;;;;
+1D805;SIGNWRITING HAND-ANGLE INDEX;So;0;L;;;;;N;;;;;
+1D806;SIGNWRITING HAND-FIST INDEX BENT;So;0;L;;;;;N;;;;;
+1D807;SIGNWRITING HAND-CIRCLE INDEX BENT;So;0;L;;;;;N;;;;;
+1D808;SIGNWRITING HAND-FIST THUMB UNDER INDEX BENT;So;0;L;;;;;N;;;;;
+1D809;SIGNWRITING HAND-FIST INDEX RAISED KNUCKLE;So;0;L;;;;;N;;;;;
+1D80A;SIGNWRITING HAND-FIST INDEX CUPPED;So;0;L;;;;;N;;;;;
+1D80B;SIGNWRITING HAND-FIST INDEX HINGED;So;0;L;;;;;N;;;;;
+1D80C;SIGNWRITING HAND-FIST INDEX HINGED LOW;So;0;L;;;;;N;;;;;
+1D80D;SIGNWRITING HAND-CIRCLE INDEX HINGE;So;0;L;;;;;N;;;;;
+1D80E;SIGNWRITING HAND-FIST INDEX MIDDLE;So;0;L;;;;;N;;;;;
+1D80F;SIGNWRITING HAND-CIRCLE INDEX MIDDLE;So;0;L;;;;;N;;;;;
+1D810;SIGNWRITING HAND-FIST INDEX MIDDLE BENT;So;0;L;;;;;N;;;;;
+1D811;SIGNWRITING HAND-FIST INDEX MIDDLE RAISED KNUCKLES;So;0;L;;;;;N;;;;;
+1D812;SIGNWRITING HAND-FIST INDEX MIDDLE HINGED;So;0;L;;;;;N;;;;;
+1D813;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED;So;0;L;;;;;N;;;;;
+1D814;SIGNWRITING HAND-FIST INDEX HINGED MIDDLE UP;So;0;L;;;;;N;;;;;
+1D815;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED;So;0;L;;;;;N;;;;;
+1D816;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED INDEX BENT;So;0;L;;;;;N;;;;;
+1D817;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED MIDDLE BENT;So;0;L;;;;;N;;;;;
+1D818;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED CUPPED;So;0;L;;;;;N;;;;;
+1D819;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED HINGED;So;0;L;;;;;N;;;;;
+1D81A;SIGNWRITING HAND-FIST INDEX MIDDLE CROSSED;So;0;L;;;;;N;;;;;
+1D81B;SIGNWRITING HAND-CIRCLE INDEX MIDDLE CROSSED;So;0;L;;;;;N;;;;;
+1D81C;SIGNWRITING HAND-FIST MIDDLE BENT OVER INDEX;So;0;L;;;;;N;;;;;
+1D81D;SIGNWRITING HAND-FIST INDEX BENT OVER MIDDLE;So;0;L;;;;;N;;;;;
+1D81E;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB;So;0;L;;;;;N;;;;;
+1D81F;SIGNWRITING HAND-CIRCLE INDEX MIDDLE THUMB;So;0;L;;;;;N;;;;;
+1D820;SIGNWRITING HAND-FIST INDEX MIDDLE STRAIGHT THUMB BENT;So;0;L;;;;;N;;;;;
+1D821;SIGNWRITING HAND-FIST INDEX MIDDLE BENT THUMB STRAIGHT;So;0;L;;;;;N;;;;;
+1D822;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB BENT;So;0;L;;;;;N;;;;;
+1D823;SIGNWRITING HAND-FIST INDEX MIDDLE HINGED SPREAD THUMB SIDE;So;0;L;;;;;N;;;;;
+1D824;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED THUMB SIDE;So;0;L;;;;;N;;;;;
+1D825;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED THUMB CONJOINED;So;0;L;;;;;N;;;;;
+1D826;SIGNWRITING HAND-FIST INDEX HINGED MIDDLE UP THUMB SIDE;So;0;L;;;;;N;;;;;
+1D827;SIGNWRITING HAND-FIST INDEX MIDDLE UP SPREAD THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D828;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CUPPED;So;0;L;;;;;N;;;;;
+1D829;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CIRCLED;So;0;L;;;;;N;;;;;
+1D82A;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB HOOKED;So;0;L;;;;;N;;;;;
+1D82B;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB HINGED;So;0;L;;;;;N;;;;;
+1D82C;SIGNWRITING HAND-FIST THUMB BETWEEN INDEX MIDDLE STRAIGHT;So;0;L;;;;;N;;;;;
+1D82D;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE;So;0;L;;;;;N;;;;;
+1D82E;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE CONJOINED;So;0;L;;;;;N;;;;;
+1D82F;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE BENT;So;0;L;;;;;N;;;;;
+1D830;SIGNWRITING HAND-FIST MIDDLE THUMB HOOKED INDEX UP;So;0;L;;;;;N;;;;;
+1D831;SIGNWRITING HAND-FIST INDEX THUMB HOOKED MIDDLE UP;So;0;L;;;;;N;;;;;
+1D832;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED HINGED THUMB SIDE;So;0;L;;;;;N;;;;;
+1D833;SIGNWRITING HAND-FIST INDEX MIDDLE CROSSED THUMB SIDE;So;0;L;;;;;N;;;;;
+1D834;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D835;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED CUPPED THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D836;SIGNWRITING HAND-FIST MIDDLE THUMB CUPPED INDEX UP;So;0;L;;;;;N;;;;;
+1D837;SIGNWRITING HAND-FIST INDEX THUMB CUPPED MIDDLE UP;So;0;L;;;;;N;;;;;
+1D838;SIGNWRITING HAND-FIST MIDDLE THUMB CIRCLED INDEX UP;So;0;L;;;;;N;;;;;
+1D839;SIGNWRITING HAND-FIST MIDDLE THUMB CIRCLED INDEX HINGED;So;0;L;;;;;N;;;;;
+1D83A;SIGNWRITING HAND-FIST INDEX THUMB ANGLED OUT MIDDLE UP;So;0;L;;;;;N;;;;;
+1D83B;SIGNWRITING HAND-FIST INDEX THUMB ANGLED IN MIDDLE UP;So;0;L;;;;;N;;;;;
+1D83C;SIGNWRITING HAND-FIST INDEX THUMB CIRCLED MIDDLE UP;So;0;L;;;;;N;;;;;
+1D83D;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CONJOINED HINGED;So;0;L;;;;;N;;;;;
+1D83E;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB ANGLED OUT;So;0;L;;;;;N;;;;;
+1D83F;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB ANGLED;So;0;L;;;;;N;;;;;
+1D840;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED OUT INDEX UP;So;0;L;;;;;N;;;;;
+1D841;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED OUT INDEX CROSSED;So;0;L;;;;;N;;;;;
+1D842;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED INDEX UP;So;0;L;;;;;N;;;;;
+1D843;SIGNWRITING HAND-FIST INDEX THUMB HOOKED MIDDLE HINGED;So;0;L;;;;;N;;;;;
+1D844;SIGNWRITING HAND-FLAT FOUR FINGERS;So;0;L;;;;;N;;;;;
+1D845;SIGNWRITING HAND-FLAT FOUR FINGERS BENT;So;0;L;;;;;N;;;;;
+1D846;SIGNWRITING HAND-FLAT FOUR FINGERS HINGED;So;0;L;;;;;N;;;;;
+1D847;SIGNWRITING HAND-FLAT FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;;
+1D848;SIGNWRITING HAND-FLAT FOUR FINGERS CONJOINED SPLIT;So;0;L;;;;;N;;;;;
+1D849;SIGNWRITING HAND-CLAW FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;;
+1D84A;SIGNWRITING HAND-FIST FOUR FINGERS CONJOINED BENT;So;0;L;;;;;N;;;;;
+1D84B;SIGNWRITING HAND-HINGE FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;;
+1D84C;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;
+1D84D;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;
+1D84E;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD FOUR BENT;So;0;L;;;;;N;;;;;
+1D84F;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD FOUR BENT;So;0;L;;;;;N;;;;;
+1D850;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD BENT;So;0;L;;;;;N;;;;;
+1D851;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD BENT;So;0;L;;;;;N;;;;;
+1D852;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D853;SIGNWRITING HAND-CUP FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;
+1D854;SIGNWRITING HAND-CUP FIVE FINGERS SPREAD OPEN;So;0;L;;;;;N;;;;;
+1D855;SIGNWRITING HAND-HINGE FIVE FINGERS SPREAD OPEN;So;0;L;;;;;N;;;;;
+1D856;SIGNWRITING HAND-OVAL FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;
+1D857;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED;So;0;L;;;;;N;;;;;
+1D858;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED THUMB SIDE;So;0;L;;;;;N;;;;;
+1D859;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED NO THUMB;So;0;L;;;;;N;;;;;
+1D85A;SIGNWRITING HAND-FLAT;So;0;L;;;;;N;;;;;
+1D85B;SIGNWRITING HAND-FLAT BETWEEN PALM FACINGS;So;0;L;;;;;N;;;;;
+1D85C;SIGNWRITING HAND-FLAT HEEL;So;0;L;;;;;N;;;;;
+1D85D;SIGNWRITING HAND-FLAT THUMB SIDE;So;0;L;;;;;N;;;;;
+1D85E;SIGNWRITING HAND-FLAT HEEL THUMB SIDE;So;0;L;;;;;N;;;;;
+1D85F;SIGNWRITING HAND-FLAT THUMB BENT;So;0;L;;;;;N;;;;;
+1D860;SIGNWRITING HAND-FLAT THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D861;SIGNWRITING HAND-FLAT SPLIT INDEX THUMB SIDE;So;0;L;;;;;N;;;;;
+1D862;SIGNWRITING HAND-FLAT SPLIT CENTRE;So;0;L;;;;;N;;;;;
+1D863;SIGNWRITING HAND-FLAT SPLIT CENTRE THUMB SIDE;So;0;L;;;;;N;;;;;
+1D864;SIGNWRITING HAND-FLAT SPLIT CENTRE THUMB SIDE BENT;So;0;L;;;;;N;;;;;
+1D865;SIGNWRITING HAND-FLAT SPLIT LITTLE;So;0;L;;;;;N;;;;;
+1D866;SIGNWRITING HAND-CLAW;So;0;L;;;;;N;;;;;
+1D867;SIGNWRITING HAND-CLAW THUMB SIDE;So;0;L;;;;;N;;;;;
+1D868;SIGNWRITING HAND-CLAW NO THUMB;So;0;L;;;;;N;;;;;
+1D869;SIGNWRITING HAND-CLAW THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D86A;SIGNWRITING HAND-HOOK CURLICUE;So;0;L;;;;;N;;;;;
+1D86B;SIGNWRITING HAND-HOOK;So;0;L;;;;;N;;;;;
+1D86C;SIGNWRITING HAND-CUP OPEN;So;0;L;;;;;N;;;;;
+1D86D;SIGNWRITING HAND-CUP;So;0;L;;;;;N;;;;;
+1D86E;SIGNWRITING HAND-CUP OPEN THUMB SIDE;So;0;L;;;;;N;;;;;
+1D86F;SIGNWRITING HAND-CUP THUMB SIDE;So;0;L;;;;;N;;;;;
+1D870;SIGNWRITING HAND-CUP OPEN NO THUMB;So;0;L;;;;;N;;;;;
+1D871;SIGNWRITING HAND-CUP NO THUMB;So;0;L;;;;;N;;;;;
+1D872;SIGNWRITING HAND-CUP OPEN THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D873;SIGNWRITING HAND-CUP THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D874;SIGNWRITING HAND-CURLICUE OPEN;So;0;L;;;;;N;;;;;
+1D875;SIGNWRITING HAND-CURLICUE;So;0;L;;;;;N;;;;;
+1D876;SIGNWRITING HAND-CIRCLE;So;0;L;;;;;N;;;;;
+1D877;SIGNWRITING HAND-OVAL;So;0;L;;;;;N;;;;;
+1D878;SIGNWRITING HAND-OVAL THUMB SIDE;So;0;L;;;;;N;;;;;
+1D879;SIGNWRITING HAND-OVAL NO THUMB;So;0;L;;;;;N;;;;;
+1D87A;SIGNWRITING HAND-OVAL THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D87B;SIGNWRITING HAND-HINGE OPEN;So;0;L;;;;;N;;;;;
+1D87C;SIGNWRITING HAND-HINGE OPEN THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D87D;SIGNWRITING HAND-HINGE;So;0;L;;;;;N;;;;;
+1D87E;SIGNWRITING HAND-HINGE SMALL;So;0;L;;;;;N;;;;;
+1D87F;SIGNWRITING HAND-HINGE OPEN THUMB SIDE;So;0;L;;;;;N;;;;;
+1D880;SIGNWRITING HAND-HINGE THUMB SIDE;So;0;L;;;;;N;;;;;
+1D881;SIGNWRITING HAND-HINGE OPEN NO THUMB;So;0;L;;;;;N;;;;;
+1D882;SIGNWRITING HAND-HINGE NO THUMB;So;0;L;;;;;N;;;;;
+1D883;SIGNWRITING HAND-HINGE THUMB SIDE TOUCHING INDEX;So;0;L;;;;;N;;;;;
+1D884;SIGNWRITING HAND-HINGE THUMB BETWEEN MIDDLE RING;So;0;L;;;;;N;;;;;
+1D885;SIGNWRITING HAND-ANGLE;So;0;L;;;;;N;;;;;
+1D886;SIGNWRITING HAND-FIST INDEX MIDDLE RING;So;0;L;;;;;N;;;;;
+1D887;SIGNWRITING HAND-CIRCLE INDEX MIDDLE RING;So;0;L;;;;;N;;;;;
+1D888;SIGNWRITING HAND-HINGE INDEX MIDDLE RING;So;0;L;;;;;N;;;;;
+1D889;SIGNWRITING HAND-ANGLE INDEX MIDDLE RING;So;0;L;;;;;N;;;;;
+1D88A;SIGNWRITING HAND-HINGE LITTLE;So;0;L;;;;;N;;;;;
+1D88B;SIGNWRITING HAND-FIST INDEX MIDDLE RING BENT;So;0;L;;;;;N;;;;;
+1D88C;SIGNWRITING HAND-FIST INDEX MIDDLE RING CONJOINED;So;0;L;;;;;N;;;;;
+1D88D;SIGNWRITING HAND-HINGE INDEX MIDDLE RING CONJOINED;So;0;L;;;;;N;;;;;
+1D88E;SIGNWRITING HAND-FIST LITTLE DOWN;So;0;L;;;;;N;;;;;
+1D88F;SIGNWRITING HAND-FIST LITTLE DOWN RIPPLE STRAIGHT;So;0;L;;;;;N;;;;;
+1D890;SIGNWRITING HAND-FIST LITTLE DOWN RIPPLE CURVED;So;0;L;;;;;N;;;;;
+1D891;SIGNWRITING HAND-FIST LITTLE DOWN OTHERS CIRCLED;So;0;L;;;;;N;;;;;
+1D892;SIGNWRITING HAND-FIST LITTLE UP;So;0;L;;;;;N;;;;;
+1D893;SIGNWRITING HAND-FIST THUMB UNDER LITTLE UP;So;0;L;;;;;N;;;;;
+1D894;SIGNWRITING HAND-CIRCLE LITTLE UP;So;0;L;;;;;N;;;;;
+1D895;SIGNWRITING HAND-OVAL LITTLE UP;So;0;L;;;;;N;;;;;
+1D896;SIGNWRITING HAND-ANGLE LITTLE UP;So;0;L;;;;;N;;;;;
+1D897;SIGNWRITING HAND-FIST LITTLE RAISED KNUCKLE;So;0;L;;;;;N;;;;;
+1D898;SIGNWRITING HAND-FIST LITTLE BENT;So;0;L;;;;;N;;;;;
+1D899;SIGNWRITING HAND-FIST LITTLE TOUCHES THUMB;So;0;L;;;;;N;;;;;
+1D89A;SIGNWRITING HAND-FIST LITTLE THUMB;So;0;L;;;;;N;;;;;
+1D89B;SIGNWRITING HAND-HINGE LITTLE THUMB;So;0;L;;;;;N;;;;;
+1D89C;SIGNWRITING HAND-FIST LITTLE INDEX THUMB;So;0;L;;;;;N;;;;;
+1D89D;SIGNWRITING HAND-HINGE LITTLE INDEX THUMB;So;0;L;;;;;N;;;;;
+1D89E;SIGNWRITING HAND-ANGLE LITTLE INDEX THUMB INDEX THUMB OUT;So;0;L;;;;;N;;;;;
+1D89F;SIGNWRITING HAND-ANGLE LITTLE INDEX THUMB INDEX THUMB;So;0;L;;;;;N;;;;;
+1D8A0;SIGNWRITING HAND-FIST LITTLE INDEX;So;0;L;;;;;N;;;;;
+1D8A1;SIGNWRITING HAND-CIRCLE LITTLE INDEX;So;0;L;;;;;N;;;;;
+1D8A2;SIGNWRITING HAND-HINGE LITTLE INDEX;So;0;L;;;;;N;;;;;
+1D8A3;SIGNWRITING HAND-ANGLE LITTLE INDEX;So;0;L;;;;;N;;;;;
+1D8A4;SIGNWRITING HAND-FIST INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;
+1D8A5;SIGNWRITING HAND-CIRCLE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;
+1D8A6;SIGNWRITING HAND-HINGE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;
+1D8A7;SIGNWRITING HAND-HINGE RING;So;0;L;;;;;N;;;;;
+1D8A8;SIGNWRITING HAND-ANGLE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;
+1D8A9;SIGNWRITING HAND-FIST INDEX MIDDLE CROSS LITTLE;So;0;L;;;;;N;;;;;
+1D8AA;SIGNWRITING HAND-CIRCLE INDEX MIDDLE CROSS LITTLE;So;0;L;;;;;N;;;;;
+1D8AB;SIGNWRITING HAND-FIST RING DOWN;So;0;L;;;;;N;;;;;
+1D8AC;SIGNWRITING HAND-HINGE RING DOWN INDEX THUMB HOOK MIDDLE;So;0;L;;;;;N;;;;;
+1D8AD;SIGNWRITING HAND-ANGLE RING DOWN MIDDLE THUMB INDEX CROSS;So;0;L;;;;;N;;;;;
+1D8AE;SIGNWRITING HAND-FIST RING UP;So;0;L;;;;;N;;;;;
+1D8AF;SIGNWRITING HAND-FIST RING RAISED KNUCKLE;So;0;L;;;;;N;;;;;
+1D8B0;SIGNWRITING HAND-FIST RING LITTLE;So;0;L;;;;;N;;;;;
+1D8B1;SIGNWRITING HAND-CIRCLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8B2;SIGNWRITING HAND-OVAL RING LITTLE;So;0;L;;;;;N;;;;;
+1D8B3;SIGNWRITING HAND-ANGLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8B4;SIGNWRITING HAND-FIST RING MIDDLE;So;0;L;;;;;N;;;;;
+1D8B5;SIGNWRITING HAND-FIST RING MIDDLE CONJOINED;So;0;L;;;;;N;;;;;
+1D8B6;SIGNWRITING HAND-FIST RING MIDDLE RAISED KNUCKLES;So;0;L;;;;;N;;;;;
+1D8B7;SIGNWRITING HAND-FIST RING INDEX;So;0;L;;;;;N;;;;;
+1D8B8;SIGNWRITING HAND-FIST RING THUMB;So;0;L;;;;;N;;;;;
+1D8B9;SIGNWRITING HAND-HOOK RING THUMB;So;0;L;;;;;N;;;;;
+1D8BA;SIGNWRITING HAND-FIST INDEX RING LITTLE;So;0;L;;;;;N;;;;;
+1D8BB;SIGNWRITING HAND-CIRCLE INDEX RING LITTLE;So;0;L;;;;;N;;;;;
+1D8BC;SIGNWRITING HAND-CURLICUE INDEX RING LITTLE ON;So;0;L;;;;;N;;;;;
+1D8BD;SIGNWRITING HAND-HOOK INDEX RING LITTLE OUT;So;0;L;;;;;N;;;;;
+1D8BE;SIGNWRITING HAND-HOOK INDEX RING LITTLE IN;So;0;L;;;;;N;;;;;
+1D8BF;SIGNWRITING HAND-HOOK INDEX RING LITTLE UNDER;So;0;L;;;;;N;;;;;
+1D8C0;SIGNWRITING HAND-CUP INDEX RING LITTLE;So;0;L;;;;;N;;;;;
+1D8C1;SIGNWRITING HAND-HINGE INDEX RING LITTLE;So;0;L;;;;;N;;;;;
+1D8C2;SIGNWRITING HAND-ANGLE INDEX RING LITTLE OUT;So;0;L;;;;;N;;;;;
+1D8C3;SIGNWRITING HAND-ANGLE INDEX RING LITTLE;So;0;L;;;;;N;;;;;
+1D8C4;SIGNWRITING HAND-FIST MIDDLE DOWN;So;0;L;;;;;N;;;;;
+1D8C5;SIGNWRITING HAND-HINGE MIDDLE;So;0;L;;;;;N;;;;;
+1D8C6;SIGNWRITING HAND-FIST MIDDLE UP;So;0;L;;;;;N;;;;;
+1D8C7;SIGNWRITING HAND-CIRCLE MIDDLE UP;So;0;L;;;;;N;;;;;
+1D8C8;SIGNWRITING HAND-FIST MIDDLE RAISED KNUCKLE;So;0;L;;;;;N;;;;;
+1D8C9;SIGNWRITING HAND-FIST MIDDLE UP THUMB SIDE;So;0;L;;;;;N;;;;;
+1D8CA;SIGNWRITING HAND-HOOK MIDDLE THUMB;So;0;L;;;;;N;;;;;
+1D8CB;SIGNWRITING HAND-FIST MIDDLE THUMB LITTLE;So;0;L;;;;;N;;;;;
+1D8CC;SIGNWRITING HAND-FIST MIDDLE LITTLE;So;0;L;;;;;N;;;;;
+1D8CD;SIGNWRITING HAND-FIST MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8CE;SIGNWRITING HAND-CIRCLE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8CF;SIGNWRITING HAND-CURLICUE MIDDLE RING LITTLE ON;So;0;L;;;;;N;;;;;
+1D8D0;SIGNWRITING HAND-CUP MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8D1;SIGNWRITING HAND-HINGE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8D2;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE OUT;So;0;L;;;;;N;;;;;
+1D8D3;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE IN;So;0;L;;;;;N;;;;;
+1D8D4;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;
+1D8D5;SIGNWRITING HAND-CIRCLE MIDDLE RING LITTLE BENT;So;0;L;;;;;N;;;;;
+1D8D6;SIGNWRITING HAND-CLAW MIDDLE RING LITTLE CONJOINED;So;0;L;;;;;N;;;;;
+1D8D7;SIGNWRITING HAND-CLAW MIDDLE RING LITTLE CONJOINED SIDE;So;0;L;;;;;N;;;;;
+1D8D8;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED OUT;So;0;L;;;;;N;;;;;
+1D8D9;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED IN;So;0;L;;;;;N;;;;;
+1D8DA;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED;So;0;L;;;;;N;;;;;
+1D8DB;SIGNWRITING HAND-HINGE INDEX HINGED;So;0;L;;;;;N;;;;;
+1D8DC;SIGNWRITING HAND-FIST INDEX THUMB SIDE;So;0;L;;;;;N;;;;;
+1D8DD;SIGNWRITING HAND-HINGE INDEX THUMB SIDE;So;0;L;;;;;N;;;;;
+1D8DE;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB DIAGONAL;So;0;L;;;;;N;;;;;
+1D8DF;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB CONJOINED;So;0;L;;;;;N;;;;;
+1D8E0;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB BENT;So;0;L;;;;;N;;;;;
+1D8E1;SIGNWRITING HAND-FIST INDEX THUMB SIDE INDEX BENT;So;0;L;;;;;N;;;;;
+1D8E2;SIGNWRITING HAND-FIST INDEX THUMB SIDE BOTH BENT;So;0;L;;;;;N;;;;;
+1D8E3;SIGNWRITING HAND-FIST INDEX THUMB SIDE INDEX HINGE;So;0;L;;;;;N;;;;;
+1D8E4;SIGNWRITING HAND-FIST INDEX THUMB FORWARD INDEX STRAIGHT;So;0;L;;;;;N;;;;;
+1D8E5;SIGNWRITING HAND-FIST INDEX THUMB FORWARD INDEX BENT;So;0;L;;;;;N;;;;;
+1D8E6;SIGNWRITING HAND-FIST INDEX THUMB HOOK;So;0;L;;;;;N;;;;;
+1D8E7;SIGNWRITING HAND-FIST INDEX THUMB CURLICUE;So;0;L;;;;;N;;;;;
+1D8E8;SIGNWRITING HAND-FIST INDEX THUMB CURVE THUMB INSIDE;So;0;L;;;;;N;;;;;
+1D8E9;SIGNWRITING HAND-CLAW INDEX THUMB CURVE THUMB INSIDE;So;0;L;;;;;N;;;;;
+1D8EA;SIGNWRITING HAND-FIST INDEX THUMB CURVE THUMB UNDER;So;0;L;;;;;N;;;;;
+1D8EB;SIGNWRITING HAND-FIST INDEX THUMB CIRCLE;So;0;L;;;;;N;;;;;
+1D8EC;SIGNWRITING HAND-CUP INDEX THUMB;So;0;L;;;;;N;;;;;
+1D8ED;SIGNWRITING HAND-CUP INDEX THUMB OPEN;So;0;L;;;;;N;;;;;
+1D8EE;SIGNWRITING HAND-HINGE INDEX THUMB OPEN;So;0;L;;;;;N;;;;;
+1D8EF;SIGNWRITING HAND-HINGE INDEX THUMB LARGE;So;0;L;;;;;N;;;;;
+1D8F0;SIGNWRITING HAND-HINGE INDEX THUMB;So;0;L;;;;;N;;;;;
+1D8F1;SIGNWRITING HAND-HINGE INDEX THUMB SMALL;So;0;L;;;;;N;;;;;
+1D8F2;SIGNWRITING HAND-ANGLE INDEX THUMB OUT;So;0;L;;;;;N;;;;;
+1D8F3;SIGNWRITING HAND-ANGLE INDEX THUMB IN;So;0;L;;;;;N;;;;;
+1D8F4;SIGNWRITING HAND-ANGLE INDEX THUMB;So;0;L;;;;;N;;;;;
+1D8F5;SIGNWRITING HAND-FIST THUMB;So;0;L;;;;;N;;;;;
+1D8F6;SIGNWRITING HAND-FIST THUMB HEEL;So;0;L;;;;;N;;;;;
+1D8F7;SIGNWRITING HAND-FIST THUMB SIDE DIAGONAL;So;0;L;;;;;N;;;;;
+1D8F8;SIGNWRITING HAND-FIST THUMB SIDE CONJOINED;So;0;L;;;;;N;;;;;
+1D8F9;SIGNWRITING HAND-FIST THUMB SIDE BENT;So;0;L;;;;;N;;;;;
+1D8FA;SIGNWRITING HAND-FIST THUMB FORWARD;So;0;L;;;;;N;;;;;
+1D8FB;SIGNWRITING HAND-FIST THUMB BETWEEN INDEX MIDDLE;So;0;L;;;;;N;;;;;
+1D8FC;SIGNWRITING HAND-FIST THUMB BETWEEN MIDDLE RING;So;0;L;;;;;N;;;;;
+1D8FD;SIGNWRITING HAND-FIST THUMB BETWEEN RING LITTLE;So;0;L;;;;;N;;;;;
+1D8FE;SIGNWRITING HAND-FIST THUMB UNDER TWO FINGERS;So;0;L;;;;;N;;;;;
+1D8FF;SIGNWRITING HAND-FIST THUMB OVER TWO FINGERS;So;0;L;;;;;N;;;;;
+1D900;SIGNWRITING HAND-FIST THUMB UNDER THREE FINGERS;So;0;L;;;;;N;;;;;
+1D901;SIGNWRITING HAND-FIST THUMB UNDER FOUR FINGERS;So;0;L;;;;;N;;;;;
+1D902;SIGNWRITING HAND-FIST THUMB OVER FOUR RAISED KNUCKLES;So;0;L;;;;;N;;;;;
+1D903;SIGNWRITING HAND-FIST;So;0;L;;;;;N;;;;;
+1D904;SIGNWRITING HAND-FIST HEEL;So;0;L;;;;;N;;;;;
+1D905;SIGNWRITING TOUCH SINGLE;So;0;L;;;;;N;;;;;
+1D906;SIGNWRITING TOUCH MULTIPLE;So;0;L;;;;;N;;;;;
+1D907;SIGNWRITING TOUCH BETWEEN;So;0;L;;;;;N;;;;;
+1D908;SIGNWRITING GRASP SINGLE;So;0;L;;;;;N;;;;;
+1D909;SIGNWRITING GRASP MULTIPLE;So;0;L;;;;;N;;;;;
+1D90A;SIGNWRITING GRASP BETWEEN;So;0;L;;;;;N;;;;;
+1D90B;SIGNWRITING STRIKE SINGLE;So;0;L;;;;;N;;;;;
+1D90C;SIGNWRITING STRIKE MULTIPLE;So;0;L;;;;;N;;;;;
+1D90D;SIGNWRITING STRIKE BETWEEN;So;0;L;;;;;N;;;;;
+1D90E;SIGNWRITING BRUSH SINGLE;So;0;L;;;;;N;;;;;
+1D90F;SIGNWRITING BRUSH MULTIPLE;So;0;L;;;;;N;;;;;
+1D910;SIGNWRITING BRUSH BETWEEN;So;0;L;;;;;N;;;;;
+1D911;SIGNWRITING RUB SINGLE;So;0;L;;;;;N;;;;;
+1D912;SIGNWRITING RUB MULTIPLE;So;0;L;;;;;N;;;;;
+1D913;SIGNWRITING RUB BETWEEN;So;0;L;;;;;N;;;;;
+1D914;SIGNWRITING SURFACE SYMBOLS;So;0;L;;;;;N;;;;;
+1D915;SIGNWRITING SURFACE BETWEEN;So;0;L;;;;;N;;;;;
+1D916;SIGNWRITING SQUEEZE LARGE SINGLE;So;0;L;;;;;N;;;;;
+1D917;SIGNWRITING SQUEEZE SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D918;SIGNWRITING SQUEEZE LARGE MULTIPLE;So;0;L;;;;;N;;;;;
+1D919;SIGNWRITING SQUEEZE SMALL MULTIPLE;So;0;L;;;;;N;;;;;
+1D91A;SIGNWRITING SQUEEZE SEQUENTIAL;So;0;L;;;;;N;;;;;
+1D91B;SIGNWRITING FLICK LARGE SINGLE;So;0;L;;;;;N;;;;;
+1D91C;SIGNWRITING FLICK SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D91D;SIGNWRITING FLICK LARGE MULTIPLE;So;0;L;;;;;N;;;;;
+1D91E;SIGNWRITING FLICK SMALL MULTIPLE;So;0;L;;;;;N;;;;;
+1D91F;SIGNWRITING FLICK SEQUENTIAL;So;0;L;;;;;N;;;;;
+1D920;SIGNWRITING SQUEEZE FLICK ALTERNATING;So;0;L;;;;;N;;;;;
+1D921;SIGNWRITING MOVEMENT-HINGE UP DOWN LARGE;So;0;L;;;;;N;;;;;
+1D922;SIGNWRITING MOVEMENT-HINGE UP DOWN SMALL;So;0;L;;;;;N;;;;;
+1D923;SIGNWRITING MOVEMENT-HINGE UP SEQUENTIAL;So;0;L;;;;;N;;;;;
+1D924;SIGNWRITING MOVEMENT-HINGE DOWN SEQUENTIAL;So;0;L;;;;;N;;;;;
+1D925;SIGNWRITING MOVEMENT-HINGE UP DOWN ALTERNATING LARGE;So;0;L;;;;;N;;;;;
+1D926;SIGNWRITING MOVEMENT-HINGE UP DOWN ALTERNATING SMALL;So;0;L;;;;;N;;;;;
+1D927;SIGNWRITING MOVEMENT-HINGE SIDE TO SIDE SCISSORS;So;0;L;;;;;N;;;;;
+1D928;SIGNWRITING MOVEMENT-WALLPLANE FINGER CONTACT;So;0;L;;;;;N;;;;;
+1D929;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CONTACT;So;0;L;;;;;N;;;;;
+1D92A;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT SMALL;So;0;L;;;;;N;;;;;
+1D92B;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT MEDIUM;So;0;L;;;;;N;;;;;
+1D92C;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT LARGE;So;0;L;;;;;N;;;;;
+1D92D;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT LARGEST;So;0;L;;;;;N;;;;;
+1D92E;SIGNWRITING MOVEMENT-WALLPLANE SINGLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D92F;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE STRAIGHT;So;0;L;;;;;N;;;;;
+1D930;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D931;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE ALTERNATING;So;0;L;;;;;N;;;;;
+1D932;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;
+1D933;SIGNWRITING MOVEMENT-WALLPLANE CROSS;So;0;L;;;;;N;;;;;
+1D934;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE STRAIGHT MOVEMENT;So;0;L;;;;;N;;;;;
+1D935;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D936;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE ALTERNATING;So;0;L;;;;;N;;;;;
+1D937;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;
+1D938;SIGNWRITING MOVEMENT-WALLPLANE BEND SMALL;So;0;L;;;;;N;;;;;
+1D939;SIGNWRITING MOVEMENT-WALLPLANE BEND MEDIUM;So;0;L;;;;;N;;;;;
+1D93A;SIGNWRITING MOVEMENT-WALLPLANE BEND LARGE;So;0;L;;;;;N;;;;;
+1D93B;SIGNWRITING MOVEMENT-WALLPLANE CORNER SMALL;So;0;L;;;;;N;;;;;
+1D93C;SIGNWRITING MOVEMENT-WALLPLANE CORNER MEDIUM;So;0;L;;;;;N;;;;;
+1D93D;SIGNWRITING MOVEMENT-WALLPLANE CORNER LARGE;So;0;L;;;;;N;;;;;
+1D93E;SIGNWRITING MOVEMENT-WALLPLANE CORNER ROTATION;So;0;L;;;;;N;;;;;
+1D93F;SIGNWRITING MOVEMENT-WALLPLANE CHECK SMALL;So;0;L;;;;;N;;;;;
+1D940;SIGNWRITING MOVEMENT-WALLPLANE CHECK MEDIUM;So;0;L;;;;;N;;;;;
+1D941;SIGNWRITING MOVEMENT-WALLPLANE CHECK LARGE;So;0;L;;;;;N;;;;;
+1D942;SIGNWRITING MOVEMENT-WALLPLANE BOX SMALL;So;0;L;;;;;N;;;;;
+1D943;SIGNWRITING MOVEMENT-WALLPLANE BOX MEDIUM;So;0;L;;;;;N;;;;;
+1D944;SIGNWRITING MOVEMENT-WALLPLANE BOX LARGE;So;0;L;;;;;N;;;;;
+1D945;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG SMALL;So;0;L;;;;;N;;;;;
+1D946;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG MEDIUM;So;0;L;;;;;N;;;;;
+1D947;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG LARGE;So;0;L;;;;;N;;;;;
+1D948;SIGNWRITING MOVEMENT-WALLPLANE PEAKS SMALL;So;0;L;;;;;N;;;;;
+1D949;SIGNWRITING MOVEMENT-WALLPLANE PEAKS MEDIUM;So;0;L;;;;;N;;;;;
+1D94A;SIGNWRITING MOVEMENT-WALLPLANE PEAKS LARGE;So;0;L;;;;;N;;;;;
+1D94B;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D94C;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D94D;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE ALTERNATING;So;0;L;;;;;N;;;;;
+1D94E;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D94F;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D950;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;;
+1D951;SIGNWRITING TRAVEL-WALLPLANE SHAKING;So;0;L;;;;;N;;;;;
+1D952;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL SINGLE;So;0;L;;;;;N;;;;;
+1D953;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL DOUBLE;So;0;L;;;;;N;;;;;
+1D954;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL TRIPLE;So;0;L;;;;;N;;;;;
+1D955;SIGNWRITING MOVEMENT-DIAGONAL AWAY SMALL;So;0;L;;;;;N;;;;;
+1D956;SIGNWRITING MOVEMENT-DIAGONAL AWAY MEDIUM;So;0;L;;;;;N;;;;;
+1D957;SIGNWRITING MOVEMENT-DIAGONAL AWAY LARGE;So;0;L;;;;;N;;;;;
+1D958;SIGNWRITING MOVEMENT-DIAGONAL AWAY LARGEST;So;0;L;;;;;N;;;;;
+1D959;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS SMALL;So;0;L;;;;;N;;;;;
+1D95A;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS MEDIUM;So;0;L;;;;;N;;;;;
+1D95B;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS LARGE;So;0;L;;;;;N;;;;;
+1D95C;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS LARGEST;So;0;L;;;;;N;;;;;
+1D95D;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY SMALL;So;0;L;;;;;N;;;;;
+1D95E;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY MEDIUM;So;0;L;;;;;N;;;;;
+1D95F;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY LARGE;So;0;L;;;;;N;;;;;
+1D960;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY LARGEST;So;0;L;;;;;N;;;;;
+1D961;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS SMALL;So;0;L;;;;;N;;;;;
+1D962;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS MEDIUM;So;0;L;;;;;N;;;;;
+1D963;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS LARGE;So;0;L;;;;;N;;;;;
+1D964;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS LARGEST;So;0;L;;;;;N;;;;;
+1D965;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT SMALL;So;0;L;;;;;N;;;;;
+1D966;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT MEDIUM;So;0;L;;;;;N;;;;;
+1D967;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT LARGE;So;0;L;;;;;N;;;;;
+1D968;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT LARGEST;So;0;L;;;;;N;;;;;
+1D969;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D96A;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE STRAIGHT;So;0;L;;;;;N;;;;;
+1D96B;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D96C;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE ALTERNATING;So;0;L;;;;;N;;;;;
+1D96D;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;
+1D96E;SIGNWRITING MOVEMENT-FLOORPLANE CROSS;So;0;L;;;;;N;;;;;
+1D96F;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE STRAIGHT MOVEMENT;So;0;L;;;;;N;;;;;
+1D970;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE WRIST FLEX;So;0;L;;;;;N;;;;;
+1D971;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE ALTERNATING MOVEMENT;So;0;L;;;;;N;;;;;
+1D972;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;
+1D973;SIGNWRITING MOVEMENT-FLOORPLANE BEND;So;0;L;;;;;N;;;;;
+1D974;SIGNWRITING MOVEMENT-FLOORPLANE CORNER SMALL;So;0;L;;;;;N;;;;;
+1D975;SIGNWRITING MOVEMENT-FLOORPLANE CORNER MEDIUM;So;0;L;;;;;N;;;;;
+1D976;SIGNWRITING MOVEMENT-FLOORPLANE CORNER LARGE;So;0;L;;;;;N;;;;;
+1D977;SIGNWRITING MOVEMENT-FLOORPLANE CHECK;So;0;L;;;;;N;;;;;
+1D978;SIGNWRITING MOVEMENT-FLOORPLANE BOX SMALL;So;0;L;;;;;N;;;;;
+1D979;SIGNWRITING MOVEMENT-FLOORPLANE BOX MEDIUM;So;0;L;;;;;N;;;;;
+1D97A;SIGNWRITING MOVEMENT-FLOORPLANE BOX LARGE;So;0;L;;;;;N;;;;;
+1D97B;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG SMALL;So;0;L;;;;;N;;;;;
+1D97C;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG MEDIUM;So;0;L;;;;;N;;;;;
+1D97D;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG LARGE;So;0;L;;;;;N;;;;;
+1D97E;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS SMALL;So;0;L;;;;;N;;;;;
+1D97F;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS MEDIUM;So;0;L;;;;;N;;;;;
+1D980;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS LARGE;So;0;L;;;;;N;;;;;
+1D981;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D982;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D983;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;;
+1D984;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D985;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D986;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE ALTERNATING;So;0;L;;;;;N;;;;;
+1D987;SIGNWRITING TRAVEL-FLOORPLANE SHAKING;So;0;L;;;;;N;;;;;
+1D988;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER SMALL;So;0;L;;;;;N;;;;;
+1D989;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER MEDIUM;So;0;L;;;;;N;;;;;
+1D98A;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER LARGE;So;0;L;;;;;N;;;;;
+1D98B;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER LARGEST;So;0;L;;;;;N;;;;;
+1D98C;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE SMALL;So;0;L;;;;;N;;;;;
+1D98D;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE MEDIUM;So;0;L;;;;;N;;;;;
+1D98E;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE LARGE;So;0;L;;;;;N;;;;;
+1D98F;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE LARGEST;So;0;L;;;;;N;;;;;
+1D990;SIGNWRITING MOVEMENT-WALLPLANE CURVE THREE-QUARTER CIRCLE SMALL;So;0;L;;;;;N;;;;;
+1D991;SIGNWRITING MOVEMENT-WALLPLANE CURVE THREE-QUARTER CIRCLE MEDIUM;So;0;L;;;;;N;;;;;
+1D992;SIGNWRITING MOVEMENT-WALLPLANE HUMP SMALL;So;0;L;;;;;N;;;;;
+1D993;SIGNWRITING MOVEMENT-WALLPLANE HUMP MEDIUM;So;0;L;;;;;N;;;;;
+1D994;SIGNWRITING MOVEMENT-WALLPLANE HUMP LARGE;So;0;L;;;;;N;;;;;
+1D995;SIGNWRITING MOVEMENT-WALLPLANE LOOP SMALL;So;0;L;;;;;N;;;;;
+1D996;SIGNWRITING MOVEMENT-WALLPLANE LOOP MEDIUM;So;0;L;;;;;N;;;;;
+1D997;SIGNWRITING MOVEMENT-WALLPLANE LOOP LARGE;So;0;L;;;;;N;;;;;
+1D998;SIGNWRITING MOVEMENT-WALLPLANE LOOP SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D999;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE SMALL;So;0;L;;;;;N;;;;;
+1D99A;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE MEDIUM;So;0;L;;;;;N;;;;;
+1D99B;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE LARGE;So;0;L;;;;;N;;;;;
+1D99C;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE SMALL;So;0;L;;;;;N;;;;;
+1D99D;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE MEDIUM;So;0;L;;;;;N;;;;;
+1D99E;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE LARGE;So;0;L;;;;;N;;;;;
+1D99F;SIGNWRITING MOVEMENT-WALLPLANE CURVE THEN STRAIGHT;So;0;L;;;;;N;;;;;
+1D9A0;SIGNWRITING MOVEMENT-WALLPLANE CURVED CROSS SMALL;So;0;L;;;;;N;;;;;
+1D9A1;SIGNWRITING MOVEMENT-WALLPLANE CURVED CROSS MEDIUM;So;0;L;;;;;N;;;;;
+1D9A2;SIGNWRITING ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D9A3;SIGNWRITING ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D9A4;SIGNWRITING ROTATION-WALLPLANE ALTERNATE;So;0;L;;;;;N;;;;;
+1D9A5;SIGNWRITING MOVEMENT-WALLPLANE SHAKING;So;0;L;;;;;N;;;;;
+1D9A6;SIGNWRITING MOVEMENT-WALLPLANE CURVE HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9A7;SIGNWRITING MOVEMENT-WALLPLANE HUMP HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9A8;SIGNWRITING MOVEMENT-WALLPLANE LOOP HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9A9;SIGNWRITING MOVEMENT-WALLPLANE WAVE HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9AA;SIGNWRITING ROTATION-WALLPLANE SINGLE HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9AB;SIGNWRITING ROTATION-WALLPLANE DOUBLE HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9AC;SIGNWRITING ROTATION-WALLPLANE ALTERNATING HITTING FRONT WALL;So;0;L;;;;;N;;;;;
+1D9AD;SIGNWRITING MOVEMENT-WALLPLANE CURVE HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9AE;SIGNWRITING MOVEMENT-WALLPLANE HUMP HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9AF;SIGNWRITING MOVEMENT-WALLPLANE LOOP HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9B0;SIGNWRITING MOVEMENT-WALLPLANE WAVE HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9B1;SIGNWRITING ROTATION-WALLPLANE SINGLE HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9B2;SIGNWRITING ROTATION-WALLPLANE DOUBLE HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9B3;SIGNWRITING ROTATION-WALLPLANE ALTERNATING HITTING CHEST;So;0;L;;;;;N;;;;;
+1D9B4;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH SMALL;So;0;L;;;;;N;;;;;
+1D9B5;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH MEDIUM;So;0;L;;;;;N;;;;;
+1D9B6;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH LARGE;So;0;L;;;;;N;;;;;
+1D9B7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING CEILING SMALL;So;0;L;;;;;N;;;;;
+1D9B8;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING CEILING LARGE;So;0;L;;;;;N;;;;;
+1D9B9;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9BA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING LARGE DOUBLE;So;0;L;;;;;N;;;;;
+1D9BB;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING SMALL TRIPLE;So;0;L;;;;;N;;;;;
+1D9BC;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING LARGE TRIPLE;So;0;L;;;;;N;;;;;
+1D9BD;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D9BE;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING LARGE SINGLE;So;0;L;;;;;N;;;;;
+1D9BF;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9C0;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING LARGE DOUBLE;So;0;L;;;;;N;;;;;
+1D9C1;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING CEILING SMALL;So;0;L;;;;;N;;;;;
+1D9C2;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING CEILING LARGE;So;0;L;;;;;N;;;;;
+1D9C3;SIGNWRITING ROTATION-FLOORPLANE SINGLE HITTING CEILING;So;0;L;;;;;N;;;;;
+1D9C4;SIGNWRITING ROTATION-FLOORPLANE DOUBLE HITTING CEILING;So;0;L;;;;;N;;;;;
+1D9C5;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING HITTING CEILING;So;0;L;;;;;N;;;;;
+1D9C6;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING FLOOR SMALL;So;0;L;;;;;N;;;;;
+1D9C7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING FLOOR LARGE;So;0;L;;;;;N;;;;;
+1D9C8;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9C9;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR LARGE DOUBLE;So;0;L;;;;;N;;;;;
+1D9CA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR TRIPLE SMALL TRIPLE;So;0;L;;;;;N;;;;;
+1D9CB;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR TRIPLE LARGE TRIPLE;So;0;L;;;;;N;;;;;
+1D9CC;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D9CD;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR LARGE SINGLE;So;0;L;;;;;N;;;;;
+1D9CE;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9CF;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR LARGE DOUBLE;So;0;L;;;;;N;;;;;
+1D9D0;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING FLOOR SMALL;So;0;L;;;;;N;;;;;
+1D9D1;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING FLOOR LARGE;So;0;L;;;;;N;;;;;
+1D9D2;SIGNWRITING ROTATION-FLOORPLANE SINGLE HITTING FLOOR;So;0;L;;;;;N;;;;;
+1D9D3;SIGNWRITING ROTATION-FLOORPLANE DOUBLE HITTING FLOOR;So;0;L;;;;;N;;;;;
+1D9D4;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING HITTING FLOOR;So;0;L;;;;;N;;;;;
+1D9D5;SIGNWRITING MOVEMENT-FLOORPLANE CURVE SMALL;So;0;L;;;;;N;;;;;
+1D9D6;SIGNWRITING MOVEMENT-FLOORPLANE CURVE MEDIUM;So;0;L;;;;;N;;;;;
+1D9D7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE LARGE;So;0;L;;;;;N;;;;;
+1D9D8;SIGNWRITING MOVEMENT-FLOORPLANE CURVE LARGEST;So;0;L;;;;;N;;;;;
+1D9D9;SIGNWRITING MOVEMENT-FLOORPLANE CURVE COMBINED;So;0;L;;;;;N;;;;;
+1D9DA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP SMALL;So;0;L;;;;;N;;;;;
+1D9DB;SIGNWRITING MOVEMENT-FLOORPLANE LOOP SMALL;So;0;L;;;;;N;;;;;
+1D9DC;SIGNWRITING MOVEMENT-FLOORPLANE WAVE SNAKE;So;0;L;;;;;N;;;;;
+1D9DD;SIGNWRITING MOVEMENT-FLOORPLANE WAVE SMALL;So;0;L;;;;;N;;;;;
+1D9DE;SIGNWRITING MOVEMENT-FLOORPLANE WAVE LARGE;So;0;L;;;;;N;;;;;
+1D9DF;SIGNWRITING ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;;
+1D9E0;SIGNWRITING ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;;
+1D9E1;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;;
+1D9E2;SIGNWRITING MOVEMENT-FLOORPLANE SHAKING PARALLEL;So;0;L;;;;;N;;;;;
+1D9E3;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D9E4;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE MEDIUM SINGLE;So;0;L;;;;;N;;;;;
+1D9E5;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9E6;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE MEDIUM DOUBLE;So;0;L;;;;;N;;;;;
+1D9E7;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL SMALL SINGLE;So;0;L;;;;;N;;;;;
+1D9E8;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL MEDIUM SINGLE;So;0;L;;;;;N;;;;;
+1D9E9;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL LARGE SINGLE;So;0;L;;;;;N;;;;;
+1D9EA;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL SMALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9EB;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL MEDIUM DOUBLE;So;0;L;;;;;N;;;;;
+1D9EC;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL LARGE DOUBLE;So;0;L;;;;;N;;;;;
+1D9ED;SIGNWRITING MOVEMENT-WALLPLANE WRIST CIRCLE FRONT SINGLE;So;0;L;;;;;N;;;;;
+1D9EE;SIGNWRITING MOVEMENT-WALLPLANE WRIST CIRCLE FRONT DOUBLE;So;0;L;;;;;N;;;;;
+1D9EF;SIGNWRITING MOVEMENT-FLOORPLANE WRIST CIRCLE HITTING WALL SINGLE;So;0;L;;;;;N;;;;;
+1D9F0;SIGNWRITING MOVEMENT-FLOORPLANE WRIST CIRCLE HITTING WALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9F1;SIGNWRITING MOVEMENT-WALLPLANE FINGER CIRCLES SINGLE;So;0;L;;;;;N;;;;;
+1D9F2;SIGNWRITING MOVEMENT-WALLPLANE FINGER CIRCLES DOUBLE;So;0;L;;;;;N;;;;;
+1D9F3;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CIRCLES HITTING WALL SINGLE;So;0;L;;;;;N;;;;;
+1D9F4;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CIRCLES HITTING WALL DOUBLE;So;0;L;;;;;N;;;;;
+1D9F5;SIGNWRITING DYNAMIC ARROWHEAD SMALL;So;0;L;;;;;N;;;;;
+1D9F6;SIGNWRITING DYNAMIC ARROWHEAD LARGE;So;0;L;;;;;N;;;;;
+1D9F7;SIGNWRITING DYNAMIC FAST;So;0;L;;;;;N;;;;;
+1D9F8;SIGNWRITING DYNAMIC SLOW;So;0;L;;;;;N;;;;;
+1D9F9;SIGNWRITING DYNAMIC TENSE;So;0;L;;;;;N;;;;;
+1D9FA;SIGNWRITING DYNAMIC RELAXED;So;0;L;;;;;N;;;;;
+1D9FB;SIGNWRITING DYNAMIC SIMULTANEOUS;So;0;L;;;;;N;;;;;
+1D9FC;SIGNWRITING DYNAMIC SIMULTANEOUS ALTERNATING;So;0;L;;;;;N;;;;;
+1D9FD;SIGNWRITING DYNAMIC EVERY OTHER TIME;So;0;L;;;;;N;;;;;
+1D9FE;SIGNWRITING DYNAMIC GRADUAL;So;0;L;;;;;N;;;;;
+1D9FF;SIGNWRITING HEAD;So;0;L;;;;;N;;;;;
+1DA00;SIGNWRITING HEAD RIM;Mn;0;NSM;;;;;N;;;;;
+1DA01;SIGNWRITING HEAD MOVEMENT-WALLPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;
+1DA02;SIGNWRITING HEAD MOVEMENT-WALLPLANE TILT;Mn;0;NSM;;;;;N;;;;;
+1DA03;SIGNWRITING HEAD MOVEMENT-FLOORPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;
+1DA04;SIGNWRITING HEAD MOVEMENT-WALLPLANE CURVE;Mn;0;NSM;;;;;N;;;;;
+1DA05;SIGNWRITING HEAD MOVEMENT-FLOORPLANE CURVE;Mn;0;NSM;;;;;N;;;;;
+1DA06;SIGNWRITING HEAD MOVEMENT CIRCLE;Mn;0;NSM;;;;;N;;;;;
+1DA07;SIGNWRITING FACE DIRECTION POSITION NOSE FORWARD TILTING;Mn;0;NSM;;;;;N;;;;;
+1DA08;SIGNWRITING FACE DIRECTION POSITION NOSE UP OR DOWN;Mn;0;NSM;;;;;N;;;;;
+1DA09;SIGNWRITING FACE DIRECTION POSITION NOSE UP OR DOWN TILTING;Mn;0;NSM;;;;;N;;;;;
+1DA0A;SIGNWRITING EYEBROWS STRAIGHT UP;Mn;0;NSM;;;;;N;;;;;
+1DA0B;SIGNWRITING EYEBROWS STRAIGHT NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA0C;SIGNWRITING EYEBROWS STRAIGHT DOWN;Mn;0;NSM;;;;;N;;;;;
+1DA0D;SIGNWRITING DREAMY EYEBROWS NEUTRAL DOWN;Mn;0;NSM;;;;;N;;;;;
+1DA0E;SIGNWRITING DREAMY EYEBROWS DOWN NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA0F;SIGNWRITING DREAMY EYEBROWS UP NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA10;SIGNWRITING DREAMY EYEBROWS NEUTRAL UP;Mn;0;NSM;;;;;N;;;;;
+1DA11;SIGNWRITING FOREHEAD NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA12;SIGNWRITING FOREHEAD CONTACT;Mn;0;NSM;;;;;N;;;;;
+1DA13;SIGNWRITING FOREHEAD WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA14;SIGNWRITING EYES OPEN;Mn;0;NSM;;;;;N;;;;;
+1DA15;SIGNWRITING EYES SQUEEZED;Mn;0;NSM;;;;;N;;;;;
+1DA16;SIGNWRITING EYES CLOSED;Mn;0;NSM;;;;;N;;;;;
+1DA17;SIGNWRITING EYE BLINK SINGLE;Mn;0;NSM;;;;;N;;;;;
+1DA18;SIGNWRITING EYE BLINK MULTIPLE;Mn;0;NSM;;;;;N;;;;;
+1DA19;SIGNWRITING EYES HALF OPEN;Mn;0;NSM;;;;;N;;;;;
+1DA1A;SIGNWRITING EYES WIDE OPEN;Mn;0;NSM;;;;;N;;;;;
+1DA1B;SIGNWRITING EYES HALF CLOSED;Mn;0;NSM;;;;;N;;;;;
+1DA1C;SIGNWRITING EYES WIDENING MOVEMENT;Mn;0;NSM;;;;;N;;;;;
+1DA1D;SIGNWRITING EYE WINK;Mn;0;NSM;;;;;N;;;;;
+1DA1E;SIGNWRITING EYELASHES UP;Mn;0;NSM;;;;;N;;;;;
+1DA1F;SIGNWRITING EYELASHES DOWN;Mn;0;NSM;;;;;N;;;;;
+1DA20;SIGNWRITING EYELASHES FLUTTERING;Mn;0;NSM;;;;;N;;;;;
+1DA21;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;
+1DA22;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT DOUBLE;Mn;0;NSM;;;;;N;;;;;
+1DA23;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT ALTERNATING;Mn;0;NSM;;;;;N;;;;;
+1DA24;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;
+1DA25;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT DOUBLE;Mn;0;NSM;;;;;N;;;;;
+1DA26;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT ALTERNATING;Mn;0;NSM;;;;;N;;;;;
+1DA27;SIGNWRITING EYEGAZE-WALLPLANE CURVED;Mn;0;NSM;;;;;N;;;;;
+1DA28;SIGNWRITING EYEGAZE-FLOORPLANE CURVED;Mn;0;NSM;;;;;N;;;;;
+1DA29;SIGNWRITING EYEGAZE-WALLPLANE CIRCLING;Mn;0;NSM;;;;;N;;;;;
+1DA2A;SIGNWRITING CHEEKS PUFFED;Mn;0;NSM;;;;;N;;;;;
+1DA2B;SIGNWRITING CHEEKS NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA2C;SIGNWRITING CHEEKS SUCKED;Mn;0;NSM;;;;;N;;;;;
+1DA2D;SIGNWRITING TENSE CHEEKS HIGH;Mn;0;NSM;;;;;N;;;;;
+1DA2E;SIGNWRITING TENSE CHEEKS MIDDLE;Mn;0;NSM;;;;;N;;;;;
+1DA2F;SIGNWRITING TENSE CHEEKS LOW;Mn;0;NSM;;;;;N;;;;;
+1DA30;SIGNWRITING EARS;Mn;0;NSM;;;;;N;;;;;
+1DA31;SIGNWRITING NOSE NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA32;SIGNWRITING NOSE CONTACT;Mn;0;NSM;;;;;N;;;;;
+1DA33;SIGNWRITING NOSE WRINKLES;Mn;0;NSM;;;;;N;;;;;
+1DA34;SIGNWRITING NOSE WIGGLES;Mn;0;NSM;;;;;N;;;;;
+1DA35;SIGNWRITING AIR BLOWING OUT;Mn;0;NSM;;;;;N;;;;;
+1DA36;SIGNWRITING AIR SUCKING IN;Mn;0;NSM;;;;;N;;;;;
+1DA37;SIGNWRITING AIR BLOW SMALL ROTATIONS;So;0;L;;;;;N;;;;;
+1DA38;SIGNWRITING AIR SUCK SMALL ROTATIONS;So;0;L;;;;;N;;;;;
+1DA39;SIGNWRITING BREATH INHALE;So;0;L;;;;;N;;;;;
+1DA3A;SIGNWRITING BREATH EXHALE;So;0;L;;;;;N;;;;;
+1DA3B;SIGNWRITING MOUTH CLOSED NEUTRAL;Mn;0;NSM;;;;;N;;;;;
+1DA3C;SIGNWRITING MOUTH CLOSED FORWARD;Mn;0;NSM;;;;;N;;;;;
+1DA3D;SIGNWRITING MOUTH CLOSED CONTACT;Mn;0;NSM;;;;;N;;;;;
+1DA3E;SIGNWRITING MOUTH SMILE;Mn;0;NSM;;;;;N;;;;;
+1DA3F;SIGNWRITING MOUTH SMILE WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA40;SIGNWRITING MOUTH SMILE OPEN;Mn;0;NSM;;;;;N;;;;;
+1DA41;SIGNWRITING MOUTH FROWN;Mn;0;NSM;;;;;N;;;;;
+1DA42;SIGNWRITING MOUTH FROWN WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA43;SIGNWRITING MOUTH FROWN OPEN;Mn;0;NSM;;;;;N;;;;;
+1DA44;SIGNWRITING MOUTH OPEN CIRCLE;Mn;0;NSM;;;;;N;;;;;
+1DA45;SIGNWRITING MOUTH OPEN FORWARD;Mn;0;NSM;;;;;N;;;;;
+1DA46;SIGNWRITING MOUTH OPEN WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA47;SIGNWRITING MOUTH OPEN OVAL;Mn;0;NSM;;;;;N;;;;;
+1DA48;SIGNWRITING MOUTH OPEN OVAL WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA49;SIGNWRITING MOUTH OPEN OVAL YAWN;Mn;0;NSM;;;;;N;;;;;
+1DA4A;SIGNWRITING MOUTH OPEN RECTANGLE;Mn;0;NSM;;;;;N;;;;;
+1DA4B;SIGNWRITING MOUTH OPEN RECTANGLE WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA4C;SIGNWRITING MOUTH OPEN RECTANGLE YAWN;Mn;0;NSM;;;;;N;;;;;
+1DA4D;SIGNWRITING MOUTH KISS;Mn;0;NSM;;;;;N;;;;;
+1DA4E;SIGNWRITING MOUTH KISS FORWARD;Mn;0;NSM;;;;;N;;;;;
+1DA4F;SIGNWRITING MOUTH KISS WRINKLED;Mn;0;NSM;;;;;N;;;;;
+1DA50;SIGNWRITING MOUTH TENSE;Mn;0;NSM;;;;;N;;;;;
+1DA51;SIGNWRITING MOUTH TENSE FORWARD;Mn;0;NSM;;;;;N;;;;;
+1DA52;SIGNWRITING MOUTH TENSE SUCKED;Mn;0;NSM;;;;;N;;;;;
+1DA53;SIGNWRITING LIPS PRESSED TOGETHER;Mn;0;NSM;;;;;N;;;;;
+1DA54;SIGNWRITING LIP LOWER OVER UPPER;Mn;0;NSM;;;;;N;;;;;
+1DA55;SIGNWRITING LIP UPPER OVER LOWER;Mn;0;NSM;;;;;N;;;;;
+1DA56;SIGNWRITING MOUTH CORNERS;Mn;0;NSM;;;;;N;;;;;
+1DA57;SIGNWRITING MOUTH WRINKLES SINGLE;Mn;0;NSM;;;;;N;;;;;
+1DA58;SIGNWRITING MOUTH WRINKLES DOUBLE;Mn;0;NSM;;;;;N;;;;;
+1DA59;SIGNWRITING TONGUE STICKING OUT FAR;Mn;0;NSM;;;;;N;;;;;
+1DA5A;SIGNWRITING TONGUE LICKING LIPS;Mn;0;NSM;;;;;N;;;;;
+1DA5B;SIGNWRITING TONGUE TIP BETWEEN LIPS;Mn;0;NSM;;;;;N;;;;;
+1DA5C;SIGNWRITING TONGUE TIP TOUCHING INSIDE MOUTH;Mn;0;NSM;;;;;N;;;;;
+1DA5D;SIGNWRITING TONGUE INSIDE MOUTH RELAXED;Mn;0;NSM;;;;;N;;;;;
+1DA5E;SIGNWRITING TONGUE MOVES AGAINST CHEEK;Mn;0;NSM;;;;;N;;;;;
+1DA5F;SIGNWRITING TONGUE CENTRE STICKING OUT;Mn;0;NSM;;;;;N;;;;;
+1DA60;SIGNWRITING TONGUE CENTRE INSIDE MOUTH;Mn;0;NSM;;;;;N;;;;;
+1DA61;SIGNWRITING TEETH;Mn;0;NSM;;;;;N;;;;;
+1DA62;SIGNWRITING TEETH MOVEMENT;Mn;0;NSM;;;;;N;;;;;
+1DA63;SIGNWRITING TEETH ON TONGUE;Mn;0;NSM;;;;;N;;;;;
+1DA64;SIGNWRITING TEETH ON TONGUE MOVEMENT;Mn;0;NSM;;;;;N;;;;;
+1DA65;SIGNWRITING TEETH ON LIPS;Mn;0;NSM;;;;;N;;;;;
+1DA66;SIGNWRITING TEETH ON LIPS MOVEMENT;Mn;0;NSM;;;;;N;;;;;
+1DA67;SIGNWRITING TEETH BITE LIPS;Mn;0;NSM;;;;;N;;;;;
+1DA68;SIGNWRITING MOVEMENT-WALLPLANE JAW;Mn;0;NSM;;;;;N;;;;;
+1DA69;SIGNWRITING MOVEMENT-FLOORPLANE JAW;Mn;0;NSM;;;;;N;;;;;
+1DA6A;SIGNWRITING NECK;Mn;0;NSM;;;;;N;;;;;
+1DA6B;SIGNWRITING HAIR;Mn;0;NSM;;;;;N;;;;;
+1DA6C;SIGNWRITING EXCITEMENT;Mn;0;NSM;;;;;N;;;;;
+1DA6D;SIGNWRITING SHOULDER HIP SPINE;So;0;L;;;;;N;;;;;
+1DA6E;SIGNWRITING SHOULDER HIP POSITIONS;So;0;L;;;;;N;;;;;
+1DA6F;SIGNWRITING WALLPLANE SHOULDER HIP MOVE;So;0;L;;;;;N;;;;;
+1DA70;SIGNWRITING FLOORPLANE SHOULDER HIP MOVE;So;0;L;;;;;N;;;;;
+1DA71;SIGNWRITING SHOULDER TILTING FROM WAIST;So;0;L;;;;;N;;;;;
+1DA72;SIGNWRITING TORSO-WALLPLANE STRAIGHT STRETCH;So;0;L;;;;;N;;;;;
+1DA73;SIGNWRITING TORSO-WALLPLANE CURVED BEND;So;0;L;;;;;N;;;;;
+1DA74;SIGNWRITING TORSO-FLOORPLANE TWISTING;So;0;L;;;;;N;;;;;
+1DA75;SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS;Mn;0;NSM;;;;;N;;;;;
+1DA76;SIGNWRITING LIMB COMBINATION;So;0;L;;;;;N;;;;;
+1DA77;SIGNWRITING LIMB LENGTH-1;So;0;L;;;;;N;;;;;
+1DA78;SIGNWRITING LIMB LENGTH-2;So;0;L;;;;;N;;;;;
+1DA79;SIGNWRITING LIMB LENGTH-3;So;0;L;;;;;N;;;;;
+1DA7A;SIGNWRITING LIMB LENGTH-4;So;0;L;;;;;N;;;;;
+1DA7B;SIGNWRITING LIMB LENGTH-5;So;0;L;;;;;N;;;;;
+1DA7C;SIGNWRITING LIMB LENGTH-6;So;0;L;;;;;N;;;;;
+1DA7D;SIGNWRITING LIMB LENGTH-7;So;0;L;;;;;N;;;;;
+1DA7E;SIGNWRITING FINGER;So;0;L;;;;;N;;;;;
+1DA7F;SIGNWRITING LOCATION-WALLPLANE SPACE;So;0;L;;;;;N;;;;;
+1DA80;SIGNWRITING LOCATION-FLOORPLANE SPACE;So;0;L;;;;;N;;;;;
+1DA81;SIGNWRITING LOCATION HEIGHT;So;0;L;;;;;N;;;;;
+1DA82;SIGNWRITING LOCATION WIDTH;So;0;L;;;;;N;;;;;
+1DA83;SIGNWRITING LOCATION DEPTH;So;0;L;;;;;N;;;;;
+1DA84;SIGNWRITING LOCATION HEAD NECK;Mn;0;NSM;;;;;N;;;;;
+1DA85;SIGNWRITING LOCATION TORSO;So;0;L;;;;;N;;;;;
+1DA86;SIGNWRITING LOCATION LIMBS DIGITS;So;0;L;;;;;N;;;;;
+1DA87;SIGNWRITING COMMA;Po;0;L;;;;;N;;;;;
+1DA88;SIGNWRITING FULL STOP;Po;0;L;;;;;N;;;;;
+1DA89;SIGNWRITING SEMICOLON;Po;0;L;;;;;N;;;;;
+1DA8A;SIGNWRITING COLON;Po;0;L;;;;;N;;;;;
+1DA8B;SIGNWRITING PARENTHESIS;Po;0;L;;;;;N;;;;;
+1DA9B;SIGNWRITING FILL MODIFIER-2;Mn;0;NSM;;;;;N;;;;;
+1DA9C;SIGNWRITING FILL MODIFIER-3;Mn;0;NSM;;;;;N;;;;;
+1DA9D;SIGNWRITING FILL MODIFIER-4;Mn;0;NSM;;;;;N;;;;;
+1DA9E;SIGNWRITING FILL MODIFIER-5;Mn;0;NSM;;;;;N;;;;;
+1DA9F;SIGNWRITING FILL MODIFIER-6;Mn;0;NSM;;;;;N;;;;;
+1DAA1;SIGNWRITING ROTATION MODIFIER-2;Mn;0;NSM;;;;;N;;;;;
+1DAA2;SIGNWRITING ROTATION MODIFIER-3;Mn;0;NSM;;;;;N;;;;;
+1DAA3;SIGNWRITING ROTATION MODIFIER-4;Mn;0;NSM;;;;;N;;;;;
+1DAA4;SIGNWRITING ROTATION MODIFIER-5;Mn;0;NSM;;;;;N;;;;;
+1DAA5;SIGNWRITING ROTATION MODIFIER-6;Mn;0;NSM;;;;;N;;;;;
+1DAA6;SIGNWRITING ROTATION MODIFIER-7;Mn;0;NSM;;;;;N;;;;;
+1DAA7;SIGNWRITING ROTATION MODIFIER-8;Mn;0;NSM;;;;;N;;;;;
+1DAA8;SIGNWRITING ROTATION MODIFIER-9;Mn;0;NSM;;;;;N;;;;;
+1DAA9;SIGNWRITING ROTATION MODIFIER-10;Mn;0;NSM;;;;;N;;;;;
+1DAAA;SIGNWRITING ROTATION MODIFIER-11;Mn;0;NSM;;;;;N;;;;;
+1DAAB;SIGNWRITING ROTATION MODIFIER-12;Mn;0;NSM;;;;;N;;;;;
+1DAAC;SIGNWRITING ROTATION MODIFIER-13;Mn;0;NSM;;;;;N;;;;;
+1DAAD;SIGNWRITING ROTATION MODIFIER-14;Mn;0;NSM;;;;;N;;;;;
+1DAAE;SIGNWRITING ROTATION MODIFIER-15;Mn;0;NSM;;;;;N;;;;;
+1DAAF;SIGNWRITING ROTATION MODIFIER-16;Mn;0;NSM;;;;;N;;;;;
+1E000;COMBINING GLAGOLITIC LETTER AZU;Mn;230;NSM;;;;;N;;;;;
+1E001;COMBINING GLAGOLITIC LETTER BUKY;Mn;230;NSM;;;;;N;;;;;
+1E002;COMBINING GLAGOLITIC LETTER VEDE;Mn;230;NSM;;;;;N;;;;;
+1E003;COMBINING GLAGOLITIC LETTER GLAGOLI;Mn;230;NSM;;;;;N;;;;;
+1E004;COMBINING GLAGOLITIC LETTER DOBRO;Mn;230;NSM;;;;;N;;;;;
+1E005;COMBINING GLAGOLITIC LETTER YESTU;Mn;230;NSM;;;;;N;;;;;
+1E006;COMBINING GLAGOLITIC LETTER ZHIVETE;Mn;230;NSM;;;;;N;;;;;
+1E008;COMBINING GLAGOLITIC LETTER ZEMLJA;Mn;230;NSM;;;;;N;;;;;
+1E009;COMBINING GLAGOLITIC LETTER IZHE;Mn;230;NSM;;;;;N;;;;;
+1E00A;COMBINING GLAGOLITIC LETTER INITIAL IZHE;Mn;230;NSM;;;;;N;;;;;
+1E00B;COMBINING GLAGOLITIC LETTER I;Mn;230;NSM;;;;;N;;;;;
+1E00C;COMBINING GLAGOLITIC LETTER DJERVI;Mn;230;NSM;;;;;N;;;;;
+1E00D;COMBINING GLAGOLITIC LETTER KAKO;Mn;230;NSM;;;;;N;;;;;
+1E00E;COMBINING GLAGOLITIC LETTER LJUDIJE;Mn;230;NSM;;;;;N;;;;;
+1E00F;COMBINING GLAGOLITIC LETTER MYSLITE;Mn;230;NSM;;;;;N;;;;;
+1E010;COMBINING GLAGOLITIC LETTER NASHI;Mn;230;NSM;;;;;N;;;;;
+1E011;COMBINING GLAGOLITIC LETTER ONU;Mn;230;NSM;;;;;N;;;;;
+1E012;COMBINING GLAGOLITIC LETTER POKOJI;Mn;230;NSM;;;;;N;;;;;
+1E013;COMBINING GLAGOLITIC LETTER RITSI;Mn;230;NSM;;;;;N;;;;;
+1E014;COMBINING GLAGOLITIC LETTER SLOVO;Mn;230;NSM;;;;;N;;;;;
+1E015;COMBINING GLAGOLITIC LETTER TVRIDO;Mn;230;NSM;;;;;N;;;;;
+1E016;COMBINING GLAGOLITIC LETTER UKU;Mn;230;NSM;;;;;N;;;;;
+1E017;COMBINING GLAGOLITIC LETTER FRITU;Mn;230;NSM;;;;;N;;;;;
+1E018;COMBINING GLAGOLITIC LETTER HERU;Mn;230;NSM;;;;;N;;;;;
+1E01B;COMBINING GLAGOLITIC LETTER SHTA;Mn;230;NSM;;;;;N;;;;;
+1E01C;COMBINING GLAGOLITIC LETTER TSI;Mn;230;NSM;;;;;N;;;;;
+1E01D;COMBINING GLAGOLITIC LETTER CHRIVI;Mn;230;NSM;;;;;N;;;;;
+1E01E;COMBINING GLAGOLITIC LETTER SHA;Mn;230;NSM;;;;;N;;;;;
+1E01F;COMBINING GLAGOLITIC LETTER YERU;Mn;230;NSM;;;;;N;;;;;
+1E020;COMBINING GLAGOLITIC LETTER YERI;Mn;230;NSM;;;;;N;;;;;
+1E021;COMBINING GLAGOLITIC LETTER YATI;Mn;230;NSM;;;;;N;;;;;
+1E023;COMBINING GLAGOLITIC LETTER YU;Mn;230;NSM;;;;;N;;;;;
+1E024;COMBINING GLAGOLITIC LETTER SMALL YUS;Mn;230;NSM;;;;;N;;;;;
+1E026;COMBINING GLAGOLITIC LETTER YO;Mn;230;NSM;;;;;N;;;;;
+1E027;COMBINING GLAGOLITIC LETTER IOTATED SMALL YUS;Mn;230;NSM;;;;;N;;;;;
+1E028;COMBINING GLAGOLITIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;;
+1E029;COMBINING GLAGOLITIC LETTER IOTATED BIG YUS;Mn;230;NSM;;;;;N;;;;;
+1E02A;COMBINING GLAGOLITIC LETTER FITA;Mn;230;NSM;;;;;N;;;;;
+1E800;MENDE KIKAKUI SYLLABLE M001 KI;Lo;0;R;;;;;N;;;;;
+1E801;MENDE KIKAKUI SYLLABLE M002 KA;Lo;0;R;;;;;N;;;;;
+1E802;MENDE KIKAKUI SYLLABLE M003 KU;Lo;0;R;;;;;N;;;;;
+1E803;MENDE KIKAKUI SYLLABLE M065 KEE;Lo;0;R;;;;;N;;;;;
+1E804;MENDE KIKAKUI SYLLABLE M095 KE;Lo;0;R;;;;;N;;;;;
+1E805;MENDE KIKAKUI SYLLABLE M076 KOO;Lo;0;R;;;;;N;;;;;
+1E806;MENDE KIKAKUI SYLLABLE M048 KO;Lo;0;R;;;;;N;;;;;
+1E807;MENDE KIKAKUI SYLLABLE M179 KUA;Lo;0;R;;;;;N;;;;;
+1E808;MENDE KIKAKUI SYLLABLE M004 WI;Lo;0;R;;;;;N;;;;;
+1E809;MENDE KIKAKUI SYLLABLE M005 WA;Lo;0;R;;;;;N;;;;;
+1E80A;MENDE KIKAKUI SYLLABLE M006 WU;Lo;0;R;;;;;N;;;;;
+1E80B;MENDE KIKAKUI SYLLABLE M126 WEE;Lo;0;R;;;;;N;;;;;
+1E80C;MENDE KIKAKUI SYLLABLE M118 WE;Lo;0;R;;;;;N;;;;;
+1E80D;MENDE KIKAKUI SYLLABLE M114 WOO;Lo;0;R;;;;;N;;;;;
+1E80E;MENDE KIKAKUI SYLLABLE M045 WO;Lo;0;R;;;;;N;;;;;
+1E80F;MENDE KIKAKUI SYLLABLE M194 WUI;Lo;0;R;;;;;N;;;;;
+1E810;MENDE KIKAKUI SYLLABLE M143 WEI;Lo;0;R;;;;;N;;;;;
+1E811;MENDE KIKAKUI SYLLABLE M061 WVI;Lo;0;R;;;;;N;;;;;
+1E812;MENDE KIKAKUI SYLLABLE M049 WVA;Lo;0;R;;;;;N;;;;;
+1E813;MENDE KIKAKUI SYLLABLE M139 WVE;Lo;0;R;;;;;N;;;;;
+1E814;MENDE KIKAKUI SYLLABLE M007 MIN;Lo;0;R;;;;;N;;;;;
+1E815;MENDE KIKAKUI SYLLABLE M008 MAN;Lo;0;R;;;;;N;;;;;
+1E816;MENDE KIKAKUI SYLLABLE M009 MUN;Lo;0;R;;;;;N;;;;;
+1E817;MENDE KIKAKUI SYLLABLE M059 MEN;Lo;0;R;;;;;N;;;;;
+1E818;MENDE KIKAKUI SYLLABLE M094 MON;Lo;0;R;;;;;N;;;;;
+1E819;MENDE KIKAKUI SYLLABLE M154 MUAN;Lo;0;R;;;;;N;;;;;
+1E81A;MENDE KIKAKUI SYLLABLE M189 MUEN;Lo;0;R;;;;;N;;;;;
+1E81B;MENDE KIKAKUI SYLLABLE M010 BI;Lo;0;R;;;;;N;;;;;
+1E81C;MENDE KIKAKUI SYLLABLE M011 BA;Lo;0;R;;;;;N;;;;;
+1E81D;MENDE KIKAKUI SYLLABLE M012 BU;Lo;0;R;;;;;N;;;;;
+1E81E;MENDE KIKAKUI SYLLABLE M150 BEE;Lo;0;R;;;;;N;;;;;
+1E81F;MENDE KIKAKUI SYLLABLE M097 BE;Lo;0;R;;;;;N;;;;;
+1E820;MENDE KIKAKUI SYLLABLE M103 BOO;Lo;0;R;;;;;N;;;;;
+1E821;MENDE KIKAKUI SYLLABLE M138 BO;Lo;0;R;;;;;N;;;;;
+1E822;MENDE KIKAKUI SYLLABLE M013 I;Lo;0;R;;;;;N;;;;;
+1E823;MENDE KIKAKUI SYLLABLE M014 A;Lo;0;R;;;;;N;;;;;
+1E824;MENDE KIKAKUI SYLLABLE M015 U;Lo;0;R;;;;;N;;;;;
+1E825;MENDE KIKAKUI SYLLABLE M163 EE;Lo;0;R;;;;;N;;;;;
+1E826;MENDE KIKAKUI SYLLABLE M100 E;Lo;0;R;;;;;N;;;;;
+1E827;MENDE KIKAKUI SYLLABLE M165 OO;Lo;0;R;;;;;N;;;;;
+1E828;MENDE KIKAKUI SYLLABLE M147 O;Lo;0;R;;;;;N;;;;;
+1E829;MENDE KIKAKUI SYLLABLE M137 EI;Lo;0;R;;;;;N;;;;;
+1E82A;MENDE KIKAKUI SYLLABLE M131 IN;Lo;0;R;;;;;N;;;;;
+1E82B;MENDE KIKAKUI SYLLABLE M135 IN;Lo;0;R;;;;;N;;;;;
+1E82C;MENDE KIKAKUI SYLLABLE M195 AN;Lo;0;R;;;;;N;;;;;
+1E82D;MENDE KIKAKUI SYLLABLE M178 EN;Lo;0;R;;;;;N;;;;;
+1E82E;MENDE KIKAKUI SYLLABLE M019 SI;Lo;0;R;;;;;N;;;;;
+1E82F;MENDE KIKAKUI SYLLABLE M020 SA;Lo;0;R;;;;;N;;;;;
+1E830;MENDE KIKAKUI SYLLABLE M021 SU;Lo;0;R;;;;;N;;;;;
+1E831;MENDE KIKAKUI SYLLABLE M162 SEE;Lo;0;R;;;;;N;;;;;
+1E832;MENDE KIKAKUI SYLLABLE M116 SE;Lo;0;R;;;;;N;;;;;
+1E833;MENDE KIKAKUI SYLLABLE M136 SOO;Lo;0;R;;;;;N;;;;;
+1E834;MENDE KIKAKUI SYLLABLE M079 SO;Lo;0;R;;;;;N;;;;;
+1E835;MENDE KIKAKUI SYLLABLE M196 SIA;Lo;0;R;;;;;N;;;;;
+1E836;MENDE KIKAKUI SYLLABLE M025 LI;Lo;0;R;;;;;N;;;;;
+1E837;MENDE KIKAKUI SYLLABLE M026 LA;Lo;0;R;;;;;N;;;;;
+1E838;MENDE KIKAKUI SYLLABLE M027 LU;Lo;0;R;;;;;N;;;;;
+1E839;MENDE KIKAKUI SYLLABLE M084 LEE;Lo;0;R;;;;;N;;;;;
+1E83A;MENDE KIKAKUI SYLLABLE M073 LE;Lo;0;R;;;;;N;;;;;
+1E83B;MENDE KIKAKUI SYLLABLE M054 LOO;Lo;0;R;;;;;N;;;;;
+1E83C;MENDE KIKAKUI SYLLABLE M153 LO;Lo;0;R;;;;;N;;;;;
+1E83D;MENDE KIKAKUI SYLLABLE M110 LONG LE;Lo;0;R;;;;;N;;;;;
+1E83E;MENDE KIKAKUI SYLLABLE M016 DI;Lo;0;R;;;;;N;;;;;
+1E83F;MENDE KIKAKUI SYLLABLE M017 DA;Lo;0;R;;;;;N;;;;;
+1E840;MENDE KIKAKUI SYLLABLE M018 DU;Lo;0;R;;;;;N;;;;;
+1E841;MENDE KIKAKUI SYLLABLE M089 DEE;Lo;0;R;;;;;N;;;;;
+1E842;MENDE KIKAKUI SYLLABLE M180 DOO;Lo;0;R;;;;;N;;;;;
+1E843;MENDE KIKAKUI SYLLABLE M181 DO;Lo;0;R;;;;;N;;;;;
+1E844;MENDE KIKAKUI SYLLABLE M022 TI;Lo;0;R;;;;;N;;;;;
+1E845;MENDE KIKAKUI SYLLABLE M023 TA;Lo;0;R;;;;;N;;;;;
+1E846;MENDE KIKAKUI SYLLABLE M024 TU;Lo;0;R;;;;;N;;;;;
+1E847;MENDE KIKAKUI SYLLABLE M091 TEE;Lo;0;R;;;;;N;;;;;
+1E848;MENDE KIKAKUI SYLLABLE M055 TE;Lo;0;R;;;;;N;;;;;
+1E849;MENDE KIKAKUI SYLLABLE M104 TOO;Lo;0;R;;;;;N;;;;;
+1E84A;MENDE KIKAKUI SYLLABLE M069 TO;Lo;0;R;;;;;N;;;;;
+1E84B;MENDE KIKAKUI SYLLABLE M028 JI;Lo;0;R;;;;;N;;;;;
+1E84C;MENDE KIKAKUI SYLLABLE M029 JA;Lo;0;R;;;;;N;;;;;
+1E84D;MENDE KIKAKUI SYLLABLE M030 JU;Lo;0;R;;;;;N;;;;;
+1E84E;MENDE KIKAKUI SYLLABLE M157 JEE;Lo;0;R;;;;;N;;;;;
+1E84F;MENDE KIKAKUI SYLLABLE M113 JE;Lo;0;R;;;;;N;;;;;
+1E850;MENDE KIKAKUI SYLLABLE M160 JOO;Lo;0;R;;;;;N;;;;;
+1E851;MENDE KIKAKUI SYLLABLE M063 JO;Lo;0;R;;;;;N;;;;;
+1E852;MENDE KIKAKUI SYLLABLE M175 LONG JO;Lo;0;R;;;;;N;;;;;
+1E853;MENDE KIKAKUI SYLLABLE M031 YI;Lo;0;R;;;;;N;;;;;
+1E854;MENDE KIKAKUI SYLLABLE M032 YA;Lo;0;R;;;;;N;;;;;
+1E855;MENDE KIKAKUI SYLLABLE M033 YU;Lo;0;R;;;;;N;;;;;
+1E856;MENDE KIKAKUI SYLLABLE M109 YEE;Lo;0;R;;;;;N;;;;;
+1E857;MENDE KIKAKUI SYLLABLE M080 YE;Lo;0;R;;;;;N;;;;;
+1E858;MENDE KIKAKUI SYLLABLE M141 YOO;Lo;0;R;;;;;N;;;;;
+1E859;MENDE KIKAKUI SYLLABLE M121 YO;Lo;0;R;;;;;N;;;;;
+1E85A;MENDE KIKAKUI SYLLABLE M034 FI;Lo;0;R;;;;;N;;;;;
+1E85B;MENDE KIKAKUI SYLLABLE M035 FA;Lo;0;R;;;;;N;;;;;
+1E85C;MENDE KIKAKUI SYLLABLE M036 FU;Lo;0;R;;;;;N;;;;;
+1E85D;MENDE KIKAKUI SYLLABLE M078 FEE;Lo;0;R;;;;;N;;;;;
+1E85E;MENDE KIKAKUI SYLLABLE M075 FE;Lo;0;R;;;;;N;;;;;
+1E85F;MENDE KIKAKUI SYLLABLE M133 FOO;Lo;0;R;;;;;N;;;;;
+1E860;MENDE KIKAKUI SYLLABLE M088 FO;Lo;0;R;;;;;N;;;;;
+1E861;MENDE KIKAKUI SYLLABLE M197 FUA;Lo;0;R;;;;;N;;;;;
+1E862;MENDE KIKAKUI SYLLABLE M101 FAN;Lo;0;R;;;;;N;;;;;
+1E863;MENDE KIKAKUI SYLLABLE M037 NIN;Lo;0;R;;;;;N;;;;;
+1E864;MENDE KIKAKUI SYLLABLE M038 NAN;Lo;0;R;;;;;N;;;;;
+1E865;MENDE KIKAKUI SYLLABLE M039 NUN;Lo;0;R;;;;;N;;;;;
+1E866;MENDE KIKAKUI SYLLABLE M117 NEN;Lo;0;R;;;;;N;;;;;
+1E867;MENDE KIKAKUI SYLLABLE M169 NON;Lo;0;R;;;;;N;;;;;
+1E868;MENDE KIKAKUI SYLLABLE M176 HI;Lo;0;R;;;;;N;;;;;
+1E869;MENDE KIKAKUI SYLLABLE M041 HA;Lo;0;R;;;;;N;;;;;
+1E86A;MENDE KIKAKUI SYLLABLE M186 HU;Lo;0;R;;;;;N;;;;;
+1E86B;MENDE KIKAKUI SYLLABLE M040 HEE;Lo;0;R;;;;;N;;;;;
+1E86C;MENDE KIKAKUI SYLLABLE M096 HE;Lo;0;R;;;;;N;;;;;
+1E86D;MENDE KIKAKUI SYLLABLE M042 HOO;Lo;0;R;;;;;N;;;;;
+1E86E;MENDE KIKAKUI SYLLABLE M140 HO;Lo;0;R;;;;;N;;;;;
+1E86F;MENDE KIKAKUI SYLLABLE M083 HEEI;Lo;0;R;;;;;N;;;;;
+1E870;MENDE KIKAKUI SYLLABLE M128 HOOU;Lo;0;R;;;;;N;;;;;
+1E871;MENDE KIKAKUI SYLLABLE M053 HIN;Lo;0;R;;;;;N;;;;;
+1E872;MENDE KIKAKUI SYLLABLE M130 HAN;Lo;0;R;;;;;N;;;;;
+1E873;MENDE KIKAKUI SYLLABLE M087 HUN;Lo;0;R;;;;;N;;;;;
+1E874;MENDE KIKAKUI SYLLABLE M052 HEN;Lo;0;R;;;;;N;;;;;
+1E875;MENDE KIKAKUI SYLLABLE M193 HON;Lo;0;R;;;;;N;;;;;
+1E876;MENDE KIKAKUI SYLLABLE M046 HUAN;Lo;0;R;;;;;N;;;;;
+1E877;MENDE KIKAKUI SYLLABLE M090 NGGI;Lo;0;R;;;;;N;;;;;
+1E878;MENDE KIKAKUI SYLLABLE M043 NGGA;Lo;0;R;;;;;N;;;;;
+1E879;MENDE KIKAKUI SYLLABLE M082 NGGU;Lo;0;R;;;;;N;;;;;
+1E87A;MENDE KIKAKUI SYLLABLE M115 NGGEE;Lo;0;R;;;;;N;;;;;
+1E87B;MENDE KIKAKUI SYLLABLE M146 NGGE;Lo;0;R;;;;;N;;;;;
+1E87C;MENDE KIKAKUI SYLLABLE M156 NGGOO;Lo;0;R;;;;;N;;;;;
+1E87D;MENDE KIKAKUI SYLLABLE M120 NGGO;Lo;0;R;;;;;N;;;;;
+1E87E;MENDE KIKAKUI SYLLABLE M159 NGGAA;Lo;0;R;;;;;N;;;;;
+1E87F;MENDE KIKAKUI SYLLABLE M127 NGGUA;Lo;0;R;;;;;N;;;;;
+1E880;MENDE KIKAKUI SYLLABLE M086 LONG NGGE;Lo;0;R;;;;;N;;;;;
+1E881;MENDE KIKAKUI SYLLABLE M106 LONG NGGOO;Lo;0;R;;;;;N;;;;;
+1E882;MENDE KIKAKUI SYLLABLE M183 LONG NGGO;Lo;0;R;;;;;N;;;;;
+1E883;MENDE KIKAKUI SYLLABLE M155 GI;Lo;0;R;;;;;N;;;;;
+1E884;MENDE KIKAKUI SYLLABLE M111 GA;Lo;0;R;;;;;N;;;;;
+1E885;MENDE KIKAKUI SYLLABLE M168 GU;Lo;0;R;;;;;N;;;;;
+1E886;MENDE KIKAKUI SYLLABLE M190 GEE;Lo;0;R;;;;;N;;;;;
+1E887;MENDE KIKAKUI SYLLABLE M166 GUEI;Lo;0;R;;;;;N;;;;;
+1E888;MENDE KIKAKUI SYLLABLE M167 GUAN;Lo;0;R;;;;;N;;;;;
+1E889;MENDE KIKAKUI SYLLABLE M184 NGEN;Lo;0;R;;;;;N;;;;;
+1E88A;MENDE KIKAKUI SYLLABLE M057 NGON;Lo;0;R;;;;;N;;;;;
+1E88B;MENDE KIKAKUI SYLLABLE M177 NGUAN;Lo;0;R;;;;;N;;;;;
+1E88C;MENDE KIKAKUI SYLLABLE M068 PI;Lo;0;R;;;;;N;;;;;
+1E88D;MENDE KIKAKUI SYLLABLE M099 PA;Lo;0;R;;;;;N;;;;;
+1E88E;MENDE KIKAKUI SYLLABLE M050 PU;Lo;0;R;;;;;N;;;;;
+1E88F;MENDE KIKAKUI SYLLABLE M081 PEE;Lo;0;R;;;;;N;;;;;
+1E890;MENDE KIKAKUI SYLLABLE M051 PE;Lo;0;R;;;;;N;;;;;
+1E891;MENDE KIKAKUI SYLLABLE M102 POO;Lo;0;R;;;;;N;;;;;
+1E892;MENDE KIKAKUI SYLLABLE M066 PO;Lo;0;R;;;;;N;;;;;
+1E893;MENDE KIKAKUI SYLLABLE M145 MBI;Lo;0;R;;;;;N;;;;;
+1E894;MENDE KIKAKUI SYLLABLE M062 MBA;Lo;0;R;;;;;N;;;;;
+1E895;MENDE KIKAKUI SYLLABLE M122 MBU;Lo;0;R;;;;;N;;;;;
+1E896;MENDE KIKAKUI SYLLABLE M047 MBEE;Lo;0;R;;;;;N;;;;;
+1E897;MENDE KIKAKUI SYLLABLE M188 MBEE;Lo;0;R;;;;;N;;;;;
+1E898;MENDE KIKAKUI SYLLABLE M072 MBE;Lo;0;R;;;;;N;;;;;
+1E899;MENDE KIKAKUI SYLLABLE M172 MBOO;Lo;0;R;;;;;N;;;;;
+1E89A;MENDE KIKAKUI SYLLABLE M174 MBO;Lo;0;R;;;;;N;;;;;
+1E89B;MENDE KIKAKUI SYLLABLE M187 MBUU;Lo;0;R;;;;;N;;;;;
+1E89C;MENDE KIKAKUI SYLLABLE M161 LONG MBE;Lo;0;R;;;;;N;;;;;
+1E89D;MENDE KIKAKUI SYLLABLE M105 LONG MBOO;Lo;0;R;;;;;N;;;;;
+1E89E;MENDE KIKAKUI SYLLABLE M142 LONG MBO;Lo;0;R;;;;;N;;;;;
+1E89F;MENDE KIKAKUI SYLLABLE M132 KPI;Lo;0;R;;;;;N;;;;;
+1E8A0;MENDE KIKAKUI SYLLABLE M092 KPA;Lo;0;R;;;;;N;;;;;
+1E8A1;MENDE KIKAKUI SYLLABLE M074 KPU;Lo;0;R;;;;;N;;;;;
+1E8A2;MENDE KIKAKUI SYLLABLE M044 KPEE;Lo;0;R;;;;;N;;;;;
+1E8A3;MENDE KIKAKUI SYLLABLE M108 KPE;Lo;0;R;;;;;N;;;;;
+1E8A4;MENDE KIKAKUI SYLLABLE M112 KPOO;Lo;0;R;;;;;N;;;;;
+1E8A5;MENDE KIKAKUI SYLLABLE M158 KPO;Lo;0;R;;;;;N;;;;;
+1E8A6;MENDE KIKAKUI SYLLABLE M124 GBI;Lo;0;R;;;;;N;;;;;
+1E8A7;MENDE KIKAKUI SYLLABLE M056 GBA;Lo;0;R;;;;;N;;;;;
+1E8A8;MENDE KIKAKUI SYLLABLE M148 GBU;Lo;0;R;;;;;N;;;;;
+1E8A9;MENDE KIKAKUI SYLLABLE M093 GBEE;Lo;0;R;;;;;N;;;;;
+1E8AA;MENDE KIKAKUI SYLLABLE M107 GBE;Lo;0;R;;;;;N;;;;;
+1E8AB;MENDE KIKAKUI SYLLABLE M071 GBOO;Lo;0;R;;;;;N;;;;;
+1E8AC;MENDE KIKAKUI SYLLABLE M070 GBO;Lo;0;R;;;;;N;;;;;
+1E8AD;MENDE KIKAKUI SYLLABLE M171 RA;Lo;0;R;;;;;N;;;;;
+1E8AE;MENDE KIKAKUI SYLLABLE M123 NDI;Lo;0;R;;;;;N;;;;;
+1E8AF;MENDE KIKAKUI SYLLABLE M129 NDA;Lo;0;R;;;;;N;;;;;
+1E8B0;MENDE KIKAKUI SYLLABLE M125 NDU;Lo;0;R;;;;;N;;;;;
+1E8B1;MENDE KIKAKUI SYLLABLE M191 NDEE;Lo;0;R;;;;;N;;;;;
+1E8B2;MENDE KIKAKUI SYLLABLE M119 NDE;Lo;0;R;;;;;N;;;;;
+1E8B3;MENDE KIKAKUI SYLLABLE M067 NDOO;Lo;0;R;;;;;N;;;;;
+1E8B4;MENDE KIKAKUI SYLLABLE M064 NDO;Lo;0;R;;;;;N;;;;;
+1E8B5;MENDE KIKAKUI SYLLABLE M152 NJA;Lo;0;R;;;;;N;;;;;
+1E8B6;MENDE KIKAKUI SYLLABLE M192 NJU;Lo;0;R;;;;;N;;;;;
+1E8B7;MENDE KIKAKUI SYLLABLE M149 NJEE;Lo;0;R;;;;;N;;;;;
+1E8B8;MENDE KIKAKUI SYLLABLE M134 NJOO;Lo;0;R;;;;;N;;;;;
+1E8B9;MENDE KIKAKUI SYLLABLE M182 VI;Lo;0;R;;;;;N;;;;;
+1E8BA;MENDE KIKAKUI SYLLABLE M185 VA;Lo;0;R;;;;;N;;;;;
+1E8BB;MENDE KIKAKUI SYLLABLE M151 VU;Lo;0;R;;;;;N;;;;;
+1E8BC;MENDE KIKAKUI SYLLABLE M173 VEE;Lo;0;R;;;;;N;;;;;
+1E8BD;MENDE KIKAKUI SYLLABLE M085 VE;Lo;0;R;;;;;N;;;;;
+1E8BE;MENDE KIKAKUI SYLLABLE M144 VOO;Lo;0;R;;;;;N;;;;;
+1E8BF;MENDE KIKAKUI SYLLABLE M077 VO;Lo;0;R;;;;;N;;;;;
+1E8C0;MENDE KIKAKUI SYLLABLE M164 NYIN;Lo;0;R;;;;;N;;;;;
+1E8C1;MENDE KIKAKUI SYLLABLE M058 NYAN;Lo;0;R;;;;;N;;;;;
+1E8C2;MENDE KIKAKUI SYLLABLE M170 NYUN;Lo;0;R;;;;;N;;;;;
+1E8C3;MENDE KIKAKUI SYLLABLE M098 NYEN;Lo;0;R;;;;;N;;;;;
+1E8C4;MENDE KIKAKUI SYLLABLE M060 NYON;Lo;0;R;;;;;N;;;;;
+1E8C7;MENDE KIKAKUI DIGIT ONE;No;0;R;;;;1;N;;;;;
+1E8C8;MENDE KIKAKUI DIGIT TWO;No;0;R;;;;2;N;;;;;
+1E8C9;MENDE KIKAKUI DIGIT THREE;No;0;R;;;;3;N;;;;;
+1E8CA;MENDE KIKAKUI DIGIT FOUR;No;0;R;;;;4;N;;;;;
+1E8CB;MENDE KIKAKUI DIGIT FIVE;No;0;R;;;;5;N;;;;;
+1E8CC;MENDE KIKAKUI DIGIT SIX;No;0;R;;;;6;N;;;;;
+1E8CD;MENDE KIKAKUI DIGIT SEVEN;No;0;R;;;;7;N;;;;;
+1E8CE;MENDE KIKAKUI DIGIT EIGHT;No;0;R;;;;8;N;;;;;
+1E8CF;MENDE KIKAKUI DIGIT NINE;No;0;R;;;;9;N;;;;;
+1E8D0;MENDE KIKAKUI COMBINING NUMBER TEENS;Mn;220;NSM;;;;;N;;;;;
+1E8D1;MENDE KIKAKUI COMBINING NUMBER TENS;Mn;220;NSM;;;;;N;;;;;
+1E8D2;MENDE KIKAKUI COMBINING NUMBER HUNDREDS;Mn;220;NSM;;;;;N;;;;;
+1E8D3;MENDE KIKAKUI COMBINING NUMBER THOUSANDS;Mn;220;NSM;;;;;N;;;;;
+1E8D4;MENDE KIKAKUI COMBINING NUMBER TEN THOUSANDS;Mn;220;NSM;;;;;N;;;;;
+1E8D5;MENDE KIKAKUI COMBINING NUMBER HUNDRED THOUSANDS;Mn;220;NSM;;;;;N;;;;;
+1E8D6;MENDE KIKAKUI COMBINING NUMBER MILLIONS;Mn;220;NSM;;;;;N;;;;;
+1E900;ADLAM CAPITAL LETTER ALIF;Lu;0;R;;;;;N;;;;1E922;
+1E901;ADLAM CAPITAL LETTER DAALI;Lu;0;R;;;;;N;;;;1E923;
+1E902;ADLAM CAPITAL LETTER LAAM;Lu;0;R;;;;;N;;;;1E924;
+1E903;ADLAM CAPITAL LETTER MIIM;Lu;0;R;;;;;N;;;;1E925;
+1E904;ADLAM CAPITAL LETTER BA;Lu;0;R;;;;;N;;;;1E926;
+1E905;ADLAM CAPITAL LETTER SINNYIIYHE;Lu;0;R;;;;;N;;;;1E927;
+1E906;ADLAM CAPITAL LETTER PE;Lu;0;R;;;;;N;;;;1E928;
+1E907;ADLAM CAPITAL LETTER BHE;Lu;0;R;;;;;N;;;;1E929;
+1E908;ADLAM CAPITAL LETTER RA;Lu;0;R;;;;;N;;;;1E92A;
+1E909;ADLAM CAPITAL LETTER E;Lu;0;R;;;;;N;;;;1E92B;
+1E90A;ADLAM CAPITAL LETTER FA;Lu;0;R;;;;;N;;;;1E92C;
+1E90B;ADLAM CAPITAL LETTER I;Lu;0;R;;;;;N;;;;1E92D;
+1E90C;ADLAM CAPITAL LETTER O;Lu;0;R;;;;;N;;;;1E92E;
+1E90D;ADLAM CAPITAL LETTER DHA;Lu;0;R;;;;;N;;;;1E92F;
+1E90E;ADLAM CAPITAL LETTER YHE;Lu;0;R;;;;;N;;;;1E930;
+1E90F;ADLAM CAPITAL LETTER WAW;Lu;0;R;;;;;N;;;;1E931;
+1E910;ADLAM CAPITAL LETTER NUN;Lu;0;R;;;;;N;;;;1E932;
+1E911;ADLAM CAPITAL LETTER KAF;Lu;0;R;;;;;N;;;;1E933;
+1E912;ADLAM CAPITAL LETTER YA;Lu;0;R;;;;;N;;;;1E934;
+1E913;ADLAM CAPITAL LETTER U;Lu;0;R;;;;;N;;;;1E935;
+1E914;ADLAM CAPITAL LETTER JIIM;Lu;0;R;;;;;N;;;;1E936;
+1E915;ADLAM CAPITAL LETTER CHI;Lu;0;R;;;;;N;;;;1E937;
+1E916;ADLAM CAPITAL LETTER HA;Lu;0;R;;;;;N;;;;1E938;
+1E917;ADLAM CAPITAL LETTER QAAF;Lu;0;R;;;;;N;;;;1E939;
+1E918;ADLAM CAPITAL LETTER GA;Lu;0;R;;;;;N;;;;1E93A;
+1E919;ADLAM CAPITAL LETTER NYA;Lu;0;R;;;;;N;;;;1E93B;
+1E91A;ADLAM CAPITAL LETTER TU;Lu;0;R;;;;;N;;;;1E93C;
+1E91B;ADLAM CAPITAL LETTER NHA;Lu;0;R;;;;;N;;;;1E93D;
+1E91C;ADLAM CAPITAL LETTER VA;Lu;0;R;;;;;N;;;;1E93E;
+1E91D;ADLAM CAPITAL LETTER KHA;Lu;0;R;;;;;N;;;;1E93F;
+1E91E;ADLAM CAPITAL LETTER GBE;Lu;0;R;;;;;N;;;;1E940;
+1E91F;ADLAM CAPITAL LETTER ZAL;Lu;0;R;;;;;N;;;;1E941;
+1E920;ADLAM CAPITAL LETTER KPO;Lu;0;R;;;;;N;;;;1E942;
+1E921;ADLAM CAPITAL LETTER SHA;Lu;0;R;;;;;N;;;;1E943;
+1E922;ADLAM SMALL LETTER ALIF;Ll;0;R;;;;;N;;;1E900;;1E900
+1E923;ADLAM SMALL LETTER DAALI;Ll;0;R;;;;;N;;;1E901;;1E901
+1E924;ADLAM SMALL LETTER LAAM;Ll;0;R;;;;;N;;;1E902;;1E902
+1E925;ADLAM SMALL LETTER MIIM;Ll;0;R;;;;;N;;;1E903;;1E903
+1E926;ADLAM SMALL LETTER BA;Ll;0;R;;;;;N;;;1E904;;1E904
+1E927;ADLAM SMALL LETTER SINNYIIYHE;Ll;0;R;;;;;N;;;1E905;;1E905
+1E928;ADLAM SMALL LETTER PE;Ll;0;R;;;;;N;;;1E906;;1E906
+1E929;ADLAM SMALL LETTER BHE;Ll;0;R;;;;;N;;;1E907;;1E907
+1E92A;ADLAM SMALL LETTER RA;Ll;0;R;;;;;N;;;1E908;;1E908
+1E92B;ADLAM SMALL LETTER E;Ll;0;R;;;;;N;;;1E909;;1E909
+1E92C;ADLAM SMALL LETTER FA;Ll;0;R;;;;;N;;;1E90A;;1E90A
+1E92D;ADLAM SMALL LETTER I;Ll;0;R;;;;;N;;;1E90B;;1E90B
+1E92E;ADLAM SMALL LETTER O;Ll;0;R;;;;;N;;;1E90C;;1E90C
+1E92F;ADLAM SMALL LETTER DHA;Ll;0;R;;;;;N;;;1E90D;;1E90D
+1E930;ADLAM SMALL LETTER YHE;Ll;0;R;;;;;N;;;1E90E;;1E90E
+1E931;ADLAM SMALL LETTER WAW;Ll;0;R;;;;;N;;;1E90F;;1E90F
+1E932;ADLAM SMALL LETTER NUN;Ll;0;R;;;;;N;;;1E910;;1E910
+1E933;ADLAM SMALL LETTER KAF;Ll;0;R;;;;;N;;;1E911;;1E911
+1E934;ADLAM SMALL LETTER YA;Ll;0;R;;;;;N;;;1E912;;1E912
+1E935;ADLAM SMALL LETTER U;Ll;0;R;;;;;N;;;1E913;;1E913
+1E936;ADLAM SMALL LETTER JIIM;Ll;0;R;;;;;N;;;1E914;;1E914
+1E937;ADLAM SMALL LETTER CHI;Ll;0;R;;;;;N;;;1E915;;1E915
+1E938;ADLAM SMALL LETTER HA;Ll;0;R;;;;;N;;;1E916;;1E916
+1E939;ADLAM SMALL LETTER QAAF;Ll;0;R;;;;;N;;;1E917;;1E917
+1E93A;ADLAM SMALL LETTER GA;Ll;0;R;;;;;N;;;1E918;;1E918
+1E93B;ADLAM SMALL LETTER NYA;Ll;0;R;;;;;N;;;1E919;;1E919
+1E93C;ADLAM SMALL LETTER TU;Ll;0;R;;;;;N;;;1E91A;;1E91A
+1E93D;ADLAM SMALL LETTER NHA;Ll;0;R;;;;;N;;;1E91B;;1E91B
+1E93E;ADLAM SMALL LETTER VA;Ll;0;R;;;;;N;;;1E91C;;1E91C
+1E93F;ADLAM SMALL LETTER KHA;Ll;0;R;;;;;N;;;1E91D;;1E91D
+1E940;ADLAM SMALL LETTER GBE;Ll;0;R;;;;;N;;;1E91E;;1E91E
+1E941;ADLAM SMALL LETTER ZAL;Ll;0;R;;;;;N;;;1E91F;;1E91F
+1E942;ADLAM SMALL LETTER KPO;Ll;0;R;;;;;N;;;1E920;;1E920
+1E943;ADLAM SMALL LETTER SHA;Ll;0;R;;;;;N;;;1E921;;1E921
+1E944;ADLAM ALIF LENGTHENER;Mn;230;NSM;;;;;N;;;;;
+1E945;ADLAM VOWEL LENGTHENER;Mn;230;NSM;;;;;N;;;;;
+1E946;ADLAM GEMINATION MARK;Mn;230;NSM;;;;;N;;;;;
+1E947;ADLAM HAMZA;Mn;230;NSM;;;;;N;;;;;
+1E948;ADLAM CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;;
+1E949;ADLAM GEMINATE CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;;
+1E94A;ADLAM NUKTA;Mn;7;NSM;;;;;N;;;;;
+1E950;ADLAM DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;;
+1E951;ADLAM DIGIT ONE;Nd;0;R;;1;1;1;N;;;;;
+1E952;ADLAM DIGIT TWO;Nd;0;R;;2;2;2;N;;;;;
+1E953;ADLAM DIGIT THREE;Nd;0;R;;3;3;3;N;;;;;
+1E954;ADLAM DIGIT FOUR;Nd;0;R;;4;4;4;N;;;;;
+1E955;ADLAM DIGIT FIVE;Nd;0;R;;5;5;5;N;;;;;
+1E956;ADLAM DIGIT SIX;Nd;0;R;;6;6;6;N;;;;;
+1E957;ADLAM DIGIT SEVEN;Nd;0;R;;7;7;7;N;;;;;
+1E958;ADLAM DIGIT EIGHT;Nd;0;R;;8;8;8;N;;;;;
+1E959;ADLAM DIGIT NINE;Nd;0;R;;9;9;9;N;;;;;
+1E95E;ADLAM INITIAL EXCLAMATION MARK;Po;0;R;;;;;N;;;;;
+1E95F;ADLAM INITIAL QUESTION MARK;Po;0;R;;;;;N;;;;;
+1EE00;ARABIC MATHEMATICAL ALEF;Lo;0;AL;<font> 0627;;;;N;;;;;
+1EE01;ARABIC MATHEMATICAL BEH;Lo;0;AL;<font> 0628;;;;N;;;;;
+1EE02;ARABIC MATHEMATICAL JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EE03;ARABIC MATHEMATICAL DAL;Lo;0;AL;<font> 062F;;;;N;;;;;
+1EE05;ARABIC MATHEMATICAL WAW;Lo;0;AL;<font> 0648;;;;N;;;;;
+1EE06;ARABIC MATHEMATICAL ZAIN;Lo;0;AL;<font> 0632;;;;N;;;;;
+1EE07;ARABIC MATHEMATICAL HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EE08;ARABIC MATHEMATICAL TAH;Lo;0;AL;<font> 0637;;;;N;;;;;
+1EE09;ARABIC MATHEMATICAL YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EE0A;ARABIC MATHEMATICAL KAF;Lo;0;AL;<font> 0643;;;;N;;;;;
+1EE0B;ARABIC MATHEMATICAL LAM;Lo;0;AL;<font> 0644;;;;N;;;;;
+1EE0C;ARABIC MATHEMATICAL MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;
+1EE0D;ARABIC MATHEMATICAL NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EE0E;ARABIC MATHEMATICAL SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EE0F;ARABIC MATHEMATICAL AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EE10;ARABIC MATHEMATICAL FEH;Lo;0;AL;<font> 0641;;;;N;;;;;
+1EE11;ARABIC MATHEMATICAL SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EE12;ARABIC MATHEMATICAL QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EE13;ARABIC MATHEMATICAL REH;Lo;0;AL;<font> 0631;;;;N;;;;;
+1EE14;ARABIC MATHEMATICAL SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EE15;ARABIC MATHEMATICAL TEH;Lo;0;AL;<font> 062A;;;;N;;;;;
+1EE16;ARABIC MATHEMATICAL THEH;Lo;0;AL;<font> 062B;;;;N;;;;;
+1EE17;ARABIC MATHEMATICAL KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EE18;ARABIC MATHEMATICAL THAL;Lo;0;AL;<font> 0630;;;;N;;;;;
+1EE19;ARABIC MATHEMATICAL DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EE1A;ARABIC MATHEMATICAL ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;
+1EE1B;ARABIC MATHEMATICAL GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EE1C;ARABIC MATHEMATICAL DOTLESS BEH;Lo;0;AL;<font> 066E;;;;N;;;;;
+1EE1D;ARABIC MATHEMATICAL DOTLESS NOON;Lo;0;AL;<font> 06BA;;;;N;;;;;
+1EE1E;ARABIC MATHEMATICAL DOTLESS FEH;Lo;0;AL;<font> 06A1;;;;N;;;;;
+1EE1F;ARABIC MATHEMATICAL DOTLESS QAF;Lo;0;AL;<font> 066F;;;;N;;;;;
+1EE21;ARABIC MATHEMATICAL INITIAL BEH;Lo;0;AL;<font> 0628;;;;N;;;;;
+1EE22;ARABIC MATHEMATICAL INITIAL JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EE24;ARABIC MATHEMATICAL INITIAL HEH;Lo;0;AL;<font> 0647;;;;N;;;;;
+1EE27;ARABIC MATHEMATICAL INITIAL HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EE29;ARABIC MATHEMATICAL INITIAL YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EE2A;ARABIC MATHEMATICAL INITIAL KAF;Lo;0;AL;<font> 0643;;;;N;;;;;
+1EE2B;ARABIC MATHEMATICAL INITIAL LAM;Lo;0;AL;<font> 0644;;;;N;;;;;
+1EE2C;ARABIC MATHEMATICAL INITIAL MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;
+1EE2D;ARABIC MATHEMATICAL INITIAL NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EE2E;ARABIC MATHEMATICAL INITIAL SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EE2F;ARABIC MATHEMATICAL INITIAL AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EE30;ARABIC MATHEMATICAL INITIAL FEH;Lo;0;AL;<font> 0641;;;;N;;;;;
+1EE31;ARABIC MATHEMATICAL INITIAL SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EE32;ARABIC MATHEMATICAL INITIAL QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EE34;ARABIC MATHEMATICAL INITIAL SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EE35;ARABIC MATHEMATICAL INITIAL TEH;Lo;0;AL;<font> 062A;;;;N;;;;;
+1EE36;ARABIC MATHEMATICAL INITIAL THEH;Lo;0;AL;<font> 062B;;;;N;;;;;
+1EE37;ARABIC MATHEMATICAL INITIAL KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EE39;ARABIC MATHEMATICAL INITIAL DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EE3B;ARABIC MATHEMATICAL INITIAL GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EE42;ARABIC MATHEMATICAL TAILED JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EE47;ARABIC MATHEMATICAL TAILED HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EE49;ARABIC MATHEMATICAL TAILED YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EE4B;ARABIC MATHEMATICAL TAILED LAM;Lo;0;AL;<font> 0644;;;;N;;;;;
+1EE4D;ARABIC MATHEMATICAL TAILED NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EE4E;ARABIC MATHEMATICAL TAILED SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EE4F;ARABIC MATHEMATICAL TAILED AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EE51;ARABIC MATHEMATICAL TAILED SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EE52;ARABIC MATHEMATICAL TAILED QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EE54;ARABIC MATHEMATICAL TAILED SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EE57;ARABIC MATHEMATICAL TAILED KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EE59;ARABIC MATHEMATICAL TAILED DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EE5B;ARABIC MATHEMATICAL TAILED GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EE5D;ARABIC MATHEMATICAL TAILED DOTLESS NOON;Lo;0;AL;<font> 06BA;;;;N;;;;;
+1EE5F;ARABIC MATHEMATICAL TAILED DOTLESS QAF;Lo;0;AL;<font> 066F;;;;N;;;;;
+1EE61;ARABIC MATHEMATICAL STRETCHED BEH;Lo;0;AL;<font> 0628;;;;N;;;;;
+1EE62;ARABIC MATHEMATICAL STRETCHED JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EE64;ARABIC MATHEMATICAL STRETCHED HEH;Lo;0;AL;<font> 0647;;;;N;;;;;
+1EE67;ARABIC MATHEMATICAL STRETCHED HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EE68;ARABIC MATHEMATICAL STRETCHED TAH;Lo;0;AL;<font> 0637;;;;N;;;;;
+1EE69;ARABIC MATHEMATICAL STRETCHED YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EE6A;ARABIC MATHEMATICAL STRETCHED KAF;Lo;0;AL;<font> 0643;;;;N;;;;;
+1EE6C;ARABIC MATHEMATICAL STRETCHED MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;
+1EE6D;ARABIC MATHEMATICAL STRETCHED NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EE6E;ARABIC MATHEMATICAL STRETCHED SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EE6F;ARABIC MATHEMATICAL STRETCHED AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EE70;ARABIC MATHEMATICAL STRETCHED FEH;Lo;0;AL;<font> 0641;;;;N;;;;;
+1EE71;ARABIC MATHEMATICAL STRETCHED SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EE72;ARABIC MATHEMATICAL STRETCHED QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EE74;ARABIC MATHEMATICAL STRETCHED SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EE75;ARABIC MATHEMATICAL STRETCHED TEH;Lo;0;AL;<font> 062A;;;;N;;;;;
+1EE76;ARABIC MATHEMATICAL STRETCHED THEH;Lo;0;AL;<font> 062B;;;;N;;;;;
+1EE77;ARABIC MATHEMATICAL STRETCHED KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EE79;ARABIC MATHEMATICAL STRETCHED DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EE7A;ARABIC MATHEMATICAL STRETCHED ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;
+1EE7B;ARABIC MATHEMATICAL STRETCHED GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EE7C;ARABIC MATHEMATICAL STRETCHED DOTLESS BEH;Lo;0;AL;<font> 066E;;;;N;;;;;
+1EE7E;ARABIC MATHEMATICAL STRETCHED DOTLESS FEH;Lo;0;AL;<font> 06A1;;;;N;;;;;
+1EE80;ARABIC MATHEMATICAL LOOPED ALEF;Lo;0;AL;<font> 0627;;;;N;;;;;
+1EE81;ARABIC MATHEMATICAL LOOPED BEH;Lo;0;AL;<font> 0628;;;;N;;;;;
+1EE82;ARABIC MATHEMATICAL LOOPED JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EE83;ARABIC MATHEMATICAL LOOPED DAL;Lo;0;AL;<font> 062F;;;;N;;;;;
+1EE84;ARABIC MATHEMATICAL LOOPED HEH;Lo;0;AL;<font> 0647;;;;N;;;;;
+1EE85;ARABIC MATHEMATICAL LOOPED WAW;Lo;0;AL;<font> 0648;;;;N;;;;;
+1EE86;ARABIC MATHEMATICAL LOOPED ZAIN;Lo;0;AL;<font> 0632;;;;N;;;;;
+1EE87;ARABIC MATHEMATICAL LOOPED HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EE88;ARABIC MATHEMATICAL LOOPED TAH;Lo;0;AL;<font> 0637;;;;N;;;;;
+1EE89;ARABIC MATHEMATICAL LOOPED YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EE8B;ARABIC MATHEMATICAL LOOPED LAM;Lo;0;AL;<font> 0644;;;;N;;;;;
+1EE8C;ARABIC MATHEMATICAL LOOPED MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;
+1EE8D;ARABIC MATHEMATICAL LOOPED NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EE8E;ARABIC MATHEMATICAL LOOPED SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EE8F;ARABIC MATHEMATICAL LOOPED AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EE90;ARABIC MATHEMATICAL LOOPED FEH;Lo;0;AL;<font> 0641;;;;N;;;;;
+1EE91;ARABIC MATHEMATICAL LOOPED SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EE92;ARABIC MATHEMATICAL LOOPED QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EE93;ARABIC MATHEMATICAL LOOPED REH;Lo;0;AL;<font> 0631;;;;N;;;;;
+1EE94;ARABIC MATHEMATICAL LOOPED SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EE95;ARABIC MATHEMATICAL LOOPED TEH;Lo;0;AL;<font> 062A;;;;N;;;;;
+1EE96;ARABIC MATHEMATICAL LOOPED THEH;Lo;0;AL;<font> 062B;;;;N;;;;;
+1EE97;ARABIC MATHEMATICAL LOOPED KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EE98;ARABIC MATHEMATICAL LOOPED THAL;Lo;0;AL;<font> 0630;;;;N;;;;;
+1EE99;ARABIC MATHEMATICAL LOOPED DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EE9A;ARABIC MATHEMATICAL LOOPED ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;
+1EE9B;ARABIC MATHEMATICAL LOOPED GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EEA1;ARABIC MATHEMATICAL DOUBLE-STRUCK BEH;Lo;0;AL;<font> 0628;;;;N;;;;;
+1EEA2;ARABIC MATHEMATICAL DOUBLE-STRUCK JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
+1EEA3;ARABIC MATHEMATICAL DOUBLE-STRUCK DAL;Lo;0;AL;<font> 062F;;;;N;;;;;
+1EEA5;ARABIC MATHEMATICAL DOUBLE-STRUCK WAW;Lo;0;AL;<font> 0648;;;;N;;;;;
+1EEA6;ARABIC MATHEMATICAL DOUBLE-STRUCK ZAIN;Lo;0;AL;<font> 0632;;;;N;;;;;
+1EEA7;ARABIC MATHEMATICAL DOUBLE-STRUCK HAH;Lo;0;AL;<font> 062D;;;;N;;;;;
+1EEA8;ARABIC MATHEMATICAL DOUBLE-STRUCK TAH;Lo;0;AL;<font> 0637;;;;N;;;;;
+1EEA9;ARABIC MATHEMATICAL DOUBLE-STRUCK YEH;Lo;0;AL;<font> 064A;;;;N;;;;;
+1EEAB;ARABIC MATHEMATICAL DOUBLE-STRUCK LAM;Lo;0;AL;<font> 0644;;;;N;;;;;
+1EEAC;ARABIC MATHEMATICAL DOUBLE-STRUCK MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;
+1EEAD;ARABIC MATHEMATICAL DOUBLE-STRUCK NOON;Lo;0;AL;<font> 0646;;;;N;;;;;
+1EEAE;ARABIC MATHEMATICAL DOUBLE-STRUCK SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;
+1EEAF;ARABIC MATHEMATICAL DOUBLE-STRUCK AIN;Lo;0;AL;<font> 0639;;;;N;;;;;
+1EEB0;ARABIC MATHEMATICAL DOUBLE-STRUCK FEH;Lo;0;AL;<font> 0641;;;;N;;;;;
+1EEB1;ARABIC MATHEMATICAL DOUBLE-STRUCK SAD;Lo;0;AL;<font> 0635;;;;N;;;;;
+1EEB2;ARABIC MATHEMATICAL DOUBLE-STRUCK QAF;Lo;0;AL;<font> 0642;;;;N;;;;;
+1EEB3;ARABIC MATHEMATICAL DOUBLE-STRUCK REH;Lo;0;AL;<font> 0631;;;;N;;;;;
+1EEB4;ARABIC MATHEMATICAL DOUBLE-STRUCK SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;
+1EEB5;ARABIC MATHEMATICAL DOUBLE-STRUCK TEH;Lo;0;AL;<font> 062A;;;;N;;;;;
+1EEB6;ARABIC MATHEMATICAL DOUBLE-STRUCK THEH;Lo;0;AL;<font> 062B;;;;N;;;;;
+1EEB7;ARABIC MATHEMATICAL DOUBLE-STRUCK KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;
+1EEB8;ARABIC MATHEMATICAL DOUBLE-STRUCK THAL;Lo;0;AL;<font> 0630;;;;N;;;;;
+1EEB9;ARABIC MATHEMATICAL DOUBLE-STRUCK DAD;Lo;0;AL;<font> 0636;;;;N;;;;;
+1EEBA;ARABIC MATHEMATICAL DOUBLE-STRUCK ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;
+1EEBB;ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;
+1EEF0;ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL;Sm;0;ON;;;;;N;;;;;
+1EEF1;ARABIC MATHEMATICAL OPERATOR HAH WITH DAL;Sm;0;ON;;;;;N;;;;;
+1F000;MAHJONG TILE EAST WIND;So;0;ON;;;;;N;;;;;
+1F001;MAHJONG TILE SOUTH WIND;So;0;ON;;;;;N;;;;;
+1F002;MAHJONG TILE WEST WIND;So;0;ON;;;;;N;;;;;
+1F003;MAHJONG TILE NORTH WIND;So;0;ON;;;;;N;;;;;
+1F004;MAHJONG TILE RED DRAGON;So;0;ON;;;;;N;;;;;
+1F005;MAHJONG TILE GREEN DRAGON;So;0;ON;;;;;N;;;;;
+1F006;MAHJONG TILE WHITE DRAGON;So;0;ON;;;;;N;;;;;
+1F007;MAHJONG TILE ONE OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F008;MAHJONG TILE TWO OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F009;MAHJONG TILE THREE OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00A;MAHJONG TILE FOUR OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00B;MAHJONG TILE FIVE OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00C;MAHJONG TILE SIX OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00D;MAHJONG TILE SEVEN OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00E;MAHJONG TILE EIGHT OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F00F;MAHJONG TILE NINE OF CHARACTERS;So;0;ON;;;;;N;;;;;
+1F010;MAHJONG TILE ONE OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F011;MAHJONG TILE TWO OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F012;MAHJONG TILE THREE OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F013;MAHJONG TILE FOUR OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F014;MAHJONG TILE FIVE OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F015;MAHJONG TILE SIX OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F016;MAHJONG TILE SEVEN OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F017;MAHJONG TILE EIGHT OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F018;MAHJONG TILE NINE OF BAMBOOS;So;0;ON;;;;;N;;;;;
+1F019;MAHJONG TILE ONE OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01A;MAHJONG TILE TWO OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01B;MAHJONG TILE THREE OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01C;MAHJONG TILE FOUR OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01D;MAHJONG TILE FIVE OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01E;MAHJONG TILE SIX OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F01F;MAHJONG TILE SEVEN OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F020;MAHJONG TILE EIGHT OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F021;MAHJONG TILE NINE OF CIRCLES;So;0;ON;;;;;N;;;;;
+1F022;MAHJONG TILE PLUM;So;0;ON;;;;;N;;;;;
+1F023;MAHJONG TILE ORCHID;So;0;ON;;;;;N;;;;;
+1F024;MAHJONG TILE BAMBOO;So;0;ON;;;;;N;;;;;
+1F025;MAHJONG TILE CHRYSANTHEMUM;So;0;ON;;;;;N;;;;;
+1F026;MAHJONG TILE SPRING;So;0;ON;;;;;N;;;;;
+1F027;MAHJONG TILE SUMMER;So;0;ON;;;;;N;;;;;
+1F028;MAHJONG TILE AUTUMN;So;0;ON;;;;;N;;;;;
+1F029;MAHJONG TILE WINTER;So;0;ON;;;;;N;;;;;
+1F02A;MAHJONG TILE JOKER;So;0;ON;;;;;N;;;;;
+1F02B;MAHJONG TILE BACK;So;0;ON;;;;;N;;;;;
+1F030;DOMINO TILE HORIZONTAL BACK;So;0;ON;;;;;N;;;;;
+1F031;DOMINO TILE HORIZONTAL-00-00;So;0;ON;;;;;N;;;;;
+1F032;DOMINO TILE HORIZONTAL-00-01;So;0;ON;;;;;N;;;;;
+1F033;DOMINO TILE HORIZONTAL-00-02;So;0;ON;;;;;N;;;;;
+1F034;DOMINO TILE HORIZONTAL-00-03;So;0;ON;;;;;N;;;;;
+1F035;DOMINO TILE HORIZONTAL-00-04;So;0;ON;;;;;N;;;;;
+1F036;DOMINO TILE HORIZONTAL-00-05;So;0;ON;;;;;N;;;;;
+1F037;DOMINO TILE HORIZONTAL-00-06;So;0;ON;;;;;N;;;;;
+1F038;DOMINO TILE HORIZONTAL-01-00;So;0;ON;;;;;N;;;;;
+1F039;DOMINO TILE HORIZONTAL-01-01;So;0;ON;;;;;N;;;;;
+1F03A;DOMINO TILE HORIZONTAL-01-02;So;0;ON;;;;;N;;;;;
+1F03B;DOMINO TILE HORIZONTAL-01-03;So;0;ON;;;;;N;;;;;
+1F03C;DOMINO TILE HORIZONTAL-01-04;So;0;ON;;;;;N;;;;;
+1F03D;DOMINO TILE HORIZONTAL-01-05;So;0;ON;;;;;N;;;;;
+1F03E;DOMINO TILE HORIZONTAL-01-06;So;0;ON;;;;;N;;;;;
+1F03F;DOMINO TILE HORIZONTAL-02-00;So;0;ON;;;;;N;;;;;
+1F040;DOMINO TILE HORIZONTAL-02-01;So;0;ON;;;;;N;;;;;
+1F041;DOMINO TILE HORIZONTAL-02-02;So;0;ON;;;;;N;;;;;
+1F042;DOMINO TILE HORIZONTAL-02-03;So;0;ON;;;;;N;;;;;
+1F043;DOMINO TILE HORIZONTAL-02-04;So;0;ON;;;;;N;;;;;
+1F044;DOMINO TILE HORIZONTAL-02-05;So;0;ON;;;;;N;;;;;
+1F045;DOMINO TILE HORIZONTAL-02-06;So;0;ON;;;;;N;;;;;
+1F046;DOMINO TILE HORIZONTAL-03-00;So;0;ON;;;;;N;;;;;
+1F047;DOMINO TILE HORIZONTAL-03-01;So;0;ON;;;;;N;;;;;
+1F048;DOMINO TILE HORIZONTAL-03-02;So;0;ON;;;;;N;;;;;
+1F049;DOMINO TILE HORIZONTAL-03-03;So;0;ON;;;;;N;;;;;
+1F04A;DOMINO TILE HORIZONTAL-03-04;So;0;ON;;;;;N;;;;;
+1F04B;DOMINO TILE HORIZONTAL-03-05;So;0;ON;;;;;N;;;;;
+1F04C;DOMINO TILE HORIZONTAL-03-06;So;0;ON;;;;;N;;;;;
+1F04D;DOMINO TILE HORIZONTAL-04-00;So;0;ON;;;;;N;;;;;
+1F04E;DOMINO TILE HORIZONTAL-04-01;So;0;ON;;;;;N;;;;;
+1F04F;DOMINO TILE HORIZONTAL-04-02;So;0;ON;;;;;N;;;;;
+1F050;DOMINO TILE HORIZONTAL-04-03;So;0;ON;;;;;N;;;;;
+1F051;DOMINO TILE HORIZONTAL-04-04;So;0;ON;;;;;N;;;;;
+1F052;DOMINO TILE HORIZONTAL-04-05;So;0;ON;;;;;N;;;;;
+1F053;DOMINO TILE HORIZONTAL-04-06;So;0;ON;;;;;N;;;;;
+1F054;DOMINO TILE HORIZONTAL-05-00;So;0;ON;;;;;N;;;;;
+1F055;DOMINO TILE HORIZONTAL-05-01;So;0;ON;;;;;N;;;;;
+1F056;DOMINO TILE HORIZONTAL-05-02;So;0;ON;;;;;N;;;;;
+1F057;DOMINO TILE HORIZONTAL-05-03;So;0;ON;;;;;N;;;;;
+1F058;DOMINO TILE HORIZONTAL-05-04;So;0;ON;;;;;N;;;;;
+1F059;DOMINO TILE HORIZONTAL-05-05;So;0;ON;;;;;N;;;;;
+1F05A;DOMINO TILE HORIZONTAL-05-06;So;0;ON;;;;;N;;;;;
+1F05B;DOMINO TILE HORIZONTAL-06-00;So;0;ON;;;;;N;;;;;
+1F05C;DOMINO TILE HORIZONTAL-06-01;So;0;ON;;;;;N;;;;;
+1F05D;DOMINO TILE HORIZONTAL-06-02;So;0;ON;;;;;N;;;;;
+1F05E;DOMINO TILE HORIZONTAL-06-03;So;0;ON;;;;;N;;;;;
+1F05F;DOMINO TILE HORIZONTAL-06-04;So;0;ON;;;;;N;;;;;
+1F060;DOMINO TILE HORIZONTAL-06-05;So;0;ON;;;;;N;;;;;
+1F061;DOMINO TILE HORIZONTAL-06-06;So;0;ON;;;;;N;;;;;
+1F062;DOMINO TILE VERTICAL BACK;So;0;ON;;;;;N;;;;;
+1F063;DOMINO TILE VERTICAL-00-00;So;0;ON;;;;;N;;;;;
+1F064;DOMINO TILE VERTICAL-00-01;So;0;ON;;;;;N;;;;;
+1F065;DOMINO TILE VERTICAL-00-02;So;0;ON;;;;;N;;;;;
+1F066;DOMINO TILE VERTICAL-00-03;So;0;ON;;;;;N;;;;;
+1F067;DOMINO TILE VERTICAL-00-04;So;0;ON;;;;;N;;;;;
+1F068;DOMINO TILE VERTICAL-00-05;So;0;ON;;;;;N;;;;;
+1F069;DOMINO TILE VERTICAL-00-06;So;0;ON;;;;;N;;;;;
+1F06A;DOMINO TILE VERTICAL-01-00;So;0;ON;;;;;N;;;;;
+1F06B;DOMINO TILE VERTICAL-01-01;So;0;ON;;;;;N;;;;;
+1F06C;DOMINO TILE VERTICAL-01-02;So;0;ON;;;;;N;;;;;
+1F06D;DOMINO TILE VERTICAL-01-03;So;0;ON;;;;;N;;;;;
+1F06E;DOMINO TILE VERTICAL-01-04;So;0;ON;;;;;N;;;;;
+1F06F;DOMINO TILE VERTICAL-01-05;So;0;ON;;;;;N;;;;;
+1F070;DOMINO TILE VERTICAL-01-06;So;0;ON;;;;;N;;;;;
+1F071;DOMINO TILE VERTICAL-02-00;So;0;ON;;;;;N;;;;;
+1F072;DOMINO TILE VERTICAL-02-01;So;0;ON;;;;;N;;;;;
+1F073;DOMINO TILE VERTICAL-02-02;So;0;ON;;;;;N;;;;;
+1F074;DOMINO TILE VERTICAL-02-03;So;0;ON;;;;;N;;;;;
+1F075;DOMINO TILE VERTICAL-02-04;So;0;ON;;;;;N;;;;;
+1F076;DOMINO TILE VERTICAL-02-05;So;0;ON;;;;;N;;;;;
+1F077;DOMINO TILE VERTICAL-02-06;So;0;ON;;;;;N;;;;;
+1F078;DOMINO TILE VERTICAL-03-00;So;0;ON;;;;;N;;;;;
+1F079;DOMINO TILE VERTICAL-03-01;So;0;ON;;;;;N;;;;;
+1F07A;DOMINO TILE VERTICAL-03-02;So;0;ON;;;;;N;;;;;
+1F07B;DOMINO TILE VERTICAL-03-03;So;0;ON;;;;;N;;;;;
+1F07C;DOMINO TILE VERTICAL-03-04;So;0;ON;;;;;N;;;;;
+1F07D;DOMINO TILE VERTICAL-03-05;So;0;ON;;;;;N;;;;;
+1F07E;DOMINO TILE VERTICAL-03-06;So;0;ON;;;;;N;;;;;
+1F07F;DOMINO TILE VERTICAL-04-00;So;0;ON;;;;;N;;;;;
+1F080;DOMINO TILE VERTICAL-04-01;So;0;ON;;;;;N;;;;;
+1F081;DOMINO TILE VERTICAL-04-02;So;0;ON;;;;;N;;;;;
+1F082;DOMINO TILE VERTICAL-04-03;So;0;ON;;;;;N;;;;;
+1F083;DOMINO TILE VERTICAL-04-04;So;0;ON;;;;;N;;;;;
+1F084;DOMINO TILE VERTICAL-04-05;So;0;ON;;;;;N;;;;;
+1F085;DOMINO TILE VERTICAL-04-06;So;0;ON;;;;;N;;;;;
+1F086;DOMINO TILE VERTICAL-05-00;So;0;ON;;;;;N;;;;;
+1F087;DOMINO TILE VERTICAL-05-01;So;0;ON;;;;;N;;;;;
+1F088;DOMINO TILE VERTICAL-05-02;So;0;ON;;;;;N;;;;;
+1F089;DOMINO TILE VERTICAL-05-03;So;0;ON;;;;;N;;;;;
+1F08A;DOMINO TILE VERTICAL-05-04;So;0;ON;;;;;N;;;;;
+1F08B;DOMINO TILE VERTICAL-05-05;So;0;ON;;;;;N;;;;;
+1F08C;DOMINO TILE VERTICAL-05-06;So;0;ON;;;;;N;;;;;
+1F08D;DOMINO TILE VERTICAL-06-00;So;0;ON;;;;;N;;;;;
+1F08E;DOMINO TILE VERTICAL-06-01;So;0;ON;;;;;N;;;;;
+1F08F;DOMINO TILE VERTICAL-06-02;So;0;ON;;;;;N;;;;;
+1F090;DOMINO TILE VERTICAL-06-03;So;0;ON;;;;;N;;;;;
+1F091;DOMINO TILE VERTICAL-06-04;So;0;ON;;;;;N;;;;;
+1F092;DOMINO TILE VERTICAL-06-05;So;0;ON;;;;;N;;;;;
+1F093;DOMINO TILE VERTICAL-06-06;So;0;ON;;;;;N;;;;;
+1F0A0;PLAYING CARD BACK;So;0;ON;;;;;N;;;;;
+1F0A1;PLAYING CARD ACE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A2;PLAYING CARD TWO OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A3;PLAYING CARD THREE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A4;PLAYING CARD FOUR OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A5;PLAYING CARD FIVE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A6;PLAYING CARD SIX OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A7;PLAYING CARD SEVEN OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A8;PLAYING CARD EIGHT OF SPADES;So;0;ON;;;;;N;;;;;
+1F0A9;PLAYING CARD NINE OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AA;PLAYING CARD TEN OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AB;PLAYING CARD JACK OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AC;PLAYING CARD KNIGHT OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AD;PLAYING CARD QUEEN OF SPADES;So;0;ON;;;;;N;;;;;
+1F0AE;PLAYING CARD KING OF SPADES;So;0;ON;;;;;N;;;;;
+1F0B1;PLAYING CARD ACE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B2;PLAYING CARD TWO OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B3;PLAYING CARD THREE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B4;PLAYING CARD FOUR OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B5;PLAYING CARD FIVE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B6;PLAYING CARD SIX OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B7;PLAYING CARD SEVEN OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B8;PLAYING CARD EIGHT OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0B9;PLAYING CARD NINE OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BA;PLAYING CARD TEN OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BB;PLAYING CARD JACK OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BC;PLAYING CARD KNIGHT OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BD;PLAYING CARD QUEEN OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BE;PLAYING CARD KING OF HEARTS;So;0;ON;;;;;N;;;;;
+1F0BF;PLAYING CARD RED JOKER;So;0;ON;;;;;N;;;;;
+1F0C1;PLAYING CARD ACE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C2;PLAYING CARD TWO OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C3;PLAYING CARD THREE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C4;PLAYING CARD FOUR OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C5;PLAYING CARD FIVE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C6;PLAYING CARD SIX OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C7;PLAYING CARD SEVEN OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C8;PLAYING CARD EIGHT OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0C9;PLAYING CARD NINE OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CA;PLAYING CARD TEN OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CB;PLAYING CARD JACK OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CC;PLAYING CARD KNIGHT OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CD;PLAYING CARD QUEEN OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CE;PLAYING CARD KING OF DIAMONDS;So;0;ON;;;;;N;;;;;
+1F0CF;PLAYING CARD BLACK JOKER;So;0;ON;;;;;N;;;;;
+1F0D1;PLAYING CARD ACE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D2;PLAYING CARD TWO OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D3;PLAYING CARD THREE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D4;PLAYING CARD FOUR OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D5;PLAYING CARD FIVE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D6;PLAYING CARD SIX OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D7;PLAYING CARD SEVEN OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D8;PLAYING CARD EIGHT OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0D9;PLAYING CARD NINE OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DA;PLAYING CARD TEN OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DB;PLAYING CARD JACK OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DC;PLAYING CARD KNIGHT OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DD;PLAYING CARD QUEEN OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DE;PLAYING CARD KING OF CLUBS;So;0;ON;;;;;N;;;;;
+1F0DF;PLAYING CARD WHITE JOKER;So;0;ON;;;;;N;;;;;
+1F0E0;PLAYING CARD FOOL;So;0;ON;;;;;N;;;;;
+1F0E1;PLAYING CARD TRUMP-1;So;0;ON;;;;;N;;;;;
+1F0E2;PLAYING CARD TRUMP-2;So;0;ON;;;;;N;;;;;
+1F0E3;PLAYING CARD TRUMP-3;So;0;ON;;;;;N;;;;;
+1F0E4;PLAYING CARD TRUMP-4;So;0;ON;;;;;N;;;;;
+1F0E5;PLAYING CARD TRUMP-5;So;0;ON;;;;;N;;;;;
+1F0E6;PLAYING CARD TRUMP-6;So;0;ON;;;;;N;;;;;
+1F0E7;PLAYING CARD TRUMP-7;So;0;ON;;;;;N;;;;;
+1F0E8;PLAYING CARD TRUMP-8;So;0;ON;;;;;N;;;;;
+1F0E9;PLAYING CARD TRUMP-9;So;0;ON;;;;;N;;;;;
+1F0EA;PLAYING CARD TRUMP-10;So;0;ON;;;;;N;;;;;
+1F0EB;PLAYING CARD TRUMP-11;So;0;ON;;;;;N;;;;;
+1F0EC;PLAYING CARD TRUMP-12;So;0;ON;;;;;N;;;;;
+1F0ED;PLAYING CARD TRUMP-13;So;0;ON;;;;;N;;;;;
+1F0EE;PLAYING CARD TRUMP-14;So;0;ON;;;;;N;;;;;
+1F0EF;PLAYING CARD TRUMP-15;So;0;ON;;;;;N;;;;;
+1F0F0;PLAYING CARD TRUMP-16;So;0;ON;;;;;N;;;;;
+1F0F1;PLAYING CARD TRUMP-17;So;0;ON;;;;;N;;;;;
+1F0F2;PLAYING CARD TRUMP-18;So;0;ON;;;;;N;;;;;
+1F0F3;PLAYING CARD TRUMP-19;So;0;ON;;;;;N;;;;;
+1F0F4;PLAYING CARD TRUMP-20;So;0;ON;;;;;N;;;;;
+1F0F5;PLAYING CARD TRUMP-21;So;0;ON;;;;;N;;;;;
+1F100;DIGIT ZERO FULL STOP;No;0;EN;<compat> 0030 002E;;0;0;N;;;;;
+1F101;DIGIT ZERO COMMA;No;0;EN;<compat> 0030 002C;;0;0;N;;;;;
+1F102;DIGIT ONE COMMA;No;0;EN;<compat> 0031 002C;;1;1;N;;;;;
+1F103;DIGIT TWO COMMA;No;0;EN;<compat> 0032 002C;;2;2;N;;;;;
+1F104;DIGIT THREE COMMA;No;0;EN;<compat> 0033 002C;;3;3;N;;;;;
+1F105;DIGIT FOUR COMMA;No;0;EN;<compat> 0034 002C;;4;4;N;;;;;
+1F106;DIGIT FIVE COMMA;No;0;EN;<compat> 0035 002C;;5;5;N;;;;;
+1F107;DIGIT SIX COMMA;No;0;EN;<compat> 0036 002C;;6;6;N;;;;;
+1F108;DIGIT SEVEN COMMA;No;0;EN;<compat> 0037 002C;;7;7;N;;;;;
+1F109;DIGIT EIGHT COMMA;No;0;EN;<compat> 0038 002C;;8;8;N;;;;;
+1F10A;DIGIT NINE COMMA;No;0;EN;<compat> 0039 002C;;9;9;N;;;;;
+1F10B;DINGBAT CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;;
+1F10C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;;
+1F110;PARENTHESIZED LATIN CAPITAL LETTER A;So;0;L;<compat> 0028 0041 0029;;;;N;;;;;
+1F111;PARENTHESIZED LATIN CAPITAL LETTER B;So;0;L;<compat> 0028 0042 0029;;;;N;;;;;
+1F112;PARENTHESIZED LATIN CAPITAL LETTER C;So;0;L;<compat> 0028 0043 0029;;;;N;;;;;
+1F113;PARENTHESIZED LATIN CAPITAL LETTER D;So;0;L;<compat> 0028 0044 0029;;;;N;;;;;
+1F114;PARENTHESIZED LATIN CAPITAL LETTER E;So;0;L;<compat> 0028 0045 0029;;;;N;;;;;
+1F115;PARENTHESIZED LATIN CAPITAL LETTER F;So;0;L;<compat> 0028 0046 0029;;;;N;;;;;
+1F116;PARENTHESIZED LATIN CAPITAL LETTER G;So;0;L;<compat> 0028 0047 0029;;;;N;;;;;
+1F117;PARENTHESIZED LATIN CAPITAL LETTER H;So;0;L;<compat> 0028 0048 0029;;;;N;;;;;
+1F118;PARENTHESIZED LATIN CAPITAL LETTER I;So;0;L;<compat> 0028 0049 0029;;;;N;;;;;
+1F119;PARENTHESIZED LATIN CAPITAL LETTER J;So;0;L;<compat> 0028 004A 0029;;;;N;;;;;
+1F11A;PARENTHESIZED LATIN CAPITAL LETTER K;So;0;L;<compat> 0028 004B 0029;;;;N;;;;;
+1F11B;PARENTHESIZED LATIN CAPITAL LETTER L;So;0;L;<compat> 0028 004C 0029;;;;N;;;;;
+1F11C;PARENTHESIZED LATIN CAPITAL LETTER M;So;0;L;<compat> 0028 004D 0029;;;;N;;;;;
+1F11D;PARENTHESIZED LATIN CAPITAL LETTER N;So;0;L;<compat> 0028 004E 0029;;;;N;;;;;
+1F11E;PARENTHESIZED LATIN CAPITAL LETTER O;So;0;L;<compat> 0028 004F 0029;;;;N;;;;;
+1F11F;PARENTHESIZED LATIN CAPITAL LETTER P;So;0;L;<compat> 0028 0050 0029;;;;N;;;;;
+1F120;PARENTHESIZED LATIN CAPITAL LETTER Q;So;0;L;<compat> 0028 0051 0029;;;;N;;;;;
+1F121;PARENTHESIZED LATIN CAPITAL LETTER R;So;0;L;<compat> 0028 0052 0029;;;;N;;;;;
+1F122;PARENTHESIZED LATIN CAPITAL LETTER S;So;0;L;<compat> 0028 0053 0029;;;;N;;;;;
+1F123;PARENTHESIZED LATIN CAPITAL LETTER T;So;0;L;<compat> 0028 0054 0029;;;;N;;;;;
+1F124;PARENTHESIZED LATIN CAPITAL LETTER U;So;0;L;<compat> 0028 0055 0029;;;;N;;;;;
+1F125;PARENTHESIZED LATIN CAPITAL LETTER V;So;0;L;<compat> 0028 0056 0029;;;;N;;;;;
+1F126;PARENTHESIZED LATIN CAPITAL LETTER W;So;0;L;<compat> 0028 0057 0029;;;;N;;;;;
+1F127;PARENTHESIZED LATIN CAPITAL LETTER X;So;0;L;<compat> 0028 0058 0029;;;;N;;;;;
+1F128;PARENTHESIZED LATIN CAPITAL LETTER Y;So;0;L;<compat> 0028 0059 0029;;;;N;;;;;
+1F129;PARENTHESIZED LATIN CAPITAL LETTER Z;So;0;L;<compat> 0028 005A 0029;;;;N;;;;;
+1F12A;TORTOISE SHELL BRACKETED LATIN CAPITAL LETTER S;So;0;L;<compat> 3014 0053 3015;;;;N;;;;;
+1F12B;CIRCLED ITALIC LATIN CAPITAL LETTER C;So;0;L;<circle> 0043;;;;N;;;;;
+1F12C;CIRCLED ITALIC LATIN CAPITAL LETTER R;So;0;L;<circle> 0052;;;;N;;;;;
+1F12D;CIRCLED CD;So;0;L;<circle> 0043 0044;;;;N;;;;;
+1F12E;CIRCLED WZ;So;0;L;<circle> 0057 005A;;;;N;;;;;
+1F130;SQUARED LATIN CAPITAL LETTER A;So;0;L;<square> 0041;;;;N;;;;;
+1F131;SQUARED LATIN CAPITAL LETTER B;So;0;L;<square> 0042;;;;N;;;;;
+1F132;SQUARED LATIN CAPITAL LETTER C;So;0;L;<square> 0043;;;;N;;;;;
+1F133;SQUARED LATIN CAPITAL LETTER D;So;0;L;<square> 0044;;;;N;;;;;
+1F134;SQUARED LATIN CAPITAL LETTER E;So;0;L;<square> 0045;;;;N;;;;;
+1F135;SQUARED LATIN CAPITAL LETTER F;So;0;L;<square> 0046;;;;N;;;;;
+1F136;SQUARED LATIN CAPITAL LETTER G;So;0;L;<square> 0047;;;;N;;;;;
+1F137;SQUARED LATIN CAPITAL LETTER H;So;0;L;<square> 0048;;;;N;;;;;
+1F138;SQUARED LATIN CAPITAL LETTER I;So;0;L;<square> 0049;;;;N;;;;;
+1F139;SQUARED LATIN CAPITAL LETTER J;So;0;L;<square> 004A;;;;N;;;;;
+1F13A;SQUARED LATIN CAPITAL LETTER K;So;0;L;<square> 004B;;;;N;;;;;
+1F13B;SQUARED LATIN CAPITAL LETTER L;So;0;L;<square> 004C;;;;N;;;;;
+1F13C;SQUARED LATIN CAPITAL LETTER M;So;0;L;<square> 004D;;;;N;;;;;
+1F13D;SQUARED LATIN CAPITAL LETTER N;So;0;L;<square> 004E;;;;N;;;;;
+1F13E;SQUARED LATIN CAPITAL LETTER O;So;0;L;<square> 004F;;;;N;;;;;
+1F13F;SQUARED LATIN CAPITAL LETTER P;So;0;L;<square> 0050;;;;N;;;;;
+1F140;SQUARED LATIN CAPITAL LETTER Q;So;0;L;<square> 0051;;;;N;;;;;
+1F141;SQUARED LATIN CAPITAL LETTER R;So;0;L;<square> 0052;;;;N;;;;;
+1F142;SQUARED LATIN CAPITAL LETTER S;So;0;L;<square> 0053;;;;N;;;;;
+1F143;SQUARED LATIN CAPITAL LETTER T;So;0;L;<square> 0054;;;;N;;;;;
+1F144;SQUARED LATIN CAPITAL LETTER U;So;0;L;<square> 0055;;;;N;;;;;
+1F145;SQUARED LATIN CAPITAL LETTER V;So;0;L;<square> 0056;;;;N;;;;;
+1F146;SQUARED LATIN CAPITAL LETTER W;So;0;L;<square> 0057;;;;N;;;;;
+1F147;SQUARED LATIN CAPITAL LETTER X;So;0;L;<square> 0058;;;;N;;;;;
+1F148;SQUARED LATIN CAPITAL LETTER Y;So;0;L;<square> 0059;;;;N;;;;;
+1F149;SQUARED LATIN CAPITAL LETTER Z;So;0;L;<square> 005A;;;;N;;;;;
+1F14A;SQUARED HV;So;0;L;<square> 0048 0056;;;;N;;;;;
+1F14B;SQUARED MV;So;0;L;<square> 004D 0056;;;;N;;;;;
+1F14C;SQUARED SD;So;0;L;<square> 0053 0044;;;;N;;;;;
+1F14D;SQUARED SS;So;0;L;<square> 0053 0053;;;;N;;;;;
+1F14E;SQUARED PPV;So;0;L;<square> 0050 0050 0056;;;;N;;;;;
+1F14F;SQUARED WC;So;0;L;<square> 0057 0043;;;;N;;;;;
+1F150;NEGATIVE CIRCLED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;;
+1F151;NEGATIVE CIRCLED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;;
+1F152;NEGATIVE CIRCLED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;;
+1F153;NEGATIVE CIRCLED LATIN CAPITAL LETTER D;So;0;L;;;;;N;;;;;
+1F154;NEGATIVE CIRCLED LATIN CAPITAL LETTER E;So;0;L;;;;;N;;;;;
+1F155;NEGATIVE CIRCLED LATIN CAPITAL LETTER F;So;0;L;;;;;N;;;;;
+1F156;NEGATIVE CIRCLED LATIN CAPITAL LETTER G;So;0;L;;;;;N;;;;;
+1F157;NEGATIVE CIRCLED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;;
+1F158;NEGATIVE CIRCLED LATIN CAPITAL LETTER I;So;0;L;;;;;N;;;;;
+1F159;NEGATIVE CIRCLED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;;
+1F15A;NEGATIVE CIRCLED LATIN CAPITAL LETTER K;So;0;L;;;;;N;;;;;
+1F15B;NEGATIVE CIRCLED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;;
+1F15C;NEGATIVE CIRCLED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;;
+1F15D;NEGATIVE CIRCLED LATIN CAPITAL LETTER N;So;0;L;;;;;N;;;;;
+1F15E;NEGATIVE CIRCLED LATIN CAPITAL LETTER O;So;0;L;;;;;N;;;;;
+1F15F;NEGATIVE CIRCLED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;
+1F160;NEGATIVE CIRCLED LATIN CAPITAL LETTER Q;So;0;L;;;;;N;;;;;
+1F161;NEGATIVE CIRCLED LATIN CAPITAL LETTER R;So;0;L;;;;;N;;;;;
+1F162;NEGATIVE CIRCLED LATIN CAPITAL LETTER S;So;0;L;;;;;N;;;;;
+1F163;NEGATIVE CIRCLED LATIN CAPITAL LETTER T;So;0;L;;;;;N;;;;;
+1F164;NEGATIVE CIRCLED LATIN CAPITAL LETTER U;So;0;L;;;;;N;;;;;
+1F165;NEGATIVE CIRCLED LATIN CAPITAL LETTER V;So;0;L;;;;;N;;;;;
+1F166;NEGATIVE CIRCLED LATIN CAPITAL LETTER W;So;0;L;;;;;N;;;;;
+1F167;NEGATIVE CIRCLED LATIN CAPITAL LETTER X;So;0;L;;;;;N;;;;;
+1F168;NEGATIVE CIRCLED LATIN CAPITAL LETTER Y;So;0;L;;;;;N;;;;;
+1F169;NEGATIVE CIRCLED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;;
+1F16A;RAISED MC SIGN;So;0;ON;<super> 004D 0043;;;;N;;;;;
+1F16B;RAISED MD SIGN;So;0;ON;<super> 004D 0044;;;;N;;;;;
+1F170;NEGATIVE SQUARED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;;
+1F171;NEGATIVE SQUARED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;;
+1F172;NEGATIVE SQUARED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;;
+1F173;NEGATIVE SQUARED LATIN CAPITAL LETTER D;So;0;L;;;;;N;;;;;
+1F174;NEGATIVE SQUARED LATIN CAPITAL LETTER E;So;0;L;;;;;N;;;;;
+1F175;NEGATIVE SQUARED LATIN CAPITAL LETTER F;So;0;L;;;;;N;;;;;
+1F176;NEGATIVE SQUARED LATIN CAPITAL LETTER G;So;0;L;;;;;N;;;;;
+1F177;NEGATIVE SQUARED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;;
+1F178;NEGATIVE SQUARED LATIN CAPITAL LETTER I;So;0;L;;;;;N;;;;;
+1F179;NEGATIVE SQUARED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;;
+1F17A;NEGATIVE SQUARED LATIN CAPITAL LETTER K;So;0;L;;;;;N;;;;;
+1F17B;NEGATIVE SQUARED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;;
+1F17C;NEGATIVE SQUARED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;;
+1F17D;NEGATIVE SQUARED LATIN CAPITAL LETTER N;So;0;L;;;;;N;;;;;
+1F17E;NEGATIVE SQUARED LATIN CAPITAL LETTER O;So;0;L;;;;;N;;;;;
+1F17F;NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;
+1F180;NEGATIVE SQUARED LATIN CAPITAL LETTER Q;So;0;L;;;;;N;;;;;
+1F181;NEGATIVE SQUARED LATIN CAPITAL LETTER R;So;0;L;;;;;N;;;;;
+1F182;NEGATIVE SQUARED LATIN CAPITAL LETTER S;So;0;L;;;;;N;;;;;
+1F183;NEGATIVE SQUARED LATIN CAPITAL LETTER T;So;0;L;;;;;N;;;;;
+1F184;NEGATIVE SQUARED LATIN CAPITAL LETTER U;So;0;L;;;;;N;;;;;
+1F185;NEGATIVE SQUARED LATIN CAPITAL LETTER V;So;0;L;;;;;N;;;;;
+1F186;NEGATIVE SQUARED LATIN CAPITAL LETTER W;So;0;L;;;;;N;;;;;
+1F187;NEGATIVE SQUARED LATIN CAPITAL LETTER X;So;0;L;;;;;N;;;;;
+1F188;NEGATIVE SQUARED LATIN CAPITAL LETTER Y;So;0;L;;;;;N;;;;;
+1F189;NEGATIVE SQUARED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;;
+1F18A;CROSSED NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;
+1F18B;NEGATIVE SQUARED IC;So;0;L;;;;;N;;;;;
+1F18C;NEGATIVE SQUARED PA;So;0;L;;;;;N;;;;;
+1F18D;NEGATIVE SQUARED SA;So;0;L;;;;;N;;;;;
+1F18E;NEGATIVE SQUARED AB;So;0;L;;;;;N;;;;;
+1F18F;NEGATIVE SQUARED WC;So;0;L;;;;;N;;;;;
+1F190;SQUARE DJ;So;0;L;<square> 0044 004A;;;;N;;;;;
+1F191;SQUARED CL;So;0;L;;;;;N;;;;;
+1F192;SQUARED COOL;So;0;L;;;;;N;;;;;
+1F193;SQUARED FREE;So;0;L;;;;;N;;;;;
+1F194;SQUARED ID;So;0;L;;;;;N;;;;;
+1F195;SQUARED NEW;So;0;L;;;;;N;;;;;
+1F196;SQUARED NG;So;0;L;;;;;N;;;;;
+1F197;SQUARED OK;So;0;L;;;;;N;;;;;
+1F198;SQUARED SOS;So;0;L;;;;;N;;;;;
+1F199;SQUARED UP WITH EXCLAMATION MARK;So;0;L;;;;;N;;;;;
+1F19A;SQUARED VS;So;0;L;;;;;N;;;;;
+1F19B;SQUARED THREE D;So;0;L;;;;;N;;;;;
+1F19C;SQUARED SECOND SCREEN;So;0;L;;;;;N;;;;;
+1F19D;SQUARED TWO K;So;0;L;;;;;N;;;;;
+1F19E;SQUARED FOUR K;So;0;L;;;;;N;;;;;
+1F19F;SQUARED EIGHT K;So;0;L;;;;;N;;;;;
+1F1A0;SQUARED FIVE POINT ONE;So;0;L;;;;;N;;;;;
+1F1A1;SQUARED SEVEN POINT ONE;So;0;L;;;;;N;;;;;
+1F1A2;SQUARED TWENTY-TWO POINT TWO;So;0;L;;;;;N;;;;;
+1F1A3;SQUARED SIXTY P;So;0;L;;;;;N;;;;;
+1F1A4;SQUARED ONE HUNDRED TWENTY P;So;0;L;;;;;N;;;;;
+1F1A5;SQUARED LATIN SMALL LETTER D;So;0;L;;;;;N;;;;;
+1F1A6;SQUARED HC;So;0;L;;;;;N;;;;;
+1F1A7;SQUARED HDR;So;0;L;;;;;N;;;;;
+1F1A8;SQUARED HI-RES;So;0;L;;;;;N;;;;;
+1F1A9;SQUARED LOSSLESS;So;0;L;;;;;N;;;;;
+1F1AA;SQUARED SHV;So;0;L;;;;;N;;;;;
+1F1AB;SQUARED UHD;So;0;L;;;;;N;;;;;
+1F1AC;SQUARED VOD;So;0;L;;;;;N;;;;;
+1F1E6;REGIONAL INDICATOR SYMBOL LETTER A;So;0;L;;;;;N;;;;;
+1F1E7;REGIONAL INDICATOR SYMBOL LETTER B;So;0;L;;;;;N;;;;;
+1F1E8;REGIONAL INDICATOR SYMBOL LETTER C;So;0;L;;;;;N;;;;;
+1F1E9;REGIONAL INDICATOR SYMBOL LETTER D;So;0;L;;;;;N;;;;;
+1F1EA;REGIONAL INDICATOR SYMBOL LETTER E;So;0;L;;;;;N;;;;;
+1F1EB;REGIONAL INDICATOR SYMBOL LETTER F;So;0;L;;;;;N;;;;;
+1F1EC;REGIONAL INDICATOR SYMBOL LETTER G;So;0;L;;;;;N;;;;;
+1F1ED;REGIONAL INDICATOR SYMBOL LETTER H;So;0;L;;;;;N;;;;;
+1F1EE;REGIONAL INDICATOR SYMBOL LETTER I;So;0;L;;;;;N;;;;;
+1F1EF;REGIONAL INDICATOR SYMBOL LETTER J;So;0;L;;;;;N;;;;;
+1F1F0;REGIONAL INDICATOR SYMBOL LETTER K;So;0;L;;;;;N;;;;;
+1F1F1;REGIONAL INDICATOR SYMBOL LETTER L;So;0;L;;;;;N;;;;;
+1F1F2;REGIONAL INDICATOR SYMBOL LETTER M;So;0;L;;;;;N;;;;;
+1F1F3;REGIONAL INDICATOR SYMBOL LETTER N;So;0;L;;;;;N;;;;;
+1F1F4;REGIONAL INDICATOR SYMBOL LETTER O;So;0;L;;;;;N;;;;;
+1F1F5;REGIONAL INDICATOR SYMBOL LETTER P;So;0;L;;;;;N;;;;;
+1F1F6;REGIONAL INDICATOR SYMBOL LETTER Q;So;0;L;;;;;N;;;;;
+1F1F7;REGIONAL INDICATOR SYMBOL LETTER R;So;0;L;;;;;N;;;;;
+1F1F8;REGIONAL INDICATOR SYMBOL LETTER S;So;0;L;;;;;N;;;;;
+1F1F9;REGIONAL INDICATOR SYMBOL LETTER T;So;0;L;;;;;N;;;;;
+1F1FA;REGIONAL INDICATOR SYMBOL LETTER U;So;0;L;;;;;N;;;;;
+1F1FB;REGIONAL INDICATOR SYMBOL LETTER V;So;0;L;;;;;N;;;;;
+1F1FC;REGIONAL INDICATOR SYMBOL LETTER W;So;0;L;;;;;N;;;;;
+1F1FD;REGIONAL INDICATOR SYMBOL LETTER X;So;0;L;;;;;N;;;;;
+1F1FE;REGIONAL INDICATOR SYMBOL LETTER Y;So;0;L;;;;;N;;;;;
+1F1FF;REGIONAL INDICATOR SYMBOL LETTER Z;So;0;L;;;;;N;;;;;
+1F200;SQUARE HIRAGANA HOKA;So;0;L;<square> 307B 304B;;;;N;;;;;
+1F201;SQUARED KATAKANA KOKO;So;0;L;<square> 30B3 30B3;;;;N;;;;;
+1F202;SQUARED KATAKANA SA;So;0;L;<square> 30B5;;;;N;;;;;
+1F210;SQUARED CJK UNIFIED IDEOGRAPH-624B;So;0;L;<square> 624B;;;;N;;;;;
+1F211;SQUARED CJK UNIFIED IDEOGRAPH-5B57;So;0;L;<square> 5B57;;;;N;;;;;
+1F212;SQUARED CJK UNIFIED IDEOGRAPH-53CC;So;0;L;<square> 53CC;;;;N;;;;;
+1F213;SQUARED KATAKANA DE;So;0;L;<square> 30C7;;;;N;;;;;
+1F214;SQUARED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L;<square> 4E8C;;;;N;;;;;
+1F215;SQUARED CJK UNIFIED IDEOGRAPH-591A;So;0;L;<square> 591A;;;;N;;;;;
+1F216;SQUARED CJK UNIFIED IDEOGRAPH-89E3;So;0;L;<square> 89E3;;;;N;;;;;
+1F217;SQUARED CJK UNIFIED IDEOGRAPH-5929;So;0;L;<square> 5929;;;;N;;;;;
+1F218;SQUARED CJK UNIFIED IDEOGRAPH-4EA4;So;0;L;<square> 4EA4;;;;N;;;;;
+1F219;SQUARED CJK UNIFIED IDEOGRAPH-6620;So;0;L;<square> 6620;;;;N;;;;;
+1F21A;SQUARED CJK UNIFIED IDEOGRAPH-7121;So;0;L;<square> 7121;;;;N;;;;;
+1F21B;SQUARED CJK UNIFIED IDEOGRAPH-6599;So;0;L;<square> 6599;;;;N;;;;;
+1F21C;SQUARED CJK UNIFIED IDEOGRAPH-524D;So;0;L;<square> 524D;;;;N;;;;;
+1F21D;SQUARED CJK UNIFIED IDEOGRAPH-5F8C;So;0;L;<square> 5F8C;;;;N;;;;;
+1F21E;SQUARED CJK UNIFIED IDEOGRAPH-518D;So;0;L;<square> 518D;;;;N;;;;;
+1F21F;SQUARED CJK UNIFIED IDEOGRAPH-65B0;So;0;L;<square> 65B0;;;;N;;;;;
+1F220;SQUARED CJK UNIFIED IDEOGRAPH-521D;So;0;L;<square> 521D;;;;N;;;;;
+1F221;SQUARED CJK UNIFIED IDEOGRAPH-7D42;So;0;L;<square> 7D42;;;;N;;;;;
+1F222;SQUARED CJK UNIFIED IDEOGRAPH-751F;So;0;L;<square> 751F;;;;N;;;;;
+1F223;SQUARED CJK UNIFIED IDEOGRAPH-8CA9;So;0;L;<square> 8CA9;;;;N;;;;;
+1F224;SQUARED CJK UNIFIED IDEOGRAPH-58F0;So;0;L;<square> 58F0;;;;N;;;;;
+1F225;SQUARED CJK UNIFIED IDEOGRAPH-5439;So;0;L;<square> 5439;;;;N;;;;;
+1F226;SQUARED CJK UNIFIED IDEOGRAPH-6F14;So;0;L;<square> 6F14;;;;N;;;;;
+1F227;SQUARED CJK UNIFIED IDEOGRAPH-6295;So;0;L;<square> 6295;;;;N;;;;;
+1F228;SQUARED CJK UNIFIED IDEOGRAPH-6355;So;0;L;<square> 6355;;;;N;;;;;
+1F229;SQUARED CJK UNIFIED IDEOGRAPH-4E00;So;0;L;<square> 4E00;;;;N;;;;;
+1F22A;SQUARED CJK UNIFIED IDEOGRAPH-4E09;So;0;L;<square> 4E09;;;;N;;;;;
+1F22B;SQUARED CJK UNIFIED IDEOGRAPH-904A;So;0;L;<square> 904A;;;;N;;;;;
+1F22C;SQUARED CJK UNIFIED IDEOGRAPH-5DE6;So;0;L;<square> 5DE6;;;;N;;;;;
+1F22D;SQUARED CJK UNIFIED IDEOGRAPH-4E2D;So;0;L;<square> 4E2D;;;;N;;;;;
+1F22E;SQUARED CJK UNIFIED IDEOGRAPH-53F3;So;0;L;<square> 53F3;;;;N;;;;;
+1F22F;SQUARED CJK UNIFIED IDEOGRAPH-6307;So;0;L;<square> 6307;;;;N;;;;;
+1F230;SQUARED CJK UNIFIED IDEOGRAPH-8D70;So;0;L;<square> 8D70;;;;N;;;;;
+1F231;SQUARED CJK UNIFIED IDEOGRAPH-6253;So;0;L;<square> 6253;;;;N;;;;;
+1F232;SQUARED CJK UNIFIED IDEOGRAPH-7981;So;0;L;<square> 7981;;;;N;;;;;
+1F233;SQUARED CJK UNIFIED IDEOGRAPH-7A7A;So;0;L;<square> 7A7A;;;;N;;;;;
+1F234;SQUARED CJK UNIFIED IDEOGRAPH-5408;So;0;L;<square> 5408;;;;N;;;;;
+1F235;SQUARED CJK UNIFIED IDEOGRAPH-6E80;So;0;L;<square> 6E80;;;;N;;;;;
+1F236;SQUARED CJK UNIFIED IDEOGRAPH-6709;So;0;L;<square> 6709;;;;N;;;;;
+1F237;SQUARED CJK UNIFIED IDEOGRAPH-6708;So;0;L;<square> 6708;;;;N;;;;;
+1F238;SQUARED CJK UNIFIED IDEOGRAPH-7533;So;0;L;<square> 7533;;;;N;;;;;
+1F239;SQUARED CJK UNIFIED IDEOGRAPH-5272;So;0;L;<square> 5272;;;;N;;;;;
+1F23A;SQUARED CJK UNIFIED IDEOGRAPH-55B6;So;0;L;<square> 55B6;;;;N;;;;;
+1F23B;SQUARED CJK UNIFIED IDEOGRAPH-914D;So;0;L;<square> 914D;;;;N;;;;;
+1F240;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C;So;0;L;<compat> 3014 672C 3015;;;;N;;;;;
+1F241;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09;So;0;L;<compat> 3014 4E09 3015;;;;N;;;;;
+1F242;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L;<compat> 3014 4E8C 3015;;;;N;;;;;
+1F243;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-5B89;So;0;L;<compat> 3014 5B89 3015;;;;N;;;;;
+1F244;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-70B9;So;0;L;<compat> 3014 70B9 3015;;;;N;;;;;
+1F245;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6253;So;0;L;<compat> 3014 6253 3015;;;;N;;;;;
+1F246;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-76D7;So;0;L;<compat> 3014 76D7 3015;;;;N;;;;;
+1F247;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-52DD;So;0;L;<compat> 3014 52DD 3015;;;;N;;;;;
+1F248;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557;So;0;L;<compat> 3014 6557 3015;;;;N;;;;;
+1F250;CIRCLED IDEOGRAPH ADVANTAGE;So;0;L;<circle> 5F97;;;;N;;;;;
+1F251;CIRCLED IDEOGRAPH ACCEPT;So;0;L;<circle> 53EF;;;;N;;;;;
+1F300;CYCLONE;So;0;ON;;;;;N;;;;;
+1F301;FOGGY;So;0;ON;;;;;N;;;;;
+1F302;CLOSED UMBRELLA;So;0;ON;;;;;N;;;;;
+1F303;NIGHT WITH STARS;So;0;ON;;;;;N;;;;;
+1F304;SUNRISE OVER MOUNTAINS;So;0;ON;;;;;N;;;;;
+1F305;SUNRISE;So;0;ON;;;;;N;;;;;
+1F306;CITYSCAPE AT DUSK;So;0;ON;;;;;N;;;;;
+1F307;SUNSET OVER BUILDINGS;So;0;ON;;;;;N;;;;;
+1F308;RAINBOW;So;0;ON;;;;;N;;;;;
+1F309;BRIDGE AT NIGHT;So;0;ON;;;;;N;;;;;
+1F30A;WATER WAVE;So;0;ON;;;;;N;;;;;
+1F30B;VOLCANO;So;0;ON;;;;;N;;;;;
+1F30C;MILKY WAY;So;0;ON;;;;;N;;;;;
+1F30D;EARTH GLOBE EUROPE-AFRICA;So;0;ON;;;;;N;;;;;
+1F30E;EARTH GLOBE AMERICAS;So;0;ON;;;;;N;;;;;
+1F30F;EARTH GLOBE ASIA-AUSTRALIA;So;0;ON;;;;;N;;;;;
+1F310;GLOBE WITH MERIDIANS;So;0;ON;;;;;N;;;;;
+1F311;NEW MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F312;WAXING CRESCENT MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F313;FIRST QUARTER MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F314;WAXING GIBBOUS MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F315;FULL MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F316;WANING GIBBOUS MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F317;LAST QUARTER MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F318;WANING CRESCENT MOON SYMBOL;So;0;ON;;;;;N;;;;;
+1F319;CRESCENT MOON;So;0;ON;;;;;N;;;;;
+1F31A;NEW MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31B;FIRST QUARTER MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31C;LAST QUARTER MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31D;FULL MOON WITH FACE;So;0;ON;;;;;N;;;;;
+1F31E;SUN WITH FACE;So;0;ON;;;;;N;;;;;
+1F31F;GLOWING STAR;So;0;ON;;;;;N;;;;;
+1F320;SHOOTING STAR;So;0;ON;;;;;N;;;;;
+1F321;THERMOMETER;So;0;ON;;;;;N;;;;;
+1F322;BLACK DROPLET;So;0;ON;;;;;N;;;;;
+1F323;WHITE SUN;So;0;ON;;;;;N;;;;;
+1F324;WHITE SUN WITH SMALL CLOUD;So;0;ON;;;;;N;;;;;
+1F325;WHITE SUN BEHIND CLOUD;So;0;ON;;;;;N;;;;;
+1F326;WHITE SUN BEHIND CLOUD WITH RAIN;So;0;ON;;;;;N;;;;;
+1F327;CLOUD WITH RAIN;So;0;ON;;;;;N;;;;;
+1F328;CLOUD WITH SNOW;So;0;ON;;;;;N;;;;;
+1F329;CLOUD WITH LIGHTNING;So;0;ON;;;;;N;;;;;
+1F32A;CLOUD WITH TORNADO;So;0;ON;;;;;N;;;;;
+1F32B;FOG;So;0;ON;;;;;N;;;;;
+1F32C;WIND BLOWING FACE;So;0;ON;;;;;N;;;;;
+1F32D;HOT DOG;So;0;ON;;;;;N;;;;;
+1F32E;TACO;So;0;ON;;;;;N;;;;;
+1F32F;BURRITO;So;0;ON;;;;;N;;;;;
+1F330;CHESTNUT;So;0;ON;;;;;N;;;;;
+1F331;SEEDLING;So;0;ON;;;;;N;;;;;
+1F332;EVERGREEN TREE;So;0;ON;;;;;N;;;;;
+1F333;DECIDUOUS TREE;So;0;ON;;;;;N;;;;;
+1F334;PALM TREE;So;0;ON;;;;;N;;;;;
+1F335;CACTUS;So;0;ON;;;;;N;;;;;
+1F336;HOT PEPPER;So;0;ON;;;;;N;;;;;
+1F337;TULIP;So;0;ON;;;;;N;;;;;
+1F338;CHERRY BLOSSOM;So;0;ON;;;;;N;;;;;
+1F339;ROSE;So;0;ON;;;;;N;;;;;
+1F33A;HIBISCUS;So;0;ON;;;;;N;;;;;
+1F33B;SUNFLOWER;So;0;ON;;;;;N;;;;;
+1F33C;BLOSSOM;So;0;ON;;;;;N;;;;;
+1F33D;EAR OF MAIZE;So;0;ON;;;;;N;;;;;
+1F33E;EAR OF RICE;So;0;ON;;;;;N;;;;;
+1F33F;HERB;So;0;ON;;;;;N;;;;;
+1F340;FOUR LEAF CLOVER;So;0;ON;;;;;N;;;;;
+1F341;MAPLE LEAF;So;0;ON;;;;;N;;;;;
+1F342;FALLEN LEAF;So;0;ON;;;;;N;;;;;
+1F343;LEAF FLUTTERING IN WIND;So;0;ON;;;;;N;;;;;
+1F344;MUSHROOM;So;0;ON;;;;;N;;;;;
+1F345;TOMATO;So;0;ON;;;;;N;;;;;
+1F346;AUBERGINE;So;0;ON;;;;;N;;;;;
+1F347;GRAPES;So;0;ON;;;;;N;;;;;
+1F348;MELON;So;0;ON;;;;;N;;;;;
+1F349;WATERMELON;So;0;ON;;;;;N;;;;;
+1F34A;TANGERINE;So;0;ON;;;;;N;;;;;
+1F34B;LEMON;So;0;ON;;;;;N;;;;;
+1F34C;BANANA;So;0;ON;;;;;N;;;;;
+1F34D;PINEAPPLE;So;0;ON;;;;;N;;;;;
+1F34E;RED APPLE;So;0;ON;;;;;N;;;;;
+1F34F;GREEN APPLE;So;0;ON;;;;;N;;;;;
+1F350;PEAR;So;0;ON;;;;;N;;;;;
+1F351;PEACH;So;0;ON;;;;;N;;;;;
+1F352;CHERRIES;So;0;ON;;;;;N;;;;;
+1F353;STRAWBERRY;So;0;ON;;;;;N;;;;;
+1F354;HAMBURGER;So;0;ON;;;;;N;;;;;
+1F355;SLICE OF PIZZA;So;0;ON;;;;;N;;;;;
+1F356;MEAT ON BONE;So;0;ON;;;;;N;;;;;
+1F357;POULTRY LEG;So;0;ON;;;;;N;;;;;
+1F358;RICE CRACKER;So;0;ON;;;;;N;;;;;
+1F359;RICE BALL;So;0;ON;;;;;N;;;;;
+1F35A;COOKED RICE;So;0;ON;;;;;N;;;;;
+1F35B;CURRY AND RICE;So;0;ON;;;;;N;;;;;
+1F35C;STEAMING BOWL;So;0;ON;;;;;N;;;;;
+1F35D;SPAGHETTI;So;0;ON;;;;;N;;;;;
+1F35E;BREAD;So;0;ON;;;;;N;;;;;
+1F35F;FRENCH FRIES;So;0;ON;;;;;N;;;;;
+1F360;ROASTED SWEET POTATO;So;0;ON;;;;;N;;;;;
+1F361;DANGO;So;0;ON;;;;;N;;;;;
+1F362;ODEN;So;0;ON;;;;;N;;;;;
+1F363;SUSHI;So;0;ON;;;;;N;;;;;
+1F364;FRIED SHRIMP;So;0;ON;;;;;N;;;;;
+1F365;FISH CAKE WITH SWIRL DESIGN;So;0;ON;;;;;N;;;;;
+1F366;SOFT ICE CREAM;So;0;ON;;;;;N;;;;;
+1F367;SHAVED ICE;So;0;ON;;;;;N;;;;;
+1F368;ICE CREAM;So;0;ON;;;;;N;;;;;
+1F369;DOUGHNUT;So;0;ON;;;;;N;;;;;
+1F36A;COOKIE;So;0;ON;;;;;N;;;;;
+1F36B;CHOCOLATE BAR;So;0;ON;;;;;N;;;;;
+1F36C;CANDY;So;0;ON;;;;;N;;;;;
+1F36D;LOLLIPOP;So;0;ON;;;;;N;;;;;
+1F36E;CUSTARD;So;0;ON;;;;;N;;;;;
+1F36F;HONEY POT;So;0;ON;;;;;N;;;;;
+1F370;SHORTCAKE;So;0;ON;;;;;N;;;;;
+1F371;BENTO BOX;So;0;ON;;;;;N;;;;;
+1F372;POT OF FOOD;So;0;ON;;;;;N;;;;;
+1F373;COOKING;So;0;ON;;;;;N;;;;;
+1F374;FORK AND KNIFE;So;0;ON;;;;;N;;;;;
+1F375;TEACUP WITHOUT HANDLE;So;0;ON;;;;;N;;;;;
+1F376;SAKE BOTTLE AND CUP;So;0;ON;;;;;N;;;;;
+1F377;WINE GLASS;So;0;ON;;;;;N;;;;;
+1F378;COCKTAIL GLASS;So;0;ON;;;;;N;;;;;
+1F379;TROPICAL DRINK;So;0;ON;;;;;N;;;;;
+1F37A;BEER MUG;So;0;ON;;;;;N;;;;;
+1F37B;CLINKING BEER MUGS;So;0;ON;;;;;N;;;;;
+1F37C;BABY BOTTLE;So;0;ON;;;;;N;;;;;
+1F37D;FORK AND KNIFE WITH PLATE;So;0;ON;;;;;N;;;;;
+1F37E;BOTTLE WITH POPPING CORK;So;0;ON;;;;;N;;;;;
+1F37F;POPCORN;So;0;ON;;;;;N;;;;;
+1F380;RIBBON;So;0;ON;;;;;N;;;;;
+1F381;WRAPPED PRESENT;So;0;ON;;;;;N;;;;;
+1F382;BIRTHDAY CAKE;So;0;ON;;;;;N;;;;;
+1F383;JACK-O-LANTERN;So;0;ON;;;;;N;;;;;
+1F384;CHRISTMAS TREE;So;0;ON;;;;;N;;;;;
+1F385;FATHER CHRISTMAS;So;0;ON;;;;;N;;;;;
+1F386;FIREWORKS;So;0;ON;;;;;N;;;;;
+1F387;FIREWORK SPARKLER;So;0;ON;;;;;N;;;;;
+1F388;BALLOON;So;0;ON;;;;;N;;;;;
+1F389;PARTY POPPER;So;0;ON;;;;;N;;;;;
+1F38A;CONFETTI BALL;So;0;ON;;;;;N;;;;;
+1F38B;TANABATA TREE;So;0;ON;;;;;N;;;;;
+1F38C;CROSSED FLAGS;So;0;ON;;;;;N;;;;;
+1F38D;PINE DECORATION;So;0;ON;;;;;N;;;;;
+1F38E;JAPANESE DOLLS;So;0;ON;;;;;N;;;;;
+1F38F;CARP STREAMER;So;0;ON;;;;;N;;;;;
+1F390;WIND CHIME;So;0;ON;;;;;N;;;;;
+1F391;MOON VIEWING CEREMONY;So;0;ON;;;;;N;;;;;
+1F392;SCHOOL SATCHEL;So;0;ON;;;;;N;;;;;
+1F393;GRADUATION CAP;So;0;ON;;;;;N;;;;;
+1F394;HEART WITH TIP ON THE LEFT;So;0;ON;;;;;N;;;;;
+1F395;BOUQUET OF FLOWERS;So;0;ON;;;;;N;;;;;
+1F396;MILITARY MEDAL;So;0;ON;;;;;N;;;;;
+1F397;REMINDER RIBBON;So;0;ON;;;;;N;;;;;
+1F398;MUSICAL KEYBOARD WITH JACKS;So;0;ON;;;;;N;;;;;
+1F399;STUDIO MICROPHONE;So;0;ON;;;;;N;;;;;
+1F39A;LEVEL SLIDER;So;0;ON;;;;;N;;;;;
+1F39B;CONTROL KNOBS;So;0;ON;;;;;N;;;;;
+1F39C;BEAMED ASCENDING MUSICAL NOTES;So;0;ON;;;;;N;;;;;
+1F39D;BEAMED DESCENDING MUSICAL NOTES;So;0;ON;;;;;N;;;;;
+1F39E;FILM FRAMES;So;0;ON;;;;;N;;;;;
+1F39F;ADMISSION TICKETS;So;0;ON;;;;;N;;;;;
+1F3A0;CAROUSEL HORSE;So;0;ON;;;;;N;;;;;
+1F3A1;FERRIS WHEEL;So;0;ON;;;;;N;;;;;
+1F3A2;ROLLER COASTER;So;0;ON;;;;;N;;;;;
+1F3A3;FISHING POLE AND FISH;So;0;ON;;;;;N;;;;;
+1F3A4;MICROPHONE;So;0;ON;;;;;N;;;;;
+1F3A5;MOVIE CAMERA;So;0;ON;;;;;N;;;;;
+1F3A6;CINEMA;So;0;ON;;;;;N;;;;;
+1F3A7;HEADPHONE;So;0;ON;;;;;N;;;;;
+1F3A8;ARTIST PALETTE;So;0;ON;;;;;N;;;;;
+1F3A9;TOP HAT;So;0;ON;;;;;N;;;;;
+1F3AA;CIRCUS TENT;So;0;ON;;;;;N;;;;;
+1F3AB;TICKET;So;0;ON;;;;;N;;;;;
+1F3AC;CLAPPER BOARD;So;0;ON;;;;;N;;;;;
+1F3AD;PERFORMING ARTS;So;0;ON;;;;;N;;;;;
+1F3AE;VIDEO GAME;So;0;ON;;;;;N;;;;;
+1F3AF;DIRECT HIT;So;0;ON;;;;;N;;;;;
+1F3B0;SLOT MACHINE;So;0;ON;;;;;N;;;;;
+1F3B1;BILLIARDS;So;0;ON;;;;;N;;;;;
+1F3B2;GAME DIE;So;0;ON;;;;;N;;;;;
+1F3B3;BOWLING;So;0;ON;;;;;N;;;;;
+1F3B4;FLOWER PLAYING CARDS;So;0;ON;;;;;N;;;;;
+1F3B5;MUSICAL NOTE;So;0;ON;;;;;N;;;;;
+1F3B6;MULTIPLE MUSICAL NOTES;So;0;ON;;;;;N;;;;;
+1F3B7;SAXOPHONE;So;0;ON;;;;;N;;;;;
+1F3B8;GUITAR;So;0;ON;;;;;N;;;;;
+1F3B9;MUSICAL KEYBOARD;So;0;ON;;;;;N;;;;;
+1F3BA;TRUMPET;So;0;ON;;;;;N;;;;;
+1F3BB;VIOLIN;So;0;ON;;;;;N;;;;;
+1F3BC;MUSICAL SCORE;So;0;ON;;;;;N;;;;;
+1F3BD;RUNNING SHIRT WITH SASH;So;0;ON;;;;;N;;;;;
+1F3BE;TENNIS RACQUET AND BALL;So;0;ON;;;;;N;;;;;
+1F3BF;SKI AND SKI BOOT;So;0;ON;;;;;N;;;;;
+1F3C0;BASKETBALL AND HOOP;So;0;ON;;;;;N;;;;;
+1F3C1;CHEQUERED FLAG;So;0;ON;;;;;N;;;;;
+1F3C2;SNOWBOARDER;So;0;ON;;;;;N;;;;;
+1F3C3;RUNNER;So;0;ON;;;;;N;;;;;
+1F3C4;SURFER;So;0;ON;;;;;N;;;;;
+1F3C5;SPORTS MEDAL;So;0;ON;;;;;N;;;;;
+1F3C6;TROPHY;So;0;ON;;;;;N;;;;;
+1F3C7;HORSE RACING;So;0;ON;;;;;N;;;;;
+1F3C8;AMERICAN FOOTBALL;So;0;ON;;;;;N;;;;;
+1F3C9;RUGBY FOOTBALL;So;0;ON;;;;;N;;;;;
+1F3CA;SWIMMER;So;0;ON;;;;;N;;;;;
+1F3CB;WEIGHT LIFTER;So;0;ON;;;;;N;;;;;
+1F3CC;GOLFER;So;0;ON;;;;;N;;;;;
+1F3CD;RACING MOTORCYCLE;So;0;ON;;;;;N;;;;;
+1F3CE;RACING CAR;So;0;ON;;;;;N;;;;;
+1F3CF;CRICKET BAT AND BALL;So;0;ON;;;;;N;;;;;
+1F3D0;VOLLEYBALL;So;0;ON;;;;;N;;;;;
+1F3D1;FIELD HOCKEY STICK AND BALL;So;0;ON;;;;;N;;;;;
+1F3D2;ICE HOCKEY STICK AND PUCK;So;0;ON;;;;;N;;;;;
+1F3D3;TABLE TENNIS PADDLE AND BALL;So;0;ON;;;;;N;;;;;
+1F3D4;SNOW CAPPED MOUNTAIN;So;0;ON;;;;;N;;;;;
+1F3D5;CAMPING;So;0;ON;;;;;N;;;;;
+1F3D6;BEACH WITH UMBRELLA;So;0;ON;;;;;N;;;;;
+1F3D7;BUILDING CONSTRUCTION;So;0;ON;;;;;N;;;;;
+1F3D8;HOUSE BUILDINGS;So;0;ON;;;;;N;;;;;
+1F3D9;CITYSCAPE;So;0;ON;;;;;N;;;;;
+1F3DA;DERELICT HOUSE BUILDING;So;0;ON;;;;;N;;;;;
+1F3DB;CLASSICAL BUILDING;So;0;ON;;;;;N;;;;;
+1F3DC;DESERT;So;0;ON;;;;;N;;;;;
+1F3DD;DESERT ISLAND;So;0;ON;;;;;N;;;;;
+1F3DE;NATIONAL PARK;So;0;ON;;;;;N;;;;;
+1F3DF;STADIUM;So;0;ON;;;;;N;;;;;
+1F3E0;HOUSE BUILDING;So;0;ON;;;;;N;;;;;
+1F3E1;HOUSE WITH GARDEN;So;0;ON;;;;;N;;;;;
+1F3E2;OFFICE BUILDING;So;0;ON;;;;;N;;;;;
+1F3E3;JAPANESE POST OFFICE;So;0;ON;;;;;N;;;;;
+1F3E4;EUROPEAN POST OFFICE;So;0;ON;;;;;N;;;;;
+1F3E5;HOSPITAL;So;0;ON;;;;;N;;;;;
+1F3E6;BANK;So;0;ON;;;;;N;;;;;
+1F3E7;AUTOMATED TELLER MACHINE;So;0;ON;;;;;N;;;;;
+1F3E8;HOTEL;So;0;ON;;;;;N;;;;;
+1F3E9;LOVE HOTEL;So;0;ON;;;;;N;;;;;
+1F3EA;CONVENIENCE STORE;So;0;ON;;;;;N;;;;;
+1F3EB;SCHOOL;So;0;ON;;;;;N;;;;;
+1F3EC;DEPARTMENT STORE;So;0;ON;;;;;N;;;;;
+1F3ED;FACTORY;So;0;ON;;;;;N;;;;;
+1F3EE;IZAKAYA LANTERN;So;0;ON;;;;;N;;;;;
+1F3EF;JAPANESE CASTLE;So;0;ON;;;;;N;;;;;
+1F3F0;EUROPEAN CASTLE;So;0;ON;;;;;N;;;;;
+1F3F1;WHITE PENNANT;So;0;ON;;;;;N;;;;;
+1F3F2;BLACK PENNANT;So;0;ON;;;;;N;;;;;
+1F3F3;WAVING WHITE FLAG;So;0;ON;;;;;N;;;;;
+1F3F4;WAVING BLACK FLAG;So;0;ON;;;;;N;;;;;
+1F3F5;ROSETTE;So;0;ON;;;;;N;;;;;
+1F3F6;BLACK ROSETTE;So;0;ON;;;;;N;;;;;
+1F3F7;LABEL;So;0;ON;;;;;N;;;;;
+1F3F8;BADMINTON RACQUET AND SHUTTLECOCK;So;0;ON;;;;;N;;;;;
+1F3F9;BOW AND ARROW;So;0;ON;;;;;N;;;;;
+1F3FA;AMPHORA;So;0;ON;;;;;N;;;;;
+1F3FB;EMOJI MODIFIER FITZPATRICK TYPE-1-2;Sk;0;ON;;;;;N;;;;;
+1F3FC;EMOJI MODIFIER FITZPATRICK TYPE-3;Sk;0;ON;;;;;N;;;;;
+1F3FD;EMOJI MODIFIER FITZPATRICK TYPE-4;Sk;0;ON;;;;;N;;;;;
+1F3FE;EMOJI MODIFIER FITZPATRICK TYPE-5;Sk;0;ON;;;;;N;;;;;
+1F3FF;EMOJI MODIFIER FITZPATRICK TYPE-6;Sk;0;ON;;;;;N;;;;;
+1F400;RAT;So;0;ON;;;;;N;;;;;
+1F401;MOUSE;So;0;ON;;;;;N;;;;;
+1F402;OX;So;0;ON;;;;;N;;;;;
+1F403;WATER BUFFALO;So;0;ON;;;;;N;;;;;
+1F404;COW;So;0;ON;;;;;N;;;;;
+1F405;TIGER;So;0;ON;;;;;N;;;;;
+1F406;LEOPARD;So;0;ON;;;;;N;;;;;
+1F407;RABBIT;So;0;ON;;;;;N;;;;;
+1F408;CAT;So;0;ON;;;;;N;;;;;
+1F409;DRAGON;So;0;ON;;;;;N;;;;;
+1F40A;CROCODILE;So;0;ON;;;;;N;;;;;
+1F40B;WHALE;So;0;ON;;;;;N;;;;;
+1F40C;SNAIL;So;0;ON;;;;;N;;;;;
+1F40D;SNAKE;So;0;ON;;;;;N;;;;;
+1F40E;HORSE;So;0;ON;;;;;N;;;;;
+1F40F;RAM;So;0;ON;;;;;N;;;;;
+1F410;GOAT;So;0;ON;;;;;N;;;;;
+1F411;SHEEP;So;0;ON;;;;;N;;;;;
+1F412;MONKEY;So;0;ON;;;;;N;;;;;
+1F413;ROOSTER;So;0;ON;;;;;N;;;;;
+1F414;CHICKEN;So;0;ON;;;;;N;;;;;
+1F415;DOG;So;0;ON;;;;;N;;;;;
+1F416;PIG;So;0;ON;;;;;N;;;;;
+1F417;BOAR;So;0;ON;;;;;N;;;;;
+1F418;ELEPHANT;So;0;ON;;;;;N;;;;;
+1F419;OCTOPUS;So;0;ON;;;;;N;;;;;
+1F41A;SPIRAL SHELL;So;0;ON;;;;;N;;;;;
+1F41B;BUG;So;0;ON;;;;;N;;;;;
+1F41C;ANT;So;0;ON;;;;;N;;;;;
+1F41D;HONEYBEE;So;0;ON;;;;;N;;;;;
+1F41E;LADY BEETLE;So;0;ON;;;;;N;;;;;
+1F41F;FISH;So;0;ON;;;;;N;;;;;
+1F420;TROPICAL FISH;So;0;ON;;;;;N;;;;;
+1F421;BLOWFISH;So;0;ON;;;;;N;;;;;
+1F422;TURTLE;So;0;ON;;;;;N;;;;;
+1F423;HATCHING CHICK;So;0;ON;;;;;N;;;;;
+1F424;BABY CHICK;So;0;ON;;;;;N;;;;;
+1F425;FRONT-FACING BABY CHICK;So;0;ON;;;;;N;;;;;
+1F426;BIRD;So;0;ON;;;;;N;;;;;
+1F427;PENGUIN;So;0;ON;;;;;N;;;;;
+1F428;KOALA;So;0;ON;;;;;N;;;;;
+1F429;POODLE;So;0;ON;;;;;N;;;;;
+1F42A;DROMEDARY CAMEL;So;0;ON;;;;;N;;;;;
+1F42B;BACTRIAN CAMEL;So;0;ON;;;;;N;;;;;
+1F42C;DOLPHIN;So;0;ON;;;;;N;;;;;
+1F42D;MOUSE FACE;So;0;ON;;;;;N;;;;;
+1F42E;COW FACE;So;0;ON;;;;;N;;;;;
+1F42F;TIGER FACE;So;0;ON;;;;;N;;;;;
+1F430;RABBIT FACE;So;0;ON;;;;;N;;;;;
+1F431;CAT FACE;So;0;ON;;;;;N;;;;;
+1F432;DRAGON FACE;So;0;ON;;;;;N;;;;;
+1F433;SPOUTING WHALE;So;0;ON;;;;;N;;;;;
+1F434;HORSE FACE;So;0;ON;;;;;N;;;;;
+1F435;MONKEY FACE;So;0;ON;;;;;N;;;;;
+1F436;DOG FACE;So;0;ON;;;;;N;;;;;
+1F437;PIG FACE;So;0;ON;;;;;N;;;;;
+1F438;FROG FACE;So;0;ON;;;;;N;;;;;
+1F439;HAMSTER FACE;So;0;ON;;;;;N;;;;;
+1F43A;WOLF FACE;So;0;ON;;;;;N;;;;;
+1F43B;BEAR FACE;So;0;ON;;;;;N;;;;;
+1F43C;PANDA FACE;So;0;ON;;;;;N;;;;;
+1F43D;PIG NOSE;So;0;ON;;;;;N;;;;;
+1F43E;PAW PRINTS;So;0;ON;;;;;N;;;;;
+1F43F;CHIPMUNK;So;0;ON;;;;;N;;;;;
+1F440;EYES;So;0;ON;;;;;N;;;;;
+1F441;EYE;So;0;ON;;;;;N;;;;;
+1F442;EAR;So;0;ON;;;;;N;;;;;
+1F443;NOSE;So;0;ON;;;;;N;;;;;
+1F444;MOUTH;So;0;ON;;;;;N;;;;;
+1F445;TONGUE;So;0;ON;;;;;N;;;;;
+1F446;WHITE UP POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F447;WHITE DOWN POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F448;WHITE LEFT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F449;WHITE RIGHT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F44A;FISTED HAND SIGN;So;0;ON;;;;;N;;;;;
+1F44B;WAVING HAND SIGN;So;0;ON;;;;;N;;;;;
+1F44C;OK HAND SIGN;So;0;ON;;;;;N;;;;;
+1F44D;THUMBS UP SIGN;So;0;ON;;;;;N;;;;;
+1F44E;THUMBS DOWN SIGN;So;0;ON;;;;;N;;;;;
+1F44F;CLAPPING HANDS SIGN;So;0;ON;;;;;N;;;;;
+1F450;OPEN HANDS SIGN;So;0;ON;;;;;N;;;;;
+1F451;CROWN;So;0;ON;;;;;N;;;;;
+1F452;WOMANS HAT;So;0;ON;;;;;N;;;;;
+1F453;EYEGLASSES;So;0;ON;;;;;N;;;;;
+1F454;NECKTIE;So;0;ON;;;;;N;;;;;
+1F455;T-SHIRT;So;0;ON;;;;;N;;;;;
+1F456;JEANS;So;0;ON;;;;;N;;;;;
+1F457;DRESS;So;0;ON;;;;;N;;;;;
+1F458;KIMONO;So;0;ON;;;;;N;;;;;
+1F459;BIKINI;So;0;ON;;;;;N;;;;;
+1F45A;WOMANS CLOTHES;So;0;ON;;;;;N;;;;;
+1F45B;PURSE;So;0;ON;;;;;N;;;;;
+1F45C;HANDBAG;So;0;ON;;;;;N;;;;;
+1F45D;POUCH;So;0;ON;;;;;N;;;;;
+1F45E;MANS SHOE;So;0;ON;;;;;N;;;;;
+1F45F;ATHLETIC SHOE;So;0;ON;;;;;N;;;;;
+1F460;HIGH-HEELED SHOE;So;0;ON;;;;;N;;;;;
+1F461;WOMANS SANDAL;So;0;ON;;;;;N;;;;;
+1F462;WOMANS BOOTS;So;0;ON;;;;;N;;;;;
+1F463;FOOTPRINTS;So;0;ON;;;;;N;;;;;
+1F464;BUST IN SILHOUETTE;So;0;ON;;;;;N;;;;;
+1F465;BUSTS IN SILHOUETTE;So;0;ON;;;;;N;;;;;
+1F466;BOY;So;0;ON;;;;;N;;;;;
+1F467;GIRL;So;0;ON;;;;;N;;;;;
+1F468;MAN;So;0;ON;;;;;N;;;;;
+1F469;WOMAN;So;0;ON;;;;;N;;;;;
+1F46A;FAMILY;So;0;ON;;;;;N;;;;;
+1F46B;MAN AND WOMAN HOLDING HANDS;So;0;ON;;;;;N;;;;;
+1F46C;TWO MEN HOLDING HANDS;So;0;ON;;;;;N;;;;;
+1F46D;TWO WOMEN HOLDING HANDS;So;0;ON;;;;;N;;;;;
+1F46E;POLICE OFFICER;So;0;ON;;;;;N;;;;;
+1F46F;WOMAN WITH BUNNY EARS;So;0;ON;;;;;N;;;;;
+1F470;BRIDE WITH VEIL;So;0;ON;;;;;N;;;;;
+1F471;PERSON WITH BLOND HAIR;So;0;ON;;;;;N;;;;;
+1F472;MAN WITH GUA PI MAO;So;0;ON;;;;;N;;;;;
+1F473;MAN WITH TURBAN;So;0;ON;;;;;N;;;;;
+1F474;OLDER MAN;So;0;ON;;;;;N;;;;;
+1F475;OLDER WOMAN;So;0;ON;;;;;N;;;;;
+1F476;BABY;So;0;ON;;;;;N;;;;;
+1F477;CONSTRUCTION WORKER;So;0;ON;;;;;N;;;;;
+1F478;PRINCESS;So;0;ON;;;;;N;;;;;
+1F479;JAPANESE OGRE;So;0;ON;;;;;N;;;;;
+1F47A;JAPANESE GOBLIN;So;0;ON;;;;;N;;;;;
+1F47B;GHOST;So;0;ON;;;;;N;;;;;
+1F47C;BABY ANGEL;So;0;ON;;;;;N;;;;;
+1F47D;EXTRATERRESTRIAL ALIEN;So;0;ON;;;;;N;;;;;
+1F47E;ALIEN MONSTER;So;0;ON;;;;;N;;;;;
+1F47F;IMP;So;0;ON;;;;;N;;;;;
+1F480;SKULL;So;0;ON;;;;;N;;;;;
+1F481;INFORMATION DESK PERSON;So;0;ON;;;;;N;;;;;
+1F482;GUARDSMAN;So;0;ON;;;;;N;;;;;
+1F483;DANCER;So;0;ON;;;;;N;;;;;
+1F484;LIPSTICK;So;0;ON;;;;;N;;;;;
+1F485;NAIL POLISH;So;0;ON;;;;;N;;;;;
+1F486;FACE MASSAGE;So;0;ON;;;;;N;;;;;
+1F487;HAIRCUT;So;0;ON;;;;;N;;;;;
+1F488;BARBER POLE;So;0;ON;;;;;N;;;;;
+1F489;SYRINGE;So;0;ON;;;;;N;;;;;
+1F48A;PILL;So;0;ON;;;;;N;;;;;
+1F48B;KISS MARK;So;0;ON;;;;;N;;;;;
+1F48C;LOVE LETTER;So;0;ON;;;;;N;;;;;
+1F48D;RING;So;0;ON;;;;;N;;;;;
+1F48E;GEM STONE;So;0;ON;;;;;N;;;;;
+1F48F;KISS;So;0;ON;;;;;N;;;;;
+1F490;BOUQUET;So;0;ON;;;;;N;;;;;
+1F491;COUPLE WITH HEART;So;0;ON;;;;;N;;;;;
+1F492;WEDDING;So;0;ON;;;;;N;;;;;
+1F493;BEATING HEART;So;0;ON;;;;;N;;;;;
+1F494;BROKEN HEART;So;0;ON;;;;;N;;;;;
+1F495;TWO HEARTS;So;0;ON;;;;;N;;;;;
+1F496;SPARKLING HEART;So;0;ON;;;;;N;;;;;
+1F497;GROWING HEART;So;0;ON;;;;;N;;;;;
+1F498;HEART WITH ARROW;So;0;ON;;;;;N;;;;;
+1F499;BLUE HEART;So;0;ON;;;;;N;;;;;
+1F49A;GREEN HEART;So;0;ON;;;;;N;;;;;
+1F49B;YELLOW HEART;So;0;ON;;;;;N;;;;;
+1F49C;PURPLE HEART;So;0;ON;;;;;N;;;;;
+1F49D;HEART WITH RIBBON;So;0;ON;;;;;N;;;;;
+1F49E;REVOLVING HEARTS;So;0;ON;;;;;N;;;;;
+1F49F;HEART DECORATION;So;0;ON;;;;;N;;;;;
+1F4A0;DIAMOND SHAPE WITH A DOT INSIDE;So;0;ON;;;;;N;;;;;
+1F4A1;ELECTRIC LIGHT BULB;So;0;ON;;;;;N;;;;;
+1F4A2;ANGER SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A3;BOMB;So;0;ON;;;;;N;;;;;
+1F4A4;SLEEPING SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A5;COLLISION SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A6;SPLASHING SWEAT SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A7;DROPLET;So;0;ON;;;;;N;;;;;
+1F4A8;DASH SYMBOL;So;0;ON;;;;;N;;;;;
+1F4A9;PILE OF POO;So;0;ON;;;;;N;;;;;
+1F4AA;FLEXED BICEPS;So;0;ON;;;;;N;;;;;
+1F4AB;DIZZY SYMBOL;So;0;ON;;;;;N;;;;;
+1F4AC;SPEECH BALLOON;So;0;ON;;;;;N;;;;;
+1F4AD;THOUGHT BALLOON;So;0;ON;;;;;N;;;;;
+1F4AE;WHITE FLOWER;So;0;ON;;;;;N;;;;;
+1F4AF;HUNDRED POINTS SYMBOL;So;0;ON;;;;;N;;;;;
+1F4B0;MONEY BAG;So;0;ON;;;;;N;;;;;
+1F4B1;CURRENCY EXCHANGE;So;0;ON;;;;;N;;;;;
+1F4B2;HEAVY DOLLAR SIGN;So;0;ON;;;;;N;;;;;
+1F4B3;CREDIT CARD;So;0;ON;;;;;N;;;;;
+1F4B4;BANKNOTE WITH YEN SIGN;So;0;ON;;;;;N;;;;;
+1F4B5;BANKNOTE WITH DOLLAR SIGN;So;0;ON;;;;;N;;;;;
+1F4B6;BANKNOTE WITH EURO SIGN;So;0;ON;;;;;N;;;;;
+1F4B7;BANKNOTE WITH POUND SIGN;So;0;ON;;;;;N;;;;;
+1F4B8;MONEY WITH WINGS;So;0;ON;;;;;N;;;;;
+1F4B9;CHART WITH UPWARDS TREND AND YEN SIGN;So;0;ON;;;;;N;;;;;
+1F4BA;SEAT;So;0;ON;;;;;N;;;;;
+1F4BB;PERSONAL COMPUTER;So;0;ON;;;;;N;;;;;
+1F4BC;BRIEFCASE;So;0;ON;;;;;N;;;;;
+1F4BD;MINIDISC;So;0;ON;;;;;N;;;;;
+1F4BE;FLOPPY DISK;So;0;ON;;;;;N;;;;;
+1F4BF;OPTICAL DISC;So;0;ON;;;;;N;;;;;
+1F4C0;DVD;So;0;ON;;;;;N;;;;;
+1F4C1;FILE FOLDER;So;0;ON;;;;;N;;;;;
+1F4C2;OPEN FILE FOLDER;So;0;ON;;;;;N;;;;;
+1F4C3;PAGE WITH CURL;So;0;ON;;;;;N;;;;;
+1F4C4;PAGE FACING UP;So;0;ON;;;;;N;;;;;
+1F4C5;CALENDAR;So;0;ON;;;;;N;;;;;
+1F4C6;TEAR-OFF CALENDAR;So;0;ON;;;;;N;;;;;
+1F4C7;CARD INDEX;So;0;ON;;;;;N;;;;;
+1F4C8;CHART WITH UPWARDS TREND;So;0;ON;;;;;N;;;;;
+1F4C9;CHART WITH DOWNWARDS TREND;So;0;ON;;;;;N;;;;;
+1F4CA;BAR CHART;So;0;ON;;;;;N;;;;;
+1F4CB;CLIPBOARD;So;0;ON;;;;;N;;;;;
+1F4CC;PUSHPIN;So;0;ON;;;;;N;;;;;
+1F4CD;ROUND PUSHPIN;So;0;ON;;;;;N;;;;;
+1F4CE;PAPERCLIP;So;0;ON;;;;;N;;;;;
+1F4CF;STRAIGHT RULER;So;0;ON;;;;;N;;;;;
+1F4D0;TRIANGULAR RULER;So;0;ON;;;;;N;;;;;
+1F4D1;BOOKMARK TABS;So;0;ON;;;;;N;;;;;
+1F4D2;LEDGER;So;0;ON;;;;;N;;;;;
+1F4D3;NOTEBOOK;So;0;ON;;;;;N;;;;;
+1F4D4;NOTEBOOK WITH DECORATIVE COVER;So;0;ON;;;;;N;;;;;
+1F4D5;CLOSED BOOK;So;0;ON;;;;;N;;;;;
+1F4D6;OPEN BOOK;So;0;ON;;;;;N;;;;;
+1F4D7;GREEN BOOK;So;0;ON;;;;;N;;;;;
+1F4D8;BLUE BOOK;So;0;ON;;;;;N;;;;;
+1F4D9;ORANGE BOOK;So;0;ON;;;;;N;;;;;
+1F4DA;BOOKS;So;0;ON;;;;;N;;;;;
+1F4DB;NAME BADGE;So;0;ON;;;;;N;;;;;
+1F4DC;SCROLL;So;0;ON;;;;;N;;;;;
+1F4DD;MEMO;So;0;ON;;;;;N;;;;;
+1F4DE;TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;;
+1F4DF;PAGER;So;0;ON;;;;;N;;;;;
+1F4E0;FAX MACHINE;So;0;ON;;;;;N;;;;;
+1F4E1;SATELLITE ANTENNA;So;0;ON;;;;;N;;;;;
+1F4E2;PUBLIC ADDRESS LOUDSPEAKER;So;0;ON;;;;;N;;;;;
+1F4E3;CHEERING MEGAPHONE;So;0;ON;;;;;N;;;;;
+1F4E4;OUTBOX TRAY;So;0;ON;;;;;N;;;;;
+1F4E5;INBOX TRAY;So;0;ON;;;;;N;;;;;
+1F4E6;PACKAGE;So;0;ON;;;;;N;;;;;
+1F4E7;E-MAIL SYMBOL;So;0;ON;;;;;N;;;;;
+1F4E8;INCOMING ENVELOPE;So;0;ON;;;;;N;;;;;
+1F4E9;ENVELOPE WITH DOWNWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F4EA;CLOSED MAILBOX WITH LOWERED FLAG;So;0;ON;;;;;N;;;;;
+1F4EB;CLOSED MAILBOX WITH RAISED FLAG;So;0;ON;;;;;N;;;;;
+1F4EC;OPEN MAILBOX WITH RAISED FLAG;So;0;ON;;;;;N;;;;;
+1F4ED;OPEN MAILBOX WITH LOWERED FLAG;So;0;ON;;;;;N;;;;;
+1F4EE;POSTBOX;So;0;ON;;;;;N;;;;;
+1F4EF;POSTAL HORN;So;0;ON;;;;;N;;;;;
+1F4F0;NEWSPAPER;So;0;ON;;;;;N;;;;;
+1F4F1;MOBILE PHONE;So;0;ON;;;;;N;;;;;
+1F4F2;MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT;So;0;ON;;;;;N;;;;;
+1F4F3;VIBRATION MODE;So;0;ON;;;;;N;;;;;
+1F4F4;MOBILE PHONE OFF;So;0;ON;;;;;N;;;;;
+1F4F5;NO MOBILE PHONES;So;0;ON;;;;;N;;;;;
+1F4F6;ANTENNA WITH BARS;So;0;ON;;;;;N;;;;;
+1F4F7;CAMERA;So;0;ON;;;;;N;;;;;
+1F4F8;CAMERA WITH FLASH;So;0;ON;;;;;N;;;;;
+1F4F9;VIDEO CAMERA;So;0;ON;;;;;N;;;;;
+1F4FA;TELEVISION;So;0;ON;;;;;N;;;;;
+1F4FB;RADIO;So;0;ON;;;;;N;;;;;
+1F4FC;VIDEOCASSETTE;So;0;ON;;;;;N;;;;;
+1F4FD;FILM PROJECTOR;So;0;ON;;;;;N;;;;;
+1F4FE;PORTABLE STEREO;So;0;ON;;;;;N;;;;;
+1F4FF;PRAYER BEADS;So;0;ON;;;;;N;;;;;
+1F500;TWISTED RIGHTWARDS ARROWS;So;0;ON;;;;;N;;;;;
+1F501;CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;
+1F502;CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY;So;0;ON;;;;;N;;;;;
+1F503;CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;
+1F504;ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;
+1F505;LOW BRIGHTNESS SYMBOL;So;0;ON;;;;;N;;;;;
+1F506;HIGH BRIGHTNESS SYMBOL;So;0;ON;;;;;N;;;;;
+1F507;SPEAKER WITH CANCELLATION STROKE;So;0;ON;;;;;N;;;;;
+1F508;SPEAKER;So;0;ON;;;;;N;;;;;
+1F509;SPEAKER WITH ONE SOUND WAVE;So;0;ON;;;;;N;;;;;
+1F50A;SPEAKER WITH THREE SOUND WAVES;So;0;ON;;;;;N;;;;;
+1F50B;BATTERY;So;0;ON;;;;;N;;;;;
+1F50C;ELECTRIC PLUG;So;0;ON;;;;;N;;;;;
+1F50D;LEFT-POINTING MAGNIFYING GLASS;So;0;ON;;;;;N;;;;;
+1F50E;RIGHT-POINTING MAGNIFYING GLASS;So;0;ON;;;;;N;;;;;
+1F50F;LOCK WITH INK PEN;So;0;ON;;;;;N;;;;;
+1F510;CLOSED LOCK WITH KEY;So;0;ON;;;;;N;;;;;
+1F511;KEY;So;0;ON;;;;;N;;;;;
+1F512;LOCK;So;0;ON;;;;;N;;;;;
+1F513;OPEN LOCK;So;0;ON;;;;;N;;;;;
+1F514;BELL;So;0;ON;;;;;N;;;;;
+1F515;BELL WITH CANCELLATION STROKE;So;0;ON;;;;;N;;;;;
+1F516;BOOKMARK;So;0;ON;;;;;N;;;;;
+1F517;LINK SYMBOL;So;0;ON;;;;;N;;;;;
+1F518;RADIO BUTTON;So;0;ON;;;;;N;;;;;
+1F519;BACK WITH LEFTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51A;END WITH LEFTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51B;ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51C;SOON WITH RIGHTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51D;TOP WITH UPWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;
+1F51E;NO ONE UNDER EIGHTEEN SYMBOL;So;0;ON;;;;;N;;;;;
+1F51F;KEYCAP TEN;So;0;ON;;;;;N;;;;;
+1F520;INPUT SYMBOL FOR LATIN CAPITAL LETTERS;So;0;ON;;;;;N;;;;;
+1F521;INPUT SYMBOL FOR LATIN SMALL LETTERS;So;0;ON;;;;;N;;;;;
+1F522;INPUT SYMBOL FOR NUMBERS;So;0;ON;;;;;N;;;;;
+1F523;INPUT SYMBOL FOR SYMBOLS;So;0;ON;;;;;N;;;;;
+1F524;INPUT SYMBOL FOR LATIN LETTERS;So;0;ON;;;;;N;;;;;
+1F525;FIRE;So;0;ON;;;;;N;;;;;
+1F526;ELECTRIC TORCH;So;0;ON;;;;;N;;;;;
+1F527;WRENCH;So;0;ON;;;;;N;;;;;
+1F528;HAMMER;So;0;ON;;;;;N;;;;;
+1F529;NUT AND BOLT;So;0;ON;;;;;N;;;;;
+1F52A;HOCHO;So;0;ON;;;;;N;;;;;
+1F52B;PISTOL;So;0;ON;;;;;N;;;;;
+1F52C;MICROSCOPE;So;0;ON;;;;;N;;;;;
+1F52D;TELESCOPE;So;0;ON;;;;;N;;;;;
+1F52E;CRYSTAL BALL;So;0;ON;;;;;N;;;;;
+1F52F;SIX POINTED STAR WITH MIDDLE DOT;So;0;ON;;;;;N;;;;;
+1F530;JAPANESE SYMBOL FOR BEGINNER;So;0;ON;;;;;N;;;;;
+1F531;TRIDENT EMBLEM;So;0;ON;;;;;N;;;;;
+1F532;BLACK SQUARE BUTTON;So;0;ON;;;;;N;;;;;
+1F533;WHITE SQUARE BUTTON;So;0;ON;;;;;N;;;;;
+1F534;LARGE RED CIRCLE;So;0;ON;;;;;N;;;;;
+1F535;LARGE BLUE CIRCLE;So;0;ON;;;;;N;;;;;
+1F536;LARGE ORANGE DIAMOND;So;0;ON;;;;;N;;;;;
+1F537;LARGE BLUE DIAMOND;So;0;ON;;;;;N;;;;;
+1F538;SMALL ORANGE DIAMOND;So;0;ON;;;;;N;;;;;
+1F539;SMALL BLUE DIAMOND;So;0;ON;;;;;N;;;;;
+1F53A;UP-POINTING RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F53B;DOWN-POINTING RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F53C;UP-POINTING SMALL RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F53D;DOWN-POINTING SMALL RED TRIANGLE;So;0;ON;;;;;N;;;;;
+1F53E;LOWER RIGHT SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F53F;UPPER RIGHT SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F540;CIRCLED CROSS POMMEE;So;0;ON;;;;;N;;;;;
+1F541;CROSS POMMEE WITH HALF-CIRCLE BELOW;So;0;ON;;;;;N;;;;;
+1F542;CROSS POMMEE;So;0;ON;;;;;N;;;;;
+1F543;NOTCHED LEFT SEMICIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;;
+1F544;NOTCHED RIGHT SEMICIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;;
+1F545;SYMBOL FOR MARKS CHAPTER;So;0;ON;;;;;N;;;;;
+1F546;WHITE LATIN CROSS;So;0;ON;;;;;N;;;;;
+1F547;HEAVY LATIN CROSS;So;0;ON;;;;;N;;;;;
+1F548;CELTIC CROSS;So;0;ON;;;;;N;;;;;
+1F549;OM SYMBOL;So;0;ON;;;;;N;;;;;
+1F54A;DOVE OF PEACE;So;0;ON;;;;;N;;;;;
+1F54B;KAABA;So;0;ON;;;;;N;;;;;
+1F54C;MOSQUE;So;0;ON;;;;;N;;;;;
+1F54D;SYNAGOGUE;So;0;ON;;;;;N;;;;;
+1F54E;MENORAH WITH NINE BRANCHES;So;0;ON;;;;;N;;;;;
+1F54F;BOWL OF HYGIEIA;So;0;ON;;;;;N;;;;;
+1F550;CLOCK FACE ONE OCLOCK;So;0;ON;;;;;N;;;;;
+1F551;CLOCK FACE TWO OCLOCK;So;0;ON;;;;;N;;;;;
+1F552;CLOCK FACE THREE OCLOCK;So;0;ON;;;;;N;;;;;
+1F553;CLOCK FACE FOUR OCLOCK;So;0;ON;;;;;N;;;;;
+1F554;CLOCK FACE FIVE OCLOCK;So;0;ON;;;;;N;;;;;
+1F555;CLOCK FACE SIX OCLOCK;So;0;ON;;;;;N;;;;;
+1F556;CLOCK FACE SEVEN OCLOCK;So;0;ON;;;;;N;;;;;
+1F557;CLOCK FACE EIGHT OCLOCK;So;0;ON;;;;;N;;;;;
+1F558;CLOCK FACE NINE OCLOCK;So;0;ON;;;;;N;;;;;
+1F559;CLOCK FACE TEN OCLOCK;So;0;ON;;;;;N;;;;;
+1F55A;CLOCK FACE ELEVEN OCLOCK;So;0;ON;;;;;N;;;;;
+1F55B;CLOCK FACE TWELVE OCLOCK;So;0;ON;;;;;N;;;;;
+1F55C;CLOCK FACE ONE-THIRTY;So;0;ON;;;;;N;;;;;
+1F55D;CLOCK FACE TWO-THIRTY;So;0;ON;;;;;N;;;;;
+1F55E;CLOCK FACE THREE-THIRTY;So;0;ON;;;;;N;;;;;
+1F55F;CLOCK FACE FOUR-THIRTY;So;0;ON;;;;;N;;;;;
+1F560;CLOCK FACE FIVE-THIRTY;So;0;ON;;;;;N;;;;;
+1F561;CLOCK FACE SIX-THIRTY;So;0;ON;;;;;N;;;;;
+1F562;CLOCK FACE SEVEN-THIRTY;So;0;ON;;;;;N;;;;;
+1F563;CLOCK FACE EIGHT-THIRTY;So;0;ON;;;;;N;;;;;
+1F564;CLOCK FACE NINE-THIRTY;So;0;ON;;;;;N;;;;;
+1F565;CLOCK FACE TEN-THIRTY;So;0;ON;;;;;N;;;;;
+1F566;CLOCK FACE ELEVEN-THIRTY;So;0;ON;;;;;N;;;;;
+1F567;CLOCK FACE TWELVE-THIRTY;So;0;ON;;;;;N;;;;;
+1F568;RIGHT SPEAKER;So;0;ON;;;;;N;;;;;
+1F569;RIGHT SPEAKER WITH ONE SOUND WAVE;So;0;ON;;;;;N;;;;;
+1F56A;RIGHT SPEAKER WITH THREE SOUND WAVES;So;0;ON;;;;;N;;;;;
+1F56B;BULLHORN;So;0;ON;;;;;N;;;;;
+1F56C;BULLHORN WITH SOUND WAVES;So;0;ON;;;;;N;;;;;
+1F56D;RINGING BELL;So;0;ON;;;;;N;;;;;
+1F56E;BOOK;So;0;ON;;;;;N;;;;;
+1F56F;CANDLE;So;0;ON;;;;;N;;;;;
+1F570;MANTELPIECE CLOCK;So;0;ON;;;;;N;;;;;
+1F571;BLACK SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;;
+1F572;NO PIRACY;So;0;ON;;;;;N;;;;;
+1F573;HOLE;So;0;ON;;;;;N;;;;;
+1F574;MAN IN BUSINESS SUIT LEVITATING;So;0;ON;;;;;N;;;;;
+1F575;SLEUTH OR SPY;So;0;ON;;;;;N;;;;;
+1F576;DARK SUNGLASSES;So;0;ON;;;;;N;;;;;
+1F577;SPIDER;So;0;ON;;;;;N;;;;;
+1F578;SPIDER WEB;So;0;ON;;;;;N;;;;;
+1F579;JOYSTICK;So;0;ON;;;;;N;;;;;
+1F57A;MAN DANCING;So;0;ON;;;;;N;;;;;
+1F57B;LEFT HAND TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;;
+1F57C;TELEPHONE RECEIVER WITH PAGE;So;0;ON;;;;;N;;;;;
+1F57D;RIGHT HAND TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;;
+1F57E;WHITE TOUCHTONE TELEPHONE;So;0;ON;;;;;N;;;;;
+1F57F;BLACK TOUCHTONE TELEPHONE;So;0;ON;;;;;N;;;;;
+1F580;TELEPHONE ON TOP OF MODEM;So;0;ON;;;;;N;;;;;
+1F581;CLAMSHELL MOBILE PHONE;So;0;ON;;;;;N;;;;;
+1F582;BACK OF ENVELOPE;So;0;ON;;;;;N;;;;;
+1F583;STAMPED ENVELOPE;So;0;ON;;;;;N;;;;;
+1F584;ENVELOPE WITH LIGHTNING;So;0;ON;;;;;N;;;;;
+1F585;FLYING ENVELOPE;So;0;ON;;;;;N;;;;;
+1F586;PEN OVER STAMPED ENVELOPE;So;0;ON;;;;;N;;;;;
+1F587;LINKED PAPERCLIPS;So;0;ON;;;;;N;;;;;
+1F588;BLACK PUSHPIN;So;0;ON;;;;;N;;;;;
+1F589;LOWER LEFT PENCIL;So;0;ON;;;;;N;;;;;
+1F58A;LOWER LEFT BALLPOINT PEN;So;0;ON;;;;;N;;;;;
+1F58B;LOWER LEFT FOUNTAIN PEN;So;0;ON;;;;;N;;;;;
+1F58C;LOWER LEFT PAINTBRUSH;So;0;ON;;;;;N;;;;;
+1F58D;LOWER LEFT CRAYON;So;0;ON;;;;;N;;;;;
+1F58E;LEFT WRITING HAND;So;0;ON;;;;;N;;;;;
+1F58F;TURNED OK HAND SIGN;So;0;ON;;;;;N;;;;;
+1F590;RAISED HAND WITH FINGERS SPLAYED;So;0;ON;;;;;N;;;;;
+1F591;REVERSED RAISED HAND WITH FINGERS SPLAYED;So;0;ON;;;;;N;;;;;
+1F592;REVERSED THUMBS UP SIGN;So;0;ON;;;;;N;;;;;
+1F593;REVERSED THUMBS DOWN SIGN;So;0;ON;;;;;N;;;;;
+1F594;REVERSED VICTORY HAND;So;0;ON;;;;;N;;;;;
+1F595;REVERSED HAND WITH MIDDLE FINGER EXTENDED;So;0;ON;;;;;N;;;;;
+1F596;RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS;So;0;ON;;;;;N;;;;;
+1F597;WHITE DOWN POINTING LEFT HAND INDEX;So;0;ON;;;;;N;;;;;
+1F598;SIDEWAYS WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F599;SIDEWAYS WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F59A;SIDEWAYS BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F59B;SIDEWAYS BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F59C;BLACK LEFT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F59D;BLACK RIGHT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F59E;SIDEWAYS WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F59F;SIDEWAYS WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F5A0;SIDEWAYS BLACK UP POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F5A1;SIDEWAYS BLACK DOWN POINTING INDEX;So;0;ON;;;;;N;;;;;
+1F5A2;BLACK UP POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F5A3;BLACK DOWN POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;
+1F5A4;BLACK HEART;So;0;ON;;;;;N;;;;;
+1F5A5;DESKTOP COMPUTER;So;0;ON;;;;;N;;;;;
+1F5A6;KEYBOARD AND MOUSE;So;0;ON;;;;;N;;;;;
+1F5A7;THREE NETWORKED COMPUTERS;So;0;ON;;;;;N;;;;;
+1F5A8;PRINTER;So;0;ON;;;;;N;;;;;
+1F5A9;POCKET CALCULATOR;So;0;ON;;;;;N;;;;;
+1F5AA;BLACK HARD SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;;
+1F5AB;WHITE HARD SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;;
+1F5AC;SOFT SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;;
+1F5AD;TAPE CARTRIDGE;So;0;ON;;;;;N;;;;;
+1F5AE;WIRED KEYBOARD;So;0;ON;;;;;N;;;;;
+1F5AF;ONE BUTTON MOUSE;So;0;ON;;;;;N;;;;;
+1F5B0;TWO BUTTON MOUSE;So;0;ON;;;;;N;;;;;
+1F5B1;THREE BUTTON MOUSE;So;0;ON;;;;;N;;;;;
+1F5B2;TRACKBALL;So;0;ON;;;;;N;;;;;
+1F5B3;OLD PERSONAL COMPUTER;So;0;ON;;;;;N;;;;;
+1F5B4;HARD DISK;So;0;ON;;;;;N;;;;;
+1F5B5;SCREEN;So;0;ON;;;;;N;;;;;
+1F5B6;PRINTER ICON;So;0;ON;;;;;N;;;;;
+1F5B7;FAX ICON;So;0;ON;;;;;N;;;;;
+1F5B8;OPTICAL DISC ICON;So;0;ON;;;;;N;;;;;
+1F5B9;DOCUMENT WITH TEXT;So;0;ON;;;;;N;;;;;
+1F5BA;DOCUMENT WITH TEXT AND PICTURE;So;0;ON;;;;;N;;;;;
+1F5BB;DOCUMENT WITH PICTURE;So;0;ON;;;;;N;;;;;
+1F5BC;FRAME WITH PICTURE;So;0;ON;;;;;N;;;;;
+1F5BD;FRAME WITH TILES;So;0;ON;;;;;N;;;;;
+1F5BE;FRAME WITH AN X;So;0;ON;;;;;N;;;;;
+1F5BF;BLACK FOLDER;So;0;ON;;;;;N;;;;;
+1F5C0;FOLDER;So;0;ON;;;;;N;;;;;
+1F5C1;OPEN FOLDER;So;0;ON;;;;;N;;;;;
+1F5C2;CARD INDEX DIVIDERS;So;0;ON;;;;;N;;;;;
+1F5C3;CARD FILE BOX;So;0;ON;;;;;N;;;;;
+1F5C4;FILE CABINET;So;0;ON;;;;;N;;;;;
+1F5C5;EMPTY NOTE;So;0;ON;;;;;N;;;;;
+1F5C6;EMPTY NOTE PAGE;So;0;ON;;;;;N;;;;;
+1F5C7;EMPTY NOTE PAD;So;0;ON;;;;;N;;;;;
+1F5C8;NOTE;So;0;ON;;;;;N;;;;;
+1F5C9;NOTE PAGE;So;0;ON;;;;;N;;;;;
+1F5CA;NOTE PAD;So;0;ON;;;;;N;;;;;
+1F5CB;EMPTY DOCUMENT;So;0;ON;;;;;N;;;;;
+1F5CC;EMPTY PAGE;So;0;ON;;;;;N;;;;;
+1F5CD;EMPTY PAGES;So;0;ON;;;;;N;;;;;
+1F5CE;DOCUMENT;So;0;ON;;;;;N;;;;;
+1F5CF;PAGE;So;0;ON;;;;;N;;;;;
+1F5D0;PAGES;So;0;ON;;;;;N;;;;;
+1F5D1;WASTEBASKET;So;0;ON;;;;;N;;;;;
+1F5D2;SPIRAL NOTE PAD;So;0;ON;;;;;N;;;;;
+1F5D3;SPIRAL CALENDAR PAD;So;0;ON;;;;;N;;;;;
+1F5D4;DESKTOP WINDOW;So;0;ON;;;;;N;;;;;
+1F5D5;MINIMIZE;So;0;ON;;;;;N;;;;;
+1F5D6;MAXIMIZE;So;0;ON;;;;;N;;;;;
+1F5D7;OVERLAP;So;0;ON;;;;;N;;;;;
+1F5D8;CLOCKWISE RIGHT AND LEFT SEMICIRCLE ARROWS;So;0;ON;;;;;N;;;;;
+1F5D9;CANCELLATION X;So;0;ON;;;;;N;;;;;
+1F5DA;INCREASE FONT SIZE SYMBOL;So;0;ON;;;;;N;;;;;
+1F5DB;DECREASE FONT SIZE SYMBOL;So;0;ON;;;;;N;;;;;
+1F5DC;COMPRESSION;So;0;ON;;;;;N;;;;;
+1F5DD;OLD KEY;So;0;ON;;;;;N;;;;;
+1F5DE;ROLLED-UP NEWSPAPER;So;0;ON;;;;;N;;;;;
+1F5DF;PAGE WITH CIRCLED TEXT;So;0;ON;;;;;N;;;;;
+1F5E0;STOCK CHART;So;0;ON;;;;;N;;;;;
+1F5E1;DAGGER KNIFE;So;0;ON;;;;;N;;;;;
+1F5E2;LIPS;So;0;ON;;;;;N;;;;;
+1F5E3;SPEAKING HEAD IN SILHOUETTE;So;0;ON;;;;;N;;;;;
+1F5E4;THREE RAYS ABOVE;So;0;ON;;;;;N;;;;;
+1F5E5;THREE RAYS BELOW;So;0;ON;;;;;N;;;;;
+1F5E6;THREE RAYS LEFT;So;0;ON;;;;;N;;;;;
+1F5E7;THREE RAYS RIGHT;So;0;ON;;;;;N;;;;;
+1F5E8;LEFT SPEECH BUBBLE;So;0;ON;;;;;N;;;;;
+1F5E9;RIGHT SPEECH BUBBLE;So;0;ON;;;;;N;;;;;
+1F5EA;TWO SPEECH BUBBLES;So;0;ON;;;;;N;;;;;
+1F5EB;THREE SPEECH BUBBLES;So;0;ON;;;;;N;;;;;
+1F5EC;LEFT THOUGHT BUBBLE;So;0;ON;;;;;N;;;;;
+1F5ED;RIGHT THOUGHT BUBBLE;So;0;ON;;;;;N;;;;;
+1F5EE;LEFT ANGER BUBBLE;So;0;ON;;;;;N;;;;;
+1F5EF;RIGHT ANGER BUBBLE;So;0;ON;;;;;N;;;;;
+1F5F0;MOOD BUBBLE;So;0;ON;;;;;N;;;;;
+1F5F1;LIGHTNING MOOD BUBBLE;So;0;ON;;;;;N;;;;;
+1F5F2;LIGHTNING MOOD;So;0;ON;;;;;N;;;;;
+1F5F3;BALLOT BOX WITH BALLOT;So;0;ON;;;;;N;;;;;
+1F5F4;BALLOT SCRIPT X;So;0;ON;;;;;N;;;;;
+1F5F5;BALLOT BOX WITH SCRIPT X;So;0;ON;;;;;N;;;;;
+1F5F6;BALLOT BOLD SCRIPT X;So;0;ON;;;;;N;;;;;
+1F5F7;BALLOT BOX WITH BOLD SCRIPT X;So;0;ON;;;;;N;;;;;
+1F5F8;LIGHT CHECK MARK;So;0;ON;;;;;N;;;;;
+1F5F9;BALLOT BOX WITH BOLD CHECK;So;0;ON;;;;;N;;;;;
+1F5FA;WORLD MAP;So;0;ON;;;;;N;;;;;
+1F5FB;MOUNT FUJI;So;0;ON;;;;;N;;;;;
+1F5FC;TOKYO TOWER;So;0;ON;;;;;N;;;;;
+1F5FD;STATUE OF LIBERTY;So;0;ON;;;;;N;;;;;
+1F5FE;SILHOUETTE OF JAPAN;So;0;ON;;;;;N;;;;;
+1F5FF;MOYAI;So;0;ON;;;;;N;;;;;
+1F600;GRINNING FACE;So;0;ON;;;;;N;;;;;
+1F601;GRINNING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;
+1F602;FACE WITH TEARS OF JOY;So;0;ON;;;;;N;;;;;
+1F603;SMILING FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;
+1F604;SMILING FACE WITH OPEN MOUTH AND SMILING EYES;So;0;ON;;;;;N;;;;;
+1F605;SMILING FACE WITH OPEN MOUTH AND COLD SWEAT;So;0;ON;;;;;N;;;;;
+1F606;SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F607;SMILING FACE WITH HALO;So;0;ON;;;;;N;;;;;
+1F608;SMILING FACE WITH HORNS;So;0;ON;;;;;N;;;;;
+1F609;WINKING FACE;So;0;ON;;;;;N;;;;;
+1F60A;SMILING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;
+1F60B;FACE SAVOURING DELICIOUS FOOD;So;0;ON;;;;;N;;;;;
+1F60C;RELIEVED FACE;So;0;ON;;;;;N;;;;;
+1F60D;SMILING FACE WITH HEART-SHAPED EYES;So;0;ON;;;;;N;;;;;
+1F60E;SMILING FACE WITH SUNGLASSES;So;0;ON;;;;;N;;;;;
+1F60F;SMIRKING FACE;So;0;ON;;;;;N;;;;;
+1F610;NEUTRAL FACE;So;0;ON;;;;;N;;;;;
+1F611;EXPRESSIONLESS FACE;So;0;ON;;;;;N;;;;;
+1F612;UNAMUSED FACE;So;0;ON;;;;;N;;;;;
+1F613;FACE WITH COLD SWEAT;So;0;ON;;;;;N;;;;;
+1F614;PENSIVE FACE;So;0;ON;;;;;N;;;;;
+1F615;CONFUSED FACE;So;0;ON;;;;;N;;;;;
+1F616;CONFOUNDED FACE;So;0;ON;;;;;N;;;;;
+1F617;KISSING FACE;So;0;ON;;;;;N;;;;;
+1F618;FACE THROWING A KISS;So;0;ON;;;;;N;;;;;
+1F619;KISSING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;
+1F61A;KISSING FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F61B;FACE WITH STUCK-OUT TONGUE;So;0;ON;;;;;N;;;;;
+1F61C;FACE WITH STUCK-OUT TONGUE AND WINKING EYE;So;0;ON;;;;;N;;;;;
+1F61D;FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F61E;DISAPPOINTED FACE;So;0;ON;;;;;N;;;;;
+1F61F;WORRIED FACE;So;0;ON;;;;;N;;;;;
+1F620;ANGRY FACE;So;0;ON;;;;;N;;;;;
+1F621;POUTING FACE;So;0;ON;;;;;N;;;;;
+1F622;CRYING FACE;So;0;ON;;;;;N;;;;;
+1F623;PERSEVERING FACE;So;0;ON;;;;;N;;;;;
+1F624;FACE WITH LOOK OF TRIUMPH;So;0;ON;;;;;N;;;;;
+1F625;DISAPPOINTED BUT RELIEVED FACE;So;0;ON;;;;;N;;;;;
+1F626;FROWNING FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;
+1F627;ANGUISHED FACE;So;0;ON;;;;;N;;;;;
+1F628;FEARFUL FACE;So;0;ON;;;;;N;;;;;
+1F629;WEARY FACE;So;0;ON;;;;;N;;;;;
+1F62A;SLEEPY FACE;So;0;ON;;;;;N;;;;;
+1F62B;TIRED FACE;So;0;ON;;;;;N;;;;;
+1F62C;GRIMACING FACE;So;0;ON;;;;;N;;;;;
+1F62D;LOUDLY CRYING FACE;So;0;ON;;;;;N;;;;;
+1F62E;FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;
+1F62F;HUSHED FACE;So;0;ON;;;;;N;;;;;
+1F630;FACE WITH OPEN MOUTH AND COLD SWEAT;So;0;ON;;;;;N;;;;;
+1F631;FACE SCREAMING IN FEAR;So;0;ON;;;;;N;;;;;
+1F632;ASTONISHED FACE;So;0;ON;;;;;N;;;;;
+1F633;FLUSHED FACE;So;0;ON;;;;;N;;;;;
+1F634;SLEEPING FACE;So;0;ON;;;;;N;;;;;
+1F635;DIZZY FACE;So;0;ON;;;;;N;;;;;
+1F636;FACE WITHOUT MOUTH;So;0;ON;;;;;N;;;;;
+1F637;FACE WITH MEDICAL MASK;So;0;ON;;;;;N;;;;;
+1F638;GRINNING CAT FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;
+1F639;CAT FACE WITH TEARS OF JOY;So;0;ON;;;;;N;;;;;
+1F63A;SMILING CAT FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;
+1F63B;SMILING CAT FACE WITH HEART-SHAPED EYES;So;0;ON;;;;;N;;;;;
+1F63C;CAT FACE WITH WRY SMILE;So;0;ON;;;;;N;;;;;
+1F63D;KISSING CAT FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;;
+1F63E;POUTING CAT FACE;So;0;ON;;;;;N;;;;;
+1F63F;CRYING CAT FACE;So;0;ON;;;;;N;;;;;
+1F640;WEARY CAT FACE;So;0;ON;;;;;N;;;;;
+1F641;SLIGHTLY FROWNING FACE;So;0;ON;;;;;N;;;;;
+1F642;SLIGHTLY SMILING FACE;So;0;ON;;;;;N;;;;;
+1F643;UPSIDE-DOWN FACE;So;0;ON;;;;;N;;;;;
+1F644;FACE WITH ROLLING EYES;So;0;ON;;;;;N;;;;;
+1F645;FACE WITH NO GOOD GESTURE;So;0;ON;;;;;N;;;;;
+1F646;FACE WITH OK GESTURE;So;0;ON;;;;;N;;;;;
+1F647;PERSON BOWING DEEPLY;So;0;ON;;;;;N;;;;;
+1F648;SEE-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;
+1F649;HEAR-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;
+1F64A;SPEAK-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;
+1F64B;HAPPY PERSON RAISING ONE HAND;So;0;ON;;;;;N;;;;;
+1F64C;PERSON RAISING BOTH HANDS IN CELEBRATION;So;0;ON;;;;;N;;;;;
+1F64D;PERSON FROWNING;So;0;ON;;;;;N;;;;;
+1F64E;PERSON WITH POUTING FACE;So;0;ON;;;;;N;;;;;
+1F64F;PERSON WITH FOLDED HANDS;So;0;ON;;;;;N;;;;;
+1F650;NORTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F651;SOUTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F652;NORTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F653;SOUTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F654;TURNED NORTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F655;TURNED SOUTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F656;TURNED NORTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F657;TURNED SOUTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;
+1F658;NORTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F659;SOUTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65A;NORTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65B;SOUTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65C;HEAVY NORTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65D;HEAVY SOUTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65E;HEAVY NORTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F65F;HEAVY SOUTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;
+1F660;NORTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F661;SOUTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F662;NORTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F663;SOUTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F664;HEAVY NORTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F665;HEAVY SOUTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F666;HEAVY NORTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F667;HEAVY SOUTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;
+1F668;HOLLOW QUILT SQUARE ORNAMENT;So;0;ON;;;;;N;;;;;
+1F669;HOLLOW QUILT SQUARE ORNAMENT IN BLACK SQUARE;So;0;ON;;;;;N;;;;;
+1F66A;SOLID QUILT SQUARE ORNAMENT;So;0;ON;;;;;N;;;;;
+1F66B;SOLID QUILT SQUARE ORNAMENT IN BLACK SQUARE;So;0;ON;;;;;N;;;;;
+1F66C;LEFTWARDS ROCKET;So;0;ON;;;;;N;;;;;
+1F66D;UPWARDS ROCKET;So;0;ON;;;;;N;;;;;
+1F66E;RIGHTWARDS ROCKET;So;0;ON;;;;;N;;;;;
+1F66F;DOWNWARDS ROCKET;So;0;ON;;;;;N;;;;;
+1F670;SCRIPT LIGATURE ET ORNAMENT;So;0;ON;;;;;N;;;;;
+1F671;HEAVY SCRIPT LIGATURE ET ORNAMENT;So;0;ON;;;;;N;;;;;
+1F672;LIGATURE OPEN ET ORNAMENT;So;0;ON;;;;;N;;;;;
+1F673;HEAVY LIGATURE OPEN ET ORNAMENT;So;0;ON;;;;;N;;;;;
+1F674;HEAVY AMPERSAND ORNAMENT;So;0;ON;;;;;N;;;;;
+1F675;SWASH AMPERSAND ORNAMENT;So;0;ON;;;;;N;;;;;
+1F676;SANS-SERIF HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+1F677;SANS-SERIF HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+1F678;SANS-SERIF HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
+1F679;HEAVY INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;;
+1F67A;SANS-SERIF INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;;
+1F67B;HEAVY SANS-SERIF INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;;
+1F67C;VERY HEAVY SOLIDUS;So;0;ON;;;;;N;;;;;
+1F67D;VERY HEAVY REVERSE SOLIDUS;So;0;ON;;;;;N;;;;;
+1F67E;CHECKER BOARD;So;0;ON;;;;;N;;;;;
+1F67F;REVERSE CHECKER BOARD;So;0;ON;;;;;N;;;;;
+1F680;ROCKET;So;0;ON;;;;;N;;;;;
+1F681;HELICOPTER;So;0;ON;;;;;N;;;;;
+1F682;STEAM LOCOMOTIVE;So;0;ON;;;;;N;;;;;
+1F683;RAILWAY CAR;So;0;ON;;;;;N;;;;;
+1F684;HIGH-SPEED TRAIN;So;0;ON;;;;;N;;;;;
+1F685;HIGH-SPEED TRAIN WITH BULLET NOSE;So;0;ON;;;;;N;;;;;
+1F686;TRAIN;So;0;ON;;;;;N;;;;;
+1F687;METRO;So;0;ON;;;;;N;;;;;
+1F688;LIGHT RAIL;So;0;ON;;;;;N;;;;;
+1F689;STATION;So;0;ON;;;;;N;;;;;
+1F68A;TRAM;So;0;ON;;;;;N;;;;;
+1F68B;TRAM CAR;So;0;ON;;;;;N;;;;;
+1F68C;BUS;So;0;ON;;;;;N;;;;;
+1F68D;ONCOMING BUS;So;0;ON;;;;;N;;;;;
+1F68E;TROLLEYBUS;So;0;ON;;;;;N;;;;;
+1F68F;BUS STOP;So;0;ON;;;;;N;;;;;
+1F690;MINIBUS;So;0;ON;;;;;N;;;;;
+1F691;AMBULANCE;So;0;ON;;;;;N;;;;;
+1F692;FIRE ENGINE;So;0;ON;;;;;N;;;;;
+1F693;POLICE CAR;So;0;ON;;;;;N;;;;;
+1F694;ONCOMING POLICE CAR;So;0;ON;;;;;N;;;;;
+1F695;TAXI;So;0;ON;;;;;N;;;;;
+1F696;ONCOMING TAXI;So;0;ON;;;;;N;;;;;
+1F697;AUTOMOBILE;So;0;ON;;;;;N;;;;;
+1F698;ONCOMING AUTOMOBILE;So;0;ON;;;;;N;;;;;
+1F699;RECREATIONAL VEHICLE;So;0;ON;;;;;N;;;;;
+1F69A;DELIVERY TRUCK;So;0;ON;;;;;N;;;;;
+1F69B;ARTICULATED LORRY;So;0;ON;;;;;N;;;;;
+1F69C;TRACTOR;So;0;ON;;;;;N;;;;;
+1F69D;MONORAIL;So;0;ON;;;;;N;;;;;
+1F69E;MOUNTAIN RAILWAY;So;0;ON;;;;;N;;;;;
+1F69F;SUSPENSION RAILWAY;So;0;ON;;;;;N;;;;;
+1F6A0;MOUNTAIN CABLEWAY;So;0;ON;;;;;N;;;;;
+1F6A1;AERIAL TRAMWAY;So;0;ON;;;;;N;;;;;
+1F6A2;SHIP;So;0;ON;;;;;N;;;;;
+1F6A3;ROWBOAT;So;0;ON;;;;;N;;;;;
+1F6A4;SPEEDBOAT;So;0;ON;;;;;N;;;;;
+1F6A5;HORIZONTAL TRAFFIC LIGHT;So;0;ON;;;;;N;;;;;
+1F6A6;VERTICAL TRAFFIC LIGHT;So;0;ON;;;;;N;;;;;
+1F6A7;CONSTRUCTION SIGN;So;0;ON;;;;;N;;;;;
+1F6A8;POLICE CARS REVOLVING LIGHT;So;0;ON;;;;;N;;;;;
+1F6A9;TRIANGULAR FLAG ON POST;So;0;ON;;;;;N;;;;;
+1F6AA;DOOR;So;0;ON;;;;;N;;;;;
+1F6AB;NO ENTRY SIGN;So;0;ON;;;;;N;;;;;
+1F6AC;SMOKING SYMBOL;So;0;ON;;;;;N;;;;;
+1F6AD;NO SMOKING SYMBOL;So;0;ON;;;;;N;;;;;
+1F6AE;PUT LITTER IN ITS PLACE SYMBOL;So;0;ON;;;;;N;;;;;
+1F6AF;DO NOT LITTER SYMBOL;So;0;ON;;;;;N;;;;;
+1F6B0;POTABLE WATER SYMBOL;So;0;ON;;;;;N;;;;;
+1F6B1;NON-POTABLE WATER SYMBOL;So;0;ON;;;;;N;;;;;
+1F6B2;BICYCLE;So;0;ON;;;;;N;;;;;
+1F6B3;NO BICYCLES;So;0;ON;;;;;N;;;;;
+1F6B4;BICYCLIST;So;0;ON;;;;;N;;;;;
+1F6B5;MOUNTAIN BICYCLIST;So;0;ON;;;;;N;;;;;
+1F6B6;PEDESTRIAN;So;0;ON;;;;;N;;;;;
+1F6B7;NO PEDESTRIANS;So;0;ON;;;;;N;;;;;
+1F6B8;CHILDREN CROSSING;So;0;ON;;;;;N;;;;;
+1F6B9;MENS SYMBOL;So;0;ON;;;;;N;;;;;
+1F6BA;WOMENS SYMBOL;So;0;ON;;;;;N;;;;;
+1F6BB;RESTROOM;So;0;ON;;;;;N;;;;;
+1F6BC;BABY SYMBOL;So;0;ON;;;;;N;;;;;
+1F6BD;TOILET;So;0;ON;;;;;N;;;;;
+1F6BE;WATER CLOSET;So;0;ON;;;;;N;;;;;
+1F6BF;SHOWER;So;0;ON;;;;;N;;;;;
+1F6C0;BATH;So;0;ON;;;;;N;;;;;
+1F6C1;BATHTUB;So;0;ON;;;;;N;;;;;
+1F6C2;PASSPORT CONTROL;So;0;ON;;;;;N;;;;;
+1F6C3;CUSTOMS;So;0;ON;;;;;N;;;;;
+1F6C4;BAGGAGE CLAIM;So;0;ON;;;;;N;;;;;
+1F6C5;LEFT LUGGAGE;So;0;ON;;;;;N;;;;;
+1F6C6;TRIANGLE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;;
+1F6C7;PROHIBITED SIGN;So;0;ON;;;;;N;;;;;
+1F6C8;CIRCLED INFORMATION SOURCE;So;0;ON;;;;;N;;;;;
+1F6C9;BOYS SYMBOL;So;0;ON;;;;;N;;;;;
+1F6CA;GIRLS SYMBOL;So;0;ON;;;;;N;;;;;
+1F6CB;COUCH AND LAMP;So;0;ON;;;;;N;;;;;
+1F6CC;SLEEPING ACCOMMODATION;So;0;ON;;;;;N;;;;;
+1F6CD;SHOPPING BAGS;So;0;ON;;;;;N;;;;;
+1F6CE;BELLHOP BELL;So;0;ON;;;;;N;;;;;
+1F6CF;BED;So;0;ON;;;;;N;;;;;
+1F6D0;PLACE OF WORSHIP;So;0;ON;;;;;N;;;;;
+1F6D1;OCTAGONAL SIGN;So;0;ON;;;;;N;;;;;
+1F6D2;SHOPPING TROLLEY;So;0;ON;;;;;N;;;;;
+1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;;
+1F6E1;SHIELD;So;0;ON;;;;;N;;;;;
+1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;;
+1F6E3;MOTORWAY;So;0;ON;;;;;N;;;;;
+1F6E4;RAILWAY TRACK;So;0;ON;;;;;N;;;;;
+1F6E5;MOTOR BOAT;So;0;ON;;;;;N;;;;;
+1F6E6;UP-POINTING MILITARY AIRPLANE;So;0;ON;;;;;N;;;;;
+1F6E7;UP-POINTING AIRPLANE;So;0;ON;;;;;N;;;;;
+1F6E8;UP-POINTING SMALL AIRPLANE;So;0;ON;;;;;N;;;;;
+1F6E9;SMALL AIRPLANE;So;0;ON;;;;;N;;;;;
+1F6EA;NORTHEAST-POINTING AIRPLANE;So;0;ON;;;;;N;;;;;
+1F6EB;AIRPLANE DEPARTURE;So;0;ON;;;;;N;;;;;
+1F6EC;AIRPLANE ARRIVING;So;0;ON;;;;;N;;;;;
+1F6F0;SATELLITE;So;0;ON;;;;;N;;;;;
+1F6F1;ONCOMING FIRE ENGINE;So;0;ON;;;;;N;;;;;
+1F6F2;DIESEL LOCOMOTIVE;So;0;ON;;;;;N;;;;;
+1F6F3;PASSENGER SHIP;So;0;ON;;;;;N;;;;;
+1F6F4;SCOOTER;So;0;ON;;;;;N;;;;;
+1F6F5;MOTOR SCOOTER;So;0;ON;;;;;N;;;;;
+1F6F6;CANOE;So;0;ON;;;;;N;;;;;
+1F700;ALCHEMICAL SYMBOL FOR QUINTESSENCE;So;0;ON;;;;;N;;;;;
+1F701;ALCHEMICAL SYMBOL FOR AIR;So;0;ON;;;;;N;;;;;
+1F702;ALCHEMICAL SYMBOL FOR FIRE;So;0;ON;;;;;N;;;;;
+1F703;ALCHEMICAL SYMBOL FOR EARTH;So;0;ON;;;;;N;;;;;
+1F704;ALCHEMICAL SYMBOL FOR WATER;So;0;ON;;;;;N;;;;;
+1F705;ALCHEMICAL SYMBOL FOR AQUAFORTIS;So;0;ON;;;;;N;;;;;
+1F706;ALCHEMICAL SYMBOL FOR AQUA REGIA;So;0;ON;;;;;N;;;;;
+1F707;ALCHEMICAL SYMBOL FOR AQUA REGIA-2;So;0;ON;;;;;N;;;;;
+1F708;ALCHEMICAL SYMBOL FOR AQUA VITAE;So;0;ON;;;;;N;;;;;
+1F709;ALCHEMICAL SYMBOL FOR AQUA VITAE-2;So;0;ON;;;;;N;;;;;
+1F70A;ALCHEMICAL SYMBOL FOR VINEGAR;So;0;ON;;;;;N;;;;;
+1F70B;ALCHEMICAL SYMBOL FOR VINEGAR-2;So;0;ON;;;;;N;;;;;
+1F70C;ALCHEMICAL SYMBOL FOR VINEGAR-3;So;0;ON;;;;;N;;;;;
+1F70D;ALCHEMICAL SYMBOL FOR SULFUR;So;0;ON;;;;;N;;;;;
+1F70E;ALCHEMICAL SYMBOL FOR PHILOSOPHERS SULFUR;So;0;ON;;;;;N;;;;;
+1F70F;ALCHEMICAL SYMBOL FOR BLACK SULFUR;So;0;ON;;;;;N;;;;;
+1F710;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE;So;0;ON;;;;;N;;;;;
+1F711;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-2;So;0;ON;;;;;N;;;;;
+1F712;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-3;So;0;ON;;;;;N;;;;;
+1F713;ALCHEMICAL SYMBOL FOR CINNABAR;So;0;ON;;;;;N;;;;;
+1F714;ALCHEMICAL SYMBOL FOR SALT;So;0;ON;;;;;N;;;;;
+1F715;ALCHEMICAL SYMBOL FOR NITRE;So;0;ON;;;;;N;;;;;
+1F716;ALCHEMICAL SYMBOL FOR VITRIOL;So;0;ON;;;;;N;;;;;
+1F717;ALCHEMICAL SYMBOL FOR VITRIOL-2;So;0;ON;;;;;N;;;;;
+1F718;ALCHEMICAL SYMBOL FOR ROCK SALT;So;0;ON;;;;;N;;;;;
+1F719;ALCHEMICAL SYMBOL FOR ROCK SALT-2;So;0;ON;;;;;N;;;;;
+1F71A;ALCHEMICAL SYMBOL FOR GOLD;So;0;ON;;;;;N;;;;;
+1F71B;ALCHEMICAL SYMBOL FOR SILVER;So;0;ON;;;;;N;;;;;
+1F71C;ALCHEMICAL SYMBOL FOR IRON ORE;So;0;ON;;;;;N;;;;;
+1F71D;ALCHEMICAL SYMBOL FOR IRON ORE-2;So;0;ON;;;;;N;;;;;
+1F71E;ALCHEMICAL SYMBOL FOR CROCUS OF IRON;So;0;ON;;;;;N;;;;;
+1F71F;ALCHEMICAL SYMBOL FOR REGULUS OF IRON;So;0;ON;;;;;N;;;;;
+1F720;ALCHEMICAL SYMBOL FOR COPPER ORE;So;0;ON;;;;;N;;;;;
+1F721;ALCHEMICAL SYMBOL FOR IRON-COPPER ORE;So;0;ON;;;;;N;;;;;
+1F722;ALCHEMICAL SYMBOL FOR SUBLIMATE OF COPPER;So;0;ON;;;;;N;;;;;
+1F723;ALCHEMICAL SYMBOL FOR CROCUS OF COPPER;So;0;ON;;;;;N;;;;;
+1F724;ALCHEMICAL SYMBOL FOR CROCUS OF COPPER-2;So;0;ON;;;;;N;;;;;
+1F725;ALCHEMICAL SYMBOL FOR COPPER ANTIMONIATE;So;0;ON;;;;;N;;;;;
+1F726;ALCHEMICAL SYMBOL FOR SALT OF COPPER ANTIMONIATE;So;0;ON;;;;;N;;;;;
+1F727;ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF COPPER;So;0;ON;;;;;N;;;;;
+1F728;ALCHEMICAL SYMBOL FOR VERDIGRIS;So;0;ON;;;;;N;;;;;
+1F729;ALCHEMICAL SYMBOL FOR TIN ORE;So;0;ON;;;;;N;;;;;
+1F72A;ALCHEMICAL SYMBOL FOR LEAD ORE;So;0;ON;;;;;N;;;;;
+1F72B;ALCHEMICAL SYMBOL FOR ANTIMONY ORE;So;0;ON;;;;;N;;;;;
+1F72C;ALCHEMICAL SYMBOL FOR SUBLIMATE OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F72D;ALCHEMICAL SYMBOL FOR SALT OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F72E;ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F72F;ALCHEMICAL SYMBOL FOR VINEGAR OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F730;ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY;So;0;ON;;;;;N;;;;;
+1F731;ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY-2;So;0;ON;;;;;N;;;;;
+1F732;ALCHEMICAL SYMBOL FOR REGULUS;So;0;ON;;;;;N;;;;;
+1F733;ALCHEMICAL SYMBOL FOR REGULUS-2;So;0;ON;;;;;N;;;;;
+1F734;ALCHEMICAL SYMBOL FOR REGULUS-3;So;0;ON;;;;;N;;;;;
+1F735;ALCHEMICAL SYMBOL FOR REGULUS-4;So;0;ON;;;;;N;;;;;
+1F736;ALCHEMICAL SYMBOL FOR ALKALI;So;0;ON;;;;;N;;;;;
+1F737;ALCHEMICAL SYMBOL FOR ALKALI-2;So;0;ON;;;;;N;;;;;
+1F738;ALCHEMICAL SYMBOL FOR MARCASITE;So;0;ON;;;;;N;;;;;
+1F739;ALCHEMICAL SYMBOL FOR SAL-AMMONIAC;So;0;ON;;;;;N;;;;;
+1F73A;ALCHEMICAL SYMBOL FOR ARSENIC;So;0;ON;;;;;N;;;;;
+1F73B;ALCHEMICAL SYMBOL FOR REALGAR;So;0;ON;;;;;N;;;;;
+1F73C;ALCHEMICAL SYMBOL FOR REALGAR-2;So;0;ON;;;;;N;;;;;
+1F73D;ALCHEMICAL SYMBOL FOR AURIPIGMENT;So;0;ON;;;;;N;;;;;
+1F73E;ALCHEMICAL SYMBOL FOR BISMUTH ORE;So;0;ON;;;;;N;;;;;
+1F73F;ALCHEMICAL SYMBOL FOR TARTAR;So;0;ON;;;;;N;;;;;
+1F740;ALCHEMICAL SYMBOL FOR TARTAR-2;So;0;ON;;;;;N;;;;;
+1F741;ALCHEMICAL SYMBOL FOR QUICK LIME;So;0;ON;;;;;N;;;;;
+1F742;ALCHEMICAL SYMBOL FOR BORAX;So;0;ON;;;;;N;;;;;
+1F743;ALCHEMICAL SYMBOL FOR BORAX-2;So;0;ON;;;;;N;;;;;
+1F744;ALCHEMICAL SYMBOL FOR BORAX-3;So;0;ON;;;;;N;;;;;
+1F745;ALCHEMICAL SYMBOL FOR ALUM;So;0;ON;;;;;N;;;;;
+1F746;ALCHEMICAL SYMBOL FOR OIL;So;0;ON;;;;;N;;;;;
+1F747;ALCHEMICAL SYMBOL FOR SPIRIT;So;0;ON;;;;;N;;;;;
+1F748;ALCHEMICAL SYMBOL FOR TINCTURE;So;0;ON;;;;;N;;;;;
+1F749;ALCHEMICAL SYMBOL FOR GUM;So;0;ON;;;;;N;;;;;
+1F74A;ALCHEMICAL SYMBOL FOR WAX;So;0;ON;;;;;N;;;;;
+1F74B;ALCHEMICAL SYMBOL FOR POWDER;So;0;ON;;;;;N;;;;;
+1F74C;ALCHEMICAL SYMBOL FOR CALX;So;0;ON;;;;;N;;;;;
+1F74D;ALCHEMICAL SYMBOL FOR TUTTY;So;0;ON;;;;;N;;;;;
+1F74E;ALCHEMICAL SYMBOL FOR CAPUT MORTUUM;So;0;ON;;;;;N;;;;;
+1F74F;ALCHEMICAL SYMBOL FOR SCEPTER OF JOVE;So;0;ON;;;;;N;;;;;
+1F750;ALCHEMICAL SYMBOL FOR CADUCEUS;So;0;ON;;;;;N;;;;;
+1F751;ALCHEMICAL SYMBOL FOR TRIDENT;So;0;ON;;;;;N;;;;;
+1F752;ALCHEMICAL SYMBOL FOR STARRED TRIDENT;So;0;ON;;;;;N;;;;;
+1F753;ALCHEMICAL SYMBOL FOR LODESTONE;So;0;ON;;;;;N;;;;;
+1F754;ALCHEMICAL SYMBOL FOR SOAP;So;0;ON;;;;;N;;;;;
+1F755;ALCHEMICAL SYMBOL FOR URINE;So;0;ON;;;;;N;;;;;
+1F756;ALCHEMICAL SYMBOL FOR HORSE DUNG;So;0;ON;;;;;N;;;;;
+1F757;ALCHEMICAL SYMBOL FOR ASHES;So;0;ON;;;;;N;;;;;
+1F758;ALCHEMICAL SYMBOL FOR POT ASHES;So;0;ON;;;;;N;;;;;
+1F759;ALCHEMICAL SYMBOL FOR BRICK;So;0;ON;;;;;N;;;;;
+1F75A;ALCHEMICAL SYMBOL FOR POWDERED BRICK;So;0;ON;;;;;N;;;;;
+1F75B;ALCHEMICAL SYMBOL FOR AMALGAM;So;0;ON;;;;;N;;;;;
+1F75C;ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM;So;0;ON;;;;;N;;;;;
+1F75D;ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM-2;So;0;ON;;;;;N;;;;;
+1F75E;ALCHEMICAL SYMBOL FOR SUBLIMATION;So;0;ON;;;;;N;;;;;
+1F75F;ALCHEMICAL SYMBOL FOR PRECIPITATE;So;0;ON;;;;;N;;;;;
+1F760;ALCHEMICAL SYMBOL FOR DISTILL;So;0;ON;;;;;N;;;;;
+1F761;ALCHEMICAL SYMBOL FOR DISSOLVE;So;0;ON;;;;;N;;;;;
+1F762;ALCHEMICAL SYMBOL FOR DISSOLVE-2;So;0;ON;;;;;N;;;;;
+1F763;ALCHEMICAL SYMBOL FOR PURIFY;So;0;ON;;;;;N;;;;;
+1F764;ALCHEMICAL SYMBOL FOR PUTREFACTION;So;0;ON;;;;;N;;;;;
+1F765;ALCHEMICAL SYMBOL FOR CRUCIBLE;So;0;ON;;;;;N;;;;;
+1F766;ALCHEMICAL SYMBOL FOR CRUCIBLE-2;So;0;ON;;;;;N;;;;;
+1F767;ALCHEMICAL SYMBOL FOR CRUCIBLE-3;So;0;ON;;;;;N;;;;;
+1F768;ALCHEMICAL SYMBOL FOR CRUCIBLE-4;So;0;ON;;;;;N;;;;;
+1F769;ALCHEMICAL SYMBOL FOR CRUCIBLE-5;So;0;ON;;;;;N;;;;;
+1F76A;ALCHEMICAL SYMBOL FOR ALEMBIC;So;0;ON;;;;;N;;;;;
+1F76B;ALCHEMICAL SYMBOL FOR BATH OF MARY;So;0;ON;;;;;N;;;;;
+1F76C;ALCHEMICAL SYMBOL FOR BATH OF VAPOURS;So;0;ON;;;;;N;;;;;
+1F76D;ALCHEMICAL SYMBOL FOR RETORT;So;0;ON;;;;;N;;;;;
+1F76E;ALCHEMICAL SYMBOL FOR HOUR;So;0;ON;;;;;N;;;;;
+1F76F;ALCHEMICAL SYMBOL FOR NIGHT;So;0;ON;;;;;N;;;;;
+1F770;ALCHEMICAL SYMBOL FOR DAY-NIGHT;So;0;ON;;;;;N;;;;;
+1F771;ALCHEMICAL SYMBOL FOR MONTH;So;0;ON;;;;;N;;;;;
+1F772;ALCHEMICAL SYMBOL FOR HALF DRAM;So;0;ON;;;;;N;;;;;
+1F773;ALCHEMICAL SYMBOL FOR HALF OUNCE;So;0;ON;;;;;N;;;;;
+1F780;BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+1F781;BLACK UP-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+1F782;BLACK RIGHT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+1F783;BLACK DOWN-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
+1F784;BLACK SLIGHTLY SMALL CIRCLE;So;0;ON;;;;;N;;;;;
+1F785;MEDIUM BOLD WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F786;BOLD WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F787;HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F788;VERY HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F789;EXTREMELY HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;;
+1F78A;WHITE CIRCLE CONTAINING BLACK SMALL CIRCLE;So;0;ON;;;;;N;;;;;
+1F78B;ROUND TARGET;So;0;ON;;;;;N;;;;;
+1F78C;BLACK TINY SQUARE;So;0;ON;;;;;N;;;;;
+1F78D;BLACK SLIGHTLY SMALL SQUARE;So;0;ON;;;;;N;;;;;
+1F78E;LIGHT WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F78F;MEDIUM WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F790;BOLD WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F791;HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F792;VERY HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F793;EXTREMELY HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;;
+1F794;WHITE SQUARE CONTAINING BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;;
+1F795;WHITE SQUARE CONTAINING BLACK MEDIUM SQUARE;So;0;ON;;;;;N;;;;;
+1F796;SQUARE TARGET;So;0;ON;;;;;N;;;;;
+1F797;BLACK TINY DIAMOND;So;0;ON;;;;;N;;;;;
+1F798;BLACK VERY SMALL DIAMOND;So;0;ON;;;;;N;;;;;
+1F799;BLACK MEDIUM SMALL DIAMOND;So;0;ON;;;;;N;;;;;
+1F79A;WHITE DIAMOND CONTAINING BLACK VERY SMALL DIAMOND;So;0;ON;;;;;N;;;;;
+1F79B;WHITE DIAMOND CONTAINING BLACK MEDIUM DIAMOND;So;0;ON;;;;;N;;;;;
+1F79C;DIAMOND TARGET;So;0;ON;;;;;N;;;;;
+1F79D;BLACK TINY LOZENGE;So;0;ON;;;;;N;;;;;
+1F79E;BLACK VERY SMALL LOZENGE;So;0;ON;;;;;N;;;;;
+1F79F;BLACK MEDIUM SMALL LOZENGE;So;0;ON;;;;;N;;;;;
+1F7A0;WHITE LOZENGE CONTAINING BLACK SMALL LOZENGE;So;0;ON;;;;;N;;;;;
+1F7A1;THIN GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A2;LIGHT GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A3;MEDIUM GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A4;BOLD GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A5;VERY BOLD GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A6;VERY HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A7;EXTREMELY HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;;
+1F7A8;THIN SALTIRE;So;0;ON;;;;;N;;;;;
+1F7A9;LIGHT SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AA;MEDIUM SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AB;BOLD SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AC;HEAVY SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AD;VERY HEAVY SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AE;EXTREMELY HEAVY SALTIRE;So;0;ON;;;;;N;;;;;
+1F7AF;LIGHT FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B0;MEDIUM FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B1;BOLD FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B2;HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B3;VERY HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B4;EXTREMELY HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B5;LIGHT SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B6;MEDIUM SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B7;BOLD SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B8;HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7B9;VERY HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BA;EXTREMELY HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BB;LIGHT EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BC;MEDIUM EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BD;BOLD EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BE;HEAVY EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7BF;VERY HEAVY EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
+1F7C0;LIGHT THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C1;MEDIUM THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C2;THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C3;MEDIUM THREE POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F7C4;LIGHT FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C5;MEDIUM FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C6;FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7C7;MEDIUM FOUR POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F7C8;REVERSE LIGHT FOUR POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F7C9;LIGHT FIVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7CA;HEAVY FIVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7CB;MEDIUM SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7CC;HEAVY SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7CD;SIX POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F7CE;MEDIUM EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7CF;HEAVY EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7D0;VERY HEAVY EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7D1;HEAVY EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F7D2;LIGHT TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7D3;HEAVY TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
+1F7D4;HEAVY TWELVE POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
+1F800;LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F801;UPWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F802;RIGHTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F803;DOWNWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F804;LEFTWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F805;UPWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F806;RIGHTWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F807;DOWNWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F808;LEFTWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F809;UPWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F80A;RIGHTWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F80B;DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F810;LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F811;UPWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F812;RIGHTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F813;DOWNWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F814;LEFTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F815;UPWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F816;RIGHTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F817;DOWNWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F818;HEAVY LEFTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F819;HEAVY UPWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81A;HEAVY RIGHTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81B;HEAVY DOWNWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81C;HEAVY LEFTWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81D;HEAVY UPWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81E;HEAVY RIGHTWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F81F;HEAVY DOWNWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F820;LEFTWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;
+1F821;UPWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;
+1F822;RIGHTWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;
+1F823;DOWNWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;
+1F824;LEFTWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;
+1F825;UPWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;
+1F826;RIGHTWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;
+1F827;DOWNWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;
+1F828;LEFTWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;
+1F829;UPWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;
+1F82A;RIGHTWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;
+1F82B;DOWNWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;
+1F82C;LEFTWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F82D;UPWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F82E;RIGHTWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F82F;DOWNWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F830;LEFTWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F831;UPWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F832;RIGHTWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F833;DOWNWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;
+1F834;LEFTWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;
+1F835;UPWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;
+1F836;RIGHTWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;
+1F837;DOWNWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;
+1F838;LEFTWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;
+1F839;UPWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;
+1F83A;RIGHTWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;
+1F83B;DOWNWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;
+1F83C;LEFTWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F83D;UPWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F83E;RIGHTWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F83F;DOWNWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F840;LEFTWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F841;UPWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F842;RIGHTWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F843;DOWNWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;
+1F844;LEFTWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;
+1F845;UPWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;
+1F846;RIGHTWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;
+1F847;DOWNWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;
+1F850;LEFTWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F851;UPWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F852;RIGHTWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F853;DOWNWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F854;NORTH WEST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F855;NORTH EAST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F856;SOUTH EAST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F857;SOUTH WEST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F858;LEFT RIGHT SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F859;UP DOWN SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;
+1F860;WIDE-HEADED LEFTWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F861;WIDE-HEADED UPWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F862;WIDE-HEADED RIGHTWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F863;WIDE-HEADED DOWNWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F864;WIDE-HEADED NORTH WEST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F865;WIDE-HEADED NORTH EAST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F866;WIDE-HEADED SOUTH EAST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F867;WIDE-HEADED SOUTH WEST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;
+1F868;WIDE-HEADED LEFTWARDS BARB ARROW;So;0;ON;;;;;N;;;;;
+1F869;WIDE-HEADED UPWARDS BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86A;WIDE-HEADED RIGHTWARDS BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86B;WIDE-HEADED DOWNWARDS BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86C;WIDE-HEADED NORTH WEST BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86D;WIDE-HEADED NORTH EAST BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86E;WIDE-HEADED SOUTH EAST BARB ARROW;So;0;ON;;;;;N;;;;;
+1F86F;WIDE-HEADED SOUTH WEST BARB ARROW;So;0;ON;;;;;N;;;;;
+1F870;WIDE-HEADED LEFTWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F871;WIDE-HEADED UPWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F872;WIDE-HEADED RIGHTWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F873;WIDE-HEADED DOWNWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F874;WIDE-HEADED NORTH WEST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F875;WIDE-HEADED NORTH EAST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F876;WIDE-HEADED SOUTH EAST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F877;WIDE-HEADED SOUTH WEST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;
+1F878;WIDE-HEADED LEFTWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F879;WIDE-HEADED UPWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87A;WIDE-HEADED RIGHTWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87B;WIDE-HEADED DOWNWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87C;WIDE-HEADED NORTH WEST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87D;WIDE-HEADED NORTH EAST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87E;WIDE-HEADED SOUTH EAST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F87F;WIDE-HEADED SOUTH WEST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F880;WIDE-HEADED LEFTWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F881;WIDE-HEADED UPWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F882;WIDE-HEADED RIGHTWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F883;WIDE-HEADED DOWNWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F884;WIDE-HEADED NORTH WEST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F885;WIDE-HEADED NORTH EAST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F886;WIDE-HEADED SOUTH EAST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F887;WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;
+1F890;LEFTWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F891;UPWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F892;RIGHTWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F893;DOWNWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F894;LEFTWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F895;UPWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F896;RIGHTWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F897;DOWNWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
+1F898;LEFTWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;
+1F899;UPWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;
+1F89A;RIGHTWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;
+1F89B;DOWNWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;
+1F89C;HEAVY ARROW SHAFT WIDTH ONE;So;0;ON;;;;;N;;;;;
+1F89D;HEAVY ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;;
+1F89E;HEAVY ARROW SHAFT WIDTH ONE HALF;So;0;ON;;;;;N;;;;;
+1F89F;HEAVY ARROW SHAFT WIDTH ONE THIRD;So;0;ON;;;;;N;;;;;
+1F8A0;LEFTWARDS BOTTOM-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A1;RIGHTWARDS BOTTOM SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A2;LEFTWARDS TOP SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A3;RIGHTWARDS TOP SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A4;LEFTWARDS LEFT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A5;RIGHTWARDS RIGHT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A6;LEFTWARDS RIGHT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A7;RIGHTWARDS LEFT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A8;LEFTWARDS BACK-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8A9;RIGHTWARDS BACK-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8AA;LEFTWARDS FRONT-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8AB;RIGHTWARDS FRONT-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;
+1F8AC;WHITE ARROW SHAFT WIDTH ONE;So;0;ON;;;;;N;;;;;
+1F8AD;WHITE ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;;
+1F910;ZIPPER-MOUTH FACE;So;0;ON;;;;;N;;;;;
+1F911;MONEY-MOUTH FACE;So;0;ON;;;;;N;;;;;
+1F912;FACE WITH THERMOMETER;So;0;ON;;;;;N;;;;;
+1F913;NERD FACE;So;0;ON;;;;;N;;;;;
+1F914;THINKING FACE;So;0;ON;;;;;N;;;;;
+1F915;FACE WITH HEAD-BANDAGE;So;0;ON;;;;;N;;;;;
+1F916;ROBOT FACE;So;0;ON;;;;;N;;;;;
+1F917;HUGGING FACE;So;0;ON;;;;;N;;;;;
+1F918;SIGN OF THE HORNS;So;0;ON;;;;;N;;;;;
+1F919;CALL ME HAND;So;0;ON;;;;;N;;;;;
+1F91A;RAISED BACK OF HAND;So;0;ON;;;;;N;;;;;
+1F91B;LEFT-FACING FIST;So;0;ON;;;;;N;;;;;
+1F91C;RIGHT-FACING FIST;So;0;ON;;;;;N;;;;;
+1F91D;HANDSHAKE;So;0;ON;;;;;N;;;;;
+1F91E;HAND WITH INDEX AND MIDDLE FINGERS CROSSED;So;0;ON;;;;;N;;;;;
+1F920;FACE WITH COWBOY HAT;So;0;ON;;;;;N;;;;;
+1F921;CLOWN FACE;So;0;ON;;;;;N;;;;;
+1F922;NAUSEATED FACE;So;0;ON;;;;;N;;;;;
+1F923;ROLLING ON THE FLOOR LAUGHING;So;0;ON;;;;;N;;;;;
+1F924;DROOLING FACE;So;0;ON;;;;;N;;;;;
+1F925;LYING FACE;So;0;ON;;;;;N;;;;;
+1F926;FACE PALM;So;0;ON;;;;;N;;;;;
+1F927;SNEEZING FACE;So;0;ON;;;;;N;;;;;
+1F930;PREGNANT WOMAN;So;0;ON;;;;;N;;;;;
+1F933;SELFIE;So;0;ON;;;;;N;;;;;
+1F934;PRINCE;So;0;ON;;;;;N;;;;;
+1F935;MAN IN TUXEDO;So;0;ON;;;;;N;;;;;
+1F936;MOTHER CHRISTMAS;So;0;ON;;;;;N;;;;;
+1F937;SHRUG;So;0;ON;;;;;N;;;;;
+1F938;PERSON DOING CARTWHEEL;So;0;ON;;;;;N;;;;;
+1F939;JUGGLING;So;0;ON;;;;;N;;;;;
+1F93A;FENCER;So;0;ON;;;;;N;;;;;
+1F93B;MODERN PENTATHLON;So;0;ON;;;;;N;;;;;
+1F93C;WRESTLERS;So;0;ON;;;;;N;;;;;
+1F93D;WATER POLO;So;0;ON;;;;;N;;;;;
+1F93E;HANDBALL;So;0;ON;;;;;N;;;;;
+1F940;WILTED FLOWER;So;0;ON;;;;;N;;;;;
+1F941;DRUM WITH DRUMSTICKS;So;0;ON;;;;;N;;;;;
+1F942;CLINKING GLASSES;So;0;ON;;;;;N;;;;;
+1F943;TUMBLER GLASS;So;0;ON;;;;;N;;;;;
+1F944;SPOON;So;0;ON;;;;;N;;;;;
+1F945;GOAL NET;So;0;ON;;;;;N;;;;;
+1F946;RIFLE;So;0;ON;;;;;N;;;;;
+1F947;FIRST PLACE MEDAL;So;0;ON;;;;;N;;;;;
+1F948;SECOND PLACE MEDAL;So;0;ON;;;;;N;;;;;
+1F949;THIRD PLACE MEDAL;So;0;ON;;;;;N;;;;;
+1F94A;BOXING GLOVE;So;0;ON;;;;;N;;;;;
+1F94B;MARTIAL ARTS UNIFORM;So;0;ON;;;;;N;;;;;
+1F950;CROISSANT;So;0;ON;;;;;N;;;;;
+1F951;AVOCADO;So;0;ON;;;;;N;;;;;
+1F952;CUCUMBER;So;0;ON;;;;;N;;;;;
+1F953;BACON;So;0;ON;;;;;N;;;;;
+1F954;POTATO;So;0;ON;;;;;N;;;;;
+1F955;CARROT;So;0;ON;;;;;N;;;;;
+1F956;BAGUETTE BREAD;So;0;ON;;;;;N;;;;;
+1F957;GREEN SALAD;So;0;ON;;;;;N;;;;;
+1F958;SHALLOW PAN OF FOOD;So;0;ON;;;;;N;;;;;
+1F959;STUFFED FLATBREAD;So;0;ON;;;;;N;;;;;
+1F95A;EGG;So;0;ON;;;;;N;;;;;
+1F95B;GLASS OF MILK;So;0;ON;;;;;N;;;;;
+1F95C;PEANUTS;So;0;ON;;;;;N;;;;;
+1F95D;KIWIFRUIT;So;0;ON;;;;;N;;;;;
+1F95E;PANCAKES;So;0;ON;;;;;N;;;;;
+1F980;CRAB;So;0;ON;;;;;N;;;;;
+1F981;LION FACE;So;0;ON;;;;;N;;;;;
+1F982;SCORPION;So;0;ON;;;;;N;;;;;
+1F983;TURKEY;So;0;ON;;;;;N;;;;;
+1F984;UNICORN FACE;So;0;ON;;;;;N;;;;;
+1F985;EAGLE;So;0;ON;;;;;N;;;;;
+1F986;DUCK;So;0;ON;;;;;N;;;;;
+1F987;BAT;So;0;ON;;;;;N;;;;;
+1F988;SHARK;So;0;ON;;;;;N;;;;;
+1F989;OWL;So;0;ON;;;;;N;;;;;
+1F98A;FOX FACE;So;0;ON;;;;;N;;;;;
+1F98B;BUTTERFLY;So;0;ON;;;;;N;;;;;
+1F98C;DEER;So;0;ON;;;;;N;;;;;
+1F98D;GORILLA;So;0;ON;;;;;N;;;;;
+1F98E;LIZARD;So;0;ON;;;;;N;;;;;
+1F98F;RHINOCEROS;So;0;ON;;;;;N;;;;;
+1F990;SHRIMP;So;0;ON;;;;;N;;;;;
+1F991;SQUID;So;0;ON;;;;;N;;;;;
+1F9C0;CHEESE WEDGE;So;0;ON;;;;;N;;;;;
+20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;;
+2A6D6;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
+2A700;<CJK Ideograph Extension C, First>;Lo;0;L;;;;;N;;;;;
+2B734;<CJK Ideograph Extension C, Last>;Lo;0;L;;;;;N;;;;;
+2B740;<CJK Ideograph Extension D, First>;Lo;0;L;;;;;N;;;;;
+2B81D;<CJK Ideograph Extension D, Last>;Lo;0;L;;;;;N;;;;;
+2B820;<CJK Ideograph Extension E, First>;Lo;0;L;;;;;N;;;;;
+2CEA1;<CJK Ideograph Extension E, Last>;Lo;0;L;;;;;N;;;;;
+2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;;
+2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;;
+2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;;
+2F803;CJK COMPATIBILITY IDEOGRAPH-2F803;Lo;0;L;20122;;;;N;;;;;
+2F804;CJK COMPATIBILITY IDEOGRAPH-2F804;Lo;0;L;4F60;;;;N;;;;;
+2F805;CJK COMPATIBILITY IDEOGRAPH-2F805;Lo;0;L;4FAE;;;;N;;;;;
+2F806;CJK COMPATIBILITY IDEOGRAPH-2F806;Lo;0;L;4FBB;;;;N;;;;;
+2F807;CJK COMPATIBILITY IDEOGRAPH-2F807;Lo;0;L;5002;;;;N;;;;;
+2F808;CJK COMPATIBILITY IDEOGRAPH-2F808;Lo;0;L;507A;;;;N;;;;;
+2F809;CJK COMPATIBILITY IDEOGRAPH-2F809;Lo;0;L;5099;;;;N;;;;;
+2F80A;CJK COMPATIBILITY IDEOGRAPH-2F80A;Lo;0;L;50E7;;;;N;;;;;
+2F80B;CJK COMPATIBILITY IDEOGRAPH-2F80B;Lo;0;L;50CF;;;;N;;;;;
+2F80C;CJK COMPATIBILITY IDEOGRAPH-2F80C;Lo;0;L;349E;;;;N;;;;;
+2F80D;CJK COMPATIBILITY IDEOGRAPH-2F80D;Lo;0;L;2063A;;;;N;;;;;
+2F80E;CJK COMPATIBILITY IDEOGRAPH-2F80E;Lo;0;L;514D;;;;N;;;;;
+2F80F;CJK COMPATIBILITY IDEOGRAPH-2F80F;Lo;0;L;5154;;;;N;;;;;
+2F810;CJK COMPATIBILITY IDEOGRAPH-2F810;Lo;0;L;5164;;;;N;;;;;
+2F811;CJK COMPATIBILITY IDEOGRAPH-2F811;Lo;0;L;5177;;;;N;;;;;
+2F812;CJK COMPATIBILITY IDEOGRAPH-2F812;Lo;0;L;2051C;;;;N;;;;;
+2F813;CJK COMPATIBILITY IDEOGRAPH-2F813;Lo;0;L;34B9;;;;N;;;;;
+2F814;CJK COMPATIBILITY IDEOGRAPH-2F814;Lo;0;L;5167;;;;N;;;;;
+2F815;CJK COMPATIBILITY IDEOGRAPH-2F815;Lo;0;L;518D;;;;N;;;;;
+2F816;CJK COMPATIBILITY IDEOGRAPH-2F816;Lo;0;L;2054B;;;;N;;;;;
+2F817;CJK COMPATIBILITY IDEOGRAPH-2F817;Lo;0;L;5197;;;;N;;;;;
+2F818;CJK COMPATIBILITY IDEOGRAPH-2F818;Lo;0;L;51A4;;;;N;;;;;
+2F819;CJK COMPATIBILITY IDEOGRAPH-2F819;Lo;0;L;4ECC;;;;N;;;;;
+2F81A;CJK COMPATIBILITY IDEOGRAPH-2F81A;Lo;0;L;51AC;;;;N;;;;;
+2F81B;CJK COMPATIBILITY IDEOGRAPH-2F81B;Lo;0;L;51B5;;;;N;;;;;
+2F81C;CJK COMPATIBILITY IDEOGRAPH-2F81C;Lo;0;L;291DF;;;;N;;;;;
+2F81D;CJK COMPATIBILITY IDEOGRAPH-2F81D;Lo;0;L;51F5;;;;N;;;;;
+2F81E;CJK COMPATIBILITY IDEOGRAPH-2F81E;Lo;0;L;5203;;;;N;;;;;
+2F81F;CJK COMPATIBILITY IDEOGRAPH-2F81F;Lo;0;L;34DF;;;;N;;;;;
+2F820;CJK COMPATIBILITY IDEOGRAPH-2F820;Lo;0;L;523B;;;;N;;;;;
+2F821;CJK COMPATIBILITY IDEOGRAPH-2F821;Lo;0;L;5246;;;;N;;;;;
+2F822;CJK COMPATIBILITY IDEOGRAPH-2F822;Lo;0;L;5272;;;;N;;;;;
+2F823;CJK COMPATIBILITY IDEOGRAPH-2F823;Lo;0;L;5277;;;;N;;;;;
+2F824;CJK COMPATIBILITY IDEOGRAPH-2F824;Lo;0;L;3515;;;;N;;;;;
+2F825;CJK COMPATIBILITY IDEOGRAPH-2F825;Lo;0;L;52C7;;;;N;;;;;
+2F826;CJK COMPATIBILITY IDEOGRAPH-2F826;Lo;0;L;52C9;;;;N;;;;;
+2F827;CJK COMPATIBILITY IDEOGRAPH-2F827;Lo;0;L;52E4;;;;N;;;;;
+2F828;CJK COMPATIBILITY IDEOGRAPH-2F828;Lo;0;L;52FA;;;;N;;;;;
+2F829;CJK COMPATIBILITY IDEOGRAPH-2F829;Lo;0;L;5305;;;;N;;;;;
+2F82A;CJK COMPATIBILITY IDEOGRAPH-2F82A;Lo;0;L;5306;;;;N;;;;;
+2F82B;CJK COMPATIBILITY IDEOGRAPH-2F82B;Lo;0;L;5317;;;;N;;;;;
+2F82C;CJK COMPATIBILITY IDEOGRAPH-2F82C;Lo;0;L;5349;;;;N;;;;;
+2F82D;CJK COMPATIBILITY IDEOGRAPH-2F82D;Lo;0;L;5351;;;;N;;;;;
+2F82E;CJK COMPATIBILITY IDEOGRAPH-2F82E;Lo;0;L;535A;;;;N;;;;;
+2F82F;CJK COMPATIBILITY IDEOGRAPH-2F82F;Lo;0;L;5373;;;;N;;;;;
+2F830;CJK COMPATIBILITY IDEOGRAPH-2F830;Lo;0;L;537D;;;;N;;;;;
+2F831;CJK COMPATIBILITY IDEOGRAPH-2F831;Lo;0;L;537F;;;;N;;;;;
+2F832;CJK COMPATIBILITY IDEOGRAPH-2F832;Lo;0;L;537F;;;;N;;;;;
+2F833;CJK COMPATIBILITY IDEOGRAPH-2F833;Lo;0;L;537F;;;;N;;;;;
+2F834;CJK COMPATIBILITY IDEOGRAPH-2F834;Lo;0;L;20A2C;;;;N;;;;;
+2F835;CJK COMPATIBILITY IDEOGRAPH-2F835;Lo;0;L;7070;;;;N;;;;;
+2F836;CJK COMPATIBILITY IDEOGRAPH-2F836;Lo;0;L;53CA;;;;N;;;;;
+2F837;CJK COMPATIBILITY IDEOGRAPH-2F837;Lo;0;L;53DF;;;;N;;;;;
+2F838;CJK COMPATIBILITY IDEOGRAPH-2F838;Lo;0;L;20B63;;;;N;;;;;
+2F839;CJK COMPATIBILITY IDEOGRAPH-2F839;Lo;0;L;53EB;;;;N;;;;;
+2F83A;CJK COMPATIBILITY IDEOGRAPH-2F83A;Lo;0;L;53F1;;;;N;;;;;
+2F83B;CJK COMPATIBILITY IDEOGRAPH-2F83B;Lo;0;L;5406;;;;N;;;;;
+2F83C;CJK COMPATIBILITY IDEOGRAPH-2F83C;Lo;0;L;549E;;;;N;;;;;
+2F83D;CJK COMPATIBILITY IDEOGRAPH-2F83D;Lo;0;L;5438;;;;N;;;;;
+2F83E;CJK COMPATIBILITY IDEOGRAPH-2F83E;Lo;0;L;5448;;;;N;;;;;
+2F83F;CJK COMPATIBILITY IDEOGRAPH-2F83F;Lo;0;L;5468;;;;N;;;;;
+2F840;CJK COMPATIBILITY IDEOGRAPH-2F840;Lo;0;L;54A2;;;;N;;;;;
+2F841;CJK COMPATIBILITY IDEOGRAPH-2F841;Lo;0;L;54F6;;;;N;;;;;
+2F842;CJK COMPATIBILITY IDEOGRAPH-2F842;Lo;0;L;5510;;;;N;;;;;
+2F843;CJK COMPATIBILITY IDEOGRAPH-2F843;Lo;0;L;5553;;;;N;;;;;
+2F844;CJK COMPATIBILITY IDEOGRAPH-2F844;Lo;0;L;5563;;;;N;;;;;
+2F845;CJK COMPATIBILITY IDEOGRAPH-2F845;Lo;0;L;5584;;;;N;;;;;
+2F846;CJK COMPATIBILITY IDEOGRAPH-2F846;Lo;0;L;5584;;;;N;;;;;
+2F847;CJK COMPATIBILITY IDEOGRAPH-2F847;Lo;0;L;5599;;;;N;;;;;
+2F848;CJK COMPATIBILITY IDEOGRAPH-2F848;Lo;0;L;55AB;;;;N;;;;;
+2F849;CJK COMPATIBILITY IDEOGRAPH-2F849;Lo;0;L;55B3;;;;N;;;;;
+2F84A;CJK COMPATIBILITY IDEOGRAPH-2F84A;Lo;0;L;55C2;;;;N;;;;;
+2F84B;CJK COMPATIBILITY IDEOGRAPH-2F84B;Lo;0;L;5716;;;;N;;;;;
+2F84C;CJK COMPATIBILITY IDEOGRAPH-2F84C;Lo;0;L;5606;;;;N;;;;;
+2F84D;CJK COMPATIBILITY IDEOGRAPH-2F84D;Lo;0;L;5717;;;;N;;;;;
+2F84E;CJK COMPATIBILITY IDEOGRAPH-2F84E;Lo;0;L;5651;;;;N;;;;;
+2F84F;CJK COMPATIBILITY IDEOGRAPH-2F84F;Lo;0;L;5674;;;;N;;;;;
+2F850;CJK COMPATIBILITY IDEOGRAPH-2F850;Lo;0;L;5207;;;;N;;;;;
+2F851;CJK COMPATIBILITY IDEOGRAPH-2F851;Lo;0;L;58EE;;;;N;;;;;
+2F852;CJK COMPATIBILITY IDEOGRAPH-2F852;Lo;0;L;57CE;;;;N;;;;;
+2F853;CJK COMPATIBILITY IDEOGRAPH-2F853;Lo;0;L;57F4;;;;N;;;;;
+2F854;CJK COMPATIBILITY IDEOGRAPH-2F854;Lo;0;L;580D;;;;N;;;;;
+2F855;CJK COMPATIBILITY IDEOGRAPH-2F855;Lo;0;L;578B;;;;N;;;;;
+2F856;CJK COMPATIBILITY IDEOGRAPH-2F856;Lo;0;L;5832;;;;N;;;;;
+2F857;CJK COMPATIBILITY IDEOGRAPH-2F857;Lo;0;L;5831;;;;N;;;;;
+2F858;CJK COMPATIBILITY IDEOGRAPH-2F858;Lo;0;L;58AC;;;;N;;;;;
+2F859;CJK COMPATIBILITY IDEOGRAPH-2F859;Lo;0;L;214E4;;;;N;;;;;
+2F85A;CJK COMPATIBILITY IDEOGRAPH-2F85A;Lo;0;L;58F2;;;;N;;;;;
+2F85B;CJK COMPATIBILITY IDEOGRAPH-2F85B;Lo;0;L;58F7;;;;N;;;;;
+2F85C;CJK COMPATIBILITY IDEOGRAPH-2F85C;Lo;0;L;5906;;;;N;;;;;
+2F85D;CJK COMPATIBILITY IDEOGRAPH-2F85D;Lo;0;L;591A;;;;N;;;;;
+2F85E;CJK COMPATIBILITY IDEOGRAPH-2F85E;Lo;0;L;5922;;;;N;;;;;
+2F85F;CJK COMPATIBILITY IDEOGRAPH-2F85F;Lo;0;L;5962;;;;N;;;;;
+2F860;CJK COMPATIBILITY IDEOGRAPH-2F860;Lo;0;L;216A8;;;;N;;;;;
+2F861;CJK COMPATIBILITY IDEOGRAPH-2F861;Lo;0;L;216EA;;;;N;;;;;
+2F862;CJK COMPATIBILITY IDEOGRAPH-2F862;Lo;0;L;59EC;;;;N;;;;;
+2F863;CJK COMPATIBILITY IDEOGRAPH-2F863;Lo;0;L;5A1B;;;;N;;;;;
+2F864;CJK COMPATIBILITY IDEOGRAPH-2F864;Lo;0;L;5A27;;;;N;;;;;
+2F865;CJK COMPATIBILITY IDEOGRAPH-2F865;Lo;0;L;59D8;;;;N;;;;;
+2F866;CJK COMPATIBILITY IDEOGRAPH-2F866;Lo;0;L;5A66;;;;N;;;;;
+2F867;CJK COMPATIBILITY IDEOGRAPH-2F867;Lo;0;L;36EE;;;;N;;;;;
+2F868;CJK COMPATIBILITY IDEOGRAPH-2F868;Lo;0;L;36FC;;;;N;;;;;
+2F869;CJK COMPATIBILITY IDEOGRAPH-2F869;Lo;0;L;5B08;;;;N;;;;;
+2F86A;CJK COMPATIBILITY IDEOGRAPH-2F86A;Lo;0;L;5B3E;;;;N;;;;;
+2F86B;CJK COMPATIBILITY IDEOGRAPH-2F86B;Lo;0;L;5B3E;;;;N;;;;;
+2F86C;CJK COMPATIBILITY IDEOGRAPH-2F86C;Lo;0;L;219C8;;;;N;;;;;
+2F86D;CJK COMPATIBILITY IDEOGRAPH-2F86D;Lo;0;L;5BC3;;;;N;;;;;
+2F86E;CJK COMPATIBILITY IDEOGRAPH-2F86E;Lo;0;L;5BD8;;;;N;;;;;
+2F86F;CJK COMPATIBILITY IDEOGRAPH-2F86F;Lo;0;L;5BE7;;;;N;;;;;
+2F870;CJK COMPATIBILITY IDEOGRAPH-2F870;Lo;0;L;5BF3;;;;N;;;;;
+2F871;CJK COMPATIBILITY IDEOGRAPH-2F871;Lo;0;L;21B18;;;;N;;;;;
+2F872;CJK COMPATIBILITY IDEOGRAPH-2F872;Lo;0;L;5BFF;;;;N;;;;;
+2F873;CJK COMPATIBILITY IDEOGRAPH-2F873;Lo;0;L;5C06;;;;N;;;;;
+2F874;CJK COMPATIBILITY IDEOGRAPH-2F874;Lo;0;L;5F53;;;;N;;;;;
+2F875;CJK COMPATIBILITY IDEOGRAPH-2F875;Lo;0;L;5C22;;;;N;;;;;
+2F876;CJK COMPATIBILITY IDEOGRAPH-2F876;Lo;0;L;3781;;;;N;;;;;
+2F877;CJK COMPATIBILITY IDEOGRAPH-2F877;Lo;0;L;5C60;;;;N;;;;;
+2F878;CJK COMPATIBILITY IDEOGRAPH-2F878;Lo;0;L;5C6E;;;;N;;;;;
+2F879;CJK COMPATIBILITY IDEOGRAPH-2F879;Lo;0;L;5CC0;;;;N;;;;;
+2F87A;CJK COMPATIBILITY IDEOGRAPH-2F87A;Lo;0;L;5C8D;;;;N;;;;;
+2F87B;CJK COMPATIBILITY IDEOGRAPH-2F87B;Lo;0;L;21DE4;;;;N;;;;;
+2F87C;CJK COMPATIBILITY IDEOGRAPH-2F87C;Lo;0;L;5D43;;;;N;;;;;
+2F87D;CJK COMPATIBILITY IDEOGRAPH-2F87D;Lo;0;L;21DE6;;;;N;;;;;
+2F87E;CJK COMPATIBILITY IDEOGRAPH-2F87E;Lo;0;L;5D6E;;;;N;;;;;
+2F87F;CJK COMPATIBILITY IDEOGRAPH-2F87F;Lo;0;L;5D6B;;;;N;;;;;
+2F880;CJK COMPATIBILITY IDEOGRAPH-2F880;Lo;0;L;5D7C;;;;N;;;;;
+2F881;CJK COMPATIBILITY IDEOGRAPH-2F881;Lo;0;L;5DE1;;;;N;;;;;
+2F882;CJK COMPATIBILITY IDEOGRAPH-2F882;Lo;0;L;5DE2;;;;N;;;;;
+2F883;CJK COMPATIBILITY IDEOGRAPH-2F883;Lo;0;L;382F;;;;N;;;;;
+2F884;CJK COMPATIBILITY IDEOGRAPH-2F884;Lo;0;L;5DFD;;;;N;;;;;
+2F885;CJK COMPATIBILITY IDEOGRAPH-2F885;Lo;0;L;5E28;;;;N;;;;;
+2F886;CJK COMPATIBILITY IDEOGRAPH-2F886;Lo;0;L;5E3D;;;;N;;;;;
+2F887;CJK COMPATIBILITY IDEOGRAPH-2F887;Lo;0;L;5E69;;;;N;;;;;
+2F888;CJK COMPATIBILITY IDEOGRAPH-2F888;Lo;0;L;3862;;;;N;;;;;
+2F889;CJK COMPATIBILITY IDEOGRAPH-2F889;Lo;0;L;22183;;;;N;;;;;
+2F88A;CJK COMPATIBILITY IDEOGRAPH-2F88A;Lo;0;L;387C;;;;N;;;;;
+2F88B;CJK COMPATIBILITY IDEOGRAPH-2F88B;Lo;0;L;5EB0;;;;N;;;;;
+2F88C;CJK COMPATIBILITY IDEOGRAPH-2F88C;Lo;0;L;5EB3;;;;N;;;;;
+2F88D;CJK COMPATIBILITY IDEOGRAPH-2F88D;Lo;0;L;5EB6;;;;N;;;;;
+2F88E;CJK COMPATIBILITY IDEOGRAPH-2F88E;Lo;0;L;5ECA;;;;N;;;;;
+2F88F;CJK COMPATIBILITY IDEOGRAPH-2F88F;Lo;0;L;2A392;;;;N;;;;;
+2F890;CJK COMPATIBILITY IDEOGRAPH-2F890;Lo;0;L;5EFE;;;9;N;;;;;
+2F891;CJK COMPATIBILITY IDEOGRAPH-2F891;Lo;0;L;22331;;;;N;;;;;
+2F892;CJK COMPATIBILITY IDEOGRAPH-2F892;Lo;0;L;22331;;;;N;;;;;
+2F893;CJK COMPATIBILITY IDEOGRAPH-2F893;Lo;0;L;8201;;;;N;;;;;
+2F894;CJK COMPATIBILITY IDEOGRAPH-2F894;Lo;0;L;5F22;;;;N;;;;;
+2F895;CJK COMPATIBILITY IDEOGRAPH-2F895;Lo;0;L;5F22;;;;N;;;;;
+2F896;CJK COMPATIBILITY IDEOGRAPH-2F896;Lo;0;L;38C7;;;;N;;;;;
+2F897;CJK COMPATIBILITY IDEOGRAPH-2F897;Lo;0;L;232B8;;;;N;;;;;
+2F898;CJK COMPATIBILITY IDEOGRAPH-2F898;Lo;0;L;261DA;;;;N;;;;;
+2F899;CJK COMPATIBILITY IDEOGRAPH-2F899;Lo;0;L;5F62;;;;N;;;;;
+2F89A;CJK COMPATIBILITY IDEOGRAPH-2F89A;Lo;0;L;5F6B;;;;N;;;;;
+2F89B;CJK COMPATIBILITY IDEOGRAPH-2F89B;Lo;0;L;38E3;;;;N;;;;;
+2F89C;CJK COMPATIBILITY IDEOGRAPH-2F89C;Lo;0;L;5F9A;;;;N;;;;;
+2F89D;CJK COMPATIBILITY IDEOGRAPH-2F89D;Lo;0;L;5FCD;;;;N;;;;;
+2F89E;CJK COMPATIBILITY IDEOGRAPH-2F89E;Lo;0;L;5FD7;;;;N;;;;;
+2F89F;CJK COMPATIBILITY IDEOGRAPH-2F89F;Lo;0;L;5FF9;;;;N;;;;;
+2F8A0;CJK COMPATIBILITY IDEOGRAPH-2F8A0;Lo;0;L;6081;;;;N;;;;;
+2F8A1;CJK COMPATIBILITY IDEOGRAPH-2F8A1;Lo;0;L;393A;;;;N;;;;;
+2F8A2;CJK COMPATIBILITY IDEOGRAPH-2F8A2;Lo;0;L;391C;;;;N;;;;;
+2F8A3;CJK COMPATIBILITY IDEOGRAPH-2F8A3;Lo;0;L;6094;;;;N;;;;;
+2F8A4;CJK COMPATIBILITY IDEOGRAPH-2F8A4;Lo;0;L;226D4;;;;N;;;;;
+2F8A5;CJK COMPATIBILITY IDEOGRAPH-2F8A5;Lo;0;L;60C7;;;;N;;;;;
+2F8A6;CJK COMPATIBILITY IDEOGRAPH-2F8A6;Lo;0;L;6148;;;;N;;;;;
+2F8A7;CJK COMPATIBILITY IDEOGRAPH-2F8A7;Lo;0;L;614C;;;;N;;;;;
+2F8A8;CJK COMPATIBILITY IDEOGRAPH-2F8A8;Lo;0;L;614E;;;;N;;;;;
+2F8A9;CJK COMPATIBILITY IDEOGRAPH-2F8A9;Lo;0;L;614C;;;;N;;;;;
+2F8AA;CJK COMPATIBILITY IDEOGRAPH-2F8AA;Lo;0;L;617A;;;;N;;;;;
+2F8AB;CJK COMPATIBILITY IDEOGRAPH-2F8AB;Lo;0;L;618E;;;;N;;;;;
+2F8AC;CJK COMPATIBILITY IDEOGRAPH-2F8AC;Lo;0;L;61B2;;;;N;;;;;
+2F8AD;CJK COMPATIBILITY IDEOGRAPH-2F8AD;Lo;0;L;61A4;;;;N;;;;;
+2F8AE;CJK COMPATIBILITY IDEOGRAPH-2F8AE;Lo;0;L;61AF;;;;N;;;;;
+2F8AF;CJK COMPATIBILITY IDEOGRAPH-2F8AF;Lo;0;L;61DE;;;;N;;;;;
+2F8B0;CJK COMPATIBILITY IDEOGRAPH-2F8B0;Lo;0;L;61F2;;;;N;;;;;
+2F8B1;CJK COMPATIBILITY IDEOGRAPH-2F8B1;Lo;0;L;61F6;;;;N;;;;;
+2F8B2;CJK COMPATIBILITY IDEOGRAPH-2F8B2;Lo;0;L;6210;;;;N;;;;;
+2F8B3;CJK COMPATIBILITY IDEOGRAPH-2F8B3;Lo;0;L;621B;;;;N;;;;;
+2F8B4;CJK COMPATIBILITY IDEOGRAPH-2F8B4;Lo;0;L;625D;;;;N;;;;;
+2F8B5;CJK COMPATIBILITY IDEOGRAPH-2F8B5;Lo;0;L;62B1;;;;N;;;;;
+2F8B6;CJK COMPATIBILITY IDEOGRAPH-2F8B6;Lo;0;L;62D4;;;;N;;;;;
+2F8B7;CJK COMPATIBILITY IDEOGRAPH-2F8B7;Lo;0;L;6350;;;;N;;;;;
+2F8B8;CJK COMPATIBILITY IDEOGRAPH-2F8B8;Lo;0;L;22B0C;;;;N;;;;;
+2F8B9;CJK COMPATIBILITY IDEOGRAPH-2F8B9;Lo;0;L;633D;;;;N;;;;;
+2F8BA;CJK COMPATIBILITY IDEOGRAPH-2F8BA;Lo;0;L;62FC;;;;N;;;;;
+2F8BB;CJK COMPATIBILITY IDEOGRAPH-2F8BB;Lo;0;L;6368;;;;N;;;;;
+2F8BC;CJK COMPATIBILITY IDEOGRAPH-2F8BC;Lo;0;L;6383;;;;N;;;;;
+2F8BD;CJK COMPATIBILITY IDEOGRAPH-2F8BD;Lo;0;L;63E4;;;;N;;;;;
+2F8BE;CJK COMPATIBILITY IDEOGRAPH-2F8BE;Lo;0;L;22BF1;;;;N;;;;;
+2F8BF;CJK COMPATIBILITY IDEOGRAPH-2F8BF;Lo;0;L;6422;;;;N;;;;;
+2F8C0;CJK COMPATIBILITY IDEOGRAPH-2F8C0;Lo;0;L;63C5;;;;N;;;;;
+2F8C1;CJK COMPATIBILITY IDEOGRAPH-2F8C1;Lo;0;L;63A9;;;;N;;;;;
+2F8C2;CJK COMPATIBILITY IDEOGRAPH-2F8C2;Lo;0;L;3A2E;;;;N;;;;;
+2F8C3;CJK COMPATIBILITY IDEOGRAPH-2F8C3;Lo;0;L;6469;;;;N;;;;;
+2F8C4;CJK COMPATIBILITY IDEOGRAPH-2F8C4;Lo;0;L;647E;;;;N;;;;;
+2F8C5;CJK COMPATIBILITY IDEOGRAPH-2F8C5;Lo;0;L;649D;;;;N;;;;;
+2F8C6;CJK COMPATIBILITY IDEOGRAPH-2F8C6;Lo;0;L;6477;;;;N;;;;;
+2F8C7;CJK COMPATIBILITY IDEOGRAPH-2F8C7;Lo;0;L;3A6C;;;;N;;;;;
+2F8C8;CJK COMPATIBILITY IDEOGRAPH-2F8C8;Lo;0;L;654F;;;;N;;;;;
+2F8C9;CJK COMPATIBILITY IDEOGRAPH-2F8C9;Lo;0;L;656C;;;;N;;;;;
+2F8CA;CJK COMPATIBILITY IDEOGRAPH-2F8CA;Lo;0;L;2300A;;;;N;;;;;
+2F8CB;CJK COMPATIBILITY IDEOGRAPH-2F8CB;Lo;0;L;65E3;;;;N;;;;;
+2F8CC;CJK COMPATIBILITY IDEOGRAPH-2F8CC;Lo;0;L;66F8;;;;N;;;;;
+2F8CD;CJK COMPATIBILITY IDEOGRAPH-2F8CD;Lo;0;L;6649;;;;N;;;;;
+2F8CE;CJK COMPATIBILITY IDEOGRAPH-2F8CE;Lo;0;L;3B19;;;;N;;;;;
+2F8CF;CJK COMPATIBILITY IDEOGRAPH-2F8CF;Lo;0;L;6691;;;;N;;;;;
+2F8D0;CJK COMPATIBILITY IDEOGRAPH-2F8D0;Lo;0;L;3B08;;;;N;;;;;
+2F8D1;CJK COMPATIBILITY IDEOGRAPH-2F8D1;Lo;0;L;3AE4;;;;N;;;;;
+2F8D2;CJK COMPATIBILITY IDEOGRAPH-2F8D2;Lo;0;L;5192;;;;N;;;;;
+2F8D3;CJK COMPATIBILITY IDEOGRAPH-2F8D3;Lo;0;L;5195;;;;N;;;;;
+2F8D4;CJK COMPATIBILITY IDEOGRAPH-2F8D4;Lo;0;L;6700;;;;N;;;;;
+2F8D5;CJK COMPATIBILITY IDEOGRAPH-2F8D5;Lo;0;L;669C;;;;N;;;;;
+2F8D6;CJK COMPATIBILITY IDEOGRAPH-2F8D6;Lo;0;L;80AD;;;;N;;;;;
+2F8D7;CJK COMPATIBILITY IDEOGRAPH-2F8D7;Lo;0;L;43D9;;;;N;;;;;
+2F8D8;CJK COMPATIBILITY IDEOGRAPH-2F8D8;Lo;0;L;6717;;;;N;;;;;
+2F8D9;CJK COMPATIBILITY IDEOGRAPH-2F8D9;Lo;0;L;671B;;;;N;;;;;
+2F8DA;CJK COMPATIBILITY IDEOGRAPH-2F8DA;Lo;0;L;6721;;;;N;;;;;
+2F8DB;CJK COMPATIBILITY IDEOGRAPH-2F8DB;Lo;0;L;675E;;;;N;;;;;
+2F8DC;CJK COMPATIBILITY IDEOGRAPH-2F8DC;Lo;0;L;6753;;;;N;;;;;
+2F8DD;CJK COMPATIBILITY IDEOGRAPH-2F8DD;Lo;0;L;233C3;;;;N;;;;;
+2F8DE;CJK COMPATIBILITY IDEOGRAPH-2F8DE;Lo;0;L;3B49;;;;N;;;;;
+2F8DF;CJK COMPATIBILITY IDEOGRAPH-2F8DF;Lo;0;L;67FA;;;;N;;;;;
+2F8E0;CJK COMPATIBILITY IDEOGRAPH-2F8E0;Lo;0;L;6785;;;;N;;;;;
+2F8E1;CJK COMPATIBILITY IDEOGRAPH-2F8E1;Lo;0;L;6852;;;;N;;;;;
+2F8E2;CJK COMPATIBILITY IDEOGRAPH-2F8E2;Lo;0;L;6885;;;;N;;;;;
+2F8E3;CJK COMPATIBILITY IDEOGRAPH-2F8E3;Lo;0;L;2346D;;;;N;;;;;
+2F8E4;CJK COMPATIBILITY IDEOGRAPH-2F8E4;Lo;0;L;688E;;;;N;;;;;
+2F8E5;CJK COMPATIBILITY IDEOGRAPH-2F8E5;Lo;0;L;681F;;;;N;;;;;
+2F8E6;CJK COMPATIBILITY IDEOGRAPH-2F8E6;Lo;0;L;6914;;;;N;;;;;
+2F8E7;CJK COMPATIBILITY IDEOGRAPH-2F8E7;Lo;0;L;3B9D;;;;N;;;;;
+2F8E8;CJK COMPATIBILITY IDEOGRAPH-2F8E8;Lo;0;L;6942;;;;N;;;;;
+2F8E9;CJK COMPATIBILITY IDEOGRAPH-2F8E9;Lo;0;L;69A3;;;;N;;;;;
+2F8EA;CJK COMPATIBILITY IDEOGRAPH-2F8EA;Lo;0;L;69EA;;;;N;;;;;
+2F8EB;CJK COMPATIBILITY IDEOGRAPH-2F8EB;Lo;0;L;6AA8;;;;N;;;;;
+2F8EC;CJK COMPATIBILITY IDEOGRAPH-2F8EC;Lo;0;L;236A3;;;;N;;;;;
+2F8ED;CJK COMPATIBILITY IDEOGRAPH-2F8ED;Lo;0;L;6ADB;;;;N;;;;;
+2F8EE;CJK COMPATIBILITY IDEOGRAPH-2F8EE;Lo;0;L;3C18;;;;N;;;;;
+2F8EF;CJK COMPATIBILITY IDEOGRAPH-2F8EF;Lo;0;L;6B21;;;;N;;;;;
+2F8F0;CJK COMPATIBILITY IDEOGRAPH-2F8F0;Lo;0;L;238A7;;;;N;;;;;
+2F8F1;CJK COMPATIBILITY IDEOGRAPH-2F8F1;Lo;0;L;6B54;;;;N;;;;;
+2F8F2;CJK COMPATIBILITY IDEOGRAPH-2F8F2;Lo;0;L;3C4E;;;;N;;;;;
+2F8F3;CJK COMPATIBILITY IDEOGRAPH-2F8F3;Lo;0;L;6B72;;;;N;;;;;
+2F8F4;CJK COMPATIBILITY IDEOGRAPH-2F8F4;Lo;0;L;6B9F;;;;N;;;;;
+2F8F5;CJK COMPATIBILITY IDEOGRAPH-2F8F5;Lo;0;L;6BBA;;;;N;;;;;
+2F8F6;CJK COMPATIBILITY IDEOGRAPH-2F8F6;Lo;0;L;6BBB;;;;N;;;;;
+2F8F7;CJK COMPATIBILITY IDEOGRAPH-2F8F7;Lo;0;L;23A8D;;;;N;;;;;
+2F8F8;CJK COMPATIBILITY IDEOGRAPH-2F8F8;Lo;0;L;21D0B;;;;N;;;;;
+2F8F9;CJK COMPATIBILITY IDEOGRAPH-2F8F9;Lo;0;L;23AFA;;;;N;;;;;
+2F8FA;CJK COMPATIBILITY IDEOGRAPH-2F8FA;Lo;0;L;6C4E;;;;N;;;;;
+2F8FB;CJK COMPATIBILITY IDEOGRAPH-2F8FB;Lo;0;L;23CBC;;;;N;;;;;
+2F8FC;CJK COMPATIBILITY IDEOGRAPH-2F8FC;Lo;0;L;6CBF;;;;N;;;;;
+2F8FD;CJK COMPATIBILITY IDEOGRAPH-2F8FD;Lo;0;L;6CCD;;;;N;;;;;
+2F8FE;CJK COMPATIBILITY IDEOGRAPH-2F8FE;Lo;0;L;6C67;;;;N;;;;;
+2F8FF;CJK COMPATIBILITY IDEOGRAPH-2F8FF;Lo;0;L;6D16;;;;N;;;;;
+2F900;CJK COMPATIBILITY IDEOGRAPH-2F900;Lo;0;L;6D3E;;;;N;;;;;
+2F901;CJK COMPATIBILITY IDEOGRAPH-2F901;Lo;0;L;6D77;;;;N;;;;;
+2F902;CJK COMPATIBILITY IDEOGRAPH-2F902;Lo;0;L;6D41;;;;N;;;;;
+2F903;CJK COMPATIBILITY IDEOGRAPH-2F903;Lo;0;L;6D69;;;;N;;;;;
+2F904;CJK COMPATIBILITY IDEOGRAPH-2F904;Lo;0;L;6D78;;;;N;;;;;
+2F905;CJK COMPATIBILITY IDEOGRAPH-2F905;Lo;0;L;6D85;;;;N;;;;;
+2F906;CJK COMPATIBILITY IDEOGRAPH-2F906;Lo;0;L;23D1E;;;;N;;;;;
+2F907;CJK COMPATIBILITY IDEOGRAPH-2F907;Lo;0;L;6D34;;;;N;;;;;
+2F908;CJK COMPATIBILITY IDEOGRAPH-2F908;Lo;0;L;6E2F;;;;N;;;;;
+2F909;CJK COMPATIBILITY IDEOGRAPH-2F909;Lo;0;L;6E6E;;;;N;;;;;
+2F90A;CJK COMPATIBILITY IDEOGRAPH-2F90A;Lo;0;L;3D33;;;;N;;;;;
+2F90B;CJK COMPATIBILITY IDEOGRAPH-2F90B;Lo;0;L;6ECB;;;;N;;;;;
+2F90C;CJK COMPATIBILITY IDEOGRAPH-2F90C;Lo;0;L;6EC7;;;;N;;;;;
+2F90D;CJK COMPATIBILITY IDEOGRAPH-2F90D;Lo;0;L;23ED1;;;;N;;;;;
+2F90E;CJK COMPATIBILITY IDEOGRAPH-2F90E;Lo;0;L;6DF9;;;;N;;;;;
+2F90F;CJK COMPATIBILITY IDEOGRAPH-2F90F;Lo;0;L;6F6E;;;;N;;;;;
+2F910;CJK COMPATIBILITY IDEOGRAPH-2F910;Lo;0;L;23F5E;;;;N;;;;;
+2F911;CJK COMPATIBILITY IDEOGRAPH-2F911;Lo;0;L;23F8E;;;;N;;;;;
+2F912;CJK COMPATIBILITY IDEOGRAPH-2F912;Lo;0;L;6FC6;;;;N;;;;;
+2F913;CJK COMPATIBILITY IDEOGRAPH-2F913;Lo;0;L;7039;;;;N;;;;;
+2F914;CJK COMPATIBILITY IDEOGRAPH-2F914;Lo;0;L;701E;;;;N;;;;;
+2F915;CJK COMPATIBILITY IDEOGRAPH-2F915;Lo;0;L;701B;;;;N;;;;;
+2F916;CJK COMPATIBILITY IDEOGRAPH-2F916;Lo;0;L;3D96;;;;N;;;;;
+2F917;CJK COMPATIBILITY IDEOGRAPH-2F917;Lo;0;L;704A;;;;N;;;;;
+2F918;CJK COMPATIBILITY IDEOGRAPH-2F918;Lo;0;L;707D;;;;N;;;;;
+2F919;CJK COMPATIBILITY IDEOGRAPH-2F919;Lo;0;L;7077;;;;N;;;;;
+2F91A;CJK COMPATIBILITY IDEOGRAPH-2F91A;Lo;0;L;70AD;;;;N;;;;;
+2F91B;CJK COMPATIBILITY IDEOGRAPH-2F91B;Lo;0;L;20525;;;;N;;;;;
+2F91C;CJK COMPATIBILITY IDEOGRAPH-2F91C;Lo;0;L;7145;;;;N;;;;;
+2F91D;CJK COMPATIBILITY IDEOGRAPH-2F91D;Lo;0;L;24263;;;;N;;;;;
+2F91E;CJK COMPATIBILITY IDEOGRAPH-2F91E;Lo;0;L;719C;;;;N;;;;;
+2F91F;CJK COMPATIBILITY IDEOGRAPH-2F91F;Lo;0;L;243AB;;;;N;;;;;
+2F920;CJK COMPATIBILITY IDEOGRAPH-2F920;Lo;0;L;7228;;;;N;;;;;
+2F921;CJK COMPATIBILITY IDEOGRAPH-2F921;Lo;0;L;7235;;;;N;;;;;
+2F922;CJK COMPATIBILITY IDEOGRAPH-2F922;Lo;0;L;7250;;;;N;;;;;
+2F923;CJK COMPATIBILITY IDEOGRAPH-2F923;Lo;0;L;24608;;;;N;;;;;
+2F924;CJK COMPATIBILITY IDEOGRAPH-2F924;Lo;0;L;7280;;;;N;;;;;
+2F925;CJK COMPATIBILITY IDEOGRAPH-2F925;Lo;0;L;7295;;;;N;;;;;
+2F926;CJK COMPATIBILITY IDEOGRAPH-2F926;Lo;0;L;24735;;;;N;;;;;
+2F927;CJK COMPATIBILITY IDEOGRAPH-2F927;Lo;0;L;24814;;;;N;;;;;
+2F928;CJK COMPATIBILITY IDEOGRAPH-2F928;Lo;0;L;737A;;;;N;;;;;
+2F929;CJK COMPATIBILITY IDEOGRAPH-2F929;Lo;0;L;738B;;;;N;;;;;
+2F92A;CJK COMPATIBILITY IDEOGRAPH-2F92A;Lo;0;L;3EAC;;;;N;;;;;
+2F92B;CJK COMPATIBILITY IDEOGRAPH-2F92B;Lo;0;L;73A5;;;;N;;;;;
+2F92C;CJK COMPATIBILITY IDEOGRAPH-2F92C;Lo;0;L;3EB8;;;;N;;;;;
+2F92D;CJK COMPATIBILITY IDEOGRAPH-2F92D;Lo;0;L;3EB8;;;;N;;;;;
+2F92E;CJK COMPATIBILITY IDEOGRAPH-2F92E;Lo;0;L;7447;;;;N;;;;;
+2F92F;CJK COMPATIBILITY IDEOGRAPH-2F92F;Lo;0;L;745C;;;;N;;;;;
+2F930;CJK COMPATIBILITY IDEOGRAPH-2F930;Lo;0;L;7471;;;;N;;;;;
+2F931;CJK COMPATIBILITY IDEOGRAPH-2F931;Lo;0;L;7485;;;;N;;;;;
+2F932;CJK COMPATIBILITY IDEOGRAPH-2F932;Lo;0;L;74CA;;;;N;;;;;
+2F933;CJK COMPATIBILITY IDEOGRAPH-2F933;Lo;0;L;3F1B;;;;N;;;;;
+2F934;CJK COMPATIBILITY IDEOGRAPH-2F934;Lo;0;L;7524;;;;N;;;;;
+2F935;CJK COMPATIBILITY IDEOGRAPH-2F935;Lo;0;L;24C36;;;;N;;;;;
+2F936;CJK COMPATIBILITY IDEOGRAPH-2F936;Lo;0;L;753E;;;;N;;;;;
+2F937;CJK COMPATIBILITY IDEOGRAPH-2F937;Lo;0;L;24C92;;;;N;;;;;
+2F938;CJK COMPATIBILITY IDEOGRAPH-2F938;Lo;0;L;7570;;;;N;;;;;
+2F939;CJK COMPATIBILITY IDEOGRAPH-2F939;Lo;0;L;2219F;;;;N;;;;;
+2F93A;CJK COMPATIBILITY IDEOGRAPH-2F93A;Lo;0;L;7610;;;;N;;;;;
+2F93B;CJK COMPATIBILITY IDEOGRAPH-2F93B;Lo;0;L;24FA1;;;;N;;;;;
+2F93C;CJK COMPATIBILITY IDEOGRAPH-2F93C;Lo;0;L;24FB8;;;;N;;;;;
+2F93D;CJK COMPATIBILITY IDEOGRAPH-2F93D;Lo;0;L;25044;;;;N;;;;;
+2F93E;CJK COMPATIBILITY IDEOGRAPH-2F93E;Lo;0;L;3FFC;;;;N;;;;;
+2F93F;CJK COMPATIBILITY IDEOGRAPH-2F93F;Lo;0;L;4008;;;;N;;;;;
+2F940;CJK COMPATIBILITY IDEOGRAPH-2F940;Lo;0;L;76F4;;;;N;;;;;
+2F941;CJK COMPATIBILITY IDEOGRAPH-2F941;Lo;0;L;250F3;;;;N;;;;;
+2F942;CJK COMPATIBILITY IDEOGRAPH-2F942;Lo;0;L;250F2;;;;N;;;;;
+2F943;CJK COMPATIBILITY IDEOGRAPH-2F943;Lo;0;L;25119;;;;N;;;;;
+2F944;CJK COMPATIBILITY IDEOGRAPH-2F944;Lo;0;L;25133;;;;N;;;;;
+2F945;CJK COMPATIBILITY IDEOGRAPH-2F945;Lo;0;L;771E;;;;N;;;;;
+2F946;CJK COMPATIBILITY IDEOGRAPH-2F946;Lo;0;L;771F;;;;N;;;;;
+2F947;CJK COMPATIBILITY IDEOGRAPH-2F947;Lo;0;L;771F;;;;N;;;;;
+2F948;CJK COMPATIBILITY IDEOGRAPH-2F948;Lo;0;L;774A;;;;N;;;;;
+2F949;CJK COMPATIBILITY IDEOGRAPH-2F949;Lo;0;L;4039;;;;N;;;;;
+2F94A;CJK COMPATIBILITY IDEOGRAPH-2F94A;Lo;0;L;778B;;;;N;;;;;
+2F94B;CJK COMPATIBILITY IDEOGRAPH-2F94B;Lo;0;L;4046;;;;N;;;;;
+2F94C;CJK COMPATIBILITY IDEOGRAPH-2F94C;Lo;0;L;4096;;;;N;;;;;
+2F94D;CJK COMPATIBILITY IDEOGRAPH-2F94D;Lo;0;L;2541D;;;;N;;;;;
+2F94E;CJK COMPATIBILITY IDEOGRAPH-2F94E;Lo;0;L;784E;;;;N;;;;;
+2F94F;CJK COMPATIBILITY IDEOGRAPH-2F94F;Lo;0;L;788C;;;;N;;;;;
+2F950;CJK COMPATIBILITY IDEOGRAPH-2F950;Lo;0;L;78CC;;;;N;;;;;
+2F951;CJK COMPATIBILITY IDEOGRAPH-2F951;Lo;0;L;40E3;;;;N;;;;;
+2F952;CJK COMPATIBILITY IDEOGRAPH-2F952;Lo;0;L;25626;;;;N;;;;;
+2F953;CJK COMPATIBILITY IDEOGRAPH-2F953;Lo;0;L;7956;;;;N;;;;;
+2F954;CJK COMPATIBILITY IDEOGRAPH-2F954;Lo;0;L;2569A;;;;N;;;;;
+2F955;CJK COMPATIBILITY IDEOGRAPH-2F955;Lo;0;L;256C5;;;;N;;;;;
+2F956;CJK COMPATIBILITY IDEOGRAPH-2F956;Lo;0;L;798F;;;;N;;;;;
+2F957;CJK COMPATIBILITY IDEOGRAPH-2F957;Lo;0;L;79EB;;;;N;;;;;
+2F958;CJK COMPATIBILITY IDEOGRAPH-2F958;Lo;0;L;412F;;;;N;;;;;
+2F959;CJK COMPATIBILITY IDEOGRAPH-2F959;Lo;0;L;7A40;;;;N;;;;;
+2F95A;CJK COMPATIBILITY IDEOGRAPH-2F95A;Lo;0;L;7A4A;;;;N;;;;;
+2F95B;CJK COMPATIBILITY IDEOGRAPH-2F95B;Lo;0;L;7A4F;;;;N;;;;;
+2F95C;CJK COMPATIBILITY IDEOGRAPH-2F95C;Lo;0;L;2597C;;;;N;;;;;
+2F95D;CJK COMPATIBILITY IDEOGRAPH-2F95D;Lo;0;L;25AA7;;;;N;;;;;
+2F95E;CJK COMPATIBILITY IDEOGRAPH-2F95E;Lo;0;L;25AA7;;;;N;;;;;
+2F95F;CJK COMPATIBILITY IDEOGRAPH-2F95F;Lo;0;L;7AEE;;;;N;;;;;
+2F960;CJK COMPATIBILITY IDEOGRAPH-2F960;Lo;0;L;4202;;;;N;;;;;
+2F961;CJK COMPATIBILITY IDEOGRAPH-2F961;Lo;0;L;25BAB;;;;N;;;;;
+2F962;CJK COMPATIBILITY IDEOGRAPH-2F962;Lo;0;L;7BC6;;;;N;;;;;
+2F963;CJK COMPATIBILITY IDEOGRAPH-2F963;Lo;0;L;7BC9;;;;N;;;;;
+2F964;CJK COMPATIBILITY IDEOGRAPH-2F964;Lo;0;L;4227;;;;N;;;;;
+2F965;CJK COMPATIBILITY IDEOGRAPH-2F965;Lo;0;L;25C80;;;;N;;;;;
+2F966;CJK COMPATIBILITY IDEOGRAPH-2F966;Lo;0;L;7CD2;;;;N;;;;;
+2F967;CJK COMPATIBILITY IDEOGRAPH-2F967;Lo;0;L;42A0;;;;N;;;;;
+2F968;CJK COMPATIBILITY IDEOGRAPH-2F968;Lo;0;L;7CE8;;;;N;;;;;
+2F969;CJK COMPATIBILITY IDEOGRAPH-2F969;Lo;0;L;7CE3;;;;N;;;;;
+2F96A;CJK COMPATIBILITY IDEOGRAPH-2F96A;Lo;0;L;7D00;;;;N;;;;;
+2F96B;CJK COMPATIBILITY IDEOGRAPH-2F96B;Lo;0;L;25F86;;;;N;;;;;
+2F96C;CJK COMPATIBILITY IDEOGRAPH-2F96C;Lo;0;L;7D63;;;;N;;;;;
+2F96D;CJK COMPATIBILITY IDEOGRAPH-2F96D;Lo;0;L;4301;;;;N;;;;;
+2F96E;CJK COMPATIBILITY IDEOGRAPH-2F96E;Lo;0;L;7DC7;;;;N;;;;;
+2F96F;CJK COMPATIBILITY IDEOGRAPH-2F96F;Lo;0;L;7E02;;;;N;;;;;
+2F970;CJK COMPATIBILITY IDEOGRAPH-2F970;Lo;0;L;7E45;;;;N;;;;;
+2F971;CJK COMPATIBILITY IDEOGRAPH-2F971;Lo;0;L;4334;;;;N;;;;;
+2F972;CJK COMPATIBILITY IDEOGRAPH-2F972;Lo;0;L;26228;;;;N;;;;;
+2F973;CJK COMPATIBILITY IDEOGRAPH-2F973;Lo;0;L;26247;;;;N;;;;;
+2F974;CJK COMPATIBILITY IDEOGRAPH-2F974;Lo;0;L;4359;;;;N;;;;;
+2F975;CJK COMPATIBILITY IDEOGRAPH-2F975;Lo;0;L;262D9;;;;N;;;;;
+2F976;CJK COMPATIBILITY IDEOGRAPH-2F976;Lo;0;L;7F7A;;;;N;;;;;
+2F977;CJK COMPATIBILITY IDEOGRAPH-2F977;Lo;0;L;2633E;;;;N;;;;;
+2F978;CJK COMPATIBILITY IDEOGRAPH-2F978;Lo;0;L;7F95;;;;N;;;;;
+2F979;CJK COMPATIBILITY IDEOGRAPH-2F979;Lo;0;L;7FFA;;;;N;;;;;
+2F97A;CJK COMPATIBILITY IDEOGRAPH-2F97A;Lo;0;L;8005;;;;N;;;;;
+2F97B;CJK COMPATIBILITY IDEOGRAPH-2F97B;Lo;0;L;264DA;;;;N;;;;;
+2F97C;CJK COMPATIBILITY IDEOGRAPH-2F97C;Lo;0;L;26523;;;;N;;;;;
+2F97D;CJK COMPATIBILITY IDEOGRAPH-2F97D;Lo;0;L;8060;;;;N;;;;;
+2F97E;CJK COMPATIBILITY IDEOGRAPH-2F97E;Lo;0;L;265A8;;;;N;;;;;
+2F97F;CJK COMPATIBILITY IDEOGRAPH-2F97F;Lo;0;L;8070;;;;N;;;;;
+2F980;CJK COMPATIBILITY IDEOGRAPH-2F980;Lo;0;L;2335F;;;;N;;;;;
+2F981;CJK COMPATIBILITY IDEOGRAPH-2F981;Lo;0;L;43D5;;;;N;;;;;
+2F982;CJK COMPATIBILITY IDEOGRAPH-2F982;Lo;0;L;80B2;;;;N;;;;;
+2F983;CJK COMPATIBILITY IDEOGRAPH-2F983;Lo;0;L;8103;;;;N;;;;;
+2F984;CJK COMPATIBILITY IDEOGRAPH-2F984;Lo;0;L;440B;;;;N;;;;;
+2F985;CJK COMPATIBILITY IDEOGRAPH-2F985;Lo;0;L;813E;;;;N;;;;;
+2F986;CJK COMPATIBILITY IDEOGRAPH-2F986;Lo;0;L;5AB5;;;;N;;;;;
+2F987;CJK COMPATIBILITY IDEOGRAPH-2F987;Lo;0;L;267A7;;;;N;;;;;
+2F988;CJK COMPATIBILITY IDEOGRAPH-2F988;Lo;0;L;267B5;;;;N;;;;;
+2F989;CJK COMPATIBILITY IDEOGRAPH-2F989;Lo;0;L;23393;;;;N;;;;;
+2F98A;CJK COMPATIBILITY IDEOGRAPH-2F98A;Lo;0;L;2339C;;;;N;;;;;
+2F98B;CJK COMPATIBILITY IDEOGRAPH-2F98B;Lo;0;L;8201;;;;N;;;;;
+2F98C;CJK COMPATIBILITY IDEOGRAPH-2F98C;Lo;0;L;8204;;;;N;;;;;
+2F98D;CJK COMPATIBILITY IDEOGRAPH-2F98D;Lo;0;L;8F9E;;;;N;;;;;
+2F98E;CJK COMPATIBILITY IDEOGRAPH-2F98E;Lo;0;L;446B;;;;N;;;;;
+2F98F;CJK COMPATIBILITY IDEOGRAPH-2F98F;Lo;0;L;8291;;;;N;;;;;
+2F990;CJK COMPATIBILITY IDEOGRAPH-2F990;Lo;0;L;828B;;;;N;;;;;
+2F991;CJK COMPATIBILITY IDEOGRAPH-2F991;Lo;0;L;829D;;;;N;;;;;
+2F992;CJK COMPATIBILITY IDEOGRAPH-2F992;Lo;0;L;52B3;;;;N;;;;;
+2F993;CJK COMPATIBILITY IDEOGRAPH-2F993;Lo;0;L;82B1;;;;N;;;;;
+2F994;CJK COMPATIBILITY IDEOGRAPH-2F994;Lo;0;L;82B3;;;;N;;;;;
+2F995;CJK COMPATIBILITY IDEOGRAPH-2F995;Lo;0;L;82BD;;;;N;;;;;
+2F996;CJK COMPATIBILITY IDEOGRAPH-2F996;Lo;0;L;82E6;;;;N;;;;;
+2F997;CJK COMPATIBILITY IDEOGRAPH-2F997;Lo;0;L;26B3C;;;;N;;;;;
+2F998;CJK COMPATIBILITY IDEOGRAPH-2F998;Lo;0;L;82E5;;;;N;;;;;
+2F999;CJK COMPATIBILITY IDEOGRAPH-2F999;Lo;0;L;831D;;;;N;;;;;
+2F99A;CJK COMPATIBILITY IDEOGRAPH-2F99A;Lo;0;L;8363;;;;N;;;;;
+2F99B;CJK COMPATIBILITY IDEOGRAPH-2F99B;Lo;0;L;83AD;;;;N;;;;;
+2F99C;CJK COMPATIBILITY IDEOGRAPH-2F99C;Lo;0;L;8323;;;;N;;;;;
+2F99D;CJK COMPATIBILITY IDEOGRAPH-2F99D;Lo;0;L;83BD;;;;N;;;;;
+2F99E;CJK COMPATIBILITY IDEOGRAPH-2F99E;Lo;0;L;83E7;;;;N;;;;;
+2F99F;CJK COMPATIBILITY IDEOGRAPH-2F99F;Lo;0;L;8457;;;;N;;;;;
+2F9A0;CJK COMPATIBILITY IDEOGRAPH-2F9A0;Lo;0;L;8353;;;;N;;;;;
+2F9A1;CJK COMPATIBILITY IDEOGRAPH-2F9A1;Lo;0;L;83CA;;;;N;;;;;
+2F9A2;CJK COMPATIBILITY IDEOGRAPH-2F9A2;Lo;0;L;83CC;;;;N;;;;;
+2F9A3;CJK COMPATIBILITY IDEOGRAPH-2F9A3;Lo;0;L;83DC;;;;N;;;;;
+2F9A4;CJK COMPATIBILITY IDEOGRAPH-2F9A4;Lo;0;L;26C36;;;;N;;;;;
+2F9A5;CJK COMPATIBILITY IDEOGRAPH-2F9A5;Lo;0;L;26D6B;;;;N;;;;;
+2F9A6;CJK COMPATIBILITY IDEOGRAPH-2F9A6;Lo;0;L;26CD5;;;;N;;;;;
+2F9A7;CJK COMPATIBILITY IDEOGRAPH-2F9A7;Lo;0;L;452B;;;;N;;;;;
+2F9A8;CJK COMPATIBILITY IDEOGRAPH-2F9A8;Lo;0;L;84F1;;;;N;;;;;
+2F9A9;CJK COMPATIBILITY IDEOGRAPH-2F9A9;Lo;0;L;84F3;;;;N;;;;;
+2F9AA;CJK COMPATIBILITY IDEOGRAPH-2F9AA;Lo;0;L;8516;;;;N;;;;;
+2F9AB;CJK COMPATIBILITY IDEOGRAPH-2F9AB;Lo;0;L;273CA;;;;N;;;;;
+2F9AC;CJK COMPATIBILITY IDEOGRAPH-2F9AC;Lo;0;L;8564;;;;N;;;;;
+2F9AD;CJK COMPATIBILITY IDEOGRAPH-2F9AD;Lo;0;L;26F2C;;;;N;;;;;
+2F9AE;CJK COMPATIBILITY IDEOGRAPH-2F9AE;Lo;0;L;455D;;;;N;;;;;
+2F9AF;CJK COMPATIBILITY IDEOGRAPH-2F9AF;Lo;0;L;4561;;;;N;;;;;
+2F9B0;CJK COMPATIBILITY IDEOGRAPH-2F9B0;Lo;0;L;26FB1;;;;N;;;;;
+2F9B1;CJK COMPATIBILITY IDEOGRAPH-2F9B1;Lo;0;L;270D2;;;;N;;;;;
+2F9B2;CJK COMPATIBILITY IDEOGRAPH-2F9B2;Lo;0;L;456B;;;;N;;;;;
+2F9B3;CJK COMPATIBILITY IDEOGRAPH-2F9B3;Lo;0;L;8650;;;;N;;;;;
+2F9B4;CJK COMPATIBILITY IDEOGRAPH-2F9B4;Lo;0;L;865C;;;;N;;;;;
+2F9B5;CJK COMPATIBILITY IDEOGRAPH-2F9B5;Lo;0;L;8667;;;;N;;;;;
+2F9B6;CJK COMPATIBILITY IDEOGRAPH-2F9B6;Lo;0;L;8669;;;;N;;;;;
+2F9B7;CJK COMPATIBILITY IDEOGRAPH-2F9B7;Lo;0;L;86A9;;;;N;;;;;
+2F9B8;CJK COMPATIBILITY IDEOGRAPH-2F9B8;Lo;0;L;8688;;;;N;;;;;
+2F9B9;CJK COMPATIBILITY IDEOGRAPH-2F9B9;Lo;0;L;870E;;;;N;;;;;
+2F9BA;CJK COMPATIBILITY IDEOGRAPH-2F9BA;Lo;0;L;86E2;;;;N;;;;;
+2F9BB;CJK COMPATIBILITY IDEOGRAPH-2F9BB;Lo;0;L;8779;;;;N;;;;;
+2F9BC;CJK COMPATIBILITY IDEOGRAPH-2F9BC;Lo;0;L;8728;;;;N;;;;;
+2F9BD;CJK COMPATIBILITY IDEOGRAPH-2F9BD;Lo;0;L;876B;;;;N;;;;;
+2F9BE;CJK COMPATIBILITY IDEOGRAPH-2F9BE;Lo;0;L;8786;;;;N;;;;;
+2F9BF;CJK COMPATIBILITY IDEOGRAPH-2F9BF;Lo;0;L;45D7;;;;N;;;;;
+2F9C0;CJK COMPATIBILITY IDEOGRAPH-2F9C0;Lo;0;L;87E1;;;;N;;;;;
+2F9C1;CJK COMPATIBILITY IDEOGRAPH-2F9C1;Lo;0;L;8801;;;;N;;;;;
+2F9C2;CJK COMPATIBILITY IDEOGRAPH-2F9C2;Lo;0;L;45F9;;;;N;;;;;
+2F9C3;CJK COMPATIBILITY IDEOGRAPH-2F9C3;Lo;0;L;8860;;;;N;;;;;
+2F9C4;CJK COMPATIBILITY IDEOGRAPH-2F9C4;Lo;0;L;8863;;;;N;;;;;
+2F9C5;CJK COMPATIBILITY IDEOGRAPH-2F9C5;Lo;0;L;27667;;;;N;;;;;
+2F9C6;CJK COMPATIBILITY IDEOGRAPH-2F9C6;Lo;0;L;88D7;;;;N;;;;;
+2F9C7;CJK COMPATIBILITY IDEOGRAPH-2F9C7;Lo;0;L;88DE;;;;N;;;;;
+2F9C8;CJK COMPATIBILITY IDEOGRAPH-2F9C8;Lo;0;L;4635;;;;N;;;;;
+2F9C9;CJK COMPATIBILITY IDEOGRAPH-2F9C9;Lo;0;L;88FA;;;;N;;;;;
+2F9CA;CJK COMPATIBILITY IDEOGRAPH-2F9CA;Lo;0;L;34BB;;;;N;;;;;
+2F9CB;CJK COMPATIBILITY IDEOGRAPH-2F9CB;Lo;0;L;278AE;;;;N;;;;;
+2F9CC;CJK COMPATIBILITY IDEOGRAPH-2F9CC;Lo;0;L;27966;;;;N;;;;;
+2F9CD;CJK COMPATIBILITY IDEOGRAPH-2F9CD;Lo;0;L;46BE;;;;N;;;;;
+2F9CE;CJK COMPATIBILITY IDEOGRAPH-2F9CE;Lo;0;L;46C7;;;;N;;;;;
+2F9CF;CJK COMPATIBILITY IDEOGRAPH-2F9CF;Lo;0;L;8AA0;;;;N;;;;;
+2F9D0;CJK COMPATIBILITY IDEOGRAPH-2F9D0;Lo;0;L;8AED;;;;N;;;;;
+2F9D1;CJK COMPATIBILITY IDEOGRAPH-2F9D1;Lo;0;L;8B8A;;;;N;;;;;
+2F9D2;CJK COMPATIBILITY IDEOGRAPH-2F9D2;Lo;0;L;8C55;;;;N;;;;;
+2F9D3;CJK COMPATIBILITY IDEOGRAPH-2F9D3;Lo;0;L;27CA8;;;;N;;;;;
+2F9D4;CJK COMPATIBILITY IDEOGRAPH-2F9D4;Lo;0;L;8CAB;;;;N;;;;;
+2F9D5;CJK COMPATIBILITY IDEOGRAPH-2F9D5;Lo;0;L;8CC1;;;;N;;;;;
+2F9D6;CJK COMPATIBILITY IDEOGRAPH-2F9D6;Lo;0;L;8D1B;;;;N;;;;;
+2F9D7;CJK COMPATIBILITY IDEOGRAPH-2F9D7;Lo;0;L;8D77;;;;N;;;;;
+2F9D8;CJK COMPATIBILITY IDEOGRAPH-2F9D8;Lo;0;L;27F2F;;;;N;;;;;
+2F9D9;CJK COMPATIBILITY IDEOGRAPH-2F9D9;Lo;0;L;20804;;;;N;;;;;
+2F9DA;CJK COMPATIBILITY IDEOGRAPH-2F9DA;Lo;0;L;8DCB;;;;N;;;;;
+2F9DB;CJK COMPATIBILITY IDEOGRAPH-2F9DB;Lo;0;L;8DBC;;;;N;;;;;
+2F9DC;CJK COMPATIBILITY IDEOGRAPH-2F9DC;Lo;0;L;8DF0;;;;N;;;;;
+2F9DD;CJK COMPATIBILITY IDEOGRAPH-2F9DD;Lo;0;L;208DE;;;;N;;;;;
+2F9DE;CJK COMPATIBILITY IDEOGRAPH-2F9DE;Lo;0;L;8ED4;;;;N;;;;;
+2F9DF;CJK COMPATIBILITY IDEOGRAPH-2F9DF;Lo;0;L;8F38;;;;N;;;;;
+2F9E0;CJK COMPATIBILITY IDEOGRAPH-2F9E0;Lo;0;L;285D2;;;;N;;;;;
+2F9E1;CJK COMPATIBILITY IDEOGRAPH-2F9E1;Lo;0;L;285ED;;;;N;;;;;
+2F9E2;CJK COMPATIBILITY IDEOGRAPH-2F9E2;Lo;0;L;9094;;;;N;;;;;
+2F9E3;CJK COMPATIBILITY IDEOGRAPH-2F9E3;Lo;0;L;90F1;;;;N;;;;;
+2F9E4;CJK COMPATIBILITY IDEOGRAPH-2F9E4;Lo;0;L;9111;;;;N;;;;;
+2F9E5;CJK COMPATIBILITY IDEOGRAPH-2F9E5;Lo;0;L;2872E;;;;N;;;;;
+2F9E6;CJK COMPATIBILITY IDEOGRAPH-2F9E6;Lo;0;L;911B;;;;N;;;;;
+2F9E7;CJK COMPATIBILITY IDEOGRAPH-2F9E7;Lo;0;L;9238;;;;N;;;;;
+2F9E8;CJK COMPATIBILITY IDEOGRAPH-2F9E8;Lo;0;L;92D7;;;;N;;;;;
+2F9E9;CJK COMPATIBILITY IDEOGRAPH-2F9E9;Lo;0;L;92D8;;;;N;;;;;
+2F9EA;CJK COMPATIBILITY IDEOGRAPH-2F9EA;Lo;0;L;927C;;;;N;;;;;
+2F9EB;CJK COMPATIBILITY IDEOGRAPH-2F9EB;Lo;0;L;93F9;;;;N;;;;;
+2F9EC;CJK COMPATIBILITY IDEOGRAPH-2F9EC;Lo;0;L;9415;;;;N;;;;;
+2F9ED;CJK COMPATIBILITY IDEOGRAPH-2F9ED;Lo;0;L;28BFA;;;;N;;;;;
+2F9EE;CJK COMPATIBILITY IDEOGRAPH-2F9EE;Lo;0;L;958B;;;;N;;;;;
+2F9EF;CJK COMPATIBILITY IDEOGRAPH-2F9EF;Lo;0;L;4995;;;;N;;;;;
+2F9F0;CJK COMPATIBILITY IDEOGRAPH-2F9F0;Lo;0;L;95B7;;;;N;;;;;
+2F9F1;CJK COMPATIBILITY IDEOGRAPH-2F9F1;Lo;0;L;28D77;;;;N;;;;;
+2F9F2;CJK COMPATIBILITY IDEOGRAPH-2F9F2;Lo;0;L;49E6;;;;N;;;;;
+2F9F3;CJK COMPATIBILITY IDEOGRAPH-2F9F3;Lo;0;L;96C3;;;;N;;;;;
+2F9F4;CJK COMPATIBILITY IDEOGRAPH-2F9F4;Lo;0;L;5DB2;;;;N;;;;;
+2F9F5;CJK COMPATIBILITY IDEOGRAPH-2F9F5;Lo;0;L;9723;;;;N;;;;;
+2F9F6;CJK COMPATIBILITY IDEOGRAPH-2F9F6;Lo;0;L;29145;;;;N;;;;;
+2F9F7;CJK COMPATIBILITY IDEOGRAPH-2F9F7;Lo;0;L;2921A;;;;N;;;;;
+2F9F8;CJK COMPATIBILITY IDEOGRAPH-2F9F8;Lo;0;L;4A6E;;;;N;;;;;
+2F9F9;CJK COMPATIBILITY IDEOGRAPH-2F9F9;Lo;0;L;4A76;;;;N;;;;;
+2F9FA;CJK COMPATIBILITY IDEOGRAPH-2F9FA;Lo;0;L;97E0;;;;N;;;;;
+2F9FB;CJK COMPATIBILITY IDEOGRAPH-2F9FB;Lo;0;L;2940A;;;;N;;;;;
+2F9FC;CJK COMPATIBILITY IDEOGRAPH-2F9FC;Lo;0;L;4AB2;;;;N;;;;;
+2F9FD;CJK COMPATIBILITY IDEOGRAPH-2F9FD;Lo;0;L;29496;;;;N;;;;;
+2F9FE;CJK COMPATIBILITY IDEOGRAPH-2F9FE;Lo;0;L;980B;;;;N;;;;;
+2F9FF;CJK COMPATIBILITY IDEOGRAPH-2F9FF;Lo;0;L;980B;;;;N;;;;;
+2FA00;CJK COMPATIBILITY IDEOGRAPH-2FA00;Lo;0;L;9829;;;;N;;;;;
+2FA01;CJK COMPATIBILITY IDEOGRAPH-2FA01;Lo;0;L;295B6;;;;N;;;;;
+2FA02;CJK COMPATIBILITY IDEOGRAPH-2FA02;Lo;0;L;98E2;;;;N;;;;;
+2FA03;CJK COMPATIBILITY IDEOGRAPH-2FA03;Lo;0;L;4B33;;;;N;;;;;
+2FA04;CJK COMPATIBILITY IDEOGRAPH-2FA04;Lo;0;L;9929;;;;N;;;;;
+2FA05;CJK COMPATIBILITY IDEOGRAPH-2FA05;Lo;0;L;99A7;;;;N;;;;;
+2FA06;CJK COMPATIBILITY IDEOGRAPH-2FA06;Lo;0;L;99C2;;;;N;;;;;
+2FA07;CJK COMPATIBILITY IDEOGRAPH-2FA07;Lo;0;L;99FE;;;;N;;;;;
+2FA08;CJK COMPATIBILITY IDEOGRAPH-2FA08;Lo;0;L;4BCE;;;;N;;;;;
+2FA09;CJK COMPATIBILITY IDEOGRAPH-2FA09;Lo;0;L;29B30;;;;N;;;;;
+2FA0A;CJK COMPATIBILITY IDEOGRAPH-2FA0A;Lo;0;L;9B12;;;;N;;;;;
+2FA0B;CJK COMPATIBILITY IDEOGRAPH-2FA0B;Lo;0;L;9C40;;;;N;;;;;
+2FA0C;CJK COMPATIBILITY IDEOGRAPH-2FA0C;Lo;0;L;9CFD;;;;N;;;;;
+2FA0D;CJK COMPATIBILITY IDEOGRAPH-2FA0D;Lo;0;L;4CCE;;;;N;;;;;
+2FA0E;CJK COMPATIBILITY IDEOGRAPH-2FA0E;Lo;0;L;4CED;;;;N;;;;;
+2FA0F;CJK COMPATIBILITY IDEOGRAPH-2FA0F;Lo;0;L;9D67;;;;N;;;;;
+2FA10;CJK COMPATIBILITY IDEOGRAPH-2FA10;Lo;0;L;2A0CE;;;;N;;;;;
+2FA11;CJK COMPATIBILITY IDEOGRAPH-2FA11;Lo;0;L;4CF8;;;;N;;;;;
+2FA12;CJK COMPATIBILITY IDEOGRAPH-2FA12;Lo;0;L;2A105;;;;N;;;;;
+2FA13;CJK COMPATIBILITY IDEOGRAPH-2FA13;Lo;0;L;2A20E;;;;N;;;;;
+2FA14;CJK COMPATIBILITY IDEOGRAPH-2FA14;Lo;0;L;2A291;;;;N;;;;;
+2FA15;CJK COMPATIBILITY IDEOGRAPH-2FA15;Lo;0;L;9EBB;;;;N;;;;;
+2FA16;CJK COMPATIBILITY IDEOGRAPH-2FA16;Lo;0;L;4D56;;;;N;;;;;
+2FA17;CJK COMPATIBILITY IDEOGRAPH-2FA17;Lo;0;L;9EF9;;;;N;;;;;
+2FA18;CJK COMPATIBILITY IDEOGRAPH-2FA18;Lo;0;L;9EFE;;;;N;;;;;
+2FA19;CJK COMPATIBILITY IDEOGRAPH-2FA19;Lo;0;L;9F05;;;;N;;;;;
+2FA1A;CJK COMPATIBILITY IDEOGRAPH-2FA1A;Lo;0;L;9F0F;;;;N;;;;;
+2FA1B;CJK COMPATIBILITY IDEOGRAPH-2FA1B;Lo;0;L;9F16;;;;N;;;;;
+2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;;
+2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;;
+E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;;
+E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;;
+E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;;
+E0022;TAG QUOTATION MARK;Cf;0;BN;;;;;N;;;;;
+E0023;TAG NUMBER SIGN;Cf;0;BN;;;;;N;;;;;
+E0024;TAG DOLLAR SIGN;Cf;0;BN;;;;;N;;;;;
+E0025;TAG PERCENT SIGN;Cf;0;BN;;;;;N;;;;;
+E0026;TAG AMPERSAND;Cf;0;BN;;;;;N;;;;;
+E0027;TAG APOSTROPHE;Cf;0;BN;;;;;N;;;;;
+E0028;TAG LEFT PARENTHESIS;Cf;0;BN;;;;;N;;;;;
+E0029;TAG RIGHT PARENTHESIS;Cf;0;BN;;;;;N;;;;;
+E002A;TAG ASTERISK;Cf;0;BN;;;;;N;;;;;
+E002B;TAG PLUS SIGN;Cf;0;BN;;;;;N;;;;;
+E002C;TAG COMMA;Cf;0;BN;;;;;N;;;;;
+E002D;TAG HYPHEN-MINUS;Cf;0;BN;;;;;N;;;;;
+E002E;TAG FULL STOP;Cf;0;BN;;;;;N;;;;;
+E002F;TAG SOLIDUS;Cf;0;BN;;;;;N;;;;;
+E0030;TAG DIGIT ZERO;Cf;0;BN;;;;;N;;;;;
+E0031;TAG DIGIT ONE;Cf;0;BN;;;;;N;;;;;
+E0032;TAG DIGIT TWO;Cf;0;BN;;;;;N;;;;;
+E0033;TAG DIGIT THREE;Cf;0;BN;;;;;N;;;;;
+E0034;TAG DIGIT FOUR;Cf;0;BN;;;;;N;;;;;
+E0035;TAG DIGIT FIVE;Cf;0;BN;;;;;N;;;;;
+E0036;TAG DIGIT SIX;Cf;0;BN;;;;;N;;;;;
+E0037;TAG DIGIT SEVEN;Cf;0;BN;;;;;N;;;;;
+E0038;TAG DIGIT EIGHT;Cf;0;BN;;;;;N;;;;;
+E0039;TAG DIGIT NINE;Cf;0;BN;;;;;N;;;;;
+E003A;TAG COLON;Cf;0;BN;;;;;N;;;;;
+E003B;TAG SEMICOLON;Cf;0;BN;;;;;N;;;;;
+E003C;TAG LESS-THAN SIGN;Cf;0;BN;;;;;N;;;;;
+E003D;TAG EQUALS SIGN;Cf;0;BN;;;;;N;;;;;
+E003E;TAG GREATER-THAN SIGN;Cf;0;BN;;;;;N;;;;;
+E003F;TAG QUESTION MARK;Cf;0;BN;;;;;N;;;;;
+E0040;TAG COMMERCIAL AT;Cf;0;BN;;;;;N;;;;;
+E0041;TAG LATIN CAPITAL LETTER A;Cf;0;BN;;;;;N;;;;;
+E0042;TAG LATIN CAPITAL LETTER B;Cf;0;BN;;;;;N;;;;;
+E0043;TAG LATIN CAPITAL LETTER C;Cf;0;BN;;;;;N;;;;;
+E0044;TAG LATIN CAPITAL LETTER D;Cf;0;BN;;;;;N;;;;;
+E0045;TAG LATIN CAPITAL LETTER E;Cf;0;BN;;;;;N;;;;;
+E0046;TAG LATIN CAPITAL LETTER F;Cf;0;BN;;;;;N;;;;;
+E0047;TAG LATIN CAPITAL LETTER G;Cf;0;BN;;;;;N;;;;;
+E0048;TAG LATIN CAPITAL LETTER H;Cf;0;BN;;;;;N;;;;;
+E0049;TAG LATIN CAPITAL LETTER I;Cf;0;BN;;;;;N;;;;;
+E004A;TAG LATIN CAPITAL LETTER J;Cf;0;BN;;;;;N;;;;;
+E004B;TAG LATIN CAPITAL LETTER K;Cf;0;BN;;;;;N;;;;;
+E004C;TAG LATIN CAPITAL LETTER L;Cf;0;BN;;;;;N;;;;;
+E004D;TAG LATIN CAPITAL LETTER M;Cf;0;BN;;;;;N;;;;;
+E004E;TAG LATIN CAPITAL LETTER N;Cf;0;BN;;;;;N;;;;;
+E004F;TAG LATIN CAPITAL LETTER O;Cf;0;BN;;;;;N;;;;;
+E0050;TAG LATIN CAPITAL LETTER P;Cf;0;BN;;;;;N;;;;;
+E0051;TAG LATIN CAPITAL LETTER Q;Cf;0;BN;;;;;N;;;;;
+E0052;TAG LATIN CAPITAL LETTER R;Cf;0;BN;;;;;N;;;;;
+E0053;TAG LATIN CAPITAL LETTER S;Cf;0;BN;;;;;N;;;;;
+E0054;TAG LATIN CAPITAL LETTER T;Cf;0;BN;;;;;N;;;;;
+E0055;TAG LATIN CAPITAL LETTER U;Cf;0;BN;;;;;N;;;;;
+E0056;TAG LATIN CAPITAL LETTER V;Cf;0;BN;;;;;N;;;;;
+E0057;TAG LATIN CAPITAL LETTER W;Cf;0;BN;;;;;N;;;;;
+E0058;TAG LATIN CAPITAL LETTER X;Cf;0;BN;;;;;N;;;;;
+E0059;TAG LATIN CAPITAL LETTER Y;Cf;0;BN;;;;;N;;;;;
+E005A;TAG LATIN CAPITAL LETTER Z;Cf;0;BN;;;;;N;;;;;
+E005B;TAG LEFT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;;
+E005C;TAG REVERSE SOLIDUS;Cf;0;BN;;;;;N;;;;;
+E005D;TAG RIGHT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;;
+E005E;TAG CIRCUMFLEX ACCENT;Cf;0;BN;;;;;N;;;;;
+E005F;TAG LOW LINE;Cf;0;BN;;;;;N;;;;;
+E0060;TAG GRAVE ACCENT;Cf;0;BN;;;;;N;;;;;
+E0061;TAG LATIN SMALL LETTER A;Cf;0;BN;;;;;N;;;;;
+E0062;TAG LATIN SMALL LETTER B;Cf;0;BN;;;;;N;;;;;
+E0063;TAG LATIN SMALL LETTER C;Cf;0;BN;;;;;N;;;;;
+E0064;TAG LATIN SMALL LETTER D;Cf;0;BN;;;;;N;;;;;
+E0065;TAG LATIN SMALL LETTER E;Cf;0;BN;;;;;N;;;;;
+E0066;TAG LATIN SMALL LETTER F;Cf;0;BN;;;;;N;;;;;
+E0067;TAG LATIN SMALL LETTER G;Cf;0;BN;;;;;N;;;;;
+E0068;TAG LATIN SMALL LETTER H;Cf;0;BN;;;;;N;;;;;
+E0069;TAG LATIN SMALL LETTER I;Cf;0;BN;;;;;N;;;;;
+E006A;TAG LATIN SMALL LETTER J;Cf;0;BN;;;;;N;;;;;
+E006B;TAG LATIN SMALL LETTER K;Cf;0;BN;;;;;N;;;;;
+E006C;TAG LATIN SMALL LETTER L;Cf;0;BN;;;;;N;;;;;
+E006D;TAG LATIN SMALL LETTER M;Cf;0;BN;;;;;N;;;;;
+E006E;TAG LATIN SMALL LETTER N;Cf;0;BN;;;;;N;;;;;
+E006F;TAG LATIN SMALL LETTER O;Cf;0;BN;;;;;N;;;;;
+E0070;TAG LATIN SMALL LETTER P;Cf;0;BN;;;;;N;;;;;
+E0071;TAG LATIN SMALL LETTER Q;Cf;0;BN;;;;;N;;;;;
+E0072;TAG LATIN SMALL LETTER R;Cf;0;BN;;;;;N;;;;;
+E0073;TAG LATIN SMALL LETTER S;Cf;0;BN;;;;;N;;;;;
+E0074;TAG LATIN SMALL LETTER T;Cf;0;BN;;;;;N;;;;;
+E0075;TAG LATIN SMALL LETTER U;Cf;0;BN;;;;;N;;;;;
+E0076;TAG LATIN SMALL LETTER V;Cf;0;BN;;;;;N;;;;;
+E0077;TAG LATIN SMALL LETTER W;Cf;0;BN;;;;;N;;;;;
+E0078;TAG LATIN SMALL LETTER X;Cf;0;BN;;;;;N;;;;;
+E0079;TAG LATIN SMALL LETTER Y;Cf;0;BN;;;;;N;;;;;
+E007A;TAG LATIN SMALL LETTER Z;Cf;0;BN;;;;;N;;;;;
+E007B;TAG LEFT CURLY BRACKET;Cf;0;BN;;;;;N;;;;;
+E007C;TAG VERTICAL LINE;Cf;0;BN;;;;;N;;;;;
+E007D;TAG RIGHT CURLY BRACKET;Cf;0;BN;;;;;N;;;;;
+E007E;TAG TILDE;Cf;0;BN;;;;;N;;;;;
+E007F;CANCEL TAG;Cf;0;BN;;;;;N;;;;;
+E0100;VARIATION SELECTOR-17;Mn;0;NSM;;;;;N;;;;;
+E0101;VARIATION SELECTOR-18;Mn;0;NSM;;;;;N;;;;;
+E0102;VARIATION SELECTOR-19;Mn;0;NSM;;;;;N;;;;;
+E0103;VARIATION SELECTOR-20;Mn;0;NSM;;;;;N;;;;;
+E0104;VARIATION SELECTOR-21;Mn;0;NSM;;;;;N;;;;;
+E0105;VARIATION SELECTOR-22;Mn;0;NSM;;;;;N;;;;;
+E0106;VARIATION SELECTOR-23;Mn;0;NSM;;;;;N;;;;;
+E0107;VARIATION SELECTOR-24;Mn;0;NSM;;;;;N;;;;;
+E0108;VARIATION SELECTOR-25;Mn;0;NSM;;;;;N;;;;;
+E0109;VARIATION SELECTOR-26;Mn;0;NSM;;;;;N;;;;;
+E010A;VARIATION SELECTOR-27;Mn;0;NSM;;;;;N;;;;;
+E010B;VARIATION SELECTOR-28;Mn;0;NSM;;;;;N;;;;;
+E010C;VARIATION SELECTOR-29;Mn;0;NSM;;;;;N;;;;;
+E010D;VARIATION SELECTOR-30;Mn;0;NSM;;;;;N;;;;;
+E010E;VARIATION SELECTOR-31;Mn;0;NSM;;;;;N;;;;;
+E010F;VARIATION SELECTOR-32;Mn;0;NSM;;;;;N;;;;;
+E0110;VARIATION SELECTOR-33;Mn;0;NSM;;;;;N;;;;;
+E0111;VARIATION SELECTOR-34;Mn;0;NSM;;;;;N;;;;;
+E0112;VARIATION SELECTOR-35;Mn;0;NSM;;;;;N;;;;;
+E0113;VARIATION SELECTOR-36;Mn;0;NSM;;;;;N;;;;;
+E0114;VARIATION SELECTOR-37;Mn;0;NSM;;;;;N;;;;;
+E0115;VARIATION SELECTOR-38;Mn;0;NSM;;;;;N;;;;;
+E0116;VARIATION SELECTOR-39;Mn;0;NSM;;;;;N;;;;;
+E0117;VARIATION SELECTOR-40;Mn;0;NSM;;;;;N;;;;;
+E0118;VARIATION SELECTOR-41;Mn;0;NSM;;;;;N;;;;;
+E0119;VARIATION SELECTOR-42;Mn;0;NSM;;;;;N;;;;;
+E011A;VARIATION SELECTOR-43;Mn;0;NSM;;;;;N;;;;;
+E011B;VARIATION SELECTOR-44;Mn;0;NSM;;;;;N;;;;;
+E011C;VARIATION SELECTOR-45;Mn;0;NSM;;;;;N;;;;;
+E011D;VARIATION SELECTOR-46;Mn;0;NSM;;;;;N;;;;;
+E011E;VARIATION SELECTOR-47;Mn;0;NSM;;;;;N;;;;;
+E011F;VARIATION SELECTOR-48;Mn;0;NSM;;;;;N;;;;;
+E0120;VARIATION SELECTOR-49;Mn;0;NSM;;;;;N;;;;;
+E0121;VARIATION SELECTOR-50;Mn;0;NSM;;;;;N;;;;;
+E0122;VARIATION SELECTOR-51;Mn;0;NSM;;;;;N;;;;;
+E0123;VARIATION SELECTOR-52;Mn;0;NSM;;;;;N;;;;;
+E0124;VARIATION SELECTOR-53;Mn;0;NSM;;;;;N;;;;;
+E0125;VARIATION SELECTOR-54;Mn;0;NSM;;;;;N;;;;;
+E0126;VARIATION SELECTOR-55;Mn;0;NSM;;;;;N;;;;;
+E0127;VARIATION SELECTOR-56;Mn;0;NSM;;;;;N;;;;;
+E0128;VARIATION SELECTOR-57;Mn;0;NSM;;;;;N;;;;;
+E0129;VARIATION SELECTOR-58;Mn;0;NSM;;;;;N;;;;;
+E012A;VARIATION SELECTOR-59;Mn;0;NSM;;;;;N;;;;;
+E012B;VARIATION SELECTOR-60;Mn;0;NSM;;;;;N;;;;;
+E012C;VARIATION SELECTOR-61;Mn;0;NSM;;;;;N;;;;;
+E012D;VARIATION SELECTOR-62;Mn;0;NSM;;;;;N;;;;;
+E012E;VARIATION SELECTOR-63;Mn;0;NSM;;;;;N;;;;;
+E012F;VARIATION SELECTOR-64;Mn;0;NSM;;;;;N;;;;;
+E0130;VARIATION SELECTOR-65;Mn;0;NSM;;;;;N;;;;;
+E0131;VARIATION SELECTOR-66;Mn;0;NSM;;;;;N;;;;;
+E0132;VARIATION SELECTOR-67;Mn;0;NSM;;;;;N;;;;;
+E0133;VARIATION SELECTOR-68;Mn;0;NSM;;;;;N;;;;;
+E0134;VARIATION SELECTOR-69;Mn;0;NSM;;;;;N;;;;;
+E0135;VARIATION SELECTOR-70;Mn;0;NSM;;;;;N;;;;;
+E0136;VARIATION SELECTOR-71;Mn;0;NSM;;;;;N;;;;;
+E0137;VARIATION SELECTOR-72;Mn;0;NSM;;;;;N;;;;;
+E0138;VARIATION SELECTOR-73;Mn;0;NSM;;;;;N;;;;;
+E0139;VARIATION SELECTOR-74;Mn;0;NSM;;;;;N;;;;;
+E013A;VARIATION SELECTOR-75;Mn;0;NSM;;;;;N;;;;;
+E013B;VARIATION SELECTOR-76;Mn;0;NSM;;;;;N;;;;;
+E013C;VARIATION SELECTOR-77;Mn;0;NSM;;;;;N;;;;;
+E013D;VARIATION SELECTOR-78;Mn;0;NSM;;;;;N;;;;;
+E013E;VARIATION SELECTOR-79;Mn;0;NSM;;;;;N;;;;;
+E013F;VARIATION SELECTOR-80;Mn;0;NSM;;;;;N;;;;;
+E0140;VARIATION SELECTOR-81;Mn;0;NSM;;;;;N;;;;;
+E0141;VARIATION SELECTOR-82;Mn;0;NSM;;;;;N;;;;;
+E0142;VARIATION SELECTOR-83;Mn;0;NSM;;;;;N;;;;;
+E0143;VARIATION SELECTOR-84;Mn;0;NSM;;;;;N;;;;;
+E0144;VARIATION SELECTOR-85;Mn;0;NSM;;;;;N;;;;;
+E0145;VARIATION SELECTOR-86;Mn;0;NSM;;;;;N;;;;;
+E0146;VARIATION SELECTOR-87;Mn;0;NSM;;;;;N;;;;;
+E0147;VARIATION SELECTOR-88;Mn;0;NSM;;;;;N;;;;;
+E0148;VARIATION SELECTOR-89;Mn;0;NSM;;;;;N;;;;;
+E0149;VARIATION SELECTOR-90;Mn;0;NSM;;;;;N;;;;;
+E014A;VARIATION SELECTOR-91;Mn;0;NSM;;;;;N;;;;;
+E014B;VARIATION SELECTOR-92;Mn;0;NSM;;;;;N;;;;;
+E014C;VARIATION SELECTOR-93;Mn;0;NSM;;;;;N;;;;;
+E014D;VARIATION SELECTOR-94;Mn;0;NSM;;;;;N;;;;;
+E014E;VARIATION SELECTOR-95;Mn;0;NSM;;;;;N;;;;;
+E014F;VARIATION SELECTOR-96;Mn;0;NSM;;;;;N;;;;;
+E0150;VARIATION SELECTOR-97;Mn;0;NSM;;;;;N;;;;;
+E0151;VARIATION SELECTOR-98;Mn;0;NSM;;;;;N;;;;;
+E0152;VARIATION SELECTOR-99;Mn;0;NSM;;;;;N;;;;;
+E0153;VARIATION SELECTOR-100;Mn;0;NSM;;;;;N;;;;;
+E0154;VARIATION SELECTOR-101;Mn;0;NSM;;;;;N;;;;;
+E0155;VARIATION SELECTOR-102;Mn;0;NSM;;;;;N;;;;;
+E0156;VARIATION SELECTOR-103;Mn;0;NSM;;;;;N;;;;;
+E0157;VARIATION SELECTOR-104;Mn;0;NSM;;;;;N;;;;;
+E0158;VARIATION SELECTOR-105;Mn;0;NSM;;;;;N;;;;;
+E0159;VARIATION SELECTOR-106;Mn;0;NSM;;;;;N;;;;;
+E015A;VARIATION SELECTOR-107;Mn;0;NSM;;;;;N;;;;;
+E015B;VARIATION SELECTOR-108;Mn;0;NSM;;;;;N;;;;;
+E015C;VARIATION SELECTOR-109;Mn;0;NSM;;;;;N;;;;;
+E015D;VARIATION SELECTOR-110;Mn;0;NSM;;;;;N;;;;;
+E015E;VARIATION SELECTOR-111;Mn;0;NSM;;;;;N;;;;;
+E015F;VARIATION SELECTOR-112;Mn;0;NSM;;;;;N;;;;;
+E0160;VARIATION SELECTOR-113;Mn;0;NSM;;;;;N;;;;;
+E0161;VARIATION SELECTOR-114;Mn;0;NSM;;;;;N;;;;;
+E0162;VARIATION SELECTOR-115;Mn;0;NSM;;;;;N;;;;;
+E0163;VARIATION SELECTOR-116;Mn;0;NSM;;;;;N;;;;;
+E0164;VARIATION SELECTOR-117;Mn;0;NSM;;;;;N;;;;;
+E0165;VARIATION SELECTOR-118;Mn;0;NSM;;;;;N;;;;;
+E0166;VARIATION SELECTOR-119;Mn;0;NSM;;;;;N;;;;;
+E0167;VARIATION SELECTOR-120;Mn;0;NSM;;;;;N;;;;;
+E0168;VARIATION SELECTOR-121;Mn;0;NSM;;;;;N;;;;;
+E0169;VARIATION SELECTOR-122;Mn;0;NSM;;;;;N;;;;;
+E016A;VARIATION SELECTOR-123;Mn;0;NSM;;;;;N;;;;;
+E016B;VARIATION SELECTOR-124;Mn;0;NSM;;;;;N;;;;;
+E016C;VARIATION SELECTOR-125;Mn;0;NSM;;;;;N;;;;;
+E016D;VARIATION SELECTOR-126;Mn;0;NSM;;;;;N;;;;;
+E016E;VARIATION SELECTOR-127;Mn;0;NSM;;;;;N;;;;;
+E016F;VARIATION SELECTOR-128;Mn;0;NSM;;;;;N;;;;;
+E0170;VARIATION SELECTOR-129;Mn;0;NSM;;;;;N;;;;;
+E0171;VARIATION SELECTOR-130;Mn;0;NSM;;;;;N;;;;;
+E0172;VARIATION SELECTOR-131;Mn;0;NSM;;;;;N;;;;;
+E0173;VARIATION SELECTOR-132;Mn;0;NSM;;;;;N;;;;;
+E0174;VARIATION SELECTOR-133;Mn;0;NSM;;;;;N;;;;;
+E0175;VARIATION SELECTOR-134;Mn;0;NSM;;;;;N;;;;;
+E0176;VARIATION SELECTOR-135;Mn;0;NSM;;;;;N;;;;;
+E0177;VARIATION SELECTOR-136;Mn;0;NSM;;;;;N;;;;;
+E0178;VARIATION SELECTOR-137;Mn;0;NSM;;;;;N;;;;;
+E0179;VARIATION SELECTOR-138;Mn;0;NSM;;;;;N;;;;;
+E017A;VARIATION SELECTOR-139;Mn;0;NSM;;;;;N;;;;;
+E017B;VARIATION SELECTOR-140;Mn;0;NSM;;;;;N;;;;;
+E017C;VARIATION SELECTOR-141;Mn;0;NSM;;;;;N;;;;;
+E017D;VARIATION SELECTOR-142;Mn;0;NSM;;;;;N;;;;;
+E017E;VARIATION SELECTOR-143;Mn;0;NSM;;;;;N;;;;;
+E017F;VARIATION SELECTOR-144;Mn;0;NSM;;;;;N;;;;;
+E0180;VARIATION SELECTOR-145;Mn;0;NSM;;;;;N;;;;;
+E0181;VARIATION SELECTOR-146;Mn;0;NSM;;;;;N;;;;;
+E0182;VARIATION SELECTOR-147;Mn;0;NSM;;;;;N;;;;;
+E0183;VARIATION SELECTOR-148;Mn;0;NSM;;;;;N;;;;;
+E0184;VARIATION SELECTOR-149;Mn;0;NSM;;;;;N;;;;;
+E0185;VARIATION SELECTOR-150;Mn;0;NSM;;;;;N;;;;;
+E0186;VARIATION SELECTOR-151;Mn;0;NSM;;;;;N;;;;;
+E0187;VARIATION SELECTOR-152;Mn;0;NSM;;;;;N;;;;;
+E0188;VARIATION SELECTOR-153;Mn;0;NSM;;;;;N;;;;;
+E0189;VARIATION SELECTOR-154;Mn;0;NSM;;;;;N;;;;;
+E018A;VARIATION SELECTOR-155;Mn;0;NSM;;;;;N;;;;;
+E018B;VARIATION SELECTOR-156;Mn;0;NSM;;;;;N;;;;;
+E018C;VARIATION SELECTOR-157;Mn;0;NSM;;;;;N;;;;;
+E018D;VARIATION SELECTOR-158;Mn;0;NSM;;;;;N;;;;;
+E018E;VARIATION SELECTOR-159;Mn;0;NSM;;;;;N;;;;;
+E018F;VARIATION SELECTOR-160;Mn;0;NSM;;;;;N;;;;;
+E0190;VARIATION SELECTOR-161;Mn;0;NSM;;;;;N;;;;;
+E0191;VARIATION SELECTOR-162;Mn;0;NSM;;;;;N;;;;;
+E0192;VARIATION SELECTOR-163;Mn;0;NSM;;;;;N;;;;;
+E0193;VARIATION SELECTOR-164;Mn;0;NSM;;;;;N;;;;;
+E0194;VARIATION SELECTOR-165;Mn;0;NSM;;;;;N;;;;;
+E0195;VARIATION SELECTOR-166;Mn;0;NSM;;;;;N;;;;;
+E0196;VARIATION SELECTOR-167;Mn;0;NSM;;;;;N;;;;;
+E0197;VARIATION SELECTOR-168;Mn;0;NSM;;;;;N;;;;;
+E0198;VARIATION SELECTOR-169;Mn;0;NSM;;;;;N;;;;;
+E0199;VARIATION SELECTOR-170;Mn;0;NSM;;;;;N;;;;;
+E019A;VARIATION SELECTOR-171;Mn;0;NSM;;;;;N;;;;;
+E019B;VARIATION SELECTOR-172;Mn;0;NSM;;;;;N;;;;;
+E019C;VARIATION SELECTOR-173;Mn;0;NSM;;;;;N;;;;;
+E019D;VARIATION SELECTOR-174;Mn;0;NSM;;;;;N;;;;;
+E019E;VARIATION SELECTOR-175;Mn;0;NSM;;;;;N;;;;;
+E019F;VARIATION SELECTOR-176;Mn;0;NSM;;;;;N;;;;;
+E01A0;VARIATION SELECTOR-177;Mn;0;NSM;;;;;N;;;;;
+E01A1;VARIATION SELECTOR-178;Mn;0;NSM;;;;;N;;;;;
+E01A2;VARIATION SELECTOR-179;Mn;0;NSM;;;;;N;;;;;
+E01A3;VARIATION SELECTOR-180;Mn;0;NSM;;;;;N;;;;;
+E01A4;VARIATION SELECTOR-181;Mn;0;NSM;;;;;N;;;;;
+E01A5;VARIATION SELECTOR-182;Mn;0;NSM;;;;;N;;;;;
+E01A6;VARIATION SELECTOR-183;Mn;0;NSM;;;;;N;;;;;
+E01A7;VARIATION SELECTOR-184;Mn;0;NSM;;;;;N;;;;;
+E01A8;VARIATION SELECTOR-185;Mn;0;NSM;;;;;N;;;;;
+E01A9;VARIATION SELECTOR-186;Mn;0;NSM;;;;;N;;;;;
+E01AA;VARIATION SELECTOR-187;Mn;0;NSM;;;;;N;;;;;
+E01AB;VARIATION SELECTOR-188;Mn;0;NSM;;;;;N;;;;;
+E01AC;VARIATION SELECTOR-189;Mn;0;NSM;;;;;N;;;;;
+E01AD;VARIATION SELECTOR-190;Mn;0;NSM;;;;;N;;;;;
+E01AE;VARIATION SELECTOR-191;Mn;0;NSM;;;;;N;;;;;
+E01AF;VARIATION SELECTOR-192;Mn;0;NSM;;;;;N;;;;;
+E01B0;VARIATION SELECTOR-193;Mn;0;NSM;;;;;N;;;;;
+E01B1;VARIATION SELECTOR-194;Mn;0;NSM;;;;;N;;;;;
+E01B2;VARIATION SELECTOR-195;Mn;0;NSM;;;;;N;;;;;
+E01B3;VARIATION SELECTOR-196;Mn;0;NSM;;;;;N;;;;;
+E01B4;VARIATION SELECTOR-197;Mn;0;NSM;;;;;N;;;;;
+E01B5;VARIATION SELECTOR-198;Mn;0;NSM;;;;;N;;;;;
+E01B6;VARIATION SELECTOR-199;Mn;0;NSM;;;;;N;;;;;
+E01B7;VARIATION SELECTOR-200;Mn;0;NSM;;;;;N;;;;;
+E01B8;VARIATION SELECTOR-201;Mn;0;NSM;;;;;N;;;;;
+E01B9;VARIATION SELECTOR-202;Mn;0;NSM;;;;;N;;;;;
+E01BA;VARIATION SELECTOR-203;Mn;0;NSM;;;;;N;;;;;
+E01BB;VARIATION SELECTOR-204;Mn;0;NSM;;;;;N;;;;;
+E01BC;VARIATION SELECTOR-205;Mn;0;NSM;;;;;N;;;;;
+E01BD;VARIATION SELECTOR-206;Mn;0;NSM;;;;;N;;;;;
+E01BE;VARIATION SELECTOR-207;Mn;0;NSM;;;;;N;;;;;
+E01BF;VARIATION SELECTOR-208;Mn;0;NSM;;;;;N;;;;;
+E01C0;VARIATION SELECTOR-209;Mn;0;NSM;;;;;N;;;;;
+E01C1;VARIATION SELECTOR-210;Mn;0;NSM;;;;;N;;;;;
+E01C2;VARIATION SELECTOR-211;Mn;0;NSM;;;;;N;;;;;
+E01C3;VARIATION SELECTOR-212;Mn;0;NSM;;;;;N;;;;;
+E01C4;VARIATION SELECTOR-213;Mn;0;NSM;;;;;N;;;;;
+E01C5;VARIATION SELECTOR-214;Mn;0;NSM;;;;;N;;;;;
+E01C6;VARIATION SELECTOR-215;Mn;0;NSM;;;;;N;;;;;
+E01C7;VARIATION SELECTOR-216;Mn;0;NSM;;;;;N;;;;;
+E01C8;VARIATION SELECTOR-217;Mn;0;NSM;;;;;N;;;;;
+E01C9;VARIATION SELECTOR-218;Mn;0;NSM;;;;;N;;;;;
+E01CA;VARIATION SELECTOR-219;Mn;0;NSM;;;;;N;;;;;
+E01CB;VARIATION SELECTOR-220;Mn;0;NSM;;;;;N;;;;;
+E01CC;VARIATION SELECTOR-221;Mn;0;NSM;;;;;N;;;;;
+E01CD;VARIATION SELECTOR-222;Mn;0;NSM;;;;;N;;;;;
+E01CE;VARIATION SELECTOR-223;Mn;0;NSM;;;;;N;;;;;
+E01CF;VARIATION SELECTOR-224;Mn;0;NSM;;;;;N;;;;;
+E01D0;VARIATION SELECTOR-225;Mn;0;NSM;;;;;N;;;;;
+E01D1;VARIATION SELECTOR-226;Mn;0;NSM;;;;;N;;;;;
+E01D2;VARIATION SELECTOR-227;Mn;0;NSM;;;;;N;;;;;
+E01D3;VARIATION SELECTOR-228;Mn;0;NSM;;;;;N;;;;;
+E01D4;VARIATION SELECTOR-229;Mn;0;NSM;;;;;N;;;;;
+E01D5;VARIATION SELECTOR-230;Mn;0;NSM;;;;;N;;;;;
+E01D6;VARIATION SELECTOR-231;Mn;0;NSM;;;;;N;;;;;
+E01D7;VARIATION SELECTOR-232;Mn;0;NSM;;;;;N;;;;;
+E01D8;VARIATION SELECTOR-233;Mn;0;NSM;;;;;N;;;;;
+E01D9;VARIATION SELECTOR-234;Mn;0;NSM;;;;;N;;;;;
+E01DA;VARIATION SELECTOR-235;Mn;0;NSM;;;;;N;;;;;
+E01DB;VARIATION SELECTOR-236;Mn;0;NSM;;;;;N;;;;;
+E01DC;VARIATION SELECTOR-237;Mn;0;NSM;;;;;N;;;;;
+E01DD;VARIATION SELECTOR-238;Mn;0;NSM;;;;;N;;;;;
+E01DE;VARIATION SELECTOR-239;Mn;0;NSM;;;;;N;;;;;
+E01DF;VARIATION SELECTOR-240;Mn;0;NSM;;;;;N;;;;;
+E01E0;VARIATION SELECTOR-241;Mn;0;NSM;;;;;N;;;;;
+E01E1;VARIATION SELECTOR-242;Mn;0;NSM;;;;;N;;;;;
+E01E2;VARIATION SELECTOR-243;Mn;0;NSM;;;;;N;;;;;
+E01E3;VARIATION SELECTOR-244;Mn;0;NSM;;;;;N;;;;;
+E01E4;VARIATION SELECTOR-245;Mn;0;NSM;;;;;N;;;;;
+E01E5;VARIATION SELECTOR-246;Mn;0;NSM;;;;;N;;;;;
+E01E6;VARIATION SELECTOR-247;Mn;0;NSM;;;;;N;;;;;
+E01E7;VARIATION SELECTOR-248;Mn;0;NSM;;;;;N;;;;;
+E01E8;VARIATION SELECTOR-249;Mn;0;NSM;;;;;N;;;;;
+E01E9;VARIATION SELECTOR-250;Mn;0;NSM;;;;;N;;;;;
+E01EA;VARIATION SELECTOR-251;Mn;0;NSM;;;;;N;;;;;
+E01EB;VARIATION SELECTOR-252;Mn;0;NSM;;;;;N;;;;;
+E01EC;VARIATION SELECTOR-253;Mn;0;NSM;;;;;N;;;;;
+E01ED;VARIATION SELECTOR-254;Mn;0;NSM;;;;;N;;;;;
+E01EE;VARIATION SELECTOR-255;Mn;0;NSM;;;;;N;;;;;
+E01EF;VARIATION SELECTOR-256;Mn;0;NSM;;;;;N;;;;;
+F0000;<Plane 15 Private Use, First>;Co;0;L;;;;;N;;;;;
+FFFFD;<Plane 15 Private Use, Last>;Co;0;L;;;;;N;;;;;
+100000;<Plane 16 Private Use, First>;Co;0;L;;;;;N;;;;;
+10FFFD;<Plane 16 Private Use, Last>;Co;0;L;;;;;N;;;;;
diff --git a/lib/stdlib/uc_spec/gen_unicode_mod.escript b/lib/stdlib/uc_spec/gen_unicode_mod.escript
new file mode 100755
index 0000000000..fefd7d3b70
--- /dev/null
+++ b/lib/stdlib/uc_spec/gen_unicode_mod.escript
@@ -0,0 +1,911 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%%! +A0
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-mode(compile).
+
+-record(cp, {name, class, dec, comp, cs}).
+-define(MOD, "unicode_util").
+
+main(_) ->
+ %% Parse main table
+ {ok, UD} = file:open("../uc_spec/UnicodeData.txt", [read, raw, {read_ahead, 1000000}]),
+ Data0 = foldl(fun parse_unicode_data/2, [], UD),
+ Data1 = array:from_orddict(lists:reverse(Data0)),
+ ok = file:close(UD),
+
+ %% Special Casing table
+ {ok, SC} = file:open("../uc_spec/SpecialCasing.txt", [read, raw, {read_ahead, 1000000}]),
+ Data2 = foldl(fun parse_special_casing/2, Data1, SC),
+ ok = file:close(SC),
+ %% Casing Folding table
+ {ok, CF} = file:open("../uc_spec/CaseFolding.txt", [read, raw, {read_ahead, 1000000}]),
+ Data = foldl(fun parse_case_folding/2, Data2, CF),
+ ok = file:close(CF),
+
+ %% Normalization
+ {ok, ExclF} = file:open("../uc_spec/CompositionExclusions.txt", [read, raw, {read_ahead, 1000000}]),
+ ExclData = foldl(fun parse_comp_excl/2, Data, ExclF),
+ ok = file:close(ExclF),
+
+ %% GraphemeBreakProperty table
+ {ok, GBPF} = file:open("../uc_spec/GraphemeBreakProperty.txt", [read, raw, {read_ahead, 1000000}]),
+ Props0 = foldl(fun parse_properties/2, [], GBPF),
+ ok = file:close(GBPF),
+ {ok, PropF} = file:open("../uc_spec/PropList.txt", [read, raw, {read_ahead, 1000000}]),
+ Props1 = foldl(fun parse_properties/2, Props0, PropF),
+ ok = file:close(PropF),
+ Props = sofs:to_external(sofs:relation_to_family(sofs:relation(Props1))),
+
+ %% Make module
+ {ok, Out} = file:open(?MOD++".erl", [write]),
+ gen_file(Out, Data, ExclData, maps:from_list(Props)),
+ ok = file:close(Out),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+parse_unicode_data(Line0, Acc) ->
+ Line = string:strip(Line0, right, $\n),
+ [CodePoint,Name,_Cat,Class,_BiDi,Decomp,
+ _N1,_N2,_N3,_BDMirror,_Uni1,_Iso|Case] = tokens(Line, ";"),
+ {Dec,Comp} = case to_decomp(Decomp) of
+ {_, _} = Compabil -> {[], Compabil};
+ Canon -> {Canon, []}
+ end,
+ [{hex_to_int(CodePoint),
+ #cp{name=list_to_binary(Name),class=to_class(Class),
+ dec=Dec, comp=Comp, cs=to_case(Case)}}
+ |Acc].
+
+to_class(String) ->
+ list_to_integer(string:strip(String, both)).
+
+to_decomp("") -> [];
+to_decomp("<" ++ Str) ->
+ [Tag,Rest] = string:tokens(Str, ">"),
+ {list_to_atom(Tag), to_decomp(Rest)};
+to_decomp(CodePoints) ->
+ CPL = string:tokens(CodePoints, " "),
+ [hex_to_int(CP) || CP <- CPL].
+
+to_case(["","",""]) -> [];
+to_case([Upper,Lower,Title]) ->
+ {hex_to_int(Upper),hex_to_int(Lower),hex_to_int(Title),[]}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+parse_special_casing("03A3;" ++ _, Acc) ->
+ %% Break for conditional handling, which we don't support
+ {done, Acc};
+parse_special_casing(Line, Table) ->
+ [CodePoint|CaseStr] = tokens(Line, ";"),
+ CP = hex_to_int(CodePoint),
+ Entry = array:get(CP, Table),
+ Case = to_scase(CaseStr),
+ array:set(CP, Entry#cp{cs=Case}, Table).
+
+to_scase([Lower,Title,Upper|_]) ->
+ {unlist([hex_to_int(CP) || CP <- string:strip(string:tokens(Upper, " "), both)]),
+ unlist([hex_to_int(CP) || CP <- string:strip(string:tokens(Lower, " "), both)]),
+ unlist([hex_to_int(CP) || CP <- string:strip(string:tokens(Title, " "), both)]),
+ []}.
+
+parse_case_folding(Line, Table) ->
+ [CodePoint, Class0, CaseStr |_Comments] = tokens(Line, ";"),
+ Class = string:strip(Class0, both),
+ if Class =:= "T" -> Table; %% Do not support localization yet
+ Class =:= "S" -> Table; %% Ignore simple
+ true ->
+ CP = hex_to_int(CodePoint),
+ Case = unlist([hex_to_int(CPC) ||
+ CPC <- string:strip(string:tokens(CaseStr, " "), both)]),
+ #cp{cs={U,L,T,_}} = Entry = array:get(CP, Table),
+ array:set(CP, Entry#cp{cs={U,L,T,Case}}, Table)
+ end.
+
+unlist([A]) -> A;
+unlist(A) -> A.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+parse_comp_excl(Line, Table) ->
+ [CodePoint|_Comments] = tokens(Line, "#"),
+ CP = hex_to_int(CodePoint),
+ Entry = array:get(CP, Table),
+ array:set(CP, Entry#cp{dec=none}, Table).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+parse_properties(Line0, Acc) ->
+ [Line|_Comments] = tokens(Line0, "#"),
+ [CodePoints, Class] = tokens(Line, ";"),
+ case tokens(CodePoints, ".") of
+ [CodePoint] ->
+ [{to_atom(Class), {hex_to_int(CodePoint), undefined}}|Acc];
+ [CodePoint1,"",CodePoint2] ->
+ [{to_atom(Class), {hex_to_int(CodePoint1), hex_to_int(CodePoint2)}}|Acc]
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+gen_file(Fd, Data, ExclData, Props) ->
+ gen_header(Fd),
+ gen_static(Fd),
+ gen_norm(Fd),
+ gen_ws(Fd, Props),
+ gen_cp(Fd),
+ gen_gc(Fd, Props),
+ gen_compose_pairs(Fd, ExclData, Data),
+ gen_case_table(Fd, Data),
+ gen_unicode_table(Fd, Data),
+ ok.
+
+gen_header(Fd) ->
+ io:put_chars(Fd, "%%\n%% this file is generated do not modify\n"),
+ io:put_chars(Fd, "%% see ../uc_spec/gen_unicode_mod.escript\n\n"),
+ io:put_chars(Fd, "-module(" ++ ?MOD ++").\n"),
+ io:put_chars(Fd, "-export([cp/1, gc/1]).\n"),
+ io:put_chars(Fd, "-export([nfd/1, nfc/1, nfkd/1, nfkc/1]).\n"),
+ io:put_chars(Fd, "-export([whitespace/0, is_whitespace/1]).\n"),
+ io:put_chars(Fd, "-export([uppercase/1, lowercase/1, titlecase/1, casefold/1]).\n\n"),
+ io:put_chars(Fd, "-export([spec_version/0, lookup/1, get_case/1]).\n"),
+ io:put_chars(Fd, "-inline([class/1]).\n"),
+ io:put_chars(Fd, "-compile(nowarn_unused_vars).\n"),
+ io:put_chars(Fd, "-dialyzer({no_improper_lists, [cp/1, gc_prepend/2, gc_e_cont/2]}).\n"),
+ io:put_chars(Fd, "-type gc() :: char()|[char()].\n\n\n"),
+ ok.
+
+gen_static(Fd) ->
+ io:put_chars(Fd, "-spec lookup(char()) -> #{'canon':=[{byte(),char()}], 'ccc':=byte(), "
+ "'compat':=[] | {atom(),[{byte(),char()}]}}.\n"),
+ io:put_chars(Fd, "lookup(Codepoint) ->\n"
+ " {CCC,Can,Comp} = unicode_table(Codepoint),\n"
+ " #{ccc=>CCC, canon=>Can, compat=>Comp}.\n\n"),
+ io:put_chars(Fd, "-spec get_case(char()) -> #{'fold':=gc(), 'lower':=gc(), 'title':=gc(), 'upper':=gc()}.\n"),
+ io:put_chars(Fd, "get_case(Codepoint) ->\n"
+ " case case_table(Codepoint) of\n"
+ " {U,L} -> #{upper=>U,lower=>L,title=>U,fold=>L};\n"
+ " {U,L,T,F} -> #{upper=>U,lower=>L,title=>T,fold=>F}\n"
+ " end.\n\n"),
+ io:put_chars(Fd, "spec_version() -> {9,0}.\n\n\n"),
+ io:put_chars(Fd, "class(Codepoint) -> {CCC,_,_} = unicode_table(Codepoint),\n CCC.\n\n"),
+ io:put_chars(Fd, "-spec uppercase(unicode:chardata()) -> "
+ "maybe_improper_list(gc(),unicode:chardata()).\n"),
+ io:put_chars(Fd, "uppercase(Str0) ->\n"),
+ io:put_chars(Fd, " case cp(Str0) of\n"),
+ io:put_chars(Fd, " [CP|Str] = Str1 ->\n"),
+ io:put_chars(Fd, " case case_table(CP) of\n"),
+ io:put_chars(Fd, " {Upper,_} -> [Upper|Str];\n"),
+ io:put_chars(Fd, " {Upper,_,_,_} -> [Upper|Str]\n"),
+ io:put_chars(Fd, " end;\n"),
+ io:put_chars(Fd, " [] -> []\n"),
+ io:put_chars(Fd, " end.\n\n"),
+ io:put_chars(Fd, "-spec lowercase(unicode:chardata()) -> "
+ "maybe_improper_list(gc(),unicode:chardata()).\n"),
+ io:put_chars(Fd, "lowercase(Str0) ->\n"),
+ io:put_chars(Fd, " case cp(Str0) of\n"),
+ io:put_chars(Fd, " [CP|Str] = Str1 ->\n"),
+ io:put_chars(Fd, " case case_table(CP) of\n"),
+ io:put_chars(Fd, " {_,Lower} -> [Lower|Str];\n"),
+ io:put_chars(Fd, " {_,Lower,_,_} -> [Lower|Str]\n"),
+ io:put_chars(Fd, " end;\n"),
+ io:put_chars(Fd, " [] -> []\n"),
+ io:put_chars(Fd, " end.\n\n"),
+ io:put_chars(Fd, "-spec titlecase(unicode:chardata()) -> "
+ "maybe_improper_list(gc(),unicode:chardata()).\n"),
+ io:put_chars(Fd, "titlecase(Str0) ->\n"),
+ io:put_chars(Fd, " case cp(Str0) of\n"),
+ io:put_chars(Fd, " [CP|Str] = Str1 ->\n"),
+ io:put_chars(Fd, " case case_table(CP) of\n"),
+ io:put_chars(Fd, " {_,_,Title,_} -> [Title|Str];\n"),
+ io:put_chars(Fd, " {Upper,_} -> [Upper|Str]\n"),
+ io:put_chars(Fd, " end;\n"),
+ io:put_chars(Fd, " [] -> []\n"),
+ io:put_chars(Fd, " end.\n\n"),
+ io:put_chars(Fd, "-spec casefold(unicode:chardata()) -> "
+ "maybe_improper_list(gc(),unicode:chardata()).\n"),
+ io:put_chars(Fd, "casefold(Str0) ->\n"),
+ io:put_chars(Fd, " case cp(Str0) of\n"),
+ io:put_chars(Fd, " [CP|Str] = Str1 ->\n"),
+ io:put_chars(Fd, " case case_table(CP) of\n"),
+ io:put_chars(Fd, " {_,_,_,Fold} -> [Fold|Str];\n"),
+ io:put_chars(Fd, " {_,Lower} -> [Lower|Str]\n"),
+ io:put_chars(Fd, " end;\n"),
+ io:put_chars(Fd, " [] -> []\n"),
+ io:put_chars(Fd, " end.\n\n"),
+
+ ok.
+
+gen_norm(Fd) ->
+ io:put_chars(Fd,
+ "-spec nfd(unicode:chardata()) -> maybe_improper_list(gc(),unicode:chardata()) | {error, unicode:chardata()}.\n"
+ "nfd(Str0) ->\n"
+ " case gc(Str0) of\n"
+ " [GC|R] when GC < 127 -> [GC|R];\n"
+ " [GC|Str] -> [decompose(GC)|Str];\n"
+ " [] -> [];\n"
+ " {error,_}=Error -> Error\n end.\n\n"
+ ),
+
+ io:put_chars(Fd,
+ "-spec nfkd(unicode:chardata()) -> maybe_improper_list(gc(),unicode:chardata()) | {error, unicode:chardata()}.\n"
+ "nfkd(Str0) ->\n"
+ " case gc(Str0) of\n"
+ " [GC|R] when GC < 127 -> [GC|R];\n"
+ " [GC|Str] -> [decompose_compat(GC)|Str];\n"
+ " [] -> [];\n"
+ " {error,_}=Error -> Error\n end.\n\n"
+ ),
+
+ io:put_chars(Fd,
+ "-spec nfc(unicode:chardata()) -> maybe_improper_list(gc(),unicode:chardata()) | {error, unicode:chardata()}.\n"
+ "nfc(Str0) ->\n"
+ " case gc(Str0) of\n"
+ " [GC|R] when GC < 255 -> [GC|R];\n"
+ " [GC|Str] -> [compose(decompose(GC))|Str];\n"
+ " [] -> [];\n"
+ " {error,_}=Error -> Error\n end.\n\n"
+ ),
+
+ io:put_chars(Fd,
+ "-spec nfkc(unicode:chardata()) -> maybe_improper_list(gc(),unicode:chardata()) | {error, unicode:chardata()}.\n"
+ "nfkc(Str0) ->\n"
+ " case gc(Str0) of\n"
+ " [GC|R] when GC < 127 -> [GC|R];\n"
+ " [GC|Str] -> [compose_compat_0(decompose_compat(GC))|Str];\n"
+ " [] -> [];\n"
+ " {error,_}=Error -> Error\n end.\n\n"
+ ),
+
+ io:put_chars(Fd,
+ "decompose(CP) when is_integer(CP), CP < 16#AC00, 16#D7A3 > CP ->\n"
+ " case unicode_table(CP) of\n"
+ " {_,[],_} -> CP;\n"
+ " {_,CPs,_} -> canonical_order(CPs)\n"
+ " end;\n"
+ "decompose(CP) ->\n"
+ " canonical_order(decompose_1(CP)).\n"
+ "\n"
+ "decompose_1(CP) when 16#AC00 =< CP, CP =< 16#D7A3 ->\n"
+ " Syll = CP-16#AC00,\n"
+ " T = 28,\n"
+ " N = 588,\n"
+ " Lead = 16#1100 + Syll div N,\n"
+ " Vowel = 16#1161 + (Syll rem N) div T,\n"
+ " case Syll rem T of\n"
+ " 0 -> [{0,Lead},{0,Vowel}];\n"
+ " Trail -> [{0,Lead}, {0,Vowel}, {0,Trail+16#11A7}]\n"
+ " end;\n"
+ "decompose_1(CP) when is_integer(CP) ->\n"
+ " case unicode_table(CP) of\n"
+ " {CCC, [],_} -> [{CCC,CP}];\n"
+ " {_, CPs, _} -> CPs\n"
+ " end;\n"
+ "decompose_1([CP|CPs]) ->\n"
+ " decompose_1(CP) ++ decompose_1(CPs);\n"
+ "decompose_1([]) -> [].\n"
+ "\n"
+ "canonical_order([{_,CP}]) -> CP;\n"
+ "canonical_order(CPs) ->\n"
+ " canonical_order_1(CPs).\n"
+ "\n"
+ "canonical_order_1([{0,CP}|TaggedCPs]) ->\n"
+ " [CP|canonical_order_1(TaggedCPs)];\n"
+ "canonical_order_1([_|_]=TaggedCPs) ->\n"
+ " canonical_order_2(TaggedCPs, []);\n"
+ "canonical_order_1([]) -> [].\n"
+ "\n"
+ "canonical_order_2([{CCC,_}=First|Cont], Seq) when CCC > 0 ->\n"
+ " canonical_order_2(Cont, [First|Seq]);\n"
+ "canonical_order_2(Cont, Seq) ->\n"
+ " [CP || {_, CP} <- lists:keysort(1,lists:reverse(Seq))] ++ canonical_order_1(Cont).\n\n"),
+
+ io:put_chars(Fd,
+ "decompose_compat(CP) when is_integer(CP), CP < 16#AC00, 16#D7A3 > CP ->\n"
+ " case unicode_table(CP) of\n"
+ " {_, [], []} -> CP;\n"
+ " {_, _, {_,CPs}} -> canonical_order(CPs);\n"
+ " {_, CPs, _} -> canonical_order(CPs)\n"
+ " end;\n"
+ "decompose_compat(CP) ->\n"
+ " canonical_order(decompose_compat_1(CP)).\n"
+ "\n"
+ "decompose_compat_1(CP) when 16#AC00 =< CP, CP =< 16#D7A3 ->\n"
+ " Syll = CP-16#AC00,\n"
+ " T = 28,\n"
+ " N = 588,\n"
+ " Lead = 16#1100 + Syll div N,\n"
+ " Vowel = 16#1161 + (Syll rem N) div T,\n"
+ " case Syll rem T of\n"
+ " 0 -> [{0,Lead},{0,Vowel}];\n"
+ " Trail -> [{0,Lead}, {0,Vowel}, {0,Trail+16#11A7}]\n"
+ " end;\n"
+ "decompose_compat_1(CP) when is_integer(CP) ->\n"
+ " case unicode_table(CP) of\n"
+ " {CCC, [], []} -> [{CCC,CP}];\n"
+ " {_, _, {_,CPs}} -> CPs;\n"
+ " {_, CPs, _} -> CPs\n"
+ " end;\n"
+ "decompose_compat_1([CP|CPs]) ->\n"
+ " decompose_compat_1(CP) ++ decompose_compat_1(CPs);\n"
+ "decompose_compat_1([]) -> [].\n"),
+
+
+ io:put_chars(Fd,
+ "compose(CP) when is_integer(CP) -> CP;\n"
+ "compose([Lead,Vowel|Trail]) %% Hangul\n"
+ " when 16#1100 =< Lead, Lead =< 16#1112 ->\n"
+ " if 16#1161 =< Vowel, Vowel =< 16#1175 ->\n"
+ " CP = 16#AC00 + ((Lead - 16#1100) * 588) + ((Vowel - 16#1161) * 28),\n"
+ " case Trail of\n"
+ " [T|Acc] when 16#11A7 =< T, T =< 16#11C2 -> nolist(CP+T-16#11A7,Acc);\n"
+ " Acc -> nolist(CP,Acc)\n"
+ " end;\n"
+ " true ->\n"
+ " case compose([Vowel|Trail]) of\n"
+ " [_|_] = CPs -> [Lead|CPs];\n"
+ " CP -> [Lead,CP]\n"
+ " end\n"
+ " end;\n"
+ "compose([Base,Accent]=GC0) ->\n"
+ " case compose_pair(Base,Accent) of\n"
+ " false -> GC0;\n"
+ " GC -> GC\n"
+ " end;\n"
+ "compose([CP|Many]) ->\n"
+ " compose_many(Many, CP, [], class(CP)).\n"
+ "\n"
+ "compose_many([CP|Rest], Base, Accents, Prev) ->\n"
+ " Class = class(CP),\n"
+ " case (Prev =:= 0 orelse Prev < Class) andalso compose_pair(Base, CP) of\n"
+ " false -> compose_many(Rest, Base, [CP|Accents], Class);\n"
+ " Combined -> compose_many(Rest, Combined, Accents, Prev)\n"
+ " end;\n"
+ "compose_many([], Base, [], Prev) ->\n"
+ " Base;\n"
+ "compose_many([], Base, Accents, Prev) ->\n"
+ " [Base|lists:reverse(Accents)].\n"
+ "\n\n"),
+ io:put_chars(Fd,
+ "compose_compat_0(CP) when is_integer(CP) ->\n"
+ " CP;\n"
+ "compose_compat_0(L) ->\n"
+ " case gc(L) of\n"
+ " [First|Rest] ->\n"
+ " case compose_compat(First) of\n"
+ " [_|_] = GC -> GC ++ compose_compat_0(Rest);\n"
+ " CP -> [CP|compose_compat_0(Rest)]\n"
+ " end;\n"
+ " [] -> []\n"
+ " end.\n\n"
+ "compose_compat(CP) when is_integer(CP) -> CP;\n"
+ "compose_compat([Lead,Vowel|Trail]) %% Hangul\n"
+ " when 16#1100 =< Lead, Lead =< 16#1112 ->\n"
+ " if 16#1161 =< Vowel, Vowel =< 16#1175 ->\n"
+ " CP = 16#AC00 + ((Lead - 16#1100) * 588) + ((Vowel - 16#1161) * 28),\n"
+ " case Trail of\n"
+ " [T|Acc] when 16#11A7 =< T, T =< 16#11C2 -> nolist(CP+T-16#11A7,Acc);\n"
+ " Acc -> nolist(CP,Acc)\n"
+ " end;\n"
+ " true ->\n"
+ " case compose_compat([Vowel|Trail]) of\n"
+ " [_|_] = CPs -> [Lead|CPs];\n"
+ " CP -> [Lead,CP]\n"
+ " end\n"
+ " end;\n"
+ "compose_compat([Base,Accent]=GC0) ->\n"
+ " case compose_pair(Base,Accent) of\n"
+ " false -> GC0;\n"
+ " GC -> GC\n"
+ " end;\n"
+ "compose_compat([CP|Many]) ->\n"
+ " compose_compat_many(Many, CP, [], class(CP)).\n"
+ "\n"
+ "compose_compat_many([CP|Rest], Base, Accents, Prev) ->\n"
+ " Class = class(CP),\n"
+ " case (Prev =:= 0 orelse Prev < Class) andalso compose_pair(Base, CP) of\n"
+ " false -> compose_compat_many(Rest, Base, [CP|Accents], Class);\n"
+ " Combined -> compose_compat_many(Rest, Combined, Accents, Prev)\n"
+ " end;\n"
+ "compose_compat_many([], Base, [], Prev) ->\n"
+ " Base;\n"
+ "compose_compat_many([], Base, Accents, Prev) ->\n"
+ " [Base|lists:reverse(Accents)].\n"
+ "\n\n"),
+
+ ok.
+
+gen_ws(Fd, Props) ->
+ WS0 = maps:get(pattern_white_space, Props),
+ WS = merge_ranges(WS0, split),
+ io:put_chars(Fd, "%% Useful non-breakable whitespace chars\n"
+ "%% defined as Pattern White Space in Unicode Standard Annex #31\n"),
+ io:put_chars(Fd, "-spec whitespace() -> [gc()].\n"),
+ WsChars = [CP || {CP, undefined} <- WS],
+ io:format(Fd, "whitespace() -> ~w.\n\n", [[[$\r,$\n]|WsChars]]),
+
+ io:put_chars(Fd, "-spec is_whitespace(gc()) -> boolean().\n"),
+ IsWS = fun(Range) -> io:format(Fd, "is_whitespace~s true;\n", [gen_single_clause(Range)]) end,
+ io:format(Fd, "is_whitespace([13,10]) -> true;\n", []),
+ [IsWS(CP) || CP <- WS],
+ io:put_chars(Fd, "is_whitespace(_) -> false.\n\n"),
+ ok.
+
+gen_cp(Fd) ->
+ io:put_chars(Fd, "-spec cp(String::unicode:chardata()) ->"
+ " maybe_improper_list() | {error, unicode:chardata()}.\n"),
+ io:put_chars(Fd, "cp([C|_]=L) when is_integer(C) -> L;\n"),
+ io:put_chars(Fd, "cp([List]) -> cp(List);\n"),
+ io:put_chars(Fd, "cp([List|R]) ->\n"),
+ io:put_chars(Fd, " case cp(List) of\n"),
+ io:put_chars(Fd, " [] -> cp(R);\n"),
+ io:put_chars(Fd, " [CP] -> [CP|R];\n"),
+ io:put_chars(Fd, " [C|R0] -> [C|[R0|R]];\n"),
+ io:put_chars(Fd, " {error,Error} -> {error,[Error|R]}\n"),
+ io:put_chars(Fd, " end;\n"),
+ io:put_chars(Fd, "cp([]) -> [];\n"),
+ io:put_chars(Fd, "cp(<<C/utf8, R/binary>>) -> [C|R];\n"),
+ io:put_chars(Fd, "cp(<<>>) -> [];\n"),
+ io:put_chars(Fd, "cp(<<R/binary>>) -> {error,R}.\n\n"),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+gen_gc(Fd, GBP) ->
+ %% see http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules
+ io:put_chars(Fd,
+ "-spec gc(String::unicode:chardata()) ->"
+ " maybe_improper_list() | {error, unicode:chardata()}.\n"),
+ io:put_chars(Fd,
+ "gc(Str) ->\n"
+ " gc_1(cp(Str)).\n\n"
+ "gc_1([$\\r|R0] = R) ->\n"
+ " case cp(R0) of % Don't break CRLF\n"
+ " [$\\n|R1] -> [[$\\r,$\\n]|R1];\n"
+ " _ -> R\n"
+ " end;\n"),
+
+ io:put_chars(Fd, "%% Handle control\n"),
+ GenControl = fun(Range) -> io:format(Fd, "gc_1~s R0;\n", [gen_clause(Range)]) end,
+ CRs0 = merge_ranges(maps:get(cr, GBP) ++ maps:get(lf, GBP) ++ maps:get(control, GBP), false),
+ [R1,R2,R3|Crs] = CRs0,
+ [GenControl(CP) || CP <- merge_ranges([R1,R2,R3], split), CP =/= {$\r, undefined}],
+ %%GenControl(R1),GenControl(R2),GenControl(R3),
+ io:format(Fd, "gc_1([CP|R]) when CP < 255 -> gc_extend(R,CP);\n", []),
+ [GenControl(CP) || CP <- Crs],
+ %% One clause per CP
+ %% CRs0 = merge_ranges(maps:get(cr, GBP) ++ maps:get(lf, GBP) ++ maps:get(control, GBP)),
+ %% [GenControl(CP) || CP <- CRs0, CP =/= {$\r, undefined}],
+
+ io:put_chars(Fd, "%% Handle ZWJ\n"),
+ GenZWJ = fun(Range) -> io:format(Fd, "gc_1~s gc_zwj(R1, [CP]);\n", [gen_clause(Range)]) end,
+ [GenZWJ(CP) || CP <- merge_ranges(maps:get(zwj,GBP))],
+
+ io:put_chars(Fd, "%% Handle prepend\n"),
+ GenPrepend = fun(Range) -> io:format(Fd, "gc_1~s gc_prepend(R1, CP);\n", [gen_clause(Range)]) end,
+ [GenPrepend(CP) || CP <- merge_ranges(maps:get(prepend,GBP))],
+
+ io:put_chars(Fd, "%% Handle Hangul L\n"),
+ GenHangulL = fun(Range) -> io:format(Fd, "gc_1~s gc_h_L(R1,[CP]);\n", [gen_clause(Range)]) end,
+ [GenHangulL(CP) || CP <- merge_ranges(maps:get(l,GBP))],
+ io:put_chars(Fd, "%% Handle Hangul V\n"),
+ GenHangulV = fun(Range) -> io:format(Fd, "gc_1~s gc_h_V(R1,[CP]);\n", [gen_clause(Range)]) end,
+ [GenHangulV(CP) || CP <- merge_ranges(maps:get(v,GBP))],
+ io:put_chars(Fd, "%% Handle Hangul T\n"),
+ GenHangulT = fun(Range) -> io:format(Fd, "gc_1~s gc_h_T(R1,[CP]);\n", [gen_clause(Range)]) end,
+ [GenHangulT(CP) || CP <- merge_ranges(maps:get(t,GBP))],
+ io:put_chars(Fd, "%% Handle Hangul LV and LVT special, since they are large\n"),
+ io:put_chars(Fd, "gc_1([CP|_]=R0) when 44000 < CP, CP < 56000 -> gc_h_lv_lvt(R0, []);\n"),
+
+ io:put_chars(Fd, "%% Handle Regional\n"),
+ GenRegional = fun(Range) -> io:format(Fd, "gc_1~s gc_regional(R1,[CP]);\n", [gen_clause(Range)]) end,
+ [GenRegional(CP) || CP <- merge_ranges(maps:get(regional_indicator,GBP))],
+ io:put_chars(Fd, "%% Handle E_Base\n"),
+ GenEBase = fun(Range) -> io:format(Fd, "gc_1~s gc_e_cont(R1,[CP]);\n", [gen_clause(Range)]) end,
+ [GenEBase(CP) || CP <- merge_ranges(maps:get(e_base,GBP))],
+ io:put_chars(Fd, "%% Handle EBG\n"),
+ GenEBG = fun(Range) -> io:format(Fd, "gc_1~s gc_e_cont(R1,[CP]);\n", [gen_clause(Range)]) end,
+ [GenEBG(CP) || CP <- merge_ranges(maps:get(e_base_gaz,GBP))],
+
+ io:put_chars(Fd, "gc_1([CP|R]) -> gc_extend(R, CP);\n"),
+ io:put_chars(Fd, "gc_1([]) -> [];\n"),
+ io:put_chars(Fd, "gc_1({error,_}=Error) -> Error.\n\n"),
+
+ io:put_chars(Fd, "%% Handle Prepend\n"),
+ io:put_chars(Fd,
+ "gc_prepend(R00, CP0) ->\n"
+ " case cp(R00) of\n"
+ " [CP1|_] = R0 ->\n"
+ " case is_control(CP1) of\n"
+ " true -> [CP0|R00];\n"
+ " false ->\n"
+ " case gc_1(R0) of\n"
+ " [GC|R1] when is_integer(GC) -> [[CP0,GC]|R1];\n"
+ " [GC|R1] -> [[CP0|GC]|R1]\n"
+ " end\n"
+ " end;\n"
+ " [] -> [CP0];\n"
+ " {error,R} -> [CP0|R]\n"
+ " end.\n\n"),
+
+ IsCtrl = fun(Range) -> io:format(Fd, "is_control~s true;\n", [gen_single_clause(Range)]) end,
+ [IsCtrl(CP) || CP <- merge_ranges(maps:get(cr, GBP) ++ maps:get(lf, GBP) ++ maps:get(control, GBP))],
+ io:put_chars(Fd, "is_control(_) -> false.\n\n"),
+
+ io:put_chars(Fd, "%% Handle Extend\n"
+ "%% To simplify binary handling in libraries the tail should be kept binary\n"
+ "%% and not a lookahead CP\n"
+ ),
+ io:put_chars(Fd, "gc_extend(T, Acc) ->\n"
+ " gc_extend(cp(T), T, Acc).\n\n"),
+ io:put_chars(Fd,
+ "gc_extend([CP|T], T0, Acc0) ->\n"
+ " case is_extend(CP) of\n"
+ " zwj ->\n"
+ " case Acc0 of\n"
+ " [_|_] -> gc_zwj(T, [CP|Acc0]);\n"
+ " Acc -> gc_zwj(T, [CP,Acc])\n"
+ " end;\n"
+ " true ->\n"
+ " case Acc0 of\n"
+ " [_|_] -> gc_extend(T, [CP|Acc0]);\n"
+ " Acc -> gc_extend(T, [CP,Acc])\n"
+ " end;\n"
+ " false ->\n"
+ " case Acc0 of\n"
+ " [Acc] -> [Acc|T0];\n"
+ " [_|_]=Acc -> [lists:reverse(Acc)|T0];\n"
+ " Acc -> [Acc|T0]\n"
+ " end\n"
+ " end;\n"
+ "gc_extend([], _, Acc0) ->\n"
+ " case Acc0 of\n"
+ " [_]=Acc -> Acc;\n"
+ " [_|_]=Acc -> [lists:reverse(Acc)];\n"
+ " Acc -> [Acc]\n"
+ " end;\n"
+ "gc_extend({error,R}, T, Acc0) ->\n"
+ " gc_extend([], T, Acc0) ++ [R].\n\n"
+ ),
+ [ZWJ] = maps:get(zwj, GBP),
+ GenExtend = fun(R) when R =:= ZWJ -> io:format(Fd, "is_extend~s zwj;\n", [gen_single_clause(ZWJ)]);
+ (Range) -> io:format(Fd, "is_extend~s true;\n", [gen_single_clause(Range)])
+ end,
+ Extends = merge_ranges(maps:get(extend,GBP)++maps:get(spacingmark, GBP) ++ maps:get(zwj, GBP), split),
+ [GenExtend(CP) || CP <- Extends],
+ io:put_chars(Fd, "is_extend(_) -> false.\n\n"),
+
+ io:put_chars(Fd,
+ "gc_e_cont(R0, Acc) ->\n"
+ " case cp(R0) of\n"
+ " [CP|R1] ->\n"
+ " case is_extend(CP) of\n"
+ " zwj -> gc_zwj(R1, [CP|Acc]);\n"
+ " true -> gc_e_cont(R1, [CP|Acc]);\n"
+ " false ->\n"
+ " case is_emodifier(CP) of\n"
+ " true -> [lists:reverse([CP|Acc])|R1];\n"
+ " false ->\n"
+ " case Acc of\n"
+ " [A] -> [A|R0];\n"
+ " _ -> [lists:reverse(Acc)|R0]\n"
+ " end\n"
+ " end\n"
+ " end;\n"
+ " [] ->\n"
+ " case Acc of\n"
+ " [A] -> [A];\n"
+ " _ -> [lists:reverse(Acc)]\n"
+ " end;\n"
+ " {error,R} ->\n"
+ " case Acc of\n"
+ " [A] -> [A|R];\n"
+ " _ -> [lists:reverse(Acc)|R]\n"
+ " end\n"
+ " end.\n\n"),
+
+ GenEMod = fun(Range) -> io:format(Fd, "is_emodifier~s true;\n", [gen_single_clause(Range)]) end,
+ EMods = merge_ranges(maps:get(e_modifier, GBP), split),
+ [GenEMod(CP) || CP <- EMods],
+ io:put_chars(Fd, "is_emodifier(_) -> false.\n\n"),
+
+ io:put_chars(Fd, "gc_zwj(R0, Acc) ->\n case cp(R0) of\n"),
+ GenZWJGlue = fun(Range) -> io:format(Fd, "~8c~s gc_extend(R1, R0, [CP|Acc]);\n",
+ [$\s,gen_case_clause(Range)]) end,
+ [GenZWJGlue(CP) || CP <- merge_ranges(maps:get(glue_after_zwj,GBP))],
+ GenZWJEBG = fun(Range) -> io:format(Fd, "~8c~s gc_e_cont(R1, [CP|Acc]);\n",
+ [$\s,gen_case_clause(Range)]) end,
+ [GenZWJEBG(CP) || CP <- merge_ranges(maps:get(e_base_gaz,GBP))],
+ io:put_chars(Fd," R1 -> gc_extend(R1, R0, Acc)\n"
+ " end.\n\n"),
+
+
+ %% --------------------
+ io:put_chars(Fd, "%% Handle Regional\n"),
+ [{RLess,RLarge}] = merge_ranges(maps:get(regional_indicator,GBP)),
+ io:put_chars(Fd,"gc_regional(R0, Acc) ->\n"
+ " case cp(R0) of\n"),
+ io:format(Fd, " [CP|R1] when ~w =< CP,CP =< ~w-> gc_extend(R1,[CP|Acc]);~n",[RLess, RLarge]),
+ io:put_chars(Fd," R1 -> gc_extend(R1, R0, Acc)\n"
+ " end.\n\n"),
+
+ %% Special hangul
+ io:put_chars(Fd, "%% Handle Hangul L\n"),
+ io:put_chars(Fd, "gc_h_L(R0, Acc) ->\n case cp(R0) of\n"),
+ GenHangulL_1 = fun(Range) -> io:format(Fd, "~8c~s gc_h_L(R1,[CP|Acc]);\n",
+ [$\s,gen_case_clause(Range)]) end,
+ [GenHangulL_1(CP) || CP <- merge_ranges(maps:get(l,GBP))],
+ GenHangulL_2 = fun(Range) -> io:format(Fd, "~8c~s gc_h_V(R1,[CP|Acc]);\n",
+ [$\s,gen_case_clause(Range)]) end,
+ [GenHangulL_2(CP) || CP <- merge_ranges(maps:get(v,GBP))],
+ io:put_chars(Fd, " R1 -> gc_h_lv_lvt(R1, Acc)\n end.\n\n"),
+
+ io:put_chars(Fd, "%% Handle Hangul V\n"),
+ io:put_chars(Fd, "gc_h_V(R0, Acc) ->\n case cp(R0) of\n"),
+ GenHangulV_1 = fun(Range) -> io:format(Fd, "~8c~s gc_h_V(R1,[CP|Acc]);\n",
+ [$\s,gen_case_clause(Range)]) end,
+ [GenHangulV_1(CP) || CP <- merge_ranges(maps:get(v,GBP))],
+ GenHangulV_2 = fun(Range) -> io:format(Fd, "~8c~s gc_h_T(R1,[CP|Acc]);\n",
+ [$\s,gen_case_clause(Range)]) end,
+ [GenHangulV_2(CP) || CP <- merge_ranges(maps:get(t,GBP))],
+ io:put_chars(Fd, " R1 -> gc_extend(R1, R0, Acc)\n end.\n\n"),
+
+ io:put_chars(Fd, "%% Handle Hangul T\n"),
+ io:put_chars(Fd, "gc_h_T(R0, Acc) ->\n case cp(R0) of\n"),
+ GenHangulT_1 = fun(Range) -> io:format(Fd, "~8c~s gc_h_T(R1,[CP|Acc]);\n",
+ [$\s,gen_case_clause(Range)]) end,
+ [GenHangulT_1(CP) || CP <- merge_ranges(maps:get(t,GBP))],
+ io:put_chars(Fd, " R1 -> gc_extend(R1, R0, Acc)\n end.\n\n"),
+
+ io:put_chars(Fd, "gc_h_lv_lvt({error,_}=Error, Acc) -> gc_extend(Error, [], Acc);\n"),
+ io:put_chars(Fd, "%% Handle Hangul LV\n"),
+ GenHangulLV = fun(Range) -> io:format(Fd, "gc_h_lv_lvt~s gc_h_V(R1,[CP|Acc]);\n",
+ [gen_clause2(Range)]) end,
+ [GenHangulLV(CP) || CP <- merge_ranges(maps:get(lv,GBP))],
+ io:put_chars(Fd, "%% Handle Hangul LVT\n"),
+ GenHangulLVT = fun(Range) -> io:format(Fd, "gc_h_lv_lvt~s gc_h_T(R1,[CP|Acc]);\n",
+ [gen_clause2(Range)]) end,
+ [GenHangulLVT(CP) || CP <- merge_ranges(maps:get(lvt,GBP))],
+ io:put_chars(Fd, "gc_h_lv_lvt([CP|R], []) -> gc_extend(R, CP);\n"), %% From gc_1/1
+ io:put_chars(Fd, "gc_h_lv_lvt(R, Acc) -> gc_extend(R, Acc).\n\n"),
+ ok.
+
+gen_compose_pairs(Fd, ExclData, Data) ->
+ GetPairs =
+ fun(CP, #cp{dec=[DCP,_]=Pair}, Acc) ->
+ case array:get(DCP,Data) of
+ #cp{class=0} -> [{Pair, CP}|Acc];
+ #cp{} -> Acc %% Ignore Non-Starter Decompositions
+ end;
+ (_, _, Acc) -> Acc
+ end,
+ DeCmp2 = array:sparse_foldl(GetPairs, [], ExclData),
+ [io:format(Fd, "compose_pair(~w,~w) -> ~w;~n", [A,B,CP]) || {[A,B],CP} <- lists:sort(DeCmp2)],
+ io:put_chars(Fd, "compose_pair(_,_) -> false.\n\n"),
+
+ io:put_chars(Fd, "nolist(CP, []) -> CP;\nnolist(CP,L) -> [CP|L].\n\n"),
+ ok.
+
+gen_case_table(Fd, Data) ->
+ Case = array:foldr(fun(CP, #cp{cs={U0,L0,T0,F0}}, Acc) ->
+ U = def_cp(U0,CP),
+ L = def_cp(L0,CP),
+ T = def_cp(T0,CP),
+ F = def_cp(F0,CP),
+ case T =:= U andalso F =:= L of
+ true ->
+ [{CP,{U,L}}|Acc];
+ false ->
+ [{CP,{U,L,T,F}}|Acc]
+ end;
+ (_CP, _, Acc) -> Acc
+ end, [], Data),
+ [io:format(Fd, "case_table(~w) -> ~w;\n", [CP, Map])|| {CP,Map} <- Case],
+ io:format(Fd, "case_table(CP) -> {CP, CP}.\n\n",[]),
+ ok.
+
+def_cp([], CP) -> CP;
+def_cp(CP, _) -> CP.
+
+gen_unicode_table(Fd, Data) ->
+ FixCanon = fun(_, #cp{class=CCC, dec=Dec, comp=Comp}) ->
+ Canon = decompose(Dec,Data),
+ #{ccc=>CCC, canonical=>Canon, compat=>Comp}
+ end,
+ AofMaps0 = array:sparse_map(FixCanon, Data),
+ FixCompat = fun(_, #{ccc:=CCC, canonical:=Canon, compat:=Comp}) ->
+ Compat = decompose_compat(Canon, Comp, AofMaps0),
+ {CCC, Canon, Compat}
+ end,
+ AofMaps1 = array:sparse_map(FixCompat, AofMaps0),
+
+ Dict0 = array:sparse_to_orddict(AofMaps1),
+ Def = {0, [], []},
+ Dict = lists:filter(fun({_, Map}) -> Map =/= Def end, Dict0),
+
+ [io:format(Fd, "unicode_table(~w) -> ~w;~n", [CP, Map]) || {CP,Map} <- Dict],
+ io:format(Fd, "unicode_table(_) -> ~w.~n~n",[Def]),
+ ok.
+
+decompose([], _Data) -> [];
+decompose([CP|CPs], Data) when is_integer(CP) ->
+ case array:get(CP,Data) of
+ undefined -> [{0,CP}|decompose(CPs,Data)];
+ #cp{class=CCC, dec=[]} -> [{CCC,CP}|decompose(CPs,Data)];
+ #cp{dec=Dec} -> decompose(Dec, Data) ++ decompose(CPs,Data)
+ end.
+
+
+decompose_compat(Canon, [], Data) ->
+ case decompose_compat(Canon, Data) of
+ Canon -> [];
+ Other -> {compat, Other}
+ end;
+decompose_compat([], {CompatMode, CPs}, Data) ->
+ {CompatMode, decompose_compat(CPs, Data)}.
+
+decompose_compat([], _Data) -> [];
+decompose_compat([CP|CPs], Data) when is_integer(CP) ->
+ case array:get(CP,Data) of
+ undefined ->
+ [{0,CP}|decompose_compat(CPs,Data)];
+ #{ccc:=CCC, canonical:=[], compat:=[]} ->
+ [{CCC,CP}|decompose_compat(CPs,Data)];
+ #{canonical:=[], compat:={_,Dec}} ->
+ decompose_compat(Dec, Data) ++ decompose_compat(CPs,Data);
+ #{canonical:=Dec} ->
+ decompose_compat(Dec, Data) ++ decompose_compat(CPs,Data)
+ end;
+decompose_compat([{_,CP}|CPs], Data) ->
+ decompose_compat([CP|CPs], Data).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+gen_clause({R0, undefined}) ->
+ io_lib:format("([~w=CP|R1]=R0) ->", [R0]);
+gen_clause({R0, R1}) ->
+ io_lib:format("([CP|R1]=R0) when ~w =< CP, CP =< ~w ->", [R0,R1]).
+
+gen_clause2({R0, undefined}) ->
+ io_lib:format("([~w=CP|R1], Acc) ->", [R0]);
+gen_clause2({R0, R1}) ->
+ io_lib:format("([CP|R1], Acc) when ~w =< CP, CP =< ~w ->", [R0,R1]).
+
+gen_case_clause({R0, undefined}) ->
+ io_lib:format("[~w=CP|R1] ->", [R0]);
+gen_case_clause({R0, R1}) ->
+ io_lib:format("[CP|R1] when ~w =< CP, CP =< ~w ->", [R0,R1]).
+
+
+gen_single_clause({R0, undefined}) ->
+ io_lib:format("(~w) ->", [R0]);
+gen_single_clause({R0, R1}) ->
+ io_lib:format("(CP) when ~w =< CP, CP =< ~w ->", [R0,R1]).
+
+
+merge_ranges(List) ->
+ merge_ranges(List, true).
+
+merge_ranges(List, Opt) ->
+ Res0 = merge_ranges_1(lists:sort(List), []),
+ case Opt of
+ split ->
+ split_ranges(Res0,[]); % One clause per CP
+ true ->
+ Res = Res0,
+ OptRes = optimize_ranges(Res),
+ true = lists:sort(Res) =:= lists:sort(OptRes), %Assertion.
+ OptRes;
+ false ->
+ Res0
+ end.
+
+merge_ranges_1([{Next, Stop}|R], [{Start,undefined}|Acc]) when Start+1 =:= Next ->
+ case Stop of
+ undefined -> merge_ranges_1(R, [{Start, Next}|Acc]);
+ _ -> merge_ranges_1(R, [{Start,Stop}|Acc])
+ end;
+merge_ranges_1([{Next, Stop}|R], [{Start,Prev}|Acc]) when Prev+1 =:= Next ->
+ case Stop of
+ undefined -> merge_ranges_1(R, [{Start, Next}|Acc]);
+ _ -> merge_ranges_1(R, [{Start,Stop}|Acc])
+ end;
+merge_ranges_1([{Next, Stop}|R], [{Start,undefined}|Acc]) when Start+1 =:= Next ->
+ case Stop of
+ undefined -> merge_ranges_1(R, [{Start, Next}|Acc]);
+ _ -> merge_ranges_1(R, [{Start,Stop}|Acc])
+ end;
+merge_ranges_1([Next|R], Acc) ->
+ merge_ranges_1(R, [Next|Acc]);
+merge_ranges_1([], Acc) ->
+ lists:reverse(Acc).
+
+split_ranges([{_,undefined}=CP|Rs], Acc) ->
+ split_ranges(Rs,[CP|Acc]);
+split_ranges([{F,L}|Rs], Acc) when F < L ->
+ split_ranges([{F+1,L}|Rs],[{F,undefined}|Acc]);
+split_ranges([{L,L}|Rs], Acc) ->
+ split_ranges(Rs,[{L, undefined}|Acc]);
+split_ranges([], Acc) ->
+ lists:reverse(Acc).
+
+optimize_ranges(Rs0) ->
+ PF = fun({N,undefined}) when is_integer(N) -> true;
+ (_) -> false
+ end,
+ {Singles,Rs} = lists:partition(PF, Rs0),
+ Singles ++ optimize_ranges_1(Rs).
+
+optimize_ranges_1(Rs) ->
+ case length(Rs) of
+ N when N >= 4 ->
+ {R0,[Mid|R1]} = lists:split(N div 2, Rs),
+ [Mid|optimize_ranges_1(R0)++optimize_ranges_1(R1)];
+ _ ->
+ Rs
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+hex_to_int([]) -> [];
+hex_to_int(HexStr) ->
+ list_to_integer(string:strip(HexStr, both), 16).
+
+to_atom(Str) ->
+ list_to_atom(string:to_lower(string:strip(Str, both))).
+
+foldl(Fun, Acc, Fd) ->
+ Get = fun() -> file:read_line(Fd) end,
+ foldl_1(Fun, Acc, Get).
+
+foldl_1(_Fun, {done, Acc}, _Get) -> Acc;
+foldl_1(Fun, Acc, Get) ->
+ case Get() of
+ eof -> Acc;
+ {ok, "#" ++ _} -> %% Ignore comments
+ foldl_1(Fun, Acc, Get);
+ {ok, "\n"} -> %% Ignore empty lines
+ foldl_1(Fun, Acc, Get);
+ {ok, Line} ->
+ foldl_1(Fun, Fun(Line, Acc), Get)
+ end.
+
+
+
+%% Differs from string:tokens, it returns empty string as token between two delimiters
+tokens(S, [C]) ->
+ tokens(lists:reverse(S), C, []).
+
+tokens([Sep|S], Sep, Toks) ->
+ tokens(S, Sep, [[]|Toks]);
+tokens([C|S], Sep, Toks) ->
+ tokens_2(S, Sep, Toks, [C]);
+tokens([], _, Toks) ->
+ Toks.
+
+tokens_2([Sep|S], Sep, Toks, Tok) ->
+ tokens(S, Sep, [Tok|Toks]);
+tokens_2([C|S], Sep, Toks, Tok) ->
+ tokens_2(S, Sep, Toks, [C|Tok]);
+tokens_2([], _Sep, Toks, Tok) ->
+ [Tok|Toks].
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index 46e3ceac03..f062c7fe6e 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1 +1 @@
-STDLIB_VSN = 3.0
+STDLIB_VSN = 3.4
diff --git a/lib/syntax_tools/AUTHORS b/lib/syntax_tools/AUTHORS
deleted file mode 100644
index 0212787b30..0000000000
--- a/lib/syntax_tools/AUTHORS
+++ /dev/null
@@ -1,2 +0,0 @@
-Original Authors and Contributors:
-
diff --git a/lib/syntax_tools/COPYING b/lib/syntax_tools/COPYING
deleted file mode 100644
index 223ede7de3..0000000000
--- a/lib/syntax_tools/COPYING
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/lib/syntax_tools/doc/specs/.gitignore b/lib/syntax_tools/doc/specs/.gitignore
new file mode 100644
index 0000000000..322eebcb06
--- /dev/null
+++ b/lib/syntax_tools/doc/specs/.gitignore
@@ -0,0 +1 @@
+specs_*.xml
diff --git a/lib/syntax_tools/doc/src/Makefile b/lib/syntax_tools/doc/src/Makefile
index ff4f3f78ff..e55222e59c 100644
--- a/lib/syntax_tools/doc/src/Makefile
+++ b/lib/syntax_tools/doc/src/Makefile
@@ -81,10 +81,15 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
+SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml)
+
+TOP_SPECS_FILE = specs.xml
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
XML_FLAGS +=
+SPECS_FLAGS = -I../../include
DVIPS_FLAGS +=
# ----------------------------------------------------
@@ -93,7 +98,7 @@ DVIPS_FLAGS +=
$(HTMLDIR)/%.gif: %.gif
$(INSTALL_DATA) $< $@
-docs: pdf html man
+docs: man pdf html
$(TOP_PDF_FILE): $(XML_FILES)
@@ -120,6 +125,7 @@ clean clean_docs:
rm -f $(MAN3DIR)/*
rm -f $(XML_REF3_FILES) $(XML_CHAPTER_FILES) *.html
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f $(SPECDIR)/*
rm -f errs core *~
# ----------------------------------------------------
diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml
index ef207f7c3d..f85d963919 100644
--- a/lib/syntax_tools/doc/src/notes.xml
+++ b/lib/syntax_tools/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2007</year><year>2016</year>
+ <year>2007</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,6 +32,71 @@
<p>This document describes the changes made to the Syntax_Tools
application.</p>
+<section><title>Syntax_Tools 2.1.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Miscellaneous updates due to atoms containing
+ arbitrary Unicode characters. </p>
+ <p>
+ Own Id: OTP-14285</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Syntax_Tools 2.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The address to the FSF in the license header has been
+ updated.</p>
+ <p>
+ Own Id: OTP-14084</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Syntax_Tools 2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix a bug where <c>erl_tidy</c> crashed on the tilde
+ character when printing to standard output. </p>
+ <p>
+ Own Id: OTP-13725 Aux Id: ERL-151, PR-1071 </p>
+ </item>
+ <item>
+ <p><c>merl_transform</c> could get into an infinite loop
+ when syntactically incorrect text was passed to a
+ <c>merl:qquote/2,3</c> call.</p>
+ <p>
+ Own Id: OTP-13755</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Improve types and specs in OTP documentation generated
+ from Erlang source files. </p>
+ <p>
+ Own Id: OTP-13720 Aux Id: ERL-120 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Syntax_Tools 2.0</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/syntax_tools/doc/src/specs.xml b/lib/syntax_tools/doc/src/specs.xml
new file mode 100644
index 0000000000..04c3a494e7
--- /dev/null
+++ b/lib/syntax_tools/doc/src/specs.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<specs xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="../specs/specs_epp_dodger.xml"/>
+ <xi:include href="../specs/specs_erl_comment_scan.xml"/>
+ <xi:include href="../specs/specs_erl_prettypr.xml"/>
+ <xi:include href="../specs/specs_erl_recomment.xml"/>
+ <xi:include href="../specs/specs_erl_syntax.xml"/>
+ <xi:include href="../specs/specs_erl_syntax_lib.xml"/>
+ <xi:include href="../specs/specs_erl_tidy.xml"/>
+ <xi:include href="../specs/specs_igor.xml"/>
+ <xi:include href="../specs/specs_merl.xml"/>
+ <xi:include href="../specs/specs_merl_transform.xml"/>
+ <xi:include href="../specs/specs_prettypr.xml"/>
+</specs>
diff --git a/lib/syntax_tools/src/epp_dodger.erl b/lib/syntax_tools/src/epp_dodger.erl
index 39c522fd11..cf1ba0abfa 100644
--- a/lib/syntax_tools/src/epp_dodger.erl
+++ b/lib/syntax_tools/src/epp_dodger.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2001-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/syntax_tools/src/erl_comment_scan.erl b/lib/syntax_tools/src/erl_comment_scan.erl
index 03429d4d42..a7a2c10b79 100644
--- a/lib/syntax_tools/src/erl_comment_scan.erl
+++ b/lib/syntax_tools/src/erl_comment_scan.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% =====================================================================
%% @copyright 1997-2006 Richard Carlsson
@@ -30,8 +35,14 @@
%% =====================================================================
--type comment() :: {integer(), integer(), integer(), [string()]}.
--type commentLine() :: {integer(), integer(), integer(), string()}.
+-type comment() :: {Line:: integer(),
+ Column:: integer(),
+ Indentation :: integer(),
+ Text :: [string()]}.
+-type commentLine() :: {Line :: integer(),
+ Column :: integer(),
+ Indent :: integer(),
+ Text :: string()}.
%% =====================================================================
%% @spec file(FileName::file:filename()) -> [Comment]
diff --git a/lib/syntax_tools/src/erl_prettypr.erl b/lib/syntax_tools/src/erl_prettypr.erl
index f1615b2610..40ddd2b22a 100644
--- a/lib/syntax_tools/src/erl_prettypr.erl
+++ b/lib/syntax_tools/src/erl_prettypr.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1997-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -195,10 +200,16 @@ format(Node) ->
%% =====================================================================
%% @spec format(Tree::syntaxTree(), Options::[term()]) -> string()
-%% syntaxTree() = erl_syntax:syntaxTree()
%%
-%% @type hook() = (syntaxTree(), context(), Continuation) -> document()
-%% Continuation = (syntaxTree(), context()) -> document().
+%% @type syntaxTree() = erl_syntax:syntaxTree().
+%%
+%% An abstract syntax tree. See the {@link erl_syntax} module for
+%% details.
+%%
+%% @type hook() = (syntaxTree(), context(), Continuation) ->
+%% prettypr:document()
+%% Continuation = (syntaxTree(), context()) ->
+%% prettypr:document().
%%
%% A call-back function for user-controlled formatting. See {@link
%% format/2}.
@@ -277,7 +288,7 @@ format(Node, Options) ->
%% =====================================================================
-%% @spec best(Tree::syntaxTree()) -> empty | document()
+%% @spec best(Tree::syntaxTree()) -> empty | prettypr:document()
%% @equiv best(Tree, [])
-spec best(erl_syntax:syntaxTree()) -> 'empty' | prettypr:document().
@@ -288,7 +299,7 @@ best(Node) ->
%% =====================================================================
%% @spec best(Tree::syntaxTree(), Options::[term()]) ->
-%% empty | document()
+%% empty | prettypr:document()
%%
%% @doc Creates a fixed "best" abstract layout for a syntax tree. This
%% is similar to the `layout/2' function, except that here, the final
@@ -310,7 +321,7 @@ best(Node, Options) ->
%% =====================================================================
-%% @spec layout(Tree::syntaxTree()) -> document()
+%% @spec layout(Tree::syntaxTree()) -> prettypr:document()
%% @equiv layout(Tree, [])
-spec layout(erl_syntax:syntaxTree()) -> prettypr:document().
@@ -320,8 +331,7 @@ layout(Node) ->
%% =====================================================================
-%% @spec layout(Tree::syntaxTree(), Options::[term()]) -> document()
-%% document() = prettypr:document()
+%% @spec layout(Tree::syntaxTree(), Options::[term()]) -> prettypr:document()
%%
%% @doc Creates an abstract document layout for a syntax tree. The
%% result represents a set of possible layouts (cf. module `prettypr').
@@ -442,7 +452,7 @@ lay_2(Node, Ctxt) ->
text(erl_syntax:variable_literal(Node));
atom ->
- text(erl_syntax:atom_literal(Node));
+ text(erl_syntax:atom_literal(Node, Ctxt#ctxt.encoding));
integer ->
text(erl_syntax:integer_literal(Node));
diff --git a/lib/syntax_tools/src/erl_recomment.erl b/lib/syntax_tools/src/erl_recomment.erl
index c1141b2bc6..4d9aaf4eed 100644
--- a/lib/syntax_tools/src/erl_recomment.erl
+++ b/lib/syntax_tools/src/erl_recomment.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1997-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -30,6 +35,9 @@
-export([recomment_forms/2, quick_recomment_forms/2, recomment_tree/2]).
+%% @type syntaxTree() = erl_syntax:syntaxTree(). An abstract syntax
+%% tree. See the {@link erl_syntax} module for details.
+
%% =====================================================================
%% @spec quick_recomment_forms(Forms, Comments::[Comment]) ->
%% syntaxTree()
@@ -55,7 +63,6 @@ quick_recomment_forms(Tree, Cs) ->
%% =====================================================================
%% @spec recomment_forms(Forms, Comments::[Comment]) -> syntaxTree()
%%
-%% syntaxTree() = erl_syntax:syntaxTree()
%% Forms = syntaxTree() | [syntaxTree()]
%% Comment = {Line, Column, Indentation, Text}
%% Line = integer()
diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl
index ee42e56172..9b2b503762 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1997-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -134,6 +139,7 @@
is_atom/2,
atom_value/1,
atom_literal/1,
+ atom_literal/2,
atom_name/1,
attribute/1,
attribute/2,
@@ -1836,7 +1842,7 @@ char_literal(Node) ->
%% @doc Returns the literal string represented by a `char'
%% node. This includes the leading "`$'" character.
%% Depending on the encoding a character beyond 255 will be escaped
-%% ('latin1') or copied as is ('utf8').
+%% (`latin1') or copied as is (`utf8').
%%
%% @see char/1
@@ -1939,7 +1945,7 @@ string_literal(Node) ->
%% @doc Returns the literal string represented by a `string'
%% node. This includes surrounding double-quote characters.
%% Depending on the encoding characters beyond 255 will be escaped
-%% ('latin1') or copied as is ('utf8').
+%% (`latin1') or copied as is (`utf8').
%%
%% @see string/1
@@ -1960,6 +1966,7 @@ string_literal(Node, latin1) ->
%% @see atom_value/1
%% @see atom_name/1
%% @see atom_literal/1
+%% @see atom_literal/2
%% @see is_atom/2
%% type(Node) = atom
@@ -2032,6 +2039,7 @@ atom_name(Node) ->
%% =====================================================================
%% @doc Returns the literal string represented by an `atom'
%% node. This includes surrounding single-quote characters if necessary.
+%% Characters beyond 255 will be escaped.
%%
%% Note that e.g. the result of `atom("x\ny")' represents
%% any and all of `'x\ny'', `'x\12y'',
@@ -2043,8 +2051,24 @@ atom_name(Node) ->
-spec atom_literal(syntaxTree()) -> string().
atom_literal(Node) ->
- io_lib:write_atom(atom_value(Node)).
+ atom_literal(Node, latin1).
+
+%% =====================================================================
+%% @doc Returns the literal string represented by an `atom'
+%% node. This includes surrounding single-quote characters if necessary.
+%% Depending on the encoding a character beyond 255 will be escaped
+%% (`latin1') or copied as is (`utf8').
+%%
+%% @see atom/1
+%% @see atom_literal/1
+%% @see string/1
+atom_literal(Node, utf8) ->
+ io_lib:write_atom(atom_value(Node));
+atom_literal(Node, unicode) ->
+ io_lib:write_atom(atom_value(Node));
+atom_literal(Node, latin1) ->
+ io_lib:write_atom_as_latin1(atom_value(Node)).
%% =====================================================================
%% @equiv map_expr(none, Fields)
diff --git a/lib/syntax_tools/src/erl_syntax_lib.erl b/lib/syntax_tools/src/erl_syntax_lib.erl
index 9815559779..c7f477c4d2 100644
--- a/lib/syntax_tools/src/erl_syntax_lib.erl
+++ b/lib/syntax_tools/src/erl_syntax_lib.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1997-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -280,7 +285,7 @@ mapfoldl(_, S, []) ->
%% =====================================================================
%% @spec variables(syntaxTree()) -> set(atom())
%%
-%% set(T) = //stdlib/sets:set(T)
+%% @type set(T) = //stdlib/sets:set(T)
%%
%% @doc Returns the names of variables occurring in a syntax tree, The
%% result is a set of variable names represented by atoms. Macro names
@@ -1955,7 +1960,7 @@ analyze_application(Node) ->
%% =====================================================================
-%% @spec analyze_type_application(Node::syntaxTree()) -> typeName()
+%% @spec analyze_type_application(Node::syntaxTree()) -> TypeName
%%
%% TypeName = {atom(), integer()}
%% | {ModuleName, {atom(), integer()}}
diff --git a/lib/syntax_tools/src/erl_tidy.erl b/lib/syntax_tools/src/erl_tidy.erl
index f2de12b410..1ca60ea73b 100644
--- a/lib/syntax_tools/src/erl_tidy.erl
+++ b/lib/syntax_tools/src/erl_tidy.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or
-%% modify it under the terms of the GNU Lesser General Public License
-%% as published by the Free Software Foundation; either version 2 of
-%% the License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1999-2014 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -36,6 +41,11 @@
%% been reasonably well tested, but the possibility of errors remains.
%% Keep backups of your original code safely stored, until you feel
%% confident that the new, modified code can be trusted.
+%%
+%% @type syntaxTree() = erl_syntax:syntaxTree(). An abstract syntax
+%% tree. See the {@link erl_syntax} module for details.
+%%
+%% @type filename() = file:filename().
-module(erl_tidy).
@@ -79,7 +89,6 @@ dir(Dir) ->
%% =====================================================================
%% @spec dir(Directory::filename(), Options::[term()]) -> ok
-%% filename() = file:filename()
%%
%% @doc Tidies Erlang source files in a directory and its
%% subdirectories.
@@ -206,7 +215,7 @@ file__defaults() ->
{verbose, false}].
default_printer() ->
- fun (Tree, Options) -> erl_prettypr:format(Tree, Options) end.
+ fun erl_prettypr:format/2.
%% =====================================================================
%% @spec file(Name) -> ok
@@ -253,7 +262,7 @@ file(Name) ->
%%
%% <dt>{printer, Function}</dt>
%% <dd><ul>
-%% <li>`Function = (syntaxTree()) -> string()'</li>
+%% <li>`Function = (syntaxTree(), [term()]) -> string()'</li>
%% </ul>
%%
%% Specifies a function for prettyprinting Erlang syntax trees.
@@ -414,7 +423,7 @@ write_module(Tree, Name, Opts) ->
print_module(Tree, Opts) ->
Printer = proplists:get_value(printer, Opts),
- io:format(Printer(Tree, Opts)).
+ io:put_chars(Printer(Tree, Opts)).
output(FD, Printer, Tree, Opts) ->
io:put_chars(FD, Printer(Tree, Opts)),
@@ -513,7 +522,6 @@ module(Forms) ->
%% @spec module(Forms, Options::[term()]) -> syntaxTree()
%%
%% Forms = syntaxTree() | [syntaxTree()]
-%% syntaxTree() = erl_syntax:syntaxTree()
%%
%% @doc Tidies a syntax tree representation of a module
%% definition. The given `Forms' may be either a single
diff --git a/lib/syntax_tools/src/igor.erl b/lib/syntax_tools/src/igor.erl
index 1d14bd7c3a..b92cd8d607 100644
--- a/lib/syntax_tools/src/igor.erl
+++ b/lib/syntax_tools/src/igor.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1998-2014 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -151,7 +156,8 @@ default_printer(Tree, Options) ->
%% @spec parse_transform(Forms::[syntaxTree()], Options::[term()]) ->
%% [syntaxTree()]
%%
-%% syntaxTree() = erl_syntax:syntaxTree()
+%% @type syntaxTree() = erl_syntax:syntaxTree(). An abstract syntax
+%% tree. See the {@link erl_syntax} module for details.
%%
%% @doc Allows Igor to work as a component of the Erlang compiler.
%% Including the term `{parse_transform, igor}' in the
@@ -212,7 +218,7 @@ merge(Name, Files) ->
%% @spec merge(Name::atom(), Files::[filename()], Options::[term()]) ->
%% [filename()]
%%
-%% filename() = file:filename()
+%% @type filename() = file:filename()
%%
%% @doc Merges source code files to a single file. `Name'
%% specifies the name of the resulting module - not the name of the
@@ -367,6 +373,7 @@ merge_files(Name, Files, Options) ->
%% @spec merge_files(Name::atom(), Sources::[Forms],
%% Files::[filename()], Options::[term()]) ->
%% {syntaxTree(), [stubDescriptor()]}
+%%
%% Forms = syntaxTree() | [syntaxTree()]
%%
%% @doc Merges source code files and syntax trees to a single syntax
@@ -410,7 +417,7 @@ merge_files(Name, Files, Options) ->
%%
%% <dd>Specifies a list of rules for associating object files with
%% source files, to be passed to the function
-%% `filename:find_src/2'. This can be used to change the
+%% `filelib:find_source/2'. This can be used to change the
%% way Igor looks for source files. If this option is not specified,
%% the default system rules are used. The first occurrence of this
%% option completely overrides any later in the option list.</dd>
@@ -455,7 +462,7 @@ merge_files(Name, Files, Options) ->
%% @see merge/3
%% @see merge_files/3
%% @see merge_sources/3
-%% @see //stdlib/filename:find_src/2
+%% @see //stdlib/filelib:find_source/2
%% @see epp_dodger
-spec merge_files(atom(), erl_syntax:forms(), [file:filename()], [option()]) ->
@@ -2739,8 +2746,8 @@ read_module(Name, Options) ->
%% It seems that we have no file - go on anyway,
%% just to get a decent error message.
read_module_1(Name, Options);
- {Name1, _} ->
- read_module_1(Name1 ++ ".erl", Options)
+ {ok, Name1} ->
+ read_module_1(Name1, Options)
end
end.
@@ -2800,9 +2807,9 @@ check_forms([], _) ->
ok.
find_src(Name, undefined) ->
- filename:find_src(filename(Name));
+ filelib:find_source(filename(Name));
find_src(Name, Rules) ->
- filename:find_src(filename(Name), Rules).
+ filelib:find_source(filename(Name), Rules).
%% file_type(filename()) -> {value, Type} | none
diff --git a/lib/syntax_tools/src/merl.erl b/lib/syntax_tools/src/merl.erl
index 163ce48bbc..d6cf208998 100644
--- a/lib/syntax_tools/src/merl.erl
+++ b/lib/syntax_tools/src/merl.erl
@@ -9,6 +9,16 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
+%%
%% Note: EDoc uses @@ and @} as escape sequences, so in the doc text below,
%% `@@' must be written `@@@@' and `@}' must be written `@@}'.
%%
diff --git a/lib/syntax_tools/src/merl_tests.erl b/lib/syntax_tools/src/merl_tests.erl
index c1aae3100e..61efc6935e 100644
--- a/lib/syntax_tools/src/merl_tests.erl
+++ b/lib/syntax_tools/src/merl_tests.erl
@@ -9,6 +9,16 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
+%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2012-2015 Richard Carlsson
%% @doc Unit tests for merl.
@@ -48,6 +58,21 @@ parse_error_test_() ->
f(merl:quote("{")))
].
+transform_parse_error_test_() ->
+ [?_assertEqual("merl:quote(\"{\")",
+ f(merl_transform:parse_transform(
+ [?Q("merl:quote(\"{\")")], []))),
+ ?_assertEqual("merl:quote(2, \"{\")",
+ f(merl_transform:parse_transform(
+ [?Q("merl:quote(2, \"{\")")], []))),
+ ?_assertEqual("merl:qquote(\"{\", [{var, V}])",
+ f(merl_transform:parse_transform(
+ [?Q("merl:qquote(\"{\", [{var, V}])")], []))),
+ ?_assertEqual("merl:qquote(2, \"{\", [{var, V}])",
+ f(merl_transform:parse_transform(
+ [?Q("merl:qquote(2, \"{\", [{var, V}])")], [])))
+ ].
+
term_test_() ->
[?_assertEqual(tuple, erl_syntax:type(merl:term({}))),
?_assertEqual("{foo, 42}", f(merl:term({foo, 42})))
diff --git a/lib/syntax_tools/src/merl_transform.erl b/lib/syntax_tools/src/merl_transform.erl
index fe58b6a122..b298bc407f 100644
--- a/lib/syntax_tools/src/merl_transform.erl
+++ b/lib/syntax_tools/src/merl_transform.erl
@@ -9,6 +9,16 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
+%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2012-2015 Richard Carlsson
%% @doc Parse transform for merl. Enables the use of automatic metavariables
@@ -104,10 +114,15 @@ expand_qquote([Text, Env], T, Line) ->
case erl_syntax:is_literal(Text) of
true ->
As = [Line, erl_syntax:concrete(Text)],
- %% expand further if possible
- expand(merl:qquote(Line, "merl:subst(_@tree, _@env)",
- [{tree, eval_call(Line, quote, As, T)},
- {env, Env}]));
+ case eval_call(Line, quote, As, failed) of
+ failed ->
+ T;
+ T1 ->
+ %% expand further if possible
+ expand(merl:qquote(Line, "merl:subst(_@tree, _@env)",
+ [{tree, T1},
+ {env, Env}]))
+ end;
false ->
T
end;
diff --git a/lib/syntax_tools/src/prettypr.erl b/lib/syntax_tools/src/prettypr.erl
index 1b5ba6b05a..61a8993b84 100644
--- a/lib/syntax_tools/src/prettypr.erl
+++ b/lib/syntax_tools/src/prettypr.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2000-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/syntax_tools/syntax_tools.pub b/lib/syntax_tools/syntax_tools.pub
deleted file mode 100644
index 6d69b31818..0000000000
--- a/lib/syntax_tools/syntax_tools.pub
+++ /dev/null
@@ -1,13 +0,0 @@
-{name, "syntax_tools"}.
-{vsn, {1,3}}.
-{summary, "A set of modules for working with Erlang source code."}.
-{author, "Richard Carlsson", "[email protected]", "031124"}.
-{keywords, ["source code", "syntax", "syntax trees", "erl_parse",
- "pretty printing", "comments", "tidying"]}.
-{needs, []}.
-{abstract, "This package defines an abstract datatype that is\n"
- "compatible with the `erl_parse' data structures, and\n"
- "provides modules for analysis and manipulation,\n"
- "flexible pretty printing, and preservation of source-code\n"
- "comments. Also includes `erl_tidy': automatic code tidying\n"
- "and checking."}.
diff --git a/lib/syntax_tools/test/merl_SUITE.erl b/lib/syntax_tools/test/merl_SUITE.erl
index 945972d405..52bbd9b3b8 100644
--- a/lib/syntax_tools/test/merl_SUITE.erl
+++ b/lib/syntax_tools/test/merl_SUITE.erl
@@ -29,12 +29,14 @@
init_per_group/2,end_per_group/2]).
%% Test cases
--export([merl_smoke_test/1]).
+-export([merl_smoke_test/1,
+ transform_parse_error_test/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [merl_smoke_test].
+ [merl_smoke_test,
+ transform_parse_error_test].
groups() ->
[].
@@ -84,6 +86,21 @@ merl_smoke_test(Config) when is_list(Config) ->
end)),
ok.
+transform_parse_error_test(_Config) ->
+ ?assertEqual("merl:quote(\"{\")",
+ f(merl_transform:parse_transform(
+ [?Q("merl:quote(\"{\")")], []))),
+ ?assertEqual("merl:quote(2, \"{\")",
+ f(merl_transform:parse_transform(
+ [?Q("merl:quote(2, \"{\")")], []))),
+ ?assertEqual("merl:qquote(\"{\", [{var, V}])",
+ f(merl_transform:parse_transform(
+ [?Q("merl:qquote(\"{\", [{var, V}])")], []))),
+ ?assertEqual("merl:qquote(2, \"{\", [{var, V}])",
+ f(merl_transform:parse_transform(
+ [?Q("merl:qquote(2, \"{\", [{var, V}])")], []))),
+ ok.
+
%% utilities
f(Ts) when is_list(Ts) ->
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE.erl b/lib/syntax_tools/test/syntax_tools_SUITE.erl
index b935d42bb7..868f43b8ee 100644
--- a/lib/syntax_tools/test/syntax_tools_SUITE.erl
+++ b/lib/syntax_tools/test/syntax_tools_SUITE.erl
@@ -9,13 +9,11 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
+%%
%% 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(syntax_tools_SUITE).
-include_lib("common_test/include/ct.hrl").
@@ -27,14 +25,14 @@
%% Test cases
-export([app_test/1,appup_test/1,smoke_test/1,revert/1,revert_map/1,
t_abstract_type/1,t_erl_parse_type/1,t_epp_dodger/1,
- t_comment_scan/1,t_igor/1]).
+ t_comment_scan/1,t_igor/1,t_erl_tidy/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[app_test,appup_test,smoke_test,revert,revert_map,
t_abstract_type,t_erl_parse_type,t_epp_dodger,
- t_comment_scan,t_igor].
+ t_comment_scan,t_igor,t_erl_tidy].
groups() ->
[].
@@ -237,6 +235,12 @@ t_igor(Config) when is_list(Config) ->
ok.
+t_erl_tidy(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ File = filename:join(DataDir,"erl_tidy_tilde.erl"),
+ ok = erl_tidy:file(File, [{stdout, true}]),
+ ok.
+
test_comment_scan([],_) -> ok;
test_comment_scan([File|Files],DataDir) ->
Filename = filename:join(DataDir,File),
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE_data/erl_tidy_tilde.erl b/lib/syntax_tools/test/syntax_tools_SUITE_data/erl_tidy_tilde.erl
new file mode 100644
index 0000000000..888264bad6
--- /dev/null
+++ b/lib/syntax_tools/test/syntax_tools_SUITE_data/erl_tidy_tilde.erl
@@ -0,0 +1,13 @@
+%%
+%% File: erl_tidy_tilde.erl
+%% Author: Mark Bucciarelli
+%% Created: 2016-06-05
+%%
+
+-module(erl_tidy_tilde).
+
+-export([start/0]).
+
+start() ->
+ io:put_chars("tilde characters ('~')in source were "
+ "breaking erl_tidy\n").
diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk
index f09c2a01d0..9b33f1e1f4 100644
--- a/lib/syntax_tools/vsn.mk
+++ b/lib/syntax_tools/vsn.mk
@@ -1 +1 @@
-SYNTAX_TOOLS_VSN = 2.0
+SYNTAX_TOOLS_VSN = 2.1.2
diff --git a/lib/tools/doc/src/erlang_mode.xml b/lib/tools/doc/src/erlang_mode.xml
index 00cf5196b4..7fef74813b 100644
--- a/lib/tools/doc/src/erlang_mode.xml
+++ b/lib/tools/doc/src/erlang_mode.xml
@@ -252,7 +252,14 @@
behavior</item>
<item>gen_event - skeleton for the OTP gen_event behavior</item>
<item>gen_fsm - skeleton for the OTP gen_fsm behavior</item>
- <item>gen_statem - skeleton for the OTP gen_statem behavior</item>
+ <item>
+ gen_statem (StateName/3) - skeleton for the OTP gen_statem behavior
+ using state name functions
+ </item>
+ <item>
+ gen_statem (handle_event/4) - skeleton for the OTP gen_statem behavior
+ using one state function
+ </item>
<item>Library module - skeleton for a module that does not
implement a process.</item>
<item>Corba callback - skeleton for a Corba callback module.</item>
diff --git a/lib/tools/doc/src/lcnt.xml b/lib/tools/doc/src/lcnt.xml
index 9c8ce148e9..31e5c241e9 100644
--- a/lib/tools/doc/src/lcnt.xml
+++ b/lib/tools/doc/src/lcnt.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2009</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -38,7 +38,7 @@
<modulesummary>A runtime system Lock Profiling tool.</modulesummary>
<description>
<p>The <c>lcnt</c> module is used to profile the internal ethread locks in the
- Erlang Runtime System. With <c>lcnt</c> enabled, Internal counters in the
+ Erlang Runtime System. With <c>lcnt</c> enabled, internal counters in the
runtime system are updated each time a lock is taken. The counters stores
information about the number of acquisition tries and the number of collisions
that has occurred during the acquisition tries. The counters also record the
@@ -47,17 +47,17 @@
<p>
The data produced by the lock counters will give an estimate on how well
the runtime system will behave from a parallelizable view point for the
- scenarios tested. This tool was mainly developed to help erlang runtime
+ scenarios tested. This tool was mainly developed to help Erlang runtime
developers iron out potential and generic bottlenecks.
</p>
<p>Locks in the emulator are named after what type of resource they protect and where
in the emulator they are initialized, those are lock 'classes'. Most of those
locks are also instantiated several times, and given unique identifiers, to increase
locking granularity. Typically an instantiated lock protects a disjunct set of
- the resource, i.e ets-tables, processes or ports. In other cases it protects a
- specific range of a resource, e.g. <c>pix_lock</c> which protects index to process
+ the resource, for example ets tables, processes or ports. In other cases it protects a
+ specific range of a resource, for example <c>pix_lock</c> which protects index to process
mappings, and is given a unique number within the class. A unique lock in <c>lcnt</c>
- is referenced by a name (class) and an identifier, <c>{Name, Id}</c>.
+ is referenced by a name (class) and an identifier: <c>{Name, Id}</c>.
</p>
<p>Some locks in the system are static and protects global resources, for example
<c>bif_timers</c> and the <c>run_queue</c> locks. Other locks are dynamic and not
diff --git a/lib/tools/doc/src/lcnt_chapter.xml b/lib/tools/doc/src/lcnt_chapter.xml
index 6cfdb5cf1b..c73fcb31e0 100644
--- a/lib/tools/doc/src/lcnt_chapter.xml
+++ b/lib/tools/doc/src/lcnt_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2009</year><year>2016</year>
+ <year>2009</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -42,42 +42,32 @@
completed its access to the resource and unlocked it. The <c>lcnt</c> tool measures these lock conflicts.
</p>
<p>
- Locks has an inherent cost in execution time and memory space. It takes time initialize, destroy, aquiring or releasing locks. To decrease lock contention it
+ Locks have an inherent cost in execution time and memory space. It takes time initialize, destroy, aquiring or releasing locks. To decrease lock contention it
some times necessary to use finer grained locking strategies. This will usually also increase the locking overhead and hence there is a tradeoff
between lock contention and overhead. In general, lock contention increases with the number of threads running concurrently. The <c>lcnt</c> tool does not measure locking overhead.
</p>
<section>
<title> Enabling lock-counting </title>
- <p>For investigation of locks in the emulator we use an internal tool called <c>lcnt</c> (short for lock-count). The VM needs to be compiled with this option enabled. To enable this, use:</p>
+ <p>For investigation of locks in the emulator we use an internal tool called <c>lcnt</c> (short for lock-count). The VM needs to be compiled with this option enabled.
+ To compile a lock-counting VM along with a normal VM, use:</p>
<pre>
cd $ERL_TOP
-./configure --enable-lock-counter
- </pre>
-
- <p>
- Another way to enable this alongside a normal VM is to compile it at emulator directory level, much like a debug build. To compile it this way do the following,
- </p>
- <pre>
-cd $ERL_TOP/erts/emulator
-make lcnt FLAVOR=smp
- </pre>
- <p> and then starting Erlang with,</p>
+./configure --enable-lock-counter</pre>
+ <p>Start the lock-counting VM like this:</p>
<pre>
-$ERL_TOP/bin/cerl -lcnt
- </pre>
- <p>To verify that you lock-counting enabled check that <c>[lock-counting]</c> appears in the status text when the VM is started.</p>
+$ERL_TOP/bin/erl -emu_type lcnt</pre>
+ <p>To verify that lock counting is enabled check that <c>[lock-counting]</c> appears in the status text when the VM is started.</p>
<pre>
-Erlang R13B03 (erts-5.7.4) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe]
- [kernel-poll:false] [lock-counting]
- </pre>
+Erlang/OTP 20 [erts-9.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe]
+ [kernel-poll:false] [lock-counting]</pre>
</section>
<section>
<title>Getting started</title>
<p>Once you have a lock counting enabled VM the module <c>lcnt</c> can be used. The module is intended to be used from the current running nodes shell. To access remote nodes use <c>lcnt:clear(Node)</c> and <c>lcnt:collect(Node)</c>. </p>
<p>All locks are continuously monitored and its statistics updated. Use <c>lcnt:clear/0</c> to initially clear all counters before running any specific tests. This command will also reset the duration timer internally.</p>
- <p>To retrieve lock statistics information use, <c>lcnt:collect/0,1</c>. The collect operation will start a <c>lcnt</c> server if it not already started. All collected data will be built into an erlang term and uploaded to the server and a duration time will also be uploaded. This duration is the time between <c>lcnt:clear/0,1</c> and <c>lcnt:collect/0,1</c>.</p>
+ <p>To retrieve lock statistics information, use <c>lcnt:collect/0,1</c>. The collect operation will start a <c>lcnt</c> server if it not already started. All collected data will be built into an Erlang term and uploaded to the server and a duration time will also be uploaded. This duration is the time between <c>lcnt:clear/0,1</c> and <c>lcnt:collect/0,1</c>.</p>
<p>Once the data is collected to the server it can be filtered, sorted and printed in many different ways.</p>
<p>See the <seealso marker="lcnt">reference manual</seealso> for a description of each function.</p>
diff --git a/lib/tools/doc/src/make.xml b/lib/tools/doc/src/make.xml
index fddf5ebd7b..123fcd4afc 100644
--- a/lib/tools/doc/src/make.xml
+++ b/lib/tools/doc/src/make.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1996</year>
- <year>2016</year>
+ <year>2017</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -43,15 +43,15 @@
<fsummary>Compile a set of modules.</fsummary>
<type>
<v>Options = [Option]</v>
- <v>&nbsp;Option = noexec | load | netload | &lt;compiler option&gt;</v>
+ <v>&nbsp;Option = noexec | load | netload | {emake, Emake} | &lt;compiler option&gt;</v>
</type>
<desc>
- <p>This function first looks in the current working directory
- for a file named <c>Emakefile</c> (see below) specifying the
- set of modules to compile and the compile options to use. If
- no such file is found, the set of modules to compile
- defaults to all modules in the current working
- directory.</p>
+ <p>This function determines the set of modules to compile and the
+ compile options to use, by first looking for the <c>emake</c> make
+ option, if not present reads the configuration from a file named
+ <c>Emakefile</c> (see below). If no such file is found, the
+ set of modules to compile defaults to all modules in the
+ current working directory.</p>
<p>Traversing the set of modules, it then recompiles every module for
which at least one of the following conditions apply:</p>
<list type="bulleted">
@@ -77,6 +77,9 @@
<item><c>netload</c> <br></br>
Net load mode. Loads all recompiled modules on all known nodes.</item>
+ <item><c>{emake, Emake}</c> <br></br>
+
+ Rather than reading the <c>Emakefile</c> specify configuration explicitly.</item>
</list>
<p>All items in <c>Options</c> that are not make options are assumed
to be compiler options and are passed as-is to
@@ -108,9 +111,10 @@
<section>
<title>Emakefile</title>
- <p><c>make:all/0,1</c> and <c>make:files/1,2</c> looks in the
- current working directory for a file named <c>Emakefile</c>. If
- it exists, <c>Emakefile</c> should contain elements like this:</p>
+ <p><c>make:all/0,1</c> and <c>make:files/1,2</c> first looks for
+ <c>{emake, Emake}</c> in options, then in the current working directory
+ for a file named <c>Emakefile</c>. If present <c>Emake</c> should
+ contain elements like this:</p>
<code type="none">
Modules.
{Modules,Options}. </code>
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index 0b8a2be715..bdd5455354 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,139 @@
</header>
<p>This document describes the changes made to the Tools application.</p>
+<section><title>Tools 2.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ In some situations, <c>make:all()</c> and friends did not
+ detect changes in include files located in the current
+ directory. This is now corrected.</p>
+ <p>
+ Own Id: OTP-14339 Aux Id: ERL-395 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The <c>make</c> module now accepts the
+ <c>{emake,Emake}</c> option.</p>
+ <p>
+ Own Id: OTP-14253</p>
+ </item>
+ <item>
+ <p> Miscellaneous updates due to atoms containing
+ arbitrary Unicode characters. </p>
+ <p>
+ Own Id: OTP-14285</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.9.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improved edoc support in emacs mode.</p>
+ <p>
+ Own Id: OTP-14217 Aux Id: PR-1282 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix unhandled trace event send_to_non_existing_process in
+ fprof.</p>
+ <p>
+ Own Id: OTP-13998</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improved edoc support in emacs erlang-mode.</p>
+ <p>
+ Own Id: OTP-13945 Aux Id: PR-1157 </p>
+ </item>
+ <item>
+ <p>
+ Added erldoc to emacs mode which opens html documentation
+ in browser from emacs. For example <c>M-x erldoc-browse
+ RET lists:foreach/2</c>.</p>
+ <p>
+ Own Id: OTP-14018 Aux Id: PR-1197 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.8.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Errors in type specification and Emacs template
+ generation for <c>gen_statem:code_change/4</c> has been
+ fixed from bugs.erlang.org's Jira cases ERL-172 and
+ ERL-187.</p>
+ <p>
+ Own Id: OTP-13746 Aux Id: ERL-172, ERL-187 </p>
+ </item>
+ <item>
+ <p>
+ Fix gc_start/gc_end in fprof tags when parsing old trace
+ logs.</p>
+ <p>
+ Own Id: OTP-13778 Aux Id: PR-1136 </p>
+ </item>
+ <item>
+ <p><c>make</c> (tools) and <c>ct_make</c> (common_test)
+ would crash if an Erlang source file contained a
+ <c>-warning()</c> directive.</p>
+ <p>
+ Own Id: OTP-13855</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.8.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Correct a bug when adding multiple modules to an Xref
+ server. The bug was introduced in OTP-19.0. </p>
+ <p>
+ Own Id: OTP-13708 Aux Id: ERL-173 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Tools 2.8.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/tools/doc/src/xref_chapter.xml b/lib/tools/doc/src/xref_chapter.xml
index 8b14e03064..872793bdcb 100644
--- a/lib/tools/doc/src/xref_chapter.xml
+++ b/lib/tools/doc/src/xref_chapter.xml
@@ -234,7 +234,7 @@
operand of the intersection operator <c>*</c> is implicitly
converted to the more special type of the second operand.</item>
<tag><c>xref:q(s, "(Mod) tools").</c></tag>
- <item>All modules of the <c>tools</c> application.</item>
+ <item>All modules of the Tools application.</item>
<tag><c>xref:q(s, '"xref_.*" : Mod').</c></tag>
<item>All modules with a name beginning with <c>xref_</c>.</item>
<tag><c>xref:q(s, "# E&nbsp;|&nbsp;X&nbsp;").</c></tag>
@@ -252,9 +252,9 @@
<tag><c>xref:q(s, "XC * (ME - strict ME)").</c></tag>
<item>External calls within some module.</item>
<tag><c>xref:q(s, "E&nbsp;|||&nbsp;kernel").</c></tag>
- <item>All calls within the <c>kernel</c> application. </item>
+ <item>All calls within the Kernel application. </item>
<tag><c>xref:q(s, "closure&nbsp;E&nbsp;|&nbsp;kernel&nbsp;||&nbsp;kernel").</c></tag>
- <item>All direct and indirect calls within the <c>kernel</c>
+ <item>All direct and indirect calls within the Kernel
application. Both the calling and the used functions of
indirect calls are defined in modules of the kernel
application, but it is possible that some functions outside
diff --git a/lib/tools/emacs/Makefile b/lib/tools/emacs/Makefile
index 585425e5f1..35c93ba4ed 100644
--- a/lib/tools/emacs/Makefile
+++ b/lib/tools/emacs/Makefile
@@ -38,11 +38,13 @@ MAN_FILES= \
tags.3
EMACS_FILES= \
+ erldoc \
erlang-skels \
erlang-skels-old \
erlang_appwiz \
erlang-start \
erlang-eunit \
+ erlang-edoc \
erlang-flymake \
erlang
diff --git a/lib/tools/emacs/erlang-edoc.el b/lib/tools/emacs/erlang-edoc.el
new file mode 100644
index 0000000000..d0dcc81028
--- /dev/null
+++ b/lib/tools/emacs/erlang-edoc.el
@@ -0,0 +1,178 @@
+;;; erlang-edoc.el --- EDoc support for Erlang mode -*- lexical-binding: t; -*-
+
+;; %CopyrightBegin%
+;;
+;; Copyright Ericsson AB 1996-2016. All Rights Reserved.
+;;
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
+;;
+;; http://www.apache.org/licenses/LICENSE-2.0
+;;
+;; Unless required by applicable law or agreed to in writing, software
+;; distributed under the License is distributed on an "AS IS" BASIS,
+;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+;; See the License for the specific language governing permissions and
+;; limitations under the License.
+;;
+;; %CopyrightEnd%
+
+;;; Commentary:
+
+;; Ref: http://www.erlang.org/doc/apps/edoc/users_guide.html
+;;
+;; To use: (add-hook 'erlang-mode-hook 'erlang-edoc-mode)
+
+;;; Code:
+
+(defcustom erlang-edoc-indent-level 2
+ "Indentation level of xhtml in Erlang edoc."
+ :safe 'integerp
+ :group 'erlang)
+
+(defvar erlang-edoc-generic-tags
+ '("clear" "docfile" "end" "headerfile" "todo" "TODO" "type")
+ "Tags that can be used anywhere within a module.")
+
+(defvar erlang-edoc-overview-tags
+ '("author" "copyright" "doc" "reference" "see" "since" "title" "version")
+ "Tags that can be used in an overview file.")
+
+(defvar erlang-edoc-module-tags
+ '("author" "copyright" "deprecated" "doc" "hidden" "private" "reference"
+ "see" "since" "version")
+ "Tags that can be used before a module declaration.")
+
+(defvar erlang-edoc-function-tags
+ '("deprecated" "doc" "equiv" "hidden" "param" "private" "returns"
+ "see" "since" "spec" "throws" "type")
+ "Tags that can be used before a function definition.")
+
+(defvar erlang-edoc-predefined-macros
+ '("date" "docRoot" "link" "module" "package" "section" "time"
+ "type" "version"))
+
+(defface erlang-edoc-tag '((t (:inherit font-lock-constant-face)))
+ "Face used to highlight edoc tags."
+ :group 'erlang)
+
+(defface erlang-edoc-macro '((t (:inherit font-lock-preprocessor-face)))
+ "Face used to highlight edoc macros."
+ :group 'erlang)
+
+(defface erlang-edoc-verbatim
+ '((t (:family "Monospace" :inherit font-lock-keyword-face)))
+ "Face used to highlight verbatim text."
+ :group 'erlang)
+
+(defface erlang-edoc-todo '((t (:inherit font-lock-warning-face)))
+ "Face used to highlight edoc macros."
+ :group 'erlang)
+
+(defface erlang-edoc-heading '((t (:inherit bold)))
+ "Face used to highlight edoc headings."
+ :group 'erlang)
+
+(defvar erlang-edoc-font-lock-keywords
+ '(("^%+\\s-*\\(@\\w+\\)\\_>" 1 'erlang-edoc-tag prepend)
+ ("^%+\\s-*" ("{\\(@\\w+\\)\\_>" nil nil (1 'erlang-edoc-macro prepend)))
+ ("^%+\\s-*" ("\\(?:@@\\)*\\(@[@{}]\\)" nil nil (1 'escape-glyph prepend)))
+ ("^%+\\s-*\\(@deprecated\\)\\_>" 1 font-lock-warning-face prepend)
+ ;; http://www.erlang.org/doc/apps/edoc/chapter.html#Wiki_notation
+ ("^%+\\s-*" ("[^`]`\\([^`]?\\|[^`].*?[^']\\)'"
+ (forward-char -1) nil (1 'erlang-edoc-verbatim prepend)))
+ ("^%+\\s-*" ("\\[\\(\\(?:https?\\|file\\|ftp\\)://[^][]+\\)\\]"
+ nil nil (1 'link prepend)))
+ ("^%+\\s-*\\(?:\\(?1:@todo\\|@TODO\\)\\_>\\|\\(?1:TODO\\):\\)"
+ 1 'erlang-edoc-todo prepend)
+ ("^%+\\s-*\\(\\(=\\{2,4\\}\\)[^=\n].*[^=\n]\\2\\)\\s-*$"
+ 1 'erlang-edoc-heading prepend)))
+
+(defun erlang-edoc-xml-context ()
+ "Parse edoc x(ht)ml context at comment start of current line."
+ (eval-and-compile (require 'xmltok))
+ (save-excursion
+ (beginning-of-line)
+ (when (looking-at "^%+\\s-*")
+ (let ((pt (match-end 0)) context)
+ (forward-comment (- (point)))
+ (while (< (point) pt)
+ (xmltok-forward)
+ (cond ((eq xmltok-type 'start-tag)
+ (push (cons xmltok-type xmltok-start) context))
+ ((eq xmltok-type 'end-tag)
+ (pop context))))
+ (goto-char pt)
+ (xmltok-forward)
+ (push (car (memq xmltok-type '(start-tag end-tag))) context)
+ context))))
+
+(defun erlang-edoc-indent-line ()
+ (let ((context (erlang-edoc-xml-context)))
+ (when context
+ (save-excursion
+ (beginning-of-line)
+ (re-search-forward "^%+\\s-*" (line-end-position))
+ (when (or (car context) (cadr context))
+ (let ((pad (when (cadr context)
+ (save-excursion
+ (goto-char (cdr (cadr context)))
+ (- (current-column)
+ (progn
+ (beginning-of-line)
+ (skip-chars-forward "%")
+ (current-column)))))))
+ (just-one-space (cond ((not pad) 1)
+ ((eq (car context) 'end-tag) pad)
+ (t (+ erlang-edoc-indent-level pad)))))))
+ (when (looking-back "^%*\\s-*" (line-beginning-position))
+ (re-search-forward "\\=%*\\s-*")))))
+
+(defun erlang-edoc-before-module-declaration-p ()
+ (save-excursion
+ (beginning-of-line)
+ (forward-comment (point-max))
+ (or (eobp) (re-search-forward "^-module\\s-*(" nil t))))
+
+(defun erlang-edoc-completion-at-point ()
+ (when (eq (syntax-ppss-context (syntax-ppss)) 'comment)
+ (save-excursion
+ (skip-syntax-backward "w_")
+ (when (= (preceding-char) ?@)
+ (let* ((is-tag (looking-back "^%+\\s-*@" (line-beginning-position)))
+ (beg (point))
+ (end (progn (skip-syntax-forward "w_") (point)))
+ (table (cond
+ ((not is-tag)
+ erlang-edoc-predefined-macros)
+ ((erlang-edoc-before-module-declaration-p)
+ (append erlang-edoc-module-tags
+ erlang-edoc-generic-tags))
+ (t (append erlang-edoc-function-tags
+ erlang-edoc-generic-tags)))))
+ (list beg end table))))))
+
+;;;###autoload
+(define-minor-mode erlang-edoc-mode nil
+ :lighter " EDoc"
+ (cond (erlang-edoc-mode
+ (add-hook 'erlang-indent-line-hook #'erlang-edoc-indent-line nil t)
+ (font-lock-add-keywords nil erlang-edoc-font-lock-keywords t)
+ (add-hook 'completion-at-point-functions
+ #'erlang-edoc-completion-at-point nil t))
+ (t
+ (remove-hook 'erlang-indent-line-hook #'erlang-edoc-indent-line t)
+ (font-lock-remove-keywords nil erlang-edoc-font-lock-keywords)
+ (remove-hook 'completion-at-point-functions
+ #'erlang-edoc-completion-at-point t)))
+ (jit-lock-refontify))
+
+(provide 'erlang-edoc)
+
+;; Local variables:
+;; coding: utf-8
+;; indent-tabs-mode: nil
+;; End:
+
+;;; erlang-edoc.el ends here
diff --git a/lib/tools/emacs/erlang-eunit.el b/lib/tools/emacs/erlang-eunit.el
index 3b85e6680a..38c40927f4 100644
--- a/lib/tools/emacs/erlang-eunit.el
+++ b/lib/tools/emacs/erlang-eunit.el
@@ -68,7 +68,7 @@ buffer and vice versa"
;;;
(defun erlang-eunit-open-src-file-other-window (test-file-path)
"Open the src file which corresponds to the an EUnit test file"
- (find-file-other-window (erlang-eunit-src-filename test-file-path)))
+ (find-file-other-window (erlang-eunit-src-filename test-file-path)))
;;; Return the name and path of the EUnit test file
;;, (input may be either the source filename itself or the EUnit test filename)
@@ -154,7 +154,7 @@ buffer and vice versa"
;;; Join filenames
(defun filename-join (dir file)
(if (or (= (elt file 0) ?/)
- (= (car (last (append dir nil))) ?/))
+ (= (car (last (append dir nil))) ?/))
(concat dir file)
(concat dir "/" file)))
@@ -299,7 +299,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set."
;;; Compile source and EUnit test file and finally run EUnit tests for
;;; the current module
(defun erlang-eunit-compile-and-test (test-fun test-args &optional under-cover)
- "Compile the source and test files and run the EUnit test suite.
+ "Compile the source and test files and run the EUnit test suite.
If under-cover is set to t, the module under test is compile for
code coverage analysis. If under-cover is left out or not set,
@@ -311,7 +311,7 @@ and the number of times each line is covered).
With prefix arg, compiles for debug and runs tests with the verbose flag set."
(erlang-eunit-record-recent-compile under-cover)
(let ((src-filename (erlang-eunit-src-filename buffer-file-name))
- (test-filename (erlang-eunit-test-filename buffer-file-name)))
+ (test-filename (erlang-eunit-test-filename buffer-file-name)))
;; The purpose of out-maneuvering `save-some-buffers', as is done
;; below, is to ask the question about saving buffers only once,
@@ -326,9 +326,9 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set."
;; be placed in the source file instead. Any compilation error
;; will prevent the subsequent steps to be run (hence the `and')
(and (erlang-eunit-compile-file src-filename under-cover)
- (if (file-readable-p test-filename)
- (erlang-eunit-compile-file test-filename)
- t)
+ (if (file-readable-p test-filename)
+ (erlang-eunit-compile-file test-filename)
+ t)
(apply test-fun test-args)
(if under-cover
(save-excursion
@@ -381,16 +381,16 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set."
(goto-char compilation-parsing-end)
(erlang-eunit-all-list-elems-fulfill-p
(lambda (re) (let ((continue t)
- (result t))
- (while continue ; ignore warnings, stop at errors
- (if (re-search-forward re (point-max) t)
- (if (erlang-eunit-is-compilation-warning)
- t
- (setq result nil)
- (setq continue nil))
- (setq result t)
- (setq continue nil)))
- result))
+ (result t))
+ (while continue ; ignore warnings, stop at errors
+ (if (re-search-forward re (point-max) t)
+ (if (erlang-eunit-is-compilation-warning)
+ t
+ (setq result nil)
+ (setq continue nil))
+ (setq result t)
+ (setq continue nil)))
+ result))
(mapcar (lambda (e) (car e)) erlang-error-regexp-alist))))
(defun erlang-eunit-is-compilation-warning ()
@@ -402,7 +402,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set."
(let ((matches-p t))
(while (and list matches-p)
(if (not (funcall pred (car list)))
- (setq matches-p nil))
+ (setq matches-p nil))
(setq list (cdr list)))
matches-p))
@@ -439,15 +439,21 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set."
(defun erlang-eunit-ensure-keymap-for-key (key-seq)
(let ((prefix-keys (butlast (append key-seq nil)))
- (prefix-seq ""))
+ (prefix-seq ""))
(while prefix-keys
(setq prefix-seq (concat prefix-seq (make-string 1 (car prefix-keys))))
(setq prefix-keys (cdr prefix-keys))
(if (not (keymapp (lookup-key (current-local-map) prefix-seq)))
- (local-set-key prefix-seq (make-sparse-keymap))))))
+ (local-set-key prefix-seq (make-sparse-keymap))))))
(add-hook 'erlang-mode-hook 'erlang-eunit-add-key-bindings)
(provide 'erlang-eunit)
-;; erlang-eunit ends here
+
+;; Local variables:
+;; coding: utf-8
+;; indent-tabs-mode: nil
+;; End:
+
+;; erlang-eunit.el ends here
diff --git a/lib/tools/emacs/erlang-flymake.el b/lib/tools/emacs/erlang-flymake.el
index 2e447b55de..0b7936a81f 100644
--- a/lib/tools/emacs/erlang-flymake.el
+++ b/lib/tools/emacs/erlang-flymake.el
@@ -37,8 +37,7 @@
"Return a list of include directories to add to the compiler options.")
(defvar erlang-flymake-extra-opts
- (list "+warn_obsolete_guard"
- "+warn_unused_import"
+ (list "+warn_unused_import"
"+warn_shadow_vars"
"+warn_export_vars"
"+strong_validation"
diff --git a/lib/tools/emacs/erlang-pkg.el b/lib/tools/emacs/erlang-pkg.el
index 4d0aa6fcd3..02d6bebbf4 100644
--- a/lib/tools/emacs/erlang-pkg.el
+++ b/lib/tools/emacs/erlang-pkg.el
@@ -1,3 +1,3 @@
(define-package "erlang" "2.7.0"
- "Erlang major mode"
- '())
+ "Erlang major mode"
+ '((emacs "24.1")))
diff --git a/lib/tools/emacs/erlang-skels.el b/lib/tools/emacs/erlang-skels.el
index ce26c83295..bdb3d9ad4a 100644
--- a/lib/tools/emacs/erlang-skels.el
+++ b/lib/tools/emacs/erlang-skels.el
@@ -1,7 +1,7 @@
;;
;; %CopyrightBegin%
;;
-;; Copyright Ericsson AB 2010-2016. All Rights Reserved.
+;; Copyright Ericsson AB 2010-2017. All Rights Reserved.
;;
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
@@ -56,8 +56,10 @@
erlang-skel-gen-event erlang-skel-header)
("gen_fsm" "gen-fsm"
erlang-skel-gen-fsm erlang-skel-header)
- ("gen_statem" "gen-statem"
- erlang-skel-gen-statem erlang-skel-header)
+ ("gen_statem (StateName/3)" "gen-statem-StateName"
+ erlang-skel-gen-statem-StateName erlang-skel-header)
+ ("gen_statem (handle_event/4)" "gen-statem-handle-event"
+ erlang-skel-gen-statem-handle-event erlang-skel-header)
("wx_object" "wx-object"
erlang-skel-wx-object erlang-skel-header)
("Library module" "gen-lib"
@@ -497,6 +499,7 @@ Please see the function `tempo-define-template'.")
"%% {stop, Reason}" n
(erlang-skel-separator-end 2)
"init([]) ->" n>
+ "process_flag(trap_exit, true)," n>
"{ok, #state{}}." n
n
(erlang-skel-separator-start 2)
@@ -740,6 +743,7 @@ Please see the function `tempo-define-template'.")
"%% {stop, StopReason}" n
(erlang-skel-separator-end 2)
"init([]) ->" n>
+ "process_flag(trap_exit, true)," n>
"{ok, state_name, #state{}}." n
n
(erlang-skel-separator-start 2)
@@ -860,7 +864,7 @@ Please see the function `tempo-define-template'.")
"*The template of a gen_fsm.
Please see the function `tempo-define-template'.")
-(defvar erlang-skel-gen-statem
+(defvar erlang-skel-gen-statem-StateName
'((erlang-skel-include erlang-skel-large-header)
"-behaviour(gen_statem)." n n
@@ -868,9 +872,8 @@ Please see the function `tempo-define-template'.")
"-export([start_link/0])." n
n
"%% gen_statem callbacks" n
- "-export([init/1, terminate/3, code_change/4])." n
+ "-export([callback_mode/0, init/1, terminate/3, code_change/4])." n
"-export([state_name/3])." n
- "-export([handle_event/4])." n
n
"-define(SERVER, ?MODULE)." n
n
@@ -899,48 +902,149 @@ Please see the function `tempo-define-template'.")
(erlang-skel-separator-start 2)
"%% @private" n
"%% @doc" n
+ "%% Define the callback_mode() for this callback module." n
+ (erlang-skel-separator-end 2)
+ "-spec callback_mode() -> gen_statem:callback_mode_result()." n
+ "callback_mode() -> state_functions." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
"%% Whenever a gen_statem is started using gen_statem:start/[3,4] or" n
"%% gen_statem:start_link/[3,4], this function is called by the new" n
"%% process to initialize." n
(erlang-skel-separator-end 2)
- "-spec init(Args :: term()) -> " n>
- "{gen_statem:callback_mode()," n>
- "State :: term(), Data :: term()} |" n>
- "{gen_statem:callback_mode()," n>
- "State :: term(), Data :: term()," n>
- "[gen_statem:action()] | gen_statem:action()} |" n>
- "ignore |" n>
- "{stop, Reason :: term()}." n
+ "-spec init(Args :: term()) ->" n>
+ "gen_statem:init_result(atom())." n
"init([]) ->" n>
- "{state_functions, state_name, #data{}}." n
+ "process_flag(trap_exit, true)," n>
+ "{ok, state_name, #data{}}." n
n
(erlang-skel-separator-start 2)
"%% @private" n
"%% @doc" n
- "%% If the gen_statem runs with CallbackMode =:= state_functions" n
- "%% there should be one instance of this function for each possible" n
- "%% state name. Whenever a gen_statem receives an event," n
- "%% the instance of this function with the same name" n
- "%% as the current state name StateName is called to" n
- "%% handle the event." n
+ "%% There should be one function like this for each state name." n
+ "%% Whenever a gen_statem receives an event, the function " n
+ "%% with the name of the current state (StateName) " n
+ "%% is called to handle the event." n
(erlang-skel-separator-end 2)
- "-spec state_name(" n>
- "gen_statem:event_type(), Msg :: term()," n>
+ "-spec state_name('enter'," n>
+ "OldState :: atom()," n>
+ "Data :: term()) ->" n>
+ "gen_statem:state_enter_result('state_name');" n>
+ "(gen_statem:event_type()," n>
+ "Msg :: term()," n>
"Data :: term()) ->" n>
- "gen_statem:state_function_result(). " n
+ "gen_statem:event_handler_result(atom())." n
+ ;;
"state_name({call,Caller}, _Msg, Data) ->" n>
"{next_state, state_name, Data, [{reply,Caller,ok}]}." n
n
(erlang-skel-separator-start 2)
"%% @private" n
"%% @doc" n
- "%% If the gen_statem runs with CallbackMode =:= handle_event_function" n
- "%% this function is called for every event a gen_statem receives." n
+ "%% This function is called by a gen_statem when it is about to" n
+ "%% terminate. It should be the opposite of Module:init/1 and do any" n
+ "%% necessary cleaning up. When it returns, the gen_statem terminates with" n
+ "%% Reason. The return value is ignored." n
+ (erlang-skel-separator-end 2)
+ "-spec terminate(Reason :: term(), State :: term(), Data :: term()) ->" n>
+ "any()." n
+ "terminate(_Reason, _State, _Data) ->" n>
+ "void." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Convert process state when code is changed" n
+ (erlang-skel-separator-end 2)
+ "-spec code_change(" n>
+ "OldVsn :: term() | {down,term()}," n>
+ "State :: term(), Data :: term(), Extra :: term()) ->" n>
+ "{ok, NewState :: term(), NewData :: term()} |" n>
+ "(Reason :: term())." n
+ "code_change(_OldVsn, State, Data, _Extra) ->" n>
+ "{ok, State, Data}." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Internal functions" n
+ (erlang-skel-double-separator-end 3)
+ )
+ "*The template of a gen_statem (StateName/3).
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-gen-statem-handle-event
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(gen_statem)." n n
+
+ "%% API" n
+ "-export([start_link/0])." n
+ n
+ "%% gen_statem callbacks" n
+ "-export([callback_mode/0, init/1, terminate/3, code_change/4])." n
+ "-export([handle_event/4])." n
+ n
+ "-define(SERVER, ?MODULE)." n
+ n
+ "-record(data, {})." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% API" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Creates a gen_statem process which calls Module:init/1 to" n
+ "%% initialize. To ensure a synchronized start-up procedure, this" n
+ "%% function does not return until Module:init/1 has returned." n
+ "%%" n
+ (erlang-skel-separator-end 2)
+ "-spec start_link() ->" n>
+ "{ok, Pid :: pid()} |" n>
+ "ignore |" n>
+ "{error, Error :: term()}." n
+ "start_link() ->" n>
+ "gen_statem:start_link({local, ?SERVER}, ?MODULE, [], [])." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% gen_statem callbacks" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Define the callback_mode() for this callback module." n
+ (erlang-skel-separator-end 2)
+ "-spec callback_mode() -> gen_statem:callback_mode_result()." n
+ "callback_mode() -> handle_event_function." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Whenever a gen_statem is started using gen_statem:start/[3,4] or" n
+ "%% gen_statem:start_link/[3,4], this function is called by the new" n
+ "%% process to initialize." n
(erlang-skel-separator-end 2)
- "-spec handle_event(" n>
- "gen_statem:event_type(), Msg :: term()," n>
- "State :: term(), Data :: term()) ->" n>
- "gen_statem:handle_event_result(). " n
+ "-spec init(Args :: term()) ->" n>
+ "gen_statem:init_result(term())." n
+ "init([]) ->" n>
+ "process_flag(trap_exit, true)," n>
+ "{ok, state_name, #data{}}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% This function is called for every event a gen_statem receives." n
+ (erlang-skel-separator-end 2)
+ "-spec handle_event('enter'," n>
+ "OldState :: term()," n>
+ "State :: term()," n>
+ "Data :: term()) ->" n>
+ "gen_statem:state_enter_result(term());" n>
+ "(gen_statem:event_type()," n>
+ "Msg :: term()," n>
+ "State :: term()," n>
+ "Data :: term()) ->" n>
+ "gen_statem:event_handler_result(term())." n
+ ;;
"handle_event({call,From}, _Msg, State, Data) ->" n>
"{next_state, State, Data, [{reply,From,ok}]}." n
n
@@ -965,7 +1069,8 @@ Please see the function `tempo-define-template'.")
"-spec code_change(" n>
"OldVsn :: term() | {down,term()}," n>
"State :: term(), Data :: term(), Extra :: term()) ->" n>
- "{ok, NewState :: term(), NewData :: term()}." n
+ "{ok, NewState :: term(), NewData :: term()} |" n>
+ "(Reason :: term())." n
"code_change(_OldVsn, State, Data, _Extra) ->" n>
"{ok, State, Data}." n
n
@@ -973,7 +1078,7 @@ Please see the function `tempo-define-template'.")
"%%% Internal functions" n
(erlang-skel-double-separator-end 3)
)
- "*The template of a gen_statem.
+ "*The template of a gen_statem (handle_event/4).
Please see the function `tempo-define-template'.")
(defvar erlang-skel-wx-object
diff --git a/lib/tools/emacs/erlang-start.el b/lib/tools/emacs/erlang-start.el
index 76e0575e68..c35f280bf4 100644
--- a/lib/tools/emacs/erlang-start.el
+++ b/lib/tools/emacs/erlang-start.el
@@ -39,7 +39,7 @@
;;
;; Please state as exactly as possible:
;; - Version number of Erlang Mode (see the menu), Emacs, Erlang,
-;; and of any other relevant software.
+;; and of any other relevant software.
;; - What the expected result was.
;; - What you did, preferably in a repeatable step-by-step form.
;; - A description of the unexpected result.
@@ -60,7 +60,7 @@
;;
(autoload 'erlang-mode "erlang" "Major mode for editing Erlang code." t)
-(autoload 'erlang-version "erlang"
+(autoload 'erlang-version "erlang"
"Return the current version of Erlang mode." t)
(autoload 'erlang-shell "erlang" "Start a new Erlang shell." t)
(autoload 'run-erlang "erlang" "Start a new Erlang shell." t)
@@ -68,7 +68,7 @@
(autoload 'erlang-compile "erlang"
"Compile Erlang module in current buffer." t)
-(autoload 'erlang-man-module "erlang"
+(autoload 'erlang-man-module "erlang"
"Find manual page for MODULE." t)
(autoload 'erlang-man-function "erlang"
"Find manual page for NAME, where NAME is module:function." t)
@@ -78,6 +78,21 @@
(autoload 'erlang-find-tag-other-window "erlang"
"Like `find-tag-other-window'. Capable of retreiving Erlang modules.")
+;;
+;; Declare functions in "erlang-edoc.el".
+;;
+
+(autoload 'erlang-edoc-mode "erlang-edoc" "Toggle Erlang-Edoc mode on or off." t)
+
+;;
+;; Declare functions in "erldoc.el".
+;;
+
+(autoload 'erldoc-browse "erldoc" "\n\n(fn MFA)" t nil)
+(autoload 'erldoc-browse-topic "erldoc" "\n\n(fn TOPIC)" t nil)
+(autoload 'erldoc-apropos "erldoc" "\n\n(fn PATTERN)" t nil)
+(autoload 'erldoc-eldoc-function "erldoc" "\
+A function suitable for `eldoc-documentation-function'.\n\n(fn)" nil nil)
;;
;; Associate files extensions ".erl" and ".hrl" with Erlang mode.
@@ -93,25 +108,22 @@
;;
;; Associate files using interpreter "escript" with Erlang mode.
-;;
+;;
;;;###autoload
(add-to-list 'interpreter-mode-alist (cons "escript" 'erlang-mode))
;;
;; Ignore files ending in ".jam", ".vee", and ".beam" when performing
-;; file completion.
+;; file completion and in dired omit mode.
;;
;;;###autoload
(let ((erl-ext '(".jam" ".vee" ".beam")))
(while erl-ext
- (let ((cie completion-ignored-extensions))
- (while (and cie (not (string-equal (car cie) (car erl-ext))))
- (setq cie (cdr cie)))
- (if (null cie)
- (setq completion-ignored-extensions
- (cons (car erl-ext) completion-ignored-extensions))))
+ (add-to-list 'completion-ignored-extensions (car erl-ext))
+ (when (boundp 'dired-omit-extensions)
+ (add-to-list 'dired-omit-extensions (car erl-ext)))
(setq erl-ext (cdr erl-ext))))
@@ -121,4 +133,9 @@
(provide 'erlang-start)
+;; Local variables:
+;; coding: utf-8
+;; indent-tabs-mode: nil
+;; End:
+
;; erlang-start.el ends here.
diff --git a/lib/tools/emacs/erlang-test.el b/lib/tools/emacs/erlang-test.el
index 9a146632c5..efe3d515e9 100644
--- a/lib/tools/emacs/erlang-test.el
+++ b/lib/tools/emacs/erlang-test.el
@@ -2,13 +2,13 @@
;;; Unit tests for erlang.el.
-;; Author: Johan Claesson
+;; Author: Johan Claesson
;; Created: 2016-05-07
;; Keywords: erlang, languages
;; %CopyrightBegin%
;;
-;; Copyright Ericsson AB 2016. All Rights Reserved.
+;; Copyright Ericsson AB 2016-2017. All Rights Reserved.
;;
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
@@ -28,6 +28,27 @@
;;; Commentary:
;; This library require GNU Emacs 25 or later.
+;;
+;; There are two ways to run emacs unit tests.
+;;
+;; 1. Within a running emacs process. Load this file. Then to run
+;; all defined test cases:
+;;
+;; M-x ert RET t RET
+;;
+;; To run only the erlang test cases:
+;;
+;; M-x ert RET "^erlang" RET
+;;
+;;
+;; 2. In a new stand-alone emacs process. This process exits
+;; when it executed the tests. For example:
+;;
+;; emacs -Q -batch -L . -l erlang.el -l erlang-test.el \
+;; -f ert-run-tests-batch-and-exit
+;;
+;; The -L option adds a directory to the load-path. It should be the
+;; directory containing erlang.el and erlang-test.el.
;;; Code:
@@ -52,28 +73,46 @@ concatenated to form an erlang file to test on.")
(ert-deftest erlang-test-tags ()
(let* ((dir (make-temp-file "erlang-test" t))
- (erlang-file (expand-file-name "erlang_test.erl" dir))
- (tags-file (expand-file-name "TAGS" dir))
- tags-file-name tags-table-list erlang-buffer)
- (unwind-protect
- (progn
- (erlang-test-create-erlang-file erlang-file)
- (erlang-test-compile-tags erlang-file tags-file)
- (setq erlang-buffer (find-file-noselect erlang-file))
- (with-current-buffer erlang-buffer
- (setq-local tags-file-name tags-file))
- ;; Setting global tags-file-name is a workaround for
- ;; GNU Emacs bug#23164.
- (setq tags-file-name tags-file)
- (erlang-test-completion-table)
- (erlang-test-xref-find-definitions erlang-file erlang-buffer))
- (when (buffer-live-p erlang-buffer)
- (kill-buffer erlang-buffer))
- (let ((tags-buffer (find-buffer-visiting tags-file)))
- (when (buffer-live-p tags-buffer)
- (kill-buffer tags-buffer)))
- (when (file-exists-p dir)
- (delete-directory dir t)))))
+ (erlang-file (expand-file-name "erlang_test.erl" dir))
+ (tags-file (expand-file-name "TAGS" dir))
+ (old-tags-file-name (default-value 'tags-file-name))
+ (old-tags-table-list (default-value 'tags-table-list))
+ tags-file-name
+ tags-table-list
+ tags-table-set-list
+ tags-add-tables
+ tags-completion-table
+ erlang-buffer
+ erlang-mode-hook
+ prog-mode-hook
+ erlang-shell-mode-hook)
+ (unwind-protect
+ (progn
+ (setq-default tags-file-name nil)
+ (setq-default tags-table-list nil)
+ (erlang-test-create-erlang-file erlang-file)
+ (erlang-test-compile-tags erlang-file tags-file)
+ (setq erlang-buffer (find-file-noselect erlang-file))
+ (if (< emacs-major-version 26)
+ (progn
+ (with-current-buffer erlang-buffer
+ (setq-local tags-file-name tags-file))
+ ;; Setting global tags-file-name is a workaround for
+ ;; GNU Emacs bug#23164.
+ (setq tags-file-name tags-file))
+ (visit-tags-table tags-file t))
+ (erlang-test-complete-at-point tags-file)
+ (erlang-test-completion-table)
+ (erlang-test-xref-find-definitions erlang-file erlang-buffer))
+ (when (buffer-live-p erlang-buffer)
+ (kill-buffer erlang-buffer))
+ (let ((tags-buffer (find-buffer-visiting tags-file)))
+ (when (buffer-live-p tags-buffer)
+ (kill-buffer tags-buffer)))
+ (when (file-exists-p dir)
+ (delete-directory dir t))
+ (setq-default tags-file-name old-tags-file-name)
+ (setq-default tags-table-list old-tags-table-list))))
(defun erlang-test-create-erlang-file (erlang-file)
(with-temp-file erlang-file
@@ -103,12 +142,20 @@ concatenated to form an erlang file to test on.")
for line = 1 then (1+ line)
do (when tagname
(switch-to-buffer erlang-buffer)
- (xref-find-definitions tagname)
- (erlang-test-verify-pos erlang-file line)
- (xref-find-definitions (concat "erlang_test:" tagname))
- (erlang-test-verify-pos erlang-file line)))
- (xref-find-definitions "erlang_test:")
- (erlang-test-verify-pos erlang-file 1))
+ (erlang-test-xref-jump tagname erlang-file line)
+ (erlang-test-xref-jump (concat "erlang_test:" tagname)
+ erlang-file line)))
+ (erlang-test-xref-jump "erlang_test:" erlang-file 1))
+
+(defun erlang-test-xref-jump (id expected-file expected-line)
+ (goto-char (point-max))
+ (insert "\n%% " id)
+ (save-buffer)
+ (if (fboundp 'xref-find-definitions)
+ (xref-find-definitions (erlang-id-to-string
+ (erlang-get-identifier-at-point)))
+ (error "xref-find-definitions not defined (too old emacs?)"))
+ (erlang-test-verify-pos expected-file expected-line))
(defun erlang-test-verify-pos (expected-file expected-line)
(should (string-equal (file-truename expected-file)
@@ -116,6 +163,78 @@ concatenated to form an erlang file to test on.")
(should (eq expected-line (line-number-at-pos)))
(should (= (point-at-bol) (point))))
+(defun erlang-test-complete-at-point (tags-file)
+ (with-temp-buffer
+ (erlang-mode)
+ (setq-local tags-file-name tags-file)
+ (insert "\nerlang_test:fun")
+ (erlang-complete-tag)
+ (should (looking-back "erlang_test:function" (point-at-bol)))
+ (insert "\nfun")
+ (erlang-complete-tag)
+ (should (looking-back "function" (point-at-bol)))
+ (insert "\nerlang_")
+ (erlang-complete-tag)
+ (should (looking-back "erlang_test:" (point-at-bol)))))
+
+
+(ert-deftest erlang-test-compile-options ()
+ (erlang-test-format-opt t
+ "t")
+ (erlang-test-format-opt nil
+ "nil")
+ (erlang-test-format-opt (cons 1 2)
+ "{1, 2}")
+ (erlang-test-format-opt (list 1)
+ "[1]")
+ (erlang-test-format-opt (list 1 2)
+ "[1, 2]")
+ (erlang-test-format-opt (list 1 2 3)
+ "[1, 2, 3]")
+ (erlang-test-format-opt 'symbol
+ "symbol")
+ (erlang-test-format-opt "string"
+ "\"string\"")
+ (erlang-test-format-opt []
+ "{}")
+ (erlang-test-format-opt [1]
+ "{1}")
+ (erlang-test-format-opt [1 2]
+ "{1, 2}")
+ (erlang-test-format-opt [1 2 (3 [4 5 6] 7)]
+ "{1, 2, [3, {4, 5, 6}, 7]}"))
+
+(defun erlang-test-format-opt (elisp &optional expected-erlang)
+ (let ((erlang (inferior-erlang-format-opt elisp)))
+ (message "%s -> %s" elisp erlang)
+ (when expected-erlang
+ (should (equal erlang expected-erlang)))
+ erlang))
+
+
+(ert-deftest erlang-test-parse-id ()
+ (cl-loop for id-string in '("fun/10"
+ "qualified-function module:fun/10"
+ "record reko"
+ "macro _SYMBOL"
+ "macro MACRO/10"
+ "module modula"
+ "macro"
+ nil)
+ for id-list in '((nil nil "fun" 10)
+ (qualified-function "module" "fun" 10)
+ (record nil "reko" nil)
+ (macro nil "_SYMBOL" nil)
+ (macro nil "MACRO" 10)
+ (module nil "modula" nil)
+ (nil nil "macro" nil)
+ nil)
+ for id-list2 = (erlang-id-to-list id-string)
+ do (should (equal id-list id-list2))
+ for id-string2 = (erlang-id-to-string id-list)
+ do (should (equal id-string id-string2))
+ collect id-list2))
+
(provide 'erlang-test)
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index a2062180f3..438abc2d29 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -4,10 +4,12 @@
;; Author: Anders Lindgren
;; Keywords: erlang, languages, processes
;; Date: 2011-12-11
+;; Version: 2.7.0
+;; Package-Requires: ((emacs "24.1"))
;; %CopyrightBegin%
;;
-;; Copyright Ericsson AB 1996-2016. All Rights Reserved.
+;; Copyright Ericsson AB 1996-2017. All Rights Reserved.
;;
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
@@ -24,7 +26,7 @@
;; %CopyrightEnd%
;;
-;; Lars Thors�n's modifications of 2000-06-07 included.
+;; Lars Thorsén's modifications of 2000-06-07 included.
;; The original version of this package was written by Robert Virding.
;;
;;; Commentary:
@@ -59,7 +61,7 @@
;; Please state as exactly as possible:
;; - Version number of Erlang Mode (see the menu), Emacs, Erlang,
-;; and of any other relevant software.
+;; and of any other relevant software.
;; - What the expected result was.
;; - What you did, preferably in a repeatable step-by-step form.
;; - A description of the unexpected result.
@@ -78,54 +80,31 @@
;; Variables:
+(defgroup erlang nil
+ "The Erlang programming language."
+ :group 'languages)
+
(defconst erlang-version "2.7"
"The version number of Erlang mode.")
-(defvar erlang-root-dir nil
+(defcustom erlang-root-dir nil
"The directory where the Erlang system is installed.
The name should not contain the trailing slash.
Should this variable be nil, no manual pages will show up in the
-Erlang mode menu.")
-
-(eval-and-compile
- (defconst erlang-emacs-major-version
- (if (boundp 'emacs-major-version)
- emacs-major-version
- (string-match "\\([0-9]+\\)\\.\\([0-9]+\\)" emacs-version)
- (erlang-string-to-int (substring emacs-version
- (match-beginning 1) (match-end 1))))
- "Major version number of Emacs."))
-
-(eval-and-compile
- (defconst erlang-emacs-minor-version
- (if (boundp 'emacs-minor-version)
- emacs-minor-version
- (string-match "\\([0-9]+\\)\\.\\([0-9]+\\)" emacs-version)
- (erlang-string-to-int (substring emacs-version
- (match-beginning 2) (match-end 2))))
- "Minor version number of Emacs."))
-
-(defconst erlang-xemacs-p (string-match "Lucid\\|XEmacs" emacs-version)
- "Non-nil when running under XEmacs or Lucid Emacs.")
-
-(defvar erlang-xemacs-popup-menu '("Erlang Mode Commands" . nil)
- "Common popup menu for all buffers in Erlang mode.
-
-This variable is destructively modified every time the Erlang menu
-is modified. The effect is that all changes take effect in all
-buffers in Erlang mode, just like under GNU Emacs.
-
-Never EVER set this variable!")
+Erlang mode menu."
+ :group 'erlang
+ :type '(restricted-sexp :match-alternatives (stringp 'nil))
+ :safe (lambda (val) (or (eq nil val) (stringp val))))
(defvar erlang-menu-items '(erlang-menu-base-items
- erlang-menu-skel-items
- erlang-menu-shell-items
- erlang-menu-compile-items
- erlang-menu-man-items
- erlang-menu-personal-items
- erlang-menu-version-items)
- "*List of menu item list to combine to create Erlang mode menu.
+ erlang-menu-skel-items
+ erlang-menu-shell-items
+ erlang-menu-compile-items
+ erlang-menu-man-items
+ erlang-menu-personal-items
+ erlang-menu-version-items)
+ "List of menu item list to combine to create Erlang mode menu.
External programs which temporarily add menu items to the Erlang mode
menu may use this variable. Please use the function `add-hook' to add
@@ -137,17 +116,14 @@ variable.")
(defvar erlang-menu-base-items
'(("Indent"
(("Indent Line" erlang-indent-command)
- ("Indent Region " erlang-indent-region
- (if erlang-xemacs-p (mark) mark-active))
+ ("Indent Region " erlang-indent-region mark-active)
("Indent Clause" erlang-indent-clause)
("Indent Function" erlang-indent-function)
("Indent Buffer" erlang-indent-current-buffer)))
("Edit"
(("Fill Comment" erlang-fill-paragraph)
- ("Comment Region" comment-region
- (if erlang-xemacs-p (mark) mark-active))
- ("Uncomment Region" erlang-uncomment-region
- (if erlang-xemacs-p (mark) mark-active))
+ ("Comment Region" comment-region mark-active)
+ ("Uncomment Region" uncomment-region mark-active)
nil
("Beginning of Function" erlang-beginning-of-function)
("End of Function" erlang-end-of-function)
@@ -170,7 +146,7 @@ variable.")
("TAGS"
(("Find Tag" find-tag)
("Find Next Tag" erlang-find-next-tag)
- ;("Find Regexp" find-tag-regexp)
+ ;("Find Regexp" find-tag-regexp)
("Complete Word" erlang-complete-tag)
("Tags Apropos" tags-apropos)
("Search Files" tags-search))))
@@ -234,7 +210,7 @@ This variable is added to the list of Erlang menus stored in
The menu is in the form described by the variable `erlang-menu-base-items'.")
(defvar erlang-mode-hook nil
- "*Functions to run when Erlang mode is activated.
+ "Functions to run when Erlang mode is activated.
This hook is used to change the behaviour of Erlang mode. It is
normally used by the user to personalise the programming environment.
@@ -268,7 +244,7 @@ To use the example, copy the following lines to your `~/.emacs' file:
(imenu-add-to-menubar \"Imenu\")))")
(defvar erlang-load-hook nil
- "*Functions to run when Erlang mode is loaded.
+ "Functions to run when Erlang mode is loaded.
This hook is used to change the behaviour of Erlang mode. It is
normally used by the user to personalise the programming environment.
@@ -300,17 +276,20 @@ manual pages can be retrieved (note that you must set the value of
A useful function is `tempo-template-erlang-normal-header'.
\(This function only exists when the `tempo' package is available.)")
-(defvar erlang-check-module-name 'ask
- "*Non-nil means check that module name and file name agrees when saving.
+(defcustom erlang-check-module-name 'ask
+ "Non-nil means check that module name and file name agrees when saving.
-If the value of this variable is the atom `ask', the user is
-prompted. If the value is t the source is silently changed.")
+If the value of this variable is the symbol `ask', the user is
+prompted. If the value is t the source is silently changed."
+ :group 'erlang
+ :type '(choice (const :tag "Check on save" 'ask)
+ (const :tag "Don't check on save" t)))
(defvar erlang-electric-commands
'(erlang-electric-comma
erlang-electric-semicolon
erlang-electric-gt)
- "*List of activated electric commands.
+ "List of activated electric commands.
The list should contain the electric commands which should be active.
Currently, the available electric commands are:
@@ -324,8 +303,8 @@ are activated.
To deactivate all electric commands, set this variable to nil.")
-(defvar erlang-electric-newline-inhibit t
- "*Set to non-nil to inhibit newline after electric command.
+(defcustom erlang-electric-newline-inhibit t
+ "Set to non-nil to inhibit newline after electric command.
This is useful since a lot of people press return after executing an
electric command.
@@ -335,28 +314,32 @@ list `erlang-electric-newline-inhibit-list'.
Note that commands in this list are required to set the variable
`erlang-electric-newline-inhibit' to nil when the newline shouldn't be
-inhibited.")
+inhibited."
+ :group 'erlang
+ :type 'boolean
+ :safe 'booleanp)
(defvar erlang-electric-newline-inhibit-list
'(erlang-electric-semicolon
erlang-electric-comma
erlang-electric-gt)
- "*Commands which can inhibit the next newline.")
+ "Commands which can inhibit the next newline.")
-(defvar erlang-electric-semicolon-insert-blank-lines nil
- "*Number of blank lines inserted before header, or nil.
+(defcustom erlang-electric-semicolon-insert-blank-lines nil
+ "Number of blank lines inserted before header, or nil.
This variable controls the behaviour of `erlang-electric-semicolon'
when a new function header is generated. When nil, no blank line is
inserted between the current line and the new header. When bound to a
number it represents the number of blank lines which should be
-inserted.")
+inserted."
+ :group 'erlang)
(defvar erlang-electric-semicolon-criteria
'(erlang-next-lines-empty-p
erlang-at-keyword-end-p
erlang-at-end-of-function-p)
- "*List of functions controlling `erlang-electric-semicolon'.
+ "List of functions controlling `erlang-electric-semicolon'.
The functions in this list are called, in order, whenever a semicolon
is typed. Each function in the list is called with no arguments,
and should return one of the following values:
@@ -377,7 +360,7 @@ The test is performed by the function `erlang-test-criteria-list'.")
erlang-at-keyword-end-p
erlang-at-end-of-clause-p
erlang-at-end-of-function-p)
- "*List of functions controlling `erlang-electric-comma'.
+ "List of functions controlling `erlang-electric-comma'.
The functions in this list are called, in order, whenever a comma
is typed. Each function in the list is called with no arguments,
and should return one of the following values:
@@ -395,7 +378,7 @@ The test is performed by the function `erlang-test-criteria-list'.")
'(erlang-stop-when-in-type-spec
erlang-next-lines-empty-p
erlang-at-end-of-function-p)
- "*List of functions controlling the arrow aspect of `erlang-electric-gt'.
+ "List of functions controlling the arrow aspect of `erlang-electric-gt'.
The functions in this list are called, in order, whenever a `>'
is typed. Each function in the list is called with no arguments,
and should return one of the following values:
@@ -411,7 +394,7 @@ The test is performed by the function `erlang-test-criteria-list'.")
(defvar erlang-electric-newline-criteria
'(t)
- "*List of functions controlling `erlang-electric-newline'.
+ "List of functions controlling `erlang-electric-newline'.
The electric newline commands indents the next line. Should the
current line begin with a comment the comment start is copied to
@@ -431,8 +414,8 @@ list, it is treated as a function triggering the electric command.
The test is performed by the function `erlang-test-criteria-list'.")
-(defvar erlang-next-lines-empty-threshold 2
- "*Number of blank lines required to activate an electric command.
+(defcustom erlang-next-lines-empty-threshold 2
+ "Number of blank lines required to activate an electric command.
Actually, this value controls the behaviour of the function
`erlang-next-lines-empty-p' which normally is a member of the
@@ -453,41 +436,67 @@ function `erlang-next-lines-empty-p' would be removed from the criteria
lists.
Note that even if `erlang-next-lines-empty-p' should not trigger an
-electric command, other functions in the criteria list could.")
+electric command, other functions in the criteria list could."
+ :group 'erlang
+ :type '(restricted-sexp :match-alternatives (integerp 'nil))
+ :safe (lambda (val) (or (eq val nil) (integerp val))))
-(defvar erlang-new-clause-with-arguments nil
- "*Non-nil means that the arguments are cloned when a clause is generated.
+(defcustom erlang-new-clause-with-arguments nil
+ "Non-nil means that the arguments are cloned when a clause is generated.
A new function header can be generated by calls to the function
-`erlang-generate-new-clause' and by use of the electric semicolon.")
+`erlang-generate-new-clause' and by use of the electric semicolon."
+ :group 'erlang
+ :type 'boolean
+ :safe 'booleanp)
-(defvar erlang-compile-use-outdir t
- "*When nil, go to the directory containing source file when compiling.
+(defcustom erlang-compile-use-outdir t
+ "When nil, go to the directory containing source file when compiling.
This is a workaround for a bug in the `outdir' option of compile. If the
outdir is not in the current load path, Erlang doesn't load the object
module after it has been compiled.
To activate the workaround, place the following in your `~/.emacs' file:
- (setq erlang-compile-use-outdir nil)")
-
-(defvar erlang-indent-level 4
- "*Indentation of Erlang calls/clauses within blocks.")
-(put 'erlang-indent-level 'safe-local-variable 'integerp)
-
-(defvar erlang-indent-guard 2
- "*Indentation of Erlang guards.")
-(put 'erlang-indent-guard 'safe-local-variable 'integerp)
-
-(defvar erlang-argument-indent 2
- "*Indentation of the first argument in a function call.
+ (setq erlang-compile-use-outdir nil)"
+ :group 'erlang
+ :type 'boolean
+ :safe 'booleanp)
+
+(defcustom erlang-indent-level 4
+ "Indentation of Erlang calls/clauses within blocks."
+ :group 'erlang
+ :type 'integer
+ :safe 'integerp)
+
+(defcustom erlang-icr-indent nil
+ "Indentation of Erlang if/case/receive patterns.
+nil means keeping default behavior. When non-nil, indent to the column of
+if/case/receive."
+ :group 'erlang
+ :type 'boolean
+ :safe 'booleanp)
+
+(defcustom erlang-indent-guard 2
+ "Indentation of Erlang guards."
+ :group 'erlang
+ :type 'integer
+ :safe 'integerp)
+
+(defcustom erlang-argument-indent 2
+ "Indentation of the first argument in a function call.
When nil, indent to the column after the `(' of the
-function.")
-(put 'erlang-argument-indent 'safe-local-variable '(lambda (val) (or (null val) (integerp val))))
-
-(defvar erlang-tab-always-indent t
- "*Non-nil means TAB in Erlang mode should always re-indent the current line,
-regardless of where in the line point is when the TAB command is used.")
+function."
+ :group 'erlang
+ :type '(restricted-sexp :match-alternatives (integerp 'nil))
+ :safe (lambda (val) (or (eq val nil) (integerp val))))
+
+(defcustom erlang-tab-always-indent t
+ "Non-nil means TAB in Erlang mode should always re-indent the current line,
+regardless of where in the line point is when the TAB command is used."
+ :group 'erlang
+ :type 'boolean
+ :safe 'booleanp)
(defvar erlang-man-inhibit (eq system-type 'windows-nt)
"Inhibit the creation of the Erlang Manual Pages menu.
@@ -500,7 +509,7 @@ there is no attempt to create the menu.")
("Man - Modules" "/man/man3" t)
("Man - Files" "/man/man4" t)
("Man - Applications" "/man/man6" t))
- "*The man directories displayed in the Erlang menu.
+ "The man directories displayed in the Erlang menu.
Each item in the list should be a list with three elements, the first
the name of the menu, the second the directory, and the last a flag.
@@ -508,17 +517,17 @@ Should the flag the nil, the directory is absolute, should it be non-nil
the directory is relative to the variable `erlang-root-dir'.")
(defvar erlang-man-max-menu-size 35
- "*The maximum number of menu items in one menu allowed.")
+ "The maximum number of menu items in one menu allowed.")
(defvar erlang-man-display-function 'erlang-man-display
- "*Function used to display man page.
+ "Function used to display man page.
The function is called with one argument, the name of the file
containing the man page. Use this variable when the default
function, `erlang-man-display', does not work on your system.")
(defvar erlang-compile-extra-opts '()
- "*Additional options to the compilation command.
+ "Additional options to the compilation command.
This is an elisp list of options. Each option can be either:
- an atom
- a dotted pair
@@ -530,7 +539,7 @@ Example: '(bin_opt_info (i . \"/path1/include\") (i . \"/path2/include\"))")
(".xrl\\'" . inferior-erlang-compute-leex-compile-command)
(".yrl\\'" . inferior-erlang-compute-yecc-compile-command)
("." . inferior-erlang-compute-erl-compile-command))
- "*Alist of filename patterns vs corresponding compilation functions.
+ "Alist of filename patterns vs corresponding compilation functions.
Each element looks like (REGEXP . FUNCTION). Compiling a file whose name
matches REGEXP specifies FUNCTION to use to compute the compilation
command. The FUNCTION will be called with two arguments: module name and
@@ -538,55 +547,54 @@ default compilation options, like output directory. The FUNCTION
is expected to return a string.")
(defvar erlang-leex-compile-opts '()
- "*Options to pass to leex when compiling xrl files.
+ "Options to pass to leex when compiling xrl files.
This is an elisp list of options. Each option can be either:
- an atom
- a dotted pair
- a string")
(defvar erlang-yecc-compile-opts '()
- "*Options to pass to yecc when compiling yrl files.
+ "Options to pass to yecc when compiling yrl files.
This is an elisp list of options. Each option can be either:
- an atom
- a dotted pair
- a string")
(eval-and-compile
- (defvar erlang-regexp-modern-p
- (if (> erlang-emacs-major-version 21) t nil)
+ (defvar erlang-regexp-modern-p t
"Non-nil when this version of Emacs uses a modern version of regexp.
Supporting \_< and \_> This is determined by checking the version of Emacs used."))
(eval-and-compile
- (defconst erlang-atom-quoted-regexp
+ (defconst erlang-atom-quoted-regexp
"'\\(?:[^\\']\\|\\(?:\\\\.\\)\\)*'"
"Regexp describing a single-quoted atom"))
(eval-and-compile
(defconst erlang-atom-regular-regexp
(if erlang-regexp-modern-p
- "\\_<[[:lower:]]\\(?:\\sw\\|\\s_\\)*\\_>"
+ "\\_<[[:lower:]]\\(?:\\sw\\|\\s_\\)*\\_>"
"\\<[[:lower:]]\\(?:\\sw\\|\\s_\\)*\\>")
"Regexp describing a regular (non-quoted) atom"))
(eval-and-compile
- (defconst erlang-atom-regexp
- (concat "\\(" erlang-atom-quoted-regexp "\\|"
- erlang-atom-regular-regexp "\\)")
+ (defconst erlang-atom-regexp
+ (concat "\\(" erlang-atom-quoted-regexp "\\|"
+ erlang-atom-regular-regexp "\\)")
"Regexp describing an Erlang atom."))
(eval-and-compile
(defconst erlang-atom-regexp-matches 1
"Number of regexp parenthesis pairs in `erlang-atom-regexp'.
-
+
This is used to determine parenthesis matches in complex regexps which
contains `erlang-atom-regexp'."))
(eval-and-compile
- (defconst erlang-variable-regexp
- (if erlang-regexp-modern-p
- "\\_<\\([[:upper:]_]\\(?:\\sw\\|\\s_\\)*\\)\\_>"
+ (defconst erlang-variable-regexp
+ (if erlang-regexp-modern-p
+ "\\_<\\([[:upper:]_]\\(?:\\sw\\|\\s_\\)*\\)\\_>"
"\\<\\([[:upper:]_]\\(?:\\sw\\|\\s_\\)*\\)\\>")
"Regexp which should match an Erlang variable.
@@ -599,19 +607,37 @@ The regexp must be surrounded with a pair of regexp parentheses."))
This is used to determine matches in complex regexps which contains
`erlang-variable-regexp'."))
+(defconst erlang-module-function-regexp
+ (eval-when-compile
+ (concat erlang-atom-regexp ":" erlang-atom-regexp))
+ "Regexp matching an erlang module:function.")
+
+(defconst erlang-name-regexp
+ (concat "\\("
+ "\\(?:\\sw\\|\\s_\\)+"
+ "\\|"
+ erlang-atom-quoted-regexp
+ "\\)")
+ "Matches a name of a function, macro or record")
+
+(defconst erlang-id-regexp
+ (concat "\\(?:\\(qualified-function\\|record\\|macro\\|module\\) \\)?"
+ "\\(?:" erlang-atom-regexp ":\\)?"
+ erlang-name-regexp "?"
+ "\\(?:/\\([0-9]+\\)\\)?"))
(eval-and-compile
(defun erlang-regexp-opt (strings &optional paren)
"Like `regexp-opt', except if PAREN is `symbols', then the
resulting regexp is surrounded by \\_< and \\_>."
(if (eq paren 'symbols)
- (if erlang-regexp-modern-p
- (concat "\\_<" (regexp-opt strings t) "\\_>")
- (concat "\\<" (regexp-opt strings t) "\\>"))
+ (if erlang-regexp-modern-p
+ (concat "\\_<" (regexp-opt strings t) "\\_>")
+ (concat "\\<" (regexp-opt strings t) "\\>"))
(regexp-opt strings paren))))
-(eval-and-compile
+(eval-and-compile
(defvar erlang-keywords
'("after"
"begin"
@@ -630,7 +656,7 @@ resulting regexp is surrounded by \\_< and \\_>."
(eval-and-compile
(defconst erlang-keywords-regexp (erlang-regexp-opt erlang-keywords 'symbols)))
-
+
(eval-and-compile
(defvar erlang-operators
'("and"
@@ -653,7 +679,7 @@ resulting regexp is surrounded by \\_< and \\_>."
(eval-and-compile
(defconst erlang-operators-regexp (erlang-regexp-opt erlang-operators 'symbols)))
-
+
(eval-and-compile
(defvar erlang-guards
@@ -676,7 +702,7 @@ resulting regexp is surrounded by \\_< and \\_>."
"binary"
"bitstring"
"boolean"
- ;;"float" ; Not included to avoid clashes with the bif float/1
+ ;;"float" ; Not included to avoid clashes with the bif float/1
"function"
"integer"
"list"
@@ -722,7 +748,7 @@ resulting regexp is surrounded by \\_< and \\_>."
"Erlang type specs types"))
(eval-and-compile
- (defconst erlang-predefined-types-regexp
+ (defconst erlang-predefined-types-regexp
(erlang-regexp-opt erlang-predefined-types 'symbols)))
@@ -743,6 +769,7 @@ resulting regexp is surrounded by \\_< and \\_>."
"bitsize"
"bitstring_to_list"
"byte_size"
+ "ceil"
"check_old_code"
"check_process_code"
"date"
@@ -753,6 +780,7 @@ resulting regexp is surrounded by \\_< and \\_>."
"erase"
"error"
"exit"
+ "floor"
"float"
"float_to_binary"
"float_to_list"
@@ -792,6 +820,8 @@ resulting regexp is surrounded by \\_< and \\_>."
"list_to_float"
"list_to_integer"
"list_to_pid"
+ "list_to_port"
+ "list_to_ref"
"list_to_tuple"
"load_module"
"make_ref"
@@ -810,12 +840,14 @@ resulting regexp is surrounded by \\_< and \\_>."
"port_command"
"port_connect"
"port_control"
+ "port_to_list"
"pre_loaded"
"process_flag"
"process_info"
"processes"
"purge_module"
"put"
+ "ref_to_list"
"register"
"registered"
"round"
@@ -842,7 +874,7 @@ resulting regexp is surrounded by \\_< and \\_>."
(eval-and-compile
(defconst erlang-int-bif-regexp (erlang-regexp-opt erlang-int-bifs 'symbols)))
-
+
(eval-and-compile
(defvar erlang-ext-bifs
@@ -896,7 +928,6 @@ resulting regexp is surrounded by \\_< and \\_>."
"get_cookie"
"get_module_info"
"get_stacktrace"
- "hash"
"has_prepared_code_on_load"
"hibernate"
"insert_element"
@@ -923,14 +954,12 @@ resulting regexp is surrounded by \\_< and \\_>."
"port_get_data"
"port_info"
"port_set_data"
- "port_to_list"
"ports"
"posixtime_to_universaltime"
"prepare_loading"
"process_display"
"raise"
"read_timer"
- "ref_to_list"
"resume_process"
"send"
"send_after"
@@ -972,7 +1001,7 @@ resulting regexp is surrounded by \\_< and \\_>."
"Regexp which should match beginning of a clause.")
(defvar erlang-file-name-extension-regexp "\\.erl$"
- "*Regexp which should match an Erlang file name.
+ "Regexp which should match an Erlang file name.
This regexp is used when an Erlang module name is extracted from the
name of an Erlang source file.
@@ -986,7 +1015,7 @@ tags system should interpret tags on the form `module:tag' for
files written in other languages than Erlang.")
(defvar erlang-inferior-shell-split-window t
- "*If non-nil, when starting an inferior shell, split windows.
+ "If non-nil, when starting an inferior shell, split windows.
If nil, the inferior shell replaces the window. This is the traditional
behaviour.")
@@ -997,8 +1026,8 @@ behaviour.")
(let ((map (make-sparse-keymap)))
(unless (boundp 'indent-line-function)
(define-key map "\t" 'erlang-indent-command))
- (define-key map ";" 'erlang-electric-semicolon)
- (define-key map "," 'erlang-electric-comma)
+ (define-key map ";" 'erlang-electric-semicolon)
+ (define-key map "," 'erlang-electric-comma)
(define-key map "<" 'erlang-electric-lt)
(define-key map ">" 'erlang-electric-gt)
(define-key map "\C-m" 'erlang-electric-newline)
@@ -1009,8 +1038,7 @@ behaviour.")
(define-key map "\M-q" 'erlang-fill-paragraph)
(unless (boundp 'beginning-of-defun-function)
(define-key map "\M-\C-a" 'erlang-beginning-of-function)
- (define-key map "\M-\C-e" 'erlang-end-of-function)
- (define-key map '(meta control h) 'erlang-mark-function)) ; Xemacs
+ (define-key map "\M-\C-e" 'erlang-end-of-function))
(define-key map "\M-\t" 'erlang-complete-tag)
(define-key map "\C-c\M-\t" 'tempo-complete-tag)
(define-key map "\M-+" 'erlang-find-next-tag)
@@ -1025,14 +1053,14 @@ behaviour.")
(define-key map "\C-c\C-l" 'erlang-compile-display)
(define-key map "\C-c\C-s" 'erlang-show-syntactic-information)
(define-key map "\C-c\C-q" 'erlang-indent-function)
- (define-key map "\C-c\C-u" 'erlang-uncomment-region)
+ (define-key map "\C-c\C-u" 'uncomment-region)
(define-key map "\C-c\C-y" 'erlang-clone-arguments)
(define-key map "\C-c\C-a" 'erlang-align-arrows)
(define-key map "\C-c\C-z" 'erlang-shell-display)
(unless inferior-erlang-use-cmm
(define-key map "\C-x`" 'erlang-next-error))
map)
- "*Keymap used in Erlang mode.")
+ "Keymap used in Erlang mode.")
(defvar erlang-mode-abbrev-table nil
"Abbrev table in use in Erlang-mode buffers.")
(defvar erlang-mode-syntax-table nil
@@ -1064,16 +1092,11 @@ behaviour.")
(defvar erlang-font-lock-keywords-function-header
(list
(list (concat "^" erlang-atom-regexp "\\s-*(")
- 1 'font-lock-function-name-face t))
+ 1 'font-lock-function-name-face t))
"Font lock keyword highlighting a function header.")
(defface erlang-font-lock-exported-function-name-face
- (if (featurep 'xemacs)
- (progn
- (require 'font-lock)
- `((t (:foreground ,(face-foreground 'font-lock-function-name-face))
- (:background ,(face-background 'font-lock-function-name-face)))))
- '((default (:inherit font-lock-function-name-face))))
+ '((default (:inherit font-lock-function-name-face)))
"Face used for highlighting exported functions."
:group 'erlang)
@@ -1086,7 +1109,7 @@ behaviour.")
(defvar erlang-font-lock-keywords-exported-function-header
(list
(list #'erlang-match-next-exported-function
- 1 'erlang-font-lock-exported-function-name-face t))
+ 1 'erlang-font-lock-exported-function-name-face t))
"Font lock keyword highlighting an exported function header.")
(defvar erlang-font-lock-keywords-int-bifs
@@ -1098,8 +1121,8 @@ behaviour.")
(defvar erlang-font-lock-keywords-ext-bifs
(list
(list (concat "\\<\\(erlang\\)\\s-*:\\s-*" erlang-ext-bif-regexp "\\s-*(")
- '(1 'font-lock-builtin-face)
- '(2 'font-lock-builtin-face)))
+ '(1 'font-lock-builtin-face)
+ '(2 'font-lock-builtin-face)))
"Font lock keyword highlighting built in functions.")
(defvar erlang-font-lock-keywords-int-function-calls
@@ -1113,7 +1136,7 @@ behaviour.")
(list (concat erlang-atom-regexp "\\s-*:\\s-*"
erlang-atom-regexp "\\s-*(")
'(1 'font-lock-type-face)
- '(2 'font-lock-type-face)))
+ '(2 'font-lock-type-face)))
"Font lock keyword highlighting an external function call.")
(defvar erlang-font-lock-keywords-fun-n
@@ -1131,7 +1154,7 @@ behaviour.")
(defvar erlang-font-lock-keywords-dollar
(list
(list "\\(\\$\\([^\\]\\|\\\\\\([^0-7^\n]\\|[0-7]+\\|\\^[a-zA-Z]\\)\\)\\)"
- 1 'font-lock-constant-face))
+ 1 'font-lock-constant-face))
"Font lock keyword highlighting numbers in ASCII form (e.g. $A).")
(defvar erlang-font-lock-keywords-arrow
@@ -1151,18 +1174,18 @@ behaviour.")
(defvar erlang-font-lock-keywords-attr
(list
- (list (concat "^\\(-" erlang-atom-regexp "\\)\\(\\s-\\|\\.\\|(\\)")
- 1 (if (boundp 'font-lock-preprocessor-face)
- 'font-lock-preprocessor-face
- 'font-lock-constant-face)))
+ (list (concat "^\\(-" erlang-atom-regexp "\\)\\(\\s-\\|\\.\\|(\\)")
+ 1 (if (boundp 'font-lock-preprocessor-face)
+ 'font-lock-preprocessor-face
+ 'font-lock-constant-face)))
"Font lock keyword highlighting attributes.")
(defvar erlang-font-lock-keywords-quotes
(list
(list "`\\([-+a-zA-Z0-9_:*][-+a-zA-Z0-9_:*]+\\)'"
- 1
- 'font-lock-keyword-face
- t))
+ 1
+ 'font-lock-keyword-face
+ t))
"Font lock keyword highlighting words in single quotes in comments.
This is not the highlighting of Erlang strings and atoms, which
@@ -1171,27 +1194,27 @@ are highlighted by syntactic analysis.")
(defvar erlang-font-lock-keywords-guards
(list
(list (concat "[^:]" erlang-guards-regexp "\\s-*(")
- 1 'font-lock-builtin-face))
+ 1 'font-lock-builtin-face))
"Font lock keyword highlighting guards.")
(defvar erlang-font-lock-keywords-predefined-types
(list
(list (concat "[^:]" erlang-predefined-types-regexp "\\s-*(")
- 1 'font-lock-builtin-face))
+ 1 'font-lock-builtin-face))
"Font lock keyword highlighting predefined types.")
(defvar erlang-font-lock-keywords-macros
(list
(list (concat "?\\s-*\\(" erlang-atom-regexp
- "\\|" erlang-variable-regexp "\\)")
- 1 'font-lock-constant-face)
+ "\\|" erlang-variable-regexp "\\)")
+ 1 'font-lock-constant-face)
(list (concat "^\\(-\\(?:define\\|ifn?def\\)\\)\\s-*(\\s-*\\(" erlang-atom-regexp
- "\\|" erlang-variable-regexp "\\)")
- (if (boundp 'font-lock-preprocessor-face)
- (list 1 'font-lock-preprocessor-face t)
- (list 1 'font-lock-constant-face t))
- (list 3 'font-lock-type-face t t))
+ "\\|" erlang-variable-regexp "\\)")
+ (if (boundp 'font-lock-preprocessor-face)
+ (list 1 'font-lock-preprocessor-face t)
+ (list 1 'font-lock-constant-face t))
+ (list 3 'font-lock-type-face t t))
(list "^-e\\(lse\\|ndif\\)\\>" 0 'font-lock-preprocessor-face t))
"Font lock keyword highlighting macros.
This must be placed in front of `erlang-font-lock-keywords-vars'.")
@@ -1202,8 +1225,8 @@ This must be placed in front of `erlang-font-lock-keywords-vars'.")
1 'font-lock-type-face)
;; Don't highlight numerical constants.
(list (if erlang-regexp-modern-p
- "\\_<[0-9]+#\\([0-9a-zA-Z]+\\)"
- "\\<[0-9]+#\\([0-9a-zA-Z]+\\)")
+ "\\_<[0-9]+#\\([0-9a-zA-Z]+\\)"
+ "\\<[0-9]+#\\([0-9a-zA-Z]+\\)")
1 nil t)
(list (concat "^-record\\s-*(\\s-*" erlang-atom-regexp)
1 'font-lock-type-face))
@@ -1212,8 +1235,8 @@ This must be placed in front of `erlang-font-lock-keywords-vars'.")
(defvar erlang-font-lock-keywords-vars
(list
- (list (concat "[^#]" erlang-variable-regexp) ; no numerical constants
- 1 'font-lock-variable-name-face))
+ (list (concat "[^#]" erlang-variable-regexp) ; no numerical constants
+ 1 'font-lock-variable-name-face))
"Font lock keyword highlighting Erlang variables.
Must be preceded by `erlang-font-lock-keywords-macros' to work properly.")
@@ -1236,32 +1259,32 @@ Example:
(defvar erlang-font-lock-keywords-1
(append erlang-font-lock-keywords-function-header
- erlang-font-lock-keywords-dollar
- erlang-font-lock-keywords-arrow
- erlang-font-lock-keywords-keywords
- )
+ erlang-font-lock-keywords-dollar
+ erlang-font-lock-keywords-arrow
+ erlang-font-lock-keywords-keywords
+ )
;; DocStringOrig: erlang-font-lock-keywords
erlang-font-lock-descr-string)
(defvar erlang-font-lock-keywords-2
(append erlang-font-lock-keywords-1
- erlang-font-lock-keywords-int-bifs
- erlang-font-lock-keywords-ext-bifs
- erlang-font-lock-keywords-attr
- erlang-font-lock-keywords-quotes
- erlang-font-lock-keywords-guards
- )
+ erlang-font-lock-keywords-int-bifs
+ erlang-font-lock-keywords-ext-bifs
+ erlang-font-lock-keywords-attr
+ erlang-font-lock-keywords-quotes
+ erlang-font-lock-keywords-guards
+ )
;; DocStringCopy: erlang-font-lock-keywords
erlang-font-lock-descr-string)
(defvar erlang-font-lock-keywords-3
(append erlang-font-lock-keywords-2
- erlang-font-lock-keywords-operators
- erlang-font-lock-keywords-macros
- erlang-font-lock-keywords-records
- erlang-font-lock-keywords-vars
- erlang-font-lock-keywords-predefined-types
- )
+ erlang-font-lock-keywords-operators
+ erlang-font-lock-keywords-macros
+ erlang-font-lock-keywords-records
+ erlang-font-lock-keywords-vars
+ erlang-font-lock-keywords-predefined-types
+ )
;; DocStringCopy: erlang-font-lock-keywords
erlang-font-lock-descr-string)
@@ -1269,10 +1292,10 @@ Example:
(append erlang-font-lock-keywords-3
erlang-font-lock-keywords-exported-function-header
erlang-font-lock-keywords-int-function-calls
- erlang-font-lock-keywords-ext-function-calls
- erlang-font-lock-keywords-fun-n
+ erlang-font-lock-keywords-ext-function-calls
+ erlang-font-lock-keywords-fun-n
erlang-font-lock-keywords-lc
- )
+ )
;; DocStringCopy: erlang-font-lock-keywords
erlang-font-lock-descr-string)
@@ -1285,11 +1308,7 @@ Example:
The difference between this and the standard Erlang Mode
syntax table is that `_' is treated as part of words by
-this syntax table.
-
-Unfortunately, XEmacs hasn't got support for a special Font
-Lock syntax table. The effect is that `apply' in the atom
-`foo_apply' will be highlighted as a bif.")
+this syntax table.")
(defvar erlang-replace-etags-tags-completion-table nil
"Internal flag used by advice `erlang-replace-tags-table'.
@@ -1299,29 +1318,6 @@ replaced by `erlang-etags-tags-completion-table'.")
;;; Avoid errors while compiling this file.
-;; `eval-when-compile' is not defined in Emacs 18. We define it as a
-;; no-op.
-(or (fboundp 'eval-when-compile)
- (defmacro eval-when-compile (&rest rest) nil))
-
-;; These umm...functions are new in Emacs 20. And, yes, until version
-;; 19.27 Emacs backquotes were this ugly.
-
-(or (fboundp 'unless)
- (defmacro unless (condition &rest body)
- "(unless CONDITION BODY...): If CONDITION is false, do BODY, else return nil."
- `((if (, condition) nil ,@body))))
-
-(or (fboundp 'when)
- (defmacro when (condition &rest body)
- "(when CONDITION BODY...): If CONDITION is true, do BODY, else return nil."
- `((if (, condition) (progn ,@body) nil))))
-
-(or (fboundp 'char-before)
- (defmacro char-before (&optional pos)
- "Return the character in the current buffer just before POS."
- `( (char-after (1- (or ,pos (point)))))))
-
;; defvar some obsolete variables, which we still support for
;; backwards compatibility reasons.
(eval-when-compile
@@ -1332,37 +1328,19 @@ replaced by `erlang-etags-tags-completion-table'.")
(defvar next-error-last-buffer))
(eval-when-compile
- (if (or (featurep 'bytecomp)
- (featurep 'byte-compile))
- (progn
- (cond ((string-match "Lucid\\|XEmacs" emacs-version)
- (put 'comment-indent-hook 'byte-obsolete-variable nil)
- ;; Do not warn for unused variables
- ;; when compiling under XEmacs.
- (setq byte-compile-warnings
- '(free-vars unresolved callargs redefine))))
- (require 'comint)
- (require 'tempo)
- (require 'compile))))
+ (require 'comint)
+ (require 'tempo)
+ (require 'compile))
(defun erlang-version ()
"Return the current version of Erlang mode."
(interactive)
- (if (erlang-interactive-p)
+ (if (called-interactively-p 'interactive)
(message "Erlang mode version %s, written by Anders Lindgren"
- erlang-version))
+ erlang-version))
erlang-version)
-(defun erlang-interactive-p ()
- (if (fboundp 'called-interactively-p)
- (called-interactively-p 'interactive)
- (funcall (symbol-function 'interactive-p))))
-
-(unless (fboundp 'prog-mode)
- (defun prog-mode ()
- (use-local-map (make-keymap))))
-
;;;###autoload
(define-derived-mode erlang-mode prog-mode "Erlang"
"Major mode for editing Erlang source files in Emacs.
@@ -1389,7 +1367,7 @@ useful commands:
C-c C-q - Indent current function.
M-; - Create a comment at the end of the line.
M-q - Fill a comment, i.e. wrap lines so that they (hopefully)
- will look better.
+ will look better.
M-a - Goto the beginning of an Erlang clause.
M-C-a - Ditto for function.
M-e - Goto the end of an Erlang clause.
@@ -1434,10 +1412,12 @@ Other commands:
(erlang-tags-init)
(erlang-font-lock-init)
(erlang-skel-init)
- (when (fboundp 'tempo-use-tag-list)
- (tempo-use-tag-list 'erlang-tempo-tags))
- (when (boundp 'xref-backend-functions)
- (add-hook 'xref-backend-functions #'erlang-etags--xref-backend nil t))
+ (tempo-use-tag-list 'erlang-tempo-tags)
+ (when (and (fboundp 'add-function) (fboundp 'erldoc-eldoc-function))
+ (or eldoc-documentation-function
+ (setq-local eldoc-documentation-function #'ignore))
+ (add-function :before-until (local 'eldoc-documentation-function)
+ #'erldoc-eldoc-function))
(run-hooks 'erlang-mode-hook)
(if (zerop (buffer-size))
(run-hooks 'erlang-new-file-hook)))
@@ -1448,52 +1428,54 @@ Other commands:
(add-to-list 'auto-mode-alist (cons r 'erlang-mode)))
(defun erlang-syntax-table-init ()
- (if (null erlang-mode-syntax-table)
- (let ((table (make-syntax-table)))
- (modify-syntax-entry ?\n ">" table)
- (modify-syntax-entry ?\" "\"" table)
- (modify-syntax-entry ?# "." table)
-;; (modify-syntax-entry ?$ "\\" table) ;; Creates problems with indention afterwards
-;; (modify-syntax-entry ?$ "'" table) ;; Creates syntax highlighting and indention problems
- (modify-syntax-entry ?$ "/" table) ;; Misses the corner case "string that ends with $"
- ;; we have to live with that for now..it is the best alternative
- ;; that can be worked around with "string hat ends with \$"
- (modify-syntax-entry ?% "<" table)
- (modify-syntax-entry ?& "." table)
- (modify-syntax-entry ?\' "\"" table)
- (modify-syntax-entry ?* "." table)
- (modify-syntax-entry ?+ "." table)
- (modify-syntax-entry ?- "." table)
- (modify-syntax-entry ?/ "." table)
- (modify-syntax-entry ?: "." table)
- (modify-syntax-entry ?< "." table)
- (modify-syntax-entry ?= "." table)
- (modify-syntax-entry ?> "." table)
- (modify-syntax-entry ?\\ "\\" table)
- (modify-syntax-entry ?_ "_" table)
- (modify-syntax-entry ?| "." table)
- (modify-syntax-entry ?^ "'" table)
-
- ;; Pseudo bit-syntax: Latin1 double angle quotes as parens.
- ;;(modify-syntax-entry ?\253 "(?\273" table)
- ;;(modify-syntax-entry ?\273 ")?\253" table)
-
- (setq erlang-mode-syntax-table table)))
-
+ (erlang-ensure-syntax-table-is-initialized)
(set-syntax-table erlang-mode-syntax-table))
+(defun erlang-ensure-syntax-table-is-initialized ()
+ (unless erlang-mode-syntax-table
+ (let ((table (make-syntax-table)))
+ (modify-syntax-entry ?\n ">" table)
+ (modify-syntax-entry ?\" "\"" table)
+ (modify-syntax-entry ?# "." table)
+ ;; (modify-syntax-entry ?$ "\\" table) ;; Creates problems with indention afterwards
+ ;; (modify-syntax-entry ?$ "'" table) ;; Creates syntax highlighting and indention problems
+ (modify-syntax-entry ?$ "/" table) ;; Misses the corner case "string that ends with $"
+ ;; we have to live with that for now..it is the best alternative
+ ;; that can be worked around with "string that ends with \$"
+ (modify-syntax-entry ?% "<" table)
+ (modify-syntax-entry ?& "." table)
+ (modify-syntax-entry ?\' "\"" table)
+ (modify-syntax-entry ?* "." table)
+ (modify-syntax-entry ?+ "." table)
+ (modify-syntax-entry ?- "." table)
+ (modify-syntax-entry ?/ "." table)
+ (modify-syntax-entry ?: "." table)
+ (modify-syntax-entry ?< "." table)
+ (modify-syntax-entry ?= "." table)
+ (modify-syntax-entry ?> "." table)
+ (modify-syntax-entry ?\\ "\\" table)
+ (modify-syntax-entry ?_ "_" table)
+ (modify-syntax-entry ?| "." table)
+ (modify-syntax-entry ?^ "'" table)
+
+ ;; Pseudo bit-syntax: Latin1 double angle quotes as parens.
+ ;;(modify-syntax-entry ?\253 "(?\273" table)
+ ;;(modify-syntax-entry ?\273 ")?\253" table)
+
+ (setq erlang-mode-syntax-table table))))
+
+
(defun erlang-electric-init ()
;; Set up electric character functions to work with
;; delsel/pending-del mode. Also, set up text properties for bit
;; syntax handling.
(mapc #'(lambda (cmd)
- (put cmd 'delete-selection t) ;for delsel (Emacs)
- (put cmd 'pending-delete t)) ;for pending-del (XEmacs)
- '(erlang-electric-semicolon
- erlang-electric-comma
- erlang-electric-gt))
-
+ (put cmd 'delete-selection t)) ;for delsel (Emacs)
+ '(erlang-electric-semicolon
+ erlang-electric-comma
+ erlang-electric-gt))
+
(put 'bitsyntax-open-outer 'syntax-table '(4 . ?>))
(put 'bitsyntax-open-outer 'rear-nonsticky '(category))
(put 'bitsyntax-open-inner 'rear-nonsticky '(category))
@@ -1514,8 +1496,6 @@ Other commands:
(setq paragraph-separate paragraph-start)
(make-local-variable 'paragraph-ignore-fill-prefix)
(setq paragraph-ignore-fill-prefix t)
- (make-local-variable 'require-final-newline)
- (setq require-final-newline t)
(make-local-variable 'defun-prompt-regexp)
(setq defun-prompt-regexp erlang-defun-prompt-regexp)
(make-local-variable 'comment-start)
@@ -1529,8 +1509,6 @@ Other commands:
(make-local-variable 'indent-region-function)
(setq indent-region-function 'erlang-indent-region)
(set (make-local-variable 'comment-indent-function) 'erlang-comment-indent)
- (if (<= erlang-emacs-major-version 18)
- (set (make-local-variable 'comment-indent-hook) 'erlang-comment-indent))
(set (make-local-variable 'parse-sexp-ignore-comments) t)
(set (make-local-variable 'dabbrev-case-fold-search) nil)
(set (make-local-variable 'imenu-prev-index-position-function)
@@ -1548,17 +1526,15 @@ Other commands:
(set (make-local-variable 'outline-regexp) "[[:lower:]0-9_]+ *(.*) *-> *$")
(set (make-local-variable 'outline-level) (lambda () 1))
(set (make-local-variable 'add-log-current-defun-function)
- 'erlang-current-defun)
- (set (make-local-variable 'find-tag-default-function)
- 'erlang-find-tag-for-completion))
+ 'erlang-current-defun))
(defun erlang-font-lock-init ()
"Initialize Font Lock for Erlang mode."
(or erlang-font-lock-syntax-table
(setq erlang-font-lock-syntax-table
- (let ((table (copy-syntax-table erlang-mode-syntax-table)))
- (modify-syntax-entry ?_ "w" table)
- table)))
+ (let ((table (copy-syntax-table erlang-mode-syntax-table)))
+ (modify-syntax-entry ?_ "w" table)
+ table)))
(set (make-local-variable 'font-lock-syntax-table)
erlang-font-lock-syntax-table)
(set (make-local-variable (if (boundp 'syntax-begin-function)
@@ -1567,23 +1543,23 @@ Other commands:
'erlang-beginning-of-clause)
(make-local-variable 'font-lock-keywords)
(let ((level (cond ((boundp 'font-lock-maximum-decoration)
- (symbol-value 'font-lock-maximum-decoration))
- ((boundp 'font-lock-use-maximal-decoration)
- (symbol-value 'font-lock-use-maximal-decoration))
- (t nil))))
+ (symbol-value 'font-lock-maximum-decoration))
+ ((boundp 'font-lock-use-maximal-decoration)
+ (symbol-value 'font-lock-use-maximal-decoration))
+ (t nil))))
(if (consp level)
- (setq level (cdr-safe (or (assq 'erlang-mode level)
- (assq t level)))))
+ (setq level (cdr-safe (or (assq 'erlang-mode level)
+ (assq t level)))))
;; `level' can here be:
;; A number - The fontification level
;; nil - Use the default
;; t - Use maximum
(cond ((eq level nil)
- (set 'font-lock-keywords erlang-font-lock-keywords))
- ((eq level 1)
- (set 'font-lock-keywords erlang-font-lock-keywords-1))
- ((eq level 2)
- (set 'font-lock-keywords erlang-font-lock-keywords-2))
+ (set 'font-lock-keywords erlang-font-lock-keywords))
+ ((eq level 1)
+ (set 'font-lock-keywords erlang-font-lock-keywords-1))
+ ((eq level 2)
+ (set 'font-lock-keywords erlang-font-lock-keywords-2))
((eq level 3)
(set 'font-lock-keywords erlang-font-lock-keywords-3))
(t
@@ -1592,11 +1568,11 @@ Other commands:
;; Modern font-locks can handle the above much more elegantly:
(set (make-local-variable 'font-lock-defaults)
'((erlang-font-lock-keywords erlang-font-lock-keywords-1
- erlang-font-lock-keywords-2
- erlang-font-lock-keywords-3
- erlang-font-lock-keywords-4)
- nil nil ((?_ . "w")) erlang-beginning-of-clause
- (font-lock-mark-block-function . erlang-mark-clause)
+ erlang-font-lock-keywords-2
+ erlang-font-lock-keywords-3
+ erlang-font-lock-keywords-4)
+ nil nil ((?_ . "w")) erlang-beginning-of-clause
+ (font-lock-mark-block-function . erlang-mark-clause)
(font-lock-syntactic-keywords
;; A dollar sign right before the double quote that ends a
;; string is not a character escape.
@@ -1610,8 +1586,8 @@ Other commands:
;; know whether matching started inside a string: limiting
;; search to a single line keeps things sane.
. (("\\(?:^\\|[^$]\\)\"\\(?:[^\"\n]\\|\\\\\"\\)*\\(\\$\\)\"" 1 "w")
- ;; Likewise for atoms
- ("\\(?:^\\|[^$]\\)'\\(?:[^'\n]\\|\\\\'\\)*\\(\\$\\)'" 1 "w")
+ ;; Likewise for atoms
+ ("\\(?:^\\|[^$]\\)'\\(?:[^'\n]\\|\\\\'\\)*\\(\\$\\)'" 1 "w")
;; And the dollar sign in $\" or $\' escapes two
;; characters, not just one.
("\\(\\$\\)\\\\[\"']" 1 "'"))))))
@@ -1657,17 +1633,17 @@ For a more elaborate example, please see the beginning of the file
(let ((res '()))
(while ks
(let* ((regexp (car (car ks)))
- (number (car (cdr (car ks))))
- (new-face (if (and faces (car faces))
- (car faces)
- (car (cdr (cdr (car ks))))))
- (overwrite (car (cdr (cdr (cdr (car ks))))))
- (new-keyword (list regexp number new-face)))
- (if overwrite (nconc new-keyword (list overwrite)))
- (setq res (cons new-keyword res))
- (setq ks (cdr ks))
- (if (and faces (cdr faces))
- (setq faces (cdr faces)))))
+ (number (car (cdr (car ks))))
+ (new-face (if (and faces (car faces))
+ (car faces)
+ (car (cdr (cdr (car ks))))))
+ (overwrite (car (cdr (cdr (cdr (car ks))))))
+ (new-keyword (list regexp number new-face)))
+ (if overwrite (nconc new-keyword (list overwrite)))
+ (setq res (cons new-keyword res))
+ (setq ks (cdr ks))
+ (if (and faces (cdr faces))
+ (setq faces (cdr faces)))))
(nreverse res)))
@@ -1739,7 +1715,7 @@ menu configuration is changed."
(defun erlang-menu-install (name items keymap &optional popup)
- "Install a menu in Emacs or XEmacs based on an abstract description.
+ "Install a menu in Emacs based on an abstract description.
NAME is the name of the menu.
@@ -1750,117 +1726,52 @@ same same form as ITEMS. The third optional element is an expression
which is evaluated every time the menu is displayed. Should the
expression evaluate to nil the menu item is ghosted.
-KEYMAP is the keymap to add to menu to. (When using XEmacs, the menu
-will only be visible when this menu is the global, the local, or an
-activate minor mode keymap.)
-
-If POPUP is non-nil, the menu is bound to the XEmacs `mode-popup-menu'
-variable, i.e. it will popup when pressing the right mouse button.
+KEYMAP is the keymap to add to menu to.
Please see the variable `erlang-menu-base-items'."
- (cond (erlang-xemacs-p
- (let ((menu (erlang-menu-xemacs name items keymap)))
- ;; We add the menu to the global menubar.
- ;;(funcall (symbol-function 'set-buffer-menubar)
- ;; (symbol-value 'current-menubar))
- (funcall (symbol-function 'add-submenu) nil menu)
- (setcdr erlang-xemacs-popup-menu (cdr menu))
- (if (and popup (boundp 'mode-popup-menu))
- (funcall (symbol-function 'set)
- 'mode-popup-menu erlang-xemacs-popup-menu))))
- ((>= erlang-emacs-major-version 19)
- (define-key keymap (vector 'menu-bar (intern name))
- (erlang-menu-make-keymap name items)))
- (t nil)))
+ (define-key keymap (vector 'menu-bar (intern name))
+ (erlang-menu-make-keymap name items)))
(defun erlang-menu-make-keymap (name items)
- "Build a menu for Emacs 19."
+ "Build a menu."
(let ((menumap (funcall (symbol-function 'make-sparse-keymap)
- name))
- (count 0)
- id def first second third)
+ name))
+ (count 0)
+ id def first second third)
(setq items (reverse items))
(while items
;; Replace any occurrence of atoms by their value.
(while (and items (atom (car items)) (not (null (car items))))
- (if (and (boundp (car items))
- (listp (symbol-value (car items))))
- (setq items (append (reverse (symbol-value (car items)))
- (cdr items)))
- (setq items (cdr items))))
+ (if (and (boundp (car items))
+ (listp (symbol-value (car items))))
+ (setq items (append (reverse (symbol-value (car items)))
+ (cdr items)))
+ (setq items (cdr items))))
(setq first (car-safe (car items)))
(setq second (car-safe (cdr-safe (car items))))
(setq third (car-safe (cdr-safe (cdr-safe (car items)))))
(cond ((null first)
- (setq count (+ count 1))
- (setq id (intern (format "separator-%d" count)))
- (setq def '("--" . nil)))
- ((and (consp second) (eq (car second) 'lambda))
- (setq count (+ count 1))
- (setq id (intern (format "lambda-%d" count)))
- (setq def (cons first second)))
- ((symbolp second)
- (setq id second)
- (setq def (cons first second)))
- (t
- (setq count (+ count 1))
- (setq id (intern (format "submenu-%d" count)))
- (setq def (erlang-menu-make-keymap first second))))
+ (setq count (+ count 1))
+ (setq id (intern (format "separator-%d" count)))
+ (setq def '("--" . nil)))
+ ((and (consp second) (eq (car second) 'lambda))
+ (setq count (+ count 1))
+ (setq id (intern (format "lambda-%d" count)))
+ (setq def (cons first second)))
+ ((symbolp second)
+ (setq id second)
+ (setq def (cons first second)))
+ (t
+ (setq count (+ count 1))
+ (setq id (intern (format "submenu-%d" count)))
+ (setq def (erlang-menu-make-keymap first second))))
(define-key menumap (vector id) def)
(if third
- (put id 'menu-enable third))
+ (put id 'menu-enable third))
(setq items (cdr items)))
(cons name menumap)))
-
-(defun erlang-menu-xemacs (name items &optional keymap)
- "Build a menu for XEmacs."
- (let ((res '())
- first second third entry)
- (while items
- ;; Replace any occurrence of atoms by their value.
- (while (and items (atom (car items)) (not (null (car items))))
- (if (and (boundp (car items))
- (listp (symbol-value (car items))))
- (setq items (append (reverse (symbol-value (car items)))
- (cdr items)))
- (setq items (cdr items))))
- (setq first (car-safe (car items)))
- (setq second (car-safe (cdr-safe (car items))))
- (setq third (car-safe (cdr-safe (cdr-safe (car items)))))
- (cond ((null first)
- (setq res (cons "------" res)))
- ((symbolp second)
- (setq res (cons (vector first second (or third t)) res)))
- ((and (consp second) (eq (car second) 'lambda))
- (setq res (cons (vector first (list 'call-interactively second)
- (or third t)) res)))
- (t
- (setq res (cons (cons first
- (cdr (erlang-menu-xemacs
- first second)))
- res))))
- (setq items (cdr items)))
- (setq res (reverse res))
- ;; When adding a menu to a minor-mode keymap under Emacs,
- ;; it disappears when the mode is disabled. The expression
- ;; generated below imitates this behaviour.
- ;; (This could be expressed much clearer using backquotes,
- ;; but I don't want to pull in every package.)
- (if keymap
- (let ((expr (list 'or
- (list 'eq keymap 'global-map)
- (list 'eq keymap (list 'current-local-map))
- (list 'symbol-value
- (list 'car-safe
- (list 'rassq
- keymap
- 'minor-mode-map-alist))))))
- (setq res (cons ':included (cons expr res)))))
- (cons name res)))
-
-
(defun erlang-menu-substitute (items alist)
"Substitute functions in menu described by ITEMS.
@@ -1872,13 +1783,13 @@ ALIST is list of pairs where the car is the old function and cdr the new."
(setq first (car-safe (car items)))
(setq second (car-safe (cdr-safe (car items))))
(cond ((null first))
- ((symbolp second)
- (setq pair (and second (assq second alist)))
- (if pair
- (setcar (cdr (car items)) (cdr pair))))
- ((and (consp second) (eq (car second) 'lambda)))
- (t
- (erlang-menu-substitute second alist)))
+ ((symbolp second)
+ (setq pair (and second (assq second alist)))
+ (if pair
+ (setcar (cdr (car items)) (cdr pair))))
+ ((and (consp second) (eq (car second) 'lambda)))
+ (t
+ (erlang-menu-substitute second alist)))
(setq items (cdr items)))))
@@ -1913,27 +1824,27 @@ Example:
\(setq erlang-menu-items
(erlang-menu-add-below 'my-erlang-menu-items
- 'erlang-menu-base-items
+ 'erlang-menu-base-items
erlang-menu-items))"
(if (memq entry items)
- items ; Return the original menu.
+ items ; Return the original menu.
(let ((head '())
- (done nil)
- res)
+ (done nil)
+ res)
(while (not done)
- (cond ((null items)
- (setq res (append head (list entry)))
- (setq done t))
- ((eq below (car items))
- (setq res
- (if above-p
- (append head (cons entry items))
- (append head (cons (car items)
- (cons entry (cdr items))))))
- (setq done t))
- (t
- (setq head (append head (list (car items))))
- (setq items (cdr items)))))
+ (cond ((null items)
+ (setq res (append head (list entry)))
+ (setq done t))
+ ((eq below (car items))
+ (setq res
+ (if above-p
+ (append head (cons entry items))
+ (append head (cons (car items)
+ (cons entry (cdr items))))))
+ (setq done t))
+ (t
+ (setq head (append head (list (car items))))
+ (setq items (cdr items)))))
res)))
(defun erlang-menu-delete (entry items)
@@ -1951,19 +1862,21 @@ menu is left unchanged."
The variable `erlang-man-dirs' contains entries describing
the location of the manual pages."
(interactive)
- (if erlang-man-inhibit
+ (if (or erlang-man-inhibit
+ (and (boundp 'menu-bar-mode)
+ (not menu-bar-mode)))
()
(setq erlang-menu-man-items
- '(nil
- ("Man - Function" erlang-man-function)))
+ '(nil
+ ("Man - Function" erlang-man-function)))
(if erlang-man-dirs
- (setq erlang-menu-man-items
- (append erlang-menu-man-items
- (erlang-man-make-top-menu erlang-man-dirs))))
+ (setq erlang-menu-man-items
+ (append erlang-menu-man-items
+ (erlang-man-make-top-menu erlang-man-dirs))))
(setq erlang-menu-items
- (erlang-menu-add-above 'erlang-menu-man-items
- 'erlang-menu-version-items
- erlang-menu-items))
+ (erlang-menu-add-above 'erlang-menu-man-items
+ 'erlang-menu-version-items
+ erlang-menu-items))
(erlang-menu-init)))
@@ -1971,7 +1884,7 @@ the location of the manual pages."
"Remove the man pages from the Erlang mode."
(interactive)
(setq erlang-menu-items
- (erlang-menu-delete 'erlang-menu-man-items erlang-menu-items))
+ (erlang-menu-delete 'erlang-menu-man-items erlang-menu-items))
(erlang-menu-init))
@@ -1985,29 +1898,31 @@ the location of the manual pages."
"Create one menu entry per element of DIR-LIST.
The format is described in the documentation of `erlang-man-dirs'."
(let ((menu '())
- dir)
+ dir)
(while dir-list
(setq dir (cond ((nth 2 (car dir-list))
- ;; Relative to `erlang-root-dir'.
- (and (stringp erlang-root-dir)
- (concat erlang-root-dir (nth 1 (car dir-list)))))
- (t
- ;; Absolute
- (nth 1 (car dir-list)))))
+ ;; Relative to `erlang-root-dir'.
+ (and (stringp erlang-root-dir)
+ (erlang-man-dir (nth 1 (car dir-list)))))
+ (t
+ ;; Absolute
+ (nth 1 (car dir-list)))))
(if (and dir
- (file-readable-p dir))
- (setq menu (cons (list (car (car dir-list))
- (erlang-man-make-middle-menu
- (erlang-man-get-files dir)))
- menu)))
+ (file-readable-p dir))
+ (setq menu (cons (list (car (car dir-list))
+ (erlang-man-make-middle-menu
+ (erlang-man-get-files dir)))
+ menu)))
(setq dir-list (cdr dir-list)))
;; Should no menus be found, generate a menu item which
;; will display a help text, when selected.
(if menu
- (nreverse menu)
+ (nreverse menu)
'(("Man Pages"
- (("Error! Why?" erlang-man-describe-error)))))))
+ (("Error! Why?" erlang-man-describe-error)))))))
+(defun erlang-man-dir (subdir)
+ (concat erlang-root-dir "/lib/erlang/" subdir))
;; Should the menu be to long, let's split it into a number of
;; smaller menus. Warning, this code contains beautiful
@@ -2020,32 +1935,32 @@ menus is created."
(if (<= (length filelist) erlang-man-max-menu-size)
(erlang-man-make-menu filelist)
(let ((menu '())
- (filelist (copy-sequence filelist))
- segment submenu pair)
+ (filelist (copy-sequence filelist))
+ segment submenu pair)
(while filelist
- (setq pair (nthcdr (- erlang-man-max-menu-size 1) filelist))
- (setq segment filelist)
- (if (null pair)
- (setq filelist nil)
- (setq filelist (cdr pair))
- (setcdr pair nil))
- (setq submenu (erlang-man-make-menu segment))
- (setq menu (cons (list (concat (car (car submenu))
- " -- "
- (car (car (reverse submenu))))
- submenu)
- menu)))
+ (setq pair (nthcdr (- erlang-man-max-menu-size 1) filelist))
+ (setq segment filelist)
+ (if (null pair)
+ (setq filelist nil)
+ (setq filelist (cdr pair))
+ (setcdr pair nil))
+ (setq submenu (erlang-man-make-menu segment))
+ (setq menu (cons (list (concat (car (car submenu))
+ " -- "
+ (car (car (reverse submenu))))
+ submenu)
+ menu)))
(nreverse menu))))
(defun erlang-man-make-menu (filelist)
"Make a leaf menu based on FILELIST."
(let ((menu '())
- item)
+ item)
(while filelist
(setq item (erlang-man-make-menu-item (car filelist)))
(if item
- (setq menu (cons item menu)))
+ (setq menu (cons item menu)))
(setq filelist (cdr filelist)))
(nreverse menu)))
@@ -2054,11 +1969,11 @@ menus is created."
"Create a menu item containing the name of the man page."
(and (string-match ".+/\\([^/]+\\)\\.\\([124-9]\\|3\\(erl\\)?\\)\\(\\.gz\\)?$" file)
(let ((page (substring file (match-beginning 1) (match-end 1))))
- (list (capitalize page)
- (list 'lambda '()
- '(interactive)
- (list 'funcall 'erlang-man-display-function
- file))))))
+ (list (capitalize page)
+ (list 'lambda '()
+ '(interactive)
+ (list 'funcall 'erlang-man-display-function
+ file))))))
(defun erlang-man-get-files (dir)
@@ -2070,35 +1985,45 @@ menus is created."
"Find manual page for MODULE, defaults to module of function under point.
This function is aware of imported functions."
(interactive
- (list (let* ((mod (car-safe (erlang-get-function-under-point)))
- (input (read-string
- (format "Manual entry for module%s: "
- (if (or (null mod) (string= mod ""))
- ""
- (format " (default %s)" mod))))))
- (if (string= input "")
- mod
- input))))
- (or module (setq module (car (erlang-get-function-under-point))))
- (if (or (null module) (string= module ""))
- (error "No Erlang module name given"))
+ (list (let* ((mod (erlang-default-module))
+ (input (read-string
+ (format "Manual entry for module%s: "
+ (if (or (null mod) (string= mod ""))
+ ""
+ (format " (default %s)" mod))))))
+ (if (string= input "")
+ mod
+ input))))
+ (setq module (or module
+ (erlang-default-module)))
+ (when (or (null module) (string= module ""))
+ (error "No Erlang module name given"))
(let ((dir-list erlang-man-dirs)
- (pat (concat "/" (regexp-quote module) "\\.\\([124-9]\\|3\\(erl\\)?\\)\\(\\.gz\\)?$"))
- (file nil)
- file-list)
+ (pat (concat "/" (regexp-quote module)
+ "\\.\\([124-9]\\|3\\(erl\\)?\\)\\(\\.gz\\)?$"))
+ (file nil)
+ file-list)
(while (and dir-list (null file))
- (setq file-list (erlang-man-get-files
- (if (nth 2 (car dir-list))
- (concat erlang-root-dir (nth 1 (car dir-list)))
- (nth 1 (car dir-list)))))
- (while (and file-list (null file))
- (if (string-match pat (car file-list))
- (setq file (car file-list)))
- (setq file-list (cdr file-list)))
- (setq dir-list (cdr dir-list)))
+ (let ((dir (if (nth 2 (car dir-list))
+ (erlang-man-dir (nth 1 (car dir-list)))
+ (nth 1 (car dir-list)))))
+ (when (file-directory-p dir)
+ (setq file-list (erlang-man-get-files dir))
+ (while (and file-list (null file))
+ (if (string-match pat (car file-list))
+ (setq file (car file-list)))
+ (setq file-list (cdr file-list))))
+ (setq dir-list (cdr dir-list))))
(if file
- (funcall erlang-man-display-function file)
- (error "No manual page for module %s found" module))))
+ (funcall erlang-man-display-function file)
+ ;; Did not found the manual file. Fallback to manual-entry.
+ (manual-entry module))))
+
+(defun erlang-default-module ()
+ (let ((id (erlang-get-identifier-at-point)))
+ (if (eq (erlang-id-kind id) 'qualified-function)
+ (erlang-id-module id)
+ (erlang-id-name id))))
;; Warning, the function `erlang-man-function' is a hack!
@@ -2118,56 +2043,51 @@ The entry for `function' is displayed.
This function is aware of imported functions."
(interactive
- (list (let* ((mod-func (erlang-get-function-under-point))
- (mod (car-safe mod-func))
- (func (nth 1 mod-func))
- (input (read-string
- (format
- "Manual entry for `module:func' or `module'%s: "
- (if (or (null mod) (string= mod ""))
- ""
- (format " (default %s:%s)" mod func))))))
- (if (string= input "")
- (if (and mod func)
- (concat mod ":" func)
- mod)
- input))))
- ;; Emacs 18 doesn't provide `man'...
- (condition-case nil
- (require 'man)
- (error nil))
+ (list (let* ((default (erlang-default-function-or-module))
+ (input (read-string
+ (format
+ "Manual entry for `module:func' or `module'%s: "
+ (if default
+ (format " (default %s)" default)
+ "")))))
+ (if (string= input "")
+ default
+ input))))
+ (require 'man)
+ (setq name (or name
+ (erlang-default-function-or-module)))
(let ((modname nil)
- (funcname nil))
- (cond ((null name)
- (let ((mod-func (erlang-get-function-under-point)))
- (setq modname (car-safe mod-func))
- (setq funcname (nth 1 mod-func))))
- ((string-match ":" name)
- (setq modname (substring name 0 (match-beginning 0)))
- (setq funcname (substring name (match-end 0) nil)))
- ((stringp name)
- (setq modname name)))
- (if (or (null modname) (string= modname ""))
- (error "No Erlang module name given"))
+ (funcname nil))
+ (cond ((string-match ":" name)
+ (setq modname (substring name 0 (match-beginning 0)))
+ (setq funcname (substring name (match-end 0) nil)))
+ ((stringp name)
+ (setq modname name)))
+ (when (or (null modname) (string= modname ""))
+ (error "No Erlang module name given"))
(cond ((fboundp 'Man-notify-when-ready)
- ;; Emacs 19: The man command could possibly start an
- ;; asynchronous process, i.e. we must hook ourselves into
- ;; the system to be activated when the man-process
- ;; terminates.
- (if (null funcname)
- ()
- (erlang-man-patch-notify)
- (setq erlang-man-function-name funcname))
- (condition-case nil
- (erlang-man-module modname)
- (error (setq erlang-man-function-name nil))))
- (t
- (erlang-man-module modname)
- (if funcname
- (erlang-man-find-function
- (or (get-buffer "*Manual Entry*") ; Emacs 18
- (current-buffer)) ; XEmacs
- funcname))))))
+ ;; Emacs 19: The man command could possibly start an
+ ;; asynchronous process, i.e. we must hook ourselves into
+ ;; the system to be activated when the man-process
+ ;; terminates.
+ (if (null funcname)
+ ()
+ (erlang-man-patch-notify)
+ (setq erlang-man-function-name funcname))
+ (condition-case err
+ (erlang-man-module modname)
+ (error (setq erlang-man-function-name nil)
+ (signal (car err) (cdr err)))))
+ (t
+ (erlang-man-module modname)
+ (when funcname
+ (erlang-man-find-function (current-buffer) funcname))))))
+
+(defun erlang-default-function-or-module ()
+ (let ((id (erlang-get-identifier-at-point)))
+ (if (eq (erlang-id-kind id) 'qualified-function)
+ (format "%s:%s" (erlang-id-module id) (erlang-id-name id))
+ (erlang-id-name id))))
;; Should the defadvice be at the top level, the package `advice' would
@@ -2185,14 +2105,14 @@ command is executed asynchronously."
;; This should never happened since this is only called when
;; running under Emacs 19.
(error (error (concat "This command needs the package `advice', "
- "please upgrade your Emacs."))))
+ "please upgrade your Emacs."))))
(require 'man)
(defadvice Man-notify-when-ready
- (after erlang-Man-notify-when-ready activate)
+ (after erlang-Man-notify-when-ready activate)
"Set point at the documentation of the function name in
`erlang-man-function-name' when the man page is displayed."
(if erlang-man-function-name
- (erlang-man-find-function (ad-get-arg 0) erlang-man-function-name))
+ (erlang-man-find-function (ad-get-arg 0) erlang-man-function-name))
(setq erlang-man-function-name nil)))
@@ -2200,49 +2120,35 @@ command is executed asynchronously."
"Find manual page for function in `erlang-man-function-name' in buffer BUF."
(if func
(let ((win (get-buffer-window buf)))
- (if win
- (progn
- (set-buffer buf)
- (goto-char (point-min))
- (if (re-search-forward
- (concat "^[ \t]+" func " ?(")
- (point-max) t)
- (progn
- (forward-word -1)
- (set-window-point win (point)))
- (message "Could not find function `%s'" func)))))))
-
+ (if win
+ (progn
+ (set-buffer buf)
+ (goto-char (point-min))
+ (if (re-search-forward
+ (concat "^[ \t]+" func " ?(")
+ (point-max) t)
+ (progn
+ (forward-word -1)
+ (set-window-point win (point)))
+ (message "Could not find function `%s'" func)))))))
+
+(defvar erlang-man-file-regexp
+ "\\(.*\\)/man[^/]*/\\([^.]+\\)\\.\\([124-9]\\|3\\(erl\\)?\\)\\(\\.gz\\)?$")
(defun erlang-man-display (file)
"Display FILE as a `man' file.
This is the default manual page display function.
The variables `erlang-man-display-function' contains the function
to be used."
- ;; Emacs 18 doesn't `provide' man.
- (condition-case nil
- (require 'man)
- (error nil))
+ (require 'man)
(if file
(let ((process-environment (copy-sequence process-environment)))
- (if (string-match "\\(.*\\)/man[^/]*/\\([^.]+\\)\\.\\([124-9]\\|3\\(erl\\)?\\)\\(\\.gz\\)?$" file)
- (let ((dir (substring file (match-beginning 1) (match-end 1)))
- (page (substring file (match-beginning 2) (match-end 2))))
- (if (fboundp 'setenv)
- (setenv "MANPATH" dir)
- ;; Emacs 18
- (setq process-environment (cons (concat "MANPATH=" dir)
- process-environment)))
- (cond ((not (and (not erlang-xemacs-p)
- (= erlang-emacs-major-version 19)
- (< erlang-emacs-minor-version 29)))
- (manual-entry page))
- (t
- ;; Emacs 19.28 and earlier versions of 19:
- ;; The manual-entry command unconditionally prompts
- ;; the user :-(
- (funcall (symbol-function 'Man-getpage-in-background)
- page))))
- (error "Can't find man page for %s\n" file)))))
+ (if (string-match erlang-man-file-regexp file)
+ (let ((dir (substring file (match-beginning 1) (match-end 1)))
+ (page (substring file (match-beginning 2) (match-end 2))))
+ (setenv "MANPATH" dir)
+ (manual-entry page))
+ (error "Can't find man page for %s\n" file)))))
(defun erlang-man-describe-error ()
@@ -2269,7 +2175,7 @@ mode with the command `M-x erlang-mode RET'.")))
;; Skeleton code:
;; This code is based on the package `tempo' which is part of modern
-;; Emacsen. (GNU Emacs 19.25 (?) and XEmacs 19.14.)
+;; Emacsen.
(defvar erlang-skel)
(defun erlang-skel-init ()
@@ -2280,48 +2186,45 @@ all skeletons.
The skeleton routines are based on the `tempo' package. Should this
package not be present, this function does nothing."
(interactive)
- (condition-case nil
- (require 'tempo)
- (error t))
- (if (featurep 'tempo)
- (let ((skel erlang-skel)
- (menu '()))
- (while skel
- (cond ((null (car skel))
- (setq menu (cons nil menu)))
- (t
- (funcall (symbol-function 'tempo-define-template)
- (concat "erlang-" (nth 1 (car skel)))
- ;; The tempo template used contains an `include'
- ;; function call only, hence changes to the
- ;; variables describing the templates take effect
- ;; immdiately.
- (list (list 'erlang-skel-include (nth 2 (car skel))))
- (nth 1 (car skel))
- (car (car skel))
- 'erlang-tempo-tags)
- (setq menu (cons (erlang-skel-make-menu-item
- (car skel)) menu))))
- (setq skel (cdr skel)))
- (setq erlang-menu-skel-items
- (list nil (list "Skeletons" (nreverse menu))))
- (setq erlang-menu-items
- (erlang-menu-add-above 'erlang-menu-skel-items
- 'erlang-menu-version-items
- erlang-menu-items))
- (erlang-menu-init))))
+ (require 'tempo)
+ (let ((skel erlang-skel)
+ (menu '()))
+ (while skel
+ (cond ((null (car skel))
+ (setq menu (cons nil menu)))
+ (t
+ (funcall (symbol-function 'tempo-define-template)
+ (concat "erlang-" (nth 1 (car skel)))
+ ;; The tempo template used contains an `include'
+ ;; function call only, hence changes to the
+ ;; variables describing the templates take effect
+ ;; immediately.
+ (list (list 'erlang-skel-include (nth 2 (car skel))))
+ (nth 1 (car skel))
+ (car (car skel))
+ 'erlang-tempo-tags)
+ (setq menu (cons (erlang-skel-make-menu-item
+ (car skel)) menu))))
+ (setq skel (cdr skel)))
+ (setq erlang-menu-skel-items
+ (list nil (list "Skeletons" (nreverse menu))))
+ (setq erlang-menu-items
+ (erlang-menu-add-above 'erlang-menu-skel-items
+ 'erlang-menu-version-items
+ erlang-menu-items))
+ (erlang-menu-init)))
(defun erlang-skel-make-menu-item (skel)
(let ((func (intern (concat "tempo-template-erlang-" (nth 1 skel)))))
(cond ((null (nth 3 skel))
- (list (car skel) func))
- (t
- (list (car skel)
- (list 'lambda '()
- '(interactive)
- (list 'funcall
- (list 'quote (nth 3 skel))
- (list 'quote func))))))))
+ (list (car skel) func))
+ (t
+ (list (car skel)
+ (list 'lambda '()
+ '(interactive)
+ (list 'funcall
+ (list 'quote (nth 3 skel))
+ (list 'quote func))))))))
;; Functions designed to be added to the skeleton menu.
;; (Not normally used)
@@ -2354,12 +2257,12 @@ Technically, this function returns the `tempo' attribute`(l ...)' which
can contain other `tempo' attributes. Please see the function
`tempo-define-template' for a description of the `(l ...)' attribute."
(let ((res '())
- entry)
+ entry)
(while args
(setq entry (car args))
(while entry
- (setq res (cons (car entry) res))
- (setq entry (cdr entry)))
+ (setq res (cons (car entry) res))
+ (setq entry (cdr entry)))
(setq args (cdr args)))
(cons 'l (nreverse res))))
@@ -2368,25 +2271,25 @@ can contain other `tempo' attributes. Please see the function
(defun erlang-skel-separator (&optional percent)
"Return a comment separator."
(let ((percent (or percent 3)))
- (concat (make-string percent ?%)
- (make-string (- erlang-skel-separator-length percent) ?-)
- "\n")))
+ (concat (make-string percent ?%)
+ (make-string (- erlang-skel-separator-length percent) ?-)
+ "\n")))
(defun erlang-skel-double-separator (&optional percent)
"Return a comment separator."
(let ((percent (or percent 3)))
- (concat (make-string percent ?%)
- (make-string (- erlang-skel-separator-length percent) ?=)
- "\n")))
+ (concat (make-string percent ?%)
+ (make-string (- erlang-skel-separator-length percent) ?=)
+ "\n")))
(defun erlang-skel-dd-mmm-yyyy ()
"Return the current date as a string in \"DD Mon YYYY\" form.
The first character of DD is space if the value is less than 10."
(let ((date (current-time-string)))
(format "%2d %s %s"
- (erlang-string-to-int (substring date 8 10))
- (substring date 4 7)
- (substring date -4))))
+ (string-to-number (substring date 8 10))
+ (substring date 4 7)
+ (substring date -4))))
;; Indentation code:
@@ -2399,23 +2302,23 @@ rigidly along with this one."
;; If arg, always indent this line as Erlang
;; and shift remaining lines of clause the same amount.
(let ((shift-amt (erlang-indent-line))
- beg end)
- (save-excursion
- (if erlang-tab-always-indent
- (beginning-of-line))
- (setq beg (point))
- (erlang-end-of-clause 1)
- (setq end (point))
- (goto-char beg)
- (forward-line 1)
- (setq beg (point)))
- (if (> end beg)
- (indent-code-rigidly beg end shift-amt "\n")))
+ beg end)
+ (save-excursion
+ (if erlang-tab-always-indent
+ (beginning-of-line))
+ (setq beg (point))
+ (erlang-end-of-clause 1)
+ (setq end (point))
+ (goto-char beg)
+ (forward-line 1)
+ (setq beg (point)))
+ (if (> end beg)
+ (indent-code-rigidly beg end shift-amt "\n")))
(if (and (not erlang-tab-always-indent)
- (save-excursion
- (skip-chars-backward " \t")
- (not (bolp))))
- (insert-tab)
+ (save-excursion
+ (skip-chars-backward " \t")
+ (not (bolp))))
+ (insert-tab)
(erlang-indent-line))))
@@ -2423,33 +2326,34 @@ rigidly along with this one."
"Indent current line as Erlang code.
Return the amount the indentation changed by."
(let ((pos (- (point-max) (point)))
- indent beg
- shift-amt)
+ indent beg
+ shift-amt)
(beginning-of-line 1)
(setq beg (point))
(skip-chars-forward " \t")
(cond ((looking-at "%")
- (setq indent (funcall comment-indent-function))
- (setq shift-amt (- indent (current-column))))
- (t
- (setq indent (erlang-calculate-indent))
- (cond ((null indent)
- (setq indent (current-indentation)))
- ((eq indent t)
- ;; This should never occur here.
- (error "Erlang mode error"))
- ;;((= (char-syntax (following-char)) ?\))
- ;; (setq indent (1- indent)))
- )
- (setq shift-amt (- indent (current-column)))))
+ (setq indent (funcall comment-indent-function))
+ (setq shift-amt (- indent (current-column))))
+ (t
+ (setq indent (erlang-calculate-indent))
+ (cond ((null indent)
+ (setq indent (current-indentation)))
+ ((eq indent t)
+ ;; This should never occur here.
+ (error "Erlang mode error"))
+ ;;((= (char-syntax (following-char)) ?\))
+ ;; (setq indent (1- indent)))
+ )
+ (setq shift-amt (- indent (current-column)))))
(if (zerop shift-amt)
- nil
+ nil
(delete-region beg (point))
(indent-to indent))
;; If initial point was within line's indentation, position
;; after the indentation. Else stay at same point in text.
(if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos)))
+ (goto-char (- (point-max) pos)))
+ (run-hooks 'erlang-indent-line-hook)
shift-amt))
@@ -2460,11 +2364,11 @@ This is automagically called by the user level function `indent-region'."
(interactive "r")
(save-excursion
(let ((case-fold-search nil)
- (continue t)
- (from-end (- (point-max) end))
- indent-point;; The beginning of the current line
- indent;; The indent amount
- state)
+ (continue t)
+ (from-end (- (point-max) end))
+ indent-point;; The beginning of the current line
+ indent;; The indent amount
+ state)
(goto-char beg)
(beginning-of-line)
(setq indent-point (point))
@@ -2478,39 +2382,39 @@ This is automagically called by the user level function `indent-region'."
(error "Illegal syntax"))))
;; Indent every line in the region
(while continue
- (goto-char indent-point)
- (skip-chars-forward " \t")
- (cond ((looking-at "%")
- ;; Do not use our stack to help the user to customize
- ;; comment indentation.
- (setq indent (funcall comment-indent-function)))
- ((looking-at "$")
- ;; Don't indent empty lines.
- (setq indent 0))
- (t
- (setq indent
- (save-excursion
- (erlang-calculate-stack-indent (point) state)))
- (cond ((null indent)
- (setq indent (current-indentation)))
- ((eq indent t)
- ;; This should never occur here.
- (error "Erlang mode error"))
- ;;((= (char-syntax (following-char)) ?\))
- ;; (setq indent (1- indent)))
- )))
- (if (zerop (- indent (current-column)))
- nil
- (delete-region indent-point (point))
- (indent-to indent))
- ;; Find the next line in the region
- (goto-char indent-point)
- (save-excursion
- (forward-line 1)
- (setq indent-point (point)))
- (if (>= from-end (- (point-max) indent-point))
- (setq continue nil)
- (while (< (point) indent-point)
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (cond ((looking-at "%")
+ ;; Do not use our stack to help the user to customize
+ ;; comment indentation.
+ (setq indent (funcall comment-indent-function)))
+ ((looking-at "$")
+ ;; Don't indent empty lines.
+ (setq indent 0))
+ (t
+ (setq indent
+ (save-excursion
+ (erlang-calculate-stack-indent (point) state)))
+ (cond ((null indent)
+ (setq indent (current-indentation)))
+ ((eq indent t)
+ ;; This should never occur here.
+ (error "Erlang mode error"))
+ ;;((= (char-syntax (following-char)) ?\))
+ ;; (setq indent (1- indent)))
+ )))
+ (if (zerop (- indent (current-column)))
+ nil
+ (delete-region indent-point (point))
+ (indent-to indent))
+ ;; Find the next line in the region
+ (goto-char indent-point)
+ (save-excursion
+ (forward-line 1)
+ (setq indent-point (point)))
+ (if (>= from-end (- (point-max) indent-point))
+ (setq continue nil)
+ (while (< (point) indent-point)
(let ((pt (point)))
(setq state (erlang-partial-parse
pt indent-point state))
@@ -2532,7 +2436,7 @@ This is automagically called by the user level function `indent-region'."
(interactive)
(save-excursion
(let ((end (progn (erlang-end-of-function 1) (point)))
- (beg (progn (erlang-beginning-of-function 1) (point))))
+ (beg (progn (erlang-beginning-of-function 1) (point))))
(erlang-indent-region beg end))))
@@ -2541,7 +2445,7 @@ This is automagically called by the user level function `indent-region'."
(interactive)
(save-excursion
(let ((end (progn (erlang-end-of-clause 1) (point)))
- (beg (progn (erlang-beginning-of-clause 1) (point))))
+ (beg (progn (erlang-beginning-of-clause 1) (point))))
(erlang-indent-region beg end))))
@@ -2556,11 +2460,11 @@ This is automagically called by the user level function `indent-region'."
Return nil if line starts inside string, t if in a comment."
(save-excursion
(let ((indent-point (point))
- (case-fold-search nil)
- (state nil))
+ (case-fold-search nil)
+ (state nil))
(if parse-start
- (goto-char parse-start)
- (erlang-beginning-of-clause))
+ (goto-char parse-start)
+ (erlang-beginning-of-clause))
(while (< (point) indent-point)
(let ((pt (point)))
(setq state (erlang-partial-parse pt indent-point state))
@@ -2575,25 +2479,25 @@ Return nil if line starts inside string, t if in a comment."
(save-excursion
(let ((starting-point (point))
- (case-fold-search nil)
- (state nil))
+ (case-fold-search nil)
+ (state nil))
(erlang-beginning-of-clause)
(while (< (point) starting-point)
- (setq state (erlang-partial-parse (point) starting-point state)))
+ (setq state (erlang-partial-parse (point) starting-point state)))
(message "%S" state))))
(defun erlang-partial-parse (from to &optional state)
"Parse Erlang syntax starting at FROM until TO, with an optional STATE.
Value is list (stack token-start token-type in-what)."
- (goto-char from) ; Start at the beginning
+ (goto-char from) ; Start at the beginning
(erlang-skip-blank to)
(let ((cs (char-syntax (following-char)))
- (stack (car state))
- (token (point))
- in-what)
- (cond
-
+ (stack (car state))
+ (token (point))
+ in-what)
+ (cond
+
;; Done: Return previous state.
((>= token to)
(setq token (nth 1 state))
@@ -2603,230 +2507,230 @@ Value is list (stack token-start token-type in-what)."
;; Word constituent: check and handle keywords.
((= cs ?w)
(cond ((looking-at "\\(end\\|after\\)[^_a-zA-Z0-9]")
- ;; Must pop top icr layer, `after' will push a new
- ;; layer next.
- (progn
- (while (and stack (eq (car (car stack)) '->))
- (erlang-pop stack))
- (if (and stack (memq (car (car stack)) '(icr begin fun try)))
- (erlang-pop stack))))
- ((looking-at "catch\\b.*of")
- t)
- ((looking-at "catch\\b\\s *\\($\\|%\\|.*->\\)")
- ;; Must pop top icr layer, `catch' in try/catch
- ;;will push a new layer next.
- (progn
- (while (and stack (eq (car (car stack)) '->))
- (erlang-pop stack))
- (if (and stack (memq (car (car stack)) '(icr begin try)))
- (erlang-pop stack))))
- )
+ ;; Must pop top icr layer, `after' will push a new
+ ;; layer next.
+ (progn
+ (while (and stack (eq (car (car stack)) '->))
+ (erlang-pop stack))
+ (if (and stack (memq (car (car stack)) '(icr begin fun try)))
+ (erlang-pop stack))))
+ ((looking-at "catch\\b.*of")
+ t)
+ ((looking-at "catch\\b\\s *\\($\\|%\\|.*->\\)")
+ ;; Must pop top icr layer, `catch' in try/catch
+ ;;will push a new layer next.
+ (progn
+ (while (and stack (eq (car (car stack)) '->))
+ (erlang-pop stack))
+ (if (and stack (memq (car (car stack)) '(icr begin try)))
+ (erlang-pop stack))))
+ )
(cond ((looking-at "\\(if\\|case\\|receive\\)[^_a-zA-Z0-9]")
- ;; Must push a new icr (if/case/receive) layer.
- (erlang-push (list 'icr token (current-column)) stack))
- ((looking-at "\\(try\\|after\\)[^_a-zA-Z0-9]")
- ;; Must handle separately, try catch or try X of -> catch
- ;; same for `after', it could be
- ;; receive after Time -> X end, or
- ;; try after X end
- (erlang-push (list 'try token (current-column)) stack))
- ((looking-at "\\(of\\)[^_a-zA-Z0-9]")
- ;; Must handle separately, try X of -> catch
- (if (and stack (eq (car (car stack)) 'try))
- (let ((try-column (nth 2 (car stack)))
- (try-pos (nth 1 (car stack))))
- (erlang-pop stack)
- (erlang-push (list 'icr try-pos try-column) stack))))
-
- ((looking-at "\\(fun\\)[^_a-zA-Z0-9]")
- ;; Push a new layer if we are defining a `fun'
- ;; expression, not when we are refering an existing
- ;; function. 'fun's defines are only indented one level now.
- (if (save-excursion
- (goto-char (match-end 1))
- (erlang-skip-blank to)
- ;; Use erlang-variable-regexp here to look for an
- ;; optional variable name to match EEP37 named funs.
- (if (looking-at erlang-variable-regexp)
- (progn
- (goto-char (match-end 0))
- (erlang-skip-blank to)))
- (eq (following-char) ?\())
- (erlang-push (list 'fun token (current-column)) stack)))
- ((looking-at "\\(begin\\)[^_a-zA-Z0-9]")
- (erlang-push (list 'begin token (current-column)) stack))
- ;; Normal when case
- ;;((looking-at "when\\s ")
- ;;((looking-at "when\\s *\\($\\|%\\)")
- ((looking-at "when[^_a-zA-Z0-9]")
- (erlang-push (list 'when token (current-column)) stack))
- ((looking-at "catch\\b.*of")
- t)
- ((looking-at "catch\\b\\s *\\($\\|%\\|.*->\\)")
- (erlang-push (list 'icr token (current-column)) stack))
- ;;(erlang-push (list '-> token (current-column)) stack))
- ;;((looking-at "^of$")
- ;; (erlang-push (list 'icr token (current-column)) stack)
- ;;(erlang-push (list '-> token (current-column)) stack))
- )
+ ;; Must push a new icr (if/case/receive) layer.
+ (erlang-push (list 'icr token (current-column)) stack))
+ ((looking-at "\\(try\\|after\\)[^_a-zA-Z0-9]")
+ ;; Must handle separately, try catch or try X of -> catch
+ ;; same for `after', it could be
+ ;; receive after Time -> X end, or
+ ;; try after X end
+ (erlang-push (list 'try token (current-column)) stack))
+ ((looking-at "\\(of\\)[^_a-zA-Z0-9]")
+ ;; Must handle separately, try X of -> catch
+ (if (and stack (eq (car (car stack)) 'try))
+ (let ((try-column (nth 2 (car stack)))
+ (try-pos (nth 1 (car stack))))
+ (erlang-pop stack)
+ (erlang-push (list 'icr try-pos try-column) stack))))
+
+ ((looking-at "\\(fun\\)[^_a-zA-Z0-9]")
+ ;; Push a new layer if we are defining a `fun'
+ ;; expression, not when we are refering an existing
+ ;; function. 'fun's defines are only indented one level now.
+ (if (save-excursion
+ (goto-char (match-end 1))
+ (erlang-skip-blank to)
+ ;; Use erlang-variable-regexp here to look for an
+ ;; optional variable name to match EEP37 named funs.
+ (if (looking-at erlang-variable-regexp)
+ (progn
+ (goto-char (match-end 0))
+ (erlang-skip-blank to)))
+ (eq (following-char) ?\())
+ (erlang-push (list 'fun token (current-column)) stack)))
+ ((looking-at "\\(begin\\)[^_a-zA-Z0-9]")
+ (erlang-push (list 'begin token (current-column)) stack))
+ ;; Normal when case
+ ;;((looking-at "when\\s ")
+ ;;((looking-at "when\\s *\\($\\|%\\)")
+ ((looking-at "when[^_a-zA-Z0-9]")
+ (erlang-push (list 'when token (current-column)) stack))
+ ((looking-at "catch\\b.*of")
+ t)
+ ((looking-at "catch\\b\\s *\\($\\|%\\|.*->\\)")
+ (erlang-push (list 'icr token (current-column)) stack))
+ ;;(erlang-push (list '-> token (current-column)) stack))
+ ;;((looking-at "^of$")
+ ;; (erlang-push (list 'icr token (current-column)) stack)
+ ;;(erlang-push (list '-> token (current-column)) stack))
+ )
(forward-sexp 1))
- ;; String: Try to skip over it. (Catch error if not complete.)
- ((= cs ?\")
- (condition-case nil
- (progn
- (forward-sexp 1)
- (if (> (point) to)
- (progn
- (setq in-what 'string)
- (goto-char to))))
- (error
- (setq in-what 'string)
- (goto-char to))))
+ ;; String: Try to skip over it. (Catch error if not complete.)
+ ((= cs ?\")
+ (condition-case nil
+ (progn
+ (forward-sexp 1)
+ (if (> (point) to)
+ (progn
+ (setq in-what 'string)
+ (goto-char to))))
+ (error
+ (setq in-what 'string)
+ (goto-char to))))
;; Expression prefix e.i. $ or ^ (Note ^ can be in the character
;; literal $^ or part of string and $ outside of a string denotes
;; a character literal)
((= cs ?')
- (cond
+ (cond
((= (following-char) ?\") ;; $ or ^ was the last char in a string
- (forward-char 1))
+ (forward-char 1))
(t
- ;; Maybe a character literal, quote the next char to avoid
- ;; situations as $" being seen as the begining of a string.
- ;; Note the quoting something in the middle of a string is harmless.
- (quote (following-char))
- (forward-char 1))))
+ ;; Maybe a character literal, quote the next char to avoid
+ ;; situations as $" being seen as the begining of a string.
+ ;; Note the quoting something in the middle of a string is harmless.
+ (quote (following-char))
+ (forward-char 1))))
;; Symbol constituent or punctuation
-
+
((memq cs '(?. ?_))
- (cond
-
+ (cond
+
;; Clause end
((= (following-char) ?\;)
- (if (eq (car (car (last stack))) 'spec)
- (while (memq (car (car stack)) '(when ::))
- (erlang-pop stack)))
- (if (and stack (eq (car (car stack)) '->))
- (erlang-pop stack))
- (forward-char 1))
-
+ (if (eq (car (car (last stack))) 'spec)
+ (while (memq (car (car stack)) '(when ::))
+ (erlang-pop stack)))
+ (if (and stack (eq (car (car stack)) '->))
+ (erlang-pop stack))
+ (forward-char 1))
+
;; Parameter separator
((looking-at ",")
- (forward-char 1)
- (if (and stack (eq (car (car stack)) '::))
- ;; Type or spec
- (erlang-pop stack)))
+ (forward-char 1)
+ (if (and stack (eq (car (car stack)) '::))
+ ;; Type or spec
+ (erlang-pop stack)))
;; Function end
((looking-at "\\.\\(\\s \\|\n\\|\\s<\\)")
- (setq stack nil)
- (forward-char 1))
-
+ (setq stack nil)
+ (forward-char 1))
+
;; Function head
((looking-at "->")
- (if (and stack (eq (car (car stack)) 'when))
- (erlang-pop stack))
- (erlang-push (list '-> token (current-column)) stack)
- (forward-char 2))
-
+ (if (and stack (eq (car (car stack)) 'when))
+ (erlang-pop stack))
+ (erlang-push (list '-> token (current-column)) stack)
+ (forward-char 2))
+
;; List-comprehension divider
((looking-at "||")
- (erlang-push (list '|| token (current-column)) stack)
- (forward-char 2))
+ (erlang-push (list '|| token (current-column)) stack)
+ (forward-char 2))
;; Bit-syntax open. Note that map syntax allows "<<" to follow ":="
;; or "=>" without intervening whitespace, so handle that case here
((looking-at "\\(:=\\|=>\\)?<<")
- (erlang-push (list '<< token (current-column)) stack)
- (forward-char (- (match-end 0) (match-beginning 0))))
-
+ (erlang-push (list '<< token (current-column)) stack)
+ (forward-char (- (match-end 0) (match-beginning 0))))
+
;; Bit-syntax close
((looking-at ">>")
- (while (memq (car (car stack)) '(|| ->))
- (erlang-pop stack))
- (cond ((eq (car (car stack)) '<<)
- (erlang-pop stack))
- ((memq (car (car stack)) '(icr begin fun))
- (error "Missing `end'"))
- (t
- (error "Unbalanced parentheses")))
- (forward-char 2))
-
+ (while (memq (car (car stack)) '(|| ->))
+ (erlang-pop stack))
+ (cond ((eq (car (car stack)) '<<)
+ (erlang-pop stack))
+ ((memq (car (car stack)) '(icr begin fun))
+ (error "Missing `end'"))
+ (t
+ (error "Unbalanced parentheses")))
+ (forward-char 2))
+
;; Macro
((= (following-char) ??)
- ;; Skip over the ?
- (forward-char 1)
- )
+ ;; Skip over the ?
+ (forward-char 1)
+ )
;; Type spec's
((looking-at "-type\\s \\|-opaque\\s ")
- (if stack
- (forward-char 1)
- (erlang-push (list 'icr token (current-column)) stack)
- (forward-char 6)))
+ (if stack
+ (forward-char 1)
+ (erlang-push (list 'icr token (current-column)) stack)
+ (forward-char 6)))
((looking-at "-spec\\s ")
- (if stack
- (forward-char 1)
- (forward-char 6)
- (skip-chars-forward "^(\n")
- (erlang-push (list 'spec (point) (current-column)) stack)
- ))
+ (if stack
+ (forward-char 1)
+ (forward-char 6)
+ (skip-chars-forward "^(\n")
+ (erlang-push (list 'spec (point) (current-column)) stack)
+ ))
;; Type spec delimiter
((looking-at "::")
- (erlang-push (list ':: token (current-column)) stack)
- (forward-char 2))
-
- ;; Don't follow through in the clause below
- ;; '|' don't need spaces around it
+ (erlang-push (list ':: token (current-column)) stack)
+ (forward-char 2))
+
+ ;; Don't follow through in the clause below
+ ;; '|' don't need spaces around it
((looking-at "|")
- (forward-char 1))
-
+ (forward-char 1))
+
;; Other punctuation: Skip over it and any following punctuation
((= cs ?.)
- ;; Skip over all characters in the operand.
- (skip-syntax-forward "."))
-
+ ;; Skip over all characters in the operand.
+ (skip-syntax-forward "."))
+
;; Other char: Skip over it.
(t
- (forward-char 1))))
-
+ (forward-char 1))))
+
;; Open parenthesis
((= cs ?\()
(erlang-push (list '\( token (current-column)) stack)
(forward-char 1))
-
+
;; Close parenthesis
((= cs ?\))
(while (memq (car (car stack)) '(|| -> :: when))
- (erlang-pop stack))
+ (erlang-pop stack))
(cond ((eq (car (car stack)) '\()
- (erlang-pop stack)
- (if (and (eq (car (car stack)) 'fun)
- (or (eq (car (car (last stack))) 'spec)
- (eq (car (car (cdr stack))) '::))) ;; -type()
- ;; Inside fun type def ') closes fun definition
- (erlang-pop stack)))
- ((eq (car (car stack)) 'icr)
- (erlang-pop stack)
- ;; Normal catch not try-catch might have caused icr
- ;; and then incr should be removed and is not an error.
- (if (eq (car (car stack)) '\()
- (erlang-pop stack)
- (error "Missing `end'")
- ))
- ((eq (car (car stack)) 'begin)
- (error "Missing `end'"))
- (t
- (error "Unbalanced parenthesis"))
- )
- (forward-char 1))
-
+ (erlang-pop stack)
+ (if (and (eq (car (car stack)) 'fun)
+ (or (eq (car (car (last stack))) 'spec)
+ (eq (car (car (cdr stack))) '::))) ;; -type()
+ ;; Inside fun type def ') closes fun definition
+ (erlang-pop stack)))
+ ((eq (car (car stack)) 'icr)
+ (erlang-pop stack)
+ ;; Normal catch not try-catch might have caused icr
+ ;; and then incr should be removed and is not an error.
+ (if (eq (car (car stack)) '\()
+ (erlang-pop stack)
+ (error "Missing `end'")
+ ))
+ ((eq (car (car stack)) 'begin)
+ (error "Missing `end'"))
+ (t
+ (error "Unbalanced parenthesis"))
+ )
+ (forward-char 1))
+
;; Character quote: Skip it and the quoted char.
((= cs ?/)
(forward-char 2))
-
+
;; Character escape: Skip it and the escape sequence.
((= cs ?\\)
(forward-char 1)
@@ -2855,49 +2759,49 @@ Return nil if inside string, t if in a comment."
((eq (car stack-top) '\()
;; Element of list, tuple or part of an expression,
(cond ((null erlang-argument-indent)
- ;; indent to next column.
- (1+ (nth 2 stack-top)))
- ((= (char-syntax (following-char)) ?\))
- (goto-char (nth 1 stack-top))
- (cond ((looking-at "[({]\\s *\\($\\|%\\)")
- ;; Line ends with parenthesis.
- (let ((previous (erlang-indent-find-preceding-expr))
- (stack-pos (nth 2 stack-top)))
- (if (>= previous stack-pos) stack-pos
- (- (+ previous erlang-argument-indent) 1))))
- (t
- (nth 2 stack-top))))
- ((= (following-char) ?,)
- ;; a comma at the start of the line: line up with opening parenthesis.
- (nth 2 stack-top))
- (t
- (goto-char (nth 1 stack-top))
- (let ((base (cond ((looking-at "[({]\\s *\\($\\|%\\)")
- ;; Line ends with parenthesis.
- (erlang-indent-parenthesis (nth 2 stack-top)))
- (t
- ;; Indent to the same column as the first
- ;; argument.
- (goto-char (1+ (nth 1 stack-top)))
- (skip-chars-forward " \t")
- (current-column)))))
- (erlang-indent-standard indent-point token base 't)))))
- ;;
- ((eq (car stack-top) '<<)
- ;; Element of binary (possible comprehension) expression,
- (cond ((null erlang-argument-indent)
- ;; indent to next column.
- (+ 2 (nth 2 stack-top)))
- ((looking-at "\\(>>\\)[^_a-zA-Z0-9]")
- (nth 2 stack-top))
- (t
- (goto-char (nth 1 stack-top))
- ;; Indent to the same column as the first
- ;; argument.
- (goto-char (+ 2 (nth 1 stack-top)))
- (skip-chars-forward " \t")
- (current-column))))
-
+ ;; indent to next column.
+ (1+ (nth 2 stack-top)))
+ ((= (char-syntax (following-char)) ?\))
+ (goto-char (nth 1 stack-top))
+ (cond ((looking-at "[({]\\s *\\($\\|%\\)")
+ ;; Line ends with parenthesis.
+ (let ((previous (erlang-indent-find-preceding-expr))
+ (stack-pos (nth 2 stack-top)))
+ (if (>= previous stack-pos) stack-pos
+ (- (+ previous erlang-argument-indent) 1))))
+ (t
+ (nth 2 stack-top))))
+ ((= (following-char) ?,)
+ ;; a comma at the start of the line: line up with opening parenthesis.
+ (nth 2 stack-top))
+ (t
+ (goto-char (nth 1 stack-top))
+ (let ((base (cond ((looking-at "[({]\\s *\\($\\|%\\)")
+ ;; Line ends with parenthesis.
+ (erlang-indent-parenthesis (nth 2 stack-top)))
+ (t
+ ;; Indent to the same column as the first
+ ;; argument.
+ (goto-char (1+ (nth 1 stack-top)))
+ (skip-chars-forward " \t")
+ (current-column)))))
+ (erlang-indent-standard indent-point token base 't)))))
+ ;;
+ ((eq (car stack-top) '<<)
+ ;; Element of binary (possible comprehension) expression,
+ (cond ((null erlang-argument-indent)
+ ;; indent to next column.
+ (+ 2 (nth 2 stack-top)))
+ ((looking-at "\\(>>\\)[^_a-zA-Z0-9]")
+ (nth 2 stack-top))
+ (t
+ (goto-char (nth 1 stack-top))
+ ;; Indent to the same column as the first
+ ;; argument.
+ (goto-char (+ 2 (nth 1 stack-top)))
+ (skip-chars-forward " \t")
+ (current-column))))
+
((memq (car stack-top) '(icr fun spec))
;; The default indentation is the column of the option
;; directly following the keyword. (This does not apply to
@@ -2908,156 +2812,160 @@ Return nil if inside string, t if in a comment."
;; `after' should be indented to the same level as the
;; corresponding receive.
(cond ((looking-at "\\(after\\|of\\)\\($\\|[^_a-zA-Z0-9]\\)")
- (nth 2 stack-top))
- ((looking-at "when[^_a-zA-Z0-9]")
- ;; Handling one when part
- (+ (nth 2 stack-top) erlang-indent-level erlang-indent-guard))
- (t
- (save-excursion
- (goto-char (nth 1 stack-top))
- (if (looking-at "case[^_a-zA-Z0-9]")
- (+ (nth 2 stack-top) erlang-indent-level)
- (skip-chars-forward "a-z")
- (skip-chars-forward " \t")
- (if (memq (following-char) '(?% ?\n))
- (+ (nth 2 stack-top) erlang-indent-level)
- (current-column))))))
- )
- ((and (eq (car stack-top) '||) (looking-at "\\(]\\|>>\\)[^_a-zA-Z0-9]"))
- (nth 2 (car (cdr stack))))
+ (nth 2 stack-top))
+ ((looking-at "when[^_a-zA-Z0-9]")
+ ;; Handling one when part
+ (+ (nth 2 stack-top) erlang-indent-level erlang-indent-guard))
+ (t
+ (save-excursion
+ (goto-char (nth 1 stack-top))
+ (if (and erlang-icr-indent
+ (looking-at "\\(if\\|case\\|receive\\)[^_a-zA-Z0-9]"))
+ (+ (nth 2 stack-top) erlang-icr-indent)
+ (if (looking-at "\\(case\\|receive\\)[^_a-zA-Z0-9]")
+ (+ (nth 2 stack-top) erlang-indent-level)
+ (skip-chars-forward "a-z")
+ (skip-chars-forward " \t")
+ (if (memq (following-char) '(?% ?\n))
+ (+ (nth 2 stack-top) erlang-indent-level)
+ (current-column))))))))
+ ((and (eq (car stack-top) '||) (looking-at "\\(]\\|>>\\)[^_a-zA-Z0-9]"))
+ (nth 2 (car (cdr stack))))
;; Real indentation, where operators create extra indentation etc.
((memq (car stack-top) '(-> || try begin))
- (if (looking-at "\\(of\\)[^_a-zA-Z0-9]")
- (nth 2 stack-top)
- (goto-char (nth 1 stack-top))
- ;; Check if there is more code after the '->' on the
- ;; same line. If so use this indentation as base, else
- ;; use parent indentation + 2 * level as base.
- (let ((off erlang-indent-level)
- (skip 2))
- (cond ((null (cdr stack))) ; Top level in function.
- ((eq (car stack-top) 'begin)
- (setq skip 5))
- ((eq (car stack-top) 'try)
- (setq skip 5))
- ((eq (car stack-top) '->)
- ;; If in fun definition use standard indent level not double
- ;;(if (not (eq (car (car (cdr stack))) 'fun))
- ;; Removed it made multi clause fun's look to bad
- (setq off (* 2 erlang-indent-level)))) ;; )
- (let ((base (erlang-indent-find-base stack indent-point off skip)))
- ;; Special cases
- (goto-char indent-point)
- (cond ((looking-at "\\(end\\|after\\)\\($\\|[^_a-zA-Z0-9]\\)")
- (if (eq (car stack-top) '->)
- (erlang-pop stack))
- (if stack
- (erlang-caddr (car stack))
- 0))
- ((looking-at "catch\\b\\($\\|[^_a-zA-Z0-9]\\)")
- ;; Are we in a try
- (let ((start (if (eq (car stack-top) '->)
- (car (cdr stack))
- stack-top)))
- (if (null start) nil
- (goto-char (nth 1 start)))
- (cond ((looking-at "try\\($\\|[^_a-zA-Z0-9]\\)")
- (progn
- (if (eq (car stack-top) '->)
- (erlang-pop stack))
- (if stack
- (erlang-caddr (car stack))
- 0)))
- (t (erlang-indent-standard indent-point token base 'nil))))) ;; old catch
- (t
- (erlang-indent-standard indent-point token base 'nil)
- ))))
- ))
- ((eq (car stack-top) 'when)
- (goto-char (nth 1 stack-top))
- (if (looking-at "when\\s *\\($\\|%\\)")
- (progn
- (erlang-pop stack)
- (if (and stack (memq (nth 0 (car stack)) '(icr fun)))
- (progn
- (goto-char (nth 1 (car stack)))
- (+ (nth 2 (car stack)) erlang-indent-guard
- ;; receive XYZ or receive
- ;; XYZ
- ;; This if thing does not seem to be needed
- ;;(if (looking-at "[a-z]+\\s *\\($\\|%\\)")
- ;; erlang-indent-level
- ;; (* 2 erlang-indent-level))))
- (* 2 erlang-indent-level)))
- ;;erlang-indent-level))
- (+ erlang-indent-level erlang-indent-guard)))
+ (if (looking-at "\\(of\\)[^_a-zA-Z0-9]")
+ (nth 2 stack-top)
+ (goto-char (nth 1 stack-top))
+ ;; Check if there is more code after the '->' on the
+ ;; same line. If so use this indentation as base, else
+ ;; use parent indentation + 2 * level as base.
+ (let ((off erlang-indent-level)
+ (skip 2))
+ (cond ((null (cdr stack))) ; Top level in function.
+ ((eq (car stack-top) 'begin)
+ (setq skip 5))
+ ((eq (car stack-top) 'try)
+ (setq skip 5))
+ ((eq (car stack-top) '->)
+ ;; If in fun definition use standard indent level not double
+ ;;(if (not (eq (car (car (cdr stack))) 'fun))
+ ;; Removed it made multi clause fun's look too bad
+ (setq off (+ erlang-indent-level (if (not erlang-icr-indent)
+ erlang-indent-level
+ erlang-icr-indent)))))
+ (let ((base (erlang-indent-find-base stack indent-point off skip)))
+ ;; Special cases
+ (goto-char indent-point)
+ (cond ((looking-at "\\(end\\|after\\)\\($\\|[^_a-zA-Z0-9]\\)")
+ (if (eq (car stack-top) '->)
+ (erlang-pop stack))
+ (if stack
+ (erlang-caddr (car stack))
+ 0))
+ ((looking-at "catch\\b\\($\\|[^_a-zA-Z0-9]\\)")
+ ;; Are we in a try
+ (let ((start (if (eq (car stack-top) '->)
+ (car (cdr stack))
+ stack-top)))
+ (if (null start) nil
+ (goto-char (nth 1 start)))
+ (cond ((looking-at "try\\($\\|[^_a-zA-Z0-9]\\)")
+ (progn
+ (if (eq (car stack-top) '->)
+ (erlang-pop stack))
+ (if stack
+ (erlang-caddr (car stack))
+ 0)))
+ (t (erlang-indent-standard indent-point token base 'nil))))) ;; old catch
+ (t
+ (erlang-indent-standard indent-point token base 'nil)
+ ))))
+ ))
+ ((eq (car stack-top) 'when)
+ (goto-char (nth 1 stack-top))
+ (if (looking-at "when\\s *\\($\\|%\\)")
+ (progn
+ (erlang-pop stack)
+ (if (and stack (memq (nth 0 (car stack)) '(icr fun)))
+ (progn
+ (goto-char (nth 1 (car stack)))
+ (+ (nth 2 (car stack)) erlang-indent-guard
+ ;; receive XYZ or receive
+ ;; XYZ
+ ;; This if thing does not seem to be needed
+ ;;(if (looking-at "[a-z]+\\s *\\($\\|%\\)")
+ ;; erlang-indent-level
+ ;; (* 2 erlang-indent-level))))
+ (* 2 erlang-indent-level)))
+ ;;erlang-indent-level))
+ (+ erlang-indent-level erlang-indent-guard)))
;; "when" is followed by code, let's indent to the same
;; column.
(forward-char 4) ; Skip "when"
(skip-chars-forward " \t")
(current-column)))
- ;; Type and Spec indentation
- ((eq (car stack-top) '::)
- (if (looking-at "[},)]")
- ;; Closing function spec, record definition with types,
+ ;; Type and Spec indentation
+ ((eq (car stack-top) '::)
+ (if (looking-at "[},)]")
+ ;; Closing function spec, record definition with types,
;; or a comma at the start of the line
- ;; pop stack and recurse
- (erlang-calculate-stack-indent indent-point
- (cons (erlang-pop stack) (cdr state)))
- (cond ((null erlang-argument-indent)
- ;; indent to next column.
- (+ 2 (nth 2 stack-top)))
- ((looking-at "::[^_a-zA-Z0-9]")
- (nth 2 stack-top))
- (t
- (let ((start-alternativ (if (looking-at "|") 2 0)))
- (goto-char (nth 1 stack-top))
- (- (cond ((looking-at "::\\s *\\($\\|%\\)")
- ;; Line ends with ::
- (if (eq (car (car (last stack))) 'spec)
- (+ (erlang-indent-find-preceding-expr 1)
- erlang-argument-indent)
- (+ (erlang-indent-find-preceding-expr 2)
- erlang-argument-indent)))
- (t
- ;; Indent to the same column as the first
- ;; argument.
- (goto-char (+ 2 (nth 1 stack-top)))
- (skip-chars-forward " \t")
- (current-column))) start-alternativ))))))
- )))
+ ;; pop stack and recurse
+ (erlang-calculate-stack-indent indent-point
+ (cons (erlang-pop stack) (cdr state)))
+ (cond ((null erlang-argument-indent)
+ ;; indent to next column.
+ (+ 2 (nth 2 stack-top)))
+ ((looking-at "::[^_a-zA-Z0-9]")
+ (nth 2 stack-top))
+ (t
+ (let ((start-alternativ (if (looking-at "|") 2 0)))
+ (goto-char (nth 1 stack-top))
+ (- (cond ((looking-at "::\\s *\\($\\|%\\)")
+ ;; Line ends with ::
+ (if (eq (car (car (last stack))) 'spec)
+ (+ (erlang-indent-find-preceding-expr 1)
+ erlang-argument-indent)
+ (+ (erlang-indent-find-preceding-expr 2)
+ erlang-argument-indent)))
+ (t
+ ;; Indent to the same column as the first
+ ;; argument.
+ (goto-char (+ 2 (nth 1 stack-top)))
+ (skip-chars-forward " \t")
+ (current-column))) start-alternativ))))))
+ )))
(defun erlang-indent-standard (indent-point token base inside-parenthesis)
"Standard indent when in blocks or tuple or arguments.
Look at last thing to see in what state we are, move relative to the base."
- (goto-char token)
+ (goto-char token)
(cond ((looking-at "||\\|,\\|->\\||")
- base)
- ((erlang-at-keyword)
- (+ (current-column) erlang-indent-level))
- ((or (= (char-syntax (following-char)) ?.)
- (erlang-at-operator))
- (+ base erlang-indent-level))
- (t
- (goto-char indent-point)
- (cond ((memq (following-char) '(?\( ))
- ;; Function application.
- (+ (erlang-indent-find-preceding-expr)
- erlang-argument-indent))
- ;; Empty line, or end; treat it as the end of
- ;; the block. (Here we have a choice: should
- ;; the user be forced to reindent continued
- ;; lines, or should the "end" be reindented?)
-
- ;; Avoid treating comments a continued line.
- ((= (following-char) ?%)
- base)
- ;; Continued line (e.g. line beginning
- ;; with an operator.)
- (t
- (if (or (erlang-at-operator) (not inside-parenthesis))
- (+ base erlang-indent-level)
- base))))))
+ base)
+ ((erlang-at-keyword)
+ (+ (current-column) erlang-indent-level))
+ ((or (= (char-syntax (following-char)) ?.)
+ (erlang-at-operator))
+ (+ base erlang-indent-level))
+ (t
+ (goto-char indent-point)
+ (cond ((memq (following-char) '(?\( ))
+ ;; Function application.
+ (+ (erlang-indent-find-preceding-expr)
+ erlang-argument-indent))
+ ;; Empty line, or end; treat it as the end of
+ ;; the block. (Here we have a choice: should
+ ;; the user be forced to reindent continued
+ ;; lines, or should the "end" be reindented?)
+
+ ;; Avoid treating comments a continued line.
+ ((= (following-char) ?%)
+ base)
+ ;; Continued line (e.g. line beginning
+ ;; with an operator.)
+ (t
+ (if (or (erlang-at-operator) (not inside-parenthesis))
+ (+ base erlang-indent-level)
+ base))))))
(defun erlang-indent-find-base (stack indent-point &optional offset skip)
"Find the base column for current stack."
@@ -3067,21 +2975,21 @@ Return nil if inside string, t if in a comment."
(let* ((stack-top (car stack)))
(goto-char (nth 1 stack-top))
(if (< skip (- (point-max) (point)))
- (progn
- (forward-char skip)
- (if (looking-at "\\s *\\($\\|%\\)")
- (progn
- (if (memq (car stack-top) '(-> ||))
- (erlang-pop stack))
- ;; Take parent identation + offset,
- ;; else just erlang-indent-level if no parent
- (if stack
- (+ (erlang-caddr (car stack))
- offset)
- erlang-indent-level))
- (erlang-skip-blank indent-point)
- (current-column)))
- (+ (current-column) skip)))))
+ (progn
+ (forward-char skip)
+ (if (looking-at "\\s *\\($\\|%\\)")
+ (progn
+ (if (memq (car stack-top) '(-> ||))
+ (erlang-pop stack))
+ ;; Take parent identation + offset,
+ ;; else just erlang-indent-level if no parent
+ (if stack
+ (+ (erlang-caddr (car stack))
+ offset)
+ erlang-indent-level))
+ (erlang-skip-blank indent-point)
+ (current-column)))
+ (+ (current-column) skip)))))
;; Does not handle `begin' .. `end'.
@@ -3100,51 +3008,51 @@ This assumes that the preceding expression is either simple
;; where the call (forward-sexp -1) will fail when point is at the `#'.
(or
(ignore-errors
- ;; Needed to match the colon in "'foo':'bar'".
- (cond ((eq (preceding-char) ?:)
- (backward-char 1)
- (forward-sexp -1)
- (current-column))
- ((eq (preceding-char) ?#)
- ;; We may now be at:
- ;; - either a construction of a new record
- ;; - or update of a record, in which case we want
- ;; the column of the expression to be updated.
- ;;
- ;; To see which of the two cases we are at, we first
- ;; move an expression backwards, check for keywords,
- ;; then immediately an expression forwards. Moving
- ;; backwards skips past tokens like `,' or `->', but
- ;; when moving forwards again, we won't skip past such
- ;; tokens. We use this: if, after having moved
- ;; forwards, we're back where we started, then it was
- ;; a record update.
- ;; The check for keywords is to detect cases like:
- ;; case Something of #record_construction{...}
- (backward-char 1)
- (let ((record-start (point))
- (record-start-col (current-column)))
- (forward-sexp -1)
- (let ((preceding-expr-col (current-column))
- ;; white space definition according to erl_scan
- (white-space "\000-\040\200-\240"))
- (if (erlang-at-keyword)
- ;; The (forward-sexp -1) call moved past a keyword
- (1+ record-start-col)
- (forward-sexp 1)
- (skip-chars-forward white-space record-start)
- ;; Are we back where we started? If so, it was an update.
- (if (= (point) record-start)
- preceding-expr-col
- (goto-char record-start)
- (1+ (current-column)))))))
- (t col)))
+ ;; Needed to match the colon in "'foo':'bar'".
+ (cond ((eq (preceding-char) ?:)
+ (backward-char 1)
+ (forward-sexp -1)
+ (current-column))
+ ((eq (preceding-char) ?#)
+ ;; We may now be at:
+ ;; - either a construction of a new record
+ ;; - or update of a record, in which case we want
+ ;; the column of the expression to be updated.
+ ;;
+ ;; To see which of the two cases we are at, we first
+ ;; move an expression backwards, check for keywords,
+ ;; then immediately an expression forwards. Moving
+ ;; backwards skips past tokens like `,' or `->', but
+ ;; when moving forwards again, we won't skip past such
+ ;; tokens. We use this: if, after having moved
+ ;; forwards, we're back where we started, then it was
+ ;; a record update.
+ ;; The check for keywords is to detect cases like:
+ ;; case Something of #record_construction{...}
+ (backward-char 1)
+ (let ((record-start (point))
+ (record-start-col (current-column)))
+ (forward-sexp -1)
+ (let ((preceding-expr-col (current-column))
+ ;; white space definition according to erl_scan
+ (white-space "\000-\040\200-\240"))
+ (if (erlang-at-keyword)
+ ;; The (forward-sexp -1) call moved past a keyword
+ (1+ record-start-col)
+ (forward-sexp 1)
+ (skip-chars-forward white-space record-start)
+ ;; Are we back where we started? If so, it was an update.
+ (if (= (point) record-start)
+ preceding-expr-col
+ (goto-char record-start)
+ (1+ (current-column)))))))
+ (t col)))
col))))
-(defun erlang-indent-parenthesis (stack-position)
+(defun erlang-indent-parenthesis (stack-position)
(let ((previous (erlang-indent-find-preceding-expr)))
(if (> previous stack-position)
- (+ stack-position erlang-argument-indent)
+ (+ stack-position erlang-argument-indent)
(+ previous erlang-argument-indent))))
(defun erlang-skip-blank (&optional lim)
@@ -3153,20 +3061,20 @@ This assumes that the preceding expression is either simple
(let (stop)
(while (and (not stop) (< (point) lim))
(cond ((= (following-char) ?%)
- (skip-chars-forward "^\n" lim))
- ((= (following-char) ?\n)
- (skip-chars-forward "\n" lim))
- ((looking-at "\\s ")
- (if (re-search-forward "\\S " lim 'move)
- (forward-char -1)))
- (t
- (setq stop t))))
+ (skip-chars-forward "^\n" lim))
+ ((= (following-char) ?\n)
+ (skip-chars-forward "\n" lim))
+ ((looking-at "\\s ")
+ (if (re-search-forward "\\S " lim 'move)
+ (forward-char -1)))
+ (t
+ (setq stop t))))
stop))
(defun erlang-at-keyword ()
"Are we looking at an Erlang keyword which will increase indentation?"
(looking-at (concat "\\(when\\|if\\|fun\\|case\\|begin\\|"
- "of\\|receive\\|after\\|catch\\|try\\)\\b")))
+ "of\\|receive\\|after\\|catch\\|try\\)\\b")))
(defun erlang-at-operator ()
"Are we looking at an Erlang operator?"
@@ -3179,14 +3087,14 @@ This assumes that the preceding expression is either simple
Used both by `indent-for-comment' and the Erlang specific indentation
commands."
(cond ((looking-at "%%%") 0)
- ((looking-at "%%")
- (or (erlang-calculate-indent)
- (current-indentation)))
- (t
- (save-excursion
- (skip-chars-backward " \t")
- (max (if (bolp) 0 (1+ (current-column)))
- comment-column)))))
+ ((looking-at "%%")
+ (or (erlang-calculate-indent)
+ (current-indentation)))
+ (t
+ (save-excursion
+ (skip-chars-backward " \t")
+ (max (if (bolp) 0 (1+ (current-column)))
+ comment-column)))))
;;; Erlang movement commands
@@ -3214,18 +3122,18 @@ Return t unless search stops due to end of buffer."
;; that the regexp below includes the last character of the
;; previous line.
(if (bobp)
- (or (looking-at "\n")
- (forward-char 1))
- (forward-char -1)
- (if (looking-at "\\`\n")
- (forward-char 1))))
+ (or (looking-at "\n")
+ (forward-char 1))
+ (forward-char -1)
+ (if (looking-at "\\`\n")
+ (forward-char 1))))
;; The regexp matches a function header that isn't
;; included in a string.
(and (re-search-forward "\\(\\`\\|\\`\n\\|[^\\]\n\\)\\(-?[a-z]\\|'\\|-\\)"
- nil 'move (- arg))
+ nil 'move (- arg))
(let ((beg (match-beginning 2)))
- (and beg (goto-char beg))
- t)))
+ (and beg (goto-char beg))
+ t)))
(defun erlang-end-of-clause (&optional arg)
"Move to the end of the current clause.
@@ -3233,29 +3141,24 @@ With argument, do this that many times."
(interactive "p")
(or arg (setq arg 1))
(while (and (looking-at "[ \t]*[%\n]")
- (zerop (forward-line 1))))
+ (zerop (forward-line 1))))
;; Move to the next clause.
(erlang-beginning-of-clause (- arg))
(beginning-of-line);; Just to be sure...
(let ((continue t))
(while (and (not (bobp)) continue)
(forward-line -1)
- (skip-chars-forward " \t")
- (if (looking-at "[%\n]")
- nil
- (end-of-line)
- (setq continue nil)))))
+ (unless (looking-at "[ \t]*[%\n]")
+ (end-of-line)
+ (setq continue nil)))))
(defun erlang-mark-clause ()
"Put mark at end of clause, point at beginning."
(interactive)
(push-mark (point))
(erlang-end-of-clause 1)
- ;; Sets the region. In Emacs 19 and XEmacs, we want to activate
- ;; the region.
- (condition-case nil
- (push-mark (point) nil t)
- (error (push-mark (point))))
+ ;; Sets the region.
+ (push-mark (point) nil t)
(erlang-beginning-of-clause 1)
;; The above function deactivates the mark.
(if (boundp 'deactivate-mark)
@@ -3273,22 +3176,22 @@ Return t unless search stops due to end of buffer."
;; Search backward
((> arg 0)
(while (and (> arg 0)
- (and (erlang-beginning-of-clause 1)
- (let ((start (point))
- (name (erlang-name-of-function))
- (arity (erlang-get-function-arity)))
- ;; Note: "arity" is nil for e.g. "-import", hence
- ;; two "-import" clauses are not considered to
- ;; be part of the same function.
- (while (and (erlang-beginning-of-clause 1)
- (string-equal name
- (erlang-name-of-function))
- arity
- (equal arity
- (erlang-get-function-arity)))
- (setq start (point)))
- (goto-char start)
- t)))
+ (and (erlang-beginning-of-clause 1)
+ (let ((start (point))
+ (name (erlang-name-of-function))
+ (arity (erlang-get-function-arity)))
+ ;; Note: "arity" is nil for e.g. "-import", hence
+ ;; two "-import" clauses are not considered to
+ ;; be part of the same function.
+ (while (and (erlang-beginning-of-clause 1)
+ (string-equal name
+ (erlang-name-of-function))
+ arity
+ (equal arity
+ (erlang-get-function-arity)))
+ (setq start (point)))
+ (goto-char start)
+ t)))
(setq arg (1- arg))))
;; Search forward
((< arg 0)
@@ -3296,19 +3199,19 @@ Return t unless search stops due to end of buffer."
(erlang-beginning-of-clause 1)
;; Step -arg functions forward.
(while (and (< arg 0)
- ;; Step one function forward, or stop if the end of
- ;; the buffer was reached. Return t if we found the
- ;; function.
- (let ((name (erlang-name-of-function))
- (arity (erlang-get-function-arity))
- (found (erlang-beginning-of-clause -1)))
- (while (and found
- (string-equal name (erlang-name-of-function))
- arity
- (equal arity
- (erlang-get-function-arity)))
- (setq found (erlang-beginning-of-clause -1)))
- found))
+ ;; Step one function forward, or stop if the end of
+ ;; the buffer was reached. Return t if we found the
+ ;; function.
+ (let ((name (erlang-name-of-function))
+ (arity (erlang-get-function-arity))
+ (found (erlang-beginning-of-clause -1)))
+ (while (and found
+ (string-equal name (erlang-name-of-function))
+ arity
+ (equal arity
+ (erlang-get-function-arity)))
+ (setq found (erlang-beginning-of-clause -1)))
+ found))
(setq arg (1+ arg)))))
(zerop arg))
@@ -3324,35 +3227,35 @@ With negative argument go towards the beginning of the buffer."
;; Forward
(while (and (> arg 0) (< (point) (point-max)))
(let ((pos (point)))
- (while (progn
- (if (and first
- (progn
- (forward-char 1)
- (erlang-beginning-of-clause 1)))
- nil
- (or (bobp) (forward-char -1))
- (erlang-beginning-of-clause -1))
- (setq first nil)
- (erlang-pass-over-function)
- (skip-chars-forward " \t")
- (if (looking-at "[%\n]")
- (forward-line 1))
- (<= (point) pos))))
+ (while (progn
+ (if (and first
+ (progn
+ (forward-char 1)
+ (erlang-beginning-of-clause 1)))
+ nil
+ (or (bobp) (forward-char -1))
+ (erlang-beginning-of-clause -1))
+ (setq first nil)
+ (erlang-pass-over-function)
+ (skip-chars-forward " \t")
+ (if (looking-at "[%\n]")
+ (forward-line 1))
+ (<= (point) pos))))
(setq arg (1- arg)))
;; Backward
(while (< arg 0)
(let ((pos (point)))
- (erlang-beginning-of-clause 1)
- (erlang-pass-over-function)
- (forward-line 1)
- (if (>= (point) pos)
- (if (erlang-beginning-of-function 2)
- (progn
- (erlang-pass-over-function)
- (skip-chars-forward " \t")
- (if (looking-at "[%\n]")
- (forward-line 1)))
- (goto-char (point-min)))))
+ (erlang-beginning-of-clause 1)
+ (erlang-pass-over-function)
+ (forward-line 1)
+ (if (>= (point) pos)
+ (if (erlang-beginning-of-function 2)
+ (progn
+ (erlang-pass-over-function)
+ (skip-chars-forward " \t")
+ (if (looking-at "[%\n]")
+ (forward-line 1)))
+ (goto-char (point-min)))))
(setq arg (1+ arg)))))
(eval-and-compile
@@ -3363,21 +3266,18 @@ With negative argument go towards the beginning of the buffer."
(interactive)
(push-mark (point))
(erlang-end-of-function 1)
- ;; Sets the region. In Emacs 19 and XEmacs, we want to activate
- ;; the region.
- (condition-case nil
- (push-mark (point) nil t)
- (error (push-mark (point))))
+ ;; Sets the region.
+ (push-mark (point) nil t)
(erlang-beginning-of-function 1)
;; The above function deactivates the mark.
(if (boundp 'deactivate-mark)
- (funcall (symbol-function 'set) 'deactivate-mark nil)))))
+ (funcall (symbol-function 'set) 'deactivate-mark nil)))))
(defun erlang-pass-over-function ()
(while (progn
- (erlang-skip-blank)
- (and (not (looking-at "\\.\\(\\s \\|\n\\|\\s<\\)"))
- (not (eobp))))
+ (erlang-skip-blank)
+ (and (not (looking-at "\\.\\(\\s \\|\n\\|\\s<\\)"))
+ (not (eobp))))
(forward-sexp 1))
(if (not (eobp))
(forward-char 1)))
@@ -3386,7 +3286,7 @@ With negative argument go towards the beginning of the buffer."
(save-excursion
;; Skip over attribute leader.
(if (looking-at "-[ \t]*")
- (re-search-forward "-[ \t]*" nil 'move))
+ (re-search-forward "-[ \t]*" nil 'move))
(let ((start (point)))
(forward-sexp 1)
(buffer-substring start (point)))))
@@ -3401,61 +3301,54 @@ paragraph of it that point is in, preserving the comment's indentation
and initial `%':s."
(interactive "P")
(let ((has-comment nil)
- ;; If has-comment, the appropriate fill-prefix for the comment.
- comment-fill-prefix)
+ ;; If has-comment, the appropriate fill-prefix for the comment.
+ comment-fill-prefix)
;; Figure out what kind of comment we are looking at.
(save-excursion
(beginning-of-line)
(cond
;; Find the command prefix.
((looking-at (concat "\\s *" comment-start-skip))
- (setq has-comment t)
- (setq comment-fill-prefix (buffer-substring (match-beginning 0)
- (match-end 0))))
+ (setq has-comment t)
+ (setq comment-fill-prefix (buffer-substring (match-beginning 0)
+ (match-end 0))))
;; A line with some code, followed by a comment? Remember that the
;; % which starts the comment shouldn't be part of a string or
;; character.
((progn
- (while (not (looking-at "%\\|$"))
- (skip-chars-forward "^%\n\"\\\\")
- (cond
- ((eq (char-after (point)) ?\\) (forward-char 2))
- ((eq (char-after (point)) ?\") (forward-sexp 1))))
- (looking-at comment-start-skip))
- (setq has-comment t)
- (setq comment-fill-prefix
- (concat (make-string (current-column) ? )
- (buffer-substring (match-beginning 0) (match-end 0)))))))
+ (while (not (looking-at "%\\|$"))
+ (skip-chars-forward "^%\n\"\\\\")
+ (cond
+ ((eq (char-after (point)) ?\\) (forward-char 2))
+ ((eq (char-after (point)) ?\") (forward-sexp 1))))
+ (looking-at comment-start-skip))
+ (setq has-comment t)
+ (setq comment-fill-prefix
+ (concat (make-string (current-column) ? )
+ (buffer-substring (match-beginning 0) (match-end 0)))))))
(if (not has-comment)
- (fill-paragraph justify)
+ (fill-paragraph justify)
;; Narrow to include only the comment, and then fill the region.
(save-restriction
- (narrow-to-region
- ;; Find the first line we should include in the region to fill.
- (save-excursion
- (while (and (zerop (forward-line -1))
- (looking-at "^\\s *%")))
- ;; We may have gone to far. Go forward again.
- (or (looking-at "^\\s *%")
- (forward-line 1))
- (point))
- ;; Find the beginning of the first line past the region to fill.
- (save-excursion
- (while (progn (forward-line 1)
- (looking-at "^\\s *%")))
- (point)))
- ;; Lines with only % on them can be paragraph boundaries.
- (let ((paragraph-start (concat paragraph-start "\\|^[ \t%]*$"))
- (paragraph-separate (concat paragraph-start "\\|^[ \t%]*$"))
- (fill-prefix comment-fill-prefix))
- (fill-paragraph justify))))))
-
-
-(defun erlang-uncomment-region (beg end)
- "Uncomment all commented lines in the region."
- (interactive "r")
- (uncomment-region beg end))
-
+ (narrow-to-region
+ ;; Find the first line we should include in the region to fill.
+ (save-excursion
+ (while (and (zerop (forward-line -1))
+ (looking-at "^\\s *%")))
+ ;; We may have gone to far. Go forward again.
+ (or (looking-at "^\\s *%")
+ (forward-line 1))
+ (point))
+ ;; Find the beginning of the first line past the region to fill.
+ (save-excursion
+ (while (progn (forward-line 1)
+ (looking-at "^\\s *%")))
+ (point)))
+ ;; Lines with only % on them can be paragraph boundaries.
+ (let ((paragraph-start (concat paragraph-start "\\|^[ \t%]*$"))
+ (paragraph-separate (concat paragraph-start "\\|^[ \t%]*$"))
+ (fill-prefix comment-fill-prefix))
+ (fill-paragraph justify))))))
(defun erlang-generate-new-clause ()
"Create additional Erlang clause header.
@@ -3467,22 +3360,22 @@ first parenthesis is preserved. The point is placed between
the parentheses."
(interactive)
(let ((name (save-excursion
- (and (erlang-beginning-of-clause)
- (erlang-get-function-name t))))
- (arrow (save-excursion
- (and (erlang-beginning-of-clause)
- (erlang-get-function-arrow)))))
+ (and (erlang-beginning-of-clause)
+ (erlang-get-function-name t))))
+ (arrow (save-excursion
+ (and (erlang-beginning-of-clause)
+ (erlang-get-function-arrow)))))
(if (or (null arrow) (null name))
- (error "Can't find name of current Erlang function"))
+ (error "Can't find name of current Erlang function"))
(if (and (bolp) (eolp))
- nil
+ nil
(end-of-line)
(newline))
(insert name)
(save-excursion
(insert ") " arrow))
(if erlang-new-clause-with-arguments
- (erlang-clone-arguments))))
+ (erlang-clone-arguments))))
(defun erlang-clone-arguments ()
@@ -3492,12 +3385,12 @@ The mark is set at the beginning of the inserted text, the point
at the end."
(interactive)
(let ((args (save-excursion
- (beginning-of-line)
- (and (erlang-beginning-of-clause)
- (erlang-get-function-arguments))))
- (p (point)))
+ (beginning-of-line)
+ (and (erlang-beginning-of-clause)
+ (erlang-get-function-arguments))))
+ (p (point)))
(if (null args)
- (error "Can't clone argument list"))
+ (error "Can't clone argument list"))
(insert args)
(set-mark p)))
@@ -3520,18 +3413,18 @@ Return nil if file contains no `-module' attribute."
(widen)
(goto-char (point-min))
(let ((md (match-data)))
- (unwind-protect
- (if (re-search-forward
- (eval-when-compile
- (concat "^-module\\s *(\\s *\\(\\("
- erlang-atom-regexp
- "\\)?\\)\\s *)\\s *\\."))
- (point-max) t)
- (erlang-remove-quotes
- (erlang-buffer-substring (match-beginning 1)
- (match-end 1)))
- nil)
- (store-match-data md))))))
+ (unwind-protect
+ (if (re-search-forward
+ (eval-when-compile
+ (concat "^-module\\s *(\\s *\\(\\("
+ erlang-atom-regexp
+ "\\)?\\)\\s *)\\s *\\."))
+ (point-max) t)
+ (erlang-remove-quotes
+ (erlang-buffer-substring (match-beginning 1)
+ (match-end 1)))
+ nil)
+ (store-match-data md))))))
(defun erlang-get-module-from-file-name (&optional file)
@@ -3551,7 +3444,7 @@ tags system could be used by files written in other languages."
nil
(setq file (file-name-nondirectory file))
(if (string-match erlang-file-name-extension-regexp file)
- (substring file 0 (match-beginning 0))
+ (substring file 0 (match-beginning 0))
nil)))
@@ -3572,30 +3465,30 @@ corresponds to the order of the parsed Erlang list."
(erlang-skip-blank)
(forward-char 1)
(if (not (eq (preceding-char) ?\[))
- '() ; Not looking at an Erlang list.
- (while ; Note: `while' has no body.
- (progn
- (erlang-skip-blank)
- (and (looking-at (eval-when-compile
- (concat erlang-atom-regexp "/\\([0-9]+\\)\\>")))
- (progn
- (setq res (cons
- (cons
- (erlang-remove-quotes
- (erlang-buffer-substring
- (match-beginning 1) (match-end 1)))
- (erlang-string-to-int
- (erlang-buffer-substring
- (match-beginning
- (+ 1 erlang-atom-regexp-matches))
- (match-end
- (+ 1 erlang-atom-regexp-matches)))))
- res))
- (goto-char (match-end 0))
- (erlang-skip-blank)
- (forward-char 1)
- ;; Test if there are more exported functions.
- (eq (preceding-char) ?,))))))
+ '() ; Not looking at an Erlang list.
+ (while ; Note: `while' has no body.
+ (progn
+ (erlang-skip-blank)
+ (and (looking-at (eval-when-compile
+ (concat erlang-atom-regexp "/\\([0-9]+\\)\\>")))
+ (progn
+ (setq res (cons
+ (cons
+ (erlang-remove-quotes
+ (erlang-buffer-substring
+ (match-beginning 1) (match-end 1)))
+ (string-to-number
+ (erlang-buffer-substring
+ (match-beginning
+ (+ 1 erlang-atom-regexp-matches))
+ (match-end
+ (+ 1 erlang-atom-regexp-matches)))))
+ res))
+ (goto-char (match-end 0))
+ (erlang-skip-blank)
+ (forward-char 1)
+ ;; Test if there are more exported functions.
+ (eq (preceding-char) ?,))))))
(nreverse res)))
@@ -3607,14 +3500,14 @@ corresponds to the order of the parsed Erlang list."
(save-excursion
(goto-char (point-min))
(let ((md (match-data))
- (res '()))
+ (res '()))
(unwind-protect
- (progn
- (while (re-search-forward "^-export\\s *(" (point-max) t)
- (erlang-skip-blank)
- (setq res (nconc res (erlang-get-function-arity-list))))
- res)
- (store-match-data md)))))
+ (progn
+ (while (re-search-forward "^-export\\s *(" (point-max) t)
+ (erlang-skip-blank)
+ (setq res (nconc res (erlang-get-function-arity-list))))
+ res)
+ (store-match-data md)))))
(defun erlang-get-import ()
@@ -3625,30 +3518,30 @@ function and arity as cdr part."
(save-excursion
(goto-char (point-min))
(let ((md (match-data))
- (res '()))
+ (res '()))
(unwind-protect
- (progn
- (while (re-search-forward "^-import\\s *(" (point-max) t)
- (erlang-skip-blank)
- (if (looking-at erlang-atom-regexp)
- (let ((module (erlang-remove-quotes
- (erlang-buffer-substring
- (match-beginning 0)
- (match-end 0)))))
- (goto-char (match-end 0))
- (erlang-skip-blank)
- (if (eq (following-char) ?,)
- (progn
- (forward-char 1)
- (erlang-skip-blank)
- (let ((funcs (erlang-get-function-arity-list))
- (pair (assoc module res)))
- (if pair
- (setcdr pair (nconc (cdr pair) funcs))
- (setq res (cons (cons module funcs)
- res)))))))))
- (nreverse res))
- (store-match-data md)))))
+ (progn
+ (while (re-search-forward "^-import\\s *(" (point-max) t)
+ (erlang-skip-blank)
+ (if (looking-at erlang-atom-regexp)
+ (let ((module (erlang-remove-quotes
+ (erlang-buffer-substring
+ (match-beginning 0)
+ (match-end 0)))))
+ (goto-char (match-end 0))
+ (erlang-skip-blank)
+ (if (eq (following-char) ?,)
+ (progn
+ (forward-char 1)
+ (erlang-skip-blank)
+ (let ((funcs (erlang-get-function-arity-list))
+ (pair (assoc module res)))
+ (if pair
+ (setcdr pair (nconc (cdr pair) funcs))
+ (setq res (cons (cons module funcs)
+ res)))))))))
+ (nreverse res))
+ (store-match-data md)))))
(defun erlang-get-function-name (&optional arg)
@@ -3660,12 +3553,12 @@ the first `(' is returned.
Normally used in conjunction with `erlang-beginning-of-clause', e.g.:
(save-excursion
(if (not (eobp)) (forward-char 1))
- (and (erlang-beginning-of-clause)
- (erlang-get-function-name t)))"
+ (and (erlang-beginning-of-clause)
+ (erlang-get-function-name t)))"
(let ((n (if arg 0 1)))
(and (looking-at (eval-when-compile
- (concat "^" erlang-atom-regexp "\\s *(")))
- (erlang-buffer-substring (match-beginning n) (match-end n)))))
+ (concat "^" erlang-atom-regexp "\\s *(")))
+ (erlang-buffer-substring (match-beginning n) (match-end n)))))
(defun erlang-get-function-arrow ()
@@ -3674,43 +3567,59 @@ Normally used in conjunction with `erlang-beginning-of-clause', e.g.:
Normally used in conjunction with `erlang-beginning-of-clause', e.g.:
(save-excursion
(if (not (eobp)) (forward-char 1))
- (and (erlang-beginning-of-clause)
- (erlang-get-function-arrow)))"
- (and
+ (and (erlang-beginning-of-clause)
+ (erlang-get-function-arrow)))"
+ (and
(save-excursion
(re-search-forward "->" (point-max) t)
(erlang-buffer-substring (- (point) 2) (+ (point) 1)))))
(defun erlang-get-function-arity ()
"Return the number of arguments of function at point, or nil."
- (and (looking-at (eval-when-compile
- (concat "^" erlang-atom-regexp "\\s *(")))
- (save-excursion
- (goto-char (match-end 0))
- (condition-case nil
- (let ((res 0)
- (cont t))
- (while cont
- (cond ((eobp)
- (setq res nil)
- (setq cont nil))
- ((looking-at "\\s *)")
- (setq cont nil))
- ((looking-at "\\s *\\($\\|%\\)")
- (forward-line 1))
- ((looking-at "\\s *<<[^>]*?>>")
- (when (zerop res)
- (setq res (+ 1 res)))
- (goto-char (match-end 0)))
- ((looking-at "\\s *,")
- (setq res (+ 1 res))
- (goto-char (match-end 0)))
- (t
- (when (zerop res)
- (setq res (+ 1 res)))
- (forward-sexp 1))))
- res)
- (error nil)))))
+ (erlang-get-arity-after-regexp (concat "^" erlang-atom-regexp "\\s *(")))
+
+(defun erlang-get-argument-list-arity ()
+ "Return the number of arguments in argument list at point, or nil.
+The point should be before the opening parenthesis of the
+argument list before calling this function."
+ (erlang-get-arity-after-regexp "\\s *("))
+
+(defun erlang-get-arity-after-regexp (regexp)
+ "Return the number of arguments in argument list after REGEXP, or nil."
+ (when (looking-at regexp)
+ (save-excursion
+ (goto-char (match-end 0))
+ (erlang-get-arity))))
+
+(defun erlang-get-arity ()
+ "Return the number of arguments in argument list at point, or nil.
+The point should be after the opening parenthesis of the argument
+list before calling this function."
+ (condition-case nil
+ (let ((res 0)
+ (cont t))
+ (while cont
+ (cond ((eobp)
+ (setq res nil)
+ (setq cont nil))
+ ((looking-at "\\s *)")
+ (setq cont nil))
+ ((looking-at "\\s *\\($\\|%\\)")
+ (forward-line 1))
+ ((looking-at "\\s *<<[^>]*?>>")
+ (when (zerop res)
+ (setq res (+ 1 res)))
+ (goto-char (match-end 0)))
+ ((looking-at "\\s *,")
+ (setq res (+ 1 res))
+ (goto-char (match-end 0)))
+ (t
+ (when (zerop res)
+ (setq res (+ 1 res)))
+ (forward-sexp 1))))
+ res)
+ (error nil)))
+
(defun erlang-get-function-name-and-arity ()
"Return the name and arity of the function at point, or nil.
@@ -3722,17 +3631,19 @@ The return value is a string of the form \"foo/1\"."
(defun erlang-get-function-arguments ()
"Return arguments of current function, or nil."
(if (not (looking-at (eval-when-compile
- (concat "^" erlang-atom-regexp "\\s *("))))
+ (concat "^" erlang-atom-regexp "\\s *("))))
nil
(save-excursion
(condition-case nil
- (let ((start (match-end 0)))
- (goto-char (- start 1))
- (forward-sexp)
- (erlang-buffer-substring start (- (point) 1)))
- (error nil)))))
+ (let ((start (match-end 0)))
+ (goto-char (- start 1))
+ (forward-sexp)
+ (erlang-buffer-substring start (- (point) 1)))
+ (error nil)))))
+;; Keeping erlang-get-function-under-point for backward compatibility.
+;; It is used by erldoc.el and maybe other code out there.
(defun erlang-get-function-under-point ()
"Return the module and function under the point, or nil.
@@ -3742,44 +3653,141 @@ list of imported functions is searched.
The following could be returned:
(\"module\" \"function\") -- Both module and function name found.
(nil \"function\") -- No module name was found.
- nil -- No function name found
+ nil -- No function name found.
+
+See also `erlang-get-identifier-at-point'."
+ (let* ((id (erlang-get-identifier-at-point))
+ (kind (erlang-id-kind id))
+ (module (erlang-id-module id))
+ (name (erlang-id-name id)))
+ (cond ((eq kind 'qualified-function)
+ (list module name))
+ (name
+ (list nil name)))))
+
+(defun erlang-get-identifier-at-point ()
+ "Return the erlang identifier at point, or nil.
+
+Should no explicit module name be present at the point, the
+list of imported functions is searched.
+
+When an identifier is found return a list with 4 elements:
+
+1. Kind - One of the symbols qualified-function, record, macro,
+module or nil.
-In the future the list may contain more elements."
+2. Module - Module name string or nil. In case of a
+qualified-function a search fails if no entries with correct
+module are found. For other kinds the module is just a
+preference. If no matching entries are found the search will be
+retried without regard to module.
+
+3. Name - String name of function, module, record or macro.
+
+4. Arity - Integer in case of functions and macros if the number
+of arguments could be found, otherwise nil."
(save-excursion
- (let ((md (match-data))
- (res nil))
+ (save-match-data
(if (eq (char-syntax (following-char)) ? )
- (skip-chars-backward " \t"))
- (skip-chars-backward "a-zA-Z0-9_:'")
- (cond ((looking-at (eval-when-compile
- (concat erlang-atom-regexp ":" erlang-atom-regexp)))
- (setq res (list
- (erlang-remove-quotes
- (erlang-buffer-substring
- (match-beginning 1) (match-end 1)))
- (erlang-remove-quotes
- (erlang-buffer-substring
- (match-beginning (1+ erlang-atom-regexp-matches))
- (match-end (1+ erlang-atom-regexp-matches)))))))
- ((looking-at erlang-atom-regexp)
- (let ((fk (erlang-remove-quotes
- (erlang-buffer-substring
- (match-beginning 0) (match-end 0))))
- (mod nil)
- (imports (erlang-get-import)))
- (while (and imports (null mod))
- (if (assoc fk (cdr (car imports)))
- (setq mod (car (car imports)))
- (setq imports (cdr imports))))
- (cond ((eq (preceding-char) ?#)
- (setq fk (concat "-record(" fk)))
- ((eq (preceding-char) ??)
- (setq fk (concat "-define(" fk)))
- ((and (null mod) (not (member fk erlang-int-bifs)))
- (setq mod (erlang-get-module))))
- (setq res (list mod fk)))))
- (store-match-data md)
- res)))
+ (skip-chars-backward " \t"))
+ (skip-chars-backward "[:word:]_:'")
+ (cond ((looking-at erlang-module-function-regexp)
+ (erlang-get-qualified-function-id-at-point))
+ ((looking-at (concat erlang-atom-regexp ":"))
+ (erlang-get-module-id-at-point))
+ ((looking-at erlang-name-regexp)
+ (erlang-get-some-other-id-at-point))))))
+
+(defun erlang-get-qualified-function-id-at-point ()
+ (let ((kind 'qualified-function)
+ (module (erlang-remove-quotes
+ (erlang-buffer-substring
+ (match-beginning 1) (match-end 1))))
+ (name (erlang-remove-quotes
+ (erlang-buffer-substring
+ (match-beginning (1+ erlang-atom-regexp-matches))
+ (match-end (1+ erlang-atom-regexp-matches)))))
+ (arity (progn
+ (goto-char (match-end 0))
+ (erlang-get-argument-list-arity))))
+ (list kind module name arity)))
+
+(defun erlang-get-module-id-at-point ()
+ (let ((kind 'module)
+ (module nil)
+ (name (erlang-remove-quotes
+ (erlang-buffer-substring (match-beginning 1)
+ (match-end 1))))
+ (arity nil))
+ (list kind module name arity)))
+
+(defun erlang-get-some-other-id-at-point ()
+ (let ((name (erlang-remove-quotes
+ (erlang-buffer-substring
+ (match-beginning 0) (match-end 0))))
+ (imports (erlang-get-import))
+ kind module arity)
+ (while (and imports (null module))
+ (if (assoc name (cdr (car imports)))
+ (setq module (car (car imports)))
+ (setq imports (cdr imports))))
+ (cond ((eq (preceding-char) ?#)
+ (setq kind 'record))
+ ((eq (preceding-char) ??)
+ (setq kind 'macro))
+ ((and (null module) (not (member name erlang-int-bifs)))
+ (setq module (erlang-get-module))))
+ (setq arity (progn
+ (goto-char (match-end 0))
+ (erlang-get-argument-list-arity)))
+ (list kind module name arity)))
+
+(defmacro erlang-with-id (slots id-string &rest body)
+ (declare (indent 2))
+ (let ((id-var (make-symbol "id")))
+ `(let* ((,id-var (erlang-id-to-list ,id-string))
+ ,@(mapcar (lambda (slot)
+ (list slot
+ (list (intern (format "erlang-id-%s" slot))
+ id-var)))
+ slots))
+ ,@body)))
+
+(defun erlang-id-to-string (id)
+ (when id
+ (erlang-with-id (kind module name arity) id
+ (format "%s%s%s%s"
+ (if kind (format "%s " kind) "")
+ (if module (format "%s:" module) "")
+ name
+ (if arity (format "/%s" arity) "")))))
+
+(defun erlang-id-to-list (id)
+ (if (listp id)
+ id
+ (save-match-data
+ (erlang-ensure-syntax-table-is-initialized)
+ (with-syntax-table erlang-mode-syntax-table
+ (let (case-fold-search)
+ (when (string-match erlang-id-regexp id)
+ (list (when (match-string 1 id)
+ (intern (match-string 1 id)))
+ (match-string 2 id)
+ (match-string 3 id)
+ (when (match-string 4 id)
+ (string-to-number (match-string 4 id))))))))))
+
+(defun erlang-id-kind (id)
+ (car (erlang-id-to-list id)))
+
+(defun erlang-id-module (id)
+ (nth 1 (erlang-id-to-list id)))
+
+(defun erlang-id-name (id)
+ (nth 2 (erlang-id-to-list id)))
+
+(defun erlang-id-arity (id)
+ (nth 3 (erlang-id-to-list id)))
;; TODO: Escape single quotes inside the string without
@@ -3788,11 +3796,11 @@ In the future the list may contain more elements."
"Return STR, possibly with quotes."
(let ((case-fold-search nil)) ; force string matching to be case sensitive
(if (and (stringp str)
- (not (string-match (eval-when-compile
- (concat "\\`" erlang-atom-regexp "\\'")) str)))
- (progn (if (fboundp 'replace-regexp-in-string)
- (setq str (replace-regexp-in-string "'" "\\'" str t t )))
- (concat "'" str "'"))
+ (not (string-match (eval-when-compile
+ (concat "\\`" erlang-atom-regexp "\\'")) str)))
+ (progn
+ (setq str (replace-regexp-in-string "'" "\\'" str t t ))
+ (concat "'" str "'"))
str)))
@@ -3800,19 +3808,19 @@ In the future the list may contain more elements."
"Return STR without quotes, if present."
(let ((md (match-data)))
(prog1
- (if (string-match "\\`'\\(.*\\)'\\'" str)
- (substring str 1 -1)
- str)
+ (if (string-match "\\`'\\(.*\\)'\\'" str)
+ (substring str 1 -1)
+ str)
(store-match-data md))))
(defun erlang-match-next-exported-function (max)
"Returns non-nil if there is an exported function in the current
buffer between point and MAX."
(block nil
- (while (and (not erlang-inhibit-exported-function-name-face)
- (erlang-match-next-function max))
- (when (erlang-last-match-exported-p)
- (return (match-data))))))
+ (while (and (not erlang-inhibit-exported-function-name-face)
+ (erlang-match-next-function max))
+ (when (erlang-last-match-exported-p)
+ (return (match-data))))))
(defun erlang-match-next-function (max)
"Searches forward in current buffer for the next erlang function,
@@ -3872,30 +3880,30 @@ is prompted.
This function is normally placed in the hook `local-write-file-hooks'."
(if erlang-check-module-name
- (let ((mn (erlang-add-quotes-if-needed
- (erlang-get-module)))
- (fn (erlang-add-quotes-if-needed
- (erlang-get-module-from-file-name (buffer-file-name)))))
- (if (and (stringp mn) (stringp fn))
- (or (string-equal mn fn)
- (if (or (eq erlang-check-module-name t)
- (y-or-n-p
- "Module does not match file name. Modify source? "))
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (point-min))
- (if (re-search-forward
- (eval-when-compile
- (concat "^-module\\s *(\\s *\\(\\("
- erlang-atom-regexp
- "\\)?\\)\\s *)\\s *\\."))
- (point-max) t)
- (progn
- (goto-char (match-beginning 1))
- (delete-region (match-beginning 1)
- (match-end 1))
- (insert fn))))))))))
+ (let ((mn (erlang-add-quotes-if-needed
+ (erlang-get-module)))
+ (fn (erlang-add-quotes-if-needed
+ (erlang-get-module-from-file-name (buffer-file-name)))))
+ (if (and (stringp mn) (stringp fn))
+ (or (string-equal mn fn)
+ (if (or (eq erlang-check-module-name t)
+ (y-or-n-p
+ "Module does not match file name. Modify source? "))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (if (re-search-forward
+ (eval-when-compile
+ (concat "^-module\\s *(\\s *\\(\\("
+ erlang-atom-regexp
+ "\\)?\\)\\s *)\\s *\\."))
+ (point-max) t)
+ (progn
+ (goto-char (match-beginning 1))
+ (delete-region (match-beginning 1)
+ (match-end 1))
+ (insert fn))))))))))
;; Must return nil since it is added to `local-write-file-hook'.
nil)
@@ -3921,13 +3929,13 @@ non-whitespace characters following the point on the current line."
(interactive "P")
(self-insert-command (prefix-numeric-value arg))
(if (or arg
- (and (listp erlang-electric-commands)
- (not (memq 'erlang-electric-semicolon
- erlang-electric-commands)))
- (erlang-in-literal)
- (not (looking-at "\\s *\\(%.*\\)?$"))
- (null (erlang-test-criteria-list
- erlang-electric-semicolon-criteria)))
+ (and (listp erlang-electric-commands)
+ (not (memq 'erlang-electric-semicolon
+ erlang-electric-commands)))
+ (erlang-in-literal)
+ (not (looking-at "\\s *\\(%.*\\)?$"))
+ (null (erlang-test-criteria-list
+ erlang-electric-semicolon-criteria)))
(setq erlang-electric-newline-inhibit nil)
(setq erlang-electric-newline-inhibit t)
(undo-boundary)
@@ -3935,20 +3943,20 @@ non-whitespace characters following the point on the current line."
(end-of-line)
(newline)
(if (condition-case nil
- (progn (erlang-indent-line) t)
- (error (if (bolp) (delete-char -1))))
- (if (not (bolp))
- (save-excursion
- (insert " ->"))
- (condition-case nil
- (progn
- (erlang-generate-new-clause)
- (if erlang-electric-semicolon-insert-blank-lines
- (save-excursion
- (beginning-of-line)
- (newline
- erlang-electric-semicolon-insert-blank-lines))))
- (error (if (bolp) (delete-char -1))))))))
+ (progn (erlang-indent-line) t)
+ (error (if (bolp) (delete-char -1))))
+ (if (not (bolp))
+ (save-excursion
+ (insert " ->"))
+ (condition-case nil
+ (progn
+ (erlang-generate-new-clause)
+ (if erlang-electric-semicolon-insert-blank-lines
+ (save-excursion
+ (beginning-of-line)
+ (newline
+ erlang-electric-semicolon-insert-blank-lines))))
+ (error (if (bolp) (delete-char -1))))))))
(defun erlang-electric-comma (&optional arg)
@@ -3964,12 +3972,12 @@ non-whitespace characters following the point on the current line."
(self-insert-command (prefix-numeric-value arg))
(if (or arg
- (and (listp erlang-electric-commands)
- (not (memq 'erlang-electric-comma erlang-electric-commands)))
- (erlang-in-literal)
- (not (looking-at "\\s *\\(%.*\\)?$"))
- (null (erlang-test-criteria-list
- erlang-electric-comma-criteria)))
+ (and (listp erlang-electric-commands)
+ (not (memq 'erlang-electric-comma erlang-electric-commands)))
+ (erlang-in-literal)
+ (not (looking-at "\\s *\\(%.*\\)?$"))
+ (null (erlang-test-criteria-list
+ erlang-electric-comma-criteria)))
(setq erlang-electric-newline-inhibit nil)
(setq erlang-electric-newline-inhibit t)
(undo-boundary)
@@ -3977,12 +3985,12 @@ non-whitespace characters following the point on the current line."
(end-of-line)
(newline)
(condition-case nil
- (erlang-indent-line)
+ (erlang-indent-line)
(error (if (bolp) (delete-char -1))))))
(defun erlang-electric-lt (&optional arg)
"Insert a less-than sign, and optionally mark it as an open paren."
-
+
(interactive "p")
(self-insert-command arg)
@@ -3992,48 +4000,48 @@ non-whitespace characters following the point on the current line."
(save-excursion
(backward-char 2)
(when (and (eq (char-after (point)) ?<)
- (not (eq (get-text-property (point) 'category)
- 'bitsyntax-open-inner)))
- ;; Then mark the two chars...
- (put-text-property (point) (1+ (point))
- 'category 'bitsyntax-open-outer)
- (forward-char 1)
- (put-text-property (point) (1+ (point))
- 'category 'bitsyntax-open-inner)
- ;;...and unmark any subsequent less-than chars.
- (forward-char 1)
- (while (eq (char-after (point)) ?<)
- (remove-text-properties (point) (1+ (point))
- '(category nil))
- (forward-char 1))))))
+ (not (eq (get-text-property (point) 'category)
+ 'bitsyntax-open-inner)))
+ ;; Then mark the two chars...
+ (put-text-property (point) (1+ (point))
+ 'category 'bitsyntax-open-outer)
+ (forward-char 1)
+ (put-text-property (point) (1+ (point))
+ 'category 'bitsyntax-open-inner)
+ ;;...and unmark any subsequent less-than chars.
+ (forward-char 1)
+ (while (eq (char-after (point)) ?<)
+ (remove-text-properties (point) (1+ (point))
+ '(category nil))
+ (forward-char 1))))))
(defun erlang-after-bitsyntax-close ()
"Return t if point is immediately after a bit-syntax close parenthesis (`>>')."
(and (>= (point) 3)
(save-excursion
- (backward-char 2)
- (and (eq (char-after (point)) ?>)
- (not (eq (get-text-property (point) 'category)
- 'bitsyntax-close-outer))))))
-
+ (backward-char 2)
+ (and (eq (char-after (point)) ?>)
+ (not (eq (get-text-property (point) 'category)
+ 'bitsyntax-close-outer))))))
+
(defun erlang-after-arrow ()
"Return true if point is immediately after a function arrow (`->')."
(and (>= (point) 2)
- (and
- (save-excursion
- (backward-char)
- (eq (char-before (point)) ?-))
- (or (not (listp erlang-electric-commands))
- (memq 'erlang-electric-gt
- erlang-electric-commands))
- (not (erlang-in-literal))
- (looking-at "\\s *\\(%.*\\)?$")
- (erlang-test-criteria-list erlang-electric-arrow-criteria))))
+ (and
+ (save-excursion
+ (backward-char)
+ (eq (char-before (point)) ?-))
+ (or (not (listp erlang-electric-commands))
+ (memq 'erlang-electric-gt
+ erlang-electric-commands))
+ (not (erlang-in-literal))
+ (looking-at "\\s *\\(%.*\\)?$")
+ (erlang-test-criteria-list erlang-electric-arrow-criteria))))
(defun erlang-electric-gt (&optional arg)
"Insert a greater-than sign, and optionally mark it as a close paren."
-
+
(interactive "p")
(self-insert-command arg)
@@ -4044,17 +4052,17 @@ non-whitespace characters following the point on the current line."
(save-excursion
;; Then mark the two chars...
(backward-char 2)
- (put-text-property (point) (1+ (point))
- 'category 'bitsyntax-close-inner)
+ (put-text-property (point) (1+ (point))
+ 'category 'bitsyntax-close-inner)
(forward-char)
(put-text-property (point) (1+ (point))
- 'category 'bitsyntax-close-outer)
+ 'category 'bitsyntax-close-outer)
;;...and unmark any subsequent greater-than chars.
(forward-char)
(while (eq (char-after (point)) ?>)
- (remove-text-properties (point) (1+ (point))
- '(category nil))
- (forward-char))))
+ (remove-text-properties (point) (1+ (point))
+ '(category nil))
+ (forward-char))))
;; Did we just write a function arrow (`->')?
((erlang-after-arrow)
@@ -4063,15 +4071,15 @@ non-whitespace characters following the point on the current line."
(end-of-line)
(newline)
(condition-case nil
- (erlang-indent-line)
- (error (if (bolp) (delete-char -1))))))
+ (erlang-indent-line)
+ (error (if (bolp) (delete-char -1))))))
;; Then it's just a plain greater-than.
(t
nil)))
-
-(defun erlang-electric-arrow\ off (&optional arg)
+
+(defun erlang-electric-arrow (&optional arg)
"Insert a '>'-sign and possibly a new indented line.
This command is only `electric' when the `>' is part of an `->' arrow.
@@ -4089,22 +4097,22 @@ After being split/merged into `erlang-after-arrow' and
(let ((prec (preceding-char)))
(self-insert-command (prefix-numeric-value arg))
(if (or arg
- (and (listp erlang-electric-commands)
- (not (memq 'erlang-electric-arrow
- erlang-electric-commands)))
- (not (eq prec ?-))
- (erlang-in-literal)
- (not (looking-at "\\s *\\(%.*\\)?$"))
- (null (erlang-test-criteria-list
- erlang-electric-arrow-criteria)))
- (setq erlang-electric-newline-inhibit nil)
+ (and (listp erlang-electric-commands)
+ (not (memq 'erlang-electric-arrow
+ erlang-electric-commands)))
+ (not (eq prec ?-))
+ (erlang-in-literal)
+ (not (looking-at "\\s *\\(%.*\\)?$"))
+ (null (erlang-test-criteria-list
+ erlang-electric-arrow-criteria)))
+ (setq erlang-electric-newline-inhibit nil)
(setq erlang-electric-newline-inhibit t)
(undo-boundary)
(end-of-line)
(newline)
(condition-case nil
- (erlang-indent-line)
- (error (if (bolp) (delete-char -1)))))))
+ (erlang-indent-line)
+ (error (if (bolp) (delete-char -1)))))))
(defun erlang-electric-newline (&optional arg)
@@ -4119,30 +4127,30 @@ Should the previous command be another electric command we assume that
the user pressed newline out of old habit, hence we will do nothing."
(interactive "P")
(cond ((and (not arg)
- erlang-electric-newline-inhibit
- (memq last-command erlang-electric-newline-inhibit-list))
- ()) ; Do nothing!
- ((or arg
- (and (listp erlang-electric-commands)
- (not (memq 'erlang-electric-newline
- erlang-electric-commands)))
- (null (erlang-test-criteria-list
- erlang-electric-newline-criteria)))
- (newline (prefix-numeric-value arg)))
- (t
- (if (and comment-multi-line
- (save-excursion
- (beginning-of-line)
- (looking-at (concat "\\s *" comment-start-skip))))
- (let ((str (buffer-substring
- (or (match-end 1) (match-beginning 0))
- (min (match-end 0) (point)))))
- (newline)
- (undo-boundary)
- (insert str))
- (newline)
- (undo-boundary)
- (indent-according-to-mode)))))
+ erlang-electric-newline-inhibit
+ (memq last-command erlang-electric-newline-inhibit-list))
+ ()) ; Do nothing!
+ ((or arg
+ (and (listp erlang-electric-commands)
+ (not (memq 'erlang-electric-newline
+ erlang-electric-commands)))
+ (null (erlang-test-criteria-list
+ erlang-electric-newline-criteria)))
+ (newline (prefix-numeric-value arg)))
+ (t
+ (if (and comment-multi-line
+ (save-excursion
+ (beginning-of-line)
+ (looking-at (concat "\\s *" comment-start-skip))))
+ (let ((str (buffer-substring
+ (or (match-end 1) (match-beginning 0))
+ (min (match-end 0) (point)))))
+ (newline)
+ (undo-boundary)
+ (insert str))
+ (newline)
+ (undo-boundary)
+ (indent-according-to-mode)))))
(defun erlang-test-criteria-list (criteria)
@@ -4167,14 +4175,14 @@ Return t if criteria fulfilled, nil otherwise."
t
(save-excursion
(let ((answer nil))
- (while (and criteria (null answer))
- (if (eq (car criteria) t)
- (setq answer t)
- (setq answer (funcall (car criteria))))
- (setq criteria (cdr criteria)))
- (if (and answer (not (eq answer 'stop)))
- t
- nil)))))
+ (while (and criteria (null answer))
+ (if (eq (car criteria) t)
+ (setq answer t)
+ (setq answer (funcall (car criteria))))
+ (setq criteria (cdr criteria)))
+ (if (and answer (not (eq answer 'stop)))
+ t
+ nil)))))
(defun erlang-in-literal (&optional lim)
@@ -4185,11 +4193,9 @@ Should the point be inside none of the above mentioned types of
context, nil is returned."
(save-excursion
(let* ((lim (or lim (save-excursion
- (erlang-beginning-of-clause)
- (point))))
- (state (if (fboundp 'syntax-ppss) ; post Emacs 21.3
- (funcall (symbol-function 'syntax-ppss))
- (parse-partial-sexp lim (point)))))
+ (erlang-beginning-of-clause)
+ (point))))
+ (state (funcall (symbol-function 'syntax-ppss))))
(cond
((eq (nth 3 state) ?') 'atom)
((nth 3 state) 'string)
@@ -4203,7 +4209,7 @@ context, nil is returned."
This function is designed to be a member of a criteria list."
(eq (save-excursion (erlang-skip-blank) (point))
(save-excursion
- (erlang-beginning-of-function -1) (point))))
+ (erlang-beginning-of-function -1) (point))))
(defun erlang-at-end-of-clause-p ()
@@ -4212,7 +4218,7 @@ This function is designed to be a member of a criteria list."
This function is designed to be a member of a criteria list."
(eq (save-excursion (erlang-skip-blank) (point))
(save-excursion
- (erlang-beginning-of-clause -1) (point))))
+ (erlang-beginning-of-clause -1) (point))))
(defun erlang-stop-when-inside-argument-list ()
@@ -4224,22 +4230,22 @@ after `||', `stop' is not returned.
This function is designed to be a member of a criteria list."
(save-excursion
(condition-case nil
- (let ((orig-point (point))
- (state nil))
- (up-list -1)
- (if (not (eq (following-char) ?\[))
- 'stop
- ;; Do not return `stop' when inside a list comprehension
- ;; construction. (The point must be after `||').
- (while (< (point) orig-point)
+ (let ((orig-point (point))
+ (state nil))
+ (up-list -1)
+ (if (not (eq (following-char) ?\[))
+ 'stop
+ ;; Do not return `stop' when inside a list comprehension
+ ;; construction. (The point must be after `||').
+ (while (< (point) orig-point)
(let ((pt (point)))
(setq state (erlang-partial-parse pt orig-point state))
(if (= pt (point))
(error "Illegal syntax"))))
- (if (and (car state) (eq (car (car (car state))) '||))
- nil
- 'stop)))
- (error
+ (if (and (car state) (eq (car (car (car state))) '||))
+ nil
+ 'stop)))
+ (error
nil))))
@@ -4250,11 +4256,11 @@ This function is designed to be a member of a criteria list."
(save-excursion
(beginning-of-line)
(if (and (looking-at (eval-when-compile
- (concat "^" erlang-atom-regexp "\\s *(")))
- (not (looking-at
- (eval-when-compile
- (concat "^" erlang-atom-regexp ".*->")))))
- 'stop
+ (concat "^" erlang-atom-regexp "\\s *(")))
+ (not (looking-at
+ (eval-when-compile
+ (concat "^" erlang-atom-regexp ".*->")))))
+ 'stop
nil)))
@@ -4279,13 +4285,13 @@ A line containing only spaces and tabs is considered empty.
This function is designed to be a member of a criteria list."
(and erlang-next-lines-empty-threshold
(save-excursion
- (let ((left erlang-next-lines-empty-threshold)
- (cont t))
- (while (and cont (> left 0))
- (forward-line 1)
- (setq cont (looking-at "\\s *$"))
- (setq left (- left 1)))
- cont))))
+ (let ((left erlang-next-lines-empty-threshold)
+ (cont t))
+ (while (and cont (> left 0))
+ (forward-line 1)
+ (setq cont (looking-at "\\s *$"))
+ (setq left (- left 1)))
+ cont))))
(defun erlang-at-keyword-end-p ()
@@ -4297,16 +4303,10 @@ This function is designed to be a member of a criteria list."
(looking-at "end[^_a-zA-Z0-9]")))
-;; Erlang tags support which is aware of erlang modules.
-;;
-;; Not yet implemented under XEmacs. (Hint: The Emacs 19 etags
-;; package works under XEmacs.)
+;;; Erlang tags support which is aware of erlang modules.
(eval-when-compile
- (if (or (featurep 'bytecomp)
- (featurep 'byte-compile))
- (progn
- (require 'etags))))
+ (require 'etags))
;; Variables:
@@ -4350,28 +4350,16 @@ After calling this function, the tags functions are aware of
Erlang modules. Tags can be entered on the for `module:tag' as well
as on the old form `tag'.
-In the completion list, `module:tag' and `module:' shows up.
-
-Call this function from an appropriate init file, or add it to
-Erlang mode hook with the commands:
- (add-hook 'erlang-mode-hook 'erlang-tags-init)
- (add-hook 'erlang-shell-mode-hook 'erlang-tags-init)
-
-This function only works under Emacs 18 and Emacs 19. Currently, It
-is not implemented under XEmacs. (Hint: The Emacs 19 etags module
-works under XEmacs.)"
+In the completion list, `module:tag' and `module:' shows up."
(interactive)
- (cond ((= erlang-emacs-major-version 18)
- (require 'tags)
- (erlang-tags-define-keys (current-local-map))
- (setq erlang-tags-installed t))
- (t
- (require 'etags)
- ;; Test on a function available in the Emacs 19 version
- ;; of tags but not in the XEmacs version.
- (when (fboundp 'find-tag-noselect)
- (erlang-tags-define-keys (current-local-map))
- (setq erlang-tags-installed t)))))
+ (require 'etags)
+ (set (make-local-variable 'find-tag-default-function)
+ 'erlang-find-tag-for-completion)
+ (if (>= emacs-major-version 25)
+ (add-hook 'xref-backend-functions
+ #'erlang-etags--xref-backend nil t)
+ (erlang-tags-define-keys (current-local-map))
+ (setq erlang-tags-installed t)))
@@ -4386,30 +4374,16 @@ works under XEmacs.)"
(let ((alist erlang-tags-function-alist))
(while alist
(let* ((old (car (car alist)))
- (new (cdr (car alist)))
- (keys (append (where-is-internal old global-map))))
- (while keys
- (define-key map (car keys) new)
- (setq keys (cdr keys))))
+ (new (cdr (car alist)))
+ (keys (append (where-is-internal old global-map))))
+ (while keys
+ (define-key map (car keys) new)
+ (setq keys (cdr keys))))
(setq alist (cdr alist))))
;; Update the menu.
(erlang-menu-substitute erlang-menu-base-items erlang-tags-function-alist)
(erlang-menu-init))
-
-(defun erlang-find-tag-default ()
- "Return the default tag.
-Search `-import' list of imported functions.
-Single quotes are been stripped away."
- (let ((mod-func (erlang-get-function-under-point)))
- (cond ((null mod-func)
- nil)
- ((null (car mod-func))
- (nth 1 mod-func))
- (t
- (concat (car mod-func) ":" (nth 1 mod-func))))))
-
-
;; Return `t' since it is used inside `tags-loop-form'.
;;;###autoload
(defun erlang-find-tag (modtagname &optional next-p regexp-p)
@@ -4426,31 +4400,31 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(defun erlang-find-tag-other-window (tagname &optional next-p regexp-p)
"Like `find-tag-other-window' but aware of Erlang modules."
(interactive (erlang-tag-interactive
- "Find `module:tag' or `tag' other window: "))
+ "Find `module:tag' or `tag' other window: "))
;; This is to deal with the case where the tag is found in the
;; selected window's buffer; without this, point is moved in both
;; windows. To prevent this, we save the selected window's point
;; before doing find-tag-noselect, and restore it afterwards.
(let* ((window-point (window-point (selected-window)))
- (tagbuf (erlang-find-tag-noselect tagname next-p regexp-p))
- (tagpoint (progn (set-buffer tagbuf) (point))))
+ (tagbuf (erlang-find-tag-noselect tagname next-p regexp-p))
+ (tagpoint (progn (set-buffer tagbuf) (point))))
(set-window-point (prog1
- (selected-window)
- (switch-to-buffer-other-window tagbuf)
- ;; We have to set this new window's point; it
- ;; might already have been displaying a
- ;; different portion of tagbuf, in which case
- ;; switch-to-buffer-other-window doesn't set
- ;; the window's point from the buffer.
- (set-window-point (selected-window) tagpoint))
- window-point)))
+ (selected-window)
+ (switch-to-buffer-other-window tagbuf)
+ ;; We have to set this new window's point; it
+ ;; might already have been displaying a
+ ;; different portion of tagbuf, in which case
+ ;; switch-to-buffer-other-window doesn't set
+ ;; the window's point from the buffer.
+ (set-window-point (selected-window) tagpoint))
+ window-point)))
(defun erlang-find-tag-other-frame (tagname &optional next-p)
"Like `find-tag-other-frame' but aware of Erlang modules."
(interactive (erlang-tag-interactive
- "Find `module:tag' or `tag' other frame: "))
+ "Find `module:tag' or `tag' other frame: "))
(let ((pop-up-frames t))
(erlang-find-tag-other-window tagname next-p)))
@@ -4458,13 +4432,13 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(defun erlang-find-tag-regexp (regexp &optional next-p other-window)
"Like `find-tag-regexp' but aware of Erlang modules."
(interactive (if (fboundp 'find-tag-regexp)
- (erlang-tag-interactive
- "Find `module:regexp' or `regexp': ")
- (error "This version of Emacs can't find tags by regexps")))
+ (erlang-tag-interactive
+ "Find `module:regexp' or `regexp': ")
+ (error "This version of Emacs can't find tags by regexps")))
(funcall (if other-window
- 'erlang-find-tag-other-window
- 'erlang-find-tag)
- regexp next-p t))
+ 'erlang-find-tag-other-window
+ 'erlang-find-tag)
+ regexp next-p t))
;; Just like C-u M-. This could be added to the menu.
@@ -4473,7 +4447,7 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(interactive)
(let ((current-prefix-arg '(4)))
(if erlang-tags-installed
- (call-interactively 'erlang-find-tag)
+ (call-interactively 'erlang-find-tag)
(call-interactively 'find-tag))))
@@ -4485,9 +4459,9 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
;; without extension and directory matches the module.
;;
;; * `module:tag'
-;; Emacs 19: Replace test functions with functions aware of
-;; Erlang modules. Tricky because the etags system wasn't
-;; built for these kind of operations...
+;; Emacs 19: Replace test functions with functions aware of
+;; Erlang modules. Tricky because the etags system wasn't
+;; built for these kind of operations...
;;
;; Emacs 18: We loop over `find-tag' until we find a file
;; whose module matches the requested module. The
@@ -4506,78 +4480,54 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
;; know where to restart a tags command.
(if (boundp 'tags-loop-form)
(funcall (symbol-function 'set)
- 'tags-loop-form '(erlang-find-tag nil t)))
+ 'tags-loop-form '(erlang-find-tag nil t)))
(save-window-excursion
(cond
((string-match ":$" modtagname)
;; Only the module name was given. Read all files whose file name
;; match.
(let ((modname (substring modtagname 0 (match-beginning 0)))
- (file nil))
- (if (not next-p)
- (save-excursion
- (visit-tags-table-buffer)
- (setq erlang-tags-file-list
- (funcall (symbol-function 'tags-table-files)))))
- (while (null file)
- (or erlang-tags-file-list
- (save-excursion
- (if (and (featurep 'etags)
- (funcall
- (symbol-function 'visit-tags-table-buffer) 'same)
- (funcall
- (symbol-function 'visit-tags-table-buffer) t))
- (setq erlang-tags-file-list
- (funcall (symbol-function 'tags-table-files)))
- (error "No %stags containing %s" (if next-p "more " "")
- modtagname))))
- (if erlang-tags-file-list
- (let ((this-module (erlang-get-module-from-file-name
- (car erlang-tags-file-list))))
- (if (and (stringp this-module)
- (string= modname this-module))
- (setq file (car erlang-tags-file-list)))
- (setq erlang-tags-file-list (cdr erlang-tags-file-list)))))
- (set-buffer (or (get-file-buffer file)
- (find-file-noselect file)))))
+ (file nil))
+ (if (not next-p)
+ (save-excursion
+ (visit-tags-table-buffer)
+ (setq erlang-tags-file-list
+ (funcall (symbol-function 'tags-table-files)))))
+ (while (null file)
+ (or erlang-tags-file-list
+ (save-excursion
+ (if (and (funcall
+ (symbol-function 'visit-tags-table-buffer) 'same)
+ (funcall
+ (symbol-function 'visit-tags-table-buffer) t))
+ (setq erlang-tags-file-list
+ (funcall (symbol-function 'tags-table-files)))
+ (error "No %stags containing %s" (if next-p "more " "")
+ modtagname))))
+ (if erlang-tags-file-list
+ (let ((this-module (erlang-get-module-from-file-name
+ (car erlang-tags-file-list))))
+ (if (and (stringp this-module)
+ (string= modname this-module))
+ (setq file (car erlang-tags-file-list)))
+ (setq erlang-tags-file-list (cdr erlang-tags-file-list)))))
+ (set-buffer (or (get-file-buffer file)
+ (find-file-noselect file)))))
((string-match ":" modtagname)
- (if (boundp 'find-tag-tag-order)
- ;; Method one: Add module-recognising functions to the
- ;; list of order functions. However, the tags system
- ;; from Emacs 18, and derives thereof (read: XEmacs)
- ;; hasn't got this feature.
- (progn
- (erlang-tags-install-module-check)
- (unwind-protect
- (funcall (symbol-function 'find-tag)
- modtagname next-p regexp-p)
- (erlang-tags-remove-module-check)))
- ;; Method two: Call the tags system until a file matching
- ;; the module is found. This could result in that many
- ;; files are read. (e.g. The tag "foo:file" will take a
- ;; while to process.)
- (let* ((modname (substring modtagname 0 (match-beginning 0)))
- (tagname (substring modtagname (match-end 0) nil))
- (last-tag tagname)
- file)
- (while
- (progn
- (funcall (symbol-function 'find-tag) tagname next-p regexp-p)
- (setq next-p t)
- ;; Determine the module form the file name. (The
- ;; alternative, to check `-module', would make this
- ;; code useless for non-Erlang programs.)
- (setq file (erlang-get-module-from-file-name buffer-file-name))
- (not (and (stringp file)
- (string= modname file))))))))
+ (progn
+ (erlang-tags-install-module-check)
+ (unwind-protect
+ (funcall (symbol-function 'find-tag)
+ modtagname next-p regexp-p)
+ (erlang-tags-remove-module-check))))
(t
(funcall (symbol-function 'find-tag) modtagname next-p regexp-p)))
- (current-buffer))) ; Return the new buffer.
+ (current-buffer))) ; Return the new buffer.
+
-
@@ -4594,18 +4544,16 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(require 'tags)))
(if current-prefix-arg
(list nil (if (< (prefix-numeric-value current-prefix-arg) 0)
- '-
- t))
- (let* ((default (erlang-find-tag-default))
- (prompt (if default
- (format "%s(default %s) " prompt default)
- prompt))
- (spec (if (featurep 'etags)
- (completing-read prompt 'erlang-tags-complete-tag)
- (read-string prompt))))
+ '-
+ t))
+ (let* ((default (erlang-default-function-or-module))
+ (prompt (if default
+ (format "%s(default %s) " prompt default)
+ prompt))
+ (spec (completing-read prompt 'erlang-tags-complete-tag)))
(list (if (equal spec "")
- (or default (error "There is no default tag"))
- spec)))))
+ (or default (error "There is no default tag"))
+ spec)))))
;; Search tag functions which are aware of Erlang modules. The tactic
@@ -4619,34 +4567,23 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
"Install our own tag search functions."
;; Make sure our functions are installed in TAGS files loaded
;; into Emacs while searching.
- (cond
- ((>= erlang-emacs-major-version 20)
- (setq erlang-tags-orig-format-functions
- (symbol-value 'tags-table-format-functions))
- (funcall (symbol-function 'set) 'tags-table-format-functions
- (cons 'erlang-tags-recognize-tags-table
- erlang-tags-orig-format-functions))
- (setq erlang-tags-buffer-list '())
- )
- (t
- (setq erlang-tags-orig-format-hooks
- (symbol-value 'tags-table-format-hooks))
- (funcall (symbol-function 'set) 'tags-table-format-hooks
- (cons 'erlang-tags-recognize-tags-table
- erlang-tags-orig-format-hooks))
- (setq erlang-tags-buffer-list '())
- ))
-
+ (setq erlang-tags-orig-format-functions
+ (symbol-value 'tags-table-format-functions))
+ (funcall (symbol-function 'set) 'tags-table-format-functions
+ (cons 'erlang-tags-recognize-tags-table
+ erlang-tags-orig-format-functions))
+ (setq erlang-tags-buffer-list '())
+
;; Install our functions in the TAGS files already resident.
(save-excursion
(let ((files (symbol-value 'tags-table-computed-list)))
(while files
- (if (stringp (car files))
- (if (get-file-buffer (car files))
- (progn
- (set-buffer (get-file-buffer (car files)))
- (erlang-tags-install-local))))
- (setq files (cdr files))))))
+ (if (stringp (car files))
+ (if (get-file-buffer (car files))
+ (progn
+ (set-buffer (get-file-buffer (car files)))
+ (erlang-tags-install-local))))
+ (setq files (cdr files))))))
(defun erlang-tags-install-local ()
@@ -4656,23 +4593,23 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
;; Mark this buffer as "installed" and record.
(set (make-local-variable 'erlang-tags-buffer-installed-p) t)
(setq erlang-tags-buffer-list
- (cons (current-buffer) erlang-tags-buffer-list))
+ (cons (current-buffer) erlang-tags-buffer-list))
;; Save the original values.
(set (make-local-variable 'erlang-tags-orig-tag-order)
- (symbol-value 'find-tag-tag-order))
+ (symbol-value 'find-tag-tag-order))
(set (make-local-variable 'erlang-tags-orig-regexp-tag-order)
- (symbol-value 'find-tag-regexp-tag-order))
+ (symbol-value 'find-tag-regexp-tag-order))
(set (make-local-variable 'erlang-tags-orig-search-function)
- (symbol-value 'find-tag-search-function))
+ (symbol-value 'find-tag-search-function))
(set (make-local-variable 'erlang-tags-orig-regexp-search-function)
- (symbol-value 'find-tag-regexp-search-function))
+ (symbol-value 'find-tag-regexp-search-function))
;; Install our own functions.
(set (make-local-variable 'find-tag-search-function)
- 'erlang-tags-search-forward)
+ 'erlang-tags-search-forward)
(set (make-local-variable 'find-tag-regexp-search-function)
- 'erlang-tags-regexp-search-forward)
+ 'erlang-tags-regexp-search-forward)
(set (make-local-variable 'find-tag-tag-order)
(mapcar #'erlang-make-order-function-aware-of-modules
erlang-tags-orig-tag-order))
@@ -4697,17 +4634,9 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(defun erlang-tags-remove-module-check ()
"Remove our own tags search functions."
- (cond
- ((>= erlang-emacs-major-version 20)
- (funcall (symbol-function 'set)
- 'tags-table-format-functions
- erlang-tags-orig-format-functions)
- )
- (t
- (funcall (symbol-function 'set)
- 'tags-table-format-hooks
- erlang-tags-orig-format-hooks)
- ))
+ (funcall (symbol-function 'set)
+ 'tags-table-format-functions
+ erlang-tags-orig-format-functions)
;; Remove our functions from the TAGS files. (Note that
;; `tags-table-computed-list' need not be the same list as when
@@ -4715,11 +4644,11 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(save-excursion
(let ((buffers erlang-tags-buffer-list))
(while buffers
- (if (buffer-name (car buffers))
- (progn
- (set-buffer (car buffers))
- (erlang-tags-remove-local)))
- (setq buffers (cdr buffers))))))
+ (if (buffer-name (car buffers))
+ (progn
+ (set-buffer (car buffers))
+ (erlang-tags-remove-local)))
+ (setq buffers (cdr buffers))))))
(defun erlang-tags-remove-local ()
@@ -4728,14 +4657,14 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
()
(funcall (symbol-function 'set) 'erlang-tags-buffer-installed-p nil)
(funcall (symbol-function 'set)
- 'find-tag-tag-order erlang-tags-orig-tag-order)
+ 'find-tag-tag-order erlang-tags-orig-tag-order)
(funcall (symbol-function 'set)
- 'find-tag-regexp-tag-order erlang-tags-orig-regexp-tag-order)
+ 'find-tag-regexp-tag-order erlang-tags-orig-regexp-tag-order)
(funcall (symbol-function 'set)
- 'find-tag-search-function erlang-tags-orig-search-function)
+ 'find-tag-search-function erlang-tags-orig-search-function)
(funcall (symbol-function 'set)
- 'find-tag-regexp-search-function
- erlang-tags-orig-regexp-search-function)))
+ 'find-tag-regexp-search-function
+ erlang-tags-orig-regexp-search-function)))
(defun erlang-tags-recognize-tags-table ()
@@ -4764,10 +4693,10 @@ for a tag on the form `module:tag'."
(if (string-match ":" tag)
(setq tag (substring tag (match-end 0) nil)))
(if (eq erlang-tags-orig-regexp-search-function
- 'erlang-tags-regexp-search-forward)
+ 'erlang-tags-regexp-search-forward)
(re-search-forward tag bound noerror count)
(funcall erlang-tags-orig-regexp-search-function
- tag bound noerror count)))
+ tag bound noerror count)))
;;; Tags completion, Emacs 19 `etags' specific.
;;;
@@ -4775,27 +4704,24 @@ for a tag on the form `module:tag'."
;;; completion-table' containing all normal tags plus tags on the form
;;; `module:tag' and `module:'.
-;; PENDING - Should probably make use of the
-;; `completion-at-point-functions' hook instead of this advice.
-(when (and (locate-library "etags")
- (require 'etags)
- (fboundp 'etags-tags-completion-table)
- (fboundp 'tags-lazy-completion-table)) ; Emacs 23.1+
- (if (fboundp 'advice-add)
- ;; Emacs 24.4+
+(if (fboundp 'advice-add)
+ ;; Emacs 24.4+
+ (progn
+ (require 'etags)
(advice-add 'etags-tags-completion-table :around
- (lambda (oldfun)
- (if erlang-replace-etags-tags-completion-table
- (erlang-etags-tags-completion-table)
- (funcall oldfun)))
- (list :name 'erlang-replace-tags-table))
- ;; Emacs 23.1-24.3
- (defadvice etags-tags-completion-table (around
- erlang-replace-tags-table
- activate)
- (if erlang-replace-etags-tags-completion-table
- (setq ad-return-value (erlang-etags-tags-completion-table))
- ad-do-it))))
+ #'erlang-etags-tags-completion-table-advice))
+ ;; Emacs 23.1-24.3
+ (defadvice etags-tags-completion-table (around
+ erlang-replace-tags-table
+ activate)
+ (if erlang-replace-etags-tags-completion-table
+ (setq ad-return-value (erlang-etags-tags-completion-table))
+ ad-do-it)))
+
+(defun erlang-etags-tags-completion-table-advice (oldfun)
+ (if erlang-replace-etags-tags-completion-table
+ (erlang-etags-tags-completion-table)
+ (funcall oldfun)))
(defun erlang-complete-tag ()
"Perform tags completion on the text around point.
@@ -4804,29 +4730,9 @@ Completes to the set of names listed in the current tags table.
Should the Erlang tags system be installed this command knows
about Erlang modules."
(interactive)
- (condition-case nil
- (require 'etags)
- (error nil))
- (cond ((and erlang-tags-installed
- (fboundp 'etags-tags-completion-table)
- (fboundp 'tags-lazy-completion-table)) ; Emacs 23.1+
- (let ((erlang-replace-etags-tags-completion-table t))
- (complete-tag)))
- ((and erlang-tags-installed
- (fboundp 'complete-tag)
- (fboundp 'tags-complete-tag)) ; Emacs 19-22
- (let ((orig-tags-complete-tag (symbol-function 'tags-complete-tag)))
- (fset 'tags-complete-tag
- (symbol-function 'erlang-tags-complete-tag))
- (unwind-protect
- (complete-tag)
- (fset 'tags-complete-tag orig-tags-complete-tag))))
- ((fboundp 'complete-tag) ; Emacs 19
- (complete-tag))
- ((fboundp 'tag-complete-symbol) ; XEmacs
- (funcall (symbol-function 'tag-complete-symbol)))
- (t
- (error "This version of Emacs can't complete tags"))))
+ (require 'etags)
+ (let ((erlang-replace-etags-tags-completion-table t))
+ (complete-tag)))
(defun erlang-find-tag-for-completion ()
@@ -4850,9 +4756,9 @@ about Erlang modules."
;; If we need to ask for the tag table, allow that.
(let ((enable-recursive-minibuffers t))
(visit-tags-table-buffer))
- (if (eq what t)
- (all-completions string (erlang-tags-completion-table) predicate)
- (try-completion string (erlang-tags-completion-table) predicate)))))
+ (if (eq what t)
+ (all-completions string (erlang-tags-completion-table) predicate)
+ (try-completion string (erlang-tags-completion-table) predicate)))))
;; `tags-completion-table' calls itself recursively, make it
@@ -4862,22 +4768,22 @@ about Erlang modules."
(defun erlang-tags-completion-table ()
"Build completion table. Tags on the form `tag' or `module:tag'."
(setq erlang-tags-orig-completion-table
- (symbol-function 'tags-completion-table))
+ (symbol-function 'tags-completion-table))
(fset 'tags-completion-table
- (symbol-function 'erlang-tags-completion-table-1))
+ (symbol-function 'erlang-tags-completion-table-1))
(unwind-protect
(erlang-tags-completion-table-1)
(fset 'tags-completion-table
- erlang-tags-orig-completion-table)))
+ erlang-tags-orig-completion-table)))
(defun erlang-tags-completion-table-1 ()
(make-local-variable 'erlang-tags-completion-table)
(or erlang-tags-completion-table
(let ((tags-completion-table nil)
- (tags-completion-table-function
- 'erlang-etags-tags-completion-table))
- (funcall erlang-tags-orig-completion-table)
- (setq erlang-tags-completion-table tags-completion-table))))
+ (tags-completion-table-function
+ 'erlang-etags-tags-completion-table))
+ (funcall erlang-tags-orig-completion-table)
+ (setq erlang-tags-completion-table tags-completion-table))))
@@ -4950,6 +4856,14 @@ about Erlang modules."
;; It adds awareness of the module:tag syntax in a similar way that is
;; done above for the old etags commands.
+(defvar erlang-current-arity nil
+ "The arity of the function currently being searched.
+
+There is no information about arity in the TAGS file.
+Consecutive functions with same name but different arity will
+only get one entry in the TAGS file. Matching TAGS entries are
+therefore selected without regarding arity. The arity is
+considered first when it is time to jump to the definition.")
(defun erlang-etags--xref-backend () 'erlang-etags)
@@ -4959,13 +4873,15 @@ about Erlang modules."
(and (erlang-soft-require 'xref)
(erlang-soft-require 'cl-generic)
+ (erlang-soft-require 'eieio)
+ (erlang-soft-require 'etags)
;; The purpose of using eval here is to avoid compilation
- ;; warnings in emacsen without cl-defmethod.
+ ;; warnings in emacsen without cl-defmethod etc.
(eval
'(progn
(cl-defmethod xref-backend-identifier-at-point
((_backend (eql erlang-etags)))
- (erlang-find-tag-default))
+ (erlang-id-to-string (erlang-get-identifier-at-point)))
(cl-defmethod xref-backend-definitions
((_backend (eql erlang-etags)) identifier)
@@ -4978,42 +4894,99 @@ about Erlang modules."
(cl-defmethod xref-backend-identifier-completion-table
((_backend (eql erlang-etags)))
(let ((erlang-replace-etags-tags-completion-table t))
- (tags-completion-table))))))
-
-
+ (tags-completion-table)))
+
+ (defclass erlang-xref-location (xref-etags-location) ())
+
+ (defun erlang-convert-xrefs (xrefs)
+ (mapcar (lambda (xref)
+ (oset xref location (erlang-make-location
+ (oref xref location)))
+ xref)
+ xrefs))
+
+ (defun erlang-make-location (etags-location)
+ (with-slots (tag-info file) etags-location
+ (make-instance 'erlang-xref-location :tag-info tag-info
+ :file file)))
+
+ (cl-defmethod xref-location-marker ((locus erlang-xref-location))
+ (with-slots (tag-info file) locus
+ (with-current-buffer (find-file-noselect file)
+ (save-excursion
+ (or (erlang-goto-tag-location-by-arity tag-info)
+ (etags-goto-tag-location tag-info))
+ ;; Reset erlang-current-arity. We want to jump to
+ ;; correct arity in the first attempt. That is now
+ ;; done. Possible remaining jumps will be from
+ ;; entries in the *xref* buffer and then we want to
+ ;; ignore the arity. (Alternatively we could remove
+ ;; all but one xref entry per file when we know the
+ ;; arity).
+ (setq erlang-current-arity nil)
+ (point-marker)))))
+
+ (defun erlang-xref-context (xref)
+ (with-slots (tag-info) (xref-item-location xref)
+ (car tag-info))))))
+
+
+(defun erlang-goto-tag-location-by-arity (tag-info)
+ (when erlang-current-arity
+ (let* ((tag-text (car tag-info))
+ (tag-pos (cdr (cdr tag-info)))
+ (tag-line (car (cdr tag-info)))
+ (regexp (erlang-tag-info-regexp tag-text))
+ (startpos (or tag-pos
+ (when tag-line
+ (goto-char (point-min))
+ (forward-line (1- tag-line))
+ (point))
+ (point-min))))
+ (setq startpos (max (- startpos 2000)
+ (point-min)))
+ (goto-char startpos)
+ (let ((pos (or (erlang-search-by-arity regexp)
+ (unless (eq startpos (point-min))
+ (goto-char (point-min))
+ (erlang-search-by-arity regexp)))))
+ (when pos
+ (goto-char pos)
+ t)))))
+
+(defun erlang-tag-info-regexp (tag-text)
+ (concat "^"
+ (regexp-quote tag-text)
+ ;; Erlang function entries in TAGS includes the opening
+ ;; parenthesis for the argument list. Erlang macro entries
+ ;; do not. Add it here in order to end up in correct
+ ;; position for erlang-get-arity.
+ (if (string-prefix-p "-define" tag-text)
+ "\\s-*("
+ "")))
+
+(defun erlang-search-by-arity (regexp)
+ (let (pos)
+ (while (and (null pos)
+ (re-search-forward regexp nil t))
+ (when (eq erlang-current-arity (save-excursion (erlang-get-arity)))
+ (setq pos (point-at-bol))))
+ pos))
(defun erlang-xref-find-definitions (identifier &optional is-regexp)
- (let ((id-list (split-string identifier ":")))
- (cond
- ;; Handle "tag"
- ((null (cdr id-list))
- (erlang-xref-find-definitions-tag identifier is-regexp))
- ;; Handle "module:"
- ((string-equal (cadr id-list) "")
- (erlang-xref-find-definitions-module (car id-list)))
- ;; Handle "module:tag"
- (t
- (erlang-xref-find-definitions-module-tag (car id-list)
- (cadr id-list)
- is-regexp)))))
-
-(defun erlang-xref-find-definitions-tag (tag is-regexp)
- "Find all definitions of TAG and reorder them so that
-definitions in the currently visited file comes first."
- (when (fboundp 'etags--xref-find-definitions)
- (let* ((current-file (and (buffer-file-name)
- (file-truename (buffer-file-name))))
- (xrefs (etags--xref-find-definitions tag is-regexp))
- local-xrefs non-local-xrefs)
- (while xrefs
- (if (string-equal (erlang-xref-truename-file (car xrefs))
- current-file)
- (push (car xrefs) local-xrefs)
- (push (car xrefs) non-local-xrefs))
- (setq xrefs (cdr xrefs)))
- (append (reverse local-xrefs)
- (reverse non-local-xrefs)))))
+ (erlang-with-id (kind module name arity) identifier
+ (setq erlang-current-arity arity)
+ (cond ((eq kind 'module)
+ (erlang-xref-find-definitions-module name))
+ (module
+ (erlang-xref-find-definitions-module-tag module
+ name
+ (eq kind
+ 'qualified-function)
+ is-regexp))
+ (t
+ (erlang-xref-find-definitions-tag kind name is-regexp)))))
(defun erlang-xref-find-definitions-module (module)
(and (fboundp 'xref-make)
@@ -5037,17 +5010,58 @@ definitions in the currently visited file comes first."
(setq files (cdr files))))))
(nreverse xrefs))))
-(defun erlang-xref-find-definitions-module-tag (module tag is-regexp)
- "Find all definitions of TAG and filter away definitions
-outside of MODULE."
- (when (fboundp 'etags--xref-find-definitions)
- (let ((xrefs (etags--xref-find-definitions tag is-regexp))
- xrefs-in-module)
- (while xrefs
- (when (string-equal module (erlang-xref-module (car xrefs)))
- (push (car xrefs) xrefs-in-module))
- (setq xrefs (cdr xrefs)))
- xrefs-in-module)))
+
+(defun erlang-xref-find-definitions-module-tag (module
+ tag
+ is-qualified
+ is-regexp)
+ "Find definitions of TAG and filter away definitions outside of
+MODULE. If IS-QUALIFIED is nil and no definitions was found inside
+the MODULE then return any definitions found outside. If
+IS-REGEXP is non-nil then TAG is a regexp."
+ (and (fboundp 'etags--xref-find-definitions)
+ (fboundp 'erlang-convert-xrefs)
+ (let ((xrefs (erlang-convert-xrefs
+ (etags--xref-find-definitions tag is-regexp)))
+ xrefs-in-module)
+ (dolist (xref xrefs)
+ (when (string-equal module (erlang-xref-module xref))
+ (push xref xrefs-in-module)))
+ (cond (is-qualified xrefs-in-module)
+ (xrefs-in-module xrefs-in-module)
+ (t xrefs)))))
+
+(defun erlang-xref-find-definitions-tag (kind tag is-regexp)
+ "Find all definitions of TAG and reorder them so that
+definitions in the currently visited file comes first."
+ (and (fboundp 'etags--xref-find-definitions)
+ (fboundp 'erlang-convert-xrefs)
+ (let* ((current-file (and (buffer-file-name)
+ (file-truename (buffer-file-name))))
+ (regexp (erlang-etags-regexp kind tag is-regexp))
+ (xrefs (erlang-convert-xrefs
+ (etags--xref-find-definitions regexp t)))
+ local-xrefs non-local-xrefs)
+ (while xrefs
+ (let ((xref (car xrefs)))
+ (if (string-equal (erlang-xref-truename-file xref)
+ current-file)
+ (push xref local-xrefs)
+ (push xref non-local-xrefs))
+ (setq xrefs (cdr xrefs))))
+ (append (reverse local-xrefs)
+ (reverse non-local-xrefs)))))
+
+(defun erlang-etags-regexp (kind tag is-regexp)
+ (let ((tag-regexp (if is-regexp
+ tag
+ (regexp-quote tag))))
+ (cond ((eq kind 'record)
+ (concat "-record\\s-*(\\s-*" tag-regexp))
+ ((eq kind 'macro)
+ (concat "-define\\s-*(\\s-*" tag-regexp))
+ (t tag-regexp))))
+
(defun erlang-xref-module (xref)
(erlang-get-module-from-file-name (erlang-xref-file xref)))
@@ -5163,7 +5177,7 @@ future, a new shell on an already running host will be started."
(defvar erlang-shell-mode-hook nil
- "*User functions to run when an Erlang shell is started.
+ "User functions to run when an Erlang shell is started.
This hook is used to change the behaviour of Erlang mode. It is
normally used by the user to personalise the programming environment.
@@ -5179,7 +5193,7 @@ Erlang source file is loaded into Emacs.")
(defvar erlang-input-ring-file-name "~/.erlang_history"
- "*When non-nil, file name used to store Erlang shell history information.")
+ "When non-nil, file name used to store Erlang shell history information.")
(defun erlang-shell-mode ()
@@ -5213,44 +5227,34 @@ The following special commands are available:
(setq comint-input-ignoredups t)
(setq comint-scroll-show-maximum-output t)
(setq comint-scroll-to-bottom-on-output t)
- ;; In Emacs 19.30, `add-hook' has got a `local' flag, use it. If
- ;; the call fails, just call the normal `add-hook'.
- (condition-case nil
- (progn
- (add-hook 'comint-output-filter-functions
- 'inferior-erlang-strip-delete nil t)
- (add-hook 'comint-output-filter-functions
- 'inferior-erlang-strip-ctrl-m nil t))
- (error
- (funcall (symbol-function 'make-local-hook)
- 'comint-output-filter-functions) ; obsolete as of Emacs 21.1
- (add-hook 'comint-output-filter-functions 'inferior-erlang-strip-delete)
- (add-hook 'comint-output-filter-functions 'inferior-erlang-strip-ctrl-m)))
- ;; Some older versions of comint don't have an input ring.
- (if (fboundp 'comint-read-input-ring)
- (progn
- (setq comint-input-ring-file-name erlang-input-ring-file-name)
- (comint-read-input-ring t)
- (make-local-variable 'kill-buffer-hook)
- (add-hook 'kill-buffer-hook 'comint-write-input-ring)))
+ (add-hook 'comint-output-filter-functions
+ 'inferior-erlang-strip-delete nil t)
+ (add-hook 'comint-output-filter-functions
+ 'inferior-erlang-strip-ctrl-m nil t)
+
+ (setq comint-input-ring-file-name erlang-input-ring-file-name)
+ (comint-read-input-ring t)
+ (make-local-variable 'kill-buffer-hook)
+ (add-hook 'kill-buffer-hook 'comint-write-input-ring)
;; At least in Emacs 21, we need to be in `compilation-minor-mode'
;; for `next-error' to work. We can avoid it clobbering the shell
;; keys thus.
(when inferior-erlang-use-cmm
(compilation-minor-mode 1)
(set (make-local-variable 'minor-mode-overriding-map-alist)
- `((compilation-minor-mode
- . ,(let ((map (make-sparse-keymap)))
- ;; It would be useful to put keymap properties on the
- ;; error lines so that we could use RET and mouse-2
- ;; on them directly.
- (when (boundp 'compilation-skip-threshold) ; new compile.el
- (define-key map [mouse-2] #'erlang-mouse-2-command)
- (define-key map "\C-m" #'erlang-RET-command))
- (if (boundp 'compilation-menu-map)
- (define-key map [menu-bar compilation]
- (cons "Errors" compilation-menu-map)))
- map)))))
+ `((compilation-minor-mode
+ . ,(let ((map (make-sparse-keymap)))
+ ;; It would be useful to put keymap properties on the
+ ;; error lines so that we could use RET and mouse-2
+ ;; on them directly.
+ (when (boundp 'compilation-skip-threshold) ; new compile.el
+ (define-key map [mouse-2] #'erlang-mouse-2-command)
+ (define-key map "\C-m" #'erlang-RET-command))
+ (if (boundp 'compilation-menu-map)
+ (define-key map [menu-bar compilation]
+ (cons "Errors" compilation-menu-map)))
+ map)))))
+ (erlang-tags-init)
(run-hooks 'erlang-shell-mode-hook))
@@ -5259,9 +5263,9 @@ The following special commands are available:
Selects Comint or Compilation mode command as appropriate."
(interactive "e")
(if (save-window-excursion
- (save-excursion
- (mouse-set-point event)
- (consp (get-text-property (line-beginning-position) 'message))))
+ (save-excursion
+ (mouse-set-point event)
+ (consp (get-text-property (line-beginning-position) 'message))))
(call-interactively (lookup-key compilation-mode-map [mouse-2]))
(call-interactively (lookup-key comint-mode-map [mouse-2]))))
@@ -5277,7 +5281,7 @@ Selects Comint or Compilation mode command as appropriate."
(define-key map "\M-\t" 'erlang-complete-tag)
(define-key map "\C-a" 'comint-bol) ; Normally the other way around.
(define-key map "\C-c\C-a" 'beginning-of-line)
- (define-key map "\C-d" nil) ; Was `comint-delchar-or-maybe-eof'
+ (define-key map "\C-d" nil) ; Was `comint-delchar-or-maybe-eof'
(define-key map "\M-\C-m" 'compile-goto-error)
(unless inferior-erlang-use-cmm
(define-key map "\C-x`" 'erlang-next-error)))
@@ -5287,7 +5291,7 @@ Selects Comint or Compilation mode command as appropriate."
;;;
(defvar inferior-erlang-display-buffer-any-frame nil
- "*When nil, `inferior-erlang-display-buffer' use only selected frame.
+ "When nil, `inferior-erlang-display-buffer' use only selected frame.
When t, all frames are searched. When 'raise, the frame is raised.")
(defvar inferior-erlang-shell-type 'newshell
@@ -5300,10 +5304,10 @@ nil, the default shell is used.
This variable influence the setting of other variables.")
(defvar inferior-erlang-machine "erl"
- "*The name of the Erlang shell.")
+ "The name of the Erlang shell.")
(defvar inferior-erlang-machine-options '()
- "*The options used when activating the Erlang shell.
+ "The options used when activating the Erlang shell.
This must be a list of strings.")
@@ -5314,7 +5318,7 @@ This must be a list of strings.")
"The name of the inferior Erlang buffer.")
(defvar inferior-erlang-prompt-timeout 60
- "*Number of seconds before `inferior-erlang-wait-prompt' timeouts.
+ "Number of seconds before `inferior-erlang-wait-prompt' timeouts.
The time specified is waited after every output made by the inferior
Erlang shell. When this variable is t, we assume that we always have
@@ -5349,10 +5353,7 @@ editing control characters:
\\{erlang-shell-mode-map}"
(interactive
(when current-prefix-arg
- (list (if (fboundp 'read-shell-command)
- ;; `read-shell-command' is a new function in Emacs 23.
- (read-shell-command "Erlang command: ")
- (read-string "Erlang command: ")))))
+ (list (read-shell-command "Erlang command: "))))
(require 'comint)
(let (cmd opts)
(if command
@@ -5379,16 +5380,14 @@ editing control characters:
(setq list-buffers-directory fake-file-name))))
(setq inferior-erlang-process
- (get-buffer-process inferior-erlang-buffer))
- (if (> 21 erlang-emacs-major-version) ; funcalls to avoid compiler warnings
- (funcall (symbol-function 'set-process-query-on-exit-flag)
- inferior-erlang-process nil)
- (funcall (symbol-function 'process-kill-without-query) inferior-erlang-process))
+ (get-buffer-process inferior-erlang-buffer))
+ (funcall (symbol-function 'set-process-query-on-exit-flag)
+ inferior-erlang-process nil)
(if erlang-inferior-shell-split-window
(switch-to-buffer-other-window inferior-erlang-buffer)
- (switch-to-buffer inferior-erlang-buffer))
+ (switch-to-buffer inferior-erlang-buffer))
(if (and (not (eq system-type 'windows-nt))
- (eq inferior-erlang-shell-type 'newshell))
+ (eq inferior-erlang-shell-type 'newshell))
(setq comint-process-echoes t))
(erlang-shell-mode))
@@ -5420,22 +5419,22 @@ frame will become deselected before the next command."
(or (inferior-erlang-running-p)
(error "No inferior Erlang process is running"))
(let ((win (inferior-erlang-window
- inferior-erlang-display-buffer-any-frame))
- (frames-p (fboundp 'selected-frame)))
+ inferior-erlang-display-buffer-any-frame))
+ (frames-p (fboundp 'selected-frame)))
(if (null win)
- (let ((old-win (selected-window)))
- (save-excursion
- (switch-to-buffer-other-window inferior-erlang-buffer)
- (setq win (selected-window)))
- (select-window old-win))
+ (let ((old-win (selected-window)))
+ (save-excursion
+ (switch-to-buffer-other-window inferior-erlang-buffer)
+ (setq win (selected-window)))
+ (select-window old-win))
(if (and window-system
- frames-p
- (or select
- (eq inferior-erlang-display-buffer-any-frame 'raise))
- (not (eq (selected-frame) (window-frame win))))
- (raise-frame (window-frame win))))
+ frames-p
+ (or select
+ (eq inferior-erlang-display-buffer-any-frame 'raise))
+ (not (eq (selected-frame) (window-frame win))))
+ (raise-frame (window-frame win))))
(if select
- (select-window win))
+ (select-window win))
(sit-for 0)
win))
@@ -5451,9 +5450,9 @@ frame will become deselected before the next command."
(defun inferior-erlang-window (&optional all-frames)
"Return the window containing the inferior Erlang, or nil."
(and (inferior-erlang-running-p)
- (if (and all-frames (>= erlang-emacs-major-version 19))
- (get-buffer-window inferior-erlang-buffer t)
- (get-buffer-window inferior-erlang-buffer))))
+ (if all-frames
+ (get-buffer-window inferior-erlang-buffer t)
+ (get-buffer-window inferior-erlang-buffer))))
(defun inferior-erlang-wait-prompt ()
@@ -5461,21 +5460,21 @@ frame will become deselected before the next command."
(if (eq inferior-erlang-prompt-timeout t)
()
(or (inferior-erlang-running-p)
- (error "No inferior Erlang shell is running"))
+ (error "No inferior Erlang shell is running"))
(with-current-buffer inferior-erlang-buffer
(let ((msg nil))
- (while (save-excursion
- (goto-char (process-mark inferior-erlang-process))
- (forward-line 0)
- (not (looking-at comint-prompt-regexp)))
- (if msg
- ()
- (setq msg t)
- (message "Waiting for Erlang shell prompt (press C-g to abort)."))
- (or (accept-process-output inferior-erlang-process
- inferior-erlang-prompt-timeout)
- (error "No Erlang shell prompt before timeout")))
- (if msg (message ""))))))
+ (while (save-excursion
+ (goto-char (process-mark inferior-erlang-process))
+ (forward-line 0)
+ (not (looking-at comint-prompt-regexp)))
+ (if msg
+ ()
+ (setq msg t)
+ (message "Waiting for Erlang shell prompt (press C-g to abort)."))
+ (or (accept-process-output inferior-erlang-process
+ inferior-erlang-prompt-timeout)
+ (error "No Erlang shell prompt before timeout")))
+ (if msg (message ""))))))
(defun inferior-erlang-send-empty-cmd-unless-already-at-prompt ()
"If not already at a prompt, try to send an empty cmd to get a prompt.
@@ -5484,12 +5483,12 @@ situations, for instance if a crash or error report from sasl
has been printed after the last prompt."
(with-current-buffer inferior-erlang-buffer
(if (> (point-max) 1)
- ;; make sure we get a prompt if buffer contains data
- (if (save-excursion
- (goto-char (process-mark inferior-erlang-process))
- (forward-line 0)
- (not (looking-at comint-prompt-regexp)))
- (inferior-erlang-send-command "")))))
+ ;; make sure we get a prompt if buffer contains data
+ (if (save-excursion
+ (goto-char (process-mark inferior-erlang-process))
+ (forward-line 0)
+ (not (looking-at comint-prompt-regexp)))
+ (inferior-erlang-send-command "")))))
(autoload 'comint-send-input "comint")
@@ -5506,10 +5505,10 @@ Return the position after the newly inserted command."
(or (inferior-erlang-running-p)
(error "No inferior Erlang process is running"))
(let ((old-buffer (current-buffer))
- (insert-point (marker-position (process-mark inferior-erlang-process)))
- (insert-length (if comint-process-echoes
- 0
- (1+ (length cmd)))))
+ (insert-point (marker-position (process-mark inferior-erlang-process)))
+ (insert-length (if comint-process-echoes
+ 0
+ (1+ (length cmd)))))
(set-buffer inferior-erlang-buffer)
(goto-char insert-point)
(insert cmd)
@@ -5522,21 +5521,18 @@ Return the position after the newly inserted command."
;; This was previously cautioned against in the Lisp manual. It
;; has been sorted out in Emacs 21. -- fx
(let ((comint-eol-on-send nil)
- (comint-input-filter (if hist comint-input-filter 'ignore)))
- (if (and (not erlang-xemacs-p)
- (>= emacs-major-version 22))
- (comint-send-input nil t)
- (comint-send-input)))
+ (comint-input-filter (if hist comint-input-filter 'ignore)))
+ (comint-send-input nil t))
;; Adjust all windows whose points are incorrect.
(if (null comint-process-echoes)
- (walk-windows
- (function
- (lambda (window)
- (if (and (eq (window-buffer window) inferior-erlang-buffer)
- (= (window-point window) insert-point))
- (set-window-point window
- (+ insert-point insert-length)))))
- nil t))
+ (walk-windows
+ (function
+ (lambda (window)
+ (if (and (eq (window-buffer window) inferior-erlang-buffer)
+ (= (window-point window) insert-point))
+ (set-window-point window
+ (+ insert-point insert-length)))))
+ nil t))
(set-buffer old-buffer)
(+ insert-point insert-length)))
@@ -5545,17 +5541,17 @@ Return the position after the newly inserted command."
"Remove `^H' (delete) and the characters it was supposed to remove."
(interactive)
(if (and (boundp 'comint-last-input-end)
- (boundp 'comint-last-output-start))
+ (boundp 'comint-last-output-start))
(save-excursion
- (goto-char
- (if (erlang-interactive-p)
- (symbol-value 'comint-last-input-end)
- (symbol-value 'comint-last-output-start)))
- (while (progn (skip-chars-forward "^\C-h")
- (not (eq (point) (point-max))))
- (delete-char 1)
- (or (bolp)
- (backward-delete-char 1))))))
+ (goto-char
+ (if (called-interactively-p 'interactive)
+ (symbol-value 'comint-last-input-end)
+ (symbol-value 'comint-last-output-start)))
+ (while (progn (skip-chars-forward "^\C-h")
+ (not (eq (point) (point-max))))
+ (delete-char 1)
+ (or (bolp)
+ (backward-delete-char 1))))))
;; Basically `comint-strip-ctrl-m', with a few extra checks.
@@ -5563,15 +5559,15 @@ Return the position after the newly inserted command."
"Strip trailing `^M' characters from the current output group."
(interactive)
(if (and (boundp 'comint-last-input-end)
- (boundp 'comint-last-output-start))
+ (boundp 'comint-last-output-start))
(let ((pmark (process-mark (get-buffer-process (current-buffer)))))
- (save-excursion
- (goto-char
- (if (erlang-interactive-p)
- (symbol-value 'comint-last-input-end)
- (symbol-value 'comint-last-output-start)))
- (while (re-search-forward "\r+$" pmark t)
- (replace-match "" t t))))))
+ (save-excursion
+ (goto-char
+ (if (called-interactively-p 'interactive)
+ (symbol-value 'comint-last-input-end)
+ (symbol-value 'comint-last-output-start)))
+ (while (re-search-forward "\r+$" pmark t)
+ (replace-match "" t t))))))
(defun inferior-erlang-compile (arg)
@@ -5594,18 +5590,18 @@ There exists two workarounds for this bug:
(save-some-buffers)
(inferior-erlang-prepare-for-input)
(let* ((dir (inferior-erlang-compile-outdir))
- (noext (substring (erlang-local-buffer-file-name) 0 -4))
- (opts (append (list (cons 'outdir dir))
- (if current-prefix-arg
- (list 'debug_info 'export_all))
- erlang-compile-extra-opts))
- end)
+ (noext (substring (erlang-local-buffer-file-name) 0 -4))
+ (opts (append (list (cons 'outdir dir))
+ (if current-prefix-arg
+ (list 'debug_info 'export_all))
+ erlang-compile-extra-opts))
+ end)
(with-current-buffer inferior-erlang-buffer
(when (fboundp 'compilation-forget-errors)
(compilation-forget-errors)))
(setq end (inferior-erlang-send-command
- (inferior-erlang-compute-compile-command noext opts)
- nil))
+ (inferior-erlang-compute-compile-command noext opts)
+ nil))
(sit-for 0)
(inferior-erlang-wait-prompt)
(with-current-buffer inferior-erlang-buffer
@@ -5619,7 +5615,7 @@ The buffer is displayed, according to `inferior-erlang-display-buffer'
unless the optional NO-DISPLAY is non-nil."
(or (inferior-erlang-running-p)
(save-excursion
- (inferior-erlang)))
+ (inferior-erlang)))
(or (inferior-erlang-running-p)
(error "Error starting inferior Erlang shell"))
(if (not no-display)
@@ -5631,96 +5627,96 @@ unless the optional NO-DISPLAY is non-nil."
(defun inferior-erlang-compile-outdir ()
"Return the directory to compile the current buffer into."
(let* ((buffer-dir (directory-file-name
- (file-name-directory (erlang-local-buffer-file-name))))
- (parent-dir (directory-file-name
- (file-name-directory buffer-dir)))
+ (file-name-directory (erlang-local-buffer-file-name))))
+ (parent-dir (directory-file-name
+ (file-name-directory buffer-dir)))
(ebin-dir (concat (file-name-as-directory parent-dir) "ebin"))
- (buffer-dir-base-name (file-name-nondirectory
- (expand-file-name
- (concat (file-name-as-directory buffer-dir)
- ".")))))
+ (buffer-dir-base-name (file-name-nondirectory
+ (expand-file-name
+ (concat (file-name-as-directory buffer-dir)
+ ".")))))
(if (and (string= buffer-dir-base-name "src")
- (file-directory-p ebin-dir))
- (file-name-as-directory ebin-dir)
+ (file-directory-p ebin-dir))
+ (file-name-as-directory ebin-dir)
(file-name-as-directory buffer-dir))))
(defun inferior-erlang-compute-compile-command (module-name opts)
(let ((ccfn erlang-compile-command-function-alist)
- (res (inferior-erlang-compute-erl-compile-command module-name opts))
- ccfn-entry
- done
+ (res (inferior-erlang-compute-erl-compile-command module-name opts))
+ ccfn-entry
+ done
result)
(if (not (null (erlang-local-buffer-file-name)))
- (while (and (not done) (not (null ccfn)))
- (setq ccfn-entry (car ccfn))
- (setq ccfn (cdr ccfn))
- (if (string-match (car ccfn-entry) (erlang-local-buffer-file-name))
- (let ((c-fn (cdr ccfn-entry)))
- (setq done t)
- (if (not (null c-fn))
- (setq result (funcall c-fn module-name opts)))))))
+ (while (and (not done) (not (null ccfn)))
+ (setq ccfn-entry (car ccfn))
+ (setq ccfn (cdr ccfn))
+ (if (string-match (car ccfn-entry) (erlang-local-buffer-file-name))
+ (let ((c-fn (cdr ccfn-entry)))
+ (setq done t)
+ (if (not (null c-fn))
+ (setq result (funcall c-fn module-name opts)))))))
result))
(defun inferior-erlang-compute-erl-compile-command (module-name opts)
(let* ((out-dir-opt (assoc 'outdir opts))
- (out-dir (cdr out-dir-opt)))
+ (out-dir (cdr out-dir-opt)))
(if erlang-compile-use-outdir
- (format "%s(\"%s\"%s)."
- erlang-compile-erlang-function
- module-name
- (inferior-erlang-format-comma-opts opts))
+ (format "%s(\"%s\"%s)."
+ erlang-compile-erlang-function
+ module-name
+ (inferior-erlang-format-comma-opts opts))
(let (;; Hopefully, noone else will ever use these...
- (tmpvar "Tmp7236")
- (tmpvar2 "Tmp8742"))
- (format
- (concat
- "f(%s), {ok, %s} = file:get_cwd(), "
- "file:set_cwd(\"%s\"), "
- "%s = %s(\"%s\"%s), file:set_cwd(%s), f(%s), %s.")
- tmpvar2 tmpvar
- out-dir
- tmpvar2
- erlang-compile-erlang-function
- module-name (inferior-erlang-format-comma-opts
- (remq out-dir-opt opts))
- tmpvar tmpvar tmpvar2)))))
+ (tmpvar "Tmp7236")
+ (tmpvar2 "Tmp8742"))
+ (format
+ (concat
+ "f(%s), {ok, %s} = file:get_cwd(), "
+ "file:set_cwd(\"%s\"), "
+ "%s = %s(\"%s\"%s), file:set_cwd(%s), f(%s), %s.")
+ tmpvar2 tmpvar
+ out-dir
+ tmpvar2
+ erlang-compile-erlang-function
+ module-name (inferior-erlang-format-comma-opts
+ (remq out-dir-opt opts))
+ tmpvar tmpvar tmpvar2)))))
(defun inferior-erlang-compute-leex-compile-command (module-name opts)
(let ((file-name (erlang-local-buffer-file-name))
- (erl-compile-expr (inferior-erlang-remove-any-trailing-dot
- (inferior-erlang-compute-erl-compile-command
- module-name opts))))
+ (erl-compile-expr (inferior-erlang-remove-any-trailing-dot
+ (inferior-erlang-compute-erl-compile-command
+ module-name opts))))
(format (concat "f(LErr1__), f(LErr2__), "
- "case case leex:file(\"%s\", [%s]) of"
- " ok -> ok;"
- " {ok,_} -> ok;"
- " {ok,_,_} -> ok;"
- " LErr1__ -> LErr1__ "
- "end of"
- " ok -> %s;"
- " LErr2__ -> LErr2__ "
- "end.")
- file-name
- (inferior-erlang-format-comma-opts erlang-leex-compile-opts)
- erl-compile-expr)))
+ "case case leex:file(\"%s\", [%s]) of"
+ " ok -> ok;"
+ " {ok,_} -> ok;"
+ " {ok,_,_} -> ok;"
+ " LErr1__ -> LErr1__ "
+ "end of"
+ " ok -> %s;"
+ " LErr2__ -> LErr2__ "
+ "end.")
+ file-name
+ (inferior-erlang-format-comma-opts erlang-leex-compile-opts)
+ erl-compile-expr)))
(defun inferior-erlang-compute-yecc-compile-command (module-name opts)
(let ((file-name (erlang-local-buffer-file-name))
- (erl-compile-expr (inferior-erlang-remove-any-trailing-dot
- (inferior-erlang-compute-erl-compile-command
- module-name opts))))
+ (erl-compile-expr (inferior-erlang-remove-any-trailing-dot
+ (inferior-erlang-compute-erl-compile-command
+ module-name opts))))
(format (concat "f(YErr1__), f(YErr2__), "
- "case case yecc:file(\"%s\", [%s]) of"
- " {ok,_} -> ok;"
- " {ok,_,_} -> ok;"
- " YErr1__ -> YErr1__ "
- "end of"
- " ok -> %s;"
- " YErr2__ -> YErr2__ "
- "end.")
- file-name
- (inferior-erlang-format-comma-opts erlang-yecc-compile-opts)
- erl-compile-expr)))
+ "case case yecc:file(\"%s\", [%s]) of"
+ " {ok,_} -> ok;"
+ " {ok,_,_} -> ok;"
+ " YErr1__ -> YErr1__ "
+ "end of"
+ " ok -> %s;"
+ " YErr2__ -> YErr2__ "
+ "end.")
+ file-name
+ (inferior-erlang-format-comma-opts erlang-yecc-compile-opts)
+ erl-compile-expr)))
(defun inferior-erlang-remove-any-trailing-dot (str)
(if (string= (substring str -1) ".")
@@ -5730,31 +5726,29 @@ unless the optional NO-DISPLAY is non-nil."
(defun inferior-erlang-format-comma-opts (opts)
(if (null opts)
""
- (concat ", " (inferior-erlang-format-opts opts))))
-
-(defun inferior-erlang-format-opts (opts)
- (concat "[" (inferior-erlang-string-join (mapcar 'inferior-erlang-format-opt
- opts)
- ", ")
- "]"))
+ (concat ", " (inferior-erlang-format-opt opts))))
(defun inferior-erlang-format-opt (opt)
(cond ((stringp opt) (concat "\"" opt "\""))
- ((atom opt) (format "%s" opt))
- ((consp opt) (concat "{" (inferior-erlang-string-join
- (mapcar 'inferior-erlang-format-opt
- (list (car opt) (cdr opt)))
- ", ")
- "}"))
- (t (error (format "Unexpected opt %s" opt)))))
-
-(defun inferior-erlang-string-join (strs sep)
- (let ((result (or (car strs) "")))
- (setq strs (cdr strs))
- (while strs
- (setq result (concat result sep (car strs)))
- (setq strs (cdr strs)))
- result))
+ ((vectorp opt) (inferior-erlang-tuple (append opt nil)))
+ ((atom opt) (format "%s" opt))
+ ((consp opt) (if (listp (cdr opt))
+ (inferior-erlang-list opt)
+ (inferior-erlang-tuple (list (car opt) (cdr opt)))))
+ (t (error "Unexpected erlang compile option %s" opt))))
+
+(defun inferior-erlang-tuple (opts)
+ (concat "{" (mapconcat 'inferior-erlang-format-opt
+ opts
+ ", ")
+ "}"))
+
+(defun inferior-erlang-list (opts)
+ (concat "[" (mapconcat 'inferior-erlang-format-opt
+ opts
+ ", ")
+ "]"))
+
(defun erlang-local-buffer-file-name ()
;; When editing a file remotely via tramp,
@@ -5768,11 +5762,11 @@ unless the optional NO-DISPLAY is non-nil."
;; the file name "/some/path/x.erl" without the
;; tramp-prefix "/ssh:host.example.com:".
(cond ((null (buffer-file-name))
- nil)
- ((erlang-tramp-remote-file-p)
- (erlang-tramp-get-localname))
- (t
- (buffer-file-name))))
+ nil)
+ ((erlang-tramp-remote-file-p)
+ (erlang-tramp-get-localname))
+ (t
+ (buffer-file-name))))
(defun erlang-tramp-remote-file-p ()
(and (fboundp 'tramp-tramp-file-p)
@@ -5798,22 +5792,22 @@ unless the optional NO-DISPLAY is non-nil."
Capable of finding error messages in an inferior Erlang buffer."
(interactive "P")
(let ((done nil)
- (buf (or (and (boundp 'next-error-last-buffer)
- next-error-last-buffer)
- (and (boundp 'compilation-last-buffer)
- compilation-last-buffer))))
+ (buf (or (and (boundp 'next-error-last-buffer)
+ next-error-last-buffer)
+ (and (boundp 'compilation-last-buffer)
+ compilation-last-buffer))))
(if (and (bufferp buf)
- (with-current-buffer buf
- (and (eq major-mode 'erlang-shell-mode)
- (setq major-mode 'compilation-mode))))
- (unwind-protect
- (progn
- (setq done t)
- (next-error argp))
- (with-current-buffer buf
- (setq major-mode 'erlang-shell-mode))))
+ (with-current-buffer buf
+ (and (eq major-mode 'erlang-shell-mode)
+ (setq major-mode 'compilation-mode))))
+ (unwind-protect
+ (progn
+ (setq done t)
+ (next-error argp))
+ (with-current-buffer buf
+ (setq major-mode 'erlang-shell-mode))))
(or done
- (next-error argp))))
+ (next-error argp))))
(defun inferior-erlang-change-directory (&optional dir)
@@ -5850,44 +5844,44 @@ sum([], Sum) -> Sum."
(interactive "r")
(save-excursion
(let (;; regexp for matching arrows. without a prefix argument,
- ;; the regexp matches function heads. With a prefix, it
- ;; matches any arrow.
- (re (if current-prefix-arg
- "^.*\\(\\)->"
- (eval-when-compile
- (concat "^" erlang-atom-regexp ".*\\(\\)->"))))
- ;; part of regexp matching directly before the arrow
- (arrow-match-pos (if current-prefix-arg
- 1
- (1+ erlang-atom-regexp-matches)))
- ;; accumulator for positions where arrows are found, ordered
- ;; by buffer position (from greatest to smallest)
- (arrow-positions '())
- ;; accumulator for longest distance from start of line to arrow
- (most-indent 0)
- ;; marker to track the end of the region we're aligning
- (end-marker (progn (goto-char end)
- (point-marker))))
+ ;; the regexp matches function heads. With a prefix, it
+ ;; matches any arrow.
+ (re (if current-prefix-arg
+ "^.*\\(\\)->"
+ (eval-when-compile
+ (concat "^" erlang-atom-regexp ".*\\(\\)->"))))
+ ;; part of regexp matching directly before the arrow
+ (arrow-match-pos (if current-prefix-arg
+ 1
+ (1+ erlang-atom-regexp-matches)))
+ ;; accumulator for positions where arrows are found, ordered
+ ;; by buffer position (from greatest to smallest)
+ (arrow-positions '())
+ ;; accumulator for longest distance from start of line to arrow
+ (most-indent 0)
+ ;; marker to track the end of the region we're aligning
+ (end-marker (progn (goto-char end)
+ (point-marker))))
;; Pass 1: Find the arrow positions, adjust the whitespace
;; before each arrow to one space, and find the greatest
;; indentation level.
(goto-char start)
(while (re-search-forward re end-marker t)
- (goto-char (match-beginning arrow-match-pos))
- (just-one-space) ; adjust whitespace
- (setq arrow-positions (cons (point) arrow-positions))
- (setq most-indent (max most-indent (erlang-column-number))))
- (set-marker end-marker nil) ; free the marker
+ (goto-char (match-beginning arrow-match-pos))
+ (just-one-space) ; adjust whitespace
+ (setq arrow-positions (cons (point) arrow-positions))
+ (setq most-indent (max most-indent (erlang-column-number))))
+ (set-marker end-marker nil) ; free the marker
;; Pass 2: Insert extra padding so that all arrow indentation is
;; equal. This is done last-to-first by buffer position, so that
;; inserting spaces before one arrow doesn't change the
;; positions of the next ones.
(mapc (lambda (arrow-pos)
- (goto-char arrow-pos)
- (let* ((pad (- most-indent (erlang-column-number))))
- (when (> pad 0)
- (insert-char ?\ pad))))
- arrow-positions))))
+ (goto-char arrow-pos)
+ (let* ((pad (- most-indent (erlang-column-number))))
+ (when (> pad 0)
+ (insert-char ?\ pad))))
+ arrow-positions))))
(defun erlang-column-number ()
"Return the column number of the current position in the buffer.
@@ -5899,7 +5893,7 @@ Tab characters are counted by their visual width."
(save-excursion
(erlang-beginning-of-function)
(if (looking-at "[a-z0-9_]+")
- (match-string 0))))
+ (match-string 0))))
;; Aliases for backward compatibility with older versions of Erlang Mode.
;;
@@ -5912,13 +5906,12 @@ Tab characters are counted by their visual width."
Simplified version of a combination `defalias' and `make-obsolete',
it assumes that NEWDEF is loaded."
(defalias sym (symbol-function newdef))
- (if (fboundp 'make-obsolete)
- (make-obsolete sym newdef "long ago")))
+ (make-obsolete sym newdef "long ago"))
(erlang-obsolete 'calculate-erlang-indent 'erlang-calculate-indent)
(erlang-obsolete 'calculate-erlang-stack-indent
- 'erlang-calculate-stack-indent)
+ 'erlang-calculate-stack-indent)
(erlang-obsolete 'at-erlang-keyword 'erlang-at-keyword)
(erlang-obsolete 'at-erlang-operator 'erlang-at-operator)
(erlang-obsolete 'beginning-of-erlang-clause 'erlang-beginning-of-clause)
@@ -5933,15 +5926,8 @@ it assumes that NEWDEF is loaded."
(defconst erlang-unload-hook
(list (lambda ()
- (when (featurep 'advice)
- (ad-unadvise 'Man-notify-when-ready)
- (ad-unadvise 'set-visited-file-name)))))
-
-
-(defun erlang-string-to-int (string)
- (if (fboundp 'string-to-number)
- (string-to-number string)
- (funcall (symbol-function 'string-to-int) string)))
+ (ad-unadvise 'Man-notify-when-ready)
+ (ad-unadvise 'set-visited-file-name))))
;; The end...
@@ -5950,7 +5936,8 @@ it assumes that NEWDEF is loaded."
(run-hooks 'erlang-load-hook)
;; Local variables:
-;; coding: iso-8859-1
+;; coding: utf-8
+;; indent-tabs-mode: nil
;; End:
;;; erlang.el ends here
diff --git a/lib/tools/emacs/erldoc.el b/lib/tools/emacs/erldoc.el
new file mode 100644
index 0000000000..770ab299ee
--- /dev/null
+++ b/lib/tools/emacs/erldoc.el
@@ -0,0 +1,514 @@
+;;; erldoc.el --- browse Erlang/OTP documentation -*- lexical-binding: t; -*-
+
+;; %CopyrightBegin%
+;;
+;; Copyright Ericsson AB 2016-2017. All Rights Reserved.
+;;
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
+;;
+;; http://www.apache.org/licenses/LICENSE-2.0
+;;
+;; Unless required by applicable law or agreed to in writing, software
+;; distributed under the License is distributed on an "AS IS" BASIS,
+;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+;; See the License for the specific language governing permissions and
+;; limitations under the License.
+;;
+;; %CopyrightEnd%
+
+;;; Commentary:
+
+;; Crawl Erlang/OTP HTML documentation and generate lookup tables.
+;;
+;; This package depends on `cl-lib', `pcase' and
+;; `libxml-parse-html-region'. Emacs 24+ compiled with libxml2 should
+;; work. On Emacs 24.1 and 24.2 do `M-x package-install RET cl-lib
+;; RET' to install `cl-lib'.
+;;
+;; Please customise `erldoc-man-index' to point to your local OTP
+;; documentation.
+;;
+;; To use:
+;;
+;; (define-key help-map "u" 'erldoc-browse)
+;; (define-key help-map "t" 'erldoc-browse-topic)
+;; (define-key help-map "a" 'erldoc-apropos)
+;;
+;; Note: these commands trigger indexing OTP documentation on first
+;; run with cache to disk which may take 1-2 minutes.
+
+
+;;; Examples:
+
+;; 1. `M-x erldoc-browse RET erlang:integer_to_binary/2 RET' opens the
+;; `erlang' manual anchored on the entry for `integer_to_binary/2'.
+;;
+;; 2. `M-x erldoc-apropos RET first RET' list all MFAs matching
+;; substring `first'.
+;;
+;; 3. `M-x erldoc-browse-topic RET efficiency_guide#Introduction RET'
+;; opens chapter `Introduction' of the `Efficiency Guide' in the
+;; browser.
+
+;;; History:
+
+;; Written in December 2013 as a temporary solution to help me browse
+;; the rich Erlang/OTP documentation. Three years on I find myself
+;; still using it every day. - Leo (2016)
+
+;;; Code:
+
+(eval-when-compile (require 'url-parse))
+(require 'cl-lib)
+(require 'erlang)
+
+(eval-and-compile ;for emacs < 24.3
+ (or (fboundp 'user-error) (defalias 'user-error 'error)))
+
+(defgroup erldoc nil
+ "Browse Erlang document."
+ :group 'help)
+
+(defcustom erldoc-man-index "http://www.erlang.org/doc/man_index.html"
+ "The URL to the man_index.html page.
+Note it is advisable to customise this to a local URL for example
+`file:///usr/local/19.1/lib/erlang/doc/man_index.html' to speed
+up the indexing."
+ :type 'string
+ :group 'erldoc)
+
+(defcustom erldoc-verify-man-path nil
+ "If non-nil verify man path existence for `file://'."
+ :type 'boolean
+ :group 'erldoc)
+
+(defcustom erldoc-output-file (locate-user-emacs-file "cache/erldoc")
+ "File to store the parsed results."
+ :type 'file
+ :group 'erldoc)
+
+(defun erldoc-strip-string (s)
+ (let* ((re "[ \t\n\r\f\v\u00a0]+")
+ (from (if (string-match (concat "\\`" re) s) (match-end 0) 0))
+ (to (and (string-match (concat re "\\'") s) (match-beginning 0))))
+ (substring s from (and to (max to from)))))
+
+;; Note: don't know how to get the BASE-URL to
+;; `libxml-parse-html-region' to work.
+(defun erldoc-expand-url (url base-url)
+ (if (url-type (url-generic-parse-url url))
+ url
+ (let* ((base (url-generic-parse-url base-url))
+ (dir (directory-file-name (file-name-directory (url-filename base)))))
+ (setf (url-filename base) (expand-file-name url dir))
+ (url-recreate-url base))))
+
+(defun erldoc-parse-html (url)
+ (with-temp-buffer
+ (url-insert-file-contents url)
+ (libxml-parse-html-region (point-min) (point-max))))
+
+(defalias 'erldoc-dom-text-node-p #'stringp)
+
+(defun erldoc-dom-attributes (dom)
+ (and (not (erldoc-dom-text-node-p dom)) (cadr dom)))
+
+(defun erldoc-dom-get-attribute (dom attrib-name)
+ (cdr (assq attrib-name (erldoc-dom-attributes dom))))
+
+(defun erldoc-dom-children (dom)
+ (and (not (erldoc-dom-text-node-p dom)) (cddr dom)))
+
+(defun erldoc-dom-get-text (dom)
+ (let ((text (car (last (erldoc-dom-children dom)))))
+ (and (erldoc-dom-text-node-p text) text)))
+
+(defvar erldoc-dom-walk-parent nil)
+(defvar erldoc-dom-walk-siblings nil)
+
+(defun erldoc-dom-walk (dom k)
+ (funcall k dom)
+ (let ((erldoc-dom-walk-parent dom)
+ (erldoc-dom-walk-siblings (unless (erldoc-dom-text-node-p dom)
+ (cddr dom))))
+ (dolist (child erldoc-dom-walk-siblings)
+ (erldoc-dom-walk child k))))
+
+(defun erldoc-dom-get-element (dom element-name)
+ (catch 'return
+ (erldoc-dom-walk dom (lambda (d)
+ (when (eq (car-safe d) element-name)
+ (throw 'return d))))))
+
+(defun erldoc-dom-get-element-by-id (dom id)
+ (catch 'return
+ (erldoc-dom-walk dom (lambda (d)
+ (when (equal (erldoc-dom-get-attribute d 'id) id)
+ (throw 'return d))))))
+
+(defun erldoc-dom-get-elements-by-id (dom id)
+ (let (result)
+ (erldoc-dom-walk dom (lambda (d)
+ (when (equal (erldoc-dom-get-attribute d 'id) id)
+ (push d result))))
+ (nreverse result)))
+
+(defun erldoc-fix-path (url)
+ (if (and erldoc-verify-man-path
+ ;; Could only verify local files
+ (equal (url-type (url-generic-parse-url url)) "file"))
+ (let* ((obj (url-generic-parse-url url))
+ (new (car (file-expand-wildcards
+ (replace-regexp-in-string
+ "-[0-9]+\\(?:[.][0-9]+\\)*" "*"
+ (url-filename obj))))))
+ (or new (error "File %s does not exist" (url-filename obj)))
+ (setf (url-filename obj) new)
+ (url-recreate-url obj))
+ url))
+
+(defun erldoc-parse-man-index (url)
+ (let ((table (erldoc-dom-get-element (erldoc-parse-html url) 'table))
+ (mans))
+ (erldoc-dom-walk
+ table
+ (lambda (d)
+ (when (eq (car-safe d) 'a)
+ (let ((href (erldoc-dom-get-attribute d 'href)))
+ (when (and href (not (string-match-p "index\\.html\\'" href)))
+ (with-demoted-errors "erldoc-parse-man-index: %S"
+ (push (cons (erldoc-dom-get-text d)
+ (erldoc-fix-path (erldoc-expand-url href url)))
+ mans)))))))
+ (nreverse mans)))
+
+(defun erldoc-parse-man (man)
+ (let ((dom (erldoc-parse-html (cdr man)))
+ (table (make-hash-table :test #'equal)))
+ (erldoc-dom-walk
+ (erldoc-dom-get-element-by-id dom "loadscrollpos")
+ (lambda (d)
+ (let ((href (erldoc-dom-get-attribute d 'href)))
+ (when (and href (string-match "#" href))
+ (puthash (substring href (match-end 0))
+ (list (concat (car man) ":" (erldoc-strip-string
+ (erldoc-dom-get-text d)))
+ (erldoc-expand-url href (cdr man)))
+ table)))))
+ (let ((span-content
+ (lambda (span)
+ (let ((texts))
+ (erldoc-dom-walk span
+ (lambda (d)
+ (and (erldoc-dom-text-node-p d)
+ (push (erldoc-strip-string d) texts))))
+ (and texts (mapconcat 'identity (nreverse texts) " ")))))
+ entries)
+ (erldoc-dom-walk
+ dom
+ (lambda (d)
+ ;; Get the full function signature.
+ (when (and (eq (car-safe d) 'a)
+ (gethash (erldoc-dom-get-attribute d 'name) table))
+ (push (append (gethash (erldoc-dom-get-attribute d 'name) table)
+ (list (funcall span-content
+ (or (erldoc-dom-get-element d 'span)
+ (cadr (memq d erldoc-dom-walk-siblings))))))
+ entries))
+ ;; Get data types
+ (when (and (eq (car-safe d) 'a)
+ (string-prefix-p "type-"
+ (or (erldoc-dom-get-attribute d 'name) "")))
+ (push (list (concat (car man) ":" (funcall span-content d))
+ (concat (cdr man) "#" (erldoc-dom-get-attribute d 'name))
+ (funcall span-content erldoc-dom-walk-parent))
+ entries))))
+ entries)))
+
+(defun erldoc-parse-all (man-index output &optional json)
+ (let* ((output (expand-file-name output))
+ (table (make-hash-table :size 11503 :test #'equal))
+ (mans (erldoc-parse-man-index man-index))
+ (progress 1)
+ (reporter (make-progress-reporter "Parsing Erlang/OTP documentation"
+ progress (length mans)))
+ fails all)
+ (dolist (man mans)
+ (condition-case err
+ (push (erldoc-parse-man man) all)
+ (error (push (error-message-string err) fails)))
+ (accept-process-output nil 0.01)
+ (progress-reporter-update reporter (cl-incf progress)))
+ (when fails
+ (display-warning 'erldoc-parse-all
+ (format "\n\n%s" (mapconcat #'identity fails "\n"))
+ :error))
+ (progress-reporter-done reporter)
+ (mapc (lambda (x) (puthash (car x) (cdr x) table))
+ (apply #'nconc (nreverse all)))
+ (with-temp-buffer
+ (if (not json)
+ (pp table (current-buffer))
+ (eval-and-compile (require 'json))
+ (let ((json-encoding-pretty-print t))
+ (insert (json-encode table))))
+ (unless (file-directory-p (file-name-directory output))
+ (make-directory (file-name-directory output) t))
+ (write-region nil nil output nil nil nil 'ask))))
+
+(defun erldoc-otp-release ()
+ "Get the otp release version (as string) or nil if not found."
+ (let ((otp (erldoc-dom-get-text
+ (erldoc-dom-get-element
+ (erldoc-parse-html
+ (erldoc-expand-url "index.html" erldoc-man-index))
+ 'title))))
+ (and (string-match "[0-9.]+\\'" otp) (match-string 0 otp))))
+
+(defvar erldoc-browse-history nil)
+(defvar erldoc-lookup-table nil)
+
+(defun erldoc-lookup-table ()
+ (or erldoc-lookup-table
+ (progn
+ (unless (file-exists-p erldoc-output-file)
+ (let ((of (pcase (erldoc-otp-release)
+ (`nil erldoc-output-file)
+ (ver (concat erldoc-output-file "-" ver)))))
+ (unless (file-exists-p of)
+ (erldoc-parse-all erldoc-man-index of))
+ (unless (string= erldoc-output-file of)
+ (make-symbolic-link of erldoc-output-file))))
+ (setq erldoc-lookup-table
+ (with-temp-buffer
+ (insert-file-contents erldoc-output-file)
+ (read (current-buffer)))))))
+
+(defun erldoc-best-matches (mfa)
+ (pcase mfa
+ ((and `(,m ,f) (let a (erlang-get-function-arity)))
+ (let ((mfa (format "%s:%s/%s" m f a)))
+ (cond ((gethash mfa (erldoc-lookup-table)) (list mfa))
+ (m (all-completions (concat m ":" f "/") (erldoc-lookup-table)))
+ (t (let* ((mod (erlang-get-module))
+ (mf1 (and mod (concat mod ":" f "/")))
+ (mf2 (concat "erlang:" f "/"))
+ (re (concat ":" (regexp-quote f) "/")))
+ (or (and mf1 (all-completions mf1 (erldoc-lookup-table)))
+ (all-completions mf2 (erldoc-lookup-table))
+ (cl-loop for k being the hash-keys of (erldoc-lookup-table)
+ when (string-match-p re k)
+ collect k)))))))))
+
+;;;###autoload
+(defun erldoc-browse (mfa)
+ (interactive
+ (let ((default
+ ;; `erlang-mode-syntax-table' is lazily initialised.
+ (with-syntax-table (or erlang-mode-syntax-table (standard-syntax-table))
+ (ignore-errors
+ (erldoc-best-matches
+ (or (erlang-get-function-under-point)
+ (save-excursion
+ (goto-char (or (cadr (syntax-ppss)) (point)))
+ (erlang-get-function-under-point))))))))
+ (list (completing-read (format (if default "Function {%d %s} (default %s): "
+ "Function: ")
+ (length default)
+ (if (= (length default) 1) "guess" "guesses")
+ (car default))
+ (erldoc-lookup-table)
+ nil t nil 'erldoc-browse-history default))))
+ (or (stringp mfa)
+ (signal 'wrong-type-argument (list 'string mfa 'mfa)))
+ (browse-url (or (car (gethash mfa (erldoc-lookup-table)))
+ (user-error "No documentation for %s" mfa))))
+
+;;;###autoload
+(defun erldoc-apropos (pattern)
+ (interactive "sPattern: ")
+ (with-help-window (help-buffer)
+ (with-current-buffer standard-output
+ (princ (concat "Erldoc apropos pattern: " pattern "\n\n"))
+ (maphash (lambda (k v)
+ (when (string-match-p pattern k)
+ (insert-text-button k :type 'help-url
+ 'help-args (list (car v)))
+ (insert "\n")))
+ (erldoc-lookup-table)))))
+
+(defun erldoc-tokenize-signature (sig)
+ ;; Divide SIG into (MF ARGLIST RETTYPE)
+ (let ((from (if (string-match "\\`.+?(" sig)
+ (1- (match-end 0))
+ 0))
+ (to (and (string-match "\\s-*->\\s-*.*?\\'" sig) (match-beginning 0))))
+ (list (erldoc-strip-string (substring sig 0 from))
+ (erldoc-strip-string (substring sig from (and to (max from to))))
+ (and to (erldoc-strip-string (substring sig to))))))
+
+(defun erldoc-format-signature (mod fn)
+ (when (and mod fn (or erldoc-lookup-table
+ (file-exists-p erldoc-output-file)))
+ (let ((re (concat "\\`" mod ":" fn "/\\([0-9]+\\)\\'"))
+ (sigs))
+ (maphash (lambda (k v)
+ (when (string-match re k)
+ (push (cons (string-to-number (match-string 1 k))
+ (cdr (erldoc-tokenize-signature (cadr v))))
+ sigs)))
+ (erldoc-lookup-table))
+ (when sigs
+ ;; Mostly single return type but there are exceptions such as
+ ;; `beam_lib:chunks/2,3'.
+ (let ((single-rettype
+ (cl-reduce (lambda (x1 x2) (and x1 x2 (equal x1 x2) x1))
+ sigs :key #'cl-caddr))
+ (sigs (sort sigs #'car-less-than-car)))
+ (if single-rettype
+ (concat mod ":" fn (mapconcat #'cadr sigs " | ") " " single-rettype)
+ (mapconcat (lambda (x) (concat mod ":" fn (nth 1 x) " " (nth 2 x)))
+ sigs "\n")))))))
+
+;;;###autoload
+(defun erldoc-eldoc-function ()
+ "A function suitable for `eldoc-documentation-function'."
+ (save-excursion
+ (pcase (erlang-get-function-under-point)
+ (`(,_ nil) )
+ (`(nil ,fn) (erldoc-format-signature "erlang" fn))
+ (`(,mod ,fn) (erldoc-format-signature mod fn)))))
+
+(defun erldoc-parse-eeps-index ()
+ (let* ((url "http://www.erlang.org/eeps/")
+ (table (catch 'return
+ (erldoc-dom-walk (erldoc-parse-html url)
+ (lambda (d)
+ (and (eq (car-safe d) 'table)
+ (equal (erldoc-dom-get-attribute d 'summary)
+ "Numerical Index of EEPs")
+ (throw 'return d))))))
+ (fix-title (lambda (title)
+ (replace-regexp-in-string
+ "`` *" "" (replace-regexp-in-string " *``, *" " by " title))))
+ (result))
+ (erldoc-dom-walk
+ table (lambda (d)
+ (when (eq (car-safe d) 'a)
+ (push (cons (funcall fix-title (erldoc-dom-get-attribute d 'title))
+ (erldoc-expand-url
+ (erldoc-dom-get-attribute d 'href)
+ url))
+ result))))
+ (nreverse result)))
+
+(defvar erldoc-user-guides nil)
+
+(defvar erldoc-missing-user-guides
+ '("compiler" "hipe" "kernel" "os_mon" "parsetools")
+ "List of standard Erlang applications with no user guides.")
+
+;; Search in `code:lib_dir/0' using find LIB_DIR -type f -name
+;; '*_app.html'.
+(defvar erldoc-app-manuals '("crypto" "diameter" "erl_docgen"
+ "kernel" "observer" "os_mon"
+ "runtime_tools" "sasl" "snmp"
+ "ssl" "test_server"
+ ("ssh" . "SSH") ("stdlib" . "STDLIB")
+ ("hipe" . "HiPE"))
+ "List of applications that come with a manual.")
+
+(defun erldoc-user-guide-chapters (user-guide)
+ (pcase-let ((`(,name . ,url) user-guide))
+ (unless (member name erldoc-missing-user-guides)
+ (let ((chaps (erldoc-dom-get-elements-by-id
+ (erldoc-dom-get-element-by-id (erldoc-parse-html url) "leftnav")
+ "no")))
+ (or chaps (warn "erldoc-user-guide-chapters no chapters found for `%s'"
+ (cdr user-guide)))
+ (mapcar (lambda (li)
+ (cons (concat name "#" (erldoc-dom-get-attribute li 'title))
+ (erldoc-expand-url (erldoc-dom-get-attribute
+ (erldoc-dom-get-element li 'a) 'href)
+ url)))
+ chaps)))))
+
+(defun erldoc-user-guides-1 ()
+ (let ((url (erldoc-expand-url "applications.html" erldoc-man-index))
+ app-guides app-mans)
+ (erldoc-dom-walk
+ (erldoc-parse-html url)
+ (lambda (d)
+ (when (and (eq (car-safe d) 'a)
+ (not (string-match-p "\\`[0-9.]+\\'" (erldoc-dom-get-text d))))
+ (with-demoted-errors "erldoc-user-guides-1: %S"
+ (let ((name (erldoc-strip-string (erldoc-dom-get-text d)))
+ (index-page (erldoc-fix-path (erldoc-expand-url
+ (erldoc-dom-get-attribute d 'href) url))))
+ (push (cons name (if (member name erldoc-missing-user-guides)
+ index-page
+ (erldoc-expand-url "users_guide.html" index-page)))
+ app-guides)
+ ;; Collect application manuals.
+ (pcase (assoc name (mapcar (lambda (x) (if (consp x) x (cons x x)))
+ erldoc-app-manuals))
+ (`(,_ . ,manual)
+ (push (cons name
+ (erldoc-expand-url (format "%s_app.html" manual)
+ index-page))
+ app-mans))))))))
+ (list (nreverse app-guides)
+ (nreverse app-mans))))
+
+(defun erldoc-user-guides ()
+ (or erldoc-user-guides
+ (let ((file (concat erldoc-output-file "-topics")))
+ (unless (file-exists-p file)
+ (unless (file-directory-p (file-name-directory file))
+ (make-directory (file-name-directory file) t))
+ (with-temp-buffer
+ (pcase-let ((`(,guides ,mans) (erldoc-user-guides-1)))
+ (pp (append (cl-mapcan #'erldoc-user-guide-chapters
+ (append (mapcar
+ (lambda (dir)
+ (cons dir (erldoc-expand-url
+ (concat dir "/users_guide.html")
+ erldoc-man-index)))
+ '("design_principles"
+ "efficiency_guide"
+ "embedded"
+ "getting_started"
+ "installation_guide"
+ "oam"
+ "programming_examples"
+ "reference_manual"
+ "system_architecture_intro"
+ "system_principles"
+ "tutorial"))
+ guides))
+ (mapcar (lambda (man)
+ (pcase-let ((`(,name . ,url) man))
+ (cons (concat name " (App)") url)))
+ mans)
+ (erldoc-parse-eeps-index))
+ (current-buffer)))
+ (write-region nil nil file nil nil nil 'ask)))
+ (setq erldoc-user-guides (with-temp-buffer (insert-file-contents file)
+ (read (current-buffer)))))))
+
+;;;###autoload
+(defun erldoc-browse-topic (topic)
+ (interactive
+ (list (completing-read "User guide: " (erldoc-user-guides) nil t)))
+ (browse-url (cdr (assoc topic (erldoc-user-guides)))))
+
+(provide 'erldoc)
+
+;; Local variables:
+;; coding: utf-8
+;; indent-tabs-mode: nil
+;; End:
+
+;;; erldoc.el ends here
diff --git a/lib/tools/emacs/test.erl.indented b/lib/tools/emacs/test.erl.indented
index 7a1ff6a954..14a4eca7c3 100644
--- a/lib/tools/emacs/test.erl.indented
+++ b/lib/tools/emacs/test.erl.indented
@@ -1,4 +1,4 @@
-%% -*- erlang -*-
+%% -*- Mode: erlang; indent-tabs-mode: nil -*-
%%
%% %CopyrightBegin%
%%
@@ -27,7 +27,7 @@
%%% Created : 6 Oct 2009 by Dan Gudmundsson <[email protected]>
%%%-------------------------------------------------------------------
-%% Start off with syntax highlighting you have to verify this by looking here
+%% Start off with syntax highlighting you have to verify this by looking here
%% and see that the code looks alright
-module(test).
@@ -44,175 +44,175 @@ foo() ->
%% Module attributes should be highlighted
-export([t/1]).
--record(record1, {a,
- b,
- c
- }).
+-record(record1, {a,
+ b,
+ c
+ }).
-record(record2, {
- a,
- b
- }).
+ a,
+ b
+ }).
-record(record3, {a = 8#42423 bor
- 8#4234,
- b = 8#5432
- bor 2#1010101
- c = 123 +
- 234,
+ 8#4234,
+ b = 8#5432
+ bor 2#1010101
+ c = 123 +
+ 234,
d}).
-record(record4, {
- a = 8#42423 bor
- 8#4234,
- b = 8#5432
- bor 2#1010101
- c = 123 +
- 234,
- d}).
+ a = 8#42423 bor
+ 8#4234,
+ b = 8#5432
+ bor 2#1010101
+ c = 123 +
+ 234,
+ d}).
-record(record5, { a = 1 :: integer()
- , b = foobar :: atom()
- }).
+ , b = foobar :: atom()
+ }).
-define(MACRO_1, macro).
-define(MACRO_2(_), macro).
-spec t(integer()) -> any().
--type ann() :: Var :: integer().
--type ann2() :: Var ::
- 'return'
- | 'return_white_spaces'
- | 'return_comments'
- | 'text' | ann().
--type paren() ::
- (ann2()).
--type t1() :: atom().
--type t2() :: [t1()].
--type t3(Atom) :: integer(Atom).
--type t4() :: t3(foobar).
--type t5() :: {t1(), t3(foo)}.
--type t6() :: 1 | 2 | 3 |
- 'foo' | 'bar'.
--type t7() :: [].
--type t71() :: [_].
+-type ann() :: Var :: integer().
+-type ann2() :: Var ::
+ 'return'
+ | 'return_white_spaces'
+ | 'return_comments'
+ | 'text' | ann().
+-type paren() ::
+ (ann2()).
+-type t1() :: atom().
+-type t2() :: [t1()].
+-type t3(Atom) :: integer(Atom).
+-type t4() :: t3(foobar).
+-type t5() :: {t1(), t3(foo)}.
+-type t6() :: 1 | 2 | 3 |
+ 'foo' | 'bar'.
+-type t7() :: [].
+-type t71() :: [_].
-type t8() :: {any(),none(),pid(),port(),
- reference(),float()}.
--type t9() :: [1|2|3|foo|bar] |
- list(a | b | c) | t71().
--type t10() :: {1|2|3|foo|t9()} | {}.
--type t11() :: 1..2.
--type t13() :: maybe_improper_list(integer(), t11()).
--type t14() :: [erl_scan:foo() |
- %% Should be highlighted
- term() |
- bool() |
- byte() |
- char() |
- non_neg_integer() | nonempty_list() |
- pos_integer() |
- neg_integer() |
- number() |
- list() |
- nonempty_improper_list() | nonempty_maybe_improper_list() |
- maybe_improper_list() | string() | iolist() | byte() |
- module() |
- mfa() |
- node() |
- timeout() |
- no_return() |
- %% Should not be highlighted
- nonempty_() | nonlist() |
- erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)].
+ reference(),float()}.
+-type t9() :: [1|2|3|foo|bar] |
+ list(a | b | c) | t71().
+-type t10() :: {1|2|3|foo|t9()} | {}.
+-type t11() :: 1..2.
+-type t13() :: maybe_improper_list(integer(), t11()).
+-type t14() :: [erl_scan:foo() |
+ %% Should be highlighted
+ term() |
+ bool() |
+ byte() |
+ char() |
+ non_neg_integer() | nonempty_list() |
+ pos_integer() |
+ neg_integer() |
+ number() |
+ list() |
+ nonempty_improper_list() | nonempty_maybe_improper_list() |
+ maybe_improper_list() | string() | iolist() | byte() |
+ module() |
+ mfa() |
+ node() |
+ timeout() |
+ no_return() |
+ %% Should not be highlighted
+ nonempty_() | nonlist() |
+ erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)].
-type t15() :: {binary(),<<>>,<<_:34>>,<<_:_*42>>,
<<_:3,_:_*14>>,<<>>} | [<<>>|<<_:34>>|<<_:16>>|
- <<_:3,_:_*1472>>|<<_:19,_:_*14>>| <<_:34>>|
- <<_:34>>|<<_:34>>|<<_:34>>].
--type t16() :: fun().
--type t17() :: fun((...) -> paren()).
--type t18() :: fun(() -> t17() | t16()).
+ <<_:3,_:_*1472>>|<<_:19,_:_*14>>| <<_:34>>|
+ <<_:34>>|<<_:34>>|<<_:34>>].
+-type t16() :: fun().
+-type t17() :: fun((...) -> paren()).
+-type t18() :: fun(() -> t17() | t16()).
-type t19() :: fun((t18()) -> t16()) |
- fun((nonempty_maybe_improper_list('integer', any())|
- 1|2|3|a|b|<<_:3,_:_*14>>|integer()) ->
- nonempty_maybe_improper_list('integer', any())|
- 1|2|3|a|b|<<_:3,_:_*14>>|integer()).
--type t20() :: [t19(), ...].
--type t21() :: tuple().
--type t21(A) :: A.
--type t22() :: t21(integer()).
--type t23() :: #rec1{}.
--type t24() :: #rec2{a :: t23(), b :: [atom()]}.
--type t25() :: #rec3{f123 :: [t24() |
- 1|2|3|4|a|b|c|d|
- nonempty_maybe_improper_list(integer, any())]}.
+ fun((nonempty_maybe_improper_list('integer', any())|
+ 1|2|3|a|b|<<_:3,_:_*14>>|integer()) ->
+ nonempty_maybe_improper_list('integer', any())|
+ 1|2|3|a|b|<<_:3,_:_*14>>|integer()).
+-type t20() :: [t19(), ...].
+-type t21() :: tuple().
+-type t21(A) :: A.
+-type t22() :: t21(integer()).
+-type t23() :: #rec1{}.
+-type t24() :: #rec2{a :: t23(), b :: [atom()]}.
+-type t25() :: #rec3{f123 :: [t24() |
+ 1|2|3|4|a|b|c|d|
+ nonempty_maybe_improper_list(integer, any())]}.
-type t26() :: #rec4{ a :: integer()
- , b :: any()
- }.
+ , b :: any()
+ }.
-type t27() :: { integer()
- , atom()
- }.
+ , atom()
+ }.
-type t99() ::
- {t2(),t4(),t5(),t6(),t7(),t8(),t10(),t14(),
- t15(),t20(),t21(), t22(),t25()}.
+ {t2(),t4(),t5(),t6(),t7(),t8(),t10(),t14(),
+ t15(),t20(),t21(), t22(),t25()}.
-spec t1(FooBar :: t99()) -> t99();
- (t2()) -> t2();
+ (t2()) -> t2();
(t4()) -> t4() when is_subtype(t4(), t24);
- (t23()) -> t23() when is_subtype(t23(), atom()),
- is_subtype(t23(), t14());
- (t24()) -> t24() when is_subtype(t24(), atom()),
- is_subtype(t24(), t14()),
- is_subtype(t24(), t4()).
+ (t23()) -> t23() when is_subtype(t23(), atom()),
+ is_subtype(t23(), t14());
+ (t24()) -> t24() when is_subtype(t24(), atom()),
+ is_subtype(t24(), t14()),
+ is_subtype(t24(), t4()).
-spec over(I :: integer()) -> R1 :: foo:typen();
- (A :: atom()) -> R2 :: foo:atomen();
- (T :: tuple()) -> R3 :: bar:typen().
+ (A :: atom()) -> R2 :: foo:atomen();
+ (T :: tuple()) -> R3 :: bar:typen().
--spec mod:t2() -> any().
+-spec mod:t2() -> any().
--spec handle_cast(Cast :: {'exchange', node(), [[name(),...]]}
- | {'del_member', name(), pid()},
- #state{}) -> {'noreply', #state{}}.
+-spec handle_cast(Cast :: {'exchange', node(), [[name(),...]]}
+ | {'del_member', name(), pid()},
+ #state{}) -> {'noreply', #state{}}.
--spec handle_cast(Cast ::
- {'exchange', node(), [[name(),...]]}
- | {'del_member', name(), pid()},
- #state{}) -> {'noreply', #state{}}.
+-spec handle_cast(Cast ::
+ {'exchange', node(), [[name(),...]]}
+ | {'del_member', name(), pid()},
+ #state{}) -> {'noreply', #state{}}.
-spec all(fun((T) -> boolean()), List :: [T]) ->
- boolean() when is_subtype(T, term()). % (*)
+ boolean() when is_subtype(T, term()). % (*)
--spec get_closest_pid(term()) ->
- Return :: pid()
- | {'error', {'no_process', term()}
- | {'no_such_group', term()}}.
+-spec get_closest_pid(term()) ->
+ Return :: pid()
+ | {'error', {'no_process', term()}
+ | {'no_such_group', term()}}.
-spec add( X :: integer()
- , Y :: integer()
- ) -> integer().
+ , Y :: integer()
+ ) -> integer().
--opaque attributes_data() ::
- [{'column', column()} | {'line', info_line()} |
- {'text', string()}] | {line(),column()}.
+-opaque attributes_data() ::
+ [{'column', column()} | {'line', info_line()} |
+ {'text', string()}] | {line(),column()}.
-record(r,{
f1 :: attributes_data(),
- f222 = foo:bar(34, #rec3{}, 234234234423,
- aassdsfsdfsdf, 2234242323) ::
- [t24() | 1|2|3|4|a|b|c|d|
- nonempty_maybe_improper_list(integer, any())],
- f333 :: [t24() | 1|2|3|4|a|b|c|d|
- nonempty_maybe_improper_list(integer, any())],
- f3 = x:y(),
- f4 = x:z() :: t99(),
- f17 :: 'undefined',
- f18 :: 1 | 2 | 'undefined',
- f19 = 3 :: integer()|undefined,
- f5 = 3 :: undefined|integer()}).
+ f222 = foo:bar(34, #rec3{}, 234234234423,
+ aassdsfsdfsdf, 2234242323) ::
+ [t24() | 1|2|3|4|a|b|c|d|
+ nonempty_maybe_improper_list(integer, any())],
+ f333 :: [t24() | 1|2|3|4|a|b|c|d|
+ nonempty_maybe_improper_list(integer, any())],
+ f3 = x:y(),
+ f4 = x:z() :: t99(),
+ f17 :: 'undefined',
+ f18 :: 1 | 2 | 'undefined',
+ f19 = 3 :: integer()|undefined,
+ f5 = 3 :: undefined|integer()}).
-record(state, {
- sequence_number = 1 :: integer()
- }).
+ sequence_number = 1 :: integer()
+ }).
highlighting(X) % Function definitions should be highlighted
@@ -230,12 +230,12 @@ highlighting(X) % Function definitions should be highlighted
'#1',atom,
$", atom, % atom should be ok
- $', atom,
+ $', atom,
"string$", atom, "string$", atom, % currently buggy I know...
"string\$", atom, % workaround for bug above
- "char $in string", atom,
+ "char $in string", atom,
'atom$', atom, 'atom$', atom,
'atom\$', atom,
@@ -270,15 +270,15 @@ highlighting(X) % Function definitions should be highlighted
erlang:anything(lists),
%% Guards
is_atom(foo), is_float(2.3), is_integer(32), is_number(4323.3),
- is_function(Fun), is_pid(self()),
+ is_function(Fun), is_pid(self()),
not_a_guard:is_list([]),
%% Other Types
atom, % not (currently) hightlighted
- 234234,
+ 234234,
234.43,
- [list, are, not, higlighted],
+ [list, are, not, higlighted],
{nor, is, tuple},
ok.
@@ -290,35 +290,35 @@ highlighting(X) % Function definitions should be highlighted
%% Indented
- % Right
+ % Right
-indent_basics(X, Y, Z)
+indent_basics(X, Y, Z)
when X > 42,
Z < 13;
Y =:= 4711 ->
%% comments
- % right comments
- case lists:filter(fun(_, AlongName,
- B,
- C) ->
- true
- end,
- [a,v,b])
+ % right comments
+ case lists:filter(fun(_, AlongName,
+ B,
+ C) ->
+ true
+ end,
+ [a,v,b])
of
- [] ->
- Y = 5 * 43,
- ok;
- [_|_] ->
- Y = 5 * 43,
- ok
+ [] ->
+ Y = 5 * 43,
+ ok;
+ [_|_] ->
+ Y = 5 * 43,
+ ok
end,
Y,
%% List, tuples and binaries
- [a,
+ [a,
b, c
],
- [ a,
+ [ a,
b, c
],
@@ -326,10 +326,10 @@ indent_basics(X, Y, Z)
a,
b
],
- {a,
+ {a,
b,c
},
- { a,
+ { a,
b,c
},
@@ -366,16 +366,16 @@ indent_basics(X, Y, Z)
c
),
- call(2#42423 bor
- #4234,
- 2#5432,
- other_arg),
+ call(2#42423 bor
+ #4234,
+ 2#5432,
+ other_arg),
ok;
-indent_basics(Xlongname,
- #struct{a=Foo,
- b=Bar},
- [X|
- Y]) ->
+indent_basics(Xlongname,
+ #struct{a=Foo,
+ b=Bar},
+ [X|
+ Y]) ->
testing_next_clause,
ok;
indent_basics( % AD added clause
@@ -408,295 +408,295 @@ indent_nested() ->
indent_icr(Z) -> % icr = if case receive
%% If
if Z >= 0 ->
- X = 43 div 4,
- foo(X);
+ X = 43 div 4,
+ foo(X);
Z =< 10 ->
- X = 43 div 4,
- foo(X);
+ X = 43 div 4,
+ foo(X);
Z == 5 orelse
Z == 7 ->
- X = 43 div 4,
- foo(X);
+ X = 43 div 4,
+ foo(X);
true ->
- if_works
+ if_works
end,
%% Case
case {Z, foo, bar} of
- {Z,_,_} ->
- X = 43 div 4,
- foo(X);
- {Z,_,_} when
- Z =:= 42 -> % AD line should be indented as a when
- X = 43 div 4,
- foo(X);
- {Z,_,_}
- when Z < 10 -> % AD when should be indented
- X = 43 div 4,
- foo(X);
- {Z,_,_}
- when % AD when should be indented
- Z < 10 % and the guards should follow when
- andalso % unsure about how though
- true ->
- X = 43 div 4,
- foo(X)
+ {Z,_,_} ->
+ X = 43 div 4,
+ foo(X);
+ {Z,_,_} when
+ Z =:= 42 -> % AD line should be indented as a when
+ X = 43 div 4,
+ foo(X);
+ {Z,_,_}
+ when Z < 10 -> % AD when should be indented
+ X = 43 div 4,
+ foo(X);
+ {Z,_,_}
+ when % AD when should be indented
+ Z < 10 % and the guards should follow when
+ andalso % unsure about how though
+ true ->
+ X = 43 div 4,
+ foo(X)
end,
%% begin
begin
- sune,
- X = 74234 + foo(8456) +
- 345 div 43,
- ok
+ sune,
+ X = 74234 + foo(8456) +
+ 345 div 43,
+ ok
end,
%% receive
- receive
- {Z,_,_} ->
- X = 43 div 4,
- foo(X);
- Z ->
- X = 43 div 4,
- foo(X)
+ receive
+ {Z,_,_} ->
+ X = 43 div 4,
+ foo(X);
+ Z ->
+ X = 43 div 4,
+ foo(X)
end,
receive
- {Z,_,_} ->
- X = 43 div 4,
- foo(X);
- Z % AD added clause
- when Z =:= 1 -> % This line should be indented by 2
- X = 43 div 4,
- foo(X);
- Z when % AD added clause
- Z =:= 2 -> % This line should be indented by 2
- X = 43 div 4,
- foo(X);
- Z ->
- X = 43 div 4,
- foo(X)
+ {Z,_,_} ->
+ X = 43 div 4,
+ foo(X);
+ Z % AD added clause
+ when Z =:= 1 -> % This line should be indented by 2
+ X = 43 div 4,
+ foo(X);
+ Z when % AD added clause
+ Z =:= 2 -> % This line should be indented by 2
+ X = 43 div 4,
+ foo(X);
+ Z ->
+ X = 43 div 4,
+ foo(X)
after infinity ->
- foo(X),
- asd(X),
- 5*43
+ foo(X),
+ asd(X),
+ 5*43
end,
receive
- after 10 ->
- foo(X),
- asd(X),
- 5*43
+ after 10 ->
+ foo(X),
+ asd(X),
+ 5*43
end,
ok.
indent_fun() ->
%% Changed fun to one indention level
- Var = spawn(fun(X)
- when X == 2;
- X > 10 ->
- hello,
- case Hello() of
- true when is_atom(X) ->
- foo;
- false ->
- bar
- end;
- (Foo) when is_atom(Foo),
- is_integer(X) ->
- X = 6* 45,
- Y = true andalso
- kalle
- end),
+ Var = spawn(fun(X)
+ when X == 2;
+ X > 10 ->
+ hello,
+ case Hello() of
+ true when is_atom(X) ->
+ foo;
+ false ->
+ bar
+ end;
+ (Foo) when is_atom(Foo),
+ is_integer(X) ->
+ X = 6* 45,
+ Y = true andalso
+ kalle
+ end),
%% check EEP37 named funs
Fn1 = fun Fact(N) when N > 0 ->
- F = Fact(N-1),
- N * F;
- Fact(0) ->
- 1
- end,
+ F = Fact(N-1),
+ N * F;
+ Fact(0) ->
+ 1
+ end,
%% check anonymous funs too
Fn2 = fun(0) ->
- 1;
- (N) ->
- N
- end,
+ 1;
+ (N) ->
+ N
+ end,
ok.
indent_try_catch() ->
try
- io:format(stdout, "Parsing file ~s, ",
- [St0#leex.xfile]),
- {ok,Line3,REAs,Actions,St3} =
- parse_rules(Xfile, Line2, Macs, St2)
+ io:format(stdout, "Parsing file ~s, ",
+ [St0#leex.xfile]),
+ {ok,Line3,REAs,Actions,St3} =
+ parse_rules(Xfile, Line2, Macs, St2)
catch
- exit:{badarg,R} ->
- foo(R),
- io:format(stdout,
- "ERROR reason ~p~n",
- R);
- error:R % AD added clause
- when R =:= 42 -> % when should be indented
- foo(R);
- error:R % AD added clause
- when % when should be indented
- R =:= 42 -> % but unsure about this (maybe 2 more)
- foo(R);
- error:R when % AD added clause
- R =:= foo -> % line should be 2 indented (works)
- foo(R);
- error:R ->
- foo(R),
- io:format(stdout,
- "ERROR reason ~p~n",
- R)
+ exit:{badarg,R} ->
+ foo(R),
+ io:format(stdout,
+ "ERROR reason ~p~n",
+ R);
+ error:R % AD added clause
+ when R =:= 42 -> % when should be indented
+ foo(R);
+ error:R % AD added clause
+ when % when should be indented
+ R =:= 42 -> % but unsure about this (maybe 2 more)
+ foo(R);
+ error:R when % AD added clause
+ R =:= foo -> % line should be 2 indented (works)
+ foo(R);
+ error:R ->
+ foo(R),
+ io:format(stdout,
+ "ERROR reason ~p~n",
+ R)
after
- foo('after'),
- file:close(Xfile)
+ foo('after'),
+ file:close(Xfile)
end;
indent_try_catch() ->
try
- foo(bar)
+ foo(bar)
of
- X when true andalso
- kalle ->
- io:format(stdout, "Parsing file ~s, ",
- [St0#leex.xfile]),
- {ok,Line3,REAs,Actions,St3} =
- parse_rules(Xfile, Line2, Macs, St2);
- X % AD added clause
- when false andalso % when should be 2 indented
- bengt ->
- gurka();
- X when % AD added clause
- false andalso % line should be 2 indented
- not bengt ->
- gurka();
- X ->
- io:format(stdout, "Parsing file ~s, ",
- [St0#leex.xfile]),
- {ok,Line3,REAs,Actions,St3} =
- parse_rules(Xfile, Line2, Macs, St2)
+ X when true andalso
+ kalle ->
+ io:format(stdout, "Parsing file ~s, ",
+ [St0#leex.xfile]),
+ {ok,Line3,REAs,Actions,St3} =
+ parse_rules(Xfile, Line2, Macs, St2);
+ X % AD added clause
+ when false andalso % when should be 2 indented
+ bengt ->
+ gurka();
+ X when % AD added clause
+ false andalso % line should be 2 indented
+ not bengt ->
+ gurka();
+ X ->
+ io:format(stdout, "Parsing file ~s, ",
+ [St0#leex.xfile]),
+ {ok,Line3,REAs,Actions,St3} =
+ parse_rules(Xfile, Line2, Macs, St2)
catch
- exit:{badarg,R} ->
- foo(R),
- io:format(stdout,
- "ERROR reason ~p~n",
- R);
- error:R ->
- foo(R),
- io:format(stdout,
- "ERROR reason ~p~n",
- R)
+ exit:{badarg,R} ->
+ foo(R),
+ io:format(stdout,
+ "ERROR reason ~p~n",
+ R);
+ error:R ->
+ foo(R),
+ io:format(stdout,
+ "ERROR reason ~p~n",
+ R)
after
- foo('after'),
- file:close(Xfile),
- bar(with_long_arg,
- with_second_arg)
+ foo('after'),
+ file:close(Xfile),
+ bar(with_long_arg,
+ with_second_arg)
end;
indent_try_catch() ->
try foo()
- after
- foo(),
- bar(with_long_arg,
- with_second_arg)
+ after
+ foo(),
+ bar(with_long_arg,
+ with_second_arg)
end.
indent_catch() ->
D = B +
- float(43.1),
+ float(43.1),
B = catch oskar(X),
- A = catch (baz +
- bax),
+ A = catch (baz +
+ bax),
catch foo(),
- C = catch B +
- float(43.1),
+ C = catch B +
+ float(43.1),
case catch foo(X) of
- A ->
- B
+ A ->
+ B
end,
case
- catch foo(X)
+ catch foo(X)
of
- A ->
- B
+ A ->
+ B
end,
case
- foo(X)
+ foo(X)
of
- A ->
- catch B,
- X
+ A ->
+ catch B,
+ X
end,
try sune of
- _ -> foo
+ _ -> foo
catch _:_ -> baf
end,
try
- sune
+ sune
of
- _ ->
- X = 5,
- (catch foo(X)),
- X + 10
+ _ ->
+ X = 5,
+ (catch foo(X)),
+ X + 10
catch _:_ -> baf
end,
try
- (catch sune)
+ (catch sune)
of
- _ ->
- catch foo() %% BUGBUG can't handle catch inside try without parentheses
+ _ ->
+ catch foo() %% BUGBUG can't handle catch inside try without parentheses
catch _:_ ->
- baf
+ baf
end,
try
- (catch exit())
+ (catch exit())
catch
- _ ->
- catch baf()
+ _ ->
+ catch baf()
end,
ok.
indent_binary() ->
X = lists:foldr(fun(M) ->
- <<Ma/binary, " ">>
- end, [], A),
+ <<Ma/binary, " ">>
+ end, [], A),
A = <<X/binary, 0:8>>,
B.
indent_comprehensions() ->
- %% I don't have a good idea how we want to handle this
+ %% I don't have a good idea how we want to handle this
%% but they are here to show how they are indented today.
- Result1 = [X ||
- #record{a=X} <- lists:seq(1, 10),
- true = (X rem 2)
- ],
+ Result1 = [X ||
+ #record{a=X} <- lists:seq(1, 10),
+ true = (X rem 2)
+ ],
Result2 = [X || <<X:32,_:32>> <= <<0:512>>,
- true = (X rem 2)
- ],
+ true = (X rem 2)
+ ],
- Binary1 = << <<X:8>> ||
- #record{a=X} <- lists:seq(1, 10),
- true = (X rem 2)
- >>,
+ Binary1 = << <<X:8>> ||
+ #record{a=X} <- lists:seq(1, 10),
+ true = (X rem 2)
+ >>,
Binary2 = << <<X:8>> || <<X:32,_:32>> <= <<0:512>>,
- true = (X rem 2)
- >>,
+ true = (X rem 2)
+ >>,
ok.
%% This causes an error in earlier erlang-mode versions.
foo() ->
[#foo{
- foo = foo}].
+ foo = foo}].
%% Record indentation
some_function_with_a_very_long_name() ->
@@ -704,20 +704,20 @@ some_function_with_a_very_long_name() ->
field1=a,
field2=b},
case dummy_function_with_a_very_very_long_name(x) of
- #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
- field1=a,
- field2=b} ->
- ok;
- Var = #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
- field1=a,
- field2=b} ->
- Var#'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
- field1=a,
- field2=b};
- #xyz{
- a=1,
- b=2} ->
- ok
+ #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
+ field1=a,
+ field2=b} ->
+ ok;
+ Var = #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
+ field1=a,
+ field2=b} ->
+ Var#'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
+ field1=a,
+ field2=b};
+ #xyz{
+ a=1,
+ b=2} ->
+ ok
end.
another_function_with_a_very_very_long_name() ->
@@ -726,45 +726,45 @@ another_function_with_a_very_very_long_name() ->
field2=1}.
some_function_name_xyz(xyzzy, #some_record{
- field1=Field1,
- field2=Field2}) ->
+ field1=Field1,
+ field2=Field2}) ->
SomeVariable = f(#'Some-long-record-name'{
- field_a = 1,
- 'inter-xyz-parameters' =
- #'Some-other-very-long-record-name'{
- field2 = Field1,
- field2 = Field2}}),
+ field_a = 1,
+ 'inter-xyz-parameters' =
+ #'Some-other-very-long-record-name'{
+ field2 = Field1,
+ field2 = Field2}}),
{ok, SomeVariable}.
commas_first() ->
{abc, [ {some_var, 1}
- , {some_other_var, 2}
- , {erlang_ftw, 9}
- , {erlang_cookie, 'cookie'}
- , {cmds,
- [ {one, "sudo ls"}
- , {one, "sudo ls"}
- , {two, "sudo ls"}
- , {three, "sudo ls"}
- , {four, "sudo ls"}
- , {three, "sudo ls"}
- ] }
- , {ssh_username, "yow"}
- , {cluster,
- [ {aaaa, [ {"10.198.55.12" , "" }
- , {"10.198.55.13" , "" }
- ] }
- , {bbbb, [ {"10.198.55.151", "" }
- , {"10.198.55.123", "" }
- , {"10.198.55.34" , "" }
- , {"10.198.55.85" , "" }
- , {"10.198.55.67" , "" }
- ] }
- , {cccc, [ {"10.198.55.68" , "" }
- , {"10.198.55.69" , "" }
- ] }
- ] }
- ]
+ , {some_other_var, 2}
+ , {erlang_ftw, 9}
+ , {erlang_cookie, 'cookie'}
+ , {cmds,
+ [ {one, "sudo ls"}
+ , {one, "sudo ls"}
+ , {two, "sudo ls"}
+ , {three, "sudo ls"}
+ , {four, "sudo ls"}
+ , {three, "sudo ls"}
+ ] }
+ , {ssh_username, "yow"}
+ , {cluster,
+ [ {aaaa, [ {"10.198.55.12" , "" }
+ , {"10.198.55.13" , "" }
+ ] }
+ , {bbbb, [ {"10.198.55.151", "" }
+ , {"10.198.55.123", "" }
+ , {"10.198.55.34" , "" }
+ , {"10.198.55.85" , "" }
+ , {"10.198.55.67" , "" }
+ ] }
+ , {cccc, [ {"10.198.55.68" , "" }
+ , {"10.198.55.69" , "" }
+ ] }
+ ] }
+ ]
}.
@@ -776,9 +776,9 @@ commas_first() ->
%% body, due to the function name being mistaken for a keyword
catcher(N) ->
try generate_exception(N) of
- Val -> {N, normal, Val}
+ Val -> {N, normal, Val}
catch
- throw:X -> {N, caught, thrown, X};
- exit:X -> {N, caught, exited, X};
- error:X -> {N, caught, error, X}
+ throw:X -> {N, caught, thrown, X};
+ exit:X -> {N, caught, exited, X};
+ error:X -> {N, caught, error, X}
end.
diff --git a/lib/tools/emacs/test.erl.orig b/lib/tools/emacs/test.erl.orig
index 2552c71baf..c0cf1749b6 100644
--- a/lib/tools/emacs/test.erl.orig
+++ b/lib/tools/emacs/test.erl.orig
@@ -1,4 +1,4 @@
-%% -*- erlang -*-
+%% -*- Mode: erlang; indent-tabs-mode: nil -*-
%%
%% %CopyrightBegin%
%%
@@ -27,7 +27,7 @@
%%% Created : 6 Oct 2009 by Dan Gudmundsson <[email protected]>
%%%-------------------------------------------------------------------
-%% Start off with syntax highlighting you have to verify this by looking here
+%% Start off with syntax highlighting you have to verify this by looking here
%% and see that the code looks alright
-module(test).
@@ -44,18 +44,18 @@ foo() ->
%% Module attributes should be highlighted
-export([t/1]).
--record(record1, {a,
- b,
+-record(record1, {a,
+ b,
c
}).
-record(record2, {
a,
b
}).
-
+
-record(record3, {a = 8#42423 bor
8#4234,
- b = 8#5432
+ b = 8#5432
bor 2#1010101
c = 123 +
234,
@@ -64,7 +64,7 @@ foo() ->
-record(record4, {
a = 8#42423 bor
8#4234,
- b = 8#5432
+ b = 8#5432
bor 2#1010101
c = 123 +
234,
@@ -79,31 +79,31 @@ foo() ->
-spec t(integer()) -> any().
--type ann() :: Var :: integer().
--type ann2() :: Var ::
- 'return'
- | 'return_white_spaces'
+-type ann() :: Var :: integer().
+-type ann2() :: Var ::
+ 'return'
+ | 'return_white_spaces'
| 'return_comments'
- | 'text' | ann().
--type paren() ::
- (ann2()).
--type t1() :: atom().
--type t2() :: [t1()].
--type t3(Atom) :: integer(Atom).
--type t4() :: t3(foobar).
--type t5() :: {t1(), t3(foo)}.
--type t6() :: 1 | 2 | 3 |
- 'foo' | 'bar'.
--type t7() :: [].
--type t71() :: [_].
+ | 'text' | ann().
+-type paren() ::
+ (ann2()).
+-type t1() :: atom().
+-type t2() :: [t1()].
+-type t3(Atom) :: integer(Atom).
+-type t4() :: t3(foobar).
+-type t5() :: {t1(), t3(foo)}.
+-type t6() :: 1 | 2 | 3 |
+ 'foo' | 'bar'.
+-type t7() :: [].
+-type t71() :: [_].
-type t8() :: {any(),none(),pid(),port(),
- reference(),float()}.
--type t9() :: [1|2|3|foo|bar] |
- list(a | b | c) | t71().
--type t10() :: {1|2|3|foo|t9()} | {}.
--type t11() :: 1..2.
--type t13() :: maybe_improper_list(integer(), t11()).
--type t14() :: [erl_scan:foo() |
+ reference(),float()}.
+-type t9() :: [1|2|3|foo|bar] |
+ list(a | b | c) | t71().
+-type t10() :: {1|2|3|foo|t9()} | {}.
+-type t11() :: 1..2.
+-type t13() :: maybe_improper_list(integer(), t11()).
+-type t14() :: [erl_scan:foo() |
%% Should be highlighted
term() |
bool() |
@@ -122,31 +122,31 @@ foo() ->
timeout() |
no_return() |
%% Should not be highlighted
- nonempty_() | nonlist() |
+ nonempty_() | nonlist() |
erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)].
-type t15() :: {binary(),<<>>,<<_:34>>,<<_:_*42>>,
<<_:3,_:_*14>>,<<>>} | [<<>>|<<_:34>>|<<_:16>>|
<<_:3,_:_*1472>>|<<_:19,_:_*14>>| <<_:34>>|
-<<_:34>>|<<_:34>>|<<_:34>>].
--type t16() :: fun().
--type t17() :: fun((...) -> paren()).
--type t18() :: fun(() -> t17() | t16()).
+<<_:34>>|<<_:34>>|<<_:34>>].
+-type t16() :: fun().
+-type t17() :: fun((...) -> paren()).
+-type t18() :: fun(() -> t17() | t16()).
-type t19() :: fun((t18()) -> t16()) |
fun((nonempty_maybe_improper_list('integer', any())|
1|2|3|a|b|<<_:3,_:_*14>>|integer()) ->
nonempty_maybe_improper_list('integer', any())|
-1|2|3|a|b|<<_:3,_:_*14>>|integer()).
--type t20() :: [t19(), ...].
--type t21() :: tuple().
--type t21(A) :: A.
--type t22() :: t21(integer()).
--type t23() :: #rec1{}.
--type t24() :: #rec2{a :: t23(), b :: [atom()]}.
--type t25() :: #rec3{f123 :: [t24() |
-1|2|3|4|a|b|c|d|
-nonempty_maybe_improper_list(integer, any())]}.
+1|2|3|a|b|<<_:3,_:_*14>>|integer()).
+-type t20() :: [t19(), ...].
+-type t21() :: tuple().
+-type t21(A) :: A.
+-type t22() :: t21(integer()).
+-type t23() :: #rec1{}.
+-type t24() :: #rec2{a :: t23(), b :: [atom()]}.
+-type t25() :: #rec3{f123 :: [t24() |
+1|2|3|4|a|b|c|d|
+nonempty_maybe_improper_list(integer, any())]}.
-type t26() :: #rec4{ a :: integer()
, b :: any()
}.
@@ -155,7 +155,7 @@ nonempty_maybe_improper_list(integer, any())]}.
}.
-type t99() ::
{t2(),t4(),t5(),t6(),t7(),t8(),t10(),t14(),
-t15(),t20(),t21(), t22(),t25()}.
+t15(),t20(),t21(), t22(),t25()}.
-spec t1(FooBar :: t99()) -> t99();
(t2()) -> t2();
(t4()) -> t4() when is_subtype(t4(), t24);
@@ -169,21 +169,21 @@ t15(),t20(),t21(), t22(),t25()}.
(A :: atom()) -> R2 :: foo:atomen();
(T :: tuple()) -> R3 :: bar:typen().
--spec mod:t2() -> any().
+-spec mod:t2() -> any().
--spec handle_cast(Cast :: {'exchange', node(), [[name(),...]]}
+-spec handle_cast(Cast :: {'exchange', node(), [[name(),...]]}
| {'del_member', name(), pid()},
#state{}) -> {'noreply', #state{}}.
--spec handle_cast(Cast ::
- {'exchange', node(), [[name(),...]]}
+-spec handle_cast(Cast ::
+ {'exchange', node(), [[name(),...]]}
| {'del_member', name(), pid()},
#state{}) -> {'noreply', #state{}}.
-spec all(fun((T) -> boolean()), List :: [T]) ->
boolean() when is_subtype(T, term()). % (*)
--spec get_closest_pid(term()) ->
+-spec get_closest_pid(term()) ->
Return :: pid()
| {'error', {'no_process', term()}
| {'no_such_group', term()}}.
@@ -192,23 +192,23 @@ t15(),t20(),t21(), t22(),t25()}.
, Y :: integer()
) -> integer().
--opaque attributes_data() ::
+-opaque attributes_data() ::
[{'column', column()} | {'line', info_line()} |
- {'text', string()}] | {line(),column()}.
+ {'text', string()}] | {line(),column()}.
-record(r,{
f1 :: attributes_data(),
-f222 = foo:bar(34, #rec3{}, 234234234423,
- aassdsfsdfsdf, 2234242323) ::
-[t24() | 1|2|3|4|a|b|c|d|
+f222 = foo:bar(34, #rec3{}, 234234234423,
+ aassdsfsdfsdf, 2234242323) ::
+[t24() | 1|2|3|4|a|b|c|d|
nonempty_maybe_improper_list(integer, any())],
-f333 :: [t24() | 1|2|3|4|a|b|c|d|
+f333 :: [t24() | 1|2|3|4|a|b|c|d|
nonempty_maybe_improper_list(integer, any())],
f3 = x:y(),
f4 = x:z() :: t99(),
f17 :: 'undefined',
f18 :: 1 | 2 | 'undefined',
f19 = 3 :: integer()|undefined,
-f5 = 3 :: undefined|integer()}).
+f5 = 3 :: undefined|integer()}).
-record(state, {
sequence_number = 1 :: integer()
@@ -230,12 +230,12 @@ highlighting(X) % Function definitions should be highlighted
'#1',atom,
$", atom, % atom should be ok
- $', atom,
-
+ $', atom,
+
"string$", atom, "string$", atom, % currently buggy I know...
"string\$", atom, % workaround for bug above
-
- "char $in string", atom,
+
+ "char $in string", atom,
'atom$', atom, 'atom$', atom,
'atom\$', atom,
@@ -270,18 +270,18 @@ highlighting(X) % Function definitions should be highlighted
erlang:anything(lists),
%% Guards
is_atom(foo), is_float(2.3), is_integer(32), is_number(4323.3),
- is_function(Fun), is_pid(self()),
+ is_function(Fun), is_pid(self()),
not_a_guard:is_list([]),
%% Other Types
atom, % not (currently) hightlighted
- 234234,
+ 234234,
234.43,
- [list, are, not, higlighted],
+ [list, are, not, higlighted],
{nor, is, tuple},
ok.
-
+
%%%
%%% Indentation
%%%
@@ -293,32 +293,32 @@ highlighting(X) % Function definitions should be highlighted
% Right
-indent_basics(X, Y, Z)
+indent_basics(X, Y, Z)
when X > 42,
Z < 13;
Y =:= 4711 ->
%% comments
% right comments
- case lists:filter(fun(_, AlongName,
- B,
+ case lists:filter(fun(_, AlongName,
+ B,
C) ->
true
- end,
+ end,
[a,v,b])
of
[] ->
Y = 5 * 43,
ok;
- [_|_] ->
+ [_|_] ->
Y = 5 * 43,
ok
end,
Y,
%% List, tuples and binaries
- [a,
+ [a,
b, c
],
- [ a,
+ [ a,
b, c
],
@@ -326,10 +326,10 @@ Y =:= 4711 ->
a,
b
],
- {a,
+ {a,
b,c
},
- { a,
+ { a,
b,c
},
@@ -337,7 +337,7 @@ Y =:= 4711 ->
a,
b
},
-
+
<<1:8,
2:8
>>,
@@ -359,21 +359,21 @@ Y =:= 4711 ->
c
),
-
+
(
a,
b,
c
),
- call(2#42423 bor
+ call(2#42423 bor
#4234,
2#5432,
other_arg),
ok;
-indent_basics(Xlongname,
+indent_basics(Xlongname,
#struct{a=Foo,
- b=Bar},
+ b=Bar},
[X|
Y]) ->
testing_next_clause,
@@ -451,13 +451,13 @@ indent_icr(Z) -> % icr = if case receive
%% receive
- receive
+ receive
{Z,_,_} ->
X = 43 div 4,
foo(X);
Z ->
X = 43 div 4,
- foo(X)
+ foo(X)
end,
receive
{Z,_,_} ->
@@ -473,33 +473,33 @@ indent_icr(Z) -> % icr = if case receive
foo(X);
Z ->
X = 43 div 4,
- foo(X)
+ foo(X)
after infinity ->
foo(X),
asd(X),
5*43
end,
receive
- after 10 ->
+ after 10 ->
foo(X),
asd(X),
5*43
end,
ok.
-
+
indent_fun() ->
%% Changed fun to one indention level
-Var = spawn(fun(X)
+Var = spawn(fun(X)
when X == 2;
- X > 10 ->
+ X > 10 ->
hello,
- case Hello() of
- true when is_atom(X) ->
+ case Hello() of
+ true when is_atom(X) ->
foo;
false ->
bar
end;
- (Foo) when is_atom(Foo),
+ (Foo) when is_atom(Foo),
is_integer(X) ->
X = 6* 45,
Y = true andalso
@@ -522,14 +522,14 @@ Fact(0) ->
indent_try_catch() ->
try
- io:format(stdout, "Parsing file ~s, ",
+ io:format(stdout, "Parsing file ~s, ",
[St0#leex.xfile]),
- {ok,Line3,REAs,Actions,St3} =
+ {ok,Line3,REAs,Actions,St3} =
parse_rules(Xfile, Line2, Macs, St2)
catch
exit:{badarg,R} ->
foo(R),
- io:format(stdout,
+ io:format(stdout,
"ERROR reason ~p~n",
R);
error:R % AD added clause
@@ -544,7 +544,7 @@ indent_try_catch() ->
foo(R);
error:R ->
foo(R),
- io:format(stdout,
+ io:format(stdout,
"ERROR reason ~p~n",
R)
after
@@ -577,12 +577,12 @@ indent_try_catch() ->
catch
exit:{badarg,R} ->
foo(R),
- io:format(stdout,
+ io:format(stdout,
"ERROR reason ~p~n",
R);
error:R ->
foo(R),
- io:format(stdout,
+ io:format(stdout,
"ERROR reason ~p~n",
R)
after
@@ -593,7 +593,7 @@ indent_try_catch() ->
end;
indent_try_catch() ->
try foo()
- after
+ after
foo(),
bar(with_long_arg,
with_second_arg)
@@ -602,16 +602,16 @@ indent_try_catch() ->
indent_catch() ->
D = B +
float(43.1),
-
+
B = catch oskar(X),
-
- A = catch (baz +
+
+ A = catch (baz +
bax),
catch foo(),
- C = catch B +
+ C = catch B +
float(43.1),
-
+
case catch foo(X) of
A ->
B
@@ -673,9 +673,9 @@ indent_binary() ->
indent_comprehensions() ->
-%% I don't have a good idea how we want to handle this
+%% I don't have a good idea how we want to handle this
%% but they are here to show how they are indented today.
-Result1 = [X ||
+Result1 = [X ||
#record{a=X} <- lists:seq(1, 10),
true = (X rem 2)
],
@@ -683,7 +683,7 @@ Result2 = [X || <<X:32,_:32>> <= <<0:512>>,
true = (X rem 2)
],
-Binary1 = << <<X:8>> ||
+Binary1 = << <<X:8>> ||
#record{a=X} <- lists:seq(1, 10),
true = (X rem 2)
>>,
diff --git a/lib/tools/examples/xref_examples.erl b/lib/tools/examples/xref_examples.erl
index 4c082195a2..f7e71c9708 100644
--- a/lib/tools/examples/xref_examples.erl
+++ b/lib/tools/examples/xref_examples.erl
@@ -7,7 +7,7 @@
%% ${HOME}/unused_locals.txt.
script() ->
Root = code:root_dir(),
- Dir = os:getenv("HOME"),
+ {ok,[[Dir]]} = init:get_argument(home),
Server = s,
xref:start(Server),
{ok, _Relname} = xref:add_release(Server, code:lib_dir(), {name,otp}),
diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl
index 92c10cc306..5517882ffa 100644
--- a/lib/tools/src/cover.erl
+++ b/lib/tools/src/cover.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -2053,7 +2053,7 @@ munge_expr({bin_element,Line,Value,Size,TypeSpecifierList}, Vars) ->
{MungedValue,Vars2} = munge_expr(Value, Vars),
{MungedSize,Vars3} = munge_expr(Size, Vars2),
{{bin_element,Line,MungedValue,MungedSize,TypeSpecifierList},Vars3};
-munge_expr(Form, Vars) -> % var|char|integer|float|string|atom|nil|eof|default
+munge_expr(Form, Vars) ->
{Form, Vars}.
munge_exprs([Expr|Exprs], Vars, MungedExprs) when Vars#vars.is_guard=:=true,
@@ -2414,8 +2414,8 @@ do_analyse_to_file1(Module, OutFile, ErlFile, HTML) ->
{ok, InFd} ->
case file:open(OutFile, [write,raw,delayed_write]) of
{ok, OutFd} ->
+ Enc = encoding(ErlFile),
if HTML ->
- Encoding = encoding(ErlFile),
Header =
["<!DOCTYPE HTML PUBLIC "
"\"-//W3C//DTD HTML 3.2 Final//EN\">\n"
@@ -2423,13 +2423,14 @@ do_analyse_to_file1(Module, OutFile, ErlFile, HTML) ->
"<head>\n"
"<meta http-equiv=\"Content-Type\""
" content=\"text/html; charset=",
- Encoding,"\"/>\n"
+ html_encoding(Enc),"\"/>\n"
"<title>",OutFile,"</title>\n"
"</head>"
"<body style='background-color: white;"
" color: black'>\n"
"<pre>\n"],
- ok = file:write(OutFd,Header);
+ H1Bin = unicode:characters_to_binary(Header,Enc,Enc),
+ ok = file:write(OutFd,H1Bin);
true -> ok
end,
@@ -2443,12 +2444,15 @@ do_analyse_to_file1(Module, OutFile, ErlFile, HTML) ->
string:right(integer_to_list(H), 2, $0),
string:right(integer_to_list(Mi), 2, $0),
string:right(integer_to_list(S), 2, $0)]),
- ok = file:write(OutFd,
- ["File generated from ",ErlFile," by COVER ",
+
+ H2Bin = unicode:characters_to_binary(
+ ["File generated from ",ErlFile," by COVER ",
Timestamp,"\n\n"
"**************************************"
"**************************************"
- "\n\n"]),
+ "\n\n"],
+ Enc, Enc),
+ ok = file:write(OutFd, H2Bin),
Pattern = {#bump{module=Module,line='$1',_='_'},'$2'},
MS = [{Pattern,[{is_integer,'$1'},{'>','$1',0}],[{{'$1','$2'}}]}],
@@ -2752,16 +2756,22 @@ pmap_collect(Mons,Acc) ->
end.
%%%-----------------------------------------------------------------
-%%% Read encoding from source file
+%%% Decide which encoding to use when analyzing to file.
+%%% The target file contains the file path, so if either the file name
+%%% encoding or the encoding of the source file is utf8, then we need
+%%% to use utf8.
encoding(File) ->
- Encoding =
- case epp:read_encoding(File) of
- none ->
- epp:default_encoding();
- E ->
- E
- end,
- html_encoding(Encoding).
+ case file:native_name_encoding() of
+ latin1 ->
+ case epp:read_encoding(File) of
+ none ->
+ epp:default_encoding();
+ E ->
+ E
+ end;
+ utf8 ->
+ utf8
+ end.
html_encoding(latin1) ->
"iso-8859-1";
diff --git a/lib/tools/src/fprof.erl b/lib/tools/src/fprof.erl
index 8db23dd151..d1a4624419 100644
--- a/lib/tools/src/fprof.erl
+++ b/lib/tools/src/fprof.erl
@@ -1636,6 +1636,11 @@ trace_handler({trace_ts, Pid, gc_major_start, _Func, TS} = Trace, Table, _, Dump
dump_stack(Dump, get(Pid), Trace),
trace_gc_start(Table, Pid, TS),
TS;
+
+trace_handler({trace_ts, Pid, gc_start, _Func, TS} = Trace, Table, _, Dump) ->
+ dump_stack(Dump, get(Pid), Trace),
+ trace_gc_start(Table, Pid, TS),
+ TS;
%%
%% gc_end
@@ -1648,6 +1653,12 @@ trace_handler({trace_ts, Pid, gc_major_end, _Func, TS} = Trace, Table, _, Dump)
dump_stack(Dump, get(Pid), Trace),
trace_gc_end(Table, Pid, TS),
TS;
+
+trace_handler({trace_ts, Pid, gc_end, _Func, TS} = Trace, Table, _, Dump) ->
+ dump_stack(Dump, get(Pid), Trace),
+ trace_gc_end(Table, Pid, TS),
+ TS;
+
%%
%% link
trace_handler({trace_ts, Pid, link, _OtherPid, TS} = Trace,
@@ -1691,6 +1702,12 @@ trace_handler({trace_ts, Pid, send, _OtherPid, _Msg, TS} = Trace,
dump_stack(Dump, get(Pid), Trace),
TS;
%%
+%% send_to_non_existing_process
+trace_handler({trace_ts, Pid, send_to_non_existing_process, _OtherPid, _Msg, TS} = Trace,
+ _Table, _, Dump) ->
+ dump_stack(Dump, get(Pid), Trace),
+ TS;
+%%
%% 'receive'
trace_handler({trace_ts, Pid, 'receive', _Msg, TS} = Trace,
_Table, _, Dump) ->
diff --git a/lib/tools/src/lcnt.erl b/lib/tools/src/lcnt.erl
index 23d66b084e..d881fedbd5 100644
--- a/lib/tools/src/lcnt.erl
+++ b/lib/tools/src/lcnt.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -698,19 +698,47 @@ stats2record([{{File,Line},{Tries,Colls,{S,Ns,N}}}|Stats]) ->
nt = N} | stats2record(Stats)];
stats2record([]) -> [].
+
clean_id_creation(Id) when is_pid(Id) ->
Bin = term_to_binary(Id),
- <<H:3/binary, L:16, Node:L/binary, Ids:8/binary, _Creation/binary>> = Bin,
- Bin2 = list_to_binary([H, bytes16(L), Node, Ids, 0]),
+ <<H:3/binary, Rest/binary>> = Bin,
+ <<131, PidTag, AtomTag>> = H,
+ LL = atomlen_bits(AtomTag),
+ CL = creation_bits(PidTag),
+ <<L:LL, Node:L/binary, Ids:8/binary, _Creation/binary>> = Rest,
+ Bin2 = list_to_binary([H, <<L:LL>>, Node, Ids, <<0:CL>>]),
binary_to_term(Bin2);
clean_id_creation(Id) when is_port(Id) ->
Bin = term_to_binary(Id),
- <<H:3/binary, L:16, Node:L/binary, Ids:4/binary, _Creation/binary>> = Bin,
- Bin2 = list_to_binary([H, bytes16(L), Node, Ids, 0]),
+ <<H:3/binary, Rest/binary>> = Bin,
+ <<131, PortTag, AtomTag>> = H,
+ LL = atomlen_bits(AtomTag),
+ CL = creation_bits(PortTag),
+ <<L:LL, Node:L/binary, Ids:4/binary, _Creation/binary>> = Rest,
+ Bin2 = list_to_binary([H, <<L:LL>>, Node, Ids, <<0:CL>>]),
binary_to_term(Bin2);
clean_id_creation(Id) ->
Id.
+-define(PID_EXT, $g).
+-define(NEW_PID_EXT, $X).
+-define(PORT_EXT, $f).
+-define(NEW_PORT_EXT, $Y).
+-define(ATOM_EXT, $d).
+-define(SMALL_ATOM_EXT, $s).
+-define(ATOM_UTF8_EXT, $v).
+-define(SMALL_ATOM_UTF8_EXT, $w).
+
+atomlen_bits(?ATOM_EXT) -> 16;
+atomlen_bits(?SMALL_ATOM_EXT) -> 8;
+atomlen_bits(?ATOM_UTF8_EXT) -> 16;
+atomlen_bits(?SMALL_ATOM_UTF8_EXT) -> 8.
+
+creation_bits(?PID_EXT) -> 8;
+creation_bits(?NEW_PID_EXT) -> 32;
+creation_bits(?PORT_EXT) -> 8;
+creation_bits(?NEW_PORT_EXT) -> 32.
+
%% serializer
state_default(Field) -> proplists:get_value(Field, state2list(#state{})).
@@ -936,12 +964,24 @@ strings([S|Ss], Out) -> strings(Ss, Out ++ term2string("~ts", [S])).
term2string({M,F,A}) when is_atom(M), is_atom(F), is_integer(A) -> term2string("~p:~p/~p", [M,F,A]);
term2string(Term) when is_port(Term) ->
% ex #Port<6442.816>
- <<_:3/binary, L:16, Node:L/binary, Ids:32, _/binary>> = term_to_binary(Term),
- term2string("#Port<~s.~w>", [Node, Ids]);
+ case term_to_binary(Term) of
+ <<_:2/binary, ?SMALL_ATOM_UTF8_EXT, L:8, Node:L/binary, Ids:32, _/binary>> ->
+ term2string("#Port<~ts.~w>", [Node, Ids]);
+ <<_:2/binary, ?ATOM_UTF8_EXT, L:16, Node:L/binary, Ids:32, _/binary>> ->
+ term2string("#Port<~ts.~w>", [Node, Ids]);
+ <<_:2/binary, ?ATOM_EXT, L:16, Node:L/binary, Ids:32, _/binary>> ->
+ term2string("#Port<~s.~w>", [Node, Ids])
+ end;
term2string(Term) when is_pid(Term) ->
% ex <0.80.0>
- <<_:3/binary, L:16, Node:L/binary, Ids:32, Serial:32, _/binary>> = term_to_binary(Term),
- term2string("<~s.~w.~w>", [Node, Ids, Serial]);
+ case term_to_binary(Term) of
+ <<_:2/binary, ?SMALL_ATOM_UTF8_EXT, L:8, Node:L/binary, Ids:32, Serial:32, _/binary>> ->
+ term2string("<~ts.~w.~w>", [Node, Ids, Serial]);
+ <<_:2/binary, ?ATOM_UTF8_EXT, L:16, Node:L/binary, Ids:32, Serial:32, _/binary>> ->
+ term2string("<~ts.~w.~w>", [Node, Ids, Serial]);
+ <<_:2/binary, ?ATOM_EXT, L:16, Node:L/binary, Ids:32, Serial:32, _/binary>> ->
+ term2string("<~s.~w.~w>", [Node, Ids, Serial])
+ end;
term2string(Term) -> term2string("~w", [Term]).
term2string(Format, Terms) -> lists:flatten(io_lib:format(Format, Terms)).
diff --git a/lib/tools/src/make.erl b/lib/tools/src/make.erl
index 26378f28a0..ce30156db6 100644
--- a/lib/tools/src/make.erl
+++ b/lib/tools/src/make.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@
-include_lib("kernel/include/file.hrl").
--define(MakeOpts,[noexec,load,netload,noload]).
+-define(MakeOpts,[noexec,load,netload,noload,emake]).
all_or_nothing() ->
case all() of
@@ -43,29 +43,30 @@ all() ->
all([]).
all(Options) ->
- {MakeOpts,CompileOpts} = sort_options(Options,[],[]),
- case read_emakefile('Emakefile',CompileOpts) of
- Files when is_list(Files) ->
- do_make_files(Files,MakeOpts);
- error ->
- error
- end.
+ run_emake(undefined, Options).
files(Fs) ->
files(Fs, []).
files(Fs0, Options) ->
Fs = [filename:rootname(F,".erl") || F <- Fs0],
+ run_emake(Fs, Options).
+
+run_emake(Mods, Options) ->
{MakeOpts,CompileOpts} = sort_options(Options,[],[]),
- case get_opts_from_emakefile(Fs,'Emakefile',CompileOpts) of
+ Emake = get_emake(Options),
+ case normalize_emake(Emake, Mods, CompileOpts) of
Files when is_list(Files) ->
- do_make_files(Files,MakeOpts);
- error -> error
+ do_make_files(Files,MakeOpts);
+ error ->
+ error
end.
do_make_files(Fs, Opts) ->
process(Fs, lists:member(noexec, Opts), load_opt(Opts)).
+sort_options([{emake, _}=H|T],Make,Comp) ->
+ sort_options(T,[H|Make],Comp);
sort_options([H|T],Make,Comp) ->
case lists:member(H,?MakeOpts) of
@@ -89,20 +90,35 @@ sort_options([],Make,Comp) ->
%%%
%%% These elements are converted to [{ModList,OptList},...]
%%% ModList is a list of modulenames (strings)
-read_emakefile(Emakefile,Opts) ->
- case file:consult(Emakefile) of
- {ok,Emake} ->
+
+normalize_emake(EmakeRaw, Mods, Opts) ->
+ case EmakeRaw of
+ {ok, Emake} when Mods =:= undefined ->
transform(Emake,Opts,[],[]);
- {error,enoent} ->
+ {ok, Emake} when is_list(Mods) ->
+ ModsOpts = transform(Emake,Opts,[],[]),
+ ModStrings = [coerce_2_list(M) || M <- Mods],
+ get_opts_from_emakefile(ModsOpts,ModStrings,Opts,[]);
+ {error,enoent} when Mods =:= undefined ->
%% No Emakefile found - return all modules in current
%% directory and the options given at command line
- Mods = [filename:rootname(F) || F <- filelib:wildcard("*.erl")],
+ CwdMods = [filename:rootname(F) || F <- filelib:wildcard("*.erl")],
+ [{CwdMods, Opts}];
+ {error,enoent} when is_list(Mods) ->
[{Mods, Opts}];
- {error,Other} ->
- io:format("make: Trouble reading 'Emakefile':~n~tp~n",[Other]),
+ {error, Error} ->
+ io:format("make: Trouble reading 'Emakefile':~n~tp~n",[Error]),
error
end.
+get_emake(Opts) ->
+ case proplists:get_value(emake, Opts, false) of
+ false ->
+ file:consult('Emakefile');
+ OptsEmake ->
+ {ok, OptsEmake}
+ end.
+
transform([{Mod,ModOpts}|Emake],Opts,Files,Already) ->
case expand(Mod,Already) of
[] ->
@@ -143,31 +159,19 @@ expand(Mod,Already) ->
end
end.
-%%% Reads the given Emakefile to see if there are any specific compile
+%%% Reads the given Emake to see if there are any specific compile
%%% options given for the modules.
-get_opts_from_emakefile(Mods,Emakefile,Opts) ->
- case file:consult(Emakefile) of
- {ok,Emake} ->
- Modsandopts = transform(Emake,Opts,[],[]),
- ModStrings = [coerce_2_list(M) || M <- Mods],
- get_opts_from_emakefile2(Modsandopts,ModStrings,Opts,[]);
- {error,enoent} ->
- [{Mods, Opts}];
- {error,Other} ->
- io:format("make: Trouble reading 'Emakefile':~n~tp~n",[Other]),
- error
- end.
-get_opts_from_emakefile2([{MakefileMods,O}|Rest],Mods,Opts,Result) ->
+get_opts_from_emakefile([{MakefileMods,O}|Rest],Mods,Opts,Result) ->
case members(Mods,MakefileMods,[],Mods) of
{[],_} ->
- get_opts_from_emakefile2(Rest,Mods,Opts,Result);
+ get_opts_from_emakefile(Rest,Mods,Opts,Result);
{I,RestOfMods} ->
- get_opts_from_emakefile2(Rest,RestOfMods,Opts,[{I,O}|Result])
+ get_opts_from_emakefile(Rest,RestOfMods,Opts,[{I,O}|Result])
end;
-get_opts_from_emakefile2([],[],_Opts,Result) ->
+get_opts_from_emakefile([],[],_Opts,Result) ->
Result;
-get_opts_from_emakefile2([],RestOfMods,Opts,Result) ->
+get_opts_from_emakefile([],RestOfMods,Opts,Result) ->
[{RestOfMods,Opts}|Result].
members([H|T],MakefileMods,I,Rest) ->
@@ -286,11 +290,12 @@ coerce_2_list(X) when is_atom(X) ->
coerce_2_list(X) ->
X.
-%%% If you an include file is found with a modification
+%%% If an include file is found with a modification
%%% time larger than the modification time of the object
%%% file, return true. Otherwise return false.
check_includes(File, IncludePath, ObjMTime) ->
- Path = [filename:dirname(File)|IncludePath],
+ {ok,Cwd} = file:get_cwd(),
+ Path = [Cwd,filename:dirname(File)|IncludePath],
case epp:open(File, Path, []) of
{ok, Epp} ->
check_includes2(Epp, File, ObjMTime);
@@ -317,5 +322,7 @@ check_includes2(Epp, File, ObjMTime) ->
epp:close(Epp),
false;
{error, _Error} ->
+ check_includes2(Epp, File, ObjMTime);
+ {warning, _Warning} ->
check_includes2(Epp, File, ObjMTime)
end.
diff --git a/lib/tools/src/tags.erl b/lib/tools/src/tags.erl
index b833d96c19..fff67eb0fd 100644
--- a/lib/tools/src/tags.erl
+++ b/lib/tools/src/tags.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/tools/src/tools.app.src b/lib/tools/src/tools.app.src
index a00969eabe..12f0cfd2df 100644
--- a/lib/tools/src/tools.app.src
+++ b/lib/tools/src/tools.app.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -40,8 +40,7 @@
{env, [{file_util_search_methods,[{"", ""}, {"ebin", "esrc"}, {"ebin", "src"}]}
]
},
- {runtime_dependencies, ["stdlib-2.5","runtime_tools-1.8.14",
- "kernel-3.0","inets-5.10","erts-7.0",
- "compiler-5.0"]}
+ {runtime_dependencies, ["stdlib-3.1","runtime_tools-1.8.14",
+ "kernel-3.0","erts-7.0","compiler-5.0"]}
]
}.
diff --git a/lib/tools/src/xref_base.erl b/lib/tools/src/xref_base.erl
index bb9815f9b0..8d2cc07e40 100644
--- a/lib/tools/src/xref_base.erl
+++ b/lib/tools/src/xref_base.erl
@@ -746,7 +746,7 @@ read_a_module({Dir, BaseName}, AppName, Builtins, Verbose, Warnings, Mode) ->
message(Warnings, no_debug_info, [File]),
no;
{ok, M, Data, UnresCalls0} ->
- message(Verbose, done, [File]),
+ message(Verbose, done_file, [File]),
%% Remove duplicates. Identical unresolved calls on the
%% same line are counted as _one_ unresolved call.
UnresCalls = usort(UnresCalls0),
@@ -809,7 +809,8 @@ abst(File, Builtins, _Mode = functions) ->
{exports,X0}, {attributes,A}]}} ->
%% R9C-
Forms0 = epp:interpret_file_attribute(Code),
- {_,_,Forms,_} = sys_pre_expand:module(Forms0, []),
+ Forms1 = erl_expand_records:module(Forms0, []),
+ Forms = erl_internal:add_predefined_functions(Forms1),
X = mfa_exports(X0, A, M),
D = deprecated(A, X, M),
xref_reader:module(M, Forms, Builtins, X, D);
@@ -1842,6 +1843,8 @@ message(true, What, Arg) ->
set_up ->
io:format("Setting up...", Arg);
done ->
+ io:format("done~n", Arg);
+ done_file ->
io:format("done reading ~ts~n", Arg);
error ->
io:format("error~n", Arg);
diff --git a/lib/tools/src/xref_reader.erl b/lib/tools/src/xref_reader.erl
index 41b93caaeb..88f92df35a 100644
--- a/lib/tools/src/xref_reader.erl
+++ b/lib/tools/src/xref_reader.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -42,17 +42,15 @@
%% experimental; -xref(FunEdge) is recognized.
lattrs=[], % local calls, {{mfa(),mfa()},Line}
xattrs=[], % external calls, -"-
- battrs=[] % badly formed xref attributes, term().
+ battrs=[] % badly formed xref attributes, term().
}).
-include("xref.hrl").
-%% sys_pre_expand has modified the forms slightly compared to what
-%% erl_id_trans recognizes.
-
%% The versions of the abstract code are as follows:
-%% R7: abstract_v1
-%% R8: abstract_v2
+%% R7: abstract_v1
+%% R8: abstract_v2
+%% R9C: raw_abstract_v1
%% -> {ok, Module, {DefAt, CallAt, LC, XC, X, Attrs}, Unresolved}} | EXIT
%% Attrs = {ALC, AXC, Bad}
@@ -92,7 +90,12 @@ form({function, Anno, Name, Arity, Clauses}, S) ->
Line = erl_anno:line(Anno),
S2 = S1#xrefr{def_at = [{MFA,Line} | S#xrefr.def_at]},
S3 = clauses(Clauses, S2),
- S3#xrefr{function = []}.
+ S3#xrefr{function = []};
+form(_, S) ->
+ %% OTP 20. Other uninteresting forms such as {eof, _} and {warning, _}.
+ %% Exposed because sys_pre_expand is no longer run.
+ S.
+
clauses(Cls, S) ->
#xrefr{funvars = FunVars, matches = Matches} = S,
@@ -109,6 +112,8 @@ clauses([{clause, _Line, _H, G, B} | Cs], FunVars, Matches, S) ->
clauses([], _FunVars, _Matches, S) ->
S.
+attr(NotList, Ln, M, Fun, AL, AX, B, S) when not is_list(NotList) ->
+ attr([NotList], Ln, M, Fun, AL, AX, B, S);
attr([E={From, To} | As], Ln, M, Fun, AL, AX, B, S) ->
case mfa(From, M) of
{_, _, MFA} when MFA =:= Fun; [] =:= Fun ->
@@ -154,6 +159,15 @@ expr({'try',_Line,Es,Scs,Ccs,As}, S) ->
S2 = clauses(Scs, S1),
S3 = clauses(Ccs, S2),
expr(As, S3);
+expr({'fun', Line, {function,M,F,A}}, S)
+ when is_atom(M), is_atom(F), is_integer(A) ->
+ %% This is the old format for external funs, generated by a pre-R15
+ %% compiler. Exposed in OTP 20 because sys_pre_expand is no longer
+ %% run.
+ Fun = {'fun', Line, {function, {atom,Line,M},
+ {atom,Line,F},
+ {integer,Line,A}}},
+ expr(Fun, S);
expr({'fun', Line, {function, {atom,_,Mod},
{atom,_,Name},
{integer,_,Arity}}}, S) ->
@@ -168,14 +182,21 @@ expr({'fun', Line, {function, Mod, Name, _Arity}}, S) ->
%% New format in R15. M:F/A (one or more variables).
As = {var, Line, '_'},
external_call(erlang, apply, [Mod, Name, As], Line, true, S);
+%% Only abstract_v1 and abstract_v2.
expr({'fun', Line, {function, Name, Arity}, _Extra}, S) ->
%% Added in R8.
handle_call(local, S#xrefr.module, Name, Arity, Line, S);
expr({'fun', _Line, {clauses, Cs}, _Extra}, S) ->
clauses(Cs, S);
-expr({named_fun, _Line, '_', Cs, _Extra}, S) ->
+%% End abstract_v1 and abstract_v2.
+expr({'fun', Line, {function, Name, Arity}}, S) ->
+ %% Added in OTP 20.
+ handle_call(local, S#xrefr.module, Name, Arity, Line, S);
+expr({'fun', _Line, {clauses, Cs}}, S) ->
+ clauses(Cs, S);
+expr({named_fun, _Line, '_', Cs}, S) ->
clauses(Cs, S);
-expr({named_fun, _Line, Name, Cs, _Extra}, S) ->
+expr({named_fun, _Line, Name, Cs}, S) ->
S1 = S#xrefr{funvars = [Name | S#xrefr.funvars]},
clauses(Cs, S1);
expr({call, Line, {atom, _, Name}, As}, S) ->
@@ -193,7 +214,12 @@ expr({match, _Line, {var,_,Var}, {'fun', _, {clauses, Cs}, _Extra}}, S) ->
%% that are passed around by the "expansion" of list comprehension.
S1 = S#xrefr{funvars = [Var | S#xrefr.funvars]},
clauses(Cs, S1);
-expr({match, _Line, {var,_,Var}, {named_fun, _, _, _, _} = Fun}, S) ->
+expr({match, _Line, {var,_,Var}, {'fun', _, {clauses, Cs}}}, S) ->
+ %% OTP 20. Exposed because sys_pre_expand is no longer run.
+ S1 = S#xrefr{funvars = [Var | S#xrefr.funvars]},
+ clauses(Cs, S1);
+expr({match, _Line, {var,_,Var}, {named_fun, _, _, _} = Fun}, S) ->
+ %% OTP 20. Exposed because sys_pre_expand is no longer run.
S1 = S#xrefr{funvars = [Var | S#xrefr.funvars]},
expr(Fun, S1);
expr({match, _Line, {var,_,Var}, E}, S) ->
@@ -295,10 +321,17 @@ check_funarg(W, ArgsList, Line, S) ->
expr(ArgsList, S1).
funarg({'fun', _, _Clauses, _Extra}, _S) -> true;
+funarg({'fun', _, {clauses, _}}, _S) ->
+ %% OTP 20. sys_pre_expand not run.
+ true;
+funarg({'fun', _, {function, _, _}}, _S) ->
+ %% OTP 20. sys_pre_expand not run.
+ true;
funarg({'fun', _, {function,_,_,_}}, _S) ->
%% New abstract format for fun M:F/A in R15.
true;
-funarg({named_fun, _, _, _, _}, _S) ->
+funarg({named_fun, _, _, _}, _S) ->
+ %% OTP 20. sys_pre_expand not run.
true;
funarg({var, _, Var}, S) -> member(Var, S#xrefr.funvars);
funarg(_, _S) -> false.
diff --git a/lib/tools/test/Makefile b/lib/tools/test/Makefile
index 84c4e56aff..2b7b17afb3 100644
--- a/lib/tools/test/Makefile
+++ b/lib/tools/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
+# Copyright Ericsson AB 1997-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -52,8 +52,8 @@ RELSYSDIR = $(RELEASE_PATH)/tools_test
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_MAKE_FLAGS +=
-ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/percept/include
+ERL_MAKE_FLAGS +=
+ERL_COMPILE_FLAGS +=
EBIN = .
diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl
index b4c9264b30..90e113c178 100644
--- a/lib/tools/test/cover_SUITE.erl
+++ b/lib/tools/test/cover_SUITE.erl
@@ -1001,41 +1001,40 @@ otp_6115(Config) when is_list(Config) ->
%% Cover compile f1, but not f2
{ok, f1} = cover:compile(f1),
+ %% This test used to ensure that a process containing a
+ %% fun refering to cover compiled code was killed.
+ %% check_process_code may however ignore funs as of ERTS
+ %% version 8.1. The test has therefore been rewritten to
+ %% check that a process with a direct reference (in this
+ %% case a return address) to the code is killed.
+ %%
%% 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
+ %% direct reference to the f1, and cover:stop() is called,
+ %% then P should be killed.
+ %% This is because of the return address to 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.
- Pid1 = f1:start_a(),
- Pid2 = f1:start_b(),
+ Pid = spawn(fun () -> f1:non_tail_call_f2_wait() end),
%% Now stop cover
cover:stop(),
%% Ensure that f1 is loaded (and not cover compiled), and that
- %% both Pid1 and Pid2 are dead.
+ %% both Pid is dead.
case code:which(f1) of
Beam when is_list(Beam) ->
ok;
Other ->
ct:fail({"f1 is not reloaded", Other})
end,
- case process_info(Pid1) of
+ case process_info(Pid) of
undefined ->
ok;
- _PI1 ->
- RefToOldP1 = erlang:check_process_code(Pid1, f1),
- ct:fail({"Pid1 still alive", RefToOldP1})
- end,
- case process_info(Pid2) of
- undefined ->
- ok;
- _PI2 ->
- RefToOldP2 = erlang:check_process_code(Pid1, f2),
- ct:fail({"Pid2 still alive", RefToOldP2})
+ _PI ->
+ RefToOldP = erlang:check_process_code(Pid, f1),
+ ct:fail({"Pid still alive", RefToOldP})
end,
file:set_cwd(CWD),
diff --git a/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl b/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl
index 5399b33f19..fc4a62e70e 100644
--- a/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl
+++ b/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl
@@ -1,13 +1,6 @@
-module(f1).
--export([start_a/0, start_b/0]).
+-export([non_tail_call_f2_wait/0]).
-start_a() ->
- f2:start(fun() ->
- ok
- end).
-
-start_b() ->
- f2:start(fun fun1/0).
-
-fun1() ->
- ok.
+non_tail_call_f2_wait() ->
+ f2:wait(),
+ im_back.
diff --git a/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl b/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl
index 72a6a64c4d..4bc88035c7 100644
--- a/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl
+++ b/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl
@@ -1,13 +1,5 @@
-module(f2).
--export([start/1]).
+-export([wait/0]).
-start(Fun) ->
- spawn(fun() ->
- wait(Fun)
- end).
-
-wait(Fun) ->
- receive
- go ->
- Fun()
- end.
+wait() ->
+ receive after infinity -> ok end.
diff --git a/lib/tools/test/lcnt_SUITE.erl b/lib/tools/test/lcnt_SUITE.erl
index d39a5deeab..af3ce88fdd 100644
--- a/lib/tools/test/lcnt_SUITE.erl
+++ b/lib/tools/test/lcnt_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -29,7 +29,8 @@
-export([t_load/1,
t_conflicts/1,
t_locations/1,
- t_swap_keys/1]).
+ t_swap_keys/1,
+ smoke_lcnt/1]).
init_per_testcase(_Case, Config) ->
Config.
@@ -43,7 +44,8 @@ suite() ->
{timetrap,{minutes,4}}].
all() ->
- [t_load, t_conflicts, t_locations, t_swap_keys].
+ [t_load, t_conflicts, t_locations, t_swap_keys,
+ smoke_lcnt].
%%----------------------------------------------------------------------
%% Tests
@@ -146,3 +148,82 @@ t_swap_keys_file([File|Files]) ->
ok = lcnt:conflicts(),
ok = lcnt:stop(),
t_swap_keys_file(Files).
+
+%% Simple smoke test of actual lock-counting, if running on
+%% a run-time with lock-counting enabled.
+
+smoke_lcnt(Config) ->
+ case erlang:system_info(build_type) of
+ lcnt ->
+ do_smoke_lcnt(Config);
+ _ ->
+ {skip,"Lock counting is not enabled"}
+ end.
+
+do_smoke_lcnt(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ SaveFile = filename:join(PrivDir, atom_to_list(?FUNCTION_NAME)),
+ {Time,ok} = timer:tc(fun() -> lcnt:apply(fun() -> big_bang(200) end) end),
+ io:format("~p ms\n", [Time]),
+ ok = lcnt:conflicts(),
+ ok = lcnt:save(SaveFile),
+ ok = lcnt:load(SaveFile),
+ ok = lcnt:conflicts(),
+ lcnt:stop().
+
+
+%%%
+%%% A slightly modified version of Rickard Green's Big Bang benchmark.
+%%%
+
+big_bang(N) when is_integer(N) ->
+ Procs = spawn_procs(N),
+ RMsgs = lists:map(fun (P) -> {done, P} end, Procs),
+ send_procs(Procs, {procs, Procs, self()}),
+ receive_msgs(RMsgs),
+ lists:foreach(fun (P) -> exit(P, normal) end, Procs).
+
+pinger([], [], true) ->
+ receive
+ {procs, Procs, ReportTo} ->
+ pinger(Procs, [], ReportTo)
+ end;
+pinger([], [], false) ->
+ receive {ping, From} -> From ! {pong, self()} end,
+ pinger([],[],false);
+pinger([], [], ReportTo) ->
+ ReportTo ! {done, self()},
+ pinger([],[],false);
+pinger([],[Po|Pos] = Pongers, ReportTo) ->
+ receive
+ {ping, From} ->
+ From ! {pong, self()},
+ pinger([], Pongers, ReportTo);
+ {pong, Po} ->
+ pinger([], Pos, ReportTo)
+ end;
+pinger([Pi|Pis], Pongers, ReportTo) ->
+ receive {ping, From} -> From ! {pong, self()}
+ after 0 -> ok
+ end,
+ Pi ! {ping, self()},
+ pinger(Pis, [Pi|Pongers], ReportTo).
+
+spawn_procs(N) when N =< 0 ->
+ [];
+spawn_procs(N) ->
+ [spawn_link(fun () -> pinger([], [], true) end) | spawn_procs(N-1)].
+
+send_procs([], Msg) ->
+ Msg;
+send_procs([P|Ps], Msg) ->
+ P ! Msg,
+ send_procs(Ps, Msg).
+
+receive_msgs([]) ->
+ ok;
+receive_msgs([M|Ms]) ->
+ receive
+ M ->
+ receive_msgs(Ms)
+ end.
diff --git a/lib/tools/test/make_SUITE.erl b/lib/tools/test/make_SUITE.erl
index e6284db8b8..2f6fe1c732 100644
--- a/lib/tools/test/make_SUITE.erl
+++ b/lib/tools/test/make_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -19,11 +19,7 @@
%%
-module(make_SUITE).
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2, 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]).
+-compile(export_all).
-include_lib("common_test/include/ct.hrl").
@@ -40,7 +36,8 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [make_all, make_files, {group, otp_6057}].
+ [make_all, make_files, recompile_on_changed_include,
+ emake_opts, {group, otp_6057}].
groups() ->
[{otp_6057,[],[otp_6057_a, otp_6057_b,
@@ -86,6 +83,55 @@ make_files(Config) when is_list(Config) ->
ensure_no_messages(),
ok.
+recompile_on_changed_include(Config) ->
+ Current = prepare_data_dir(Config),
+
+ Files = [test_incl1,"incl_src/test_incl2"],
+ up_to_date = make:files(Files),
+ ok = ensure_exists([test_incl1,test_incl2]),
+
+ {ok, FileInfo11} = file:read_file_info("test_incl1.beam"),
+ Date11 = FileInfo11#file_info.mtime,
+ {ok, FileInfo21} = file:read_file_info("test_incl2.beam"),
+ Date21 = FileInfo21#file_info.mtime,
+ timer:sleep(2000),
+
+ %% Touch the include file
+ {ok,Bin} = file:read_file("test_incl.hrl"),
+ ok = file:delete("test_incl.hrl"),
+ ok = file:write_file("test_incl.hrl",Bin),
+
+ up_to_date = make:files(Files),
+
+ {ok, FileInfo12} = file:read_file_info("test_incl1.beam"),
+ case FileInfo12#file_info.mtime of
+ Date11 -> ct:fail({"file not recompiled", "test_incl1.beam"});
+ _Date12 -> ok
+ end,
+ {ok, FileInfo22} = file:read_file_info("test_incl2.beam"),
+ case FileInfo22#file_info.mtime of
+ Date21 -> ct:fail({"file not recompiled", "test_incl2.beam"});
+ _Date22 -> ok
+ end,
+
+ file:set_cwd(Current),
+ ensure_no_messages(),
+ ok.
+
+emake_opts(Config) when is_list(Config) ->
+ Current = prepare_data_dir(Config),
+
+ %% prove that emake is used in opts instead of local Emakefile
+ Opts = [{emake, [test8, test9]}],
+ error = make:all(Opts),
+ error = make:files([test9], Opts),
+ "test8.beam" = ensure_exists([test8]),
+ "test9.beam" = ensure_exists([test9]),
+ "test5.S" = ensure_exists(["test5"],".S"),
+
+ file:set_cwd(Current),
+ 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.
diff --git a/lib/tools/test/make_SUITE_data/incl_src/test_incl2.erl b/lib/tools/test/make_SUITE_data/incl_src/test_incl2.erl
new file mode 100644
index 0000000000..d0db98c19a
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/incl_src/test_incl2.erl
@@ -0,0 +1,9 @@
+-module(test_incl2).
+-compile(export_all).
+-include("test_incl.hrl").
+
+f1() ->
+ ?d.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/make_SUITE_data/test1.erl b/lib/tools/test/make_SUITE_data/test1.erl
index f4a133008e..9e21bdc767 100644
--- a/lib/tools/test/make_SUITE_data/test1.erl
+++ b/lib/tools/test/make_SUITE_data/test1.erl
@@ -3,6 +3,8 @@
-vsn('$Revision: /main/release/2 $').
-compile(export_all).
+-warning("a warning").
+
f1() ->
true.
diff --git a/lib/tools/test/make_SUITE_data/test_incl.hrl b/lib/tools/test/make_SUITE_data/test_incl.hrl
new file mode 100644
index 0000000000..3a1bcfadd0
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test_incl.hrl
@@ -0,0 +1 @@
+-define(d,"defined").
diff --git a/lib/tools/test/make_SUITE_data/test_incl1.erl b/lib/tools/test/make_SUITE_data/test_incl1.erl
new file mode 100644
index 0000000000..4a1dd0e73d
--- /dev/null
+++ b/lib/tools/test/make_SUITE_data/test_incl1.erl
@@ -0,0 +1,9 @@
+-module(test_incl1).
+-compile(export_all).
+-include("test_incl.hrl").
+
+f1() ->
+ ?d.
+
+f2() ->
+ true.
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
index ce30fb711a..057449d4a2 100644
--- a/lib/tools/test/xref_SUITE.erl
+++ b/lib/tools/test/xref_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -50,7 +50,7 @@
-export([analyze/1, basic/1, md/1, q/1, variables/1, unused_locals/1]).
--export([format_error/1, otp_7423/1, otp_7831/1, otp_10192/1]).
+-export([format_error/1, otp_7423/1, otp_7831/1, otp_10192/1, otp_13708/1]).
-import(lists, [append/2, flatten/1, keysearch/3, member/2, sort/1, usort/1]).
@@ -82,18 +82,18 @@ groups() ->
fun_mfa_r14, fun_mfa_vars, qlc]},
{analyses, [],
[analyze, basic, md, q, variables, unused_locals]},
- {misc, [], [format_error, otp_7423, otp_7831, otp_10192]}].
+ {misc, [], [format_error, otp_7423, otp_7831, otp_10192, otp_13708]}].
init_per_suite(Conf) when is_list(Conf) ->
DataDir = ?datadir,
PrivDir = ?privdir,
CopyDir = fname(PrivDir, "datacopy"),
+ ok = file:make_dir(CopyDir),
TarFile = fname(PrivDir, "datacopy.tgz"),
- {ok, Tar} = erl_tar:open(TarFile, [write, compressed]),
- ok = erl_tar:add(Tar, DataDir, CopyDir, [compressed]),
- ok = erl_tar:close(Tar),
- ok = erl_tar:extract(TarFile, [compressed]),
+ ok = file:set_cwd(DataDir),
+ ok = erl_tar:create(TarFile, ["."], [compressed]),
+ ok = erl_tar:extract(TarFile, [compressed, {cwd,CopyDir}]),
ok = file:delete(TarFile),
[{copy_dir, CopyDir}|Conf].
@@ -1222,6 +1222,9 @@ read2(Conf) when is_list(Conf) ->
f() ->
%% Duplicated unresolved calls are ignored:
(f())(foo,bar),(f())(foo,bar). % POS1
+
+ %% Warning forms must be ignored.
+ -warning(must_not_crash).
">>,
ok = file:write_file(File, Test),
{ok, read2} = compile:file(File, [debug_info,{outdir,Dir}]),
@@ -2393,6 +2396,19 @@ otp_10192(Conf) when is_list(Conf) ->
xref:stop(s),
ok.
+%% OTP-10192. Allow filenames with character codes greater than 126.
+otp_13708(Conf) when is_list(Conf) ->
+ {ok, _} = start(s),
+ ok = xref:set_default(s, [{verbose, true}]),
+ {ok, []} = xref:q(s,"E"),
+ xref:stop(s),
+
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"lib_test"),
+ {ok, _} = start(s),
+ ok = xref:set_library_path(s, [Dir], [{verbose, true}]),
+ xref:stop(s).
+
%%%
%%% Utilities
%%%
diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk
index 8c889cbe4e..8aa7814e1d 100644
--- a/lib/tools/vsn.mk
+++ b/lib/tools/vsn.mk
@@ -1 +1 @@
-TOOLS_VSN = 2.8.4
+TOOLS_VSN = 2.10
diff --git a/lib/typer/Makefile b/lib/typer/Makefile
deleted file mode 100644
index bd1b6458a8..0000000000
--- a/lib/typer/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2006-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-#=============================================================================
-#
-# File: lib/typer/Makefile
-# Authors: Bingwen He, Tobias Lindahl, and Kostis Sagonas
-#
-#=============================================================================
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-#
-# Macros
-#
-
-SUB_DIRECTORIES = src doc/src
-
-include vsn.mk
-VSN = $(TYPER_VSN)
-
-SPECIAL_TARGETS =
-
-#
-# Default Subdir Targets
-#
-include $(ERL_TOP)/make/otp_subdir.mk
-
diff --git a/lib/typer/RELEASE_NOTES b/lib/typer/RELEASE_NOTES
deleted file mode 100644
index d91a815ee9..0000000000
--- a/lib/typer/RELEASE_NOTES
+++ /dev/null
@@ -1,22 +0,0 @@
-==============================================================================
- Major features, additions and changes between Typer versions
- (in reversed chronological order)
-==============================================================================
-
-Version 0.9 (in Erlang/OTP R14B02)
-----------------------------------
- - Major rewrite; all code has been cleaned up and placed in one file.
- The only reason why this is not version 1.0 yet is that there is no proper
- documentation for typer which can be displayed in the www.erlang.org site.
- - Added ability to receive the set of exported types and report unknown ones.
- - Better handling of overloaded contracts; especially erroneous ones on which
- typer does not crash anymore.
- - Fixed problem that caused typer to hang when given a file whose module name
- did not correspond to the file name.
- - Added two undocumented options that may come very handy when trying to
- understand why typer reports some particular set of types for the functions
- in a module. These options are mainly for typer developers at this point,
- but may become documented in some future version.
-
-Older versions
---------------
diff --git a/lib/typer/doc/Makefile b/lib/typer/doc/Makefile
deleted file mode 100644
index 1015ca78eb..0000000000
--- a/lib/typer/doc/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2006-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-SHELL=/bin/sh
-
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-clean:
- -rm -f *.html edoc-info stylesheet.css erlang.png
-
-distclean: clean
-realclean: clean
-
-# ----------------------------------------------------
-# Special Build Targets
-# ----------------------------------------------------
-
-
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
diff --git a/lib/typer/doc/html/.gitignore b/lib/typer/doc/html/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/typer/doc/html/.gitignore
+++ /dev/null
diff --git a/lib/typer/doc/pdf/.gitignore b/lib/typer/doc/pdf/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/typer/doc/pdf/.gitignore
+++ /dev/null
diff --git a/lib/typer/doc/src/Makefile b/lib/typer/doc/src/Makefile
deleted file mode 100644
index 3724a2e4d1..0000000000
--- a/lib/typer/doc/src/Makefile
+++ /dev/null
@@ -1,118 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2006-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include ../../vsn.mk
-VSN=$(TYPER_VSN)
-APPLICATION=typer
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-XML_APPLICATION_FILES = ref_man.xml
-XML_REF3_FILES =
-
-XML_PART_FILES = part_notes.xml
-XML_CHAPTER_FILES = notes.xml
-
-BOOK_FILES = book.xml
-
-XML_FILES = \
- $(BOOK_FILES) $(XML_CHAPTER_FILES) \
- $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES)
-
-GIF_FILES =
-
-# ----------------------------------------------------
-
-HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
- $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
-
-INFO_FILE = ../../info
-EXTRA_FILES = \
- $(DEFAULT_GIF_FILES) \
- $(DEFAULT_HTML_FILES) \
- $(XML_REF3_FILES:%.xml=$(HTMLDIR)/%.html) \
- $(XML_CHAPTER_FILES:%.xml=$(HTMLDIR)/%.html)
-
-MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3)
-
-HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
-
-TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-XML_FLAGS +=
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-$(HTMLDIR)/%.gif: %.gif
- $(INSTALL_DATA) $< $@
-
-docs: pdf html man
-
-$(TOP_PDF_FILE): $(XML_FILES)
-
-pdf: $(TOP_PDF_FILE)
-
-html: gifs $(HTML_REF_MAN_FILE)
-
-man: $(MAN3_FILES)
-
-gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
-
-debug opt:
-
-clean clean_docs:
- rm -rf $(HTMLDIR)/*
- rm -f $(MAN3DIR)/*
- rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
- rm -f errs core *~
-
-distclean: clean
-realclean: clean
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-release_docs_spec: docs
- $(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) $(INFO_FILE) "$(RELSYSDIR)"
-
-
-release_spec:
diff --git a/lib/typer/doc/src/book.xml b/lib/typer/doc/src/book.xml
deleted file mode 100644
index 20da44ae04..0000000000
--- a/lib/typer/doc/src/book.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE book SYSTEM "book.dtd">
-
-<book xmlns:xi="http://www.w3.org/2001/XInclude">
- <header titlestyle="normal">
- <copyright>
- <year>2006</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>TypEr</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- </header>
- <pagetext></pagetext>
- <preamble>
- </preamble>
- <pagetext>TypEr</pagetext>
- <applications>
- <xi:include href="ref_man.xml"/>
- </applications>
- <releasenotes>
- <xi:include href="notes.xml"/>
- </releasenotes>
-</book>
-
diff --git a/lib/typer/doc/src/fascicules.xml b/lib/typer/doc/src/fascicules.xml
deleted file mode 100644
index b15610fa8b..0000000000
--- a/lib/typer/doc/src/fascicules.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
-
-<fascicules>
- <fascicule file="part_notes" href="part_notes_frame.html" entry="yes">
- Release Notes
- </fascicule>
- <fascicule file="" href="../../../../doc/print.html" entry="no">
- Off-Print
- </fascicule>
-</fascicules>
-
diff --git a/lib/typer/doc/src/notes.xml b/lib/typer/doc/src/notes.xml
deleted file mode 100644
index 9ef5ca1c70..0000000000
--- a/lib/typer/doc/src/notes.xml
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2014</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>TypEr Release Notes</title>
- <prepared>otp_appnotes</prepared>
- <docno>nil</docno>
- <date>nil</date>
- <rev>nil</rev>
- <file>notes.xml</file>
- </header>
- <p>This document describes the changes made to TypEr.</p>
-
-<section><title>TypEr 0.9.11</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Internal changes</p>
- <p>
- Own Id: OTP-13551</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>TypEr 0.9.10</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>Fix a bug that could result in a crash when printing
- warnings onto standard error. </p>
- <p>
- Own Id: OTP-13010</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>TypEr 0.9.9</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p> Properly extract annotations from core code. </p>
- <p>
- Own Id: OTP-12727</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>TypEr 0.9.8</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p> The name of a compiler option has been fixed in the
- Makefile. </p>
- <p>
- Own Id: OTP-11996</p>
- </item>
- </list>
- </section>
-
-</section>
-
-<section><title>TypEr 0.9.7</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Added initial documentation framework for TypEr.</p>
- <p>
- Own Id: OTP-11860</p>
- </item>
- </list>
- </section>
-
-</section>
-
-
-
-</chapter>
-
diff --git a/lib/typer/doc/src/part_notes.xml b/lib/typer/doc/src/part_notes.xml
deleted file mode 100644
index 3234f0903e..0000000000
--- a/lib/typer/doc/src/part_notes.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>2006</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>TypEr Release Notes</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- </header>
- <description>
- <p><em>TypEr</em></p>
- </description>
- <xi:include href="notes.xml"/>
-</part>
-
diff --git a/lib/typer/doc/src/ref_man.xml b/lib/typer/doc/src/ref_man.xml
deleted file mode 100644
index c793207443..0000000000
--- a/lib/typer/doc/src/ref_man.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE application SYSTEM "application.dtd">
-
-<application xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>2014</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>TypEr</title>
- <prepared></prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- <file>ref_man.xml</file>
- </header>
- <description>
- </description>
- <xi:include href="typer_app.xml"/>
-</application>
-
diff --git a/lib/typer/doc/src/typer_app.xml b/lib/typer/doc/src/typer_app.xml
deleted file mode 100644
index d52df5d0da..0000000000
--- a/lib/typer/doc/src/typer_app.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE appref SYSTEM "appref.dtd">
-
-<appref>
- <header>
- <copyright>
- <year>2014</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- </legalnotice>
-
- <title>TypEr</title>
- <prepared></prepared>
- <responsible></responsible>
- <docno></docno>
- <approved></approved>
- <checked></checked>
- <date></date>
- <rev></rev>
- <file>typer.xml</file>
- </header>
- <app>TypEr</app>
- <appsummary>The TypEr Application</appsummary>
- <description>
- <p>An Erlang/OTP application that shows type information
- for Erlang modules to the user. Additionally, it can
- annotate the code of files with such type information.</p>
- </description>
-
-</appref>
-
diff --git a/lib/typer/ebin/.gitignore b/lib/typer/ebin/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/typer/ebin/.gitignore
+++ /dev/null
diff --git a/lib/typer/info b/lib/typer/info
deleted file mode 100644
index 5145fbcfff..0000000000
--- a/lib/typer/info
+++ /dev/null
@@ -1,2 +0,0 @@
-group: tools
-short: TypEr
diff --git a/lib/typer/src/Makefile b/lib/typer/src/Makefile
deleted file mode 100644
index 6c5d8b0726..0000000000
--- a/lib/typer/src/Makefile
+++ /dev/null
@@ -1,111 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2006-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-#=============================================================================
-#
-# File: lib/typer/src/Makefile
-# Authors: Kostis Sagonas
-#
-#=============================================================================
-
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include ../vsn.mk
-VSN=$(TYPER_VSN)
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/typer-$(VSN)
-
-# ----------------------------------------------------
-# Orientation information -- find dialyzer's dir
-# ----------------------------------------------------
-DIALYZER_DIR = $(ERL_TOP)/lib/dialyzer
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-MODULES = typer
-
-HRL_FILES=
-ERL_FILES= $(MODULES:%=%.erl)
-INSTALL_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
-TARGET_FILES= $(INSTALL_FILES)
-
-APP_FILE= typer.app
-APP_SRC= $(APP_FILE).src
-APP_TARGET= $(EBIN)/$(APP_FILE)
-
-APPUP_FILE= typer.appup
-APPUP_SRC= $(APPUP_FILE).src
-APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-ERL_COMPILE_FLAGS += +warn_export_vars +warn_untyped_record +warn_missing_spec
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-debug opt: $(TARGET_FILES)
-
-docs:
-
-clean:
- rm -f $(TARGET_FILES)
- rm -f core
-
-# ----------------------------------------------------
-# Special Build Targets
-# ----------------------------------------------------
-
-$(EBIN)/typer.$(EMULATOR): typer.erl ../vsn.mk Makefile
- $(erlc_verbose)erlc -W $(ERL_COMPILE_FLAGS) -DVSN="\"v$(VSN)\"" -o$(EBIN) typer.erl
-
-$(APP_TARGET): $(APP_SRC) ../vsn.mk
- $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
-
-$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
- $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
-
-# ---------------------------------------------------------------------
-# dependencies
-# ---------------------------------------------------------------------
-
-
-# ----------------------------------------------------
-# Release Target
-# ----------------------------------------------------
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-release_spec: opt
- $(INSTALL_DIR) "$(RELSYSDIR)/src"
- $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(YRL_FILES) \
- "$(RELSYSDIR)/src"
- $(INSTALL_DIR) "$(RELSYSDIR)/ebin"
- $(INSTALL_DATA) $(INSTALL_FILES) "$(RELSYSDIR)/ebin"
-
-release_docs_spec:
diff --git a/lib/typer/src/typer.app.src b/lib/typer/src/typer.app.src
deleted file mode 100644
index 974091b44c..0000000000
--- a/lib/typer/src/typer.app.src
+++ /dev/null
@@ -1,11 +0,0 @@
-% This is an -*- erlang -*- file.
-
-{application, typer,
- [{description, "TYPe annotator for ERlang programs, version %VSN%"},
- {vsn, "%VSN%"},
- {modules, [typer]},
- {registered, []},
- {applications, [compiler, dialyzer, hipe, kernel, stdlib]},
- {env, []},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","hipe-3.10.3","erts-6.0",
- "dialyzer-2.7","compiler-5.0"]}]}.
diff --git a/lib/typer/test/Makefile b/lib/typer/test/Makefile
deleted file mode 100644
index fb5570d9f0..0000000000
--- a/lib/typer/test/Makefile
+++ /dev/null
@@ -1,65 +0,0 @@
-include $(ERL_TOP)/make/target.mk
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-
-MODULES= \
- typer_SUITE
-
-ERL_FILES= $(MODULES:%=%.erl)
-
-TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
-INSTALL_PROGS= $(TARGET_FILES)
-
-EMAKEFILE=Emakefile
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/typer_test
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-
-ERL_MAKE_FLAGS +=
-ERL_COMPILE_FLAGS +=
-
-EBIN = .
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-
-make_emakefile:
- $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
- > $(EMAKEFILE)
- $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' \
- >> $(EMAKEFILE)
-
-tests debug opt: make_emakefile
- erl $(ERL_MAKE_FLAGS) -make
-
-clean:
- rm -f $(EMAKEFILE)
- rm -f $(TARGET_FILES) $(GEN_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) $(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)"
- $(INSTALL_DATA) typer.spec "$(RELSYSDIR)"
- chmod -R u+w "$(RELSYSDIR)"
-
-release_docs_spec:
diff --git a/lib/typer/test/typer.spec b/lib/typer/test/typer.spec
deleted file mode 100644
index 79f51b6781..0000000000
--- a/lib/typer/test/typer.spec
+++ /dev/null
@@ -1 +0,0 @@
-{suites,"../typer_test",all}.
diff --git a/lib/typer/test/typer_SUITE.erl b/lib/typer/test/typer_SUITE.erl
deleted file mode 100644
index 25f0229640..0000000000
--- a/lib/typer/test/typer_SUITE.erl
+++ /dev/null
@@ -1,57 +0,0 @@
-%% ``Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% 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(typer_SUITE).
-
--compile([export_all]).
--include_lib("common_test/include/ct.hrl").
-
-suite() ->
- [{ct_hooks, [ts_install_cth]}].
-
-all() ->
- case application:ensure_all_started(typer) of
- {ok, Apps} ->
- [application:stop(App) || App <- lists:reverse(Apps)],
- [app, appup];
- _ ->
- [appup]
- end.
-
-groups() ->
- [].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-app() ->
- [{doc, "Test that the typer app file is ok"}].
-app(Config) when is_list(Config) ->
- ok = ?t:app_test(typer).
-
-appup() ->
- [{doc, "Test that the typer appup file is ok"}].
-appup(Config) when is_list(Config) ->
- ok = ?t:appup_test(typer).
diff --git a/lib/typer/vsn.mk b/lib/typer/vsn.mk
deleted file mode 100644
index ed12e067c1..0000000000
--- a/lib/typer/vsn.mk
+++ /dev/null
@@ -1 +0,0 @@
-TYPER_VSN = 0.9.11
diff --git a/lib/wx/api_gen/gen_util.erl b/lib/wx/api_gen/gen_util.erl
index cd42ad2d96..5e2f405498 100644
--- a/lib/wx/api_gen/gen_util.erl
+++ b/lib/wx/api_gen/gen_util.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -203,7 +203,7 @@ replace_and_remove([$; | R], Acc) ->
replace_and_remove([$@ | R], Acc) ->
replace_and_remove(R, [directive|Acc]);
-replace_and_remove([_E|R], Acc) -> %% Ignore everthing else
+replace_and_remove([_E|R], Acc) -> %% Ignore everything else
replace_and_remove(R, Acc);
replace_and_remove([], Acc) ->
Acc.
diff --git a/lib/wx/api_gen/gl_gen.erl b/lib/wx/api_gen/gl_gen.erl
index 54635bdd2e..7e3766a43b 100644
--- a/lib/wx/api_gen/gl_gen.erl
+++ b/lib/wx/api_gen/gl_gen.erl
@@ -354,6 +354,7 @@ handle_arg_opt({single,Opt},P=#arg{type=T}) -> P#arg{type=T#type{single=Opt}};
handle_arg_opt({base,{Opt, Sz}}, P=#arg{type=T}) -> P#arg{type=T#type{base=Opt, size=Sz}};
handle_arg_opt({base,Opt}, P=#arg{type=T}) -> P#arg{type=T#type{base=Opt}};
handle_arg_opt({c_only,Opt},P) -> P#arg{where=c, alt=Opt};
+handle_arg_opt(list_binary, P) -> P#arg{alt=list_binary};
handle_arg_opt(string, P=#arg{type=T}) -> P#arg{type=T#type{base=string}};
handle_arg_opt({string,Max,Sz}, P=#arg{type=T}) ->
P#arg{type=T#type{base=string, size={Max,Sz}}}.
@@ -588,7 +589,7 @@ lookup(Name,[_|R],Def) ->
lookup(Name,R,Def);
lookup(_,[], Def) -> Def.
-setup_idx_binary(Name,Ext,_Opts) ->
+setup_idx_binary(Name,Ext, Opts) ->
FuncName = Name ++ Ext,
Func = #func{params=Args} = get(FuncName),
Id = next_id(function),
@@ -607,8 +608,7 @@ setup_idx_binary(Name,Ext,_Opts) ->
ok;
(_) -> ok
end, Args),
-
- case setup_idx_binary(Args, []) of
+ case setup_idx_binary_1(Args, []) of
ignore ->
put(FuncName, Func#func{id=Id}),
Name++Ext;
@@ -624,30 +624,41 @@ setup_idx_binary(Name,Ext,_Opts) ->
[FuncName,Extra]
end.
-setup_idx_binary([A=#arg{in=true,type=T=#type{base=idx_binary}}|R], Acc) ->
+setup_idx_binary_1([A=#arg{in=true,type=T=#type{base=idx_binary}}|R], Acc) ->
A1 = A#arg{type=T#type{base=guard_int,size=4}},
A2 = A#arg{type=T#type{base=binary}},
Head = reverse(Acc),
- case setup_idx_binary(R, []) of
+ case setup_idx_binary_1(R, []) of
ignore ->
{bin, Head ++ [A1|R], Head ++ [A2|R]};
{bin, R1,R2} ->
{bin, Head ++ [A1|R1], Head ++ [A2|R2]}
end;
-setup_idx_binary([A=#arg{in=true,type=T=#type{single={tuple,matrix}}}|R], Acc) ->
+setup_idx_binary_1([A=#arg{in=true,type=T=#type{base=int,size=4},alt=list_binary}|R], Acc) ->
+ A1 = A#arg{type=T#type{base=guard_int}},
+ A2 = A#arg{type=T#type{base=binary}},
+ Head = reverse(Acc),
+ case setup_idx_binary_1(R, []) of
+ ignore ->
+ {bin, Head ++ [A1|R], Head ++ [A2|R]};
+ {bin, R1,R2} ->
+ {bin, Head ++ [A1|R1], Head ++ [A2|R2]}
+ end;
+
+setup_idx_binary_1([A=#arg{in=true,type=T=#type{single={tuple,matrix}}}|R], Acc) ->
A1 = A#arg{type=T#type{single={tuple, matrix12}}},
A2 = A#arg{type=T#type{single={tuple, 16}}},
Head = reverse(Acc),
- case setup_idx_binary(R, []) of
+ case setup_idx_binary_1(R, []) of
ignore ->
{matrix, Head ++ [A1|R], Head ++ [A2|R]};
{matrix, R1,R2} ->
{matrix, Head ++ [A1|R1], Head ++ [A2|R2]}
end;
-setup_idx_binary([H|R],Acc) ->
- setup_idx_binary(R,[H|Acc]);
-setup_idx_binary([],_) -> ignore.
-
+setup_idx_binary_1([H|R],Acc) ->
+ setup_idx_binary_1(R,[H|Acc]);
+setup_idx_binary_1([],_) -> ignore.
+
is_equal(F1=#func{type=T1,params=A1},F2=#func{type=T2,params=A2}) ->
Equal = is_equal_type(T1,T2) andalso is_equal_args(A1,A2),
case Equal of
diff --git a/lib/wx/api_gen/gl_gen_c.erl b/lib/wx/api_gen/gl_gen_c.erl
index c6d4f3a520..53c194a315 100644
--- a/lib/wx/api_gen/gl_gen_c.erl
+++ b/lib/wx/api_gen/gl_gen_c.erl
@@ -123,20 +123,14 @@ declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=B,single={list,Sz}}})
when is_number(Sz) ->
w(" ~s ~s[~p] = {~s};~n", [T,N,Sz,args(fun zero/1,",",lists:duplicate(Sz,B))]),
A;
-declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=string,size={Max,_}, single=Single}}) ->
+declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=string,size={Max,_}}}) ->
case is_integer(Max) of
- true ->
+ true ->
w(" ~s ~s[~p];~n", [T,N,Max]);
false ->
- %% w(" ~s ~s[*~s];~n", [T,N,Max]),
- w(" ~s *~s;~n", [T,N]),
+ w(" ~s *~s;~n", [T,N]),
w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~s);~n", [N,T,T,Max]),
- store_free(N)
- %% case Single of
- %% {list, _, _} ->
- %% w(" ~s *~s_p = ~s;~n", [T,N,N]);
- %% _ -> ok
- %% end
+ store_free(N)
end,
A;
declare_var(A=#arg{name=N,in=false,type=#type{base=binary,size={MaxSz, _}}}) ->
@@ -163,9 +157,9 @@ declare_var(A=#arg{name=N,in=false,
type=#type{name=T,base=B,by_val=false,single=true}}) ->
w(" ~s ~s[1] = {~s};~n", [T,N,zero(B)]),
A;
-declare_var(A=#arg{where=c, type=#type{name=T}, alt={size,Var}}) ->
+declare_var(A=#arg{where=c, type=#type{name=T}, alt={size,Var}}) ->
w(" ~s ~s_size = bins_sz[~p];~n", [T, Var, get(bin_count)]),
- A;
+ A;
declare_var(A=#arg{where=_}) ->
A.
@@ -194,9 +188,16 @@ decode_arg(P=#arg{where=erl},A) -> {P,A};
decode_arg(P=#arg{where=c},A) -> {P,A};
decode_arg(P=#arg{in=false},A) -> {P,A};
-decode_arg(P=#arg{name=Name,type=#type{name=Type,base=binary}},A0) ->
+decode_arg(P=#arg{name=Name,alt=Alt,type=#type{name=Type,base=binary}},A0) ->
w(" ~s *~s = (~s *) bins[~p];~n", [Type,Name,Type,next_id(bin_count)]),
- {P, A0};
+ case Alt of
+ list_binary ->
+ A = align(4, A0),
+ w(" int * ~sLen = (int *) bp; bp += 4; (void) ~sLen;~n", [Name, Name]),
+ {P, A};
+ _ ->
+ {P, A0}
+ end;
decode_arg(P=#arg{name=Name,type=#type{name=Type,base=memory}},A0) ->
w(" ~s *~s = (~s *) bins[~p];~n", [Type,Name,Type,next_id(bin_count)]),
{P, A0};
@@ -217,7 +218,7 @@ decode_arg(P=#arg{name=Name,type=#type{size=Sz,single=list,name=Type}},A0) ->
A = align(max([Sz,4]),A0),
w(" int * ~sLen = (int *) bp; bp += ~p;~n", [Name, max([4,Sz])]),
w(" ~s * ~s = (~s *) bp; ", [Type,Name,Type]),
- w(" bp += (8-((*~sLen*~p+~p)%8))%8;~n", [Name,Sz,A]),
+ w(" bp += *~sLen*~p + (8-((*~sLen*~p+~p)%8))%8;~n", [Name,Sz,Name,Sz,A]),
{P, 0};
decode_arg(P=#arg{name=Name,type=#type{size=TSz,name=Type,single={tuple,undefined}}},A0) ->
A = align(TSz,A0),
diff --git a/lib/wx/api_gen/gl_gen_erl.erl b/lib/wx/api_gen/gl_gen_erl.erl
index 1be8d775be..3ad14825dd 100644
--- a/lib/wx/api_gen/gl_gen_erl.erl
+++ b/lib/wx/api_gen/gl_gen_erl.erl
@@ -116,7 +116,7 @@ gl_api(Fs) ->
w("call(Op, Args) ->~n", []),
w(" Port = get(opengl_port), ~n", []),
w(" _ = erlang:port_control(Port,Op,Args),~n", []),
- w(" rec().~n", []),
+ w(" rec(Op).~n", []),
w(" ~n", []),
w("%% @hidden~n", []),
w("cast(Op, Args) ->~n", []),
@@ -125,11 +125,15 @@ gl_api(Fs) ->
w(" ok.~n", []),
w(" ~n", []),
w("%% @hidden~n", []),
- w("rec() ->~n", []),
- w(" receive ~n", []),
+ w("rec(Op) ->~n", []),
+ w(" receive~n", []),
w(" {'_egl_result_', Res} -> Res;~n", []),
- w(" {'_egl_error_', Op, Res} -> error({error,Res,Op})~n", []),
- w(" end. ~n", []),
+ w(" {'_egl_error_', Op, Res} -> error({error,Res,Op});~n", []),
+ w(" {'_egl_error_', Other, Res} ->~n ", []),
+ w(" Err = io_lib:format(\"~~p in op: ~~p\", [Res, Other]),~n", []),
+ w(" error_logger:error_report([{gl, error}, {message, lists:flatten(Err)}]),~n", []),
+ w(" rec(Op)~n", []),
+ w(" end.~n", []),
w("~n", []),
w("%% @hidden~n", []),
w("send_bin(Bin) when is_binary(Bin) ->~n", []),
@@ -492,6 +496,8 @@ doc_arg_type2(#type{base=string, single=list}) ->
"iolist()";
doc_arg_type2(T=#type{single={tuple,Sz}}) ->
"{" ++ args(fun doc_arg_type3/1, ",", lists:duplicate(Sz,T)) ++ "}";
+doc_arg_type2(#type{base=guard_int, single=list}) ->
+ "[integer()]|mem()";
doc_arg_type2(T=#type{single=list}) ->
"[" ++ doc_arg_type3(T) ++ "]";
doc_arg_type2(T=#type{single={list, _Max}}) ->
@@ -512,7 +518,9 @@ doc_arg_type3(#type{base=binary}) -> "binary()";
doc_arg_type3(#type{base=memory}) -> "mem()".
guard_test(As) ->
- Str = args(fun(#arg{name=N,type=#type{base=guard_int}}) ->
+ Str = args(fun(#arg{name=N,type=#type{base=guard_int, single=list}}) ->
+ " is_list("++erl_arg_name(N)++")";
+ (#arg{name=N,type=#type{base=guard_int}}) ->
" is_integer("++erl_arg_name(N)++")";
(_) ->
skip
@@ -522,6 +530,13 @@ guard_test(As) ->
Other -> " when " ++ Other
end.
+pre_marshal([#arg{name=N,in=true, type=#type{base=binary, single=list}=T, alt=list_binary}=A|R]) ->
+ w(" send_bin(~s),~n", [erl_arg_name(N)]),
+ w(" ~sLen = byte_size(if is_binary(~s) -> ~s; is_tuple(~s) -> element(2, ~s) end) div 4,~n",
+ [erl_arg_name(N),erl_arg_name(N), erl_arg_name(N), erl_arg_name(N), erl_arg_name(N)]),
+ Type = T#type{base=int, by_val=true, single=true, ref=undefined},
+ Arg=A#arg{name=N++"Len", where=both, type=Type},
+ [Arg|pre_marshal(R)];
pre_marshal([#arg{name=N,in=true,type=#type{base=binary}}|R]) ->
w(" send_bin(~s),~n", [erl_arg_name(N)]),
pre_marshal(R);
@@ -530,8 +545,18 @@ pre_marshal([#arg{name=N,type=#type{base=memory}}|R]) ->
pre_marshal(R);
pre_marshal([A=#arg{name=N,type=#type{base=string,single=list}}|R]) ->
%% With null terminations
- w(" ~sTemp = list_to_binary([[Str|[0]] || Str <- ~s ]),~n",
+ w(" ~sTemp = list_to_binary([[Str|[0]] || Str <- ~s ]),~n",
[erl_arg_name(N), erl_arg_name(N)]),
+ w(" ~sLen = length(~s),~n",[erl_arg_name(N), erl_arg_name(N)]),
+ [A|pre_marshal(R)];
+pre_marshal([A=#arg{name=N,type=#type{base=string,single=true,ref={pointer,1}}}|R]) ->
+ w(" ~sLen = length(~s),~n",[erl_arg_name(N), erl_arg_name(N)]),
+ [A|pre_marshal(R)];
+pre_marshal([A=#arg{name=N,type=#type{single=list}}|R]) ->
+ w(" ~sLen = length(~s),~n",[erl_arg_name(N), erl_arg_name(N)]),
+ [A|pre_marshal(R)];
+pre_marshal([A=#arg{name=N,type=#type{single={tuple_list,_}}}|R]) ->
+ w(" ~sLen = length(~s),~n",[erl_arg_name(N), erl_arg_name(N)]),
[A|pre_marshal(R)];
pre_marshal([A|R]) ->
[A|pre_marshal(R)];
@@ -583,9 +608,9 @@ marshal_arg(#type{size=BSz,name=Type,single={tuple,matrix12}},Name,A0) ->
align(BSz,16,A0,All);
marshal_arg(#type{size=Sz,name=Type,base=Base,single=list},Name,A0)
- when Base =:= float; Base =:= int ->
+ when Base =:= float; Base =:= int; Base =:= guard_int ->
KeepA = case Sz of 8 -> "0:32,"; _ -> "" end,
- Str0 = "(length("++Name++")):?GLuint,"++KeepA++"\n"
+ Str0 = Name++"Len:?GLuint,"++KeepA++"\n"
" (<< <<C:?"++Type++">> || C <- "++Name++">>)/binary",
{Str,Align} = align(max([Sz,4]),A0,Str0),
align_after(Sz,Align,0,1,Name,Str);
@@ -606,7 +631,7 @@ marshal_arg(#type{base=string,single=true,ref={pointer,1}},Name,A0) ->
marshal_arg(#type{base=string,single=list,ref={pointer,2}},Name,A0) ->
Str0 =
- "(length("++Name++")):?GLuint,"
+ Name++"Len:?GLuint,"
"(size("++Name ++ "Temp)):?GLuint,"
"(" ++ Name ++ "Temp)/binary",
{Str,A} = align(4,A0,Str0),
@@ -620,7 +645,7 @@ marshal_arg(#type{size=Sz,name=Type,single={tuple_list,TSz}},Name,A0) ->
TBin = args(fun(ElName) -> ElName ++ ":?" ++ Type end, ",", Names),
KeepA = case Sz of 8 -> "0:32,"; 4 -> "" end,
- Str0 = "(length("++Name++")):?GLuint,"++KeepA++"\n"
+ Str0 = Name++"Len:?GLuint,"++KeepA++"\n"
" (<< <<"++TBin++">> || {"++TTup++"} <- "++Name++">>)/binary",
align(Sz,A0,Str0);
@@ -656,19 +681,19 @@ align(8,_,7,Str) -> {"0:8," ++Str, 0}.
align_after(8,0,_Add,_Multiplier,_Name,Str) -> {Str,0};
align_after(4,0,Add,Mult,Name,Str) ->
Extra = extra_align(Add,Mult),
- Align = ",0:(((length("++Name++")"++Extra++") rem 2)*32)",
+ Align = ",0:((("++Name++"Len"++Extra++") rem 2)*32)",
{Str ++ Align,0};
align_after(4,4,Add,Mult,Name,Str) ->
Extra = extra_align(Add,Mult),
- Align = ",0:(((1+length("++Name++")"++Extra++") rem 2)*32)",
+ Align = ",0:(((1+"++Name++"Len"++Extra++") rem 2)*32)",
{Str ++ Align,0};
align_after(2,A,Add,Mult,Name,Str) when (A rem 2) =:= 0 ->
Extra = extra_align(A+Add*2,Mult),
- Align = ",0:((8-((length("++Name++")*2"++Extra++") rem 8)) rem 8)",
+ Align = ",0:((8-(("++Name++"Len*2"++Extra++") rem 8)) rem 8)",
{Str ++ Align,0};
align_after(1,A,Add,Mult,Name,Str) ->
Extra = extra_align(A+Add,Mult),
- Align = ",0:((8-((length("++Name++")"++Extra++") rem 8)) rem 8)",
+ Align = ",0:((8-(("++Name++"Len"++Extra++") rem 8)) rem 8)",
{Str ++ Align,0};
align_after(Sz,A,Add,Mult,Name,Str) ->
io:format("~p ~p with ~p ~p ~s~n, ~p", [Sz,A,Add,Mult,Name,Str]),
diff --git a/lib/wx/api_gen/glapi.conf b/lib/wx/api_gen/glapi.conf
index 59fa8f7727..57f30a3f7e 100644
--- a/lib/wx/api_gen/glapi.conf
+++ b/lib/wx/api_gen/glapi.conf
@@ -181,9 +181,9 @@
{"glLoadTransposeMatrix", {"m", {single,{tuple,matrix}}}}.
{"glMultTransposeMatrix", {"m",{single,{tuple,matrix}}}}.
-{"glMultiDrawArrays", [{"first", [in,{single,list}]},
- {"count", [in,{single,list}]},
- {"primcount", {c_only, {length,"first"}}}]}.
+{"glMultiDrawArrays", [{"first", [in,{single,list}, list_binary]},
+ {"count", [in,{single,list}, list_binary]},
+ {"primcount", {c_only, {length,"count"}}}]}.
{"glGenQueries", {"ids", {single,{list, "n", "n"}}}}.
{"glGetQueryiv", {"params", {single, true}}}.
diff --git a/lib/wx/api_gen/wx_doxygen.conf b/lib/wx/api_gen/wx_doxygen.conf
index f4d3c99ec0..a96db00254 100644
--- a/lib/wx/api_gen/wx_doxygen.conf
+++ b/lib/wx/api_gen/wx_doxygen.conf
@@ -252,7 +252,7 @@ PREDEFINED = \
wxUSE_POPUPWIN=1 \
wxUSE_SYSTEM_OPTIONS=1 \
wxUSE_INTL=1 \
- wxABI_VERSION=20809 \
+ wxABI_VERSION=20812 \
__WXGTK24__=1 \
__WXGTK20__=1 \
__WXGTK__=1 \
diff --git a/lib/wx/api_gen/wx_extra/added_func.h b/lib/wx/api_gen/wx_extra/added_func.h
index 417188cc8a..bffe391140 100644
--- a/lib/wx/api_gen/wx_extra/added_func.h
+++ b/lib/wx/api_gen/wx_extra/added_func.h
@@ -34,8 +34,13 @@ class wxToolBar {
};
-class wxWindow {
+/* class wxWindow { */
+/* public: */
+/* bool IsDoubleBuffered(); */
+/* void SetDoubleBuffered(bool on); */
+/* }; */
+
+class wxWindowGTK {
public:
- bool IsDoubleBuffered();
- void SetDoubleBuffered(bool on);
+ double GetContentScaleFactor();
};
diff --git a/lib/wx/api_gen/wx_extra/wxListCtrl.erl b/lib/wx/api_gen/wx_extra/wxListCtrl.erl
index acdb69fdeb..355a4cdfd1 100644
--- a/lib/wx/api_gen/wx_extra/wxListCtrl.erl
+++ b/lib/wx/api_gen/wx_extra/wxListCtrl.erl
@@ -43,33 +43,36 @@ SortItems>>
<<EXPORT:wxListCtrl new/0, new/1, new/2 wxListCtrl:EXPORT>>
<<wxListCtrl_new_0
-%% @spec () -> wxListCtrl()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+-spec new() -> wxListCtrl().
new() ->
wxe_util:construct(~s, <<>>).
wxListCtrl_new_0>>
<<wxListCtrl_new_2
-%% @spec (Parent::wxWindow:wxWindow()) -> wxListCtrl()
-%% @equiv new(Parent, [])
+-spec new(Parent) -> wxListCtrl() when
+ Parent::wxWindow:wxWindow().
new(Parent)
when is_record(Parent, wx_ref) ->
new(Parent, []).
-%% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxListCtrl()
-%% Option = {winid, integer()} |
-%% {pos, {X::integer(),Y::integer()}} |
-%% {size, {W::integer(),H::integer()}} |
-%% {style, integer()} |
-%% {validator, wx:wx()} |
-%% {onGetItemText, OnGetItemText} |
-%% {onGetItemAttr, OnGetItemAttr} |
-%% {onGetItemColumnImage, OnGetItemColumnImage}
+%% @doc Creates a listctrl with optional callback functions:
%%
-%% OnGetItemText = (This, Item, Column) -> wxString()
-%% OnGetItemAttr = (This, Item) -> wxListItemAttr()
+%% OnGetItemText = (This, Item, Column) -> unicode:charlist()
+%% OnGetItemAttr = (This, Item) -> wxListItemAttr:wxListItemAttr()
%% OnGetItemColumnImage = (This, Item, Column) -> integer()
-%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+%%
+%% See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+-spec new(Parent, [Option]) -> wxListCtrl() when
+ Parent::wxWindow:wxWindow(),
+ Option::{winid, integer()} |
+ {pos, {X::integer(),Y::integer()}} |
+ {size, {W::integer(),H::integer()}} |
+ {style, integer()} |
+ {validator, wx:wx_object()} |
+ {onGetItemText, function()} |
+ {onGetItemAttr, function()} |
+ {onGetItemColumnImage, function()}.
new(#wx_ref{type=ParentT,ref=ParentRef}, Options)
when is_list(Options)->
@@ -101,26 +104,27 @@ wxListCtrl_new_2>>
<<EXPORT:Create create/2, create/3 Create:EXPORT>>
<<Create
-%% @spec (This::wxListCtrl(), Parent::wxWindow:wxWindow()) -> bool()
%% @equiv create(This,Parent, [])
+-spec create(This, Parent) -> wxListCtrl() when
+ This::wxWindow:wxWindow(),
+ Parent::wxWindow:wxWindow().
create(This,Parent)
when is_record(This, wx_ref),is_record(Parent, wx_ref) ->
create(This,Parent, []).
-%% @spec (This::wxListCtrl(), Parent::wxWindow:wxWindow(), [Option]) -> bool()
-%% Option = {winid, integer()} |
-%% {pos, {X::integer(),Y::integer()}} |
-%% {size, {W::integer(),H::integer()}} |
-%% {style, integer()} |
-%% {validator, wx:wx()} |
-%% {onGetItemText, OnGetItemText} |
-%% {onGetItemAttr, OnGetItemAttr} |
-%% {onGetItemColumnImage, OnGetItemColumnImage}
-%%
-%% OnGetItemText = (This, Item, Column) -> wxString()
-%% OnGetItemAttr = (This, Item) -> wxListItemAttr()
-%% OnGetItemColumnImage = (This, Item, Column) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlcreate">external documentation</a>.
+-spec create(This, Parent, [Option]) -> wxListCtrl() when
+ This::wxWindow:wxWindow(),
+ Parent::wxWindow:wxWindow(),
+ Option::{winid, integer()} |
+ {pos, {X::integer(),Y::integer()}} |
+ {size, {W::integer(),H::integer()}} |
+ {style, integer()} |
+ {validator, wx:wx_object()} |
+ {onGetItemText, function()} |
+ {onGetItemAttr, function()} |
+ {onGetItemColumnImage, function()}.
+
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options)
when is_list(Options) ->
?CLASS(ThisT,wxListCtrl),
diff --git a/lib/wx/api_gen/wx_extra/wxXmlResource.erl b/lib/wx/api_gen/wx_extra/wxXmlResource.erl
index 7700e2333e..b29ffba7c6 100644
--- a/lib/wx/api_gen/wx_extra/wxXmlResource.erl
+++ b/lib/wx/api_gen/wx_extra/wxXmlResource.erl
@@ -21,8 +21,6 @@
<<EXPORT:xrcctrl xrcctrl/3 xrcctrl:EXPORT>>
<<xrcctrl
-%% @spec (Window::wxWindow:wxWindow(),Name::string(), Type::atom()) -> wx:wxObject()
-
%% @doc Looks up a control with Name in a window created with XML
%% resources. You can use it to set/get values from controls.
%% The object is type casted to <b>Type</b>.
@@ -32,6 +30,10 @@
%% true = wxXmlResource:loadDialog(Xrc, Dlg, Frame, "controls_dialog"), <br />
%% LCtrl = xrcctrl(Dlg, "controls_listctrl", wxListCtrl), <br />
%% wxListCtrl:insertColumn(LCtrl, 0, "Name", [{width, 200}]), <br />
+-spec xrcctrl(Window, Name, Type) -> wx:wx_object() when
+ Window::wxWindow:wxWindow(),
+ Name::string(),
+ Type::atom().
xrcctrl(Window = #wx_ref{}, Name, Type) when is_list(Name), is_atom(Type) ->
%% Func Id ~s
diff --git a/lib/wx/api_gen/wx_gen.erl b/lib/wx/api_gen/wx_gen.erl
index cfae2197f8..6979a600f3 100644
--- a/lib/wx/api_gen/wx_gen.erl
+++ b/lib/wx/api_gen/wx_gen.erl
@@ -271,33 +271,31 @@ parse_attr1([{{attr,_}, #xmlElement{content=C, attributes=Attrs}}|R], AttrList0,
#param{where=nowhere} ->
parse_attr1(R,AttrList0,Opts,Res);
_ ->
- case keysearch(prot, #xmlAttribute.name, Attrs) of
- {value, #xmlAttribute{value = "public"}} ->
- {Acc,AttrList} = attr_acc(Param0, AttrList0),
- parse_attr1(R,AttrList,Opts,
- [Param0#param{in=false,prot=public,acc=Acc}|Res]);
- {value, #xmlAttribute{value = "protected"}} ->
- {Acc,AttrList} = attr_acc(Param0, AttrList0),
- parse_attr1(R,AttrList,Opts,
- [Param0#param{in=false,prot=protected,acc=Acc}|Res]);
- {value, #xmlAttribute{value = "private"}} ->
- {Acc,AttrList} = attr_acc(Param0, AttrList0),
- parse_attr1(R,AttrList,Opts,
- [Param0#param{in=false,prot=private,acc=Acc}|Res])
- end
+ {value, #xmlAttribute{value=Type}} =
+ keysearch(prot, #xmlAttribute.name, Attrs),
+ {Param,AttrList} = attr_acc(Param0, list_to_atom(Type), AttrList0),
+ parse_attr1(R,AttrList,Opts,[Param|Res])
end;
parse_attr1([{_Id,_}|R],AttrList,Info, Res) ->
parse_attr1(R,AttrList,Info, Res);
parse_attr1([],Left,_, Res) ->
{reverse(Res), Left}.
-attr_acc(#param{name=N}, List) ->
+attr_acc(#param{name=N}=P, Type, List) ->
Name = list_to_atom(N),
case get_value(Name, List, undefined) of
- undefined -> {undefined, List};
- Val -> {Val, lists:keydelete(Name,1,List)}
+ undefined -> {P#param{in=false,prot=Type,acc=undefined}, List};
+ Val when is_list(Val), is_integer(hd(Val)) ->
+ %% Function String
+ {P#param{in=false,prot=Type,acc=Val}, lists:keydelete(Name,1,List)};
+ OptList when is_list(OptList) ->
+ Param = foldl(fun handle_param_opt/2,P,OptList),
+ {Param#param{in=false,prot=Type,acc=undefined},
+ lists:keydelete(Name,1,List)};
+ Val ->
+ {P#param{in=false,prot=Type,acc=Val}, lists:keydelete(Name,1,List)}
end.
-
+
load_members(FileName, Class, Defs, Tab, Type,Opts) ->
File = filename:join(["wx_xml",FileName ++ ".xml"]),
put({loaded, FileName}, true),
diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl
index 84d3990786..573abfa9b8 100644
--- a/lib/wx/api_gen/wx_gen_cpp.erl
+++ b/lib/wx/api_gen/wx_gen_cpp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -627,7 +627,7 @@ decode_arg(N,#type{name="wxArrayString"},Place,A0) ->
w(" int * ~sLen = (int *) bp; bp += 4;~n", [N]),
case Place of
arg -> w(" wxArrayString ~s;~n", [N]);
- opt -> ignore %% Allready declared
+ opt -> ignore %% Already declared
end,
w(" int ~sASz = 0, * ~sTemp;~n", [N,N]),
w(" for(int i=0; i < *~sLen; i++) {~n", [N]),
@@ -1079,6 +1079,13 @@ build_ret(Name,_,#type{base=string,single=true}) ->
w(" rt.add(~s);~n",[Name]);
build_ret(Name,_,#type{name="wxArrayString", single=array}) ->
w(" rt.add(~s);~n", [Name]);
+build_ret(Name,_,#type{name="wxString", single={list,Variable}}) ->
+ Obj = case Name of
+ "ev->" ++ _ -> "ev";
+ _ -> "This"
+ end,
+ w(" wxArrayString tmpArrayStr(~s->~s, ~s);~n", [Obj,Variable,Name]),
+ w(" rt.add(tmpArrayStr);~n", []);
build_ret(Name,In,T) ->
?error({nyi, Name,In, T}).
@@ -1309,7 +1316,8 @@ encode_events(Evs) ->
w(" } else {~n"),
w(" send_res = rt.send();~n"),
w(" if(cb->skip) event->Skip();~n"),
- w(" if(app->recurse_level < 1) {~n"),
+ #class{id=MouseId} = lists:keyfind("wxMouseEvent", #class.name, Evs),
+ w(" if(app->recurse_level < 1 && Etype->cID != ~p) {~n", [MouseId]),
w(" app->recurse_level++;~n"),
w(" app->dispatch_cmds();~n"),
w(" app->recurse_level--;~n"),
diff --git a/lib/wx/api_gen/wx_gen_erl.erl b/lib/wx/api_gen/wx_gen_erl.erl
index 794de25002..e272c08d90 100644
--- a/lib/wx/api_gen/wx_gen_erl.erl
+++ b/lib/wx/api_gen/wx_gen_erl.erl
@@ -649,7 +649,7 @@ guard_test(#param{def=Def}) when Def =/= none -> skip;
guard_test(#param{where=c}) -> skip;
guard_test(#param{in=In}) when In == false -> skip;
guard_test(#param{name=N, type=#type{base=string}}) ->
- "is_list(" ++ erl_arg_name(N) ++")";
+ "?is_chardata(" ++ erl_arg_name(N) ++")";
guard_test(#param{name=N, type=#type{name="wxArtClient"}}) ->
"is_list(" ++ erl_arg_name(N) ++")";
guard_test(#param{name=N, type=#type{name="wxArrayString"}}) ->
@@ -801,8 +801,13 @@ doc_arg_type(_, _) -> skip.
doc_arg_type2(T) ->
doc_arg_type2(T, in).
-doc_arg_type2(T=#type{single=Single}, Out) when Single =:= array; Single =:= list ->
- "[" ++ doc_arg_type3(T, Out) ++ "]";
+doc_arg_type2(T=#type{single=Single}, Out) ->
+ case Single of
+ array -> "[" ++ doc_arg_type3(T, Out) ++ "]";
+ list -> "[" ++ doc_arg_type3(T, Out) ++ "]";
+ {list, _} -> "[" ++ doc_arg_type3(T, Out) ++ "]";
+ true -> doc_arg_type3(T, Out)
+ end;
doc_arg_type2(T, Out) ->
doc_arg_type3(T, Out).
@@ -1207,7 +1212,7 @@ gen_event_recs() ->
w("-type wx() :: #wx{}. %% wx event record ~n",[]),
w("%% Here comes the definitions of all event records.~n"
"%% they contain the event type and possible some extra information.~n~n",[]),
- Events = [build_event_rec(C) || {_,C=#class{event=Evs}} <- get(), Evs =/= false],
+ Events = [build_event_rec(C) || {_,C=#class{event=Evs}} <- lists:sort(get()), Evs =/= false],
EventSubTypes = [Type || {_Rec, Type} <- Events],
EventRecs = [Rec || {Rec, _Type} <- Events],
w("-type event() :: ~s.~n",
diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf
index 786e536f93..a0dfa61dd1 100644
--- a/lib/wx/api_gen/wxapi.conf
+++ b/lib/wx/api_gen/wxapi.conf
@@ -104,7 +104,8 @@
'Center','CenterOnParent','Centre','CentreOnParent','ClearBackground',
{'ClientToScreen',[{"x",both},{"y",both}]}, 'Close',
'ConvertDialogToPixels','ConvertPixelsToDialog','Destroy','DestroyChildren',
- 'Disable',%%'DoGetBestSize','DoUpdateWindowUI', 'DragAcceptFiles',
+ 'Disable',%%'DoGetBestSize','DoUpdateWindowUI',
+ {'DragAcceptFiles', [{test_if, "wxCHECK_VERSION(2,8,10)"}]},
'Enable',
'FindFocus','FindWindow','FindWindowById','FindWindowByName','FindWindowByLabel',
'Fit','FitInside','Freeze', 'GetAcceleratorTable', % 'GetAccessible',
@@ -154,7 +155,8 @@
{'SetTransparent', [{test_if, "wxCHECK_VERSION(2,8,12)"}]},
{'CanSetTransparent', [{test_if, "wxCHECK_VERSION(2,8,12)"}]},
{'IsDoubleBuffered', [{test_if, "wxCHECK_VERSION(3,0,0)"}]},
- {'SetDoubleBuffered', [{test_if, "wxCHECK_VERSION(3,0,0) && !defined(__WXMAC__)"}]}
+ {'SetDoubleBuffered', [{test_if, "wxCHECK_VERSION(3,0,0) && !defined(__WXMAC__)"}]},
+ {'GetContentScaleFactor', [{test_if, "wxCHECK_VERSION(2,9,5)"}]}
]}.
{class, wxTopLevelWindowGTK, wxWindow,
@@ -1490,8 +1492,6 @@
['ButtonDown','ButtonIsDown','ButtonUp','GetButtonChange','GetButtonState',
'GetJoystick','GetPosition','GetZPosition','IsButton','IsMove','IsZMove']}.
-%% {class, wxDropFilesEvent, wxEvent, [{event,[wxEVT_DROP_FILES]}],[]}. %FIXME
-
{enum, wxUpdateUIMode, "wxUPDATE_UI_"}.
{class, wxUpdateUIEvent, wxCommandEvent,
@@ -1988,3 +1988,10 @@
{class, wxDCOverlay, root, [],
['wxDCOverlay', '~wxDCOverlay', 'Clear']}.
+
+{class, wxDropFilesEvent, wxEvent,
+ [{acc, [{m_files, [{single, {list, 'm_noFiles'}}]}]},
+ {event,[wxEVT_DROP_FILES]}],
+ ['GetPosition', 'GetNumberOfFiles',
+ {'GetFiles', [{return, [{single, {list, 'm_noFiles'}}]}]}
+ ]}.
diff --git a/lib/wx/c_src/egl_impl.h b/lib/wx/c_src/egl_impl.h
index 719b4926db..f52f68c84a 100644
--- a/lib/wx/c_src/egl_impl.h
+++ b/lib/wx/c_src/egl_impl.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2010-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -112,7 +112,7 @@ typedef long int int32_t;
typedef long long int int64_t;
typedef unsigned long long int uint64_t;
#elif defined(WIN32) && defined(_MSC_VER)
-typedef long int int32_t;
+typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#elif defined(WIN32) && defined(__GNUC__)
diff --git a/lib/wx/c_src/gen/gl_funcs.cpp b/lib/wx/c_src/gen/gl_funcs.cpp
index 4dd3ad44ef..bc8d5bbdca 100644
--- a/lib/wx/c_src/gen/gl_funcs.cpp
+++ b/lib/wx/c_src/gen/gl_funcs.cpp
@@ -815,7 +815,7 @@ case 5107: { // glCallList
}; break;
case 5108: { // glCallLists
int * listsLen = (int *) bp; bp += 4;
- GLuint * lists = (GLuint *) bp; bp += (8-((*listsLen*4+4)%8))%8;
+ GLuint * lists = (GLuint *) bp; bp += *listsLen*4 + (8-((*listsLen*4+4)%8))%8;
weglCallLists(*listsLen,GL_UNSIGNED_INT,lists);
}; break;
case 5109: { // glListBase
@@ -1866,7 +1866,7 @@ case 5271: { // glGenTextures
}; break;
case 5272: { // glDeleteTextures
int * texturesLen = (int *) bp; bp += 4;
- GLuint * textures = (GLuint *) bp; bp += (8-((*texturesLen*4+4)%8))%8;
+ GLuint * textures = (GLuint *) bp; bp += *texturesLen*4 + (8-((*texturesLen*4+4)%8))%8;
weglDeleteTextures(*texturesLen,textures);
}; break;
case 5273: { // glBindTexture
@@ -1876,14 +1876,14 @@ case 5273: { // glBindTexture
}; break;
case 5274: { // glPrioritizeTextures
int * texturesLen = (int *) bp; bp += 4;
- GLuint * textures = (GLuint *) bp; bp += (8-((*texturesLen*4+4)%8))%8;
+ GLuint * textures = (GLuint *) bp; bp += *texturesLen*4 + (8-((*texturesLen*4+4)%8))%8;
int * prioritiesLen = (int *) bp; bp += 4;
- GLclampf * priorities = (GLclampf *) bp; bp += (8-((*prioritiesLen*4+4)%8))%8;
+ GLclampf * priorities = (GLclampf *) bp; bp += *prioritiesLen*4 + (8-((*prioritiesLen*4+4)%8))%8;
weglPrioritizeTextures(*texturesLen,textures,priorities);
}; break;
case 5275: { // glAreTexturesResident
int * texturesLen = (int *) bp; bp += 4;
- GLuint * textures = (GLuint *) bp; bp += (8-((*texturesLen*4+4)%8))%8;
+ GLuint * textures = (GLuint *) bp; bp += *texturesLen*4 + (8-((*texturesLen*4+4)%8))%8;
GLboolean *residences;
residences = (GLboolean *) driver_alloc(sizeof(GLboolean) * *texturesLen);
GLboolean result = weglAreTexturesResident(*texturesLen,textures,residences);
@@ -2921,132 +2921,140 @@ case 5394: { // glBlendFuncSeparate
case 5395: { // glMultiDrawArrays
GLenum *mode = (GLenum *) bp; bp += 4;
int * firstLen = (int *) bp; bp += 4;
- GLint * first = (GLint *) bp; bp += (8-((*firstLen*4+0)%8))%8;
+ GLint * first = (GLint *) bp; bp += *firstLen*4 + (8-((*firstLen*4+0)%8))%8;
int * countLen = (int *) bp; bp += 4;
- GLsizei * count = (GLsizei *) bp; bp += (8-((*countLen*4+4)%8))%8;
- weglMultiDrawArrays(*mode,first,count,*firstLen);
+ GLsizei * count = (GLsizei *) bp; bp += *countLen*4 + (8-((*countLen*4+4)%8))%8;
+ weglMultiDrawArrays(*mode,first,count,*countLen);
}; break;
-case 5396: { // glPointParameterf
+case 5396: { // glMultiDrawArrays
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLint *first = (GLint *) bins[0];
+ int * firstLen = (int *) bp; bp += 4; (void) firstLen;
+ GLsizei *count = (GLsizei *) bins[1];
+ int * countLen = (int *) bp; bp += 4; (void) countLen;
+ weglMultiDrawArrays(*mode,first,count,*countLen);
+}; break;
+case 5397: { // glPointParameterf
GLenum *pname = (GLenum *) bp; bp += 4;
GLfloat *param = (GLfloat *) bp; bp += 4;
weglPointParameterf(*pname,*param);
}; break;
-case 5397: { // glPointParameterfv
+case 5398: { // glPointParameterfv
GLenum *pname = (GLenum *) bp; bp += 4;
int *paramsLen = (int *) bp; bp += 4;
GLfloat *params = (GLfloat *) bp; bp += *paramsLen*4+((*paramsLen)+0)%2*4;
weglPointParameterfv(*pname,params);
}; break;
-case 5398: { // glPointParameteri
+case 5399: { // glPointParameteri
GLenum *pname = (GLenum *) bp; bp += 4;
GLint *param = (GLint *) bp; bp += 4;
weglPointParameteri(*pname,*param);
}; break;
-case 5399: { // glPointParameteriv
+case 5400: { // glPointParameteriv
GLenum *pname = (GLenum *) bp; bp += 4;
int *paramsLen = (int *) bp; bp += 4;
GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+0)%2*4;
weglPointParameteriv(*pname,params);
}; break;
-case 5400: { // glFogCoordfv
+case 5401: { // glFogCoordfv
GLfloat *coord = (GLfloat *) bp; bp += 4;
weglFogCoordfv(coord);
}; break;
-case 5401: { // glFogCoorddv
+case 5402: { // glFogCoorddv
GLdouble *coord = (GLdouble *) bp; bp += 8;
weglFogCoorddv(coord);
}; break;
-case 5402: { // glFogCoordPointer
+case 5403: { // glFogCoordPointer
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
GLvoid *pointer = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglFogCoordPointer(*type,*stride,pointer);
}; break;
-case 5403: { // glFogCoordPointer
+case 5404: { // glFogCoordPointer
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
GLvoid *pointer = (GLvoid *) bins[0];
weglFogCoordPointer(*type,*stride,pointer);
}; break;
-case 5404: { // glSecondaryColor3bv
+case 5405: { // glSecondaryColor3bv
GLbyte *v = (GLbyte *) bp; bp += 1;
weglSecondaryColor3bv(v);
}; break;
-case 5405: { // glSecondaryColor3dv
+case 5406: { // glSecondaryColor3dv
GLdouble *v = (GLdouble *) bp; bp += 8;
weglSecondaryColor3dv(v);
}; break;
-case 5406: { // glSecondaryColor3fv
+case 5407: { // glSecondaryColor3fv
GLfloat *v = (GLfloat *) bp; bp += 4;
weglSecondaryColor3fv(v);
}; break;
-case 5407: { // glSecondaryColor3iv
+case 5408: { // glSecondaryColor3iv
GLint *v = (GLint *) bp; bp += 4;
weglSecondaryColor3iv(v);
}; break;
-case 5408: { // glSecondaryColor3sv
+case 5409: { // glSecondaryColor3sv
GLshort *v = (GLshort *) bp; bp += 2;
weglSecondaryColor3sv(v);
}; break;
-case 5409: { // glSecondaryColor3ubv
+case 5410: { // glSecondaryColor3ubv
GLubyte *v = (GLubyte *) bp; bp += 1;
weglSecondaryColor3ubv(v);
}; break;
-case 5410: { // glSecondaryColor3uiv
+case 5411: { // glSecondaryColor3uiv
GLuint *v = (GLuint *) bp; bp += 4;
weglSecondaryColor3uiv(v);
}; break;
-case 5411: { // glSecondaryColor3usv
+case 5412: { // glSecondaryColor3usv
GLushort *v = (GLushort *) bp; bp += 2;
weglSecondaryColor3usv(v);
}; break;
-case 5412: { // glSecondaryColorPointer
+case 5413: { // glSecondaryColorPointer
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
GLvoid *pointer = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglSecondaryColorPointer(*size,*type,*stride,pointer);
}; break;
-case 5413: { // glSecondaryColorPointer
+case 5414: { // glSecondaryColorPointer
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
GLvoid *pointer = (GLvoid *) bins[0];
weglSecondaryColorPointer(*size,*type,*stride,pointer);
}; break;
-case 5414: { // glWindowPos2dv
+case 5415: { // glWindowPos2dv
GLdouble *v = (GLdouble *) bp; bp += 8;
weglWindowPos2dv(v);
}; break;
-case 5415: { // glWindowPos2fv
+case 5416: { // glWindowPos2fv
GLfloat *v = (GLfloat *) bp; bp += 4;
weglWindowPos2fv(v);
}; break;
-case 5416: { // glWindowPos2iv
+case 5417: { // glWindowPos2iv
GLint *v = (GLint *) bp; bp += 4;
weglWindowPos2iv(v);
}; break;
-case 5417: { // glWindowPos2sv
+case 5418: { // glWindowPos2sv
GLshort *v = (GLshort *) bp; bp += 2;
weglWindowPos2sv(v);
}; break;
-case 5418: { // glWindowPos3dv
+case 5419: { // glWindowPos3dv
GLdouble *v = (GLdouble *) bp; bp += 8;
weglWindowPos3dv(v);
}; break;
-case 5419: { // glWindowPos3fv
+case 5420: { // glWindowPos3fv
GLfloat *v = (GLfloat *) bp; bp += 4;
weglWindowPos3fv(v);
}; break;
-case 5420: { // glWindowPos3iv
+case 5421: { // glWindowPos3iv
GLint *v = (GLint *) bp; bp += 4;
weglWindowPos3iv(v);
}; break;
-case 5421: { // glWindowPos3sv
+case 5422: { // glWindowPos3sv
GLshort *v = (GLshort *) bp; bp += 2;
weglWindowPos3sv(v);
}; break;
-case 5422: { // glGenQueries
+case 5423: { // glGenQueries
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *ids;
ids = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -3062,12 +3070,12 @@ case 5422: { // glGenQueries
driver_free(rt);
driver_free(ids);
}; break;
-case 5423: { // glDeleteQueries
+case 5424: { // glDeleteQueries
int * idsLen = (int *) bp; bp += 4;
- GLuint * ids = (GLuint *) bp; bp += (8-((*idsLen*4+4)%8))%8;
+ GLuint * ids = (GLuint *) bp; bp += *idsLen*4 + (8-((*idsLen*4+4)%8))%8;
weglDeleteQueries(*idsLen,ids);
}; break;
-case 5424: { // glIsQuery
+case 5425: { // glIsQuery
GLuint *id = (GLuint *) bp; bp += 4;
GLboolean result = weglIsQuery(*id);
int AP = 0; ErlDrvTermData rt[6];
@@ -3076,16 +3084,16 @@ case 5424: { // glIsQuery
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5425: { // glBeginQuery
+case 5426: { // glBeginQuery
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
weglBeginQuery(*target,*id);
}; break;
-case 5426: { // glEndQuery
+case 5427: { // glEndQuery
GLenum *target = (GLenum *) bp; bp += 4;
weglEndQuery(*target);
}; break;
-case 5427: { // glGetQueryiv
+case 5428: { // glGetQueryiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -3096,7 +3104,7 @@ case 5427: { // glGetQueryiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5428: { // glGetQueryObjectiv
+case 5429: { // glGetQueryObjectiv
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -3107,7 +3115,7 @@ case 5428: { // glGetQueryObjectiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5429: { // glGetQueryObjectuiv
+case 5430: { // glGetQueryObjectuiv
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint params[1] = {0};
@@ -3118,17 +3126,17 @@ case 5429: { // glGetQueryObjectuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5430: { // glBindBuffer
+case 5431: { // glBindBuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *buffer = (GLuint *) bp; bp += 4;
weglBindBuffer(*target,*buffer);
}; break;
-case 5431: { // glDeleteBuffers
+case 5432: { // glDeleteBuffers
int * buffersLen = (int *) bp; bp += 4;
- GLuint * buffers = (GLuint *) bp; bp += (8-((*buffersLen*4+4)%8))%8;
+ GLuint * buffers = (GLuint *) bp; bp += *buffersLen*4 + (8-((*buffersLen*4+4)%8))%8;
weglDeleteBuffers(*buffersLen,buffers);
}; break;
-case 5432: { // glGenBuffers
+case 5433: { // glGenBuffers
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *buffers;
buffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -3144,7 +3152,7 @@ case 5432: { // glGenBuffers
driver_free(rt);
driver_free(buffers);
}; break;
-case 5433: { // glIsBuffer
+case 5434: { // glIsBuffer
GLuint *buffer = (GLuint *) bp; bp += 4;
GLboolean result = weglIsBuffer(*buffer);
int AP = 0; ErlDrvTermData rt[6];
@@ -3153,7 +3161,7 @@ case 5433: { // glIsBuffer
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5434: { // glBufferData
+case 5435: { // glBufferData
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
@@ -3161,7 +3169,7 @@ case 5434: { // glBufferData
GLenum *usage = (GLenum *) bp; bp += 4;
weglBufferData(*target,size,data,*usage);
}; break;
-case 5435: { // glBufferData
+case 5436: { // glBufferData
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
@@ -3169,7 +3177,7 @@ case 5435: { // glBufferData
GLenum *usage = (GLenum *) bp; bp += 4;
weglBufferData(*target,size,data,*usage);
}; break;
-case 5436: { // glBufferSubData
+case 5437: { // glBufferSubData
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
@@ -3177,7 +3185,7 @@ case 5436: { // glBufferSubData
GLvoid *data = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglBufferSubData(*target,offset,size,data);
}; break;
-case 5437: { // glBufferSubData
+case 5438: { // glBufferSubData
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
@@ -3185,7 +3193,7 @@ case 5437: { // glBufferSubData
GLvoid *data = (GLvoid *) bins[0];
weglBufferSubData(*target,offset,size,data);
}; break;
-case 5438: { // glGetBufferSubData
+case 5439: { // glGetBufferSubData
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
@@ -3198,7 +3206,7 @@ case 5438: { // glGetBufferSubData
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5439: { // glGetBufferParameteriv
+case 5440: { // glGetBufferParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -3209,52 +3217,52 @@ case 5439: { // glGetBufferParameteriv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5440: { // glBlendEquationSeparate
+case 5441: { // glBlendEquationSeparate
GLenum *modeRGB = (GLenum *) bp; bp += 4;
GLenum *modeAlpha = (GLenum *) bp; bp += 4;
weglBlendEquationSeparate(*modeRGB,*modeAlpha);
}; break;
-case 5441: { // glDrawBuffers
+case 5442: { // glDrawBuffers
int * bufsLen = (int *) bp; bp += 4;
- GLenum * bufs = (GLenum *) bp; bp += (8-((*bufsLen*4+4)%8))%8;
+ GLenum * bufs = (GLenum *) bp; bp += *bufsLen*4 + (8-((*bufsLen*4+4)%8))%8;
weglDrawBuffers(*bufsLen,bufs);
}; break;
-case 5442: { // glStencilOpSeparate
+case 5443: { // glStencilOpSeparate
GLenum *face = (GLenum *) bp; bp += 4;
GLenum *sfail = (GLenum *) bp; bp += 4;
GLenum *dpfail = (GLenum *) bp; bp += 4;
GLenum *dppass = (GLenum *) bp; bp += 4;
weglStencilOpSeparate(*face,*sfail,*dpfail,*dppass);
}; break;
-case 5443: { // glStencilFuncSeparate
+case 5444: { // glStencilFuncSeparate
GLenum *face = (GLenum *) bp; bp += 4;
GLenum *func = (GLenum *) bp; bp += 4;
GLint *ref = (GLint *) bp; bp += 4;
GLuint *mask = (GLuint *) bp; bp += 4;
weglStencilFuncSeparate(*face,*func,*ref,*mask);
}; break;
-case 5444: { // glStencilMaskSeparate
+case 5445: { // glStencilMaskSeparate
GLenum *face = (GLenum *) bp; bp += 4;
GLuint *mask = (GLuint *) bp; bp += 4;
weglStencilMaskSeparate(*face,*mask);
}; break;
-case 5445: { // glAttachShader
+case 5446: { // glAttachShader
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *shader = (GLuint *) bp; bp += 4;
weglAttachShader(*program,*shader);
}; break;
-case 5446: { // glBindAttribLocation
+case 5447: { // glBindAttribLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
weglBindAttribLocation(*program,*index,name);
}; break;
-case 5447: { // glCompileShader
+case 5448: { // glCompileShader
GLuint *shader = (GLuint *) bp; bp += 4;
weglCompileShader(*shader);
}; break;
-case 5448: { // glCreateProgram
+case 5449: { // glCreateProgram
GLuint result = weglCreateProgram();
int AP = 0; ErlDrvTermData rt[6];
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
@@ -3262,7 +3270,7 @@ case 5448: { // glCreateProgram
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5449: { // glCreateShader
+case 5450: { // glCreateShader
GLenum *type = (GLenum *) bp; bp += 4;
GLuint result = weglCreateShader(*type);
int AP = 0; ErlDrvTermData rt[6];
@@ -3271,28 +3279,28 @@ case 5449: { // glCreateShader
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5450: { // glDeleteProgram
+case 5451: { // glDeleteProgram
GLuint *program = (GLuint *) bp; bp += 4;
weglDeleteProgram(*program);
}; break;
-case 5451: { // glDeleteShader
+case 5452: { // glDeleteShader
GLuint *shader = (GLuint *) bp; bp += 4;
weglDeleteShader(*shader);
}; break;
-case 5452: { // glDetachShader
+case 5453: { // glDetachShader
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *shader = (GLuint *) bp; bp += 4;
weglDetachShader(*program,*shader);
}; break;
-case 5453: { // glDisableVertexAttribArray
+case 5454: { // glDisableVertexAttribArray
GLuint *index = (GLuint *) bp; bp += 4;
weglDisableVertexAttribArray(*index);
}; break;
-case 5454: { // glEnableVertexAttribArray
+case 5455: { // glEnableVertexAttribArray
GLuint *index = (GLuint *) bp; bp += 4;
weglEnableVertexAttribArray(*index);
}; break;
-case 5455: { // glGetActiveAttrib
+case 5456: { // glGetActiveAttrib
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -3312,7 +3320,7 @@ case 5455: { // glGetActiveAttrib
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5456: { // glGetActiveUniform
+case 5457: { // glGetActiveUniform
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -3332,7 +3340,7 @@ case 5456: { // glGetActiveUniform
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5457: { // glGetAttachedShaders
+case 5458: { // glGetAttachedShaders
GLuint *program = (GLuint *) bp; bp += 4;
GLsizei *maxCount = (GLsizei *) bp; bp += 4;
GLsizei count[1] = {0};
@@ -3350,7 +3358,7 @@ case 5457: { // glGetAttachedShaders
driver_free(rt);
driver_free(obj);
}; break;
-case 5458: { // glGetAttribLocation
+case 5459: { // glGetAttribLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
@@ -3361,7 +3369,7 @@ case 5458: { // glGetAttribLocation
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5459: { // glGetProgramiv
+case 5460: { // glGetProgramiv
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -3372,7 +3380,7 @@ case 5459: { // glGetProgramiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5460: { // glGetProgramInfoLog
+case 5461: { // glGetProgramInfoLog
GLuint *program = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -3386,7 +3394,7 @@ case 5460: { // glGetProgramInfoLog
driver_send_term(port,caller,rt,AP);
driver_free(infoLog);
}; break;
-case 5461: { // glGetShaderiv
+case 5462: { // glGetShaderiv
GLuint *shader = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -3397,7 +3405,7 @@ case 5461: { // glGetShaderiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5462: { // glGetShaderInfoLog
+case 5463: { // glGetShaderInfoLog
GLuint *shader = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -3411,7 +3419,7 @@ case 5462: { // glGetShaderInfoLog
driver_send_term(port,caller,rt,AP);
driver_free(infoLog);
}; break;
-case 5463: { // glGetShaderSource
+case 5464: { // glGetShaderSource
GLuint *shader = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -3425,7 +3433,7 @@ case 5463: { // glGetShaderSource
driver_send_term(port,caller,rt,AP);
driver_free(source);
}; break;
-case 5464: { // glGetUniformLocation
+case 5465: { // glGetUniformLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
@@ -3436,7 +3444,7 @@ case 5464: { // glGetUniformLocation
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5465: { // glGetUniformfv
+case 5466: { // glGetUniformfv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLfloat params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
@@ -3465,7 +3473,7 @@ case 5465: { // glGetUniformfv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5466: { // glGetUniformiv
+case 5467: { // glGetUniformiv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -3493,7 +3501,7 @@ case 5466: { // glGetUniformiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5467: { // glGetVertexAttribdv
+case 5468: { // glGetVertexAttribdv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLdouble params[4] = {0.0,0.0,0.0,0.0};
@@ -3509,7 +3517,7 @@ case 5467: { // glGetVertexAttribdv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5468: { // glGetVertexAttribfv
+case 5469: { // glGetVertexAttribfv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLfloat params[4] = {0.0,0.0,0.0,0.0};
@@ -3526,7 +3534,7 @@ case 5468: { // glGetVertexAttribfv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5469: { // glGetVertexAttribiv
+case 5470: { // glGetVertexAttribiv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[4] = {0,0,0,0};
@@ -3542,7 +3550,7 @@ case 5469: { // glGetVertexAttribiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5470: { // glIsProgram
+case 5471: { // glIsProgram
GLuint *program = (GLuint *) bp; bp += 4;
GLboolean result = weglIsProgram(*program);
int AP = 0; ErlDrvTermData rt[6];
@@ -3551,7 +3559,7 @@ case 5470: { // glIsProgram
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5471: { // glIsShader
+case 5472: { // glIsShader
GLuint *shader = (GLuint *) bp; bp += 4;
GLboolean result = weglIsShader(*shader);
int AP = 0; ErlDrvTermData rt[6];
@@ -3560,11 +3568,11 @@ case 5471: { // glIsShader
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5472: { // glLinkProgram
+case 5473: { // glLinkProgram
GLuint *program = (GLuint *) bp; bp += 4;
weglLinkProgram(*program);
}; break;
-case 5473: { // glShaderSource
+case 5474: { // glShaderSource
GLuint *shader = (GLuint *) bp; bp += 4;
int * stringLen = (int *) bp; bp += 4;
int * stringTotSize = (int *) bp; bp += 4;
@@ -3576,29 +3584,29 @@ case 5473: { // glShaderSource
weglShaderSource(*shader,*stringLen,(const GLchar **) string,NULL);
driver_free(string);
}; break;
-case 5474: { // glUseProgram
+case 5475: { // glUseProgram
GLuint *program = (GLuint *) bp; bp += 4;
weglUseProgram(*program);
}; break;
-case 5475: { // glUniform1f
+case 5476: { // glUniform1f
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
weglUniform1f(*location,*v0);
}; break;
-case 5476: { // glUniform2f
+case 5477: { // glUniform2f
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
GLfloat *v1 = (GLfloat *) bp; bp += 4;
weglUniform2f(*location,*v0,*v1);
}; break;
-case 5477: { // glUniform3f
+case 5478: { // glUniform3f
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
GLfloat *v1 = (GLfloat *) bp; bp += 4;
GLfloat *v2 = (GLfloat *) bp; bp += 4;
weglUniform3f(*location,*v0,*v1,*v2);
}; break;
-case 5478: { // glUniform4f
+case 5479: { // glUniform4f
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
GLfloat *v1 = (GLfloat *) bp; bp += 4;
@@ -3606,25 +3614,25 @@ case 5478: { // glUniform4f
GLfloat *v3 = (GLfloat *) bp; bp += 4;
weglUniform4f(*location,*v0,*v1,*v2,*v3);
}; break;
-case 5479: { // glUniform1i
+case 5480: { // glUniform1i
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
weglUniform1i(*location,*v0);
}; break;
-case 5480: { // glUniform2i
+case 5481: { // glUniform2i
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
GLint *v1 = (GLint *) bp; bp += 4;
weglUniform2i(*location,*v0,*v1);
}; break;
-case 5481: { // glUniform3i
+case 5482: { // glUniform3i
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
GLint *v1 = (GLint *) bp; bp += 4;
GLint *v2 = (GLint *) bp; bp += 4;
weglUniform3i(*location,*v0,*v1,*v2);
}; break;
-case 5482: { // glUniform4i
+case 5483: { // glUniform4i
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
GLint *v1 = (GLint *) bp; bp += 4;
@@ -3632,55 +3640,55 @@ case 5482: { // glUniform4i
GLint *v3 = (GLint *) bp; bp += 4;
weglUniform4i(*location,*v0,*v1,*v2,*v3);
}; break;
-case 5483: { // glUniform1fv
+case 5484: { // glUniform1fv
GLint *location = (GLint *) bp; bp += 4;
int * valueLen = (int *) bp; bp += 4;
- GLfloat * value = (GLfloat *) bp; bp += (8-((*valueLen*4+0)%8))%8;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*4 + (8-((*valueLen*4+0)%8))%8;
weglUniform1fv(*location,*valueLen,value);
}; break;
-case 5484: { // glUniform2fv
+case 5485: { // glUniform2fv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLfloat * value = (GLfloat *) bp; bp += *valueLen*8;
weglUniform2fv(*location,*valueLen,value);
}; break;
-case 5485: { // glUniform3fv
+case 5486: { // glUniform3fv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLfloat * value = (GLfloat *) bp; bp += *valueLen*12;
weglUniform3fv(*location,*valueLen,value);
}; break;
-case 5486: { // glUniform4fv
+case 5487: { // glUniform4fv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLfloat * value = (GLfloat *) bp; bp += *valueLen*16;
weglUniform4fv(*location,*valueLen,value);
}; break;
-case 5487: { // glUniform1iv
+case 5488: { // glUniform1iv
GLint *location = (GLint *) bp; bp += 4;
int * valueLen = (int *) bp; bp += 4;
- GLint * value = (GLint *) bp; bp += (8-((*valueLen*4+0)%8))%8;
+ GLint * value = (GLint *) bp; bp += *valueLen*4 + (8-((*valueLen*4+0)%8))%8;
weglUniform1iv(*location,*valueLen,value);
}; break;
-case 5488: { // glUniform2iv
+case 5489: { // glUniform2iv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLint * value = (GLint *) bp; bp += *valueLen*8;
weglUniform2iv(*location,*valueLen,value);
}; break;
-case 5489: { // glUniform3iv
+case 5490: { // glUniform3iv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLint * value = (GLint *) bp; bp += *valueLen*12;
weglUniform3iv(*location,*valueLen,value);
}; break;
-case 5490: { // glUniform4iv
+case 5491: { // glUniform4iv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLint * value = (GLint *) bp; bp += *valueLen*16;
weglUniform4iv(*location,*valueLen,value);
}; break;
-case 5491: { // glUniformMatrix2fv
+case 5492: { // glUniformMatrix2fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3688,7 +3696,7 @@ case 5491: { // glUniformMatrix2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*16;
weglUniformMatrix2fv(*location,*valueLen,*transpose,value);
}; break;
-case 5492: { // glUniformMatrix3fv
+case 5493: { // glUniformMatrix3fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3696,7 +3704,7 @@ case 5492: { // glUniformMatrix3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*36;
weglUniformMatrix3fv(*location,*valueLen,*transpose,value);
}; break;
-case 5493: { // glUniformMatrix4fv
+case 5494: { // glUniformMatrix4fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3704,130 +3712,130 @@ case 5493: { // glUniformMatrix4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*64;
weglUniformMatrix4fv(*location,*valueLen,*transpose,value);
}; break;
-case 5494: { // glValidateProgram
+case 5495: { // glValidateProgram
GLuint *program = (GLuint *) bp; bp += 4;
weglValidateProgram(*program);
}; break;
-case 5495: { // glVertexAttrib1dv
+case 5496: { // glVertexAttrib1dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttrib1dv(*index,v);
}; break;
-case 5496: { // glVertexAttrib1fv
+case 5497: { // glVertexAttrib1fv
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *v = (GLfloat *) bp; bp += 4;
weglVertexAttrib1fv(*index,v);
}; break;
-case 5497: { // glVertexAttrib1sv
+case 5498: { // glVertexAttrib1sv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort *v = (GLshort *) bp; bp += 2;
weglVertexAttrib1sv(*index,v);
}; break;
-case 5498: { // glVertexAttrib2dv
+case 5499: { // glVertexAttrib2dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttrib2dv(*index,v);
}; break;
-case 5499: { // glVertexAttrib2fv
+case 5500: { // glVertexAttrib2fv
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *v = (GLfloat *) bp; bp += 4;
weglVertexAttrib2fv(*index,v);
}; break;
-case 5500: { // glVertexAttrib2sv
+case 5501: { // glVertexAttrib2sv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort *v = (GLshort *) bp; bp += 2;
weglVertexAttrib2sv(*index,v);
}; break;
-case 5501: { // glVertexAttrib3dv
+case 5502: { // glVertexAttrib3dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttrib3dv(*index,v);
}; break;
-case 5502: { // glVertexAttrib3fv
+case 5503: { // glVertexAttrib3fv
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *v = (GLfloat *) bp; bp += 4;
weglVertexAttrib3fv(*index,v);
}; break;
-case 5503: { // glVertexAttrib3sv
+case 5504: { // glVertexAttrib3sv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort *v = (GLshort *) bp; bp += 2;
weglVertexAttrib3sv(*index,v);
}; break;
-case 5504: { // glVertexAttrib4Nbv
+case 5505: { // glVertexAttrib4Nbv
GLuint *index = (GLuint *) bp; bp += 4;
GLbyte * v = (GLbyte *) bp; bp += 4;
weglVertexAttrib4Nbv(*index,v);
}; break;
-case 5505: { // glVertexAttrib4Niv
+case 5506: { // glVertexAttrib4Niv
GLuint *index = (GLuint *) bp; bp += 4;
GLint * v = (GLint *) bp; bp += 16;
weglVertexAttrib4Niv(*index,v);
}; break;
-case 5506: { // glVertexAttrib4Nsv
+case 5507: { // glVertexAttrib4Nsv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort * v = (GLshort *) bp; bp += 8;
weglVertexAttrib4Nsv(*index,v);
}; break;
-case 5507: { // glVertexAttrib4Nubv
+case 5508: { // glVertexAttrib4Nubv
GLuint *index = (GLuint *) bp; bp += 4;
GLubyte * v = (GLubyte *) bp; bp += 4;
weglVertexAttrib4Nubv(*index,v);
}; break;
-case 5508: { // glVertexAttrib4Nuiv
+case 5509: { // glVertexAttrib4Nuiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint * v = (GLuint *) bp; bp += 16;
weglVertexAttrib4Nuiv(*index,v);
}; break;
-case 5509: { // glVertexAttrib4Nusv
+case 5510: { // glVertexAttrib4Nusv
GLuint *index = (GLuint *) bp; bp += 4;
GLushort * v = (GLushort *) bp; bp += 8;
weglVertexAttrib4Nusv(*index,v);
}; break;
-case 5510: { // glVertexAttrib4bv
+case 5511: { // glVertexAttrib4bv
GLuint *index = (GLuint *) bp; bp += 4;
GLbyte * v = (GLbyte *) bp; bp += 4;
weglVertexAttrib4bv(*index,v);
}; break;
-case 5511: { // glVertexAttrib4dv
+case 5512: { // glVertexAttrib4dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble * v = (GLdouble *) bp; bp += 32;
weglVertexAttrib4dv(*index,v);
}; break;
-case 5512: { // glVertexAttrib4fv
+case 5513: { // glVertexAttrib4fv
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat * v = (GLfloat *) bp; bp += 16;
weglVertexAttrib4fv(*index,v);
}; break;
-case 5513: { // glVertexAttrib4iv
+case 5514: { // glVertexAttrib4iv
GLuint *index = (GLuint *) bp; bp += 4;
GLint * v = (GLint *) bp; bp += 16;
weglVertexAttrib4iv(*index,v);
}; break;
-case 5514: { // glVertexAttrib4sv
+case 5515: { // glVertexAttrib4sv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort * v = (GLshort *) bp; bp += 8;
weglVertexAttrib4sv(*index,v);
}; break;
-case 5515: { // glVertexAttrib4ubv
+case 5516: { // glVertexAttrib4ubv
GLuint *index = (GLuint *) bp; bp += 4;
GLubyte * v = (GLubyte *) bp; bp += 4;
weglVertexAttrib4ubv(*index,v);
}; break;
-case 5516: { // glVertexAttrib4uiv
+case 5517: { // glVertexAttrib4uiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint * v = (GLuint *) bp; bp += 16;
weglVertexAttrib4uiv(*index,v);
}; break;
-case 5517: { // glVertexAttrib4usv
+case 5518: { // glVertexAttrib4usv
GLuint *index = (GLuint *) bp; bp += 4;
GLushort * v = (GLushort *) bp; bp += 8;
weglVertexAttrib4usv(*index,v);
}; break;
-case 5518: { // glVertexAttribPointer
+case 5519: { // glVertexAttribPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -3837,7 +3845,7 @@ case 5518: { // glVertexAttribPointer
GLvoid *pointer = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglVertexAttribPointer(*index,*size,*type,*normalized,*stride,pointer);
}; break;
-case 5519: { // glVertexAttribPointer
+case 5520: { // glVertexAttribPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -3847,7 +3855,7 @@ case 5519: { // glVertexAttribPointer
GLvoid *pointer = (GLvoid *) bins[0];
weglVertexAttribPointer(*index,*size,*type,*normalized,*stride,pointer);
}; break;
-case 5520: { // glUniformMatrix2x3fv
+case 5521: { // glUniformMatrix2x3fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3855,7 +3863,7 @@ case 5520: { // glUniformMatrix2x3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*24;
weglUniformMatrix2x3fv(*location,*valueLen,*transpose,value);
}; break;
-case 5521: { // glUniformMatrix3x2fv
+case 5522: { // glUniformMatrix3x2fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3863,7 +3871,7 @@ case 5521: { // glUniformMatrix3x2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*24;
weglUniformMatrix3x2fv(*location,*valueLen,*transpose,value);
}; break;
-case 5522: { // glUniformMatrix2x4fv
+case 5523: { // glUniformMatrix2x4fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3871,7 +3879,7 @@ case 5522: { // glUniformMatrix2x4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*32;
weglUniformMatrix2x4fv(*location,*valueLen,*transpose,value);
}; break;
-case 5523: { // glUniformMatrix4x2fv
+case 5524: { // glUniformMatrix4x2fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3879,7 +3887,7 @@ case 5523: { // glUniformMatrix4x2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*32;
weglUniformMatrix4x2fv(*location,*valueLen,*transpose,value);
}; break;
-case 5524: { // glUniformMatrix3x4fv
+case 5525: { // glUniformMatrix3x4fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3887,7 +3895,7 @@ case 5524: { // glUniformMatrix3x4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*48;
weglUniformMatrix3x4fv(*location,*valueLen,*transpose,value);
}; break;
-case 5525: { // glUniformMatrix4x3fv
+case 5526: { // glUniformMatrix4x3fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3895,7 +3903,7 @@ case 5525: { // glUniformMatrix4x3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*48;
weglUniformMatrix4x3fv(*location,*valueLen,*transpose,value);
}; break;
-case 5526: { // glColorMaski
+case 5527: { // glColorMaski
GLuint *index = (GLuint *) bp; bp += 4;
GLboolean *r = (GLboolean *) bp; bp += 1;
GLboolean *g = (GLboolean *) bp; bp += 1;
@@ -3903,7 +3911,7 @@ case 5526: { // glColorMaski
GLboolean *a = (GLboolean *) bp; bp += 1;
weglColorMaski(*index,*r,*g,*b,*a);
}; break;
-case 5527: { // glGetBooleani_v
+case 5528: { // glGetBooleani_v
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLboolean data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -3931,7 +3939,7 @@ case 5527: { // glGetBooleani_v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5528: { // glGetIntegeri_v
+case 5529: { // glGetIntegeri_v
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLint data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -3959,17 +3967,17 @@ case 5528: { // glGetIntegeri_v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5529: { // glEnablei
+case 5530: { // glEnablei
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
weglEnablei(*target,*index);
}; break;
-case 5530: { // glDisablei
+case 5531: { // glDisablei
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
weglDisablei(*target,*index);
}; break;
-case 5531: { // glIsEnabledi
+case 5532: { // glIsEnabledi
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLboolean result = weglIsEnabledi(*target,*index);
@@ -3979,14 +3987,14 @@ case 5531: { // glIsEnabledi
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5532: { // glBeginTransformFeedback
+case 5533: { // glBeginTransformFeedback
GLenum *primitiveMode = (GLenum *) bp; bp += 4;
weglBeginTransformFeedback(*primitiveMode);
}; break;
-case 5533: { // glEndTransformFeedback
+case 5534: { // glEndTransformFeedback
weglEndTransformFeedback();
}; break;
-case 5534: { // glBindBufferRange
+case 5535: { // glBindBufferRange
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *buffer = (GLuint *) bp; bp += 4;
@@ -3995,13 +4003,13 @@ case 5534: { // glBindBufferRange
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
weglBindBufferRange(*target,*index,*buffer,offset,size);
}; break;
-case 5535: { // glBindBufferBase
+case 5536: { // glBindBufferBase
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *buffer = (GLuint *) bp; bp += 4;
weglBindBufferBase(*target,*index,*buffer);
}; break;
-case 5536: { // glTransformFeedbackVaryings
+case 5537: { // glTransformFeedbackVaryings
GLuint *program = (GLuint *) bp; bp += 4;
int * varyingsLen = (int *) bp; bp += 4;
int * varyingsTotSize = (int *) bp; bp += 4;
@@ -4014,7 +4022,7 @@ case 5536: { // glTransformFeedbackVaryings
weglTransformFeedbackVaryings(*program,*varyingsLen,(const GLchar **) varyings,*bufferMode);
driver_free(varyings);
}; break;
-case 5537: { // glGetTransformFeedbackVarying
+case 5538: { // glGetTransformFeedbackVarying
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -4034,20 +4042,20 @@ case 5537: { // glGetTransformFeedbackVarying
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5538: { // glClampColor
+case 5539: { // glClampColor
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *clamp = (GLenum *) bp; bp += 4;
weglClampColor(*target,*clamp);
}; break;
-case 5539: { // glBeginConditionalRender
+case 5540: { // glBeginConditionalRender
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *mode = (GLenum *) bp; bp += 4;
weglBeginConditionalRender(*id,*mode);
}; break;
-case 5540: { // glEndConditionalRender
+case 5541: { // glEndConditionalRender
weglEndConditionalRender();
}; break;
-case 5541: { // glVertexAttribIPointer
+case 5542: { // glVertexAttribIPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -4055,7 +4063,7 @@ case 5541: { // glVertexAttribIPointer
GLvoid *pointer = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglVertexAttribIPointer(*index,*size,*type,*stride,pointer);
}; break;
-case 5542: { // glVertexAttribIPointer
+case 5543: { // glVertexAttribIPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -4063,7 +4071,7 @@ case 5542: { // glVertexAttribIPointer
GLvoid *pointer = (GLvoid *) bins[0];
weglVertexAttribIPointer(*index,*size,*type,*stride,pointer);
}; break;
-case 5543: { // glGetVertexAttribIiv
+case 5544: { // glGetVertexAttribIiv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[4] = {0,0,0,0};
@@ -4079,7 +4087,7 @@ case 5543: { // glGetVertexAttribIiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5544: { // glGetVertexAttribIuiv
+case 5545: { // glGetVertexAttribIuiv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint params[4] = {0,0,0,0};
@@ -4095,67 +4103,67 @@ case 5544: { // glGetVertexAttribIuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5545: { // glVertexAttribI1iv
+case 5546: { // glVertexAttribI1iv
GLuint *index = (GLuint *) bp; bp += 4;
GLint *v = (GLint *) bp; bp += 4;
weglVertexAttribI1iv(*index,v);
}; break;
-case 5546: { // glVertexAttribI2iv
+case 5547: { // glVertexAttribI2iv
GLuint *index = (GLuint *) bp; bp += 4;
GLint *v = (GLint *) bp; bp += 4;
weglVertexAttribI2iv(*index,v);
}; break;
-case 5547: { // glVertexAttribI3iv
+case 5548: { // glVertexAttribI3iv
GLuint *index = (GLuint *) bp; bp += 4;
GLint *v = (GLint *) bp; bp += 4;
weglVertexAttribI3iv(*index,v);
}; break;
-case 5548: { // glVertexAttribI4iv
+case 5549: { // glVertexAttribI4iv
GLuint *index = (GLuint *) bp; bp += 4;
GLint * v = (GLint *) bp; bp += 16;
weglVertexAttribI4iv(*index,v);
}; break;
-case 5549: { // glVertexAttribI1uiv
+case 5550: { // glVertexAttribI1uiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *v = (GLuint *) bp; bp += 4;
weglVertexAttribI1uiv(*index,v);
}; break;
-case 5550: { // glVertexAttribI2uiv
+case 5551: { // glVertexAttribI2uiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *v = (GLuint *) bp; bp += 4;
weglVertexAttribI2uiv(*index,v);
}; break;
-case 5551: { // glVertexAttribI3uiv
+case 5552: { // glVertexAttribI3uiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *v = (GLuint *) bp; bp += 4;
weglVertexAttribI3uiv(*index,v);
}; break;
-case 5552: { // glVertexAttribI4uiv
+case 5553: { // glVertexAttribI4uiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint * v = (GLuint *) bp; bp += 16;
weglVertexAttribI4uiv(*index,v);
}; break;
-case 5553: { // glVertexAttribI4bv
+case 5554: { // glVertexAttribI4bv
GLuint *index = (GLuint *) bp; bp += 4;
GLbyte * v = (GLbyte *) bp; bp += 4;
weglVertexAttribI4bv(*index,v);
}; break;
-case 5554: { // glVertexAttribI4sv
+case 5555: { // glVertexAttribI4sv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort * v = (GLshort *) bp; bp += 8;
weglVertexAttribI4sv(*index,v);
}; break;
-case 5555: { // glVertexAttribI4ubv
+case 5556: { // glVertexAttribI4ubv
GLuint *index = (GLuint *) bp; bp += 4;
GLubyte * v = (GLubyte *) bp; bp += 4;
weglVertexAttribI4ubv(*index,v);
}; break;
-case 5556: { // glVertexAttribI4usv
+case 5557: { // glVertexAttribI4usv
GLuint *index = (GLuint *) bp; bp += 4;
GLushort * v = (GLushort *) bp; bp += 8;
weglVertexAttribI4usv(*index,v);
}; break;
-case 5557: { // glGetUniformuiv
+case 5558: { // glGetUniformuiv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLuint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -4183,14 +4191,14 @@ case 5557: { // glGetUniformuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5558: { // glBindFragDataLocation
+case 5559: { // glBindFragDataLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *color = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
weglBindFragDataLocation(*program,*color,name);
}; break;
-case 5559: { // glGetFragDataLocation
+case 5560: { // glGetFragDataLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
@@ -4201,25 +4209,25 @@ case 5559: { // glGetFragDataLocation
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5560: { // glUniform1ui
+case 5561: { // glUniform1ui
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
weglUniform1ui(*location,*v0);
}; break;
-case 5561: { // glUniform2ui
+case 5562: { // glUniform2ui
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
GLuint *v1 = (GLuint *) bp; bp += 4;
weglUniform2ui(*location,*v0,*v1);
}; break;
-case 5562: { // glUniform3ui
+case 5563: { // glUniform3ui
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
GLuint *v1 = (GLuint *) bp; bp += 4;
GLuint *v2 = (GLuint *) bp; bp += 4;
weglUniform3ui(*location,*v0,*v1,*v2);
}; break;
-case 5563: { // glUniform4ui
+case 5564: { // glUniform4ui
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
GLuint *v1 = (GLuint *) bp; bp += 4;
@@ -4227,45 +4235,45 @@ case 5563: { // glUniform4ui
GLuint *v3 = (GLuint *) bp; bp += 4;
weglUniform4ui(*location,*v0,*v1,*v2,*v3);
}; break;
-case 5564: { // glUniform1uiv
+case 5565: { // glUniform1uiv
GLint *location = (GLint *) bp; bp += 4;
int * valueLen = (int *) bp; bp += 4;
- GLuint * value = (GLuint *) bp; bp += (8-((*valueLen*4+0)%8))%8;
+ GLuint * value = (GLuint *) bp; bp += *valueLen*4 + (8-((*valueLen*4+0)%8))%8;
weglUniform1uiv(*location,*valueLen,value);
}; break;
-case 5565: { // glUniform2uiv
+case 5566: { // glUniform2uiv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLuint * value = (GLuint *) bp; bp += *valueLen*8;
weglUniform2uiv(*location,*valueLen,value);
}; break;
-case 5566: { // glUniform3uiv
+case 5567: { // glUniform3uiv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLuint * value = (GLuint *) bp; bp += *valueLen*12;
weglUniform3uiv(*location,*valueLen,value);
}; break;
-case 5567: { // glUniform4uiv
+case 5568: { // glUniform4uiv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLuint * value = (GLuint *) bp; bp += *valueLen*16;
weglUniform4uiv(*location,*valueLen,value);
}; break;
-case 5568: { // glTexParameterIiv
+case 5569: { // glTexParameterIiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
int *paramsLen = (int *) bp; bp += 4;
GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4;
weglTexParameterIiv(*target,*pname,params);
}; break;
-case 5569: { // glTexParameterIuiv
+case 5570: { // glTexParameterIuiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
int *paramsLen = (int *) bp; bp += 4;
GLuint *params = (GLuint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4;
weglTexParameterIuiv(*target,*pname,params);
}; break;
-case 5570: { // glGetTexParameterIiv
+case 5571: { // glGetTexParameterIiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[4] = {0,0,0,0};
@@ -4281,7 +4289,7 @@ case 5570: { // glGetTexParameterIiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5571: { // glGetTexParameterIuiv
+case 5572: { // glGetTexParameterIuiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint params[4] = {0,0,0,0};
@@ -4297,35 +4305,35 @@ case 5571: { // glGetTexParameterIuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5572: { // glClearBufferiv
+case 5573: { // glClearBufferiv
GLenum *buffer = (GLenum *) bp; bp += 4;
GLint *drawbuffer = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLint *value = (GLint *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4;
weglClearBufferiv(*buffer,*drawbuffer,value);
}; break;
-case 5573: { // glClearBufferuiv
+case 5574: { // glClearBufferuiv
GLenum *buffer = (GLenum *) bp; bp += 4;
GLint *drawbuffer = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLuint *value = (GLuint *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4;
weglClearBufferuiv(*buffer,*drawbuffer,value);
}; break;
-case 5574: { // glClearBufferfv
+case 5575: { // glClearBufferfv
GLenum *buffer = (GLenum *) bp; bp += 4;
GLint *drawbuffer = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLfloat *value = (GLfloat *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4;
weglClearBufferfv(*buffer,*drawbuffer,value);
}; break;
-case 5575: { // glClearBufferfi
+case 5576: { // glClearBufferfi
GLenum *buffer = (GLenum *) bp; bp += 4;
GLint *drawbuffer = (GLint *) bp; bp += 4;
GLfloat *depth = (GLfloat *) bp; bp += 4;
GLint *stencil = (GLint *) bp; bp += 4;
weglClearBufferfi(*buffer,*drawbuffer,*depth,*stencil);
}; break;
-case 5576: { // glGetStringi
+case 5577: { // glGetStringi
GLenum *name = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
const GLubyte * result = weglGetStringi(*name,*index);
@@ -4335,14 +4343,14 @@ case 5576: { // glGetStringi
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5577: { // glDrawArraysInstanced
+case 5578: { // glDrawArraysInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
GLint *first = (GLint *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLsizei *primcount = (GLsizei *) bp; bp += 4;
weglDrawArraysInstanced(*mode,*first,*count,*primcount);
}; break;
-case 5578: { // glDrawElementsInstanced
+case 5579: { // glDrawElementsInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -4350,7 +4358,7 @@ case 5578: { // glDrawElementsInstanced
GLsizei *primcount = (GLsizei *) bp; bp += 4;
weglDrawElementsInstanced(*mode,*count,*type,indices,*primcount);
}; break;
-case 5579: { // glDrawElementsInstanced
+case 5580: { // glDrawElementsInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -4358,17 +4366,17 @@ case 5579: { // glDrawElementsInstanced
GLsizei *primcount = (GLsizei *) bp; bp += 4;
weglDrawElementsInstanced(*mode,*count,*type,indices,*primcount);
}; break;
-case 5580: { // glTexBuffer
+case 5581: { // glTexBuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
GLuint *buffer = (GLuint *) bp; bp += 4;
weglTexBuffer(*target,*internalformat,*buffer);
}; break;
-case 5581: { // glPrimitiveRestartIndex
+case 5582: { // glPrimitiveRestartIndex
GLuint *index = (GLuint *) bp; bp += 4;
weglPrimitiveRestartIndex(*index);
}; break;
-case 5582: { // glGetInteger64i_v
+case 5583: { // glGetInteger64i_v
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLint64 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -4396,7 +4404,7 @@ case 5582: { // glGetInteger64i_v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5583: { // glGetBufferParameteri64v
+case 5584: { // glGetBufferParameteri64v
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint64 params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -4424,40 +4432,40 @@ case 5583: { // glGetBufferParameteri64v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5584: { // glFramebufferTexture
+case 5585: { // glFramebufferTexture
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLuint *texture = (GLuint *) bp; bp += 4;
GLint *level = (GLint *) bp; bp += 4;
weglFramebufferTexture(*target,*attachment,*texture,*level);
}; break;
-case 5585: { // glVertexAttribDivisor
+case 5586: { // glVertexAttribDivisor
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *divisor = (GLuint *) bp; bp += 4;
weglVertexAttribDivisor(*index,*divisor);
}; break;
-case 5586: { // glMinSampleShading
+case 5587: { // glMinSampleShading
GLclampf *value = (GLclampf *) bp; bp += 4;
weglMinSampleShading(*value);
}; break;
-case 5587: { // glBlendEquationi
+case 5588: { // glBlendEquationi
GLuint *buf = (GLuint *) bp; bp += 4;
GLenum *mode = (GLenum *) bp; bp += 4;
weglBlendEquationi(*buf,*mode);
}; break;
-case 5588: { // glBlendEquationSeparatei
+case 5589: { // glBlendEquationSeparatei
GLuint *buf = (GLuint *) bp; bp += 4;
GLenum *modeRGB = (GLenum *) bp; bp += 4;
GLenum *modeAlpha = (GLenum *) bp; bp += 4;
weglBlendEquationSeparatei(*buf,*modeRGB,*modeAlpha);
}; break;
-case 5589: { // glBlendFunci
+case 5590: { // glBlendFunci
GLuint *buf = (GLuint *) bp; bp += 4;
GLenum *src = (GLenum *) bp; bp += 4;
GLenum *dst = (GLenum *) bp; bp += 4;
weglBlendFunci(*buf,*src,*dst);
}; break;
-case 5590: { // glBlendFuncSeparatei
+case 5591: { // glBlendFuncSeparatei
GLuint *buf = (GLuint *) bp; bp += 4;
GLenum *srcRGB = (GLenum *) bp; bp += 4;
GLenum *dstRGB = (GLenum *) bp; bp += 4;
@@ -4465,103 +4473,103 @@ case 5590: { // glBlendFuncSeparatei
GLenum *dstAlpha = (GLenum *) bp; bp += 4;
weglBlendFuncSeparatei(*buf,*srcRGB,*dstRGB,*srcAlpha,*dstAlpha);
}; break;
-case 5591: { // glLoadTransposeMatrixfARB
+case 5592: { // glLoadTransposeMatrixfARB
GLfloat * m = (GLfloat *) bp; bp += 64;
weglLoadTransposeMatrixfARB(m);
}; break;
-case 5592: { // glLoadTransposeMatrixdARB
+case 5593: { // glLoadTransposeMatrixdARB
GLdouble * m = (GLdouble *) bp; bp += 128;
weglLoadTransposeMatrixdARB(m);
}; break;
-case 5593: { // glMultTransposeMatrixfARB
+case 5594: { // glMultTransposeMatrixfARB
GLfloat * m = (GLfloat *) bp; bp += 64;
weglMultTransposeMatrixfARB(m);
}; break;
-case 5594: { // glMultTransposeMatrixdARB
+case 5595: { // glMultTransposeMatrixdARB
GLdouble * m = (GLdouble *) bp; bp += 128;
weglMultTransposeMatrixdARB(m);
}; break;
-case 5595: { // glWeightbvARB
+case 5596: { // glWeightbvARB
int * weightsLen = (int *) bp; bp += 4;
- GLbyte * weights = (GLbyte *) bp; bp += (8-((*weightsLen*1+4)%8))%8;
+ GLbyte * weights = (GLbyte *) bp; bp += *weightsLen*1 + (8-((*weightsLen*1+4)%8))%8;
weglWeightbvARB(*weightsLen,weights);
}; break;
-case 5596: { // glWeightsvARB
+case 5597: { // glWeightsvARB
int * weightsLen = (int *) bp; bp += 4;
- GLshort * weights = (GLshort *) bp; bp += (8-((*weightsLen*2+4)%8))%8;
+ GLshort * weights = (GLshort *) bp; bp += *weightsLen*2 + (8-((*weightsLen*2+4)%8))%8;
weglWeightsvARB(*weightsLen,weights);
}; break;
-case 5597: { // glWeightivARB
+case 5598: { // glWeightivARB
int * weightsLen = (int *) bp; bp += 4;
- GLint * weights = (GLint *) bp; bp += (8-((*weightsLen*4+4)%8))%8;
+ GLint * weights = (GLint *) bp; bp += *weightsLen*4 + (8-((*weightsLen*4+4)%8))%8;
weglWeightivARB(*weightsLen,weights);
}; break;
-case 5598: { // glWeightfvARB
+case 5599: { // glWeightfvARB
int * weightsLen = (int *) bp; bp += 4;
- GLfloat * weights = (GLfloat *) bp; bp += (8-((*weightsLen*4+4)%8))%8;
+ GLfloat * weights = (GLfloat *) bp; bp += *weightsLen*4 + (8-((*weightsLen*4+4)%8))%8;
weglWeightfvARB(*weightsLen,weights);
}; break;
-case 5599: { // glWeightdvARB
+case 5600: { // glWeightdvARB
int * weightsLen = (int *) bp; bp += 8;
- GLdouble * weights = (GLdouble *) bp; bp += (8-((*weightsLen*8+0)%8))%8;
+ GLdouble * weights = (GLdouble *) bp; bp += *weightsLen*8 + (8-((*weightsLen*8+0)%8))%8;
weglWeightdvARB(*weightsLen,weights);
}; break;
-case 5600: { // glWeightubvARB
+case 5601: { // glWeightubvARB
int * weightsLen = (int *) bp; bp += 4;
- GLubyte * weights = (GLubyte *) bp; bp += (8-((*weightsLen*1+4)%8))%8;
+ GLubyte * weights = (GLubyte *) bp; bp += *weightsLen*1 + (8-((*weightsLen*1+4)%8))%8;
weglWeightubvARB(*weightsLen,weights);
}; break;
-case 5601: { // glWeightusvARB
+case 5602: { // glWeightusvARB
int * weightsLen = (int *) bp; bp += 4;
- GLushort * weights = (GLushort *) bp; bp += (8-((*weightsLen*2+4)%8))%8;
+ GLushort * weights = (GLushort *) bp; bp += *weightsLen*2 + (8-((*weightsLen*2+4)%8))%8;
weglWeightusvARB(*weightsLen,weights);
}; break;
-case 5602: { // glWeightuivARB
+case 5603: { // glWeightuivARB
int * weightsLen = (int *) bp; bp += 4;
- GLuint * weights = (GLuint *) bp; bp += (8-((*weightsLen*4+4)%8))%8;
+ GLuint * weights = (GLuint *) bp; bp += *weightsLen*4 + (8-((*weightsLen*4+4)%8))%8;
weglWeightuivARB(*weightsLen,weights);
}; break;
-case 5603: { // glVertexBlendARB
+case 5604: { // glVertexBlendARB
GLint *count = (GLint *) bp; bp += 4;
weglVertexBlendARB(*count);
}; break;
-case 5604: { // glCurrentPaletteMatrixARB
+case 5605: { // glCurrentPaletteMatrixARB
GLint *index = (GLint *) bp; bp += 4;
weglCurrentPaletteMatrixARB(*index);
}; break;
-case 5605: { // glMatrixIndexubvARB
+case 5606: { // glMatrixIndexubvARB
int * indicesLen = (int *) bp; bp += 4;
- GLubyte * indices = (GLubyte *) bp; bp += (8-((*indicesLen*1+4)%8))%8;
+ GLubyte * indices = (GLubyte *) bp; bp += *indicesLen*1 + (8-((*indicesLen*1+4)%8))%8;
weglMatrixIndexubvARB(*indicesLen,indices);
}; break;
-case 5606: { // glMatrixIndexusvARB
+case 5607: { // glMatrixIndexusvARB
int * indicesLen = (int *) bp; bp += 4;
- GLushort * indices = (GLushort *) bp; bp += (8-((*indicesLen*2+4)%8))%8;
+ GLushort * indices = (GLushort *) bp; bp += *indicesLen*2 + (8-((*indicesLen*2+4)%8))%8;
weglMatrixIndexusvARB(*indicesLen,indices);
}; break;
-case 5607: { // glMatrixIndexuivARB
+case 5608: { // glMatrixIndexuivARB
int * indicesLen = (int *) bp; bp += 4;
- GLuint * indices = (GLuint *) bp; bp += (8-((*indicesLen*4+4)%8))%8;
+ GLuint * indices = (GLuint *) bp; bp += *indicesLen*4 + (8-((*indicesLen*4+4)%8))%8;
weglMatrixIndexuivARB(*indicesLen,indices);
}; break;
-case 5608: { // glProgramStringARB
+case 5609: { // glProgramStringARB
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLvoid *string = (GLvoid *) bp;
int stringLen[1] = {(int)strlen((char *)string)}; bp += stringLen[0]+1+((8-((1+stringLen[0]+0)%8))%8);
weglProgramStringARB(*target,*format,*stringLen,string);
}; break;
-case 5609: { // glBindProgramARB
+case 5610: { // glBindProgramARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *program = (GLuint *) bp; bp += 4;
weglBindProgramARB(*target,*program);
}; break;
-case 5610: { // glDeleteProgramsARB
+case 5611: { // glDeleteProgramsARB
int * programsLen = (int *) bp; bp += 4;
- GLuint * programs = (GLuint *) bp; bp += (8-((*programsLen*4+4)%8))%8;
+ GLuint * programs = (GLuint *) bp; bp += *programsLen*4 + (8-((*programsLen*4+4)%8))%8;
weglDeleteProgramsARB(*programsLen,programs);
}; break;
-case 5611: { // glGenProgramsARB
+case 5612: { // glGenProgramsARB
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *programs;
programs = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -4577,7 +4585,7 @@ case 5611: { // glGenProgramsARB
driver_free(rt);
driver_free(programs);
}; break;
-case 5612: { // glProgramEnvParameter4dARB
+case 5613: { // glProgramEnvParameter4dARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
@@ -4586,13 +4594,13 @@ case 5612: { // glProgramEnvParameter4dARB
GLdouble *w = (GLdouble *) bp; bp += 8;
weglProgramEnvParameter4dARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5613: { // glProgramEnvParameter4dvARB
+case 5614: { // glProgramEnvParameter4dvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble * params = (GLdouble *) bp; bp += 32;
weglProgramEnvParameter4dvARB(*target,*index,params);
}; break;
-case 5614: { // glProgramEnvParameter4fARB
+case 5615: { // glProgramEnvParameter4fARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *x = (GLfloat *) bp; bp += 4;
@@ -4601,13 +4609,13 @@ case 5614: { // glProgramEnvParameter4fARB
GLfloat *w = (GLfloat *) bp; bp += 4;
weglProgramEnvParameter4fARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5615: { // glProgramEnvParameter4fvARB
+case 5616: { // glProgramEnvParameter4fvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat * params = (GLfloat *) bp; bp += 16;
weglProgramEnvParameter4fvARB(*target,*index,params);
}; break;
-case 5616: { // glProgramLocalParameter4dARB
+case 5617: { // glProgramLocalParameter4dARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
@@ -4616,13 +4624,13 @@ case 5616: { // glProgramLocalParameter4dARB
GLdouble *w = (GLdouble *) bp; bp += 8;
weglProgramLocalParameter4dARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5617: { // glProgramLocalParameter4dvARB
+case 5618: { // glProgramLocalParameter4dvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble * params = (GLdouble *) bp; bp += 32;
weglProgramLocalParameter4dvARB(*target,*index,params);
}; break;
-case 5618: { // glProgramLocalParameter4fARB
+case 5619: { // glProgramLocalParameter4fARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *x = (GLfloat *) bp; bp += 4;
@@ -4631,13 +4639,13 @@ case 5618: { // glProgramLocalParameter4fARB
GLfloat *w = (GLfloat *) bp; bp += 4;
weglProgramLocalParameter4fARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5619: { // glProgramLocalParameter4fvARB
+case 5620: { // glProgramLocalParameter4fvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat * params = (GLfloat *) bp; bp += 16;
weglProgramLocalParameter4fvARB(*target,*index,params);
}; break;
-case 5620: { // glGetProgramEnvParameterdvARB
+case 5621: { // glGetProgramEnvParameterdvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble params[4] = {0.0,0.0,0.0,0.0};
@@ -4653,7 +4661,7 @@ case 5620: { // glGetProgramEnvParameterdvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5621: { // glGetProgramEnvParameterfvARB
+case 5622: { // glGetProgramEnvParameterfvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat params[4] = {0.0,0.0,0.0,0.0};
@@ -4670,7 +4678,7 @@ case 5621: { // glGetProgramEnvParameterfvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5622: { // glGetProgramLocalParameterdvARB
+case 5623: { // glGetProgramLocalParameterdvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble params[4] = {0.0,0.0,0.0,0.0};
@@ -4686,7 +4694,7 @@ case 5622: { // glGetProgramLocalParameterdvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5623: { // glGetProgramLocalParameterfvARB
+case 5624: { // glGetProgramLocalParameterfvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat params[4] = {0.0,0.0,0.0,0.0};
@@ -4703,7 +4711,7 @@ case 5623: { // glGetProgramLocalParameterfvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5624: { // glGetProgramStringARB
+case 5625: { // glGetProgramStringARB
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLvoid *string = (GLvoid *) bins[0];
@@ -4714,7 +4722,7 @@ case 5624: { // glGetProgramStringARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5625: { // glGetBufferParameterivARB
+case 5626: { // glGetBufferParameterivARB
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -4742,11 +4750,11 @@ case 5625: { // glGetBufferParameterivARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5626: { // glDeleteObjectARB
+case 5627: { // glDeleteObjectARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglDeleteObjectARB(obj);
}; break;
-case 5627: { // glGetHandleARB
+case 5628: { // glGetHandleARB
GLenum *pname = (GLenum *) bp; bp += 4;
GLhandleARB result = weglGetHandleARB(*pname);
int AP = 0; ErlDrvTermData rt[6];
@@ -4755,12 +4763,12 @@ case 5627: { // glGetHandleARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5628: { // glDetachObjectARB
+case 5629: { // glDetachObjectARB
GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLhandleARB attachedObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglDetachObjectARB(containerObj,attachedObj);
}; break;
-case 5629: { // glCreateShaderObjectARB
+case 5630: { // glCreateShaderObjectARB
GLenum *shaderType = (GLenum *) bp; bp += 4;
GLhandleARB result = weglCreateShaderObjectARB(*shaderType);
int AP = 0; ErlDrvTermData rt[6];
@@ -4769,7 +4777,7 @@ case 5629: { // glCreateShaderObjectARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5630: { // glShaderSourceARB
+case 5631: { // glShaderSourceARB
GLhandleARB shaderObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
int * stringLen = (int *) bp; bp += 4;
int * stringTotSize = (int *) bp; bp += 4;
@@ -4781,11 +4789,11 @@ case 5630: { // glShaderSourceARB
weglShaderSourceARB(shaderObj,*stringLen,(const GLchar **) string,NULL);
driver_free(string);
}; break;
-case 5631: { // glCompileShaderARB
+case 5632: { // glCompileShaderARB
GLhandleARB shaderObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglCompileShaderARB(shaderObj);
}; break;
-case 5632: { // glCreateProgramObjectARB
+case 5633: { // glCreateProgramObjectARB
GLhandleARB result = weglCreateProgramObjectARB();
int AP = 0; ErlDrvTermData rt[6];
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
@@ -4793,24 +4801,24 @@ case 5632: { // glCreateProgramObjectARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5633: { // glAttachObjectARB
+case 5634: { // glAttachObjectARB
GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglAttachObjectARB(containerObj,obj);
}; break;
-case 5634: { // glLinkProgramARB
+case 5635: { // glLinkProgramARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglLinkProgramARB(programObj);
}; break;
-case 5635: { // glUseProgramObjectARB
+case 5636: { // glUseProgramObjectARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglUseProgramObjectARB(programObj);
}; break;
-case 5636: { // glValidateProgramARB
+case 5637: { // glValidateProgramARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglValidateProgramARB(programObj);
}; break;
-case 5637: { // glGetObjectParameterfvARB
+case 5638: { // glGetObjectParameterfvARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLenum *pname = (GLenum *) bp; bp += 4;
GLfloat params[1] = {0.0};
@@ -4822,7 +4830,7 @@ case 5637: { // glGetObjectParameterfvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5638: { // glGetObjectParameterivARB
+case 5639: { // glGetObjectParameterivARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -4833,7 +4841,7 @@ case 5638: { // glGetObjectParameterivARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5639: { // glGetInfoLogARB
+case 5640: { // glGetInfoLogARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -4847,7 +4855,7 @@ case 5639: { // glGetInfoLogARB
driver_send_term(port,caller,rt,AP);
driver_free(infoLog);
}; break;
-case 5640: { // glGetAttachedObjectsARB
+case 5641: { // glGetAttachedObjectsARB
GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLsizei *maxCount = (GLsizei *) bp; bp += 4;
GLsizei count[1] = {0};
@@ -4865,7 +4873,7 @@ case 5640: { // glGetAttachedObjectsARB
driver_free(rt);
driver_free(obj);
}; break;
-case 5641: { // glGetUniformLocationARB
+case 5642: { // glGetUniformLocationARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
@@ -4876,7 +4884,7 @@ case 5641: { // glGetUniformLocationARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5642: { // glGetActiveUniformARB
+case 5643: { // glGetActiveUniformARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
@@ -4896,7 +4904,7 @@ case 5642: { // glGetActiveUniformARB
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5643: { // glGetUniformfvARB
+case 5644: { // glGetUniformfvARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLint *location = (GLint *) bp; bp += 4;
GLfloat params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
@@ -4925,7 +4933,7 @@ case 5643: { // glGetUniformfvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5644: { // glGetUniformivARB
+case 5645: { // glGetUniformivARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLint *location = (GLint *) bp; bp += 4;
GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -4953,7 +4961,7 @@ case 5644: { // glGetUniformivARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5645: { // glGetShaderSourceARB
+case 5646: { // glGetShaderSourceARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -4967,14 +4975,14 @@ case 5645: { // glGetShaderSourceARB
driver_send_term(port,caller,rt,AP);
driver_free(source);
}; break;
-case 5646: { // glBindAttribLocationARB
+case 5647: { // glBindAttribLocationARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLuint *index = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
weglBindAttribLocationARB(programObj,*index,name);
}; break;
-case 5647: { // glGetActiveAttribARB
+case 5648: { // glGetActiveAttribARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
@@ -4994,7 +5002,7 @@ case 5647: { // glGetActiveAttribARB
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5648: { // glGetAttribLocationARB
+case 5649: { // glGetAttribLocationARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
@@ -5005,7 +5013,7 @@ case 5648: { // glGetAttribLocationARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5649: { // glIsRenderbuffer
+case 5650: { // glIsRenderbuffer
GLuint *renderbuffer = (GLuint *) bp; bp += 4;
GLboolean result = weglIsRenderbuffer(*renderbuffer);
int AP = 0; ErlDrvTermData rt[6];
@@ -5014,17 +5022,17 @@ case 5649: { // glIsRenderbuffer
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5650: { // glBindRenderbuffer
+case 5651: { // glBindRenderbuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *renderbuffer = (GLuint *) bp; bp += 4;
weglBindRenderbuffer(*target,*renderbuffer);
}; break;
-case 5651: { // glDeleteRenderbuffers
+case 5652: { // glDeleteRenderbuffers
int * renderbuffersLen = (int *) bp; bp += 4;
- GLuint * renderbuffers = (GLuint *) bp; bp += (8-((*renderbuffersLen*4+4)%8))%8;
+ GLuint * renderbuffers = (GLuint *) bp; bp += *renderbuffersLen*4 + (8-((*renderbuffersLen*4+4)%8))%8;
weglDeleteRenderbuffers(*renderbuffersLen,renderbuffers);
}; break;
-case 5652: { // glGenRenderbuffers
+case 5653: { // glGenRenderbuffers
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *renderbuffers;
renderbuffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -5040,14 +5048,14 @@ case 5652: { // glGenRenderbuffers
driver_free(rt);
driver_free(renderbuffers);
}; break;
-case 5653: { // glRenderbufferStorage
+case 5654: { // glRenderbufferStorage
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
GLsizei *width = (GLsizei *) bp; bp += 4;
GLsizei *height = (GLsizei *) bp; bp += 4;
weglRenderbufferStorage(*target,*internalformat,*width,*height);
}; break;
-case 5654: { // glGetRenderbufferParameteriv
+case 5655: { // glGetRenderbufferParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -5058,7 +5066,7 @@ case 5654: { // glGetRenderbufferParameteriv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5655: { // glIsFramebuffer
+case 5656: { // glIsFramebuffer
GLuint *framebuffer = (GLuint *) bp; bp += 4;
GLboolean result = weglIsFramebuffer(*framebuffer);
int AP = 0; ErlDrvTermData rt[6];
@@ -5067,17 +5075,17 @@ case 5655: { // glIsFramebuffer
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5656: { // glBindFramebuffer
+case 5657: { // glBindFramebuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *framebuffer = (GLuint *) bp; bp += 4;
weglBindFramebuffer(*target,*framebuffer);
}; break;
-case 5657: { // glDeleteFramebuffers
+case 5658: { // glDeleteFramebuffers
int * framebuffersLen = (int *) bp; bp += 4;
- GLuint * framebuffers = (GLuint *) bp; bp += (8-((*framebuffersLen*4+4)%8))%8;
+ GLuint * framebuffers = (GLuint *) bp; bp += *framebuffersLen*4 + (8-((*framebuffersLen*4+4)%8))%8;
weglDeleteFramebuffers(*framebuffersLen,framebuffers);
}; break;
-case 5658: { // glGenFramebuffers
+case 5659: { // glGenFramebuffers
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *framebuffers;
framebuffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -5093,7 +5101,7 @@ case 5658: { // glGenFramebuffers
driver_free(rt);
driver_free(framebuffers);
}; break;
-case 5659: { // glCheckFramebufferStatus
+case 5660: { // glCheckFramebufferStatus
GLenum *target = (GLenum *) bp; bp += 4;
GLenum result = weglCheckFramebufferStatus(*target);
int AP = 0; ErlDrvTermData rt[6];
@@ -5102,7 +5110,7 @@ case 5659: { // glCheckFramebufferStatus
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5660: { // glFramebufferTexture1D
+case 5661: { // glFramebufferTexture1D
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *textarget = (GLenum *) bp; bp += 4;
@@ -5110,7 +5118,7 @@ case 5660: { // glFramebufferTexture1D
GLint *level = (GLint *) bp; bp += 4;
weglFramebufferTexture1D(*target,*attachment,*textarget,*texture,*level);
}; break;
-case 5661: { // glFramebufferTexture2D
+case 5662: { // glFramebufferTexture2D
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *textarget = (GLenum *) bp; bp += 4;
@@ -5118,7 +5126,7 @@ case 5661: { // glFramebufferTexture2D
GLint *level = (GLint *) bp; bp += 4;
weglFramebufferTexture2D(*target,*attachment,*textarget,*texture,*level);
}; break;
-case 5662: { // glFramebufferTexture3D
+case 5663: { // glFramebufferTexture3D
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *textarget = (GLenum *) bp; bp += 4;
@@ -5127,14 +5135,14 @@ case 5662: { // glFramebufferTexture3D
GLint *zoffset = (GLint *) bp; bp += 4;
weglFramebufferTexture3D(*target,*attachment,*textarget,*texture,*level,*zoffset);
}; break;
-case 5663: { // glFramebufferRenderbuffer
+case 5664: { // glFramebufferRenderbuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *renderbuffertarget = (GLenum *) bp; bp += 4;
GLuint *renderbuffer = (GLuint *) bp; bp += 4;
weglFramebufferRenderbuffer(*target,*attachment,*renderbuffertarget,*renderbuffer);
}; break;
-case 5664: { // glGetFramebufferAttachmentParameteriv
+case 5665: { // glGetFramebufferAttachmentParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -5146,11 +5154,11 @@ case 5664: { // glGetFramebufferAttachmentParameteriv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5665: { // glGenerateMipmap
+case 5666: { // glGenerateMipmap
GLenum *target = (GLenum *) bp; bp += 4;
weglGenerateMipmap(*target);
}; break;
-case 5666: { // glBlitFramebuffer
+case 5667: { // glBlitFramebuffer
GLint *srcX0 = (GLint *) bp; bp += 4;
GLint *srcY0 = (GLint *) bp; bp += 4;
GLint *srcX1 = (GLint *) bp; bp += 4;
@@ -5163,7 +5171,7 @@ case 5666: { // glBlitFramebuffer
GLenum *filter = (GLenum *) bp; bp += 4;
weglBlitFramebuffer(*srcX0,*srcY0,*srcX1,*srcY1,*dstX0,*dstY0,*dstX1,*dstY1,*mask,*filter);
}; break;
-case 5667: { // glRenderbufferStorageMultisample
+case 5668: { // glRenderbufferStorageMultisample
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *samples = (GLsizei *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
@@ -5171,7 +5179,7 @@ case 5667: { // glRenderbufferStorageMultisample
GLsizei *height = (GLsizei *) bp; bp += 4;
weglRenderbufferStorageMultisample(*target,*samples,*internalformat,*width,*height);
}; break;
-case 5668: { // glFramebufferTextureLayer
+case 5669: { // glFramebufferTextureLayer
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLuint *texture = (GLuint *) bp; bp += 4;
@@ -5179,7 +5187,7 @@ case 5668: { // glFramebufferTextureLayer
GLint *layer = (GLint *) bp; bp += 4;
weglFramebufferTextureLayer(*target,*attachment,*texture,*level,*layer);
}; break;
-case 5669: { // glFramebufferTextureFaceARB
+case 5670: { // glFramebufferTextureFaceARB
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLuint *texture = (GLuint *) bp; bp += 4;
@@ -5187,23 +5195,23 @@ case 5669: { // glFramebufferTextureFaceARB
GLenum *face = (GLenum *) bp; bp += 4;
weglFramebufferTextureFaceARB(*target,*attachment,*texture,*level,*face);
}; break;
-case 5670: { // glFlushMappedBufferRange
+case 5671: { // glFlushMappedBufferRange
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
GLsizeiptr length = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
weglFlushMappedBufferRange(*target,offset,length);
}; break;
-case 5671: { // glBindVertexArray
+case 5672: { // glBindVertexArray
GLuint *array = (GLuint *) bp; bp += 4;
weglBindVertexArray(*array);
}; break;
-case 5672: { // glDeleteVertexArrays
+case 5673: { // glDeleteVertexArrays
int * arraysLen = (int *) bp; bp += 4;
- GLuint * arrays = (GLuint *) bp; bp += (8-((*arraysLen*4+4)%8))%8;
+ GLuint * arrays = (GLuint *) bp; bp += *arraysLen*4 + (8-((*arraysLen*4+4)%8))%8;
weglDeleteVertexArrays(*arraysLen,arrays);
}; break;
-case 5673: { // glGenVertexArrays
+case 5674: { // glGenVertexArrays
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *arrays;
arrays = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -5219,7 +5227,7 @@ case 5673: { // glGenVertexArrays
driver_free(rt);
driver_free(arrays);
}; break;
-case 5674: { // glIsVertexArray
+case 5675: { // glIsVertexArray
GLuint *array = (GLuint *) bp; bp += 4;
GLboolean result = weglIsVertexArray(*array);
int AP = 0; ErlDrvTermData rt[6];
@@ -5228,7 +5236,7 @@ case 5674: { // glIsVertexArray
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5675: { // glGetUniformIndices
+case 5676: { // glGetUniformIndices
GLuint *program = (GLuint *) bp; bp += 4;
int * uniformNamesLen = (int *) bp; bp += 4;
int * uniformNamesTotSize = (int *) bp; bp += 4;
@@ -5252,10 +5260,10 @@ case 5675: { // glGetUniformIndices
driver_free(uniformIndices);
driver_free(uniformNames);
}; break;
-case 5676: { // glGetActiveUniformsiv
+case 5677: { // glGetActiveUniformsiv
GLuint *program = (GLuint *) bp; bp += 4;
int * uniformIndicesLen = (int *) bp; bp += 4;
- GLuint * uniformIndices = (GLuint *) bp; bp += (8-((*uniformIndicesLen*4+0)%8))%8;
+ GLuint * uniformIndices = (GLuint *) bp; bp += *uniformIndicesLen*4 + (8-((*uniformIndicesLen*4+0)%8))%8;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint *params;
params = (GLint *) driver_alloc(sizeof(GLint) * *uniformIndicesLen);
@@ -5271,7 +5279,7 @@ case 5676: { // glGetActiveUniformsiv
driver_free(rt);
driver_free(params);
}; break;
-case 5677: { // glGetActiveUniformName
+case 5678: { // glGetActiveUniformName
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *uniformIndex = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -5286,7 +5294,7 @@ case 5677: { // glGetActiveUniformName
driver_send_term(port,caller,rt,AP);
driver_free(uniformName);
}; break;
-case 5678: { // glGetUniformBlockIndex
+case 5679: { // glGetUniformBlockIndex
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *uniformBlockName = (GLchar *) bp;
int uniformBlockNameLen[1] = {(int)strlen((char *)uniformBlockName)}; bp += uniformBlockNameLen[0]+1+((8-((1+uniformBlockNameLen[0]+4)%8))%8);
@@ -5297,7 +5305,7 @@ case 5678: { // glGetUniformBlockIndex
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5679: { // glGetActiveUniformBlockiv
+case 5680: { // glGetActiveUniformBlockiv
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -5309,7 +5317,7 @@ case 5679: { // glGetActiveUniformBlockiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5680: { // glGetActiveUniformBlockName
+case 5681: { // glGetActiveUniformBlockName
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -5324,13 +5332,13 @@ case 5680: { // glGetActiveUniformBlockName
driver_send_term(port,caller,rt,AP);
driver_free(uniformBlockName);
}; break;
-case 5681: { // glUniformBlockBinding
+case 5682: { // glUniformBlockBinding
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4;
GLuint *uniformBlockBinding = (GLuint *) bp; bp += 4;
weglUniformBlockBinding(*program,*uniformBlockIndex,*uniformBlockBinding);
}; break;
-case 5682: { // glCopyBufferSubData
+case 5683: { // glCopyBufferSubData
GLenum *readTarget = (GLenum *) bp; bp += 4;
GLenum *writeTarget = (GLenum *) bp; bp += 4;
GLintptr readOffset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
@@ -5338,7 +5346,7 @@ case 5682: { // glCopyBufferSubData
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
weglCopyBufferSubData(*readTarget,*writeTarget,readOffset,writeOffset,size);
}; break;
-case 5683: { // glDrawElementsBaseVertex
+case 5684: { // glDrawElementsBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -5346,7 +5354,7 @@ case 5683: { // glDrawElementsBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawElementsBaseVertex(*mode,*count,*type,indices,*basevertex);
}; break;
-case 5684: { // glDrawElementsBaseVertex
+case 5685: { // glDrawElementsBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -5354,7 +5362,7 @@ case 5684: { // glDrawElementsBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawElementsBaseVertex(*mode,*count,*type,indices,*basevertex);
}; break;
-case 5685: { // glDrawRangeElementsBaseVertex
+case 5686: { // glDrawRangeElementsBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLuint *start = (GLuint *) bp; bp += 4;
GLuint *end = (GLuint *) bp; bp += 4;
@@ -5364,7 +5372,7 @@ case 5685: { // glDrawRangeElementsBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawRangeElementsBaseVertex(*mode,*start,*end,*count,*type,indices,*basevertex);
}; break;
-case 5686: { // glDrawRangeElementsBaseVertex
+case 5687: { // glDrawRangeElementsBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLuint *start = (GLuint *) bp; bp += 4;
GLuint *end = (GLuint *) bp; bp += 4;
@@ -5374,7 +5382,7 @@ case 5686: { // glDrawRangeElementsBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawRangeElementsBaseVertex(*mode,*start,*end,*count,*type,indices,*basevertex);
}; break;
-case 5687: { // glDrawElementsInstancedBaseVertex
+case 5688: { // glDrawElementsInstancedBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -5383,7 +5391,7 @@ case 5687: { // glDrawElementsInstancedBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawElementsInstancedBaseVertex(*mode,*count,*type,indices,*primcount,*basevertex);
}; break;
-case 5688: { // glDrawElementsInstancedBaseVertex
+case 5689: { // glDrawElementsInstancedBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -5392,11 +5400,11 @@ case 5688: { // glDrawElementsInstancedBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawElementsInstancedBaseVertex(*mode,*count,*type,indices,*primcount,*basevertex);
}; break;
-case 5689: { // glProvokingVertex
+case 5690: { // glProvokingVertex
GLenum *mode = (GLenum *) bp; bp += 4;
weglProvokingVertex(*mode);
}; break;
-case 5690: { // glFenceSync
+case 5691: { // glFenceSync
GLenum *condition = (GLenum *) bp; bp += 4;
GLbitfield *flags = (GLbitfield *) bp; bp += 4;
GLsync result = weglFenceSync(*condition,*flags);
@@ -5406,7 +5414,7 @@ case 5690: { // glFenceSync
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5691: { // glIsSync
+case 5692: { // glIsSync
GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
GLboolean result = weglIsSync(sync);
int AP = 0; ErlDrvTermData rt[6];
@@ -5415,11 +5423,11 @@ case 5691: { // glIsSync
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5692: { // glDeleteSync
+case 5693: { // glDeleteSync
GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
weglDeleteSync(sync);
}; break;
-case 5693: { // glClientWaitSync
+case 5694: { // glClientWaitSync
GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
GLbitfield *flags = (GLbitfield *) bp; bp += 4;
bp += 4;
@@ -5431,14 +5439,14 @@ case 5693: { // glClientWaitSync
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5694: { // glWaitSync
+case 5695: { // glWaitSync
GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
GLbitfield *flags = (GLbitfield *) bp; bp += 4;
bp += 4;
GLuint64 timeout = (GLuint64) * (GLuint64EXT *) bp; bp += 8;
weglWaitSync(sync,*flags,timeout);
}; break;
-case 5695: { // glGetInteger64v
+case 5696: { // glGetInteger64v
GLenum *pname = (GLenum *) bp; bp += 4;
GLint64 params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
weglGetInteger64v(*pname,params);
@@ -5465,7 +5473,7 @@ case 5695: { // glGetInteger64v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5696: { // glGetSynciv
+case 5697: { // glGetSynciv
GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
GLenum *pname = (GLenum *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -5484,7 +5492,7 @@ case 5696: { // glGetSynciv
driver_free(rt);
driver_free(values);
}; break;
-case 5697: { // glTexImage2DMultisample
+case 5698: { // glTexImage2DMultisample
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *samples = (GLsizei *) bp; bp += 4;
GLint *internalformat = (GLint *) bp; bp += 4;
@@ -5493,7 +5501,7 @@ case 5697: { // glTexImage2DMultisample
GLboolean *fixedsamplelocations = (GLboolean *) bp; bp += 1;
weglTexImage2DMultisample(*target,*samples,*internalformat,*width,*height,*fixedsamplelocations);
}; break;
-case 5698: { // glTexImage3DMultisample
+case 5699: { // glTexImage3DMultisample
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *samples = (GLsizei *) bp; bp += 4;
GLint *internalformat = (GLint *) bp; bp += 4;
@@ -5503,7 +5511,7 @@ case 5698: { // glTexImage3DMultisample
GLboolean *fixedsamplelocations = (GLboolean *) bp; bp += 1;
weglTexImage3DMultisample(*target,*samples,*internalformat,*width,*height,*depth,*fixedsamplelocations);
}; break;
-case 5699: { // glGetMultisamplefv
+case 5700: { // glGetMultisamplefv
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat val[2] = {0.0,0.0};
@@ -5518,12 +5526,12 @@ case 5699: { // glGetMultisamplefv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5700: { // glSampleMaski
+case 5701: { // glSampleMaski
GLuint *index = (GLuint *) bp; bp += 4;
GLbitfield *mask = (GLbitfield *) bp; bp += 4;
weglSampleMaski(*index,*mask);
}; break;
-case 5701: { // glNamedStringARB
+case 5702: { // glNamedStringARB
GLenum *type = (GLenum *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
@@ -5531,12 +5539,12 @@ case 5701: { // glNamedStringARB
int stringLen[1] = {(int)strlen((char *)string)}; bp += stringLen[0]+1+((8-((1+stringLen[0]+0)%8))%8);
weglNamedStringARB(*type,*nameLen,name,*stringLen,string);
}; break;
-case 5702: { // glDeleteNamedStringARB
+case 5703: { // glDeleteNamedStringARB
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
weglDeleteNamedStringARB(*nameLen,name);
}; break;
-case 5703: { // glCompileShaderIncludeARB
+case 5704: { // glCompileShaderIncludeARB
GLuint *shader = (GLuint *) bp; bp += 4;
int * pathLen = (int *) bp; bp += 4;
int * pathTotSize = (int *) bp; bp += 4;
@@ -5548,7 +5556,7 @@ case 5703: { // glCompileShaderIncludeARB
weglCompileShaderIncludeARB(*shader,*pathLen,(const GLchar **) path,NULL);
driver_free(path);
}; break;
-case 5704: { // glIsNamedStringARB
+case 5705: { // glIsNamedStringARB
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
GLboolean result = weglIsNamedStringARB(*nameLen,name);
@@ -5558,7 +5566,7 @@ case 5704: { // glIsNamedStringARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5705: { // glGetNamedStringARB
+case 5706: { // glGetNamedStringARB
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -5573,7 +5581,7 @@ case 5705: { // glGetNamedStringARB
driver_send_term(port,caller,rt,AP);
driver_free(string);
}; break;
-case 5706: { // glGetNamedStringivARB
+case 5707: { // glGetNamedStringivARB
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -5585,7 +5593,7 @@ case 5706: { // glGetNamedStringivARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5707: { // glBindFragDataLocationIndexed
+case 5708: { // glBindFragDataLocationIndexed
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *colorNumber = (GLuint *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
@@ -5593,7 +5601,7 @@ case 5707: { // glBindFragDataLocationIndexed
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
weglBindFragDataLocationIndexed(*program,*colorNumber,*index,name);
}; break;
-case 5708: { // glGetFragDataIndex
+case 5709: { // glGetFragDataIndex
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
@@ -5604,7 +5612,7 @@ case 5708: { // glGetFragDataIndex
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5709: { // glGenSamplers
+case 5710: { // glGenSamplers
GLsizei *count = (GLsizei *) bp; bp += 4;
GLuint *samplers;
samplers = (GLuint *) driver_alloc(sizeof(GLuint) * *count);
@@ -5620,12 +5628,12 @@ case 5709: { // glGenSamplers
driver_free(rt);
driver_free(samplers);
}; break;
-case 5710: { // glDeleteSamplers
+case 5711: { // glDeleteSamplers
int * samplersLen = (int *) bp; bp += 4;
- GLuint * samplers = (GLuint *) bp; bp += (8-((*samplersLen*4+4)%8))%8;
+ GLuint * samplers = (GLuint *) bp; bp += *samplersLen*4 + (8-((*samplersLen*4+4)%8))%8;
weglDeleteSamplers(*samplersLen,samplers);
}; break;
-case 5711: { // glIsSampler
+case 5712: { // glIsSampler
GLuint *sampler = (GLuint *) bp; bp += 4;
GLboolean result = weglIsSampler(*sampler);
int AP = 0; ErlDrvTermData rt[6];
@@ -5634,52 +5642,52 @@ case 5711: { // glIsSampler
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5712: { // glBindSampler
+case 5713: { // glBindSampler
GLuint *unit = (GLuint *) bp; bp += 4;
GLuint *sampler = (GLuint *) bp; bp += 4;
weglBindSampler(*unit,*sampler);
}; break;
-case 5713: { // glSamplerParameteri
+case 5714: { // glSamplerParameteri
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint *param = (GLint *) bp; bp += 4;
weglSamplerParameteri(*sampler,*pname,*param);
}; break;
-case 5714: { // glSamplerParameteriv
+case 5715: { // glSamplerParameteriv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
int * paramLen = (int *) bp; bp += 4;
- GLint * param = (GLint *) bp; bp += (8-((*paramLen*4+4)%8))%8;
+ GLint * param = (GLint *) bp; bp += *paramLen*4 + (8-((*paramLen*4+4)%8))%8;
weglSamplerParameteriv(*sampler,*pname,param);
}; break;
-case 5715: { // glSamplerParameterf
+case 5716: { // glSamplerParameterf
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLfloat *param = (GLfloat *) bp; bp += 4;
weglSamplerParameterf(*sampler,*pname,*param);
}; break;
-case 5716: { // glSamplerParameterfv
+case 5717: { // glSamplerParameterfv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
int * paramLen = (int *) bp; bp += 4;
- GLfloat * param = (GLfloat *) bp; bp += (8-((*paramLen*4+4)%8))%8;
+ GLfloat * param = (GLfloat *) bp; bp += *paramLen*4 + (8-((*paramLen*4+4)%8))%8;
weglSamplerParameterfv(*sampler,*pname,param);
}; break;
-case 5717: { // glSamplerParameterIiv
+case 5718: { // glSamplerParameterIiv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
int * paramLen = (int *) bp; bp += 4;
- GLint * param = (GLint *) bp; bp += (8-((*paramLen*4+4)%8))%8;
+ GLint * param = (GLint *) bp; bp += *paramLen*4 + (8-((*paramLen*4+4)%8))%8;
weglSamplerParameterIiv(*sampler,*pname,param);
}; break;
-case 5718: { // glSamplerParameterIuiv
+case 5719: { // glSamplerParameterIuiv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
int * paramLen = (int *) bp; bp += 4;
- GLuint * param = (GLuint *) bp; bp += (8-((*paramLen*4+4)%8))%8;
+ GLuint * param = (GLuint *) bp; bp += *paramLen*4 + (8-((*paramLen*4+4)%8))%8;
weglSamplerParameterIuiv(*sampler,*pname,param);
}; break;
-case 5719: { // glGetSamplerParameteriv
+case 5720: { // glGetSamplerParameteriv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[4] = {0,0,0,0};
@@ -5695,7 +5703,7 @@ case 5719: { // glGetSamplerParameteriv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5720: { // glGetSamplerParameterIiv
+case 5721: { // glGetSamplerParameterIiv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[4] = {0,0,0,0};
@@ -5711,7 +5719,7 @@ case 5720: { // glGetSamplerParameterIiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5721: { // glGetSamplerParameterfv
+case 5722: { // glGetSamplerParameterfv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLfloat params[4] = {0.0,0.0,0.0,0.0};
@@ -5728,7 +5736,7 @@ case 5721: { // glGetSamplerParameterfv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5722: { // glGetSamplerParameterIuiv
+case 5723: { // glGetSamplerParameterIuiv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint params[4] = {0,0,0,0};
@@ -5744,12 +5752,12 @@ case 5722: { // glGetSamplerParameterIuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5723: { // glQueryCounter
+case 5724: { // glQueryCounter
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *target = (GLenum *) bp; bp += 4;
weglQueryCounter(*id,*target);
}; break;
-case 5724: { // glGetQueryObjecti64v
+case 5725: { // glGetQueryObjecti64v
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint64 params[1] = {0};
@@ -5760,7 +5768,7 @@ case 5724: { // glGetQueryObjecti64v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5725: { // glGetQueryObjectui64v
+case 5726: { // glGetQueryObjectui64v
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint64 params[1] = {0};
@@ -5771,42 +5779,42 @@ case 5725: { // glGetQueryObjectui64v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5726: { // glDrawArraysIndirect
+case 5727: { // glDrawArraysIndirect
GLenum *mode = (GLenum *) bp; bp += 4;
GLvoid *indirect = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglDrawArraysIndirect(*mode,indirect);
}; break;
-case 5727: { // glDrawArraysIndirect
+case 5728: { // glDrawArraysIndirect
GLenum *mode = (GLenum *) bp; bp += 4;
GLvoid *indirect = (GLvoid *) bins[0];
weglDrawArraysIndirect(*mode,indirect);
}; break;
-case 5728: { // glDrawElementsIndirect
+case 5729: { // glDrawElementsIndirect
GLenum *mode = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLvoid *indirect = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglDrawElementsIndirect(*mode,*type,indirect);
}; break;
-case 5729: { // glDrawElementsIndirect
+case 5730: { // glDrawElementsIndirect
GLenum *mode = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLvoid *indirect = (GLvoid *) bins[0];
weglDrawElementsIndirect(*mode,*type,indirect);
}; break;
-case 5730: { // glUniform1d
+case 5731: { // glUniform1d
GLint *location = (GLint *) bp; bp += 4;
bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
weglUniform1d(*location,*x);
}; break;
-case 5731: { // glUniform2d
+case 5732: { // glUniform2d
GLint *location = (GLint *) bp; bp += 4;
bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
GLdouble *y = (GLdouble *) bp; bp += 8;
weglUniform2d(*location,*x,*y);
}; break;
-case 5732: { // glUniform3d
+case 5733: { // glUniform3d
GLint *location = (GLint *) bp; bp += 4;
bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
@@ -5814,7 +5822,7 @@ case 5732: { // glUniform3d
GLdouble *z = (GLdouble *) bp; bp += 8;
weglUniform3d(*location,*x,*y,*z);
}; break;
-case 5733: { // glUniform4d
+case 5734: { // glUniform4d
GLint *location = (GLint *) bp; bp += 4;
bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
@@ -5823,35 +5831,35 @@ case 5733: { // glUniform4d
GLdouble *w = (GLdouble *) bp; bp += 8;
weglUniform4d(*location,*x,*y,*z,*w);
}; break;
-case 5734: { // glUniform1dv
+case 5735: { // glUniform1dv
GLint *location = (GLint *) bp; bp += 4;
bp += 4;
int * valueLen = (int *) bp; bp += 8;
- GLdouble * value = (GLdouble *) bp; bp += (8-((*valueLen*8+0)%8))%8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*8 + (8-((*valueLen*8+0)%8))%8;
weglUniform1dv(*location,*valueLen,value);
}; break;
-case 5735: { // glUniform2dv
+case 5736: { // glUniform2dv
GLint *location = (GLint *) bp; bp += 4;
bp += 4;
int *valueLen = (int *) bp; bp += 8;
GLdouble * value = (GLdouble *) bp; bp += *valueLen*16;
weglUniform2dv(*location,*valueLen,value);
}; break;
-case 5736: { // glUniform3dv
+case 5737: { // glUniform3dv
GLint *location = (GLint *) bp; bp += 4;
bp += 4;
int *valueLen = (int *) bp; bp += 8;
GLdouble * value = (GLdouble *) bp; bp += *valueLen*24;
weglUniform3dv(*location,*valueLen,value);
}; break;
-case 5737: { // glUniform4dv
+case 5738: { // glUniform4dv
GLint *location = (GLint *) bp; bp += 4;
bp += 4;
int *valueLen = (int *) bp; bp += 8;
GLdouble * value = (GLdouble *) bp; bp += *valueLen*32;
weglUniform4dv(*location,*valueLen,value);
}; break;
-case 5738: { // glUniformMatrix2dv
+case 5739: { // glUniformMatrix2dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5859,7 +5867,7 @@ case 5738: { // glUniformMatrix2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*32;
weglUniformMatrix2dv(*location,*valueLen,*transpose,value);
}; break;
-case 5739: { // glUniformMatrix3dv
+case 5740: { // glUniformMatrix3dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5867,7 +5875,7 @@ case 5739: { // glUniformMatrix3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*72;
weglUniformMatrix3dv(*location,*valueLen,*transpose,value);
}; break;
-case 5740: { // glUniformMatrix4dv
+case 5741: { // glUniformMatrix4dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5875,7 +5883,7 @@ case 5740: { // glUniformMatrix4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*128;
weglUniformMatrix4dv(*location,*valueLen,*transpose,value);
}; break;
-case 5741: { // glUniformMatrix2x3dv
+case 5742: { // glUniformMatrix2x3dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5883,7 +5891,7 @@ case 5741: { // glUniformMatrix2x3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
weglUniformMatrix2x3dv(*location,*valueLen,*transpose,value);
}; break;
-case 5742: { // glUniformMatrix2x4dv
+case 5743: { // glUniformMatrix2x4dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5891,7 +5899,7 @@ case 5742: { // glUniformMatrix2x4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
weglUniformMatrix2x4dv(*location,*valueLen,*transpose,value);
}; break;
-case 5743: { // glUniformMatrix3x2dv
+case 5744: { // glUniformMatrix3x2dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5899,7 +5907,7 @@ case 5743: { // glUniformMatrix3x2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
weglUniformMatrix3x2dv(*location,*valueLen,*transpose,value);
}; break;
-case 5744: { // glUniformMatrix3x4dv
+case 5745: { // glUniformMatrix3x4dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5907,7 +5915,7 @@ case 5744: { // glUniformMatrix3x4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
weglUniformMatrix3x4dv(*location,*valueLen,*transpose,value);
}; break;
-case 5745: { // glUniformMatrix4x2dv
+case 5746: { // glUniformMatrix4x2dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5915,7 +5923,7 @@ case 5745: { // glUniformMatrix4x2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
weglUniformMatrix4x2dv(*location,*valueLen,*transpose,value);
}; break;
-case 5746: { // glUniformMatrix4x3dv
+case 5747: { // glUniformMatrix4x3dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5923,7 +5931,7 @@ case 5746: { // glUniformMatrix4x3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
weglUniformMatrix4x3dv(*location,*valueLen,*transpose,value);
}; break;
-case 5747: { // glGetUniformdv
+case 5748: { // glGetUniformdv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLdouble params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
@@ -5951,7 +5959,7 @@ case 5747: { // glGetUniformdv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5748: { // glGetSubroutineUniformLocation
+case 5749: { // glGetSubroutineUniformLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
@@ -5963,7 +5971,7 @@ case 5748: { // glGetSubroutineUniformLocation
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5749: { // glGetSubroutineIndex
+case 5750: { // glGetSubroutineIndex
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
@@ -5975,7 +5983,7 @@ case 5749: { // glGetSubroutineIndex
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5750: { // glGetActiveSubroutineUniformName
+case 5751: { // glGetActiveSubroutineUniformName
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
@@ -5991,7 +5999,7 @@ case 5750: { // glGetActiveSubroutineUniformName
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5751: { // glGetActiveSubroutineName
+case 5752: { // glGetActiveSubroutineName
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
@@ -6007,13 +6015,13 @@ case 5751: { // glGetActiveSubroutineName
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5752: { // glUniformSubroutinesuiv
+case 5753: { // glUniformSubroutinesuiv
GLenum *shadertype = (GLenum *) bp; bp += 4;
int * indicesLen = (int *) bp; bp += 4;
- GLuint * indices = (GLuint *) bp; bp += (8-((*indicesLen*4+0)%8))%8;
+ GLuint * indices = (GLuint *) bp; bp += *indicesLen*4 + (8-((*indicesLen*4+0)%8))%8;
weglUniformSubroutinesuiv(*shadertype,*indicesLen,indices);
}; break;
-case 5753: { // glGetUniformSubroutineuiv
+case 5754: { // glGetUniformSubroutineuiv
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLuint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -6041,7 +6049,7 @@ case 5753: { // glGetUniformSubroutineuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5754: { // glGetProgramStageiv
+case 5755: { // glGetProgramStageiv
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -6053,28 +6061,28 @@ case 5754: { // glGetProgramStageiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5755: { // glPatchParameteri
+case 5756: { // glPatchParameteri
GLenum *pname = (GLenum *) bp; bp += 4;
GLint *value = (GLint *) bp; bp += 4;
weglPatchParameteri(*pname,*value);
}; break;
-case 5756: { // glPatchParameterfv
+case 5757: { // glPatchParameterfv
GLenum *pname = (GLenum *) bp; bp += 4;
int * valuesLen = (int *) bp; bp += 4;
- GLfloat * values = (GLfloat *) bp; bp += (8-((*valuesLen*4+0)%8))%8;
+ GLfloat * values = (GLfloat *) bp; bp += *valuesLen*4 + (8-((*valuesLen*4+0)%8))%8;
weglPatchParameterfv(*pname,values);
}; break;
-case 5757: { // glBindTransformFeedback
+case 5758: { // glBindTransformFeedback
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
weglBindTransformFeedback(*target,*id);
}; break;
-case 5758: { // glDeleteTransformFeedbacks
+case 5759: { // glDeleteTransformFeedbacks
int * idsLen = (int *) bp; bp += 4;
- GLuint * ids = (GLuint *) bp; bp += (8-((*idsLen*4+4)%8))%8;
+ GLuint * ids = (GLuint *) bp; bp += *idsLen*4 + (8-((*idsLen*4+4)%8))%8;
weglDeleteTransformFeedbacks(*idsLen,ids);
}; break;
-case 5759: { // glGenTransformFeedbacks
+case 5760: { // glGenTransformFeedbacks
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *ids;
ids = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -6090,7 +6098,7 @@ case 5759: { // glGenTransformFeedbacks
driver_free(rt);
driver_free(ids);
}; break;
-case 5760: { // glIsTransformFeedback
+case 5761: { // glIsTransformFeedback
GLuint *id = (GLuint *) bp; bp += 4;
GLboolean result = weglIsTransformFeedback(*id);
int AP = 0; ErlDrvTermData rt[6];
@@ -6099,35 +6107,35 @@ case 5760: { // glIsTransformFeedback
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5761: { // glPauseTransformFeedback
+case 5762: { // glPauseTransformFeedback
weglPauseTransformFeedback();
}; break;
-case 5762: { // glResumeTransformFeedback
+case 5763: { // glResumeTransformFeedback
weglResumeTransformFeedback();
}; break;
-case 5763: { // glDrawTransformFeedback
+case 5764: { // glDrawTransformFeedback
GLenum *mode = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
weglDrawTransformFeedback(*mode,*id);
}; break;
-case 5764: { // glDrawTransformFeedbackStream
+case 5765: { // glDrawTransformFeedbackStream
GLenum *mode = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
GLuint *stream = (GLuint *) bp; bp += 4;
weglDrawTransformFeedbackStream(*mode,*id,*stream);
}; break;
-case 5765: { // glBeginQueryIndexed
+case 5766: { // glBeginQueryIndexed
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
weglBeginQueryIndexed(*target,*index,*id);
}; break;
-case 5766: { // glEndQueryIndexed
+case 5767: { // glEndQueryIndexed
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
weglEndQueryIndexed(*target,*index);
}; break;
-case 5767: { // glGetQueryIndexediv
+case 5768: { // glGetQueryIndexediv
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -6139,18 +6147,18 @@ case 5767: { // glGetQueryIndexediv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5768: { // glReleaseShaderCompiler
+case 5769: { // glReleaseShaderCompiler
weglReleaseShaderCompiler();
}; break;
-case 5769: { // glShaderBinary
+case 5770: { // glShaderBinary
int * shadersLen = (int *) bp; bp += 4;
- GLuint * shaders = (GLuint *) bp; bp += (8-((*shadersLen*4+4)%8))%8;
+ GLuint * shaders = (GLuint *) bp; bp += *shadersLen*4 + (8-((*shadersLen*4+4)%8))%8;
GLenum *binaryformat = (GLenum *) bp; bp += 4;
GLvoid *binary = (GLvoid *) bins[0];
GLsizei binary_size = bins_sz[0];
weglShaderBinary(*shadersLen,shaders,*binaryformat,binary,binary_size);
}; break;
-case 5770: { // glGetShaderPrecisionFormat
+case 5771: { // glGetShaderPrecisionFormat
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLenum *precisiontype = (GLenum *) bp; bp += 4;
GLint range[2] = {0,0};
@@ -6167,16 +6175,16 @@ case 5770: { // glGetShaderPrecisionFormat
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5771: { // glDepthRangef
+case 5772: { // glDepthRangef
GLclampf *n = (GLclampf *) bp; bp += 4;
GLclampf *f = (GLclampf *) bp; bp += 4;
weglDepthRangef(*n,*f);
}; break;
-case 5772: { // glClearDepthf
+case 5773: { // glClearDepthf
GLclampf *d = (GLclampf *) bp; bp += 4;
weglClearDepthf(*d);
}; break;
-case 5773: { // glGetProgramBinary
+case 5774: { // glGetProgramBinary
GLuint *program = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -6192,31 +6200,31 @@ case 5773: { // glGetProgramBinary
driver_send_term(port,caller,rt,AP);
driver_free_binary(binary);
}; break;
-case 5774: { // glProgramBinary
+case 5775: { // glProgramBinary
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *binaryFormat = (GLenum *) bp; bp += 4;
GLvoid *binary = (GLvoid *) bins[0];
GLsizei binary_size = bins_sz[0];
weglProgramBinary(*program,*binaryFormat,binary,binary_size);
}; break;
-case 5775: { // glProgramParameteri
+case 5776: { // glProgramParameteri
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint *value = (GLint *) bp; bp += 4;
weglProgramParameteri(*program,*pname,*value);
}; break;
-case 5776: { // glUseProgramStages
+case 5777: { // glUseProgramStages
GLuint *pipeline = (GLuint *) bp; bp += 4;
GLbitfield *stages = (GLbitfield *) bp; bp += 4;
GLuint *program = (GLuint *) bp; bp += 4;
weglUseProgramStages(*pipeline,*stages,*program);
}; break;
-case 5777: { // glActiveShaderProgram
+case 5778: { // glActiveShaderProgram
GLuint *pipeline = (GLuint *) bp; bp += 4;
GLuint *program = (GLuint *) bp; bp += 4;
weglActiveShaderProgram(*pipeline,*program);
}; break;
-case 5778: { // glCreateShaderProgramv
+case 5779: { // glCreateShaderProgramv
GLenum *type = (GLenum *) bp; bp += 4;
int * stringsLen = (int *) bp; bp += 4;
int * stringsTotSize = (int *) bp; bp += 4;
@@ -6233,16 +6241,16 @@ case 5778: { // glCreateShaderProgramv
driver_send_term(port,caller,rt,AP);
driver_free(strings);
}; break;
-case 5779: { // glBindProgramPipeline
+case 5780: { // glBindProgramPipeline
GLuint *pipeline = (GLuint *) bp; bp += 4;
weglBindProgramPipeline(*pipeline);
}; break;
-case 5780: { // glDeleteProgramPipelines
+case 5781: { // glDeleteProgramPipelines
int * pipelinesLen = (int *) bp; bp += 4;
- GLuint * pipelines = (GLuint *) bp; bp += (8-((*pipelinesLen*4+4)%8))%8;
+ GLuint * pipelines = (GLuint *) bp; bp += *pipelinesLen*4 + (8-((*pipelinesLen*4+4)%8))%8;
weglDeleteProgramPipelines(*pipelinesLen,pipelines);
}; break;
-case 5781: { // glGenProgramPipelines
+case 5782: { // glGenProgramPipelines
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *pipelines;
pipelines = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -6258,7 +6266,7 @@ case 5781: { // glGenProgramPipelines
driver_free(rt);
driver_free(pipelines);
}; break;
-case 5782: { // glIsProgramPipeline
+case 5783: { // glIsProgramPipeline
GLuint *pipeline = (GLuint *) bp; bp += 4;
GLboolean result = weglIsProgramPipeline(*pipeline);
int AP = 0; ErlDrvTermData rt[6];
@@ -6267,7 +6275,7 @@ case 5782: { // glIsProgramPipeline
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5783: { // glGetProgramPipelineiv
+case 5784: { // glGetProgramPipelineiv
GLuint *pipeline = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -6278,115 +6286,115 @@ case 5783: { // glGetProgramPipelineiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5784: { // glProgramUniform1i
+case 5785: { // glProgramUniform1i
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
weglProgramUniform1i(*program,*location,*v0);
}; break;
-case 5785: { // glProgramUniform1iv
+case 5786: { // glProgramUniform1iv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int * valueLen = (int *) bp; bp += 4;
- GLint * value = (GLint *) bp; bp += (8-((*valueLen*4+4)%8))%8;
+ GLint * value = (GLint *) bp; bp += *valueLen*4 + (8-((*valueLen*4+4)%8))%8;
weglProgramUniform1iv(*program,*location,*valueLen,value);
}; break;
-case 5786: { // glProgramUniform1f
+case 5787: { // glProgramUniform1f
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
weglProgramUniform1f(*program,*location,*v0);
}; break;
-case 5787: { // glProgramUniform1fv
+case 5788: { // glProgramUniform1fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int * valueLen = (int *) bp; bp += 4;
- GLfloat * value = (GLfloat *) bp; bp += (8-((*valueLen*4+4)%8))%8;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*4 + (8-((*valueLen*4+4)%8))%8;
weglProgramUniform1fv(*program,*location,*valueLen,value);
}; break;
-case 5788: { // glProgramUniform1d
+case 5789: { // glProgramUniform1d
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLdouble *v0 = (GLdouble *) bp; bp += 8;
weglProgramUniform1d(*program,*location,*v0);
}; break;
-case 5789: { // glProgramUniform1dv
+case 5790: { // glProgramUniform1dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int * valueLen = (int *) bp; bp += 8;
- GLdouble * value = (GLdouble *) bp; bp += (8-((*valueLen*8+0)%8))%8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*8 + (8-((*valueLen*8+0)%8))%8;
weglProgramUniform1dv(*program,*location,*valueLen,value);
}; break;
-case 5790: { // glProgramUniform1ui
+case 5791: { // glProgramUniform1ui
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
weglProgramUniform1ui(*program,*location,*v0);
}; break;
-case 5791: { // glProgramUniform1uiv
+case 5792: { // glProgramUniform1uiv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int * valueLen = (int *) bp; bp += 4;
- GLuint * value = (GLuint *) bp; bp += (8-((*valueLen*4+4)%8))%8;
+ GLuint * value = (GLuint *) bp; bp += *valueLen*4 + (8-((*valueLen*4+4)%8))%8;
weglProgramUniform1uiv(*program,*location,*valueLen,value);
}; break;
-case 5792: { // glProgramUniform2i
+case 5793: { // glProgramUniform2i
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
GLint *v1 = (GLint *) bp; bp += 4;
weglProgramUniform2i(*program,*location,*v0,*v1);
}; break;
-case 5793: { // glProgramUniform2iv
+case 5794: { // glProgramUniform2iv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLint * value = (GLint *) bp; bp += *valueLen*8;
weglProgramUniform2iv(*program,*location,*valueLen,value);
}; break;
-case 5794: { // glProgramUniform2f
+case 5795: { // glProgramUniform2f
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
GLfloat *v1 = (GLfloat *) bp; bp += 4;
weglProgramUniform2f(*program,*location,*v0,*v1);
}; break;
-case 5795: { // glProgramUniform2fv
+case 5796: { // glProgramUniform2fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLfloat * value = (GLfloat *) bp; bp += *valueLen*8;
weglProgramUniform2fv(*program,*location,*valueLen,value);
}; break;
-case 5796: { // glProgramUniform2d
+case 5797: { // glProgramUniform2d
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLdouble *v0 = (GLdouble *) bp; bp += 8;
GLdouble *v1 = (GLdouble *) bp; bp += 8;
weglProgramUniform2d(*program,*location,*v0,*v1);
}; break;
-case 5797: { // glProgramUniform2dv
+case 5798: { // glProgramUniform2dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 8;
GLdouble * value = (GLdouble *) bp; bp += *valueLen*16;
weglProgramUniform2dv(*program,*location,*valueLen,value);
}; break;
-case 5798: { // glProgramUniform2ui
+case 5799: { // glProgramUniform2ui
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
GLuint *v1 = (GLuint *) bp; bp += 4;
weglProgramUniform2ui(*program,*location,*v0,*v1);
}; break;
-case 5799: { // glProgramUniform2uiv
+case 5800: { // glProgramUniform2uiv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLuint * value = (GLuint *) bp; bp += *valueLen*8;
weglProgramUniform2uiv(*program,*location,*valueLen,value);
}; break;
-case 5800: { // glProgramUniform3i
+case 5801: { // glProgramUniform3i
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
@@ -6394,14 +6402,14 @@ case 5800: { // glProgramUniform3i
GLint *v2 = (GLint *) bp; bp += 4;
weglProgramUniform3i(*program,*location,*v0,*v1,*v2);
}; break;
-case 5801: { // glProgramUniform3iv
+case 5802: { // glProgramUniform3iv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLint * value = (GLint *) bp; bp += *valueLen*12;
weglProgramUniform3iv(*program,*location,*valueLen,value);
}; break;
-case 5802: { // glProgramUniform3f
+case 5803: { // glProgramUniform3f
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
@@ -6409,14 +6417,14 @@ case 5802: { // glProgramUniform3f
GLfloat *v2 = (GLfloat *) bp; bp += 4;
weglProgramUniform3f(*program,*location,*v0,*v1,*v2);
}; break;
-case 5803: { // glProgramUniform3fv
+case 5804: { // glProgramUniform3fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLfloat * value = (GLfloat *) bp; bp += *valueLen*12;
weglProgramUniform3fv(*program,*location,*valueLen,value);
}; break;
-case 5804: { // glProgramUniform3d
+case 5805: { // glProgramUniform3d
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLdouble *v0 = (GLdouble *) bp; bp += 8;
@@ -6424,14 +6432,14 @@ case 5804: { // glProgramUniform3d
GLdouble *v2 = (GLdouble *) bp; bp += 8;
weglProgramUniform3d(*program,*location,*v0,*v1,*v2);
}; break;
-case 5805: { // glProgramUniform3dv
+case 5806: { // glProgramUniform3dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 8;
GLdouble * value = (GLdouble *) bp; bp += *valueLen*24;
weglProgramUniform3dv(*program,*location,*valueLen,value);
}; break;
-case 5806: { // glProgramUniform3ui
+case 5807: { // glProgramUniform3ui
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
@@ -6439,14 +6447,14 @@ case 5806: { // glProgramUniform3ui
GLuint *v2 = (GLuint *) bp; bp += 4;
weglProgramUniform3ui(*program,*location,*v0,*v1,*v2);
}; break;
-case 5807: { // glProgramUniform3uiv
+case 5808: { // glProgramUniform3uiv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLuint * value = (GLuint *) bp; bp += *valueLen*12;
weglProgramUniform3uiv(*program,*location,*valueLen,value);
}; break;
-case 5808: { // glProgramUniform4i
+case 5809: { // glProgramUniform4i
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
@@ -6455,14 +6463,14 @@ case 5808: { // glProgramUniform4i
GLint *v3 = (GLint *) bp; bp += 4;
weglProgramUniform4i(*program,*location,*v0,*v1,*v2,*v3);
}; break;
-case 5809: { // glProgramUniform4iv
+case 5810: { // glProgramUniform4iv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLint * value = (GLint *) bp; bp += *valueLen*16;
weglProgramUniform4iv(*program,*location,*valueLen,value);
}; break;
-case 5810: { // glProgramUniform4f
+case 5811: { // glProgramUniform4f
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
@@ -6471,14 +6479,14 @@ case 5810: { // glProgramUniform4f
GLfloat *v3 = (GLfloat *) bp; bp += 4;
weglProgramUniform4f(*program,*location,*v0,*v1,*v2,*v3);
}; break;
-case 5811: { // glProgramUniform4fv
+case 5812: { // glProgramUniform4fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLfloat * value = (GLfloat *) bp; bp += *valueLen*16;
weglProgramUniform4fv(*program,*location,*valueLen,value);
}; break;
-case 5812: { // glProgramUniform4d
+case 5813: { // glProgramUniform4d
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLdouble *v0 = (GLdouble *) bp; bp += 8;
@@ -6487,14 +6495,14 @@ case 5812: { // glProgramUniform4d
GLdouble *v3 = (GLdouble *) bp; bp += 8;
weglProgramUniform4d(*program,*location,*v0,*v1,*v2,*v3);
}; break;
-case 5813: { // glProgramUniform4dv
+case 5814: { // glProgramUniform4dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 8;
GLdouble * value = (GLdouble *) bp; bp += *valueLen*32;
weglProgramUniform4dv(*program,*location,*valueLen,value);
}; break;
-case 5814: { // glProgramUniform4ui
+case 5815: { // glProgramUniform4ui
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
@@ -6503,14 +6511,14 @@ case 5814: { // glProgramUniform4ui
GLuint *v3 = (GLuint *) bp; bp += 4;
weglProgramUniform4ui(*program,*location,*v0,*v1,*v2,*v3);
}; break;
-case 5815: { // glProgramUniform4uiv
+case 5816: { // glProgramUniform4uiv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLuint * value = (GLuint *) bp; bp += *valueLen*16;
weglProgramUniform4uiv(*program,*location,*valueLen,value);
}; break;
-case 5816: { // glProgramUniformMatrix2fv
+case 5817: { // glProgramUniformMatrix2fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6519,7 +6527,7 @@ case 5816: { // glProgramUniformMatrix2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*16;
weglProgramUniformMatrix2fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5817: { // glProgramUniformMatrix3fv
+case 5818: { // glProgramUniformMatrix3fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6528,7 +6536,7 @@ case 5817: { // glProgramUniformMatrix3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*36;
weglProgramUniformMatrix3fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5818: { // glProgramUniformMatrix4fv
+case 5819: { // glProgramUniformMatrix4fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6537,7 +6545,7 @@ case 5818: { // glProgramUniformMatrix4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*64;
weglProgramUniformMatrix4fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5819: { // glProgramUniformMatrix2dv
+case 5820: { // glProgramUniformMatrix2dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6546,7 +6554,7 @@ case 5819: { // glProgramUniformMatrix2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*32;
weglProgramUniformMatrix2dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5820: { // glProgramUniformMatrix3dv
+case 5821: { // glProgramUniformMatrix3dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6555,7 +6563,7 @@ case 5820: { // glProgramUniformMatrix3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*72;
weglProgramUniformMatrix3dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5821: { // glProgramUniformMatrix4dv
+case 5822: { // glProgramUniformMatrix4dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6564,7 +6572,7 @@ case 5821: { // glProgramUniformMatrix4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*128;
weglProgramUniformMatrix4dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5822: { // glProgramUniformMatrix2x3fv
+case 5823: { // glProgramUniformMatrix2x3fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6573,7 +6581,7 @@ case 5822: { // glProgramUniformMatrix2x3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*24;
weglProgramUniformMatrix2x3fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5823: { // glProgramUniformMatrix3x2fv
+case 5824: { // glProgramUniformMatrix3x2fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6582,7 +6590,7 @@ case 5823: { // glProgramUniformMatrix3x2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*24;
weglProgramUniformMatrix3x2fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5824: { // glProgramUniformMatrix2x4fv
+case 5825: { // glProgramUniformMatrix2x4fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6591,7 +6599,7 @@ case 5824: { // glProgramUniformMatrix2x4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*32;
weglProgramUniformMatrix2x4fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5825: { // glProgramUniformMatrix4x2fv
+case 5826: { // glProgramUniformMatrix4x2fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6600,7 +6608,7 @@ case 5825: { // glProgramUniformMatrix4x2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*32;
weglProgramUniformMatrix4x2fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5826: { // glProgramUniformMatrix3x4fv
+case 5827: { // glProgramUniformMatrix3x4fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6609,7 +6617,7 @@ case 5826: { // glProgramUniformMatrix3x4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*48;
weglProgramUniformMatrix3x4fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5827: { // glProgramUniformMatrix4x3fv
+case 5828: { // glProgramUniformMatrix4x3fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6618,7 +6626,7 @@ case 5827: { // glProgramUniformMatrix4x3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*48;
weglProgramUniformMatrix4x3fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5828: { // glProgramUniformMatrix2x3dv
+case 5829: { // glProgramUniformMatrix2x3dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6627,7 +6635,7 @@ case 5828: { // glProgramUniformMatrix2x3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
weglProgramUniformMatrix2x3dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5829: { // glProgramUniformMatrix3x2dv
+case 5830: { // glProgramUniformMatrix3x2dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6636,7 +6644,7 @@ case 5829: { // glProgramUniformMatrix3x2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
weglProgramUniformMatrix3x2dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5830: { // glProgramUniformMatrix2x4dv
+case 5831: { // glProgramUniformMatrix2x4dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6645,7 +6653,7 @@ case 5830: { // glProgramUniformMatrix2x4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
weglProgramUniformMatrix2x4dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5831: { // glProgramUniformMatrix4x2dv
+case 5832: { // glProgramUniformMatrix4x2dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6654,7 +6662,7 @@ case 5831: { // glProgramUniformMatrix4x2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
weglProgramUniformMatrix4x2dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5832: { // glProgramUniformMatrix3x4dv
+case 5833: { // glProgramUniformMatrix3x4dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6663,7 +6671,7 @@ case 5832: { // glProgramUniformMatrix3x4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
weglProgramUniformMatrix3x4dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5833: { // glProgramUniformMatrix4x3dv
+case 5834: { // glProgramUniformMatrix4x3dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6672,11 +6680,11 @@ case 5833: { // glProgramUniformMatrix4x3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
weglProgramUniformMatrix4x3dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5834: { // glValidateProgramPipeline
+case 5835: { // glValidateProgramPipeline
GLuint *pipeline = (GLuint *) bp; bp += 4;
weglValidateProgramPipeline(*pipeline);
}; break;
-case 5835: { // glGetProgramPipelineInfoLog
+case 5836: { // glGetProgramPipelineInfoLog
GLuint *pipeline = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -6690,31 +6698,31 @@ case 5835: { // glGetProgramPipelineInfoLog
driver_send_term(port,caller,rt,AP);
driver_free(infoLog);
}; break;
-case 5836: { // glVertexAttribL1dv
+case 5837: { // glVertexAttribL1dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttribL1dv(*index,v);
}; break;
-case 5837: { // glVertexAttribL2dv
+case 5838: { // glVertexAttribL2dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttribL2dv(*index,v);
}; break;
-case 5838: { // glVertexAttribL3dv
+case 5839: { // glVertexAttribL3dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttribL3dv(*index,v);
}; break;
-case 5839: { // glVertexAttribL4dv
+case 5840: { // glVertexAttribL4dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttribL4dv(*index,v);
}; break;
-case 5840: { // glVertexAttribLPointer
+case 5841: { // glVertexAttribLPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6722,7 +6730,7 @@ case 5840: { // glVertexAttribLPointer
GLvoid *pointer = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglVertexAttribLPointer(*index,*size,*type,*stride,pointer);
}; break;
-case 5841: { // glVertexAttribLPointer
+case 5842: { // glVertexAttribLPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6730,7 +6738,7 @@ case 5841: { // glVertexAttribLPointer
GLvoid *pointer = (GLvoid *) bins[0];
weglVertexAttribLPointer(*index,*size,*type,*stride,pointer);
}; break;
-case 5842: { // glGetVertexAttribLdv
+case 5843: { // glGetVertexAttribLdv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLdouble params[4] = {0.0,0.0,0.0,0.0};
@@ -6746,13 +6754,13 @@ case 5842: { // glGetVertexAttribLdv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5843: { // glViewportArrayv
+case 5844: { // glViewportArrayv
GLuint *first = (GLuint *) bp; bp += 4;
int *vLen = (int *) bp; bp += 4;
GLfloat * v = (GLfloat *) bp; bp += *vLen*16;
weglViewportArrayv(*first,*vLen,v);
}; break;
-case 5844: { // glViewportIndexedf
+case 5845: { // glViewportIndexedf
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *x = (GLfloat *) bp; bp += 4;
GLfloat *y = (GLfloat *) bp; bp += 4;
@@ -6760,18 +6768,18 @@ case 5844: { // glViewportIndexedf
GLfloat *h = (GLfloat *) bp; bp += 4;
weglViewportIndexedf(*index,*x,*y,*w,*h);
}; break;
-case 5845: { // glViewportIndexedfv
+case 5846: { // glViewportIndexedfv
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat * v = (GLfloat *) bp; bp += 16;
weglViewportIndexedfv(*index,v);
}; break;
-case 5846: { // glScissorArrayv
+case 5847: { // glScissorArrayv
GLuint *first = (GLuint *) bp; bp += 4;
int *vLen = (int *) bp; bp += 4;
GLint * v = (GLint *) bp; bp += *vLen*16;
weglScissorArrayv(*first,*vLen,v);
}; break;
-case 5847: { // glScissorIndexed
+case 5848: { // glScissorIndexed
GLuint *index = (GLuint *) bp; bp += 4;
GLint *left = (GLint *) bp; bp += 4;
GLint *bottom = (GLint *) bp; bp += 4;
@@ -6779,26 +6787,26 @@ case 5847: { // glScissorIndexed
GLsizei *height = (GLsizei *) bp; bp += 4;
weglScissorIndexed(*index,*left,*bottom,*width,*height);
}; break;
-case 5848: { // glScissorIndexedv
+case 5849: { // glScissorIndexedv
GLuint *index = (GLuint *) bp; bp += 4;
GLint * v = (GLint *) bp; bp += 16;
weglScissorIndexedv(*index,v);
}; break;
-case 5849: { // glDepthRangeArrayv
+case 5850: { // glDepthRangeArrayv
GLuint *first = (GLuint *) bp; bp += 4;
bp += 4;
int *vLen = (int *) bp; bp += 8;
GLclampd * v = (GLclampd *) bp; bp += *vLen*16;
weglDepthRangeArrayv(*first,*vLen,v);
}; break;
-case 5850: { // glDepthRangeIndexed
+case 5851: { // glDepthRangeIndexed
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLclampd *n = (GLclampd *) bp; bp += 8;
GLclampd *f = (GLclampd *) bp; bp += 8;
weglDepthRangeIndexed(*index,*n,*f);
}; break;
-case 5851: { // glGetFloati_v
+case 5852: { // glGetFloati_v
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat data[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
@@ -6827,7 +6835,7 @@ case 5851: { // glGetFloati_v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5852: { // glGetDoublei_v
+case 5853: { // glGetDoublei_v
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble data[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
@@ -6855,16 +6863,16 @@ case 5852: { // glGetDoublei_v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5853: { // glDebugMessageControlARB
+case 5854: { // glDebugMessageControlARB
GLenum *source = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLenum *severity = (GLenum *) bp; bp += 4;
int * idsLen = (int *) bp; bp += 4;
- GLuint * ids = (GLuint *) bp; bp += (8-((*idsLen*4+0)%8))%8;
+ GLuint * ids = (GLuint *) bp; bp += *idsLen*4 + (8-((*idsLen*4+0)%8))%8;
GLboolean *enabled = (GLboolean *) bp; bp += 1;
weglDebugMessageControlARB(*source,*type,*severity,*idsLen,ids,*enabled);
}; break;
-case 5854: { // glDebugMessageInsertARB
+case 5855: { // glDebugMessageInsertARB
GLenum *source = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
@@ -6873,7 +6881,7 @@ case 5854: { // glDebugMessageInsertARB
int bufLen[1] = {(int)strlen((char *)buf)}; bp += bufLen[0]+1+((8-((1+bufLen[0]+0)%8))%8);
weglDebugMessageInsertARB(*source,*type,*id,*severity,*bufLen,buf);
}; break;
-case 5855: { // glGetDebugMessageLogARB
+case 5856: { // glGetDebugMessageLogARB
GLuint *count = (GLuint *) bp; bp += 4;
GLsizei *bufsize = (GLsizei *) bp; bp += 4;
GLenum *sources;
@@ -6920,7 +6928,7 @@ case 5855: { // glGetDebugMessageLogARB
driver_free(types);
driver_free(sources);
}; break;
-case 5856: { // glGetGraphicsResetStatusARB
+case 5857: { // glGetGraphicsResetStatusARB
GLenum result = weglGetGraphicsResetStatusARB();
int AP = 0; ErlDrvTermData rt[6];
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
@@ -6928,7 +6936,7 @@ case 5856: { // glGetGraphicsResetStatusARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5857: { // glDrawArraysInstancedBaseInstance
+case 5858: { // glDrawArraysInstancedBaseInstance
GLenum *mode = (GLenum *) bp; bp += 4;
GLint *first = (GLint *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
@@ -6936,7 +6944,7 @@ case 5857: { // glDrawArraysInstancedBaseInstance
GLuint *baseinstance = (GLuint *) bp; bp += 4;
weglDrawArraysInstancedBaseInstance(*mode,*first,*count,*primcount,*baseinstance);
}; break;
-case 5858: { // glDrawElementsInstancedBaseInstance
+case 5859: { // glDrawElementsInstancedBaseInstance
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6945,7 +6953,7 @@ case 5858: { // glDrawElementsInstancedBaseInstance
GLuint *baseinstance = (GLuint *) bp; bp += 4;
weglDrawElementsInstancedBaseInstance(*mode,*count,*type,indices,*primcount,*baseinstance);
}; break;
-case 5859: { // glDrawElementsInstancedBaseInstance
+case 5860: { // glDrawElementsInstancedBaseInstance
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6954,7 +6962,7 @@ case 5859: { // glDrawElementsInstancedBaseInstance
GLuint *baseinstance = (GLuint *) bp; bp += 4;
weglDrawElementsInstancedBaseInstance(*mode,*count,*type,indices,*primcount,*baseinstance);
}; break;
-case 5860: { // glDrawElementsInstancedBaseVertexBaseInstance
+case 5861: { // glDrawElementsInstancedBaseVertexBaseInstance
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6964,7 +6972,7 @@ case 5860: { // glDrawElementsInstancedBaseVertexBaseInstance
GLuint *baseinstance = (GLuint *) bp; bp += 4;
weglDrawElementsInstancedBaseVertexBaseInstance(*mode,*count,*type,indices,*primcount,*basevertex,*baseinstance);
}; break;
-case 5861: { // glDrawElementsInstancedBaseVertexBaseInstance
+case 5862: { // glDrawElementsInstancedBaseVertexBaseInstance
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6974,20 +6982,20 @@ case 5861: { // glDrawElementsInstancedBaseVertexBaseInstance
GLuint *baseinstance = (GLuint *) bp; bp += 4;
weglDrawElementsInstancedBaseVertexBaseInstance(*mode,*count,*type,indices,*primcount,*basevertex,*baseinstance);
}; break;
-case 5862: { // glDrawTransformFeedbackInstanced
+case 5863: { // glDrawTransformFeedbackInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
GLsizei *primcount = (GLsizei *) bp; bp += 4;
weglDrawTransformFeedbackInstanced(*mode,*id,*primcount);
}; break;
-case 5863: { // glDrawTransformFeedbackStreamInstanced
+case 5864: { // glDrawTransformFeedbackStreamInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
GLuint *stream = (GLuint *) bp; bp += 4;
GLsizei *primcount = (GLsizei *) bp; bp += 4;
weglDrawTransformFeedbackStreamInstanced(*mode,*id,*stream,*primcount);
}; break;
-case 5864: { // glGetInternalformativ
+case 5865: { // glGetInternalformativ
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -7006,7 +7014,7 @@ case 5864: { // glGetInternalformativ
driver_free(rt);
driver_free(params);
}; break;
-case 5865: { // glBindImageTexture
+case 5866: { // glBindImageTexture
GLuint *unit = (GLuint *) bp; bp += 4;
GLuint *texture = (GLuint *) bp; bp += 4;
GLint *level = (GLint *) bp; bp += 4;
@@ -7017,18 +7025,18 @@ case 5865: { // glBindImageTexture
GLenum *format = (GLenum *) bp; bp += 4;
weglBindImageTexture(*unit,*texture,*level,*layered,*layer,*access,*format);
}; break;
-case 5866: { // glMemoryBarrier
+case 5867: { // glMemoryBarrier
GLbitfield *barriers = (GLbitfield *) bp; bp += 4;
weglMemoryBarrier(*barriers);
}; break;
-case 5867: { // glTexStorage1D
+case 5868: { // glTexStorage1D
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *levels = (GLsizei *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
GLsizei *width = (GLsizei *) bp; bp += 4;
weglTexStorage1D(*target,*levels,*internalformat,*width);
}; break;
-case 5868: { // glTexStorage2D
+case 5869: { // glTexStorage2D
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *levels = (GLsizei *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
@@ -7036,7 +7044,7 @@ case 5868: { // glTexStorage2D
GLsizei *height = (GLsizei *) bp; bp += 4;
weglTexStorage2D(*target,*levels,*internalformat,*width,*height);
}; break;
-case 5869: { // glTexStorage3D
+case 5870: { // glTexStorage3D
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *levels = (GLsizei *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
@@ -7045,12 +7053,12 @@ case 5869: { // glTexStorage3D
GLsizei *depth = (GLsizei *) bp; bp += 4;
weglTexStorage3D(*target,*levels,*internalformat,*width,*height,*depth);
}; break;
-case 5870: { // glDepthBoundsEXT
+case 5871: { // glDepthBoundsEXT
GLclampd *zmin = (GLclampd *) bp; bp += 8;
GLclampd *zmax = (GLclampd *) bp; bp += 8;
weglDepthBoundsEXT(*zmin,*zmax);
}; break;
-case 5871: { // glStencilClearTagEXT
+case 5872: { // glStencilClearTagEXT
GLsizei *stencilTagBits = (GLsizei *) bp; bp += 4;
GLuint *stencilClearTag = (GLuint *) bp; bp += 4;
weglStencilClearTagEXT(*stencilTagBits,*stencilClearTag);
diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp
index 4affe2ba53..01787c8a64 100644
--- a/lib/wx/c_src/gen/wxe_events.cpp
+++ b/lib/wx/c_src/gen/wxe_events.cpp
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2015. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2016. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -306,6 +306,7 @@ void initEventTable()
{wxEVT_ACTIVATE_APP, 232, "activate_app"},
{wxEVT_HIBERNATE, 232, "hibernate"},
{wxEVT_MOUSE_CAPTURE_LOST, 235, "mouse_capture_lost"},
+ {wxEVT_DROP_FILES, 238, "drop_files"},
{-1, 0, }
};
for(int i=0; event_types[i].ev_type != -1; i++) {
@@ -881,6 +882,18 @@ case 235: {// wxMouseCaptureLostEvent
rt.addTupleCount(2);
break;
}
+case 238: {// wxDropFilesEvent
+ wxDropFilesEvent * ev = (wxDropFilesEvent *) event;
+ evClass = (char*)"wxDropFilesEvent";
+ rt.addAtom((char*)"wxDropFiles");
+ rt.addAtom(Etype->eName);
+ rt.addInt(ev->m_noFiles);
+ rt.add(ev->m_pos);
+ wxArrayString tmpArrayStr(ev->m_noFiles, ev->m_files);
+ rt.add(tmpArrayStr);
+ rt.addTupleCount(5);
+ break;
+}
}
rt.addTupleCount(5);
@@ -897,7 +910,7 @@ case 235: {// wxMouseCaptureLostEvent
} else {
send_res = rt.send();
if(cb->skip) event->Skip();
- if(app->recurse_level < 1) {
+ if(app->recurse_level < 1 && Etype->cID != 168) {
app->recurse_level++;
app->dispatch_cmds();
app->recurse_level--;
diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp
index 4243d8a35a..5425e9f3cb 100644
--- a/lib/wx/c_src/gen/wxe_funcs.cpp
+++ b/lib/wx/c_src/gen/wxe_funcs.cpp
@@ -315,6 +315,15 @@ case wxWindow_Disable: { // wxWindow::Disable
rt.addBool(Result);
break;
}
+#if wxCHECK_VERSION(2,8,10)
+case wxWindow_DragAcceptFiles: { // wxWindow::DragAcceptFiles
+ wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
+ bool * accept = (bool *) bp; bp += 4;
+ if(!This) throw wxe_badarg(0);
+ This->DragAcceptFiles(*accept);
+ break;
+}
+#endif
case wxWindow_Enable: { // wxWindow::Enable
bool enable=true;
wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
@@ -1707,6 +1716,15 @@ case wxWindow_SetDoubleBuffered: { // wxWindow::SetDoubleBuffered
break;
}
#endif
+#if wxCHECK_VERSION(2,9,5)
+case wxWindow_GetContentScaleFactor: { // wxWindow::GetContentScaleFactor
+ wxWindow *This = (wxWindow *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ double Result = This->GetContentScaleFactor();
+ rt.addFloat(Result);
+ break;
+}
+#endif
case wxTopLevelWindow_GetIcon: { // wxTopLevelWindow::GetIcon
wxTopLevelWindow *This = (wxTopLevelWindow *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
@@ -32049,6 +32067,28 @@ case wxDCOverlay_Clear: { // wxDCOverlay::Clear
This->Clear();
break;
}
+case wxDropFilesEvent_GetPosition: { // wxDropFilesEvent::GetPosition
+ wxDropFilesEvent *This = (wxDropFilesEvent *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ wxPoint Result = This->GetPosition();
+ rt.add(Result);
+ break;
+}
+case wxDropFilesEvent_GetNumberOfFiles: { // wxDropFilesEvent::GetNumberOfFiles
+ wxDropFilesEvent *This = (wxDropFilesEvent *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ int Result = This->GetNumberOfFiles();
+ rt.addInt(Result);
+ break;
+}
+case wxDropFilesEvent_GetFiles: { // wxDropFilesEvent::GetFiles
+ wxDropFilesEvent *This = (wxDropFilesEvent *) getPtr(bp,memenv); bp += 4;
+ if(!This) throw wxe_badarg(0);
+ wxString * Result = (wxString*)This->GetFiles();
+ wxArrayString tmpArrayStr(This->m_noFiles, Result);
+ rt.add(tmpArrayStr);
+ break;
+}
default: {
wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false); error.addAtom("_wxe_error_");
error.addInt((int) op);
diff --git a/lib/wx/c_src/gen/wxe_macros.h b/lib/wx/c_src/gen/wxe_macros.h
index 82b39b49cd..f44fa57053 100644
--- a/lib/wx/c_src/gen/wxe_macros.h
+++ b/lib/wx/c_src/gen/wxe_macros.h
@@ -94,3332 +94,3337 @@
#define wxWindow_Destroy 123
#define wxWindow_DestroyChildren 124
#define wxWindow_Disable 125
-#define wxWindow_Enable 126
-#define wxWindow_FindFocus 127
-#define wxWindow_FindWindow_1_0 128
-#define wxWindow_FindWindow_1_1 129
-#define wxWindow_FindWindowById 130
-#define wxWindow_FindWindowByName 131
-#define wxWindow_FindWindowByLabel 132
-#define wxWindow_Fit 133
-#define wxWindow_FitInside 134
-#define wxWindow_Freeze 135
-#define wxWindow_GetAcceleratorTable 136
-#define wxWindow_GetBackgroundColour 137
-#define wxWindow_GetBackgroundStyle 138
-#define wxWindow_GetBestSize 139
-#define wxWindow_GetCaret 141
-#define wxWindow_GetCapture 142
-#define wxWindow_GetCharHeight 143
-#define wxWindow_GetCharWidth 144
-#define wxWindow_GetChildren 145
-#define wxWindow_GetClientSize 148
-#define wxWindow_GetContainingSizer 149
-#define wxWindow_GetCursor 150
-#define wxWindow_GetDropTarget 151
-#define wxWindow_GetEventHandler 152
-#define wxWindow_GetExtraStyle 153
-#define wxWindow_GetFont 154
-#define wxWindow_GetForegroundColour 155
-#define wxWindow_GetGrandParent 156
-#define wxWindow_GetHandle 157
-#define wxWindow_GetHelpText 158
-#define wxWindow_GetId 159
-#define wxWindow_GetLabel 160
-#define wxWindow_GetMaxSize 161
-#define wxWindow_GetMinSize 162
-#define wxWindow_GetName 163
-#define wxWindow_GetParent 164
-#define wxWindow_GetPosition 166
-#define wxWindow_GetRect 167
-#define wxWindow_GetScreenPosition 169
-#define wxWindow_GetScreenRect 170
-#define wxWindow_GetScrollPos 171
-#define wxWindow_GetScrollRange 172
-#define wxWindow_GetScrollThumb 173
-#define wxWindow_GetSize 175
-#define wxWindow_GetSizer 176
-#define wxWindow_GetTextExtent 177
-#define wxWindow_GetToolTip 178
-#define wxWindow_GetUpdateRegion 179
-#define wxWindow_GetVirtualSize 181
-#define wxWindow_GetWindowStyleFlag 183
-#define wxWindow_GetWindowVariant 184
-#define wxWindow_HasCapture 185
-#define wxWindow_HasScrollbar 186
-#define wxWindow_HasTransparentBackground 187
-#define wxWindow_Hide 188
-#define wxWindow_InheritAttributes 189
-#define wxWindow_InitDialog 190
-#define wxWindow_InvalidateBestSize 191
-#define wxWindow_IsEnabled 192
-#define wxWindow_IsExposed_2 193
-#define wxWindow_IsExposed_4 194
-#define wxWindow_IsExposed_1_0 195
-#define wxWindow_IsExposed_1_1 196
-#define wxWindow_IsRetained 197
-#define wxWindow_IsShown 198
-#define wxWindow_IsTopLevel 199
-#define wxWindow_Layout 200
-#define wxWindow_LineDown 201
-#define wxWindow_LineUp 202
-#define wxWindow_Lower 203
-#define wxWindow_MakeModal 204
-#define wxWindow_Move_3 205
-#define wxWindow_Move_2 206
-#define wxWindow_MoveAfterInTabOrder 207
-#define wxWindow_MoveBeforeInTabOrder 208
-#define wxWindow_Navigate 209
-#define wxWindow_PageDown 210
-#define wxWindow_PageUp 211
-#define wxWindow_PopEventHandler 212
-#define wxWindow_PopupMenu_2 213
-#define wxWindow_PopupMenu_3 214
-#define wxWindow_Raise 215
-#define wxWindow_Refresh 216
-#define wxWindow_RefreshRect 217
-#define wxWindow_ReleaseMouse 218
-#define wxWindow_RemoveChild 219
-#define wxWindow_Reparent 220
-#define wxWindow_ScreenToClient_2 221
-#define wxWindow_ScreenToClient_1 222
-#define wxWindow_ScrollLines 224
-#define wxWindow_ScrollPages 226
-#define wxWindow_ScrollWindow 227
-#define wxWindow_SetAcceleratorTable 228
-#define wxWindow_SetAutoLayout 229
-#define wxWindow_SetBackgroundColour 230
-#define wxWindow_SetBackgroundStyle 231
-#define wxWindow_SetCaret 232
-#define wxWindow_SetClientSize_2 233
-#define wxWindow_SetClientSize_1_0 234
-#define wxWindow_SetClientSize_1_1 235
-#define wxWindow_SetContainingSizer 236
-#define wxWindow_SetCursor 237
-#define wxWindow_SetMaxSize 238
-#define wxWindow_SetMinSize 239
-#define wxWindow_SetOwnBackgroundColour 240
-#define wxWindow_SetOwnFont 241
-#define wxWindow_SetOwnForegroundColour 242
-#define wxWindow_SetDropTarget 243
-#define wxWindow_SetExtraStyle 244
-#define wxWindow_SetFocus 245
-#define wxWindow_SetFocusFromKbd 246
-#define wxWindow_SetFont 247
-#define wxWindow_SetForegroundColour 248
-#define wxWindow_SetHelpText 249
-#define wxWindow_SetId 250
-#define wxWindow_SetLabel 252
-#define wxWindow_SetName 253
-#define wxWindow_SetPalette 254
-#define wxWindow_SetScrollbar 255
-#define wxWindow_SetScrollPos 256
-#define wxWindow_SetSize_5 257
-#define wxWindow_SetSize_2_0 258
-#define wxWindow_SetSize_1 259
-#define wxWindow_SetSize_2_1 260
-#define wxWindow_SetSizeHints_3 261
-#define wxWindow_SetSizeHints_2 262
-#define wxWindow_SetSizer 263
-#define wxWindow_SetSizerAndFit 264
-#define wxWindow_SetThemeEnabled 265
-#define wxWindow_SetToolTip_1_0 266
-#define wxWindow_SetToolTip_1_1 267
-#define wxWindow_SetVirtualSize_1 268
-#define wxWindow_SetVirtualSize_2 269
-#define wxWindow_SetVirtualSizeHints_3 270
-#define wxWindow_SetVirtualSizeHints_2 271
-#define wxWindow_SetWindowStyle 272
-#define wxWindow_SetWindowStyleFlag 273
-#define wxWindow_SetWindowVariant 274
-#define wxWindow_ShouldInheritColours 275
-#define wxWindow_Show 276
-#define wxWindow_Thaw 277
-#define wxWindow_TransferDataFromWindow 278
-#define wxWindow_TransferDataToWindow 279
-#define wxWindow_Update 280
-#define wxWindow_UpdateWindowUI 281
-#define wxWindow_Validate 282
-#define wxWindow_WarpPointer 283
-#define wxWindow_SetTransparent 284
-#define wxWindow_CanSetTransparent 285
-#define wxWindow_IsDoubleBuffered 286
-#define wxWindow_SetDoubleBuffered 287
-#define wxTopLevelWindow_GetIcon 288
-#define wxTopLevelWindow_GetIcons 289
-#define wxTopLevelWindow_GetTitle 290
-#define wxTopLevelWindow_IsActive 291
-#define wxTopLevelWindow_Iconize 292
-#define wxTopLevelWindow_IsFullScreen 293
-#define wxTopLevelWindow_IsIconized 294
-#define wxTopLevelWindow_IsMaximized 295
-#define wxTopLevelWindow_Maximize 296
-#define wxTopLevelWindow_RequestUserAttention 297
-#define wxTopLevelWindow_SetIcon 298
-#define wxTopLevelWindow_SetIcons 299
-#define wxTopLevelWindow_CenterOnScreen 300
-#define wxTopLevelWindow_CentreOnScreen 301
-#define wxTopLevelWindow_SetShape 303
-#define wxTopLevelWindow_SetTitle 304
-#define wxTopLevelWindow_ShowFullScreen 305
-#define wxFrame_new_4 307
-#define wxFrame_new_0 308
-#define wxFrame_destruct 310
-#define wxFrame_Create 311
-#define wxFrame_CreateStatusBar 312
-#define wxFrame_CreateToolBar 313
-#define wxFrame_GetClientAreaOrigin 314
-#define wxFrame_GetMenuBar 315
-#define wxFrame_GetStatusBar 316
-#define wxFrame_GetStatusBarPane 317
-#define wxFrame_GetToolBar 318
-#define wxFrame_ProcessCommand 319
-#define wxFrame_SendSizeEvent 320
-#define wxFrame_SetMenuBar 321
-#define wxFrame_SetStatusBar 322
-#define wxFrame_SetStatusBarPane 323
-#define wxFrame_SetStatusText 324
-#define wxFrame_SetStatusWidths 325
-#define wxFrame_SetToolBar 326
-#define wxMiniFrame_new_0 327
-#define wxMiniFrame_new_4 328
-#define wxMiniFrame_Create 329
-#define wxMiniFrame_destroy 330
-#define wxSplashScreen_new_0 331
-#define wxSplashScreen_new_6 332
-#define wxSplashScreen_destruct 333
-#define wxSplashScreen_GetSplashStyle 334
-#define wxSplashScreen_GetTimeout 335
-#define wxPanel_new_0 336
-#define wxPanel_new_6 337
-#define wxPanel_new_2 338
-#define wxPanel_destruct 339
-#define wxPanel_InitDialog 340
-#define wxPanel_SetFocusIgnoringChildren 341
-#define wxScrolledWindow_new_0 342
-#define wxScrolledWindow_new_2 343
-#define wxScrolledWindow_destruct 344
-#define wxScrolledWindow_CalcScrolledPosition_4 345
-#define wxScrolledWindow_CalcScrolledPosition_1 346
-#define wxScrolledWindow_CalcUnscrolledPosition_4 347
-#define wxScrolledWindow_CalcUnscrolledPosition_1 348
-#define wxScrolledWindow_EnableScrolling 349
-#define wxScrolledWindow_GetScrollPixelsPerUnit 350
-#define wxScrolledWindow_GetViewStart 351
-#define wxScrolledWindow_DoPrepareDC 352
-#define wxScrolledWindow_PrepareDC 353
-#define wxScrolledWindow_Scroll 354
-#define wxScrolledWindow_SetScrollbars 355
-#define wxScrolledWindow_SetScrollRate 356
-#define wxScrolledWindow_SetTargetWindow 357
-#define wxSashWindow_new_0 358
-#define wxSashWindow_new_2 359
-#define wxSashWindow_destruct 360
-#define wxSashWindow_GetSashVisible 361
-#define wxSashWindow_GetMaximumSizeX 362
-#define wxSashWindow_GetMaximumSizeY 363
-#define wxSashWindow_GetMinimumSizeX 364
-#define wxSashWindow_GetMinimumSizeY 365
-#define wxSashWindow_SetMaximumSizeX 366
-#define wxSashWindow_SetMaximumSizeY 367
-#define wxSashWindow_SetMinimumSizeX 368
-#define wxSashWindow_SetMinimumSizeY 369
-#define wxSashWindow_SetSashVisible 370
-#define wxSashLayoutWindow_new_0 371
-#define wxSashLayoutWindow_new_2 372
-#define wxSashLayoutWindow_Create 373
-#define wxSashLayoutWindow_GetAlignment 374
-#define wxSashLayoutWindow_GetOrientation 375
-#define wxSashLayoutWindow_SetAlignment 376
-#define wxSashLayoutWindow_SetDefaultSize 377
-#define wxSashLayoutWindow_SetOrientation 378
-#define wxSashLayoutWindow_destroy 379
-#define wxGrid_new_0 380
-#define wxGrid_new_3 381
-#define wxGrid_new_4 382
-#define wxGrid_destruct 383
-#define wxGrid_AppendCols 384
-#define wxGrid_AppendRows 385
-#define wxGrid_AutoSize 386
-#define wxGrid_AutoSizeColumn 387
-#define wxGrid_AutoSizeColumns 388
-#define wxGrid_AutoSizeRow 389
-#define wxGrid_AutoSizeRows 390
-#define wxGrid_BeginBatch 391
-#define wxGrid_BlockToDeviceRect 392
-#define wxGrid_CanDragColSize 393
-#define wxGrid_CanDragRowSize 394
-#define wxGrid_CanDragGridSize 395
-#define wxGrid_CanEnableCellControl 396
-#define wxGrid_CellToRect_2 397
-#define wxGrid_CellToRect_1 398
-#define wxGrid_ClearGrid 399
-#define wxGrid_ClearSelection 400
-#define wxGrid_CreateGrid 401
-#define wxGrid_DeleteCols 402
-#define wxGrid_DeleteRows 403
-#define wxGrid_DisableCellEditControl 404
-#define wxGrid_DisableDragColSize 405
-#define wxGrid_DisableDragGridSize 406
-#define wxGrid_DisableDragRowSize 407
-#define wxGrid_EnableCellEditControl 408
-#define wxGrid_EnableDragColSize 409
-#define wxGrid_EnableDragGridSize 410
-#define wxGrid_EnableDragRowSize 411
-#define wxGrid_EnableEditing 412
-#define wxGrid_EnableGridLines 413
-#define wxGrid_EndBatch 414
-#define wxGrid_Fit 415
-#define wxGrid_ForceRefresh 416
-#define wxGrid_GetBatchCount 417
-#define wxGrid_GetCellAlignment 418
-#define wxGrid_GetCellBackgroundColour 419
-#define wxGrid_GetCellEditor 420
-#define wxGrid_GetCellFont 421
-#define wxGrid_GetCellRenderer 422
-#define wxGrid_GetCellTextColour 423
-#define wxGrid_GetCellValue_2 424
-#define wxGrid_GetCellValue_1 425
-#define wxGrid_GetColLabelAlignment 426
-#define wxGrid_GetColLabelSize 427
-#define wxGrid_GetColLabelValue 428
-#define wxGrid_GetColMinimalAcceptableWidth 429
-#define wxGrid_GetDefaultCellAlignment 430
-#define wxGrid_GetDefaultCellBackgroundColour 431
-#define wxGrid_GetDefaultCellFont 432
-#define wxGrid_GetDefaultCellTextColour 433
-#define wxGrid_GetDefaultColLabelSize 434
-#define wxGrid_GetDefaultColSize 435
-#define wxGrid_GetDefaultEditor 436
-#define wxGrid_GetDefaultEditorForCell_2 437
-#define wxGrid_GetDefaultEditorForCell_1 438
-#define wxGrid_GetDefaultEditorForType 439
-#define wxGrid_GetDefaultRenderer 440
-#define wxGrid_GetDefaultRendererForCell 441
-#define wxGrid_GetDefaultRendererForType 442
-#define wxGrid_GetDefaultRowLabelSize 443
-#define wxGrid_GetDefaultRowSize 444
-#define wxGrid_GetGridCursorCol 445
-#define wxGrid_GetGridCursorRow 446
-#define wxGrid_GetGridLineColour 447
-#define wxGrid_GridLinesEnabled 448
-#define wxGrid_GetLabelBackgroundColour 449
-#define wxGrid_GetLabelFont 450
-#define wxGrid_GetLabelTextColour 451
-#define wxGrid_GetNumberCols 452
-#define wxGrid_GetNumberRows 453
-#define wxGrid_GetOrCreateCellAttr 454
-#define wxGrid_GetRowMinimalAcceptableHeight 455
-#define wxGrid_GetRowLabelAlignment 456
-#define wxGrid_GetRowLabelSize 457
-#define wxGrid_GetRowLabelValue 458
-#define wxGrid_GetRowSize 459
-#define wxGrid_GetScrollLineX 460
-#define wxGrid_GetScrollLineY 461
-#define wxGrid_GetSelectedCells 462
-#define wxGrid_GetSelectedCols 463
-#define wxGrid_GetSelectedRows 464
-#define wxGrid_GetSelectionBackground 465
-#define wxGrid_GetSelectionBlockTopLeft 466
-#define wxGrid_GetSelectionBlockBottomRight 467
-#define wxGrid_GetSelectionForeground 468
-#define wxGrid_GetViewWidth 469
-#define wxGrid_GetGridWindow 470
-#define wxGrid_GetGridRowLabelWindow 471
-#define wxGrid_GetGridColLabelWindow 472
-#define wxGrid_GetGridCornerLabelWindow 473
-#define wxGrid_HideCellEditControl 474
-#define wxGrid_InsertCols 475
-#define wxGrid_InsertRows 476
-#define wxGrid_IsCellEditControlEnabled 477
-#define wxGrid_IsCurrentCellReadOnly 478
-#define wxGrid_IsEditable 479
-#define wxGrid_IsInSelection_2 480
-#define wxGrid_IsInSelection_1 481
-#define wxGrid_IsReadOnly 482
-#define wxGrid_IsSelection 483
-#define wxGrid_IsVisible_3 484
-#define wxGrid_IsVisible_2 485
-#define wxGrid_MakeCellVisible_2 486
-#define wxGrid_MakeCellVisible_1 487
-#define wxGrid_MoveCursorDown 488
-#define wxGrid_MoveCursorLeft 489
-#define wxGrid_MoveCursorRight 490
-#define wxGrid_MoveCursorUp 491
-#define wxGrid_MoveCursorDownBlock 492
-#define wxGrid_MoveCursorLeftBlock 493
-#define wxGrid_MoveCursorRightBlock 494
-#define wxGrid_MoveCursorUpBlock 495
-#define wxGrid_MovePageDown 496
-#define wxGrid_MovePageUp 497
-#define wxGrid_RegisterDataType 498
-#define wxGrid_SaveEditControlValue 499
-#define wxGrid_SelectAll 500
-#define wxGrid_SelectBlock_5 501
-#define wxGrid_SelectBlock_3 502
-#define wxGrid_SelectCol 503
-#define wxGrid_SelectRow 504
-#define wxGrid_SetCellAlignment_4 505
-#define wxGrid_SetCellAlignment_3 506
-#define wxGrid_SetCellAlignment_1 507
-#define wxGrid_SetCellBackgroundColour_3_0 508
-#define wxGrid_SetCellBackgroundColour_1 509
-#define wxGrid_SetCellBackgroundColour_3_1 510
-#define wxGrid_SetCellEditor 511
-#define wxGrid_SetCellFont 512
-#define wxGrid_SetCellRenderer 513
-#define wxGrid_SetCellTextColour_3_0 514
-#define wxGrid_SetCellTextColour_3_1 515
-#define wxGrid_SetCellTextColour_1 516
-#define wxGrid_SetCellValue_3_0 517
-#define wxGrid_SetCellValue_2 518
-#define wxGrid_SetCellValue_3_1 519
-#define wxGrid_SetColAttr 520
-#define wxGrid_SetColFormatBool 521
-#define wxGrid_SetColFormatNumber 522
-#define wxGrid_SetColFormatFloat 523
-#define wxGrid_SetColFormatCustom 524
-#define wxGrid_SetColLabelAlignment 525
-#define wxGrid_SetColLabelSize 526
-#define wxGrid_SetColLabelValue 527
-#define wxGrid_SetColMinimalWidth 528
-#define wxGrid_SetColMinimalAcceptableWidth 529
-#define wxGrid_SetColSize 530
-#define wxGrid_SetDefaultCellAlignment 531
-#define wxGrid_SetDefaultCellBackgroundColour 532
-#define wxGrid_SetDefaultCellFont 533
-#define wxGrid_SetDefaultCellTextColour 534
-#define wxGrid_SetDefaultEditor 535
-#define wxGrid_SetDefaultRenderer 536
-#define wxGrid_SetDefaultColSize 537
-#define wxGrid_SetDefaultRowSize 538
-#define wxGrid_SetGridCursor 539
-#define wxGrid_SetGridLineColour 540
-#define wxGrid_SetLabelBackgroundColour 541
-#define wxGrid_SetLabelFont 542
-#define wxGrid_SetLabelTextColour 543
-#define wxGrid_SetMargins 544
-#define wxGrid_SetReadOnly 545
-#define wxGrid_SetRowAttr 546
-#define wxGrid_SetRowLabelAlignment 547
-#define wxGrid_SetRowLabelSize 548
-#define wxGrid_SetRowLabelValue 549
-#define wxGrid_SetRowMinimalHeight 550
-#define wxGrid_SetRowMinimalAcceptableHeight 551
-#define wxGrid_SetRowSize 552
-#define wxGrid_SetScrollLineX 553
-#define wxGrid_SetScrollLineY 554
-#define wxGrid_SetSelectionBackground 555
-#define wxGrid_SetSelectionForeground 556
-#define wxGrid_SetSelectionMode 557
-#define wxGrid_ShowCellEditControl 558
-#define wxGrid_XToCol 559
-#define wxGrid_XToEdgeOfCol 560
-#define wxGrid_YToEdgeOfRow 561
-#define wxGrid_YToRow 562
-#define wxGridCellRenderer_Draw 563
-#define wxGridCellRenderer_GetBestSize 564
-#define wxGridCellEditor_Create 565
-#define wxGridCellEditor_IsCreated 566
-#define wxGridCellEditor_SetSize 567
-#define wxGridCellEditor_Show 568
-#define wxGridCellEditor_PaintBackground 569
-#define wxGridCellEditor_BeginEdit 570
-#define wxGridCellEditor_EndEdit 571
-#define wxGridCellEditor_Reset 572
-#define wxGridCellEditor_StartingKey 573
-#define wxGridCellEditor_StartingClick 574
-#define wxGridCellEditor_HandleReturn 575
-#define wxGridCellBoolRenderer_new 576
-#define wxGridCellBoolRenderer_destroy 577
-#define wxGridCellBoolEditor_new 578
-#define wxGridCellBoolEditor_IsTrueValue 579
-#define wxGridCellBoolEditor_UseStringValues 580
-#define wxGridCellBoolEditor_destroy 581
-#define wxGridCellFloatRenderer_new 582
-#define wxGridCellFloatRenderer_GetPrecision 583
-#define wxGridCellFloatRenderer_GetWidth 584
-#define wxGridCellFloatRenderer_SetParameters 585
-#define wxGridCellFloatRenderer_SetPrecision 586
-#define wxGridCellFloatRenderer_SetWidth 587
-#define wxGridCellFloatRenderer_destroy 588
-#define wxGridCellFloatEditor_new 589
-#define wxGridCellFloatEditor_SetParameters 590
-#define wxGridCellFloatEditor_destroy 591
-#define wxGridCellStringRenderer_new 592
-#define wxGridCellStringRenderer_destroy 593
-#define wxGridCellTextEditor_new 594
-#define wxGridCellTextEditor_SetParameters 595
-#define wxGridCellTextEditor_destroy 596
-#define wxGridCellChoiceEditor_new 598
-#define wxGridCellChoiceEditor_SetParameters 599
-#define wxGridCellChoiceEditor_destroy 600
-#define wxGridCellNumberRenderer_new 601
-#define wxGridCellNumberRenderer_destroy 602
-#define wxGridCellNumberEditor_new 603
-#define wxGridCellNumberEditor_GetValue 604
-#define wxGridCellNumberEditor_SetParameters 605
-#define wxGridCellNumberEditor_destroy 606
-#define wxGridCellAttr_SetTextColour 607
-#define wxGridCellAttr_SetBackgroundColour 608
-#define wxGridCellAttr_SetFont 609
-#define wxGridCellAttr_SetAlignment 610
-#define wxGridCellAttr_SetReadOnly 611
-#define wxGridCellAttr_SetRenderer 612
-#define wxGridCellAttr_SetEditor 613
-#define wxGridCellAttr_HasTextColour 614
-#define wxGridCellAttr_HasBackgroundColour 615
-#define wxGridCellAttr_HasFont 616
-#define wxGridCellAttr_HasAlignment 617
-#define wxGridCellAttr_HasRenderer 618
-#define wxGridCellAttr_HasEditor 619
-#define wxGridCellAttr_GetTextColour 620
-#define wxGridCellAttr_GetBackgroundColour 621
-#define wxGridCellAttr_GetFont 622
-#define wxGridCellAttr_GetAlignment 623
-#define wxGridCellAttr_GetRenderer 624
-#define wxGridCellAttr_GetEditor 625
-#define wxGridCellAttr_IsReadOnly 626
-#define wxGridCellAttr_SetDefAttr 627
-#define wxDC_Blit 628
-#define wxDC_CalcBoundingBox 629
-#define wxDC_Clear 630
-#define wxDC_ComputeScaleAndOrigin 631
-#define wxDC_CrossHair 632
-#define wxDC_DestroyClippingRegion 633
-#define wxDC_DeviceToLogicalX 634
-#define wxDC_DeviceToLogicalXRel 635
-#define wxDC_DeviceToLogicalY 636
-#define wxDC_DeviceToLogicalYRel 637
-#define wxDC_DrawArc 638
-#define wxDC_DrawBitmap 639
-#define wxDC_DrawCheckMark 640
-#define wxDC_DrawCircle 641
-#define wxDC_DrawEllipse_2 643
-#define wxDC_DrawEllipse_1 644
-#define wxDC_DrawEllipticArc 645
-#define wxDC_DrawIcon 646
-#define wxDC_DrawLabel 647
-#define wxDC_DrawLine 648
-#define wxDC_DrawLines 649
-#define wxDC_DrawPolygon 651
-#define wxDC_DrawPoint 653
-#define wxDC_DrawRectangle_2 655
-#define wxDC_DrawRectangle_1 656
-#define wxDC_DrawRotatedText 657
-#define wxDC_DrawRoundedRectangle_3 659
-#define wxDC_DrawRoundedRectangle_2 660
-#define wxDC_DrawText 661
-#define wxDC_EndDoc 662
-#define wxDC_EndPage 663
-#define wxDC_FloodFill 664
-#define wxDC_GetBackground 665
-#define wxDC_GetBackgroundMode 666
-#define wxDC_GetBrush 667
-#define wxDC_GetCharHeight 668
-#define wxDC_GetCharWidth 669
-#define wxDC_GetClippingBox 670
-#define wxDC_GetFont 672
-#define wxDC_GetLayoutDirection 673
-#define wxDC_GetLogicalFunction 674
-#define wxDC_GetMapMode 675
-#define wxDC_GetMultiLineTextExtent_4 676
-#define wxDC_GetMultiLineTextExtent_1 677
-#define wxDC_GetPartialTextExtents 678
-#define wxDC_GetPen 679
-#define wxDC_GetPixel 680
-#define wxDC_GetPPI 681
-#define wxDC_GetSize 683
-#define wxDC_GetSizeMM 685
-#define wxDC_GetTextBackground 686
-#define wxDC_GetTextExtent_4 687
-#define wxDC_GetTextExtent_1 688
-#define wxDC_GetTextForeground 690
-#define wxDC_GetUserScale 691
-#define wxDC_GradientFillConcentric_3 692
-#define wxDC_GradientFillConcentric_4 693
-#define wxDC_GradientFillLinear 694
-#define wxDC_LogicalToDeviceX 695
-#define wxDC_LogicalToDeviceXRel 696
-#define wxDC_LogicalToDeviceY 697
-#define wxDC_LogicalToDeviceYRel 698
-#define wxDC_MaxX 699
-#define wxDC_MaxY 700
-#define wxDC_MinX 701
-#define wxDC_MinY 702
-#define wxDC_IsOk 703
-#define wxDC_ResetBoundingBox 704
-#define wxDC_SetAxisOrientation 705
-#define wxDC_SetBackground 706
-#define wxDC_SetBackgroundMode 707
-#define wxDC_SetBrush 708
-#define wxDC_SetClippingRegion_2 710
-#define wxDC_SetClippingRegion_1_1 711
-#define wxDC_SetClippingRegion_1_0 712
-#define wxDC_SetDeviceOrigin 713
-#define wxDC_SetFont 714
-#define wxDC_SetLayoutDirection 715
-#define wxDC_SetLogicalFunction 716
-#define wxDC_SetMapMode 717
-#define wxDC_SetPalette 718
-#define wxDC_SetPen 719
-#define wxDC_SetTextBackground 720
-#define wxDC_SetTextForeground 721
-#define wxDC_SetUserScale 722
-#define wxDC_StartDoc 723
-#define wxDC_StartPage 724
-#define wxMirrorDC_new 725
-#define wxMirrorDC_destroy 726
-#define wxScreenDC_new 727
-#define wxScreenDC_destruct 728
-#define wxPostScriptDC_new_0 729
-#define wxPostScriptDC_new_1 730
-#define wxPostScriptDC_destruct 731
-#define wxPostScriptDC_SetResolution 732
-#define wxPostScriptDC_GetResolution 733
-#define wxWindowDC_new_0 734
-#define wxWindowDC_new_1 735
-#define wxWindowDC_destruct 736
-#define wxClientDC_new_0 737
-#define wxClientDC_new_1 738
-#define wxClientDC_destroy 739
-#define wxPaintDC_new_0 740
-#define wxPaintDC_new_1 741
-#define wxPaintDC_destroy 742
-#define wxMemoryDC_new_1_0 744
-#define wxMemoryDC_new_1_1 745
-#define wxMemoryDC_new_0 746
-#define wxMemoryDC_destruct 748
-#define wxMemoryDC_SelectObject 749
-#define wxMemoryDC_SelectObjectAsSource 750
-#define wxBufferedDC_new_0 751
-#define wxBufferedDC_new_2 752
-#define wxBufferedDC_new_3 753
-#define wxBufferedDC_destruct 754
-#define wxBufferedDC_Init_2 755
-#define wxBufferedDC_Init_3 756
-#define wxBufferedPaintDC_new_3 757
-#define wxBufferedPaintDC_new_2 758
-#define wxBufferedPaintDC_destruct 759
-#define wxGraphicsObject_destruct 760
-#define wxGraphicsObject_GetRenderer 761
-#define wxGraphicsObject_IsNull 762
-#define wxGraphicsContext_destruct 763
-#define wxGraphicsContext_Create_1_1 764
-#define wxGraphicsContext_Create_1_0 765
-#define wxGraphicsContext_Create_0 766
-#define wxGraphicsContext_CreatePen 767
-#define wxGraphicsContext_CreateBrush 768
-#define wxGraphicsContext_CreateRadialGradientBrush 769
-#define wxGraphicsContext_CreateLinearGradientBrush 770
-#define wxGraphicsContext_CreateFont 771
-#define wxGraphicsContext_CreateMatrix 772
-#define wxGraphicsContext_CreatePath 773
-#define wxGraphicsContext_Clip_1 774
-#define wxGraphicsContext_Clip_4 775
-#define wxGraphicsContext_ResetClip 776
-#define wxGraphicsContext_DrawBitmap 777
-#define wxGraphicsContext_DrawEllipse 778
-#define wxGraphicsContext_DrawIcon 779
-#define wxGraphicsContext_DrawLines 780
-#define wxGraphicsContext_DrawPath 781
-#define wxGraphicsContext_DrawRectangle 782
-#define wxGraphicsContext_DrawRoundedRectangle 783
-#define wxGraphicsContext_DrawText_3 784
-#define wxGraphicsContext_DrawText_4_0 785
-#define wxGraphicsContext_DrawText_4_1 786
-#define wxGraphicsContext_DrawText_5 787
-#define wxGraphicsContext_FillPath 788
-#define wxGraphicsContext_StrokePath 789
-#define wxGraphicsContext_GetPartialTextExtents 790
-#define wxGraphicsContext_GetTextExtent 791
-#define wxGraphicsContext_Rotate 792
-#define wxGraphicsContext_Scale 793
-#define wxGraphicsContext_Translate 794
-#define wxGraphicsContext_GetTransform 795
-#define wxGraphicsContext_SetTransform 796
-#define wxGraphicsContext_ConcatTransform 797
-#define wxGraphicsContext_SetBrush_1_1 798
-#define wxGraphicsContext_SetBrush_1_0 799
-#define wxGraphicsContext_SetFont_1 800
-#define wxGraphicsContext_SetFont_2 801
-#define wxGraphicsContext_SetPen_1_0 802
-#define wxGraphicsContext_SetPen_1_1 803
-#define wxGraphicsContext_StrokeLine 804
-#define wxGraphicsContext_StrokeLines 805
-#define wxGraphicsMatrix_Concat 807
-#define wxGraphicsMatrix_Get 809
-#define wxGraphicsMatrix_Invert 810
-#define wxGraphicsMatrix_IsEqual 811
-#define wxGraphicsMatrix_IsIdentity 813
-#define wxGraphicsMatrix_Rotate 814
-#define wxGraphicsMatrix_Scale 815
-#define wxGraphicsMatrix_Translate 816
-#define wxGraphicsMatrix_Set 817
-#define wxGraphicsMatrix_TransformPoint 818
-#define wxGraphicsMatrix_TransformDistance 819
-#define wxGraphicsPath_MoveToPoint_2 820
-#define wxGraphicsPath_MoveToPoint_1 821
-#define wxGraphicsPath_AddArc_6 822
-#define wxGraphicsPath_AddArc_5 823
-#define wxGraphicsPath_AddArcToPoint 824
-#define wxGraphicsPath_AddCircle 825
-#define wxGraphicsPath_AddCurveToPoint_6 826
-#define wxGraphicsPath_AddCurveToPoint_3 827
-#define wxGraphicsPath_AddEllipse 828
-#define wxGraphicsPath_AddLineToPoint_2 829
-#define wxGraphicsPath_AddLineToPoint_1 830
-#define wxGraphicsPath_AddPath 831
-#define wxGraphicsPath_AddQuadCurveToPoint 832
-#define wxGraphicsPath_AddRectangle 833
-#define wxGraphicsPath_AddRoundedRectangle 834
-#define wxGraphicsPath_CloseSubpath 835
-#define wxGraphicsPath_Contains_3 836
-#define wxGraphicsPath_Contains_2 837
-#define wxGraphicsPath_GetBox 839
-#define wxGraphicsPath_GetCurrentPoint 841
-#define wxGraphicsPath_Transform 842
-#define wxGraphicsRenderer_GetDefaultRenderer 843
-#define wxGraphicsRenderer_CreateContext_1_1 844
-#define wxGraphicsRenderer_CreateContext_1_0 845
-#define wxGraphicsRenderer_CreatePen 846
-#define wxGraphicsRenderer_CreateBrush 847
-#define wxGraphicsRenderer_CreateLinearGradientBrush 848
-#define wxGraphicsRenderer_CreateRadialGradientBrush 849
-#define wxGraphicsRenderer_CreateFont 850
-#define wxGraphicsRenderer_CreateMatrix 851
-#define wxGraphicsRenderer_CreatePath 852
-#define wxMenuBar_new_1 854
-#define wxMenuBar_new_0 856
-#define wxMenuBar_destruct 858
-#define wxMenuBar_Append 859
-#define wxMenuBar_Check 860
-#define wxMenuBar_Enable_2 861
-#define wxMenuBar_Enable_1 862
-#define wxMenuBar_EnableTop 863
-#define wxMenuBar_FindMenu 864
-#define wxMenuBar_FindMenuItem 865
-#define wxMenuBar_FindItem 866
-#define wxMenuBar_GetHelpString 867
-#define wxMenuBar_GetLabel_1 868
-#define wxMenuBar_GetLabel_0 869
-#define wxMenuBar_GetLabelTop 870
-#define wxMenuBar_GetMenu 871
-#define wxMenuBar_GetMenuCount 872
-#define wxMenuBar_Insert 873
-#define wxMenuBar_IsChecked 874
-#define wxMenuBar_IsEnabled_1 875
-#define wxMenuBar_IsEnabled_0 876
-#define wxMenuBar_Remove 877
-#define wxMenuBar_Replace 878
-#define wxMenuBar_SetHelpString 879
-#define wxMenuBar_SetLabel_2 880
-#define wxMenuBar_SetLabel_1 881
-#define wxMenuBar_SetLabelTop 882
-#define wxControl_GetLabel 883
-#define wxControl_SetLabel 884
-#define wxControlWithItems_Append_1 885
-#define wxControlWithItems_Append_2 886
-#define wxControlWithItems_appendStrings_1 887
-#define wxControlWithItems_Clear 888
-#define wxControlWithItems_Delete 889
-#define wxControlWithItems_FindString 890
-#define wxControlWithItems_getClientData 891
-#define wxControlWithItems_setClientData 892
-#define wxControlWithItems_GetCount 893
-#define wxControlWithItems_GetSelection 894
-#define wxControlWithItems_GetString 895
-#define wxControlWithItems_GetStringSelection 896
-#define wxControlWithItems_Insert_2 897
-#define wxControlWithItems_Insert_3 898
-#define wxControlWithItems_IsEmpty 899
-#define wxControlWithItems_Select 900
-#define wxControlWithItems_SetSelection 901
-#define wxControlWithItems_SetString 902
-#define wxControlWithItems_SetStringSelection 903
-#define wxMenu_new_2 906
-#define wxMenu_new_1 907
-#define wxMenu_destruct 909
-#define wxMenu_Append_3 910
-#define wxMenu_Append_1 911
-#define wxMenu_Append_4_0 912
-#define wxMenu_Append_4_1 913
-#define wxMenu_AppendCheckItem 914
-#define wxMenu_AppendRadioItem 915
-#define wxMenu_AppendSeparator 916
-#define wxMenu_Break 917
-#define wxMenu_Check 918
-#define wxMenu_Delete_1_0 919
-#define wxMenu_Delete_1_1 920
-#define wxMenu_Destroy_1_0 921
-#define wxMenu_Destroy_1_1 922
-#define wxMenu_Enable 923
-#define wxMenu_FindItem_1 924
-#define wxMenu_FindItem_2 925
-#define wxMenu_FindItemByPosition 926
-#define wxMenu_GetHelpString 927
-#define wxMenu_GetLabel 928
-#define wxMenu_GetMenuItemCount 929
-#define wxMenu_GetMenuItems 930
-#define wxMenu_GetTitle 932
-#define wxMenu_Insert_2 933
-#define wxMenu_Insert_3 934
-#define wxMenu_Insert_5_1 935
-#define wxMenu_Insert_5_0 936
-#define wxMenu_InsertCheckItem 937
-#define wxMenu_InsertRadioItem 938
-#define wxMenu_InsertSeparator 939
-#define wxMenu_IsChecked 940
-#define wxMenu_IsEnabled 941
-#define wxMenu_Prepend_1 942
-#define wxMenu_Prepend_2 943
-#define wxMenu_Prepend_4_1 944
-#define wxMenu_Prepend_4_0 945
-#define wxMenu_PrependCheckItem 946
-#define wxMenu_PrependRadioItem 947
-#define wxMenu_PrependSeparator 948
-#define wxMenu_Remove_1_0 949
-#define wxMenu_Remove_1_1 950
-#define wxMenu_SetHelpString 951
-#define wxMenu_SetLabel 952
-#define wxMenu_SetTitle 953
-#define wxMenuItem_new 954
-#define wxMenuItem_destruct 956
-#define wxMenuItem_Check 957
-#define wxMenuItem_Enable 958
-#define wxMenuItem_GetBitmap 959
-#define wxMenuItem_GetHelp 960
-#define wxMenuItem_GetId 961
-#define wxMenuItem_GetKind 962
-#define wxMenuItem_GetLabel 963
-#define wxMenuItem_GetLabelFromText 964
-#define wxMenuItem_GetMenu 965
-#define wxMenuItem_GetText 966
-#define wxMenuItem_GetSubMenu 967
-#define wxMenuItem_IsCheckable 968
-#define wxMenuItem_IsChecked 969
-#define wxMenuItem_IsEnabled 970
-#define wxMenuItem_IsSeparator 971
-#define wxMenuItem_IsSubMenu 972
-#define wxMenuItem_SetBitmap 973
-#define wxMenuItem_SetHelp 974
-#define wxMenuItem_SetMenu 975
-#define wxMenuItem_SetSubMenu 976
-#define wxMenuItem_SetText 977
-#define wxToolBar_AddControl 978
-#define wxToolBar_AddSeparator 979
-#define wxToolBar_AddTool_5 980
-#define wxToolBar_AddTool_4_0 981
-#define wxToolBar_AddTool_1 982
-#define wxToolBar_AddTool_4_1 983
-#define wxToolBar_AddTool_3 984
-#define wxToolBar_AddTool_6 985
-#define wxToolBar_AddCheckTool 986
-#define wxToolBar_AddRadioTool 987
-#define wxToolBar_AddStretchableSpace 988
-#define wxToolBar_InsertStretchableSpace 989
-#define wxToolBar_DeleteTool 990
-#define wxToolBar_DeleteToolByPos 991
-#define wxToolBar_EnableTool 992
-#define wxToolBar_FindById 993
-#define wxToolBar_FindControl 994
-#define wxToolBar_FindToolForPosition 995
-#define wxToolBar_GetToolSize 996
-#define wxToolBar_GetToolBitmapSize 997
-#define wxToolBar_GetMargins 998
-#define wxToolBar_GetToolEnabled 999
-#define wxToolBar_GetToolLongHelp 1000
-#define wxToolBar_GetToolPacking 1001
-#define wxToolBar_GetToolPos 1002
-#define wxToolBar_GetToolSeparation 1003
-#define wxToolBar_GetToolShortHelp 1004
-#define wxToolBar_GetToolState 1005
-#define wxToolBar_InsertControl 1006
-#define wxToolBar_InsertSeparator 1007
-#define wxToolBar_InsertTool_5 1008
-#define wxToolBar_InsertTool_2 1009
-#define wxToolBar_InsertTool_4 1010
-#define wxToolBar_Realize 1011
-#define wxToolBar_RemoveTool 1012
-#define wxToolBar_SetMargins 1013
-#define wxToolBar_SetToolBitmapSize 1014
-#define wxToolBar_SetToolLongHelp 1015
-#define wxToolBar_SetToolPacking 1016
-#define wxToolBar_SetToolShortHelp 1017
-#define wxToolBar_SetToolSeparation 1018
-#define wxToolBar_ToggleTool 1019
-#define wxStatusBar_new_0 1021
-#define wxStatusBar_new_2 1022
-#define wxStatusBar_destruct 1024
-#define wxStatusBar_Create 1025
-#define wxStatusBar_GetFieldRect 1026
-#define wxStatusBar_GetFieldsCount 1027
-#define wxStatusBar_GetStatusText 1028
-#define wxStatusBar_PopStatusText 1029
-#define wxStatusBar_PushStatusText 1030
-#define wxStatusBar_SetFieldsCount 1031
-#define wxStatusBar_SetMinHeight 1032
-#define wxStatusBar_SetStatusText 1033
-#define wxStatusBar_SetStatusWidths 1034
-#define wxStatusBar_SetStatusStyles 1035
-#define wxBitmap_new_0 1036
-#define wxBitmap_new_3 1037
-#define wxBitmap_new_4 1038
-#define wxBitmap_new_2_0 1039
-#define wxBitmap_new_2_1 1040
-#define wxBitmap_destruct 1041
-#define wxBitmap_ConvertToImage 1042
-#define wxBitmap_CopyFromIcon 1043
-#define wxBitmap_Create 1044
-#define wxBitmap_GetDepth 1045
-#define wxBitmap_GetHeight 1046
-#define wxBitmap_GetPalette 1047
-#define wxBitmap_GetMask 1048
-#define wxBitmap_GetWidth 1049
-#define wxBitmap_GetSubBitmap 1050
-#define wxBitmap_LoadFile 1051
-#define wxBitmap_Ok 1052
-#define wxBitmap_SaveFile 1053
-#define wxBitmap_SetDepth 1054
-#define wxBitmap_SetHeight 1055
-#define wxBitmap_SetMask 1056
-#define wxBitmap_SetPalette 1057
-#define wxBitmap_SetWidth 1058
-#define wxIcon_new_0 1059
-#define wxIcon_new_2 1060
-#define wxIcon_new_1 1061
-#define wxIcon_CopyFromBitmap 1062
-#define wxIcon_destroy 1063
-#define wxIconBundle_new_0 1064
-#define wxIconBundle_new_2 1065
-#define wxIconBundle_new_1_0 1066
-#define wxIconBundle_new_1_1 1067
-#define wxIconBundle_destruct 1068
-#define wxIconBundle_AddIcon_2 1069
-#define wxIconBundle_AddIcon_1 1070
-#define wxIconBundle_GetIcon_1_1 1071
-#define wxIconBundle_GetIcon_1_0 1072
-#define wxCursor_new_0 1073
-#define wxCursor_new_1_0 1074
-#define wxCursor_new_1_1 1075
-#define wxCursor_new_4 1076
-#define wxCursor_destruct 1077
-#define wxCursor_Ok 1078
-#define wxMask_new_0 1079
-#define wxMask_new_2_1 1080
-#define wxMask_new_2_0 1081
-#define wxMask_new_1 1082
-#define wxMask_destruct 1083
-#define wxMask_Create_2_1 1084
-#define wxMask_Create_2_0 1085
-#define wxMask_Create_1 1086
-#define wxImage_new_0 1087
-#define wxImage_new_3_0 1088
-#define wxImage_new_4 1089
-#define wxImage_new_5 1090
-#define wxImage_new_2 1091
-#define wxImage_new_3_1 1092
-#define wxImage_Blur 1093
-#define wxImage_BlurHorizontal 1094
-#define wxImage_BlurVertical 1095
-#define wxImage_ConvertAlphaToMask 1096
-#define wxImage_ConvertToGreyscale 1097
-#define wxImage_ConvertToMono 1098
-#define wxImage_Copy 1099
-#define wxImage_Create_3 1100
-#define wxImage_Create_4 1101
-#define wxImage_Create_5 1102
-#define wxImage_Destroy 1103
-#define wxImage_FindFirstUnusedColour 1104
-#define wxImage_GetImageExtWildcard 1105
-#define wxImage_GetAlpha_2 1106
-#define wxImage_GetAlpha_0 1107
-#define wxImage_GetBlue 1108
-#define wxImage_GetData 1109
-#define wxImage_GetGreen 1110
-#define wxImage_GetImageCount 1111
-#define wxImage_GetHeight 1112
-#define wxImage_GetMaskBlue 1113
-#define wxImage_GetMaskGreen 1114
-#define wxImage_GetMaskRed 1115
-#define wxImage_GetOrFindMaskColour 1116
-#define wxImage_GetPalette 1117
-#define wxImage_GetRed 1118
-#define wxImage_GetSubImage 1119
-#define wxImage_GetWidth 1120
-#define wxImage_HasAlpha 1121
-#define wxImage_HasMask 1122
-#define wxImage_GetOption 1123
-#define wxImage_GetOptionInt 1124
-#define wxImage_HasOption 1125
-#define wxImage_InitAlpha 1126
-#define wxImage_InitStandardHandlers 1127
-#define wxImage_IsTransparent 1128
-#define wxImage_LoadFile_2 1129
-#define wxImage_LoadFile_3 1130
-#define wxImage_Ok 1131
-#define wxImage_RemoveHandler 1132
-#define wxImage_Mirror 1133
-#define wxImage_Replace 1134
-#define wxImage_Rescale 1135
-#define wxImage_Resize 1136
-#define wxImage_Rotate 1137
-#define wxImage_RotateHue 1138
-#define wxImage_Rotate90 1139
-#define wxImage_SaveFile_1 1140
-#define wxImage_SaveFile_2_0 1141
-#define wxImage_SaveFile_2_1 1142
-#define wxImage_Scale 1143
-#define wxImage_Size 1144
-#define wxImage_SetAlpha_3 1145
-#define wxImage_SetAlpha_2 1146
-#define wxImage_SetData_2 1147
-#define wxImage_SetData_4 1148
-#define wxImage_SetMask 1149
-#define wxImage_SetMaskColour 1150
-#define wxImage_SetMaskFromImage 1151
-#define wxImage_SetOption_2_1 1152
-#define wxImage_SetOption_2_0 1153
-#define wxImage_SetPalette 1154
-#define wxImage_SetRGB_5 1155
-#define wxImage_SetRGB_4 1156
-#define wxImage_destroy 1157
-#define wxBrush_new_0 1158
-#define wxBrush_new_2 1159
-#define wxBrush_new_1 1160
-#define wxBrush_destruct 1162
-#define wxBrush_GetColour 1163
-#define wxBrush_GetStipple 1164
-#define wxBrush_GetStyle 1165
-#define wxBrush_IsHatch 1166
-#define wxBrush_IsOk 1167
-#define wxBrush_SetColour_1 1168
-#define wxBrush_SetColour_3 1169
-#define wxBrush_SetStipple 1170
-#define wxBrush_SetStyle 1171
-#define wxPen_new_0 1172
-#define wxPen_new_2 1173
-#define wxPen_destruct 1174
-#define wxPen_GetCap 1175
-#define wxPen_GetColour 1176
-#define wxPen_GetJoin 1177
-#define wxPen_GetStyle 1178
-#define wxPen_GetWidth 1179
-#define wxPen_IsOk 1180
-#define wxPen_SetCap 1181
-#define wxPen_SetColour_1 1182
-#define wxPen_SetColour_3 1183
-#define wxPen_SetJoin 1184
-#define wxPen_SetStyle 1185
-#define wxPen_SetWidth 1186
-#define wxRegion_new_0 1187
-#define wxRegion_new_4 1188
-#define wxRegion_new_2 1189
-#define wxRegion_new_1_1 1190
-#define wxRegion_new_1_0 1192
-#define wxRegion_destruct 1194
-#define wxRegion_Clear 1195
-#define wxRegion_Contains_2 1196
-#define wxRegion_Contains_1_0 1197
-#define wxRegion_Contains_4 1198
-#define wxRegion_Contains_1_1 1199
-#define wxRegion_ConvertToBitmap 1200
-#define wxRegion_GetBox 1201
-#define wxRegion_Intersect_4 1202
-#define wxRegion_Intersect_1_1 1203
-#define wxRegion_Intersect_1_0 1204
-#define wxRegion_IsEmpty 1205
-#define wxRegion_Subtract_4 1206
-#define wxRegion_Subtract_1_1 1207
-#define wxRegion_Subtract_1_0 1208
-#define wxRegion_Offset_2 1209
-#define wxRegion_Offset_1 1210
-#define wxRegion_Union_4 1211
-#define wxRegion_Union_1_2 1212
-#define wxRegion_Union_1_1 1213
-#define wxRegion_Union_1_0 1214
-#define wxRegion_Union_3 1215
-#define wxRegion_Xor_4 1216
-#define wxRegion_Xor_1_1 1217
-#define wxRegion_Xor_1_0 1218
-#define wxAcceleratorTable_new_0 1219
-#define wxAcceleratorTable_new_2 1220
-#define wxAcceleratorTable_destruct 1221
-#define wxAcceleratorTable_Ok 1222
-#define wxAcceleratorEntry_new_1_0 1223
-#define wxAcceleratorEntry_new_1_1 1224
-#define wxAcceleratorEntry_GetCommand 1225
-#define wxAcceleratorEntry_GetFlags 1226
-#define wxAcceleratorEntry_GetKeyCode 1227
-#define wxAcceleratorEntry_Set 1228
-#define wxAcceleratorEntry_destroy 1229
-#define wxCaret_new_3 1234
-#define wxCaret_new_2 1235
-#define wxCaret_destruct 1237
-#define wxCaret_Create_3 1238
-#define wxCaret_Create_2 1239
-#define wxCaret_GetBlinkTime 1240
-#define wxCaret_GetPosition 1242
-#define wxCaret_GetSize 1244
-#define wxCaret_GetWindow 1245
-#define wxCaret_Hide 1246
-#define wxCaret_IsOk 1247
-#define wxCaret_IsVisible 1248
-#define wxCaret_Move_2 1249
-#define wxCaret_Move_1 1250
-#define wxCaret_SetBlinkTime 1251
-#define wxCaret_SetSize_2 1252
-#define wxCaret_SetSize_1 1253
-#define wxCaret_Show 1254
-#define wxSizer_Add_2_1 1255
-#define wxSizer_Add_2_0 1256
-#define wxSizer_Add_3 1257
-#define wxSizer_Add_2_3 1258
-#define wxSizer_Add_2_2 1259
-#define wxSizer_AddSpacer 1260
-#define wxSizer_AddStretchSpacer 1261
-#define wxSizer_CalcMin 1262
-#define wxSizer_Clear 1263
-#define wxSizer_Detach_1_2 1264
-#define wxSizer_Detach_1_1 1265
-#define wxSizer_Detach_1_0 1266
-#define wxSizer_Fit 1267
-#define wxSizer_FitInside 1268
-#define wxSizer_GetChildren 1269
-#define wxSizer_GetItem_2_1 1270
-#define wxSizer_GetItem_2_0 1271
-#define wxSizer_GetItem_1 1272
-#define wxSizer_GetSize 1273
-#define wxSizer_GetPosition 1274
-#define wxSizer_GetMinSize 1275
-#define wxSizer_Hide_2_0 1276
-#define wxSizer_Hide_2_1 1277
-#define wxSizer_Hide_1 1278
-#define wxSizer_Insert_3_1 1279
-#define wxSizer_Insert_3_0 1280
-#define wxSizer_Insert_4 1281
-#define wxSizer_Insert_3_3 1282
-#define wxSizer_Insert_3_2 1283
-#define wxSizer_Insert_2 1284
-#define wxSizer_InsertSpacer 1285
-#define wxSizer_InsertStretchSpacer 1286
-#define wxSizer_IsShown_1_2 1287
-#define wxSizer_IsShown_1_1 1288
-#define wxSizer_IsShown_1_0 1289
-#define wxSizer_Layout 1290
-#define wxSizer_Prepend_2_1 1291
-#define wxSizer_Prepend_2_0 1292
-#define wxSizer_Prepend_3 1293
-#define wxSizer_Prepend_2_3 1294
-#define wxSizer_Prepend_2_2 1295
-#define wxSizer_Prepend_1 1296
-#define wxSizer_PrependSpacer 1297
-#define wxSizer_PrependStretchSpacer 1298
-#define wxSizer_RecalcSizes 1299
-#define wxSizer_Remove_1_1 1300
-#define wxSizer_Remove_1_0 1301
-#define wxSizer_Replace_3_1 1302
-#define wxSizer_Replace_3_0 1303
-#define wxSizer_Replace_2 1304
-#define wxSizer_SetDimension 1305
-#define wxSizer_SetMinSize_2 1306
-#define wxSizer_SetMinSize_1 1307
-#define wxSizer_SetItemMinSize_3_2 1308
-#define wxSizer_SetItemMinSize_2_2 1309
-#define wxSizer_SetItemMinSize_3_1 1310
-#define wxSizer_SetItemMinSize_2_1 1311
-#define wxSizer_SetItemMinSize_3_0 1312
-#define wxSizer_SetItemMinSize_2_0 1313
-#define wxSizer_SetSizeHints 1314
-#define wxSizer_SetVirtualSizeHints 1315
-#define wxSizer_Show_2_2 1316
-#define wxSizer_Show_2_1 1317
-#define wxSizer_Show_2_0 1318
-#define wxSizer_Show_1 1319
-#define wxSizerFlags_new 1320
-#define wxSizerFlags_Align 1321
-#define wxSizerFlags_Border_2 1322
-#define wxSizerFlags_Border_1 1323
-#define wxSizerFlags_Center 1324
-#define wxSizerFlags_Centre 1325
-#define wxSizerFlags_Expand 1326
-#define wxSizerFlags_Left 1327
-#define wxSizerFlags_Proportion 1328
-#define wxSizerFlags_Right 1329
-#define wxSizerFlags_destroy 1330
-#define wxSizerItem_new_5_1 1331
-#define wxSizerItem_new_2_1 1332
-#define wxSizerItem_new_5_0 1333
-#define wxSizerItem_new_2_0 1334
-#define wxSizerItem_new_6 1335
-#define wxSizerItem_new_3 1336
-#define wxSizerItem_new_0 1337
-#define wxSizerItem_destruct 1338
-#define wxSizerItem_CalcMin 1339
-#define wxSizerItem_DeleteWindows 1340
-#define wxSizerItem_DetachSizer 1341
-#define wxSizerItem_GetBorder 1342
-#define wxSizerItem_GetFlag 1343
-#define wxSizerItem_GetMinSize 1344
-#define wxSizerItem_GetPosition 1345
-#define wxSizerItem_GetProportion 1346
-#define wxSizerItem_GetRatio 1347
-#define wxSizerItem_GetRect 1348
-#define wxSizerItem_GetSize 1349
-#define wxSizerItem_GetSizer 1350
-#define wxSizerItem_GetSpacer 1351
-#define wxSizerItem_GetUserData 1352
-#define wxSizerItem_GetWindow 1353
-#define wxSizerItem_IsSizer 1354
-#define wxSizerItem_IsShown 1355
-#define wxSizerItem_IsSpacer 1356
-#define wxSizerItem_IsWindow 1357
-#define wxSizerItem_SetBorder 1358
-#define wxSizerItem_SetDimension 1359
-#define wxSizerItem_SetFlag 1360
-#define wxSizerItem_SetInitSize 1361
-#define wxSizerItem_SetMinSize_1 1362
-#define wxSizerItem_SetMinSize_2 1363
-#define wxSizerItem_SetProportion 1364
-#define wxSizerItem_SetRatio_2 1365
-#define wxSizerItem_SetRatio_1_1 1366
-#define wxSizerItem_SetRatio_1_0 1367
-#define wxSizerItem_SetSizer 1368
-#define wxSizerItem_SetSpacer_1 1369
-#define wxSizerItem_SetSpacer_2 1370
-#define wxSizerItem_SetWindow 1371
-#define wxSizerItem_Show 1372
-#define wxBoxSizer_new 1373
-#define wxBoxSizer_GetOrientation 1374
-#define wxBoxSizer_destroy 1375
-#define wxStaticBoxSizer_new_2 1376
-#define wxStaticBoxSizer_new_3 1377
-#define wxStaticBoxSizer_GetStaticBox 1378
-#define wxStaticBoxSizer_destroy 1379
-#define wxGridSizer_new_4 1380
-#define wxGridSizer_new_2 1381
-#define wxGridSizer_GetCols 1382
-#define wxGridSizer_GetHGap 1383
-#define wxGridSizer_GetRows 1384
-#define wxGridSizer_GetVGap 1385
-#define wxGridSizer_SetCols 1386
-#define wxGridSizer_SetHGap 1387
-#define wxGridSizer_SetRows 1388
-#define wxGridSizer_SetVGap 1389
-#define wxGridSizer_destroy 1390
-#define wxFlexGridSizer_new_4 1391
-#define wxFlexGridSizer_new_2 1392
-#define wxFlexGridSizer_AddGrowableCol 1393
-#define wxFlexGridSizer_AddGrowableRow 1394
-#define wxFlexGridSizer_GetFlexibleDirection 1395
-#define wxFlexGridSizer_GetNonFlexibleGrowMode 1396
-#define wxFlexGridSizer_RemoveGrowableCol 1397
-#define wxFlexGridSizer_RemoveGrowableRow 1398
-#define wxFlexGridSizer_SetFlexibleDirection 1399
-#define wxFlexGridSizer_SetNonFlexibleGrowMode 1400
-#define wxFlexGridSizer_destroy 1401
-#define wxGridBagSizer_new 1402
-#define wxGridBagSizer_Add_3_2 1403
-#define wxGridBagSizer_Add_3_1 1404
-#define wxGridBagSizer_Add_4 1405
-#define wxGridBagSizer_Add_1_0 1406
-#define wxGridBagSizer_Add_2_1 1407
-#define wxGridBagSizer_Add_2_0 1408
-#define wxGridBagSizer_Add_3_0 1409
-#define wxGridBagSizer_Add_1_1 1410
-#define wxGridBagSizer_CalcMin 1411
-#define wxGridBagSizer_CheckForIntersection_2 1412
-#define wxGridBagSizer_CheckForIntersection_3 1413
-#define wxGridBagSizer_FindItem_1_1 1414
-#define wxGridBagSizer_FindItem_1_0 1415
-#define wxGridBagSizer_FindItemAtPoint 1416
-#define wxGridBagSizer_FindItemAtPosition 1417
-#define wxGridBagSizer_FindItemWithData 1418
-#define wxGridBagSizer_GetCellSize 1419
-#define wxGridBagSizer_GetEmptyCellSize 1420
-#define wxGridBagSizer_GetItemPosition_1_2 1421
-#define wxGridBagSizer_GetItemPosition_1_1 1422
-#define wxGridBagSizer_GetItemPosition_1_0 1423
-#define wxGridBagSizer_GetItemSpan_1_2 1424
-#define wxGridBagSizer_GetItemSpan_1_1 1425
-#define wxGridBagSizer_GetItemSpan_1_0 1426
-#define wxGridBagSizer_SetEmptyCellSize 1427
-#define wxGridBagSizer_SetItemPosition_2_2 1428
-#define wxGridBagSizer_SetItemPosition_2_1 1429
-#define wxGridBagSizer_SetItemPosition_2_0 1430
-#define wxGridBagSizer_SetItemSpan_2_2 1431
-#define wxGridBagSizer_SetItemSpan_2_1 1432
-#define wxGridBagSizer_SetItemSpan_2_0 1433
-#define wxGridBagSizer_destroy 1434
-#define wxStdDialogButtonSizer_new 1435
-#define wxStdDialogButtonSizer_AddButton 1436
-#define wxStdDialogButtonSizer_Realize 1437
-#define wxStdDialogButtonSizer_SetAffirmativeButton 1438
-#define wxStdDialogButtonSizer_SetCancelButton 1439
-#define wxStdDialogButtonSizer_SetNegativeButton 1440
-#define wxStdDialogButtonSizer_destroy 1441
-#define wxFont_new_0 1442
-#define wxFont_new_1 1443
-#define wxFont_new_5 1444
-#define wxFont_destruct 1446
-#define wxFont_IsFixedWidth 1447
-#define wxFont_GetDefaultEncoding 1448
-#define wxFont_GetFaceName 1449
-#define wxFont_GetFamily 1450
-#define wxFont_GetNativeFontInfoDesc 1451
-#define wxFont_GetNativeFontInfoUserDesc 1452
-#define wxFont_GetPointSize 1453
-#define wxFont_GetStyle 1454
-#define wxFont_GetUnderlined 1455
-#define wxFont_GetWeight 1456
-#define wxFont_Ok 1457
-#define wxFont_SetDefaultEncoding 1458
-#define wxFont_SetFaceName 1459
-#define wxFont_SetFamily 1460
-#define wxFont_SetPointSize 1461
-#define wxFont_SetStyle 1462
-#define wxFont_SetUnderlined 1463
-#define wxFont_SetWeight 1464
-#define wxToolTip_Enable 1465
-#define wxToolTip_SetDelay 1466
-#define wxToolTip_new 1467
-#define wxToolTip_SetTip 1468
-#define wxToolTip_GetTip 1469
-#define wxToolTip_GetWindow 1470
-#define wxToolTip_destroy 1471
-#define wxButton_new_3 1473
-#define wxButton_new_0 1474
-#define wxButton_destruct 1475
-#define wxButton_Create 1476
-#define wxButton_GetDefaultSize 1477
-#define wxButton_SetDefault 1478
-#define wxButton_SetLabel 1479
-#define wxBitmapButton_new_4 1481
-#define wxBitmapButton_new_0 1482
-#define wxBitmapButton_Create 1483
-#define wxBitmapButton_GetBitmapDisabled 1484
-#define wxBitmapButton_GetBitmapFocus 1486
-#define wxBitmapButton_GetBitmapLabel 1488
-#define wxBitmapButton_GetBitmapSelected 1490
-#define wxBitmapButton_SetBitmapDisabled 1492
-#define wxBitmapButton_SetBitmapFocus 1493
-#define wxBitmapButton_SetBitmapLabel 1494
-#define wxBitmapButton_SetBitmapSelected 1495
-#define wxBitmapButton_destroy 1496
-#define wxToggleButton_new_0 1497
-#define wxToggleButton_new_4 1498
-#define wxToggleButton_Create 1499
-#define wxToggleButton_GetValue 1500
-#define wxToggleButton_SetValue 1501
-#define wxToggleButton_destroy 1502
-#define wxCalendarCtrl_new_0 1503
-#define wxCalendarCtrl_new_3 1504
-#define wxCalendarCtrl_Create 1505
-#define wxCalendarCtrl_destruct 1506
-#define wxCalendarCtrl_SetDate 1507
-#define wxCalendarCtrl_GetDate 1508
-#define wxCalendarCtrl_EnableYearChange 1509
-#define wxCalendarCtrl_EnableMonthChange 1510
-#define wxCalendarCtrl_EnableHolidayDisplay 1511
-#define wxCalendarCtrl_SetHeaderColours 1512
-#define wxCalendarCtrl_GetHeaderColourFg 1513
-#define wxCalendarCtrl_GetHeaderColourBg 1514
-#define wxCalendarCtrl_SetHighlightColours 1515
-#define wxCalendarCtrl_GetHighlightColourFg 1516
-#define wxCalendarCtrl_GetHighlightColourBg 1517
-#define wxCalendarCtrl_SetHolidayColours 1518
-#define wxCalendarCtrl_GetHolidayColourFg 1519
-#define wxCalendarCtrl_GetHolidayColourBg 1520
-#define wxCalendarCtrl_GetAttr 1521
-#define wxCalendarCtrl_SetAttr 1522
-#define wxCalendarCtrl_SetHoliday 1523
-#define wxCalendarCtrl_ResetAttr 1524
-#define wxCalendarCtrl_HitTest 1525
-#define wxCalendarDateAttr_new_0 1526
-#define wxCalendarDateAttr_new_2_1 1527
-#define wxCalendarDateAttr_new_2_0 1528
-#define wxCalendarDateAttr_SetTextColour 1529
-#define wxCalendarDateAttr_SetBackgroundColour 1530
-#define wxCalendarDateAttr_SetBorderColour 1531
-#define wxCalendarDateAttr_SetFont 1532
-#define wxCalendarDateAttr_SetBorder 1533
-#define wxCalendarDateAttr_SetHoliday 1534
-#define wxCalendarDateAttr_HasTextColour 1535
-#define wxCalendarDateAttr_HasBackgroundColour 1536
-#define wxCalendarDateAttr_HasBorderColour 1537
-#define wxCalendarDateAttr_HasFont 1538
-#define wxCalendarDateAttr_HasBorder 1539
-#define wxCalendarDateAttr_IsHoliday 1540
-#define wxCalendarDateAttr_GetTextColour 1541
-#define wxCalendarDateAttr_GetBackgroundColour 1542
-#define wxCalendarDateAttr_GetBorderColour 1543
-#define wxCalendarDateAttr_GetFont 1544
-#define wxCalendarDateAttr_GetBorder 1545
-#define wxCalendarDateAttr_destroy 1546
-#define wxCheckBox_new_4 1548
-#define wxCheckBox_new_0 1549
-#define wxCheckBox_Create 1550
-#define wxCheckBox_GetValue 1551
-#define wxCheckBox_Get3StateValue 1552
-#define wxCheckBox_Is3rdStateAllowedForUser 1553
-#define wxCheckBox_Is3State 1554
-#define wxCheckBox_IsChecked 1555
-#define wxCheckBox_SetValue 1556
-#define wxCheckBox_Set3StateValue 1557
-#define wxCheckBox_destroy 1558
-#define wxCheckListBox_new_0 1559
-#define wxCheckListBox_new_3 1561
-#define wxCheckListBox_Check 1562
-#define wxCheckListBox_IsChecked 1563
-#define wxCheckListBox_destroy 1564
-#define wxChoice_new_3 1567
-#define wxChoice_new_0 1568
-#define wxChoice_destruct 1570
-#define wxChoice_Create 1572
-#define wxChoice_Delete 1573
-#define wxChoice_GetColumns 1574
-#define wxChoice_SetColumns 1575
-#define wxComboBox_new_0 1576
-#define wxComboBox_new_3 1578
-#define wxComboBox_destruct 1579
-#define wxComboBox_Create 1581
-#define wxComboBox_CanCopy 1582
-#define wxComboBox_CanCut 1583
-#define wxComboBox_CanPaste 1584
-#define wxComboBox_CanRedo 1585
-#define wxComboBox_CanUndo 1586
-#define wxComboBox_Copy 1587
-#define wxComboBox_Cut 1588
-#define wxComboBox_GetInsertionPoint 1589
-#define wxComboBox_GetLastPosition 1590
-#define wxComboBox_GetValue 1591
-#define wxComboBox_Paste 1592
-#define wxComboBox_Redo 1593
-#define wxComboBox_Replace 1594
-#define wxComboBox_Remove 1595
-#define wxComboBox_SetInsertionPoint 1596
-#define wxComboBox_SetInsertionPointEnd 1597
-#define wxComboBox_SetSelection_1 1598
-#define wxComboBox_SetSelection_2 1599
-#define wxComboBox_SetValue 1600
-#define wxComboBox_Undo 1601
-#define wxGauge_new_0 1602
-#define wxGauge_new_4 1603
-#define wxGauge_Create 1604
-#define wxGauge_GetRange 1605
-#define wxGauge_GetValue 1606
-#define wxGauge_IsVertical 1607
-#define wxGauge_SetRange 1608
-#define wxGauge_SetValue 1609
-#define wxGauge_Pulse 1610
-#define wxGauge_destroy 1611
-#define wxGenericDirCtrl_new_0 1612
-#define wxGenericDirCtrl_new_2 1613
-#define wxGenericDirCtrl_destruct 1614
-#define wxGenericDirCtrl_Create 1615
-#define wxGenericDirCtrl_Init 1616
-#define wxGenericDirCtrl_CollapseTree 1617
-#define wxGenericDirCtrl_ExpandPath 1618
-#define wxGenericDirCtrl_GetDefaultPath 1619
-#define wxGenericDirCtrl_GetPath 1620
-#define wxGenericDirCtrl_GetFilePath 1621
-#define wxGenericDirCtrl_GetFilter 1622
-#define wxGenericDirCtrl_GetFilterIndex 1623
-#define wxGenericDirCtrl_GetRootId 1624
-#define wxGenericDirCtrl_GetTreeCtrl 1625
-#define wxGenericDirCtrl_ReCreateTree 1626
-#define wxGenericDirCtrl_SetDefaultPath 1627
-#define wxGenericDirCtrl_SetFilter 1628
-#define wxGenericDirCtrl_SetFilterIndex 1629
-#define wxGenericDirCtrl_SetPath 1630
-#define wxStaticBox_new_4 1632
-#define wxStaticBox_new_0 1633
-#define wxStaticBox_Create 1634
-#define wxStaticBox_destroy 1635
-#define wxStaticLine_new_2 1637
-#define wxStaticLine_new_0 1638
-#define wxStaticLine_Create 1639
-#define wxStaticLine_IsVertical 1640
-#define wxStaticLine_GetDefaultSize 1641
-#define wxStaticLine_destroy 1642
-#define wxListBox_new_3 1645
-#define wxListBox_new_0 1646
-#define wxListBox_destruct 1648
-#define wxListBox_Create 1650
-#define wxListBox_Deselect 1651
-#define wxListBox_GetSelections 1652
-#define wxListBox_InsertItems 1653
-#define wxListBox_IsSelected 1654
-#define wxListBox_Set 1655
-#define wxListBox_HitTest 1656
-#define wxListBox_SetFirstItem_1_0 1657
-#define wxListBox_SetFirstItem_1_1 1658
-#define wxListCtrl_new_0 1659
-#define wxListCtrl_new_2 1660
-#define wxListCtrl_Arrange 1661
-#define wxListCtrl_AssignImageList 1662
-#define wxListCtrl_ClearAll 1663
-#define wxListCtrl_Create 1664
-#define wxListCtrl_DeleteAllItems 1665
-#define wxListCtrl_DeleteColumn 1666
-#define wxListCtrl_DeleteItem 1667
-#define wxListCtrl_EditLabel 1668
-#define wxListCtrl_EnsureVisible 1669
-#define wxListCtrl_FindItem_3_0 1670
-#define wxListCtrl_FindItem_3_1 1671
-#define wxListCtrl_GetColumn 1672
-#define wxListCtrl_GetColumnCount 1673
-#define wxListCtrl_GetColumnWidth 1674
-#define wxListCtrl_GetCountPerPage 1675
-#define wxListCtrl_GetEditControl 1676
-#define wxListCtrl_GetImageList 1677
-#define wxListCtrl_GetItem 1678
-#define wxListCtrl_GetItemBackgroundColour 1679
-#define wxListCtrl_GetItemCount 1680
-#define wxListCtrl_GetItemData 1681
-#define wxListCtrl_GetItemFont 1682
-#define wxListCtrl_GetItemPosition 1683
-#define wxListCtrl_GetItemRect 1684
-#define wxListCtrl_GetItemSpacing 1685
-#define wxListCtrl_GetItemState 1686
-#define wxListCtrl_GetItemText 1687
-#define wxListCtrl_GetItemTextColour 1688
-#define wxListCtrl_GetNextItem 1689
-#define wxListCtrl_GetSelectedItemCount 1690
-#define wxListCtrl_GetTextColour 1691
-#define wxListCtrl_GetTopItem 1692
-#define wxListCtrl_GetViewRect 1693
-#define wxListCtrl_HitTest 1694
-#define wxListCtrl_InsertColumn_2 1695
-#define wxListCtrl_InsertColumn_3 1696
-#define wxListCtrl_InsertItem_1 1697
-#define wxListCtrl_InsertItem_2_1 1698
-#define wxListCtrl_InsertItem_2_0 1699
-#define wxListCtrl_InsertItem_3 1700
-#define wxListCtrl_RefreshItem 1701
-#define wxListCtrl_RefreshItems 1702
-#define wxListCtrl_ScrollList 1703
-#define wxListCtrl_SetBackgroundColour 1704
-#define wxListCtrl_SetColumn 1705
-#define wxListCtrl_SetColumnWidth 1706
-#define wxListCtrl_SetImageList 1707
-#define wxListCtrl_SetItem_1 1708
-#define wxListCtrl_SetItem_4 1709
-#define wxListCtrl_SetItemBackgroundColour 1710
-#define wxListCtrl_SetItemCount 1711
-#define wxListCtrl_SetItemData 1712
-#define wxListCtrl_SetItemFont 1713
-#define wxListCtrl_SetItemImage 1714
-#define wxListCtrl_SetItemColumnImage 1715
-#define wxListCtrl_SetItemPosition 1716
-#define wxListCtrl_SetItemState 1717
-#define wxListCtrl_SetItemText 1718
-#define wxListCtrl_SetItemTextColour 1719
-#define wxListCtrl_SetSingleStyle 1720
-#define wxListCtrl_SetTextColour 1721
-#define wxListCtrl_SetWindowStyleFlag 1722
-#define wxListCtrl_SortItems 1723
-#define wxListCtrl_destroy 1724
-#define wxListView_ClearColumnImage 1725
-#define wxListView_Focus 1726
-#define wxListView_GetFirstSelected 1727
-#define wxListView_GetFocusedItem 1728
-#define wxListView_GetNextSelected 1729
-#define wxListView_IsSelected 1730
-#define wxListView_Select 1731
-#define wxListView_SetColumnImage 1732
-#define wxListItem_new_0 1733
-#define wxListItem_new_1 1734
-#define wxListItem_destruct 1735
-#define wxListItem_Clear 1736
-#define wxListItem_GetAlign 1737
-#define wxListItem_GetBackgroundColour 1738
-#define wxListItem_GetColumn 1739
-#define wxListItem_GetFont 1740
-#define wxListItem_GetId 1741
-#define wxListItem_GetImage 1742
-#define wxListItem_GetMask 1743
-#define wxListItem_GetState 1744
-#define wxListItem_GetText 1745
-#define wxListItem_GetTextColour 1746
-#define wxListItem_GetWidth 1747
-#define wxListItem_SetAlign 1748
-#define wxListItem_SetBackgroundColour 1749
-#define wxListItem_SetColumn 1750
-#define wxListItem_SetFont 1751
-#define wxListItem_SetId 1752
-#define wxListItem_SetImage 1753
-#define wxListItem_SetMask 1754
-#define wxListItem_SetState 1755
-#define wxListItem_SetStateMask 1756
-#define wxListItem_SetText 1757
-#define wxListItem_SetTextColour 1758
-#define wxListItem_SetWidth 1759
-#define wxListItemAttr_new_0 1760
-#define wxListItemAttr_new_3 1761
-#define wxListItemAttr_GetBackgroundColour 1762
-#define wxListItemAttr_GetFont 1763
-#define wxListItemAttr_GetTextColour 1764
-#define wxListItemAttr_HasBackgroundColour 1765
-#define wxListItemAttr_HasFont 1766
-#define wxListItemAttr_HasTextColour 1767
-#define wxListItemAttr_SetBackgroundColour 1768
-#define wxListItemAttr_SetFont 1769
-#define wxListItemAttr_SetTextColour 1770
-#define wxListItemAttr_destroy 1771
-#define wxImageList_new_0 1772
-#define wxImageList_new_3 1773
-#define wxImageList_Add_1 1774
-#define wxImageList_Add_2_0 1775
-#define wxImageList_Add_2_1 1776
-#define wxImageList_Create 1777
-#define wxImageList_Draw 1779
-#define wxImageList_GetBitmap 1780
-#define wxImageList_GetIcon 1781
-#define wxImageList_GetImageCount 1782
-#define wxImageList_GetSize 1783
-#define wxImageList_Remove 1784
-#define wxImageList_RemoveAll 1785
-#define wxImageList_Replace_2 1786
-#define wxImageList_Replace_3 1787
-#define wxImageList_destroy 1788
-#define wxTextAttr_new_0 1789
-#define wxTextAttr_new_2 1790
-#define wxTextAttr_GetAlignment 1791
-#define wxTextAttr_GetBackgroundColour 1792
-#define wxTextAttr_GetFont 1793
-#define wxTextAttr_GetLeftIndent 1794
-#define wxTextAttr_GetLeftSubIndent 1795
-#define wxTextAttr_GetRightIndent 1796
-#define wxTextAttr_GetTabs 1797
-#define wxTextAttr_GetTextColour 1798
-#define wxTextAttr_HasBackgroundColour 1799
-#define wxTextAttr_HasFont 1800
-#define wxTextAttr_HasTextColour 1801
-#define wxTextAttr_GetFlags 1802
-#define wxTextAttr_IsDefault 1803
-#define wxTextAttr_SetAlignment 1804
-#define wxTextAttr_SetBackgroundColour 1805
-#define wxTextAttr_SetFlags 1806
-#define wxTextAttr_SetFont 1807
-#define wxTextAttr_SetLeftIndent 1808
-#define wxTextAttr_SetRightIndent 1809
-#define wxTextAttr_SetTabs 1810
-#define wxTextAttr_SetTextColour 1811
-#define wxTextAttr_destroy 1812
-#define wxTextCtrl_new_3 1814
-#define wxTextCtrl_new_0 1815
-#define wxTextCtrl_destruct 1817
-#define wxTextCtrl_AppendText 1818
-#define wxTextCtrl_CanCopy 1819
-#define wxTextCtrl_CanCut 1820
-#define wxTextCtrl_CanPaste 1821
-#define wxTextCtrl_CanRedo 1822
-#define wxTextCtrl_CanUndo 1823
-#define wxTextCtrl_Clear 1824
-#define wxTextCtrl_Copy 1825
-#define wxTextCtrl_Create 1826
-#define wxTextCtrl_Cut 1827
-#define wxTextCtrl_DiscardEdits 1828
-#define wxTextCtrl_ChangeValue 1829
-#define wxTextCtrl_EmulateKeyPress 1830
-#define wxTextCtrl_GetDefaultStyle 1831
-#define wxTextCtrl_GetInsertionPoint 1832
-#define wxTextCtrl_GetLastPosition 1833
-#define wxTextCtrl_GetLineLength 1834
-#define wxTextCtrl_GetLineText 1835
-#define wxTextCtrl_GetNumberOfLines 1836
-#define wxTextCtrl_GetRange 1837
-#define wxTextCtrl_GetSelection 1838
-#define wxTextCtrl_GetStringSelection 1839
-#define wxTextCtrl_GetStyle 1840
-#define wxTextCtrl_GetValue 1841
-#define wxTextCtrl_IsEditable 1842
-#define wxTextCtrl_IsModified 1843
-#define wxTextCtrl_IsMultiLine 1844
-#define wxTextCtrl_IsSingleLine 1845
-#define wxTextCtrl_LoadFile 1846
-#define wxTextCtrl_MarkDirty 1847
-#define wxTextCtrl_Paste 1848
-#define wxTextCtrl_PositionToXY 1849
-#define wxTextCtrl_Redo 1850
-#define wxTextCtrl_Remove 1851
-#define wxTextCtrl_Replace 1852
-#define wxTextCtrl_SaveFile 1853
-#define wxTextCtrl_SetDefaultStyle 1854
-#define wxTextCtrl_SetEditable 1855
-#define wxTextCtrl_SetInsertionPoint 1856
-#define wxTextCtrl_SetInsertionPointEnd 1857
-#define wxTextCtrl_SetMaxLength 1859
-#define wxTextCtrl_SetSelection 1860
-#define wxTextCtrl_SetStyle 1861
-#define wxTextCtrl_SetValue 1862
-#define wxTextCtrl_ShowPosition 1863
-#define wxTextCtrl_Undo 1864
-#define wxTextCtrl_WriteText 1865
-#define wxTextCtrl_XYToPosition 1866
-#define wxNotebook_new_0 1869
-#define wxNotebook_new_3 1870
-#define wxNotebook_destruct 1871
-#define wxNotebook_AddPage 1872
-#define wxNotebook_AdvanceSelection 1873
-#define wxNotebook_AssignImageList 1874
-#define wxNotebook_Create 1875
-#define wxNotebook_DeleteAllPages 1876
-#define wxNotebook_DeletePage 1877
-#define wxNotebook_RemovePage 1878
-#define wxNotebook_GetCurrentPage 1879
-#define wxNotebook_GetImageList 1880
-#define wxNotebook_GetPage 1882
-#define wxNotebook_GetPageCount 1883
-#define wxNotebook_GetPageImage 1884
-#define wxNotebook_GetPageText 1885
-#define wxNotebook_GetRowCount 1886
-#define wxNotebook_GetSelection 1887
-#define wxNotebook_GetThemeBackgroundColour 1888
-#define wxNotebook_HitTest 1890
-#define wxNotebook_InsertPage 1892
-#define wxNotebook_SetImageList 1893
-#define wxNotebook_SetPadding 1894
-#define wxNotebook_SetPageSize 1895
-#define wxNotebook_SetPageImage 1896
-#define wxNotebook_SetPageText 1897
-#define wxNotebook_SetSelection 1898
-#define wxNotebook_ChangeSelection 1899
-#define wxChoicebook_new_0 1900
-#define wxChoicebook_new_3 1901
-#define wxChoicebook_AddPage 1902
-#define wxChoicebook_AdvanceSelection 1903
-#define wxChoicebook_AssignImageList 1904
-#define wxChoicebook_Create 1905
-#define wxChoicebook_DeleteAllPages 1906
-#define wxChoicebook_DeletePage 1907
-#define wxChoicebook_RemovePage 1908
-#define wxChoicebook_GetCurrentPage 1909
-#define wxChoicebook_GetImageList 1910
-#define wxChoicebook_GetPage 1912
-#define wxChoicebook_GetPageCount 1913
-#define wxChoicebook_GetPageImage 1914
-#define wxChoicebook_GetPageText 1915
-#define wxChoicebook_GetSelection 1916
-#define wxChoicebook_HitTest 1917
-#define wxChoicebook_InsertPage 1918
-#define wxChoicebook_SetImageList 1919
-#define wxChoicebook_SetPageSize 1920
-#define wxChoicebook_SetPageImage 1921
-#define wxChoicebook_SetPageText 1922
-#define wxChoicebook_SetSelection 1923
-#define wxChoicebook_ChangeSelection 1924
-#define wxChoicebook_destroy 1925
-#define wxToolbook_new_0 1926
-#define wxToolbook_new_3 1927
-#define wxToolbook_AddPage 1928
-#define wxToolbook_AdvanceSelection 1929
-#define wxToolbook_AssignImageList 1930
-#define wxToolbook_Create 1931
-#define wxToolbook_DeleteAllPages 1932
-#define wxToolbook_DeletePage 1933
-#define wxToolbook_RemovePage 1934
-#define wxToolbook_GetCurrentPage 1935
-#define wxToolbook_GetImageList 1936
-#define wxToolbook_GetPage 1938
-#define wxToolbook_GetPageCount 1939
-#define wxToolbook_GetPageImage 1940
-#define wxToolbook_GetPageText 1941
-#define wxToolbook_GetSelection 1942
-#define wxToolbook_HitTest 1944
-#define wxToolbook_InsertPage 1945
-#define wxToolbook_SetImageList 1946
-#define wxToolbook_SetPageSize 1947
-#define wxToolbook_SetPageImage 1948
-#define wxToolbook_SetPageText 1949
-#define wxToolbook_SetSelection 1950
-#define wxToolbook_ChangeSelection 1951
-#define wxToolbook_destroy 1952
-#define wxListbook_new_0 1953
-#define wxListbook_new_3 1954
-#define wxListbook_AddPage 1955
-#define wxListbook_AdvanceSelection 1956
-#define wxListbook_AssignImageList 1957
-#define wxListbook_Create 1958
-#define wxListbook_DeleteAllPages 1959
-#define wxListbook_DeletePage 1960
-#define wxListbook_RemovePage 1961
-#define wxListbook_GetCurrentPage 1962
-#define wxListbook_GetImageList 1963
-#define wxListbook_GetPage 1965
-#define wxListbook_GetPageCount 1966
-#define wxListbook_GetPageImage 1967
-#define wxListbook_GetPageText 1968
-#define wxListbook_GetSelection 1969
-#define wxListbook_HitTest 1971
-#define wxListbook_InsertPage 1972
-#define wxListbook_SetImageList 1973
-#define wxListbook_SetPageSize 1974
-#define wxListbook_SetPageImage 1975
-#define wxListbook_SetPageText 1976
-#define wxListbook_SetSelection 1977
-#define wxListbook_ChangeSelection 1978
-#define wxListbook_destroy 1979
-#define wxTreebook_new_0 1980
-#define wxTreebook_new_3 1981
-#define wxTreebook_AddPage 1982
-#define wxTreebook_AdvanceSelection 1983
-#define wxTreebook_AssignImageList 1984
-#define wxTreebook_Create 1985
-#define wxTreebook_DeleteAllPages 1986
-#define wxTreebook_DeletePage 1987
-#define wxTreebook_RemovePage 1988
-#define wxTreebook_GetCurrentPage 1989
-#define wxTreebook_GetImageList 1990
-#define wxTreebook_GetPage 1992
-#define wxTreebook_GetPageCount 1993
-#define wxTreebook_GetPageImage 1994
-#define wxTreebook_GetPageText 1995
-#define wxTreebook_GetSelection 1996
-#define wxTreebook_ExpandNode 1997
-#define wxTreebook_IsNodeExpanded 1998
-#define wxTreebook_HitTest 2000
-#define wxTreebook_InsertPage 2001
-#define wxTreebook_InsertSubPage 2002
-#define wxTreebook_SetImageList 2003
-#define wxTreebook_SetPageSize 2004
-#define wxTreebook_SetPageImage 2005
-#define wxTreebook_SetPageText 2006
-#define wxTreebook_SetSelection 2007
-#define wxTreebook_ChangeSelection 2008
-#define wxTreebook_destroy 2009
-#define wxTreeCtrl_new_2 2012
-#define wxTreeCtrl_new_0 2013
-#define wxTreeCtrl_destruct 2015
-#define wxTreeCtrl_AddRoot 2016
-#define wxTreeCtrl_AppendItem 2017
-#define wxTreeCtrl_AssignImageList 2018
-#define wxTreeCtrl_AssignStateImageList 2019
-#define wxTreeCtrl_Collapse 2020
-#define wxTreeCtrl_CollapseAndReset 2021
-#define wxTreeCtrl_Create 2022
-#define wxTreeCtrl_Delete 2023
-#define wxTreeCtrl_DeleteAllItems 2024
-#define wxTreeCtrl_DeleteChildren 2025
-#define wxTreeCtrl_EditLabel 2026
-#define wxTreeCtrl_EnsureVisible 2027
-#define wxTreeCtrl_Expand 2028
-#define wxTreeCtrl_GetBoundingRect 2029
-#define wxTreeCtrl_GetChildrenCount 2031
-#define wxTreeCtrl_GetCount 2032
-#define wxTreeCtrl_GetEditControl 2033
-#define wxTreeCtrl_GetFirstChild 2034
-#define wxTreeCtrl_GetNextChild 2035
-#define wxTreeCtrl_GetFirstVisibleItem 2036
-#define wxTreeCtrl_GetImageList 2037
-#define wxTreeCtrl_GetIndent 2038
-#define wxTreeCtrl_GetItemBackgroundColour 2039
-#define wxTreeCtrl_GetItemData 2040
-#define wxTreeCtrl_GetItemFont 2041
-#define wxTreeCtrl_GetItemImage_1 2042
-#define wxTreeCtrl_GetItemImage_2 2043
-#define wxTreeCtrl_GetItemText 2044
-#define wxTreeCtrl_GetItemTextColour 2045
-#define wxTreeCtrl_GetLastChild 2046
-#define wxTreeCtrl_GetNextSibling 2047
-#define wxTreeCtrl_GetNextVisible 2048
-#define wxTreeCtrl_GetItemParent 2049
-#define wxTreeCtrl_GetPrevSibling 2050
-#define wxTreeCtrl_GetPrevVisible 2051
-#define wxTreeCtrl_GetRootItem 2052
-#define wxTreeCtrl_GetSelection 2053
-#define wxTreeCtrl_GetSelections 2054
-#define wxTreeCtrl_GetStateImageList 2055
-#define wxTreeCtrl_HitTest 2056
-#define wxTreeCtrl_InsertItem 2058
-#define wxTreeCtrl_IsBold 2059
-#define wxTreeCtrl_IsExpanded 2060
-#define wxTreeCtrl_IsSelected 2061
-#define wxTreeCtrl_IsVisible 2062
-#define wxTreeCtrl_ItemHasChildren 2063
-#define wxTreeCtrl_IsTreeItemIdOk 2064
-#define wxTreeCtrl_PrependItem 2065
-#define wxTreeCtrl_ScrollTo 2066
-#define wxTreeCtrl_SelectItem_1 2067
-#define wxTreeCtrl_SelectItem_2 2068
-#define wxTreeCtrl_SetIndent 2069
-#define wxTreeCtrl_SetImageList 2070
-#define wxTreeCtrl_SetItemBackgroundColour 2071
-#define wxTreeCtrl_SetItemBold 2072
-#define wxTreeCtrl_SetItemData 2073
-#define wxTreeCtrl_SetItemDropHighlight 2074
-#define wxTreeCtrl_SetItemFont 2075
-#define wxTreeCtrl_SetItemHasChildren 2076
-#define wxTreeCtrl_SetItemImage_2 2077
-#define wxTreeCtrl_SetItemImage_3 2078
-#define wxTreeCtrl_SetItemText 2079
-#define wxTreeCtrl_SetItemTextColour 2080
-#define wxTreeCtrl_SetStateImageList 2081
-#define wxTreeCtrl_SetWindowStyle 2082
-#define wxTreeCtrl_SortChildren 2083
-#define wxTreeCtrl_Toggle 2084
-#define wxTreeCtrl_ToggleItemSelection 2085
-#define wxTreeCtrl_Unselect 2086
-#define wxTreeCtrl_UnselectAll 2087
-#define wxTreeCtrl_UnselectItem 2088
-#define wxScrollBar_new_0 2089
-#define wxScrollBar_new_3 2090
-#define wxScrollBar_destruct 2091
-#define wxScrollBar_Create 2092
-#define wxScrollBar_GetRange 2093
-#define wxScrollBar_GetPageSize 2094
-#define wxScrollBar_GetThumbPosition 2095
-#define wxScrollBar_GetThumbSize 2096
-#define wxScrollBar_SetThumbPosition 2097
-#define wxScrollBar_SetScrollbar 2098
-#define wxSpinButton_new_2 2100
-#define wxSpinButton_new_0 2101
-#define wxSpinButton_Create 2102
-#define wxSpinButton_GetMax 2103
-#define wxSpinButton_GetMin 2104
-#define wxSpinButton_GetValue 2105
-#define wxSpinButton_SetRange 2106
-#define wxSpinButton_SetValue 2107
-#define wxSpinButton_destroy 2108
-#define wxSpinCtrl_new_0 2109
-#define wxSpinCtrl_new_2 2110
-#define wxSpinCtrl_Create 2112
-#define wxSpinCtrl_SetValue_1_1 2115
-#define wxSpinCtrl_SetValue_1_0 2116
-#define wxSpinCtrl_GetValue 2118
-#define wxSpinCtrl_SetRange 2120
-#define wxSpinCtrl_SetSelection 2121
-#define wxSpinCtrl_GetMin 2123
-#define wxSpinCtrl_GetMax 2125
-#define wxSpinCtrl_destroy 2126
-#define wxStaticText_new_0 2127
-#define wxStaticText_new_4 2128
-#define wxStaticText_Create 2129
-#define wxStaticText_GetLabel 2130
-#define wxStaticText_SetLabel 2131
-#define wxStaticText_Wrap 2132
-#define wxStaticText_destroy 2133
-#define wxStaticBitmap_new_0 2134
-#define wxStaticBitmap_new_4 2135
-#define wxStaticBitmap_Create 2136
-#define wxStaticBitmap_GetBitmap 2137
-#define wxStaticBitmap_SetBitmap 2138
-#define wxStaticBitmap_destroy 2139
-#define wxRadioBox_new 2140
-#define wxRadioBox_destruct 2142
-#define wxRadioBox_Create 2143
-#define wxRadioBox_Enable_2 2144
-#define wxRadioBox_Enable_1 2145
-#define wxRadioBox_GetSelection 2146
-#define wxRadioBox_GetString 2147
-#define wxRadioBox_SetSelection 2148
-#define wxRadioBox_Show_2 2149
-#define wxRadioBox_Show_1 2150
-#define wxRadioBox_GetColumnCount 2151
-#define wxRadioBox_GetItemHelpText 2152
-#define wxRadioBox_GetItemToolTip 2153
-#define wxRadioBox_GetItemFromPoint 2155
-#define wxRadioBox_GetRowCount 2156
-#define wxRadioBox_IsItemEnabled 2157
-#define wxRadioBox_IsItemShown 2158
-#define wxRadioBox_SetItemHelpText 2159
-#define wxRadioBox_SetItemToolTip 2160
-#define wxRadioButton_new_0 2161
-#define wxRadioButton_new_4 2162
-#define wxRadioButton_Create 2163
-#define wxRadioButton_GetValue 2164
-#define wxRadioButton_SetValue 2165
-#define wxRadioButton_destroy 2166
-#define wxSlider_new_6 2168
-#define wxSlider_new_0 2169
-#define wxSlider_Create 2170
-#define wxSlider_GetLineSize 2171
-#define wxSlider_GetMax 2172
-#define wxSlider_GetMin 2173
-#define wxSlider_GetPageSize 2174
-#define wxSlider_GetThumbLength 2175
-#define wxSlider_GetValue 2176
-#define wxSlider_SetLineSize 2177
-#define wxSlider_SetPageSize 2178
-#define wxSlider_SetRange 2179
-#define wxSlider_SetThumbLength 2180
-#define wxSlider_SetValue 2181
-#define wxSlider_destroy 2182
-#define wxDialog_new_4 2184
-#define wxDialog_new_0 2185
-#define wxDialog_destruct 2187
-#define wxDialog_Create 2188
-#define wxDialog_CreateButtonSizer 2189
-#define wxDialog_CreateStdDialogButtonSizer 2190
-#define wxDialog_EndModal 2191
-#define wxDialog_GetAffirmativeId 2192
-#define wxDialog_GetReturnCode 2193
-#define wxDialog_IsModal 2194
-#define wxDialog_SetAffirmativeId 2195
-#define wxDialog_SetReturnCode 2196
-#define wxDialog_Show 2197
-#define wxDialog_ShowModal 2198
-#define wxColourDialog_new_0 2199
-#define wxColourDialog_new_2 2200
-#define wxColourDialog_destruct 2201
-#define wxColourDialog_Create 2202
-#define wxColourDialog_GetColourData 2203
-#define wxColourData_new_0 2204
-#define wxColourData_new_1 2205
-#define wxColourData_destruct 2206
-#define wxColourData_GetChooseFull 2207
-#define wxColourData_GetColour 2208
-#define wxColourData_GetCustomColour 2210
-#define wxColourData_SetChooseFull 2211
-#define wxColourData_SetColour 2212
-#define wxColourData_SetCustomColour 2213
-#define wxPalette_new_0 2214
-#define wxPalette_new_4 2215
-#define wxPalette_destruct 2217
-#define wxPalette_Create 2218
-#define wxPalette_GetColoursCount 2219
-#define wxPalette_GetPixel 2220
-#define wxPalette_GetRGB 2221
-#define wxPalette_IsOk 2222
-#define wxDirDialog_new 2226
-#define wxDirDialog_destruct 2227
-#define wxDirDialog_GetPath 2228
-#define wxDirDialog_GetMessage 2229
-#define wxDirDialog_SetMessage 2230
-#define wxDirDialog_SetPath 2231
-#define wxFileDialog_new 2235
-#define wxFileDialog_destruct 2236
-#define wxFileDialog_GetDirectory 2237
-#define wxFileDialog_GetFilename 2238
-#define wxFileDialog_GetFilenames 2239
-#define wxFileDialog_GetFilterIndex 2240
-#define wxFileDialog_GetMessage 2241
-#define wxFileDialog_GetPath 2242
-#define wxFileDialog_GetPaths 2243
-#define wxFileDialog_GetWildcard 2244
-#define wxFileDialog_SetDirectory 2245
-#define wxFileDialog_SetFilename 2246
-#define wxFileDialog_SetFilterIndex 2247
-#define wxFileDialog_SetMessage 2248
-#define wxFileDialog_SetPath 2249
-#define wxFileDialog_SetWildcard 2250
-#define wxPickerBase_SetInternalMargin 2251
-#define wxPickerBase_GetInternalMargin 2252
-#define wxPickerBase_SetTextCtrlProportion 2253
-#define wxPickerBase_SetPickerCtrlProportion 2254
-#define wxPickerBase_GetTextCtrlProportion 2255
-#define wxPickerBase_GetPickerCtrlProportion 2256
-#define wxPickerBase_HasTextCtrl 2257
-#define wxPickerBase_GetTextCtrl 2258
-#define wxPickerBase_IsTextCtrlGrowable 2259
-#define wxPickerBase_SetPickerCtrlGrowable 2260
-#define wxPickerBase_SetTextCtrlGrowable 2261
-#define wxPickerBase_IsPickerCtrlGrowable 2262
-#define wxFilePickerCtrl_new_0 2263
-#define wxFilePickerCtrl_new_3 2264
-#define wxFilePickerCtrl_Create 2265
-#define wxFilePickerCtrl_GetPath 2266
-#define wxFilePickerCtrl_SetPath 2267
-#define wxFilePickerCtrl_destroy 2268
-#define wxDirPickerCtrl_new_0 2269
-#define wxDirPickerCtrl_new_3 2270
-#define wxDirPickerCtrl_Create 2271
-#define wxDirPickerCtrl_GetPath 2272
-#define wxDirPickerCtrl_SetPath 2273
-#define wxDirPickerCtrl_destroy 2274
-#define wxColourPickerCtrl_new_0 2275
-#define wxColourPickerCtrl_new_3 2276
-#define wxColourPickerCtrl_Create 2277
-#define wxColourPickerCtrl_GetColour 2278
-#define wxColourPickerCtrl_SetColour_1_1 2279
-#define wxColourPickerCtrl_SetColour_1_0 2280
-#define wxColourPickerCtrl_destroy 2281
-#define wxDatePickerCtrl_new_0 2282
-#define wxDatePickerCtrl_new_3 2283
-#define wxDatePickerCtrl_GetRange 2284
-#define wxDatePickerCtrl_GetValue 2285
-#define wxDatePickerCtrl_SetRange 2286
-#define wxDatePickerCtrl_SetValue 2287
-#define wxDatePickerCtrl_destroy 2288
-#define wxFontPickerCtrl_new_0 2289
-#define wxFontPickerCtrl_new_3 2290
-#define wxFontPickerCtrl_Create 2291
-#define wxFontPickerCtrl_GetSelectedFont 2292
-#define wxFontPickerCtrl_SetSelectedFont 2293
-#define wxFontPickerCtrl_GetMaxPointSize 2294
-#define wxFontPickerCtrl_SetMaxPointSize 2295
-#define wxFontPickerCtrl_destroy 2296
-#define wxFindReplaceDialog_new_0 2299
-#define wxFindReplaceDialog_new_4 2300
-#define wxFindReplaceDialog_destruct 2301
-#define wxFindReplaceDialog_Create 2302
-#define wxFindReplaceDialog_GetData 2303
-#define wxFindReplaceData_new_0 2304
-#define wxFindReplaceData_new_1 2305
-#define wxFindReplaceData_GetFindString 2306
-#define wxFindReplaceData_GetReplaceString 2307
-#define wxFindReplaceData_GetFlags 2308
-#define wxFindReplaceData_SetFlags 2309
-#define wxFindReplaceData_SetFindString 2310
-#define wxFindReplaceData_SetReplaceString 2311
-#define wxFindReplaceData_destroy 2312
-#define wxMultiChoiceDialog_new_0 2313
-#define wxMultiChoiceDialog_new_5 2315
-#define wxMultiChoiceDialog_GetSelections 2316
-#define wxMultiChoiceDialog_SetSelections 2317
-#define wxMultiChoiceDialog_destroy 2318
-#define wxSingleChoiceDialog_new_0 2319
-#define wxSingleChoiceDialog_new_5 2321
-#define wxSingleChoiceDialog_GetSelection 2322
-#define wxSingleChoiceDialog_GetStringSelection 2323
-#define wxSingleChoiceDialog_SetSelection 2324
-#define wxSingleChoiceDialog_destroy 2325
-#define wxTextEntryDialog_new 2326
-#define wxTextEntryDialog_GetValue 2327
-#define wxTextEntryDialog_SetValue 2328
-#define wxTextEntryDialog_destroy 2329
-#define wxPasswordEntryDialog_new 2330
-#define wxPasswordEntryDialog_destroy 2331
-#define wxFontData_new_0 2332
-#define wxFontData_new_1 2333
-#define wxFontData_destruct 2334
-#define wxFontData_EnableEffects 2335
-#define wxFontData_GetAllowSymbols 2336
-#define wxFontData_GetColour 2337
-#define wxFontData_GetChosenFont 2338
-#define wxFontData_GetEnableEffects 2339
-#define wxFontData_GetInitialFont 2340
-#define wxFontData_GetShowHelp 2341
-#define wxFontData_SetAllowSymbols 2342
-#define wxFontData_SetChosenFont 2343
-#define wxFontData_SetColour 2344
-#define wxFontData_SetInitialFont 2345
-#define wxFontData_SetRange 2346
-#define wxFontData_SetShowHelp 2347
-#define wxFontDialog_new_0 2351
-#define wxFontDialog_new_2 2353
-#define wxFontDialog_Create 2355
-#define wxFontDialog_GetFontData 2356
-#define wxFontDialog_destroy 2358
-#define wxProgressDialog_new 2359
-#define wxProgressDialog_destruct 2360
-#define wxProgressDialog_Resume 2361
-#define wxProgressDialog_Update_2 2362
-#define wxProgressDialog_Update_0 2363
-#define wxMessageDialog_new 2364
-#define wxMessageDialog_destruct 2365
-#define wxPageSetupDialog_new 2366
-#define wxPageSetupDialog_destruct 2367
-#define wxPageSetupDialog_GetPageSetupData 2368
-#define wxPageSetupDialog_ShowModal 2369
-#define wxPageSetupDialogData_new_0 2370
-#define wxPageSetupDialogData_new_1_0 2371
-#define wxPageSetupDialogData_new_1_1 2372
-#define wxPageSetupDialogData_destruct 2373
-#define wxPageSetupDialogData_EnableHelp 2374
-#define wxPageSetupDialogData_EnableMargins 2375
-#define wxPageSetupDialogData_EnableOrientation 2376
-#define wxPageSetupDialogData_EnablePaper 2377
-#define wxPageSetupDialogData_EnablePrinter 2378
-#define wxPageSetupDialogData_GetDefaultMinMargins 2379
-#define wxPageSetupDialogData_GetEnableMargins 2380
-#define wxPageSetupDialogData_GetEnableOrientation 2381
-#define wxPageSetupDialogData_GetEnablePaper 2382
-#define wxPageSetupDialogData_GetEnablePrinter 2383
-#define wxPageSetupDialogData_GetEnableHelp 2384
-#define wxPageSetupDialogData_GetDefaultInfo 2385
-#define wxPageSetupDialogData_GetMarginTopLeft 2386
-#define wxPageSetupDialogData_GetMarginBottomRight 2387
-#define wxPageSetupDialogData_GetMinMarginTopLeft 2388
-#define wxPageSetupDialogData_GetMinMarginBottomRight 2389
-#define wxPageSetupDialogData_GetPaperId 2390
-#define wxPageSetupDialogData_GetPaperSize 2391
-#define wxPageSetupDialogData_GetPrintData 2393
-#define wxPageSetupDialogData_IsOk 2394
-#define wxPageSetupDialogData_SetDefaultInfo 2395
-#define wxPageSetupDialogData_SetDefaultMinMargins 2396
-#define wxPageSetupDialogData_SetMarginTopLeft 2397
-#define wxPageSetupDialogData_SetMarginBottomRight 2398
-#define wxPageSetupDialogData_SetMinMarginTopLeft 2399
-#define wxPageSetupDialogData_SetMinMarginBottomRight 2400
-#define wxPageSetupDialogData_SetPaperId 2401
-#define wxPageSetupDialogData_SetPaperSize_1_1 2402
-#define wxPageSetupDialogData_SetPaperSize_1_0 2403
-#define wxPageSetupDialogData_SetPrintData 2404
-#define wxPrintDialog_new_2_0 2405
-#define wxPrintDialog_new_2_1 2406
-#define wxPrintDialog_destruct 2407
-#define wxPrintDialog_GetPrintDialogData 2408
-#define wxPrintDialog_GetPrintDC 2409
-#define wxPrintDialogData_new_0 2410
-#define wxPrintDialogData_new_1_1 2411
-#define wxPrintDialogData_new_1_0 2412
-#define wxPrintDialogData_destruct 2413
-#define wxPrintDialogData_EnableHelp 2414
-#define wxPrintDialogData_EnablePageNumbers 2415
-#define wxPrintDialogData_EnablePrintToFile 2416
-#define wxPrintDialogData_EnableSelection 2417
-#define wxPrintDialogData_GetAllPages 2418
-#define wxPrintDialogData_GetCollate 2419
-#define wxPrintDialogData_GetFromPage 2420
-#define wxPrintDialogData_GetMaxPage 2421
-#define wxPrintDialogData_GetMinPage 2422
-#define wxPrintDialogData_GetNoCopies 2423
-#define wxPrintDialogData_GetPrintData 2424
-#define wxPrintDialogData_GetPrintToFile 2425
-#define wxPrintDialogData_GetSelection 2426
-#define wxPrintDialogData_GetToPage 2427
-#define wxPrintDialogData_IsOk 2428
-#define wxPrintDialogData_SetCollate 2429
-#define wxPrintDialogData_SetFromPage 2430
-#define wxPrintDialogData_SetMaxPage 2431
-#define wxPrintDialogData_SetMinPage 2432
-#define wxPrintDialogData_SetNoCopies 2433
-#define wxPrintDialogData_SetPrintData 2434
-#define wxPrintDialogData_SetPrintToFile 2435
-#define wxPrintDialogData_SetSelection 2436
-#define wxPrintDialogData_SetToPage 2437
-#define wxPrintData_new_0 2438
-#define wxPrintData_new_1 2439
-#define wxPrintData_destruct 2440
-#define wxPrintData_GetCollate 2441
-#define wxPrintData_GetBin 2442
-#define wxPrintData_GetColour 2443
-#define wxPrintData_GetDuplex 2444
-#define wxPrintData_GetNoCopies 2445
-#define wxPrintData_GetOrientation 2446
-#define wxPrintData_GetPaperId 2447
-#define wxPrintData_GetPrinterName 2448
-#define wxPrintData_GetQuality 2449
-#define wxPrintData_IsOk 2450
-#define wxPrintData_SetBin 2451
-#define wxPrintData_SetCollate 2452
-#define wxPrintData_SetColour 2453
-#define wxPrintData_SetDuplex 2454
-#define wxPrintData_SetNoCopies 2455
-#define wxPrintData_SetOrientation 2456
-#define wxPrintData_SetPaperId 2457
-#define wxPrintData_SetPrinterName 2458
-#define wxPrintData_SetQuality 2459
-#define wxPrintPreview_new_2 2462
-#define wxPrintPreview_new_3 2463
-#define wxPrintPreview_destruct 2465
-#define wxPrintPreview_GetCanvas 2466
-#define wxPrintPreview_GetCurrentPage 2467
-#define wxPrintPreview_GetFrame 2468
-#define wxPrintPreview_GetMaxPage 2469
-#define wxPrintPreview_GetMinPage 2470
-#define wxPrintPreview_GetPrintout 2471
-#define wxPrintPreview_GetPrintoutForPrinting 2472
-#define wxPrintPreview_IsOk 2473
-#define wxPrintPreview_PaintPage 2474
-#define wxPrintPreview_Print 2475
-#define wxPrintPreview_RenderPage 2476
-#define wxPrintPreview_SetCanvas 2477
-#define wxPrintPreview_SetCurrentPage 2478
-#define wxPrintPreview_SetFrame 2479
-#define wxPrintPreview_SetPrintout 2480
-#define wxPrintPreview_SetZoom 2481
-#define wxPreviewFrame_new 2482
-#define wxPreviewFrame_destruct 2483
-#define wxPreviewFrame_CreateControlBar 2484
-#define wxPreviewFrame_CreateCanvas 2485
-#define wxPreviewFrame_Initialize 2486
-#define wxPreviewFrame_OnCloseWindow 2487
-#define wxPreviewControlBar_new 2488
-#define wxPreviewControlBar_destruct 2489
-#define wxPreviewControlBar_CreateButtons 2490
-#define wxPreviewControlBar_GetPrintPreview 2491
-#define wxPreviewControlBar_GetZoomControl 2492
-#define wxPreviewControlBar_SetZoomControl 2493
-#define wxPrinter_new 2495
-#define wxPrinter_CreateAbortWindow 2496
-#define wxPrinter_GetAbort 2497
-#define wxPrinter_GetLastError 2498
-#define wxPrinter_GetPrintDialogData 2499
-#define wxPrinter_Print 2500
-#define wxPrinter_PrintDialog 2501
-#define wxPrinter_ReportError 2502
-#define wxPrinter_Setup 2503
-#define wxPrinter_destroy 2504
-#define wxXmlResource_new_1 2505
-#define wxXmlResource_new_2 2506
-#define wxXmlResource_destruct 2507
-#define wxXmlResource_AttachUnknownControl 2508
-#define wxXmlResource_ClearHandlers 2509
-#define wxXmlResource_CompareVersion 2510
-#define wxXmlResource_Get 2511
-#define wxXmlResource_GetFlags 2512
-#define wxXmlResource_GetVersion 2513
-#define wxXmlResource_GetXRCID 2514
-#define wxXmlResource_InitAllHandlers 2515
-#define wxXmlResource_Load 2516
-#define wxXmlResource_LoadBitmap 2517
-#define wxXmlResource_LoadDialog_2 2518
-#define wxXmlResource_LoadDialog_3 2519
-#define wxXmlResource_LoadFrame_2 2520
-#define wxXmlResource_LoadFrame_3 2521
-#define wxXmlResource_LoadIcon 2522
-#define wxXmlResource_LoadMenu 2523
-#define wxXmlResource_LoadMenuBar_2 2524
-#define wxXmlResource_LoadMenuBar_1 2525
-#define wxXmlResource_LoadPanel_2 2526
-#define wxXmlResource_LoadPanel_3 2527
-#define wxXmlResource_LoadToolBar 2528
-#define wxXmlResource_Set 2529
-#define wxXmlResource_SetFlags 2530
-#define wxXmlResource_Unload 2531
-#define wxXmlResource_xrcctrl 2532
-#define wxHtmlEasyPrinting_new 2533
-#define wxHtmlEasyPrinting_destruct 2534
-#define wxHtmlEasyPrinting_GetPrintData 2535
-#define wxHtmlEasyPrinting_GetPageSetupData 2536
-#define wxHtmlEasyPrinting_PreviewFile 2537
-#define wxHtmlEasyPrinting_PreviewText 2538
-#define wxHtmlEasyPrinting_PrintFile 2539
-#define wxHtmlEasyPrinting_PrintText 2540
-#define wxHtmlEasyPrinting_PageSetup 2541
-#define wxHtmlEasyPrinting_SetFonts 2542
-#define wxHtmlEasyPrinting_SetHeader 2543
-#define wxHtmlEasyPrinting_SetFooter 2544
-#define wxGLCanvas_new_2 2546
-#define wxGLCanvas_new_3_1 2547
-#define wxGLCanvas_new_3_0 2548
-#define wxGLCanvas_GetContext 2549
-#define wxGLCanvas_SetCurrent 2551
-#define wxGLCanvas_SwapBuffers 2552
-#define wxGLCanvas_destroy 2553
-#define wxAuiManager_new 2554
-#define wxAuiManager_destruct 2555
-#define wxAuiManager_AddPane_2_1 2556
-#define wxAuiManager_AddPane_3 2557
-#define wxAuiManager_AddPane_2_0 2558
-#define wxAuiManager_DetachPane 2559
-#define wxAuiManager_GetAllPanes 2560
-#define wxAuiManager_GetArtProvider 2561
-#define wxAuiManager_GetDockSizeConstraint 2562
-#define wxAuiManager_GetFlags 2563
-#define wxAuiManager_GetManagedWindow 2564
-#define wxAuiManager_GetManager 2565
-#define wxAuiManager_GetPane_1_1 2566
-#define wxAuiManager_GetPane_1_0 2567
-#define wxAuiManager_HideHint 2568
-#define wxAuiManager_InsertPane 2569
-#define wxAuiManager_LoadPaneInfo 2570
-#define wxAuiManager_LoadPerspective 2571
-#define wxAuiManager_SavePaneInfo 2572
-#define wxAuiManager_SavePerspective 2573
-#define wxAuiManager_SetArtProvider 2574
-#define wxAuiManager_SetDockSizeConstraint 2575
-#define wxAuiManager_SetFlags 2576
-#define wxAuiManager_SetManagedWindow 2577
-#define wxAuiManager_ShowHint 2578
-#define wxAuiManager_UnInit 2579
-#define wxAuiManager_Update 2580
-#define wxAuiPaneInfo_new_0 2581
-#define wxAuiPaneInfo_new_1 2582
-#define wxAuiPaneInfo_destruct 2583
-#define wxAuiPaneInfo_BestSize_1 2584
-#define wxAuiPaneInfo_BestSize_2 2585
-#define wxAuiPaneInfo_Bottom 2586
-#define wxAuiPaneInfo_BottomDockable 2587
-#define wxAuiPaneInfo_Caption 2588
-#define wxAuiPaneInfo_CaptionVisible 2589
-#define wxAuiPaneInfo_Centre 2590
-#define wxAuiPaneInfo_CentrePane 2591
-#define wxAuiPaneInfo_CloseButton 2592
-#define wxAuiPaneInfo_DefaultPane 2593
-#define wxAuiPaneInfo_DestroyOnClose 2594
-#define wxAuiPaneInfo_Direction 2595
-#define wxAuiPaneInfo_Dock 2596
-#define wxAuiPaneInfo_Dockable 2597
-#define wxAuiPaneInfo_Fixed 2598
-#define wxAuiPaneInfo_Float 2599
-#define wxAuiPaneInfo_Floatable 2600
-#define wxAuiPaneInfo_FloatingPosition_1 2601
-#define wxAuiPaneInfo_FloatingPosition_2 2602
-#define wxAuiPaneInfo_FloatingSize_1 2603
-#define wxAuiPaneInfo_FloatingSize_2 2604
-#define wxAuiPaneInfo_Gripper 2605
-#define wxAuiPaneInfo_GripperTop 2606
-#define wxAuiPaneInfo_HasBorder 2607
-#define wxAuiPaneInfo_HasCaption 2608
-#define wxAuiPaneInfo_HasCloseButton 2609
-#define wxAuiPaneInfo_HasFlag 2610
-#define wxAuiPaneInfo_HasGripper 2611
-#define wxAuiPaneInfo_HasGripperTop 2612
-#define wxAuiPaneInfo_HasMaximizeButton 2613
-#define wxAuiPaneInfo_HasMinimizeButton 2614
-#define wxAuiPaneInfo_HasPinButton 2615
-#define wxAuiPaneInfo_Hide 2616
-#define wxAuiPaneInfo_IsBottomDockable 2617
-#define wxAuiPaneInfo_IsDocked 2618
-#define wxAuiPaneInfo_IsFixed 2619
-#define wxAuiPaneInfo_IsFloatable 2620
-#define wxAuiPaneInfo_IsFloating 2621
-#define wxAuiPaneInfo_IsLeftDockable 2622
-#define wxAuiPaneInfo_IsMovable 2623
-#define wxAuiPaneInfo_IsOk 2624
-#define wxAuiPaneInfo_IsResizable 2625
-#define wxAuiPaneInfo_IsRightDockable 2626
-#define wxAuiPaneInfo_IsShown 2627
-#define wxAuiPaneInfo_IsToolbar 2628
-#define wxAuiPaneInfo_IsTopDockable 2629
-#define wxAuiPaneInfo_Layer 2630
-#define wxAuiPaneInfo_Left 2631
-#define wxAuiPaneInfo_LeftDockable 2632
-#define wxAuiPaneInfo_MaxSize_1 2633
-#define wxAuiPaneInfo_MaxSize_2 2634
-#define wxAuiPaneInfo_MaximizeButton 2635
-#define wxAuiPaneInfo_MinSize_1 2636
-#define wxAuiPaneInfo_MinSize_2 2637
-#define wxAuiPaneInfo_MinimizeButton 2638
-#define wxAuiPaneInfo_Movable 2639
-#define wxAuiPaneInfo_Name 2640
-#define wxAuiPaneInfo_PaneBorder 2641
-#define wxAuiPaneInfo_PinButton 2642
-#define wxAuiPaneInfo_Position 2643
-#define wxAuiPaneInfo_Resizable 2644
-#define wxAuiPaneInfo_Right 2645
-#define wxAuiPaneInfo_RightDockable 2646
-#define wxAuiPaneInfo_Row 2647
-#define wxAuiPaneInfo_SafeSet 2648
-#define wxAuiPaneInfo_SetFlag 2649
-#define wxAuiPaneInfo_Show 2650
-#define wxAuiPaneInfo_ToolbarPane 2651
-#define wxAuiPaneInfo_Top 2652
-#define wxAuiPaneInfo_TopDockable 2653
-#define wxAuiPaneInfo_Window 2654
-#define wxAuiPaneInfo_GetWindow 2655
-#define wxAuiPaneInfo_GetFrame 2656
-#define wxAuiPaneInfo_GetDirection 2657
-#define wxAuiPaneInfo_GetLayer 2658
-#define wxAuiPaneInfo_GetRow 2659
-#define wxAuiPaneInfo_GetPosition 2660
-#define wxAuiPaneInfo_GetFloatingPosition 2661
-#define wxAuiPaneInfo_GetFloatingSize 2662
-#define wxAuiNotebook_new_0 2663
-#define wxAuiNotebook_new_2 2664
-#define wxAuiNotebook_AddPage 2665
-#define wxAuiNotebook_Create 2666
-#define wxAuiNotebook_DeletePage 2667
-#define wxAuiNotebook_GetArtProvider 2668
-#define wxAuiNotebook_GetPage 2669
-#define wxAuiNotebook_GetPageBitmap 2670
-#define wxAuiNotebook_GetPageCount 2671
-#define wxAuiNotebook_GetPageIndex 2672
-#define wxAuiNotebook_GetPageText 2673
-#define wxAuiNotebook_GetSelection 2674
-#define wxAuiNotebook_InsertPage 2675
-#define wxAuiNotebook_RemovePage 2676
-#define wxAuiNotebook_SetArtProvider 2677
-#define wxAuiNotebook_SetFont 2678
-#define wxAuiNotebook_SetPageBitmap 2679
-#define wxAuiNotebook_SetPageText 2680
-#define wxAuiNotebook_SetSelection 2681
-#define wxAuiNotebook_SetTabCtrlHeight 2682
-#define wxAuiNotebook_SetUniformBitmapSize 2683
-#define wxAuiNotebook_destroy 2684
-#define wxAuiTabArt_SetFlags 2685
-#define wxAuiTabArt_SetMeasuringFont 2686
-#define wxAuiTabArt_SetNormalFont 2687
-#define wxAuiTabArt_SetSelectedFont 2688
-#define wxAuiTabArt_SetColour 2689
-#define wxAuiTabArt_SetActiveColour 2690
-#define wxAuiDockArt_GetColour 2691
-#define wxAuiDockArt_GetFont 2692
-#define wxAuiDockArt_GetMetric 2693
-#define wxAuiDockArt_SetColour 2694
-#define wxAuiDockArt_SetFont 2695
-#define wxAuiDockArt_SetMetric 2696
-#define wxAuiSimpleTabArt_new 2697
-#define wxAuiSimpleTabArt_destroy 2698
-#define wxMDIParentFrame_new_0 2699
-#define wxMDIParentFrame_new_4 2700
-#define wxMDIParentFrame_destruct 2701
-#define wxMDIParentFrame_ActivateNext 2702
-#define wxMDIParentFrame_ActivatePrevious 2703
-#define wxMDIParentFrame_ArrangeIcons 2704
-#define wxMDIParentFrame_Cascade 2705
-#define wxMDIParentFrame_Create 2706
-#define wxMDIParentFrame_GetActiveChild 2707
-#define wxMDIParentFrame_GetClientWindow 2708
-#define wxMDIParentFrame_Tile 2709
-#define wxMDIChildFrame_new_0 2710
-#define wxMDIChildFrame_new_4 2711
-#define wxMDIChildFrame_destruct 2712
-#define wxMDIChildFrame_Activate 2713
-#define wxMDIChildFrame_Create 2714
-#define wxMDIChildFrame_Maximize 2715
-#define wxMDIChildFrame_Restore 2716
-#define wxMDIClientWindow_new_0 2717
-#define wxMDIClientWindow_new_2 2718
-#define wxMDIClientWindow_destruct 2719
-#define wxMDIClientWindow_CreateClient 2720
-#define wxLayoutAlgorithm_new 2721
-#define wxLayoutAlgorithm_LayoutFrame 2722
-#define wxLayoutAlgorithm_LayoutMDIFrame 2723
-#define wxLayoutAlgorithm_LayoutWindow 2724
-#define wxLayoutAlgorithm_destroy 2725
-#define wxEvent_GetId 2726
-#define wxEvent_GetSkipped 2727
-#define wxEvent_GetTimestamp 2728
-#define wxEvent_IsCommandEvent 2729
-#define wxEvent_ResumePropagation 2730
-#define wxEvent_ShouldPropagate 2731
-#define wxEvent_Skip 2732
-#define wxEvent_StopPropagation 2733
-#define wxCommandEvent_getClientData 2734
-#define wxCommandEvent_GetExtraLong 2735
-#define wxCommandEvent_GetInt 2736
-#define wxCommandEvent_GetSelection 2737
-#define wxCommandEvent_GetString 2738
-#define wxCommandEvent_IsChecked 2739
-#define wxCommandEvent_IsSelection 2740
-#define wxCommandEvent_SetInt 2741
-#define wxCommandEvent_SetString 2742
-#define wxScrollEvent_GetOrientation 2743
-#define wxScrollEvent_GetPosition 2744
-#define wxScrollWinEvent_GetOrientation 2745
-#define wxScrollWinEvent_GetPosition 2746
-#define wxMouseEvent_AltDown 2747
-#define wxMouseEvent_Button 2748
-#define wxMouseEvent_ButtonDClick 2749
-#define wxMouseEvent_ButtonDown 2750
-#define wxMouseEvent_ButtonUp 2751
-#define wxMouseEvent_CmdDown 2752
-#define wxMouseEvent_ControlDown 2753
-#define wxMouseEvent_Dragging 2754
-#define wxMouseEvent_Entering 2755
-#define wxMouseEvent_GetButton 2756
-#define wxMouseEvent_GetPosition 2759
-#define wxMouseEvent_GetLogicalPosition 2760
-#define wxMouseEvent_GetLinesPerAction 2761
-#define wxMouseEvent_GetWheelRotation 2762
-#define wxMouseEvent_GetWheelDelta 2763
-#define wxMouseEvent_GetX 2764
-#define wxMouseEvent_GetY 2765
-#define wxMouseEvent_IsButton 2766
-#define wxMouseEvent_IsPageScroll 2767
-#define wxMouseEvent_Leaving 2768
-#define wxMouseEvent_LeftDClick 2769
-#define wxMouseEvent_LeftDown 2770
-#define wxMouseEvent_LeftIsDown 2771
-#define wxMouseEvent_LeftUp 2772
-#define wxMouseEvent_MetaDown 2773
-#define wxMouseEvent_MiddleDClick 2774
-#define wxMouseEvent_MiddleDown 2775
-#define wxMouseEvent_MiddleIsDown 2776
-#define wxMouseEvent_MiddleUp 2777
-#define wxMouseEvent_Moving 2778
-#define wxMouseEvent_RightDClick 2779
-#define wxMouseEvent_RightDown 2780
-#define wxMouseEvent_RightIsDown 2781
-#define wxMouseEvent_RightUp 2782
-#define wxMouseEvent_ShiftDown 2783
-#define wxSetCursorEvent_GetCursor 2784
-#define wxSetCursorEvent_GetX 2785
-#define wxSetCursorEvent_GetY 2786
-#define wxSetCursorEvent_HasCursor 2787
-#define wxSetCursorEvent_SetCursor 2788
-#define wxKeyEvent_AltDown 2789
-#define wxKeyEvent_CmdDown 2790
-#define wxKeyEvent_ControlDown 2791
-#define wxKeyEvent_GetKeyCode 2792
-#define wxKeyEvent_GetModifiers 2793
-#define wxKeyEvent_GetPosition 2796
-#define wxKeyEvent_GetRawKeyCode 2797
-#define wxKeyEvent_GetRawKeyFlags 2798
-#define wxKeyEvent_GetUnicodeKey 2799
-#define wxKeyEvent_GetX 2800
-#define wxKeyEvent_GetY 2801
-#define wxKeyEvent_HasModifiers 2802
-#define wxKeyEvent_MetaDown 2803
-#define wxKeyEvent_ShiftDown 2804
-#define wxSizeEvent_GetSize 2805
-#define wxMoveEvent_GetPosition 2806
-#define wxEraseEvent_GetDC 2807
-#define wxFocusEvent_GetWindow 2808
-#define wxChildFocusEvent_GetWindow 2809
-#define wxMenuEvent_GetMenu 2810
-#define wxMenuEvent_GetMenuId 2811
-#define wxMenuEvent_IsPopup 2812
-#define wxCloseEvent_CanVeto 2813
-#define wxCloseEvent_GetLoggingOff 2814
-#define wxCloseEvent_SetCanVeto 2815
-#define wxCloseEvent_SetLoggingOff 2816
-#define wxCloseEvent_Veto 2817
-#define wxShowEvent_SetShow 2818
-#define wxShowEvent_GetShow 2819
-#define wxIconizeEvent_Iconized 2820
-#define wxJoystickEvent_ButtonDown 2821
-#define wxJoystickEvent_ButtonIsDown 2822
-#define wxJoystickEvent_ButtonUp 2823
-#define wxJoystickEvent_GetButtonChange 2824
-#define wxJoystickEvent_GetButtonState 2825
-#define wxJoystickEvent_GetJoystick 2826
-#define wxJoystickEvent_GetPosition 2827
-#define wxJoystickEvent_GetZPosition 2828
-#define wxJoystickEvent_IsButton 2829
-#define wxJoystickEvent_IsMove 2830
-#define wxJoystickEvent_IsZMove 2831
-#define wxUpdateUIEvent_CanUpdate 2832
-#define wxUpdateUIEvent_Check 2833
-#define wxUpdateUIEvent_Enable 2834
-#define wxUpdateUIEvent_Show 2835
-#define wxUpdateUIEvent_GetChecked 2836
-#define wxUpdateUIEvent_GetEnabled 2837
-#define wxUpdateUIEvent_GetShown 2838
-#define wxUpdateUIEvent_GetSetChecked 2839
-#define wxUpdateUIEvent_GetSetEnabled 2840
-#define wxUpdateUIEvent_GetSetShown 2841
-#define wxUpdateUIEvent_GetSetText 2842
-#define wxUpdateUIEvent_GetText 2843
-#define wxUpdateUIEvent_GetMode 2844
-#define wxUpdateUIEvent_GetUpdateInterval 2845
-#define wxUpdateUIEvent_ResetUpdateTime 2846
-#define wxUpdateUIEvent_SetMode 2847
-#define wxUpdateUIEvent_SetText 2848
-#define wxUpdateUIEvent_SetUpdateInterval 2849
-#define wxMouseCaptureChangedEvent_GetCapturedWindow 2850
-#define wxPaletteChangedEvent_SetChangedWindow 2851
-#define wxPaletteChangedEvent_GetChangedWindow 2852
-#define wxQueryNewPaletteEvent_SetPaletteRealized 2853
-#define wxQueryNewPaletteEvent_GetPaletteRealized 2854
-#define wxNavigationKeyEvent_GetDirection 2855
-#define wxNavigationKeyEvent_SetDirection 2856
-#define wxNavigationKeyEvent_IsWindowChange 2857
-#define wxNavigationKeyEvent_SetWindowChange 2858
-#define wxNavigationKeyEvent_IsFromTab 2859
-#define wxNavigationKeyEvent_SetFromTab 2860
-#define wxNavigationKeyEvent_GetCurrentFocus 2861
-#define wxNavigationKeyEvent_SetCurrentFocus 2862
-#define wxHelpEvent_GetOrigin 2863
-#define wxHelpEvent_GetPosition 2864
-#define wxHelpEvent_SetOrigin 2865
-#define wxHelpEvent_SetPosition 2866
-#define wxContextMenuEvent_GetPosition 2867
-#define wxContextMenuEvent_SetPosition 2868
-#define wxIdleEvent_CanSend 2869
-#define wxIdleEvent_GetMode 2870
-#define wxIdleEvent_RequestMore 2871
-#define wxIdleEvent_MoreRequested 2872
-#define wxIdleEvent_SetMode 2873
-#define wxGridEvent_AltDown 2874
-#define wxGridEvent_ControlDown 2875
-#define wxGridEvent_GetCol 2876
-#define wxGridEvent_GetPosition 2877
-#define wxGridEvent_GetRow 2878
-#define wxGridEvent_MetaDown 2879
-#define wxGridEvent_Selecting 2880
-#define wxGridEvent_ShiftDown 2881
-#define wxNotifyEvent_Allow 2882
-#define wxNotifyEvent_IsAllowed 2883
-#define wxNotifyEvent_Veto 2884
-#define wxSashEvent_GetEdge 2885
-#define wxSashEvent_GetDragRect 2886
-#define wxSashEvent_GetDragStatus 2887
-#define wxListEvent_GetCacheFrom 2888
-#define wxListEvent_GetCacheTo 2889
-#define wxListEvent_GetKeyCode 2890
-#define wxListEvent_GetIndex 2891
-#define wxListEvent_GetColumn 2892
-#define wxListEvent_GetPoint 2893
-#define wxListEvent_GetLabel 2894
-#define wxListEvent_GetText 2895
-#define wxListEvent_GetImage 2896
-#define wxListEvent_GetData 2897
-#define wxListEvent_GetMask 2898
-#define wxListEvent_GetItem 2899
-#define wxListEvent_IsEditCancelled 2900
-#define wxDateEvent_GetDate 2901
-#define wxCalendarEvent_GetWeekDay 2902
-#define wxFileDirPickerEvent_GetPath 2903
-#define wxColourPickerEvent_GetColour 2904
-#define wxFontPickerEvent_GetFont 2905
-#define wxStyledTextEvent_GetPosition 2906
-#define wxStyledTextEvent_GetKey 2907
-#define wxStyledTextEvent_GetModifiers 2908
-#define wxStyledTextEvent_GetModificationType 2909
-#define wxStyledTextEvent_GetText 2910
-#define wxStyledTextEvent_GetLength 2911
-#define wxStyledTextEvent_GetLinesAdded 2912
-#define wxStyledTextEvent_GetLine 2913
-#define wxStyledTextEvent_GetFoldLevelNow 2914
-#define wxStyledTextEvent_GetFoldLevelPrev 2915
-#define wxStyledTextEvent_GetMargin 2916
-#define wxStyledTextEvent_GetMessage 2917
-#define wxStyledTextEvent_GetWParam 2918
-#define wxStyledTextEvent_GetLParam 2919
-#define wxStyledTextEvent_GetListType 2920
-#define wxStyledTextEvent_GetX 2921
-#define wxStyledTextEvent_GetY 2922
-#define wxStyledTextEvent_GetDragText 2923
-#define wxStyledTextEvent_GetDragAllowMove 2924
-#define wxStyledTextEvent_GetDragResult 2925
-#define wxStyledTextEvent_GetShift 2926
-#define wxStyledTextEvent_GetControl 2927
-#define wxStyledTextEvent_GetAlt 2928
-#define utils_wxGetKeyState 2929
-#define utils_wxGetMousePosition 2930
-#define utils_wxGetMouseState 2931
-#define utils_wxSetDetectableAutoRepeat 2932
-#define utils_wxBell 2933
-#define utils_wxFindMenuItemId 2934
-#define utils_wxGenericFindWindowAtPoint 2935
-#define utils_wxFindWindowAtPoint 2936
-#define utils_wxBeginBusyCursor 2937
-#define utils_wxEndBusyCursor 2938
-#define utils_wxIsBusy 2939
-#define utils_wxShutdown 2940
-#define utils_wxShell 2941
-#define utils_wxLaunchDefaultBrowser 2942
-#define utils_wxGetEmailAddress 2943
-#define utils_wxGetUserId 2944
-#define utils_wxGetHomeDir 2945
-#define utils_wxNewId 2946
-#define utils_wxRegisterId 2947
-#define utils_wxGetCurrentId 2948
-#define utils_wxGetOsDescription 2949
-#define utils_wxIsPlatformLittleEndian 2950
-#define utils_wxIsPlatform64Bit 2951
-#define gdicmn_wxDisplaySize 2952
-#define gdicmn_wxSetCursor 2953
-#define wxPrintout_new 2954
-#define wxPrintout_destruct 2955
-#define wxPrintout_GetDC 2956
-#define wxPrintout_GetPageSizeMM 2957
-#define wxPrintout_GetPageSizePixels 2958
-#define wxPrintout_GetPaperRectPixels 2959
-#define wxPrintout_GetPPIPrinter 2960
-#define wxPrintout_GetPPIScreen 2961
-#define wxPrintout_GetTitle 2962
-#define wxPrintout_IsPreview 2963
-#define wxPrintout_FitThisSizeToPaper 2964
-#define wxPrintout_FitThisSizeToPage 2965
-#define wxPrintout_FitThisSizeToPageMargins 2966
-#define wxPrintout_MapScreenSizeToPaper 2967
-#define wxPrintout_MapScreenSizeToPage 2968
-#define wxPrintout_MapScreenSizeToPageMargins 2969
-#define wxPrintout_MapScreenSizeToDevice 2970
-#define wxPrintout_GetLogicalPaperRect 2971
-#define wxPrintout_GetLogicalPageRect 2972
-#define wxPrintout_GetLogicalPageMarginsRect 2973
-#define wxPrintout_SetLogicalOrigin 2974
-#define wxPrintout_OffsetLogicalOrigin 2975
-#define wxStyledTextCtrl_new_2 2976
-#define wxStyledTextCtrl_new_0 2977
-#define wxStyledTextCtrl_destruct 2978
-#define wxStyledTextCtrl_Create 2979
-#define wxStyledTextCtrl_AddText 2980
-#define wxStyledTextCtrl_AddStyledText 2981
-#define wxStyledTextCtrl_InsertText 2982
-#define wxStyledTextCtrl_ClearAll 2983
-#define wxStyledTextCtrl_ClearDocumentStyle 2984
-#define wxStyledTextCtrl_GetLength 2985
-#define wxStyledTextCtrl_GetCharAt 2986
-#define wxStyledTextCtrl_GetCurrentPos 2987
-#define wxStyledTextCtrl_GetAnchor 2988
-#define wxStyledTextCtrl_GetStyleAt 2989
-#define wxStyledTextCtrl_Redo 2990
-#define wxStyledTextCtrl_SetUndoCollection 2991
-#define wxStyledTextCtrl_SelectAll 2992
-#define wxStyledTextCtrl_SetSavePoint 2993
-#define wxStyledTextCtrl_GetStyledText 2994
-#define wxStyledTextCtrl_CanRedo 2995
-#define wxStyledTextCtrl_MarkerLineFromHandle 2996
-#define wxStyledTextCtrl_MarkerDeleteHandle 2997
-#define wxStyledTextCtrl_GetUndoCollection 2998
-#define wxStyledTextCtrl_GetViewWhiteSpace 2999
-#define wxStyledTextCtrl_SetViewWhiteSpace 3000
-#define wxStyledTextCtrl_PositionFromPoint 3001
-#define wxStyledTextCtrl_PositionFromPointClose 3002
-#define wxStyledTextCtrl_GotoLine 3003
-#define wxStyledTextCtrl_GotoPos 3004
-#define wxStyledTextCtrl_SetAnchor 3005
-#define wxStyledTextCtrl_GetCurLine 3006
-#define wxStyledTextCtrl_GetEndStyled 3007
-#define wxStyledTextCtrl_ConvertEOLs 3008
-#define wxStyledTextCtrl_GetEOLMode 3009
-#define wxStyledTextCtrl_SetEOLMode 3010
-#define wxStyledTextCtrl_StartStyling 3011
-#define wxStyledTextCtrl_SetStyling 3012
-#define wxStyledTextCtrl_GetBufferedDraw 3013
-#define wxStyledTextCtrl_SetBufferedDraw 3014
-#define wxStyledTextCtrl_SetTabWidth 3015
-#define wxStyledTextCtrl_GetTabWidth 3016
-#define wxStyledTextCtrl_SetCodePage 3017
-#define wxStyledTextCtrl_MarkerDefine 3018
-#define wxStyledTextCtrl_MarkerSetForeground 3019
-#define wxStyledTextCtrl_MarkerSetBackground 3020
-#define wxStyledTextCtrl_MarkerAdd 3021
-#define wxStyledTextCtrl_MarkerDelete 3022
-#define wxStyledTextCtrl_MarkerDeleteAll 3023
-#define wxStyledTextCtrl_MarkerGet 3024
-#define wxStyledTextCtrl_MarkerNext 3025
-#define wxStyledTextCtrl_MarkerPrevious 3026
-#define wxStyledTextCtrl_MarkerDefineBitmap 3027
-#define wxStyledTextCtrl_MarkerAddSet 3028
-#define wxStyledTextCtrl_MarkerSetAlpha 3029
-#define wxStyledTextCtrl_SetMarginType 3030
-#define wxStyledTextCtrl_GetMarginType 3031
-#define wxStyledTextCtrl_SetMarginWidth 3032
-#define wxStyledTextCtrl_GetMarginWidth 3033
-#define wxStyledTextCtrl_SetMarginMask 3034
-#define wxStyledTextCtrl_GetMarginMask 3035
-#define wxStyledTextCtrl_SetMarginSensitive 3036
-#define wxStyledTextCtrl_GetMarginSensitive 3037
-#define wxStyledTextCtrl_StyleClearAll 3038
-#define wxStyledTextCtrl_StyleSetForeground 3039
-#define wxStyledTextCtrl_StyleSetBackground 3040
-#define wxStyledTextCtrl_StyleSetBold 3041
-#define wxStyledTextCtrl_StyleSetItalic 3042
-#define wxStyledTextCtrl_StyleSetSize 3043
-#define wxStyledTextCtrl_StyleSetFaceName 3044
-#define wxStyledTextCtrl_StyleSetEOLFilled 3045
-#define wxStyledTextCtrl_StyleResetDefault 3046
-#define wxStyledTextCtrl_StyleSetUnderline 3047
-#define wxStyledTextCtrl_StyleSetCase 3048
-#define wxStyledTextCtrl_StyleSetHotSpot 3049
-#define wxStyledTextCtrl_SetSelForeground 3050
-#define wxStyledTextCtrl_SetSelBackground 3051
-#define wxStyledTextCtrl_GetSelAlpha 3052
-#define wxStyledTextCtrl_SetSelAlpha 3053
-#define wxStyledTextCtrl_SetCaretForeground 3054
-#define wxStyledTextCtrl_CmdKeyAssign 3055
-#define wxStyledTextCtrl_CmdKeyClear 3056
-#define wxStyledTextCtrl_CmdKeyClearAll 3057
-#define wxStyledTextCtrl_SetStyleBytes 3058
-#define wxStyledTextCtrl_StyleSetVisible 3059
-#define wxStyledTextCtrl_GetCaretPeriod 3060
-#define wxStyledTextCtrl_SetCaretPeriod 3061
-#define wxStyledTextCtrl_SetWordChars 3062
-#define wxStyledTextCtrl_BeginUndoAction 3063
-#define wxStyledTextCtrl_EndUndoAction 3064
-#define wxStyledTextCtrl_IndicatorSetStyle 3065
-#define wxStyledTextCtrl_IndicatorGetStyle 3066
-#define wxStyledTextCtrl_IndicatorSetForeground 3067
-#define wxStyledTextCtrl_IndicatorGetForeground 3068
-#define wxStyledTextCtrl_SetWhitespaceForeground 3069
-#define wxStyledTextCtrl_SetWhitespaceBackground 3070
-#define wxStyledTextCtrl_GetStyleBits 3071
-#define wxStyledTextCtrl_SetLineState 3072
-#define wxStyledTextCtrl_GetLineState 3073
-#define wxStyledTextCtrl_GetMaxLineState 3074
-#define wxStyledTextCtrl_GetCaretLineVisible 3075
-#define wxStyledTextCtrl_SetCaretLineVisible 3076
-#define wxStyledTextCtrl_GetCaretLineBackground 3077
-#define wxStyledTextCtrl_SetCaretLineBackground 3078
-#define wxStyledTextCtrl_AutoCompShow 3079
-#define wxStyledTextCtrl_AutoCompCancel 3080
-#define wxStyledTextCtrl_AutoCompActive 3081
-#define wxStyledTextCtrl_AutoCompPosStart 3082
-#define wxStyledTextCtrl_AutoCompComplete 3083
-#define wxStyledTextCtrl_AutoCompStops 3084
-#define wxStyledTextCtrl_AutoCompSetSeparator 3085
-#define wxStyledTextCtrl_AutoCompGetSeparator 3086
-#define wxStyledTextCtrl_AutoCompSelect 3087
-#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3088
-#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3089
-#define wxStyledTextCtrl_AutoCompSetFillUps 3090
-#define wxStyledTextCtrl_AutoCompSetChooseSingle 3091
-#define wxStyledTextCtrl_AutoCompGetChooseSingle 3092
-#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3093
-#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3094
-#define wxStyledTextCtrl_UserListShow 3095
-#define wxStyledTextCtrl_AutoCompSetAutoHide 3096
-#define wxStyledTextCtrl_AutoCompGetAutoHide 3097
-#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3098
-#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3099
-#define wxStyledTextCtrl_RegisterImage 3100
-#define wxStyledTextCtrl_ClearRegisteredImages 3101
-#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3102
-#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3103
-#define wxStyledTextCtrl_AutoCompSetMaxWidth 3104
-#define wxStyledTextCtrl_AutoCompGetMaxWidth 3105
-#define wxStyledTextCtrl_AutoCompSetMaxHeight 3106
-#define wxStyledTextCtrl_AutoCompGetMaxHeight 3107
-#define wxStyledTextCtrl_SetIndent 3108
-#define wxStyledTextCtrl_GetIndent 3109
-#define wxStyledTextCtrl_SetUseTabs 3110
-#define wxStyledTextCtrl_GetUseTabs 3111
-#define wxStyledTextCtrl_SetLineIndentation 3112
-#define wxStyledTextCtrl_GetLineIndentation 3113
-#define wxStyledTextCtrl_GetLineIndentPosition 3114
-#define wxStyledTextCtrl_GetColumn 3115
-#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3116
-#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3117
-#define wxStyledTextCtrl_SetIndentationGuides 3118
-#define wxStyledTextCtrl_GetIndentationGuides 3119
-#define wxStyledTextCtrl_SetHighlightGuide 3120
-#define wxStyledTextCtrl_GetHighlightGuide 3121
-#define wxStyledTextCtrl_GetLineEndPosition 3122
-#define wxStyledTextCtrl_GetCodePage 3123
-#define wxStyledTextCtrl_GetCaretForeground 3124
-#define wxStyledTextCtrl_GetReadOnly 3125
-#define wxStyledTextCtrl_SetCurrentPos 3126
-#define wxStyledTextCtrl_SetSelectionStart 3127
-#define wxStyledTextCtrl_GetSelectionStart 3128
-#define wxStyledTextCtrl_SetSelectionEnd 3129
-#define wxStyledTextCtrl_GetSelectionEnd 3130
-#define wxStyledTextCtrl_SetPrintMagnification 3131
-#define wxStyledTextCtrl_GetPrintMagnification 3132
-#define wxStyledTextCtrl_SetPrintColourMode 3133
-#define wxStyledTextCtrl_GetPrintColourMode 3134
-#define wxStyledTextCtrl_FindText 3135
-#define wxStyledTextCtrl_FormatRange 3136
-#define wxStyledTextCtrl_GetFirstVisibleLine 3137
-#define wxStyledTextCtrl_GetLine 3138
-#define wxStyledTextCtrl_GetLineCount 3139
-#define wxStyledTextCtrl_SetMarginLeft 3140
-#define wxStyledTextCtrl_GetMarginLeft 3141
-#define wxStyledTextCtrl_SetMarginRight 3142
-#define wxStyledTextCtrl_GetMarginRight 3143
-#define wxStyledTextCtrl_GetModify 3144
-#define wxStyledTextCtrl_SetSelection 3145
-#define wxStyledTextCtrl_GetSelectedText 3146
-#define wxStyledTextCtrl_GetTextRange 3147
-#define wxStyledTextCtrl_HideSelection 3148
-#define wxStyledTextCtrl_LineFromPosition 3149
-#define wxStyledTextCtrl_PositionFromLine 3150
-#define wxStyledTextCtrl_LineScroll 3151
-#define wxStyledTextCtrl_EnsureCaretVisible 3152
-#define wxStyledTextCtrl_ReplaceSelection 3153
-#define wxStyledTextCtrl_SetReadOnly 3154
-#define wxStyledTextCtrl_CanPaste 3155
-#define wxStyledTextCtrl_CanUndo 3156
-#define wxStyledTextCtrl_EmptyUndoBuffer 3157
-#define wxStyledTextCtrl_Undo 3158
-#define wxStyledTextCtrl_Cut 3159
-#define wxStyledTextCtrl_Copy 3160
-#define wxStyledTextCtrl_Paste 3161
-#define wxStyledTextCtrl_Clear 3162
-#define wxStyledTextCtrl_SetText 3163
-#define wxStyledTextCtrl_GetText 3164
-#define wxStyledTextCtrl_GetTextLength 3165
-#define wxStyledTextCtrl_GetOvertype 3166
-#define wxStyledTextCtrl_SetCaretWidth 3167
-#define wxStyledTextCtrl_GetCaretWidth 3168
-#define wxStyledTextCtrl_SetTargetStart 3169
-#define wxStyledTextCtrl_GetTargetStart 3170
-#define wxStyledTextCtrl_SetTargetEnd 3171
-#define wxStyledTextCtrl_GetTargetEnd 3172
-#define wxStyledTextCtrl_ReplaceTarget 3173
-#define wxStyledTextCtrl_SearchInTarget 3174
-#define wxStyledTextCtrl_SetSearchFlags 3175
-#define wxStyledTextCtrl_GetSearchFlags 3176
-#define wxStyledTextCtrl_CallTipShow 3177
-#define wxStyledTextCtrl_CallTipCancel 3178
-#define wxStyledTextCtrl_CallTipActive 3179
-#define wxStyledTextCtrl_CallTipPosAtStart 3180
-#define wxStyledTextCtrl_CallTipSetHighlight 3181
-#define wxStyledTextCtrl_CallTipSetBackground 3182
-#define wxStyledTextCtrl_CallTipSetForeground 3183
-#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3184
-#define wxStyledTextCtrl_CallTipUseStyle 3185
-#define wxStyledTextCtrl_VisibleFromDocLine 3186
-#define wxStyledTextCtrl_DocLineFromVisible 3187
-#define wxStyledTextCtrl_WrapCount 3188
-#define wxStyledTextCtrl_SetFoldLevel 3189
-#define wxStyledTextCtrl_GetFoldLevel 3190
-#define wxStyledTextCtrl_GetLastChild 3191
-#define wxStyledTextCtrl_GetFoldParent 3192
-#define wxStyledTextCtrl_ShowLines 3193
-#define wxStyledTextCtrl_HideLines 3194
-#define wxStyledTextCtrl_GetLineVisible 3195
-#define wxStyledTextCtrl_SetFoldExpanded 3196
-#define wxStyledTextCtrl_GetFoldExpanded 3197
-#define wxStyledTextCtrl_ToggleFold 3198
-#define wxStyledTextCtrl_EnsureVisible 3199
-#define wxStyledTextCtrl_SetFoldFlags 3200
-#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3201
-#define wxStyledTextCtrl_SetTabIndents 3202
-#define wxStyledTextCtrl_GetTabIndents 3203
-#define wxStyledTextCtrl_SetBackSpaceUnIndents 3204
-#define wxStyledTextCtrl_GetBackSpaceUnIndents 3205
-#define wxStyledTextCtrl_SetMouseDwellTime 3206
-#define wxStyledTextCtrl_GetMouseDwellTime 3207
-#define wxStyledTextCtrl_WordStartPosition 3208
-#define wxStyledTextCtrl_WordEndPosition 3209
-#define wxStyledTextCtrl_SetWrapMode 3210
-#define wxStyledTextCtrl_GetWrapMode 3211
-#define wxStyledTextCtrl_SetWrapVisualFlags 3212
-#define wxStyledTextCtrl_GetWrapVisualFlags 3213
-#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3214
-#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3215
-#define wxStyledTextCtrl_SetWrapStartIndent 3216
-#define wxStyledTextCtrl_GetWrapStartIndent 3217
-#define wxStyledTextCtrl_SetLayoutCache 3218
-#define wxStyledTextCtrl_GetLayoutCache 3219
-#define wxStyledTextCtrl_SetScrollWidth 3220
-#define wxStyledTextCtrl_GetScrollWidth 3221
-#define wxStyledTextCtrl_TextWidth 3222
-#define wxStyledTextCtrl_GetEndAtLastLine 3223
-#define wxStyledTextCtrl_TextHeight 3224
-#define wxStyledTextCtrl_SetUseVerticalScrollBar 3225
-#define wxStyledTextCtrl_GetUseVerticalScrollBar 3226
-#define wxStyledTextCtrl_AppendText 3227
-#define wxStyledTextCtrl_GetTwoPhaseDraw 3228
-#define wxStyledTextCtrl_SetTwoPhaseDraw 3229
-#define wxStyledTextCtrl_TargetFromSelection 3230
-#define wxStyledTextCtrl_LinesJoin 3231
-#define wxStyledTextCtrl_LinesSplit 3232
-#define wxStyledTextCtrl_SetFoldMarginColour 3233
-#define wxStyledTextCtrl_SetFoldMarginHiColour 3234
-#define wxStyledTextCtrl_LineDown 3235
-#define wxStyledTextCtrl_LineDownExtend 3236
-#define wxStyledTextCtrl_LineUp 3237
-#define wxStyledTextCtrl_LineUpExtend 3238
-#define wxStyledTextCtrl_CharLeft 3239
-#define wxStyledTextCtrl_CharLeftExtend 3240
-#define wxStyledTextCtrl_CharRight 3241
-#define wxStyledTextCtrl_CharRightExtend 3242
-#define wxStyledTextCtrl_WordLeft 3243
-#define wxStyledTextCtrl_WordLeftExtend 3244
-#define wxStyledTextCtrl_WordRight 3245
-#define wxStyledTextCtrl_WordRightExtend 3246
-#define wxStyledTextCtrl_Home 3247
-#define wxStyledTextCtrl_HomeExtend 3248
-#define wxStyledTextCtrl_LineEnd 3249
-#define wxStyledTextCtrl_LineEndExtend 3250
-#define wxStyledTextCtrl_DocumentStart 3251
-#define wxStyledTextCtrl_DocumentStartExtend 3252
-#define wxStyledTextCtrl_DocumentEnd 3253
-#define wxStyledTextCtrl_DocumentEndExtend 3254
-#define wxStyledTextCtrl_PageUp 3255
-#define wxStyledTextCtrl_PageUpExtend 3256
-#define wxStyledTextCtrl_PageDown 3257
-#define wxStyledTextCtrl_PageDownExtend 3258
-#define wxStyledTextCtrl_EditToggleOvertype 3259
-#define wxStyledTextCtrl_Cancel 3260
-#define wxStyledTextCtrl_DeleteBack 3261
-#define wxStyledTextCtrl_Tab 3262
-#define wxStyledTextCtrl_BackTab 3263
-#define wxStyledTextCtrl_NewLine 3264
-#define wxStyledTextCtrl_FormFeed 3265
-#define wxStyledTextCtrl_VCHome 3266
-#define wxStyledTextCtrl_VCHomeExtend 3267
-#define wxStyledTextCtrl_ZoomIn 3268
-#define wxStyledTextCtrl_ZoomOut 3269
-#define wxStyledTextCtrl_DelWordLeft 3270
-#define wxStyledTextCtrl_DelWordRight 3271
-#define wxStyledTextCtrl_LineCut 3272
-#define wxStyledTextCtrl_LineDelete 3273
-#define wxStyledTextCtrl_LineTranspose 3274
-#define wxStyledTextCtrl_LineDuplicate 3275
-#define wxStyledTextCtrl_LowerCase 3276
-#define wxStyledTextCtrl_UpperCase 3277
-#define wxStyledTextCtrl_LineScrollDown 3278
-#define wxStyledTextCtrl_LineScrollUp 3279
-#define wxStyledTextCtrl_DeleteBackNotLine 3280
-#define wxStyledTextCtrl_HomeDisplay 3281
-#define wxStyledTextCtrl_HomeDisplayExtend 3282
-#define wxStyledTextCtrl_LineEndDisplay 3283
-#define wxStyledTextCtrl_LineEndDisplayExtend 3284
-#define wxStyledTextCtrl_HomeWrapExtend 3285
-#define wxStyledTextCtrl_LineEndWrap 3286
-#define wxStyledTextCtrl_LineEndWrapExtend 3287
-#define wxStyledTextCtrl_VCHomeWrap 3288
-#define wxStyledTextCtrl_VCHomeWrapExtend 3289
-#define wxStyledTextCtrl_LineCopy 3290
-#define wxStyledTextCtrl_MoveCaretInsideView 3291
-#define wxStyledTextCtrl_LineLength 3292
-#define wxStyledTextCtrl_BraceHighlight 3293
-#define wxStyledTextCtrl_BraceBadLight 3294
-#define wxStyledTextCtrl_BraceMatch 3295
-#define wxStyledTextCtrl_GetViewEOL 3296
-#define wxStyledTextCtrl_SetViewEOL 3297
-#define wxStyledTextCtrl_SetModEventMask 3298
-#define wxStyledTextCtrl_GetEdgeColumn 3299
-#define wxStyledTextCtrl_SetEdgeColumn 3300
-#define wxStyledTextCtrl_SetEdgeMode 3301
-#define wxStyledTextCtrl_GetEdgeMode 3302
-#define wxStyledTextCtrl_GetEdgeColour 3303
-#define wxStyledTextCtrl_SetEdgeColour 3304
-#define wxStyledTextCtrl_SearchAnchor 3305
-#define wxStyledTextCtrl_SearchNext 3306
-#define wxStyledTextCtrl_SearchPrev 3307
-#define wxStyledTextCtrl_LinesOnScreen 3308
-#define wxStyledTextCtrl_UsePopUp 3309
-#define wxStyledTextCtrl_SelectionIsRectangle 3310
-#define wxStyledTextCtrl_SetZoom 3311
-#define wxStyledTextCtrl_GetZoom 3312
-#define wxStyledTextCtrl_GetModEventMask 3313
-#define wxStyledTextCtrl_SetSTCFocus 3314
-#define wxStyledTextCtrl_GetSTCFocus 3315
-#define wxStyledTextCtrl_SetStatus 3316
-#define wxStyledTextCtrl_GetStatus 3317
-#define wxStyledTextCtrl_SetMouseDownCaptures 3318
-#define wxStyledTextCtrl_GetMouseDownCaptures 3319
-#define wxStyledTextCtrl_SetSTCCursor 3320
-#define wxStyledTextCtrl_GetSTCCursor 3321
-#define wxStyledTextCtrl_SetControlCharSymbol 3322
-#define wxStyledTextCtrl_GetControlCharSymbol 3323
-#define wxStyledTextCtrl_WordPartLeft 3324
-#define wxStyledTextCtrl_WordPartLeftExtend 3325
-#define wxStyledTextCtrl_WordPartRight 3326
-#define wxStyledTextCtrl_WordPartRightExtend 3327
-#define wxStyledTextCtrl_SetVisiblePolicy 3328
-#define wxStyledTextCtrl_DelLineLeft 3329
-#define wxStyledTextCtrl_DelLineRight 3330
-#define wxStyledTextCtrl_GetXOffset 3331
-#define wxStyledTextCtrl_ChooseCaretX 3332
-#define wxStyledTextCtrl_SetXCaretPolicy 3333
-#define wxStyledTextCtrl_SetYCaretPolicy 3334
-#define wxStyledTextCtrl_GetPrintWrapMode 3335
-#define wxStyledTextCtrl_SetHotspotActiveForeground 3336
-#define wxStyledTextCtrl_SetHotspotActiveBackground 3337
-#define wxStyledTextCtrl_SetHotspotActiveUnderline 3338
-#define wxStyledTextCtrl_SetHotspotSingleLine 3339
-#define wxStyledTextCtrl_ParaDownExtend 3340
-#define wxStyledTextCtrl_ParaUp 3341
-#define wxStyledTextCtrl_ParaUpExtend 3342
-#define wxStyledTextCtrl_PositionBefore 3343
-#define wxStyledTextCtrl_PositionAfter 3344
-#define wxStyledTextCtrl_CopyRange 3345
-#define wxStyledTextCtrl_CopyText 3346
-#define wxStyledTextCtrl_SetSelectionMode 3347
-#define wxStyledTextCtrl_GetSelectionMode 3348
-#define wxStyledTextCtrl_LineDownRectExtend 3349
-#define wxStyledTextCtrl_LineUpRectExtend 3350
-#define wxStyledTextCtrl_CharLeftRectExtend 3351
-#define wxStyledTextCtrl_CharRightRectExtend 3352
-#define wxStyledTextCtrl_HomeRectExtend 3353
-#define wxStyledTextCtrl_VCHomeRectExtend 3354
-#define wxStyledTextCtrl_LineEndRectExtend 3355
-#define wxStyledTextCtrl_PageUpRectExtend 3356
-#define wxStyledTextCtrl_PageDownRectExtend 3357
-#define wxStyledTextCtrl_StutteredPageUp 3358
-#define wxStyledTextCtrl_StutteredPageUpExtend 3359
-#define wxStyledTextCtrl_StutteredPageDown 3360
-#define wxStyledTextCtrl_StutteredPageDownExtend 3361
-#define wxStyledTextCtrl_WordLeftEnd 3362
-#define wxStyledTextCtrl_WordLeftEndExtend 3363
-#define wxStyledTextCtrl_WordRightEnd 3364
-#define wxStyledTextCtrl_WordRightEndExtend 3365
-#define wxStyledTextCtrl_SetWhitespaceChars 3366
-#define wxStyledTextCtrl_SetCharsDefault 3367
-#define wxStyledTextCtrl_AutoCompGetCurrent 3368
-#define wxStyledTextCtrl_Allocate 3369
-#define wxStyledTextCtrl_FindColumn 3370
-#define wxStyledTextCtrl_GetCaretSticky 3371
-#define wxStyledTextCtrl_SetCaretSticky 3372
-#define wxStyledTextCtrl_ToggleCaretSticky 3373
-#define wxStyledTextCtrl_SetPasteConvertEndings 3374
-#define wxStyledTextCtrl_GetPasteConvertEndings 3375
-#define wxStyledTextCtrl_SelectionDuplicate 3376
-#define wxStyledTextCtrl_SetCaretLineBackAlpha 3377
-#define wxStyledTextCtrl_GetCaretLineBackAlpha 3378
-#define wxStyledTextCtrl_StartRecord 3379
-#define wxStyledTextCtrl_StopRecord 3380
-#define wxStyledTextCtrl_SetLexer 3381
-#define wxStyledTextCtrl_GetLexer 3382
-#define wxStyledTextCtrl_Colourise 3383
-#define wxStyledTextCtrl_SetProperty 3384
-#define wxStyledTextCtrl_SetKeyWords 3385
-#define wxStyledTextCtrl_SetLexerLanguage 3386
-#define wxStyledTextCtrl_GetProperty 3387
-#define wxStyledTextCtrl_GetStyleBitsNeeded 3388
-#define wxStyledTextCtrl_GetCurrentLine 3389
-#define wxStyledTextCtrl_StyleSetSpec 3390
-#define wxStyledTextCtrl_StyleSetFont 3391
-#define wxStyledTextCtrl_StyleSetFontAttr 3392
-#define wxStyledTextCtrl_StyleSetCharacterSet 3393
-#define wxStyledTextCtrl_StyleSetFontEncoding 3394
-#define wxStyledTextCtrl_CmdKeyExecute 3395
-#define wxStyledTextCtrl_SetMargins 3396
-#define wxStyledTextCtrl_GetSelection 3397
-#define wxStyledTextCtrl_PointFromPosition 3398
-#define wxStyledTextCtrl_ScrollToLine 3399
-#define wxStyledTextCtrl_ScrollToColumn 3400
-#define wxStyledTextCtrl_SetVScrollBar 3401
-#define wxStyledTextCtrl_SetHScrollBar 3402
-#define wxStyledTextCtrl_GetLastKeydownProcessed 3403
-#define wxStyledTextCtrl_SetLastKeydownProcessed 3404
-#define wxStyledTextCtrl_SaveFile 3405
-#define wxStyledTextCtrl_LoadFile 3406
-#define wxStyledTextCtrl_DoDragOver 3407
-#define wxStyledTextCtrl_DoDropText 3408
-#define wxStyledTextCtrl_GetUseAntiAliasing 3409
-#define wxStyledTextCtrl_AddTextRaw 3410
-#define wxStyledTextCtrl_InsertTextRaw 3411
-#define wxStyledTextCtrl_GetCurLineRaw 3412
-#define wxStyledTextCtrl_GetLineRaw 3413
-#define wxStyledTextCtrl_GetSelectedTextRaw 3414
-#define wxStyledTextCtrl_GetTextRangeRaw 3415
-#define wxStyledTextCtrl_SetTextRaw 3416
-#define wxStyledTextCtrl_GetTextRaw 3417
-#define wxStyledTextCtrl_AppendTextRaw 3418
-#define wxArtProvider_GetBitmap 3419
-#define wxArtProvider_GetIcon 3420
-#define wxTreeEvent_GetKeyCode 3421
-#define wxTreeEvent_GetItem 3422
-#define wxTreeEvent_GetKeyEvent 3423
-#define wxTreeEvent_GetLabel 3424
-#define wxTreeEvent_GetOldItem 3425
-#define wxTreeEvent_GetPoint 3426
-#define wxTreeEvent_IsEditCancelled 3427
-#define wxTreeEvent_SetToolTip 3428
-#define wxNotebookEvent_GetOldSelection 3429
-#define wxNotebookEvent_GetSelection 3430
-#define wxNotebookEvent_SetOldSelection 3431
-#define wxNotebookEvent_SetSelection 3432
-#define wxFileDataObject_new 3433
-#define wxFileDataObject_AddFile 3434
-#define wxFileDataObject_GetFilenames 3435
-#define wxFileDataObject_destroy 3436
-#define wxTextDataObject_new 3437
-#define wxTextDataObject_GetTextLength 3438
-#define wxTextDataObject_GetText 3439
-#define wxTextDataObject_SetText 3440
-#define wxTextDataObject_destroy 3441
-#define wxBitmapDataObject_new_1_1 3442
-#define wxBitmapDataObject_new_1_0 3443
-#define wxBitmapDataObject_GetBitmap 3444
-#define wxBitmapDataObject_SetBitmap 3445
-#define wxBitmapDataObject_destroy 3446
-#define wxClipboard_new 3448
-#define wxClipboard_destruct 3449
-#define wxClipboard_AddData 3450
-#define wxClipboard_Clear 3451
-#define wxClipboard_Close 3452
-#define wxClipboard_Flush 3453
-#define wxClipboard_GetData 3454
-#define wxClipboard_IsOpened 3455
-#define wxClipboard_Open 3456
-#define wxClipboard_SetData 3457
-#define wxClipboard_UsePrimarySelection 3459
-#define wxClipboard_IsSupported 3460
-#define wxClipboard_Get 3461
-#define wxSpinEvent_GetPosition 3462
-#define wxSpinEvent_SetPosition 3463
-#define wxSplitterWindow_new_0 3464
-#define wxSplitterWindow_new_2 3465
-#define wxSplitterWindow_destruct 3466
-#define wxSplitterWindow_Create 3467
-#define wxSplitterWindow_GetMinimumPaneSize 3468
-#define wxSplitterWindow_GetSashGravity 3469
-#define wxSplitterWindow_GetSashPosition 3470
-#define wxSplitterWindow_GetSplitMode 3471
-#define wxSplitterWindow_GetWindow1 3472
-#define wxSplitterWindow_GetWindow2 3473
-#define wxSplitterWindow_Initialize 3474
-#define wxSplitterWindow_IsSplit 3475
-#define wxSplitterWindow_ReplaceWindow 3476
-#define wxSplitterWindow_SetSashGravity 3477
-#define wxSplitterWindow_SetSashPosition 3478
-#define wxSplitterWindow_SetSashSize 3479
-#define wxSplitterWindow_SetMinimumPaneSize 3480
-#define wxSplitterWindow_SetSplitMode 3481
-#define wxSplitterWindow_SplitHorizontally 3482
-#define wxSplitterWindow_SplitVertically 3483
-#define wxSplitterWindow_Unsplit 3484
-#define wxSplitterWindow_UpdateSize 3485
-#define wxSplitterEvent_GetSashPosition 3486
-#define wxSplitterEvent_GetX 3487
-#define wxSplitterEvent_GetY 3488
-#define wxSplitterEvent_GetWindowBeingRemoved 3489
-#define wxSplitterEvent_SetSashPosition 3490
-#define wxHtmlWindow_new_0 3491
-#define wxHtmlWindow_new_2 3492
-#define wxHtmlWindow_AppendToPage 3493
-#define wxHtmlWindow_GetOpenedAnchor 3494
-#define wxHtmlWindow_GetOpenedPage 3495
-#define wxHtmlWindow_GetOpenedPageTitle 3496
-#define wxHtmlWindow_GetRelatedFrame 3497
-#define wxHtmlWindow_HistoryBack 3498
-#define wxHtmlWindow_HistoryCanBack 3499
-#define wxHtmlWindow_HistoryCanForward 3500
-#define wxHtmlWindow_HistoryClear 3501
-#define wxHtmlWindow_HistoryForward 3502
-#define wxHtmlWindow_LoadFile 3503
-#define wxHtmlWindow_LoadPage 3504
-#define wxHtmlWindow_SelectAll 3505
-#define wxHtmlWindow_SelectionToText 3506
-#define wxHtmlWindow_SelectLine 3507
-#define wxHtmlWindow_SelectWord 3508
-#define wxHtmlWindow_SetBorders 3509
-#define wxHtmlWindow_SetFonts 3510
-#define wxHtmlWindow_SetPage 3511
-#define wxHtmlWindow_SetRelatedFrame 3512
-#define wxHtmlWindow_SetRelatedStatusBar 3513
-#define wxHtmlWindow_ToText 3514
-#define wxHtmlWindow_destroy 3515
-#define wxHtmlLinkEvent_GetLinkInfo 3516
-#define wxSystemSettings_GetColour 3517
-#define wxSystemSettings_GetFont 3518
-#define wxSystemSettings_GetMetric 3519
-#define wxSystemSettings_GetScreenType 3520
-#define wxSystemOptions_GetOption 3521
-#define wxSystemOptions_GetOptionInt 3522
-#define wxSystemOptions_HasOption 3523
-#define wxSystemOptions_IsFalse 3524
-#define wxSystemOptions_SetOption_2_1 3525
-#define wxSystemOptions_SetOption_2_0 3526
-#define wxAuiNotebookEvent_SetSelection 3527
-#define wxAuiNotebookEvent_GetSelection 3528
-#define wxAuiNotebookEvent_SetOldSelection 3529
-#define wxAuiNotebookEvent_GetOldSelection 3530
-#define wxAuiNotebookEvent_SetDragSource 3531
-#define wxAuiNotebookEvent_GetDragSource 3532
-#define wxAuiManagerEvent_SetManager 3533
-#define wxAuiManagerEvent_GetManager 3534
-#define wxAuiManagerEvent_SetPane 3535
-#define wxAuiManagerEvent_GetPane 3536
-#define wxAuiManagerEvent_SetButton 3537
-#define wxAuiManagerEvent_GetButton 3538
-#define wxAuiManagerEvent_SetDC 3539
-#define wxAuiManagerEvent_GetDC 3540
-#define wxAuiManagerEvent_Veto 3541
-#define wxAuiManagerEvent_GetVeto 3542
-#define wxAuiManagerEvent_SetCanVeto 3543
-#define wxAuiManagerEvent_CanVeto 3544
-#define wxLogNull_new 3545
-#define wxLogNull_destroy 3546
-#define wxTaskBarIcon_new 3547
-#define wxTaskBarIcon_destruct 3548
-#define wxTaskBarIcon_PopupMenu 3549
-#define wxTaskBarIcon_RemoveIcon 3550
-#define wxTaskBarIcon_SetIcon 3551
-#define wxLocale_new_0 3552
-#define wxLocale_new_2 3554
-#define wxLocale_destruct 3555
-#define wxLocale_Init 3557
-#define wxLocale_AddCatalog_1 3558
-#define wxLocale_AddCatalog_3 3559
-#define wxLocale_AddCatalogLookupPathPrefix 3560
-#define wxLocale_GetCanonicalName 3561
-#define wxLocale_GetLanguage 3562
-#define wxLocale_GetLanguageName 3563
-#define wxLocale_GetLocale 3564
-#define wxLocale_GetName 3565
-#define wxLocale_GetString_2 3566
-#define wxLocale_GetString_4 3567
-#define wxLocale_GetHeaderValue 3568
-#define wxLocale_GetSysName 3569
-#define wxLocale_GetSystemEncoding 3570
-#define wxLocale_GetSystemEncodingName 3571
-#define wxLocale_GetSystemLanguage 3572
-#define wxLocale_IsLoaded 3573
-#define wxLocale_IsOk 3574
-#define wxActivateEvent_GetActive 3575
-#define wxPopupWindow_new_2 3577
-#define wxPopupWindow_new_0 3578
-#define wxPopupWindow_destruct 3580
-#define wxPopupWindow_Create 3581
-#define wxPopupWindow_Position 3582
-#define wxPopupTransientWindow_new_0 3583
-#define wxPopupTransientWindow_new_2 3584
-#define wxPopupTransientWindow_destruct 3585
-#define wxPopupTransientWindow_Popup 3586
-#define wxPopupTransientWindow_Dismiss 3587
-#define wxOverlay_new 3588
-#define wxOverlay_destruct 3589
-#define wxOverlay_Reset 3590
-#define wxDCOverlay_new_6 3591
-#define wxDCOverlay_new_2 3592
-#define wxDCOverlay_destruct 3593
-#define wxDCOverlay_Clear 3594
+#define wxWindow_DragAcceptFiles 126
+#define wxWindow_Enable 127
+#define wxWindow_FindFocus 128
+#define wxWindow_FindWindow_1_0 129
+#define wxWindow_FindWindow_1_1 130
+#define wxWindow_FindWindowById 131
+#define wxWindow_FindWindowByName 132
+#define wxWindow_FindWindowByLabel 133
+#define wxWindow_Fit 134
+#define wxWindow_FitInside 135
+#define wxWindow_Freeze 136
+#define wxWindow_GetAcceleratorTable 137
+#define wxWindow_GetBackgroundColour 138
+#define wxWindow_GetBackgroundStyle 139
+#define wxWindow_GetBestSize 140
+#define wxWindow_GetCaret 142
+#define wxWindow_GetCapture 143
+#define wxWindow_GetCharHeight 144
+#define wxWindow_GetCharWidth 145
+#define wxWindow_GetChildren 146
+#define wxWindow_GetClientSize 149
+#define wxWindow_GetContainingSizer 150
+#define wxWindow_GetCursor 151
+#define wxWindow_GetDropTarget 152
+#define wxWindow_GetEventHandler 153
+#define wxWindow_GetExtraStyle 154
+#define wxWindow_GetFont 155
+#define wxWindow_GetForegroundColour 156
+#define wxWindow_GetGrandParent 157
+#define wxWindow_GetHandle 158
+#define wxWindow_GetHelpText 159
+#define wxWindow_GetId 160
+#define wxWindow_GetLabel 161
+#define wxWindow_GetMaxSize 162
+#define wxWindow_GetMinSize 163
+#define wxWindow_GetName 164
+#define wxWindow_GetParent 165
+#define wxWindow_GetPosition 167
+#define wxWindow_GetRect 168
+#define wxWindow_GetScreenPosition 170
+#define wxWindow_GetScreenRect 171
+#define wxWindow_GetScrollPos 172
+#define wxWindow_GetScrollRange 173
+#define wxWindow_GetScrollThumb 174
+#define wxWindow_GetSize 176
+#define wxWindow_GetSizer 177
+#define wxWindow_GetTextExtent 178
+#define wxWindow_GetToolTip 179
+#define wxWindow_GetUpdateRegion 180
+#define wxWindow_GetVirtualSize 182
+#define wxWindow_GetWindowStyleFlag 184
+#define wxWindow_GetWindowVariant 185
+#define wxWindow_HasCapture 186
+#define wxWindow_HasScrollbar 187
+#define wxWindow_HasTransparentBackground 188
+#define wxWindow_Hide 189
+#define wxWindow_InheritAttributes 190
+#define wxWindow_InitDialog 191
+#define wxWindow_InvalidateBestSize 192
+#define wxWindow_IsEnabled 193
+#define wxWindow_IsExposed_2 194
+#define wxWindow_IsExposed_4 195
+#define wxWindow_IsExposed_1_0 196
+#define wxWindow_IsExposed_1_1 197
+#define wxWindow_IsRetained 198
+#define wxWindow_IsShown 199
+#define wxWindow_IsTopLevel 200
+#define wxWindow_Layout 201
+#define wxWindow_LineDown 202
+#define wxWindow_LineUp 203
+#define wxWindow_Lower 204
+#define wxWindow_MakeModal 205
+#define wxWindow_Move_3 206
+#define wxWindow_Move_2 207
+#define wxWindow_MoveAfterInTabOrder 208
+#define wxWindow_MoveBeforeInTabOrder 209
+#define wxWindow_Navigate 210
+#define wxWindow_PageDown 211
+#define wxWindow_PageUp 212
+#define wxWindow_PopEventHandler 213
+#define wxWindow_PopupMenu_2 214
+#define wxWindow_PopupMenu_3 215
+#define wxWindow_Raise 216
+#define wxWindow_Refresh 217
+#define wxWindow_RefreshRect 218
+#define wxWindow_ReleaseMouse 219
+#define wxWindow_RemoveChild 220
+#define wxWindow_Reparent 221
+#define wxWindow_ScreenToClient_2 222
+#define wxWindow_ScreenToClient_1 223
+#define wxWindow_ScrollLines 225
+#define wxWindow_ScrollPages 227
+#define wxWindow_ScrollWindow 228
+#define wxWindow_SetAcceleratorTable 229
+#define wxWindow_SetAutoLayout 230
+#define wxWindow_SetBackgroundColour 231
+#define wxWindow_SetBackgroundStyle 232
+#define wxWindow_SetCaret 233
+#define wxWindow_SetClientSize_2 234
+#define wxWindow_SetClientSize_1_0 235
+#define wxWindow_SetClientSize_1_1 236
+#define wxWindow_SetContainingSizer 237
+#define wxWindow_SetCursor 238
+#define wxWindow_SetMaxSize 239
+#define wxWindow_SetMinSize 240
+#define wxWindow_SetOwnBackgroundColour 241
+#define wxWindow_SetOwnFont 242
+#define wxWindow_SetOwnForegroundColour 243
+#define wxWindow_SetDropTarget 244
+#define wxWindow_SetExtraStyle 245
+#define wxWindow_SetFocus 246
+#define wxWindow_SetFocusFromKbd 247
+#define wxWindow_SetFont 248
+#define wxWindow_SetForegroundColour 249
+#define wxWindow_SetHelpText 250
+#define wxWindow_SetId 251
+#define wxWindow_SetLabel 253
+#define wxWindow_SetName 254
+#define wxWindow_SetPalette 255
+#define wxWindow_SetScrollbar 256
+#define wxWindow_SetScrollPos 257
+#define wxWindow_SetSize_5 258
+#define wxWindow_SetSize_2_0 259
+#define wxWindow_SetSize_1 260
+#define wxWindow_SetSize_2_1 261
+#define wxWindow_SetSizeHints_3 262
+#define wxWindow_SetSizeHints_2 263
+#define wxWindow_SetSizer 264
+#define wxWindow_SetSizerAndFit 265
+#define wxWindow_SetThemeEnabled 266
+#define wxWindow_SetToolTip_1_0 267
+#define wxWindow_SetToolTip_1_1 268
+#define wxWindow_SetVirtualSize_1 269
+#define wxWindow_SetVirtualSize_2 270
+#define wxWindow_SetVirtualSizeHints_3 271
+#define wxWindow_SetVirtualSizeHints_2 272
+#define wxWindow_SetWindowStyle 273
+#define wxWindow_SetWindowStyleFlag 274
+#define wxWindow_SetWindowVariant 275
+#define wxWindow_ShouldInheritColours 276
+#define wxWindow_Show 277
+#define wxWindow_Thaw 278
+#define wxWindow_TransferDataFromWindow 279
+#define wxWindow_TransferDataToWindow 280
+#define wxWindow_Update 281
+#define wxWindow_UpdateWindowUI 282
+#define wxWindow_Validate 283
+#define wxWindow_WarpPointer 284
+#define wxWindow_SetTransparent 285
+#define wxWindow_CanSetTransparent 286
+#define wxWindow_IsDoubleBuffered 287
+#define wxWindow_SetDoubleBuffered 288
+#define wxWindow_GetContentScaleFactor 289
+#define wxTopLevelWindow_GetIcon 290
+#define wxTopLevelWindow_GetIcons 291
+#define wxTopLevelWindow_GetTitle 292
+#define wxTopLevelWindow_IsActive 293
+#define wxTopLevelWindow_Iconize 294
+#define wxTopLevelWindow_IsFullScreen 295
+#define wxTopLevelWindow_IsIconized 296
+#define wxTopLevelWindow_IsMaximized 297
+#define wxTopLevelWindow_Maximize 298
+#define wxTopLevelWindow_RequestUserAttention 299
+#define wxTopLevelWindow_SetIcon 300
+#define wxTopLevelWindow_SetIcons 301
+#define wxTopLevelWindow_CenterOnScreen 302
+#define wxTopLevelWindow_CentreOnScreen 303
+#define wxTopLevelWindow_SetShape 305
+#define wxTopLevelWindow_SetTitle 306
+#define wxTopLevelWindow_ShowFullScreen 307
+#define wxFrame_new_4 309
+#define wxFrame_new_0 310
+#define wxFrame_destruct 312
+#define wxFrame_Create 313
+#define wxFrame_CreateStatusBar 314
+#define wxFrame_CreateToolBar 315
+#define wxFrame_GetClientAreaOrigin 316
+#define wxFrame_GetMenuBar 317
+#define wxFrame_GetStatusBar 318
+#define wxFrame_GetStatusBarPane 319
+#define wxFrame_GetToolBar 320
+#define wxFrame_ProcessCommand 321
+#define wxFrame_SendSizeEvent 322
+#define wxFrame_SetMenuBar 323
+#define wxFrame_SetStatusBar 324
+#define wxFrame_SetStatusBarPane 325
+#define wxFrame_SetStatusText 326
+#define wxFrame_SetStatusWidths 327
+#define wxFrame_SetToolBar 328
+#define wxMiniFrame_new_0 329
+#define wxMiniFrame_new_4 330
+#define wxMiniFrame_Create 331
+#define wxMiniFrame_destroy 332
+#define wxSplashScreen_new_0 333
+#define wxSplashScreen_new_6 334
+#define wxSplashScreen_destruct 335
+#define wxSplashScreen_GetSplashStyle 336
+#define wxSplashScreen_GetTimeout 337
+#define wxPanel_new_0 338
+#define wxPanel_new_6 339
+#define wxPanel_new_2 340
+#define wxPanel_destruct 341
+#define wxPanel_InitDialog 342
+#define wxPanel_SetFocusIgnoringChildren 343
+#define wxScrolledWindow_new_0 344
+#define wxScrolledWindow_new_2 345
+#define wxScrolledWindow_destruct 346
+#define wxScrolledWindow_CalcScrolledPosition_4 347
+#define wxScrolledWindow_CalcScrolledPosition_1 348
+#define wxScrolledWindow_CalcUnscrolledPosition_4 349
+#define wxScrolledWindow_CalcUnscrolledPosition_1 350
+#define wxScrolledWindow_EnableScrolling 351
+#define wxScrolledWindow_GetScrollPixelsPerUnit 352
+#define wxScrolledWindow_GetViewStart 353
+#define wxScrolledWindow_DoPrepareDC 354
+#define wxScrolledWindow_PrepareDC 355
+#define wxScrolledWindow_Scroll 356
+#define wxScrolledWindow_SetScrollbars 357
+#define wxScrolledWindow_SetScrollRate 358
+#define wxScrolledWindow_SetTargetWindow 359
+#define wxSashWindow_new_0 360
+#define wxSashWindow_new_2 361
+#define wxSashWindow_destruct 362
+#define wxSashWindow_GetSashVisible 363
+#define wxSashWindow_GetMaximumSizeX 364
+#define wxSashWindow_GetMaximumSizeY 365
+#define wxSashWindow_GetMinimumSizeX 366
+#define wxSashWindow_GetMinimumSizeY 367
+#define wxSashWindow_SetMaximumSizeX 368
+#define wxSashWindow_SetMaximumSizeY 369
+#define wxSashWindow_SetMinimumSizeX 370
+#define wxSashWindow_SetMinimumSizeY 371
+#define wxSashWindow_SetSashVisible 372
+#define wxSashLayoutWindow_new_0 373
+#define wxSashLayoutWindow_new_2 374
+#define wxSashLayoutWindow_Create 375
+#define wxSashLayoutWindow_GetAlignment 376
+#define wxSashLayoutWindow_GetOrientation 377
+#define wxSashLayoutWindow_SetAlignment 378
+#define wxSashLayoutWindow_SetDefaultSize 379
+#define wxSashLayoutWindow_SetOrientation 380
+#define wxSashLayoutWindow_destroy 381
+#define wxGrid_new_0 382
+#define wxGrid_new_3 383
+#define wxGrid_new_4 384
+#define wxGrid_destruct 385
+#define wxGrid_AppendCols 386
+#define wxGrid_AppendRows 387
+#define wxGrid_AutoSize 388
+#define wxGrid_AutoSizeColumn 389
+#define wxGrid_AutoSizeColumns 390
+#define wxGrid_AutoSizeRow 391
+#define wxGrid_AutoSizeRows 392
+#define wxGrid_BeginBatch 393
+#define wxGrid_BlockToDeviceRect 394
+#define wxGrid_CanDragColSize 395
+#define wxGrid_CanDragRowSize 396
+#define wxGrid_CanDragGridSize 397
+#define wxGrid_CanEnableCellControl 398
+#define wxGrid_CellToRect_2 399
+#define wxGrid_CellToRect_1 400
+#define wxGrid_ClearGrid 401
+#define wxGrid_ClearSelection 402
+#define wxGrid_CreateGrid 403
+#define wxGrid_DeleteCols 404
+#define wxGrid_DeleteRows 405
+#define wxGrid_DisableCellEditControl 406
+#define wxGrid_DisableDragColSize 407
+#define wxGrid_DisableDragGridSize 408
+#define wxGrid_DisableDragRowSize 409
+#define wxGrid_EnableCellEditControl 410
+#define wxGrid_EnableDragColSize 411
+#define wxGrid_EnableDragGridSize 412
+#define wxGrid_EnableDragRowSize 413
+#define wxGrid_EnableEditing 414
+#define wxGrid_EnableGridLines 415
+#define wxGrid_EndBatch 416
+#define wxGrid_Fit 417
+#define wxGrid_ForceRefresh 418
+#define wxGrid_GetBatchCount 419
+#define wxGrid_GetCellAlignment 420
+#define wxGrid_GetCellBackgroundColour 421
+#define wxGrid_GetCellEditor 422
+#define wxGrid_GetCellFont 423
+#define wxGrid_GetCellRenderer 424
+#define wxGrid_GetCellTextColour 425
+#define wxGrid_GetCellValue_2 426
+#define wxGrid_GetCellValue_1 427
+#define wxGrid_GetColLabelAlignment 428
+#define wxGrid_GetColLabelSize 429
+#define wxGrid_GetColLabelValue 430
+#define wxGrid_GetColMinimalAcceptableWidth 431
+#define wxGrid_GetDefaultCellAlignment 432
+#define wxGrid_GetDefaultCellBackgroundColour 433
+#define wxGrid_GetDefaultCellFont 434
+#define wxGrid_GetDefaultCellTextColour 435
+#define wxGrid_GetDefaultColLabelSize 436
+#define wxGrid_GetDefaultColSize 437
+#define wxGrid_GetDefaultEditor 438
+#define wxGrid_GetDefaultEditorForCell_2 439
+#define wxGrid_GetDefaultEditorForCell_1 440
+#define wxGrid_GetDefaultEditorForType 441
+#define wxGrid_GetDefaultRenderer 442
+#define wxGrid_GetDefaultRendererForCell 443
+#define wxGrid_GetDefaultRendererForType 444
+#define wxGrid_GetDefaultRowLabelSize 445
+#define wxGrid_GetDefaultRowSize 446
+#define wxGrid_GetGridCursorCol 447
+#define wxGrid_GetGridCursorRow 448
+#define wxGrid_GetGridLineColour 449
+#define wxGrid_GridLinesEnabled 450
+#define wxGrid_GetLabelBackgroundColour 451
+#define wxGrid_GetLabelFont 452
+#define wxGrid_GetLabelTextColour 453
+#define wxGrid_GetNumberCols 454
+#define wxGrid_GetNumberRows 455
+#define wxGrid_GetOrCreateCellAttr 456
+#define wxGrid_GetRowMinimalAcceptableHeight 457
+#define wxGrid_GetRowLabelAlignment 458
+#define wxGrid_GetRowLabelSize 459
+#define wxGrid_GetRowLabelValue 460
+#define wxGrid_GetRowSize 461
+#define wxGrid_GetScrollLineX 462
+#define wxGrid_GetScrollLineY 463
+#define wxGrid_GetSelectedCells 464
+#define wxGrid_GetSelectedCols 465
+#define wxGrid_GetSelectedRows 466
+#define wxGrid_GetSelectionBackground 467
+#define wxGrid_GetSelectionBlockTopLeft 468
+#define wxGrid_GetSelectionBlockBottomRight 469
+#define wxGrid_GetSelectionForeground 470
+#define wxGrid_GetViewWidth 471
+#define wxGrid_GetGridWindow 472
+#define wxGrid_GetGridRowLabelWindow 473
+#define wxGrid_GetGridColLabelWindow 474
+#define wxGrid_GetGridCornerLabelWindow 475
+#define wxGrid_HideCellEditControl 476
+#define wxGrid_InsertCols 477
+#define wxGrid_InsertRows 478
+#define wxGrid_IsCellEditControlEnabled 479
+#define wxGrid_IsCurrentCellReadOnly 480
+#define wxGrid_IsEditable 481
+#define wxGrid_IsInSelection_2 482
+#define wxGrid_IsInSelection_1 483
+#define wxGrid_IsReadOnly 484
+#define wxGrid_IsSelection 485
+#define wxGrid_IsVisible_3 486
+#define wxGrid_IsVisible_2 487
+#define wxGrid_MakeCellVisible_2 488
+#define wxGrid_MakeCellVisible_1 489
+#define wxGrid_MoveCursorDown 490
+#define wxGrid_MoveCursorLeft 491
+#define wxGrid_MoveCursorRight 492
+#define wxGrid_MoveCursorUp 493
+#define wxGrid_MoveCursorDownBlock 494
+#define wxGrid_MoveCursorLeftBlock 495
+#define wxGrid_MoveCursorRightBlock 496
+#define wxGrid_MoveCursorUpBlock 497
+#define wxGrid_MovePageDown 498
+#define wxGrid_MovePageUp 499
+#define wxGrid_RegisterDataType 500
+#define wxGrid_SaveEditControlValue 501
+#define wxGrid_SelectAll 502
+#define wxGrid_SelectBlock_5 503
+#define wxGrid_SelectBlock_3 504
+#define wxGrid_SelectCol 505
+#define wxGrid_SelectRow 506
+#define wxGrid_SetCellAlignment_4 507
+#define wxGrid_SetCellAlignment_3 508
+#define wxGrid_SetCellAlignment_1 509
+#define wxGrid_SetCellBackgroundColour_3_0 510
+#define wxGrid_SetCellBackgroundColour_1 511
+#define wxGrid_SetCellBackgroundColour_3_1 512
+#define wxGrid_SetCellEditor 513
+#define wxGrid_SetCellFont 514
+#define wxGrid_SetCellRenderer 515
+#define wxGrid_SetCellTextColour_3_0 516
+#define wxGrid_SetCellTextColour_3_1 517
+#define wxGrid_SetCellTextColour_1 518
+#define wxGrid_SetCellValue_3_0 519
+#define wxGrid_SetCellValue_2 520
+#define wxGrid_SetCellValue_3_1 521
+#define wxGrid_SetColAttr 522
+#define wxGrid_SetColFormatBool 523
+#define wxGrid_SetColFormatNumber 524
+#define wxGrid_SetColFormatFloat 525
+#define wxGrid_SetColFormatCustom 526
+#define wxGrid_SetColLabelAlignment 527
+#define wxGrid_SetColLabelSize 528
+#define wxGrid_SetColLabelValue 529
+#define wxGrid_SetColMinimalWidth 530
+#define wxGrid_SetColMinimalAcceptableWidth 531
+#define wxGrid_SetColSize 532
+#define wxGrid_SetDefaultCellAlignment 533
+#define wxGrid_SetDefaultCellBackgroundColour 534
+#define wxGrid_SetDefaultCellFont 535
+#define wxGrid_SetDefaultCellTextColour 536
+#define wxGrid_SetDefaultEditor 537
+#define wxGrid_SetDefaultRenderer 538
+#define wxGrid_SetDefaultColSize 539
+#define wxGrid_SetDefaultRowSize 540
+#define wxGrid_SetGridCursor 541
+#define wxGrid_SetGridLineColour 542
+#define wxGrid_SetLabelBackgroundColour 543
+#define wxGrid_SetLabelFont 544
+#define wxGrid_SetLabelTextColour 545
+#define wxGrid_SetMargins 546
+#define wxGrid_SetReadOnly 547
+#define wxGrid_SetRowAttr 548
+#define wxGrid_SetRowLabelAlignment 549
+#define wxGrid_SetRowLabelSize 550
+#define wxGrid_SetRowLabelValue 551
+#define wxGrid_SetRowMinimalHeight 552
+#define wxGrid_SetRowMinimalAcceptableHeight 553
+#define wxGrid_SetRowSize 554
+#define wxGrid_SetScrollLineX 555
+#define wxGrid_SetScrollLineY 556
+#define wxGrid_SetSelectionBackground 557
+#define wxGrid_SetSelectionForeground 558
+#define wxGrid_SetSelectionMode 559
+#define wxGrid_ShowCellEditControl 560
+#define wxGrid_XToCol 561
+#define wxGrid_XToEdgeOfCol 562
+#define wxGrid_YToEdgeOfRow 563
+#define wxGrid_YToRow 564
+#define wxGridCellRenderer_Draw 565
+#define wxGridCellRenderer_GetBestSize 566
+#define wxGridCellEditor_Create 567
+#define wxGridCellEditor_IsCreated 568
+#define wxGridCellEditor_SetSize 569
+#define wxGridCellEditor_Show 570
+#define wxGridCellEditor_PaintBackground 571
+#define wxGridCellEditor_BeginEdit 572
+#define wxGridCellEditor_EndEdit 573
+#define wxGridCellEditor_Reset 574
+#define wxGridCellEditor_StartingKey 575
+#define wxGridCellEditor_StartingClick 576
+#define wxGridCellEditor_HandleReturn 577
+#define wxGridCellBoolRenderer_new 578
+#define wxGridCellBoolRenderer_destroy 579
+#define wxGridCellBoolEditor_new 580
+#define wxGridCellBoolEditor_IsTrueValue 581
+#define wxGridCellBoolEditor_UseStringValues 582
+#define wxGridCellBoolEditor_destroy 583
+#define wxGridCellFloatRenderer_new 584
+#define wxGridCellFloatRenderer_GetPrecision 585
+#define wxGridCellFloatRenderer_GetWidth 586
+#define wxGridCellFloatRenderer_SetParameters 587
+#define wxGridCellFloatRenderer_SetPrecision 588
+#define wxGridCellFloatRenderer_SetWidth 589
+#define wxGridCellFloatRenderer_destroy 590
+#define wxGridCellFloatEditor_new 591
+#define wxGridCellFloatEditor_SetParameters 592
+#define wxGridCellFloatEditor_destroy 593
+#define wxGridCellStringRenderer_new 594
+#define wxGridCellStringRenderer_destroy 595
+#define wxGridCellTextEditor_new 596
+#define wxGridCellTextEditor_SetParameters 597
+#define wxGridCellTextEditor_destroy 598
+#define wxGridCellChoiceEditor_new 600
+#define wxGridCellChoiceEditor_SetParameters 601
+#define wxGridCellChoiceEditor_destroy 602
+#define wxGridCellNumberRenderer_new 603
+#define wxGridCellNumberRenderer_destroy 604
+#define wxGridCellNumberEditor_new 605
+#define wxGridCellNumberEditor_GetValue 606
+#define wxGridCellNumberEditor_SetParameters 607
+#define wxGridCellNumberEditor_destroy 608
+#define wxGridCellAttr_SetTextColour 609
+#define wxGridCellAttr_SetBackgroundColour 610
+#define wxGridCellAttr_SetFont 611
+#define wxGridCellAttr_SetAlignment 612
+#define wxGridCellAttr_SetReadOnly 613
+#define wxGridCellAttr_SetRenderer 614
+#define wxGridCellAttr_SetEditor 615
+#define wxGridCellAttr_HasTextColour 616
+#define wxGridCellAttr_HasBackgroundColour 617
+#define wxGridCellAttr_HasFont 618
+#define wxGridCellAttr_HasAlignment 619
+#define wxGridCellAttr_HasRenderer 620
+#define wxGridCellAttr_HasEditor 621
+#define wxGridCellAttr_GetTextColour 622
+#define wxGridCellAttr_GetBackgroundColour 623
+#define wxGridCellAttr_GetFont 624
+#define wxGridCellAttr_GetAlignment 625
+#define wxGridCellAttr_GetRenderer 626
+#define wxGridCellAttr_GetEditor 627
+#define wxGridCellAttr_IsReadOnly 628
+#define wxGridCellAttr_SetDefAttr 629
+#define wxDC_Blit 630
+#define wxDC_CalcBoundingBox 631
+#define wxDC_Clear 632
+#define wxDC_ComputeScaleAndOrigin 633
+#define wxDC_CrossHair 634
+#define wxDC_DestroyClippingRegion 635
+#define wxDC_DeviceToLogicalX 636
+#define wxDC_DeviceToLogicalXRel 637
+#define wxDC_DeviceToLogicalY 638
+#define wxDC_DeviceToLogicalYRel 639
+#define wxDC_DrawArc 640
+#define wxDC_DrawBitmap 641
+#define wxDC_DrawCheckMark 642
+#define wxDC_DrawCircle 643
+#define wxDC_DrawEllipse_2 645
+#define wxDC_DrawEllipse_1 646
+#define wxDC_DrawEllipticArc 647
+#define wxDC_DrawIcon 648
+#define wxDC_DrawLabel 649
+#define wxDC_DrawLine 650
+#define wxDC_DrawLines 651
+#define wxDC_DrawPolygon 653
+#define wxDC_DrawPoint 655
+#define wxDC_DrawRectangle_2 657
+#define wxDC_DrawRectangle_1 658
+#define wxDC_DrawRotatedText 659
+#define wxDC_DrawRoundedRectangle_3 661
+#define wxDC_DrawRoundedRectangle_2 662
+#define wxDC_DrawText 663
+#define wxDC_EndDoc 664
+#define wxDC_EndPage 665
+#define wxDC_FloodFill 666
+#define wxDC_GetBackground 667
+#define wxDC_GetBackgroundMode 668
+#define wxDC_GetBrush 669
+#define wxDC_GetCharHeight 670
+#define wxDC_GetCharWidth 671
+#define wxDC_GetClippingBox 672
+#define wxDC_GetFont 674
+#define wxDC_GetLayoutDirection 675
+#define wxDC_GetLogicalFunction 676
+#define wxDC_GetMapMode 677
+#define wxDC_GetMultiLineTextExtent_4 678
+#define wxDC_GetMultiLineTextExtent_1 679
+#define wxDC_GetPartialTextExtents 680
+#define wxDC_GetPen 681
+#define wxDC_GetPixel 682
+#define wxDC_GetPPI 683
+#define wxDC_GetSize 685
+#define wxDC_GetSizeMM 687
+#define wxDC_GetTextBackground 688
+#define wxDC_GetTextExtent_4 689
+#define wxDC_GetTextExtent_1 690
+#define wxDC_GetTextForeground 692
+#define wxDC_GetUserScale 693
+#define wxDC_GradientFillConcentric_3 694
+#define wxDC_GradientFillConcentric_4 695
+#define wxDC_GradientFillLinear 696
+#define wxDC_LogicalToDeviceX 697
+#define wxDC_LogicalToDeviceXRel 698
+#define wxDC_LogicalToDeviceY 699
+#define wxDC_LogicalToDeviceYRel 700
+#define wxDC_MaxX 701
+#define wxDC_MaxY 702
+#define wxDC_MinX 703
+#define wxDC_MinY 704
+#define wxDC_IsOk 705
+#define wxDC_ResetBoundingBox 706
+#define wxDC_SetAxisOrientation 707
+#define wxDC_SetBackground 708
+#define wxDC_SetBackgroundMode 709
+#define wxDC_SetBrush 710
+#define wxDC_SetClippingRegion_2 712
+#define wxDC_SetClippingRegion_1_1 713
+#define wxDC_SetClippingRegion_1_0 714
+#define wxDC_SetDeviceOrigin 715
+#define wxDC_SetFont 716
+#define wxDC_SetLayoutDirection 717
+#define wxDC_SetLogicalFunction 718
+#define wxDC_SetMapMode 719
+#define wxDC_SetPalette 720
+#define wxDC_SetPen 721
+#define wxDC_SetTextBackground 722
+#define wxDC_SetTextForeground 723
+#define wxDC_SetUserScale 724
+#define wxDC_StartDoc 725
+#define wxDC_StartPage 726
+#define wxMirrorDC_new 727
+#define wxMirrorDC_destroy 728
+#define wxScreenDC_new 729
+#define wxScreenDC_destruct 730
+#define wxPostScriptDC_new_0 731
+#define wxPostScriptDC_new_1 732
+#define wxPostScriptDC_destruct 733
+#define wxPostScriptDC_SetResolution 734
+#define wxPostScriptDC_GetResolution 735
+#define wxWindowDC_new_0 736
+#define wxWindowDC_new_1 737
+#define wxWindowDC_destruct 738
+#define wxClientDC_new_0 739
+#define wxClientDC_new_1 740
+#define wxClientDC_destroy 741
+#define wxPaintDC_new_0 742
+#define wxPaintDC_new_1 743
+#define wxPaintDC_destroy 744
+#define wxMemoryDC_new_1_0 746
+#define wxMemoryDC_new_1_1 747
+#define wxMemoryDC_new_0 748
+#define wxMemoryDC_destruct 750
+#define wxMemoryDC_SelectObject 751
+#define wxMemoryDC_SelectObjectAsSource 752
+#define wxBufferedDC_new_0 753
+#define wxBufferedDC_new_2 754
+#define wxBufferedDC_new_3 755
+#define wxBufferedDC_destruct 756
+#define wxBufferedDC_Init_2 757
+#define wxBufferedDC_Init_3 758
+#define wxBufferedPaintDC_new_3 759
+#define wxBufferedPaintDC_new_2 760
+#define wxBufferedPaintDC_destruct 761
+#define wxGraphicsObject_destruct 762
+#define wxGraphicsObject_GetRenderer 763
+#define wxGraphicsObject_IsNull 764
+#define wxGraphicsContext_destruct 765
+#define wxGraphicsContext_Create_1_1 766
+#define wxGraphicsContext_Create_1_0 767
+#define wxGraphicsContext_Create_0 768
+#define wxGraphicsContext_CreatePen 769
+#define wxGraphicsContext_CreateBrush 770
+#define wxGraphicsContext_CreateRadialGradientBrush 771
+#define wxGraphicsContext_CreateLinearGradientBrush 772
+#define wxGraphicsContext_CreateFont 773
+#define wxGraphicsContext_CreateMatrix 774
+#define wxGraphicsContext_CreatePath 775
+#define wxGraphicsContext_Clip_1 776
+#define wxGraphicsContext_Clip_4 777
+#define wxGraphicsContext_ResetClip 778
+#define wxGraphicsContext_DrawBitmap 779
+#define wxGraphicsContext_DrawEllipse 780
+#define wxGraphicsContext_DrawIcon 781
+#define wxGraphicsContext_DrawLines 782
+#define wxGraphicsContext_DrawPath 783
+#define wxGraphicsContext_DrawRectangle 784
+#define wxGraphicsContext_DrawRoundedRectangle 785
+#define wxGraphicsContext_DrawText_3 786
+#define wxGraphicsContext_DrawText_4_0 787
+#define wxGraphicsContext_DrawText_4_1 788
+#define wxGraphicsContext_DrawText_5 789
+#define wxGraphicsContext_FillPath 790
+#define wxGraphicsContext_StrokePath 791
+#define wxGraphicsContext_GetPartialTextExtents 792
+#define wxGraphicsContext_GetTextExtent 793
+#define wxGraphicsContext_Rotate 794
+#define wxGraphicsContext_Scale 795
+#define wxGraphicsContext_Translate 796
+#define wxGraphicsContext_GetTransform 797
+#define wxGraphicsContext_SetTransform 798
+#define wxGraphicsContext_ConcatTransform 799
+#define wxGraphicsContext_SetBrush_1_1 800
+#define wxGraphicsContext_SetBrush_1_0 801
+#define wxGraphicsContext_SetFont_1 802
+#define wxGraphicsContext_SetFont_2 803
+#define wxGraphicsContext_SetPen_1_0 804
+#define wxGraphicsContext_SetPen_1_1 805
+#define wxGraphicsContext_StrokeLine 806
+#define wxGraphicsContext_StrokeLines 807
+#define wxGraphicsMatrix_Concat 809
+#define wxGraphicsMatrix_Get 811
+#define wxGraphicsMatrix_Invert 812
+#define wxGraphicsMatrix_IsEqual 813
+#define wxGraphicsMatrix_IsIdentity 815
+#define wxGraphicsMatrix_Rotate 816
+#define wxGraphicsMatrix_Scale 817
+#define wxGraphicsMatrix_Translate 818
+#define wxGraphicsMatrix_Set 819
+#define wxGraphicsMatrix_TransformPoint 820
+#define wxGraphicsMatrix_TransformDistance 821
+#define wxGraphicsPath_MoveToPoint_2 822
+#define wxGraphicsPath_MoveToPoint_1 823
+#define wxGraphicsPath_AddArc_6 824
+#define wxGraphicsPath_AddArc_5 825
+#define wxGraphicsPath_AddArcToPoint 826
+#define wxGraphicsPath_AddCircle 827
+#define wxGraphicsPath_AddCurveToPoint_6 828
+#define wxGraphicsPath_AddCurveToPoint_3 829
+#define wxGraphicsPath_AddEllipse 830
+#define wxGraphicsPath_AddLineToPoint_2 831
+#define wxGraphicsPath_AddLineToPoint_1 832
+#define wxGraphicsPath_AddPath 833
+#define wxGraphicsPath_AddQuadCurveToPoint 834
+#define wxGraphicsPath_AddRectangle 835
+#define wxGraphicsPath_AddRoundedRectangle 836
+#define wxGraphicsPath_CloseSubpath 837
+#define wxGraphicsPath_Contains_3 838
+#define wxGraphicsPath_Contains_2 839
+#define wxGraphicsPath_GetBox 841
+#define wxGraphicsPath_GetCurrentPoint 843
+#define wxGraphicsPath_Transform 844
+#define wxGraphicsRenderer_GetDefaultRenderer 845
+#define wxGraphicsRenderer_CreateContext_1_1 846
+#define wxGraphicsRenderer_CreateContext_1_0 847
+#define wxGraphicsRenderer_CreatePen 848
+#define wxGraphicsRenderer_CreateBrush 849
+#define wxGraphicsRenderer_CreateLinearGradientBrush 850
+#define wxGraphicsRenderer_CreateRadialGradientBrush 851
+#define wxGraphicsRenderer_CreateFont 852
+#define wxGraphicsRenderer_CreateMatrix 853
+#define wxGraphicsRenderer_CreatePath 854
+#define wxMenuBar_new_1 856
+#define wxMenuBar_new_0 858
+#define wxMenuBar_destruct 860
+#define wxMenuBar_Append 861
+#define wxMenuBar_Check 862
+#define wxMenuBar_Enable_2 863
+#define wxMenuBar_Enable_1 864
+#define wxMenuBar_EnableTop 865
+#define wxMenuBar_FindMenu 866
+#define wxMenuBar_FindMenuItem 867
+#define wxMenuBar_FindItem 868
+#define wxMenuBar_GetHelpString 869
+#define wxMenuBar_GetLabel_1 870
+#define wxMenuBar_GetLabel_0 871
+#define wxMenuBar_GetLabelTop 872
+#define wxMenuBar_GetMenu 873
+#define wxMenuBar_GetMenuCount 874
+#define wxMenuBar_Insert 875
+#define wxMenuBar_IsChecked 876
+#define wxMenuBar_IsEnabled_1 877
+#define wxMenuBar_IsEnabled_0 878
+#define wxMenuBar_Remove 879
+#define wxMenuBar_Replace 880
+#define wxMenuBar_SetHelpString 881
+#define wxMenuBar_SetLabel_2 882
+#define wxMenuBar_SetLabel_1 883
+#define wxMenuBar_SetLabelTop 884
+#define wxControl_GetLabel 885
+#define wxControl_SetLabel 886
+#define wxControlWithItems_Append_1 887
+#define wxControlWithItems_Append_2 888
+#define wxControlWithItems_appendStrings_1 889
+#define wxControlWithItems_Clear 890
+#define wxControlWithItems_Delete 891
+#define wxControlWithItems_FindString 892
+#define wxControlWithItems_getClientData 893
+#define wxControlWithItems_setClientData 894
+#define wxControlWithItems_GetCount 895
+#define wxControlWithItems_GetSelection 896
+#define wxControlWithItems_GetString 897
+#define wxControlWithItems_GetStringSelection 898
+#define wxControlWithItems_Insert_2 899
+#define wxControlWithItems_Insert_3 900
+#define wxControlWithItems_IsEmpty 901
+#define wxControlWithItems_Select 902
+#define wxControlWithItems_SetSelection 903
+#define wxControlWithItems_SetString 904
+#define wxControlWithItems_SetStringSelection 905
+#define wxMenu_new_2 908
+#define wxMenu_new_1 909
+#define wxMenu_destruct 911
+#define wxMenu_Append_3 912
+#define wxMenu_Append_1 913
+#define wxMenu_Append_4_0 914
+#define wxMenu_Append_4_1 915
+#define wxMenu_AppendCheckItem 916
+#define wxMenu_AppendRadioItem 917
+#define wxMenu_AppendSeparator 918
+#define wxMenu_Break 919
+#define wxMenu_Check 920
+#define wxMenu_Delete_1_0 921
+#define wxMenu_Delete_1_1 922
+#define wxMenu_Destroy_1_0 923
+#define wxMenu_Destroy_1_1 924
+#define wxMenu_Enable 925
+#define wxMenu_FindItem_1 926
+#define wxMenu_FindItem_2 927
+#define wxMenu_FindItemByPosition 928
+#define wxMenu_GetHelpString 929
+#define wxMenu_GetLabel 930
+#define wxMenu_GetMenuItemCount 931
+#define wxMenu_GetMenuItems 932
+#define wxMenu_GetTitle 934
+#define wxMenu_Insert_2 935
+#define wxMenu_Insert_3 936
+#define wxMenu_Insert_5_1 937
+#define wxMenu_Insert_5_0 938
+#define wxMenu_InsertCheckItem 939
+#define wxMenu_InsertRadioItem 940
+#define wxMenu_InsertSeparator 941
+#define wxMenu_IsChecked 942
+#define wxMenu_IsEnabled 943
+#define wxMenu_Prepend_1 944
+#define wxMenu_Prepend_2 945
+#define wxMenu_Prepend_4_1 946
+#define wxMenu_Prepend_4_0 947
+#define wxMenu_PrependCheckItem 948
+#define wxMenu_PrependRadioItem 949
+#define wxMenu_PrependSeparator 950
+#define wxMenu_Remove_1_0 951
+#define wxMenu_Remove_1_1 952
+#define wxMenu_SetHelpString 953
+#define wxMenu_SetLabel 954
+#define wxMenu_SetTitle 955
+#define wxMenuItem_new 956
+#define wxMenuItem_destruct 958
+#define wxMenuItem_Check 959
+#define wxMenuItem_Enable 960
+#define wxMenuItem_GetBitmap 961
+#define wxMenuItem_GetHelp 962
+#define wxMenuItem_GetId 963
+#define wxMenuItem_GetKind 964
+#define wxMenuItem_GetLabel 965
+#define wxMenuItem_GetLabelFromText 966
+#define wxMenuItem_GetMenu 967
+#define wxMenuItem_GetText 968
+#define wxMenuItem_GetSubMenu 969
+#define wxMenuItem_IsCheckable 970
+#define wxMenuItem_IsChecked 971
+#define wxMenuItem_IsEnabled 972
+#define wxMenuItem_IsSeparator 973
+#define wxMenuItem_IsSubMenu 974
+#define wxMenuItem_SetBitmap 975
+#define wxMenuItem_SetHelp 976
+#define wxMenuItem_SetMenu 977
+#define wxMenuItem_SetSubMenu 978
+#define wxMenuItem_SetText 979
+#define wxToolBar_AddControl 980
+#define wxToolBar_AddSeparator 981
+#define wxToolBar_AddTool_5 982
+#define wxToolBar_AddTool_4_0 983
+#define wxToolBar_AddTool_1 984
+#define wxToolBar_AddTool_4_1 985
+#define wxToolBar_AddTool_3 986
+#define wxToolBar_AddTool_6 987
+#define wxToolBar_AddCheckTool 988
+#define wxToolBar_AddRadioTool 989
+#define wxToolBar_AddStretchableSpace 990
+#define wxToolBar_InsertStretchableSpace 991
+#define wxToolBar_DeleteTool 992
+#define wxToolBar_DeleteToolByPos 993
+#define wxToolBar_EnableTool 994
+#define wxToolBar_FindById 995
+#define wxToolBar_FindControl 996
+#define wxToolBar_FindToolForPosition 997
+#define wxToolBar_GetToolSize 998
+#define wxToolBar_GetToolBitmapSize 999
+#define wxToolBar_GetMargins 1000
+#define wxToolBar_GetToolEnabled 1001
+#define wxToolBar_GetToolLongHelp 1002
+#define wxToolBar_GetToolPacking 1003
+#define wxToolBar_GetToolPos 1004
+#define wxToolBar_GetToolSeparation 1005
+#define wxToolBar_GetToolShortHelp 1006
+#define wxToolBar_GetToolState 1007
+#define wxToolBar_InsertControl 1008
+#define wxToolBar_InsertSeparator 1009
+#define wxToolBar_InsertTool_5 1010
+#define wxToolBar_InsertTool_2 1011
+#define wxToolBar_InsertTool_4 1012
+#define wxToolBar_Realize 1013
+#define wxToolBar_RemoveTool 1014
+#define wxToolBar_SetMargins 1015
+#define wxToolBar_SetToolBitmapSize 1016
+#define wxToolBar_SetToolLongHelp 1017
+#define wxToolBar_SetToolPacking 1018
+#define wxToolBar_SetToolShortHelp 1019
+#define wxToolBar_SetToolSeparation 1020
+#define wxToolBar_ToggleTool 1021
+#define wxStatusBar_new_0 1023
+#define wxStatusBar_new_2 1024
+#define wxStatusBar_destruct 1026
+#define wxStatusBar_Create 1027
+#define wxStatusBar_GetFieldRect 1028
+#define wxStatusBar_GetFieldsCount 1029
+#define wxStatusBar_GetStatusText 1030
+#define wxStatusBar_PopStatusText 1031
+#define wxStatusBar_PushStatusText 1032
+#define wxStatusBar_SetFieldsCount 1033
+#define wxStatusBar_SetMinHeight 1034
+#define wxStatusBar_SetStatusText 1035
+#define wxStatusBar_SetStatusWidths 1036
+#define wxStatusBar_SetStatusStyles 1037
+#define wxBitmap_new_0 1038
+#define wxBitmap_new_3 1039
+#define wxBitmap_new_4 1040
+#define wxBitmap_new_2_0 1041
+#define wxBitmap_new_2_1 1042
+#define wxBitmap_destruct 1043
+#define wxBitmap_ConvertToImage 1044
+#define wxBitmap_CopyFromIcon 1045
+#define wxBitmap_Create 1046
+#define wxBitmap_GetDepth 1047
+#define wxBitmap_GetHeight 1048
+#define wxBitmap_GetPalette 1049
+#define wxBitmap_GetMask 1050
+#define wxBitmap_GetWidth 1051
+#define wxBitmap_GetSubBitmap 1052
+#define wxBitmap_LoadFile 1053
+#define wxBitmap_Ok 1054
+#define wxBitmap_SaveFile 1055
+#define wxBitmap_SetDepth 1056
+#define wxBitmap_SetHeight 1057
+#define wxBitmap_SetMask 1058
+#define wxBitmap_SetPalette 1059
+#define wxBitmap_SetWidth 1060
+#define wxIcon_new_0 1061
+#define wxIcon_new_2 1062
+#define wxIcon_new_1 1063
+#define wxIcon_CopyFromBitmap 1064
+#define wxIcon_destroy 1065
+#define wxIconBundle_new_0 1066
+#define wxIconBundle_new_2 1067
+#define wxIconBundle_new_1_0 1068
+#define wxIconBundle_new_1_1 1069
+#define wxIconBundle_destruct 1070
+#define wxIconBundle_AddIcon_2 1071
+#define wxIconBundle_AddIcon_1 1072
+#define wxIconBundle_GetIcon_1_1 1073
+#define wxIconBundle_GetIcon_1_0 1074
+#define wxCursor_new_0 1075
+#define wxCursor_new_1_0 1076
+#define wxCursor_new_1_1 1077
+#define wxCursor_new_4 1078
+#define wxCursor_destruct 1079
+#define wxCursor_Ok 1080
+#define wxMask_new_0 1081
+#define wxMask_new_2_1 1082
+#define wxMask_new_2_0 1083
+#define wxMask_new_1 1084
+#define wxMask_destruct 1085
+#define wxMask_Create_2_1 1086
+#define wxMask_Create_2_0 1087
+#define wxMask_Create_1 1088
+#define wxImage_new_0 1089
+#define wxImage_new_3_0 1090
+#define wxImage_new_4 1091
+#define wxImage_new_5 1092
+#define wxImage_new_2 1093
+#define wxImage_new_3_1 1094
+#define wxImage_Blur 1095
+#define wxImage_BlurHorizontal 1096
+#define wxImage_BlurVertical 1097
+#define wxImage_ConvertAlphaToMask 1098
+#define wxImage_ConvertToGreyscale 1099
+#define wxImage_ConvertToMono 1100
+#define wxImage_Copy 1101
+#define wxImage_Create_3 1102
+#define wxImage_Create_4 1103
+#define wxImage_Create_5 1104
+#define wxImage_Destroy 1105
+#define wxImage_FindFirstUnusedColour 1106
+#define wxImage_GetImageExtWildcard 1107
+#define wxImage_GetAlpha_2 1108
+#define wxImage_GetAlpha_0 1109
+#define wxImage_GetBlue 1110
+#define wxImage_GetData 1111
+#define wxImage_GetGreen 1112
+#define wxImage_GetImageCount 1113
+#define wxImage_GetHeight 1114
+#define wxImage_GetMaskBlue 1115
+#define wxImage_GetMaskGreen 1116
+#define wxImage_GetMaskRed 1117
+#define wxImage_GetOrFindMaskColour 1118
+#define wxImage_GetPalette 1119
+#define wxImage_GetRed 1120
+#define wxImage_GetSubImage 1121
+#define wxImage_GetWidth 1122
+#define wxImage_HasAlpha 1123
+#define wxImage_HasMask 1124
+#define wxImage_GetOption 1125
+#define wxImage_GetOptionInt 1126
+#define wxImage_HasOption 1127
+#define wxImage_InitAlpha 1128
+#define wxImage_InitStandardHandlers 1129
+#define wxImage_IsTransparent 1130
+#define wxImage_LoadFile_2 1131
+#define wxImage_LoadFile_3 1132
+#define wxImage_Ok 1133
+#define wxImage_RemoveHandler 1134
+#define wxImage_Mirror 1135
+#define wxImage_Replace 1136
+#define wxImage_Rescale 1137
+#define wxImage_Resize 1138
+#define wxImage_Rotate 1139
+#define wxImage_RotateHue 1140
+#define wxImage_Rotate90 1141
+#define wxImage_SaveFile_1 1142
+#define wxImage_SaveFile_2_0 1143
+#define wxImage_SaveFile_2_1 1144
+#define wxImage_Scale 1145
+#define wxImage_Size 1146
+#define wxImage_SetAlpha_3 1147
+#define wxImage_SetAlpha_2 1148
+#define wxImage_SetData_2 1149
+#define wxImage_SetData_4 1150
+#define wxImage_SetMask 1151
+#define wxImage_SetMaskColour 1152
+#define wxImage_SetMaskFromImage 1153
+#define wxImage_SetOption_2_1 1154
+#define wxImage_SetOption_2_0 1155
+#define wxImage_SetPalette 1156
+#define wxImage_SetRGB_5 1157
+#define wxImage_SetRGB_4 1158
+#define wxImage_destroy 1159
+#define wxBrush_new_0 1160
+#define wxBrush_new_2 1161
+#define wxBrush_new_1 1162
+#define wxBrush_destruct 1164
+#define wxBrush_GetColour 1165
+#define wxBrush_GetStipple 1166
+#define wxBrush_GetStyle 1167
+#define wxBrush_IsHatch 1168
+#define wxBrush_IsOk 1169
+#define wxBrush_SetColour_1 1170
+#define wxBrush_SetColour_3 1171
+#define wxBrush_SetStipple 1172
+#define wxBrush_SetStyle 1173
+#define wxPen_new_0 1174
+#define wxPen_new_2 1175
+#define wxPen_destruct 1176
+#define wxPen_GetCap 1177
+#define wxPen_GetColour 1178
+#define wxPen_GetJoin 1179
+#define wxPen_GetStyle 1180
+#define wxPen_GetWidth 1181
+#define wxPen_IsOk 1182
+#define wxPen_SetCap 1183
+#define wxPen_SetColour_1 1184
+#define wxPen_SetColour_3 1185
+#define wxPen_SetJoin 1186
+#define wxPen_SetStyle 1187
+#define wxPen_SetWidth 1188
+#define wxRegion_new_0 1189
+#define wxRegion_new_4 1190
+#define wxRegion_new_2 1191
+#define wxRegion_new_1_1 1192
+#define wxRegion_new_1_0 1194
+#define wxRegion_destruct 1196
+#define wxRegion_Clear 1197
+#define wxRegion_Contains_2 1198
+#define wxRegion_Contains_1_0 1199
+#define wxRegion_Contains_4 1200
+#define wxRegion_Contains_1_1 1201
+#define wxRegion_ConvertToBitmap 1202
+#define wxRegion_GetBox 1203
+#define wxRegion_Intersect_4 1204
+#define wxRegion_Intersect_1_1 1205
+#define wxRegion_Intersect_1_0 1206
+#define wxRegion_IsEmpty 1207
+#define wxRegion_Subtract_4 1208
+#define wxRegion_Subtract_1_1 1209
+#define wxRegion_Subtract_1_0 1210
+#define wxRegion_Offset_2 1211
+#define wxRegion_Offset_1 1212
+#define wxRegion_Union_4 1213
+#define wxRegion_Union_1_2 1214
+#define wxRegion_Union_1_1 1215
+#define wxRegion_Union_1_0 1216
+#define wxRegion_Union_3 1217
+#define wxRegion_Xor_4 1218
+#define wxRegion_Xor_1_1 1219
+#define wxRegion_Xor_1_0 1220
+#define wxAcceleratorTable_new_0 1221
+#define wxAcceleratorTable_new_2 1222
+#define wxAcceleratorTable_destruct 1223
+#define wxAcceleratorTable_Ok 1224
+#define wxAcceleratorEntry_new_1_0 1225
+#define wxAcceleratorEntry_new_1_1 1226
+#define wxAcceleratorEntry_GetCommand 1227
+#define wxAcceleratorEntry_GetFlags 1228
+#define wxAcceleratorEntry_GetKeyCode 1229
+#define wxAcceleratorEntry_Set 1230
+#define wxAcceleratorEntry_destroy 1231
+#define wxCaret_new_3 1236
+#define wxCaret_new_2 1237
+#define wxCaret_destruct 1239
+#define wxCaret_Create_3 1240
+#define wxCaret_Create_2 1241
+#define wxCaret_GetBlinkTime 1242
+#define wxCaret_GetPosition 1244
+#define wxCaret_GetSize 1246
+#define wxCaret_GetWindow 1247
+#define wxCaret_Hide 1248
+#define wxCaret_IsOk 1249
+#define wxCaret_IsVisible 1250
+#define wxCaret_Move_2 1251
+#define wxCaret_Move_1 1252
+#define wxCaret_SetBlinkTime 1253
+#define wxCaret_SetSize_2 1254
+#define wxCaret_SetSize_1 1255
+#define wxCaret_Show 1256
+#define wxSizer_Add_2_1 1257
+#define wxSizer_Add_2_0 1258
+#define wxSizer_Add_3 1259
+#define wxSizer_Add_2_3 1260
+#define wxSizer_Add_2_2 1261
+#define wxSizer_AddSpacer 1262
+#define wxSizer_AddStretchSpacer 1263
+#define wxSizer_CalcMin 1264
+#define wxSizer_Clear 1265
+#define wxSizer_Detach_1_2 1266
+#define wxSizer_Detach_1_1 1267
+#define wxSizer_Detach_1_0 1268
+#define wxSizer_Fit 1269
+#define wxSizer_FitInside 1270
+#define wxSizer_GetChildren 1271
+#define wxSizer_GetItem_2_1 1272
+#define wxSizer_GetItem_2_0 1273
+#define wxSizer_GetItem_1 1274
+#define wxSizer_GetSize 1275
+#define wxSizer_GetPosition 1276
+#define wxSizer_GetMinSize 1277
+#define wxSizer_Hide_2_0 1278
+#define wxSizer_Hide_2_1 1279
+#define wxSizer_Hide_1 1280
+#define wxSizer_Insert_3_1 1281
+#define wxSizer_Insert_3_0 1282
+#define wxSizer_Insert_4 1283
+#define wxSizer_Insert_3_3 1284
+#define wxSizer_Insert_3_2 1285
+#define wxSizer_Insert_2 1286
+#define wxSizer_InsertSpacer 1287
+#define wxSizer_InsertStretchSpacer 1288
+#define wxSizer_IsShown_1_2 1289
+#define wxSizer_IsShown_1_1 1290
+#define wxSizer_IsShown_1_0 1291
+#define wxSizer_Layout 1292
+#define wxSizer_Prepend_2_1 1293
+#define wxSizer_Prepend_2_0 1294
+#define wxSizer_Prepend_3 1295
+#define wxSizer_Prepend_2_3 1296
+#define wxSizer_Prepend_2_2 1297
+#define wxSizer_Prepend_1 1298
+#define wxSizer_PrependSpacer 1299
+#define wxSizer_PrependStretchSpacer 1300
+#define wxSizer_RecalcSizes 1301
+#define wxSizer_Remove_1_1 1302
+#define wxSizer_Remove_1_0 1303
+#define wxSizer_Replace_3_1 1304
+#define wxSizer_Replace_3_0 1305
+#define wxSizer_Replace_2 1306
+#define wxSizer_SetDimension 1307
+#define wxSizer_SetMinSize_2 1308
+#define wxSizer_SetMinSize_1 1309
+#define wxSizer_SetItemMinSize_3_2 1310
+#define wxSizer_SetItemMinSize_2_2 1311
+#define wxSizer_SetItemMinSize_3_1 1312
+#define wxSizer_SetItemMinSize_2_1 1313
+#define wxSizer_SetItemMinSize_3_0 1314
+#define wxSizer_SetItemMinSize_2_0 1315
+#define wxSizer_SetSizeHints 1316
+#define wxSizer_SetVirtualSizeHints 1317
+#define wxSizer_Show_2_2 1318
+#define wxSizer_Show_2_1 1319
+#define wxSizer_Show_2_0 1320
+#define wxSizer_Show_1 1321
+#define wxSizerFlags_new 1322
+#define wxSizerFlags_Align 1323
+#define wxSizerFlags_Border_2 1324
+#define wxSizerFlags_Border_1 1325
+#define wxSizerFlags_Center 1326
+#define wxSizerFlags_Centre 1327
+#define wxSizerFlags_Expand 1328
+#define wxSizerFlags_Left 1329
+#define wxSizerFlags_Proportion 1330
+#define wxSizerFlags_Right 1331
+#define wxSizerFlags_destroy 1332
+#define wxSizerItem_new_5_1 1333
+#define wxSizerItem_new_2_1 1334
+#define wxSizerItem_new_5_0 1335
+#define wxSizerItem_new_2_0 1336
+#define wxSizerItem_new_6 1337
+#define wxSizerItem_new_3 1338
+#define wxSizerItem_new_0 1339
+#define wxSizerItem_destruct 1340
+#define wxSizerItem_CalcMin 1341
+#define wxSizerItem_DeleteWindows 1342
+#define wxSizerItem_DetachSizer 1343
+#define wxSizerItem_GetBorder 1344
+#define wxSizerItem_GetFlag 1345
+#define wxSizerItem_GetMinSize 1346
+#define wxSizerItem_GetPosition 1347
+#define wxSizerItem_GetProportion 1348
+#define wxSizerItem_GetRatio 1349
+#define wxSizerItem_GetRect 1350
+#define wxSizerItem_GetSize 1351
+#define wxSizerItem_GetSizer 1352
+#define wxSizerItem_GetSpacer 1353
+#define wxSizerItem_GetUserData 1354
+#define wxSizerItem_GetWindow 1355
+#define wxSizerItem_IsSizer 1356
+#define wxSizerItem_IsShown 1357
+#define wxSizerItem_IsSpacer 1358
+#define wxSizerItem_IsWindow 1359
+#define wxSizerItem_SetBorder 1360
+#define wxSizerItem_SetDimension 1361
+#define wxSizerItem_SetFlag 1362
+#define wxSizerItem_SetInitSize 1363
+#define wxSizerItem_SetMinSize_1 1364
+#define wxSizerItem_SetMinSize_2 1365
+#define wxSizerItem_SetProportion 1366
+#define wxSizerItem_SetRatio_2 1367
+#define wxSizerItem_SetRatio_1_1 1368
+#define wxSizerItem_SetRatio_1_0 1369
+#define wxSizerItem_SetSizer 1370
+#define wxSizerItem_SetSpacer_1 1371
+#define wxSizerItem_SetSpacer_2 1372
+#define wxSizerItem_SetWindow 1373
+#define wxSizerItem_Show 1374
+#define wxBoxSizer_new 1375
+#define wxBoxSizer_GetOrientation 1376
+#define wxBoxSizer_destroy 1377
+#define wxStaticBoxSizer_new_2 1378
+#define wxStaticBoxSizer_new_3 1379
+#define wxStaticBoxSizer_GetStaticBox 1380
+#define wxStaticBoxSizer_destroy 1381
+#define wxGridSizer_new_4 1382
+#define wxGridSizer_new_2 1383
+#define wxGridSizer_GetCols 1384
+#define wxGridSizer_GetHGap 1385
+#define wxGridSizer_GetRows 1386
+#define wxGridSizer_GetVGap 1387
+#define wxGridSizer_SetCols 1388
+#define wxGridSizer_SetHGap 1389
+#define wxGridSizer_SetRows 1390
+#define wxGridSizer_SetVGap 1391
+#define wxGridSizer_destroy 1392
+#define wxFlexGridSizer_new_4 1393
+#define wxFlexGridSizer_new_2 1394
+#define wxFlexGridSizer_AddGrowableCol 1395
+#define wxFlexGridSizer_AddGrowableRow 1396
+#define wxFlexGridSizer_GetFlexibleDirection 1397
+#define wxFlexGridSizer_GetNonFlexibleGrowMode 1398
+#define wxFlexGridSizer_RemoveGrowableCol 1399
+#define wxFlexGridSizer_RemoveGrowableRow 1400
+#define wxFlexGridSizer_SetFlexibleDirection 1401
+#define wxFlexGridSizer_SetNonFlexibleGrowMode 1402
+#define wxFlexGridSizer_destroy 1403
+#define wxGridBagSizer_new 1404
+#define wxGridBagSizer_Add_3_2 1405
+#define wxGridBagSizer_Add_3_1 1406
+#define wxGridBagSizer_Add_4 1407
+#define wxGridBagSizer_Add_1_0 1408
+#define wxGridBagSizer_Add_2_1 1409
+#define wxGridBagSizer_Add_2_0 1410
+#define wxGridBagSizer_Add_3_0 1411
+#define wxGridBagSizer_Add_1_1 1412
+#define wxGridBagSizer_CalcMin 1413
+#define wxGridBagSizer_CheckForIntersection_2 1414
+#define wxGridBagSizer_CheckForIntersection_3 1415
+#define wxGridBagSizer_FindItem_1_1 1416
+#define wxGridBagSizer_FindItem_1_0 1417
+#define wxGridBagSizer_FindItemAtPoint 1418
+#define wxGridBagSizer_FindItemAtPosition 1419
+#define wxGridBagSizer_FindItemWithData 1420
+#define wxGridBagSizer_GetCellSize 1421
+#define wxGridBagSizer_GetEmptyCellSize 1422
+#define wxGridBagSizer_GetItemPosition_1_2 1423
+#define wxGridBagSizer_GetItemPosition_1_1 1424
+#define wxGridBagSizer_GetItemPosition_1_0 1425
+#define wxGridBagSizer_GetItemSpan_1_2 1426
+#define wxGridBagSizer_GetItemSpan_1_1 1427
+#define wxGridBagSizer_GetItemSpan_1_0 1428
+#define wxGridBagSizer_SetEmptyCellSize 1429
+#define wxGridBagSizer_SetItemPosition_2_2 1430
+#define wxGridBagSizer_SetItemPosition_2_1 1431
+#define wxGridBagSizer_SetItemPosition_2_0 1432
+#define wxGridBagSizer_SetItemSpan_2_2 1433
+#define wxGridBagSizer_SetItemSpan_2_1 1434
+#define wxGridBagSizer_SetItemSpan_2_0 1435
+#define wxGridBagSizer_destroy 1436
+#define wxStdDialogButtonSizer_new 1437
+#define wxStdDialogButtonSizer_AddButton 1438
+#define wxStdDialogButtonSizer_Realize 1439
+#define wxStdDialogButtonSizer_SetAffirmativeButton 1440
+#define wxStdDialogButtonSizer_SetCancelButton 1441
+#define wxStdDialogButtonSizer_SetNegativeButton 1442
+#define wxStdDialogButtonSizer_destroy 1443
+#define wxFont_new_0 1444
+#define wxFont_new_1 1445
+#define wxFont_new_5 1446
+#define wxFont_destruct 1448
+#define wxFont_IsFixedWidth 1449
+#define wxFont_GetDefaultEncoding 1450
+#define wxFont_GetFaceName 1451
+#define wxFont_GetFamily 1452
+#define wxFont_GetNativeFontInfoDesc 1453
+#define wxFont_GetNativeFontInfoUserDesc 1454
+#define wxFont_GetPointSize 1455
+#define wxFont_GetStyle 1456
+#define wxFont_GetUnderlined 1457
+#define wxFont_GetWeight 1458
+#define wxFont_Ok 1459
+#define wxFont_SetDefaultEncoding 1460
+#define wxFont_SetFaceName 1461
+#define wxFont_SetFamily 1462
+#define wxFont_SetPointSize 1463
+#define wxFont_SetStyle 1464
+#define wxFont_SetUnderlined 1465
+#define wxFont_SetWeight 1466
+#define wxToolTip_Enable 1467
+#define wxToolTip_SetDelay 1468
+#define wxToolTip_new 1469
+#define wxToolTip_SetTip 1470
+#define wxToolTip_GetTip 1471
+#define wxToolTip_GetWindow 1472
+#define wxToolTip_destroy 1473
+#define wxButton_new_3 1475
+#define wxButton_new_0 1476
+#define wxButton_destruct 1477
+#define wxButton_Create 1478
+#define wxButton_GetDefaultSize 1479
+#define wxButton_SetDefault 1480
+#define wxButton_SetLabel 1481
+#define wxBitmapButton_new_4 1483
+#define wxBitmapButton_new_0 1484
+#define wxBitmapButton_Create 1485
+#define wxBitmapButton_GetBitmapDisabled 1486
+#define wxBitmapButton_GetBitmapFocus 1488
+#define wxBitmapButton_GetBitmapLabel 1490
+#define wxBitmapButton_GetBitmapSelected 1492
+#define wxBitmapButton_SetBitmapDisabled 1494
+#define wxBitmapButton_SetBitmapFocus 1495
+#define wxBitmapButton_SetBitmapLabel 1496
+#define wxBitmapButton_SetBitmapSelected 1497
+#define wxBitmapButton_destroy 1498
+#define wxToggleButton_new_0 1499
+#define wxToggleButton_new_4 1500
+#define wxToggleButton_Create 1501
+#define wxToggleButton_GetValue 1502
+#define wxToggleButton_SetValue 1503
+#define wxToggleButton_destroy 1504
+#define wxCalendarCtrl_new_0 1505
+#define wxCalendarCtrl_new_3 1506
+#define wxCalendarCtrl_Create 1507
+#define wxCalendarCtrl_destruct 1508
+#define wxCalendarCtrl_SetDate 1509
+#define wxCalendarCtrl_GetDate 1510
+#define wxCalendarCtrl_EnableYearChange 1511
+#define wxCalendarCtrl_EnableMonthChange 1512
+#define wxCalendarCtrl_EnableHolidayDisplay 1513
+#define wxCalendarCtrl_SetHeaderColours 1514
+#define wxCalendarCtrl_GetHeaderColourFg 1515
+#define wxCalendarCtrl_GetHeaderColourBg 1516
+#define wxCalendarCtrl_SetHighlightColours 1517
+#define wxCalendarCtrl_GetHighlightColourFg 1518
+#define wxCalendarCtrl_GetHighlightColourBg 1519
+#define wxCalendarCtrl_SetHolidayColours 1520
+#define wxCalendarCtrl_GetHolidayColourFg 1521
+#define wxCalendarCtrl_GetHolidayColourBg 1522
+#define wxCalendarCtrl_GetAttr 1523
+#define wxCalendarCtrl_SetAttr 1524
+#define wxCalendarCtrl_SetHoliday 1525
+#define wxCalendarCtrl_ResetAttr 1526
+#define wxCalendarCtrl_HitTest 1527
+#define wxCalendarDateAttr_new_0 1528
+#define wxCalendarDateAttr_new_2_1 1529
+#define wxCalendarDateAttr_new_2_0 1530
+#define wxCalendarDateAttr_SetTextColour 1531
+#define wxCalendarDateAttr_SetBackgroundColour 1532
+#define wxCalendarDateAttr_SetBorderColour 1533
+#define wxCalendarDateAttr_SetFont 1534
+#define wxCalendarDateAttr_SetBorder 1535
+#define wxCalendarDateAttr_SetHoliday 1536
+#define wxCalendarDateAttr_HasTextColour 1537
+#define wxCalendarDateAttr_HasBackgroundColour 1538
+#define wxCalendarDateAttr_HasBorderColour 1539
+#define wxCalendarDateAttr_HasFont 1540
+#define wxCalendarDateAttr_HasBorder 1541
+#define wxCalendarDateAttr_IsHoliday 1542
+#define wxCalendarDateAttr_GetTextColour 1543
+#define wxCalendarDateAttr_GetBackgroundColour 1544
+#define wxCalendarDateAttr_GetBorderColour 1545
+#define wxCalendarDateAttr_GetFont 1546
+#define wxCalendarDateAttr_GetBorder 1547
+#define wxCalendarDateAttr_destroy 1548
+#define wxCheckBox_new_4 1550
+#define wxCheckBox_new_0 1551
+#define wxCheckBox_Create 1552
+#define wxCheckBox_GetValue 1553
+#define wxCheckBox_Get3StateValue 1554
+#define wxCheckBox_Is3rdStateAllowedForUser 1555
+#define wxCheckBox_Is3State 1556
+#define wxCheckBox_IsChecked 1557
+#define wxCheckBox_SetValue 1558
+#define wxCheckBox_Set3StateValue 1559
+#define wxCheckBox_destroy 1560
+#define wxCheckListBox_new_0 1561
+#define wxCheckListBox_new_3 1563
+#define wxCheckListBox_Check 1564
+#define wxCheckListBox_IsChecked 1565
+#define wxCheckListBox_destroy 1566
+#define wxChoice_new_3 1569
+#define wxChoice_new_0 1570
+#define wxChoice_destruct 1572
+#define wxChoice_Create 1574
+#define wxChoice_Delete 1575
+#define wxChoice_GetColumns 1576
+#define wxChoice_SetColumns 1577
+#define wxComboBox_new_0 1578
+#define wxComboBox_new_3 1580
+#define wxComboBox_destruct 1581
+#define wxComboBox_Create 1583
+#define wxComboBox_CanCopy 1584
+#define wxComboBox_CanCut 1585
+#define wxComboBox_CanPaste 1586
+#define wxComboBox_CanRedo 1587
+#define wxComboBox_CanUndo 1588
+#define wxComboBox_Copy 1589
+#define wxComboBox_Cut 1590
+#define wxComboBox_GetInsertionPoint 1591
+#define wxComboBox_GetLastPosition 1592
+#define wxComboBox_GetValue 1593
+#define wxComboBox_Paste 1594
+#define wxComboBox_Redo 1595
+#define wxComboBox_Replace 1596
+#define wxComboBox_Remove 1597
+#define wxComboBox_SetInsertionPoint 1598
+#define wxComboBox_SetInsertionPointEnd 1599
+#define wxComboBox_SetSelection_1 1600
+#define wxComboBox_SetSelection_2 1601
+#define wxComboBox_SetValue 1602
+#define wxComboBox_Undo 1603
+#define wxGauge_new_0 1604
+#define wxGauge_new_4 1605
+#define wxGauge_Create 1606
+#define wxGauge_GetRange 1607
+#define wxGauge_GetValue 1608
+#define wxGauge_IsVertical 1609
+#define wxGauge_SetRange 1610
+#define wxGauge_SetValue 1611
+#define wxGauge_Pulse 1612
+#define wxGauge_destroy 1613
+#define wxGenericDirCtrl_new_0 1614
+#define wxGenericDirCtrl_new_2 1615
+#define wxGenericDirCtrl_destruct 1616
+#define wxGenericDirCtrl_Create 1617
+#define wxGenericDirCtrl_Init 1618
+#define wxGenericDirCtrl_CollapseTree 1619
+#define wxGenericDirCtrl_ExpandPath 1620
+#define wxGenericDirCtrl_GetDefaultPath 1621
+#define wxGenericDirCtrl_GetPath 1622
+#define wxGenericDirCtrl_GetFilePath 1623
+#define wxGenericDirCtrl_GetFilter 1624
+#define wxGenericDirCtrl_GetFilterIndex 1625
+#define wxGenericDirCtrl_GetRootId 1626
+#define wxGenericDirCtrl_GetTreeCtrl 1627
+#define wxGenericDirCtrl_ReCreateTree 1628
+#define wxGenericDirCtrl_SetDefaultPath 1629
+#define wxGenericDirCtrl_SetFilter 1630
+#define wxGenericDirCtrl_SetFilterIndex 1631
+#define wxGenericDirCtrl_SetPath 1632
+#define wxStaticBox_new_4 1634
+#define wxStaticBox_new_0 1635
+#define wxStaticBox_Create 1636
+#define wxStaticBox_destroy 1637
+#define wxStaticLine_new_2 1639
+#define wxStaticLine_new_0 1640
+#define wxStaticLine_Create 1641
+#define wxStaticLine_IsVertical 1642
+#define wxStaticLine_GetDefaultSize 1643
+#define wxStaticLine_destroy 1644
+#define wxListBox_new_3 1647
+#define wxListBox_new_0 1648
+#define wxListBox_destruct 1650
+#define wxListBox_Create 1652
+#define wxListBox_Deselect 1653
+#define wxListBox_GetSelections 1654
+#define wxListBox_InsertItems 1655
+#define wxListBox_IsSelected 1656
+#define wxListBox_Set 1657
+#define wxListBox_HitTest 1658
+#define wxListBox_SetFirstItem_1_0 1659
+#define wxListBox_SetFirstItem_1_1 1660
+#define wxListCtrl_new_0 1661
+#define wxListCtrl_new_2 1662
+#define wxListCtrl_Arrange 1663
+#define wxListCtrl_AssignImageList 1664
+#define wxListCtrl_ClearAll 1665
+#define wxListCtrl_Create 1666
+#define wxListCtrl_DeleteAllItems 1667
+#define wxListCtrl_DeleteColumn 1668
+#define wxListCtrl_DeleteItem 1669
+#define wxListCtrl_EditLabel 1670
+#define wxListCtrl_EnsureVisible 1671
+#define wxListCtrl_FindItem_3_0 1672
+#define wxListCtrl_FindItem_3_1 1673
+#define wxListCtrl_GetColumn 1674
+#define wxListCtrl_GetColumnCount 1675
+#define wxListCtrl_GetColumnWidth 1676
+#define wxListCtrl_GetCountPerPage 1677
+#define wxListCtrl_GetEditControl 1678
+#define wxListCtrl_GetImageList 1679
+#define wxListCtrl_GetItem 1680
+#define wxListCtrl_GetItemBackgroundColour 1681
+#define wxListCtrl_GetItemCount 1682
+#define wxListCtrl_GetItemData 1683
+#define wxListCtrl_GetItemFont 1684
+#define wxListCtrl_GetItemPosition 1685
+#define wxListCtrl_GetItemRect 1686
+#define wxListCtrl_GetItemSpacing 1687
+#define wxListCtrl_GetItemState 1688
+#define wxListCtrl_GetItemText 1689
+#define wxListCtrl_GetItemTextColour 1690
+#define wxListCtrl_GetNextItem 1691
+#define wxListCtrl_GetSelectedItemCount 1692
+#define wxListCtrl_GetTextColour 1693
+#define wxListCtrl_GetTopItem 1694
+#define wxListCtrl_GetViewRect 1695
+#define wxListCtrl_HitTest 1696
+#define wxListCtrl_InsertColumn_2 1697
+#define wxListCtrl_InsertColumn_3 1698
+#define wxListCtrl_InsertItem_1 1699
+#define wxListCtrl_InsertItem_2_1 1700
+#define wxListCtrl_InsertItem_2_0 1701
+#define wxListCtrl_InsertItem_3 1702
+#define wxListCtrl_RefreshItem 1703
+#define wxListCtrl_RefreshItems 1704
+#define wxListCtrl_ScrollList 1705
+#define wxListCtrl_SetBackgroundColour 1706
+#define wxListCtrl_SetColumn 1707
+#define wxListCtrl_SetColumnWidth 1708
+#define wxListCtrl_SetImageList 1709
+#define wxListCtrl_SetItem_1 1710
+#define wxListCtrl_SetItem_4 1711
+#define wxListCtrl_SetItemBackgroundColour 1712
+#define wxListCtrl_SetItemCount 1713
+#define wxListCtrl_SetItemData 1714
+#define wxListCtrl_SetItemFont 1715
+#define wxListCtrl_SetItemImage 1716
+#define wxListCtrl_SetItemColumnImage 1717
+#define wxListCtrl_SetItemPosition 1718
+#define wxListCtrl_SetItemState 1719
+#define wxListCtrl_SetItemText 1720
+#define wxListCtrl_SetItemTextColour 1721
+#define wxListCtrl_SetSingleStyle 1722
+#define wxListCtrl_SetTextColour 1723
+#define wxListCtrl_SetWindowStyleFlag 1724
+#define wxListCtrl_SortItems 1725
+#define wxListCtrl_destroy 1726
+#define wxListView_ClearColumnImage 1727
+#define wxListView_Focus 1728
+#define wxListView_GetFirstSelected 1729
+#define wxListView_GetFocusedItem 1730
+#define wxListView_GetNextSelected 1731
+#define wxListView_IsSelected 1732
+#define wxListView_Select 1733
+#define wxListView_SetColumnImage 1734
+#define wxListItem_new_0 1735
+#define wxListItem_new_1 1736
+#define wxListItem_destruct 1737
+#define wxListItem_Clear 1738
+#define wxListItem_GetAlign 1739
+#define wxListItem_GetBackgroundColour 1740
+#define wxListItem_GetColumn 1741
+#define wxListItem_GetFont 1742
+#define wxListItem_GetId 1743
+#define wxListItem_GetImage 1744
+#define wxListItem_GetMask 1745
+#define wxListItem_GetState 1746
+#define wxListItem_GetText 1747
+#define wxListItem_GetTextColour 1748
+#define wxListItem_GetWidth 1749
+#define wxListItem_SetAlign 1750
+#define wxListItem_SetBackgroundColour 1751
+#define wxListItem_SetColumn 1752
+#define wxListItem_SetFont 1753
+#define wxListItem_SetId 1754
+#define wxListItem_SetImage 1755
+#define wxListItem_SetMask 1756
+#define wxListItem_SetState 1757
+#define wxListItem_SetStateMask 1758
+#define wxListItem_SetText 1759
+#define wxListItem_SetTextColour 1760
+#define wxListItem_SetWidth 1761
+#define wxListItemAttr_new_0 1762
+#define wxListItemAttr_new_3 1763
+#define wxListItemAttr_GetBackgroundColour 1764
+#define wxListItemAttr_GetFont 1765
+#define wxListItemAttr_GetTextColour 1766
+#define wxListItemAttr_HasBackgroundColour 1767
+#define wxListItemAttr_HasFont 1768
+#define wxListItemAttr_HasTextColour 1769
+#define wxListItemAttr_SetBackgroundColour 1770
+#define wxListItemAttr_SetFont 1771
+#define wxListItemAttr_SetTextColour 1772
+#define wxListItemAttr_destroy 1773
+#define wxImageList_new_0 1774
+#define wxImageList_new_3 1775
+#define wxImageList_Add_1 1776
+#define wxImageList_Add_2_0 1777
+#define wxImageList_Add_2_1 1778
+#define wxImageList_Create 1779
+#define wxImageList_Draw 1781
+#define wxImageList_GetBitmap 1782
+#define wxImageList_GetIcon 1783
+#define wxImageList_GetImageCount 1784
+#define wxImageList_GetSize 1785
+#define wxImageList_Remove 1786
+#define wxImageList_RemoveAll 1787
+#define wxImageList_Replace_2 1788
+#define wxImageList_Replace_3 1789
+#define wxImageList_destroy 1790
+#define wxTextAttr_new_0 1791
+#define wxTextAttr_new_2 1792
+#define wxTextAttr_GetAlignment 1793
+#define wxTextAttr_GetBackgroundColour 1794
+#define wxTextAttr_GetFont 1795
+#define wxTextAttr_GetLeftIndent 1796
+#define wxTextAttr_GetLeftSubIndent 1797
+#define wxTextAttr_GetRightIndent 1798
+#define wxTextAttr_GetTabs 1799
+#define wxTextAttr_GetTextColour 1800
+#define wxTextAttr_HasBackgroundColour 1801
+#define wxTextAttr_HasFont 1802
+#define wxTextAttr_HasTextColour 1803
+#define wxTextAttr_GetFlags 1804
+#define wxTextAttr_IsDefault 1805
+#define wxTextAttr_SetAlignment 1806
+#define wxTextAttr_SetBackgroundColour 1807
+#define wxTextAttr_SetFlags 1808
+#define wxTextAttr_SetFont 1809
+#define wxTextAttr_SetLeftIndent 1810
+#define wxTextAttr_SetRightIndent 1811
+#define wxTextAttr_SetTabs 1812
+#define wxTextAttr_SetTextColour 1813
+#define wxTextAttr_destroy 1814
+#define wxTextCtrl_new_3 1816
+#define wxTextCtrl_new_0 1817
+#define wxTextCtrl_destruct 1819
+#define wxTextCtrl_AppendText 1820
+#define wxTextCtrl_CanCopy 1821
+#define wxTextCtrl_CanCut 1822
+#define wxTextCtrl_CanPaste 1823
+#define wxTextCtrl_CanRedo 1824
+#define wxTextCtrl_CanUndo 1825
+#define wxTextCtrl_Clear 1826
+#define wxTextCtrl_Copy 1827
+#define wxTextCtrl_Create 1828
+#define wxTextCtrl_Cut 1829
+#define wxTextCtrl_DiscardEdits 1830
+#define wxTextCtrl_ChangeValue 1831
+#define wxTextCtrl_EmulateKeyPress 1832
+#define wxTextCtrl_GetDefaultStyle 1833
+#define wxTextCtrl_GetInsertionPoint 1834
+#define wxTextCtrl_GetLastPosition 1835
+#define wxTextCtrl_GetLineLength 1836
+#define wxTextCtrl_GetLineText 1837
+#define wxTextCtrl_GetNumberOfLines 1838
+#define wxTextCtrl_GetRange 1839
+#define wxTextCtrl_GetSelection 1840
+#define wxTextCtrl_GetStringSelection 1841
+#define wxTextCtrl_GetStyle 1842
+#define wxTextCtrl_GetValue 1843
+#define wxTextCtrl_IsEditable 1844
+#define wxTextCtrl_IsModified 1845
+#define wxTextCtrl_IsMultiLine 1846
+#define wxTextCtrl_IsSingleLine 1847
+#define wxTextCtrl_LoadFile 1848
+#define wxTextCtrl_MarkDirty 1849
+#define wxTextCtrl_Paste 1850
+#define wxTextCtrl_PositionToXY 1851
+#define wxTextCtrl_Redo 1852
+#define wxTextCtrl_Remove 1853
+#define wxTextCtrl_Replace 1854
+#define wxTextCtrl_SaveFile 1855
+#define wxTextCtrl_SetDefaultStyle 1856
+#define wxTextCtrl_SetEditable 1857
+#define wxTextCtrl_SetInsertionPoint 1858
+#define wxTextCtrl_SetInsertionPointEnd 1859
+#define wxTextCtrl_SetMaxLength 1861
+#define wxTextCtrl_SetSelection 1862
+#define wxTextCtrl_SetStyle 1863
+#define wxTextCtrl_SetValue 1864
+#define wxTextCtrl_ShowPosition 1865
+#define wxTextCtrl_Undo 1866
+#define wxTextCtrl_WriteText 1867
+#define wxTextCtrl_XYToPosition 1868
+#define wxNotebook_new_0 1871
+#define wxNotebook_new_3 1872
+#define wxNotebook_destruct 1873
+#define wxNotebook_AddPage 1874
+#define wxNotebook_AdvanceSelection 1875
+#define wxNotebook_AssignImageList 1876
+#define wxNotebook_Create 1877
+#define wxNotebook_DeleteAllPages 1878
+#define wxNotebook_DeletePage 1879
+#define wxNotebook_RemovePage 1880
+#define wxNotebook_GetCurrentPage 1881
+#define wxNotebook_GetImageList 1882
+#define wxNotebook_GetPage 1884
+#define wxNotebook_GetPageCount 1885
+#define wxNotebook_GetPageImage 1886
+#define wxNotebook_GetPageText 1887
+#define wxNotebook_GetRowCount 1888
+#define wxNotebook_GetSelection 1889
+#define wxNotebook_GetThemeBackgroundColour 1890
+#define wxNotebook_HitTest 1892
+#define wxNotebook_InsertPage 1894
+#define wxNotebook_SetImageList 1895
+#define wxNotebook_SetPadding 1896
+#define wxNotebook_SetPageSize 1897
+#define wxNotebook_SetPageImage 1898
+#define wxNotebook_SetPageText 1899
+#define wxNotebook_SetSelection 1900
+#define wxNotebook_ChangeSelection 1901
+#define wxChoicebook_new_0 1902
+#define wxChoicebook_new_3 1903
+#define wxChoicebook_AddPage 1904
+#define wxChoicebook_AdvanceSelection 1905
+#define wxChoicebook_AssignImageList 1906
+#define wxChoicebook_Create 1907
+#define wxChoicebook_DeleteAllPages 1908
+#define wxChoicebook_DeletePage 1909
+#define wxChoicebook_RemovePage 1910
+#define wxChoicebook_GetCurrentPage 1911
+#define wxChoicebook_GetImageList 1912
+#define wxChoicebook_GetPage 1914
+#define wxChoicebook_GetPageCount 1915
+#define wxChoicebook_GetPageImage 1916
+#define wxChoicebook_GetPageText 1917
+#define wxChoicebook_GetSelection 1918
+#define wxChoicebook_HitTest 1919
+#define wxChoicebook_InsertPage 1920
+#define wxChoicebook_SetImageList 1921
+#define wxChoicebook_SetPageSize 1922
+#define wxChoicebook_SetPageImage 1923
+#define wxChoicebook_SetPageText 1924
+#define wxChoicebook_SetSelection 1925
+#define wxChoicebook_ChangeSelection 1926
+#define wxChoicebook_destroy 1927
+#define wxToolbook_new_0 1928
+#define wxToolbook_new_3 1929
+#define wxToolbook_AddPage 1930
+#define wxToolbook_AdvanceSelection 1931
+#define wxToolbook_AssignImageList 1932
+#define wxToolbook_Create 1933
+#define wxToolbook_DeleteAllPages 1934
+#define wxToolbook_DeletePage 1935
+#define wxToolbook_RemovePage 1936
+#define wxToolbook_GetCurrentPage 1937
+#define wxToolbook_GetImageList 1938
+#define wxToolbook_GetPage 1940
+#define wxToolbook_GetPageCount 1941
+#define wxToolbook_GetPageImage 1942
+#define wxToolbook_GetPageText 1943
+#define wxToolbook_GetSelection 1944
+#define wxToolbook_HitTest 1946
+#define wxToolbook_InsertPage 1947
+#define wxToolbook_SetImageList 1948
+#define wxToolbook_SetPageSize 1949
+#define wxToolbook_SetPageImage 1950
+#define wxToolbook_SetPageText 1951
+#define wxToolbook_SetSelection 1952
+#define wxToolbook_ChangeSelection 1953
+#define wxToolbook_destroy 1954
+#define wxListbook_new_0 1955
+#define wxListbook_new_3 1956
+#define wxListbook_AddPage 1957
+#define wxListbook_AdvanceSelection 1958
+#define wxListbook_AssignImageList 1959
+#define wxListbook_Create 1960
+#define wxListbook_DeleteAllPages 1961
+#define wxListbook_DeletePage 1962
+#define wxListbook_RemovePage 1963
+#define wxListbook_GetCurrentPage 1964
+#define wxListbook_GetImageList 1965
+#define wxListbook_GetPage 1967
+#define wxListbook_GetPageCount 1968
+#define wxListbook_GetPageImage 1969
+#define wxListbook_GetPageText 1970
+#define wxListbook_GetSelection 1971
+#define wxListbook_HitTest 1973
+#define wxListbook_InsertPage 1974
+#define wxListbook_SetImageList 1975
+#define wxListbook_SetPageSize 1976
+#define wxListbook_SetPageImage 1977
+#define wxListbook_SetPageText 1978
+#define wxListbook_SetSelection 1979
+#define wxListbook_ChangeSelection 1980
+#define wxListbook_destroy 1981
+#define wxTreebook_new_0 1982
+#define wxTreebook_new_3 1983
+#define wxTreebook_AddPage 1984
+#define wxTreebook_AdvanceSelection 1985
+#define wxTreebook_AssignImageList 1986
+#define wxTreebook_Create 1987
+#define wxTreebook_DeleteAllPages 1988
+#define wxTreebook_DeletePage 1989
+#define wxTreebook_RemovePage 1990
+#define wxTreebook_GetCurrentPage 1991
+#define wxTreebook_GetImageList 1992
+#define wxTreebook_GetPage 1994
+#define wxTreebook_GetPageCount 1995
+#define wxTreebook_GetPageImage 1996
+#define wxTreebook_GetPageText 1997
+#define wxTreebook_GetSelection 1998
+#define wxTreebook_ExpandNode 1999
+#define wxTreebook_IsNodeExpanded 2000
+#define wxTreebook_HitTest 2002
+#define wxTreebook_InsertPage 2003
+#define wxTreebook_InsertSubPage 2004
+#define wxTreebook_SetImageList 2005
+#define wxTreebook_SetPageSize 2006
+#define wxTreebook_SetPageImage 2007
+#define wxTreebook_SetPageText 2008
+#define wxTreebook_SetSelection 2009
+#define wxTreebook_ChangeSelection 2010
+#define wxTreebook_destroy 2011
+#define wxTreeCtrl_new_2 2014
+#define wxTreeCtrl_new_0 2015
+#define wxTreeCtrl_destruct 2017
+#define wxTreeCtrl_AddRoot 2018
+#define wxTreeCtrl_AppendItem 2019
+#define wxTreeCtrl_AssignImageList 2020
+#define wxTreeCtrl_AssignStateImageList 2021
+#define wxTreeCtrl_Collapse 2022
+#define wxTreeCtrl_CollapseAndReset 2023
+#define wxTreeCtrl_Create 2024
+#define wxTreeCtrl_Delete 2025
+#define wxTreeCtrl_DeleteAllItems 2026
+#define wxTreeCtrl_DeleteChildren 2027
+#define wxTreeCtrl_EditLabel 2028
+#define wxTreeCtrl_EnsureVisible 2029
+#define wxTreeCtrl_Expand 2030
+#define wxTreeCtrl_GetBoundingRect 2031
+#define wxTreeCtrl_GetChildrenCount 2033
+#define wxTreeCtrl_GetCount 2034
+#define wxTreeCtrl_GetEditControl 2035
+#define wxTreeCtrl_GetFirstChild 2036
+#define wxTreeCtrl_GetNextChild 2037
+#define wxTreeCtrl_GetFirstVisibleItem 2038
+#define wxTreeCtrl_GetImageList 2039
+#define wxTreeCtrl_GetIndent 2040
+#define wxTreeCtrl_GetItemBackgroundColour 2041
+#define wxTreeCtrl_GetItemData 2042
+#define wxTreeCtrl_GetItemFont 2043
+#define wxTreeCtrl_GetItemImage_1 2044
+#define wxTreeCtrl_GetItemImage_2 2045
+#define wxTreeCtrl_GetItemText 2046
+#define wxTreeCtrl_GetItemTextColour 2047
+#define wxTreeCtrl_GetLastChild 2048
+#define wxTreeCtrl_GetNextSibling 2049
+#define wxTreeCtrl_GetNextVisible 2050
+#define wxTreeCtrl_GetItemParent 2051
+#define wxTreeCtrl_GetPrevSibling 2052
+#define wxTreeCtrl_GetPrevVisible 2053
+#define wxTreeCtrl_GetRootItem 2054
+#define wxTreeCtrl_GetSelection 2055
+#define wxTreeCtrl_GetSelections 2056
+#define wxTreeCtrl_GetStateImageList 2057
+#define wxTreeCtrl_HitTest 2058
+#define wxTreeCtrl_InsertItem 2060
+#define wxTreeCtrl_IsBold 2061
+#define wxTreeCtrl_IsExpanded 2062
+#define wxTreeCtrl_IsSelected 2063
+#define wxTreeCtrl_IsVisible 2064
+#define wxTreeCtrl_ItemHasChildren 2065
+#define wxTreeCtrl_IsTreeItemIdOk 2066
+#define wxTreeCtrl_PrependItem 2067
+#define wxTreeCtrl_ScrollTo 2068
+#define wxTreeCtrl_SelectItem_1 2069
+#define wxTreeCtrl_SelectItem_2 2070
+#define wxTreeCtrl_SetIndent 2071
+#define wxTreeCtrl_SetImageList 2072
+#define wxTreeCtrl_SetItemBackgroundColour 2073
+#define wxTreeCtrl_SetItemBold 2074
+#define wxTreeCtrl_SetItemData 2075
+#define wxTreeCtrl_SetItemDropHighlight 2076
+#define wxTreeCtrl_SetItemFont 2077
+#define wxTreeCtrl_SetItemHasChildren 2078
+#define wxTreeCtrl_SetItemImage_2 2079
+#define wxTreeCtrl_SetItemImage_3 2080
+#define wxTreeCtrl_SetItemText 2081
+#define wxTreeCtrl_SetItemTextColour 2082
+#define wxTreeCtrl_SetStateImageList 2083
+#define wxTreeCtrl_SetWindowStyle 2084
+#define wxTreeCtrl_SortChildren 2085
+#define wxTreeCtrl_Toggle 2086
+#define wxTreeCtrl_ToggleItemSelection 2087
+#define wxTreeCtrl_Unselect 2088
+#define wxTreeCtrl_UnselectAll 2089
+#define wxTreeCtrl_UnselectItem 2090
+#define wxScrollBar_new_0 2091
+#define wxScrollBar_new_3 2092
+#define wxScrollBar_destruct 2093
+#define wxScrollBar_Create 2094
+#define wxScrollBar_GetRange 2095
+#define wxScrollBar_GetPageSize 2096
+#define wxScrollBar_GetThumbPosition 2097
+#define wxScrollBar_GetThumbSize 2098
+#define wxScrollBar_SetThumbPosition 2099
+#define wxScrollBar_SetScrollbar 2100
+#define wxSpinButton_new_2 2102
+#define wxSpinButton_new_0 2103
+#define wxSpinButton_Create 2104
+#define wxSpinButton_GetMax 2105
+#define wxSpinButton_GetMin 2106
+#define wxSpinButton_GetValue 2107
+#define wxSpinButton_SetRange 2108
+#define wxSpinButton_SetValue 2109
+#define wxSpinButton_destroy 2110
+#define wxSpinCtrl_new_0 2111
+#define wxSpinCtrl_new_2 2112
+#define wxSpinCtrl_Create 2114
+#define wxSpinCtrl_SetValue_1_1 2117
+#define wxSpinCtrl_SetValue_1_0 2118
+#define wxSpinCtrl_GetValue 2120
+#define wxSpinCtrl_SetRange 2122
+#define wxSpinCtrl_SetSelection 2123
+#define wxSpinCtrl_GetMin 2125
+#define wxSpinCtrl_GetMax 2127
+#define wxSpinCtrl_destroy 2128
+#define wxStaticText_new_0 2129
+#define wxStaticText_new_4 2130
+#define wxStaticText_Create 2131
+#define wxStaticText_GetLabel 2132
+#define wxStaticText_SetLabel 2133
+#define wxStaticText_Wrap 2134
+#define wxStaticText_destroy 2135
+#define wxStaticBitmap_new_0 2136
+#define wxStaticBitmap_new_4 2137
+#define wxStaticBitmap_Create 2138
+#define wxStaticBitmap_GetBitmap 2139
+#define wxStaticBitmap_SetBitmap 2140
+#define wxStaticBitmap_destroy 2141
+#define wxRadioBox_new 2142
+#define wxRadioBox_destruct 2144
+#define wxRadioBox_Create 2145
+#define wxRadioBox_Enable_2 2146
+#define wxRadioBox_Enable_1 2147
+#define wxRadioBox_GetSelection 2148
+#define wxRadioBox_GetString 2149
+#define wxRadioBox_SetSelection 2150
+#define wxRadioBox_Show_2 2151
+#define wxRadioBox_Show_1 2152
+#define wxRadioBox_GetColumnCount 2153
+#define wxRadioBox_GetItemHelpText 2154
+#define wxRadioBox_GetItemToolTip 2155
+#define wxRadioBox_GetItemFromPoint 2157
+#define wxRadioBox_GetRowCount 2158
+#define wxRadioBox_IsItemEnabled 2159
+#define wxRadioBox_IsItemShown 2160
+#define wxRadioBox_SetItemHelpText 2161
+#define wxRadioBox_SetItemToolTip 2162
+#define wxRadioButton_new_0 2163
+#define wxRadioButton_new_4 2164
+#define wxRadioButton_Create 2165
+#define wxRadioButton_GetValue 2166
+#define wxRadioButton_SetValue 2167
+#define wxRadioButton_destroy 2168
+#define wxSlider_new_6 2170
+#define wxSlider_new_0 2171
+#define wxSlider_Create 2172
+#define wxSlider_GetLineSize 2173
+#define wxSlider_GetMax 2174
+#define wxSlider_GetMin 2175
+#define wxSlider_GetPageSize 2176
+#define wxSlider_GetThumbLength 2177
+#define wxSlider_GetValue 2178
+#define wxSlider_SetLineSize 2179
+#define wxSlider_SetPageSize 2180
+#define wxSlider_SetRange 2181
+#define wxSlider_SetThumbLength 2182
+#define wxSlider_SetValue 2183
+#define wxSlider_destroy 2184
+#define wxDialog_new_4 2186
+#define wxDialog_new_0 2187
+#define wxDialog_destruct 2189
+#define wxDialog_Create 2190
+#define wxDialog_CreateButtonSizer 2191
+#define wxDialog_CreateStdDialogButtonSizer 2192
+#define wxDialog_EndModal 2193
+#define wxDialog_GetAffirmativeId 2194
+#define wxDialog_GetReturnCode 2195
+#define wxDialog_IsModal 2196
+#define wxDialog_SetAffirmativeId 2197
+#define wxDialog_SetReturnCode 2198
+#define wxDialog_Show 2199
+#define wxDialog_ShowModal 2200
+#define wxColourDialog_new_0 2201
+#define wxColourDialog_new_2 2202
+#define wxColourDialog_destruct 2203
+#define wxColourDialog_Create 2204
+#define wxColourDialog_GetColourData 2205
+#define wxColourData_new_0 2206
+#define wxColourData_new_1 2207
+#define wxColourData_destruct 2208
+#define wxColourData_GetChooseFull 2209
+#define wxColourData_GetColour 2210
+#define wxColourData_GetCustomColour 2212
+#define wxColourData_SetChooseFull 2213
+#define wxColourData_SetColour 2214
+#define wxColourData_SetCustomColour 2215
+#define wxPalette_new_0 2216
+#define wxPalette_new_4 2217
+#define wxPalette_destruct 2219
+#define wxPalette_Create 2220
+#define wxPalette_GetColoursCount 2221
+#define wxPalette_GetPixel 2222
+#define wxPalette_GetRGB 2223
+#define wxPalette_IsOk 2224
+#define wxDirDialog_new 2228
+#define wxDirDialog_destruct 2229
+#define wxDirDialog_GetPath 2230
+#define wxDirDialog_GetMessage 2231
+#define wxDirDialog_SetMessage 2232
+#define wxDirDialog_SetPath 2233
+#define wxFileDialog_new 2237
+#define wxFileDialog_destruct 2238
+#define wxFileDialog_GetDirectory 2239
+#define wxFileDialog_GetFilename 2240
+#define wxFileDialog_GetFilenames 2241
+#define wxFileDialog_GetFilterIndex 2242
+#define wxFileDialog_GetMessage 2243
+#define wxFileDialog_GetPath 2244
+#define wxFileDialog_GetPaths 2245
+#define wxFileDialog_GetWildcard 2246
+#define wxFileDialog_SetDirectory 2247
+#define wxFileDialog_SetFilename 2248
+#define wxFileDialog_SetFilterIndex 2249
+#define wxFileDialog_SetMessage 2250
+#define wxFileDialog_SetPath 2251
+#define wxFileDialog_SetWildcard 2252
+#define wxPickerBase_SetInternalMargin 2253
+#define wxPickerBase_GetInternalMargin 2254
+#define wxPickerBase_SetTextCtrlProportion 2255
+#define wxPickerBase_SetPickerCtrlProportion 2256
+#define wxPickerBase_GetTextCtrlProportion 2257
+#define wxPickerBase_GetPickerCtrlProportion 2258
+#define wxPickerBase_HasTextCtrl 2259
+#define wxPickerBase_GetTextCtrl 2260
+#define wxPickerBase_IsTextCtrlGrowable 2261
+#define wxPickerBase_SetPickerCtrlGrowable 2262
+#define wxPickerBase_SetTextCtrlGrowable 2263
+#define wxPickerBase_IsPickerCtrlGrowable 2264
+#define wxFilePickerCtrl_new_0 2265
+#define wxFilePickerCtrl_new_3 2266
+#define wxFilePickerCtrl_Create 2267
+#define wxFilePickerCtrl_GetPath 2268
+#define wxFilePickerCtrl_SetPath 2269
+#define wxFilePickerCtrl_destroy 2270
+#define wxDirPickerCtrl_new_0 2271
+#define wxDirPickerCtrl_new_3 2272
+#define wxDirPickerCtrl_Create 2273
+#define wxDirPickerCtrl_GetPath 2274
+#define wxDirPickerCtrl_SetPath 2275
+#define wxDirPickerCtrl_destroy 2276
+#define wxColourPickerCtrl_new_0 2277
+#define wxColourPickerCtrl_new_3 2278
+#define wxColourPickerCtrl_Create 2279
+#define wxColourPickerCtrl_GetColour 2280
+#define wxColourPickerCtrl_SetColour_1_1 2281
+#define wxColourPickerCtrl_SetColour_1_0 2282
+#define wxColourPickerCtrl_destroy 2283
+#define wxDatePickerCtrl_new_0 2284
+#define wxDatePickerCtrl_new_3 2285
+#define wxDatePickerCtrl_GetRange 2286
+#define wxDatePickerCtrl_GetValue 2287
+#define wxDatePickerCtrl_SetRange 2288
+#define wxDatePickerCtrl_SetValue 2289
+#define wxDatePickerCtrl_destroy 2290
+#define wxFontPickerCtrl_new_0 2291
+#define wxFontPickerCtrl_new_3 2292
+#define wxFontPickerCtrl_Create 2293
+#define wxFontPickerCtrl_GetSelectedFont 2294
+#define wxFontPickerCtrl_SetSelectedFont 2295
+#define wxFontPickerCtrl_GetMaxPointSize 2296
+#define wxFontPickerCtrl_SetMaxPointSize 2297
+#define wxFontPickerCtrl_destroy 2298
+#define wxFindReplaceDialog_new_0 2301
+#define wxFindReplaceDialog_new_4 2302
+#define wxFindReplaceDialog_destruct 2303
+#define wxFindReplaceDialog_Create 2304
+#define wxFindReplaceDialog_GetData 2305
+#define wxFindReplaceData_new_0 2306
+#define wxFindReplaceData_new_1 2307
+#define wxFindReplaceData_GetFindString 2308
+#define wxFindReplaceData_GetReplaceString 2309
+#define wxFindReplaceData_GetFlags 2310
+#define wxFindReplaceData_SetFlags 2311
+#define wxFindReplaceData_SetFindString 2312
+#define wxFindReplaceData_SetReplaceString 2313
+#define wxFindReplaceData_destroy 2314
+#define wxMultiChoiceDialog_new_0 2315
+#define wxMultiChoiceDialog_new_5 2317
+#define wxMultiChoiceDialog_GetSelections 2318
+#define wxMultiChoiceDialog_SetSelections 2319
+#define wxMultiChoiceDialog_destroy 2320
+#define wxSingleChoiceDialog_new_0 2321
+#define wxSingleChoiceDialog_new_5 2323
+#define wxSingleChoiceDialog_GetSelection 2324
+#define wxSingleChoiceDialog_GetStringSelection 2325
+#define wxSingleChoiceDialog_SetSelection 2326
+#define wxSingleChoiceDialog_destroy 2327
+#define wxTextEntryDialog_new 2328
+#define wxTextEntryDialog_GetValue 2329
+#define wxTextEntryDialog_SetValue 2330
+#define wxTextEntryDialog_destroy 2331
+#define wxPasswordEntryDialog_new 2332
+#define wxPasswordEntryDialog_destroy 2333
+#define wxFontData_new_0 2334
+#define wxFontData_new_1 2335
+#define wxFontData_destruct 2336
+#define wxFontData_EnableEffects 2337
+#define wxFontData_GetAllowSymbols 2338
+#define wxFontData_GetColour 2339
+#define wxFontData_GetChosenFont 2340
+#define wxFontData_GetEnableEffects 2341
+#define wxFontData_GetInitialFont 2342
+#define wxFontData_GetShowHelp 2343
+#define wxFontData_SetAllowSymbols 2344
+#define wxFontData_SetChosenFont 2345
+#define wxFontData_SetColour 2346
+#define wxFontData_SetInitialFont 2347
+#define wxFontData_SetRange 2348
+#define wxFontData_SetShowHelp 2349
+#define wxFontDialog_new_0 2353
+#define wxFontDialog_new_2 2355
+#define wxFontDialog_Create 2357
+#define wxFontDialog_GetFontData 2358
+#define wxFontDialog_destroy 2360
+#define wxProgressDialog_new 2361
+#define wxProgressDialog_destruct 2362
+#define wxProgressDialog_Resume 2363
+#define wxProgressDialog_Update_2 2364
+#define wxProgressDialog_Update_0 2365
+#define wxMessageDialog_new 2366
+#define wxMessageDialog_destruct 2367
+#define wxPageSetupDialog_new 2368
+#define wxPageSetupDialog_destruct 2369
+#define wxPageSetupDialog_GetPageSetupData 2370
+#define wxPageSetupDialog_ShowModal 2371
+#define wxPageSetupDialogData_new_0 2372
+#define wxPageSetupDialogData_new_1_0 2373
+#define wxPageSetupDialogData_new_1_1 2374
+#define wxPageSetupDialogData_destruct 2375
+#define wxPageSetupDialogData_EnableHelp 2376
+#define wxPageSetupDialogData_EnableMargins 2377
+#define wxPageSetupDialogData_EnableOrientation 2378
+#define wxPageSetupDialogData_EnablePaper 2379
+#define wxPageSetupDialogData_EnablePrinter 2380
+#define wxPageSetupDialogData_GetDefaultMinMargins 2381
+#define wxPageSetupDialogData_GetEnableMargins 2382
+#define wxPageSetupDialogData_GetEnableOrientation 2383
+#define wxPageSetupDialogData_GetEnablePaper 2384
+#define wxPageSetupDialogData_GetEnablePrinter 2385
+#define wxPageSetupDialogData_GetEnableHelp 2386
+#define wxPageSetupDialogData_GetDefaultInfo 2387
+#define wxPageSetupDialogData_GetMarginTopLeft 2388
+#define wxPageSetupDialogData_GetMarginBottomRight 2389
+#define wxPageSetupDialogData_GetMinMarginTopLeft 2390
+#define wxPageSetupDialogData_GetMinMarginBottomRight 2391
+#define wxPageSetupDialogData_GetPaperId 2392
+#define wxPageSetupDialogData_GetPaperSize 2393
+#define wxPageSetupDialogData_GetPrintData 2395
+#define wxPageSetupDialogData_IsOk 2396
+#define wxPageSetupDialogData_SetDefaultInfo 2397
+#define wxPageSetupDialogData_SetDefaultMinMargins 2398
+#define wxPageSetupDialogData_SetMarginTopLeft 2399
+#define wxPageSetupDialogData_SetMarginBottomRight 2400
+#define wxPageSetupDialogData_SetMinMarginTopLeft 2401
+#define wxPageSetupDialogData_SetMinMarginBottomRight 2402
+#define wxPageSetupDialogData_SetPaperId 2403
+#define wxPageSetupDialogData_SetPaperSize_1_1 2404
+#define wxPageSetupDialogData_SetPaperSize_1_0 2405
+#define wxPageSetupDialogData_SetPrintData 2406
+#define wxPrintDialog_new_2_0 2407
+#define wxPrintDialog_new_2_1 2408
+#define wxPrintDialog_destruct 2409
+#define wxPrintDialog_GetPrintDialogData 2410
+#define wxPrintDialog_GetPrintDC 2411
+#define wxPrintDialogData_new_0 2412
+#define wxPrintDialogData_new_1_1 2413
+#define wxPrintDialogData_new_1_0 2414
+#define wxPrintDialogData_destruct 2415
+#define wxPrintDialogData_EnableHelp 2416
+#define wxPrintDialogData_EnablePageNumbers 2417
+#define wxPrintDialogData_EnablePrintToFile 2418
+#define wxPrintDialogData_EnableSelection 2419
+#define wxPrintDialogData_GetAllPages 2420
+#define wxPrintDialogData_GetCollate 2421
+#define wxPrintDialogData_GetFromPage 2422
+#define wxPrintDialogData_GetMaxPage 2423
+#define wxPrintDialogData_GetMinPage 2424
+#define wxPrintDialogData_GetNoCopies 2425
+#define wxPrintDialogData_GetPrintData 2426
+#define wxPrintDialogData_GetPrintToFile 2427
+#define wxPrintDialogData_GetSelection 2428
+#define wxPrintDialogData_GetToPage 2429
+#define wxPrintDialogData_IsOk 2430
+#define wxPrintDialogData_SetCollate 2431
+#define wxPrintDialogData_SetFromPage 2432
+#define wxPrintDialogData_SetMaxPage 2433
+#define wxPrintDialogData_SetMinPage 2434
+#define wxPrintDialogData_SetNoCopies 2435
+#define wxPrintDialogData_SetPrintData 2436
+#define wxPrintDialogData_SetPrintToFile 2437
+#define wxPrintDialogData_SetSelection 2438
+#define wxPrintDialogData_SetToPage 2439
+#define wxPrintData_new_0 2440
+#define wxPrintData_new_1 2441
+#define wxPrintData_destruct 2442
+#define wxPrintData_GetCollate 2443
+#define wxPrintData_GetBin 2444
+#define wxPrintData_GetColour 2445
+#define wxPrintData_GetDuplex 2446
+#define wxPrintData_GetNoCopies 2447
+#define wxPrintData_GetOrientation 2448
+#define wxPrintData_GetPaperId 2449
+#define wxPrintData_GetPrinterName 2450
+#define wxPrintData_GetQuality 2451
+#define wxPrintData_IsOk 2452
+#define wxPrintData_SetBin 2453
+#define wxPrintData_SetCollate 2454
+#define wxPrintData_SetColour 2455
+#define wxPrintData_SetDuplex 2456
+#define wxPrintData_SetNoCopies 2457
+#define wxPrintData_SetOrientation 2458
+#define wxPrintData_SetPaperId 2459
+#define wxPrintData_SetPrinterName 2460
+#define wxPrintData_SetQuality 2461
+#define wxPrintPreview_new_2 2464
+#define wxPrintPreview_new_3 2465
+#define wxPrintPreview_destruct 2467
+#define wxPrintPreview_GetCanvas 2468
+#define wxPrintPreview_GetCurrentPage 2469
+#define wxPrintPreview_GetFrame 2470
+#define wxPrintPreview_GetMaxPage 2471
+#define wxPrintPreview_GetMinPage 2472
+#define wxPrintPreview_GetPrintout 2473
+#define wxPrintPreview_GetPrintoutForPrinting 2474
+#define wxPrintPreview_IsOk 2475
+#define wxPrintPreview_PaintPage 2476
+#define wxPrintPreview_Print 2477
+#define wxPrintPreview_RenderPage 2478
+#define wxPrintPreview_SetCanvas 2479
+#define wxPrintPreview_SetCurrentPage 2480
+#define wxPrintPreview_SetFrame 2481
+#define wxPrintPreview_SetPrintout 2482
+#define wxPrintPreview_SetZoom 2483
+#define wxPreviewFrame_new 2484
+#define wxPreviewFrame_destruct 2485
+#define wxPreviewFrame_CreateControlBar 2486
+#define wxPreviewFrame_CreateCanvas 2487
+#define wxPreviewFrame_Initialize 2488
+#define wxPreviewFrame_OnCloseWindow 2489
+#define wxPreviewControlBar_new 2490
+#define wxPreviewControlBar_destruct 2491
+#define wxPreviewControlBar_CreateButtons 2492
+#define wxPreviewControlBar_GetPrintPreview 2493
+#define wxPreviewControlBar_GetZoomControl 2494
+#define wxPreviewControlBar_SetZoomControl 2495
+#define wxPrinter_new 2497
+#define wxPrinter_CreateAbortWindow 2498
+#define wxPrinter_GetAbort 2499
+#define wxPrinter_GetLastError 2500
+#define wxPrinter_GetPrintDialogData 2501
+#define wxPrinter_Print 2502
+#define wxPrinter_PrintDialog 2503
+#define wxPrinter_ReportError 2504
+#define wxPrinter_Setup 2505
+#define wxPrinter_destroy 2506
+#define wxXmlResource_new_1 2507
+#define wxXmlResource_new_2 2508
+#define wxXmlResource_destruct 2509
+#define wxXmlResource_AttachUnknownControl 2510
+#define wxXmlResource_ClearHandlers 2511
+#define wxXmlResource_CompareVersion 2512
+#define wxXmlResource_Get 2513
+#define wxXmlResource_GetFlags 2514
+#define wxXmlResource_GetVersion 2515
+#define wxXmlResource_GetXRCID 2516
+#define wxXmlResource_InitAllHandlers 2517
+#define wxXmlResource_Load 2518
+#define wxXmlResource_LoadBitmap 2519
+#define wxXmlResource_LoadDialog_2 2520
+#define wxXmlResource_LoadDialog_3 2521
+#define wxXmlResource_LoadFrame_2 2522
+#define wxXmlResource_LoadFrame_3 2523
+#define wxXmlResource_LoadIcon 2524
+#define wxXmlResource_LoadMenu 2525
+#define wxXmlResource_LoadMenuBar_2 2526
+#define wxXmlResource_LoadMenuBar_1 2527
+#define wxXmlResource_LoadPanel_2 2528
+#define wxXmlResource_LoadPanel_3 2529
+#define wxXmlResource_LoadToolBar 2530
+#define wxXmlResource_Set 2531
+#define wxXmlResource_SetFlags 2532
+#define wxXmlResource_Unload 2533
+#define wxXmlResource_xrcctrl 2534
+#define wxHtmlEasyPrinting_new 2535
+#define wxHtmlEasyPrinting_destruct 2536
+#define wxHtmlEasyPrinting_GetPrintData 2537
+#define wxHtmlEasyPrinting_GetPageSetupData 2538
+#define wxHtmlEasyPrinting_PreviewFile 2539
+#define wxHtmlEasyPrinting_PreviewText 2540
+#define wxHtmlEasyPrinting_PrintFile 2541
+#define wxHtmlEasyPrinting_PrintText 2542
+#define wxHtmlEasyPrinting_PageSetup 2543
+#define wxHtmlEasyPrinting_SetFonts 2544
+#define wxHtmlEasyPrinting_SetHeader 2545
+#define wxHtmlEasyPrinting_SetFooter 2546
+#define wxGLCanvas_new_2 2548
+#define wxGLCanvas_new_3_1 2549
+#define wxGLCanvas_new_3_0 2550
+#define wxGLCanvas_GetContext 2551
+#define wxGLCanvas_SetCurrent 2553
+#define wxGLCanvas_SwapBuffers 2554
+#define wxGLCanvas_destroy 2555
+#define wxAuiManager_new 2556
+#define wxAuiManager_destruct 2557
+#define wxAuiManager_AddPane_2_1 2558
+#define wxAuiManager_AddPane_3 2559
+#define wxAuiManager_AddPane_2_0 2560
+#define wxAuiManager_DetachPane 2561
+#define wxAuiManager_GetAllPanes 2562
+#define wxAuiManager_GetArtProvider 2563
+#define wxAuiManager_GetDockSizeConstraint 2564
+#define wxAuiManager_GetFlags 2565
+#define wxAuiManager_GetManagedWindow 2566
+#define wxAuiManager_GetManager 2567
+#define wxAuiManager_GetPane_1_1 2568
+#define wxAuiManager_GetPane_1_0 2569
+#define wxAuiManager_HideHint 2570
+#define wxAuiManager_InsertPane 2571
+#define wxAuiManager_LoadPaneInfo 2572
+#define wxAuiManager_LoadPerspective 2573
+#define wxAuiManager_SavePaneInfo 2574
+#define wxAuiManager_SavePerspective 2575
+#define wxAuiManager_SetArtProvider 2576
+#define wxAuiManager_SetDockSizeConstraint 2577
+#define wxAuiManager_SetFlags 2578
+#define wxAuiManager_SetManagedWindow 2579
+#define wxAuiManager_ShowHint 2580
+#define wxAuiManager_UnInit 2581
+#define wxAuiManager_Update 2582
+#define wxAuiPaneInfo_new_0 2583
+#define wxAuiPaneInfo_new_1 2584
+#define wxAuiPaneInfo_destruct 2585
+#define wxAuiPaneInfo_BestSize_1 2586
+#define wxAuiPaneInfo_BestSize_2 2587
+#define wxAuiPaneInfo_Bottom 2588
+#define wxAuiPaneInfo_BottomDockable 2589
+#define wxAuiPaneInfo_Caption 2590
+#define wxAuiPaneInfo_CaptionVisible 2591
+#define wxAuiPaneInfo_Centre 2592
+#define wxAuiPaneInfo_CentrePane 2593
+#define wxAuiPaneInfo_CloseButton 2594
+#define wxAuiPaneInfo_DefaultPane 2595
+#define wxAuiPaneInfo_DestroyOnClose 2596
+#define wxAuiPaneInfo_Direction 2597
+#define wxAuiPaneInfo_Dock 2598
+#define wxAuiPaneInfo_Dockable 2599
+#define wxAuiPaneInfo_Fixed 2600
+#define wxAuiPaneInfo_Float 2601
+#define wxAuiPaneInfo_Floatable 2602
+#define wxAuiPaneInfo_FloatingPosition_1 2603
+#define wxAuiPaneInfo_FloatingPosition_2 2604
+#define wxAuiPaneInfo_FloatingSize_1 2605
+#define wxAuiPaneInfo_FloatingSize_2 2606
+#define wxAuiPaneInfo_Gripper 2607
+#define wxAuiPaneInfo_GripperTop 2608
+#define wxAuiPaneInfo_HasBorder 2609
+#define wxAuiPaneInfo_HasCaption 2610
+#define wxAuiPaneInfo_HasCloseButton 2611
+#define wxAuiPaneInfo_HasFlag 2612
+#define wxAuiPaneInfo_HasGripper 2613
+#define wxAuiPaneInfo_HasGripperTop 2614
+#define wxAuiPaneInfo_HasMaximizeButton 2615
+#define wxAuiPaneInfo_HasMinimizeButton 2616
+#define wxAuiPaneInfo_HasPinButton 2617
+#define wxAuiPaneInfo_Hide 2618
+#define wxAuiPaneInfo_IsBottomDockable 2619
+#define wxAuiPaneInfo_IsDocked 2620
+#define wxAuiPaneInfo_IsFixed 2621
+#define wxAuiPaneInfo_IsFloatable 2622
+#define wxAuiPaneInfo_IsFloating 2623
+#define wxAuiPaneInfo_IsLeftDockable 2624
+#define wxAuiPaneInfo_IsMovable 2625
+#define wxAuiPaneInfo_IsOk 2626
+#define wxAuiPaneInfo_IsResizable 2627
+#define wxAuiPaneInfo_IsRightDockable 2628
+#define wxAuiPaneInfo_IsShown 2629
+#define wxAuiPaneInfo_IsToolbar 2630
+#define wxAuiPaneInfo_IsTopDockable 2631
+#define wxAuiPaneInfo_Layer 2632
+#define wxAuiPaneInfo_Left 2633
+#define wxAuiPaneInfo_LeftDockable 2634
+#define wxAuiPaneInfo_MaxSize_1 2635
+#define wxAuiPaneInfo_MaxSize_2 2636
+#define wxAuiPaneInfo_MaximizeButton 2637
+#define wxAuiPaneInfo_MinSize_1 2638
+#define wxAuiPaneInfo_MinSize_2 2639
+#define wxAuiPaneInfo_MinimizeButton 2640
+#define wxAuiPaneInfo_Movable 2641
+#define wxAuiPaneInfo_Name 2642
+#define wxAuiPaneInfo_PaneBorder 2643
+#define wxAuiPaneInfo_PinButton 2644
+#define wxAuiPaneInfo_Position 2645
+#define wxAuiPaneInfo_Resizable 2646
+#define wxAuiPaneInfo_Right 2647
+#define wxAuiPaneInfo_RightDockable 2648
+#define wxAuiPaneInfo_Row 2649
+#define wxAuiPaneInfo_SafeSet 2650
+#define wxAuiPaneInfo_SetFlag 2651
+#define wxAuiPaneInfo_Show 2652
+#define wxAuiPaneInfo_ToolbarPane 2653
+#define wxAuiPaneInfo_Top 2654
+#define wxAuiPaneInfo_TopDockable 2655
+#define wxAuiPaneInfo_Window 2656
+#define wxAuiPaneInfo_GetWindow 2657
+#define wxAuiPaneInfo_GetFrame 2658
+#define wxAuiPaneInfo_GetDirection 2659
+#define wxAuiPaneInfo_GetLayer 2660
+#define wxAuiPaneInfo_GetRow 2661
+#define wxAuiPaneInfo_GetPosition 2662
+#define wxAuiPaneInfo_GetFloatingPosition 2663
+#define wxAuiPaneInfo_GetFloatingSize 2664
+#define wxAuiNotebook_new_0 2665
+#define wxAuiNotebook_new_2 2666
+#define wxAuiNotebook_AddPage 2667
+#define wxAuiNotebook_Create 2668
+#define wxAuiNotebook_DeletePage 2669
+#define wxAuiNotebook_GetArtProvider 2670
+#define wxAuiNotebook_GetPage 2671
+#define wxAuiNotebook_GetPageBitmap 2672
+#define wxAuiNotebook_GetPageCount 2673
+#define wxAuiNotebook_GetPageIndex 2674
+#define wxAuiNotebook_GetPageText 2675
+#define wxAuiNotebook_GetSelection 2676
+#define wxAuiNotebook_InsertPage 2677
+#define wxAuiNotebook_RemovePage 2678
+#define wxAuiNotebook_SetArtProvider 2679
+#define wxAuiNotebook_SetFont 2680
+#define wxAuiNotebook_SetPageBitmap 2681
+#define wxAuiNotebook_SetPageText 2682
+#define wxAuiNotebook_SetSelection 2683
+#define wxAuiNotebook_SetTabCtrlHeight 2684
+#define wxAuiNotebook_SetUniformBitmapSize 2685
+#define wxAuiNotebook_destroy 2686
+#define wxAuiTabArt_SetFlags 2687
+#define wxAuiTabArt_SetMeasuringFont 2688
+#define wxAuiTabArt_SetNormalFont 2689
+#define wxAuiTabArt_SetSelectedFont 2690
+#define wxAuiTabArt_SetColour 2691
+#define wxAuiTabArt_SetActiveColour 2692
+#define wxAuiDockArt_GetColour 2693
+#define wxAuiDockArt_GetFont 2694
+#define wxAuiDockArt_GetMetric 2695
+#define wxAuiDockArt_SetColour 2696
+#define wxAuiDockArt_SetFont 2697
+#define wxAuiDockArt_SetMetric 2698
+#define wxAuiSimpleTabArt_new 2699
+#define wxAuiSimpleTabArt_destroy 2700
+#define wxMDIParentFrame_new_0 2701
+#define wxMDIParentFrame_new_4 2702
+#define wxMDIParentFrame_destruct 2703
+#define wxMDIParentFrame_ActivateNext 2704
+#define wxMDIParentFrame_ActivatePrevious 2705
+#define wxMDIParentFrame_ArrangeIcons 2706
+#define wxMDIParentFrame_Cascade 2707
+#define wxMDIParentFrame_Create 2708
+#define wxMDIParentFrame_GetActiveChild 2709
+#define wxMDIParentFrame_GetClientWindow 2710
+#define wxMDIParentFrame_Tile 2711
+#define wxMDIChildFrame_new_0 2712
+#define wxMDIChildFrame_new_4 2713
+#define wxMDIChildFrame_destruct 2714
+#define wxMDIChildFrame_Activate 2715
+#define wxMDIChildFrame_Create 2716
+#define wxMDIChildFrame_Maximize 2717
+#define wxMDIChildFrame_Restore 2718
+#define wxMDIClientWindow_new_0 2719
+#define wxMDIClientWindow_new_2 2720
+#define wxMDIClientWindow_destruct 2721
+#define wxMDIClientWindow_CreateClient 2722
+#define wxLayoutAlgorithm_new 2723
+#define wxLayoutAlgorithm_LayoutFrame 2724
+#define wxLayoutAlgorithm_LayoutMDIFrame 2725
+#define wxLayoutAlgorithm_LayoutWindow 2726
+#define wxLayoutAlgorithm_destroy 2727
+#define wxEvent_GetId 2728
+#define wxEvent_GetSkipped 2729
+#define wxEvent_GetTimestamp 2730
+#define wxEvent_IsCommandEvent 2731
+#define wxEvent_ResumePropagation 2732
+#define wxEvent_ShouldPropagate 2733
+#define wxEvent_Skip 2734
+#define wxEvent_StopPropagation 2735
+#define wxCommandEvent_getClientData 2736
+#define wxCommandEvent_GetExtraLong 2737
+#define wxCommandEvent_GetInt 2738
+#define wxCommandEvent_GetSelection 2739
+#define wxCommandEvent_GetString 2740
+#define wxCommandEvent_IsChecked 2741
+#define wxCommandEvent_IsSelection 2742
+#define wxCommandEvent_SetInt 2743
+#define wxCommandEvent_SetString 2744
+#define wxScrollEvent_GetOrientation 2745
+#define wxScrollEvent_GetPosition 2746
+#define wxScrollWinEvent_GetOrientation 2747
+#define wxScrollWinEvent_GetPosition 2748
+#define wxMouseEvent_AltDown 2749
+#define wxMouseEvent_Button 2750
+#define wxMouseEvent_ButtonDClick 2751
+#define wxMouseEvent_ButtonDown 2752
+#define wxMouseEvent_ButtonUp 2753
+#define wxMouseEvent_CmdDown 2754
+#define wxMouseEvent_ControlDown 2755
+#define wxMouseEvent_Dragging 2756
+#define wxMouseEvent_Entering 2757
+#define wxMouseEvent_GetButton 2758
+#define wxMouseEvent_GetPosition 2761
+#define wxMouseEvent_GetLogicalPosition 2762
+#define wxMouseEvent_GetLinesPerAction 2763
+#define wxMouseEvent_GetWheelRotation 2764
+#define wxMouseEvent_GetWheelDelta 2765
+#define wxMouseEvent_GetX 2766
+#define wxMouseEvent_GetY 2767
+#define wxMouseEvent_IsButton 2768
+#define wxMouseEvent_IsPageScroll 2769
+#define wxMouseEvent_Leaving 2770
+#define wxMouseEvent_LeftDClick 2771
+#define wxMouseEvent_LeftDown 2772
+#define wxMouseEvent_LeftIsDown 2773
+#define wxMouseEvent_LeftUp 2774
+#define wxMouseEvent_MetaDown 2775
+#define wxMouseEvent_MiddleDClick 2776
+#define wxMouseEvent_MiddleDown 2777
+#define wxMouseEvent_MiddleIsDown 2778
+#define wxMouseEvent_MiddleUp 2779
+#define wxMouseEvent_Moving 2780
+#define wxMouseEvent_RightDClick 2781
+#define wxMouseEvent_RightDown 2782
+#define wxMouseEvent_RightIsDown 2783
+#define wxMouseEvent_RightUp 2784
+#define wxMouseEvent_ShiftDown 2785
+#define wxSetCursorEvent_GetCursor 2786
+#define wxSetCursorEvent_GetX 2787
+#define wxSetCursorEvent_GetY 2788
+#define wxSetCursorEvent_HasCursor 2789
+#define wxSetCursorEvent_SetCursor 2790
+#define wxKeyEvent_AltDown 2791
+#define wxKeyEvent_CmdDown 2792
+#define wxKeyEvent_ControlDown 2793
+#define wxKeyEvent_GetKeyCode 2794
+#define wxKeyEvent_GetModifiers 2795
+#define wxKeyEvent_GetPosition 2798
+#define wxKeyEvent_GetRawKeyCode 2799
+#define wxKeyEvent_GetRawKeyFlags 2800
+#define wxKeyEvent_GetUnicodeKey 2801
+#define wxKeyEvent_GetX 2802
+#define wxKeyEvent_GetY 2803
+#define wxKeyEvent_HasModifiers 2804
+#define wxKeyEvent_MetaDown 2805
+#define wxKeyEvent_ShiftDown 2806
+#define wxSizeEvent_GetSize 2807
+#define wxMoveEvent_GetPosition 2808
+#define wxEraseEvent_GetDC 2809
+#define wxFocusEvent_GetWindow 2810
+#define wxChildFocusEvent_GetWindow 2811
+#define wxMenuEvent_GetMenu 2812
+#define wxMenuEvent_GetMenuId 2813
+#define wxMenuEvent_IsPopup 2814
+#define wxCloseEvent_CanVeto 2815
+#define wxCloseEvent_GetLoggingOff 2816
+#define wxCloseEvent_SetCanVeto 2817
+#define wxCloseEvent_SetLoggingOff 2818
+#define wxCloseEvent_Veto 2819
+#define wxShowEvent_SetShow 2820
+#define wxShowEvent_GetShow 2821
+#define wxIconizeEvent_Iconized 2822
+#define wxJoystickEvent_ButtonDown 2823
+#define wxJoystickEvent_ButtonIsDown 2824
+#define wxJoystickEvent_ButtonUp 2825
+#define wxJoystickEvent_GetButtonChange 2826
+#define wxJoystickEvent_GetButtonState 2827
+#define wxJoystickEvent_GetJoystick 2828
+#define wxJoystickEvent_GetPosition 2829
+#define wxJoystickEvent_GetZPosition 2830
+#define wxJoystickEvent_IsButton 2831
+#define wxJoystickEvent_IsMove 2832
+#define wxJoystickEvent_IsZMove 2833
+#define wxUpdateUIEvent_CanUpdate 2834
+#define wxUpdateUIEvent_Check 2835
+#define wxUpdateUIEvent_Enable 2836
+#define wxUpdateUIEvent_Show 2837
+#define wxUpdateUIEvent_GetChecked 2838
+#define wxUpdateUIEvent_GetEnabled 2839
+#define wxUpdateUIEvent_GetShown 2840
+#define wxUpdateUIEvent_GetSetChecked 2841
+#define wxUpdateUIEvent_GetSetEnabled 2842
+#define wxUpdateUIEvent_GetSetShown 2843
+#define wxUpdateUIEvent_GetSetText 2844
+#define wxUpdateUIEvent_GetText 2845
+#define wxUpdateUIEvent_GetMode 2846
+#define wxUpdateUIEvent_GetUpdateInterval 2847
+#define wxUpdateUIEvent_ResetUpdateTime 2848
+#define wxUpdateUIEvent_SetMode 2849
+#define wxUpdateUIEvent_SetText 2850
+#define wxUpdateUIEvent_SetUpdateInterval 2851
+#define wxMouseCaptureChangedEvent_GetCapturedWindow 2852
+#define wxPaletteChangedEvent_SetChangedWindow 2853
+#define wxPaletteChangedEvent_GetChangedWindow 2854
+#define wxQueryNewPaletteEvent_SetPaletteRealized 2855
+#define wxQueryNewPaletteEvent_GetPaletteRealized 2856
+#define wxNavigationKeyEvent_GetDirection 2857
+#define wxNavigationKeyEvent_SetDirection 2858
+#define wxNavigationKeyEvent_IsWindowChange 2859
+#define wxNavigationKeyEvent_SetWindowChange 2860
+#define wxNavigationKeyEvent_IsFromTab 2861
+#define wxNavigationKeyEvent_SetFromTab 2862
+#define wxNavigationKeyEvent_GetCurrentFocus 2863
+#define wxNavigationKeyEvent_SetCurrentFocus 2864
+#define wxHelpEvent_GetOrigin 2865
+#define wxHelpEvent_GetPosition 2866
+#define wxHelpEvent_SetOrigin 2867
+#define wxHelpEvent_SetPosition 2868
+#define wxContextMenuEvent_GetPosition 2869
+#define wxContextMenuEvent_SetPosition 2870
+#define wxIdleEvent_CanSend 2871
+#define wxIdleEvent_GetMode 2872
+#define wxIdleEvent_RequestMore 2873
+#define wxIdleEvent_MoreRequested 2874
+#define wxIdleEvent_SetMode 2875
+#define wxGridEvent_AltDown 2876
+#define wxGridEvent_ControlDown 2877
+#define wxGridEvent_GetCol 2878
+#define wxGridEvent_GetPosition 2879
+#define wxGridEvent_GetRow 2880
+#define wxGridEvent_MetaDown 2881
+#define wxGridEvent_Selecting 2882
+#define wxGridEvent_ShiftDown 2883
+#define wxNotifyEvent_Allow 2884
+#define wxNotifyEvent_IsAllowed 2885
+#define wxNotifyEvent_Veto 2886
+#define wxSashEvent_GetEdge 2887
+#define wxSashEvent_GetDragRect 2888
+#define wxSashEvent_GetDragStatus 2889
+#define wxListEvent_GetCacheFrom 2890
+#define wxListEvent_GetCacheTo 2891
+#define wxListEvent_GetKeyCode 2892
+#define wxListEvent_GetIndex 2893
+#define wxListEvent_GetColumn 2894
+#define wxListEvent_GetPoint 2895
+#define wxListEvent_GetLabel 2896
+#define wxListEvent_GetText 2897
+#define wxListEvent_GetImage 2898
+#define wxListEvent_GetData 2899
+#define wxListEvent_GetMask 2900
+#define wxListEvent_GetItem 2901
+#define wxListEvent_IsEditCancelled 2902
+#define wxDateEvent_GetDate 2903
+#define wxCalendarEvent_GetWeekDay 2904
+#define wxFileDirPickerEvent_GetPath 2905
+#define wxColourPickerEvent_GetColour 2906
+#define wxFontPickerEvent_GetFont 2907
+#define wxStyledTextEvent_GetPosition 2908
+#define wxStyledTextEvent_GetKey 2909
+#define wxStyledTextEvent_GetModifiers 2910
+#define wxStyledTextEvent_GetModificationType 2911
+#define wxStyledTextEvent_GetText 2912
+#define wxStyledTextEvent_GetLength 2913
+#define wxStyledTextEvent_GetLinesAdded 2914
+#define wxStyledTextEvent_GetLine 2915
+#define wxStyledTextEvent_GetFoldLevelNow 2916
+#define wxStyledTextEvent_GetFoldLevelPrev 2917
+#define wxStyledTextEvent_GetMargin 2918
+#define wxStyledTextEvent_GetMessage 2919
+#define wxStyledTextEvent_GetWParam 2920
+#define wxStyledTextEvent_GetLParam 2921
+#define wxStyledTextEvent_GetListType 2922
+#define wxStyledTextEvent_GetX 2923
+#define wxStyledTextEvent_GetY 2924
+#define wxStyledTextEvent_GetDragText 2925
+#define wxStyledTextEvent_GetDragAllowMove 2926
+#define wxStyledTextEvent_GetDragResult 2927
+#define wxStyledTextEvent_GetShift 2928
+#define wxStyledTextEvent_GetControl 2929
+#define wxStyledTextEvent_GetAlt 2930
+#define utils_wxGetKeyState 2931
+#define utils_wxGetMousePosition 2932
+#define utils_wxGetMouseState 2933
+#define utils_wxSetDetectableAutoRepeat 2934
+#define utils_wxBell 2935
+#define utils_wxFindMenuItemId 2936
+#define utils_wxGenericFindWindowAtPoint 2937
+#define utils_wxFindWindowAtPoint 2938
+#define utils_wxBeginBusyCursor 2939
+#define utils_wxEndBusyCursor 2940
+#define utils_wxIsBusy 2941
+#define utils_wxShutdown 2942
+#define utils_wxShell 2943
+#define utils_wxLaunchDefaultBrowser 2944
+#define utils_wxGetEmailAddress 2945
+#define utils_wxGetUserId 2946
+#define utils_wxGetHomeDir 2947
+#define utils_wxNewId 2948
+#define utils_wxRegisterId 2949
+#define utils_wxGetCurrentId 2950
+#define utils_wxGetOsDescription 2951
+#define utils_wxIsPlatformLittleEndian 2952
+#define utils_wxIsPlatform64Bit 2953
+#define gdicmn_wxDisplaySize 2954
+#define gdicmn_wxSetCursor 2955
+#define wxPrintout_new 2956
+#define wxPrintout_destruct 2957
+#define wxPrintout_GetDC 2958
+#define wxPrintout_GetPageSizeMM 2959
+#define wxPrintout_GetPageSizePixels 2960
+#define wxPrintout_GetPaperRectPixels 2961
+#define wxPrintout_GetPPIPrinter 2962
+#define wxPrintout_GetPPIScreen 2963
+#define wxPrintout_GetTitle 2964
+#define wxPrintout_IsPreview 2965
+#define wxPrintout_FitThisSizeToPaper 2966
+#define wxPrintout_FitThisSizeToPage 2967
+#define wxPrintout_FitThisSizeToPageMargins 2968
+#define wxPrintout_MapScreenSizeToPaper 2969
+#define wxPrintout_MapScreenSizeToPage 2970
+#define wxPrintout_MapScreenSizeToPageMargins 2971
+#define wxPrintout_MapScreenSizeToDevice 2972
+#define wxPrintout_GetLogicalPaperRect 2973
+#define wxPrintout_GetLogicalPageRect 2974
+#define wxPrintout_GetLogicalPageMarginsRect 2975
+#define wxPrintout_SetLogicalOrigin 2976
+#define wxPrintout_OffsetLogicalOrigin 2977
+#define wxStyledTextCtrl_new_2 2978
+#define wxStyledTextCtrl_new_0 2979
+#define wxStyledTextCtrl_destruct 2980
+#define wxStyledTextCtrl_Create 2981
+#define wxStyledTextCtrl_AddText 2982
+#define wxStyledTextCtrl_AddStyledText 2983
+#define wxStyledTextCtrl_InsertText 2984
+#define wxStyledTextCtrl_ClearAll 2985
+#define wxStyledTextCtrl_ClearDocumentStyle 2986
+#define wxStyledTextCtrl_GetLength 2987
+#define wxStyledTextCtrl_GetCharAt 2988
+#define wxStyledTextCtrl_GetCurrentPos 2989
+#define wxStyledTextCtrl_GetAnchor 2990
+#define wxStyledTextCtrl_GetStyleAt 2991
+#define wxStyledTextCtrl_Redo 2992
+#define wxStyledTextCtrl_SetUndoCollection 2993
+#define wxStyledTextCtrl_SelectAll 2994
+#define wxStyledTextCtrl_SetSavePoint 2995
+#define wxStyledTextCtrl_GetStyledText 2996
+#define wxStyledTextCtrl_CanRedo 2997
+#define wxStyledTextCtrl_MarkerLineFromHandle 2998
+#define wxStyledTextCtrl_MarkerDeleteHandle 2999
+#define wxStyledTextCtrl_GetUndoCollection 3000
+#define wxStyledTextCtrl_GetViewWhiteSpace 3001
+#define wxStyledTextCtrl_SetViewWhiteSpace 3002
+#define wxStyledTextCtrl_PositionFromPoint 3003
+#define wxStyledTextCtrl_PositionFromPointClose 3004
+#define wxStyledTextCtrl_GotoLine 3005
+#define wxStyledTextCtrl_GotoPos 3006
+#define wxStyledTextCtrl_SetAnchor 3007
+#define wxStyledTextCtrl_GetCurLine 3008
+#define wxStyledTextCtrl_GetEndStyled 3009
+#define wxStyledTextCtrl_ConvertEOLs 3010
+#define wxStyledTextCtrl_GetEOLMode 3011
+#define wxStyledTextCtrl_SetEOLMode 3012
+#define wxStyledTextCtrl_StartStyling 3013
+#define wxStyledTextCtrl_SetStyling 3014
+#define wxStyledTextCtrl_GetBufferedDraw 3015
+#define wxStyledTextCtrl_SetBufferedDraw 3016
+#define wxStyledTextCtrl_SetTabWidth 3017
+#define wxStyledTextCtrl_GetTabWidth 3018
+#define wxStyledTextCtrl_SetCodePage 3019
+#define wxStyledTextCtrl_MarkerDefine 3020
+#define wxStyledTextCtrl_MarkerSetForeground 3021
+#define wxStyledTextCtrl_MarkerSetBackground 3022
+#define wxStyledTextCtrl_MarkerAdd 3023
+#define wxStyledTextCtrl_MarkerDelete 3024
+#define wxStyledTextCtrl_MarkerDeleteAll 3025
+#define wxStyledTextCtrl_MarkerGet 3026
+#define wxStyledTextCtrl_MarkerNext 3027
+#define wxStyledTextCtrl_MarkerPrevious 3028
+#define wxStyledTextCtrl_MarkerDefineBitmap 3029
+#define wxStyledTextCtrl_MarkerAddSet 3030
+#define wxStyledTextCtrl_MarkerSetAlpha 3031
+#define wxStyledTextCtrl_SetMarginType 3032
+#define wxStyledTextCtrl_GetMarginType 3033
+#define wxStyledTextCtrl_SetMarginWidth 3034
+#define wxStyledTextCtrl_GetMarginWidth 3035
+#define wxStyledTextCtrl_SetMarginMask 3036
+#define wxStyledTextCtrl_GetMarginMask 3037
+#define wxStyledTextCtrl_SetMarginSensitive 3038
+#define wxStyledTextCtrl_GetMarginSensitive 3039
+#define wxStyledTextCtrl_StyleClearAll 3040
+#define wxStyledTextCtrl_StyleSetForeground 3041
+#define wxStyledTextCtrl_StyleSetBackground 3042
+#define wxStyledTextCtrl_StyleSetBold 3043
+#define wxStyledTextCtrl_StyleSetItalic 3044
+#define wxStyledTextCtrl_StyleSetSize 3045
+#define wxStyledTextCtrl_StyleSetFaceName 3046
+#define wxStyledTextCtrl_StyleSetEOLFilled 3047
+#define wxStyledTextCtrl_StyleResetDefault 3048
+#define wxStyledTextCtrl_StyleSetUnderline 3049
+#define wxStyledTextCtrl_StyleSetCase 3050
+#define wxStyledTextCtrl_StyleSetHotSpot 3051
+#define wxStyledTextCtrl_SetSelForeground 3052
+#define wxStyledTextCtrl_SetSelBackground 3053
+#define wxStyledTextCtrl_GetSelAlpha 3054
+#define wxStyledTextCtrl_SetSelAlpha 3055
+#define wxStyledTextCtrl_SetCaretForeground 3056
+#define wxStyledTextCtrl_CmdKeyAssign 3057
+#define wxStyledTextCtrl_CmdKeyClear 3058
+#define wxStyledTextCtrl_CmdKeyClearAll 3059
+#define wxStyledTextCtrl_SetStyleBytes 3060
+#define wxStyledTextCtrl_StyleSetVisible 3061
+#define wxStyledTextCtrl_GetCaretPeriod 3062
+#define wxStyledTextCtrl_SetCaretPeriod 3063
+#define wxStyledTextCtrl_SetWordChars 3064
+#define wxStyledTextCtrl_BeginUndoAction 3065
+#define wxStyledTextCtrl_EndUndoAction 3066
+#define wxStyledTextCtrl_IndicatorSetStyle 3067
+#define wxStyledTextCtrl_IndicatorGetStyle 3068
+#define wxStyledTextCtrl_IndicatorSetForeground 3069
+#define wxStyledTextCtrl_IndicatorGetForeground 3070
+#define wxStyledTextCtrl_SetWhitespaceForeground 3071
+#define wxStyledTextCtrl_SetWhitespaceBackground 3072
+#define wxStyledTextCtrl_GetStyleBits 3073
+#define wxStyledTextCtrl_SetLineState 3074
+#define wxStyledTextCtrl_GetLineState 3075
+#define wxStyledTextCtrl_GetMaxLineState 3076
+#define wxStyledTextCtrl_GetCaretLineVisible 3077
+#define wxStyledTextCtrl_SetCaretLineVisible 3078
+#define wxStyledTextCtrl_GetCaretLineBackground 3079
+#define wxStyledTextCtrl_SetCaretLineBackground 3080
+#define wxStyledTextCtrl_AutoCompShow 3081
+#define wxStyledTextCtrl_AutoCompCancel 3082
+#define wxStyledTextCtrl_AutoCompActive 3083
+#define wxStyledTextCtrl_AutoCompPosStart 3084
+#define wxStyledTextCtrl_AutoCompComplete 3085
+#define wxStyledTextCtrl_AutoCompStops 3086
+#define wxStyledTextCtrl_AutoCompSetSeparator 3087
+#define wxStyledTextCtrl_AutoCompGetSeparator 3088
+#define wxStyledTextCtrl_AutoCompSelect 3089
+#define wxStyledTextCtrl_AutoCompSetCancelAtStart 3090
+#define wxStyledTextCtrl_AutoCompGetCancelAtStart 3091
+#define wxStyledTextCtrl_AutoCompSetFillUps 3092
+#define wxStyledTextCtrl_AutoCompSetChooseSingle 3093
+#define wxStyledTextCtrl_AutoCompGetChooseSingle 3094
+#define wxStyledTextCtrl_AutoCompSetIgnoreCase 3095
+#define wxStyledTextCtrl_AutoCompGetIgnoreCase 3096
+#define wxStyledTextCtrl_UserListShow 3097
+#define wxStyledTextCtrl_AutoCompSetAutoHide 3098
+#define wxStyledTextCtrl_AutoCompGetAutoHide 3099
+#define wxStyledTextCtrl_AutoCompSetDropRestOfWord 3100
+#define wxStyledTextCtrl_AutoCompGetDropRestOfWord 3101
+#define wxStyledTextCtrl_RegisterImage 3102
+#define wxStyledTextCtrl_ClearRegisteredImages 3103
+#define wxStyledTextCtrl_AutoCompGetTypeSeparator 3104
+#define wxStyledTextCtrl_AutoCompSetTypeSeparator 3105
+#define wxStyledTextCtrl_AutoCompSetMaxWidth 3106
+#define wxStyledTextCtrl_AutoCompGetMaxWidth 3107
+#define wxStyledTextCtrl_AutoCompSetMaxHeight 3108
+#define wxStyledTextCtrl_AutoCompGetMaxHeight 3109
+#define wxStyledTextCtrl_SetIndent 3110
+#define wxStyledTextCtrl_GetIndent 3111
+#define wxStyledTextCtrl_SetUseTabs 3112
+#define wxStyledTextCtrl_GetUseTabs 3113
+#define wxStyledTextCtrl_SetLineIndentation 3114
+#define wxStyledTextCtrl_GetLineIndentation 3115
+#define wxStyledTextCtrl_GetLineIndentPosition 3116
+#define wxStyledTextCtrl_GetColumn 3117
+#define wxStyledTextCtrl_SetUseHorizontalScrollBar 3118
+#define wxStyledTextCtrl_GetUseHorizontalScrollBar 3119
+#define wxStyledTextCtrl_SetIndentationGuides 3120
+#define wxStyledTextCtrl_GetIndentationGuides 3121
+#define wxStyledTextCtrl_SetHighlightGuide 3122
+#define wxStyledTextCtrl_GetHighlightGuide 3123
+#define wxStyledTextCtrl_GetLineEndPosition 3124
+#define wxStyledTextCtrl_GetCodePage 3125
+#define wxStyledTextCtrl_GetCaretForeground 3126
+#define wxStyledTextCtrl_GetReadOnly 3127
+#define wxStyledTextCtrl_SetCurrentPos 3128
+#define wxStyledTextCtrl_SetSelectionStart 3129
+#define wxStyledTextCtrl_GetSelectionStart 3130
+#define wxStyledTextCtrl_SetSelectionEnd 3131
+#define wxStyledTextCtrl_GetSelectionEnd 3132
+#define wxStyledTextCtrl_SetPrintMagnification 3133
+#define wxStyledTextCtrl_GetPrintMagnification 3134
+#define wxStyledTextCtrl_SetPrintColourMode 3135
+#define wxStyledTextCtrl_GetPrintColourMode 3136
+#define wxStyledTextCtrl_FindText 3137
+#define wxStyledTextCtrl_FormatRange 3138
+#define wxStyledTextCtrl_GetFirstVisibleLine 3139
+#define wxStyledTextCtrl_GetLine 3140
+#define wxStyledTextCtrl_GetLineCount 3141
+#define wxStyledTextCtrl_SetMarginLeft 3142
+#define wxStyledTextCtrl_GetMarginLeft 3143
+#define wxStyledTextCtrl_SetMarginRight 3144
+#define wxStyledTextCtrl_GetMarginRight 3145
+#define wxStyledTextCtrl_GetModify 3146
+#define wxStyledTextCtrl_SetSelection 3147
+#define wxStyledTextCtrl_GetSelectedText 3148
+#define wxStyledTextCtrl_GetTextRange 3149
+#define wxStyledTextCtrl_HideSelection 3150
+#define wxStyledTextCtrl_LineFromPosition 3151
+#define wxStyledTextCtrl_PositionFromLine 3152
+#define wxStyledTextCtrl_LineScroll 3153
+#define wxStyledTextCtrl_EnsureCaretVisible 3154
+#define wxStyledTextCtrl_ReplaceSelection 3155
+#define wxStyledTextCtrl_SetReadOnly 3156
+#define wxStyledTextCtrl_CanPaste 3157
+#define wxStyledTextCtrl_CanUndo 3158
+#define wxStyledTextCtrl_EmptyUndoBuffer 3159
+#define wxStyledTextCtrl_Undo 3160
+#define wxStyledTextCtrl_Cut 3161
+#define wxStyledTextCtrl_Copy 3162
+#define wxStyledTextCtrl_Paste 3163
+#define wxStyledTextCtrl_Clear 3164
+#define wxStyledTextCtrl_SetText 3165
+#define wxStyledTextCtrl_GetText 3166
+#define wxStyledTextCtrl_GetTextLength 3167
+#define wxStyledTextCtrl_GetOvertype 3168
+#define wxStyledTextCtrl_SetCaretWidth 3169
+#define wxStyledTextCtrl_GetCaretWidth 3170
+#define wxStyledTextCtrl_SetTargetStart 3171
+#define wxStyledTextCtrl_GetTargetStart 3172
+#define wxStyledTextCtrl_SetTargetEnd 3173
+#define wxStyledTextCtrl_GetTargetEnd 3174
+#define wxStyledTextCtrl_ReplaceTarget 3175
+#define wxStyledTextCtrl_SearchInTarget 3176
+#define wxStyledTextCtrl_SetSearchFlags 3177
+#define wxStyledTextCtrl_GetSearchFlags 3178
+#define wxStyledTextCtrl_CallTipShow 3179
+#define wxStyledTextCtrl_CallTipCancel 3180
+#define wxStyledTextCtrl_CallTipActive 3181
+#define wxStyledTextCtrl_CallTipPosAtStart 3182
+#define wxStyledTextCtrl_CallTipSetHighlight 3183
+#define wxStyledTextCtrl_CallTipSetBackground 3184
+#define wxStyledTextCtrl_CallTipSetForeground 3185
+#define wxStyledTextCtrl_CallTipSetForegroundHighlight 3186
+#define wxStyledTextCtrl_CallTipUseStyle 3187
+#define wxStyledTextCtrl_VisibleFromDocLine 3188
+#define wxStyledTextCtrl_DocLineFromVisible 3189
+#define wxStyledTextCtrl_WrapCount 3190
+#define wxStyledTextCtrl_SetFoldLevel 3191
+#define wxStyledTextCtrl_GetFoldLevel 3192
+#define wxStyledTextCtrl_GetLastChild 3193
+#define wxStyledTextCtrl_GetFoldParent 3194
+#define wxStyledTextCtrl_ShowLines 3195
+#define wxStyledTextCtrl_HideLines 3196
+#define wxStyledTextCtrl_GetLineVisible 3197
+#define wxStyledTextCtrl_SetFoldExpanded 3198
+#define wxStyledTextCtrl_GetFoldExpanded 3199
+#define wxStyledTextCtrl_ToggleFold 3200
+#define wxStyledTextCtrl_EnsureVisible 3201
+#define wxStyledTextCtrl_SetFoldFlags 3202
+#define wxStyledTextCtrl_EnsureVisibleEnforcePolicy 3203
+#define wxStyledTextCtrl_SetTabIndents 3204
+#define wxStyledTextCtrl_GetTabIndents 3205
+#define wxStyledTextCtrl_SetBackSpaceUnIndents 3206
+#define wxStyledTextCtrl_GetBackSpaceUnIndents 3207
+#define wxStyledTextCtrl_SetMouseDwellTime 3208
+#define wxStyledTextCtrl_GetMouseDwellTime 3209
+#define wxStyledTextCtrl_WordStartPosition 3210
+#define wxStyledTextCtrl_WordEndPosition 3211
+#define wxStyledTextCtrl_SetWrapMode 3212
+#define wxStyledTextCtrl_GetWrapMode 3213
+#define wxStyledTextCtrl_SetWrapVisualFlags 3214
+#define wxStyledTextCtrl_GetWrapVisualFlags 3215
+#define wxStyledTextCtrl_SetWrapVisualFlagsLocation 3216
+#define wxStyledTextCtrl_GetWrapVisualFlagsLocation 3217
+#define wxStyledTextCtrl_SetWrapStartIndent 3218
+#define wxStyledTextCtrl_GetWrapStartIndent 3219
+#define wxStyledTextCtrl_SetLayoutCache 3220
+#define wxStyledTextCtrl_GetLayoutCache 3221
+#define wxStyledTextCtrl_SetScrollWidth 3222
+#define wxStyledTextCtrl_GetScrollWidth 3223
+#define wxStyledTextCtrl_TextWidth 3224
+#define wxStyledTextCtrl_GetEndAtLastLine 3225
+#define wxStyledTextCtrl_TextHeight 3226
+#define wxStyledTextCtrl_SetUseVerticalScrollBar 3227
+#define wxStyledTextCtrl_GetUseVerticalScrollBar 3228
+#define wxStyledTextCtrl_AppendText 3229
+#define wxStyledTextCtrl_GetTwoPhaseDraw 3230
+#define wxStyledTextCtrl_SetTwoPhaseDraw 3231
+#define wxStyledTextCtrl_TargetFromSelection 3232
+#define wxStyledTextCtrl_LinesJoin 3233
+#define wxStyledTextCtrl_LinesSplit 3234
+#define wxStyledTextCtrl_SetFoldMarginColour 3235
+#define wxStyledTextCtrl_SetFoldMarginHiColour 3236
+#define wxStyledTextCtrl_LineDown 3237
+#define wxStyledTextCtrl_LineDownExtend 3238
+#define wxStyledTextCtrl_LineUp 3239
+#define wxStyledTextCtrl_LineUpExtend 3240
+#define wxStyledTextCtrl_CharLeft 3241
+#define wxStyledTextCtrl_CharLeftExtend 3242
+#define wxStyledTextCtrl_CharRight 3243
+#define wxStyledTextCtrl_CharRightExtend 3244
+#define wxStyledTextCtrl_WordLeft 3245
+#define wxStyledTextCtrl_WordLeftExtend 3246
+#define wxStyledTextCtrl_WordRight 3247
+#define wxStyledTextCtrl_WordRightExtend 3248
+#define wxStyledTextCtrl_Home 3249
+#define wxStyledTextCtrl_HomeExtend 3250
+#define wxStyledTextCtrl_LineEnd 3251
+#define wxStyledTextCtrl_LineEndExtend 3252
+#define wxStyledTextCtrl_DocumentStart 3253
+#define wxStyledTextCtrl_DocumentStartExtend 3254
+#define wxStyledTextCtrl_DocumentEnd 3255
+#define wxStyledTextCtrl_DocumentEndExtend 3256
+#define wxStyledTextCtrl_PageUp 3257
+#define wxStyledTextCtrl_PageUpExtend 3258
+#define wxStyledTextCtrl_PageDown 3259
+#define wxStyledTextCtrl_PageDownExtend 3260
+#define wxStyledTextCtrl_EditToggleOvertype 3261
+#define wxStyledTextCtrl_Cancel 3262
+#define wxStyledTextCtrl_DeleteBack 3263
+#define wxStyledTextCtrl_Tab 3264
+#define wxStyledTextCtrl_BackTab 3265
+#define wxStyledTextCtrl_NewLine 3266
+#define wxStyledTextCtrl_FormFeed 3267
+#define wxStyledTextCtrl_VCHome 3268
+#define wxStyledTextCtrl_VCHomeExtend 3269
+#define wxStyledTextCtrl_ZoomIn 3270
+#define wxStyledTextCtrl_ZoomOut 3271
+#define wxStyledTextCtrl_DelWordLeft 3272
+#define wxStyledTextCtrl_DelWordRight 3273
+#define wxStyledTextCtrl_LineCut 3274
+#define wxStyledTextCtrl_LineDelete 3275
+#define wxStyledTextCtrl_LineTranspose 3276
+#define wxStyledTextCtrl_LineDuplicate 3277
+#define wxStyledTextCtrl_LowerCase 3278
+#define wxStyledTextCtrl_UpperCase 3279
+#define wxStyledTextCtrl_LineScrollDown 3280
+#define wxStyledTextCtrl_LineScrollUp 3281
+#define wxStyledTextCtrl_DeleteBackNotLine 3282
+#define wxStyledTextCtrl_HomeDisplay 3283
+#define wxStyledTextCtrl_HomeDisplayExtend 3284
+#define wxStyledTextCtrl_LineEndDisplay 3285
+#define wxStyledTextCtrl_LineEndDisplayExtend 3286
+#define wxStyledTextCtrl_HomeWrapExtend 3287
+#define wxStyledTextCtrl_LineEndWrap 3288
+#define wxStyledTextCtrl_LineEndWrapExtend 3289
+#define wxStyledTextCtrl_VCHomeWrap 3290
+#define wxStyledTextCtrl_VCHomeWrapExtend 3291
+#define wxStyledTextCtrl_LineCopy 3292
+#define wxStyledTextCtrl_MoveCaretInsideView 3293
+#define wxStyledTextCtrl_LineLength 3294
+#define wxStyledTextCtrl_BraceHighlight 3295
+#define wxStyledTextCtrl_BraceBadLight 3296
+#define wxStyledTextCtrl_BraceMatch 3297
+#define wxStyledTextCtrl_GetViewEOL 3298
+#define wxStyledTextCtrl_SetViewEOL 3299
+#define wxStyledTextCtrl_SetModEventMask 3300
+#define wxStyledTextCtrl_GetEdgeColumn 3301
+#define wxStyledTextCtrl_SetEdgeColumn 3302
+#define wxStyledTextCtrl_SetEdgeMode 3303
+#define wxStyledTextCtrl_GetEdgeMode 3304
+#define wxStyledTextCtrl_GetEdgeColour 3305
+#define wxStyledTextCtrl_SetEdgeColour 3306
+#define wxStyledTextCtrl_SearchAnchor 3307
+#define wxStyledTextCtrl_SearchNext 3308
+#define wxStyledTextCtrl_SearchPrev 3309
+#define wxStyledTextCtrl_LinesOnScreen 3310
+#define wxStyledTextCtrl_UsePopUp 3311
+#define wxStyledTextCtrl_SelectionIsRectangle 3312
+#define wxStyledTextCtrl_SetZoom 3313
+#define wxStyledTextCtrl_GetZoom 3314
+#define wxStyledTextCtrl_GetModEventMask 3315
+#define wxStyledTextCtrl_SetSTCFocus 3316
+#define wxStyledTextCtrl_GetSTCFocus 3317
+#define wxStyledTextCtrl_SetStatus 3318
+#define wxStyledTextCtrl_GetStatus 3319
+#define wxStyledTextCtrl_SetMouseDownCaptures 3320
+#define wxStyledTextCtrl_GetMouseDownCaptures 3321
+#define wxStyledTextCtrl_SetSTCCursor 3322
+#define wxStyledTextCtrl_GetSTCCursor 3323
+#define wxStyledTextCtrl_SetControlCharSymbol 3324
+#define wxStyledTextCtrl_GetControlCharSymbol 3325
+#define wxStyledTextCtrl_WordPartLeft 3326
+#define wxStyledTextCtrl_WordPartLeftExtend 3327
+#define wxStyledTextCtrl_WordPartRight 3328
+#define wxStyledTextCtrl_WordPartRightExtend 3329
+#define wxStyledTextCtrl_SetVisiblePolicy 3330
+#define wxStyledTextCtrl_DelLineLeft 3331
+#define wxStyledTextCtrl_DelLineRight 3332
+#define wxStyledTextCtrl_GetXOffset 3333
+#define wxStyledTextCtrl_ChooseCaretX 3334
+#define wxStyledTextCtrl_SetXCaretPolicy 3335
+#define wxStyledTextCtrl_SetYCaretPolicy 3336
+#define wxStyledTextCtrl_GetPrintWrapMode 3337
+#define wxStyledTextCtrl_SetHotspotActiveForeground 3338
+#define wxStyledTextCtrl_SetHotspotActiveBackground 3339
+#define wxStyledTextCtrl_SetHotspotActiveUnderline 3340
+#define wxStyledTextCtrl_SetHotspotSingleLine 3341
+#define wxStyledTextCtrl_ParaDownExtend 3342
+#define wxStyledTextCtrl_ParaUp 3343
+#define wxStyledTextCtrl_ParaUpExtend 3344
+#define wxStyledTextCtrl_PositionBefore 3345
+#define wxStyledTextCtrl_PositionAfter 3346
+#define wxStyledTextCtrl_CopyRange 3347
+#define wxStyledTextCtrl_CopyText 3348
+#define wxStyledTextCtrl_SetSelectionMode 3349
+#define wxStyledTextCtrl_GetSelectionMode 3350
+#define wxStyledTextCtrl_LineDownRectExtend 3351
+#define wxStyledTextCtrl_LineUpRectExtend 3352
+#define wxStyledTextCtrl_CharLeftRectExtend 3353
+#define wxStyledTextCtrl_CharRightRectExtend 3354
+#define wxStyledTextCtrl_HomeRectExtend 3355
+#define wxStyledTextCtrl_VCHomeRectExtend 3356
+#define wxStyledTextCtrl_LineEndRectExtend 3357
+#define wxStyledTextCtrl_PageUpRectExtend 3358
+#define wxStyledTextCtrl_PageDownRectExtend 3359
+#define wxStyledTextCtrl_StutteredPageUp 3360
+#define wxStyledTextCtrl_StutteredPageUpExtend 3361
+#define wxStyledTextCtrl_StutteredPageDown 3362
+#define wxStyledTextCtrl_StutteredPageDownExtend 3363
+#define wxStyledTextCtrl_WordLeftEnd 3364
+#define wxStyledTextCtrl_WordLeftEndExtend 3365
+#define wxStyledTextCtrl_WordRightEnd 3366
+#define wxStyledTextCtrl_WordRightEndExtend 3367
+#define wxStyledTextCtrl_SetWhitespaceChars 3368
+#define wxStyledTextCtrl_SetCharsDefault 3369
+#define wxStyledTextCtrl_AutoCompGetCurrent 3370
+#define wxStyledTextCtrl_Allocate 3371
+#define wxStyledTextCtrl_FindColumn 3372
+#define wxStyledTextCtrl_GetCaretSticky 3373
+#define wxStyledTextCtrl_SetCaretSticky 3374
+#define wxStyledTextCtrl_ToggleCaretSticky 3375
+#define wxStyledTextCtrl_SetPasteConvertEndings 3376
+#define wxStyledTextCtrl_GetPasteConvertEndings 3377
+#define wxStyledTextCtrl_SelectionDuplicate 3378
+#define wxStyledTextCtrl_SetCaretLineBackAlpha 3379
+#define wxStyledTextCtrl_GetCaretLineBackAlpha 3380
+#define wxStyledTextCtrl_StartRecord 3381
+#define wxStyledTextCtrl_StopRecord 3382
+#define wxStyledTextCtrl_SetLexer 3383
+#define wxStyledTextCtrl_GetLexer 3384
+#define wxStyledTextCtrl_Colourise 3385
+#define wxStyledTextCtrl_SetProperty 3386
+#define wxStyledTextCtrl_SetKeyWords 3387
+#define wxStyledTextCtrl_SetLexerLanguage 3388
+#define wxStyledTextCtrl_GetProperty 3389
+#define wxStyledTextCtrl_GetStyleBitsNeeded 3390
+#define wxStyledTextCtrl_GetCurrentLine 3391
+#define wxStyledTextCtrl_StyleSetSpec 3392
+#define wxStyledTextCtrl_StyleSetFont 3393
+#define wxStyledTextCtrl_StyleSetFontAttr 3394
+#define wxStyledTextCtrl_StyleSetCharacterSet 3395
+#define wxStyledTextCtrl_StyleSetFontEncoding 3396
+#define wxStyledTextCtrl_CmdKeyExecute 3397
+#define wxStyledTextCtrl_SetMargins 3398
+#define wxStyledTextCtrl_GetSelection 3399
+#define wxStyledTextCtrl_PointFromPosition 3400
+#define wxStyledTextCtrl_ScrollToLine 3401
+#define wxStyledTextCtrl_ScrollToColumn 3402
+#define wxStyledTextCtrl_SetVScrollBar 3403
+#define wxStyledTextCtrl_SetHScrollBar 3404
+#define wxStyledTextCtrl_GetLastKeydownProcessed 3405
+#define wxStyledTextCtrl_SetLastKeydownProcessed 3406
+#define wxStyledTextCtrl_SaveFile 3407
+#define wxStyledTextCtrl_LoadFile 3408
+#define wxStyledTextCtrl_DoDragOver 3409
+#define wxStyledTextCtrl_DoDropText 3410
+#define wxStyledTextCtrl_GetUseAntiAliasing 3411
+#define wxStyledTextCtrl_AddTextRaw 3412
+#define wxStyledTextCtrl_InsertTextRaw 3413
+#define wxStyledTextCtrl_GetCurLineRaw 3414
+#define wxStyledTextCtrl_GetLineRaw 3415
+#define wxStyledTextCtrl_GetSelectedTextRaw 3416
+#define wxStyledTextCtrl_GetTextRangeRaw 3417
+#define wxStyledTextCtrl_SetTextRaw 3418
+#define wxStyledTextCtrl_GetTextRaw 3419
+#define wxStyledTextCtrl_AppendTextRaw 3420
+#define wxArtProvider_GetBitmap 3421
+#define wxArtProvider_GetIcon 3422
+#define wxTreeEvent_GetKeyCode 3423
+#define wxTreeEvent_GetItem 3424
+#define wxTreeEvent_GetKeyEvent 3425
+#define wxTreeEvent_GetLabel 3426
+#define wxTreeEvent_GetOldItem 3427
+#define wxTreeEvent_GetPoint 3428
+#define wxTreeEvent_IsEditCancelled 3429
+#define wxTreeEvent_SetToolTip 3430
+#define wxNotebookEvent_GetOldSelection 3431
+#define wxNotebookEvent_GetSelection 3432
+#define wxNotebookEvent_SetOldSelection 3433
+#define wxNotebookEvent_SetSelection 3434
+#define wxFileDataObject_new 3435
+#define wxFileDataObject_AddFile 3436
+#define wxFileDataObject_GetFilenames 3437
+#define wxFileDataObject_destroy 3438
+#define wxTextDataObject_new 3439
+#define wxTextDataObject_GetTextLength 3440
+#define wxTextDataObject_GetText 3441
+#define wxTextDataObject_SetText 3442
+#define wxTextDataObject_destroy 3443
+#define wxBitmapDataObject_new_1_1 3444
+#define wxBitmapDataObject_new_1_0 3445
+#define wxBitmapDataObject_GetBitmap 3446
+#define wxBitmapDataObject_SetBitmap 3447
+#define wxBitmapDataObject_destroy 3448
+#define wxClipboard_new 3450
+#define wxClipboard_destruct 3451
+#define wxClipboard_AddData 3452
+#define wxClipboard_Clear 3453
+#define wxClipboard_Close 3454
+#define wxClipboard_Flush 3455
+#define wxClipboard_GetData 3456
+#define wxClipboard_IsOpened 3457
+#define wxClipboard_Open 3458
+#define wxClipboard_SetData 3459
+#define wxClipboard_UsePrimarySelection 3461
+#define wxClipboard_IsSupported 3462
+#define wxClipboard_Get 3463
+#define wxSpinEvent_GetPosition 3464
+#define wxSpinEvent_SetPosition 3465
+#define wxSplitterWindow_new_0 3466
+#define wxSplitterWindow_new_2 3467
+#define wxSplitterWindow_destruct 3468
+#define wxSplitterWindow_Create 3469
+#define wxSplitterWindow_GetMinimumPaneSize 3470
+#define wxSplitterWindow_GetSashGravity 3471
+#define wxSplitterWindow_GetSashPosition 3472
+#define wxSplitterWindow_GetSplitMode 3473
+#define wxSplitterWindow_GetWindow1 3474
+#define wxSplitterWindow_GetWindow2 3475
+#define wxSplitterWindow_Initialize 3476
+#define wxSplitterWindow_IsSplit 3477
+#define wxSplitterWindow_ReplaceWindow 3478
+#define wxSplitterWindow_SetSashGravity 3479
+#define wxSplitterWindow_SetSashPosition 3480
+#define wxSplitterWindow_SetSashSize 3481
+#define wxSplitterWindow_SetMinimumPaneSize 3482
+#define wxSplitterWindow_SetSplitMode 3483
+#define wxSplitterWindow_SplitHorizontally 3484
+#define wxSplitterWindow_SplitVertically 3485
+#define wxSplitterWindow_Unsplit 3486
+#define wxSplitterWindow_UpdateSize 3487
+#define wxSplitterEvent_GetSashPosition 3488
+#define wxSplitterEvent_GetX 3489
+#define wxSplitterEvent_GetY 3490
+#define wxSplitterEvent_GetWindowBeingRemoved 3491
+#define wxSplitterEvent_SetSashPosition 3492
+#define wxHtmlWindow_new_0 3493
+#define wxHtmlWindow_new_2 3494
+#define wxHtmlWindow_AppendToPage 3495
+#define wxHtmlWindow_GetOpenedAnchor 3496
+#define wxHtmlWindow_GetOpenedPage 3497
+#define wxHtmlWindow_GetOpenedPageTitle 3498
+#define wxHtmlWindow_GetRelatedFrame 3499
+#define wxHtmlWindow_HistoryBack 3500
+#define wxHtmlWindow_HistoryCanBack 3501
+#define wxHtmlWindow_HistoryCanForward 3502
+#define wxHtmlWindow_HistoryClear 3503
+#define wxHtmlWindow_HistoryForward 3504
+#define wxHtmlWindow_LoadFile 3505
+#define wxHtmlWindow_LoadPage 3506
+#define wxHtmlWindow_SelectAll 3507
+#define wxHtmlWindow_SelectionToText 3508
+#define wxHtmlWindow_SelectLine 3509
+#define wxHtmlWindow_SelectWord 3510
+#define wxHtmlWindow_SetBorders 3511
+#define wxHtmlWindow_SetFonts 3512
+#define wxHtmlWindow_SetPage 3513
+#define wxHtmlWindow_SetRelatedFrame 3514
+#define wxHtmlWindow_SetRelatedStatusBar 3515
+#define wxHtmlWindow_ToText 3516
+#define wxHtmlWindow_destroy 3517
+#define wxHtmlLinkEvent_GetLinkInfo 3518
+#define wxSystemSettings_GetColour 3519
+#define wxSystemSettings_GetFont 3520
+#define wxSystemSettings_GetMetric 3521
+#define wxSystemSettings_GetScreenType 3522
+#define wxSystemOptions_GetOption 3523
+#define wxSystemOptions_GetOptionInt 3524
+#define wxSystemOptions_HasOption 3525
+#define wxSystemOptions_IsFalse 3526
+#define wxSystemOptions_SetOption_2_1 3527
+#define wxSystemOptions_SetOption_2_0 3528
+#define wxAuiNotebookEvent_SetSelection 3529
+#define wxAuiNotebookEvent_GetSelection 3530
+#define wxAuiNotebookEvent_SetOldSelection 3531
+#define wxAuiNotebookEvent_GetOldSelection 3532
+#define wxAuiNotebookEvent_SetDragSource 3533
+#define wxAuiNotebookEvent_GetDragSource 3534
+#define wxAuiManagerEvent_SetManager 3535
+#define wxAuiManagerEvent_GetManager 3536
+#define wxAuiManagerEvent_SetPane 3537
+#define wxAuiManagerEvent_GetPane 3538
+#define wxAuiManagerEvent_SetButton 3539
+#define wxAuiManagerEvent_GetButton 3540
+#define wxAuiManagerEvent_SetDC 3541
+#define wxAuiManagerEvent_GetDC 3542
+#define wxAuiManagerEvent_Veto 3543
+#define wxAuiManagerEvent_GetVeto 3544
+#define wxAuiManagerEvent_SetCanVeto 3545
+#define wxAuiManagerEvent_CanVeto 3546
+#define wxLogNull_new 3547
+#define wxLogNull_destroy 3548
+#define wxTaskBarIcon_new 3549
+#define wxTaskBarIcon_destruct 3550
+#define wxTaskBarIcon_PopupMenu 3551
+#define wxTaskBarIcon_RemoveIcon 3552
+#define wxTaskBarIcon_SetIcon 3553
+#define wxLocale_new_0 3554
+#define wxLocale_new_2 3556
+#define wxLocale_destruct 3557
+#define wxLocale_Init 3559
+#define wxLocale_AddCatalog_1 3560
+#define wxLocale_AddCatalog_3 3561
+#define wxLocale_AddCatalogLookupPathPrefix 3562
+#define wxLocale_GetCanonicalName 3563
+#define wxLocale_GetLanguage 3564
+#define wxLocale_GetLanguageName 3565
+#define wxLocale_GetLocale 3566
+#define wxLocale_GetName 3567
+#define wxLocale_GetString_2 3568
+#define wxLocale_GetString_4 3569
+#define wxLocale_GetHeaderValue 3570
+#define wxLocale_GetSysName 3571
+#define wxLocale_GetSystemEncoding 3572
+#define wxLocale_GetSystemEncodingName 3573
+#define wxLocale_GetSystemLanguage 3574
+#define wxLocale_IsLoaded 3575
+#define wxLocale_IsOk 3576
+#define wxActivateEvent_GetActive 3577
+#define wxPopupWindow_new_2 3579
+#define wxPopupWindow_new_0 3580
+#define wxPopupWindow_destruct 3582
+#define wxPopupWindow_Create 3583
+#define wxPopupWindow_Position 3584
+#define wxPopupTransientWindow_new_0 3585
+#define wxPopupTransientWindow_new_2 3586
+#define wxPopupTransientWindow_destruct 3587
+#define wxPopupTransientWindow_Popup 3588
+#define wxPopupTransientWindow_Dismiss 3589
+#define wxOverlay_new 3590
+#define wxOverlay_destruct 3591
+#define wxOverlay_Reset 3592
+#define wxDCOverlay_new_6 3593
+#define wxDCOverlay_new_2 3594
+#define wxDCOverlay_destruct 3595
+#define wxDCOverlay_Clear 3596
+#define wxDropFilesEvent_GetPosition 3597
+#define wxDropFilesEvent_GetNumberOfFiles 3598
+#define wxDropFilesEvent_GetFiles 3599
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
index 0d2da5d4a7..1510866f09 100644
--- a/lib/wx/c_src/wxe_impl.cpp
+++ b/lib/wx/c_src/wxe_impl.cpp
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -128,7 +128,7 @@ bool WxeApp::OnInit()
delayed_cleanup = new wxList;
wxe_ps_init2();
- // wxIdleEvent::SetMode(wxIDLE_PROCESS_SPECIFIED); // Hmm printpreview doesn't work in 2.9 with this
+ wxIdleEvent::SetMode(wxIDLE_PROCESS_SPECIFIED);
Connect(wxID_ANY, wxEVT_IDLE, (wxObjectEventFunction) (wxEventFunction) &WxeApp::idle);
Connect(CREATE_PORT, wxeEVT_META_COMMAND,(wxObjectEventFunction) (wxEventFunction) &WxeApp::newMemEnv);
@@ -200,7 +200,8 @@ void WxeApp::OnAssertFailure(const wxChar *file, int line, const wxChar *cfunc,
// Called by wx thread
void WxeApp::idle(wxIdleEvent& event) {
event.Skip(true);
- dispatch_cmds();
+ if(dispatch_cmds())
+ event.RequestMore();
}
/* ************************************************************
@@ -233,14 +234,15 @@ void handle_event_callback(ErlDrvPort port, ErlDrvTermData process)
}
}
-void WxeApp::dispatch_cmds()
+int WxeApp::dispatch_cmds()
{
+ int more = 0;
if(wxe_status != WXE_INITIATED)
- return;
+ return more;
recurse_level++;
// fprintf(stderr, "\r\ndispatch_normal %d\r\n", recurse_level);fflush(stderr);
wxe_queue->cb_start = 0;
- dispatch(wxe_queue);
+ more = dispatch(wxe_queue);
// fprintf(stderr, "\r\ndispatch_done %d\r\n", recurse_level);fflush(stderr);
recurse_level--;
@@ -262,12 +264,16 @@ void WxeApp::dispatch_cmds()
delete event;
}
}
+ return more;
}
+#define BREAK_BATCH 10000
+
int WxeApp::dispatch(wxeFifo * batch)
{
int ping = 0;
int blevel = 0;
+ int wait = 0; // Let event handling generate events sometime
wxeCommand *event;
erl_drv_mutex_lock(wxe_batch_locker_m);
while(true) {
@@ -275,10 +281,14 @@ int WxeApp::dispatch(wxeFifo * batch)
erl_drv_mutex_unlock(wxe_batch_locker_m);
switch(event->op) {
case WXE_BATCH_END:
- {--blevel; }
+ if(blevel>0) {
+ blevel--;
+ if(blevel==0)
+ wait += BREAK_BATCH/4;
+ }
break;
case WXE_BATCH_BEGIN:
- {blevel++; }
+ blevel++;
break;
case WXE_DEBUG_PING:
// When in debugger we don't want to hang waiting for a BATCH_END
@@ -293,7 +303,7 @@ int WxeApp::dispatch(wxeFifo * batch)
memcpy(cb_buff, event->buffer, event->len);
}
event->Delete();
- return blevel;
+ return 1;
default:
if(event->op < OPENGL_START) {
// fprintf(stderr, " c %d (%d) \r\n", event->op, blevel);
@@ -307,13 +317,18 @@ int WxeApp::dispatch(wxeFifo * batch)
erl_drv_mutex_lock(wxe_batch_locker_m);
batch->Cleanup();
}
- if(blevel <= 0) {
+ if(blevel <= 0 || wait >= BREAK_BATCH) {
erl_drv_mutex_unlock(wxe_batch_locker_m);
- return blevel;
+ if(blevel > 0) {
+ return 1; // We are still in a batch but we can let wx check for events
+ } else {
+ return 0;
+ }
}
// sleep until something happens
- //fprintf(stderr, "%s:%d sleep %d %d\r\n", __FILE__, __LINE__, batch->m_n, blevel);fflush(stderr);
+ // fprintf(stderr, "%s:%d sleep %d %d %d\r\n", __FILE__, __LINE__, batch->m_n, blevel, wait);fflush(stderr);
wxe_needs_signal = 1;
+ wait += 1;
while(batch->m_n == 0) {
erl_drv_cond_wait(wxe_batch_locker_c, wxe_batch_locker_m);
}
@@ -666,7 +681,7 @@ void * WxeApp::getPtr(char * bp, wxeMemEnv *memenv) {
throw wxe_badarg(index);
}
void * temp = memenv->ref2ptr[index];
- if((index < memenv->next) && ((index == 0) || (temp > NULL)))
+ if((index < memenv->next) && ((index == 0) || (temp != (void *)NULL)))
return temp;
else {
throw wxe_badarg(index);
@@ -678,7 +693,7 @@ void WxeApp::registerPid(char * bp, ErlDrvTermData pid, wxeMemEnv * memenv) {
if(!memenv)
throw wxe_badarg(index);
void * temp = memenv->ref2ptr[index];
- if((index < memenv->next) && ((index == 0) || (temp > NULL))) {
+ if((index < memenv->next) && ((index == 0) || (temp != (void *) NULL))) {
ptrMap::iterator it;
it = ptr2ref.find(temp);
if(it != ptr2ref.end()) {
diff --git a/lib/wx/c_src/wxe_impl.h b/lib/wx/c_src/wxe_impl.h
index 57dac997ab..140a2bd36a 100644
--- a/lib/wx/c_src/wxe_impl.h
+++ b/lib/wx/c_src/wxe_impl.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2016. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -73,7 +73,7 @@ public:
void wxe_dispatch(wxeCommand& event);
void idle(wxIdleEvent& event);
- void dispatch_cmds();
+ int dispatch_cmds();
void dummy_close(wxEvent& Ev);
bool sendevent(wxEvent *event);
diff --git a/lib/wx/c_src/wxe_main.cpp b/lib/wx/c_src/wxe_main.cpp
index 6fcde42eb5..c7565e33bd 100644
--- a/lib/wx/c_src/wxe_main.cpp
+++ b/lib/wx/c_src/wxe_main.cpp
@@ -67,6 +67,7 @@ int load_native_gui()
int start_native_gui(wxe_data *sd)
{
int res;
+ ErlDrvThreadOpts *opts = NULL;
wxe_status_m = erl_drv_mutex_create((char *) "wxe_status_m");
wxe_status_c = erl_drv_cond_create((char *)"wxe_status_c");
@@ -78,8 +79,11 @@ int start_native_gui(wxe_data *sd)
res = erl_drv_steal_main_thread((char *)"wxwidgets",
&wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL);
#else
+ opts = erl_drv_thread_opts_create((char *)"wx thread");
+ opts->suggested_stack_size = 8192;
res = erl_drv_thread_create((char *)"wxwidgets",
- &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL);
+ &wxe_thread,wxe_main_loop,(void *) sd->pdl,opts);
+ erl_drv_thread_opts_destroy(opts);
#endif
if(res == 0) {
erl_drv_mutex_lock(wxe_status_m);
diff --git a/lib/wx/doc/specs/.gitignore b/lib/wx/doc/specs/.gitignore
new file mode 100644
index 0000000000..322eebcb06
--- /dev/null
+++ b/lib/wx/doc/specs/.gitignore
@@ -0,0 +1 @@
+specs_*.xml
diff --git a/lib/wx/doc/src/Makefile b/lib/wx/doc/src/Makefile
index cae2f9fe4e..23890f47f0 100644
--- a/lib/wx/doc/src/Makefile
+++ b/lib/wx/doc/src/Makefile
@@ -63,10 +63,15 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
+SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml)
+
+TOP_SPECS_FILE = specs.xml
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
XML_FLAGS +=
+SPECS_FLAGS = -I../../include -I../../src
DVIPS_FLAGS +=
# ----------------------------------------------------
@@ -111,6 +116,7 @@ clean clean_docs:
rm -rf $(HTMLDIR)/*
rm -f $(MAN3DIR)/*
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f $(SPECDIR)/*
rm -f errs core *~ ../html/edoc-info
rm -f $(XML_REF3_FILES) $(XML_CHAPTER_FILES) *.html
diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml
index 4f0e166924..d300ab5128 100644
--- a/lib/wx/doc/src/notes.xml
+++ b/lib/wx/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2009</year><year>2016</year>
+ <year>2009</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,6 +32,67 @@
<p>This document describes the changes made to the wxErlang
application.</p>
+<section><title>Wx 1.8.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix a livelock that could be caused by <c>wx:batch/1</c>.</p>
+ <p>
+ Own Id: OTP-14289</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Wx 1.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Allow string arguments to be binaries as specified, i.e.
+ unicode:chardata().</p>
+ <p>
+ Own Id: OTP-13934 Aux Id: ERL-270 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add wxWindow:dragAcceptFiles/2 and wxDropFilesEvent to
+ support simple drag and drop from file browser.</p>
+ <p>
+ Own Id: OTP-13933</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Wx 1.7.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Increased the stacksize for the wx thread. The default
+ stacksize on Windows is 1MB which is not enough if the
+ user created many nested dialogs.</p>
+ <p>
+ Own Id: OTP-13816</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Wx 1.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/wx/doc/src/specs.xml b/lib/wx/doc/src/specs.xml
new file mode 100644
index 0000000000..2e19baafc4
--- /dev/null
+++ b/lib/wx/doc/src/specs.xml
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<specs xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="../specs/specs_wx.xml"/>
+ <xi:include href="../specs/specs_wx_object.xml"/>
+ <xi:include href="../specs/specs_wxAcceleratorEntry.xml"/>
+ <xi:include href="../specs/specs_wxAcceleratorTable.xml"/>
+ <xi:include href="../specs/specs_wxActivateEvent.xml"/>
+ <xi:include href="../specs/specs_wxArtProvider.xml"/>
+ <xi:include href="../specs/specs_wxAuiDockArt.xml"/>
+ <xi:include href="../specs/specs_wxAuiManager.xml"/>
+ <xi:include href="../specs/specs_wxAuiManagerEvent.xml"/>
+ <xi:include href="../specs/specs_wxAuiNotebook.xml"/>
+ <xi:include href="../specs/specs_wxAuiNotebookEvent.xml"/>
+ <xi:include href="../specs/specs_wxAuiPaneInfo.xml"/>
+ <xi:include href="../specs/specs_wxAuiSimpleTabArt.xml"/>
+ <xi:include href="../specs/specs_wxAuiTabArt.xml"/>
+ <xi:include href="../specs/specs_wxBitmapButton.xml"/>
+ <xi:include href="../specs/specs_wxBitmapDataObject.xml"/>
+ <xi:include href="../specs/specs_wxBitmap.xml"/>
+ <xi:include href="../specs/specs_wxBoxSizer.xml"/>
+ <xi:include href="../specs/specs_wxBrush.xml"/>
+ <xi:include href="../specs/specs_wxBufferedDC.xml"/>
+ <xi:include href="../specs/specs_wxBufferedPaintDC.xml"/>
+ <xi:include href="../specs/specs_wxButton.xml"/>
+ <xi:include href="../specs/specs_wxCalendarCtrl.xml"/>
+ <xi:include href="../specs/specs_wxCalendarDateAttr.xml"/>
+ <xi:include href="../specs/specs_wxCalendarEvent.xml"/>
+ <xi:include href="../specs/specs_wxCaret.xml"/>
+ <xi:include href="../specs/specs_wxCheckBox.xml"/>
+ <xi:include href="../specs/specs_wxCheckListBox.xml"/>
+ <xi:include href="../specs/specs_wxChildFocusEvent.xml"/>
+ <xi:include href="../specs/specs_wxChoicebook.xml"/>
+ <xi:include href="../specs/specs_wxChoice.xml"/>
+ <xi:include href="../specs/specs_wxClientDC.xml"/>
+ <xi:include href="../specs/specs_wxClipboard.xml"/>
+ <xi:include href="../specs/specs_wxClipboardTextEvent.xml"/>
+ <xi:include href="../specs/specs_wxCloseEvent.xml"/>
+ <xi:include href="../specs/specs_wxColourData.xml"/>
+ <xi:include href="../specs/specs_wxColourDialog.xml"/>
+ <xi:include href="../specs/specs_wxColourPickerCtrl.xml"/>
+ <xi:include href="../specs/specs_wxColourPickerEvent.xml"/>
+ <xi:include href="../specs/specs_wxComboBox.xml"/>
+ <xi:include href="../specs/specs_wxCommandEvent.xml"/>
+ <xi:include href="../specs/specs_wxContextMenuEvent.xml"/>
+ <xi:include href="../specs/specs_wxControl.xml"/>
+ <xi:include href="../specs/specs_wxControlWithItems.xml"/>
+ <xi:include href="../specs/specs_wxCursor.xml"/>
+ <xi:include href="../specs/specs_wxDataObject.xml"/>
+ <xi:include href="../specs/specs_wxDateEvent.xml"/>
+ <xi:include href="../specs/specs_wxDatePickerCtrl.xml"/>
+ <xi:include href="../specs/specs_wxDC.xml"/>
+ <xi:include href="../specs/specs_wxDCOverlay.xml"/>
+ <xi:include href="../specs/specs_wxDialog.xml"/>
+ <xi:include href="../specs/specs_wxDirDialog.xml"/>
+ <xi:include href="../specs/specs_wxDirPickerCtrl.xml"/>
+ <xi:include href="../specs/specs_wxDisplayChangedEvent.xml"/>
+ <xi:include href="../specs/specs_wxEraseEvent.xml"/>
+ <xi:include href="../specs/specs_wxEvent.xml"/>
+ <xi:include href="../specs/specs_wxEvtHandler.xml"/>
+ <xi:include href="../specs/specs_wxFileDataObject.xml"/>
+ <xi:include href="../specs/specs_wxFileDialog.xml"/>
+ <xi:include href="../specs/specs_wxFileDirPickerEvent.xml"/>
+ <xi:include href="../specs/specs_wxFilePickerCtrl.xml"/>
+ <xi:include href="../specs/specs_wxFindReplaceData.xml"/>
+ <xi:include href="../specs/specs_wxFindReplaceDialog.xml"/>
+ <xi:include href="../specs/specs_wxFlexGridSizer.xml"/>
+ <xi:include href="../specs/specs_wxFocusEvent.xml"/>
+ <xi:include href="../specs/specs_wxFontData.xml"/>
+ <xi:include href="../specs/specs_wxFontDialog.xml"/>
+ <xi:include href="../specs/specs_wxFont.xml"/>
+ <xi:include href="../specs/specs_wxFontPickerCtrl.xml"/>
+ <xi:include href="../specs/specs_wxFontPickerEvent.xml"/>
+ <xi:include href="../specs/specs_wxFrame.xml"/>
+ <xi:include href="../specs/specs_wxGauge.xml"/>
+ <xi:include href="../specs/specs_wxGBSizerItem.xml"/>
+ <xi:include href="../specs/specs_wxGenericDirCtrl.xml"/>
+ <xi:include href="../specs/specs_wxGLCanvas.xml"/>
+ <xi:include href="../specs/specs_wxGraphicsBrush.xml"/>
+ <xi:include href="../specs/specs_wxGraphicsContext.xml"/>
+ <xi:include href="../specs/specs_wxGraphicsFont.xml"/>
+ <xi:include href="../specs/specs_wxGraphicsMatrix.xml"/>
+ <xi:include href="../specs/specs_wxGraphicsObject.xml"/>
+ <xi:include href="../specs/specs_wxGraphicsPath.xml"/>
+ <xi:include href="../specs/specs_wxGraphicsPen.xml"/>
+ <xi:include href="../specs/specs_wxGraphicsRenderer.xml"/>
+ <xi:include href="../specs/specs_wxGridBagSizer.xml"/>
+ <xi:include href="../specs/specs_wxGridCellAttr.xml"/>
+ <xi:include href="../specs/specs_wxGridCellBoolEditor.xml"/>
+ <xi:include href="../specs/specs_wxGridCellBoolRenderer.xml"/>
+ <xi:include href="../specs/specs_wxGridCellChoiceEditor.xml"/>
+ <xi:include href="../specs/specs_wxGridCellEditor.xml"/>
+ <xi:include href="../specs/specs_wxGridCellFloatEditor.xml"/>
+ <xi:include href="../specs/specs_wxGridCellFloatRenderer.xml"/>
+ <xi:include href="../specs/specs_wxGridCellNumberEditor.xml"/>
+ <xi:include href="../specs/specs_wxGridCellNumberRenderer.xml"/>
+ <xi:include href="../specs/specs_wxGridCellRenderer.xml"/>
+ <xi:include href="../specs/specs_wxGridCellStringRenderer.xml"/>
+ <xi:include href="../specs/specs_wxGridCellTextEditor.xml"/>
+ <xi:include href="../specs/specs_wxGrid.xml"/>
+ <xi:include href="../specs/specs_wxGridEvent.xml"/>
+ <xi:include href="../specs/specs_wxGridSizer.xml"/>
+ <xi:include href="../specs/specs_wxHelpEvent.xml"/>
+ <xi:include href="../specs/specs_wxHtmlEasyPrinting.xml"/>
+ <xi:include href="../specs/specs_wxHtmlLinkEvent.xml"/>
+ <xi:include href="../specs/specs_wxHtmlWindow.xml"/>
+ <xi:include href="../specs/specs_wxIconBundle.xml"/>
+ <xi:include href="../specs/specs_wxIcon.xml"/>
+ <xi:include href="../specs/specs_wxIconizeEvent.xml"/>
+ <xi:include href="../specs/specs_wxIdleEvent.xml"/>
+ <xi:include href="../specs/specs_wxImage.xml"/>
+ <xi:include href="../specs/specs_wxImageList.xml"/>
+ <xi:include href="../specs/specs_wxInitDialogEvent.xml"/>
+ <xi:include href="../specs/specs_wxJoystickEvent.xml"/>
+ <xi:include href="../specs/specs_wxKeyEvent.xml"/>
+ <xi:include href="../specs/specs_wxLayoutAlgorithm.xml"/>
+ <xi:include href="../specs/specs_wxListbook.xml"/>
+ <xi:include href="../specs/specs_wxListBox.xml"/>
+ <xi:include href="../specs/specs_wxListCtrl.xml"/>
+ <xi:include href="../specs/specs_wxListEvent.xml"/>
+ <xi:include href="../specs/specs_wxListItemAttr.xml"/>
+ <xi:include href="../specs/specs_wxListItem.xml"/>
+ <xi:include href="../specs/specs_wxListView.xml"/>
+ <xi:include href="../specs/specs_wxLocale.xml"/>
+ <xi:include href="../specs/specs_wxLogNull.xml"/>
+ <xi:include href="../specs/specs_wxMask.xml"/>
+ <xi:include href="../specs/specs_wxMaximizeEvent.xml"/>
+ <xi:include href="../specs/specs_wxMDIChildFrame.xml"/>
+ <xi:include href="../specs/specs_wxMDIClientWindow.xml"/>
+ <xi:include href="../specs/specs_wxMDIParentFrame.xml"/>
+ <xi:include href="../specs/specs_wxMemoryDC.xml"/>
+ <xi:include href="../specs/specs_wxMenuBar.xml"/>
+ <xi:include href="../specs/specs_wxMenu.xml"/>
+ <xi:include href="../specs/specs_wxMenuEvent.xml"/>
+ <xi:include href="../specs/specs_wxMenuItem.xml"/>
+ <xi:include href="../specs/specs_wxMessageDialog.xml"/>
+ <xi:include href="../specs/specs_wxMiniFrame.xml"/>
+ <xi:include href="../specs/specs_wxMirrorDC.xml"/>
+ <xi:include href="../specs/specs_wxMouseCaptureChangedEvent.xml"/>
+ <xi:include href="../specs/specs_wxMouseCaptureLostEvent.xml"/>
+ <xi:include href="../specs/specs_wxMouseEvent.xml"/>
+ <xi:include href="../specs/specs_wxMoveEvent.xml"/>
+ <xi:include href="../specs/specs_wxMultiChoiceDialog.xml"/>
+ <xi:include href="../specs/specs_wxNavigationKeyEvent.xml"/>
+ <xi:include href="../specs/specs_wxNotebook.xml"/>
+ <xi:include href="../specs/specs_wxNotebookEvent.xml"/>
+ <xi:include href="../specs/specs_wxNotifyEvent.xml"/>
+ <xi:include href="../specs/specs_wxOverlay.xml"/>
+ <xi:include href="../specs/specs_wxPageSetupDialogData.xml"/>
+ <xi:include href="../specs/specs_wxPageSetupDialog.xml"/>
+ <xi:include href="../specs/specs_wxPaintDC.xml"/>
+ <xi:include href="../specs/specs_wxPaintEvent.xml"/>
+ <xi:include href="../specs/specs_wxPaletteChangedEvent.xml"/>
+ <xi:include href="../specs/specs_wxPalette.xml"/>
+ <xi:include href="../specs/specs_wxPanel.xml"/>
+ <xi:include href="../specs/specs_wxPasswordEntryDialog.xml"/>
+ <xi:include href="../specs/specs_wxPen.xml"/>
+ <xi:include href="../specs/specs_wxPickerBase.xml"/>
+ <xi:include href="../specs/specs_wxPopupTransientWindow.xml"/>
+ <xi:include href="../specs/specs_wxPopupWindow.xml"/>
+ <xi:include href="../specs/specs_wxPostScriptDC.xml"/>
+ <xi:include href="../specs/specs_wxPreviewCanvas.xml"/>
+ <xi:include href="../specs/specs_wxPreviewControlBar.xml"/>
+ <xi:include href="../specs/specs_wxPreviewFrame.xml"/>
+ <xi:include href="../specs/specs_wxPrintData.xml"/>
+ <xi:include href="../specs/specs_wxPrintDialogData.xml"/>
+ <xi:include href="../specs/specs_wxPrintDialog.xml"/>
+ <xi:include href="../specs/specs_wxPrinter.xml"/>
+ <xi:include href="../specs/specs_wxPrintout.xml"/>
+ <xi:include href="../specs/specs_wxPrintPreview.xml"/>
+ <xi:include href="../specs/specs_wxProgressDialog.xml"/>
+ <xi:include href="../specs/specs_wxQueryNewPaletteEvent.xml"/>
+ <xi:include href="../specs/specs_wxRadioBox.xml"/>
+ <xi:include href="../specs/specs_wxRadioButton.xml"/>
+ <xi:include href="../specs/specs_wxRegion.xml"/>
+ <xi:include href="../specs/specs_wxSashEvent.xml"/>
+ <xi:include href="../specs/specs_wxSashLayoutWindow.xml"/>
+ <xi:include href="../specs/specs_wxSashWindow.xml"/>
+ <xi:include href="../specs/specs_wxScreenDC.xml"/>
+ <xi:include href="../specs/specs_wxScrollBar.xml"/>
+ <xi:include href="../specs/specs_wxScrolledWindow.xml"/>
+ <xi:include href="../specs/specs_wxScrollEvent.xml"/>
+ <xi:include href="../specs/specs_wxScrollWinEvent.xml"/>
+ <xi:include href="../specs/specs_wxSetCursorEvent.xml"/>
+ <xi:include href="../specs/specs_wxShowEvent.xml"/>
+ <xi:include href="../specs/specs_wxSingleChoiceDialog.xml"/>
+ <xi:include href="../specs/specs_wxSizeEvent.xml"/>
+ <xi:include href="../specs/specs_wxSizer.xml"/>
+ <xi:include href="../specs/specs_wxSizerFlags.xml"/>
+ <xi:include href="../specs/specs_wxSizerItem.xml"/>
+ <xi:include href="../specs/specs_wxSlider.xml"/>
+ <xi:include href="../specs/specs_wxSpinButton.xml"/>
+ <xi:include href="../specs/specs_wxSpinCtrl.xml"/>
+ <xi:include href="../specs/specs_wxSpinEvent.xml"/>
+ <xi:include href="../specs/specs_wxSplashScreen.xml"/>
+ <xi:include href="../specs/specs_wxSplitterEvent.xml"/>
+ <xi:include href="../specs/specs_wxSplitterWindow.xml"/>
+ <xi:include href="../specs/specs_wxStaticBitmap.xml"/>
+ <xi:include href="../specs/specs_wxStaticBox.xml"/>
+ <xi:include href="../specs/specs_wxStaticBoxSizer.xml"/>
+ <xi:include href="../specs/specs_wxStaticLine.xml"/>
+ <xi:include href="../specs/specs_wxStaticText.xml"/>
+ <xi:include href="../specs/specs_wxStatusBar.xml"/>
+ <xi:include href="../specs/specs_wxStdDialogButtonSizer.xml"/>
+ <xi:include href="../specs/specs_wxStyledTextCtrl.xml"/>
+ <xi:include href="../specs/specs_wxStyledTextEvent.xml"/>
+ <xi:include href="../specs/specs_wxSysColourChangedEvent.xml"/>
+ <xi:include href="../specs/specs_wxSystemOptions.xml"/>
+ <xi:include href="../specs/specs_wxSystemSettings.xml"/>
+ <xi:include href="../specs/specs_wxTaskBarIcon.xml"/>
+ <xi:include href="../specs/specs_wxTaskBarIconEvent.xml"/>
+ <xi:include href="../specs/specs_wxTextAttr.xml"/>
+ <xi:include href="../specs/specs_wxTextCtrl.xml"/>
+ <xi:include href="../specs/specs_wxTextDataObject.xml"/>
+ <xi:include href="../specs/specs_wxTextEntryDialog.xml"/>
+ <xi:include href="../specs/specs_wxToggleButton.xml"/>
+ <xi:include href="../specs/specs_wxToolBar.xml"/>
+ <xi:include href="../specs/specs_wxToolbook.xml"/>
+ <xi:include href="../specs/specs_wxToolTip.xml"/>
+ <xi:include href="../specs/specs_wxTopLevelWindow.xml"/>
+ <xi:include href="../specs/specs_wxTreebook.xml"/>
+ <xi:include href="../specs/specs_wxTreeCtrl.xml"/>
+ <xi:include href="../specs/specs_wxTreeEvent.xml"/>
+ <xi:include href="../specs/specs_wxUpdateUIEvent.xml"/>
+ <xi:include href="../specs/specs_wxWindowCreateEvent.xml"/>
+ <xi:include href="../specs/specs_wxWindowDC.xml"/>
+ <xi:include href="../specs/specs_wxWindowDestroyEvent.xml"/>
+ <xi:include href="../specs/specs_wxWindow.xml"/>
+ <xi:include href="../specs/specs_wxXmlResource.xml"/>
+ <xi:include href="../specs/specs_wx_misc.xml"/>
+ <xi:include href="../specs/specs_glu.xml"/>
+ <xi:include href="../specs/specs_gl.xml"/>
+</specs>
diff --git a/lib/wx/examples/demo/demo.erl b/lib/wx/examples/demo/demo.erl
index 99c28b3177..8fb70ad7b0 100644
--- a/lib/wx/examples/demo/demo.erl
+++ b/lib/wx/examples/demo/demo.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -60,11 +60,15 @@ start_link() ->
start_link(Debug) ->
wx_object:start_link(?MODULE, Debug, []).
+format(#state{log=Log}, Str, Args) ->
+ wxTextCtrl:appendText(Log, io_lib:format(Str, Args)),
+ ok;
format(Config,Str,Args) ->
Log = proplists:get_value(log, Config),
wxTextCtrl:appendText(Log, io_lib:format(Str, Args)),
ok.
+
-define(DEBUG_NONE, 101).
-define(DEBUG_VERBOSE, 102).
-define(DEBUG_TRACE, 103).
@@ -97,7 +101,11 @@ init(Options) ->
wxFrame:connect(Frame, close_window),
_SB = wxFrame:createStatusBar(Frame,[]),
-
+
+ %% Setup on toplevel because stc seems to steal this on linux
+ wxFrame:dragAcceptFiles(Frame, true),
+ wxFrame:connect(Frame, drop_files),
+
%% T Uppersplitter
%% O Left | Right
%% P Widgets|Code | Demo
@@ -201,15 +209,15 @@ handle_info({'EXIT',_, shutdown}, State) ->
handle_info({'EXIT',_, normal}, State) ->
{noreply,State};
handle_info(Msg, State) ->
- io:format("Got Info ~p~n",[Msg]),
+ format(State, "Got Info ~p~n",[Msg]),
{noreply,State}.
handle_call(Msg, _From, State) ->
- io:format("Got Call ~p~n",[Msg]),
+ format(State, "Got Call ~p~n",[Msg]),
{reply,ok,State}.
handle_cast(Msg, State) ->
- io:format("Got cast ~p~n",[Msg]),
+ format(State, "Got cast ~p~n",[Msg]),
{noreply,State}.
%% Async Events are handled in handle_event as in handle_info
@@ -235,6 +243,9 @@ handle_event(#wx{id = Id,
%% If you are going to printout mainly text it is easier if
%% you generate HTML code and use a wxHtmlEasyPrint
%% instead of using DCs
+
+ %% Printpreview doesn't work in >2.9 without this
+ wxIdleEvent:setMode(?wxIDLE_PROCESS_ALL),
Module = "ex_" ++ wxListBox:getStringSelection(State#state.selector) ++ ".erl",
HEP = wxHtmlEasyPrinting:new([{name, "Print"},
{parentWindow, State#state.win}]),
@@ -286,7 +297,7 @@ handle_event(#wx{event=#wxClose{}}, State = #state{win=Frame}) ->
ok = wxFrame:setStatusText(Frame, "Closing...",[]),
{stop, normal, State};
handle_event(Ev,State) ->
- io:format("~p Got event ~p ~n",[?MODULE, Ev]),
+ format(State, "~p Got event ~p ~n",[?MODULE, Ev]),
{noreply, State}.
code_change(_, _, State) ->
@@ -364,6 +375,7 @@ code_area(Parent) ->
?stc:setVisiblePolicy(Ed, Policy, 3),
%% ?stc:connect(Ed, stc_doubleclick),
+ %% ?stc:connect(Ed, std_do_drop, fun(Ev, Obj) -> io:format("Ev ~p ~p~n",[Ev,Obj]) end),
?stc:setReadOnly(Ed, true),
Ed.
diff --git a/lib/wx/include/wx.hrl b/lib/wx/include/wx.hrl
index af7cca7ed2..a14cc89cee 100644
--- a/lib/wx/include/wx.hrl
+++ b/lib/wx/include/wx.hrl
@@ -33,164 +33,157 @@
%% Here comes the definitions of all event records.
%% they contain the event type and possible some extra information.
--record(wxInitDialog, {type :: wxInitDialogEventType()}). %% Callback event: {@link wxInitDialogEvent}
--type wxInitDialogEventType() :: 'init_dialog'.
--type wxInitDialog() :: #wxInitDialog{}. %% Callback event: {@link wxInitDialogEvent}
+-record(wxActivate,{type :: wxActivateEventType(), %% Callback event: {@link wxActivateEvent}
+ active :: boolean()}).
+-type wxActivateEventType() :: 'activate' | 'activate_app' | 'hibernate'.
+-type wxActivate() :: #wxActivate{}. %% Callback event: {@link wxActivateEvent}
--record(wxClose, {type :: wxCloseEventType()}). %% Callback event: {@link wxCloseEvent}
--type wxCloseEventType() :: 'close_window' | 'end_session' | 'query_end_session'.
--type wxClose() :: #wxClose{}. %% Callback event: {@link wxCloseEvent}
+-record(wxAuiManager,{type :: wxAuiManagerEventType(), %% Callback event: {@link wxAuiManagerEvent}
+ manager :: wxAuiManager:wxAuiManager(),
+ pane :: wxAuiPaneInfo:wxAuiPaneInfo(),
+ button :: integer(),
+ veto_flag :: boolean(),
+ canveto_flag :: boolean(),
+ dc :: wxDC:wxDC()}).
+-type wxAuiManagerEventType() :: 'aui_pane_button' | 'aui_pane_close' | 'aui_pane_maximize' | 'aui_pane_restore' | 'aui_pane_activated' | 'aui_render' | 'aui_find_manager'.
+-type wxAuiManager() :: #wxAuiManager{}. %% Callback event: {@link wxAuiManagerEvent}
--record(wxStyledText,{type :: wxStyledTextEventType(), %% Callback event: {@link wxStyledTextEvent}
- position :: integer(),
- key :: integer(),
- modifiers :: integer(),
- modificationType :: integer(),
- text :: unicode:chardata(),
- length :: integer(),
- linesAdded :: integer(),
- line :: integer(),
- foldLevelNow :: integer(),
- foldLevelPrev :: integer(),
- margin :: integer(),
- message :: integer(),
- wParam :: integer(),
- lParam :: integer(),
- listType :: integer(),
- x :: integer(),
- y :: integer(),
- dragText :: unicode:chardata(),
- dragAllowMove :: boolean(),
- dragResult :: wx:wx_enum()}).
--type wxStyledTextEventType() :: 'stc_change' | 'stc_styleneeded' | 'stc_charadded' | 'stc_savepointreached' | 'stc_savepointleft' | 'stc_romodifyattempt' | 'stc_key' | 'stc_doubleclick' | 'stc_updateui' | 'stc_modified' | 'stc_macrorecord' | 'stc_marginclick' | 'stc_needshown' | 'stc_painted' | 'stc_userlistselection' | 'stc_uridropped' | 'stc_dwellstart' | 'stc_dwellend' | 'stc_start_drag' | 'stc_drag_over' | 'stc_do_drop' | 'stc_zoom' | 'stc_hotspot_click' | 'stc_hotspot_dclick' | 'stc_calltip_click' | 'stc_autocomp_selection'.
--type wxStyledText() :: #wxStyledText{}. %% Callback event: {@link wxStyledTextEvent}
+-record(wxAuiNotebook,{type :: wxAuiNotebookEventType(), %% Callback event: {@link wxAuiNotebookEvent}
+ old_selection :: integer(),
+ selection :: integer(),
+ drag_source :: wxAuiNotebook:wxAuiNotebook()}).
+-type wxAuiNotebookEventType() :: 'command_auinotebook_page_close' | 'command_auinotebook_page_changed' | 'command_auinotebook_page_changing' | 'command_auinotebook_button' | 'command_auinotebook_begin_drag' | 'command_auinotebook_end_drag' | 'command_auinotebook_drag_motion' | 'command_auinotebook_allow_dnd' | 'command_auinotebook_tab_middle_down' | 'command_auinotebook_tab_middle_up' | 'command_auinotebook_tab_right_down' | 'command_auinotebook_tab_right_up' | 'command_auinotebook_page_closed' | 'command_auinotebook_drag_done' | 'command_auinotebook_bg_dclick'.
+-type wxAuiNotebook() :: #wxAuiNotebook{}. %% Callback event: {@link wxAuiNotebookEvent}
--record(wxFileDirPicker,{type :: wxFileDirPickerEventType(), %% Callback event: {@link wxFileDirPickerEvent}
- path :: unicode:chardata()}).
--type wxFileDirPickerEventType() :: 'command_filepicker_changed' | 'command_dirpicker_changed'.
--type wxFileDirPicker() :: #wxFileDirPicker{}. %% Callback event: {@link wxFileDirPickerEvent}
+-record(wxCalendar,{type :: wxCalendarEventType(), %% Callback event: {@link wxCalendarEvent}
+ wday :: wx:wx_enum(),
+ date :: wx:wx_datetime()}).
+-type wxCalendarEventType() :: 'calendar_sel_changed' | 'calendar_day_changed' | 'calendar_month_changed' | 'calendar_year_changed' | 'calendar_doubleclicked' | 'calendar_weekday_clicked'.
+-type wxCalendar() :: #wxCalendar{}. %% Callback event: {@link wxCalendarEvent}
--record(wxNotebook,{type :: wxNotebookEventType(), %% Callback event: {@link wxNotebookEvent}
- nSel :: integer(),
- nOldSel :: integer()}).
--type wxNotebookEventType() :: 'command_notebook_page_changed' | 'command_notebook_page_changing'.
--type wxNotebook() :: #wxNotebook{}. %% Callback event: {@link wxNotebookEvent}
+-record(wxChildFocus, {type :: wxChildFocusEventType()}). %% Callback event: {@link wxChildFocusEvent}
+-type wxChildFocusEventType() :: 'child_focus'.
+-type wxChildFocus() :: #wxChildFocus{}. %% Callback event: {@link wxChildFocusEvent}
--record(wxIdle, {type :: wxIdleEventType()}). %% Callback event: {@link wxIdleEvent}
--type wxIdleEventType() :: 'idle'.
--type wxIdle() :: #wxIdle{}. %% Callback event: {@link wxIdleEvent}
+-record(wxClipboardText, {type :: wxClipboardTextEventType()}). %% Callback event: {@link wxClipboardTextEvent}
+-type wxClipboardTextEventType() :: 'command_text_copy' | 'command_text_cut' | 'command_text_paste'.
+-type wxClipboardText() :: #wxClipboardText{}. %% Callback event: {@link wxClipboardTextEvent}
+
+-record(wxClose, {type :: wxCloseEventType()}). %% Callback event: {@link wxCloseEvent}
+-type wxCloseEventType() :: 'close_window' | 'end_session' | 'query_end_session'.
+-type wxClose() :: #wxClose{}. %% Callback event: {@link wxCloseEvent}
-record(wxColourPicker,{type :: wxColourPickerEventType(), %% Callback event: {@link wxColourPickerEvent}
colour :: wx:wx_colour()}).
-type wxColourPickerEventType() :: 'command_colourpicker_changed'.
-type wxColourPicker() :: #wxColourPicker{}. %% Callback event: {@link wxColourPickerEvent}
--record(wxSplitter, {type :: wxSplitterEventType()}). %% Callback event: {@link wxSplitterEvent}
--type wxSplitterEventType() :: 'command_splitter_sash_pos_changed' | 'command_splitter_sash_pos_changing' | 'command_splitter_doubleclicked' | 'command_splitter_unsplit'.
--type wxSplitter() :: #wxSplitter{}. %% Callback event: {@link wxSplitterEvent}
+-record(wxCommand,{type :: wxCommandEventType(), %% Callback event: {@link wxCommandEvent}
+ cmdString :: unicode:chardata(),
+ commandInt :: integer(),
+ extraLong :: integer()}).
+-type wxCommandEventType() :: 'command_button_clicked' | 'command_checkbox_clicked' | 'command_choice_selected' | 'command_listbox_selected' | 'command_listbox_doubleclicked' | 'command_text_updated' | 'command_text_enter' | 'command_menu_selected' | 'command_slider_updated' | 'command_radiobox_selected' | 'command_radiobutton_selected' | 'command_scrollbar_updated' | 'command_vlbox_selected' | 'command_combobox_selected' | 'command_tool_rclicked' | 'command_tool_enter' | 'command_checklistbox_toggled' | 'command_togglebutton_clicked' | 'command_left_click' | 'command_left_dclick' | 'command_right_click' | 'command_set_focus' | 'command_kill_focus' | 'command_enter'.
+-type wxCommand() :: #wxCommand{}. %% Callback event: {@link wxCommandEvent}
--record(wxSash,{type :: wxSashEventType(), %% Callback event: {@link wxSashEvent}
- edge :: wx:wx_enum(),
- dragRect :: {X::integer(), Y::integer(), W::integer(), H::integer()},
- dragStatus :: wx:wx_enum()}).
--type wxSashEventType() :: 'sash_dragged'.
--type wxSash() :: #wxSash{}. %% Callback event: {@link wxSashEvent}
+-record(wxContextMenu,{type :: wxContextMenuEventType(), %% Callback event: {@link wxContextMenuEvent}
+ pos :: {X::integer(), Y::integer()}}).
+-type wxContextMenuEventType() :: 'context_menu'.
+-type wxContextMenu() :: #wxContextMenu{}. %% Callback event: {@link wxContextMenuEvent}
--record(wxHelp, {type :: wxHelpEventType()}). %% Callback event: {@link wxHelpEvent}
--type wxHelpEventType() :: 'help' | 'detailed_help'.
--type wxHelp() :: #wxHelp{}. %% Callback event: {@link wxHelpEvent}
+-record(wxDate,{type :: wxDateEventType(), %% Callback event: {@link wxDateEvent}
+ date :: wx:wx_datetime()}).
+-type wxDateEventType() :: 'date_changed'.
+-type wxDate() :: #wxDate{}. %% Callback event: {@link wxDateEvent}
-record(wxDisplayChanged, {type :: wxDisplayChangedEventType()}). %% Callback event: {@link wxDisplayChangedEvent}
-type wxDisplayChangedEventType() :: 'display_changed'.
-type wxDisplayChanged() :: #wxDisplayChanged{}. %% Callback event: {@link wxDisplayChangedEvent}
--record(wxMouseCaptureLost, {type :: wxMouseCaptureLostEventType()}). %% Callback event: {@link wxMouseCaptureLostEvent}
--type wxMouseCaptureLostEventType() :: 'mouse_capture_lost'.
--type wxMouseCaptureLost() :: #wxMouseCaptureLost{}. %% Callback event: {@link wxMouseCaptureLostEvent}
+-record(wxDropFiles,{type :: wxDropFilesEventType(), %% Callback event: {@link wxDropFilesEvent}
+ noFiles :: integer(),
+ pos :: {X::integer(), Y::integer()},
+ files :: [unicode:chardata()]}).
+-type wxDropFilesEventType() :: 'drop_files'.
+-type wxDropFiles() :: #wxDropFiles{}. %% Callback event: {@link wxDropFilesEvent}
--record(wxFontPicker,{type :: wxFontPickerEventType(), %% Callback event: {@link wxFontPickerEvent}
- font :: wxFont:wxFont()}).
--type wxFontPickerEventType() :: 'command_fontpicker_changed'.
--type wxFontPicker() :: #wxFontPicker{}. %% Callback event: {@link wxFontPickerEvent}
+-record(wxErase,{type :: wxEraseEventType(), %% Callback event: {@link wxEraseEvent}
+ dc :: wxDC:wxDC()}).
+-type wxEraseEventType() :: 'erase_background'.
+-type wxErase() :: #wxErase{}. %% Callback event: {@link wxEraseEvent}
+
+-record(wxFileDirPicker,{type :: wxFileDirPickerEventType(), %% Callback event: {@link wxFileDirPickerEvent}
+ path :: unicode:chardata()}).
+-type wxFileDirPickerEventType() :: 'command_filepicker_changed' | 'command_dirpicker_changed'.
+-type wxFileDirPicker() :: #wxFileDirPicker{}. %% Callback event: {@link wxFileDirPickerEvent}
-record(wxFocus,{type :: wxFocusEventType(), %% Callback event: {@link wxFocusEvent}
win :: wxWindow:wxWindow()}).
-type wxFocusEventType() :: 'set_focus' | 'kill_focus'.
-type wxFocus() :: #wxFocus{}. %% Callback event: {@link wxFocusEvent}
--record(wxPaletteChanged, {type :: wxPaletteChangedEventType()}). %% Callback event: {@link wxPaletteChangedEvent}
--type wxPaletteChangedEventType() :: 'palette_changed'.
--type wxPaletteChanged() :: #wxPaletteChanged{}. %% Callback event: {@link wxPaletteChangedEvent}
-
--record(wxScroll,{type :: wxScrollEventType(), %% Callback event: {@link wxScrollEvent}
- commandInt :: integer(),
- extraLong :: integer()}).
--type wxScrollEventType() :: 'scroll_top' | 'scroll_bottom' | 'scroll_lineup' | 'scroll_linedown' | 'scroll_pageup' | 'scroll_pagedown' | 'scroll_thumbtrack' | 'scroll_thumbrelease' | 'scroll_changed'.
--type wxScroll() :: #wxScroll{}. %% Callback event: {@link wxScrollEvent}
-
--record(wxChildFocus, {type :: wxChildFocusEventType()}). %% Callback event: {@link wxChildFocusEvent}
--type wxChildFocusEventType() :: 'child_focus'.
--type wxChildFocus() :: #wxChildFocus{}. %% Callback event: {@link wxChildFocusEvent}
-
--record(wxAuiNotebook,{type :: wxAuiNotebookEventType(), %% Callback event: {@link wxAuiNotebookEvent}
- old_selection :: integer(),
- selection :: integer(),
- drag_source :: wxAuiNotebook:wxAuiNotebook()}).
--type wxAuiNotebookEventType() :: 'command_auinotebook_page_close' | 'command_auinotebook_page_changed' | 'command_auinotebook_page_changing' | 'command_auinotebook_button' | 'command_auinotebook_begin_drag' | 'command_auinotebook_end_drag' | 'command_auinotebook_drag_motion' | 'command_auinotebook_allow_dnd' | 'command_auinotebook_tab_middle_down' | 'command_auinotebook_tab_middle_up' | 'command_auinotebook_tab_right_down' | 'command_auinotebook_tab_right_up' | 'command_auinotebook_page_closed' | 'command_auinotebook_drag_done' | 'command_auinotebook_bg_dclick'.
--type wxAuiNotebook() :: #wxAuiNotebook{}. %% Callback event: {@link wxAuiNotebookEvent}
-
--record(wxSize,{type :: wxSizeEventType(), %% Callback event: {@link wxSizeEvent}
- size :: {W::integer(), H::integer()},
- rect :: {X::integer(), Y::integer(), W::integer(), H::integer()}}).
--type wxSizeEventType() :: 'size'.
--type wxSize() :: #wxSize{}. %% Callback event: {@link wxSizeEvent}
-
--record(wxCommand,{type :: wxCommandEventType(), %% Callback event: {@link wxCommandEvent}
- cmdString :: unicode:chardata(),
- commandInt :: integer(),
- extraLong :: integer()}).
--type wxCommandEventType() :: 'command_button_clicked' | 'command_checkbox_clicked' | 'command_choice_selected' | 'command_listbox_selected' | 'command_listbox_doubleclicked' | 'command_text_updated' | 'command_text_enter' | 'command_menu_selected' | 'command_slider_updated' | 'command_radiobox_selected' | 'command_radiobutton_selected' | 'command_scrollbar_updated' | 'command_vlbox_selected' | 'command_combobox_selected' | 'command_tool_rclicked' | 'command_tool_enter' | 'command_checklistbox_toggled' | 'command_togglebutton_clicked' | 'command_left_click' | 'command_left_dclick' | 'command_right_click' | 'command_set_focus' | 'command_kill_focus' | 'command_enter'.
--type wxCommand() :: #wxCommand{}. %% Callback event: {@link wxCommandEvent}
-
--record(wxMaximize, {type :: wxMaximizeEventType()}). %% Callback event: {@link wxMaximizeEvent}
--type wxMaximizeEventType() :: 'maximize'.
--type wxMaximize() :: #wxMaximize{}. %% Callback event: {@link wxMaximizeEvent}
+-record(wxFontPicker,{type :: wxFontPickerEventType(), %% Callback event: {@link wxFontPickerEvent}
+ font :: wxFont:wxFont()}).
+-type wxFontPickerEventType() :: 'command_fontpicker_changed'.
+-type wxFontPicker() :: #wxFontPicker{}. %% Callback event: {@link wxFontPickerEvent}
--record(wxSpin,{type :: wxSpinEventType(), %% Callback event: {@link wxSpinEvent}
- commandInt :: integer()}).
--type wxSpinEventType() :: 'command_spinctrl_updated' | 'spin_up' | 'spin_down' | 'spin'.
--type wxSpin() :: #wxSpin{}. %% Callback event: {@link wxSpinEvent}
+-record(wxGrid,{type :: wxGridEventType(), %% Callback event: {@link wxGridEvent}
+ row :: integer(),
+ col :: integer(),
+ x :: integer(),
+ y :: integer(),
+ selecting :: boolean(),
+ control :: boolean(),
+ meta :: boolean(),
+ shift :: boolean(),
+ alt :: boolean()}).
+-type wxGridEventType() :: 'grid_cell_left_click' | 'grid_cell_right_click' | 'grid_cell_left_dclick' | 'grid_cell_right_dclick' | 'grid_label_left_click' | 'grid_label_right_click' | 'grid_label_left_dclick' | 'grid_label_right_dclick' | 'grid_row_size' | 'grid_col_size' | 'grid_range_select' | 'grid_cell_change' | 'grid_select_cell' | 'grid_editor_shown' | 'grid_editor_hidden' | 'grid_editor_created' | 'grid_cell_begin_drag'.
+-type wxGrid() :: #wxGrid{}. %% Callback event: {@link wxGridEvent}
--record(wxMenu,{type :: wxMenuEventType(), %% Callback event: {@link wxMenuEvent}
- menuId :: integer(),
- menu :: wxMenu:wxMenu()}).
--type wxMenuEventType() :: 'menu_open' | 'menu_close' | 'menu_highlight'.
--type wxMenu() :: #wxMenu{}. %% Callback event: {@link wxMenuEvent}
+-record(wxHelp, {type :: wxHelpEventType()}). %% Callback event: {@link wxHelpEvent}
+-type wxHelpEventType() :: 'help' | 'detailed_help'.
+-type wxHelp() :: #wxHelp{}. %% Callback event: {@link wxHelpEvent}
--record(wxShow,{type :: wxShowEventType(), %% Callback event: {@link wxShowEvent}
- show :: boolean()}).
--type wxShowEventType() :: 'show'.
--type wxShow() :: #wxShow{}. %% Callback event: {@link wxShowEvent}
+-record(wxHtmlLink,{type :: wxHtmlLinkEventType(), %% Callback event: {@link wxHtmlLinkEvent}
+ linkInfo :: wx:wx_wxHtmlLinkInfo()}).
+-type wxHtmlLinkEventType() :: 'command_html_link_clicked'.
+-type wxHtmlLink() :: #wxHtmlLink{}. %% Callback event: {@link wxHtmlLinkEvent}
--record(wxWindowDestroy, {type :: wxWindowDestroyEventType()}). %% Callback event: {@link wxWindowDestroyEvent}
--type wxWindowDestroyEventType() :: 'destroy'.
--type wxWindowDestroy() :: #wxWindowDestroy{}. %% Callback event: {@link wxWindowDestroyEvent}
+-record(wxIconize,{type :: wxIconizeEventType(), %% Callback event: {@link wxIconizeEvent}
+ iconized :: boolean()}).
+-type wxIconizeEventType() :: 'iconize'.
+-type wxIconize() :: #wxIconize{}. %% Callback event: {@link wxIconizeEvent}
--record(wxContextMenu,{type :: wxContextMenuEventType(), %% Callback event: {@link wxContextMenuEvent}
- pos :: {X::integer(), Y::integer()}}).
--type wxContextMenuEventType() :: 'context_menu'.
--type wxContextMenu() :: #wxContextMenu{}. %% Callback event: {@link wxContextMenuEvent}
+-record(wxIdle, {type :: wxIdleEventType()}). %% Callback event: {@link wxIdleEvent}
+-type wxIdleEventType() :: 'idle'.
+-type wxIdle() :: #wxIdle{}. %% Callback event: {@link wxIdleEvent}
--record(wxActivate,{type :: wxActivateEventType(), %% Callback event: {@link wxActivateEvent}
- active :: boolean()}).
--type wxActivateEventType() :: 'activate' | 'activate_app' | 'hibernate'.
--type wxActivate() :: #wxActivate{}. %% Callback event: {@link wxActivateEvent}
+-record(wxInitDialog, {type :: wxInitDialogEventType()}). %% Callback event: {@link wxInitDialogEvent}
+-type wxInitDialogEventType() :: 'init_dialog'.
+-type wxInitDialog() :: #wxInitDialog{}. %% Callback event: {@link wxInitDialogEvent}
--record(wxMove,{type :: wxMoveEventType(), %% Callback event: {@link wxMoveEvent}
+-record(wxJoystick,{type :: wxJoystickEventType(), %% Callback event: {@link wxJoystickEvent}
pos :: {X::integer(), Y::integer()},
- rect :: {X::integer(), Y::integer(), W::integer(), H::integer()}}).
--type wxMoveEventType() :: 'move'.
--type wxMove() :: #wxMove{}. %% Callback event: {@link wxMoveEvent}
+ zPosition :: integer(),
+ buttonChange :: integer(),
+ buttonState :: integer(),
+ joyStick :: integer()}).
+-type wxJoystickEventType() :: 'joy_button_down' | 'joy_button_up' | 'joy_move' | 'joy_zmove'.
+-type wxJoystick() :: #wxJoystick{}. %% Callback event: {@link wxJoystickEvent}
+
+-record(wxKey,{type :: wxKeyEventType(), %% Callback event: {@link wxKeyEvent}
+ x :: integer(),
+ y :: integer(),
+ keyCode :: integer(),
+ controlDown :: boolean(),
+ shiftDown :: boolean(),
+ altDown :: boolean(),
+ metaDown :: boolean(),
+ scanCode :: boolean(),
+ uniChar :: integer(),
+ rawCode :: integer(),
+ rawFlags :: integer()}).
+-type wxKeyEventType() :: 'char' | 'char_hook' | 'key_down' | 'key_up'.
+-type wxKey() :: #wxKey{}. %% Callback event: {@link wxKeyEvent}
-record(wxList,{type :: wxListEventType(), %% Callback event: {@link wxListEvent}
code :: integer(),
@@ -201,24 +194,23 @@
-type wxListEventType() :: 'command_list_begin_drag' | 'command_list_begin_rdrag' | 'command_list_begin_label_edit' | 'command_list_end_label_edit' | 'command_list_delete_item' | 'command_list_delete_all_items' | 'command_list_key_down' | 'command_list_insert_item' | 'command_list_col_click' | 'command_list_col_right_click' | 'command_list_col_begin_drag' | 'command_list_col_dragging' | 'command_list_col_end_drag' | 'command_list_item_selected' | 'command_list_item_deselected' | 'command_list_item_right_click' | 'command_list_item_middle_click' | 'command_list_item_activated' | 'command_list_item_focused' | 'command_list_cache_hint'.
-type wxList() :: #wxList{}. %% Callback event: {@link wxListEvent}
--record(wxClipboardText, {type :: wxClipboardTextEventType()}). %% Callback event: {@link wxClipboardTextEvent}
--type wxClipboardTextEventType() :: 'command_text_copy' | 'command_text_cut' | 'command_text_paste'.
--type wxClipboardText() :: #wxClipboardText{}. %% Callback event: {@link wxClipboardTextEvent}
+-record(wxMaximize, {type :: wxMaximizeEventType()}). %% Callback event: {@link wxMaximizeEvent}
+-type wxMaximizeEventType() :: 'maximize'.
+-type wxMaximize() :: #wxMaximize{}. %% Callback event: {@link wxMaximizeEvent}
--record(wxScrollWin,{type :: wxScrollWinEventType(), %% Callback event: {@link wxScrollWinEvent}
- commandInt :: integer(),
- extraLong :: integer()}).
--type wxScrollWinEventType() :: 'scrollwin_top' | 'scrollwin_bottom' | 'scrollwin_lineup' | 'scrollwin_linedown' | 'scrollwin_pageup' | 'scrollwin_pagedown' | 'scrollwin_thumbtrack' | 'scrollwin_thumbrelease'.
--type wxScrollWin() :: #wxScrollWin{}. %% Callback event: {@link wxScrollWinEvent}
+-record(wxMenu,{type :: wxMenuEventType(), %% Callback event: {@link wxMenuEvent}
+ menuId :: integer(),
+ menu :: wxMenu:wxMenu()}).
+-type wxMenuEventType() :: 'menu_open' | 'menu_close' | 'menu_highlight'.
+-type wxMenu() :: #wxMenu{}. %% Callback event: {@link wxMenuEvent}
--record(wxIconize,{type :: wxIconizeEventType(), %% Callback event: {@link wxIconizeEvent}
- iconized :: boolean()}).
--type wxIconizeEventType() :: 'iconize'.
--type wxIconize() :: #wxIconize{}. %% Callback event: {@link wxIconizeEvent}
+-record(wxMouseCaptureChanged, {type :: wxMouseCaptureChangedEventType()}). %% Callback event: {@link wxMouseCaptureChangedEvent}
+-type wxMouseCaptureChangedEventType() :: 'mouse_capture_changed'.
+-type wxMouseCaptureChanged() :: #wxMouseCaptureChanged{}. %% Callback event: {@link wxMouseCaptureChangedEvent}
--record(wxUpdateUI, {type :: wxUpdateUIEventType()}). %% Callback event: {@link wxUpdateUIEvent}
--type wxUpdateUIEventType() :: 'update_ui'.
--type wxUpdateUI() :: #wxUpdateUI{}. %% Callback event: {@link wxUpdateUIEvent}
+-record(wxMouseCaptureLost, {type :: wxMouseCaptureLostEventType()}). %% Callback event: {@link wxMouseCaptureLostEvent}
+-type wxMouseCaptureLostEventType() :: 'mouse_capture_lost'.
+-type wxMouseCaptureLost() :: #wxMouseCaptureLost{}. %% Callback event: {@link wxMouseCaptureLostEvent}
-record(wxMouse,{type :: wxMouseEventType(), %% Callback event: {@link wxMouseEvent}
x :: integer(),
@@ -236,16 +228,11 @@
-type wxMouseEventType() :: 'left_down' | 'left_up' | 'middle_down' | 'middle_up' | 'right_down' | 'right_up' | 'motion' | 'enter_window' | 'leave_window' | 'left_dclick' | 'middle_dclick' | 'right_dclick' | 'mousewheel'.
-type wxMouse() :: #wxMouse{}. %% Callback event: {@link wxMouseEvent}
--record(wxTree,{type :: wxTreeEventType(), %% Callback event: {@link wxTreeEvent}
- item :: integer(),
- itemOld :: integer(),
- pointDrag :: {X::integer(), Y::integer()}}).
--type wxTreeEventType() :: 'command_tree_begin_drag' | 'command_tree_begin_rdrag' | 'command_tree_begin_label_edit' | 'command_tree_end_label_edit' | 'command_tree_delete_item' | 'command_tree_get_info' | 'command_tree_set_info' | 'command_tree_item_expanded' | 'command_tree_item_expanding' | 'command_tree_item_collapsed' | 'command_tree_item_collapsing' | 'command_tree_sel_changed' | 'command_tree_sel_changing' | 'command_tree_key_down' | 'command_tree_item_activated' | 'command_tree_item_right_click' | 'command_tree_item_middle_click' | 'command_tree_end_drag' | 'command_tree_state_image_click' | 'command_tree_item_gettooltip' | 'command_tree_item_menu'.
--type wxTree() :: #wxTree{}. %% Callback event: {@link wxTreeEvent}
-
--record(wxSysColourChanged, {type :: wxSysColourChangedEventType()}). %% Callback event: {@link wxSysColourChangedEvent}
--type wxSysColourChangedEventType() :: 'sys_colour_changed'.
--type wxSysColourChanged() :: #wxSysColourChanged{}. %% Callback event: {@link wxSysColourChangedEvent}
+-record(wxMove,{type :: wxMoveEventType(), %% Callback event: {@link wxMoveEvent}
+ pos :: {X::integer(), Y::integer()},
+ rect :: {X::integer(), Y::integer(), W::integer(), H::integer()}}).
+-type wxMoveEventType() :: 'move'.
+-type wxMove() :: #wxMove{}. %% Callback event: {@link wxMoveEvent}
-record(wxNavigationKey,{type :: wxNavigationKeyEventType(), %% Callback event: {@link wxNavigationKeyEvent}
flags :: integer(),
@@ -253,103 +240,123 @@
-type wxNavigationKeyEventType() :: 'navigation_key'.
-type wxNavigationKey() :: #wxNavigationKey{}. %% Callback event: {@link wxNavigationKeyEvent}
+-record(wxNotebook,{type :: wxNotebookEventType(), %% Callback event: {@link wxNotebookEvent}
+ nSel :: integer(),
+ nOldSel :: integer()}).
+-type wxNotebookEventType() :: 'command_notebook_page_changed' | 'command_notebook_page_changing'.
+-type wxNotebook() :: #wxNotebook{}. %% Callback event: {@link wxNotebookEvent}
+
+-record(wxPaint, {type :: wxPaintEventType()}). %% Callback event: {@link wxPaintEvent}
+-type wxPaintEventType() :: 'paint'.
+-type wxPaint() :: #wxPaint{}. %% Callback event: {@link wxPaintEvent}
+
+-record(wxPaletteChanged, {type :: wxPaletteChangedEventType()}). %% Callback event: {@link wxPaletteChangedEvent}
+-type wxPaletteChangedEventType() :: 'palette_changed'.
+-type wxPaletteChanged() :: #wxPaletteChanged{}. %% Callback event: {@link wxPaletteChangedEvent}
+
-record(wxQueryNewPalette, {type :: wxQueryNewPaletteEventType()}). %% Callback event: {@link wxQueryNewPaletteEvent}
-type wxQueryNewPaletteEventType() :: 'query_new_palette'.
-type wxQueryNewPalette() :: #wxQueryNewPalette{}. %% Callback event: {@link wxQueryNewPaletteEvent}
--record(wxMouseCaptureChanged, {type :: wxMouseCaptureChangedEventType()}). %% Callback event: {@link wxMouseCaptureChangedEvent}
--type wxMouseCaptureChangedEventType() :: 'mouse_capture_changed'.
--type wxMouseCaptureChanged() :: #wxMouseCaptureChanged{}. %% Callback event: {@link wxMouseCaptureChangedEvent}
+-record(wxSash,{type :: wxSashEventType(), %% Callback event: {@link wxSashEvent}
+ edge :: wx:wx_enum(),
+ dragRect :: {X::integer(), Y::integer(), W::integer(), H::integer()},
+ dragStatus :: wx:wx_enum()}).
+-type wxSashEventType() :: 'sash_dragged'.
+-type wxSash() :: #wxSash{}. %% Callback event: {@link wxSashEvent}
--record(wxHtmlLink,{type :: wxHtmlLinkEventType(), %% Callback event: {@link wxHtmlLinkEvent}
- linkInfo :: wx:wx_wxHtmlLinkInfo()}).
--type wxHtmlLinkEventType() :: 'command_html_link_clicked'.
--type wxHtmlLink() :: #wxHtmlLink{}. %% Callback event: {@link wxHtmlLinkEvent}
+-record(wxScroll,{type :: wxScrollEventType(), %% Callback event: {@link wxScrollEvent}
+ commandInt :: integer(),
+ extraLong :: integer()}).
+-type wxScrollEventType() :: 'scroll_top' | 'scroll_bottom' | 'scroll_lineup' | 'scroll_linedown' | 'scroll_pageup' | 'scroll_pagedown' | 'scroll_thumbtrack' | 'scroll_thumbrelease' | 'scroll_changed'.
+-type wxScroll() :: #wxScroll{}. %% Callback event: {@link wxScrollEvent}
--record(wxKey,{type :: wxKeyEventType(), %% Callback event: {@link wxKeyEvent}
+-record(wxScrollWin,{type :: wxScrollWinEventType(), %% Callback event: {@link wxScrollWinEvent}
+ commandInt :: integer(),
+ extraLong :: integer()}).
+-type wxScrollWinEventType() :: 'scrollwin_top' | 'scrollwin_bottom' | 'scrollwin_lineup' | 'scrollwin_linedown' | 'scrollwin_pageup' | 'scrollwin_pagedown' | 'scrollwin_thumbtrack' | 'scrollwin_thumbrelease'.
+-type wxScrollWin() :: #wxScrollWin{}. %% Callback event: {@link wxScrollWinEvent}
+
+-record(wxSetCursor,{type :: wxSetCursorEventType(), %% Callback event: {@link wxSetCursorEvent}
x :: integer(),
y :: integer(),
- keyCode :: integer(),
- controlDown :: boolean(),
- shiftDown :: boolean(),
- altDown :: boolean(),
- metaDown :: boolean(),
- scanCode :: boolean(),
- uniChar :: integer(),
- rawCode :: integer(),
- rawFlags :: integer()}).
--type wxKeyEventType() :: 'char' | 'char_hook' | 'key_down' | 'key_up'.
--type wxKey() :: #wxKey{}. %% Callback event: {@link wxKeyEvent}
+ cursor :: wxCursor:wxCursor()}).
+-type wxSetCursorEventType() :: 'set_cursor'.
+-type wxSetCursor() :: #wxSetCursor{}. %% Callback event: {@link wxSetCursorEvent}
+
+-record(wxShow,{type :: wxShowEventType(), %% Callback event: {@link wxShowEvent}
+ show :: boolean()}).
+-type wxShowEventType() :: 'show'.
+-type wxShow() :: #wxShow{}. %% Callback event: {@link wxShowEvent}
+
+-record(wxSize,{type :: wxSizeEventType(), %% Callback event: {@link wxSizeEvent}
+ size :: {W::integer(), H::integer()},
+ rect :: {X::integer(), Y::integer(), W::integer(), H::integer()}}).
+-type wxSizeEventType() :: 'size'.
+-type wxSize() :: #wxSize{}. %% Callback event: {@link wxSizeEvent}
+
+-record(wxSpin,{type :: wxSpinEventType(), %% Callback event: {@link wxSpinEvent}
+ commandInt :: integer()}).
+-type wxSpinEventType() :: 'command_spinctrl_updated' | 'spin_up' | 'spin_down' | 'spin'.
+-type wxSpin() :: #wxSpin{}. %% Callback event: {@link wxSpinEvent}
+
+-record(wxSplitter, {type :: wxSplitterEventType()}). %% Callback event: {@link wxSplitterEvent}
+-type wxSplitterEventType() :: 'command_splitter_sash_pos_changed' | 'command_splitter_sash_pos_changing' | 'command_splitter_doubleclicked' | 'command_splitter_unsplit'.
+-type wxSplitter() :: #wxSplitter{}. %% Callback event: {@link wxSplitterEvent}
+
+-record(wxStyledText,{type :: wxStyledTextEventType(), %% Callback event: {@link wxStyledTextEvent}
+ position :: integer(),
+ key :: integer(),
+ modifiers :: integer(),
+ modificationType :: integer(),
+ text :: unicode:chardata(),
+ length :: integer(),
+ linesAdded :: integer(),
+ line :: integer(),
+ foldLevelNow :: integer(),
+ foldLevelPrev :: integer(),
+ margin :: integer(),
+ message :: integer(),
+ wParam :: integer(),
+ lParam :: integer(),
+ listType :: integer(),
+ x :: integer(),
+ y :: integer(),
+ dragText :: unicode:chardata(),
+ dragAllowMove :: boolean(),
+ dragResult :: wx:wx_enum()}).
+-type wxStyledTextEventType() :: 'stc_change' | 'stc_styleneeded' | 'stc_charadded' | 'stc_savepointreached' | 'stc_savepointleft' | 'stc_romodifyattempt' | 'stc_key' | 'stc_doubleclick' | 'stc_updateui' | 'stc_modified' | 'stc_macrorecord' | 'stc_marginclick' | 'stc_needshown' | 'stc_painted' | 'stc_userlistselection' | 'stc_uridropped' | 'stc_dwellstart' | 'stc_dwellend' | 'stc_start_drag' | 'stc_drag_over' | 'stc_do_drop' | 'stc_zoom' | 'stc_hotspot_click' | 'stc_hotspot_dclick' | 'stc_calltip_click' | 'stc_autocomp_selection'.
+-type wxStyledText() :: #wxStyledText{}. %% Callback event: {@link wxStyledTextEvent}
+
+-record(wxSysColourChanged, {type :: wxSysColourChangedEventType()}). %% Callback event: {@link wxSysColourChangedEvent}
+-type wxSysColourChangedEventType() :: 'sys_colour_changed'.
+-type wxSysColourChanged() :: #wxSysColourChanged{}. %% Callback event: {@link wxSysColourChangedEvent}
-record(wxTaskBarIcon, {type :: wxTaskBarIconEventType()}). %% Callback event: {@link wxTaskBarIconEvent}
-type wxTaskBarIconEventType() :: 'taskbar_move' | 'taskbar_left_down' | 'taskbar_left_up' | 'taskbar_right_down' | 'taskbar_right_up' | 'taskbar_left_dclick' | 'taskbar_right_dclick'.
-type wxTaskBarIcon() :: #wxTaskBarIcon{}. %% Callback event: {@link wxTaskBarIconEvent}
--record(wxGrid,{type :: wxGridEventType(), %% Callback event: {@link wxGridEvent}
- row :: integer(),
- col :: integer(),
- x :: integer(),
- y :: integer(),
- selecting :: boolean(),
- control :: boolean(),
- meta :: boolean(),
- shift :: boolean(),
- alt :: boolean()}).
--type wxGridEventType() :: 'grid_cell_left_click' | 'grid_cell_right_click' | 'grid_cell_left_dclick' | 'grid_cell_right_dclick' | 'grid_label_left_click' | 'grid_label_right_click' | 'grid_label_left_dclick' | 'grid_label_right_dclick' | 'grid_row_size' | 'grid_col_size' | 'grid_range_select' | 'grid_cell_change' | 'grid_select_cell' | 'grid_editor_shown' | 'grid_editor_hidden' | 'grid_editor_created' | 'grid_cell_begin_drag'.
--type wxGrid() :: #wxGrid{}. %% Callback event: {@link wxGridEvent}
+-record(wxTree,{type :: wxTreeEventType(), %% Callback event: {@link wxTreeEvent}
+ item :: integer(),
+ itemOld :: integer(),
+ pointDrag :: {X::integer(), Y::integer()}}).
+-type wxTreeEventType() :: 'command_tree_begin_drag' | 'command_tree_begin_rdrag' | 'command_tree_begin_label_edit' | 'command_tree_end_label_edit' | 'command_tree_delete_item' | 'command_tree_get_info' | 'command_tree_set_info' | 'command_tree_item_expanded' | 'command_tree_item_expanding' | 'command_tree_item_collapsed' | 'command_tree_item_collapsing' | 'command_tree_sel_changed' | 'command_tree_sel_changing' | 'command_tree_key_down' | 'command_tree_item_activated' | 'command_tree_item_right_click' | 'command_tree_item_middle_click' | 'command_tree_end_drag' | 'command_tree_state_image_click' | 'command_tree_item_gettooltip' | 'command_tree_item_menu'.
+-type wxTree() :: #wxTree{}. %% Callback event: {@link wxTreeEvent}
--record(wxCalendar,{type :: wxCalendarEventType(), %% Callback event: {@link wxCalendarEvent}
- wday :: wx:wx_enum(),
- date :: wx:wx_datetime()}).
--type wxCalendarEventType() :: 'calendar_sel_changed' | 'calendar_day_changed' | 'calendar_month_changed' | 'calendar_year_changed' | 'calendar_doubleclicked' | 'calendar_weekday_clicked'.
--type wxCalendar() :: #wxCalendar{}. %% Callback event: {@link wxCalendarEvent}
+-record(wxUpdateUI, {type :: wxUpdateUIEventType()}). %% Callback event: {@link wxUpdateUIEvent}
+-type wxUpdateUIEventType() :: 'update_ui'.
+-type wxUpdateUI() :: #wxUpdateUI{}. %% Callback event: {@link wxUpdateUIEvent}
-record(wxWindowCreate, {type :: wxWindowCreateEventType()}). %% Callback event: {@link wxWindowCreateEvent}
-type wxWindowCreateEventType() :: 'create'.
-type wxWindowCreate() :: #wxWindowCreate{}. %% Callback event: {@link wxWindowCreateEvent}
--record(wxDate,{type :: wxDateEventType(), %% Callback event: {@link wxDateEvent}
- date :: wx:wx_datetime()}).
--type wxDateEventType() :: 'date_changed'.
--type wxDate() :: #wxDate{}. %% Callback event: {@link wxDateEvent}
-
--record(wxAuiManager,{type :: wxAuiManagerEventType(), %% Callback event: {@link wxAuiManagerEvent}
- manager :: wxAuiManager:wxAuiManager(),
- pane :: wxAuiPaneInfo:wxAuiPaneInfo(),
- button :: integer(),
- veto_flag :: boolean(),
- canveto_flag :: boolean(),
- dc :: wxDC:wxDC()}).
--type wxAuiManagerEventType() :: 'aui_pane_button' | 'aui_pane_close' | 'aui_pane_maximize' | 'aui_pane_restore' | 'aui_pane_activated' | 'aui_render' | 'aui_find_manager'.
--type wxAuiManager() :: #wxAuiManager{}. %% Callback event: {@link wxAuiManagerEvent}
-
--record(wxJoystick,{type :: wxJoystickEventType(), %% Callback event: {@link wxJoystickEvent}
- pos :: {X::integer(), Y::integer()},
- zPosition :: integer(),
- buttonChange :: integer(),
- buttonState :: integer(),
- joyStick :: integer()}).
--type wxJoystickEventType() :: 'joy_button_down' | 'joy_button_up' | 'joy_move' | 'joy_zmove'.
--type wxJoystick() :: #wxJoystick{}. %% Callback event: {@link wxJoystickEvent}
-
--record(wxPaint, {type :: wxPaintEventType()}). %% Callback event: {@link wxPaintEvent}
--type wxPaintEventType() :: 'paint'.
--type wxPaint() :: #wxPaint{}. %% Callback event: {@link wxPaintEvent}
-
--record(wxErase,{type :: wxEraseEventType(), %% Callback event: {@link wxEraseEvent}
- dc :: wxDC:wxDC()}).
--type wxEraseEventType() :: 'erase_background'.
--type wxErase() :: #wxErase{}. %% Callback event: {@link wxEraseEvent}
-
--record(wxSetCursor,{type :: wxSetCursorEventType(), %% Callback event: {@link wxSetCursorEvent}
- x :: integer(),
- y :: integer(),
- cursor :: wxCursor:wxCursor()}).
--type wxSetCursorEventType() :: 'set_cursor'.
--type wxSetCursor() :: #wxSetCursor{}. %% Callback event: {@link wxSetCursorEvent}
+-record(wxWindowDestroy, {type :: wxWindowDestroyEventType()}). %% Callback event: {@link wxWindowDestroyEvent}
+-type wxWindowDestroyEventType() :: 'destroy'.
+-type wxWindowDestroy() :: #wxWindowDestroy{}. %% Callback event: {@link wxWindowDestroyEvent}
--type event() :: wxActivate() | wxAuiManager() | wxAuiNotebook() | wxCalendar() | wxChildFocus() | wxClipboardText() | wxClose() | wxColourPicker() | wxCommand() | wxContextMenu() | wxDate() | wxDisplayChanged() | wxErase() | wxFileDirPicker() | wxFocus() | wxFontPicker() | wxGrid() | wxHelp() | wxHtmlLink() | wxIconize() | wxIdle() | wxInitDialog() | wxJoystick() | wxKey() | wxList() | wxMaximize() | wxMenu() | wxMouse() | wxMouseCaptureChanged() | wxMouseCaptureLost() | wxMove() | wxNavigationKey() | wxNotebook() | wxPaint() | wxPaletteChanged() | wxQueryNewPalette() | wxSash() | wxScroll() | wxScrollWin() | wxSetCursor() | wxShow() | wxSize() | wxSpin() | wxSplitter() | wxStyledText() | wxSysColourChanged() | wxTaskBarIcon() | wxTree() | wxUpdateUI() | wxWindowCreate() | wxWindowDestroy().
--type wxEventType() :: wxActivateEventType() | wxAuiManagerEventType() | wxAuiNotebookEventType() | wxCalendarEventType() | wxChildFocusEventType() | wxClipboardTextEventType() | wxCloseEventType() | wxColourPickerEventType() | wxCommandEventType() | wxContextMenuEventType() | wxDateEventType() | wxDisplayChangedEventType() | wxEraseEventType() | wxFileDirPickerEventType() | wxFocusEventType() | wxFontPickerEventType() | wxGridEventType() | wxHelpEventType() | wxHtmlLinkEventType() | wxIconizeEventType() | wxIdleEventType() | wxInitDialogEventType() | wxJoystickEventType() | wxKeyEventType() | wxListEventType() | wxMaximizeEventType() | wxMenuEventType() | wxMouseCaptureChangedEventType() | wxMouseCaptureLostEventType() | wxMouseEventType() | wxMoveEventType() | wxNavigationKeyEventType() | wxNotebookEventType() | wxPaintEventType() | wxPaletteChangedEventType() | wxQueryNewPaletteEventType() | wxSashEventType() | wxScrollEventType() | wxScrollWinEventType() | wxSetCursorEventType() | wxShowEventType() | wxSizeEventType() | wxSpinEventType() | wxSplitterEventType() | wxStyledTextEventType() | wxSysColourChangedEventType() | wxTaskBarIconEventType() | wxTreeEventType() | wxUpdateUIEventType() | wxWindowCreateEventType() | wxWindowDestroyEventType().
+-type event() :: wxActivate() | wxAuiManager() | wxAuiNotebook() | wxCalendar() | wxChildFocus() | wxClipboardText() | wxClose() | wxColourPicker() | wxCommand() | wxContextMenu() | wxDate() | wxDisplayChanged() | wxDropFiles() | wxErase() | wxFileDirPicker() | wxFocus() | wxFontPicker() | wxGrid() | wxHelp() | wxHtmlLink() | wxIconize() | wxIdle() | wxInitDialog() | wxJoystick() | wxKey() | wxList() | wxMaximize() | wxMenu() | wxMouse() | wxMouseCaptureChanged() | wxMouseCaptureLost() | wxMove() | wxNavigationKey() | wxNotebook() | wxPaint() | wxPaletteChanged() | wxQueryNewPalette() | wxSash() | wxScroll() | wxScrollWin() | wxSetCursor() | wxShow() | wxSize() | wxSpin() | wxSplitter() | wxStyledText() | wxSysColourChanged() | wxTaskBarIcon() | wxTree() | wxUpdateUI() | wxWindowCreate() | wxWindowDestroy().
+-type wxEventType() :: wxActivateEventType() | wxAuiManagerEventType() | wxAuiNotebookEventType() | wxCalendarEventType() | wxChildFocusEventType() | wxClipboardTextEventType() | wxCloseEventType() | wxColourPickerEventType() | wxCommandEventType() | wxContextMenuEventType() | wxDateEventType() | wxDisplayChangedEventType() | wxDropFilesEventType() | wxEraseEventType() | wxFileDirPickerEventType() | wxFocusEventType() | wxFontPickerEventType() | wxGridEventType() | wxHelpEventType() | wxHtmlLinkEventType() | wxIconizeEventType() | wxIdleEventType() | wxInitDialogEventType() | wxJoystickEventType() | wxKeyEventType() | wxListEventType() | wxMaximizeEventType() | wxMenuEventType() | wxMouseCaptureChangedEventType() | wxMouseCaptureLostEventType() | wxMouseEventType() | wxMoveEventType() | wxNavigationKeyEventType() | wxNotebookEventType() | wxPaintEventType() | wxPaletteChangedEventType() | wxQueryNewPaletteEventType() | wxSashEventType() | wxScrollEventType() | wxScrollWinEventType() | wxSetCursorEventType() | wxShowEventType() | wxSizeEventType() | wxSpinEventType() | wxSplitterEventType() | wxStyledTextEventType() | wxSysColourChangedEventType() | wxTaskBarIconEventType() | wxTreeEventType() | wxUpdateUIEventType() | wxWindowCreateEventType() | wxWindowDestroyEventType().
%% Hardcoded Records
-record(wxMouseState, {x :: integer(), y :: integer(),
@@ -4085,3 +4092,7 @@
-define(wxWINDOW_VARIANT_MINI, 2).
-define(wxWINDOW_VARIANT_LARGE, 3).
-define(wxWINDOW_VARIANT_MAX, 4).
+% From "xmlres.h": wxXmlResourceFlags
+-define(wxXRC_USE_LOCALE, 1).
+-define(wxXRC_NO_SUBCLASSING, 2).
+-define(wxXRC_NO_RELOADING, 4).
diff --git a/lib/wx/src/gen/gl.erl b/lib/wx/src/gen/gl.erl
index e10b99b10a..4a178ea1e4 100644
--- a/lib/wx/src/gen/gl.erl
+++ b/lib/wx/src/gen/gl.erl
@@ -283,7 +283,7 @@
call(Op, Args) ->
Port = get(opengl_port),
_ = erlang:port_control(Port,Op,Args),
- rec().
+ rec(Op).
%% @hidden
cast(Op, Args) ->
@@ -292,11 +292,15 @@ cast(Op, Args) ->
ok.
%% @hidden
-rec() ->
- receive
+rec(Op) ->
+ receive
{'_egl_result_', Res} -> Res;
- {'_egl_error_', Op, Res} -> error({error,Res,Op})
- end.
+ {'_egl_error_', Op, Res} -> error({error,Res,Op});
+ {'_egl_error_', Other, Res} ->
+ Err = io_lib:format("~p in op: ~p", [Res, Other]),
+ error_logger:error_report([{gl, error}, {message, lists:flatten(Err)}]),
+ rec(Op)
+ end.
%% @hidden
send_bin(Bin) when is_binary(Bin) ->
@@ -2949,8 +2953,9 @@ callList(List) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCallLists.xml">external</a> documentation.
-spec callLists(Lists) -> 'ok' when Lists :: [integer()].
callLists(Lists) ->
- cast(5108, <<(length(Lists)):?GLuint,
- (<< <<C:?GLuint>> || C <- Lists>>)/binary,0:(((1+length(Lists)) rem 2)*32)>>).
+ ListsLen = length(Lists),
+ cast(5108, <<ListsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Lists>>)/binary,0:(((1+ListsLen) rem 2)*32)>>).
%% @doc set the display-list base for
%%
@@ -6945,8 +6950,9 @@ genTextures(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteTextures.xml">external</a> documentation.
-spec deleteTextures(Textures) -> 'ok' when Textures :: [integer()].
deleteTextures(Textures) ->
- cast(5272, <<(length(Textures)):?GLuint,
- (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+length(Textures)) rem 2)*32)>>).
+ TexturesLen = length(Textures),
+ cast(5272, <<TexturesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+TexturesLen) rem 2)*32)>>).
%% @doc Bind a named texture to a texturing target
%%
@@ -7026,9 +7032,11 @@ bindTexture(Target,Texture) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPrioritizeTextures.xml">external</a> documentation.
-spec prioritizeTextures(Textures, Priorities) -> 'ok' when Textures :: [integer()],Priorities :: [clamp()].
prioritizeTextures(Textures,Priorities) ->
- cast(5274, <<(length(Textures)):?GLuint,
- (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+length(Textures)) rem 2)*32),(length(Priorities)):?GLuint,
- (<< <<C:?GLclampf>> || C <- Priorities>>)/binary,0:(((1+length(Priorities)) rem 2)*32)>>).
+ TexturesLen = length(Textures),
+ PrioritiesLen = length(Priorities),
+ cast(5274, <<TexturesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+TexturesLen) rem 2)*32),PrioritiesLen:?GLuint,
+ (<< <<C:?GLclampf>> || C <- Priorities>>)/binary,0:(((1+PrioritiesLen) rem 2)*32)>>).
%% @doc Determine if textures are loaded in texture memory
%%
@@ -7052,8 +7060,9 @@ prioritizeTextures(Textures,Priorities) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAreTexturesResident.xml">external</a> documentation.
-spec areTexturesResident(Textures) -> {0|1,Residences :: [0|1]} when Textures :: [integer()].
areTexturesResident(Textures) ->
- call(5275, <<(length(Textures)):?GLuint,
- (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+length(Textures)) rem 2)*32)>>).
+ TexturesLen = length(Textures),
+ call(5275, <<TexturesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+TexturesLen) rem 2)*32)>>).
%% @doc Determine if a name corresponds to a texture
%%
@@ -9650,11 +9659,19 @@ blendFuncSeparate(SfactorRGB,DfactorRGB,SfactorAlpha,DfactorAlpha) ->
%%
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiDrawArrays.xml">external</a> documentation.
--spec multiDrawArrays(Mode, First, Count) -> 'ok' when Mode :: enum(),First :: [integer()],Count :: [integer()].
+-spec multiDrawArrays(Mode, First, Count) -> 'ok' when Mode :: enum(),First :: [integer()]|mem(),Count :: [integer()]|mem().
+multiDrawArrays(Mode,First,Count) when is_list(First), is_list(Count) ->
+ FirstLen = length(First),
+ CountLen = length(Count),
+ cast(5395, <<Mode:?GLenum,FirstLen:?GLuint,
+ (<< <<C:?GLint>> || C <- First>>)/binary,0:(((FirstLen) rem 2)*32),CountLen:?GLuint,
+ (<< <<C:?GLsizei>> || C <- Count>>)/binary,0:(((1+CountLen) rem 2)*32)>>);
multiDrawArrays(Mode,First,Count) ->
- cast(5395, <<Mode:?GLenum,(length(First)):?GLuint,
- (<< <<C:?GLint>> || C <- First>>)/binary,0:(((length(First)) rem 2)*32),(length(Count)):?GLuint,
- (<< <<C:?GLsizei>> || C <- Count>>)/binary,0:(((1+length(Count)) rem 2)*32)>>).
+ send_bin(First),
+ FirstLen = byte_size(if is_binary(First) -> First; is_tuple(First) -> element(2, First) end) div 4,
+ send_bin(Count),
+ CountLen = byte_size(if is_binary(Count) -> Count; is_tuple(Count) -> element(2, Count) end) div 4,
+ cast(5396, <<Mode:?GLenum,FirstLen:?GLint,CountLen:?GLsizei>>).
%% @doc Specify point parameters
%%
@@ -9671,26 +9688,26 @@ multiDrawArrays(Mode,First,Count) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointParameter.xml">external</a> documentation.
-spec pointParameterf(Pname, Param) -> 'ok' when Pname :: enum(),Param :: float().
pointParameterf(Pname,Param) ->
- cast(5396, <<Pname:?GLenum,Param:?GLfloat>>).
+ cast(5397, <<Pname:?GLenum,Param:?GLfloat>>).
%% @doc
%% See {@link pointParameterf/2}
-spec pointParameterfv(Pname, Params) -> 'ok' when Pname :: enum(),Params :: tuple().
pointParameterfv(Pname,Params) ->
- cast(5397, <<Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5398, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link pointParameterf/2}
-spec pointParameteri(Pname, Param) -> 'ok' when Pname :: enum(),Param :: integer().
pointParameteri(Pname,Param) ->
- cast(5398, <<Pname:?GLenum,Param:?GLint>>).
+ cast(5399, <<Pname:?GLenum,Param:?GLint>>).
%% @doc
%% See {@link pointParameterf/2}
-spec pointParameteriv(Pname, Params) -> 'ok' when Pname :: enum(),Params :: tuple().
pointParameteriv(Pname,Params) ->
- cast(5399, <<Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5400, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @doc Set the current fog coordinates
@@ -9702,7 +9719,7 @@ pointParameteriv(Pname,Params) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFogCoord.xml">external</a> documentation.
-spec fogCoordf(Coord) -> 'ok' when Coord :: float().
fogCoordf(Coord) ->
- cast(5400, <<Coord:?GLfloat>>).
+ cast(5401, <<Coord:?GLfloat>>).
%% @equiv fogCoordf(Coord)
-spec fogCoordfv(Coord) -> 'ok' when Coord :: {Coord :: float()}.
@@ -9712,7 +9729,7 @@ fogCoordfv({Coord}) -> fogCoordf(Coord).
%% See {@link fogCoordf/1}
-spec fogCoordd(Coord) -> 'ok' when Coord :: float().
fogCoordd(Coord) ->
- cast(5401, <<Coord:?GLdouble>>).
+ cast(5402, <<Coord:?GLdouble>>).
%% @equiv fogCoordd(Coord)
-spec fogCoorddv(Coord) -> 'ok' when Coord :: {Coord :: float()}.
@@ -9743,10 +9760,10 @@ fogCoorddv({Coord}) -> fogCoordd(Coord).
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFogCoordPointer.xml">external</a> documentation.
-spec fogCoordPointer(Type, Stride, Pointer) -> 'ok' when Type :: enum(),Stride :: integer(),Pointer :: offset()|mem().
fogCoordPointer(Type,Stride,Pointer) when is_integer(Pointer) ->
- cast(5402, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5403, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
fogCoordPointer(Type,Stride,Pointer) ->
send_bin(Pointer),
- cast(5403, <<Type:?GLenum,Stride:?GLsizei>>).
+ cast(5404, <<Type:?GLenum,Stride:?GLsizei>>).
%% @doc Set the current secondary color
%%
@@ -9780,7 +9797,7 @@ fogCoordPointer(Type,Stride,Pointer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation.
-spec secondaryColor3b(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3b(Red,Green,Blue) ->
- cast(5404, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>).
+ cast(5405, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>).
%% @equiv secondaryColor3b(Red,Green,Blue)
-spec secondaryColor3bv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9790,7 +9807,7 @@ secondaryColor3bv({Red,Green,Blue}) -> secondaryColor3b(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3d(Red, Green, Blue) -> 'ok' when Red :: float(),Green :: float(),Blue :: float().
secondaryColor3d(Red,Green,Blue) ->
- cast(5405, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>).
+ cast(5406, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>).
%% @equiv secondaryColor3d(Red,Green,Blue)
-spec secondaryColor3dv(V) -> 'ok' when V :: {Red :: float(),Green :: float(),Blue :: float()}.
@@ -9800,7 +9817,7 @@ secondaryColor3dv({Red,Green,Blue}) -> secondaryColor3d(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3f(Red, Green, Blue) -> 'ok' when Red :: float(),Green :: float(),Blue :: float().
secondaryColor3f(Red,Green,Blue) ->
- cast(5406, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>).
+ cast(5407, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>).
%% @equiv secondaryColor3f(Red,Green,Blue)
-spec secondaryColor3fv(V) -> 'ok' when V :: {Red :: float(),Green :: float(),Blue :: float()}.
@@ -9810,7 +9827,7 @@ secondaryColor3fv({Red,Green,Blue}) -> secondaryColor3f(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3i(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3i(Red,Green,Blue) ->
- cast(5407, <<Red:?GLint,Green:?GLint,Blue:?GLint>>).
+ cast(5408, <<Red:?GLint,Green:?GLint,Blue:?GLint>>).
%% @equiv secondaryColor3i(Red,Green,Blue)
-spec secondaryColor3iv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9820,7 +9837,7 @@ secondaryColor3iv({Red,Green,Blue}) -> secondaryColor3i(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3s(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3s(Red,Green,Blue) ->
- cast(5408, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>).
+ cast(5409, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>).
%% @equiv secondaryColor3s(Red,Green,Blue)
-spec secondaryColor3sv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9830,7 +9847,7 @@ secondaryColor3sv({Red,Green,Blue}) -> secondaryColor3s(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3ub(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3ub(Red,Green,Blue) ->
- cast(5409, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>).
+ cast(5410, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>).
%% @equiv secondaryColor3ub(Red,Green,Blue)
-spec secondaryColor3ubv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9840,7 +9857,7 @@ secondaryColor3ubv({Red,Green,Blue}) -> secondaryColor3ub(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3ui(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3ui(Red,Green,Blue) ->
- cast(5410, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>).
+ cast(5411, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>).
%% @equiv secondaryColor3ui(Red,Green,Blue)
-spec secondaryColor3uiv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9850,7 +9867,7 @@ secondaryColor3uiv({Red,Green,Blue}) -> secondaryColor3ui(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3us(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3us(Red,Green,Blue) ->
- cast(5411, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>).
+ cast(5412, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>).
%% @equiv secondaryColor3us(Red,Green,Blue)
-spec secondaryColor3usv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9883,10 +9900,10 @@ secondaryColor3usv({Red,Green,Blue}) -> secondaryColor3us(Red,Green,Blue).
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColorPointer.xml">external</a> documentation.
-spec secondaryColorPointer(Size, Type, Stride, Pointer) -> 'ok' when Size :: integer(),Type :: enum(),Stride :: integer(),Pointer :: offset()|mem().
secondaryColorPointer(Size,Type,Stride,Pointer) when is_integer(Pointer) ->
- cast(5412, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5413, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
secondaryColorPointer(Size,Type,Stride,Pointer) ->
send_bin(Pointer),
- cast(5413, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
+ cast(5414, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
%% @doc Specify the raster position in window coordinates for pixel operations
%%
@@ -9929,7 +9946,7 @@ secondaryColorPointer(Size,Type,Stride,Pointer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation.
-spec windowPos2d(X, Y) -> 'ok' when X :: float(),Y :: float().
windowPos2d(X,Y) ->
- cast(5414, <<X:?GLdouble,Y:?GLdouble>>).
+ cast(5415, <<X:?GLdouble,Y:?GLdouble>>).
%% @equiv windowPos2d(X,Y)
-spec windowPos2dv(V) -> 'ok' when V :: {X :: float(),Y :: float()}.
@@ -9939,7 +9956,7 @@ windowPos2dv({X,Y}) -> windowPos2d(X,Y).
%% See {@link windowPos2d/2}
-spec windowPos2f(X, Y) -> 'ok' when X :: float(),Y :: float().
windowPos2f(X,Y) ->
- cast(5415, <<X:?GLfloat,Y:?GLfloat>>).
+ cast(5416, <<X:?GLfloat,Y:?GLfloat>>).
%% @equiv windowPos2f(X,Y)
-spec windowPos2fv(V) -> 'ok' when V :: {X :: float(),Y :: float()}.
@@ -9949,7 +9966,7 @@ windowPos2fv({X,Y}) -> windowPos2f(X,Y).
%% See {@link windowPos2d/2}
-spec windowPos2i(X, Y) -> 'ok' when X :: integer(),Y :: integer().
windowPos2i(X,Y) ->
- cast(5416, <<X:?GLint,Y:?GLint>>).
+ cast(5417, <<X:?GLint,Y:?GLint>>).
%% @equiv windowPos2i(X,Y)
-spec windowPos2iv(V) -> 'ok' when V :: {X :: integer(),Y :: integer()}.
@@ -9959,7 +9976,7 @@ windowPos2iv({X,Y}) -> windowPos2i(X,Y).
%% See {@link windowPos2d/2}
-spec windowPos2s(X, Y) -> 'ok' when X :: integer(),Y :: integer().
windowPos2s(X,Y) ->
- cast(5417, <<X:?GLshort,Y:?GLshort>>).
+ cast(5418, <<X:?GLshort,Y:?GLshort>>).
%% @equiv windowPos2s(X,Y)
-spec windowPos2sv(V) -> 'ok' when V :: {X :: integer(),Y :: integer()}.
@@ -9969,7 +9986,7 @@ windowPos2sv({X,Y}) -> windowPos2s(X,Y).
%% See {@link windowPos2d/2}
-spec windowPos3d(X, Y, Z) -> 'ok' when X :: float(),Y :: float(),Z :: float().
windowPos3d(X,Y,Z) ->
- cast(5418, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5419, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @equiv windowPos3d(X,Y,Z)
-spec windowPos3dv(V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float()}.
@@ -9979,7 +9996,7 @@ windowPos3dv({X,Y,Z}) -> windowPos3d(X,Y,Z).
%% See {@link windowPos2d/2}
-spec windowPos3f(X, Y, Z) -> 'ok' when X :: float(),Y :: float(),Z :: float().
windowPos3f(X,Y,Z) ->
- cast(5419, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
+ cast(5420, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
%% @equiv windowPos3f(X,Y,Z)
-spec windowPos3fv(V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float()}.
@@ -9989,7 +10006,7 @@ windowPos3fv({X,Y,Z}) -> windowPos3f(X,Y,Z).
%% See {@link windowPos2d/2}
-spec windowPos3i(X, Y, Z) -> 'ok' when X :: integer(),Y :: integer(),Z :: integer().
windowPos3i(X,Y,Z) ->
- cast(5420, <<X:?GLint,Y:?GLint,Z:?GLint>>).
+ cast(5421, <<X:?GLint,Y:?GLint,Z:?GLint>>).
%% @equiv windowPos3i(X,Y,Z)
-spec windowPos3iv(V) -> 'ok' when V :: {X :: integer(),Y :: integer(),Z :: integer()}.
@@ -9999,7 +10016,7 @@ windowPos3iv({X,Y,Z}) -> windowPos3i(X,Y,Z).
%% See {@link windowPos2d/2}
-spec windowPos3s(X, Y, Z) -> 'ok' when X :: integer(),Y :: integer(),Z :: integer().
windowPos3s(X,Y,Z) ->
- cast(5421, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>).
+ cast(5422, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>).
%% @equiv windowPos3s(X,Y,Z)
-spec windowPos3sv(V) -> 'ok' when V :: {X :: integer(),Y :: integer(),Z :: integer()}.
@@ -10020,7 +10037,7 @@ windowPos3sv({X,Y,Z}) -> windowPos3s(X,Y,Z).
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenQueries.xml">external</a> documentation.
-spec genQueries(N) -> [integer()] when N :: integer().
genQueries(N) ->
- call(5422, <<N:?GLsizei>>).
+ call(5423, <<N:?GLsizei>>).
%% @doc Delete named query objects
%%
@@ -10034,8 +10051,9 @@ genQueries(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteQueries.xml">external</a> documentation.
-spec deleteQueries(Ids) -> 'ok' when Ids :: [integer()].
deleteQueries(Ids) ->
- cast(5423, <<(length(Ids)):?GLuint,
- (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+length(Ids)) rem 2)*32)>>).
+ IdsLen = length(Ids),
+ cast(5424, <<IdsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+IdsLen) rem 2)*32)>>).
%% @doc Determine if a name corresponds to a query object
%%
@@ -10049,7 +10067,7 @@ deleteQueries(Ids) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsQuery.xml">external</a> documentation.
-spec isQuery(Id) -> 0|1 when Id :: integer().
isQuery(Id) ->
- call(5424, <<Id:?GLuint>>).
+ call(5425, <<Id:?GLuint>>).
%% @doc Delimit the boundaries of a query object
%%
@@ -10116,20 +10134,20 @@ isQuery(Id) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginQuery.xml">external</a> documentation.
-spec beginQuery(Target, Id) -> 'ok' when Target :: enum(),Id :: integer().
beginQuery(Target,Id) ->
- cast(5425, <<Target:?GLenum,Id:?GLuint>>).
+ cast(5426, <<Target:?GLenum,Id:?GLuint>>).
%% @doc
%% See {@link beginQuery/2}
-spec endQuery(Target) -> 'ok' when Target :: enum().
endQuery(Target) ->
- cast(5426, <<Target:?GLenum>>).
+ cast(5427, <<Target:?GLenum>>).
%% @doc glGetQuery
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQuery.xml">external</a> documentation.
-spec getQueryiv(Target, Pname) -> integer() when Target :: enum(),Pname :: enum().
getQueryiv(Target,Pname) ->
- call(5427, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5428, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc Return parameters of a query object
%%
@@ -10149,13 +10167,13 @@ getQueryiv(Target,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObject.xml">external</a> documentation.
-spec getQueryObjectiv(Id, Pname) -> integer() when Id :: integer(),Pname :: enum().
getQueryObjectiv(Id,Pname) ->
- call(5428, <<Id:?GLuint,Pname:?GLenum>>).
+ call(5429, <<Id:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link getQueryObjectiv/2}
-spec getQueryObjectuiv(Id, Pname) -> integer() when Id :: integer(),Pname :: enum().
getQueryObjectuiv(Id,Pname) ->
- call(5429, <<Id:?GLuint,Pname:?GLenum>>).
+ call(5430, <<Id:?GLuint,Pname:?GLenum>>).
%% @doc Bind a named buffer object
%%
@@ -10238,7 +10256,7 @@ getQueryObjectuiv(Id,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml">external</a> documentation.
-spec bindBuffer(Target, Buffer) -> 'ok' when Target :: enum(),Buffer :: integer().
bindBuffer(Target,Buffer) ->
- cast(5430, <<Target:?GLenum,Buffer:?GLuint>>).
+ cast(5431, <<Target:?GLenum,Buffer:?GLuint>>).
%% @doc Delete named buffer objects
%%
@@ -10253,8 +10271,9 @@ bindBuffer(Target,Buffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteBuffers.xml">external</a> documentation.
-spec deleteBuffers(Buffers) -> 'ok' when Buffers :: [integer()].
deleteBuffers(Buffers) ->
- cast(5431, <<(length(Buffers)):?GLuint,
- (<< <<C:?GLuint>> || C <- Buffers>>)/binary,0:(((1+length(Buffers)) rem 2)*32)>>).
+ BuffersLen = length(Buffers),
+ cast(5432, <<BuffersLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Buffers>>)/binary,0:(((1+BuffersLen) rem 2)*32)>>).
%% @doc Generate buffer object names
%%
@@ -10272,7 +10291,7 @@ deleteBuffers(Buffers) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenBuffers.xml">external</a> documentation.
-spec genBuffers(N) -> [integer()] when N :: integer().
genBuffers(N) ->
- call(5432, <<N:?GLsizei>>).
+ call(5433, <<N:?GLsizei>>).
%% @doc Determine if a name corresponds to a buffer object
%%
@@ -10287,7 +10306,7 @@ genBuffers(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsBuffer.xml">external</a> documentation.
-spec isBuffer(Buffer) -> 0|1 when Buffer :: integer().
isBuffer(Buffer) ->
- call(5433, <<Buffer:?GLuint>>).
+ call(5434, <<Buffer:?GLuint>>).
%% @doc Creates and initializes a buffer object's data store
%%
@@ -10325,10 +10344,10 @@ isBuffer(Buffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBufferData.xml">external</a> documentation.
-spec bufferData(Target, Size, Data, Usage) -> 'ok' when Target :: enum(),Size :: integer(),Data :: offset()|mem(),Usage :: enum().
bufferData(Target,Size,Data,Usage) when is_integer(Data) ->
- cast(5434, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Data:?GLuint,Usage:?GLenum>>);
+ cast(5435, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Data:?GLuint,Usage:?GLenum>>);
bufferData(Target,Size,Data,Usage) ->
send_bin(Data),
- cast(5435, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Usage:?GLenum>>).
+ cast(5436, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Usage:?GLenum>>).
%% @doc Updates a subset of a buffer object's data store
%%
@@ -10341,10 +10360,10 @@ bufferData(Target,Size,Data,Usage) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBufferSubData.xml">external</a> documentation.
-spec bufferSubData(Target, Offset, Size, Data) -> 'ok' when Target :: enum(),Offset :: integer(),Size :: integer(),Data :: offset()|mem().
bufferSubData(Target,Offset,Size,Data) when is_integer(Data) ->
- cast(5436, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr,Data:?GLuint>>);
+ cast(5437, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr,Data:?GLuint>>);
bufferSubData(Target,Offset,Size,Data) ->
send_bin(Data),
- cast(5437, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
+ cast(5438, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
%% @doc Returns a subset of a buffer object's data store
%%
@@ -10358,7 +10377,7 @@ bufferSubData(Target,Offset,Size,Data) ->
-spec getBufferSubData(Target, Offset, Size, Data) -> 'ok' when Target :: enum(),Offset :: integer(),Size :: integer(),Data :: mem().
getBufferSubData(Target,Offset,Size,Data) ->
send_bin(Data),
- call(5438, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
+ call(5439, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
%% @doc Return parameters of a buffer object
%%
@@ -10382,7 +10401,7 @@ getBufferSubData(Target,Offset,Size,Data) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameteriv.xml">external</a> documentation.
-spec getBufferParameteriv(Target, Pname) -> integer() when Target :: enum(),Pname :: enum().
getBufferParameteriv(Target,Pname) ->
- call(5439, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5440, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc Set the RGB blend equation and the alpha blend equation separately
%%
@@ -10424,7 +10443,7 @@ getBufferParameteriv(Target,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquationSeparate.xml">external</a> documentation.
-spec blendEquationSeparate(ModeRGB, ModeAlpha) -> 'ok' when ModeRGB :: enum(),ModeAlpha :: enum().
blendEquationSeparate(ModeRGB,ModeAlpha) ->
- cast(5440, <<ModeRGB:?GLenum,ModeAlpha:?GLenum>>).
+ cast(5441, <<ModeRGB:?GLenum,ModeAlpha:?GLenum>>).
%% @doc Specifies a list of color buffers to be drawn into
%%
@@ -10464,8 +10483,9 @@ blendEquationSeparate(ModeRGB,ModeAlpha) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawBuffers.xml">external</a> documentation.
-spec drawBuffers(Bufs) -> 'ok' when Bufs :: [enum()].
drawBuffers(Bufs) ->
- cast(5441, <<(length(Bufs)):?GLuint,
- (<< <<C:?GLenum>> || C <- Bufs>>)/binary,0:(((1+length(Bufs)) rem 2)*32)>>).
+ BufsLen = length(Bufs),
+ cast(5442, <<BufsLen:?GLuint,
+ (<< <<C:?GLenum>> || C <- Bufs>>)/binary,0:(((1+BufsLen) rem 2)*32)>>).
%% @doc Set front and/or back stencil test actions
%%
@@ -10526,7 +10546,7 @@ drawBuffers(Bufs) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilOpSeparate.xml">external</a> documentation.
-spec stencilOpSeparate(Face, Sfail, Dpfail, Dppass) -> 'ok' when Face :: enum(),Sfail :: enum(),Dpfail :: enum(),Dppass :: enum().
stencilOpSeparate(Face,Sfail,Dpfail,Dppass) ->
- cast(5442, <<Face:?GLenum,Sfail:?GLenum,Dpfail:?GLenum,Dppass:?GLenum>>).
+ cast(5443, <<Face:?GLenum,Sfail:?GLenum,Dpfail:?GLenum,Dppass:?GLenum>>).
%% @doc Set front and/or back function and reference value for stencil testing
%%
@@ -10589,7 +10609,7 @@ stencilOpSeparate(Face,Sfail,Dpfail,Dppass) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilFuncSeparate.xml">external</a> documentation.
-spec stencilFuncSeparate(Face, Func, Ref, Mask) -> 'ok' when Face :: enum(),Func :: enum(),Ref :: integer(),Mask :: integer().
stencilFuncSeparate(Face,Func,Ref,Mask) ->
- cast(5443, <<Face:?GLenum,Func:?GLenum,Ref:?GLint,Mask:?GLuint>>).
+ cast(5444, <<Face:?GLenum,Func:?GLenum,Ref:?GLint,Mask:?GLuint>>).
%% @doc Control the front and/or back writing of individual bits in the stencil planes
%%
@@ -10607,7 +10627,7 @@ stencilFuncSeparate(Face,Func,Ref,Mask) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilMaskSeparate.xml">external</a> documentation.
-spec stencilMaskSeparate(Face, Mask) -> 'ok' when Face :: enum(),Mask :: integer().
stencilMaskSeparate(Face,Mask) ->
- cast(5444, <<Face:?GLenum,Mask:?GLuint>>).
+ cast(5445, <<Face:?GLenum,Mask:?GLuint>>).
%% @doc Attaches a shader object to a program object
%%
@@ -10631,7 +10651,7 @@ stencilMaskSeparate(Face,Mask) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAttachShader.xml">external</a> documentation.
-spec attachShader(Program, Shader) -> 'ok' when Program :: integer(),Shader :: integer().
attachShader(Program,Shader) ->
- cast(5445, <<Program:?GLuint,Shader:?GLuint>>).
+ cast(5446, <<Program:?GLuint,Shader:?GLuint>>).
%% @doc Associates a generic vertex attribute index with a named attribute variable
%%
@@ -10668,7 +10688,8 @@ attachShader(Program,Shader) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocation.xml">external</a> documentation.
-spec bindAttribLocation(Program, Index, Name) -> 'ok' when Program :: integer(),Index :: integer(),Name :: string().
bindAttribLocation(Program,Index,Name) ->
- cast(5446, <<Program:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ cast(5447, <<Program:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc Compiles a shader object
%%
@@ -10688,7 +10709,7 @@ bindAttribLocation(Program,Index,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShader.xml">external</a> documentation.
-spec compileShader(Shader) -> 'ok' when Shader :: integer().
compileShader(Shader) ->
- cast(5447, <<Shader:?GLuint>>).
+ cast(5448, <<Shader:?GLuint>>).
%% @doc Creates a program object
%%
@@ -10711,7 +10732,7 @@ compileShader(Shader) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateProgram.xml">external</a> documentation.
-spec createProgram() -> integer().
createProgram() ->
- call(5448, <<>>).
+ call(5449, <<>>).
%% @doc Creates a shader object
%%
@@ -10734,7 +10755,7 @@ createProgram() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShader.xml">external</a> documentation.
-spec createShader(Type) -> integer() when Type :: enum().
createShader(Type) ->
- call(5449, <<Type:?GLenum>>).
+ call(5450, <<Type:?GLenum>>).
%% @doc Deletes a program object
%%
@@ -10755,7 +10776,7 @@ createShader(Type) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgram.xml">external</a> documentation.
-spec deleteProgram(Program) -> 'ok' when Program :: integer().
deleteProgram(Program) ->
- cast(5450, <<Program:?GLuint>>).
+ cast(5451, <<Program:?GLuint>>).
%% @doc Deletes a shader object
%%
@@ -10774,7 +10795,7 @@ deleteProgram(Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteShader.xml">external</a> documentation.
-spec deleteShader(Shader) -> 'ok' when Shader :: integer().
deleteShader(Shader) ->
- cast(5451, <<Shader:?GLuint>>).
+ cast(5452, <<Shader:?GLuint>>).
%% @doc Detaches a shader object from a program object to which it is attached
%%
@@ -10789,7 +10810,7 @@ deleteShader(Shader) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDetachShader.xml">external</a> documentation.
-spec detachShader(Program, Shader) -> 'ok' when Program :: integer(),Shader :: integer().
detachShader(Program,Shader) ->
- cast(5452, <<Program:?GLuint,Shader:?GLuint>>).
+ cast(5453, <<Program:?GLuint,Shader:?GLuint>>).
%% @doc Enable or disable a generic vertex attribute array
%%
@@ -10804,13 +10825,13 @@ detachShader(Program,Shader) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml">external</a> documentation.
-spec disableVertexAttribArray(Index) -> 'ok' when Index :: integer().
disableVertexAttribArray(Index) ->
- cast(5453, <<Index:?GLuint>>).
+ cast(5454, <<Index:?GLuint>>).
%% @doc
%% See {@link disableVertexAttribArray/1}
-spec enableVertexAttribArray(Index) -> 'ok' when Index :: integer().
enableVertexAttribArray(Index) ->
- cast(5454, <<Index:?GLuint>>).
+ cast(5455, <<Index:?GLuint>>).
%% @doc Returns information about an active attribute variable for the specified program object
%%
@@ -10868,7 +10889,7 @@ enableVertexAttribArray(Index) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveAttrib.xml">external</a> documentation.
-spec getActiveAttrib(Program, Index, BufSize) -> {Size :: integer(),Type :: enum(),Name :: string()} when Program :: integer(),Index :: integer(),BufSize :: integer().
getActiveAttrib(Program,Index,BufSize) ->
- call(5455, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
+ call(5456, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
%% @doc Returns information about an active uniform variable for the specified program object
%%
@@ -11015,7 +11036,7 @@ getActiveAttrib(Program,Index,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniform.xml">external</a> documentation.
-spec getActiveUniform(Program, Index, BufSize) -> {Size :: integer(),Type :: enum(),Name :: string()} when Program :: integer(),Index :: integer(),BufSize :: integer().
getActiveUniform(Program,Index,BufSize) ->
- call(5456, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
+ call(5457, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
%% @doc Returns the handles of the shader objects attached to a program object
%%
@@ -11035,7 +11056,7 @@ getActiveUniform(Program,Index,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttachedShaders.xml">external</a> documentation.
-spec getAttachedShaders(Program, MaxCount) -> [integer()] when Program :: integer(),MaxCount :: integer().
getAttachedShaders(Program,MaxCount) ->
- call(5457, <<Program:?GLuint,MaxCount:?GLsizei>>).
+ call(5458, <<Program:?GLuint,MaxCount:?GLsizei>>).
%% @doc Returns the location of an attribute variable
%%
@@ -11059,7 +11080,8 @@ getAttachedShaders(Program,MaxCount) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml">external</a> documentation.
-spec getAttribLocation(Program, Name) -> integer() when Program :: integer(),Name :: string().
getAttribLocation(Program,Name) ->
- call(5458, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5459, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc Returns a parameter from a program object
%%
@@ -11130,7 +11152,7 @@ getAttribLocation(Program,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgram.xml">external</a> documentation.
-spec getProgramiv(Program, Pname) -> integer() when Program :: integer(),Pname :: enum().
getProgramiv(Program,Pname) ->
- call(5459, <<Program:?GLuint,Pname:?GLenum>>).
+ call(5460, <<Program:?GLuint,Pname:?GLenum>>).
%% @doc Returns the information log for a program object
%%
@@ -11155,7 +11177,7 @@ getProgramiv(Program,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramInfoLog.xml">external</a> documentation.
-spec getProgramInfoLog(Program, BufSize) -> string() when Program :: integer(),BufSize :: integer().
getProgramInfoLog(Program,BufSize) ->
- call(5460, <<Program:?GLuint,BufSize:?GLsizei>>).
+ call(5461, <<Program:?GLuint,BufSize:?GLsizei>>).
%% @doc Returns a parameter from a shader object
%%
@@ -11186,7 +11208,7 @@ getProgramInfoLog(Program,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShader.xml">external</a> documentation.
-spec getShaderiv(Shader, Pname) -> integer() when Shader :: integer(),Pname :: enum().
getShaderiv(Shader,Pname) ->
- call(5461, <<Shader:?GLuint,Pname:?GLenum>>).
+ call(5462, <<Shader:?GLuint,Pname:?GLenum>>).
%% @doc Returns the information log for a shader object
%%
@@ -11209,7 +11231,7 @@ getShaderiv(Shader,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderInfoLog.xml">external</a> documentation.
-spec getShaderInfoLog(Shader, BufSize) -> string() when Shader :: integer(),BufSize :: integer().
getShaderInfoLog(Shader,BufSize) ->
- call(5462, <<Shader:?GLuint,BufSize:?GLsizei>>).
+ call(5463, <<Shader:?GLuint,BufSize:?GLsizei>>).
%% @doc Returns the source code string from a shader object
%%
@@ -11229,7 +11251,7 @@ getShaderInfoLog(Shader,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderSource.xml">external</a> documentation.
-spec getShaderSource(Shader, BufSize) -> string() when Shader :: integer(),BufSize :: integer().
getShaderSource(Shader,BufSize) ->
- call(5463, <<Shader:?GLuint,BufSize:?GLsizei>>).
+ call(5464, <<Shader:?GLuint,BufSize:?GLsizei>>).
%% @doc Returns the location of a uniform variable
%%
@@ -11262,7 +11284,8 @@ getShaderSource(Shader,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformLocation.xml">external</a> documentation.
-spec getUniformLocation(Program, Name) -> integer() when Program :: integer(),Name :: string().
getUniformLocation(Program,Name) ->
- call(5464, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5465, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc Returns the value of a uniform variable
%%
@@ -11288,13 +11311,13 @@ getUniformLocation(Program,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml">external</a> documentation.
-spec getUniformfv(Program, Location) -> matrix() when Program :: integer(),Location :: integer().
getUniformfv(Program,Location) ->
- call(5465, <<Program:?GLuint,Location:?GLint>>).
+ call(5466, <<Program:?GLuint,Location:?GLint>>).
%% @doc
%% See {@link getUniformfv/2}
-spec getUniformiv(Program, Location) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} when Program :: integer(),Location :: integer().
getUniformiv(Program,Location) ->
- call(5466, <<Program:?GLuint,Location:?GLint>>).
+ call(5467, <<Program:?GLuint,Location:?GLint>>).
%% @doc Return a generic vertex attribute parameter
%%
@@ -11361,19 +11384,19 @@ getUniformiv(Program,Location) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttrib.xml">external</a> documentation.
-spec getVertexAttribdv(Index, Pname) -> {float(),float(),float(),float()} when Index :: integer(),Pname :: enum().
getVertexAttribdv(Index,Pname) ->
- call(5467, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5468, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link getVertexAttribdv/2}
-spec getVertexAttribfv(Index, Pname) -> {float(),float(),float(),float()} when Index :: integer(),Pname :: enum().
getVertexAttribfv(Index,Pname) ->
- call(5468, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5469, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link getVertexAttribdv/2}
-spec getVertexAttribiv(Index, Pname) -> {integer(),integer(),integer(),integer()} when Index :: integer(),Pname :: enum().
getVertexAttribiv(Index,Pname) ->
- call(5469, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5470, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc Determines if a name corresponds to a program object
%%
@@ -11385,7 +11408,7 @@ getVertexAttribiv(Index,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsProgram.xml">external</a> documentation.
-spec isProgram(Program) -> 0|1 when Program :: integer().
isProgram(Program) ->
- call(5470, <<Program:?GLuint>>).
+ call(5471, <<Program:?GLuint>>).
%% @doc Determines if a name corresponds to a shader object
%%
@@ -11397,7 +11420,7 @@ isProgram(Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsShader.xml">external</a> documentation.
-spec isShader(Shader) -> 0|1 when Shader :: integer().
isShader(Shader) ->
- call(5471, <<Shader:?GLuint>>).
+ call(5472, <<Shader:?GLuint>>).
%% @doc Links a program object
%%
@@ -11517,7 +11540,7 @@ isShader(Shader) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgram.xml">external</a> documentation.
-spec linkProgram(Program) -> 'ok' when Program :: integer().
linkProgram(Program) ->
- cast(5472, <<Program:?GLuint>>).
+ cast(5473, <<Program:?GLuint>>).
%% @doc Replaces the source code in a shader object
%%
@@ -11535,8 +11558,9 @@ linkProgram(Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderSource.xml">external</a> documentation.
-spec shaderSource(Shader, String) -> 'ok' when Shader :: integer(),String :: iolist().
shaderSource(Shader,String) ->
- StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
- cast(5473, <<Shader:?GLuint,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+0) rem 8)) rem 8)>>).
+ StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
+ StringLen = length(String),
+ cast(5474, <<Shader:?GLuint,StringLen:?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+0) rem 8)) rem 8)>>).
%% @doc Installs a program object as part of current rendering state
%%
@@ -11577,7 +11601,7 @@ shaderSource(Shader,String) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgram.xml">external</a> documentation.
-spec useProgram(Program) -> 'ok' when Program :: integer().
useProgram(Program) ->
- cast(5474, <<Program:?GLuint>>).
+ cast(5475, <<Program:?GLuint>>).
%% @doc Specify the value of a uniform variable for the current program object
%%
@@ -11645,125 +11669,136 @@ useProgram(Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
-spec uniform1f(Location, V0) -> 'ok' when Location :: integer(),V0 :: float().
uniform1f(Location,V0) ->
- cast(5475, <<Location:?GLint,V0:?GLfloat>>).
+ cast(5476, <<Location:?GLint,V0:?GLfloat>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2f(Location, V0, V1) -> 'ok' when Location :: integer(),V0 :: float(),V1 :: float().
uniform2f(Location,V0,V1) ->
- cast(5476, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat>>).
+ cast(5477, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3f(Location, V0, V1, V2) -> 'ok' when Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float().
uniform3f(Location,V0,V1,V2) ->
- cast(5477, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
+ cast(5478, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4f(Location, V0, V1, V2, V3) -> 'ok' when Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float(),V3 :: float().
uniform4f(Location,V0,V1,V2,V3) ->
- cast(5478, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>).
+ cast(5479, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1i(Location, V0) -> 'ok' when Location :: integer(),V0 :: integer().
uniform1i(Location,V0) ->
- cast(5479, <<Location:?GLint,V0:?GLint>>).
+ cast(5480, <<Location:?GLint,V0:?GLint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2i(Location, V0, V1) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer().
uniform2i(Location,V0,V1) ->
- cast(5480, <<Location:?GLint,V0:?GLint,V1:?GLint>>).
+ cast(5481, <<Location:?GLint,V0:?GLint,V1:?GLint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3i(Location, V0, V1, V2) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer().
uniform3i(Location,V0,V1,V2) ->
- cast(5481, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>).
+ cast(5482, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4i(Location, V0, V1, V2, V3) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer(),V3 :: integer().
uniform4i(Location,V0,V1,V2,V3) ->
- cast(5482, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>).
+ cast(5483, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1fv(Location, Value) -> 'ok' when Location :: integer(),Value :: [float()].
uniform1fv(Location,Value) ->
- cast(5483, <<Location:?GLint,(length(Value)):?GLuint,
- (<< <<C:?GLfloat>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>).
+ ValueLen = length(Value),
+ cast(5484, <<Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLfloat>> || C <- Value>>)/binary,0:(((ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2fv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float()}].
uniform2fv(Location,Value) ->
- cast(5484, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5485, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3fv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float(),float()}].
uniform3fv(Location,Value) ->
- cast(5485, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5486, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4fv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float(),float(),float()}].
uniform4fv(Location,Value) ->
- cast(5486, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5487, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1iv(Location, Value) -> 'ok' when Location :: integer(),Value :: [integer()].
uniform1iv(Location,Value) ->
- cast(5487, <<Location:?GLint,(length(Value)):?GLuint,
- (<< <<C:?GLint>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>).
+ ValueLen = length(Value),
+ cast(5488, <<Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLint>> || C <- Value>>)/binary,0:(((ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2iv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer()}].
uniform2iv(Location,Value) ->
- cast(5488, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5489, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3iv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer(),integer()}].
uniform3iv(Location,Value) ->
- cast(5489, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5490, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4iv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer(),integer(),integer()}].
uniform4iv(Location,Value) ->
- cast(5490, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5491, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float()}].
uniformMatrix2fv(Location,Transpose,Value) ->
- cast(5491, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5492, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix3fv(Location,Transpose,Value) ->
- cast(5492, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5493, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4fv(Location,Transpose,Value) ->
- cast(5493, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5494, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat,V13:?GLfloat,V14:?GLfloat,V15:?GLfloat,V16:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>).
%% @doc Validates a program object
@@ -11791,7 +11826,7 @@ uniformMatrix4fv(Location,Transpose,Value) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgram.xml">external</a> documentation.
-spec validateProgram(Program) -> 'ok' when Program :: integer().
validateProgram(Program) ->
- cast(5494, <<Program:?GLuint>>).
+ cast(5495, <<Program:?GLuint>>).
%% @doc Specifies the value of a generic vertex attribute
%%
@@ -11866,7 +11901,7 @@ validateProgram(Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
-spec vertexAttrib1d(Index, X) -> 'ok' when Index :: integer(),X :: float().
vertexAttrib1d(Index,X) ->
- cast(5495, <<Index:?GLuint,0:32,X:?GLdouble>>).
+ cast(5496, <<Index:?GLuint,0:32,X:?GLdouble>>).
%% @equiv vertexAttrib1d(Index,X)
-spec vertexAttrib1dv(Index :: integer(),V) -> 'ok' when V :: {X :: float()}.
@@ -11876,7 +11911,7 @@ vertexAttrib1dv(Index,{X}) -> vertexAttrib1d(Index,X).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib1f(Index, X) -> 'ok' when Index :: integer(),X :: float().
vertexAttrib1f(Index,X) ->
- cast(5496, <<Index:?GLuint,X:?GLfloat>>).
+ cast(5497, <<Index:?GLuint,X:?GLfloat>>).
%% @equiv vertexAttrib1f(Index,X)
-spec vertexAttrib1fv(Index :: integer(),V) -> 'ok' when V :: {X :: float()}.
@@ -11886,7 +11921,7 @@ vertexAttrib1fv(Index,{X}) -> vertexAttrib1f(Index,X).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib1s(Index, X) -> 'ok' when Index :: integer(),X :: integer().
vertexAttrib1s(Index,X) ->
- cast(5497, <<Index:?GLuint,X:?GLshort>>).
+ cast(5498, <<Index:?GLuint,X:?GLshort>>).
%% @equiv vertexAttrib1s(Index,X)
-spec vertexAttrib1sv(Index :: integer(),V) -> 'ok' when V :: {X :: integer()}.
@@ -11896,7 +11931,7 @@ vertexAttrib1sv(Index,{X}) -> vertexAttrib1s(Index,X).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib2d(Index, X, Y) -> 'ok' when Index :: integer(),X :: float(),Y :: float().
vertexAttrib2d(Index,X,Y) ->
- cast(5498, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>).
+ cast(5499, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>).
%% @equiv vertexAttrib2d(Index,X,Y)
-spec vertexAttrib2dv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float()}.
@@ -11906,7 +11941,7 @@ vertexAttrib2dv(Index,{X,Y}) -> vertexAttrib2d(Index,X,Y).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib2f(Index, X, Y) -> 'ok' when Index :: integer(),X :: float(),Y :: float().
vertexAttrib2f(Index,X,Y) ->
- cast(5499, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat>>).
+ cast(5500, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat>>).
%% @equiv vertexAttrib2f(Index,X,Y)
-spec vertexAttrib2fv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float()}.
@@ -11916,7 +11951,7 @@ vertexAttrib2fv(Index,{X,Y}) -> vertexAttrib2f(Index,X,Y).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib2s(Index, X, Y) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer().
vertexAttrib2s(Index,X,Y) ->
- cast(5500, <<Index:?GLuint,X:?GLshort,Y:?GLshort>>).
+ cast(5501, <<Index:?GLuint,X:?GLshort,Y:?GLshort>>).
%% @equiv vertexAttrib2s(Index,X,Y)
-spec vertexAttrib2sv(Index :: integer(),V) -> 'ok' when V :: {X :: integer(),Y :: integer()}.
@@ -11926,7 +11961,7 @@ vertexAttrib2sv(Index,{X,Y}) -> vertexAttrib2s(Index,X,Y).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib3d(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float().
vertexAttrib3d(Index,X,Y,Z) ->
- cast(5501, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5502, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @equiv vertexAttrib3d(Index,X,Y,Z)
-spec vertexAttrib3dv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float()}.
@@ -11936,7 +11971,7 @@ vertexAttrib3dv(Index,{X,Y,Z}) -> vertexAttrib3d(Index,X,Y,Z).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib3f(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float().
vertexAttrib3f(Index,X,Y,Z) ->
- cast(5502, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
+ cast(5503, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
%% @equiv vertexAttrib3f(Index,X,Y,Z)
-spec vertexAttrib3fv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float()}.
@@ -11946,7 +11981,7 @@ vertexAttrib3fv(Index,{X,Y,Z}) -> vertexAttrib3f(Index,X,Y,Z).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib3s(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer().
vertexAttrib3s(Index,X,Y,Z) ->
- cast(5503, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort>>).
+ cast(5504, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort>>).
%% @equiv vertexAttrib3s(Index,X,Y,Z)
-spec vertexAttrib3sv(Index :: integer(),V) -> 'ok' when V :: {X :: integer(),Y :: integer(),Z :: integer()}.
@@ -11956,25 +11991,25 @@ vertexAttrib3sv(Index,{X,Y,Z}) -> vertexAttrib3s(Index,X,Y,Z).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Nbv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4Nbv(Index,{V1,V2,V3,V4}) ->
- cast(5504, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
+ cast(5505, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Niv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4Niv(Index,{V1,V2,V3,V4}) ->
- cast(5505, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+ cast(5506, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Nsv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4Nsv(Index,{V1,V2,V3,V4}) ->
- cast(5506, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
+ cast(5507, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Nub(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer(),W :: integer().
vertexAttrib4Nub(Index,X,Y,Z,W) ->
- cast(5507, <<Index:?GLuint,X:?GLubyte,Y:?GLubyte,Z:?GLubyte,W:?GLubyte>>).
+ cast(5508, <<Index:?GLuint,X:?GLubyte,Y:?GLubyte,Z:?GLubyte,W:?GLubyte>>).
%% @equiv vertexAttrib4Nub(Index,X,Y,Z,W)
-spec vertexAttrib4Nubv(Index :: integer(),V) -> 'ok' when V :: {X :: integer(),Y :: integer(),Z :: integer(),W :: integer()}.
@@ -11984,25 +12019,25 @@ vertexAttrib4Nubv(Index,{X,Y,Z,W}) -> vertexAttrib4Nub(Index,X,Y,Z,W).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Nuiv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4Nuiv(Index,{V1,V2,V3,V4}) ->
- cast(5508, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
+ cast(5509, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Nusv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4Nusv(Index,{V1,V2,V3,V4}) ->
- cast(5509, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
+ cast(5510, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4bv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4bv(Index,{V1,V2,V3,V4}) ->
- cast(5510, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
+ cast(5511, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4d(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
vertexAttrib4d(Index,X,Y,Z,W) ->
- cast(5511, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5512, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @equiv vertexAttrib4d(Index,X,Y,Z,W)
-spec vertexAttrib4dv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float(),W :: float()}.
@@ -12012,7 +12047,7 @@ vertexAttrib4dv(Index,{X,Y,Z,W}) -> vertexAttrib4d(Index,X,Y,Z,W).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4f(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
vertexAttrib4f(Index,X,Y,Z,W) ->
- cast(5512, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5513, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
%% @equiv vertexAttrib4f(Index,X,Y,Z,W)
-spec vertexAttrib4fv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float(),W :: float()}.
@@ -12022,13 +12057,13 @@ vertexAttrib4fv(Index,{X,Y,Z,W}) -> vertexAttrib4f(Index,X,Y,Z,W).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4iv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4iv(Index,{V1,V2,V3,V4}) ->
- cast(5513, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+ cast(5514, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4s(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer(),W :: integer().
vertexAttrib4s(Index,X,Y,Z,W) ->
- cast(5514, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
+ cast(5515, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
%% @equiv vertexAttrib4s(Index,X,Y,Z,W)
-spec vertexAttrib4sv(Index :: integer(),V) -> 'ok' when V :: {X :: integer(),Y :: integer(),Z :: integer(),W :: integer()}.
@@ -12038,19 +12073,19 @@ vertexAttrib4sv(Index,{X,Y,Z,W}) -> vertexAttrib4s(Index,X,Y,Z,W).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4ubv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4ubv(Index,{V1,V2,V3,V4}) ->
- cast(5515, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
+ cast(5516, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4uiv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4uiv(Index,{V1,V2,V3,V4}) ->
- cast(5516, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
+ cast(5517, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4usv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4usv(Index,{V1,V2,V3,V4}) ->
- cast(5517, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
+ cast(5518, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
%% @doc Define an array of generic vertex attribute data
%%
@@ -12094,51 +12129,57 @@ vertexAttrib4usv(Index,{V1,V2,V3,V4}) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml">external</a> documentation.
-spec vertexAttribPointer(Index, Size, Type, Normalized, Stride, Pointer) -> 'ok' when Index :: integer(),Size :: integer(),Type :: enum(),Normalized :: 0|1,Stride :: integer(),Pointer :: offset()|mem().
vertexAttribPointer(Index,Size,Type,Normalized,Stride,Pointer) when is_integer(Pointer) ->
- cast(5518, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5519, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei,Pointer:?GLuint>>);
vertexAttribPointer(Index,Size,Type,Normalized,Stride,Pointer) ->
send_bin(Pointer),
- cast(5519, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei>>).
+ cast(5520, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2x3fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
uniformMatrix2x3fv(Location,Transpose,Value) ->
- cast(5520, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5521, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3x2fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
uniformMatrix3x2fv(Location,Transpose,Value) ->
- cast(5521, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5522, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2x4fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix2x4fv(Location,Transpose,Value) ->
- cast(5522, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5523, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4x2fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4x2fv(Location,Transpose,Value) ->
- cast(5523, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5524, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3x4fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix3x4fv(Location,Transpose,Value) ->
- cast(5524, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5525, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4x3fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4x3fv(Location,Transpose,Value) ->
- cast(5525, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5526, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
%% @doc glColorMaski
@@ -12146,39 +12187,39 @@ uniformMatrix4x3fv(Location,Transpose,Value) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorMaski.xml">external</a> documentation.
-spec colorMaski(Index, R, G, B, A) -> 'ok' when Index :: integer(),R :: 0|1,G :: 0|1,B :: 0|1,A :: 0|1.
colorMaski(Index,R,G,B,A) ->
- cast(5526, <<Index:?GLuint,R:?GLboolean,G:?GLboolean,B:?GLboolean,A:?GLboolean>>).
+ cast(5527, <<Index:?GLuint,R:?GLboolean,G:?GLboolean,B:?GLboolean,A:?GLboolean>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getBooleani_v(Target, Index) -> [0|1] when Target :: enum(),Index :: integer().
getBooleani_v(Target,Index) ->
- call(5527, <<Target:?GLenum,Index:?GLuint>>).
+ call(5528, <<Target:?GLenum,Index:?GLuint>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getIntegeri_v(Target, Index) -> [integer()] when Target :: enum(),Index :: integer().
getIntegeri_v(Target,Index) ->
- call(5528, <<Target:?GLenum,Index:?GLuint>>).
+ call(5529, <<Target:?GLenum,Index:?GLuint>>).
%% @doc
%% See {@link enable/1}
-spec enablei(Target, Index) -> 'ok' when Target :: enum(),Index :: integer().
enablei(Target,Index) ->
- cast(5529, <<Target:?GLenum,Index:?GLuint>>).
+ cast(5530, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glEnablei
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnablei.xml">external</a> documentation.
-spec disablei(Target, Index) -> 'ok' when Target :: enum(),Index :: integer().
disablei(Target,Index) ->
- cast(5530, <<Target:?GLenum,Index:?GLuint>>).
+ cast(5531, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glIsEnabledi
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsEnabledi.xml">external</a> documentation.
-spec isEnabledi(Target, Index) -> 0|1 when Target :: enum(),Index :: integer().
isEnabledi(Target,Index) ->
- call(5531, <<Target:?GLenum,Index:?GLuint>>).
+ call(5532, <<Target:?GLenum,Index:?GLuint>>).
%% @doc Start transform feedback operation
%%
@@ -12206,13 +12247,13 @@ isEnabledi(Target,Index) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginTransformFeedback.xml">external</a> documentation.
-spec beginTransformFeedback(PrimitiveMode) -> 'ok' when PrimitiveMode :: enum().
beginTransformFeedback(PrimitiveMode) ->
- cast(5532, <<PrimitiveMode:?GLenum>>).
+ cast(5533, <<PrimitiveMode:?GLenum>>).
%% @doc
%% See {@link beginTransformFeedback/1}
-spec endTransformFeedback() -> 'ok'.
endTransformFeedback() ->
- cast(5533, <<>>).
+ cast(5534, <<>>).
%% @doc Bind a range within a buffer object to an indexed buffer target
%%
@@ -12231,7 +12272,7 @@ endTransformFeedback() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBufferRange.xml">external</a> documentation.
-spec bindBufferRange(Target, Index, Buffer, Offset, Size) -> 'ok' when Target :: enum(),Index :: integer(),Buffer :: integer(),Offset :: integer(),Size :: integer().
bindBufferRange(Target,Index,Buffer,Offset,Size) ->
- cast(5534, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
+ cast(5535, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
%% @doc Bind a buffer object to an indexed buffer target
%%
@@ -12246,7 +12287,7 @@ bindBufferRange(Target,Index,Buffer,Offset,Size) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBufferBase.xml">external</a> documentation.
-spec bindBufferBase(Target, Index, Buffer) -> 'ok' when Target :: enum(),Index :: integer(),Buffer :: integer().
bindBufferBase(Target,Index,Buffer) ->
- cast(5535, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint>>).
+ cast(5536, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint>>).
%% @doc Specify values to record in transform feedback buffers
%%
@@ -12284,8 +12325,9 @@ bindBufferBase(Target,Index,Buffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTransformFeedbackVaryings.xml">external</a> documentation.
-spec transformFeedbackVaryings(Program, Varyings, BufferMode) -> 'ok' when Program :: integer(),Varyings :: iolist(),BufferMode :: enum().
transformFeedbackVaryings(Program,Varyings,BufferMode) ->
- VaryingsTemp = list_to_binary([[Str|[0]] || Str <- Varyings ]),
- cast(5536, <<Program:?GLuint,(length(Varyings)):?GLuint,(size(VaryingsTemp)):?GLuint,(VaryingsTemp)/binary,0:((8-((size(VaryingsTemp)+0) rem 8)) rem 8),BufferMode:?GLenum>>).
+ VaryingsTemp = list_to_binary([[Str|[0]] || Str <- Varyings ]),
+ VaryingsLen = length(Varyings),
+ cast(5537, <<Program:?GLuint,VaryingsLen:?GLuint,(size(VaryingsTemp)):?GLuint,(VaryingsTemp)/binary,0:((8-((size(VaryingsTemp)+0) rem 8)) rem 8),BufferMode:?GLenum>>).
%% @doc Retrieve information about varying variables selected for transform feedback
%%
@@ -12318,7 +12360,7 @@ transformFeedbackVaryings(Program,Varyings,BufferMode) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTransformFeedbackVarying.xml">external</a> documentation.
-spec getTransformFeedbackVarying(Program, Index, BufSize) -> {Size :: integer(),Type :: enum(),Name :: string()} when Program :: integer(),Index :: integer(),BufSize :: integer().
getTransformFeedbackVarying(Program,Index,BufSize) ->
- call(5537, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
+ call(5538, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
%% @doc specify whether data read via
%%
@@ -12333,7 +12375,7 @@ getTransformFeedbackVarying(Program,Index,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClampColor.xml">external</a> documentation.
-spec clampColor(Target, Clamp) -> 'ok' when Target :: enum(),Clamp :: enum().
clampColor(Target,Clamp) ->
- cast(5538, <<Target:?GLenum,Clamp:?GLenum>>).
+ cast(5539, <<Target:?GLenum,Clamp:?GLenum>>).
%% @doc Start conditional rendering
%%
@@ -12365,84 +12407,84 @@ clampColor(Target,Clamp) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginConditionalRender.xml">external</a> documentation.
-spec beginConditionalRender(Id, Mode) -> 'ok' when Id :: integer(),Mode :: enum().
beginConditionalRender(Id,Mode) ->
- cast(5539, <<Id:?GLuint,Mode:?GLenum>>).
+ cast(5540, <<Id:?GLuint,Mode:?GLenum>>).
%% @doc
%% See {@link beginConditionalRender/2}
-spec endConditionalRender() -> 'ok'.
endConditionalRender() ->
- cast(5540, <<>>).
+ cast(5541, <<>>).
%% @doc glVertexAttribIPointer
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribIPointer.xml">external</a> documentation.
-spec vertexAttribIPointer(Index, Size, Type, Stride, Pointer) -> 'ok' when Index :: integer(),Size :: integer(),Type :: enum(),Stride :: integer(),Pointer :: offset()|mem().
vertexAttribIPointer(Index,Size,Type,Stride,Pointer) when is_integer(Pointer) ->
- cast(5541, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5542, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
vertexAttribIPointer(Index,Size,Type,Stride,Pointer) ->
send_bin(Pointer),
- cast(5542, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
+ cast(5543, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
%% @doc
%% See {@link getVertexAttribdv/2}
-spec getVertexAttribIiv(Index, Pname) -> {integer(),integer(),integer(),integer()} when Index :: integer(),Pname :: enum().
getVertexAttribIiv(Index,Pname) ->
- call(5543, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5544, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc glGetVertexAttribI
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttribI.xml">external</a> documentation.
-spec getVertexAttribIuiv(Index, Pname) -> {integer(),integer(),integer(),integer()} when Index :: integer(),Pname :: enum().
getVertexAttribIuiv(Index,Pname) ->
- call(5544, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5545, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI1i(Index, X) -> 'ok' when Index :: integer(),X :: integer().
vertexAttribI1i(Index,X) ->
- cast(5545, <<Index:?GLuint,X:?GLint>>).
+ cast(5546, <<Index:?GLuint,X:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI2i(Index, X, Y) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer().
vertexAttribI2i(Index,X,Y) ->
- cast(5546, <<Index:?GLuint,X:?GLint,Y:?GLint>>).
+ cast(5547, <<Index:?GLuint,X:?GLint,Y:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI3i(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer().
vertexAttribI3i(Index,X,Y,Z) ->
- cast(5547, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint>>).
+ cast(5548, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4i(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer(),W :: integer().
vertexAttribI4i(Index,X,Y,Z,W) ->
- cast(5548, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
+ cast(5549, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI1ui(Index, X) -> 'ok' when Index :: integer(),X :: integer().
vertexAttribI1ui(Index,X) ->
- cast(5549, <<Index:?GLuint,X:?GLuint>>).
+ cast(5550, <<Index:?GLuint,X:?GLuint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI2ui(Index, X, Y) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer().
vertexAttribI2ui(Index,X,Y) ->
- cast(5550, <<Index:?GLuint,X:?GLuint,Y:?GLuint>>).
+ cast(5551, <<Index:?GLuint,X:?GLuint,Y:?GLuint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI3ui(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer().
vertexAttribI3ui(Index,X,Y,Z) ->
- cast(5551, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint>>).
+ cast(5552, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4ui(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer(),W :: integer().
vertexAttribI4ui(Index,X,Y,Z,W) ->
- cast(5552, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint,W:?GLuint>>).
+ cast(5553, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint,W:?GLuint>>).
%% @equiv vertexAttribI1i(Index,X)
-spec vertexAttribI1iv(Index :: integer(),V) -> 'ok' when V :: {X :: integer()}.
@@ -12480,31 +12522,31 @@ vertexAttribI4uiv(Index,{X,Y,Z,W}) -> vertexAttribI4ui(Index,X,Y,Z,W).
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4bv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttribI4bv(Index,{V1,V2,V3,V4}) ->
- cast(5553, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
+ cast(5554, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4sv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttribI4sv(Index,{V1,V2,V3,V4}) ->
- cast(5554, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
+ cast(5555, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4ubv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttribI4ubv(Index,{V1,V2,V3,V4}) ->
- cast(5555, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
+ cast(5556, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4usv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttribI4usv(Index,{V1,V2,V3,V4}) ->
- cast(5556, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
+ cast(5557, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
%% @doc
%% See {@link getUniformfv/2}
-spec getUniformuiv(Program, Location) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} when Program :: integer(),Location :: integer().
getUniformuiv(Program,Location) ->
- call(5557, <<Program:?GLuint,Location:?GLint>>).
+ call(5558, <<Program:?GLuint,Location:?GLint>>).
%% @doc Bind a user-defined varying out variable to a fragment shader color number
%%
@@ -12531,7 +12573,8 @@ getUniformuiv(Program,Location) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFragDataLocation.xml">external</a> documentation.
-spec bindFragDataLocation(Program, Color, Name) -> 'ok' when Program :: integer(),Color :: integer(),Name :: string().
bindFragDataLocation(Program,Color,Name) ->
- cast(5558, <<Program:?GLuint,Color:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ cast(5559, <<Program:?GLuint,Color:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc Query the bindings of color numbers to user-defined varying out variables
%%
@@ -12544,65 +12587,70 @@ bindFragDataLocation(Program,Color,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFragDataLocation.xml">external</a> documentation.
-spec getFragDataLocation(Program, Name) -> integer() when Program :: integer(),Name :: string().
getFragDataLocation(Program,Name) ->
- call(5559, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5560, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1ui(Location, V0) -> 'ok' when Location :: integer(),V0 :: integer().
uniform1ui(Location,V0) ->
- cast(5560, <<Location:?GLint,V0:?GLuint>>).
+ cast(5561, <<Location:?GLint,V0:?GLuint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2ui(Location, V0, V1) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer().
uniform2ui(Location,V0,V1) ->
- cast(5561, <<Location:?GLint,V0:?GLuint,V1:?GLuint>>).
+ cast(5562, <<Location:?GLint,V0:?GLuint,V1:?GLuint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3ui(Location, V0, V1, V2) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer().
uniform3ui(Location,V0,V1,V2) ->
- cast(5562, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>).
+ cast(5563, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4ui(Location, V0, V1, V2, V3) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer(),V3 :: integer().
uniform4ui(Location,V0,V1,V2,V3) ->
- cast(5563, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>).
+ cast(5564, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1uiv(Location, Value) -> 'ok' when Location :: integer(),Value :: [integer()].
uniform1uiv(Location,Value) ->
- cast(5564, <<Location:?GLint,(length(Value)):?GLuint,
- (<< <<C:?GLuint>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>).
+ ValueLen = length(Value),
+ cast(5565, <<Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Value>>)/binary,0:(((ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2uiv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer()}].
uniform2uiv(Location,Value) ->
- cast(5565, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5566, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3uiv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer(),integer()}].
uniform3uiv(Location,Value) ->
- cast(5566, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5567, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4uiv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer(),integer(),integer()}].
uniform4uiv(Location,Value) ->
- cast(5567, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5568, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link texParameterf/3}
-spec texParameterIiv(Target, Pname, Params) -> 'ok' when Target :: enum(),Pname :: enum(),Params :: tuple().
texParameterIiv(Target,Pname,Params) ->
- cast(5568, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5569, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc glTexParameterI
@@ -12610,21 +12658,21 @@ texParameterIiv(Target,Pname,Params) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameterI.xml">external</a> documentation.
-spec texParameterIuiv(Target, Pname, Params) -> 'ok' when Target :: enum(),Pname :: enum(),Params :: tuple().
texParameterIuiv(Target,Pname,Params) ->
- cast(5569, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5570, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLuint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link getTexParameterfv/2}
-spec getTexParameterIiv(Target, Pname) -> {integer(),integer(),integer(),integer()} when Target :: enum(),Pname :: enum().
getTexParameterIiv(Target,Pname) ->
- call(5570, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5571, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc glGetTexParameterI
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexParameterI.xml">external</a> documentation.
-spec getTexParameterIuiv(Target, Pname) -> {integer(),integer(),integer(),integer()} when Target :: enum(),Pname :: enum().
getTexParameterIuiv(Target,Pname) ->
- call(5571, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5572, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc Clear individual buffers of the currently bound draw framebuffer
%%
@@ -12657,21 +12705,21 @@ getTexParameterIuiv(Target,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBuffer.xml">external</a> documentation.
-spec clearBufferiv(Buffer, Drawbuffer, Value) -> 'ok' when Buffer :: enum(),Drawbuffer :: integer(),Value :: tuple().
clearBufferiv(Buffer,Drawbuffer,Value) ->
- cast(5572, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
+ cast(5573, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
%% @doc
%% See {@link clearBufferiv/3}
-spec clearBufferuiv(Buffer, Drawbuffer, Value) -> 'ok' when Buffer :: enum(),Drawbuffer :: integer(),Value :: tuple().
clearBufferuiv(Buffer,Drawbuffer,Value) ->
- cast(5573, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
+ cast(5574, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLuint>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
%% @doc
%% See {@link clearBufferiv/3}
-spec clearBufferfv(Buffer, Drawbuffer, Value) -> 'ok' when Buffer :: enum(),Drawbuffer :: integer(),Value :: tuple().
clearBufferfv(Buffer,Drawbuffer,Value) ->
- cast(5574, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
+ cast(5575, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
%% @doc glClearBufferfi
@@ -12679,30 +12727,30 @@ clearBufferfv(Buffer,Drawbuffer,Value) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBufferfi.xml">external</a> documentation.
-spec clearBufferfi(Buffer, Drawbuffer, Depth, Stencil) -> 'ok' when Buffer :: enum(),Drawbuffer :: integer(),Depth :: float(),Stencil :: integer().
clearBufferfi(Buffer,Drawbuffer,Depth,Stencil) ->
- cast(5575, <<Buffer:?GLenum,Drawbuffer:?GLint,Depth:?GLfloat,Stencil:?GLint>>).
+ cast(5576, <<Buffer:?GLenum,Drawbuffer:?GLint,Depth:?GLfloat,Stencil:?GLint>>).
%% @doc
%% See {@link getString/1}
-spec getStringi(Name, Index) -> string() when Name :: enum(),Index :: integer().
getStringi(Name,Index) ->
- call(5576, <<Name:?GLenum,Index:?GLuint>>).
+ call(5577, <<Name:?GLenum,Index:?GLuint>>).
%% @doc glDrawArraysInstance
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArraysInstance.xml">external</a> documentation.
-spec drawArraysInstanced(Mode, First, Count, Primcount) -> 'ok' when Mode :: enum(),First :: integer(),Count :: integer(),Primcount :: integer().
drawArraysInstanced(Mode,First,Count,Primcount) ->
- cast(5577, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei>>).
+ cast(5578, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei>>).
%% @doc glDrawElementsInstance
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstance.xml">external</a> documentation.
-spec drawElementsInstanced(Mode, Count, Type, Indices, Primcount) -> 'ok' when Mode :: enum(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Primcount :: integer().
drawElementsInstanced(Mode,Count,Type,Indices,Primcount) when is_integer(Indices) ->
- cast(5578, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei>>);
+ cast(5579, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei>>);
drawElementsInstanced(Mode,Count,Type,Indices,Primcount) ->
send_bin(Indices),
- cast(5579, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei>>).
+ cast(5580, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei>>).
%% @doc Attach the storage for a buffer object to the active buffer texture
%%
@@ -12770,7 +12818,7 @@ drawElementsInstanced(Mode,Count,Type,Indices,Primcount) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexBuffer.xml">external</a> documentation.
-spec texBuffer(Target, Internalformat, Buffer) -> 'ok' when Target :: enum(),Internalformat :: enum(),Buffer :: integer().
texBuffer(Target,Internalformat,Buffer) ->
- cast(5580, <<Target:?GLenum,Internalformat:?GLenum,Buffer:?GLuint>>).
+ cast(5581, <<Target:?GLenum,Internalformat:?GLenum,Buffer:?GLuint>>).
%% @doc Specify the primitive restart index
%%
@@ -12792,20 +12840,20 @@ texBuffer(Target,Internalformat,Buffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPrimitiveRestartIndex.xml">external</a> documentation.
-spec primitiveRestartIndex(Index) -> 'ok' when Index :: integer().
primitiveRestartIndex(Index) ->
- cast(5581, <<Index:?GLuint>>).
+ cast(5582, <<Index:?GLuint>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getInteger64i_v(Target, Index) -> [integer()] when Target :: enum(),Index :: integer().
getInteger64i_v(Target,Index) ->
- call(5582, <<Target:?GLenum,Index:?GLuint>>).
+ call(5583, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glGetBufferParameteri64v
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameteri64v.xml">external</a> documentation.
-spec getBufferParameteri64v(Target, Pname) -> [integer()] when Target :: enum(),Pname :: enum().
getBufferParameteri64v(Target,Pname) ->
- call(5583, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5584, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc Attach a level of a texture object as a logical buffer to the currently bound framebuffer object
%%
@@ -12862,7 +12910,7 @@ getBufferParameteri64v(Target,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTexture.xml">external</a> documentation.
-spec framebufferTexture(Target, Attachment, Texture, Level) -> 'ok' when Target :: enum(),Attachment :: enum(),Texture :: integer(),Level :: integer().
framebufferTexture(Target,Attachment,Texture,Level) ->
- cast(5584, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint>>).
+ cast(5585, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint>>).
%% @doc Modify the rate at which generic vertex attributes advance during instanced rendering
%%
@@ -12878,7 +12926,7 @@ framebufferTexture(Target,Attachment,Texture,Level) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribDivisor.xml">external</a> documentation.
-spec vertexAttribDivisor(Index, Divisor) -> 'ok' when Index :: integer(),Divisor :: integer().
vertexAttribDivisor(Index,Divisor) ->
- cast(5585, <<Index:?GLuint,Divisor:?GLuint>>).
+ cast(5586, <<Index:?GLuint,Divisor:?GLuint>>).
%% @doc Specifies minimum rate at which sample shaing takes place
%%
@@ -12899,107 +12947,112 @@ vertexAttribDivisor(Index,Divisor) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMinSampleShading.xml">external</a> documentation.
-spec minSampleShading(Value) -> 'ok' when Value :: clamp().
minSampleShading(Value) ->
- cast(5586, <<Value:?GLclampf>>).
+ cast(5587, <<Value:?GLclampf>>).
%% @doc
%% See {@link blendEquation/1}
-spec blendEquationi(Buf, Mode) -> 'ok' when Buf :: integer(),Mode :: enum().
blendEquationi(Buf,Mode) ->
- cast(5587, <<Buf:?GLuint,Mode:?GLenum>>).
+ cast(5588, <<Buf:?GLuint,Mode:?GLenum>>).
%% @doc
%% See {@link blendEquationSeparate/2}
-spec blendEquationSeparatei(Buf, ModeRGB, ModeAlpha) -> 'ok' when Buf :: integer(),ModeRGB :: enum(),ModeAlpha :: enum().
blendEquationSeparatei(Buf,ModeRGB,ModeAlpha) ->
- cast(5588, <<Buf:?GLuint,ModeRGB:?GLenum,ModeAlpha:?GLenum>>).
+ cast(5589, <<Buf:?GLuint,ModeRGB:?GLenum,ModeAlpha:?GLenum>>).
%% @doc glBlendFunci
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendFunci.xml">external</a> documentation.
-spec blendFunci(Buf, Src, Dst) -> 'ok' when Buf :: integer(),Src :: enum(),Dst :: enum().
blendFunci(Buf,Src,Dst) ->
- cast(5589, <<Buf:?GLuint,Src:?GLenum,Dst:?GLenum>>).
+ cast(5590, <<Buf:?GLuint,Src:?GLenum,Dst:?GLenum>>).
%% @doc
%% See {@link blendFuncSeparate/4}
-spec blendFuncSeparatei(Buf, SrcRGB, DstRGB, SrcAlpha, DstAlpha) -> 'ok' when Buf :: integer(),SrcRGB :: enum(),DstRGB :: enum(),SrcAlpha :: enum(),DstAlpha :: enum().
blendFuncSeparatei(Buf,SrcRGB,DstRGB,SrcAlpha,DstAlpha) ->
- cast(5590, <<Buf:?GLuint,SrcRGB:?GLenum,DstRGB:?GLenum,SrcAlpha:?GLenum,DstAlpha:?GLenum>>).
+ cast(5591, <<Buf:?GLuint,SrcRGB:?GLenum,DstRGB:?GLenum,SrcAlpha:?GLenum,DstAlpha:?GLenum>>).
%% @doc glLoadTransposeMatrixARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrixARB.xml">external</a> documentation.
-spec loadTransposeMatrixfARB(M) -> 'ok' when M :: matrix().
loadTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- cast(5591, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
+ cast(5592, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
loadTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- cast(5591, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
+ cast(5592, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
%% @doc glLoadTransposeMatrixARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrixARB.xml">external</a> documentation.
-spec loadTransposeMatrixdARB(M) -> 'ok' when M :: matrix().
loadTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- cast(5592, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
+ cast(5593, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
loadTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- cast(5592, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
+ cast(5593, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
%% @doc glMultTransposeMatrixARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrixARB.xml">external</a> documentation.
-spec multTransposeMatrixfARB(M) -> 'ok' when M :: matrix().
multTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- cast(5593, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
+ cast(5594, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
multTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- cast(5593, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
+ cast(5594, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
%% @doc glMultTransposeMatrixARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrixARB.xml">external</a> documentation.
-spec multTransposeMatrixdARB(M) -> 'ok' when M :: matrix().
multTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- cast(5594, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
+ cast(5595, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
multTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- cast(5594, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
+ cast(5595, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightbvARB(Weights) -> 'ok' when Weights :: [integer()].
weightbvARB(Weights) ->
- cast(5595, <<(length(Weights)):?GLuint,
- (<< <<C:?GLbyte>> || C <- Weights>>)/binary,0:((8-((length(Weights)+ 4) rem 8)) rem 8)>>).
+ WeightsLen = length(Weights),
+ cast(5596, <<WeightsLen:?GLuint,
+ (<< <<C:?GLbyte>> || C <- Weights>>)/binary,0:((8-((WeightsLen+ 4) rem 8)) rem 8)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightsvARB(Weights) -> 'ok' when Weights :: [integer()].
weightsvARB(Weights) ->
- cast(5596, <<(length(Weights)):?GLuint,
- (<< <<C:?GLshort>> || C <- Weights>>)/binary,0:((8-((length(Weights)*2+ 4) rem 8)) rem 8)>>).
+ WeightsLen = length(Weights),
+ cast(5597, <<WeightsLen:?GLuint,
+ (<< <<C:?GLshort>> || C <- Weights>>)/binary,0:((8-((WeightsLen*2+ 4) rem 8)) rem 8)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightivARB(Weights) -> 'ok' when Weights :: [integer()].
weightivARB(Weights) ->
- cast(5597, <<(length(Weights)):?GLuint,
- (<< <<C:?GLint>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>).
+ WeightsLen = length(Weights),
+ cast(5598, <<WeightsLen:?GLuint,
+ (<< <<C:?GLint>> || C <- Weights>>)/binary,0:(((1+WeightsLen) rem 2)*32)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightfvARB(Weights) -> 'ok' when Weights :: [float()].
weightfvARB(Weights) ->
- cast(5598, <<(length(Weights)):?GLuint,
- (<< <<C:?GLfloat>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>).
+ WeightsLen = length(Weights),
+ cast(5599, <<WeightsLen:?GLuint,
+ (<< <<C:?GLfloat>> || C <- Weights>>)/binary,0:(((1+WeightsLen) rem 2)*32)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightdvARB(Weights) -> 'ok' when Weights :: [float()].
weightdvARB(Weights) ->
- cast(5599, <<(length(Weights)):?GLuint,0:32,
+ WeightsLen = length(Weights),
+ cast(5600, <<WeightsLen:?GLuint,0:32,
(<< <<C:?GLdouble>> || C <- Weights>>)/binary>>).
%% @doc glWeightARB
@@ -13007,175 +13060,183 @@ weightdvARB(Weights) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightubvARB(Weights) -> 'ok' when Weights :: [integer()].
weightubvARB(Weights) ->
- cast(5600, <<(length(Weights)):?GLuint,
- (<< <<C:?GLubyte>> || C <- Weights>>)/binary,0:((8-((length(Weights)+ 4) rem 8)) rem 8)>>).
+ WeightsLen = length(Weights),
+ cast(5601, <<WeightsLen:?GLuint,
+ (<< <<C:?GLubyte>> || C <- Weights>>)/binary,0:((8-((WeightsLen+ 4) rem 8)) rem 8)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightusvARB(Weights) -> 'ok' when Weights :: [integer()].
weightusvARB(Weights) ->
- cast(5601, <<(length(Weights)):?GLuint,
- (<< <<C:?GLushort>> || C <- Weights>>)/binary,0:((8-((length(Weights)*2+ 4) rem 8)) rem 8)>>).
+ WeightsLen = length(Weights),
+ cast(5602, <<WeightsLen:?GLuint,
+ (<< <<C:?GLushort>> || C <- Weights>>)/binary,0:((8-((WeightsLen*2+ 4) rem 8)) rem 8)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightuivARB(Weights) -> 'ok' when Weights :: [integer()].
weightuivARB(Weights) ->
- cast(5602, <<(length(Weights)):?GLuint,
- (<< <<C:?GLuint>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>).
+ WeightsLen = length(Weights),
+ cast(5603, <<WeightsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Weights>>)/binary,0:(((1+WeightsLen) rem 2)*32)>>).
%% @doc glVertexBlenARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexBlenARB.xml">external</a> documentation.
-spec vertexBlendARB(Count) -> 'ok' when Count :: integer().
vertexBlendARB(Count) ->
- cast(5603, <<Count:?GLint>>).
+ cast(5604, <<Count:?GLint>>).
%% @doc glCurrentPaletteMatrixARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCurrentPaletteMatrixARB.xml">external</a> documentation.
-spec currentPaletteMatrixARB(Index) -> 'ok' when Index :: integer().
currentPaletteMatrixARB(Index) ->
- cast(5604, <<Index:?GLint>>).
+ cast(5605, <<Index:?GLint>>).
%% @doc glMatrixIndexARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation.
-spec matrixIndexubvARB(Indices) -> 'ok' when Indices :: [integer()].
matrixIndexubvARB(Indices) ->
- cast(5605, <<(length(Indices)):?GLuint,
- (<< <<C:?GLubyte>> || C <- Indices>>)/binary,0:((8-((length(Indices)+ 4) rem 8)) rem 8)>>).
+ IndicesLen = length(Indices),
+ cast(5606, <<IndicesLen:?GLuint,
+ (<< <<C:?GLubyte>> || C <- Indices>>)/binary,0:((8-((IndicesLen+ 4) rem 8)) rem 8)>>).
%% @doc glMatrixIndexARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation.
-spec matrixIndexusvARB(Indices) -> 'ok' when Indices :: [integer()].
matrixIndexusvARB(Indices) ->
- cast(5606, <<(length(Indices)):?GLuint,
- (<< <<C:?GLushort>> || C <- Indices>>)/binary,0:((8-((length(Indices)*2+ 4) rem 8)) rem 8)>>).
+ IndicesLen = length(Indices),
+ cast(5607, <<IndicesLen:?GLuint,
+ (<< <<C:?GLushort>> || C <- Indices>>)/binary,0:((8-((IndicesLen*2+ 4) rem 8)) rem 8)>>).
%% @doc glMatrixIndexARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation.
-spec matrixIndexuivARB(Indices) -> 'ok' when Indices :: [integer()].
matrixIndexuivARB(Indices) ->
- cast(5607, <<(length(Indices)):?GLuint,
- (<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((1+length(Indices)) rem 2)*32)>>).
+ IndicesLen = length(Indices),
+ cast(5608, <<IndicesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((1+IndicesLen) rem 2)*32)>>).
%% @doc glProgramStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramStringARB.xml">external</a> documentation.
-spec programStringARB(Target, Format, String) -> 'ok' when Target :: enum(),Format :: enum(),String :: string().
programStringARB(Target,Format,String) ->
- cast(5608, <<Target:?GLenum,Format:?GLenum,(list_to_binary([String|[0]]))/binary,0:((8-((length(String)+ 1) rem 8)) rem 8)>>).
+ StringLen = length(String),
+ cast(5609, <<Target:?GLenum,Format:?GLenum,(list_to_binary([String|[0]]))/binary,0:((8-((StringLen+ 1) rem 8)) rem 8)>>).
%% @doc glBindProgramARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindProgramARB.xml">external</a> documentation.
-spec bindProgramARB(Target, Program) -> 'ok' when Target :: enum(),Program :: integer().
bindProgramARB(Target,Program) ->
- cast(5609, <<Target:?GLenum,Program:?GLuint>>).
+ cast(5610, <<Target:?GLenum,Program:?GLuint>>).
%% @doc glDeleteProgramsARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgramsARB.xml">external</a> documentation.
-spec deleteProgramsARB(Programs) -> 'ok' when Programs :: [integer()].
deleteProgramsARB(Programs) ->
- cast(5610, <<(length(Programs)):?GLuint,
- (<< <<C:?GLuint>> || C <- Programs>>)/binary,0:(((1+length(Programs)) rem 2)*32)>>).
+ ProgramsLen = length(Programs),
+ cast(5611, <<ProgramsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Programs>>)/binary,0:(((1+ProgramsLen) rem 2)*32)>>).
%% @doc glGenProgramsARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenProgramsARB.xml">external</a> documentation.
-spec genProgramsARB(N) -> [integer()] when N :: integer().
genProgramsARB(N) ->
- call(5611, <<N:?GLsizei>>).
+ call(5612, <<N:?GLsizei>>).
%% @doc glProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
-spec programEnvParameter4dARB(Target, Index, X, Y, Z, W) -> 'ok' when Target :: enum(),Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
programEnvParameter4dARB(Target,Index,X,Y,Z,W) ->
- cast(5612, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5613, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @doc glProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
-spec programEnvParameter4dvARB(Target, Index, Params) -> 'ok' when Target :: enum(),Index :: integer(),Params :: {float(),float(),float(),float()}.
programEnvParameter4dvARB(Target,Index,{P1,P2,P3,P4}) ->
- cast(5613, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
+ cast(5614, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
%% @doc glProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
-spec programEnvParameter4fARB(Target, Index, X, Y, Z, W) -> 'ok' when Target :: enum(),Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
programEnvParameter4fARB(Target,Index,X,Y,Z,W) ->
- cast(5614, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5615, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
%% @doc glProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
-spec programEnvParameter4fvARB(Target, Index, Params) -> 'ok' when Target :: enum(),Index :: integer(),Params :: {float(),float(),float(),float()}.
programEnvParameter4fvARB(Target,Index,{P1,P2,P3,P4}) ->
- cast(5615, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
+ cast(5616, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
%% @doc glProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
-spec programLocalParameter4dARB(Target, Index, X, Y, Z, W) -> 'ok' when Target :: enum(),Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
programLocalParameter4dARB(Target,Index,X,Y,Z,W) ->
- cast(5616, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5617, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @doc glProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
-spec programLocalParameter4dvARB(Target, Index, Params) -> 'ok' when Target :: enum(),Index :: integer(),Params :: {float(),float(),float(),float()}.
programLocalParameter4dvARB(Target,Index,{P1,P2,P3,P4}) ->
- cast(5617, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
+ cast(5618, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
%% @doc glProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
-spec programLocalParameter4fARB(Target, Index, X, Y, Z, W) -> 'ok' when Target :: enum(),Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
programLocalParameter4fARB(Target,Index,X,Y,Z,W) ->
- cast(5618, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5619, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
%% @doc glProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
-spec programLocalParameter4fvARB(Target, Index, Params) -> 'ok' when Target :: enum(),Index :: integer(),Params :: {float(),float(),float(),float()}.
programLocalParameter4fvARB(Target,Index,{P1,P2,P3,P4}) ->
- cast(5619, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
+ cast(5620, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
%% @doc glGetProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramEnvParameterARB.xml">external</a> documentation.
-spec getProgramEnvParameterdvARB(Target, Index) -> {float(),float(),float(),float()} when Target :: enum(),Index :: integer().
getProgramEnvParameterdvARB(Target,Index) ->
- call(5620, <<Target:?GLenum,Index:?GLuint>>).
+ call(5621, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glGetProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramEnvParameterARB.xml">external</a> documentation.
-spec getProgramEnvParameterfvARB(Target, Index) -> {float(),float(),float(),float()} when Target :: enum(),Index :: integer().
getProgramEnvParameterfvARB(Target,Index) ->
- call(5621, <<Target:?GLenum,Index:?GLuint>>).
+ call(5622, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glGetProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramLocalParameterARB.xml">external</a> documentation.
-spec getProgramLocalParameterdvARB(Target, Index) -> {float(),float(),float(),float()} when Target :: enum(),Index :: integer().
getProgramLocalParameterdvARB(Target,Index) ->
- call(5622, <<Target:?GLenum,Index:?GLuint>>).
+ call(5623, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glGetProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramLocalParameterARB.xml">external</a> documentation.
-spec getProgramLocalParameterfvARB(Target, Index) -> {float(),float(),float(),float()} when Target :: enum(),Index :: integer().
getProgramLocalParameterfvARB(Target,Index) ->
- call(5623, <<Target:?GLenum,Index:?GLuint>>).
+ call(5624, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glGetProgramStringARB
%%
@@ -13183,176 +13244,180 @@ getProgramLocalParameterfvARB(Target,Index) ->
-spec getProgramStringARB(Target, Pname, String) -> 'ok' when Target :: enum(),Pname :: enum(),String :: mem().
getProgramStringARB(Target,Pname,String) ->
send_bin(String),
- call(5624, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5625, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc glGetBufferParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameterARB.xml">external</a> documentation.
-spec getBufferParameterivARB(Target, Pname) -> [integer()] when Target :: enum(),Pname :: enum().
getBufferParameterivARB(Target,Pname) ->
- call(5625, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5626, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc glDeleteObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteObjectARB.xml">external</a> documentation.
-spec deleteObjectARB(Obj) -> 'ok' when Obj :: integer().
deleteObjectARB(Obj) ->
- cast(5626, <<Obj:?GLhandleARB>>).
+ cast(5627, <<Obj:?GLhandleARB>>).
%% @doc glGetHandleARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetHandleARB.xml">external</a> documentation.
-spec getHandleARB(Pname) -> integer() when Pname :: enum().
getHandleARB(Pname) ->
- call(5627, <<Pname:?GLenum>>).
+ call(5628, <<Pname:?GLenum>>).
%% @doc glDetachObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDetachObjectARB.xml">external</a> documentation.
-spec detachObjectARB(ContainerObj, AttachedObj) -> 'ok' when ContainerObj :: integer(),AttachedObj :: integer().
detachObjectARB(ContainerObj,AttachedObj) ->
- cast(5628, <<ContainerObj:?GLhandleARB,AttachedObj:?GLhandleARB>>).
+ cast(5629, <<ContainerObj:?GLhandleARB,AttachedObj:?GLhandleARB>>).
%% @doc glCreateShaderObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShaderObjectARB.xml">external</a> documentation.
-spec createShaderObjectARB(ShaderType) -> integer() when ShaderType :: enum().
createShaderObjectARB(ShaderType) ->
- call(5629, <<ShaderType:?GLenum>>).
+ call(5630, <<ShaderType:?GLenum>>).
%% @doc glShaderSourceARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderSourceARB.xml">external</a> documentation.
-spec shaderSourceARB(ShaderObj, String) -> 'ok' when ShaderObj :: integer(),String :: iolist().
shaderSourceARB(ShaderObj,String) ->
- StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
- cast(5630, <<ShaderObj:?GLhandleARB,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+4) rem 8)) rem 8)>>).
+ StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
+ StringLen = length(String),
+ cast(5631, <<ShaderObj:?GLhandleARB,StringLen:?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+4) rem 8)) rem 8)>>).
%% @doc glCompileShaderARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShaderARB.xml">external</a> documentation.
-spec compileShaderARB(ShaderObj) -> 'ok' when ShaderObj :: integer().
compileShaderARB(ShaderObj) ->
- cast(5631, <<ShaderObj:?GLhandleARB>>).
+ cast(5632, <<ShaderObj:?GLhandleARB>>).
%% @doc glCreateProgramObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateProgramObjectARB.xml">external</a> documentation.
-spec createProgramObjectARB() -> integer().
createProgramObjectARB() ->
- call(5632, <<>>).
+ call(5633, <<>>).
%% @doc glAttachObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAttachObjectARB.xml">external</a> documentation.
-spec attachObjectARB(ContainerObj, Obj) -> 'ok' when ContainerObj :: integer(),Obj :: integer().
attachObjectARB(ContainerObj,Obj) ->
- cast(5633, <<ContainerObj:?GLhandleARB,Obj:?GLhandleARB>>).
+ cast(5634, <<ContainerObj:?GLhandleARB,Obj:?GLhandleARB>>).
%% @doc glLinkProgramARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgramARB.xml">external</a> documentation.
-spec linkProgramARB(ProgramObj) -> 'ok' when ProgramObj :: integer().
linkProgramARB(ProgramObj) ->
- cast(5634, <<ProgramObj:?GLhandleARB>>).
+ cast(5635, <<ProgramObj:?GLhandleARB>>).
%% @doc glUseProgramObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgramObjectARB.xml">external</a> documentation.
-spec useProgramObjectARB(ProgramObj) -> 'ok' when ProgramObj :: integer().
useProgramObjectARB(ProgramObj) ->
- cast(5635, <<ProgramObj:?GLhandleARB>>).
+ cast(5636, <<ProgramObj:?GLhandleARB>>).
%% @doc glValidateProgramARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgramARB.xml">external</a> documentation.
-spec validateProgramARB(ProgramObj) -> 'ok' when ProgramObj :: integer().
validateProgramARB(ProgramObj) ->
- cast(5636, <<ProgramObj:?GLhandleARB>>).
+ cast(5637, <<ProgramObj:?GLhandleARB>>).
%% @doc glGetObjectParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetObjectParameterARB.xml">external</a> documentation.
-spec getObjectParameterfvARB(Obj, Pname) -> float() when Obj :: integer(),Pname :: enum().
getObjectParameterfvARB(Obj,Pname) ->
- call(5637, <<Obj:?GLhandleARB,Pname:?GLenum>>).
+ call(5638, <<Obj:?GLhandleARB,Pname:?GLenum>>).
%% @doc glGetObjectParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetObjectParameterARB.xml">external</a> documentation.
-spec getObjectParameterivARB(Obj, Pname) -> integer() when Obj :: integer(),Pname :: enum().
getObjectParameterivARB(Obj,Pname) ->
- call(5638, <<Obj:?GLhandleARB,Pname:?GLenum>>).
+ call(5639, <<Obj:?GLhandleARB,Pname:?GLenum>>).
%% @doc glGetInfoLogARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetInfoLogARB.xml">external</a> documentation.
-spec getInfoLogARB(Obj, MaxLength) -> string() when Obj :: integer(),MaxLength :: integer().
getInfoLogARB(Obj,MaxLength) ->
- call(5639, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
+ call(5640, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
%% @doc glGetAttachedObjectsARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttachedObjectsARB.xml">external</a> documentation.
-spec getAttachedObjectsARB(ContainerObj, MaxCount) -> [integer()] when ContainerObj :: integer(),MaxCount :: integer().
getAttachedObjectsARB(ContainerObj,MaxCount) ->
- call(5640, <<ContainerObj:?GLhandleARB,MaxCount:?GLsizei>>).
+ call(5641, <<ContainerObj:?GLhandleARB,MaxCount:?GLsizei>>).
%% @doc glGetUniformLocationARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformLocationARB.xml">external</a> documentation.
-spec getUniformLocationARB(ProgramObj, Name) -> integer() when ProgramObj :: integer(),Name :: string().
getUniformLocationARB(ProgramObj,Name) ->
- call(5641, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5642, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc glGetActiveUniformARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformARB.xml">external</a> documentation.
-spec getActiveUniformARB(ProgramObj, Index, MaxLength) -> {Size :: integer(),Type :: enum(),Name :: string()} when ProgramObj :: integer(),Index :: integer(),MaxLength :: integer().
getActiveUniformARB(ProgramObj,Index,MaxLength) ->
- call(5642, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
+ call(5643, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
%% @doc glGetUniformARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformARB.xml">external</a> documentation.
-spec getUniformfvARB(ProgramObj, Location) -> matrix() when ProgramObj :: integer(),Location :: integer().
getUniformfvARB(ProgramObj,Location) ->
- call(5643, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
+ call(5644, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
%% @doc glGetUniformARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformARB.xml">external</a> documentation.
-spec getUniformivARB(ProgramObj, Location) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} when ProgramObj :: integer(),Location :: integer().
getUniformivARB(ProgramObj,Location) ->
- call(5644, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
+ call(5645, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
%% @doc glGetShaderSourceARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderSourceARB.xml">external</a> documentation.
-spec getShaderSourceARB(Obj, MaxLength) -> string() when Obj :: integer(),MaxLength :: integer().
getShaderSourceARB(Obj,MaxLength) ->
- call(5645, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
+ call(5646, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
%% @doc glBindAttribLocationARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocationARB.xml">external</a> documentation.
-spec bindAttribLocationARB(ProgramObj, Index, Name) -> 'ok' when ProgramObj :: integer(),Index :: integer(),Name :: string().
bindAttribLocationARB(ProgramObj,Index,Name) ->
- cast(5646, <<ProgramObj:?GLhandleARB,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ cast(5647, <<ProgramObj:?GLhandleARB,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc glGetActiveAttribARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveAttribARB.xml">external</a> documentation.
-spec getActiveAttribARB(ProgramObj, Index, MaxLength) -> {Size :: integer(),Type :: enum(),Name :: string()} when ProgramObj :: integer(),Index :: integer(),MaxLength :: integer().
getActiveAttribARB(ProgramObj,Index,MaxLength) ->
- call(5647, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
+ call(5648, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
%% @doc glGetAttribLocationARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocationARB.xml">external</a> documentation.
-spec getAttribLocationARB(ProgramObj, Name) -> integer() when ProgramObj :: integer(),Name :: string().
getAttribLocationARB(ProgramObj,Name) ->
- call(5648, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5649, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc Determine if a name corresponds to a renderbuffer object
%%
@@ -13367,7 +13432,7 @@ getAttribLocationARB(ProgramObj,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsRenderbuffer.xml">external</a> documentation.
-spec isRenderbuffer(Renderbuffer) -> 0|1 when Renderbuffer :: integer().
isRenderbuffer(Renderbuffer) ->
- call(5649, <<Renderbuffer:?GLuint>>).
+ call(5650, <<Renderbuffer:?GLuint>>).
%% @doc Bind a renderbuffer to a renderbuffer target
%%
@@ -13380,7 +13445,7 @@ isRenderbuffer(Renderbuffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindRenderbuffer.xml">external</a> documentation.
-spec bindRenderbuffer(Target, Renderbuffer) -> 'ok' when Target :: enum(),Renderbuffer :: integer().
bindRenderbuffer(Target,Renderbuffer) ->
- cast(5650, <<Target:?GLenum,Renderbuffer:?GLuint>>).
+ cast(5651, <<Target:?GLenum,Renderbuffer:?GLuint>>).
%% @doc Delete renderbuffer objects
%%
@@ -13402,8 +13467,9 @@ bindRenderbuffer(Target,Renderbuffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteRenderbuffers.xml">external</a> documentation.
-spec deleteRenderbuffers(Renderbuffers) -> 'ok' when Renderbuffers :: [integer()].
deleteRenderbuffers(Renderbuffers) ->
- cast(5651, <<(length(Renderbuffers)):?GLuint,
- (<< <<C:?GLuint>> || C <- Renderbuffers>>)/binary,0:(((1+length(Renderbuffers)) rem 2)*32)>>).
+ RenderbuffersLen = length(Renderbuffers),
+ cast(5652, <<RenderbuffersLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Renderbuffers>>)/binary,0:(((1+RenderbuffersLen) rem 2)*32)>>).
%% @doc Generate renderbuffer object names
%%
@@ -13421,7 +13487,7 @@ deleteRenderbuffers(Renderbuffers) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenRenderbuffers.xml">external</a> documentation.
-spec genRenderbuffers(N) -> [integer()] when N :: integer().
genRenderbuffers(N) ->
- call(5652, <<N:?GLsizei>>).
+ call(5653, <<N:?GLsizei>>).
%% @doc Establish data storage, format and dimensions of a renderbuffer object's image
%%
@@ -13442,7 +13508,7 @@ genRenderbuffers(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRenderbufferStorage.xml">external</a> documentation.
-spec renderbufferStorage(Target, Internalformat, Width, Height) -> 'ok' when Target :: enum(),Internalformat :: enum(),Width :: integer(),Height :: integer().
renderbufferStorage(Target,Internalformat,Width,Height) ->
- cast(5653, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5654, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
%% @doc Retrieve information about a bound renderbuffer object
%%
@@ -13470,7 +13536,7 @@ renderbufferStorage(Target,Internalformat,Width,Height) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetRenderbufferParameter.xml">external</a> documentation.
-spec getRenderbufferParameteriv(Target, Pname) -> integer() when Target :: enum(),Pname :: enum().
getRenderbufferParameteriv(Target,Pname) ->
- call(5654, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5655, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc Determine if a name corresponds to a framebuffer object
%%
@@ -13484,7 +13550,7 @@ getRenderbufferParameteriv(Target,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsFramebuffer.xml">external</a> documentation.
-spec isFramebuffer(Framebuffer) -> 0|1 when Framebuffer :: integer().
isFramebuffer(Framebuffer) ->
- call(5655, <<Framebuffer:?GLuint>>).
+ call(5656, <<Framebuffer:?GLuint>>).
%% @doc Bind a framebuffer to a framebuffer target
%%
@@ -13502,7 +13568,7 @@ isFramebuffer(Framebuffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFramebuffer.xml">external</a> documentation.
-spec bindFramebuffer(Target, Framebuffer) -> 'ok' when Target :: enum(),Framebuffer :: integer().
bindFramebuffer(Target,Framebuffer) ->
- cast(5656, <<Target:?GLenum,Framebuffer:?GLuint>>).
+ cast(5657, <<Target:?GLenum,Framebuffer:?GLuint>>).
%% @doc Delete framebuffer objects
%%
@@ -13517,8 +13583,9 @@ bindFramebuffer(Target,Framebuffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteFramebuffers.xml">external</a> documentation.
-spec deleteFramebuffers(Framebuffers) -> 'ok' when Framebuffers :: [integer()].
deleteFramebuffers(Framebuffers) ->
- cast(5657, <<(length(Framebuffers)):?GLuint,
- (<< <<C:?GLuint>> || C <- Framebuffers>>)/binary,0:(((1+length(Framebuffers)) rem 2)*32)>>).
+ FramebuffersLen = length(Framebuffers),
+ cast(5658, <<FramebuffersLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Framebuffers>>)/binary,0:(((1+FramebuffersLen) rem 2)*32)>>).
%% @doc Generate framebuffer object names
%%
@@ -13536,7 +13603,7 @@ deleteFramebuffers(Framebuffers) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenFramebuffers.xml">external</a> documentation.
-spec genFramebuffers(N) -> [integer()] when N :: integer().
genFramebuffers(N) ->
- call(5658, <<N:?GLsizei>>).
+ call(5659, <<N:?GLsizei>>).
%% @doc Check the completeness status of a framebuffer
%%
@@ -13587,25 +13654,25 @@ genFramebuffers(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCheckFramebufferStatus.xml">external</a> documentation.
-spec checkFramebufferStatus(Target) -> enum() when Target :: enum().
checkFramebufferStatus(Target) ->
- call(5659, <<Target:?GLenum>>).
+ call(5660, <<Target:?GLenum>>).
%% @doc
%% See {@link framebufferTexture/4}
-spec framebufferTexture1D(Target, Attachment, Textarget, Texture, Level) -> 'ok' when Target :: enum(),Attachment :: enum(),Textarget :: enum(),Texture :: integer(),Level :: integer().
framebufferTexture1D(Target,Attachment,Textarget,Texture,Level) ->
- cast(5660, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
+ cast(5661, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
%% @doc
%% See {@link framebufferTexture/4}
-spec framebufferTexture2D(Target, Attachment, Textarget, Texture, Level) -> 'ok' when Target :: enum(),Attachment :: enum(),Textarget :: enum(),Texture :: integer(),Level :: integer().
framebufferTexture2D(Target,Attachment,Textarget,Texture,Level) ->
- cast(5661, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
+ cast(5662, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
%% @doc
%% See {@link framebufferTexture/4}
-spec framebufferTexture3D(Target, Attachment, Textarget, Texture, Level, Zoffset) -> 'ok' when Target :: enum(),Attachment :: enum(),Textarget :: enum(),Texture :: integer(),Level :: integer(),Zoffset :: integer().
framebufferTexture3D(Target,Attachment,Textarget,Texture,Level,Zoffset) ->
- cast(5662, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint,Zoffset:?GLint>>).
+ cast(5663, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint,Zoffset:?GLint>>).
%% @doc Attach a renderbuffer as a logical buffer to the currently bound framebuffer object
%%
@@ -13637,7 +13704,7 @@ framebufferTexture3D(Target,Attachment,Textarget,Texture,Level,Zoffset) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferRenderbuffer.xml">external</a> documentation.
-spec framebufferRenderbuffer(Target, Attachment, Renderbuffertarget, Renderbuffer) -> 'ok' when Target :: enum(),Attachment :: enum(),Renderbuffertarget :: enum(),Renderbuffer :: integer().
framebufferRenderbuffer(Target,Attachment,Renderbuffertarget,Renderbuffer) ->
- cast(5663, <<Target:?GLenum,Attachment:?GLenum,Renderbuffertarget:?GLenum,Renderbuffer:?GLuint>>).
+ cast(5664, <<Target:?GLenum,Attachment:?GLenum,Renderbuffertarget:?GLenum,Renderbuffer:?GLuint>>).
%% @doc Retrieve information about attachments of a bound framebuffer object
%%
@@ -13733,7 +13800,7 @@ framebufferRenderbuffer(Target,Attachment,Renderbuffertarget,Renderbuffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFramebufferAttachmentParameter.xml">external</a> documentation.
-spec getFramebufferAttachmentParameteriv(Target, Attachment, Pname) -> integer() when Target :: enum(),Attachment :: enum(),Pname :: enum().
getFramebufferAttachmentParameteriv(Target,Attachment,Pname) ->
- call(5664, <<Target:?GLenum,Attachment:?GLenum,Pname:?GLenum>>).
+ call(5665, <<Target:?GLenum,Attachment:?GLenum,Pname:?GLenum>>).
%% @doc Generate mipmaps for a specified texture target
%%
@@ -13753,7 +13820,7 @@ getFramebufferAttachmentParameteriv(Target,Attachment,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenerateMipmap.xml">external</a> documentation.
-spec generateMipmap(Target) -> 'ok' when Target :: enum().
generateMipmap(Target) ->
- cast(5665, <<Target:?GLenum>>).
+ cast(5666, <<Target:?GLenum>>).
%% @doc Copy a block of pixels from the read framebuffer to the draw framebuffer
%%
@@ -13795,7 +13862,7 @@ generateMipmap(Target) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlitFramebuffer.xml">external</a> documentation.
-spec blitFramebuffer(SrcX0, SrcY0, SrcX1, SrcY1, DstX0, DstY0, DstX1, DstY1, Mask, Filter) -> 'ok' when SrcX0 :: integer(),SrcY0 :: integer(),SrcX1 :: integer(),SrcY1 :: integer(),DstX0 :: integer(),DstY0 :: integer(),DstX1 :: integer(),DstY1 :: integer(),Mask :: integer(),Filter :: enum().
blitFramebuffer(SrcX0,SrcY0,SrcX1,SrcY1,DstX0,DstY0,DstX1,DstY1,Mask,Filter) ->
- cast(5666, <<SrcX0:?GLint,SrcY0:?GLint,SrcX1:?GLint,SrcY1:?GLint,DstX0:?GLint,DstY0:?GLint,DstX1:?GLint,DstY1:?GLint,Mask:?GLbitfield,Filter:?GLenum>>).
+ cast(5667, <<SrcX0:?GLint,SrcY0:?GLint,SrcX1:?GLint,SrcY1:?GLint,DstX0:?GLint,DstY0:?GLint,DstX1:?GLint,DstY1:?GLint,Mask:?GLbitfield,Filter:?GLenum>>).
%% @doc Establish data storage, format, dimensions and sample count of a renderbuffer object's image
%%
@@ -13819,19 +13886,19 @@ blitFramebuffer(SrcX0,SrcY0,SrcX1,SrcY1,DstX0,DstY0,DstX1,DstY1,Mask,Filter) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRenderbufferStorageMultisample.xml">external</a> documentation.
-spec renderbufferStorageMultisample(Target, Samples, Internalformat, Width, Height) -> 'ok' when Target :: enum(),Samples :: integer(),Internalformat :: enum(),Width :: integer(),Height :: integer().
renderbufferStorageMultisample(Target,Samples,Internalformat,Width,Height) ->
- cast(5667, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5668, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
%% @doc
%% See {@link framebufferTexture/4}
-spec framebufferTextureLayer(Target, Attachment, Texture, Level, Layer) -> 'ok' when Target :: enum(),Attachment :: enum(),Texture :: integer(),Level :: integer(),Layer :: integer().
framebufferTextureLayer(Target,Attachment,Texture,Level,Layer) ->
- cast(5668, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Layer:?GLint>>).
+ cast(5669, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Layer:?GLint>>).
%% @doc
%% See {@link framebufferTexture/4}
-spec framebufferTextureFaceARB(Target, Attachment, Texture, Level, Face) -> 'ok' when Target :: enum(),Attachment :: enum(),Texture :: integer(),Level :: integer(),Face :: enum().
framebufferTextureFaceARB(Target,Attachment,Texture,Level,Face) ->
- cast(5669, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Face:?GLenum>>).
+ cast(5670, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Face:?GLenum>>).
%% @doc Indicate modifications to a range of a mapped buffer
%%
@@ -13845,7 +13912,7 @@ framebufferTextureFaceARB(Target,Attachment,Texture,Level,Face) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFlushMappedBufferRange.xml">external</a> documentation.
-spec flushMappedBufferRange(Target, Offset, Length) -> 'ok' when Target :: enum(),Offset :: integer(),Length :: integer().
flushMappedBufferRange(Target,Offset,Length) ->
- cast(5670, <<Target:?GLenum,0:32,Offset:?GLintptr,Length:?GLsizeiptr>>).
+ cast(5671, <<Target:?GLenum,0:32,Offset:?GLintptr,Length:?GLsizeiptr>>).
%% @doc Bind a vertex array object
%%
@@ -13860,7 +13927,7 @@ flushMappedBufferRange(Target,Offset,Length) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindVertexArray.xml">external</a> documentation.
-spec bindVertexArray(Array) -> 'ok' when Array :: integer().
bindVertexArray(Array) ->
- cast(5671, <<Array:?GLuint>>).
+ cast(5672, <<Array:?GLuint>>).
%% @doc Delete vertex array objects
%%
@@ -13873,8 +13940,9 @@ bindVertexArray(Array) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteVertexArrays.xml">external</a> documentation.
-spec deleteVertexArrays(Arrays) -> 'ok' when Arrays :: [integer()].
deleteVertexArrays(Arrays) ->
- cast(5672, <<(length(Arrays)):?GLuint,
- (<< <<C:?GLuint>> || C <- Arrays>>)/binary,0:(((1+length(Arrays)) rem 2)*32)>>).
+ ArraysLen = length(Arrays),
+ cast(5673, <<ArraysLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Arrays>>)/binary,0:(((1+ArraysLen) rem 2)*32)>>).
%% @doc Generate vertex array object names
%%
@@ -13892,7 +13960,7 @@ deleteVertexArrays(Arrays) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenVertexArrays.xml">external</a> documentation.
-spec genVertexArrays(N) -> [integer()] when N :: integer().
genVertexArrays(N) ->
- call(5673, <<N:?GLsizei>>).
+ call(5674, <<N:?GLsizei>>).
%% @doc Determine if a name corresponds to a vertex array object
%%
@@ -13906,7 +13974,7 @@ genVertexArrays(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsVertexArray.xml">external</a> documentation.
-spec isVertexArray(Array) -> 0|1 when Array :: integer().
isVertexArray(Array) ->
- call(5674, <<Array:?GLuint>>).
+ call(5675, <<Array:?GLuint>>).
%% @doc Retrieve the index of a named uniform block
%%
@@ -13933,16 +14001,18 @@ isVertexArray(Array) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformIndices.xml">external</a> documentation.
-spec getUniformIndices(Program, UniformNames) -> [integer()] when Program :: integer(),UniformNames :: iolist().
getUniformIndices(Program,UniformNames) ->
- UniformNamesTemp = list_to_binary([[Str|[0]] || Str <- UniformNames ]),
- call(5675, <<Program:?GLuint,(length(UniformNames)):?GLuint,(size(UniformNamesTemp)):?GLuint,(UniformNamesTemp)/binary,0:((8-((size(UniformNamesTemp)+0) rem 8)) rem 8)>>).
+ UniformNamesTemp = list_to_binary([[Str|[0]] || Str <- UniformNames ]),
+ UniformNamesLen = length(UniformNames),
+ call(5676, <<Program:?GLuint,UniformNamesLen:?GLuint,(size(UniformNamesTemp)):?GLuint,(UniformNamesTemp)/binary,0:((8-((size(UniformNamesTemp)+0) rem 8)) rem 8)>>).
%% @doc glGetActiveUniforms
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniforms.xml">external</a> documentation.
-spec getActiveUniformsiv(Program, UniformIndices, Pname) -> [integer()] when Program :: integer(),UniformIndices :: [integer()],Pname :: enum().
getActiveUniformsiv(Program,UniformIndices,Pname) ->
- call(5676, <<Program:?GLuint,(length(UniformIndices)):?GLuint,
- (<< <<C:?GLuint>> || C <- UniformIndices>>)/binary,0:(((length(UniformIndices)) rem 2)*32),Pname:?GLenum>>).
+ UniformIndicesLen = length(UniformIndices),
+ call(5677, <<Program:?GLuint,UniformIndicesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- UniformIndices>>)/binary,0:(((UniformIndicesLen) rem 2)*32),Pname:?GLenum>>).
%% @doc Query the name of an active uniform
%%
@@ -13971,7 +14041,7 @@ getActiveUniformsiv(Program,UniformIndices,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformName.xml">external</a> documentation.
-spec getActiveUniformName(Program, UniformIndex, BufSize) -> string() when Program :: integer(),UniformIndex :: integer(),BufSize :: integer().
getActiveUniformName(Program,UniformIndex,BufSize) ->
- call(5677, <<Program:?GLuint,UniformIndex:?GLuint,BufSize:?GLsizei>>).
+ call(5678, <<Program:?GLuint,UniformIndex:?GLuint,BufSize:?GLsizei>>).
%% @doc Retrieve the index of a named uniform block
%%
@@ -13995,7 +14065,8 @@ getActiveUniformName(Program,UniformIndex,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformBlockIndex.xml">external</a> documentation.
-spec getUniformBlockIndex(Program, UniformBlockName) -> integer() when Program :: integer(),UniformBlockName :: string().
getUniformBlockIndex(Program,UniformBlockName) ->
- call(5678, <<Program:?GLuint,(list_to_binary([UniformBlockName|[0]]))/binary,0:((8-((length(UniformBlockName)+ 5) rem 8)) rem 8)>>).
+ UniformBlockNameLen = length(UniformBlockName),
+ call(5679, <<Program:?GLuint,(list_to_binary([UniformBlockName|[0]]))/binary,0:((8-((UniformBlockNameLen+ 5) rem 8)) rem 8)>>).
%% @doc Query information about an active uniform block
%%
@@ -14048,7 +14119,7 @@ getUniformBlockIndex(Program,UniformBlockName) ->
-spec getActiveUniformBlockiv(Program, UniformBlockIndex, Pname, Params) -> 'ok' when Program :: integer(),UniformBlockIndex :: integer(),Pname :: enum(),Params :: mem().
getActiveUniformBlockiv(Program,UniformBlockIndex,Pname,Params) ->
send_bin(Params),
- call(5679, <<Program:?GLuint,UniformBlockIndex:?GLuint,Pname:?GLenum>>).
+ call(5680, <<Program:?GLuint,UniformBlockIndex:?GLuint,Pname:?GLenum>>).
%% @doc Retrieve the name of an active uniform block
%%
@@ -14077,7 +14148,7 @@ getActiveUniformBlockiv(Program,UniformBlockIndex,Pname,Params) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformBlockName.xml">external</a> documentation.
-spec getActiveUniformBlockName(Program, UniformBlockIndex, BufSize) -> string() when Program :: integer(),UniformBlockIndex :: integer(),BufSize :: integer().
getActiveUniformBlockName(Program,UniformBlockIndex,BufSize) ->
- call(5680, <<Program:?GLuint,UniformBlockIndex:?GLuint,BufSize:?GLsizei>>).
+ call(5681, <<Program:?GLuint,UniformBlockIndex:?GLuint,BufSize:?GLsizei>>).
%% @doc Assign a binding point to an active uniform block
%%
@@ -14097,7 +14168,7 @@ getActiveUniformBlockName(Program,UniformBlockIndex,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformBlockBinding.xml">external</a> documentation.
-spec uniformBlockBinding(Program, UniformBlockIndex, UniformBlockBinding) -> 'ok' when Program :: integer(),UniformBlockIndex :: integer(),UniformBlockBinding :: integer().
uniformBlockBinding(Program,UniformBlockIndex,UniformBlockBinding) ->
- cast(5681, <<Program:?GLuint,UniformBlockIndex:?GLuint,UniformBlockBinding:?GLuint>>).
+ cast(5682, <<Program:?GLuint,UniformBlockIndex:?GLuint,UniformBlockBinding:?GLuint>>).
%% @doc Copy part of the data store of a buffer object to the data store of another buffer object
%%
@@ -14123,7 +14194,7 @@ uniformBlockBinding(Program,UniformBlockIndex,UniformBlockBinding) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyBufferSubData.xml">external</a> documentation.
-spec copyBufferSubData(ReadTarget, WriteTarget, ReadOffset, WriteOffset, Size) -> 'ok' when ReadTarget :: enum(),WriteTarget :: enum(),ReadOffset :: integer(),WriteOffset :: integer(),Size :: integer().
copyBufferSubData(ReadTarget,WriteTarget,ReadOffset,WriteOffset,Size) ->
- cast(5682, <<ReadTarget:?GLenum,WriteTarget:?GLenum,ReadOffset:?GLintptr,WriteOffset:?GLintptr,Size:?GLsizeiptr>>).
+ cast(5683, <<ReadTarget:?GLenum,WriteTarget:?GLenum,ReadOffset:?GLintptr,WriteOffset:?GLintptr,Size:?GLsizeiptr>>).
%% @doc Render primitives from array data with a per-element offset
%%
@@ -14137,10 +14208,10 @@ copyBufferSubData(ReadTarget,WriteTarget,ReadOffset,WriteOffset,Size) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsBaseVertex.xml">external</a> documentation.
-spec drawElementsBaseVertex(Mode, Count, Type, Indices, Basevertex) -> 'ok' when Mode :: enum(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Basevertex :: integer().
drawElementsBaseVertex(Mode,Count,Type,Indices,Basevertex) when is_integer(Indices) ->
- cast(5683, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Basevertex:?GLint>>);
+ cast(5684, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Basevertex:?GLint>>);
drawElementsBaseVertex(Mode,Count,Type,Indices,Basevertex) ->
send_bin(Indices),
- cast(5684, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Basevertex:?GLint>>).
+ cast(5685, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Basevertex:?GLint>>).
%% @doc Render primitives from array data with a per-element offset
%%
@@ -14159,10 +14230,10 @@ drawElementsBaseVertex(Mode,Count,Type,Indices,Basevertex) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawRangeElementsBaseVertex.xml">external</a> documentation.
-spec drawRangeElementsBaseVertex(Mode, Start, End, Count, Type, Indices, Basevertex) -> 'ok' when Mode :: enum(),Start :: integer(),End :: integer(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Basevertex :: integer().
drawRangeElementsBaseVertex(Mode,Start,End,Count,Type,Indices,Basevertex) when is_integer(Indices) ->
- cast(5685, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Basevertex:?GLint>>);
+ cast(5686, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Basevertex:?GLint>>);
drawRangeElementsBaseVertex(Mode,Start,End,Count,Type,Indices,Basevertex) ->
send_bin(Indices),
- cast(5686, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Basevertex:?GLint>>).
+ cast(5687, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Basevertex:?GLint>>).
%% @doc Render multiple instances of a set of primitives from array data with a per-element offset
%%
@@ -14176,10 +14247,10 @@ drawRangeElementsBaseVertex(Mode,Start,End,Count,Type,Indices,Basevertex) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstancedBaseVertex.xml">external</a> documentation.
-spec drawElementsInstancedBaseVertex(Mode, Count, Type, Indices, Primcount, Basevertex) -> 'ok' when Mode :: enum(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Primcount :: integer(),Basevertex :: integer().
drawElementsInstancedBaseVertex(Mode,Count,Type,Indices,Primcount,Basevertex) when is_integer(Indices) ->
- cast(5687, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Basevertex:?GLint>>);
+ cast(5688, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Basevertex:?GLint>>);
drawElementsInstancedBaseVertex(Mode,Count,Type,Indices,Primcount,Basevertex) ->
send_bin(Indices),
- cast(5688, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Basevertex:?GLint>>).
+ cast(5689, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Basevertex:?GLint>>).
%% @doc Specifiy the vertex to be used as the source of data for flat shaded varyings
%%
@@ -14213,7 +14284,7 @@ drawElementsInstancedBaseVertex(Mode,Count,Type,Indices,Primcount,Basevertex) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProvokingVertex.xml">external</a> documentation.
-spec provokingVertex(Mode) -> 'ok' when Mode :: enum().
provokingVertex(Mode) ->
- cast(5689, <<Mode:?GLenum>>).
+ cast(5690, <<Mode:?GLenum>>).
%% @doc Create a new sync object and insert it into the GL command stream
%%
@@ -14237,7 +14308,7 @@ provokingVertex(Mode) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFenceSync.xml">external</a> documentation.
-spec fenceSync(Condition, Flags) -> integer() when Condition :: enum(),Flags :: integer().
fenceSync(Condition,Flags) ->
- call(5690, <<Condition:?GLenum,Flags:?GLbitfield>>).
+ call(5691, <<Condition:?GLenum,Flags:?GLbitfield>>).
%% @doc Determine if a name corresponds to a sync object
%%
@@ -14248,7 +14319,7 @@ fenceSync(Condition,Flags) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsSync.xml">external</a> documentation.
-spec isSync(Sync) -> 0|1 when Sync :: integer().
isSync(Sync) ->
- call(5691, <<Sync:?GLsync>>).
+ call(5692, <<Sync:?GLsync>>).
%% @doc Delete a sync object
%%
@@ -14265,7 +14336,7 @@ isSync(Sync) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteSync.xml">external</a> documentation.
-spec deleteSync(Sync) -> 'ok' when Sync :: integer().
deleteSync(Sync) ->
- cast(5692, <<Sync:?GLsync>>).
+ cast(5693, <<Sync:?GLsync>>).
%% @doc Block and wait for a sync object to become signaled
%%
@@ -14291,7 +14362,7 @@ deleteSync(Sync) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClientWaitSync.xml">external</a> documentation.
-spec clientWaitSync(Sync, Flags, Timeout) -> enum() when Sync :: integer(),Flags :: integer(),Timeout :: integer().
clientWaitSync(Sync,Flags,Timeout) ->
- call(5693, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>).
+ call(5694, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>).
%% @doc Instruct the GL server to block until the specified sync object becomes signaled
%%
@@ -14313,13 +14384,13 @@ clientWaitSync(Sync,Flags,Timeout) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWaitSync.xml">external</a> documentation.
-spec waitSync(Sync, Flags, Timeout) -> 'ok' when Sync :: integer(),Flags :: integer(),Timeout :: integer().
waitSync(Sync,Flags,Timeout) ->
- cast(5694, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>).
+ cast(5695, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getInteger64v(Pname) -> [integer()] when Pname :: enum().
getInteger64v(Pname) ->
- call(5695, <<Pname:?GLenum>>).
+ call(5696, <<Pname:?GLenum>>).
%% @doc Query the properties of a sync object
%%
@@ -14354,7 +14425,7 @@ getInteger64v(Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSync.xml">external</a> documentation.
-spec getSynciv(Sync, Pname, BufSize) -> [integer()] when Sync :: integer(),Pname :: enum(),BufSize :: integer().
getSynciv(Sync,Pname,BufSize) ->
- call(5696, <<Sync:?GLsync,Pname:?GLenum,BufSize:?GLsizei>>).
+ call(5697, <<Sync:?GLsync,Pname:?GLenum,BufSize:?GLsizei>>).
%% @doc Establish the data storage, format, dimensions, and number of samples of a multisample texture's image
%%
@@ -14382,7 +14453,7 @@ getSynciv(Sync,Pname,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2DMultisample.xml">external</a> documentation.
-spec texImage2DMultisample(Target, Samples, Internalformat, Width, Height, Fixedsamplelocations) -> 'ok' when Target :: enum(),Samples :: integer(),Internalformat :: integer(),Width :: integer(),Height :: integer(),Fixedsamplelocations :: 0|1.
texImage2DMultisample(Target,Samples,Internalformat,Width,Height,Fixedsamplelocations) ->
- cast(5697, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Fixedsamplelocations:?GLboolean>>).
+ cast(5698, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Fixedsamplelocations:?GLboolean>>).
%% @doc Establish the data storage, format, dimensions, and number of samples of a multisample texture's image
%%
@@ -14410,7 +14481,7 @@ texImage2DMultisample(Target,Samples,Internalformat,Width,Height,Fixedsampleloca
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage3DMultisample.xml">external</a> documentation.
-spec texImage3DMultisample(Target, Samples, Internalformat, Width, Height, Depth, Fixedsamplelocations) -> 'ok' when Target :: enum(),Samples :: integer(),Internalformat :: integer(),Width :: integer(),Height :: integer(),Depth :: integer(),Fixedsamplelocations :: 0|1.
texImage3DMultisample(Target,Samples,Internalformat,Width,Height,Depth,Fixedsamplelocations) ->
- cast(5698, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Fixedsamplelocations:?GLboolean>>).
+ cast(5699, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Fixedsamplelocations:?GLboolean>>).
%% @doc Retrieve the location of a sample
%%
@@ -14428,7 +14499,7 @@ texImage3DMultisample(Target,Samples,Internalformat,Width,Height,Depth,Fixedsamp
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMultisample.xml">external</a> documentation.
-spec getMultisamplefv(Pname, Index) -> {float(),float()} when Pname :: enum(),Index :: integer().
getMultisamplefv(Pname,Index) ->
- call(5699, <<Pname:?GLenum,Index:?GLuint>>).
+ call(5700, <<Pname:?GLenum,Index:?GLuint>>).
%% @doc Set the value of a sub-word of the sample mask
%%
@@ -14443,57 +14514,65 @@ getMultisamplefv(Pname,Index) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSampleMaski.xml">external</a> documentation.
-spec sampleMaski(Index, Mask) -> 'ok' when Index :: integer(),Mask :: integer().
sampleMaski(Index,Mask) ->
- cast(5700, <<Index:?GLuint,Mask:?GLbitfield>>).
+ cast(5701, <<Index:?GLuint,Mask:?GLbitfield>>).
%% @doc glNamedStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNamedStringARB.xml">external</a> documentation.
-spec namedStringARB(Type, Name, String) -> 'ok' when Type :: enum(),Name :: string(),String :: string().
namedStringARB(Type,Name,String) ->
- cast(5701, <<Type:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8),(list_to_binary([String|[0]]))/binary,0:((8-((length(String)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ StringLen = length(String),
+ cast(5702, <<Type:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8),(list_to_binary([String|[0]]))/binary,0:((8-((StringLen+ 1) rem 8)) rem 8)>>).
%% @doc glDeleteNamedStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteNamedStringARB.xml">external</a> documentation.
-spec deleteNamedStringARB(Name) -> 'ok' when Name :: string().
deleteNamedStringARB(Name) ->
- cast(5702, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ cast(5703, <<(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc glCompileShaderIncludeARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShaderIncludeARB.xml">external</a> documentation.
-spec compileShaderIncludeARB(Shader, Path) -> 'ok' when Shader :: integer(),Path :: iolist().
compileShaderIncludeARB(Shader,Path) ->
- PathTemp = list_to_binary([[Str|[0]] || Str <- Path ]),
- cast(5703, <<Shader:?GLuint,(length(Path)):?GLuint,(size(PathTemp)):?GLuint,(PathTemp)/binary,0:((8-((size(PathTemp)+0) rem 8)) rem 8)>>).
+ PathTemp = list_to_binary([[Str|[0]] || Str <- Path ]),
+ PathLen = length(Path),
+ cast(5704, <<Shader:?GLuint,PathLen:?GLuint,(size(PathTemp)):?GLuint,(PathTemp)/binary,0:((8-((size(PathTemp)+0) rem 8)) rem 8)>>).
%% @doc glIsNamedStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsNamedStringARB.xml">external</a> documentation.
-spec isNamedStringARB(Name) -> 0|1 when Name :: string().
isNamedStringARB(Name) ->
- call(5704, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5705, <<(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc glGetNamedStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetNamedStringARB.xml">external</a> documentation.
-spec getNamedStringARB(Name, BufSize) -> string() when Name :: string(),BufSize :: integer().
getNamedStringARB(Name,BufSize) ->
- call(5705, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8),BufSize:?GLsizei>>).
+ NameLen = length(Name),
+ call(5706, <<(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8),BufSize:?GLsizei>>).
%% @doc glGetNamedStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetNamedStringARB.xml">external</a> documentation.
-spec getNamedStringivARB(Name, Pname) -> integer() when Name :: string(),Pname :: enum().
getNamedStringivARB(Name,Pname) ->
- call(5706, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8),Pname:?GLenum>>).
+ NameLen = length(Name),
+ call(5707, <<(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8),Pname:?GLenum>>).
%% @doc glBindFragDataLocationIndexe
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFragDataLocationIndexe.xml">external</a> documentation.
-spec bindFragDataLocationIndexed(Program, ColorNumber, Index, Name) -> 'ok' when Program :: integer(),ColorNumber :: integer(),Index :: integer(),Name :: string().
bindFragDataLocationIndexed(Program,ColorNumber,Index,Name) ->
- cast(5707, <<Program:?GLuint,ColorNumber:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ cast(5708, <<Program:?GLuint,ColorNumber:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc Query the bindings of color indices to user-defined varying out variables
%%
@@ -14504,7 +14583,8 @@ bindFragDataLocationIndexed(Program,ColorNumber,Index,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFragDataIndex.xml">external</a> documentation.
-spec getFragDataIndex(Program, Name) -> integer() when Program :: integer(),Name :: string().
getFragDataIndex(Program,Name) ->
- call(5708, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5709, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc Generate sampler object names
%%
@@ -14522,7 +14602,7 @@ getFragDataIndex(Program,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenSamplers.xml">external</a> documentation.
-spec genSamplers(Count) -> [integer()] when Count :: integer().
genSamplers(Count) ->
- call(5709, <<Count:?GLsizei>>).
+ call(5710, <<Count:?GLsizei>>).
%% @doc Delete named sampler objects
%%
@@ -14535,8 +14615,9 @@ genSamplers(Count) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteSamplers.xml">external</a> documentation.
-spec deleteSamplers(Samplers) -> 'ok' when Samplers :: [integer()].
deleteSamplers(Samplers) ->
- cast(5710, <<(length(Samplers)):?GLuint,
- (<< <<C:?GLuint>> || C <- Samplers>>)/binary,0:(((1+length(Samplers)) rem 2)*32)>>).
+ SamplersLen = length(Samplers),
+ cast(5711, <<SamplersLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Samplers>>)/binary,0:(((1+SamplersLen) rem 2)*32)>>).
%% @doc Determine if a name corresponds to a sampler object
%%
@@ -14549,7 +14630,7 @@ deleteSamplers(Samplers) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsSampler.xml">external</a> documentation.
-spec isSampler(Sampler) -> 0|1 when Sampler :: integer().
isSampler(Sampler) ->
- call(5711, <<Sampler:?GLuint>>).
+ call(5712, <<Sampler:?GLuint>>).
%% @doc Bind a named sampler to a texturing target
%%
@@ -14566,7 +14647,7 @@ isSampler(Sampler) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindSampler.xml">external</a> documentation.
-spec bindSampler(Unit, Sampler) -> 'ok' when Unit :: integer(),Sampler :: integer().
bindSampler(Unit,Sampler) ->
- cast(5712, <<Unit:?GLuint,Sampler:?GLuint>>).
+ cast(5713, <<Unit:?GLuint,Sampler:?GLuint>>).
%% @doc Set sampler parameters
%%
@@ -14712,42 +14793,46 @@ bindSampler(Unit,Sampler) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameter.xml">external</a> documentation.
-spec samplerParameteri(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: integer().
samplerParameteri(Sampler,Pname,Param) ->
- cast(5713, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLint>>).
+ cast(5714, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLint>>).
%% @doc
%% See {@link samplerParameteri/3}
-spec samplerParameteriv(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: [integer()].
samplerParameteriv(Sampler,Pname,Param) ->
- cast(5714, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint,
- (<< <<C:?GLint>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>).
+ ParamLen = length(Param),
+ cast(5715, <<Sampler:?GLuint,Pname:?GLenum,ParamLen:?GLuint,
+ (<< <<C:?GLint>> || C <- Param>>)/binary,0:(((1+ParamLen) rem 2)*32)>>).
%% @doc
%% See {@link samplerParameteri/3}
-spec samplerParameterf(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: float().
samplerParameterf(Sampler,Pname,Param) ->
- cast(5715, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLfloat>>).
+ cast(5716, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLfloat>>).
%% @doc
%% See {@link samplerParameteri/3}
-spec samplerParameterfv(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: [float()].
samplerParameterfv(Sampler,Pname,Param) ->
- cast(5716, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint,
- (<< <<C:?GLfloat>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>).
+ ParamLen = length(Param),
+ cast(5717, <<Sampler:?GLuint,Pname:?GLenum,ParamLen:?GLuint,
+ (<< <<C:?GLfloat>> || C <- Param>>)/binary,0:(((1+ParamLen) rem 2)*32)>>).
%% @doc
%% See {@link samplerParameteri/3}
-spec samplerParameterIiv(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: [integer()].
samplerParameterIiv(Sampler,Pname,Param) ->
- cast(5717, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint,
- (<< <<C:?GLint>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>).
+ ParamLen = length(Param),
+ cast(5718, <<Sampler:?GLuint,Pname:?GLenum,ParamLen:?GLuint,
+ (<< <<C:?GLint>> || C <- Param>>)/binary,0:(((1+ParamLen) rem 2)*32)>>).
%% @doc glSamplerParameterI
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameterI.xml">external</a> documentation.
-spec samplerParameterIuiv(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: [integer()].
samplerParameterIuiv(Sampler,Pname,Param) ->
- cast(5718, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint,
- (<< <<C:?GLuint>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>).
+ ParamLen = length(Param),
+ cast(5719, <<Sampler:?GLuint,Pname:?GLenum,ParamLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Param>>)/binary,0:(((1+ParamLen) rem 2)*32)>>).
%% @doc Return sampler parameter values
%%
@@ -14794,26 +14879,26 @@ samplerParameterIuiv(Sampler,Pname,Param) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameter.xml">external</a> documentation.
-spec getSamplerParameteriv(Sampler, Pname) -> [integer()] when Sampler :: integer(),Pname :: enum().
getSamplerParameteriv(Sampler,Pname) ->
- call(5719, <<Sampler:?GLuint,Pname:?GLenum>>).
+ call(5720, <<Sampler:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link getSamplerParameteriv/2}
-spec getSamplerParameterIiv(Sampler, Pname) -> [integer()] when Sampler :: integer(),Pname :: enum().
getSamplerParameterIiv(Sampler,Pname) ->
- call(5720, <<Sampler:?GLuint,Pname:?GLenum>>).
+ call(5721, <<Sampler:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link getSamplerParameteriv/2}
-spec getSamplerParameterfv(Sampler, Pname) -> [float()] when Sampler :: integer(),Pname :: enum().
getSamplerParameterfv(Sampler,Pname) ->
- call(5721, <<Sampler:?GLuint,Pname:?GLenum>>).
+ call(5722, <<Sampler:?GLuint,Pname:?GLenum>>).
%% @doc glGetSamplerParameterI
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameterI.xml">external</a> documentation.
-spec getSamplerParameterIuiv(Sampler, Pname) -> [integer()] when Sampler :: integer(),Pname :: enum().
getSamplerParameterIuiv(Sampler,Pname) ->
- call(5722, <<Sampler:?GLuint,Pname:?GLenum>>).
+ call(5723, <<Sampler:?GLuint,Pname:?GLenum>>).
%% @doc Record the GL time into a query object after all previous commands have reached the GL server but have not yet necessarily executed.
%%
@@ -14828,21 +14913,21 @@ getSamplerParameterIuiv(Sampler,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glQueryCounter.xml">external</a> documentation.
-spec queryCounter(Id, Target) -> 'ok' when Id :: integer(),Target :: enum().
queryCounter(Id,Target) ->
- cast(5723, <<Id:?GLuint,Target:?GLenum>>).
+ cast(5724, <<Id:?GLuint,Target:?GLenum>>).
%% @doc glGetQueryObjecti64v
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObjecti64v.xml">external</a> documentation.
-spec getQueryObjecti64v(Id, Pname) -> integer() when Id :: integer(),Pname :: enum().
getQueryObjecti64v(Id,Pname) ->
- call(5724, <<Id:?GLuint,Pname:?GLenum>>).
+ call(5725, <<Id:?GLuint,Pname:?GLenum>>).
%% @doc glGetQueryObjectui64v
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObjectui64v.xml">external</a> documentation.
-spec getQueryObjectui64v(Id, Pname) -> integer() when Id :: integer(),Pname :: enum().
getQueryObjectui64v(Id,Pname) ->
- call(5725, <<Id:?GLuint,Pname:?GLenum>>).
+ call(5726, <<Id:?GLuint,Pname:?GLenum>>).
%% @doc Render primitives from array data, taking parameters from memory
%%
@@ -14872,10 +14957,10 @@ getQueryObjectui64v(Id,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArraysIndirect.xml">external</a> documentation.
-spec drawArraysIndirect(Mode, Indirect) -> 'ok' when Mode :: enum(),Indirect :: offset()|mem().
drawArraysIndirect(Mode,Indirect) when is_integer(Indirect) ->
- cast(5726, <<Mode:?GLenum,Indirect:?GLuint>>);
+ cast(5727, <<Mode:?GLenum,Indirect:?GLuint>>);
drawArraysIndirect(Mode,Indirect) ->
send_bin(Indirect),
- cast(5727, <<Mode:?GLenum>>).
+ cast(5728, <<Mode:?GLenum>>).
%% @doc Render indexed primitives from array data, taking parameters from memory
%%
@@ -14912,131 +14997,144 @@ drawArraysIndirect(Mode,Indirect) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsIndirect.xml">external</a> documentation.
-spec drawElementsIndirect(Mode, Type, Indirect) -> 'ok' when Mode :: enum(),Type :: enum(),Indirect :: offset()|mem().
drawElementsIndirect(Mode,Type,Indirect) when is_integer(Indirect) ->
- cast(5728, <<Mode:?GLenum,Type:?GLenum,Indirect:?GLuint>>);
+ cast(5729, <<Mode:?GLenum,Type:?GLenum,Indirect:?GLuint>>);
drawElementsIndirect(Mode,Type,Indirect) ->
send_bin(Indirect),
- cast(5729, <<Mode:?GLenum,Type:?GLenum>>).
+ cast(5730, <<Mode:?GLenum,Type:?GLenum>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1d(Location, X) -> 'ok' when Location :: integer(),X :: float().
uniform1d(Location,X) ->
- cast(5730, <<Location:?GLint,0:32,X:?GLdouble>>).
+ cast(5731, <<Location:?GLint,0:32,X:?GLdouble>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2d(Location, X, Y) -> 'ok' when Location :: integer(),X :: float(),Y :: float().
uniform2d(Location,X,Y) ->
- cast(5731, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble>>).
+ cast(5732, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3d(Location, X, Y, Z) -> 'ok' when Location :: integer(),X :: float(),Y :: float(),Z :: float().
uniform3d(Location,X,Y,Z) ->
- cast(5732, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5733, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4d(Location, X, Y, Z, W) -> 'ok' when Location :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
uniform4d(Location,X,Y,Z,W) ->
- cast(5733, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5734, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1dv(Location, Value) -> 'ok' when Location :: integer(),Value :: [float()].
uniform1dv(Location,Value) ->
- cast(5734, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5735, <<Location:?GLint,0:32,ValueLen:?GLuint,0:32,
(<< <<C:?GLdouble>> || C <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2dv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float()}].
uniform2dv(Location,Value) ->
- cast(5735, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5736, <<Location:?GLint,0:32,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3dv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float(),float()}].
uniform3dv(Location,Value) ->
- cast(5736, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5737, <<Location:?GLint,0:32,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4dv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float(),float(),float()}].
uniform4dv(Location,Value) ->
- cast(5737, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5738, <<Location:?GLint,0:32,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float()}].
uniformMatrix2dv(Location,Transpose,Value) ->
- cast(5738, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5739, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix3dv(Location,Transpose,Value) ->
- cast(5739, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5740, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4dv(Location,Transpose,Value) ->
- cast(5740, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5741, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble,V13:?GLdouble,V14:?GLdouble,V15:?GLdouble,V16:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2x3dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
uniformMatrix2x3dv(Location,Transpose,Value) ->
- cast(5741, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5742, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2x4dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix2x4dv(Location,Transpose,Value) ->
- cast(5742, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5743, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3x2dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
uniformMatrix3x2dv(Location,Transpose,Value) ->
- cast(5743, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5744, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3x4dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix3x4dv(Location,Transpose,Value) ->
- cast(5744, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5745, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4x2dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4x2dv(Location,Transpose,Value) ->
- cast(5745, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5746, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4x3dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4x3dv(Location,Transpose,Value) ->
- cast(5746, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5747, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
%% @doc
%% See {@link getUniformfv/2}
-spec getUniformdv(Program, Location) -> matrix() when Program :: integer(),Location :: integer().
getUniformdv(Program,Location) ->
- call(5747, <<Program:?GLuint,Location:?GLint>>).
+ call(5748, <<Program:?GLuint,Location:?GLint>>).
%% @doc Retrieve the location of a subroutine uniform of a given shader stage within a program
%%
@@ -15055,7 +15153,8 @@ getUniformdv(Program,Location) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSubroutineUniformLocation.xml">external</a> documentation.
-spec getSubroutineUniformLocation(Program, Shadertype, Name) -> integer() when Program :: integer(),Shadertype :: enum(),Name :: string().
getSubroutineUniformLocation(Program,Shadertype,Name) ->
- call(5748, <<Program:?GLuint,Shadertype:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5749, <<Program:?GLuint,Shadertype:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc Retrieve the index of a subroutine uniform of a given shader stage within a program
%%
@@ -15075,7 +15174,8 @@ getSubroutineUniformLocation(Program,Shadertype,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSubroutineIndex.xml">external</a> documentation.
-spec getSubroutineIndex(Program, Shadertype, Name) -> integer() when Program :: integer(),Shadertype :: enum(),Name :: string().
getSubroutineIndex(Program,Shadertype,Name) ->
- call(5749, <<Program:?GLuint,Shadertype:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5750, <<Program:?GLuint,Shadertype:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc Query the name of an active shader subroutine uniform
%%
@@ -15096,7 +15196,7 @@ getSubroutineIndex(Program,Shadertype,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveSubroutineUniformName.xml">external</a> documentation.
-spec getActiveSubroutineUniformName(Program, Shadertype, Index, Bufsize) -> string() when Program :: integer(),Shadertype :: enum(),Index :: integer(),Bufsize :: integer().
getActiveSubroutineUniformName(Program,Shadertype,Index,Bufsize) ->
- call(5750, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>).
+ call(5751, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>).
%% @doc Query the name of an active shader subroutine
%%
@@ -15114,7 +15214,7 @@ getActiveSubroutineUniformName(Program,Shadertype,Index,Bufsize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveSubroutineName.xml">external</a> documentation.
-spec getActiveSubroutineName(Program, Shadertype, Index, Bufsize) -> string() when Program :: integer(),Shadertype :: enum(),Index :: integer(),Bufsize :: integer().
getActiveSubroutineName(Program,Shadertype,Index,Bufsize) ->
- call(5751, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>).
+ call(5752, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>).
%% @doc Load active subroutine uniforms
%%
@@ -15128,8 +15228,9 @@ getActiveSubroutineName(Program,Shadertype,Index,Bufsize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformSubroutines.xml">external</a> documentation.
-spec uniformSubroutinesuiv(Shadertype, Indices) -> 'ok' when Shadertype :: enum(),Indices :: [integer()].
uniformSubroutinesuiv(Shadertype,Indices) ->
- cast(5752, <<Shadertype:?GLenum,(length(Indices)):?GLuint,
- (<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((length(Indices)) rem 2)*32)>>).
+ IndicesLen = length(Indices),
+ cast(5753, <<Shadertype:?GLenum,IndicesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((IndicesLen) rem 2)*32)>>).
%% @doc Retrieve the value of a subroutine uniform of a given shader stage of the current program
%%
@@ -15142,7 +15243,7 @@ uniformSubroutinesuiv(Shadertype,Indices) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformSubroutine.xml">external</a> documentation.
-spec getUniformSubroutineuiv(Shadertype, Location) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} when Shadertype :: enum(),Location :: integer().
getUniformSubroutineuiv(Shadertype,Location) ->
- call(5753, <<Shadertype:?GLenum,Location:?GLint>>).
+ call(5754, <<Shadertype:?GLenum,Location:?GLint>>).
%% @doc Retrieve properties of a program object corresponding to a specified shader stage
%%
@@ -15174,7 +15275,7 @@ getUniformSubroutineuiv(Shadertype,Location) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramStage.xml">external</a> documentation.
-spec getProgramStageiv(Program, Shadertype, Pname) -> integer() when Program :: integer(),Shadertype :: enum(),Pname :: enum().
getProgramStageiv(Program,Shadertype,Pname) ->
- call(5754, <<Program:?GLuint,Shadertype:?GLenum,Pname:?GLenum>>).
+ call(5755, <<Program:?GLuint,Shadertype:?GLenum,Pname:?GLenum>>).
%% @doc Specifies the parameters for patch primitives
%%
@@ -15201,14 +15302,15 @@ getProgramStageiv(Program,Shadertype,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPatchParameter.xml">external</a> documentation.
-spec patchParameteri(Pname, Value) -> 'ok' when Pname :: enum(),Value :: integer().
patchParameteri(Pname,Value) ->
- cast(5755, <<Pname:?GLenum,Value:?GLint>>).
+ cast(5756, <<Pname:?GLenum,Value:?GLint>>).
%% @doc
%% See {@link patchParameteri/2}
-spec patchParameterfv(Pname, Values) -> 'ok' when Pname :: enum(),Values :: [float()].
patchParameterfv(Pname,Values) ->
- cast(5756, <<Pname:?GLenum,(length(Values)):?GLuint,
- (<< <<C:?GLfloat>> || C <- Values>>)/binary,0:(((length(Values)) rem 2)*32)>>).
+ ValuesLen = length(Values),
+ cast(5757, <<Pname:?GLenum,ValuesLen:?GLuint,
+ (<< <<C:?GLfloat>> || C <- Values>>)/binary,0:(((ValuesLen) rem 2)*32)>>).
%% @doc Bind a transform feedback object
%%
@@ -15231,7 +15333,7 @@ patchParameterfv(Pname,Values) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindTransformFeedback.xml">external</a> documentation.
-spec bindTransformFeedback(Target, Id) -> 'ok' when Target :: enum(),Id :: integer().
bindTransformFeedback(Target,Id) ->
- cast(5757, <<Target:?GLenum,Id:?GLuint>>).
+ cast(5758, <<Target:?GLenum,Id:?GLuint>>).
%% @doc Delete transform feedback objects
%%
@@ -15244,8 +15346,9 @@ bindTransformFeedback(Target,Id) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteTransformFeedbacks.xml">external</a> documentation.
-spec deleteTransformFeedbacks(Ids) -> 'ok' when Ids :: [integer()].
deleteTransformFeedbacks(Ids) ->
- cast(5758, <<(length(Ids)):?GLuint,
- (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+length(Ids)) rem 2)*32)>>).
+ IdsLen = length(Ids),
+ cast(5759, <<IdsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+IdsLen) rem 2)*32)>>).
%% @doc Reserve transform feedback object names
%%
@@ -15256,7 +15359,7 @@ deleteTransformFeedbacks(Ids) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenTransformFeedbacks.xml">external</a> documentation.
-spec genTransformFeedbacks(N) -> [integer()] when N :: integer().
genTransformFeedbacks(N) ->
- call(5759, <<N:?GLsizei>>).
+ call(5760, <<N:?GLsizei>>).
%% @doc Determine if a name corresponds to a transform feedback object
%%
@@ -15271,7 +15374,7 @@ genTransformFeedbacks(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsTransformFeedback.xml">external</a> documentation.
-spec isTransformFeedback(Id) -> 0|1 when Id :: integer().
isTransformFeedback(Id) ->
- call(5760, <<Id:?GLuint>>).
+ call(5761, <<Id:?GLuint>>).
%% @doc Pause transform feedback operations
%%
@@ -15284,7 +15387,7 @@ isTransformFeedback(Id) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPauseTransformFeedback.xml">external</a> documentation.
-spec pauseTransformFeedback() -> 'ok'.
pauseTransformFeedback() ->
- cast(5761, <<>>).
+ cast(5762, <<>>).
%% @doc Resume transform feedback operations
%%
@@ -15297,7 +15400,7 @@ pauseTransformFeedback() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glResumeTransformFeedback.xml">external</a> documentation.
-spec resumeTransformFeedback() -> 'ok'.
resumeTransformFeedback() ->
- cast(5762, <<>>).
+ cast(5763, <<>>).
%% @doc Render primitives using a count derived from a transform feedback object
%%
@@ -15311,7 +15414,7 @@ resumeTransformFeedback() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedback.xml">external</a> documentation.
-spec drawTransformFeedback(Mode, Id) -> 'ok' when Mode :: enum(),Id :: integer().
drawTransformFeedback(Mode,Id) ->
- cast(5763, <<Mode:?GLenum,Id:?GLuint>>).
+ cast(5764, <<Mode:?GLenum,Id:?GLuint>>).
%% @doc Render primitives using a count derived from a specifed stream of a transform feedback object
%%
@@ -15329,14 +15432,14 @@ drawTransformFeedback(Mode,Id) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedbackStream.xml">external</a> documentation.
-spec drawTransformFeedbackStream(Mode, Id, Stream) -> 'ok' when Mode :: enum(),Id :: integer(),Stream :: integer().
drawTransformFeedbackStream(Mode,Id,Stream) ->
- cast(5764, <<Mode:?GLenum,Id:?GLuint,Stream:?GLuint>>).
+ cast(5765, <<Mode:?GLenum,Id:?GLuint,Stream:?GLuint>>).
%% @doc glBeginQueryIndexe
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginQueryIndexe.xml">external</a> documentation.
-spec beginQueryIndexed(Target, Index, Id) -> 'ok' when Target :: enum(),Index :: integer(),Id :: integer().
beginQueryIndexed(Target,Index,Id) ->
- cast(5765, <<Target:?GLenum,Index:?GLuint,Id:?GLuint>>).
+ cast(5766, <<Target:?GLenum,Index:?GLuint,Id:?GLuint>>).
%% @doc Delimit the boundaries of a query object on an indexed target
%%
@@ -15413,7 +15516,7 @@ beginQueryIndexed(Target,Index,Id) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginQueryIndexed.xml">external</a> documentation.
-spec endQueryIndexed(Target, Index) -> 'ok' when Target :: enum(),Index :: integer().
endQueryIndexed(Target,Index) ->
- cast(5766, <<Target:?GLenum,Index:?GLuint>>).
+ cast(5767, <<Target:?GLenum,Index:?GLuint>>).
%% @doc Return parameters of an indexed query object target
%%
@@ -15431,7 +15534,7 @@ endQueryIndexed(Target,Index) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryIndexed.xml">external</a> documentation.
-spec getQueryIndexediv(Target, Index, Pname) -> integer() when Target :: enum(),Index :: integer(),Pname :: enum().
getQueryIndexediv(Target,Index,Pname) ->
- call(5767, <<Target:?GLenum,Index:?GLuint,Pname:?GLenum>>).
+ call(5768, <<Target:?GLenum,Index:?GLuint,Pname:?GLenum>>).
%% @doc Release resources consumed by the implementation's shader compiler
%%
@@ -15443,7 +15546,7 @@ getQueryIndexediv(Target,Index,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glReleaseShaderCompiler.xml">external</a> documentation.
-spec releaseShaderCompiler() -> 'ok'.
releaseShaderCompiler() ->
- cast(5768, <<>>).
+ cast(5769, <<>>).
%% @doc Load pre-compiled shader binaries
%%
@@ -15465,9 +15568,10 @@ releaseShaderCompiler() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderBinary.xml">external</a> documentation.
-spec shaderBinary(Shaders, Binaryformat, Binary) -> 'ok' when Shaders :: [integer()],Binaryformat :: enum(),Binary :: binary().
shaderBinary(Shaders,Binaryformat,Binary) ->
+ ShadersLen = length(Shaders),
send_bin(Binary),
- cast(5769, <<(length(Shaders)):?GLuint,
- (<< <<C:?GLuint>> || C <- Shaders>>)/binary,0:(((1+length(Shaders)) rem 2)*32),Binaryformat:?GLenum>>).
+ cast(5770, <<ShadersLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Shaders>>)/binary,0:(((1+ShadersLen) rem 2)*32),Binaryformat:?GLenum>>).
%% @doc Retrieve the range and precision for numeric formats supported by the shader compiler
%%
@@ -15492,20 +15596,20 @@ shaderBinary(Shaders,Binaryformat,Binary) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderPrecisionFormat.xml">external</a> documentation.
-spec getShaderPrecisionFormat(Shadertype, Precisiontype) -> {Range :: {integer(),integer()},Precision :: integer()} when Shadertype :: enum(),Precisiontype :: enum().
getShaderPrecisionFormat(Shadertype,Precisiontype) ->
- call(5770, <<Shadertype:?GLenum,Precisiontype:?GLenum>>).
+ call(5771, <<Shadertype:?GLenum,Precisiontype:?GLenum>>).
%% @doc
%% See {@link depthRange/2}
-spec depthRangef(N, F) -> 'ok' when N :: clamp(),F :: clamp().
depthRangef(N,F) ->
- cast(5771, <<N:?GLclampf,F:?GLclampf>>).
+ cast(5772, <<N:?GLclampf,F:?GLclampf>>).
%% @doc glClearDepthf
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearDepthf.xml">external</a> documentation.
-spec clearDepthf(D) -> 'ok' when D :: clamp().
clearDepthf(D) ->
- cast(5772, <<D:?GLclampf>>).
+ cast(5773, <<D:?GLclampf>>).
%% @doc Return a binary representation of a program object's compiled and linked executable source
%%
@@ -15526,7 +15630,7 @@ clearDepthf(D) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramBinary.xml">external</a> documentation.
-spec getProgramBinary(Program, BufSize) -> {BinaryFormat :: enum(),Binary :: binary()} when Program :: integer(),BufSize :: integer().
getProgramBinary(Program,BufSize) ->
- call(5773, <<Program:?GLuint,BufSize:?GLsizei>>).
+ call(5774, <<Program:?GLuint,BufSize:?GLsizei>>).
%% @doc Load a program object with a program binary
%%
@@ -15554,7 +15658,7 @@ getProgramBinary(Program,BufSize) ->
-spec programBinary(Program, BinaryFormat, Binary) -> 'ok' when Program :: integer(),BinaryFormat :: enum(),Binary :: binary().
programBinary(Program,BinaryFormat,Binary) ->
send_bin(Binary),
- cast(5774, <<Program:?GLuint,BinaryFormat:?GLenum>>).
+ cast(5775, <<Program:?GLuint,BinaryFormat:?GLenum>>).
%% @doc Specify a parameter for a program object
%%
@@ -15579,7 +15683,7 @@ programBinary(Program,BinaryFormat,Binary) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramParameter.xml">external</a> documentation.
-spec programParameteri(Program, Pname, Value) -> 'ok' when Program :: integer(),Pname :: enum(),Value :: integer().
programParameteri(Program,Pname,Value) ->
- cast(5775, <<Program:?GLuint,Pname:?GLenum,Value:?GLint>>).
+ cast(5776, <<Program:?GLuint,Pname:?GLenum,Value:?GLint>>).
%% @doc Bind stages of a program object to a program pipeline
%%
@@ -15604,7 +15708,7 @@ programParameteri(Program,Pname,Value) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgramStages.xml">external</a> documentation.
-spec useProgramStages(Pipeline, Stages, Program) -> 'ok' when Pipeline :: integer(),Stages :: integer(),Program :: integer().
useProgramStages(Pipeline,Stages,Program) ->
- cast(5776, <<Pipeline:?GLuint,Stages:?GLbitfield,Program:?GLuint>>).
+ cast(5777, <<Pipeline:?GLuint,Stages:?GLbitfield,Program:?GLuint>>).
%% @doc Set the active program object for a program pipeline object
%%
@@ -15616,15 +15720,16 @@ useProgramStages(Pipeline,Stages,Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glActiveShaderProgram.xml">external</a> documentation.
-spec activeShaderProgram(Pipeline, Program) -> 'ok' when Pipeline :: integer(),Program :: integer().
activeShaderProgram(Pipeline,Program) ->
- cast(5777, <<Pipeline:?GLuint,Program:?GLuint>>).
+ cast(5778, <<Pipeline:?GLuint,Program:?GLuint>>).
%% @doc glCreateShaderProgramv
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShaderProgramv.xml">external</a> documentation.
-spec createShaderProgramv(Type, Strings) -> integer() when Type :: enum(),Strings :: iolist().
createShaderProgramv(Type,Strings) ->
- StringsTemp = list_to_binary([[Str|[0]] || Str <- Strings ]),
- call(5778, <<Type:?GLenum,(length(Strings)):?GLuint,(size(StringsTemp)):?GLuint,(StringsTemp)/binary,0:((8-((size(StringsTemp)+0) rem 8)) rem 8)>>).
+ StringsTemp = list_to_binary([[Str|[0]] || Str <- Strings ]),
+ StringsLen = length(Strings),
+ call(5779, <<Type:?GLenum,StringsLen:?GLuint,(size(StringsTemp)):?GLuint,(StringsTemp)/binary,0:((8-((size(StringsTemp)+0) rem 8)) rem 8)>>).
%% @doc Bind a program pipeline to the current context
%%
@@ -15646,7 +15751,7 @@ createShaderProgramv(Type,Strings) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindProgramPipeline.xml">external</a> documentation.
-spec bindProgramPipeline(Pipeline) -> 'ok' when Pipeline :: integer().
bindProgramPipeline(Pipeline) ->
- cast(5779, <<Pipeline:?GLuint>>).
+ cast(5780, <<Pipeline:?GLuint>>).
%% @doc Delete program pipeline objects
%%
@@ -15660,8 +15765,9 @@ bindProgramPipeline(Pipeline) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgramPipelines.xml">external</a> documentation.
-spec deleteProgramPipelines(Pipelines) -> 'ok' when Pipelines :: [integer()].
deleteProgramPipelines(Pipelines) ->
- cast(5780, <<(length(Pipelines)):?GLuint,
- (<< <<C:?GLuint>> || C <- Pipelines>>)/binary,0:(((1+length(Pipelines)) rem 2)*32)>>).
+ PipelinesLen = length(Pipelines),
+ cast(5781, <<PipelinesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Pipelines>>)/binary,0:(((1+PipelinesLen) rem 2)*32)>>).
%% @doc Reserve program pipeline object names
%%
@@ -15672,7 +15778,7 @@ deleteProgramPipelines(Pipelines) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenProgramPipelines.xml">external</a> documentation.
-spec genProgramPipelines(N) -> [integer()] when N :: integer().
genProgramPipelines(N) ->
- call(5781, <<N:?GLsizei>>).
+ call(5782, <<N:?GLsizei>>).
%% @doc Determine if a name corresponds to a program pipeline object
%%
@@ -15687,7 +15793,7 @@ genProgramPipelines(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsProgramPipeline.xml">external</a> documentation.
-spec isProgramPipeline(Pipeline) -> 0|1 when Pipeline :: integer().
isProgramPipeline(Pipeline) ->
- call(5782, <<Pipeline:?GLuint>>).
+ call(5783, <<Pipeline:?GLuint>>).
%% @doc Retrieve properties of a program pipeline object
%%
@@ -15725,7 +15831,7 @@ isProgramPipeline(Pipeline) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramPipeline.xml">external</a> documentation.
-spec getProgramPipelineiv(Pipeline, Pname) -> integer() when Pipeline :: integer(),Pname :: enum().
getProgramPipelineiv(Pipeline,Pname) ->
- call(5783, <<Pipeline:?GLuint,Pname:?GLenum>>).
+ call(5784, <<Pipeline:?GLuint,Pname:?GLenum>>).
%% @doc Specify the value of a uniform variable for a specified program object
%%
@@ -15792,334 +15898,368 @@ getProgramPipelineiv(Pipeline,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
-spec programUniform1i(Program, Location, V0) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer().
programUniform1i(Program,Location,V0) ->
- cast(5784, <<Program:?GLuint,Location:?GLint,V0:?GLint>>).
+ cast(5785, <<Program:?GLuint,Location:?GLint,V0:?GLint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1iv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [integer()].
programUniform1iv(Program,Location,Value) ->
- cast(5785, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
- (<< <<C:?GLint>> || C <- Value>>)/binary,0:(((1+length(Value)) rem 2)*32)>>).
+ ValueLen = length(Value),
+ cast(5786, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLint>> || C <- Value>>)/binary,0:(((1+ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1f(Program, Location, V0) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float().
programUniform1f(Program,Location,V0) ->
- cast(5786, <<Program:?GLuint,Location:?GLint,V0:?GLfloat>>).
+ cast(5787, <<Program:?GLuint,Location:?GLint,V0:?GLfloat>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1fv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [float()].
programUniform1fv(Program,Location,Value) ->
- cast(5787, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
- (<< <<C:?GLfloat>> || C <- Value>>)/binary,0:(((1+length(Value)) rem 2)*32)>>).
+ ValueLen = length(Value),
+ cast(5788, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLfloat>> || C <- Value>>)/binary,0:(((1+ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1d(Program, Location, V0) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float().
programUniform1d(Program,Location,V0) ->
- cast(5788, <<Program:?GLuint,Location:?GLint,V0:?GLdouble>>).
+ cast(5789, <<Program:?GLuint,Location:?GLint,V0:?GLdouble>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1dv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [float()].
programUniform1dv(Program,Location,Value) ->
- cast(5789, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5790, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,0:32,
(<< <<C:?GLdouble>> || C <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1ui(Program, Location, V0) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer().
programUniform1ui(Program,Location,V0) ->
- cast(5790, <<Program:?GLuint,Location:?GLint,V0:?GLuint>>).
+ cast(5791, <<Program:?GLuint,Location:?GLint,V0:?GLuint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1uiv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [integer()].
programUniform1uiv(Program,Location,Value) ->
- cast(5791, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
- (<< <<C:?GLuint>> || C <- Value>>)/binary,0:(((1+length(Value)) rem 2)*32)>>).
+ ValueLen = length(Value),
+ cast(5792, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Value>>)/binary,0:(((1+ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2i(Program, Location, V0, V1) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer().
programUniform2i(Program,Location,V0,V1) ->
- cast(5792, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint>>).
+ cast(5793, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2iv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer()}].
programUniform2iv(Program,Location,Value) ->
- cast(5793, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5794, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2f(Program, Location, V0, V1) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float().
programUniform2f(Program,Location,V0,V1) ->
- cast(5794, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat>>).
+ cast(5795, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2fv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float()}].
programUniform2fv(Program,Location,Value) ->
- cast(5795, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5796, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2d(Program, Location, V0, V1) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float().
programUniform2d(Program,Location,V0,V1) ->
- cast(5796, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble>>).
+ cast(5797, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2dv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float()}].
programUniform2dv(Program,Location,Value) ->
- cast(5797, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5798, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2ui(Program, Location, V0, V1) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer().
programUniform2ui(Program,Location,V0,V1) ->
- cast(5798, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint>>).
+ cast(5799, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2uiv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer()}].
programUniform2uiv(Program,Location,Value) ->
- cast(5799, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5800, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3i(Program, Location, V0, V1, V2) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer().
programUniform3i(Program,Location,V0,V1,V2) ->
- cast(5800, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>).
+ cast(5801, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3iv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer(),integer()}].
programUniform3iv(Program,Location,Value) ->
- cast(5801, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5802, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3f(Program, Location, V0, V1, V2) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float().
programUniform3f(Program,Location,V0,V1,V2) ->
- cast(5802, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
+ cast(5803, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3fv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float(),float()}].
programUniform3fv(Program,Location,Value) ->
- cast(5803, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5804, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3d(Program, Location, V0, V1, V2) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float().
programUniform3d(Program,Location,V0,V1,V2) ->
- cast(5804, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble>>).
+ cast(5805, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3dv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float(),float()}].
programUniform3dv(Program,Location,Value) ->
- cast(5805, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5806, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3ui(Program, Location, V0, V1, V2) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer().
programUniform3ui(Program,Location,V0,V1,V2) ->
- cast(5806, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>).
+ cast(5807, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3uiv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer(),integer()}].
programUniform3uiv(Program,Location,Value) ->
- cast(5807, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5808, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4i(Program, Location, V0, V1, V2, V3) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer(),V3 :: integer().
programUniform4i(Program,Location,V0,V1,V2,V3) ->
- cast(5808, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>).
+ cast(5809, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4iv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer(),integer(),integer()}].
programUniform4iv(Program,Location,Value) ->
- cast(5809, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5810, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4f(Program, Location, V0, V1, V2, V3) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float(),V3 :: float().
programUniform4f(Program,Location,V0,V1,V2,V3) ->
- cast(5810, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>).
+ cast(5811, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4fv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float(),float(),float()}].
programUniform4fv(Program,Location,Value) ->
- cast(5811, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5812, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4d(Program, Location, V0, V1, V2, V3) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float(),V3 :: float().
programUniform4d(Program,Location,V0,V1,V2,V3) ->
- cast(5812, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>>).
+ cast(5813, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4dv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float(),float(),float()}].
programUniform4dv(Program,Location,Value) ->
- cast(5813, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5814, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4ui(Program, Location, V0, V1, V2, V3) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer(),V3 :: integer().
programUniform4ui(Program,Location,V0,V1,V2,V3) ->
- cast(5814, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>).
+ cast(5815, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4uiv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer(),integer(),integer()}].
programUniform4uiv(Program,Location,Value) ->
- cast(5815, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5816, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float()}].
programUniformMatrix2fv(Program,Location,Transpose,Value) ->
- cast(5816, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5817, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix3fv(Program,Location,Transpose,Value) ->
- cast(5817, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5818, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4fv(Program,Location,Transpose,Value) ->
- cast(5818, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5819, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat,V13:?GLfloat,V14:?GLfloat,V15:?GLfloat,V16:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float()}].
programUniformMatrix2dv(Program,Location,Transpose,Value) ->
- cast(5819, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5820, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix3dv(Program,Location,Transpose,Value) ->
- cast(5820, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5821, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4dv(Program,Location,Transpose,Value) ->
- cast(5821, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5822, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble,V13:?GLdouble,V14:?GLdouble,V15:?GLdouble,V16:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2x3fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
programUniformMatrix2x3fv(Program,Location,Transpose,Value) ->
- cast(5822, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5823, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3x2fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
programUniformMatrix3x2fv(Program,Location,Transpose,Value) ->
- cast(5823, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5824, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2x4fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix2x4fv(Program,Location,Transpose,Value) ->
- cast(5824, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5825, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4x2fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4x2fv(Program,Location,Transpose,Value) ->
- cast(5825, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5826, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3x4fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix3x4fv(Program,Location,Transpose,Value) ->
- cast(5826, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5827, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4x3fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4x3fv(Program,Location,Transpose,Value) ->
- cast(5827, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5828, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2x3dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
programUniformMatrix2x3dv(Program,Location,Transpose,Value) ->
- cast(5828, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5829, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3x2dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
programUniformMatrix3x2dv(Program,Location,Transpose,Value) ->
- cast(5829, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5830, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2x4dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix2x4dv(Program,Location,Transpose,Value) ->
- cast(5830, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5831, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4x2dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4x2dv(Program,Location,Transpose,Value) ->
- cast(5831, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5832, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3x4dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix3x4dv(Program,Location,Transpose,Value) ->
- cast(5832, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5833, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4x3dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4x3dv(Program,Location,Transpose,Value) ->
- cast(5833, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5834, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
%% @doc Validate a program pipeline object against current GL state
@@ -16140,7 +16280,7 @@ programUniformMatrix4x3dv(Program,Location,Transpose,Value) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgramPipeline.xml">external</a> documentation.
-spec validateProgramPipeline(Pipeline) -> 'ok' when Pipeline :: integer().
validateProgramPipeline(Pipeline) ->
- cast(5834, <<Pipeline:?GLuint>>).
+ cast(5835, <<Pipeline:?GLuint>>).
%% @doc Retrieve the info log string from a program pipeline object
%%
@@ -16157,35 +16297,35 @@ validateProgramPipeline(Pipeline) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramPipelineInfoLog.xml">external</a> documentation.
-spec getProgramPipelineInfoLog(Pipeline, BufSize) -> string() when Pipeline :: integer(),BufSize :: integer().
getProgramPipelineInfoLog(Pipeline,BufSize) ->
- call(5835, <<Pipeline:?GLuint,BufSize:?GLsizei>>).
+ call(5836, <<Pipeline:?GLuint,BufSize:?GLsizei>>).
%% @doc glVertexAttribL
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
-spec vertexAttribL1d(Index, X) -> 'ok' when Index :: integer(),X :: float().
vertexAttribL1d(Index,X) ->
- cast(5836, <<Index:?GLuint,0:32,X:?GLdouble>>).
+ cast(5837, <<Index:?GLuint,0:32,X:?GLdouble>>).
%% @doc glVertexAttribL
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
-spec vertexAttribL2d(Index, X, Y) -> 'ok' when Index :: integer(),X :: float(),Y :: float().
vertexAttribL2d(Index,X,Y) ->
- cast(5837, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>).
+ cast(5838, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>).
%% @doc glVertexAttribL
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
-spec vertexAttribL3d(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float().
vertexAttribL3d(Index,X,Y,Z) ->
- cast(5838, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5839, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @doc glVertexAttribL
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
-spec vertexAttribL4d(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
vertexAttribL4d(Index,X,Y,Z,W) ->
- cast(5839, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5840, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @equiv vertexAttribL1d(Index,X)
-spec vertexAttribL1dv(Index :: integer(),V) -> 'ok' when V :: {X :: float()}.
@@ -16208,24 +16348,25 @@ vertexAttribL4dv(Index,{X,Y,Z,W}) -> vertexAttribL4d(Index,X,Y,Z,W).
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribLPointer.xml">external</a> documentation.
-spec vertexAttribLPointer(Index, Size, Type, Stride, Pointer) -> 'ok' when Index :: integer(),Size :: integer(),Type :: enum(),Stride :: integer(),Pointer :: offset()|mem().
vertexAttribLPointer(Index,Size,Type,Stride,Pointer) when is_integer(Pointer) ->
- cast(5840, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5841, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
vertexAttribLPointer(Index,Size,Type,Stride,Pointer) ->
send_bin(Pointer),
- cast(5841, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
+ cast(5842, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
%% @doc glGetVertexAttribL
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttribL.xml">external</a> documentation.
-spec getVertexAttribLdv(Index, Pname) -> {float(),float(),float(),float()} when Index :: integer(),Pname :: enum().
getVertexAttribLdv(Index,Pname) ->
- call(5842, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5843, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc glViewportArrayv
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewportArrayv.xml">external</a> documentation.
-spec viewportArrayv(First, V) -> 'ok' when First :: integer(),V :: [{float(),float(),float(),float()}].
viewportArrayv(First,V) ->
- cast(5843, <<First:?GLuint,(length(V)):?GLuint,
+ VLen = length(V),
+ cast(5844, <<First:?GLuint,VLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- V>>)/binary>>).
%% @doc Set a specified viewport
@@ -16265,20 +16406,21 @@ viewportArrayv(First,V) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewportIndexed.xml">external</a> documentation.
-spec viewportIndexedf(Index, X, Y, W, H) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),W :: float(),H :: float().
viewportIndexedf(Index,X,Y,W,H) ->
- cast(5844, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,W:?GLfloat,H:?GLfloat>>).
+ cast(5845, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,W:?GLfloat,H:?GLfloat>>).
%% @doc
%% See {@link viewportIndexedf/5}
-spec viewportIndexedfv(Index, V) -> 'ok' when Index :: integer(),V :: {float(),float(),float(),float()}.
viewportIndexedfv(Index,{V1,V2,V3,V4}) ->
- cast(5845, <<Index:?GLuint,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>>).
+ cast(5846, <<Index:?GLuint,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>>).
%% @doc glScissorArrayv
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorArrayv.xml">external</a> documentation.
-spec scissorArrayv(First, V) -> 'ok' when First :: integer(),V :: [{integer(),integer(),integer(),integer()}].
scissorArrayv(First,V) ->
- cast(5846, <<First:?GLuint,(length(V)):?GLuint,
+ VLen = length(V),
+ cast(5847, <<First:?GLuint,VLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- V>>)/binary>>).
%% @doc glScissorIndexe
@@ -16286,21 +16428,22 @@ scissorArrayv(First,V) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorIndexe.xml">external</a> documentation.
-spec scissorIndexed(Index, Left, Bottom, Width, Height) -> 'ok' when Index :: integer(),Left :: integer(),Bottom :: integer(),Width :: integer(),Height :: integer().
scissorIndexed(Index,Left,Bottom,Width,Height) ->
- cast(5847, <<Index:?GLuint,Left:?GLint,Bottom:?GLint,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5848, <<Index:?GLuint,Left:?GLint,Bottom:?GLint,Width:?GLsizei,Height:?GLsizei>>).
%% @doc glScissorIndexe
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorIndexe.xml">external</a> documentation.
-spec scissorIndexedv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
scissorIndexedv(Index,{V1,V2,V3,V4}) ->
- cast(5848, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+ cast(5849, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
%% @doc glDepthRangeArrayv
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRangeArrayv.xml">external</a> documentation.
-spec depthRangeArrayv(First, V) -> 'ok' when First :: integer(),V :: [{clamp(),clamp()}].
depthRangeArrayv(First,V) ->
- cast(5849, <<First:?GLuint,0:32,(length(V)):?GLuint,0:32,
+ VLen = length(V),
+ cast(5850, <<First:?GLuint,0:32,VLen:?GLuint,0:32,
(<< <<V1:?GLclampd,V2:?GLclampd>> || {V1,V2} <- V>>)/binary>>).
%% @doc glDepthRangeIndexe
@@ -16308,48 +16451,50 @@ depthRangeArrayv(First,V) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRangeIndexe.xml">external</a> documentation.
-spec depthRangeIndexed(Index, N, F) -> 'ok' when Index :: integer(),N :: clamp(),F :: clamp().
depthRangeIndexed(Index,N,F) ->
- cast(5850, <<Index:?GLuint,0:32,N:?GLclampd,F:?GLclampd>>).
+ cast(5851, <<Index:?GLuint,0:32,N:?GLclampd,F:?GLclampd>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getFloati_v(Target, Index) -> [float()] when Target :: enum(),Index :: integer().
getFloati_v(Target,Index) ->
- call(5851, <<Target:?GLenum,Index:?GLuint>>).
+ call(5852, <<Target:?GLenum,Index:?GLuint>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getDoublei_v(Target, Index) -> [float()] when Target :: enum(),Index :: integer().
getDoublei_v(Target,Index) ->
- call(5852, <<Target:?GLenum,Index:?GLuint>>).
+ call(5853, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glDebugMessageControlARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDebugMessageControlARB.xml">external</a> documentation.
-spec debugMessageControlARB(Source, Type, Severity, Ids, Enabled) -> 'ok' when Source :: enum(),Type :: enum(),Severity :: enum(),Ids :: [integer()],Enabled :: 0|1.
debugMessageControlARB(Source,Type,Severity,Ids,Enabled) ->
- cast(5853, <<Source:?GLenum,Type:?GLenum,Severity:?GLenum,(length(Ids)):?GLuint,
- (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((length(Ids)) rem 2)*32),Enabled:?GLboolean>>).
+ IdsLen = length(Ids),
+ cast(5854, <<Source:?GLenum,Type:?GLenum,Severity:?GLenum,IdsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((IdsLen) rem 2)*32),Enabled:?GLboolean>>).
%% @doc glDebugMessageInsertARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDebugMessageInsertARB.xml">external</a> documentation.
-spec debugMessageInsertARB(Source, Type, Id, Severity, Buf) -> 'ok' when Source :: enum(),Type :: enum(),Id :: integer(),Severity :: enum(),Buf :: string().
debugMessageInsertARB(Source,Type,Id,Severity,Buf) ->
- cast(5854, <<Source:?GLenum,Type:?GLenum,Id:?GLuint,Severity:?GLenum,(list_to_binary([Buf|[0]]))/binary,0:((8-((length(Buf)+ 1) rem 8)) rem 8)>>).
+ BufLen = length(Buf),
+ cast(5855, <<Source:?GLenum,Type:?GLenum,Id:?GLuint,Severity:?GLenum,(list_to_binary([Buf|[0]]))/binary,0:((8-((BufLen+ 1) rem 8)) rem 8)>>).
%% @doc glGetDebugMessageLogARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetDebugMessageLogARB.xml">external</a> documentation.
-spec getDebugMessageLogARB(Count, Bufsize) -> {integer(),Sources :: [enum()],Types :: [enum()],Ids :: [integer()],Severities :: [enum()],MessageLog :: [string()]} when Count :: integer(),Bufsize :: integer().
getDebugMessageLogARB(Count,Bufsize) ->
- call(5855, <<Count:?GLuint,Bufsize:?GLsizei>>).
+ call(5856, <<Count:?GLuint,Bufsize:?GLsizei>>).
%% @doc glGetGraphicsResetStatusARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetGraphicsResetStatusARB.xml">external</a> documentation.
-spec getGraphicsResetStatusARB() -> enum().
getGraphicsResetStatusARB() ->
- call(5856, <<>>).
+ call(5857, <<>>).
%% @doc Draw multiple instances of a range of elements with offset applied to instanced attributes
%%
@@ -16372,7 +16517,7 @@ getGraphicsResetStatusARB() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArraysInstancedBaseInstance.xml">external</a> documentation.
-spec drawArraysInstancedBaseInstance(Mode, First, Count, Primcount, Baseinstance) -> 'ok' when Mode :: enum(),First :: integer(),Count :: integer(),Primcount :: integer(),Baseinstance :: integer().
drawArraysInstancedBaseInstance(Mode,First,Count,Primcount,Baseinstance) ->
- cast(5857, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei,Baseinstance:?GLuint>>).
+ cast(5858, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei,Baseinstance:?GLuint>>).
%% @doc Draw multiple instances of a set of elements with offset applied to instanced attributes
%%
@@ -16395,10 +16540,10 @@ drawArraysInstancedBaseInstance(Mode,First,Count,Primcount,Baseinstance) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstancedBaseInstance.xml">external</a> documentation.
-spec drawElementsInstancedBaseInstance(Mode, Count, Type, Indices, Primcount, Baseinstance) -> 'ok' when Mode :: enum(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Primcount :: integer(),Baseinstance :: integer().
drawElementsInstancedBaseInstance(Mode,Count,Type,Indices,Primcount,Baseinstance) when is_integer(Indices) ->
- cast(5858, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Baseinstance:?GLuint>>);
+ cast(5859, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Baseinstance:?GLuint>>);
drawElementsInstancedBaseInstance(Mode,Count,Type,Indices,Primcount,Baseinstance) ->
send_bin(Indices),
- cast(5859, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Baseinstance:?GLuint>>).
+ cast(5860, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Baseinstance:?GLuint>>).
%% @doc Render multiple instances of a set of primitives from array data with a per-element offset
%%
@@ -16419,31 +16564,31 @@ drawElementsInstancedBaseInstance(Mode,Count,Type,Indices,Primcount,Baseinstance
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstancedBaseVertexBaseInstance.xml">external</a> documentation.
-spec drawElementsInstancedBaseVertexBaseInstance(Mode, Count, Type, Indices, Primcount, Basevertex, Baseinstance) -> 'ok' when Mode :: enum(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Primcount :: integer(),Basevertex :: integer(),Baseinstance :: integer().
drawElementsInstancedBaseVertexBaseInstance(Mode,Count,Type,Indices,Primcount,Basevertex,Baseinstance) when is_integer(Indices) ->
- cast(5860, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Basevertex:?GLint,Baseinstance:?GLuint>>);
+ cast(5861, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Basevertex:?GLint,Baseinstance:?GLuint>>);
drawElementsInstancedBaseVertexBaseInstance(Mode,Count,Type,Indices,Primcount,Basevertex,Baseinstance) ->
send_bin(Indices),
- cast(5861, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Basevertex:?GLint,Baseinstance:?GLuint>>).
+ cast(5862, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Basevertex:?GLint,Baseinstance:?GLuint>>).
%% @doc glDrawTransformFeedbackInstance
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedbackInstance.xml">external</a> documentation.
-spec drawTransformFeedbackInstanced(Mode, Id, Primcount) -> 'ok' when Mode :: enum(),Id :: integer(),Primcount :: integer().
drawTransformFeedbackInstanced(Mode,Id,Primcount) ->
- cast(5862, <<Mode:?GLenum,Id:?GLuint,Primcount:?GLsizei>>).
+ cast(5863, <<Mode:?GLenum,Id:?GLuint,Primcount:?GLsizei>>).
%% @doc glDrawTransformFeedbackStreamInstance
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedbackStreamInstance.xml">external</a> documentation.
-spec drawTransformFeedbackStreamInstanced(Mode, Id, Stream, Primcount) -> 'ok' when Mode :: enum(),Id :: integer(),Stream :: integer(),Primcount :: integer().
drawTransformFeedbackStreamInstanced(Mode,Id,Stream,Primcount) ->
- cast(5863, <<Mode:?GLenum,Id:?GLuint,Stream:?GLuint,Primcount:?GLsizei>>).
+ cast(5864, <<Mode:?GLenum,Id:?GLuint,Stream:?GLuint,Primcount:?GLsizei>>).
%% @doc glGetInternalformat
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetInternalformat.xml">external</a> documentation.
-spec getInternalformativ(Target, Internalformat, Pname, BufSize) -> [integer()] when Target :: enum(),Internalformat :: enum(),Pname :: enum(),BufSize :: integer().
getInternalformativ(Target,Internalformat,Pname,BufSize) ->
- call(5864, <<Target:?GLenum,Internalformat:?GLenum,Pname:?GLenum,BufSize:?GLsizei>>).
+ call(5865, <<Target:?GLenum,Internalformat:?GLenum,Pname:?GLenum,BufSize:?GLsizei>>).
%% @doc Bind a level of a texture to an image unit
%%
@@ -16505,7 +16650,7 @@ getInternalformativ(Target,Internalformat,Pname,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindImageTexture.xml">external</a> documentation.
-spec bindImageTexture(Unit, Texture, Level, Layered, Layer, Access, Format) -> 'ok' when Unit :: integer(),Texture :: integer(),Level :: integer(),Layered :: 0|1,Layer :: integer(),Access :: enum(),Format :: enum().
bindImageTexture(Unit,Texture,Level,Layered,Layer,Access,Format) ->
- cast(5865, <<Unit:?GLuint,Texture:?GLuint,Level:?GLint,Layered:?GLboolean,0:24,Layer:?GLint,Access:?GLenum,Format:?GLenum>>).
+ cast(5866, <<Unit:?GLuint,Texture:?GLuint,Level:?GLint,Layered:?GLboolean,0:24,Layer:?GLint,Access:?GLenum,Format:?GLenum>>).
%% @doc Defines a barrier ordering memory transactions
%%
@@ -16632,7 +16777,7 @@ bindImageTexture(Unit,Texture,Level,Layered,Layer,Access,Format) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMemoryBarrier.xml">external</a> documentation.
-spec memoryBarrier(Barriers) -> 'ok' when Barriers :: integer().
memoryBarrier(Barriers) ->
- cast(5866, <<Barriers:?GLbitfield>>).
+ cast(5867, <<Barriers:?GLbitfield>>).
%% @doc Simultaneously specify storage for all levels of a one-dimensional texture
%%
@@ -16665,7 +16810,7 @@ memoryBarrier(Barriers) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexStorage1D.xml">external</a> documentation.
-spec texStorage1D(Target, Levels, Internalformat, Width) -> 'ok' when Target :: enum(),Levels :: integer(),Internalformat :: enum(),Width :: integer().
texStorage1D(Target,Levels,Internalformat,Width) ->
- cast(5867, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei>>).
+ cast(5868, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei>>).
%% @doc Simultaneously specify storage for all levels of a two-dimensional or one-dimensional array texture
%%
@@ -16710,7 +16855,7 @@ texStorage1D(Target,Levels,Internalformat,Width) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexStorage2D.xml">external</a> documentation.
-spec texStorage2D(Target, Levels, Internalformat, Width, Height) -> 'ok' when Target :: enum(),Levels :: integer(),Internalformat :: enum(),Width :: integer(),Height :: integer().
texStorage2D(Target,Levels,Internalformat,Width,Height) ->
- cast(5868, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5869, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
%% @doc Simultaneously specify storage for all levels of a three-dimensional, two-dimensional array or cube-map array texture
%%
@@ -16753,19 +16898,19 @@ texStorage2D(Target,Levels,Internalformat,Width,Height) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexStorage3D.xml">external</a> documentation.
-spec texStorage3D(Target, Levels, Internalformat, Width, Height, Depth) -> 'ok' when Target :: enum(),Levels :: integer(),Internalformat :: enum(),Width :: integer(),Height :: integer(),Depth :: integer().
texStorage3D(Target,Levels,Internalformat,Width,Height,Depth) ->
- cast(5869, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei>>).
+ cast(5870, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei>>).
%% @doc glDepthBoundsEXT
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthBoundsEXT.xml">external</a> documentation.
-spec depthBoundsEXT(Zmin, Zmax) -> 'ok' when Zmin :: clamp(),Zmax :: clamp().
depthBoundsEXT(Zmin,Zmax) ->
- cast(5870, <<Zmin:?GLclampd,Zmax:?GLclampd>>).
+ cast(5871, <<Zmin:?GLclampd,Zmax:?GLclampd>>).
%% @doc glStencilClearTagEXT
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilClearTagEXT.xml">external</a> documentation.
-spec stencilClearTagEXT(StencilTagBits, StencilClearTag) -> 'ok' when StencilTagBits :: integer(),StencilClearTag :: integer().
stencilClearTagEXT(StencilTagBits,StencilClearTag) ->
- cast(5871, <<StencilTagBits:?GLsizei,StencilClearTag:?GLuint>>).
+ cast(5872, <<StencilTagBits:?GLsizei,StencilClearTag:?GLuint>>).
diff --git a/lib/wx/src/gen/glu.erl b/lib/wx/src/gen/glu.erl
index 47d9a83999..f641f41262 100644
--- a/lib/wx/src/gen/glu.erl
+++ b/lib/wx/src/gen/glu.erl
@@ -334,7 +334,9 @@ build3DMipmaps(Target,InternalFormat,Width,Height,Depth,Format,Type,Data) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluCheckExtension.xml">external</a> documentation.
-spec checkExtension(ExtName, ExtString) -> 0|1 when ExtName :: string(),ExtString :: string().
checkExtension(ExtName,ExtString) ->
- call(5016, <<(list_to_binary([ExtName|[0]]))/binary,0:((8-((length(ExtName)+ 1) rem 8)) rem 8),(list_to_binary([ExtString|[0]]))/binary,0:((8-((length(ExtString)+ 1) rem 8)) rem 8)>>).
+ ExtNameLen = length(ExtName),
+ ExtStringLen = length(ExtString),
+ call(5016, <<(list_to_binary([ExtName|[0]]))/binary,0:((8-((ExtNameLen+ 1) rem 8)) rem 8),(list_to_binary([ExtString|[0]]))/binary,0:((8-((ExtStringLen+ 1) rem 8)) rem 8)>>).
%% @doc Draw a cylinder
%%
diff --git a/lib/wx/src/gen/wxArtProvider.erl b/lib/wx/src/gen/wxArtProvider.erl
index da220a90c8..b52c141b1f 100644
--- a/lib/wx/src/gen/wxArtProvider.erl
+++ b/lib/wx/src/gen/wxArtProvider.erl
@@ -40,7 +40,7 @@ parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
Id::unicode:chardata().
getBitmap(Id)
- when is_list(Id) ->
+ when ?is_chardata(Id) ->
getBitmap(Id, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxartprovider.html#wxartprovidergetbitmap">external documentation</a>.
@@ -49,7 +49,7 @@ getBitmap(Id)
Option :: {'client', unicode:chardata()}
| {'size', {W::integer(), H::integer()}}.
getBitmap(Id, Options)
- when is_list(Id),is_list(Options) ->
+ when ?is_chardata(Id),is_list(Options) ->
Id_UC = unicode:characters_to_binary([Id,0]),
MOpts = fun({client, Client}, Acc) -> Client_UC = unicode:characters_to_binary([Client, $_, $C,0]),[<<1:32/?UI,(byte_size(Client_UC)):32/?UI,(Client_UC)/binary, 0:(((8- ((0+byte_size(Client_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
({size, {SizeW,SizeH}}, Acc) -> [<<2:32/?UI,SizeW:32/?UI,SizeH:32/?UI,0:32>>|Acc];
@@ -63,7 +63,7 @@ getBitmap(Id, Options)
Id::unicode:chardata().
getIcon(Id)
- when is_list(Id) ->
+ when ?is_chardata(Id) ->
getIcon(Id, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxartprovider.html#wxartprovidergeticon">external documentation</a>.
@@ -72,7 +72,7 @@ getIcon(Id)
Option :: {'client', unicode:chardata()}
| {'size', {W::integer(), H::integer()}}.
getIcon(Id, Options)
- when is_list(Id),is_list(Options) ->
+ when ?is_chardata(Id),is_list(Options) ->
Id_UC = unicode:characters_to_binary([Id,0]),
MOpts = fun({client, Client}, Acc) -> Client_UC = unicode:characters_to_binary([Client, $_, $C,0]),[<<1:32/?UI,(byte_size(Client_UC)):32/?UI,(Client_UC)/binary, 0:(((8- ((0+byte_size(Client_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
({size, {SizeW,SizeH}}, Acc) -> [<<2:32/?UI,SizeW:32/?UI,SizeH:32/?UI,0:32>>|Acc];
diff --git a/lib/wx/src/gen/wxAuiManager.erl b/lib/wx/src/gen/wxAuiManager.erl
index 37693060e1..a33e5e9a65 100644
--- a/lib/wx/src/gen/wxAuiManager.erl
+++ b/lib/wx/src/gen/wxAuiManager.erl
@@ -177,7 +177,7 @@ getManager(#wx_ref{type=WindowT,ref=WindowRef}) ->
(This, Window) -> wxAuiPaneInfo:wxAuiPaneInfo() when
This::wxAuiManager(), Window::wxWindow:wxWindow().
getPane(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxAuiManager),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxAuiManager_GetPane_1_0,
@@ -223,7 +223,7 @@ insertPane(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef},#
-spec loadPaneInfo(This, Pane_part, Pane) -> 'ok' when
This::wxAuiManager(), Pane_part::unicode:chardata(), Pane::wxAuiPaneInfo:wxAuiPaneInfo().
loadPaneInfo(#wx_ref{type=ThisT,ref=ThisRef},Pane_part,#wx_ref{type=PaneT,ref=PaneRef})
- when is_list(Pane_part) ->
+ when ?is_chardata(Pane_part) ->
?CLASS(ThisT,wxAuiManager),
Pane_part_UC = unicode:characters_to_binary([Pane_part,0]),
?CLASS(PaneT,wxAuiPaneInfo),
@@ -235,7 +235,7 @@ loadPaneInfo(#wx_ref{type=ThisT,ref=ThisRef},Pane_part,#wx_ref{type=PaneT,ref=Pa
This::wxAuiManager(), Perspective::unicode:chardata().
loadPerspective(This,Perspective)
- when is_record(This, wx_ref),is_list(Perspective) ->
+ when is_record(This, wx_ref),?is_chardata(Perspective) ->
loadPerspective(This,Perspective, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauimanager.html#wxauimanagerloadperspective">external documentation</a>.
@@ -243,7 +243,7 @@ loadPerspective(This,Perspective)
This::wxAuiManager(), Perspective::unicode:chardata(),
Option :: {'update', boolean()}.
loadPerspective(#wx_ref{type=ThisT,ref=ThisRef},Perspective, Options)
- when is_list(Perspective),is_list(Options) ->
+ when ?is_chardata(Perspective),is_list(Options) ->
?CLASS(ThisT,wxAuiManager),
Perspective_UC = unicode:characters_to_binary([Perspective,0]),
MOpts = fun({update, Update}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Update)):32/?UI>>|Acc];
diff --git a/lib/wx/src/gen/wxAuiNotebook.erl b/lib/wx/src/gen/wxAuiNotebook.erl
index 42da35e16a..adb90c224f 100644
--- a/lib/wx/src/gen/wxAuiNotebook.erl
+++ b/lib/wx/src/gen/wxAuiNotebook.erl
@@ -42,38 +42,38 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setForegroundColour/2,
- setHelpText/2,setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,
- setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,setPalette/2,
- setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
- setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
- setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
- transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
- validate/1,warpPointer/3]).
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
+ show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
+ update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
-export_type([wxAuiNotebook/0]).
%% @hidden
@@ -121,7 +121,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef}, Options)
This::wxAuiNotebook(), Page::wxWindow:wxWindow(), Caption::unicode:chardata().
addPage(This,Page,Caption)
- when is_record(This, wx_ref),is_record(Page, wx_ref),is_list(Caption) ->
+ when is_record(This, wx_ref),is_record(Page, wx_ref),?is_chardata(Caption) ->
addPage(This,Page,Caption, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauinotebook.html#wxauinotebookaddpage">external documentation</a>.
@@ -130,7 +130,7 @@ addPage(This,Page,Caption)
Option :: {'select', boolean()}
| {'bitmap', wxBitmap:wxBitmap()}.
addPage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PageT,ref=PageRef},Caption, Options)
- when is_list(Caption),is_list(Options) ->
+ when ?is_chardata(Caption),is_list(Options) ->
?CLASS(ThisT,wxAuiNotebook),
?CLASS(PageT,wxWindow),
Caption_UC = unicode:characters_to_binary([Caption,0]),
@@ -243,7 +243,7 @@ getSelection(#wx_ref{type=ThisT,ref=ThisRef}) ->
This::wxAuiNotebook(), Page_idx::integer(), Page::wxWindow:wxWindow(), Caption::unicode:chardata().
insertPage(This,Page_idx,Page,Caption)
- when is_record(This, wx_ref),is_integer(Page_idx),is_record(Page, wx_ref),is_list(Caption) ->
+ when is_record(This, wx_ref),is_integer(Page_idx),is_record(Page, wx_ref),?is_chardata(Caption) ->
insertPage(This,Page_idx,Page,Caption, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxauinotebook.html#wxauinotebookinsertpage">external documentation</a>.
@@ -252,7 +252,7 @@ insertPage(This,Page_idx,Page,Caption)
Option :: {'select', boolean()}
| {'bitmap', wxBitmap:wxBitmap()}.
insertPage(#wx_ref{type=ThisT,ref=ThisRef},Page_idx,#wx_ref{type=PageT,ref=PageRef},Caption, Options)
- when is_integer(Page_idx),is_list(Caption),is_list(Options) ->
+ when is_integer(Page_idx),?is_chardata(Caption),is_list(Options) ->
?CLASS(ThisT,wxAuiNotebook),
?CLASS(PageT,wxWindow),
Caption_UC = unicode:characters_to_binary([Caption,0]),
@@ -304,7 +304,7 @@ setPageBitmap(#wx_ref{type=ThisT,ref=ThisRef},Page,#wx_ref{type=BitmapT,ref=Bitm
-spec setPageText(This, Page, Text) -> boolean() when
This::wxAuiNotebook(), Page::integer(), Text::unicode:chardata().
setPageText(#wx_ref{type=ThisT,ref=ThisRef},Page,Text)
- when is_integer(Page),is_list(Text) ->
+ when is_integer(Page),?is_chardata(Text) ->
?CLASS(ThisT,wxAuiNotebook),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:call(?wxAuiNotebook_SetPageText,
@@ -350,6 +350,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -664,6 +666,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxAuiPaneInfo.erl b/lib/wx/src/gen/wxAuiPaneInfo.erl
index 858da200be..c8273269ac 100644
--- a/lib/wx/src/gen/wxAuiPaneInfo.erl
+++ b/lib/wx/src/gen/wxAuiPaneInfo.erl
@@ -117,7 +117,7 @@ bottomDockable(#wx_ref{type=ThisT,ref=ThisRef}, Options)
-spec caption(This, C) -> wxAuiPaneInfo() when
This::wxAuiPaneInfo(), C::unicode:chardata().
caption(#wx_ref{type=ThisT,ref=ThisRef},C)
- when is_list(C) ->
+ when ?is_chardata(C) ->
?CLASS(ThisT,wxAuiPaneInfo),
C_UC = unicode:characters_to_binary([C,0]),
wxe_util:call(?wxAuiPaneInfo_Caption,
@@ -689,7 +689,7 @@ movable(#wx_ref{type=ThisT,ref=ThisRef}, Options)
-spec name(This, N) -> wxAuiPaneInfo() when
This::wxAuiPaneInfo(), N::unicode:chardata().
name(#wx_ref{type=ThisT,ref=ThisRef},N)
- when is_list(N) ->
+ when ?is_chardata(N) ->
?CLASS(ThisT,wxAuiPaneInfo),
N_UC = unicode:characters_to_binary([N,0]),
wxe_util:call(?wxAuiPaneInfo_Name,
diff --git a/lib/wx/src/gen/wxBitmap.erl b/lib/wx/src/gen/wxBitmap.erl
index e7830dae9b..4a6e308d8d 100644
--- a/lib/wx/src/gen/wxBitmap.erl
+++ b/lib/wx/src/gen/wxBitmap.erl
@@ -56,7 +56,7 @@ new() ->
Image::wxImage:wxImage().
new(Filename)
- when is_list(Filename) ->
+ when ?is_chardata(Filename) ->
new(Filename, []);
new(Image)
@@ -86,7 +86,7 @@ new(Width,Height)
when is_integer(Width),is_integer(Height) ->
new(Width,Height, []);
new(Filename, Options)
- when is_list(Filename),is_list(Options) ->
+ when ?is_chardata(Filename),is_list(Options) ->
Filename_UC = unicode:characters_to_binary([Filename,0]),
MOpts = fun({type, Type}, Acc) -> [<<1:32/?UI,Type:32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
@@ -230,7 +230,7 @@ getSubBitmap(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH})
This::wxBitmap(), Name::unicode:chardata().
loadFile(This,Name)
- when is_record(This, wx_ref),is_list(Name) ->
+ when is_record(This, wx_ref),?is_chardata(Name) ->
loadFile(This,Name, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxbitmap.html#wxbitmaploadfile">external documentation</a>.
@@ -239,7 +239,7 @@ loadFile(This,Name)
This::wxBitmap(), Name::unicode:chardata(),
Option :: {'type', wx:wx_enum()}.
loadFile(#wx_ref{type=ThisT,ref=ThisRef},Name, Options)
- when is_list(Name),is_list(Options) ->
+ when ?is_chardata(Name),is_list(Options) ->
?CLASS(ThisT,wxBitmap),
Name_UC = unicode:characters_to_binary([Name,0]),
MOpts = fun({type, Type}, Acc) -> [<<1:32/?UI,Type:32/?UI>>|Acc];
@@ -261,7 +261,7 @@ ok(#wx_ref{type=ThisT,ref=ThisRef}) ->
This::wxBitmap(), Name::unicode:chardata(), Type::wx:wx_enum().
saveFile(This,Name,Type)
- when is_record(This, wx_ref),is_list(Name),is_integer(Type) ->
+ when is_record(This, wx_ref),?is_chardata(Name),is_integer(Type) ->
saveFile(This,Name,Type, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxbitmap.html#wxbitmapsavefile">external documentation</a>.
@@ -270,7 +270,7 @@ saveFile(This,Name,Type)
This::wxBitmap(), Name::unicode:chardata(), Type::wx:wx_enum(),
Option :: {'palette', wxPalette:wxPalette()}.
saveFile(#wx_ref{type=ThisT,ref=ThisRef},Name,Type, Options)
- when is_list(Name),is_integer(Type),is_list(Options) ->
+ when ?is_chardata(Name),is_integer(Type),is_list(Options) ->
?CLASS(ThisT,wxBitmap),
Name_UC = unicode:characters_to_binary([Name,0]),
MOpts = fun({palette, #wx_ref{type=PaletteT,ref=PaletteRef}}, Acc) -> ?CLASS(PaletteT,wxPalette),[<<1:32/?UI,PaletteRef:32/?UI>>|Acc];
diff --git a/lib/wx/src/gen/wxBitmapButton.erl b/lib/wx/src/gen/wxBitmapButton.erl
index d1d2d037e8..d0a810bdb9 100644
--- a/lib/wx/src/gen/wxBitmapButton.erl
+++ b/lib/wx/src/gen/wxBitmapButton.erl
@@ -41,38 +41,39 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDefault/1,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
- setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
- setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
- setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDefault/1,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,
+ setFocus/1,setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
+ setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,setToolTip/2,
+ setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxBitmapButton/0]).
%% @hidden
@@ -230,6 +231,8 @@ setDefault(This) -> wxButton:setDefault(This).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -546,6 +549,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxButton.erl b/lib/wx/src/gen/wxButton.erl
index 65d45caa13..f8e24beffa 100644
--- a/lib/wx/src/gen/wxButton.erl
+++ b/lib/wx/src/gen/wxButton.erl
@@ -39,30 +39,30 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,setMinSize/2,
- setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
@@ -163,7 +163,7 @@ setDefault(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setLabel(This, Label) -> 'ok' when
This::wxButton(), Label::unicode:chardata().
setLabel(#wx_ref{type=ThisT,ref=ThisRef},Label)
- when is_list(Label) ->
+ when ?is_chardata(Label) ->
?CLASS(ThisT,wxButton),
Label_UC = unicode:characters_to_binary([Label,0]),
wxe_util:cast(?wxButton_SetLabel,
@@ -180,6 +180,8 @@ destroy(Obj=#wx_ref{type=Type}) ->
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -496,6 +498,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxCalendarCtrl.erl b/lib/wx/src/gen/wxCalendarCtrl.erl
index 93fcb61464..bf033e9bc0 100644
--- a/lib/wx/src/gen/wxCalendarCtrl.erl
+++ b/lib/wx/src/gen/wxCalendarCtrl.erl
@@ -43,29 +43,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -364,6 +364,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -680,6 +682,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxCheckBox.erl b/lib/wx/src/gen/wxCheckBox.erl
index 3276add802..5ed49d91b6 100644
--- a/lib/wx/src/gen/wxCheckBox.erl
+++ b/lib/wx/src/gen/wxCheckBox.erl
@@ -40,29 +40,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -92,7 +92,7 @@ new() ->
Parent::wxWindow:wxWindow(), Id::integer(), Label::unicode:chardata().
new(Parent,Id,Label)
- when is_record(Parent, wx_ref),is_integer(Id),is_list(Label) ->
+ when is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Label) ->
new(Parent,Id,Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxcheckbox.html#wxcheckboxwxcheckbox">external documentation</a>.
@@ -103,7 +103,7 @@ new(Parent,Id,Label)
| {'style', integer()}
| {'validator', wx:wx_object()}.
new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
- when is_integer(Id),is_list(Label),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Label),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Label_UC = unicode:characters_to_binary([Label,0]),
MOpts = fun({pos, {PosX,PosY}}, Acc) -> [<<1:32/?UI,PosX:32/?UI,PosY:32/?UI,0:32>>|Acc];
@@ -120,7 +120,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
This::wxCheckBox(), Parent::wxWindow:wxWindow(), Id::integer(), Label::unicode:chardata().
create(This,Parent,Id,Label)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Label) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Label) ->
create(This,Parent,Id,Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxcheckbox.html#wxcheckboxcreate">external documentation</a>.
@@ -131,7 +131,7 @@ create(This,Parent,Id,Label)
| {'style', integer()}
| {'validator', wx:wx_object()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
- when is_integer(Id),is_list(Label),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Label),is_list(Options) ->
?CLASS(ThisT,wxCheckBox),
?CLASS(ParentT,wxWindow),
Label_UC = unicode:characters_to_binary([Label,0]),
@@ -217,6 +217,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -533,6 +535,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxCheckListBox.erl b/lib/wx/src/gen/wxCheckListBox.erl
index 888f29518c..ddef6a29e2 100644
--- a/lib/wx/src/gen/wxCheckListBox.erl
+++ b/lib/wx/src/gen/wxCheckListBox.erl
@@ -41,13 +41,14 @@
clientToScreen/2,clientToScreen/3,close/1,close/2,connect/2,connect/3,
convertDialogToPixels/2,convertPixelsToDialog/2,delete/2,deselect/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findString/2,findString/3,findWindow/2,fit/1,fitInside/1,
- freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
- getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
- getClientData/2,getClientSize/1,getContainingSizer/1,getCount/1,getCursor/1,
- getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ dragAcceptFiles/2,enable/1,enable/2,findString/2,findString/3,findWindow/2,
+ fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
+ getBackgroundStyle/1,getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,
+ getChildren/1,getClientData/2,getClientSize/1,getContainingSizer/1,
+ getContentScaleFactor/1,getCount/1,getCursor/1,getDropTarget/1,getEventHandler/1,
+ getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
+ getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
getSelection/1,getSelections/1,getSize/1,getSizer/1,getString/2,getStringSelection/1,
getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
@@ -222,6 +223,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -538,6 +541,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxChoice.erl b/lib/wx/src/gen/wxChoice.erl
index 1a90b275d1..266a257442 100644
--- a/lib/wx/src/gen/wxChoice.erl
+++ b/lib/wx/src/gen/wxChoice.erl
@@ -40,40 +40,41 @@
centre/1,centre/2,centreOnParent/1,centreOnParent/2,clear/1,clearBackground/1,
clientToScreen/2,clientToScreen/3,close/1,close/2,connect/2,connect/3,
convertDialogToPixels/2,convertPixelsToDialog/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- findString/2,findString/3,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientData/2,getClientSize/1,
- getContainingSizer/1,getCount/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,getMinSize/1,
- getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
- getSelection/1,getSize/1,getSizer/1,getString/2,getStringSelection/1,
- getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
- getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
- hasTransparentBackground/1,hide/1,inheritAttributes/1,initDialog/1,
- insert/3,insert/4,invalidateBestSize/1,isDoubleBuffered/1,isEmpty/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,select/2,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientData/3,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
- setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
- setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
- setSelection/2,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
- setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
- setSizerAndFit/3,setString/3,setStringSelection/2,setThemeEnabled/2,
- setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
- setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
- setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,findString/2,findString/3,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientData/2,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCount/1,getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,
+ getFont/1,getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSelection/1,getSize/1,getSizer/1,
+ getString/2,getStringSelection/1,getTextExtent/2,getTextExtent/3,
+ getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
+ getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
+ hide/1,inheritAttributes/1,initDialog/1,insert/3,insert/4,invalidateBestSize/1,
+ isDoubleBuffered/1,isEmpty/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
+ isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,
+ makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,select/2,setAcceleratorTable/2,
+ setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
+ setClientData/3,setClientSize/2,setClientSize/3,setContainingSizer/2,
+ setCursor/2,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,
+ setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,setId/2,
+ setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSelection/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setString/3,
+ setStringSelection/2,setThemeEnabled/2,setToolTip/2,setTransparent/2,
+ setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
+ setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
+ shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
validate/1,warpPointer/3]).
@@ -237,6 +238,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -553,6 +556,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxChoicebook.erl b/lib/wx/src/gen/wxChoicebook.erl
index 34b62ff75b..c6e0941978 100644
--- a/lib/wx/src/gen/wxChoicebook.erl
+++ b/lib/wx/src/gen/wxChoicebook.erl
@@ -43,29 +43,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -120,7 +120,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options)
This::wxChoicebook(), Page::wxWindow:wxWindow(), Text::unicode:chardata().
addPage(This,Page,Text)
- when is_record(This, wx_ref),is_record(Page, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_record(Page, wx_ref),?is_chardata(Text) ->
addPage(This,Page,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxchoicebook.html#wxchoicebookaddpage">external documentation</a>.
@@ -129,7 +129,7 @@ addPage(This,Page,Text)
Option :: {'bSelect', boolean()}
| {'imageId', integer()}.
addPage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PageT,ref=PageRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+ when ?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxChoicebook),
?CLASS(PageT,wxWindow),
Text_UC = unicode:characters_to_binary([Text,0]),
@@ -296,7 +296,7 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY})
This::wxChoicebook(), N::integer(), Page::wxWindow:wxWindow(), Text::unicode:chardata().
insertPage(This,N,Page,Text)
- when is_record(This, wx_ref),is_integer(N),is_record(Page, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(N),is_record(Page, wx_ref),?is_chardata(Text) ->
insertPage(This,N,Page,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxchoicebook.html#wxchoicebookinsertpage">external documentation</a>.
@@ -305,7 +305,7 @@ insertPage(This,N,Page,Text)
Option :: {'bSelect', boolean()}
| {'imageId', integer()}.
insertPage(#wx_ref{type=ThisT,ref=ThisRef},N,#wx_ref{type=PageT,ref=PageRef},Text, Options)
- when is_integer(N),is_list(Text),is_list(Options) ->
+ when is_integer(N),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxChoicebook),
?CLASS(PageT,wxWindow),
Text_UC = unicode:characters_to_binary([Text,0]),
@@ -347,7 +347,7 @@ setPageImage(#wx_ref{type=ThisT,ref=ThisRef},N,ImageId)
-spec setPageText(This, N, StrText) -> boolean() when
This::wxChoicebook(), N::integer(), StrText::unicode:chardata().
setPageText(#wx_ref{type=ThisT,ref=ThisRef},N,StrText)
- when is_integer(N),is_list(StrText) ->
+ when is_integer(N),?is_chardata(StrText) ->
?CLASS(ThisT,wxChoicebook),
StrText_UC = unicode:characters_to_binary([StrText,0]),
wxe_util:call(?wxChoicebook_SetPageText,
@@ -384,6 +384,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -700,6 +702,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxColourDialog.erl b/lib/wx/src/gen/wxColourDialog.erl
index 9c97434d9a..936c0e5099 100644
--- a/lib/wx/src/gen/wxColourDialog.erl
+++ b/lib/wx/src/gen/wxColourDialog.erl
@@ -40,40 +40,40 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
+ lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
+ requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
@@ -223,6 +223,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -539,6 +541,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxColourPickerCtrl.erl b/lib/wx/src/gen/wxColourPickerCtrl.erl
index 9c987b4dde..c97b194bc8 100644
--- a/lib/wx/src/gen/wxColourPickerCtrl.erl
+++ b/lib/wx/src/gen/wxColourPickerCtrl.erl
@@ -39,17 +39,18 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getInternalMargin/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,
- getParent/1,getPickerCtrlProportion/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
- getSize/1,getSizer/1,getTextCtrl/1,getTextCtrlProportion/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getInternalMargin/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPickerCtrlProportion/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextCtrl/1,
+ getTextCtrlProportion/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,
isRetained/1,isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,
@@ -168,7 +169,7 @@ getColour(#wx_ref{type=ThisT,ref=ThisRef}) ->
(This, Col) -> 'ok' when
This::wxColourPickerCtrl(), Col::wx:wx_colour().
setColour(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxColourPickerCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:call(?wxColourPickerCtrl_SetColour_1_0,
@@ -221,6 +222,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -537,6 +540,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxComboBox.erl b/lib/wx/src/gen/wxComboBox.erl
index bbdf768eba..9f8cf77445 100644
--- a/lib/wx/src/gen/wxComboBox.erl
+++ b/lib/wx/src/gen/wxComboBox.erl
@@ -42,42 +42,42 @@
centre/1,centre/2,centreOnParent/1,centreOnParent/2,clear/1,clearBackground/1,
clientToScreen/2,clientToScreen/3,close/1,close/2,connect/2,connect/3,
convertDialogToPixels/2,convertPixelsToDialog/2,delete/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- findString/2,findString/3,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientData/2,getClientSize/1,
- getContainingSizer/1,getCount/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,getMinSize/1,
- getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
- getSelection/1,getSize/1,getSizer/1,getString/2,getStringSelection/1,
- getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
- getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
- hasTransparentBackground/1,hide/1,inheritAttributes/1,initDialog/1,
- insert/3,insert/4,invalidateBestSize/1,isDoubleBuffered/1,isEmpty/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,select/2,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientData/3,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
- setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
- setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setString/3,setStringSelection/2,setThemeEnabled/2,setToolTip/2,setTransparent/2,
- setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
- setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
- shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
- transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
- validate/1,warpPointer/3]).
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,findString/2,findString/3,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientData/2,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCount/1,getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,
+ getFont/1,getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSelection/1,getSize/1,getSizer/1,
+ getString/2,getStringSelection/1,getTextExtent/2,getTextExtent/3,
+ getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
+ getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
+ hide/1,inheritAttributes/1,initDialog/1,insert/3,insert/4,invalidateBestSize/1,
+ isDoubleBuffered/1,isEmpty/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
+ isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,
+ makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,select/2,setAcceleratorTable/2,
+ setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
+ setClientData/3,setClientSize/2,setClientSize/3,setContainingSizer/2,
+ setCursor/2,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,
+ setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,setId/2,
+ setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
+ setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setString/3,setStringSelection/2,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
+ show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
+ update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
-export_type([wxComboBox/0]).
%% @hidden
@@ -130,7 +130,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options)
This::wxComboBox(), Parent::wxWindow:wxWindow(), Id::integer(), Value::unicode:chardata(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[unicode:chardata()].
create(This,Parent,Id,Value,Pos={PosX,PosY},Size={SizeW,SizeH},Choices)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Value),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Value),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices) ->
create(This,Parent,Id,Value,Pos,Size,Choices, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxcombobox.html#wxcomboboxcreate">external documentation</a>.
@@ -139,7 +139,7 @@ create(This,Parent,Id,Value,Pos={PosX,PosY},Size={SizeW,SizeH},Choices)
Option :: {'style', integer()}
| {'validator', wx:wx_object()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Value,{PosX,PosY},{SizeW,SizeH},Choices, Options)
- when is_integer(Id),is_list(Value),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Value),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices),is_list(Options) ->
?CLASS(ThisT,wxComboBox),
?CLASS(ParentT,wxWindow),
Value_UC = unicode:characters_to_binary([Value,0]),
@@ -252,7 +252,7 @@ redo(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec replace(This, From, To, Value) -> 'ok' when
This::wxComboBox(), From::integer(), To::integer(), Value::unicode:chardata().
replace(#wx_ref{type=ThisT,ref=ThisRef},From,To,Value)
- when is_integer(From),is_integer(To),is_list(Value) ->
+ when is_integer(From),is_integer(To),?is_chardata(Value) ->
?CLASS(ThisT,wxComboBox),
Value_UC = unicode:characters_to_binary([Value,0]),
wxe_util:cast(?wxComboBox_Replace,
@@ -306,7 +306,7 @@ setSelection(#wx_ref{type=ThisT,ref=ThisRef},From,To)
-spec setValue(This, Value) -> 'ok' when
This::wxComboBox(), Value::unicode:chardata().
setValue(#wx_ref{type=ThisT,ref=ThisRef},Value)
- when is_list(Value) ->
+ when ?is_chardata(Value) ->
?CLASS(ThisT,wxComboBox),
Value_UC = unicode:characters_to_binary([Value,0]),
wxe_util:cast(?wxComboBox_SetValue,
@@ -372,6 +372,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -688,6 +690,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxCommandEvent.erl b/lib/wx/src/gen/wxCommandEvent.erl
index 781482aebb..18ccbc65f0 100644
--- a/lib/wx/src/gen/wxCommandEvent.erl
+++ b/lib/wx/src/gen/wxCommandEvent.erl
@@ -114,7 +114,7 @@ setInt(#wx_ref{type=ThisT,ref=ThisRef},I)
-spec setString(This, S) -> 'ok' when
This::wxCommandEvent(), S::unicode:chardata().
setString(#wx_ref{type=ThisT,ref=ThisRef},S)
- when is_list(S) ->
+ when ?is_chardata(S) ->
?CLASS(ThisT,wxCommandEvent),
S_UC = unicode:characters_to_binary([S,0]),
wxe_util:cast(?wxCommandEvent_SetString,
diff --git a/lib/wx/src/gen/wxControl.erl b/lib/wx/src/gen/wxControl.erl
index a84f88639b..6be7574d80 100644
--- a/lib/wx/src/gen/wxControl.erl
+++ b/lib/wx/src/gen/wxControl.erl
@@ -37,30 +37,30 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
- getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,setMinSize/2,
- setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getMaxSize/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
@@ -89,7 +89,7 @@ getLabel(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setLabel(This, Label) -> 'ok' when
This::wxControl(), Label::unicode:chardata().
setLabel(#wx_ref{type=ThisT,ref=ThisRef},Label)
- when is_list(Label) ->
+ when ?is_chardata(Label) ->
?CLASS(ThisT,wxControl),
Label_UC = unicode:characters_to_binary([Label,0]),
wxe_util:cast(?wxControl_SetLabel,
@@ -97,6 +97,8 @@ setLabel(#wx_ref{type=ThisT,ref=ThisRef},Label)
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -413,6 +415,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxControlWithItems.erl b/lib/wx/src/gen/wxControlWithItems.erl
index c4d116d9e7..47ffa7dcba 100644
--- a/lib/wx/src/gen/wxControlWithItems.erl
+++ b/lib/wx/src/gen/wxControlWithItems.erl
@@ -41,29 +41,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -86,7 +86,7 @@ parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
-spec append(This, Item) -> integer() when
This::wxControlWithItems(), Item::unicode:chardata().
append(#wx_ref{type=ThisT,ref=ThisRef},Item)
- when is_list(Item) ->
+ when ?is_chardata(Item) ->
?CLASS(ThisT,wxControlWithItems),
Item_UC = unicode:characters_to_binary([Item,0]),
wxe_util:call(?wxControlWithItems_Append_1,
@@ -96,7 +96,7 @@ append(#wx_ref{type=ThisT,ref=ThisRef},Item)
-spec append(This, Item, ClientData) -> integer() when
This::wxControlWithItems(), Item::unicode:chardata(), ClientData::term().
append(#wx_ref{type=ThisT,ref=ThisRef},Item,ClientData)
- when is_list(Item) ->
+ when ?is_chardata(Item) ->
?CLASS(ThisT,wxControlWithItems),
Item_UC = unicode:characters_to_binary([Item,0]),
wxe_util:send_bin(term_to_binary(ClientData)),
@@ -136,7 +136,7 @@ delete(#wx_ref{type=ThisT,ref=ThisRef},N)
This::wxControlWithItems(), S::unicode:chardata().
findString(This,S)
- when is_record(This, wx_ref),is_list(S) ->
+ when is_record(This, wx_ref),?is_chardata(S) ->
findString(This,S, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxcontrolwithitems.html#wxcontrolwithitemsfindstring">external documentation</a>.
@@ -144,7 +144,7 @@ findString(This,S)
This::wxControlWithItems(), S::unicode:chardata(),
Option :: {'bCase', boolean()}.
findString(#wx_ref{type=ThisT,ref=ThisRef},S, Options)
- when is_list(S),is_list(Options) ->
+ when ?is_chardata(S),is_list(Options) ->
?CLASS(ThisT,wxControlWithItems),
S_UC = unicode:characters_to_binary([S,0]),
MOpts = fun({bCase, BCase}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(BCase)):32/?UI>>|Acc];
@@ -209,7 +209,7 @@ getStringSelection(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec insert(This, Item, Pos) -> integer() when
This::wxControlWithItems(), Item::unicode:chardata(), Pos::integer().
insert(#wx_ref{type=ThisT,ref=ThisRef},Item,Pos)
- when is_list(Item),is_integer(Pos) ->
+ when ?is_chardata(Item),is_integer(Pos) ->
?CLASS(ThisT,wxControlWithItems),
Item_UC = unicode:characters_to_binary([Item,0]),
wxe_util:call(?wxControlWithItems_Insert_2,
@@ -219,7 +219,7 @@ insert(#wx_ref{type=ThisT,ref=ThisRef},Item,Pos)
-spec insert(This, Item, Pos, ClientData) -> integer() when
This::wxControlWithItems(), Item::unicode:chardata(), Pos::integer(), ClientData::term().
insert(#wx_ref{type=ThisT,ref=ThisRef},Item,Pos,ClientData)
- when is_list(Item),is_integer(Pos) ->
+ when ?is_chardata(Item),is_integer(Pos) ->
?CLASS(ThisT,wxControlWithItems),
Item_UC = unicode:characters_to_binary([Item,0]),
wxe_util:send_bin(term_to_binary(ClientData)),
@@ -256,7 +256,7 @@ setSelection(#wx_ref{type=ThisT,ref=ThisRef},N)
-spec setString(This, N, S) -> 'ok' when
This::wxControlWithItems(), N::integer(), S::unicode:chardata().
setString(#wx_ref{type=ThisT,ref=ThisRef},N,S)
- when is_integer(N),is_list(S) ->
+ when is_integer(N),?is_chardata(S) ->
?CLASS(ThisT,wxControlWithItems),
S_UC = unicode:characters_to_binary([S,0]),
wxe_util:cast(?wxControlWithItems_SetString,
@@ -266,7 +266,7 @@ setString(#wx_ref{type=ThisT,ref=ThisRef},N,S)
-spec setStringSelection(This, S) -> boolean() when
This::wxControlWithItems(), S::unicode:chardata().
setStringSelection(#wx_ref{type=ThisT,ref=ThisRef},S)
- when is_list(S) ->
+ when ?is_chardata(S) ->
?CLASS(ThisT,wxControlWithItems),
S_UC = unicode:characters_to_binary([S,0]),
wxe_util:call(?wxControlWithItems_SetStringSelection,
@@ -279,6 +279,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -595,6 +597,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxDC.erl b/lib/wx/src/gen/wxDC.erl
index ad7a4251ec..16bfcc3463 100644
--- a/lib/wx/src/gen/wxDC.erl
+++ b/lib/wx/src/gen/wxDC.erl
@@ -253,7 +253,7 @@ drawIcon(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=IconT,ref=IconRef},{PtX,Pt
This::wxDC(), Text::unicode:chardata(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}.
drawLabel(This,Text,Rect={RectX,RectY,RectW,RectH})
- when is_record(This, wx_ref),is_list(Text),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) ->
+ when is_record(This, wx_ref),?is_chardata(Text),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) ->
drawLabel(This,Text,Rect, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdc.html#wxdcdrawlabel">external documentation</a>.
@@ -262,7 +262,7 @@ drawLabel(This,Text,Rect={RectX,RectY,RectW,RectH})
Option :: {'alignment', integer()}
| {'indexAccel', integer()}.
drawLabel(#wx_ref{type=ThisT,ref=ThisRef},Text,{RectX,RectY,RectW,RectH}, Options)
- when is_list(Text),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),is_list(Options) ->
+ when ?is_chardata(Text),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),is_list(Options) ->
?CLASS(ThisT,wxDC),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({alignment, Alignment}, Acc) -> [<<1:32/?UI,Alignment:32/?UI>>|Acc];
@@ -363,7 +363,7 @@ drawRectangle(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},{SzW,SzH})
-spec drawRotatedText(This, Text, Pt, Angle) -> 'ok' when
This::wxDC(), Text::unicode:chardata(), Pt::{X::integer(), Y::integer()}, Angle::number().
drawRotatedText(#wx_ref{type=ThisT,ref=ThisRef},Text,{PtX,PtY},Angle)
- when is_list(Text),is_integer(PtX),is_integer(PtY),is_number(Angle) ->
+ when ?is_chardata(Text),is_integer(PtX),is_integer(PtY),is_number(Angle) ->
?CLASS(ThisT,wxDC),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxDC_DrawRotatedText,
@@ -391,7 +391,7 @@ drawRoundedRectangle(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},{SzW,SzH},Radius)
-spec drawText(This, Text, Pt) -> 'ok' when
This::wxDC(), Text::unicode:chardata(), Pt::{X::integer(), Y::integer()}.
drawText(#wx_ref{type=ThisT,ref=ThisRef},Text,{PtX,PtY})
- when is_list(Text),is_integer(PtX),is_integer(PtY) ->
+ when ?is_chardata(Text),is_integer(PtX),is_integer(PtY) ->
?CLASS(ThisT,wxDC),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxDC_DrawText,
@@ -521,7 +521,7 @@ getMapMode(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec getMultiLineTextExtent(This, String) -> {W::integer(), H::integer()} when
This::wxDC(), String::unicode:chardata().
getMultiLineTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String)
- when is_list(String) ->
+ when ?is_chardata(String) ->
?CLASS(ThisT,wxDC),
String_UC = unicode:characters_to_binary([String,0]),
wxe_util:call(?wxDC_GetMultiLineTextExtent_1,
@@ -532,7 +532,7 @@ getMultiLineTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String)
This::wxDC(), String::unicode:chardata(),
Option :: {'font', wxFont:wxFont()}.
getMultiLineTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String, Options)
- when is_list(String),is_list(Options) ->
+ when ?is_chardata(String),is_list(Options) ->
?CLASS(ThisT,wxDC),
String_UC = unicode:characters_to_binary([String,0]),
MOpts = fun({font, #wx_ref{type=FontT,ref=FontRef}}, Acc) -> ?CLASS(FontT,wxFont),[<<1:32/?UI,FontRef:32/?UI>>|Acc];
@@ -546,7 +546,7 @@ getMultiLineTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String, Options)
Result ::{Res ::boolean(), Widths::[integer()]},
This::wxDC(), Text::unicode:chardata().
getPartialTextExtents(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxDC),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:call(?wxDC_GetPartialTextExtents,
@@ -606,7 +606,7 @@ getTextBackground(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec getTextExtent(This, String) -> {W::integer(), H::integer()} when
This::wxDC(), String::unicode:chardata().
getTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String)
- when is_list(String) ->
+ when ?is_chardata(String) ->
?CLASS(ThisT,wxDC),
String_UC = unicode:characters_to_binary([String,0]),
wxe_util:call(?wxDC_GetTextExtent_1,
@@ -618,7 +618,7 @@ getTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String)
This::wxDC(), String::unicode:chardata(),
Option :: {'theFont', wxFont:wxFont()}.
getTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String, Options)
- when is_list(String),is_list(Options) ->
+ when ?is_chardata(String),is_list(Options) ->
?CLASS(ThisT,wxDC),
String_UC = unicode:characters_to_binary([String,0]),
MOpts = fun({theFont, #wx_ref{type=TheFontT,ref=TheFontRef}}, Acc) -> ?CLASS(TheFontT,wxFont),[<<1:32/?UI,TheFontRef:32/?UI>>|Acc];
@@ -929,7 +929,7 @@ setUserScale(#wx_ref{type=ThisT,ref=ThisRef},X,Y)
-spec startDoc(This, Message) -> boolean() when
This::wxDC(), Message::unicode:chardata().
startDoc(#wx_ref{type=ThisT,ref=ThisRef},Message)
- when is_list(Message) ->
+ when ?is_chardata(Message) ->
?CLASS(ThisT,wxDC),
Message_UC = unicode:characters_to_binary([Message,0]),
wxe_util:call(?wxDC_StartDoc,
diff --git a/lib/wx/src/gen/wxDatePickerCtrl.erl b/lib/wx/src/gen/wxDatePickerCtrl.erl
index 1b306a498a..743169c58e 100644
--- a/lib/wx/src/gen/wxDatePickerCtrl.erl
+++ b/lib/wx/src/gen/wxDatePickerCtrl.erl
@@ -39,17 +39,18 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getInternalMargin/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,
- getParent/1,getPickerCtrlProportion/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
- getSize/1,getSizer/1,getTextCtrl/1,getTextCtrlProportion/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getInternalMargin/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPickerCtrlProportion/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextCtrl/1,
+ getTextCtrlProportion/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,
isRetained/1,isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,
@@ -197,6 +198,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -513,6 +516,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxDialog.erl b/lib/wx/src/gen/wxDialog.erl
index 9f98644828..72f37df178 100644
--- a/lib/wx/src/gen/wxDialog.erl
+++ b/lib/wx/src/gen/wxDialog.erl
@@ -41,32 +41,32 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,
- getParent/1,getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,
- getScrollPos/2,getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,
- getTextExtent/2,getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,
- getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
- hasScrollbar/2,hasTransparentBackground/1,hide/1,iconize/1,iconize/2,
- inheritAttributes/1,initDialog/1,invalidateBestSize/1,isActive/1,
- isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
- isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
+ getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
+ getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
+ getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
+ hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,
+ setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
+ setCursor/2,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,
+ setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,
+ setIcons/2,setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
@@ -97,7 +97,7 @@ new() ->
Parent::wxWindow:wxWindow(), Id::integer(), Title::unicode:chardata().
new(Parent,Id,Title)
- when is_record(Parent, wx_ref),is_integer(Id),is_list(Title) ->
+ when is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title) ->
new(Parent,Id,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdialog.html#wxdialogwxdialog">external documentation</a>.
@@ -107,7 +107,7 @@ new(Parent,Id,Title)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
- when is_integer(Id),is_list(Title),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Title_UC = unicode:characters_to_binary([Title,0]),
MOpts = fun({pos, {PosX,PosY}}, Acc) -> [<<1:32/?UI,PosX:32/?UI,PosY:32/?UI,0:32>>|Acc];
@@ -123,7 +123,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
This::wxDialog(), Parent::wxWindow:wxWindow(), Id::integer(), Title::unicode:chardata().
create(This,Parent,Id,Title)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Title) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title) ->
create(This,Parent,Id,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdialog.html#wxdialogcreate">external documentation</a>.
@@ -133,7 +133,7 @@ create(This,Parent,Id,Title)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
- when is_integer(Id),is_list(Title),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_list(Options) ->
?CLASS(ThisT,wxDialog),
?CLASS(ParentT,wxWindow),
Title_UC = unicode:characters_to_binary([Title,0]),
@@ -298,6 +298,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -614,6 +616,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxDirDialog.erl b/lib/wx/src/gen/wxDirDialog.erl
index 1b6b9dba71..5a2df9821a 100644
--- a/lib/wx/src/gen/wxDirDialog.erl
+++ b/lib/wx/src/gen/wxDirDialog.erl
@@ -40,40 +40,40 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
+ lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
+ requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
@@ -137,7 +137,7 @@ getMessage(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setMessage(This, Message) -> 'ok' when
This::wxDirDialog(), Message::unicode:chardata().
setMessage(#wx_ref{type=ThisT,ref=ThisRef},Message)
- when is_list(Message) ->
+ when ?is_chardata(Message) ->
?CLASS(ThisT,wxDirDialog),
Message_UC = unicode:characters_to_binary([Message,0]),
wxe_util:cast(?wxDirDialog_SetMessage,
@@ -147,7 +147,7 @@ setMessage(#wx_ref{type=ThisT,ref=ThisRef},Message)
-spec setPath(This, Path) -> 'ok' when
This::wxDirDialog(), Path::unicode:chardata().
setPath(#wx_ref{type=ThisT,ref=ThisRef},Path)
- when is_list(Path) ->
+ when ?is_chardata(Path) ->
?CLASS(ThisT,wxDirDialog),
Path_UC = unicode:characters_to_binary([Path,0]),
wxe_util:cast(?wxDirDialog_SetPath,
@@ -231,6 +231,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -547,6 +549,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxDirPickerCtrl.erl b/lib/wx/src/gen/wxDirPickerCtrl.erl
index 3bedeb7f54..9bfff7d458 100644
--- a/lib/wx/src/gen/wxDirPickerCtrl.erl
+++ b/lib/wx/src/gen/wxDirPickerCtrl.erl
@@ -39,17 +39,18 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getInternalMargin/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,
- getParent/1,getPickerCtrlProportion/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
- getSize/1,getSizer/1,getTextCtrl/1,getTextCtrlProportion/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getInternalMargin/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPickerCtrlProportion/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextCtrl/1,
+ getTextCtrlProportion/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,
isRetained/1,isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,
@@ -166,7 +167,7 @@ getPath(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setPath(This, Str) -> 'ok' when
This::wxDirPickerCtrl(), Str::unicode:chardata().
setPath(#wx_ref{type=ThisT,ref=ThisRef},Str)
- when is_list(Str) ->
+ when ?is_chardata(Str) ->
?CLASS(ThisT,wxDirPickerCtrl),
Str_UC = unicode:characters_to_binary([Str,0]),
wxe_util:cast(?wxDirPickerCtrl_SetPath,
@@ -214,6 +215,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -530,6 +533,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxDropFilesEvent.erl b/lib/wx/src/gen/wxDropFilesEvent.erl
new file mode 100644
index 0000000000..d28dcd1f7a
--- /dev/null
+++ b/lib/wx/src/gen/wxDropFilesEvent.erl
@@ -0,0 +1,89 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%% This file is generated DO NOT EDIT
+
+%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdropfilesevent.html">wxDropFilesEvent</a>.
+%% <dl><dt>Use {@link wxEvtHandler:connect/3.} with EventType:</dt>
+%% <dd><em>drop_files</em></dd></dl>
+%% See also the message variant {@link wxEvtHandler:wxDropFiles(). #wxDropFiles{}} event record type.
+%%
+%% <p>This class is derived (and can use functions) from:
+%% <br />{@link wxEvent}
+%% </p>
+%% @type wxDropFilesEvent(). An object reference, The representation is internal
+%% and can be changed without notice. It can't be used for comparsion
+%% stored on disc or distributed for use on other nodes.
+
+-module(wxDropFilesEvent).
+-include("wxe.hrl").
+-export([getFiles/1,getNumberOfFiles/1,getPosition/1]).
+
+%% inherited exports
+-export([getId/1,getSkipped/1,getTimestamp/1,isCommandEvent/1,parent_class/1,
+ resumePropagation/2,shouldPropagate/1,skip/1,skip/2,stopPropagation/1]).
+
+-export_type([wxDropFilesEvent/0]).
+%% @hidden
+parent_class(wxEvent) -> true;
+parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
+
+-type wxDropFilesEvent() :: wx:wx_object().
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdropfilesevent.html#wxdropfileseventgetposition">external documentation</a>.
+-spec getPosition(This) -> {X::integer(), Y::integer()} when
+ This::wxDropFilesEvent().
+getPosition(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxDropFilesEvent),
+ wxe_util:call(?wxDropFilesEvent_GetPosition,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdropfilesevent.html#wxdropfileseventgetnumberoffiles">external documentation</a>.
+-spec getNumberOfFiles(This) -> integer() when
+ This::wxDropFilesEvent().
+getNumberOfFiles(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxDropFilesEvent),
+ wxe_util:call(?wxDropFilesEvent_GetNumberOfFiles,
+ <<ThisRef:32/?UI>>).
+
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxdropfilesevent.html#wxdropfileseventgetfiles">external documentation</a>.
+-spec getFiles(This) -> [unicode:charlist()] when
+ This::wxDropFilesEvent().
+getFiles(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxDropFilesEvent),
+ wxe_util:call(?wxDropFilesEvent_GetFiles,
+ <<ThisRef:32/?UI>>).
+
+ %% From wxEvent
+%% @hidden
+stopPropagation(This) -> wxEvent:stopPropagation(This).
+%% @hidden
+skip(This, Options) -> wxEvent:skip(This, Options).
+%% @hidden
+skip(This) -> wxEvent:skip(This).
+%% @hidden
+shouldPropagate(This) -> wxEvent:shouldPropagate(This).
+%% @hidden
+resumePropagation(This,PropagationLevel) -> wxEvent:resumePropagation(This,PropagationLevel).
+%% @hidden
+isCommandEvent(This) -> wxEvent:isCommandEvent(This).
+%% @hidden
+getTimestamp(This) -> wxEvent:getTimestamp(This).
+%% @hidden
+getSkipped(This) -> wxEvent:getSkipped(This).
+%% @hidden
+getId(This) -> wxEvent:getId(This).
diff --git a/lib/wx/src/gen/wxFileDataObject.erl b/lib/wx/src/gen/wxFileDataObject.erl
index 06d8ceb9cd..d4e9198225 100644
--- a/lib/wx/src/gen/wxFileDataObject.erl
+++ b/lib/wx/src/gen/wxFileDataObject.erl
@@ -49,7 +49,7 @@ new() ->
-spec addFile(This, Filename) -> 'ok' when
This::wxFileDataObject(), Filename::unicode:chardata().
addFile(#wx_ref{type=ThisT,ref=ThisRef},Filename)
- when is_list(Filename) ->
+ when ?is_chardata(Filename) ->
?CLASS(ThisT,wxFileDataObject),
Filename_UC = unicode:characters_to_binary([Filename,0]),
wxe_util:cast(?wxFileDataObject_AddFile,
diff --git a/lib/wx/src/gen/wxFileDialog.erl b/lib/wx/src/gen/wxFileDialog.erl
index 070fce3a39..6032e38a16 100644
--- a/lib/wx/src/gen/wxFileDialog.erl
+++ b/lib/wx/src/gen/wxFileDialog.erl
@@ -42,40 +42,40 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
+ lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
+ requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
@@ -191,7 +191,7 @@ getWildcard(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setDirectory(This, Dir) -> 'ok' when
This::wxFileDialog(), Dir::unicode:chardata().
setDirectory(#wx_ref{type=ThisT,ref=ThisRef},Dir)
- when is_list(Dir) ->
+ when ?is_chardata(Dir) ->
?CLASS(ThisT,wxFileDialog),
Dir_UC = unicode:characters_to_binary([Dir,0]),
wxe_util:cast(?wxFileDialog_SetDirectory,
@@ -201,7 +201,7 @@ setDirectory(#wx_ref{type=ThisT,ref=ThisRef},Dir)
-spec setFilename(This, Name) -> 'ok' when
This::wxFileDialog(), Name::unicode:chardata().
setFilename(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxFileDialog),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:cast(?wxFileDialog_SetFilename,
@@ -220,7 +220,7 @@ setFilterIndex(#wx_ref{type=ThisT,ref=ThisRef},FilterIndex)
-spec setMessage(This, Message) -> 'ok' when
This::wxFileDialog(), Message::unicode:chardata().
setMessage(#wx_ref{type=ThisT,ref=ThisRef},Message)
- when is_list(Message) ->
+ when ?is_chardata(Message) ->
?CLASS(ThisT,wxFileDialog),
Message_UC = unicode:characters_to_binary([Message,0]),
wxe_util:cast(?wxFileDialog_SetMessage,
@@ -230,7 +230,7 @@ setMessage(#wx_ref{type=ThisT,ref=ThisRef},Message)
-spec setPath(This, Path) -> 'ok' when
This::wxFileDialog(), Path::unicode:chardata().
setPath(#wx_ref{type=ThisT,ref=ThisRef},Path)
- when is_list(Path) ->
+ when ?is_chardata(Path) ->
?CLASS(ThisT,wxFileDialog),
Path_UC = unicode:characters_to_binary([Path,0]),
wxe_util:cast(?wxFileDialog_SetPath,
@@ -240,7 +240,7 @@ setPath(#wx_ref{type=ThisT,ref=ThisRef},Path)
-spec setWildcard(This, WildCard) -> 'ok' when
This::wxFileDialog(), WildCard::unicode:chardata().
setWildcard(#wx_ref{type=ThisT,ref=ThisRef},WildCard)
- when is_list(WildCard) ->
+ when ?is_chardata(WildCard) ->
?CLASS(ThisT,wxFileDialog),
WildCard_UC = unicode:characters_to_binary([WildCard,0]),
wxe_util:cast(?wxFileDialog_SetWildcard,
@@ -324,6 +324,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -640,6 +642,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxFilePickerCtrl.erl b/lib/wx/src/gen/wxFilePickerCtrl.erl
index 396403dc22..3b1943cbee 100644
--- a/lib/wx/src/gen/wxFilePickerCtrl.erl
+++ b/lib/wx/src/gen/wxFilePickerCtrl.erl
@@ -39,17 +39,18 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getInternalMargin/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,
- getParent/1,getPickerCtrlProportion/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
- getSize/1,getSizer/1,getTextCtrl/1,getTextCtrlProportion/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getInternalMargin/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPickerCtrlProportion/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextCtrl/1,
+ getTextCtrlProportion/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,
isRetained/1,isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,
@@ -170,7 +171,7 @@ getPath(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setPath(This, Str) -> 'ok' when
This::wxFilePickerCtrl(), Str::unicode:chardata().
setPath(#wx_ref{type=ThisT,ref=ThisRef},Str)
- when is_list(Str) ->
+ when ?is_chardata(Str) ->
?CLASS(ThisT,wxFilePickerCtrl),
Str_UC = unicode:characters_to_binary([Str,0]),
wxe_util:cast(?wxFilePickerCtrl_SetPath,
@@ -218,6 +219,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -534,6 +537,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxFindReplaceData.erl b/lib/wx/src/gen/wxFindReplaceData.erl
index 9b4b910f7e..388bf5f238 100644
--- a/lib/wx/src/gen/wxFindReplaceData.erl
+++ b/lib/wx/src/gen/wxFindReplaceData.erl
@@ -87,7 +87,7 @@ setFlags(#wx_ref{type=ThisT,ref=ThisRef},Flags)
-spec setFindString(This, Str) -> 'ok' when
This::wxFindReplaceData(), Str::unicode:chardata().
setFindString(#wx_ref{type=ThisT,ref=ThisRef},Str)
- when is_list(Str) ->
+ when ?is_chardata(Str) ->
?CLASS(ThisT,wxFindReplaceData),
Str_UC = unicode:characters_to_binary([Str,0]),
wxe_util:cast(?wxFindReplaceData_SetFindString,
@@ -97,7 +97,7 @@ setFindString(#wx_ref{type=ThisT,ref=ThisRef},Str)
-spec setReplaceString(This, Str) -> 'ok' when
This::wxFindReplaceData(), Str::unicode:chardata().
setReplaceString(#wx_ref{type=ThisT,ref=ThisRef},Str)
- when is_list(Str) ->
+ when ?is_chardata(Str) ->
?CLASS(ThisT,wxFindReplaceData),
Str_UC = unicode:characters_to_binary([Str,0]),
wxe_util:cast(?wxFindReplaceData_SetReplaceString,
diff --git a/lib/wx/src/gen/wxFindReplaceDialog.erl b/lib/wx/src/gen/wxFindReplaceDialog.erl
index a34fc329ae..9250c2fa2f 100644
--- a/lib/wx/src/gen/wxFindReplaceDialog.erl
+++ b/lib/wx/src/gen/wxFindReplaceDialog.erl
@@ -40,40 +40,40 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
+ lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
+ requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
@@ -99,7 +99,7 @@ new() ->
Parent::wxWindow:wxWindow(), Data::wxFindReplaceData:wxFindReplaceData(), Title::unicode:chardata().
new(Parent,Data,Title)
- when is_record(Parent, wx_ref),is_record(Data, wx_ref),is_list(Title) ->
+ when is_record(Parent, wx_ref),is_record(Data, wx_ref),?is_chardata(Title) ->
new(Parent,Data,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxfindreplacedialog.html#wxfindreplacedialogwxfindreplacedialog">external documentation</a>.
@@ -107,7 +107,7 @@ new(Parent,Data,Title)
Parent::wxWindow:wxWindow(), Data::wxFindReplaceData:wxFindReplaceData(), Title::unicode:chardata(),
Option :: {'style', integer()}.
new(#wx_ref{type=ParentT,ref=ParentRef},#wx_ref{type=DataT,ref=DataRef},Title, Options)
- when is_list(Title),is_list(Options) ->
+ when ?is_chardata(Title),is_list(Options) ->
?CLASS(ParentT,wxWindow),
?CLASS(DataT,wxFindReplaceData),
Title_UC = unicode:characters_to_binary([Title,0]),
@@ -122,7 +122,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},#wx_ref{type=DataT,ref=DataRef},Title, O
This::wxFindReplaceDialog(), Parent::wxWindow:wxWindow(), Data::wxFindReplaceData:wxFindReplaceData(), Title::unicode:chardata().
create(This,Parent,Data,Title)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_record(Data, wx_ref),is_list(Title) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_record(Data, wx_ref),?is_chardata(Title) ->
create(This,Parent,Data,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxfindreplacedialog.html#wxfindreplacedialogcreate">external documentation</a>.
@@ -130,7 +130,7 @@ create(This,Parent,Data,Title)
This::wxFindReplaceDialog(), Parent::wxWindow:wxWindow(), Data::wxFindReplaceData:wxFindReplaceData(), Title::unicode:chardata(),
Option :: {'style', integer()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},#wx_ref{type=DataT,ref=DataRef},Title, Options)
- when is_list(Title),is_list(Options) ->
+ when ?is_chardata(Title),is_list(Options) ->
?CLASS(ThisT,wxFindReplaceDialog),
?CLASS(ParentT,wxWindow),
?CLASS(DataT,wxFindReplaceData),
@@ -227,6 +227,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -543,6 +545,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxFont.erl b/lib/wx/src/gen/wxFont.erl
index 56e6e96b6d..fb0ba8b505 100644
--- a/lib/wx/src/gen/wxFont.erl
+++ b/lib/wx/src/gen/wxFont.erl
@@ -49,7 +49,7 @@ new() ->
-spec new(Fontname) -> wxFont() when
Fontname::unicode:chardata().
new(Fontname)
- when is_list(Fontname) ->
+ when ?is_chardata(Fontname) ->
Fontname_UC = unicode:characters_to_binary([Fontname,0]),
wxe_util:construct(?wxFont_new_1,
<<(byte_size(Fontname_UC)):32/?UI,(Fontname_UC)/binary, 0:(((8- ((4+byte_size(Fontname_UC)) band 16#7)) band 16#7))/unit:8>>).
@@ -183,7 +183,7 @@ setDefaultEncoding(Encoding)
-spec setFaceName(This, FaceName) -> boolean() when
This::wxFont(), FaceName::unicode:chardata().
setFaceName(#wx_ref{type=ThisT,ref=ThisRef},FaceName)
- when is_list(FaceName) ->
+ when ?is_chardata(FaceName) ->
?CLASS(ThisT,wxFont),
FaceName_UC = unicode:characters_to_binary([FaceName,0]),
wxe_util:call(?wxFont_SetFaceName,
diff --git a/lib/wx/src/gen/wxFontDialog.erl b/lib/wx/src/gen/wxFontDialog.erl
index 3e6a913973..26010aa46b 100644
--- a/lib/wx/src/gen/wxFontDialog.erl
+++ b/lib/wx/src/gen/wxFontDialog.erl
@@ -40,40 +40,40 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
+ lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
+ requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
@@ -199,6 +199,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -515,6 +517,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxFontPickerCtrl.erl b/lib/wx/src/gen/wxFontPickerCtrl.erl
index 0356f795eb..d1234c5589 100644
--- a/lib/wx/src/gen/wxFontPickerCtrl.erl
+++ b/lib/wx/src/gen/wxFontPickerCtrl.erl
@@ -40,17 +40,18 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getInternalMargin/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,
- getParent/1,getPickerCtrlProportion/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
- getSize/1,getSizer/1,getTextCtrl/1,getTextCtrlProportion/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getInternalMargin/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPickerCtrlProportion/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextCtrl/1,
+ getTextCtrlProportion/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTextCtrl/1,hasTransparentBackground/1,
hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isPickerCtrlGrowable/1,
isRetained/1,isShown/1,isTextCtrlGrowable/1,isTopLevel/1,layout/1,
@@ -227,6 +228,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -543,6 +546,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxFrame.erl b/lib/wx/src/gen/wxFrame.erl
index 93aad5b235..1dc6106bfa 100644
--- a/lib/wx/src/gen/wxFrame.erl
+++ b/lib/wx/src/gen/wxFrame.erl
@@ -43,32 +43,32 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,
- getParent/1,getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,
- getScrollPos/2,getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,
- getTextExtent/2,getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,
- getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
- hasScrollbar/2,hasTransparentBackground/1,hide/1,iconize/1,iconize/2,
- inheritAttributes/1,initDialog/1,invalidateBestSize/1,isActive/1,
- isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
- isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
- maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
+ getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
+ getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
+ getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
+ hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
+ isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
+ isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
+ makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,
+ setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
+ setCursor/2,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,
+ setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,
+ setIcons/2,setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
@@ -99,7 +99,7 @@ new() ->
Parent::wxWindow:wxWindow(), Id::integer(), Title::unicode:chardata().
new(Parent,Id,Title)
- when is_record(Parent, wx_ref),is_integer(Id),is_list(Title) ->
+ when is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title) ->
new(Parent,Id,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxframe.html#wxframewxframe">external documentation</a>.
@@ -109,7 +109,7 @@ new(Parent,Id,Title)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
- when is_integer(Id),is_list(Title),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Title_UC = unicode:characters_to_binary([Title,0]),
MOpts = fun({pos, {PosX,PosY}}, Acc) -> [<<1:32/?UI,PosX:32/?UI,PosY:32/?UI,0:32>>|Acc];
@@ -125,7 +125,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
This::wxFrame(), Parent::wxWindow:wxWindow(), Id::integer(), Title::unicode:chardata().
create(This,Parent,Id,Title)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Title) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title) ->
create(This,Parent,Id,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxframe.html#wxframecreate">external documentation</a>.
@@ -135,7 +135,7 @@ create(This,Parent,Id,Title)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
- when is_integer(Id),is_list(Title),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_list(Options) ->
?CLASS(ThisT,wxFrame),
?CLASS(ParentT,wxWindow),
Title_UC = unicode:characters_to_binary([Title,0]),
@@ -284,7 +284,7 @@ setStatusBarPane(#wx_ref{type=ThisT,ref=ThisRef},N)
This::wxFrame(), Text::unicode:chardata().
setStatusText(This,Text)
- when is_record(This, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),?is_chardata(Text) ->
setStatusText(This,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxframe.html#wxframesetstatustext">external documentation</a>.
@@ -292,7 +292,7 @@ setStatusText(This,Text)
This::wxFrame(), Text::unicode:chardata(),
Option :: {'number', integer()}.
setStatusText(#wx_ref{type=ThisT,ref=ThisRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+ when ?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxFrame),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({number, Number}, Acc) -> [<<1:32/?UI,Number:32/?UI>>|Acc];
@@ -375,6 +375,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -695,6 +697,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxGLCanvas.erl b/lib/wx/src/gen/wxGLCanvas.erl
index 2007047bd3..8a94d1df26 100644
--- a/lib/wx/src/gen/wxGLCanvas.erl
+++ b/lib/wx/src/gen/wxGLCanvas.erl
@@ -37,29 +37,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -194,6 +194,8 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -514,6 +516,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxGauge.erl b/lib/wx/src/gen/wxGauge.erl
index fa2e7618e8..40f7f120b0 100644
--- a/lib/wx/src/gen/wxGauge.erl
+++ b/lib/wx/src/gen/wxGauge.erl
@@ -39,29 +39,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -204,6 +204,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -520,6 +522,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxGenericDirCtrl.erl b/lib/wx/src/gen/wxGenericDirCtrl.erl
index 3ea99c682d..383d592269 100644
--- a/lib/wx/src/gen/wxGenericDirCtrl.erl
+++ b/lib/wx/src/gen/wxGenericDirCtrl.erl
@@ -41,29 +41,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -175,7 +175,7 @@ collapseTree(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec expandPath(This, Path) -> boolean() when
This::wxGenericDirCtrl(), Path::unicode:chardata().
expandPath(#wx_ref{type=ThisT,ref=ThisRef},Path)
- when is_list(Path) ->
+ when ?is_chardata(Path) ->
?CLASS(ThisT,wxGenericDirCtrl),
Path_UC = unicode:characters_to_binary([Path,0]),
wxe_util:call(?wxGenericDirCtrl_ExpandPath,
@@ -249,7 +249,7 @@ reCreateTree(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setDefaultPath(This, Path) -> 'ok' when
This::wxGenericDirCtrl(), Path::unicode:chardata().
setDefaultPath(#wx_ref{type=ThisT,ref=ThisRef},Path)
- when is_list(Path) ->
+ when ?is_chardata(Path) ->
?CLASS(ThisT,wxGenericDirCtrl),
Path_UC = unicode:characters_to_binary([Path,0]),
wxe_util:cast(?wxGenericDirCtrl_SetDefaultPath,
@@ -259,7 +259,7 @@ setDefaultPath(#wx_ref{type=ThisT,ref=ThisRef},Path)
-spec setFilter(This, Filter) -> 'ok' when
This::wxGenericDirCtrl(), Filter::unicode:chardata().
setFilter(#wx_ref{type=ThisT,ref=ThisRef},Filter)
- when is_list(Filter) ->
+ when ?is_chardata(Filter) ->
?CLASS(ThisT,wxGenericDirCtrl),
Filter_UC = unicode:characters_to_binary([Filter,0]),
wxe_util:cast(?wxGenericDirCtrl_SetFilter,
@@ -278,7 +278,7 @@ setFilterIndex(#wx_ref{type=ThisT,ref=ThisRef},N)
-spec setPath(This, Path) -> 'ok' when
This::wxGenericDirCtrl(), Path::unicode:chardata().
setPath(#wx_ref{type=ThisT,ref=ThisRef},Path)
- when is_list(Path) ->
+ when ?is_chardata(Path) ->
?CLASS(ThisT,wxGenericDirCtrl),
Path_UC = unicode:characters_to_binary([Path,0]),
wxe_util:cast(?wxGenericDirCtrl_SetPath,
@@ -297,6 +297,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -613,6 +615,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxGraphicsContext.erl b/lib/wx/src/gen/wxGraphicsContext.erl
index 0aa2119210..2d0271ac48 100644
--- a/lib/wx/src/gen/wxGraphicsContext.erl
+++ b/lib/wx/src/gen/wxGraphicsContext.erl
@@ -287,7 +287,7 @@ drawRoundedRectangle(#wx_ref{type=ThisT,ref=ThisRef},X,Y,W,H,Radius)
-spec drawText(This, Str, X, Y) -> 'ok' when
This::wxGraphicsContext(), Str::unicode:chardata(), X::number(), Y::number().
drawText(#wx_ref{type=ThisT,ref=ThisRef},Str,X,Y)
- when is_list(Str),is_number(X),is_number(Y) ->
+ when ?is_chardata(Str),is_number(X),is_number(Y) ->
?CLASS(ThisT,wxGraphicsContext),
Str_UC = unicode:characters_to_binary([Str,0]),
wxe_util:cast(?wxGraphicsContext_DrawText_3,
@@ -303,13 +303,13 @@ drawText(#wx_ref{type=ThisT,ref=ThisRef},Str,X,Y)
(This, Str, X, Y, BackgroundBrush) -> 'ok' when
This::wxGraphicsContext(), Str::unicode:chardata(), X::number(), Y::number(), BackgroundBrush::wxGraphicsBrush:wxGraphicsBrush().
drawText(#wx_ref{type=ThisT,ref=ThisRef},Str,X,Y,Angle)
- when is_list(Str),is_number(X),is_number(Y),is_number(Angle) ->
+ when ?is_chardata(Str),is_number(X),is_number(Y),is_number(Angle) ->
?CLASS(ThisT,wxGraphicsContext),
Str_UC = unicode:characters_to_binary([Str,0]),
wxe_util:cast(?wxGraphicsContext_DrawText_4_0,
<<ThisRef:32/?UI,(byte_size(Str_UC)):32/?UI,(Str_UC)/binary, 0:(((8- ((0+byte_size(Str_UC)) band 16#7)) band 16#7))/unit:8,X:64/?F,Y:64/?F,Angle:64/?F>>);
drawText(#wx_ref{type=ThisT,ref=ThisRef},Str,X,Y,#wx_ref{type=BackgroundBrushT,ref=BackgroundBrushRef})
- when is_list(Str),is_number(X),is_number(Y) ->
+ when ?is_chardata(Str),is_number(X),is_number(Y) ->
?CLASS(ThisT,wxGraphicsContext),
Str_UC = unicode:characters_to_binary([Str,0]),
?CLASS(BackgroundBrushT,wxGraphicsBrush),
@@ -320,7 +320,7 @@ drawText(#wx_ref{type=ThisT,ref=ThisRef},Str,X,Y,#wx_ref{type=BackgroundBrushT,r
-spec drawText(This, Str, X, Y, Angle, BackgroundBrush) -> 'ok' when
This::wxGraphicsContext(), Str::unicode:chardata(), X::number(), Y::number(), Angle::number(), BackgroundBrush::wxGraphicsBrush:wxGraphicsBrush().
drawText(#wx_ref{type=ThisT,ref=ThisRef},Str,X,Y,Angle,#wx_ref{type=BackgroundBrushT,ref=BackgroundBrushRef})
- when is_list(Str),is_number(X),is_number(Y),is_number(Angle) ->
+ when ?is_chardata(Str),is_number(X),is_number(Y),is_number(Angle) ->
?CLASS(ThisT,wxGraphicsContext),
Str_UC = unicode:characters_to_binary([Str,0]),
?CLASS(BackgroundBrushT,wxGraphicsBrush),
@@ -363,7 +363,7 @@ strokePath(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PathT,ref=PathRef}) ->
-spec getPartialTextExtents(This, Text) -> [number()] when
This::wxGraphicsContext(), Text::unicode:chardata().
getPartialTextExtents(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxGraphicsContext),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:call(?wxGraphicsContext_GetPartialTextExtents,
@@ -374,7 +374,7 @@ getPartialTextExtents(#wx_ref{type=ThisT,ref=ThisRef},Text)
Result ::{Width::number(), Height::number(), Descent::number(), ExternalLeading::number()},
This::wxGraphicsContext(), Text::unicode:chardata().
getTextExtent(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxGraphicsContext),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:call(?wxGraphicsContext_GetTextExtent,
diff --git a/lib/wx/src/gen/wxGrid.erl b/lib/wx/src/gen/wxGrid.erl
index a1533cbd9f..b8c94ab555 100644
--- a/lib/wx/src/gen/wxGrid.erl
+++ b/lib/wx/src/gen/wxGrid.erl
@@ -91,37 +91,37 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- doPrepareDC/2,enable/1,enable/2,enableScrolling/3,findWindow/2,fitInside/1,
- freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
- getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
- getClientSize/1,getContainingSizer/1,getCursor/1,getDropTarget/1,
- getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPixelsPerUnit/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getToolTip/1,getUpdateRegion/1,getViewStart/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scroll/3,
- scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFocusIgnoringChildren/1,setFont/2,setForegroundColour/2,setHelpText/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
- setScrollPos/4,setScrollRate/3,setScrollbar/5,setScrollbar/6,setScrollbars/5,
- setScrollbars/6,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
- setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
- setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,setToolTip/2,
- setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ doPrepareDC/2,dragAcceptFiles/2,enable/1,enable/2,enableScrolling/3,
+ findWindow/2,fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
+ getBackgroundStyle/1,getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,
+ getChildren/1,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
+ getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPixelsPerUnit/1,
+ getScrollPos/2,getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,
+ getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getViewStart/1,
+ getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
+ hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,raise/1,refresh/1,refresh/2,
+ refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,
+ screenToClient/1,screenToClient/2,scroll/3,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5,
+ setScrollbar/6,setScrollbars/5,setScrollbars/6,setSize/2,setSize/3,
+ setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,
+ setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
@@ -851,7 +851,7 @@ getDefaultEditorForCell(#wx_ref{type=ThisT,ref=ThisRef},Row,Col)
-spec getDefaultEditorForType(This, TypeName) -> wxGridCellEditor:wxGridCellEditor() when
This::wxGrid(), TypeName::unicode:chardata().
getDefaultEditorForType(#wx_ref{type=ThisT,ref=ThisRef},TypeName)
- when is_list(TypeName) ->
+ when ?is_chardata(TypeName) ->
?CLASS(ThisT,wxGrid),
TypeName_UC = unicode:characters_to_binary([TypeName,0]),
wxe_util:call(?wxGrid_GetDefaultEditorForType,
@@ -878,7 +878,7 @@ getDefaultRendererForCell(#wx_ref{type=ThisT,ref=ThisRef},Row,Col)
-spec getDefaultRendererForType(This, TypeName) -> wxGridCellRenderer:wxGridCellRenderer() when
This::wxGrid(), TypeName::unicode:chardata().
getDefaultRendererForType(#wx_ref{type=ThisT,ref=ThisRef},TypeName)
- when is_list(TypeName) ->
+ when ?is_chardata(TypeName) ->
?CLASS(ThisT,wxGrid),
TypeName_UC = unicode:characters_to_binary([TypeName,0]),
wxe_util:call(?wxGrid_GetDefaultRendererForType,
@@ -1407,7 +1407,7 @@ movePageUp(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec registerDataType(This, TypeName, Renderer, Editor) -> 'ok' when
This::wxGrid(), TypeName::unicode:chardata(), Renderer::wxGridCellRenderer:wxGridCellRenderer(), Editor::wxGridCellEditor:wxGridCellEditor().
registerDataType(#wx_ref{type=ThisT,ref=ThisRef},TypeName,#wx_ref{type=RendererT,ref=RendererRef},#wx_ref{type=EditorT,ref=EditorRef})
- when is_list(TypeName) ->
+ when ?is_chardata(TypeName) ->
?CLASS(ThisT,wxGrid),
TypeName_UC = unicode:characters_to_binary([TypeName,0]),
?CLASS(RendererT,wxGridCellRenderer),
@@ -1634,7 +1634,7 @@ setCellTextColour(#wx_ref{type=ThisT,ref=ThisRef},Val,Row,Col)
-spec setCellValue(This, Coords, S) -> 'ok' when
This::wxGrid(), Coords::{R::integer(), C::integer()}, S::unicode:chardata().
setCellValue(#wx_ref{type=ThisT,ref=ThisRef},{CoordsR,CoordsC},S)
- when is_integer(CoordsR),is_integer(CoordsC),is_list(S) ->
+ when is_integer(CoordsR),is_integer(CoordsC),?is_chardata(S) ->
?CLASS(ThisT,wxGrid),
S_UC = unicode:characters_to_binary([S,0]),
wxe_util:cast(?wxGrid_SetCellValue_2,
@@ -1650,13 +1650,13 @@ setCellValue(#wx_ref{type=ThisT,ref=ThisRef},{CoordsR,CoordsC},S)
(This, Val, Row, Col) -> 'ok' when
This::wxGrid(), Val::unicode:chardata(), Row::integer(), Col::integer().
setCellValue(#wx_ref{type=ThisT,ref=ThisRef},Row,Col,S)
- when is_integer(Row),is_integer(Col),is_list(S) ->
+ when is_integer(Row),is_integer(Col),?is_chardata(S) ->
?CLASS(ThisT,wxGrid),
S_UC = unicode:characters_to_binary([S,0]),
wxe_util:cast(?wxGrid_SetCellValue_3_0,
<<ThisRef:32/?UI,Row:32/?UI,Col:32/?UI,(byte_size(S_UC)):32/?UI,(S_UC)/binary, 0:(((8- ((0+byte_size(S_UC)) band 16#7)) band 16#7))/unit:8>>);
setCellValue(#wx_ref{type=ThisT,ref=ThisRef},Val,Row,Col)
- when is_list(Val),is_integer(Row),is_integer(Col) ->
+ when ?is_chardata(Val),is_integer(Row),is_integer(Col) ->
?CLASS(ThisT,wxGrid),
Val_UC = unicode:characters_to_binary([Val,0]),
wxe_util:cast(?wxGrid_SetCellValue_3_1,
@@ -1717,7 +1717,7 @@ setColFormatFloat(#wx_ref{type=ThisT,ref=ThisRef},Col, Options)
-spec setColFormatCustom(This, Col, TypeName) -> 'ok' when
This::wxGrid(), Col::integer(), TypeName::unicode:chardata().
setColFormatCustom(#wx_ref{type=ThisT,ref=ThisRef},Col,TypeName)
- when is_integer(Col),is_list(TypeName) ->
+ when is_integer(Col),?is_chardata(TypeName) ->
?CLASS(ThisT,wxGrid),
TypeName_UC = unicode:characters_to_binary([TypeName,0]),
wxe_util:cast(?wxGrid_SetColFormatCustom,
@@ -1745,7 +1745,7 @@ setColLabelSize(#wx_ref{type=ThisT,ref=ThisRef},Height)
-spec setColLabelValue(This, Col, Val) -> 'ok' when
This::wxGrid(), Col::integer(), Val::unicode:chardata().
setColLabelValue(#wx_ref{type=ThisT,ref=ThisRef},Col,Val)
- when is_integer(Col),is_list(Val) ->
+ when is_integer(Col),?is_chardata(Val) ->
?CLASS(ThisT,wxGrid),
Val_UC = unicode:characters_to_binary([Val,0]),
wxe_util:cast(?wxGrid_SetColLabelValue,
@@ -1981,7 +1981,7 @@ setRowLabelSize(#wx_ref{type=ThisT,ref=ThisRef},Width)
-spec setRowLabelValue(This, Row, Val) -> 'ok' when
This::wxGrid(), Row::integer(), Val::unicode:chardata().
setRowLabelValue(#wx_ref{type=ThisT,ref=ThisRef},Row,Val)
- when is_integer(Row),is_list(Val) ->
+ when is_integer(Row),?is_chardata(Val) ->
?CLASS(ThisT,wxGrid),
Val_UC = unicode:characters_to_binary([Val,0]),
wxe_util:cast(?wxGrid_SetRowLabelValue,
@@ -2158,6 +2158,8 @@ setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This).
initDialog(This) -> wxPanel:initDialog(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -2474,6 +2476,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxGridCellBoolEditor.erl b/lib/wx/src/gen/wxGridCellBoolEditor.erl
index 1d949d54ff..59348f94f8 100644
--- a/lib/wx/src/gen/wxGridCellBoolEditor.erl
+++ b/lib/wx/src/gen/wxGridCellBoolEditor.erl
@@ -52,7 +52,7 @@ new() ->
-spec isTrueValue(Value) -> boolean() when
Value::unicode:chardata().
isTrueValue(Value)
- when is_list(Value) ->
+ when ?is_chardata(Value) ->
Value_UC = unicode:characters_to_binary([Value,0]),
wxe_util:call(?wxGridCellBoolEditor_IsTrueValue,
<<(byte_size(Value_UC)):32/?UI,(Value_UC)/binary, 0:(((8- ((4+byte_size(Value_UC)) band 16#7)) band 16#7))/unit:8>>).
diff --git a/lib/wx/src/gen/wxGridCellChoiceEditor.erl b/lib/wx/src/gen/wxGridCellChoiceEditor.erl
index d5487c3618..8f4a07a0bb 100644
--- a/lib/wx/src/gen/wxGridCellChoiceEditor.erl
+++ b/lib/wx/src/gen/wxGridCellChoiceEditor.erl
@@ -68,7 +68,7 @@ new(Choices, Options)
-spec setParameters(This, Params) -> 'ok' when
This::wxGridCellChoiceEditor(), Params::unicode:chardata().
setParameters(#wx_ref{type=ThisT,ref=ThisRef},Params)
- when is_list(Params) ->
+ when ?is_chardata(Params) ->
?CLASS(ThisT,wxGridCellChoiceEditor),
Params_UC = unicode:characters_to_binary([Params,0]),
wxe_util:cast(?wxGridCellChoiceEditor_SetParameters,
diff --git a/lib/wx/src/gen/wxGridCellFloatEditor.erl b/lib/wx/src/gen/wxGridCellFloatEditor.erl
index 6e85469ecf..90b9542afc 100644
--- a/lib/wx/src/gen/wxGridCellFloatEditor.erl
+++ b/lib/wx/src/gen/wxGridCellFloatEditor.erl
@@ -65,7 +65,7 @@ new(Options)
-spec setParameters(This, Params) -> 'ok' when
This::wxGridCellFloatEditor(), Params::unicode:chardata().
setParameters(#wx_ref{type=ThisT,ref=ThisRef},Params)
- when is_list(Params) ->
+ when ?is_chardata(Params) ->
?CLASS(ThisT,wxGridCellFloatEditor),
Params_UC = unicode:characters_to_binary([Params,0]),
wxe_util:cast(?wxGridCellFloatEditor_SetParameters,
diff --git a/lib/wx/src/gen/wxGridCellFloatRenderer.erl b/lib/wx/src/gen/wxGridCellFloatRenderer.erl
index ccb29902b3..72bdc6fc29 100644
--- a/lib/wx/src/gen/wxGridCellFloatRenderer.erl
+++ b/lib/wx/src/gen/wxGridCellFloatRenderer.erl
@@ -81,7 +81,7 @@ getWidth(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setParameters(This, Params) -> 'ok' when
This::wxGridCellFloatRenderer(), Params::unicode:chardata().
setParameters(#wx_ref{type=ThisT,ref=ThisRef},Params)
- when is_list(Params) ->
+ when ?is_chardata(Params) ->
?CLASS(ThisT,wxGridCellFloatRenderer),
Params_UC = unicode:characters_to_binary([Params,0]),
wxe_util:cast(?wxGridCellFloatRenderer_SetParameters,
diff --git a/lib/wx/src/gen/wxGridCellNumberEditor.erl b/lib/wx/src/gen/wxGridCellNumberEditor.erl
index 7a47024b2f..22f9a1839c 100644
--- a/lib/wx/src/gen/wxGridCellNumberEditor.erl
+++ b/lib/wx/src/gen/wxGridCellNumberEditor.erl
@@ -75,7 +75,7 @@ getValue(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setParameters(This, Params) -> 'ok' when
This::wxGridCellNumberEditor(), Params::unicode:chardata().
setParameters(#wx_ref{type=ThisT,ref=ThisRef},Params)
- when is_list(Params) ->
+ when ?is_chardata(Params) ->
?CLASS(ThisT,wxGridCellNumberEditor),
Params_UC = unicode:characters_to_binary([Params,0]),
wxe_util:cast(?wxGridCellNumberEditor_SetParameters,
diff --git a/lib/wx/src/gen/wxGridCellTextEditor.erl b/lib/wx/src/gen/wxGridCellTextEditor.erl
index 4ddb4a7028..39adda5d8b 100644
--- a/lib/wx/src/gen/wxGridCellTextEditor.erl
+++ b/lib/wx/src/gen/wxGridCellTextEditor.erl
@@ -52,7 +52,7 @@ new() ->
-spec setParameters(This, Params) -> 'ok' when
This::wxGridCellTextEditor(), Params::unicode:chardata().
setParameters(#wx_ref{type=ThisT,ref=ThisRef},Params)
- when is_list(Params) ->
+ when ?is_chardata(Params) ->
?CLASS(ThisT,wxGridCellTextEditor),
Params_UC = unicode:characters_to_binary([Params,0]),
wxe_util:cast(?wxGridCellTextEditor_SetParameters,
diff --git a/lib/wx/src/gen/wxHtmlEasyPrinting.erl b/lib/wx/src/gen/wxHtmlEasyPrinting.erl
index a2cf46ed8d..dfb9dcfa1c 100644
--- a/lib/wx/src/gen/wxHtmlEasyPrinting.erl
+++ b/lib/wx/src/gen/wxHtmlEasyPrinting.erl
@@ -77,7 +77,7 @@ getPageSetupData(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec previewFile(This, Htmlfile) -> boolean() when
This::wxHtmlEasyPrinting(), Htmlfile::unicode:chardata().
previewFile(#wx_ref{type=ThisT,ref=ThisRef},Htmlfile)
- when is_list(Htmlfile) ->
+ when ?is_chardata(Htmlfile) ->
?CLASS(ThisT,wxHtmlEasyPrinting),
Htmlfile_UC = unicode:characters_to_binary([Htmlfile,0]),
wxe_util:call(?wxHtmlEasyPrinting_PreviewFile,
@@ -88,7 +88,7 @@ previewFile(#wx_ref{type=ThisT,ref=ThisRef},Htmlfile)
This::wxHtmlEasyPrinting(), Htmltext::unicode:chardata().
previewText(This,Htmltext)
- when is_record(This, wx_ref),is_list(Htmltext) ->
+ when is_record(This, wx_ref),?is_chardata(Htmltext) ->
previewText(This,Htmltext, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxhtmleasyprinting.html#wxhtmleasyprintingpreviewtext">external documentation</a>.
@@ -96,7 +96,7 @@ previewText(This,Htmltext)
This::wxHtmlEasyPrinting(), Htmltext::unicode:chardata(),
Option :: {'basepath', unicode:chardata()}.
previewText(#wx_ref{type=ThisT,ref=ThisRef},Htmltext, Options)
- when is_list(Htmltext),is_list(Options) ->
+ when ?is_chardata(Htmltext),is_list(Options) ->
?CLASS(ThisT,wxHtmlEasyPrinting),
Htmltext_UC = unicode:characters_to_binary([Htmltext,0]),
MOpts = fun({basepath, Basepath}, Acc) -> Basepath_UC = unicode:characters_to_binary([Basepath,0]),[<<1:32/?UI,(byte_size(Basepath_UC)):32/?UI,(Basepath_UC)/binary, 0:(((8- ((0+byte_size(Basepath_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -109,7 +109,7 @@ previewText(#wx_ref{type=ThisT,ref=ThisRef},Htmltext, Options)
-spec printFile(This, Htmlfile) -> boolean() when
This::wxHtmlEasyPrinting(), Htmlfile::unicode:chardata().
printFile(#wx_ref{type=ThisT,ref=ThisRef},Htmlfile)
- when is_list(Htmlfile) ->
+ when ?is_chardata(Htmlfile) ->
?CLASS(ThisT,wxHtmlEasyPrinting),
Htmlfile_UC = unicode:characters_to_binary([Htmlfile,0]),
wxe_util:call(?wxHtmlEasyPrinting_PrintFile,
@@ -120,7 +120,7 @@ printFile(#wx_ref{type=ThisT,ref=ThisRef},Htmlfile)
This::wxHtmlEasyPrinting(), Htmltext::unicode:chardata().
printText(This,Htmltext)
- when is_record(This, wx_ref),is_list(Htmltext) ->
+ when is_record(This, wx_ref),?is_chardata(Htmltext) ->
printText(This,Htmltext, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxhtmleasyprinting.html#wxhtmleasyprintingprinttext">external documentation</a>.
@@ -128,7 +128,7 @@ printText(This,Htmltext)
This::wxHtmlEasyPrinting(), Htmltext::unicode:chardata(),
Option :: {'basepath', unicode:chardata()}.
printText(#wx_ref{type=ThisT,ref=ThisRef},Htmltext, Options)
- when is_list(Htmltext),is_list(Options) ->
+ when ?is_chardata(Htmltext),is_list(Options) ->
?CLASS(ThisT,wxHtmlEasyPrinting),
Htmltext_UC = unicode:characters_to_binary([Htmltext,0]),
MOpts = fun({basepath, Basepath}, Acc) -> Basepath_UC = unicode:characters_to_binary([Basepath,0]),[<<1:32/?UI,(byte_size(Basepath_UC)):32/?UI,(Basepath_UC)/binary, 0:(((8- ((0+byte_size(Basepath_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -150,7 +150,7 @@ pageSetup(#wx_ref{type=ThisT,ref=ThisRef}) ->
This::wxHtmlEasyPrinting(), Normal_face::unicode:chardata(), Fixed_face::unicode:chardata().
setFonts(This,Normal_face,Fixed_face)
- when is_record(This, wx_ref),is_list(Normal_face),is_list(Fixed_face) ->
+ when is_record(This, wx_ref),?is_chardata(Normal_face),?is_chardata(Fixed_face) ->
setFonts(This,Normal_face,Fixed_face, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxhtmleasyprinting.html#wxhtmleasyprintingsetfonts">external documentation</a>.
@@ -158,7 +158,7 @@ setFonts(This,Normal_face,Fixed_face)
This::wxHtmlEasyPrinting(), Normal_face::unicode:chardata(), Fixed_face::unicode:chardata(),
Option :: {'sizes', [integer()]}.
setFonts(#wx_ref{type=ThisT,ref=ThisRef},Normal_face,Fixed_face, Options)
- when is_list(Normal_face),is_list(Fixed_face),is_list(Options) ->
+ when ?is_chardata(Normal_face),?is_chardata(Fixed_face),is_list(Options) ->
?CLASS(ThisT,wxHtmlEasyPrinting),
Normal_face_UC = unicode:characters_to_binary([Normal_face,0]),
Fixed_face_UC = unicode:characters_to_binary([Fixed_face,0]),
@@ -174,7 +174,7 @@ setFonts(#wx_ref{type=ThisT,ref=ThisRef},Normal_face,Fixed_face, Options)
This::wxHtmlEasyPrinting(), Header::unicode:chardata().
setHeader(This,Header)
- when is_record(This, wx_ref),is_list(Header) ->
+ when is_record(This, wx_ref),?is_chardata(Header) ->
setHeader(This,Header, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxhtmleasyprinting.html#wxhtmleasyprintingsetheader">external documentation</a>.
@@ -182,7 +182,7 @@ setHeader(This,Header)
This::wxHtmlEasyPrinting(), Header::unicode:chardata(),
Option :: {'pg', integer()}.
setHeader(#wx_ref{type=ThisT,ref=ThisRef},Header, Options)
- when is_list(Header),is_list(Options) ->
+ when ?is_chardata(Header),is_list(Options) ->
?CLASS(ThisT,wxHtmlEasyPrinting),
Header_UC = unicode:characters_to_binary([Header,0]),
MOpts = fun({pg, Pg}, Acc) -> [<<1:32/?UI,Pg:32/?UI>>|Acc];
@@ -196,7 +196,7 @@ setHeader(#wx_ref{type=ThisT,ref=ThisRef},Header, Options)
This::wxHtmlEasyPrinting(), Footer::unicode:chardata().
setFooter(This,Footer)
- when is_record(This, wx_ref),is_list(Footer) ->
+ when is_record(This, wx_ref),?is_chardata(Footer) ->
setFooter(This,Footer, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxhtmleasyprinting.html#wxhtmleasyprintingsetfooter">external documentation</a>.
@@ -204,7 +204,7 @@ setFooter(This,Footer)
This::wxHtmlEasyPrinting(), Footer::unicode:chardata(),
Option :: {'pg', integer()}.
setFooter(#wx_ref{type=ThisT,ref=ThisRef},Footer, Options)
- when is_list(Footer),is_list(Options) ->
+ when ?is_chardata(Footer),is_list(Options) ->
?CLASS(ThisT,wxHtmlEasyPrinting),
Footer_UC = unicode:characters_to_binary([Footer,0]),
MOpts = fun({pg, Pg}, Acc) -> [<<1:32/?UI,Pg:32/?UI>>|Acc];
diff --git a/lib/wx/src/gen/wxHtmlWindow.erl b/lib/wx/src/gen/wxHtmlWindow.erl
index f9bb135fcf..7e3906b9a9 100644
--- a/lib/wx/src/gen/wxHtmlWindow.erl
+++ b/lib/wx/src/gen/wxHtmlWindow.erl
@@ -45,37 +45,37 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- doPrepareDC/2,enable/1,enable/2,enableScrolling/3,findWindow/2,fit/1,
- fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
+ doPrepareDC/2,dragAcceptFiles/2,enable/1,enable/2,enableScrolling/3,
+ findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
getBackgroundStyle/1,getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,
- getChildren/1,getClientSize/1,getContainingSizer/1,getCursor/1,getDropTarget/1,
- getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPixelsPerUnit/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getToolTip/1,getUpdateRegion/1,getViewStart/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scroll/3,
- scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFocusIgnoringChildren/1,setFont/2,setForegroundColour/2,setHelpText/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
- setScrollPos/4,setScrollRate/3,setScrollbar/5,setScrollbar/6,setScrollbars/5,
- setScrollbars/6,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
- setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
- setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,setToolTip/2,
- setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ getChildren/1,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
+ getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPixelsPerUnit/1,
+ getScrollPos/2,getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,
+ getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getViewStart/1,
+ getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
+ hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,raise/1,refresh/1,refresh/2,
+ refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,
+ screenToClient/1,screenToClient/2,scroll/3,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5,
+ setScrollbar/6,setScrollbars/5,setScrollbars/6,setSize/2,setSize/3,
+ setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,
+ setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
@@ -127,7 +127,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef}, Options)
-spec appendToPage(This, Source) -> boolean() when
This::wxHtmlWindow(), Source::unicode:chardata().
appendToPage(#wx_ref{type=ThisT,ref=ThisRef},Source)
- when is_list(Source) ->
+ when ?is_chardata(Source) ->
?CLASS(ThisT,wxHtmlWindow),
Source_UC = unicode:characters_to_binary([Source,0]),
wxe_util:call(?wxHtmlWindow_AppendToPage,
@@ -209,7 +209,7 @@ historyForward(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec loadFile(This, Filename) -> boolean() when
This::wxHtmlWindow(), Filename::unicode:chardata().
loadFile(#wx_ref{type=ThisT,ref=ThisRef},Filename)
- when is_list(Filename) ->
+ when ?is_chardata(Filename) ->
?CLASS(ThisT,wxHtmlWindow),
Filename_UC = unicode:characters_to_binary([Filename,0]),
wxe_util:call(?wxHtmlWindow_LoadFile,
@@ -219,7 +219,7 @@ loadFile(#wx_ref{type=ThisT,ref=ThisRef},Filename)
-spec loadPage(This, Location) -> boolean() when
This::wxHtmlWindow(), Location::unicode:chardata().
loadPage(#wx_ref{type=ThisT,ref=ThisRef},Location)
- when is_list(Location) ->
+ when ?is_chardata(Location) ->
?CLASS(ThisT,wxHtmlWindow),
Location_UC = unicode:characters_to_binary([Location,0]),
wxe_util:call(?wxHtmlWindow_LoadPage,
@@ -273,7 +273,7 @@ setBorders(#wx_ref{type=ThisT,ref=ThisRef},B)
This::wxHtmlWindow(), Normal_face::unicode:chardata(), Fixed_face::unicode:chardata().
setFonts(This,Normal_face,Fixed_face)
- when is_record(This, wx_ref),is_list(Normal_face),is_list(Fixed_face) ->
+ when is_record(This, wx_ref),?is_chardata(Normal_face),?is_chardata(Fixed_face) ->
setFonts(This,Normal_face,Fixed_face, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxhtmlwindow.html#wxhtmlwindowsetfonts">external documentation</a>.
@@ -281,7 +281,7 @@ setFonts(This,Normal_face,Fixed_face)
This::wxHtmlWindow(), Normal_face::unicode:chardata(), Fixed_face::unicode:chardata(),
Option :: {'sizes', integer()}.
setFonts(#wx_ref{type=ThisT,ref=ThisRef},Normal_face,Fixed_face, Options)
- when is_list(Normal_face),is_list(Fixed_face),is_list(Options) ->
+ when ?is_chardata(Normal_face),?is_chardata(Fixed_face),is_list(Options) ->
?CLASS(ThisT,wxHtmlWindow),
Normal_face_UC = unicode:characters_to_binary([Normal_face,0]),
Fixed_face_UC = unicode:characters_to_binary([Fixed_face,0]),
@@ -295,7 +295,7 @@ setFonts(#wx_ref{type=ThisT,ref=ThisRef},Normal_face,Fixed_face, Options)
-spec setPage(This, Source) -> boolean() when
This::wxHtmlWindow(), Source::unicode:chardata().
setPage(#wx_ref{type=ThisT,ref=ThisRef},Source)
- when is_list(Source) ->
+ when ?is_chardata(Source) ->
?CLASS(ThisT,wxHtmlWindow),
Source_UC = unicode:characters_to_binary([Source,0]),
wxe_util:call(?wxHtmlWindow_SetPage,
@@ -305,7 +305,7 @@ setPage(#wx_ref{type=ThisT,ref=ThisRef},Source)
-spec setRelatedFrame(This, Frame, Format) -> 'ok' when
This::wxHtmlWindow(), Frame::wxFrame:wxFrame(), Format::unicode:chardata().
setRelatedFrame(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=FrameT,ref=FrameRef},Format)
- when is_list(Format) ->
+ when ?is_chardata(Format) ->
?CLASS(ThisT,wxHtmlWindow),
?CLASS(FrameT,wxFrame),
Format_UC = unicode:characters_to_binary([Format,0]),
@@ -371,6 +371,8 @@ setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This).
initDialog(This) -> wxPanel:initDialog(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -689,6 +691,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxIcon.erl b/lib/wx/src/gen/wxIcon.erl
index c9ec32dffc..9739a403ff 100644
--- a/lib/wx/src/gen/wxIcon.erl
+++ b/lib/wx/src/gen/wxIcon.erl
@@ -60,7 +60,7 @@ new() ->
Loc::wx:wx_object().
new(Filename)
- when is_list(Filename) ->
+ when ?is_chardata(Filename) ->
new(Filename, []);
new(#wx_ref{type=LocT,ref=LocRef}) ->
?CLASS(LocT,wx),
@@ -75,7 +75,7 @@ new(#wx_ref{type=LocT,ref=LocRef}) ->
| {'desiredWidth', integer()}
| {'desiredHeight', integer()}.
new(Filename, Options)
- when is_list(Filename),is_list(Options) ->
+ when ?is_chardata(Filename),is_list(Options) ->
Filename_UC = unicode:characters_to_binary([Filename,0]),
MOpts = fun({type, Type}, Acc) -> [<<1:32/?UI,Type:32/?UI>>|Acc];
({desiredWidth, DesiredWidth}, Acc) -> [<<2:32/?UI,DesiredWidth:32/?UI>>|Acc];
diff --git a/lib/wx/src/gen/wxIconBundle.erl b/lib/wx/src/gen/wxIconBundle.erl
index 47785963e3..aecf382a9f 100644
--- a/lib/wx/src/gen/wxIconBundle.erl
+++ b/lib/wx/src/gen/wxIconBundle.erl
@@ -58,7 +58,7 @@ new(#wx_ref{type=IcT,ref=IcRef}) ->
-spec new(File, Type) -> wxIconBundle() when
File::unicode:chardata(), Type::integer().
new(File,Type)
- when is_list(File),is_integer(Type) ->
+ when ?is_chardata(File),is_integer(Type) ->
File_UC = unicode:characters_to_binary([File,0]),
wxe_util:construct(?wxIconBundle_new_2,
<<(byte_size(File_UC)):32/?UI,(File_UC)/binary, 0:(((8- ((4+byte_size(File_UC)) band 16#7)) band 16#7))/unit:8,Type:32/?UI>>).
@@ -76,7 +76,7 @@ addIcon(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=IconT,ref=IconRef}) ->
-spec addIcon(This, File, Type) -> 'ok' when
This::wxIconBundle(), File::unicode:chardata(), Type::integer().
addIcon(#wx_ref{type=ThisT,ref=ThisRef},File,Type)
- when is_list(File),is_integer(Type) ->
+ when ?is_chardata(File),is_integer(Type) ->
?CLASS(ThisT,wxIconBundle),
File_UC = unicode:characters_to_binary([File,0]),
wxe_util:cast(?wxIconBundle_AddIcon_2,
diff --git a/lib/wx/src/gen/wxImage.erl b/lib/wx/src/gen/wxImage.erl
index e82f3d609e..f3b3d393d1 100644
--- a/lib/wx/src/gen/wxImage.erl
+++ b/lib/wx/src/gen/wxImage.erl
@@ -64,7 +64,7 @@ new() ->
Name::unicode:chardata().
new(Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
new(Name, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wximage.html#wximagewximage">external documentation</a>.
@@ -85,7 +85,7 @@ new(Width,Height)
when is_integer(Width),is_integer(Height) ->
new(Width,Height, []);
new(Name, Options)
- when is_list(Name),is_list(Options) ->
+ when ?is_chardata(Name),is_list(Options) ->
Name_UC = unicode:characters_to_binary([Name,0]),
MOpts = fun({type, Type}, Acc) -> [<<1:32/?UI,Type:32/?UI>>|Acc];
({index, Index}, Acc) -> [<<2:32/?UI,Index:32/?UI>>|Acc];
@@ -123,7 +123,7 @@ new(Width,Height, Options)
wxe_util:construct(?wxImage_new_3_0,
<<Width:32/?UI,Height:32/?UI, BinOpt/binary>>);
new(Name,Mimetype, Options)
- when is_list(Name),is_list(Mimetype),is_list(Options) ->
+ when ?is_chardata(Name),?is_chardata(Mimetype),is_list(Options) ->
Name_UC = unicode:characters_to_binary([Name,0]),
Mimetype_UC = unicode:characters_to_binary([Mimetype,0]),
MOpts = fun({index, Index}, Acc) -> [<<1:32/?UI,Index:32/?UI>>|Acc];
@@ -421,7 +421,7 @@ getGreen(#wx_ref{type=ThisT,ref=ThisRef},X,Y)
Name::unicode:chardata().
getImageCount(Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
getImageCount(Name, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wximage.html#wximagegetimagecount">external documentation</a>.
@@ -430,7 +430,7 @@ getImageCount(Name)
Name::unicode:chardata(),
Option :: {'type', wx:wx_enum()}.
getImageCount(Name, Options)
- when is_list(Name),is_list(Options) ->
+ when ?is_chardata(Name),is_list(Options) ->
Name_UC = unicode:characters_to_binary([Name,0]),
MOpts = fun({type, Type}, Acc) -> [<<1:32/?UI,Type:32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
@@ -533,7 +533,7 @@ hasMask(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec getOption(This, Name) -> unicode:charlist() when
This::wxImage(), Name::unicode:chardata().
getOption(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxImage),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxImage_GetOption,
@@ -543,7 +543,7 @@ getOption(#wx_ref{type=ThisT,ref=ThisRef},Name)
-spec getOptionInt(This, Name) -> integer() when
This::wxImage(), Name::unicode:chardata().
getOptionInt(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxImage),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxImage_GetOptionInt,
@@ -553,7 +553,7 @@ getOptionInt(#wx_ref{type=ThisT,ref=ThisRef},Name)
-spec hasOption(This, Name) -> boolean() when
This::wxImage(), Name::unicode:chardata().
hasOption(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxImage),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxImage_HasOption,
@@ -599,7 +599,7 @@ isTransparent(#wx_ref{type=ThisT,ref=ThisRef},X,Y, Options)
This::wxImage(), Name::unicode:chardata().
loadFile(This,Name)
- when is_record(This, wx_ref),is_list(Name) ->
+ when is_record(This, wx_ref),?is_chardata(Name) ->
loadFile(This,Name, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wximage.html#wximageloadfile">external documentation</a>.
@@ -608,7 +608,7 @@ loadFile(This,Name)
Option :: {'type', integer()}
| {'index', integer()}.
loadFile(#wx_ref{type=ThisT,ref=ThisRef},Name, Options)
- when is_list(Name),is_list(Options) ->
+ when ?is_chardata(Name),is_list(Options) ->
?CLASS(ThisT,wxImage),
Name_UC = unicode:characters_to_binary([Name,0]),
MOpts = fun({type, Type}, Acc) -> [<<1:32/?UI,Type:32/?UI>>|Acc];
@@ -623,7 +623,7 @@ loadFile(#wx_ref{type=ThisT,ref=ThisRef},Name, Options)
This::wxImage(), Name::unicode:chardata(), Mimetype::unicode:chardata(),
Option :: {'index', integer()}.
loadFile(#wx_ref{type=ThisT,ref=ThisRef},Name,Mimetype, Options)
- when is_list(Name),is_list(Mimetype),is_list(Options) ->
+ when ?is_chardata(Name),?is_chardata(Mimetype),is_list(Options) ->
?CLASS(ThisT,wxImage),
Name_UC = unicode:characters_to_binary([Name,0]),
Mimetype_UC = unicode:characters_to_binary([Mimetype,0]),
@@ -645,7 +645,7 @@ ok(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec removeHandler(Name) -> boolean() when
Name::unicode:chardata().
removeHandler(Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxImage_RemoveHandler,
<<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8>>).
@@ -784,7 +784,7 @@ rotate90(#wx_ref{type=ThisT,ref=ThisRef}, Options)
-spec saveFile(This, Name) -> boolean() when
This::wxImage(), Name::unicode:chardata().
saveFile(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxImage),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxImage_SaveFile_1,
@@ -800,13 +800,13 @@ saveFile(#wx_ref{type=ThisT,ref=ThisRef},Name)
(This, Name, Mimetype) -> boolean() when
This::wxImage(), Name::unicode:chardata(), Mimetype::unicode:chardata().
saveFile(#wx_ref{type=ThisT,ref=ThisRef},Name,Type)
- when is_list(Name),is_integer(Type) ->
+ when ?is_chardata(Name),is_integer(Type) ->
?CLASS(ThisT,wxImage),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxImage_SaveFile_2_0,
<<ThisRef:32/?UI,(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((0+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8,Type:32/?UI>>);
saveFile(#wx_ref{type=ThisT,ref=ThisRef},Name,Mimetype)
- when is_list(Name),is_list(Mimetype) ->
+ when ?is_chardata(Name),?is_chardata(Mimetype) ->
?CLASS(ThisT,wxImage),
Name_UC = unicode:characters_to_binary([Name,0]),
Mimetype_UC = unicode:characters_to_binary([Mimetype,0]),
@@ -985,13 +985,13 @@ setMaskFromImage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=MaskT,ref=MaskRef}
(This, Name, Value) -> 'ok' when
This::wxImage(), Name::unicode:chardata(), Value::unicode:chardata().
setOption(#wx_ref{type=ThisT,ref=ThisRef},Name,Value)
- when is_list(Name),is_integer(Value) ->
+ when ?is_chardata(Name),is_integer(Value) ->
?CLASS(ThisT,wxImage),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:cast(?wxImage_SetOption_2_0,
<<ThisRef:32/?UI,(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((0+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8,Value:32/?UI>>);
setOption(#wx_ref{type=ThisT,ref=ThisRef},Name,Value)
- when is_list(Name),is_list(Value) ->
+ when ?is_chardata(Name),?is_chardata(Value) ->
?CLASS(ThisT,wxImage),
Name_UC = unicode:characters_to_binary([Name,0]),
Value_UC = unicode:characters_to_binary([Value,0]),
diff --git a/lib/wx/src/gen/wxListBox.erl b/lib/wx/src/gen/wxListBox.erl
index 9ab3616e9b..86d8d41f36 100644
--- a/lib/wx/src/gen/wxListBox.erl
+++ b/lib/wx/src/gen/wxListBox.erl
@@ -40,40 +40,41 @@
centre/1,centre/2,centreOnParent/1,centreOnParent/2,clear/1,clearBackground/1,
clientToScreen/2,clientToScreen/3,close/1,close/2,connect/2,connect/3,
convertDialogToPixels/2,convertPixelsToDialog/2,delete/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- findString/2,findString/3,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientData/2,getClientSize/1,
- getContainingSizer/1,getCount/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,getMinSize/1,
- getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
- getSelection/1,getSize/1,getSizer/1,getString/2,getStringSelection/1,
- getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
- getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
- hasTransparentBackground/1,hide/1,inheritAttributes/1,initDialog/1,
- insert/3,insert/4,invalidateBestSize/1,isDoubleBuffered/1,isEmpty/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,select/2,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientData/3,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
- setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
- setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
- setSelection/2,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
- setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
- setSizerAndFit/3,setString/3,setStringSelection/2,setThemeEnabled/2,
- setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
- setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
- setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,findString/2,findString/3,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientData/2,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCount/1,getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,
+ getFont/1,getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSelection/1,getSize/1,getSizer/1,
+ getString/2,getStringSelection/1,getTextExtent/2,getTextExtent/3,
+ getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
+ getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
+ hide/1,inheritAttributes/1,initDialog/1,insert/3,insert/4,invalidateBestSize/1,
+ isDoubleBuffered/1,isEmpty/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
+ isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,
+ makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,select/2,setAcceleratorTable/2,
+ setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
+ setClientData/3,setClientSize/2,setClientSize/3,setContainingSizer/2,
+ setCursor/2,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,
+ setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,setId/2,
+ setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSelection/2,setSize/2,
+ setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
+ setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setString/3,
+ setStringSelection/2,setThemeEnabled/2,setToolTip/2,setTransparent/2,
+ setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
+ setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
+ shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
validate/1,warpPointer/3]).
@@ -220,7 +221,7 @@ setFirstItem(#wx_ref{type=ThisT,ref=ThisRef},N)
wxe_util:cast(?wxListBox_SetFirstItem_1_0,
<<ThisRef:32/?UI,N:32/?UI>>);
setFirstItem(#wx_ref{type=ThisT,ref=ThisRef},S)
- when is_list(S) ->
+ when ?is_chardata(S) ->
?CLASS(ThisT,wxListBox),
S_UC = unicode:characters_to_binary([S,0]),
wxe_util:cast(?wxListBox_SetFirstItem_1_1,
@@ -280,6 +281,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -596,6 +599,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxListCtrl.erl b/lib/wx/src/gen/wxListCtrl.erl
index d1a063d900..10dc76f276 100644
--- a/lib/wx/src/gen/wxListCtrl.erl
+++ b/lib/wx/src/gen/wxListCtrl.erl
@@ -52,38 +52,38 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
- setCursor/2,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,
- setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,setId/2,
- setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
- setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
- setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,setToolTip/2,
- setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
- setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowVariant/2,
- shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
- transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
- validate/1,warpPointer/3]).
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundStyle/2,setCaret/2,
+ setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ setWindowStyle/2,setWindowVariant/2,shouldInheritColours/1,show/1,
+ show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,update/1,
+ updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
-export_type([wxListCtrl/0]).
%% @hidden
@@ -94,31 +94,34 @@ parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
-type wxListCtrl() :: wx:wx_object().
-%% @spec () -> wxListCtrl()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+-spec new() -> wxListCtrl().
new() ->
wxe_util:construct(?wxListCtrl_new_0, <<>>).
-%% @spec (Parent::wxWindow:wxWindow()) -> wxListCtrl()
-%% @equiv new(Parent, [])
+-spec new(Parent) -> wxListCtrl() when
+ Parent::wxWindow:wxWindow().
new(Parent)
when is_record(Parent, wx_ref) ->
new(Parent, []).
-%% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxListCtrl()
-%% Option = {winid, integer()} |
-%% {pos, {X::integer(),Y::integer()}} |
-%% {size, {W::integer(),H::integer()}} |
-%% {style, integer()} |
-%% {validator, wx:wx()} |
-%% {onGetItemText, OnGetItemText} |
-%% {onGetItemAttr, OnGetItemAttr} |
-%% {onGetItemColumnImage, OnGetItemColumnImage}
+%% @doc Creates a listctrl with optional callback functions:
%%
-%% OnGetItemText = (This, Item, Column) -> wxString()
-%% OnGetItemAttr = (This, Item) -> wxListItemAttr()
+%% OnGetItemText = (This, Item, Column) -> unicode:charlist()
+%% OnGetItemAttr = (This, Item) -> wxListItemAttr:wxListItemAttr()
%% OnGetItemColumnImage = (This, Item, Column) -> integer()
-%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+%%
+%% See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlwxlistctrl">external documentation</a>.
+-spec new(Parent, [Option]) -> wxListCtrl() when
+ Parent::wxWindow:wxWindow(),
+ Option::{winid, integer()} |
+ {pos, {X::integer(),Y::integer()}} |
+ {size, {W::integer(),H::integer()}} |
+ {style, integer()} |
+ {validator, wx:wx_object()} |
+ {onGetItemText, function()} |
+ {onGetItemAttr, function()} |
+ {onGetItemColumnImage, function()}.
new(#wx_ref{type=ParentT,ref=ParentRef}, Options)
when is_list(Options)->
@@ -185,26 +188,27 @@ clearAll(#wx_ref{type=ThisT,ref=ThisRef}) ->
<<ThisRef:32/?UI>>).
-%% @spec (This::wxListCtrl(), Parent::wxWindow:wxWindow()) -> bool()
%% @equiv create(This,Parent, [])
+-spec create(This, Parent) -> wxListCtrl() when
+ This::wxWindow:wxWindow(),
+ Parent::wxWindow:wxWindow().
create(This,Parent)
when is_record(This, wx_ref),is_record(Parent, wx_ref) ->
create(This,Parent, []).
-%% @spec (This::wxListCtrl(), Parent::wxWindow:wxWindow(), [Option]) -> bool()
-%% Option = {winid, integer()} |
-%% {pos, {X::integer(),Y::integer()}} |
-%% {size, {W::integer(),H::integer()}} |
-%% {style, integer()} |
-%% {validator, wx:wx()} |
-%% {onGetItemText, OnGetItemText} |
-%% {onGetItemAttr, OnGetItemAttr} |
-%% {onGetItemColumnImage, OnGetItemColumnImage}
-%%
-%% OnGetItemText = (This, Item, Column) -> wxString()
-%% OnGetItemAttr = (This, Item) -> wxListItemAttr()
-%% OnGetItemColumnImage = (This, Item, Column) -> integer()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlcreate">external documentation</a>.
+-spec create(This, Parent, [Option]) -> wxListCtrl() when
+ This::wxWindow:wxWindow(),
+ Parent::wxWindow:wxWindow(),
+ Option::{winid, integer()} |
+ {pos, {X::integer(),Y::integer()}} |
+ {size, {W::integer(),H::integer()}} |
+ {style, integer()} |
+ {validator, wx:wx_object()} |
+ {onGetItemText, function()} |
+ {onGetItemAttr, function()} |
+ {onGetItemColumnImage, function()}.
+
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options)
when is_list(Options) ->
?CLASS(ThisT,wxListCtrl),
@@ -268,7 +272,7 @@ ensureVisible(#wx_ref{type=ThisT,ref=ThisRef},Item)
This::wxListCtrl(), Start::integer(), Str::unicode:chardata().
findItem(This,Start,Str)
- when is_record(This, wx_ref),is_integer(Start),is_list(Str) ->
+ when is_record(This, wx_ref),is_integer(Start),?is_chardata(Str) ->
findItem(This,Start,Str, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxlistctrl.html#wxlistctrlfinditem">external documentation</a>.
@@ -282,7 +286,7 @@ findItem(This,Start,Str)
(This, Start, Pt, Direction) -> integer() when
This::wxListCtrl(), Start::integer(), Pt::{X::integer(), Y::integer()}, Direction::integer().
findItem(#wx_ref{type=ThisT,ref=ThisRef},Start,Str, Options)
- when is_integer(Start),is_list(Str),is_list(Options) ->
+ when is_integer(Start),?is_chardata(Str),is_list(Options) ->
?CLASS(ThisT,wxListCtrl),
Str_UC = unicode:characters_to_binary([Str,0]),
MOpts = fun({partial, Partial}, Acc) -> [<<1:32/?UI,(wxe_util:from_bool(Partial)):32/?UI>>|Acc];
@@ -536,7 +540,7 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY})
This::wxListCtrl(), Col::integer(), Info::wxListItem:wxListItem().
insertColumn(This,Col,Heading)
- when is_record(This, wx_ref),is_integer(Col),is_list(Heading) ->
+ when is_record(This, wx_ref),is_integer(Col),?is_chardata(Heading) ->
insertColumn(This,Col,Heading, []);
insertColumn(#wx_ref{type=ThisT,ref=ThisRef},Col,#wx_ref{type=InfoT,ref=InfoRef})
when is_integer(Col) ->
@@ -551,7 +555,7 @@ insertColumn(#wx_ref{type=ThisT,ref=ThisRef},Col,#wx_ref{type=InfoT,ref=InfoRef}
Option :: {'format', integer()}
| {'width', integer()}.
insertColumn(#wx_ref{type=ThisT,ref=ThisRef},Col,Heading, Options)
- when is_integer(Col),is_list(Heading),is_list(Options) ->
+ when is_integer(Col),?is_chardata(Heading),is_list(Options) ->
?CLASS(ThisT,wxListCtrl),
Heading_UC = unicode:characters_to_binary([Heading,0]),
MOpts = fun({format, Format}, Acc) -> [<<1:32/?UI,Format:32/?UI>>|Acc];
@@ -585,7 +589,7 @@ insertItem(#wx_ref{type=ThisT,ref=ThisRef},Index,ImageIndex)
wxe_util:call(?wxListCtrl_InsertItem_2_0,
<<ThisRef:32/?UI,Index:32/?UI,ImageIndex:32/?UI>>);
insertItem(#wx_ref{type=ThisT,ref=ThisRef},Index,Label)
- when is_integer(Index),is_list(Label) ->
+ when is_integer(Index),?is_chardata(Label) ->
?CLASS(ThisT,wxListCtrl),
Label_UC = unicode:characters_to_binary([Label,0]),
wxe_util:call(?wxListCtrl_InsertItem_2_1,
@@ -595,7 +599,7 @@ insertItem(#wx_ref{type=ThisT,ref=ThisRef},Index,Label)
-spec insertItem(This, Index, Label, ImageIndex) -> integer() when
This::wxListCtrl(), Index::integer(), Label::unicode:chardata(), ImageIndex::integer().
insertItem(#wx_ref{type=ThisT,ref=ThisRef},Index,Label,ImageIndex)
- when is_integer(Index),is_list(Label),is_integer(ImageIndex) ->
+ when is_integer(Index),?is_chardata(Label),is_integer(ImageIndex) ->
?CLASS(ThisT,wxListCtrl),
Label_UC = unicode:characters_to_binary([Label,0]),
wxe_util:call(?wxListCtrl_InsertItem_3,
@@ -680,7 +684,7 @@ setItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=InfoT,ref=InfoRef}) ->
This::wxListCtrl(), Index::integer(), Col::integer(), Label::unicode:chardata().
setItem(This,Index,Col,Label)
- when is_record(This, wx_ref),is_integer(Index),is_integer(Col),is_list(Label) ->
+ when is_record(This, wx_ref),is_integer(Index),is_integer(Col),?is_chardata(Label) ->
setItem(This,Index,Col,Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxlistctrl.html#wxlistctrlsetitem">external documentation</a>.
@@ -688,7 +692,7 @@ setItem(This,Index,Col,Label)
This::wxListCtrl(), Index::integer(), Col::integer(), Label::unicode:chardata(),
Option :: {'imageId', integer()}.
setItem(#wx_ref{type=ThisT,ref=ThisRef},Index,Col,Label, Options)
- when is_integer(Index),is_integer(Col),is_list(Label),is_list(Options) ->
+ when is_integer(Index),is_integer(Col),?is_chardata(Label),is_list(Options) ->
?CLASS(ThisT,wxListCtrl),
Label_UC = unicode:characters_to_binary([Label,0]),
MOpts = fun({imageId, ImageId}, Acc) -> [<<1:32/?UI,ImageId:32/?UI>>|Acc];
@@ -786,7 +790,7 @@ setItemState(#wx_ref{type=ThisT,ref=ThisRef},Item,State,StateMask)
-spec setItemText(This, Item, Str) -> 'ok' when
This::wxListCtrl(), Item::integer(), Str::unicode:chardata().
setItemText(#wx_ref{type=ThisT,ref=ThisRef},Item,Str)
- when is_integer(Item),is_list(Str) ->
+ when is_integer(Item),?is_chardata(Str) ->
?CLASS(ThisT,wxListCtrl),
Str_UC = unicode:characters_to_binary([Str,0]),
wxe_util:cast(?wxListCtrl_SetItemText,
@@ -871,6 +875,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -1183,6 +1189,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxListItem.erl b/lib/wx/src/gen/wxListItem.erl
index 1530a8c514..56a1719c55 100644
--- a/lib/wx/src/gen/wxListItem.erl
+++ b/lib/wx/src/gen/wxListItem.erl
@@ -236,7 +236,7 @@ setStateMask(#wx_ref{type=ThisT,ref=ThisRef},StateMask)
-spec setText(This, Text) -> 'ok' when
This::wxListItem(), Text::unicode:chardata().
setText(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxListItem),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxListItem_SetText,
diff --git a/lib/wx/src/gen/wxListView.erl b/lib/wx/src/gen/wxListView.erl
index 908bf4c1c9..adba629d5a 100644
--- a/lib/wx/src/gen/wxListView.erl
+++ b/lib/wx/src/gen/wxListView.erl
@@ -39,29 +39,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -169,6 +169,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -485,6 +487,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxListbook.erl b/lib/wx/src/gen/wxListbook.erl
index a7050e1db9..e2ea559587 100644
--- a/lib/wx/src/gen/wxListbook.erl
+++ b/lib/wx/src/gen/wxListbook.erl
@@ -43,29 +43,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -120,7 +120,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options)
This::wxListbook(), Page::wxWindow:wxWindow(), Text::unicode:chardata().
addPage(This,Page,Text)
- when is_record(This, wx_ref),is_record(Page, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_record(Page, wx_ref),?is_chardata(Text) ->
addPage(This,Page,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxlistbook.html#wxlistbookaddpage">external documentation</a>.
@@ -129,7 +129,7 @@ addPage(This,Page,Text)
Option :: {'bSelect', boolean()}
| {'imageId', integer()}.
addPage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PageT,ref=PageRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+ when ?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxListbook),
?CLASS(PageT,wxWindow),
Text_UC = unicode:characters_to_binary([Text,0]),
@@ -296,7 +296,7 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY})
This::wxListbook(), N::integer(), Page::wxWindow:wxWindow(), Text::unicode:chardata().
insertPage(This,N,Page,Text)
- when is_record(This, wx_ref),is_integer(N),is_record(Page, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(N),is_record(Page, wx_ref),?is_chardata(Text) ->
insertPage(This,N,Page,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxlistbook.html#wxlistbookinsertpage">external documentation</a>.
@@ -305,7 +305,7 @@ insertPage(This,N,Page,Text)
Option :: {'bSelect', boolean()}
| {'imageId', integer()}.
insertPage(#wx_ref{type=ThisT,ref=ThisRef},N,#wx_ref{type=PageT,ref=PageRef},Text, Options)
- when is_integer(N),is_list(Text),is_list(Options) ->
+ when is_integer(N),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxListbook),
?CLASS(PageT,wxWindow),
Text_UC = unicode:characters_to_binary([Text,0]),
@@ -347,7 +347,7 @@ setPageImage(#wx_ref{type=ThisT,ref=ThisRef},N,ImageId)
-spec setPageText(This, N, StrText) -> boolean() when
This::wxListbook(), N::integer(), StrText::unicode:chardata().
setPageText(#wx_ref{type=ThisT,ref=ThisRef},N,StrText)
- when is_integer(N),is_list(StrText) ->
+ when is_integer(N),?is_chardata(StrText) ->
?CLASS(ThisT,wxListbook),
StrText_UC = unicode:characters_to_binary([StrText,0]),
wxe_util:call(?wxListbook_SetPageText,
@@ -384,6 +384,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -700,6 +702,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxLocale.erl b/lib/wx/src/gen/wxLocale.erl
index d473731bf8..1ce7c3e3e8 100644
--- a/lib/wx/src/gen/wxLocale.erl
+++ b/lib/wx/src/gen/wxLocale.erl
@@ -92,7 +92,7 @@ init(#wx_ref{type=ThisT,ref=ThisRef}, Options)
-spec addCatalog(This, SzDomain) -> boolean() when
This::wxLocale(), SzDomain::unicode:chardata().
addCatalog(#wx_ref{type=ThisT,ref=ThisRef},SzDomain)
- when is_list(SzDomain) ->
+ when ?is_chardata(SzDomain) ->
?CLASS(ThisT,wxLocale),
SzDomain_UC = unicode:characters_to_binary([SzDomain,0]),
wxe_util:call(?wxLocale_AddCatalog_1,
@@ -103,7 +103,7 @@ addCatalog(#wx_ref{type=ThisT,ref=ThisRef},SzDomain)
-spec addCatalog(This, SzDomain, MsgIdLanguage, MsgIdCharset) -> boolean() when
This::wxLocale(), SzDomain::unicode:chardata(), MsgIdLanguage::wx:wx_enum(), MsgIdCharset::unicode:chardata().
addCatalog(#wx_ref{type=ThisT,ref=ThisRef},SzDomain,MsgIdLanguage,MsgIdCharset)
- when is_list(SzDomain),is_integer(MsgIdLanguage),is_list(MsgIdCharset) ->
+ when ?is_chardata(SzDomain),is_integer(MsgIdLanguage),?is_chardata(MsgIdCharset) ->
?CLASS(ThisT,wxLocale),
SzDomain_UC = unicode:characters_to_binary([SzDomain,0]),
MsgIdCharset_UC = unicode:characters_to_binary([MsgIdCharset,0]),
@@ -114,7 +114,7 @@ addCatalog(#wx_ref{type=ThisT,ref=ThisRef},SzDomain,MsgIdLanguage,MsgIdCharset)
-spec addCatalogLookupPathPrefix(Prefix) -> 'ok' when
Prefix::unicode:chardata().
addCatalogLookupPathPrefix(Prefix)
- when is_list(Prefix) ->
+ when ?is_chardata(Prefix) ->
Prefix_UC = unicode:characters_to_binary([Prefix,0]),
wxe_util:cast(?wxLocale_AddCatalogLookupPathPrefix,
<<(byte_size(Prefix_UC)):32/?UI,(Prefix_UC)/binary, 0:(((8- ((4+byte_size(Prefix_UC)) band 16#7)) band 16#7))/unit:8>>).
@@ -164,7 +164,7 @@ getName(#wx_ref{type=ThisT,ref=ThisRef}) ->
This::wxLocale(), SzOrigString::unicode:chardata().
getString(This,SzOrigString)
- when is_record(This, wx_ref),is_list(SzOrigString) ->
+ when is_record(This, wx_ref),?is_chardata(SzOrigString) ->
getString(This,SzOrigString, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxlocale.html#wxlocalegetstring">external documentation</a>.
@@ -172,7 +172,7 @@ getString(This,SzOrigString)
This::wxLocale(), SzOrigString::unicode:chardata(),
Option :: {'szDomain', unicode:chardata()}.
getString(#wx_ref{type=ThisT,ref=ThisRef},SzOrigString, Options)
- when is_list(SzOrigString),is_list(Options) ->
+ when ?is_chardata(SzOrigString),is_list(Options) ->
?CLASS(ThisT,wxLocale),
SzOrigString_UC = unicode:characters_to_binary([SzOrigString,0]),
MOpts = fun({szDomain, SzDomain}, Acc) -> SzDomain_UC = unicode:characters_to_binary([SzDomain,0]),[<<1:32/?UI,(byte_size(SzDomain_UC)):32/?UI,(SzDomain_UC)/binary, 0:(((8- ((0+byte_size(SzDomain_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -186,7 +186,7 @@ getString(#wx_ref{type=ThisT,ref=ThisRef},SzOrigString, Options)
This::wxLocale(), SzOrigString::unicode:chardata(), SzOrigString2::unicode:chardata(), N::integer().
getString(This,SzOrigString,SzOrigString2,N)
- when is_record(This, wx_ref),is_list(SzOrigString),is_list(SzOrigString2),is_integer(N) ->
+ when is_record(This, wx_ref),?is_chardata(SzOrigString),?is_chardata(SzOrigString2),is_integer(N) ->
getString(This,SzOrigString,SzOrigString2,N, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxlocale.html#wxlocalegetstring">external documentation</a>.
@@ -194,7 +194,7 @@ getString(This,SzOrigString,SzOrigString2,N)
This::wxLocale(), SzOrigString::unicode:chardata(), SzOrigString2::unicode:chardata(), N::integer(),
Option :: {'szDomain', unicode:chardata()}.
getString(#wx_ref{type=ThisT,ref=ThisRef},SzOrigString,SzOrigString2,N, Options)
- when is_list(SzOrigString),is_list(SzOrigString2),is_integer(N),is_list(Options) ->
+ when ?is_chardata(SzOrigString),?is_chardata(SzOrigString2),is_integer(N),is_list(Options) ->
?CLASS(ThisT,wxLocale),
SzOrigString_UC = unicode:characters_to_binary([SzOrigString,0]),
SzOrigString2_UC = unicode:characters_to_binary([SzOrigString2,0]),
@@ -209,7 +209,7 @@ getString(#wx_ref{type=ThisT,ref=ThisRef},SzOrigString,SzOrigString2,N, Options)
This::wxLocale(), SzHeader::unicode:chardata().
getHeaderValue(This,SzHeader)
- when is_record(This, wx_ref),is_list(SzHeader) ->
+ when is_record(This, wx_ref),?is_chardata(SzHeader) ->
getHeaderValue(This,SzHeader, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxlocale.html#wxlocalegetheadervalue">external documentation</a>.
@@ -217,7 +217,7 @@ getHeaderValue(This,SzHeader)
This::wxLocale(), SzHeader::unicode:chardata(),
Option :: {'szDomain', unicode:chardata()}.
getHeaderValue(#wx_ref{type=ThisT,ref=ThisRef},SzHeader, Options)
- when is_list(SzHeader),is_list(Options) ->
+ when ?is_chardata(SzHeader),is_list(Options) ->
?CLASS(ThisT,wxLocale),
SzHeader_UC = unicode:characters_to_binary([SzHeader,0]),
MOpts = fun({szDomain, SzDomain}, Acc) -> SzDomain_UC = unicode:characters_to_binary([SzDomain,0]),[<<1:32/?UI,(byte_size(SzDomain_UC)):32/?UI,(SzDomain_UC)/binary, 0:(((8- ((0+byte_size(SzDomain_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -257,7 +257,7 @@ getSystemLanguage() ->
-spec isLoaded(This, SzDomain) -> boolean() when
This::wxLocale(), SzDomain::unicode:chardata().
isLoaded(#wx_ref{type=ThisT,ref=ThisRef},SzDomain)
- when is_list(SzDomain) ->
+ when ?is_chardata(SzDomain) ->
?CLASS(ThisT,wxLocale),
SzDomain_UC = unicode:characters_to_binary([SzDomain,0]),
wxe_util:call(?wxLocale_IsLoaded,
diff --git a/lib/wx/src/gen/wxMDIChildFrame.erl b/lib/wx/src/gen/wxMDIChildFrame.erl
index b294e4898d..0d388c016a 100644
--- a/lib/wx/src/gen/wxMDIChildFrame.erl
+++ b/lib/wx/src/gen/wxMDIChildFrame.erl
@@ -42,45 +42,45 @@
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createStatusBar/1,createStatusBar/2,createToolBar/1,createToolBar/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientAreaOrigin/1,
- getClientSize/1,getContainingSizer/1,getCursor/1,getDropTarget/1,
- getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
- getLabel/1,getMaxSize/1,getMenuBar/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getStatusBar/1,
- getStatusBarPane/1,getTextExtent/2,getTextExtent/3,getTitle/1,getToolBar/1,
- getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMenuBar/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setStatusBar/2,
- setStatusBarPane/2,setStatusText/2,setStatusText/3,setStatusWidths/2,
- setThemeEnabled/2,setTitle/2,setToolBar/2,setToolTip/2,setTransparent/2,
- setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,
- setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,
- shouldInheritColours/1,show/1,show/2,showFullScreen/2,showFullScreen/3,
- thaw/1,transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
- updateWindowUI/2,validate/1,warpPointer/3]).
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientAreaOrigin/1,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
+ getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,getMenuBar/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getStatusBar/1,getStatusBarPane/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolBar/1,getToolTip/1,getUpdateRegion/1,
+ getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
+ hasScrollbar/2,hasTransparentBackground/1,hide/1,iconize/1,iconize/2,
+ inheritAttributes/1,initDialog/1,invalidateBestSize/1,isActive/1,
+ isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
+ isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,
+ setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
+ setCursor/2,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,
+ setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,
+ setIcons/2,setId/2,setLabel/2,setMaxSize/2,setMenuBar/2,setMinSize/2,
+ setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
+ setShape/2,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setStatusBar/2,setStatusBarPane/2,setStatusText/2,setStatusText/3,
+ setStatusWidths/2,setThemeEnabled/2,setTitle/2,setToolBar/2,setToolTip/2,
+ setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,showFullScreen/2,
+ showFullScreen/3,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
+ update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
-export_type([wxMDIChildFrame/0]).
%% @hidden
@@ -102,7 +102,7 @@ new() ->
Parent::wxMDIParentFrame:wxMDIParentFrame(), Id::integer(), Title::unicode:chardata().
new(Parent,Id,Title)
- when is_record(Parent, wx_ref),is_integer(Id),is_list(Title) ->
+ when is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title) ->
new(Parent,Id,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmdichildframe.html#wxmdichildframewxmdichildframe">external documentation</a>.
@@ -112,7 +112,7 @@ new(Parent,Id,Title)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
- when is_integer(Id),is_list(Title),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_list(Options) ->
?CLASS(ParentT,wxMDIParentFrame),
Title_UC = unicode:characters_to_binary([Title,0]),
MOpts = fun({pos, {PosX,PosY}}, Acc) -> [<<1:32/?UI,PosX:32/?UI,PosY:32/?UI,0:32>>|Acc];
@@ -136,7 +136,7 @@ activate(#wx_ref{type=ThisT,ref=ThisRef}) ->
This::wxMDIChildFrame(), Parent::wxMDIParentFrame:wxMDIParentFrame(), Id::integer(), Title::unicode:chardata().
create(This,Parent,Id,Title)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Title) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title) ->
create(This,Parent,Id,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmdichildframe.html#wxmdichildframecreate">external documentation</a>.
@@ -146,7 +146,7 @@ create(This,Parent,Id,Title)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
- when is_integer(Id),is_list(Title),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_list(Options) ->
?CLASS(ThisT,wxMDIChildFrame),
?CLASS(ParentT,wxMDIParentFrame),
Title_UC = unicode:characters_to_binary([Title,0]),
@@ -275,6 +275,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -595,6 +597,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxMDIClientWindow.erl b/lib/wx/src/gen/wxMDIClientWindow.erl
index ddc31760f4..4fc080c64d 100644
--- a/lib/wx/src/gen/wxMDIClientWindow.erl
+++ b/lib/wx/src/gen/wxMDIClientWindow.erl
@@ -37,29 +37,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -136,6 +136,8 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -456,6 +458,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxMDIParentFrame.erl b/lib/wx/src/gen/wxMDIParentFrame.erl
index 63b4ec8e23..59f24a1b40 100644
--- a/lib/wx/src/gen/wxMDIParentFrame.erl
+++ b/lib/wx/src/gen/wxMDIParentFrame.erl
@@ -43,27 +43,28 @@
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createStatusBar/1,createStatusBar/2,createToolBar/1,createToolBar/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientAreaOrigin/1,
- getClientSize/1,getContainingSizer/1,getCursor/1,getDropTarget/1,
- getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
- getLabel/1,getMaxSize/1,getMenuBar/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getStatusBar/1,
- getStatusBarPane/1,getTextExtent/2,getTextExtent/3,getTitle/1,getToolBar/1,
- getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- processCommand/2,raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,
- releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientAreaOrigin/1,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
+ getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,getMenuBar/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getStatusBar/1,getStatusBarPane/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolBar/1,getToolTip/1,getUpdateRegion/1,
+ getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
+ hasScrollbar/2,hasTransparentBackground/1,hide/1,iconize/1,iconize/2,
+ inheritAttributes/1,initDialog/1,invalidateBestSize/1,isActive/1,
+ isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
+ isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
+ maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
scrollWindow/4,sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,
setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
@@ -103,7 +104,7 @@ new() ->
Parent::wxWindow:wxWindow(), Id::integer(), Title::unicode:chardata().
new(Parent,Id,Title)
- when is_record(Parent, wx_ref),is_integer(Id),is_list(Title) ->
+ when is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title) ->
new(Parent,Id,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmdiparentframe.html#wxmdiparentframewxmdiparentframe">external documentation</a>.
@@ -113,7 +114,7 @@ new(Parent,Id,Title)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
- when is_integer(Id),is_list(Title),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Title_UC = unicode:characters_to_binary([Title,0]),
MOpts = fun({pos, {PosX,PosY}}, Acc) -> [<<1:32/?UI,PosX:32/?UI,PosY:32/?UI,0:32>>|Acc];
@@ -161,7 +162,7 @@ cascade(#wx_ref{type=ThisT,ref=ThisRef}) ->
This::wxMDIParentFrame(), Parent::wxWindow:wxWindow(), Id::integer(), Title::unicode:chardata().
create(This,Parent,Id,Title)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Title) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title) ->
create(This,Parent,Id,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmdiparentframe.html#wxmdiparentframecreate">external documentation</a>.
@@ -171,7 +172,7 @@ create(This,Parent,Id,Title)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
- when is_integer(Id),is_list(Title),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_list(Options) ->
?CLASS(ThisT,wxMDIParentFrame),
?CLASS(ParentT,wxWindow),
Title_UC = unicode:characters_to_binary([Title,0]),
@@ -313,6 +314,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -633,6 +636,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxMenu.erl b/lib/wx/src/gen/wxMenu.erl
index 317ea38685..26fe23701d 100644
--- a/lib/wx/src/gen/wxMenu.erl
+++ b/lib/wx/src/gen/wxMenu.erl
@@ -69,7 +69,7 @@ new(Options)
Title::unicode:chardata(),
Option :: {'style', integer()}.
new(Title, Options)
- when is_list(Title),is_list(Options) ->
+ when ?is_chardata(Title),is_list(Options) ->
Title_UC = unicode:characters_to_binary([Title,0]),
MOpts = fun({style, Style}, Acc) -> [<<1:32/?UI,Style:32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
@@ -91,7 +91,7 @@ append(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ItemT,ref=ItemRef}) ->
This::wxMenu(), Itemid::integer(), Text::unicode:chardata().
append(This,Itemid,Text)
- when is_record(This, wx_ref),is_integer(Itemid),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Itemid),?is_chardata(Text) ->
append(This,Itemid,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmenu.html#wxmenuappend">external documentation</a>.
@@ -110,10 +110,10 @@ append(This,Itemid,Text)
| {'kind', wx:wx_enum()}.
append(This,Itemid,Text,Submenu)
- when is_record(This, wx_ref),is_integer(Itemid),is_list(Text),is_record(Submenu, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Itemid),?is_chardata(Text),is_record(Submenu, wx_ref) ->
append(This,Itemid,Text,Submenu, []);
append(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text, Options)
- when is_integer(Itemid),is_list(Text),is_list(Options) ->
+ when is_integer(Itemid),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({help, Help}, Acc) -> Help_UC = unicode:characters_to_binary([Help,0]),[<<1:32/?UI,(byte_size(Help_UC)):32/?UI,(Help_UC)/binary, 0:(((8- ((0+byte_size(Help_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -135,14 +135,14 @@ append(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text, Options)
This::wxMenu(), Itemid::integer(), Text::unicode:chardata(), Submenu::wxMenu(),
Option :: {'help', unicode:chardata()}.
append(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text,Help,IsCheckable)
- when is_integer(Itemid),is_list(Text),is_list(Help),is_boolean(IsCheckable) ->
+ when is_integer(Itemid),?is_chardata(Text),?is_chardata(Help),is_boolean(IsCheckable) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
Help_UC = unicode:characters_to_binary([Help,0]),
wxe_util:cast(?wxMenu_Append_4_0,
<<ThisRef:32/?UI,Itemid: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,(byte_size(Help_UC)):32/?UI,(Help_UC)/binary, 0:(((8- ((4+byte_size(Help_UC)) band 16#7)) band 16#7))/unit:8,(wxe_util:from_bool(IsCheckable)):32/?UI>>);
append(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text,#wx_ref{type=SubmenuT,ref=SubmenuRef}, Options)
- when is_integer(Itemid),is_list(Text),is_list(Options) ->
+ when is_integer(Itemid),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
?CLASS(SubmenuT,wxMenu),
@@ -157,7 +157,7 @@ append(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text,#wx_ref{type=SubmenuT,ref=Sub
This::wxMenu(), Itemid::integer(), Text::unicode:chardata().
appendCheckItem(This,Itemid,Text)
- when is_record(This, wx_ref),is_integer(Itemid),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Itemid),?is_chardata(Text) ->
appendCheckItem(This,Itemid,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmenu.html#wxmenuappendcheckitem">external documentation</a>.
@@ -165,7 +165,7 @@ appendCheckItem(This,Itemid,Text)
This::wxMenu(), Itemid::integer(), Text::unicode:chardata(),
Option :: {'help', unicode:chardata()}.
appendCheckItem(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text, Options)
- when is_integer(Itemid),is_list(Text),is_list(Options) ->
+ when is_integer(Itemid),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({help, Help}, Acc) -> Help_UC = unicode:characters_to_binary([Help,0]),[<<1:32/?UI,(byte_size(Help_UC)):32/?UI,(Help_UC)/binary, 0:(((8- ((0+byte_size(Help_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -179,7 +179,7 @@ appendCheckItem(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text, Options)
This::wxMenu(), Itemid::integer(), Text::unicode:chardata().
appendRadioItem(This,Itemid,Text)
- when is_record(This, wx_ref),is_integer(Itemid),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Itemid),?is_chardata(Text) ->
appendRadioItem(This,Itemid,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmenu.html#wxmenuappendradioitem">external documentation</a>.
@@ -187,7 +187,7 @@ appendRadioItem(This,Itemid,Text)
This::wxMenu(), Itemid::integer(), Text::unicode:chardata(),
Option :: {'help', unicode:chardata()}.
appendRadioItem(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text, Options)
- when is_integer(Itemid),is_list(Text),is_list(Options) ->
+ when is_integer(Itemid),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({help, Help}, Acc) -> Help_UC = unicode:characters_to_binary([Help,0]),[<<1:32/?UI,(byte_size(Help_UC)):32/?UI,(Help_UC)/binary, 0:(((8- ((0+byte_size(Help_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -285,7 +285,7 @@ findItem(#wx_ref{type=ThisT,ref=ThisRef},Itemid)
wxe_util:call(?wxMenu_FindItem_2,
<<ThisRef:32/?UI,Itemid:32/?UI>>);
findItem(#wx_ref{type=ThisT,ref=ThisRef},Item)
- when is_list(Item) ->
+ when ?is_chardata(Item) ->
?CLASS(ThisT,wxMenu),
Item_UC = unicode:characters_to_binary([Item,0]),
wxe_util:call(?wxMenu_FindItem_1,
@@ -386,7 +386,7 @@ insert(#wx_ref{type=ThisT,ref=ThisRef},Pos,Itemid, Options)
This::wxMenu(), Pos::integer(), Itemid::integer(), Text::unicode:chardata(), Submenu::wxMenu().
insert(This,Pos,Itemid,Text,Submenu)
- when is_record(This, wx_ref),is_integer(Pos),is_integer(Itemid),is_list(Text),is_record(Submenu, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Pos),is_integer(Itemid),?is_chardata(Text),is_record(Submenu, wx_ref) ->
insert(This,Pos,Itemid,Text,Submenu, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmenu.html#wxmenuinsert">external documentation</a>.
@@ -401,14 +401,14 @@ insert(This,Pos,Itemid,Text,Submenu)
This::wxMenu(), Pos::integer(), Itemid::integer(), Text::unicode:chardata(), Submenu::wxMenu(),
Option :: {'help', unicode:chardata()}.
insert(#wx_ref{type=ThisT,ref=ThisRef},Pos,Itemid,Text,Help,IsCheckable)
- when is_integer(Pos),is_integer(Itemid),is_list(Text),is_list(Help),is_boolean(IsCheckable) ->
+ when is_integer(Pos),is_integer(Itemid),?is_chardata(Text),?is_chardata(Help),is_boolean(IsCheckable) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
Help_UC = unicode:characters_to_binary([Help,0]),
wxe_util:cast(?wxMenu_Insert_5_0,
<<ThisRef:32/?UI,Pos:32/?UI,Itemid: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,(byte_size(Help_UC)):32/?UI,(Help_UC)/binary, 0:(((8- ((4+byte_size(Help_UC)) band 16#7)) band 16#7))/unit:8,(wxe_util:from_bool(IsCheckable)):32/?UI>>);
insert(#wx_ref{type=ThisT,ref=ThisRef},Pos,Itemid,Text,#wx_ref{type=SubmenuT,ref=SubmenuRef}, Options)
- when is_integer(Pos),is_integer(Itemid),is_list(Text),is_list(Options) ->
+ when is_integer(Pos),is_integer(Itemid),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
?CLASS(SubmenuT,wxMenu),
@@ -423,7 +423,7 @@ insert(#wx_ref{type=ThisT,ref=ThisRef},Pos,Itemid,Text,#wx_ref{type=SubmenuT,ref
This::wxMenu(), Pos::integer(), Itemid::integer(), Text::unicode:chardata().
insertCheckItem(This,Pos,Itemid,Text)
- when is_record(This, wx_ref),is_integer(Pos),is_integer(Itemid),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Pos),is_integer(Itemid),?is_chardata(Text) ->
insertCheckItem(This,Pos,Itemid,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmenu.html#wxmenuinsertcheckitem">external documentation</a>.
@@ -431,7 +431,7 @@ insertCheckItem(This,Pos,Itemid,Text)
This::wxMenu(), Pos::integer(), Itemid::integer(), Text::unicode:chardata(),
Option :: {'help', unicode:chardata()}.
insertCheckItem(#wx_ref{type=ThisT,ref=ThisRef},Pos,Itemid,Text, Options)
- when is_integer(Pos),is_integer(Itemid),is_list(Text),is_list(Options) ->
+ when is_integer(Pos),is_integer(Itemid),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({help, Help}, Acc) -> Help_UC = unicode:characters_to_binary([Help,0]),[<<1:32/?UI,(byte_size(Help_UC)):32/?UI,(Help_UC)/binary, 0:(((8- ((0+byte_size(Help_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -445,7 +445,7 @@ insertCheckItem(#wx_ref{type=ThisT,ref=ThisRef},Pos,Itemid,Text, Options)
This::wxMenu(), Pos::integer(), Itemid::integer(), Text::unicode:chardata().
insertRadioItem(This,Pos,Itemid,Text)
- when is_record(This, wx_ref),is_integer(Pos),is_integer(Itemid),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Pos),is_integer(Itemid),?is_chardata(Text) ->
insertRadioItem(This,Pos,Itemid,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmenu.html#wxmenuinsertradioitem">external documentation</a>.
@@ -453,7 +453,7 @@ insertRadioItem(This,Pos,Itemid,Text)
This::wxMenu(), Pos::integer(), Itemid::integer(), Text::unicode:chardata(),
Option :: {'help', unicode:chardata()}.
insertRadioItem(#wx_ref{type=ThisT,ref=ThisRef},Pos,Itemid,Text, Options)
- when is_integer(Pos),is_integer(Itemid),is_list(Text),is_list(Options) ->
+ when is_integer(Pos),is_integer(Itemid),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({help, Help}, Acc) -> Help_UC = unicode:characters_to_binary([Help,0]),[<<1:32/?UI,(byte_size(Help_UC)):32/?UI,(Help_UC)/binary, 0:(((8- ((0+byte_size(Help_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -532,7 +532,7 @@ prepend(#wx_ref{type=ThisT,ref=ThisRef},Itemid, Options)
This::wxMenu(), Itemid::integer(), Text::unicode:chardata(), Submenu::wxMenu().
prepend(This,Itemid,Text,Submenu)
- when is_record(This, wx_ref),is_integer(Itemid),is_list(Text),is_record(Submenu, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Itemid),?is_chardata(Text),is_record(Submenu, wx_ref) ->
prepend(This,Itemid,Text,Submenu, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmenu.html#wxmenuprepend">external documentation</a>.
@@ -547,14 +547,14 @@ prepend(This,Itemid,Text,Submenu)
This::wxMenu(), Itemid::integer(), Text::unicode:chardata(), Submenu::wxMenu(),
Option :: {'help', unicode:chardata()}.
prepend(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text,Help,IsCheckable)
- when is_integer(Itemid),is_list(Text),is_list(Help),is_boolean(IsCheckable) ->
+ when is_integer(Itemid),?is_chardata(Text),?is_chardata(Help),is_boolean(IsCheckable) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
Help_UC = unicode:characters_to_binary([Help,0]),
wxe_util:cast(?wxMenu_Prepend_4_0,
<<ThisRef:32/?UI,Itemid: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,(byte_size(Help_UC)):32/?UI,(Help_UC)/binary, 0:(((8- ((4+byte_size(Help_UC)) band 16#7)) band 16#7))/unit:8,(wxe_util:from_bool(IsCheckable)):32/?UI>>);
prepend(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text,#wx_ref{type=SubmenuT,ref=SubmenuRef}, Options)
- when is_integer(Itemid),is_list(Text),is_list(Options) ->
+ when is_integer(Itemid),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
?CLASS(SubmenuT,wxMenu),
@@ -569,7 +569,7 @@ prepend(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text,#wx_ref{type=SubmenuT,ref=Su
This::wxMenu(), Itemid::integer(), Text::unicode:chardata().
prependCheckItem(This,Itemid,Text)
- when is_record(This, wx_ref),is_integer(Itemid),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Itemid),?is_chardata(Text) ->
prependCheckItem(This,Itemid,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmenu.html#wxmenuprependcheckitem">external documentation</a>.
@@ -577,7 +577,7 @@ prependCheckItem(This,Itemid,Text)
This::wxMenu(), Itemid::integer(), Text::unicode:chardata(),
Option :: {'help', unicode:chardata()}.
prependCheckItem(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text, Options)
- when is_integer(Itemid),is_list(Text),is_list(Options) ->
+ when is_integer(Itemid),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({help, Help}, Acc) -> Help_UC = unicode:characters_to_binary([Help,0]),[<<1:32/?UI,(byte_size(Help_UC)):32/?UI,(Help_UC)/binary, 0:(((8- ((0+byte_size(Help_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -591,7 +591,7 @@ prependCheckItem(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text, Options)
This::wxMenu(), Itemid::integer(), Text::unicode:chardata().
prependRadioItem(This,Itemid,Text)
- when is_record(This, wx_ref),is_integer(Itemid),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Itemid),?is_chardata(Text) ->
prependRadioItem(This,Itemid,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmenu.html#wxmenuprependradioitem">external documentation</a>.
@@ -599,7 +599,7 @@ prependRadioItem(This,Itemid,Text)
This::wxMenu(), Itemid::integer(), Text::unicode:chardata(),
Option :: {'help', unicode:chardata()}.
prependRadioItem(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Text, Options)
- when is_integer(Itemid),is_list(Text),is_list(Options) ->
+ when is_integer(Itemid),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxMenu),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({help, Help}, Acc) -> Help_UC = unicode:characters_to_binary([Help,0]),[<<1:32/?UI,(byte_size(Help_UC)):32/?UI,(Help_UC)/binary, 0:(((8- ((0+byte_size(Help_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -640,7 +640,7 @@ remove(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ItemT,ref=ItemRef}) ->
-spec setHelpString(This, Itemid, HelpString) -> 'ok' when
This::wxMenu(), Itemid::integer(), HelpString::unicode:chardata().
setHelpString(#wx_ref{type=ThisT,ref=ThisRef},Itemid,HelpString)
- when is_integer(Itemid),is_list(HelpString) ->
+ when is_integer(Itemid),?is_chardata(HelpString) ->
?CLASS(ThisT,wxMenu),
HelpString_UC = unicode:characters_to_binary([HelpString,0]),
wxe_util:cast(?wxMenu_SetHelpString,
@@ -650,7 +650,7 @@ setHelpString(#wx_ref{type=ThisT,ref=ThisRef},Itemid,HelpString)
-spec setLabel(This, Itemid, Label) -> 'ok' when
This::wxMenu(), Itemid::integer(), Label::unicode:chardata().
setLabel(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Label)
- when is_integer(Itemid),is_list(Label) ->
+ when is_integer(Itemid),?is_chardata(Label) ->
?CLASS(ThisT,wxMenu),
Label_UC = unicode:characters_to_binary([Label,0]),
wxe_util:cast(?wxMenu_SetLabel,
@@ -660,7 +660,7 @@ setLabel(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Label)
-spec setTitle(This, Title) -> 'ok' when
This::wxMenu(), Title::unicode:chardata().
setTitle(#wx_ref{type=ThisT,ref=ThisRef},Title)
- when is_list(Title) ->
+ when ?is_chardata(Title) ->
?CLASS(ThisT,wxMenu),
Title_UC = unicode:characters_to_binary([Title,0]),
wxe_util:cast(?wxMenu_SetTitle,
diff --git a/lib/wx/src/gen/wxMenuBar.erl b/lib/wx/src/gen/wxMenuBar.erl
index 05f7a423d5..fa613c9f3b 100644
--- a/lib/wx/src/gen/wxMenuBar.erl
+++ b/lib/wx/src/gen/wxMenuBar.erl
@@ -41,26 +41,27 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
- getBackgroundStyle/1,getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,
- getChildren/1,getClientSize/1,getContainingSizer/1,getCursor/1,getDropTarget/1,
- getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getMaxSize/1,getMinSize/1,
- getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
- getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
- getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
- hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
- initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isExposed/2,
- isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,layout/1,
- lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,
- moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
- pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ dragAcceptFiles/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
+ getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
+ getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
+ getContentScaleFactor/1,getCursor/1,getDropTarget/1,getEventHandler/1,
+ getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
+ getHandle/1,getHelpText/1,getId/1,getMaxSize/1,getMinSize/1,getName/1,
+ getParent/1,getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,
+ getScrollPos/2,getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,
+ getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,inheritAttributes/1,initDialog/1,
+ invalidateBestSize/1,isDoubleBuffered/1,isExposed/2,isExposed/3,isExposed/5,
+ isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,
+ makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
+ setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
@@ -98,7 +99,7 @@ new(Style)
-spec append(This, Menu, Title) -> boolean() when
This::wxMenuBar(), Menu::wxMenu:wxMenu(), Title::unicode:chardata().
append(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=MenuT,ref=MenuRef},Title)
- when is_list(Title) ->
+ when ?is_chardata(Title) ->
?CLASS(ThisT,wxMenuBar),
?CLASS(MenuT,wxMenu),
Title_UC = unicode:characters_to_binary([Title,0]),
@@ -157,7 +158,7 @@ enableTop(#wx_ref{type=ThisT,ref=ThisRef},Pos,Flag)
-spec findMenu(This, Title) -> integer() when
This::wxMenuBar(), Title::unicode:chardata().
findMenu(#wx_ref{type=ThisT,ref=ThisRef},Title)
- when is_list(Title) ->
+ when ?is_chardata(Title) ->
?CLASS(ThisT,wxMenuBar),
Title_UC = unicode:characters_to_binary([Title,0]),
wxe_util:call(?wxMenuBar_FindMenu,
@@ -167,7 +168,7 @@ findMenu(#wx_ref{type=ThisT,ref=ThisRef},Title)
-spec findMenuItem(This, MenuString, ItemString) -> integer() when
This::wxMenuBar(), MenuString::unicode:chardata(), ItemString::unicode:chardata().
findMenuItem(#wx_ref{type=ThisT,ref=ThisRef},MenuString,ItemString)
- when is_list(MenuString),is_list(ItemString) ->
+ when ?is_chardata(MenuString),?is_chardata(ItemString) ->
?CLASS(ThisT,wxMenuBar),
MenuString_UC = unicode:characters_to_binary([MenuString,0]),
ItemString_UC = unicode:characters_to_binary([ItemString,0]),
@@ -239,7 +240,7 @@ getMenuCount(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec insert(This, Pos, Menu, Title) -> boolean() when
This::wxMenuBar(), Pos::integer(), Menu::wxMenu:wxMenu(), Title::unicode:chardata().
insert(#wx_ref{type=ThisT,ref=ThisRef},Pos,#wx_ref{type=MenuT,ref=MenuRef},Title)
- when is_integer(Pos),is_list(Title) ->
+ when is_integer(Pos),?is_chardata(Title) ->
?CLASS(ThisT,wxMenuBar),
?CLASS(MenuT,wxMenu),
Title_UC = unicode:characters_to_binary([Title,0]),
@@ -285,7 +286,7 @@ remove(#wx_ref{type=ThisT,ref=ThisRef},Pos)
-spec replace(This, Pos, Menu, Title) -> wxMenu:wxMenu() when
This::wxMenuBar(), Pos::integer(), Menu::wxMenu:wxMenu(), Title::unicode:chardata().
replace(#wx_ref{type=ThisT,ref=ThisRef},Pos,#wx_ref{type=MenuT,ref=MenuRef},Title)
- when is_integer(Pos),is_list(Title) ->
+ when is_integer(Pos),?is_chardata(Title) ->
?CLASS(ThisT,wxMenuBar),
?CLASS(MenuT,wxMenu),
Title_UC = unicode:characters_to_binary([Title,0]),
@@ -296,7 +297,7 @@ replace(#wx_ref{type=ThisT,ref=ThisRef},Pos,#wx_ref{type=MenuT,ref=MenuRef},Titl
-spec setHelpString(This, Itemid, HelpString) -> 'ok' when
This::wxMenuBar(), Itemid::integer(), HelpString::unicode:chardata().
setHelpString(#wx_ref{type=ThisT,ref=ThisRef},Itemid,HelpString)
- when is_integer(Itemid),is_list(HelpString) ->
+ when is_integer(Itemid),?is_chardata(HelpString) ->
?CLASS(ThisT,wxMenuBar),
HelpString_UC = unicode:characters_to_binary([HelpString,0]),
wxe_util:cast(?wxMenuBar_SetHelpString,
@@ -306,7 +307,7 @@ setHelpString(#wx_ref{type=ThisT,ref=ThisRef},Itemid,HelpString)
-spec setLabel(This, S) -> 'ok' when
This::wxMenuBar(), S::unicode:chardata().
setLabel(#wx_ref{type=ThisT,ref=ThisRef},S)
- when is_list(S) ->
+ when ?is_chardata(S) ->
?CLASS(ThisT,wxMenuBar),
S_UC = unicode:characters_to_binary([S,0]),
wxe_util:cast(?wxMenuBar_SetLabel_1,
@@ -316,7 +317,7 @@ setLabel(#wx_ref{type=ThisT,ref=ThisRef},S)
-spec setLabel(This, Itemid, Label) -> 'ok' when
This::wxMenuBar(), Itemid::integer(), Label::unicode:chardata().
setLabel(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Label)
- when is_integer(Itemid),is_list(Label) ->
+ when is_integer(Itemid),?is_chardata(Label) ->
?CLASS(ThisT,wxMenuBar),
Label_UC = unicode:characters_to_binary([Label,0]),
wxe_util:cast(?wxMenuBar_SetLabel_2,
@@ -326,7 +327,7 @@ setLabel(#wx_ref{type=ThisT,ref=ThisRef},Itemid,Label)
-spec setLabelTop(This, Pos, Label) -> 'ok' when
This::wxMenuBar(), Pos::integer(), Label::unicode:chardata().
setLabelTop(#wx_ref{type=ThisT,ref=ThisRef},Pos,Label)
- when is_integer(Pos),is_list(Label) ->
+ when is_integer(Pos),?is_chardata(Label) ->
?CLASS(ThisT,wxMenuBar),
Label_UC = unicode:characters_to_binary([Label,0]),
wxe_util:cast(?wxMenuBar_SetLabelTop,
@@ -340,6 +341,8 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -650,6 +653,8 @@ fit(This) -> wxWindow:fit(This).
%% @hidden
findWindow(This,Winid) -> wxWindow:findWindow(This,Winid).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxMenuItem.erl b/lib/wx/src/gen/wxMenuItem.erl
index 324910d15d..2e0a1c756a 100644
--- a/lib/wx/src/gen/wxMenuItem.erl
+++ b/lib/wx/src/gen/wxMenuItem.erl
@@ -153,7 +153,7 @@ getLabel(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec getLabelFromText(Text) -> unicode:charlist() when
Text::unicode:chardata().
getLabelFromText(Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:call(?wxMenuItem_GetLabelFromText,
<<(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((4+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8>>).
@@ -235,7 +235,7 @@ setBitmap(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BitmapT,ref=BitmapRef}) -
-spec setHelp(This, Str) -> 'ok' when
This::wxMenuItem(), Str::unicode:chardata().
setHelp(#wx_ref{type=ThisT,ref=ThisRef},Str)
- when is_list(Str) ->
+ when ?is_chardata(Str) ->
?CLASS(ThisT,wxMenuItem),
Str_UC = unicode:characters_to_binary([Str,0]),
wxe_util:cast(?wxMenuItem_SetHelp,
@@ -263,7 +263,7 @@ setSubMenu(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=MenuT,ref=MenuRef}) ->
-spec setText(This, Str) -> 'ok' when
This::wxMenuItem(), Str::unicode:chardata().
setText(#wx_ref{type=ThisT,ref=ThisRef},Str)
- when is_list(Str) ->
+ when ?is_chardata(Str) ->
?CLASS(ThisT,wxMenuItem),
Str_UC = unicode:characters_to_binary([Str,0]),
wxe_util:cast(?wxMenuItem_SetText,
diff --git a/lib/wx/src/gen/wxMessageDialog.erl b/lib/wx/src/gen/wxMessageDialog.erl
index 30e47529cc..a63f66741b 100644
--- a/lib/wx/src/gen/wxMessageDialog.erl
+++ b/lib/wx/src/gen/wxMessageDialog.erl
@@ -40,40 +40,40 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
+ lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
+ requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
@@ -93,7 +93,7 @@ parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
Parent::wxWindow:wxWindow(), Message::unicode:chardata().
new(Parent,Message)
- when is_record(Parent, wx_ref),is_list(Message) ->
+ when is_record(Parent, wx_ref),?is_chardata(Message) ->
new(Parent,Message, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmessagedialog.html#wxmessagedialogwxmessagedialog">external documentation</a>.
@@ -103,7 +103,7 @@ new(Parent,Message)
| {'style', integer()}
| {'pos', {X::integer(), Y::integer()}}.
new(#wx_ref{type=ParentT,ref=ParentRef},Message, Options)
- when is_list(Message),is_list(Options) ->
+ when ?is_chardata(Message),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Message_UC = unicode:characters_to_binary([Message,0]),
MOpts = fun({caption, Caption}, Acc) -> Caption_UC = unicode:characters_to_binary([Caption,0]),[<<1:32/?UI,(byte_size(Caption_UC)):32/?UI,(Caption_UC)/binary, 0:(((8- ((0+byte_size(Caption_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -192,6 +192,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -508,6 +510,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxMiniFrame.erl b/lib/wx/src/gen/wxMiniFrame.erl
index 4ae9764819..37dc2f2e04 100644
--- a/lib/wx/src/gen/wxMiniFrame.erl
+++ b/lib/wx/src/gen/wxMiniFrame.erl
@@ -41,27 +41,28 @@
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createStatusBar/1,createStatusBar/2,createToolBar/1,createToolBar/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientAreaOrigin/1,
- getClientSize/1,getContainingSizer/1,getCursor/1,getDropTarget/1,
- getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
- getLabel/1,getMaxSize/1,getMenuBar/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getStatusBar/1,
- getStatusBarPane/1,getTextExtent/2,getTextExtent/3,getTitle/1,getToolBar/1,
- getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- processCommand/2,raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,
- releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientAreaOrigin/1,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
+ getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,getMenuBar/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getStatusBar/1,getStatusBarPane/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolBar/1,getToolTip/1,getUpdateRegion/1,
+ getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
+ hasScrollbar/2,hasTransparentBackground/1,hide/1,iconize/1,iconize/2,
+ inheritAttributes/1,initDialog/1,invalidateBestSize/1,isActive/1,
+ isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
+ isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
+ maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
scrollWindow/4,sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,
setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
@@ -101,7 +102,7 @@ new() ->
Parent::wxWindow:wxWindow(), Id::integer(), Title::unicode:chardata().
new(Parent,Id,Title)
- when is_record(Parent, wx_ref),is_integer(Id),is_list(Title) ->
+ when is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title) ->
new(Parent,Id,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxminiframe.html#wxminiframewxminiframe">external documentation</a>.
@@ -111,7 +112,7 @@ new(Parent,Id,Title)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
- when is_integer(Id),is_list(Title),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Title_UC = unicode:characters_to_binary([Title,0]),
MOpts = fun({pos, {PosX,PosY}}, Acc) -> [<<1:32/?UI,PosX:32/?UI,PosY:32/?UI,0:32>>|Acc];
@@ -127,7 +128,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
This::wxMiniFrame(), Parent::wxWindow:wxWindow(), Id::integer(), Title::unicode:chardata().
create(This,Parent,Id,Title)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Title) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title) ->
create(This,Parent,Id,Title, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxminiframe.html#wxminiframecreate">external documentation</a>.
@@ -137,7 +138,7 @@ create(This,Parent,Id,Title)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options)
- when is_integer(Id),is_list(Title),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_list(Options) ->
?CLASS(ThisT,wxMiniFrame),
?CLASS(ParentT,wxWindow),
Title_UC = unicode:characters_to_binary([Title,0]),
@@ -241,6 +242,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -561,6 +564,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxMultiChoiceDialog.erl b/lib/wx/src/gen/wxMultiChoiceDialog.erl
index 0436515256..eef15d561e 100644
--- a/lib/wx/src/gen/wxMultiChoiceDialog.erl
+++ b/lib/wx/src/gen/wxMultiChoiceDialog.erl
@@ -40,40 +40,40 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
+ lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
+ requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
@@ -99,7 +99,7 @@ new() ->
Parent::wxWindow:wxWindow(), Message::unicode:chardata(), Caption::unicode:chardata(), Choices::[unicode:chardata()].
new(Parent,Message,Caption,Choices)
- when is_record(Parent, wx_ref),is_list(Message),is_list(Caption),is_list(Choices) ->
+ when is_record(Parent, wx_ref),?is_chardata(Message),?is_chardata(Caption),is_list(Choices) ->
new(Parent,Message,Caption,Choices, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxmultichoicedialog.html#wxmultichoicedialogwxmultichoicedialog">external documentation</a>.
@@ -108,7 +108,7 @@ new(Parent,Message,Caption,Choices)
Option :: {'style', integer()}
| {'pos', {X::integer(), Y::integer()}}.
new(#wx_ref{type=ParentT,ref=ParentRef},Message,Caption,Choices, Options)
- when is_list(Message),is_list(Caption),is_list(Choices),is_list(Options) ->
+ when ?is_chardata(Message),?is_chardata(Caption),is_list(Choices),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Message_UC = unicode:characters_to_binary([Message,0]),
Caption_UC = unicode:characters_to_binary([Caption,0]),
@@ -217,6 +217,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -533,6 +535,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxNotebook.erl b/lib/wx/src/gen/wxNotebook.erl
index 24f96ac88c..d7d1b0f87f 100644
--- a/lib/wx/src/gen/wxNotebook.erl
+++ b/lib/wx/src/gen/wxNotebook.erl
@@ -43,29 +43,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -120,7 +120,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Winid, Options)
This::wxNotebook(), Page::wxWindow:wxWindow(), Text::unicode:chardata().
addPage(This,Page,Text)
- when is_record(This, wx_ref),is_record(Page, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_record(Page, wx_ref),?is_chardata(Text) ->
addPage(This,Page,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxnotebook.html#wxnotebookaddpage">external documentation</a>.
@@ -129,7 +129,7 @@ addPage(This,Page,Text)
Option :: {'bSelect', boolean()}
| {'imageId', integer()}.
addPage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PageT,ref=PageRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+ when ?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxNotebook),
?CLASS(PageT,wxWindow),
Text_UC = unicode:characters_to_binary([Text,0]),
@@ -312,7 +312,7 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY})
This::wxNotebook(), Position::integer(), Win::wxWindow:wxWindow(), StrText::unicode:chardata().
insertPage(This,Position,Win,StrText)
- when is_record(This, wx_ref),is_integer(Position),is_record(Win, wx_ref),is_list(StrText) ->
+ when is_record(This, wx_ref),is_integer(Position),is_record(Win, wx_ref),?is_chardata(StrText) ->
insertPage(This,Position,Win,StrText, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxnotebook.html#wxnotebookinsertpage">external documentation</a>.
@@ -321,7 +321,7 @@ insertPage(This,Position,Win,StrText)
Option :: {'bSelect', boolean()}
| {'imageId', integer()}.
insertPage(#wx_ref{type=ThisT,ref=ThisRef},Position,#wx_ref{type=WinT,ref=WinRef},StrText, Options)
- when is_integer(Position),is_list(StrText),is_list(Options) ->
+ when is_integer(Position),?is_chardata(StrText),is_list(Options) ->
?CLASS(ThisT,wxNotebook),
?CLASS(WinT,wxWindow),
StrText_UC = unicode:characters_to_binary([StrText,0]),
@@ -372,7 +372,7 @@ setPageImage(#wx_ref{type=ThisT,ref=ThisRef},NPage,NImage)
-spec setPageText(This, NPage, StrText) -> boolean() when
This::wxNotebook(), NPage::integer(), StrText::unicode:chardata().
setPageText(#wx_ref{type=ThisT,ref=ThisRef},NPage,StrText)
- when is_integer(NPage),is_list(StrText) ->
+ when is_integer(NPage),?is_chardata(StrText) ->
?CLASS(ThisT,wxNotebook),
StrText_UC = unicode:characters_to_binary([StrText,0]),
wxe_util:call(?wxNotebook_SetPageText,
@@ -409,6 +409,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -725,6 +727,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxPanel.erl b/lib/wx/src/gen/wxPanel.erl
index 07898cf19e..fc48d569af 100644
--- a/lib/wx/src/gen/wxPanel.erl
+++ b/lib/wx/src/gen/wxPanel.erl
@@ -37,29 +37,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
+ isExposed/5,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,
+ lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
+ popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
+ setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -155,6 +155,8 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -473,6 +475,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxPasswordEntryDialog.erl b/lib/wx/src/gen/wxPasswordEntryDialog.erl
index e8ee8c8f37..4667376783 100644
--- a/lib/wx/src/gen/wxPasswordEntryDialog.erl
+++ b/lib/wx/src/gen/wxPasswordEntryDialog.erl
@@ -41,34 +41,34 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getValue/1,getVirtualSize/1,
- getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
- hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
- initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
- isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
- lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
- move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
- pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
- requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
- scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getValue/1,
+ getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
+ hasScrollbar/2,hasTransparentBackground/1,hide/1,iconize/1,iconize/2,
+ inheritAttributes/1,initDialog/1,invalidateBestSize/1,isActive/1,
+ isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
+ isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,requestUserAttention/1,requestUserAttention/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,
+ setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
+ setCursor/2,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,
+ setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,
+ setIcons/2,setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -95,7 +95,7 @@ parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
Parent::wxWindow:wxWindow(), Message::unicode:chardata().
new(Parent,Message)
- when is_record(Parent, wx_ref),is_list(Message) ->
+ when is_record(Parent, wx_ref),?is_chardata(Message) ->
new(Parent,Message, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxpasswordentrydialog.html#wxpasswordentrydialogwxpasswordentrydialog">external documentation</a>.
@@ -106,7 +106,7 @@ new(Parent,Message)
| {'style', integer()}
| {'pos', {X::integer(), Y::integer()}}.
new(#wx_ref{type=ParentT,ref=ParentRef},Message, Options)
- when is_list(Message),is_list(Options) ->
+ when ?is_chardata(Message),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Message_UC = unicode:characters_to_binary([Message,0]),
MOpts = fun({caption, Caption}, Acc) -> Caption_UC = unicode:characters_to_binary([Caption,0]),[<<1:32/?UI,(byte_size(Caption_UC)):32/?UI,(Caption_UC)/binary, 0:(((8- ((0+byte_size(Caption_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -201,6 +201,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -517,6 +519,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxPickerBase.erl b/lib/wx/src/gen/wxPickerBase.erl
index 33931f9119..0ea3a36d33 100644
--- a/lib/wx/src/gen/wxPickerBase.erl
+++ b/lib/wx/src/gen/wxPickerBase.erl
@@ -41,29 +41,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -214,6 +214,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -530,6 +532,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxPopupTransientWindow.erl b/lib/wx/src/gen/wxPopupTransientWindow.erl
index b1feef6dcb..6ec2fcae62 100644
--- a/lib/wx/src/gen/wxPopupTransientWindow.erl
+++ b/lib/wx/src/gen/wxPopupTransientWindow.erl
@@ -38,38 +38,39 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,position/3,raise/1,
- refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
- setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
- setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
- setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,position/3,raise/1,refresh/1,refresh/2,
+ refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,
+ screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
+ scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,
+ setBackgroundStyle/2,setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,
+ setCursor/2,setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,
+ setFocusFromKbd/1,setFont/2,setForegroundColour/2,setHelpText/2,setId/2,
+ setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
+ setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,setToolTip/2,
+ setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxPopupTransientWindow/0]).
%% @hidden
@@ -146,6 +147,8 @@ destroy(Obj=#wx_ref{type=Type}) ->
position(This,PtOrigin,Size) -> wxPopupWindow:position(This,PtOrigin,Size).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -466,6 +469,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxPopupWindow.erl b/lib/wx/src/gen/wxPopupWindow.erl
index 962fd9903b..ddf1033841 100644
--- a/lib/wx/src/gen/wxPopupWindow.erl
+++ b/lib/wx/src/gen/wxPopupWindow.erl
@@ -37,29 +37,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -143,6 +143,8 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -463,6 +465,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxPreviewCanvas.erl b/lib/wx/src/gen/wxPreviewCanvas.erl
index 67357dbd65..4e869dd6f2 100644
--- a/lib/wx/src/gen/wxPreviewCanvas.erl
+++ b/lib/wx/src/gen/wxPreviewCanvas.erl
@@ -40,37 +40,37 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- doPrepareDC/2,enable/1,enable/2,enableScrolling/3,findWindow/2,fit/1,
- fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
+ doPrepareDC/2,dragAcceptFiles/2,enable/1,enable/2,enableScrolling/3,
+ findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
getBackgroundStyle/1,getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,
- getChildren/1,getClientSize/1,getContainingSizer/1,getCursor/1,getDropTarget/1,
- getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPixelsPerUnit/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getToolTip/1,getUpdateRegion/1,getViewStart/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scroll/3,
- scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFocusIgnoringChildren/1,setFont/2,setForegroundColour/2,setHelpText/2,
- setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
- setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
- setScrollPos/4,setScrollRate/3,setScrollbar/5,setScrollbar/6,setScrollbars/5,
- setScrollbars/6,setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,
- setSizeHints/3,setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,
- setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,setToolTip/2,
- setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ getChildren/1,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
+ getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPixelsPerUnit/1,
+ getScrollPos/2,getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,
+ getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getViewStart/1,
+ getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
+ hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,prepareDC/2,raise/1,refresh/1,refresh/2,
+ refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,
+ screenToClient/1,screenToClient/2,scroll/3,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ setPalette/2,setScrollPos/3,setScrollPos/4,setScrollRate/3,setScrollbar/5,
+ setScrollbar/6,setScrollbars/5,setScrollbars/6,setSize/2,setSize/3,
+ setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setTargetWindow/2,setThemeEnabled/2,
+ setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
@@ -121,6 +121,8 @@ setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This).
initDialog(This) -> wxPanel:initDialog(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -439,6 +441,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxPreviewControlBar.erl b/lib/wx/src/gen/wxPreviewControlBar.erl
index 4dd224b26b..cf17f40527 100644
--- a/lib/wx/src/gen/wxPreviewControlBar.erl
+++ b/lib/wx/src/gen/wxPreviewControlBar.erl
@@ -39,38 +39,39 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
- setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
- setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
- setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFocusIgnoringChildren/1,setFont/2,setForegroundColour/2,setHelpText/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
+ setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,setToolTip/2,
+ setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxPreviewControlBar/0]).
%% @hidden
@@ -152,6 +153,8 @@ setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This).
initDialog(This) -> wxPanel:initDialog(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -470,6 +473,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxPreviewFrame.erl b/lib/wx/src/gen/wxPreviewFrame.erl
index 2f530b49ea..022b0cd46e 100644
--- a/lib/wx/src/gen/wxPreviewFrame.erl
+++ b/lib/wx/src/gen/wxPreviewFrame.erl
@@ -42,27 +42,28 @@
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createStatusBar/1,createStatusBar/2,createToolBar/1,createToolBar/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientAreaOrigin/1,
- getClientSize/1,getContainingSizer/1,getCursor/1,getDropTarget/1,
- getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
- getLabel/1,getMaxSize/1,getMenuBar/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getStatusBar/1,
- getStatusBarPane/1,getTextExtent/2,getTextExtent/3,getTitle/1,getToolBar/1,
- getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- processCommand/2,raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,
- releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientAreaOrigin/1,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
+ getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,getMenuBar/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getStatusBar/1,getStatusBarPane/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolBar/1,getToolTip/1,getUpdateRegion/1,
+ getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
+ hasScrollbar/2,hasTransparentBackground/1,hide/1,iconize/1,iconize/2,
+ inheritAttributes/1,initDialog/1,invalidateBestSize/1,isActive/1,
+ isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
+ isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
+ maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
scrollWindow/4,sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,
setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
@@ -244,6 +245,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -564,6 +567,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxPrintData.erl b/lib/wx/src/gen/wxPrintData.erl
index 6b6b678adf..b6815da90b 100644
--- a/lib/wx/src/gen/wxPrintData.erl
+++ b/lib/wx/src/gen/wxPrintData.erl
@@ -205,7 +205,7 @@ setPaperId(#wx_ref{type=ThisT,ref=ThisRef},SizeId)
-spec setPrinterName(This, Name) -> 'ok' when
This::wxPrintData(), Name::unicode:chardata().
setPrinterName(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxPrintData),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:cast(?wxPrintData_SetPrinterName,
diff --git a/lib/wx/src/gen/wxPrintDialog.erl b/lib/wx/src/gen/wxPrintDialog.erl
index d4188e79c4..4024036166 100644
--- a/lib/wx/src/gen/wxPrintDialog.erl
+++ b/lib/wx/src/gen/wxPrintDialog.erl
@@ -40,40 +40,40 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
+ lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
+ requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
@@ -214,6 +214,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -530,6 +532,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxPrinter.erl b/lib/wx/src/gen/wxPrinter.erl
index b9fb1c07bd..bdca37b4a8 100644
--- a/lib/wx/src/gen/wxPrinter.erl
+++ b/lib/wx/src/gen/wxPrinter.erl
@@ -122,7 +122,7 @@ printDialog(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef})
-spec reportError(This, Parent, Printout, Message) -> 'ok' when
This::wxPrinter(), Parent::wxWindow:wxWindow(), Printout::wxPrintout:wxPrintout(), Message::unicode:chardata().
reportError(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},#wx_ref{type=PrintoutT,ref=PrintoutRef},Message)
- when is_list(Message) ->
+ when ?is_chardata(Message) ->
?CLASS(ThisT,wxPrinter),
?CLASS(ParentT,wxWindow),
?CLASS(PrintoutT,wxPrintout),
diff --git a/lib/wx/src/gen/wxProgressDialog.erl b/lib/wx/src/gen/wxProgressDialog.erl
index 8e275f9dc8..a17cb0383a 100644
--- a/lib/wx/src/gen/wxProgressDialog.erl
+++ b/lib/wx/src/gen/wxProgressDialog.erl
@@ -40,40 +40,40 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
+ lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
+ requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
transferDataFromWindow/1,transferDataToWindow/1,updateWindowUI/1,
@@ -93,7 +93,7 @@ parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
Title::unicode:chardata(), Message::unicode:chardata().
new(Title,Message)
- when is_list(Title),is_list(Message) ->
+ when ?is_chardata(Title),?is_chardata(Message) ->
new(Title,Message, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxprogressdialog.html#wxprogressdialogwxprogressdialog">external documentation</a>.
@@ -103,7 +103,7 @@ new(Title,Message)
| {'parent', wxWindow:wxWindow()}
| {'style', integer()}.
new(Title,Message, Options)
- when is_list(Title),is_list(Message),is_list(Options) ->
+ when ?is_chardata(Title),?is_chardata(Message),is_list(Options) ->
Title_UC = unicode:characters_to_binary([Title,0]),
Message_UC = unicode:characters_to_binary([Message,0]),
MOpts = fun({maximum, Maximum}, Acc) -> [<<1:32/?UI,Maximum:32/?UI>>|Acc];
@@ -229,6 +229,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -543,6 +545,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxRadioBox.erl b/lib/wx/src/gen/wxRadioBox.erl
index 348d75db2a..13d3a496ac 100644
--- a/lib/wx/src/gen/wxRadioBox.erl
+++ b/lib/wx/src/gen/wxRadioBox.erl
@@ -41,12 +41,13 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,getBackgroundColour/1,
- getBackgroundStyle/1,getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,
- getChildren/1,getClientSize/1,getContainingSizer/1,getCursor/1,getDropTarget/1,
- getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ dragAcceptFiles/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
+ getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
+ getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
+ getContentScaleFactor/1,getCursor/1,getDropTarget/1,getEventHandler/1,
+ getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
+ getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
@@ -86,7 +87,7 @@ parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
Parent::wxWindow:wxWindow(), Id::integer(), Title::unicode:chardata(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[unicode:chardata()].
new(Parent,Id,Title,Pos={PosX,PosY},Size={SizeW,SizeH},Choices)
- when is_record(Parent, wx_ref),is_integer(Id),is_list(Title),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices) ->
+ when is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices) ->
new(Parent,Id,Title,Pos,Size,Choices, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxradiobox.html#wxradioboxwxradiobox">external documentation</a>.
@@ -96,7 +97,7 @@ new(Parent,Id,Title,Pos={PosX,PosY},Size={SizeW,SizeH},Choices)
| {'style', integer()}
| {'val', wx:wx_object()}.
new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title,{PosX,PosY},{SizeW,SizeH},Choices, Options)
- when is_integer(Id),is_list(Title),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Title_UC = unicode:characters_to_binary([Title,0]),
Choices_UCA = [unicode:characters_to_binary([ChoicesTemp,0]) ||
@@ -114,7 +115,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title,{PosX,PosY},{SizeW,SizeH},Choic
This::wxRadioBox(), Parent::wxWindow:wxWindow(), Id::integer(), Title::unicode:chardata(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[unicode:chardata()].
create(This,Parent,Id,Title,Pos={PosX,PosY},Size={SizeW,SizeH},Choices)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Title),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Title),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices) ->
create(This,Parent,Id,Title,Pos,Size,Choices, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxradiobox.html#wxradioboxcreate">external documentation</a>.
@@ -124,7 +125,7 @@ create(This,Parent,Id,Title,Pos={PosX,PosY},Size={SizeW,SizeH},Choices)
| {'style', integer()}
| {'val', wx:wx_object()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title,{PosX,PosY},{SizeW,SizeH},Choices, Options)
- when is_integer(Id),is_list(Title),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Title),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices),is_list(Options) ->
?CLASS(ThisT,wxRadioBox),
?CLASS(ParentT,wxWindow),
Title_UC = unicode:characters_to_binary([Title,0]),
@@ -319,7 +320,7 @@ isItemShown(#wx_ref{type=ThisT,ref=ThisRef},N)
-spec setItemHelpText(This, N, HelpText) -> 'ok' when
This::wxRadioBox(), N::integer(), HelpText::unicode:chardata().
setItemHelpText(#wx_ref{type=ThisT,ref=ThisRef},N,HelpText)
- when is_integer(N),is_list(HelpText) ->
+ when is_integer(N),?is_chardata(HelpText) ->
?CLASS(ThisT,wxRadioBox),
HelpText_UC = unicode:characters_to_binary([HelpText,0]),
wxe_util:cast(?wxRadioBox_SetItemHelpText,
@@ -329,7 +330,7 @@ setItemHelpText(#wx_ref{type=ThisT,ref=ThisRef},N,HelpText)
-spec setItemToolTip(This, Item, Text) -> 'ok' when
This::wxRadioBox(), Item::integer(), Text::unicode:chardata().
setItemToolTip(#wx_ref{type=ThisT,ref=ThisRef},Item,Text)
- when is_integer(Item),is_list(Text) ->
+ when is_integer(Item),?is_chardata(Text) ->
?CLASS(ThisT,wxRadioBox),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxRadioBox_SetItemToolTip,
@@ -348,6 +349,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -656,6 +659,8 @@ fit(This) -> wxWindow:fit(This).
%% @hidden
findWindow(This,Winid) -> wxWindow:findWindow(This,Winid).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxRadioButton.erl b/lib/wx/src/gen/wxRadioButton.erl
index 4487724be6..b5635e8afe 100644
--- a/lib/wx/src/gen/wxRadioButton.erl
+++ b/lib/wx/src/gen/wxRadioButton.erl
@@ -38,29 +38,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -90,7 +90,7 @@ new() ->
Parent::wxWindow:wxWindow(), Id::integer(), Label::unicode:chardata().
new(Parent,Id,Label)
- when is_record(Parent, wx_ref),is_integer(Id),is_list(Label) ->
+ when is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Label) ->
new(Parent,Id,Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxradiobutton.html#wxradiobuttonwxradiobutton">external documentation</a>.
@@ -101,7 +101,7 @@ new(Parent,Id,Label)
| {'style', integer()}
| {'validator', wx:wx_object()}.
new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
- when is_integer(Id),is_list(Label),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Label),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Label_UC = unicode:characters_to_binary([Label,0]),
MOpts = fun({pos, {PosX,PosY}}, Acc) -> [<<1:32/?UI,PosX:32/?UI,PosY:32/?UI,0:32>>|Acc];
@@ -118,7 +118,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
This::wxRadioButton(), Parent::wxWindow:wxWindow(), Id::integer(), Label::unicode:chardata().
create(This,Parent,Id,Label)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Label) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Label) ->
create(This,Parent,Id,Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxradiobutton.html#wxradiobuttoncreate">external documentation</a>.
@@ -129,7 +129,7 @@ create(This,Parent,Id,Label)
| {'style', integer()}
| {'validator', wx:wx_object()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
- when is_integer(Id),is_list(Label),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Label),is_list(Options) ->
?CLASS(ThisT,wxRadioButton),
?CLASS(ParentT,wxWindow),
Label_UC = unicode:characters_to_binary([Label,0]),
@@ -172,6 +172,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -488,6 +490,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxSashLayoutWindow.erl b/lib/wx/src/gen/wxSashLayoutWindow.erl
index ae081ae800..a0e240b25d 100644
--- a/lib/wx/src/gen/wxSashLayoutWindow.erl
+++ b/lib/wx/src/gen/wxSashLayoutWindow.erl
@@ -39,30 +39,31 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMaximumSizeX/1,getMaximumSizeY/1,
- getMinSize/1,getMinimumSizeX/1,getMinimumSizeY/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getSashVisible/2,getScreenPosition/1,getScreenRect/1,
- getScrollPos/2,getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,
- getTextExtent/2,getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
- getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
- hasTransparentBackground/1,hide/1,inheritAttributes/1,initDialog/1,
- invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,
- lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,
- scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMaximumSizeX/1,getMaximumSizeY/1,getMinSize/1,getMinimumSizeX/1,
+ getMinimumSizeY/1,getName/1,getParent/1,getPosition/1,getRect/1,getSashVisible/2,
+ getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
+ getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
+ getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
+ getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMaximumSizeX/2,setMaximumSizeY/2,setMinSize/2,setMinimumSizeX/2,
setMinimumSizeY/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
setOwnForegroundColour/2,setPalette/2,setSashVisible/3,setScrollPos/3,
@@ -220,6 +221,8 @@ getMaximumSizeX(This) -> wxSashWindow:getMaximumSizeX(This).
getSashVisible(This,Edge) -> wxSashWindow:getSashVisible(This,Edge).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -540,6 +543,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxSashWindow.erl b/lib/wx/src/gen/wxSashWindow.erl
index 773e0f1ab0..5e66d79b11 100644
--- a/lib/wx/src/gen/wxSashWindow.erl
+++ b/lib/wx/src/gen/wxSashWindow.erl
@@ -39,29 +39,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -208,6 +208,8 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -528,6 +530,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxScrollBar.erl b/lib/wx/src/gen/wxScrollBar.erl
index 7f70d9d97b..a1138725cd 100644
--- a/lib/wx/src/gen/wxScrollBar.erl
+++ b/lib/wx/src/gen/wxScrollBar.erl
@@ -39,29 +39,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setSize/2,setSize/3,setSize/5,
setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
@@ -216,6 +216,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -528,6 +530,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxScrolledWindow.erl b/lib/wx/src/gen/wxScrolledWindow.erl
index 70bc5adbd9..e3f6122cfa 100644
--- a/lib/wx/src/gen/wxScrolledWindow.erl
+++ b/lib/wx/src/gen/wxScrolledWindow.erl
@@ -41,38 +41,39 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFocusIgnoringChildren/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
- setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
- setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
- setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
- setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
- setThemeEnabled/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
- setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
- setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
- show/1,show/2,thaw/1,transferDataFromWindow/1,transferDataToWindow/1,
- update/1,updateWindowUI/1,updateWindowUI/2,validate/1,warpPointer/3]).
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFocusIgnoringChildren/1,setFont/2,setForegroundColour/2,setHelpText/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setScrollPos/3,
+ setScrollPos/4,setScrollbar/5,setScrollbar/6,setSize/2,setSize/3,setSize/5,
+ setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,setSizer/2,
+ setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,setToolTip/2,
+ setTransparent/2,setVirtualSize/2,setVirtualSize/3,setVirtualSizeHints/2,
+ setVirtualSizeHints/3,setVirtualSizeHints/4,setWindowStyle/2,setWindowStyleFlag/2,
+ setWindowVariant/2,shouldInheritColours/1,show/1,show/2,thaw/1,transferDataFromWindow/1,
+ transferDataToWindow/1,update/1,updateWindowUI/1,updateWindowUI/2,
+ validate/1,warpPointer/3]).
-export_type([wxScrolledWindow/0]).
%% @hidden
@@ -259,6 +260,8 @@ setFocusIgnoringChildren(This) -> wxPanel:setFocusIgnoringChildren(This).
initDialog(This) -> wxPanel:initDialog(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -577,6 +580,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxSingleChoiceDialog.erl b/lib/wx/src/gen/wxSingleChoiceDialog.erl
index baff296d11..8b2991da4d 100644
--- a/lib/wx/src/gen/wxSingleChoiceDialog.erl
+++ b/lib/wx/src/gen/wxSingleChoiceDialog.erl
@@ -40,40 +40,40 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
+ lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
+ requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
@@ -99,7 +99,7 @@ new() ->
Parent::wxWindow:wxWindow(), Message::unicode:chardata(), Caption::unicode:chardata(), Choices::[unicode:chardata()].
new(Parent,Message,Caption,Choices)
- when is_record(Parent, wx_ref),is_list(Message),is_list(Caption),is_list(Choices) ->
+ when is_record(Parent, wx_ref),?is_chardata(Message),?is_chardata(Caption),is_list(Choices) ->
new(Parent,Message,Caption,Choices, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxsinglechoicedialog.html#wxsinglechoicedialogwxsinglechoicedialog">external documentation</a>.
@@ -108,7 +108,7 @@ new(Parent,Message,Caption,Choices)
Option :: {'style', integer()}
| {'pos', {X::integer(), Y::integer()}}.
new(#wx_ref{type=ParentT,ref=ParentRef},Message,Caption,Choices, Options)
- when is_list(Message),is_list(Caption),is_list(Choices),is_list(Options) ->
+ when ?is_chardata(Message),?is_chardata(Caption),is_list(Choices),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Message_UC = unicode:characters_to_binary([Message,0]),
Caption_UC = unicode:characters_to_binary([Caption,0]),
@@ -224,6 +224,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -540,6 +542,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxSlider.erl b/lib/wx/src/gen/wxSlider.erl
index a215b3c1d5..7bdff00589 100644
--- a/lib/wx/src/gen/wxSlider.erl
+++ b/lib/wx/src/gen/wxSlider.erl
@@ -40,29 +40,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -248,6 +248,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -564,6 +566,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxSpinButton.erl b/lib/wx/src/gen/wxSpinButton.erl
index 1c8d674d05..6c24176974 100644
--- a/lib/wx/src/gen/wxSpinButton.erl
+++ b/lib/wx/src/gen/wxSpinButton.erl
@@ -39,29 +39,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -196,6 +196,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -512,6 +514,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxSpinCtrl.erl b/lib/wx/src/gen/wxSpinCtrl.erl
index f8a46dd146..c229b4caf1 100644
--- a/lib/wx/src/gen/wxSpinCtrl.erl
+++ b/lib/wx/src/gen/wxSpinCtrl.erl
@@ -39,29 +39,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -172,7 +172,7 @@ setValue(#wx_ref{type=ThisT,ref=ThisRef},Value)
wxe_util:cast(?wxSpinCtrl_SetValue_1_0,
<<ThisRef:32/?UI,Value:32/?UI>>);
setValue(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxSpinCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxSpinCtrl_SetValue_1_1,
@@ -233,6 +233,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -549,6 +551,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxSplashScreen.erl b/lib/wx/src/gen/wxSplashScreen.erl
index 3b53e670c1..9729b3529b 100644
--- a/lib/wx/src/gen/wxSplashScreen.erl
+++ b/lib/wx/src/gen/wxSplashScreen.erl
@@ -41,27 +41,28 @@
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createStatusBar/1,createStatusBar/2,createToolBar/1,createToolBar/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientAreaOrigin/1,
- getClientSize/1,getContainingSizer/1,getCursor/1,getDropTarget/1,
- getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
- getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
- getLabel/1,getMaxSize/1,getMenuBar/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getStatusBar/1,
- getStatusBarPane/1,getTextExtent/2,getTextExtent/3,getTitle/1,getToolBar/1,
- getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- processCommand/2,raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,
- releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientAreaOrigin/1,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
+ getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,getMenuBar/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getStatusBar/1,getStatusBarPane/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolBar/1,getToolTip/1,getUpdateRegion/1,
+ getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,
+ hasScrollbar/2,hasTransparentBackground/1,hide/1,iconize/1,iconize/2,
+ inheritAttributes/1,initDialog/1,invalidateBestSize/1,isActive/1,
+ isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,isExposed/5,
+ isFullScreen/1,isIconized/1,isMaximized/1,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,maximize/1,
+ maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,processCommand/2,
+ raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
+ removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
scrollWindow/4,sendSizeEvent/1,setAcceleratorTable/2,setAutoLayout/2,
setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
@@ -230,6 +231,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -550,6 +553,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxSplitterWindow.erl b/lib/wx/src/gen/wxSplitterWindow.erl
index f311d5011f..fb2f355f43 100644
--- a/lib/wx/src/gen/wxSplitterWindow.erl
+++ b/lib/wx/src/gen/wxSplitterWindow.erl
@@ -42,29 +42,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -359,6 +359,8 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -679,6 +681,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxStaticBitmap.erl b/lib/wx/src/gen/wxStaticBitmap.erl
index 3ef1499a28..64d8cc4364 100644
--- a/lib/wx/src/gen/wxStaticBitmap.erl
+++ b/lib/wx/src/gen/wxStaticBitmap.erl
@@ -38,29 +38,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -168,6 +168,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -484,6 +486,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxStaticBox.erl b/lib/wx/src/gen/wxStaticBox.erl
index 46cca3b6f3..728c02e9e4 100644
--- a/lib/wx/src/gen/wxStaticBox.erl
+++ b/lib/wx/src/gen/wxStaticBox.erl
@@ -38,29 +38,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -90,7 +90,7 @@ new() ->
Parent::wxWindow:wxWindow(), Id::integer(), Label::unicode:chardata().
new(Parent,Id,Label)
- when is_record(Parent, wx_ref),is_integer(Id),is_list(Label) ->
+ when is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Label) ->
new(Parent,Id,Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxstaticbox.html#wxstaticboxwxstaticbox">external documentation</a>.
@@ -100,7 +100,7 @@ new(Parent,Id,Label)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
- when is_integer(Id),is_list(Label),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Label),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Label_UC = unicode:characters_to_binary([Label,0]),
MOpts = fun({pos, {PosX,PosY}}, Acc) -> [<<1:32/?UI,PosX:32/?UI,PosY:32/?UI,0:32>>|Acc];
@@ -116,7 +116,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
This::wxStaticBox(), Parent::wxWindow:wxWindow(), Id::integer(), Label::unicode:chardata().
create(This,Parent,Id,Label)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Label) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Label) ->
create(This,Parent,Id,Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxstaticbox.html#wxstaticboxcreate">external documentation</a>.
@@ -126,7 +126,7 @@ create(This,Parent,Id,Label)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
- when is_integer(Id),is_list(Label),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Label),is_list(Options) ->
?CLASS(ThisT,wxStaticBox),
?CLASS(ParentT,wxWindow),
Label_UC = unicode:characters_to_binary([Label,0]),
@@ -151,6 +151,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -467,6 +469,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxStaticLine.erl b/lib/wx/src/gen/wxStaticLine.erl
index 94dd339cfc..3c648b7746 100644
--- a/lib/wx/src/gen/wxStaticLine.erl
+++ b/lib/wx/src/gen/wxStaticLine.erl
@@ -39,29 +39,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -168,6 +168,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -484,6 +486,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxStaticText.erl b/lib/wx/src/gen/wxStaticText.erl
index 37d0219bc6..34216f975f 100644
--- a/lib/wx/src/gen/wxStaticText.erl
+++ b/lib/wx/src/gen/wxStaticText.erl
@@ -38,30 +38,30 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
- getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,setMinSize/2,
- setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getMaxSize/1,getMinSize/1,
+ getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setMaxSize/2,
+ setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
@@ -90,7 +90,7 @@ new() ->
Parent::wxWindow:wxWindow(), Id::integer(), Label::unicode:chardata().
new(Parent,Id,Label)
- when is_record(Parent, wx_ref),is_integer(Id),is_list(Label) ->
+ when is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Label) ->
new(Parent,Id,Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxstatictext.html#wxstatictextwxstatictext">external documentation</a>.
@@ -100,7 +100,7 @@ new(Parent,Id,Label)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
- when is_integer(Id),is_list(Label),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Label),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Label_UC = unicode:characters_to_binary([Label,0]),
MOpts = fun({pos, {PosX,PosY}}, Acc) -> [<<1:32/?UI,PosX:32/?UI,PosY:32/?UI,0:32>>|Acc];
@@ -116,7 +116,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
This::wxStaticText(), Parent::wxWindow:wxWindow(), Id::integer(), Label::unicode:chardata().
create(This,Parent,Id,Label)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Label) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Label) ->
create(This,Parent,Id,Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxstatictext.html#wxstatictextcreate">external documentation</a>.
@@ -126,7 +126,7 @@ create(This,Parent,Id,Label)
| {'size', {W::integer(), H::integer()}}
| {'style', integer()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
- when is_integer(Id),is_list(Label),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Label),is_list(Options) ->
?CLASS(ThisT,wxStaticText),
?CLASS(ParentT,wxWindow),
Label_UC = unicode:characters_to_binary([Label,0]),
@@ -150,7 +150,7 @@ getLabel(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setLabel(This, Label) -> 'ok' when
This::wxStaticText(), Label::unicode:chardata().
setLabel(#wx_ref{type=ThisT,ref=ThisRef},Label)
- when is_list(Label) ->
+ when ?is_chardata(Label) ->
?CLASS(ThisT,wxStaticText),
Label_UC = unicode:characters_to_binary([Label,0]),
wxe_util:cast(?wxStaticText_SetLabel,
@@ -174,6 +174,8 @@ destroy(Obj=#wx_ref{type=Type}) ->
%% From wxControl
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -490,6 +492,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxStatusBar.erl b/lib/wx/src/gen/wxStatusBar.erl
index d0ce65273b..8d9f77c209 100644
--- a/lib/wx/src/gen/wxStatusBar.erl
+++ b/lib/wx/src/gen/wxStatusBar.erl
@@ -40,29 +40,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -198,7 +198,7 @@ popStatusText(#wx_ref{type=ThisT,ref=ThisRef}, Options)
This::wxStatusBar(), Text::unicode:chardata().
pushStatusText(This,Text)
- when is_record(This, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),?is_chardata(Text) ->
pushStatusText(This,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxstatusbar.html#wxstatusbarpushstatustext">external documentation</a>.
@@ -206,7 +206,7 @@ pushStatusText(This,Text)
This::wxStatusBar(), Text::unicode:chardata(),
Option :: {'number', integer()}.
pushStatusText(#wx_ref{type=ThisT,ref=ThisRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+ when ?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxStatusBar),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({number, Number}, Acc) -> [<<1:32/?UI,Number:32/?UI>>|Acc];
@@ -251,7 +251,7 @@ setMinHeight(#wx_ref{type=ThisT,ref=ThisRef},Height)
This::wxStatusBar(), Text::unicode:chardata().
setStatusText(This,Text)
- when is_record(This, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),?is_chardata(Text) ->
setStatusText(This,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxstatusbar.html#wxstatusbarsetstatustext">external documentation</a>.
@@ -259,7 +259,7 @@ setStatusText(This,Text)
This::wxStatusBar(), Text::unicode:chardata(),
Option :: {'number', integer()}.
setStatusText(#wx_ref{type=ThisT,ref=ThisRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+ when ?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxStatusBar),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({number, Number}, Acc) -> [<<1:32/?UI,Number:32/?UI>>|Acc];
@@ -296,6 +296,8 @@ destroy(Obj=#wx_ref{type=Type}) ->
ok.
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -616,6 +618,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxStyledTextCtrl.erl b/lib/wx/src/gen/wxStyledTextCtrl.erl
index 15ef728659..7e45245a72 100644
--- a/lib/wx/src/gen/wxStyledTextCtrl.erl
+++ b/lib/wx/src/gen/wxStyledTextCtrl.erl
@@ -140,28 +140,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,
- move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
- parent_class/1,popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,
- popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,
- releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,screenToClient/2,
- scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
- setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,
- setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lower/1,makeModal/1,makeModal/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
+ moveBeforeInTabOrder/2,navigate/1,navigate/2,parent_class/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -245,7 +246,7 @@ create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Opti
-spec addText(This, Text) -> 'ok' when
This::wxStyledTextCtrl(), Text::unicode:chardata().
addText(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxStyledTextCtrl_AddText,
@@ -264,7 +265,7 @@ addStyledText(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=DataT,ref=DataRef}) -
-spec insertText(This, Pos, Text) -> 'ok' when
This::wxStyledTextCtrl(), Pos::integer(), Text::unicode:chardata().
insertText(#wx_ref{type=ThisT,ref=ThisRef},Pos,Text)
- when is_integer(Pos),is_list(Text) ->
+ when is_integer(Pos),?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxStyledTextCtrl_InsertText,
@@ -822,7 +823,7 @@ styleSetSize(#wx_ref{type=ThisT,ref=ThisRef},Style,SizePoints)
-spec styleSetFaceName(This, Style, FontName) -> 'ok' when
This::wxStyledTextCtrl(), Style::integer(), FontName::unicode:chardata().
styleSetFaceName(#wx_ref{type=ThisT,ref=ThisRef},Style,FontName)
- when is_integer(Style),is_list(FontName) ->
+ when is_integer(Style),?is_chardata(FontName) ->
?CLASS(ThisT,wxStyledTextCtrl),
FontName_UC = unicode:characters_to_binary([FontName,0]),
wxe_util:cast(?wxStyledTextCtrl_StyleSetFaceName,
@@ -981,7 +982,7 @@ setCaretPeriod(#wx_ref{type=ThisT,ref=ThisRef},PeriodMilliseconds)
-spec setWordChars(This, Characters) -> 'ok' when
This::wxStyledTextCtrl(), Characters::unicode:chardata().
setWordChars(#wx_ref{type=ThisT,ref=ThisRef},Characters)
- when is_list(Characters) ->
+ when ?is_chardata(Characters) ->
?CLASS(ThisT,wxStyledTextCtrl),
Characters_UC = unicode:characters_to_binary([Characters,0]),
wxe_util:cast(?wxStyledTextCtrl_SetWordChars,
@@ -1129,7 +1130,7 @@ setCaretLineBackground(#wx_ref{type=ThisT,ref=ThisRef},Back)
-spec autoCompShow(This, LenEntered, ItemList) -> 'ok' when
This::wxStyledTextCtrl(), LenEntered::integer(), ItemList::unicode:chardata().
autoCompShow(#wx_ref{type=ThisT,ref=ThisRef},LenEntered,ItemList)
- when is_integer(LenEntered),is_list(ItemList) ->
+ when is_integer(LenEntered),?is_chardata(ItemList) ->
?CLASS(ThisT,wxStyledTextCtrl),
ItemList_UC = unicode:characters_to_binary([ItemList,0]),
wxe_util:cast(?wxStyledTextCtrl_AutoCompShow,
@@ -1171,7 +1172,7 @@ autoCompComplete(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec autoCompStops(This, CharacterSet) -> 'ok' when
This::wxStyledTextCtrl(), CharacterSet::unicode:chardata().
autoCompStops(#wx_ref{type=ThisT,ref=ThisRef},CharacterSet)
- when is_list(CharacterSet) ->
+ when ?is_chardata(CharacterSet) ->
?CLASS(ThisT,wxStyledTextCtrl),
CharacterSet_UC = unicode:characters_to_binary([CharacterSet,0]),
wxe_util:cast(?wxStyledTextCtrl_AutoCompStops,
@@ -1198,7 +1199,7 @@ autoCompGetSeparator(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec autoCompSelect(This, Text) -> 'ok' when
This::wxStyledTextCtrl(), Text::unicode:chardata().
autoCompSelect(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxStyledTextCtrl_AutoCompSelect,
@@ -1225,7 +1226,7 @@ autoCompGetCancelAtStart(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec autoCompSetFillUps(This, CharacterSet) -> 'ok' when
This::wxStyledTextCtrl(), CharacterSet::unicode:chardata().
autoCompSetFillUps(#wx_ref{type=ThisT,ref=ThisRef},CharacterSet)
- when is_list(CharacterSet) ->
+ when ?is_chardata(CharacterSet) ->
?CLASS(ThisT,wxStyledTextCtrl),
CharacterSet_UC = unicode:characters_to_binary([CharacterSet,0]),
wxe_util:cast(?wxStyledTextCtrl_AutoCompSetFillUps,
@@ -1269,7 +1270,7 @@ autoCompGetIgnoreCase(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec userListShow(This, ListType, ItemList) -> 'ok' when
This::wxStyledTextCtrl(), ListType::integer(), ItemList::unicode:chardata().
userListShow(#wx_ref{type=ThisT,ref=ThisRef},ListType,ItemList)
- when is_integer(ListType),is_list(ItemList) ->
+ when is_integer(ListType),?is_chardata(ItemList) ->
?CLASS(ThisT,wxStyledTextCtrl),
ItemList_UC = unicode:characters_to_binary([ItemList,0]),
wxe_util:cast(?wxStyledTextCtrl_UserListShow,
@@ -1614,7 +1615,7 @@ getPrintColourMode(#wx_ref{type=ThisT,ref=ThisRef}) ->
This::wxStyledTextCtrl(), MinPos::integer(), MaxPos::integer(), Text::unicode:chardata().
findText(This,MinPos,MaxPos,Text)
- when is_record(This, wx_ref),is_integer(MinPos),is_integer(MaxPos),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(MinPos),is_integer(MaxPos),?is_chardata(Text) ->
findText(This,MinPos,MaxPos,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxstyledtextctrl.html#wxstyledtextctrlfindtext">external documentation</a>.
@@ -1622,7 +1623,7 @@ findText(This,MinPos,MaxPos,Text)
This::wxStyledTextCtrl(), MinPos::integer(), MaxPos::integer(), Text::unicode:chardata(),
Option :: {'flags', integer()}.
findText(#wx_ref{type=ThisT,ref=ThisRef},MinPos,MaxPos,Text, Options)
- when is_integer(MinPos),is_integer(MaxPos),is_list(Text),is_list(Options) ->
+ when is_integer(MinPos),is_integer(MaxPos),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
MOpts = fun({flags, Flags}, Acc) -> [<<1:32/?UI,Flags:32/?UI>>|Acc];
@@ -1783,7 +1784,7 @@ ensureCaretVisible(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec replaceSelection(This, Text) -> 'ok' when
This::wxStyledTextCtrl(), Text::unicode:chardata().
replaceSelection(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxStyledTextCtrl_ReplaceSelection,
@@ -1866,7 +1867,7 @@ clear(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setText(This, Text) -> 'ok' when
This::wxStyledTextCtrl(), Text::unicode:chardata().
setText(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxStyledTextCtrl_SetText,
@@ -1951,7 +1952,7 @@ getTargetEnd(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec replaceTarget(This, Text) -> integer() when
This::wxStyledTextCtrl(), Text::unicode:chardata().
replaceTarget(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:call(?wxStyledTextCtrl_ReplaceTarget,
@@ -1961,7 +1962,7 @@ replaceTarget(#wx_ref{type=ThisT,ref=ThisRef},Text)
-spec searchInTarget(This, Text) -> integer() when
This::wxStyledTextCtrl(), Text::unicode:chardata().
searchInTarget(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:call(?wxStyledTextCtrl_SearchInTarget,
@@ -1988,7 +1989,7 @@ getSearchFlags(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec callTipShow(This, Pos, Definition) -> 'ok' when
This::wxStyledTextCtrl(), Pos::integer(), Definition::unicode:chardata().
callTipShow(#wx_ref{type=ThisT,ref=ThisRef},Pos,Definition)
- when is_integer(Pos),is_list(Definition) ->
+ when is_integer(Pos),?is_chardata(Definition) ->
?CLASS(ThisT,wxStyledTextCtrl),
Definition_UC = unicode:characters_to_binary([Definition,0]),
wxe_util:cast(?wxStyledTextCtrl_CallTipShow,
@@ -2382,7 +2383,7 @@ getScrollWidth(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec textWidth(This, Style, Text) -> integer() when
This::wxStyledTextCtrl(), Style::integer(), Text::unicode:chardata().
textWidth(#wx_ref{type=ThisT,ref=ThisRef},Style,Text)
- when is_integer(Style),is_list(Text) ->
+ when is_integer(Style),?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:call(?wxStyledTextCtrl_TextWidth,
@@ -2426,7 +2427,7 @@ getUseVerticalScrollBar(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec appendText(This, Text) -> 'ok' when
This::wxStyledTextCtrl(), Text::unicode:chardata().
appendText(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxStyledTextCtrl_AppendText,
@@ -3073,7 +3074,7 @@ searchAnchor(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec searchNext(This, Flags, Text) -> integer() when
This::wxStyledTextCtrl(), Flags::integer(), Text::unicode:chardata().
searchNext(#wx_ref{type=ThisT,ref=ThisRef},Flags,Text)
- when is_integer(Flags),is_list(Text) ->
+ when is_integer(Flags),?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:call(?wxStyledTextCtrl_SearchNext,
@@ -3083,7 +3084,7 @@ searchNext(#wx_ref{type=ThisT,ref=ThisRef},Flags,Text)
-spec searchPrev(This, Flags, Text) -> integer() when
This::wxStyledTextCtrl(), Flags::integer(), Text::unicode:chardata().
searchPrev(#wx_ref{type=ThisT,ref=ThisRef},Flags,Text)
- when is_integer(Flags),is_list(Text) ->
+ when is_integer(Flags),?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:call(?wxStyledTextCtrl_SearchPrev,
@@ -3414,7 +3415,7 @@ copyRange(#wx_ref{type=ThisT,ref=ThisRef},Start,End)
-spec copyText(This, Length, Text) -> 'ok' when
This::wxStyledTextCtrl(), Length::integer(), Text::unicode:chardata().
copyText(#wx_ref{type=ThisT,ref=ThisRef},Length,Text)
- when is_integer(Length),is_list(Text) ->
+ when is_integer(Length),?is_chardata(Text) ->
?CLASS(ThisT,wxStyledTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxStyledTextCtrl_CopyText,
@@ -3577,7 +3578,7 @@ wordRightEndExtend(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setWhitespaceChars(This, Characters) -> 'ok' when
This::wxStyledTextCtrl(), Characters::unicode:chardata().
setWhitespaceChars(#wx_ref{type=ThisT,ref=ThisRef},Characters)
- when is_list(Characters) ->
+ when ?is_chardata(Characters) ->
?CLASS(ThisT,wxStyledTextCtrl),
Characters_UC = unicode:characters_to_binary([Characters,0]),
wxe_util:cast(?wxStyledTextCtrl_SetWhitespaceChars,
@@ -3730,7 +3731,7 @@ colourise(#wx_ref{type=ThisT,ref=ThisRef},Start,End)
-spec setProperty(This, Key, Value) -> 'ok' when
This::wxStyledTextCtrl(), Key::unicode:chardata(), Value::unicode:chardata().
setProperty(#wx_ref{type=ThisT,ref=ThisRef},Key,Value)
- when is_list(Key),is_list(Value) ->
+ when ?is_chardata(Key),?is_chardata(Value) ->
?CLASS(ThisT,wxStyledTextCtrl),
Key_UC = unicode:characters_to_binary([Key,0]),
Value_UC = unicode:characters_to_binary([Value,0]),
@@ -3741,7 +3742,7 @@ setProperty(#wx_ref{type=ThisT,ref=ThisRef},Key,Value)
-spec setKeyWords(This, KeywordSet, KeyWords) -> 'ok' when
This::wxStyledTextCtrl(), KeywordSet::integer(), KeyWords::unicode:chardata().
setKeyWords(#wx_ref{type=ThisT,ref=ThisRef},KeywordSet,KeyWords)
- when is_integer(KeywordSet),is_list(KeyWords) ->
+ when is_integer(KeywordSet),?is_chardata(KeyWords) ->
?CLASS(ThisT,wxStyledTextCtrl),
KeyWords_UC = unicode:characters_to_binary([KeyWords,0]),
wxe_util:cast(?wxStyledTextCtrl_SetKeyWords,
@@ -3751,7 +3752,7 @@ setKeyWords(#wx_ref{type=ThisT,ref=ThisRef},KeywordSet,KeyWords)
-spec setLexerLanguage(This, Language) -> 'ok' when
This::wxStyledTextCtrl(), Language::unicode:chardata().
setLexerLanguage(#wx_ref{type=ThisT,ref=ThisRef},Language)
- when is_list(Language) ->
+ when ?is_chardata(Language) ->
?CLASS(ThisT,wxStyledTextCtrl),
Language_UC = unicode:characters_to_binary([Language,0]),
wxe_util:cast(?wxStyledTextCtrl_SetLexerLanguage,
@@ -3761,7 +3762,7 @@ setLexerLanguage(#wx_ref{type=ThisT,ref=ThisRef},Language)
-spec getProperty(This, Key) -> unicode:charlist() when
This::wxStyledTextCtrl(), Key::unicode:chardata().
getProperty(#wx_ref{type=ThisT,ref=ThisRef},Key)
- when is_list(Key) ->
+ when ?is_chardata(Key) ->
?CLASS(ThisT,wxStyledTextCtrl),
Key_UC = unicode:characters_to_binary([Key,0]),
wxe_util:call(?wxStyledTextCtrl_GetProperty,
@@ -3787,7 +3788,7 @@ getCurrentLine(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec styleSetSpec(This, StyleNum, Spec) -> 'ok' when
This::wxStyledTextCtrl(), StyleNum::integer(), Spec::unicode:chardata().
styleSetSpec(#wx_ref{type=ThisT,ref=ThisRef},StyleNum,Spec)
- when is_integer(StyleNum),is_list(Spec) ->
+ when is_integer(StyleNum),?is_chardata(Spec) ->
?CLASS(ThisT,wxStyledTextCtrl),
Spec_UC = unicode:characters_to_binary([Spec,0]),
wxe_util:cast(?wxStyledTextCtrl_StyleSetSpec,
@@ -3808,7 +3809,7 @@ styleSetFont(#wx_ref{type=ThisT,ref=ThisRef},StyleNum,#wx_ref{type=FontT,ref=Fon
This::wxStyledTextCtrl(), StyleNum::integer(), Size::integer(), FaceName::unicode:chardata(), Bold::boolean(), Italic::boolean(), Underline::boolean().
styleSetFontAttr(This,StyleNum,Size,FaceName,Bold,Italic,Underline)
- when is_record(This, wx_ref),is_integer(StyleNum),is_integer(Size),is_list(FaceName),is_boolean(Bold),is_boolean(Italic),is_boolean(Underline) ->
+ when is_record(This, wx_ref),is_integer(StyleNum),is_integer(Size),?is_chardata(FaceName),is_boolean(Bold),is_boolean(Italic),is_boolean(Underline) ->
styleSetFontAttr(This,StyleNum,Size,FaceName,Bold,Italic,Underline, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxstyledtextctrl.html#wxstyledtextctrlstylesetfontattr">external documentation</a>.
@@ -3817,7 +3818,7 @@ styleSetFontAttr(This,StyleNum,Size,FaceName,Bold,Italic,Underline)
This::wxStyledTextCtrl(), StyleNum::integer(), Size::integer(), FaceName::unicode:chardata(), Bold::boolean(), Italic::boolean(), Underline::boolean(),
Option :: {'encoding', wx:wx_enum()}.
styleSetFontAttr(#wx_ref{type=ThisT,ref=ThisRef},StyleNum,Size,FaceName,Bold,Italic,Underline, Options)
- when is_integer(StyleNum),is_integer(Size),is_list(FaceName),is_boolean(Bold),is_boolean(Italic),is_boolean(Underline),is_list(Options) ->
+ when is_integer(StyleNum),is_integer(Size),?is_chardata(FaceName),is_boolean(Bold),is_boolean(Italic),is_boolean(Underline),is_list(Options) ->
?CLASS(ThisT,wxStyledTextCtrl),
FaceName_UC = unicode:characters_to_binary([FaceName,0]),
MOpts = fun({encoding, Encoding}, Acc) -> [<<1:32/?UI,Encoding:32/?UI>>|Acc];
@@ -3937,7 +3938,7 @@ setLastKeydownProcessed(#wx_ref{type=ThisT,ref=ThisRef},Val)
-spec saveFile(This, Filename) -> boolean() when
This::wxStyledTextCtrl(), Filename::unicode:chardata().
saveFile(#wx_ref{type=ThisT,ref=ThisRef},Filename)
- when is_list(Filename) ->
+ when ?is_chardata(Filename) ->
?CLASS(ThisT,wxStyledTextCtrl),
Filename_UC = unicode:characters_to_binary([Filename,0]),
wxe_util:call(?wxStyledTextCtrl_SaveFile,
@@ -3947,7 +3948,7 @@ saveFile(#wx_ref{type=ThisT,ref=ThisRef},Filename)
-spec loadFile(This, Filename) -> boolean() when
This::wxStyledTextCtrl(), Filename::unicode:chardata().
loadFile(#wx_ref{type=ThisT,ref=ThisRef},Filename)
- when is_list(Filename) ->
+ when ?is_chardata(Filename) ->
?CLASS(ThisT,wxStyledTextCtrl),
Filename_UC = unicode:characters_to_binary([Filename,0]),
wxe_util:call(?wxStyledTextCtrl_LoadFile,
@@ -3968,7 +3969,7 @@ doDragOver(#wx_ref{type=ThisT,ref=ThisRef},X,Y,Def)
-spec doDropText(This, X, Y, Data) -> boolean() when
This::wxStyledTextCtrl(), X::integer(), Y::integer(), Data::unicode:chardata().
doDropText(#wx_ref{type=ThisT,ref=ThisRef},X,Y,Data)
- when is_integer(X),is_integer(Y),is_list(Data) ->
+ when is_integer(X),is_integer(Y),?is_chardata(Data) ->
?CLASS(ThisT,wxStyledTextCtrl),
Data_UC = unicode:characters_to_binary([Data,0]),
wxe_util:call(?wxStyledTextCtrl_DoDropText,
@@ -4078,6 +4079,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -4386,6 +4389,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxSystemOptions.erl b/lib/wx/src/gen/wxSystemOptions.erl
index 28d77b1e26..c613d66c73 100644
--- a/lib/wx/src/gen/wxSystemOptions.erl
+++ b/lib/wx/src/gen/wxSystemOptions.erl
@@ -39,7 +39,7 @@ parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
-spec getOption(Name) -> unicode:charlist() when
Name::unicode:chardata().
getOption(Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxSystemOptions_GetOption,
<<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8>>).
@@ -48,7 +48,7 @@ getOption(Name)
-spec getOptionInt(Name) -> integer() when
Name::unicode:chardata().
getOptionInt(Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxSystemOptions_GetOptionInt,
<<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8>>).
@@ -57,7 +57,7 @@ getOptionInt(Name)
-spec hasOption(Name) -> boolean() when
Name::unicode:chardata().
hasOption(Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxSystemOptions_HasOption,
<<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8>>).
@@ -66,7 +66,7 @@ hasOption(Name)
-spec isFalse(Name) -> boolean() when
Name::unicode:chardata().
isFalse(Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxSystemOptions_IsFalse,
<<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8>>).
@@ -81,12 +81,12 @@ isFalse(Name)
(Name, Value) -> 'ok' when
Name::unicode:chardata(), Value::unicode:chardata().
setOption(Name,Value)
- when is_list(Name),is_integer(Value) ->
+ when ?is_chardata(Name),is_integer(Value) ->
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:cast(?wxSystemOptions_SetOption_2_0,
<<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8,Value:32/?UI>>);
setOption(Name,Value)
- when is_list(Name),is_list(Value) ->
+ when ?is_chardata(Name),?is_chardata(Value) ->
Name_UC = unicode:characters_to_binary([Name,0]),
Value_UC = unicode:characters_to_binary([Value,0]),
wxe_util:cast(?wxSystemOptions_SetOption_2_1,
diff --git a/lib/wx/src/gen/wxTextCtrl.erl b/lib/wx/src/gen/wxTextCtrl.erl
index 5f03398959..3acc61ce02 100644
--- a/lib/wx/src/gen/wxTextCtrl.erl
+++ b/lib/wx/src/gen/wxTextCtrl.erl
@@ -46,29 +46,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -126,7 +126,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options)
-spec appendText(This, Text) -> 'ok' when
This::wxTextCtrl(), Text::unicode:chardata().
appendText(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxTextCtrl_AppendText,
@@ -238,7 +238,7 @@ discardEdits(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec changeValue(This, Value) -> 'ok' when
This::wxTextCtrl(), Value::unicode:chardata().
changeValue(#wx_ref{type=ThisT,ref=ThisRef},Value)
- when is_list(Value) ->
+ when ?is_chardata(Value) ->
?CLASS(ThisT,wxTextCtrl),
Value_UC = unicode:characters_to_binary([Value,0]),
wxe_util:cast(?wxTextCtrl_ChangeValue,
@@ -383,7 +383,7 @@ isSingleLine(#wx_ref{type=ThisT,ref=ThisRef}) ->
This::wxTextCtrl(), File::unicode:chardata().
loadFile(This,File)
- when is_record(This, wx_ref),is_list(File) ->
+ when is_record(This, wx_ref),?is_chardata(File) ->
loadFile(This,File, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtextctrl.html#wxtextctrlloadfile">external documentation</a>.
@@ -391,7 +391,7 @@ loadFile(This,File)
This::wxTextCtrl(), File::unicode:chardata(),
Option :: {'fileType', integer()}.
loadFile(#wx_ref{type=ThisT,ref=ThisRef},File, Options)
- when is_list(File),is_list(Options) ->
+ when ?is_chardata(File),is_list(Options) ->
?CLASS(ThisT,wxTextCtrl),
File_UC = unicode:characters_to_binary([File,0]),
MOpts = fun({fileType, FileType}, Acc) -> [<<1:32/?UI,FileType:32/?UI>>|Acc];
@@ -447,7 +447,7 @@ remove(#wx_ref{type=ThisT,ref=ThisRef},From,To)
-spec replace(This, From, To, Value) -> 'ok' when
This::wxTextCtrl(), From::integer(), To::integer(), Value::unicode:chardata().
replace(#wx_ref{type=ThisT,ref=ThisRef},From,To,Value)
- when is_integer(From),is_integer(To),is_list(Value) ->
+ when is_integer(From),is_integer(To),?is_chardata(Value) ->
?CLASS(ThisT,wxTextCtrl),
Value_UC = unicode:characters_to_binary([Value,0]),
wxe_util:cast(?wxTextCtrl_Replace,
@@ -543,7 +543,7 @@ setStyle(#wx_ref{type=ThisT,ref=ThisRef},Start,End,#wx_ref{type=StyleT,ref=Style
-spec setValue(This, Value) -> 'ok' when
This::wxTextCtrl(), Value::unicode:chardata().
setValue(#wx_ref{type=ThisT,ref=ThisRef},Value)
- when is_list(Value) ->
+ when ?is_chardata(Value) ->
?CLASS(ThisT,wxTextCtrl),
Value_UC = unicode:characters_to_binary([Value,0]),
wxe_util:cast(?wxTextCtrl_SetValue,
@@ -570,7 +570,7 @@ undo(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec writeText(This, Text) -> 'ok' when
This::wxTextCtrl(), Text::unicode:chardata().
writeText(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxTextCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxTextCtrl_WriteText,
@@ -598,6 +598,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -914,6 +916,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxTextDataObject.erl b/lib/wx/src/gen/wxTextDataObject.erl
index eb3e1f4bff..5c8a44a879 100644
--- a/lib/wx/src/gen/wxTextDataObject.erl
+++ b/lib/wx/src/gen/wxTextDataObject.erl
@@ -76,7 +76,7 @@ getText(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setText(This, Text) -> 'ok' when
This::wxTextDataObject(), Text::unicode:chardata().
setText(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxTextDataObject),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxTextDataObject_SetText,
diff --git a/lib/wx/src/gen/wxTextEntryDialog.erl b/lib/wx/src/gen/wxTextEntryDialog.erl
index eaf6dc3926..c43a2d12b8 100644
--- a/lib/wx/src/gen/wxTextEntryDialog.erl
+++ b/lib/wx/src/gen/wxTextEntryDialog.erl
@@ -40,40 +40,40 @@
centreOnScreen/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
createButtonSizer/2,createStdDialogButtonSizer/2,destroyChildren/1,
- disable/1,disconnect/1,disconnect/2,disconnect/3,enable/1,enable/2,
- endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,getLabel/1,getMaxSize/1,
- getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getReturnCode/1,
- getScreenPosition/1,getScreenRect/1,getScrollPos/2,getScrollRange/2,
- getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,
- getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,iconize/1,iconize/2,inheritAttributes/1,initDialog/1,invalidateBestSize/1,
- isActive/1,isDoubleBuffered/1,isEnabled/1,isExposed/2,isExposed/3,
- isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,isModal/1,isRetained/1,
- isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,
- makeModal/2,maximize/1,maximize/2,move/2,move/3,move/4,moveAfterInTabOrder/2,
- moveBeforeInTabOrder/2,navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,
- popEventHandler/1,popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,
- raise/1,refresh/1,refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,
- removeChild/2,reparent/2,requestUserAttention/1,requestUserAttention/2,
- screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,
- scrollWindow/4,setAcceleratorTable/2,setAffirmativeId/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,setId/2,setLabel/2,
- setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,
- setOwnForegroundColour/2,setPalette/2,setReturnCode/2,setScrollPos/3,
- setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,setSize/2,
- setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,setSizeHints/4,
- setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,setThemeEnabled/2,
- setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,setVirtualSize/3,
- setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
+ disable/1,disconnect/1,disconnect/2,disconnect/3,dragAcceptFiles/2,
+ enable/1,enable/2,endModal/2,findWindow/2,fit/1,fitInside/1,freeze/1,
+ getAcceleratorTable/1,getAffirmativeId/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getIcon/1,getIcons/1,getId/1,
+ getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,getPosition/1,
+ getRect/1,getReturnCode/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getTitle/1,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,
+ getWindowStyleFlag/1,getWindowVariant/1,hasCapture/1,hasScrollbar/2,
+ hasTransparentBackground/1,hide/1,iconize/1,iconize/2,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isActive/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isFullScreen/1,isIconized/1,isMaximized/1,
+ isModal/1,isRetained/1,isShown/1,isTopLevel/1,layout/1,lineDown/1,lineUp/1,
+ lower/1,makeModal/1,makeModal/2,maximize/1,maximize/2,move/2,move/3,
+ move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,navigate/2,
+ pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,requestUserAttention/1,
+ requestUserAttention/2,screenToClient/1,screenToClient/2,scrollLines/2,
+ scrollPages/2,scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,
+ setAffirmativeId/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setIcon/2,setIcons/2,
+ setId/2,setLabel/2,setMaxSize/2,setMinSize/2,setName/2,setOwnBackgroundColour/2,
+ setOwnFont/2,setOwnForegroundColour/2,setPalette/2,setReturnCode/2,
+ setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,setShape/2,
+ setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
+ setSizeHints/4,setSizer/2,setSizer/3,setSizerAndFit/2,setSizerAndFit/3,
+ setThemeEnabled/2,setTitle/2,setToolTip/2,setTransparent/2,setVirtualSize/2,
+ setVirtualSize/3,setVirtualSizeHints/2,setVirtualSizeHints/3,setVirtualSizeHints/4,
setWindowStyle/2,setWindowStyleFlag/2,setWindowVariant/2,shouldInheritColours/1,
show/1,show/2,showFullScreen/2,showFullScreen/3,showModal/1,thaw/1,
transferDataFromWindow/1,transferDataToWindow/1,update/1,updateWindowUI/1,
@@ -93,7 +93,7 @@ parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
Parent::wxWindow:wxWindow(), Message::unicode:chardata().
new(Parent,Message)
- when is_record(Parent, wx_ref),is_list(Message) ->
+ when is_record(Parent, wx_ref),?is_chardata(Message) ->
new(Parent,Message, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtextentrydialog.html#wxtextentrydialogwxtextentrydialog">external documentation</a>.
@@ -104,7 +104,7 @@ new(Parent,Message)
| {'style', integer()}
| {'pos', {X::integer(), Y::integer()}}.
new(#wx_ref{type=ParentT,ref=ParentRef},Message, Options)
- when is_list(Message),is_list(Options) ->
+ when ?is_chardata(Message),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Message_UC = unicode:characters_to_binary([Message,0]),
MOpts = fun({caption, Caption}, Acc) -> Caption_UC = unicode:characters_to_binary([Caption,0]),[<<1:32/?UI,(byte_size(Caption_UC)):32/?UI,(Caption_UC)/binary, 0:(((8- ((0+byte_size(Caption_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -128,7 +128,7 @@ getValue(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setValue(This, Val) -> 'ok' when
This::wxTextEntryDialog(), Val::unicode:chardata().
setValue(#wx_ref{type=ThisT,ref=ThisRef},Val)
- when is_list(Val) ->
+ when ?is_chardata(Val) ->
?CLASS(ThisT,wxTextEntryDialog),
Val_UC = unicode:characters_to_binary([Val,0]),
wxe_util:cast(?wxTextEntryDialog_SetValue,
@@ -212,6 +212,8 @@ getIcons(This) -> wxTopLevelWindow:getIcons(This).
getIcon(This) -> wxTopLevelWindow:getIcon(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -528,6 +530,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxToggleButton.erl b/lib/wx/src/gen/wxToggleButton.erl
index 9e8dab1c32..b82ff4fe68 100644
--- a/lib/wx/src/gen/wxToggleButton.erl
+++ b/lib/wx/src/gen/wxToggleButton.erl
@@ -38,29 +38,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -90,7 +90,7 @@ new() ->
Parent::wxWindow:wxWindow(), Id::integer(), Label::unicode:chardata().
new(Parent,Id,Label)
- when is_record(Parent, wx_ref),is_integer(Id),is_list(Label) ->
+ when is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Label) ->
new(Parent,Id,Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtogglebutton.html#wxtogglebuttonwxtogglebutton">external documentation</a>.
@@ -101,7 +101,7 @@ new(Parent,Id,Label)
| {'style', integer()}
| {'validator', wx:wx_object()}.
new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
- when is_integer(Id),is_list(Label),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Label),is_list(Options) ->
?CLASS(ParentT,wxWindow),
Label_UC = unicode:characters_to_binary([Label,0]),
MOpts = fun({pos, {PosX,PosY}}, Acc) -> [<<1:32/?UI,PosX:32/?UI,PosY:32/?UI,0:32>>|Acc];
@@ -118,7 +118,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
This::wxToggleButton(), Parent::wxWindow:wxWindow(), Id::integer(), Label::unicode:chardata().
create(This,Parent,Id,Label)
- when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Label) ->
+ when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),?is_chardata(Label) ->
create(This,Parent,Id,Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtogglebutton.html#wxtogglebuttoncreate">external documentation</a>.
@@ -129,7 +129,7 @@ create(This,Parent,Id,Label)
| {'style', integer()}
| {'validator', wx:wx_object()}.
create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options)
- when is_integer(Id),is_list(Label),is_list(Options) ->
+ when is_integer(Id),?is_chardata(Label),is_list(Options) ->
?CLASS(ThisT,wxToggleButton),
?CLASS(ParentT,wxWindow),
Label_UC = unicode:characters_to_binary([Label,0]),
@@ -172,6 +172,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -488,6 +490,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxToolBar.erl b/lib/wx/src/gen/wxToolBar.erl
index 9be37f943c..e2835bf7c4 100644
--- a/lib/wx/src/gen/wxToolBar.erl
+++ b/lib/wx/src/gen/wxToolBar.erl
@@ -47,29 +47,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -142,7 +142,7 @@ addTool(This,Toolid,Bitmap)
| {'longHelpString', unicode:chardata()}.
addTool(This,Toolid,Label,Bitmap)
- when is_record(This, wx_ref),is_integer(Toolid),is_list(Label),is_record(Bitmap, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Toolid),?is_chardata(Label),is_record(Bitmap, wx_ref) ->
addTool(This,Toolid,Label,Bitmap, []);
addTool(This,Toolid,Bitmap,BmpDisabled)
@@ -187,10 +187,10 @@ addTool(#wx_ref{type=ThisT,ref=ThisRef},Toolid,#wx_ref{type=BitmapT,ref=BitmapRe
| {'longHelpString', unicode:chardata()}.
addTool(This,Toolid,Label,Bitmap,BmpDisabled)
- when is_record(This, wx_ref),is_integer(Toolid),is_list(Label),is_record(Bitmap, wx_ref),is_record(BmpDisabled, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Toolid),?is_chardata(Label),is_record(Bitmap, wx_ref),is_record(BmpDisabled, wx_ref) ->
addTool(This,Toolid,Label,Bitmap,BmpDisabled, []);
addTool(#wx_ref{type=ThisT,ref=ThisRef},Toolid,Label,#wx_ref{type=BitmapT,ref=BitmapRef}, Options)
- when is_integer(Toolid),is_list(Label),is_list(Options) ->
+ when is_integer(Toolid),?is_chardata(Label),is_list(Options) ->
?CLASS(ThisT,wxToolBar),
Label_UC = unicode:characters_to_binary([Label,0]),
?CLASS(BitmapT,wxBitmap),
@@ -237,7 +237,7 @@ addTool(This,Toolid,Bitmap,BmpDisabled,Toggle,XPos)
when is_record(This, wx_ref),is_integer(Toolid),is_record(Bitmap, wx_ref),is_record(BmpDisabled, wx_ref),is_boolean(Toggle),is_integer(XPos) ->
addTool(This,Toolid,Bitmap,BmpDisabled,Toggle,XPos, []);
addTool(#wx_ref{type=ThisT,ref=ThisRef},Toolid,Label,#wx_ref{type=BitmapT,ref=BitmapRef},#wx_ref{type=BmpDisabledT,ref=BmpDisabledRef}, Options)
- when is_integer(Toolid),is_list(Label),is_list(Options) ->
+ when is_integer(Toolid),?is_chardata(Label),is_list(Options) ->
?CLASS(ThisT,wxToolBar),
Label_UC = unicode:characters_to_binary([Label,0]),
?CLASS(BitmapT,wxBitmap),
@@ -277,7 +277,7 @@ addTool(#wx_ref{type=ThisT,ref=ThisRef},Toolid,#wx_ref{type=BitmapT,ref=BitmapRe
This::wxToolBar(), Toolid::integer(), Label::unicode:chardata(), Bitmap::wxBitmap:wxBitmap().
addCheckTool(This,Toolid,Label,Bitmap)
- when is_record(This, wx_ref),is_integer(Toolid),is_list(Label),is_record(Bitmap, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Toolid),?is_chardata(Label),is_record(Bitmap, wx_ref) ->
addCheckTool(This,Toolid,Label,Bitmap, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtoolbar.html#wxtoolbaraddchecktool">external documentation</a>.
@@ -288,7 +288,7 @@ addCheckTool(This,Toolid,Label,Bitmap)
| {'longHelp', unicode:chardata()}
| {'data', wx:wx_object()}.
addCheckTool(#wx_ref{type=ThisT,ref=ThisRef},Toolid,Label,#wx_ref{type=BitmapT,ref=BitmapRef}, Options)
- when is_integer(Toolid),is_list(Label),is_list(Options) ->
+ when is_integer(Toolid),?is_chardata(Label),is_list(Options) ->
?CLASS(ThisT,wxToolBar),
Label_UC = unicode:characters_to_binary([Label,0]),
?CLASS(BitmapT,wxBitmap),
@@ -306,7 +306,7 @@ addCheckTool(#wx_ref{type=ThisT,ref=ThisRef},Toolid,Label,#wx_ref{type=BitmapT,r
This::wxToolBar(), Toolid::integer(), Label::unicode:chardata(), Bitmap::wxBitmap:wxBitmap().
addRadioTool(This,Toolid,Label,Bitmap)
- when is_record(This, wx_ref),is_integer(Toolid),is_list(Label),is_record(Bitmap, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Toolid),?is_chardata(Label),is_record(Bitmap, wx_ref) ->
addRadioTool(This,Toolid,Label,Bitmap, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtoolbar.html#wxtoolbaraddradiotool">external documentation</a>.
@@ -317,7 +317,7 @@ addRadioTool(This,Toolid,Label,Bitmap)
| {'longHelp', unicode:chardata()}
| {'data', wx:wx_object()}.
addRadioTool(#wx_ref{type=ThisT,ref=ThisRef},Toolid,Label,#wx_ref{type=BitmapT,ref=BitmapRef}, Options)
- when is_integer(Toolid),is_list(Label),is_list(Options) ->
+ when is_integer(Toolid),?is_chardata(Label),is_list(Options) ->
?CLASS(ThisT,wxToolBar),
Label_UC = unicode:characters_to_binary([Label,0]),
?CLASS(BitmapT,wxBitmap),
@@ -545,7 +545,7 @@ insertTool(This,Pos,Toolid,Bitmap)
| {'longHelp', unicode:chardata()}.
insertTool(This,Pos,Toolid,Label,Bitmap)
- when is_record(This, wx_ref),is_integer(Pos),is_integer(Toolid),is_list(Label),is_record(Bitmap, wx_ref) ->
+ when is_record(This, wx_ref),is_integer(Pos),is_integer(Toolid),?is_chardata(Label),is_record(Bitmap, wx_ref) ->
insertTool(This,Pos,Toolid,Label,Bitmap, []);
insertTool(#wx_ref{type=ThisT,ref=ThisRef},Pos,Toolid,#wx_ref{type=BitmapT,ref=BitmapRef}, Options)
when is_integer(Pos),is_integer(Toolid),is_list(Options) ->
@@ -571,7 +571,7 @@ insertTool(#wx_ref{type=ThisT,ref=ThisRef},Pos,Toolid,#wx_ref{type=BitmapT,ref=B
| {'longHelp', unicode:chardata()}
| {'clientData', wx:wx_object()}.
insertTool(#wx_ref{type=ThisT,ref=ThisRef},Pos,Toolid,Label,#wx_ref{type=BitmapT,ref=BitmapRef}, Options)
- when is_integer(Pos),is_integer(Toolid),is_list(Label),is_list(Options) ->
+ when is_integer(Pos),is_integer(Toolid),?is_chardata(Label),is_list(Options) ->
?CLASS(ThisT,wxToolBar),
Label_UC = unicode:characters_to_binary([Label,0]),
?CLASS(BitmapT,wxBitmap),
@@ -624,7 +624,7 @@ setToolBitmapSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH})
-spec setToolLongHelp(This, Toolid, HelpString) -> 'ok' when
This::wxToolBar(), Toolid::integer(), HelpString::unicode:chardata().
setToolLongHelp(#wx_ref{type=ThisT,ref=ThisRef},Toolid,HelpString)
- when is_integer(Toolid),is_list(HelpString) ->
+ when is_integer(Toolid),?is_chardata(HelpString) ->
?CLASS(ThisT,wxToolBar),
HelpString_UC = unicode:characters_to_binary([HelpString,0]),
wxe_util:cast(?wxToolBar_SetToolLongHelp,
@@ -643,7 +643,7 @@ setToolPacking(#wx_ref{type=ThisT,ref=ThisRef},Packing)
-spec setToolShortHelp(This, Id, HelpString) -> 'ok' when
This::wxToolBar(), Id::integer(), HelpString::unicode:chardata().
setToolShortHelp(#wx_ref{type=ThisT,ref=ThisRef},Id,HelpString)
- when is_integer(Id),is_list(HelpString) ->
+ when is_integer(Id),?is_chardata(HelpString) ->
?CLASS(ThisT,wxToolBar),
HelpString_UC = unicode:characters_to_binary([HelpString,0]),
wxe_util:cast(?wxToolBar_SetToolShortHelp,
@@ -674,6 +674,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -990,6 +992,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxToolTip.erl b/lib/wx/src/gen/wxToolTip.erl
index 163e764d8c..0596173ebe 100644
--- a/lib/wx/src/gen/wxToolTip.erl
+++ b/lib/wx/src/gen/wxToolTip.erl
@@ -55,7 +55,7 @@ setDelay(Msecs)
-spec new(Tip) -> wxToolTip() when
Tip::unicode:chardata().
new(Tip)
- when is_list(Tip) ->
+ when ?is_chardata(Tip) ->
Tip_UC = unicode:characters_to_binary([Tip,0]),
wxe_util:construct(?wxToolTip_new,
<<(byte_size(Tip_UC)):32/?UI,(Tip_UC)/binary, 0:(((8- ((4+byte_size(Tip_UC)) band 16#7)) band 16#7))/unit:8>>).
@@ -64,7 +64,7 @@ new(Tip)
-spec setTip(This, Tip) -> 'ok' when
This::wxToolTip(), Tip::unicode:chardata().
setTip(#wx_ref{type=ThisT,ref=ThisRef},Tip)
- when is_list(Tip) ->
+ when ?is_chardata(Tip) ->
?CLASS(ThisT,wxToolTip),
Tip_UC = unicode:characters_to_binary([Tip,0]),
wxe_util:cast(?wxToolTip_SetTip,
diff --git a/lib/wx/src/gen/wxToolbook.erl b/lib/wx/src/gen/wxToolbook.erl
index 92dcbc726b..c22719680c 100644
--- a/lib/wx/src/gen/wxToolbook.erl
+++ b/lib/wx/src/gen/wxToolbook.erl
@@ -43,29 +43,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -120,7 +120,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options)
This::wxToolbook(), Page::wxWindow:wxWindow(), Text::unicode:chardata().
addPage(This,Page,Text)
- when is_record(This, wx_ref),is_record(Page, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_record(Page, wx_ref),?is_chardata(Text) ->
addPage(This,Page,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtoolbook.html#wxtoolbookaddpage">external documentation</a>.
@@ -129,7 +129,7 @@ addPage(This,Page,Text)
Option :: {'bSelect', boolean()}
| {'imageId', integer()}.
addPage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PageT,ref=PageRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+ when ?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxToolbook),
?CLASS(PageT,wxWindow),
Text_UC = unicode:characters_to_binary([Text,0]),
@@ -296,7 +296,7 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY})
This::wxToolbook(), N::integer(), Page::wxWindow:wxWindow(), Text::unicode:chardata().
insertPage(This,N,Page,Text)
- when is_record(This, wx_ref),is_integer(N),is_record(Page, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(N),is_record(Page, wx_ref),?is_chardata(Text) ->
insertPage(This,N,Page,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtoolbook.html#wxtoolbookinsertpage">external documentation</a>.
@@ -305,7 +305,7 @@ insertPage(This,N,Page,Text)
Option :: {'bSelect', boolean()}
| {'imageId', integer()}.
insertPage(#wx_ref{type=ThisT,ref=ThisRef},N,#wx_ref{type=PageT,ref=PageRef},Text, Options)
- when is_integer(N),is_list(Text),is_list(Options) ->
+ when is_integer(N),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxToolbook),
?CLASS(PageT,wxWindow),
Text_UC = unicode:characters_to_binary([Text,0]),
@@ -347,7 +347,7 @@ setPageImage(#wx_ref{type=ThisT,ref=ThisRef},N,ImageId)
-spec setPageText(This, N, StrText) -> boolean() when
This::wxToolbook(), N::integer(), StrText::unicode:chardata().
setPageText(#wx_ref{type=ThisT,ref=ThisRef},N,StrText)
- when is_integer(N),is_list(StrText) ->
+ when is_integer(N),?is_chardata(StrText) ->
?CLASS(ThisT,wxToolbook),
StrText_UC = unicode:characters_to_binary([StrText,0]),
wxe_util:call(?wxToolbook_SetPageText,
@@ -384,6 +384,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -700,6 +702,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxTopLevelWindow.erl b/lib/wx/src/gen/wxTopLevelWindow.erl
index 6ba81691c7..64713099f6 100644
--- a/lib/wx/src/gen/wxTopLevelWindow.erl
+++ b/lib/wx/src/gen/wxTopLevelWindow.erl
@@ -41,29 +41,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -273,7 +273,7 @@ setShape(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=RegionT,ref=RegionRef}) ->
-spec setTitle(This, Title) -> 'ok' when
This::wxTopLevelWindow(), Title::unicode:chardata().
setTitle(#wx_ref{type=ThisT,ref=ThisRef},Title)
- when is_list(Title) ->
+ when ?is_chardata(Title) ->
?CLASS(ThisT,wxTopLevelWindow),
Title_UC = unicode:characters_to_binary([Title,0]),
wxe_util:cast(?wxTopLevelWindow_SetTitle,
@@ -302,6 +302,8 @@ showFullScreen(#wx_ref{type=ThisT,ref=ThisRef},Show, Options)
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -622,6 +624,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxTreeCtrl.erl b/lib/wx/src/gen/wxTreeCtrl.erl
index 97b43309ad..373cb4c77f 100644
--- a/lib/wx/src/gen/wxTreeCtrl.erl
+++ b/lib/wx/src/gen/wxTreeCtrl.erl
@@ -59,29 +59,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -140,7 +140,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef}, Options)
This::wxTreeCtrl(), Text::unicode:chardata().
addRoot(This,Text)
- when is_record(This, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),?is_chardata(Text) ->
addRoot(This,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtreectrl.html#wxtreectrladdroot">external documentation</a>.
@@ -150,7 +150,7 @@ addRoot(This,Text)
| {'selectedImage', integer()}
| {'data', term()}.
addRoot(#wx_ref{type=ThisT,ref=ThisRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+ when ?is_chardata(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];
@@ -166,7 +166,7 @@ addRoot(#wx_ref{type=ThisT,ref=ThisRef},Text, Options)
This::wxTreeCtrl(), Parent::integer(), Text::unicode:chardata().
appendItem(This,Parent,Text)
- when is_record(This, wx_ref),is_integer(Parent),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Parent),?is_chardata(Text) ->
appendItem(This,Parent,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtreectrl.html#wxtreectrlappenditem">external documentation</a>.
@@ -176,7 +176,7 @@ appendItem(This,Parent,Text)
| {'selectedImage', integer()}
| {'data', term()}.
appendItem(#wx_ref{type=ThisT,ref=ThisRef},Parent,Text, Options)
- when is_integer(Parent),is_list(Text),is_list(Options) ->
+ when is_integer(Parent),?is_chardata(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];
@@ -580,7 +580,7 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY})
This::wxTreeCtrl(), Parent::integer(), Pos::integer(), Text::unicode:chardata().
insertItem(This,Parent,Pos,Text)
- when is_record(This, wx_ref),is_integer(Parent),is_integer(Pos),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Parent),is_integer(Pos),?is_chardata(Text) ->
insertItem(This,Parent,Pos,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtreectrl.html#wxtreectrlinsertitem">external documentation</a>.
@@ -590,7 +590,7 @@ insertItem(This,Parent,Pos,Text)
| {'selImage', integer()}
| {'data', term()}.
insertItem(#wx_ref{type=ThisT,ref=ThisRef},Parent,Pos,Text, Options)
- when is_integer(Parent),is_integer(Pos),is_list(Text),is_list(Options) ->
+ when is_integer(Parent),is_integer(Pos),?is_chardata(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];
@@ -659,7 +659,7 @@ isTreeItemIdOk(Id)
This::wxTreeCtrl(), Parent::integer(), Text::unicode:chardata().
prependItem(This,Parent,Text)
- when is_record(This, wx_ref),is_integer(Parent),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Parent),?is_chardata(Text) ->
prependItem(This,Parent,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtreectrl.html#wxtreectrlprependitem">external documentation</a>.
@@ -669,7 +669,7 @@ prependItem(This,Parent,Text)
| {'selectedImage', integer()}
| {'data', term()}.
prependItem(#wx_ref{type=ThisT,ref=ThisRef},Parent,Text, Options)
- when is_integer(Parent),is_list(Text),is_list(Options) ->
+ when is_integer(Parent),?is_chardata(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];
@@ -848,7 +848,7 @@ setItemImage(#wx_ref{type=ThisT,ref=ThisRef},Item,Image, Options)
-spec setItemText(This, Item, Text) -> 'ok' when
This::wxTreeCtrl(), Item::integer(), Text::unicode:chardata().
setItemText(#wx_ref{type=ThisT,ref=ThisRef},Item,Text)
- when is_integer(Item),is_list(Text) ->
+ when is_integer(Item),?is_chardata(Text) ->
?CLASS(ThisT,wxTreeCtrl),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxTreeCtrl_SetItemText,
@@ -946,6 +946,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -1260,6 +1262,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxTreeEvent.erl b/lib/wx/src/gen/wxTreeEvent.erl
index 41e86fe41f..368f32a386 100644
--- a/lib/wx/src/gen/wxTreeEvent.erl
+++ b/lib/wx/src/gen/wxTreeEvent.erl
@@ -111,7 +111,7 @@ isEditCancelled(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec setToolTip(This, ToolTip) -> 'ok' when
This::wxTreeEvent(), ToolTip::unicode:chardata().
setToolTip(#wx_ref{type=ThisT,ref=ThisRef},ToolTip)
- when is_list(ToolTip) ->
+ when ?is_chardata(ToolTip) ->
?CLASS(ThisT,wxTreeEvent),
ToolTip_UC = unicode:characters_to_binary([ToolTip,0]),
wxe_util:cast(?wxTreeEvent_SetToolTip,
diff --git a/lib/wx/src/gen/wxTreebook.erl b/lib/wx/src/gen/wxTreebook.erl
index 5d3c177f7e..dc95730224 100644
--- a/lib/wx/src/gen/wxTreebook.erl
+++ b/lib/wx/src/gen/wxTreebook.erl
@@ -44,29 +44,29 @@
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,connect/2,connect/3,convertDialogToPixels/2,convertPixelsToDialog/2,
destroyChildren/1,disable/1,disconnect/1,disconnect/2,disconnect/3,
- enable/1,enable/2,findWindow/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCaret/1,
- getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,getContainingSizer/1,
- getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
- getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
- getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
- getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
- getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
- getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
- getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
- hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
- isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
- isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
- move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
- navigate/1,navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,
- popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
- refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
- reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
- scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
- setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
- setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
- setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
- setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ dragAcceptFiles/2,enable/1,enable/2,findWindow/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,
+ getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,getCursor/1,
+ getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,getForegroundColour/1,
+ getGrandParent/1,getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,
+ getMinSize/1,getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
+ getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
+ getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
+ getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
+ hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
+ initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
+ isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
+ layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
+ move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
+ navigate/2,pageDown/1,pageUp/1,parent_class/1,popEventHandler/1,popEventHandler/2,
+ popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
+ refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
+ screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
+ setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
+ setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
+ setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
+ setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -121,7 +121,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options)
This::wxTreebook(), Page::wxWindow:wxWindow(), Text::unicode:chardata().
addPage(This,Page,Text)
- when is_record(This, wx_ref),is_record(Page, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_record(Page, wx_ref),?is_chardata(Text) ->
addPage(This,Page,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtreebook.html#wxtreebookaddpage">external documentation</a>.
@@ -130,7 +130,7 @@ addPage(This,Page,Text)
Option :: {'bSelect', boolean()}
| {'imageId', integer()}.
addPage(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PageT,ref=PageRef},Text, Options)
- when is_list(Text),is_list(Options) ->
+ when ?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxTreebook),
?CLASS(PageT,wxWindow),
Text_UC = unicode:characters_to_binary([Text,0]),
@@ -327,7 +327,7 @@ hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY})
This::wxTreebook(), Pos::integer(), Page::wxWindow:wxWindow(), Text::unicode:chardata().
insertPage(This,Pos,Page,Text)
- when is_record(This, wx_ref),is_integer(Pos),is_record(Page, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Pos),is_record(Page, wx_ref),?is_chardata(Text) ->
insertPage(This,Pos,Page,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtreebook.html#wxtreebookinsertpage">external documentation</a>.
@@ -336,7 +336,7 @@ insertPage(This,Pos,Page,Text)
Option :: {'bSelect', boolean()}
| {'imageId', integer()}.
insertPage(#wx_ref{type=ThisT,ref=ThisRef},Pos,#wx_ref{type=PageT,ref=PageRef},Text, Options)
- when is_integer(Pos),is_list(Text),is_list(Options) ->
+ when is_integer(Pos),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxTreebook),
?CLASS(PageT,wxWindow),
Text_UC = unicode:characters_to_binary([Text,0]),
@@ -352,7 +352,7 @@ insertPage(#wx_ref{type=ThisT,ref=ThisRef},Pos,#wx_ref{type=PageT,ref=PageRef},T
This::wxTreebook(), Pos::integer(), Page::wxWindow:wxWindow(), Text::unicode:chardata().
insertSubPage(This,Pos,Page,Text)
- when is_record(This, wx_ref),is_integer(Pos),is_record(Page, wx_ref),is_list(Text) ->
+ when is_record(This, wx_ref),is_integer(Pos),is_record(Page, wx_ref),?is_chardata(Text) ->
insertSubPage(This,Pos,Page,Text, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxtreebook.html#wxtreebookinsertsubpage">external documentation</a>.
@@ -361,7 +361,7 @@ insertSubPage(This,Pos,Page,Text)
Option :: {'bSelect', boolean()}
| {'imageId', integer()}.
insertSubPage(#wx_ref{type=ThisT,ref=ThisRef},Pos,#wx_ref{type=PageT,ref=PageRef},Text, Options)
- when is_integer(Pos),is_list(Text),is_list(Options) ->
+ when is_integer(Pos),?is_chardata(Text),is_list(Options) ->
?CLASS(ThisT,wxTreebook),
?CLASS(PageT,wxWindow),
Text_UC = unicode:characters_to_binary([Text,0]),
@@ -403,7 +403,7 @@ setPageImage(#wx_ref{type=ThisT,ref=ThisRef},N,ImageId)
-spec setPageText(This, N, StrText) -> boolean() when
This::wxTreebook(), N::integer(), StrText::unicode:chardata().
setPageText(#wx_ref{type=ThisT,ref=ThisRef},N,StrText)
- when is_integer(N),is_list(StrText) ->
+ when is_integer(N),?is_chardata(StrText) ->
?CLASS(ThisT,wxTreebook),
StrText_UC = unicode:characters_to_binary([StrText,0]),
wxe_util:call(?wxTreebook_SetPageText,
@@ -440,6 +440,8 @@ setLabel(This,Label) -> wxControl:setLabel(This,Label).
getLabel(This) -> wxControl:getLabel(This).
%% From wxWindow
%% @hidden
+getContentScaleFactor(This) -> wxWindow:getContentScaleFactor(This).
+%% @hidden
setDoubleBuffered(This,On) -> wxWindow:setDoubleBuffered(This,On).
%% @hidden
isDoubleBuffered(This) -> wxWindow:isDoubleBuffered(This).
@@ -756,6 +758,8 @@ enable(This, Options) -> wxWindow:enable(This, Options).
%% @hidden
enable(This) -> wxWindow:enable(This).
%% @hidden
+dragAcceptFiles(This,Accept) -> wxWindow:dragAcceptFiles(This,Accept).
+%% @hidden
disable(This) -> wxWindow:disable(This).
%% @hidden
destroyChildren(This) -> wxWindow:destroyChildren(This).
diff --git a/lib/wx/src/gen/wxUpdateUIEvent.erl b/lib/wx/src/gen/wxUpdateUIEvent.erl
index fec42ed8eb..e7bda40a7a 100644
--- a/lib/wx/src/gen/wxUpdateUIEvent.erl
+++ b/lib/wx/src/gen/wxUpdateUIEvent.erl
@@ -181,7 +181,7 @@ setMode(Mode)
-spec setText(This, Text) -> 'ok' when
This::wxUpdateUIEvent(), Text::unicode:chardata().
setText(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxUpdateUIEvent),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxUpdateUIEvent_SetText,
diff --git a/lib/wx/src/gen/wxWindow.erl b/lib/wx/src/gen/wxWindow.erl
index 4ac7cc5d75..9ace4533c8 100644
--- a/lib/wx/src/gen/wxWindow.erl
+++ b/lib/wx/src/gen/wxWindow.erl
@@ -32,31 +32,32 @@
center/2,centerOnParent/1,centerOnParent/2,centre/1,centre/2,centreOnParent/1,
centreOnParent/2,clearBackground/1,clientToScreen/2,clientToScreen/3,
close/1,close/2,convertDialogToPixels/2,convertPixelsToDialog/2,destroy/1,
- destroyChildren/1,disable/1,enable/1,enable/2,findFocus/0,findWindow/2,
- findWindowById/1,findWindowById/2,findWindowByLabel/1,findWindowByLabel/2,
- findWindowByName/1,findWindowByName/2,fit/1,fitInside/1,freeze/1,getAcceleratorTable/1,
- getBackgroundColour/1,getBackgroundStyle/1,getBestSize/1,getCapture/0,
- getCaret/1,getCharHeight/1,getCharWidth/1,getChildren/1,getClientSize/1,
- getContainingSizer/1,getCursor/1,getDropTarget/1,getEventHandler/1,
- getExtraStyle/1,getFont/1,getForegroundColour/1,getGrandParent/1,
- getHandle/1,getHelpText/1,getId/1,getLabel/1,getMaxSize/1,getMinSize/1,
- getName/1,getParent/1,getPosition/1,getRect/1,getScreenPosition/1,
- getScreenRect/1,getScrollPos/2,getScrollRange/2,getScrollThumb/2,
- getSize/1,getSizer/1,getTextExtent/2,getTextExtent/3,getToolTip/1,
- getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,getWindowVariant/1,
- hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,hide/1,inheritAttributes/1,
- initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,isEnabled/1,
- isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,isTopLevel/1,
- layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,move/2,
- move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,navigate/1,
- navigate/2,new/0,new/2,new/3,pageDown/1,pageUp/1,popEventHandler/1,popEventHandler/2,
- popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,refresh/2,refreshRect/2,
- refreshRect/3,releaseMouse/1,removeChild/2,reparent/2,screenToClient/1,
- screenToClient/2,scrollLines/2,scrollPages/2,scrollWindow/3,scrollWindow/4,
- setAcceleratorTable/2,setAutoLayout/2,setBackgroundColour/2,setBackgroundStyle/2,
- setCaret/2,setClientSize/2,setClientSize/3,setContainingSizer/2,setCursor/2,
- setDoubleBuffered/2,setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,
- setFont/2,setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
+ destroyChildren/1,disable/1,dragAcceptFiles/2,enable/1,enable/2,findFocus/0,
+ findWindow/2,findWindowById/1,findWindowById/2,findWindowByLabel/1,
+ findWindowByLabel/2,findWindowByName/1,findWindowByName/2,fit/1,fitInside/1,
+ freeze/1,getAcceleratorTable/1,getBackgroundColour/1,getBackgroundStyle/1,
+ getBestSize/1,getCapture/0,getCaret/1,getCharHeight/1,getCharWidth/1,
+ getChildren/1,getClientSize/1,getContainingSizer/1,getContentScaleFactor/1,
+ getCursor/1,getDropTarget/1,getEventHandler/1,getExtraStyle/1,getFont/1,
+ getForegroundColour/1,getGrandParent/1,getHandle/1,getHelpText/1,
+ getId/1,getLabel/1,getMaxSize/1,getMinSize/1,getName/1,getParent/1,
+ getPosition/1,getRect/1,getScreenPosition/1,getScreenRect/1,getScrollPos/2,
+ getScrollRange/2,getScrollThumb/2,getSize/1,getSizer/1,getTextExtent/2,
+ getTextExtent/3,getToolTip/1,getUpdateRegion/1,getVirtualSize/1,getWindowStyleFlag/1,
+ getWindowVariant/1,hasCapture/1,hasScrollbar/2,hasTransparentBackground/1,
+ hide/1,inheritAttributes/1,initDialog/1,invalidateBestSize/1,isDoubleBuffered/1,
+ isEnabled/1,isExposed/2,isExposed/3,isExposed/5,isRetained/1,isShown/1,
+ isTopLevel/1,layout/1,lineDown/1,lineUp/1,lower/1,makeModal/1,makeModal/2,
+ move/2,move/3,move/4,moveAfterInTabOrder/2,moveBeforeInTabOrder/2,
+ navigate/1,navigate/2,new/0,new/2,new/3,pageDown/1,pageUp/1,popEventHandler/1,
+ popEventHandler/2,popupMenu/2,popupMenu/3,popupMenu/4,raise/1,refresh/1,
+ refresh/2,refreshRect/2,refreshRect/3,releaseMouse/1,removeChild/2,
+ reparent/2,screenToClient/1,screenToClient/2,scrollLines/2,scrollPages/2,
+ scrollWindow/3,scrollWindow/4,setAcceleratorTable/2,setAutoLayout/2,
+ setBackgroundColour/2,setBackgroundStyle/2,setCaret/2,setClientSize/2,
+ setClientSize/3,setContainingSizer/2,setCursor/2,setDoubleBuffered/2,
+ setDropTarget/2,setExtraStyle/2,setFocus/1,setFocusFromKbd/1,setFont/2,
+ setForegroundColour/2,setHelpText/2,setId/2,setLabel/2,setMaxSize/2,
setMinSize/2,setName/2,setOwnBackgroundColour/2,setOwnFont/2,setOwnForegroundColour/2,
setPalette/2,setScrollPos/3,setScrollPos/4,setScrollbar/5,setScrollbar/6,
setSize/2,setSize/3,setSize/5,setSize/6,setSizeHints/2,setSizeHints/3,
@@ -297,6 +298,15 @@ disable(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxWindow_Disable,
<<ThisRef:32/?UI>>).
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxwindow.html#wxwindowdragacceptfiles">external documentation</a>.
+-spec dragAcceptFiles(This, Accept) -> 'ok' when
+ This::wxWindow(), Accept::boolean().
+dragAcceptFiles(#wx_ref{type=ThisT,ref=ThisRef},Accept)
+ when is_boolean(Accept) ->
+ ?CLASS(ThisT,wxWindow),
+ wxe_util:cast(?wxWindow_DragAcceptFiles,
+ <<ThisRef:32/?UI,(wxe_util:from_bool(Accept)):32/?UI>>).
+
%% @equiv enable(This, [])
-spec enable(This) -> boolean() when
This::wxWindow().
@@ -339,7 +349,7 @@ findWindow(#wx_ref{type=ThisT,ref=ThisRef},Winid)
wxe_util:call(?wxWindow_FindWindow_1_0,
<<ThisRef:32/?UI,Winid:32/?UI>>);
findWindow(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxWindow),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxWindow_FindWindow_1_1,
@@ -370,7 +380,7 @@ findWindowById(Winid, Options)
Name::unicode:chardata().
findWindowByName(Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
findWindowByName(Name, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxwindow.html#wxwindowfindwindowbyname">external documentation</a>.
@@ -378,7 +388,7 @@ findWindowByName(Name)
Name::unicode:chardata(),
Option :: {'parent', wxWindow()}.
findWindowByName(Name, Options)
- when is_list(Name),is_list(Options) ->
+ when ?is_chardata(Name),is_list(Options) ->
Name_UC = unicode:characters_to_binary([Name,0]),
MOpts = fun({parent, #wx_ref{type=ParentT,ref=ParentRef}}, Acc) -> ?CLASS(ParentT,wxWindow),[<<1:32/?UI,ParentRef:32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
@@ -391,7 +401,7 @@ findWindowByName(Name, Options)
Label::unicode:chardata().
findWindowByLabel(Label)
- when is_list(Label) ->
+ when ?is_chardata(Label) ->
findWindowByLabel(Label, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxwindow.html#wxwindowfindwindowbylabel">external documentation</a>.
@@ -399,7 +409,7 @@ findWindowByLabel(Label)
Label::unicode:chardata(),
Option :: {'parent', wxWindow()}.
findWindowByLabel(Label, Options)
- when is_list(Label),is_list(Options) ->
+ when ?is_chardata(Label),is_list(Options) ->
Label_UC = unicode:characters_to_binary([Label,0]),
MOpts = fun({parent, #wx_ref{type=ParentT,ref=ParentRef}}, Acc) -> ?CLASS(ParentT,wxWindow),[<<1:32/?UI,ParentRef:32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
@@ -719,7 +729,7 @@ getSizer(#wx_ref{type=ThisT,ref=ThisRef}) ->
This::wxWindow(), String::unicode:chardata().
getTextExtent(This,String)
- when is_record(This, wx_ref),is_list(String) ->
+ when is_record(This, wx_ref),?is_chardata(String) ->
getTextExtent(This,String, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxwindow.html#wxwindowgettextextent">external documentation</a>.
@@ -728,7 +738,7 @@ getTextExtent(This,String)
This::wxWindow(), String::unicode:chardata(),
Option :: {'theFont', wxFont:wxFont()}.
getTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String, Options)
- when is_list(String),is_list(Options) ->
+ when ?is_chardata(String),is_list(Options) ->
?CLASS(ThisT,wxWindow),
String_UC = unicode:characters_to_binary([String,0]),
MOpts = fun({theFont, #wx_ref{type=TheFontT,ref=TheFontRef}}, Acc) -> ?CLASS(TheFontT,wxFont),[<<1:32/?UI,TheFontRef:32/?UI>>|Acc];
@@ -1439,7 +1449,7 @@ setForegroundColour(#wx_ref{type=ThisT,ref=ThisRef},Colour)
-spec setHelpText(This, Text) -> 'ok' when
This::wxWindow(), Text::unicode:chardata().
setHelpText(#wx_ref{type=ThisT,ref=ThisRef},Text)
- when is_list(Text) ->
+ when ?is_chardata(Text) ->
?CLASS(ThisT,wxWindow),
Text_UC = unicode:characters_to_binary([Text,0]),
wxe_util:cast(?wxWindow_SetHelpText,
@@ -1458,7 +1468,7 @@ setId(#wx_ref{type=ThisT,ref=ThisRef},Winid)
-spec setLabel(This, Label) -> 'ok' when
This::wxWindow(), Label::unicode:chardata().
setLabel(#wx_ref{type=ThisT,ref=ThisRef},Label)
- when is_list(Label) ->
+ when ?is_chardata(Label) ->
?CLASS(ThisT,wxWindow),
Label_UC = unicode:characters_to_binary([Label,0]),
wxe_util:cast(?wxWindow_SetLabel,
@@ -1468,7 +1478,7 @@ setLabel(#wx_ref{type=ThisT,ref=ThisRef},Label)
-spec setName(This, Name) -> 'ok' when
This::wxWindow(), Name::unicode:chardata().
setName(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxWindow),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:cast(?wxWindow_SetName,
@@ -1707,7 +1717,7 @@ setThemeEnabled(#wx_ref{type=ThisT,ref=ThisRef},EnableTheme)
(This, Tip) -> 'ok' when
This::wxWindow(), Tip::wxToolTip:wxToolTip().
setToolTip(#wx_ref{type=ThisT,ref=ThisRef},Tip)
- when is_list(Tip) ->
+ when ?is_chardata(Tip) ->
?CLASS(ThisT,wxWindow),
Tip_UC = unicode:characters_to_binary([Tip,0]),
wxe_util:cast(?wxWindow_SetToolTip_1_0,
@@ -1944,6 +1954,14 @@ setDoubleBuffered(#wx_ref{type=ThisT,ref=ThisRef},On)
wxe_util:cast(?wxWindow_SetDoubleBuffered,
<<ThisRef:32/?UI,(wxe_util:from_bool(On)):32/?UI>>).
+%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxwindow.html#wxwindowgetcontentscalefactor">external documentation</a>.
+-spec getContentScaleFactor(This) -> number() when
+ This::wxWindow().
+getContentScaleFactor(#wx_ref{type=ThisT,ref=ThisRef}) ->
+ ?CLASS(ThisT,wxWindow),
+ wxe_util:call(?wxWindow_GetContentScaleFactor,
+ <<ThisRef:32/?UI>>).
+
%% @doc Destroys this object, do not use object again
-spec destroy(This::wxWindow()) -> 'ok'.
destroy(Obj=#wx_ref{type=Type}) ->
diff --git a/lib/wx/src/gen/wxXmlResource.erl b/lib/wx/src/gen/wxXmlResource.erl
index ae02c74751..51f6231f48 100644
--- a/lib/wx/src/gen/wxXmlResource.erl
+++ b/lib/wx/src/gen/wxXmlResource.erl
@@ -65,7 +65,7 @@ new(Options)
Option :: {'flags', integer()}
| {'domain', unicode:chardata()}.
new(Filemask, Options)
- when is_list(Filemask),is_list(Options) ->
+ when ?is_chardata(Filemask),is_list(Options) ->
Filemask_UC = unicode:characters_to_binary([Filemask,0]),
MOpts = fun({flags, Flags}, Acc) -> [<<1:32/?UI,Flags:32/?UI>>|Acc];
({domain, Domain}, Acc) -> Domain_UC = unicode:characters_to_binary([Domain,0]),[<<2:32/?UI,(byte_size(Domain_UC)):32/?UI,(Domain_UC)/binary, 0:(((8- ((0+byte_size(Domain_UC)) band 16#7)) band 16#7))/unit:8>>|Acc];
@@ -79,7 +79,7 @@ new(Filemask, Options)
This::wxXmlResource(), Name::unicode:chardata(), Control::wxWindow:wxWindow().
attachUnknownControl(This,Name,Control)
- when is_record(This, wx_ref),is_list(Name),is_record(Control, wx_ref) ->
+ when is_record(This, wx_ref),?is_chardata(Name),is_record(Control, wx_ref) ->
attachUnknownControl(This,Name,Control, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_wxxmlresource.html#wxxmlresourceattachunknowncontrol">external documentation</a>.
@@ -87,7 +87,7 @@ attachUnknownControl(This,Name,Control)
This::wxXmlResource(), Name::unicode:chardata(), Control::wxWindow:wxWindow(),
Option :: {'parent', wxWindow:wxWindow()}.
attachUnknownControl(#wx_ref{type=ThisT,ref=ThisRef},Name,#wx_ref{type=ControlT,ref=ControlRef}, Options)
- when is_list(Name),is_list(Options) ->
+ when ?is_chardata(Name),is_list(Options) ->
?CLASS(ThisT,wxXmlResource),
Name_UC = unicode:characters_to_binary([Name,0]),
?CLASS(ControlT,wxWindow),
@@ -169,7 +169,7 @@ initAllHandlers(#wx_ref{type=ThisT,ref=ThisRef}) ->
-spec load(This, Filemask) -> boolean() when
This::wxXmlResource(), Filemask::unicode:chardata().
load(#wx_ref{type=ThisT,ref=ThisRef},Filemask)
- when is_list(Filemask) ->
+ when ?is_chardata(Filemask) ->
?CLASS(ThisT,wxXmlResource),
Filemask_UC = unicode:characters_to_binary([Filemask,0]),
wxe_util:call(?wxXmlResource_Load,
@@ -179,7 +179,7 @@ load(#wx_ref{type=ThisT,ref=ThisRef},Filemask)
-spec loadBitmap(This, Name) -> wxBitmap:wxBitmap() when
This::wxXmlResource(), Name::unicode:chardata().
loadBitmap(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxXmlResource_LoadBitmap,
@@ -189,7 +189,7 @@ loadBitmap(#wx_ref{type=ThisT,ref=ThisRef},Name)
-spec loadDialog(This, Parent, Name) -> wxDialog:wxDialog() when
This::wxXmlResource(), Parent::wxWindow:wxWindow(), Name::unicode:chardata().
loadDialog(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
?CLASS(ParentT,wxWindow),
Name_UC = unicode:characters_to_binary([Name,0]),
@@ -200,7 +200,7 @@ loadDialog(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},N
-spec loadDialog(This, Dlg, Parent, Name) -> boolean() when
This::wxXmlResource(), Dlg::wxDialog:wxDialog(), Parent::wxWindow:wxWindow(), Name::unicode:chardata().
loadDialog(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=DlgT,ref=DlgRef},#wx_ref{type=ParentT,ref=ParentRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
?CLASS(DlgT,wxDialog),
?CLASS(ParentT,wxWindow),
@@ -212,7 +212,7 @@ loadDialog(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=DlgT,ref=DlgRef},#wx_ref
-spec loadFrame(This, Parent, Name) -> wxFrame:wxFrame() when
This::wxXmlResource(), Parent::wxWindow:wxWindow(), Name::unicode:chardata().
loadFrame(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
?CLASS(ParentT,wxWindow),
Name_UC = unicode:characters_to_binary([Name,0]),
@@ -223,7 +223,7 @@ loadFrame(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Na
-spec loadFrame(This, Frame, Parent, Name) -> boolean() when
This::wxXmlResource(), Frame::wxFrame:wxFrame(), Parent::wxWindow:wxWindow(), Name::unicode:chardata().
loadFrame(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=FrameT,ref=FrameRef},#wx_ref{type=ParentT,ref=ParentRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
?CLASS(FrameT,wxFrame),
?CLASS(ParentT,wxWindow),
@@ -235,7 +235,7 @@ loadFrame(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=FrameT,ref=FrameRef},#wx_
-spec loadIcon(This, Name) -> wxIcon:wxIcon() when
This::wxXmlResource(), Name::unicode:chardata().
loadIcon(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxXmlResource_LoadIcon,
@@ -245,7 +245,7 @@ loadIcon(#wx_ref{type=ThisT,ref=ThisRef},Name)
-spec loadMenu(This, Name) -> wxMenu:wxMenu() when
This::wxXmlResource(), Name::unicode:chardata().
loadMenu(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxXmlResource_LoadMenu,
@@ -255,7 +255,7 @@ loadMenu(#wx_ref{type=ThisT,ref=ThisRef},Name)
-spec loadMenuBar(This, Name) -> wxMenuBar:wxMenuBar() when
This::wxXmlResource(), Name::unicode:chardata().
loadMenuBar(#wx_ref{type=ThisT,ref=ThisRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
Name_UC = unicode:characters_to_binary([Name,0]),
wxe_util:call(?wxXmlResource_LoadMenuBar_1,
@@ -265,7 +265,7 @@ loadMenuBar(#wx_ref{type=ThisT,ref=ThisRef},Name)
-spec loadMenuBar(This, Parent, Name) -> wxMenuBar:wxMenuBar() when
This::wxXmlResource(), Parent::wxWindow:wxWindow(), Name::unicode:chardata().
loadMenuBar(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
?CLASS(ParentT,wxWindow),
Name_UC = unicode:characters_to_binary([Name,0]),
@@ -276,7 +276,7 @@ loadMenuBar(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},
-spec loadPanel(This, Parent, Name) -> wxPanel:wxPanel() when
This::wxXmlResource(), Parent::wxWindow:wxWindow(), Name::unicode:chardata().
loadPanel(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
?CLASS(ParentT,wxWindow),
Name_UC = unicode:characters_to_binary([Name,0]),
@@ -287,7 +287,7 @@ loadPanel(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Na
-spec loadPanel(This, Panel, Parent, Name) -> boolean() when
This::wxXmlResource(), Panel::wxPanel:wxPanel(), Parent::wxWindow:wxWindow(), Name::unicode:chardata().
loadPanel(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PanelT,ref=PanelRef},#wx_ref{type=ParentT,ref=ParentRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
?CLASS(PanelT,wxPanel),
?CLASS(ParentT,wxWindow),
@@ -299,7 +299,7 @@ loadPanel(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PanelT,ref=PanelRef},#wx_
-spec loadToolBar(This, Parent, Name) -> wxToolBar:wxToolBar() when
This::wxXmlResource(), Parent::wxWindow:wxWindow(), Name::unicode:chardata().
loadToolBar(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Name)
- when is_list(Name) ->
+ when ?is_chardata(Name) ->
?CLASS(ThisT,wxXmlResource),
?CLASS(ParentT,wxWindow),
Name_UC = unicode:characters_to_binary([Name,0]),
@@ -327,15 +327,13 @@ setFlags(#wx_ref{type=ThisT,ref=ThisRef},Flags)
-spec unload(This, Filename) -> boolean() when
This::wxXmlResource(), Filename::unicode:chardata().
unload(#wx_ref{type=ThisT,ref=ThisRef},Filename)
- when is_list(Filename) ->
+ when ?is_chardata(Filename) ->
?CLASS(ThisT,wxXmlResource),
Filename_UC = unicode:characters_to_binary([Filename,0]),
wxe_util:call(?wxXmlResource_Unload,
<<ThisRef:32/?UI,(byte_size(Filename_UC)):32/?UI,(Filename_UC)/binary, 0:(((8- ((0+byte_size(Filename_UC)) band 16#7)) band 16#7))/unit:8>>).
-%% @spec (Window::wxWindow:wxWindow(),Name::string(), Type::atom()) -> wx:wxObject()
-
%% @doc Looks up a control with Name in a window created with XML
%% resources. You can use it to set/get values from controls.
%% The object is type casted to <b>Type</b>.
@@ -345,6 +343,10 @@ unload(#wx_ref{type=ThisT,ref=ThisRef},Filename)
%% true = wxXmlResource:loadDialog(Xrc, Dlg, Frame, "controls_dialog"), <br />
%% LCtrl = xrcctrl(Dlg, "controls_listctrl", wxListCtrl), <br />
%% wxListCtrl:insertColumn(LCtrl, 0, "Name", [{width, 200}]), <br />
+-spec xrcctrl(Window, Name, Type) -> wx:wx_object() when
+ Window::wxWindow:wxWindow(),
+ Name::string(),
+ Type::atom().
xrcctrl(Window = #wx_ref{}, Name, Type) when is_list(Name), is_atom(Type) ->
%% Func Id ?wxXmlResource_xrcctrl
diff --git a/lib/wx/src/gen/wx_misc.erl b/lib/wx/src/gen/wx_misc.erl
index ce5d917136..66b1756a2f 100644
--- a/lib/wx/src/gen/wx_misc.erl
+++ b/lib/wx/src/gen/wx_misc.erl
@@ -72,7 +72,7 @@ bell() ->
-spec findMenuItemId(Frame, MenuString, ItemString) -> integer() when
Frame::wxFrame:wxFrame(), MenuString::unicode:chardata(), ItemString::unicode:chardata().
findMenuItemId(#wx_ref{type=FrameT,ref=FrameRef},MenuString,ItemString)
- when is_list(MenuString),is_list(ItemString) ->
+ when ?is_chardata(MenuString),?is_chardata(ItemString) ->
?CLASS(FrameT,wxFrame),
MenuString_UC = unicode:characters_to_binary([MenuString,0]),
ItemString_UC = unicode:characters_to_binary([ItemString,0]),
@@ -155,7 +155,7 @@ shell(Options)
Url::unicode:chardata().
launchDefaultBrowser(Url)
- when is_list(Url) ->
+ when ?is_chardata(Url) ->
launchDefaultBrowser(Url, []).
%% @doc See <a href="http://www.wxwidgets.org/manuals/2.8.12/wx_miscellany.html#wxlaunchdefaultbrowser">external documentation</a>.
@@ -163,7 +163,7 @@ launchDefaultBrowser(Url)
Url::unicode:chardata(),
Option :: {'flags', integer()}.
launchDefaultBrowser(Url, Options)
- when is_list(Url),is_list(Options) ->
+ when ?is_chardata(Url),is_list(Options) ->
Url_UC = unicode:characters_to_binary([Url,0]),
MOpts = fun({flags, Flags}, Acc) -> [<<1:32/?UI,Flags:32/?UI>>|Acc];
(BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
diff --git a/lib/wx/src/gen/wxe_debug.hrl b/lib/wx/src/gen/wxe_debug.hrl
index 78c6577439..58cb5298e6 100644
--- a/lib/wx/src/gen/wxe_debug.hrl
+++ b/lib/wx/src/gen/wxe_debug.hrl
@@ -45,3333 +45,3338 @@ wxdebug_table() ->
{123, {wxWindow, 'Destroy', 0}},
{124, {wxWindow, destroyChildren, 0}},
{125, {wxWindow, disable, 0}},
- {126, {wxWindow, enable, 1}},
- {127, {wxWindow, findFocus, 0}},
- {128, {wxWindow, findWindow_1_0, 1}},
- {129, {wxWindow, findWindow_1_1, 1}},
- {130, {wxWindow, findWindowById, 2}},
- {131, {wxWindow, findWindowByName, 2}},
- {132, {wxWindow, findWindowByLabel, 2}},
- {133, {wxWindow, fit, 0}},
- {134, {wxWindow, fitInside, 0}},
- {135, {wxWindow, freeze, 0}},
- {136, {wxWindow, getAcceleratorTable, 0}},
- {137, {wxWindow, getBackgroundColour, 0}},
- {138, {wxWindow, getBackgroundStyle, 0}},
- {139, {wxWindow, getBestSize, 0}},
- {141, {wxWindow, getCaret, 0}},
- {142, {wxWindow, getCapture, 0}},
- {143, {wxWindow, getCharHeight, 0}},
- {144, {wxWindow, getCharWidth, 0}},
- {145, {wxWindow, getChildren, 0}},
- {148, {wxWindow, getClientSize, 0}},
- {149, {wxWindow, getContainingSizer, 0}},
- {150, {wxWindow, getCursor, 0}},
- {151, {wxWindow, getDropTarget, 0}},
- {152, {wxWindow, getEventHandler, 0}},
- {153, {wxWindow, getExtraStyle, 0}},
- {154, {wxWindow, getFont, 0}},
- {155, {wxWindow, getForegroundColour, 0}},
- {156, {wxWindow, getGrandParent, 0}},
- {157, {wxWindow, getHandle, 0}},
- {158, {wxWindow, getHelpText, 0}},
- {159, {wxWindow, getId, 0}},
- {160, {wxWindow, getLabel, 0}},
- {161, {wxWindow, getMaxSize, 0}},
- {162, {wxWindow, getMinSize, 0}},
- {163, {wxWindow, getName, 0}},
- {164, {wxWindow, getParent, 0}},
- {166, {wxWindow, getPosition, 0}},
- {167, {wxWindow, getRect, 0}},
- {169, {wxWindow, getScreenPosition, 0}},
- {170, {wxWindow, getScreenRect, 0}},
- {171, {wxWindow, getScrollPos, 1}},
- {172, {wxWindow, getScrollRange, 1}},
- {173, {wxWindow, getScrollThumb, 1}},
- {175, {wxWindow, getSize, 0}},
- {176, {wxWindow, getSizer, 0}},
- {177, {wxWindow, getTextExtent, 4}},
- {178, {wxWindow, getToolTip, 0}},
- {179, {wxWindow, getUpdateRegion, 0}},
- {181, {wxWindow, getVirtualSize, 0}},
- {183, {wxWindow, getWindowStyleFlag, 0}},
- {184, {wxWindow, getWindowVariant, 0}},
- {185, {wxWindow, hasCapture, 0}},
- {186, {wxWindow, hasScrollbar, 1}},
- {187, {wxWindow, hasTransparentBackground, 0}},
- {188, {wxWindow, hide, 0}},
- {189, {wxWindow, inheritAttributes, 0}},
- {190, {wxWindow, initDialog, 0}},
- {191, {wxWindow, invalidateBestSize, 0}},
- {192, {wxWindow, isEnabled, 0}},
- {193, {wxWindow, isExposed_2, 2}},
- {194, {wxWindow, isExposed_4, 4}},
- {195, {wxWindow, isExposed_1_0, 1}},
- {196, {wxWindow, isExposed_1_1, 1}},
- {197, {wxWindow, isRetained, 0}},
- {198, {wxWindow, isShown, 0}},
- {199, {wxWindow, isTopLevel, 0}},
- {200, {wxWindow, layout, 0}},
- {201, {wxWindow, lineDown, 0}},
- {202, {wxWindow, lineUp, 0}},
- {203, {wxWindow, lower, 0}},
- {204, {wxWindow, makeModal, 1}},
- {205, {wxWindow, move_3, 3}},
- {206, {wxWindow, move_2, 2}},
- {207, {wxWindow, moveAfterInTabOrder, 1}},
- {208, {wxWindow, moveBeforeInTabOrder, 1}},
- {209, {wxWindow, navigate, 1}},
- {210, {wxWindow, pageDown, 0}},
- {211, {wxWindow, pageUp, 0}},
- {212, {wxWindow, popEventHandler, 1}},
- {213, {wxWindow, popupMenu_2, 2}},
- {214, {wxWindow, popupMenu_3, 3}},
- {215, {wxWindow, raise, 0}},
- {216, {wxWindow, refresh, 1}},
- {217, {wxWindow, refreshRect, 2}},
- {218, {wxWindow, releaseMouse, 0}},
- {219, {wxWindow, removeChild, 1}},
- {220, {wxWindow, reparent, 1}},
- {221, {wxWindow, screenToClient_2, 2}},
- {222, {wxWindow, screenToClient_1, 1}},
- {224, {wxWindow, scrollLines, 1}},
- {226, {wxWindow, scrollPages, 1}},
- {227, {wxWindow, scrollWindow, 3}},
- {228, {wxWindow, setAcceleratorTable, 1}},
- {229, {wxWindow, setAutoLayout, 1}},
- {230, {wxWindow, setBackgroundColour, 1}},
- {231, {wxWindow, setBackgroundStyle, 1}},
- {232, {wxWindow, setCaret, 1}},
- {233, {wxWindow, setClientSize_2, 2}},
- {234, {wxWindow, setClientSize_1_0, 1}},
- {235, {wxWindow, setClientSize_1_1, 1}},
- {236, {wxWindow, setContainingSizer, 1}},
- {237, {wxWindow, setCursor, 1}},
- {238, {wxWindow, setMaxSize, 1}},
- {239, {wxWindow, setMinSize, 1}},
- {240, {wxWindow, setOwnBackgroundColour, 1}},
- {241, {wxWindow, setOwnFont, 1}},
- {242, {wxWindow, setOwnForegroundColour, 1}},
- {243, {wxWindow, setDropTarget, 1}},
- {244, {wxWindow, setExtraStyle, 1}},
- {245, {wxWindow, setFocus, 0}},
- {246, {wxWindow, setFocusFromKbd, 0}},
- {247, {wxWindow, setFont, 1}},
- {248, {wxWindow, setForegroundColour, 1}},
- {249, {wxWindow, setHelpText, 1}},
- {250, {wxWindow, setId, 1}},
- {252, {wxWindow, setLabel, 1}},
- {253, {wxWindow, setName, 1}},
- {254, {wxWindow, setPalette, 1}},
- {255, {wxWindow, setScrollbar, 5}},
- {256, {wxWindow, setScrollPos, 3}},
- {257, {wxWindow, setSize_5, 5}},
- {258, {wxWindow, setSize_2_0, 2}},
- {259, {wxWindow, setSize_1, 1}},
- {260, {wxWindow, setSize_2_1, 2}},
- {261, {wxWindow, setSizeHints_3, 3}},
- {262, {wxWindow, setSizeHints_2, 2}},
- {263, {wxWindow, setSizer, 2}},
- {264, {wxWindow, setSizerAndFit, 2}},
- {265, {wxWindow, setThemeEnabled, 1}},
- {266, {wxWindow, setToolTip_1_0, 1}},
- {267, {wxWindow, setToolTip_1_1, 1}},
- {268, {wxWindow, setVirtualSize_1, 1}},
- {269, {wxWindow, setVirtualSize_2, 2}},
- {270, {wxWindow, setVirtualSizeHints_3, 3}},
- {271, {wxWindow, setVirtualSizeHints_2, 2}},
- {272, {wxWindow, setWindowStyle, 1}},
- {273, {wxWindow, setWindowStyleFlag, 1}},
- {274, {wxWindow, setWindowVariant, 1}},
- {275, {wxWindow, shouldInheritColours, 0}},
- {276, {wxWindow, show, 1}},
- {277, {wxWindow, thaw, 0}},
- {278, {wxWindow, transferDataFromWindow, 0}},
- {279, {wxWindow, transferDataToWindow, 0}},
- {280, {wxWindow, update, 0}},
- {281, {wxWindow, updateWindowUI, 1}},
- {282, {wxWindow, validate, 0}},
- {283, {wxWindow, warpPointer, 2}},
- {284, {wxWindow, setTransparent, 1}},
- {285, {wxWindow, canSetTransparent, 0}},
- {286, {wxWindow, isDoubleBuffered, 0}},
- {287, {wxWindow, setDoubleBuffered, 1}},
- {288, {wxTopLevelWindow, getIcon, 0}},
- {289, {wxTopLevelWindow, getIcons, 0}},
- {290, {wxTopLevelWindow, getTitle, 0}},
- {291, {wxTopLevelWindow, isActive, 0}},
- {292, {wxTopLevelWindow, iconize, 1}},
- {293, {wxTopLevelWindow, isFullScreen, 0}},
- {294, {wxTopLevelWindow, isIconized, 0}},
- {295, {wxTopLevelWindow, isMaximized, 0}},
- {296, {wxTopLevelWindow, maximize, 1}},
- {297, {wxTopLevelWindow, requestUserAttention, 1}},
- {298, {wxTopLevelWindow, setIcon, 1}},
- {299, {wxTopLevelWindow, setIcons, 1}},
- {300, {wxTopLevelWindow, centerOnScreen, 1}},
- {301, {wxTopLevelWindow, centreOnScreen, 1}},
- {303, {wxTopLevelWindow, setShape, 1}},
- {304, {wxTopLevelWindow, setTitle, 1}},
- {305, {wxTopLevelWindow, showFullScreen, 2}},
- {307, {wxFrame, new_4, 4}},
- {308, {wxFrame, new_0, 0}},
- {310, {wxFrame, destruct, 0}},
- {311, {wxFrame, create, 4}},
- {312, {wxFrame, createStatusBar, 1}},
- {313, {wxFrame, createToolBar, 1}},
- {314, {wxFrame, getClientAreaOrigin, 0}},
- {315, {wxFrame, getMenuBar, 0}},
- {316, {wxFrame, getStatusBar, 0}},
- {317, {wxFrame, getStatusBarPane, 0}},
- {318, {wxFrame, getToolBar, 0}},
- {319, {wxFrame, processCommand, 1}},
- {320, {wxFrame, sendSizeEvent, 0}},
- {321, {wxFrame, setMenuBar, 1}},
- {322, {wxFrame, setStatusBar, 1}},
- {323, {wxFrame, setStatusBarPane, 1}},
- {324, {wxFrame, setStatusText, 2}},
- {325, {wxFrame, setStatusWidths, 2}},
- {326, {wxFrame, setToolBar, 1}},
- {327, {wxMiniFrame, new_0, 0}},
- {328, {wxMiniFrame, new_4, 4}},
- {329, {wxMiniFrame, create, 4}},
- {330, {wxMiniFrame, 'Destroy', undefined}},
- {331, {wxSplashScreen, new_0, 0}},
- {332, {wxSplashScreen, new_6, 6}},
- {333, {wxSplashScreen, destruct, 0}},
- {334, {wxSplashScreen, getSplashStyle, 0}},
- {335, {wxSplashScreen, getTimeout, 0}},
- {336, {wxPanel, new_0, 0}},
- {337, {wxPanel, new_6, 6}},
- {338, {wxPanel, new_2, 2}},
- {339, {wxPanel, destruct, 0}},
- {340, {wxPanel, initDialog, 0}},
- {341, {wxPanel, setFocusIgnoringChildren, 0}},
- {342, {wxScrolledWindow, new_0, 0}},
- {343, {wxScrolledWindow, new_2, 2}},
- {344, {wxScrolledWindow, destruct, 0}},
- {345, {wxScrolledWindow, calcScrolledPosition_4, 4}},
- {346, {wxScrolledWindow, calcScrolledPosition_1, 1}},
- {347, {wxScrolledWindow, calcUnscrolledPosition_4, 4}},
- {348, {wxScrolledWindow, calcUnscrolledPosition_1, 1}},
- {349, {wxScrolledWindow, enableScrolling, 2}},
- {350, {wxScrolledWindow, getScrollPixelsPerUnit, 2}},
- {351, {wxScrolledWindow, getViewStart, 2}},
- {352, {wxScrolledWindow, doPrepareDC, 1}},
- {353, {wxScrolledWindow, prepareDC, 1}},
- {354, {wxScrolledWindow, scroll, 2}},
- {355, {wxScrolledWindow, setScrollbars, 5}},
- {356, {wxScrolledWindow, setScrollRate, 2}},
- {357, {wxScrolledWindow, setTargetWindow, 1}},
- {358, {wxSashWindow, new_0, 0}},
- {359, {wxSashWindow, new_2, 2}},
- {360, {wxSashWindow, destruct, 0}},
- {361, {wxSashWindow, getSashVisible, 1}},
- {362, {wxSashWindow, getMaximumSizeX, 0}},
- {363, {wxSashWindow, getMaximumSizeY, 0}},
- {364, {wxSashWindow, getMinimumSizeX, 0}},
- {365, {wxSashWindow, getMinimumSizeY, 0}},
- {366, {wxSashWindow, setMaximumSizeX, 1}},
- {367, {wxSashWindow, setMaximumSizeY, 1}},
- {368, {wxSashWindow, setMinimumSizeX, 1}},
- {369, {wxSashWindow, setMinimumSizeY, 1}},
- {370, {wxSashWindow, setSashVisible, 2}},
- {371, {wxSashLayoutWindow, new_0, 0}},
- {372, {wxSashLayoutWindow, new_2, 2}},
- {373, {wxSashLayoutWindow, create, 2}},
- {374, {wxSashLayoutWindow, getAlignment, 0}},
- {375, {wxSashLayoutWindow, getOrientation, 0}},
- {376, {wxSashLayoutWindow, setAlignment, 1}},
- {377, {wxSashLayoutWindow, setDefaultSize, 1}},
- {378, {wxSashLayoutWindow, setOrientation, 1}},
- {379, {wxSashLayoutWindow, 'Destroy', undefined}},
- {380, {wxGrid, new_0, 0}},
- {381, {wxGrid, new_3, 3}},
- {382, {wxGrid, new_4, 4}},
- {383, {wxGrid, destruct, 0}},
- {384, {wxGrid, appendCols, 1}},
- {385, {wxGrid, appendRows, 1}},
- {386, {wxGrid, autoSize, 0}},
- {387, {wxGrid, autoSizeColumn, 2}},
- {388, {wxGrid, autoSizeColumns, 1}},
- {389, {wxGrid, autoSizeRow, 2}},
- {390, {wxGrid, autoSizeRows, 1}},
- {391, {wxGrid, beginBatch, 0}},
- {392, {wxGrid, blockToDeviceRect, 2}},
- {393, {wxGrid, canDragColSize, 0}},
- {394, {wxGrid, canDragRowSize, 0}},
- {395, {wxGrid, canDragGridSize, 0}},
- {396, {wxGrid, canEnableCellControl, 0}},
- {397, {wxGrid, cellToRect_2, 2}},
- {398, {wxGrid, cellToRect_1, 1}},
- {399, {wxGrid, clearGrid, 0}},
- {400, {wxGrid, clearSelection, 0}},
- {401, {wxGrid, createGrid, 3}},
- {402, {wxGrid, deleteCols, 1}},
- {403, {wxGrid, deleteRows, 1}},
- {404, {wxGrid, disableCellEditControl, 0}},
- {405, {wxGrid, disableDragColSize, 0}},
- {406, {wxGrid, disableDragGridSize, 0}},
- {407, {wxGrid, disableDragRowSize, 0}},
- {408, {wxGrid, enableCellEditControl, 1}},
- {409, {wxGrid, enableDragColSize, 1}},
- {410, {wxGrid, enableDragGridSize, 1}},
- {411, {wxGrid, enableDragRowSize, 1}},
- {412, {wxGrid, enableEditing, 1}},
- {413, {wxGrid, enableGridLines, 1}},
- {414, {wxGrid, endBatch, 0}},
- {415, {wxGrid, fit, 0}},
- {416, {wxGrid, forceRefresh, 0}},
- {417, {wxGrid, getBatchCount, 0}},
- {418, {wxGrid, getCellAlignment, 4}},
- {419, {wxGrid, getCellBackgroundColour, 2}},
- {420, {wxGrid, getCellEditor, 2}},
- {421, {wxGrid, getCellFont, 2}},
- {422, {wxGrid, getCellRenderer, 2}},
- {423, {wxGrid, getCellTextColour, 2}},
- {424, {wxGrid, getCellValue_2, 2}},
- {425, {wxGrid, getCellValue_1, 1}},
- {426, {wxGrid, getColLabelAlignment, 2}},
- {427, {wxGrid, getColLabelSize, 0}},
- {428, {wxGrid, getColLabelValue, 1}},
- {429, {wxGrid, getColMinimalAcceptableWidth, 0}},
- {430, {wxGrid, getDefaultCellAlignment, 2}},
- {431, {wxGrid, getDefaultCellBackgroundColour, 0}},
- {432, {wxGrid, getDefaultCellFont, 0}},
- {433, {wxGrid, getDefaultCellTextColour, 0}},
- {434, {wxGrid, getDefaultColLabelSize, 0}},
- {435, {wxGrid, getDefaultColSize, 0}},
- {436, {wxGrid, getDefaultEditor, 0}},
- {437, {wxGrid, getDefaultEditorForCell_2, 2}},
- {438, {wxGrid, getDefaultEditorForCell_1, 1}},
- {439, {wxGrid, getDefaultEditorForType, 1}},
- {440, {wxGrid, getDefaultRenderer, 0}},
- {441, {wxGrid, getDefaultRendererForCell, 2}},
- {442, {wxGrid, getDefaultRendererForType, 1}},
- {443, {wxGrid, getDefaultRowLabelSize, 0}},
- {444, {wxGrid, getDefaultRowSize, 0}},
- {445, {wxGrid, getGridCursorCol, 0}},
- {446, {wxGrid, getGridCursorRow, 0}},
- {447, {wxGrid, getGridLineColour, 0}},
- {448, {wxGrid, gridLinesEnabled, 0}},
- {449, {wxGrid, getLabelBackgroundColour, 0}},
- {450, {wxGrid, getLabelFont, 0}},
- {451, {wxGrid, getLabelTextColour, 0}},
- {452, {wxGrid, getNumberCols, 0}},
- {453, {wxGrid, getNumberRows, 0}},
- {454, {wxGrid, getOrCreateCellAttr, 2}},
- {455, {wxGrid, getRowMinimalAcceptableHeight, 0}},
- {456, {wxGrid, getRowLabelAlignment, 2}},
- {457, {wxGrid, getRowLabelSize, 0}},
- {458, {wxGrid, getRowLabelValue, 1}},
- {459, {wxGrid, getRowSize, 1}},
- {460, {wxGrid, getScrollLineX, 0}},
- {461, {wxGrid, getScrollLineY, 0}},
- {462, {wxGrid, getSelectedCells, 0}},
- {463, {wxGrid, getSelectedCols, 0}},
- {464, {wxGrid, getSelectedRows, 0}},
- {465, {wxGrid, getSelectionBackground, 0}},
- {466, {wxGrid, getSelectionBlockTopLeft, 0}},
- {467, {wxGrid, getSelectionBlockBottomRight, 0}},
- {468, {wxGrid, getSelectionForeground, 0}},
- {469, {wxGrid, getViewWidth, 0}},
- {470, {wxGrid, getGridWindow, 0}},
- {471, {wxGrid, getGridRowLabelWindow, 0}},
- {472, {wxGrid, getGridColLabelWindow, 0}},
- {473, {wxGrid, getGridCornerLabelWindow, 0}},
- {474, {wxGrid, hideCellEditControl, 0}},
- {475, {wxGrid, insertCols, 1}},
- {476, {wxGrid, insertRows, 1}},
- {477, {wxGrid, isCellEditControlEnabled, 0}},
- {478, {wxGrid, isCurrentCellReadOnly, 0}},
- {479, {wxGrid, isEditable, 0}},
- {480, {wxGrid, isInSelection_2, 2}},
- {481, {wxGrid, isInSelection_1, 1}},
- {482, {wxGrid, isReadOnly, 2}},
- {483, {wxGrid, isSelection, 0}},
- {484, {wxGrid, isVisible_3, 3}},
- {485, {wxGrid, isVisible_2, 2}},
- {486, {wxGrid, makeCellVisible_2, 2}},
- {487, {wxGrid, makeCellVisible_1, 1}},
- {488, {wxGrid, moveCursorDown, 1}},
- {489, {wxGrid, moveCursorLeft, 1}},
- {490, {wxGrid, moveCursorRight, 1}},
- {491, {wxGrid, moveCursorUp, 1}},
- {492, {wxGrid, moveCursorDownBlock, 1}},
- {493, {wxGrid, moveCursorLeftBlock, 1}},
- {494, {wxGrid, moveCursorRightBlock, 1}},
- {495, {wxGrid, moveCursorUpBlock, 1}},
- {496, {wxGrid, movePageDown, 0}},
- {497, {wxGrid, movePageUp, 0}},
- {498, {wxGrid, registerDataType, 3}},
- {499, {wxGrid, saveEditControlValue, 0}},
- {500, {wxGrid, selectAll, 0}},
- {501, {wxGrid, selectBlock_5, 5}},
- {502, {wxGrid, selectBlock_3, 3}},
- {503, {wxGrid, selectCol, 2}},
- {504, {wxGrid, selectRow, 2}},
- {505, {wxGrid, setCellAlignment_4, 4}},
- {506, {wxGrid, setCellAlignment_3, 3}},
- {507, {wxGrid, setCellAlignment_1, 1}},
- {508, {wxGrid, setCellBackgroundColour_3_0, 3}},
- {509, {wxGrid, setCellBackgroundColour_1, 1}},
- {510, {wxGrid, setCellBackgroundColour_3_1, 3}},
- {511, {wxGrid, setCellEditor, 3}},
- {512, {wxGrid, setCellFont, 3}},
- {513, {wxGrid, setCellRenderer, 3}},
- {514, {wxGrid, setCellTextColour_3_0, 3}},
- {515, {wxGrid, setCellTextColour_3_1, 3}},
- {516, {wxGrid, setCellTextColour_1, 1}},
- {517, {wxGrid, setCellValue_3_0, 3}},
- {518, {wxGrid, setCellValue_2, 2}},
- {519, {wxGrid, setCellValue_3_1, 3}},
- {520, {wxGrid, setColAttr, 2}},
- {521, {wxGrid, setColFormatBool, 1}},
- {522, {wxGrid, setColFormatNumber, 1}},
- {523, {wxGrid, setColFormatFloat, 2}},
- {524, {wxGrid, setColFormatCustom, 2}},
- {525, {wxGrid, setColLabelAlignment, 2}},
- {526, {wxGrid, setColLabelSize, 1}},
- {527, {wxGrid, setColLabelValue, 2}},
- {528, {wxGrid, setColMinimalWidth, 2}},
- {529, {wxGrid, setColMinimalAcceptableWidth, 1}},
- {530, {wxGrid, setColSize, 2}},
- {531, {wxGrid, setDefaultCellAlignment, 2}},
- {532, {wxGrid, setDefaultCellBackgroundColour, 1}},
- {533, {wxGrid, setDefaultCellFont, 1}},
- {534, {wxGrid, setDefaultCellTextColour, 1}},
- {535, {wxGrid, setDefaultEditor, 1}},
- {536, {wxGrid, setDefaultRenderer, 1}},
- {537, {wxGrid, setDefaultColSize, 2}},
- {538, {wxGrid, setDefaultRowSize, 2}},
- {539, {wxGrid, setGridCursor, 2}},
- {540, {wxGrid, setGridLineColour, 1}},
- {541, {wxGrid, setLabelBackgroundColour, 1}},
- {542, {wxGrid, setLabelFont, 1}},
- {543, {wxGrid, setLabelTextColour, 1}},
- {544, {wxGrid, setMargins, 2}},
- {545, {wxGrid, setReadOnly, 3}},
- {546, {wxGrid, setRowAttr, 2}},
- {547, {wxGrid, setRowLabelAlignment, 2}},
- {548, {wxGrid, setRowLabelSize, 1}},
- {549, {wxGrid, setRowLabelValue, 2}},
- {550, {wxGrid, setRowMinimalHeight, 2}},
- {551, {wxGrid, setRowMinimalAcceptableHeight, 1}},
- {552, {wxGrid, setRowSize, 2}},
- {553, {wxGrid, setScrollLineX, 1}},
- {554, {wxGrid, setScrollLineY, 1}},
- {555, {wxGrid, setSelectionBackground, 1}},
- {556, {wxGrid, setSelectionForeground, 1}},
- {557, {wxGrid, setSelectionMode, 1}},
- {558, {wxGrid, showCellEditControl, 0}},
- {559, {wxGrid, xToCol, 2}},
- {560, {wxGrid, xToEdgeOfCol, 1}},
- {561, {wxGrid, yToEdgeOfRow, 1}},
- {562, {wxGrid, yToRow, 1}},
- {563, {wxGridCellRenderer, draw, 7}},
- {564, {wxGridCellRenderer, getBestSize, 5}},
- {565, {wxGridCellEditor, create, 3}},
- {566, {wxGridCellEditor, isCreated, 0}},
- {567, {wxGridCellEditor, setSize, 1}},
- {568, {wxGridCellEditor, show, 2}},
- {569, {wxGridCellEditor, paintBackground, 2}},
- {570, {wxGridCellEditor, beginEdit, 3}},
- {571, {wxGridCellEditor, endEdit, 3}},
- {572, {wxGridCellEditor, reset, 0}},
- {573, {wxGridCellEditor, startingKey, 1}},
- {574, {wxGridCellEditor, startingClick, 0}},
- {575, {wxGridCellEditor, handleReturn, 1}},
- {576, {wxGridCellBoolRenderer, new, 0}},
- {577, {wxGridCellBoolRenderer, 'Destroy', undefined}},
- {578, {wxGridCellBoolEditor, new, 0}},
- {579, {wxGridCellBoolEditor, isTrueValue, 1}},
- {580, {wxGridCellBoolEditor, useStringValues, 1}},
- {581, {wxGridCellBoolEditor, 'Destroy', undefined}},
- {582, {wxGridCellFloatRenderer, new, 1}},
- {583, {wxGridCellFloatRenderer, getPrecision, 0}},
- {584, {wxGridCellFloatRenderer, getWidth, 0}},
- {585, {wxGridCellFloatRenderer, setParameters, 1}},
- {586, {wxGridCellFloatRenderer, setPrecision, 1}},
- {587, {wxGridCellFloatRenderer, setWidth, 1}},
- {588, {wxGridCellFloatRenderer, 'Destroy', undefined}},
- {589, {wxGridCellFloatEditor, new, 1}},
- {590, {wxGridCellFloatEditor, setParameters, 1}},
- {591, {wxGridCellFloatEditor, 'Destroy', undefined}},
- {592, {wxGridCellStringRenderer, new, 0}},
- {593, {wxGridCellStringRenderer, 'Destroy', undefined}},
- {594, {wxGridCellTextEditor, new, 0}},
- {595, {wxGridCellTextEditor, setParameters, 1}},
- {596, {wxGridCellTextEditor, 'Destroy', undefined}},
- {598, {wxGridCellChoiceEditor, new, 2}},
- {599, {wxGridCellChoiceEditor, setParameters, 1}},
- {600, {wxGridCellChoiceEditor, 'Destroy', undefined}},
- {601, {wxGridCellNumberRenderer, new, 0}},
- {602, {wxGridCellNumberRenderer, 'Destroy', undefined}},
- {603, {wxGridCellNumberEditor, new, 1}},
- {604, {wxGridCellNumberEditor, getValue, 0}},
- {605, {wxGridCellNumberEditor, setParameters, 1}},
- {606, {wxGridCellNumberEditor, 'Destroy', undefined}},
- {607, {wxGridCellAttr, setTextColour, 1}},
- {608, {wxGridCellAttr, setBackgroundColour, 1}},
- {609, {wxGridCellAttr, setFont, 1}},
- {610, {wxGridCellAttr, setAlignment, 2}},
- {611, {wxGridCellAttr, setReadOnly, 1}},
- {612, {wxGridCellAttr, setRenderer, 1}},
- {613, {wxGridCellAttr, setEditor, 1}},
- {614, {wxGridCellAttr, hasTextColour, 0}},
- {615, {wxGridCellAttr, hasBackgroundColour, 0}},
- {616, {wxGridCellAttr, hasFont, 0}},
- {617, {wxGridCellAttr, hasAlignment, 0}},
- {618, {wxGridCellAttr, hasRenderer, 0}},
- {619, {wxGridCellAttr, hasEditor, 0}},
- {620, {wxGridCellAttr, getTextColour, 0}},
- {621, {wxGridCellAttr, getBackgroundColour, 0}},
- {622, {wxGridCellAttr, getFont, 0}},
- {623, {wxGridCellAttr, getAlignment, 2}},
- {624, {wxGridCellAttr, getRenderer, 3}},
- {625, {wxGridCellAttr, getEditor, 3}},
- {626, {wxGridCellAttr, isReadOnly, 0}},
- {627, {wxGridCellAttr, setDefAttr, 1}},
- {628, {wxDC, blit, 5}},
- {629, {wxDC, calcBoundingBox, 2}},
- {630, {wxDC, clear, 0}},
- {631, {wxDC, computeScaleAndOrigin, 0}},
- {632, {wxDC, crossHair, 1}},
- {633, {wxDC, destroyClippingRegion, 0}},
- {634, {wxDC, deviceToLogicalX, 1}},
- {635, {wxDC, deviceToLogicalXRel, 1}},
- {636, {wxDC, deviceToLogicalY, 1}},
- {637, {wxDC, deviceToLogicalYRel, 1}},
- {638, {wxDC, drawArc, 3}},
- {639, {wxDC, drawBitmap, 3}},
- {640, {wxDC, drawCheckMark, 1}},
- {641, {wxDC, drawCircle, 2}},
- {643, {wxDC, drawEllipse_2, 2}},
- {644, {wxDC, drawEllipse_1, 1}},
- {645, {wxDC, drawEllipticArc, 4}},
- {646, {wxDC, drawIcon, 2}},
- {647, {wxDC, drawLabel, 3}},
- {648, {wxDC, drawLine, 2}},
- {649, {wxDC, drawLines, 3}},
- {651, {wxDC, drawPolygon, 3}},
- {653, {wxDC, drawPoint, 1}},
- {655, {wxDC, drawRectangle_2, 2}},
- {656, {wxDC, drawRectangle_1, 1}},
- {657, {wxDC, drawRotatedText, 3}},
- {659, {wxDC, drawRoundedRectangle_3, 3}},
- {660, {wxDC, drawRoundedRectangle_2, 2}},
- {661, {wxDC, drawText, 2}},
- {662, {wxDC, endDoc, 0}},
- {663, {wxDC, endPage, 0}},
- {664, {wxDC, floodFill, 3}},
- {665, {wxDC, getBackground, 0}},
- {666, {wxDC, getBackgroundMode, 0}},
- {667, {wxDC, getBrush, 0}},
- {668, {wxDC, getCharHeight, 0}},
- {669, {wxDC, getCharWidth, 0}},
- {670, {wxDC, getClippingBox, 4}},
- {672, {wxDC, getFont, 0}},
- {673, {wxDC, getLayoutDirection, 0}},
- {674, {wxDC, getLogicalFunction, 0}},
- {675, {wxDC, getMapMode, 0}},
- {676, {wxDC, getMultiLineTextExtent_4, 4}},
- {677, {wxDC, getMultiLineTextExtent_1, 1}},
- {678, {wxDC, getPartialTextExtents, 2}},
- {679, {wxDC, getPen, 0}},
- {680, {wxDC, getPixel, 2}},
- {681, {wxDC, getPPI, 0}},
- {683, {wxDC, getSize, 0}},
- {685, {wxDC, getSizeMM, 0}},
- {686, {wxDC, getTextBackground, 0}},
- {687, {wxDC, getTextExtent_4, 4}},
- {688, {wxDC, getTextExtent_1, 1}},
- {690, {wxDC, getTextForeground, 0}},
- {691, {wxDC, getUserScale, 2}},
- {692, {wxDC, gradientFillConcentric_3, 3}},
- {693, {wxDC, gradientFillConcentric_4, 4}},
- {694, {wxDC, gradientFillLinear, 4}},
- {695, {wxDC, logicalToDeviceX, 1}},
- {696, {wxDC, logicalToDeviceXRel, 1}},
- {697, {wxDC, logicalToDeviceY, 1}},
- {698, {wxDC, logicalToDeviceYRel, 1}},
- {699, {wxDC, maxX, 0}},
- {700, {wxDC, maxY, 0}},
- {701, {wxDC, minX, 0}},
- {702, {wxDC, minY, 0}},
- {703, {wxDC, isOk, 0}},
- {704, {wxDC, resetBoundingBox, 0}},
- {705, {wxDC, setAxisOrientation, 2}},
- {706, {wxDC, setBackground, 1}},
- {707, {wxDC, setBackgroundMode, 1}},
- {708, {wxDC, setBrush, 1}},
- {710, {wxDC, setClippingRegion_2, 2}},
- {711, {wxDC, setClippingRegion_1_1, 1}},
- {712, {wxDC, setClippingRegion_1_0, 1}},
- {713, {wxDC, setDeviceOrigin, 2}},
- {714, {wxDC, setFont, 1}},
- {715, {wxDC, setLayoutDirection, 1}},
- {716, {wxDC, setLogicalFunction, 1}},
- {717, {wxDC, setMapMode, 1}},
- {718, {wxDC, setPalette, 1}},
- {719, {wxDC, setPen, 1}},
- {720, {wxDC, setTextBackground, 1}},
- {721, {wxDC, setTextForeground, 1}},
- {722, {wxDC, setUserScale, 2}},
- {723, {wxDC, startDoc, 1}},
- {724, {wxDC, startPage, 0}},
- {725, {wxMirrorDC, new, 2}},
- {726, {wxMirrorDC, 'Destroy', undefined}},
- {727, {wxScreenDC, new, 0}},
- {728, {wxScreenDC, destruct, 0}},
- {729, {wxPostScriptDC, new_0, 0}},
- {730, {wxPostScriptDC, new_1, 1}},
- {731, {wxPostScriptDC, destruct, 0}},
- {732, {wxPostScriptDC, setResolution, 1}},
- {733, {wxPostScriptDC, getResolution, 0}},
- {734, {wxWindowDC, new_0, 0}},
- {735, {wxWindowDC, new_1, 1}},
- {736, {wxWindowDC, destruct, 0}},
- {737, {wxClientDC, new_0, 0}},
- {738, {wxClientDC, new_1, 1}},
- {739, {wxClientDC, 'Destroy', undefined}},
- {740, {wxPaintDC, new_0, 0}},
- {741, {wxPaintDC, new_1, 1}},
- {742, {wxPaintDC, 'Destroy', undefined}},
- {744, {wxMemoryDC, new_1_0, 1}},
- {745, {wxMemoryDC, new_1_1, 1}},
- {746, {wxMemoryDC, new_0, 0}},
- {748, {wxMemoryDC, destruct, 0}},
- {749, {wxMemoryDC, selectObject, 1}},
- {750, {wxMemoryDC, selectObjectAsSource, 1}},
- {751, {wxBufferedDC, new_0, 0}},
- {752, {wxBufferedDC, new_2, 2}},
- {753, {wxBufferedDC, new_3, 3}},
- {754, {wxBufferedDC, destruct, 0}},
- {755, {wxBufferedDC, init_2, 2}},
- {756, {wxBufferedDC, init_3, 3}},
- {757, {wxBufferedPaintDC, new_3, 3}},
- {758, {wxBufferedPaintDC, new_2, 2}},
- {759, {wxBufferedPaintDC, destruct, 0}},
- {760, {wxGraphicsObject, destruct, 0}},
- {761, {wxGraphicsObject, getRenderer, 0}},
- {762, {wxGraphicsObject, isNull, 0}},
- {763, {wxGraphicsContext, destruct, 0}},
- {764, {wxGraphicsContext, create_1_1, 1}},
- {765, {wxGraphicsContext, create_1_0, 1}},
- {766, {wxGraphicsContext, create_0, 0}},
- {767, {wxGraphicsContext, createPen, 1}},
- {768, {wxGraphicsContext, createBrush, 1}},
- {769, {wxGraphicsContext, createRadialGradientBrush, 7}},
- {770, {wxGraphicsContext, createLinearGradientBrush, 6}},
- {771, {wxGraphicsContext, createFont, 2}},
- {772, {wxGraphicsContext, createMatrix, 1}},
- {773, {wxGraphicsContext, createPath, 0}},
- {774, {wxGraphicsContext, clip_1, 1}},
- {775, {wxGraphicsContext, clip_4, 4}},
- {776, {wxGraphicsContext, resetClip, 0}},
- {777, {wxGraphicsContext, drawBitmap, 5}},
- {778, {wxGraphicsContext, drawEllipse, 4}},
- {779, {wxGraphicsContext, drawIcon, 5}},
- {780, {wxGraphicsContext, drawLines, 3}},
- {781, {wxGraphicsContext, drawPath, 2}},
- {782, {wxGraphicsContext, drawRectangle, 4}},
- {783, {wxGraphicsContext, drawRoundedRectangle, 5}},
- {784, {wxGraphicsContext, drawText_3, 3}},
- {785, {wxGraphicsContext, drawText_4_0, 4}},
- {786, {wxGraphicsContext, drawText_4_1, 4}},
- {787, {wxGraphicsContext, drawText_5, 5}},
- {788, {wxGraphicsContext, fillPath, 2}},
- {789, {wxGraphicsContext, strokePath, 1}},
- {790, {wxGraphicsContext, getPartialTextExtents, 2}},
- {791, {wxGraphicsContext, getTextExtent, 5}},
- {792, {wxGraphicsContext, rotate, 1}},
- {793, {wxGraphicsContext, scale, 2}},
- {794, {wxGraphicsContext, translate, 2}},
- {795, {wxGraphicsContext, getTransform, 0}},
- {796, {wxGraphicsContext, setTransform, 1}},
- {797, {wxGraphicsContext, concatTransform, 1}},
- {798, {wxGraphicsContext, setBrush_1_1, 1}},
- {799, {wxGraphicsContext, setBrush_1_0, 1}},
- {800, {wxGraphicsContext, setFont_1, 1}},
- {801, {wxGraphicsContext, setFont_2, 2}},
- {802, {wxGraphicsContext, setPen_1_0, 1}},
- {803, {wxGraphicsContext, setPen_1_1, 1}},
- {804, {wxGraphicsContext, strokeLine, 4}},
- {805, {wxGraphicsContext, strokeLines, 2}},
- {807, {wxGraphicsMatrix, concat, 1}},
- {809, {wxGraphicsMatrix, get, 1}},
- {810, {wxGraphicsMatrix, invert, 0}},
- {811, {wxGraphicsMatrix, isEqual, 1}},
- {813, {wxGraphicsMatrix, isIdentity, 0}},
- {814, {wxGraphicsMatrix, rotate, 1}},
- {815, {wxGraphicsMatrix, scale, 2}},
- {816, {wxGraphicsMatrix, translate, 2}},
- {817, {wxGraphicsMatrix, set, 1}},
- {818, {wxGraphicsMatrix, transformPoint, 2}},
- {819, {wxGraphicsMatrix, transformDistance, 2}},
- {820, {wxGraphicsPath, moveToPoint_2, 2}},
- {821, {wxGraphicsPath, moveToPoint_1, 1}},
- {822, {wxGraphicsPath, addArc_6, 6}},
- {823, {wxGraphicsPath, addArc_5, 5}},
- {824, {wxGraphicsPath, addArcToPoint, 5}},
- {825, {wxGraphicsPath, addCircle, 3}},
- {826, {wxGraphicsPath, addCurveToPoint_6, 6}},
- {827, {wxGraphicsPath, addCurveToPoint_3, 3}},
- {828, {wxGraphicsPath, addEllipse, 4}},
- {829, {wxGraphicsPath, addLineToPoint_2, 2}},
- {830, {wxGraphicsPath, addLineToPoint_1, 1}},
- {831, {wxGraphicsPath, addPath, 1}},
- {832, {wxGraphicsPath, addQuadCurveToPoint, 4}},
- {833, {wxGraphicsPath, addRectangle, 4}},
- {834, {wxGraphicsPath, addRoundedRectangle, 5}},
- {835, {wxGraphicsPath, closeSubpath, 0}},
- {836, {wxGraphicsPath, contains_3, 3}},
- {837, {wxGraphicsPath, contains_2, 2}},
- {839, {wxGraphicsPath, getBox, 0}},
- {841, {wxGraphicsPath, getCurrentPoint, 0}},
- {842, {wxGraphicsPath, transform, 1}},
- {843, {wxGraphicsRenderer, getDefaultRenderer, 0}},
- {844, {wxGraphicsRenderer, createContext_1_1, 1}},
- {845, {wxGraphicsRenderer, createContext_1_0, 1}},
- {846, {wxGraphicsRenderer, createPen, 1}},
- {847, {wxGraphicsRenderer, createBrush, 1}},
- {848, {wxGraphicsRenderer, createLinearGradientBrush, 6}},
- {849, {wxGraphicsRenderer, createRadialGradientBrush, 7}},
- {850, {wxGraphicsRenderer, createFont, 2}},
- {851, {wxGraphicsRenderer, createMatrix, 1}},
- {852, {wxGraphicsRenderer, createPath, 0}},
- {854, {wxMenuBar, new_1, 1}},
- {856, {wxMenuBar, new_0, 0}},
- {858, {wxMenuBar, destruct, 0}},
- {859, {wxMenuBar, append, 2}},
- {860, {wxMenuBar, check, 2}},
- {861, {wxMenuBar, enable_2, 2}},
- {862, {wxMenuBar, enable_1, 1}},
- {863, {wxMenuBar, enableTop, 2}},
- {864, {wxMenuBar, findMenu, 1}},
- {865, {wxMenuBar, findMenuItem, 2}},
- {866, {wxMenuBar, findItem, 2}},
- {867, {wxMenuBar, getHelpString, 1}},
- {868, {wxMenuBar, getLabel_1, 1}},
- {869, {wxMenuBar, getLabel_0, 0}},
- {870, {wxMenuBar, getLabelTop, 1}},
- {871, {wxMenuBar, getMenu, 1}},
- {872, {wxMenuBar, getMenuCount, 0}},
- {873, {wxMenuBar, insert, 3}},
- {874, {wxMenuBar, isChecked, 1}},
- {875, {wxMenuBar, isEnabled_1, 1}},
- {876, {wxMenuBar, isEnabled_0, 0}},
- {877, {wxMenuBar, remove, 1}},
- {878, {wxMenuBar, replace, 3}},
- {879, {wxMenuBar, setHelpString, 2}},
- {880, {wxMenuBar, setLabel_2, 2}},
- {881, {wxMenuBar, setLabel_1, 1}},
- {882, {wxMenuBar, setLabelTop, 2}},
- {883, {wxControl, getLabel, 0}},
- {884, {wxControl, setLabel, 1}},
- {885, {wxControlWithItems, append_1, 1}},
- {886, {wxControlWithItems, append_2, 2}},
- {887, {wxControlWithItems, appendStrings_1, 1}},
- {888, {wxControlWithItems, clear, 0}},
- {889, {wxControlWithItems, delete, 1}},
- {890, {wxControlWithItems, findString, 2}},
- {891, {wxControlWithItems, getClientData, 1}},
- {892, {wxControlWithItems, setClientData, 2}},
- {893, {wxControlWithItems, getCount, 0}},
- {894, {wxControlWithItems, getSelection, 0}},
- {895, {wxControlWithItems, getString, 1}},
- {896, {wxControlWithItems, getStringSelection, 0}},
- {897, {wxControlWithItems, insert_2, 2}},
- {898, {wxControlWithItems, insert_3, 3}},
- {899, {wxControlWithItems, isEmpty, 0}},
- {900, {wxControlWithItems, select, 1}},
- {901, {wxControlWithItems, setSelection, 1}},
- {902, {wxControlWithItems, setString, 2}},
- {903, {wxControlWithItems, setStringSelection, 1}},
- {906, {wxMenu, new_2, 2}},
- {907, {wxMenu, new_1, 1}},
- {909, {wxMenu, destruct, 0}},
- {910, {wxMenu, append_3, 3}},
- {911, {wxMenu, append_1, 1}},
- {912, {wxMenu, append_4_0, 4}},
- {913, {wxMenu, append_4_1, 4}},
- {914, {wxMenu, appendCheckItem, 3}},
- {915, {wxMenu, appendRadioItem, 3}},
- {916, {wxMenu, appendSeparator, 0}},
- {917, {wxMenu, break, 0}},
- {918, {wxMenu, check, 2}},
- {919, {wxMenu, delete_1_0, 1}},
- {920, {wxMenu, delete_1_1, 1}},
- {921, {wxMenu, destroy_1_0, 1}},
- {922, {wxMenu, destroy_1_1, 1}},
- {923, {wxMenu, enable, 2}},
- {924, {wxMenu, findItem_1, 1}},
- {925, {wxMenu, findItem_2, 2}},
- {926, {wxMenu, findItemByPosition, 1}},
- {927, {wxMenu, getHelpString, 1}},
- {928, {wxMenu, getLabel, 1}},
- {929, {wxMenu, getMenuItemCount, 0}},
- {930, {wxMenu, getMenuItems, 0}},
- {932, {wxMenu, getTitle, 0}},
- {933, {wxMenu, insert_2, 2}},
- {934, {wxMenu, insert_3, 3}},
- {935, {wxMenu, insert_5_1, 5}},
- {936, {wxMenu, insert_5_0, 5}},
- {937, {wxMenu, insertCheckItem, 4}},
- {938, {wxMenu, insertRadioItem, 4}},
- {939, {wxMenu, insertSeparator, 1}},
- {940, {wxMenu, isChecked, 1}},
- {941, {wxMenu, isEnabled, 1}},
- {942, {wxMenu, prepend_1, 1}},
- {943, {wxMenu, prepend_2, 2}},
- {944, {wxMenu, prepend_4_1, 4}},
- {945, {wxMenu, prepend_4_0, 4}},
- {946, {wxMenu, prependCheckItem, 3}},
- {947, {wxMenu, prependRadioItem, 3}},
- {948, {wxMenu, prependSeparator, 0}},
- {949, {wxMenu, remove_1_0, 1}},
- {950, {wxMenu, remove_1_1, 1}},
- {951, {wxMenu, setHelpString, 2}},
- {952, {wxMenu, setLabel, 2}},
- {953, {wxMenu, setTitle, 1}},
- {954, {wxMenuItem, new, 1}},
- {956, {wxMenuItem, destruct, 0}},
- {957, {wxMenuItem, check, 1}},
- {958, {wxMenuItem, enable, 1}},
- {959, {wxMenuItem, getBitmap, 0}},
- {960, {wxMenuItem, getHelp, 0}},
- {961, {wxMenuItem, getId, 0}},
- {962, {wxMenuItem, getKind, 0}},
- {963, {wxMenuItem, getLabel, 0}},
- {964, {wxMenuItem, getLabelFromText, 1}},
- {965, {wxMenuItem, getMenu, 0}},
- {966, {wxMenuItem, getText, 0}},
- {967, {wxMenuItem, getSubMenu, 0}},
- {968, {wxMenuItem, isCheckable, 0}},
- {969, {wxMenuItem, isChecked, 0}},
- {970, {wxMenuItem, isEnabled, 0}},
- {971, {wxMenuItem, isSeparator, 0}},
- {972, {wxMenuItem, isSubMenu, 0}},
- {973, {wxMenuItem, setBitmap, 1}},
- {974, {wxMenuItem, setHelp, 1}},
- {975, {wxMenuItem, setMenu, 1}},
- {976, {wxMenuItem, setSubMenu, 1}},
- {977, {wxMenuItem, setText, 1}},
- {978, {wxToolBar, addControl, 1}},
- {979, {wxToolBar, addSeparator, 0}},
- {980, {wxToolBar, addTool_5, 5}},
- {981, {wxToolBar, addTool_4_0, 4}},
- {982, {wxToolBar, addTool_1, 1}},
- {983, {wxToolBar, addTool_4_1, 4}},
- {984, {wxToolBar, addTool_3, 3}},
- {985, {wxToolBar, addTool_6, 6}},
- {986, {wxToolBar, addCheckTool, 4}},
- {987, {wxToolBar, addRadioTool, 4}},
- {988, {wxToolBar, addStretchableSpace, 0}},
- {989, {wxToolBar, insertStretchableSpace, 1}},
- {990, {wxToolBar, deleteTool, 1}},
- {991, {wxToolBar, deleteToolByPos, 1}},
- {992, {wxToolBar, enableTool, 2}},
- {993, {wxToolBar, findById, 1}},
- {994, {wxToolBar, findControl, 1}},
- {995, {wxToolBar, findToolForPosition, 2}},
- {996, {wxToolBar, getToolSize, 0}},
- {997, {wxToolBar, getToolBitmapSize, 0}},
- {998, {wxToolBar, getMargins, 0}},
- {999, {wxToolBar, getToolEnabled, 1}},
- {1000, {wxToolBar, getToolLongHelp, 1}},
- {1001, {wxToolBar, getToolPacking, 0}},
- {1002, {wxToolBar, getToolPos, 1}},
- {1003, {wxToolBar, getToolSeparation, 0}},
- {1004, {wxToolBar, getToolShortHelp, 1}},
- {1005, {wxToolBar, getToolState, 1}},
- {1006, {wxToolBar, insertControl, 2}},
- {1007, {wxToolBar, insertSeparator, 1}},
- {1008, {wxToolBar, insertTool_5, 5}},
- {1009, {wxToolBar, insertTool_2, 2}},
- {1010, {wxToolBar, insertTool_4, 4}},
- {1011, {wxToolBar, realize, 0}},
- {1012, {wxToolBar, removeTool, 1}},
- {1013, {wxToolBar, setMargins, 2}},
- {1014, {wxToolBar, setToolBitmapSize, 1}},
- {1015, {wxToolBar, setToolLongHelp, 2}},
- {1016, {wxToolBar, setToolPacking, 1}},
- {1017, {wxToolBar, setToolShortHelp, 2}},
- {1018, {wxToolBar, setToolSeparation, 1}},
- {1019, {wxToolBar, toggleTool, 2}},
- {1021, {wxStatusBar, new_0, 0}},
- {1022, {wxStatusBar, new_2, 2}},
- {1024, {wxStatusBar, destruct, 0}},
- {1025, {wxStatusBar, create, 2}},
- {1026, {wxStatusBar, getFieldRect, 2}},
- {1027, {wxStatusBar, getFieldsCount, 0}},
- {1028, {wxStatusBar, getStatusText, 1}},
- {1029, {wxStatusBar, popStatusText, 1}},
- {1030, {wxStatusBar, pushStatusText, 2}},
- {1031, {wxStatusBar, setFieldsCount, 2}},
- {1032, {wxStatusBar, setMinHeight, 1}},
- {1033, {wxStatusBar, setStatusText, 2}},
- {1034, {wxStatusBar, setStatusWidths, 2}},
- {1035, {wxStatusBar, setStatusStyles, 2}},
- {1036, {wxBitmap, new_0, 0}},
- {1037, {wxBitmap, new_3, 3}},
- {1038, {wxBitmap, new_4, 4}},
- {1039, {wxBitmap, new_2_0, 2}},
- {1040, {wxBitmap, new_2_1, 2}},
- {1041, {wxBitmap, destruct, 0}},
- {1042, {wxBitmap, convertToImage, 0}},
- {1043, {wxBitmap, copyFromIcon, 1}},
- {1044, {wxBitmap, create, 3}},
- {1045, {wxBitmap, getDepth, 0}},
- {1046, {wxBitmap, getHeight, 0}},
- {1047, {wxBitmap, getPalette, 0}},
- {1048, {wxBitmap, getMask, 0}},
- {1049, {wxBitmap, getWidth, 0}},
- {1050, {wxBitmap, getSubBitmap, 1}},
- {1051, {wxBitmap, loadFile, 2}},
- {1052, {wxBitmap, ok, 0}},
- {1053, {wxBitmap, saveFile, 3}},
- {1054, {wxBitmap, setDepth, 1}},
- {1055, {wxBitmap, setHeight, 1}},
- {1056, {wxBitmap, setMask, 1}},
- {1057, {wxBitmap, setPalette, 1}},
- {1058, {wxBitmap, setWidth, 1}},
- {1059, {wxIcon, new_0, 0}},
- {1060, {wxIcon, new_2, 2}},
- {1061, {wxIcon, new_1, 1}},
- {1062, {wxIcon, copyFromBitmap, 1}},
- {1063, {wxIcon, 'Destroy', undefined}},
- {1064, {wxIconBundle, new_0, 0}},
- {1065, {wxIconBundle, new_2, 2}},
- {1066, {wxIconBundle, new_1_0, 1}},
- {1067, {wxIconBundle, new_1_1, 1}},
- {1068, {wxIconBundle, destruct, 0}},
- {1069, {wxIconBundle, addIcon_2, 2}},
- {1070, {wxIconBundle, addIcon_1, 1}},
- {1071, {wxIconBundle, getIcon_1_1, 1}},
- {1072, {wxIconBundle, getIcon_1_0, 1}},
- {1073, {wxCursor, new_0, 0}},
- {1074, {wxCursor, new_1_0, 1}},
- {1075, {wxCursor, new_1_1, 1}},
- {1076, {wxCursor, new_4, 4}},
- {1077, {wxCursor, destruct, 0}},
- {1078, {wxCursor, ok, 0}},
- {1079, {wxMask, new_0, 0}},
- {1080, {wxMask, new_2_1, 2}},
- {1081, {wxMask, new_2_0, 2}},
- {1082, {wxMask, new_1, 1}},
- {1083, {wxMask, destruct, 0}},
- {1084, {wxMask, create_2_1, 2}},
- {1085, {wxMask, create_2_0, 2}},
- {1086, {wxMask, create_1, 1}},
- {1087, {wxImage, new_0, 0}},
- {1088, {wxImage, new_3_0, 3}},
- {1089, {wxImage, new_4, 4}},
- {1090, {wxImage, new_5, 5}},
- {1091, {wxImage, new_2, 2}},
- {1092, {wxImage, new_3_1, 3}},
- {1093, {wxImage, blur, 1}},
- {1094, {wxImage, blurHorizontal, 1}},
- {1095, {wxImage, blurVertical, 1}},
- {1096, {wxImage, convertAlphaToMask, 1}},
- {1097, {wxImage, convertToGreyscale, 1}},
- {1098, {wxImage, convertToMono, 3}},
- {1099, {wxImage, copy, 0}},
- {1100, {wxImage, create_3, 3}},
- {1101, {wxImage, create_4, 4}},
- {1102, {wxImage, create_5, 5}},
- {1103, {wxImage, 'Destroy', 0}},
- {1104, {wxImage, findFirstUnusedColour, 4}},
- {1105, {wxImage, getImageExtWildcard, 0}},
- {1106, {wxImage, getAlpha_2, 2}},
- {1107, {wxImage, getAlpha_0, 0}},
- {1108, {wxImage, getBlue, 2}},
- {1109, {wxImage, getData, 0}},
- {1110, {wxImage, getGreen, 2}},
- {1111, {wxImage, getImageCount, 2}},
- {1112, {wxImage, getHeight, 0}},
- {1113, {wxImage, getMaskBlue, 0}},
- {1114, {wxImage, getMaskGreen, 0}},
- {1115, {wxImage, getMaskRed, 0}},
- {1116, {wxImage, getOrFindMaskColour, 3}},
- {1117, {wxImage, getPalette, 0}},
- {1118, {wxImage, getRed, 2}},
- {1119, {wxImage, getSubImage, 1}},
- {1120, {wxImage, getWidth, 0}},
- {1121, {wxImage, hasAlpha, 0}},
- {1122, {wxImage, hasMask, 0}},
- {1123, {wxImage, getOption, 1}},
- {1124, {wxImage, getOptionInt, 1}},
- {1125, {wxImage, hasOption, 1}},
- {1126, {wxImage, initAlpha, 0}},
- {1127, {wxImage, initStandardHandlers, 0}},
- {1128, {wxImage, isTransparent, 3}},
- {1129, {wxImage, loadFile_2, 2}},
- {1130, {wxImage, loadFile_3, 3}},
- {1131, {wxImage, ok, 0}},
- {1132, {wxImage, removeHandler, 1}},
- {1133, {wxImage, mirror, 1}},
- {1134, {wxImage, replace, 6}},
- {1135, {wxImage, rescale, 3}},
- {1136, {wxImage, resize, 3}},
- {1137, {wxImage, rotate, 3}},
- {1138, {wxImage, rotateHue, 1}},
- {1139, {wxImage, rotate90, 1}},
- {1140, {wxImage, saveFile_1, 1}},
- {1141, {wxImage, saveFile_2_0, 2}},
- {1142, {wxImage, saveFile_2_1, 2}},
- {1143, {wxImage, scale, 3}},
- {1144, {wxImage, size, 3}},
- {1145, {wxImage, setAlpha_3, 3}},
- {1146, {wxImage, setAlpha_2, 2}},
- {1147, {wxImage, setData_2, 2}},
- {1148, {wxImage, setData_4, 4}},
- {1149, {wxImage, setMask, 1}},
- {1150, {wxImage, setMaskColour, 3}},
- {1151, {wxImage, setMaskFromImage, 4}},
- {1152, {wxImage, setOption_2_1, 2}},
- {1153, {wxImage, setOption_2_0, 2}},
- {1154, {wxImage, setPalette, 1}},
- {1155, {wxImage, setRGB_5, 5}},
- {1156, {wxImage, setRGB_4, 4}},
- {1157, {wxImage, 'Destroy', undefined}},
- {1158, {wxBrush, new_0, 0}},
- {1159, {wxBrush, new_2, 2}},
- {1160, {wxBrush, new_1, 1}},
- {1162, {wxBrush, destruct, 0}},
- {1163, {wxBrush, getColour, 0}},
- {1164, {wxBrush, getStipple, 0}},
- {1165, {wxBrush, getStyle, 0}},
- {1166, {wxBrush, isHatch, 0}},
- {1167, {wxBrush, isOk, 0}},
- {1168, {wxBrush, setColour_1, 1}},
- {1169, {wxBrush, setColour_3, 3}},
- {1170, {wxBrush, setStipple, 1}},
- {1171, {wxBrush, setStyle, 1}},
- {1172, {wxPen, new_0, 0}},
- {1173, {wxPen, new_2, 2}},
- {1174, {wxPen, destruct, 0}},
- {1175, {wxPen, getCap, 0}},
- {1176, {wxPen, getColour, 0}},
- {1177, {wxPen, getJoin, 0}},
- {1178, {wxPen, getStyle, 0}},
- {1179, {wxPen, getWidth, 0}},
- {1180, {wxPen, isOk, 0}},
- {1181, {wxPen, setCap, 1}},
- {1182, {wxPen, setColour_1, 1}},
- {1183, {wxPen, setColour_3, 3}},
- {1184, {wxPen, setJoin, 1}},
- {1185, {wxPen, setStyle, 1}},
- {1186, {wxPen, setWidth, 1}},
- {1187, {wxRegion, new_0, 0}},
- {1188, {wxRegion, new_4, 4}},
- {1189, {wxRegion, new_2, 2}},
- {1190, {wxRegion, new_1_1, 1}},
- {1192, {wxRegion, new_1_0, 1}},
- {1194, {wxRegion, destruct, 0}},
- {1195, {wxRegion, clear, 0}},
- {1196, {wxRegion, contains_2, 2}},
- {1197, {wxRegion, contains_1_0, 1}},
- {1198, {wxRegion, contains_4, 4}},
- {1199, {wxRegion, contains_1_1, 1}},
- {1200, {wxRegion, convertToBitmap, 0}},
- {1201, {wxRegion, getBox, 0}},
- {1202, {wxRegion, intersect_4, 4}},
- {1203, {wxRegion, intersect_1_1, 1}},
- {1204, {wxRegion, intersect_1_0, 1}},
- {1205, {wxRegion, isEmpty, 0}},
- {1206, {wxRegion, subtract_4, 4}},
- {1207, {wxRegion, subtract_1_1, 1}},
- {1208, {wxRegion, subtract_1_0, 1}},
- {1209, {wxRegion, offset_2, 2}},
- {1210, {wxRegion, offset_1, 1}},
- {1211, {wxRegion, union_4, 4}},
- {1212, {wxRegion, union_1_2, 1}},
- {1213, {wxRegion, union_1_1, 1}},
- {1214, {wxRegion, union_1_0, 1}},
- {1215, {wxRegion, union_3, 3}},
- {1216, {wxRegion, xor_4, 4}},
- {1217, {wxRegion, xor_1_1, 1}},
- {1218, {wxRegion, xor_1_0, 1}},
- {1219, {wxAcceleratorTable, new_0, 0}},
- {1220, {wxAcceleratorTable, new_2, 2}},
- {1221, {wxAcceleratorTable, destruct, 0}},
- {1222, {wxAcceleratorTable, ok, 0}},
- {1223, {wxAcceleratorEntry, new_1_0, 1}},
- {1224, {wxAcceleratorEntry, new_1_1, 1}},
- {1225, {wxAcceleratorEntry, getCommand, 0}},
- {1226, {wxAcceleratorEntry, getFlags, 0}},
- {1227, {wxAcceleratorEntry, getKeyCode, 0}},
- {1228, {wxAcceleratorEntry, set, 4}},
- {1229, {wxAcceleratorEntry, 'Destroy', undefined}},
- {1234, {wxCaret, new_3, 3}},
- {1235, {wxCaret, new_2, 2}},
- {1237, {wxCaret, destruct, 0}},
- {1238, {wxCaret, create_3, 3}},
- {1239, {wxCaret, create_2, 2}},
- {1240, {wxCaret, getBlinkTime, 0}},
- {1242, {wxCaret, getPosition, 0}},
- {1244, {wxCaret, getSize, 0}},
- {1245, {wxCaret, getWindow, 0}},
- {1246, {wxCaret, hide, 0}},
- {1247, {wxCaret, isOk, 0}},
- {1248, {wxCaret, isVisible, 0}},
- {1249, {wxCaret, move_2, 2}},
- {1250, {wxCaret, move_1, 1}},
- {1251, {wxCaret, setBlinkTime, 1}},
- {1252, {wxCaret, setSize_2, 2}},
- {1253, {wxCaret, setSize_1, 1}},
- {1254, {wxCaret, show, 1}},
- {1255, {wxSizer, add_2_1, 2}},
- {1256, {wxSizer, add_2_0, 2}},
- {1257, {wxSizer, add_3, 3}},
- {1258, {wxSizer, add_2_3, 2}},
- {1259, {wxSizer, add_2_2, 2}},
- {1260, {wxSizer, addSpacer, 1}},
- {1261, {wxSizer, addStretchSpacer, 1}},
- {1262, {wxSizer, calcMin, 0}},
- {1263, {wxSizer, clear, 1}},
- {1264, {wxSizer, detach_1_2, 1}},
- {1265, {wxSizer, detach_1_1, 1}},
- {1266, {wxSizer, detach_1_0, 1}},
- {1267, {wxSizer, fit, 1}},
- {1268, {wxSizer, fitInside, 1}},
- {1269, {wxSizer, getChildren, 0}},
- {1270, {wxSizer, getItem_2_1, 2}},
- {1271, {wxSizer, getItem_2_0, 2}},
- {1272, {wxSizer, getItem_1, 1}},
- {1273, {wxSizer, getSize, 0}},
- {1274, {wxSizer, getPosition, 0}},
- {1275, {wxSizer, getMinSize, 0}},
- {1276, {wxSizer, hide_2_0, 2}},
- {1277, {wxSizer, hide_2_1, 2}},
- {1278, {wxSizer, hide_1, 1}},
- {1279, {wxSizer, insert_3_1, 3}},
- {1280, {wxSizer, insert_3_0, 3}},
- {1281, {wxSizer, insert_4, 4}},
- {1282, {wxSizer, insert_3_3, 3}},
- {1283, {wxSizer, insert_3_2, 3}},
- {1284, {wxSizer, insert_2, 2}},
- {1285, {wxSizer, insertSpacer, 2}},
- {1286, {wxSizer, insertStretchSpacer, 2}},
- {1287, {wxSizer, isShown_1_2, 1}},
- {1288, {wxSizer, isShown_1_1, 1}},
- {1289, {wxSizer, isShown_1_0, 1}},
- {1290, {wxSizer, layout, 0}},
- {1291, {wxSizer, prepend_2_1, 2}},
- {1292, {wxSizer, prepend_2_0, 2}},
- {1293, {wxSizer, prepend_3, 3}},
- {1294, {wxSizer, prepend_2_3, 2}},
- {1295, {wxSizer, prepend_2_2, 2}},
- {1296, {wxSizer, prepend_1, 1}},
- {1297, {wxSizer, prependSpacer, 1}},
- {1298, {wxSizer, prependStretchSpacer, 1}},
- {1299, {wxSizer, recalcSizes, 0}},
- {1300, {wxSizer, remove_1_1, 1}},
- {1301, {wxSizer, remove_1_0, 1}},
- {1302, {wxSizer, replace_3_1, 3}},
- {1303, {wxSizer, replace_3_0, 3}},
- {1304, {wxSizer, replace_2, 2}},
- {1305, {wxSizer, setDimension, 4}},
- {1306, {wxSizer, setMinSize_2, 2}},
- {1307, {wxSizer, setMinSize_1, 1}},
- {1308, {wxSizer, setItemMinSize_3_2, 3}},
- {1309, {wxSizer, setItemMinSize_2_2, 2}},
- {1310, {wxSizer, setItemMinSize_3_1, 3}},
- {1311, {wxSizer, setItemMinSize_2_1, 2}},
- {1312, {wxSizer, setItemMinSize_3_0, 3}},
- {1313, {wxSizer, setItemMinSize_2_0, 2}},
- {1314, {wxSizer, setSizeHints, 1}},
- {1315, {wxSizer, setVirtualSizeHints, 1}},
- {1316, {wxSizer, show_2_2, 2}},
- {1317, {wxSizer, show_2_1, 2}},
- {1318, {wxSizer, show_2_0, 2}},
- {1319, {wxSizer, show_1, 1}},
- {1320, {wxSizerFlags, new, 1}},
- {1321, {wxSizerFlags, align, 1}},
- {1322, {wxSizerFlags, border_2, 2}},
- {1323, {wxSizerFlags, border_1, 1}},
- {1324, {wxSizerFlags, center, 0}},
- {1325, {wxSizerFlags, centre, 0}},
- {1326, {wxSizerFlags, expand, 0}},
- {1327, {wxSizerFlags, left, 0}},
- {1328, {wxSizerFlags, proportion, 1}},
- {1329, {wxSizerFlags, right, 0}},
- {1330, {wxSizerFlags, 'Destroy', undefined}},
- {1331, {wxSizerItem, new_5_1, 5}},
- {1332, {wxSizerItem, new_2_1, 2}},
- {1333, {wxSizerItem, new_5_0, 5}},
- {1334, {wxSizerItem, new_2_0, 2}},
- {1335, {wxSizerItem, new_6, 6}},
- {1336, {wxSizerItem, new_3, 3}},
- {1337, {wxSizerItem, new_0, 0}},
- {1338, {wxSizerItem, destruct, 0}},
- {1339, {wxSizerItem, calcMin, 0}},
- {1340, {wxSizerItem, deleteWindows, 0}},
- {1341, {wxSizerItem, detachSizer, 0}},
- {1342, {wxSizerItem, getBorder, 0}},
- {1343, {wxSizerItem, getFlag, 0}},
- {1344, {wxSizerItem, getMinSize, 0}},
- {1345, {wxSizerItem, getPosition, 0}},
- {1346, {wxSizerItem, getProportion, 0}},
- {1347, {wxSizerItem, getRatio, 0}},
- {1348, {wxSizerItem, getRect, 0}},
- {1349, {wxSizerItem, getSize, 0}},
- {1350, {wxSizerItem, getSizer, 0}},
- {1351, {wxSizerItem, getSpacer, 0}},
- {1352, {wxSizerItem, getUserData, 0}},
- {1353, {wxSizerItem, getWindow, 0}},
- {1354, {wxSizerItem, isSizer, 0}},
- {1355, {wxSizerItem, isShown, 0}},
- {1356, {wxSizerItem, isSpacer, 0}},
- {1357, {wxSizerItem, isWindow, 0}},
- {1358, {wxSizerItem, setBorder, 1}},
- {1359, {wxSizerItem, setDimension, 2}},
- {1360, {wxSizerItem, setFlag, 1}},
- {1361, {wxSizerItem, setInitSize, 2}},
- {1362, {wxSizerItem, setMinSize_1, 1}},
- {1363, {wxSizerItem, setMinSize_2, 2}},
- {1364, {wxSizerItem, setProportion, 1}},
- {1365, {wxSizerItem, setRatio_2, 2}},
- {1366, {wxSizerItem, setRatio_1_1, 1}},
- {1367, {wxSizerItem, setRatio_1_0, 1}},
- {1368, {wxSizerItem, setSizer, 1}},
- {1369, {wxSizerItem, setSpacer_1, 1}},
- {1370, {wxSizerItem, setSpacer_2, 2}},
- {1371, {wxSizerItem, setWindow, 1}},
- {1372, {wxSizerItem, show, 1}},
- {1373, {wxBoxSizer, new, 1}},
- {1374, {wxBoxSizer, getOrientation, 0}},
- {1375, {wxBoxSizer, 'Destroy', undefined}},
- {1376, {wxStaticBoxSizer, new_2, 2}},
- {1377, {wxStaticBoxSizer, new_3, 3}},
- {1378, {wxStaticBoxSizer, getStaticBox, 0}},
- {1379, {wxStaticBoxSizer, 'Destroy', undefined}},
- {1380, {wxGridSizer, new_4, 4}},
- {1381, {wxGridSizer, new_2, 2}},
- {1382, {wxGridSizer, getCols, 0}},
- {1383, {wxGridSizer, getHGap, 0}},
- {1384, {wxGridSizer, getRows, 0}},
- {1385, {wxGridSizer, getVGap, 0}},
- {1386, {wxGridSizer, setCols, 1}},
- {1387, {wxGridSizer, setHGap, 1}},
- {1388, {wxGridSizer, setRows, 1}},
- {1389, {wxGridSizer, setVGap, 1}},
- {1390, {wxGridSizer, 'Destroy', undefined}},
- {1391, {wxFlexGridSizer, new_4, 4}},
- {1392, {wxFlexGridSizer, new_2, 2}},
- {1393, {wxFlexGridSizer, addGrowableCol, 2}},
- {1394, {wxFlexGridSizer, addGrowableRow, 2}},
- {1395, {wxFlexGridSizer, getFlexibleDirection, 0}},
- {1396, {wxFlexGridSizer, getNonFlexibleGrowMode, 0}},
- {1397, {wxFlexGridSizer, removeGrowableCol, 1}},
- {1398, {wxFlexGridSizer, removeGrowableRow, 1}},
- {1399, {wxFlexGridSizer, setFlexibleDirection, 1}},
- {1400, {wxFlexGridSizer, setNonFlexibleGrowMode, 1}},
- {1401, {wxFlexGridSizer, 'Destroy', undefined}},
- {1402, {wxGridBagSizer, new, 1}},
- {1403, {wxGridBagSizer, add_3_2, 3}},
- {1404, {wxGridBagSizer, add_3_1, 3}},
- {1405, {wxGridBagSizer, add_4, 4}},
- {1406, {wxGridBagSizer, add_1_0, 1}},
- {1407, {wxGridBagSizer, add_2_1, 2}},
- {1408, {wxGridBagSizer, add_2_0, 2}},
- {1409, {wxGridBagSizer, add_3_0, 3}},
- {1410, {wxGridBagSizer, add_1_1, 1}},
- {1411, {wxGridBagSizer, calcMin, 0}},
- {1412, {wxGridBagSizer, checkForIntersection_2, 2}},
- {1413, {wxGridBagSizer, checkForIntersection_3, 3}},
- {1414, {wxGridBagSizer, findItem_1_1, 1}},
- {1415, {wxGridBagSizer, findItem_1_0, 1}},
- {1416, {wxGridBagSizer, findItemAtPoint, 1}},
- {1417, {wxGridBagSizer, findItemAtPosition, 1}},
- {1418, {wxGridBagSizer, findItemWithData, 1}},
- {1419, {wxGridBagSizer, getCellSize, 2}},
- {1420, {wxGridBagSizer, getEmptyCellSize, 0}},
- {1421, {wxGridBagSizer, getItemPosition_1_2, 1}},
- {1422, {wxGridBagSizer, getItemPosition_1_1, 1}},
- {1423, {wxGridBagSizer, getItemPosition_1_0, 1}},
- {1424, {wxGridBagSizer, getItemSpan_1_2, 1}},
- {1425, {wxGridBagSizer, getItemSpan_1_1, 1}},
- {1426, {wxGridBagSizer, getItemSpan_1_0, 1}},
- {1427, {wxGridBagSizer, setEmptyCellSize, 1}},
- {1428, {wxGridBagSizer, setItemPosition_2_2, 2}},
- {1429, {wxGridBagSizer, setItemPosition_2_1, 2}},
- {1430, {wxGridBagSizer, setItemPosition_2_0, 2}},
- {1431, {wxGridBagSizer, setItemSpan_2_2, 2}},
- {1432, {wxGridBagSizer, setItemSpan_2_1, 2}},
- {1433, {wxGridBagSizer, setItemSpan_2_0, 2}},
- {1434, {wxGridBagSizer, 'Destroy', undefined}},
- {1435, {wxStdDialogButtonSizer, new, 0}},
- {1436, {wxStdDialogButtonSizer, addButton, 1}},
- {1437, {wxStdDialogButtonSizer, realize, 0}},
- {1438, {wxStdDialogButtonSizer, setAffirmativeButton, 1}},
- {1439, {wxStdDialogButtonSizer, setCancelButton, 1}},
- {1440, {wxStdDialogButtonSizer, setNegativeButton, 1}},
- {1441, {wxStdDialogButtonSizer, 'Destroy', undefined}},
- {1442, {wxFont, new_0, 0}},
- {1443, {wxFont, new_1, 1}},
- {1444, {wxFont, new_5, 5}},
- {1446, {wxFont, destruct, 0}},
- {1447, {wxFont, isFixedWidth, 0}},
- {1448, {wxFont, getDefaultEncoding, 0}},
- {1449, {wxFont, getFaceName, 0}},
- {1450, {wxFont, getFamily, 0}},
- {1451, {wxFont, getNativeFontInfoDesc, 0}},
- {1452, {wxFont, getNativeFontInfoUserDesc, 0}},
- {1453, {wxFont, getPointSize, 0}},
- {1454, {wxFont, getStyle, 0}},
- {1455, {wxFont, getUnderlined, 0}},
- {1456, {wxFont, getWeight, 0}},
- {1457, {wxFont, ok, 0}},
- {1458, {wxFont, setDefaultEncoding, 1}},
- {1459, {wxFont, setFaceName, 1}},
- {1460, {wxFont, setFamily, 1}},
- {1461, {wxFont, setPointSize, 1}},
- {1462, {wxFont, setStyle, 1}},
- {1463, {wxFont, setUnderlined, 1}},
- {1464, {wxFont, setWeight, 1}},
- {1465, {wxToolTip, enable, 1}},
- {1466, {wxToolTip, setDelay, 1}},
- {1467, {wxToolTip, new, 1}},
- {1468, {wxToolTip, setTip, 1}},
- {1469, {wxToolTip, getTip, 0}},
- {1470, {wxToolTip, getWindow, 0}},
- {1471, {wxToolTip, 'Destroy', undefined}},
- {1473, {wxButton, new_3, 3}},
- {1474, {wxButton, new_0, 0}},
- {1475, {wxButton, destruct, 0}},
- {1476, {wxButton, create, 3}},
- {1477, {wxButton, getDefaultSize, 0}},
- {1478, {wxButton, setDefault, 0}},
- {1479, {wxButton, setLabel, 1}},
- {1481, {wxBitmapButton, new_4, 4}},
- {1482, {wxBitmapButton, new_0, 0}},
- {1483, {wxBitmapButton, create, 4}},
- {1484, {wxBitmapButton, getBitmapDisabled, 0}},
- {1486, {wxBitmapButton, getBitmapFocus, 0}},
- {1488, {wxBitmapButton, getBitmapLabel, 0}},
- {1490, {wxBitmapButton, getBitmapSelected, 0}},
- {1492, {wxBitmapButton, setBitmapDisabled, 1}},
- {1493, {wxBitmapButton, setBitmapFocus, 1}},
- {1494, {wxBitmapButton, setBitmapLabel, 1}},
- {1495, {wxBitmapButton, setBitmapSelected, 1}},
- {1496, {wxBitmapButton, 'Destroy', undefined}},
- {1497, {wxToggleButton, new_0, 0}},
- {1498, {wxToggleButton, new_4, 4}},
- {1499, {wxToggleButton, create, 4}},
- {1500, {wxToggleButton, getValue, 0}},
- {1501, {wxToggleButton, setValue, 1}},
- {1502, {wxToggleButton, 'Destroy', undefined}},
- {1503, {wxCalendarCtrl, new_0, 0}},
- {1504, {wxCalendarCtrl, new_3, 3}},
- {1505, {wxCalendarCtrl, create, 3}},
- {1506, {wxCalendarCtrl, destruct, 0}},
- {1507, {wxCalendarCtrl, setDate, 1}},
- {1508, {wxCalendarCtrl, getDate, 0}},
- {1509, {wxCalendarCtrl, enableYearChange, 1}},
- {1510, {wxCalendarCtrl, enableMonthChange, 1}},
- {1511, {wxCalendarCtrl, enableHolidayDisplay, 1}},
- {1512, {wxCalendarCtrl, setHeaderColours, 2}},
- {1513, {wxCalendarCtrl, getHeaderColourFg, 0}},
- {1514, {wxCalendarCtrl, getHeaderColourBg, 0}},
- {1515, {wxCalendarCtrl, setHighlightColours, 2}},
- {1516, {wxCalendarCtrl, getHighlightColourFg, 0}},
- {1517, {wxCalendarCtrl, getHighlightColourBg, 0}},
- {1518, {wxCalendarCtrl, setHolidayColours, 2}},
- {1519, {wxCalendarCtrl, getHolidayColourFg, 0}},
- {1520, {wxCalendarCtrl, getHolidayColourBg, 0}},
- {1521, {wxCalendarCtrl, getAttr, 1}},
- {1522, {wxCalendarCtrl, setAttr, 2}},
- {1523, {wxCalendarCtrl, setHoliday, 1}},
- {1524, {wxCalendarCtrl, resetAttr, 1}},
- {1525, {wxCalendarCtrl, hitTest, 2}},
- {1526, {wxCalendarDateAttr, new_0, 0}},
- {1527, {wxCalendarDateAttr, new_2_1, 2}},
- {1528, {wxCalendarDateAttr, new_2_0, 2}},
- {1529, {wxCalendarDateAttr, setTextColour, 1}},
- {1530, {wxCalendarDateAttr, setBackgroundColour, 1}},
- {1531, {wxCalendarDateAttr, setBorderColour, 1}},
- {1532, {wxCalendarDateAttr, setFont, 1}},
- {1533, {wxCalendarDateAttr, setBorder, 1}},
- {1534, {wxCalendarDateAttr, setHoliday, 1}},
- {1535, {wxCalendarDateAttr, hasTextColour, 0}},
- {1536, {wxCalendarDateAttr, hasBackgroundColour, 0}},
- {1537, {wxCalendarDateAttr, hasBorderColour, 0}},
- {1538, {wxCalendarDateAttr, hasFont, 0}},
- {1539, {wxCalendarDateAttr, hasBorder, 0}},
- {1540, {wxCalendarDateAttr, isHoliday, 0}},
- {1541, {wxCalendarDateAttr, getTextColour, 0}},
- {1542, {wxCalendarDateAttr, getBackgroundColour, 0}},
- {1543, {wxCalendarDateAttr, getBorderColour, 0}},
- {1544, {wxCalendarDateAttr, getFont, 0}},
- {1545, {wxCalendarDateAttr, getBorder, 0}},
- {1546, {wxCalendarDateAttr, 'Destroy', undefined}},
- {1548, {wxCheckBox, new_4, 4}},
- {1549, {wxCheckBox, new_0, 0}},
- {1550, {wxCheckBox, create, 4}},
- {1551, {wxCheckBox, getValue, 0}},
- {1552, {wxCheckBox, get3StateValue, 0}},
- {1553, {wxCheckBox, is3rdStateAllowedForUser, 0}},
- {1554, {wxCheckBox, is3State, 0}},
- {1555, {wxCheckBox, isChecked, 0}},
- {1556, {wxCheckBox, setValue, 1}},
- {1557, {wxCheckBox, set3StateValue, 1}},
- {1558, {wxCheckBox, 'Destroy', undefined}},
- {1559, {wxCheckListBox, new_0, 0}},
- {1561, {wxCheckListBox, new_3, 3}},
- {1562, {wxCheckListBox, check, 2}},
- {1563, {wxCheckListBox, isChecked, 1}},
- {1564, {wxCheckListBox, 'Destroy', undefined}},
- {1567, {wxChoice, new_3, 3}},
- {1568, {wxChoice, new_0, 0}},
- {1570, {wxChoice, destruct, 0}},
- {1572, {wxChoice, create, 6}},
- {1573, {wxChoice, delete, 1}},
- {1574, {wxChoice, getColumns, 0}},
- {1575, {wxChoice, setColumns, 1}},
- {1576, {wxComboBox, new_0, 0}},
- {1578, {wxComboBox, new_3, 3}},
- {1579, {wxComboBox, destruct, 0}},
- {1581, {wxComboBox, create, 7}},
- {1582, {wxComboBox, canCopy, 0}},
- {1583, {wxComboBox, canCut, 0}},
- {1584, {wxComboBox, canPaste, 0}},
- {1585, {wxComboBox, canRedo, 0}},
- {1586, {wxComboBox, canUndo, 0}},
- {1587, {wxComboBox, copy, 0}},
- {1588, {wxComboBox, cut, 0}},
- {1589, {wxComboBox, getInsertionPoint, 0}},
- {1590, {wxComboBox, getLastPosition, 0}},
- {1591, {wxComboBox, getValue, 0}},
- {1592, {wxComboBox, paste, 0}},
- {1593, {wxComboBox, redo, 0}},
- {1594, {wxComboBox, replace, 3}},
- {1595, {wxComboBox, remove, 2}},
- {1596, {wxComboBox, setInsertionPoint, 1}},
- {1597, {wxComboBox, setInsertionPointEnd, 0}},
- {1598, {wxComboBox, setSelection_1, 1}},
- {1599, {wxComboBox, setSelection_2, 2}},
- {1600, {wxComboBox, setValue, 1}},
- {1601, {wxComboBox, undo, 0}},
- {1602, {wxGauge, new_0, 0}},
- {1603, {wxGauge, new_4, 4}},
- {1604, {wxGauge, create, 4}},
- {1605, {wxGauge, getRange, 0}},
- {1606, {wxGauge, getValue, 0}},
- {1607, {wxGauge, isVertical, 0}},
- {1608, {wxGauge, setRange, 1}},
- {1609, {wxGauge, setValue, 1}},
- {1610, {wxGauge, pulse, 0}},
- {1611, {wxGauge, 'Destroy', undefined}},
- {1612, {wxGenericDirCtrl, new_0, 0}},
- {1613, {wxGenericDirCtrl, new_2, 2}},
- {1614, {wxGenericDirCtrl, destruct, 0}},
- {1615, {wxGenericDirCtrl, create, 2}},
- {1616, {wxGenericDirCtrl, init, 0}},
- {1617, {wxGenericDirCtrl, collapseTree, 0}},
- {1618, {wxGenericDirCtrl, expandPath, 1}},
- {1619, {wxGenericDirCtrl, getDefaultPath, 0}},
- {1620, {wxGenericDirCtrl, getPath, 0}},
- {1621, {wxGenericDirCtrl, getFilePath, 0}},
- {1622, {wxGenericDirCtrl, getFilter, 0}},
- {1623, {wxGenericDirCtrl, getFilterIndex, 0}},
- {1624, {wxGenericDirCtrl, getRootId, 0}},
- {1625, {wxGenericDirCtrl, getTreeCtrl, 0}},
- {1626, {wxGenericDirCtrl, reCreateTree, 0}},
- {1627, {wxGenericDirCtrl, setDefaultPath, 1}},
- {1628, {wxGenericDirCtrl, setFilter, 1}},
- {1629, {wxGenericDirCtrl, setFilterIndex, 1}},
- {1630, {wxGenericDirCtrl, setPath, 1}},
- {1632, {wxStaticBox, new_4, 4}},
- {1633, {wxStaticBox, new_0, 0}},
- {1634, {wxStaticBox, create, 4}},
- {1635, {wxStaticBox, 'Destroy', undefined}},
- {1637, {wxStaticLine, new_2, 2}},
- {1638, {wxStaticLine, new_0, 0}},
- {1639, {wxStaticLine, create, 2}},
- {1640, {wxStaticLine, isVertical, 0}},
- {1641, {wxStaticLine, getDefaultSize, 0}},
- {1642, {wxStaticLine, 'Destroy', undefined}},
- {1645, {wxListBox, new_3, 3}},
- {1646, {wxListBox, new_0, 0}},
- {1648, {wxListBox, destruct, 0}},
- {1650, {wxListBox, create, 6}},
- {1651, {wxListBox, deselect, 1}},
- {1652, {wxListBox, getSelections, 1}},
- {1653, {wxListBox, insertItems, 2}},
- {1654, {wxListBox, isSelected, 1}},
- {1655, {wxListBox, set, 1}},
- {1656, {wxListBox, hitTest, 1}},
- {1657, {wxListBox, setFirstItem_1_0, 1}},
- {1658, {wxListBox, setFirstItem_1_1, 1}},
- {1659, {wxListCtrl, new_0, 0}},
- {1660, {wxListCtrl, new_2, 2}},
- {1661, {wxListCtrl, arrange, 1}},
- {1662, {wxListCtrl, assignImageList, 2}},
- {1663, {wxListCtrl, clearAll, 0}},
- {1664, {wxListCtrl, create, 2}},
- {1665, {wxListCtrl, deleteAllItems, 0}},
- {1666, {wxListCtrl, deleteColumn, 1}},
- {1667, {wxListCtrl, deleteItem, 1}},
- {1668, {wxListCtrl, editLabel, 1}},
- {1669, {wxListCtrl, ensureVisible, 1}},
- {1670, {wxListCtrl, findItem_3_0, 3}},
- {1671, {wxListCtrl, findItem_3_1, 3}},
- {1672, {wxListCtrl, getColumn, 2}},
- {1673, {wxListCtrl, getColumnCount, 0}},
- {1674, {wxListCtrl, getColumnWidth, 1}},
- {1675, {wxListCtrl, getCountPerPage, 0}},
- {1676, {wxListCtrl, getEditControl, 0}},
- {1677, {wxListCtrl, getImageList, 1}},
- {1678, {wxListCtrl, getItem, 1}},
- {1679, {wxListCtrl, getItemBackgroundColour, 1}},
- {1680, {wxListCtrl, getItemCount, 0}},
- {1681, {wxListCtrl, getItemData, 1}},
- {1682, {wxListCtrl, getItemFont, 1}},
- {1683, {wxListCtrl, getItemPosition, 2}},
- {1684, {wxListCtrl, getItemRect, 3}},
- {1685, {wxListCtrl, getItemSpacing, 0}},
- {1686, {wxListCtrl, getItemState, 2}},
- {1687, {wxListCtrl, getItemText, 1}},
- {1688, {wxListCtrl, getItemTextColour, 1}},
- {1689, {wxListCtrl, getNextItem, 2}},
- {1690, {wxListCtrl, getSelectedItemCount, 0}},
- {1691, {wxListCtrl, getTextColour, 0}},
- {1692, {wxListCtrl, getTopItem, 0}},
- {1693, {wxListCtrl, getViewRect, 0}},
- {1694, {wxListCtrl, hitTest, 3}},
- {1695, {wxListCtrl, insertColumn_2, 2}},
- {1696, {wxListCtrl, insertColumn_3, 3}},
- {1697, {wxListCtrl, insertItem_1, 1}},
- {1698, {wxListCtrl, insertItem_2_1, 2}},
- {1699, {wxListCtrl, insertItem_2_0, 2}},
- {1700, {wxListCtrl, insertItem_3, 3}},
- {1701, {wxListCtrl, refreshItem, 1}},
- {1702, {wxListCtrl, refreshItems, 2}},
- {1703, {wxListCtrl, scrollList, 2}},
- {1704, {wxListCtrl, setBackgroundColour, 1}},
- {1705, {wxListCtrl, setColumn, 2}},
- {1706, {wxListCtrl, setColumnWidth, 2}},
- {1707, {wxListCtrl, setImageList, 2}},
- {1708, {wxListCtrl, setItem_1, 1}},
- {1709, {wxListCtrl, setItem_4, 4}},
- {1710, {wxListCtrl, setItemBackgroundColour, 2}},
- {1711, {wxListCtrl, setItemCount, 1}},
- {1712, {wxListCtrl, setItemData, 2}},
- {1713, {wxListCtrl, setItemFont, 2}},
- {1714, {wxListCtrl, setItemImage, 3}},
- {1715, {wxListCtrl, setItemColumnImage, 3}},
- {1716, {wxListCtrl, setItemPosition, 2}},
- {1717, {wxListCtrl, setItemState, 3}},
- {1718, {wxListCtrl, setItemText, 2}},
- {1719, {wxListCtrl, setItemTextColour, 2}},
- {1720, {wxListCtrl, setSingleStyle, 2}},
- {1721, {wxListCtrl, setTextColour, 1}},
- {1722, {wxListCtrl, setWindowStyleFlag, 1}},
- {1723, {wxListCtrl, sortItems, 2}},
- {1724, {wxListCtrl, 'Destroy', undefined}},
- {1725, {wxListView, clearColumnImage, 1}},
- {1726, {wxListView, focus, 1}},
- {1727, {wxListView, getFirstSelected, 0}},
- {1728, {wxListView, getFocusedItem, 0}},
- {1729, {wxListView, getNextSelected, 1}},
- {1730, {wxListView, isSelected, 1}},
- {1731, {wxListView, select, 2}},
- {1732, {wxListView, setColumnImage, 2}},
- {1733, {wxListItem, new_0, 0}},
- {1734, {wxListItem, new_1, 1}},
- {1735, {wxListItem, destruct, 0}},
- {1736, {wxListItem, clear, 0}},
- {1737, {wxListItem, getAlign, 0}},
- {1738, {wxListItem, getBackgroundColour, 0}},
- {1739, {wxListItem, getColumn, 0}},
- {1740, {wxListItem, getFont, 0}},
- {1741, {wxListItem, getId, 0}},
- {1742, {wxListItem, getImage, 0}},
- {1743, {wxListItem, getMask, 0}},
- {1744, {wxListItem, getState, 0}},
- {1745, {wxListItem, getText, 0}},
- {1746, {wxListItem, getTextColour, 0}},
- {1747, {wxListItem, getWidth, 0}},
- {1748, {wxListItem, setAlign, 1}},
- {1749, {wxListItem, setBackgroundColour, 1}},
- {1750, {wxListItem, setColumn, 1}},
- {1751, {wxListItem, setFont, 1}},
- {1752, {wxListItem, setId, 1}},
- {1753, {wxListItem, setImage, 1}},
- {1754, {wxListItem, setMask, 1}},
- {1755, {wxListItem, setState, 1}},
- {1756, {wxListItem, setStateMask, 1}},
- {1757, {wxListItem, setText, 1}},
- {1758, {wxListItem, setTextColour, 1}},
- {1759, {wxListItem, setWidth, 1}},
- {1760, {wxListItemAttr, new_0, 0}},
- {1761, {wxListItemAttr, new_3, 3}},
- {1762, {wxListItemAttr, getBackgroundColour, 0}},
- {1763, {wxListItemAttr, getFont, 0}},
- {1764, {wxListItemAttr, getTextColour, 0}},
- {1765, {wxListItemAttr, hasBackgroundColour, 0}},
- {1766, {wxListItemAttr, hasFont, 0}},
- {1767, {wxListItemAttr, hasTextColour, 0}},
- {1768, {wxListItemAttr, setBackgroundColour, 1}},
- {1769, {wxListItemAttr, setFont, 1}},
- {1770, {wxListItemAttr, setTextColour, 1}},
- {1771, {wxListItemAttr, 'Destroy', undefined}},
- {1772, {wxImageList, new_0, 0}},
- {1773, {wxImageList, new_3, 3}},
- {1774, {wxImageList, add_1, 1}},
- {1775, {wxImageList, add_2_0, 2}},
- {1776, {wxImageList, add_2_1, 2}},
- {1777, {wxImageList, create, 3}},
- {1779, {wxImageList, draw, 5}},
- {1780, {wxImageList, getBitmap, 1}},
- {1781, {wxImageList, getIcon, 1}},
- {1782, {wxImageList, getImageCount, 0}},
- {1783, {wxImageList, getSize, 3}},
- {1784, {wxImageList, remove, 1}},
- {1785, {wxImageList, removeAll, 0}},
- {1786, {wxImageList, replace_2, 2}},
- {1787, {wxImageList, replace_3, 3}},
- {1788, {wxImageList, 'Destroy', undefined}},
- {1789, {wxTextAttr, new_0, 0}},
- {1790, {wxTextAttr, new_2, 2}},
- {1791, {wxTextAttr, getAlignment, 0}},
- {1792, {wxTextAttr, getBackgroundColour, 0}},
- {1793, {wxTextAttr, getFont, 0}},
- {1794, {wxTextAttr, getLeftIndent, 0}},
- {1795, {wxTextAttr, getLeftSubIndent, 0}},
- {1796, {wxTextAttr, getRightIndent, 0}},
- {1797, {wxTextAttr, getTabs, 0}},
- {1798, {wxTextAttr, getTextColour, 0}},
- {1799, {wxTextAttr, hasBackgroundColour, 0}},
- {1800, {wxTextAttr, hasFont, 0}},
- {1801, {wxTextAttr, hasTextColour, 0}},
- {1802, {wxTextAttr, getFlags, 0}},
- {1803, {wxTextAttr, isDefault, 0}},
- {1804, {wxTextAttr, setAlignment, 1}},
- {1805, {wxTextAttr, setBackgroundColour, 1}},
- {1806, {wxTextAttr, setFlags, 1}},
- {1807, {wxTextAttr, setFont, 2}},
- {1808, {wxTextAttr, setLeftIndent, 2}},
- {1809, {wxTextAttr, setRightIndent, 1}},
- {1810, {wxTextAttr, setTabs, 1}},
- {1811, {wxTextAttr, setTextColour, 1}},
- {1812, {wxTextAttr, 'Destroy', undefined}},
- {1814, {wxTextCtrl, new_3, 3}},
- {1815, {wxTextCtrl, new_0, 0}},
- {1817, {wxTextCtrl, destruct, 0}},
- {1818, {wxTextCtrl, appendText, 1}},
- {1819, {wxTextCtrl, canCopy, 0}},
- {1820, {wxTextCtrl, canCut, 0}},
- {1821, {wxTextCtrl, canPaste, 0}},
- {1822, {wxTextCtrl, canRedo, 0}},
- {1823, {wxTextCtrl, canUndo, 0}},
- {1824, {wxTextCtrl, clear, 0}},
- {1825, {wxTextCtrl, copy, 0}},
- {1826, {wxTextCtrl, create, 3}},
- {1827, {wxTextCtrl, cut, 0}},
- {1828, {wxTextCtrl, discardEdits, 0}},
- {1829, {wxTextCtrl, changeValue, 1}},
- {1830, {wxTextCtrl, emulateKeyPress, 1}},
- {1831, {wxTextCtrl, getDefaultStyle, 0}},
- {1832, {wxTextCtrl, getInsertionPoint, 0}},
- {1833, {wxTextCtrl, getLastPosition, 0}},
- {1834, {wxTextCtrl, getLineLength, 1}},
- {1835, {wxTextCtrl, getLineText, 1}},
- {1836, {wxTextCtrl, getNumberOfLines, 0}},
- {1837, {wxTextCtrl, getRange, 2}},
- {1838, {wxTextCtrl, getSelection, 2}},
- {1839, {wxTextCtrl, getStringSelection, 0}},
- {1840, {wxTextCtrl, getStyle, 2}},
- {1841, {wxTextCtrl, getValue, 0}},
- {1842, {wxTextCtrl, isEditable, 0}},
- {1843, {wxTextCtrl, isModified, 0}},
- {1844, {wxTextCtrl, isMultiLine, 0}},
- {1845, {wxTextCtrl, isSingleLine, 0}},
- {1846, {wxTextCtrl, loadFile, 2}},
- {1847, {wxTextCtrl, markDirty, 0}},
- {1848, {wxTextCtrl, paste, 0}},
- {1849, {wxTextCtrl, positionToXY, 3}},
- {1850, {wxTextCtrl, redo, 0}},
- {1851, {wxTextCtrl, remove, 2}},
- {1852, {wxTextCtrl, replace, 3}},
- {1853, {wxTextCtrl, saveFile, 1}},
- {1854, {wxTextCtrl, setDefaultStyle, 1}},
- {1855, {wxTextCtrl, setEditable, 1}},
- {1856, {wxTextCtrl, setInsertionPoint, 1}},
- {1857, {wxTextCtrl, setInsertionPointEnd, 0}},
- {1859, {wxTextCtrl, setMaxLength, 1}},
- {1860, {wxTextCtrl, setSelection, 2}},
- {1861, {wxTextCtrl, setStyle, 3}},
- {1862, {wxTextCtrl, setValue, 1}},
- {1863, {wxTextCtrl, showPosition, 1}},
- {1864, {wxTextCtrl, undo, 0}},
- {1865, {wxTextCtrl, writeText, 1}},
- {1866, {wxTextCtrl, xYToPosition, 2}},
- {1869, {wxNotebook, new_0, 0}},
- {1870, {wxNotebook, new_3, 3}},
- {1871, {wxNotebook, destruct, 0}},
- {1872, {wxNotebook, addPage, 3}},
- {1873, {wxNotebook, advanceSelection, 1}},
- {1874, {wxNotebook, assignImageList, 1}},
- {1875, {wxNotebook, create, 3}},
- {1876, {wxNotebook, deleteAllPages, 0}},
- {1877, {wxNotebook, deletePage, 1}},
- {1878, {wxNotebook, removePage, 1}},
- {1879, {wxNotebook, getCurrentPage, 0}},
- {1880, {wxNotebook, getImageList, 0}},
- {1882, {wxNotebook, getPage, 1}},
- {1883, {wxNotebook, getPageCount, 0}},
- {1884, {wxNotebook, getPageImage, 1}},
- {1885, {wxNotebook, getPageText, 1}},
- {1886, {wxNotebook, getRowCount, 0}},
- {1887, {wxNotebook, getSelection, 0}},
- {1888, {wxNotebook, getThemeBackgroundColour, 0}},
- {1890, {wxNotebook, hitTest, 2}},
- {1892, {wxNotebook, insertPage, 4}},
- {1893, {wxNotebook, setImageList, 1}},
- {1894, {wxNotebook, setPadding, 1}},
- {1895, {wxNotebook, setPageSize, 1}},
- {1896, {wxNotebook, setPageImage, 2}},
- {1897, {wxNotebook, setPageText, 2}},
- {1898, {wxNotebook, setSelection, 1}},
- {1899, {wxNotebook, changeSelection, 1}},
- {1900, {wxChoicebook, new_0, 0}},
- {1901, {wxChoicebook, new_3, 3}},
- {1902, {wxChoicebook, addPage, 3}},
- {1903, {wxChoicebook, advanceSelection, 1}},
- {1904, {wxChoicebook, assignImageList, 1}},
- {1905, {wxChoicebook, create, 3}},
- {1906, {wxChoicebook, deleteAllPages, 0}},
- {1907, {wxChoicebook, deletePage, 1}},
- {1908, {wxChoicebook, removePage, 1}},
- {1909, {wxChoicebook, getCurrentPage, 0}},
- {1910, {wxChoicebook, getImageList, 0}},
- {1912, {wxChoicebook, getPage, 1}},
- {1913, {wxChoicebook, getPageCount, 0}},
- {1914, {wxChoicebook, getPageImage, 1}},
- {1915, {wxChoicebook, getPageText, 1}},
- {1916, {wxChoicebook, getSelection, 0}},
- {1917, {wxChoicebook, hitTest, 2}},
- {1918, {wxChoicebook, insertPage, 4}},
- {1919, {wxChoicebook, setImageList, 1}},
- {1920, {wxChoicebook, setPageSize, 1}},
- {1921, {wxChoicebook, setPageImage, 2}},
- {1922, {wxChoicebook, setPageText, 2}},
- {1923, {wxChoicebook, setSelection, 1}},
- {1924, {wxChoicebook, changeSelection, 1}},
- {1925, {wxChoicebook, 'Destroy', undefined}},
- {1926, {wxToolbook, new_0, 0}},
- {1927, {wxToolbook, new_3, 3}},
- {1928, {wxToolbook, addPage, 3}},
- {1929, {wxToolbook, advanceSelection, 1}},
- {1930, {wxToolbook, assignImageList, 1}},
- {1931, {wxToolbook, create, 3}},
- {1932, {wxToolbook, deleteAllPages, 0}},
- {1933, {wxToolbook, deletePage, 1}},
- {1934, {wxToolbook, removePage, 1}},
- {1935, {wxToolbook, getCurrentPage, 0}},
- {1936, {wxToolbook, getImageList, 0}},
- {1938, {wxToolbook, getPage, 1}},
- {1939, {wxToolbook, getPageCount, 0}},
- {1940, {wxToolbook, getPageImage, 1}},
- {1941, {wxToolbook, getPageText, 1}},
- {1942, {wxToolbook, getSelection, 0}},
- {1944, {wxToolbook, hitTest, 2}},
- {1945, {wxToolbook, insertPage, 4}},
- {1946, {wxToolbook, setImageList, 1}},
- {1947, {wxToolbook, setPageSize, 1}},
- {1948, {wxToolbook, setPageImage, 2}},
- {1949, {wxToolbook, setPageText, 2}},
- {1950, {wxToolbook, setSelection, 1}},
- {1951, {wxToolbook, changeSelection, 1}},
- {1952, {wxToolbook, 'Destroy', undefined}},
- {1953, {wxListbook, new_0, 0}},
- {1954, {wxListbook, new_3, 3}},
- {1955, {wxListbook, addPage, 3}},
- {1956, {wxListbook, advanceSelection, 1}},
- {1957, {wxListbook, assignImageList, 1}},
- {1958, {wxListbook, create, 3}},
- {1959, {wxListbook, deleteAllPages, 0}},
- {1960, {wxListbook, deletePage, 1}},
- {1961, {wxListbook, removePage, 1}},
- {1962, {wxListbook, getCurrentPage, 0}},
- {1963, {wxListbook, getImageList, 0}},
- {1965, {wxListbook, getPage, 1}},
- {1966, {wxListbook, getPageCount, 0}},
- {1967, {wxListbook, getPageImage, 1}},
- {1968, {wxListbook, getPageText, 1}},
- {1969, {wxListbook, getSelection, 0}},
- {1971, {wxListbook, hitTest, 2}},
- {1972, {wxListbook, insertPage, 4}},
- {1973, {wxListbook, setImageList, 1}},
- {1974, {wxListbook, setPageSize, 1}},
- {1975, {wxListbook, setPageImage, 2}},
- {1976, {wxListbook, setPageText, 2}},
- {1977, {wxListbook, setSelection, 1}},
- {1978, {wxListbook, changeSelection, 1}},
- {1979, {wxListbook, 'Destroy', undefined}},
- {1980, {wxTreebook, new_0, 0}},
- {1981, {wxTreebook, new_3, 3}},
- {1982, {wxTreebook, addPage, 3}},
- {1983, {wxTreebook, advanceSelection, 1}},
- {1984, {wxTreebook, assignImageList, 1}},
- {1985, {wxTreebook, create, 3}},
- {1986, {wxTreebook, deleteAllPages, 0}},
- {1987, {wxTreebook, deletePage, 1}},
- {1988, {wxTreebook, removePage, 1}},
- {1989, {wxTreebook, getCurrentPage, 0}},
- {1990, {wxTreebook, getImageList, 0}},
- {1992, {wxTreebook, getPage, 1}},
- {1993, {wxTreebook, getPageCount, 0}},
- {1994, {wxTreebook, getPageImage, 1}},
- {1995, {wxTreebook, getPageText, 1}},
- {1996, {wxTreebook, getSelection, 0}},
- {1997, {wxTreebook, expandNode, 2}},
- {1998, {wxTreebook, isNodeExpanded, 1}},
- {2000, {wxTreebook, hitTest, 2}},
- {2001, {wxTreebook, insertPage, 4}},
- {2002, {wxTreebook, insertSubPage, 4}},
- {2003, {wxTreebook, setImageList, 1}},
- {2004, {wxTreebook, setPageSize, 1}},
- {2005, {wxTreebook, setPageImage, 2}},
- {2006, {wxTreebook, setPageText, 2}},
- {2007, {wxTreebook, setSelection, 1}},
- {2008, {wxTreebook, changeSelection, 1}},
- {2009, {wxTreebook, 'Destroy', undefined}},
- {2012, {wxTreeCtrl, new_2, 2}},
- {2013, {wxTreeCtrl, new_0, 0}},
- {2015, {wxTreeCtrl, destruct, 0}},
- {2016, {wxTreeCtrl, addRoot, 2}},
- {2017, {wxTreeCtrl, appendItem, 3}},
- {2018, {wxTreeCtrl, assignImageList, 1}},
- {2019, {wxTreeCtrl, assignStateImageList, 1}},
- {2020, {wxTreeCtrl, collapse, 1}},
- {2021, {wxTreeCtrl, collapseAndReset, 1}},
- {2022, {wxTreeCtrl, create, 2}},
- {2023, {wxTreeCtrl, delete, 1}},
- {2024, {wxTreeCtrl, deleteAllItems, 0}},
- {2025, {wxTreeCtrl, deleteChildren, 1}},
- {2026, {wxTreeCtrl, editLabel, 1}},
- {2027, {wxTreeCtrl, ensureVisible, 1}},
- {2028, {wxTreeCtrl, expand, 1}},
- {2029, {wxTreeCtrl, getBoundingRect, 3}},
- {2031, {wxTreeCtrl, getChildrenCount, 2}},
- {2032, {wxTreeCtrl, getCount, 0}},
- {2033, {wxTreeCtrl, getEditControl, 0}},
- {2034, {wxTreeCtrl, getFirstChild, 2}},
- {2035, {wxTreeCtrl, getNextChild, 2}},
- {2036, {wxTreeCtrl, getFirstVisibleItem, 0}},
- {2037, {wxTreeCtrl, getImageList, 0}},
- {2038, {wxTreeCtrl, getIndent, 0}},
- {2039, {wxTreeCtrl, getItemBackgroundColour, 1}},
- {2040, {wxTreeCtrl, getItemData, 1}},
- {2041, {wxTreeCtrl, getItemFont, 1}},
- {2042, {wxTreeCtrl, getItemImage_1, 1}},
- {2043, {wxTreeCtrl, getItemImage_2, 2}},
- {2044, {wxTreeCtrl, getItemText, 1}},
- {2045, {wxTreeCtrl, getItemTextColour, 1}},
- {2046, {wxTreeCtrl, getLastChild, 1}},
- {2047, {wxTreeCtrl, getNextSibling, 1}},
- {2048, {wxTreeCtrl, getNextVisible, 1}},
- {2049, {wxTreeCtrl, getItemParent, 1}},
- {2050, {wxTreeCtrl, getPrevSibling, 1}},
- {2051, {wxTreeCtrl, getPrevVisible, 1}},
- {2052, {wxTreeCtrl, getRootItem, 0}},
- {2053, {wxTreeCtrl, getSelection, 0}},
- {2054, {wxTreeCtrl, getSelections, 1}},
- {2055, {wxTreeCtrl, getStateImageList, 0}},
- {2056, {wxTreeCtrl, hitTest, 2}},
- {2058, {wxTreeCtrl, insertItem, 4}},
- {2059, {wxTreeCtrl, isBold, 1}},
- {2060, {wxTreeCtrl, isExpanded, 1}},
- {2061, {wxTreeCtrl, isSelected, 1}},
- {2062, {wxTreeCtrl, isVisible, 1}},
- {2063, {wxTreeCtrl, itemHasChildren, 1}},
- {2064, {wxTreeCtrl, isTreeItemIdOk, 1}},
- {2065, {wxTreeCtrl, prependItem, 3}},
- {2066, {wxTreeCtrl, scrollTo, 1}},
- {2067, {wxTreeCtrl, selectItem_1, 1}},
- {2068, {wxTreeCtrl, selectItem_2, 2}},
- {2069, {wxTreeCtrl, setIndent, 1}},
- {2070, {wxTreeCtrl, setImageList, 1}},
- {2071, {wxTreeCtrl, setItemBackgroundColour, 2}},
- {2072, {wxTreeCtrl, setItemBold, 2}},
- {2073, {wxTreeCtrl, setItemData, 2}},
- {2074, {wxTreeCtrl, setItemDropHighlight, 2}},
- {2075, {wxTreeCtrl, setItemFont, 2}},
- {2076, {wxTreeCtrl, setItemHasChildren, 2}},
- {2077, {wxTreeCtrl, setItemImage_2, 2}},
- {2078, {wxTreeCtrl, setItemImage_3, 3}},
- {2079, {wxTreeCtrl, setItemText, 2}},
- {2080, {wxTreeCtrl, setItemTextColour, 2}},
- {2081, {wxTreeCtrl, setStateImageList, 1}},
- {2082, {wxTreeCtrl, setWindowStyle, 1}},
- {2083, {wxTreeCtrl, sortChildren, 1}},
- {2084, {wxTreeCtrl, toggle, 1}},
- {2085, {wxTreeCtrl, toggleItemSelection, 1}},
- {2086, {wxTreeCtrl, unselect, 0}},
- {2087, {wxTreeCtrl, unselectAll, 0}},
- {2088, {wxTreeCtrl, unselectItem, 1}},
- {2089, {wxScrollBar, new_0, 0}},
- {2090, {wxScrollBar, new_3, 3}},
- {2091, {wxScrollBar, destruct, 0}},
- {2092, {wxScrollBar, create, 3}},
- {2093, {wxScrollBar, getRange, 0}},
- {2094, {wxScrollBar, getPageSize, 0}},
- {2095, {wxScrollBar, getThumbPosition, 0}},
- {2096, {wxScrollBar, getThumbSize, 0}},
- {2097, {wxScrollBar, setThumbPosition, 1}},
- {2098, {wxScrollBar, setScrollbar, 5}},
- {2100, {wxSpinButton, new_2, 2}},
- {2101, {wxSpinButton, new_0, 0}},
- {2102, {wxSpinButton, create, 2}},
- {2103, {wxSpinButton, getMax, 0}},
- {2104, {wxSpinButton, getMin, 0}},
- {2105, {wxSpinButton, getValue, 0}},
- {2106, {wxSpinButton, setRange, 2}},
- {2107, {wxSpinButton, setValue, 1}},
- {2108, {wxSpinButton, 'Destroy', undefined}},
- {2109, {wxSpinCtrl, new_0, 0}},
- {2110, {wxSpinCtrl, new_2, 2}},
- {2112, {wxSpinCtrl, create, 2}},
- {2115, {wxSpinCtrl, setValue_1_1, 1}},
- {2116, {wxSpinCtrl, setValue_1_0, 1}},
- {2118, {wxSpinCtrl, getValue, 0}},
- {2120, {wxSpinCtrl, setRange, 2}},
- {2121, {wxSpinCtrl, setSelection, 2}},
- {2123, {wxSpinCtrl, getMin, 0}},
- {2125, {wxSpinCtrl, getMax, 0}},
- {2126, {wxSpinCtrl, 'Destroy', undefined}},
- {2127, {wxStaticText, new_0, 0}},
- {2128, {wxStaticText, new_4, 4}},
- {2129, {wxStaticText, create, 4}},
- {2130, {wxStaticText, getLabel, 0}},
- {2131, {wxStaticText, setLabel, 1}},
- {2132, {wxStaticText, wrap, 1}},
- {2133, {wxStaticText, 'Destroy', undefined}},
- {2134, {wxStaticBitmap, new_0, 0}},
- {2135, {wxStaticBitmap, new_4, 4}},
- {2136, {wxStaticBitmap, create, 4}},
- {2137, {wxStaticBitmap, getBitmap, 0}},
- {2138, {wxStaticBitmap, setBitmap, 1}},
- {2139, {wxStaticBitmap, 'Destroy', undefined}},
- {2140, {wxRadioBox, new, 7}},
- {2142, {wxRadioBox, destruct, 0}},
- {2143, {wxRadioBox, create, 7}},
- {2144, {wxRadioBox, enable_2, 2}},
- {2145, {wxRadioBox, enable_1, 1}},
- {2146, {wxRadioBox, getSelection, 0}},
- {2147, {wxRadioBox, getString, 1}},
- {2148, {wxRadioBox, setSelection, 1}},
- {2149, {wxRadioBox, show_2, 2}},
- {2150, {wxRadioBox, show_1, 1}},
- {2151, {wxRadioBox, getColumnCount, 0}},
- {2152, {wxRadioBox, getItemHelpText, 1}},
- {2153, {wxRadioBox, getItemToolTip, 1}},
- {2155, {wxRadioBox, getItemFromPoint, 1}},
- {2156, {wxRadioBox, getRowCount, 0}},
- {2157, {wxRadioBox, isItemEnabled, 1}},
- {2158, {wxRadioBox, isItemShown, 1}},
- {2159, {wxRadioBox, setItemHelpText, 2}},
- {2160, {wxRadioBox, setItemToolTip, 2}},
- {2161, {wxRadioButton, new_0, 0}},
- {2162, {wxRadioButton, new_4, 4}},
- {2163, {wxRadioButton, create, 4}},
- {2164, {wxRadioButton, getValue, 0}},
- {2165, {wxRadioButton, setValue, 1}},
- {2166, {wxRadioButton, 'Destroy', undefined}},
- {2168, {wxSlider, new_6, 6}},
- {2169, {wxSlider, new_0, 0}},
- {2170, {wxSlider, create, 6}},
- {2171, {wxSlider, getLineSize, 0}},
- {2172, {wxSlider, getMax, 0}},
- {2173, {wxSlider, getMin, 0}},
- {2174, {wxSlider, getPageSize, 0}},
- {2175, {wxSlider, getThumbLength, 0}},
- {2176, {wxSlider, getValue, 0}},
- {2177, {wxSlider, setLineSize, 1}},
- {2178, {wxSlider, setPageSize, 1}},
- {2179, {wxSlider, setRange, 2}},
- {2180, {wxSlider, setThumbLength, 1}},
- {2181, {wxSlider, setValue, 1}},
- {2182, {wxSlider, 'Destroy', undefined}},
- {2184, {wxDialog, new_4, 4}},
- {2185, {wxDialog, new_0, 0}},
- {2187, {wxDialog, destruct, 0}},
- {2188, {wxDialog, create, 4}},
- {2189, {wxDialog, createButtonSizer, 1}},
- {2190, {wxDialog, createStdDialogButtonSizer, 1}},
- {2191, {wxDialog, endModal, 1}},
- {2192, {wxDialog, getAffirmativeId, 0}},
- {2193, {wxDialog, getReturnCode, 0}},
- {2194, {wxDialog, isModal, 0}},
- {2195, {wxDialog, setAffirmativeId, 1}},
- {2196, {wxDialog, setReturnCode, 1}},
- {2197, {wxDialog, show, 1}},
- {2198, {wxDialog, showModal, 0}},
- {2199, {wxColourDialog, new_0, 0}},
- {2200, {wxColourDialog, new_2, 2}},
- {2201, {wxColourDialog, destruct, 0}},
- {2202, {wxColourDialog, create, 2}},
- {2203, {wxColourDialog, getColourData, 0}},
- {2204, {wxColourData, new_0, 0}},
- {2205, {wxColourData, new_1, 1}},
- {2206, {wxColourData, destruct, 0}},
- {2207, {wxColourData, getChooseFull, 0}},
- {2208, {wxColourData, getColour, 0}},
- {2210, {wxColourData, getCustomColour, 1}},
- {2211, {wxColourData, setChooseFull, 1}},
- {2212, {wxColourData, setColour, 1}},
- {2213, {wxColourData, setCustomColour, 2}},
- {2214, {wxPalette, new_0, 0}},
- {2215, {wxPalette, new_4, 4}},
- {2217, {wxPalette, destruct, 0}},
- {2218, {wxPalette, create, 4}},
- {2219, {wxPalette, getColoursCount, 0}},
- {2220, {wxPalette, getPixel, 3}},
- {2221, {wxPalette, getRGB, 4}},
- {2222, {wxPalette, isOk, 0}},
- {2226, {wxDirDialog, new, 2}},
- {2227, {wxDirDialog, destruct, 0}},
- {2228, {wxDirDialog, getPath, 0}},
- {2229, {wxDirDialog, getMessage, 0}},
- {2230, {wxDirDialog, setMessage, 1}},
- {2231, {wxDirDialog, setPath, 1}},
- {2235, {wxFileDialog, new, 2}},
- {2236, {wxFileDialog, destruct, 0}},
- {2237, {wxFileDialog, getDirectory, 0}},
- {2238, {wxFileDialog, getFilename, 0}},
- {2239, {wxFileDialog, getFilenames, 1}},
- {2240, {wxFileDialog, getFilterIndex, 0}},
- {2241, {wxFileDialog, getMessage, 0}},
- {2242, {wxFileDialog, getPath, 0}},
- {2243, {wxFileDialog, getPaths, 1}},
- {2244, {wxFileDialog, getWildcard, 0}},
- {2245, {wxFileDialog, setDirectory, 1}},
- {2246, {wxFileDialog, setFilename, 1}},
- {2247, {wxFileDialog, setFilterIndex, 1}},
- {2248, {wxFileDialog, setMessage, 1}},
- {2249, {wxFileDialog, setPath, 1}},
- {2250, {wxFileDialog, setWildcard, 1}},
- {2251, {wxPickerBase, setInternalMargin, 1}},
- {2252, {wxPickerBase, getInternalMargin, 0}},
- {2253, {wxPickerBase, setTextCtrlProportion, 1}},
- {2254, {wxPickerBase, setPickerCtrlProportion, 1}},
- {2255, {wxPickerBase, getTextCtrlProportion, 0}},
- {2256, {wxPickerBase, getPickerCtrlProportion, 0}},
- {2257, {wxPickerBase, hasTextCtrl, 0}},
- {2258, {wxPickerBase, getTextCtrl, 0}},
- {2259, {wxPickerBase, isTextCtrlGrowable, 0}},
- {2260, {wxPickerBase, setPickerCtrlGrowable, 1}},
- {2261, {wxPickerBase, setTextCtrlGrowable, 1}},
- {2262, {wxPickerBase, isPickerCtrlGrowable, 0}},
- {2263, {wxFilePickerCtrl, new_0, 0}},
- {2264, {wxFilePickerCtrl, new_3, 3}},
- {2265, {wxFilePickerCtrl, create, 3}},
- {2266, {wxFilePickerCtrl, getPath, 0}},
- {2267, {wxFilePickerCtrl, setPath, 1}},
- {2268, {wxFilePickerCtrl, 'Destroy', undefined}},
- {2269, {wxDirPickerCtrl, new_0, 0}},
- {2270, {wxDirPickerCtrl, new_3, 3}},
- {2271, {wxDirPickerCtrl, create, 3}},
- {2272, {wxDirPickerCtrl, getPath, 0}},
- {2273, {wxDirPickerCtrl, setPath, 1}},
- {2274, {wxDirPickerCtrl, 'Destroy', undefined}},
- {2275, {wxColourPickerCtrl, new_0, 0}},
- {2276, {wxColourPickerCtrl, new_3, 3}},
- {2277, {wxColourPickerCtrl, create, 3}},
- {2278, {wxColourPickerCtrl, getColour, 0}},
- {2279, {wxColourPickerCtrl, setColour_1_1, 1}},
- {2280, {wxColourPickerCtrl, setColour_1_0, 1}},
- {2281, {wxColourPickerCtrl, 'Destroy', undefined}},
- {2282, {wxDatePickerCtrl, new_0, 0}},
- {2283, {wxDatePickerCtrl, new_3, 3}},
- {2284, {wxDatePickerCtrl, getRange, 2}},
- {2285, {wxDatePickerCtrl, getValue, 0}},
- {2286, {wxDatePickerCtrl, setRange, 2}},
- {2287, {wxDatePickerCtrl, setValue, 1}},
- {2288, {wxDatePickerCtrl, 'Destroy', undefined}},
- {2289, {wxFontPickerCtrl, new_0, 0}},
- {2290, {wxFontPickerCtrl, new_3, 3}},
- {2291, {wxFontPickerCtrl, create, 3}},
- {2292, {wxFontPickerCtrl, getSelectedFont, 0}},
- {2293, {wxFontPickerCtrl, setSelectedFont, 1}},
- {2294, {wxFontPickerCtrl, getMaxPointSize, 0}},
- {2295, {wxFontPickerCtrl, setMaxPointSize, 1}},
- {2296, {wxFontPickerCtrl, 'Destroy', undefined}},
- {2299, {wxFindReplaceDialog, new_0, 0}},
- {2300, {wxFindReplaceDialog, new_4, 4}},
- {2301, {wxFindReplaceDialog, destruct, 0}},
- {2302, {wxFindReplaceDialog, create, 4}},
- {2303, {wxFindReplaceDialog, getData, 0}},
- {2304, {wxFindReplaceData, new_0, 0}},
- {2305, {wxFindReplaceData, new_1, 1}},
- {2306, {wxFindReplaceData, getFindString, 0}},
- {2307, {wxFindReplaceData, getReplaceString, 0}},
- {2308, {wxFindReplaceData, getFlags, 0}},
- {2309, {wxFindReplaceData, setFlags, 1}},
- {2310, {wxFindReplaceData, setFindString, 1}},
- {2311, {wxFindReplaceData, setReplaceString, 1}},
- {2312, {wxFindReplaceData, 'Destroy', undefined}},
- {2313, {wxMultiChoiceDialog, new_0, 0}},
- {2315, {wxMultiChoiceDialog, new_5, 5}},
- {2316, {wxMultiChoiceDialog, getSelections, 0}},
- {2317, {wxMultiChoiceDialog, setSelections, 1}},
- {2318, {wxMultiChoiceDialog, 'Destroy', undefined}},
- {2319, {wxSingleChoiceDialog, new_0, 0}},
- {2321, {wxSingleChoiceDialog, new_5, 5}},
- {2322, {wxSingleChoiceDialog, getSelection, 0}},
- {2323, {wxSingleChoiceDialog, getStringSelection, 0}},
- {2324, {wxSingleChoiceDialog, setSelection, 1}},
- {2325, {wxSingleChoiceDialog, 'Destroy', undefined}},
- {2326, {wxTextEntryDialog, new, 3}},
- {2327, {wxTextEntryDialog, getValue, 0}},
- {2328, {wxTextEntryDialog, setValue, 1}},
- {2329, {wxTextEntryDialog, 'Destroy', undefined}},
- {2330, {wxPasswordEntryDialog, new, 3}},
- {2331, {wxPasswordEntryDialog, 'Destroy', undefined}},
- {2332, {wxFontData, new_0, 0}},
- {2333, {wxFontData, new_1, 1}},
- {2334, {wxFontData, destruct, 0}},
- {2335, {wxFontData, enableEffects, 1}},
- {2336, {wxFontData, getAllowSymbols, 0}},
- {2337, {wxFontData, getColour, 0}},
- {2338, {wxFontData, getChosenFont, 0}},
- {2339, {wxFontData, getEnableEffects, 0}},
- {2340, {wxFontData, getInitialFont, 0}},
- {2341, {wxFontData, getShowHelp, 0}},
- {2342, {wxFontData, setAllowSymbols, 1}},
- {2343, {wxFontData, setChosenFont, 1}},
- {2344, {wxFontData, setColour, 1}},
- {2345, {wxFontData, setInitialFont, 1}},
- {2346, {wxFontData, setRange, 2}},
- {2347, {wxFontData, setShowHelp, 1}},
- {2351, {wxFontDialog, new_0, 0}},
- {2353, {wxFontDialog, new_2, 2}},
- {2355, {wxFontDialog, create, 2}},
- {2356, {wxFontDialog, getFontData, 0}},
- {2358, {wxFontDialog, 'Destroy', undefined}},
- {2359, {wxProgressDialog, new, 3}},
- {2360, {wxProgressDialog, destruct, 0}},
- {2361, {wxProgressDialog, resume, 0}},
- {2362, {wxProgressDialog, update_2, 2}},
- {2363, {wxProgressDialog, update_0, 0}},
- {2364, {wxMessageDialog, new, 3}},
- {2365, {wxMessageDialog, destruct, 0}},
- {2366, {wxPageSetupDialog, new, 2}},
- {2367, {wxPageSetupDialog, destruct, 0}},
- {2368, {wxPageSetupDialog, getPageSetupData, 0}},
- {2369, {wxPageSetupDialog, showModal, 0}},
- {2370, {wxPageSetupDialogData, new_0, 0}},
- {2371, {wxPageSetupDialogData, new_1_0, 1}},
- {2372, {wxPageSetupDialogData, new_1_1, 1}},
- {2373, {wxPageSetupDialogData, destruct, 0}},
- {2374, {wxPageSetupDialogData, enableHelp, 1}},
- {2375, {wxPageSetupDialogData, enableMargins, 1}},
- {2376, {wxPageSetupDialogData, enableOrientation, 1}},
- {2377, {wxPageSetupDialogData, enablePaper, 1}},
- {2378, {wxPageSetupDialogData, enablePrinter, 1}},
- {2379, {wxPageSetupDialogData, getDefaultMinMargins, 0}},
- {2380, {wxPageSetupDialogData, getEnableMargins, 0}},
- {2381, {wxPageSetupDialogData, getEnableOrientation, 0}},
- {2382, {wxPageSetupDialogData, getEnablePaper, 0}},
- {2383, {wxPageSetupDialogData, getEnablePrinter, 0}},
- {2384, {wxPageSetupDialogData, getEnableHelp, 0}},
- {2385, {wxPageSetupDialogData, getDefaultInfo, 0}},
- {2386, {wxPageSetupDialogData, getMarginTopLeft, 0}},
- {2387, {wxPageSetupDialogData, getMarginBottomRight, 0}},
- {2388, {wxPageSetupDialogData, getMinMarginTopLeft, 0}},
- {2389, {wxPageSetupDialogData, getMinMarginBottomRight, 0}},
- {2390, {wxPageSetupDialogData, getPaperId, 0}},
- {2391, {wxPageSetupDialogData, getPaperSize, 0}},
- {2393, {wxPageSetupDialogData, getPrintData, 0}},
- {2394, {wxPageSetupDialogData, isOk, 0}},
- {2395, {wxPageSetupDialogData, setDefaultInfo, 1}},
- {2396, {wxPageSetupDialogData, setDefaultMinMargins, 1}},
- {2397, {wxPageSetupDialogData, setMarginTopLeft, 1}},
- {2398, {wxPageSetupDialogData, setMarginBottomRight, 1}},
- {2399, {wxPageSetupDialogData, setMinMarginTopLeft, 1}},
- {2400, {wxPageSetupDialogData, setMinMarginBottomRight, 1}},
- {2401, {wxPageSetupDialogData, setPaperId, 1}},
- {2402, {wxPageSetupDialogData, setPaperSize_1_1, 1}},
- {2403, {wxPageSetupDialogData, setPaperSize_1_0, 1}},
- {2404, {wxPageSetupDialogData, setPrintData, 1}},
- {2405, {wxPrintDialog, new_2_0, 2}},
- {2406, {wxPrintDialog, new_2_1, 2}},
- {2407, {wxPrintDialog, destruct, 0}},
- {2408, {wxPrintDialog, getPrintDialogData, 0}},
- {2409, {wxPrintDialog, getPrintDC, 0}},
- {2410, {wxPrintDialogData, new_0, 0}},
- {2411, {wxPrintDialogData, new_1_1, 1}},
- {2412, {wxPrintDialogData, new_1_0, 1}},
- {2413, {wxPrintDialogData, destruct, 0}},
- {2414, {wxPrintDialogData, enableHelp, 1}},
- {2415, {wxPrintDialogData, enablePageNumbers, 1}},
- {2416, {wxPrintDialogData, enablePrintToFile, 1}},
- {2417, {wxPrintDialogData, enableSelection, 1}},
- {2418, {wxPrintDialogData, getAllPages, 0}},
- {2419, {wxPrintDialogData, getCollate, 0}},
- {2420, {wxPrintDialogData, getFromPage, 0}},
- {2421, {wxPrintDialogData, getMaxPage, 0}},
- {2422, {wxPrintDialogData, getMinPage, 0}},
- {2423, {wxPrintDialogData, getNoCopies, 0}},
- {2424, {wxPrintDialogData, getPrintData, 0}},
- {2425, {wxPrintDialogData, getPrintToFile, 0}},
- {2426, {wxPrintDialogData, getSelection, 0}},
- {2427, {wxPrintDialogData, getToPage, 0}},
- {2428, {wxPrintDialogData, isOk, 0}},
- {2429, {wxPrintDialogData, setCollate, 1}},
- {2430, {wxPrintDialogData, setFromPage, 1}},
- {2431, {wxPrintDialogData, setMaxPage, 1}},
- {2432, {wxPrintDialogData, setMinPage, 1}},
- {2433, {wxPrintDialogData, setNoCopies, 1}},
- {2434, {wxPrintDialogData, setPrintData, 1}},
- {2435, {wxPrintDialogData, setPrintToFile, 1}},
- {2436, {wxPrintDialogData, setSelection, 1}},
- {2437, {wxPrintDialogData, setToPage, 1}},
- {2438, {wxPrintData, new_0, 0}},
- {2439, {wxPrintData, new_1, 1}},
- {2440, {wxPrintData, destruct, 0}},
- {2441, {wxPrintData, getCollate, 0}},
- {2442, {wxPrintData, getBin, 0}},
- {2443, {wxPrintData, getColour, 0}},
- {2444, {wxPrintData, getDuplex, 0}},
- {2445, {wxPrintData, getNoCopies, 0}},
- {2446, {wxPrintData, getOrientation, 0}},
- {2447, {wxPrintData, getPaperId, 0}},
- {2448, {wxPrintData, getPrinterName, 0}},
- {2449, {wxPrintData, getQuality, 0}},
- {2450, {wxPrintData, isOk, 0}},
- {2451, {wxPrintData, setBin, 1}},
- {2452, {wxPrintData, setCollate, 1}},
- {2453, {wxPrintData, setColour, 1}},
- {2454, {wxPrintData, setDuplex, 1}},
- {2455, {wxPrintData, setNoCopies, 1}},
- {2456, {wxPrintData, setOrientation, 1}},
- {2457, {wxPrintData, setPaperId, 1}},
- {2458, {wxPrintData, setPrinterName, 1}},
- {2459, {wxPrintData, setQuality, 1}},
- {2462, {wxPrintPreview, new_2, 2}},
- {2463, {wxPrintPreview, new_3, 3}},
- {2465, {wxPrintPreview, destruct, 0}},
- {2466, {wxPrintPreview, getCanvas, 0}},
- {2467, {wxPrintPreview, getCurrentPage, 0}},
- {2468, {wxPrintPreview, getFrame, 0}},
- {2469, {wxPrintPreview, getMaxPage, 0}},
- {2470, {wxPrintPreview, getMinPage, 0}},
- {2471, {wxPrintPreview, getPrintout, 0}},
- {2472, {wxPrintPreview, getPrintoutForPrinting, 0}},
- {2473, {wxPrintPreview, isOk, 0}},
- {2474, {wxPrintPreview, paintPage, 2}},
- {2475, {wxPrintPreview, print, 1}},
- {2476, {wxPrintPreview, renderPage, 1}},
- {2477, {wxPrintPreview, setCanvas, 1}},
- {2478, {wxPrintPreview, setCurrentPage, 1}},
- {2479, {wxPrintPreview, setFrame, 1}},
- {2480, {wxPrintPreview, setPrintout, 1}},
- {2481, {wxPrintPreview, setZoom, 1}},
- {2482, {wxPreviewFrame, new, 3}},
- {2483, {wxPreviewFrame, destruct, 0}},
- {2484, {wxPreviewFrame, createControlBar, 0}},
- {2485, {wxPreviewFrame, createCanvas, 0}},
- {2486, {wxPreviewFrame, initialize, 0}},
- {2487, {wxPreviewFrame, onCloseWindow, 1}},
- {2488, {wxPreviewControlBar, new, 4}},
- {2489, {wxPreviewControlBar, destruct, 0}},
- {2490, {wxPreviewControlBar, createButtons, 0}},
- {2491, {wxPreviewControlBar, getPrintPreview, 0}},
- {2492, {wxPreviewControlBar, getZoomControl, 0}},
- {2493, {wxPreviewControlBar, setZoomControl, 1}},
- {2495, {wxPrinter, new, 1}},
- {2496, {wxPrinter, createAbortWindow, 2}},
- {2497, {wxPrinter, getAbort, 0}},
- {2498, {wxPrinter, getLastError, 0}},
- {2499, {wxPrinter, getPrintDialogData, 0}},
- {2500, {wxPrinter, print, 3}},
- {2501, {wxPrinter, printDialog, 1}},
- {2502, {wxPrinter, reportError, 3}},
- {2503, {wxPrinter, setup, 1}},
- {2504, {wxPrinter, 'Destroy', undefined}},
- {2505, {wxXmlResource, new_1, 1}},
- {2506, {wxXmlResource, new_2, 2}},
- {2507, {wxXmlResource, destruct, 0}},
- {2508, {wxXmlResource, attachUnknownControl, 3}},
- {2509, {wxXmlResource, clearHandlers, 0}},
- {2510, {wxXmlResource, compareVersion, 4}},
- {2511, {wxXmlResource, get, 0}},
- {2512, {wxXmlResource, getFlags, 0}},
- {2513, {wxXmlResource, getVersion, 0}},
- {2514, {wxXmlResource, getXRCID, 2}},
- {2515, {wxXmlResource, initAllHandlers, 0}},
- {2516, {wxXmlResource, load, 1}},
- {2517, {wxXmlResource, loadBitmap, 1}},
- {2518, {wxXmlResource, loadDialog_2, 2}},
- {2519, {wxXmlResource, loadDialog_3, 3}},
- {2520, {wxXmlResource, loadFrame_2, 2}},
- {2521, {wxXmlResource, loadFrame_3, 3}},
- {2522, {wxXmlResource, loadIcon, 1}},
- {2523, {wxXmlResource, loadMenu, 1}},
- {2524, {wxXmlResource, loadMenuBar_2, 2}},
- {2525, {wxXmlResource, loadMenuBar_1, 1}},
- {2526, {wxXmlResource, loadPanel_2, 2}},
- {2527, {wxXmlResource, loadPanel_3, 3}},
- {2528, {wxXmlResource, loadToolBar, 2}},
- {2529, {wxXmlResource, set, 1}},
- {2530, {wxXmlResource, setFlags, 1}},
- {2531, {wxXmlResource, unload, 1}},
- {2532, {wxXmlResource, xrcctrl, 3}},
- {2533, {wxHtmlEasyPrinting, new, 1}},
- {2534, {wxHtmlEasyPrinting, destruct, 0}},
- {2535, {wxHtmlEasyPrinting, getPrintData, 0}},
- {2536, {wxHtmlEasyPrinting, getPageSetupData, 0}},
- {2537, {wxHtmlEasyPrinting, previewFile, 1}},
- {2538, {wxHtmlEasyPrinting, previewText, 2}},
- {2539, {wxHtmlEasyPrinting, printFile, 1}},
- {2540, {wxHtmlEasyPrinting, printText, 2}},
- {2541, {wxHtmlEasyPrinting, pageSetup, 0}},
- {2542, {wxHtmlEasyPrinting, setFonts, 3}},
- {2543, {wxHtmlEasyPrinting, setHeader, 2}},
- {2544, {wxHtmlEasyPrinting, setFooter, 2}},
- {2546, {wxGLCanvas, new_2, 2}},
- {2547, {wxGLCanvas, new_3_1, 3}},
- {2548, {wxGLCanvas, new_3_0, 3}},
- {2549, {wxGLCanvas, getContext, 0}},
- {2551, {wxGLCanvas, setCurrent, 0}},
- {2552, {wxGLCanvas, swapBuffers, 0}},
- {2553, {wxGLCanvas, 'Destroy', undefined}},
- {2554, {wxAuiManager, new, 1}},
- {2555, {wxAuiManager, destruct, 0}},
- {2556, {wxAuiManager, addPane_2_1, 2}},
- {2557, {wxAuiManager, addPane_3, 3}},
- {2558, {wxAuiManager, addPane_2_0, 2}},
- {2559, {wxAuiManager, detachPane, 1}},
- {2560, {wxAuiManager, getAllPanes, 0}},
- {2561, {wxAuiManager, getArtProvider, 0}},
- {2562, {wxAuiManager, getDockSizeConstraint, 2}},
- {2563, {wxAuiManager, getFlags, 0}},
- {2564, {wxAuiManager, getManagedWindow, 0}},
- {2565, {wxAuiManager, getManager, 1}},
- {2566, {wxAuiManager, getPane_1_1, 1}},
- {2567, {wxAuiManager, getPane_1_0, 1}},
- {2568, {wxAuiManager, hideHint, 0}},
- {2569, {wxAuiManager, insertPane, 3}},
- {2570, {wxAuiManager, loadPaneInfo, 2}},
- {2571, {wxAuiManager, loadPerspective, 2}},
- {2572, {wxAuiManager, savePaneInfo, 1}},
- {2573, {wxAuiManager, savePerspective, 0}},
- {2574, {wxAuiManager, setArtProvider, 1}},
- {2575, {wxAuiManager, setDockSizeConstraint, 2}},
- {2576, {wxAuiManager, setFlags, 1}},
- {2577, {wxAuiManager, setManagedWindow, 1}},
- {2578, {wxAuiManager, showHint, 1}},
- {2579, {wxAuiManager, unInit, 0}},
- {2580, {wxAuiManager, update, 0}},
- {2581, {wxAuiPaneInfo, new_0, 0}},
- {2582, {wxAuiPaneInfo, new_1, 1}},
- {2583, {wxAuiPaneInfo, destruct, 0}},
- {2584, {wxAuiPaneInfo, bestSize_1, 1}},
- {2585, {wxAuiPaneInfo, bestSize_2, 2}},
- {2586, {wxAuiPaneInfo, bottom, 0}},
- {2587, {wxAuiPaneInfo, bottomDockable, 1}},
- {2588, {wxAuiPaneInfo, caption, 1}},
- {2589, {wxAuiPaneInfo, captionVisible, 1}},
- {2590, {wxAuiPaneInfo, centre, 0}},
- {2591, {wxAuiPaneInfo, centrePane, 0}},
- {2592, {wxAuiPaneInfo, closeButton, 1}},
- {2593, {wxAuiPaneInfo, defaultPane, 0}},
- {2594, {wxAuiPaneInfo, destroyOnClose, 1}},
- {2595, {wxAuiPaneInfo, direction, 1}},
- {2596, {wxAuiPaneInfo, dock, 0}},
- {2597, {wxAuiPaneInfo, dockable, 1}},
- {2598, {wxAuiPaneInfo, fixed, 0}},
- {2599, {wxAuiPaneInfo, float, 0}},
- {2600, {wxAuiPaneInfo, floatable, 1}},
- {2601, {wxAuiPaneInfo, floatingPosition_1, 1}},
- {2602, {wxAuiPaneInfo, floatingPosition_2, 2}},
- {2603, {wxAuiPaneInfo, floatingSize_1, 1}},
- {2604, {wxAuiPaneInfo, floatingSize_2, 2}},
- {2605, {wxAuiPaneInfo, gripper, 1}},
- {2606, {wxAuiPaneInfo, gripperTop, 1}},
- {2607, {wxAuiPaneInfo, hasBorder, 0}},
- {2608, {wxAuiPaneInfo, hasCaption, 0}},
- {2609, {wxAuiPaneInfo, hasCloseButton, 0}},
- {2610, {wxAuiPaneInfo, hasFlag, 1}},
- {2611, {wxAuiPaneInfo, hasGripper, 0}},
- {2612, {wxAuiPaneInfo, hasGripperTop, 0}},
- {2613, {wxAuiPaneInfo, hasMaximizeButton, 0}},
- {2614, {wxAuiPaneInfo, hasMinimizeButton, 0}},
- {2615, {wxAuiPaneInfo, hasPinButton, 0}},
- {2616, {wxAuiPaneInfo, hide, 0}},
- {2617, {wxAuiPaneInfo, isBottomDockable, 0}},
- {2618, {wxAuiPaneInfo, isDocked, 0}},
- {2619, {wxAuiPaneInfo, isFixed, 0}},
- {2620, {wxAuiPaneInfo, isFloatable, 0}},
- {2621, {wxAuiPaneInfo, isFloating, 0}},
- {2622, {wxAuiPaneInfo, isLeftDockable, 0}},
- {2623, {wxAuiPaneInfo, isMovable, 0}},
- {2624, {wxAuiPaneInfo, isOk, 0}},
- {2625, {wxAuiPaneInfo, isResizable, 0}},
- {2626, {wxAuiPaneInfo, isRightDockable, 0}},
- {2627, {wxAuiPaneInfo, isShown, 0}},
- {2628, {wxAuiPaneInfo, isToolbar, 0}},
- {2629, {wxAuiPaneInfo, isTopDockable, 0}},
- {2630, {wxAuiPaneInfo, layer, 1}},
- {2631, {wxAuiPaneInfo, left, 0}},
- {2632, {wxAuiPaneInfo, leftDockable, 1}},
- {2633, {wxAuiPaneInfo, maxSize_1, 1}},
- {2634, {wxAuiPaneInfo, maxSize_2, 2}},
- {2635, {wxAuiPaneInfo, maximizeButton, 1}},
- {2636, {wxAuiPaneInfo, minSize_1, 1}},
- {2637, {wxAuiPaneInfo, minSize_2, 2}},
- {2638, {wxAuiPaneInfo, minimizeButton, 1}},
- {2639, {wxAuiPaneInfo, movable, 1}},
- {2640, {wxAuiPaneInfo, name, 1}},
- {2641, {wxAuiPaneInfo, paneBorder, 1}},
- {2642, {wxAuiPaneInfo, pinButton, 1}},
- {2643, {wxAuiPaneInfo, position, 1}},
- {2644, {wxAuiPaneInfo, resizable, 1}},
- {2645, {wxAuiPaneInfo, right, 0}},
- {2646, {wxAuiPaneInfo, rightDockable, 1}},
- {2647, {wxAuiPaneInfo, row, 1}},
- {2648, {wxAuiPaneInfo, safeSet, 1}},
- {2649, {wxAuiPaneInfo, setFlag, 2}},
- {2650, {wxAuiPaneInfo, show, 1}},
- {2651, {wxAuiPaneInfo, toolbarPane, 0}},
- {2652, {wxAuiPaneInfo, top, 0}},
- {2653, {wxAuiPaneInfo, topDockable, 1}},
- {2654, {wxAuiPaneInfo, window, 1}},
- {2655, {wxAuiPaneInfo, getWindow, 0}},
- {2656, {wxAuiPaneInfo, getFrame, 0}},
- {2657, {wxAuiPaneInfo, getDirection, 0}},
- {2658, {wxAuiPaneInfo, getLayer, 0}},
- {2659, {wxAuiPaneInfo, getRow, 0}},
- {2660, {wxAuiPaneInfo, getPosition, 0}},
- {2661, {wxAuiPaneInfo, getFloatingPosition, 0}},
- {2662, {wxAuiPaneInfo, getFloatingSize, 0}},
- {2663, {wxAuiNotebook, new_0, 0}},
- {2664, {wxAuiNotebook, new_2, 2}},
- {2665, {wxAuiNotebook, addPage, 3}},
- {2666, {wxAuiNotebook, create, 2}},
- {2667, {wxAuiNotebook, deletePage, 1}},
- {2668, {wxAuiNotebook, getArtProvider, 0}},
- {2669, {wxAuiNotebook, getPage, 1}},
- {2670, {wxAuiNotebook, getPageBitmap, 1}},
- {2671, {wxAuiNotebook, getPageCount, 0}},
- {2672, {wxAuiNotebook, getPageIndex, 1}},
- {2673, {wxAuiNotebook, getPageText, 1}},
- {2674, {wxAuiNotebook, getSelection, 0}},
- {2675, {wxAuiNotebook, insertPage, 4}},
- {2676, {wxAuiNotebook, removePage, 1}},
- {2677, {wxAuiNotebook, setArtProvider, 1}},
- {2678, {wxAuiNotebook, setFont, 1}},
- {2679, {wxAuiNotebook, setPageBitmap, 2}},
- {2680, {wxAuiNotebook, setPageText, 2}},
- {2681, {wxAuiNotebook, setSelection, 1}},
- {2682, {wxAuiNotebook, setTabCtrlHeight, 1}},
- {2683, {wxAuiNotebook, setUniformBitmapSize, 1}},
- {2684, {wxAuiNotebook, 'Destroy', undefined}},
- {2685, {wxAuiTabArt, setFlags, 1}},
- {2686, {wxAuiTabArt, setMeasuringFont, 1}},
- {2687, {wxAuiTabArt, setNormalFont, 1}},
- {2688, {wxAuiTabArt, setSelectedFont, 1}},
- {2689, {wxAuiTabArt, setColour, 1}},
- {2690, {wxAuiTabArt, setActiveColour, 1}},
- {2691, {wxAuiDockArt, getColour, 1}},
- {2692, {wxAuiDockArt, getFont, 1}},
- {2693, {wxAuiDockArt, getMetric, 1}},
- {2694, {wxAuiDockArt, setColour, 2}},
- {2695, {wxAuiDockArt, setFont, 2}},
- {2696, {wxAuiDockArt, setMetric, 2}},
- {2697, {wxAuiSimpleTabArt, new, 0}},
- {2698, {wxAuiSimpleTabArt, 'Destroy', undefined}},
- {2699, {wxMDIParentFrame, new_0, 0}},
- {2700, {wxMDIParentFrame, new_4, 4}},
- {2701, {wxMDIParentFrame, destruct, 0}},
- {2702, {wxMDIParentFrame, activateNext, 0}},
- {2703, {wxMDIParentFrame, activatePrevious, 0}},
- {2704, {wxMDIParentFrame, arrangeIcons, 0}},
- {2705, {wxMDIParentFrame, cascade, 0}},
- {2706, {wxMDIParentFrame, create, 4}},
- {2707, {wxMDIParentFrame, getActiveChild, 0}},
- {2708, {wxMDIParentFrame, getClientWindow, 0}},
- {2709, {wxMDIParentFrame, tile, 1}},
- {2710, {wxMDIChildFrame, new_0, 0}},
- {2711, {wxMDIChildFrame, new_4, 4}},
- {2712, {wxMDIChildFrame, destruct, 0}},
- {2713, {wxMDIChildFrame, activate, 0}},
- {2714, {wxMDIChildFrame, create, 4}},
- {2715, {wxMDIChildFrame, maximize, 1}},
- {2716, {wxMDIChildFrame, restore, 0}},
- {2717, {wxMDIClientWindow, new_0, 0}},
- {2718, {wxMDIClientWindow, new_2, 2}},
- {2719, {wxMDIClientWindow, destruct, 0}},
- {2720, {wxMDIClientWindow, createClient, 2}},
- {2721, {wxLayoutAlgorithm, new, 0}},
- {2722, {wxLayoutAlgorithm, layoutFrame, 2}},
- {2723, {wxLayoutAlgorithm, layoutMDIFrame, 2}},
- {2724, {wxLayoutAlgorithm, layoutWindow, 2}},
- {2725, {wxLayoutAlgorithm, 'Destroy', undefined}},
- {2726, {wxEvent, getId, 0}},
- {2727, {wxEvent, getSkipped, 0}},
- {2728, {wxEvent, getTimestamp, 0}},
- {2729, {wxEvent, isCommandEvent, 0}},
- {2730, {wxEvent, resumePropagation, 1}},
- {2731, {wxEvent, shouldPropagate, 0}},
- {2732, {wxEvent, skip, 1}},
- {2733, {wxEvent, stopPropagation, 0}},
- {2734, {wxCommandEvent, getClientData, 0}},
- {2735, {wxCommandEvent, getExtraLong, 0}},
- {2736, {wxCommandEvent, getInt, 0}},
- {2737, {wxCommandEvent, getSelection, 0}},
- {2738, {wxCommandEvent, getString, 0}},
- {2739, {wxCommandEvent, isChecked, 0}},
- {2740, {wxCommandEvent, isSelection, 0}},
- {2741, {wxCommandEvent, setInt, 1}},
- {2742, {wxCommandEvent, setString, 1}},
- {2743, {wxScrollEvent, getOrientation, 0}},
- {2744, {wxScrollEvent, getPosition, 0}},
- {2745, {wxScrollWinEvent, getOrientation, 0}},
- {2746, {wxScrollWinEvent, getPosition, 0}},
- {2747, {wxMouseEvent, altDown, 0}},
- {2748, {wxMouseEvent, button, 1}},
- {2749, {wxMouseEvent, buttonDClick, 1}},
- {2750, {wxMouseEvent, buttonDown, 1}},
- {2751, {wxMouseEvent, buttonUp, 1}},
- {2752, {wxMouseEvent, cmdDown, 0}},
- {2753, {wxMouseEvent, controlDown, 0}},
- {2754, {wxMouseEvent, dragging, 0}},
- {2755, {wxMouseEvent, entering, 0}},
- {2756, {wxMouseEvent, getButton, 0}},
- {2759, {wxMouseEvent, getPosition, 0}},
- {2760, {wxMouseEvent, getLogicalPosition, 1}},
- {2761, {wxMouseEvent, getLinesPerAction, 0}},
- {2762, {wxMouseEvent, getWheelRotation, 0}},
- {2763, {wxMouseEvent, getWheelDelta, 0}},
- {2764, {wxMouseEvent, getX, 0}},
- {2765, {wxMouseEvent, getY, 0}},
- {2766, {wxMouseEvent, isButton, 0}},
- {2767, {wxMouseEvent, isPageScroll, 0}},
- {2768, {wxMouseEvent, leaving, 0}},
- {2769, {wxMouseEvent, leftDClick, 0}},
- {2770, {wxMouseEvent, leftDown, 0}},
- {2771, {wxMouseEvent, leftIsDown, 0}},
- {2772, {wxMouseEvent, leftUp, 0}},
- {2773, {wxMouseEvent, metaDown, 0}},
- {2774, {wxMouseEvent, middleDClick, 0}},
- {2775, {wxMouseEvent, middleDown, 0}},
- {2776, {wxMouseEvent, middleIsDown, 0}},
- {2777, {wxMouseEvent, middleUp, 0}},
- {2778, {wxMouseEvent, moving, 0}},
- {2779, {wxMouseEvent, rightDClick, 0}},
- {2780, {wxMouseEvent, rightDown, 0}},
- {2781, {wxMouseEvent, rightIsDown, 0}},
- {2782, {wxMouseEvent, rightUp, 0}},
- {2783, {wxMouseEvent, shiftDown, 0}},
- {2784, {wxSetCursorEvent, getCursor, 0}},
- {2785, {wxSetCursorEvent, getX, 0}},
- {2786, {wxSetCursorEvent, getY, 0}},
- {2787, {wxSetCursorEvent, hasCursor, 0}},
- {2788, {wxSetCursorEvent, setCursor, 1}},
- {2789, {wxKeyEvent, altDown, 0}},
- {2790, {wxKeyEvent, cmdDown, 0}},
- {2791, {wxKeyEvent, controlDown, 0}},
- {2792, {wxKeyEvent, getKeyCode, 0}},
- {2793, {wxKeyEvent, getModifiers, 0}},
- {2796, {wxKeyEvent, getPosition, 0}},
- {2797, {wxKeyEvent, getRawKeyCode, 0}},
- {2798, {wxKeyEvent, getRawKeyFlags, 0}},
- {2799, {wxKeyEvent, getUnicodeKey, 0}},
- {2800, {wxKeyEvent, getX, 0}},
- {2801, {wxKeyEvent, getY, 0}},
- {2802, {wxKeyEvent, hasModifiers, 0}},
- {2803, {wxKeyEvent, metaDown, 0}},
- {2804, {wxKeyEvent, shiftDown, 0}},
- {2805, {wxSizeEvent, getSize, 0}},
- {2806, {wxMoveEvent, getPosition, 0}},
- {2807, {wxEraseEvent, getDC, 0}},
- {2808, {wxFocusEvent, getWindow, 0}},
- {2809, {wxChildFocusEvent, getWindow, 0}},
- {2810, {wxMenuEvent, getMenu, 0}},
- {2811, {wxMenuEvent, getMenuId, 0}},
- {2812, {wxMenuEvent, isPopup, 0}},
- {2813, {wxCloseEvent, canVeto, 0}},
- {2814, {wxCloseEvent, getLoggingOff, 0}},
- {2815, {wxCloseEvent, setCanVeto, 1}},
- {2816, {wxCloseEvent, setLoggingOff, 1}},
- {2817, {wxCloseEvent, veto, 1}},
- {2818, {wxShowEvent, setShow, 1}},
- {2819, {wxShowEvent, getShow, 0}},
- {2820, {wxIconizeEvent, iconized, 0}},
- {2821, {wxJoystickEvent, buttonDown, 1}},
- {2822, {wxJoystickEvent, buttonIsDown, 1}},
- {2823, {wxJoystickEvent, buttonUp, 1}},
- {2824, {wxJoystickEvent, getButtonChange, 0}},
- {2825, {wxJoystickEvent, getButtonState, 0}},
- {2826, {wxJoystickEvent, getJoystick, 0}},
- {2827, {wxJoystickEvent, getPosition, 0}},
- {2828, {wxJoystickEvent, getZPosition, 0}},
- {2829, {wxJoystickEvent, isButton, 0}},
- {2830, {wxJoystickEvent, isMove, 0}},
- {2831, {wxJoystickEvent, isZMove, 0}},
- {2832, {wxUpdateUIEvent, canUpdate, 1}},
- {2833, {wxUpdateUIEvent, check, 1}},
- {2834, {wxUpdateUIEvent, enable, 1}},
- {2835, {wxUpdateUIEvent, show, 1}},
- {2836, {wxUpdateUIEvent, getChecked, 0}},
- {2837, {wxUpdateUIEvent, getEnabled, 0}},
- {2838, {wxUpdateUIEvent, getShown, 0}},
- {2839, {wxUpdateUIEvent, getSetChecked, 0}},
- {2840, {wxUpdateUIEvent, getSetEnabled, 0}},
- {2841, {wxUpdateUIEvent, getSetShown, 0}},
- {2842, {wxUpdateUIEvent, getSetText, 0}},
- {2843, {wxUpdateUIEvent, getText, 0}},
- {2844, {wxUpdateUIEvent, getMode, 0}},
- {2845, {wxUpdateUIEvent, getUpdateInterval, 0}},
- {2846, {wxUpdateUIEvent, resetUpdateTime, 0}},
- {2847, {wxUpdateUIEvent, setMode, 1}},
- {2848, {wxUpdateUIEvent, setText, 1}},
- {2849, {wxUpdateUIEvent, setUpdateInterval, 1}},
- {2850, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}},
- {2851, {wxPaletteChangedEvent, setChangedWindow, 1}},
- {2852, {wxPaletteChangedEvent, getChangedWindow, 0}},
- {2853, {wxQueryNewPaletteEvent, setPaletteRealized, 1}},
- {2854, {wxQueryNewPaletteEvent, getPaletteRealized, 0}},
- {2855, {wxNavigationKeyEvent, getDirection, 0}},
- {2856, {wxNavigationKeyEvent, setDirection, 1}},
- {2857, {wxNavigationKeyEvent, isWindowChange, 0}},
- {2858, {wxNavigationKeyEvent, setWindowChange, 1}},
- {2859, {wxNavigationKeyEvent, isFromTab, 0}},
- {2860, {wxNavigationKeyEvent, setFromTab, 1}},
- {2861, {wxNavigationKeyEvent, getCurrentFocus, 0}},
- {2862, {wxNavigationKeyEvent, setCurrentFocus, 1}},
- {2863, {wxHelpEvent, getOrigin, 0}},
- {2864, {wxHelpEvent, getPosition, 0}},
- {2865, {wxHelpEvent, setOrigin, 1}},
- {2866, {wxHelpEvent, setPosition, 1}},
- {2867, {wxContextMenuEvent, getPosition, 0}},
- {2868, {wxContextMenuEvent, setPosition, 1}},
- {2869, {wxIdleEvent, canSend, 1}},
- {2870, {wxIdleEvent, getMode, 0}},
- {2871, {wxIdleEvent, requestMore, 1}},
- {2872, {wxIdleEvent, moreRequested, 0}},
- {2873, {wxIdleEvent, setMode, 1}},
- {2874, {wxGridEvent, altDown, 0}},
- {2875, {wxGridEvent, controlDown, 0}},
- {2876, {wxGridEvent, getCol, 0}},
- {2877, {wxGridEvent, getPosition, 0}},
- {2878, {wxGridEvent, getRow, 0}},
- {2879, {wxGridEvent, metaDown, 0}},
- {2880, {wxGridEvent, selecting, 0}},
- {2881, {wxGridEvent, shiftDown, 0}},
- {2882, {wxNotifyEvent, allow, 0}},
- {2883, {wxNotifyEvent, isAllowed, 0}},
- {2884, {wxNotifyEvent, veto, 0}},
- {2885, {wxSashEvent, getEdge, 0}},
- {2886, {wxSashEvent, getDragRect, 0}},
- {2887, {wxSashEvent, getDragStatus, 0}},
- {2888, {wxListEvent, getCacheFrom, 0}},
- {2889, {wxListEvent, getCacheTo, 0}},
- {2890, {wxListEvent, getKeyCode, 0}},
- {2891, {wxListEvent, getIndex, 0}},
- {2892, {wxListEvent, getColumn, 0}},
- {2893, {wxListEvent, getPoint, 0}},
- {2894, {wxListEvent, getLabel, 0}},
- {2895, {wxListEvent, getText, 0}},
- {2896, {wxListEvent, getImage, 0}},
- {2897, {wxListEvent, getData, 0}},
- {2898, {wxListEvent, getMask, 0}},
- {2899, {wxListEvent, getItem, 0}},
- {2900, {wxListEvent, isEditCancelled, 0}},
- {2901, {wxDateEvent, getDate, 0}},
- {2902, {wxCalendarEvent, getWeekDay, 0}},
- {2903, {wxFileDirPickerEvent, getPath, 0}},
- {2904, {wxColourPickerEvent, getColour, 0}},
- {2905, {wxFontPickerEvent, getFont, 0}},
- {2906, {wxStyledTextEvent, getPosition, 0}},
- {2907, {wxStyledTextEvent, getKey, 0}},
- {2908, {wxStyledTextEvent, getModifiers, 0}},
- {2909, {wxStyledTextEvent, getModificationType, 0}},
- {2910, {wxStyledTextEvent, getText, 0}},
- {2911, {wxStyledTextEvent, getLength, 0}},
- {2912, {wxStyledTextEvent, getLinesAdded, 0}},
- {2913, {wxStyledTextEvent, getLine, 0}},
- {2914, {wxStyledTextEvent, getFoldLevelNow, 0}},
- {2915, {wxStyledTextEvent, getFoldLevelPrev, 0}},
- {2916, {wxStyledTextEvent, getMargin, 0}},
- {2917, {wxStyledTextEvent, getMessage, 0}},
- {2918, {wxStyledTextEvent, getWParam, 0}},
- {2919, {wxStyledTextEvent, getLParam, 0}},
- {2920, {wxStyledTextEvent, getListType, 0}},
- {2921, {wxStyledTextEvent, getX, 0}},
- {2922, {wxStyledTextEvent, getY, 0}},
- {2923, {wxStyledTextEvent, getDragText, 0}},
- {2924, {wxStyledTextEvent, getDragAllowMove, 0}},
- {2925, {wxStyledTextEvent, getDragResult, 0}},
- {2926, {wxStyledTextEvent, getShift, 0}},
- {2927, {wxStyledTextEvent, getControl, 0}},
- {2928, {wxStyledTextEvent, getAlt, 0}},
- {2929, {utils, getKeyState, 1}},
- {2930, {utils, getMousePosition, 2}},
- {2931, {utils, getMouseState, 0}},
- {2932, {utils, setDetectableAutoRepeat, 1}},
- {2933, {utils, bell, 0}},
- {2934, {utils, findMenuItemId, 3}},
- {2935, {utils, genericFindWindowAtPoint, 1}},
- {2936, {utils, findWindowAtPoint, 1}},
- {2937, {utils, beginBusyCursor, 1}},
- {2938, {utils, endBusyCursor, 0}},
- {2939, {utils, isBusy, 0}},
- {2940, {utils, shutdown, 1}},
- {2941, {utils, shell, 1}},
- {2942, {utils, launchDefaultBrowser, 2}},
- {2943, {utils, getEmailAddress, 0}},
- {2944, {utils, getUserId, 0}},
- {2945, {utils, getHomeDir, 0}},
- {2946, {utils, newId, 0}},
- {2947, {utils, registerId, 1}},
- {2948, {utils, getCurrentId, 0}},
- {2949, {utils, getOsDescription, 0}},
- {2950, {utils, isPlatformLittleEndian, 0}},
- {2951, {utils, isPlatform64Bit, 0}},
- {2952, {gdicmn, displaySize, 2}},
- {2953, {gdicmn, setCursor, 1}},
- {2954, {wxPrintout, new, 1}},
- {2955, {wxPrintout, destruct, 0}},
- {2956, {wxPrintout, getDC, 0}},
- {2957, {wxPrintout, getPageSizeMM, 2}},
- {2958, {wxPrintout, getPageSizePixels, 2}},
- {2959, {wxPrintout, getPaperRectPixels, 0}},
- {2960, {wxPrintout, getPPIPrinter, 2}},
- {2961, {wxPrintout, getPPIScreen, 2}},
- {2962, {wxPrintout, getTitle, 0}},
- {2963, {wxPrintout, isPreview, 0}},
- {2964, {wxPrintout, fitThisSizeToPaper, 1}},
- {2965, {wxPrintout, fitThisSizeToPage, 1}},
- {2966, {wxPrintout, fitThisSizeToPageMargins, 2}},
- {2967, {wxPrintout, mapScreenSizeToPaper, 0}},
- {2968, {wxPrintout, mapScreenSizeToPage, 0}},
- {2969, {wxPrintout, mapScreenSizeToPageMargins, 1}},
- {2970, {wxPrintout, mapScreenSizeToDevice, 0}},
- {2971, {wxPrintout, getLogicalPaperRect, 0}},
- {2972, {wxPrintout, getLogicalPageRect, 0}},
- {2973, {wxPrintout, getLogicalPageMarginsRect, 1}},
- {2974, {wxPrintout, setLogicalOrigin, 2}},
- {2975, {wxPrintout, offsetLogicalOrigin, 2}},
- {2976, {wxStyledTextCtrl, new_2, 2}},
- {2977, {wxStyledTextCtrl, new_0, 0}},
- {2978, {wxStyledTextCtrl, destruct, 0}},
- {2979, {wxStyledTextCtrl, create, 2}},
- {2980, {wxStyledTextCtrl, addText, 1}},
- {2981, {wxStyledTextCtrl, addStyledText, 1}},
- {2982, {wxStyledTextCtrl, insertText, 2}},
- {2983, {wxStyledTextCtrl, clearAll, 0}},
- {2984, {wxStyledTextCtrl, clearDocumentStyle, 0}},
- {2985, {wxStyledTextCtrl, getLength, 0}},
- {2986, {wxStyledTextCtrl, getCharAt, 1}},
- {2987, {wxStyledTextCtrl, getCurrentPos, 0}},
- {2988, {wxStyledTextCtrl, getAnchor, 0}},
- {2989, {wxStyledTextCtrl, getStyleAt, 1}},
- {2990, {wxStyledTextCtrl, redo, 0}},
- {2991, {wxStyledTextCtrl, setUndoCollection, 1}},
- {2992, {wxStyledTextCtrl, selectAll, 0}},
- {2993, {wxStyledTextCtrl, setSavePoint, 0}},
- {2994, {wxStyledTextCtrl, getStyledText, 2}},
- {2995, {wxStyledTextCtrl, canRedo, 0}},
- {2996, {wxStyledTextCtrl, markerLineFromHandle, 1}},
- {2997, {wxStyledTextCtrl, markerDeleteHandle, 1}},
- {2998, {wxStyledTextCtrl, getUndoCollection, 0}},
- {2999, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
- {3000, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
- {3001, {wxStyledTextCtrl, positionFromPoint, 1}},
- {3002, {wxStyledTextCtrl, positionFromPointClose, 2}},
- {3003, {wxStyledTextCtrl, gotoLine, 1}},
- {3004, {wxStyledTextCtrl, gotoPos, 1}},
- {3005, {wxStyledTextCtrl, setAnchor, 1}},
- {3006, {wxStyledTextCtrl, getCurLine, 1}},
- {3007, {wxStyledTextCtrl, getEndStyled, 0}},
- {3008, {wxStyledTextCtrl, convertEOLs, 1}},
- {3009, {wxStyledTextCtrl, getEOLMode, 0}},
- {3010, {wxStyledTextCtrl, setEOLMode, 1}},
- {3011, {wxStyledTextCtrl, startStyling, 2}},
- {3012, {wxStyledTextCtrl, setStyling, 2}},
- {3013, {wxStyledTextCtrl, getBufferedDraw, 0}},
- {3014, {wxStyledTextCtrl, setBufferedDraw, 1}},
- {3015, {wxStyledTextCtrl, setTabWidth, 1}},
- {3016, {wxStyledTextCtrl, getTabWidth, 0}},
- {3017, {wxStyledTextCtrl, setCodePage, 1}},
- {3018, {wxStyledTextCtrl, markerDefine, 3}},
- {3019, {wxStyledTextCtrl, markerSetForeground, 2}},
- {3020, {wxStyledTextCtrl, markerSetBackground, 2}},
- {3021, {wxStyledTextCtrl, markerAdd, 2}},
- {3022, {wxStyledTextCtrl, markerDelete, 2}},
- {3023, {wxStyledTextCtrl, markerDeleteAll, 1}},
- {3024, {wxStyledTextCtrl, markerGet, 1}},
- {3025, {wxStyledTextCtrl, markerNext, 2}},
- {3026, {wxStyledTextCtrl, markerPrevious, 2}},
- {3027, {wxStyledTextCtrl, markerDefineBitmap, 2}},
- {3028, {wxStyledTextCtrl, markerAddSet, 2}},
- {3029, {wxStyledTextCtrl, markerSetAlpha, 2}},
- {3030, {wxStyledTextCtrl, setMarginType, 2}},
- {3031, {wxStyledTextCtrl, getMarginType, 1}},
- {3032, {wxStyledTextCtrl, setMarginWidth, 2}},
- {3033, {wxStyledTextCtrl, getMarginWidth, 1}},
- {3034, {wxStyledTextCtrl, setMarginMask, 2}},
- {3035, {wxStyledTextCtrl, getMarginMask, 1}},
- {3036, {wxStyledTextCtrl, setMarginSensitive, 2}},
- {3037, {wxStyledTextCtrl, getMarginSensitive, 1}},
- {3038, {wxStyledTextCtrl, styleClearAll, 0}},
- {3039, {wxStyledTextCtrl, styleSetForeground, 2}},
- {3040, {wxStyledTextCtrl, styleSetBackground, 2}},
- {3041, {wxStyledTextCtrl, styleSetBold, 2}},
- {3042, {wxStyledTextCtrl, styleSetItalic, 2}},
- {3043, {wxStyledTextCtrl, styleSetSize, 2}},
- {3044, {wxStyledTextCtrl, styleSetFaceName, 2}},
- {3045, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
- {3046, {wxStyledTextCtrl, styleResetDefault, 0}},
- {3047, {wxStyledTextCtrl, styleSetUnderline, 2}},
- {3048, {wxStyledTextCtrl, styleSetCase, 2}},
- {3049, {wxStyledTextCtrl, styleSetHotSpot, 2}},
- {3050, {wxStyledTextCtrl, setSelForeground, 2}},
- {3051, {wxStyledTextCtrl, setSelBackground, 2}},
- {3052, {wxStyledTextCtrl, getSelAlpha, 0}},
- {3053, {wxStyledTextCtrl, setSelAlpha, 1}},
- {3054, {wxStyledTextCtrl, setCaretForeground, 1}},
- {3055, {wxStyledTextCtrl, cmdKeyAssign, 3}},
- {3056, {wxStyledTextCtrl, cmdKeyClear, 2}},
- {3057, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
- {3058, {wxStyledTextCtrl, setStyleBytes, 2}},
- {3059, {wxStyledTextCtrl, styleSetVisible, 2}},
- {3060, {wxStyledTextCtrl, getCaretPeriod, 0}},
- {3061, {wxStyledTextCtrl, setCaretPeriod, 1}},
- {3062, {wxStyledTextCtrl, setWordChars, 1}},
- {3063, {wxStyledTextCtrl, beginUndoAction, 0}},
- {3064, {wxStyledTextCtrl, endUndoAction, 0}},
- {3065, {wxStyledTextCtrl, indicatorSetStyle, 2}},
- {3066, {wxStyledTextCtrl, indicatorGetStyle, 1}},
- {3067, {wxStyledTextCtrl, indicatorSetForeground, 2}},
- {3068, {wxStyledTextCtrl, indicatorGetForeground, 1}},
- {3069, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
- {3070, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
- {3071, {wxStyledTextCtrl, getStyleBits, 0}},
- {3072, {wxStyledTextCtrl, setLineState, 2}},
- {3073, {wxStyledTextCtrl, getLineState, 1}},
- {3074, {wxStyledTextCtrl, getMaxLineState, 0}},
- {3075, {wxStyledTextCtrl, getCaretLineVisible, 0}},
- {3076, {wxStyledTextCtrl, setCaretLineVisible, 1}},
- {3077, {wxStyledTextCtrl, getCaretLineBackground, 0}},
- {3078, {wxStyledTextCtrl, setCaretLineBackground, 1}},
- {3079, {wxStyledTextCtrl, autoCompShow, 2}},
- {3080, {wxStyledTextCtrl, autoCompCancel, 0}},
- {3081, {wxStyledTextCtrl, autoCompActive, 0}},
- {3082, {wxStyledTextCtrl, autoCompPosStart, 0}},
- {3083, {wxStyledTextCtrl, autoCompComplete, 0}},
- {3084, {wxStyledTextCtrl, autoCompStops, 1}},
- {3085, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
- {3086, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
- {3087, {wxStyledTextCtrl, autoCompSelect, 1}},
- {3088, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
- {3089, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
- {3090, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
- {3091, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
- {3092, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
- {3093, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
- {3094, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
- {3095, {wxStyledTextCtrl, userListShow, 2}},
- {3096, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
- {3097, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
- {3098, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
- {3099, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
- {3100, {wxStyledTextCtrl, registerImage, 2}},
- {3101, {wxStyledTextCtrl, clearRegisteredImages, 0}},
- {3102, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
- {3103, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
- {3104, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
- {3105, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
- {3106, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
- {3107, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
- {3108, {wxStyledTextCtrl, setIndent, 1}},
- {3109, {wxStyledTextCtrl, getIndent, 0}},
- {3110, {wxStyledTextCtrl, setUseTabs, 1}},
- {3111, {wxStyledTextCtrl, getUseTabs, 0}},
- {3112, {wxStyledTextCtrl, setLineIndentation, 2}},
- {3113, {wxStyledTextCtrl, getLineIndentation, 1}},
- {3114, {wxStyledTextCtrl, getLineIndentPosition, 1}},
- {3115, {wxStyledTextCtrl, getColumn, 1}},
- {3116, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
- {3117, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
- {3118, {wxStyledTextCtrl, setIndentationGuides, 1}},
- {3119, {wxStyledTextCtrl, getIndentationGuides, 0}},
- {3120, {wxStyledTextCtrl, setHighlightGuide, 1}},
- {3121, {wxStyledTextCtrl, getHighlightGuide, 0}},
- {3122, {wxStyledTextCtrl, getLineEndPosition, 1}},
- {3123, {wxStyledTextCtrl, getCodePage, 0}},
- {3124, {wxStyledTextCtrl, getCaretForeground, 0}},
- {3125, {wxStyledTextCtrl, getReadOnly, 0}},
- {3126, {wxStyledTextCtrl, setCurrentPos, 1}},
- {3127, {wxStyledTextCtrl, setSelectionStart, 1}},
- {3128, {wxStyledTextCtrl, getSelectionStart, 0}},
- {3129, {wxStyledTextCtrl, setSelectionEnd, 1}},
- {3130, {wxStyledTextCtrl, getSelectionEnd, 0}},
- {3131, {wxStyledTextCtrl, setPrintMagnification, 1}},
- {3132, {wxStyledTextCtrl, getPrintMagnification, 0}},
- {3133, {wxStyledTextCtrl, setPrintColourMode, 1}},
- {3134, {wxStyledTextCtrl, getPrintColourMode, 0}},
- {3135, {wxStyledTextCtrl, findText, 4}},
- {3136, {wxStyledTextCtrl, formatRange, 7}},
- {3137, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
- {3138, {wxStyledTextCtrl, getLine, 1}},
- {3139, {wxStyledTextCtrl, getLineCount, 0}},
- {3140, {wxStyledTextCtrl, setMarginLeft, 1}},
- {3141, {wxStyledTextCtrl, getMarginLeft, 0}},
- {3142, {wxStyledTextCtrl, setMarginRight, 1}},
- {3143, {wxStyledTextCtrl, getMarginRight, 0}},
- {3144, {wxStyledTextCtrl, getModify, 0}},
- {3145, {wxStyledTextCtrl, setSelection, 2}},
- {3146, {wxStyledTextCtrl, getSelectedText, 0}},
- {3147, {wxStyledTextCtrl, getTextRange, 2}},
- {3148, {wxStyledTextCtrl, hideSelection, 1}},
- {3149, {wxStyledTextCtrl, lineFromPosition, 1}},
- {3150, {wxStyledTextCtrl, positionFromLine, 1}},
- {3151, {wxStyledTextCtrl, lineScroll, 2}},
- {3152, {wxStyledTextCtrl, ensureCaretVisible, 0}},
- {3153, {wxStyledTextCtrl, replaceSelection, 1}},
- {3154, {wxStyledTextCtrl, setReadOnly, 1}},
- {3155, {wxStyledTextCtrl, canPaste, 0}},
- {3156, {wxStyledTextCtrl, canUndo, 0}},
- {3157, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
- {3158, {wxStyledTextCtrl, undo, 0}},
- {3159, {wxStyledTextCtrl, cut, 0}},
- {3160, {wxStyledTextCtrl, copy, 0}},
- {3161, {wxStyledTextCtrl, paste, 0}},
- {3162, {wxStyledTextCtrl, clear, 0}},
- {3163, {wxStyledTextCtrl, setText, 1}},
- {3164, {wxStyledTextCtrl, getText, 0}},
- {3165, {wxStyledTextCtrl, getTextLength, 0}},
- {3166, {wxStyledTextCtrl, getOvertype, 0}},
- {3167, {wxStyledTextCtrl, setCaretWidth, 1}},
- {3168, {wxStyledTextCtrl, getCaretWidth, 0}},
- {3169, {wxStyledTextCtrl, setTargetStart, 1}},
- {3170, {wxStyledTextCtrl, getTargetStart, 0}},
- {3171, {wxStyledTextCtrl, setTargetEnd, 1}},
- {3172, {wxStyledTextCtrl, getTargetEnd, 0}},
- {3173, {wxStyledTextCtrl, replaceTarget, 1}},
- {3174, {wxStyledTextCtrl, searchInTarget, 1}},
- {3175, {wxStyledTextCtrl, setSearchFlags, 1}},
- {3176, {wxStyledTextCtrl, getSearchFlags, 0}},
- {3177, {wxStyledTextCtrl, callTipShow, 2}},
- {3178, {wxStyledTextCtrl, callTipCancel, 0}},
- {3179, {wxStyledTextCtrl, callTipActive, 0}},
- {3180, {wxStyledTextCtrl, callTipPosAtStart, 0}},
- {3181, {wxStyledTextCtrl, callTipSetHighlight, 2}},
- {3182, {wxStyledTextCtrl, callTipSetBackground, 1}},
- {3183, {wxStyledTextCtrl, callTipSetForeground, 1}},
- {3184, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
- {3185, {wxStyledTextCtrl, callTipUseStyle, 1}},
- {3186, {wxStyledTextCtrl, visibleFromDocLine, 1}},
- {3187, {wxStyledTextCtrl, docLineFromVisible, 1}},
- {3188, {wxStyledTextCtrl, wrapCount, 1}},
- {3189, {wxStyledTextCtrl, setFoldLevel, 2}},
- {3190, {wxStyledTextCtrl, getFoldLevel, 1}},
- {3191, {wxStyledTextCtrl, getLastChild, 2}},
- {3192, {wxStyledTextCtrl, getFoldParent, 1}},
- {3193, {wxStyledTextCtrl, showLines, 2}},
- {3194, {wxStyledTextCtrl, hideLines, 2}},
- {3195, {wxStyledTextCtrl, getLineVisible, 1}},
- {3196, {wxStyledTextCtrl, setFoldExpanded, 2}},
- {3197, {wxStyledTextCtrl, getFoldExpanded, 1}},
- {3198, {wxStyledTextCtrl, toggleFold, 1}},
- {3199, {wxStyledTextCtrl, ensureVisible, 1}},
- {3200, {wxStyledTextCtrl, setFoldFlags, 1}},
- {3201, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
- {3202, {wxStyledTextCtrl, setTabIndents, 1}},
- {3203, {wxStyledTextCtrl, getTabIndents, 0}},
- {3204, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
- {3205, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
- {3206, {wxStyledTextCtrl, setMouseDwellTime, 1}},
- {3207, {wxStyledTextCtrl, getMouseDwellTime, 0}},
- {3208, {wxStyledTextCtrl, wordStartPosition, 2}},
- {3209, {wxStyledTextCtrl, wordEndPosition, 2}},
- {3210, {wxStyledTextCtrl, setWrapMode, 1}},
- {3211, {wxStyledTextCtrl, getWrapMode, 0}},
- {3212, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
- {3213, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
- {3214, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
- {3215, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
- {3216, {wxStyledTextCtrl, setWrapStartIndent, 1}},
- {3217, {wxStyledTextCtrl, getWrapStartIndent, 0}},
- {3218, {wxStyledTextCtrl, setLayoutCache, 1}},
- {3219, {wxStyledTextCtrl, getLayoutCache, 0}},
- {3220, {wxStyledTextCtrl, setScrollWidth, 1}},
- {3221, {wxStyledTextCtrl, getScrollWidth, 0}},
- {3222, {wxStyledTextCtrl, textWidth, 2}},
- {3223, {wxStyledTextCtrl, getEndAtLastLine, 0}},
- {3224, {wxStyledTextCtrl, textHeight, 1}},
- {3225, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
- {3226, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
- {3227, {wxStyledTextCtrl, appendText, 1}},
- {3228, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
- {3229, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
- {3230, {wxStyledTextCtrl, targetFromSelection, 0}},
- {3231, {wxStyledTextCtrl, linesJoin, 0}},
- {3232, {wxStyledTextCtrl, linesSplit, 1}},
- {3233, {wxStyledTextCtrl, setFoldMarginColour, 2}},
- {3234, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
- {3235, {wxStyledTextCtrl, lineDown, 0}},
- {3236, {wxStyledTextCtrl, lineDownExtend, 0}},
- {3237, {wxStyledTextCtrl, lineUp, 0}},
- {3238, {wxStyledTextCtrl, lineUpExtend, 0}},
- {3239, {wxStyledTextCtrl, charLeft, 0}},
- {3240, {wxStyledTextCtrl, charLeftExtend, 0}},
- {3241, {wxStyledTextCtrl, charRight, 0}},
- {3242, {wxStyledTextCtrl, charRightExtend, 0}},
- {3243, {wxStyledTextCtrl, wordLeft, 0}},
- {3244, {wxStyledTextCtrl, wordLeftExtend, 0}},
- {3245, {wxStyledTextCtrl, wordRight, 0}},
- {3246, {wxStyledTextCtrl, wordRightExtend, 0}},
- {3247, {wxStyledTextCtrl, home, 0}},
- {3248, {wxStyledTextCtrl, homeExtend, 0}},
- {3249, {wxStyledTextCtrl, lineEnd, 0}},
- {3250, {wxStyledTextCtrl, lineEndExtend, 0}},
- {3251, {wxStyledTextCtrl, documentStart, 0}},
- {3252, {wxStyledTextCtrl, documentStartExtend, 0}},
- {3253, {wxStyledTextCtrl, documentEnd, 0}},
- {3254, {wxStyledTextCtrl, documentEndExtend, 0}},
- {3255, {wxStyledTextCtrl, pageUp, 0}},
- {3256, {wxStyledTextCtrl, pageUpExtend, 0}},
- {3257, {wxStyledTextCtrl, pageDown, 0}},
- {3258, {wxStyledTextCtrl, pageDownExtend, 0}},
- {3259, {wxStyledTextCtrl, editToggleOvertype, 0}},
- {3260, {wxStyledTextCtrl, cancel, 0}},
- {3261, {wxStyledTextCtrl, deleteBack, 0}},
- {3262, {wxStyledTextCtrl, tab, 0}},
- {3263, {wxStyledTextCtrl, backTab, 0}},
- {3264, {wxStyledTextCtrl, newLine, 0}},
- {3265, {wxStyledTextCtrl, formFeed, 0}},
- {3266, {wxStyledTextCtrl, vCHome, 0}},
- {3267, {wxStyledTextCtrl, vCHomeExtend, 0}},
- {3268, {wxStyledTextCtrl, zoomIn, 0}},
- {3269, {wxStyledTextCtrl, zoomOut, 0}},
- {3270, {wxStyledTextCtrl, delWordLeft, 0}},
- {3271, {wxStyledTextCtrl, delWordRight, 0}},
- {3272, {wxStyledTextCtrl, lineCut, 0}},
- {3273, {wxStyledTextCtrl, lineDelete, 0}},
- {3274, {wxStyledTextCtrl, lineTranspose, 0}},
- {3275, {wxStyledTextCtrl, lineDuplicate, 0}},
- {3276, {wxStyledTextCtrl, lowerCase, 0}},
- {3277, {wxStyledTextCtrl, upperCase, 0}},
- {3278, {wxStyledTextCtrl, lineScrollDown, 0}},
- {3279, {wxStyledTextCtrl, lineScrollUp, 0}},
- {3280, {wxStyledTextCtrl, deleteBackNotLine, 0}},
- {3281, {wxStyledTextCtrl, homeDisplay, 0}},
- {3282, {wxStyledTextCtrl, homeDisplayExtend, 0}},
- {3283, {wxStyledTextCtrl, lineEndDisplay, 0}},
- {3284, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
- {3285, {wxStyledTextCtrl, homeWrapExtend, 0}},
- {3286, {wxStyledTextCtrl, lineEndWrap, 0}},
- {3287, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
- {3288, {wxStyledTextCtrl, vCHomeWrap, 0}},
- {3289, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
- {3290, {wxStyledTextCtrl, lineCopy, 0}},
- {3291, {wxStyledTextCtrl, moveCaretInsideView, 0}},
- {3292, {wxStyledTextCtrl, lineLength, 1}},
- {3293, {wxStyledTextCtrl, braceHighlight, 2}},
- {3294, {wxStyledTextCtrl, braceBadLight, 1}},
- {3295, {wxStyledTextCtrl, braceMatch, 1}},
- {3296, {wxStyledTextCtrl, getViewEOL, 0}},
- {3297, {wxStyledTextCtrl, setViewEOL, 1}},
- {3298, {wxStyledTextCtrl, setModEventMask, 1}},
- {3299, {wxStyledTextCtrl, getEdgeColumn, 0}},
- {3300, {wxStyledTextCtrl, setEdgeColumn, 1}},
- {3301, {wxStyledTextCtrl, setEdgeMode, 1}},
- {3302, {wxStyledTextCtrl, getEdgeMode, 0}},
- {3303, {wxStyledTextCtrl, getEdgeColour, 0}},
- {3304, {wxStyledTextCtrl, setEdgeColour, 1}},
- {3305, {wxStyledTextCtrl, searchAnchor, 0}},
- {3306, {wxStyledTextCtrl, searchNext, 2}},
- {3307, {wxStyledTextCtrl, searchPrev, 2}},
- {3308, {wxStyledTextCtrl, linesOnScreen, 0}},
- {3309, {wxStyledTextCtrl, usePopUp, 1}},
- {3310, {wxStyledTextCtrl, selectionIsRectangle, 0}},
- {3311, {wxStyledTextCtrl, setZoom, 1}},
- {3312, {wxStyledTextCtrl, getZoom, 0}},
- {3313, {wxStyledTextCtrl, getModEventMask, 0}},
- {3314, {wxStyledTextCtrl, setSTCFocus, 1}},
- {3315, {wxStyledTextCtrl, getSTCFocus, 0}},
- {3316, {wxStyledTextCtrl, setStatus, 1}},
- {3317, {wxStyledTextCtrl, getStatus, 0}},
- {3318, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
- {3319, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
- {3320, {wxStyledTextCtrl, setSTCCursor, 1}},
- {3321, {wxStyledTextCtrl, getSTCCursor, 0}},
- {3322, {wxStyledTextCtrl, setControlCharSymbol, 1}},
- {3323, {wxStyledTextCtrl, getControlCharSymbol, 0}},
- {3324, {wxStyledTextCtrl, wordPartLeft, 0}},
- {3325, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
- {3326, {wxStyledTextCtrl, wordPartRight, 0}},
- {3327, {wxStyledTextCtrl, wordPartRightExtend, 0}},
- {3328, {wxStyledTextCtrl, setVisiblePolicy, 2}},
- {3329, {wxStyledTextCtrl, delLineLeft, 0}},
- {3330, {wxStyledTextCtrl, delLineRight, 0}},
- {3331, {wxStyledTextCtrl, getXOffset, 0}},
- {3332, {wxStyledTextCtrl, chooseCaretX, 0}},
- {3333, {wxStyledTextCtrl, setXCaretPolicy, 2}},
- {3334, {wxStyledTextCtrl, setYCaretPolicy, 2}},
- {3335, {wxStyledTextCtrl, getPrintWrapMode, 0}},
- {3336, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
- {3337, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
- {3338, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
- {3339, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
- {3340, {wxStyledTextCtrl, paraDownExtend, 0}},
- {3341, {wxStyledTextCtrl, paraUp, 0}},
- {3342, {wxStyledTextCtrl, paraUpExtend, 0}},
- {3343, {wxStyledTextCtrl, positionBefore, 1}},
- {3344, {wxStyledTextCtrl, positionAfter, 1}},
- {3345, {wxStyledTextCtrl, copyRange, 2}},
- {3346, {wxStyledTextCtrl, copyText, 2}},
- {3347, {wxStyledTextCtrl, setSelectionMode, 1}},
- {3348, {wxStyledTextCtrl, getSelectionMode, 0}},
- {3349, {wxStyledTextCtrl, lineDownRectExtend, 0}},
- {3350, {wxStyledTextCtrl, lineUpRectExtend, 0}},
- {3351, {wxStyledTextCtrl, charLeftRectExtend, 0}},
- {3352, {wxStyledTextCtrl, charRightRectExtend, 0}},
- {3353, {wxStyledTextCtrl, homeRectExtend, 0}},
- {3354, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
- {3355, {wxStyledTextCtrl, lineEndRectExtend, 0}},
- {3356, {wxStyledTextCtrl, pageUpRectExtend, 0}},
- {3357, {wxStyledTextCtrl, pageDownRectExtend, 0}},
- {3358, {wxStyledTextCtrl, stutteredPageUp, 0}},
- {3359, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
- {3360, {wxStyledTextCtrl, stutteredPageDown, 0}},
- {3361, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
- {3362, {wxStyledTextCtrl, wordLeftEnd, 0}},
- {3363, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
- {3364, {wxStyledTextCtrl, wordRightEnd, 0}},
- {3365, {wxStyledTextCtrl, wordRightEndExtend, 0}},
- {3366, {wxStyledTextCtrl, setWhitespaceChars, 1}},
- {3367, {wxStyledTextCtrl, setCharsDefault, 0}},
- {3368, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
- {3369, {wxStyledTextCtrl, allocate, 1}},
- {3370, {wxStyledTextCtrl, findColumn, 2}},
- {3371, {wxStyledTextCtrl, getCaretSticky, 0}},
- {3372, {wxStyledTextCtrl, setCaretSticky, 1}},
- {3373, {wxStyledTextCtrl, toggleCaretSticky, 0}},
- {3374, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
- {3375, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
- {3376, {wxStyledTextCtrl, selectionDuplicate, 0}},
- {3377, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
- {3378, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
- {3379, {wxStyledTextCtrl, startRecord, 0}},
- {3380, {wxStyledTextCtrl, stopRecord, 0}},
- {3381, {wxStyledTextCtrl, setLexer, 1}},
- {3382, {wxStyledTextCtrl, getLexer, 0}},
- {3383, {wxStyledTextCtrl, colourise, 2}},
- {3384, {wxStyledTextCtrl, setProperty, 2}},
- {3385, {wxStyledTextCtrl, setKeyWords, 2}},
- {3386, {wxStyledTextCtrl, setLexerLanguage, 1}},
- {3387, {wxStyledTextCtrl, getProperty, 1}},
- {3388, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
- {3389, {wxStyledTextCtrl, getCurrentLine, 0}},
- {3390, {wxStyledTextCtrl, styleSetSpec, 2}},
- {3391, {wxStyledTextCtrl, styleSetFont, 2}},
- {3392, {wxStyledTextCtrl, styleSetFontAttr, 7}},
- {3393, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
- {3394, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
- {3395, {wxStyledTextCtrl, cmdKeyExecute, 1}},
- {3396, {wxStyledTextCtrl, setMargins, 2}},
- {3397, {wxStyledTextCtrl, getSelection, 2}},
- {3398, {wxStyledTextCtrl, pointFromPosition, 1}},
- {3399, {wxStyledTextCtrl, scrollToLine, 1}},
- {3400, {wxStyledTextCtrl, scrollToColumn, 1}},
- {3401, {wxStyledTextCtrl, setVScrollBar, 1}},
- {3402, {wxStyledTextCtrl, setHScrollBar, 1}},
- {3403, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
- {3404, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
- {3405, {wxStyledTextCtrl, saveFile, 1}},
- {3406, {wxStyledTextCtrl, loadFile, 1}},
- {3407, {wxStyledTextCtrl, doDragOver, 3}},
- {3408, {wxStyledTextCtrl, doDropText, 3}},
- {3409, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
- {3410, {wxStyledTextCtrl, addTextRaw, 1}},
- {3411, {wxStyledTextCtrl, insertTextRaw, 2}},
- {3412, {wxStyledTextCtrl, getCurLineRaw, 1}},
- {3413, {wxStyledTextCtrl, getLineRaw, 1}},
- {3414, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
- {3415, {wxStyledTextCtrl, getTextRangeRaw, 2}},
- {3416, {wxStyledTextCtrl, setTextRaw, 1}},
- {3417, {wxStyledTextCtrl, getTextRaw, 0}},
- {3418, {wxStyledTextCtrl, appendTextRaw, 1}},
- {3419, {wxArtProvider, getBitmap, 2}},
- {3420, {wxArtProvider, getIcon, 2}},
- {3421, {wxTreeEvent, getKeyCode, 0}},
- {3422, {wxTreeEvent, getItem, 0}},
- {3423, {wxTreeEvent, getKeyEvent, 0}},
- {3424, {wxTreeEvent, getLabel, 0}},
- {3425, {wxTreeEvent, getOldItem, 0}},
- {3426, {wxTreeEvent, getPoint, 0}},
- {3427, {wxTreeEvent, isEditCancelled, 0}},
- {3428, {wxTreeEvent, setToolTip, 1}},
- {3429, {wxNotebookEvent, getOldSelection, 0}},
- {3430, {wxNotebookEvent, getSelection, 0}},
- {3431, {wxNotebookEvent, setOldSelection, 1}},
- {3432, {wxNotebookEvent, setSelection, 1}},
- {3433, {wxFileDataObject, new, 0}},
- {3434, {wxFileDataObject, addFile, 1}},
- {3435, {wxFileDataObject, getFilenames, 0}},
- {3436, {wxFileDataObject, 'Destroy', undefined}},
- {3437, {wxTextDataObject, new, 1}},
- {3438, {wxTextDataObject, getTextLength, 0}},
- {3439, {wxTextDataObject, getText, 0}},
- {3440, {wxTextDataObject, setText, 1}},
- {3441, {wxTextDataObject, 'Destroy', undefined}},
- {3442, {wxBitmapDataObject, new_1_1, 1}},
- {3443, {wxBitmapDataObject, new_1_0, 1}},
- {3444, {wxBitmapDataObject, getBitmap, 0}},
- {3445, {wxBitmapDataObject, setBitmap, 1}},
- {3446, {wxBitmapDataObject, 'Destroy', undefined}},
- {3448, {wxClipboard, new, 0}},
- {3449, {wxClipboard, destruct, 0}},
- {3450, {wxClipboard, addData, 1}},
- {3451, {wxClipboard, clear, 0}},
- {3452, {wxClipboard, close, 0}},
- {3453, {wxClipboard, flush, 0}},
- {3454, {wxClipboard, getData, 1}},
- {3455, {wxClipboard, isOpened, 0}},
- {3456, {wxClipboard, open, 0}},
- {3457, {wxClipboard, setData, 1}},
- {3459, {wxClipboard, usePrimarySelection, 1}},
- {3460, {wxClipboard, isSupported, 1}},
- {3461, {wxClipboard, get, 0}},
- {3462, {wxSpinEvent, getPosition, 0}},
- {3463, {wxSpinEvent, setPosition, 1}},
- {3464, {wxSplitterWindow, new_0, 0}},
- {3465, {wxSplitterWindow, new_2, 2}},
- {3466, {wxSplitterWindow, destruct, 0}},
- {3467, {wxSplitterWindow, create, 2}},
- {3468, {wxSplitterWindow, getMinimumPaneSize, 0}},
- {3469, {wxSplitterWindow, getSashGravity, 0}},
- {3470, {wxSplitterWindow, getSashPosition, 0}},
- {3471, {wxSplitterWindow, getSplitMode, 0}},
- {3472, {wxSplitterWindow, getWindow1, 0}},
- {3473, {wxSplitterWindow, getWindow2, 0}},
- {3474, {wxSplitterWindow, initialize, 1}},
- {3475, {wxSplitterWindow, isSplit, 0}},
- {3476, {wxSplitterWindow, replaceWindow, 2}},
- {3477, {wxSplitterWindow, setSashGravity, 1}},
- {3478, {wxSplitterWindow, setSashPosition, 2}},
- {3479, {wxSplitterWindow, setSashSize, 1}},
- {3480, {wxSplitterWindow, setMinimumPaneSize, 1}},
- {3481, {wxSplitterWindow, setSplitMode, 1}},
- {3482, {wxSplitterWindow, splitHorizontally, 3}},
- {3483, {wxSplitterWindow, splitVertically, 3}},
- {3484, {wxSplitterWindow, unsplit, 1}},
- {3485, {wxSplitterWindow, updateSize, 0}},
- {3486, {wxSplitterEvent, getSashPosition, 0}},
- {3487, {wxSplitterEvent, getX, 0}},
- {3488, {wxSplitterEvent, getY, 0}},
- {3489, {wxSplitterEvent, getWindowBeingRemoved, 0}},
- {3490, {wxSplitterEvent, setSashPosition, 1}},
- {3491, {wxHtmlWindow, new_0, 0}},
- {3492, {wxHtmlWindow, new_2, 2}},
- {3493, {wxHtmlWindow, appendToPage, 1}},
- {3494, {wxHtmlWindow, getOpenedAnchor, 0}},
- {3495, {wxHtmlWindow, getOpenedPage, 0}},
- {3496, {wxHtmlWindow, getOpenedPageTitle, 0}},
- {3497, {wxHtmlWindow, getRelatedFrame, 0}},
- {3498, {wxHtmlWindow, historyBack, 0}},
- {3499, {wxHtmlWindow, historyCanBack, 0}},
- {3500, {wxHtmlWindow, historyCanForward, 0}},
- {3501, {wxHtmlWindow, historyClear, 0}},
- {3502, {wxHtmlWindow, historyForward, 0}},
- {3503, {wxHtmlWindow, loadFile, 1}},
- {3504, {wxHtmlWindow, loadPage, 1}},
- {3505, {wxHtmlWindow, selectAll, 0}},
- {3506, {wxHtmlWindow, selectionToText, 0}},
- {3507, {wxHtmlWindow, selectLine, 1}},
- {3508, {wxHtmlWindow, selectWord, 1}},
- {3509, {wxHtmlWindow, setBorders, 1}},
- {3510, {wxHtmlWindow, setFonts, 3}},
- {3511, {wxHtmlWindow, setPage, 1}},
- {3512, {wxHtmlWindow, setRelatedFrame, 2}},
- {3513, {wxHtmlWindow, setRelatedStatusBar, 1}},
- {3514, {wxHtmlWindow, toText, 0}},
- {3515, {wxHtmlWindow, 'Destroy', undefined}},
- {3516, {wxHtmlLinkEvent, getLinkInfo, 0}},
- {3517, {wxSystemSettings, getColour, 1}},
- {3518, {wxSystemSettings, getFont, 1}},
- {3519, {wxSystemSettings, getMetric, 2}},
- {3520, {wxSystemSettings, getScreenType, 0}},
- {3521, {wxSystemOptions, getOption, 1}},
- {3522, {wxSystemOptions, getOptionInt, 1}},
- {3523, {wxSystemOptions, hasOption, 1}},
- {3524, {wxSystemOptions, isFalse, 1}},
- {3525, {wxSystemOptions, setOption_2_1, 2}},
- {3526, {wxSystemOptions, setOption_2_0, 2}},
- {3527, {wxAuiNotebookEvent, setSelection, 1}},
- {3528, {wxAuiNotebookEvent, getSelection, 0}},
- {3529, {wxAuiNotebookEvent, setOldSelection, 1}},
- {3530, {wxAuiNotebookEvent, getOldSelection, 0}},
- {3531, {wxAuiNotebookEvent, setDragSource, 1}},
- {3532, {wxAuiNotebookEvent, getDragSource, 0}},
- {3533, {wxAuiManagerEvent, setManager, 1}},
- {3534, {wxAuiManagerEvent, getManager, 0}},
- {3535, {wxAuiManagerEvent, setPane, 1}},
- {3536, {wxAuiManagerEvent, getPane, 0}},
- {3537, {wxAuiManagerEvent, setButton, 1}},
- {3538, {wxAuiManagerEvent, getButton, 0}},
- {3539, {wxAuiManagerEvent, setDC, 1}},
- {3540, {wxAuiManagerEvent, getDC, 0}},
- {3541, {wxAuiManagerEvent, veto, 1}},
- {3542, {wxAuiManagerEvent, getVeto, 0}},
- {3543, {wxAuiManagerEvent, setCanVeto, 1}},
- {3544, {wxAuiManagerEvent, canVeto, 0}},
- {3545, {wxLogNull, new, 0}},
- {3546, {wxLogNull, 'Destroy', undefined}},
- {3547, {wxTaskBarIcon, new, 0}},
- {3548, {wxTaskBarIcon, destruct, 0}},
- {3549, {wxTaskBarIcon, popupMenu, 1}},
- {3550, {wxTaskBarIcon, removeIcon, 0}},
- {3551, {wxTaskBarIcon, setIcon, 2}},
- {3552, {wxLocale, new_0, 0}},
- {3554, {wxLocale, new_2, 2}},
- {3555, {wxLocale, destruct, 0}},
- {3557, {wxLocale, init, 1}},
- {3558, {wxLocale, addCatalog_1, 1}},
- {3559, {wxLocale, addCatalog_3, 3}},
- {3560, {wxLocale, addCatalogLookupPathPrefix, 1}},
- {3561, {wxLocale, getCanonicalName, 0}},
- {3562, {wxLocale, getLanguage, 0}},
- {3563, {wxLocale, getLanguageName, 1}},
- {3564, {wxLocale, getLocale, 0}},
- {3565, {wxLocale, getName, 0}},
- {3566, {wxLocale, getString_2, 2}},
- {3567, {wxLocale, getString_4, 4}},
- {3568, {wxLocale, getHeaderValue, 2}},
- {3569, {wxLocale, getSysName, 0}},
- {3570, {wxLocale, getSystemEncoding, 0}},
- {3571, {wxLocale, getSystemEncodingName, 0}},
- {3572, {wxLocale, getSystemLanguage, 0}},
- {3573, {wxLocale, isLoaded, 1}},
- {3574, {wxLocale, isOk, 0}},
- {3575, {wxActivateEvent, getActive, 0}},
- {3577, {wxPopupWindow, new_2, 2}},
- {3578, {wxPopupWindow, new_0, 0}},
- {3580, {wxPopupWindow, destruct, 0}},
- {3581, {wxPopupWindow, create, 2}},
- {3582, {wxPopupWindow, position, 2}},
- {3583, {wxPopupTransientWindow, new_0, 0}},
- {3584, {wxPopupTransientWindow, new_2, 2}},
- {3585, {wxPopupTransientWindow, destruct, 0}},
- {3586, {wxPopupTransientWindow, popup, 1}},
- {3587, {wxPopupTransientWindow, dismiss, 0}},
- {3588, {wxOverlay, new, 0}},
- {3589, {wxOverlay, destruct, 0}},
- {3590, {wxOverlay, reset, 0}},
- {3591, {wxDCOverlay, new_6, 6}},
- {3592, {wxDCOverlay, new_2, 2}},
- {3593, {wxDCOverlay, destruct, 0}},
- {3594, {wxDCOverlay, clear, 0}},
+ {126, {wxWindow, dragAcceptFiles, 1}},
+ {127, {wxWindow, enable, 1}},
+ {128, {wxWindow, findFocus, 0}},
+ {129, {wxWindow, findWindow_1_0, 1}},
+ {130, {wxWindow, findWindow_1_1, 1}},
+ {131, {wxWindow, findWindowById, 2}},
+ {132, {wxWindow, findWindowByName, 2}},
+ {133, {wxWindow, findWindowByLabel, 2}},
+ {134, {wxWindow, fit, 0}},
+ {135, {wxWindow, fitInside, 0}},
+ {136, {wxWindow, freeze, 0}},
+ {137, {wxWindow, getAcceleratorTable, 0}},
+ {138, {wxWindow, getBackgroundColour, 0}},
+ {139, {wxWindow, getBackgroundStyle, 0}},
+ {140, {wxWindow, getBestSize, 0}},
+ {142, {wxWindow, getCaret, 0}},
+ {143, {wxWindow, getCapture, 0}},
+ {144, {wxWindow, getCharHeight, 0}},
+ {145, {wxWindow, getCharWidth, 0}},
+ {146, {wxWindow, getChildren, 0}},
+ {149, {wxWindow, getClientSize, 0}},
+ {150, {wxWindow, getContainingSizer, 0}},
+ {151, {wxWindow, getCursor, 0}},
+ {152, {wxWindow, getDropTarget, 0}},
+ {153, {wxWindow, getEventHandler, 0}},
+ {154, {wxWindow, getExtraStyle, 0}},
+ {155, {wxWindow, getFont, 0}},
+ {156, {wxWindow, getForegroundColour, 0}},
+ {157, {wxWindow, getGrandParent, 0}},
+ {158, {wxWindow, getHandle, 0}},
+ {159, {wxWindow, getHelpText, 0}},
+ {160, {wxWindow, getId, 0}},
+ {161, {wxWindow, getLabel, 0}},
+ {162, {wxWindow, getMaxSize, 0}},
+ {163, {wxWindow, getMinSize, 0}},
+ {164, {wxWindow, getName, 0}},
+ {165, {wxWindow, getParent, 0}},
+ {167, {wxWindow, getPosition, 0}},
+ {168, {wxWindow, getRect, 0}},
+ {170, {wxWindow, getScreenPosition, 0}},
+ {171, {wxWindow, getScreenRect, 0}},
+ {172, {wxWindow, getScrollPos, 1}},
+ {173, {wxWindow, getScrollRange, 1}},
+ {174, {wxWindow, getScrollThumb, 1}},
+ {176, {wxWindow, getSize, 0}},
+ {177, {wxWindow, getSizer, 0}},
+ {178, {wxWindow, getTextExtent, 4}},
+ {179, {wxWindow, getToolTip, 0}},
+ {180, {wxWindow, getUpdateRegion, 0}},
+ {182, {wxWindow, getVirtualSize, 0}},
+ {184, {wxWindow, getWindowStyleFlag, 0}},
+ {185, {wxWindow, getWindowVariant, 0}},
+ {186, {wxWindow, hasCapture, 0}},
+ {187, {wxWindow, hasScrollbar, 1}},
+ {188, {wxWindow, hasTransparentBackground, 0}},
+ {189, {wxWindow, hide, 0}},
+ {190, {wxWindow, inheritAttributes, 0}},
+ {191, {wxWindow, initDialog, 0}},
+ {192, {wxWindow, invalidateBestSize, 0}},
+ {193, {wxWindow, isEnabled, 0}},
+ {194, {wxWindow, isExposed_2, 2}},
+ {195, {wxWindow, isExposed_4, 4}},
+ {196, {wxWindow, isExposed_1_0, 1}},
+ {197, {wxWindow, isExposed_1_1, 1}},
+ {198, {wxWindow, isRetained, 0}},
+ {199, {wxWindow, isShown, 0}},
+ {200, {wxWindow, isTopLevel, 0}},
+ {201, {wxWindow, layout, 0}},
+ {202, {wxWindow, lineDown, 0}},
+ {203, {wxWindow, lineUp, 0}},
+ {204, {wxWindow, lower, 0}},
+ {205, {wxWindow, makeModal, 1}},
+ {206, {wxWindow, move_3, 3}},
+ {207, {wxWindow, move_2, 2}},
+ {208, {wxWindow, moveAfterInTabOrder, 1}},
+ {209, {wxWindow, moveBeforeInTabOrder, 1}},
+ {210, {wxWindow, navigate, 1}},
+ {211, {wxWindow, pageDown, 0}},
+ {212, {wxWindow, pageUp, 0}},
+ {213, {wxWindow, popEventHandler, 1}},
+ {214, {wxWindow, popupMenu_2, 2}},
+ {215, {wxWindow, popupMenu_3, 3}},
+ {216, {wxWindow, raise, 0}},
+ {217, {wxWindow, refresh, 1}},
+ {218, {wxWindow, refreshRect, 2}},
+ {219, {wxWindow, releaseMouse, 0}},
+ {220, {wxWindow, removeChild, 1}},
+ {221, {wxWindow, reparent, 1}},
+ {222, {wxWindow, screenToClient_2, 2}},
+ {223, {wxWindow, screenToClient_1, 1}},
+ {225, {wxWindow, scrollLines, 1}},
+ {227, {wxWindow, scrollPages, 1}},
+ {228, {wxWindow, scrollWindow, 3}},
+ {229, {wxWindow, setAcceleratorTable, 1}},
+ {230, {wxWindow, setAutoLayout, 1}},
+ {231, {wxWindow, setBackgroundColour, 1}},
+ {232, {wxWindow, setBackgroundStyle, 1}},
+ {233, {wxWindow, setCaret, 1}},
+ {234, {wxWindow, setClientSize_2, 2}},
+ {235, {wxWindow, setClientSize_1_0, 1}},
+ {236, {wxWindow, setClientSize_1_1, 1}},
+ {237, {wxWindow, setContainingSizer, 1}},
+ {238, {wxWindow, setCursor, 1}},
+ {239, {wxWindow, setMaxSize, 1}},
+ {240, {wxWindow, setMinSize, 1}},
+ {241, {wxWindow, setOwnBackgroundColour, 1}},
+ {242, {wxWindow, setOwnFont, 1}},
+ {243, {wxWindow, setOwnForegroundColour, 1}},
+ {244, {wxWindow, setDropTarget, 1}},
+ {245, {wxWindow, setExtraStyle, 1}},
+ {246, {wxWindow, setFocus, 0}},
+ {247, {wxWindow, setFocusFromKbd, 0}},
+ {248, {wxWindow, setFont, 1}},
+ {249, {wxWindow, setForegroundColour, 1}},
+ {250, {wxWindow, setHelpText, 1}},
+ {251, {wxWindow, setId, 1}},
+ {253, {wxWindow, setLabel, 1}},
+ {254, {wxWindow, setName, 1}},
+ {255, {wxWindow, setPalette, 1}},
+ {256, {wxWindow, setScrollbar, 5}},
+ {257, {wxWindow, setScrollPos, 3}},
+ {258, {wxWindow, setSize_5, 5}},
+ {259, {wxWindow, setSize_2_0, 2}},
+ {260, {wxWindow, setSize_1, 1}},
+ {261, {wxWindow, setSize_2_1, 2}},
+ {262, {wxWindow, setSizeHints_3, 3}},
+ {263, {wxWindow, setSizeHints_2, 2}},
+ {264, {wxWindow, setSizer, 2}},
+ {265, {wxWindow, setSizerAndFit, 2}},
+ {266, {wxWindow, setThemeEnabled, 1}},
+ {267, {wxWindow, setToolTip_1_0, 1}},
+ {268, {wxWindow, setToolTip_1_1, 1}},
+ {269, {wxWindow, setVirtualSize_1, 1}},
+ {270, {wxWindow, setVirtualSize_2, 2}},
+ {271, {wxWindow, setVirtualSizeHints_3, 3}},
+ {272, {wxWindow, setVirtualSizeHints_2, 2}},
+ {273, {wxWindow, setWindowStyle, 1}},
+ {274, {wxWindow, setWindowStyleFlag, 1}},
+ {275, {wxWindow, setWindowVariant, 1}},
+ {276, {wxWindow, shouldInheritColours, 0}},
+ {277, {wxWindow, show, 1}},
+ {278, {wxWindow, thaw, 0}},
+ {279, {wxWindow, transferDataFromWindow, 0}},
+ {280, {wxWindow, transferDataToWindow, 0}},
+ {281, {wxWindow, update, 0}},
+ {282, {wxWindow, updateWindowUI, 1}},
+ {283, {wxWindow, validate, 0}},
+ {284, {wxWindow, warpPointer, 2}},
+ {285, {wxWindow, setTransparent, 1}},
+ {286, {wxWindow, canSetTransparent, 0}},
+ {287, {wxWindow, isDoubleBuffered, 0}},
+ {288, {wxWindow, setDoubleBuffered, 1}},
+ {289, {wxWindow, getContentScaleFactor, 0}},
+ {290, {wxTopLevelWindow, getIcon, 0}},
+ {291, {wxTopLevelWindow, getIcons, 0}},
+ {292, {wxTopLevelWindow, getTitle, 0}},
+ {293, {wxTopLevelWindow, isActive, 0}},
+ {294, {wxTopLevelWindow, iconize, 1}},
+ {295, {wxTopLevelWindow, isFullScreen, 0}},
+ {296, {wxTopLevelWindow, isIconized, 0}},
+ {297, {wxTopLevelWindow, isMaximized, 0}},
+ {298, {wxTopLevelWindow, maximize, 1}},
+ {299, {wxTopLevelWindow, requestUserAttention, 1}},
+ {300, {wxTopLevelWindow, setIcon, 1}},
+ {301, {wxTopLevelWindow, setIcons, 1}},
+ {302, {wxTopLevelWindow, centerOnScreen, 1}},
+ {303, {wxTopLevelWindow, centreOnScreen, 1}},
+ {305, {wxTopLevelWindow, setShape, 1}},
+ {306, {wxTopLevelWindow, setTitle, 1}},
+ {307, {wxTopLevelWindow, showFullScreen, 2}},
+ {309, {wxFrame, new_4, 4}},
+ {310, {wxFrame, new_0, 0}},
+ {312, {wxFrame, destruct, 0}},
+ {313, {wxFrame, create, 4}},
+ {314, {wxFrame, createStatusBar, 1}},
+ {315, {wxFrame, createToolBar, 1}},
+ {316, {wxFrame, getClientAreaOrigin, 0}},
+ {317, {wxFrame, getMenuBar, 0}},
+ {318, {wxFrame, getStatusBar, 0}},
+ {319, {wxFrame, getStatusBarPane, 0}},
+ {320, {wxFrame, getToolBar, 0}},
+ {321, {wxFrame, processCommand, 1}},
+ {322, {wxFrame, sendSizeEvent, 0}},
+ {323, {wxFrame, setMenuBar, 1}},
+ {324, {wxFrame, setStatusBar, 1}},
+ {325, {wxFrame, setStatusBarPane, 1}},
+ {326, {wxFrame, setStatusText, 2}},
+ {327, {wxFrame, setStatusWidths, 2}},
+ {328, {wxFrame, setToolBar, 1}},
+ {329, {wxMiniFrame, new_0, 0}},
+ {330, {wxMiniFrame, new_4, 4}},
+ {331, {wxMiniFrame, create, 4}},
+ {332, {wxMiniFrame, 'Destroy', undefined}},
+ {333, {wxSplashScreen, new_0, 0}},
+ {334, {wxSplashScreen, new_6, 6}},
+ {335, {wxSplashScreen, destruct, 0}},
+ {336, {wxSplashScreen, getSplashStyle, 0}},
+ {337, {wxSplashScreen, getTimeout, 0}},
+ {338, {wxPanel, new_0, 0}},
+ {339, {wxPanel, new_6, 6}},
+ {340, {wxPanel, new_2, 2}},
+ {341, {wxPanel, destruct, 0}},
+ {342, {wxPanel, initDialog, 0}},
+ {343, {wxPanel, setFocusIgnoringChildren, 0}},
+ {344, {wxScrolledWindow, new_0, 0}},
+ {345, {wxScrolledWindow, new_2, 2}},
+ {346, {wxScrolledWindow, destruct, 0}},
+ {347, {wxScrolledWindow, calcScrolledPosition_4, 4}},
+ {348, {wxScrolledWindow, calcScrolledPosition_1, 1}},
+ {349, {wxScrolledWindow, calcUnscrolledPosition_4, 4}},
+ {350, {wxScrolledWindow, calcUnscrolledPosition_1, 1}},
+ {351, {wxScrolledWindow, enableScrolling, 2}},
+ {352, {wxScrolledWindow, getScrollPixelsPerUnit, 2}},
+ {353, {wxScrolledWindow, getViewStart, 2}},
+ {354, {wxScrolledWindow, doPrepareDC, 1}},
+ {355, {wxScrolledWindow, prepareDC, 1}},
+ {356, {wxScrolledWindow, scroll, 2}},
+ {357, {wxScrolledWindow, setScrollbars, 5}},
+ {358, {wxScrolledWindow, setScrollRate, 2}},
+ {359, {wxScrolledWindow, setTargetWindow, 1}},
+ {360, {wxSashWindow, new_0, 0}},
+ {361, {wxSashWindow, new_2, 2}},
+ {362, {wxSashWindow, destruct, 0}},
+ {363, {wxSashWindow, getSashVisible, 1}},
+ {364, {wxSashWindow, getMaximumSizeX, 0}},
+ {365, {wxSashWindow, getMaximumSizeY, 0}},
+ {366, {wxSashWindow, getMinimumSizeX, 0}},
+ {367, {wxSashWindow, getMinimumSizeY, 0}},
+ {368, {wxSashWindow, setMaximumSizeX, 1}},
+ {369, {wxSashWindow, setMaximumSizeY, 1}},
+ {370, {wxSashWindow, setMinimumSizeX, 1}},
+ {371, {wxSashWindow, setMinimumSizeY, 1}},
+ {372, {wxSashWindow, setSashVisible, 2}},
+ {373, {wxSashLayoutWindow, new_0, 0}},
+ {374, {wxSashLayoutWindow, new_2, 2}},
+ {375, {wxSashLayoutWindow, create, 2}},
+ {376, {wxSashLayoutWindow, getAlignment, 0}},
+ {377, {wxSashLayoutWindow, getOrientation, 0}},
+ {378, {wxSashLayoutWindow, setAlignment, 1}},
+ {379, {wxSashLayoutWindow, setDefaultSize, 1}},
+ {380, {wxSashLayoutWindow, setOrientation, 1}},
+ {381, {wxSashLayoutWindow, 'Destroy', undefined}},
+ {382, {wxGrid, new_0, 0}},
+ {383, {wxGrid, new_3, 3}},
+ {384, {wxGrid, new_4, 4}},
+ {385, {wxGrid, destruct, 0}},
+ {386, {wxGrid, appendCols, 1}},
+ {387, {wxGrid, appendRows, 1}},
+ {388, {wxGrid, autoSize, 0}},
+ {389, {wxGrid, autoSizeColumn, 2}},
+ {390, {wxGrid, autoSizeColumns, 1}},
+ {391, {wxGrid, autoSizeRow, 2}},
+ {392, {wxGrid, autoSizeRows, 1}},
+ {393, {wxGrid, beginBatch, 0}},
+ {394, {wxGrid, blockToDeviceRect, 2}},
+ {395, {wxGrid, canDragColSize, 0}},
+ {396, {wxGrid, canDragRowSize, 0}},
+ {397, {wxGrid, canDragGridSize, 0}},
+ {398, {wxGrid, canEnableCellControl, 0}},
+ {399, {wxGrid, cellToRect_2, 2}},
+ {400, {wxGrid, cellToRect_1, 1}},
+ {401, {wxGrid, clearGrid, 0}},
+ {402, {wxGrid, clearSelection, 0}},
+ {403, {wxGrid, createGrid, 3}},
+ {404, {wxGrid, deleteCols, 1}},
+ {405, {wxGrid, deleteRows, 1}},
+ {406, {wxGrid, disableCellEditControl, 0}},
+ {407, {wxGrid, disableDragColSize, 0}},
+ {408, {wxGrid, disableDragGridSize, 0}},
+ {409, {wxGrid, disableDragRowSize, 0}},
+ {410, {wxGrid, enableCellEditControl, 1}},
+ {411, {wxGrid, enableDragColSize, 1}},
+ {412, {wxGrid, enableDragGridSize, 1}},
+ {413, {wxGrid, enableDragRowSize, 1}},
+ {414, {wxGrid, enableEditing, 1}},
+ {415, {wxGrid, enableGridLines, 1}},
+ {416, {wxGrid, endBatch, 0}},
+ {417, {wxGrid, fit, 0}},
+ {418, {wxGrid, forceRefresh, 0}},
+ {419, {wxGrid, getBatchCount, 0}},
+ {420, {wxGrid, getCellAlignment, 4}},
+ {421, {wxGrid, getCellBackgroundColour, 2}},
+ {422, {wxGrid, getCellEditor, 2}},
+ {423, {wxGrid, getCellFont, 2}},
+ {424, {wxGrid, getCellRenderer, 2}},
+ {425, {wxGrid, getCellTextColour, 2}},
+ {426, {wxGrid, getCellValue_2, 2}},
+ {427, {wxGrid, getCellValue_1, 1}},
+ {428, {wxGrid, getColLabelAlignment, 2}},
+ {429, {wxGrid, getColLabelSize, 0}},
+ {430, {wxGrid, getColLabelValue, 1}},
+ {431, {wxGrid, getColMinimalAcceptableWidth, 0}},
+ {432, {wxGrid, getDefaultCellAlignment, 2}},
+ {433, {wxGrid, getDefaultCellBackgroundColour, 0}},
+ {434, {wxGrid, getDefaultCellFont, 0}},
+ {435, {wxGrid, getDefaultCellTextColour, 0}},
+ {436, {wxGrid, getDefaultColLabelSize, 0}},
+ {437, {wxGrid, getDefaultColSize, 0}},
+ {438, {wxGrid, getDefaultEditor, 0}},
+ {439, {wxGrid, getDefaultEditorForCell_2, 2}},
+ {440, {wxGrid, getDefaultEditorForCell_1, 1}},
+ {441, {wxGrid, getDefaultEditorForType, 1}},
+ {442, {wxGrid, getDefaultRenderer, 0}},
+ {443, {wxGrid, getDefaultRendererForCell, 2}},
+ {444, {wxGrid, getDefaultRendererForType, 1}},
+ {445, {wxGrid, getDefaultRowLabelSize, 0}},
+ {446, {wxGrid, getDefaultRowSize, 0}},
+ {447, {wxGrid, getGridCursorCol, 0}},
+ {448, {wxGrid, getGridCursorRow, 0}},
+ {449, {wxGrid, getGridLineColour, 0}},
+ {450, {wxGrid, gridLinesEnabled, 0}},
+ {451, {wxGrid, getLabelBackgroundColour, 0}},
+ {452, {wxGrid, getLabelFont, 0}},
+ {453, {wxGrid, getLabelTextColour, 0}},
+ {454, {wxGrid, getNumberCols, 0}},
+ {455, {wxGrid, getNumberRows, 0}},
+ {456, {wxGrid, getOrCreateCellAttr, 2}},
+ {457, {wxGrid, getRowMinimalAcceptableHeight, 0}},
+ {458, {wxGrid, getRowLabelAlignment, 2}},
+ {459, {wxGrid, getRowLabelSize, 0}},
+ {460, {wxGrid, getRowLabelValue, 1}},
+ {461, {wxGrid, getRowSize, 1}},
+ {462, {wxGrid, getScrollLineX, 0}},
+ {463, {wxGrid, getScrollLineY, 0}},
+ {464, {wxGrid, getSelectedCells, 0}},
+ {465, {wxGrid, getSelectedCols, 0}},
+ {466, {wxGrid, getSelectedRows, 0}},
+ {467, {wxGrid, getSelectionBackground, 0}},
+ {468, {wxGrid, getSelectionBlockTopLeft, 0}},
+ {469, {wxGrid, getSelectionBlockBottomRight, 0}},
+ {470, {wxGrid, getSelectionForeground, 0}},
+ {471, {wxGrid, getViewWidth, 0}},
+ {472, {wxGrid, getGridWindow, 0}},
+ {473, {wxGrid, getGridRowLabelWindow, 0}},
+ {474, {wxGrid, getGridColLabelWindow, 0}},
+ {475, {wxGrid, getGridCornerLabelWindow, 0}},
+ {476, {wxGrid, hideCellEditControl, 0}},
+ {477, {wxGrid, insertCols, 1}},
+ {478, {wxGrid, insertRows, 1}},
+ {479, {wxGrid, isCellEditControlEnabled, 0}},
+ {480, {wxGrid, isCurrentCellReadOnly, 0}},
+ {481, {wxGrid, isEditable, 0}},
+ {482, {wxGrid, isInSelection_2, 2}},
+ {483, {wxGrid, isInSelection_1, 1}},
+ {484, {wxGrid, isReadOnly, 2}},
+ {485, {wxGrid, isSelection, 0}},
+ {486, {wxGrid, isVisible_3, 3}},
+ {487, {wxGrid, isVisible_2, 2}},
+ {488, {wxGrid, makeCellVisible_2, 2}},
+ {489, {wxGrid, makeCellVisible_1, 1}},
+ {490, {wxGrid, moveCursorDown, 1}},
+ {491, {wxGrid, moveCursorLeft, 1}},
+ {492, {wxGrid, moveCursorRight, 1}},
+ {493, {wxGrid, moveCursorUp, 1}},
+ {494, {wxGrid, moveCursorDownBlock, 1}},
+ {495, {wxGrid, moveCursorLeftBlock, 1}},
+ {496, {wxGrid, moveCursorRightBlock, 1}},
+ {497, {wxGrid, moveCursorUpBlock, 1}},
+ {498, {wxGrid, movePageDown, 0}},
+ {499, {wxGrid, movePageUp, 0}},
+ {500, {wxGrid, registerDataType, 3}},
+ {501, {wxGrid, saveEditControlValue, 0}},
+ {502, {wxGrid, selectAll, 0}},
+ {503, {wxGrid, selectBlock_5, 5}},
+ {504, {wxGrid, selectBlock_3, 3}},
+ {505, {wxGrid, selectCol, 2}},
+ {506, {wxGrid, selectRow, 2}},
+ {507, {wxGrid, setCellAlignment_4, 4}},
+ {508, {wxGrid, setCellAlignment_3, 3}},
+ {509, {wxGrid, setCellAlignment_1, 1}},
+ {510, {wxGrid, setCellBackgroundColour_3_0, 3}},
+ {511, {wxGrid, setCellBackgroundColour_1, 1}},
+ {512, {wxGrid, setCellBackgroundColour_3_1, 3}},
+ {513, {wxGrid, setCellEditor, 3}},
+ {514, {wxGrid, setCellFont, 3}},
+ {515, {wxGrid, setCellRenderer, 3}},
+ {516, {wxGrid, setCellTextColour_3_0, 3}},
+ {517, {wxGrid, setCellTextColour_3_1, 3}},
+ {518, {wxGrid, setCellTextColour_1, 1}},
+ {519, {wxGrid, setCellValue_3_0, 3}},
+ {520, {wxGrid, setCellValue_2, 2}},
+ {521, {wxGrid, setCellValue_3_1, 3}},
+ {522, {wxGrid, setColAttr, 2}},
+ {523, {wxGrid, setColFormatBool, 1}},
+ {524, {wxGrid, setColFormatNumber, 1}},
+ {525, {wxGrid, setColFormatFloat, 2}},
+ {526, {wxGrid, setColFormatCustom, 2}},
+ {527, {wxGrid, setColLabelAlignment, 2}},
+ {528, {wxGrid, setColLabelSize, 1}},
+ {529, {wxGrid, setColLabelValue, 2}},
+ {530, {wxGrid, setColMinimalWidth, 2}},
+ {531, {wxGrid, setColMinimalAcceptableWidth, 1}},
+ {532, {wxGrid, setColSize, 2}},
+ {533, {wxGrid, setDefaultCellAlignment, 2}},
+ {534, {wxGrid, setDefaultCellBackgroundColour, 1}},
+ {535, {wxGrid, setDefaultCellFont, 1}},
+ {536, {wxGrid, setDefaultCellTextColour, 1}},
+ {537, {wxGrid, setDefaultEditor, 1}},
+ {538, {wxGrid, setDefaultRenderer, 1}},
+ {539, {wxGrid, setDefaultColSize, 2}},
+ {540, {wxGrid, setDefaultRowSize, 2}},
+ {541, {wxGrid, setGridCursor, 2}},
+ {542, {wxGrid, setGridLineColour, 1}},
+ {543, {wxGrid, setLabelBackgroundColour, 1}},
+ {544, {wxGrid, setLabelFont, 1}},
+ {545, {wxGrid, setLabelTextColour, 1}},
+ {546, {wxGrid, setMargins, 2}},
+ {547, {wxGrid, setReadOnly, 3}},
+ {548, {wxGrid, setRowAttr, 2}},
+ {549, {wxGrid, setRowLabelAlignment, 2}},
+ {550, {wxGrid, setRowLabelSize, 1}},
+ {551, {wxGrid, setRowLabelValue, 2}},
+ {552, {wxGrid, setRowMinimalHeight, 2}},
+ {553, {wxGrid, setRowMinimalAcceptableHeight, 1}},
+ {554, {wxGrid, setRowSize, 2}},
+ {555, {wxGrid, setScrollLineX, 1}},
+ {556, {wxGrid, setScrollLineY, 1}},
+ {557, {wxGrid, setSelectionBackground, 1}},
+ {558, {wxGrid, setSelectionForeground, 1}},
+ {559, {wxGrid, setSelectionMode, 1}},
+ {560, {wxGrid, showCellEditControl, 0}},
+ {561, {wxGrid, xToCol, 2}},
+ {562, {wxGrid, xToEdgeOfCol, 1}},
+ {563, {wxGrid, yToEdgeOfRow, 1}},
+ {564, {wxGrid, yToRow, 1}},
+ {565, {wxGridCellRenderer, draw, 7}},
+ {566, {wxGridCellRenderer, getBestSize, 5}},
+ {567, {wxGridCellEditor, create, 3}},
+ {568, {wxGridCellEditor, isCreated, 0}},
+ {569, {wxGridCellEditor, setSize, 1}},
+ {570, {wxGridCellEditor, show, 2}},
+ {571, {wxGridCellEditor, paintBackground, 2}},
+ {572, {wxGridCellEditor, beginEdit, 3}},
+ {573, {wxGridCellEditor, endEdit, 3}},
+ {574, {wxGridCellEditor, reset, 0}},
+ {575, {wxGridCellEditor, startingKey, 1}},
+ {576, {wxGridCellEditor, startingClick, 0}},
+ {577, {wxGridCellEditor, handleReturn, 1}},
+ {578, {wxGridCellBoolRenderer, new, 0}},
+ {579, {wxGridCellBoolRenderer, 'Destroy', undefined}},
+ {580, {wxGridCellBoolEditor, new, 0}},
+ {581, {wxGridCellBoolEditor, isTrueValue, 1}},
+ {582, {wxGridCellBoolEditor, useStringValues, 1}},
+ {583, {wxGridCellBoolEditor, 'Destroy', undefined}},
+ {584, {wxGridCellFloatRenderer, new, 1}},
+ {585, {wxGridCellFloatRenderer, getPrecision, 0}},
+ {586, {wxGridCellFloatRenderer, getWidth, 0}},
+ {587, {wxGridCellFloatRenderer, setParameters, 1}},
+ {588, {wxGridCellFloatRenderer, setPrecision, 1}},
+ {589, {wxGridCellFloatRenderer, setWidth, 1}},
+ {590, {wxGridCellFloatRenderer, 'Destroy', undefined}},
+ {591, {wxGridCellFloatEditor, new, 1}},
+ {592, {wxGridCellFloatEditor, setParameters, 1}},
+ {593, {wxGridCellFloatEditor, 'Destroy', undefined}},
+ {594, {wxGridCellStringRenderer, new, 0}},
+ {595, {wxGridCellStringRenderer, 'Destroy', undefined}},
+ {596, {wxGridCellTextEditor, new, 0}},
+ {597, {wxGridCellTextEditor, setParameters, 1}},
+ {598, {wxGridCellTextEditor, 'Destroy', undefined}},
+ {600, {wxGridCellChoiceEditor, new, 2}},
+ {601, {wxGridCellChoiceEditor, setParameters, 1}},
+ {602, {wxGridCellChoiceEditor, 'Destroy', undefined}},
+ {603, {wxGridCellNumberRenderer, new, 0}},
+ {604, {wxGridCellNumberRenderer, 'Destroy', undefined}},
+ {605, {wxGridCellNumberEditor, new, 1}},
+ {606, {wxGridCellNumberEditor, getValue, 0}},
+ {607, {wxGridCellNumberEditor, setParameters, 1}},
+ {608, {wxGridCellNumberEditor, 'Destroy', undefined}},
+ {609, {wxGridCellAttr, setTextColour, 1}},
+ {610, {wxGridCellAttr, setBackgroundColour, 1}},
+ {611, {wxGridCellAttr, setFont, 1}},
+ {612, {wxGridCellAttr, setAlignment, 2}},
+ {613, {wxGridCellAttr, setReadOnly, 1}},
+ {614, {wxGridCellAttr, setRenderer, 1}},
+ {615, {wxGridCellAttr, setEditor, 1}},
+ {616, {wxGridCellAttr, hasTextColour, 0}},
+ {617, {wxGridCellAttr, hasBackgroundColour, 0}},
+ {618, {wxGridCellAttr, hasFont, 0}},
+ {619, {wxGridCellAttr, hasAlignment, 0}},
+ {620, {wxGridCellAttr, hasRenderer, 0}},
+ {621, {wxGridCellAttr, hasEditor, 0}},
+ {622, {wxGridCellAttr, getTextColour, 0}},
+ {623, {wxGridCellAttr, getBackgroundColour, 0}},
+ {624, {wxGridCellAttr, getFont, 0}},
+ {625, {wxGridCellAttr, getAlignment, 2}},
+ {626, {wxGridCellAttr, getRenderer, 3}},
+ {627, {wxGridCellAttr, getEditor, 3}},
+ {628, {wxGridCellAttr, isReadOnly, 0}},
+ {629, {wxGridCellAttr, setDefAttr, 1}},
+ {630, {wxDC, blit, 5}},
+ {631, {wxDC, calcBoundingBox, 2}},
+ {632, {wxDC, clear, 0}},
+ {633, {wxDC, computeScaleAndOrigin, 0}},
+ {634, {wxDC, crossHair, 1}},
+ {635, {wxDC, destroyClippingRegion, 0}},
+ {636, {wxDC, deviceToLogicalX, 1}},
+ {637, {wxDC, deviceToLogicalXRel, 1}},
+ {638, {wxDC, deviceToLogicalY, 1}},
+ {639, {wxDC, deviceToLogicalYRel, 1}},
+ {640, {wxDC, drawArc, 3}},
+ {641, {wxDC, drawBitmap, 3}},
+ {642, {wxDC, drawCheckMark, 1}},
+ {643, {wxDC, drawCircle, 2}},
+ {645, {wxDC, drawEllipse_2, 2}},
+ {646, {wxDC, drawEllipse_1, 1}},
+ {647, {wxDC, drawEllipticArc, 4}},
+ {648, {wxDC, drawIcon, 2}},
+ {649, {wxDC, drawLabel, 3}},
+ {650, {wxDC, drawLine, 2}},
+ {651, {wxDC, drawLines, 3}},
+ {653, {wxDC, drawPolygon, 3}},
+ {655, {wxDC, drawPoint, 1}},
+ {657, {wxDC, drawRectangle_2, 2}},
+ {658, {wxDC, drawRectangle_1, 1}},
+ {659, {wxDC, drawRotatedText, 3}},
+ {661, {wxDC, drawRoundedRectangle_3, 3}},
+ {662, {wxDC, drawRoundedRectangle_2, 2}},
+ {663, {wxDC, drawText, 2}},
+ {664, {wxDC, endDoc, 0}},
+ {665, {wxDC, endPage, 0}},
+ {666, {wxDC, floodFill, 3}},
+ {667, {wxDC, getBackground, 0}},
+ {668, {wxDC, getBackgroundMode, 0}},
+ {669, {wxDC, getBrush, 0}},
+ {670, {wxDC, getCharHeight, 0}},
+ {671, {wxDC, getCharWidth, 0}},
+ {672, {wxDC, getClippingBox, 4}},
+ {674, {wxDC, getFont, 0}},
+ {675, {wxDC, getLayoutDirection, 0}},
+ {676, {wxDC, getLogicalFunction, 0}},
+ {677, {wxDC, getMapMode, 0}},
+ {678, {wxDC, getMultiLineTextExtent_4, 4}},
+ {679, {wxDC, getMultiLineTextExtent_1, 1}},
+ {680, {wxDC, getPartialTextExtents, 2}},
+ {681, {wxDC, getPen, 0}},
+ {682, {wxDC, getPixel, 2}},
+ {683, {wxDC, getPPI, 0}},
+ {685, {wxDC, getSize, 0}},
+ {687, {wxDC, getSizeMM, 0}},
+ {688, {wxDC, getTextBackground, 0}},
+ {689, {wxDC, getTextExtent_4, 4}},
+ {690, {wxDC, getTextExtent_1, 1}},
+ {692, {wxDC, getTextForeground, 0}},
+ {693, {wxDC, getUserScale, 2}},
+ {694, {wxDC, gradientFillConcentric_3, 3}},
+ {695, {wxDC, gradientFillConcentric_4, 4}},
+ {696, {wxDC, gradientFillLinear, 4}},
+ {697, {wxDC, logicalToDeviceX, 1}},
+ {698, {wxDC, logicalToDeviceXRel, 1}},
+ {699, {wxDC, logicalToDeviceY, 1}},
+ {700, {wxDC, logicalToDeviceYRel, 1}},
+ {701, {wxDC, maxX, 0}},
+ {702, {wxDC, maxY, 0}},
+ {703, {wxDC, minX, 0}},
+ {704, {wxDC, minY, 0}},
+ {705, {wxDC, isOk, 0}},
+ {706, {wxDC, resetBoundingBox, 0}},
+ {707, {wxDC, setAxisOrientation, 2}},
+ {708, {wxDC, setBackground, 1}},
+ {709, {wxDC, setBackgroundMode, 1}},
+ {710, {wxDC, setBrush, 1}},
+ {712, {wxDC, setClippingRegion_2, 2}},
+ {713, {wxDC, setClippingRegion_1_1, 1}},
+ {714, {wxDC, setClippingRegion_1_0, 1}},
+ {715, {wxDC, setDeviceOrigin, 2}},
+ {716, {wxDC, setFont, 1}},
+ {717, {wxDC, setLayoutDirection, 1}},
+ {718, {wxDC, setLogicalFunction, 1}},
+ {719, {wxDC, setMapMode, 1}},
+ {720, {wxDC, setPalette, 1}},
+ {721, {wxDC, setPen, 1}},
+ {722, {wxDC, setTextBackground, 1}},
+ {723, {wxDC, setTextForeground, 1}},
+ {724, {wxDC, setUserScale, 2}},
+ {725, {wxDC, startDoc, 1}},
+ {726, {wxDC, startPage, 0}},
+ {727, {wxMirrorDC, new, 2}},
+ {728, {wxMirrorDC, 'Destroy', undefined}},
+ {729, {wxScreenDC, new, 0}},
+ {730, {wxScreenDC, destruct, 0}},
+ {731, {wxPostScriptDC, new_0, 0}},
+ {732, {wxPostScriptDC, new_1, 1}},
+ {733, {wxPostScriptDC, destruct, 0}},
+ {734, {wxPostScriptDC, setResolution, 1}},
+ {735, {wxPostScriptDC, getResolution, 0}},
+ {736, {wxWindowDC, new_0, 0}},
+ {737, {wxWindowDC, new_1, 1}},
+ {738, {wxWindowDC, destruct, 0}},
+ {739, {wxClientDC, new_0, 0}},
+ {740, {wxClientDC, new_1, 1}},
+ {741, {wxClientDC, 'Destroy', undefined}},
+ {742, {wxPaintDC, new_0, 0}},
+ {743, {wxPaintDC, new_1, 1}},
+ {744, {wxPaintDC, 'Destroy', undefined}},
+ {746, {wxMemoryDC, new_1_0, 1}},
+ {747, {wxMemoryDC, new_1_1, 1}},
+ {748, {wxMemoryDC, new_0, 0}},
+ {750, {wxMemoryDC, destruct, 0}},
+ {751, {wxMemoryDC, selectObject, 1}},
+ {752, {wxMemoryDC, selectObjectAsSource, 1}},
+ {753, {wxBufferedDC, new_0, 0}},
+ {754, {wxBufferedDC, new_2, 2}},
+ {755, {wxBufferedDC, new_3, 3}},
+ {756, {wxBufferedDC, destruct, 0}},
+ {757, {wxBufferedDC, init_2, 2}},
+ {758, {wxBufferedDC, init_3, 3}},
+ {759, {wxBufferedPaintDC, new_3, 3}},
+ {760, {wxBufferedPaintDC, new_2, 2}},
+ {761, {wxBufferedPaintDC, destruct, 0}},
+ {762, {wxGraphicsObject, destruct, 0}},
+ {763, {wxGraphicsObject, getRenderer, 0}},
+ {764, {wxGraphicsObject, isNull, 0}},
+ {765, {wxGraphicsContext, destruct, 0}},
+ {766, {wxGraphicsContext, create_1_1, 1}},
+ {767, {wxGraphicsContext, create_1_0, 1}},
+ {768, {wxGraphicsContext, create_0, 0}},
+ {769, {wxGraphicsContext, createPen, 1}},
+ {770, {wxGraphicsContext, createBrush, 1}},
+ {771, {wxGraphicsContext, createRadialGradientBrush, 7}},
+ {772, {wxGraphicsContext, createLinearGradientBrush, 6}},
+ {773, {wxGraphicsContext, createFont, 2}},
+ {774, {wxGraphicsContext, createMatrix, 1}},
+ {775, {wxGraphicsContext, createPath, 0}},
+ {776, {wxGraphicsContext, clip_1, 1}},
+ {777, {wxGraphicsContext, clip_4, 4}},
+ {778, {wxGraphicsContext, resetClip, 0}},
+ {779, {wxGraphicsContext, drawBitmap, 5}},
+ {780, {wxGraphicsContext, drawEllipse, 4}},
+ {781, {wxGraphicsContext, drawIcon, 5}},
+ {782, {wxGraphicsContext, drawLines, 3}},
+ {783, {wxGraphicsContext, drawPath, 2}},
+ {784, {wxGraphicsContext, drawRectangle, 4}},
+ {785, {wxGraphicsContext, drawRoundedRectangle, 5}},
+ {786, {wxGraphicsContext, drawText_3, 3}},
+ {787, {wxGraphicsContext, drawText_4_0, 4}},
+ {788, {wxGraphicsContext, drawText_4_1, 4}},
+ {789, {wxGraphicsContext, drawText_5, 5}},
+ {790, {wxGraphicsContext, fillPath, 2}},
+ {791, {wxGraphicsContext, strokePath, 1}},
+ {792, {wxGraphicsContext, getPartialTextExtents, 2}},
+ {793, {wxGraphicsContext, getTextExtent, 5}},
+ {794, {wxGraphicsContext, rotate, 1}},
+ {795, {wxGraphicsContext, scale, 2}},
+ {796, {wxGraphicsContext, translate, 2}},
+ {797, {wxGraphicsContext, getTransform, 0}},
+ {798, {wxGraphicsContext, setTransform, 1}},
+ {799, {wxGraphicsContext, concatTransform, 1}},
+ {800, {wxGraphicsContext, setBrush_1_1, 1}},
+ {801, {wxGraphicsContext, setBrush_1_0, 1}},
+ {802, {wxGraphicsContext, setFont_1, 1}},
+ {803, {wxGraphicsContext, setFont_2, 2}},
+ {804, {wxGraphicsContext, setPen_1_0, 1}},
+ {805, {wxGraphicsContext, setPen_1_1, 1}},
+ {806, {wxGraphicsContext, strokeLine, 4}},
+ {807, {wxGraphicsContext, strokeLines, 2}},
+ {809, {wxGraphicsMatrix, concat, 1}},
+ {811, {wxGraphicsMatrix, get, 1}},
+ {812, {wxGraphicsMatrix, invert, 0}},
+ {813, {wxGraphicsMatrix, isEqual, 1}},
+ {815, {wxGraphicsMatrix, isIdentity, 0}},
+ {816, {wxGraphicsMatrix, rotate, 1}},
+ {817, {wxGraphicsMatrix, scale, 2}},
+ {818, {wxGraphicsMatrix, translate, 2}},
+ {819, {wxGraphicsMatrix, set, 1}},
+ {820, {wxGraphicsMatrix, transformPoint, 2}},
+ {821, {wxGraphicsMatrix, transformDistance, 2}},
+ {822, {wxGraphicsPath, moveToPoint_2, 2}},
+ {823, {wxGraphicsPath, moveToPoint_1, 1}},
+ {824, {wxGraphicsPath, addArc_6, 6}},
+ {825, {wxGraphicsPath, addArc_5, 5}},
+ {826, {wxGraphicsPath, addArcToPoint, 5}},
+ {827, {wxGraphicsPath, addCircle, 3}},
+ {828, {wxGraphicsPath, addCurveToPoint_6, 6}},
+ {829, {wxGraphicsPath, addCurveToPoint_3, 3}},
+ {830, {wxGraphicsPath, addEllipse, 4}},
+ {831, {wxGraphicsPath, addLineToPoint_2, 2}},
+ {832, {wxGraphicsPath, addLineToPoint_1, 1}},
+ {833, {wxGraphicsPath, addPath, 1}},
+ {834, {wxGraphicsPath, addQuadCurveToPoint, 4}},
+ {835, {wxGraphicsPath, addRectangle, 4}},
+ {836, {wxGraphicsPath, addRoundedRectangle, 5}},
+ {837, {wxGraphicsPath, closeSubpath, 0}},
+ {838, {wxGraphicsPath, contains_3, 3}},
+ {839, {wxGraphicsPath, contains_2, 2}},
+ {841, {wxGraphicsPath, getBox, 0}},
+ {843, {wxGraphicsPath, getCurrentPoint, 0}},
+ {844, {wxGraphicsPath, transform, 1}},
+ {845, {wxGraphicsRenderer, getDefaultRenderer, 0}},
+ {846, {wxGraphicsRenderer, createContext_1_1, 1}},
+ {847, {wxGraphicsRenderer, createContext_1_0, 1}},
+ {848, {wxGraphicsRenderer, createPen, 1}},
+ {849, {wxGraphicsRenderer, createBrush, 1}},
+ {850, {wxGraphicsRenderer, createLinearGradientBrush, 6}},
+ {851, {wxGraphicsRenderer, createRadialGradientBrush, 7}},
+ {852, {wxGraphicsRenderer, createFont, 2}},
+ {853, {wxGraphicsRenderer, createMatrix, 1}},
+ {854, {wxGraphicsRenderer, createPath, 0}},
+ {856, {wxMenuBar, new_1, 1}},
+ {858, {wxMenuBar, new_0, 0}},
+ {860, {wxMenuBar, destruct, 0}},
+ {861, {wxMenuBar, append, 2}},
+ {862, {wxMenuBar, check, 2}},
+ {863, {wxMenuBar, enable_2, 2}},
+ {864, {wxMenuBar, enable_1, 1}},
+ {865, {wxMenuBar, enableTop, 2}},
+ {866, {wxMenuBar, findMenu, 1}},
+ {867, {wxMenuBar, findMenuItem, 2}},
+ {868, {wxMenuBar, findItem, 2}},
+ {869, {wxMenuBar, getHelpString, 1}},
+ {870, {wxMenuBar, getLabel_1, 1}},
+ {871, {wxMenuBar, getLabel_0, 0}},
+ {872, {wxMenuBar, getLabelTop, 1}},
+ {873, {wxMenuBar, getMenu, 1}},
+ {874, {wxMenuBar, getMenuCount, 0}},
+ {875, {wxMenuBar, insert, 3}},
+ {876, {wxMenuBar, isChecked, 1}},
+ {877, {wxMenuBar, isEnabled_1, 1}},
+ {878, {wxMenuBar, isEnabled_0, 0}},
+ {879, {wxMenuBar, remove, 1}},
+ {880, {wxMenuBar, replace, 3}},
+ {881, {wxMenuBar, setHelpString, 2}},
+ {882, {wxMenuBar, setLabel_2, 2}},
+ {883, {wxMenuBar, setLabel_1, 1}},
+ {884, {wxMenuBar, setLabelTop, 2}},
+ {885, {wxControl, getLabel, 0}},
+ {886, {wxControl, setLabel, 1}},
+ {887, {wxControlWithItems, append_1, 1}},
+ {888, {wxControlWithItems, append_2, 2}},
+ {889, {wxControlWithItems, appendStrings_1, 1}},
+ {890, {wxControlWithItems, clear, 0}},
+ {891, {wxControlWithItems, delete, 1}},
+ {892, {wxControlWithItems, findString, 2}},
+ {893, {wxControlWithItems, getClientData, 1}},
+ {894, {wxControlWithItems, setClientData, 2}},
+ {895, {wxControlWithItems, getCount, 0}},
+ {896, {wxControlWithItems, getSelection, 0}},
+ {897, {wxControlWithItems, getString, 1}},
+ {898, {wxControlWithItems, getStringSelection, 0}},
+ {899, {wxControlWithItems, insert_2, 2}},
+ {900, {wxControlWithItems, insert_3, 3}},
+ {901, {wxControlWithItems, isEmpty, 0}},
+ {902, {wxControlWithItems, select, 1}},
+ {903, {wxControlWithItems, setSelection, 1}},
+ {904, {wxControlWithItems, setString, 2}},
+ {905, {wxControlWithItems, setStringSelection, 1}},
+ {908, {wxMenu, new_2, 2}},
+ {909, {wxMenu, new_1, 1}},
+ {911, {wxMenu, destruct, 0}},
+ {912, {wxMenu, append_3, 3}},
+ {913, {wxMenu, append_1, 1}},
+ {914, {wxMenu, append_4_0, 4}},
+ {915, {wxMenu, append_4_1, 4}},
+ {916, {wxMenu, appendCheckItem, 3}},
+ {917, {wxMenu, appendRadioItem, 3}},
+ {918, {wxMenu, appendSeparator, 0}},
+ {919, {wxMenu, break, 0}},
+ {920, {wxMenu, check, 2}},
+ {921, {wxMenu, delete_1_0, 1}},
+ {922, {wxMenu, delete_1_1, 1}},
+ {923, {wxMenu, destroy_1_0, 1}},
+ {924, {wxMenu, destroy_1_1, 1}},
+ {925, {wxMenu, enable, 2}},
+ {926, {wxMenu, findItem_1, 1}},
+ {927, {wxMenu, findItem_2, 2}},
+ {928, {wxMenu, findItemByPosition, 1}},
+ {929, {wxMenu, getHelpString, 1}},
+ {930, {wxMenu, getLabel, 1}},
+ {931, {wxMenu, getMenuItemCount, 0}},
+ {932, {wxMenu, getMenuItems, 0}},
+ {934, {wxMenu, getTitle, 0}},
+ {935, {wxMenu, insert_2, 2}},
+ {936, {wxMenu, insert_3, 3}},
+ {937, {wxMenu, insert_5_1, 5}},
+ {938, {wxMenu, insert_5_0, 5}},
+ {939, {wxMenu, insertCheckItem, 4}},
+ {940, {wxMenu, insertRadioItem, 4}},
+ {941, {wxMenu, insertSeparator, 1}},
+ {942, {wxMenu, isChecked, 1}},
+ {943, {wxMenu, isEnabled, 1}},
+ {944, {wxMenu, prepend_1, 1}},
+ {945, {wxMenu, prepend_2, 2}},
+ {946, {wxMenu, prepend_4_1, 4}},
+ {947, {wxMenu, prepend_4_0, 4}},
+ {948, {wxMenu, prependCheckItem, 3}},
+ {949, {wxMenu, prependRadioItem, 3}},
+ {950, {wxMenu, prependSeparator, 0}},
+ {951, {wxMenu, remove_1_0, 1}},
+ {952, {wxMenu, remove_1_1, 1}},
+ {953, {wxMenu, setHelpString, 2}},
+ {954, {wxMenu, setLabel, 2}},
+ {955, {wxMenu, setTitle, 1}},
+ {956, {wxMenuItem, new, 1}},
+ {958, {wxMenuItem, destruct, 0}},
+ {959, {wxMenuItem, check, 1}},
+ {960, {wxMenuItem, enable, 1}},
+ {961, {wxMenuItem, getBitmap, 0}},
+ {962, {wxMenuItem, getHelp, 0}},
+ {963, {wxMenuItem, getId, 0}},
+ {964, {wxMenuItem, getKind, 0}},
+ {965, {wxMenuItem, getLabel, 0}},
+ {966, {wxMenuItem, getLabelFromText, 1}},
+ {967, {wxMenuItem, getMenu, 0}},
+ {968, {wxMenuItem, getText, 0}},
+ {969, {wxMenuItem, getSubMenu, 0}},
+ {970, {wxMenuItem, isCheckable, 0}},
+ {971, {wxMenuItem, isChecked, 0}},
+ {972, {wxMenuItem, isEnabled, 0}},
+ {973, {wxMenuItem, isSeparator, 0}},
+ {974, {wxMenuItem, isSubMenu, 0}},
+ {975, {wxMenuItem, setBitmap, 1}},
+ {976, {wxMenuItem, setHelp, 1}},
+ {977, {wxMenuItem, setMenu, 1}},
+ {978, {wxMenuItem, setSubMenu, 1}},
+ {979, {wxMenuItem, setText, 1}},
+ {980, {wxToolBar, addControl, 1}},
+ {981, {wxToolBar, addSeparator, 0}},
+ {982, {wxToolBar, addTool_5, 5}},
+ {983, {wxToolBar, addTool_4_0, 4}},
+ {984, {wxToolBar, addTool_1, 1}},
+ {985, {wxToolBar, addTool_4_1, 4}},
+ {986, {wxToolBar, addTool_3, 3}},
+ {987, {wxToolBar, addTool_6, 6}},
+ {988, {wxToolBar, addCheckTool, 4}},
+ {989, {wxToolBar, addRadioTool, 4}},
+ {990, {wxToolBar, addStretchableSpace, 0}},
+ {991, {wxToolBar, insertStretchableSpace, 1}},
+ {992, {wxToolBar, deleteTool, 1}},
+ {993, {wxToolBar, deleteToolByPos, 1}},
+ {994, {wxToolBar, enableTool, 2}},
+ {995, {wxToolBar, findById, 1}},
+ {996, {wxToolBar, findControl, 1}},
+ {997, {wxToolBar, findToolForPosition, 2}},
+ {998, {wxToolBar, getToolSize, 0}},
+ {999, {wxToolBar, getToolBitmapSize, 0}},
+ {1000, {wxToolBar, getMargins, 0}},
+ {1001, {wxToolBar, getToolEnabled, 1}},
+ {1002, {wxToolBar, getToolLongHelp, 1}},
+ {1003, {wxToolBar, getToolPacking, 0}},
+ {1004, {wxToolBar, getToolPos, 1}},
+ {1005, {wxToolBar, getToolSeparation, 0}},
+ {1006, {wxToolBar, getToolShortHelp, 1}},
+ {1007, {wxToolBar, getToolState, 1}},
+ {1008, {wxToolBar, insertControl, 2}},
+ {1009, {wxToolBar, insertSeparator, 1}},
+ {1010, {wxToolBar, insertTool_5, 5}},
+ {1011, {wxToolBar, insertTool_2, 2}},
+ {1012, {wxToolBar, insertTool_4, 4}},
+ {1013, {wxToolBar, realize, 0}},
+ {1014, {wxToolBar, removeTool, 1}},
+ {1015, {wxToolBar, setMargins, 2}},
+ {1016, {wxToolBar, setToolBitmapSize, 1}},
+ {1017, {wxToolBar, setToolLongHelp, 2}},
+ {1018, {wxToolBar, setToolPacking, 1}},
+ {1019, {wxToolBar, setToolShortHelp, 2}},
+ {1020, {wxToolBar, setToolSeparation, 1}},
+ {1021, {wxToolBar, toggleTool, 2}},
+ {1023, {wxStatusBar, new_0, 0}},
+ {1024, {wxStatusBar, new_2, 2}},
+ {1026, {wxStatusBar, destruct, 0}},
+ {1027, {wxStatusBar, create, 2}},
+ {1028, {wxStatusBar, getFieldRect, 2}},
+ {1029, {wxStatusBar, getFieldsCount, 0}},
+ {1030, {wxStatusBar, getStatusText, 1}},
+ {1031, {wxStatusBar, popStatusText, 1}},
+ {1032, {wxStatusBar, pushStatusText, 2}},
+ {1033, {wxStatusBar, setFieldsCount, 2}},
+ {1034, {wxStatusBar, setMinHeight, 1}},
+ {1035, {wxStatusBar, setStatusText, 2}},
+ {1036, {wxStatusBar, setStatusWidths, 2}},
+ {1037, {wxStatusBar, setStatusStyles, 2}},
+ {1038, {wxBitmap, new_0, 0}},
+ {1039, {wxBitmap, new_3, 3}},
+ {1040, {wxBitmap, new_4, 4}},
+ {1041, {wxBitmap, new_2_0, 2}},
+ {1042, {wxBitmap, new_2_1, 2}},
+ {1043, {wxBitmap, destruct, 0}},
+ {1044, {wxBitmap, convertToImage, 0}},
+ {1045, {wxBitmap, copyFromIcon, 1}},
+ {1046, {wxBitmap, create, 3}},
+ {1047, {wxBitmap, getDepth, 0}},
+ {1048, {wxBitmap, getHeight, 0}},
+ {1049, {wxBitmap, getPalette, 0}},
+ {1050, {wxBitmap, getMask, 0}},
+ {1051, {wxBitmap, getWidth, 0}},
+ {1052, {wxBitmap, getSubBitmap, 1}},
+ {1053, {wxBitmap, loadFile, 2}},
+ {1054, {wxBitmap, ok, 0}},
+ {1055, {wxBitmap, saveFile, 3}},
+ {1056, {wxBitmap, setDepth, 1}},
+ {1057, {wxBitmap, setHeight, 1}},
+ {1058, {wxBitmap, setMask, 1}},
+ {1059, {wxBitmap, setPalette, 1}},
+ {1060, {wxBitmap, setWidth, 1}},
+ {1061, {wxIcon, new_0, 0}},
+ {1062, {wxIcon, new_2, 2}},
+ {1063, {wxIcon, new_1, 1}},
+ {1064, {wxIcon, copyFromBitmap, 1}},
+ {1065, {wxIcon, 'Destroy', undefined}},
+ {1066, {wxIconBundle, new_0, 0}},
+ {1067, {wxIconBundle, new_2, 2}},
+ {1068, {wxIconBundle, new_1_0, 1}},
+ {1069, {wxIconBundle, new_1_1, 1}},
+ {1070, {wxIconBundle, destruct, 0}},
+ {1071, {wxIconBundle, addIcon_2, 2}},
+ {1072, {wxIconBundle, addIcon_1, 1}},
+ {1073, {wxIconBundle, getIcon_1_1, 1}},
+ {1074, {wxIconBundle, getIcon_1_0, 1}},
+ {1075, {wxCursor, new_0, 0}},
+ {1076, {wxCursor, new_1_0, 1}},
+ {1077, {wxCursor, new_1_1, 1}},
+ {1078, {wxCursor, new_4, 4}},
+ {1079, {wxCursor, destruct, 0}},
+ {1080, {wxCursor, ok, 0}},
+ {1081, {wxMask, new_0, 0}},
+ {1082, {wxMask, new_2_1, 2}},
+ {1083, {wxMask, new_2_0, 2}},
+ {1084, {wxMask, new_1, 1}},
+ {1085, {wxMask, destruct, 0}},
+ {1086, {wxMask, create_2_1, 2}},
+ {1087, {wxMask, create_2_0, 2}},
+ {1088, {wxMask, create_1, 1}},
+ {1089, {wxImage, new_0, 0}},
+ {1090, {wxImage, new_3_0, 3}},
+ {1091, {wxImage, new_4, 4}},
+ {1092, {wxImage, new_5, 5}},
+ {1093, {wxImage, new_2, 2}},
+ {1094, {wxImage, new_3_1, 3}},
+ {1095, {wxImage, blur, 1}},
+ {1096, {wxImage, blurHorizontal, 1}},
+ {1097, {wxImage, blurVertical, 1}},
+ {1098, {wxImage, convertAlphaToMask, 1}},
+ {1099, {wxImage, convertToGreyscale, 1}},
+ {1100, {wxImage, convertToMono, 3}},
+ {1101, {wxImage, copy, 0}},
+ {1102, {wxImage, create_3, 3}},
+ {1103, {wxImage, create_4, 4}},
+ {1104, {wxImage, create_5, 5}},
+ {1105, {wxImage, 'Destroy', 0}},
+ {1106, {wxImage, findFirstUnusedColour, 4}},
+ {1107, {wxImage, getImageExtWildcard, 0}},
+ {1108, {wxImage, getAlpha_2, 2}},
+ {1109, {wxImage, getAlpha_0, 0}},
+ {1110, {wxImage, getBlue, 2}},
+ {1111, {wxImage, getData, 0}},
+ {1112, {wxImage, getGreen, 2}},
+ {1113, {wxImage, getImageCount, 2}},
+ {1114, {wxImage, getHeight, 0}},
+ {1115, {wxImage, getMaskBlue, 0}},
+ {1116, {wxImage, getMaskGreen, 0}},
+ {1117, {wxImage, getMaskRed, 0}},
+ {1118, {wxImage, getOrFindMaskColour, 3}},
+ {1119, {wxImage, getPalette, 0}},
+ {1120, {wxImage, getRed, 2}},
+ {1121, {wxImage, getSubImage, 1}},
+ {1122, {wxImage, getWidth, 0}},
+ {1123, {wxImage, hasAlpha, 0}},
+ {1124, {wxImage, hasMask, 0}},
+ {1125, {wxImage, getOption, 1}},
+ {1126, {wxImage, getOptionInt, 1}},
+ {1127, {wxImage, hasOption, 1}},
+ {1128, {wxImage, initAlpha, 0}},
+ {1129, {wxImage, initStandardHandlers, 0}},
+ {1130, {wxImage, isTransparent, 3}},
+ {1131, {wxImage, loadFile_2, 2}},
+ {1132, {wxImage, loadFile_3, 3}},
+ {1133, {wxImage, ok, 0}},
+ {1134, {wxImage, removeHandler, 1}},
+ {1135, {wxImage, mirror, 1}},
+ {1136, {wxImage, replace, 6}},
+ {1137, {wxImage, rescale, 3}},
+ {1138, {wxImage, resize, 3}},
+ {1139, {wxImage, rotate, 3}},
+ {1140, {wxImage, rotateHue, 1}},
+ {1141, {wxImage, rotate90, 1}},
+ {1142, {wxImage, saveFile_1, 1}},
+ {1143, {wxImage, saveFile_2_0, 2}},
+ {1144, {wxImage, saveFile_2_1, 2}},
+ {1145, {wxImage, scale, 3}},
+ {1146, {wxImage, size, 3}},
+ {1147, {wxImage, setAlpha_3, 3}},
+ {1148, {wxImage, setAlpha_2, 2}},
+ {1149, {wxImage, setData_2, 2}},
+ {1150, {wxImage, setData_4, 4}},
+ {1151, {wxImage, setMask, 1}},
+ {1152, {wxImage, setMaskColour, 3}},
+ {1153, {wxImage, setMaskFromImage, 4}},
+ {1154, {wxImage, setOption_2_1, 2}},
+ {1155, {wxImage, setOption_2_0, 2}},
+ {1156, {wxImage, setPalette, 1}},
+ {1157, {wxImage, setRGB_5, 5}},
+ {1158, {wxImage, setRGB_4, 4}},
+ {1159, {wxImage, 'Destroy', undefined}},
+ {1160, {wxBrush, new_0, 0}},
+ {1161, {wxBrush, new_2, 2}},
+ {1162, {wxBrush, new_1, 1}},
+ {1164, {wxBrush, destruct, 0}},
+ {1165, {wxBrush, getColour, 0}},
+ {1166, {wxBrush, getStipple, 0}},
+ {1167, {wxBrush, getStyle, 0}},
+ {1168, {wxBrush, isHatch, 0}},
+ {1169, {wxBrush, isOk, 0}},
+ {1170, {wxBrush, setColour_1, 1}},
+ {1171, {wxBrush, setColour_3, 3}},
+ {1172, {wxBrush, setStipple, 1}},
+ {1173, {wxBrush, setStyle, 1}},
+ {1174, {wxPen, new_0, 0}},
+ {1175, {wxPen, new_2, 2}},
+ {1176, {wxPen, destruct, 0}},
+ {1177, {wxPen, getCap, 0}},
+ {1178, {wxPen, getColour, 0}},
+ {1179, {wxPen, getJoin, 0}},
+ {1180, {wxPen, getStyle, 0}},
+ {1181, {wxPen, getWidth, 0}},
+ {1182, {wxPen, isOk, 0}},
+ {1183, {wxPen, setCap, 1}},
+ {1184, {wxPen, setColour_1, 1}},
+ {1185, {wxPen, setColour_3, 3}},
+ {1186, {wxPen, setJoin, 1}},
+ {1187, {wxPen, setStyle, 1}},
+ {1188, {wxPen, setWidth, 1}},
+ {1189, {wxRegion, new_0, 0}},
+ {1190, {wxRegion, new_4, 4}},
+ {1191, {wxRegion, new_2, 2}},
+ {1192, {wxRegion, new_1_1, 1}},
+ {1194, {wxRegion, new_1_0, 1}},
+ {1196, {wxRegion, destruct, 0}},
+ {1197, {wxRegion, clear, 0}},
+ {1198, {wxRegion, contains_2, 2}},
+ {1199, {wxRegion, contains_1_0, 1}},
+ {1200, {wxRegion, contains_4, 4}},
+ {1201, {wxRegion, contains_1_1, 1}},
+ {1202, {wxRegion, convertToBitmap, 0}},
+ {1203, {wxRegion, getBox, 0}},
+ {1204, {wxRegion, intersect_4, 4}},
+ {1205, {wxRegion, intersect_1_1, 1}},
+ {1206, {wxRegion, intersect_1_0, 1}},
+ {1207, {wxRegion, isEmpty, 0}},
+ {1208, {wxRegion, subtract_4, 4}},
+ {1209, {wxRegion, subtract_1_1, 1}},
+ {1210, {wxRegion, subtract_1_0, 1}},
+ {1211, {wxRegion, offset_2, 2}},
+ {1212, {wxRegion, offset_1, 1}},
+ {1213, {wxRegion, union_4, 4}},
+ {1214, {wxRegion, union_1_2, 1}},
+ {1215, {wxRegion, union_1_1, 1}},
+ {1216, {wxRegion, union_1_0, 1}},
+ {1217, {wxRegion, union_3, 3}},
+ {1218, {wxRegion, xor_4, 4}},
+ {1219, {wxRegion, xor_1_1, 1}},
+ {1220, {wxRegion, xor_1_0, 1}},
+ {1221, {wxAcceleratorTable, new_0, 0}},
+ {1222, {wxAcceleratorTable, new_2, 2}},
+ {1223, {wxAcceleratorTable, destruct, 0}},
+ {1224, {wxAcceleratorTable, ok, 0}},
+ {1225, {wxAcceleratorEntry, new_1_0, 1}},
+ {1226, {wxAcceleratorEntry, new_1_1, 1}},
+ {1227, {wxAcceleratorEntry, getCommand, 0}},
+ {1228, {wxAcceleratorEntry, getFlags, 0}},
+ {1229, {wxAcceleratorEntry, getKeyCode, 0}},
+ {1230, {wxAcceleratorEntry, set, 4}},
+ {1231, {wxAcceleratorEntry, 'Destroy', undefined}},
+ {1236, {wxCaret, new_3, 3}},
+ {1237, {wxCaret, new_2, 2}},
+ {1239, {wxCaret, destruct, 0}},
+ {1240, {wxCaret, create_3, 3}},
+ {1241, {wxCaret, create_2, 2}},
+ {1242, {wxCaret, getBlinkTime, 0}},
+ {1244, {wxCaret, getPosition, 0}},
+ {1246, {wxCaret, getSize, 0}},
+ {1247, {wxCaret, getWindow, 0}},
+ {1248, {wxCaret, hide, 0}},
+ {1249, {wxCaret, isOk, 0}},
+ {1250, {wxCaret, isVisible, 0}},
+ {1251, {wxCaret, move_2, 2}},
+ {1252, {wxCaret, move_1, 1}},
+ {1253, {wxCaret, setBlinkTime, 1}},
+ {1254, {wxCaret, setSize_2, 2}},
+ {1255, {wxCaret, setSize_1, 1}},
+ {1256, {wxCaret, show, 1}},
+ {1257, {wxSizer, add_2_1, 2}},
+ {1258, {wxSizer, add_2_0, 2}},
+ {1259, {wxSizer, add_3, 3}},
+ {1260, {wxSizer, add_2_3, 2}},
+ {1261, {wxSizer, add_2_2, 2}},
+ {1262, {wxSizer, addSpacer, 1}},
+ {1263, {wxSizer, addStretchSpacer, 1}},
+ {1264, {wxSizer, calcMin, 0}},
+ {1265, {wxSizer, clear, 1}},
+ {1266, {wxSizer, detach_1_2, 1}},
+ {1267, {wxSizer, detach_1_1, 1}},
+ {1268, {wxSizer, detach_1_0, 1}},
+ {1269, {wxSizer, fit, 1}},
+ {1270, {wxSizer, fitInside, 1}},
+ {1271, {wxSizer, getChildren, 0}},
+ {1272, {wxSizer, getItem_2_1, 2}},
+ {1273, {wxSizer, getItem_2_0, 2}},
+ {1274, {wxSizer, getItem_1, 1}},
+ {1275, {wxSizer, getSize, 0}},
+ {1276, {wxSizer, getPosition, 0}},
+ {1277, {wxSizer, getMinSize, 0}},
+ {1278, {wxSizer, hide_2_0, 2}},
+ {1279, {wxSizer, hide_2_1, 2}},
+ {1280, {wxSizer, hide_1, 1}},
+ {1281, {wxSizer, insert_3_1, 3}},
+ {1282, {wxSizer, insert_3_0, 3}},
+ {1283, {wxSizer, insert_4, 4}},
+ {1284, {wxSizer, insert_3_3, 3}},
+ {1285, {wxSizer, insert_3_2, 3}},
+ {1286, {wxSizer, insert_2, 2}},
+ {1287, {wxSizer, insertSpacer, 2}},
+ {1288, {wxSizer, insertStretchSpacer, 2}},
+ {1289, {wxSizer, isShown_1_2, 1}},
+ {1290, {wxSizer, isShown_1_1, 1}},
+ {1291, {wxSizer, isShown_1_0, 1}},
+ {1292, {wxSizer, layout, 0}},
+ {1293, {wxSizer, prepend_2_1, 2}},
+ {1294, {wxSizer, prepend_2_0, 2}},
+ {1295, {wxSizer, prepend_3, 3}},
+ {1296, {wxSizer, prepend_2_3, 2}},
+ {1297, {wxSizer, prepend_2_2, 2}},
+ {1298, {wxSizer, prepend_1, 1}},
+ {1299, {wxSizer, prependSpacer, 1}},
+ {1300, {wxSizer, prependStretchSpacer, 1}},
+ {1301, {wxSizer, recalcSizes, 0}},
+ {1302, {wxSizer, remove_1_1, 1}},
+ {1303, {wxSizer, remove_1_0, 1}},
+ {1304, {wxSizer, replace_3_1, 3}},
+ {1305, {wxSizer, replace_3_0, 3}},
+ {1306, {wxSizer, replace_2, 2}},
+ {1307, {wxSizer, setDimension, 4}},
+ {1308, {wxSizer, setMinSize_2, 2}},
+ {1309, {wxSizer, setMinSize_1, 1}},
+ {1310, {wxSizer, setItemMinSize_3_2, 3}},
+ {1311, {wxSizer, setItemMinSize_2_2, 2}},
+ {1312, {wxSizer, setItemMinSize_3_1, 3}},
+ {1313, {wxSizer, setItemMinSize_2_1, 2}},
+ {1314, {wxSizer, setItemMinSize_3_0, 3}},
+ {1315, {wxSizer, setItemMinSize_2_0, 2}},
+ {1316, {wxSizer, setSizeHints, 1}},
+ {1317, {wxSizer, setVirtualSizeHints, 1}},
+ {1318, {wxSizer, show_2_2, 2}},
+ {1319, {wxSizer, show_2_1, 2}},
+ {1320, {wxSizer, show_2_0, 2}},
+ {1321, {wxSizer, show_1, 1}},
+ {1322, {wxSizerFlags, new, 1}},
+ {1323, {wxSizerFlags, align, 1}},
+ {1324, {wxSizerFlags, border_2, 2}},
+ {1325, {wxSizerFlags, border_1, 1}},
+ {1326, {wxSizerFlags, center, 0}},
+ {1327, {wxSizerFlags, centre, 0}},
+ {1328, {wxSizerFlags, expand, 0}},
+ {1329, {wxSizerFlags, left, 0}},
+ {1330, {wxSizerFlags, proportion, 1}},
+ {1331, {wxSizerFlags, right, 0}},
+ {1332, {wxSizerFlags, 'Destroy', undefined}},
+ {1333, {wxSizerItem, new_5_1, 5}},
+ {1334, {wxSizerItem, new_2_1, 2}},
+ {1335, {wxSizerItem, new_5_0, 5}},
+ {1336, {wxSizerItem, new_2_0, 2}},
+ {1337, {wxSizerItem, new_6, 6}},
+ {1338, {wxSizerItem, new_3, 3}},
+ {1339, {wxSizerItem, new_0, 0}},
+ {1340, {wxSizerItem, destruct, 0}},
+ {1341, {wxSizerItem, calcMin, 0}},
+ {1342, {wxSizerItem, deleteWindows, 0}},
+ {1343, {wxSizerItem, detachSizer, 0}},
+ {1344, {wxSizerItem, getBorder, 0}},
+ {1345, {wxSizerItem, getFlag, 0}},
+ {1346, {wxSizerItem, getMinSize, 0}},
+ {1347, {wxSizerItem, getPosition, 0}},
+ {1348, {wxSizerItem, getProportion, 0}},
+ {1349, {wxSizerItem, getRatio, 0}},
+ {1350, {wxSizerItem, getRect, 0}},
+ {1351, {wxSizerItem, getSize, 0}},
+ {1352, {wxSizerItem, getSizer, 0}},
+ {1353, {wxSizerItem, getSpacer, 0}},
+ {1354, {wxSizerItem, getUserData, 0}},
+ {1355, {wxSizerItem, getWindow, 0}},
+ {1356, {wxSizerItem, isSizer, 0}},
+ {1357, {wxSizerItem, isShown, 0}},
+ {1358, {wxSizerItem, isSpacer, 0}},
+ {1359, {wxSizerItem, isWindow, 0}},
+ {1360, {wxSizerItem, setBorder, 1}},
+ {1361, {wxSizerItem, setDimension, 2}},
+ {1362, {wxSizerItem, setFlag, 1}},
+ {1363, {wxSizerItem, setInitSize, 2}},
+ {1364, {wxSizerItem, setMinSize_1, 1}},
+ {1365, {wxSizerItem, setMinSize_2, 2}},
+ {1366, {wxSizerItem, setProportion, 1}},
+ {1367, {wxSizerItem, setRatio_2, 2}},
+ {1368, {wxSizerItem, setRatio_1_1, 1}},
+ {1369, {wxSizerItem, setRatio_1_0, 1}},
+ {1370, {wxSizerItem, setSizer, 1}},
+ {1371, {wxSizerItem, setSpacer_1, 1}},
+ {1372, {wxSizerItem, setSpacer_2, 2}},
+ {1373, {wxSizerItem, setWindow, 1}},
+ {1374, {wxSizerItem, show, 1}},
+ {1375, {wxBoxSizer, new, 1}},
+ {1376, {wxBoxSizer, getOrientation, 0}},
+ {1377, {wxBoxSizer, 'Destroy', undefined}},
+ {1378, {wxStaticBoxSizer, new_2, 2}},
+ {1379, {wxStaticBoxSizer, new_3, 3}},
+ {1380, {wxStaticBoxSizer, getStaticBox, 0}},
+ {1381, {wxStaticBoxSizer, 'Destroy', undefined}},
+ {1382, {wxGridSizer, new_4, 4}},
+ {1383, {wxGridSizer, new_2, 2}},
+ {1384, {wxGridSizer, getCols, 0}},
+ {1385, {wxGridSizer, getHGap, 0}},
+ {1386, {wxGridSizer, getRows, 0}},
+ {1387, {wxGridSizer, getVGap, 0}},
+ {1388, {wxGridSizer, setCols, 1}},
+ {1389, {wxGridSizer, setHGap, 1}},
+ {1390, {wxGridSizer, setRows, 1}},
+ {1391, {wxGridSizer, setVGap, 1}},
+ {1392, {wxGridSizer, 'Destroy', undefined}},
+ {1393, {wxFlexGridSizer, new_4, 4}},
+ {1394, {wxFlexGridSizer, new_2, 2}},
+ {1395, {wxFlexGridSizer, addGrowableCol, 2}},
+ {1396, {wxFlexGridSizer, addGrowableRow, 2}},
+ {1397, {wxFlexGridSizer, getFlexibleDirection, 0}},
+ {1398, {wxFlexGridSizer, getNonFlexibleGrowMode, 0}},
+ {1399, {wxFlexGridSizer, removeGrowableCol, 1}},
+ {1400, {wxFlexGridSizer, removeGrowableRow, 1}},
+ {1401, {wxFlexGridSizer, setFlexibleDirection, 1}},
+ {1402, {wxFlexGridSizer, setNonFlexibleGrowMode, 1}},
+ {1403, {wxFlexGridSizer, 'Destroy', undefined}},
+ {1404, {wxGridBagSizer, new, 1}},
+ {1405, {wxGridBagSizer, add_3_2, 3}},
+ {1406, {wxGridBagSizer, add_3_1, 3}},
+ {1407, {wxGridBagSizer, add_4, 4}},
+ {1408, {wxGridBagSizer, add_1_0, 1}},
+ {1409, {wxGridBagSizer, add_2_1, 2}},
+ {1410, {wxGridBagSizer, add_2_0, 2}},
+ {1411, {wxGridBagSizer, add_3_0, 3}},
+ {1412, {wxGridBagSizer, add_1_1, 1}},
+ {1413, {wxGridBagSizer, calcMin, 0}},
+ {1414, {wxGridBagSizer, checkForIntersection_2, 2}},
+ {1415, {wxGridBagSizer, checkForIntersection_3, 3}},
+ {1416, {wxGridBagSizer, findItem_1_1, 1}},
+ {1417, {wxGridBagSizer, findItem_1_0, 1}},
+ {1418, {wxGridBagSizer, findItemAtPoint, 1}},
+ {1419, {wxGridBagSizer, findItemAtPosition, 1}},
+ {1420, {wxGridBagSizer, findItemWithData, 1}},
+ {1421, {wxGridBagSizer, getCellSize, 2}},
+ {1422, {wxGridBagSizer, getEmptyCellSize, 0}},
+ {1423, {wxGridBagSizer, getItemPosition_1_2, 1}},
+ {1424, {wxGridBagSizer, getItemPosition_1_1, 1}},
+ {1425, {wxGridBagSizer, getItemPosition_1_0, 1}},
+ {1426, {wxGridBagSizer, getItemSpan_1_2, 1}},
+ {1427, {wxGridBagSizer, getItemSpan_1_1, 1}},
+ {1428, {wxGridBagSizer, getItemSpan_1_0, 1}},
+ {1429, {wxGridBagSizer, setEmptyCellSize, 1}},
+ {1430, {wxGridBagSizer, setItemPosition_2_2, 2}},
+ {1431, {wxGridBagSizer, setItemPosition_2_1, 2}},
+ {1432, {wxGridBagSizer, setItemPosition_2_0, 2}},
+ {1433, {wxGridBagSizer, setItemSpan_2_2, 2}},
+ {1434, {wxGridBagSizer, setItemSpan_2_1, 2}},
+ {1435, {wxGridBagSizer, setItemSpan_2_0, 2}},
+ {1436, {wxGridBagSizer, 'Destroy', undefined}},
+ {1437, {wxStdDialogButtonSizer, new, 0}},
+ {1438, {wxStdDialogButtonSizer, addButton, 1}},
+ {1439, {wxStdDialogButtonSizer, realize, 0}},
+ {1440, {wxStdDialogButtonSizer, setAffirmativeButton, 1}},
+ {1441, {wxStdDialogButtonSizer, setCancelButton, 1}},
+ {1442, {wxStdDialogButtonSizer, setNegativeButton, 1}},
+ {1443, {wxStdDialogButtonSizer, 'Destroy', undefined}},
+ {1444, {wxFont, new_0, 0}},
+ {1445, {wxFont, new_1, 1}},
+ {1446, {wxFont, new_5, 5}},
+ {1448, {wxFont, destruct, 0}},
+ {1449, {wxFont, isFixedWidth, 0}},
+ {1450, {wxFont, getDefaultEncoding, 0}},
+ {1451, {wxFont, getFaceName, 0}},
+ {1452, {wxFont, getFamily, 0}},
+ {1453, {wxFont, getNativeFontInfoDesc, 0}},
+ {1454, {wxFont, getNativeFontInfoUserDesc, 0}},
+ {1455, {wxFont, getPointSize, 0}},
+ {1456, {wxFont, getStyle, 0}},
+ {1457, {wxFont, getUnderlined, 0}},
+ {1458, {wxFont, getWeight, 0}},
+ {1459, {wxFont, ok, 0}},
+ {1460, {wxFont, setDefaultEncoding, 1}},
+ {1461, {wxFont, setFaceName, 1}},
+ {1462, {wxFont, setFamily, 1}},
+ {1463, {wxFont, setPointSize, 1}},
+ {1464, {wxFont, setStyle, 1}},
+ {1465, {wxFont, setUnderlined, 1}},
+ {1466, {wxFont, setWeight, 1}},
+ {1467, {wxToolTip, enable, 1}},
+ {1468, {wxToolTip, setDelay, 1}},
+ {1469, {wxToolTip, new, 1}},
+ {1470, {wxToolTip, setTip, 1}},
+ {1471, {wxToolTip, getTip, 0}},
+ {1472, {wxToolTip, getWindow, 0}},
+ {1473, {wxToolTip, 'Destroy', undefined}},
+ {1475, {wxButton, new_3, 3}},
+ {1476, {wxButton, new_0, 0}},
+ {1477, {wxButton, destruct, 0}},
+ {1478, {wxButton, create, 3}},
+ {1479, {wxButton, getDefaultSize, 0}},
+ {1480, {wxButton, setDefault, 0}},
+ {1481, {wxButton, setLabel, 1}},
+ {1483, {wxBitmapButton, new_4, 4}},
+ {1484, {wxBitmapButton, new_0, 0}},
+ {1485, {wxBitmapButton, create, 4}},
+ {1486, {wxBitmapButton, getBitmapDisabled, 0}},
+ {1488, {wxBitmapButton, getBitmapFocus, 0}},
+ {1490, {wxBitmapButton, getBitmapLabel, 0}},
+ {1492, {wxBitmapButton, getBitmapSelected, 0}},
+ {1494, {wxBitmapButton, setBitmapDisabled, 1}},
+ {1495, {wxBitmapButton, setBitmapFocus, 1}},
+ {1496, {wxBitmapButton, setBitmapLabel, 1}},
+ {1497, {wxBitmapButton, setBitmapSelected, 1}},
+ {1498, {wxBitmapButton, 'Destroy', undefined}},
+ {1499, {wxToggleButton, new_0, 0}},
+ {1500, {wxToggleButton, new_4, 4}},
+ {1501, {wxToggleButton, create, 4}},
+ {1502, {wxToggleButton, getValue, 0}},
+ {1503, {wxToggleButton, setValue, 1}},
+ {1504, {wxToggleButton, 'Destroy', undefined}},
+ {1505, {wxCalendarCtrl, new_0, 0}},
+ {1506, {wxCalendarCtrl, new_3, 3}},
+ {1507, {wxCalendarCtrl, create, 3}},
+ {1508, {wxCalendarCtrl, destruct, 0}},
+ {1509, {wxCalendarCtrl, setDate, 1}},
+ {1510, {wxCalendarCtrl, getDate, 0}},
+ {1511, {wxCalendarCtrl, enableYearChange, 1}},
+ {1512, {wxCalendarCtrl, enableMonthChange, 1}},
+ {1513, {wxCalendarCtrl, enableHolidayDisplay, 1}},
+ {1514, {wxCalendarCtrl, setHeaderColours, 2}},
+ {1515, {wxCalendarCtrl, getHeaderColourFg, 0}},
+ {1516, {wxCalendarCtrl, getHeaderColourBg, 0}},
+ {1517, {wxCalendarCtrl, setHighlightColours, 2}},
+ {1518, {wxCalendarCtrl, getHighlightColourFg, 0}},
+ {1519, {wxCalendarCtrl, getHighlightColourBg, 0}},
+ {1520, {wxCalendarCtrl, setHolidayColours, 2}},
+ {1521, {wxCalendarCtrl, getHolidayColourFg, 0}},
+ {1522, {wxCalendarCtrl, getHolidayColourBg, 0}},
+ {1523, {wxCalendarCtrl, getAttr, 1}},
+ {1524, {wxCalendarCtrl, setAttr, 2}},
+ {1525, {wxCalendarCtrl, setHoliday, 1}},
+ {1526, {wxCalendarCtrl, resetAttr, 1}},
+ {1527, {wxCalendarCtrl, hitTest, 2}},
+ {1528, {wxCalendarDateAttr, new_0, 0}},
+ {1529, {wxCalendarDateAttr, new_2_1, 2}},
+ {1530, {wxCalendarDateAttr, new_2_0, 2}},
+ {1531, {wxCalendarDateAttr, setTextColour, 1}},
+ {1532, {wxCalendarDateAttr, setBackgroundColour, 1}},
+ {1533, {wxCalendarDateAttr, setBorderColour, 1}},
+ {1534, {wxCalendarDateAttr, setFont, 1}},
+ {1535, {wxCalendarDateAttr, setBorder, 1}},
+ {1536, {wxCalendarDateAttr, setHoliday, 1}},
+ {1537, {wxCalendarDateAttr, hasTextColour, 0}},
+ {1538, {wxCalendarDateAttr, hasBackgroundColour, 0}},
+ {1539, {wxCalendarDateAttr, hasBorderColour, 0}},
+ {1540, {wxCalendarDateAttr, hasFont, 0}},
+ {1541, {wxCalendarDateAttr, hasBorder, 0}},
+ {1542, {wxCalendarDateAttr, isHoliday, 0}},
+ {1543, {wxCalendarDateAttr, getTextColour, 0}},
+ {1544, {wxCalendarDateAttr, getBackgroundColour, 0}},
+ {1545, {wxCalendarDateAttr, getBorderColour, 0}},
+ {1546, {wxCalendarDateAttr, getFont, 0}},
+ {1547, {wxCalendarDateAttr, getBorder, 0}},
+ {1548, {wxCalendarDateAttr, 'Destroy', undefined}},
+ {1550, {wxCheckBox, new_4, 4}},
+ {1551, {wxCheckBox, new_0, 0}},
+ {1552, {wxCheckBox, create, 4}},
+ {1553, {wxCheckBox, getValue, 0}},
+ {1554, {wxCheckBox, get3StateValue, 0}},
+ {1555, {wxCheckBox, is3rdStateAllowedForUser, 0}},
+ {1556, {wxCheckBox, is3State, 0}},
+ {1557, {wxCheckBox, isChecked, 0}},
+ {1558, {wxCheckBox, setValue, 1}},
+ {1559, {wxCheckBox, set3StateValue, 1}},
+ {1560, {wxCheckBox, 'Destroy', undefined}},
+ {1561, {wxCheckListBox, new_0, 0}},
+ {1563, {wxCheckListBox, new_3, 3}},
+ {1564, {wxCheckListBox, check, 2}},
+ {1565, {wxCheckListBox, isChecked, 1}},
+ {1566, {wxCheckListBox, 'Destroy', undefined}},
+ {1569, {wxChoice, new_3, 3}},
+ {1570, {wxChoice, new_0, 0}},
+ {1572, {wxChoice, destruct, 0}},
+ {1574, {wxChoice, create, 6}},
+ {1575, {wxChoice, delete, 1}},
+ {1576, {wxChoice, getColumns, 0}},
+ {1577, {wxChoice, setColumns, 1}},
+ {1578, {wxComboBox, new_0, 0}},
+ {1580, {wxComboBox, new_3, 3}},
+ {1581, {wxComboBox, destruct, 0}},
+ {1583, {wxComboBox, create, 7}},
+ {1584, {wxComboBox, canCopy, 0}},
+ {1585, {wxComboBox, canCut, 0}},
+ {1586, {wxComboBox, canPaste, 0}},
+ {1587, {wxComboBox, canRedo, 0}},
+ {1588, {wxComboBox, canUndo, 0}},
+ {1589, {wxComboBox, copy, 0}},
+ {1590, {wxComboBox, cut, 0}},
+ {1591, {wxComboBox, getInsertionPoint, 0}},
+ {1592, {wxComboBox, getLastPosition, 0}},
+ {1593, {wxComboBox, getValue, 0}},
+ {1594, {wxComboBox, paste, 0}},
+ {1595, {wxComboBox, redo, 0}},
+ {1596, {wxComboBox, replace, 3}},
+ {1597, {wxComboBox, remove, 2}},
+ {1598, {wxComboBox, setInsertionPoint, 1}},
+ {1599, {wxComboBox, setInsertionPointEnd, 0}},
+ {1600, {wxComboBox, setSelection_1, 1}},
+ {1601, {wxComboBox, setSelection_2, 2}},
+ {1602, {wxComboBox, setValue, 1}},
+ {1603, {wxComboBox, undo, 0}},
+ {1604, {wxGauge, new_0, 0}},
+ {1605, {wxGauge, new_4, 4}},
+ {1606, {wxGauge, create, 4}},
+ {1607, {wxGauge, getRange, 0}},
+ {1608, {wxGauge, getValue, 0}},
+ {1609, {wxGauge, isVertical, 0}},
+ {1610, {wxGauge, setRange, 1}},
+ {1611, {wxGauge, setValue, 1}},
+ {1612, {wxGauge, pulse, 0}},
+ {1613, {wxGauge, 'Destroy', undefined}},
+ {1614, {wxGenericDirCtrl, new_0, 0}},
+ {1615, {wxGenericDirCtrl, new_2, 2}},
+ {1616, {wxGenericDirCtrl, destruct, 0}},
+ {1617, {wxGenericDirCtrl, create, 2}},
+ {1618, {wxGenericDirCtrl, init, 0}},
+ {1619, {wxGenericDirCtrl, collapseTree, 0}},
+ {1620, {wxGenericDirCtrl, expandPath, 1}},
+ {1621, {wxGenericDirCtrl, getDefaultPath, 0}},
+ {1622, {wxGenericDirCtrl, getPath, 0}},
+ {1623, {wxGenericDirCtrl, getFilePath, 0}},
+ {1624, {wxGenericDirCtrl, getFilter, 0}},
+ {1625, {wxGenericDirCtrl, getFilterIndex, 0}},
+ {1626, {wxGenericDirCtrl, getRootId, 0}},
+ {1627, {wxGenericDirCtrl, getTreeCtrl, 0}},
+ {1628, {wxGenericDirCtrl, reCreateTree, 0}},
+ {1629, {wxGenericDirCtrl, setDefaultPath, 1}},
+ {1630, {wxGenericDirCtrl, setFilter, 1}},
+ {1631, {wxGenericDirCtrl, setFilterIndex, 1}},
+ {1632, {wxGenericDirCtrl, setPath, 1}},
+ {1634, {wxStaticBox, new_4, 4}},
+ {1635, {wxStaticBox, new_0, 0}},
+ {1636, {wxStaticBox, create, 4}},
+ {1637, {wxStaticBox, 'Destroy', undefined}},
+ {1639, {wxStaticLine, new_2, 2}},
+ {1640, {wxStaticLine, new_0, 0}},
+ {1641, {wxStaticLine, create, 2}},
+ {1642, {wxStaticLine, isVertical, 0}},
+ {1643, {wxStaticLine, getDefaultSize, 0}},
+ {1644, {wxStaticLine, 'Destroy', undefined}},
+ {1647, {wxListBox, new_3, 3}},
+ {1648, {wxListBox, new_0, 0}},
+ {1650, {wxListBox, destruct, 0}},
+ {1652, {wxListBox, create, 6}},
+ {1653, {wxListBox, deselect, 1}},
+ {1654, {wxListBox, getSelections, 1}},
+ {1655, {wxListBox, insertItems, 2}},
+ {1656, {wxListBox, isSelected, 1}},
+ {1657, {wxListBox, set, 1}},
+ {1658, {wxListBox, hitTest, 1}},
+ {1659, {wxListBox, setFirstItem_1_0, 1}},
+ {1660, {wxListBox, setFirstItem_1_1, 1}},
+ {1661, {wxListCtrl, new_0, 0}},
+ {1662, {wxListCtrl, new_2, 2}},
+ {1663, {wxListCtrl, arrange, 1}},
+ {1664, {wxListCtrl, assignImageList, 2}},
+ {1665, {wxListCtrl, clearAll, 0}},
+ {1666, {wxListCtrl, create, 2}},
+ {1667, {wxListCtrl, deleteAllItems, 0}},
+ {1668, {wxListCtrl, deleteColumn, 1}},
+ {1669, {wxListCtrl, deleteItem, 1}},
+ {1670, {wxListCtrl, editLabel, 1}},
+ {1671, {wxListCtrl, ensureVisible, 1}},
+ {1672, {wxListCtrl, findItem_3_0, 3}},
+ {1673, {wxListCtrl, findItem_3_1, 3}},
+ {1674, {wxListCtrl, getColumn, 2}},
+ {1675, {wxListCtrl, getColumnCount, 0}},
+ {1676, {wxListCtrl, getColumnWidth, 1}},
+ {1677, {wxListCtrl, getCountPerPage, 0}},
+ {1678, {wxListCtrl, getEditControl, 0}},
+ {1679, {wxListCtrl, getImageList, 1}},
+ {1680, {wxListCtrl, getItem, 1}},
+ {1681, {wxListCtrl, getItemBackgroundColour, 1}},
+ {1682, {wxListCtrl, getItemCount, 0}},
+ {1683, {wxListCtrl, getItemData, 1}},
+ {1684, {wxListCtrl, getItemFont, 1}},
+ {1685, {wxListCtrl, getItemPosition, 2}},
+ {1686, {wxListCtrl, getItemRect, 3}},
+ {1687, {wxListCtrl, getItemSpacing, 0}},
+ {1688, {wxListCtrl, getItemState, 2}},
+ {1689, {wxListCtrl, getItemText, 1}},
+ {1690, {wxListCtrl, getItemTextColour, 1}},
+ {1691, {wxListCtrl, getNextItem, 2}},
+ {1692, {wxListCtrl, getSelectedItemCount, 0}},
+ {1693, {wxListCtrl, getTextColour, 0}},
+ {1694, {wxListCtrl, getTopItem, 0}},
+ {1695, {wxListCtrl, getViewRect, 0}},
+ {1696, {wxListCtrl, hitTest, 3}},
+ {1697, {wxListCtrl, insertColumn_2, 2}},
+ {1698, {wxListCtrl, insertColumn_3, 3}},
+ {1699, {wxListCtrl, insertItem_1, 1}},
+ {1700, {wxListCtrl, insertItem_2_1, 2}},
+ {1701, {wxListCtrl, insertItem_2_0, 2}},
+ {1702, {wxListCtrl, insertItem_3, 3}},
+ {1703, {wxListCtrl, refreshItem, 1}},
+ {1704, {wxListCtrl, refreshItems, 2}},
+ {1705, {wxListCtrl, scrollList, 2}},
+ {1706, {wxListCtrl, setBackgroundColour, 1}},
+ {1707, {wxListCtrl, setColumn, 2}},
+ {1708, {wxListCtrl, setColumnWidth, 2}},
+ {1709, {wxListCtrl, setImageList, 2}},
+ {1710, {wxListCtrl, setItem_1, 1}},
+ {1711, {wxListCtrl, setItem_4, 4}},
+ {1712, {wxListCtrl, setItemBackgroundColour, 2}},
+ {1713, {wxListCtrl, setItemCount, 1}},
+ {1714, {wxListCtrl, setItemData, 2}},
+ {1715, {wxListCtrl, setItemFont, 2}},
+ {1716, {wxListCtrl, setItemImage, 3}},
+ {1717, {wxListCtrl, setItemColumnImage, 3}},
+ {1718, {wxListCtrl, setItemPosition, 2}},
+ {1719, {wxListCtrl, setItemState, 3}},
+ {1720, {wxListCtrl, setItemText, 2}},
+ {1721, {wxListCtrl, setItemTextColour, 2}},
+ {1722, {wxListCtrl, setSingleStyle, 2}},
+ {1723, {wxListCtrl, setTextColour, 1}},
+ {1724, {wxListCtrl, setWindowStyleFlag, 1}},
+ {1725, {wxListCtrl, sortItems, 2}},
+ {1726, {wxListCtrl, 'Destroy', undefined}},
+ {1727, {wxListView, clearColumnImage, 1}},
+ {1728, {wxListView, focus, 1}},
+ {1729, {wxListView, getFirstSelected, 0}},
+ {1730, {wxListView, getFocusedItem, 0}},
+ {1731, {wxListView, getNextSelected, 1}},
+ {1732, {wxListView, isSelected, 1}},
+ {1733, {wxListView, select, 2}},
+ {1734, {wxListView, setColumnImage, 2}},
+ {1735, {wxListItem, new_0, 0}},
+ {1736, {wxListItem, new_1, 1}},
+ {1737, {wxListItem, destruct, 0}},
+ {1738, {wxListItem, clear, 0}},
+ {1739, {wxListItem, getAlign, 0}},
+ {1740, {wxListItem, getBackgroundColour, 0}},
+ {1741, {wxListItem, getColumn, 0}},
+ {1742, {wxListItem, getFont, 0}},
+ {1743, {wxListItem, getId, 0}},
+ {1744, {wxListItem, getImage, 0}},
+ {1745, {wxListItem, getMask, 0}},
+ {1746, {wxListItem, getState, 0}},
+ {1747, {wxListItem, getText, 0}},
+ {1748, {wxListItem, getTextColour, 0}},
+ {1749, {wxListItem, getWidth, 0}},
+ {1750, {wxListItem, setAlign, 1}},
+ {1751, {wxListItem, setBackgroundColour, 1}},
+ {1752, {wxListItem, setColumn, 1}},
+ {1753, {wxListItem, setFont, 1}},
+ {1754, {wxListItem, setId, 1}},
+ {1755, {wxListItem, setImage, 1}},
+ {1756, {wxListItem, setMask, 1}},
+ {1757, {wxListItem, setState, 1}},
+ {1758, {wxListItem, setStateMask, 1}},
+ {1759, {wxListItem, setText, 1}},
+ {1760, {wxListItem, setTextColour, 1}},
+ {1761, {wxListItem, setWidth, 1}},
+ {1762, {wxListItemAttr, new_0, 0}},
+ {1763, {wxListItemAttr, new_3, 3}},
+ {1764, {wxListItemAttr, getBackgroundColour, 0}},
+ {1765, {wxListItemAttr, getFont, 0}},
+ {1766, {wxListItemAttr, getTextColour, 0}},
+ {1767, {wxListItemAttr, hasBackgroundColour, 0}},
+ {1768, {wxListItemAttr, hasFont, 0}},
+ {1769, {wxListItemAttr, hasTextColour, 0}},
+ {1770, {wxListItemAttr, setBackgroundColour, 1}},
+ {1771, {wxListItemAttr, setFont, 1}},
+ {1772, {wxListItemAttr, setTextColour, 1}},
+ {1773, {wxListItemAttr, 'Destroy', undefined}},
+ {1774, {wxImageList, new_0, 0}},
+ {1775, {wxImageList, new_3, 3}},
+ {1776, {wxImageList, add_1, 1}},
+ {1777, {wxImageList, add_2_0, 2}},
+ {1778, {wxImageList, add_2_1, 2}},
+ {1779, {wxImageList, create, 3}},
+ {1781, {wxImageList, draw, 5}},
+ {1782, {wxImageList, getBitmap, 1}},
+ {1783, {wxImageList, getIcon, 1}},
+ {1784, {wxImageList, getImageCount, 0}},
+ {1785, {wxImageList, getSize, 3}},
+ {1786, {wxImageList, remove, 1}},
+ {1787, {wxImageList, removeAll, 0}},
+ {1788, {wxImageList, replace_2, 2}},
+ {1789, {wxImageList, replace_3, 3}},
+ {1790, {wxImageList, 'Destroy', undefined}},
+ {1791, {wxTextAttr, new_0, 0}},
+ {1792, {wxTextAttr, new_2, 2}},
+ {1793, {wxTextAttr, getAlignment, 0}},
+ {1794, {wxTextAttr, getBackgroundColour, 0}},
+ {1795, {wxTextAttr, getFont, 0}},
+ {1796, {wxTextAttr, getLeftIndent, 0}},
+ {1797, {wxTextAttr, getLeftSubIndent, 0}},
+ {1798, {wxTextAttr, getRightIndent, 0}},
+ {1799, {wxTextAttr, getTabs, 0}},
+ {1800, {wxTextAttr, getTextColour, 0}},
+ {1801, {wxTextAttr, hasBackgroundColour, 0}},
+ {1802, {wxTextAttr, hasFont, 0}},
+ {1803, {wxTextAttr, hasTextColour, 0}},
+ {1804, {wxTextAttr, getFlags, 0}},
+ {1805, {wxTextAttr, isDefault, 0}},
+ {1806, {wxTextAttr, setAlignment, 1}},
+ {1807, {wxTextAttr, setBackgroundColour, 1}},
+ {1808, {wxTextAttr, setFlags, 1}},
+ {1809, {wxTextAttr, setFont, 2}},
+ {1810, {wxTextAttr, setLeftIndent, 2}},
+ {1811, {wxTextAttr, setRightIndent, 1}},
+ {1812, {wxTextAttr, setTabs, 1}},
+ {1813, {wxTextAttr, setTextColour, 1}},
+ {1814, {wxTextAttr, 'Destroy', undefined}},
+ {1816, {wxTextCtrl, new_3, 3}},
+ {1817, {wxTextCtrl, new_0, 0}},
+ {1819, {wxTextCtrl, destruct, 0}},
+ {1820, {wxTextCtrl, appendText, 1}},
+ {1821, {wxTextCtrl, canCopy, 0}},
+ {1822, {wxTextCtrl, canCut, 0}},
+ {1823, {wxTextCtrl, canPaste, 0}},
+ {1824, {wxTextCtrl, canRedo, 0}},
+ {1825, {wxTextCtrl, canUndo, 0}},
+ {1826, {wxTextCtrl, clear, 0}},
+ {1827, {wxTextCtrl, copy, 0}},
+ {1828, {wxTextCtrl, create, 3}},
+ {1829, {wxTextCtrl, cut, 0}},
+ {1830, {wxTextCtrl, discardEdits, 0}},
+ {1831, {wxTextCtrl, changeValue, 1}},
+ {1832, {wxTextCtrl, emulateKeyPress, 1}},
+ {1833, {wxTextCtrl, getDefaultStyle, 0}},
+ {1834, {wxTextCtrl, getInsertionPoint, 0}},
+ {1835, {wxTextCtrl, getLastPosition, 0}},
+ {1836, {wxTextCtrl, getLineLength, 1}},
+ {1837, {wxTextCtrl, getLineText, 1}},
+ {1838, {wxTextCtrl, getNumberOfLines, 0}},
+ {1839, {wxTextCtrl, getRange, 2}},
+ {1840, {wxTextCtrl, getSelection, 2}},
+ {1841, {wxTextCtrl, getStringSelection, 0}},
+ {1842, {wxTextCtrl, getStyle, 2}},
+ {1843, {wxTextCtrl, getValue, 0}},
+ {1844, {wxTextCtrl, isEditable, 0}},
+ {1845, {wxTextCtrl, isModified, 0}},
+ {1846, {wxTextCtrl, isMultiLine, 0}},
+ {1847, {wxTextCtrl, isSingleLine, 0}},
+ {1848, {wxTextCtrl, loadFile, 2}},
+ {1849, {wxTextCtrl, markDirty, 0}},
+ {1850, {wxTextCtrl, paste, 0}},
+ {1851, {wxTextCtrl, positionToXY, 3}},
+ {1852, {wxTextCtrl, redo, 0}},
+ {1853, {wxTextCtrl, remove, 2}},
+ {1854, {wxTextCtrl, replace, 3}},
+ {1855, {wxTextCtrl, saveFile, 1}},
+ {1856, {wxTextCtrl, setDefaultStyle, 1}},
+ {1857, {wxTextCtrl, setEditable, 1}},
+ {1858, {wxTextCtrl, setInsertionPoint, 1}},
+ {1859, {wxTextCtrl, setInsertionPointEnd, 0}},
+ {1861, {wxTextCtrl, setMaxLength, 1}},
+ {1862, {wxTextCtrl, setSelection, 2}},
+ {1863, {wxTextCtrl, setStyle, 3}},
+ {1864, {wxTextCtrl, setValue, 1}},
+ {1865, {wxTextCtrl, showPosition, 1}},
+ {1866, {wxTextCtrl, undo, 0}},
+ {1867, {wxTextCtrl, writeText, 1}},
+ {1868, {wxTextCtrl, xYToPosition, 2}},
+ {1871, {wxNotebook, new_0, 0}},
+ {1872, {wxNotebook, new_3, 3}},
+ {1873, {wxNotebook, destruct, 0}},
+ {1874, {wxNotebook, addPage, 3}},
+ {1875, {wxNotebook, advanceSelection, 1}},
+ {1876, {wxNotebook, assignImageList, 1}},
+ {1877, {wxNotebook, create, 3}},
+ {1878, {wxNotebook, deleteAllPages, 0}},
+ {1879, {wxNotebook, deletePage, 1}},
+ {1880, {wxNotebook, removePage, 1}},
+ {1881, {wxNotebook, getCurrentPage, 0}},
+ {1882, {wxNotebook, getImageList, 0}},
+ {1884, {wxNotebook, getPage, 1}},
+ {1885, {wxNotebook, getPageCount, 0}},
+ {1886, {wxNotebook, getPageImage, 1}},
+ {1887, {wxNotebook, getPageText, 1}},
+ {1888, {wxNotebook, getRowCount, 0}},
+ {1889, {wxNotebook, getSelection, 0}},
+ {1890, {wxNotebook, getThemeBackgroundColour, 0}},
+ {1892, {wxNotebook, hitTest, 2}},
+ {1894, {wxNotebook, insertPage, 4}},
+ {1895, {wxNotebook, setImageList, 1}},
+ {1896, {wxNotebook, setPadding, 1}},
+ {1897, {wxNotebook, setPageSize, 1}},
+ {1898, {wxNotebook, setPageImage, 2}},
+ {1899, {wxNotebook, setPageText, 2}},
+ {1900, {wxNotebook, setSelection, 1}},
+ {1901, {wxNotebook, changeSelection, 1}},
+ {1902, {wxChoicebook, new_0, 0}},
+ {1903, {wxChoicebook, new_3, 3}},
+ {1904, {wxChoicebook, addPage, 3}},
+ {1905, {wxChoicebook, advanceSelection, 1}},
+ {1906, {wxChoicebook, assignImageList, 1}},
+ {1907, {wxChoicebook, create, 3}},
+ {1908, {wxChoicebook, deleteAllPages, 0}},
+ {1909, {wxChoicebook, deletePage, 1}},
+ {1910, {wxChoicebook, removePage, 1}},
+ {1911, {wxChoicebook, getCurrentPage, 0}},
+ {1912, {wxChoicebook, getImageList, 0}},
+ {1914, {wxChoicebook, getPage, 1}},
+ {1915, {wxChoicebook, getPageCount, 0}},
+ {1916, {wxChoicebook, getPageImage, 1}},
+ {1917, {wxChoicebook, getPageText, 1}},
+ {1918, {wxChoicebook, getSelection, 0}},
+ {1919, {wxChoicebook, hitTest, 2}},
+ {1920, {wxChoicebook, insertPage, 4}},
+ {1921, {wxChoicebook, setImageList, 1}},
+ {1922, {wxChoicebook, setPageSize, 1}},
+ {1923, {wxChoicebook, setPageImage, 2}},
+ {1924, {wxChoicebook, setPageText, 2}},
+ {1925, {wxChoicebook, setSelection, 1}},
+ {1926, {wxChoicebook, changeSelection, 1}},
+ {1927, {wxChoicebook, 'Destroy', undefined}},
+ {1928, {wxToolbook, new_0, 0}},
+ {1929, {wxToolbook, new_3, 3}},
+ {1930, {wxToolbook, addPage, 3}},
+ {1931, {wxToolbook, advanceSelection, 1}},
+ {1932, {wxToolbook, assignImageList, 1}},
+ {1933, {wxToolbook, create, 3}},
+ {1934, {wxToolbook, deleteAllPages, 0}},
+ {1935, {wxToolbook, deletePage, 1}},
+ {1936, {wxToolbook, removePage, 1}},
+ {1937, {wxToolbook, getCurrentPage, 0}},
+ {1938, {wxToolbook, getImageList, 0}},
+ {1940, {wxToolbook, getPage, 1}},
+ {1941, {wxToolbook, getPageCount, 0}},
+ {1942, {wxToolbook, getPageImage, 1}},
+ {1943, {wxToolbook, getPageText, 1}},
+ {1944, {wxToolbook, getSelection, 0}},
+ {1946, {wxToolbook, hitTest, 2}},
+ {1947, {wxToolbook, insertPage, 4}},
+ {1948, {wxToolbook, setImageList, 1}},
+ {1949, {wxToolbook, setPageSize, 1}},
+ {1950, {wxToolbook, setPageImage, 2}},
+ {1951, {wxToolbook, setPageText, 2}},
+ {1952, {wxToolbook, setSelection, 1}},
+ {1953, {wxToolbook, changeSelection, 1}},
+ {1954, {wxToolbook, 'Destroy', undefined}},
+ {1955, {wxListbook, new_0, 0}},
+ {1956, {wxListbook, new_3, 3}},
+ {1957, {wxListbook, addPage, 3}},
+ {1958, {wxListbook, advanceSelection, 1}},
+ {1959, {wxListbook, assignImageList, 1}},
+ {1960, {wxListbook, create, 3}},
+ {1961, {wxListbook, deleteAllPages, 0}},
+ {1962, {wxListbook, deletePage, 1}},
+ {1963, {wxListbook, removePage, 1}},
+ {1964, {wxListbook, getCurrentPage, 0}},
+ {1965, {wxListbook, getImageList, 0}},
+ {1967, {wxListbook, getPage, 1}},
+ {1968, {wxListbook, getPageCount, 0}},
+ {1969, {wxListbook, getPageImage, 1}},
+ {1970, {wxListbook, getPageText, 1}},
+ {1971, {wxListbook, getSelection, 0}},
+ {1973, {wxListbook, hitTest, 2}},
+ {1974, {wxListbook, insertPage, 4}},
+ {1975, {wxListbook, setImageList, 1}},
+ {1976, {wxListbook, setPageSize, 1}},
+ {1977, {wxListbook, setPageImage, 2}},
+ {1978, {wxListbook, setPageText, 2}},
+ {1979, {wxListbook, setSelection, 1}},
+ {1980, {wxListbook, changeSelection, 1}},
+ {1981, {wxListbook, 'Destroy', undefined}},
+ {1982, {wxTreebook, new_0, 0}},
+ {1983, {wxTreebook, new_3, 3}},
+ {1984, {wxTreebook, addPage, 3}},
+ {1985, {wxTreebook, advanceSelection, 1}},
+ {1986, {wxTreebook, assignImageList, 1}},
+ {1987, {wxTreebook, create, 3}},
+ {1988, {wxTreebook, deleteAllPages, 0}},
+ {1989, {wxTreebook, deletePage, 1}},
+ {1990, {wxTreebook, removePage, 1}},
+ {1991, {wxTreebook, getCurrentPage, 0}},
+ {1992, {wxTreebook, getImageList, 0}},
+ {1994, {wxTreebook, getPage, 1}},
+ {1995, {wxTreebook, getPageCount, 0}},
+ {1996, {wxTreebook, getPageImage, 1}},
+ {1997, {wxTreebook, getPageText, 1}},
+ {1998, {wxTreebook, getSelection, 0}},
+ {1999, {wxTreebook, expandNode, 2}},
+ {2000, {wxTreebook, isNodeExpanded, 1}},
+ {2002, {wxTreebook, hitTest, 2}},
+ {2003, {wxTreebook, insertPage, 4}},
+ {2004, {wxTreebook, insertSubPage, 4}},
+ {2005, {wxTreebook, setImageList, 1}},
+ {2006, {wxTreebook, setPageSize, 1}},
+ {2007, {wxTreebook, setPageImage, 2}},
+ {2008, {wxTreebook, setPageText, 2}},
+ {2009, {wxTreebook, setSelection, 1}},
+ {2010, {wxTreebook, changeSelection, 1}},
+ {2011, {wxTreebook, 'Destroy', undefined}},
+ {2014, {wxTreeCtrl, new_2, 2}},
+ {2015, {wxTreeCtrl, new_0, 0}},
+ {2017, {wxTreeCtrl, destruct, 0}},
+ {2018, {wxTreeCtrl, addRoot, 2}},
+ {2019, {wxTreeCtrl, appendItem, 3}},
+ {2020, {wxTreeCtrl, assignImageList, 1}},
+ {2021, {wxTreeCtrl, assignStateImageList, 1}},
+ {2022, {wxTreeCtrl, collapse, 1}},
+ {2023, {wxTreeCtrl, collapseAndReset, 1}},
+ {2024, {wxTreeCtrl, create, 2}},
+ {2025, {wxTreeCtrl, delete, 1}},
+ {2026, {wxTreeCtrl, deleteAllItems, 0}},
+ {2027, {wxTreeCtrl, deleteChildren, 1}},
+ {2028, {wxTreeCtrl, editLabel, 1}},
+ {2029, {wxTreeCtrl, ensureVisible, 1}},
+ {2030, {wxTreeCtrl, expand, 1}},
+ {2031, {wxTreeCtrl, getBoundingRect, 3}},
+ {2033, {wxTreeCtrl, getChildrenCount, 2}},
+ {2034, {wxTreeCtrl, getCount, 0}},
+ {2035, {wxTreeCtrl, getEditControl, 0}},
+ {2036, {wxTreeCtrl, getFirstChild, 2}},
+ {2037, {wxTreeCtrl, getNextChild, 2}},
+ {2038, {wxTreeCtrl, getFirstVisibleItem, 0}},
+ {2039, {wxTreeCtrl, getImageList, 0}},
+ {2040, {wxTreeCtrl, getIndent, 0}},
+ {2041, {wxTreeCtrl, getItemBackgroundColour, 1}},
+ {2042, {wxTreeCtrl, getItemData, 1}},
+ {2043, {wxTreeCtrl, getItemFont, 1}},
+ {2044, {wxTreeCtrl, getItemImage_1, 1}},
+ {2045, {wxTreeCtrl, getItemImage_2, 2}},
+ {2046, {wxTreeCtrl, getItemText, 1}},
+ {2047, {wxTreeCtrl, getItemTextColour, 1}},
+ {2048, {wxTreeCtrl, getLastChild, 1}},
+ {2049, {wxTreeCtrl, getNextSibling, 1}},
+ {2050, {wxTreeCtrl, getNextVisible, 1}},
+ {2051, {wxTreeCtrl, getItemParent, 1}},
+ {2052, {wxTreeCtrl, getPrevSibling, 1}},
+ {2053, {wxTreeCtrl, getPrevVisible, 1}},
+ {2054, {wxTreeCtrl, getRootItem, 0}},
+ {2055, {wxTreeCtrl, getSelection, 0}},
+ {2056, {wxTreeCtrl, getSelections, 1}},
+ {2057, {wxTreeCtrl, getStateImageList, 0}},
+ {2058, {wxTreeCtrl, hitTest, 2}},
+ {2060, {wxTreeCtrl, insertItem, 4}},
+ {2061, {wxTreeCtrl, isBold, 1}},
+ {2062, {wxTreeCtrl, isExpanded, 1}},
+ {2063, {wxTreeCtrl, isSelected, 1}},
+ {2064, {wxTreeCtrl, isVisible, 1}},
+ {2065, {wxTreeCtrl, itemHasChildren, 1}},
+ {2066, {wxTreeCtrl, isTreeItemIdOk, 1}},
+ {2067, {wxTreeCtrl, prependItem, 3}},
+ {2068, {wxTreeCtrl, scrollTo, 1}},
+ {2069, {wxTreeCtrl, selectItem_1, 1}},
+ {2070, {wxTreeCtrl, selectItem_2, 2}},
+ {2071, {wxTreeCtrl, setIndent, 1}},
+ {2072, {wxTreeCtrl, setImageList, 1}},
+ {2073, {wxTreeCtrl, setItemBackgroundColour, 2}},
+ {2074, {wxTreeCtrl, setItemBold, 2}},
+ {2075, {wxTreeCtrl, setItemData, 2}},
+ {2076, {wxTreeCtrl, setItemDropHighlight, 2}},
+ {2077, {wxTreeCtrl, setItemFont, 2}},
+ {2078, {wxTreeCtrl, setItemHasChildren, 2}},
+ {2079, {wxTreeCtrl, setItemImage_2, 2}},
+ {2080, {wxTreeCtrl, setItemImage_3, 3}},
+ {2081, {wxTreeCtrl, setItemText, 2}},
+ {2082, {wxTreeCtrl, setItemTextColour, 2}},
+ {2083, {wxTreeCtrl, setStateImageList, 1}},
+ {2084, {wxTreeCtrl, setWindowStyle, 1}},
+ {2085, {wxTreeCtrl, sortChildren, 1}},
+ {2086, {wxTreeCtrl, toggle, 1}},
+ {2087, {wxTreeCtrl, toggleItemSelection, 1}},
+ {2088, {wxTreeCtrl, unselect, 0}},
+ {2089, {wxTreeCtrl, unselectAll, 0}},
+ {2090, {wxTreeCtrl, unselectItem, 1}},
+ {2091, {wxScrollBar, new_0, 0}},
+ {2092, {wxScrollBar, new_3, 3}},
+ {2093, {wxScrollBar, destruct, 0}},
+ {2094, {wxScrollBar, create, 3}},
+ {2095, {wxScrollBar, getRange, 0}},
+ {2096, {wxScrollBar, getPageSize, 0}},
+ {2097, {wxScrollBar, getThumbPosition, 0}},
+ {2098, {wxScrollBar, getThumbSize, 0}},
+ {2099, {wxScrollBar, setThumbPosition, 1}},
+ {2100, {wxScrollBar, setScrollbar, 5}},
+ {2102, {wxSpinButton, new_2, 2}},
+ {2103, {wxSpinButton, new_0, 0}},
+ {2104, {wxSpinButton, create, 2}},
+ {2105, {wxSpinButton, getMax, 0}},
+ {2106, {wxSpinButton, getMin, 0}},
+ {2107, {wxSpinButton, getValue, 0}},
+ {2108, {wxSpinButton, setRange, 2}},
+ {2109, {wxSpinButton, setValue, 1}},
+ {2110, {wxSpinButton, 'Destroy', undefined}},
+ {2111, {wxSpinCtrl, new_0, 0}},
+ {2112, {wxSpinCtrl, new_2, 2}},
+ {2114, {wxSpinCtrl, create, 2}},
+ {2117, {wxSpinCtrl, setValue_1_1, 1}},
+ {2118, {wxSpinCtrl, setValue_1_0, 1}},
+ {2120, {wxSpinCtrl, getValue, 0}},
+ {2122, {wxSpinCtrl, setRange, 2}},
+ {2123, {wxSpinCtrl, setSelection, 2}},
+ {2125, {wxSpinCtrl, getMin, 0}},
+ {2127, {wxSpinCtrl, getMax, 0}},
+ {2128, {wxSpinCtrl, 'Destroy', undefined}},
+ {2129, {wxStaticText, new_0, 0}},
+ {2130, {wxStaticText, new_4, 4}},
+ {2131, {wxStaticText, create, 4}},
+ {2132, {wxStaticText, getLabel, 0}},
+ {2133, {wxStaticText, setLabel, 1}},
+ {2134, {wxStaticText, wrap, 1}},
+ {2135, {wxStaticText, 'Destroy', undefined}},
+ {2136, {wxStaticBitmap, new_0, 0}},
+ {2137, {wxStaticBitmap, new_4, 4}},
+ {2138, {wxStaticBitmap, create, 4}},
+ {2139, {wxStaticBitmap, getBitmap, 0}},
+ {2140, {wxStaticBitmap, setBitmap, 1}},
+ {2141, {wxStaticBitmap, 'Destroy', undefined}},
+ {2142, {wxRadioBox, new, 7}},
+ {2144, {wxRadioBox, destruct, 0}},
+ {2145, {wxRadioBox, create, 7}},
+ {2146, {wxRadioBox, enable_2, 2}},
+ {2147, {wxRadioBox, enable_1, 1}},
+ {2148, {wxRadioBox, getSelection, 0}},
+ {2149, {wxRadioBox, getString, 1}},
+ {2150, {wxRadioBox, setSelection, 1}},
+ {2151, {wxRadioBox, show_2, 2}},
+ {2152, {wxRadioBox, show_1, 1}},
+ {2153, {wxRadioBox, getColumnCount, 0}},
+ {2154, {wxRadioBox, getItemHelpText, 1}},
+ {2155, {wxRadioBox, getItemToolTip, 1}},
+ {2157, {wxRadioBox, getItemFromPoint, 1}},
+ {2158, {wxRadioBox, getRowCount, 0}},
+ {2159, {wxRadioBox, isItemEnabled, 1}},
+ {2160, {wxRadioBox, isItemShown, 1}},
+ {2161, {wxRadioBox, setItemHelpText, 2}},
+ {2162, {wxRadioBox, setItemToolTip, 2}},
+ {2163, {wxRadioButton, new_0, 0}},
+ {2164, {wxRadioButton, new_4, 4}},
+ {2165, {wxRadioButton, create, 4}},
+ {2166, {wxRadioButton, getValue, 0}},
+ {2167, {wxRadioButton, setValue, 1}},
+ {2168, {wxRadioButton, 'Destroy', undefined}},
+ {2170, {wxSlider, new_6, 6}},
+ {2171, {wxSlider, new_0, 0}},
+ {2172, {wxSlider, create, 6}},
+ {2173, {wxSlider, getLineSize, 0}},
+ {2174, {wxSlider, getMax, 0}},
+ {2175, {wxSlider, getMin, 0}},
+ {2176, {wxSlider, getPageSize, 0}},
+ {2177, {wxSlider, getThumbLength, 0}},
+ {2178, {wxSlider, getValue, 0}},
+ {2179, {wxSlider, setLineSize, 1}},
+ {2180, {wxSlider, setPageSize, 1}},
+ {2181, {wxSlider, setRange, 2}},
+ {2182, {wxSlider, setThumbLength, 1}},
+ {2183, {wxSlider, setValue, 1}},
+ {2184, {wxSlider, 'Destroy', undefined}},
+ {2186, {wxDialog, new_4, 4}},
+ {2187, {wxDialog, new_0, 0}},
+ {2189, {wxDialog, destruct, 0}},
+ {2190, {wxDialog, create, 4}},
+ {2191, {wxDialog, createButtonSizer, 1}},
+ {2192, {wxDialog, createStdDialogButtonSizer, 1}},
+ {2193, {wxDialog, endModal, 1}},
+ {2194, {wxDialog, getAffirmativeId, 0}},
+ {2195, {wxDialog, getReturnCode, 0}},
+ {2196, {wxDialog, isModal, 0}},
+ {2197, {wxDialog, setAffirmativeId, 1}},
+ {2198, {wxDialog, setReturnCode, 1}},
+ {2199, {wxDialog, show, 1}},
+ {2200, {wxDialog, showModal, 0}},
+ {2201, {wxColourDialog, new_0, 0}},
+ {2202, {wxColourDialog, new_2, 2}},
+ {2203, {wxColourDialog, destruct, 0}},
+ {2204, {wxColourDialog, create, 2}},
+ {2205, {wxColourDialog, getColourData, 0}},
+ {2206, {wxColourData, new_0, 0}},
+ {2207, {wxColourData, new_1, 1}},
+ {2208, {wxColourData, destruct, 0}},
+ {2209, {wxColourData, getChooseFull, 0}},
+ {2210, {wxColourData, getColour, 0}},
+ {2212, {wxColourData, getCustomColour, 1}},
+ {2213, {wxColourData, setChooseFull, 1}},
+ {2214, {wxColourData, setColour, 1}},
+ {2215, {wxColourData, setCustomColour, 2}},
+ {2216, {wxPalette, new_0, 0}},
+ {2217, {wxPalette, new_4, 4}},
+ {2219, {wxPalette, destruct, 0}},
+ {2220, {wxPalette, create, 4}},
+ {2221, {wxPalette, getColoursCount, 0}},
+ {2222, {wxPalette, getPixel, 3}},
+ {2223, {wxPalette, getRGB, 4}},
+ {2224, {wxPalette, isOk, 0}},
+ {2228, {wxDirDialog, new, 2}},
+ {2229, {wxDirDialog, destruct, 0}},
+ {2230, {wxDirDialog, getPath, 0}},
+ {2231, {wxDirDialog, getMessage, 0}},
+ {2232, {wxDirDialog, setMessage, 1}},
+ {2233, {wxDirDialog, setPath, 1}},
+ {2237, {wxFileDialog, new, 2}},
+ {2238, {wxFileDialog, destruct, 0}},
+ {2239, {wxFileDialog, getDirectory, 0}},
+ {2240, {wxFileDialog, getFilename, 0}},
+ {2241, {wxFileDialog, getFilenames, 1}},
+ {2242, {wxFileDialog, getFilterIndex, 0}},
+ {2243, {wxFileDialog, getMessage, 0}},
+ {2244, {wxFileDialog, getPath, 0}},
+ {2245, {wxFileDialog, getPaths, 1}},
+ {2246, {wxFileDialog, getWildcard, 0}},
+ {2247, {wxFileDialog, setDirectory, 1}},
+ {2248, {wxFileDialog, setFilename, 1}},
+ {2249, {wxFileDialog, setFilterIndex, 1}},
+ {2250, {wxFileDialog, setMessage, 1}},
+ {2251, {wxFileDialog, setPath, 1}},
+ {2252, {wxFileDialog, setWildcard, 1}},
+ {2253, {wxPickerBase, setInternalMargin, 1}},
+ {2254, {wxPickerBase, getInternalMargin, 0}},
+ {2255, {wxPickerBase, setTextCtrlProportion, 1}},
+ {2256, {wxPickerBase, setPickerCtrlProportion, 1}},
+ {2257, {wxPickerBase, getTextCtrlProportion, 0}},
+ {2258, {wxPickerBase, getPickerCtrlProportion, 0}},
+ {2259, {wxPickerBase, hasTextCtrl, 0}},
+ {2260, {wxPickerBase, getTextCtrl, 0}},
+ {2261, {wxPickerBase, isTextCtrlGrowable, 0}},
+ {2262, {wxPickerBase, setPickerCtrlGrowable, 1}},
+ {2263, {wxPickerBase, setTextCtrlGrowable, 1}},
+ {2264, {wxPickerBase, isPickerCtrlGrowable, 0}},
+ {2265, {wxFilePickerCtrl, new_0, 0}},
+ {2266, {wxFilePickerCtrl, new_3, 3}},
+ {2267, {wxFilePickerCtrl, create, 3}},
+ {2268, {wxFilePickerCtrl, getPath, 0}},
+ {2269, {wxFilePickerCtrl, setPath, 1}},
+ {2270, {wxFilePickerCtrl, 'Destroy', undefined}},
+ {2271, {wxDirPickerCtrl, new_0, 0}},
+ {2272, {wxDirPickerCtrl, new_3, 3}},
+ {2273, {wxDirPickerCtrl, create, 3}},
+ {2274, {wxDirPickerCtrl, getPath, 0}},
+ {2275, {wxDirPickerCtrl, setPath, 1}},
+ {2276, {wxDirPickerCtrl, 'Destroy', undefined}},
+ {2277, {wxColourPickerCtrl, new_0, 0}},
+ {2278, {wxColourPickerCtrl, new_3, 3}},
+ {2279, {wxColourPickerCtrl, create, 3}},
+ {2280, {wxColourPickerCtrl, getColour, 0}},
+ {2281, {wxColourPickerCtrl, setColour_1_1, 1}},
+ {2282, {wxColourPickerCtrl, setColour_1_0, 1}},
+ {2283, {wxColourPickerCtrl, 'Destroy', undefined}},
+ {2284, {wxDatePickerCtrl, new_0, 0}},
+ {2285, {wxDatePickerCtrl, new_3, 3}},
+ {2286, {wxDatePickerCtrl, getRange, 2}},
+ {2287, {wxDatePickerCtrl, getValue, 0}},
+ {2288, {wxDatePickerCtrl, setRange, 2}},
+ {2289, {wxDatePickerCtrl, setValue, 1}},
+ {2290, {wxDatePickerCtrl, 'Destroy', undefined}},
+ {2291, {wxFontPickerCtrl, new_0, 0}},
+ {2292, {wxFontPickerCtrl, new_3, 3}},
+ {2293, {wxFontPickerCtrl, create, 3}},
+ {2294, {wxFontPickerCtrl, getSelectedFont, 0}},
+ {2295, {wxFontPickerCtrl, setSelectedFont, 1}},
+ {2296, {wxFontPickerCtrl, getMaxPointSize, 0}},
+ {2297, {wxFontPickerCtrl, setMaxPointSize, 1}},
+ {2298, {wxFontPickerCtrl, 'Destroy', undefined}},
+ {2301, {wxFindReplaceDialog, new_0, 0}},
+ {2302, {wxFindReplaceDialog, new_4, 4}},
+ {2303, {wxFindReplaceDialog, destruct, 0}},
+ {2304, {wxFindReplaceDialog, create, 4}},
+ {2305, {wxFindReplaceDialog, getData, 0}},
+ {2306, {wxFindReplaceData, new_0, 0}},
+ {2307, {wxFindReplaceData, new_1, 1}},
+ {2308, {wxFindReplaceData, getFindString, 0}},
+ {2309, {wxFindReplaceData, getReplaceString, 0}},
+ {2310, {wxFindReplaceData, getFlags, 0}},
+ {2311, {wxFindReplaceData, setFlags, 1}},
+ {2312, {wxFindReplaceData, setFindString, 1}},
+ {2313, {wxFindReplaceData, setReplaceString, 1}},
+ {2314, {wxFindReplaceData, 'Destroy', undefined}},
+ {2315, {wxMultiChoiceDialog, new_0, 0}},
+ {2317, {wxMultiChoiceDialog, new_5, 5}},
+ {2318, {wxMultiChoiceDialog, getSelections, 0}},
+ {2319, {wxMultiChoiceDialog, setSelections, 1}},
+ {2320, {wxMultiChoiceDialog, 'Destroy', undefined}},
+ {2321, {wxSingleChoiceDialog, new_0, 0}},
+ {2323, {wxSingleChoiceDialog, new_5, 5}},
+ {2324, {wxSingleChoiceDialog, getSelection, 0}},
+ {2325, {wxSingleChoiceDialog, getStringSelection, 0}},
+ {2326, {wxSingleChoiceDialog, setSelection, 1}},
+ {2327, {wxSingleChoiceDialog, 'Destroy', undefined}},
+ {2328, {wxTextEntryDialog, new, 3}},
+ {2329, {wxTextEntryDialog, getValue, 0}},
+ {2330, {wxTextEntryDialog, setValue, 1}},
+ {2331, {wxTextEntryDialog, 'Destroy', undefined}},
+ {2332, {wxPasswordEntryDialog, new, 3}},
+ {2333, {wxPasswordEntryDialog, 'Destroy', undefined}},
+ {2334, {wxFontData, new_0, 0}},
+ {2335, {wxFontData, new_1, 1}},
+ {2336, {wxFontData, destruct, 0}},
+ {2337, {wxFontData, enableEffects, 1}},
+ {2338, {wxFontData, getAllowSymbols, 0}},
+ {2339, {wxFontData, getColour, 0}},
+ {2340, {wxFontData, getChosenFont, 0}},
+ {2341, {wxFontData, getEnableEffects, 0}},
+ {2342, {wxFontData, getInitialFont, 0}},
+ {2343, {wxFontData, getShowHelp, 0}},
+ {2344, {wxFontData, setAllowSymbols, 1}},
+ {2345, {wxFontData, setChosenFont, 1}},
+ {2346, {wxFontData, setColour, 1}},
+ {2347, {wxFontData, setInitialFont, 1}},
+ {2348, {wxFontData, setRange, 2}},
+ {2349, {wxFontData, setShowHelp, 1}},
+ {2353, {wxFontDialog, new_0, 0}},
+ {2355, {wxFontDialog, new_2, 2}},
+ {2357, {wxFontDialog, create, 2}},
+ {2358, {wxFontDialog, getFontData, 0}},
+ {2360, {wxFontDialog, 'Destroy', undefined}},
+ {2361, {wxProgressDialog, new, 3}},
+ {2362, {wxProgressDialog, destruct, 0}},
+ {2363, {wxProgressDialog, resume, 0}},
+ {2364, {wxProgressDialog, update_2, 2}},
+ {2365, {wxProgressDialog, update_0, 0}},
+ {2366, {wxMessageDialog, new, 3}},
+ {2367, {wxMessageDialog, destruct, 0}},
+ {2368, {wxPageSetupDialog, new, 2}},
+ {2369, {wxPageSetupDialog, destruct, 0}},
+ {2370, {wxPageSetupDialog, getPageSetupData, 0}},
+ {2371, {wxPageSetupDialog, showModal, 0}},
+ {2372, {wxPageSetupDialogData, new_0, 0}},
+ {2373, {wxPageSetupDialogData, new_1_0, 1}},
+ {2374, {wxPageSetupDialogData, new_1_1, 1}},
+ {2375, {wxPageSetupDialogData, destruct, 0}},
+ {2376, {wxPageSetupDialogData, enableHelp, 1}},
+ {2377, {wxPageSetupDialogData, enableMargins, 1}},
+ {2378, {wxPageSetupDialogData, enableOrientation, 1}},
+ {2379, {wxPageSetupDialogData, enablePaper, 1}},
+ {2380, {wxPageSetupDialogData, enablePrinter, 1}},
+ {2381, {wxPageSetupDialogData, getDefaultMinMargins, 0}},
+ {2382, {wxPageSetupDialogData, getEnableMargins, 0}},
+ {2383, {wxPageSetupDialogData, getEnableOrientation, 0}},
+ {2384, {wxPageSetupDialogData, getEnablePaper, 0}},
+ {2385, {wxPageSetupDialogData, getEnablePrinter, 0}},
+ {2386, {wxPageSetupDialogData, getEnableHelp, 0}},
+ {2387, {wxPageSetupDialogData, getDefaultInfo, 0}},
+ {2388, {wxPageSetupDialogData, getMarginTopLeft, 0}},
+ {2389, {wxPageSetupDialogData, getMarginBottomRight, 0}},
+ {2390, {wxPageSetupDialogData, getMinMarginTopLeft, 0}},
+ {2391, {wxPageSetupDialogData, getMinMarginBottomRight, 0}},
+ {2392, {wxPageSetupDialogData, getPaperId, 0}},
+ {2393, {wxPageSetupDialogData, getPaperSize, 0}},
+ {2395, {wxPageSetupDialogData, getPrintData, 0}},
+ {2396, {wxPageSetupDialogData, isOk, 0}},
+ {2397, {wxPageSetupDialogData, setDefaultInfo, 1}},
+ {2398, {wxPageSetupDialogData, setDefaultMinMargins, 1}},
+ {2399, {wxPageSetupDialogData, setMarginTopLeft, 1}},
+ {2400, {wxPageSetupDialogData, setMarginBottomRight, 1}},
+ {2401, {wxPageSetupDialogData, setMinMarginTopLeft, 1}},
+ {2402, {wxPageSetupDialogData, setMinMarginBottomRight, 1}},
+ {2403, {wxPageSetupDialogData, setPaperId, 1}},
+ {2404, {wxPageSetupDialogData, setPaperSize_1_1, 1}},
+ {2405, {wxPageSetupDialogData, setPaperSize_1_0, 1}},
+ {2406, {wxPageSetupDialogData, setPrintData, 1}},
+ {2407, {wxPrintDialog, new_2_0, 2}},
+ {2408, {wxPrintDialog, new_2_1, 2}},
+ {2409, {wxPrintDialog, destruct, 0}},
+ {2410, {wxPrintDialog, getPrintDialogData, 0}},
+ {2411, {wxPrintDialog, getPrintDC, 0}},
+ {2412, {wxPrintDialogData, new_0, 0}},
+ {2413, {wxPrintDialogData, new_1_1, 1}},
+ {2414, {wxPrintDialogData, new_1_0, 1}},
+ {2415, {wxPrintDialogData, destruct, 0}},
+ {2416, {wxPrintDialogData, enableHelp, 1}},
+ {2417, {wxPrintDialogData, enablePageNumbers, 1}},
+ {2418, {wxPrintDialogData, enablePrintToFile, 1}},
+ {2419, {wxPrintDialogData, enableSelection, 1}},
+ {2420, {wxPrintDialogData, getAllPages, 0}},
+ {2421, {wxPrintDialogData, getCollate, 0}},
+ {2422, {wxPrintDialogData, getFromPage, 0}},
+ {2423, {wxPrintDialogData, getMaxPage, 0}},
+ {2424, {wxPrintDialogData, getMinPage, 0}},
+ {2425, {wxPrintDialogData, getNoCopies, 0}},
+ {2426, {wxPrintDialogData, getPrintData, 0}},
+ {2427, {wxPrintDialogData, getPrintToFile, 0}},
+ {2428, {wxPrintDialogData, getSelection, 0}},
+ {2429, {wxPrintDialogData, getToPage, 0}},
+ {2430, {wxPrintDialogData, isOk, 0}},
+ {2431, {wxPrintDialogData, setCollate, 1}},
+ {2432, {wxPrintDialogData, setFromPage, 1}},
+ {2433, {wxPrintDialogData, setMaxPage, 1}},
+ {2434, {wxPrintDialogData, setMinPage, 1}},
+ {2435, {wxPrintDialogData, setNoCopies, 1}},
+ {2436, {wxPrintDialogData, setPrintData, 1}},
+ {2437, {wxPrintDialogData, setPrintToFile, 1}},
+ {2438, {wxPrintDialogData, setSelection, 1}},
+ {2439, {wxPrintDialogData, setToPage, 1}},
+ {2440, {wxPrintData, new_0, 0}},
+ {2441, {wxPrintData, new_1, 1}},
+ {2442, {wxPrintData, destruct, 0}},
+ {2443, {wxPrintData, getCollate, 0}},
+ {2444, {wxPrintData, getBin, 0}},
+ {2445, {wxPrintData, getColour, 0}},
+ {2446, {wxPrintData, getDuplex, 0}},
+ {2447, {wxPrintData, getNoCopies, 0}},
+ {2448, {wxPrintData, getOrientation, 0}},
+ {2449, {wxPrintData, getPaperId, 0}},
+ {2450, {wxPrintData, getPrinterName, 0}},
+ {2451, {wxPrintData, getQuality, 0}},
+ {2452, {wxPrintData, isOk, 0}},
+ {2453, {wxPrintData, setBin, 1}},
+ {2454, {wxPrintData, setCollate, 1}},
+ {2455, {wxPrintData, setColour, 1}},
+ {2456, {wxPrintData, setDuplex, 1}},
+ {2457, {wxPrintData, setNoCopies, 1}},
+ {2458, {wxPrintData, setOrientation, 1}},
+ {2459, {wxPrintData, setPaperId, 1}},
+ {2460, {wxPrintData, setPrinterName, 1}},
+ {2461, {wxPrintData, setQuality, 1}},
+ {2464, {wxPrintPreview, new_2, 2}},
+ {2465, {wxPrintPreview, new_3, 3}},
+ {2467, {wxPrintPreview, destruct, 0}},
+ {2468, {wxPrintPreview, getCanvas, 0}},
+ {2469, {wxPrintPreview, getCurrentPage, 0}},
+ {2470, {wxPrintPreview, getFrame, 0}},
+ {2471, {wxPrintPreview, getMaxPage, 0}},
+ {2472, {wxPrintPreview, getMinPage, 0}},
+ {2473, {wxPrintPreview, getPrintout, 0}},
+ {2474, {wxPrintPreview, getPrintoutForPrinting, 0}},
+ {2475, {wxPrintPreview, isOk, 0}},
+ {2476, {wxPrintPreview, paintPage, 2}},
+ {2477, {wxPrintPreview, print, 1}},
+ {2478, {wxPrintPreview, renderPage, 1}},
+ {2479, {wxPrintPreview, setCanvas, 1}},
+ {2480, {wxPrintPreview, setCurrentPage, 1}},
+ {2481, {wxPrintPreview, setFrame, 1}},
+ {2482, {wxPrintPreview, setPrintout, 1}},
+ {2483, {wxPrintPreview, setZoom, 1}},
+ {2484, {wxPreviewFrame, new, 3}},
+ {2485, {wxPreviewFrame, destruct, 0}},
+ {2486, {wxPreviewFrame, createControlBar, 0}},
+ {2487, {wxPreviewFrame, createCanvas, 0}},
+ {2488, {wxPreviewFrame, initialize, 0}},
+ {2489, {wxPreviewFrame, onCloseWindow, 1}},
+ {2490, {wxPreviewControlBar, new, 4}},
+ {2491, {wxPreviewControlBar, destruct, 0}},
+ {2492, {wxPreviewControlBar, createButtons, 0}},
+ {2493, {wxPreviewControlBar, getPrintPreview, 0}},
+ {2494, {wxPreviewControlBar, getZoomControl, 0}},
+ {2495, {wxPreviewControlBar, setZoomControl, 1}},
+ {2497, {wxPrinter, new, 1}},
+ {2498, {wxPrinter, createAbortWindow, 2}},
+ {2499, {wxPrinter, getAbort, 0}},
+ {2500, {wxPrinter, getLastError, 0}},
+ {2501, {wxPrinter, getPrintDialogData, 0}},
+ {2502, {wxPrinter, print, 3}},
+ {2503, {wxPrinter, printDialog, 1}},
+ {2504, {wxPrinter, reportError, 3}},
+ {2505, {wxPrinter, setup, 1}},
+ {2506, {wxPrinter, 'Destroy', undefined}},
+ {2507, {wxXmlResource, new_1, 1}},
+ {2508, {wxXmlResource, new_2, 2}},
+ {2509, {wxXmlResource, destruct, 0}},
+ {2510, {wxXmlResource, attachUnknownControl, 3}},
+ {2511, {wxXmlResource, clearHandlers, 0}},
+ {2512, {wxXmlResource, compareVersion, 4}},
+ {2513, {wxXmlResource, get, 0}},
+ {2514, {wxXmlResource, getFlags, 0}},
+ {2515, {wxXmlResource, getVersion, 0}},
+ {2516, {wxXmlResource, getXRCID, 2}},
+ {2517, {wxXmlResource, initAllHandlers, 0}},
+ {2518, {wxXmlResource, load, 1}},
+ {2519, {wxXmlResource, loadBitmap, 1}},
+ {2520, {wxXmlResource, loadDialog_2, 2}},
+ {2521, {wxXmlResource, loadDialog_3, 3}},
+ {2522, {wxXmlResource, loadFrame_2, 2}},
+ {2523, {wxXmlResource, loadFrame_3, 3}},
+ {2524, {wxXmlResource, loadIcon, 1}},
+ {2525, {wxXmlResource, loadMenu, 1}},
+ {2526, {wxXmlResource, loadMenuBar_2, 2}},
+ {2527, {wxXmlResource, loadMenuBar_1, 1}},
+ {2528, {wxXmlResource, loadPanel_2, 2}},
+ {2529, {wxXmlResource, loadPanel_3, 3}},
+ {2530, {wxXmlResource, loadToolBar, 2}},
+ {2531, {wxXmlResource, set, 1}},
+ {2532, {wxXmlResource, setFlags, 1}},
+ {2533, {wxXmlResource, unload, 1}},
+ {2534, {wxXmlResource, xrcctrl, 3}},
+ {2535, {wxHtmlEasyPrinting, new, 1}},
+ {2536, {wxHtmlEasyPrinting, destruct, 0}},
+ {2537, {wxHtmlEasyPrinting, getPrintData, 0}},
+ {2538, {wxHtmlEasyPrinting, getPageSetupData, 0}},
+ {2539, {wxHtmlEasyPrinting, previewFile, 1}},
+ {2540, {wxHtmlEasyPrinting, previewText, 2}},
+ {2541, {wxHtmlEasyPrinting, printFile, 1}},
+ {2542, {wxHtmlEasyPrinting, printText, 2}},
+ {2543, {wxHtmlEasyPrinting, pageSetup, 0}},
+ {2544, {wxHtmlEasyPrinting, setFonts, 3}},
+ {2545, {wxHtmlEasyPrinting, setHeader, 2}},
+ {2546, {wxHtmlEasyPrinting, setFooter, 2}},
+ {2548, {wxGLCanvas, new_2, 2}},
+ {2549, {wxGLCanvas, new_3_1, 3}},
+ {2550, {wxGLCanvas, new_3_0, 3}},
+ {2551, {wxGLCanvas, getContext, 0}},
+ {2553, {wxGLCanvas, setCurrent, 0}},
+ {2554, {wxGLCanvas, swapBuffers, 0}},
+ {2555, {wxGLCanvas, 'Destroy', undefined}},
+ {2556, {wxAuiManager, new, 1}},
+ {2557, {wxAuiManager, destruct, 0}},
+ {2558, {wxAuiManager, addPane_2_1, 2}},
+ {2559, {wxAuiManager, addPane_3, 3}},
+ {2560, {wxAuiManager, addPane_2_0, 2}},
+ {2561, {wxAuiManager, detachPane, 1}},
+ {2562, {wxAuiManager, getAllPanes, 0}},
+ {2563, {wxAuiManager, getArtProvider, 0}},
+ {2564, {wxAuiManager, getDockSizeConstraint, 2}},
+ {2565, {wxAuiManager, getFlags, 0}},
+ {2566, {wxAuiManager, getManagedWindow, 0}},
+ {2567, {wxAuiManager, getManager, 1}},
+ {2568, {wxAuiManager, getPane_1_1, 1}},
+ {2569, {wxAuiManager, getPane_1_0, 1}},
+ {2570, {wxAuiManager, hideHint, 0}},
+ {2571, {wxAuiManager, insertPane, 3}},
+ {2572, {wxAuiManager, loadPaneInfo, 2}},
+ {2573, {wxAuiManager, loadPerspective, 2}},
+ {2574, {wxAuiManager, savePaneInfo, 1}},
+ {2575, {wxAuiManager, savePerspective, 0}},
+ {2576, {wxAuiManager, setArtProvider, 1}},
+ {2577, {wxAuiManager, setDockSizeConstraint, 2}},
+ {2578, {wxAuiManager, setFlags, 1}},
+ {2579, {wxAuiManager, setManagedWindow, 1}},
+ {2580, {wxAuiManager, showHint, 1}},
+ {2581, {wxAuiManager, unInit, 0}},
+ {2582, {wxAuiManager, update, 0}},
+ {2583, {wxAuiPaneInfo, new_0, 0}},
+ {2584, {wxAuiPaneInfo, new_1, 1}},
+ {2585, {wxAuiPaneInfo, destruct, 0}},
+ {2586, {wxAuiPaneInfo, bestSize_1, 1}},
+ {2587, {wxAuiPaneInfo, bestSize_2, 2}},
+ {2588, {wxAuiPaneInfo, bottom, 0}},
+ {2589, {wxAuiPaneInfo, bottomDockable, 1}},
+ {2590, {wxAuiPaneInfo, caption, 1}},
+ {2591, {wxAuiPaneInfo, captionVisible, 1}},
+ {2592, {wxAuiPaneInfo, centre, 0}},
+ {2593, {wxAuiPaneInfo, centrePane, 0}},
+ {2594, {wxAuiPaneInfo, closeButton, 1}},
+ {2595, {wxAuiPaneInfo, defaultPane, 0}},
+ {2596, {wxAuiPaneInfo, destroyOnClose, 1}},
+ {2597, {wxAuiPaneInfo, direction, 1}},
+ {2598, {wxAuiPaneInfo, dock, 0}},
+ {2599, {wxAuiPaneInfo, dockable, 1}},
+ {2600, {wxAuiPaneInfo, fixed, 0}},
+ {2601, {wxAuiPaneInfo, float, 0}},
+ {2602, {wxAuiPaneInfo, floatable, 1}},
+ {2603, {wxAuiPaneInfo, floatingPosition_1, 1}},
+ {2604, {wxAuiPaneInfo, floatingPosition_2, 2}},
+ {2605, {wxAuiPaneInfo, floatingSize_1, 1}},
+ {2606, {wxAuiPaneInfo, floatingSize_2, 2}},
+ {2607, {wxAuiPaneInfo, gripper, 1}},
+ {2608, {wxAuiPaneInfo, gripperTop, 1}},
+ {2609, {wxAuiPaneInfo, hasBorder, 0}},
+ {2610, {wxAuiPaneInfo, hasCaption, 0}},
+ {2611, {wxAuiPaneInfo, hasCloseButton, 0}},
+ {2612, {wxAuiPaneInfo, hasFlag, 1}},
+ {2613, {wxAuiPaneInfo, hasGripper, 0}},
+ {2614, {wxAuiPaneInfo, hasGripperTop, 0}},
+ {2615, {wxAuiPaneInfo, hasMaximizeButton, 0}},
+ {2616, {wxAuiPaneInfo, hasMinimizeButton, 0}},
+ {2617, {wxAuiPaneInfo, hasPinButton, 0}},
+ {2618, {wxAuiPaneInfo, hide, 0}},
+ {2619, {wxAuiPaneInfo, isBottomDockable, 0}},
+ {2620, {wxAuiPaneInfo, isDocked, 0}},
+ {2621, {wxAuiPaneInfo, isFixed, 0}},
+ {2622, {wxAuiPaneInfo, isFloatable, 0}},
+ {2623, {wxAuiPaneInfo, isFloating, 0}},
+ {2624, {wxAuiPaneInfo, isLeftDockable, 0}},
+ {2625, {wxAuiPaneInfo, isMovable, 0}},
+ {2626, {wxAuiPaneInfo, isOk, 0}},
+ {2627, {wxAuiPaneInfo, isResizable, 0}},
+ {2628, {wxAuiPaneInfo, isRightDockable, 0}},
+ {2629, {wxAuiPaneInfo, isShown, 0}},
+ {2630, {wxAuiPaneInfo, isToolbar, 0}},
+ {2631, {wxAuiPaneInfo, isTopDockable, 0}},
+ {2632, {wxAuiPaneInfo, layer, 1}},
+ {2633, {wxAuiPaneInfo, left, 0}},
+ {2634, {wxAuiPaneInfo, leftDockable, 1}},
+ {2635, {wxAuiPaneInfo, maxSize_1, 1}},
+ {2636, {wxAuiPaneInfo, maxSize_2, 2}},
+ {2637, {wxAuiPaneInfo, maximizeButton, 1}},
+ {2638, {wxAuiPaneInfo, minSize_1, 1}},
+ {2639, {wxAuiPaneInfo, minSize_2, 2}},
+ {2640, {wxAuiPaneInfo, minimizeButton, 1}},
+ {2641, {wxAuiPaneInfo, movable, 1}},
+ {2642, {wxAuiPaneInfo, name, 1}},
+ {2643, {wxAuiPaneInfo, paneBorder, 1}},
+ {2644, {wxAuiPaneInfo, pinButton, 1}},
+ {2645, {wxAuiPaneInfo, position, 1}},
+ {2646, {wxAuiPaneInfo, resizable, 1}},
+ {2647, {wxAuiPaneInfo, right, 0}},
+ {2648, {wxAuiPaneInfo, rightDockable, 1}},
+ {2649, {wxAuiPaneInfo, row, 1}},
+ {2650, {wxAuiPaneInfo, safeSet, 1}},
+ {2651, {wxAuiPaneInfo, setFlag, 2}},
+ {2652, {wxAuiPaneInfo, show, 1}},
+ {2653, {wxAuiPaneInfo, toolbarPane, 0}},
+ {2654, {wxAuiPaneInfo, top, 0}},
+ {2655, {wxAuiPaneInfo, topDockable, 1}},
+ {2656, {wxAuiPaneInfo, window, 1}},
+ {2657, {wxAuiPaneInfo, getWindow, 0}},
+ {2658, {wxAuiPaneInfo, getFrame, 0}},
+ {2659, {wxAuiPaneInfo, getDirection, 0}},
+ {2660, {wxAuiPaneInfo, getLayer, 0}},
+ {2661, {wxAuiPaneInfo, getRow, 0}},
+ {2662, {wxAuiPaneInfo, getPosition, 0}},
+ {2663, {wxAuiPaneInfo, getFloatingPosition, 0}},
+ {2664, {wxAuiPaneInfo, getFloatingSize, 0}},
+ {2665, {wxAuiNotebook, new_0, 0}},
+ {2666, {wxAuiNotebook, new_2, 2}},
+ {2667, {wxAuiNotebook, addPage, 3}},
+ {2668, {wxAuiNotebook, create, 2}},
+ {2669, {wxAuiNotebook, deletePage, 1}},
+ {2670, {wxAuiNotebook, getArtProvider, 0}},
+ {2671, {wxAuiNotebook, getPage, 1}},
+ {2672, {wxAuiNotebook, getPageBitmap, 1}},
+ {2673, {wxAuiNotebook, getPageCount, 0}},
+ {2674, {wxAuiNotebook, getPageIndex, 1}},
+ {2675, {wxAuiNotebook, getPageText, 1}},
+ {2676, {wxAuiNotebook, getSelection, 0}},
+ {2677, {wxAuiNotebook, insertPage, 4}},
+ {2678, {wxAuiNotebook, removePage, 1}},
+ {2679, {wxAuiNotebook, setArtProvider, 1}},
+ {2680, {wxAuiNotebook, setFont, 1}},
+ {2681, {wxAuiNotebook, setPageBitmap, 2}},
+ {2682, {wxAuiNotebook, setPageText, 2}},
+ {2683, {wxAuiNotebook, setSelection, 1}},
+ {2684, {wxAuiNotebook, setTabCtrlHeight, 1}},
+ {2685, {wxAuiNotebook, setUniformBitmapSize, 1}},
+ {2686, {wxAuiNotebook, 'Destroy', undefined}},
+ {2687, {wxAuiTabArt, setFlags, 1}},
+ {2688, {wxAuiTabArt, setMeasuringFont, 1}},
+ {2689, {wxAuiTabArt, setNormalFont, 1}},
+ {2690, {wxAuiTabArt, setSelectedFont, 1}},
+ {2691, {wxAuiTabArt, setColour, 1}},
+ {2692, {wxAuiTabArt, setActiveColour, 1}},
+ {2693, {wxAuiDockArt, getColour, 1}},
+ {2694, {wxAuiDockArt, getFont, 1}},
+ {2695, {wxAuiDockArt, getMetric, 1}},
+ {2696, {wxAuiDockArt, setColour, 2}},
+ {2697, {wxAuiDockArt, setFont, 2}},
+ {2698, {wxAuiDockArt, setMetric, 2}},
+ {2699, {wxAuiSimpleTabArt, new, 0}},
+ {2700, {wxAuiSimpleTabArt, 'Destroy', undefined}},
+ {2701, {wxMDIParentFrame, new_0, 0}},
+ {2702, {wxMDIParentFrame, new_4, 4}},
+ {2703, {wxMDIParentFrame, destruct, 0}},
+ {2704, {wxMDIParentFrame, activateNext, 0}},
+ {2705, {wxMDIParentFrame, activatePrevious, 0}},
+ {2706, {wxMDIParentFrame, arrangeIcons, 0}},
+ {2707, {wxMDIParentFrame, cascade, 0}},
+ {2708, {wxMDIParentFrame, create, 4}},
+ {2709, {wxMDIParentFrame, getActiveChild, 0}},
+ {2710, {wxMDIParentFrame, getClientWindow, 0}},
+ {2711, {wxMDIParentFrame, tile, 1}},
+ {2712, {wxMDIChildFrame, new_0, 0}},
+ {2713, {wxMDIChildFrame, new_4, 4}},
+ {2714, {wxMDIChildFrame, destruct, 0}},
+ {2715, {wxMDIChildFrame, activate, 0}},
+ {2716, {wxMDIChildFrame, create, 4}},
+ {2717, {wxMDIChildFrame, maximize, 1}},
+ {2718, {wxMDIChildFrame, restore, 0}},
+ {2719, {wxMDIClientWindow, new_0, 0}},
+ {2720, {wxMDIClientWindow, new_2, 2}},
+ {2721, {wxMDIClientWindow, destruct, 0}},
+ {2722, {wxMDIClientWindow, createClient, 2}},
+ {2723, {wxLayoutAlgorithm, new, 0}},
+ {2724, {wxLayoutAlgorithm, layoutFrame, 2}},
+ {2725, {wxLayoutAlgorithm, layoutMDIFrame, 2}},
+ {2726, {wxLayoutAlgorithm, layoutWindow, 2}},
+ {2727, {wxLayoutAlgorithm, 'Destroy', undefined}},
+ {2728, {wxEvent, getId, 0}},
+ {2729, {wxEvent, getSkipped, 0}},
+ {2730, {wxEvent, getTimestamp, 0}},
+ {2731, {wxEvent, isCommandEvent, 0}},
+ {2732, {wxEvent, resumePropagation, 1}},
+ {2733, {wxEvent, shouldPropagate, 0}},
+ {2734, {wxEvent, skip, 1}},
+ {2735, {wxEvent, stopPropagation, 0}},
+ {2736, {wxCommandEvent, getClientData, 0}},
+ {2737, {wxCommandEvent, getExtraLong, 0}},
+ {2738, {wxCommandEvent, getInt, 0}},
+ {2739, {wxCommandEvent, getSelection, 0}},
+ {2740, {wxCommandEvent, getString, 0}},
+ {2741, {wxCommandEvent, isChecked, 0}},
+ {2742, {wxCommandEvent, isSelection, 0}},
+ {2743, {wxCommandEvent, setInt, 1}},
+ {2744, {wxCommandEvent, setString, 1}},
+ {2745, {wxScrollEvent, getOrientation, 0}},
+ {2746, {wxScrollEvent, getPosition, 0}},
+ {2747, {wxScrollWinEvent, getOrientation, 0}},
+ {2748, {wxScrollWinEvent, getPosition, 0}},
+ {2749, {wxMouseEvent, altDown, 0}},
+ {2750, {wxMouseEvent, button, 1}},
+ {2751, {wxMouseEvent, buttonDClick, 1}},
+ {2752, {wxMouseEvent, buttonDown, 1}},
+ {2753, {wxMouseEvent, buttonUp, 1}},
+ {2754, {wxMouseEvent, cmdDown, 0}},
+ {2755, {wxMouseEvent, controlDown, 0}},
+ {2756, {wxMouseEvent, dragging, 0}},
+ {2757, {wxMouseEvent, entering, 0}},
+ {2758, {wxMouseEvent, getButton, 0}},
+ {2761, {wxMouseEvent, getPosition, 0}},
+ {2762, {wxMouseEvent, getLogicalPosition, 1}},
+ {2763, {wxMouseEvent, getLinesPerAction, 0}},
+ {2764, {wxMouseEvent, getWheelRotation, 0}},
+ {2765, {wxMouseEvent, getWheelDelta, 0}},
+ {2766, {wxMouseEvent, getX, 0}},
+ {2767, {wxMouseEvent, getY, 0}},
+ {2768, {wxMouseEvent, isButton, 0}},
+ {2769, {wxMouseEvent, isPageScroll, 0}},
+ {2770, {wxMouseEvent, leaving, 0}},
+ {2771, {wxMouseEvent, leftDClick, 0}},
+ {2772, {wxMouseEvent, leftDown, 0}},
+ {2773, {wxMouseEvent, leftIsDown, 0}},
+ {2774, {wxMouseEvent, leftUp, 0}},
+ {2775, {wxMouseEvent, metaDown, 0}},
+ {2776, {wxMouseEvent, middleDClick, 0}},
+ {2777, {wxMouseEvent, middleDown, 0}},
+ {2778, {wxMouseEvent, middleIsDown, 0}},
+ {2779, {wxMouseEvent, middleUp, 0}},
+ {2780, {wxMouseEvent, moving, 0}},
+ {2781, {wxMouseEvent, rightDClick, 0}},
+ {2782, {wxMouseEvent, rightDown, 0}},
+ {2783, {wxMouseEvent, rightIsDown, 0}},
+ {2784, {wxMouseEvent, rightUp, 0}},
+ {2785, {wxMouseEvent, shiftDown, 0}},
+ {2786, {wxSetCursorEvent, getCursor, 0}},
+ {2787, {wxSetCursorEvent, getX, 0}},
+ {2788, {wxSetCursorEvent, getY, 0}},
+ {2789, {wxSetCursorEvent, hasCursor, 0}},
+ {2790, {wxSetCursorEvent, setCursor, 1}},
+ {2791, {wxKeyEvent, altDown, 0}},
+ {2792, {wxKeyEvent, cmdDown, 0}},
+ {2793, {wxKeyEvent, controlDown, 0}},
+ {2794, {wxKeyEvent, getKeyCode, 0}},
+ {2795, {wxKeyEvent, getModifiers, 0}},
+ {2798, {wxKeyEvent, getPosition, 0}},
+ {2799, {wxKeyEvent, getRawKeyCode, 0}},
+ {2800, {wxKeyEvent, getRawKeyFlags, 0}},
+ {2801, {wxKeyEvent, getUnicodeKey, 0}},
+ {2802, {wxKeyEvent, getX, 0}},
+ {2803, {wxKeyEvent, getY, 0}},
+ {2804, {wxKeyEvent, hasModifiers, 0}},
+ {2805, {wxKeyEvent, metaDown, 0}},
+ {2806, {wxKeyEvent, shiftDown, 0}},
+ {2807, {wxSizeEvent, getSize, 0}},
+ {2808, {wxMoveEvent, getPosition, 0}},
+ {2809, {wxEraseEvent, getDC, 0}},
+ {2810, {wxFocusEvent, getWindow, 0}},
+ {2811, {wxChildFocusEvent, getWindow, 0}},
+ {2812, {wxMenuEvent, getMenu, 0}},
+ {2813, {wxMenuEvent, getMenuId, 0}},
+ {2814, {wxMenuEvent, isPopup, 0}},
+ {2815, {wxCloseEvent, canVeto, 0}},
+ {2816, {wxCloseEvent, getLoggingOff, 0}},
+ {2817, {wxCloseEvent, setCanVeto, 1}},
+ {2818, {wxCloseEvent, setLoggingOff, 1}},
+ {2819, {wxCloseEvent, veto, 1}},
+ {2820, {wxShowEvent, setShow, 1}},
+ {2821, {wxShowEvent, getShow, 0}},
+ {2822, {wxIconizeEvent, iconized, 0}},
+ {2823, {wxJoystickEvent, buttonDown, 1}},
+ {2824, {wxJoystickEvent, buttonIsDown, 1}},
+ {2825, {wxJoystickEvent, buttonUp, 1}},
+ {2826, {wxJoystickEvent, getButtonChange, 0}},
+ {2827, {wxJoystickEvent, getButtonState, 0}},
+ {2828, {wxJoystickEvent, getJoystick, 0}},
+ {2829, {wxJoystickEvent, getPosition, 0}},
+ {2830, {wxJoystickEvent, getZPosition, 0}},
+ {2831, {wxJoystickEvent, isButton, 0}},
+ {2832, {wxJoystickEvent, isMove, 0}},
+ {2833, {wxJoystickEvent, isZMove, 0}},
+ {2834, {wxUpdateUIEvent, canUpdate, 1}},
+ {2835, {wxUpdateUIEvent, check, 1}},
+ {2836, {wxUpdateUIEvent, enable, 1}},
+ {2837, {wxUpdateUIEvent, show, 1}},
+ {2838, {wxUpdateUIEvent, getChecked, 0}},
+ {2839, {wxUpdateUIEvent, getEnabled, 0}},
+ {2840, {wxUpdateUIEvent, getShown, 0}},
+ {2841, {wxUpdateUIEvent, getSetChecked, 0}},
+ {2842, {wxUpdateUIEvent, getSetEnabled, 0}},
+ {2843, {wxUpdateUIEvent, getSetShown, 0}},
+ {2844, {wxUpdateUIEvent, getSetText, 0}},
+ {2845, {wxUpdateUIEvent, getText, 0}},
+ {2846, {wxUpdateUIEvent, getMode, 0}},
+ {2847, {wxUpdateUIEvent, getUpdateInterval, 0}},
+ {2848, {wxUpdateUIEvent, resetUpdateTime, 0}},
+ {2849, {wxUpdateUIEvent, setMode, 1}},
+ {2850, {wxUpdateUIEvent, setText, 1}},
+ {2851, {wxUpdateUIEvent, setUpdateInterval, 1}},
+ {2852, {wxMouseCaptureChangedEvent, getCapturedWindow, 0}},
+ {2853, {wxPaletteChangedEvent, setChangedWindow, 1}},
+ {2854, {wxPaletteChangedEvent, getChangedWindow, 0}},
+ {2855, {wxQueryNewPaletteEvent, setPaletteRealized, 1}},
+ {2856, {wxQueryNewPaletteEvent, getPaletteRealized, 0}},
+ {2857, {wxNavigationKeyEvent, getDirection, 0}},
+ {2858, {wxNavigationKeyEvent, setDirection, 1}},
+ {2859, {wxNavigationKeyEvent, isWindowChange, 0}},
+ {2860, {wxNavigationKeyEvent, setWindowChange, 1}},
+ {2861, {wxNavigationKeyEvent, isFromTab, 0}},
+ {2862, {wxNavigationKeyEvent, setFromTab, 1}},
+ {2863, {wxNavigationKeyEvent, getCurrentFocus, 0}},
+ {2864, {wxNavigationKeyEvent, setCurrentFocus, 1}},
+ {2865, {wxHelpEvent, getOrigin, 0}},
+ {2866, {wxHelpEvent, getPosition, 0}},
+ {2867, {wxHelpEvent, setOrigin, 1}},
+ {2868, {wxHelpEvent, setPosition, 1}},
+ {2869, {wxContextMenuEvent, getPosition, 0}},
+ {2870, {wxContextMenuEvent, setPosition, 1}},
+ {2871, {wxIdleEvent, canSend, 1}},
+ {2872, {wxIdleEvent, getMode, 0}},
+ {2873, {wxIdleEvent, requestMore, 1}},
+ {2874, {wxIdleEvent, moreRequested, 0}},
+ {2875, {wxIdleEvent, setMode, 1}},
+ {2876, {wxGridEvent, altDown, 0}},
+ {2877, {wxGridEvent, controlDown, 0}},
+ {2878, {wxGridEvent, getCol, 0}},
+ {2879, {wxGridEvent, getPosition, 0}},
+ {2880, {wxGridEvent, getRow, 0}},
+ {2881, {wxGridEvent, metaDown, 0}},
+ {2882, {wxGridEvent, selecting, 0}},
+ {2883, {wxGridEvent, shiftDown, 0}},
+ {2884, {wxNotifyEvent, allow, 0}},
+ {2885, {wxNotifyEvent, isAllowed, 0}},
+ {2886, {wxNotifyEvent, veto, 0}},
+ {2887, {wxSashEvent, getEdge, 0}},
+ {2888, {wxSashEvent, getDragRect, 0}},
+ {2889, {wxSashEvent, getDragStatus, 0}},
+ {2890, {wxListEvent, getCacheFrom, 0}},
+ {2891, {wxListEvent, getCacheTo, 0}},
+ {2892, {wxListEvent, getKeyCode, 0}},
+ {2893, {wxListEvent, getIndex, 0}},
+ {2894, {wxListEvent, getColumn, 0}},
+ {2895, {wxListEvent, getPoint, 0}},
+ {2896, {wxListEvent, getLabel, 0}},
+ {2897, {wxListEvent, getText, 0}},
+ {2898, {wxListEvent, getImage, 0}},
+ {2899, {wxListEvent, getData, 0}},
+ {2900, {wxListEvent, getMask, 0}},
+ {2901, {wxListEvent, getItem, 0}},
+ {2902, {wxListEvent, isEditCancelled, 0}},
+ {2903, {wxDateEvent, getDate, 0}},
+ {2904, {wxCalendarEvent, getWeekDay, 0}},
+ {2905, {wxFileDirPickerEvent, getPath, 0}},
+ {2906, {wxColourPickerEvent, getColour, 0}},
+ {2907, {wxFontPickerEvent, getFont, 0}},
+ {2908, {wxStyledTextEvent, getPosition, 0}},
+ {2909, {wxStyledTextEvent, getKey, 0}},
+ {2910, {wxStyledTextEvent, getModifiers, 0}},
+ {2911, {wxStyledTextEvent, getModificationType, 0}},
+ {2912, {wxStyledTextEvent, getText, 0}},
+ {2913, {wxStyledTextEvent, getLength, 0}},
+ {2914, {wxStyledTextEvent, getLinesAdded, 0}},
+ {2915, {wxStyledTextEvent, getLine, 0}},
+ {2916, {wxStyledTextEvent, getFoldLevelNow, 0}},
+ {2917, {wxStyledTextEvent, getFoldLevelPrev, 0}},
+ {2918, {wxStyledTextEvent, getMargin, 0}},
+ {2919, {wxStyledTextEvent, getMessage, 0}},
+ {2920, {wxStyledTextEvent, getWParam, 0}},
+ {2921, {wxStyledTextEvent, getLParam, 0}},
+ {2922, {wxStyledTextEvent, getListType, 0}},
+ {2923, {wxStyledTextEvent, getX, 0}},
+ {2924, {wxStyledTextEvent, getY, 0}},
+ {2925, {wxStyledTextEvent, getDragText, 0}},
+ {2926, {wxStyledTextEvent, getDragAllowMove, 0}},
+ {2927, {wxStyledTextEvent, getDragResult, 0}},
+ {2928, {wxStyledTextEvent, getShift, 0}},
+ {2929, {wxStyledTextEvent, getControl, 0}},
+ {2930, {wxStyledTextEvent, getAlt, 0}},
+ {2931, {utils, getKeyState, 1}},
+ {2932, {utils, getMousePosition, 2}},
+ {2933, {utils, getMouseState, 0}},
+ {2934, {utils, setDetectableAutoRepeat, 1}},
+ {2935, {utils, bell, 0}},
+ {2936, {utils, findMenuItemId, 3}},
+ {2937, {utils, genericFindWindowAtPoint, 1}},
+ {2938, {utils, findWindowAtPoint, 1}},
+ {2939, {utils, beginBusyCursor, 1}},
+ {2940, {utils, endBusyCursor, 0}},
+ {2941, {utils, isBusy, 0}},
+ {2942, {utils, shutdown, 1}},
+ {2943, {utils, shell, 1}},
+ {2944, {utils, launchDefaultBrowser, 2}},
+ {2945, {utils, getEmailAddress, 0}},
+ {2946, {utils, getUserId, 0}},
+ {2947, {utils, getHomeDir, 0}},
+ {2948, {utils, newId, 0}},
+ {2949, {utils, registerId, 1}},
+ {2950, {utils, getCurrentId, 0}},
+ {2951, {utils, getOsDescription, 0}},
+ {2952, {utils, isPlatformLittleEndian, 0}},
+ {2953, {utils, isPlatform64Bit, 0}},
+ {2954, {gdicmn, displaySize, 2}},
+ {2955, {gdicmn, setCursor, 1}},
+ {2956, {wxPrintout, new, 1}},
+ {2957, {wxPrintout, destruct, 0}},
+ {2958, {wxPrintout, getDC, 0}},
+ {2959, {wxPrintout, getPageSizeMM, 2}},
+ {2960, {wxPrintout, getPageSizePixels, 2}},
+ {2961, {wxPrintout, getPaperRectPixels, 0}},
+ {2962, {wxPrintout, getPPIPrinter, 2}},
+ {2963, {wxPrintout, getPPIScreen, 2}},
+ {2964, {wxPrintout, getTitle, 0}},
+ {2965, {wxPrintout, isPreview, 0}},
+ {2966, {wxPrintout, fitThisSizeToPaper, 1}},
+ {2967, {wxPrintout, fitThisSizeToPage, 1}},
+ {2968, {wxPrintout, fitThisSizeToPageMargins, 2}},
+ {2969, {wxPrintout, mapScreenSizeToPaper, 0}},
+ {2970, {wxPrintout, mapScreenSizeToPage, 0}},
+ {2971, {wxPrintout, mapScreenSizeToPageMargins, 1}},
+ {2972, {wxPrintout, mapScreenSizeToDevice, 0}},
+ {2973, {wxPrintout, getLogicalPaperRect, 0}},
+ {2974, {wxPrintout, getLogicalPageRect, 0}},
+ {2975, {wxPrintout, getLogicalPageMarginsRect, 1}},
+ {2976, {wxPrintout, setLogicalOrigin, 2}},
+ {2977, {wxPrintout, offsetLogicalOrigin, 2}},
+ {2978, {wxStyledTextCtrl, new_2, 2}},
+ {2979, {wxStyledTextCtrl, new_0, 0}},
+ {2980, {wxStyledTextCtrl, destruct, 0}},
+ {2981, {wxStyledTextCtrl, create, 2}},
+ {2982, {wxStyledTextCtrl, addText, 1}},
+ {2983, {wxStyledTextCtrl, addStyledText, 1}},
+ {2984, {wxStyledTextCtrl, insertText, 2}},
+ {2985, {wxStyledTextCtrl, clearAll, 0}},
+ {2986, {wxStyledTextCtrl, clearDocumentStyle, 0}},
+ {2987, {wxStyledTextCtrl, getLength, 0}},
+ {2988, {wxStyledTextCtrl, getCharAt, 1}},
+ {2989, {wxStyledTextCtrl, getCurrentPos, 0}},
+ {2990, {wxStyledTextCtrl, getAnchor, 0}},
+ {2991, {wxStyledTextCtrl, getStyleAt, 1}},
+ {2992, {wxStyledTextCtrl, redo, 0}},
+ {2993, {wxStyledTextCtrl, setUndoCollection, 1}},
+ {2994, {wxStyledTextCtrl, selectAll, 0}},
+ {2995, {wxStyledTextCtrl, setSavePoint, 0}},
+ {2996, {wxStyledTextCtrl, getStyledText, 2}},
+ {2997, {wxStyledTextCtrl, canRedo, 0}},
+ {2998, {wxStyledTextCtrl, markerLineFromHandle, 1}},
+ {2999, {wxStyledTextCtrl, markerDeleteHandle, 1}},
+ {3000, {wxStyledTextCtrl, getUndoCollection, 0}},
+ {3001, {wxStyledTextCtrl, getViewWhiteSpace, 0}},
+ {3002, {wxStyledTextCtrl, setViewWhiteSpace, 1}},
+ {3003, {wxStyledTextCtrl, positionFromPoint, 1}},
+ {3004, {wxStyledTextCtrl, positionFromPointClose, 2}},
+ {3005, {wxStyledTextCtrl, gotoLine, 1}},
+ {3006, {wxStyledTextCtrl, gotoPos, 1}},
+ {3007, {wxStyledTextCtrl, setAnchor, 1}},
+ {3008, {wxStyledTextCtrl, getCurLine, 1}},
+ {3009, {wxStyledTextCtrl, getEndStyled, 0}},
+ {3010, {wxStyledTextCtrl, convertEOLs, 1}},
+ {3011, {wxStyledTextCtrl, getEOLMode, 0}},
+ {3012, {wxStyledTextCtrl, setEOLMode, 1}},
+ {3013, {wxStyledTextCtrl, startStyling, 2}},
+ {3014, {wxStyledTextCtrl, setStyling, 2}},
+ {3015, {wxStyledTextCtrl, getBufferedDraw, 0}},
+ {3016, {wxStyledTextCtrl, setBufferedDraw, 1}},
+ {3017, {wxStyledTextCtrl, setTabWidth, 1}},
+ {3018, {wxStyledTextCtrl, getTabWidth, 0}},
+ {3019, {wxStyledTextCtrl, setCodePage, 1}},
+ {3020, {wxStyledTextCtrl, markerDefine, 3}},
+ {3021, {wxStyledTextCtrl, markerSetForeground, 2}},
+ {3022, {wxStyledTextCtrl, markerSetBackground, 2}},
+ {3023, {wxStyledTextCtrl, markerAdd, 2}},
+ {3024, {wxStyledTextCtrl, markerDelete, 2}},
+ {3025, {wxStyledTextCtrl, markerDeleteAll, 1}},
+ {3026, {wxStyledTextCtrl, markerGet, 1}},
+ {3027, {wxStyledTextCtrl, markerNext, 2}},
+ {3028, {wxStyledTextCtrl, markerPrevious, 2}},
+ {3029, {wxStyledTextCtrl, markerDefineBitmap, 2}},
+ {3030, {wxStyledTextCtrl, markerAddSet, 2}},
+ {3031, {wxStyledTextCtrl, markerSetAlpha, 2}},
+ {3032, {wxStyledTextCtrl, setMarginType, 2}},
+ {3033, {wxStyledTextCtrl, getMarginType, 1}},
+ {3034, {wxStyledTextCtrl, setMarginWidth, 2}},
+ {3035, {wxStyledTextCtrl, getMarginWidth, 1}},
+ {3036, {wxStyledTextCtrl, setMarginMask, 2}},
+ {3037, {wxStyledTextCtrl, getMarginMask, 1}},
+ {3038, {wxStyledTextCtrl, setMarginSensitive, 2}},
+ {3039, {wxStyledTextCtrl, getMarginSensitive, 1}},
+ {3040, {wxStyledTextCtrl, styleClearAll, 0}},
+ {3041, {wxStyledTextCtrl, styleSetForeground, 2}},
+ {3042, {wxStyledTextCtrl, styleSetBackground, 2}},
+ {3043, {wxStyledTextCtrl, styleSetBold, 2}},
+ {3044, {wxStyledTextCtrl, styleSetItalic, 2}},
+ {3045, {wxStyledTextCtrl, styleSetSize, 2}},
+ {3046, {wxStyledTextCtrl, styleSetFaceName, 2}},
+ {3047, {wxStyledTextCtrl, styleSetEOLFilled, 2}},
+ {3048, {wxStyledTextCtrl, styleResetDefault, 0}},
+ {3049, {wxStyledTextCtrl, styleSetUnderline, 2}},
+ {3050, {wxStyledTextCtrl, styleSetCase, 2}},
+ {3051, {wxStyledTextCtrl, styleSetHotSpot, 2}},
+ {3052, {wxStyledTextCtrl, setSelForeground, 2}},
+ {3053, {wxStyledTextCtrl, setSelBackground, 2}},
+ {3054, {wxStyledTextCtrl, getSelAlpha, 0}},
+ {3055, {wxStyledTextCtrl, setSelAlpha, 1}},
+ {3056, {wxStyledTextCtrl, setCaretForeground, 1}},
+ {3057, {wxStyledTextCtrl, cmdKeyAssign, 3}},
+ {3058, {wxStyledTextCtrl, cmdKeyClear, 2}},
+ {3059, {wxStyledTextCtrl, cmdKeyClearAll, 0}},
+ {3060, {wxStyledTextCtrl, setStyleBytes, 2}},
+ {3061, {wxStyledTextCtrl, styleSetVisible, 2}},
+ {3062, {wxStyledTextCtrl, getCaretPeriod, 0}},
+ {3063, {wxStyledTextCtrl, setCaretPeriod, 1}},
+ {3064, {wxStyledTextCtrl, setWordChars, 1}},
+ {3065, {wxStyledTextCtrl, beginUndoAction, 0}},
+ {3066, {wxStyledTextCtrl, endUndoAction, 0}},
+ {3067, {wxStyledTextCtrl, indicatorSetStyle, 2}},
+ {3068, {wxStyledTextCtrl, indicatorGetStyle, 1}},
+ {3069, {wxStyledTextCtrl, indicatorSetForeground, 2}},
+ {3070, {wxStyledTextCtrl, indicatorGetForeground, 1}},
+ {3071, {wxStyledTextCtrl, setWhitespaceForeground, 2}},
+ {3072, {wxStyledTextCtrl, setWhitespaceBackground, 2}},
+ {3073, {wxStyledTextCtrl, getStyleBits, 0}},
+ {3074, {wxStyledTextCtrl, setLineState, 2}},
+ {3075, {wxStyledTextCtrl, getLineState, 1}},
+ {3076, {wxStyledTextCtrl, getMaxLineState, 0}},
+ {3077, {wxStyledTextCtrl, getCaretLineVisible, 0}},
+ {3078, {wxStyledTextCtrl, setCaretLineVisible, 1}},
+ {3079, {wxStyledTextCtrl, getCaretLineBackground, 0}},
+ {3080, {wxStyledTextCtrl, setCaretLineBackground, 1}},
+ {3081, {wxStyledTextCtrl, autoCompShow, 2}},
+ {3082, {wxStyledTextCtrl, autoCompCancel, 0}},
+ {3083, {wxStyledTextCtrl, autoCompActive, 0}},
+ {3084, {wxStyledTextCtrl, autoCompPosStart, 0}},
+ {3085, {wxStyledTextCtrl, autoCompComplete, 0}},
+ {3086, {wxStyledTextCtrl, autoCompStops, 1}},
+ {3087, {wxStyledTextCtrl, autoCompSetSeparator, 1}},
+ {3088, {wxStyledTextCtrl, autoCompGetSeparator, 0}},
+ {3089, {wxStyledTextCtrl, autoCompSelect, 1}},
+ {3090, {wxStyledTextCtrl, autoCompSetCancelAtStart, 1}},
+ {3091, {wxStyledTextCtrl, autoCompGetCancelAtStart, 0}},
+ {3092, {wxStyledTextCtrl, autoCompSetFillUps, 1}},
+ {3093, {wxStyledTextCtrl, autoCompSetChooseSingle, 1}},
+ {3094, {wxStyledTextCtrl, autoCompGetChooseSingle, 0}},
+ {3095, {wxStyledTextCtrl, autoCompSetIgnoreCase, 1}},
+ {3096, {wxStyledTextCtrl, autoCompGetIgnoreCase, 0}},
+ {3097, {wxStyledTextCtrl, userListShow, 2}},
+ {3098, {wxStyledTextCtrl, autoCompSetAutoHide, 1}},
+ {3099, {wxStyledTextCtrl, autoCompGetAutoHide, 0}},
+ {3100, {wxStyledTextCtrl, autoCompSetDropRestOfWord, 1}},
+ {3101, {wxStyledTextCtrl, autoCompGetDropRestOfWord, 0}},
+ {3102, {wxStyledTextCtrl, registerImage, 2}},
+ {3103, {wxStyledTextCtrl, clearRegisteredImages, 0}},
+ {3104, {wxStyledTextCtrl, autoCompGetTypeSeparator, 0}},
+ {3105, {wxStyledTextCtrl, autoCompSetTypeSeparator, 1}},
+ {3106, {wxStyledTextCtrl, autoCompSetMaxWidth, 1}},
+ {3107, {wxStyledTextCtrl, autoCompGetMaxWidth, 0}},
+ {3108, {wxStyledTextCtrl, autoCompSetMaxHeight, 1}},
+ {3109, {wxStyledTextCtrl, autoCompGetMaxHeight, 0}},
+ {3110, {wxStyledTextCtrl, setIndent, 1}},
+ {3111, {wxStyledTextCtrl, getIndent, 0}},
+ {3112, {wxStyledTextCtrl, setUseTabs, 1}},
+ {3113, {wxStyledTextCtrl, getUseTabs, 0}},
+ {3114, {wxStyledTextCtrl, setLineIndentation, 2}},
+ {3115, {wxStyledTextCtrl, getLineIndentation, 1}},
+ {3116, {wxStyledTextCtrl, getLineIndentPosition, 1}},
+ {3117, {wxStyledTextCtrl, getColumn, 1}},
+ {3118, {wxStyledTextCtrl, setUseHorizontalScrollBar, 1}},
+ {3119, {wxStyledTextCtrl, getUseHorizontalScrollBar, 0}},
+ {3120, {wxStyledTextCtrl, setIndentationGuides, 1}},
+ {3121, {wxStyledTextCtrl, getIndentationGuides, 0}},
+ {3122, {wxStyledTextCtrl, setHighlightGuide, 1}},
+ {3123, {wxStyledTextCtrl, getHighlightGuide, 0}},
+ {3124, {wxStyledTextCtrl, getLineEndPosition, 1}},
+ {3125, {wxStyledTextCtrl, getCodePage, 0}},
+ {3126, {wxStyledTextCtrl, getCaretForeground, 0}},
+ {3127, {wxStyledTextCtrl, getReadOnly, 0}},
+ {3128, {wxStyledTextCtrl, setCurrentPos, 1}},
+ {3129, {wxStyledTextCtrl, setSelectionStart, 1}},
+ {3130, {wxStyledTextCtrl, getSelectionStart, 0}},
+ {3131, {wxStyledTextCtrl, setSelectionEnd, 1}},
+ {3132, {wxStyledTextCtrl, getSelectionEnd, 0}},
+ {3133, {wxStyledTextCtrl, setPrintMagnification, 1}},
+ {3134, {wxStyledTextCtrl, getPrintMagnification, 0}},
+ {3135, {wxStyledTextCtrl, setPrintColourMode, 1}},
+ {3136, {wxStyledTextCtrl, getPrintColourMode, 0}},
+ {3137, {wxStyledTextCtrl, findText, 4}},
+ {3138, {wxStyledTextCtrl, formatRange, 7}},
+ {3139, {wxStyledTextCtrl, getFirstVisibleLine, 0}},
+ {3140, {wxStyledTextCtrl, getLine, 1}},
+ {3141, {wxStyledTextCtrl, getLineCount, 0}},
+ {3142, {wxStyledTextCtrl, setMarginLeft, 1}},
+ {3143, {wxStyledTextCtrl, getMarginLeft, 0}},
+ {3144, {wxStyledTextCtrl, setMarginRight, 1}},
+ {3145, {wxStyledTextCtrl, getMarginRight, 0}},
+ {3146, {wxStyledTextCtrl, getModify, 0}},
+ {3147, {wxStyledTextCtrl, setSelection, 2}},
+ {3148, {wxStyledTextCtrl, getSelectedText, 0}},
+ {3149, {wxStyledTextCtrl, getTextRange, 2}},
+ {3150, {wxStyledTextCtrl, hideSelection, 1}},
+ {3151, {wxStyledTextCtrl, lineFromPosition, 1}},
+ {3152, {wxStyledTextCtrl, positionFromLine, 1}},
+ {3153, {wxStyledTextCtrl, lineScroll, 2}},
+ {3154, {wxStyledTextCtrl, ensureCaretVisible, 0}},
+ {3155, {wxStyledTextCtrl, replaceSelection, 1}},
+ {3156, {wxStyledTextCtrl, setReadOnly, 1}},
+ {3157, {wxStyledTextCtrl, canPaste, 0}},
+ {3158, {wxStyledTextCtrl, canUndo, 0}},
+ {3159, {wxStyledTextCtrl, emptyUndoBuffer, 0}},
+ {3160, {wxStyledTextCtrl, undo, 0}},
+ {3161, {wxStyledTextCtrl, cut, 0}},
+ {3162, {wxStyledTextCtrl, copy, 0}},
+ {3163, {wxStyledTextCtrl, paste, 0}},
+ {3164, {wxStyledTextCtrl, clear, 0}},
+ {3165, {wxStyledTextCtrl, setText, 1}},
+ {3166, {wxStyledTextCtrl, getText, 0}},
+ {3167, {wxStyledTextCtrl, getTextLength, 0}},
+ {3168, {wxStyledTextCtrl, getOvertype, 0}},
+ {3169, {wxStyledTextCtrl, setCaretWidth, 1}},
+ {3170, {wxStyledTextCtrl, getCaretWidth, 0}},
+ {3171, {wxStyledTextCtrl, setTargetStart, 1}},
+ {3172, {wxStyledTextCtrl, getTargetStart, 0}},
+ {3173, {wxStyledTextCtrl, setTargetEnd, 1}},
+ {3174, {wxStyledTextCtrl, getTargetEnd, 0}},
+ {3175, {wxStyledTextCtrl, replaceTarget, 1}},
+ {3176, {wxStyledTextCtrl, searchInTarget, 1}},
+ {3177, {wxStyledTextCtrl, setSearchFlags, 1}},
+ {3178, {wxStyledTextCtrl, getSearchFlags, 0}},
+ {3179, {wxStyledTextCtrl, callTipShow, 2}},
+ {3180, {wxStyledTextCtrl, callTipCancel, 0}},
+ {3181, {wxStyledTextCtrl, callTipActive, 0}},
+ {3182, {wxStyledTextCtrl, callTipPosAtStart, 0}},
+ {3183, {wxStyledTextCtrl, callTipSetHighlight, 2}},
+ {3184, {wxStyledTextCtrl, callTipSetBackground, 1}},
+ {3185, {wxStyledTextCtrl, callTipSetForeground, 1}},
+ {3186, {wxStyledTextCtrl, callTipSetForegroundHighlight, 1}},
+ {3187, {wxStyledTextCtrl, callTipUseStyle, 1}},
+ {3188, {wxStyledTextCtrl, visibleFromDocLine, 1}},
+ {3189, {wxStyledTextCtrl, docLineFromVisible, 1}},
+ {3190, {wxStyledTextCtrl, wrapCount, 1}},
+ {3191, {wxStyledTextCtrl, setFoldLevel, 2}},
+ {3192, {wxStyledTextCtrl, getFoldLevel, 1}},
+ {3193, {wxStyledTextCtrl, getLastChild, 2}},
+ {3194, {wxStyledTextCtrl, getFoldParent, 1}},
+ {3195, {wxStyledTextCtrl, showLines, 2}},
+ {3196, {wxStyledTextCtrl, hideLines, 2}},
+ {3197, {wxStyledTextCtrl, getLineVisible, 1}},
+ {3198, {wxStyledTextCtrl, setFoldExpanded, 2}},
+ {3199, {wxStyledTextCtrl, getFoldExpanded, 1}},
+ {3200, {wxStyledTextCtrl, toggleFold, 1}},
+ {3201, {wxStyledTextCtrl, ensureVisible, 1}},
+ {3202, {wxStyledTextCtrl, setFoldFlags, 1}},
+ {3203, {wxStyledTextCtrl, ensureVisibleEnforcePolicy, 1}},
+ {3204, {wxStyledTextCtrl, setTabIndents, 1}},
+ {3205, {wxStyledTextCtrl, getTabIndents, 0}},
+ {3206, {wxStyledTextCtrl, setBackSpaceUnIndents, 1}},
+ {3207, {wxStyledTextCtrl, getBackSpaceUnIndents, 0}},
+ {3208, {wxStyledTextCtrl, setMouseDwellTime, 1}},
+ {3209, {wxStyledTextCtrl, getMouseDwellTime, 0}},
+ {3210, {wxStyledTextCtrl, wordStartPosition, 2}},
+ {3211, {wxStyledTextCtrl, wordEndPosition, 2}},
+ {3212, {wxStyledTextCtrl, setWrapMode, 1}},
+ {3213, {wxStyledTextCtrl, getWrapMode, 0}},
+ {3214, {wxStyledTextCtrl, setWrapVisualFlags, 1}},
+ {3215, {wxStyledTextCtrl, getWrapVisualFlags, 0}},
+ {3216, {wxStyledTextCtrl, setWrapVisualFlagsLocation, 1}},
+ {3217, {wxStyledTextCtrl, getWrapVisualFlagsLocation, 0}},
+ {3218, {wxStyledTextCtrl, setWrapStartIndent, 1}},
+ {3219, {wxStyledTextCtrl, getWrapStartIndent, 0}},
+ {3220, {wxStyledTextCtrl, setLayoutCache, 1}},
+ {3221, {wxStyledTextCtrl, getLayoutCache, 0}},
+ {3222, {wxStyledTextCtrl, setScrollWidth, 1}},
+ {3223, {wxStyledTextCtrl, getScrollWidth, 0}},
+ {3224, {wxStyledTextCtrl, textWidth, 2}},
+ {3225, {wxStyledTextCtrl, getEndAtLastLine, 0}},
+ {3226, {wxStyledTextCtrl, textHeight, 1}},
+ {3227, {wxStyledTextCtrl, setUseVerticalScrollBar, 1}},
+ {3228, {wxStyledTextCtrl, getUseVerticalScrollBar, 0}},
+ {3229, {wxStyledTextCtrl, appendText, 1}},
+ {3230, {wxStyledTextCtrl, getTwoPhaseDraw, 0}},
+ {3231, {wxStyledTextCtrl, setTwoPhaseDraw, 1}},
+ {3232, {wxStyledTextCtrl, targetFromSelection, 0}},
+ {3233, {wxStyledTextCtrl, linesJoin, 0}},
+ {3234, {wxStyledTextCtrl, linesSplit, 1}},
+ {3235, {wxStyledTextCtrl, setFoldMarginColour, 2}},
+ {3236, {wxStyledTextCtrl, setFoldMarginHiColour, 2}},
+ {3237, {wxStyledTextCtrl, lineDown, 0}},
+ {3238, {wxStyledTextCtrl, lineDownExtend, 0}},
+ {3239, {wxStyledTextCtrl, lineUp, 0}},
+ {3240, {wxStyledTextCtrl, lineUpExtend, 0}},
+ {3241, {wxStyledTextCtrl, charLeft, 0}},
+ {3242, {wxStyledTextCtrl, charLeftExtend, 0}},
+ {3243, {wxStyledTextCtrl, charRight, 0}},
+ {3244, {wxStyledTextCtrl, charRightExtend, 0}},
+ {3245, {wxStyledTextCtrl, wordLeft, 0}},
+ {3246, {wxStyledTextCtrl, wordLeftExtend, 0}},
+ {3247, {wxStyledTextCtrl, wordRight, 0}},
+ {3248, {wxStyledTextCtrl, wordRightExtend, 0}},
+ {3249, {wxStyledTextCtrl, home, 0}},
+ {3250, {wxStyledTextCtrl, homeExtend, 0}},
+ {3251, {wxStyledTextCtrl, lineEnd, 0}},
+ {3252, {wxStyledTextCtrl, lineEndExtend, 0}},
+ {3253, {wxStyledTextCtrl, documentStart, 0}},
+ {3254, {wxStyledTextCtrl, documentStartExtend, 0}},
+ {3255, {wxStyledTextCtrl, documentEnd, 0}},
+ {3256, {wxStyledTextCtrl, documentEndExtend, 0}},
+ {3257, {wxStyledTextCtrl, pageUp, 0}},
+ {3258, {wxStyledTextCtrl, pageUpExtend, 0}},
+ {3259, {wxStyledTextCtrl, pageDown, 0}},
+ {3260, {wxStyledTextCtrl, pageDownExtend, 0}},
+ {3261, {wxStyledTextCtrl, editToggleOvertype, 0}},
+ {3262, {wxStyledTextCtrl, cancel, 0}},
+ {3263, {wxStyledTextCtrl, deleteBack, 0}},
+ {3264, {wxStyledTextCtrl, tab, 0}},
+ {3265, {wxStyledTextCtrl, backTab, 0}},
+ {3266, {wxStyledTextCtrl, newLine, 0}},
+ {3267, {wxStyledTextCtrl, formFeed, 0}},
+ {3268, {wxStyledTextCtrl, vCHome, 0}},
+ {3269, {wxStyledTextCtrl, vCHomeExtend, 0}},
+ {3270, {wxStyledTextCtrl, zoomIn, 0}},
+ {3271, {wxStyledTextCtrl, zoomOut, 0}},
+ {3272, {wxStyledTextCtrl, delWordLeft, 0}},
+ {3273, {wxStyledTextCtrl, delWordRight, 0}},
+ {3274, {wxStyledTextCtrl, lineCut, 0}},
+ {3275, {wxStyledTextCtrl, lineDelete, 0}},
+ {3276, {wxStyledTextCtrl, lineTranspose, 0}},
+ {3277, {wxStyledTextCtrl, lineDuplicate, 0}},
+ {3278, {wxStyledTextCtrl, lowerCase, 0}},
+ {3279, {wxStyledTextCtrl, upperCase, 0}},
+ {3280, {wxStyledTextCtrl, lineScrollDown, 0}},
+ {3281, {wxStyledTextCtrl, lineScrollUp, 0}},
+ {3282, {wxStyledTextCtrl, deleteBackNotLine, 0}},
+ {3283, {wxStyledTextCtrl, homeDisplay, 0}},
+ {3284, {wxStyledTextCtrl, homeDisplayExtend, 0}},
+ {3285, {wxStyledTextCtrl, lineEndDisplay, 0}},
+ {3286, {wxStyledTextCtrl, lineEndDisplayExtend, 0}},
+ {3287, {wxStyledTextCtrl, homeWrapExtend, 0}},
+ {3288, {wxStyledTextCtrl, lineEndWrap, 0}},
+ {3289, {wxStyledTextCtrl, lineEndWrapExtend, 0}},
+ {3290, {wxStyledTextCtrl, vCHomeWrap, 0}},
+ {3291, {wxStyledTextCtrl, vCHomeWrapExtend, 0}},
+ {3292, {wxStyledTextCtrl, lineCopy, 0}},
+ {3293, {wxStyledTextCtrl, moveCaretInsideView, 0}},
+ {3294, {wxStyledTextCtrl, lineLength, 1}},
+ {3295, {wxStyledTextCtrl, braceHighlight, 2}},
+ {3296, {wxStyledTextCtrl, braceBadLight, 1}},
+ {3297, {wxStyledTextCtrl, braceMatch, 1}},
+ {3298, {wxStyledTextCtrl, getViewEOL, 0}},
+ {3299, {wxStyledTextCtrl, setViewEOL, 1}},
+ {3300, {wxStyledTextCtrl, setModEventMask, 1}},
+ {3301, {wxStyledTextCtrl, getEdgeColumn, 0}},
+ {3302, {wxStyledTextCtrl, setEdgeColumn, 1}},
+ {3303, {wxStyledTextCtrl, setEdgeMode, 1}},
+ {3304, {wxStyledTextCtrl, getEdgeMode, 0}},
+ {3305, {wxStyledTextCtrl, getEdgeColour, 0}},
+ {3306, {wxStyledTextCtrl, setEdgeColour, 1}},
+ {3307, {wxStyledTextCtrl, searchAnchor, 0}},
+ {3308, {wxStyledTextCtrl, searchNext, 2}},
+ {3309, {wxStyledTextCtrl, searchPrev, 2}},
+ {3310, {wxStyledTextCtrl, linesOnScreen, 0}},
+ {3311, {wxStyledTextCtrl, usePopUp, 1}},
+ {3312, {wxStyledTextCtrl, selectionIsRectangle, 0}},
+ {3313, {wxStyledTextCtrl, setZoom, 1}},
+ {3314, {wxStyledTextCtrl, getZoom, 0}},
+ {3315, {wxStyledTextCtrl, getModEventMask, 0}},
+ {3316, {wxStyledTextCtrl, setSTCFocus, 1}},
+ {3317, {wxStyledTextCtrl, getSTCFocus, 0}},
+ {3318, {wxStyledTextCtrl, setStatus, 1}},
+ {3319, {wxStyledTextCtrl, getStatus, 0}},
+ {3320, {wxStyledTextCtrl, setMouseDownCaptures, 1}},
+ {3321, {wxStyledTextCtrl, getMouseDownCaptures, 0}},
+ {3322, {wxStyledTextCtrl, setSTCCursor, 1}},
+ {3323, {wxStyledTextCtrl, getSTCCursor, 0}},
+ {3324, {wxStyledTextCtrl, setControlCharSymbol, 1}},
+ {3325, {wxStyledTextCtrl, getControlCharSymbol, 0}},
+ {3326, {wxStyledTextCtrl, wordPartLeft, 0}},
+ {3327, {wxStyledTextCtrl, wordPartLeftExtend, 0}},
+ {3328, {wxStyledTextCtrl, wordPartRight, 0}},
+ {3329, {wxStyledTextCtrl, wordPartRightExtend, 0}},
+ {3330, {wxStyledTextCtrl, setVisiblePolicy, 2}},
+ {3331, {wxStyledTextCtrl, delLineLeft, 0}},
+ {3332, {wxStyledTextCtrl, delLineRight, 0}},
+ {3333, {wxStyledTextCtrl, getXOffset, 0}},
+ {3334, {wxStyledTextCtrl, chooseCaretX, 0}},
+ {3335, {wxStyledTextCtrl, setXCaretPolicy, 2}},
+ {3336, {wxStyledTextCtrl, setYCaretPolicy, 2}},
+ {3337, {wxStyledTextCtrl, getPrintWrapMode, 0}},
+ {3338, {wxStyledTextCtrl, setHotspotActiveForeground, 2}},
+ {3339, {wxStyledTextCtrl, setHotspotActiveBackground, 2}},
+ {3340, {wxStyledTextCtrl, setHotspotActiveUnderline, 1}},
+ {3341, {wxStyledTextCtrl, setHotspotSingleLine, 1}},
+ {3342, {wxStyledTextCtrl, paraDownExtend, 0}},
+ {3343, {wxStyledTextCtrl, paraUp, 0}},
+ {3344, {wxStyledTextCtrl, paraUpExtend, 0}},
+ {3345, {wxStyledTextCtrl, positionBefore, 1}},
+ {3346, {wxStyledTextCtrl, positionAfter, 1}},
+ {3347, {wxStyledTextCtrl, copyRange, 2}},
+ {3348, {wxStyledTextCtrl, copyText, 2}},
+ {3349, {wxStyledTextCtrl, setSelectionMode, 1}},
+ {3350, {wxStyledTextCtrl, getSelectionMode, 0}},
+ {3351, {wxStyledTextCtrl, lineDownRectExtend, 0}},
+ {3352, {wxStyledTextCtrl, lineUpRectExtend, 0}},
+ {3353, {wxStyledTextCtrl, charLeftRectExtend, 0}},
+ {3354, {wxStyledTextCtrl, charRightRectExtend, 0}},
+ {3355, {wxStyledTextCtrl, homeRectExtend, 0}},
+ {3356, {wxStyledTextCtrl, vCHomeRectExtend, 0}},
+ {3357, {wxStyledTextCtrl, lineEndRectExtend, 0}},
+ {3358, {wxStyledTextCtrl, pageUpRectExtend, 0}},
+ {3359, {wxStyledTextCtrl, pageDownRectExtend, 0}},
+ {3360, {wxStyledTextCtrl, stutteredPageUp, 0}},
+ {3361, {wxStyledTextCtrl, stutteredPageUpExtend, 0}},
+ {3362, {wxStyledTextCtrl, stutteredPageDown, 0}},
+ {3363, {wxStyledTextCtrl, stutteredPageDownExtend, 0}},
+ {3364, {wxStyledTextCtrl, wordLeftEnd, 0}},
+ {3365, {wxStyledTextCtrl, wordLeftEndExtend, 0}},
+ {3366, {wxStyledTextCtrl, wordRightEnd, 0}},
+ {3367, {wxStyledTextCtrl, wordRightEndExtend, 0}},
+ {3368, {wxStyledTextCtrl, setWhitespaceChars, 1}},
+ {3369, {wxStyledTextCtrl, setCharsDefault, 0}},
+ {3370, {wxStyledTextCtrl, autoCompGetCurrent, 0}},
+ {3371, {wxStyledTextCtrl, allocate, 1}},
+ {3372, {wxStyledTextCtrl, findColumn, 2}},
+ {3373, {wxStyledTextCtrl, getCaretSticky, 0}},
+ {3374, {wxStyledTextCtrl, setCaretSticky, 1}},
+ {3375, {wxStyledTextCtrl, toggleCaretSticky, 0}},
+ {3376, {wxStyledTextCtrl, setPasteConvertEndings, 1}},
+ {3377, {wxStyledTextCtrl, getPasteConvertEndings, 0}},
+ {3378, {wxStyledTextCtrl, selectionDuplicate, 0}},
+ {3379, {wxStyledTextCtrl, setCaretLineBackAlpha, 1}},
+ {3380, {wxStyledTextCtrl, getCaretLineBackAlpha, 0}},
+ {3381, {wxStyledTextCtrl, startRecord, 0}},
+ {3382, {wxStyledTextCtrl, stopRecord, 0}},
+ {3383, {wxStyledTextCtrl, setLexer, 1}},
+ {3384, {wxStyledTextCtrl, getLexer, 0}},
+ {3385, {wxStyledTextCtrl, colourise, 2}},
+ {3386, {wxStyledTextCtrl, setProperty, 2}},
+ {3387, {wxStyledTextCtrl, setKeyWords, 2}},
+ {3388, {wxStyledTextCtrl, setLexerLanguage, 1}},
+ {3389, {wxStyledTextCtrl, getProperty, 1}},
+ {3390, {wxStyledTextCtrl, getStyleBitsNeeded, 0}},
+ {3391, {wxStyledTextCtrl, getCurrentLine, 0}},
+ {3392, {wxStyledTextCtrl, styleSetSpec, 2}},
+ {3393, {wxStyledTextCtrl, styleSetFont, 2}},
+ {3394, {wxStyledTextCtrl, styleSetFontAttr, 7}},
+ {3395, {wxStyledTextCtrl, styleSetCharacterSet, 2}},
+ {3396, {wxStyledTextCtrl, styleSetFontEncoding, 2}},
+ {3397, {wxStyledTextCtrl, cmdKeyExecute, 1}},
+ {3398, {wxStyledTextCtrl, setMargins, 2}},
+ {3399, {wxStyledTextCtrl, getSelection, 2}},
+ {3400, {wxStyledTextCtrl, pointFromPosition, 1}},
+ {3401, {wxStyledTextCtrl, scrollToLine, 1}},
+ {3402, {wxStyledTextCtrl, scrollToColumn, 1}},
+ {3403, {wxStyledTextCtrl, setVScrollBar, 1}},
+ {3404, {wxStyledTextCtrl, setHScrollBar, 1}},
+ {3405, {wxStyledTextCtrl, getLastKeydownProcessed, 0}},
+ {3406, {wxStyledTextCtrl, setLastKeydownProcessed, 1}},
+ {3407, {wxStyledTextCtrl, saveFile, 1}},
+ {3408, {wxStyledTextCtrl, loadFile, 1}},
+ {3409, {wxStyledTextCtrl, doDragOver, 3}},
+ {3410, {wxStyledTextCtrl, doDropText, 3}},
+ {3411, {wxStyledTextCtrl, getUseAntiAliasing, 0}},
+ {3412, {wxStyledTextCtrl, addTextRaw, 1}},
+ {3413, {wxStyledTextCtrl, insertTextRaw, 2}},
+ {3414, {wxStyledTextCtrl, getCurLineRaw, 1}},
+ {3415, {wxStyledTextCtrl, getLineRaw, 1}},
+ {3416, {wxStyledTextCtrl, getSelectedTextRaw, 0}},
+ {3417, {wxStyledTextCtrl, getTextRangeRaw, 2}},
+ {3418, {wxStyledTextCtrl, setTextRaw, 1}},
+ {3419, {wxStyledTextCtrl, getTextRaw, 0}},
+ {3420, {wxStyledTextCtrl, appendTextRaw, 1}},
+ {3421, {wxArtProvider, getBitmap, 2}},
+ {3422, {wxArtProvider, getIcon, 2}},
+ {3423, {wxTreeEvent, getKeyCode, 0}},
+ {3424, {wxTreeEvent, getItem, 0}},
+ {3425, {wxTreeEvent, getKeyEvent, 0}},
+ {3426, {wxTreeEvent, getLabel, 0}},
+ {3427, {wxTreeEvent, getOldItem, 0}},
+ {3428, {wxTreeEvent, getPoint, 0}},
+ {3429, {wxTreeEvent, isEditCancelled, 0}},
+ {3430, {wxTreeEvent, setToolTip, 1}},
+ {3431, {wxNotebookEvent, getOldSelection, 0}},
+ {3432, {wxNotebookEvent, getSelection, 0}},
+ {3433, {wxNotebookEvent, setOldSelection, 1}},
+ {3434, {wxNotebookEvent, setSelection, 1}},
+ {3435, {wxFileDataObject, new, 0}},
+ {3436, {wxFileDataObject, addFile, 1}},
+ {3437, {wxFileDataObject, getFilenames, 0}},
+ {3438, {wxFileDataObject, 'Destroy', undefined}},
+ {3439, {wxTextDataObject, new, 1}},
+ {3440, {wxTextDataObject, getTextLength, 0}},
+ {3441, {wxTextDataObject, getText, 0}},
+ {3442, {wxTextDataObject, setText, 1}},
+ {3443, {wxTextDataObject, 'Destroy', undefined}},
+ {3444, {wxBitmapDataObject, new_1_1, 1}},
+ {3445, {wxBitmapDataObject, new_1_0, 1}},
+ {3446, {wxBitmapDataObject, getBitmap, 0}},
+ {3447, {wxBitmapDataObject, setBitmap, 1}},
+ {3448, {wxBitmapDataObject, 'Destroy', undefined}},
+ {3450, {wxClipboard, new, 0}},
+ {3451, {wxClipboard, destruct, 0}},
+ {3452, {wxClipboard, addData, 1}},
+ {3453, {wxClipboard, clear, 0}},
+ {3454, {wxClipboard, close, 0}},
+ {3455, {wxClipboard, flush, 0}},
+ {3456, {wxClipboard, getData, 1}},
+ {3457, {wxClipboard, isOpened, 0}},
+ {3458, {wxClipboard, open, 0}},
+ {3459, {wxClipboard, setData, 1}},
+ {3461, {wxClipboard, usePrimarySelection, 1}},
+ {3462, {wxClipboard, isSupported, 1}},
+ {3463, {wxClipboard, get, 0}},
+ {3464, {wxSpinEvent, getPosition, 0}},
+ {3465, {wxSpinEvent, setPosition, 1}},
+ {3466, {wxSplitterWindow, new_0, 0}},
+ {3467, {wxSplitterWindow, new_2, 2}},
+ {3468, {wxSplitterWindow, destruct, 0}},
+ {3469, {wxSplitterWindow, create, 2}},
+ {3470, {wxSplitterWindow, getMinimumPaneSize, 0}},
+ {3471, {wxSplitterWindow, getSashGravity, 0}},
+ {3472, {wxSplitterWindow, getSashPosition, 0}},
+ {3473, {wxSplitterWindow, getSplitMode, 0}},
+ {3474, {wxSplitterWindow, getWindow1, 0}},
+ {3475, {wxSplitterWindow, getWindow2, 0}},
+ {3476, {wxSplitterWindow, initialize, 1}},
+ {3477, {wxSplitterWindow, isSplit, 0}},
+ {3478, {wxSplitterWindow, replaceWindow, 2}},
+ {3479, {wxSplitterWindow, setSashGravity, 1}},
+ {3480, {wxSplitterWindow, setSashPosition, 2}},
+ {3481, {wxSplitterWindow, setSashSize, 1}},
+ {3482, {wxSplitterWindow, setMinimumPaneSize, 1}},
+ {3483, {wxSplitterWindow, setSplitMode, 1}},
+ {3484, {wxSplitterWindow, splitHorizontally, 3}},
+ {3485, {wxSplitterWindow, splitVertically, 3}},
+ {3486, {wxSplitterWindow, unsplit, 1}},
+ {3487, {wxSplitterWindow, updateSize, 0}},
+ {3488, {wxSplitterEvent, getSashPosition, 0}},
+ {3489, {wxSplitterEvent, getX, 0}},
+ {3490, {wxSplitterEvent, getY, 0}},
+ {3491, {wxSplitterEvent, getWindowBeingRemoved, 0}},
+ {3492, {wxSplitterEvent, setSashPosition, 1}},
+ {3493, {wxHtmlWindow, new_0, 0}},
+ {3494, {wxHtmlWindow, new_2, 2}},
+ {3495, {wxHtmlWindow, appendToPage, 1}},
+ {3496, {wxHtmlWindow, getOpenedAnchor, 0}},
+ {3497, {wxHtmlWindow, getOpenedPage, 0}},
+ {3498, {wxHtmlWindow, getOpenedPageTitle, 0}},
+ {3499, {wxHtmlWindow, getRelatedFrame, 0}},
+ {3500, {wxHtmlWindow, historyBack, 0}},
+ {3501, {wxHtmlWindow, historyCanBack, 0}},
+ {3502, {wxHtmlWindow, historyCanForward, 0}},
+ {3503, {wxHtmlWindow, historyClear, 0}},
+ {3504, {wxHtmlWindow, historyForward, 0}},
+ {3505, {wxHtmlWindow, loadFile, 1}},
+ {3506, {wxHtmlWindow, loadPage, 1}},
+ {3507, {wxHtmlWindow, selectAll, 0}},
+ {3508, {wxHtmlWindow, selectionToText, 0}},
+ {3509, {wxHtmlWindow, selectLine, 1}},
+ {3510, {wxHtmlWindow, selectWord, 1}},
+ {3511, {wxHtmlWindow, setBorders, 1}},
+ {3512, {wxHtmlWindow, setFonts, 3}},
+ {3513, {wxHtmlWindow, setPage, 1}},
+ {3514, {wxHtmlWindow, setRelatedFrame, 2}},
+ {3515, {wxHtmlWindow, setRelatedStatusBar, 1}},
+ {3516, {wxHtmlWindow, toText, 0}},
+ {3517, {wxHtmlWindow, 'Destroy', undefined}},
+ {3518, {wxHtmlLinkEvent, getLinkInfo, 0}},
+ {3519, {wxSystemSettings, getColour, 1}},
+ {3520, {wxSystemSettings, getFont, 1}},
+ {3521, {wxSystemSettings, getMetric, 2}},
+ {3522, {wxSystemSettings, getScreenType, 0}},
+ {3523, {wxSystemOptions, getOption, 1}},
+ {3524, {wxSystemOptions, getOptionInt, 1}},
+ {3525, {wxSystemOptions, hasOption, 1}},
+ {3526, {wxSystemOptions, isFalse, 1}},
+ {3527, {wxSystemOptions, setOption_2_1, 2}},
+ {3528, {wxSystemOptions, setOption_2_0, 2}},
+ {3529, {wxAuiNotebookEvent, setSelection, 1}},
+ {3530, {wxAuiNotebookEvent, getSelection, 0}},
+ {3531, {wxAuiNotebookEvent, setOldSelection, 1}},
+ {3532, {wxAuiNotebookEvent, getOldSelection, 0}},
+ {3533, {wxAuiNotebookEvent, setDragSource, 1}},
+ {3534, {wxAuiNotebookEvent, getDragSource, 0}},
+ {3535, {wxAuiManagerEvent, setManager, 1}},
+ {3536, {wxAuiManagerEvent, getManager, 0}},
+ {3537, {wxAuiManagerEvent, setPane, 1}},
+ {3538, {wxAuiManagerEvent, getPane, 0}},
+ {3539, {wxAuiManagerEvent, setButton, 1}},
+ {3540, {wxAuiManagerEvent, getButton, 0}},
+ {3541, {wxAuiManagerEvent, setDC, 1}},
+ {3542, {wxAuiManagerEvent, getDC, 0}},
+ {3543, {wxAuiManagerEvent, veto, 1}},
+ {3544, {wxAuiManagerEvent, getVeto, 0}},
+ {3545, {wxAuiManagerEvent, setCanVeto, 1}},
+ {3546, {wxAuiManagerEvent, canVeto, 0}},
+ {3547, {wxLogNull, new, 0}},
+ {3548, {wxLogNull, 'Destroy', undefined}},
+ {3549, {wxTaskBarIcon, new, 0}},
+ {3550, {wxTaskBarIcon, destruct, 0}},
+ {3551, {wxTaskBarIcon, popupMenu, 1}},
+ {3552, {wxTaskBarIcon, removeIcon, 0}},
+ {3553, {wxTaskBarIcon, setIcon, 2}},
+ {3554, {wxLocale, new_0, 0}},
+ {3556, {wxLocale, new_2, 2}},
+ {3557, {wxLocale, destruct, 0}},
+ {3559, {wxLocale, init, 1}},
+ {3560, {wxLocale, addCatalog_1, 1}},
+ {3561, {wxLocale, addCatalog_3, 3}},
+ {3562, {wxLocale, addCatalogLookupPathPrefix, 1}},
+ {3563, {wxLocale, getCanonicalName, 0}},
+ {3564, {wxLocale, getLanguage, 0}},
+ {3565, {wxLocale, getLanguageName, 1}},
+ {3566, {wxLocale, getLocale, 0}},
+ {3567, {wxLocale, getName, 0}},
+ {3568, {wxLocale, getString_2, 2}},
+ {3569, {wxLocale, getString_4, 4}},
+ {3570, {wxLocale, getHeaderValue, 2}},
+ {3571, {wxLocale, getSysName, 0}},
+ {3572, {wxLocale, getSystemEncoding, 0}},
+ {3573, {wxLocale, getSystemEncodingName, 0}},
+ {3574, {wxLocale, getSystemLanguage, 0}},
+ {3575, {wxLocale, isLoaded, 1}},
+ {3576, {wxLocale, isOk, 0}},
+ {3577, {wxActivateEvent, getActive, 0}},
+ {3579, {wxPopupWindow, new_2, 2}},
+ {3580, {wxPopupWindow, new_0, 0}},
+ {3582, {wxPopupWindow, destruct, 0}},
+ {3583, {wxPopupWindow, create, 2}},
+ {3584, {wxPopupWindow, position, 2}},
+ {3585, {wxPopupTransientWindow, new_0, 0}},
+ {3586, {wxPopupTransientWindow, new_2, 2}},
+ {3587, {wxPopupTransientWindow, destruct, 0}},
+ {3588, {wxPopupTransientWindow, popup, 1}},
+ {3589, {wxPopupTransientWindow, dismiss, 0}},
+ {3590, {wxOverlay, new, 0}},
+ {3591, {wxOverlay, destruct, 0}},
+ {3592, {wxOverlay, reset, 0}},
+ {3593, {wxDCOverlay, new_6, 6}},
+ {3594, {wxDCOverlay, new_2, 2}},
+ {3595, {wxDCOverlay, destruct, 0}},
+ {3596, {wxDCOverlay, clear, 0}},
+ {3597, {wxDropFilesEvent, getPosition, 0}},
+ {3598, {wxDropFilesEvent, getNumberOfFiles, 0}},
+ {3599, {wxDropFilesEvent, getFiles, 0}},
{-1, {mod, func, -1}}
].
diff --git a/lib/wx/src/gen/wxe_funcs.hrl b/lib/wx/src/gen/wxe_funcs.hrl
index 84fa592aaa..af0cee0dcd 100644
--- a/lib/wx/src/gen/wxe_funcs.hrl
+++ b/lib/wx/src/gen/wxe_funcs.hrl
@@ -42,3330 +42,3335 @@
-define(wxWindow_Destroy, 123).
-define(wxWindow_DestroyChildren, 124).
-define(wxWindow_Disable, 125).
--define(wxWindow_Enable, 126).
--define(wxWindow_FindFocus, 127).
--define(wxWindow_FindWindow_1_0, 128).
--define(wxWindow_FindWindow_1_1, 129).
--define(wxWindow_FindWindowById, 130).
--define(wxWindow_FindWindowByName, 131).
--define(wxWindow_FindWindowByLabel, 132).
--define(wxWindow_Fit, 133).
--define(wxWindow_FitInside, 134).
--define(wxWindow_Freeze, 135).
--define(wxWindow_GetAcceleratorTable, 136).
--define(wxWindow_GetBackgroundColour, 137).
--define(wxWindow_GetBackgroundStyle, 138).
--define(wxWindow_GetBestSize, 139).
--define(wxWindow_GetCaret, 141).
--define(wxWindow_GetCapture, 142).
--define(wxWindow_GetCharHeight, 143).
--define(wxWindow_GetCharWidth, 144).
--define(wxWindow_GetChildren, 145).
--define(wxWindow_GetClientSize, 148).
--define(wxWindow_GetContainingSizer, 149).
--define(wxWindow_GetCursor, 150).
--define(wxWindow_GetDropTarget, 151).
--define(wxWindow_GetEventHandler, 152).
--define(wxWindow_GetExtraStyle, 153).
--define(wxWindow_GetFont, 154).
--define(wxWindow_GetForegroundColour, 155).
--define(wxWindow_GetGrandParent, 156).
--define(wxWindow_GetHandle, 157).
--define(wxWindow_GetHelpText, 158).
--define(wxWindow_GetId, 159).
--define(wxWindow_GetLabel, 160).
--define(wxWindow_GetMaxSize, 161).
--define(wxWindow_GetMinSize, 162).
--define(wxWindow_GetName, 163).
--define(wxWindow_GetParent, 164).
--define(wxWindow_GetPosition, 166).
--define(wxWindow_GetRect, 167).
--define(wxWindow_GetScreenPosition, 169).
--define(wxWindow_GetScreenRect, 170).
--define(wxWindow_GetScrollPos, 171).
--define(wxWindow_GetScrollRange, 172).
--define(wxWindow_GetScrollThumb, 173).
--define(wxWindow_GetSize, 175).
--define(wxWindow_GetSizer, 176).
--define(wxWindow_GetTextExtent, 177).
--define(wxWindow_GetToolTip, 178).
--define(wxWindow_GetUpdateRegion, 179).
--define(wxWindow_GetVirtualSize, 181).
--define(wxWindow_GetWindowStyleFlag, 183).
--define(wxWindow_GetWindowVariant, 184).
--define(wxWindow_HasCapture, 185).
--define(wxWindow_HasScrollbar, 186).
--define(wxWindow_HasTransparentBackground, 187).
--define(wxWindow_Hide, 188).
--define(wxWindow_InheritAttributes, 189).
--define(wxWindow_InitDialog, 190).
--define(wxWindow_InvalidateBestSize, 191).
--define(wxWindow_IsEnabled, 192).
--define(wxWindow_IsExposed_2, 193).
--define(wxWindow_IsExposed_4, 194).
--define(wxWindow_IsExposed_1_0, 195).
--define(wxWindow_IsExposed_1_1, 196).
--define(wxWindow_IsRetained, 197).
--define(wxWindow_IsShown, 198).
--define(wxWindow_IsTopLevel, 199).
--define(wxWindow_Layout, 200).
--define(wxWindow_LineDown, 201).
--define(wxWindow_LineUp, 202).
--define(wxWindow_Lower, 203).
--define(wxWindow_MakeModal, 204).
--define(wxWindow_Move_3, 205).
--define(wxWindow_Move_2, 206).
--define(wxWindow_MoveAfterInTabOrder, 207).
--define(wxWindow_MoveBeforeInTabOrder, 208).
--define(wxWindow_Navigate, 209).
--define(wxWindow_PageDown, 210).
--define(wxWindow_PageUp, 211).
--define(wxWindow_PopEventHandler, 212).
--define(wxWindow_PopupMenu_2, 213).
--define(wxWindow_PopupMenu_3, 214).
--define(wxWindow_Raise, 215).
--define(wxWindow_Refresh, 216).
--define(wxWindow_RefreshRect, 217).
--define(wxWindow_ReleaseMouse, 218).
--define(wxWindow_RemoveChild, 219).
--define(wxWindow_Reparent, 220).
--define(wxWindow_ScreenToClient_2, 221).
--define(wxWindow_ScreenToClient_1, 222).
--define(wxWindow_ScrollLines, 224).
--define(wxWindow_ScrollPages, 226).
--define(wxWindow_ScrollWindow, 227).
--define(wxWindow_SetAcceleratorTable, 228).
--define(wxWindow_SetAutoLayout, 229).
--define(wxWindow_SetBackgroundColour, 230).
--define(wxWindow_SetBackgroundStyle, 231).
--define(wxWindow_SetCaret, 232).
--define(wxWindow_SetClientSize_2, 233).
--define(wxWindow_SetClientSize_1_0, 234).
--define(wxWindow_SetClientSize_1_1, 235).
--define(wxWindow_SetContainingSizer, 236).
--define(wxWindow_SetCursor, 237).
--define(wxWindow_SetMaxSize, 238).
--define(wxWindow_SetMinSize, 239).
--define(wxWindow_SetOwnBackgroundColour, 240).
--define(wxWindow_SetOwnFont, 241).
--define(wxWindow_SetOwnForegroundColour, 242).
--define(wxWindow_SetDropTarget, 243).
--define(wxWindow_SetExtraStyle, 244).
--define(wxWindow_SetFocus, 245).
--define(wxWindow_SetFocusFromKbd, 246).
--define(wxWindow_SetFont, 247).
--define(wxWindow_SetForegroundColour, 248).
--define(wxWindow_SetHelpText, 249).
--define(wxWindow_SetId, 250).
--define(wxWindow_SetLabel, 252).
--define(wxWindow_SetName, 253).
--define(wxWindow_SetPalette, 254).
--define(wxWindow_SetScrollbar, 255).
--define(wxWindow_SetScrollPos, 256).
--define(wxWindow_SetSize_5, 257).
--define(wxWindow_SetSize_2_0, 258).
--define(wxWindow_SetSize_1, 259).
--define(wxWindow_SetSize_2_1, 260).
--define(wxWindow_SetSizeHints_3, 261).
--define(wxWindow_SetSizeHints_2, 262).
--define(wxWindow_SetSizer, 263).
--define(wxWindow_SetSizerAndFit, 264).
--define(wxWindow_SetThemeEnabled, 265).
--define(wxWindow_SetToolTip_1_0, 266).
--define(wxWindow_SetToolTip_1_1, 267).
--define(wxWindow_SetVirtualSize_1, 268).
--define(wxWindow_SetVirtualSize_2, 269).
--define(wxWindow_SetVirtualSizeHints_3, 270).
--define(wxWindow_SetVirtualSizeHints_2, 271).
--define(wxWindow_SetWindowStyle, 272).
--define(wxWindow_SetWindowStyleFlag, 273).
--define(wxWindow_SetWindowVariant, 274).
--define(wxWindow_ShouldInheritColours, 275).
--define(wxWindow_Show, 276).
--define(wxWindow_Thaw, 277).
--define(wxWindow_TransferDataFromWindow, 278).
--define(wxWindow_TransferDataToWindow, 279).
--define(wxWindow_Update, 280).
--define(wxWindow_UpdateWindowUI, 281).
--define(wxWindow_Validate, 282).
--define(wxWindow_WarpPointer, 283).
--define(wxWindow_SetTransparent, 284).
--define(wxWindow_CanSetTransparent, 285).
--define(wxWindow_IsDoubleBuffered, 286).
--define(wxWindow_SetDoubleBuffered, 287).
--define(wxTopLevelWindow_GetIcon, 288).
--define(wxTopLevelWindow_GetIcons, 289).
--define(wxTopLevelWindow_GetTitle, 290).
--define(wxTopLevelWindow_IsActive, 291).
--define(wxTopLevelWindow_Iconize, 292).
--define(wxTopLevelWindow_IsFullScreen, 293).
--define(wxTopLevelWindow_IsIconized, 294).
--define(wxTopLevelWindow_IsMaximized, 295).
--define(wxTopLevelWindow_Maximize, 296).
--define(wxTopLevelWindow_RequestUserAttention, 297).
--define(wxTopLevelWindow_SetIcon, 298).
--define(wxTopLevelWindow_SetIcons, 299).
--define(wxTopLevelWindow_CenterOnScreen, 300).
--define(wxTopLevelWindow_CentreOnScreen, 301).
--define(wxTopLevelWindow_SetShape, 303).
--define(wxTopLevelWindow_SetTitle, 304).
--define(wxTopLevelWindow_ShowFullScreen, 305).
--define(wxFrame_new_4, 307).
--define(wxFrame_new_0, 308).
--define(wxFrame_destruct, 310).
--define(wxFrame_Create, 311).
--define(wxFrame_CreateStatusBar, 312).
--define(wxFrame_CreateToolBar, 313).
--define(wxFrame_GetClientAreaOrigin, 314).
--define(wxFrame_GetMenuBar, 315).
--define(wxFrame_GetStatusBar, 316).
--define(wxFrame_GetStatusBarPane, 317).
--define(wxFrame_GetToolBar, 318).
--define(wxFrame_ProcessCommand, 319).
--define(wxFrame_SendSizeEvent, 320).
--define(wxFrame_SetMenuBar, 321).
--define(wxFrame_SetStatusBar, 322).
--define(wxFrame_SetStatusBarPane, 323).
--define(wxFrame_SetStatusText, 324).
--define(wxFrame_SetStatusWidths, 325).
--define(wxFrame_SetToolBar, 326).
--define(wxMiniFrame_new_0, 327).
--define(wxMiniFrame_new_4, 328).
--define(wxMiniFrame_Create, 329).
--define(wxMiniFrame_destroy, 330).
--define(wxSplashScreen_new_0, 331).
--define(wxSplashScreen_new_6, 332).
--define(wxSplashScreen_destruct, 333).
--define(wxSplashScreen_GetSplashStyle, 334).
--define(wxSplashScreen_GetTimeout, 335).
--define(wxPanel_new_0, 336).
--define(wxPanel_new_6, 337).
--define(wxPanel_new_2, 338).
--define(wxPanel_destruct, 339).
--define(wxPanel_InitDialog, 340).
--define(wxPanel_SetFocusIgnoringChildren, 341).
--define(wxScrolledWindow_new_0, 342).
--define(wxScrolledWindow_new_2, 343).
--define(wxScrolledWindow_destruct, 344).
--define(wxScrolledWindow_CalcScrolledPosition_4, 345).
--define(wxScrolledWindow_CalcScrolledPosition_1, 346).
--define(wxScrolledWindow_CalcUnscrolledPosition_4, 347).
--define(wxScrolledWindow_CalcUnscrolledPosition_1, 348).
--define(wxScrolledWindow_EnableScrolling, 349).
--define(wxScrolledWindow_GetScrollPixelsPerUnit, 350).
--define(wxScrolledWindow_GetViewStart, 351).
--define(wxScrolledWindow_DoPrepareDC, 352).
--define(wxScrolledWindow_PrepareDC, 353).
--define(wxScrolledWindow_Scroll, 354).
--define(wxScrolledWindow_SetScrollbars, 355).
--define(wxScrolledWindow_SetScrollRate, 356).
--define(wxScrolledWindow_SetTargetWindow, 357).
--define(wxSashWindow_new_0, 358).
--define(wxSashWindow_new_2, 359).
--define(wxSashWindow_destruct, 360).
--define(wxSashWindow_GetSashVisible, 361).
--define(wxSashWindow_GetMaximumSizeX, 362).
--define(wxSashWindow_GetMaximumSizeY, 363).
--define(wxSashWindow_GetMinimumSizeX, 364).
--define(wxSashWindow_GetMinimumSizeY, 365).
--define(wxSashWindow_SetMaximumSizeX, 366).
--define(wxSashWindow_SetMaximumSizeY, 367).
--define(wxSashWindow_SetMinimumSizeX, 368).
--define(wxSashWindow_SetMinimumSizeY, 369).
--define(wxSashWindow_SetSashVisible, 370).
--define(wxSashLayoutWindow_new_0, 371).
--define(wxSashLayoutWindow_new_2, 372).
--define(wxSashLayoutWindow_Create, 373).
--define(wxSashLayoutWindow_GetAlignment, 374).
--define(wxSashLayoutWindow_GetOrientation, 375).
--define(wxSashLayoutWindow_SetAlignment, 376).
--define(wxSashLayoutWindow_SetDefaultSize, 377).
--define(wxSashLayoutWindow_SetOrientation, 378).
--define(wxSashLayoutWindow_destroy, 379).
--define(wxGrid_new_0, 380).
--define(wxGrid_new_3, 381).
--define(wxGrid_new_4, 382).
--define(wxGrid_destruct, 383).
--define(wxGrid_AppendCols, 384).
--define(wxGrid_AppendRows, 385).
--define(wxGrid_AutoSize, 386).
--define(wxGrid_AutoSizeColumn, 387).
--define(wxGrid_AutoSizeColumns, 388).
--define(wxGrid_AutoSizeRow, 389).
--define(wxGrid_AutoSizeRows, 390).
--define(wxGrid_BeginBatch, 391).
--define(wxGrid_BlockToDeviceRect, 392).
--define(wxGrid_CanDragColSize, 393).
--define(wxGrid_CanDragRowSize, 394).
--define(wxGrid_CanDragGridSize, 395).
--define(wxGrid_CanEnableCellControl, 396).
--define(wxGrid_CellToRect_2, 397).
--define(wxGrid_CellToRect_1, 398).
--define(wxGrid_ClearGrid, 399).
--define(wxGrid_ClearSelection, 400).
--define(wxGrid_CreateGrid, 401).
--define(wxGrid_DeleteCols, 402).
--define(wxGrid_DeleteRows, 403).
--define(wxGrid_DisableCellEditControl, 404).
--define(wxGrid_DisableDragColSize, 405).
--define(wxGrid_DisableDragGridSize, 406).
--define(wxGrid_DisableDragRowSize, 407).
--define(wxGrid_EnableCellEditControl, 408).
--define(wxGrid_EnableDragColSize, 409).
--define(wxGrid_EnableDragGridSize, 410).
--define(wxGrid_EnableDragRowSize, 411).
--define(wxGrid_EnableEditing, 412).
--define(wxGrid_EnableGridLines, 413).
--define(wxGrid_EndBatch, 414).
--define(wxGrid_Fit, 415).
--define(wxGrid_ForceRefresh, 416).
--define(wxGrid_GetBatchCount, 417).
--define(wxGrid_GetCellAlignment, 418).
--define(wxGrid_GetCellBackgroundColour, 419).
--define(wxGrid_GetCellEditor, 420).
--define(wxGrid_GetCellFont, 421).
--define(wxGrid_GetCellRenderer, 422).
--define(wxGrid_GetCellTextColour, 423).
--define(wxGrid_GetCellValue_2, 424).
--define(wxGrid_GetCellValue_1, 425).
--define(wxGrid_GetColLabelAlignment, 426).
--define(wxGrid_GetColLabelSize, 427).
--define(wxGrid_GetColLabelValue, 428).
--define(wxGrid_GetColMinimalAcceptableWidth, 429).
--define(wxGrid_GetDefaultCellAlignment, 430).
--define(wxGrid_GetDefaultCellBackgroundColour, 431).
--define(wxGrid_GetDefaultCellFont, 432).
--define(wxGrid_GetDefaultCellTextColour, 433).
--define(wxGrid_GetDefaultColLabelSize, 434).
--define(wxGrid_GetDefaultColSize, 435).
--define(wxGrid_GetDefaultEditor, 436).
--define(wxGrid_GetDefaultEditorForCell_2, 437).
--define(wxGrid_GetDefaultEditorForCell_1, 438).
--define(wxGrid_GetDefaultEditorForType, 439).
--define(wxGrid_GetDefaultRenderer, 440).
--define(wxGrid_GetDefaultRendererForCell, 441).
--define(wxGrid_GetDefaultRendererForType, 442).
--define(wxGrid_GetDefaultRowLabelSize, 443).
--define(wxGrid_GetDefaultRowSize, 444).
--define(wxGrid_GetGridCursorCol, 445).
--define(wxGrid_GetGridCursorRow, 446).
--define(wxGrid_GetGridLineColour, 447).
--define(wxGrid_GridLinesEnabled, 448).
--define(wxGrid_GetLabelBackgroundColour, 449).
--define(wxGrid_GetLabelFont, 450).
--define(wxGrid_GetLabelTextColour, 451).
--define(wxGrid_GetNumberCols, 452).
--define(wxGrid_GetNumberRows, 453).
--define(wxGrid_GetOrCreateCellAttr, 454).
--define(wxGrid_GetRowMinimalAcceptableHeight, 455).
--define(wxGrid_GetRowLabelAlignment, 456).
--define(wxGrid_GetRowLabelSize, 457).
--define(wxGrid_GetRowLabelValue, 458).
--define(wxGrid_GetRowSize, 459).
--define(wxGrid_GetScrollLineX, 460).
--define(wxGrid_GetScrollLineY, 461).
--define(wxGrid_GetSelectedCells, 462).
--define(wxGrid_GetSelectedCols, 463).
--define(wxGrid_GetSelectedRows, 464).
--define(wxGrid_GetSelectionBackground, 465).
--define(wxGrid_GetSelectionBlockTopLeft, 466).
--define(wxGrid_GetSelectionBlockBottomRight, 467).
--define(wxGrid_GetSelectionForeground, 468).
--define(wxGrid_GetViewWidth, 469).
--define(wxGrid_GetGridWindow, 470).
--define(wxGrid_GetGridRowLabelWindow, 471).
--define(wxGrid_GetGridColLabelWindow, 472).
--define(wxGrid_GetGridCornerLabelWindow, 473).
--define(wxGrid_HideCellEditControl, 474).
--define(wxGrid_InsertCols, 475).
--define(wxGrid_InsertRows, 476).
--define(wxGrid_IsCellEditControlEnabled, 477).
--define(wxGrid_IsCurrentCellReadOnly, 478).
--define(wxGrid_IsEditable, 479).
--define(wxGrid_IsInSelection_2, 480).
--define(wxGrid_IsInSelection_1, 481).
--define(wxGrid_IsReadOnly, 482).
--define(wxGrid_IsSelection, 483).
--define(wxGrid_IsVisible_3, 484).
--define(wxGrid_IsVisible_2, 485).
--define(wxGrid_MakeCellVisible_2, 486).
--define(wxGrid_MakeCellVisible_1, 487).
--define(wxGrid_MoveCursorDown, 488).
--define(wxGrid_MoveCursorLeft, 489).
--define(wxGrid_MoveCursorRight, 490).
--define(wxGrid_MoveCursorUp, 491).
--define(wxGrid_MoveCursorDownBlock, 492).
--define(wxGrid_MoveCursorLeftBlock, 493).
--define(wxGrid_MoveCursorRightBlock, 494).
--define(wxGrid_MoveCursorUpBlock, 495).
--define(wxGrid_MovePageDown, 496).
--define(wxGrid_MovePageUp, 497).
--define(wxGrid_RegisterDataType, 498).
--define(wxGrid_SaveEditControlValue, 499).
--define(wxGrid_SelectAll, 500).
--define(wxGrid_SelectBlock_5, 501).
--define(wxGrid_SelectBlock_3, 502).
--define(wxGrid_SelectCol, 503).
--define(wxGrid_SelectRow, 504).
--define(wxGrid_SetCellAlignment_4, 505).
--define(wxGrid_SetCellAlignment_3, 506).
--define(wxGrid_SetCellAlignment_1, 507).
--define(wxGrid_SetCellBackgroundColour_3_0, 508).
--define(wxGrid_SetCellBackgroundColour_1, 509).
--define(wxGrid_SetCellBackgroundColour_3_1, 510).
--define(wxGrid_SetCellEditor, 511).
--define(wxGrid_SetCellFont, 512).
--define(wxGrid_SetCellRenderer, 513).
--define(wxGrid_SetCellTextColour_3_0, 514).
--define(wxGrid_SetCellTextColour_3_1, 515).
--define(wxGrid_SetCellTextColour_1, 516).
--define(wxGrid_SetCellValue_3_0, 517).
--define(wxGrid_SetCellValue_2, 518).
--define(wxGrid_SetCellValue_3_1, 519).
--define(wxGrid_SetColAttr, 520).
--define(wxGrid_SetColFormatBool, 521).
--define(wxGrid_SetColFormatNumber, 522).
--define(wxGrid_SetColFormatFloat, 523).
--define(wxGrid_SetColFormatCustom, 524).
--define(wxGrid_SetColLabelAlignment, 525).
--define(wxGrid_SetColLabelSize, 526).
--define(wxGrid_SetColLabelValue, 527).
--define(wxGrid_SetColMinimalWidth, 528).
--define(wxGrid_SetColMinimalAcceptableWidth, 529).
--define(wxGrid_SetColSize, 530).
--define(wxGrid_SetDefaultCellAlignment, 531).
--define(wxGrid_SetDefaultCellBackgroundColour, 532).
--define(wxGrid_SetDefaultCellFont, 533).
--define(wxGrid_SetDefaultCellTextColour, 534).
--define(wxGrid_SetDefaultEditor, 535).
--define(wxGrid_SetDefaultRenderer, 536).
--define(wxGrid_SetDefaultColSize, 537).
--define(wxGrid_SetDefaultRowSize, 538).
--define(wxGrid_SetGridCursor, 539).
--define(wxGrid_SetGridLineColour, 540).
--define(wxGrid_SetLabelBackgroundColour, 541).
--define(wxGrid_SetLabelFont, 542).
--define(wxGrid_SetLabelTextColour, 543).
--define(wxGrid_SetMargins, 544).
--define(wxGrid_SetReadOnly, 545).
--define(wxGrid_SetRowAttr, 546).
--define(wxGrid_SetRowLabelAlignment, 547).
--define(wxGrid_SetRowLabelSize, 548).
--define(wxGrid_SetRowLabelValue, 549).
--define(wxGrid_SetRowMinimalHeight, 550).
--define(wxGrid_SetRowMinimalAcceptableHeight, 551).
--define(wxGrid_SetRowSize, 552).
--define(wxGrid_SetScrollLineX, 553).
--define(wxGrid_SetScrollLineY, 554).
--define(wxGrid_SetSelectionBackground, 555).
--define(wxGrid_SetSelectionForeground, 556).
--define(wxGrid_SetSelectionMode, 557).
--define(wxGrid_ShowCellEditControl, 558).
--define(wxGrid_XToCol, 559).
--define(wxGrid_XToEdgeOfCol, 560).
--define(wxGrid_YToEdgeOfRow, 561).
--define(wxGrid_YToRow, 562).
--define(wxGridCellRenderer_Draw, 563).
--define(wxGridCellRenderer_GetBestSize, 564).
--define(wxGridCellEditor_Create, 565).
--define(wxGridCellEditor_IsCreated, 566).
--define(wxGridCellEditor_SetSize, 567).
--define(wxGridCellEditor_Show, 568).
--define(wxGridCellEditor_PaintBackground, 569).
--define(wxGridCellEditor_BeginEdit, 570).
--define(wxGridCellEditor_EndEdit, 571).
--define(wxGridCellEditor_Reset, 572).
--define(wxGridCellEditor_StartingKey, 573).
--define(wxGridCellEditor_StartingClick, 574).
--define(wxGridCellEditor_HandleReturn, 575).
--define(wxGridCellBoolRenderer_new, 576).
--define(wxGridCellBoolRenderer_destroy, 577).
--define(wxGridCellBoolEditor_new, 578).
--define(wxGridCellBoolEditor_IsTrueValue, 579).
--define(wxGridCellBoolEditor_UseStringValues, 580).
--define(wxGridCellBoolEditor_destroy, 581).
--define(wxGridCellFloatRenderer_new, 582).
--define(wxGridCellFloatRenderer_GetPrecision, 583).
--define(wxGridCellFloatRenderer_GetWidth, 584).
--define(wxGridCellFloatRenderer_SetParameters, 585).
--define(wxGridCellFloatRenderer_SetPrecision, 586).
--define(wxGridCellFloatRenderer_SetWidth, 587).
--define(wxGridCellFloatRenderer_destroy, 588).
--define(wxGridCellFloatEditor_new, 589).
--define(wxGridCellFloatEditor_SetParameters, 590).
--define(wxGridCellFloatEditor_destroy, 591).
--define(wxGridCellStringRenderer_new, 592).
--define(wxGridCellStringRenderer_destroy, 593).
--define(wxGridCellTextEditor_new, 594).
--define(wxGridCellTextEditor_SetParameters, 595).
--define(wxGridCellTextEditor_destroy, 596).
--define(wxGridCellChoiceEditor_new, 598).
--define(wxGridCellChoiceEditor_SetParameters, 599).
--define(wxGridCellChoiceEditor_destroy, 600).
--define(wxGridCellNumberRenderer_new, 601).
--define(wxGridCellNumberRenderer_destroy, 602).
--define(wxGridCellNumberEditor_new, 603).
--define(wxGridCellNumberEditor_GetValue, 604).
--define(wxGridCellNumberEditor_SetParameters, 605).
--define(wxGridCellNumberEditor_destroy, 606).
--define(wxGridCellAttr_SetTextColour, 607).
--define(wxGridCellAttr_SetBackgroundColour, 608).
--define(wxGridCellAttr_SetFont, 609).
--define(wxGridCellAttr_SetAlignment, 610).
--define(wxGridCellAttr_SetReadOnly, 611).
--define(wxGridCellAttr_SetRenderer, 612).
--define(wxGridCellAttr_SetEditor, 613).
--define(wxGridCellAttr_HasTextColour, 614).
--define(wxGridCellAttr_HasBackgroundColour, 615).
--define(wxGridCellAttr_HasFont, 616).
--define(wxGridCellAttr_HasAlignment, 617).
--define(wxGridCellAttr_HasRenderer, 618).
--define(wxGridCellAttr_HasEditor, 619).
--define(wxGridCellAttr_GetTextColour, 620).
--define(wxGridCellAttr_GetBackgroundColour, 621).
--define(wxGridCellAttr_GetFont, 622).
--define(wxGridCellAttr_GetAlignment, 623).
--define(wxGridCellAttr_GetRenderer, 624).
--define(wxGridCellAttr_GetEditor, 625).
--define(wxGridCellAttr_IsReadOnly, 626).
--define(wxGridCellAttr_SetDefAttr, 627).
--define(wxDC_Blit, 628).
--define(wxDC_CalcBoundingBox, 629).
--define(wxDC_Clear, 630).
--define(wxDC_ComputeScaleAndOrigin, 631).
--define(wxDC_CrossHair, 632).
--define(wxDC_DestroyClippingRegion, 633).
--define(wxDC_DeviceToLogicalX, 634).
--define(wxDC_DeviceToLogicalXRel, 635).
--define(wxDC_DeviceToLogicalY, 636).
--define(wxDC_DeviceToLogicalYRel, 637).
--define(wxDC_DrawArc, 638).
--define(wxDC_DrawBitmap, 639).
--define(wxDC_DrawCheckMark, 640).
--define(wxDC_DrawCircle, 641).
--define(wxDC_DrawEllipse_2, 643).
--define(wxDC_DrawEllipse_1, 644).
--define(wxDC_DrawEllipticArc, 645).
--define(wxDC_DrawIcon, 646).
--define(wxDC_DrawLabel, 647).
--define(wxDC_DrawLine, 648).
--define(wxDC_DrawLines, 649).
--define(wxDC_DrawPolygon, 651).
--define(wxDC_DrawPoint, 653).
--define(wxDC_DrawRectangle_2, 655).
--define(wxDC_DrawRectangle_1, 656).
--define(wxDC_DrawRotatedText, 657).
--define(wxDC_DrawRoundedRectangle_3, 659).
--define(wxDC_DrawRoundedRectangle_2, 660).
--define(wxDC_DrawText, 661).
--define(wxDC_EndDoc, 662).
--define(wxDC_EndPage, 663).
--define(wxDC_FloodFill, 664).
--define(wxDC_GetBackground, 665).
--define(wxDC_GetBackgroundMode, 666).
--define(wxDC_GetBrush, 667).
--define(wxDC_GetCharHeight, 668).
--define(wxDC_GetCharWidth, 669).
--define(wxDC_GetClippingBox, 670).
--define(wxDC_GetFont, 672).
--define(wxDC_GetLayoutDirection, 673).
--define(wxDC_GetLogicalFunction, 674).
--define(wxDC_GetMapMode, 675).
--define(wxDC_GetMultiLineTextExtent_4, 676).
--define(wxDC_GetMultiLineTextExtent_1, 677).
--define(wxDC_GetPartialTextExtents, 678).
--define(wxDC_GetPen, 679).
--define(wxDC_GetPixel, 680).
--define(wxDC_GetPPI, 681).
--define(wxDC_GetSize, 683).
--define(wxDC_GetSizeMM, 685).
--define(wxDC_GetTextBackground, 686).
--define(wxDC_GetTextExtent_4, 687).
--define(wxDC_GetTextExtent_1, 688).
--define(wxDC_GetTextForeground, 690).
--define(wxDC_GetUserScale, 691).
--define(wxDC_GradientFillConcentric_3, 692).
--define(wxDC_GradientFillConcentric_4, 693).
--define(wxDC_GradientFillLinear, 694).
--define(wxDC_LogicalToDeviceX, 695).
--define(wxDC_LogicalToDeviceXRel, 696).
--define(wxDC_LogicalToDeviceY, 697).
--define(wxDC_LogicalToDeviceYRel, 698).
--define(wxDC_MaxX, 699).
--define(wxDC_MaxY, 700).
--define(wxDC_MinX, 701).
--define(wxDC_MinY, 702).
--define(wxDC_IsOk, 703).
--define(wxDC_ResetBoundingBox, 704).
--define(wxDC_SetAxisOrientation, 705).
--define(wxDC_SetBackground, 706).
--define(wxDC_SetBackgroundMode, 707).
--define(wxDC_SetBrush, 708).
--define(wxDC_SetClippingRegion_2, 710).
--define(wxDC_SetClippingRegion_1_1, 711).
--define(wxDC_SetClippingRegion_1_0, 712).
--define(wxDC_SetDeviceOrigin, 713).
--define(wxDC_SetFont, 714).
--define(wxDC_SetLayoutDirection, 715).
--define(wxDC_SetLogicalFunction, 716).
--define(wxDC_SetMapMode, 717).
--define(wxDC_SetPalette, 718).
--define(wxDC_SetPen, 719).
--define(wxDC_SetTextBackground, 720).
--define(wxDC_SetTextForeground, 721).
--define(wxDC_SetUserScale, 722).
--define(wxDC_StartDoc, 723).
--define(wxDC_StartPage, 724).
--define(wxMirrorDC_new, 725).
--define(wxMirrorDC_destroy, 726).
--define(wxScreenDC_new, 727).
--define(wxScreenDC_destruct, 728).
--define(wxPostScriptDC_new_0, 729).
--define(wxPostScriptDC_new_1, 730).
--define(wxPostScriptDC_destruct, 731).
--define(wxPostScriptDC_SetResolution, 732).
--define(wxPostScriptDC_GetResolution, 733).
--define(wxWindowDC_new_0, 734).
--define(wxWindowDC_new_1, 735).
--define(wxWindowDC_destruct, 736).
--define(wxClientDC_new_0, 737).
--define(wxClientDC_new_1, 738).
--define(wxClientDC_destroy, 739).
--define(wxPaintDC_new_0, 740).
--define(wxPaintDC_new_1, 741).
--define(wxPaintDC_destroy, 742).
--define(wxMemoryDC_new_1_0, 744).
--define(wxMemoryDC_new_1_1, 745).
--define(wxMemoryDC_new_0, 746).
--define(wxMemoryDC_destruct, 748).
--define(wxMemoryDC_SelectObject, 749).
--define(wxMemoryDC_SelectObjectAsSource, 750).
--define(wxBufferedDC_new_0, 751).
--define(wxBufferedDC_new_2, 752).
--define(wxBufferedDC_new_3, 753).
--define(wxBufferedDC_destruct, 754).
--define(wxBufferedDC_Init_2, 755).
--define(wxBufferedDC_Init_3, 756).
--define(wxBufferedPaintDC_new_3, 757).
--define(wxBufferedPaintDC_new_2, 758).
--define(wxBufferedPaintDC_destruct, 759).
--define(wxGraphicsObject_destruct, 760).
--define(wxGraphicsObject_GetRenderer, 761).
--define(wxGraphicsObject_IsNull, 762).
--define(wxGraphicsContext_destruct, 763).
--define(wxGraphicsContext_Create_1_1, 764).
--define(wxGraphicsContext_Create_1_0, 765).
--define(wxGraphicsContext_Create_0, 766).
--define(wxGraphicsContext_CreatePen, 767).
--define(wxGraphicsContext_CreateBrush, 768).
--define(wxGraphicsContext_CreateRadialGradientBrush, 769).
--define(wxGraphicsContext_CreateLinearGradientBrush, 770).
--define(wxGraphicsContext_CreateFont, 771).
--define(wxGraphicsContext_CreateMatrix, 772).
--define(wxGraphicsContext_CreatePath, 773).
--define(wxGraphicsContext_Clip_1, 774).
--define(wxGraphicsContext_Clip_4, 775).
--define(wxGraphicsContext_ResetClip, 776).
--define(wxGraphicsContext_DrawBitmap, 777).
--define(wxGraphicsContext_DrawEllipse, 778).
--define(wxGraphicsContext_DrawIcon, 779).
--define(wxGraphicsContext_DrawLines, 780).
--define(wxGraphicsContext_DrawPath, 781).
--define(wxGraphicsContext_DrawRectangle, 782).
--define(wxGraphicsContext_DrawRoundedRectangle, 783).
--define(wxGraphicsContext_DrawText_3, 784).
--define(wxGraphicsContext_DrawText_4_0, 785).
--define(wxGraphicsContext_DrawText_4_1, 786).
--define(wxGraphicsContext_DrawText_5, 787).
--define(wxGraphicsContext_FillPath, 788).
--define(wxGraphicsContext_StrokePath, 789).
--define(wxGraphicsContext_GetPartialTextExtents, 790).
--define(wxGraphicsContext_GetTextExtent, 791).
--define(wxGraphicsContext_Rotate, 792).
--define(wxGraphicsContext_Scale, 793).
--define(wxGraphicsContext_Translate, 794).
--define(wxGraphicsContext_GetTransform, 795).
--define(wxGraphicsContext_SetTransform, 796).
--define(wxGraphicsContext_ConcatTransform, 797).
--define(wxGraphicsContext_SetBrush_1_1, 798).
--define(wxGraphicsContext_SetBrush_1_0, 799).
--define(wxGraphicsContext_SetFont_1, 800).
--define(wxGraphicsContext_SetFont_2, 801).
--define(wxGraphicsContext_SetPen_1_0, 802).
--define(wxGraphicsContext_SetPen_1_1, 803).
--define(wxGraphicsContext_StrokeLine, 804).
--define(wxGraphicsContext_StrokeLines, 805).
--define(wxGraphicsMatrix_Concat, 807).
--define(wxGraphicsMatrix_Get, 809).
--define(wxGraphicsMatrix_Invert, 810).
--define(wxGraphicsMatrix_IsEqual, 811).
--define(wxGraphicsMatrix_IsIdentity, 813).
--define(wxGraphicsMatrix_Rotate, 814).
--define(wxGraphicsMatrix_Scale, 815).
--define(wxGraphicsMatrix_Translate, 816).
--define(wxGraphicsMatrix_Set, 817).
--define(wxGraphicsMatrix_TransformPoint, 818).
--define(wxGraphicsMatrix_TransformDistance, 819).
--define(wxGraphicsPath_MoveToPoint_2, 820).
--define(wxGraphicsPath_MoveToPoint_1, 821).
--define(wxGraphicsPath_AddArc_6, 822).
--define(wxGraphicsPath_AddArc_5, 823).
--define(wxGraphicsPath_AddArcToPoint, 824).
--define(wxGraphicsPath_AddCircle, 825).
--define(wxGraphicsPath_AddCurveToPoint_6, 826).
--define(wxGraphicsPath_AddCurveToPoint_3, 827).
--define(wxGraphicsPath_AddEllipse, 828).
--define(wxGraphicsPath_AddLineToPoint_2, 829).
--define(wxGraphicsPath_AddLineToPoint_1, 830).
--define(wxGraphicsPath_AddPath, 831).
--define(wxGraphicsPath_AddQuadCurveToPoint, 832).
--define(wxGraphicsPath_AddRectangle, 833).
--define(wxGraphicsPath_AddRoundedRectangle, 834).
--define(wxGraphicsPath_CloseSubpath, 835).
--define(wxGraphicsPath_Contains_3, 836).
--define(wxGraphicsPath_Contains_2, 837).
--define(wxGraphicsPath_GetBox, 839).
--define(wxGraphicsPath_GetCurrentPoint, 841).
--define(wxGraphicsPath_Transform, 842).
--define(wxGraphicsRenderer_GetDefaultRenderer, 843).
--define(wxGraphicsRenderer_CreateContext_1_1, 844).
--define(wxGraphicsRenderer_CreateContext_1_0, 845).
--define(wxGraphicsRenderer_CreatePen, 846).
--define(wxGraphicsRenderer_CreateBrush, 847).
--define(wxGraphicsRenderer_CreateLinearGradientBrush, 848).
--define(wxGraphicsRenderer_CreateRadialGradientBrush, 849).
--define(wxGraphicsRenderer_CreateFont, 850).
--define(wxGraphicsRenderer_CreateMatrix, 851).
--define(wxGraphicsRenderer_CreatePath, 852).
--define(wxMenuBar_new_1, 854).
--define(wxMenuBar_new_0, 856).
--define(wxMenuBar_destruct, 858).
--define(wxMenuBar_Append, 859).
--define(wxMenuBar_Check, 860).
--define(wxMenuBar_Enable_2, 861).
--define(wxMenuBar_Enable_1, 862).
--define(wxMenuBar_EnableTop, 863).
--define(wxMenuBar_FindMenu, 864).
--define(wxMenuBar_FindMenuItem, 865).
--define(wxMenuBar_FindItem, 866).
--define(wxMenuBar_GetHelpString, 867).
--define(wxMenuBar_GetLabel_1, 868).
--define(wxMenuBar_GetLabel_0, 869).
--define(wxMenuBar_GetLabelTop, 870).
--define(wxMenuBar_GetMenu, 871).
--define(wxMenuBar_GetMenuCount, 872).
--define(wxMenuBar_Insert, 873).
--define(wxMenuBar_IsChecked, 874).
--define(wxMenuBar_IsEnabled_1, 875).
--define(wxMenuBar_IsEnabled_0, 876).
--define(wxMenuBar_Remove, 877).
--define(wxMenuBar_Replace, 878).
--define(wxMenuBar_SetHelpString, 879).
--define(wxMenuBar_SetLabel_2, 880).
--define(wxMenuBar_SetLabel_1, 881).
--define(wxMenuBar_SetLabelTop, 882).
--define(wxControl_GetLabel, 883).
--define(wxControl_SetLabel, 884).
--define(wxControlWithItems_Append_1, 885).
--define(wxControlWithItems_Append_2, 886).
--define(wxControlWithItems_appendStrings_1, 887).
--define(wxControlWithItems_Clear, 888).
--define(wxControlWithItems_Delete, 889).
--define(wxControlWithItems_FindString, 890).
--define(wxControlWithItems_getClientData, 891).
--define(wxControlWithItems_setClientData, 892).
--define(wxControlWithItems_GetCount, 893).
--define(wxControlWithItems_GetSelection, 894).
--define(wxControlWithItems_GetString, 895).
--define(wxControlWithItems_GetStringSelection, 896).
--define(wxControlWithItems_Insert_2, 897).
--define(wxControlWithItems_Insert_3, 898).
--define(wxControlWithItems_IsEmpty, 899).
--define(wxControlWithItems_Select, 900).
--define(wxControlWithItems_SetSelection, 901).
--define(wxControlWithItems_SetString, 902).
--define(wxControlWithItems_SetStringSelection, 903).
--define(wxMenu_new_2, 906).
--define(wxMenu_new_1, 907).
--define(wxMenu_destruct, 909).
--define(wxMenu_Append_3, 910).
--define(wxMenu_Append_1, 911).
--define(wxMenu_Append_4_0, 912).
--define(wxMenu_Append_4_1, 913).
--define(wxMenu_AppendCheckItem, 914).
--define(wxMenu_AppendRadioItem, 915).
--define(wxMenu_AppendSeparator, 916).
--define(wxMenu_Break, 917).
--define(wxMenu_Check, 918).
--define(wxMenu_Delete_1_0, 919).
--define(wxMenu_Delete_1_1, 920).
--define(wxMenu_Destroy_1_0, 921).
--define(wxMenu_Destroy_1_1, 922).
--define(wxMenu_Enable, 923).
--define(wxMenu_FindItem_1, 924).
--define(wxMenu_FindItem_2, 925).
--define(wxMenu_FindItemByPosition, 926).
--define(wxMenu_GetHelpString, 927).
--define(wxMenu_GetLabel, 928).
--define(wxMenu_GetMenuItemCount, 929).
--define(wxMenu_GetMenuItems, 930).
--define(wxMenu_GetTitle, 932).
--define(wxMenu_Insert_2, 933).
--define(wxMenu_Insert_3, 934).
--define(wxMenu_Insert_5_1, 935).
--define(wxMenu_Insert_5_0, 936).
--define(wxMenu_InsertCheckItem, 937).
--define(wxMenu_InsertRadioItem, 938).
--define(wxMenu_InsertSeparator, 939).
--define(wxMenu_IsChecked, 940).
--define(wxMenu_IsEnabled, 941).
--define(wxMenu_Prepend_1, 942).
--define(wxMenu_Prepend_2, 943).
--define(wxMenu_Prepend_4_1, 944).
--define(wxMenu_Prepend_4_0, 945).
--define(wxMenu_PrependCheckItem, 946).
--define(wxMenu_PrependRadioItem, 947).
--define(wxMenu_PrependSeparator, 948).
--define(wxMenu_Remove_1_0, 949).
--define(wxMenu_Remove_1_1, 950).
--define(wxMenu_SetHelpString, 951).
--define(wxMenu_SetLabel, 952).
--define(wxMenu_SetTitle, 953).
--define(wxMenuItem_new, 954).
--define(wxMenuItem_destruct, 956).
--define(wxMenuItem_Check, 957).
--define(wxMenuItem_Enable, 958).
--define(wxMenuItem_GetBitmap, 959).
--define(wxMenuItem_GetHelp, 960).
--define(wxMenuItem_GetId, 961).
--define(wxMenuItem_GetKind, 962).
--define(wxMenuItem_GetLabel, 963).
--define(wxMenuItem_GetLabelFromText, 964).
--define(wxMenuItem_GetMenu, 965).
--define(wxMenuItem_GetText, 966).
--define(wxMenuItem_GetSubMenu, 967).
--define(wxMenuItem_IsCheckable, 968).
--define(wxMenuItem_IsChecked, 969).
--define(wxMenuItem_IsEnabled, 970).
--define(wxMenuItem_IsSeparator, 971).
--define(wxMenuItem_IsSubMenu, 972).
--define(wxMenuItem_SetBitmap, 973).
--define(wxMenuItem_SetHelp, 974).
--define(wxMenuItem_SetMenu, 975).
--define(wxMenuItem_SetSubMenu, 976).
--define(wxMenuItem_SetText, 977).
--define(wxToolBar_AddControl, 978).
--define(wxToolBar_AddSeparator, 979).
--define(wxToolBar_AddTool_5, 980).
--define(wxToolBar_AddTool_4_0, 981).
--define(wxToolBar_AddTool_1, 982).
--define(wxToolBar_AddTool_4_1, 983).
--define(wxToolBar_AddTool_3, 984).
--define(wxToolBar_AddTool_6, 985).
--define(wxToolBar_AddCheckTool, 986).
--define(wxToolBar_AddRadioTool, 987).
--define(wxToolBar_AddStretchableSpace, 988).
--define(wxToolBar_InsertStretchableSpace, 989).
--define(wxToolBar_DeleteTool, 990).
--define(wxToolBar_DeleteToolByPos, 991).
--define(wxToolBar_EnableTool, 992).
--define(wxToolBar_FindById, 993).
--define(wxToolBar_FindControl, 994).
--define(wxToolBar_FindToolForPosition, 995).
--define(wxToolBar_GetToolSize, 996).
--define(wxToolBar_GetToolBitmapSize, 997).
--define(wxToolBar_GetMargins, 998).
--define(wxToolBar_GetToolEnabled, 999).
--define(wxToolBar_GetToolLongHelp, 1000).
--define(wxToolBar_GetToolPacking, 1001).
--define(wxToolBar_GetToolPos, 1002).
--define(wxToolBar_GetToolSeparation, 1003).
--define(wxToolBar_GetToolShortHelp, 1004).
--define(wxToolBar_GetToolState, 1005).
--define(wxToolBar_InsertControl, 1006).
--define(wxToolBar_InsertSeparator, 1007).
--define(wxToolBar_InsertTool_5, 1008).
--define(wxToolBar_InsertTool_2, 1009).
--define(wxToolBar_InsertTool_4, 1010).
--define(wxToolBar_Realize, 1011).
--define(wxToolBar_RemoveTool, 1012).
--define(wxToolBar_SetMargins, 1013).
--define(wxToolBar_SetToolBitmapSize, 1014).
--define(wxToolBar_SetToolLongHelp, 1015).
--define(wxToolBar_SetToolPacking, 1016).
--define(wxToolBar_SetToolShortHelp, 1017).
--define(wxToolBar_SetToolSeparation, 1018).
--define(wxToolBar_ToggleTool, 1019).
--define(wxStatusBar_new_0, 1021).
--define(wxStatusBar_new_2, 1022).
--define(wxStatusBar_destruct, 1024).
--define(wxStatusBar_Create, 1025).
--define(wxStatusBar_GetFieldRect, 1026).
--define(wxStatusBar_GetFieldsCount, 1027).
--define(wxStatusBar_GetStatusText, 1028).
--define(wxStatusBar_PopStatusText, 1029).
--define(wxStatusBar_PushStatusText, 1030).
--define(wxStatusBar_SetFieldsCount, 1031).
--define(wxStatusBar_SetMinHeight, 1032).
--define(wxStatusBar_SetStatusText, 1033).
--define(wxStatusBar_SetStatusWidths, 1034).
--define(wxStatusBar_SetStatusStyles, 1035).
--define(wxBitmap_new_0, 1036).
--define(wxBitmap_new_3, 1037).
--define(wxBitmap_new_4, 1038).
--define(wxBitmap_new_2_0, 1039).
--define(wxBitmap_new_2_1, 1040).
--define(wxBitmap_destruct, 1041).
--define(wxBitmap_ConvertToImage, 1042).
--define(wxBitmap_CopyFromIcon, 1043).
--define(wxBitmap_Create, 1044).
--define(wxBitmap_GetDepth, 1045).
--define(wxBitmap_GetHeight, 1046).
--define(wxBitmap_GetPalette, 1047).
--define(wxBitmap_GetMask, 1048).
--define(wxBitmap_GetWidth, 1049).
--define(wxBitmap_GetSubBitmap, 1050).
--define(wxBitmap_LoadFile, 1051).
--define(wxBitmap_Ok, 1052).
--define(wxBitmap_SaveFile, 1053).
--define(wxBitmap_SetDepth, 1054).
--define(wxBitmap_SetHeight, 1055).
--define(wxBitmap_SetMask, 1056).
--define(wxBitmap_SetPalette, 1057).
--define(wxBitmap_SetWidth, 1058).
--define(wxIcon_new_0, 1059).
--define(wxIcon_new_2, 1060).
--define(wxIcon_new_1, 1061).
--define(wxIcon_CopyFromBitmap, 1062).
--define(wxIcon_destroy, 1063).
--define(wxIconBundle_new_0, 1064).
--define(wxIconBundle_new_2, 1065).
--define(wxIconBundle_new_1_0, 1066).
--define(wxIconBundle_new_1_1, 1067).
--define(wxIconBundle_destruct, 1068).
--define(wxIconBundle_AddIcon_2, 1069).
--define(wxIconBundle_AddIcon_1, 1070).
--define(wxIconBundle_GetIcon_1_1, 1071).
--define(wxIconBundle_GetIcon_1_0, 1072).
--define(wxCursor_new_0, 1073).
--define(wxCursor_new_1_0, 1074).
--define(wxCursor_new_1_1, 1075).
--define(wxCursor_new_4, 1076).
--define(wxCursor_destruct, 1077).
--define(wxCursor_Ok, 1078).
--define(wxMask_new_0, 1079).
--define(wxMask_new_2_1, 1080).
--define(wxMask_new_2_0, 1081).
--define(wxMask_new_1, 1082).
--define(wxMask_destruct, 1083).
--define(wxMask_Create_2_1, 1084).
--define(wxMask_Create_2_0, 1085).
--define(wxMask_Create_1, 1086).
--define(wxImage_new_0, 1087).
--define(wxImage_new_3_0, 1088).
--define(wxImage_new_4, 1089).
--define(wxImage_new_5, 1090).
--define(wxImage_new_2, 1091).
--define(wxImage_new_3_1, 1092).
--define(wxImage_Blur, 1093).
--define(wxImage_BlurHorizontal, 1094).
--define(wxImage_BlurVertical, 1095).
--define(wxImage_ConvertAlphaToMask, 1096).
--define(wxImage_ConvertToGreyscale, 1097).
--define(wxImage_ConvertToMono, 1098).
--define(wxImage_Copy, 1099).
--define(wxImage_Create_3, 1100).
--define(wxImage_Create_4, 1101).
--define(wxImage_Create_5, 1102).
--define(wxImage_Destroy, 1103).
--define(wxImage_FindFirstUnusedColour, 1104).
--define(wxImage_GetImageExtWildcard, 1105).
--define(wxImage_GetAlpha_2, 1106).
--define(wxImage_GetAlpha_0, 1107).
--define(wxImage_GetBlue, 1108).
--define(wxImage_GetData, 1109).
--define(wxImage_GetGreen, 1110).
--define(wxImage_GetImageCount, 1111).
--define(wxImage_GetHeight, 1112).
--define(wxImage_GetMaskBlue, 1113).
--define(wxImage_GetMaskGreen, 1114).
--define(wxImage_GetMaskRed, 1115).
--define(wxImage_GetOrFindMaskColour, 1116).
--define(wxImage_GetPalette, 1117).
--define(wxImage_GetRed, 1118).
--define(wxImage_GetSubImage, 1119).
--define(wxImage_GetWidth, 1120).
--define(wxImage_HasAlpha, 1121).
--define(wxImage_HasMask, 1122).
--define(wxImage_GetOption, 1123).
--define(wxImage_GetOptionInt, 1124).
--define(wxImage_HasOption, 1125).
--define(wxImage_InitAlpha, 1126).
--define(wxImage_InitStandardHandlers, 1127).
--define(wxImage_IsTransparent, 1128).
--define(wxImage_LoadFile_2, 1129).
--define(wxImage_LoadFile_3, 1130).
--define(wxImage_Ok, 1131).
--define(wxImage_RemoveHandler, 1132).
--define(wxImage_Mirror, 1133).
--define(wxImage_Replace, 1134).
--define(wxImage_Rescale, 1135).
--define(wxImage_Resize, 1136).
--define(wxImage_Rotate, 1137).
--define(wxImage_RotateHue, 1138).
--define(wxImage_Rotate90, 1139).
--define(wxImage_SaveFile_1, 1140).
--define(wxImage_SaveFile_2_0, 1141).
--define(wxImage_SaveFile_2_1, 1142).
--define(wxImage_Scale, 1143).
--define(wxImage_Size, 1144).
--define(wxImage_SetAlpha_3, 1145).
--define(wxImage_SetAlpha_2, 1146).
--define(wxImage_SetData_2, 1147).
--define(wxImage_SetData_4, 1148).
--define(wxImage_SetMask, 1149).
--define(wxImage_SetMaskColour, 1150).
--define(wxImage_SetMaskFromImage, 1151).
--define(wxImage_SetOption_2_1, 1152).
--define(wxImage_SetOption_2_0, 1153).
--define(wxImage_SetPalette, 1154).
--define(wxImage_SetRGB_5, 1155).
--define(wxImage_SetRGB_4, 1156).
--define(wxImage_destroy, 1157).
--define(wxBrush_new_0, 1158).
--define(wxBrush_new_2, 1159).
--define(wxBrush_new_1, 1160).
--define(wxBrush_destruct, 1162).
--define(wxBrush_GetColour, 1163).
--define(wxBrush_GetStipple, 1164).
--define(wxBrush_GetStyle, 1165).
--define(wxBrush_IsHatch, 1166).
--define(wxBrush_IsOk, 1167).
--define(wxBrush_SetColour_1, 1168).
--define(wxBrush_SetColour_3, 1169).
--define(wxBrush_SetStipple, 1170).
--define(wxBrush_SetStyle, 1171).
--define(wxPen_new_0, 1172).
--define(wxPen_new_2, 1173).
--define(wxPen_destruct, 1174).
--define(wxPen_GetCap, 1175).
--define(wxPen_GetColour, 1176).
--define(wxPen_GetJoin, 1177).
--define(wxPen_GetStyle, 1178).
--define(wxPen_GetWidth, 1179).
--define(wxPen_IsOk, 1180).
--define(wxPen_SetCap, 1181).
--define(wxPen_SetColour_1, 1182).
--define(wxPen_SetColour_3, 1183).
--define(wxPen_SetJoin, 1184).
--define(wxPen_SetStyle, 1185).
--define(wxPen_SetWidth, 1186).
--define(wxRegion_new_0, 1187).
--define(wxRegion_new_4, 1188).
--define(wxRegion_new_2, 1189).
--define(wxRegion_new_1_1, 1190).
--define(wxRegion_new_1_0, 1192).
--define(wxRegion_destruct, 1194).
--define(wxRegion_Clear, 1195).
--define(wxRegion_Contains_2, 1196).
--define(wxRegion_Contains_1_0, 1197).
--define(wxRegion_Contains_4, 1198).
--define(wxRegion_Contains_1_1, 1199).
--define(wxRegion_ConvertToBitmap, 1200).
--define(wxRegion_GetBox, 1201).
--define(wxRegion_Intersect_4, 1202).
--define(wxRegion_Intersect_1_1, 1203).
--define(wxRegion_Intersect_1_0, 1204).
--define(wxRegion_IsEmpty, 1205).
--define(wxRegion_Subtract_4, 1206).
--define(wxRegion_Subtract_1_1, 1207).
--define(wxRegion_Subtract_1_0, 1208).
--define(wxRegion_Offset_2, 1209).
--define(wxRegion_Offset_1, 1210).
--define(wxRegion_Union_4, 1211).
--define(wxRegion_Union_1_2, 1212).
--define(wxRegion_Union_1_1, 1213).
--define(wxRegion_Union_1_0, 1214).
--define(wxRegion_Union_3, 1215).
--define(wxRegion_Xor_4, 1216).
--define(wxRegion_Xor_1_1, 1217).
--define(wxRegion_Xor_1_0, 1218).
--define(wxAcceleratorTable_new_0, 1219).
--define(wxAcceleratorTable_new_2, 1220).
--define(wxAcceleratorTable_destruct, 1221).
--define(wxAcceleratorTable_Ok, 1222).
--define(wxAcceleratorEntry_new_1_0, 1223).
--define(wxAcceleratorEntry_new_1_1, 1224).
--define(wxAcceleratorEntry_GetCommand, 1225).
--define(wxAcceleratorEntry_GetFlags, 1226).
--define(wxAcceleratorEntry_GetKeyCode, 1227).
--define(wxAcceleratorEntry_Set, 1228).
--define(wxAcceleratorEntry_destroy, 1229).
--define(wxCaret_new_3, 1234).
--define(wxCaret_new_2, 1235).
--define(wxCaret_destruct, 1237).
--define(wxCaret_Create_3, 1238).
--define(wxCaret_Create_2, 1239).
--define(wxCaret_GetBlinkTime, 1240).
--define(wxCaret_GetPosition, 1242).
--define(wxCaret_GetSize, 1244).
--define(wxCaret_GetWindow, 1245).
--define(wxCaret_Hide, 1246).
--define(wxCaret_IsOk, 1247).
--define(wxCaret_IsVisible, 1248).
--define(wxCaret_Move_2, 1249).
--define(wxCaret_Move_1, 1250).
--define(wxCaret_SetBlinkTime, 1251).
--define(wxCaret_SetSize_2, 1252).
--define(wxCaret_SetSize_1, 1253).
--define(wxCaret_Show, 1254).
--define(wxSizer_Add_2_1, 1255).
--define(wxSizer_Add_2_0, 1256).
--define(wxSizer_Add_3, 1257).
--define(wxSizer_Add_2_3, 1258).
--define(wxSizer_Add_2_2, 1259).
--define(wxSizer_AddSpacer, 1260).
--define(wxSizer_AddStretchSpacer, 1261).
--define(wxSizer_CalcMin, 1262).
--define(wxSizer_Clear, 1263).
--define(wxSizer_Detach_1_2, 1264).
--define(wxSizer_Detach_1_1, 1265).
--define(wxSizer_Detach_1_0, 1266).
--define(wxSizer_Fit, 1267).
--define(wxSizer_FitInside, 1268).
--define(wxSizer_GetChildren, 1269).
--define(wxSizer_GetItem_2_1, 1270).
--define(wxSizer_GetItem_2_0, 1271).
--define(wxSizer_GetItem_1, 1272).
--define(wxSizer_GetSize, 1273).
--define(wxSizer_GetPosition, 1274).
--define(wxSizer_GetMinSize, 1275).
--define(wxSizer_Hide_2_0, 1276).
--define(wxSizer_Hide_2_1, 1277).
--define(wxSizer_Hide_1, 1278).
--define(wxSizer_Insert_3_1, 1279).
--define(wxSizer_Insert_3_0, 1280).
--define(wxSizer_Insert_4, 1281).
--define(wxSizer_Insert_3_3, 1282).
--define(wxSizer_Insert_3_2, 1283).
--define(wxSizer_Insert_2, 1284).
--define(wxSizer_InsertSpacer, 1285).
--define(wxSizer_InsertStretchSpacer, 1286).
--define(wxSizer_IsShown_1_2, 1287).
--define(wxSizer_IsShown_1_1, 1288).
--define(wxSizer_IsShown_1_0, 1289).
--define(wxSizer_Layout, 1290).
--define(wxSizer_Prepend_2_1, 1291).
--define(wxSizer_Prepend_2_0, 1292).
--define(wxSizer_Prepend_3, 1293).
--define(wxSizer_Prepend_2_3, 1294).
--define(wxSizer_Prepend_2_2, 1295).
--define(wxSizer_Prepend_1, 1296).
--define(wxSizer_PrependSpacer, 1297).
--define(wxSizer_PrependStretchSpacer, 1298).
--define(wxSizer_RecalcSizes, 1299).
--define(wxSizer_Remove_1_1, 1300).
--define(wxSizer_Remove_1_0, 1301).
--define(wxSizer_Replace_3_1, 1302).
--define(wxSizer_Replace_3_0, 1303).
--define(wxSizer_Replace_2, 1304).
--define(wxSizer_SetDimension, 1305).
--define(wxSizer_SetMinSize_2, 1306).
--define(wxSizer_SetMinSize_1, 1307).
--define(wxSizer_SetItemMinSize_3_2, 1308).
--define(wxSizer_SetItemMinSize_2_2, 1309).
--define(wxSizer_SetItemMinSize_3_1, 1310).
--define(wxSizer_SetItemMinSize_2_1, 1311).
--define(wxSizer_SetItemMinSize_3_0, 1312).
--define(wxSizer_SetItemMinSize_2_0, 1313).
--define(wxSizer_SetSizeHints, 1314).
--define(wxSizer_SetVirtualSizeHints, 1315).
--define(wxSizer_Show_2_2, 1316).
--define(wxSizer_Show_2_1, 1317).
--define(wxSizer_Show_2_0, 1318).
--define(wxSizer_Show_1, 1319).
--define(wxSizerFlags_new, 1320).
--define(wxSizerFlags_Align, 1321).
--define(wxSizerFlags_Border_2, 1322).
--define(wxSizerFlags_Border_1, 1323).
--define(wxSizerFlags_Center, 1324).
--define(wxSizerFlags_Centre, 1325).
--define(wxSizerFlags_Expand, 1326).
--define(wxSizerFlags_Left, 1327).
--define(wxSizerFlags_Proportion, 1328).
--define(wxSizerFlags_Right, 1329).
--define(wxSizerFlags_destroy, 1330).
--define(wxSizerItem_new_5_1, 1331).
--define(wxSizerItem_new_2_1, 1332).
--define(wxSizerItem_new_5_0, 1333).
--define(wxSizerItem_new_2_0, 1334).
--define(wxSizerItem_new_6, 1335).
--define(wxSizerItem_new_3, 1336).
--define(wxSizerItem_new_0, 1337).
--define(wxSizerItem_destruct, 1338).
--define(wxSizerItem_CalcMin, 1339).
--define(wxSizerItem_DeleteWindows, 1340).
--define(wxSizerItem_DetachSizer, 1341).
--define(wxSizerItem_GetBorder, 1342).
--define(wxSizerItem_GetFlag, 1343).
--define(wxSizerItem_GetMinSize, 1344).
--define(wxSizerItem_GetPosition, 1345).
--define(wxSizerItem_GetProportion, 1346).
--define(wxSizerItem_GetRatio, 1347).
--define(wxSizerItem_GetRect, 1348).
--define(wxSizerItem_GetSize, 1349).
--define(wxSizerItem_GetSizer, 1350).
--define(wxSizerItem_GetSpacer, 1351).
--define(wxSizerItem_GetUserData, 1352).
--define(wxSizerItem_GetWindow, 1353).
--define(wxSizerItem_IsSizer, 1354).
--define(wxSizerItem_IsShown, 1355).
--define(wxSizerItem_IsSpacer, 1356).
--define(wxSizerItem_IsWindow, 1357).
--define(wxSizerItem_SetBorder, 1358).
--define(wxSizerItem_SetDimension, 1359).
--define(wxSizerItem_SetFlag, 1360).
--define(wxSizerItem_SetInitSize, 1361).
--define(wxSizerItem_SetMinSize_1, 1362).
--define(wxSizerItem_SetMinSize_2, 1363).
--define(wxSizerItem_SetProportion, 1364).
--define(wxSizerItem_SetRatio_2, 1365).
--define(wxSizerItem_SetRatio_1_1, 1366).
--define(wxSizerItem_SetRatio_1_0, 1367).
--define(wxSizerItem_SetSizer, 1368).
--define(wxSizerItem_SetSpacer_1, 1369).
--define(wxSizerItem_SetSpacer_2, 1370).
--define(wxSizerItem_SetWindow, 1371).
--define(wxSizerItem_Show, 1372).
--define(wxBoxSizer_new, 1373).
--define(wxBoxSizer_GetOrientation, 1374).
--define(wxBoxSizer_destroy, 1375).
--define(wxStaticBoxSizer_new_2, 1376).
--define(wxStaticBoxSizer_new_3, 1377).
--define(wxStaticBoxSizer_GetStaticBox, 1378).
--define(wxStaticBoxSizer_destroy, 1379).
--define(wxGridSizer_new_4, 1380).
--define(wxGridSizer_new_2, 1381).
--define(wxGridSizer_GetCols, 1382).
--define(wxGridSizer_GetHGap, 1383).
--define(wxGridSizer_GetRows, 1384).
--define(wxGridSizer_GetVGap, 1385).
--define(wxGridSizer_SetCols, 1386).
--define(wxGridSizer_SetHGap, 1387).
--define(wxGridSizer_SetRows, 1388).
--define(wxGridSizer_SetVGap, 1389).
--define(wxGridSizer_destroy, 1390).
--define(wxFlexGridSizer_new_4, 1391).
--define(wxFlexGridSizer_new_2, 1392).
--define(wxFlexGridSizer_AddGrowableCol, 1393).
--define(wxFlexGridSizer_AddGrowableRow, 1394).
--define(wxFlexGridSizer_GetFlexibleDirection, 1395).
--define(wxFlexGridSizer_GetNonFlexibleGrowMode, 1396).
--define(wxFlexGridSizer_RemoveGrowableCol, 1397).
--define(wxFlexGridSizer_RemoveGrowableRow, 1398).
--define(wxFlexGridSizer_SetFlexibleDirection, 1399).
--define(wxFlexGridSizer_SetNonFlexibleGrowMode, 1400).
--define(wxFlexGridSizer_destroy, 1401).
--define(wxGridBagSizer_new, 1402).
--define(wxGridBagSizer_Add_3_2, 1403).
--define(wxGridBagSizer_Add_3_1, 1404).
--define(wxGridBagSizer_Add_4, 1405).
--define(wxGridBagSizer_Add_1_0, 1406).
--define(wxGridBagSizer_Add_2_1, 1407).
--define(wxGridBagSizer_Add_2_0, 1408).
--define(wxGridBagSizer_Add_3_0, 1409).
--define(wxGridBagSizer_Add_1_1, 1410).
--define(wxGridBagSizer_CalcMin, 1411).
--define(wxGridBagSizer_CheckForIntersection_2, 1412).
--define(wxGridBagSizer_CheckForIntersection_3, 1413).
--define(wxGridBagSizer_FindItem_1_1, 1414).
--define(wxGridBagSizer_FindItem_1_0, 1415).
--define(wxGridBagSizer_FindItemAtPoint, 1416).
--define(wxGridBagSizer_FindItemAtPosition, 1417).
--define(wxGridBagSizer_FindItemWithData, 1418).
--define(wxGridBagSizer_GetCellSize, 1419).
--define(wxGridBagSizer_GetEmptyCellSize, 1420).
--define(wxGridBagSizer_GetItemPosition_1_2, 1421).
--define(wxGridBagSizer_GetItemPosition_1_1, 1422).
--define(wxGridBagSizer_GetItemPosition_1_0, 1423).
--define(wxGridBagSizer_GetItemSpan_1_2, 1424).
--define(wxGridBagSizer_GetItemSpan_1_1, 1425).
--define(wxGridBagSizer_GetItemSpan_1_0, 1426).
--define(wxGridBagSizer_SetEmptyCellSize, 1427).
--define(wxGridBagSizer_SetItemPosition_2_2, 1428).
--define(wxGridBagSizer_SetItemPosition_2_1, 1429).
--define(wxGridBagSizer_SetItemPosition_2_0, 1430).
--define(wxGridBagSizer_SetItemSpan_2_2, 1431).
--define(wxGridBagSizer_SetItemSpan_2_1, 1432).
--define(wxGridBagSizer_SetItemSpan_2_0, 1433).
--define(wxGridBagSizer_destroy, 1434).
--define(wxStdDialogButtonSizer_new, 1435).
--define(wxStdDialogButtonSizer_AddButton, 1436).
--define(wxStdDialogButtonSizer_Realize, 1437).
--define(wxStdDialogButtonSizer_SetAffirmativeButton, 1438).
--define(wxStdDialogButtonSizer_SetCancelButton, 1439).
--define(wxStdDialogButtonSizer_SetNegativeButton, 1440).
--define(wxStdDialogButtonSizer_destroy, 1441).
--define(wxFont_new_0, 1442).
--define(wxFont_new_1, 1443).
--define(wxFont_new_5, 1444).
--define(wxFont_destruct, 1446).
--define(wxFont_IsFixedWidth, 1447).
--define(wxFont_GetDefaultEncoding, 1448).
--define(wxFont_GetFaceName, 1449).
--define(wxFont_GetFamily, 1450).
--define(wxFont_GetNativeFontInfoDesc, 1451).
--define(wxFont_GetNativeFontInfoUserDesc, 1452).
--define(wxFont_GetPointSize, 1453).
--define(wxFont_GetStyle, 1454).
--define(wxFont_GetUnderlined, 1455).
--define(wxFont_GetWeight, 1456).
--define(wxFont_Ok, 1457).
--define(wxFont_SetDefaultEncoding, 1458).
--define(wxFont_SetFaceName, 1459).
--define(wxFont_SetFamily, 1460).
--define(wxFont_SetPointSize, 1461).
--define(wxFont_SetStyle, 1462).
--define(wxFont_SetUnderlined, 1463).
--define(wxFont_SetWeight, 1464).
--define(wxToolTip_Enable, 1465).
--define(wxToolTip_SetDelay, 1466).
--define(wxToolTip_new, 1467).
--define(wxToolTip_SetTip, 1468).
--define(wxToolTip_GetTip, 1469).
--define(wxToolTip_GetWindow, 1470).
--define(wxToolTip_destroy, 1471).
--define(wxButton_new_3, 1473).
--define(wxButton_new_0, 1474).
--define(wxButton_destruct, 1475).
--define(wxButton_Create, 1476).
--define(wxButton_GetDefaultSize, 1477).
--define(wxButton_SetDefault, 1478).
--define(wxButton_SetLabel, 1479).
--define(wxBitmapButton_new_4, 1481).
--define(wxBitmapButton_new_0, 1482).
--define(wxBitmapButton_Create, 1483).
--define(wxBitmapButton_GetBitmapDisabled, 1484).
--define(wxBitmapButton_GetBitmapFocus, 1486).
--define(wxBitmapButton_GetBitmapLabel, 1488).
--define(wxBitmapButton_GetBitmapSelected, 1490).
--define(wxBitmapButton_SetBitmapDisabled, 1492).
--define(wxBitmapButton_SetBitmapFocus, 1493).
--define(wxBitmapButton_SetBitmapLabel, 1494).
--define(wxBitmapButton_SetBitmapSelected, 1495).
--define(wxBitmapButton_destroy, 1496).
--define(wxToggleButton_new_0, 1497).
--define(wxToggleButton_new_4, 1498).
--define(wxToggleButton_Create, 1499).
--define(wxToggleButton_GetValue, 1500).
--define(wxToggleButton_SetValue, 1501).
--define(wxToggleButton_destroy, 1502).
--define(wxCalendarCtrl_new_0, 1503).
--define(wxCalendarCtrl_new_3, 1504).
--define(wxCalendarCtrl_Create, 1505).
--define(wxCalendarCtrl_destruct, 1506).
--define(wxCalendarCtrl_SetDate, 1507).
--define(wxCalendarCtrl_GetDate, 1508).
--define(wxCalendarCtrl_EnableYearChange, 1509).
--define(wxCalendarCtrl_EnableMonthChange, 1510).
--define(wxCalendarCtrl_EnableHolidayDisplay, 1511).
--define(wxCalendarCtrl_SetHeaderColours, 1512).
--define(wxCalendarCtrl_GetHeaderColourFg, 1513).
--define(wxCalendarCtrl_GetHeaderColourBg, 1514).
--define(wxCalendarCtrl_SetHighlightColours, 1515).
--define(wxCalendarCtrl_GetHighlightColourFg, 1516).
--define(wxCalendarCtrl_GetHighlightColourBg, 1517).
--define(wxCalendarCtrl_SetHolidayColours, 1518).
--define(wxCalendarCtrl_GetHolidayColourFg, 1519).
--define(wxCalendarCtrl_GetHolidayColourBg, 1520).
--define(wxCalendarCtrl_GetAttr, 1521).
--define(wxCalendarCtrl_SetAttr, 1522).
--define(wxCalendarCtrl_SetHoliday, 1523).
--define(wxCalendarCtrl_ResetAttr, 1524).
--define(wxCalendarCtrl_HitTest, 1525).
--define(wxCalendarDateAttr_new_0, 1526).
--define(wxCalendarDateAttr_new_2_1, 1527).
--define(wxCalendarDateAttr_new_2_0, 1528).
--define(wxCalendarDateAttr_SetTextColour, 1529).
--define(wxCalendarDateAttr_SetBackgroundColour, 1530).
--define(wxCalendarDateAttr_SetBorderColour, 1531).
--define(wxCalendarDateAttr_SetFont, 1532).
--define(wxCalendarDateAttr_SetBorder, 1533).
--define(wxCalendarDateAttr_SetHoliday, 1534).
--define(wxCalendarDateAttr_HasTextColour, 1535).
--define(wxCalendarDateAttr_HasBackgroundColour, 1536).
--define(wxCalendarDateAttr_HasBorderColour, 1537).
--define(wxCalendarDateAttr_HasFont, 1538).
--define(wxCalendarDateAttr_HasBorder, 1539).
--define(wxCalendarDateAttr_IsHoliday, 1540).
--define(wxCalendarDateAttr_GetTextColour, 1541).
--define(wxCalendarDateAttr_GetBackgroundColour, 1542).
--define(wxCalendarDateAttr_GetBorderColour, 1543).
--define(wxCalendarDateAttr_GetFont, 1544).
--define(wxCalendarDateAttr_GetBorder, 1545).
--define(wxCalendarDateAttr_destroy, 1546).
--define(wxCheckBox_new_4, 1548).
--define(wxCheckBox_new_0, 1549).
--define(wxCheckBox_Create, 1550).
--define(wxCheckBox_GetValue, 1551).
--define(wxCheckBox_Get3StateValue, 1552).
--define(wxCheckBox_Is3rdStateAllowedForUser, 1553).
--define(wxCheckBox_Is3State, 1554).
--define(wxCheckBox_IsChecked, 1555).
--define(wxCheckBox_SetValue, 1556).
--define(wxCheckBox_Set3StateValue, 1557).
--define(wxCheckBox_destroy, 1558).
--define(wxCheckListBox_new_0, 1559).
--define(wxCheckListBox_new_3, 1561).
--define(wxCheckListBox_Check, 1562).
--define(wxCheckListBox_IsChecked, 1563).
--define(wxCheckListBox_destroy, 1564).
--define(wxChoice_new_3, 1567).
--define(wxChoice_new_0, 1568).
--define(wxChoice_destruct, 1570).
--define(wxChoice_Create, 1572).
--define(wxChoice_Delete, 1573).
--define(wxChoice_GetColumns, 1574).
--define(wxChoice_SetColumns, 1575).
--define(wxComboBox_new_0, 1576).
--define(wxComboBox_new_3, 1578).
--define(wxComboBox_destruct, 1579).
--define(wxComboBox_Create, 1581).
--define(wxComboBox_CanCopy, 1582).
--define(wxComboBox_CanCut, 1583).
--define(wxComboBox_CanPaste, 1584).
--define(wxComboBox_CanRedo, 1585).
--define(wxComboBox_CanUndo, 1586).
--define(wxComboBox_Copy, 1587).
--define(wxComboBox_Cut, 1588).
--define(wxComboBox_GetInsertionPoint, 1589).
--define(wxComboBox_GetLastPosition, 1590).
--define(wxComboBox_GetValue, 1591).
--define(wxComboBox_Paste, 1592).
--define(wxComboBox_Redo, 1593).
--define(wxComboBox_Replace, 1594).
--define(wxComboBox_Remove, 1595).
--define(wxComboBox_SetInsertionPoint, 1596).
--define(wxComboBox_SetInsertionPointEnd, 1597).
--define(wxComboBox_SetSelection_1, 1598).
--define(wxComboBox_SetSelection_2, 1599).
--define(wxComboBox_SetValue, 1600).
--define(wxComboBox_Undo, 1601).
--define(wxGauge_new_0, 1602).
--define(wxGauge_new_4, 1603).
--define(wxGauge_Create, 1604).
--define(wxGauge_GetRange, 1605).
--define(wxGauge_GetValue, 1606).
--define(wxGauge_IsVertical, 1607).
--define(wxGauge_SetRange, 1608).
--define(wxGauge_SetValue, 1609).
--define(wxGauge_Pulse, 1610).
--define(wxGauge_destroy, 1611).
--define(wxGenericDirCtrl_new_0, 1612).
--define(wxGenericDirCtrl_new_2, 1613).
--define(wxGenericDirCtrl_destruct, 1614).
--define(wxGenericDirCtrl_Create, 1615).
--define(wxGenericDirCtrl_Init, 1616).
--define(wxGenericDirCtrl_CollapseTree, 1617).
--define(wxGenericDirCtrl_ExpandPath, 1618).
--define(wxGenericDirCtrl_GetDefaultPath, 1619).
--define(wxGenericDirCtrl_GetPath, 1620).
--define(wxGenericDirCtrl_GetFilePath, 1621).
--define(wxGenericDirCtrl_GetFilter, 1622).
--define(wxGenericDirCtrl_GetFilterIndex, 1623).
--define(wxGenericDirCtrl_GetRootId, 1624).
--define(wxGenericDirCtrl_GetTreeCtrl, 1625).
--define(wxGenericDirCtrl_ReCreateTree, 1626).
--define(wxGenericDirCtrl_SetDefaultPath, 1627).
--define(wxGenericDirCtrl_SetFilter, 1628).
--define(wxGenericDirCtrl_SetFilterIndex, 1629).
--define(wxGenericDirCtrl_SetPath, 1630).
--define(wxStaticBox_new_4, 1632).
--define(wxStaticBox_new_0, 1633).
--define(wxStaticBox_Create, 1634).
--define(wxStaticBox_destroy, 1635).
--define(wxStaticLine_new_2, 1637).
--define(wxStaticLine_new_0, 1638).
--define(wxStaticLine_Create, 1639).
--define(wxStaticLine_IsVertical, 1640).
--define(wxStaticLine_GetDefaultSize, 1641).
--define(wxStaticLine_destroy, 1642).
--define(wxListBox_new_3, 1645).
--define(wxListBox_new_0, 1646).
--define(wxListBox_destruct, 1648).
--define(wxListBox_Create, 1650).
--define(wxListBox_Deselect, 1651).
--define(wxListBox_GetSelections, 1652).
--define(wxListBox_InsertItems, 1653).
--define(wxListBox_IsSelected, 1654).
--define(wxListBox_Set, 1655).
--define(wxListBox_HitTest, 1656).
--define(wxListBox_SetFirstItem_1_0, 1657).
--define(wxListBox_SetFirstItem_1_1, 1658).
--define(wxListCtrl_new_0, 1659).
--define(wxListCtrl_new_2, 1660).
--define(wxListCtrl_Arrange, 1661).
--define(wxListCtrl_AssignImageList, 1662).
--define(wxListCtrl_ClearAll, 1663).
--define(wxListCtrl_Create, 1664).
--define(wxListCtrl_DeleteAllItems, 1665).
--define(wxListCtrl_DeleteColumn, 1666).
--define(wxListCtrl_DeleteItem, 1667).
--define(wxListCtrl_EditLabel, 1668).
--define(wxListCtrl_EnsureVisible, 1669).
--define(wxListCtrl_FindItem_3_0, 1670).
--define(wxListCtrl_FindItem_3_1, 1671).
--define(wxListCtrl_GetColumn, 1672).
--define(wxListCtrl_GetColumnCount, 1673).
--define(wxListCtrl_GetColumnWidth, 1674).
--define(wxListCtrl_GetCountPerPage, 1675).
--define(wxListCtrl_GetEditControl, 1676).
--define(wxListCtrl_GetImageList, 1677).
--define(wxListCtrl_GetItem, 1678).
--define(wxListCtrl_GetItemBackgroundColour, 1679).
--define(wxListCtrl_GetItemCount, 1680).
--define(wxListCtrl_GetItemData, 1681).
--define(wxListCtrl_GetItemFont, 1682).
--define(wxListCtrl_GetItemPosition, 1683).
--define(wxListCtrl_GetItemRect, 1684).
--define(wxListCtrl_GetItemSpacing, 1685).
--define(wxListCtrl_GetItemState, 1686).
--define(wxListCtrl_GetItemText, 1687).
--define(wxListCtrl_GetItemTextColour, 1688).
--define(wxListCtrl_GetNextItem, 1689).
--define(wxListCtrl_GetSelectedItemCount, 1690).
--define(wxListCtrl_GetTextColour, 1691).
--define(wxListCtrl_GetTopItem, 1692).
--define(wxListCtrl_GetViewRect, 1693).
--define(wxListCtrl_HitTest, 1694).
--define(wxListCtrl_InsertColumn_2, 1695).
--define(wxListCtrl_InsertColumn_3, 1696).
--define(wxListCtrl_InsertItem_1, 1697).
--define(wxListCtrl_InsertItem_2_1, 1698).
--define(wxListCtrl_InsertItem_2_0, 1699).
--define(wxListCtrl_InsertItem_3, 1700).
--define(wxListCtrl_RefreshItem, 1701).
--define(wxListCtrl_RefreshItems, 1702).
--define(wxListCtrl_ScrollList, 1703).
--define(wxListCtrl_SetBackgroundColour, 1704).
--define(wxListCtrl_SetColumn, 1705).
--define(wxListCtrl_SetColumnWidth, 1706).
--define(wxListCtrl_SetImageList, 1707).
--define(wxListCtrl_SetItem_1, 1708).
--define(wxListCtrl_SetItem_4, 1709).
--define(wxListCtrl_SetItemBackgroundColour, 1710).
--define(wxListCtrl_SetItemCount, 1711).
--define(wxListCtrl_SetItemData, 1712).
--define(wxListCtrl_SetItemFont, 1713).
--define(wxListCtrl_SetItemImage, 1714).
--define(wxListCtrl_SetItemColumnImage, 1715).
--define(wxListCtrl_SetItemPosition, 1716).
--define(wxListCtrl_SetItemState, 1717).
--define(wxListCtrl_SetItemText, 1718).
--define(wxListCtrl_SetItemTextColour, 1719).
--define(wxListCtrl_SetSingleStyle, 1720).
--define(wxListCtrl_SetTextColour, 1721).
--define(wxListCtrl_SetWindowStyleFlag, 1722).
--define(wxListCtrl_SortItems, 1723).
--define(wxListCtrl_destroy, 1724).
--define(wxListView_ClearColumnImage, 1725).
--define(wxListView_Focus, 1726).
--define(wxListView_GetFirstSelected, 1727).
--define(wxListView_GetFocusedItem, 1728).
--define(wxListView_GetNextSelected, 1729).
--define(wxListView_IsSelected, 1730).
--define(wxListView_Select, 1731).
--define(wxListView_SetColumnImage, 1732).
--define(wxListItem_new_0, 1733).
--define(wxListItem_new_1, 1734).
--define(wxListItem_destruct, 1735).
--define(wxListItem_Clear, 1736).
--define(wxListItem_GetAlign, 1737).
--define(wxListItem_GetBackgroundColour, 1738).
--define(wxListItem_GetColumn, 1739).
--define(wxListItem_GetFont, 1740).
--define(wxListItem_GetId, 1741).
--define(wxListItem_GetImage, 1742).
--define(wxListItem_GetMask, 1743).
--define(wxListItem_GetState, 1744).
--define(wxListItem_GetText, 1745).
--define(wxListItem_GetTextColour, 1746).
--define(wxListItem_GetWidth, 1747).
--define(wxListItem_SetAlign, 1748).
--define(wxListItem_SetBackgroundColour, 1749).
--define(wxListItem_SetColumn, 1750).
--define(wxListItem_SetFont, 1751).
--define(wxListItem_SetId, 1752).
--define(wxListItem_SetImage, 1753).
--define(wxListItem_SetMask, 1754).
--define(wxListItem_SetState, 1755).
--define(wxListItem_SetStateMask, 1756).
--define(wxListItem_SetText, 1757).
--define(wxListItem_SetTextColour, 1758).
--define(wxListItem_SetWidth, 1759).
--define(wxListItemAttr_new_0, 1760).
--define(wxListItemAttr_new_3, 1761).
--define(wxListItemAttr_GetBackgroundColour, 1762).
--define(wxListItemAttr_GetFont, 1763).
--define(wxListItemAttr_GetTextColour, 1764).
--define(wxListItemAttr_HasBackgroundColour, 1765).
--define(wxListItemAttr_HasFont, 1766).
--define(wxListItemAttr_HasTextColour, 1767).
--define(wxListItemAttr_SetBackgroundColour, 1768).
--define(wxListItemAttr_SetFont, 1769).
--define(wxListItemAttr_SetTextColour, 1770).
--define(wxListItemAttr_destroy, 1771).
--define(wxImageList_new_0, 1772).
--define(wxImageList_new_3, 1773).
--define(wxImageList_Add_1, 1774).
--define(wxImageList_Add_2_0, 1775).
--define(wxImageList_Add_2_1, 1776).
--define(wxImageList_Create, 1777).
--define(wxImageList_Draw, 1779).
--define(wxImageList_GetBitmap, 1780).
--define(wxImageList_GetIcon, 1781).
--define(wxImageList_GetImageCount, 1782).
--define(wxImageList_GetSize, 1783).
--define(wxImageList_Remove, 1784).
--define(wxImageList_RemoveAll, 1785).
--define(wxImageList_Replace_2, 1786).
--define(wxImageList_Replace_3, 1787).
--define(wxImageList_destroy, 1788).
--define(wxTextAttr_new_0, 1789).
--define(wxTextAttr_new_2, 1790).
--define(wxTextAttr_GetAlignment, 1791).
--define(wxTextAttr_GetBackgroundColour, 1792).
--define(wxTextAttr_GetFont, 1793).
--define(wxTextAttr_GetLeftIndent, 1794).
--define(wxTextAttr_GetLeftSubIndent, 1795).
--define(wxTextAttr_GetRightIndent, 1796).
--define(wxTextAttr_GetTabs, 1797).
--define(wxTextAttr_GetTextColour, 1798).
--define(wxTextAttr_HasBackgroundColour, 1799).
--define(wxTextAttr_HasFont, 1800).
--define(wxTextAttr_HasTextColour, 1801).
--define(wxTextAttr_GetFlags, 1802).
--define(wxTextAttr_IsDefault, 1803).
--define(wxTextAttr_SetAlignment, 1804).
--define(wxTextAttr_SetBackgroundColour, 1805).
--define(wxTextAttr_SetFlags, 1806).
--define(wxTextAttr_SetFont, 1807).
--define(wxTextAttr_SetLeftIndent, 1808).
--define(wxTextAttr_SetRightIndent, 1809).
--define(wxTextAttr_SetTabs, 1810).
--define(wxTextAttr_SetTextColour, 1811).
--define(wxTextAttr_destroy, 1812).
--define(wxTextCtrl_new_3, 1814).
--define(wxTextCtrl_new_0, 1815).
--define(wxTextCtrl_destruct, 1817).
--define(wxTextCtrl_AppendText, 1818).
--define(wxTextCtrl_CanCopy, 1819).
--define(wxTextCtrl_CanCut, 1820).
--define(wxTextCtrl_CanPaste, 1821).
--define(wxTextCtrl_CanRedo, 1822).
--define(wxTextCtrl_CanUndo, 1823).
--define(wxTextCtrl_Clear, 1824).
--define(wxTextCtrl_Copy, 1825).
--define(wxTextCtrl_Create, 1826).
--define(wxTextCtrl_Cut, 1827).
--define(wxTextCtrl_DiscardEdits, 1828).
--define(wxTextCtrl_ChangeValue, 1829).
--define(wxTextCtrl_EmulateKeyPress, 1830).
--define(wxTextCtrl_GetDefaultStyle, 1831).
--define(wxTextCtrl_GetInsertionPoint, 1832).
--define(wxTextCtrl_GetLastPosition, 1833).
--define(wxTextCtrl_GetLineLength, 1834).
--define(wxTextCtrl_GetLineText, 1835).
--define(wxTextCtrl_GetNumberOfLines, 1836).
--define(wxTextCtrl_GetRange, 1837).
--define(wxTextCtrl_GetSelection, 1838).
--define(wxTextCtrl_GetStringSelection, 1839).
--define(wxTextCtrl_GetStyle, 1840).
--define(wxTextCtrl_GetValue, 1841).
--define(wxTextCtrl_IsEditable, 1842).
--define(wxTextCtrl_IsModified, 1843).
--define(wxTextCtrl_IsMultiLine, 1844).
--define(wxTextCtrl_IsSingleLine, 1845).
--define(wxTextCtrl_LoadFile, 1846).
--define(wxTextCtrl_MarkDirty, 1847).
--define(wxTextCtrl_Paste, 1848).
--define(wxTextCtrl_PositionToXY, 1849).
--define(wxTextCtrl_Redo, 1850).
--define(wxTextCtrl_Remove, 1851).
--define(wxTextCtrl_Replace, 1852).
--define(wxTextCtrl_SaveFile, 1853).
--define(wxTextCtrl_SetDefaultStyle, 1854).
--define(wxTextCtrl_SetEditable, 1855).
--define(wxTextCtrl_SetInsertionPoint, 1856).
--define(wxTextCtrl_SetInsertionPointEnd, 1857).
--define(wxTextCtrl_SetMaxLength, 1859).
--define(wxTextCtrl_SetSelection, 1860).
--define(wxTextCtrl_SetStyle, 1861).
--define(wxTextCtrl_SetValue, 1862).
--define(wxTextCtrl_ShowPosition, 1863).
--define(wxTextCtrl_Undo, 1864).
--define(wxTextCtrl_WriteText, 1865).
--define(wxTextCtrl_XYToPosition, 1866).
--define(wxNotebook_new_0, 1869).
--define(wxNotebook_new_3, 1870).
--define(wxNotebook_destruct, 1871).
--define(wxNotebook_AddPage, 1872).
--define(wxNotebook_AdvanceSelection, 1873).
--define(wxNotebook_AssignImageList, 1874).
--define(wxNotebook_Create, 1875).
--define(wxNotebook_DeleteAllPages, 1876).
--define(wxNotebook_DeletePage, 1877).
--define(wxNotebook_RemovePage, 1878).
--define(wxNotebook_GetCurrentPage, 1879).
--define(wxNotebook_GetImageList, 1880).
--define(wxNotebook_GetPage, 1882).
--define(wxNotebook_GetPageCount, 1883).
--define(wxNotebook_GetPageImage, 1884).
--define(wxNotebook_GetPageText, 1885).
--define(wxNotebook_GetRowCount, 1886).
--define(wxNotebook_GetSelection, 1887).
--define(wxNotebook_GetThemeBackgroundColour, 1888).
--define(wxNotebook_HitTest, 1890).
--define(wxNotebook_InsertPage, 1892).
--define(wxNotebook_SetImageList, 1893).
--define(wxNotebook_SetPadding, 1894).
--define(wxNotebook_SetPageSize, 1895).
--define(wxNotebook_SetPageImage, 1896).
--define(wxNotebook_SetPageText, 1897).
--define(wxNotebook_SetSelection, 1898).
--define(wxNotebook_ChangeSelection, 1899).
--define(wxChoicebook_new_0, 1900).
--define(wxChoicebook_new_3, 1901).
--define(wxChoicebook_AddPage, 1902).
--define(wxChoicebook_AdvanceSelection, 1903).
--define(wxChoicebook_AssignImageList, 1904).
--define(wxChoicebook_Create, 1905).
--define(wxChoicebook_DeleteAllPages, 1906).
--define(wxChoicebook_DeletePage, 1907).
--define(wxChoicebook_RemovePage, 1908).
--define(wxChoicebook_GetCurrentPage, 1909).
--define(wxChoicebook_GetImageList, 1910).
--define(wxChoicebook_GetPage, 1912).
--define(wxChoicebook_GetPageCount, 1913).
--define(wxChoicebook_GetPageImage, 1914).
--define(wxChoicebook_GetPageText, 1915).
--define(wxChoicebook_GetSelection, 1916).
--define(wxChoicebook_HitTest, 1917).
--define(wxChoicebook_InsertPage, 1918).
--define(wxChoicebook_SetImageList, 1919).
--define(wxChoicebook_SetPageSize, 1920).
--define(wxChoicebook_SetPageImage, 1921).
--define(wxChoicebook_SetPageText, 1922).
--define(wxChoicebook_SetSelection, 1923).
--define(wxChoicebook_ChangeSelection, 1924).
--define(wxChoicebook_destroy, 1925).
--define(wxToolbook_new_0, 1926).
--define(wxToolbook_new_3, 1927).
--define(wxToolbook_AddPage, 1928).
--define(wxToolbook_AdvanceSelection, 1929).
--define(wxToolbook_AssignImageList, 1930).
--define(wxToolbook_Create, 1931).
--define(wxToolbook_DeleteAllPages, 1932).
--define(wxToolbook_DeletePage, 1933).
--define(wxToolbook_RemovePage, 1934).
--define(wxToolbook_GetCurrentPage, 1935).
--define(wxToolbook_GetImageList, 1936).
--define(wxToolbook_GetPage, 1938).
--define(wxToolbook_GetPageCount, 1939).
--define(wxToolbook_GetPageImage, 1940).
--define(wxToolbook_GetPageText, 1941).
--define(wxToolbook_GetSelection, 1942).
--define(wxToolbook_HitTest, 1944).
--define(wxToolbook_InsertPage, 1945).
--define(wxToolbook_SetImageList, 1946).
--define(wxToolbook_SetPageSize, 1947).
--define(wxToolbook_SetPageImage, 1948).
--define(wxToolbook_SetPageText, 1949).
--define(wxToolbook_SetSelection, 1950).
--define(wxToolbook_ChangeSelection, 1951).
--define(wxToolbook_destroy, 1952).
--define(wxListbook_new_0, 1953).
--define(wxListbook_new_3, 1954).
--define(wxListbook_AddPage, 1955).
--define(wxListbook_AdvanceSelection, 1956).
--define(wxListbook_AssignImageList, 1957).
--define(wxListbook_Create, 1958).
--define(wxListbook_DeleteAllPages, 1959).
--define(wxListbook_DeletePage, 1960).
--define(wxListbook_RemovePage, 1961).
--define(wxListbook_GetCurrentPage, 1962).
--define(wxListbook_GetImageList, 1963).
--define(wxListbook_GetPage, 1965).
--define(wxListbook_GetPageCount, 1966).
--define(wxListbook_GetPageImage, 1967).
--define(wxListbook_GetPageText, 1968).
--define(wxListbook_GetSelection, 1969).
--define(wxListbook_HitTest, 1971).
--define(wxListbook_InsertPage, 1972).
--define(wxListbook_SetImageList, 1973).
--define(wxListbook_SetPageSize, 1974).
--define(wxListbook_SetPageImage, 1975).
--define(wxListbook_SetPageText, 1976).
--define(wxListbook_SetSelection, 1977).
--define(wxListbook_ChangeSelection, 1978).
--define(wxListbook_destroy, 1979).
--define(wxTreebook_new_0, 1980).
--define(wxTreebook_new_3, 1981).
--define(wxTreebook_AddPage, 1982).
--define(wxTreebook_AdvanceSelection, 1983).
--define(wxTreebook_AssignImageList, 1984).
--define(wxTreebook_Create, 1985).
--define(wxTreebook_DeleteAllPages, 1986).
--define(wxTreebook_DeletePage, 1987).
--define(wxTreebook_RemovePage, 1988).
--define(wxTreebook_GetCurrentPage, 1989).
--define(wxTreebook_GetImageList, 1990).
--define(wxTreebook_GetPage, 1992).
--define(wxTreebook_GetPageCount, 1993).
--define(wxTreebook_GetPageImage, 1994).
--define(wxTreebook_GetPageText, 1995).
--define(wxTreebook_GetSelection, 1996).
--define(wxTreebook_ExpandNode, 1997).
--define(wxTreebook_IsNodeExpanded, 1998).
--define(wxTreebook_HitTest, 2000).
--define(wxTreebook_InsertPage, 2001).
--define(wxTreebook_InsertSubPage, 2002).
--define(wxTreebook_SetImageList, 2003).
--define(wxTreebook_SetPageSize, 2004).
--define(wxTreebook_SetPageImage, 2005).
--define(wxTreebook_SetPageText, 2006).
--define(wxTreebook_SetSelection, 2007).
--define(wxTreebook_ChangeSelection, 2008).
--define(wxTreebook_destroy, 2009).
--define(wxTreeCtrl_new_2, 2012).
--define(wxTreeCtrl_new_0, 2013).
--define(wxTreeCtrl_destruct, 2015).
--define(wxTreeCtrl_AddRoot, 2016).
--define(wxTreeCtrl_AppendItem, 2017).
--define(wxTreeCtrl_AssignImageList, 2018).
--define(wxTreeCtrl_AssignStateImageList, 2019).
--define(wxTreeCtrl_Collapse, 2020).
--define(wxTreeCtrl_CollapseAndReset, 2021).
--define(wxTreeCtrl_Create, 2022).
--define(wxTreeCtrl_Delete, 2023).
--define(wxTreeCtrl_DeleteAllItems, 2024).
--define(wxTreeCtrl_DeleteChildren, 2025).
--define(wxTreeCtrl_EditLabel, 2026).
--define(wxTreeCtrl_EnsureVisible, 2027).
--define(wxTreeCtrl_Expand, 2028).
--define(wxTreeCtrl_GetBoundingRect, 2029).
--define(wxTreeCtrl_GetChildrenCount, 2031).
--define(wxTreeCtrl_GetCount, 2032).
--define(wxTreeCtrl_GetEditControl, 2033).
--define(wxTreeCtrl_GetFirstChild, 2034).
--define(wxTreeCtrl_GetNextChild, 2035).
--define(wxTreeCtrl_GetFirstVisibleItem, 2036).
--define(wxTreeCtrl_GetImageList, 2037).
--define(wxTreeCtrl_GetIndent, 2038).
--define(wxTreeCtrl_GetItemBackgroundColour, 2039).
--define(wxTreeCtrl_GetItemData, 2040).
--define(wxTreeCtrl_GetItemFont, 2041).
--define(wxTreeCtrl_GetItemImage_1, 2042).
--define(wxTreeCtrl_GetItemImage_2, 2043).
--define(wxTreeCtrl_GetItemText, 2044).
--define(wxTreeCtrl_GetItemTextColour, 2045).
--define(wxTreeCtrl_GetLastChild, 2046).
--define(wxTreeCtrl_GetNextSibling, 2047).
--define(wxTreeCtrl_GetNextVisible, 2048).
--define(wxTreeCtrl_GetItemParent, 2049).
--define(wxTreeCtrl_GetPrevSibling, 2050).
--define(wxTreeCtrl_GetPrevVisible, 2051).
--define(wxTreeCtrl_GetRootItem, 2052).
--define(wxTreeCtrl_GetSelection, 2053).
--define(wxTreeCtrl_GetSelections, 2054).
--define(wxTreeCtrl_GetStateImageList, 2055).
--define(wxTreeCtrl_HitTest, 2056).
--define(wxTreeCtrl_InsertItem, 2058).
--define(wxTreeCtrl_IsBold, 2059).
--define(wxTreeCtrl_IsExpanded, 2060).
--define(wxTreeCtrl_IsSelected, 2061).
--define(wxTreeCtrl_IsVisible, 2062).
--define(wxTreeCtrl_ItemHasChildren, 2063).
--define(wxTreeCtrl_IsTreeItemIdOk, 2064).
--define(wxTreeCtrl_PrependItem, 2065).
--define(wxTreeCtrl_ScrollTo, 2066).
--define(wxTreeCtrl_SelectItem_1, 2067).
--define(wxTreeCtrl_SelectItem_2, 2068).
--define(wxTreeCtrl_SetIndent, 2069).
--define(wxTreeCtrl_SetImageList, 2070).
--define(wxTreeCtrl_SetItemBackgroundColour, 2071).
--define(wxTreeCtrl_SetItemBold, 2072).
--define(wxTreeCtrl_SetItemData, 2073).
--define(wxTreeCtrl_SetItemDropHighlight, 2074).
--define(wxTreeCtrl_SetItemFont, 2075).
--define(wxTreeCtrl_SetItemHasChildren, 2076).
--define(wxTreeCtrl_SetItemImage_2, 2077).
--define(wxTreeCtrl_SetItemImage_3, 2078).
--define(wxTreeCtrl_SetItemText, 2079).
--define(wxTreeCtrl_SetItemTextColour, 2080).
--define(wxTreeCtrl_SetStateImageList, 2081).
--define(wxTreeCtrl_SetWindowStyle, 2082).
--define(wxTreeCtrl_SortChildren, 2083).
--define(wxTreeCtrl_Toggle, 2084).
--define(wxTreeCtrl_ToggleItemSelection, 2085).
--define(wxTreeCtrl_Unselect, 2086).
--define(wxTreeCtrl_UnselectAll, 2087).
--define(wxTreeCtrl_UnselectItem, 2088).
--define(wxScrollBar_new_0, 2089).
--define(wxScrollBar_new_3, 2090).
--define(wxScrollBar_destruct, 2091).
--define(wxScrollBar_Create, 2092).
--define(wxScrollBar_GetRange, 2093).
--define(wxScrollBar_GetPageSize, 2094).
--define(wxScrollBar_GetThumbPosition, 2095).
--define(wxScrollBar_GetThumbSize, 2096).
--define(wxScrollBar_SetThumbPosition, 2097).
--define(wxScrollBar_SetScrollbar, 2098).
--define(wxSpinButton_new_2, 2100).
--define(wxSpinButton_new_0, 2101).
--define(wxSpinButton_Create, 2102).
--define(wxSpinButton_GetMax, 2103).
--define(wxSpinButton_GetMin, 2104).
--define(wxSpinButton_GetValue, 2105).
--define(wxSpinButton_SetRange, 2106).
--define(wxSpinButton_SetValue, 2107).
--define(wxSpinButton_destroy, 2108).
--define(wxSpinCtrl_new_0, 2109).
--define(wxSpinCtrl_new_2, 2110).
--define(wxSpinCtrl_Create, 2112).
--define(wxSpinCtrl_SetValue_1_1, 2115).
--define(wxSpinCtrl_SetValue_1_0, 2116).
--define(wxSpinCtrl_GetValue, 2118).
--define(wxSpinCtrl_SetRange, 2120).
--define(wxSpinCtrl_SetSelection, 2121).
--define(wxSpinCtrl_GetMin, 2123).
--define(wxSpinCtrl_GetMax, 2125).
--define(wxSpinCtrl_destroy, 2126).
--define(wxStaticText_new_0, 2127).
--define(wxStaticText_new_4, 2128).
--define(wxStaticText_Create, 2129).
--define(wxStaticText_GetLabel, 2130).
--define(wxStaticText_SetLabel, 2131).
--define(wxStaticText_Wrap, 2132).
--define(wxStaticText_destroy, 2133).
--define(wxStaticBitmap_new_0, 2134).
--define(wxStaticBitmap_new_4, 2135).
--define(wxStaticBitmap_Create, 2136).
--define(wxStaticBitmap_GetBitmap, 2137).
--define(wxStaticBitmap_SetBitmap, 2138).
--define(wxStaticBitmap_destroy, 2139).
--define(wxRadioBox_new, 2140).
--define(wxRadioBox_destruct, 2142).
--define(wxRadioBox_Create, 2143).
--define(wxRadioBox_Enable_2, 2144).
--define(wxRadioBox_Enable_1, 2145).
--define(wxRadioBox_GetSelection, 2146).
--define(wxRadioBox_GetString, 2147).
--define(wxRadioBox_SetSelection, 2148).
--define(wxRadioBox_Show_2, 2149).
--define(wxRadioBox_Show_1, 2150).
--define(wxRadioBox_GetColumnCount, 2151).
--define(wxRadioBox_GetItemHelpText, 2152).
--define(wxRadioBox_GetItemToolTip, 2153).
--define(wxRadioBox_GetItemFromPoint, 2155).
--define(wxRadioBox_GetRowCount, 2156).
--define(wxRadioBox_IsItemEnabled, 2157).
--define(wxRadioBox_IsItemShown, 2158).
--define(wxRadioBox_SetItemHelpText, 2159).
--define(wxRadioBox_SetItemToolTip, 2160).
--define(wxRadioButton_new_0, 2161).
--define(wxRadioButton_new_4, 2162).
--define(wxRadioButton_Create, 2163).
--define(wxRadioButton_GetValue, 2164).
--define(wxRadioButton_SetValue, 2165).
--define(wxRadioButton_destroy, 2166).
--define(wxSlider_new_6, 2168).
--define(wxSlider_new_0, 2169).
--define(wxSlider_Create, 2170).
--define(wxSlider_GetLineSize, 2171).
--define(wxSlider_GetMax, 2172).
--define(wxSlider_GetMin, 2173).
--define(wxSlider_GetPageSize, 2174).
--define(wxSlider_GetThumbLength, 2175).
--define(wxSlider_GetValue, 2176).
--define(wxSlider_SetLineSize, 2177).
--define(wxSlider_SetPageSize, 2178).
--define(wxSlider_SetRange, 2179).
--define(wxSlider_SetThumbLength, 2180).
--define(wxSlider_SetValue, 2181).
--define(wxSlider_destroy, 2182).
--define(wxDialog_new_4, 2184).
--define(wxDialog_new_0, 2185).
--define(wxDialog_destruct, 2187).
--define(wxDialog_Create, 2188).
--define(wxDialog_CreateButtonSizer, 2189).
--define(wxDialog_CreateStdDialogButtonSizer, 2190).
--define(wxDialog_EndModal, 2191).
--define(wxDialog_GetAffirmativeId, 2192).
--define(wxDialog_GetReturnCode, 2193).
--define(wxDialog_IsModal, 2194).
--define(wxDialog_SetAffirmativeId, 2195).
--define(wxDialog_SetReturnCode, 2196).
--define(wxDialog_Show, 2197).
--define(wxDialog_ShowModal, 2198).
--define(wxColourDialog_new_0, 2199).
--define(wxColourDialog_new_2, 2200).
--define(wxColourDialog_destruct, 2201).
--define(wxColourDialog_Create, 2202).
--define(wxColourDialog_GetColourData, 2203).
--define(wxColourData_new_0, 2204).
--define(wxColourData_new_1, 2205).
--define(wxColourData_destruct, 2206).
--define(wxColourData_GetChooseFull, 2207).
--define(wxColourData_GetColour, 2208).
--define(wxColourData_GetCustomColour, 2210).
--define(wxColourData_SetChooseFull, 2211).
--define(wxColourData_SetColour, 2212).
--define(wxColourData_SetCustomColour, 2213).
--define(wxPalette_new_0, 2214).
--define(wxPalette_new_4, 2215).
--define(wxPalette_destruct, 2217).
--define(wxPalette_Create, 2218).
--define(wxPalette_GetColoursCount, 2219).
--define(wxPalette_GetPixel, 2220).
--define(wxPalette_GetRGB, 2221).
--define(wxPalette_IsOk, 2222).
--define(wxDirDialog_new, 2226).
--define(wxDirDialog_destruct, 2227).
--define(wxDirDialog_GetPath, 2228).
--define(wxDirDialog_GetMessage, 2229).
--define(wxDirDialog_SetMessage, 2230).
--define(wxDirDialog_SetPath, 2231).
--define(wxFileDialog_new, 2235).
--define(wxFileDialog_destruct, 2236).
--define(wxFileDialog_GetDirectory, 2237).
--define(wxFileDialog_GetFilename, 2238).
--define(wxFileDialog_GetFilenames, 2239).
--define(wxFileDialog_GetFilterIndex, 2240).
--define(wxFileDialog_GetMessage, 2241).
--define(wxFileDialog_GetPath, 2242).
--define(wxFileDialog_GetPaths, 2243).
--define(wxFileDialog_GetWildcard, 2244).
--define(wxFileDialog_SetDirectory, 2245).
--define(wxFileDialog_SetFilename, 2246).
--define(wxFileDialog_SetFilterIndex, 2247).
--define(wxFileDialog_SetMessage, 2248).
--define(wxFileDialog_SetPath, 2249).
--define(wxFileDialog_SetWildcard, 2250).
--define(wxPickerBase_SetInternalMargin, 2251).
--define(wxPickerBase_GetInternalMargin, 2252).
--define(wxPickerBase_SetTextCtrlProportion, 2253).
--define(wxPickerBase_SetPickerCtrlProportion, 2254).
--define(wxPickerBase_GetTextCtrlProportion, 2255).
--define(wxPickerBase_GetPickerCtrlProportion, 2256).
--define(wxPickerBase_HasTextCtrl, 2257).
--define(wxPickerBase_GetTextCtrl, 2258).
--define(wxPickerBase_IsTextCtrlGrowable, 2259).
--define(wxPickerBase_SetPickerCtrlGrowable, 2260).
--define(wxPickerBase_SetTextCtrlGrowable, 2261).
--define(wxPickerBase_IsPickerCtrlGrowable, 2262).
--define(wxFilePickerCtrl_new_0, 2263).
--define(wxFilePickerCtrl_new_3, 2264).
--define(wxFilePickerCtrl_Create, 2265).
--define(wxFilePickerCtrl_GetPath, 2266).
--define(wxFilePickerCtrl_SetPath, 2267).
--define(wxFilePickerCtrl_destroy, 2268).
--define(wxDirPickerCtrl_new_0, 2269).
--define(wxDirPickerCtrl_new_3, 2270).
--define(wxDirPickerCtrl_Create, 2271).
--define(wxDirPickerCtrl_GetPath, 2272).
--define(wxDirPickerCtrl_SetPath, 2273).
--define(wxDirPickerCtrl_destroy, 2274).
--define(wxColourPickerCtrl_new_0, 2275).
--define(wxColourPickerCtrl_new_3, 2276).
--define(wxColourPickerCtrl_Create, 2277).
--define(wxColourPickerCtrl_GetColour, 2278).
--define(wxColourPickerCtrl_SetColour_1_1, 2279).
--define(wxColourPickerCtrl_SetColour_1_0, 2280).
--define(wxColourPickerCtrl_destroy, 2281).
--define(wxDatePickerCtrl_new_0, 2282).
--define(wxDatePickerCtrl_new_3, 2283).
--define(wxDatePickerCtrl_GetRange, 2284).
--define(wxDatePickerCtrl_GetValue, 2285).
--define(wxDatePickerCtrl_SetRange, 2286).
--define(wxDatePickerCtrl_SetValue, 2287).
--define(wxDatePickerCtrl_destroy, 2288).
--define(wxFontPickerCtrl_new_0, 2289).
--define(wxFontPickerCtrl_new_3, 2290).
--define(wxFontPickerCtrl_Create, 2291).
--define(wxFontPickerCtrl_GetSelectedFont, 2292).
--define(wxFontPickerCtrl_SetSelectedFont, 2293).
--define(wxFontPickerCtrl_GetMaxPointSize, 2294).
--define(wxFontPickerCtrl_SetMaxPointSize, 2295).
--define(wxFontPickerCtrl_destroy, 2296).
--define(wxFindReplaceDialog_new_0, 2299).
--define(wxFindReplaceDialog_new_4, 2300).
--define(wxFindReplaceDialog_destruct, 2301).
--define(wxFindReplaceDialog_Create, 2302).
--define(wxFindReplaceDialog_GetData, 2303).
--define(wxFindReplaceData_new_0, 2304).
--define(wxFindReplaceData_new_1, 2305).
--define(wxFindReplaceData_GetFindString, 2306).
--define(wxFindReplaceData_GetReplaceString, 2307).
--define(wxFindReplaceData_GetFlags, 2308).
--define(wxFindReplaceData_SetFlags, 2309).
--define(wxFindReplaceData_SetFindString, 2310).
--define(wxFindReplaceData_SetReplaceString, 2311).
--define(wxFindReplaceData_destroy, 2312).
--define(wxMultiChoiceDialog_new_0, 2313).
--define(wxMultiChoiceDialog_new_5, 2315).
--define(wxMultiChoiceDialog_GetSelections, 2316).
--define(wxMultiChoiceDialog_SetSelections, 2317).
--define(wxMultiChoiceDialog_destroy, 2318).
--define(wxSingleChoiceDialog_new_0, 2319).
--define(wxSingleChoiceDialog_new_5, 2321).
--define(wxSingleChoiceDialog_GetSelection, 2322).
--define(wxSingleChoiceDialog_GetStringSelection, 2323).
--define(wxSingleChoiceDialog_SetSelection, 2324).
--define(wxSingleChoiceDialog_destroy, 2325).
--define(wxTextEntryDialog_new, 2326).
--define(wxTextEntryDialog_GetValue, 2327).
--define(wxTextEntryDialog_SetValue, 2328).
--define(wxTextEntryDialog_destroy, 2329).
--define(wxPasswordEntryDialog_new, 2330).
--define(wxPasswordEntryDialog_destroy, 2331).
--define(wxFontData_new_0, 2332).
--define(wxFontData_new_1, 2333).
--define(wxFontData_destruct, 2334).
--define(wxFontData_EnableEffects, 2335).
--define(wxFontData_GetAllowSymbols, 2336).
--define(wxFontData_GetColour, 2337).
--define(wxFontData_GetChosenFont, 2338).
--define(wxFontData_GetEnableEffects, 2339).
--define(wxFontData_GetInitialFont, 2340).
--define(wxFontData_GetShowHelp, 2341).
--define(wxFontData_SetAllowSymbols, 2342).
--define(wxFontData_SetChosenFont, 2343).
--define(wxFontData_SetColour, 2344).
--define(wxFontData_SetInitialFont, 2345).
--define(wxFontData_SetRange, 2346).
--define(wxFontData_SetShowHelp, 2347).
--define(wxFontDialog_new_0, 2351).
--define(wxFontDialog_new_2, 2353).
--define(wxFontDialog_Create, 2355).
--define(wxFontDialog_GetFontData, 2356).
--define(wxFontDialog_destroy, 2358).
--define(wxProgressDialog_new, 2359).
--define(wxProgressDialog_destruct, 2360).
--define(wxProgressDialog_Resume, 2361).
--define(wxProgressDialog_Update_2, 2362).
--define(wxProgressDialog_Update_0, 2363).
--define(wxMessageDialog_new, 2364).
--define(wxMessageDialog_destruct, 2365).
--define(wxPageSetupDialog_new, 2366).
--define(wxPageSetupDialog_destruct, 2367).
--define(wxPageSetupDialog_GetPageSetupData, 2368).
--define(wxPageSetupDialog_ShowModal, 2369).
--define(wxPageSetupDialogData_new_0, 2370).
--define(wxPageSetupDialogData_new_1_0, 2371).
--define(wxPageSetupDialogData_new_1_1, 2372).
--define(wxPageSetupDialogData_destruct, 2373).
--define(wxPageSetupDialogData_EnableHelp, 2374).
--define(wxPageSetupDialogData_EnableMargins, 2375).
--define(wxPageSetupDialogData_EnableOrientation, 2376).
--define(wxPageSetupDialogData_EnablePaper, 2377).
--define(wxPageSetupDialogData_EnablePrinter, 2378).
--define(wxPageSetupDialogData_GetDefaultMinMargins, 2379).
--define(wxPageSetupDialogData_GetEnableMargins, 2380).
--define(wxPageSetupDialogData_GetEnableOrientation, 2381).
--define(wxPageSetupDialogData_GetEnablePaper, 2382).
--define(wxPageSetupDialogData_GetEnablePrinter, 2383).
--define(wxPageSetupDialogData_GetEnableHelp, 2384).
--define(wxPageSetupDialogData_GetDefaultInfo, 2385).
--define(wxPageSetupDialogData_GetMarginTopLeft, 2386).
--define(wxPageSetupDialogData_GetMarginBottomRight, 2387).
--define(wxPageSetupDialogData_GetMinMarginTopLeft, 2388).
--define(wxPageSetupDialogData_GetMinMarginBottomRight, 2389).
--define(wxPageSetupDialogData_GetPaperId, 2390).
--define(wxPageSetupDialogData_GetPaperSize, 2391).
--define(wxPageSetupDialogData_GetPrintData, 2393).
--define(wxPageSetupDialogData_IsOk, 2394).
--define(wxPageSetupDialogData_SetDefaultInfo, 2395).
--define(wxPageSetupDialogData_SetDefaultMinMargins, 2396).
--define(wxPageSetupDialogData_SetMarginTopLeft, 2397).
--define(wxPageSetupDialogData_SetMarginBottomRight, 2398).
--define(wxPageSetupDialogData_SetMinMarginTopLeft, 2399).
--define(wxPageSetupDialogData_SetMinMarginBottomRight, 2400).
--define(wxPageSetupDialogData_SetPaperId, 2401).
--define(wxPageSetupDialogData_SetPaperSize_1_1, 2402).
--define(wxPageSetupDialogData_SetPaperSize_1_0, 2403).
--define(wxPageSetupDialogData_SetPrintData, 2404).
--define(wxPrintDialog_new_2_0, 2405).
--define(wxPrintDialog_new_2_1, 2406).
--define(wxPrintDialog_destruct, 2407).
--define(wxPrintDialog_GetPrintDialogData, 2408).
--define(wxPrintDialog_GetPrintDC, 2409).
--define(wxPrintDialogData_new_0, 2410).
--define(wxPrintDialogData_new_1_1, 2411).
--define(wxPrintDialogData_new_1_0, 2412).
--define(wxPrintDialogData_destruct, 2413).
--define(wxPrintDialogData_EnableHelp, 2414).
--define(wxPrintDialogData_EnablePageNumbers, 2415).
--define(wxPrintDialogData_EnablePrintToFile, 2416).
--define(wxPrintDialogData_EnableSelection, 2417).
--define(wxPrintDialogData_GetAllPages, 2418).
--define(wxPrintDialogData_GetCollate, 2419).
--define(wxPrintDialogData_GetFromPage, 2420).
--define(wxPrintDialogData_GetMaxPage, 2421).
--define(wxPrintDialogData_GetMinPage, 2422).
--define(wxPrintDialogData_GetNoCopies, 2423).
--define(wxPrintDialogData_GetPrintData, 2424).
--define(wxPrintDialogData_GetPrintToFile, 2425).
--define(wxPrintDialogData_GetSelection, 2426).
--define(wxPrintDialogData_GetToPage, 2427).
--define(wxPrintDialogData_IsOk, 2428).
--define(wxPrintDialogData_SetCollate, 2429).
--define(wxPrintDialogData_SetFromPage, 2430).
--define(wxPrintDialogData_SetMaxPage, 2431).
--define(wxPrintDialogData_SetMinPage, 2432).
--define(wxPrintDialogData_SetNoCopies, 2433).
--define(wxPrintDialogData_SetPrintData, 2434).
--define(wxPrintDialogData_SetPrintToFile, 2435).
--define(wxPrintDialogData_SetSelection, 2436).
--define(wxPrintDialogData_SetToPage, 2437).
--define(wxPrintData_new_0, 2438).
--define(wxPrintData_new_1, 2439).
--define(wxPrintData_destruct, 2440).
--define(wxPrintData_GetCollate, 2441).
--define(wxPrintData_GetBin, 2442).
--define(wxPrintData_GetColour, 2443).
--define(wxPrintData_GetDuplex, 2444).
--define(wxPrintData_GetNoCopies, 2445).
--define(wxPrintData_GetOrientation, 2446).
--define(wxPrintData_GetPaperId, 2447).
--define(wxPrintData_GetPrinterName, 2448).
--define(wxPrintData_GetQuality, 2449).
--define(wxPrintData_IsOk, 2450).
--define(wxPrintData_SetBin, 2451).
--define(wxPrintData_SetCollate, 2452).
--define(wxPrintData_SetColour, 2453).
--define(wxPrintData_SetDuplex, 2454).
--define(wxPrintData_SetNoCopies, 2455).
--define(wxPrintData_SetOrientation, 2456).
--define(wxPrintData_SetPaperId, 2457).
--define(wxPrintData_SetPrinterName, 2458).
--define(wxPrintData_SetQuality, 2459).
--define(wxPrintPreview_new_2, 2462).
--define(wxPrintPreview_new_3, 2463).
--define(wxPrintPreview_destruct, 2465).
--define(wxPrintPreview_GetCanvas, 2466).
--define(wxPrintPreview_GetCurrentPage, 2467).
--define(wxPrintPreview_GetFrame, 2468).
--define(wxPrintPreview_GetMaxPage, 2469).
--define(wxPrintPreview_GetMinPage, 2470).
--define(wxPrintPreview_GetPrintout, 2471).
--define(wxPrintPreview_GetPrintoutForPrinting, 2472).
--define(wxPrintPreview_IsOk, 2473).
--define(wxPrintPreview_PaintPage, 2474).
--define(wxPrintPreview_Print, 2475).
--define(wxPrintPreview_RenderPage, 2476).
--define(wxPrintPreview_SetCanvas, 2477).
--define(wxPrintPreview_SetCurrentPage, 2478).
--define(wxPrintPreview_SetFrame, 2479).
--define(wxPrintPreview_SetPrintout, 2480).
--define(wxPrintPreview_SetZoom, 2481).
--define(wxPreviewFrame_new, 2482).
--define(wxPreviewFrame_destruct, 2483).
--define(wxPreviewFrame_CreateControlBar, 2484).
--define(wxPreviewFrame_CreateCanvas, 2485).
--define(wxPreviewFrame_Initialize, 2486).
--define(wxPreviewFrame_OnCloseWindow, 2487).
--define(wxPreviewControlBar_new, 2488).
--define(wxPreviewControlBar_destruct, 2489).
--define(wxPreviewControlBar_CreateButtons, 2490).
--define(wxPreviewControlBar_GetPrintPreview, 2491).
--define(wxPreviewControlBar_GetZoomControl, 2492).
--define(wxPreviewControlBar_SetZoomControl, 2493).
--define(wxPrinter_new, 2495).
--define(wxPrinter_CreateAbortWindow, 2496).
--define(wxPrinter_GetAbort, 2497).
--define(wxPrinter_GetLastError, 2498).
--define(wxPrinter_GetPrintDialogData, 2499).
--define(wxPrinter_Print, 2500).
--define(wxPrinter_PrintDialog, 2501).
--define(wxPrinter_ReportError, 2502).
--define(wxPrinter_Setup, 2503).
--define(wxPrinter_destroy, 2504).
--define(wxXmlResource_new_1, 2505).
--define(wxXmlResource_new_2, 2506).
--define(wxXmlResource_destruct, 2507).
--define(wxXmlResource_AttachUnknownControl, 2508).
--define(wxXmlResource_ClearHandlers, 2509).
--define(wxXmlResource_CompareVersion, 2510).
--define(wxXmlResource_Get, 2511).
--define(wxXmlResource_GetFlags, 2512).
--define(wxXmlResource_GetVersion, 2513).
--define(wxXmlResource_GetXRCID, 2514).
--define(wxXmlResource_InitAllHandlers, 2515).
--define(wxXmlResource_Load, 2516).
--define(wxXmlResource_LoadBitmap, 2517).
--define(wxXmlResource_LoadDialog_2, 2518).
--define(wxXmlResource_LoadDialog_3, 2519).
--define(wxXmlResource_LoadFrame_2, 2520).
--define(wxXmlResource_LoadFrame_3, 2521).
--define(wxXmlResource_LoadIcon, 2522).
--define(wxXmlResource_LoadMenu, 2523).
--define(wxXmlResource_LoadMenuBar_2, 2524).
--define(wxXmlResource_LoadMenuBar_1, 2525).
--define(wxXmlResource_LoadPanel_2, 2526).
--define(wxXmlResource_LoadPanel_3, 2527).
--define(wxXmlResource_LoadToolBar, 2528).
--define(wxXmlResource_Set, 2529).
--define(wxXmlResource_SetFlags, 2530).
--define(wxXmlResource_Unload, 2531).
--define(wxXmlResource_xrcctrl, 2532).
--define(wxHtmlEasyPrinting_new, 2533).
--define(wxHtmlEasyPrinting_destruct, 2534).
--define(wxHtmlEasyPrinting_GetPrintData, 2535).
--define(wxHtmlEasyPrinting_GetPageSetupData, 2536).
--define(wxHtmlEasyPrinting_PreviewFile, 2537).
--define(wxHtmlEasyPrinting_PreviewText, 2538).
--define(wxHtmlEasyPrinting_PrintFile, 2539).
--define(wxHtmlEasyPrinting_PrintText, 2540).
--define(wxHtmlEasyPrinting_PageSetup, 2541).
--define(wxHtmlEasyPrinting_SetFonts, 2542).
--define(wxHtmlEasyPrinting_SetHeader, 2543).
--define(wxHtmlEasyPrinting_SetFooter, 2544).
--define(wxGLCanvas_new_2, 2546).
--define(wxGLCanvas_new_3_1, 2547).
--define(wxGLCanvas_new_3_0, 2548).
--define(wxGLCanvas_GetContext, 2549).
--define(wxGLCanvas_SetCurrent, 2551).
--define(wxGLCanvas_SwapBuffers, 2552).
--define(wxGLCanvas_destroy, 2553).
--define(wxAuiManager_new, 2554).
--define(wxAuiManager_destruct, 2555).
--define(wxAuiManager_AddPane_2_1, 2556).
--define(wxAuiManager_AddPane_3, 2557).
--define(wxAuiManager_AddPane_2_0, 2558).
--define(wxAuiManager_DetachPane, 2559).
--define(wxAuiManager_GetAllPanes, 2560).
--define(wxAuiManager_GetArtProvider, 2561).
--define(wxAuiManager_GetDockSizeConstraint, 2562).
--define(wxAuiManager_GetFlags, 2563).
--define(wxAuiManager_GetManagedWindow, 2564).
--define(wxAuiManager_GetManager, 2565).
--define(wxAuiManager_GetPane_1_1, 2566).
--define(wxAuiManager_GetPane_1_0, 2567).
--define(wxAuiManager_HideHint, 2568).
--define(wxAuiManager_InsertPane, 2569).
--define(wxAuiManager_LoadPaneInfo, 2570).
--define(wxAuiManager_LoadPerspective, 2571).
--define(wxAuiManager_SavePaneInfo, 2572).
--define(wxAuiManager_SavePerspective, 2573).
--define(wxAuiManager_SetArtProvider, 2574).
--define(wxAuiManager_SetDockSizeConstraint, 2575).
--define(wxAuiManager_SetFlags, 2576).
--define(wxAuiManager_SetManagedWindow, 2577).
--define(wxAuiManager_ShowHint, 2578).
--define(wxAuiManager_UnInit, 2579).
--define(wxAuiManager_Update, 2580).
--define(wxAuiPaneInfo_new_0, 2581).
--define(wxAuiPaneInfo_new_1, 2582).
--define(wxAuiPaneInfo_destruct, 2583).
--define(wxAuiPaneInfo_BestSize_1, 2584).
--define(wxAuiPaneInfo_BestSize_2, 2585).
--define(wxAuiPaneInfo_Bottom, 2586).
--define(wxAuiPaneInfo_BottomDockable, 2587).
--define(wxAuiPaneInfo_Caption, 2588).
--define(wxAuiPaneInfo_CaptionVisible, 2589).
--define(wxAuiPaneInfo_Centre, 2590).
--define(wxAuiPaneInfo_CentrePane, 2591).
--define(wxAuiPaneInfo_CloseButton, 2592).
--define(wxAuiPaneInfo_DefaultPane, 2593).
--define(wxAuiPaneInfo_DestroyOnClose, 2594).
--define(wxAuiPaneInfo_Direction, 2595).
--define(wxAuiPaneInfo_Dock, 2596).
--define(wxAuiPaneInfo_Dockable, 2597).
--define(wxAuiPaneInfo_Fixed, 2598).
--define(wxAuiPaneInfo_Float, 2599).
--define(wxAuiPaneInfo_Floatable, 2600).
--define(wxAuiPaneInfo_FloatingPosition_1, 2601).
--define(wxAuiPaneInfo_FloatingPosition_2, 2602).
--define(wxAuiPaneInfo_FloatingSize_1, 2603).
--define(wxAuiPaneInfo_FloatingSize_2, 2604).
--define(wxAuiPaneInfo_Gripper, 2605).
--define(wxAuiPaneInfo_GripperTop, 2606).
--define(wxAuiPaneInfo_HasBorder, 2607).
--define(wxAuiPaneInfo_HasCaption, 2608).
--define(wxAuiPaneInfo_HasCloseButton, 2609).
--define(wxAuiPaneInfo_HasFlag, 2610).
--define(wxAuiPaneInfo_HasGripper, 2611).
--define(wxAuiPaneInfo_HasGripperTop, 2612).
--define(wxAuiPaneInfo_HasMaximizeButton, 2613).
--define(wxAuiPaneInfo_HasMinimizeButton, 2614).
--define(wxAuiPaneInfo_HasPinButton, 2615).
--define(wxAuiPaneInfo_Hide, 2616).
--define(wxAuiPaneInfo_IsBottomDockable, 2617).
--define(wxAuiPaneInfo_IsDocked, 2618).
--define(wxAuiPaneInfo_IsFixed, 2619).
--define(wxAuiPaneInfo_IsFloatable, 2620).
--define(wxAuiPaneInfo_IsFloating, 2621).
--define(wxAuiPaneInfo_IsLeftDockable, 2622).
--define(wxAuiPaneInfo_IsMovable, 2623).
--define(wxAuiPaneInfo_IsOk, 2624).
--define(wxAuiPaneInfo_IsResizable, 2625).
--define(wxAuiPaneInfo_IsRightDockable, 2626).
--define(wxAuiPaneInfo_IsShown, 2627).
--define(wxAuiPaneInfo_IsToolbar, 2628).
--define(wxAuiPaneInfo_IsTopDockable, 2629).
--define(wxAuiPaneInfo_Layer, 2630).
--define(wxAuiPaneInfo_Left, 2631).
--define(wxAuiPaneInfo_LeftDockable, 2632).
--define(wxAuiPaneInfo_MaxSize_1, 2633).
--define(wxAuiPaneInfo_MaxSize_2, 2634).
--define(wxAuiPaneInfo_MaximizeButton, 2635).
--define(wxAuiPaneInfo_MinSize_1, 2636).
--define(wxAuiPaneInfo_MinSize_2, 2637).
--define(wxAuiPaneInfo_MinimizeButton, 2638).
--define(wxAuiPaneInfo_Movable, 2639).
--define(wxAuiPaneInfo_Name, 2640).
--define(wxAuiPaneInfo_PaneBorder, 2641).
--define(wxAuiPaneInfo_PinButton, 2642).
--define(wxAuiPaneInfo_Position, 2643).
--define(wxAuiPaneInfo_Resizable, 2644).
--define(wxAuiPaneInfo_Right, 2645).
--define(wxAuiPaneInfo_RightDockable, 2646).
--define(wxAuiPaneInfo_Row, 2647).
--define(wxAuiPaneInfo_SafeSet, 2648).
--define(wxAuiPaneInfo_SetFlag, 2649).
--define(wxAuiPaneInfo_Show, 2650).
--define(wxAuiPaneInfo_ToolbarPane, 2651).
--define(wxAuiPaneInfo_Top, 2652).
--define(wxAuiPaneInfo_TopDockable, 2653).
--define(wxAuiPaneInfo_Window, 2654).
--define(wxAuiPaneInfo_GetWindow, 2655).
--define(wxAuiPaneInfo_GetFrame, 2656).
--define(wxAuiPaneInfo_GetDirection, 2657).
--define(wxAuiPaneInfo_GetLayer, 2658).
--define(wxAuiPaneInfo_GetRow, 2659).
--define(wxAuiPaneInfo_GetPosition, 2660).
--define(wxAuiPaneInfo_GetFloatingPosition, 2661).
--define(wxAuiPaneInfo_GetFloatingSize, 2662).
--define(wxAuiNotebook_new_0, 2663).
--define(wxAuiNotebook_new_2, 2664).
--define(wxAuiNotebook_AddPage, 2665).
--define(wxAuiNotebook_Create, 2666).
--define(wxAuiNotebook_DeletePage, 2667).
--define(wxAuiNotebook_GetArtProvider, 2668).
--define(wxAuiNotebook_GetPage, 2669).
--define(wxAuiNotebook_GetPageBitmap, 2670).
--define(wxAuiNotebook_GetPageCount, 2671).
--define(wxAuiNotebook_GetPageIndex, 2672).
--define(wxAuiNotebook_GetPageText, 2673).
--define(wxAuiNotebook_GetSelection, 2674).
--define(wxAuiNotebook_InsertPage, 2675).
--define(wxAuiNotebook_RemovePage, 2676).
--define(wxAuiNotebook_SetArtProvider, 2677).
--define(wxAuiNotebook_SetFont, 2678).
--define(wxAuiNotebook_SetPageBitmap, 2679).
--define(wxAuiNotebook_SetPageText, 2680).
--define(wxAuiNotebook_SetSelection, 2681).
--define(wxAuiNotebook_SetTabCtrlHeight, 2682).
--define(wxAuiNotebook_SetUniformBitmapSize, 2683).
--define(wxAuiNotebook_destroy, 2684).
--define(wxAuiTabArt_SetFlags, 2685).
--define(wxAuiTabArt_SetMeasuringFont, 2686).
--define(wxAuiTabArt_SetNormalFont, 2687).
--define(wxAuiTabArt_SetSelectedFont, 2688).
--define(wxAuiTabArt_SetColour, 2689).
--define(wxAuiTabArt_SetActiveColour, 2690).
--define(wxAuiDockArt_GetColour, 2691).
--define(wxAuiDockArt_GetFont, 2692).
--define(wxAuiDockArt_GetMetric, 2693).
--define(wxAuiDockArt_SetColour, 2694).
--define(wxAuiDockArt_SetFont, 2695).
--define(wxAuiDockArt_SetMetric, 2696).
--define(wxAuiSimpleTabArt_new, 2697).
--define(wxAuiSimpleTabArt_destroy, 2698).
--define(wxMDIParentFrame_new_0, 2699).
--define(wxMDIParentFrame_new_4, 2700).
--define(wxMDIParentFrame_destruct, 2701).
--define(wxMDIParentFrame_ActivateNext, 2702).
--define(wxMDIParentFrame_ActivatePrevious, 2703).
--define(wxMDIParentFrame_ArrangeIcons, 2704).
--define(wxMDIParentFrame_Cascade, 2705).
--define(wxMDIParentFrame_Create, 2706).
--define(wxMDIParentFrame_GetActiveChild, 2707).
--define(wxMDIParentFrame_GetClientWindow, 2708).
--define(wxMDIParentFrame_Tile, 2709).
--define(wxMDIChildFrame_new_0, 2710).
--define(wxMDIChildFrame_new_4, 2711).
--define(wxMDIChildFrame_destruct, 2712).
--define(wxMDIChildFrame_Activate, 2713).
--define(wxMDIChildFrame_Create, 2714).
--define(wxMDIChildFrame_Maximize, 2715).
--define(wxMDIChildFrame_Restore, 2716).
--define(wxMDIClientWindow_new_0, 2717).
--define(wxMDIClientWindow_new_2, 2718).
--define(wxMDIClientWindow_destruct, 2719).
--define(wxMDIClientWindow_CreateClient, 2720).
--define(wxLayoutAlgorithm_new, 2721).
--define(wxLayoutAlgorithm_LayoutFrame, 2722).
--define(wxLayoutAlgorithm_LayoutMDIFrame, 2723).
--define(wxLayoutAlgorithm_LayoutWindow, 2724).
--define(wxLayoutAlgorithm_destroy, 2725).
--define(wxEvent_GetId, 2726).
--define(wxEvent_GetSkipped, 2727).
--define(wxEvent_GetTimestamp, 2728).
--define(wxEvent_IsCommandEvent, 2729).
--define(wxEvent_ResumePropagation, 2730).
--define(wxEvent_ShouldPropagate, 2731).
--define(wxEvent_Skip, 2732).
--define(wxEvent_StopPropagation, 2733).
--define(wxCommandEvent_getClientData, 2734).
--define(wxCommandEvent_GetExtraLong, 2735).
--define(wxCommandEvent_GetInt, 2736).
--define(wxCommandEvent_GetSelection, 2737).
--define(wxCommandEvent_GetString, 2738).
--define(wxCommandEvent_IsChecked, 2739).
--define(wxCommandEvent_IsSelection, 2740).
--define(wxCommandEvent_SetInt, 2741).
--define(wxCommandEvent_SetString, 2742).
--define(wxScrollEvent_GetOrientation, 2743).
--define(wxScrollEvent_GetPosition, 2744).
--define(wxScrollWinEvent_GetOrientation, 2745).
--define(wxScrollWinEvent_GetPosition, 2746).
--define(wxMouseEvent_AltDown, 2747).
--define(wxMouseEvent_Button, 2748).
--define(wxMouseEvent_ButtonDClick, 2749).
--define(wxMouseEvent_ButtonDown, 2750).
--define(wxMouseEvent_ButtonUp, 2751).
--define(wxMouseEvent_CmdDown, 2752).
--define(wxMouseEvent_ControlDown, 2753).
--define(wxMouseEvent_Dragging, 2754).
--define(wxMouseEvent_Entering, 2755).
--define(wxMouseEvent_GetButton, 2756).
--define(wxMouseEvent_GetPosition, 2759).
--define(wxMouseEvent_GetLogicalPosition, 2760).
--define(wxMouseEvent_GetLinesPerAction, 2761).
--define(wxMouseEvent_GetWheelRotation, 2762).
--define(wxMouseEvent_GetWheelDelta, 2763).
--define(wxMouseEvent_GetX, 2764).
--define(wxMouseEvent_GetY, 2765).
--define(wxMouseEvent_IsButton, 2766).
--define(wxMouseEvent_IsPageScroll, 2767).
--define(wxMouseEvent_Leaving, 2768).
--define(wxMouseEvent_LeftDClick, 2769).
--define(wxMouseEvent_LeftDown, 2770).
--define(wxMouseEvent_LeftIsDown, 2771).
--define(wxMouseEvent_LeftUp, 2772).
--define(wxMouseEvent_MetaDown, 2773).
--define(wxMouseEvent_MiddleDClick, 2774).
--define(wxMouseEvent_MiddleDown, 2775).
--define(wxMouseEvent_MiddleIsDown, 2776).
--define(wxMouseEvent_MiddleUp, 2777).
--define(wxMouseEvent_Moving, 2778).
--define(wxMouseEvent_RightDClick, 2779).
--define(wxMouseEvent_RightDown, 2780).
--define(wxMouseEvent_RightIsDown, 2781).
--define(wxMouseEvent_RightUp, 2782).
--define(wxMouseEvent_ShiftDown, 2783).
--define(wxSetCursorEvent_GetCursor, 2784).
--define(wxSetCursorEvent_GetX, 2785).
--define(wxSetCursorEvent_GetY, 2786).
--define(wxSetCursorEvent_HasCursor, 2787).
--define(wxSetCursorEvent_SetCursor, 2788).
--define(wxKeyEvent_AltDown, 2789).
--define(wxKeyEvent_CmdDown, 2790).
--define(wxKeyEvent_ControlDown, 2791).
--define(wxKeyEvent_GetKeyCode, 2792).
--define(wxKeyEvent_GetModifiers, 2793).
--define(wxKeyEvent_GetPosition, 2796).
--define(wxKeyEvent_GetRawKeyCode, 2797).
--define(wxKeyEvent_GetRawKeyFlags, 2798).
--define(wxKeyEvent_GetUnicodeKey, 2799).
--define(wxKeyEvent_GetX, 2800).
--define(wxKeyEvent_GetY, 2801).
--define(wxKeyEvent_HasModifiers, 2802).
--define(wxKeyEvent_MetaDown, 2803).
--define(wxKeyEvent_ShiftDown, 2804).
--define(wxSizeEvent_GetSize, 2805).
--define(wxMoveEvent_GetPosition, 2806).
--define(wxEraseEvent_GetDC, 2807).
--define(wxFocusEvent_GetWindow, 2808).
--define(wxChildFocusEvent_GetWindow, 2809).
--define(wxMenuEvent_GetMenu, 2810).
--define(wxMenuEvent_GetMenuId, 2811).
--define(wxMenuEvent_IsPopup, 2812).
--define(wxCloseEvent_CanVeto, 2813).
--define(wxCloseEvent_GetLoggingOff, 2814).
--define(wxCloseEvent_SetCanVeto, 2815).
--define(wxCloseEvent_SetLoggingOff, 2816).
--define(wxCloseEvent_Veto, 2817).
--define(wxShowEvent_SetShow, 2818).
--define(wxShowEvent_GetShow, 2819).
--define(wxIconizeEvent_Iconized, 2820).
--define(wxJoystickEvent_ButtonDown, 2821).
--define(wxJoystickEvent_ButtonIsDown, 2822).
--define(wxJoystickEvent_ButtonUp, 2823).
--define(wxJoystickEvent_GetButtonChange, 2824).
--define(wxJoystickEvent_GetButtonState, 2825).
--define(wxJoystickEvent_GetJoystick, 2826).
--define(wxJoystickEvent_GetPosition, 2827).
--define(wxJoystickEvent_GetZPosition, 2828).
--define(wxJoystickEvent_IsButton, 2829).
--define(wxJoystickEvent_IsMove, 2830).
--define(wxJoystickEvent_IsZMove, 2831).
--define(wxUpdateUIEvent_CanUpdate, 2832).
--define(wxUpdateUIEvent_Check, 2833).
--define(wxUpdateUIEvent_Enable, 2834).
--define(wxUpdateUIEvent_Show, 2835).
--define(wxUpdateUIEvent_GetChecked, 2836).
--define(wxUpdateUIEvent_GetEnabled, 2837).
--define(wxUpdateUIEvent_GetShown, 2838).
--define(wxUpdateUIEvent_GetSetChecked, 2839).
--define(wxUpdateUIEvent_GetSetEnabled, 2840).
--define(wxUpdateUIEvent_GetSetShown, 2841).
--define(wxUpdateUIEvent_GetSetText, 2842).
--define(wxUpdateUIEvent_GetText, 2843).
--define(wxUpdateUIEvent_GetMode, 2844).
--define(wxUpdateUIEvent_GetUpdateInterval, 2845).
--define(wxUpdateUIEvent_ResetUpdateTime, 2846).
--define(wxUpdateUIEvent_SetMode, 2847).
--define(wxUpdateUIEvent_SetText, 2848).
--define(wxUpdateUIEvent_SetUpdateInterval, 2849).
--define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2850).
--define(wxPaletteChangedEvent_SetChangedWindow, 2851).
--define(wxPaletteChangedEvent_GetChangedWindow, 2852).
--define(wxQueryNewPaletteEvent_SetPaletteRealized, 2853).
--define(wxQueryNewPaletteEvent_GetPaletteRealized, 2854).
--define(wxNavigationKeyEvent_GetDirection, 2855).
--define(wxNavigationKeyEvent_SetDirection, 2856).
--define(wxNavigationKeyEvent_IsWindowChange, 2857).
--define(wxNavigationKeyEvent_SetWindowChange, 2858).
--define(wxNavigationKeyEvent_IsFromTab, 2859).
--define(wxNavigationKeyEvent_SetFromTab, 2860).
--define(wxNavigationKeyEvent_GetCurrentFocus, 2861).
--define(wxNavigationKeyEvent_SetCurrentFocus, 2862).
--define(wxHelpEvent_GetOrigin, 2863).
--define(wxHelpEvent_GetPosition, 2864).
--define(wxHelpEvent_SetOrigin, 2865).
--define(wxHelpEvent_SetPosition, 2866).
--define(wxContextMenuEvent_GetPosition, 2867).
--define(wxContextMenuEvent_SetPosition, 2868).
--define(wxIdleEvent_CanSend, 2869).
--define(wxIdleEvent_GetMode, 2870).
--define(wxIdleEvent_RequestMore, 2871).
--define(wxIdleEvent_MoreRequested, 2872).
--define(wxIdleEvent_SetMode, 2873).
--define(wxGridEvent_AltDown, 2874).
--define(wxGridEvent_ControlDown, 2875).
--define(wxGridEvent_GetCol, 2876).
--define(wxGridEvent_GetPosition, 2877).
--define(wxGridEvent_GetRow, 2878).
--define(wxGridEvent_MetaDown, 2879).
--define(wxGridEvent_Selecting, 2880).
--define(wxGridEvent_ShiftDown, 2881).
--define(wxNotifyEvent_Allow, 2882).
--define(wxNotifyEvent_IsAllowed, 2883).
--define(wxNotifyEvent_Veto, 2884).
--define(wxSashEvent_GetEdge, 2885).
--define(wxSashEvent_GetDragRect, 2886).
--define(wxSashEvent_GetDragStatus, 2887).
--define(wxListEvent_GetCacheFrom, 2888).
--define(wxListEvent_GetCacheTo, 2889).
--define(wxListEvent_GetKeyCode, 2890).
--define(wxListEvent_GetIndex, 2891).
--define(wxListEvent_GetColumn, 2892).
--define(wxListEvent_GetPoint, 2893).
--define(wxListEvent_GetLabel, 2894).
--define(wxListEvent_GetText, 2895).
--define(wxListEvent_GetImage, 2896).
--define(wxListEvent_GetData, 2897).
--define(wxListEvent_GetMask, 2898).
--define(wxListEvent_GetItem, 2899).
--define(wxListEvent_IsEditCancelled, 2900).
--define(wxDateEvent_GetDate, 2901).
--define(wxCalendarEvent_GetWeekDay, 2902).
--define(wxFileDirPickerEvent_GetPath, 2903).
--define(wxColourPickerEvent_GetColour, 2904).
--define(wxFontPickerEvent_GetFont, 2905).
--define(wxStyledTextEvent_GetPosition, 2906).
--define(wxStyledTextEvent_GetKey, 2907).
--define(wxStyledTextEvent_GetModifiers, 2908).
--define(wxStyledTextEvent_GetModificationType, 2909).
--define(wxStyledTextEvent_GetText, 2910).
--define(wxStyledTextEvent_GetLength, 2911).
--define(wxStyledTextEvent_GetLinesAdded, 2912).
--define(wxStyledTextEvent_GetLine, 2913).
--define(wxStyledTextEvent_GetFoldLevelNow, 2914).
--define(wxStyledTextEvent_GetFoldLevelPrev, 2915).
--define(wxStyledTextEvent_GetMargin, 2916).
--define(wxStyledTextEvent_GetMessage, 2917).
--define(wxStyledTextEvent_GetWParam, 2918).
--define(wxStyledTextEvent_GetLParam, 2919).
--define(wxStyledTextEvent_GetListType, 2920).
--define(wxStyledTextEvent_GetX, 2921).
--define(wxStyledTextEvent_GetY, 2922).
--define(wxStyledTextEvent_GetDragText, 2923).
--define(wxStyledTextEvent_GetDragAllowMove, 2924).
--define(wxStyledTextEvent_GetDragResult, 2925).
--define(wxStyledTextEvent_GetShift, 2926).
--define(wxStyledTextEvent_GetControl, 2927).
--define(wxStyledTextEvent_GetAlt, 2928).
--define(utils_wxGetKeyState, 2929).
--define(utils_wxGetMousePosition, 2930).
--define(utils_wxGetMouseState, 2931).
--define(utils_wxSetDetectableAutoRepeat, 2932).
--define(utils_wxBell, 2933).
--define(utils_wxFindMenuItemId, 2934).
--define(utils_wxGenericFindWindowAtPoint, 2935).
--define(utils_wxFindWindowAtPoint, 2936).
--define(utils_wxBeginBusyCursor, 2937).
--define(utils_wxEndBusyCursor, 2938).
--define(utils_wxIsBusy, 2939).
--define(utils_wxShutdown, 2940).
--define(utils_wxShell, 2941).
--define(utils_wxLaunchDefaultBrowser, 2942).
--define(utils_wxGetEmailAddress, 2943).
--define(utils_wxGetUserId, 2944).
--define(utils_wxGetHomeDir, 2945).
--define(utils_wxNewId, 2946).
--define(utils_wxRegisterId, 2947).
--define(utils_wxGetCurrentId, 2948).
--define(utils_wxGetOsDescription, 2949).
--define(utils_wxIsPlatformLittleEndian, 2950).
--define(utils_wxIsPlatform64Bit, 2951).
--define(gdicmn_wxDisplaySize, 2952).
--define(gdicmn_wxSetCursor, 2953).
--define(wxPrintout_new, 2954).
--define(wxPrintout_destruct, 2955).
--define(wxPrintout_GetDC, 2956).
--define(wxPrintout_GetPageSizeMM, 2957).
--define(wxPrintout_GetPageSizePixels, 2958).
--define(wxPrintout_GetPaperRectPixels, 2959).
--define(wxPrintout_GetPPIPrinter, 2960).
--define(wxPrintout_GetPPIScreen, 2961).
--define(wxPrintout_GetTitle, 2962).
--define(wxPrintout_IsPreview, 2963).
--define(wxPrintout_FitThisSizeToPaper, 2964).
--define(wxPrintout_FitThisSizeToPage, 2965).
--define(wxPrintout_FitThisSizeToPageMargins, 2966).
--define(wxPrintout_MapScreenSizeToPaper, 2967).
--define(wxPrintout_MapScreenSizeToPage, 2968).
--define(wxPrintout_MapScreenSizeToPageMargins, 2969).
--define(wxPrintout_MapScreenSizeToDevice, 2970).
--define(wxPrintout_GetLogicalPaperRect, 2971).
--define(wxPrintout_GetLogicalPageRect, 2972).
--define(wxPrintout_GetLogicalPageMarginsRect, 2973).
--define(wxPrintout_SetLogicalOrigin, 2974).
--define(wxPrintout_OffsetLogicalOrigin, 2975).
--define(wxStyledTextCtrl_new_2, 2976).
--define(wxStyledTextCtrl_new_0, 2977).
--define(wxStyledTextCtrl_destruct, 2978).
--define(wxStyledTextCtrl_Create, 2979).
--define(wxStyledTextCtrl_AddText, 2980).
--define(wxStyledTextCtrl_AddStyledText, 2981).
--define(wxStyledTextCtrl_InsertText, 2982).
--define(wxStyledTextCtrl_ClearAll, 2983).
--define(wxStyledTextCtrl_ClearDocumentStyle, 2984).
--define(wxStyledTextCtrl_GetLength, 2985).
--define(wxStyledTextCtrl_GetCharAt, 2986).
--define(wxStyledTextCtrl_GetCurrentPos, 2987).
--define(wxStyledTextCtrl_GetAnchor, 2988).
--define(wxStyledTextCtrl_GetStyleAt, 2989).
--define(wxStyledTextCtrl_Redo, 2990).
--define(wxStyledTextCtrl_SetUndoCollection, 2991).
--define(wxStyledTextCtrl_SelectAll, 2992).
--define(wxStyledTextCtrl_SetSavePoint, 2993).
--define(wxStyledTextCtrl_GetStyledText, 2994).
--define(wxStyledTextCtrl_CanRedo, 2995).
--define(wxStyledTextCtrl_MarkerLineFromHandle, 2996).
--define(wxStyledTextCtrl_MarkerDeleteHandle, 2997).
--define(wxStyledTextCtrl_GetUndoCollection, 2998).
--define(wxStyledTextCtrl_GetViewWhiteSpace, 2999).
--define(wxStyledTextCtrl_SetViewWhiteSpace, 3000).
--define(wxStyledTextCtrl_PositionFromPoint, 3001).
--define(wxStyledTextCtrl_PositionFromPointClose, 3002).
--define(wxStyledTextCtrl_GotoLine, 3003).
--define(wxStyledTextCtrl_GotoPos, 3004).
--define(wxStyledTextCtrl_SetAnchor, 3005).
--define(wxStyledTextCtrl_GetCurLine, 3006).
--define(wxStyledTextCtrl_GetEndStyled, 3007).
--define(wxStyledTextCtrl_ConvertEOLs, 3008).
--define(wxStyledTextCtrl_GetEOLMode, 3009).
--define(wxStyledTextCtrl_SetEOLMode, 3010).
--define(wxStyledTextCtrl_StartStyling, 3011).
--define(wxStyledTextCtrl_SetStyling, 3012).
--define(wxStyledTextCtrl_GetBufferedDraw, 3013).
--define(wxStyledTextCtrl_SetBufferedDraw, 3014).
--define(wxStyledTextCtrl_SetTabWidth, 3015).
--define(wxStyledTextCtrl_GetTabWidth, 3016).
--define(wxStyledTextCtrl_SetCodePage, 3017).
--define(wxStyledTextCtrl_MarkerDefine, 3018).
--define(wxStyledTextCtrl_MarkerSetForeground, 3019).
--define(wxStyledTextCtrl_MarkerSetBackground, 3020).
--define(wxStyledTextCtrl_MarkerAdd, 3021).
--define(wxStyledTextCtrl_MarkerDelete, 3022).
--define(wxStyledTextCtrl_MarkerDeleteAll, 3023).
--define(wxStyledTextCtrl_MarkerGet, 3024).
--define(wxStyledTextCtrl_MarkerNext, 3025).
--define(wxStyledTextCtrl_MarkerPrevious, 3026).
--define(wxStyledTextCtrl_MarkerDefineBitmap, 3027).
--define(wxStyledTextCtrl_MarkerAddSet, 3028).
--define(wxStyledTextCtrl_MarkerSetAlpha, 3029).
--define(wxStyledTextCtrl_SetMarginType, 3030).
--define(wxStyledTextCtrl_GetMarginType, 3031).
--define(wxStyledTextCtrl_SetMarginWidth, 3032).
--define(wxStyledTextCtrl_GetMarginWidth, 3033).
--define(wxStyledTextCtrl_SetMarginMask, 3034).
--define(wxStyledTextCtrl_GetMarginMask, 3035).
--define(wxStyledTextCtrl_SetMarginSensitive, 3036).
--define(wxStyledTextCtrl_GetMarginSensitive, 3037).
--define(wxStyledTextCtrl_StyleClearAll, 3038).
--define(wxStyledTextCtrl_StyleSetForeground, 3039).
--define(wxStyledTextCtrl_StyleSetBackground, 3040).
--define(wxStyledTextCtrl_StyleSetBold, 3041).
--define(wxStyledTextCtrl_StyleSetItalic, 3042).
--define(wxStyledTextCtrl_StyleSetSize, 3043).
--define(wxStyledTextCtrl_StyleSetFaceName, 3044).
--define(wxStyledTextCtrl_StyleSetEOLFilled, 3045).
--define(wxStyledTextCtrl_StyleResetDefault, 3046).
--define(wxStyledTextCtrl_StyleSetUnderline, 3047).
--define(wxStyledTextCtrl_StyleSetCase, 3048).
--define(wxStyledTextCtrl_StyleSetHotSpot, 3049).
--define(wxStyledTextCtrl_SetSelForeground, 3050).
--define(wxStyledTextCtrl_SetSelBackground, 3051).
--define(wxStyledTextCtrl_GetSelAlpha, 3052).
--define(wxStyledTextCtrl_SetSelAlpha, 3053).
--define(wxStyledTextCtrl_SetCaretForeground, 3054).
--define(wxStyledTextCtrl_CmdKeyAssign, 3055).
--define(wxStyledTextCtrl_CmdKeyClear, 3056).
--define(wxStyledTextCtrl_CmdKeyClearAll, 3057).
--define(wxStyledTextCtrl_SetStyleBytes, 3058).
--define(wxStyledTextCtrl_StyleSetVisible, 3059).
--define(wxStyledTextCtrl_GetCaretPeriod, 3060).
--define(wxStyledTextCtrl_SetCaretPeriod, 3061).
--define(wxStyledTextCtrl_SetWordChars, 3062).
--define(wxStyledTextCtrl_BeginUndoAction, 3063).
--define(wxStyledTextCtrl_EndUndoAction, 3064).
--define(wxStyledTextCtrl_IndicatorSetStyle, 3065).
--define(wxStyledTextCtrl_IndicatorGetStyle, 3066).
--define(wxStyledTextCtrl_IndicatorSetForeground, 3067).
--define(wxStyledTextCtrl_IndicatorGetForeground, 3068).
--define(wxStyledTextCtrl_SetWhitespaceForeground, 3069).
--define(wxStyledTextCtrl_SetWhitespaceBackground, 3070).
--define(wxStyledTextCtrl_GetStyleBits, 3071).
--define(wxStyledTextCtrl_SetLineState, 3072).
--define(wxStyledTextCtrl_GetLineState, 3073).
--define(wxStyledTextCtrl_GetMaxLineState, 3074).
--define(wxStyledTextCtrl_GetCaretLineVisible, 3075).
--define(wxStyledTextCtrl_SetCaretLineVisible, 3076).
--define(wxStyledTextCtrl_GetCaretLineBackground, 3077).
--define(wxStyledTextCtrl_SetCaretLineBackground, 3078).
--define(wxStyledTextCtrl_AutoCompShow, 3079).
--define(wxStyledTextCtrl_AutoCompCancel, 3080).
--define(wxStyledTextCtrl_AutoCompActive, 3081).
--define(wxStyledTextCtrl_AutoCompPosStart, 3082).
--define(wxStyledTextCtrl_AutoCompComplete, 3083).
--define(wxStyledTextCtrl_AutoCompStops, 3084).
--define(wxStyledTextCtrl_AutoCompSetSeparator, 3085).
--define(wxStyledTextCtrl_AutoCompGetSeparator, 3086).
--define(wxStyledTextCtrl_AutoCompSelect, 3087).
--define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3088).
--define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3089).
--define(wxStyledTextCtrl_AutoCompSetFillUps, 3090).
--define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3091).
--define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3092).
--define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3093).
--define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3094).
--define(wxStyledTextCtrl_UserListShow, 3095).
--define(wxStyledTextCtrl_AutoCompSetAutoHide, 3096).
--define(wxStyledTextCtrl_AutoCompGetAutoHide, 3097).
--define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3098).
--define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3099).
--define(wxStyledTextCtrl_RegisterImage, 3100).
--define(wxStyledTextCtrl_ClearRegisteredImages, 3101).
--define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3102).
--define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3103).
--define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3104).
--define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3105).
--define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3106).
--define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3107).
--define(wxStyledTextCtrl_SetIndent, 3108).
--define(wxStyledTextCtrl_GetIndent, 3109).
--define(wxStyledTextCtrl_SetUseTabs, 3110).
--define(wxStyledTextCtrl_GetUseTabs, 3111).
--define(wxStyledTextCtrl_SetLineIndentation, 3112).
--define(wxStyledTextCtrl_GetLineIndentation, 3113).
--define(wxStyledTextCtrl_GetLineIndentPosition, 3114).
--define(wxStyledTextCtrl_GetColumn, 3115).
--define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3116).
--define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3117).
--define(wxStyledTextCtrl_SetIndentationGuides, 3118).
--define(wxStyledTextCtrl_GetIndentationGuides, 3119).
--define(wxStyledTextCtrl_SetHighlightGuide, 3120).
--define(wxStyledTextCtrl_GetHighlightGuide, 3121).
--define(wxStyledTextCtrl_GetLineEndPosition, 3122).
--define(wxStyledTextCtrl_GetCodePage, 3123).
--define(wxStyledTextCtrl_GetCaretForeground, 3124).
--define(wxStyledTextCtrl_GetReadOnly, 3125).
--define(wxStyledTextCtrl_SetCurrentPos, 3126).
--define(wxStyledTextCtrl_SetSelectionStart, 3127).
--define(wxStyledTextCtrl_GetSelectionStart, 3128).
--define(wxStyledTextCtrl_SetSelectionEnd, 3129).
--define(wxStyledTextCtrl_GetSelectionEnd, 3130).
--define(wxStyledTextCtrl_SetPrintMagnification, 3131).
--define(wxStyledTextCtrl_GetPrintMagnification, 3132).
--define(wxStyledTextCtrl_SetPrintColourMode, 3133).
--define(wxStyledTextCtrl_GetPrintColourMode, 3134).
--define(wxStyledTextCtrl_FindText, 3135).
--define(wxStyledTextCtrl_FormatRange, 3136).
--define(wxStyledTextCtrl_GetFirstVisibleLine, 3137).
--define(wxStyledTextCtrl_GetLine, 3138).
--define(wxStyledTextCtrl_GetLineCount, 3139).
--define(wxStyledTextCtrl_SetMarginLeft, 3140).
--define(wxStyledTextCtrl_GetMarginLeft, 3141).
--define(wxStyledTextCtrl_SetMarginRight, 3142).
--define(wxStyledTextCtrl_GetMarginRight, 3143).
--define(wxStyledTextCtrl_GetModify, 3144).
--define(wxStyledTextCtrl_SetSelection, 3145).
--define(wxStyledTextCtrl_GetSelectedText, 3146).
--define(wxStyledTextCtrl_GetTextRange, 3147).
--define(wxStyledTextCtrl_HideSelection, 3148).
--define(wxStyledTextCtrl_LineFromPosition, 3149).
--define(wxStyledTextCtrl_PositionFromLine, 3150).
--define(wxStyledTextCtrl_LineScroll, 3151).
--define(wxStyledTextCtrl_EnsureCaretVisible, 3152).
--define(wxStyledTextCtrl_ReplaceSelection, 3153).
--define(wxStyledTextCtrl_SetReadOnly, 3154).
--define(wxStyledTextCtrl_CanPaste, 3155).
--define(wxStyledTextCtrl_CanUndo, 3156).
--define(wxStyledTextCtrl_EmptyUndoBuffer, 3157).
--define(wxStyledTextCtrl_Undo, 3158).
--define(wxStyledTextCtrl_Cut, 3159).
--define(wxStyledTextCtrl_Copy, 3160).
--define(wxStyledTextCtrl_Paste, 3161).
--define(wxStyledTextCtrl_Clear, 3162).
--define(wxStyledTextCtrl_SetText, 3163).
--define(wxStyledTextCtrl_GetText, 3164).
--define(wxStyledTextCtrl_GetTextLength, 3165).
--define(wxStyledTextCtrl_GetOvertype, 3166).
--define(wxStyledTextCtrl_SetCaretWidth, 3167).
--define(wxStyledTextCtrl_GetCaretWidth, 3168).
--define(wxStyledTextCtrl_SetTargetStart, 3169).
--define(wxStyledTextCtrl_GetTargetStart, 3170).
--define(wxStyledTextCtrl_SetTargetEnd, 3171).
--define(wxStyledTextCtrl_GetTargetEnd, 3172).
--define(wxStyledTextCtrl_ReplaceTarget, 3173).
--define(wxStyledTextCtrl_SearchInTarget, 3174).
--define(wxStyledTextCtrl_SetSearchFlags, 3175).
--define(wxStyledTextCtrl_GetSearchFlags, 3176).
--define(wxStyledTextCtrl_CallTipShow, 3177).
--define(wxStyledTextCtrl_CallTipCancel, 3178).
--define(wxStyledTextCtrl_CallTipActive, 3179).
--define(wxStyledTextCtrl_CallTipPosAtStart, 3180).
--define(wxStyledTextCtrl_CallTipSetHighlight, 3181).
--define(wxStyledTextCtrl_CallTipSetBackground, 3182).
--define(wxStyledTextCtrl_CallTipSetForeground, 3183).
--define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3184).
--define(wxStyledTextCtrl_CallTipUseStyle, 3185).
--define(wxStyledTextCtrl_VisibleFromDocLine, 3186).
--define(wxStyledTextCtrl_DocLineFromVisible, 3187).
--define(wxStyledTextCtrl_WrapCount, 3188).
--define(wxStyledTextCtrl_SetFoldLevel, 3189).
--define(wxStyledTextCtrl_GetFoldLevel, 3190).
--define(wxStyledTextCtrl_GetLastChild, 3191).
--define(wxStyledTextCtrl_GetFoldParent, 3192).
--define(wxStyledTextCtrl_ShowLines, 3193).
--define(wxStyledTextCtrl_HideLines, 3194).
--define(wxStyledTextCtrl_GetLineVisible, 3195).
--define(wxStyledTextCtrl_SetFoldExpanded, 3196).
--define(wxStyledTextCtrl_GetFoldExpanded, 3197).
--define(wxStyledTextCtrl_ToggleFold, 3198).
--define(wxStyledTextCtrl_EnsureVisible, 3199).
--define(wxStyledTextCtrl_SetFoldFlags, 3200).
--define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3201).
--define(wxStyledTextCtrl_SetTabIndents, 3202).
--define(wxStyledTextCtrl_GetTabIndents, 3203).
--define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3204).
--define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3205).
--define(wxStyledTextCtrl_SetMouseDwellTime, 3206).
--define(wxStyledTextCtrl_GetMouseDwellTime, 3207).
--define(wxStyledTextCtrl_WordStartPosition, 3208).
--define(wxStyledTextCtrl_WordEndPosition, 3209).
--define(wxStyledTextCtrl_SetWrapMode, 3210).
--define(wxStyledTextCtrl_GetWrapMode, 3211).
--define(wxStyledTextCtrl_SetWrapVisualFlags, 3212).
--define(wxStyledTextCtrl_GetWrapVisualFlags, 3213).
--define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3214).
--define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3215).
--define(wxStyledTextCtrl_SetWrapStartIndent, 3216).
--define(wxStyledTextCtrl_GetWrapStartIndent, 3217).
--define(wxStyledTextCtrl_SetLayoutCache, 3218).
--define(wxStyledTextCtrl_GetLayoutCache, 3219).
--define(wxStyledTextCtrl_SetScrollWidth, 3220).
--define(wxStyledTextCtrl_GetScrollWidth, 3221).
--define(wxStyledTextCtrl_TextWidth, 3222).
--define(wxStyledTextCtrl_GetEndAtLastLine, 3223).
--define(wxStyledTextCtrl_TextHeight, 3224).
--define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3225).
--define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3226).
--define(wxStyledTextCtrl_AppendText, 3227).
--define(wxStyledTextCtrl_GetTwoPhaseDraw, 3228).
--define(wxStyledTextCtrl_SetTwoPhaseDraw, 3229).
--define(wxStyledTextCtrl_TargetFromSelection, 3230).
--define(wxStyledTextCtrl_LinesJoin, 3231).
--define(wxStyledTextCtrl_LinesSplit, 3232).
--define(wxStyledTextCtrl_SetFoldMarginColour, 3233).
--define(wxStyledTextCtrl_SetFoldMarginHiColour, 3234).
--define(wxStyledTextCtrl_LineDown, 3235).
--define(wxStyledTextCtrl_LineDownExtend, 3236).
--define(wxStyledTextCtrl_LineUp, 3237).
--define(wxStyledTextCtrl_LineUpExtend, 3238).
--define(wxStyledTextCtrl_CharLeft, 3239).
--define(wxStyledTextCtrl_CharLeftExtend, 3240).
--define(wxStyledTextCtrl_CharRight, 3241).
--define(wxStyledTextCtrl_CharRightExtend, 3242).
--define(wxStyledTextCtrl_WordLeft, 3243).
--define(wxStyledTextCtrl_WordLeftExtend, 3244).
--define(wxStyledTextCtrl_WordRight, 3245).
--define(wxStyledTextCtrl_WordRightExtend, 3246).
--define(wxStyledTextCtrl_Home, 3247).
--define(wxStyledTextCtrl_HomeExtend, 3248).
--define(wxStyledTextCtrl_LineEnd, 3249).
--define(wxStyledTextCtrl_LineEndExtend, 3250).
--define(wxStyledTextCtrl_DocumentStart, 3251).
--define(wxStyledTextCtrl_DocumentStartExtend, 3252).
--define(wxStyledTextCtrl_DocumentEnd, 3253).
--define(wxStyledTextCtrl_DocumentEndExtend, 3254).
--define(wxStyledTextCtrl_PageUp, 3255).
--define(wxStyledTextCtrl_PageUpExtend, 3256).
--define(wxStyledTextCtrl_PageDown, 3257).
--define(wxStyledTextCtrl_PageDownExtend, 3258).
--define(wxStyledTextCtrl_EditToggleOvertype, 3259).
--define(wxStyledTextCtrl_Cancel, 3260).
--define(wxStyledTextCtrl_DeleteBack, 3261).
--define(wxStyledTextCtrl_Tab, 3262).
--define(wxStyledTextCtrl_BackTab, 3263).
--define(wxStyledTextCtrl_NewLine, 3264).
--define(wxStyledTextCtrl_FormFeed, 3265).
--define(wxStyledTextCtrl_VCHome, 3266).
--define(wxStyledTextCtrl_VCHomeExtend, 3267).
--define(wxStyledTextCtrl_ZoomIn, 3268).
--define(wxStyledTextCtrl_ZoomOut, 3269).
--define(wxStyledTextCtrl_DelWordLeft, 3270).
--define(wxStyledTextCtrl_DelWordRight, 3271).
--define(wxStyledTextCtrl_LineCut, 3272).
--define(wxStyledTextCtrl_LineDelete, 3273).
--define(wxStyledTextCtrl_LineTranspose, 3274).
--define(wxStyledTextCtrl_LineDuplicate, 3275).
--define(wxStyledTextCtrl_LowerCase, 3276).
--define(wxStyledTextCtrl_UpperCase, 3277).
--define(wxStyledTextCtrl_LineScrollDown, 3278).
--define(wxStyledTextCtrl_LineScrollUp, 3279).
--define(wxStyledTextCtrl_DeleteBackNotLine, 3280).
--define(wxStyledTextCtrl_HomeDisplay, 3281).
--define(wxStyledTextCtrl_HomeDisplayExtend, 3282).
--define(wxStyledTextCtrl_LineEndDisplay, 3283).
--define(wxStyledTextCtrl_LineEndDisplayExtend, 3284).
--define(wxStyledTextCtrl_HomeWrapExtend, 3285).
--define(wxStyledTextCtrl_LineEndWrap, 3286).
--define(wxStyledTextCtrl_LineEndWrapExtend, 3287).
--define(wxStyledTextCtrl_VCHomeWrap, 3288).
--define(wxStyledTextCtrl_VCHomeWrapExtend, 3289).
--define(wxStyledTextCtrl_LineCopy, 3290).
--define(wxStyledTextCtrl_MoveCaretInsideView, 3291).
--define(wxStyledTextCtrl_LineLength, 3292).
--define(wxStyledTextCtrl_BraceHighlight, 3293).
--define(wxStyledTextCtrl_BraceBadLight, 3294).
--define(wxStyledTextCtrl_BraceMatch, 3295).
--define(wxStyledTextCtrl_GetViewEOL, 3296).
--define(wxStyledTextCtrl_SetViewEOL, 3297).
--define(wxStyledTextCtrl_SetModEventMask, 3298).
--define(wxStyledTextCtrl_GetEdgeColumn, 3299).
--define(wxStyledTextCtrl_SetEdgeColumn, 3300).
--define(wxStyledTextCtrl_SetEdgeMode, 3301).
--define(wxStyledTextCtrl_GetEdgeMode, 3302).
--define(wxStyledTextCtrl_GetEdgeColour, 3303).
--define(wxStyledTextCtrl_SetEdgeColour, 3304).
--define(wxStyledTextCtrl_SearchAnchor, 3305).
--define(wxStyledTextCtrl_SearchNext, 3306).
--define(wxStyledTextCtrl_SearchPrev, 3307).
--define(wxStyledTextCtrl_LinesOnScreen, 3308).
--define(wxStyledTextCtrl_UsePopUp, 3309).
--define(wxStyledTextCtrl_SelectionIsRectangle, 3310).
--define(wxStyledTextCtrl_SetZoom, 3311).
--define(wxStyledTextCtrl_GetZoom, 3312).
--define(wxStyledTextCtrl_GetModEventMask, 3313).
--define(wxStyledTextCtrl_SetSTCFocus, 3314).
--define(wxStyledTextCtrl_GetSTCFocus, 3315).
--define(wxStyledTextCtrl_SetStatus, 3316).
--define(wxStyledTextCtrl_GetStatus, 3317).
--define(wxStyledTextCtrl_SetMouseDownCaptures, 3318).
--define(wxStyledTextCtrl_GetMouseDownCaptures, 3319).
--define(wxStyledTextCtrl_SetSTCCursor, 3320).
--define(wxStyledTextCtrl_GetSTCCursor, 3321).
--define(wxStyledTextCtrl_SetControlCharSymbol, 3322).
--define(wxStyledTextCtrl_GetControlCharSymbol, 3323).
--define(wxStyledTextCtrl_WordPartLeft, 3324).
--define(wxStyledTextCtrl_WordPartLeftExtend, 3325).
--define(wxStyledTextCtrl_WordPartRight, 3326).
--define(wxStyledTextCtrl_WordPartRightExtend, 3327).
--define(wxStyledTextCtrl_SetVisiblePolicy, 3328).
--define(wxStyledTextCtrl_DelLineLeft, 3329).
--define(wxStyledTextCtrl_DelLineRight, 3330).
--define(wxStyledTextCtrl_GetXOffset, 3331).
--define(wxStyledTextCtrl_ChooseCaretX, 3332).
--define(wxStyledTextCtrl_SetXCaretPolicy, 3333).
--define(wxStyledTextCtrl_SetYCaretPolicy, 3334).
--define(wxStyledTextCtrl_GetPrintWrapMode, 3335).
--define(wxStyledTextCtrl_SetHotspotActiveForeground, 3336).
--define(wxStyledTextCtrl_SetHotspotActiveBackground, 3337).
--define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3338).
--define(wxStyledTextCtrl_SetHotspotSingleLine, 3339).
--define(wxStyledTextCtrl_ParaDownExtend, 3340).
--define(wxStyledTextCtrl_ParaUp, 3341).
--define(wxStyledTextCtrl_ParaUpExtend, 3342).
--define(wxStyledTextCtrl_PositionBefore, 3343).
--define(wxStyledTextCtrl_PositionAfter, 3344).
--define(wxStyledTextCtrl_CopyRange, 3345).
--define(wxStyledTextCtrl_CopyText, 3346).
--define(wxStyledTextCtrl_SetSelectionMode, 3347).
--define(wxStyledTextCtrl_GetSelectionMode, 3348).
--define(wxStyledTextCtrl_LineDownRectExtend, 3349).
--define(wxStyledTextCtrl_LineUpRectExtend, 3350).
--define(wxStyledTextCtrl_CharLeftRectExtend, 3351).
--define(wxStyledTextCtrl_CharRightRectExtend, 3352).
--define(wxStyledTextCtrl_HomeRectExtend, 3353).
--define(wxStyledTextCtrl_VCHomeRectExtend, 3354).
--define(wxStyledTextCtrl_LineEndRectExtend, 3355).
--define(wxStyledTextCtrl_PageUpRectExtend, 3356).
--define(wxStyledTextCtrl_PageDownRectExtend, 3357).
--define(wxStyledTextCtrl_StutteredPageUp, 3358).
--define(wxStyledTextCtrl_StutteredPageUpExtend, 3359).
--define(wxStyledTextCtrl_StutteredPageDown, 3360).
--define(wxStyledTextCtrl_StutteredPageDownExtend, 3361).
--define(wxStyledTextCtrl_WordLeftEnd, 3362).
--define(wxStyledTextCtrl_WordLeftEndExtend, 3363).
--define(wxStyledTextCtrl_WordRightEnd, 3364).
--define(wxStyledTextCtrl_WordRightEndExtend, 3365).
--define(wxStyledTextCtrl_SetWhitespaceChars, 3366).
--define(wxStyledTextCtrl_SetCharsDefault, 3367).
--define(wxStyledTextCtrl_AutoCompGetCurrent, 3368).
--define(wxStyledTextCtrl_Allocate, 3369).
--define(wxStyledTextCtrl_FindColumn, 3370).
--define(wxStyledTextCtrl_GetCaretSticky, 3371).
--define(wxStyledTextCtrl_SetCaretSticky, 3372).
--define(wxStyledTextCtrl_ToggleCaretSticky, 3373).
--define(wxStyledTextCtrl_SetPasteConvertEndings, 3374).
--define(wxStyledTextCtrl_GetPasteConvertEndings, 3375).
--define(wxStyledTextCtrl_SelectionDuplicate, 3376).
--define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3377).
--define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3378).
--define(wxStyledTextCtrl_StartRecord, 3379).
--define(wxStyledTextCtrl_StopRecord, 3380).
--define(wxStyledTextCtrl_SetLexer, 3381).
--define(wxStyledTextCtrl_GetLexer, 3382).
--define(wxStyledTextCtrl_Colourise, 3383).
--define(wxStyledTextCtrl_SetProperty, 3384).
--define(wxStyledTextCtrl_SetKeyWords, 3385).
--define(wxStyledTextCtrl_SetLexerLanguage, 3386).
--define(wxStyledTextCtrl_GetProperty, 3387).
--define(wxStyledTextCtrl_GetStyleBitsNeeded, 3388).
--define(wxStyledTextCtrl_GetCurrentLine, 3389).
--define(wxStyledTextCtrl_StyleSetSpec, 3390).
--define(wxStyledTextCtrl_StyleSetFont, 3391).
--define(wxStyledTextCtrl_StyleSetFontAttr, 3392).
--define(wxStyledTextCtrl_StyleSetCharacterSet, 3393).
--define(wxStyledTextCtrl_StyleSetFontEncoding, 3394).
--define(wxStyledTextCtrl_CmdKeyExecute, 3395).
--define(wxStyledTextCtrl_SetMargins, 3396).
--define(wxStyledTextCtrl_GetSelection, 3397).
--define(wxStyledTextCtrl_PointFromPosition, 3398).
--define(wxStyledTextCtrl_ScrollToLine, 3399).
--define(wxStyledTextCtrl_ScrollToColumn, 3400).
--define(wxStyledTextCtrl_SetVScrollBar, 3401).
--define(wxStyledTextCtrl_SetHScrollBar, 3402).
--define(wxStyledTextCtrl_GetLastKeydownProcessed, 3403).
--define(wxStyledTextCtrl_SetLastKeydownProcessed, 3404).
--define(wxStyledTextCtrl_SaveFile, 3405).
--define(wxStyledTextCtrl_LoadFile, 3406).
--define(wxStyledTextCtrl_DoDragOver, 3407).
--define(wxStyledTextCtrl_DoDropText, 3408).
--define(wxStyledTextCtrl_GetUseAntiAliasing, 3409).
--define(wxStyledTextCtrl_AddTextRaw, 3410).
--define(wxStyledTextCtrl_InsertTextRaw, 3411).
--define(wxStyledTextCtrl_GetCurLineRaw, 3412).
--define(wxStyledTextCtrl_GetLineRaw, 3413).
--define(wxStyledTextCtrl_GetSelectedTextRaw, 3414).
--define(wxStyledTextCtrl_GetTextRangeRaw, 3415).
--define(wxStyledTextCtrl_SetTextRaw, 3416).
--define(wxStyledTextCtrl_GetTextRaw, 3417).
--define(wxStyledTextCtrl_AppendTextRaw, 3418).
--define(wxArtProvider_GetBitmap, 3419).
--define(wxArtProvider_GetIcon, 3420).
--define(wxTreeEvent_GetKeyCode, 3421).
--define(wxTreeEvent_GetItem, 3422).
--define(wxTreeEvent_GetKeyEvent, 3423).
--define(wxTreeEvent_GetLabel, 3424).
--define(wxTreeEvent_GetOldItem, 3425).
--define(wxTreeEvent_GetPoint, 3426).
--define(wxTreeEvent_IsEditCancelled, 3427).
--define(wxTreeEvent_SetToolTip, 3428).
--define(wxNotebookEvent_GetOldSelection, 3429).
--define(wxNotebookEvent_GetSelection, 3430).
--define(wxNotebookEvent_SetOldSelection, 3431).
--define(wxNotebookEvent_SetSelection, 3432).
--define(wxFileDataObject_new, 3433).
--define(wxFileDataObject_AddFile, 3434).
--define(wxFileDataObject_GetFilenames, 3435).
--define(wxFileDataObject_destroy, 3436).
--define(wxTextDataObject_new, 3437).
--define(wxTextDataObject_GetTextLength, 3438).
--define(wxTextDataObject_GetText, 3439).
--define(wxTextDataObject_SetText, 3440).
--define(wxTextDataObject_destroy, 3441).
--define(wxBitmapDataObject_new_1_1, 3442).
--define(wxBitmapDataObject_new_1_0, 3443).
--define(wxBitmapDataObject_GetBitmap, 3444).
--define(wxBitmapDataObject_SetBitmap, 3445).
--define(wxBitmapDataObject_destroy, 3446).
--define(wxClipboard_new, 3448).
--define(wxClipboard_destruct, 3449).
--define(wxClipboard_AddData, 3450).
--define(wxClipboard_Clear, 3451).
--define(wxClipboard_Close, 3452).
--define(wxClipboard_Flush, 3453).
--define(wxClipboard_GetData, 3454).
--define(wxClipboard_IsOpened, 3455).
--define(wxClipboard_Open, 3456).
--define(wxClipboard_SetData, 3457).
--define(wxClipboard_UsePrimarySelection, 3459).
--define(wxClipboard_IsSupported, 3460).
--define(wxClipboard_Get, 3461).
--define(wxSpinEvent_GetPosition, 3462).
--define(wxSpinEvent_SetPosition, 3463).
--define(wxSplitterWindow_new_0, 3464).
--define(wxSplitterWindow_new_2, 3465).
--define(wxSplitterWindow_destruct, 3466).
--define(wxSplitterWindow_Create, 3467).
--define(wxSplitterWindow_GetMinimumPaneSize, 3468).
--define(wxSplitterWindow_GetSashGravity, 3469).
--define(wxSplitterWindow_GetSashPosition, 3470).
--define(wxSplitterWindow_GetSplitMode, 3471).
--define(wxSplitterWindow_GetWindow1, 3472).
--define(wxSplitterWindow_GetWindow2, 3473).
--define(wxSplitterWindow_Initialize, 3474).
--define(wxSplitterWindow_IsSplit, 3475).
--define(wxSplitterWindow_ReplaceWindow, 3476).
--define(wxSplitterWindow_SetSashGravity, 3477).
--define(wxSplitterWindow_SetSashPosition, 3478).
--define(wxSplitterWindow_SetSashSize, 3479).
--define(wxSplitterWindow_SetMinimumPaneSize, 3480).
--define(wxSplitterWindow_SetSplitMode, 3481).
--define(wxSplitterWindow_SplitHorizontally, 3482).
--define(wxSplitterWindow_SplitVertically, 3483).
--define(wxSplitterWindow_Unsplit, 3484).
--define(wxSplitterWindow_UpdateSize, 3485).
--define(wxSplitterEvent_GetSashPosition, 3486).
--define(wxSplitterEvent_GetX, 3487).
--define(wxSplitterEvent_GetY, 3488).
--define(wxSplitterEvent_GetWindowBeingRemoved, 3489).
--define(wxSplitterEvent_SetSashPosition, 3490).
--define(wxHtmlWindow_new_0, 3491).
--define(wxHtmlWindow_new_2, 3492).
--define(wxHtmlWindow_AppendToPage, 3493).
--define(wxHtmlWindow_GetOpenedAnchor, 3494).
--define(wxHtmlWindow_GetOpenedPage, 3495).
--define(wxHtmlWindow_GetOpenedPageTitle, 3496).
--define(wxHtmlWindow_GetRelatedFrame, 3497).
--define(wxHtmlWindow_HistoryBack, 3498).
--define(wxHtmlWindow_HistoryCanBack, 3499).
--define(wxHtmlWindow_HistoryCanForward, 3500).
--define(wxHtmlWindow_HistoryClear, 3501).
--define(wxHtmlWindow_HistoryForward, 3502).
--define(wxHtmlWindow_LoadFile, 3503).
--define(wxHtmlWindow_LoadPage, 3504).
--define(wxHtmlWindow_SelectAll, 3505).
--define(wxHtmlWindow_SelectionToText, 3506).
--define(wxHtmlWindow_SelectLine, 3507).
--define(wxHtmlWindow_SelectWord, 3508).
--define(wxHtmlWindow_SetBorders, 3509).
--define(wxHtmlWindow_SetFonts, 3510).
--define(wxHtmlWindow_SetPage, 3511).
--define(wxHtmlWindow_SetRelatedFrame, 3512).
--define(wxHtmlWindow_SetRelatedStatusBar, 3513).
--define(wxHtmlWindow_ToText, 3514).
--define(wxHtmlWindow_destroy, 3515).
--define(wxHtmlLinkEvent_GetLinkInfo, 3516).
--define(wxSystemSettings_GetColour, 3517).
--define(wxSystemSettings_GetFont, 3518).
--define(wxSystemSettings_GetMetric, 3519).
--define(wxSystemSettings_GetScreenType, 3520).
--define(wxSystemOptions_GetOption, 3521).
--define(wxSystemOptions_GetOptionInt, 3522).
--define(wxSystemOptions_HasOption, 3523).
--define(wxSystemOptions_IsFalse, 3524).
--define(wxSystemOptions_SetOption_2_1, 3525).
--define(wxSystemOptions_SetOption_2_0, 3526).
--define(wxAuiNotebookEvent_SetSelection, 3527).
--define(wxAuiNotebookEvent_GetSelection, 3528).
--define(wxAuiNotebookEvent_SetOldSelection, 3529).
--define(wxAuiNotebookEvent_GetOldSelection, 3530).
--define(wxAuiNotebookEvent_SetDragSource, 3531).
--define(wxAuiNotebookEvent_GetDragSource, 3532).
--define(wxAuiManagerEvent_SetManager, 3533).
--define(wxAuiManagerEvent_GetManager, 3534).
--define(wxAuiManagerEvent_SetPane, 3535).
--define(wxAuiManagerEvent_GetPane, 3536).
--define(wxAuiManagerEvent_SetButton, 3537).
--define(wxAuiManagerEvent_GetButton, 3538).
--define(wxAuiManagerEvent_SetDC, 3539).
--define(wxAuiManagerEvent_GetDC, 3540).
--define(wxAuiManagerEvent_Veto, 3541).
--define(wxAuiManagerEvent_GetVeto, 3542).
--define(wxAuiManagerEvent_SetCanVeto, 3543).
--define(wxAuiManagerEvent_CanVeto, 3544).
--define(wxLogNull_new, 3545).
--define(wxLogNull_destroy, 3546).
--define(wxTaskBarIcon_new, 3547).
--define(wxTaskBarIcon_destruct, 3548).
--define(wxTaskBarIcon_PopupMenu, 3549).
--define(wxTaskBarIcon_RemoveIcon, 3550).
--define(wxTaskBarIcon_SetIcon, 3551).
--define(wxLocale_new_0, 3552).
--define(wxLocale_new_2, 3554).
--define(wxLocale_destruct, 3555).
--define(wxLocale_Init, 3557).
--define(wxLocale_AddCatalog_1, 3558).
--define(wxLocale_AddCatalog_3, 3559).
--define(wxLocale_AddCatalogLookupPathPrefix, 3560).
--define(wxLocale_GetCanonicalName, 3561).
--define(wxLocale_GetLanguage, 3562).
--define(wxLocale_GetLanguageName, 3563).
--define(wxLocale_GetLocale, 3564).
--define(wxLocale_GetName, 3565).
--define(wxLocale_GetString_2, 3566).
--define(wxLocale_GetString_4, 3567).
--define(wxLocale_GetHeaderValue, 3568).
--define(wxLocale_GetSysName, 3569).
--define(wxLocale_GetSystemEncoding, 3570).
--define(wxLocale_GetSystemEncodingName, 3571).
--define(wxLocale_GetSystemLanguage, 3572).
--define(wxLocale_IsLoaded, 3573).
--define(wxLocale_IsOk, 3574).
--define(wxActivateEvent_GetActive, 3575).
--define(wxPopupWindow_new_2, 3577).
--define(wxPopupWindow_new_0, 3578).
--define(wxPopupWindow_destruct, 3580).
--define(wxPopupWindow_Create, 3581).
--define(wxPopupWindow_Position, 3582).
--define(wxPopupTransientWindow_new_0, 3583).
--define(wxPopupTransientWindow_new_2, 3584).
--define(wxPopupTransientWindow_destruct, 3585).
--define(wxPopupTransientWindow_Popup, 3586).
--define(wxPopupTransientWindow_Dismiss, 3587).
--define(wxOverlay_new, 3588).
--define(wxOverlay_destruct, 3589).
--define(wxOverlay_Reset, 3590).
--define(wxDCOverlay_new_6, 3591).
--define(wxDCOverlay_new_2, 3592).
--define(wxDCOverlay_destruct, 3593).
--define(wxDCOverlay_Clear, 3594).
+-define(wxWindow_DragAcceptFiles, 126).
+-define(wxWindow_Enable, 127).
+-define(wxWindow_FindFocus, 128).
+-define(wxWindow_FindWindow_1_0, 129).
+-define(wxWindow_FindWindow_1_1, 130).
+-define(wxWindow_FindWindowById, 131).
+-define(wxWindow_FindWindowByName, 132).
+-define(wxWindow_FindWindowByLabel, 133).
+-define(wxWindow_Fit, 134).
+-define(wxWindow_FitInside, 135).
+-define(wxWindow_Freeze, 136).
+-define(wxWindow_GetAcceleratorTable, 137).
+-define(wxWindow_GetBackgroundColour, 138).
+-define(wxWindow_GetBackgroundStyle, 139).
+-define(wxWindow_GetBestSize, 140).
+-define(wxWindow_GetCaret, 142).
+-define(wxWindow_GetCapture, 143).
+-define(wxWindow_GetCharHeight, 144).
+-define(wxWindow_GetCharWidth, 145).
+-define(wxWindow_GetChildren, 146).
+-define(wxWindow_GetClientSize, 149).
+-define(wxWindow_GetContainingSizer, 150).
+-define(wxWindow_GetCursor, 151).
+-define(wxWindow_GetDropTarget, 152).
+-define(wxWindow_GetEventHandler, 153).
+-define(wxWindow_GetExtraStyle, 154).
+-define(wxWindow_GetFont, 155).
+-define(wxWindow_GetForegroundColour, 156).
+-define(wxWindow_GetGrandParent, 157).
+-define(wxWindow_GetHandle, 158).
+-define(wxWindow_GetHelpText, 159).
+-define(wxWindow_GetId, 160).
+-define(wxWindow_GetLabel, 161).
+-define(wxWindow_GetMaxSize, 162).
+-define(wxWindow_GetMinSize, 163).
+-define(wxWindow_GetName, 164).
+-define(wxWindow_GetParent, 165).
+-define(wxWindow_GetPosition, 167).
+-define(wxWindow_GetRect, 168).
+-define(wxWindow_GetScreenPosition, 170).
+-define(wxWindow_GetScreenRect, 171).
+-define(wxWindow_GetScrollPos, 172).
+-define(wxWindow_GetScrollRange, 173).
+-define(wxWindow_GetScrollThumb, 174).
+-define(wxWindow_GetSize, 176).
+-define(wxWindow_GetSizer, 177).
+-define(wxWindow_GetTextExtent, 178).
+-define(wxWindow_GetToolTip, 179).
+-define(wxWindow_GetUpdateRegion, 180).
+-define(wxWindow_GetVirtualSize, 182).
+-define(wxWindow_GetWindowStyleFlag, 184).
+-define(wxWindow_GetWindowVariant, 185).
+-define(wxWindow_HasCapture, 186).
+-define(wxWindow_HasScrollbar, 187).
+-define(wxWindow_HasTransparentBackground, 188).
+-define(wxWindow_Hide, 189).
+-define(wxWindow_InheritAttributes, 190).
+-define(wxWindow_InitDialog, 191).
+-define(wxWindow_InvalidateBestSize, 192).
+-define(wxWindow_IsEnabled, 193).
+-define(wxWindow_IsExposed_2, 194).
+-define(wxWindow_IsExposed_4, 195).
+-define(wxWindow_IsExposed_1_0, 196).
+-define(wxWindow_IsExposed_1_1, 197).
+-define(wxWindow_IsRetained, 198).
+-define(wxWindow_IsShown, 199).
+-define(wxWindow_IsTopLevel, 200).
+-define(wxWindow_Layout, 201).
+-define(wxWindow_LineDown, 202).
+-define(wxWindow_LineUp, 203).
+-define(wxWindow_Lower, 204).
+-define(wxWindow_MakeModal, 205).
+-define(wxWindow_Move_3, 206).
+-define(wxWindow_Move_2, 207).
+-define(wxWindow_MoveAfterInTabOrder, 208).
+-define(wxWindow_MoveBeforeInTabOrder, 209).
+-define(wxWindow_Navigate, 210).
+-define(wxWindow_PageDown, 211).
+-define(wxWindow_PageUp, 212).
+-define(wxWindow_PopEventHandler, 213).
+-define(wxWindow_PopupMenu_2, 214).
+-define(wxWindow_PopupMenu_3, 215).
+-define(wxWindow_Raise, 216).
+-define(wxWindow_Refresh, 217).
+-define(wxWindow_RefreshRect, 218).
+-define(wxWindow_ReleaseMouse, 219).
+-define(wxWindow_RemoveChild, 220).
+-define(wxWindow_Reparent, 221).
+-define(wxWindow_ScreenToClient_2, 222).
+-define(wxWindow_ScreenToClient_1, 223).
+-define(wxWindow_ScrollLines, 225).
+-define(wxWindow_ScrollPages, 227).
+-define(wxWindow_ScrollWindow, 228).
+-define(wxWindow_SetAcceleratorTable, 229).
+-define(wxWindow_SetAutoLayout, 230).
+-define(wxWindow_SetBackgroundColour, 231).
+-define(wxWindow_SetBackgroundStyle, 232).
+-define(wxWindow_SetCaret, 233).
+-define(wxWindow_SetClientSize_2, 234).
+-define(wxWindow_SetClientSize_1_0, 235).
+-define(wxWindow_SetClientSize_1_1, 236).
+-define(wxWindow_SetContainingSizer, 237).
+-define(wxWindow_SetCursor, 238).
+-define(wxWindow_SetMaxSize, 239).
+-define(wxWindow_SetMinSize, 240).
+-define(wxWindow_SetOwnBackgroundColour, 241).
+-define(wxWindow_SetOwnFont, 242).
+-define(wxWindow_SetOwnForegroundColour, 243).
+-define(wxWindow_SetDropTarget, 244).
+-define(wxWindow_SetExtraStyle, 245).
+-define(wxWindow_SetFocus, 246).
+-define(wxWindow_SetFocusFromKbd, 247).
+-define(wxWindow_SetFont, 248).
+-define(wxWindow_SetForegroundColour, 249).
+-define(wxWindow_SetHelpText, 250).
+-define(wxWindow_SetId, 251).
+-define(wxWindow_SetLabel, 253).
+-define(wxWindow_SetName, 254).
+-define(wxWindow_SetPalette, 255).
+-define(wxWindow_SetScrollbar, 256).
+-define(wxWindow_SetScrollPos, 257).
+-define(wxWindow_SetSize_5, 258).
+-define(wxWindow_SetSize_2_0, 259).
+-define(wxWindow_SetSize_1, 260).
+-define(wxWindow_SetSize_2_1, 261).
+-define(wxWindow_SetSizeHints_3, 262).
+-define(wxWindow_SetSizeHints_2, 263).
+-define(wxWindow_SetSizer, 264).
+-define(wxWindow_SetSizerAndFit, 265).
+-define(wxWindow_SetThemeEnabled, 266).
+-define(wxWindow_SetToolTip_1_0, 267).
+-define(wxWindow_SetToolTip_1_1, 268).
+-define(wxWindow_SetVirtualSize_1, 269).
+-define(wxWindow_SetVirtualSize_2, 270).
+-define(wxWindow_SetVirtualSizeHints_3, 271).
+-define(wxWindow_SetVirtualSizeHints_2, 272).
+-define(wxWindow_SetWindowStyle, 273).
+-define(wxWindow_SetWindowStyleFlag, 274).
+-define(wxWindow_SetWindowVariant, 275).
+-define(wxWindow_ShouldInheritColours, 276).
+-define(wxWindow_Show, 277).
+-define(wxWindow_Thaw, 278).
+-define(wxWindow_TransferDataFromWindow, 279).
+-define(wxWindow_TransferDataToWindow, 280).
+-define(wxWindow_Update, 281).
+-define(wxWindow_UpdateWindowUI, 282).
+-define(wxWindow_Validate, 283).
+-define(wxWindow_WarpPointer, 284).
+-define(wxWindow_SetTransparent, 285).
+-define(wxWindow_CanSetTransparent, 286).
+-define(wxWindow_IsDoubleBuffered, 287).
+-define(wxWindow_SetDoubleBuffered, 288).
+-define(wxWindow_GetContentScaleFactor, 289).
+-define(wxTopLevelWindow_GetIcon, 290).
+-define(wxTopLevelWindow_GetIcons, 291).
+-define(wxTopLevelWindow_GetTitle, 292).
+-define(wxTopLevelWindow_IsActive, 293).
+-define(wxTopLevelWindow_Iconize, 294).
+-define(wxTopLevelWindow_IsFullScreen, 295).
+-define(wxTopLevelWindow_IsIconized, 296).
+-define(wxTopLevelWindow_IsMaximized, 297).
+-define(wxTopLevelWindow_Maximize, 298).
+-define(wxTopLevelWindow_RequestUserAttention, 299).
+-define(wxTopLevelWindow_SetIcon, 300).
+-define(wxTopLevelWindow_SetIcons, 301).
+-define(wxTopLevelWindow_CenterOnScreen, 302).
+-define(wxTopLevelWindow_CentreOnScreen, 303).
+-define(wxTopLevelWindow_SetShape, 305).
+-define(wxTopLevelWindow_SetTitle, 306).
+-define(wxTopLevelWindow_ShowFullScreen, 307).
+-define(wxFrame_new_4, 309).
+-define(wxFrame_new_0, 310).
+-define(wxFrame_destruct, 312).
+-define(wxFrame_Create, 313).
+-define(wxFrame_CreateStatusBar, 314).
+-define(wxFrame_CreateToolBar, 315).
+-define(wxFrame_GetClientAreaOrigin, 316).
+-define(wxFrame_GetMenuBar, 317).
+-define(wxFrame_GetStatusBar, 318).
+-define(wxFrame_GetStatusBarPane, 319).
+-define(wxFrame_GetToolBar, 320).
+-define(wxFrame_ProcessCommand, 321).
+-define(wxFrame_SendSizeEvent, 322).
+-define(wxFrame_SetMenuBar, 323).
+-define(wxFrame_SetStatusBar, 324).
+-define(wxFrame_SetStatusBarPane, 325).
+-define(wxFrame_SetStatusText, 326).
+-define(wxFrame_SetStatusWidths, 327).
+-define(wxFrame_SetToolBar, 328).
+-define(wxMiniFrame_new_0, 329).
+-define(wxMiniFrame_new_4, 330).
+-define(wxMiniFrame_Create, 331).
+-define(wxMiniFrame_destroy, 332).
+-define(wxSplashScreen_new_0, 333).
+-define(wxSplashScreen_new_6, 334).
+-define(wxSplashScreen_destruct, 335).
+-define(wxSplashScreen_GetSplashStyle, 336).
+-define(wxSplashScreen_GetTimeout, 337).
+-define(wxPanel_new_0, 338).
+-define(wxPanel_new_6, 339).
+-define(wxPanel_new_2, 340).
+-define(wxPanel_destruct, 341).
+-define(wxPanel_InitDialog, 342).
+-define(wxPanel_SetFocusIgnoringChildren, 343).
+-define(wxScrolledWindow_new_0, 344).
+-define(wxScrolledWindow_new_2, 345).
+-define(wxScrolledWindow_destruct, 346).
+-define(wxScrolledWindow_CalcScrolledPosition_4, 347).
+-define(wxScrolledWindow_CalcScrolledPosition_1, 348).
+-define(wxScrolledWindow_CalcUnscrolledPosition_4, 349).
+-define(wxScrolledWindow_CalcUnscrolledPosition_1, 350).
+-define(wxScrolledWindow_EnableScrolling, 351).
+-define(wxScrolledWindow_GetScrollPixelsPerUnit, 352).
+-define(wxScrolledWindow_GetViewStart, 353).
+-define(wxScrolledWindow_DoPrepareDC, 354).
+-define(wxScrolledWindow_PrepareDC, 355).
+-define(wxScrolledWindow_Scroll, 356).
+-define(wxScrolledWindow_SetScrollbars, 357).
+-define(wxScrolledWindow_SetScrollRate, 358).
+-define(wxScrolledWindow_SetTargetWindow, 359).
+-define(wxSashWindow_new_0, 360).
+-define(wxSashWindow_new_2, 361).
+-define(wxSashWindow_destruct, 362).
+-define(wxSashWindow_GetSashVisible, 363).
+-define(wxSashWindow_GetMaximumSizeX, 364).
+-define(wxSashWindow_GetMaximumSizeY, 365).
+-define(wxSashWindow_GetMinimumSizeX, 366).
+-define(wxSashWindow_GetMinimumSizeY, 367).
+-define(wxSashWindow_SetMaximumSizeX, 368).
+-define(wxSashWindow_SetMaximumSizeY, 369).
+-define(wxSashWindow_SetMinimumSizeX, 370).
+-define(wxSashWindow_SetMinimumSizeY, 371).
+-define(wxSashWindow_SetSashVisible, 372).
+-define(wxSashLayoutWindow_new_0, 373).
+-define(wxSashLayoutWindow_new_2, 374).
+-define(wxSashLayoutWindow_Create, 375).
+-define(wxSashLayoutWindow_GetAlignment, 376).
+-define(wxSashLayoutWindow_GetOrientation, 377).
+-define(wxSashLayoutWindow_SetAlignment, 378).
+-define(wxSashLayoutWindow_SetDefaultSize, 379).
+-define(wxSashLayoutWindow_SetOrientation, 380).
+-define(wxSashLayoutWindow_destroy, 381).
+-define(wxGrid_new_0, 382).
+-define(wxGrid_new_3, 383).
+-define(wxGrid_new_4, 384).
+-define(wxGrid_destruct, 385).
+-define(wxGrid_AppendCols, 386).
+-define(wxGrid_AppendRows, 387).
+-define(wxGrid_AutoSize, 388).
+-define(wxGrid_AutoSizeColumn, 389).
+-define(wxGrid_AutoSizeColumns, 390).
+-define(wxGrid_AutoSizeRow, 391).
+-define(wxGrid_AutoSizeRows, 392).
+-define(wxGrid_BeginBatch, 393).
+-define(wxGrid_BlockToDeviceRect, 394).
+-define(wxGrid_CanDragColSize, 395).
+-define(wxGrid_CanDragRowSize, 396).
+-define(wxGrid_CanDragGridSize, 397).
+-define(wxGrid_CanEnableCellControl, 398).
+-define(wxGrid_CellToRect_2, 399).
+-define(wxGrid_CellToRect_1, 400).
+-define(wxGrid_ClearGrid, 401).
+-define(wxGrid_ClearSelection, 402).
+-define(wxGrid_CreateGrid, 403).
+-define(wxGrid_DeleteCols, 404).
+-define(wxGrid_DeleteRows, 405).
+-define(wxGrid_DisableCellEditControl, 406).
+-define(wxGrid_DisableDragColSize, 407).
+-define(wxGrid_DisableDragGridSize, 408).
+-define(wxGrid_DisableDragRowSize, 409).
+-define(wxGrid_EnableCellEditControl, 410).
+-define(wxGrid_EnableDragColSize, 411).
+-define(wxGrid_EnableDragGridSize, 412).
+-define(wxGrid_EnableDragRowSize, 413).
+-define(wxGrid_EnableEditing, 414).
+-define(wxGrid_EnableGridLines, 415).
+-define(wxGrid_EndBatch, 416).
+-define(wxGrid_Fit, 417).
+-define(wxGrid_ForceRefresh, 418).
+-define(wxGrid_GetBatchCount, 419).
+-define(wxGrid_GetCellAlignment, 420).
+-define(wxGrid_GetCellBackgroundColour, 421).
+-define(wxGrid_GetCellEditor, 422).
+-define(wxGrid_GetCellFont, 423).
+-define(wxGrid_GetCellRenderer, 424).
+-define(wxGrid_GetCellTextColour, 425).
+-define(wxGrid_GetCellValue_2, 426).
+-define(wxGrid_GetCellValue_1, 427).
+-define(wxGrid_GetColLabelAlignment, 428).
+-define(wxGrid_GetColLabelSize, 429).
+-define(wxGrid_GetColLabelValue, 430).
+-define(wxGrid_GetColMinimalAcceptableWidth, 431).
+-define(wxGrid_GetDefaultCellAlignment, 432).
+-define(wxGrid_GetDefaultCellBackgroundColour, 433).
+-define(wxGrid_GetDefaultCellFont, 434).
+-define(wxGrid_GetDefaultCellTextColour, 435).
+-define(wxGrid_GetDefaultColLabelSize, 436).
+-define(wxGrid_GetDefaultColSize, 437).
+-define(wxGrid_GetDefaultEditor, 438).
+-define(wxGrid_GetDefaultEditorForCell_2, 439).
+-define(wxGrid_GetDefaultEditorForCell_1, 440).
+-define(wxGrid_GetDefaultEditorForType, 441).
+-define(wxGrid_GetDefaultRenderer, 442).
+-define(wxGrid_GetDefaultRendererForCell, 443).
+-define(wxGrid_GetDefaultRendererForType, 444).
+-define(wxGrid_GetDefaultRowLabelSize, 445).
+-define(wxGrid_GetDefaultRowSize, 446).
+-define(wxGrid_GetGridCursorCol, 447).
+-define(wxGrid_GetGridCursorRow, 448).
+-define(wxGrid_GetGridLineColour, 449).
+-define(wxGrid_GridLinesEnabled, 450).
+-define(wxGrid_GetLabelBackgroundColour, 451).
+-define(wxGrid_GetLabelFont, 452).
+-define(wxGrid_GetLabelTextColour, 453).
+-define(wxGrid_GetNumberCols, 454).
+-define(wxGrid_GetNumberRows, 455).
+-define(wxGrid_GetOrCreateCellAttr, 456).
+-define(wxGrid_GetRowMinimalAcceptableHeight, 457).
+-define(wxGrid_GetRowLabelAlignment, 458).
+-define(wxGrid_GetRowLabelSize, 459).
+-define(wxGrid_GetRowLabelValue, 460).
+-define(wxGrid_GetRowSize, 461).
+-define(wxGrid_GetScrollLineX, 462).
+-define(wxGrid_GetScrollLineY, 463).
+-define(wxGrid_GetSelectedCells, 464).
+-define(wxGrid_GetSelectedCols, 465).
+-define(wxGrid_GetSelectedRows, 466).
+-define(wxGrid_GetSelectionBackground, 467).
+-define(wxGrid_GetSelectionBlockTopLeft, 468).
+-define(wxGrid_GetSelectionBlockBottomRight, 469).
+-define(wxGrid_GetSelectionForeground, 470).
+-define(wxGrid_GetViewWidth, 471).
+-define(wxGrid_GetGridWindow, 472).
+-define(wxGrid_GetGridRowLabelWindow, 473).
+-define(wxGrid_GetGridColLabelWindow, 474).
+-define(wxGrid_GetGridCornerLabelWindow, 475).
+-define(wxGrid_HideCellEditControl, 476).
+-define(wxGrid_InsertCols, 477).
+-define(wxGrid_InsertRows, 478).
+-define(wxGrid_IsCellEditControlEnabled, 479).
+-define(wxGrid_IsCurrentCellReadOnly, 480).
+-define(wxGrid_IsEditable, 481).
+-define(wxGrid_IsInSelection_2, 482).
+-define(wxGrid_IsInSelection_1, 483).
+-define(wxGrid_IsReadOnly, 484).
+-define(wxGrid_IsSelection, 485).
+-define(wxGrid_IsVisible_3, 486).
+-define(wxGrid_IsVisible_2, 487).
+-define(wxGrid_MakeCellVisible_2, 488).
+-define(wxGrid_MakeCellVisible_1, 489).
+-define(wxGrid_MoveCursorDown, 490).
+-define(wxGrid_MoveCursorLeft, 491).
+-define(wxGrid_MoveCursorRight, 492).
+-define(wxGrid_MoveCursorUp, 493).
+-define(wxGrid_MoveCursorDownBlock, 494).
+-define(wxGrid_MoveCursorLeftBlock, 495).
+-define(wxGrid_MoveCursorRightBlock, 496).
+-define(wxGrid_MoveCursorUpBlock, 497).
+-define(wxGrid_MovePageDown, 498).
+-define(wxGrid_MovePageUp, 499).
+-define(wxGrid_RegisterDataType, 500).
+-define(wxGrid_SaveEditControlValue, 501).
+-define(wxGrid_SelectAll, 502).
+-define(wxGrid_SelectBlock_5, 503).
+-define(wxGrid_SelectBlock_3, 504).
+-define(wxGrid_SelectCol, 505).
+-define(wxGrid_SelectRow, 506).
+-define(wxGrid_SetCellAlignment_4, 507).
+-define(wxGrid_SetCellAlignment_3, 508).
+-define(wxGrid_SetCellAlignment_1, 509).
+-define(wxGrid_SetCellBackgroundColour_3_0, 510).
+-define(wxGrid_SetCellBackgroundColour_1, 511).
+-define(wxGrid_SetCellBackgroundColour_3_1, 512).
+-define(wxGrid_SetCellEditor, 513).
+-define(wxGrid_SetCellFont, 514).
+-define(wxGrid_SetCellRenderer, 515).
+-define(wxGrid_SetCellTextColour_3_0, 516).
+-define(wxGrid_SetCellTextColour_3_1, 517).
+-define(wxGrid_SetCellTextColour_1, 518).
+-define(wxGrid_SetCellValue_3_0, 519).
+-define(wxGrid_SetCellValue_2, 520).
+-define(wxGrid_SetCellValue_3_1, 521).
+-define(wxGrid_SetColAttr, 522).
+-define(wxGrid_SetColFormatBool, 523).
+-define(wxGrid_SetColFormatNumber, 524).
+-define(wxGrid_SetColFormatFloat, 525).
+-define(wxGrid_SetColFormatCustom, 526).
+-define(wxGrid_SetColLabelAlignment, 527).
+-define(wxGrid_SetColLabelSize, 528).
+-define(wxGrid_SetColLabelValue, 529).
+-define(wxGrid_SetColMinimalWidth, 530).
+-define(wxGrid_SetColMinimalAcceptableWidth, 531).
+-define(wxGrid_SetColSize, 532).
+-define(wxGrid_SetDefaultCellAlignment, 533).
+-define(wxGrid_SetDefaultCellBackgroundColour, 534).
+-define(wxGrid_SetDefaultCellFont, 535).
+-define(wxGrid_SetDefaultCellTextColour, 536).
+-define(wxGrid_SetDefaultEditor, 537).
+-define(wxGrid_SetDefaultRenderer, 538).
+-define(wxGrid_SetDefaultColSize, 539).
+-define(wxGrid_SetDefaultRowSize, 540).
+-define(wxGrid_SetGridCursor, 541).
+-define(wxGrid_SetGridLineColour, 542).
+-define(wxGrid_SetLabelBackgroundColour, 543).
+-define(wxGrid_SetLabelFont, 544).
+-define(wxGrid_SetLabelTextColour, 545).
+-define(wxGrid_SetMargins, 546).
+-define(wxGrid_SetReadOnly, 547).
+-define(wxGrid_SetRowAttr, 548).
+-define(wxGrid_SetRowLabelAlignment, 549).
+-define(wxGrid_SetRowLabelSize, 550).
+-define(wxGrid_SetRowLabelValue, 551).
+-define(wxGrid_SetRowMinimalHeight, 552).
+-define(wxGrid_SetRowMinimalAcceptableHeight, 553).
+-define(wxGrid_SetRowSize, 554).
+-define(wxGrid_SetScrollLineX, 555).
+-define(wxGrid_SetScrollLineY, 556).
+-define(wxGrid_SetSelectionBackground, 557).
+-define(wxGrid_SetSelectionForeground, 558).
+-define(wxGrid_SetSelectionMode, 559).
+-define(wxGrid_ShowCellEditControl, 560).
+-define(wxGrid_XToCol, 561).
+-define(wxGrid_XToEdgeOfCol, 562).
+-define(wxGrid_YToEdgeOfRow, 563).
+-define(wxGrid_YToRow, 564).
+-define(wxGridCellRenderer_Draw, 565).
+-define(wxGridCellRenderer_GetBestSize, 566).
+-define(wxGridCellEditor_Create, 567).
+-define(wxGridCellEditor_IsCreated, 568).
+-define(wxGridCellEditor_SetSize, 569).
+-define(wxGridCellEditor_Show, 570).
+-define(wxGridCellEditor_PaintBackground, 571).
+-define(wxGridCellEditor_BeginEdit, 572).
+-define(wxGridCellEditor_EndEdit, 573).
+-define(wxGridCellEditor_Reset, 574).
+-define(wxGridCellEditor_StartingKey, 575).
+-define(wxGridCellEditor_StartingClick, 576).
+-define(wxGridCellEditor_HandleReturn, 577).
+-define(wxGridCellBoolRenderer_new, 578).
+-define(wxGridCellBoolRenderer_destroy, 579).
+-define(wxGridCellBoolEditor_new, 580).
+-define(wxGridCellBoolEditor_IsTrueValue, 581).
+-define(wxGridCellBoolEditor_UseStringValues, 582).
+-define(wxGridCellBoolEditor_destroy, 583).
+-define(wxGridCellFloatRenderer_new, 584).
+-define(wxGridCellFloatRenderer_GetPrecision, 585).
+-define(wxGridCellFloatRenderer_GetWidth, 586).
+-define(wxGridCellFloatRenderer_SetParameters, 587).
+-define(wxGridCellFloatRenderer_SetPrecision, 588).
+-define(wxGridCellFloatRenderer_SetWidth, 589).
+-define(wxGridCellFloatRenderer_destroy, 590).
+-define(wxGridCellFloatEditor_new, 591).
+-define(wxGridCellFloatEditor_SetParameters, 592).
+-define(wxGridCellFloatEditor_destroy, 593).
+-define(wxGridCellStringRenderer_new, 594).
+-define(wxGridCellStringRenderer_destroy, 595).
+-define(wxGridCellTextEditor_new, 596).
+-define(wxGridCellTextEditor_SetParameters, 597).
+-define(wxGridCellTextEditor_destroy, 598).
+-define(wxGridCellChoiceEditor_new, 600).
+-define(wxGridCellChoiceEditor_SetParameters, 601).
+-define(wxGridCellChoiceEditor_destroy, 602).
+-define(wxGridCellNumberRenderer_new, 603).
+-define(wxGridCellNumberRenderer_destroy, 604).
+-define(wxGridCellNumberEditor_new, 605).
+-define(wxGridCellNumberEditor_GetValue, 606).
+-define(wxGridCellNumberEditor_SetParameters, 607).
+-define(wxGridCellNumberEditor_destroy, 608).
+-define(wxGridCellAttr_SetTextColour, 609).
+-define(wxGridCellAttr_SetBackgroundColour, 610).
+-define(wxGridCellAttr_SetFont, 611).
+-define(wxGridCellAttr_SetAlignment, 612).
+-define(wxGridCellAttr_SetReadOnly, 613).
+-define(wxGridCellAttr_SetRenderer, 614).
+-define(wxGridCellAttr_SetEditor, 615).
+-define(wxGridCellAttr_HasTextColour, 616).
+-define(wxGridCellAttr_HasBackgroundColour, 617).
+-define(wxGridCellAttr_HasFont, 618).
+-define(wxGridCellAttr_HasAlignment, 619).
+-define(wxGridCellAttr_HasRenderer, 620).
+-define(wxGridCellAttr_HasEditor, 621).
+-define(wxGridCellAttr_GetTextColour, 622).
+-define(wxGridCellAttr_GetBackgroundColour, 623).
+-define(wxGridCellAttr_GetFont, 624).
+-define(wxGridCellAttr_GetAlignment, 625).
+-define(wxGridCellAttr_GetRenderer, 626).
+-define(wxGridCellAttr_GetEditor, 627).
+-define(wxGridCellAttr_IsReadOnly, 628).
+-define(wxGridCellAttr_SetDefAttr, 629).
+-define(wxDC_Blit, 630).
+-define(wxDC_CalcBoundingBox, 631).
+-define(wxDC_Clear, 632).
+-define(wxDC_ComputeScaleAndOrigin, 633).
+-define(wxDC_CrossHair, 634).
+-define(wxDC_DestroyClippingRegion, 635).
+-define(wxDC_DeviceToLogicalX, 636).
+-define(wxDC_DeviceToLogicalXRel, 637).
+-define(wxDC_DeviceToLogicalY, 638).
+-define(wxDC_DeviceToLogicalYRel, 639).
+-define(wxDC_DrawArc, 640).
+-define(wxDC_DrawBitmap, 641).
+-define(wxDC_DrawCheckMark, 642).
+-define(wxDC_DrawCircle, 643).
+-define(wxDC_DrawEllipse_2, 645).
+-define(wxDC_DrawEllipse_1, 646).
+-define(wxDC_DrawEllipticArc, 647).
+-define(wxDC_DrawIcon, 648).
+-define(wxDC_DrawLabel, 649).
+-define(wxDC_DrawLine, 650).
+-define(wxDC_DrawLines, 651).
+-define(wxDC_DrawPolygon, 653).
+-define(wxDC_DrawPoint, 655).
+-define(wxDC_DrawRectangle_2, 657).
+-define(wxDC_DrawRectangle_1, 658).
+-define(wxDC_DrawRotatedText, 659).
+-define(wxDC_DrawRoundedRectangle_3, 661).
+-define(wxDC_DrawRoundedRectangle_2, 662).
+-define(wxDC_DrawText, 663).
+-define(wxDC_EndDoc, 664).
+-define(wxDC_EndPage, 665).
+-define(wxDC_FloodFill, 666).
+-define(wxDC_GetBackground, 667).
+-define(wxDC_GetBackgroundMode, 668).
+-define(wxDC_GetBrush, 669).
+-define(wxDC_GetCharHeight, 670).
+-define(wxDC_GetCharWidth, 671).
+-define(wxDC_GetClippingBox, 672).
+-define(wxDC_GetFont, 674).
+-define(wxDC_GetLayoutDirection, 675).
+-define(wxDC_GetLogicalFunction, 676).
+-define(wxDC_GetMapMode, 677).
+-define(wxDC_GetMultiLineTextExtent_4, 678).
+-define(wxDC_GetMultiLineTextExtent_1, 679).
+-define(wxDC_GetPartialTextExtents, 680).
+-define(wxDC_GetPen, 681).
+-define(wxDC_GetPixel, 682).
+-define(wxDC_GetPPI, 683).
+-define(wxDC_GetSize, 685).
+-define(wxDC_GetSizeMM, 687).
+-define(wxDC_GetTextBackground, 688).
+-define(wxDC_GetTextExtent_4, 689).
+-define(wxDC_GetTextExtent_1, 690).
+-define(wxDC_GetTextForeground, 692).
+-define(wxDC_GetUserScale, 693).
+-define(wxDC_GradientFillConcentric_3, 694).
+-define(wxDC_GradientFillConcentric_4, 695).
+-define(wxDC_GradientFillLinear, 696).
+-define(wxDC_LogicalToDeviceX, 697).
+-define(wxDC_LogicalToDeviceXRel, 698).
+-define(wxDC_LogicalToDeviceY, 699).
+-define(wxDC_LogicalToDeviceYRel, 700).
+-define(wxDC_MaxX, 701).
+-define(wxDC_MaxY, 702).
+-define(wxDC_MinX, 703).
+-define(wxDC_MinY, 704).
+-define(wxDC_IsOk, 705).
+-define(wxDC_ResetBoundingBox, 706).
+-define(wxDC_SetAxisOrientation, 707).
+-define(wxDC_SetBackground, 708).
+-define(wxDC_SetBackgroundMode, 709).
+-define(wxDC_SetBrush, 710).
+-define(wxDC_SetClippingRegion_2, 712).
+-define(wxDC_SetClippingRegion_1_1, 713).
+-define(wxDC_SetClippingRegion_1_0, 714).
+-define(wxDC_SetDeviceOrigin, 715).
+-define(wxDC_SetFont, 716).
+-define(wxDC_SetLayoutDirection, 717).
+-define(wxDC_SetLogicalFunction, 718).
+-define(wxDC_SetMapMode, 719).
+-define(wxDC_SetPalette, 720).
+-define(wxDC_SetPen, 721).
+-define(wxDC_SetTextBackground, 722).
+-define(wxDC_SetTextForeground, 723).
+-define(wxDC_SetUserScale, 724).
+-define(wxDC_StartDoc, 725).
+-define(wxDC_StartPage, 726).
+-define(wxMirrorDC_new, 727).
+-define(wxMirrorDC_destroy, 728).
+-define(wxScreenDC_new, 729).
+-define(wxScreenDC_destruct, 730).
+-define(wxPostScriptDC_new_0, 731).
+-define(wxPostScriptDC_new_1, 732).
+-define(wxPostScriptDC_destruct, 733).
+-define(wxPostScriptDC_SetResolution, 734).
+-define(wxPostScriptDC_GetResolution, 735).
+-define(wxWindowDC_new_0, 736).
+-define(wxWindowDC_new_1, 737).
+-define(wxWindowDC_destruct, 738).
+-define(wxClientDC_new_0, 739).
+-define(wxClientDC_new_1, 740).
+-define(wxClientDC_destroy, 741).
+-define(wxPaintDC_new_0, 742).
+-define(wxPaintDC_new_1, 743).
+-define(wxPaintDC_destroy, 744).
+-define(wxMemoryDC_new_1_0, 746).
+-define(wxMemoryDC_new_1_1, 747).
+-define(wxMemoryDC_new_0, 748).
+-define(wxMemoryDC_destruct, 750).
+-define(wxMemoryDC_SelectObject, 751).
+-define(wxMemoryDC_SelectObjectAsSource, 752).
+-define(wxBufferedDC_new_0, 753).
+-define(wxBufferedDC_new_2, 754).
+-define(wxBufferedDC_new_3, 755).
+-define(wxBufferedDC_destruct, 756).
+-define(wxBufferedDC_Init_2, 757).
+-define(wxBufferedDC_Init_3, 758).
+-define(wxBufferedPaintDC_new_3, 759).
+-define(wxBufferedPaintDC_new_2, 760).
+-define(wxBufferedPaintDC_destruct, 761).
+-define(wxGraphicsObject_destruct, 762).
+-define(wxGraphicsObject_GetRenderer, 763).
+-define(wxGraphicsObject_IsNull, 764).
+-define(wxGraphicsContext_destruct, 765).
+-define(wxGraphicsContext_Create_1_1, 766).
+-define(wxGraphicsContext_Create_1_0, 767).
+-define(wxGraphicsContext_Create_0, 768).
+-define(wxGraphicsContext_CreatePen, 769).
+-define(wxGraphicsContext_CreateBrush, 770).
+-define(wxGraphicsContext_CreateRadialGradientBrush, 771).
+-define(wxGraphicsContext_CreateLinearGradientBrush, 772).
+-define(wxGraphicsContext_CreateFont, 773).
+-define(wxGraphicsContext_CreateMatrix, 774).
+-define(wxGraphicsContext_CreatePath, 775).
+-define(wxGraphicsContext_Clip_1, 776).
+-define(wxGraphicsContext_Clip_4, 777).
+-define(wxGraphicsContext_ResetClip, 778).
+-define(wxGraphicsContext_DrawBitmap, 779).
+-define(wxGraphicsContext_DrawEllipse, 780).
+-define(wxGraphicsContext_DrawIcon, 781).
+-define(wxGraphicsContext_DrawLines, 782).
+-define(wxGraphicsContext_DrawPath, 783).
+-define(wxGraphicsContext_DrawRectangle, 784).
+-define(wxGraphicsContext_DrawRoundedRectangle, 785).
+-define(wxGraphicsContext_DrawText_3, 786).
+-define(wxGraphicsContext_DrawText_4_0, 787).
+-define(wxGraphicsContext_DrawText_4_1, 788).
+-define(wxGraphicsContext_DrawText_5, 789).
+-define(wxGraphicsContext_FillPath, 790).
+-define(wxGraphicsContext_StrokePath, 791).
+-define(wxGraphicsContext_GetPartialTextExtents, 792).
+-define(wxGraphicsContext_GetTextExtent, 793).
+-define(wxGraphicsContext_Rotate, 794).
+-define(wxGraphicsContext_Scale, 795).
+-define(wxGraphicsContext_Translate, 796).
+-define(wxGraphicsContext_GetTransform, 797).
+-define(wxGraphicsContext_SetTransform, 798).
+-define(wxGraphicsContext_ConcatTransform, 799).
+-define(wxGraphicsContext_SetBrush_1_1, 800).
+-define(wxGraphicsContext_SetBrush_1_0, 801).
+-define(wxGraphicsContext_SetFont_1, 802).
+-define(wxGraphicsContext_SetFont_2, 803).
+-define(wxGraphicsContext_SetPen_1_0, 804).
+-define(wxGraphicsContext_SetPen_1_1, 805).
+-define(wxGraphicsContext_StrokeLine, 806).
+-define(wxGraphicsContext_StrokeLines, 807).
+-define(wxGraphicsMatrix_Concat, 809).
+-define(wxGraphicsMatrix_Get, 811).
+-define(wxGraphicsMatrix_Invert, 812).
+-define(wxGraphicsMatrix_IsEqual, 813).
+-define(wxGraphicsMatrix_IsIdentity, 815).
+-define(wxGraphicsMatrix_Rotate, 816).
+-define(wxGraphicsMatrix_Scale, 817).
+-define(wxGraphicsMatrix_Translate, 818).
+-define(wxGraphicsMatrix_Set, 819).
+-define(wxGraphicsMatrix_TransformPoint, 820).
+-define(wxGraphicsMatrix_TransformDistance, 821).
+-define(wxGraphicsPath_MoveToPoint_2, 822).
+-define(wxGraphicsPath_MoveToPoint_1, 823).
+-define(wxGraphicsPath_AddArc_6, 824).
+-define(wxGraphicsPath_AddArc_5, 825).
+-define(wxGraphicsPath_AddArcToPoint, 826).
+-define(wxGraphicsPath_AddCircle, 827).
+-define(wxGraphicsPath_AddCurveToPoint_6, 828).
+-define(wxGraphicsPath_AddCurveToPoint_3, 829).
+-define(wxGraphicsPath_AddEllipse, 830).
+-define(wxGraphicsPath_AddLineToPoint_2, 831).
+-define(wxGraphicsPath_AddLineToPoint_1, 832).
+-define(wxGraphicsPath_AddPath, 833).
+-define(wxGraphicsPath_AddQuadCurveToPoint, 834).
+-define(wxGraphicsPath_AddRectangle, 835).
+-define(wxGraphicsPath_AddRoundedRectangle, 836).
+-define(wxGraphicsPath_CloseSubpath, 837).
+-define(wxGraphicsPath_Contains_3, 838).
+-define(wxGraphicsPath_Contains_2, 839).
+-define(wxGraphicsPath_GetBox, 841).
+-define(wxGraphicsPath_GetCurrentPoint, 843).
+-define(wxGraphicsPath_Transform, 844).
+-define(wxGraphicsRenderer_GetDefaultRenderer, 845).
+-define(wxGraphicsRenderer_CreateContext_1_1, 846).
+-define(wxGraphicsRenderer_CreateContext_1_0, 847).
+-define(wxGraphicsRenderer_CreatePen, 848).
+-define(wxGraphicsRenderer_CreateBrush, 849).
+-define(wxGraphicsRenderer_CreateLinearGradientBrush, 850).
+-define(wxGraphicsRenderer_CreateRadialGradientBrush, 851).
+-define(wxGraphicsRenderer_CreateFont, 852).
+-define(wxGraphicsRenderer_CreateMatrix, 853).
+-define(wxGraphicsRenderer_CreatePath, 854).
+-define(wxMenuBar_new_1, 856).
+-define(wxMenuBar_new_0, 858).
+-define(wxMenuBar_destruct, 860).
+-define(wxMenuBar_Append, 861).
+-define(wxMenuBar_Check, 862).
+-define(wxMenuBar_Enable_2, 863).
+-define(wxMenuBar_Enable_1, 864).
+-define(wxMenuBar_EnableTop, 865).
+-define(wxMenuBar_FindMenu, 866).
+-define(wxMenuBar_FindMenuItem, 867).
+-define(wxMenuBar_FindItem, 868).
+-define(wxMenuBar_GetHelpString, 869).
+-define(wxMenuBar_GetLabel_1, 870).
+-define(wxMenuBar_GetLabel_0, 871).
+-define(wxMenuBar_GetLabelTop, 872).
+-define(wxMenuBar_GetMenu, 873).
+-define(wxMenuBar_GetMenuCount, 874).
+-define(wxMenuBar_Insert, 875).
+-define(wxMenuBar_IsChecked, 876).
+-define(wxMenuBar_IsEnabled_1, 877).
+-define(wxMenuBar_IsEnabled_0, 878).
+-define(wxMenuBar_Remove, 879).
+-define(wxMenuBar_Replace, 880).
+-define(wxMenuBar_SetHelpString, 881).
+-define(wxMenuBar_SetLabel_2, 882).
+-define(wxMenuBar_SetLabel_1, 883).
+-define(wxMenuBar_SetLabelTop, 884).
+-define(wxControl_GetLabel, 885).
+-define(wxControl_SetLabel, 886).
+-define(wxControlWithItems_Append_1, 887).
+-define(wxControlWithItems_Append_2, 888).
+-define(wxControlWithItems_appendStrings_1, 889).
+-define(wxControlWithItems_Clear, 890).
+-define(wxControlWithItems_Delete, 891).
+-define(wxControlWithItems_FindString, 892).
+-define(wxControlWithItems_getClientData, 893).
+-define(wxControlWithItems_setClientData, 894).
+-define(wxControlWithItems_GetCount, 895).
+-define(wxControlWithItems_GetSelection, 896).
+-define(wxControlWithItems_GetString, 897).
+-define(wxControlWithItems_GetStringSelection, 898).
+-define(wxControlWithItems_Insert_2, 899).
+-define(wxControlWithItems_Insert_3, 900).
+-define(wxControlWithItems_IsEmpty, 901).
+-define(wxControlWithItems_Select, 902).
+-define(wxControlWithItems_SetSelection, 903).
+-define(wxControlWithItems_SetString, 904).
+-define(wxControlWithItems_SetStringSelection, 905).
+-define(wxMenu_new_2, 908).
+-define(wxMenu_new_1, 909).
+-define(wxMenu_destruct, 911).
+-define(wxMenu_Append_3, 912).
+-define(wxMenu_Append_1, 913).
+-define(wxMenu_Append_4_0, 914).
+-define(wxMenu_Append_4_1, 915).
+-define(wxMenu_AppendCheckItem, 916).
+-define(wxMenu_AppendRadioItem, 917).
+-define(wxMenu_AppendSeparator, 918).
+-define(wxMenu_Break, 919).
+-define(wxMenu_Check, 920).
+-define(wxMenu_Delete_1_0, 921).
+-define(wxMenu_Delete_1_1, 922).
+-define(wxMenu_Destroy_1_0, 923).
+-define(wxMenu_Destroy_1_1, 924).
+-define(wxMenu_Enable, 925).
+-define(wxMenu_FindItem_1, 926).
+-define(wxMenu_FindItem_2, 927).
+-define(wxMenu_FindItemByPosition, 928).
+-define(wxMenu_GetHelpString, 929).
+-define(wxMenu_GetLabel, 930).
+-define(wxMenu_GetMenuItemCount, 931).
+-define(wxMenu_GetMenuItems, 932).
+-define(wxMenu_GetTitle, 934).
+-define(wxMenu_Insert_2, 935).
+-define(wxMenu_Insert_3, 936).
+-define(wxMenu_Insert_5_1, 937).
+-define(wxMenu_Insert_5_0, 938).
+-define(wxMenu_InsertCheckItem, 939).
+-define(wxMenu_InsertRadioItem, 940).
+-define(wxMenu_InsertSeparator, 941).
+-define(wxMenu_IsChecked, 942).
+-define(wxMenu_IsEnabled, 943).
+-define(wxMenu_Prepend_1, 944).
+-define(wxMenu_Prepend_2, 945).
+-define(wxMenu_Prepend_4_1, 946).
+-define(wxMenu_Prepend_4_0, 947).
+-define(wxMenu_PrependCheckItem, 948).
+-define(wxMenu_PrependRadioItem, 949).
+-define(wxMenu_PrependSeparator, 950).
+-define(wxMenu_Remove_1_0, 951).
+-define(wxMenu_Remove_1_1, 952).
+-define(wxMenu_SetHelpString, 953).
+-define(wxMenu_SetLabel, 954).
+-define(wxMenu_SetTitle, 955).
+-define(wxMenuItem_new, 956).
+-define(wxMenuItem_destruct, 958).
+-define(wxMenuItem_Check, 959).
+-define(wxMenuItem_Enable, 960).
+-define(wxMenuItem_GetBitmap, 961).
+-define(wxMenuItem_GetHelp, 962).
+-define(wxMenuItem_GetId, 963).
+-define(wxMenuItem_GetKind, 964).
+-define(wxMenuItem_GetLabel, 965).
+-define(wxMenuItem_GetLabelFromText, 966).
+-define(wxMenuItem_GetMenu, 967).
+-define(wxMenuItem_GetText, 968).
+-define(wxMenuItem_GetSubMenu, 969).
+-define(wxMenuItem_IsCheckable, 970).
+-define(wxMenuItem_IsChecked, 971).
+-define(wxMenuItem_IsEnabled, 972).
+-define(wxMenuItem_IsSeparator, 973).
+-define(wxMenuItem_IsSubMenu, 974).
+-define(wxMenuItem_SetBitmap, 975).
+-define(wxMenuItem_SetHelp, 976).
+-define(wxMenuItem_SetMenu, 977).
+-define(wxMenuItem_SetSubMenu, 978).
+-define(wxMenuItem_SetText, 979).
+-define(wxToolBar_AddControl, 980).
+-define(wxToolBar_AddSeparator, 981).
+-define(wxToolBar_AddTool_5, 982).
+-define(wxToolBar_AddTool_4_0, 983).
+-define(wxToolBar_AddTool_1, 984).
+-define(wxToolBar_AddTool_4_1, 985).
+-define(wxToolBar_AddTool_3, 986).
+-define(wxToolBar_AddTool_6, 987).
+-define(wxToolBar_AddCheckTool, 988).
+-define(wxToolBar_AddRadioTool, 989).
+-define(wxToolBar_AddStretchableSpace, 990).
+-define(wxToolBar_InsertStretchableSpace, 991).
+-define(wxToolBar_DeleteTool, 992).
+-define(wxToolBar_DeleteToolByPos, 993).
+-define(wxToolBar_EnableTool, 994).
+-define(wxToolBar_FindById, 995).
+-define(wxToolBar_FindControl, 996).
+-define(wxToolBar_FindToolForPosition, 997).
+-define(wxToolBar_GetToolSize, 998).
+-define(wxToolBar_GetToolBitmapSize, 999).
+-define(wxToolBar_GetMargins, 1000).
+-define(wxToolBar_GetToolEnabled, 1001).
+-define(wxToolBar_GetToolLongHelp, 1002).
+-define(wxToolBar_GetToolPacking, 1003).
+-define(wxToolBar_GetToolPos, 1004).
+-define(wxToolBar_GetToolSeparation, 1005).
+-define(wxToolBar_GetToolShortHelp, 1006).
+-define(wxToolBar_GetToolState, 1007).
+-define(wxToolBar_InsertControl, 1008).
+-define(wxToolBar_InsertSeparator, 1009).
+-define(wxToolBar_InsertTool_5, 1010).
+-define(wxToolBar_InsertTool_2, 1011).
+-define(wxToolBar_InsertTool_4, 1012).
+-define(wxToolBar_Realize, 1013).
+-define(wxToolBar_RemoveTool, 1014).
+-define(wxToolBar_SetMargins, 1015).
+-define(wxToolBar_SetToolBitmapSize, 1016).
+-define(wxToolBar_SetToolLongHelp, 1017).
+-define(wxToolBar_SetToolPacking, 1018).
+-define(wxToolBar_SetToolShortHelp, 1019).
+-define(wxToolBar_SetToolSeparation, 1020).
+-define(wxToolBar_ToggleTool, 1021).
+-define(wxStatusBar_new_0, 1023).
+-define(wxStatusBar_new_2, 1024).
+-define(wxStatusBar_destruct, 1026).
+-define(wxStatusBar_Create, 1027).
+-define(wxStatusBar_GetFieldRect, 1028).
+-define(wxStatusBar_GetFieldsCount, 1029).
+-define(wxStatusBar_GetStatusText, 1030).
+-define(wxStatusBar_PopStatusText, 1031).
+-define(wxStatusBar_PushStatusText, 1032).
+-define(wxStatusBar_SetFieldsCount, 1033).
+-define(wxStatusBar_SetMinHeight, 1034).
+-define(wxStatusBar_SetStatusText, 1035).
+-define(wxStatusBar_SetStatusWidths, 1036).
+-define(wxStatusBar_SetStatusStyles, 1037).
+-define(wxBitmap_new_0, 1038).
+-define(wxBitmap_new_3, 1039).
+-define(wxBitmap_new_4, 1040).
+-define(wxBitmap_new_2_0, 1041).
+-define(wxBitmap_new_2_1, 1042).
+-define(wxBitmap_destruct, 1043).
+-define(wxBitmap_ConvertToImage, 1044).
+-define(wxBitmap_CopyFromIcon, 1045).
+-define(wxBitmap_Create, 1046).
+-define(wxBitmap_GetDepth, 1047).
+-define(wxBitmap_GetHeight, 1048).
+-define(wxBitmap_GetPalette, 1049).
+-define(wxBitmap_GetMask, 1050).
+-define(wxBitmap_GetWidth, 1051).
+-define(wxBitmap_GetSubBitmap, 1052).
+-define(wxBitmap_LoadFile, 1053).
+-define(wxBitmap_Ok, 1054).
+-define(wxBitmap_SaveFile, 1055).
+-define(wxBitmap_SetDepth, 1056).
+-define(wxBitmap_SetHeight, 1057).
+-define(wxBitmap_SetMask, 1058).
+-define(wxBitmap_SetPalette, 1059).
+-define(wxBitmap_SetWidth, 1060).
+-define(wxIcon_new_0, 1061).
+-define(wxIcon_new_2, 1062).
+-define(wxIcon_new_1, 1063).
+-define(wxIcon_CopyFromBitmap, 1064).
+-define(wxIcon_destroy, 1065).
+-define(wxIconBundle_new_0, 1066).
+-define(wxIconBundle_new_2, 1067).
+-define(wxIconBundle_new_1_0, 1068).
+-define(wxIconBundle_new_1_1, 1069).
+-define(wxIconBundle_destruct, 1070).
+-define(wxIconBundle_AddIcon_2, 1071).
+-define(wxIconBundle_AddIcon_1, 1072).
+-define(wxIconBundle_GetIcon_1_1, 1073).
+-define(wxIconBundle_GetIcon_1_0, 1074).
+-define(wxCursor_new_0, 1075).
+-define(wxCursor_new_1_0, 1076).
+-define(wxCursor_new_1_1, 1077).
+-define(wxCursor_new_4, 1078).
+-define(wxCursor_destruct, 1079).
+-define(wxCursor_Ok, 1080).
+-define(wxMask_new_0, 1081).
+-define(wxMask_new_2_1, 1082).
+-define(wxMask_new_2_0, 1083).
+-define(wxMask_new_1, 1084).
+-define(wxMask_destruct, 1085).
+-define(wxMask_Create_2_1, 1086).
+-define(wxMask_Create_2_0, 1087).
+-define(wxMask_Create_1, 1088).
+-define(wxImage_new_0, 1089).
+-define(wxImage_new_3_0, 1090).
+-define(wxImage_new_4, 1091).
+-define(wxImage_new_5, 1092).
+-define(wxImage_new_2, 1093).
+-define(wxImage_new_3_1, 1094).
+-define(wxImage_Blur, 1095).
+-define(wxImage_BlurHorizontal, 1096).
+-define(wxImage_BlurVertical, 1097).
+-define(wxImage_ConvertAlphaToMask, 1098).
+-define(wxImage_ConvertToGreyscale, 1099).
+-define(wxImage_ConvertToMono, 1100).
+-define(wxImage_Copy, 1101).
+-define(wxImage_Create_3, 1102).
+-define(wxImage_Create_4, 1103).
+-define(wxImage_Create_5, 1104).
+-define(wxImage_Destroy, 1105).
+-define(wxImage_FindFirstUnusedColour, 1106).
+-define(wxImage_GetImageExtWildcard, 1107).
+-define(wxImage_GetAlpha_2, 1108).
+-define(wxImage_GetAlpha_0, 1109).
+-define(wxImage_GetBlue, 1110).
+-define(wxImage_GetData, 1111).
+-define(wxImage_GetGreen, 1112).
+-define(wxImage_GetImageCount, 1113).
+-define(wxImage_GetHeight, 1114).
+-define(wxImage_GetMaskBlue, 1115).
+-define(wxImage_GetMaskGreen, 1116).
+-define(wxImage_GetMaskRed, 1117).
+-define(wxImage_GetOrFindMaskColour, 1118).
+-define(wxImage_GetPalette, 1119).
+-define(wxImage_GetRed, 1120).
+-define(wxImage_GetSubImage, 1121).
+-define(wxImage_GetWidth, 1122).
+-define(wxImage_HasAlpha, 1123).
+-define(wxImage_HasMask, 1124).
+-define(wxImage_GetOption, 1125).
+-define(wxImage_GetOptionInt, 1126).
+-define(wxImage_HasOption, 1127).
+-define(wxImage_InitAlpha, 1128).
+-define(wxImage_InitStandardHandlers, 1129).
+-define(wxImage_IsTransparent, 1130).
+-define(wxImage_LoadFile_2, 1131).
+-define(wxImage_LoadFile_3, 1132).
+-define(wxImage_Ok, 1133).
+-define(wxImage_RemoveHandler, 1134).
+-define(wxImage_Mirror, 1135).
+-define(wxImage_Replace, 1136).
+-define(wxImage_Rescale, 1137).
+-define(wxImage_Resize, 1138).
+-define(wxImage_Rotate, 1139).
+-define(wxImage_RotateHue, 1140).
+-define(wxImage_Rotate90, 1141).
+-define(wxImage_SaveFile_1, 1142).
+-define(wxImage_SaveFile_2_0, 1143).
+-define(wxImage_SaveFile_2_1, 1144).
+-define(wxImage_Scale, 1145).
+-define(wxImage_Size, 1146).
+-define(wxImage_SetAlpha_3, 1147).
+-define(wxImage_SetAlpha_2, 1148).
+-define(wxImage_SetData_2, 1149).
+-define(wxImage_SetData_4, 1150).
+-define(wxImage_SetMask, 1151).
+-define(wxImage_SetMaskColour, 1152).
+-define(wxImage_SetMaskFromImage, 1153).
+-define(wxImage_SetOption_2_1, 1154).
+-define(wxImage_SetOption_2_0, 1155).
+-define(wxImage_SetPalette, 1156).
+-define(wxImage_SetRGB_5, 1157).
+-define(wxImage_SetRGB_4, 1158).
+-define(wxImage_destroy, 1159).
+-define(wxBrush_new_0, 1160).
+-define(wxBrush_new_2, 1161).
+-define(wxBrush_new_1, 1162).
+-define(wxBrush_destruct, 1164).
+-define(wxBrush_GetColour, 1165).
+-define(wxBrush_GetStipple, 1166).
+-define(wxBrush_GetStyle, 1167).
+-define(wxBrush_IsHatch, 1168).
+-define(wxBrush_IsOk, 1169).
+-define(wxBrush_SetColour_1, 1170).
+-define(wxBrush_SetColour_3, 1171).
+-define(wxBrush_SetStipple, 1172).
+-define(wxBrush_SetStyle, 1173).
+-define(wxPen_new_0, 1174).
+-define(wxPen_new_2, 1175).
+-define(wxPen_destruct, 1176).
+-define(wxPen_GetCap, 1177).
+-define(wxPen_GetColour, 1178).
+-define(wxPen_GetJoin, 1179).
+-define(wxPen_GetStyle, 1180).
+-define(wxPen_GetWidth, 1181).
+-define(wxPen_IsOk, 1182).
+-define(wxPen_SetCap, 1183).
+-define(wxPen_SetColour_1, 1184).
+-define(wxPen_SetColour_3, 1185).
+-define(wxPen_SetJoin, 1186).
+-define(wxPen_SetStyle, 1187).
+-define(wxPen_SetWidth, 1188).
+-define(wxRegion_new_0, 1189).
+-define(wxRegion_new_4, 1190).
+-define(wxRegion_new_2, 1191).
+-define(wxRegion_new_1_1, 1192).
+-define(wxRegion_new_1_0, 1194).
+-define(wxRegion_destruct, 1196).
+-define(wxRegion_Clear, 1197).
+-define(wxRegion_Contains_2, 1198).
+-define(wxRegion_Contains_1_0, 1199).
+-define(wxRegion_Contains_4, 1200).
+-define(wxRegion_Contains_1_1, 1201).
+-define(wxRegion_ConvertToBitmap, 1202).
+-define(wxRegion_GetBox, 1203).
+-define(wxRegion_Intersect_4, 1204).
+-define(wxRegion_Intersect_1_1, 1205).
+-define(wxRegion_Intersect_1_0, 1206).
+-define(wxRegion_IsEmpty, 1207).
+-define(wxRegion_Subtract_4, 1208).
+-define(wxRegion_Subtract_1_1, 1209).
+-define(wxRegion_Subtract_1_0, 1210).
+-define(wxRegion_Offset_2, 1211).
+-define(wxRegion_Offset_1, 1212).
+-define(wxRegion_Union_4, 1213).
+-define(wxRegion_Union_1_2, 1214).
+-define(wxRegion_Union_1_1, 1215).
+-define(wxRegion_Union_1_0, 1216).
+-define(wxRegion_Union_3, 1217).
+-define(wxRegion_Xor_4, 1218).
+-define(wxRegion_Xor_1_1, 1219).
+-define(wxRegion_Xor_1_0, 1220).
+-define(wxAcceleratorTable_new_0, 1221).
+-define(wxAcceleratorTable_new_2, 1222).
+-define(wxAcceleratorTable_destruct, 1223).
+-define(wxAcceleratorTable_Ok, 1224).
+-define(wxAcceleratorEntry_new_1_0, 1225).
+-define(wxAcceleratorEntry_new_1_1, 1226).
+-define(wxAcceleratorEntry_GetCommand, 1227).
+-define(wxAcceleratorEntry_GetFlags, 1228).
+-define(wxAcceleratorEntry_GetKeyCode, 1229).
+-define(wxAcceleratorEntry_Set, 1230).
+-define(wxAcceleratorEntry_destroy, 1231).
+-define(wxCaret_new_3, 1236).
+-define(wxCaret_new_2, 1237).
+-define(wxCaret_destruct, 1239).
+-define(wxCaret_Create_3, 1240).
+-define(wxCaret_Create_2, 1241).
+-define(wxCaret_GetBlinkTime, 1242).
+-define(wxCaret_GetPosition, 1244).
+-define(wxCaret_GetSize, 1246).
+-define(wxCaret_GetWindow, 1247).
+-define(wxCaret_Hide, 1248).
+-define(wxCaret_IsOk, 1249).
+-define(wxCaret_IsVisible, 1250).
+-define(wxCaret_Move_2, 1251).
+-define(wxCaret_Move_1, 1252).
+-define(wxCaret_SetBlinkTime, 1253).
+-define(wxCaret_SetSize_2, 1254).
+-define(wxCaret_SetSize_1, 1255).
+-define(wxCaret_Show, 1256).
+-define(wxSizer_Add_2_1, 1257).
+-define(wxSizer_Add_2_0, 1258).
+-define(wxSizer_Add_3, 1259).
+-define(wxSizer_Add_2_3, 1260).
+-define(wxSizer_Add_2_2, 1261).
+-define(wxSizer_AddSpacer, 1262).
+-define(wxSizer_AddStretchSpacer, 1263).
+-define(wxSizer_CalcMin, 1264).
+-define(wxSizer_Clear, 1265).
+-define(wxSizer_Detach_1_2, 1266).
+-define(wxSizer_Detach_1_1, 1267).
+-define(wxSizer_Detach_1_0, 1268).
+-define(wxSizer_Fit, 1269).
+-define(wxSizer_FitInside, 1270).
+-define(wxSizer_GetChildren, 1271).
+-define(wxSizer_GetItem_2_1, 1272).
+-define(wxSizer_GetItem_2_0, 1273).
+-define(wxSizer_GetItem_1, 1274).
+-define(wxSizer_GetSize, 1275).
+-define(wxSizer_GetPosition, 1276).
+-define(wxSizer_GetMinSize, 1277).
+-define(wxSizer_Hide_2_0, 1278).
+-define(wxSizer_Hide_2_1, 1279).
+-define(wxSizer_Hide_1, 1280).
+-define(wxSizer_Insert_3_1, 1281).
+-define(wxSizer_Insert_3_0, 1282).
+-define(wxSizer_Insert_4, 1283).
+-define(wxSizer_Insert_3_3, 1284).
+-define(wxSizer_Insert_3_2, 1285).
+-define(wxSizer_Insert_2, 1286).
+-define(wxSizer_InsertSpacer, 1287).
+-define(wxSizer_InsertStretchSpacer, 1288).
+-define(wxSizer_IsShown_1_2, 1289).
+-define(wxSizer_IsShown_1_1, 1290).
+-define(wxSizer_IsShown_1_0, 1291).
+-define(wxSizer_Layout, 1292).
+-define(wxSizer_Prepend_2_1, 1293).
+-define(wxSizer_Prepend_2_0, 1294).
+-define(wxSizer_Prepend_3, 1295).
+-define(wxSizer_Prepend_2_3, 1296).
+-define(wxSizer_Prepend_2_2, 1297).
+-define(wxSizer_Prepend_1, 1298).
+-define(wxSizer_PrependSpacer, 1299).
+-define(wxSizer_PrependStretchSpacer, 1300).
+-define(wxSizer_RecalcSizes, 1301).
+-define(wxSizer_Remove_1_1, 1302).
+-define(wxSizer_Remove_1_0, 1303).
+-define(wxSizer_Replace_3_1, 1304).
+-define(wxSizer_Replace_3_0, 1305).
+-define(wxSizer_Replace_2, 1306).
+-define(wxSizer_SetDimension, 1307).
+-define(wxSizer_SetMinSize_2, 1308).
+-define(wxSizer_SetMinSize_1, 1309).
+-define(wxSizer_SetItemMinSize_3_2, 1310).
+-define(wxSizer_SetItemMinSize_2_2, 1311).
+-define(wxSizer_SetItemMinSize_3_1, 1312).
+-define(wxSizer_SetItemMinSize_2_1, 1313).
+-define(wxSizer_SetItemMinSize_3_0, 1314).
+-define(wxSizer_SetItemMinSize_2_0, 1315).
+-define(wxSizer_SetSizeHints, 1316).
+-define(wxSizer_SetVirtualSizeHints, 1317).
+-define(wxSizer_Show_2_2, 1318).
+-define(wxSizer_Show_2_1, 1319).
+-define(wxSizer_Show_2_0, 1320).
+-define(wxSizer_Show_1, 1321).
+-define(wxSizerFlags_new, 1322).
+-define(wxSizerFlags_Align, 1323).
+-define(wxSizerFlags_Border_2, 1324).
+-define(wxSizerFlags_Border_1, 1325).
+-define(wxSizerFlags_Center, 1326).
+-define(wxSizerFlags_Centre, 1327).
+-define(wxSizerFlags_Expand, 1328).
+-define(wxSizerFlags_Left, 1329).
+-define(wxSizerFlags_Proportion, 1330).
+-define(wxSizerFlags_Right, 1331).
+-define(wxSizerFlags_destroy, 1332).
+-define(wxSizerItem_new_5_1, 1333).
+-define(wxSizerItem_new_2_1, 1334).
+-define(wxSizerItem_new_5_0, 1335).
+-define(wxSizerItem_new_2_0, 1336).
+-define(wxSizerItem_new_6, 1337).
+-define(wxSizerItem_new_3, 1338).
+-define(wxSizerItem_new_0, 1339).
+-define(wxSizerItem_destruct, 1340).
+-define(wxSizerItem_CalcMin, 1341).
+-define(wxSizerItem_DeleteWindows, 1342).
+-define(wxSizerItem_DetachSizer, 1343).
+-define(wxSizerItem_GetBorder, 1344).
+-define(wxSizerItem_GetFlag, 1345).
+-define(wxSizerItem_GetMinSize, 1346).
+-define(wxSizerItem_GetPosition, 1347).
+-define(wxSizerItem_GetProportion, 1348).
+-define(wxSizerItem_GetRatio, 1349).
+-define(wxSizerItem_GetRect, 1350).
+-define(wxSizerItem_GetSize, 1351).
+-define(wxSizerItem_GetSizer, 1352).
+-define(wxSizerItem_GetSpacer, 1353).
+-define(wxSizerItem_GetUserData, 1354).
+-define(wxSizerItem_GetWindow, 1355).
+-define(wxSizerItem_IsSizer, 1356).
+-define(wxSizerItem_IsShown, 1357).
+-define(wxSizerItem_IsSpacer, 1358).
+-define(wxSizerItem_IsWindow, 1359).
+-define(wxSizerItem_SetBorder, 1360).
+-define(wxSizerItem_SetDimension, 1361).
+-define(wxSizerItem_SetFlag, 1362).
+-define(wxSizerItem_SetInitSize, 1363).
+-define(wxSizerItem_SetMinSize_1, 1364).
+-define(wxSizerItem_SetMinSize_2, 1365).
+-define(wxSizerItem_SetProportion, 1366).
+-define(wxSizerItem_SetRatio_2, 1367).
+-define(wxSizerItem_SetRatio_1_1, 1368).
+-define(wxSizerItem_SetRatio_1_0, 1369).
+-define(wxSizerItem_SetSizer, 1370).
+-define(wxSizerItem_SetSpacer_1, 1371).
+-define(wxSizerItem_SetSpacer_2, 1372).
+-define(wxSizerItem_SetWindow, 1373).
+-define(wxSizerItem_Show, 1374).
+-define(wxBoxSizer_new, 1375).
+-define(wxBoxSizer_GetOrientation, 1376).
+-define(wxBoxSizer_destroy, 1377).
+-define(wxStaticBoxSizer_new_2, 1378).
+-define(wxStaticBoxSizer_new_3, 1379).
+-define(wxStaticBoxSizer_GetStaticBox, 1380).
+-define(wxStaticBoxSizer_destroy, 1381).
+-define(wxGridSizer_new_4, 1382).
+-define(wxGridSizer_new_2, 1383).
+-define(wxGridSizer_GetCols, 1384).
+-define(wxGridSizer_GetHGap, 1385).
+-define(wxGridSizer_GetRows, 1386).
+-define(wxGridSizer_GetVGap, 1387).
+-define(wxGridSizer_SetCols, 1388).
+-define(wxGridSizer_SetHGap, 1389).
+-define(wxGridSizer_SetRows, 1390).
+-define(wxGridSizer_SetVGap, 1391).
+-define(wxGridSizer_destroy, 1392).
+-define(wxFlexGridSizer_new_4, 1393).
+-define(wxFlexGridSizer_new_2, 1394).
+-define(wxFlexGridSizer_AddGrowableCol, 1395).
+-define(wxFlexGridSizer_AddGrowableRow, 1396).
+-define(wxFlexGridSizer_GetFlexibleDirection, 1397).
+-define(wxFlexGridSizer_GetNonFlexibleGrowMode, 1398).
+-define(wxFlexGridSizer_RemoveGrowableCol, 1399).
+-define(wxFlexGridSizer_RemoveGrowableRow, 1400).
+-define(wxFlexGridSizer_SetFlexibleDirection, 1401).
+-define(wxFlexGridSizer_SetNonFlexibleGrowMode, 1402).
+-define(wxFlexGridSizer_destroy, 1403).
+-define(wxGridBagSizer_new, 1404).
+-define(wxGridBagSizer_Add_3_2, 1405).
+-define(wxGridBagSizer_Add_3_1, 1406).
+-define(wxGridBagSizer_Add_4, 1407).
+-define(wxGridBagSizer_Add_1_0, 1408).
+-define(wxGridBagSizer_Add_2_1, 1409).
+-define(wxGridBagSizer_Add_2_0, 1410).
+-define(wxGridBagSizer_Add_3_0, 1411).
+-define(wxGridBagSizer_Add_1_1, 1412).
+-define(wxGridBagSizer_CalcMin, 1413).
+-define(wxGridBagSizer_CheckForIntersection_2, 1414).
+-define(wxGridBagSizer_CheckForIntersection_3, 1415).
+-define(wxGridBagSizer_FindItem_1_1, 1416).
+-define(wxGridBagSizer_FindItem_1_0, 1417).
+-define(wxGridBagSizer_FindItemAtPoint, 1418).
+-define(wxGridBagSizer_FindItemAtPosition, 1419).
+-define(wxGridBagSizer_FindItemWithData, 1420).
+-define(wxGridBagSizer_GetCellSize, 1421).
+-define(wxGridBagSizer_GetEmptyCellSize, 1422).
+-define(wxGridBagSizer_GetItemPosition_1_2, 1423).
+-define(wxGridBagSizer_GetItemPosition_1_1, 1424).
+-define(wxGridBagSizer_GetItemPosition_1_0, 1425).
+-define(wxGridBagSizer_GetItemSpan_1_2, 1426).
+-define(wxGridBagSizer_GetItemSpan_1_1, 1427).
+-define(wxGridBagSizer_GetItemSpan_1_0, 1428).
+-define(wxGridBagSizer_SetEmptyCellSize, 1429).
+-define(wxGridBagSizer_SetItemPosition_2_2, 1430).
+-define(wxGridBagSizer_SetItemPosition_2_1, 1431).
+-define(wxGridBagSizer_SetItemPosition_2_0, 1432).
+-define(wxGridBagSizer_SetItemSpan_2_2, 1433).
+-define(wxGridBagSizer_SetItemSpan_2_1, 1434).
+-define(wxGridBagSizer_SetItemSpan_2_0, 1435).
+-define(wxGridBagSizer_destroy, 1436).
+-define(wxStdDialogButtonSizer_new, 1437).
+-define(wxStdDialogButtonSizer_AddButton, 1438).
+-define(wxStdDialogButtonSizer_Realize, 1439).
+-define(wxStdDialogButtonSizer_SetAffirmativeButton, 1440).
+-define(wxStdDialogButtonSizer_SetCancelButton, 1441).
+-define(wxStdDialogButtonSizer_SetNegativeButton, 1442).
+-define(wxStdDialogButtonSizer_destroy, 1443).
+-define(wxFont_new_0, 1444).
+-define(wxFont_new_1, 1445).
+-define(wxFont_new_5, 1446).
+-define(wxFont_destruct, 1448).
+-define(wxFont_IsFixedWidth, 1449).
+-define(wxFont_GetDefaultEncoding, 1450).
+-define(wxFont_GetFaceName, 1451).
+-define(wxFont_GetFamily, 1452).
+-define(wxFont_GetNativeFontInfoDesc, 1453).
+-define(wxFont_GetNativeFontInfoUserDesc, 1454).
+-define(wxFont_GetPointSize, 1455).
+-define(wxFont_GetStyle, 1456).
+-define(wxFont_GetUnderlined, 1457).
+-define(wxFont_GetWeight, 1458).
+-define(wxFont_Ok, 1459).
+-define(wxFont_SetDefaultEncoding, 1460).
+-define(wxFont_SetFaceName, 1461).
+-define(wxFont_SetFamily, 1462).
+-define(wxFont_SetPointSize, 1463).
+-define(wxFont_SetStyle, 1464).
+-define(wxFont_SetUnderlined, 1465).
+-define(wxFont_SetWeight, 1466).
+-define(wxToolTip_Enable, 1467).
+-define(wxToolTip_SetDelay, 1468).
+-define(wxToolTip_new, 1469).
+-define(wxToolTip_SetTip, 1470).
+-define(wxToolTip_GetTip, 1471).
+-define(wxToolTip_GetWindow, 1472).
+-define(wxToolTip_destroy, 1473).
+-define(wxButton_new_3, 1475).
+-define(wxButton_new_0, 1476).
+-define(wxButton_destruct, 1477).
+-define(wxButton_Create, 1478).
+-define(wxButton_GetDefaultSize, 1479).
+-define(wxButton_SetDefault, 1480).
+-define(wxButton_SetLabel, 1481).
+-define(wxBitmapButton_new_4, 1483).
+-define(wxBitmapButton_new_0, 1484).
+-define(wxBitmapButton_Create, 1485).
+-define(wxBitmapButton_GetBitmapDisabled, 1486).
+-define(wxBitmapButton_GetBitmapFocus, 1488).
+-define(wxBitmapButton_GetBitmapLabel, 1490).
+-define(wxBitmapButton_GetBitmapSelected, 1492).
+-define(wxBitmapButton_SetBitmapDisabled, 1494).
+-define(wxBitmapButton_SetBitmapFocus, 1495).
+-define(wxBitmapButton_SetBitmapLabel, 1496).
+-define(wxBitmapButton_SetBitmapSelected, 1497).
+-define(wxBitmapButton_destroy, 1498).
+-define(wxToggleButton_new_0, 1499).
+-define(wxToggleButton_new_4, 1500).
+-define(wxToggleButton_Create, 1501).
+-define(wxToggleButton_GetValue, 1502).
+-define(wxToggleButton_SetValue, 1503).
+-define(wxToggleButton_destroy, 1504).
+-define(wxCalendarCtrl_new_0, 1505).
+-define(wxCalendarCtrl_new_3, 1506).
+-define(wxCalendarCtrl_Create, 1507).
+-define(wxCalendarCtrl_destruct, 1508).
+-define(wxCalendarCtrl_SetDate, 1509).
+-define(wxCalendarCtrl_GetDate, 1510).
+-define(wxCalendarCtrl_EnableYearChange, 1511).
+-define(wxCalendarCtrl_EnableMonthChange, 1512).
+-define(wxCalendarCtrl_EnableHolidayDisplay, 1513).
+-define(wxCalendarCtrl_SetHeaderColours, 1514).
+-define(wxCalendarCtrl_GetHeaderColourFg, 1515).
+-define(wxCalendarCtrl_GetHeaderColourBg, 1516).
+-define(wxCalendarCtrl_SetHighlightColours, 1517).
+-define(wxCalendarCtrl_GetHighlightColourFg, 1518).
+-define(wxCalendarCtrl_GetHighlightColourBg, 1519).
+-define(wxCalendarCtrl_SetHolidayColours, 1520).
+-define(wxCalendarCtrl_GetHolidayColourFg, 1521).
+-define(wxCalendarCtrl_GetHolidayColourBg, 1522).
+-define(wxCalendarCtrl_GetAttr, 1523).
+-define(wxCalendarCtrl_SetAttr, 1524).
+-define(wxCalendarCtrl_SetHoliday, 1525).
+-define(wxCalendarCtrl_ResetAttr, 1526).
+-define(wxCalendarCtrl_HitTest, 1527).
+-define(wxCalendarDateAttr_new_0, 1528).
+-define(wxCalendarDateAttr_new_2_1, 1529).
+-define(wxCalendarDateAttr_new_2_0, 1530).
+-define(wxCalendarDateAttr_SetTextColour, 1531).
+-define(wxCalendarDateAttr_SetBackgroundColour, 1532).
+-define(wxCalendarDateAttr_SetBorderColour, 1533).
+-define(wxCalendarDateAttr_SetFont, 1534).
+-define(wxCalendarDateAttr_SetBorder, 1535).
+-define(wxCalendarDateAttr_SetHoliday, 1536).
+-define(wxCalendarDateAttr_HasTextColour, 1537).
+-define(wxCalendarDateAttr_HasBackgroundColour, 1538).
+-define(wxCalendarDateAttr_HasBorderColour, 1539).
+-define(wxCalendarDateAttr_HasFont, 1540).
+-define(wxCalendarDateAttr_HasBorder, 1541).
+-define(wxCalendarDateAttr_IsHoliday, 1542).
+-define(wxCalendarDateAttr_GetTextColour, 1543).
+-define(wxCalendarDateAttr_GetBackgroundColour, 1544).
+-define(wxCalendarDateAttr_GetBorderColour, 1545).
+-define(wxCalendarDateAttr_GetFont, 1546).
+-define(wxCalendarDateAttr_GetBorder, 1547).
+-define(wxCalendarDateAttr_destroy, 1548).
+-define(wxCheckBox_new_4, 1550).
+-define(wxCheckBox_new_0, 1551).
+-define(wxCheckBox_Create, 1552).
+-define(wxCheckBox_GetValue, 1553).
+-define(wxCheckBox_Get3StateValue, 1554).
+-define(wxCheckBox_Is3rdStateAllowedForUser, 1555).
+-define(wxCheckBox_Is3State, 1556).
+-define(wxCheckBox_IsChecked, 1557).
+-define(wxCheckBox_SetValue, 1558).
+-define(wxCheckBox_Set3StateValue, 1559).
+-define(wxCheckBox_destroy, 1560).
+-define(wxCheckListBox_new_0, 1561).
+-define(wxCheckListBox_new_3, 1563).
+-define(wxCheckListBox_Check, 1564).
+-define(wxCheckListBox_IsChecked, 1565).
+-define(wxCheckListBox_destroy, 1566).
+-define(wxChoice_new_3, 1569).
+-define(wxChoice_new_0, 1570).
+-define(wxChoice_destruct, 1572).
+-define(wxChoice_Create, 1574).
+-define(wxChoice_Delete, 1575).
+-define(wxChoice_GetColumns, 1576).
+-define(wxChoice_SetColumns, 1577).
+-define(wxComboBox_new_0, 1578).
+-define(wxComboBox_new_3, 1580).
+-define(wxComboBox_destruct, 1581).
+-define(wxComboBox_Create, 1583).
+-define(wxComboBox_CanCopy, 1584).
+-define(wxComboBox_CanCut, 1585).
+-define(wxComboBox_CanPaste, 1586).
+-define(wxComboBox_CanRedo, 1587).
+-define(wxComboBox_CanUndo, 1588).
+-define(wxComboBox_Copy, 1589).
+-define(wxComboBox_Cut, 1590).
+-define(wxComboBox_GetInsertionPoint, 1591).
+-define(wxComboBox_GetLastPosition, 1592).
+-define(wxComboBox_GetValue, 1593).
+-define(wxComboBox_Paste, 1594).
+-define(wxComboBox_Redo, 1595).
+-define(wxComboBox_Replace, 1596).
+-define(wxComboBox_Remove, 1597).
+-define(wxComboBox_SetInsertionPoint, 1598).
+-define(wxComboBox_SetInsertionPointEnd, 1599).
+-define(wxComboBox_SetSelection_1, 1600).
+-define(wxComboBox_SetSelection_2, 1601).
+-define(wxComboBox_SetValue, 1602).
+-define(wxComboBox_Undo, 1603).
+-define(wxGauge_new_0, 1604).
+-define(wxGauge_new_4, 1605).
+-define(wxGauge_Create, 1606).
+-define(wxGauge_GetRange, 1607).
+-define(wxGauge_GetValue, 1608).
+-define(wxGauge_IsVertical, 1609).
+-define(wxGauge_SetRange, 1610).
+-define(wxGauge_SetValue, 1611).
+-define(wxGauge_Pulse, 1612).
+-define(wxGauge_destroy, 1613).
+-define(wxGenericDirCtrl_new_0, 1614).
+-define(wxGenericDirCtrl_new_2, 1615).
+-define(wxGenericDirCtrl_destruct, 1616).
+-define(wxGenericDirCtrl_Create, 1617).
+-define(wxGenericDirCtrl_Init, 1618).
+-define(wxGenericDirCtrl_CollapseTree, 1619).
+-define(wxGenericDirCtrl_ExpandPath, 1620).
+-define(wxGenericDirCtrl_GetDefaultPath, 1621).
+-define(wxGenericDirCtrl_GetPath, 1622).
+-define(wxGenericDirCtrl_GetFilePath, 1623).
+-define(wxGenericDirCtrl_GetFilter, 1624).
+-define(wxGenericDirCtrl_GetFilterIndex, 1625).
+-define(wxGenericDirCtrl_GetRootId, 1626).
+-define(wxGenericDirCtrl_GetTreeCtrl, 1627).
+-define(wxGenericDirCtrl_ReCreateTree, 1628).
+-define(wxGenericDirCtrl_SetDefaultPath, 1629).
+-define(wxGenericDirCtrl_SetFilter, 1630).
+-define(wxGenericDirCtrl_SetFilterIndex, 1631).
+-define(wxGenericDirCtrl_SetPath, 1632).
+-define(wxStaticBox_new_4, 1634).
+-define(wxStaticBox_new_0, 1635).
+-define(wxStaticBox_Create, 1636).
+-define(wxStaticBox_destroy, 1637).
+-define(wxStaticLine_new_2, 1639).
+-define(wxStaticLine_new_0, 1640).
+-define(wxStaticLine_Create, 1641).
+-define(wxStaticLine_IsVertical, 1642).
+-define(wxStaticLine_GetDefaultSize, 1643).
+-define(wxStaticLine_destroy, 1644).
+-define(wxListBox_new_3, 1647).
+-define(wxListBox_new_0, 1648).
+-define(wxListBox_destruct, 1650).
+-define(wxListBox_Create, 1652).
+-define(wxListBox_Deselect, 1653).
+-define(wxListBox_GetSelections, 1654).
+-define(wxListBox_InsertItems, 1655).
+-define(wxListBox_IsSelected, 1656).
+-define(wxListBox_Set, 1657).
+-define(wxListBox_HitTest, 1658).
+-define(wxListBox_SetFirstItem_1_0, 1659).
+-define(wxListBox_SetFirstItem_1_1, 1660).
+-define(wxListCtrl_new_0, 1661).
+-define(wxListCtrl_new_2, 1662).
+-define(wxListCtrl_Arrange, 1663).
+-define(wxListCtrl_AssignImageList, 1664).
+-define(wxListCtrl_ClearAll, 1665).
+-define(wxListCtrl_Create, 1666).
+-define(wxListCtrl_DeleteAllItems, 1667).
+-define(wxListCtrl_DeleteColumn, 1668).
+-define(wxListCtrl_DeleteItem, 1669).
+-define(wxListCtrl_EditLabel, 1670).
+-define(wxListCtrl_EnsureVisible, 1671).
+-define(wxListCtrl_FindItem_3_0, 1672).
+-define(wxListCtrl_FindItem_3_1, 1673).
+-define(wxListCtrl_GetColumn, 1674).
+-define(wxListCtrl_GetColumnCount, 1675).
+-define(wxListCtrl_GetColumnWidth, 1676).
+-define(wxListCtrl_GetCountPerPage, 1677).
+-define(wxListCtrl_GetEditControl, 1678).
+-define(wxListCtrl_GetImageList, 1679).
+-define(wxListCtrl_GetItem, 1680).
+-define(wxListCtrl_GetItemBackgroundColour, 1681).
+-define(wxListCtrl_GetItemCount, 1682).
+-define(wxListCtrl_GetItemData, 1683).
+-define(wxListCtrl_GetItemFont, 1684).
+-define(wxListCtrl_GetItemPosition, 1685).
+-define(wxListCtrl_GetItemRect, 1686).
+-define(wxListCtrl_GetItemSpacing, 1687).
+-define(wxListCtrl_GetItemState, 1688).
+-define(wxListCtrl_GetItemText, 1689).
+-define(wxListCtrl_GetItemTextColour, 1690).
+-define(wxListCtrl_GetNextItem, 1691).
+-define(wxListCtrl_GetSelectedItemCount, 1692).
+-define(wxListCtrl_GetTextColour, 1693).
+-define(wxListCtrl_GetTopItem, 1694).
+-define(wxListCtrl_GetViewRect, 1695).
+-define(wxListCtrl_HitTest, 1696).
+-define(wxListCtrl_InsertColumn_2, 1697).
+-define(wxListCtrl_InsertColumn_3, 1698).
+-define(wxListCtrl_InsertItem_1, 1699).
+-define(wxListCtrl_InsertItem_2_1, 1700).
+-define(wxListCtrl_InsertItem_2_0, 1701).
+-define(wxListCtrl_InsertItem_3, 1702).
+-define(wxListCtrl_RefreshItem, 1703).
+-define(wxListCtrl_RefreshItems, 1704).
+-define(wxListCtrl_ScrollList, 1705).
+-define(wxListCtrl_SetBackgroundColour, 1706).
+-define(wxListCtrl_SetColumn, 1707).
+-define(wxListCtrl_SetColumnWidth, 1708).
+-define(wxListCtrl_SetImageList, 1709).
+-define(wxListCtrl_SetItem_1, 1710).
+-define(wxListCtrl_SetItem_4, 1711).
+-define(wxListCtrl_SetItemBackgroundColour, 1712).
+-define(wxListCtrl_SetItemCount, 1713).
+-define(wxListCtrl_SetItemData, 1714).
+-define(wxListCtrl_SetItemFont, 1715).
+-define(wxListCtrl_SetItemImage, 1716).
+-define(wxListCtrl_SetItemColumnImage, 1717).
+-define(wxListCtrl_SetItemPosition, 1718).
+-define(wxListCtrl_SetItemState, 1719).
+-define(wxListCtrl_SetItemText, 1720).
+-define(wxListCtrl_SetItemTextColour, 1721).
+-define(wxListCtrl_SetSingleStyle, 1722).
+-define(wxListCtrl_SetTextColour, 1723).
+-define(wxListCtrl_SetWindowStyleFlag, 1724).
+-define(wxListCtrl_SortItems, 1725).
+-define(wxListCtrl_destroy, 1726).
+-define(wxListView_ClearColumnImage, 1727).
+-define(wxListView_Focus, 1728).
+-define(wxListView_GetFirstSelected, 1729).
+-define(wxListView_GetFocusedItem, 1730).
+-define(wxListView_GetNextSelected, 1731).
+-define(wxListView_IsSelected, 1732).
+-define(wxListView_Select, 1733).
+-define(wxListView_SetColumnImage, 1734).
+-define(wxListItem_new_0, 1735).
+-define(wxListItem_new_1, 1736).
+-define(wxListItem_destruct, 1737).
+-define(wxListItem_Clear, 1738).
+-define(wxListItem_GetAlign, 1739).
+-define(wxListItem_GetBackgroundColour, 1740).
+-define(wxListItem_GetColumn, 1741).
+-define(wxListItem_GetFont, 1742).
+-define(wxListItem_GetId, 1743).
+-define(wxListItem_GetImage, 1744).
+-define(wxListItem_GetMask, 1745).
+-define(wxListItem_GetState, 1746).
+-define(wxListItem_GetText, 1747).
+-define(wxListItem_GetTextColour, 1748).
+-define(wxListItem_GetWidth, 1749).
+-define(wxListItem_SetAlign, 1750).
+-define(wxListItem_SetBackgroundColour, 1751).
+-define(wxListItem_SetColumn, 1752).
+-define(wxListItem_SetFont, 1753).
+-define(wxListItem_SetId, 1754).
+-define(wxListItem_SetImage, 1755).
+-define(wxListItem_SetMask, 1756).
+-define(wxListItem_SetState, 1757).
+-define(wxListItem_SetStateMask, 1758).
+-define(wxListItem_SetText, 1759).
+-define(wxListItem_SetTextColour, 1760).
+-define(wxListItem_SetWidth, 1761).
+-define(wxListItemAttr_new_0, 1762).
+-define(wxListItemAttr_new_3, 1763).
+-define(wxListItemAttr_GetBackgroundColour, 1764).
+-define(wxListItemAttr_GetFont, 1765).
+-define(wxListItemAttr_GetTextColour, 1766).
+-define(wxListItemAttr_HasBackgroundColour, 1767).
+-define(wxListItemAttr_HasFont, 1768).
+-define(wxListItemAttr_HasTextColour, 1769).
+-define(wxListItemAttr_SetBackgroundColour, 1770).
+-define(wxListItemAttr_SetFont, 1771).
+-define(wxListItemAttr_SetTextColour, 1772).
+-define(wxListItemAttr_destroy, 1773).
+-define(wxImageList_new_0, 1774).
+-define(wxImageList_new_3, 1775).
+-define(wxImageList_Add_1, 1776).
+-define(wxImageList_Add_2_0, 1777).
+-define(wxImageList_Add_2_1, 1778).
+-define(wxImageList_Create, 1779).
+-define(wxImageList_Draw, 1781).
+-define(wxImageList_GetBitmap, 1782).
+-define(wxImageList_GetIcon, 1783).
+-define(wxImageList_GetImageCount, 1784).
+-define(wxImageList_GetSize, 1785).
+-define(wxImageList_Remove, 1786).
+-define(wxImageList_RemoveAll, 1787).
+-define(wxImageList_Replace_2, 1788).
+-define(wxImageList_Replace_3, 1789).
+-define(wxImageList_destroy, 1790).
+-define(wxTextAttr_new_0, 1791).
+-define(wxTextAttr_new_2, 1792).
+-define(wxTextAttr_GetAlignment, 1793).
+-define(wxTextAttr_GetBackgroundColour, 1794).
+-define(wxTextAttr_GetFont, 1795).
+-define(wxTextAttr_GetLeftIndent, 1796).
+-define(wxTextAttr_GetLeftSubIndent, 1797).
+-define(wxTextAttr_GetRightIndent, 1798).
+-define(wxTextAttr_GetTabs, 1799).
+-define(wxTextAttr_GetTextColour, 1800).
+-define(wxTextAttr_HasBackgroundColour, 1801).
+-define(wxTextAttr_HasFont, 1802).
+-define(wxTextAttr_HasTextColour, 1803).
+-define(wxTextAttr_GetFlags, 1804).
+-define(wxTextAttr_IsDefault, 1805).
+-define(wxTextAttr_SetAlignment, 1806).
+-define(wxTextAttr_SetBackgroundColour, 1807).
+-define(wxTextAttr_SetFlags, 1808).
+-define(wxTextAttr_SetFont, 1809).
+-define(wxTextAttr_SetLeftIndent, 1810).
+-define(wxTextAttr_SetRightIndent, 1811).
+-define(wxTextAttr_SetTabs, 1812).
+-define(wxTextAttr_SetTextColour, 1813).
+-define(wxTextAttr_destroy, 1814).
+-define(wxTextCtrl_new_3, 1816).
+-define(wxTextCtrl_new_0, 1817).
+-define(wxTextCtrl_destruct, 1819).
+-define(wxTextCtrl_AppendText, 1820).
+-define(wxTextCtrl_CanCopy, 1821).
+-define(wxTextCtrl_CanCut, 1822).
+-define(wxTextCtrl_CanPaste, 1823).
+-define(wxTextCtrl_CanRedo, 1824).
+-define(wxTextCtrl_CanUndo, 1825).
+-define(wxTextCtrl_Clear, 1826).
+-define(wxTextCtrl_Copy, 1827).
+-define(wxTextCtrl_Create, 1828).
+-define(wxTextCtrl_Cut, 1829).
+-define(wxTextCtrl_DiscardEdits, 1830).
+-define(wxTextCtrl_ChangeValue, 1831).
+-define(wxTextCtrl_EmulateKeyPress, 1832).
+-define(wxTextCtrl_GetDefaultStyle, 1833).
+-define(wxTextCtrl_GetInsertionPoint, 1834).
+-define(wxTextCtrl_GetLastPosition, 1835).
+-define(wxTextCtrl_GetLineLength, 1836).
+-define(wxTextCtrl_GetLineText, 1837).
+-define(wxTextCtrl_GetNumberOfLines, 1838).
+-define(wxTextCtrl_GetRange, 1839).
+-define(wxTextCtrl_GetSelection, 1840).
+-define(wxTextCtrl_GetStringSelection, 1841).
+-define(wxTextCtrl_GetStyle, 1842).
+-define(wxTextCtrl_GetValue, 1843).
+-define(wxTextCtrl_IsEditable, 1844).
+-define(wxTextCtrl_IsModified, 1845).
+-define(wxTextCtrl_IsMultiLine, 1846).
+-define(wxTextCtrl_IsSingleLine, 1847).
+-define(wxTextCtrl_LoadFile, 1848).
+-define(wxTextCtrl_MarkDirty, 1849).
+-define(wxTextCtrl_Paste, 1850).
+-define(wxTextCtrl_PositionToXY, 1851).
+-define(wxTextCtrl_Redo, 1852).
+-define(wxTextCtrl_Remove, 1853).
+-define(wxTextCtrl_Replace, 1854).
+-define(wxTextCtrl_SaveFile, 1855).
+-define(wxTextCtrl_SetDefaultStyle, 1856).
+-define(wxTextCtrl_SetEditable, 1857).
+-define(wxTextCtrl_SetInsertionPoint, 1858).
+-define(wxTextCtrl_SetInsertionPointEnd, 1859).
+-define(wxTextCtrl_SetMaxLength, 1861).
+-define(wxTextCtrl_SetSelection, 1862).
+-define(wxTextCtrl_SetStyle, 1863).
+-define(wxTextCtrl_SetValue, 1864).
+-define(wxTextCtrl_ShowPosition, 1865).
+-define(wxTextCtrl_Undo, 1866).
+-define(wxTextCtrl_WriteText, 1867).
+-define(wxTextCtrl_XYToPosition, 1868).
+-define(wxNotebook_new_0, 1871).
+-define(wxNotebook_new_3, 1872).
+-define(wxNotebook_destruct, 1873).
+-define(wxNotebook_AddPage, 1874).
+-define(wxNotebook_AdvanceSelection, 1875).
+-define(wxNotebook_AssignImageList, 1876).
+-define(wxNotebook_Create, 1877).
+-define(wxNotebook_DeleteAllPages, 1878).
+-define(wxNotebook_DeletePage, 1879).
+-define(wxNotebook_RemovePage, 1880).
+-define(wxNotebook_GetCurrentPage, 1881).
+-define(wxNotebook_GetImageList, 1882).
+-define(wxNotebook_GetPage, 1884).
+-define(wxNotebook_GetPageCount, 1885).
+-define(wxNotebook_GetPageImage, 1886).
+-define(wxNotebook_GetPageText, 1887).
+-define(wxNotebook_GetRowCount, 1888).
+-define(wxNotebook_GetSelection, 1889).
+-define(wxNotebook_GetThemeBackgroundColour, 1890).
+-define(wxNotebook_HitTest, 1892).
+-define(wxNotebook_InsertPage, 1894).
+-define(wxNotebook_SetImageList, 1895).
+-define(wxNotebook_SetPadding, 1896).
+-define(wxNotebook_SetPageSize, 1897).
+-define(wxNotebook_SetPageImage, 1898).
+-define(wxNotebook_SetPageText, 1899).
+-define(wxNotebook_SetSelection, 1900).
+-define(wxNotebook_ChangeSelection, 1901).
+-define(wxChoicebook_new_0, 1902).
+-define(wxChoicebook_new_3, 1903).
+-define(wxChoicebook_AddPage, 1904).
+-define(wxChoicebook_AdvanceSelection, 1905).
+-define(wxChoicebook_AssignImageList, 1906).
+-define(wxChoicebook_Create, 1907).
+-define(wxChoicebook_DeleteAllPages, 1908).
+-define(wxChoicebook_DeletePage, 1909).
+-define(wxChoicebook_RemovePage, 1910).
+-define(wxChoicebook_GetCurrentPage, 1911).
+-define(wxChoicebook_GetImageList, 1912).
+-define(wxChoicebook_GetPage, 1914).
+-define(wxChoicebook_GetPageCount, 1915).
+-define(wxChoicebook_GetPageImage, 1916).
+-define(wxChoicebook_GetPageText, 1917).
+-define(wxChoicebook_GetSelection, 1918).
+-define(wxChoicebook_HitTest, 1919).
+-define(wxChoicebook_InsertPage, 1920).
+-define(wxChoicebook_SetImageList, 1921).
+-define(wxChoicebook_SetPageSize, 1922).
+-define(wxChoicebook_SetPageImage, 1923).
+-define(wxChoicebook_SetPageText, 1924).
+-define(wxChoicebook_SetSelection, 1925).
+-define(wxChoicebook_ChangeSelection, 1926).
+-define(wxChoicebook_destroy, 1927).
+-define(wxToolbook_new_0, 1928).
+-define(wxToolbook_new_3, 1929).
+-define(wxToolbook_AddPage, 1930).
+-define(wxToolbook_AdvanceSelection, 1931).
+-define(wxToolbook_AssignImageList, 1932).
+-define(wxToolbook_Create, 1933).
+-define(wxToolbook_DeleteAllPages, 1934).
+-define(wxToolbook_DeletePage, 1935).
+-define(wxToolbook_RemovePage, 1936).
+-define(wxToolbook_GetCurrentPage, 1937).
+-define(wxToolbook_GetImageList, 1938).
+-define(wxToolbook_GetPage, 1940).
+-define(wxToolbook_GetPageCount, 1941).
+-define(wxToolbook_GetPageImage, 1942).
+-define(wxToolbook_GetPageText, 1943).
+-define(wxToolbook_GetSelection, 1944).
+-define(wxToolbook_HitTest, 1946).
+-define(wxToolbook_InsertPage, 1947).
+-define(wxToolbook_SetImageList, 1948).
+-define(wxToolbook_SetPageSize, 1949).
+-define(wxToolbook_SetPageImage, 1950).
+-define(wxToolbook_SetPageText, 1951).
+-define(wxToolbook_SetSelection, 1952).
+-define(wxToolbook_ChangeSelection, 1953).
+-define(wxToolbook_destroy, 1954).
+-define(wxListbook_new_0, 1955).
+-define(wxListbook_new_3, 1956).
+-define(wxListbook_AddPage, 1957).
+-define(wxListbook_AdvanceSelection, 1958).
+-define(wxListbook_AssignImageList, 1959).
+-define(wxListbook_Create, 1960).
+-define(wxListbook_DeleteAllPages, 1961).
+-define(wxListbook_DeletePage, 1962).
+-define(wxListbook_RemovePage, 1963).
+-define(wxListbook_GetCurrentPage, 1964).
+-define(wxListbook_GetImageList, 1965).
+-define(wxListbook_GetPage, 1967).
+-define(wxListbook_GetPageCount, 1968).
+-define(wxListbook_GetPageImage, 1969).
+-define(wxListbook_GetPageText, 1970).
+-define(wxListbook_GetSelection, 1971).
+-define(wxListbook_HitTest, 1973).
+-define(wxListbook_InsertPage, 1974).
+-define(wxListbook_SetImageList, 1975).
+-define(wxListbook_SetPageSize, 1976).
+-define(wxListbook_SetPageImage, 1977).
+-define(wxListbook_SetPageText, 1978).
+-define(wxListbook_SetSelection, 1979).
+-define(wxListbook_ChangeSelection, 1980).
+-define(wxListbook_destroy, 1981).
+-define(wxTreebook_new_0, 1982).
+-define(wxTreebook_new_3, 1983).
+-define(wxTreebook_AddPage, 1984).
+-define(wxTreebook_AdvanceSelection, 1985).
+-define(wxTreebook_AssignImageList, 1986).
+-define(wxTreebook_Create, 1987).
+-define(wxTreebook_DeleteAllPages, 1988).
+-define(wxTreebook_DeletePage, 1989).
+-define(wxTreebook_RemovePage, 1990).
+-define(wxTreebook_GetCurrentPage, 1991).
+-define(wxTreebook_GetImageList, 1992).
+-define(wxTreebook_GetPage, 1994).
+-define(wxTreebook_GetPageCount, 1995).
+-define(wxTreebook_GetPageImage, 1996).
+-define(wxTreebook_GetPageText, 1997).
+-define(wxTreebook_GetSelection, 1998).
+-define(wxTreebook_ExpandNode, 1999).
+-define(wxTreebook_IsNodeExpanded, 2000).
+-define(wxTreebook_HitTest, 2002).
+-define(wxTreebook_InsertPage, 2003).
+-define(wxTreebook_InsertSubPage, 2004).
+-define(wxTreebook_SetImageList, 2005).
+-define(wxTreebook_SetPageSize, 2006).
+-define(wxTreebook_SetPageImage, 2007).
+-define(wxTreebook_SetPageText, 2008).
+-define(wxTreebook_SetSelection, 2009).
+-define(wxTreebook_ChangeSelection, 2010).
+-define(wxTreebook_destroy, 2011).
+-define(wxTreeCtrl_new_2, 2014).
+-define(wxTreeCtrl_new_0, 2015).
+-define(wxTreeCtrl_destruct, 2017).
+-define(wxTreeCtrl_AddRoot, 2018).
+-define(wxTreeCtrl_AppendItem, 2019).
+-define(wxTreeCtrl_AssignImageList, 2020).
+-define(wxTreeCtrl_AssignStateImageList, 2021).
+-define(wxTreeCtrl_Collapse, 2022).
+-define(wxTreeCtrl_CollapseAndReset, 2023).
+-define(wxTreeCtrl_Create, 2024).
+-define(wxTreeCtrl_Delete, 2025).
+-define(wxTreeCtrl_DeleteAllItems, 2026).
+-define(wxTreeCtrl_DeleteChildren, 2027).
+-define(wxTreeCtrl_EditLabel, 2028).
+-define(wxTreeCtrl_EnsureVisible, 2029).
+-define(wxTreeCtrl_Expand, 2030).
+-define(wxTreeCtrl_GetBoundingRect, 2031).
+-define(wxTreeCtrl_GetChildrenCount, 2033).
+-define(wxTreeCtrl_GetCount, 2034).
+-define(wxTreeCtrl_GetEditControl, 2035).
+-define(wxTreeCtrl_GetFirstChild, 2036).
+-define(wxTreeCtrl_GetNextChild, 2037).
+-define(wxTreeCtrl_GetFirstVisibleItem, 2038).
+-define(wxTreeCtrl_GetImageList, 2039).
+-define(wxTreeCtrl_GetIndent, 2040).
+-define(wxTreeCtrl_GetItemBackgroundColour, 2041).
+-define(wxTreeCtrl_GetItemData, 2042).
+-define(wxTreeCtrl_GetItemFont, 2043).
+-define(wxTreeCtrl_GetItemImage_1, 2044).
+-define(wxTreeCtrl_GetItemImage_2, 2045).
+-define(wxTreeCtrl_GetItemText, 2046).
+-define(wxTreeCtrl_GetItemTextColour, 2047).
+-define(wxTreeCtrl_GetLastChild, 2048).
+-define(wxTreeCtrl_GetNextSibling, 2049).
+-define(wxTreeCtrl_GetNextVisible, 2050).
+-define(wxTreeCtrl_GetItemParent, 2051).
+-define(wxTreeCtrl_GetPrevSibling, 2052).
+-define(wxTreeCtrl_GetPrevVisible, 2053).
+-define(wxTreeCtrl_GetRootItem, 2054).
+-define(wxTreeCtrl_GetSelection, 2055).
+-define(wxTreeCtrl_GetSelections, 2056).
+-define(wxTreeCtrl_GetStateImageList, 2057).
+-define(wxTreeCtrl_HitTest, 2058).
+-define(wxTreeCtrl_InsertItem, 2060).
+-define(wxTreeCtrl_IsBold, 2061).
+-define(wxTreeCtrl_IsExpanded, 2062).
+-define(wxTreeCtrl_IsSelected, 2063).
+-define(wxTreeCtrl_IsVisible, 2064).
+-define(wxTreeCtrl_ItemHasChildren, 2065).
+-define(wxTreeCtrl_IsTreeItemIdOk, 2066).
+-define(wxTreeCtrl_PrependItem, 2067).
+-define(wxTreeCtrl_ScrollTo, 2068).
+-define(wxTreeCtrl_SelectItem_1, 2069).
+-define(wxTreeCtrl_SelectItem_2, 2070).
+-define(wxTreeCtrl_SetIndent, 2071).
+-define(wxTreeCtrl_SetImageList, 2072).
+-define(wxTreeCtrl_SetItemBackgroundColour, 2073).
+-define(wxTreeCtrl_SetItemBold, 2074).
+-define(wxTreeCtrl_SetItemData, 2075).
+-define(wxTreeCtrl_SetItemDropHighlight, 2076).
+-define(wxTreeCtrl_SetItemFont, 2077).
+-define(wxTreeCtrl_SetItemHasChildren, 2078).
+-define(wxTreeCtrl_SetItemImage_2, 2079).
+-define(wxTreeCtrl_SetItemImage_3, 2080).
+-define(wxTreeCtrl_SetItemText, 2081).
+-define(wxTreeCtrl_SetItemTextColour, 2082).
+-define(wxTreeCtrl_SetStateImageList, 2083).
+-define(wxTreeCtrl_SetWindowStyle, 2084).
+-define(wxTreeCtrl_SortChildren, 2085).
+-define(wxTreeCtrl_Toggle, 2086).
+-define(wxTreeCtrl_ToggleItemSelection, 2087).
+-define(wxTreeCtrl_Unselect, 2088).
+-define(wxTreeCtrl_UnselectAll, 2089).
+-define(wxTreeCtrl_UnselectItem, 2090).
+-define(wxScrollBar_new_0, 2091).
+-define(wxScrollBar_new_3, 2092).
+-define(wxScrollBar_destruct, 2093).
+-define(wxScrollBar_Create, 2094).
+-define(wxScrollBar_GetRange, 2095).
+-define(wxScrollBar_GetPageSize, 2096).
+-define(wxScrollBar_GetThumbPosition, 2097).
+-define(wxScrollBar_GetThumbSize, 2098).
+-define(wxScrollBar_SetThumbPosition, 2099).
+-define(wxScrollBar_SetScrollbar, 2100).
+-define(wxSpinButton_new_2, 2102).
+-define(wxSpinButton_new_0, 2103).
+-define(wxSpinButton_Create, 2104).
+-define(wxSpinButton_GetMax, 2105).
+-define(wxSpinButton_GetMin, 2106).
+-define(wxSpinButton_GetValue, 2107).
+-define(wxSpinButton_SetRange, 2108).
+-define(wxSpinButton_SetValue, 2109).
+-define(wxSpinButton_destroy, 2110).
+-define(wxSpinCtrl_new_0, 2111).
+-define(wxSpinCtrl_new_2, 2112).
+-define(wxSpinCtrl_Create, 2114).
+-define(wxSpinCtrl_SetValue_1_1, 2117).
+-define(wxSpinCtrl_SetValue_1_0, 2118).
+-define(wxSpinCtrl_GetValue, 2120).
+-define(wxSpinCtrl_SetRange, 2122).
+-define(wxSpinCtrl_SetSelection, 2123).
+-define(wxSpinCtrl_GetMin, 2125).
+-define(wxSpinCtrl_GetMax, 2127).
+-define(wxSpinCtrl_destroy, 2128).
+-define(wxStaticText_new_0, 2129).
+-define(wxStaticText_new_4, 2130).
+-define(wxStaticText_Create, 2131).
+-define(wxStaticText_GetLabel, 2132).
+-define(wxStaticText_SetLabel, 2133).
+-define(wxStaticText_Wrap, 2134).
+-define(wxStaticText_destroy, 2135).
+-define(wxStaticBitmap_new_0, 2136).
+-define(wxStaticBitmap_new_4, 2137).
+-define(wxStaticBitmap_Create, 2138).
+-define(wxStaticBitmap_GetBitmap, 2139).
+-define(wxStaticBitmap_SetBitmap, 2140).
+-define(wxStaticBitmap_destroy, 2141).
+-define(wxRadioBox_new, 2142).
+-define(wxRadioBox_destruct, 2144).
+-define(wxRadioBox_Create, 2145).
+-define(wxRadioBox_Enable_2, 2146).
+-define(wxRadioBox_Enable_1, 2147).
+-define(wxRadioBox_GetSelection, 2148).
+-define(wxRadioBox_GetString, 2149).
+-define(wxRadioBox_SetSelection, 2150).
+-define(wxRadioBox_Show_2, 2151).
+-define(wxRadioBox_Show_1, 2152).
+-define(wxRadioBox_GetColumnCount, 2153).
+-define(wxRadioBox_GetItemHelpText, 2154).
+-define(wxRadioBox_GetItemToolTip, 2155).
+-define(wxRadioBox_GetItemFromPoint, 2157).
+-define(wxRadioBox_GetRowCount, 2158).
+-define(wxRadioBox_IsItemEnabled, 2159).
+-define(wxRadioBox_IsItemShown, 2160).
+-define(wxRadioBox_SetItemHelpText, 2161).
+-define(wxRadioBox_SetItemToolTip, 2162).
+-define(wxRadioButton_new_0, 2163).
+-define(wxRadioButton_new_4, 2164).
+-define(wxRadioButton_Create, 2165).
+-define(wxRadioButton_GetValue, 2166).
+-define(wxRadioButton_SetValue, 2167).
+-define(wxRadioButton_destroy, 2168).
+-define(wxSlider_new_6, 2170).
+-define(wxSlider_new_0, 2171).
+-define(wxSlider_Create, 2172).
+-define(wxSlider_GetLineSize, 2173).
+-define(wxSlider_GetMax, 2174).
+-define(wxSlider_GetMin, 2175).
+-define(wxSlider_GetPageSize, 2176).
+-define(wxSlider_GetThumbLength, 2177).
+-define(wxSlider_GetValue, 2178).
+-define(wxSlider_SetLineSize, 2179).
+-define(wxSlider_SetPageSize, 2180).
+-define(wxSlider_SetRange, 2181).
+-define(wxSlider_SetThumbLength, 2182).
+-define(wxSlider_SetValue, 2183).
+-define(wxSlider_destroy, 2184).
+-define(wxDialog_new_4, 2186).
+-define(wxDialog_new_0, 2187).
+-define(wxDialog_destruct, 2189).
+-define(wxDialog_Create, 2190).
+-define(wxDialog_CreateButtonSizer, 2191).
+-define(wxDialog_CreateStdDialogButtonSizer, 2192).
+-define(wxDialog_EndModal, 2193).
+-define(wxDialog_GetAffirmativeId, 2194).
+-define(wxDialog_GetReturnCode, 2195).
+-define(wxDialog_IsModal, 2196).
+-define(wxDialog_SetAffirmativeId, 2197).
+-define(wxDialog_SetReturnCode, 2198).
+-define(wxDialog_Show, 2199).
+-define(wxDialog_ShowModal, 2200).
+-define(wxColourDialog_new_0, 2201).
+-define(wxColourDialog_new_2, 2202).
+-define(wxColourDialog_destruct, 2203).
+-define(wxColourDialog_Create, 2204).
+-define(wxColourDialog_GetColourData, 2205).
+-define(wxColourData_new_0, 2206).
+-define(wxColourData_new_1, 2207).
+-define(wxColourData_destruct, 2208).
+-define(wxColourData_GetChooseFull, 2209).
+-define(wxColourData_GetColour, 2210).
+-define(wxColourData_GetCustomColour, 2212).
+-define(wxColourData_SetChooseFull, 2213).
+-define(wxColourData_SetColour, 2214).
+-define(wxColourData_SetCustomColour, 2215).
+-define(wxPalette_new_0, 2216).
+-define(wxPalette_new_4, 2217).
+-define(wxPalette_destruct, 2219).
+-define(wxPalette_Create, 2220).
+-define(wxPalette_GetColoursCount, 2221).
+-define(wxPalette_GetPixel, 2222).
+-define(wxPalette_GetRGB, 2223).
+-define(wxPalette_IsOk, 2224).
+-define(wxDirDialog_new, 2228).
+-define(wxDirDialog_destruct, 2229).
+-define(wxDirDialog_GetPath, 2230).
+-define(wxDirDialog_GetMessage, 2231).
+-define(wxDirDialog_SetMessage, 2232).
+-define(wxDirDialog_SetPath, 2233).
+-define(wxFileDialog_new, 2237).
+-define(wxFileDialog_destruct, 2238).
+-define(wxFileDialog_GetDirectory, 2239).
+-define(wxFileDialog_GetFilename, 2240).
+-define(wxFileDialog_GetFilenames, 2241).
+-define(wxFileDialog_GetFilterIndex, 2242).
+-define(wxFileDialog_GetMessage, 2243).
+-define(wxFileDialog_GetPath, 2244).
+-define(wxFileDialog_GetPaths, 2245).
+-define(wxFileDialog_GetWildcard, 2246).
+-define(wxFileDialog_SetDirectory, 2247).
+-define(wxFileDialog_SetFilename, 2248).
+-define(wxFileDialog_SetFilterIndex, 2249).
+-define(wxFileDialog_SetMessage, 2250).
+-define(wxFileDialog_SetPath, 2251).
+-define(wxFileDialog_SetWildcard, 2252).
+-define(wxPickerBase_SetInternalMargin, 2253).
+-define(wxPickerBase_GetInternalMargin, 2254).
+-define(wxPickerBase_SetTextCtrlProportion, 2255).
+-define(wxPickerBase_SetPickerCtrlProportion, 2256).
+-define(wxPickerBase_GetTextCtrlProportion, 2257).
+-define(wxPickerBase_GetPickerCtrlProportion, 2258).
+-define(wxPickerBase_HasTextCtrl, 2259).
+-define(wxPickerBase_GetTextCtrl, 2260).
+-define(wxPickerBase_IsTextCtrlGrowable, 2261).
+-define(wxPickerBase_SetPickerCtrlGrowable, 2262).
+-define(wxPickerBase_SetTextCtrlGrowable, 2263).
+-define(wxPickerBase_IsPickerCtrlGrowable, 2264).
+-define(wxFilePickerCtrl_new_0, 2265).
+-define(wxFilePickerCtrl_new_3, 2266).
+-define(wxFilePickerCtrl_Create, 2267).
+-define(wxFilePickerCtrl_GetPath, 2268).
+-define(wxFilePickerCtrl_SetPath, 2269).
+-define(wxFilePickerCtrl_destroy, 2270).
+-define(wxDirPickerCtrl_new_0, 2271).
+-define(wxDirPickerCtrl_new_3, 2272).
+-define(wxDirPickerCtrl_Create, 2273).
+-define(wxDirPickerCtrl_GetPath, 2274).
+-define(wxDirPickerCtrl_SetPath, 2275).
+-define(wxDirPickerCtrl_destroy, 2276).
+-define(wxColourPickerCtrl_new_0, 2277).
+-define(wxColourPickerCtrl_new_3, 2278).
+-define(wxColourPickerCtrl_Create, 2279).
+-define(wxColourPickerCtrl_GetColour, 2280).
+-define(wxColourPickerCtrl_SetColour_1_1, 2281).
+-define(wxColourPickerCtrl_SetColour_1_0, 2282).
+-define(wxColourPickerCtrl_destroy, 2283).
+-define(wxDatePickerCtrl_new_0, 2284).
+-define(wxDatePickerCtrl_new_3, 2285).
+-define(wxDatePickerCtrl_GetRange, 2286).
+-define(wxDatePickerCtrl_GetValue, 2287).
+-define(wxDatePickerCtrl_SetRange, 2288).
+-define(wxDatePickerCtrl_SetValue, 2289).
+-define(wxDatePickerCtrl_destroy, 2290).
+-define(wxFontPickerCtrl_new_0, 2291).
+-define(wxFontPickerCtrl_new_3, 2292).
+-define(wxFontPickerCtrl_Create, 2293).
+-define(wxFontPickerCtrl_GetSelectedFont, 2294).
+-define(wxFontPickerCtrl_SetSelectedFont, 2295).
+-define(wxFontPickerCtrl_GetMaxPointSize, 2296).
+-define(wxFontPickerCtrl_SetMaxPointSize, 2297).
+-define(wxFontPickerCtrl_destroy, 2298).
+-define(wxFindReplaceDialog_new_0, 2301).
+-define(wxFindReplaceDialog_new_4, 2302).
+-define(wxFindReplaceDialog_destruct, 2303).
+-define(wxFindReplaceDialog_Create, 2304).
+-define(wxFindReplaceDialog_GetData, 2305).
+-define(wxFindReplaceData_new_0, 2306).
+-define(wxFindReplaceData_new_1, 2307).
+-define(wxFindReplaceData_GetFindString, 2308).
+-define(wxFindReplaceData_GetReplaceString, 2309).
+-define(wxFindReplaceData_GetFlags, 2310).
+-define(wxFindReplaceData_SetFlags, 2311).
+-define(wxFindReplaceData_SetFindString, 2312).
+-define(wxFindReplaceData_SetReplaceString, 2313).
+-define(wxFindReplaceData_destroy, 2314).
+-define(wxMultiChoiceDialog_new_0, 2315).
+-define(wxMultiChoiceDialog_new_5, 2317).
+-define(wxMultiChoiceDialog_GetSelections, 2318).
+-define(wxMultiChoiceDialog_SetSelections, 2319).
+-define(wxMultiChoiceDialog_destroy, 2320).
+-define(wxSingleChoiceDialog_new_0, 2321).
+-define(wxSingleChoiceDialog_new_5, 2323).
+-define(wxSingleChoiceDialog_GetSelection, 2324).
+-define(wxSingleChoiceDialog_GetStringSelection, 2325).
+-define(wxSingleChoiceDialog_SetSelection, 2326).
+-define(wxSingleChoiceDialog_destroy, 2327).
+-define(wxTextEntryDialog_new, 2328).
+-define(wxTextEntryDialog_GetValue, 2329).
+-define(wxTextEntryDialog_SetValue, 2330).
+-define(wxTextEntryDialog_destroy, 2331).
+-define(wxPasswordEntryDialog_new, 2332).
+-define(wxPasswordEntryDialog_destroy, 2333).
+-define(wxFontData_new_0, 2334).
+-define(wxFontData_new_1, 2335).
+-define(wxFontData_destruct, 2336).
+-define(wxFontData_EnableEffects, 2337).
+-define(wxFontData_GetAllowSymbols, 2338).
+-define(wxFontData_GetColour, 2339).
+-define(wxFontData_GetChosenFont, 2340).
+-define(wxFontData_GetEnableEffects, 2341).
+-define(wxFontData_GetInitialFont, 2342).
+-define(wxFontData_GetShowHelp, 2343).
+-define(wxFontData_SetAllowSymbols, 2344).
+-define(wxFontData_SetChosenFont, 2345).
+-define(wxFontData_SetColour, 2346).
+-define(wxFontData_SetInitialFont, 2347).
+-define(wxFontData_SetRange, 2348).
+-define(wxFontData_SetShowHelp, 2349).
+-define(wxFontDialog_new_0, 2353).
+-define(wxFontDialog_new_2, 2355).
+-define(wxFontDialog_Create, 2357).
+-define(wxFontDialog_GetFontData, 2358).
+-define(wxFontDialog_destroy, 2360).
+-define(wxProgressDialog_new, 2361).
+-define(wxProgressDialog_destruct, 2362).
+-define(wxProgressDialog_Resume, 2363).
+-define(wxProgressDialog_Update_2, 2364).
+-define(wxProgressDialog_Update_0, 2365).
+-define(wxMessageDialog_new, 2366).
+-define(wxMessageDialog_destruct, 2367).
+-define(wxPageSetupDialog_new, 2368).
+-define(wxPageSetupDialog_destruct, 2369).
+-define(wxPageSetupDialog_GetPageSetupData, 2370).
+-define(wxPageSetupDialog_ShowModal, 2371).
+-define(wxPageSetupDialogData_new_0, 2372).
+-define(wxPageSetupDialogData_new_1_0, 2373).
+-define(wxPageSetupDialogData_new_1_1, 2374).
+-define(wxPageSetupDialogData_destruct, 2375).
+-define(wxPageSetupDialogData_EnableHelp, 2376).
+-define(wxPageSetupDialogData_EnableMargins, 2377).
+-define(wxPageSetupDialogData_EnableOrientation, 2378).
+-define(wxPageSetupDialogData_EnablePaper, 2379).
+-define(wxPageSetupDialogData_EnablePrinter, 2380).
+-define(wxPageSetupDialogData_GetDefaultMinMargins, 2381).
+-define(wxPageSetupDialogData_GetEnableMargins, 2382).
+-define(wxPageSetupDialogData_GetEnableOrientation, 2383).
+-define(wxPageSetupDialogData_GetEnablePaper, 2384).
+-define(wxPageSetupDialogData_GetEnablePrinter, 2385).
+-define(wxPageSetupDialogData_GetEnableHelp, 2386).
+-define(wxPageSetupDialogData_GetDefaultInfo, 2387).
+-define(wxPageSetupDialogData_GetMarginTopLeft, 2388).
+-define(wxPageSetupDialogData_GetMarginBottomRight, 2389).
+-define(wxPageSetupDialogData_GetMinMarginTopLeft, 2390).
+-define(wxPageSetupDialogData_GetMinMarginBottomRight, 2391).
+-define(wxPageSetupDialogData_GetPaperId, 2392).
+-define(wxPageSetupDialogData_GetPaperSize, 2393).
+-define(wxPageSetupDialogData_GetPrintData, 2395).
+-define(wxPageSetupDialogData_IsOk, 2396).
+-define(wxPageSetupDialogData_SetDefaultInfo, 2397).
+-define(wxPageSetupDialogData_SetDefaultMinMargins, 2398).
+-define(wxPageSetupDialogData_SetMarginTopLeft, 2399).
+-define(wxPageSetupDialogData_SetMarginBottomRight, 2400).
+-define(wxPageSetupDialogData_SetMinMarginTopLeft, 2401).
+-define(wxPageSetupDialogData_SetMinMarginBottomRight, 2402).
+-define(wxPageSetupDialogData_SetPaperId, 2403).
+-define(wxPageSetupDialogData_SetPaperSize_1_1, 2404).
+-define(wxPageSetupDialogData_SetPaperSize_1_0, 2405).
+-define(wxPageSetupDialogData_SetPrintData, 2406).
+-define(wxPrintDialog_new_2_0, 2407).
+-define(wxPrintDialog_new_2_1, 2408).
+-define(wxPrintDialog_destruct, 2409).
+-define(wxPrintDialog_GetPrintDialogData, 2410).
+-define(wxPrintDialog_GetPrintDC, 2411).
+-define(wxPrintDialogData_new_0, 2412).
+-define(wxPrintDialogData_new_1_1, 2413).
+-define(wxPrintDialogData_new_1_0, 2414).
+-define(wxPrintDialogData_destruct, 2415).
+-define(wxPrintDialogData_EnableHelp, 2416).
+-define(wxPrintDialogData_EnablePageNumbers, 2417).
+-define(wxPrintDialogData_EnablePrintToFile, 2418).
+-define(wxPrintDialogData_EnableSelection, 2419).
+-define(wxPrintDialogData_GetAllPages, 2420).
+-define(wxPrintDialogData_GetCollate, 2421).
+-define(wxPrintDialogData_GetFromPage, 2422).
+-define(wxPrintDialogData_GetMaxPage, 2423).
+-define(wxPrintDialogData_GetMinPage, 2424).
+-define(wxPrintDialogData_GetNoCopies, 2425).
+-define(wxPrintDialogData_GetPrintData, 2426).
+-define(wxPrintDialogData_GetPrintToFile, 2427).
+-define(wxPrintDialogData_GetSelection, 2428).
+-define(wxPrintDialogData_GetToPage, 2429).
+-define(wxPrintDialogData_IsOk, 2430).
+-define(wxPrintDialogData_SetCollate, 2431).
+-define(wxPrintDialogData_SetFromPage, 2432).
+-define(wxPrintDialogData_SetMaxPage, 2433).
+-define(wxPrintDialogData_SetMinPage, 2434).
+-define(wxPrintDialogData_SetNoCopies, 2435).
+-define(wxPrintDialogData_SetPrintData, 2436).
+-define(wxPrintDialogData_SetPrintToFile, 2437).
+-define(wxPrintDialogData_SetSelection, 2438).
+-define(wxPrintDialogData_SetToPage, 2439).
+-define(wxPrintData_new_0, 2440).
+-define(wxPrintData_new_1, 2441).
+-define(wxPrintData_destruct, 2442).
+-define(wxPrintData_GetCollate, 2443).
+-define(wxPrintData_GetBin, 2444).
+-define(wxPrintData_GetColour, 2445).
+-define(wxPrintData_GetDuplex, 2446).
+-define(wxPrintData_GetNoCopies, 2447).
+-define(wxPrintData_GetOrientation, 2448).
+-define(wxPrintData_GetPaperId, 2449).
+-define(wxPrintData_GetPrinterName, 2450).
+-define(wxPrintData_GetQuality, 2451).
+-define(wxPrintData_IsOk, 2452).
+-define(wxPrintData_SetBin, 2453).
+-define(wxPrintData_SetCollate, 2454).
+-define(wxPrintData_SetColour, 2455).
+-define(wxPrintData_SetDuplex, 2456).
+-define(wxPrintData_SetNoCopies, 2457).
+-define(wxPrintData_SetOrientation, 2458).
+-define(wxPrintData_SetPaperId, 2459).
+-define(wxPrintData_SetPrinterName, 2460).
+-define(wxPrintData_SetQuality, 2461).
+-define(wxPrintPreview_new_2, 2464).
+-define(wxPrintPreview_new_3, 2465).
+-define(wxPrintPreview_destruct, 2467).
+-define(wxPrintPreview_GetCanvas, 2468).
+-define(wxPrintPreview_GetCurrentPage, 2469).
+-define(wxPrintPreview_GetFrame, 2470).
+-define(wxPrintPreview_GetMaxPage, 2471).
+-define(wxPrintPreview_GetMinPage, 2472).
+-define(wxPrintPreview_GetPrintout, 2473).
+-define(wxPrintPreview_GetPrintoutForPrinting, 2474).
+-define(wxPrintPreview_IsOk, 2475).
+-define(wxPrintPreview_PaintPage, 2476).
+-define(wxPrintPreview_Print, 2477).
+-define(wxPrintPreview_RenderPage, 2478).
+-define(wxPrintPreview_SetCanvas, 2479).
+-define(wxPrintPreview_SetCurrentPage, 2480).
+-define(wxPrintPreview_SetFrame, 2481).
+-define(wxPrintPreview_SetPrintout, 2482).
+-define(wxPrintPreview_SetZoom, 2483).
+-define(wxPreviewFrame_new, 2484).
+-define(wxPreviewFrame_destruct, 2485).
+-define(wxPreviewFrame_CreateControlBar, 2486).
+-define(wxPreviewFrame_CreateCanvas, 2487).
+-define(wxPreviewFrame_Initialize, 2488).
+-define(wxPreviewFrame_OnCloseWindow, 2489).
+-define(wxPreviewControlBar_new, 2490).
+-define(wxPreviewControlBar_destruct, 2491).
+-define(wxPreviewControlBar_CreateButtons, 2492).
+-define(wxPreviewControlBar_GetPrintPreview, 2493).
+-define(wxPreviewControlBar_GetZoomControl, 2494).
+-define(wxPreviewControlBar_SetZoomControl, 2495).
+-define(wxPrinter_new, 2497).
+-define(wxPrinter_CreateAbortWindow, 2498).
+-define(wxPrinter_GetAbort, 2499).
+-define(wxPrinter_GetLastError, 2500).
+-define(wxPrinter_GetPrintDialogData, 2501).
+-define(wxPrinter_Print, 2502).
+-define(wxPrinter_PrintDialog, 2503).
+-define(wxPrinter_ReportError, 2504).
+-define(wxPrinter_Setup, 2505).
+-define(wxPrinter_destroy, 2506).
+-define(wxXmlResource_new_1, 2507).
+-define(wxXmlResource_new_2, 2508).
+-define(wxXmlResource_destruct, 2509).
+-define(wxXmlResource_AttachUnknownControl, 2510).
+-define(wxXmlResource_ClearHandlers, 2511).
+-define(wxXmlResource_CompareVersion, 2512).
+-define(wxXmlResource_Get, 2513).
+-define(wxXmlResource_GetFlags, 2514).
+-define(wxXmlResource_GetVersion, 2515).
+-define(wxXmlResource_GetXRCID, 2516).
+-define(wxXmlResource_InitAllHandlers, 2517).
+-define(wxXmlResource_Load, 2518).
+-define(wxXmlResource_LoadBitmap, 2519).
+-define(wxXmlResource_LoadDialog_2, 2520).
+-define(wxXmlResource_LoadDialog_3, 2521).
+-define(wxXmlResource_LoadFrame_2, 2522).
+-define(wxXmlResource_LoadFrame_3, 2523).
+-define(wxXmlResource_LoadIcon, 2524).
+-define(wxXmlResource_LoadMenu, 2525).
+-define(wxXmlResource_LoadMenuBar_2, 2526).
+-define(wxXmlResource_LoadMenuBar_1, 2527).
+-define(wxXmlResource_LoadPanel_2, 2528).
+-define(wxXmlResource_LoadPanel_3, 2529).
+-define(wxXmlResource_LoadToolBar, 2530).
+-define(wxXmlResource_Set, 2531).
+-define(wxXmlResource_SetFlags, 2532).
+-define(wxXmlResource_Unload, 2533).
+-define(wxXmlResource_xrcctrl, 2534).
+-define(wxHtmlEasyPrinting_new, 2535).
+-define(wxHtmlEasyPrinting_destruct, 2536).
+-define(wxHtmlEasyPrinting_GetPrintData, 2537).
+-define(wxHtmlEasyPrinting_GetPageSetupData, 2538).
+-define(wxHtmlEasyPrinting_PreviewFile, 2539).
+-define(wxHtmlEasyPrinting_PreviewText, 2540).
+-define(wxHtmlEasyPrinting_PrintFile, 2541).
+-define(wxHtmlEasyPrinting_PrintText, 2542).
+-define(wxHtmlEasyPrinting_PageSetup, 2543).
+-define(wxHtmlEasyPrinting_SetFonts, 2544).
+-define(wxHtmlEasyPrinting_SetHeader, 2545).
+-define(wxHtmlEasyPrinting_SetFooter, 2546).
+-define(wxGLCanvas_new_2, 2548).
+-define(wxGLCanvas_new_3_1, 2549).
+-define(wxGLCanvas_new_3_0, 2550).
+-define(wxGLCanvas_GetContext, 2551).
+-define(wxGLCanvas_SetCurrent, 2553).
+-define(wxGLCanvas_SwapBuffers, 2554).
+-define(wxGLCanvas_destroy, 2555).
+-define(wxAuiManager_new, 2556).
+-define(wxAuiManager_destruct, 2557).
+-define(wxAuiManager_AddPane_2_1, 2558).
+-define(wxAuiManager_AddPane_3, 2559).
+-define(wxAuiManager_AddPane_2_0, 2560).
+-define(wxAuiManager_DetachPane, 2561).
+-define(wxAuiManager_GetAllPanes, 2562).
+-define(wxAuiManager_GetArtProvider, 2563).
+-define(wxAuiManager_GetDockSizeConstraint, 2564).
+-define(wxAuiManager_GetFlags, 2565).
+-define(wxAuiManager_GetManagedWindow, 2566).
+-define(wxAuiManager_GetManager, 2567).
+-define(wxAuiManager_GetPane_1_1, 2568).
+-define(wxAuiManager_GetPane_1_0, 2569).
+-define(wxAuiManager_HideHint, 2570).
+-define(wxAuiManager_InsertPane, 2571).
+-define(wxAuiManager_LoadPaneInfo, 2572).
+-define(wxAuiManager_LoadPerspective, 2573).
+-define(wxAuiManager_SavePaneInfo, 2574).
+-define(wxAuiManager_SavePerspective, 2575).
+-define(wxAuiManager_SetArtProvider, 2576).
+-define(wxAuiManager_SetDockSizeConstraint, 2577).
+-define(wxAuiManager_SetFlags, 2578).
+-define(wxAuiManager_SetManagedWindow, 2579).
+-define(wxAuiManager_ShowHint, 2580).
+-define(wxAuiManager_UnInit, 2581).
+-define(wxAuiManager_Update, 2582).
+-define(wxAuiPaneInfo_new_0, 2583).
+-define(wxAuiPaneInfo_new_1, 2584).
+-define(wxAuiPaneInfo_destruct, 2585).
+-define(wxAuiPaneInfo_BestSize_1, 2586).
+-define(wxAuiPaneInfo_BestSize_2, 2587).
+-define(wxAuiPaneInfo_Bottom, 2588).
+-define(wxAuiPaneInfo_BottomDockable, 2589).
+-define(wxAuiPaneInfo_Caption, 2590).
+-define(wxAuiPaneInfo_CaptionVisible, 2591).
+-define(wxAuiPaneInfo_Centre, 2592).
+-define(wxAuiPaneInfo_CentrePane, 2593).
+-define(wxAuiPaneInfo_CloseButton, 2594).
+-define(wxAuiPaneInfo_DefaultPane, 2595).
+-define(wxAuiPaneInfo_DestroyOnClose, 2596).
+-define(wxAuiPaneInfo_Direction, 2597).
+-define(wxAuiPaneInfo_Dock, 2598).
+-define(wxAuiPaneInfo_Dockable, 2599).
+-define(wxAuiPaneInfo_Fixed, 2600).
+-define(wxAuiPaneInfo_Float, 2601).
+-define(wxAuiPaneInfo_Floatable, 2602).
+-define(wxAuiPaneInfo_FloatingPosition_1, 2603).
+-define(wxAuiPaneInfo_FloatingPosition_2, 2604).
+-define(wxAuiPaneInfo_FloatingSize_1, 2605).
+-define(wxAuiPaneInfo_FloatingSize_2, 2606).
+-define(wxAuiPaneInfo_Gripper, 2607).
+-define(wxAuiPaneInfo_GripperTop, 2608).
+-define(wxAuiPaneInfo_HasBorder, 2609).
+-define(wxAuiPaneInfo_HasCaption, 2610).
+-define(wxAuiPaneInfo_HasCloseButton, 2611).
+-define(wxAuiPaneInfo_HasFlag, 2612).
+-define(wxAuiPaneInfo_HasGripper, 2613).
+-define(wxAuiPaneInfo_HasGripperTop, 2614).
+-define(wxAuiPaneInfo_HasMaximizeButton, 2615).
+-define(wxAuiPaneInfo_HasMinimizeButton, 2616).
+-define(wxAuiPaneInfo_HasPinButton, 2617).
+-define(wxAuiPaneInfo_Hide, 2618).
+-define(wxAuiPaneInfo_IsBottomDockable, 2619).
+-define(wxAuiPaneInfo_IsDocked, 2620).
+-define(wxAuiPaneInfo_IsFixed, 2621).
+-define(wxAuiPaneInfo_IsFloatable, 2622).
+-define(wxAuiPaneInfo_IsFloating, 2623).
+-define(wxAuiPaneInfo_IsLeftDockable, 2624).
+-define(wxAuiPaneInfo_IsMovable, 2625).
+-define(wxAuiPaneInfo_IsOk, 2626).
+-define(wxAuiPaneInfo_IsResizable, 2627).
+-define(wxAuiPaneInfo_IsRightDockable, 2628).
+-define(wxAuiPaneInfo_IsShown, 2629).
+-define(wxAuiPaneInfo_IsToolbar, 2630).
+-define(wxAuiPaneInfo_IsTopDockable, 2631).
+-define(wxAuiPaneInfo_Layer, 2632).
+-define(wxAuiPaneInfo_Left, 2633).
+-define(wxAuiPaneInfo_LeftDockable, 2634).
+-define(wxAuiPaneInfo_MaxSize_1, 2635).
+-define(wxAuiPaneInfo_MaxSize_2, 2636).
+-define(wxAuiPaneInfo_MaximizeButton, 2637).
+-define(wxAuiPaneInfo_MinSize_1, 2638).
+-define(wxAuiPaneInfo_MinSize_2, 2639).
+-define(wxAuiPaneInfo_MinimizeButton, 2640).
+-define(wxAuiPaneInfo_Movable, 2641).
+-define(wxAuiPaneInfo_Name, 2642).
+-define(wxAuiPaneInfo_PaneBorder, 2643).
+-define(wxAuiPaneInfo_PinButton, 2644).
+-define(wxAuiPaneInfo_Position, 2645).
+-define(wxAuiPaneInfo_Resizable, 2646).
+-define(wxAuiPaneInfo_Right, 2647).
+-define(wxAuiPaneInfo_RightDockable, 2648).
+-define(wxAuiPaneInfo_Row, 2649).
+-define(wxAuiPaneInfo_SafeSet, 2650).
+-define(wxAuiPaneInfo_SetFlag, 2651).
+-define(wxAuiPaneInfo_Show, 2652).
+-define(wxAuiPaneInfo_ToolbarPane, 2653).
+-define(wxAuiPaneInfo_Top, 2654).
+-define(wxAuiPaneInfo_TopDockable, 2655).
+-define(wxAuiPaneInfo_Window, 2656).
+-define(wxAuiPaneInfo_GetWindow, 2657).
+-define(wxAuiPaneInfo_GetFrame, 2658).
+-define(wxAuiPaneInfo_GetDirection, 2659).
+-define(wxAuiPaneInfo_GetLayer, 2660).
+-define(wxAuiPaneInfo_GetRow, 2661).
+-define(wxAuiPaneInfo_GetPosition, 2662).
+-define(wxAuiPaneInfo_GetFloatingPosition, 2663).
+-define(wxAuiPaneInfo_GetFloatingSize, 2664).
+-define(wxAuiNotebook_new_0, 2665).
+-define(wxAuiNotebook_new_2, 2666).
+-define(wxAuiNotebook_AddPage, 2667).
+-define(wxAuiNotebook_Create, 2668).
+-define(wxAuiNotebook_DeletePage, 2669).
+-define(wxAuiNotebook_GetArtProvider, 2670).
+-define(wxAuiNotebook_GetPage, 2671).
+-define(wxAuiNotebook_GetPageBitmap, 2672).
+-define(wxAuiNotebook_GetPageCount, 2673).
+-define(wxAuiNotebook_GetPageIndex, 2674).
+-define(wxAuiNotebook_GetPageText, 2675).
+-define(wxAuiNotebook_GetSelection, 2676).
+-define(wxAuiNotebook_InsertPage, 2677).
+-define(wxAuiNotebook_RemovePage, 2678).
+-define(wxAuiNotebook_SetArtProvider, 2679).
+-define(wxAuiNotebook_SetFont, 2680).
+-define(wxAuiNotebook_SetPageBitmap, 2681).
+-define(wxAuiNotebook_SetPageText, 2682).
+-define(wxAuiNotebook_SetSelection, 2683).
+-define(wxAuiNotebook_SetTabCtrlHeight, 2684).
+-define(wxAuiNotebook_SetUniformBitmapSize, 2685).
+-define(wxAuiNotebook_destroy, 2686).
+-define(wxAuiTabArt_SetFlags, 2687).
+-define(wxAuiTabArt_SetMeasuringFont, 2688).
+-define(wxAuiTabArt_SetNormalFont, 2689).
+-define(wxAuiTabArt_SetSelectedFont, 2690).
+-define(wxAuiTabArt_SetColour, 2691).
+-define(wxAuiTabArt_SetActiveColour, 2692).
+-define(wxAuiDockArt_GetColour, 2693).
+-define(wxAuiDockArt_GetFont, 2694).
+-define(wxAuiDockArt_GetMetric, 2695).
+-define(wxAuiDockArt_SetColour, 2696).
+-define(wxAuiDockArt_SetFont, 2697).
+-define(wxAuiDockArt_SetMetric, 2698).
+-define(wxAuiSimpleTabArt_new, 2699).
+-define(wxAuiSimpleTabArt_destroy, 2700).
+-define(wxMDIParentFrame_new_0, 2701).
+-define(wxMDIParentFrame_new_4, 2702).
+-define(wxMDIParentFrame_destruct, 2703).
+-define(wxMDIParentFrame_ActivateNext, 2704).
+-define(wxMDIParentFrame_ActivatePrevious, 2705).
+-define(wxMDIParentFrame_ArrangeIcons, 2706).
+-define(wxMDIParentFrame_Cascade, 2707).
+-define(wxMDIParentFrame_Create, 2708).
+-define(wxMDIParentFrame_GetActiveChild, 2709).
+-define(wxMDIParentFrame_GetClientWindow, 2710).
+-define(wxMDIParentFrame_Tile, 2711).
+-define(wxMDIChildFrame_new_0, 2712).
+-define(wxMDIChildFrame_new_4, 2713).
+-define(wxMDIChildFrame_destruct, 2714).
+-define(wxMDIChildFrame_Activate, 2715).
+-define(wxMDIChildFrame_Create, 2716).
+-define(wxMDIChildFrame_Maximize, 2717).
+-define(wxMDIChildFrame_Restore, 2718).
+-define(wxMDIClientWindow_new_0, 2719).
+-define(wxMDIClientWindow_new_2, 2720).
+-define(wxMDIClientWindow_destruct, 2721).
+-define(wxMDIClientWindow_CreateClient, 2722).
+-define(wxLayoutAlgorithm_new, 2723).
+-define(wxLayoutAlgorithm_LayoutFrame, 2724).
+-define(wxLayoutAlgorithm_LayoutMDIFrame, 2725).
+-define(wxLayoutAlgorithm_LayoutWindow, 2726).
+-define(wxLayoutAlgorithm_destroy, 2727).
+-define(wxEvent_GetId, 2728).
+-define(wxEvent_GetSkipped, 2729).
+-define(wxEvent_GetTimestamp, 2730).
+-define(wxEvent_IsCommandEvent, 2731).
+-define(wxEvent_ResumePropagation, 2732).
+-define(wxEvent_ShouldPropagate, 2733).
+-define(wxEvent_Skip, 2734).
+-define(wxEvent_StopPropagation, 2735).
+-define(wxCommandEvent_getClientData, 2736).
+-define(wxCommandEvent_GetExtraLong, 2737).
+-define(wxCommandEvent_GetInt, 2738).
+-define(wxCommandEvent_GetSelection, 2739).
+-define(wxCommandEvent_GetString, 2740).
+-define(wxCommandEvent_IsChecked, 2741).
+-define(wxCommandEvent_IsSelection, 2742).
+-define(wxCommandEvent_SetInt, 2743).
+-define(wxCommandEvent_SetString, 2744).
+-define(wxScrollEvent_GetOrientation, 2745).
+-define(wxScrollEvent_GetPosition, 2746).
+-define(wxScrollWinEvent_GetOrientation, 2747).
+-define(wxScrollWinEvent_GetPosition, 2748).
+-define(wxMouseEvent_AltDown, 2749).
+-define(wxMouseEvent_Button, 2750).
+-define(wxMouseEvent_ButtonDClick, 2751).
+-define(wxMouseEvent_ButtonDown, 2752).
+-define(wxMouseEvent_ButtonUp, 2753).
+-define(wxMouseEvent_CmdDown, 2754).
+-define(wxMouseEvent_ControlDown, 2755).
+-define(wxMouseEvent_Dragging, 2756).
+-define(wxMouseEvent_Entering, 2757).
+-define(wxMouseEvent_GetButton, 2758).
+-define(wxMouseEvent_GetPosition, 2761).
+-define(wxMouseEvent_GetLogicalPosition, 2762).
+-define(wxMouseEvent_GetLinesPerAction, 2763).
+-define(wxMouseEvent_GetWheelRotation, 2764).
+-define(wxMouseEvent_GetWheelDelta, 2765).
+-define(wxMouseEvent_GetX, 2766).
+-define(wxMouseEvent_GetY, 2767).
+-define(wxMouseEvent_IsButton, 2768).
+-define(wxMouseEvent_IsPageScroll, 2769).
+-define(wxMouseEvent_Leaving, 2770).
+-define(wxMouseEvent_LeftDClick, 2771).
+-define(wxMouseEvent_LeftDown, 2772).
+-define(wxMouseEvent_LeftIsDown, 2773).
+-define(wxMouseEvent_LeftUp, 2774).
+-define(wxMouseEvent_MetaDown, 2775).
+-define(wxMouseEvent_MiddleDClick, 2776).
+-define(wxMouseEvent_MiddleDown, 2777).
+-define(wxMouseEvent_MiddleIsDown, 2778).
+-define(wxMouseEvent_MiddleUp, 2779).
+-define(wxMouseEvent_Moving, 2780).
+-define(wxMouseEvent_RightDClick, 2781).
+-define(wxMouseEvent_RightDown, 2782).
+-define(wxMouseEvent_RightIsDown, 2783).
+-define(wxMouseEvent_RightUp, 2784).
+-define(wxMouseEvent_ShiftDown, 2785).
+-define(wxSetCursorEvent_GetCursor, 2786).
+-define(wxSetCursorEvent_GetX, 2787).
+-define(wxSetCursorEvent_GetY, 2788).
+-define(wxSetCursorEvent_HasCursor, 2789).
+-define(wxSetCursorEvent_SetCursor, 2790).
+-define(wxKeyEvent_AltDown, 2791).
+-define(wxKeyEvent_CmdDown, 2792).
+-define(wxKeyEvent_ControlDown, 2793).
+-define(wxKeyEvent_GetKeyCode, 2794).
+-define(wxKeyEvent_GetModifiers, 2795).
+-define(wxKeyEvent_GetPosition, 2798).
+-define(wxKeyEvent_GetRawKeyCode, 2799).
+-define(wxKeyEvent_GetRawKeyFlags, 2800).
+-define(wxKeyEvent_GetUnicodeKey, 2801).
+-define(wxKeyEvent_GetX, 2802).
+-define(wxKeyEvent_GetY, 2803).
+-define(wxKeyEvent_HasModifiers, 2804).
+-define(wxKeyEvent_MetaDown, 2805).
+-define(wxKeyEvent_ShiftDown, 2806).
+-define(wxSizeEvent_GetSize, 2807).
+-define(wxMoveEvent_GetPosition, 2808).
+-define(wxEraseEvent_GetDC, 2809).
+-define(wxFocusEvent_GetWindow, 2810).
+-define(wxChildFocusEvent_GetWindow, 2811).
+-define(wxMenuEvent_GetMenu, 2812).
+-define(wxMenuEvent_GetMenuId, 2813).
+-define(wxMenuEvent_IsPopup, 2814).
+-define(wxCloseEvent_CanVeto, 2815).
+-define(wxCloseEvent_GetLoggingOff, 2816).
+-define(wxCloseEvent_SetCanVeto, 2817).
+-define(wxCloseEvent_SetLoggingOff, 2818).
+-define(wxCloseEvent_Veto, 2819).
+-define(wxShowEvent_SetShow, 2820).
+-define(wxShowEvent_GetShow, 2821).
+-define(wxIconizeEvent_Iconized, 2822).
+-define(wxJoystickEvent_ButtonDown, 2823).
+-define(wxJoystickEvent_ButtonIsDown, 2824).
+-define(wxJoystickEvent_ButtonUp, 2825).
+-define(wxJoystickEvent_GetButtonChange, 2826).
+-define(wxJoystickEvent_GetButtonState, 2827).
+-define(wxJoystickEvent_GetJoystick, 2828).
+-define(wxJoystickEvent_GetPosition, 2829).
+-define(wxJoystickEvent_GetZPosition, 2830).
+-define(wxJoystickEvent_IsButton, 2831).
+-define(wxJoystickEvent_IsMove, 2832).
+-define(wxJoystickEvent_IsZMove, 2833).
+-define(wxUpdateUIEvent_CanUpdate, 2834).
+-define(wxUpdateUIEvent_Check, 2835).
+-define(wxUpdateUIEvent_Enable, 2836).
+-define(wxUpdateUIEvent_Show, 2837).
+-define(wxUpdateUIEvent_GetChecked, 2838).
+-define(wxUpdateUIEvent_GetEnabled, 2839).
+-define(wxUpdateUIEvent_GetShown, 2840).
+-define(wxUpdateUIEvent_GetSetChecked, 2841).
+-define(wxUpdateUIEvent_GetSetEnabled, 2842).
+-define(wxUpdateUIEvent_GetSetShown, 2843).
+-define(wxUpdateUIEvent_GetSetText, 2844).
+-define(wxUpdateUIEvent_GetText, 2845).
+-define(wxUpdateUIEvent_GetMode, 2846).
+-define(wxUpdateUIEvent_GetUpdateInterval, 2847).
+-define(wxUpdateUIEvent_ResetUpdateTime, 2848).
+-define(wxUpdateUIEvent_SetMode, 2849).
+-define(wxUpdateUIEvent_SetText, 2850).
+-define(wxUpdateUIEvent_SetUpdateInterval, 2851).
+-define(wxMouseCaptureChangedEvent_GetCapturedWindow, 2852).
+-define(wxPaletteChangedEvent_SetChangedWindow, 2853).
+-define(wxPaletteChangedEvent_GetChangedWindow, 2854).
+-define(wxQueryNewPaletteEvent_SetPaletteRealized, 2855).
+-define(wxQueryNewPaletteEvent_GetPaletteRealized, 2856).
+-define(wxNavigationKeyEvent_GetDirection, 2857).
+-define(wxNavigationKeyEvent_SetDirection, 2858).
+-define(wxNavigationKeyEvent_IsWindowChange, 2859).
+-define(wxNavigationKeyEvent_SetWindowChange, 2860).
+-define(wxNavigationKeyEvent_IsFromTab, 2861).
+-define(wxNavigationKeyEvent_SetFromTab, 2862).
+-define(wxNavigationKeyEvent_GetCurrentFocus, 2863).
+-define(wxNavigationKeyEvent_SetCurrentFocus, 2864).
+-define(wxHelpEvent_GetOrigin, 2865).
+-define(wxHelpEvent_GetPosition, 2866).
+-define(wxHelpEvent_SetOrigin, 2867).
+-define(wxHelpEvent_SetPosition, 2868).
+-define(wxContextMenuEvent_GetPosition, 2869).
+-define(wxContextMenuEvent_SetPosition, 2870).
+-define(wxIdleEvent_CanSend, 2871).
+-define(wxIdleEvent_GetMode, 2872).
+-define(wxIdleEvent_RequestMore, 2873).
+-define(wxIdleEvent_MoreRequested, 2874).
+-define(wxIdleEvent_SetMode, 2875).
+-define(wxGridEvent_AltDown, 2876).
+-define(wxGridEvent_ControlDown, 2877).
+-define(wxGridEvent_GetCol, 2878).
+-define(wxGridEvent_GetPosition, 2879).
+-define(wxGridEvent_GetRow, 2880).
+-define(wxGridEvent_MetaDown, 2881).
+-define(wxGridEvent_Selecting, 2882).
+-define(wxGridEvent_ShiftDown, 2883).
+-define(wxNotifyEvent_Allow, 2884).
+-define(wxNotifyEvent_IsAllowed, 2885).
+-define(wxNotifyEvent_Veto, 2886).
+-define(wxSashEvent_GetEdge, 2887).
+-define(wxSashEvent_GetDragRect, 2888).
+-define(wxSashEvent_GetDragStatus, 2889).
+-define(wxListEvent_GetCacheFrom, 2890).
+-define(wxListEvent_GetCacheTo, 2891).
+-define(wxListEvent_GetKeyCode, 2892).
+-define(wxListEvent_GetIndex, 2893).
+-define(wxListEvent_GetColumn, 2894).
+-define(wxListEvent_GetPoint, 2895).
+-define(wxListEvent_GetLabel, 2896).
+-define(wxListEvent_GetText, 2897).
+-define(wxListEvent_GetImage, 2898).
+-define(wxListEvent_GetData, 2899).
+-define(wxListEvent_GetMask, 2900).
+-define(wxListEvent_GetItem, 2901).
+-define(wxListEvent_IsEditCancelled, 2902).
+-define(wxDateEvent_GetDate, 2903).
+-define(wxCalendarEvent_GetWeekDay, 2904).
+-define(wxFileDirPickerEvent_GetPath, 2905).
+-define(wxColourPickerEvent_GetColour, 2906).
+-define(wxFontPickerEvent_GetFont, 2907).
+-define(wxStyledTextEvent_GetPosition, 2908).
+-define(wxStyledTextEvent_GetKey, 2909).
+-define(wxStyledTextEvent_GetModifiers, 2910).
+-define(wxStyledTextEvent_GetModificationType, 2911).
+-define(wxStyledTextEvent_GetText, 2912).
+-define(wxStyledTextEvent_GetLength, 2913).
+-define(wxStyledTextEvent_GetLinesAdded, 2914).
+-define(wxStyledTextEvent_GetLine, 2915).
+-define(wxStyledTextEvent_GetFoldLevelNow, 2916).
+-define(wxStyledTextEvent_GetFoldLevelPrev, 2917).
+-define(wxStyledTextEvent_GetMargin, 2918).
+-define(wxStyledTextEvent_GetMessage, 2919).
+-define(wxStyledTextEvent_GetWParam, 2920).
+-define(wxStyledTextEvent_GetLParam, 2921).
+-define(wxStyledTextEvent_GetListType, 2922).
+-define(wxStyledTextEvent_GetX, 2923).
+-define(wxStyledTextEvent_GetY, 2924).
+-define(wxStyledTextEvent_GetDragText, 2925).
+-define(wxStyledTextEvent_GetDragAllowMove, 2926).
+-define(wxStyledTextEvent_GetDragResult, 2927).
+-define(wxStyledTextEvent_GetShift, 2928).
+-define(wxStyledTextEvent_GetControl, 2929).
+-define(wxStyledTextEvent_GetAlt, 2930).
+-define(utils_wxGetKeyState, 2931).
+-define(utils_wxGetMousePosition, 2932).
+-define(utils_wxGetMouseState, 2933).
+-define(utils_wxSetDetectableAutoRepeat, 2934).
+-define(utils_wxBell, 2935).
+-define(utils_wxFindMenuItemId, 2936).
+-define(utils_wxGenericFindWindowAtPoint, 2937).
+-define(utils_wxFindWindowAtPoint, 2938).
+-define(utils_wxBeginBusyCursor, 2939).
+-define(utils_wxEndBusyCursor, 2940).
+-define(utils_wxIsBusy, 2941).
+-define(utils_wxShutdown, 2942).
+-define(utils_wxShell, 2943).
+-define(utils_wxLaunchDefaultBrowser, 2944).
+-define(utils_wxGetEmailAddress, 2945).
+-define(utils_wxGetUserId, 2946).
+-define(utils_wxGetHomeDir, 2947).
+-define(utils_wxNewId, 2948).
+-define(utils_wxRegisterId, 2949).
+-define(utils_wxGetCurrentId, 2950).
+-define(utils_wxGetOsDescription, 2951).
+-define(utils_wxIsPlatformLittleEndian, 2952).
+-define(utils_wxIsPlatform64Bit, 2953).
+-define(gdicmn_wxDisplaySize, 2954).
+-define(gdicmn_wxSetCursor, 2955).
+-define(wxPrintout_new, 2956).
+-define(wxPrintout_destruct, 2957).
+-define(wxPrintout_GetDC, 2958).
+-define(wxPrintout_GetPageSizeMM, 2959).
+-define(wxPrintout_GetPageSizePixels, 2960).
+-define(wxPrintout_GetPaperRectPixels, 2961).
+-define(wxPrintout_GetPPIPrinter, 2962).
+-define(wxPrintout_GetPPIScreen, 2963).
+-define(wxPrintout_GetTitle, 2964).
+-define(wxPrintout_IsPreview, 2965).
+-define(wxPrintout_FitThisSizeToPaper, 2966).
+-define(wxPrintout_FitThisSizeToPage, 2967).
+-define(wxPrintout_FitThisSizeToPageMargins, 2968).
+-define(wxPrintout_MapScreenSizeToPaper, 2969).
+-define(wxPrintout_MapScreenSizeToPage, 2970).
+-define(wxPrintout_MapScreenSizeToPageMargins, 2971).
+-define(wxPrintout_MapScreenSizeToDevice, 2972).
+-define(wxPrintout_GetLogicalPaperRect, 2973).
+-define(wxPrintout_GetLogicalPageRect, 2974).
+-define(wxPrintout_GetLogicalPageMarginsRect, 2975).
+-define(wxPrintout_SetLogicalOrigin, 2976).
+-define(wxPrintout_OffsetLogicalOrigin, 2977).
+-define(wxStyledTextCtrl_new_2, 2978).
+-define(wxStyledTextCtrl_new_0, 2979).
+-define(wxStyledTextCtrl_destruct, 2980).
+-define(wxStyledTextCtrl_Create, 2981).
+-define(wxStyledTextCtrl_AddText, 2982).
+-define(wxStyledTextCtrl_AddStyledText, 2983).
+-define(wxStyledTextCtrl_InsertText, 2984).
+-define(wxStyledTextCtrl_ClearAll, 2985).
+-define(wxStyledTextCtrl_ClearDocumentStyle, 2986).
+-define(wxStyledTextCtrl_GetLength, 2987).
+-define(wxStyledTextCtrl_GetCharAt, 2988).
+-define(wxStyledTextCtrl_GetCurrentPos, 2989).
+-define(wxStyledTextCtrl_GetAnchor, 2990).
+-define(wxStyledTextCtrl_GetStyleAt, 2991).
+-define(wxStyledTextCtrl_Redo, 2992).
+-define(wxStyledTextCtrl_SetUndoCollection, 2993).
+-define(wxStyledTextCtrl_SelectAll, 2994).
+-define(wxStyledTextCtrl_SetSavePoint, 2995).
+-define(wxStyledTextCtrl_GetStyledText, 2996).
+-define(wxStyledTextCtrl_CanRedo, 2997).
+-define(wxStyledTextCtrl_MarkerLineFromHandle, 2998).
+-define(wxStyledTextCtrl_MarkerDeleteHandle, 2999).
+-define(wxStyledTextCtrl_GetUndoCollection, 3000).
+-define(wxStyledTextCtrl_GetViewWhiteSpace, 3001).
+-define(wxStyledTextCtrl_SetViewWhiteSpace, 3002).
+-define(wxStyledTextCtrl_PositionFromPoint, 3003).
+-define(wxStyledTextCtrl_PositionFromPointClose, 3004).
+-define(wxStyledTextCtrl_GotoLine, 3005).
+-define(wxStyledTextCtrl_GotoPos, 3006).
+-define(wxStyledTextCtrl_SetAnchor, 3007).
+-define(wxStyledTextCtrl_GetCurLine, 3008).
+-define(wxStyledTextCtrl_GetEndStyled, 3009).
+-define(wxStyledTextCtrl_ConvertEOLs, 3010).
+-define(wxStyledTextCtrl_GetEOLMode, 3011).
+-define(wxStyledTextCtrl_SetEOLMode, 3012).
+-define(wxStyledTextCtrl_StartStyling, 3013).
+-define(wxStyledTextCtrl_SetStyling, 3014).
+-define(wxStyledTextCtrl_GetBufferedDraw, 3015).
+-define(wxStyledTextCtrl_SetBufferedDraw, 3016).
+-define(wxStyledTextCtrl_SetTabWidth, 3017).
+-define(wxStyledTextCtrl_GetTabWidth, 3018).
+-define(wxStyledTextCtrl_SetCodePage, 3019).
+-define(wxStyledTextCtrl_MarkerDefine, 3020).
+-define(wxStyledTextCtrl_MarkerSetForeground, 3021).
+-define(wxStyledTextCtrl_MarkerSetBackground, 3022).
+-define(wxStyledTextCtrl_MarkerAdd, 3023).
+-define(wxStyledTextCtrl_MarkerDelete, 3024).
+-define(wxStyledTextCtrl_MarkerDeleteAll, 3025).
+-define(wxStyledTextCtrl_MarkerGet, 3026).
+-define(wxStyledTextCtrl_MarkerNext, 3027).
+-define(wxStyledTextCtrl_MarkerPrevious, 3028).
+-define(wxStyledTextCtrl_MarkerDefineBitmap, 3029).
+-define(wxStyledTextCtrl_MarkerAddSet, 3030).
+-define(wxStyledTextCtrl_MarkerSetAlpha, 3031).
+-define(wxStyledTextCtrl_SetMarginType, 3032).
+-define(wxStyledTextCtrl_GetMarginType, 3033).
+-define(wxStyledTextCtrl_SetMarginWidth, 3034).
+-define(wxStyledTextCtrl_GetMarginWidth, 3035).
+-define(wxStyledTextCtrl_SetMarginMask, 3036).
+-define(wxStyledTextCtrl_GetMarginMask, 3037).
+-define(wxStyledTextCtrl_SetMarginSensitive, 3038).
+-define(wxStyledTextCtrl_GetMarginSensitive, 3039).
+-define(wxStyledTextCtrl_StyleClearAll, 3040).
+-define(wxStyledTextCtrl_StyleSetForeground, 3041).
+-define(wxStyledTextCtrl_StyleSetBackground, 3042).
+-define(wxStyledTextCtrl_StyleSetBold, 3043).
+-define(wxStyledTextCtrl_StyleSetItalic, 3044).
+-define(wxStyledTextCtrl_StyleSetSize, 3045).
+-define(wxStyledTextCtrl_StyleSetFaceName, 3046).
+-define(wxStyledTextCtrl_StyleSetEOLFilled, 3047).
+-define(wxStyledTextCtrl_StyleResetDefault, 3048).
+-define(wxStyledTextCtrl_StyleSetUnderline, 3049).
+-define(wxStyledTextCtrl_StyleSetCase, 3050).
+-define(wxStyledTextCtrl_StyleSetHotSpot, 3051).
+-define(wxStyledTextCtrl_SetSelForeground, 3052).
+-define(wxStyledTextCtrl_SetSelBackground, 3053).
+-define(wxStyledTextCtrl_GetSelAlpha, 3054).
+-define(wxStyledTextCtrl_SetSelAlpha, 3055).
+-define(wxStyledTextCtrl_SetCaretForeground, 3056).
+-define(wxStyledTextCtrl_CmdKeyAssign, 3057).
+-define(wxStyledTextCtrl_CmdKeyClear, 3058).
+-define(wxStyledTextCtrl_CmdKeyClearAll, 3059).
+-define(wxStyledTextCtrl_SetStyleBytes, 3060).
+-define(wxStyledTextCtrl_StyleSetVisible, 3061).
+-define(wxStyledTextCtrl_GetCaretPeriod, 3062).
+-define(wxStyledTextCtrl_SetCaretPeriod, 3063).
+-define(wxStyledTextCtrl_SetWordChars, 3064).
+-define(wxStyledTextCtrl_BeginUndoAction, 3065).
+-define(wxStyledTextCtrl_EndUndoAction, 3066).
+-define(wxStyledTextCtrl_IndicatorSetStyle, 3067).
+-define(wxStyledTextCtrl_IndicatorGetStyle, 3068).
+-define(wxStyledTextCtrl_IndicatorSetForeground, 3069).
+-define(wxStyledTextCtrl_IndicatorGetForeground, 3070).
+-define(wxStyledTextCtrl_SetWhitespaceForeground, 3071).
+-define(wxStyledTextCtrl_SetWhitespaceBackground, 3072).
+-define(wxStyledTextCtrl_GetStyleBits, 3073).
+-define(wxStyledTextCtrl_SetLineState, 3074).
+-define(wxStyledTextCtrl_GetLineState, 3075).
+-define(wxStyledTextCtrl_GetMaxLineState, 3076).
+-define(wxStyledTextCtrl_GetCaretLineVisible, 3077).
+-define(wxStyledTextCtrl_SetCaretLineVisible, 3078).
+-define(wxStyledTextCtrl_GetCaretLineBackground, 3079).
+-define(wxStyledTextCtrl_SetCaretLineBackground, 3080).
+-define(wxStyledTextCtrl_AutoCompShow, 3081).
+-define(wxStyledTextCtrl_AutoCompCancel, 3082).
+-define(wxStyledTextCtrl_AutoCompActive, 3083).
+-define(wxStyledTextCtrl_AutoCompPosStart, 3084).
+-define(wxStyledTextCtrl_AutoCompComplete, 3085).
+-define(wxStyledTextCtrl_AutoCompStops, 3086).
+-define(wxStyledTextCtrl_AutoCompSetSeparator, 3087).
+-define(wxStyledTextCtrl_AutoCompGetSeparator, 3088).
+-define(wxStyledTextCtrl_AutoCompSelect, 3089).
+-define(wxStyledTextCtrl_AutoCompSetCancelAtStart, 3090).
+-define(wxStyledTextCtrl_AutoCompGetCancelAtStart, 3091).
+-define(wxStyledTextCtrl_AutoCompSetFillUps, 3092).
+-define(wxStyledTextCtrl_AutoCompSetChooseSingle, 3093).
+-define(wxStyledTextCtrl_AutoCompGetChooseSingle, 3094).
+-define(wxStyledTextCtrl_AutoCompSetIgnoreCase, 3095).
+-define(wxStyledTextCtrl_AutoCompGetIgnoreCase, 3096).
+-define(wxStyledTextCtrl_UserListShow, 3097).
+-define(wxStyledTextCtrl_AutoCompSetAutoHide, 3098).
+-define(wxStyledTextCtrl_AutoCompGetAutoHide, 3099).
+-define(wxStyledTextCtrl_AutoCompSetDropRestOfWord, 3100).
+-define(wxStyledTextCtrl_AutoCompGetDropRestOfWord, 3101).
+-define(wxStyledTextCtrl_RegisterImage, 3102).
+-define(wxStyledTextCtrl_ClearRegisteredImages, 3103).
+-define(wxStyledTextCtrl_AutoCompGetTypeSeparator, 3104).
+-define(wxStyledTextCtrl_AutoCompSetTypeSeparator, 3105).
+-define(wxStyledTextCtrl_AutoCompSetMaxWidth, 3106).
+-define(wxStyledTextCtrl_AutoCompGetMaxWidth, 3107).
+-define(wxStyledTextCtrl_AutoCompSetMaxHeight, 3108).
+-define(wxStyledTextCtrl_AutoCompGetMaxHeight, 3109).
+-define(wxStyledTextCtrl_SetIndent, 3110).
+-define(wxStyledTextCtrl_GetIndent, 3111).
+-define(wxStyledTextCtrl_SetUseTabs, 3112).
+-define(wxStyledTextCtrl_GetUseTabs, 3113).
+-define(wxStyledTextCtrl_SetLineIndentation, 3114).
+-define(wxStyledTextCtrl_GetLineIndentation, 3115).
+-define(wxStyledTextCtrl_GetLineIndentPosition, 3116).
+-define(wxStyledTextCtrl_GetColumn, 3117).
+-define(wxStyledTextCtrl_SetUseHorizontalScrollBar, 3118).
+-define(wxStyledTextCtrl_GetUseHorizontalScrollBar, 3119).
+-define(wxStyledTextCtrl_SetIndentationGuides, 3120).
+-define(wxStyledTextCtrl_GetIndentationGuides, 3121).
+-define(wxStyledTextCtrl_SetHighlightGuide, 3122).
+-define(wxStyledTextCtrl_GetHighlightGuide, 3123).
+-define(wxStyledTextCtrl_GetLineEndPosition, 3124).
+-define(wxStyledTextCtrl_GetCodePage, 3125).
+-define(wxStyledTextCtrl_GetCaretForeground, 3126).
+-define(wxStyledTextCtrl_GetReadOnly, 3127).
+-define(wxStyledTextCtrl_SetCurrentPos, 3128).
+-define(wxStyledTextCtrl_SetSelectionStart, 3129).
+-define(wxStyledTextCtrl_GetSelectionStart, 3130).
+-define(wxStyledTextCtrl_SetSelectionEnd, 3131).
+-define(wxStyledTextCtrl_GetSelectionEnd, 3132).
+-define(wxStyledTextCtrl_SetPrintMagnification, 3133).
+-define(wxStyledTextCtrl_GetPrintMagnification, 3134).
+-define(wxStyledTextCtrl_SetPrintColourMode, 3135).
+-define(wxStyledTextCtrl_GetPrintColourMode, 3136).
+-define(wxStyledTextCtrl_FindText, 3137).
+-define(wxStyledTextCtrl_FormatRange, 3138).
+-define(wxStyledTextCtrl_GetFirstVisibleLine, 3139).
+-define(wxStyledTextCtrl_GetLine, 3140).
+-define(wxStyledTextCtrl_GetLineCount, 3141).
+-define(wxStyledTextCtrl_SetMarginLeft, 3142).
+-define(wxStyledTextCtrl_GetMarginLeft, 3143).
+-define(wxStyledTextCtrl_SetMarginRight, 3144).
+-define(wxStyledTextCtrl_GetMarginRight, 3145).
+-define(wxStyledTextCtrl_GetModify, 3146).
+-define(wxStyledTextCtrl_SetSelection, 3147).
+-define(wxStyledTextCtrl_GetSelectedText, 3148).
+-define(wxStyledTextCtrl_GetTextRange, 3149).
+-define(wxStyledTextCtrl_HideSelection, 3150).
+-define(wxStyledTextCtrl_LineFromPosition, 3151).
+-define(wxStyledTextCtrl_PositionFromLine, 3152).
+-define(wxStyledTextCtrl_LineScroll, 3153).
+-define(wxStyledTextCtrl_EnsureCaretVisible, 3154).
+-define(wxStyledTextCtrl_ReplaceSelection, 3155).
+-define(wxStyledTextCtrl_SetReadOnly, 3156).
+-define(wxStyledTextCtrl_CanPaste, 3157).
+-define(wxStyledTextCtrl_CanUndo, 3158).
+-define(wxStyledTextCtrl_EmptyUndoBuffer, 3159).
+-define(wxStyledTextCtrl_Undo, 3160).
+-define(wxStyledTextCtrl_Cut, 3161).
+-define(wxStyledTextCtrl_Copy, 3162).
+-define(wxStyledTextCtrl_Paste, 3163).
+-define(wxStyledTextCtrl_Clear, 3164).
+-define(wxStyledTextCtrl_SetText, 3165).
+-define(wxStyledTextCtrl_GetText, 3166).
+-define(wxStyledTextCtrl_GetTextLength, 3167).
+-define(wxStyledTextCtrl_GetOvertype, 3168).
+-define(wxStyledTextCtrl_SetCaretWidth, 3169).
+-define(wxStyledTextCtrl_GetCaretWidth, 3170).
+-define(wxStyledTextCtrl_SetTargetStart, 3171).
+-define(wxStyledTextCtrl_GetTargetStart, 3172).
+-define(wxStyledTextCtrl_SetTargetEnd, 3173).
+-define(wxStyledTextCtrl_GetTargetEnd, 3174).
+-define(wxStyledTextCtrl_ReplaceTarget, 3175).
+-define(wxStyledTextCtrl_SearchInTarget, 3176).
+-define(wxStyledTextCtrl_SetSearchFlags, 3177).
+-define(wxStyledTextCtrl_GetSearchFlags, 3178).
+-define(wxStyledTextCtrl_CallTipShow, 3179).
+-define(wxStyledTextCtrl_CallTipCancel, 3180).
+-define(wxStyledTextCtrl_CallTipActive, 3181).
+-define(wxStyledTextCtrl_CallTipPosAtStart, 3182).
+-define(wxStyledTextCtrl_CallTipSetHighlight, 3183).
+-define(wxStyledTextCtrl_CallTipSetBackground, 3184).
+-define(wxStyledTextCtrl_CallTipSetForeground, 3185).
+-define(wxStyledTextCtrl_CallTipSetForegroundHighlight, 3186).
+-define(wxStyledTextCtrl_CallTipUseStyle, 3187).
+-define(wxStyledTextCtrl_VisibleFromDocLine, 3188).
+-define(wxStyledTextCtrl_DocLineFromVisible, 3189).
+-define(wxStyledTextCtrl_WrapCount, 3190).
+-define(wxStyledTextCtrl_SetFoldLevel, 3191).
+-define(wxStyledTextCtrl_GetFoldLevel, 3192).
+-define(wxStyledTextCtrl_GetLastChild, 3193).
+-define(wxStyledTextCtrl_GetFoldParent, 3194).
+-define(wxStyledTextCtrl_ShowLines, 3195).
+-define(wxStyledTextCtrl_HideLines, 3196).
+-define(wxStyledTextCtrl_GetLineVisible, 3197).
+-define(wxStyledTextCtrl_SetFoldExpanded, 3198).
+-define(wxStyledTextCtrl_GetFoldExpanded, 3199).
+-define(wxStyledTextCtrl_ToggleFold, 3200).
+-define(wxStyledTextCtrl_EnsureVisible, 3201).
+-define(wxStyledTextCtrl_SetFoldFlags, 3202).
+-define(wxStyledTextCtrl_EnsureVisibleEnforcePolicy, 3203).
+-define(wxStyledTextCtrl_SetTabIndents, 3204).
+-define(wxStyledTextCtrl_GetTabIndents, 3205).
+-define(wxStyledTextCtrl_SetBackSpaceUnIndents, 3206).
+-define(wxStyledTextCtrl_GetBackSpaceUnIndents, 3207).
+-define(wxStyledTextCtrl_SetMouseDwellTime, 3208).
+-define(wxStyledTextCtrl_GetMouseDwellTime, 3209).
+-define(wxStyledTextCtrl_WordStartPosition, 3210).
+-define(wxStyledTextCtrl_WordEndPosition, 3211).
+-define(wxStyledTextCtrl_SetWrapMode, 3212).
+-define(wxStyledTextCtrl_GetWrapMode, 3213).
+-define(wxStyledTextCtrl_SetWrapVisualFlags, 3214).
+-define(wxStyledTextCtrl_GetWrapVisualFlags, 3215).
+-define(wxStyledTextCtrl_SetWrapVisualFlagsLocation, 3216).
+-define(wxStyledTextCtrl_GetWrapVisualFlagsLocation, 3217).
+-define(wxStyledTextCtrl_SetWrapStartIndent, 3218).
+-define(wxStyledTextCtrl_GetWrapStartIndent, 3219).
+-define(wxStyledTextCtrl_SetLayoutCache, 3220).
+-define(wxStyledTextCtrl_GetLayoutCache, 3221).
+-define(wxStyledTextCtrl_SetScrollWidth, 3222).
+-define(wxStyledTextCtrl_GetScrollWidth, 3223).
+-define(wxStyledTextCtrl_TextWidth, 3224).
+-define(wxStyledTextCtrl_GetEndAtLastLine, 3225).
+-define(wxStyledTextCtrl_TextHeight, 3226).
+-define(wxStyledTextCtrl_SetUseVerticalScrollBar, 3227).
+-define(wxStyledTextCtrl_GetUseVerticalScrollBar, 3228).
+-define(wxStyledTextCtrl_AppendText, 3229).
+-define(wxStyledTextCtrl_GetTwoPhaseDraw, 3230).
+-define(wxStyledTextCtrl_SetTwoPhaseDraw, 3231).
+-define(wxStyledTextCtrl_TargetFromSelection, 3232).
+-define(wxStyledTextCtrl_LinesJoin, 3233).
+-define(wxStyledTextCtrl_LinesSplit, 3234).
+-define(wxStyledTextCtrl_SetFoldMarginColour, 3235).
+-define(wxStyledTextCtrl_SetFoldMarginHiColour, 3236).
+-define(wxStyledTextCtrl_LineDown, 3237).
+-define(wxStyledTextCtrl_LineDownExtend, 3238).
+-define(wxStyledTextCtrl_LineUp, 3239).
+-define(wxStyledTextCtrl_LineUpExtend, 3240).
+-define(wxStyledTextCtrl_CharLeft, 3241).
+-define(wxStyledTextCtrl_CharLeftExtend, 3242).
+-define(wxStyledTextCtrl_CharRight, 3243).
+-define(wxStyledTextCtrl_CharRightExtend, 3244).
+-define(wxStyledTextCtrl_WordLeft, 3245).
+-define(wxStyledTextCtrl_WordLeftExtend, 3246).
+-define(wxStyledTextCtrl_WordRight, 3247).
+-define(wxStyledTextCtrl_WordRightExtend, 3248).
+-define(wxStyledTextCtrl_Home, 3249).
+-define(wxStyledTextCtrl_HomeExtend, 3250).
+-define(wxStyledTextCtrl_LineEnd, 3251).
+-define(wxStyledTextCtrl_LineEndExtend, 3252).
+-define(wxStyledTextCtrl_DocumentStart, 3253).
+-define(wxStyledTextCtrl_DocumentStartExtend, 3254).
+-define(wxStyledTextCtrl_DocumentEnd, 3255).
+-define(wxStyledTextCtrl_DocumentEndExtend, 3256).
+-define(wxStyledTextCtrl_PageUp, 3257).
+-define(wxStyledTextCtrl_PageUpExtend, 3258).
+-define(wxStyledTextCtrl_PageDown, 3259).
+-define(wxStyledTextCtrl_PageDownExtend, 3260).
+-define(wxStyledTextCtrl_EditToggleOvertype, 3261).
+-define(wxStyledTextCtrl_Cancel, 3262).
+-define(wxStyledTextCtrl_DeleteBack, 3263).
+-define(wxStyledTextCtrl_Tab, 3264).
+-define(wxStyledTextCtrl_BackTab, 3265).
+-define(wxStyledTextCtrl_NewLine, 3266).
+-define(wxStyledTextCtrl_FormFeed, 3267).
+-define(wxStyledTextCtrl_VCHome, 3268).
+-define(wxStyledTextCtrl_VCHomeExtend, 3269).
+-define(wxStyledTextCtrl_ZoomIn, 3270).
+-define(wxStyledTextCtrl_ZoomOut, 3271).
+-define(wxStyledTextCtrl_DelWordLeft, 3272).
+-define(wxStyledTextCtrl_DelWordRight, 3273).
+-define(wxStyledTextCtrl_LineCut, 3274).
+-define(wxStyledTextCtrl_LineDelete, 3275).
+-define(wxStyledTextCtrl_LineTranspose, 3276).
+-define(wxStyledTextCtrl_LineDuplicate, 3277).
+-define(wxStyledTextCtrl_LowerCase, 3278).
+-define(wxStyledTextCtrl_UpperCase, 3279).
+-define(wxStyledTextCtrl_LineScrollDown, 3280).
+-define(wxStyledTextCtrl_LineScrollUp, 3281).
+-define(wxStyledTextCtrl_DeleteBackNotLine, 3282).
+-define(wxStyledTextCtrl_HomeDisplay, 3283).
+-define(wxStyledTextCtrl_HomeDisplayExtend, 3284).
+-define(wxStyledTextCtrl_LineEndDisplay, 3285).
+-define(wxStyledTextCtrl_LineEndDisplayExtend, 3286).
+-define(wxStyledTextCtrl_HomeWrapExtend, 3287).
+-define(wxStyledTextCtrl_LineEndWrap, 3288).
+-define(wxStyledTextCtrl_LineEndWrapExtend, 3289).
+-define(wxStyledTextCtrl_VCHomeWrap, 3290).
+-define(wxStyledTextCtrl_VCHomeWrapExtend, 3291).
+-define(wxStyledTextCtrl_LineCopy, 3292).
+-define(wxStyledTextCtrl_MoveCaretInsideView, 3293).
+-define(wxStyledTextCtrl_LineLength, 3294).
+-define(wxStyledTextCtrl_BraceHighlight, 3295).
+-define(wxStyledTextCtrl_BraceBadLight, 3296).
+-define(wxStyledTextCtrl_BraceMatch, 3297).
+-define(wxStyledTextCtrl_GetViewEOL, 3298).
+-define(wxStyledTextCtrl_SetViewEOL, 3299).
+-define(wxStyledTextCtrl_SetModEventMask, 3300).
+-define(wxStyledTextCtrl_GetEdgeColumn, 3301).
+-define(wxStyledTextCtrl_SetEdgeColumn, 3302).
+-define(wxStyledTextCtrl_SetEdgeMode, 3303).
+-define(wxStyledTextCtrl_GetEdgeMode, 3304).
+-define(wxStyledTextCtrl_GetEdgeColour, 3305).
+-define(wxStyledTextCtrl_SetEdgeColour, 3306).
+-define(wxStyledTextCtrl_SearchAnchor, 3307).
+-define(wxStyledTextCtrl_SearchNext, 3308).
+-define(wxStyledTextCtrl_SearchPrev, 3309).
+-define(wxStyledTextCtrl_LinesOnScreen, 3310).
+-define(wxStyledTextCtrl_UsePopUp, 3311).
+-define(wxStyledTextCtrl_SelectionIsRectangle, 3312).
+-define(wxStyledTextCtrl_SetZoom, 3313).
+-define(wxStyledTextCtrl_GetZoom, 3314).
+-define(wxStyledTextCtrl_GetModEventMask, 3315).
+-define(wxStyledTextCtrl_SetSTCFocus, 3316).
+-define(wxStyledTextCtrl_GetSTCFocus, 3317).
+-define(wxStyledTextCtrl_SetStatus, 3318).
+-define(wxStyledTextCtrl_GetStatus, 3319).
+-define(wxStyledTextCtrl_SetMouseDownCaptures, 3320).
+-define(wxStyledTextCtrl_GetMouseDownCaptures, 3321).
+-define(wxStyledTextCtrl_SetSTCCursor, 3322).
+-define(wxStyledTextCtrl_GetSTCCursor, 3323).
+-define(wxStyledTextCtrl_SetControlCharSymbol, 3324).
+-define(wxStyledTextCtrl_GetControlCharSymbol, 3325).
+-define(wxStyledTextCtrl_WordPartLeft, 3326).
+-define(wxStyledTextCtrl_WordPartLeftExtend, 3327).
+-define(wxStyledTextCtrl_WordPartRight, 3328).
+-define(wxStyledTextCtrl_WordPartRightExtend, 3329).
+-define(wxStyledTextCtrl_SetVisiblePolicy, 3330).
+-define(wxStyledTextCtrl_DelLineLeft, 3331).
+-define(wxStyledTextCtrl_DelLineRight, 3332).
+-define(wxStyledTextCtrl_GetXOffset, 3333).
+-define(wxStyledTextCtrl_ChooseCaretX, 3334).
+-define(wxStyledTextCtrl_SetXCaretPolicy, 3335).
+-define(wxStyledTextCtrl_SetYCaretPolicy, 3336).
+-define(wxStyledTextCtrl_GetPrintWrapMode, 3337).
+-define(wxStyledTextCtrl_SetHotspotActiveForeground, 3338).
+-define(wxStyledTextCtrl_SetHotspotActiveBackground, 3339).
+-define(wxStyledTextCtrl_SetHotspotActiveUnderline, 3340).
+-define(wxStyledTextCtrl_SetHotspotSingleLine, 3341).
+-define(wxStyledTextCtrl_ParaDownExtend, 3342).
+-define(wxStyledTextCtrl_ParaUp, 3343).
+-define(wxStyledTextCtrl_ParaUpExtend, 3344).
+-define(wxStyledTextCtrl_PositionBefore, 3345).
+-define(wxStyledTextCtrl_PositionAfter, 3346).
+-define(wxStyledTextCtrl_CopyRange, 3347).
+-define(wxStyledTextCtrl_CopyText, 3348).
+-define(wxStyledTextCtrl_SetSelectionMode, 3349).
+-define(wxStyledTextCtrl_GetSelectionMode, 3350).
+-define(wxStyledTextCtrl_LineDownRectExtend, 3351).
+-define(wxStyledTextCtrl_LineUpRectExtend, 3352).
+-define(wxStyledTextCtrl_CharLeftRectExtend, 3353).
+-define(wxStyledTextCtrl_CharRightRectExtend, 3354).
+-define(wxStyledTextCtrl_HomeRectExtend, 3355).
+-define(wxStyledTextCtrl_VCHomeRectExtend, 3356).
+-define(wxStyledTextCtrl_LineEndRectExtend, 3357).
+-define(wxStyledTextCtrl_PageUpRectExtend, 3358).
+-define(wxStyledTextCtrl_PageDownRectExtend, 3359).
+-define(wxStyledTextCtrl_StutteredPageUp, 3360).
+-define(wxStyledTextCtrl_StutteredPageUpExtend, 3361).
+-define(wxStyledTextCtrl_StutteredPageDown, 3362).
+-define(wxStyledTextCtrl_StutteredPageDownExtend, 3363).
+-define(wxStyledTextCtrl_WordLeftEnd, 3364).
+-define(wxStyledTextCtrl_WordLeftEndExtend, 3365).
+-define(wxStyledTextCtrl_WordRightEnd, 3366).
+-define(wxStyledTextCtrl_WordRightEndExtend, 3367).
+-define(wxStyledTextCtrl_SetWhitespaceChars, 3368).
+-define(wxStyledTextCtrl_SetCharsDefault, 3369).
+-define(wxStyledTextCtrl_AutoCompGetCurrent, 3370).
+-define(wxStyledTextCtrl_Allocate, 3371).
+-define(wxStyledTextCtrl_FindColumn, 3372).
+-define(wxStyledTextCtrl_GetCaretSticky, 3373).
+-define(wxStyledTextCtrl_SetCaretSticky, 3374).
+-define(wxStyledTextCtrl_ToggleCaretSticky, 3375).
+-define(wxStyledTextCtrl_SetPasteConvertEndings, 3376).
+-define(wxStyledTextCtrl_GetPasteConvertEndings, 3377).
+-define(wxStyledTextCtrl_SelectionDuplicate, 3378).
+-define(wxStyledTextCtrl_SetCaretLineBackAlpha, 3379).
+-define(wxStyledTextCtrl_GetCaretLineBackAlpha, 3380).
+-define(wxStyledTextCtrl_StartRecord, 3381).
+-define(wxStyledTextCtrl_StopRecord, 3382).
+-define(wxStyledTextCtrl_SetLexer, 3383).
+-define(wxStyledTextCtrl_GetLexer, 3384).
+-define(wxStyledTextCtrl_Colourise, 3385).
+-define(wxStyledTextCtrl_SetProperty, 3386).
+-define(wxStyledTextCtrl_SetKeyWords, 3387).
+-define(wxStyledTextCtrl_SetLexerLanguage, 3388).
+-define(wxStyledTextCtrl_GetProperty, 3389).
+-define(wxStyledTextCtrl_GetStyleBitsNeeded, 3390).
+-define(wxStyledTextCtrl_GetCurrentLine, 3391).
+-define(wxStyledTextCtrl_StyleSetSpec, 3392).
+-define(wxStyledTextCtrl_StyleSetFont, 3393).
+-define(wxStyledTextCtrl_StyleSetFontAttr, 3394).
+-define(wxStyledTextCtrl_StyleSetCharacterSet, 3395).
+-define(wxStyledTextCtrl_StyleSetFontEncoding, 3396).
+-define(wxStyledTextCtrl_CmdKeyExecute, 3397).
+-define(wxStyledTextCtrl_SetMargins, 3398).
+-define(wxStyledTextCtrl_GetSelection, 3399).
+-define(wxStyledTextCtrl_PointFromPosition, 3400).
+-define(wxStyledTextCtrl_ScrollToLine, 3401).
+-define(wxStyledTextCtrl_ScrollToColumn, 3402).
+-define(wxStyledTextCtrl_SetVScrollBar, 3403).
+-define(wxStyledTextCtrl_SetHScrollBar, 3404).
+-define(wxStyledTextCtrl_GetLastKeydownProcessed, 3405).
+-define(wxStyledTextCtrl_SetLastKeydownProcessed, 3406).
+-define(wxStyledTextCtrl_SaveFile, 3407).
+-define(wxStyledTextCtrl_LoadFile, 3408).
+-define(wxStyledTextCtrl_DoDragOver, 3409).
+-define(wxStyledTextCtrl_DoDropText, 3410).
+-define(wxStyledTextCtrl_GetUseAntiAliasing, 3411).
+-define(wxStyledTextCtrl_AddTextRaw, 3412).
+-define(wxStyledTextCtrl_InsertTextRaw, 3413).
+-define(wxStyledTextCtrl_GetCurLineRaw, 3414).
+-define(wxStyledTextCtrl_GetLineRaw, 3415).
+-define(wxStyledTextCtrl_GetSelectedTextRaw, 3416).
+-define(wxStyledTextCtrl_GetTextRangeRaw, 3417).
+-define(wxStyledTextCtrl_SetTextRaw, 3418).
+-define(wxStyledTextCtrl_GetTextRaw, 3419).
+-define(wxStyledTextCtrl_AppendTextRaw, 3420).
+-define(wxArtProvider_GetBitmap, 3421).
+-define(wxArtProvider_GetIcon, 3422).
+-define(wxTreeEvent_GetKeyCode, 3423).
+-define(wxTreeEvent_GetItem, 3424).
+-define(wxTreeEvent_GetKeyEvent, 3425).
+-define(wxTreeEvent_GetLabel, 3426).
+-define(wxTreeEvent_GetOldItem, 3427).
+-define(wxTreeEvent_GetPoint, 3428).
+-define(wxTreeEvent_IsEditCancelled, 3429).
+-define(wxTreeEvent_SetToolTip, 3430).
+-define(wxNotebookEvent_GetOldSelection, 3431).
+-define(wxNotebookEvent_GetSelection, 3432).
+-define(wxNotebookEvent_SetOldSelection, 3433).
+-define(wxNotebookEvent_SetSelection, 3434).
+-define(wxFileDataObject_new, 3435).
+-define(wxFileDataObject_AddFile, 3436).
+-define(wxFileDataObject_GetFilenames, 3437).
+-define(wxFileDataObject_destroy, 3438).
+-define(wxTextDataObject_new, 3439).
+-define(wxTextDataObject_GetTextLength, 3440).
+-define(wxTextDataObject_GetText, 3441).
+-define(wxTextDataObject_SetText, 3442).
+-define(wxTextDataObject_destroy, 3443).
+-define(wxBitmapDataObject_new_1_1, 3444).
+-define(wxBitmapDataObject_new_1_0, 3445).
+-define(wxBitmapDataObject_GetBitmap, 3446).
+-define(wxBitmapDataObject_SetBitmap, 3447).
+-define(wxBitmapDataObject_destroy, 3448).
+-define(wxClipboard_new, 3450).
+-define(wxClipboard_destruct, 3451).
+-define(wxClipboard_AddData, 3452).
+-define(wxClipboard_Clear, 3453).
+-define(wxClipboard_Close, 3454).
+-define(wxClipboard_Flush, 3455).
+-define(wxClipboard_GetData, 3456).
+-define(wxClipboard_IsOpened, 3457).
+-define(wxClipboard_Open, 3458).
+-define(wxClipboard_SetData, 3459).
+-define(wxClipboard_UsePrimarySelection, 3461).
+-define(wxClipboard_IsSupported, 3462).
+-define(wxClipboard_Get, 3463).
+-define(wxSpinEvent_GetPosition, 3464).
+-define(wxSpinEvent_SetPosition, 3465).
+-define(wxSplitterWindow_new_0, 3466).
+-define(wxSplitterWindow_new_2, 3467).
+-define(wxSplitterWindow_destruct, 3468).
+-define(wxSplitterWindow_Create, 3469).
+-define(wxSplitterWindow_GetMinimumPaneSize, 3470).
+-define(wxSplitterWindow_GetSashGravity, 3471).
+-define(wxSplitterWindow_GetSashPosition, 3472).
+-define(wxSplitterWindow_GetSplitMode, 3473).
+-define(wxSplitterWindow_GetWindow1, 3474).
+-define(wxSplitterWindow_GetWindow2, 3475).
+-define(wxSplitterWindow_Initialize, 3476).
+-define(wxSplitterWindow_IsSplit, 3477).
+-define(wxSplitterWindow_ReplaceWindow, 3478).
+-define(wxSplitterWindow_SetSashGravity, 3479).
+-define(wxSplitterWindow_SetSashPosition, 3480).
+-define(wxSplitterWindow_SetSashSize, 3481).
+-define(wxSplitterWindow_SetMinimumPaneSize, 3482).
+-define(wxSplitterWindow_SetSplitMode, 3483).
+-define(wxSplitterWindow_SplitHorizontally, 3484).
+-define(wxSplitterWindow_SplitVertically, 3485).
+-define(wxSplitterWindow_Unsplit, 3486).
+-define(wxSplitterWindow_UpdateSize, 3487).
+-define(wxSplitterEvent_GetSashPosition, 3488).
+-define(wxSplitterEvent_GetX, 3489).
+-define(wxSplitterEvent_GetY, 3490).
+-define(wxSplitterEvent_GetWindowBeingRemoved, 3491).
+-define(wxSplitterEvent_SetSashPosition, 3492).
+-define(wxHtmlWindow_new_0, 3493).
+-define(wxHtmlWindow_new_2, 3494).
+-define(wxHtmlWindow_AppendToPage, 3495).
+-define(wxHtmlWindow_GetOpenedAnchor, 3496).
+-define(wxHtmlWindow_GetOpenedPage, 3497).
+-define(wxHtmlWindow_GetOpenedPageTitle, 3498).
+-define(wxHtmlWindow_GetRelatedFrame, 3499).
+-define(wxHtmlWindow_HistoryBack, 3500).
+-define(wxHtmlWindow_HistoryCanBack, 3501).
+-define(wxHtmlWindow_HistoryCanForward, 3502).
+-define(wxHtmlWindow_HistoryClear, 3503).
+-define(wxHtmlWindow_HistoryForward, 3504).
+-define(wxHtmlWindow_LoadFile, 3505).
+-define(wxHtmlWindow_LoadPage, 3506).
+-define(wxHtmlWindow_SelectAll, 3507).
+-define(wxHtmlWindow_SelectionToText, 3508).
+-define(wxHtmlWindow_SelectLine, 3509).
+-define(wxHtmlWindow_SelectWord, 3510).
+-define(wxHtmlWindow_SetBorders, 3511).
+-define(wxHtmlWindow_SetFonts, 3512).
+-define(wxHtmlWindow_SetPage, 3513).
+-define(wxHtmlWindow_SetRelatedFrame, 3514).
+-define(wxHtmlWindow_SetRelatedStatusBar, 3515).
+-define(wxHtmlWindow_ToText, 3516).
+-define(wxHtmlWindow_destroy, 3517).
+-define(wxHtmlLinkEvent_GetLinkInfo, 3518).
+-define(wxSystemSettings_GetColour, 3519).
+-define(wxSystemSettings_GetFont, 3520).
+-define(wxSystemSettings_GetMetric, 3521).
+-define(wxSystemSettings_GetScreenType, 3522).
+-define(wxSystemOptions_GetOption, 3523).
+-define(wxSystemOptions_GetOptionInt, 3524).
+-define(wxSystemOptions_HasOption, 3525).
+-define(wxSystemOptions_IsFalse, 3526).
+-define(wxSystemOptions_SetOption_2_1, 3527).
+-define(wxSystemOptions_SetOption_2_0, 3528).
+-define(wxAuiNotebookEvent_SetSelection, 3529).
+-define(wxAuiNotebookEvent_GetSelection, 3530).
+-define(wxAuiNotebookEvent_SetOldSelection, 3531).
+-define(wxAuiNotebookEvent_GetOldSelection, 3532).
+-define(wxAuiNotebookEvent_SetDragSource, 3533).
+-define(wxAuiNotebookEvent_GetDragSource, 3534).
+-define(wxAuiManagerEvent_SetManager, 3535).
+-define(wxAuiManagerEvent_GetManager, 3536).
+-define(wxAuiManagerEvent_SetPane, 3537).
+-define(wxAuiManagerEvent_GetPane, 3538).
+-define(wxAuiManagerEvent_SetButton, 3539).
+-define(wxAuiManagerEvent_GetButton, 3540).
+-define(wxAuiManagerEvent_SetDC, 3541).
+-define(wxAuiManagerEvent_GetDC, 3542).
+-define(wxAuiManagerEvent_Veto, 3543).
+-define(wxAuiManagerEvent_GetVeto, 3544).
+-define(wxAuiManagerEvent_SetCanVeto, 3545).
+-define(wxAuiManagerEvent_CanVeto, 3546).
+-define(wxLogNull_new, 3547).
+-define(wxLogNull_destroy, 3548).
+-define(wxTaskBarIcon_new, 3549).
+-define(wxTaskBarIcon_destruct, 3550).
+-define(wxTaskBarIcon_PopupMenu, 3551).
+-define(wxTaskBarIcon_RemoveIcon, 3552).
+-define(wxTaskBarIcon_SetIcon, 3553).
+-define(wxLocale_new_0, 3554).
+-define(wxLocale_new_2, 3556).
+-define(wxLocale_destruct, 3557).
+-define(wxLocale_Init, 3559).
+-define(wxLocale_AddCatalog_1, 3560).
+-define(wxLocale_AddCatalog_3, 3561).
+-define(wxLocale_AddCatalogLookupPathPrefix, 3562).
+-define(wxLocale_GetCanonicalName, 3563).
+-define(wxLocale_GetLanguage, 3564).
+-define(wxLocale_GetLanguageName, 3565).
+-define(wxLocale_GetLocale, 3566).
+-define(wxLocale_GetName, 3567).
+-define(wxLocale_GetString_2, 3568).
+-define(wxLocale_GetString_4, 3569).
+-define(wxLocale_GetHeaderValue, 3570).
+-define(wxLocale_GetSysName, 3571).
+-define(wxLocale_GetSystemEncoding, 3572).
+-define(wxLocale_GetSystemEncodingName, 3573).
+-define(wxLocale_GetSystemLanguage, 3574).
+-define(wxLocale_IsLoaded, 3575).
+-define(wxLocale_IsOk, 3576).
+-define(wxActivateEvent_GetActive, 3577).
+-define(wxPopupWindow_new_2, 3579).
+-define(wxPopupWindow_new_0, 3580).
+-define(wxPopupWindow_destruct, 3582).
+-define(wxPopupWindow_Create, 3583).
+-define(wxPopupWindow_Position, 3584).
+-define(wxPopupTransientWindow_new_0, 3585).
+-define(wxPopupTransientWindow_new_2, 3586).
+-define(wxPopupTransientWindow_destruct, 3587).
+-define(wxPopupTransientWindow_Popup, 3588).
+-define(wxPopupTransientWindow_Dismiss, 3589).
+-define(wxOverlay_new, 3590).
+-define(wxOverlay_destruct, 3591).
+-define(wxOverlay_Reset, 3592).
+-define(wxDCOverlay_new_6, 3593).
+-define(wxDCOverlay_new_2, 3594).
+-define(wxDCOverlay_destruct, 3595).
+-define(wxDCOverlay_Clear, 3596).
+-define(wxDropFilesEvent_GetPosition, 3597).
+-define(wxDropFilesEvent_GetNumberOfFiles, 3598).
+-define(wxDropFilesEvent_GetFiles, 3599).
diff --git a/lib/wx/src/wx_object.erl b/lib/wx/src/wx_object.erl
index 40ee308358..42973335b4 100644
--- a/lib/wx/src/wx_object.erl
+++ b/lib/wx/src/wx_object.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -39,23 +39,35 @@
%% {wxObject, State} | {wxObject, State, Timeout} |
%% ignore | {stop, Reason}
%%
+%% Asynchronous window event handling: <br/>
+%% handle_event(#wx{}, State) should return <br/>
+%% {noreply, State} | {noreply, State, Timeout} | {stop, Reason, State}
+%%
+%% The user module can export the following callback functions:
+%%
%% handle_call(Msg, {From, Tag}, State) should return <br/>
%% {reply, Reply, State} | {reply, Reply, State, Timeout} |
%% {noreply, State} | {noreply, State, Timeout} |
%% {stop, Reason, Reply, State}
%%
-%% Asynchronous window event handling: <br/>
-%% handle_event(#wx{}, State) should return <br/>
-%% {noreply, State} | {noreply, State, Timeout} | {stop, Reason, State}
+%% handle_cast(Msg, State) should return <br/>
+%% {noreply, State} | {noreply, State, Timeout} |
+%% {stop, Reason, State}
+%%
+%% If the above are not exported but called, the wx_object process will crash.
+%% The user module can also export:
%%
%% Info is message e.g. {'EXIT', P, R}, {nodedown, N}, ... <br/>
%% handle_info(Info, State) should return , ... <br/>
%% {noreply, State} | {noreply, State, Timeout} | {stop, Reason, State}
-%%
+%%
+%% If a message is sent to the wx_object process when handle_info is not
+%% exported, the message will be dropped and ignored.
+%%
%% When stop is returned in one of the functions above with Reason =
%% normal | shutdown | Term, terminate(State) is called. It lets the
%% user module clean up, it is always called when server terminates or
-%% when wxObject() in the driver is deleted. If the Parent process
+%% when wx_object() in the driver is deleted. If the Parent process
%% terminates the Module:terminate/2 function is called. <br/>
%% terminate(Reason, State)
%%
@@ -135,6 +147,8 @@
{'noreply', NewState :: term()} |
{'noreply', NewState :: term(), timeout() | 'hibernate'} |
{'stop', Reason :: term(), NewState :: term()}.
+-callback handle_sync_event(Request :: #wx{}, Ref :: #wx_ref{}, State :: term()) ->
+ ok.
-callback terminate(Reason :: ('normal' | 'shutdown' | {'shutdown', term()} |
term()),
State :: term()) ->
@@ -143,6 +157,9 @@
Extra :: term()) ->
{'ok', NewState :: term()} | {'error', Reason :: term()}.
+-optional_callbacks(
+ [handle_call/3, handle_cast/2, handle_info/2,
+ handle_sync_event/3, terminate/2, code_change/3]).
%% System exports
-export([system_continue/3,
@@ -171,58 +188,59 @@
%% -----------------------------------------------------------------
-%% @spec (Mod, Args, Options) -> wxWindow:wxWindow()
-%% Mod = atom()
-%% Args = term()
-%% Options = [{timeout, Timeout} | {debug, [Flag]}]
-%% Flag = trace | log | {logfile, File} | statistics | debug
%% @doc Starts a generic wx_object server and invokes Mod:init(Args) in the
%% new process.
+-spec start(Mod, Args, Options) -> wxWindow:wxWindow() | {error, term()} when
+ Mod::atom(),
+ Args::term(),
+ Flag::trace | log | {logfile, string()} | statistics | debug,
+ Options::[{timeout, timeout()} | {debug, [Flag]}].
start(Mod, Args, Options) ->
gen_response(gen:start(?MODULE, nolink, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
-
-%% @spec (Name, Mod, Args, Options) -> wxWindow:wxWindow()
-%% Name = {local, atom()}
-%% Mod = atom()
-%% Args = term()
-%% Options = [{timeout, Timeout} | {debug, [Flag]}]
-%% Flag = trace | log | {logfile, File} | statistics | debug
+
%% @doc Starts a generic wx_object server and invokes Mod:init(Args) in the
%% new process.
+-spec start(Name, Mod, Args, Options) -> wxWindow:wxWindow() | {error, term()} when
+ Name::{local, atom()},
+ Mod::atom(),
+ Args::term(),
+ Flag::trace | log | {logfile, string()} | statistics | debug,
+ Options::[{timeout, timeout()} | {debug, [Flag]}].
start(Name, Mod, Args, Options) ->
gen_response(gen:start(?MODULE, nolink, Name, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
-%% @spec (Mod, Args, Options) -> wxWindow:wxWindow()
-%% Mod = atom()
-%% Args = term()
-%% Options = [{timeout, Timeout} | {debug, [Flag]}]
-%% Flag = trace | log | {logfile, File} | statistics | debug
%% @doc Starts a generic wx_object server and invokes Mod:init(Args) in the
%% new process.
+-spec start_link(Mod, Args, Options) -> wxWindow:wxWindow() | {error, term()} when
+ Mod::atom(),
+ Args::term(),
+ Flag::trace | log | {logfile, string()} | statistics | debug,
+ Options::[{timeout, timeout()} | {debug, [Flag]}].
start_link(Mod, Args, Options) ->
gen_response(gen:start(?MODULE, link, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
-%% @spec (Name, Mod, Args, Options) -> wxWindow:wxWindow()
-%% Name = {local, atom()}
-%% Mod = atom()
-%% Args = term()
-%% Options = [{timeout, Timeout} | {debug, [Flag]}]
-%% Flag = trace | log | {logfile, File} | statistics | debug
%% @doc Starts a generic wx_object server and invokes Mod:init(Args) in the
%% new process.
+-spec start_link(Name, Mod, Args, Options) -> wxWindow:wxWindow() | {error, term()} when
+ Name::{local, atom()},
+ Mod::atom(),
+ Args::term(),
+ Flag::trace | log | {logfile, string()} | statistics | debug,
+ Options::[{timeout, timeout()} | {debug, [Flag]}].
start_link(Name, Mod, Args, Options) ->
gen_response(gen:start(?MODULE, link, Name, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
-
+
gen_response({ok, Pid}) ->
receive {ack, Pid, Ref = #wx_ref{}} -> Ref end;
gen_response(Reply) ->
Reply.
-%% @spec (Ref::wxObject()|atom()|pid()) -> ok
%% @doc Stops a generic wx_object server with reason 'normal'.
%% Invokes terminate(Reason,State) in the server. The call waits until
%% the process is terminated. If the process does not exist, an
%% exception is raised.
+-spec stop(Obj) -> ok when
+ Obj::wx:wx_object()|atom()|pid().
stop(Ref = #wx_ref{state=Pid}) when is_pid(Pid) ->
try
gen:stop(Pid)
@@ -236,11 +254,14 @@ stop(Name) when is_atom(Name) orelse is_pid(Name) ->
erlang:error({ExitReason, {?MODULE, stop, [Name]}})
end.
-%% @spec (Ref::wxObject()|atom()|pid(), Reason::term(), Timeout::timeout()) -> ok
%% @doc Stops a generic wx_object server with the given Reason.
%% Invokes terminate(Reason,State) in the server. The call waits until
%% the process is terminated. If the call times out, or if the process
%% does not exist, an exception is raised.
+-spec stop(Obj, Reason, Timeout) -> ok when
+ Obj::wx:wx_object()|atom()|pid(),
+ Reason::term(),
+ Timeout::timeout().
stop(Ref = #wx_ref{state=Pid}, Reason, Timeout) when is_pid(Pid) ->
try
gen:stop(Pid, Reason, Timeout)
@@ -254,12 +275,14 @@ stop(Name, Reason, Timeout) when is_atom(Name) orelse is_pid(Name) ->
erlang:error({ExitReason, {?MODULE, stop, [Name, Reason, Timeout]}})
end.
-%% @spec (Ref::wxObject()|atom()|pid(), Request::term()) -> term()
%% @doc Make a call to a wx_object server.
%% The call waits until it gets a result.
%% Invokes handle_call(Request, From, State) in the server
+-spec call(Obj, Request) -> term() when
+ Obj::wx:wx_object()|atom()|pid(),
+ Request::term().
call(Ref = #wx_ref{state=Pid}, Request) when is_pid(Pid) ->
- try
+ try
{ok,Res} = gen:call(Pid, '$gen_call', Request, infinity),
Res
catch _:Reason ->
@@ -272,10 +295,13 @@ call(Name, Request) when is_atom(Name) orelse is_pid(Name) ->
catch _:Reason ->
erlang:error({Reason, {?MODULE, call, [Name, Request]}})
end.
-
-%% @spec (Ref::wxObject()|atom()|pid(), Request::term(), Timeout::integer()) -> term()
+
%% @doc Make a call to a wx_object server with a timeout.
%% Invokes handle_call(Request, From, State) in server
+-spec call(Obj, Request, Timeout) -> term() when
+ Obj::wx:wx_object()|atom()|pid(),
+ Request::term(),
+ Timeout::integer().
call(Ref = #wx_ref{state=Pid}, Request, Timeout) when is_pid(Pid) ->
try
{ok,Res} = gen:call(Pid, '$gen_call', Request, Timeout),
@@ -291,10 +317,11 @@ call(Name, Request, Timeout) when is_atom(Name) orelse is_pid(Name) ->
erlang:error({Reason, {?MODULE, call, [Name, Request, Timeout]}})
end.
-%% @spec (Ref::wxObject()|atom()|pid(), Request::term()) -> ok
%% @doc Make a cast to a wx_object server.
%% Invokes handle_cast(Request, State) in the server
-
+-spec cast(Obj, Request) -> ok when
+ Obj::wx:wx_object()|atom()|pid(),
+ Request::term().
cast(#wx_ref{state=Pid}, Request) when is_pid(Pid) ->
Pid ! {'$gen_cast',Request},
ok;
@@ -302,21 +329,23 @@ cast(Name, Request) when is_atom(Name) orelse is_pid(Name) ->
Name ! {'$gen_cast',Request},
ok.
-%% @spec (Ref::wxObject()) -> pid()
%% @doc Get the pid of the object handle.
+-spec get_pid(Obj) -> pid() when
+ Obj::wx:wx_object()|atom()|pid().
get_pid(#wx_ref{state=Pid}) when is_pid(Pid) ->
Pid.
-%% @spec (Ref::wxObject(), pid()) -> wxObject()
%% @doc Sets the controlling process of the object handle.
+-spec set_pid(Obj, pid()) -> wx:wx_object() when
+ Obj::wx:wx_object()|atom()|pid().
set_pid(#wx_ref{}=R, Pid) when is_pid(Pid) ->
R#wx_ref{state=Pid}.
%% -----------------------------------------------------------------
%% Send a reply to the client.
%% -----------------------------------------------------------------
-%% @spec (From::tuple(), Reply::term()) -> pid()
%% @doc Get the pid of the object handle.
+-spec reply({pid(), Tag::term()}, Reply::term()) -> pid().
reply({To, Tag}, Reply) ->
catch To ! {Tag, Reply}.
@@ -414,6 +443,7 @@ dispatch(Msg = #wx{}, Mod, State) ->
Mod:handle_event(Msg, State);
dispatch(Info, Mod, State) ->
Mod:handle_info(Info, State).
+
%% @hidden
handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod) ->
case catch Mod:handle_call(Msg, From, State) of
@@ -435,8 +465,12 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod) ->
Other -> handle_common_reply(Other, Name, Msg, Mod, State, [])
end;
handle_msg(Msg, Parent, Name, State, Mod) ->
- Reply = (catch dispatch(Msg, Mod, State)),
- handle_no_reply(Reply, Parent, Name, Msg, Mod, State, []).
+ case catch dispatch(Msg, Mod, State) of
+ {'EXIT', {undef, [{Mod, handle_info, [_,_], _}|_]}} ->
+ handle_no_reply({noreply, State}, Parent, Name, Msg, Mod, State, []);
+ Reply ->
+ handle_no_reply(Reply, Parent, Name, Msg, Mod, State, [])
+ end.
%% @hidden
handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Debug) ->
@@ -516,8 +550,8 @@ system_terminate(Reason, _Parent, Debug, [Name, State, Mod, _Time]) ->
%% @hidden
system_code_change([Name, State, Mod, Time], _Module, OldVsn, Extra) ->
case catch Mod:code_change(OldVsn, State, Extra) of
- {ok, NewState} -> {ok, [Name, NewState, Mod, Time]};
- Else -> Else
+ {ok, NewState} -> {ok, [Name, NewState, Mod, Time]};
+ Else -> Else
end.
%%-----------------------------------------------------------------
@@ -548,7 +582,7 @@ print_event(Dev, Event, Name) ->
%%% ---------------------------------------------------
%% @hidden
terminate(Reason, Name, Msg, Mod, State, Debug) ->
- case catch Mod:terminate(Reason, State) of
+ case try_terminate(Mod, Reason, State) of
{'EXIT', R} ->
error_info(R, Name, Msg, State, Debug),
exit(R);
@@ -565,6 +599,15 @@ terminate(Reason, Name, Msg, Mod, State, Debug) ->
exit(Reason)
end
end.
+
+try_terminate(Mod, Reason, State) ->
+ case erlang:function_exported(Mod, terminate, 2) of
+ true ->
+ catch Mod:terminate(Reason, State);
+ _ ->
+ ok
+ end.
+
%% @hidden
error_info(_Reason, application_controller, _Msg, _State, _Debug) ->
ok;
diff --git a/lib/wx/src/wxe.hrl b/lib/wx/src/wxe.hrl
index da65cb939d..0f42d7e82e 100644
--- a/lib/wx/src/wxe.hrl
+++ b/lib/wx/src/wxe.hrl
@@ -44,6 +44,8 @@
-define(I, signed-native).
-define(F, float-native).
+-define(is_chardata(String), (is_list(String) orelse is_binary(String))).
+
-define(WXE_IDENTIFIER, wx_env).
-define(BATCH_BEGIN, 0).
-define(BATCH_END, 1).
diff --git a/lib/wx/src/wxe_master.erl b/lib/wx/src/wxe_master.erl
index e17a3327ac..ce859b3eb3 100644
--- a/lib/wx/src/wxe_master.erl
+++ b/lib/wx/src/wxe_master.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -82,8 +82,14 @@ init_port(SilentStart) ->
%% Initalizes the opengl library
%%--------------------------------------------------------------------
init_opengl() ->
- GLLib = wxe_util:wxgl_dl(),
- wxe_util:call(?WXE_INIT_OPENGL, <<(list_to_binary(GLLib))/binary, 0:8>>).
+ case get(wx_init_opengl) of
+ true -> {ok, "already initialized"};
+ _ ->
+ GLLib = wxe_util:wxgl_dl(),
+ Res = wxe_util:call(?WXE_INIT_OPENGL, <<(list_to_binary(GLLib))/binary, 0:8>>),
+ element(1, Res) =:= ok andalso put(wx_init_opengl, true),
+ Res
+ end.
%%--------------------------------------------------------------------
%% Fetch early messages, hack to get start up args on mac
diff --git a/lib/wx/test/Makefile b/lib/wx/test/Makefile
index 9a78307be1..2eaf2f8ae5 100644
--- a/lib/wx/test/Makefile
+++ b/lib/wx/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2008-2016. All Rights Reserved.
+# Copyright Ericsson AB 2008-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@ APPDIR = $(shell dirname $(PWD))
ERL_COMPILE_FLAGS = -pa $(APPDIR)/ebin
Mods = wxt wx_test_lib wx_obj_test \
+ wx_oc_object \
wx_app_SUITE \
wx_basic_SUITE \
wx_event_SUITE \
diff --git a/lib/wx/test/wx_basic_SUITE.erl b/lib/wx/test/wx_basic_SUITE.erl
index 6a2528780e..d53bd3c15a 100644
--- a/lib/wx/test/wx_basic_SUITE.erl
+++ b/lib/wx/test/wx_basic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -49,10 +49,13 @@ suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap,{minutes,2}}].
all() ->
[silent_start, create_window, several_apps, wx_api, wx_misc,
- data_types, wx_object].
+ data_types, wx_object, {group, undef_callbacks},
+ undef_in_handle_info, undef_in_terminate].
groups() ->
- [].
+ [{undef_callbacks, [],
+ [undef_handle_event, undef_handle_call, undef_handle_cast, undef_handle_info,
+ undef_code_change, undef_terminate1, undef_terminate2]}].
init_per_group(_GroupName, Config) ->
Config.
@@ -426,6 +429,154 @@ wx_object(Config) ->
catch wx:destroy(),
ok.
+%% Test that the server crashes correctly if the handle_event callback is
+%% not exported in the callback module
+undef_handle_event(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+undef_handle_event(_Config) ->
+ wx:new(),
+ {_, _, _, Pid} = wx_object:start(wx_oc_object, [], []),
+ MRef = monitor(process, Pid),
+ %% Mock a call to handle_event
+ Pid ! {wx, a, b, c, d},
+ ok = receive
+ {'DOWN', MRef, process, Pid,
+ {undef, [{wx_oc_object, handle_event, _, _}|_]}} ->
+ ok
+ after 5000 ->
+ ct:fail(should_crash)
+ end.
+
+%% Test that the server crashes correctly if the handle_call callback is
+%% not exported in the callback module
+undef_handle_call(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+undef_handle_call(_Config) ->
+ wx:new(),
+ Frame = wx_object:start(wx_oc_object, [], []),
+ try
+ wx_object:call(Frame, call_msg),
+ ct:fail(should_crash)
+ catch error:{{undef, [{wx_oc_object,handle_call, _, _}|_]},
+ {wx_object,call,_}} ->
+ ok
+ end.
+
+%% Test that the server crashes correctly if the handle_cast callback is
+%% not exported in the callback module
+undef_handle_cast(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+undef_handle_cast(_Config) ->
+ wx:new(),
+ {_, _, _, Pid} = Frame = wx_object:start(wx_oc_object, [], []),
+ MRef = monitor(process, Pid),
+ wx_object:cast(Frame, cast_msg),
+ ok = receive
+ {'DOWN', MRef, process, Pid,
+ {undef, [{wx_oc_object, handle_cast, _, _}|_]}} ->
+ ok
+ after 5000 ->
+ ct:fail(should_crash)
+ end.
+
+%% Test the default implementation of handle_info if the callback module
+%% does not export it
+undef_handle_info(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+undef_handle_info(_Config) ->
+ wx:new(),
+ {_, _, _, Pid} = wx_object:start(wx_oc_object, [], []),
+ MRef = monitor(process, Pid),
+ Pid ! test,
+ receive
+ {'DOWN', MRef, process, Pid, _} ->
+ ct:fail(should_not_crash)
+ after 500 ->
+ ok
+ end,
+ ok = wx_object:stop(Pid).
+
+%% Test the server crashes correctly if called and the code_change callback is
+%% not exported in the callback module
+undef_code_change(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+undef_code_change(_Config) ->
+ wx:new(),
+ {_, _, _, Pid} = wx_object:start(wx_oc_object, [], []),
+ sys:suspend(Pid),
+ sys:replace_state(Pid, fun([P, S, M, T]) -> [P, {new, S}, M, T] end),
+ {error, {'EXIT', {undef, [{wx_oc_object,code_change, [_, _, _], _}|_]}}}
+ = sys:change_code(Pid, wx_oc_object, old_vsn, []),
+ ok = sys:resume(Pid),
+ ok = wx_object:stop(Pid).
+
+%% Test the default implementation of terminate if the callback module
+%% does not export it
+undef_terminate1(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+undef_terminate1(_Config) ->
+ ok = terminate([], normal).
+
+%% Test the default implementation of terminate if the callback module
+%% does not export it
+undef_terminate2(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+undef_terminate2(_Config) ->
+ ok = terminate([{error, test}, infinity], {error, test}).
+
+terminate(ArgsTl, Reason) ->
+ wx:new(),
+ {_, _, _, Pid} = wx_object:start(wx_oc_object, [], []),
+ MRef = monitor(process, Pid),
+ ok = apply(wx_object, stop, [Pid|ArgsTl]),
+ receive
+ {'DOWN', MRef, process, Pid, Reason} ->
+ ok
+ after 1000 ->
+ ct:fail(failed)
+ end.
+
+%% Test that the server crashes correctly if the handle_info callback is
+%% calling an undefined function
+undef_in_handle_info(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+undef_in_handle_info(_Config) ->
+ wx:new(),
+ Init = ui_init_fun(),
+ {_, _, _, Pid} = wx_object:start(wx_obj_test,
+ [{parent, self()}, {init, Init}], []),
+ unlink(Pid),
+ MRef = monitor(process, Pid),
+ Pid ! {call_undef_fun, {wx_obj_test, handle_info}},
+ receive
+ {'DOWN', MRef, process, Pid,
+ {undef, [{wx_obj_test, handle_info, _, _}|_]}} ->
+ ok
+ after 1000 ->
+ ct:fail(failed)
+ end,
+ ok.
+
+%% Test that the server crashes correctly if the terminate callback is
+%% calling an undefined function
+undef_in_terminate(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+undef_in_terminate(_Config) ->
+ wx:new(),
+ Init = ui_init_fun(),
+ Frame = wx_object:start(wx_obj_test,
+ [{parent, self()}, {init, Init},
+ {terminate, {wx_obj_test, terminate}}], []),
+ try
+ wx_object:stop(Frame),
+ ct:fail(should_crash)
+ catch error:{{undef, [{wx_obj_test, terminate, _, _}|_]}, _} ->
+ ok
+ end.
+
+ui_init_fun() ->
+ Init = fun() ->
+ Frame0 = wxFrame:new(wx:null(), ?wxID_ANY, "Test wx_object", [{size, {500, 400}}]),
+ Frame = wx_object:set_pid(Frame0, self()),
+ Sz = wxBoxSizer:new(?wxHORIZONTAL),
+ Panel = wxPanel:new(Frame),
+ wxSizer:add(Sz, Panel, [{flag, ?wxEXPAND}, {proportion, 1}]),
+ wxWindow:show(Frame),
+ {Frame, {Frame, Panel}}
+ end,
+ Init.
+
check_events(Msgs) ->
check_events(Msgs, 0,0).
diff --git a/lib/wx/test/wx_obj_test.erl b/lib/wx/test/wx_obj_test.erl
index 23142e28b2..65ecb4f50d 100644
--- a/lib/wx/test/wx_obj_test.erl
+++ b/lib/wx/test/wx_obj_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -79,6 +79,9 @@ handle_cast(What, State = #state{parent=Pid}) ->
Pid ! {cast, What},
{noreply, State}.
+handle_info({call_undef_fun, {Mod, Fun}}, State) ->
+ Mod:Fun(),
+ {noreply, State};
handle_info(What, State = #state{parent=Pid}) ->
Pid ! {info, What},
{noreply, State}.
@@ -87,6 +90,8 @@ terminate(What, #state{parent=Pid, opts=Opts, user_state=US}) ->
case proplists:get_value(terminate, Opts) of
undefined ->
ok;
+ {Mod, Fun} ->
+ Mod:Fun();
Terminate ->
Terminate(US)
end,
diff --git a/lib/wx/test/wx_oc_object.erl b/lib/wx/test/wx_oc_object.erl
new file mode 100644
index 0000000000..3924202410
--- /dev/null
+++ b/lib/wx/test/wx_oc_object.erl
@@ -0,0 +1,44 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
+%% See the License for the specific language governing permissions and
+%% limitations under the License
+%%
+%% %CopyrightEnd%
+%%
+-module(wx_oc_object).
+-include_lib("wx/include/wx.hrl").
+
+-behaviour(wx_object).
+
+%% gen_server callbacks
+-export([init/1]).
+
+-record(state, {}).
+
+init([]) ->
+ Init = fun() ->
+ Frame0 = wxFrame:new(wx:null(), ?wxID_ANY, "Test wx_object", [{size, {500, 400}}]),
+ Frame = wx_object:set_pid(Frame0, self()),
+ Sz = wxBoxSizer:new(?wxHORIZONTAL),
+ Panel = wxPanel:new(Frame),
+ wxSizer:add(Sz, Panel, [{flag, ?wxEXPAND}, {proportion, 1}]),
+ wxWindow:show(Frame),
+ {Frame, {Frame, Panel}}
+ end,
+ {Obj, _UserState} = Init(),
+ {Obj, #state{}};
+init([Init]) ->
+ {Obj, _UserState} = Init(),
+ {Obj, #state{}}.
diff --git a/lib/wx/test/wx_opengl_SUITE.erl b/lib/wx/test/wx_opengl_SUITE.erl
index 643a0df6a3..3de9209fae 100644
--- a/lib/wx/test/wx_opengl_SUITE.erl
+++ b/lib/wx/test/wx_opengl_SUITE.erl
@@ -111,6 +111,8 @@ canvas(Config) ->
?m(false, wx:is_null(wxGLCanvas:getContext(Canvas))),
?m({'EXIT', {{error, no_gl_context,_},_}}, gl:getString(?GL_VENDOR)),
+ gl:viewport(0,0,50,50), %% Show cause an error report
+
?m(ok, wxGLCanvas:setCurrent(Canvas)),
io:format("Vendor: ~s~n", [gl:getString(?GL_VENDOR)]),
diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk
index de4e5e1935..b9100e7c87 100644
--- a/lib/wx/vsn.mk
+++ b/lib/wx/vsn.mk
@@ -1 +1 @@
-WX_VSN = 1.7
+WX_VSN = 1.8.1
diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml
index 0abcb87998..1162561225 100644
--- a/lib/xmerl/doc/src/notes.xml
+++ b/lib/xmerl/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,6 +32,116 @@
<p>This document describes the changes made to the Xmerl application.</p>
+<section><title>Xmerl 1.3.15</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Improves accumulator fun in xmerl_scan so that only one
+ #xmlText record is returned for strings which have
+ character references.</p>
+ <p>
+ (Thanks to Jimmy Zöger)</p>
+ <p>
+ Own Id: OTP-14377 Aux Id: PR-1369 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Xmerl 1.3.14</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> A couple of bugs are fixed in the sax parser
+ (xmerl_sax_parser). </p> <list> <item>The continuation
+ function was not called correctly when the XML directive
+ was fragmented. </item> <item>When the event callback
+ modules (xmerl_sax_old_dom and xmerl_sax_simple) got an
+ endDocument event at certain conditions the parser
+ crashed.</item> <item>Replaced internal ets table with
+ map to avoid table leakage.</item> </list>
+ <p>
+ Own Id: OTP-14430</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Xmerl 1.3.13</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The namespace_conformant option in xmerl_scan did not
+ work when parsing documents without explicit XML
+ namespace declaration.</p>
+ <p>
+ Own Id: OTP-14139</p>
+ </item>
+ <item>
+ <p> Fix a "well-formedness" bug in the XML Sax parser so
+ it returns an error if there are something more in the
+ file after the matching document. If one using the
+ xmerl_sax_parser:stream() a rest is allowed which then
+ can be sent to a new call of xmerl_sax_parser:stream() to
+ parse next document. </p> <p> This is done to be
+ compliant with XML conformance tests. </p>
+ <p>
+ Own Id: OTP-14211</p>
+ </item>
+ <item>
+ <p> Fixed compiler and dialyzer warnings in the XML SAX
+ parser. </p>
+ <p>
+ Own Id: OTP-14212</p>
+ </item>
+ <item>
+ <p> Change how to interpret end of document in the XML
+ SAX parser to comply with Tim Brays comment on the
+ standard. This makes it possible to handle more than one
+ doc on a stream, the standard makes it impossible to know
+ when the document is ended without waiting for the next
+ document (and not always even that). </p> <p> Tim Brays
+ comment: </p> <p> Trailing "Misc"<br/> The fact that
+ you're allowed some trailing junk after the root element,
+ I decided (but unfortunately too late) is a real design
+ error in XML. If I'm writing a network client, I'm
+ probably going to close the link as soon as a I see the
+ root element end-tag, and not depend on the other end
+ closing it down properly.<br/> Furthermore, if I want to
+ send a succession of XML documents over a network link,
+ if I find a processing instruction after a root element,
+ is it a trailer on the previous document, or part of the
+ prolog of the next? </p>
+ <p>
+ Own Id: OTP-14213</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Xmerl 1.3.12</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix a number of broken links in the xmerl
+ documentation. </p>
+ <p>
+ Own Id: OTP-13880</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Xmerl 1.3.11</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/xmerl/notes.html b/lib/xmerl/notes.html
deleted file mode 100644
index 43610a37fa..0000000000
--- a/lib/xmerl/notes.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<HTML>
-<HEAD>
- <TITLE>xmerl Release Notes</TITLE>
- <style type="text/css">
-<!--
- body { background: white; margin: 3em }
-
- body { font-family: Verdana, Arial, Helvetica, sans-serif }
- h1 h2 h3 h4 { font-family: Verdana, Arial, Helvetica, sans-serif }
- h1 { font-size: 48 }
- p li { font-family: Verdana, Arial, Helvetica, sans-serif }
--->
- </style>
-</HEAD>
-
-<BODY BGCOLOR="#FFFFFF">
-
-<CENTER><H1>xmerl Release Notes</H1></CENTER>
-
-<h2>xmerl 1.0</h2>
-
-
-<p>
-There are also release notes for
-<a href="notes_history.html">older versions</a>.
-
-</body>
-</html>
diff --git a/lib/xmerl/src/xmerl_eventp.erl b/lib/xmerl/src/xmerl_eventp.erl
index 2cb76abc6e..8d7ea25e24 100644
--- a/lib/xmerl/src/xmerl_eventp.erl
+++ b/lib/xmerl/src/xmerl_eventp.erl
@@ -25,6 +25,90 @@
%% Each contain more elaborate settings of xmerl_scan that makes usage of
%% the customization functions.
%%
+%% @type xmlElement() = #xmlElement{}.
+%%
+%% @type option_list(). <p>Options allow to customize the behaviour of the
+%% scanner.
+%% See also <a href="xmerl_examples.html">tutorial</a> on customization
+%% functions.
+%% </p>
+%% <p>
+%% Possible options are:
+%% </p>
+%% <dl>
+%% <dt><code>{acc_fun, Fun}</code></dt>
+%% <dd>Call back function to accumulate contents of entity.</dd>
+%% <dt><code>{continuation_fun, Fun} |
+%% {continuation_fun, Fun, ContinuationState}</code></dt>
+%% <dd>Call back function to decide what to do if the scanner runs into EOF
+%% before the document is complete.</dd>
+%% <dt><code>{event_fun, Fun} |
+%% {event_fun, Fun, EventState}</code></dt>
+%% <dd>Call back function to handle scanner events.</dd>
+%% <dt><code>{fetch_fun, Fun} |
+%% {fetch_fun, Fun, FetchState}</code></dt>
+%% <dd>Call back function to fetch an external resource.</dd>
+%% <dt><code>{hook_fun, Fun} |
+%% {hook_fun, Fun, HookState}</code></dt>
+%% <dd>Call back function to process the document entities once
+%% identified.</dd>
+%% <dt><code>{close_fun, Fun}</code></dt>
+%% <dd>Called when document has been completely parsed.</dd>
+%% <dt><code>{rules, ReadFun, WriteFun, RulesState} |
+%% {rules, Rules}</code></dt>
+%% <dd>Handles storing of scanner information when parsing.</dd>
+%% <dt><code>{user_state, UserState}</code></dt>
+%% <dd>Global state variable accessible from all customization functions</dd>
+%%
+%% <dt><code>{fetch_path, PathList}</code></dt>
+%% <dd>PathList is a list of
+%% directories to search when fetching files. If the file in question
+%% is not in the fetch_path, the URI will be used as a file
+%% name.</dd>
+%% <dt><code>{space, Flag}</code></dt>
+%% <dd>'preserve' (default) to preserve spaces, 'normalize' to
+%% accumulate consecutive whitespace and replace it with one space.</dd>
+%% <dt><code>{line, Line}</code></dt>
+%% <dd>To specify starting line for scanning in document which contains
+%% fragments of XML.</dd>
+%% <dt><code>{namespace_conformant, Flag}</code></dt>
+%% <dd>Controls whether to behave as a namespace conformant XML parser,
+%% 'false' (default) to not otherwise 'true'.</dd>
+%% <dt><code>{validation, Flag}</code></dt>
+%% <dd>Controls whether to process as a validating XML parser:
+%% 'off' (default) no validation, or validation 'dtd' by DTD or 'schema'
+%% by XML Schema. 'false' and 'true' options are obsolete
+%% (i.e. they may be removed in a future release), if used 'false'
+%% equals 'off' and 'true' equals 'dtd'.</dd>
+%% <dt><code>{schemaLocation, [{Namespace,Link}|...]}</code></dt>
+%% <dd>Tells explicitly which XML Schema documents to use to validate
+%% the XML document. Used together with the
+%% <code>{validation,schema}</code> option.</dd>
+%% <dt><code>{quiet, Flag}</code></dt>
+%% <dd>Set to 'true' if xmerl should behave quietly and not output any
+%% information to standard output (default 'false').</dd>
+%% <dt><code>{doctype_DTD, DTD}</code></dt>
+%% <dd>Allows to specify DTD name when it isn't available in the XML
+%% document. This option has effect only together with
+%% <code>{validation,'dtd'</code> option.</dd>
+%% <dt><code>{xmlbase, Dir}</code></dt>
+%% <dd>XML Base directory. If using string/1 default is current directory.
+%% If using file/1 default is directory of given file.</dd>
+%% <dt><code>{encoding, Enc}</code></dt>
+%% <dd>Set default character set used (default UTF-8).
+%% This character set is used only if not explicitly given by the XML
+%% declaration. </dd>
+%% <dt><code>{document, Flag}</code></dt>
+%% <dd>Set to 'true' if xmerl should return a complete XML document
+%% as an xmlDocument record (default 'false').</dd>
+%% <dt><code>{comments, Flag}</code></dt>
+%% <dd>Set to 'false' if xmerl should skip comments otherwise they will
+%% be returned as xmlComment records (default 'true').</dd>
+%% <dt><code>{default_attrs, Flag}</code></dt>
+%% <dd>Set to 'true' if xmerl should add to elements missing attributes
+%% with a defined default value (default 'false').</dd>
+%% </dl>
+%%
-module(xmerl_eventp).
-vsn('0.19').
-date('03-09-17').
diff --git a/lib/xmerl/src/xmerl_regexp.erl b/lib/xmerl/src/xmerl_regexp.erl
index fc89b80ff1..1bf8496673 100644
--- a/lib/xmerl/src/xmerl_regexp.erl
+++ b/lib/xmerl/src/xmerl_regexp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1154,7 +1154,7 @@ comp_crs([], Last) -> [{Last,maxchar}].
%% build_dfa(NFA, NfaStartState) -> {DFA,DfaStartState}.
%% Build a DFA from an NFA using "subset construction". The major
%% difference from the book is that we keep the marked and unmarked
-%% DFA states in seperate lists. New DFA states are added to the
+%% DFA states in separate lists. New DFA states are added to the
%% unmarked list and states are marked by moving them to the marked
%% list. We assume that the NFA accepting state numbers are in
%% ascending order for the rules and use ordsets to keep this order.
diff --git a/lib/xmerl/src/xmerl_sax_old_dom.erl b/lib/xmerl/src/xmerl_sax_old_dom.erl
index fefcf03fce..6d0d836487 100644
--- a/lib/xmerl/src/xmerl_sax_old_dom.erl
+++ b/lib/xmerl/src/xmerl_sax_old_dom.erl
@@ -2,7 +2,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -127,9 +127,10 @@ build_dom(endDocument,
State#xmerl_sax_old_dom_state{dom=[Decl, Current#xmlElement{
content=lists:reverse(C)
}]};
- _ ->
- %%?dbg("~p\n", [D]),
- ?error("we're not at end the document when endDocument event is encountered.")
+ _ ->
+ %% endDocument is also sent by the parser when a fault occur to tell
+ %% the event receiver that no more input will be sent
+ State
end;
%% Element
diff --git a/lib/xmerl/src/xmerl_sax_parser.erl b/lib/xmerl/src/xmerl_sax_parser.erl
index 318a0cf7f4..e383c4c349 100644
--- a/lib/xmerl/src/xmerl_sax_parser.erl
+++ b/lib/xmerl/src/xmerl_sax_parser.erl
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,6 +33,7 @@
%% External exports
%%----------------------------------------------------------------------
-export([file/2,
+ stream/3,
stream/2]).
%%----------------------------------------------------------------------
@@ -63,7 +64,7 @@
%% Description: Parse file containing an XML document.
%%----------------------------------------------------------------------
file(Name,Options) ->
- case file:open(Name, [raw, read,binary]) of
+ case file:open(Name, [raw, read_ahead, read,binary]) of
{error, Reason} ->
{error,{Name, file:format_error(Reason)}};
{ok, FD} ->
@@ -72,11 +73,12 @@ file(Name,Options) ->
File = filename:basename(Name),
ContinuationFun = fun default_continuation_cb/1,
Res = stream(<<>>,
- [{continuation_fun, ContinuationFun},
- {continuation_state, FD},
- {current_location, CL},
- {entity, File}
- |Options]),
+ [{continuation_fun, ContinuationFun},
+ {continuation_state, FD},
+ {current_location, CL},
+ {entity, File}
+ |Options],
+ file),
ok = file:close(FD),
Res
end.
@@ -92,19 +94,22 @@ file(Name,Options) ->
%% EventState = term()
%% Description: Parse a stream containing an XML document.
%%----------------------------------------------------------------------
-stream(Xml, Options) when is_list(Xml), is_list(Options) ->
+stream(Xml, Options) ->
+ stream(Xml, Options, stream).
+
+stream(Xml, Options, InputType) when is_list(Xml), is_list(Options) ->
State = parse_options(Options, initial_state()),
- case State#xmerl_sax_parser_state.file_type of
+ case State#xmerl_sax_parser_state.file_type of
dtd ->
xmerl_sax_parser_list:parse_dtd(Xml,
State#xmerl_sax_parser_state{encoding = list,
- input_type = stream});
+ input_type = InputType});
normal ->
xmerl_sax_parser_list:parse(Xml,
State#xmerl_sax_parser_state{encoding = list,
- input_type = stream})
+ input_type = InputType})
end;
-stream(Xml, Options) when is_binary(Xml), is_list(Options) ->
+stream(Xml, Options, InputType) when is_binary(Xml), is_list(Options) ->
case parse_options(Options, initial_state()) of
{error, Reason} -> {error, Reason};
State ->
@@ -115,21 +120,22 @@ stream(Xml, Options) when is_binary(Xml), is_list(Options) ->
normal ->
parse
end,
- case detect_charset(Xml, State) of
- {error, Reason} -> {fatal_error,
- {
- State#xmerl_sax_parser_state.current_location,
- State#xmerl_sax_parser_state.entity,
- 1
- },
- Reason,
- [],
- State#xmerl_sax_parser_state.event_state};
- {Xml1, State1} ->
- parse_binary(Xml1,
- State1#xmerl_sax_parser_state{input_type = stream},
- ParseFunction)
- end
+ try
+ {Xml1, State1} = detect_charset(Xml, State),
+ parse_binary(Xml1,
+ State1#xmerl_sax_parser_state{input_type = InputType},
+ ParseFunction)
+ catch
+ throw:{fatal_error, {State2, Reason}} ->
+ {fatal_error,
+ {
+ State2#xmerl_sax_parser_state.current_location,
+ State2#xmerl_sax_parser_state.entity,
+ 1
+ },
+ Reason, [],
+ State2#xmerl_sax_parser_state.event_state}
+ end
end.
%%----------------------------------------------------------------------
@@ -151,8 +157,8 @@ parse_binary(Xml, #xmerl_sax_parser_state{encoding={utf16,big}}=State, F) ->
xmerl_sax_parser_utf16be:F(Xml, State);
parse_binary(Xml, #xmerl_sax_parser_state{encoding=latin1}=State, F) ->
xmerl_sax_parser_latin1:F(Xml, State);
-parse_binary(_, #xmerl_sax_parser_state{encoding=Enc}, _) ->
- {error, lists:flatten(io_lib:format("Charcter set ~p not supported", [Enc]))}.
+parse_binary(_, #xmerl_sax_parser_state{encoding=Enc}, State) ->
+ ?fatal_error(State, lists:flatten(io_lib:format("Charcter set ~p not supported", [Enc]))).
%%----------------------------------------------------------------------
%% Function: initial_state/0
@@ -206,8 +212,7 @@ parse_options([{entity, Entity} |Options], State) ->
parse_options([skip_external_dtd |Options], State) ->
parse_options(Options, State#xmerl_sax_parser_state{skip_external_dtd = true});
parse_options([O |_], _State) ->
- {error,
- lists:flatten(io_lib:format("Option: ~p not supported", [O]))}.
+ {error, lists:flatten(io_lib:format("Option: ~p not supported", [O]))}.
check_encoding_option(E) when E==utf8; E=={utf16,little}; E=={utf16,big};
@@ -225,16 +230,10 @@ check_encoding_option(E) ->
%% Output: {utf8|utf16le|utf16be|iso8859, Xml, State}
%% Description: Detects which character set is used in a binary stream.
%%----------------------------------------------------------------------
-detect_charset(<<>>, #xmerl_sax_parser_state{continuation_fun = undefined} = _) ->
- throw({error, "Can't detect character encoding due to no indata"});
-detect_charset(<<>>, #xmerl_sax_parser_state{continuation_fun = CFun,
- continuation_state = CState} = State) ->
- case CFun(CState) of
- {<<>>, _} ->
- throw({error, "Can't detect character encoding due to lack of indata"});
- {NewBytes, NewContState} ->
- detect_charset(NewBytes, State#xmerl_sax_parser_state{continuation_state = NewContState})
- end;
+detect_charset(<<>>, #xmerl_sax_parser_state{continuation_fun = undefined} = State) ->
+ ?fatal_error(State, "Can't detect character encoding due to lack of indata");
+detect_charset(<<>>, State) ->
+ cf(<<>>, State, fun detect_charset/2);
detect_charset(Bytes, State) ->
case unicode:bom_to_encoding(Bytes) of
{latin1, 0} ->
@@ -244,25 +243,47 @@ detect_charset(Bytes, State) ->
{RealBytes, State#xmerl_sax_parser_state{encoding=Enc}}
end.
+detect_charset_1(<<16#00>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#00, 16#3C>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#00, 16#3C, 16#00>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
detect_charset_1(<<16#00, 16#3C, 16#00, 16#3F, _/binary>> = Xml, State) ->
{Xml, State#xmerl_sax_parser_state{encoding={utf16, big}}};
+detect_charset_1(<<16#3C>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#00>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#00, 16#3F>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
detect_charset_1(<<16#3C, 16#00, 16#3F, 16#00, _/binary>> = Xml, State) ->
{Xml, State#xmerl_sax_parser_state{encoding={utf16, little}}};
-detect_charset_1(<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml2/binary>> = Xml, State) ->
- case parse_xml_directive(Xml2) of
+detect_charset_1(<<16#3C>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#3F>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#3F, 16#78>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#3F, 16#78, 16#6D>> = Xml, State) ->
+ cf(Xml, State, fun detect_charset_1/2);
+detect_charset_1(<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml2/binary>>, State) ->
+ {Xml3, State1} = read_until_end_of_xml_directive(Xml2, State),
+ case parse_xml_directive(Xml3) of
{error, Reason} ->
- {error, Reason};
+ ?fatal_error(State, Reason);
AttrList ->
case lists:keysearch("encoding", 1, AttrList) of
{value, {_, E}} ->
case convert_encoding(E) of
{error, Reason} ->
- {error, Reason};
+ ?fatal_error(State, Reason);
Enc ->
- {Xml, State#xmerl_sax_parser_state{encoding=Enc}}
+ {<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml3/binary>>,
+ State1#xmerl_sax_parser_state{encoding=Enc}}
end;
_ ->
- {Xml, State}
+ {<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml3/binary>>, State1}
end
end;
detect_charset_1(Xml, State) ->
@@ -372,7 +393,7 @@ parse_value_1(<<C, Rest/binary>>, Stop, Acc) ->
parse_value_1(Rest, Stop, [C |Acc]).
%%======================================================================
-%%Default functions
+%% Default functions
%%======================================================================
%%----------------------------------------------------------------------
%% Function: default_event_cb(Event, LineNo, State) -> Result
@@ -388,7 +409,7 @@ default_event_cb(_Event, _LineNo, State) ->
%%----------------------------------------------------------------------
%% Function: default_continuation_cb(IoDevice) -> Result
%% IoDevice = iodevice()
-%% Output: Result = {[char()], State}
+%% Output: Result = {binary(), IoDevice}
%% Description: Default continuation callback reading blocks.
%%----------------------------------------------------------------------
default_continuation_cb(IoDevice) ->
@@ -398,3 +419,82 @@ default_continuation_cb(IoDevice) ->
{ok, FileBin} ->
{FileBin, IoDevice}
end.
+
+%%----------------------------------------------------------------------
+%% Function: read_until_end_of_xml_directive(Rest, State) -> Result
+%% Rest = binary()
+%% Output: Result = {binary(), State}
+%% Description: Reads a utf8 or latin1 until it finds '?>'
+%%----------------------------------------------------------------------
+read_until_end_of_xml_directive(Rest, State) ->
+ case binary:match(Rest, <<"?>">>) of
+ nomatch ->
+ case cf(Rest, State) of
+ {<<>>, _} ->
+ ?fatal_error(State, "Can't detect character encoding due to lack of indata");
+ {NewBytes, NewState} ->
+ read_until_end_of_xml_directive(NewBytes, NewState)
+ end;
+ _ ->
+ {Rest, State}
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Function : cf(Rest, State) -> Result
+%% Parameters: Rest = binary()
+%% State = #xmerl_sax_parser_state{}
+%% NextCall = fun()
+%% Result : {Rest, State}
+%% Description: Function that uses provided fun to read another chunk from
+%% input stream and calls the fun in NextCall.
+%%----------------------------------------------------------------------
+cf(_Rest, #xmerl_sax_parser_state{continuation_fun = undefined} = State) ->
+ ?fatal_error(State, "Continuation function undefined");
+cf(Rest, #xmerl_sax_parser_state{continuation_fun = CFun, continuation_state = CState} = State) ->
+ Result =
+ try
+ CFun(CState)
+ catch
+ throw:ErrorTerm ->
+ ?fatal_error(State, ErrorTerm);
+ exit:Reason ->
+ ?fatal_error(State, {'EXIT', Reason})
+ end,
+ case Result of
+ {<<>>, _} ->
+ ?fatal_error(State, "Can't detect character encoding due to lack of indata");
+ {NewBytes, NewContState} ->
+ {<<Rest/binary, NewBytes/binary>>,
+ State#xmerl_sax_parser_state{continuation_state = NewContState}}
+ end.
+
+%%----------------------------------------------------------------------
+%% Function : cf(Rest, State, NextCall) -> Result
+%% Parameters: Rest = binary()
+%% State = #xmerl_sax_parser_state{}
+%% NextCall = fun()
+%% Result : {Rest, State}
+%% Description: Function that uses provided fun to read another chunk from
+%% input stream and calls the fun in NextCall.
+%%----------------------------------------------------------------------
+cf(_Rest, #xmerl_sax_parser_state{continuation_fun = undefined} = State, _) ->
+ ?fatal_error(State, "Continuation function undefined");
+cf(Rest, #xmerl_sax_parser_state{continuation_fun = CFun, continuation_state = CState} = State,
+ NextCall) ->
+ Result =
+ try
+ CFun(CState)
+ catch
+ throw:ErrorTerm ->
+ ?fatal_error(State, ErrorTerm);
+ exit:Reason ->
+ ?fatal_error(State, {'EXIT', Reason})
+ end,
+ case Result of
+ {<<>>, _} ->
+ ?fatal_error(State, "Can't detect character encoding due to lack of indata");
+ {NewBytes, NewContState} ->
+ NextCall(<<Rest/binary, NewBytes/binary>>,
+ State#xmerl_sax_parser_state{continuation_state = NewContState})
+ end.
diff --git a/lib/xmerl/src/xmerl_sax_parser.hrl b/lib/xmerl/src/xmerl_sax_parser.hrl
index 932ab0cec5..56a3a42e5f 100644
--- a/lib/xmerl/src/xmerl_sax_parser.hrl
+++ b/lib/xmerl/src/xmerl_sax_parser.hrl
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -88,14 +88,7 @@
current_location, % Location of the currently parsed XML entity
entity, % Parsed XML entity
skip_external_dtd = false,% If true the external DTD is skipped during parsing
- input_type % Source type: file | stream.
- % This field is a preparation for an fix in R17 of a bug in
- % the conformance against the standard.
- % Today a file which contains two XML documents will be considered
- % well-formed and the second is placed in the rest part of the
- % return tuple, according to the conformance tests this should fail.
- % In the future this will fail if xmerl_sax_aprser:file/2 is used but
- % left to the user in the xmerl_sax_aprser:stream/2 case.
+ input_type % Source type: file | stream
}).
diff --git a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
index 4d75805b9b..1dca9608cb 100644
--- a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
@@ -1,7 +1,7 @@
%%-*-erlang-*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -64,29 +64,42 @@
%% Description: Parsing XML from input stream.
%%----------------------------------------------------------------------
parse(Xml, State) ->
- RefTable = ets:new(xmerl_sax_entity_refs, [private]),
-
- State1 = event_callback(startDocument, State),
-
- case catch parse_document(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of
- {ok, Rest, State2} ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- {ok, State3#xmerl_sax_parser_state.event_state, Rest};
- {fatal_error, {State2, Reason}} ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- format_error(fatal_error, State3, Reason);
- {event_receiver_error, State2, {Tag, Reason}} ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- format_error(Tag, State3, Reason);
- Other ->
- _State2 = event_callback(endDocument, State1),
- ets:delete(RefTable),
- throw(Other)
+ RefTable = maps:new(),
+
+ try
+ State1 = event_callback(startDocument, State),
+ Result = parse_document(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}),
+ handle_end_document(Result)
+ catch
+ throw:Exception ->
+ handle_end_document(Exception);
+ _:OtherError ->
+ handle_end_document({other, OtherError, State})
end.
+ % case catch parse_document(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of
+ % {ok, Rest, State2} ->
+ % State3 = event_callback(endDocument, State2),
+ % case check_if_rest_ok(State3#xmerl_sax_parser_state.input_type, Rest) of
+ % true ->
+ % {ok, State3#xmerl_sax_parser_state.event_state, Rest};
+ % false ->
+ % format_error(fatal_error, State3, "Input found after legal document")
+ % end;
+ % {fatal_error, {State2, Reason}} ->
+ % State3 = event_callback(endDocument, State2),
+ % format_error(fatal_error, State3, Reason);
+ % {event_receiver_error, State2, {Tag, Reason}} ->
+ % State3 = event_callback(endDocument, State2),
+ % format_error(Tag, State3, Reason);
+ % {endDocument, Rest, State2} ->
+ % State3 = event_callback(endDocument, State2),
+ % {ok, State3#xmerl_sax_parser_state.event_state, Rest};
+ % Other ->
+ % _State2 = event_callback(endDocument, State1),
+ % {fatal_error, Other}
+ % end.
+
%%----------------------------------------------------------------------
%% Function: parse_dtd(Xml, State) -> Result
%% Input: Xml = string() | binary()
@@ -96,38 +109,120 @@ parse(Xml, State) ->
%% Description: Parsing XML DTD from input stream.
%%----------------------------------------------------------------------
parse_dtd(Xml, State) ->
- RefTable = ets:new(xmerl_sax_entity_refs, [private]),
-
- State1 = event_callback(startDocument, State),
-
- case catch parse_external_entity_1(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of
- {fatal_error, {State2, Reason}} ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- format_error(fatal_error, State3, Reason);
- {event_receiver_error, State2, {Tag, Reason}} ->
- State3 = event_callback(endDocument, State2),
- format_error(Tag, State3, Reason);
- {Rest, State2} when is_record(State2, xmerl_sax_parser_state) ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- {ok, State3#xmerl_sax_parser_state.event_state, Rest};
- {endDocument, Rest, State2} when is_record(State2, xmerl_sax_parser_state) ->
- State3 = event_callback(endDocument, State2),
- ets:delete(RefTable),
- {ok, State3#xmerl_sax_parser_state.event_state, Rest};
- Other ->
- _State2 = event_callback(endDocument, State1),
- ets:delete(RefTable),
- throw(Other)
+ RefTable = maps:new(),
+
+ try
+ State1 = event_callback(startDocument, State),
+ Result = parse_external_entity_1(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}),
+ handle_end_document(Result)
+ catch
+ throw:Exception ->
+ handle_end_document(Exception);
+ _:OtherError ->
+ handle_end_document({other, OtherError, State})
end.
+ % case catch parse_external_entity_1(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of
+ % {fatal_error, {State2, Reason}} ->
+ % State3 = event_callback(endDocument, State2),
+ % format_error(fatal_error, State3, Reason);
+ % {event_receiver_error, State2, {Tag, Reason}} ->
+ % State3 = event_callback(endDocument, State2),
+ % format_error(Tag, State3, Reason);
+ % {Rest, State2} when is_record(State2, xmerl_sax_parser_state) ->
+ % State3 = event_callback(endDocument, State2),
+ % {ok, State3#xmerl_sax_parser_state.event_state, Rest};
+ % {endDocument, Rest, State2} when is_record(State2, xmerl_sax_parser_state) ->
+ % State3 = event_callback(endDocument, State2),
+ % {ok, State3#xmerl_sax_parser_state.event_state, Rest};
+ % Other ->
+ % _State2 = event_callback(endDocument, State1),
+ % {fatal_error, Other}
+ % end.
+
+
%%======================================================================
%% Internal functions
%%======================================================================
%%----------------------------------------------------------------------
+%% Function: handle_end_document(ParserResult) -> Result
+%% Input: ParseResult = term()
+%% Output: Result = {ok, Rest, EventState} |
+%% EventState = term()
+%% Description: Ends the parsing and formats output
+%%----------------------------------------------------------------------
+handle_end_document({ok, Rest, State}) ->
+ %%ok case from parse
+ try
+ State1 = event_callback(endDocument, State),
+ case check_if_rest_ok(State1#xmerl_sax_parser_state.input_type, Rest) of
+ true ->
+ {ok, State1#xmerl_sax_parser_state.event_state, Rest};
+ false ->
+ format_error(fatal_error, State1, "Input found after legal document")
+ end
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end;
+handle_end_document({endDocument, Rest, State}) ->
+ %% ok case from parse and parse_dtd
+ try
+ State1 = event_callback(endDocument, State),
+ {ok, State1#xmerl_sax_parser_state.event_state, Rest}
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end;
+handle_end_document({fatal_error, {State, Reason}}) ->
+ try
+ State1 = event_callback(endDocument, State),
+ format_error(fatal_error, State1, Reason)
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end;
+handle_end_document({event_receiver_error, State, {Tag, Reason}}) ->
+ try
+ State1 = event_callback(endDocument, State),
+ format_error(Tag, State1, Reason)
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end;
+handle_end_document({Rest, State}) when is_record(State, xmerl_sax_parser_state) ->
+ %%ok case from parse_dtd
+ try
+ State1 = event_callback(endDocument, State),
+ {ok, State1#xmerl_sax_parser_state.event_state, Rest}
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end;
+handle_end_document({other, Error, State}) ->
+ try
+ _State1 = event_callback(endDocument, State),
+ {fatal_error, Error}
+ catch
+ throw:{event_receiver_error, State2, {Tag, Reason}} ->
+ format_error(Tag, State2, Reason);
+ _:Other ->
+ {fatal_error, Other}
+ end.
+
+%%----------------------------------------------------------------------
%% Function: parse_document(Rest, State) -> Result
%% Input: Rest = string() | binary()
%% State = #xmerl_sax_parser_state{}
@@ -136,10 +231,11 @@ parse_dtd(Xml, State) ->
%% [1] document ::= prolog element Misc*
%%----------------------------------------------------------------------
parse_document(Rest, State) when is_record(State, xmerl_sax_parser_state) ->
- {Rest1, State1} = parse_xml_decl(Rest, State),
+ {Rest1, State1} = parse_byte_order_mark(Rest, State),
{Rest2, State2} = parse_misc(Rest1, State1, true),
{ok, Rest2, State2}.
+?PARSE_BYTE_ORDER_MARK(Bytes, State).
%%----------------------------------------------------------------------
%% Function: parse_xml_decl(Rest, State) -> Result
@@ -150,15 +246,8 @@ parse_document(Rest, State) when is_record(State, xmerl_sax_parser_state) ->
%% [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
%% [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
%%----------------------------------------------------------------------
--dialyzer({[no_fail_call, no_match], parse_xml_decl/2}).
parse_xml_decl(?STRING_EMPTY, State) ->
cf(?STRING_EMPTY, State, fun parse_xml_decl/2);
-parse_xml_decl(?BYTE_ORDER_MARK_1, State) ->
- cf(?BYTE_ORDER_MARK_1, State, fun parse_xml_decl/2);
-parse_xml_decl(?BYTE_ORDER_MARK_2, State) ->
- cf(?BYTE_ORDER_MARK_2, State, fun parse_xml_decl/2);
-parse_xml_decl(?BYTE_ORDER_MARK_REST(Rest), State) ->
- cf(Rest, State, fun parse_xml_decl/2);
parse_xml_decl(?STRING("<") = Bytes, State) ->
cf(Bytes, State, fun parse_xml_decl/2);
parse_xml_decl(?STRING("<?") = Bytes, State) ->
@@ -170,31 +259,19 @@ parse_xml_decl(?STRING("<?xm") = Bytes, State) ->
parse_xml_decl(?STRING("<?xml") = Bytes, State) ->
cf(Bytes, State, fun parse_xml_decl/2);
parse_xml_decl(?STRING_REST("<?xml", Rest1), State) ->
- parse_xml_decl_1(Rest1, State);
-parse_xml_decl(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State) when is_binary(Bytes) ->
- case unicode:characters_to_list(Bytes, Enc) of
- {incomplete, _, _} ->
- cf(Bytes, State, fun parse_xml_decl/2);
- {error, _Encoded, _Rest} ->
- ?fatal_error(State, lists:flatten(io_lib:format("Bad character, not in ~p\n", [Enc])));
- _ ->
- parse_prolog(Bytes, State)
- end;
-parse_xml_decl(Bytes, State) ->
- parse_prolog(Bytes, State).
-
+ parse_xml_decl_rest(Rest1, State);
+?PARSE_XML_DECL(Bytes, State).
-parse_xml_decl_1(?STRING_UNBOUND_REST(C, Rest) = Bytes, State) ->
+parse_xml_decl_rest(?STRING_UNBOUND_REST(C, Rest) = Bytes, State) ->
if
?is_whitespace(C) ->
{_XmlAttributes, Rest1, State1} = parse_version_info(Rest, State, []),
- %State2 = event_callback({processingInstruction, "xml", XmlAttributes}, State1),% The XML decl. should not be reported as a PI
parse_prolog(Rest1, State1);
true ->
parse_prolog(?STRING_REST("<?xml", Bytes), State)
end;
-parse_xml_decl_1(Bytes, State) ->
- unicode_incomplete_check([Bytes, State, fun parse_xml_decl_1/2], undefined).
+parse_xml_decl_rest(Bytes, State) ->
+ unicode_incomplete_check([Bytes, State, fun parse_xml_decl_rest/2], undefined).
@@ -216,8 +293,6 @@ parse_prolog(?STRING_REST("<?", Rest), State) ->
parse_prolog(Rest1, State1);
{endDocument, Rest1, State1} ->
parse_prolog(Rest1, State1)
- % IValue = ?TO_INPUT_FORMAT("<?"),
- % {?APPEND_STRING(IValue, Rest1), State1}
end;
parse_prolog(?STRING_REST("<!", Rest), State) ->
parse_prolog_1(Rest, State);
@@ -230,7 +305,6 @@ parse_prolog(Bytes, State) ->
unicode_incomplete_check([Bytes, State, fun parse_prolog/2],
"expecting < or whitespace").
-
parse_prolog_1(?STRING_EMPTY, State) ->
cf(?STRING_EMPTY, State, fun parse_prolog_1/2);
parse_prolog_1(?STRING("D") = Bytes, State) ->
@@ -442,6 +516,16 @@ check_if_new_doc_allowed(stream, []) ->
check_if_new_doc_allowed(_, _) ->
false.
+check_if_rest_ok(file, []) ->
+ true;
+check_if_rest_ok(file, <<>>) ->
+ true;
+check_if_rest_ok(stream, _) ->
+ true;
+check_if_rest_ok(_, _) ->
+ false.
+
+
%%----------------------------------------------------------------------
%% Function: parse_pi_1(Rest, State) -> Result
%% Input: Rest = string() | binary()
@@ -886,11 +970,11 @@ send_end_prefix_mapping_event([{Prefix, _Uri} |Ns], State) ->
parse_eq(?STRING_EMPTY, State) ->
cf(?STRING_EMPTY, State, fun parse_eq/2);
parse_eq(?STRING_REST("=", Rest), State) ->
- {Rest, State};
+ {Rest, State};
parse_eq(?STRING_UNBOUND_REST(C, _) = Bytes, State) when ?is_whitespace(C) ->
- {_WS, Rest, State1} =
- whitespace(Bytes, State, []),
- parse_eq(Rest, State1);
+ {_WS, Rest, State1} =
+ whitespace(Bytes, State, []),
+ parse_eq(Rest, State1);
parse_eq(Bytes, State) ->
unicode_incomplete_check([Bytes, State, fun parse_eq/2],
"expecting = or whitespace").
@@ -908,11 +992,11 @@ parse_eq(Bytes, State) ->
parse_att_value(?STRING_EMPTY, State) ->
cf(?STRING_EMPTY, State, fun parse_att_value/2);
parse_att_value(?STRING_UNBOUND_REST(C, Rest), State) when C == $'; C == $" ->
- parse_att_value(Rest, State, C, []);
+ parse_att_value(Rest, State, C, []);
parse_att_value(?STRING_UNBOUND_REST(C, _) = Bytes, State) when ?is_whitespace(C) ->
- {_WS, Rest, State1} =
- whitespace(Bytes, State, []),
- parse_att_value(Rest, State1);
+ {_WS, Rest, State1} =
+ whitespace(Bytes, State, []),
+ parse_att_value(Rest, State1);
parse_att_value(Bytes, State) ->
unicode_incomplete_check([Bytes, State, fun parse_att_value/2],
"\', \" or whitespace expected").
@@ -1024,16 +1108,21 @@ parse_etag(Bytes, State) ->
unicode_incomplete_check([Bytes, State, fun parse_etag/2],
undefined).
-
parse_etag_1(?STRING_REST(">", Rest),
#xmerl_sax_parser_state{end_tags=[{_ETag, Uri, LocalName, QName, OldNsList, NewNsList}
- |RestOfETags]} = State, _Tag) ->
+ |RestOfETags],
+ input_type=InputType} = State, _Tag) ->
State1 = event_callback({endElement, Uri, LocalName, QName}, State),
State2 = send_end_prefix_mapping_event(NewNsList, State1),
- parse_content(Rest,
- State2#xmerl_sax_parser_state{end_tags=RestOfETags,
- ns = OldNsList},
- [], true);
+ case check_if_new_doc_allowed(InputType, RestOfETags) of
+ true ->
+ throw({endDocument, Rest, State2#xmerl_sax_parser_state{ns = OldNsList}});
+ false ->
+ parse_content(Rest,
+ State2#xmerl_sax_parser_state{end_tags=RestOfETags,
+ ns = OldNsList},
+ [], true)
+ end;
parse_etag_1(?STRING_UNBOUND_REST(_C, _), State, Tag) ->
{P,TN} = Tag,
?fatal_error(State, "Bad EndTag: " ++ P ++ ":" ++ TN);
@@ -1051,21 +1140,26 @@ parse_etag_1(Bytes, State, Tag) ->
%% Description: Parsing the content part of tags
%% [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
%%----------------------------------------------------------------------
-
parse_content(?STRING_EMPTY, State, Acc, IgnorableWS) ->
- case catch cf(?STRING_EMPTY, State, Acc, IgnorableWS, fun parse_content/4) of
- {Rest, State1} when is_record(State1, xmerl_sax_parser_state) ->
- {Rest, State1};
- {fatal_error, {State1, Msg}} ->
- case check_if_document_complete(State1, Msg) of
- true ->
- State2 = send_character_event(length(Acc), IgnorableWS, lists:reverse(Acc), State1),
- {?STRING_EMPTY, State2};
- false ->
- ?fatal_error(State1, Msg)
- end;
- Other ->
- throw(Other)
+ case check_if_document_complete(State, "No more bytes") of
+ true ->
+ State1 = send_character_event(length(Acc), IgnorableWS, lists:reverse(Acc), State),
+ {?STRING_EMPTY, State1};
+ false ->
+ case catch cf(?STRING_EMPTY, State, Acc, IgnorableWS, fun parse_content/4) of
+ {Rest, State1} when is_record(State1, xmerl_sax_parser_state) ->
+ {Rest, State1};
+ {fatal_error, {State1, Msg}} ->
+ case check_if_document_complete(State1, Msg) of
+ true ->
+ State2 = send_character_event(length(Acc), IgnorableWS, lists:reverse(Acc), State1),
+ {?STRING_EMPTY, State2};
+ false ->
+ ?fatal_error(State1, Msg)
+ end;
+ Other ->
+ throw(Other)
+ end
end;
parse_content(?STRING("\r") = Bytes, State, Acc, IgnorableWS) ->
cf(Bytes, State, Acc, IgnorableWS, fun parse_content/4);
@@ -1094,7 +1188,7 @@ parse_content(?STRING_REST("<?", Rest), State, Acc, IgnorableWS) ->
parse_content(?STRING_REST("<!", Rest1) = Rest, #xmerl_sax_parser_state{end_tags = ET} = State, Acc, IgnorableWS) ->
case ET of
[] ->
- {Rest, State}; %%LATH : Skicka ignorable WS ???
+ {Rest, State}; %% Skicka ignorable WS ???
_ ->
State1 = send_character_event(length(Acc), IgnorableWS, lists:reverse(Acc), State),
parse_cdata(Rest1, State1)
@@ -1102,7 +1196,7 @@ parse_content(?STRING_REST("<!", Rest1) = Rest, #xmerl_sax_parser_state{end_tags
parse_content(?STRING_REST("<", Rest1) = Rest, #xmerl_sax_parser_state{end_tags = ET} = State, Acc, IgnorableWS) ->
case ET of
[] ->
- {Rest, State}; %%LATH : Skicka ignorable WS ???
+ {Rest, State}; %% Skicka ignorable WS ???
_ ->
State1 = send_character_event(length(Acc), IgnorableWS, lists:reverse(Acc), State),
parse_stag(Rest1, State1)
@@ -1204,7 +1298,6 @@ send_character_event(_, true, String, State) ->
%% Description: Parse whitespaces.
%% [3] S ::= (#x20 | #x9 | #xD | #xA)+
%%----------------------------------------------------------------------
--dialyzer({no_fail_call, whitespace/3}).
whitespace(?STRING_EMPTY, State, Acc) ->
case cf(?STRING_EMPTY, State, Acc, fun whitespace/3) of
{?STRING_EMPTY, State} ->
@@ -1230,16 +1323,7 @@ whitespace(?STRING_REST("\r", Rest), State, Acc) ->
whitespace(Rest, State#xmerl_sax_parser_state{line_no=N+1}, [?lf |Acc]);
whitespace(?STRING_UNBOUND_REST(C, Rest), State, Acc) when ?is_whitespace(C) ->
whitespace(Rest, State, [C|Acc]);
-whitespace(?STRING_UNBOUND_REST(_C, _) = Bytes, State, Acc) ->
- {lists:reverse(Acc), Bytes, State};
-whitespace(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State, Acc) when is_binary(Bytes) ->
- case unicode:characters_to_list(Bytes, Enc) of
- {incomplete, _, _} ->
- cf(Bytes, State, Acc, fun whitespace/3);
- {error, _Encoded, _Rest} ->
- ?fatal_error(State, lists:flatten(io_lib:format("Bad character, not in ~p\n", [Enc])))
- end.
-
+?WHITESPACE(Bytes, State, Acc).
%%----------------------------------------------------------------------
%% Function: parse_reference(Rest, State, HaveToExist) -> Result
@@ -1362,23 +1446,24 @@ parse_pe_reference_1(Bytes, State, Name) ->
"missing ; after reference " ++ Name).
-
%%----------------------------------------------------------------------
-%% Function: insert_reference(Reference, State) -> Result
-%% Parameters: Reference = string()
+%% Function: insert_reference(Name, Ref, State) -> Result
+%% Parameters: Name = string()
+%% Ref = {Type, Value}
+%% Type = atom()
+%% Value = term()
%% State = #xmerl_sax_parser_state{}
%% Result :
%%----------------------------------------------------------------------
-insert_reference({Name, Type, Value}, Table) ->
- case ets:lookup(Table, Name) of
- [{Name, _, _}] ->
- ok;
+insert_reference(Name, Value, #xmerl_sax_parser_state{ref_table = Map} = State) ->
+ case maps:find(Name, Map) of
+ error ->
+ State#xmerl_sax_parser_state{ref_table = maps:put(Name, Value, Map)};
_ ->
- ets:insert(Table, {Name, Type, Value})
+ State
end.
-
%%----------------------------------------------------------------------
%% Function: look_up_reference(Reference, State) -> Result
%% Parameters: Reference = string()
@@ -1396,8 +1481,8 @@ look_up_reference("apos", _, _) ->
look_up_reference("quot", _, _) ->
{internal_general, "quot", "\""};
look_up_reference(Name, HaveToExist, State) ->
- case ets:lookup(State#xmerl_sax_parser_state.ref_table, Name) of
- [{Name, Type, Value}] ->
+ case maps:find(Name, State#xmerl_sax_parser_state.ref_table) of
+ {ok, {Type, Value}} ->
{Type, Name, Value};
_ ->
case HaveToExist of
@@ -1479,7 +1564,7 @@ parse_system_litteral(?STRING_EMPTY, State, Stop, Acc) ->
parse_system_litteral(?STRING_UNBOUND_REST(Stop, Rest), State, Stop, Acc) ->
{lists:reverse(Acc), Rest, State};
parse_system_litteral(?STRING_UNBOUND_REST(C, Rest), State, Stop, Acc) ->
- parse_system_litteral(Rest, State, Stop, [C |Acc]);
+ parse_system_litteral(Rest, State, Stop, [C |Acc]);
parse_system_litteral(Bytes, State, Stop, Acc) ->
unicode_incomplete_check([Bytes, State, Stop, Acc, fun parse_system_litteral/4],
undefined).
@@ -1651,9 +1736,11 @@ parse_external_entity(State, _PubId, SysId) ->
end_tags = []},
- EventState = handle_external_entity(ExtRef, State1),
+ {EventState, RefTable} = handle_external_entity(ExtRef, State1),
- NewState = event_callback({endEntity, SysId}, SaveState#xmerl_sax_parser_state{event_state=EventState}),
+ NewState = event_callback({endEntity, SysId},
+ SaveState#xmerl_sax_parser_state{event_state=EventState,
+ ref_table=RefTable}),
NewState#xmerl_sax_parser_state{file_type=normal}.
@@ -1680,7 +1767,8 @@ handle_external_entity({file, FileToOpen}, State) ->
entity=filename:basename(FileToOpen),
input_type=file}),
ok = file:close(FD),
- EntityState#xmerl_sax_parser_state.event_state
+ {EntityState#xmerl_sax_parser_state.event_state,
+ EntityState#xmerl_sax_parser_state.ref_table}
end;
handle_external_entity({http, Url}, State) ->
@@ -1693,14 +1781,16 @@ handle_external_entity({http, Url}, State) ->
++ file:format_error(Reason));
{ok, FD} ->
{?STRING_EMPTY, EntityState} =
- parse_external_entity_1(<<>>,
+ parse_external_entity_byte_order_mark(<<>>,
State#xmerl_sax_parser_state{continuation_state=FD,
current_location=filename:dirname(Url),
entity=filename:basename(Url),
input_type=file}),
ok = file:close(FD),
ok = file:delete(TmpFile),
- EntityState#xmerl_sax_parser_state.event_state
+ {EntityState#xmerl_sax_parser_state.event_state,
+ EntityState#xmerl_sax_parser_state.ref_table}
+
end
catch
throw:{error, Error} ->
@@ -1709,6 +1799,8 @@ handle_external_entity({http, Url}, State) ->
handle_external_entity({Tag, _Url}, State) ->
?fatal_error(State, "Unsupported URI type: " ++ atom_to_list(Tag)).
+?PARSE_EXTERNAL_ENTITY_BYTE_ORDER_MARK(Bytes, State).
+
%%----------------------------------------------------------------------
%% Function : parse_external_entity_1(Rest, State) -> Result
%% Parameters: Rest = string() | binary()
@@ -1716,22 +1808,15 @@ handle_external_entity({Tag, _Url}, State) ->
%% Result : {Rest, State}
%% Description: Parse the external entity.
%%----------------------------------------------------------------------
--dialyzer({[no_fail_call, no_match], parse_external_entity_1/2}).
parse_external_entity_1(?STRING_EMPTY, #xmerl_sax_parser_state{file_type=Type} = State) ->
case catch cf(?STRING_EMPTY, State, fun parse_external_entity_1/2) of
{Rest, State1} when is_record(State1, xmerl_sax_parser_state) ->
- {Rest, State};
+ {Rest, State1};
{fatal_error, {State1, "No more bytes"}} when Type == dtd; Type == entity ->
{?STRING_EMPTY, State1};
Other ->
throw(Other)
end;
-parse_external_entity_1(?BYTE_ORDER_MARK_1, State) ->
- cf(?BYTE_ORDER_MARK_1, State, fun parse_external_entity_1/2);
-parse_external_entity_1(?BYTE_ORDER_MARK_2, State) ->
- cf(?BYTE_ORDER_MARK_2, State, fun parse_external_entity_1/2);
-parse_external_entity_1(?BYTE_ORDER_MARK_REST(Rest), State) ->
- parse_external_entity_1(Rest, State);
parse_external_entity_1(?STRING("<") = Bytes, State) ->
cf(Bytes, State, fun parse_external_entity_1/2);
parse_external_entity_1(?STRING("<?") = Bytes, State) ->
@@ -2452,24 +2537,24 @@ parse_entity_def(?STRING_EMPTY, State, Name) ->
cf(?STRING_EMPTY, State, Name, fun parse_entity_def/3);
parse_entity_def(?STRING_UNBOUND_REST(C, Rest), State, Name) when C == $'; C == $" ->
{Value, Rest1, State1} = parse_entity_value(Rest, State, C, []),
- insert_reference({Name, internal_general, Value}, State1#xmerl_sax_parser_state.ref_table),
- State2 = event_callback({internalEntityDecl, Name, Value}, State1),
- {_WS, Rest2, State3} = whitespace(Rest1, State2, []),
- parse_def_end(Rest2, State3);
+ State2 = insert_reference(Name, {internal_general, Value}, State1),
+ State3 = event_callback({internalEntityDecl, Name, Value}, State2),
+ {_WS, Rest2, State4} = whitespace(Rest1, State3, []),
+ parse_def_end(Rest2, State4);
parse_entity_def(?STRING_UNBOUND_REST(C, _) = Rest, State, Name) when C == $S; C == $P ->
{PubId, SysId, Rest1, State1} = parse_external_id(Rest, State, false),
{Ndata, Rest2, State2} = parse_ndata(Rest1, State1),
case Ndata of
undefined ->
- insert_reference({Name, external_general, {PubId, SysId}},
- State2#xmerl_sax_parser_state.ref_table),
- State3 = event_callback({externalEntityDecl, Name, PubId, SysId}, State2),
- {Rest2, State3};
+ State3 = insert_reference(Name, {external_general, {PubId, SysId}},
+ State2),
+ State4 = event_callback({externalEntityDecl, Name, PubId, SysId}, State3),
+ {Rest2, State4};
_ ->
- insert_reference({Name, unparsed, {PubId, SysId, Ndata}},
- State2#xmerl_sax_parser_state.ref_table),
- State3 = event_callback({unparsedEntityDecl, Name, PubId, SysId, Ndata}, State2),
- {Rest2, State3}
+ State3 = insert_reference(Name, {unparsed, {PubId, SysId, Ndata}},
+ State2),
+ State4 = event_callback({unparsedEntityDecl, Name, PubId, SysId, Ndata}, State3),
+ {Rest2, State4}
end;
parse_entity_def(Bytes, State, Name) ->
unicode_incomplete_check([Bytes, State, Name, fun parse_entity_def/3],
@@ -2646,19 +2731,19 @@ parse_pe_def(?STRING_EMPTY, State, Name) ->
parse_pe_def(?STRING_UNBOUND_REST(C, Rest), State, Name) when C == $'; C == $" ->
{Value, Rest1, State1} = parse_entity_value(Rest, State, C, []),
Name1 = "%" ++ Name,
- insert_reference({Name1, internal_parameter, Value},
- State1#xmerl_sax_parser_state.ref_table),
- State2 = event_callback({internalEntityDecl, Name1, Value}, State1),
- {_WS, Rest2, State3} = whitespace(Rest1, State2, []),
- parse_def_end(Rest2, State3);
+ State2 = insert_reference(Name1, {internal_parameter, Value},
+ State1),
+ State3 = event_callback({internalEntityDecl, Name1, Value}, State2),
+ {_WS, Rest2, State4} = whitespace(Rest1, State3, []),
+ parse_def_end(Rest2, State4);
parse_pe_def(?STRING_UNBOUND_REST(C, _) = Bytes, State, Name) when C == $S; C == $P ->
{PubId, SysId, Rest1, State1} = parse_external_id(Bytes, State, false),
Name1 = "%" ++ Name,
- insert_reference({Name1, external_parameter, {PubId, SysId}},
- State1#xmerl_sax_parser_state.ref_table),
- State2 = event_callback({externalEntityDecl, Name1, PubId, SysId}, State1),
- {_WS, Rest2, State3} = whitespace(Rest1, State2, []),
- parse_def_end(Rest2, State3);
+ State2 = insert_reference(Name1, {external_parameter, {PubId, SysId}},
+ State1),
+ State3 = event_callback({externalEntityDecl, Name1, PubId, SysId}, State2),
+ {_WS, Rest2, State4} = whitespace(Rest1, State3, []),
+ parse_def_end(Rest2, State4);
parse_pe_def(Bytes, State, Name) ->
unicode_incomplete_check([Bytes, State, Name, fun parse_pe_def/3],
"\", \', SYSTEM or PUBLIC expected").
@@ -3290,7 +3375,7 @@ cf(Rest, #xmerl_sax_parser_state{continuation_fun = CFun, continuation_state = C
catch
throw:ErrorTerm ->
?fatal_error(State, ErrorTerm);
- exit:Reason ->
+ exit:Reason ->
?fatal_error(State, {'EXIT', Reason})
end,
case Result of
diff --git a/lib/xmerl/src/xmerl_sax_parser_latin1.erlsrc b/lib/xmerl/src/xmerl_sax_parser_latin1.erlsrc
index 961806bf4c..6e59347fb8 100644
--- a/lib/xmerl/src/xmerl_sax_parser_latin1.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_latin1.erlsrc
@@ -2,7 +2,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -34,8 +34,36 @@
-define(APPEND_STRING(Rest, New), <<Rest/binary, New/binary>>).
-define(TO_INPUT_FORMAT(Val), unicode:characters_to_binary(Val, unicode, latin1)).
-%% STRING_REST and STRING_UNBOUND_REST is only different in the list case
-define(STRING_UNBOUND_REST(MatchChar, Rest), <<MatchChar, Rest/binary>>).
--define(BYTE_ORDER_MARK_1, undefined_bom1).
--define(BYTE_ORDER_MARK_2, undefined_bom2).
--define(BYTE_ORDER_MARK_REST(Rest), <<undefined, Rest/binary>>).
+
+-define(PARSE_BYTE_ORDER_MARK(Bytes, State),
+ parse_byte_order_mark(Bytes, State) ->
+ parse_xml_decl(Bytes, State)).
+
+-define(PARSE_XML_DECL(Bytes, State),
+ parse_xml_decl(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State) when is_binary(Bytes) ->
+ case unicode:characters_to_list(Bytes, Enc) of
+ {incomplete, _, _} ->
+ cf(Bytes, State, fun parse_xml_decl/2);
+ {error, _Encoded, _Rest} ->
+ ?fatal_error(State, lists:flatten(io_lib:format("Bad character, not in ~p\n", [Enc])));
+ _ ->
+ parse_prolog(Bytes, State)
+ end;
+ parse_xml_decl(Bytes, State) ->
+ parse_prolog(Bytes, State)).
+
+-define(WHITESPACE(Bytes, State, Acc),
+ whitespace(?STRING_UNBOUND_REST(_C, _) = Bytes, State, Acc) ->
+ {lists:reverse(Acc), Bytes, State};
+ whitespace(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State, Acc) when is_binary(Bytes) ->
+ case unicode:characters_to_list(Bytes, Enc) of
+ {incomplete, _, _} ->
+ cf(Bytes, State, Acc, fun whitespace/3);
+ {error, _Encoded, _Rest} ->
+ ?fatal_error(State, lists:flatten(io_lib:format("Bad character, not in ~p\n", [Enc])))
+ end).
+
+-define(PARSE_EXTERNAL_ENTITY_BYTE_ORDER_MARK(Bytes, State),
+ parse_external_entity_byte_order_mark(Bytes, State) ->
+ parse_external_entity_1(Bytes, State)).
diff --git a/lib/xmerl/src/xmerl_sax_parser_list.erlsrc b/lib/xmerl/src/xmerl_sax_parser_list.erlsrc
index 624a621d92..ac89896215 100644
--- a/lib/xmerl/src/xmerl_sax_parser_list.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_list.erlsrc
@@ -2,7 +2,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -36,6 +36,19 @@
%% In the list case we can't use a '++' when matchin against an unbound variable
-define(STRING_UNBOUND_REST(MatchChar, Rest), [MatchChar | Rest]).
--define(BYTE_ORDER_MARK_1, undefined_bom1).
--define(BYTE_ORDER_MARK_2, undefined_bom2).
--define(BYTE_ORDER_MARK_REST(Rest), [undefined|Rest]).
+
+-define(PARSE_BYTE_ORDER_MARK(Bytes, State),
+ parse_byte_order_mark(Bytes, State) ->
+ parse_xml_decl(Bytes, State)).
+
+-define(PARSE_XML_DECL(Bytes, State),
+ parse_xml_decl(Bytes, State) ->
+ parse_prolog(Bytes, State)).
+
+-define(WHITESPACE(Bytes, State, Acc),
+ whitespace(?STRING_UNBOUND_REST(_C, _) = Bytes, State, Acc) ->
+ {lists:reverse(Acc), Bytes, State}).
+
+-define(PARSE_EXTERNAL_ENTITY_BYTE_ORDER_MARK(Bytes, State),
+ parse_external_entity_byte_order_mark(Bytes, State) ->
+ parse_external_entity_1(Bytes, State)).
diff --git a/lib/xmerl/src/xmerl_sax_parser_utf16be.erlsrc b/lib/xmerl/src/xmerl_sax_parser_utf16be.erlsrc
index ff84ece97a..ec89024729 100644
--- a/lib/xmerl/src/xmerl_sax_parser_utf16be.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_utf16be.erlsrc
@@ -2,7 +2,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -34,8 +34,50 @@
-define(APPEND_STRING(Rest, New), <<Rest/binary, New/binary>>).
-define(TO_INPUT_FORMAT(Val), unicode:characters_to_binary(Val, unicode, {utf16, big})).
-%% STRING_REST and STRING_UNBOUND_REST is only different in the list case
-define(STRING_UNBOUND_REST(MatchChar, Rest), <<MatchChar/big-utf16, Rest/binary>>).
--define(BYTE_ORDER_MARK_1, undefined_bom1).
--define(BYTE_ORDER_MARK_2, <<16#FE>>).
+-define(BYTE_ORDER_MARK_1, <<16#FE>>).
-define(BYTE_ORDER_MARK_REST(Rest), <<16#FE, 16#FF, Rest/binary>>).
+
+-define(PARSE_BYTE_ORDER_MARK(Bytes, State),
+ parse_byte_order_mark(?STRING_EMPTY, State) ->
+ cf(?STRING_EMPTY, State, fun parse_byte_order_mark/2);
+ parse_byte_order_mark(?BYTE_ORDER_MARK_1, State) ->
+ cf(?BYTE_ORDER_MARK_1, State, fun parse_byte_order_mark/2);
+ parse_byte_order_mark(?BYTE_ORDER_MARK_REST(Rest), State) ->
+ parse_xml_decl(Rest, State);
+ parse_byte_order_mark(Bytes, State) ->
+ parse_xml_decl(Bytes, State)).
+
+-define(PARSE_XML_DECL(Bytes, State),
+ parse_xml_decl(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State) when is_binary(Bytes) ->
+ case unicode:characters_to_list(Bytes, Enc) of
+ {incomplete, _, _} ->
+ cf(Bytes, State, fun parse_xml_decl/2);
+ {error, _Encoded, _Rest} ->
+ ?fatal_error(State, lists:flatten(io_lib:format("Bad character, not in ~p\n", [Enc])));
+ _ ->
+ parse_prolog(Bytes, State)
+ end;
+ parse_xml_decl(Bytes, State) ->
+ parse_prolog(Bytes, State)).
+
+-define(WHITESPACE(Bytes, State, Acc),
+ whitespace(?STRING_UNBOUND_REST(_C, _) = Bytes, State, Acc) ->
+ {lists:reverse(Acc), Bytes, State};
+ whitespace(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State, Acc) when is_binary(Bytes) ->
+ case unicode:characters_to_list(Bytes, Enc) of
+ {incomplete, _, _} ->
+ cf(Bytes, State, Acc, fun whitespace/3);
+ {error, _Encoded, _Rest} ->
+ ?fatal_error(State, lists:flatten(io_lib:format("Bad character, not in ~p\n", [Enc])))
+ end).
+
+-define(PARSE_EXTERNAL_ENTITY_BYTE_ORDER_MARK(Bytes, State),
+ parse_external_entity_byte_order_mark(?STRING_EMPTY, State) ->
+ cf(?STRING_EMPTY, State, fun parse_external_entity_byte_order_mark/2);
+ parse_external_entity_byte_order_mark(?BYTE_ORDER_MARK_1, State) ->
+ cf(?BYTE_ORDER_MARK_1, State, fun parse_external_entity_byte_order_mark/2);
+ parse_external_entity_byte_order_mark(?BYTE_ORDER_MARK_REST(Rest), State) ->
+ parse_external_entity_1(Rest, State);
+ parse_external_entity_byte_order_mark(Bytes, State) ->
+ parse_external_entity_1(Bytes, State)).
diff --git a/lib/xmerl/src/xmerl_sax_parser_utf16le.erlsrc b/lib/xmerl/src/xmerl_sax_parser_utf16le.erlsrc
index a330fce8d0..566333a045 100644
--- a/lib/xmerl/src/xmerl_sax_parser_utf16le.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_utf16le.erlsrc
@@ -2,7 +2,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -34,8 +34,50 @@
-define(APPEND_STRING(Rest, New), <<Rest/binary, New/binary>>).
-define(TO_INPUT_FORMAT(Val), unicode:characters_to_binary(Val, unicode, {utf16, little})).
-%% STRING_REST and STRING_UNBOUND_REST is only different in the list case
-define(STRING_UNBOUND_REST(MatchChar, Rest), <<MatchChar/little-utf16, Rest/binary>>).
--define(BYTE_ORDER_MARK_1, undefined_bom1).
--define(BYTE_ORDER_MARK_2, <<16#FF>>).
+-define(BYTE_ORDER_MARK_1, <<16#FF>>).
-define(BYTE_ORDER_MARK_REST(Rest), <<16#FF, 16#FE, Rest/binary>>).
+
+-define(PARSE_BYTE_ORDER_MARK(Bytes, State),
+ parse_byte_order_mark(?STRING_EMPTY, State) ->
+ cf(?STRING_EMPTY, State, fun parse_byte_order_mark/2);
+ parse_byte_order_mark(?BYTE_ORDER_MARK_1, State) ->
+ cf(?BYTE_ORDER_MARK_1, State, fun parse_byte_order_mark/2);
+ parse_byte_order_mark(?BYTE_ORDER_MARK_REST(Rest), State) ->
+ parse_xml_decl(Rest, State);
+ parse_byte_order_mark(Bytes, State) ->
+ parse_xml_decl(Bytes, State)).
+
+-define(PARSE_XML_DECL(Bytes, State),
+ parse_xml_decl(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State) when is_binary(Bytes) ->
+ case unicode:characters_to_list(Bytes, Enc) of
+ {incomplete, _, _} ->
+ cf(Bytes, State, fun parse_xml_decl/2);
+ {error, _Encoded, _Rest} ->
+ ?fatal_error(State, lists:flatten(io_lib:format("Bad character, not in ~p\n", [Enc])));
+ _ ->
+ parse_prolog(Bytes, State)
+ end;
+ parse_xml_decl(Bytes, State) ->
+ parse_prolog(Bytes, State)).
+
+-define(WHITESPACE(Bytes, State, Acc),
+ whitespace(?STRING_UNBOUND_REST(_C, _) = Bytes, State, Acc) ->
+ {lists:reverse(Acc), Bytes, State};
+ whitespace(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State, Acc) when is_binary(Bytes) ->
+ case unicode:characters_to_list(Bytes, Enc) of
+ {incomplete, _, _} ->
+ cf(Bytes, State, Acc, fun whitespace/3);
+ {error, _Encoded, _Rest} ->
+ ?fatal_error(State, lists:flatten(io_lib:format("Bad character, not in ~p\n", [Enc])))
+ end).
+
+-define(PARSE_EXTERNAL_ENTITY_BYTE_ORDER_MARK(Bytes, State),
+ parse_external_entity_byte_order_mark(?STRING_EMPTY, State) ->
+ cf(?STRING_EMPTY, State, fun parse_external_entity_byte_order_mark/2);
+ parse_external_entity_byte_order_mark(?BYTE_ORDER_MARK_1, State) ->
+ cf(?BYTE_ORDER_MARK_1, State, fun parse_external_entity_byte_order_mark/2);
+ parse_external_entity_byte_order_mark(?BYTE_ORDER_MARK_REST(Rest), State) ->
+ parse_external_entity_1(Rest, State);
+ parse_external_entity_byte_order_mark(Bytes, State) ->
+ parse_external_entity_1(Bytes, State)).
diff --git a/lib/xmerl/src/xmerl_sax_parser_utf8.erlsrc b/lib/xmerl/src/xmerl_sax_parser_utf8.erlsrc
index d46d60d237..f41d06d013 100644
--- a/lib/xmerl/src/xmerl_sax_parser_utf8.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_utf8.erlsrc
@@ -2,7 +2,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -34,11 +34,55 @@
-define(APPEND_STRING(Rest, New), <<Rest/binary, New/binary>>).
-define(TO_INPUT_FORMAT(Val), unicode:characters_to_binary(Val, unicode, utf8)).
-
-%% STRING_REST and STRING_UNBOUND_REST is only different in the list case
-define(STRING_UNBOUND_REST(MatchChar, Rest), <<MatchChar/utf8, Rest/binary>>).
-define(BYTE_ORDER_MARK_1, <<16#EF>>).
-define(BYTE_ORDER_MARK_2, <<16#EF, 16#BB>>).
-define(BYTE_ORDER_MARK_REST(Rest), <<16#EF, 16#BB, 16#BF, Rest/binary>>).
+-define(PARSE_BYTE_ORDER_MARK(Bytes, State),
+ parse_byte_order_mark(?STRING_EMPTY, State) ->
+ cf(?STRING_EMPTY, State, fun parse_byte_order_mark/2);
+ parse_byte_order_mark(?BYTE_ORDER_MARK_1, State) ->
+ cf(?BYTE_ORDER_MARK_1, State, fun parse_byte_order_mark/2);
+ parse_byte_order_mark(?BYTE_ORDER_MARK_2, State) ->
+ cf(?BYTE_ORDER_MARK_2, State, fun parse_byte_order_mark/2);
+ parse_byte_order_mark(?BYTE_ORDER_MARK_REST(Rest), State) ->
+ parse_xml_decl(Rest, State);
+ parse_byte_order_mark(Bytes, State) ->
+ parse_xml_decl(Bytes, State)).
+
+-define(PARSE_XML_DECL(Bytes, State),
+ parse_xml_decl(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State) when is_binary(Bytes) ->
+ case unicode:characters_to_list(Bytes, Enc) of
+ {incomplete, _, _} ->
+ cf(Bytes, State, fun parse_xml_decl/2);
+ {error, _Encoded, _Rest} ->
+ ?fatal_error(State, lists:flatten(io_lib:format("Bad character, not in ~p\n", [Enc])));
+ _ ->
+ parse_prolog(Bytes, State)
+ end;
+ parse_xml_decl(Bytes, State) ->
+ parse_prolog(Bytes, State)).
+
+-define(WHITESPACE(Bytes, State, Acc),
+ whitespace(?STRING_UNBOUND_REST(_C, _) = Bytes, State, Acc) ->
+ {lists:reverse(Acc), Bytes, State};
+ whitespace(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State, Acc) when is_binary(Bytes) ->
+ case unicode:characters_to_list(Bytes, Enc) of
+ {incomplete, _, _} ->
+ cf(Bytes, State, Acc, fun whitespace/3);
+ {error, _Encoded, _Rest} ->
+ ?fatal_error(State, lists:flatten(io_lib:format("Bad character, not in ~p\n", [Enc])))
+ end).
+-define(PARSE_EXTERNAL_ENTITY_BYTE_ORDER_MARK(Bytes, State),
+ parse_external_entity_byte_order_mark(?STRING_EMPTY, State) ->
+ cf(?STRING_EMPTY, State, fun parse_external_entity_byte_order_mark/2);
+ parse_external_entity_byte_order_mark(?BYTE_ORDER_MARK_1, State) ->
+ cf(?BYTE_ORDER_MARK_1, State, fun parse_external_entity_byte_order_mark/2);
+ parse_external_entity_byte_order_mark(?BYTE_ORDER_MARK_2, State) ->
+ cf(?BYTE_ORDER_MARK_2, State, fun parse_external_entity_byte_order_mark/2);
+ parse_external_entity_byte_order_mark(?BYTE_ORDER_MARK_REST(Rest), State) ->
+ parse_external_entity_1(Rest, State);
+ parse_external_entity_byte_order_mark(Bytes, State) ->
+ parse_external_entity_1(Bytes, State)).
diff --git a/lib/xmerl/src/xmerl_sax_simple_dom.erl b/lib/xmerl/src/xmerl_sax_simple_dom.erl
index 7eb3afd499..7b15cd92dc 100644
--- a/lib/xmerl/src/xmerl_sax_simple_dom.erl
+++ b/lib/xmerl/src/xmerl_sax_simple_dom.erl
@@ -2,7 +2,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -129,8 +129,9 @@ build_dom(endDocument,
State#xmerl_sax_simple_dom_state{dom=[Decl, {Tag, Attributes,
lists:reverse(Content)}]};
_ ->
- ?dbg("~p\n", [D]),
- ?error("we're not at end the document when endDocument event is encountered.")
+ %% endDocument is also sent by the parser when a fault occur to tell
+ %% the event receiver that no more input will be sent
+ State
end;
%% Element
diff --git a/lib/xmerl/src/xmerl_scan.erl b/lib/xmerl/src/xmerl_scan.erl
index 2147a46a13..a1f6ad4e2c 100644
--- a/lib/xmerl/src/xmerl_scan.erl
+++ b/lib/xmerl/src/xmerl_scan.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -111,13 +111,16 @@
%% <dd>Set to 'true' if xmerl should add to elements missing attributes
%% with a defined default value (default 'false').</dd>
%% </dl>
+%% @type xmlElement() = #xmlElement{}.
+%% The record definition is found in xmerl.hrl.
+%% @type xmlDocument() = #xmlDocument{}.
+%% The record definition is found in xmerl.hrl.
%% @type document() = xmlElement() | xmlDocument(). <p>
%% The document returned by <tt>xmerl_scan:string/[1,2]</tt> and
%% <tt>xmerl_scan:file/[1,2]</tt>. The type of the returned record depends on
%% the value of the document option passed to the function.
%% </p>
-
-module(xmerl_scan).
-vsn('0.20').
-date('03-09-16').
@@ -471,8 +474,8 @@ event(_X, S) ->
%% into multiple objects (in which case {Acc',Pos',S'} should be returned.)
%% If {Acc',S'} is returned, Pos will be incremented by 1 by default.
%% Below is an example of an acceptable operation
-acc(X = #xmlText{value = Text}, Acc, S) ->
- {[X#xmlText{value = Text}|Acc], S};
+acc(#xmlText{value = Text}, [X = #xmlText{value = AccText}], S) ->
+ {[X#xmlText{value = AccText ++ Text}], S};
acc(X, Acc, S) ->
{[X|Acc], S}.
@@ -2222,16 +2225,18 @@ processed_whole_element(S=#xmerl_scanner{hook_fun = _Hook,
AllAttrs =
case S#xmerl_scanner.default_attrs of
true ->
- [ #xmlAttribute{name = AttName,
- parents = [{Name, Pos} | Parents],
- language = Lang,
- nsinfo = NSI,
- namespace = Namespace,
- value = AttValue,
- normalized = true} ||
- {AttName, AttValue} <- get_default_attrs(S, Name),
- AttValue =/= no_value,
- not lists:keymember(AttName, #xmlAttribute.name, Attrs) ];
+ DefaultAttrs =
+ [ #xmlAttribute{name = AttName,
+ parents = [{Name, Pos} | Parents],
+ language = Lang,
+ nsinfo = NSI,
+ namespace = Namespace,
+ value = AttValue,
+ normalized = true} ||
+ {AttName, AttValue} <- get_default_attrs(S, Name),
+ AttValue =/= no_value,
+ not lists:keymember(AttName, #xmlAttribute.name, Attrs) ],
+ lists:append(Attrs, DefaultAttrs);
false ->
Attrs
end,
@@ -2304,7 +2309,9 @@ expanded_name(Name, [], #xmlNamespace{default = URI}, S) ->
expanded_name(Name, N = {"xmlns", Local}, #xmlNamespace{nodes = Ns}, S) ->
{_, Value} = lists:keyfind(Local, 1, Ns),
case Name of
- 'xmlns:xml' when Value =/= 'http://www.w3.org/XML/1998/namespace' ->
+ 'xmlns:xml' when Value =:= 'http://www.w3.org/XML/1998/namespace' ->
+ N;
+ 'xmlns:xml' when Value =/= 'http://www.w3.org/XML/1998/namespace' ->
?fatal({xml_prefix_cannot_be_redeclared, Value}, S);
'xmlns:xmlns' ->
?fatal({xmlns_prefix_cannot_be_declared, Value}, S);
@@ -2318,6 +2325,8 @@ expanded_name(Name, N = {"xmlns", Local}, #xmlNamespace{nodes = Ns}, S) ->
N
end
end;
+expanded_name(_Name, {"xml", Local}, _NS, _S) ->
+ {'http://www.w3.org/XML/1998/namespace', list_to_atom(Local)};
expanded_name(_Name, {Prefix, Local}, #xmlNamespace{nodes = Ns}, S) ->
case lists:keysearch(Prefix, 1, Ns) of
{value, {_, URI}} ->
@@ -2328,9 +2337,6 @@ expanded_name(_Name, {Prefix, Local}, #xmlNamespace{nodes = Ns}, S) ->
?fatal({namespace_prefix_not_declared, Prefix}, S)
end.
-
-
-
keyreplaceadd(K, Pos, [H|T], Obj) when K == element(Pos, H) ->
[Obj|T];
keyreplaceadd(K, Pos, [H|T], Obj) ->
diff --git a/lib/xmerl/src/xmerl_xpath.erl b/lib/xmerl/src/xmerl_xpath.erl
index bbebda1030..6146feba49 100644
--- a/lib/xmerl/src/xmerl_xpath.erl
+++ b/lib/xmerl/src/xmerl_xpath.erl
@@ -43,13 +43,27 @@
%% </pre>
%%
%% @type nodeEntity() =
-%% xmlElement()
-%% | xmlAttribute()
-%% | xmlText()
-%% | xmlPI()
-%% | xmlComment()
-%% | xmlNsNode()
-%% | xmlDocument()
+%% #xmlElement{}
+%% | #xmlAttribute{}
+%% | #xmlText{}
+%% | #xmlPI{}
+%% | #xmlComment{}
+%% | #xmlNsNode{}
+%% | #xmlDocument{}
+%%
+%% @type docNodes() = #xmlElement{}
+%% | #xmlAttribute{}
+%% | #xmlText{}
+%% | #xmlPI{}
+%% | #xmlComment{}
+%% | #xmlNsNode{}
+%%
+%% @type docEntity() = #xmlDocument{} | [docNodes()]
+%%
+%% @type xPathString() = string()
+%%
+%% @type parentList() = [{atom(), integer()}]
+%%
%% @type option_list(). <p>Options allows to customize the behaviour of the
%% XPath scanner.
%% </p>
@@ -115,7 +129,7 @@ string(Str, Doc, Options) ->
%% Parents = parentList()
%% Doc = nodeEntity()
%% Options = option_list()
-%% Scalar = xmlObj
+%% Scalar = #xmlObj{}
%% @doc Extracts the nodes from the parsed XML tree according to XPath.
%% xmlObj is a record with fields type and value,
%% where type is boolean | number | string
diff --git a/lib/xmerl/src/xmerl_xs.erl b/lib/xmerl/src/xmerl_xs.erl
index 3e9f6622b8..1ce76cfa41 100644
--- a/lib/xmerl/src/xmerl_xs.erl
+++ b/lib/xmerl/src/xmerl_xs.erl
@@ -45,7 +45,6 @@
% XSLT package which is written i C++.
% See also the <a href="xmerl_xs_examples.html">Tutorial</a>.
% </p>
-
-module(xmerl_xs).
-export([xslapply/2, value_of/1, select/2, built_in_rules/2 ]).
@@ -71,15 +70,13 @@
%% xslapply(fun template/1, E),
%% "&lt;/h1>"];
%% </pre>
-
xslapply(Fun, EList) when is_list(EList) ->
- lists:map( Fun, EList);
+ lists:map(Fun, EList);
xslapply(Fun, E = #xmlElement{})->
lists:map( Fun, E#xmlElement.content).
-
%% @spec value_of(E) -> List
-%% E = unknown()
+%% E = term()
%%
%% @doc Concatenates all text nodes within the tree.
%%
diff --git a/lib/xmerl/src/xmerl_xsd.erl b/lib/xmerl/src/xmerl_xsd.erl
index 4b5efae8dd..a89b3159ec 100644
--- a/lib/xmerl/src/xmerl_xsd.erl
+++ b/lib/xmerl/src/xmerl_xsd.erl
@@ -49,6 +49,7 @@
%% <dd>It is possible by this option to provide a state with process
%% information from an earlier validation.</dd>
%% </dl>
+%% @type filename() = string()
%% @end
%%%-------------------------------------------------------------------
-module(xmerl_xsd).
@@ -138,7 +139,7 @@ state2file(S=#xsd_state{schema_name=SN}) ->
%% @spec state2file(State,FileName) -> ok | {error,Reason}
%% State = global_state()
-%% FileName = filename()
+%% FileName = string()
%% @doc Saves the schema state with all information of the processed
%% schema in a file. You can provide the file name for the saved
%% state. FileName is saved with the <code>.xss</code> extension
@@ -153,7 +154,7 @@ state2file(S,FileName) when is_record(S,xsd_state) ->
%% @spec file2state(FileName) -> {ok,State} | {error,Reason}
%% State = global_state()
-%% FileName = filename()
+%% FileName = string()
%% @doc Reads the schema state with all information of the processed
%% schema from a file created with <code>state2file/[1,2]</code>. The
%% format of this file is internal. The state can then be used
@@ -202,7 +203,7 @@ xmerl_xsd_vsn_check(S=#xsd_state{vsn=MD5_VSN}) ->
process_validate(Schema,Xml) ->
process_validate(Schema,Xml,[]).
%% @spec process_validate(Schema,Element,Options) -> Result
-%% Schema = filename()
+%% Schema = string()
%% Element = XmlElement
%% Options = option_list()
%% Result = {ValidXmlElement,State} | {error,Reason}
@@ -282,7 +283,7 @@ validate3(_,_,S) ->
process_schema(Schema) ->
process_schema(Schema,[]).
%% @spec process_schema(Schema,Options) -> Result
-%% Schema = filename()
+%% Schema = string()
%% Result = {ok,State} | {error,Reason}
%% State = global_state()
%% Reason = [ErrorReason] | ErrorReason
@@ -324,7 +325,7 @@ process_schema2({SE,_},State,_Schema) ->
process_schemas(Schemas) ->
process_schemas(Schemas,[]).
%% @spec process_schemas(Schemas,Options) -> Result
-%% Schemas = [{NameSpace,filename()}|Schemas] | []
+%% Schemas = [{NameSpace,string()}|Schemas] | []
%% Result = {ok,State} | {error,Reason}
%% Reason = [ErrorReason] | ErrorReason
%% Options = option_list()
@@ -5426,7 +5427,7 @@ add_key_once(Key,N,El,L) ->
%% {filename:join([[io_lib:format("/~w(~w)",[X,Y])||{X,Y}<-Parents],Type]),Pos}.
%% @spec format_error(Errors) -> Result
-%% Errors = error_tuple() | [error_tuple()]
+%% Errors = tuple() | [tuple()]
%% Result = string() | [string()]
%% @doc Formats error descriptions to human readable strings.
format_error(L) when is_list(L) ->
diff --git a/lib/xmerl/test/Makefile b/lib/xmerl/test/Makefile
index 7a326e334f..3204f081ba 100644
--- a/lib/xmerl/test/Makefile
+++ b/lib/xmerl/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2016. All Rights Reserved.
+# Copyright Ericsson AB 2004-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -55,7 +55,8 @@ SUITE_FILES= \
xmerl_xsd_SUITE.erl \
xmerl_xsd_MS2002-01-16_SUITE.erl \
xmerl_xsd_NIST2002-01-16_SUITE.erl \
- xmerl_xsd_Sun2002-01-16_SUITE.erl
+ xmerl_xsd_Sun2002-01-16_SUITE.erl \
+ xmerl_sax_stream_SUITE.erl
XML_FILES= \
testcases.dtd \
@@ -125,4 +126,6 @@ release_tests_spec: opt
@tar cfh - xmerl_xsd_MS2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
@tar cfh - xmerl_xsd_NIST2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
@tar cfh - xmerl_xsd_Sun2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
+ @tar cfh - xmerl_sax_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
+ @tar cfh - xmerl_sax_stream_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
chmod -R u+w "$(RELSYSDIR)"
diff --git a/lib/xmerl/test/xmerl_SUITE.erl b/lib/xmerl/test/xmerl_SUITE.erl
index e97b8c6a4b..66f04f6c25 100644
--- a/lib/xmerl/test/xmerl_SUITE.erl
+++ b/lib/xmerl/test/xmerl_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -54,7 +54,8 @@ groups() ->
cpd_expl_provided_DTD]},
{misc, [],
[latin1_alias, syntax_bug1, syntax_bug2, syntax_bug3,
- pe_ref1, copyright, testXSEIF, export_simple1, export]},
+ pe_ref1, copyright, testXSEIF, export_simple1, export,
+ default_attrs_bug, xml_ns, scan_splits_string_bug]},
{eventp_tests, [], [sax_parse_and_export]},
{ticket_tests, [],
[ticket_5998, ticket_7211, ticket_7214, ticket_7430,
@@ -223,6 +224,54 @@ syntax_bug3(Config) ->
Err -> Err
end.
+default_attrs_bug(Config) ->
+ file:set_cwd(datadir(Config)),
+ Doc = "<!DOCTYPE doc [<!ATTLIST doc b CDATA \"default\">]>\n"
+ "<doc a=\"explicit\"/>",
+ {#xmlElement{attributes = [#xmlAttribute{name = a, value = "explicit"},
+ #xmlAttribute{name = b, value = "default"}]},
+ []
+ } = xmerl_scan:string(Doc, [{default_attrs, true}]),
+ Doc2 = "<!DOCTYPE doc [<!ATTLIST doc b CDATA \"default\">]>\n"
+ "<doc b=\"also explicit\" a=\"explicit\"/>",
+ {#xmlElement{attributes = [#xmlAttribute{name = b, value = "also explicit"},
+ #xmlAttribute{name = a, value = "explicit"}]},
+ []
+ } = xmerl_scan:string(Doc2, [{default_attrs, true}]),
+ ok.
+
+
+xml_ns(Config) ->
+ Doc = "<?xml version='1.0'?>\n"
+ "<doc xml:attr1=\"implicit xml ns\"/>",
+ {#xmlElement{namespace=#xmlNamespace{default = [], nodes = []},
+ attributes = [#xmlAttribute{name = 'xml:attr1',
+ expanded_name = {'http://www.w3.org/XML/1998/namespace',attr1},
+ nsinfo = {"xml","attr1"},
+ namespace = #xmlNamespace{default = [], nodes = []}}]},
+ []
+ } = xmerl_scan:string(Doc, [{namespace_conformant, true}]),
+ Doc2 = "<?xml version='1.0'?>\n"
+ "<doc xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xml:attr1=\"explicit xml ns\"/>",
+ {#xmlElement{namespace=#xmlNamespace{default = [], nodes = [{"xml",'http://www.w3.org/XML/1998/namespace'}]},
+ attributes = [#xmlAttribute{name = 'xmlns:xml',
+ expanded_name = {"xmlns","xml"},
+ nsinfo = {"xmlns","xml"},
+ namespace = #xmlNamespace{default = [],
+ nodes = [{"xml",'http://www.w3.org/XML/1998/namespace'}]}},
+ #xmlAttribute{name = 'xml:attr1',
+ expanded_name = {'http://www.w3.org/XML/1998/namespace',attr1},
+ nsinfo = {"xml","attr1"},
+ namespace = #xmlNamespace{default = [],
+ nodes = [{"xml",'http://www.w3.org/XML/1998/namespace'}]}}]},
+ []
+ } = xmerl_scan:string(Doc2, [{namespace_conformant, true}]),
+ ok.
+
+scan_splits_string_bug(_Config) ->
+ {#xmlElement{ content = [#xmlText{ value = "Jimmy Zöger" }] }, []}
+ = xmerl_scan:string("<name>Jimmy Z&#246;ger</name>").
+
pe_ref1(Config) ->
file:set_cwd(datadir(Config)),
{#xmlElement{},[]} = xmerl_scan:file(datadir_join(Config,[misc,"PE_ref1.xml"]),[{validation,true}]).
@@ -488,8 +537,7 @@ ticket_7430(Config) ->
{xmlElement,a,a,[],
{xmlNamespace,[],[]},
[],1,[],
- [{xmlText,[{a,1}],1,[],"é",text},
- {xmlText,[{a,1}],2,[],"\né",text}],
+ [{xmlText,[{a,1}],1,[],"é\né",text}],
[],_,undeclared} ->
ok;
_ ->
diff --git a/lib/xmerl/test/xmerl_sax_SUITE.erl b/lib/xmerl/test/xmerl_sax_SUITE.erl
index f5c0a783c4..68b9bcc4a2 100644
--- a/lib/xmerl/test/xmerl_sax_SUITE.erl
+++ b/lib/xmerl/test/xmerl_sax_SUITE.erl
@@ -2,7 +2,7 @@
%%----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,7 +33,6 @@
%%======================================================================
%% External functions
%%======================================================================
-
%%----------------------------------------------------------------------
%% Initializations
%%----------------------------------------------------------------------
@@ -42,12 +41,15 @@ all() ->
[{group, bugs}].
groups() ->
- [{bugs, [], [ticket_8213, ticket_8214, ticket_11551]}].
+ [{bugs, [], [ticket_8213, ticket_8214, ticket_11551,
+ fragmented_xml_directive,
+ old_dom_event_fun_endDocument_bug,
+ event_fun_endDocument_error_test,
+ event_fun_startDocument_error_test]}].
-%%----------------------------------------------------------------------
+%%======================================================================
%% Tests
-%%----------------------------------------------------------------------
-
+%%======================================================================
%%----------------------------------------------------------------------
%% Test Case
%% ID: ticket_8213
@@ -56,7 +58,6 @@ ticket_8213(_Config) ->
{ok,ok,[]} = xmerl_sax_parser:stream("<elem/>", [{event_fun, fun (_E,_,_) -> ok end}]),
ok.
-
%%----------------------------------------------------------------------
%% Test Case
%% ID: ticket_8214
@@ -85,17 +86,80 @@ ticket_11551(_Config) ->
<a>hej</a>
<?xml version=\"1.0\" encoding=\"utf-8\" ?>
<a>hej</a>">>,
- {ok, undefined, <<"<?xml", _/binary>>} = xmerl_sax_parser:stream(Stream1, []),
+ {ok, undefined, <<"\n<?xml", _/binary>>} = xmerl_sax_parser:stream(Stream1, []),
Stream2= <<"<?xml version=\"1.0\" encoding=\"utf-8\" ?>
<a>hej</a>
<?xml version=\"1.0\" encoding=\"utf-8\" ?>
<a>hej</a>">>,
- {ok, undefined, <<"<?xml", _/binary>>} = xmerl_sax_parser:stream(Stream2, []),
+ {ok, undefined, <<"\n\n\n<?xml", _/binary>>} = xmerl_sax_parser:stream(Stream2, []),
Stream3= <<"<a>hej</a>
<?xml version=\"1.0\" encoding=\"utf-8\" ?>
<a>hej</a>">>,
- {ok, undefined, <<"<?xml", _/binary>>} = xmerl_sax_parser:stream(Stream3, []),
+ {ok, undefined, <<"\n\n<?xml", _/binary>>} = xmerl_sax_parser:stream(Stream3, []),
+ ok.
+
+%%----------------------------------------------------------------------
+%% Test Case
+%% ID: fragmented_xml_directive
+%% Test of fragmented xml directive by reading one byte per continuation ca
+fragmented_xml_directive(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ Name = filename:join(DataDir, "test_data_1.xml"),
+ {ok, Fd} = file:open(Name, [raw, read,binary]),
+ Cf = fun cf_fragmented_xml_directive/1,
+ {ok, undefined, _} = xmerl_sax_parser:stream(<<>>,
+ [{continuation_fun, Cf},
+ {continuation_state, Fd}]),
+ ok.
+
+%%----------------------------------------------------------------------
+%% Test Case
+%% ID: old_dom_event_fun_endDocument_bug
+%% The old_dom backend previous generateded an uncatched exception
+%% instead of the correct fatal_error from the parser.
+old_dom_event_fun_endDocument_bug(_Config) ->
+ %% Stream contains bad characters,
+ {fatal_error, _, _, _, _} =
+ xmerl_sax_parser:stream([60,63,120,109,108,32,118,101,114,115,105,111,110,61,39,49,46,48,39,32,101,110,99,111,100,105,110,103,61,39,117,116,102,45,56,39,63,62,60,
+ 99,111,109,109,97,110,100,62,60,104,101,97,100,101,114,62,60,116,114,97,110,115,97,99,116,105,111,110,73,100,62,49,60,47,116,114,97,110,
+ 115,97,99,116,105,111,110,73,100,62,60,47,104,101,97,100,101,114,62,60,98,111,100,121,62,95,226,130,172,59,60,60,47,98,111,100,121,62,60,
+ 47,99,111,109,109,97,110,100,62,60,47,120,49,95,49,62],
+ [{event_fun,fun xmerl_sax_old_dom:event/3},
+ {event_state,xmerl_sax_old_dom:initial_state()}]),
ok.
+
+%%----------------------------------------------------------------------
+%% Test Case
+%% ID: event_fun_endDocument_error_test
+event_fun_endDocument_error_test(_Config) ->
+ Stream = <<"<?xml version=\"1.0\" encoding=\"utf-8\"?><a>hej</a>">>,
+ Ef = fun(endDocument, _ , _) -> throw({event_error, "endDocument error"});
+ (_, _, S) -> S
+ end,
+ {event_error, _, _, _, _} = xmerl_sax_parser:stream(Stream, [{event_fun, Ef}]),
+ ok.
+
+%%----------------------------------------------------------------------
+%% Test Case
+%% ID: event_fun_startDocument_error_test
+event_fun_startDocument_error_test(_Config) ->
+ Stream = <<"<?xml version=\"1.0\" encoding=\"utf-8\"?><a>hej</a>">>,
+ Ef = fun(startDocument, _ , _) -> throw({event_error, "endDocument error"});
+ (_, _, S) -> S
+ end,
+ {event_error, _, _, _, _} = xmerl_sax_parser:stream(Stream, [{event_fun, Ef}]),
+ ok.
+
+%%======================================================================
+%% Internal functions
+%%======================================================================
+cf_fragmented_xml_directive(IoDevice) ->
+ case file:read(IoDevice, 1) of
+ eof ->
+ {<<>>, IoDevice};
+ {ok, FileBin} ->
+ {FileBin, IoDevice}
+ end.
diff --git a/lib/xmerl/test/xmerl_sax_SUITE_data/test_data_1.xml b/lib/xmerl/test/xmerl_sax_SUITE_data/test_data_1.xml
new file mode 100644
index 0000000000..efbaee6b81
--- /dev/null
+++ b/lib/xmerl/test/xmerl_sax_SUITE_data/test_data_1.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<a>
+Hej
+</a>
diff --git a/lib/xmerl/test/xmerl_sax_std_SUITE.erl b/lib/xmerl/test/xmerl_sax_std_SUITE.erl
index 525a3b175a..b8412206cc 100644
--- a/lib/xmerl/test/xmerl_sax_std_SUITE.erl
+++ b/lib/xmerl/test/xmerl_sax_std_SUITE.erl
@@ -2,7 +2,7 @@
%%----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -507,11 +507,8 @@ end_per_testcase(_Func,_Config) ->
'not-wf-sa-036'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"xmltest","not-wf/sa/036.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_,<<"Illegal data\r\n">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Case
@@ -522,11 +519,8 @@ end_per_testcase(_Func,_Config) ->
'not-wf-sa-037'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"xmltest","not-wf/sa/037.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_,<<"&#32;\r\n">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Case
@@ -561,11 +555,8 @@ end_per_testcase(_Func,_Config) ->
'not-wf-sa-040'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"xmltest","not-wf/sa/040.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_,<<"<doc></doc>\r\n">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Case
@@ -576,11 +567,8 @@ end_per_testcase(_Func,_Config) ->
'not-wf-sa-041'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"xmltest","not-wf/sa/041.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_,<<"<doc></doc>\r\n">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Case
@@ -603,11 +591,8 @@ end_per_testcase(_Func,_Config) ->
'not-wf-sa-043'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"xmltest","not-wf/sa/043.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_,<<"Illegal data\r\n">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Case
@@ -618,11 +603,8 @@ end_per_testcase(_Func,_Config) ->
'not-wf-sa-044'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"xmltest","not-wf/sa/044.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_,<<"<doc/>\r\n">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Case
@@ -669,11 +651,8 @@ end_per_testcase(_Func,_Config) ->
'not-wf-sa-048'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"xmltest","not-wf/sa/048.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_,<<"<![CDATA[]]>\r\n">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Case
@@ -1416,11 +1395,8 @@ end_per_testcase(_Func,_Config) ->
'not-wf-sa-110'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"xmltest","not-wf/sa/110.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_,<<"&e;\r\n">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Case
@@ -1914,9 +1890,9 @@ end_per_testcase(_Func,_Config) ->
%% Special case becase we returns everything after a legal document
%% as an rest instead of giving and error to let the user handle
%% multipple docs on a stream.
- {ok,_,<<"<?xml version=\"1.0\"?>\r\n">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- % R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
- % check_result(R, "not-wf").
+ %{ok,_,<<"<?xml version=\"1.0\"?>\r\n">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Case
@@ -7784,11 +7760,8 @@ end_per_testcase(_Func,_Config) ->
'o-p01fail3'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"oasis","p01fail3.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_, <<"<bad/>", _/binary>>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Case
@@ -11417,12 +11390,8 @@ end_per_testcase(_Func,_Config) ->
'ibm-not-wf-P01-ibm01n02'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"ibm","not-wf/P01/ibm01n02.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_, <<"<?xml version=\"1.0\"?>", _/binary>>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- % R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
- % check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Case
@@ -11433,11 +11402,8 @@ end_per_testcase(_Func,_Config) ->
'ibm-not-wf-P01-ibm01n03'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"ibm","not-wf/P01/ibm01n03.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_, <<"<title>Wrong combination!</title>", _/binary>>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Cases
@@ -13027,11 +12993,8 @@ end_per_testcase(_Func,_Config) ->
'ibm-not-wf-P27-ibm27n01'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"ibm","not-wf/P27/ibm27n01.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_, <<"<!ELEMENT cat EMPTY>">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Cases
@@ -13461,11 +13424,8 @@ end_per_testcase(_Func,_Config) ->
'ibm-not-wf-P39-ibm39n06'(Config) ->
file:set_cwd(xmerl_test_lib:get_data_dir(Config)),
Path = filename:join([xmerl_test_lib:get_data_dir(Config),"ibm","not-wf/P39/ibm39n06.xml"]),
- %% Special case becase we returns everything after a legal document
- %% as an rest instead of giving and error to let the user handle
- %% multipple docs on a stream.
- {ok,_,<<"content after end tag\r\n">>} = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]).
- %%check_result(R, "not-wf").
+ R = xmerl_sax_parser:file(Path, [{event_fun, fun(_,_,S) -> S end}]),
+ check_result(R, "not-wf").
%%----------------------------------------------------------------------
%% Test Cases
diff --git a/lib/xmerl/test/xmerl_sax_stream_SUITE.erl b/lib/xmerl/test/xmerl_sax_stream_SUITE.erl
new file mode 100644
index 0000000000..7315f67374
--- /dev/null
+++ b/lib/xmerl/test/xmerl_sax_stream_SUITE.erl
@@ -0,0 +1,260 @@
+%%-*-erlang-*-
+%%----------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%----------------------------------------------------------------------
+%% File : xmerl_sax_stream_SUITE.erl
+%%----------------------------------------------------------------------
+-module(xmerl_sax_stream_SUITE).
+-compile(export_all).
+
+%%----------------------------------------------------------------------
+%% Include files
+%%----------------------------------------------------------------------
+-include_lib("common_test/include/ct.hrl").
+-include_lib("kernel/include/file.hrl").
+
+%%======================================================================
+%% External functions
+%%======================================================================
+
+%%----------------------------------------------------------------------
+%% Initializations
+%%----------------------------------------------------------------------
+all() ->
+ [
+ one_document,
+ two_documents,
+ one_document_and_junk,
+ end_of_stream
+ ].
+
+%%----------------------------------------------------------------------
+%% Initializations
+%%----------------------------------------------------------------------
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_Func, _Config) ->
+ ok.
+
+%%----------------------------------------------------------------------
+%% Tests
+%%----------------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% Send One doc over stream
+one_document(Config) ->
+ Port = 11111,
+
+ {ok, ListenSocket} = listen(Port),
+ Self = self(),
+
+ spawn(
+ fun() ->
+ case catch gen_tcp:accept(ListenSocket) of
+ {ok, S} ->
+ Result = xmerl_sax_parser:stream(<<>>,
+ [{continuation_state, S},
+ {continuation_fun,
+ fun(Sd) ->
+ io:format("Continuation called!!", []),
+ case gen_tcp:recv(Sd, 0) of
+ {ok, Packet} ->
+ io:format("Packet: ~p\n", [Packet]),
+ {Packet, Sd};
+ {error, Reason} ->
+ throw({error, Reason})
+ end
+ end}]),
+ Self ! {xmerl_sax, Result},
+ close(S);
+ Error ->
+ Self ! {xmerl_sax, {error, {accept, Error}}}
+ end
+ end),
+
+ {ok, SendSocket} = connect(localhost, Port),
+
+ {ok, Binary} = file:read_file(filename:join([datadir(Config), "xmerl_sax_stream_one.xml"])),
+
+ send_chunks(SendSocket, Binary),
+
+ receive
+ {xmerl_sax, {ok, undefined, Rest}} ->
+ <<"\n">> = Rest,
+ io:format("Ok Rest: ~p\n", [Rest])
+ after 5000 ->
+ ct:fail("Timeout")
+ end,
+ ok.
+
+%%----------------------------------------------------------------------
+%% Send Two doc over stream
+two_documents(Config) ->
+ Port = 11111,
+
+ {ok, ListenSocket} = listen(Port),
+ Self = self(),
+
+ spawn(
+ fun() ->
+ case catch gen_tcp:accept(ListenSocket) of
+ {ok, S} ->
+ Result = xmerl_sax_parser:stream(<<>>,
+ [{continuation_state, S},
+ {continuation_fun,
+ fun(Sd) ->
+ io:format("Continuation called!!", []),
+ case gen_tcp:recv(Sd, 0) of
+ {ok, Packet} ->
+ io:format("Packet: ~p\n", [Packet]),
+ {Packet, Sd};
+ {error, Reason} ->
+ throw({error, Reason})
+ end
+ end}]),
+ Self ! {xmerl_sax, Result},
+ close(S);
+ Error ->
+ Self ! {xmerl_sax, {error, {accept, Error}}}
+ end
+ end),
+
+ {ok, SendSocket} = connect(localhost, Port),
+
+ {ok, Binary} = file:read_file(filename:join([datadir(Config), "xmerl_sax_stream_two.xml"])),
+
+ send_chunks(SendSocket, Binary),
+
+ receive
+ {xmerl_sax, {ok, undefined, Rest}} ->
+ <<"\n<?x", _R/binary>> = Rest,
+ io:format("Ok Rest: ~p\n", [Rest])
+ after 5000 ->
+ ct:fail("Timeout")
+ end,
+ ok.
+
+%%----------------------------------------------------------------------
+%% Send one doc and then junk on stream
+one_document_and_junk(Config) ->
+ Port = 11111,
+
+ {ok, ListenSocket} = listen(Port),
+ Self = self(),
+
+ spawn(
+ fun() ->
+ case catch gen_tcp:accept(ListenSocket) of
+ {ok, S} ->
+ Result = xmerl_sax_parser:stream(<<>>,
+ [{continuation_state, S},
+ {continuation_fun,
+ fun(Sd) ->
+ io:format("Continuation called!!", []),
+ case gen_tcp:recv(Sd, 0) of
+ {ok, Packet} ->
+ io:format("Packet: ~p\n", [Packet]),
+ {Packet, Sd};
+ {error, Reason} ->
+ throw({error, Reason})
+ end
+ end}]),
+ Self ! {xmerl_sax, Result},
+ close(S);
+ Error ->
+ Self ! {xmerl_sax, {error, {accept, Error}}}
+ end
+ end),
+
+ {ok, SendSocket} = connect(localhost, Port),
+
+ {ok, Binary} = file:read_file(filename:join([datadir(Config), "xmerl_sax_stream_one_junk.xml"])),
+
+ send_chunks(SendSocket, Binary),
+
+ receive
+ {xmerl_sax, {ok, undefined, Rest}} ->
+ <<"\nth", _R/binary>> = Rest,
+ io:format("Ok Rest: ~p\n", [Rest])
+ after 10000 ->
+ ct:fail("Timeout")
+ end,
+ ok.
+
+%%----------------------------------------------------------------------
+%% Test of continuation when end of stream
+end_of_stream(Config) ->
+ Stream = <<"<?xml version=\"1.0\" encoding=\"utf-8\"?><a>hej</a>">>,
+ {ok, undefined, <<>>} = xmerl_sax_parser:stream(Stream, []),
+ ok.
+
+%%----------------------------------------------------------------------
+%% Utility functions
+%%----------------------------------------------------------------------
+listen(Port) ->
+ case catch gen_tcp:listen(Port, [{active, false},
+ binary,
+ {keepalive, true},
+ {reuseaddr,true}]) of
+ {ok, ListenSocket} ->
+ {ok, ListenSocket};
+ {error, Reason} ->
+ {error, {listen, Reason}}
+ end.
+
+close(Socket) ->
+ (catch gen_tcp:close(Socket)).
+
+connect(Host, Port) ->
+ Timeout = 5000,
+ % Options1 = check_options(Options),
+ Options = [binary],
+ case catch gen_tcp:connect(Host, Port, Options, Timeout) of
+ {ok, Socket} ->
+ {ok, Socket};
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+send_chunks(Socket, Binary) ->
+ BSize = erlang:size(Binary),
+ if
+ BSize > 25 ->
+ <<Head:25/binary, Tail/binary>> = Binary,
+ case gen_tcp:send(Socket, Head) of
+ ok ->
+ timer:sleep(1000),
+ send_chunks(Socket, Tail);
+ {error,closed} ->
+ ok
+ end;
+ true ->
+ gen_tcp:send(Socket, Binary)
+ end.
+
+datadir(Config) ->
+ proplists:get_value(data_dir, Config).
diff --git a/lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_one.xml b/lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_one.xml
new file mode 100644
index 0000000000..30328bb188
--- /dev/null
+++ b/lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_one.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<person>
+<name>
+Arne Andersson
+</name>
+<address>
+<street>
+ Old Road 456
+</street>
+<zip>
+12323
+</zip>
+<city>
+Small City
+</city>
+</address>
+</person>
diff --git a/lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_one_junk.xml b/lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_one_junk.xml
new file mode 100644
index 0000000000..f730a95865
--- /dev/null
+++ b/lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_one_junk.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<person>
+<name>
+Arne Andersson
+</name>
+<address>
+<street>
+ Old Road 456
+</street>
+<zip>
+12323
+</zip>
+<city>
+Small City
+</city>
+</address>
+</person>
+this is junk ......
diff --git a/lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_two.xml b/lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_two.xml
new file mode 100644
index 0000000000..e241a02190
--- /dev/null
+++ b/lib/xmerl/test/xmerl_sax_stream_SUITE_data/xmerl_sax_stream_two.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<person>
+<name>
+Arne Andersson
+</name>
+<address>
+<street>
+ Old Road 456
+</street>
+<zip>
+12323
+</zip>
+<city>
+Small City
+</city>
+</address>
+</person>
+<?xml version="1.0"?>
+<person>
+<name>
+Bertil Bengtson
+</name>
+<address>
+<street>
+ New Road 4
+</street>
+<zip>
+12328
+</zip>
+<city>
+Small City
+</city>
+</address>
+</person>
diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk
index a78a035a1f..2e9c9061d9 100644
--- a/lib/xmerl/vsn.mk
+++ b/lib/xmerl/vsn.mk
@@ -1 +1 @@
-XMERL_VSN = 1.3.11
+XMERL_VSN = 1.3.15
diff --git a/lib/xmerl/xmerl.pub b/lib/xmerl/xmerl.pub
deleted file mode 100644
index 29a81bbde2..0000000000
--- a/lib/xmerl/xmerl.pub
+++ /dev/null
@@ -1,19 +0,0 @@
-{name, "xmerl"}.
-{vsn, {0,18}}.
-{summary, "XML processing tools"}.
-{author, "Ulf Wiger, Johan Blom, Richard Carlsson, Mickael Remond", "[email protected]", "20020307"}.
-{keywords, ["xml", "html"]}.
-{needs, [{compiler, "3.0"}]}.
-{abstract,
- "Implements a set of tools for processing XML documents, as well as "
- "working with XML-like structures in Erlang. The main attraction so far "
- "is a single-pass, highly customizable XML processor. Other components are "
- "an export/translation facility and an XPATH query engine. "
- "This version fixes a few bugs in the scanner, and improves HTML export. "
- "The latest version can be found at http://sowap.sourceforge.net/ "
- "Note that this is still very much a beta product."}.
-
-
-
-
-